From 18ef4e0e3447ab8231cabc15eee9d0ee1ef56742 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 4 Jun 2024 13:01:33 +0200 Subject: [PATCH 01/84] modules --- libcrux-ml-kem/src/ind_cca.rs | 248 ++++++++++++++++++++++--------- libcrux-ml-kem/src/mlkem768.rs | 110 ++++++++++++++ libcrux-ml-kem/tests/nistkats.rs | 8 + 3 files changed, 299 insertions(+), 67 deletions(-) diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index 004030438..4d733ba59 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -3,11 +3,11 @@ use crate::{ compare_ciphertexts_in_constant_time, select_shared_secret_in_constant_time, }, constants::{CPA_PKE_KEY_GENERATION_SEED_SIZE, H_DIGEST_SIZE, SHARED_SECRET_SIZE}, - hash_functions::{self, Hash}, + hash_functions::Hash, ind_cpa::{into_padded_array, serialize_public_key}, serialize::deserialize_ring_elements_reduced, types::{MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey}, - vector::{Operations, PortableVector}, + vector::Operations, }; /// Seed size for key generation @@ -24,6 +24,151 @@ pub const ENCAPS_SEED_SIZE: usize = SHARED_SECRET_SIZE; /// A byte array of size [`SHARED_SECRET_SIZE`]. pub type MlKemSharedSecret = [u8; SHARED_SECRET_SIZE]; +macro_rules! instantiate { + ($modp:ident, $vector:path, $hash:path) => { + pub mod $modp { + use crate::{ + MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey, MlKemSharedSecret, + KEY_GENERATION_SEED_SIZE, SHARED_SECRET_SIZE, + }; + + /// Portable generate key pair. + pub(crate) fn generate_keypair_generic< + const K: usize, + const CPA_PRIVATE_KEY_SIZE: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + >( + randomness: [u8; KEY_GENERATION_SEED_SIZE], + ) -> MlKemKeyPair { + super::generate_keypair_generic::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + $vector, + $hash, + >(randomness) + } + + /// Portable public key validation + pub(crate) fn validate_public_key_generic< + const K: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + const PUBLIC_KEY_SIZE: usize, + >( + public_key: &[u8; PUBLIC_KEY_SIZE], + ) -> bool { + super::validate_public_key_generic::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + $vector, + >(public_key) + } + + /// Portable encapsualte + pub(crate) fn encapsulate_generic< + const K: usize, + const CIPHERTEXT_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const VECTOR_U_BLOCK_LEN: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, + >( + public_key: &MlKemPublicKey, + randomness: [u8; SHARED_SECRET_SIZE], + ) -> (MlKemCiphertext, MlKemSharedSecret) { + super::encapsulate_generic::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + $vector, + $hash, + >(public_key, randomness) + } + + /// Portable decapsulate + pub fn decapsulate_generic< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const CIPHERTEXT_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const C1_BLOCK_SIZE: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, + const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + ciphertext: &MlKemCiphertext, + ) -> MlKemSharedSecret { + super::decapsulate_generic::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + $vector, + $hash, + >(private_key, ciphertext) + } + } + }; +} + +// Portable generic implementations. +instantiate! {portable, crate::vector::PortableVector, crate::hash_functions::portable::PortableHash} + +// AVX2 generic implementation. +#[cfg(feature = "simd256")] +instantiate! {avx2, crate::vector::SIMD256Vector, crate::hash_functions::avx2::Simd256Hash} + +// NEON generic implementation. +#[cfg(feature = "simd128")] +instantiate! {neon, crate::vector::SIMD128Vector, crate::hash_functions::neon::Simd128Hash} + /// Serialize the secret key. #[inline(always)] fn serialize_kem_secret_key>( @@ -56,19 +201,15 @@ pub(crate) fn validate_public_key< && libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return validate_public_key_generic::< + return avx2::validate_public_key_generic::< K, RANKED_BYTES_PER_RING_ELEMENT, PUBLIC_KEY_SIZE, - crate::vector::SIMD256Vector, >(public_key); #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - PortableVector, - >(public_key) + portable::validate_public_key_generic::( + public_key, + ) } else if cfg!(feature = "simd128") && cfg!(target_arch = "aarch64") && libcrux_platform::simd128_support() @@ -81,19 +222,13 @@ pub(crate) fn validate_public_key< crate::vector::SIMD128Vector, >(public_key); #[cfg(not(feature = "simd128"))] - validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - PortableVector, - >(public_key) + portable::validate_public_key_generic::( + public_key, + ) } else { - validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - PortableVector, - >(public_key) + portable::validate_public_key_generic::( + public_key, + ) } } @@ -128,16 +263,13 @@ pub(crate) fn generate_keypair< >( randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> MlKemKeyPair { - let ind_cpa_keypair_randomness = &randomness[0..CPA_PKE_KEY_GENERATION_SEED_SIZE]; - let implicit_rejection_value = &randomness[CPA_PKE_KEY_GENERATION_SEED_SIZE..]; - // Runtime feature detection. if cfg!(feature = "simd256") && cfg!(target_arch = "x86_64") && libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return generate_keypair_generic::< + return avx2::generate_keypair_generic::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -145,11 +277,9 @@ pub(crate) fn generate_keypair< BYTES_PER_RING_ELEMENT, ETA1, ETA1_RANDOMNESS_SIZE, - crate::vector::SIMD256Vector, - hash_functions::avx2::Simd256Hash, - >(ind_cpa_keypair_randomness, implicit_rejection_value); + >(randomness); #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - generate_keypair_generic::< + portable::generate_keypair_generic::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -157,9 +287,7 @@ pub(crate) fn generate_keypair< BYTES_PER_RING_ELEMENT, ETA1, ETA1_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, - >(ind_cpa_keypair_randomness, implicit_rejection_value) + >(randomness) } else if cfg!(feature = "simd128") && cfg!(target_arch = "aarch64") && libcrux_platform::simd128_support() @@ -177,7 +305,7 @@ pub(crate) fn generate_keypair< hash_functions::neon::Simd128Hash, >(ind_cpa_keypair_randomness, implicit_rejection_value); #[cfg(not(feature = "simd128"))] - generate_keypair_generic::< + portable::generate_keypair_generic::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -185,11 +313,9 @@ pub(crate) fn generate_keypair< BYTES_PER_RING_ELEMENT, ETA1, ETA1_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, - >(ind_cpa_keypair_randomness, implicit_rejection_value) + >(randomness) } else { - generate_keypair_generic::< + portable::generate_keypair_generic::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -197,12 +323,14 @@ pub(crate) fn generate_keypair< BYTES_PER_RING_ELEMENT, ETA1, ETA1_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, - >(ind_cpa_keypair_randomness, implicit_rejection_value) + >(randomness) } } +/// Generate a key pair. +/// +/// Depending on the `Vector` and `Hasher` used, this requires different hardware +/// features fn generate_keypair_generic< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -214,9 +342,11 @@ fn generate_keypair_generic< Vector: Operations, Hasher: Hash, >( - ind_cpa_keypair_randomness: &[u8], - implicit_rejection_value: &[u8], + randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> MlKemKeyPair { + let ind_cpa_keypair_randomness = &randomness[0..CPA_PKE_KEY_GENERATION_SEED_SIZE]; + let implicit_rejection_value = &randomness[CPA_PKE_KEY_GENERATION_SEED_SIZE..]; + let (ind_cpa_private_key, public_key) = crate::ind_cpa::generate_keypair::< K, CPA_PRIVATE_KEY_SIZE, @@ -262,7 +392,7 @@ pub(crate) fn encapsulate< && libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return encapsulate_generic::< + return avx2::encapsulate_generic::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -276,11 +406,9 @@ pub(crate) fn encapsulate< ETA1_RANDOMNESS_SIZE, ETA2, ETA2_RANDOMNESS_SIZE, - crate::vector::SIMD256Vector, - hash_functions::avx2::Simd256Hash, >(public_key, randomness); #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - encapsulate_generic::< + portable::encapsulate_generic::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -294,15 +422,13 @@ pub(crate) fn encapsulate< ETA1_RANDOMNESS_SIZE, ETA2, ETA2_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(public_key, randomness) } else if cfg!(feature = "simd128") && cfg!(target_arch = "aarch64") && libcrux_platform::simd128_support() { #[cfg(not(feature = "simd128"))] - return encapsulate_generic::< + return portable::encapsulate_generic::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -316,8 +442,6 @@ pub(crate) fn encapsulate< ETA1_RANDOMNESS_SIZE, ETA2, ETA2_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(public_key, randomness); #[cfg(all(feature = "simd128", target_arch = "aarch64"))] encapsulate_generic::< @@ -338,7 +462,7 @@ pub(crate) fn encapsulate< hash_functions::neon::Simd128Hash, >(public_key, randomness) } else { - encapsulate_generic::< + portable::encapsulate_generic::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -352,8 +476,6 @@ pub(crate) fn encapsulate< ETA1_RANDOMNESS_SIZE, ETA2, ETA2_RANDOMNESS_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(public_key, randomness) } } @@ -431,7 +553,7 @@ pub(crate) fn decapsulate< && libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return decapsulate_generic::< + return avx2::decapsulate_generic::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -448,11 +570,9 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - crate::vector::SIMD256Vector, - hash_functions::avx2::Simd256Hash, >(private_key, ciphertext); #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - return decapsulate_generic::< + return portable::decapsulate_generic::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -469,8 +589,6 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(private_key, ciphertext); } else if cfg!(feature = "simd128") && cfg!(target_arch = "aarch64") @@ -498,7 +616,7 @@ pub(crate) fn decapsulate< hash_functions::neon::Simd128Hash, >(private_key, ciphertext); #[cfg(not(feature = "simd128"))] - return decapsulate_generic::< + return portable::decapsulate_generic::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -515,11 +633,9 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(private_key, ciphertext); } else { - decapsulate_generic::< + portable::decapsulate_generic::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -536,8 +652,6 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - PortableVector, - hash_functions::portable::PortableHash, >(private_key, ciphertext) } } diff --git a/libcrux-ml-kem/src/mlkem768.rs b/libcrux-ml-kem/src/mlkem768.rs index 79db9a660..132f33680 100644 --- a/libcrux-ml-kem/src/mlkem768.rs +++ b/libcrux-ml-kem/src/mlkem768.rs @@ -44,6 +44,109 @@ pub type MlKem768PublicKey = MlKemPublicKey; /// Am ML-KEM 768 Key pair pub type MlKem768KeyPair = MlKemKeyPair; +// Instantiate the different functions. +macro_rules! instantiate { + ($modp:ident, $p:path) => { + pub mod $modp { + use super::*; + use $p as p; + + /// Validate a public key. + /// + /// Returns `Some(public_key)` if valid, and `None` otherwise. + pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option { + if p::validate_public_key_generic::< + RANK_768, + RANKED_BYTES_PER_RING_ELEMENT_768, + CPA_PKE_PUBLIC_KEY_SIZE_768, + >(&public_key.value) + { + Some(public_key) + } else { + None + } + } + + /// Generate ML-KEM 768 Key Pair + pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE], + ) -> MlKem768KeyPair { + p::generate_keypair_generic::< + RANK_768, + CPA_PKE_SECRET_KEY_SIZE_768, + SECRET_KEY_SIZE_768, + CPA_PKE_PUBLIC_KEY_SIZE_768, + RANKED_BYTES_PER_RING_ELEMENT_768, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } + + /// Encapsulate ML-KEM 768 + /// + /// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. + /// The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] + /// bytes of `randomness`. + pub fn encapsulate( + public_key: &MlKem768PublicKey, + randomness: [u8; SHARED_SECRET_SIZE], + ) -> (MlKem768Ciphertext, MlKemSharedSecret) { + p::encapsulate_generic::< + RANK_768, + CPA_PKE_CIPHERTEXT_SIZE_768, + CPA_PKE_PUBLIC_KEY_SIZE_768, + T_AS_NTT_ENCODED_SIZE_768, + C1_SIZE_768, + C2_SIZE_768, + VECTOR_U_COMPRESSION_FACTOR_768, + VECTOR_V_COMPRESSION_FACTOR_768, + C1_BLOCK_SIZE_768, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } + + /// Decapsulate ML-KEM 768 + /// + /// Generates an [`MlKemSharedSecret`]. + /// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. + pub fn decapsulate( + private_key: &MlKem768PrivateKey, + ciphertext: &MlKem768Ciphertext, + ) -> MlKemSharedSecret { + p::decapsulate_generic::< + RANK_768, + SECRET_KEY_SIZE_768, + CPA_PKE_SECRET_KEY_SIZE_768, + CPA_PKE_PUBLIC_KEY_SIZE_768, + CPA_PKE_CIPHERTEXT_SIZE_768, + T_AS_NTT_ENCODED_SIZE_768, + C1_SIZE_768, + C2_SIZE_768, + VECTOR_U_COMPRESSION_FACTOR_768, + VECTOR_V_COMPRESSION_FACTOR_768, + C1_BLOCK_SIZE_768, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext) + } + } + }; +} + +// Instantiations + +instantiate! {portable, ind_cca::portable} +#[cfg(feature = "simd256")] +instantiate! {avx2, ind_cca::avx2} +#[cfg(feature = "simd128")] +instantiate! {neon, ind_cca::neon} + /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. @@ -65,6 +168,13 @@ pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option MlKem768KeyPair { generate_keypair::< diff --git a/libcrux-ml-kem/tests/nistkats.rs b/libcrux-ml-kem/tests/nistkats.rs index 980501bb7..cf3a1c848 100644 --- a/libcrux-ml-kem/tests/nistkats.rs +++ b/libcrux-ml-kem/tests/nistkats.rs @@ -84,3 +84,11 @@ impl_nist_known_answer_tests!( mlkem1024::encapsulate, mlkem1024::decapsulate ); + +impl_nist_known_answer_tests!( + kyber768_nist_kats_portable, + 768, + mlkem768::portable::generate_key_pair, + mlkem768::portable::encapsulate, + mlkem768::portable::decapsulate +); From d9fe4a335188b3d483afb9c160f249860693255b Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 4 Jun 2024 20:02:57 +0200 Subject: [PATCH 02/84] neon in ind_cca --- libcrux-ml-kem/src/ind_cca.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index 4d733ba59..ecb22e165 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -215,11 +215,10 @@ pub(crate) fn validate_public_key< && libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return validate_public_key_generic::< + return neon::validate_public_key_generic::< K, RANKED_BYTES_PER_RING_ELEMENT, PUBLIC_KEY_SIZE, - crate::vector::SIMD128Vector, >(public_key); #[cfg(not(feature = "simd128"))] portable::validate_public_key_generic::( @@ -293,7 +292,7 @@ pub(crate) fn generate_keypair< && libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return generate_keypair_generic::< + return neon::generate_keypair_generic::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -301,9 +300,7 @@ pub(crate) fn generate_keypair< BYTES_PER_RING_ELEMENT, ETA1, ETA1_RANDOMNESS_SIZE, - crate::vector::SIMD128Vector, - hash_functions::neon::Simd128Hash, - >(ind_cpa_keypair_randomness, implicit_rejection_value); + >(randomness); #[cfg(not(feature = "simd128"))] portable::generate_keypair_generic::< K, @@ -444,7 +441,7 @@ pub(crate) fn encapsulate< ETA2_RANDOMNESS_SIZE, >(public_key, randomness); #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - encapsulate_generic::< + neon::encapsulate_generic::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -458,8 +455,6 @@ pub(crate) fn encapsulate< ETA1_RANDOMNESS_SIZE, ETA2, ETA2_RANDOMNESS_SIZE, - crate::vector::SIMD128Vector, - hash_functions::neon::Simd128Hash, >(public_key, randomness) } else { portable::encapsulate_generic::< @@ -595,7 +590,7 @@ pub(crate) fn decapsulate< && libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return decapsulate_generic::< + return neon::decapsulate_generic::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -612,8 +607,6 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - crate::vector::SIMD128Vector, - hash_functions::neon::Simd128Hash, >(private_key, ciphertext); #[cfg(not(feature = "simd128"))] return portable::decapsulate_generic::< From a3de8b1f7ae4e9d9f5176ad5e5fd98838a622741 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Tue, 4 Jun 2024 20:40:11 -0700 Subject: [PATCH 03/84] Update config --- libcrux-ml-kem/c.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 1c8e4cff8..21e194915 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -35,6 +35,8 @@ files: monomorphizations_using: - [libcrux_sha3, neon, "*"] - [libcrux_sha3, simd, arm64, "*"] + monomorphizations_exact: + - [libcrux_sha3, generic_keccak, "KeccakState__core_core_arch_arm_shared_neon_uint64x2_t_$2size_t"] include_in_h: - '"intrinsics/libcrux_intrinsics_arm64.h"' From 01899c131b68299a6f910ff62a0c7902ed75dbbd Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 5 Jun 2024 10:41:52 +0200 Subject: [PATCH 04/84] add `Cargo.lock` --- .gitignore | 1 - Cargo.lock | 2006 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2006 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index f2eb8a8ef..71e87e917 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ /target -/Cargo.lock .vscode .DS_Store benches/boringssl/build diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..afa7a0389 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2006 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "benchmarks" +version = "0.0.2-pre.2" +dependencies = [ + "chacha20poly1305", + "criterion", + "curve25519-dalek", + "lib25519", + "libcrux", + "libjade-sys", + "openssl", + "p256", + "pqcrypto-kyber", + "rand", + "rand_core", + "ring", + "sha2", + "sha3", + "x25519-dalek", + "x25519-dalek-ng", +] + +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.66", + "which", +] + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hax-lib" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", + "num-bigint", + "num-traits", +] + +[[package]] +name = "hax-lib" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", + "num-bigint", + "num-traits", +] + +[[package]] +name = "hax-lib-macros" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "hax-lib-macros" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "hax-lib-macros-types" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "hax-lib-macros-types" +version = "0.1.0-pre.1" +source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lib25519" +version = "0.0.2-pre.2" +dependencies = [ + "bindgen", + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libcrux" +version = "0.0.2-pre.2" +dependencies = [ + "clap", + "getrandom", + "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", + "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", + "hex", + "libcrux", + "libcrux-hacl", + "libcrux-platform", + "log", + "pretty_env_logger", + "quickcheck", + "quickcheck_macros", + "rand", + "rand_core", + "serde", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "libcrux-fuzz" +version = "0.0.0" +dependencies = [ + "libcrux", + "libfuzzer-sys", + "rand", +] + +[[package]] +name = "libcrux-hacl" +version = "0.0.2-pre.2" +dependencies = [ + "bindgen", + "cc", + "hex", + "libcrux-platform", + "wasm-bindgen-test", +] + +[[package]] +name = "libcrux-intrinsics" +version = "0.0.2-pre.2" +dependencies = [ + "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", +] + +[[package]] +name = "libcrux-ml-dsa" +version = "0.0.2-pre.2" +dependencies = [ + "hex", + "libcrux-sha3", + "serde", + "serde_json", +] + +[[package]] +name = "libcrux-ml-kem" +version = "0.0.2-pre.2" +dependencies = [ + "criterion", + "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", + "hex", + "libcrux-intrinsics", + "libcrux-ml-kem", + "libcrux-platform", + "libcrux-sha3", + "rand", + "rand_core", + "serde", + "serde_json", +] + +[[package]] +name = "libcrux-platform" +version = "0.0.2-pre.2" +dependencies = [ + "libc", +] + +[[package]] +name = "libcrux-pqclean" +version = "0.0.2-pre.2" +dependencies = [ + "bindgen", + "cc", + "fs_extra", +] + +[[package]] +name = "libcrux-sha3" +version = "0.0.2-pre.2" +dependencies = [ + "criterion", + "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", + "hex", + "libcrux-intrinsics", + "libcrux-platform", + "rand", +] + +[[package]] +name = "libcrux-simd" +version = "0.0.2-pre.2" +dependencies = [ + "libcrux-platform", +] + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "libjade-sys" +version = "0.0.2-pre.2" +dependencies = [ + "bindgen", + "cc", + "libcrux-platform", + "pretty_env_logger", +] + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + +[[package]] +name = "plotters" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" + +[[package]] +name = "plotters-svg" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pqcrypto-internals" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d34bec6abe2283e6de7748b68b292d1ffa2203397e3e71380ff8418a49fb46" +dependencies = [ + "cc", + "dunce", + "getrandom", + "libc", +] + +[[package]] +name = "pqcrypto-kyber" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c00293cf898859d0c771455388054fd69ab712263c73fdc7f287a39b1ba000" +dependencies = [ + "cc", + "glob", + "libc", + "pqcrypto-internals", + "pqcrypto-traits", +] + +[[package]] +name = "pqcrypto-traits" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" + +[[package]] +name = "pretty_env_logger" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" +dependencies = [ + "env_logger 0.10.2", + "log", +] + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.66", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "env_logger 0.8.4", + "log", + "rand", +] + +[[package]] +name = "quickcheck_macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b22a693222d716a9587786f37ac3f6b4faedb5b80c23914e7303ff5a1d8016e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core", + "serde", + "zeroize", +] + +[[package]] +name = "x25519-dalek-ng" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7074de8999662970c3c4c8f7f30925028dd8f4ca31ad4c055efa9cdf2ec326" +dependencies = [ + "curve25519-dalek-ng", + "rand", + "rand_core", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] From efcea30708d6223a5e6251e13d777bb0d589998e Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 5 Jun 2024 14:57:11 +0200 Subject: [PATCH 05/84] more separation and a config experiment --- libcrux-ml-kem/c.sh | 2 + libcrux-ml-kem/c.yaml | 49 +- libcrux-ml-kem/c/eurydice_glue.h | 4 + libcrux-ml-kem/c/internal/libcrux_core.h | 2 +- ...mlkem768.h => libcrux_mlkem768_portable.h} | 11 +- .../c/internal/libcrux_mlkem_avx2.h | 35 +- .../c/internal/libcrux_polynomial.h | 8 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 2 +- .../c/internal/libcrux_sha3_internal.h | 55 +- libcrux-ml-kem/c/libcrux_core.c | 2 +- libcrux-ml-kem/c/libcrux_core.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024.c | 248 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 36 +- libcrux-ml-kem/c/libcrux_mlkem512.c | 248 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 36 +- libcrux-ml-kem/c/libcrux_mlkem768.c | 2288 +---------------- libcrux-ml-kem/c/libcrux_mlkem768.h | 7 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 93 + libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 57 + libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 2250 ++++++++++++++++ libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 60 + libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 116 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 3 +- libcrux-ml-kem/c/libcrux_platform.c | 8 - libcrux-ml-kem/c/libcrux_platform.h | 2 +- libcrux-ml-kem/c/libcrux_polynomial.c | 87 +- libcrux-ml-kem/c/libcrux_polynomial.h | 2 +- libcrux-ml-kem/c/libcrux_sha3.h | 2 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 4 +- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 3 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 14 +- .../c/libcrux_sha3_libcrux_ml_kem.h | 219 ++ libcrux-ml-kem/c/libcrux_sha3_neon.c | 2 +- libcrux-ml-kem/c/libcrux_sha3_neon.h | 2 +- libcrux-ml-kem/src/ind_cca.rs | 507 +--- libcrux-ml-kem/src/ind_cca/instantiations.rs | 144 ++ libcrux-ml-kem/src/ind_cca/multiplexing.rs | 358 +++ libcrux-ml-kem/src/mlkem1024.rs | 8 +- libcrux-ml-kem/src/mlkem512.rs | 8 +- libcrux-ml-kem/src/mlkem768.rs | 22 +- 40 files changed, 3898 insertions(+), 3108 deletions(-) rename libcrux-ml-kem/c/internal/{libcrux_mlkem768.h => libcrux_mlkem768_portable.h} (96%) create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.h delete mode 100644 libcrux-ml-kem/c/libcrux_platform.c create mode 100644 libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h create mode 100644 libcrux-ml-kem/src/ind_cca/instantiations.rs create mode 100644 libcrux-ml-kem/src/ind_cca/multiplexing.rs diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index cf72853bb..17af9d262 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -50,6 +50,8 @@ fi mkdir -p c cd c +rm -rf *.c *.h +rm -rf internal/*.h echo "Running eurydice ..." $EURYDICE_HOME/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc cp $EURYDICE_HOME/include/eurydice_glue.h . diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 21e194915..4348c51aa 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -1,17 +1,17 @@ files: # INTRINSICS - - name: libcrux_intrinsics_neon - library: true - inline_static: true - api: - - [libcrux_intrinsics, arm64] - - - name: libcrux_intrinsics_avx2 - library: true - inline_static: true - api: - - [libcrux_intrinsics, avx2] + # - name: libcrux_intrinsics_neon + # library: true + # inline_static: true + # api: + # - [libcrux_intrinsics, arm64] + + # - name: libcrux_intrinsics_avx2 + # library: true + # inline_static: true + # api: + # - [libcrux_intrinsics, avx2] - name: libcrux_platform api: @@ -182,6 +182,16 @@ files: api: - [libcrux_ml_kem, mlkem512] + - name: libcrux_mlkem768_avx2 + api: + - [libcrux_ml_kem, mlkem768, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + + - name: libcrux_mlkem768_portable + api: + - [libcrux_ml_kem, mlkem768, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + - name: libcrux_mlkem768 api: - [libcrux_ml_kem, mlkem768] @@ -190,9 +200,20 @@ files: api: - [libcrux_ml_kem, mlkem1024] - # Just a few constants not caught by anything above. Most likely can go into - # core or polynomial (TODO: try it). - - name: libcrux_mlkem_common + - name: libcrux_mlkem_multiplexing + private: + - [libcrux_ml_kem, ind_cca, multiplexing] + inline_static: true + + - name: libcrux_mlkem_ind_cca private: + - [libcrux_ml_kem, ind_cca] - [libcrux_ml_kem, "*"] inline_static: true + + # # Just a few constants not caught by anything above. Most likely can go into + # # core or polynomial (TODO: try it). + # - name: libcrux_mlkem_common + # private: + # - [libcrux_ml_kem, "*"] + # inline_static: true diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index f798f970b..bd794c456 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -155,9 +155,13 @@ static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { ? ((ret_t){.tag = core_option_None}) \ : ((ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) +// Old name (TODO: remove once everyone has upgraded to the latest Charon) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ Eurydice_range_iter_next +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ + Eurydice_range_iter_next + // See note in karamel/lib/Inlining.ml if you change this #define Eurydice_into_iter(x, t, _ret_t) (x) #define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \ diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 0ca3a224a..36a6ebec0 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_core_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem768.h b/libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h similarity index 96% rename from libcrux-ml-kem/c/internal/libcrux_mlkem768.h rename to libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h index 23d48e22f..f5fcb4e07 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h @@ -2,20 +2,19 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ -#ifndef __internal_libcrux_mlkem768_H -#define __internal_libcrux_mlkem768_H +#ifndef __internal_libcrux_mlkem768_portable_H +#define __internal_libcrux_mlkem768_portable_H #if defined(__cplusplus) extern "C" { #endif -#include "../libcrux_mlkem768.h" +#include "../libcrux_mlkem768_portable.h" #include "eurydice_glue.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_avx2.h" #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_internal.h" @@ -140,5 +139,5 @@ void libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_ke } #endif -#define __internal_libcrux_mlkem768_H_DEFINED +#define __internal_libcrux_mlkem768_portable_H_DEFINED #endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 6894d3c1f..4c7241790 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_avx2_H @@ -18,56 +18,53 @@ extern "C" { #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_avx2.h" -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value); +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]); -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]); -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value); +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]); -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]); -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value); +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]); diff --git a/libcrux-ml-kem/c/internal/libcrux_polynomial.h b/libcrux-ml-kem/c/internal/libcrux_polynomial.h index 57393f611..2c122c65d 100644 --- a/libcrux-ml-kem/c/internal/libcrux_polynomial.h +++ b/libcrux-ml-kem/c/internal/libcrux_polynomial.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_polynomial_H @@ -26,6 +26,9 @@ extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U]; #define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ + ((int16_t)1353) + #define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ (62209U) @@ -131,9 +134,6 @@ size_t libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( Eurydice_slice a, Eurydice_slice out); -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ - ((int16_t)1353) - typedef struct K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index cf31957cc..11ada5b26 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index c74eb7f77..58f4859bb 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H @@ -124,6 +124,59 @@ static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; +static inline void +libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o10, (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o20[1U]; + memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o1); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o20, (size_t)168U); + Eurydice_slice o2[1U]; + memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o30[1U]; + memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o2); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o30, (size_t)168U); + Eurydice_slice o3[1U]; + memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o4[1U]; + memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o3); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o4); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + s, buf); +} + static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self) { diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 087bc8187..8b69e17c9 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 7e5b4a58b..45892cc6d 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c index 42254373d..ed08e6f30 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.c @@ -2,17 +2,27 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem1024.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem768.h" +#include "internal/libcrux_mlkem768_portable.h" #include "internal/libcrux_mlkem_avx2.h" #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_internal.h" +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_11size_t( void) { @@ -472,16 +482,17 @@ sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functi sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { - if (!!done) { + if (done) { break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_168size_t( - uu____2, sampled_coefficients, out); } int16_t uu____3[4U][272U]; memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); @@ -987,7 +998,7 @@ encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_port } static void -decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( +decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]) { @@ -1072,30 +1083,31 @@ decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_fu memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + static void decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - uint8_t uu____2[32U]; - if (uu____1) { - libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____2); - } else { - decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____2); - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } void libcrux_ml_kem_mlkem1024_decapsulate( @@ -1108,6 +1120,17 @@ void libcrux_ml_kem_mlkem1024_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( @@ -1117,7 +1140,7 @@ static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { } static K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( +encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; @@ -1178,37 +1201,39 @@ encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_fu return lit; } +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + static K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ - uu____2; - if (uu____1) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____2; + uu____0; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____1, uu____2); + return uu____0; } - return uu____2; + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ @@ -1222,6 +1247,15 @@ libcrux_ml_kem_mlkem1024_encapsulate( uu____0, uu____1); } +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_4size_t1(void) { return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); @@ -1503,9 +1537,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ } static libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); @@ -1535,38 +1578,33 @@ generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_ha uu____4)); } +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + static libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; + libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____0; + if (libcrux_platform_platform_simd256_support()) { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____1); + return uu____0; } - libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } else { - uu____2 = - generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } - return uu____2; + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____2); + return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t @@ -1577,6 +1615,12 @@ libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) { uu____0); } +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + public_key); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_1568size_t_4size_t(void) { return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); @@ -1618,8 +1662,8 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1568size libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); } -static bool -validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( +static inline bool +validate_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector deserialized_pk[4U]; @@ -1644,27 +1688,25 @@ validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_4size_t_1536si (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return validate_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( + public_key); +} + static bool validate_public_key___4size_t_1536size_t_1568size_t( uint8_t *public_key) { bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - bool uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - public_key); - } else { - uu____2 = - validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( + if (libcrux_platform_platform_simd256_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( public_key); + return uu____0; } - return uu____2; + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); + return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index a8cd738ab..b23582faf 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H @@ -78,19 +78,53 @@ extern "C" { LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + void libcrux_ml_kem_mlkem1024_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]); +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]); +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ libcrux_ml_kem_mlkem1024_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c index a0170dede..ec48227d1 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512.c @@ -2,17 +2,27 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem512.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem768.h" +#include "internal/libcrux_mlkem768_portable.h" #include "internal/libcrux_mlkem_avx2.h" #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_internal.h" +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_10size_t(void) { return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); @@ -428,16 +438,17 @@ sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functi sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { - if (!!done) { + if (done) { break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_168size_t( - uu____2, sampled_coefficients, out); } int16_t uu____3[2U][272U]; memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); @@ -889,7 +900,7 @@ encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_port } static void -decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( +decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]) { @@ -974,30 +985,31 @@ decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_fu memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + static void decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - uint8_t uu____2[32U]; - if (uu____1) { - libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____2); - } else { - decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____2); - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } void libcrux_ml_kem_mlkem512_decapsulate( @@ -1010,6 +1022,17 @@ void libcrux_ml_kem_mlkem512_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( @@ -1019,7 +1042,7 @@ static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { } static K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( +encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; @@ -1080,37 +1103,39 @@ encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_fu return lit; } +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + static K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ - uu____2; - if (uu____1) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____2; + uu____0; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____1, uu____2); + return uu____0; } - return uu____2; + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____3, uu____4); + return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ @@ -1124,6 +1149,15 @@ libcrux_ml_kem_mlkem512_encapsulate( uu____0, uu____1); } +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_2size_t1(void) { return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); @@ -1405,9 +1439,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ } static libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); @@ -1437,38 +1480,33 @@ generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_ha uu____4)); } +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + static libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; + libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____0; + if (libcrux_platform_platform_simd256_support()) { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____1); + return uu____0; } - libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } else { - uu____2 = - generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } - return uu____2; + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____2); + return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t @@ -1479,6 +1517,12 @@ libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) { uu____0); } +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + public_key); +} + static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector closure__libcrux_ml_kem_vector_PortableVector_800size_t_2size_t(void) { return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); @@ -1520,8 +1564,8 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_800size_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); } -static bool -validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( +static inline bool +validate_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector deserialized_pk[2U]; @@ -1546,27 +1590,25 @@ validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_2size_t_768siz (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return validate_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( + public_key); +} + static bool validate_public_key___2size_t_768size_t_800size_t( uint8_t *public_key) { bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - bool uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - public_key); - } else { - uu____2 = - validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( + if (libcrux_platform_platform_simd256_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( public_key); + return uu____0; } - return uu____2; + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key); + return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 8dc3973a5..3dfe05c0c 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_H @@ -76,19 +76,53 @@ extern "C" { LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + void libcrux_ml_kem_mlkem512_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]); +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]); +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c index 545e481f7..01b9e83cb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768.c @@ -2,1708 +2,28 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ -#include "internal/libcrux_mlkem768.h" +#include "libcrux_mlkem768.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_avx2.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_10( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___10int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_11( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___11int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -typedef struct - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector_s { - libcrux_ml_kem_vector_PortableVector fst; - libcrux_ml_kem_vector_PortableVector snd; -} __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector; - -static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a, - libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { - libcrux_ml_kem_vector_PortableVector t = - libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - b, zeta_r); - b = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - a, &t); - a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - a, &t); - return (( - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ - .fst = a, .snd = b}); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer, size_t _initial_coefficient_bound) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_PortableVector x = uu____0.fst; - libcrux_ml_kem_vector_PortableVector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -void libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -void libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = (size_t)0U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U, (size_t)3328U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_4( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___4int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_5( - bytes); - re.coefficients[i0] = uu____0; - libcrux_ml_kem_vector_PortableVector uu____1 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___5int32_t( - re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a, - libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { - libcrux_ml_kem_vector_PortableVector a_minus_b = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - b, &a); - a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - a, &b)); - b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - a_minus_b, zeta_r); - return (( - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ - .fst = a, .snd = b}); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = - offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = - step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_PortableVector x = uu____0.fst; - libcrux_ml_kem_vector_PortableVector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - v, result); - return result; -} - -void libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - uint8_t ret[32U]) { - uint8_t serialized[32U] = {0U}; - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0]); - libcrux_ml_kem_vector_PortableVector coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress_1( - coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_1( - coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *);); - memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message = compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___cond_subtract_3329( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static void -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -typedef struct PortableHash____3size_t_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; -} PortableHash____3size_t; - -static inline PortableHash____3size_t shake128_init_absorb___3size_t( - uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final( - uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, - Eurydice_slice));); - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; - memcpy( - uu____1, state, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - PortableHash____3size_t lit; - memcpy( - lit.shake128_state, uu____1, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - int16_t s[272U]) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (!!done) { - break; - } - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U])); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t uu____2 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t random_bits_as_u32 = - uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = - (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t random_bits_as_u24 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( - randomness); - return uu____0; -} - -static inline void ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) { - size_t j = i; - libcrux_ml_kem_vector_PortableVector t = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___multiply_by_constant( - re->coefficients[j + step], (int16_t)-1600); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - re->coefficients[j], &t); - re->coefficients[j + step] = uu____0; - libcrux_ml_kem_vector_PortableVector uu____1 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - re->coefficients[j], &t); - re->coefficients[j] = uu____1; - } -} - -void libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector(re); - size_t zeta_i = (size_t)1U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U, (size_t)3U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t0(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_1( - Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_PortableVector( - coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &t_as_ntt[i0], &r_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___4int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_4( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -void libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficients = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___5int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_5( - coefficients, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -static void -decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} static void decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - uint8_t uu____2[32U]; - if (uu____1) { - libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____2); - } else { - decapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____2); - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____2, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } void libcrux_ml_kem_mlkem768_decapsulate( @@ -1716,107 +36,28 @@ void libcrux_ml_kem_mlkem768_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ - uu____2; - if (uu____1) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____2 = - encapsulate_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____2; - } - return uu____2; + uu____0; + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____1, uu____2); + return uu____0; + } + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ @@ -1830,378 +71,24 @@ libcrux_ml_kem_mlkem768_encapsulate( uu____0, uu____1); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t1(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - matrix_element, &s_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -void libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_12( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } else { - uu____2 = - generate_keypair_generic__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness, implicit_rejection_value); - } - return uu____2; + libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____0; + if (libcrux_platform_platform_simd256_support()) { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____1); + return uu____0; + } + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____2); + return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t @@ -2212,94 +99,19 @@ libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { uu____0); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static bool -validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - static bool validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key) { bool uu____0; - uu____0 = true; - bool uu____1; - if (uu____0) { - uu____1 = libcrux_platform_platform_simd256_support(); - } else { - uu____1 = false; - } - bool uu____2; - if (uu____1) { - uu____2 = - libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - public_key); - } else { - uu____2 = - validate_public_key_generic__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + if (libcrux_platform_platform_simd256_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( public_key); + return uu____0; } - return uu____2; + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); + return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 87e876a6c..9674c7990 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_H @@ -14,10 +14,9 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" +#include "libcrux_mlkem768_avx2.h" +#include "libcrux_mlkem768_portable.h" #include "libcrux_platform.h" -#include "libcrux_polynomial.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_internal.h" #define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c new file mode 100644 index 000000000..dc8fa29e8 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -0,0 +1,93 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768_avx2.h" + +#include "internal/libcrux_mlkem_avx2.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h new file mode 100644 index 000000000..a2c748d16 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -0,0 +1,57 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_avx2_H +#define __libcrux_mlkem768_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c new file mode 100644 index 000000000..cd051f9ba --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -0,0 +1,2250 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_mlkem768_portable.h" + +#include "internal/libcrux_core.h" +#include "internal/libcrux_polynomial.h" +#include "internal/libcrux_sha3_internal.h" + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_10( + bytes); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___10int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_11( + bytes); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___11int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( + serialized); + return uu____0; +} + +typedef struct + __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector_s { + libcrux_ml_kem_vector_PortableVector fst; + libcrux_ml_kem_vector_PortableVector snd; +} __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector; + +static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_vector_PortableVector a, + libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_PortableVector t = + libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( + b, zeta_r); + b = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( + a, &t); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( + a, &t); + return (( + __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ + .fst = a, .snd = b}); +} + +void libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t layer, size_t _initial_coefficient_bound) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +void libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +void libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +void libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +void libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re) { + size_t zeta_i = (size_t)0U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)7U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)6U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)5U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)4U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)3U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)2U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)1U, (size_t)3328U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( + re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_4( + bytes); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___4int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_PortableVector uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___5int32_t( + re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0; + uu____0 = deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( + serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_vector_PortableVector a, + libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_PortableVector a_minus_b = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( + b, &a); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( + a, &b)); + b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( + a_minus_b, zeta_r); + return (( + __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ + .fst = a, .snd = b}); +} + +void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)1U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)2U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)3U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)4U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)5U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)6U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)7U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( + re); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( + v, result); + return result; +} + +void libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re.coefficients[i0]); + libcrux_ml_kem_vector_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + message = compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( + bytes); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static void +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +typedef struct PortableHash____3size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; +} PortableHash____3size_t; + +static inline PortableHash____3size_t shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; + memcpy( + uu____1, state, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + PortableHash____3size_t lit; + memcpy( + lit.shake128_state, uu____1, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void shake128_squeeze_three_blocks___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + int16_t s[272U]) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U])); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_PortableVector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( + randomness); + return uu____0; +} + +static inline void ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + libcrux_ml_kem_vector_PortableVector t = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + libcrux_ml_kem_vector_PortableVector uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +void libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re) { + ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector(re); + size_t zeta_i = (size_t)1U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)6U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)5U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)4U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)3U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)2U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)1U, (size_t)3U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( + re); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t0(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_vector_PortableVector uu____0 = + libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_PortableVector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( + error_2, message, result); + return result; +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___4int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +void libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficients = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___5int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re, + Eurydice_slice out) { + compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____6 = v; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +static void +decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t1(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + matrix_element, &s_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +void libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline bool +validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h new file mode 100644 index 000000000..5536e97a2 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -0,0 +1,60 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_portable_H +#define __libcrux_mlkem768_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_polynomial.h" +#include "libcrux_sha3.h" +#include "libcrux_sha3_internal.h" + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index b5c800a4a..79f472cbb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_mlkem_avx2.h" @@ -1747,7 +1747,7 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector deserialized_pk[2U]; @@ -2023,16 +2023,17 @@ sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { - if (!!done) { + if (done) { break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uu____2, sampled_coefficients, out); } int16_t uu____3[2U][272U]; memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); @@ -2763,9 +2764,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); @@ -3745,7 +3755,7 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; @@ -4411,7 +4421,7 @@ static inline void PRF___2size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]) { @@ -4607,7 +4617,7 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector deserialized_pk[4U]; @@ -4893,16 +4903,17 @@ sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { - if (!!done) { + if (done) { break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uu____2, sampled_coefficients, out); } int16_t uu____3[4U][272U]; memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); @@ -5327,9 +5338,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); @@ -5778,7 +5798,7 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; @@ -6029,7 +6049,7 @@ static inline void PRF___4size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]) { @@ -6225,7 +6245,7 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector deserialized_pk[3U]; @@ -6495,16 +6515,17 @@ sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { - if (!!done) { + if (done) { break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uu____2, sampled_coefficients, out); } int16_t uu____3[3U][272U]; memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); @@ -6921,9 +6942,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice ind_cpa_keypair_randomness, - Eurydice_slice implicit_rejection_value) { +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); @@ -7297,7 +7327,7 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; @@ -7507,7 +7537,7 @@ static inline void PRF___3size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate_generic__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]) { diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index e02130610..08c2017a6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem_avx2_H @@ -16,6 +16,7 @@ extern "C" { #include "libcrux_core.h" #include "libcrux_sha3.h" #include "libcrux_sha3_avx2.h" +#include "libcrux_sha3_libcrux_ml_kem.h" core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); diff --git a/libcrux-ml-kem/c/libcrux_platform.c b/libcrux-ml-kem/c/libcrux_platform.c deleted file mode 100644 index b1f487d73..000000000 --- a/libcrux-ml-kem/c/libcrux_platform.c +++ /dev/null @@ -1,8 +0,0 @@ -// HAND-WRITTEN FILE - -#include - -bool libcrux_platform_platform_simd256_support(void) { - // TODO: query cpuid and cache the results!! - return true; -} diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index 067b38338..988a2e7f2 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_polynomial.c b/libcrux-ml-kem/c/libcrux_polynomial.c index 205c79c9d..23913a64a 100644 --- a/libcrux-ml-kem/c/libcrux_polynomial.c +++ b/libcrux-ml-kem/c/libcrux_polynomial.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_polynomial.h" @@ -678,15 +678,26 @@ static libcrux_ml_kem_vector_PortableVector bitwise_and_with_constant0( static inline libcrux_ml_kem_vector_PortableVector cond_subtract_3329( libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - if (v.elements[i0] >= (int16_t)3329) { - size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] - (int16_t)3329; + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + core_option_Option__size_t uu____0 = + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t); + if (!(uu____0.tag == core_option_None)) { + size_t i = uu____0.f0; + if (v.elements[i] >= (int16_t)3329) { + size_t uu____1 = i; + v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; + } + continue; } + return v; } - return v; } libcrux_ml_kem_vector_PortableVector @@ -2027,28 +2038,50 @@ static inline size_t rej_sample(Eurydice_slice a, Eurydice_slice result) { int16_t d1 = (b2 & (int16_t)15) << 8U | b1; int16_t d2 = b3 << 4U | b2 >> 4U; bool uu____1; + int16_t uu____2; + bool uu____3; + size_t uu____4; + int16_t uu____5; + size_t uu____6; + int16_t uu____7; if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { - uu____1 = sampled < (size_t)16U; - } else { - uu____1 = false; + if (sampled < (size_t)16U) { + int16_t uu____8 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = + uu____8; + sampled++; + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; + if (uu____1) { + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, + int16_t) = uu____5; + sampled++; + continue; + } + } + continue; + } } + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; if (uu____1) { - int16_t uu____2 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = - uu____2; - sampled++; - } - bool uu____3; - if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { - uu____3 = sampled < (size_t)16U; - } else { - uu____3 = false; - } - if (uu____3) { - int16_t uu____4 = d2; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = - uu____4; - sampled++; + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = + uu____5; + sampled++; + continue; + } } } } diff --git a/libcrux-ml-kem/c/libcrux_polynomial.h b/libcrux-ml-kem/c/libcrux_polynomial.h index b2778ad46..1a90c137d 100644 --- a/libcrux-ml-kem/c/libcrux_polynomial.h +++ b/libcrux-ml-kem/c/libcrux_polynomial.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_polynomial_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 7b01575cc..87bfd1a1a 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index aa58cae66..49e0302b8 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_sha3_avx2.h" @@ -1465,7 +1465,7 @@ keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 8b2942720..1401fee38 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H @@ -16,6 +16,7 @@ extern "C" { #include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_core.h" #include "libcrux_sha3_internal.h" +#include "libcrux_sha3_libcrux_ml_kem.h" typedef struct libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 9e2be9949..e796057eb 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H @@ -1090,7 +1090,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; @@ -1367,7 +1367,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; @@ -1644,7 +1644,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; @@ -1921,7 +1921,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; @@ -2029,7 +2029,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; @@ -2306,7 +2306,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next( + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( &iter, size_t, core_option_Option__size_t) .tag == core_option_None) { break; diff --git a/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h b/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h new file mode 100644 index 000000000..4f8d3f20c --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h @@ -0,0 +1,219 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_sha3_libcrux_ml_kem_H +#define __libcrux_sha3_libcrux_ml_kem_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_add_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_add_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_and_si256( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_andnot_si256( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_blend_epi16( + int32_t x0, core_core_arch_x86___m256i x1, core_core_arch_x86___m256i x2); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_castsi128_si256( + core_core_arch_x86___m128i x0); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm256_castsi256_si128( + core_core_arch_x86___m256i x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_cmpgt_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_cvtepi16_epi32( + core_core_arch_x86___m128i x0); + +extern core_core_arch_x86___m128i +libcrux_intrinsics_avx2_mm256_extracti128_si256(int32_t x0, + core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i +libcrux_intrinsics_avx2_mm256_inserti128_si256(int32_t x0, + core_core_arch_x86___m256i x1, + core_core_arch_x86___m128i x2); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_loadu_si256_i16( + Eurydice_slice x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + Eurydice_slice x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_madd_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mul_epu32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mulhi_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mullo_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mullo_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_packs_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i +libcrux_intrinsics_avx2_mm256_permute2x128_si256(int32_t x0, + core_core_arch_x86___m256i x1, + core_core_arch_x86___m256i x2); + +extern core_core_arch_x86___m256i +libcrux_intrinsics_avx2_mm256_permute4x64_epi64(int32_t x0, + core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i +libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi16( + int16_t x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi32( + int32_t x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi64x( + int64_t x0); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi16( + int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, + int16_t x6, int16_t x7, int16_t x8, int16_t x9, int16_t x10, int16_t x11, + int16_t x12, int16_t x13, int16_t x14, int16_t x15); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi32( + int32_t x0, int32_t x1, int32_t x2, int32_t x3, int32_t x4, int32_t x5, + int32_t x6, int32_t x7); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi8( + int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, + int8_t x7, int8_t x8, int8_t x9, int8_t x10, int8_t x11, int8_t x12, + int8_t x13, int8_t x14, int8_t x15, int8_t x16, int8_t x17, int8_t x18, + int8_t x19, int8_t x20, int8_t x21, int8_t x22, int8_t x23, int8_t x24, + int8_t x25, int8_t x26, int8_t x27, int8_t x28, int8_t x29, int8_t x30, + int8_t x31); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_setzero_si256( + void); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_shuffle_epi32( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_shuffle_epi8( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi16( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi32( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi64( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_sllv_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srai_epi16( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srai_epi32( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi16( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi32( + int32_t x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi64( + int32_t x0, core_core_arch_x86___m256i x1); + +extern void libcrux_intrinsics_avx2_mm256_storeu_si256_i16( + Eurydice_slice x0, core_core_arch_x86___m256i x1); + +extern void libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_sub_epi16( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpackhi_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpackhi_epi64( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpacklo_epi32( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpacklo_epi64( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_xor_si256( + core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_add_epi16( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_loadu_si128( + Eurydice_slice x0); + +extern int32_t libcrux_intrinsics_avx2_mm_movemask_epi8( + core_core_arch_x86___m128i x0); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_mulhi_epi16( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_mullo_epi16( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_packs_epi16( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_set1_epi16( + int16_t x0); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_set_epi8( + uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, + uint8_t x6, uint8_t x7, uint8_t x8, uint8_t x9, uint8_t x10, uint8_t x11, + uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_shuffle_epi8( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +extern void libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_slice x0, core_core_arch_x86___m128i x1); + +extern void libcrux_intrinsics_avx2_mm_storeu_si128( + Eurydice_slice x0, core_core_arch_x86___m128i x1); + +extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_sub_epi16( + core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_libcrux_ml_kem_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index bbc97948d..3d3d86bf4 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 7a7e2c455..0a665654b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 96d12198 + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index ecb22e165..3c67ef508 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -24,150 +24,13 @@ pub const ENCAPS_SEED_SIZE: usize = SHARED_SECRET_SIZE; /// A byte array of size [`SHARED_SECRET_SIZE`]. pub type MlKemSharedSecret = [u8; SHARED_SECRET_SIZE]; -macro_rules! instantiate { - ($modp:ident, $vector:path, $hash:path) => { - pub mod $modp { - use crate::{ - MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey, MlKemSharedSecret, - KEY_GENERATION_SEED_SIZE, SHARED_SECRET_SIZE, - }; +/// This module instantiates the functions in this file and multiplexes between +/// different implementations at runtime. +pub(crate) mod multiplexing; - /// Portable generate key pair. - pub(crate) fn generate_keypair_generic< - const K: usize, - const CPA_PRIVATE_KEY_SIZE: usize, - const PRIVATE_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - >( - randomness: [u8; KEY_GENERATION_SEED_SIZE], - ) -> MlKemKeyPair { - super::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - $vector, - $hash, - >(randomness) - } - - /// Portable public key validation - pub(crate) fn validate_public_key_generic< - const K: usize, - const RANKED_BYTES_PER_RING_ELEMENT: usize, - const PUBLIC_KEY_SIZE: usize, - >( - public_key: &[u8; PUBLIC_KEY_SIZE], - ) -> bool { - super::validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - $vector, - >(public_key) - } - - /// Portable encapsualte - pub(crate) fn encapsulate_generic< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const VECTOR_U_BLOCK_LEN: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, - >( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], - ) -> (MlKemCiphertext, MlKemSharedSecret) { - super::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - $vector, - $hash, - >(public_key, randomness) - } - - /// Portable decapsulate - pub fn decapsulate_generic< - const K: usize, - const SECRET_KEY_SIZE: usize, - const CPA_SECRET_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const C1_BLOCK_SIZE: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, - const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, - >( - private_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, - ) -> MlKemSharedSecret { - super::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - $vector, - $hash, - >(private_key, ciphertext) - } - } - }; -} - -// Portable generic implementations. -instantiate! {portable, crate::vector::PortableVector, crate::hash_functions::portable::PortableHash} - -// AVX2 generic implementation. -#[cfg(feature = "simd256")] -instantiate! {avx2, crate::vector::SIMD256Vector, crate::hash_functions::avx2::Simd256Hash} - -// NEON generic implementation. -#[cfg(feature = "simd128")] -instantiate! {neon, crate::vector::SIMD128Vector, crate::hash_functions::neon::Simd128Hash} +/// This module instantiates the functions in this file for each platform. +/// To use these, runtime checks must be performed before calling them. +pub(crate) mod instantiations; /// Serialize the secret key. #[inline(always)] @@ -189,49 +52,8 @@ fn serialize_kem_secret_key( - public_key: &[u8; PUBLIC_KEY_SIZE], -) -> bool { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return avx2::validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - portable::validate_public_key_generic::( - public_key, - ) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return neon::validate_public_key_generic::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key); - #[cfg(not(feature = "simd128"))] - portable::validate_public_key_generic::( - public_key, - ) - } else { - portable::validate_public_key_generic::( - public_key, - ) - } -} - -fn validate_public_key_generic< +#[inline(always)] +fn validate_public_key< const K: usize, const RANKED_BYTES_PER_RING_ELEMENT: usize, const PUBLIC_KEY_SIZE: usize, @@ -251,84 +73,11 @@ fn validate_public_key_generic< *public_key == public_key_serialized } -pub(crate) fn generate_keypair< - const K: usize, - const CPA_PRIVATE_KEY_SIZE: usize, - const PRIVATE_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, ->( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> MlKemKeyPair { - // Runtime feature detection. - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return avx2::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - portable::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return neon::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness); - #[cfg(not(feature = "simd128"))] - portable::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) - } else { - portable::generate_keypair_generic::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) - } -} - /// Generate a key pair. /// /// Depending on the `Vector` and `Hasher` used, this requires different hardware /// features -fn generate_keypair_generic< +fn generate_keypair< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, const PRIVATE_KEY_SIZE: usize, @@ -366,116 +115,7 @@ fn generate_keypair_generic< MlKemKeyPair::from(private_key, MlKemPublicKey::from(public_key)) } -pub(crate) fn encapsulate< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const VECTOR_U_BLOCK_LEN: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, ->( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], -) -> (MlKemCiphertext, MlKemSharedSecret) { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return avx2::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - portable::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { - #[cfg(not(feature = "simd128"))] - return portable::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - neon::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) - } else { - portable::encapsulate_generic::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) - } -} - -fn encapsulate_generic< +fn encapsulate< const K: usize, const CIPHERTEXT_SIZE: usize, const PUBLIC_KEY_SIZE: usize, @@ -539,133 +179,6 @@ pub(crate) fn decapsulate< const ETA2: usize, const ETA2_RANDOMNESS_SIZE: usize, const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, ->( - private_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, -) -> MlKemSharedSecret { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] - return avx2::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] - return portable::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - return neon::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - #[cfg(not(feature = "simd128"))] - return portable::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - } else { - portable::decapsulate_generic::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext) - } -} - -pub(crate) fn decapsulate_generic< - const K: usize, - const SECRET_KEY_SIZE: usize, - const CPA_SECRET_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const C1_BLOCK_SIZE: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, - const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, Vector: Operations, Hasher: Hash, >( diff --git a/libcrux-ml-kem/src/ind_cca/instantiations.rs b/libcrux-ml-kem/src/ind_cca/instantiations.rs new file mode 100644 index 000000000..0df88acef --- /dev/null +++ b/libcrux-ml-kem/src/ind_cca/instantiations.rs @@ -0,0 +1,144 @@ +macro_rules! instantiate { + ($modp:ident, $vector:path, $hash:path) => { + pub mod $modp { + use crate::{ + MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey, MlKemSharedSecret, + KEY_GENERATION_SEED_SIZE, SHARED_SECRET_SIZE, + }; + + /// Portable generate key pair. + pub(crate) fn generate_keypair< + const K: usize, + const CPA_PRIVATE_KEY_SIZE: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + >( + randomness: [u8; KEY_GENERATION_SEED_SIZE], + ) -> MlKemKeyPair { + crate::ind_cca::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + $vector, + $hash, + >(randomness) + } + + /// Portable public key validation + pub(crate) fn validate_public_key< + const K: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + const PUBLIC_KEY_SIZE: usize, + >( + public_key: &[u8; PUBLIC_KEY_SIZE], + ) -> bool { + crate::ind_cca::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + $vector, + >(public_key) + } + + /// Portable encapsualte + pub(crate) fn encapsulate< + const K: usize, + const CIPHERTEXT_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const VECTOR_U_BLOCK_LEN: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, + >( + public_key: &MlKemPublicKey, + randomness: [u8; SHARED_SECRET_SIZE], + ) -> (MlKemCiphertext, MlKemSharedSecret) { + crate::ind_cca::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + $vector, + $hash, + >(public_key, randomness) + } + + /// Portable decapsulate + pub fn decapsulate< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const CIPHERTEXT_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const C1_BLOCK_SIZE: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, + const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + ciphertext: &MlKemCiphertext, + ) -> MlKemSharedSecret { + crate::ind_cca::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + $vector, + $hash, + >(private_key, ciphertext) + } + } + }; +} + +// Portable generic implementations. +instantiate! {portable, crate::vector::PortableVector, crate::hash_functions::portable::PortableHash} + +// AVX2 generic implementation. +#[cfg(feature = "simd256")] +instantiate! {avx2, crate::vector::SIMD256Vector, crate::hash_functions::avx2::Simd256Hash} + +// NEON generic implementation. +#[cfg(feature = "simd128")] +instantiate! {neon, crate::vector::SIMD128Vector, crate::hash_functions::neon::Simd128Hash} diff --git a/libcrux-ml-kem/src/ind_cca/multiplexing.rs b/libcrux-ml-kem/src/ind_cca/multiplexing.rs new file mode 100644 index 000000000..513ebca3f --- /dev/null +++ b/libcrux-ml-kem/src/ind_cca/multiplexing.rs @@ -0,0 +1,358 @@ +use super::*; + +pub(crate) fn validate_public_key< + const K: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + const PUBLIC_KEY_SIZE: usize, +>( + public_key: &[u8; PUBLIC_KEY_SIZE], +) -> bool { + if cfg!(feature = "simd256") + && cfg!(target_arch = "x86_64") + && libcrux_platform::simd256_support() + { + #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + return instantiations::avx2::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + >(public_key); + #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + instantiations::portable::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + >(public_key) + } else if cfg!(feature = "simd128") + && cfg!(target_arch = "aarch64") + && libcrux_platform::simd128_support() + { + #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + return instantiations::neon::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + >(public_key); + #[cfg(not(feature = "simd128"))] + instantiations::portable::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + >(public_key) + } else { + instantiations::portable::validate_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + >(public_key) + } +} + +pub(crate) fn generate_keypair< + const K: usize, + const CPA_PRIVATE_KEY_SIZE: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, +>( + randomness: [u8; KEY_GENERATION_SEED_SIZE], +) -> MlKemKeyPair { + // Runtime feature detection. + if cfg!(feature = "simd256") + && cfg!(target_arch = "x86_64") + && libcrux_platform::simd256_support() + { + #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + return instantiations::avx2::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness); + #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + instantiations::portable::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } else if cfg!(feature = "simd128") + && cfg!(target_arch = "aarch64") + && libcrux_platform::simd128_support() + { + #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + return instantiations::neon::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness); + #[cfg(not(feature = "simd128"))] + instantiations::portable::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } else { + instantiations::portable::generate_keypair::< + K, + CPA_PRIVATE_KEY_SIZE, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } +} + +pub(crate) fn encapsulate< + const K: usize, + const CIPHERTEXT_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const VECTOR_U_BLOCK_LEN: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, +>( + public_key: &MlKemPublicKey, + randomness: [u8; SHARED_SECRET_SIZE], +) -> (MlKemCiphertext, MlKemSharedSecret) { + if cfg!(feature = "simd256") + && cfg!(target_arch = "x86_64") + && libcrux_platform::simd256_support() + { + #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + return instantiations::avx2::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness); + #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + instantiations::portable::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } else if cfg!(feature = "simd128") + && cfg!(target_arch = "aarch64") + && libcrux_platform::simd128_support() + { + #[cfg(not(feature = "simd128"))] + return instantiations::portable::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness); + #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + instantiations::neon::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } else { + instantiations::portable::encapsulate::< + K, + CIPHERTEXT_SIZE, + PUBLIC_KEY_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + VECTOR_U_BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } +} + +pub(crate) fn decapsulate< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const CIPHERTEXT_SIZE: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + const C1_SIZE: usize, + const C2_SIZE: usize, + const VECTOR_U_COMPRESSION_FACTOR: usize, + const VECTOR_V_COMPRESSION_FACTOR: usize, + const C1_BLOCK_SIZE: usize, + const ETA1: usize, + const ETA1_RANDOMNESS_SIZE: usize, + const ETA2: usize, + const ETA2_RANDOMNESS_SIZE: usize, + const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, +>( + private_key: &MlKemPrivateKey, + ciphertext: &MlKemCiphertext, +) -> MlKemSharedSecret { + if cfg!(feature = "simd256") + && cfg!(target_arch = "x86_64") + && libcrux_platform::simd256_support() + { + #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + return instantiations::avx2::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext); + #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + return instantiations::portable::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext); + } else if cfg!(feature = "simd128") + && cfg!(target_arch = "aarch64") + && libcrux_platform::simd128_support() + { + #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + return instantiations::neon::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext); + #[cfg(not(feature = "simd128"))] + return instantiations::portable::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext); + } else { + instantiations::portable::decapsulate::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_SIZE, + C2_SIZE, + VECTOR_U_COMPRESSION_FACTOR, + VECTOR_V_COMPRESSION_FACTOR, + C1_BLOCK_SIZE, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext) + } +} diff --git a/libcrux-ml-kem/src/mlkem1024.rs b/libcrux-ml-kem/src/mlkem1024.rs index 3fbbd251d..8ca4e0cec 100644 --- a/libcrux-ml-kem/src/mlkem1024.rs +++ b/libcrux-ml-kem/src/mlkem1024.rs @@ -49,7 +49,7 @@ pub type MlKem1024KeyPair = MlKemKeyPair Option { - if ind_cca::validate_public_key::< + if multiplexing::validate_public_key::< RANK_1024, RANKED_BYTES_PER_RING_ELEMENT_1024, CPA_PKE_PUBLIC_KEY_SIZE_1024, @@ -70,7 +70,7 @@ pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option MlKemKeyPair { - generate_keypair::< + multiplexing::generate_keypair::< RANK_1024, CPA_PKE_SECRET_KEY_SIZE_1024, SECRET_KEY_SIZE_1024, @@ -90,7 +90,7 @@ pub fn encapsulate( public_key: &MlKem1024PublicKey, randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKem1024Ciphertext, MlKemSharedSecret) { - ind_cca::encapsulate::< + multiplexing::encapsulate::< RANK_1024, CPA_PKE_CIPHERTEXT_SIZE_1024, CPA_PKE_PUBLIC_KEY_SIZE_1024, @@ -115,7 +115,7 @@ pub fn decapsulate( private_key: &MlKem1024PrivateKey, ciphertext: &MlKem1024Ciphertext, ) -> MlKemSharedSecret { - ind_cca::decapsulate::< + multiplexing::decapsulate::< RANK_1024, SECRET_KEY_SIZE_1024, CPA_PKE_SECRET_KEY_SIZE_1024, diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index d5dc4ab47..32c8a6118 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -47,7 +47,7 @@ pub type MlKem512KeyPair = MlKemKeyPair Option { - if ind_cca::validate_public_key::< + if multiplexing::validate_public_key::< RANK_512, RANKED_BYTES_PER_RING_ELEMENT_512, CPA_PKE_PUBLIC_KEY_SIZE_512, @@ -66,7 +66,7 @@ pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option MlKem512KeyPair { - generate_keypair::< + multiplexing::generate_keypair::< RANK_512, CPA_PKE_SECRET_KEY_SIZE_512, SECRET_KEY_SIZE_512, @@ -86,7 +86,7 @@ pub fn encapsulate( public_key: &MlKem512PublicKey, randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKem512Ciphertext, MlKemSharedSecret) { - ind_cca::encapsulate::< + multiplexing::encapsulate::< RANK_512, CPA_PKE_CIPHERTEXT_SIZE_512, CPA_PKE_PUBLIC_KEY_SIZE_512, @@ -111,7 +111,7 @@ pub fn decapsulate( private_key: &MlKem512PrivateKey, ciphertext: &MlKem512Ciphertext, ) -> MlKemSharedSecret { - ind_cca::decapsulate::< + multiplexing::decapsulate::< RANK_512, SECRET_KEY_SIZE_512, CPA_PKE_SECRET_KEY_SIZE_512, diff --git a/libcrux-ml-kem/src/mlkem768.rs b/libcrux-ml-kem/src/mlkem768.rs index 132f33680..9fa1b03f3 100644 --- a/libcrux-ml-kem/src/mlkem768.rs +++ b/libcrux-ml-kem/src/mlkem768.rs @@ -55,7 +55,7 @@ macro_rules! instantiate { /// /// Returns `Some(public_key)` if valid, and `None` otherwise. pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option { - if p::validate_public_key_generic::< + if p::validate_public_key::< RANK_768, RANKED_BYTES_PER_RING_ELEMENT_768, CPA_PKE_PUBLIC_KEY_SIZE_768, @@ -71,7 +71,7 @@ macro_rules! instantiate { pub fn generate_key_pair( randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> MlKem768KeyPair { - p::generate_keypair_generic::< + p::generate_keypair::< RANK_768, CPA_PKE_SECRET_KEY_SIZE_768, SECRET_KEY_SIZE_768, @@ -91,7 +91,7 @@ macro_rules! instantiate { public_key: &MlKem768PublicKey, randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKem768Ciphertext, MlKemSharedSecret) { - p::encapsulate_generic::< + p::encapsulate::< RANK_768, CPA_PKE_CIPHERTEXT_SIZE_768, CPA_PKE_PUBLIC_KEY_SIZE_768, @@ -116,7 +116,7 @@ macro_rules! instantiate { private_key: &MlKem768PrivateKey, ciphertext: &MlKem768Ciphertext, ) -> MlKemSharedSecret { - p::decapsulate_generic::< + p::decapsulate::< RANK_768, SECRET_KEY_SIZE_768, CPA_PKE_SECRET_KEY_SIZE_768, @@ -141,17 +141,17 @@ macro_rules! instantiate { // Instantiations -instantiate! {portable, ind_cca::portable} +instantiate! {portable, ind_cca::instantiations::portable} #[cfg(feature = "simd256")] -instantiate! {avx2, ind_cca::avx2} +instantiate! {avx2, ind_cca::instantiations::avx2} #[cfg(feature = "simd128")] -instantiate! {neon, ind_cca::neon} +instantiate! {neon, ind_cca::instantiations::neon} /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option { - if ind_cca::validate_public_key::< + if multiplexing::validate_public_key::< RANK_768, RANKED_BYTES_PER_RING_ELEMENT_768, CPA_PKE_PUBLIC_KEY_SIZE_768, @@ -177,7 +177,7 @@ pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option MlKem768KeyPair { - generate_keypair::< + multiplexing::generate_keypair::< RANK_768, CPA_PKE_SECRET_KEY_SIZE_768, SECRET_KEY_SIZE_768, @@ -197,7 +197,7 @@ pub fn encapsulate( public_key: &MlKem768PublicKey, randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKem768Ciphertext, MlKemSharedSecret) { - ind_cca::encapsulate::< + multiplexing::encapsulate::< RANK_768, CPA_PKE_CIPHERTEXT_SIZE_768, CPA_PKE_PUBLIC_KEY_SIZE_768, @@ -222,7 +222,7 @@ pub fn decapsulate( private_key: &MlKem768PrivateKey, ciphertext: &MlKem768Ciphertext, ) -> MlKemSharedSecret { - ind_cca::decapsulate::< + multiplexing::decapsulate::< RANK_768, SECRET_KEY_SIZE_768, CPA_PKE_SECRET_KEY_SIZE_768, From 34fc123b52d1499aa681c0a22240512c7581d859 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 5 Jun 2024 15:54:59 +0200 Subject: [PATCH 06/84] ci: update cargo dependencies --- .github/workflows/hax.yml | 3 +++ .github/workflows/mldsa.yml | 3 +++ .github/workflows/mlkem.yml | 6 ++++++ .github/workflows/platform.yml | 3 +++ .github/workflows/rust.yml | 3 +++ .github/workflows/specs.yml | 3 +++ 6 files changed, 21 insertions(+) diff --git a/.github/workflows/hax.yml b/.github/workflows/hax.yml index 9f7b6fc2d..c6f4f4748 100644 --- a/.github/workflows/hax.yml +++ b/.github/workflows/hax.yml @@ -28,6 +28,9 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Update dependencies + run: cargo update + - name: ⤵ Install FStar run: nix profile install github:FStarLang/FStar/v2024.01.13 diff --git a/.github/workflows/mldsa.yml b/.github/workflows/mldsa.yml index 03b6d91ad..a05d1e6c3 100644 --- a/.github/workflows/mldsa.yml +++ b/.github/workflows/mldsa.yml @@ -41,6 +41,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update dependencies + run: cargo update + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV if: ${{ matrix.bits == 64 }} diff --git a/.github/workflows/mlkem.yml b/.github/workflows/mlkem.yml index fe43c3025..4f3ed7102 100644 --- a/.github/workflows/mlkem.yml +++ b/.github/workflows/mlkem.yml @@ -41,6 +41,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update dependencies + run: cargo update + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV if: ${{ matrix.bits == 64 }} @@ -168,6 +171,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update dependencies + run: cargo update + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV if: ${{ matrix.bits == 64 }} diff --git a/.github/workflows/platform.yml b/.github/workflows/platform.yml index 84c4bf71f..796fd6956 100644 --- a/.github/workflows/platform.yml +++ b/.github/workflows/platform.yml @@ -41,6 +41,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update dependencies + run: cargo update + - name: 🔨 Build run: cargo build --verbose diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8f781c1f1..ee0e3f090 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -40,6 +40,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update dependencies + run: cargo update + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV if: ${{ matrix.bits == 64 }} diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml index 043d3d801..83a79e802 100644 --- a/.github/workflows/specs.yml +++ b/.github/workflows/specs.yml @@ -41,6 +41,9 @@ jobs: - uses: actions/checkout@v3 + - name: Update dependencies + run: cargo update + - name: Build working-directory: specs run: cargo build --verbose From b52a87fb110e1152f8297be9cf20ddfcf67da521 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 5 Jun 2024 15:00:30 +0200 Subject: [PATCH 07/84] fix --- libcrux-ml-kem/c/CMakeLists.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 1db8cb438..25829913a 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -108,13 +108,7 @@ target_link_libraries(sha3_test PRIVATE # --- Benchmarks -FetchContent_Populate(benchmark - GIT_REPOSITORY https://github.com/google/benchmark.git - # The latest release 1.7.1 is broken due to https://github.com/google/benchmark/pull/1517 - # But also: need the fix for https://github.com/google/benchmark/pull/1669 - GIT_TAG bc946b919cac6f25a199a526da571638cfde109f -) -add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR}) +find_package(benchmark) add_executable(ml_kem_bench ${PROJECT_SOURCE_DIR}/benches/mlkem768.cc From 657a6eb5453fb1d96911d26b3a3c16fb3d921c2b Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 5 Jun 2024 10:46:42 +0200 Subject: [PATCH 08/84] nix --- .github/workflows/nix.yml | 13 ++ flake.lock | 434 ++++++++++++++++++++++++++++++++++++++ flake.nix | 77 +++++++ 3 files changed, 524 insertions(+) create mode 100644 .github/workflows/nix.yml create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 000000000..29db314d8 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,13 @@ +name: Nix + +on: + push: + branches: [main] + +jobs: + nix: + runs-on: ubuntu-latest + steps: + - uses: DeterminateSystems/nix-installer-action@v12 + - uses: actions/checkout@v4 + - run: nix build -L .#ml-kem diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..c06ddd613 --- /dev/null +++ b/flake.lock @@ -0,0 +1,434 @@ +{ + "nodes": { + "charon": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": [ + "eurydice", + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1717577599, + "narHash": "sha256-5LxkX4sCtd82/h3WXkbDP4eWQMP+7Wd2xhg6xLQXQV4=", + "owner": "aeneasverif", + "repo": "charon", + "rev": "a00876a9cd94e9ac63dbb71dae3df337b568dba3", + "type": "github" + }, + "original": { + "owner": "aeneasverif", + "repo": "charon", + "type": "github" + } + }, + "crane": { + "inputs": { + "nixpkgs": [ + "charon", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717535930, + "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717535930, + "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "eurydice": { + "inputs": { + "charon": [ + "charon" + ], + "flake-utils": "flake-utils_2", + "fstar": "fstar", + "karamel": "karamel", + "nixpkgs": [ + "eurydice", + "karamel", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717520324, + "narHash": "sha256-w20SD6lKSjE5Zc7dLnCceF9EOHCZbWxyMDgqVds4f28=", + "owner": "aeneasverif", + "repo": "eurydice", + "rev": "9f8d759db7e7c8dfb406e1b373d316aadc5cdd98", + "type": "github" + }, + "original": { + "owner": "aeneasverif", + "repo": "eurydice", + "type": "github" + } + }, + "flake-compat": { + "locked": { + "lastModified": 1688025799, + "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=", + "owner": "nix-community", + "repo": "flake-compat", + "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1692799911, + "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1692799911, + "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fstar": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1716897445, + "narHash": "sha256-Ytz9l3PjhBHULVZphHoUj15Ad8Wq3cIK6Paus32NB1w=", + "owner": "FStarLang", + "repo": "fstar", + "rev": "9820798dcc31cd1ea5c164611a67f58ade0b7655", + "type": "github" + }, + "original": { + "owner": "FStarLang", + "repo": "fstar", + "type": "github" + } + }, + "fstar_2": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1716897445, + "narHash": "sha256-Ytz9l3PjhBHULVZphHoUj15Ad8Wq3cIK6Paus32NB1w=", + "owner": "fstarlang", + "repo": "fstar", + "rev": "9820798dcc31cd1ea5c164611a67f58ade0b7655", + "type": "github" + }, + "original": { + "owner": "fstarlang", + "repo": "fstar", + "type": "github" + } + }, + "karamel": { + "inputs": { + "flake-utils": [ + "eurydice", + "karamel", + "fstar", + "flake-utils" + ], + "fstar": "fstar_2", + "nixpkgs": [ + "eurydice", + "karamel", + "fstar", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717454922, + "narHash": "sha256-3yseAxgtqchKisDIWvU2hxC5rqNbQd7HDAPo28Gnzpk=", + "owner": "FStarLang", + "repo": "karamel", + "rev": "749859845fed65d9391f4ba318c8cf27292a85ce", + "type": "github" + }, + "original": { + "owner": "FStarLang", + "repo": "karamel", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1693158576, + "narHash": "sha256-aRTTXkYvhXosGx535iAFUaoFboUrZSYb1Ooih/auGp0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a999c1cc0c9eb2095729d5aa03e0d8f7ed256780", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1693158576, + "narHash": "sha256-aRTTXkYvhXosGx535iAFUaoFboUrZSYb1Ooih/auGp0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a999c1cc0c9eb2095729d5aa03e0d8f7ed256780", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1717196966, + "narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "charon": "charon", + "crane": "crane_2", + "eurydice": "eurydice", + "flake-utils": "flake-utils_5", + "fstar": [ + "eurydice", + "fstar" + ], + "karamel": [ + "eurydice", + "karamel" + ], + "nixpkgs": "nixpkgs_3" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "charon", + "flake-utils" + ], + "nixpkgs": [ + "charon", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1701656211, + "narHash": "sha256-lfFXsLWH4hVbEKR6K+UcDiKxeS6Lz4FkC1DZ9LHqf9Y=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "47a276e820ae4ae1b8d98a503bf09d2ceb52dfd8", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..7af9a4342 --- /dev/null +++ b/flake.nix @@ -0,0 +1,77 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + charon = { + url = "github:aeneasverif/charon"; + inputs.nixpkgs.follows = "eurydice/nixpkgs"; + }; + eurydice = { + url = "github:aeneasverif/eurydice"; + inputs.charon.follows = "charon"; + }; + fstar.follows = "eurydice/fstar"; + karamel.follows = "eurydice/karamel"; + }; + + outputs = + inputs: + inputs.flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = import inputs.nixpkgs { inherit system; }; + googletest = pkgs.fetchzip { + url = "https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip"; + sha256 = "SjlJxushfry13RGA7BCjYC9oZqV4z6x8dOiHfl/wpF0="; + }; + json = pkgs.fetchzip { + url = "https://github.com/nlohmann/json/archive/refs/tags/v3.10.3.zip"; + sha256 = "EBzwaHyDWF8h/z3Zfq4p/n5Vpz7Ozlc3eoWDKXWv2YY="; + }; + craneLib = inputs.crane.mkLib pkgs; + src = ./.; + cargoArtifacts = craneLib.buildDepsOnly { inherit src; }; + ml-kem = craneLib.buildPackage { + inherit src cargoArtifacts; + name = "ml-kem"; + nativeBuildInputs = [ + pkgs.clang + pkgs.cmake + pkgs.gbenchmark + pkgs.ninja + pkgs.python3 + ]; + buildPhase = '' + cd libcrux-ml-kem + bash c.sh + ''; + checkPhase = '' + cd c + cmake \ + -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ + -DFETCHCONTENT_SOURCE_DIR_JSON=${json} \ + -G "Ninja Multi-Config" -B build + cmake --build build --config Release + ''; + installPhase = "cp -r . $out"; + CHARON_HOME = inputs.charon.packages.${system}.default; + EURYDICE_HOME = pkgs.runCommand "eurydice-home" { } '' + mkdir -p $out + cp -r ${inputs.eurydice.packages.${system}.default}/bin/eurydice $out + cp -r ${inputs.eurydice}/include $out + ''; + FSTAR_HOME = inputs.fstar.packages.${system}.default; + KRML_HOME = inputs.karamel.packages.${system}.default.home; + }; + in + { + packages = { + inherit ml-kem; + }; + } + ); +} From 831056086156f5545fd1ee75b24cbc6513ce2caa Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 5 Jun 2024 16:36:12 +0200 Subject: [PATCH 09/84] update' --- libcrux-ml-kem/c.yaml | 40 +- libcrux-ml-kem/c/CMakeLists.txt | 19 +- libcrux-ml-kem/c/internal/libcrux_core.h | 94 +- .../c/internal/libcrux_mlkem768_portable.h | 143 - .../c/internal/libcrux_mlkem_avx2.h | 34 +- .../c/internal/libcrux_polynomial.h | 24 +- libcrux-ml-kem/c/libcrux_core.c | 178 +- libcrux-ml-kem/c/libcrux_core.h | 58 +- libcrux-ml-kem/c/libcrux_mlkem1024.c | 60 +- libcrux-ml-kem/c/libcrux_mlkem512.c | 1555 +--------- libcrux-ml-kem/c/libcrux_mlkem512.h | 39 +- libcrux-ml-kem/c/libcrux_mlkem768.c | 1532 ++++++++- libcrux-ml-kem/c/libcrux_mlkem768.h | 39 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 38 - libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 18 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 2197 +------------ libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 21 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 2744 ++++++++--------- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 1 - libcrux-ml-kem/c/libcrux_polynomial.c | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 1 - .../c/libcrux_sha3_libcrux_ml_kem.h | 219 -- libcrux-ml-kem/src/ind_cca/multiplexing.rs | 40 +- libcrux-ml-kem/src/mlkem1024.rs | 103 + libcrux-ml-kem/src/mlkem512.rs | 103 + 25 files changed, 3461 insertions(+), 5845 deletions(-) delete mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 4348c51aa..513ca98e4 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -1,17 +1,17 @@ files: # INTRINSICS - # - name: libcrux_intrinsics_neon - # library: true - # inline_static: true - # api: - # - [libcrux_intrinsics, arm64] + - name: libcrux_intrinsics_neon + library: true + inline_static: true + api: + - [libcrux_intrinsics, arm64] - # - name: libcrux_intrinsics_avx2 - # library: true - # inline_static: true - # api: - # - [libcrux_intrinsics, avx2] + - name: libcrux_intrinsics_avx2 + library: true + inline_static: true + api: + - [libcrux_intrinsics, avx2] - name: libcrux_platform api: @@ -178,6 +178,16 @@ files: api: - [libcrux_ml_kem, hash_functions, avx2, "*"] + - name: libcrux_mlkem512_avx2 + api: + - [libcrux_ml_kem, mlkem512, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + + - name: libcrux_mlkem512_portable + api: + - [libcrux_ml_kem, mlkem512, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + - name: libcrux_mlkem512 api: - [libcrux_ml_kem, mlkem512] @@ -196,6 +206,16 @@ files: api: - [libcrux_ml_kem, mlkem768] + - name: libcrux_mlkem1024_avx2 + api: + - [libcrux_ml_kem, mlkem1024, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + + - name: libcrux_mlkem1024_portable + api: + - [libcrux_ml_kem, mlkem1024, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + - name: libcrux_mlkem1024 api: - [libcrux_ml_kem, mlkem1024] diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 1db8cb438..d50b9be3d 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -11,6 +11,7 @@ project(libcrux-ml-kem ) set(CMAKE_C_STANDARD 11) +#FIXME: Windows? add_compile_options( -Wall # -Wextra @@ -21,7 +22,6 @@ add_compile_options( $<$:-Og> $<$:-g> $<$:-O3> - -fno-omit-frame-pointer -flto ) add_link_options(-flto) @@ -34,21 +34,24 @@ include_directories( file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/libcrux_core.c ${PROJECT_SOURCE_DIR}/libcrux_platform.c - ${PROJECT_SOURCE_DIR}/libcrux_mlkem512.c - ${PROJECT_SOURCE_DIR}/libcrux_mlkem768.c - ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_portable.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_portable.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_portable.c ${PROJECT_SOURCE_DIR}/libcrux_polynomial.c ) # file(GLOB VEC128_SOURCES -# libcrux_sha3_neon.c +# ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_neon.c +# ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_neon.c +# ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_neon.c +# ${PROJECT_SOURCE_DIR}/libcrux_sha3_neon.c # ) file(GLOB SOURCES_vec256 - ${PROJECT_SOURCE_DIR}/libcrux_mlkem_avx2.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_avx2.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_avx2.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_avx2.c ${PROJECT_SOURCE_DIR}/libcrux_sha3_avx2.c ) -# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) - if(${CMAKE_SYSTEM_NAME} MATCHES Linux) add_compile_options( -fPIC diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 36a6ebec0..000eda9e3 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -44,49 +44,6 @@ void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( #define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) -libcrux_ml_kem_types_MlKemPublicKey____800size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk); - -libcrux_ml_kem_types_MlKemPrivateKey____1632size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U]); - -typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s { - uint8_t fst[768U]; - uint8_t snd[800U]; -} K___uint8_t_768size_t__uint8_t_800size_t_; - -libcrux_ml_kem_types_MlKemCiphertext____768size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U]); - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self); - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, Eurydice_slice rhs); - -typedef struct - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); - -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]); - libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uint8_t value[1568U]); @@ -154,12 +111,55 @@ uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( Eurydice_slice lhs, Eurydice_slice rhs); +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self); + +void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]); + +libcrux_ml_kem_types_MlKemPublicKey____800size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uint8_t value[800U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk); + +libcrux_ml_kem_types_MlKemPrivateKey____1632size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uint8_t value[1632U]); + +typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s { + uint8_t fst[768U]; + uint8_t snd[800U]; +} K___uint8_t_768size_t__uint8_t_800size_t_; + +libcrux_ml_kem_types_MlKemCiphertext____768size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uint8_t value[768U]); + +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self); + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + Eurydice_slice lhs, Eurydice_slice rhs); + typedef struct K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { Eurydice_slice fst; Eurydice_slice snd; } K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; +typedef struct + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; + void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); @@ -179,11 +179,11 @@ typedef struct } K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self); +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]); +void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]); void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h deleted file mode 100644 index f5fcb4e07..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem768_portable.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_mlkem768_portable_H -#define __internal_libcrux_mlkem768_portable_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_mlkem768_portable.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - Eurydice_slice serialized); - -void libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer, size_t _initial_coefficient_bound); - -void libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound); - -void libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound); - -void libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound); - -void libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_slice serialized); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized); - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer); - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer); - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer); - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer); - -void libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - uint8_t ret[32U]); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice randomness); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_slice randomness); - -void libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uint8_t serialized[32U]); - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]); - -void libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice serialized); - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice out); - -void libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[384U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_mlkem768_portable_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 4c7241790..d0aac553a 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -18,23 +18,6 @@ extern "C" { #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_avx2.h" -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key); @@ -69,6 +52,23 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]); +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/internal/libcrux_polynomial.h b/libcrux-ml-kem/c/internal/libcrux_polynomial.h index 2c122c65d..ba1228d32 100644 --- a/libcrux-ml-kem/c/internal/libcrux_polynomial.h +++ b/libcrux-ml-kem/c/internal/libcrux_polynomial.h @@ -135,26 +135,26 @@ libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_m Eurydice_slice a, Eurydice_slice out); typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t_s { + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[2U]; + fst[4U]; uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t; +} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t; -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *rhs); typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t_s { + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[4U]; + fst[3U]; uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t; +} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t; -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector @@ -202,11 +202,11 @@ void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElemen *error); typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t_s { + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[3U]; + fst[2U]; uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t; +} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector( @@ -227,7 +227,7 @@ libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vec libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector b); -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 8b69e17c9..7fc937466 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -50,87 +50,6 @@ void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemPublicKey____800size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U]) { - uint8_t uu____0[800U]; - memcpy(uu____0, value, (size_t)800U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey____800size_t lit; - memcpy(lit.value, uu____0, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ - .sk = sk, .pk = pk}); -} - -libcrux_ml_kem_types_MlKemPrivateKey____1632size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U]) { - uint8_t uu____0[1632U]; - memcpy(uu____0, value, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t lit; - memcpy(lit.value, uu____0, (size_t)1632U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemCiphertext____768size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U]) { - uint8_t uu____0[768U]; - memcpy(uu____0, value, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t lit; - memcpy(lit.value, uu____0, (size_t)768U * sizeof(uint8_t)); - return lit; -} - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self) { - return self->value; -} - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, Eurydice_slice rhs) { - uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)768U; i++) { - size_t i0 = i; - uint8_t uu____0 = - Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = (uint32_t)r | - ((uint32_t)uu____0 ^ - (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); - } - return is_non_zero(r); -} - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self) { - return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, - Eurydice_slice); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]) { - uint8_t out[800U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)800U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)800U * sizeof(uint8_t)); -} - libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uint8_t value[1568U]) { @@ -271,6 +190,87 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size return is_non_zero(r); } +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self) { + return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, + Eurydice_slice); +} + +void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]) { + uint8_t out[1120U] = {0U}; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1120U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemPublicKey____800size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uint8_t value[800U]) { + uint8_t uu____0[800U]; + memcpy(uu____0, value, (size_t)800U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey____800size_t lit; + memcpy(lit.value, uu____0, (size_t)800U * sizeof(uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk) { + return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ + .sk = sk, .pk = pk}); +} + +libcrux_ml_kem_types_MlKemPrivateKey____1632size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uint8_t value[1632U]) { + uint8_t uu____0[1632U]; + memcpy(uu____0, value, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t lit; + memcpy(lit.value, uu____0, (size_t)1632U * sizeof(uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemCiphertext____768size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uint8_t value[768U]) { + uint8_t uu____0[768U]; + memcpy(uu____0, value, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t lit; + memcpy(lit.value, uu____0, (size_t)768U * sizeof(uint8_t)); + return lit; +} + +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self) { + return self->value; +} + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + Eurydice_slice lhs, Eurydice_slice rhs) { + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < (size_t)768U; i++) { + size_t i0 = i; + uint8_t uu____0 = + Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = (uint32_t)r | + ((uint32_t)uu____0 ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + } + return is_non_zero(r); +} + void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]) { uint8_t out[33U] = {0U}; @@ -302,25 +302,25 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, } Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self) { - return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self) { + return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, Eurydice_slice); } -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]) { - uint8_t out[1120U] = {0U}; +void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]) { + uint8_t out[800U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)1120U, uu____0, + (size_t)800U, uu____0, ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), slice, uint8_t, void *); - memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)800U * sizeof(uint8_t)); } void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 45892cc6d..049652436 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -37,35 +37,6 @@ static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); -typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { - uint8_t value[800U]; -} libcrux_ml_kem_types_MlKemPublicKey____800size_t; - -typedef struct - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s { - core_option_Option__size_t_tags tag; - libcrux_ml_kem_types_MlKemPublicKey____800size_t f0; -} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; - -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { - uint8_t value[1632U]; -} libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; - -typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s { - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk; - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; - -typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { - uint8_t value[768U]; -} libcrux_ml_kem_types_MlKemCiphertext____768size_t; - -typedef struct - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____768size_t fst; - uint8_t snd[32U]; -} K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; - typedef struct libcrux_ml_kem_types_MlKemPublicKey____1568size_t_s { uint8_t value[1568U]; } libcrux_ml_kem_types_MlKemPublicKey____1568size_t; @@ -124,6 +95,35 @@ typedef struct uint8_t snd[32U]; } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; +typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { + uint8_t value[800U]; +} libcrux_ml_kem_types_MlKemPublicKey____800size_t; + +typedef struct + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s { + core_option_Option__size_t_tags tag; + libcrux_ml_kem_types_MlKemPublicKey____800size_t f0; +} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; + +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { + uint8_t value[1632U]; +} libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; + +typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s { + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk; + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk; +} libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; + +typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { + uint8_t value[768U]; +} libcrux_ml_kem_types_MlKemCiphertext____768size_t; + +typedef struct + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s { + libcrux_ml_kem_types_MlKemCiphertext____768size_t fst; + uint8_t snd[32U]; +} K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; + #define core_result_Ok 0 #define core_result_Err 1 diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c index ed08e6f30..2a747078e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.c @@ -8,7 +8,7 @@ #include "libcrux_mlkem1024.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem768_portable.h" +#include "internal/libcrux_mlkem512_portable.h" #include "internal/libcrux_mlkem_avx2.h" #include "internal/libcrux_polynomial.h" #include "internal/libcrux_sha3_internal.h" @@ -1102,11 +1102,15 @@ decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_140 if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } @@ -1225,14 +1229,22 @@ encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11si uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + } else { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6); return uu____0; } - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); return uu____0; } @@ -1597,13 +1609,19 @@ generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_1 uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uu____1); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____2); + } else { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____3); } - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____2); return uu____0; } @@ -1701,11 +1719,15 @@ static bool validate_public_key___4size_t_1536size_t_1568size_t( uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( public_key); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); + } else { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); } - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); return uu____0; } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c index ec48227d1..00bc23653 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512.c @@ -8,992 +8,6 @@ #include "libcrux_mlkem512.h" #include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem768_portable.h" -#include "internal/libcrux_mlkem_avx2.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_10size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - u_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_2size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - secret_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_message__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_2size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, - (size_t)640U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_2size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message = compute_message__libcrux_ml_kem_vector_PortableVector_2size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_768size_t_2size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static void -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -typedef struct PortableHash____2size_t_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[2U]; -} PortableHash____2size_t; - -static inline PortableHash____2size_t shake128_init_absorb___2size_t( - uint8_t input[2U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final( - uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, - Eurydice_slice));); - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[2U]; - memcpy( - uu____1, state, - (size_t)2U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - PortableHash____2size_t lit; - memcpy( - lit.shake128_state, uu____1, - (size_t)2U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___2size_t( - PortableHash____2size_t *self, uint8_t ret[2U][504U]) { - uint8_t out[2U][504U] = {{0U}}; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_504size_t( - uint8_t randomness[2U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___2size_t( - PortableHash____2size_t *self, uint8_t ret[2U][168U]) { - uint8_t out[2U][168U] = {{0U}}; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_168size_t( - uint8_t randomness[2U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( - int16_t s[272U]) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - size_t sampled_coefficients[2U] = {0U}; - int16_t out[2U][272U] = {{0U}}; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); - PortableHash____2size_t xof_state = shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_2size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U][2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [2U])); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], - uint8_t ret[2U][192U]) { - uint8_t out[2U][192U] = {{0U}}; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)192U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_3size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_PortableVector( - randomness); - return uu____0; -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - re_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_3size_t( - Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[2U]; - memcpy( - uu____2, re_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[2U][128U]) { - uint8_t out[2U][128U] = {{0U}}; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - error_1[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[2U]; - memcpy( - uu____2, error_1, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___2size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_2size_t0(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_2size_t( - &result[i1]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &t_as_ntt[i0], &r_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_2size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - error_2, message, result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - input[2U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[768U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_768size_t_2size_t( - Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[2U][2U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - r_as_ntt[2U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[2U]; - memcpy( - error_1, uu____3.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___2size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_PortableVector_2size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_2size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[768U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[2U]; - memcpy( - uu____5, u, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_2size_t_640size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); -} - -static void -decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)768U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)800U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t( - Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} static void decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( @@ -1004,11 +18,15 @@ decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } @@ -1022,98 +40,6 @@ void libcrux_ml_kem_mlkem512_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___2size_t( - Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - static K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, @@ -1127,14 +53,22 @@ encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____3, uu____4); + } else { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6); return uu____0; } - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____3, uu____4); return uu____0; } @@ -1149,346 +83,6 @@ libcrux_ml_kem_mlkem512_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_2size_t1(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - matrix_element, &s_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - &result[i1], &product); - } - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - key[2U], - uint8_t ret[768U]) { - uint8_t out[768U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)768U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[2U], - Eurydice_slice seed_for_a, uint8_t ret[800U]) { - uint8_t public_key_serialized[800U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1[2U]; - memcpy( - uu____1, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, - (size_t)768U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); -} - -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[2U][2U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[2U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_as_ntt[2U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - uu____3, domain_separator) - .fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_2size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____4[2U]; - memcpy( - uu____4, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[2U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)1632U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t( - uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uu____4)); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - static libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( uint8_t randomness[64U]) { @@ -1499,13 +93,19 @@ generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192s uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( uu____1); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____2); + } else { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____3); } - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____2); return uu____0; } @@ -1517,85 +117,6 @@ libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) { uu____0); } -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - public_key); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_800size_t_2size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline bool -validate_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_800size_t_2size_t( - Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0[2U]; - memcpy( - uu____0, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - return validate_public_key__libcrux_ml_kem_vector_PortableVector_2size_t_768size_t_800size_t( - public_key); -} - static bool validate_public_key___2size_t_768size_t_800size_t( uint8_t *public_key) { bool uu____0; @@ -1603,11 +124,15 @@ static bool validate_public_key___2size_t_768size_t_800size_t( uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( public_key); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key); + } else { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key); } - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - public_key); return uu____0; } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 3dfe05c0c..4cf838da4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -14,10 +14,9 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" +#include "libcrux_mlkem512_portable.h" #include "libcrux_platform.h" -#include "libcrux_polynomial.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_internal.h" #define LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 ((size_t)10U) @@ -76,53 +75,19 @@ extern "C" { LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - void libcrux_ml_kem_mlkem512_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]); -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key); - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key); - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c index 01b9e83cb..a1e71ded9 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768.c @@ -8,6 +8,969 @@ #include "libcrux_mlkem768.h" #include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem512_portable.h" +#include "internal/libcrux_mlkem_avx2.h" +#include "internal/libcrux_polynomial.h" +#include "internal/libcrux_sha3_internal.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)1U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)2U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)3U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)4U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)5U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)6U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( + &zeta_i, re, (size_t)7U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( + re); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( + v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + message = compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static void +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +typedef struct PortableHash____3size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; +} PortableHash____3size_t; + +static inline PortableHash____3size_t shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; + memcpy( + uu____1, state, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + PortableHash____3size_t lit; + memcpy( + lit.shake128_state, uu____1, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void shake128_squeeze_three_blocks___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + int16_t s[272U]) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U])); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t0(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( + error_2, message, result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____6 = v; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +static void +decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} static void decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( @@ -18,11 +981,15 @@ decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960 if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } @@ -36,6 +1003,98 @@ void libcrux_ml_kem_mlkem768_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, @@ -49,14 +1108,22 @@ encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10siz uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + } else { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6); return uu____0; } - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); return uu____0; } @@ -71,6 +1138,346 @@ libcrux_ml_kem_mlkem768_encapsulate( uu____0, uu____1); } +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_3size_t1(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( + matrix_element, &s_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { @@ -81,13 +1488,19 @@ generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_1 uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uu____1); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____2); + } else { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____3); } - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____2); return uu____0; } @@ -99,6 +1512,85 @@ libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { uu____0); } +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector +closure__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t(void) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); +} + +static inline bool +validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( + public_key); +} + static bool validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key) { bool uu____0; @@ -106,11 +1598,15 @@ static bool validate_public_key___3size_t_1152size_t_1184size_t( uu____0 = libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( public_key); - return uu____0; + } else if (libcrux_platform_platform_simd128_support()) { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); + } else { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); } - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); return uu____0; } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 9674c7990..5fb3491b8 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -14,9 +14,10 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" -#include "libcrux_mlkem768_avx2.h" -#include "libcrux_mlkem768_portable.h" #include "libcrux_platform.h" +#include "libcrux_polynomial.h" +#include "libcrux_sha3.h" +#include "libcrux_sha3_internal.h" #define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) @@ -75,19 +76,53 @@ extern "C" { LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + void libcrux_ml_kem_mlkem768_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]); +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index dc8fa29e8..19f0762b4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -7,18 +7,6 @@ #include "libcrux_mlkem768_avx2.h" -#include "internal/libcrux_mlkem_avx2.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - void libcrux_ml_kem_mlkem768_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, @@ -29,17 +17,6 @@ void libcrux_ml_kem_mlkem768_avx2_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_avx2_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, @@ -51,15 +28,6 @@ libcrux_ml_kem_mlkem768_avx2_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -68,12 +36,6 @@ libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { uu____0); } -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - public_key); -} - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_avx2_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index a2c748d16..5b71584d3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -14,37 +14,21 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); +#include "libcrux_mlkem768.h" void libcrux_ml_kem_mlkem768_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]); -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_avx2_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_avx2_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index cd051f9ba..22c124e6e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -5,1690 +5,7 @@ KaRaMeL version: 40e3a603 */ -#include "internal/libcrux_mlkem768_portable.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_10( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___10int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_11( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___11int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -typedef struct - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector_s { - libcrux_ml_kem_vector_PortableVector fst; - libcrux_ml_kem_vector_PortableVector snd; -} __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector; - -static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a, - libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { - libcrux_ml_kem_vector_PortableVector t = - libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - b, zeta_r); - b = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - a, &t); - a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - a, &t); - return (( - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ - .fst = a, .snd = b}); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer, size_t _initial_coefficient_bound) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_PortableVector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_PortableVector x = uu____0.fst; - libcrux_ml_kem_vector_PortableVector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -void libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -void libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer, size_t _initial_coefficient_bound) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -void libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = (size_t)0U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U, (size_t)3328U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_4( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___4int32_t( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_5( - bytes); - re.coefficients[i0] = uu____0; - libcrux_ml_kem_vector_PortableVector uu____1 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___5int32_t( - re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = deserialize_then_decompress_4__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t _layer) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a, - libcrux_ml_kem_vector_PortableVector b, int16_t zeta_r) { - libcrux_ml_kem_vector_PortableVector a_minus_b = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - b, &a); - a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - a, &b)); - b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - a_minus_b, zeta_r); - return (( - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector){ - .fst = a, .snd = b}); -} - -void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = - offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = - step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_vector_PortableVector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_PortableVector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_PortableVector x = uu____0.fst; - libcrux_ml_kem_vector_PortableVector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - v, result); - return result; -} - -void libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - uint8_t ret[32U]) { - uint8_t serialized[32U] = {0U}; - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0]); - libcrux_ml_kem_vector_PortableVector coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress_1( - coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_1( - coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *);); - memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message = compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - bytes); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___cond_subtract_3329( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static void -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -typedef struct PortableHash____3size_t_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; -} PortableHash____3size_t; - -static inline PortableHash____3size_t shake128_init_absorb___3size_t( - uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final( - uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, - Eurydice_slice));); - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; - memcpy( - uu____1, state, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - PortableHash____3size_t lit; - memcpy( - lit.shake128_state, uu____1, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - int16_t s[272U]) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U])); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t uu____2 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t random_bits_as_u32 = - uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = - (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t random_bits_as_u24 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_PortableVector( - randomness); - return uu____0; -} - -static inline void ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) { - size_t j = i; - libcrux_ml_kem_vector_PortableVector t = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___multiply_by_constant( - re->coefficients[j + step], (int16_t)-1600); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - re->coefficients[j], &t); - re->coefficients[j + step] = uu____0; - libcrux_ml_kem_vector_PortableVector uu____1 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - re->coefficients[j], &t); - re->coefficients[j] = uu____1; - } -} - -void libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - ntt_at_layer_7__libcrux_ml_kem_vector_PortableVector(re); - size_t zeta_i = (size_t)1U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U, (size_t)3U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t0(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_1( - Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_PortableVector( - coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &t_as_ntt[i0], &r_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_320size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___4int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_4( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -void libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficients = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___5int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_5( - coefficients, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -void libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_PortableVector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -static void -decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} +#include "libcrux_mlkem768_portable.h" void libcrux_ml_kem_mlkem768_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, @@ -1700,87 +17,6 @@ void libcrux_ml_kem_mlkem768_portable_decapsulate( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_portable_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, @@ -1792,364 +28,6 @@ libcrux_ml_kem_mlkem768_portable_encapsulate( uu____0, uu____1); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t1(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - matrix_element, &s_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -void libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_12( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -2158,79 +36,6 @@ libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { uu____0); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline bool -validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - public_key); -} - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_portable_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 5536e97a2..9f6577139 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -14,40 +14,21 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" -#include "libcrux_polynomial.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_internal.h" - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); +#include "libcrux_mlkem768.h" void libcrux_ml_kem_mlkem768_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]); -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_portable_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_portable_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index 79f472cbb..21fc1c974 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -1561,7 +1561,7 @@ ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -1592,14 +1592,14 @@ deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -1621,7 +1621,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800s } memcpy( ret, deserialized_pk, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -1677,17 +1677,17 @@ serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[2U], - uint8_t ret[768U]) { - uint8_t out[768U] = {0U}; + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, key, + (size_t)4U, key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -1697,7 +1697,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)768U, out, + (size_t)1536U, out, ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * @@ -1711,68 +1711,68 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); } static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U], - Eurydice_slice seed_for_a, uint8_t ret[800U]) { - uint8_t public_key_serialized[800U] = {0U}; + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)800U, public_key_serialized, + (size_t)1568U, public_key_serialized, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), + .end = (size_t)1536U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[2U]; + uu____1[4U]; memcpy( uu____1, t_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( uu____1, ret0); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, - (size_t)768U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, Eurydice_slice), seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( - Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), deserialized_pk); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[2U]; + uu____0[4U]; memcpy( uu____0, deserialized_pk, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uu____0, - Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), public_key_serialized); return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), @@ -1781,22 +1781,22 @@ static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); memcpy( ret, ret0, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -1804,7 +1804,7 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 Simd256Hash; static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { +shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t state = libcrux_sha3_avx2_x4_incremental_shake128_init(); libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t @@ -1814,54 +1814,70 @@ shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); return state; } -static inline void shake128_squeeze_three_blocks___2size_t( +static inline void shake128_squeeze_three_blocks___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][504U]) { - uint8_t out[2U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - uint8_t dummy_out1[504U] = {0U}; + uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], Eurydice_slice), (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, - uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( - uint8_t randomness[2U][504U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -1887,8 +1903,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -1897,47 +1913,63 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ return done; } -static inline void shake128_squeeze_block___2size_t( +static inline void shake128_squeeze_block___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][168U]) { - uint8_t out[2U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - uint8_t dummy_out1[168U] = {0U}; + uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], Eurydice_slice), (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, - uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], + uint8_t(*)[168U], uint8_t[168U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uint8_t randomness[2U][168U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -1963,8 +1995,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -1994,7 +2026,7 @@ from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -2005,84 +2037,84 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uint8_t seeds[2U][34U], +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seeds[4U][34U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - size_t sampled_coefficients[2U] = {0U}; - int16_t out[2U][272U] = {{0U}}; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); + shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { if (done) { break; } else { - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( uu____2, sampled_coefficients, out); } } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( uu____3[i]);); memcpy( ret, ret0, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( uint8_t seed[34U], bool transpose, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U][2U]) { + ret[4U][4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( A_transpose[i]);); - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; uint8_t uu____0[34U]; memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( uu____1, sampled); for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, sampled, + (size_t)4U, sampled, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -2099,63 +2131,79 @@ sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu }); memcpy( ret, A_transpose, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U])); + [4U])); } typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[2U]; + fst[4U]; uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], - uint8_t ret[2U][192U]) { - uint8_t out[2U][192U] = {{0U}}; - uint8_t dummy_out0[192U] = {0U}; - uint8_t dummy_out1[192U] = {0U}; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], Eurydice_slice), - (size_t)1U, uint8_t[192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____9 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, - uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); + uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -2253,12 +2301,12 @@ sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( Eurydice_slice randomness) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( randomness); return uu____0; } @@ -2423,47 +2471,47 @@ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t, Eurydice_slice)); re_as_ntt[i0] = uu____1; ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( &re_as_ntt[i0]);); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; + uu____2[4U]; memcpy( uu____2, re_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; @@ -2471,7 +2519,7 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -2506,7 +2554,7 @@ ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -2554,31 +2602,31 @@ add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[2U], + *matrix_A)[4U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *s_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, matrix_A, + (size_t)4U, matrix_A, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], + [4U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], + [4U], size_t); i0++) { size_t i1 = i0; @@ -2589,7 +2637,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, row, + (size_t)4U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -2601,7 +2649,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1], &product); } add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -2609,16 +2657,16 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( } memcpy( ret, result, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); + G___4size_t(key_generation_seed, hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), @@ -2627,76 +2675,76 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; + A_transpose[4U][4U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret, true, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____1, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; + secret_as_ntt[4U]; memcpy( secret_as_ntt, uu____2.fst, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[2U]; + error_as_ntt[4U]; memcpy( error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____3, domain_separator) .fst, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[2U]; + uu____4[4U]; memcpy( uu____4, t_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uu____4, seed_for_A, public_key_serialized); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; + uu____5[4U]; memcpy( uu____5, secret_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( uu____5, secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), input); @@ -2704,17 +2752,17 @@ static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { } static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)1632U, uu____0, + (size_t)3168U, uu____0, ((core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + @@ -2727,7 +2775,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t size_t uu____5 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)1632U, uu____3, + (size_t)3168U, uu____3, ((core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + @@ -2736,13 +2784,13 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)1632U, out, + (size_t)3168U, out, ((core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; - H___2size_t(public_key, ret0); + H___4size_t(public_key, ret0); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), @@ -2753,18 +2801,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t size_t uu____9 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)1632U, uu____7, + (size_t)3168U, uu____7, ((core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, @@ -2776,49 +2824,49 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -2840,89 +2888,38 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768s } memcpy( ret, deserialized_pk, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[2U][128U]) { - uint8_t out[2U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - uint8_t dummy_out1[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - randomness); - return uu____0; -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -2930,24 +2927,24 @@ sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem uint8_t, Eurydice_slice)); error_1[i0] = uu____1;); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; + uu____2[4U]; memcpy( uu____2, error_1, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; return lit; } -static inline void PRF___2size_t_128size_t(Eurydice_slice input, +static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -2957,7 +2954,7 @@ static inline void PRF___2size_t_128size_t(Eurydice_slice input, } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t0(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -3063,7 +3060,7 @@ invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = @@ -3102,31 +3099,31 @@ static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[2U], + *a_as_ntt)[4U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *r_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_1, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, a_as_ntt, + (size_t)4U, a_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], + [4U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], + [4U], size_t); i0++) { size_t i1 = i0; @@ -3137,7 +3134,7 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, row, + (size_t)4U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -3149,17 +3146,17 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1]); add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -3225,7 +3222,7 @@ add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *t_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -3236,14 +3233,14 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( *message) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result); result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( error_2, message, result); @@ -3313,11 +3310,11 @@ static core_core_arch_x86___m256i compress___10int32_t( } static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -3328,7 +3325,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, + (size_t)352U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3337,7 +3334,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline core_core_arch_x86___m256i @@ -3403,11 +3400,11 @@ static core_core_arch_x86___m256i compress___11int32_t( } static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -3418,7 +3415,7 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, + (size_t)352U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3427,31 +3424,31 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + uint8_t ret[352U]) { + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); } static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[2U], + input[4U], Eurydice_slice out) { for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)2U, input, + (size_t)4U, input, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -3463,15 +3460,15 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640s Eurydice_slice uu____0 = Eurydice_slice_subslice( out, ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( &re, ret); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), uint8_t, void *); } } @@ -3653,64 +3650,64 @@ compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re, Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); + compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); } static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[768U]) { + uint8_t ret[1568U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( - Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), t_as_ntt); Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; + A_transpose[4U][4U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____0, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[2U]; + r_as_ntt[4U]; memcpy( r_as_ntt, uu____1.fst, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( uu____2, domain_separator0); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; + error_1[4U]; memcpy( error_1, uu____3.fst, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___2size_t_128size_t( + PRF___4size_t_128size_t( Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), prf_output); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -3719,8 +3716,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); @@ -3729,34 +3726,34 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( uu____4); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[768U] = {0U}; + uint8_t ciphertext[1568U] = {0U}; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; + uu____5[4U]; memcpy( uu____5, u, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( uu____5, Eurydice_array_to_subslice( - (size_t)768U, ciphertext, + (size_t)1568U, ciphertext, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), + .end = (size_t)1408U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( uu____6, - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -3766,10 +3763,10 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, size_t, Eurydice_slice); uint8_t ret[32U]; - H___2size_t( + H___4size_t( Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( public_key), uint8_t, Eurydice_slice), ret); @@ -3778,7 +3775,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), uint8_t, void *); uint8_t hashed[64U]; - G___2size_t( + G___4size_t( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = @@ -3789,35 +3786,35 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( public_key), uint8_t, Eurydice_slice); uint8_t uu____3[32U]; memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____2, uu____3, pseudorandomness, ciphertext); uint8_t shared_secret_array[32U] = {0U}; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, Eurydice_slice), shared_secret, uint8_t, void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uu____4); uint8_t uu____6[32U]; memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -3995,18 +3992,18 @@ deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = (size_t)0U; @@ -4025,46 +4022,46 @@ ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( } static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( uint8_t *ciphertext, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, Eurydice_slice), uint8_t, size_t) / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); + (size_t)11U / (size_t)8U); i++) { size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)768U, ciphertext, + (size_t)1568U, ciphertext, ((core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), + (size_t)11U / (size_t)8U), .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + + (size_t)11U / (size_t)8U) + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), + (size_t)11U / (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( &u_as_ntt[i0]); } memcpy( ret, u_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -4240,18 +4237,18 @@ deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t1(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -4279,14 +4276,14 @@ deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vect } static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( Eurydice_slice secret_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, + secret_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / @@ -4308,7 +4305,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( } memcpy( ret, secret_as_ntt, - (size_t)2U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -4335,7 +4332,7 @@ subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *v, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -4344,14 +4341,14 @@ compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( *u_as_ntt) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result); result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); return result; @@ -4387,24 +4384,24 @@ compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, - (size_t)640U, uint8_t, size_t, + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( secret_key, secret_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -4412,7 +4409,7 @@ decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void PRF___2size_t_32size_t(Eurydice_slice input, +static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -4421,21 +4418,21 @@ static inline void PRF___2size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, Eurydice_slice), - (size_t)768U, uint8_t, + (size_t)1536U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = core_slice___Slice_T___split_at( - secret_key0, (size_t)800U, uint8_t, + secret_key0, (size_t)1568U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; @@ -4446,7 +4443,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -4458,7 +4455,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t, size_t, Eurydice_slice), ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___2size_t( + G___4size_t( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = @@ -4468,33 +4465,33 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + implicit_rejection_value, to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( ciphertext), uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t( - Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____5, uu____6, pseudorandomness, expected_ciphertext); Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( ciphertext); uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; @@ -4507,19 +4504,19 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -4541,23 +4538,23 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568 } memcpy( ret, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, key, + (size_t)3U, key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -4567,7 +4564,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, + (size_t)1152U, out, ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * @@ -4581,68 +4578,68 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); } static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, + (size_t)1184U, public_key_serialized, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), + .end = (size_t)1152U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[4U]; + uu____1[3U]; memcpy( uu____1, t_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( uu____1, ret0); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, Eurydice_slice), seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), deserialized_pk); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[4U]; + uu____0[3U]; memcpy( uu____0, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), public_key_serialized); return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), @@ -4651,28 +4648,28 @@ static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); memcpy( ret, ret0, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { +shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t state = libcrux_sha3_avx2_x4_incremental_shake128_init(); libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t @@ -4685,67 +4682,59 @@ shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); return state; } -static inline void shake128_squeeze_three_blocks___4size_t( +static inline void shake128_squeeze_three_blocks___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], Eurydice_slice), (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], + out12, (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + Eurydice_slice out2 = uu____1.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -4771,8 +4760,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -4781,63 +4770,55 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ return done; } -static inline void shake128_squeeze_block___4size_t( +static inline void shake128_squeeze_block___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], Eurydice_slice), (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[168U], + out12, (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + Eurydice_slice out2 = uu____1.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], - uint8_t(*)[168U], uint8_t[168U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -4863,8 +4844,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -4874,7 +4855,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -4885,84 +4866,84 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seeds[4U][34U], +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seeds[3U][34U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { if (done) { break; } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( uu____2, sampled_coefficients, out); } } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( uu____3[i]);); memcpy( ret, ret0, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( uint8_t seed[34U], bool transpose, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U][4U]) { + ret[3U][3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; uint8_t uu____0[34U]; memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( uu____1, sampled); for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, sampled, + (size_t)3U, sampled, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -4979,102 +4960,94 @@ sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu }); memcpy( ret, A_transpose, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U])); + [3U])); } typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[4U]; + fst[3U]; uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], Eurydice_slice), (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], + out12, (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( + Eurydice_slice uu____7 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____9 = Eurydice_array_to_slice( + Eurydice_slice uu____8 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); + uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, + Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -5084,17 +5057,17 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( &re_as_ntt[i0]);); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; + uu____2[3U]; memcpy( uu____2, re_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; @@ -5102,12 +5075,12 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5128,31 +5101,31 @@ add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[4U], + *matrix_A)[3U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *s_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, matrix_A, + (size_t)3U, matrix_A, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], size_t); i0++) { size_t i1 = i0; @@ -5163,7 +5136,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, row, + (size_t)3U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5175,7 +5148,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1], &product); } add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -5183,16 +5156,16 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } memcpy( ret, result, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); + G___3size_t(key_generation_seed, hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), @@ -5201,75 +5174,75 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; + A_transpose[3U][3U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret, true, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____1, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; + secret_as_ntt[3U]; memcpy( secret_as_ntt, uu____2.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[4U]; + error_as_ntt[3U]; memcpy( error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____3, domain_separator) .fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[4U]; + uu____4[3U]; memcpy( uu____4, t_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uu____4, seed_for_A, public_key_serialized); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; + uu____5[3U]; memcpy( uu____5, secret_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; } -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), @@ -5278,17 +5251,17 @@ static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { } static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____0, + (size_t)2400U, uu____0, ((core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + @@ -5301,7 +5274,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t size_t uu____5 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____3, + (size_t)2400U, uu____3, ((core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + @@ -5310,13 +5283,13 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, + (size_t)2400U, out, ((core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; - H___4size_t(public_key, ret0); + H___3size_t(public_key, ret0); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), @@ -5327,18 +5300,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t size_t uu____9 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____7, + (size_t)2400U, uu____7, ((core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, @@ -5350,49 +5323,49 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -5414,38 +5387,38 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536 } memcpy( ret, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -5453,24 +5426,24 @@ sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem uint8_t, Eurydice_slice)); error_1[i0] = uu____1;); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; + uu____2[3U]; memcpy( uu____2, error_1, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; return lit; } -static inline void PRF___4size_t_128size_t(Eurydice_slice input, +static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -5480,12 +5453,12 @@ static inline void PRF___4size_t_128size_t(Eurydice_slice input, } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = @@ -5505,31 +5478,31 @@ invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[4U], + *a_as_ntt)[3U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *r_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_1, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, + (size_t)3U, a_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], size_t); i0++) { size_t i1 = i0; @@ -5540,7 +5513,7 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, row, + (size_t)3U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5552,23 +5525,23 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1]); add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *t_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5579,14 +5552,14 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( *message) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result); result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( error_2, message, result); @@ -5594,11 +5567,11 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -5609,7 +5582,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, + (size_t)320U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5618,15 +5591,15 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -5637,7 +5610,7 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, + (size_t)320U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5646,31 +5619,31 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); } static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[4U], + input[3U], Eurydice_slice out) { for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, input, + (size_t)3U, input, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5682,78 +5655,78 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408 Eurydice_slice uu____0 = Eurydice_slice_subslice( out, ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( &re, ret); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), uint8_t, void *); } } static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re, Eurydice_slice out) { - compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); + compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); } static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { + uint8_t ret[1088U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), t_as_ntt); Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; + A_transpose[3U][3U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____0, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[4U]; + r_as_ntt[3U]; memcpy( r_as_ntt, uu____1.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( uu____2, domain_separator0); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; + error_1[3U]; memcpy( error_1, uu____3.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___4size_t_128size_t( + PRF___3size_t_128size_t( Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), prf_output); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5762,8 +5735,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); @@ -5772,34 +5745,34 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( uu____4); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; + uint8_t ciphertext[1088U] = {0U}; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; + uu____5[3U]; memcpy( uu____5, u, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, + (size_t)1088U, ciphertext, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), + .end = (size_t)960U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -5809,10 +5782,10 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, size_t, Eurydice_slice); uint8_t ret[32U]; - H___4size_t( + H___3size_t( Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( public_key), uint8_t, Eurydice_slice), ret); @@ -5821,7 +5794,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), uint8_t, void *); uint8_t hashed[64U]; - G___4size_t( + G___3size_t( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = @@ -5832,52 +5805,52 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( public_key), uint8_t, Eurydice_slice); uint8_t uu____3[32U]; memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____2, uu____3, pseudorandomness, ciphertext); uint8_t shared_secret_array[32U] = {0U}; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, Eurydice_slice), shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uu____4); uint8_t uu____6[32U]; memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = (size_t)0U; @@ -5896,75 +5869,75 @@ ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( } static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( uint8_t *ciphertext, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, Eurydice_slice), uint8_t, size_t) / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); + (size_t)10U / (size_t)8U); i++) { size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, + (size_t)1088U, ciphertext, ((core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), + (size_t)10U / (size_t)8U), .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + + (size_t)10U / (size_t)8U) + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), + (size_t)10U / (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( &u_as_ntt[i0]); } memcpy( ret, u_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( Eurydice_slice secret_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / @@ -5986,13 +5959,13 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } memcpy( ret, secret_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *v, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -6001,38 +5974,38 @@ compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( *u_as_ntt) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result); result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); return result; } static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( secret_key, secret_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -6040,7 +6013,7 @@ decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_ memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void PRF___4size_t_32size_t(Eurydice_slice input, +static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -6049,21 +6022,21 @@ static inline void PRF___4size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, Eurydice_slice), - (size_t)1536U, uint8_t, + (size_t)1152U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, + secret_key0, (size_t)1184U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; @@ -6074,7 +6047,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -6086,7 +6059,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t, size_t, Eurydice_slice), ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___4size_t( + G___3size_t( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = @@ -6096,33 +6069,33 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( implicit_rejection_value, to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( ciphertext), uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____5, uu____6, pseudorandomness, expected_ciphertext); Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( ciphertext); uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; @@ -6135,19 +6108,19 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -6169,23 +6142,23 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184 } memcpy( ret, deserialized_pk, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; + key[2U], + uint8_t ret[768U]) { + uint8_t out[768U] = {0U}; for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, key, + (size_t)2U, key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -6195,7 +6168,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, + (size_t)768U, out, ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * @@ -6209,68 +6182,68 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); } static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; + t_as_ntt[2U], + Eurydice_slice seed_for_a, uint8_t ret[800U]) { + uint8_t public_key_serialized[800U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, + (size_t)800U, public_key_serialized, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), + .end = (size_t)768U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[3U]; + uu____1[2U]; memcpy( uu____1, t_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( uu____1, ret0); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, + (size_t)768U, uint8_t, size_t, Eurydice_slice), seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( + Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice), deserialized_pk); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[3U]; + uu____0[2U]; memcpy( uu____0, deserialized_pk, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice), public_key_serialized); return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); + (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), @@ -6279,28 +6252,28 @@ static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); memcpy( ret, ret0, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { +shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t state = libcrux_sha3_avx2_x4_incremental_shake128_init(); libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t @@ -6310,62 +6283,54 @@ shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( uu____0, uu____1, uu____2, uu____3, Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); return state; } -static inline void shake128_squeeze_three_blocks___3size_t( +static inline void shake128_squeeze_three_blocks___2size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; + uint8_t ret[2U][504U]) { + uint8_t out[2U][504U] = {{0U}}; uint8_t dummy_out0[504U] = {0U}; + uint8_t dummy_out1[504U] = {0U}; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], + Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], Eurydice_slice), (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + Eurydice_slice out1 = uu____0.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, + uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + uint8_t randomness[2U][504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -6391,8 +6356,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -6401,55 +6366,47 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ return done; } -static inline void shake128_squeeze_block___3size_t( +static inline void shake128_squeeze_block___2size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; + uint8_t ret[2U][168U]) { + uint8_t out[2U][168U] = {{0U}}; uint8_t dummy_out0[168U] = {0U}; + uint8_t dummy_out1[168U] = {0U}; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], + Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], Eurydice_slice), (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + Eurydice_slice out1 = uu____0.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, + uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uint8_t randomness[2U][168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -6475,8 +6432,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -6486,7 +6443,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -6497,84 +6454,84 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seeds[3U][34U], +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uint8_t seeds[2U][34U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + ret[2U]) { + size_t sampled_coefficients[2U] = {0U}; + int16_t out[2U][272U] = {{0U}}; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { if (done) { break; } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( uu____2, sampled_coefficients, out); } } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( uu____3[i]);); memcpy( ret, ret0, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( uint8_t seed[34U], bool transpose, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U][3U]) { + ret[2U][2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + A_transpose[2U][2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; uint8_t uu____0[34U]; memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( uu____1, sampled); for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, sampled, + (size_t)2U, sampled, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -6591,114 +6548,117 @@ sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu }); memcpy( ret, A_transpose, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U])); + [2U])); } typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[3U]; + fst[2U]; uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], + uint8_t ret[2U][192U]) { + uint8_t out[2U][192U] = {{0U}}; + uint8_t dummy_out0[192U] = {0U}; + uint8_t dummy_out1[192U] = {0U}; + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], + Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + (size_t)1U, uint8_t[192U], + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, + uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, - Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], uint8_t, Eurydice_slice)); re_as_ntt[i0] = uu____1; ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( &re_as_ntt[i0]);); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; + uu____2[2U]; memcpy( uu____2, re_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; @@ -6706,12 +6666,12 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -6732,31 +6692,31 @@ add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[3U], + *matrix_A)[2U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *s_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, matrix_A, + (size_t)2U, matrix_A, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [2U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [2U], size_t); i0++) { size_t i1 = i0; @@ -6767,7 +6727,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, row, + (size_t)2U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -6779,7 +6739,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result[i1], &product); } add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -6787,16 +6747,16 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } memcpy( ret, result, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); + G___2size_t(key_generation_seed, hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), @@ -6805,75 +6765,75 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; + A_transpose[2U][2U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( ret, true, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( uu____1, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; + secret_as_ntt[2U]; memcpy( secret_as_ntt, uu____2.fst, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[3U]; + error_as_ntt[2U]; memcpy( error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( uu____3, domain_separator) .fst, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[3U]; + uu____4[2U]; memcpy( uu____4, t_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uu____4, seed_for_A, public_key_serialized); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; + uu____5[2U]; memcpy( uu____5, secret_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; } -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), @@ -6882,17 +6842,17 @@ static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { } static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____0, + (size_t)1632U, uu____0, ((core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + @@ -6905,7 +6865,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t size_t uu____5 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____3, + (size_t)1632U, uu____3, ((core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + @@ -6914,13 +6874,13 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, + (size_t)1632U, out, ((core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; - H___3size_t(public_key, ret0); + H___2size_t(public_key, ret0); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), @@ -6931,18 +6891,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t size_t uu____9 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____7, + (size_t)1632U, uu____7, ((core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, @@ -6954,49 +6914,49 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, Eurydice_slice), implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -7018,38 +6978,78 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152 } memcpy( ret, deserialized_pk, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[2U][128U]) { + uint8_t out[2U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; + uint8_t dummy_out1[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -7057,24 +7057,24 @@ sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem uint8_t, Eurydice_slice)); error_1[i0] = uu____1;); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; + uu____2[2U]; memcpy( uu____2, error_1, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; return lit; } -static inline void PRF___3size_t_128size_t(Eurydice_slice input, +static inline void PRF___2size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -7084,12 +7084,12 @@ static inline void PRF___3size_t_128size_t(Eurydice_slice input, } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t0(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = @@ -7109,31 +7109,31 @@ invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[3U], + *a_as_ntt)[2U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *r_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_1, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, + (size_t)2U, a_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [2U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [2U], size_t); i0++) { size_t i1 = i0; @@ -7144,7 +7144,7 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, row, + (size_t)2U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -7156,23 +7156,23 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result[i1]); add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *t_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -7183,14 +7183,14 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( *message) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result); result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( error_2, message, result); @@ -7198,16 +7198,16 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[3U], + input[2U], Eurydice_slice out) { for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, input, + (size_t)2U, input, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -7219,8 +7219,8 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960s Eurydice_slice uu____0 = Eurydice_slice_subslice( out, ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[320U]; compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( @@ -7233,56 +7233,56 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960s } static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { + uint8_t ret[768U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( + Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice), t_as_ntt); Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; + A_transpose[2U][2U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( uu____0, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[3U]; + r_as_ntt[2U]; memcpy( r_as_ntt, uu____1.fst, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( uu____2, domain_separator0); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; + error_1[2U]; memcpy( error_1, uu____3.fst, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___3size_t_128size_t( + PRF___2size_t_128size_t( Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), prf_output); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -7291,8 +7291,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); @@ -7301,34 +7301,34 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( uu____4); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; + uint8_t ciphertext[768U] = {0U}; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; + uu____5[2U]; memcpy( uu____5, u, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, + (size_t)768U, ciphertext, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), + .end = (size_t)640U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); + memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -7338,10 +7338,10 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, size_t, Eurydice_slice); uint8_t ret[32U]; - H___3size_t( + H___2size_t( Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( public_key), uint8_t, Eurydice_slice), ret); @@ -7350,7 +7350,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), uint8_t, void *); uint8_t hashed[64U]; - G___3size_t( + G___2size_t( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = @@ -7361,52 +7361,52 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( public_key), uint8_t, Eurydice_slice); uint8_t uu____3[32U]; memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( uu____2, uu____3, pseudorandomness, ciphertext); uint8_t shared_secret_array[32U] = {0U}; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, Eurydice_slice), shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( uu____4); uint8_t uu____6[32U]; memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( uint8_t *ciphertext, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, Eurydice_slice), uint8_t, size_t) / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * @@ -7414,7 +7414,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_ i++) { size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, + (size_t)768U, ciphertext, ((core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * @@ -7434,25 +7434,25 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_ } memcpy( ret, u_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t1(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( Eurydice_slice secret_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / @@ -7474,13 +7474,13 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } memcpy( ret, secret_as_ntt, - (size_t)3U * + (size_t)2U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *v, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -7489,38 +7489,38 @@ compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( *u_as_ntt) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &result); result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); return result; } static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, + (size_t)640U, uint8_t, size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( secret_key, secret_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -7528,7 +7528,7 @@ decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_1 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void PRF___3size_t_32size_t(Eurydice_slice input, +static inline void PRF___2size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -7537,21 +7537,21 @@ static inline void PRF___3size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, Eurydice_slice), - (size_t)1152U, uint8_t, + (size_t)768U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, + secret_key0, (size_t)800U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; @@ -7562,7 +7562,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -7574,7 +7574,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t, size_t, Eurydice_slice), ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___3size_t( + G___2size_t( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = @@ -7584,33 +7584,33 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( ciphertext), uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + PRF___2size_t_32size_t( + Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( uu____5, uu____6, pseudorandomness, expected_ciphertext); Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( ciphertext); uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index 08c2017a6..026947fe9 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -16,7 +16,6 @@ extern "C" { #include "libcrux_core.h" #include "libcrux_sha3.h" #include "libcrux_sha3_avx2.h" -#include "libcrux_sha3_libcrux_ml_kem.h" core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); diff --git a/libcrux-ml-kem/c/libcrux_polynomial.c b/libcrux-ml-kem/c/libcrux_polynomial.c index 23913a64a..61c774813 100644 --- a/libcrux-ml-kem/c/libcrux_polynomial.c +++ b/libcrux-ml-kem/c/libcrux_polynomial.c @@ -2094,7 +2094,7 @@ libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_m return rej_sample(a, out); } -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector @@ -2114,7 +2114,7 @@ void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElemen } } -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector @@ -2377,7 +2377,7 @@ libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vec return b; } -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( +void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 1401fee38..2f9e86a7b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -16,7 +16,6 @@ extern "C" { #include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_core.h" #include "libcrux_sha3_internal.h" -#include "libcrux_sha3_libcrux_ml_kem.h" typedef struct libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { diff --git a/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h b/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h deleted file mode 100644 index 4f8d3f20c..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_sha3_libcrux_ml_kem_H -#define __libcrux_sha3_libcrux_ml_kem_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_add_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_add_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_and_si256( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_andnot_si256( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_blend_epi16( - int32_t x0, core_core_arch_x86___m256i x1, core_core_arch_x86___m256i x2); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_castsi128_si256( - core_core_arch_x86___m128i x0); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm256_castsi256_si128( - core_core_arch_x86___m256i x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_cmpgt_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_cvtepi16_epi32( - core_core_arch_x86___m128i x0); - -extern core_core_arch_x86___m128i -libcrux_intrinsics_avx2_mm256_extracti128_si256(int32_t x0, - core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i -libcrux_intrinsics_avx2_mm256_inserti128_si256(int32_t x0, - core_core_arch_x86___m256i x1, - core_core_arch_x86___m128i x2); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_loadu_si256_i16( - Eurydice_slice x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - Eurydice_slice x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_madd_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mul_epu32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mulhi_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mullo_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_mullo_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_packs_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i -libcrux_intrinsics_avx2_mm256_permute2x128_si256(int32_t x0, - core_core_arch_x86___m256i x1, - core_core_arch_x86___m256i x2); - -extern core_core_arch_x86___m256i -libcrux_intrinsics_avx2_mm256_permute4x64_epi64(int32_t x0, - core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i -libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi16( - int16_t x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi32( - int32_t x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set1_epi64x( - int64_t x0); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi16( - int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, - int16_t x6, int16_t x7, int16_t x8, int16_t x9, int16_t x10, int16_t x11, - int16_t x12, int16_t x13, int16_t x14, int16_t x15); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi32( - int32_t x0, int32_t x1, int32_t x2, int32_t x3, int32_t x4, int32_t x5, - int32_t x6, int32_t x7); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_set_epi8( - int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, - int8_t x7, int8_t x8, int8_t x9, int8_t x10, int8_t x11, int8_t x12, - int8_t x13, int8_t x14, int8_t x15, int8_t x16, int8_t x17, int8_t x18, - int8_t x19, int8_t x20, int8_t x21, int8_t x22, int8_t x23, int8_t x24, - int8_t x25, int8_t x26, int8_t x27, int8_t x28, int8_t x29, int8_t x30, - int8_t x31); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_setzero_si256( - void); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_shuffle_epi32( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_shuffle_epi8( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi16( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi32( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_slli_epi64( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_sllv_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srai_epi16( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srai_epi32( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi16( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi32( - int32_t x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_srli_epi64( - int32_t x0, core_core_arch_x86___m256i x1); - -extern void libcrux_intrinsics_avx2_mm256_storeu_si256_i16( - Eurydice_slice x0, core_core_arch_x86___m256i x1); - -extern void libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_sub_epi16( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpackhi_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpackhi_epi64( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpacklo_epi32( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_unpacklo_epi64( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m256i libcrux_intrinsics_avx2_mm256_xor_si256( - core_core_arch_x86___m256i x0, core_core_arch_x86___m256i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_add_epi16( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_loadu_si128( - Eurydice_slice x0); - -extern int32_t libcrux_intrinsics_avx2_mm_movemask_epi8( - core_core_arch_x86___m128i x0); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_mulhi_epi16( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_mullo_epi16( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_packs_epi16( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_set1_epi16( - int16_t x0); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_set_epi8( - uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, - uint8_t x6, uint8_t x7, uint8_t x8, uint8_t x9, uint8_t x10, uint8_t x11, - uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_shuffle_epi8( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -extern void libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_slice x0, core_core_arch_x86___m128i x1); - -extern void libcrux_intrinsics_avx2_mm_storeu_si128( - Eurydice_slice x0, core_core_arch_x86___m128i x1); - -extern core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_sub_epi16( - core_core_arch_x86___m128i x0, core_core_arch_x86___m128i x1); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_libcrux_ml_kem_H_DEFINED -#endif diff --git a/libcrux-ml-kem/src/ind_cca/multiplexing.rs b/libcrux-ml-kem/src/ind_cca/multiplexing.rs index 513ebca3f..bb3ce292b 100644 --- a/libcrux-ml-kem/src/ind_cca/multiplexing.rs +++ b/libcrux-ml-kem/src/ind_cca/multiplexing.rs @@ -7,10 +7,7 @@ pub(crate) fn validate_public_key< >( public_key: &[u8; PUBLIC_KEY_SIZE], ) -> bool { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { + if libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] return instantiations::avx2::validate_public_key::< K, @@ -23,10 +20,7 @@ pub(crate) fn validate_public_key< RANKED_BYTES_PER_RING_ELEMENT, PUBLIC_KEY_SIZE, >(public_key) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { + } else if libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] return instantiations::neon::validate_public_key::< K, @@ -60,10 +54,7 @@ pub(crate) fn generate_keypair< randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> MlKemKeyPair { // Runtime feature detection. - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { + if libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] return instantiations::avx2::generate_keypair::< K, @@ -84,10 +75,7 @@ pub(crate) fn generate_keypair< ETA1, ETA1_RANDOMNESS_SIZE, >(randomness) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { + } else if libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] return instantiations::neon::generate_keypair::< K, @@ -139,10 +127,7 @@ pub(crate) fn encapsulate< public_key: &MlKemPublicKey, randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKemCiphertext, MlKemSharedSecret) { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { + if libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] return instantiations::avx2::encapsulate::< K, @@ -175,10 +160,7 @@ pub(crate) fn encapsulate< ETA2, ETA2_RANDOMNESS_SIZE, >(public_key, randomness) - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { + } else if libcrux_platform::simd128_support() { #[cfg(not(feature = "simd128"))] return instantiations::portable::encapsulate::< K, @@ -251,10 +233,7 @@ pub(crate) fn decapsulate< private_key: &MlKemPrivateKey, ciphertext: &MlKemCiphertext, ) -> MlKemSharedSecret { - if cfg!(feature = "simd256") - && cfg!(target_arch = "x86_64") - && libcrux_platform::simd256_support() - { + if libcrux_platform::simd256_support() { #[cfg(all(feature = "simd256", target_arch = "x86_64"))] return instantiations::avx2::decapsulate::< K, @@ -293,10 +272,7 @@ pub(crate) fn decapsulate< ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, >(private_key, ciphertext); - } else if cfg!(feature = "simd128") - && cfg!(target_arch = "aarch64") - && libcrux_platform::simd128_support() - { + } else if libcrux_platform::simd128_support() { #[cfg(all(feature = "simd128", target_arch = "aarch64"))] return instantiations::neon::decapsulate::< K, diff --git a/libcrux-ml-kem/src/mlkem1024.rs b/libcrux-ml-kem/src/mlkem1024.rs index 8ca4e0cec..5a3a8b520 100644 --- a/libcrux-ml-kem/src/mlkem1024.rs +++ b/libcrux-ml-kem/src/mlkem1024.rs @@ -45,6 +45,109 @@ pub type MlKem1024PublicKey = MlKemPublicKey; /// Am ML-KEM 1024 Key pair pub type MlKem1024KeyPair = MlKemKeyPair; +// Instantiate the different functions. +macro_rules! instantiate { + ($modp:ident, $p:path) => { + pub mod $modp { + use super::*; + use $p as p; + + /// Validate a public key. + /// + /// Returns `Some(public_key)` if valid, and `None` otherwise. + pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option { + if p::validate_public_key::< + RANK_1024, + RANKED_BYTES_PER_RING_ELEMENT_1024, + CPA_PKE_PUBLIC_KEY_SIZE_1024, + >(&public_key.value) + { + Some(public_key) + } else { + None + } + } + + /// Generate ML-KEM 1024 Key Pair + pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE], + ) -> MlKem1024KeyPair { + p::generate_keypair::< + RANK_1024, + CPA_PKE_SECRET_KEY_SIZE_1024, + SECRET_KEY_SIZE_1024, + CPA_PKE_PUBLIC_KEY_SIZE_1024, + RANKED_BYTES_PER_RING_ELEMENT_1024, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } + + /// Encapsulate ML-KEM 1024 + /// + /// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. + /// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`] + /// bytes of `randomness`. + pub fn encapsulate( + public_key: &MlKem1024PublicKey, + randomness: [u8; SHARED_SECRET_SIZE], + ) -> (MlKem1024Ciphertext, MlKemSharedSecret) { + p::encapsulate::< + RANK_1024, + CPA_PKE_CIPHERTEXT_SIZE_1024, + CPA_PKE_PUBLIC_KEY_SIZE_1024, + T_AS_NTT_ENCODED_SIZE_1024, + C1_SIZE_1024, + C2_SIZE_1024, + VECTOR_U_COMPRESSION_FACTOR_1024, + VECTOR_V_COMPRESSION_FACTOR_1024, + C1_BLOCK_SIZE_1024, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } + + /// Decapsulate ML-KEM 1024 + /// + /// Generates an [`MlKemSharedSecret`]. + /// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. + pub fn decapsulate( + private_key: &MlKem1024PrivateKey, + ciphertext: &MlKem1024Ciphertext, + ) -> MlKemSharedSecret { + p::decapsulate::< + RANK_1024, + SECRET_KEY_SIZE_1024, + CPA_PKE_SECRET_KEY_SIZE_1024, + CPA_PKE_PUBLIC_KEY_SIZE_1024, + CPA_PKE_CIPHERTEXT_SIZE_1024, + T_AS_NTT_ENCODED_SIZE_1024, + C1_SIZE_1024, + C2_SIZE_1024, + VECTOR_U_COMPRESSION_FACTOR_1024, + VECTOR_V_COMPRESSION_FACTOR_1024, + C1_BLOCK_SIZE_1024, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext) + } + } + }; +} + +// Instantiations + +instantiate! {portable, ind_cca::instantiations::portable} +#[cfg(feature = "simd256")] +instantiate! {avx2, ind_cca::instantiations::avx2} +#[cfg(feature = "simd128")] +instantiate! {neon, ind_cca::instantiations::neon} + /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index 32c8a6118..3ec606dd7 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -43,6 +43,109 @@ pub type MlKem512PublicKey = MlKemPublicKey; /// Am ML-KEM 512 Key pair pub type MlKem512KeyPair = MlKemKeyPair; +// Instantiate the different functions. +macro_rules! instantiate { + ($modp:ident, $p:path) => { + pub mod $modp { + use super::*; + use $p as p; + + /// Validate a public key. + /// + /// Returns `Some(public_key)` if valid, and `None` otherwise. + pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option { + if p::validate_public_key::< + RANK_512, + RANKED_BYTES_PER_RING_ELEMENT_512, + CPA_PKE_PUBLIC_KEY_SIZE_512, + >(&public_key.value) + { + Some(public_key) + } else { + None + } + } + + /// Generate ML-KEM 512 Key Pair + pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE], + ) -> MlKem512KeyPair { + p::generate_keypair::< + RANK_512, + CPA_PKE_SECRET_KEY_SIZE_512, + SECRET_KEY_SIZE_512, + CPA_PKE_PUBLIC_KEY_SIZE_512, + RANKED_BYTES_PER_RING_ELEMENT_512, + ETA1, + ETA1_RANDOMNESS_SIZE, + >(randomness) + } + + /// Encapsulate ML-KEM 512 + /// + /// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. + /// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`] + /// bytes of `randomness`. + pub fn encapsulate( + public_key: &MlKem512PublicKey, + randomness: [u8; SHARED_SECRET_SIZE], + ) -> (MlKem512Ciphertext, MlKemSharedSecret) { + p::encapsulate::< + RANK_512, + CPA_PKE_CIPHERTEXT_SIZE_512, + CPA_PKE_PUBLIC_KEY_SIZE_512, + T_AS_NTT_ENCODED_SIZE_512, + C1_SIZE_512, + C2_SIZE_512, + VECTOR_U_COMPRESSION_FACTOR_512, + VECTOR_V_COMPRESSION_FACTOR_512, + C1_BLOCK_SIZE_512, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + >(public_key, randomness) + } + + /// Decapsulate ML-KEM 512 + /// + /// Generates an [`MlKemSharedSecret`]. + /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. + pub fn decapsulate( + private_key: &MlKem512PrivateKey, + ciphertext: &MlKem512Ciphertext, + ) -> MlKemSharedSecret { + p::decapsulate::< + RANK_512, + SECRET_KEY_SIZE_512, + CPA_PKE_SECRET_KEY_SIZE_512, + CPA_PKE_PUBLIC_KEY_SIZE_512, + CPA_PKE_CIPHERTEXT_SIZE_512, + T_AS_NTT_ENCODED_SIZE_512, + C1_SIZE_512, + C2_SIZE_512, + VECTOR_U_COMPRESSION_FACTOR_512, + VECTOR_V_COMPRESSION_FACTOR_512, + C1_BLOCK_SIZE_512, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + IMPLICIT_REJECTION_HASH_INPUT_SIZE, + >(private_key, ciphertext) + } + } + }; +} + +// Instantiations + +instantiate! {portable, ind_cca::instantiations::portable} +#[cfg(feature = "simd256")] +instantiate! {avx2, ind_cca::instantiations::avx2} +#[cfg(feature = "simd128")] +instantiate! {neon, ind_cca::instantiations::neon} + /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. From c5d4cf0bbaec2d7ad314f17cb637b098ac9b3372 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 5 Jun 2024 17:14:03 +0200 Subject: [PATCH 10/84] build updates --- libcrux-ml-kem/c.sh | 1 + libcrux-ml-kem/c.yaml | 32 +- libcrux-ml-kem/c/CMakeLists.txt | 3 + libcrux-ml-kem/c/eurydice_glue.h | 300 - libcrux-ml-kem/c/internal/libcrux_core.h | 259 - .../c/internal/libcrux_mlkem_avx2.h | 77 - .../c/internal/libcrux_polynomial.h | 272 - libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 38 - .../c/internal/libcrux_sha3_internal.h | 251 - libcrux-ml-kem/c/libcrux_core.c | 409 - libcrux-ml-kem/c/libcrux_core.h | 162 - libcrux-ml-kem/c/libcrux_mlkem1024.c | 1749 ---- libcrux-ml-kem/c/libcrux_mlkem1024.h | 137 - libcrux-ml-kem/c/libcrux_mlkem512.c | 153 - libcrux-ml-kem/c/libcrux_mlkem512.h | 100 - libcrux-ml-kem/c/libcrux_mlkem768.c | 1628 ---- libcrux-ml-kem/c/libcrux_mlkem768.h | 135 - libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 55 - libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 41 - libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 55 - libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 41 - libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 7623 ----------------- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 293 - libcrux-ml-kem/c/libcrux_platform.h | 26 - libcrux-ml-kem/c/libcrux_polynomial.c | 2531 ------ libcrux-ml-kem/c/libcrux_polynomial.h | 32 - libcrux-ml-kem/c/libcrux_sha3.h | 114 - libcrux-ml-kem/c/libcrux_sha3_avx2.c | 2028 ----- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 56 - libcrux-ml-kem/c/libcrux_sha3_internal.h | 2346 ----- libcrux-ml-kem/c/libcrux_sha3_neon.c | 187 - libcrux-ml-kem/c/libcrux_sha3_neon.h | 55 - libcrux-ml-kem/src/ind_cca/multiplexing.rs | 22 +- libcrux-sha3/build.rs | 26 +- libcrux-sha3/src/lib.rs | 109 +- 35 files changed, 108 insertions(+), 21238 deletions(-) delete mode 100644 libcrux-ml-kem/c/eurydice_glue.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_core.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_polynomial.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_internal.h delete mode 100644 libcrux-ml-kem/c/libcrux_core.c delete mode 100644 libcrux-ml-kem/c/libcrux_core.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_platform.h delete mode 100644 libcrux-ml-kem/c/libcrux_polynomial.c delete mode 100644 libcrux-ml-kem/c/libcrux_polynomial.h delete mode 100644 libcrux-ml-kem/c/libcrux_sha3.h delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_internal.h delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_sha3_neon.h diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index 17af9d262..fdd1dba86 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -32,6 +32,7 @@ if [[ "$portable_only" = 1 ]]; then export LIBCRUX_DISABLE_SIMD128=1 fi +# TODO: add LIBCRUX_ENABLE_SIMD128=1 LIBCRUX_ENABLE_SIMD256=1 charon invocations if [[ "$no_charon" = 0 ]]; then rm -rf ../libcrux_ml_kem.llbc ../libcrux_sha3.llbc echo "Running charon (sha3) ..." diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 513ca98e4..83cf038bf 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -180,13 +180,21 @@ files: - name: libcrux_mlkem512_avx2 api: - - [libcrux_ml_kem, mlkem512, avx2] - - [libcrux_ml_kem, ind_cca, instantiations, avx2] + patterns: + - [libcrux_ml_kem, mlkem512, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + monomorphizations_of: + - [libcrux_ml_kem, mlkem512, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] - name: libcrux_mlkem512_portable api: - - [libcrux_ml_kem, mlkem512, portable] - - [libcrux_ml_kem, ind_cca, instantiations, portable] + patterns: + - [libcrux_ml_kem, mlkem512, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + monomorphizations_of: + - [libcrux_ml_kem, mlkem512, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] - name: libcrux_mlkem512 api: @@ -194,13 +202,21 @@ files: - name: libcrux_mlkem768_avx2 api: - - [libcrux_ml_kem, mlkem768, avx2] - - [libcrux_ml_kem, ind_cca, instantiations, avx2] + patterns: + - [libcrux_ml_kem, mlkem768, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + monomorphizations_of: + - [libcrux_ml_kem, mlkem768, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] - name: libcrux_mlkem768_portable api: - - [libcrux_ml_kem, mlkem768, portable] - - [libcrux_ml_kem, ind_cca, instantiations, portable] + patterns: + - [libcrux_ml_kem, mlkem768, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + monomorphizations_of: + - [libcrux_ml_kem, mlkem768, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] - name: libcrux_mlkem768 api: diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index d50b9be3d..939dc09e9 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -34,6 +34,9 @@ include_directories( file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/libcrux_core.c ${PROJECT_SOURCE_DIR}/libcrux_platform.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem512.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem768.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_portable.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_portable.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_portable.c diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h deleted file mode 100644 index bd794c456..000000000 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ /dev/null @@ -1,300 +0,0 @@ -#pragma once - -#if defined(__cplusplus) -extern "C" { -#endif - -#include -#include -#include -#include -#include - -#include "krml/internal/target.h" -#include "krml/lowstar_endianness.h" - -#define LowStar_Ignore_ignore(e, t, _ret_t) ((void)e) - -// SLICES, ARRAYS, ETC. - -// We represent a slice as a pair of an (untyped) pointer, along with the length -// of the slice, i.e. the number of elements in the slice (this is NOT the -// number of bytes). This design choice has two important consequences. -// - if you need to use `ptr`, you MUST cast it to a proper type *before* -// performing pointer -// arithmetic on it (remember that C desugars pointer arithmetic based on the -// type of the address) -// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you -// need to multiply it -// by sizeof t, where t is the type of the elements. -typedef struct { - void *ptr; - size_t len; -} Eurydice_slice; - -// Helper macro to create a slice out of a pointer x, a start index in x -// (included), and an end index in x (excluded). The argument x must be suitably -// cast to something that can decay (see remark above about how pointer -// arithmetic works in C), meaning either pointer or array type. -#define EURYDICE_SLICE(x, start, end) \ - ((Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) -#define EURYDICE_SLICE_LEN(s, _) s.len -// This macro is a pain because in case the dereferenced element type is an -// array, you cannot simply write `t x` as it would yield `int[4] x` instead, -// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that -// adds an extra argument to this macro at the last minute so that we have the -// correct type of *pointers* to elements. -#define Eurydice_slice_index(s, i, t, t_ptr_t, _ret_t) (((t_ptr_t)s.ptr)[i]) -#define Eurydice_slice_subslice(s, r, t, _, _ret_t) \ - EURYDICE_SLICE((t *)s.ptr, r.start, r.end) -#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _, _ret_t) \ - EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) -#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _, _ret_t) \ - EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) -#define Eurydice_array_to_slice(end, x, t, _ret_t) \ - EURYDICE_SLICE(x, 0, \ - end) /* x is already at an array type, no need for cast */ -#define Eurydice_array_to_subslice(_arraylen, x, r, t, _, _ret_t) \ - EURYDICE_SLICE((t *)x, r.start, r.end) -#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t, _ret_t) \ - EURYDICE_SLICE((t *)x, 0, r) -#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t, _ret_t) \ - EURYDICE_SLICE((t *)x, r, size) -#define Eurydice_array_repeat(dst, len, init, t, _ret_t) \ - ERROR "should've been desugared" -#define core_slice___Slice_T___len(s, t, _ret_t) EURYDICE_SLICE_LEN(s, t) -#define core_slice___Slice_T___copy_from_slice(dst, src, t, _ret_t) \ - memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) -#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ - ((Eurydice_slice){.ptr = ptr_, .len = len_}) - -#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ - len, src, dst, elem_type, _ret_t) \ - (memcpy(dst, src, len * sizeof(elem_type))) -#define core_array_TryFromSliceError uint8_t - -#define Eurydice_array_eq(sz, a1, a2, t, _, _ret_t) \ - (memcmp(a1, a2, sz * sizeof(t)) == 0) -#define core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq \ - Eurydice_array_eq - -#define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ - ((ret_t){.fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ - .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) -#define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ - ((ret_t){.fst = {.ptr = slice.ptr, .len = mid}, \ - .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ - .len = slice.len - mid}}) - -// Can't have a flexible array as a member of a union -- this violates strict -// aliasing rules. -typedef struct { - uint8_t tag; - uint8_t case_Ok[]; -} result_tryfromslice_flexible; - -// See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) \ - Eurydice_slice_to_array3((result_tryfromslice_flexible *)dst, src, \ - sizeof(t_arr)) - -static inline void Eurydice_slice_to_array3(result_tryfromslice_flexible *dst, - Eurydice_slice src, size_t sz) { - dst->tag = 0; - memcpy(dst->case_Ok, src.ptr, sz); -} - -// CORE STUFF (conversions, endianness, ...) - -static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { - uint32_t x = htobe32(src); - memcpy(dst, &x, 4); -} - -static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { - store64_le(buf, v); -} -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { - return load64_le(buf); -} - -static inline int64_t -core_convert_num___core__convert__From_i32__for_i64__59__from(int32_t x) { - return x; -} - -static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { - return __builtin_popcount(x0); -} - -// unsigned overflow wraparound semantics in C -static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { - return x + y; -} -static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { - return x - y; -} - -static inline void core_ops_arith__i32_319__add_assign(int32_t *x0, - int32_t *x1) { - *x0 = *x0 + *x1; -} - -static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v) { - return (*p) & v; -} -static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { - return (*p) >> v; -} - -// ITERATORS - -#define core_num_nonzero_NonZeroUsize size_t -#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ - (((iter_ptr)->start == (iter_ptr)->end) \ - ? ((ret_t){.tag = core_option_None}) \ - : ((ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) - -// Old name (TODO: remove once everyone has upgraded to the latest Charon) -#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ - Eurydice_range_iter_next - -#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ - Eurydice_range_iter_next - -// See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_into_iter(x, t, _ret_t) (x) -#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \ - Eurydice_into_iter - -typedef struct { - Eurydice_slice slice; - size_t chunk_size; -} Eurydice_chunks; - -// Can't use macros Eurydice_slice_subslice_{to,from} because they require a -// type, and this static inline function cannot receive a type as an argument. -// Instead, we receive the element size and use it to peform manual offset -// computations rather than going through the macros. -static inline Eurydice_slice chunk_next(Eurydice_chunks *chunks, - size_t element_size) { - size_t chunk_size = chunks->slice.len >= chunks->chunk_size - ? chunks->chunk_size - : chunks->slice.len; - Eurydice_slice curr_chunk = - ((Eurydice_slice){.ptr = chunks->slice.ptr, .len = chunk_size}); - chunks->slice = ((Eurydice_slice){ - .ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size, - .len = chunks->slice.len - chunk_size}); - return curr_chunk; -} - -#define core_slice___Slice_T___chunks(slice_, sz_, t, _ret_t) \ - ((Eurydice_chunks){.slice = slice_, .chunk_size = sz_}) -#define core_slice___Slice_T___chunks_exact(slice_, sz_, t, _ret_t) \ - ((Eurydice_chunks){ \ - .slice = {.ptr = slice_.ptr, .len = slice_.len - (slice_.len % sz_)}, \ - .chunk_size = sz_}) -#define core_slice_iter_Chunks Eurydice_chunks -#define core_slice_iter_ChunksExact Eurydice_chunks -#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( \ - iter, t, ret_t) \ - (((iter)->slice.len == 0) ? ((ret_t){.tag = core_option_None}) \ - : ((ret_t){.tag = core_option_Some, \ - .f0 = chunk_next(iter, sizeof(t))})) -#define core_slice_iter__core__slice__iter__ChunksExact__a__T__89__next( \ - iter, t, _ret_t) \ - core_slice_iter__core__slice__iter__Chunks__a__T__70__next(iter, t) - -typedef struct { - Eurydice_slice s; - size_t index; -} Eurydice_slice_iterator; - -#define core_slice___Slice_T___iter(x, t, _ret_t) \ - ((Eurydice_slice_iterator){.s = x, .index = 0}) -#define core_slice_iter_Iter Eurydice_slice_iterator -#define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, \ - ret_t) \ - (((iter)->index == (iter)->s.len) \ - ? ((ret_t){.tag = core_option_None}) \ - : ((ret_t){.tag = core_option_Some, \ - .f0 = ((iter)->index++, \ - &((t *)((iter)->s.ptr))[(iter)->index - 1])})) - -// STRINGS - -typedef const char *Prims_string; - -// MISC (UNTESTED) - -typedef void *core_fmt_Formatter; -typedef void *core_fmt_Arguments; -typedef void *core_fmt_rt_Argument; -#define core_fmt_rt__core__fmt__rt__Argument__a__1__new_display(x1, x2, x3, \ - x4) \ - NULL - -// VECTORS (ANCIENT, POSSIBLY UNTESTED) - -/* For now these are passed by value -- three words. We could conceivably change - * the representation to heap-allocate this struct and only pass around the - * pointer (one word). */ -typedef struct { - void *ptr; - size_t len; /* the number of elements */ - size_t alloc_size; /* the size of the allocation, in number of BYTES */ -} Eurydice_vec_s, *Eurydice_vec; - -/* Here, we set everything to zero rather than use a non-standard GCC - * statement-expression -- this suitably initializes ptr to NULL and len and - * size to 0. */ -#define EURYDICE_VEC_NEW(_) calloc(1, sizeof(Eurydice_vec_s)) -#define EURYDICE_VEC_PUSH(v, x, t) \ - do { \ - /* Grow the vector if capacity has been reached. */ \ - if (v->len == v->alloc_size / sizeof(t)) { \ - /* Assuming that this does not exceed SIZE_MAX, because code proven \ - * correct by Aeneas. Would this even happen in practice? */ \ - size_t new_size; \ - if (v->alloc_size == 0) \ - new_size = 8 * sizeof(t); \ - else if (v->alloc_size <= SIZE_MAX / 2) \ - /* TODO: discuss growth policy */ \ - new_size = 2 * v->alloc_size; \ - else \ - new_size = (SIZE_MAX / sizeof(t)) * sizeof(t); \ - v->ptr = realloc(v->ptr, new_size); \ - v->alloc_size = new_size; \ - } \ - ((t *)v->ptr)[v->len] = x; \ - v->len++; \ - } while (0) - -#define EURYDICE_VEC_DROP(v, t) \ - do { \ - free(v->ptr); \ - free(v); \ - } while (0) - -#define EURYDICE_VEC_INDEX(v, i, t) &((t *)v->ptr)[i] -#define EURYDICE_VEC_LEN(v, t) (v)->len - -/* TODO: remove GCC-isms */ -#define EURYDICE_BOX_NEW(x, t) \ - ({ \ - t *p = malloc(sizeof(t)); \ - *p = x; \ - p; \ - }) - -#define EURYDICE_REPLACE(ptr, new_v, t) \ - ({ \ - t old_v = *ptr; \ - *ptr = new_v; \ - old_v; \ - }) - -#if defined(__cplusplus) -} -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h deleted file mode 100644 index 000eda9e3..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_core_H -#define __internal_libcrux_core_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_core.h" -#include "eurydice_glue.h" - -extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( - core_fmt_rt_Argument x0[0U]); - -extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( - Eurydice_slice x0, Eurydice_slice x1); - -#define CORE_NUM__U32_8__BITS (32U) - -static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); - -#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) - -void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, uint8_t ret[32U]); - -#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT ((size_t)12U) - -#define LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT ((size_t)256U) - -#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) - -#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT \ - (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) - -#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) - -libcrux_ml_kem_types_MlKemPublicKey____1568size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uint8_t value[1568U]); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk); - -libcrux_ml_kem_types_MlKemPrivateKey____3168size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uint8_t value[3168U]); - -typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s { - uint8_t fst[1536U]; - uint8_t snd[1568U]; -} K___uint8_t_1536size_t__uint8_t_1568size_t_; - -libcrux_ml_kem_types_MlKemCiphertext____1568size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uint8_t value[1568U]); - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self); - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - Eurydice_slice lhs, Eurydice_slice rhs); - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self); - -void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, - uint8_t ret[1600U]); - -libcrux_ml_kem_types_MlKemPublicKey____1184size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uint8_t value[1184U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk); - -libcrux_ml_kem_types_MlKemPrivateKey____2400size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uint8_t value[2400U]); - -typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s { - uint8_t fst[1152U]; - uint8_t snd[1184U]; -} K___uint8_t_1152size_t__uint8_t_1184size_t_; - -libcrux_ml_kem_types_MlKemCiphertext____1088size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uint8_t value[1088U]); - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self); - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - Eurydice_slice lhs, Eurydice_slice rhs); - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self); - -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]); - -libcrux_ml_kem_types_MlKemPublicKey____800size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk); - -libcrux_ml_kem_types_MlKemPrivateKey____1632size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U]); - -typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s { - uint8_t fst[768U]; - uint8_t snd[800U]; -} K___uint8_t_768size_t__uint8_t_800size_t_; - -libcrux_ml_kem_types_MlKemCiphertext____768size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U]); - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self); - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, Eurydice_slice rhs); - -typedef struct - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - -void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, - uint8_t ret[33U]); - -void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, - uint8_t ret[34U]); - -typedef struct - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); - -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]); - -void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, - uint8_t ret[64U]); - -typedef struct - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[24U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, - uint8_t ret[24U]); - -typedef struct - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[20U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, - uint8_t ret[20U]); - -typedef struct - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[10U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, - uint8_t ret[10U]); - -typedef struct core_option_Option__Eurydice_slice_uint8_t_s { - core_option_Option__size_t_tags tag; - Eurydice_slice f0; -} core_option_Option__Eurydice_slice_uint8_t; - -typedef struct - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - int16_t case_Ok[16U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__int16_t_16size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, - int16_t ret[16U]); - -typedef struct - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s { - Eurydice_slice fst[4U]; - Eurydice_slice snd[4U]; -} K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_core_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h deleted file mode 100644 index d0aac553a..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_mlkem_avx2_H -#define __internal_libcrux_mlkem_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_mlkem_avx2.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_avx2.h" - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_mlkem_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_polynomial.h b/libcrux-ml-kem/c/internal/libcrux_polynomial.h deleted file mode 100644 index ba1228d32..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_polynomial.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_polynomial_H -#define __internal_libcrux_polynomial_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_polynomial.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" - -extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U]; - -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) - -#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / \ - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) - -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) - -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ - ((int16_t)1353) - -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ - (62209U) - -extern const uint8_t - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[256U] - [16U]; - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___multiply_by_constant( - libcrux_ml_kem_vector_PortableVector v, int16_t c); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___cond_subtract_3329( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress_1( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_1( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[2U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_1( - Eurydice_slice a); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_4( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[8U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_4( - Eurydice_slice a); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_5( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[10U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_5( - Eurydice_slice a); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[20U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_10( - Eurydice_slice a); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[22U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_11( - Eurydice_slice a); - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_12( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[24U]); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - Eurydice_slice a); - -size_t -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - Eurydice_slice a, Eurydice_slice out); - -typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[4U]; - uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t; - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs); - -typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[3U]; - uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t; - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs); - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___5int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___4int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector v); - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error); - -typedef struct - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - fst[2U]; - uint8_t snd; -} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_2size_t__uint8_t; - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector( - void); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice a); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - b); - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs); - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___5int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___4int32_t( - libcrux_ml_kem_vector_PortableVector v); - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector v, int16_t fer); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___11int32_t( - libcrux_ml_kem_vector_PortableVector v); - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___10int32_t( - libcrux_ml_kem_vector_PortableVector v); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_polynomial_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h deleted file mode 100644 index 11ada5b26..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_sha3_avx2_H -#define __internal_libcrux_sha3_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_sha3_avx2.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "intrinsics/libcrux_intrinsics_avx2.h" - -typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - libcrux_sha3_avx2_x4_incremental_KeccakState4; - -void libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]); - -void libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_sha3_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h deleted file mode 100644 index 58f4859bb..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_sha3_internal_H -#define __internal_libcrux_sha3_internal_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_sha3_internal.h" -#include "eurydice_glue.h" - -typedef libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - libcrux_sha3_portable_KeccakState1; - -static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_incremental_shake128_init(void) { - return libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); -} - -static inline void libcrux_sha3_portable_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice data0) { - Eurydice_slice buf[1U] = {data0}; - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - s, buf); -} - -static inline void -libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, buf); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - s, o0); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o10, (size_t)168U); - Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o2[1U]; - memcpy(o2, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o1); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o2); -} - -static inline void -libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( - s, buf); -} - -#define libcrux_sha3_Sha224 0 -#define libcrux_sha3_Sha256 1 -#define libcrux_sha3_Sha384 2 -#define libcrux_sha3_Sha512 3 - -typedef uint8_t libcrux_sha3_Algorithm; - -static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { - size_t uu____0; - switch (mode) { - case libcrux_sha3_Sha224: { - uu____0 = (size_t)28U; - break; - } - case libcrux_sha3_Sha256: { - uu____0 = (size_t)32U; - break; - } - case libcrux_sha3_Sha384: { - uu____0 = (size_t)48U; - break; - } - case libcrux_sha3_Sha512: { - uu____0 = (size_t)64U; - break; - } - default: { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, - __LINE__); - KRML_HOST_EXIT(253U); - } - } - return uu____0; -} - -static const size_t libcrux_sha3_generic_keccak__PI[24U] = { - (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, - (size_t)9U, (size_t)10U, (size_t)16U, (size_t)22U, (size_t)1U, - (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, (size_t)4U, - (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, - (size_t)8U, (size_t)14U, (size_t)15U, (size_t)21U}; - -static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { - (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, - (size_t)44U, (size_t)6U, (size_t)55U, (size_t)20U, (size_t)3U, - (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, (size_t)41U, - (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, - (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - s, o0); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o10, (size_t)168U); - Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o20[1U]; - memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o1); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o20, (size_t)168U); - Eurydice_slice o2[1U]; - memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o30[1U]; - memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o2); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o30, (size_t)168U); - Eurydice_slice o3[1U]; - memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o4[1U]; - memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o3); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - s, o4); -} - -static inline void -libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( - s, buf); -} - -static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self) { - return self[0U]; -} - -static inline uint32_t -libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( - libcrux_sha3_Algorithm v) { - uint32_t uu____0; - switch (v) { - case libcrux_sha3_Sha224: { - uu____0 = 1U; - break; - } - case libcrux_sha3_Sha256: { - uu____0 = 2U; - break; - } - case libcrux_sha3_Sha384: { - uu____0 = 3U; - break; - } - case libcrux_sha3_Sha512: { - uu____0 = 4U; - break; - } - default: { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, - __LINE__); - KRML_HOST_EXIT(253U); - } - } - return uu____0; -} - -static inline libcrux_sha3_Algorithm -libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from( - uint32_t v) { - libcrux_sha3_Algorithm uu____0; - switch (v) { - case 1U: { - uu____0 = libcrux_sha3_Sha224; - break; - } - case 2U: { - uu____0 = libcrux_sha3_Sha256; - break; - } - case 3U: { - uu____0 = libcrux_sha3_Sha384; - break; - } - case 4U: { - uu____0 = libcrux_sha3_Sha512; - break; - } - default: { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); - } - } - return uu____0; -} - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_sha3_internal_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c deleted file mode 100644 index 7fc937466..000000000 --- a/libcrux-ml-kem/c/libcrux_core.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_core.h" - -typedef size_t RangeTo__size_t; - -typedef size_t RangeFrom__size_t; - -typedef struct Option__int32_t_s { - core_option_Option__size_t_tags tag; - int32_t f0; -} Option__int32_t; - -typedef struct Option__uint32_t_s { - core_option_Option__size_t_tags tag; - uint32_t f0; -} Option__uint32_t; - -static uint8_t is_non_zero(uint8_t value) { - uint16_t value0 = (uint16_t)value; - uint16_t uu____0 = value0; - uint16_t result = (((uint32_t)uu____0 | - (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & - 0xFFFFU) >> - 8U & - 1U; - return (uint8_t)result; -} - -void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, - uint8_t ret[32U]) { - uint8_t mask = core_num__u8_6__wrapping_sub(is_non_zero(selector), 1U); - uint8_t out[32U] = {0U}; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; - i++) { - size_t i0 = i; - uint8_t uu____0 = - (uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t) & - (uint32_t)mask; - uint8_t *uu____1 = - &Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t); - out[i0] = (uint32_t)uu____0 | ((uint32_t)uu____1[0U] & (uint32_t)~mask); - } - memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemPublicKey____1568size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uint8_t value[1568U]) { - uint8_t uu____0[1568U]; - memcpy(uu____0, value, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey____1568size_t lit; - memcpy(lit.value, uu____0, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t){ - .sk = sk, .pk = pk}); -} - -libcrux_ml_kem_types_MlKemPrivateKey____3168size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uint8_t value[3168U]) { - uint8_t uu____0[3168U]; - memcpy(uu____0, value, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t lit; - memcpy(lit.value, uu____0, (size_t)3168U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemCiphertext____1568size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uint8_t value[1568U]) { - uint8_t uu____0[1568U]; - memcpy(uu____0, value, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t lit; - memcpy(lit.value, uu____0, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self) { - return self->value; -} - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - Eurydice_slice lhs, Eurydice_slice rhs) { - uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)1568U; i++) { - size_t i0 = i; - uint8_t uu____0 = - Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = (uint32_t)r | - ((uint32_t)uu____0 ^ - (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); - } - return is_non_zero(r); -} - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self) { - return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t, - Eurydice_slice); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, - uint8_t ret[1600U]) { - uint8_t out[1600U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1600U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)1600U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemPublicKey____1184size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uint8_t value[1184U]) { - uint8_t uu____0[1184U]; - memcpy(uu____0, value, (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey____1184size_t lit; - memcpy(lit.value, uu____0, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t){ - .sk = sk, .pk = pk}); -} - -libcrux_ml_kem_types_MlKemPrivateKey____2400size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uint8_t value[2400U]) { - uint8_t uu____0[2400U]; - memcpy(uu____0, value, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t lit; - memcpy(lit.value, uu____0, (size_t)2400U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemCiphertext____1088size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uint8_t value[1088U]) { - uint8_t uu____0[1088U]; - memcpy(uu____0, value, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t lit; - memcpy(lit.value, uu____0, (size_t)1088U * sizeof(uint8_t)); - return lit; -} - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self) { - return self->value; -} - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - Eurydice_slice lhs, Eurydice_slice rhs) { - uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)1088U; i++) { - size_t i0 = i; - uint8_t uu____0 = - Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = (uint32_t)r | - ((uint32_t)uu____0 ^ - (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); - } - return is_non_zero(r); -} - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self) { - return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, - Eurydice_slice); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]) { - uint8_t out[1120U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1120U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemPublicKey____800size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U]) { - uint8_t uu____0[800U]; - memcpy(uu____0, value, (size_t)800U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey____800size_t lit; - memcpy(lit.value, uu____0, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ - .sk = sk, .pk = pk}); -} - -libcrux_ml_kem_types_MlKemPrivateKey____1632size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U]) { - uint8_t uu____0[1632U]; - memcpy(uu____0, value, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t lit; - memcpy(lit.value, uu____0, (size_t)1632U * sizeof(uint8_t)); - return lit; -} - -libcrux_ml_kem_types_MlKemCiphertext____768size_t -libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U]) { - uint8_t uu____0[768U]; - memcpy(uu____0, value, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t lit; - memcpy(lit.value, uu____0, (size_t)768U * sizeof(uint8_t)); - return lit; -} - -uint8_t * -libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self) { - return self->value; -} - -uint8_t -libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, Eurydice_slice rhs) { - uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)768U; i++) { - size_t i0 = i; - uint8_t uu____0 = - Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = (uint32_t)r | - ((uint32_t)uu____0 ^ - (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); - } - return is_non_zero(r); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, - uint8_t ret[33U]) { - uint8_t out[33U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)33U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, - uint8_t ret[34U]) { - uint8_t out[34U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)34U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)34U * sizeof(uint8_t)); -} - -Eurydice_slice -libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self) { - return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, - Eurydice_slice); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]) { - uint8_t out[800U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)800U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)800U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, - uint8_t ret[64U]) { - uint8_t out[64U] = {0U}; - uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)64U, uu____0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - slice, uint8_t, void *); - memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, - uint8_t ret[24U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[24U]; - memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, - uint8_t ret[20U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[20U]; - memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, - uint8_t ret[10U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[10U]; - memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, - int16_t ret[16U]) { - if (self.tag == core_result_Ok) { - int16_t f0[16U]; - memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t)); - memcpy(ret, f0, (size_t)16U * sizeof(int16_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[8U]; - memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)8U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h deleted file mode 100644 index 049652436..000000000 --- a/libcrux-ml-kem/c/libcrux_core.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_core_H -#define __libcrux_core_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" - -typedef struct core_ops_range_Range__size_t_s { - size_t start; - size_t end; -} core_ops_range_Range__size_t; - -extern uint8_t Eurydice_bitand_pv_u8(uint8_t *x, uint8_t y); - -extern uint8_t Eurydice_shr_pv_u8(uint8_t *x, int32_t y); - -#define core_option_None 0 -#define core_option_Some 1 - -typedef uint8_t core_option_Option__size_t_tags; - -typedef struct core_option_Option__size_t_s { - core_option_Option__size_t_tags tag; - size_t f0; -} core_option_Option__size_t; - -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); - -static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); - -typedef struct libcrux_ml_kem_types_MlKemPublicKey____1568size_t_s { - uint8_t value[1568U]; -} libcrux_ml_kem_types_MlKemPublicKey____1568size_t; - -typedef struct - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t___s { - core_option_Option__size_t_tags tag; - libcrux_ml_kem_types_MlKemPublicKey____1568size_t f0; -} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__; - -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____3168size_t_s { - uint8_t value[3168U]; -} libcrux_ml_kem_types_MlKemPrivateKey____3168size_t; - -typedef struct libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t_s { - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk; - libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t; - -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1568size_t_s { - uint8_t value[1568U]; -} libcrux_ml_kem_types_MlKemCiphertext____1568size_t; - -typedef struct - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____1568size_t fst; - uint8_t snd[32U]; -} K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_; - -typedef struct libcrux_ml_kem_types_MlKemPublicKey____1184size_t_s { - uint8_t value[1184U]; -} libcrux_ml_kem_types_MlKemPublicKey____1184size_t; - -typedef struct - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t___s { - core_option_Option__size_t_tags tag; - libcrux_ml_kem_types_MlKemPublicKey____1184size_t f0; -} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__; - -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { - uint8_t value[2400U]; -} libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; - -typedef struct libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t_s { - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk; - libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t; - -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1088size_t_s { - uint8_t value[1088U]; -} libcrux_ml_kem_types_MlKemCiphertext____1088size_t; - -typedef struct - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____1088size_t fst; - uint8_t snd[32U]; -} K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; - -typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { - uint8_t value[800U]; -} libcrux_ml_kem_types_MlKemPublicKey____800size_t; - -typedef struct - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s { - core_option_Option__size_t_tags tag; - libcrux_ml_kem_types_MlKemPublicKey____800size_t f0; -} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; - -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { - uint8_t value[1632U]; -} libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; - -typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s { - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk; - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; - -typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { - uint8_t value[768U]; -} libcrux_ml_kem_types_MlKemCiphertext____768size_t; - -typedef struct - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____768size_t fst; - uint8_t snd[32U]; -} K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; - -#define core_result_Ok 0 -#define core_result_Err 1 - -typedef uint8_t - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags; - -typedef struct - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[8U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U]); - -typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; - -typedef struct - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s { - Eurydice_slice fst[1U]; - Eurydice_slice snd[1U]; -} K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_core_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c deleted file mode 100644 index 2a747078e..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ /dev/null @@ -1,1749 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem1024.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem512_portable.h" -#include "internal/libcrux_mlkem_avx2.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_11size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_11size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -static inline void ntt_vector_u__libcrux_ml_kem_vector_PortableVector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = (size_t)0U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U, (size_t)3328U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - u_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_11size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_PortableVector_11size_t(&u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_5size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0; - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_PortableVector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_4size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - secret_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_message__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_4size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_11size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_4size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message = compute_message__libcrux_ml_kem_vector_PortableVector_4size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1536size_t_4size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static void -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -typedef struct PortableHash____4size_t_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[4U]; -} PortableHash____4size_t; - -static inline PortableHash____4size_t shake128_init_absorb___4size_t( - uint8_t input[4U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final( - uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, - Eurydice_slice));); - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[4U]; - memcpy( - uu____1, state, - (size_t)4U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - PortableHash____4size_t lit; - memcpy( - lit.shake128_state, uu____1, - (size_t)4U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___4size_t( - PortableHash____4size_t *self, uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___4size_t( - PortableHash____4size_t *self, uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( - int16_t s[272U]) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); - PortableHash____4size_t xof_state = shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_4size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U][4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [4U])); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - re_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[4U]; - memcpy( - uu____2, re_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - error_1[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[4U]; - memcpy( - uu____2, error_1, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___4size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_4size_t0(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_4size_t( - &result[i1]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &t_as_ntt[i0], &r_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_4size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_PortableVector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_PortableVector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( - libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_PortableVector_352size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - input[4U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_11size_t_352size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re, - Eurydice_slice out) { - libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_PortableVector( - re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[4U][4U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - r_as_ntt[4U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[4U]; - memcpy( - error_1, uu____3.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___4size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_PortableVector_4size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[4U]; - memcpy( - uu____5, u, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_4size_t_1408size_t_11size_t_352size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_5size_t_160size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); -} - -static void -decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1536U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static void -decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___4size_t( - Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_4size_t1(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - matrix_element, &s_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - &result[i1], &product); - } - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1[4U]; - memcpy( - uu____1, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); -} - -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[4U][4U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[4U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_as_ntt[4U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_4size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____4[4U]; - memcpy( - uu____4, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[4U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t( - uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uu____4)); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -static libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - public_key); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1568size_t_4size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline bool -validate_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0[4U]; - memcpy( - uu____0, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - return validate_public_key__libcrux_ml_kem_vector_PortableVector_4size_t_1536size_t_1568size_t( - public_key); -} - -static bool validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ - uu____0; - if (validate_public_key___4size_t_1536size_t_1568size_t(public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h deleted file mode 100644 index b23582faf..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem1024_H -#define __libcrux_mlkem1024_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_platform.h" -#include "libcrux_polynomial.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_internal.h" - -#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 ((size_t)11U) - -#define LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 ((size_t)4U) - -#define LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 * \ - LIBCRUX_ML_KEM_MLKEM1024_RANK_1024) - -#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 ((size_t)5U) - -#define LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 + \ - LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024) - -#define LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 + (size_t)32U) - -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM1024_ETA1 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM1024_ETA1_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM1024_ETA1 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM1024_ETA2 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM1024_ETA2_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM1024_ETA2 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM1024_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ - (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ - LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024) - -#define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024 \ - (LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 + \ - LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 + \ - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem1024_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c deleted file mode 100644 index 00bc23653..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem512.h" - -#include "internal/libcrux_core.h" - -static void -decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -static bool validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if (validate_public_key___2size_t_768size_t_800size_t(public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h deleted file mode 100644 index 4cf838da4..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem512_H -#define __libcrux_mlkem512_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_platform.h" - -#define LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 ((size_t)10U) - -#define LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM512_RANK_512 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 * LIBCRUX_ML_KEM_MLKEM512_RANK_512) - -#define LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 ((size_t)4U) - -#define LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512) - -#define LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 + (size_t)32U) - -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM512_ETA1 ((size_t)3U) - -#define LIBCRUX_ML_KEM_MLKEM512_ETA1_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM512_ETA1 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM512_ETA2 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM512_ETA2_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM512_ETA2 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM512_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ - (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ - LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512) - -#define LIBCRUX_ML_KEM_MLKEM512_RANKED_BYTES_PER_RING_ELEMENT_512 \ - (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM512_SECRET_KEY_SIZE_512 \ - (LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 + \ - LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 + \ - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) - -void libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem512_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c deleted file mode 100644 index a1e71ded9..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ /dev/null @@ -1,1628 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem768.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem512_portable.h" -#include "internal/libcrux_mlkem_avx2.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_internal.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_PortableVector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_PortableVector( - &zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - re); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message = compute_message__libcrux_ml_kem_vector_PortableVector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_PortableVector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static void -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -typedef struct PortableHash____3size_t_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; -} PortableHash____3size_t; - -static inline PortableHash____3size_t shake128_init_absorb___3size_t( - uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final( - uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, - Eurydice_slice));); - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; - memcpy( - uu____1, state, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - PortableHash____3size_t lit; - memcpy( - lit.shake128_state, uu____1, - (size_t)3U * - sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t( - PortableHash____3size_t *self, uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = - &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - int16_t s[272U]) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_PortableVector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U])); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], - uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256( - uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, - Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_PortableVector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t0(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - &t_as_ntt[i0], &r_as_ntt[i0]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_PortableVector_3size_t(&result); - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - error_2, message, result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_PortableVector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_PortableVector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_PortableVector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - v = compute_ring_element_v__libcrux_ml_kem_vector_PortableVector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - compress_then_serialize_u__libcrux_ml_kem_vector_PortableVector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_PortableVector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -static void -decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static void -decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -static K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_3size_t1(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - product = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - matrix_element, &s_as_ntt[j]); - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - &result[i1], &product); - } - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_PortableVector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_PortableVector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair__libcrux_ml_kem_vector_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -static libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - public_key); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -closure__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t(void) { - return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_PortableVector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); -} - -static inline bool -validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_PortableVector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return validate_public_key__libcrux_ml_kem_vector_PortableVector_3size_t_1152size_t_1184size_t( - public_key); -} - -static bool validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (validate_public_key___3size_t_1152size_t_1184size_t(public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h deleted file mode 100644 index 5fb3491b8..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_H -#define __libcrux_mlkem768_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_platform.h" -#include "libcrux_polynomial.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_internal.h" - -#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) - -#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) - -#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) - -#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) - -#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) - -#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) - -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM768_ETA2 ((size_t)2U) - -#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE \ - (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) - -#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ - (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) - -#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ - LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) - -#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + \ - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + \ - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c deleted file mode 100644 index 19f0762b4..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem768_avx2.h" - -void libcrux_ml_kem_mlkem768_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h deleted file mode 100644 index 5b71584d3..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_avx2_H -#define __libcrux_mlkem768_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem768.h" - -void libcrux_ml_kem_mlkem768_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c deleted file mode 100644 index 22c124e6e..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem768_portable.h" - -void libcrux_ml_kem_mlkem768_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h deleted file mode 100644 index 9f6577139..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_portable_H -#define __libcrux_mlkem768_portable_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem768.h" - -void libcrux_ml_kem_mlkem768_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_portable_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c deleted file mode 100644 index 21fc1c974..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ /dev/null @@ -1,7623 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_mlkem_avx2.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_polynomial.h" -#include "internal/libcrux_sha3_avx2.h" - -typedef core_core_arch_x86___m256i SIMD256Vector; - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void) { - return libcrux_intrinsics_avx2_mm256_setzero_si256(); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( - void) { - return libcrux_ml_kem_vector_avx2_zero(); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_slice array) { - return libcrux_intrinsics_avx2_mm256_loadu_si256_i16(array); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice array) { - return libcrux_ml_kem_vector_avx2_from_i16_array(array); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { - return libcrux_ml_kem_vector_avx2_arithmetic_add(lhs, rhs[0U]); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - return libcrux_intrinsics_avx2_mm256_sub_epi16(lhs, rhs); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { - return libcrux_ml_kem_vector_avx2_arithmetic_sub(lhs, rhs[0U]); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i uu____0 = vector; - return libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - core_core_arch_x86___m256i v, int16_t c) { - return libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant(v, c); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i uu____0 = vector; - return libcrux_intrinsics_avx2_mm256_and_si256( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - return libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - vector, constant); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i v_minus_field_modulus = - libcrux_intrinsics_avx2_mm256_sub_epi16(vector, field_modulus); - core_core_arch_x86___m256i sign_mask = - libcrux_intrinsics_avx2_mm256_srai_epi16( - (int32_t)15, v_minus_field_modulus, core_core_arch_x86___m256i); - core_core_arch_x86___m256i conditional_add_field_modulus = - libcrux_intrinsics_avx2_mm256_and_si256(sign_mask, field_modulus); - return libcrux_intrinsics_avx2_mm256_add_epi16(v_minus_field_modulus, - conditional_add_field_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329(vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i t = libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER)); - core_core_arch_x86___m256i uu____1 = t; - core_core_arch_x86___m256i t0 = libcrux_intrinsics_avx2_mm256_add_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16((int16_t)512)); - core_core_arch_x86___m256i quotient = - libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)10, t0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = quotient; - core_core_arch_x86___m256i quotient_times_field_modulus = - libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - return libcrux_intrinsics_avx2_mm256_sub_epi16(vector, - quotient_times_field_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i constant0 = - libcrux_intrinsics_avx2_mm256_set1_epi16(constant); - core_core_arch_x86___m256i value_low = - libcrux_intrinsics_avx2_mm256_mullo_epi16(vector, constant0); - core_core_arch_x86___m256i uu____0 = value_low; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_mulhi_epi16(vector, constant0); - return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - return libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - vector, constant); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi16( - (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / - (int16_t)2); - core_core_arch_x86___m256i field_modulus_quartered = - libcrux_intrinsics_avx2_mm256_set1_epi16( - (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / - (int16_t)4); - core_core_arch_x86___m256i shifted = - libcrux_intrinsics_avx2_mm256_sub_epi16(field_modulus_halved, vector); - core_core_arch_x86___m256i mask = libcrux_intrinsics_avx2_mm256_srai_epi16( - (int32_t)15, shifted, core_core_arch_x86___m256i); - core_core_arch_x86___m256i shifted_to_positive = - libcrux_intrinsics_avx2_mm256_xor_si256(mask, shifted); - core_core_arch_x86___m256i shifted_to_positive_in_range = - libcrux_intrinsics_avx2_mm256_sub_epi16(shifted_to_positive, - field_modulus_quartered); - return libcrux_intrinsics_avx2_mm256_srli_epi16( - (int32_t)15, shifted_to_positive_in_range, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - core_core_arch_x86___m256i prod02 = - libcrux_intrinsics_avx2_mm256_mul_epu32(lhs, rhs); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_shuffle_epi32((int32_t)245, lhs, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i prod13 = libcrux_intrinsics_avx2_mm256_mul_epu32( - uu____0, libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, rhs, core_core_arch_x86___m256i)); - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi32(prod02, prod13); - return libcrux_intrinsics_avx2_mm256_unpackhi_epi64( - uu____1, libcrux_intrinsics_avx2_mm256_unpackhi_epi32(prod02, prod13)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - core_core_arch_x86___m256i v, core_core_arch_x86___m256i c) { - core_core_arch_x86___m256i value_low = - libcrux_intrinsics_avx2_mm256_mullo_epi16(v, c); - core_core_arch_x86___m256i uu____0 = value_low; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_mulhi_epi16(v, c); - return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( - -zeta3, -zeta3, zeta3, zeta3, -zeta2, -zeta2, zeta2, zeta2, -zeta1, - -zeta1, zeta1, zeta1, -zeta0, -zeta0, zeta0, zeta0); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - rhs, zetas); - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)160, vector, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step(vector, zeta0, zeta1, - zeta2, zeta3); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( - -zeta1, -zeta1, -zeta1, -zeta1, zeta1, zeta1, zeta1, zeta1, -zeta0, - -zeta0, -zeta0, -zeta0, zeta0, zeta0, zeta0, zeta0); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)238, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - rhs, zetas); - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)68, vector, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step(vector, zeta0, zeta1); -} - -inline core_core_arch_x86___m128i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - core_core_arch_x86___m128i v, core_core_arch_x86___m128i c) { - core_core_arch_x86___m128i value_low = - libcrux_intrinsics_avx2_mm_mullo_epi16(v, c); - core_core_arch_x86___m128i uu____0 = value_low; - core_core_arch_x86___m128i k = libcrux_intrinsics_avx2_mm_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m128i uu____1 = k; - core_core_arch_x86___m128i k_times_modulus = - libcrux_intrinsics_avx2_mm_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m128i value_high = - libcrux_intrinsics_avx2_mm_mulhi_epi16(v, c); - return libcrux_intrinsics_avx2_mm_sub_epi16(value_high, k_times_modulus); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - core_core_arch_x86___m128i rhs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m128i uu____0 = rhs; - core_core_arch_x86___m128i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); - core_core_arch_x86___m128i lhs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs0); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs0); - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); - core_core_arch_x86___m256i combined0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, combined, upper_coefficients, core_core_arch_x86___m256i); - return combined0; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step(vector, zeta); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)160, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = rhs; - core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1)); - core_core_arch_x86___m256i sum0 = - libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); - core_core_arch_x86___m256i uu____1 = sum0; - core_core_arch_x86___m256i sum_times_zetas = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( - zeta3, zeta3, (int16_t)0, (int16_t)0, zeta2, zeta2, - (int16_t)0, (int16_t)0, zeta1, zeta1, (int16_t)0, - (int16_t)0, zeta0, zeta0, (int16_t)0, (int16_t)0)); - core_core_arch_x86___m256i sum = - libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(sum0); - return libcrux_intrinsics_avx2_mm256_blend_epi16( - (int32_t)204, sum, sum_times_zetas, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - vector, zeta0, zeta1, zeta2, zeta3); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - core_core_arch_x86___m256i lhs = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)160, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = rhs; - core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)-1, - (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)-1, - (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)1, - (int16_t)1, (int16_t)1, (int16_t)1)); - core_core_arch_x86___m256i sum = - libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); - core_core_arch_x86___m256i uu____1 = sum; - core_core_arch_x86___m256i sum_times_zetas = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( - zeta1, zeta1, zeta1, zeta1, (int16_t)0, (int16_t)0, - (int16_t)0, (int16_t)0, zeta0, zeta0, zeta0, zeta0, - (int16_t)0, (int16_t)0, (int16_t)0, (int16_t)0)); - return libcrux_intrinsics_avx2_mm256_blend_epi16( - (int32_t)240, sum, sum_times_zetas, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step(vector, zeta0, - zeta1); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - core_core_arch_x86___m128i lhs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m128i rhs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs); - core_core_arch_x86___m128i uu____0 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); - core_core_arch_x86___m256i combined0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, combined, upper_coefficients0, - core_core_arch_x86___m256i); - return combined0; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step(vector, zeta); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - core_core_arch_x86___m256i v) { - core_core_arch_x86___m256i uu____0 = v; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)16, v, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i result = - libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); - core_core_arch_x86___m256i result0 = libcrux_intrinsics_avx2_mm256_slli_epi32( - (int32_t)16, result, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_srai_epi32((int32_t)16, result0, - core_core_arch_x86___m256i); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i shuffle_with = - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)15, (int8_t)14, (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, - (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, - (int8_t)5, (int8_t)4, (int8_t)1, (int8_t)0, (int8_t)15, (int8_t)14, - (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, (int8_t)3, (int8_t)2, - (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, - (int8_t)1, (int8_t)0); - core_core_arch_x86___m256i lhs_shuffled = - libcrux_intrinsics_avx2_mm256_shuffle_epi8(lhs, shuffle_with); - core_core_arch_x86___m256i lhs_shuffled0 = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, lhs_shuffled, core_core_arch_x86___m256i); - core_core_arch_x86___m128i lhs_evens = - libcrux_intrinsics_avx2_mm256_castsi256_si128(lhs_shuffled0); - core_core_arch_x86___m256i lhs_evens0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_evens); - core_core_arch_x86___m128i lhs_odds = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, lhs_shuffled0, core_core_arch_x86___m128i); - core_core_arch_x86___m256i lhs_odds0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_odds); - core_core_arch_x86___m256i rhs_shuffled = - libcrux_intrinsics_avx2_mm256_shuffle_epi8(rhs, shuffle_with); - core_core_arch_x86___m256i rhs_shuffled0 = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, rhs_shuffled, core_core_arch_x86___m256i); - core_core_arch_x86___m128i rhs_evens = - libcrux_intrinsics_avx2_mm256_castsi256_si128(rhs_shuffled0); - core_core_arch_x86___m256i rhs_evens0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_evens); - core_core_arch_x86___m128i rhs_odds = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, rhs_shuffled0, core_core_arch_x86___m128i); - core_core_arch_x86___m256i rhs_odds0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_odds); - core_core_arch_x86___m256i left = - libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_evens0, rhs_evens0); - core_core_arch_x86___m256i right = - libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_odds0, rhs_odds0); - core_core_arch_x86___m256i right0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s(right); - core_core_arch_x86___m256i uu____0 = right0; - core_core_arch_x86___m256i right1 = libcrux_intrinsics_avx2_mm256_mullo_epi32( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi32( - -(int32_t)zeta3, (int32_t)zeta3, -(int32_t)zeta2, (int32_t)zeta2, - -(int32_t)zeta1, (int32_t)zeta1, -(int32_t)zeta0, (int32_t)zeta0)); - core_core_arch_x86___m256i products_left = - libcrux_intrinsics_avx2_mm256_add_epi32(left, right1); - core_core_arch_x86___m256i products_left0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - products_left); - core_core_arch_x86___m256i uu____1 = rhs; - core_core_arch_x86___m256i rhs_adjacent_swapped = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)13, (int8_t)12, (int8_t)15, (int8_t)14, - (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, (int8_t)5, - (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, (int8_t)0, - (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)15, - (int8_t)14, (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, - (int8_t)5, (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, - (int8_t)0, (int8_t)3, (int8_t)2)); - core_core_arch_x86___m256i products_right = - libcrux_intrinsics_avx2_mm256_madd_epi16(lhs, rhs_adjacent_swapped); - core_core_arch_x86___m256i products_right0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - products_right); - core_core_arch_x86___m256i products_right1 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)16, products_right0, - core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_blend_epi16((int32_t)170, products_left0, - products_right1, - core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(lhs[0U], rhs[0U], zeta0, - zeta1, zeta2, zeta3); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]) { - core_core_arch_x86___m256i lsb_to_msb = - libcrux_intrinsics_avx2_mm256_slli_epi16((int32_t)15, vector, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i low_msbs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(lsb_to_msb); - core_core_arch_x86___m128i high_msbs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, lsb_to_msb, core_core_arch_x86___m128i); - core_core_arch_x86___m128i msbs = - libcrux_intrinsics_avx2_mm_packs_epi16(low_msbs, high_msbs); - int32_t bits_packed = libcrux_intrinsics_avx2_mm_movemask_epi8(msbs); - uint8_t serialized[2U] = {0U}; - serialized[0U] = (uint8_t)bits_packed; - serialized[1U] = (uint8_t)(bits_packed >> 8U); - memcpy(ret, serialized, (size_t)2U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]) { - uint8_t ret0[2U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_1(vector, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_1(Eurydice_slice bytes) { - int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_set_epi16( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, - uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, - uu____14, - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, - uint8_t)); - core_core_arch_x86___m256i shift_lsb_to_msb = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 8U, (int16_t)1 << 9U, (int16_t)1 << 10U, - (int16_t)1 << 11U, (int16_t)1 << 12U, (int16_t)1 << 13U, - (int16_t)1 << 14U, (int16_t)1 << 15U, (int16_t)1 << 8U, - (int16_t)1 << 9U, (int16_t)1 << 10U, (int16_t)1 << 11U, - (int16_t)1 << 12U, (int16_t)1 << 13U, (int16_t)1 << 14U, - (int16_t)1 << 15U); - core_core_arch_x86___m256i coefficients_in_msb = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsb_to_msb); - return libcrux_intrinsics_avx2_mm256_srli_epi16( - (int32_t)15, coefficients_in_msb, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_1(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]) { - uint8_t serialized[16U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____1, - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, (int8_t)4, - (int8_t)0, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, - (int8_t)4, (int8_t)0)); - core_core_arch_x86___m256i uu____2 = adjacent_8_combined; - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0, - (int32_t)0, (int32_t)0, (int32_t)4, (int32_t)0)); - core_core_arch_x86___m128i combined0 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(combined); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_slice((size_t)16U, serialized, uint8_t, Eurydice_slice), - combined0); - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)16U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]) { - uint8_t ret0[8U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_4(vector, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U); - int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_set_epi16( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, - uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, - uu____14, - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, - uint8_t)); - core_core_arch_x86___m256i coefficients_in_msb = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients_in_lsb = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients_in_msb, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____15 = coefficients_in_lsb; - return libcrux_intrinsics_avx2_mm256_and_si256( - uu____15, libcrux_intrinsics_avx2_mm256_set1_epi16(((int16_t)1 << 4U) - - (int16_t)1)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_4(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22, - (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)22, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)8, adjacent_4_combined0, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_8_combined; - core_core_arch_x86___m256i adjacent_8_combined0 = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); - core_core_arch_x86___m256i adjacent_8_combined1 = - libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)5U, .end = (size_t)21U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[10U]; - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[10U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]) { - uint8_t ret0[10U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_5(vector, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_5(Eurydice_slice bytes) { - uint8_t uu____0 = - Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____1 = - Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____2 = - Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____3 = - Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____4 = - Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____5 = - Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____6 = - Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____7 = - Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____8 = - Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____9 = - Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____10 = - Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____11 = - Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____12 = - Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____13 = - Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____14 = - Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - core_core_arch_x86___m128i coefficients = libcrux_intrinsics_avx2_mm_set_epi8( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, uu____14, - Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); - core_core_arch_x86___m256i coefficients_loaded = - libcrux_intrinsics_avx2_mm256_castsi128_si256(coefficients); - core_core_arch_x86___m256i coefficients_loaded0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients_loaded, coefficients, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____15 = coefficients_loaded0; - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____15, - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)15, (int8_t)14, (int8_t)15, (int8_t)14, (int8_t)13, - (int8_t)12, (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, - (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)9, - (int8_t)8, (int8_t)7, (int8_t)6, (int8_t)7, (int8_t)6, (int8_t)5, - (int8_t)4, (int8_t)5, (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m256i uu____16 = coefficients0; - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____16, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 5U, (int16_t)1 << 2U, - (int16_t)1 << 7U, (int16_t)1 << 4U, (int16_t)1 << 9U, - (int16_t)1 << 6U, (int16_t)1 << 11U, (int16_t)1 << 0U, - (int16_t)1 << 5U, (int16_t)1 << 2U, (int16_t)1 << 7U, - (int16_t)1 << 4U, (int16_t)1 << 9U, (int16_t)1 << 6U, - (int16_t)1 << 11U)); - return libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)11, coefficients1, - core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_5(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)12, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)11, - (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)4, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)12, (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, - (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)10U, .end = (size_t)26U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[20U]; - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[20U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]) { - uint8_t ret0[20U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_10(vector, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, - (int16_t)1 << 6U, (int16_t)1 << 0U, (int16_t)1 << 2U, - (int16_t)1 << 4U, (int16_t)1 << 6U, (int16_t)1 << 0U, - (int16_t)1 << 2U, (int16_t)1 << 4U, (int16_t)1 << 6U, - (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, - (int16_t)1 << 6U); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____0 = lower_coefficients; - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____0, - libcrux_intrinsics_avx2_mm_set_epi8(9U, 8U, 8U, 7U, 7U, 6U, 6U, 5U, - 4U, 3U, 3U, 2U, 2U, 1U, 1U, 0U)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)4U, - .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____1 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 13U, - 12U, 12U, 11U, 10U, 9U, - 9U, 8U, 8U, 7U, 7U, 6U)); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients, upper_coefficients0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients2 = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)6, coefficients1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = coefficients2; - core_core_arch_x86___m256i coefficients3 = - libcrux_intrinsics_avx2_mm256_and_si256( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - ((int16_t)1 << 10U) - (int16_t)1)); - return coefficients3; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_10(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_to_i16_array( - core_core_arch_x86___m256i v, int16_t ret[16U]) { - int16_t output[16U] = {0U}; - libcrux_intrinsics_avx2_mm256_storeu_si256_i16( - Eurydice_array_to_slice((size_t)16U, output, int16_t, Eurydice_slice), v); - memcpy(ret, output, (size_t)16U * sizeof(int16_t)); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]) { - int16_t uu____0[16U]; - memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); - libcrux_ml_kem_vector_avx2_portable_PortableVector lit; - memcpy(lit.elements, uu____0, (size_t)16U * sizeof(int16_t)); - return lit; -} - -inline void libcrux_ml_kem_vector_avx2_portable_serialize_11( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]) { - uint8_t result[22U] = {0U}; - result[0U] = (uint8_t)v.elements[0U]; - result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | - (uint32_t)(uint8_t)(v.elements[0U] >> 8U); - result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | - (uint32_t)(uint8_t)(v.elements[1U] >> 5U); - result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); - result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | - (uint32_t)(uint8_t)(v.elements[2U] >> 10U); - result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | - (uint32_t)(uint8_t)(v.elements[3U] >> 7U); - result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | - (uint32_t)(uint8_t)(v.elements[4U] >> 4U); - result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); - result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | - (uint32_t)(uint8_t)(v.elements[5U] >> 9U); - result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | - (uint32_t)(uint8_t)(v.elements[6U] >> 6U); - result[10U] = (uint8_t)(v.elements[7U] >> 3U); - result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; - result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) - << 3U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); - result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); - result[14U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); - result[15U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) - << 1U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); - result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); - result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) - << 7U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[18U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); - result[19U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); - result[20U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) - << 5U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); - result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]) { - int16_t array[16U]; - libcrux_ml_kem_vector_avx2_to_i16_array(vector, array); - int16_t uu____0[16U]; - memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); - libcrux_ml_kem_vector_avx2_portable_PortableVector input = - libcrux_ml_kem_vector_avx2_portable_from_i16_array(uu____0); - uint8_t ret0[22U]; - libcrux_ml_kem_vector_avx2_portable_serialize_11(input, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]) { - uint8_t ret0[22U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_11(vector, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_zero(void) { - libcrux_ml_kem_vector_avx2_portable_PortableVector lit; - lit.elements[0U] = (int16_t)0; - lit.elements[1U] = (int16_t)0; - lit.elements[2U] = (int16_t)0; - lit.elements[3U] = (int16_t)0; - lit.elements[4U] = (int16_t)0; - lit.elements[5U] = (int16_t)0; - lit.elements[6U] = (int16_t)0; - lit.elements[7U] = (int16_t)0; - lit.elements[8U] = (int16_t)0; - lit.elements[9U] = (int16_t)0; - lit.elements[10U] = (int16_t)0; - lit.elements[11U] = (int16_t)0; - lit.elements[12U] = (int16_t)0; - lit.elements[13U] = (int16_t)0; - lit.elements[14U] = (int16_t)0; - lit.elements[15U] = (int16_t)0; - return lit; -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes) { - libcrux_ml_kem_vector_avx2_portable_PortableVector result = - libcrux_ml_kem_vector_avx2_portable_zero(); - int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____1 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; - int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; - int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____5 = - uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____6 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; - int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____8 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; - int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____10 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; - int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____12 = - uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t) - << 1U; - uint8_t *uu____13 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; - int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____15 = - &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; - int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____17 = - &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; - int16_t uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; - int16_t uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; - int16_t uu____22 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____23 = - uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, - uint8_t, uint8_t *, uint8_t); - result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; - int16_t uu____25 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, - uint8_t, uint8_t *, uint8_t); - result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; - int16_t uu____27 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, - uint8_t, uint8_t *, uint8_t); - result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; - int16_t uu____29 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____30 = - uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, - uint8_t, uint8_t *, uint8_t) - << 1U; - uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, - uint8_t, uint8_t *, uint8_t); - result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; - int16_t uu____32 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, - uint8_t, uint8_t *, uint8_t); - result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; - int16_t uu____34 = - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, - uint8_t, uint8_t *, uint8_t); - result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; - return result; -} - -inline void libcrux_ml_kem_vector_avx2_portable_to_i16_array( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]) { - memcpy(ret, v.elements, (size_t)16U * sizeof(int16_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_11(Eurydice_slice bytes) { - libcrux_ml_kem_vector_avx2_portable_PortableVector output = - libcrux_ml_kem_vector_avx2_portable_deserialize_11(bytes); - int16_t ret[16U]; - libcrux_ml_kem_vector_avx2_portable_to_i16_array(output, ret); - return libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_array_to_slice((size_t)16U, ret, int16_t, Eurydice_slice)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_11(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8, - (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, - (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)13, (int8_t)12, - (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)5, - (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)12U, .end = (size_t)28U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[24U]; - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[24U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]) { - uint8_t ret0[24U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_12(vector, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____0 = lower_coefficients; - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____0, - libcrux_intrinsics_avx2_mm_set_epi8(11U, 10U, 10U, 9U, 8U, 7U, 7U, 6U, - 5U, 4U, 4U, 3U, 2U, 1U, 1U, 0U)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____1 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 12U, - 11U, 11U, 10U, 9U, 8U, - 8U, 7U, 6U, 5U, 5U, 4U)); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients, upper_coefficients0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients2 = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = coefficients2; - core_core_arch_x86___m256i coefficients3 = - libcrux_intrinsics_avx2_mm256_and_si256( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - ((int16_t)1 << 12U) - (int16_t)1)); - return coefficients3; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_12(bytes); -} - -inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( - Eurydice_slice input, Eurydice_slice output) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i potential_coefficients = - libcrux_ml_kem_vector_avx2_serialize_deserialize_12(input); - core_core_arch_x86___m256i compare_with_field_modulus = - libcrux_intrinsics_avx2_mm256_cmpgt_epi16(field_modulus, - potential_coefficients); - uint8_t good[2U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_1(compare_with_field_modulus, - good); - uint8_t lower_shuffles[16U]; - memcpy(lower_shuffles, - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( - size_t)good[0U]], - (size_t)16U * sizeof(uint8_t)); - core_core_arch_x86___m128i lower_shuffles0 = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( - (size_t)16U, lower_shuffles, uint8_t, Eurydice_slice)); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm256_castsi256_si128(potential_coefficients); - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8(lower_coefficients, - lower_shuffles0); - libcrux_intrinsics_avx2_mm_storeu_si128(output, lower_coefficients0); - size_t sampled_count = (size_t)core_num__u8_6__count_ones(good[0U]); - uint8_t upper_shuffles[16U]; - memcpy(upper_shuffles, - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( - size_t)good[1U]], - (size_t)16U * sizeof(uint8_t)); - core_core_arch_x86___m128i upper_shuffles0 = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( - (size_t)16U, upper_shuffles, uint8_t, Eurydice_slice)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, potential_coefficients, core_core_arch_x86___m128i); - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8(upper_coefficients, - upper_shuffles0); - libcrux_intrinsics_avx2_mm_storeu_si128( - Eurydice_slice_subslice( - output, - ((core_ops_range_Range__size_t){.start = sampled_count, - .end = sampled_count + (size_t)8U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice), - upper_coefficients0); - size_t uu____0 = sampled_count; - return uu____0 + (size_t)core_num__u8_6__count_ones(good[1U]); -} - -size_t -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - Eurydice_slice input, Eurydice_slice output) { - return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( - libcrux_ml_kem_vector_avx2_portable_PortableVector *self) { - return self[0U]; -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( - core_core_arch_x86___m256i *self) { - return self[0U]; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - lit; - lit.coefficients[0U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[1U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[2U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[3U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[4U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[5U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[6U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[7U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[8U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[9U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[10U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[11U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[12U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[13U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[14U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[15U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - bytes); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline core_core_arch_x86___m256i shift_right___15int32_t( - core_core_arch_x86___m256i vector) { - return libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)15, vector, - core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i shift_right___15int32_t0( - core_core_arch_x86___m256i vector) { - return shift_right___15int32_t(vector); -} - -static core_core_arch_x86___m256i -to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a) { - core_core_arch_x86___m256i t = shift_right___15int32_t0(a); - core_core_arch_x86___m256i fm = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &fm); -} - -static inline void -serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[4U]; - memcpy( - uu____1, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[4U]; - memcpy( - uu____0, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 Simd256Hash; - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___4size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___4size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], - uint8_t(*)[168U], uint8_t[168U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice_subslice( - a, - ((core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - result.coefficients[i0] = uu____0; - } - return result; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U][4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[4U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____9 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t uu____2 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t random_bits_as_u32 = - uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = - (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t random_bits_as_u24 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - randomness); - return uu____0; -} - -static inline void ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) { - size_t j = i; - core_core_arch_x86___m256i t = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - re->coefficients[j + step], (int16_t)-1600); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - re->coefficients[j], &t); - re->coefficients[j + step] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - re->coefficients[j], &t); - re->coefficients[j] = uu____1; - } -} - -typedef struct - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector_s { - core_core_arch_x86___m256i fst; - core_core_arch_x86___m256i snd; -} __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector; - -static core_core_arch_x86___m256i -montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v, int16_t fer) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - v, fer); -} - -static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - int16_t zeta_r) { - core_core_arch_x86___m256i t = - montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector(b, - zeta_r); - b = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - a, &t); - a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &t); - return (( - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ - .fst = a, .snd = b}); -} - -static inline void -ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - core_core_arch_x86___m256i x = uu____0.fst; - core_core_arch_x86___m256i y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline void ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -static inline void ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -static inline void -poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - self->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); - size_t zeta_i = (size_t)1U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; - memcpy( - uu____2, re_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - out = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - &self->coefficients[i0], &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)3U]); - out.coefficients[i0] = uu____0; - } - return out; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static core_core_arch_x86___m256i -to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); -} - -static inline void -add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - core_core_arch_x86___m256i coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( - self->coefficients[j]); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[4U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[4U]; - memcpy( - uu____4, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( - uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; - memcpy( - uu____2, error_1, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___4size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -static inline void -invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -static inline void -invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - int16_t zeta_r) { - core_core_arch_x86___m256i a_minus_b = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - b, &a); - a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &b)); - b = montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_minus_b, zeta_r); - return (( - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ - .fst = a, .snd = b}); -} - -static inline void -invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = - offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = - step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - core_core_arch_x86___m256i x = uu____0.fst; - core_core_arch_x86___m256i y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - self->coefficients[j], (int16_t)1441); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static core_core_arch_x86___m256i -decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(), - &v), - (int16_t)1665); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - core_core_arch_x86___m256i coefficient_compressed = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i uu____0 = - decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - result.coefficients[i0], (int16_t)1441); - core_core_arch_x86___m256i tmp = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &message->coefficients[i0]); - core_core_arch_x86___m256i tmp0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &tmp); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___10int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)10) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___10int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___10int32_t(vector); -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___10int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___11int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)11) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___11int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___11int32_t(vector); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___11int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[4U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___4int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)4) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___4int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___4int32_t(vector); -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___4int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___5int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)5) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___5int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___5int32_t(vector); -} - -static inline void -compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficients = compress___5int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - coefficients, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice out) { - compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[4U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - memcpy( - error_1, uu____3.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___4size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; - memcpy( - uu____5, u, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___4size_t( - Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___10int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)10); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i -decompress_ciphertext_coefficient___10int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___10int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___10int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___11int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)11); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i -decompress_ciphertext_coefficient___11int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___11int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___11int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___4int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)4); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i decompress_ciphertext_coefficient___4int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___4int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___4int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___5int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)5); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i decompress_ciphertext_coefficient___5int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___5int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - bytes); - re.coefficients[i0] = uu____0; - core_core_arch_x86___m256i uu____1 = - decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - b) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - b.coefficients[i0], (int16_t)1441); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - self->coefficients[i0], &coefficient_normal_form)); - b.coefficients[i0] = uu____0; - } - return b; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static inline void -compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - uint8_t ret[32U]) { - uint8_t serialized[32U] = {0U}; - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - core_core_arch_x86___m256i coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0]); - core_core_arch_x86___m256i coefficient_compressed = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *);); - memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1536U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[3U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, - Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___10int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___11int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[2U], - uint8_t ret[768U]) { - uint8_t out[768U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)768U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U], - Eurydice_slice seed_for_a, uint8_t ret[800U]) { - uint8_t public_key_serialized[800U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[2U]; - memcpy( - uu____1, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, - (size_t)768U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( - Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[2U]; - memcpy( - uu____0, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___2size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][504U]) { - uint8_t out[2U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - uint8_t dummy_out1[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( - uint8_t randomness[2U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___2size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][168U]) { - uint8_t out[2U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - uint8_t dummy_out1[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uint8_t randomness[2U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - size_t sampled_coefficients[2U] = {0U}; - int16_t out[2U][272U] = {{0U}}; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U][2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[2U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], - uint8_t ret[2U][192U]) { - uint8_t out[2U][192U] = {{0U}}; - uint8_t dummy_out0[192U] = {0U}; - uint8_t dummy_out1[192U] = {0U}; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], - Eurydice_slice), - (size_t)1U, uint8_t[192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - randomness); - return uu____0; -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; - memcpy( - uu____2, re_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[2U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____3, domain_separator) - .fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[2U]; - memcpy( - uu____4, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)1632U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( - uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[2U][128U]) { - uint8_t out[2U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - uint8_t dummy_out1[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; - memcpy( - uu____2, error_1, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___2size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[2U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[768U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( - Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[2U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; - memcpy( - error_1, uu____3.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___2size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[768U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; - memcpy( - uu____5, u, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___2size_t( - Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, - (size_t)640U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)768U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)800U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t( - Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h deleted file mode 100644 index 026947fe9..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem_avx2_H -#define __libcrux_mlkem_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_avx2.h" - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( - void); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_slice array); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice array); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - core_core_arch_x86___m256i v, int16_t c); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - core_core_arch_x86___m256i vector); - -#define LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER \ - ((int16_t)20159) - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - core_core_arch_x86___m256i v, core_core_arch_x86___m256i c); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m128i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - core_core_arch_x86___m128i v, core_core_arch_x86___m128i c); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - core_core_arch_x86___m256i v); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_1( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_4( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_5( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_10( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_to_i16_array(core_core_arch_x86___m256i v, - int16_t ret[16U]); - -typedef struct libcrux_ml_kem_vector_avx2_portable_PortableVector_s { - int16_t elements[16U]; -} libcrux_ml_kem_vector_avx2_portable_PortableVector; - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]); - -void libcrux_ml_kem_vector_avx2_portable_serialize_11( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_zero(void); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_portable_to_i16_array( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_11( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_12( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - Eurydice_slice bytes); - -size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( - Eurydice_slice input, Eurydice_slice output); - -size_t -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - Eurydice_slice input, Eurydice_slice output); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( - libcrux_ml_kem_vector_avx2_portable_PortableVector *self); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( - core_core_arch_x86___m256i *self); - -typedef struct - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_s { - core_core_arch_x86___m256i coefficients[16U]; -} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h deleted file mode 100644 index 988a2e7f2..000000000 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_platform_H -#define __libcrux_platform_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" - -extern bool libcrux_platform_platform_simd256_support(void); - -extern bool libcrux_platform_platform_simd128_support(void); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_platform_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_polynomial.c b/libcrux-ml-kem/c/libcrux_polynomial.c deleted file mode 100644 index 61c774813..000000000 --- a/libcrux-ml-kem/c/libcrux_polynomial.c +++ /dev/null @@ -1,2531 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_polynomial.h" - -#include "internal/libcrux_core.h" - -const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = { - (int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, - (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, - (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, - (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, - (int16_t)573, (int16_t)-1325, (int16_t)264, (int16_t)383, - (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, - (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, - (int16_t)-1542, (int16_t)411, (int16_t)-205, (int16_t)-1571, - (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, - (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, - (int16_t)516, (int16_t)-8, (int16_t)-320, (int16_t)-666, - (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, - (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, - (int16_t)107, (int16_t)-1421, (int16_t)-247, (int16_t)-951, - (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, - (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, - (int16_t)-1103, (int16_t)430, (int16_t)555, (int16_t)843, - (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, - (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, - (int16_t)-291, (int16_t)-460, (int16_t)1574, (int16_t)1653, - (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, - (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, - (int16_t)-1590, (int16_t)644, (int16_t)-872, (int16_t)349, - (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, - (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, - (int16_t)1322, (int16_t)-1285, (int16_t)-1465, (int16_t)384, - (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, - (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, - (int16_t)-1185, (int16_t)-1530, (int16_t)-1278, (int16_t)794, - (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, - (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, - (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; - -const uint8_t - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE - [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, - 255U, 255U, 255U}, - {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 255U, 255U}, - {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, - 15U, 255U, 255U}, - {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 14U, 15U}}; - -static inline libcrux_ml_kem_vector_PortableVector zero(void) { - libcrux_ml_kem_vector_PortableVector lit; - lit.elements[0U] = (int16_t)0; - lit.elements[1U] = (int16_t)0; - lit.elements[2U] = (int16_t)0; - lit.elements[3U] = (int16_t)0; - lit.elements[4U] = (int16_t)0; - lit.elements[5U] = (int16_t)0; - lit.elements[6U] = (int16_t)0; - lit.elements[7U] = (int16_t)0; - lit.elements[8U] = (int16_t)0; - lit.elements[9U] = (int16_t)0; - lit.elements[10U] = (int16_t)0; - lit.elements[11U] = (int16_t)0; - lit.elements[12U] = (int16_t)0; - lit.elements[13U] = (int16_t)0; - lit.elements[14U] = (int16_t)0; - lit.elements[15U] = (int16_t)0; - return lit; -} - -static libcrux_ml_kem_vector_PortableVector ZERO(void) { return zero(); } - -static inline libcrux_ml_kem_vector_PortableVector from_i16_array( - Eurydice_slice array) { - libcrux_ml_kem_vector_PortableVector lit; - int16_t ret[16U]; - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice(array, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, int16_t[16U], void *); - core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( - dst, ret); - memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); - return lit; -} - -static libcrux_ml_kem_vector_PortableVector from_i16_array0( - Eurydice_slice array) { - return from_i16_array(array); -} - -static inline libcrux_ml_kem_vector_PortableVector add( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - size_t uu____0 = i0; - lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; - } - return lhs; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs) { - return add(lhs, rhs); -} - -static inline libcrux_ml_kem_vector_PortableVector sub( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - size_t uu____0 = i0; - lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; - } - return lhs; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - libcrux_ml_kem_vector_PortableVector lhs, - libcrux_ml_kem_vector_PortableVector *rhs) { - return sub(lhs, rhs); -} - -static inline libcrux_ml_kem_vector_PortableVector multiply_by_constant( - libcrux_ml_kem_vector_PortableVector v, int16_t c) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] * c; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___multiply_by_constant( - libcrux_ml_kem_vector_PortableVector v, int16_t c) { - return multiply_by_constant(v, c); -} - -static inline libcrux_ml_kem_vector_PortableVector bitwise_and_with_constant( - libcrux_ml_kem_vector_PortableVector v, int16_t c) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] & c; - } - return v; -} - -static libcrux_ml_kem_vector_PortableVector bitwise_and_with_constant0( - libcrux_ml_kem_vector_PortableVector v, int16_t c) { - return bitwise_and_with_constant(v, c); -} - -static inline libcrux_ml_kem_vector_PortableVector cond_subtract_3329( - libcrux_ml_kem_vector_PortableVector v) { - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - core_option_Option__size_t uu____0 = - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t); - if (!(uu____0.tag == core_option_None)) { - size_t i = uu____0.f0; - if (v.elements[i] >= (int16_t)3329) { - size_t uu____1 = i; - v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; - } - continue; - } - return v; - } -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___cond_subtract_3329( - libcrux_ml_kem_vector_PortableVector v) { - return cond_subtract_3329(v); -} - -#define BARRETT_MULTIPLIER ((int32_t)20159) - -#define BARRETT_SHIFT ((int32_t)26) - -#define BARRETT_R ((int32_t)1 << (uint32_t)BARRETT_SHIFT) - -static int16_t barrett_reduce_element(int16_t value) { - int32_t t = (int32_t)value * BARRETT_MULTIPLIER + (BARRETT_R >> 1U); - int16_t quotient = (int16_t)(t >> (uint32_t)BARRETT_SHIFT); - return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; -} - -static inline libcrux_ml_kem_vector_PortableVector barrett_reduce( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = barrett_reduce_element(v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector_PortableVector v) { - return barrett_reduce(v); -} - -#define MONTGOMERY_SHIFT (16U) - -static int16_t montgomery_reduce_element(int32_t value) { - int32_t k = - (int32_t)(int16_t)value * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; - int32_t k_times_modulus = - (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - int16_t c = (int16_t)(k_times_modulus >> (uint32_t)MONTGOMERY_SHIFT); - int16_t value_high = (int16_t)(value >> (uint32_t)MONTGOMERY_SHIFT); - return value_high - c; -} - -static inline int16_t montgomery_multiply_fe_by_fer(int16_t fe, int16_t fer) { - return montgomery_reduce_element((int32_t)fe * (int32_t)fer); -} - -static inline libcrux_ml_kem_vector_PortableVector -montgomery_multiply_by_constant(libcrux_ml_kem_vector_PortableVector v, - int16_t c) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = montgomery_multiply_fe_by_fer(v.elements[i0], c); - v.elements[i0] = uu____0; - } - return v; -} - -static libcrux_ml_kem_vector_PortableVector montgomery_multiply_by_constant0( - libcrux_ml_kem_vector_PortableVector v, int16_t r) { - return montgomery_multiply_by_constant(v, r); -} - -static uint8_t compress_message_coefficient(uint16_t fe) { - int16_t shifted = (int16_t)1664 - (int16_t)fe; - int16_t mask = shifted >> 15U; - int16_t shifted_to_positive = mask ^ shifted; - int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; - return (uint8_t)(shifted_positive_in_range >> 15U & (int16_t)1); -} - -static inline libcrux_ml_kem_vector_PortableVector compress_1( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - uint8_t uu____0 = compress_message_coefficient((uint16_t)v.elements[i0]); - v.elements[i0] = (int16_t)uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress_1( - libcrux_ml_kem_vector_PortableVector v) { - return compress_1(v); -} - -static inline uint32_t get_n_least_significant_bits(uint8_t n, uint32_t value) { - return value & ((1U << (uint32_t)n) - 1U); -} - -static int16_t compress_ciphertext_coefficient(uint8_t coefficient_bits, - uint16_t fe) { - uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; - compressed = compressed + 1664ULL; - compressed = compressed * 10321340ULL; - compressed = compressed >> 35U; - return (int16_t)get_n_least_significant_bits(coefficient_bits, - (uint32_t)compressed); -} - -static inline libcrux_ml_kem_vector_PortableVector ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - int16_t t = montgomery_multiply_fe_by_fer(v.elements[2U], zeta0); - v.elements[2U] = v.elements[0U] - t; - v.elements[0U] = v.elements[0U] + t; - int16_t t0 = montgomery_multiply_fe_by_fer(v.elements[3U], zeta0); - v.elements[3U] = v.elements[1U] - t0; - v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = montgomery_multiply_fe_by_fer(v.elements[6U], zeta1); - v.elements[6U] = v.elements[4U] - t1; - v.elements[4U] = v.elements[4U] + t1; - int16_t t2 = montgomery_multiply_fe_by_fer(v.elements[7U], zeta1); - v.elements[7U] = v.elements[5U] - t2; - v.elements[5U] = v.elements[5U] + t2; - int16_t t3 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)2U], zeta2); - v.elements[(size_t)8U + (size_t)2U] = - v.elements[(size_t)8U + (size_t)0U] - t3; - v.elements[(size_t)8U + (size_t)0U] = - v.elements[(size_t)8U + (size_t)0U] + t3; - int16_t t4 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)3U], zeta2); - v.elements[(size_t)8U + (size_t)3U] = - v.elements[(size_t)8U + (size_t)1U] - t4; - v.elements[(size_t)8U + (size_t)1U] = - v.elements[(size_t)8U + (size_t)1U] + t4; - int16_t t5 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], zeta3); - v.elements[(size_t)8U + (size_t)6U] = - v.elements[(size_t)8U + (size_t)4U] - t5; - v.elements[(size_t)8U + (size_t)4U] = - v.elements[(size_t)8U + (size_t)4U] + t5; - int16_t t6 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], zeta3); - v.elements[(size_t)8U + (size_t)7U] = - v.elements[(size_t)8U + (size_t)5U] - t6; - v.elements[(size_t)8U + (size_t)5U] = - v.elements[(size_t)8U + (size_t)5U] + t6; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); -} - -static inline libcrux_ml_kem_vector_PortableVector ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta0, int16_t zeta1) { - int16_t t = montgomery_multiply_fe_by_fer(v.elements[4U], zeta0); - v.elements[4U] = v.elements[0U] - t; - v.elements[0U] = v.elements[0U] + t; - int16_t t0 = montgomery_multiply_fe_by_fer(v.elements[5U], zeta0); - v.elements[5U] = v.elements[1U] - t0; - v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = montgomery_multiply_fe_by_fer(v.elements[6U], zeta0); - v.elements[6U] = v.elements[2U] - t1; - v.elements[2U] = v.elements[2U] + t1; - int16_t t2 = montgomery_multiply_fe_by_fer(v.elements[7U], zeta0); - v.elements[7U] = v.elements[3U] - t2; - v.elements[3U] = v.elements[3U] + t2; - int16_t t3 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)4U], zeta1); - v.elements[(size_t)8U + (size_t)4U] = - v.elements[(size_t)8U + (size_t)0U] - t3; - v.elements[(size_t)8U + (size_t)0U] = - v.elements[(size_t)8U + (size_t)0U] + t3; - int16_t t4 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)5U], zeta1); - v.elements[(size_t)8U + (size_t)5U] = - v.elements[(size_t)8U + (size_t)1U] - t4; - v.elements[(size_t)8U + (size_t)1U] = - v.elements[(size_t)8U + (size_t)1U] + t4; - int16_t t5 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], zeta1); - v.elements[(size_t)8U + (size_t)6U] = - v.elements[(size_t)8U + (size_t)2U] - t5; - v.elements[(size_t)8U + (size_t)2U] = - v.elements[(size_t)8U + (size_t)2U] + t5; - int16_t t6 = - montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], zeta1); - v.elements[(size_t)8U + (size_t)7U] = - v.elements[(size_t)8U + (size_t)3U] - t6; - v.elements[(size_t)8U + (size_t)3U] = - v.elements[(size_t)8U + (size_t)3U] + t6; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1) { - return ntt_layer_2_step(a, zeta0, zeta1); -} - -static inline libcrux_ml_kem_vector_PortableVector ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta) { - int16_t t = montgomery_multiply_fe_by_fer(v.elements[8U], zeta); - v.elements[8U] = v.elements[0U] - t; - v.elements[0U] = v.elements[0U] + t; - int16_t t0 = montgomery_multiply_fe_by_fer(v.elements[9U], zeta); - v.elements[9U] = v.elements[1U] - t0; - v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = montgomery_multiply_fe_by_fer(v.elements[10U], zeta); - v.elements[10U] = v.elements[2U] - t1; - v.elements[2U] = v.elements[2U] + t1; - int16_t t2 = montgomery_multiply_fe_by_fer(v.elements[11U], zeta); - v.elements[11U] = v.elements[3U] - t2; - v.elements[3U] = v.elements[3U] + t2; - int16_t t3 = montgomery_multiply_fe_by_fer(v.elements[12U], zeta); - v.elements[12U] = v.elements[4U] - t3; - v.elements[4U] = v.elements[4U] + t3; - int16_t t4 = montgomery_multiply_fe_by_fer(v.elements[13U], zeta); - v.elements[13U] = v.elements[5U] - t4; - v.elements[5U] = v.elements[5U] + t4; - int16_t t5 = montgomery_multiply_fe_by_fer(v.elements[14U], zeta); - v.elements[14U] = v.elements[6U] - t5; - v.elements[6U] = v.elements[6U] + t5; - int16_t t6 = montgomery_multiply_fe_by_fer(v.elements[15U], zeta); - v.elements[15U] = v.elements[7U] - t6; - v.elements[7U] = v.elements[7U] + t6; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta) { - return ntt_layer_3_step(a, zeta); -} - -static inline libcrux_ml_kem_vector_PortableVector inv_ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - int16_t a_minus_b = v.elements[2U] - v.elements[0U]; - int16_t uu____0 = barrett_reduce_element(v.elements[0U] + v.elements[2U]); - v.elements[0U] = uu____0; - int16_t uu____1 = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); - v.elements[2U] = uu____1; - int16_t a_minus_b0 = v.elements[3U] - v.elements[1U]; - int16_t uu____2 = barrett_reduce_element(v.elements[1U] + v.elements[3U]); - v.elements[1U] = uu____2; - int16_t uu____3 = montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); - v.elements[3U] = uu____3; - int16_t a_minus_b1 = v.elements[6U] - v.elements[4U]; - int16_t uu____4 = barrett_reduce_element(v.elements[4U] + v.elements[6U]); - v.elements[4U] = uu____4; - int16_t uu____5 = montgomery_multiply_fe_by_fer(a_minus_b1, zeta1); - v.elements[6U] = uu____5; - int16_t a_minus_b2 = v.elements[7U] - v.elements[5U]; - int16_t uu____6 = barrett_reduce_element(v.elements[5U] + v.elements[7U]); - v.elements[5U] = uu____6; - int16_t uu____7 = montgomery_multiply_fe_by_fer(a_minus_b2, zeta1); - v.elements[7U] = uu____7; - int16_t a_minus_b3 = - v.elements[(size_t)8U + (size_t)2U] - v.elements[(size_t)8U + (size_t)0U]; - int16_t uu____8 = barrett_reduce_element(v.elements[(size_t)8U + (size_t)0U] + - v.elements[(size_t)8U + (size_t)2U]); - v.elements[(size_t)8U + (size_t)0U] = uu____8; - int16_t uu____9 = montgomery_multiply_fe_by_fer(a_minus_b3, zeta2); - v.elements[(size_t)8U + (size_t)2U] = uu____9; - int16_t a_minus_b4 = - v.elements[(size_t)8U + (size_t)3U] - v.elements[(size_t)8U + (size_t)1U]; - int16_t uu____10 = - barrett_reduce_element(v.elements[(size_t)8U + (size_t)1U] + - v.elements[(size_t)8U + (size_t)3U]); - v.elements[(size_t)8U + (size_t)1U] = uu____10; - int16_t uu____11 = montgomery_multiply_fe_by_fer(a_minus_b4, zeta2); - v.elements[(size_t)8U + (size_t)3U] = uu____11; - int16_t a_minus_b5 = - v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)4U]; - int16_t uu____12 = - barrett_reduce_element(v.elements[(size_t)8U + (size_t)4U] + - v.elements[(size_t)8U + (size_t)6U]); - v.elements[(size_t)8U + (size_t)4U] = uu____12; - int16_t uu____13 = montgomery_multiply_fe_by_fer(a_minus_b5, zeta3); - v.elements[(size_t)8U + (size_t)6U] = uu____13; - int16_t a_minus_b6 = - v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)5U]; - int16_t uu____14 = - barrett_reduce_element(v.elements[(size_t)8U + (size_t)5U] + - v.elements[(size_t)8U + (size_t)7U]); - v.elements[(size_t)8U + (size_t)5U] = uu____14; - int16_t uu____15 = montgomery_multiply_fe_by_fer(a_minus_b6, zeta3); - v.elements[(size_t)8U + (size_t)7U] = uu____15; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return inv_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); -} - -static inline libcrux_ml_kem_vector_PortableVector inv_ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta0, int16_t zeta1) { - int16_t a_minus_b = v.elements[4U] - v.elements[0U]; - v.elements[0U] = v.elements[0U] + v.elements[4U]; - int16_t uu____0 = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); - v.elements[4U] = uu____0; - int16_t a_minus_b0 = v.elements[5U] - v.elements[1U]; - v.elements[1U] = v.elements[1U] + v.elements[5U]; - int16_t uu____1 = montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); - v.elements[5U] = uu____1; - int16_t a_minus_b1 = v.elements[6U] - v.elements[2U]; - v.elements[2U] = v.elements[2U] + v.elements[6U]; - int16_t uu____2 = montgomery_multiply_fe_by_fer(a_minus_b1, zeta0); - v.elements[6U] = uu____2; - int16_t a_minus_b2 = v.elements[7U] - v.elements[3U]; - v.elements[3U] = v.elements[3U] + v.elements[7U]; - int16_t uu____3 = montgomery_multiply_fe_by_fer(a_minus_b2, zeta0); - v.elements[7U] = uu____3; - int16_t a_minus_b3 = - v.elements[(size_t)8U + (size_t)4U] - v.elements[(size_t)8U + (size_t)0U]; - v.elements[(size_t)8U + (size_t)0U] = - v.elements[(size_t)8U + (size_t)0U] + v.elements[(size_t)8U + (size_t)4U]; - int16_t uu____4 = montgomery_multiply_fe_by_fer(a_minus_b3, zeta1); - v.elements[(size_t)8U + (size_t)4U] = uu____4; - int16_t a_minus_b4 = - v.elements[(size_t)8U + (size_t)5U] - v.elements[(size_t)8U + (size_t)1U]; - v.elements[(size_t)8U + (size_t)1U] = - v.elements[(size_t)8U + (size_t)1U] + v.elements[(size_t)8U + (size_t)5U]; - int16_t uu____5 = montgomery_multiply_fe_by_fer(a_minus_b4, zeta1); - v.elements[(size_t)8U + (size_t)5U] = uu____5; - int16_t a_minus_b5 = - v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)2U]; - v.elements[(size_t)8U + (size_t)2U] = - v.elements[(size_t)8U + (size_t)2U] + v.elements[(size_t)8U + (size_t)6U]; - int16_t uu____6 = montgomery_multiply_fe_by_fer(a_minus_b5, zeta1); - v.elements[(size_t)8U + (size_t)6U] = uu____6; - int16_t a_minus_b6 = - v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)3U]; - v.elements[(size_t)8U + (size_t)3U] = - v.elements[(size_t)8U + (size_t)3U] + v.elements[(size_t)8U + (size_t)7U]; - int16_t uu____7 = montgomery_multiply_fe_by_fer(a_minus_b6, zeta1); - v.elements[(size_t)8U + (size_t)7U] = uu____7; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta0, int16_t zeta1) { - return inv_ntt_layer_2_step(a, zeta0, zeta1); -} - -static inline libcrux_ml_kem_vector_PortableVector inv_ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector v, int16_t zeta) { - int16_t a_minus_b = v.elements[8U] - v.elements[0U]; - v.elements[0U] = v.elements[0U] + v.elements[8U]; - int16_t uu____0 = montgomery_multiply_fe_by_fer(a_minus_b, zeta); - v.elements[8U] = uu____0; - int16_t a_minus_b0 = v.elements[9U] - v.elements[1U]; - v.elements[1U] = v.elements[1U] + v.elements[9U]; - int16_t uu____1 = montgomery_multiply_fe_by_fer(a_minus_b0, zeta); - v.elements[9U] = uu____1; - int16_t a_minus_b1 = v.elements[10U] - v.elements[2U]; - v.elements[2U] = v.elements[2U] + v.elements[10U]; - int16_t uu____2 = montgomery_multiply_fe_by_fer(a_minus_b1, zeta); - v.elements[10U] = uu____2; - int16_t a_minus_b2 = v.elements[11U] - v.elements[3U]; - v.elements[3U] = v.elements[3U] + v.elements[11U]; - int16_t uu____3 = montgomery_multiply_fe_by_fer(a_minus_b2, zeta); - v.elements[11U] = uu____3; - int16_t a_minus_b3 = v.elements[12U] - v.elements[4U]; - v.elements[4U] = v.elements[4U] + v.elements[12U]; - int16_t uu____4 = montgomery_multiply_fe_by_fer(a_minus_b3, zeta); - v.elements[12U] = uu____4; - int16_t a_minus_b4 = v.elements[13U] - v.elements[5U]; - v.elements[5U] = v.elements[5U] + v.elements[13U]; - int16_t uu____5 = montgomery_multiply_fe_by_fer(a_minus_b4, zeta); - v.elements[13U] = uu____5; - int16_t a_minus_b5 = v.elements[14U] - v.elements[6U]; - v.elements[6U] = v.elements[6U] + v.elements[14U]; - int16_t uu____6 = montgomery_multiply_fe_by_fer(a_minus_b5, zeta); - v.elements[14U] = uu____6; - int16_t a_minus_b6 = v.elements[15U] - v.elements[7U]; - v.elements[7U] = v.elements[7U] + v.elements[15U]; - int16_t uu____7 = montgomery_multiply_fe_by_fer(a_minus_b6, zeta); - v.elements[15U] = uu____7; - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_PortableVector a, int16_t zeta) { - return inv_ntt_layer_3_step(a, zeta); -} - -typedef struct __int16_t_int16_t_s { - int16_t fst; - int16_t snd; -} __int16_t_int16_t; - -static inline __int16_t_int16_t ntt_multiply_binomials(__int16_t_int16_t _, - __int16_t_int16_t _0, - int16_t zeta) { - int16_t a0 = _.fst; - int16_t a1 = _.snd; - int16_t b0 = _0.fst; - int16_t b1 = _0.snd; - int32_t uu____0 = (int32_t)a0 * (int32_t)b0; - int16_t uu____1 = montgomery_reduce_element( - uu____0 + (int32_t)montgomery_reduce_element((int32_t)a1 * (int32_t)b1) * - (int32_t)zeta); - return ((__int16_t_int16_t){ - .fst = uu____1, - .snd = montgomery_reduce_element((int32_t)a0 * (int32_t)b1 + - (int32_t)a1 * (int32_t)b0)}); -} - -static inline libcrux_ml_kem_vector_PortableVector ntt_multiply( - libcrux_ml_kem_vector_PortableVector *lhs, - libcrux_ml_kem_vector_PortableVector *rhs, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - libcrux_ml_kem_vector_PortableVector out = zero(); - __int16_t_int16_t lit0; - lit0.fst = lhs->elements[0U]; - lit0.snd = lhs->elements[1U]; - __int16_t_int16_t lit1; - lit1.fst = rhs->elements[0U]; - lit1.snd = rhs->elements[1U]; - __int16_t_int16_t product = ntt_multiply_binomials(lit0, lit1, zeta0); - out.elements[0U] = product.fst; - out.elements[1U] = product.snd; - __int16_t_int16_t lit2; - lit2.fst = lhs->elements[2U]; - lit2.snd = lhs->elements[3U]; - __int16_t_int16_t lit3; - lit3.fst = rhs->elements[2U]; - lit3.snd = rhs->elements[3U]; - __int16_t_int16_t product0 = ntt_multiply_binomials(lit2, lit3, -zeta0); - out.elements[2U] = product0.fst; - out.elements[3U] = product0.snd; - __int16_t_int16_t lit4; - lit4.fst = lhs->elements[4U]; - lit4.snd = lhs->elements[5U]; - __int16_t_int16_t lit5; - lit5.fst = rhs->elements[4U]; - lit5.snd = rhs->elements[5U]; - __int16_t_int16_t product1 = ntt_multiply_binomials(lit4, lit5, zeta1); - out.elements[4U] = product1.fst; - out.elements[5U] = product1.snd; - __int16_t_int16_t lit6; - lit6.fst = lhs->elements[6U]; - lit6.snd = lhs->elements[7U]; - __int16_t_int16_t lit7; - lit7.fst = rhs->elements[6U]; - lit7.snd = rhs->elements[7U]; - __int16_t_int16_t product2 = ntt_multiply_binomials(lit6, lit7, -zeta1); - out.elements[6U] = product2.fst; - out.elements[7U] = product2.snd; - __int16_t_int16_t lit8; - lit8.fst = lhs->elements[(size_t)8U + (size_t)0U]; - lit8.snd = lhs->elements[(size_t)8U + (size_t)1U]; - __int16_t_int16_t lit9; - lit9.fst = rhs->elements[(size_t)8U + (size_t)0U]; - lit9.snd = rhs->elements[(size_t)8U + (size_t)1U]; - __int16_t_int16_t product3 = ntt_multiply_binomials(lit8, lit9, zeta2); - out.elements[(size_t)8U + (size_t)0U] = product3.fst; - out.elements[(size_t)8U + (size_t)1U] = product3.snd; - __int16_t_int16_t lit10; - lit10.fst = lhs->elements[(size_t)8U + (size_t)2U]; - lit10.snd = lhs->elements[(size_t)8U + (size_t)3U]; - __int16_t_int16_t lit11; - lit11.fst = rhs->elements[(size_t)8U + (size_t)2U]; - lit11.snd = rhs->elements[(size_t)8U + (size_t)3U]; - __int16_t_int16_t product4 = ntt_multiply_binomials(lit10, lit11, -zeta2); - out.elements[(size_t)8U + (size_t)2U] = product4.fst; - out.elements[(size_t)8U + (size_t)3U] = product4.snd; - __int16_t_int16_t lit12; - lit12.fst = lhs->elements[(size_t)8U + (size_t)4U]; - lit12.snd = lhs->elements[(size_t)8U + (size_t)5U]; - __int16_t_int16_t lit13; - lit13.fst = rhs->elements[(size_t)8U + (size_t)4U]; - lit13.snd = rhs->elements[(size_t)8U + (size_t)5U]; - __int16_t_int16_t product5 = ntt_multiply_binomials(lit12, lit13, zeta3); - out.elements[(size_t)8U + (size_t)4U] = product5.fst; - out.elements[(size_t)8U + (size_t)5U] = product5.snd; - __int16_t_int16_t lit14; - lit14.fst = lhs->elements[(size_t)8U + (size_t)6U]; - lit14.snd = lhs->elements[(size_t)8U + (size_t)7U]; - __int16_t_int16_t lit; - lit.fst = rhs->elements[(size_t)8U + (size_t)6U]; - lit.snd = rhs->elements[(size_t)8U + (size_t)7U]; - __int16_t_int16_t product6 = ntt_multiply_binomials(lit14, lit, -zeta3); - out.elements[(size_t)8U + (size_t)6U] = product6.fst; - out.elements[(size_t)8U + (size_t)7U] = product6.snd; - return out; -} - -static libcrux_ml_kem_vector_PortableVector ntt_multiply0( - libcrux_ml_kem_vector_PortableVector *lhs, - libcrux_ml_kem_vector_PortableVector *rhs, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return ntt_multiply(lhs, rhs, zeta0, zeta1, zeta2, zeta3); -} - -static inline void serialize_1(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[2U]) { - uint8_t result[2U] = {0U}; - KRML_MAYBE_FOR8( - i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; - size_t uu____0 = (size_t)0U; - result[uu____0] = (uint32_t)result[uu____0] | - (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;); - KRML_MAYBE_FOR8(i, (size_t)8U, (size_t)16U, (size_t)1U, size_t i0 = i; - size_t uu____1 = (size_t)1U; - result[uu____1] = (uint32_t)result[uu____1] | - (uint32_t)(uint8_t)v.elements[i0] - << (uint32_t)(i0 - (size_t)8U);); - memcpy(ret, result, (size_t)2U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_1( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[2U]) { - uint8_t ret0[2U]; - serialize_1(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_1( - Eurydice_slice v) { - libcrux_ml_kem_vector_PortableVector result = zero(); - KRML_MAYBE_FOR8(i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; - uint8_t *uu____0 = &Eurydice_slice_index( - v, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[i0] = - (int16_t)((uint32_t)uu____0[0U] >> (uint32_t)i0 & 1U);); - for (size_t i = (size_t)8U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - uint8_t *uu____1 = - &Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[i0] = - (int16_t)((uint32_t)uu____1[0U] >> (uint32_t)(i0 - (size_t)8U) & 1U); - } - return result; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_1( - Eurydice_slice a) { - return deserialize_1(a); -} - -static inline void serialize_4(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[8U]) { - uint8_t result[8U] = {0U}; - result[0U] = (uint32_t)(uint8_t)v.elements[1U] << 4U | - (uint32_t)(uint8_t)v.elements[0U]; - result[1U] = (uint32_t)(uint8_t)v.elements[3U] << 4U | - (uint32_t)(uint8_t)v.elements[2U]; - result[2U] = (uint32_t)(uint8_t)v.elements[5U] << 4U | - (uint32_t)(uint8_t)v.elements[4U]; - result[3U] = (uint32_t)(uint8_t)v.elements[7U] << 4U | - (uint32_t)(uint8_t)v.elements[6U]; - result[4U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)1U] << 4U | - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)0U]; - result[5U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)3U] << 4U | - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)2U]; - result[6U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)5U] << 4U | - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)4U]; - result[7U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)7U] << 4U | - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)6U]; - memcpy(ret, result, (size_t)8U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_4( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[8U]) { - uint8_t ret0[8U]; - serialize_4(a, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_4( - Eurydice_slice bytes) { - libcrux_ml_kem_vector_PortableVector v = zero(); - uint8_t *uu____0 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 15U); - uint8_t *uu____1 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - v.elements[1U] = (int16_t)((uint32_t)uu____1[0U] >> 4U & 15U); - uint8_t *uu____2 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - v.elements[2U] = (int16_t)((uint32_t)uu____2[0U] & 15U); - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - v.elements[3U] = (int16_t)((uint32_t)uu____3[0U] >> 4U & 15U); - uint8_t *uu____4 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - v.elements[4U] = (int16_t)((uint32_t)uu____4[0U] & 15U); - uint8_t *uu____5 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - v.elements[5U] = (int16_t)((uint32_t)uu____5[0U] >> 4U & 15U); - uint8_t *uu____6 = - &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - v.elements[6U] = (int16_t)((uint32_t)uu____6[0U] & 15U); - uint8_t *uu____7 = - &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - v.elements[7U] = (int16_t)((uint32_t)uu____7[0U] >> 4U & 15U); - uint8_t *uu____8 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - v.elements[8U] = (int16_t)((uint32_t)uu____8[0U] & 15U); - uint8_t *uu____9 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - v.elements[9U] = (int16_t)((uint32_t)uu____9[0U] >> 4U & 15U); - uint8_t *uu____10 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - v.elements[10U] = (int16_t)((uint32_t)uu____10[0U] & 15U); - uint8_t *uu____11 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - v.elements[11U] = (int16_t)((uint32_t)uu____11[0U] >> 4U & 15U); - uint8_t *uu____12 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - v.elements[12U] = (int16_t)((uint32_t)uu____12[0U] & 15U); - uint8_t *uu____13 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - v.elements[13U] = (int16_t)((uint32_t)uu____13[0U] >> 4U & 15U); - uint8_t *uu____14 = - &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - v.elements[14U] = (int16_t)((uint32_t)uu____14[0U] & 15U); - uint8_t *uu____15 = - &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - v.elements[15U] = (int16_t)((uint32_t)uu____15[0U] >> 4U & 15U); - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_4( - Eurydice_slice a) { - return deserialize_4(a); -} - -static inline void serialize_5(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[10U]) { - uint8_t result[10U] = {0U}; - result[0U] = (uint8_t)((v.elements[1U] & (int16_t)7) << 5U | v.elements[0U]); - result[1U] = - (uint8_t)(((v.elements[3U] & (int16_t)1) << 7U | v.elements[2U] << 2U) | - v.elements[1U] >> 3U); - result[2U] = - (uint8_t)((v.elements[4U] & (int16_t)15) << 4U | v.elements[3U] >> 1U); - result[3U] = - (uint8_t)(((v.elements[6U] & (int16_t)3) << 6U | v.elements[5U] << 1U) | - v.elements[4U] >> 4U); - result[4U] = (uint8_t)(v.elements[7U] << 3U | v.elements[6U] >> 2U); - result[5U] = - (uint8_t)((v.elements[(size_t)8U + (size_t)1U] & (int16_t)7) << 5U | - v.elements[(size_t)8U + (size_t)0U]); - result[6U] = - (uint8_t)(((v.elements[(size_t)8U + (size_t)3U] & (int16_t)1) << 7U | - v.elements[(size_t)8U + (size_t)2U] << 2U) | - v.elements[(size_t)8U + (size_t)1U] >> 3U); - result[7U] = - (uint8_t)((v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) << 4U | - v.elements[(size_t)8U + (size_t)3U] >> 1U); - result[8U] = - (uint8_t)(((v.elements[(size_t)8U + (size_t)6U] & (int16_t)3) << 6U | - v.elements[(size_t)8U + (size_t)5U] << 1U) | - v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[9U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] << 3U | - v.elements[(size_t)8U + (size_t)6U] >> 2U); - memcpy(ret, result, (size_t)10U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_5( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[10U]) { - uint8_t ret0[10U]; - serialize_5(a, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_5( - Eurydice_slice bytes) { - libcrux_ml_kem_vector_PortableVector v = zero(); - uint8_t *uu____0 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 31U); - uint8_t uu____1 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - 3U) - << 3U; - uint8_t *uu____2 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - v.elements[1U] = (int16_t)((uint32_t)uu____1 | (uint32_t)uu____2[0U] >> 5U); - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - v.elements[2U] = (int16_t)((uint32_t)uu____3[0U] >> 2U & 31U); - uint8_t uu____4 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - 15U) - << 1U; - uint8_t *uu____5 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - v.elements[3U] = (int16_t)((uint32_t)uu____4 | (uint32_t)uu____5[0U] >> 7U); - uint8_t uu____6 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t) & - 1U) - << 4U; - uint8_t *uu____7 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - v.elements[4U] = (int16_t)((uint32_t)uu____6 | (uint32_t)uu____7[0U] >> 4U); - uint8_t *uu____8 = - &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - v.elements[5U] = (int16_t)((uint32_t)uu____8[0U] >> 1U & 31U); - uint8_t uu____9 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - 7U) - << 2U; - uint8_t *uu____10 = - &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - v.elements[6U] = (int16_t)((uint32_t)uu____9 | (uint32_t)uu____10[0U] >> 6U); - uint8_t *uu____11 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - v.elements[7U] = (int16_t)((uint32_t)uu____11[0U] >> 3U); - uint8_t *uu____12 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - v.elements[8U] = (int16_t)((uint32_t)uu____12[0U] & 31U); - uint8_t uu____13 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - 3U) - << 3U; - uint8_t *uu____14 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - v.elements[9U] = (int16_t)((uint32_t)uu____13 | (uint32_t)uu____14[0U] >> 5U); - uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - v.elements[10U] = (int16_t)((uint32_t)uu____15[0U] >> 2U & 31U); - uint8_t uu____16 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - 15U) - << 1U; - uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - v.elements[11U] = - (int16_t)((uint32_t)uu____16 | (uint32_t)uu____17[0U] >> 7U); - uint8_t uu____18 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, - uint8_t *, uint8_t) & - 1U) - << 4U; - uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, - uint8_t, uint8_t *, uint8_t); - v.elements[12U] = - (int16_t)((uint32_t)uu____18 | (uint32_t)uu____19[0U] >> 4U); - uint8_t *uu____20 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, - uint8_t, uint8_t *, uint8_t); - v.elements[13U] = (int16_t)((uint32_t)uu____20[0U] >> 1U & 31U); - uint8_t uu____21 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - 7U) - << 2U; - uint8_t *uu____22 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, - uint8_t, uint8_t *, uint8_t); - v.elements[14U] = - (int16_t)((uint32_t)uu____21 | (uint32_t)uu____22[0U] >> 6U); - uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, - uint8_t, uint8_t *, uint8_t); - v.elements[15U] = (int16_t)((uint32_t)uu____23[0U] >> 3U); - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_5( - Eurydice_slice a) { - return deserialize_5(a); -} - -static inline void serialize_10(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[20U]) { - uint8_t result[20U] = {0U}; - result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); - result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)63) << 2U | - (uint32_t)(uint8_t)(v.elements[0U] >> 8U & (int16_t)3); - result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)15) << 4U | - (uint32_t)(uint8_t)(v.elements[1U] >> 6U & (int16_t)15); - result[3U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)3) << 6U | - (uint32_t)(uint8_t)(v.elements[2U] >> 4U & (int16_t)63); - result[4U] = (uint8_t)(v.elements[3U] >> 2U & (int16_t)255); - result[5U] = (uint8_t)(v.elements[4U] & (int16_t)255); - result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)63) << 2U | - (uint32_t)(uint8_t)(v.elements[4U] >> 8U & (int16_t)3); - result[7U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)15) << 4U | - (uint32_t)(uint8_t)(v.elements[5U] >> 6U & (int16_t)15); - result[8U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)3) << 6U | - (uint32_t)(uint8_t)(v.elements[6U] >> 4U & (int16_t)63); - result[9U] = (uint8_t)(v.elements[7U] >> 2U & (int16_t)255); - result[10U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); - result[11U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U & - (int16_t)3); - result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 6U & - (int16_t)15); - result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 4U & - (int16_t)63); - result[14U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 2U & (int16_t)255); - result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); - result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U & - (int16_t)3); - result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 6U & - (int16_t)15); - result[18U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 4U & - (int16_t)63); - result[19U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 2U & (int16_t)255); - memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_10( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[20U]) { - uint8_t ret0[20U]; - serialize_10(a, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_10( - Eurydice_slice bytes) { - libcrux_ml_kem_vector_PortableVector result = zero(); - int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 8U; - uint8_t *uu____1 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[0U] = uu____0 | ((int16_t)uu____1[0U] & (int16_t)255); - int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 6U; - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 2U; - int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 4U; - uint8_t *uu____5 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - result.elements[2U] = uu____4 | (int16_t)uu____5[0U] >> 4U; - int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____7 = - &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - result.elements[3U] = uu____6 | (int16_t)uu____7[0U] >> 6U; - int16_t uu____8 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 8U; - uint8_t *uu____9 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - result.elements[4U] = uu____8 | ((int16_t)uu____9[0U] & (int16_t)255); - int16_t uu____10 = ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 6U; - uint8_t *uu____11 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - result.elements[5U] = uu____10 | (int16_t)uu____11[0U] >> 2U; - int16_t uu____12 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 4U; - uint8_t *uu____13 = - &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - result.elements[6U] = uu____12 | (int16_t)uu____13[0U] >> 4U; - int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____15 = - &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - result.elements[7U] = uu____14 | (int16_t)uu____15[0U] >> 6U; - int16_t uu____16 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 8U; - uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - result.elements[8U] = uu____16 | ((int16_t)uu____17[0U] & (int16_t)255); - int16_t uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 6U; - uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - result.elements[9U] = uu____18 | (int16_t)uu____19[0U] >> 2U; - int16_t uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 4U; - uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, - uint8_t, uint8_t *, uint8_t); - result.elements[10U] = uu____20 | (int16_t)uu____21[0U] >> 4U; - int16_t uu____22 = - (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)4U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, - uint8_t, uint8_t *, uint8_t); - result.elements[11U] = uu____22 | (int16_t)uu____23[0U] >> 6U; - int16_t uu____24 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 8U; - uint8_t *uu____25 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)5U, - uint8_t, uint8_t *, uint8_t); - result.elements[12U] = uu____24 | ((int16_t)uu____25[0U] & (int16_t)255); - int16_t uu____26 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 6U; - uint8_t *uu____27 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, - uint8_t, uint8_t *, uint8_t); - result.elements[13U] = uu____26 | (int16_t)uu____27[0U] >> 2U; - int16_t uu____28 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 4U; - uint8_t *uu____29 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, - uint8_t, uint8_t *, uint8_t); - result.elements[14U] = uu____28 | (int16_t)uu____29[0U] >> 4U; - int16_t uu____30 = - (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)9U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, - uint8_t, uint8_t *, uint8_t); - result.elements[15U] = uu____30 | (int16_t)uu____31[0U] >> 6U; - return result; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_10( - Eurydice_slice a) { - return deserialize_10(a); -} - -static inline void serialize_11(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[22U]) { - uint8_t result[22U] = {0U}; - result[0U] = (uint8_t)v.elements[0U]; - result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | - (uint32_t)(uint8_t)(v.elements[0U] >> 8U); - result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | - (uint32_t)(uint8_t)(v.elements[1U] >> 5U); - result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); - result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | - (uint32_t)(uint8_t)(v.elements[2U] >> 10U); - result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | - (uint32_t)(uint8_t)(v.elements[3U] >> 7U); - result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | - (uint32_t)(uint8_t)(v.elements[4U] >> 4U); - result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); - result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | - (uint32_t)(uint8_t)(v.elements[5U] >> 9U); - result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | - (uint32_t)(uint8_t)(v.elements[6U] >> 6U); - result[10U] = (uint8_t)(v.elements[7U] >> 3U); - result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; - result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) - << 3U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); - result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); - result[14U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); - result[15U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) - << 1U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); - result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); - result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) - << 7U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[18U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); - result[19U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); - result[20U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) - << 5U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); - result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_11( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[22U]) { - uint8_t ret0[22U]; - serialize_11(a, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_11( - Eurydice_slice bytes) { - libcrux_ml_kem_vector_PortableVector result = zero(); - int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____1 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; - int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; - int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____5 = - uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____6 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; - int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____8 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; - int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____10 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; - int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____12 = - uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t) - << 1U; - uint8_t *uu____13 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; - int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____15 = - &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; - int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____17 = - &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; - int16_t uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; - int16_t uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; - int16_t uu____22 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____23 = - uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, - uint8_t, uint8_t *, uint8_t); - result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; - int16_t uu____25 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, - uint8_t, uint8_t *, uint8_t); - result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; - int16_t uu____27 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, - uint8_t, uint8_t *, uint8_t); - result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; - int16_t uu____29 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____30 = - uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, - uint8_t, uint8_t *, uint8_t) - << 1U; - uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, - uint8_t, uint8_t *, uint8_t); - result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; - int16_t uu____32 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, - uint8_t, uint8_t *, uint8_t); - result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; - int16_t uu____34 = - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, - uint8_t, uint8_t *, uint8_t); - result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; - return result; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_11( - Eurydice_slice a) { - return deserialize_11(a); -} - -static inline void serialize_12(libcrux_ml_kem_vector_PortableVector v, - uint8_t ret[24U]) { - uint8_t result[24U] = {0U}; - result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); - result[1U] = - (uint8_t)(v.elements[0U] >> 8U | (v.elements[1U] & (int16_t)15) << 4U); - result[2U] = (uint8_t)(v.elements[1U] >> 4U & (int16_t)255); - result[3U] = (uint8_t)(v.elements[2U] & (int16_t)255); - result[4U] = - (uint8_t)(v.elements[2U] >> 8U | (v.elements[3U] & (int16_t)15) << 4U); - result[5U] = (uint8_t)(v.elements[3U] >> 4U & (int16_t)255); - result[6U] = (uint8_t)(v.elements[4U] & (int16_t)255); - result[7U] = - (uint8_t)(v.elements[4U] >> 8U | (v.elements[5U] & (int16_t)15) << 4U); - result[8U] = (uint8_t)(v.elements[5U] >> 4U & (int16_t)255); - result[9U] = (uint8_t)(v.elements[6U] & (int16_t)255); - result[10U] = - (uint8_t)(v.elements[6U] >> 8U | (v.elements[7U] & (int16_t)15) << 4U); - result[11U] = (uint8_t)(v.elements[7U] >> 4U & (int16_t)255); - result[12U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); - result[13U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U | - (v.elements[(size_t)8U + (size_t)1U] & (int16_t)15) << 4U); - result[14U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 4U & (int16_t)255); - result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)255); - result[16U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 8U | - (v.elements[(size_t)8U + (size_t)3U] & (int16_t)15) << 4U); - result[17U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 4U & (int16_t)255); - result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); - result[19U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U | - (v.elements[(size_t)8U + (size_t)5U] & (int16_t)15) << 4U); - result[20U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 4U & (int16_t)255); - result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)255); - result[22U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 8U | - (v.elements[(size_t)8U + (size_t)7U] & (int16_t)15) << 4U); - result[23U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 4U & (int16_t)255); - memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___serialize_12( - libcrux_ml_kem_vector_PortableVector a, uint8_t ret[24U]) { - uint8_t ret0[24U]; - serialize_12(a, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -static inline libcrux_ml_kem_vector_PortableVector deserialize_12( - Eurydice_slice bytes) { - libcrux_ml_kem_vector_PortableVector re = zero(); - int16_t byte0 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t byte1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t byte2 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t byte3 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t); - int16_t byte4 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t); - int16_t byte5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t); - int16_t byte6 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t); - int16_t byte7 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t); - int16_t byte8 = (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, - uint8_t *, uint8_t); - int16_t byte9 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, - uint8_t *, uint8_t); - int16_t byte10 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, - uint8_t *, uint8_t); - int16_t byte11 = (int16_t)Eurydice_slice_index(bytes, (size_t)11U, uint8_t, - uint8_t *, uint8_t); - re.elements[0U] = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); - re.elements[1U] = byte2 << 4U | (byte1 >> 4U & (int16_t)15); - re.elements[2U] = (byte4 & (int16_t)15) << 8U | (byte3 & (int16_t)255); - re.elements[3U] = byte5 << 4U | (byte4 >> 4U & (int16_t)15); - re.elements[4U] = (byte7 & (int16_t)15) << 8U | (byte6 & (int16_t)255); - re.elements[5U] = byte8 << 4U | (byte7 >> 4U & (int16_t)15); - re.elements[6U] = (byte10 & (int16_t)15) << 8U | (byte9 & (int16_t)255); - re.elements[7U] = byte11 << 4U | (byte10 >> 4U & (int16_t)15); - int16_t byte12 = (int16_t)Eurydice_slice_index(bytes, (size_t)12U, uint8_t, - uint8_t *, uint8_t); - int16_t byte13 = (int16_t)Eurydice_slice_index(bytes, (size_t)13U, uint8_t, - uint8_t *, uint8_t); - int16_t byte14 = (int16_t)Eurydice_slice_index(bytes, (size_t)14U, uint8_t, - uint8_t *, uint8_t); - int16_t byte15 = (int16_t)Eurydice_slice_index(bytes, (size_t)15U, uint8_t, - uint8_t *, uint8_t); - int16_t byte16 = (int16_t)Eurydice_slice_index(bytes, (size_t)16U, uint8_t, - uint8_t *, uint8_t); - int16_t byte17 = (int16_t)Eurydice_slice_index(bytes, (size_t)17U, uint8_t, - uint8_t *, uint8_t); - int16_t byte18 = (int16_t)Eurydice_slice_index(bytes, (size_t)18U, uint8_t, - uint8_t *, uint8_t); - int16_t byte19 = (int16_t)Eurydice_slice_index(bytes, (size_t)19U, uint8_t, - uint8_t *, uint8_t); - int16_t byte20 = (int16_t)Eurydice_slice_index(bytes, (size_t)20U, uint8_t, - uint8_t *, uint8_t); - int16_t byte21 = (int16_t)Eurydice_slice_index(bytes, (size_t)21U, uint8_t, - uint8_t *, uint8_t); - int16_t byte22 = (int16_t)Eurydice_slice_index(bytes, (size_t)22U, uint8_t, - uint8_t *, uint8_t); - int16_t byte23 = (int16_t)Eurydice_slice_index(bytes, (size_t)23U, uint8_t, - uint8_t *, uint8_t); - re.elements[8U] = (byte13 & (int16_t)15) << 8U | (byte12 & (int16_t)255); - re.elements[9U] = byte14 << 4U | (byte13 >> 4U & (int16_t)15); - re.elements[10U] = (byte16 & (int16_t)15) << 8U | (byte15 & (int16_t)255); - re.elements[11U] = byte17 << 4U | (byte16 >> 4U & (int16_t)15); - re.elements[12U] = (byte19 & (int16_t)15) << 8U | (byte18 & (int16_t)255); - re.elements[13U] = byte20 << 4U | (byte19 >> 4U & (int16_t)15); - re.elements[14U] = (byte22 & (int16_t)15) << 8U | (byte21 & (int16_t)255); - re.elements[15U] = byte23 << 4U | (byte22 >> 4U & (int16_t)15); - return re; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___deserialize_12( - Eurydice_slice a) { - return deserialize_12(a); -} - -static inline size_t rej_sample(Eurydice_slice a, Eurydice_slice result) { - size_t sampled = (size_t)0U; - core_slice_iter_Chunks iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - core_slice___Slice_T___chunks(a, (size_t)3U, uint8_t, - core_slice_iter_Chunks), - core_slice_iter_Chunks, core_slice_iter_Chunks); - while (true) { - core_option_Option__Eurydice_slice_uint8_t uu____0 = - core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( - &iter, uint8_t, core_option_Option__Eurydice_slice_uint8_t); - if (uu____0.tag == core_option_None) { - break; - } else { - Eurydice_slice bytes = uu____0.f0; - int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t d1 = (b2 & (int16_t)15) << 8U | b1; - int16_t d2 = b3 << 4U | b2 >> 4U; - bool uu____1; - int16_t uu____2; - bool uu____3; - size_t uu____4; - int16_t uu____5; - size_t uu____6; - int16_t uu____7; - if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { - if (sampled < (size_t)16U) { - int16_t uu____8 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = - uu____8; - sampled++; - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, - int16_t) = uu____5; - sampled++; - continue; - } - } - continue; - } - } - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = - uu____5; - sampled++; - continue; - } - } - } - } - return sampled; -} - -size_t -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___rej_sample( - Eurydice_slice a, Eurydice_slice out) { - return rej_sample(a, out); -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_PortableVector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_PortableVector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static libcrux_ml_kem_vector_PortableVector -to_standard_domain__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector v) { - return montgomery_multiply_by_constant0( - v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - libcrux_ml_kem_vector_PortableVector coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_PortableVector( - self->coefficients[j]); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline libcrux_ml_kem_vector_PortableVector compress___5int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = compress_ciphertext_coefficient((uint8_t)(int32_t)5, - (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___5int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return compress___5int32_t(v); -} - -static inline libcrux_ml_kem_vector_PortableVector compress___4int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = compress_ciphertext_coefficient((uint8_t)(int32_t)4, - (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___4int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return compress___4int32_t(v); -} - -static inline libcrux_ml_kem_vector_PortableVector compress___11int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = compress_ciphertext_coefficient((uint8_t)(int32_t)11, - (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___11int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return compress___11int32_t(v); -} - -static inline libcrux_ml_kem_vector_PortableVector compress___10int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = compress_ciphertext_coefficient((uint8_t)(int32_t)10, - (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___compress___10int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return compress___10int32_t(v); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient_normal_form = - montgomery_multiply_by_constant0(result.coefficients[i0], - (int16_t)1441); - libcrux_ml_kem_vector_PortableVector tmp = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - self->coefficients[i0], &message->coefficients[i0]); - libcrux_ml_kem_vector_PortableVector tmp0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - coefficient_normal_form, &tmp); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector v) { - return bitwise_and_with_constant0( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - ZERO(), &v), - (int16_t)1665); -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - libcrux_ml_kem_vector_PortableVector coefficient_normal_form = - montgomery_multiply_by_constant0(self->coefficients[j], (int16_t)1441); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector( - void) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - lit; - lit.coefficients[0U] = ZERO(); - lit.coefficients[1U] = ZERO(); - lit.coefficients[2U] = ZERO(); - lit.coefficients[3U] = ZERO(); - lit.coefficients[4U] = ZERO(); - lit.coefficients[5U] = ZERO(); - lit.coefficients[6U] = ZERO(); - lit.coefficients[7U] = ZERO(); - lit.coefficients[8U] = ZERO(); - lit.coefficients[9U] = ZERO(); - lit.coefficients[10U] = ZERO(); - lit.coefficients[11U] = ZERO(); - lit.coefficients[12U] = ZERO(); - lit.coefficients[13U] = ZERO(); - lit.coefficients[14U] = ZERO(); - lit.coefficients[15U] = ZERO(); - return lit; -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_PortableVector( - Eurydice_slice a) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - result = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = - from_i16_array0(Eurydice_slice_subslice( - a, - ((core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - result.coefficients[i0] = uu____0; - } - return result; -} - -static inline libcrux_ml_kem_vector_PortableVector shift_right___15int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; - } - return v; -} - -static libcrux_ml_kem_vector_PortableVector shift_right___15int32_t0( - libcrux_ml_kem_vector_PortableVector v) { - return shift_right___15int32_t(v); -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector a) { - libcrux_ml_kem_vector_PortableVector t = shift_right___15int32_t0(a); - libcrux_ml_kem_vector_PortableVector fm = - bitwise_and_with_constant0(t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - a, &fm); -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - b) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector coefficient_normal_form = - montgomery_multiply_by_constant0(b.coefficients[i0], (int16_t)1441); - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___sub( - self->coefficients[i0], &coefficient_normal_form)); - b.coefficients[i0] = uu____0; - } - return b; -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - libcrux_ml_kem_vector_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_PortableVector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *rhs) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - out = - libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_PortableVector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = ntt_multiply0( - &self->coefficients[i0], &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)3U]); - out.coefficients[i0] = uu____0; - } - return out; -} - -static inline libcrux_ml_kem_vector_PortableVector -decompress_ciphertext_coefficient___5int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); - decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___5int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return decompress_ciphertext_coefficient___5int32_t(v); -} - -static inline libcrux_ml_kem_vector_PortableVector -decompress_ciphertext_coefficient___4int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); - decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___4int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return decompress_ciphertext_coefficient___4int32_t(v); -} - -void libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector - *self) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_PortableVector uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___barrett_reduce( - self->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_PortableVector( - libcrux_ml_kem_vector_PortableVector v, int16_t fer) { - return montgomery_multiply_by_constant0(v, fer); -} - -static inline libcrux_ml_kem_vector_PortableVector -decompress_ciphertext_coefficient___11int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); - decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___11int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return decompress_ciphertext_coefficient___11int32_t(v); -} - -static inline libcrux_ml_kem_vector_PortableVector -decompress_ciphertext_coefficient___10int32_t( - libcrux_ml_kem_vector_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); - decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -libcrux_ml_kem_vector_PortableVector -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__PortableVector___decompress_ciphertext_coefficient___10int32_t( - libcrux_ml_kem_vector_PortableVector v) { - return decompress_ciphertext_coefficient___10int32_t(v); -} diff --git a/libcrux-ml-kem/c/libcrux_polynomial.h b/libcrux-ml-kem/c/libcrux_polynomial.h deleted file mode 100644 index 1a90c137d..000000000 --- a/libcrux-ml-kem/c/libcrux_polynomial.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_polynomial_H -#define __libcrux_polynomial_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" - -typedef struct libcrux_ml_kem_vector_PortableVector_s { - int16_t elements[16U]; -} libcrux_ml_kem_vector_PortableVector; - -typedef struct - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector_s { - libcrux_ml_kem_vector_PortableVector coefficients[16U]; -} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_PortableVector; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_polynomial_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h deleted file mode 100644 index 87bfd1a1a..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_sha3_H -#define __libcrux_sha3_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_sha3_internal.h" - -static inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___72size_t_6uint8_t(buf0, buf); -} - -static inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___136size_t_6uint8_t(buf0, buf); -} - -static inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___136size_t_31uint8_t(buf0, buf); -} - -static inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___144size_t_6uint8_t(buf0, buf); -} - -static inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___104size_t_6uint8_t(buf0, buf); -} - -static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, - Eurydice_slice payload) { - libcrux_sha3_portable_sha224(digest, payload); -} - -static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) { - uint8_t out[28U] = {0U}; - libcrux_sha3_sha224_ema( - Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), data); - memcpy(ret, out, (size_t)28U * sizeof(uint8_t)); -} - -static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, - Eurydice_slice payload) { - libcrux_sha3_portable_sha256(digest, payload); -} - -static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) { - uint8_t out[32U] = {0U}; - libcrux_sha3_sha256_ema( - Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), data); - memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); -} - -static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, - Eurydice_slice payload) { - libcrux_sha3_portable_sha384(digest, payload); -} - -static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) { - uint8_t out[48U] = {0U}; - libcrux_sha3_sha384_ema( - Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), data); - memcpy(ret, out, (size_t)48U * sizeof(uint8_t)); -} - -static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, - Eurydice_slice payload) { - libcrux_sha3_portable_sha512(digest, payload); -} - -static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) { - uint8_t out[64U] = {0U}; - libcrux_sha3_sha512_ema( - Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), data); - memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); -} - -static inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1___168size_t_31uint8_t(buf0, buf); -} - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c deleted file mode 100644 index 49e0302b8..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ /dev/null @@ -1,2028 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_sha3_avx2.h" - -#include "internal/libcrux_core.h" - -static inline core_core_arch_x86___m256i zero(void) { - return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); -} - -static inline core_core_arch_x86___m256i _veor5q_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); - core_core_arch_x86___m256i abcd = - libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); - return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); -} - -static inline core_core_arch_x86___m256i xor5(core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, - core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e) { - return _veor5q_u64(a, b, c, d, e); -} - -static inline core_core_arch_x86___m256i rotate_left___1int32_t_63int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)1, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)63, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vrax1q_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i uu____0 = a; - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, rotate_left___1int32_t_63int32_t(b)); -} - -static inline core_core_arch_x86___m256i rotate_left1_and_xor( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vrax1q_u64(a, b); -} - -static inline core_core_arch_x86___m256i _vbcaxq_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c) { - core_core_arch_x86___m256i uu____0 = a; - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); -} - -static inline core_core_arch_x86___m256i and_not_xor( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c) { - return _vbcaxq_u64(a, b, c); -} - -static inline core_core_arch_x86___m256i _veorq_n_u64( - core_core_arch_x86___m256i a, uint64_t c) { - core_core_arch_x86___m256i c0 = - libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); - return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); -} - -static inline core_core_arch_x86___m256i xor_constant( - core_core_arch_x86___m256i a, uint64_t c) { - return _veorq_n_u64(a, c); -} - -static inline core_core_arch_x86___m256i xor0(core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b) { - return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); -} - -static inline void slice_4(Eurydice_slice a[4U], size_t start, size_t len, - Eurydice_slice ret[4U]) { - Eurydice_slice uu____0 = Eurydice_slice_subslice( - a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - a[1U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - a[2U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - ret[0U] = uu____0; - ret[1U] = uu____1; - ret[2U] = uu____2; - ret[3U] = Eurydice_slice_subslice( - a[3U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); -} - -static inline void slice_n(Eurydice_slice a[4U], size_t start, size_t len, - Eurydice_slice ret[4U]) { - Eurydice_slice uu____0[4U]; - memcpy(uu____0, a, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret0[4U]; - slice_4(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof(Eurydice_slice)); -} - -static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_4(Eurydice_slice out[4U], size_t mid) { - Eurydice_slice out0 = out[0U]; - Eurydice_slice out1 = out[1U]; - Eurydice_slice out2 = out[2U]; - Eurydice_slice out3 = out[3U]; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at_mut( - out0, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at_mut( - out1, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out10 = uu____1.fst; - Eurydice_slice out11 = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at_mut( - out2, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out20 = uu____2.fst; - Eurydice_slice out21 = uu____2.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at_mut( - out3, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out30 = uu____3.fst; - Eurydice_slice out31 = uu____3.snd; - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; - lit.fst[0U] = out00; - lit.fst[1U] = out10; - lit.fst[2U] = out20; - lit.fst[3U] = out30; - lit.snd[0U] = out01; - lit.snd[1U] = out11; - lit.snd[2U] = out21; - lit.snd[3U] = out31; - return lit; -} - -static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_n(Eurydice_slice a[4U], size_t mid) { - return split_at_mut_4(a, mid); -} - -static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -new__core_core_arch_x86___m256i_4size_t(void) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - lit; - lit.st[0U][0U] = zero(); - lit.st[0U][1U] = zero(); - lit.st[0U][2U] = zero(); - lit.st[0U][3U] = zero(); - lit.st[0U][4U] = zero(); - lit.st[1U][0U] = zero(); - lit.st[1U][1U] = zero(); - lit.st[1U][2U] = zero(); - lit.st[1U][3U] = zero(); - lit.st[1U][4U] = zero(); - lit.st[2U][0U] = zero(); - lit.st[2U][1U] = zero(); - lit.st[2U][2U] = zero(); - lit.st[2U][3U] = zero(); - lit.st[2U][4U] = zero(); - lit.st[3U][0U] = zero(); - lit.st[3U][1U] = zero(); - lit.st[3U][2U] = zero(); - lit.st[3U][3U] = zero(); - lit.st[3U][4U] = zero(); - lit.st[4U][0U] = zero(); - lit.st[4U][1U] = zero(); - lit.st[4U][2U] = zero(); - lit.st[4U][3U] = zero(); - lit.st[4U][4U] = zero(); - return lit; -} - -static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; - core_core_arch_x86___m256i uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; - core_core_arch_x86___m256i uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - Eurydice_slice uu____9 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____10 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____10, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____11 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____11, - Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____12 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____12, - Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, - Eurydice_slice)); - size_t i = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -static inline void load_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, b, (size_t)4U * sizeof(Eurydice_slice)); - load_block___136size_t(uu____0, uu____1); -} - -static inline core_core_arch_x86___m256i rotate_left___36int32_t_28int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)36, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)28, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___36int32_t_28int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___36int32_t_28int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___36int32_t_28int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___36int32_t_28int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___3int32_t_61int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)3, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)61, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___3int32_t_61int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___3int32_t_61int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___3int32_t_61int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___3int32_t_61int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___41int32_t_23int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)41, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)23, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___41int32_t_23int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___41int32_t_23int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___41int32_t_23int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___41int32_t_23int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___18int32_t_46int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)18, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)46, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___18int32_t_46int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___18int32_t_46int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___18int32_t_46int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___18int32_t_46int32_t(a, b); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___1int32_t_63int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___1int32_t_63int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___1int32_t_63int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___1int32_t_63int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___44int32_t_20int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)44, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)20, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___44int32_t_20int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___44int32_t_20int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___44int32_t_20int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___44int32_t_20int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___10int32_t_54int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)10, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)54, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___10int32_t_54int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___10int32_t_54int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___10int32_t_54int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___10int32_t_54int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___45int32_t_19int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)45, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)19, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___45int32_t_19int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___45int32_t_19int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___45int32_t_19int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___45int32_t_19int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___2int32_t_62int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)2, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)62, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___2int32_t_62int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___2int32_t_62int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___2int32_t_62int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___2int32_t_62int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___62int32_t_2int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)62, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)2, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___62int32_t_2int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___62int32_t_2int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___62int32_t_2int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___62int32_t_2int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___6int32_t_58int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)6, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)58, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___6int32_t_58int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___6int32_t_58int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___6int32_t_58int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___6int32_t_58int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___43int32_t_21int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)43, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)21, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___43int32_t_21int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___43int32_t_21int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___43int32_t_21int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___43int32_t_21int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___15int32_t_49int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)15, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)49, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___15int32_t_49int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___15int32_t_49int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___15int32_t_49int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___15int32_t_49int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___61int32_t_3int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)61, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)3, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___61int32_t_3int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___61int32_t_3int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___61int32_t_3int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___61int32_t_3int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___28int32_t_36int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)28, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)36, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___28int32_t_36int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___28int32_t_36int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___28int32_t_36int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___28int32_t_36int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___55int32_t_9int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)55, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)9, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___55int32_t_9int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___55int32_t_9int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___55int32_t_9int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___55int32_t_9int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___25int32_t_39int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)25, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)39, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___25int32_t_39int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___25int32_t_39int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___25int32_t_39int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___25int32_t_39int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___21int32_t_43int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)21, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)43, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___21int32_t_43int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___21int32_t_43int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___21int32_t_43int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___21int32_t_43int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___56int32_t_8int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)56, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)8, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___56int32_t_8int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___56int32_t_8int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___56int32_t_8int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___56int32_t_8int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___27int32_t_37int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)27, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)37, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___27int32_t_37int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___27int32_t_37int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___27int32_t_37int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___27int32_t_37int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___20int32_t_44int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)20, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)44, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___20int32_t_44int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___20int32_t_44int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___20int32_t_44int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___20int32_t_44int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___39int32_t_25int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)39, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)25, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___39int32_t_25int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___39int32_t_25int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___39int32_t_25int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___39int32_t_25int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___8int32_t_56int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)8, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)56, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___8int32_t_56int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___8int32_t_56int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___8int32_t_56int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___8int32_t_56int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___14int32_t_50int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)14, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)50, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___14int32_t_50int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___14int32_t_50int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___14int32_t_50int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___14int32_t_50int32_t(a, b); -} - -static inline void theta_rho__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i uu____0 = - xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], - s->st[4U][0U]); - core_core_arch_x86___m256i uu____1 = - xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], - s->st[4U][1U]); - core_core_arch_x86___m256i uu____2 = - xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], - s->st[4U][2U]); - core_core_arch_x86___m256i uu____3 = - xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], - s->st[4U][3U]); - core_core_arch_x86___m256i c[5U] = { - uu____0, uu____1, uu____2, uu____3, - xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], - s->st[4U][4U])}; - core_core_arch_x86___m256i uu____4 = - rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____5 = - rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____6 = - rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____7 = - rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i t[5U] = { - uu____4, uu____5, uu____6, uu____7, - rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U])}; - core_core_arch_x86___m256i uu____8 = xor0(s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - core_core_arch_x86___m256i uu____9 = - xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); - s->st[1U][0U] = uu____9; - core_core_arch_x86___m256i uu____10 = - xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); - s->st[2U][0U] = uu____10; - core_core_arch_x86___m256i uu____11 = - xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); - s->st[3U][0U] = uu____11; - core_core_arch_x86___m256i uu____12 = - xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); - s->st[4U][0U] = uu____12; - core_core_arch_x86___m256i uu____13 = - xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); - s->st[0U][1U] = uu____13; - core_core_arch_x86___m256i uu____14 = - xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); - s->st[1U][1U] = uu____14; - core_core_arch_x86___m256i uu____15 = - xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); - s->st[2U][1U] = uu____15; - core_core_arch_x86___m256i uu____16 = - xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); - s->st[3U][1U] = uu____16; - core_core_arch_x86___m256i uu____17 = - xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); - s->st[4U][1U] = uu____17; - core_core_arch_x86___m256i uu____18 = - xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); - s->st[0U][2U] = uu____18; - core_core_arch_x86___m256i uu____19 = - xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); - s->st[1U][2U] = uu____19; - core_core_arch_x86___m256i uu____20 = - xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); - s->st[2U][2U] = uu____20; - core_core_arch_x86___m256i uu____21 = - xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); - s->st[3U][2U] = uu____21; - core_core_arch_x86___m256i uu____22 = - xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); - s->st[4U][2U] = uu____22; - core_core_arch_x86___m256i uu____23 = - xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); - s->st[0U][3U] = uu____23; - core_core_arch_x86___m256i uu____24 = - xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); - s->st[1U][3U] = uu____24; - core_core_arch_x86___m256i uu____25 = - xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); - s->st[2U][3U] = uu____25; - core_core_arch_x86___m256i uu____26 = - xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); - s->st[3U][3U] = uu____26; - core_core_arch_x86___m256i uu____27 = - xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); - s->st[4U][3U] = uu____27; - core_core_arch_x86___m256i uu____28 = - xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); - s->st[0U][4U] = uu____28; - core_core_arch_x86___m256i uu____29 = - xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); - s->st[1U][4U] = uu____29; - core_core_arch_x86___m256i uu____30 = - xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); - s->st[2U][4U] = uu____30; - core_core_arch_x86___m256i uu____31 = - xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); - s->st[3U][4U] = uu____31; - core_core_arch_x86___m256i uu____32 = - xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____32; -} - -static inline void pi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone( - (size_t)5U, s->st, old, core_core_arch_x86___m256i[5U], void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -static inline void chi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof(core_core_arch_x86___m256i[5U])); - KRML_MAYBE_FOR5( - i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; - KRML_MAYBE_FOR5(i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; - core_core_arch_x86___m256i uu____0 = and_not_xor( - s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void iota__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - size_t i) { - core_core_arch_x86___m256i uu____0 = xor_constant( - s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -static inline void keccakf1600__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - for (size_t i = (size_t)0U; i < (size_t)24U; i++) { - size_t i0 = i; - theta_rho__core_core_arch_x86___m256i_4size_t(s); - pi__core_core_arch_x86___m256i_4size_t(s); - chi__core_core_arch_x86___m256i_4size_t(s); - iota__core_core_arch_x86___m256i_4size_t(s, i0); - } -} - -static inline void absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice blocks[4U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, blocks, (size_t)4U * sizeof(Eurydice_slice)); - load_block___136size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -static inline void load_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, blocks[3U], - uint8_t, Eurydice_slice)}; - load_block___136size_t(uu____0, buf); -} - -static inline void load_block_full___136size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___136size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = {{0U}}; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_x86___m256i(*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - size_t i = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice uu____6 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____8 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____8, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____9 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t ret[4U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - uint8_t out2[200U] = {0U}; - uint8_t out3[200U] = {0U}; - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = { - uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, out3, uint8_t, Eurydice_slice)}; - store_block___136size_t(uu____0, buf); - uint8_t uu____4[200U]; - memcpy(uu____4, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____5[200U]; - memcpy(uu____5, out1, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____6[200U]; - memcpy(uu____6, out2, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____7[200U]; - memcpy(uu____7, out3, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____4, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____5, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[2U], uu____6, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[3U], uu____7, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___136size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t ret[4U][200U]) { - uint8_t ret0[4U][200U]; - store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - uint8_t b[4U][200U]; - store_block_full___136size_t0(s->st, b); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - store_block___136size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(s); - store_block___136size_t0(s->st, out); -} - -static inline void squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(&s); - uint8_t b[4U][200U]; - store_block_full___136size_t0(s.st, b); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - Eurydice_slice data[4U], Eurydice_slice out[4U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - s = new__core_core_arch_x86___m256i_4size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &s; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, data, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_x86___m256i_4size_t_136size_t(uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = &s; - Eurydice_slice uu____3[4U]; - memcpy(uu____3, data, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t(&s, - out); - } else { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____4.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o1[4U]; - memcpy(o1, uu____4.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[4U]; - memcpy(o, uu____5.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice orest[4U]; - memcpy(orest, uu____5.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)4U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t(s, o1); - } - } -} - -void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, - Eurydice_slice input2, Eurydice_slice input3, - Eurydice_slice out0, Eurydice_slice out1, - Eurydice_slice out2, Eurydice_slice out3) { - Eurydice_slice buf0[4U] = {input0, input1, input2, input3}; - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(buf0, buf); -} - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_avx2_x4_incremental_shake128_init(void) { - return new__core_core_arch_x86___m256i_4size_t(); -} - -static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; - core_core_arch_x86___m256i uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; - core_core_arch_x86___m256i uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - Eurydice_slice uu____9 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____10 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____10, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____11 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____11, - Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____12 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____12, - Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, - Eurydice_slice)); - size_t i = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -static inline void load_block_full___168size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, blocks[3U], - uint8_t, Eurydice_slice)}; - load_block___168size_t(uu____0, buf); -} - -static inline void load_block_full___168size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___168size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = {{0U}}; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); - core_core_arch_x86___m256i(*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___168size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, - Eurydice_slice data3) { - Eurydice_slice buf[4U] = {data0, data1, data2, data3}; - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - s, buf); -} - -static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - size_t i = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice uu____6 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____8 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____8, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____9 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block___168size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - store_block___168size_t(a, b); -} - -static inline void -squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(s); - store_block___168size_t0(s->st, out); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3) { - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, buf); -} - -static inline void -squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - store_block___168size_t0(s->st, out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____0 = - split_at_mut_n(out, (size_t)168U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____0.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o10[4U]; - memcpy(o10, uu____0.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____1 = - split_at_mut_n(o10, (size_t)168U); - Eurydice_slice o1[4U]; - memcpy(o1, uu____1.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o2[4U]; - memcpy(o2, uu____1.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o1); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o2); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3) { - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - s, buf); -} diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h deleted file mode 100644 index 2f9e86a7b..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_sha3_avx2_H -#define __libcrux_sha3_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "intrinsics/libcrux_intrinsics_avx2.h" -#include "libcrux_core.h" -#include "libcrux_sha3_internal.h" - -typedef struct - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { - core_core_arch_x86___m256i st[5U][5U]; -} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; - -void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, - Eurydice_slice input2, Eurydice_slice input3, - Eurydice_slice out0, Eurydice_slice out1, - Eurydice_slice out2, Eurydice_slice out3); - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_avx2_x4_incremental_shake128_init(void); - -void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, - Eurydice_slice data3); - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3); - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h deleted file mode 100644 index e796057eb..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ /dev/null @@ -1,2346 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_sha3_internal_H -#define __libcrux_sha3_internal_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" - -static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { - 1ULL, - 32898ULL, - 9223372036854808714ULL, - 9223372039002292224ULL, - 32907ULL, - 2147483649ULL, - 9223372039002292353ULL, - 9223372036854808585ULL, - 138ULL, - 136ULL, - 2147516425ULL, - 2147483658ULL, - 2147516555ULL, - 9223372036854775947ULL, - 9223372036854808713ULL, - 9223372036854808579ULL, - 9223372036854808578ULL, - 9223372036854775936ULL, - 32778ULL, - 9223372039002259466ULL, - 9223372039002292353ULL, - 9223372036854808704ULL, - 2147483649ULL, - 9223372039002292232ULL}; - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero( - void) { - return 0ULL; -} - -static inline uint64_t libcrux_sha3_portable_keccak__veor5q_u64( - uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { - uint64_t ab = a ^ b; - uint64_t cd = c ^ d; - uint64_t abcd = ab ^ cd; - return abcd ^ e; -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { - return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; -} - -static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, - uint64_t b) { - uint64_t uu____0 = a; - return uu____0 ^ - libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); -} - -static inline uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, - uint64_t b, - uint64_t c) { - return a ^ (b & ~c); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( - uint64_t a, uint64_t b, uint64_t c) { - return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); -} - -static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, - uint64_t c) { - return a ^ c; -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( - uint64_t a, uint64_t c) { - return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( - uint64_t a, uint64_t b) { - return a ^ b; -} - -static inline void libcrux_sha3_portable_keccak_slice_1( - Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { - ret[0U] = Eurydice_slice_subslice( - a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, a, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret0[1U]; - libcrux_sha3_portable_keccak_slice_1(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice)); -} - -static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], - size_t mid) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at_mut( - out[0U], mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ lit; - lit.fst[0U] = out00; - lit.snd[0U] = out01; - return lit; -} - -static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - Eurydice_slice a[1U], size_t mid) { - return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); -} - -typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s { - uint64_t st[5U][5U]; -} libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; - -static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( - void) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; - lit.st[0U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - return lit; -} - -static inline void libcrux_sha3_portable_keccak_load_block___168size_t( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -static inline void libcrux_sha3_portable_keccak_load_block_full___168size_t( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, buf); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full___168size_t(uu____0, uu____1); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); -} - -static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) { - return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; -} - -static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, - uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(ab); -} - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( - uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); -} - -static inline void libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { - uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], - s->st[4U][0U]); - uint64_t uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], - s->st[4U][1U]); - uint64_t uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], - s->st[4U][2U]); - uint64_t uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], - s->st[4U][3U]); - uint64_t c[5U] = { - uu____0, uu____1, uu____2, uu____3, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], - s->st[4U][4U])}; - uint64_t uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - uint64_t uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - uint64_t uu____6 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - uint64_t uu____7 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - uint64_t t[5U] = { - uu____4, uu____5, uu____6, uu____7, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U])}; - uint64_t uu____8 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( - s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - uint64_t uu____9 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( - s->st[1U][0U], t[0U]); - s->st[1U][0U] = uu____9; - uint64_t uu____10 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( - s->st[2U][0U], t[0U]); - s->st[2U][0U] = uu____10; - uint64_t uu____11 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( - s->st[3U][0U], t[0U]); - s->st[3U][0U] = uu____11; - uint64_t uu____12 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( - s->st[4U][0U], t[0U]); - s->st[4U][0U] = uu____12; - uint64_t uu____13 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( - s->st[0U][1U], t[1U]); - s->st[0U][1U] = uu____13; - uint64_t uu____14 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( - s->st[1U][1U], t[1U]); - s->st[1U][1U] = uu____14; - uint64_t uu____15 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( - s->st[2U][1U], t[1U]); - s->st[2U][1U] = uu____15; - uint64_t uu____16 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( - s->st[3U][1U], t[1U]); - s->st[3U][1U] = uu____16; - uint64_t uu____17 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( - s->st[4U][1U], t[1U]); - s->st[4U][1U] = uu____17; - uint64_t uu____18 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( - s->st[0U][2U], t[2U]); - s->st[0U][2U] = uu____18; - uint64_t uu____19 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( - s->st[1U][2U], t[2U]); - s->st[1U][2U] = uu____19; - uint64_t uu____20 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( - s->st[2U][2U], t[2U]); - s->st[2U][2U] = uu____20; - uint64_t uu____21 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( - s->st[3U][2U], t[2U]); - s->st[3U][2U] = uu____21; - uint64_t uu____22 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( - s->st[4U][2U], t[2U]); - s->st[4U][2U] = uu____22; - uint64_t uu____23 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( - s->st[0U][3U], t[3U]); - s->st[0U][3U] = uu____23; - uint64_t uu____24 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( - s->st[1U][3U], t[3U]); - s->st[1U][3U] = uu____24; - uint64_t uu____25 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( - s->st[2U][3U], t[3U]); - s->st[2U][3U] = uu____25; - uint64_t uu____26 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( - s->st[3U][3U], t[3U]); - s->st[3U][3U] = uu____26; - uint64_t uu____27 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( - s->st[4U][3U], t[3U]); - s->st[4U][3U] = uu____27; - uint64_t uu____28 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( - s->st[0U][4U], t[4U]); - s->st[0U][4U] = uu____28; - uint64_t uu____29 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( - s->st[1U][4U], t[4U]); - s->st[1U][4U] = uu____29; - uint64_t uu____30 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( - s->st[2U][4U], t[4U]); - s->st[2U][4U] = uu____30; - uint64_t uu____31 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( - s->st[3U][4U], t[4U]); - s->st[3U][4U] = uu____31; - uint64_t uu____32 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( - s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____32; -} - -static inline void libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { - uint64_t old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone( - (size_t)5U, s->st, old, uint64_t[5U], void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -static inline void libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { - uint64_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); - KRML_MAYBE_FOR5( - i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( - i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; - uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( - s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, size_t i) { - uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( - s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -static inline void libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { - for (size_t i = (size_t)0U; i < (size_t)24U; i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_pi__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_chi__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_iota__uint64_t_1size_t(s, i0); - } -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 31U; - blocks[i][(size_t)168U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)168U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block___168size_t( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block___168size_t(a, b); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - s->st, out); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( - uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block_full___168size_t( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_store_block___168size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - s->st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - s.st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)168U, (size_t)168U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)168U; - size_t last = outlen - outlen % (size_t)168U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)168U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( - uu____0, out); -} - -static inline void libcrux_sha3_portable_keccak_load_block___104size_t( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( - uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_load_block_full___104size_t( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, buf); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full___104size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 6U; - blocks[i][(size_t)104U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)104U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block___104size_t( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void libcrux_sha3_portable_keccak_store_block_full___104size_t( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_store_block___104size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - s->st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block___104size_t(a, b); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - s.st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)104U, (size_t)104U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)104U; - size_t last = outlen - outlen % (size_t)104U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)104U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)104U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( - uu____0, out); -} - -static inline void libcrux_sha3_portable_keccak_load_block___144size_t( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( - uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_load_block_full___144size_t( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, buf); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full___144size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 6U; - blocks[i][(size_t)144U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)144U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block___144size_t( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void libcrux_sha3_portable_keccak_store_block_full___144size_t( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_store_block___144size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - s->st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block___144size_t(a, b); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - s.st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)144U, (size_t)144U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)144U; - size_t last = outlen - outlen % (size_t)144U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)144U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)144U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( - uu____0, out); -} - -static inline void libcrux_sha3_portable_keccak_load_block___136size_t( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( - uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_load_block_full___136size_t( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, buf); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full___136size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 31U; - blocks[i][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block___136size_t( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void libcrux_sha3_portable_keccak_store_block_full___136size_t( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_store_block___136size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - s->st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block___136size_t(a, b); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - s.st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)136U, (size_t)136U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( - uu____0, out); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 6U; - blocks[i][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)136U, (size_t)136U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( - uu____0, out); -} - -static inline void libcrux_sha3_portable_keccak_load_block___72size_t( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( - uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_load_block_full___72size_t( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, buf); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full___72size_t(uu____0, uu____1); -} - -static inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = {{0U}}; - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); - blocks[i][last_len] = 6U; - blocks[i][(size_t)72U - (size_t)1U] = - (uint32_t)blocks[i][(size_t)72U - (size_t)1U] | 128U; - } - uint64_t(*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( - uu____1, uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -static inline void libcrux_sha3_portable_keccak_store_block___72size_t( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void libcrux_sha3_portable_keccak_store_block_full___72size_t( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - uint64_t(*uu____0)[5U] = s; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; - libcrux_sha3_portable_keccak_store_block___72size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - s->st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block___72size_t(a, b); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - s->st, out); -} - -static inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - s.st, b); - { - size_t i = (size_t)0U; - Eurydice_slice uu____0 = out[i]; - uint8_t *uu____1 = b[i]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____1, i0 * (size_t)72U, (size_t)72U, ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, - ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)72U; - size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - out, (size_t)72U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - o1, (size_t)72U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( - &s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, - o1); - } - } -} - -static inline void libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( - uu____0, out); -} - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_internal_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c deleted file mode 100644 index 3d3d86bf4..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_sha3_neon.h" - -#include "internal/libcrux_core.h" - -inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline libcrux_sha3_neon_x2_incremental_KeccakState2 -libcrux_sha3_neon_x2_incremental_shake128_init(void) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, - Eurydice_slice data1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h deleted file mode 100644 index 0a665654b..000000000 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_sha3_neon_H -#define __libcrux_sha3_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "intrinsics/libcrux_intrinsics_arm64.h" -#include "libcrux_core.h" -#include "libcrux_sha3_internal.h" - -void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, - Eurydice_slice out0, Eurydice_slice out1); - -typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; -} libcrux_sha3_neon_x2_incremental_KeccakState2; - -libcrux_sha3_neon_x2_incremental_KeccakState2 -libcrux_sha3_neon_x2_incremental_shake128_init(void); - -void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, - Eurydice_slice data1); - -void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1); - -void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1); - -void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/src/ind_cca/multiplexing.rs b/libcrux-ml-kem/src/ind_cca/multiplexing.rs index bb3ce292b..54542df86 100644 --- a/libcrux-ml-kem/src/ind_cca/multiplexing.rs +++ b/libcrux-ml-kem/src/ind_cca/multiplexing.rs @@ -8,20 +8,20 @@ pub(crate) fn validate_public_key< public_key: &[u8; PUBLIC_KEY_SIZE], ) -> bool { if libcrux_platform::simd256_support() { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] return instantiations::avx2::validate_public_key::< K, RANKED_BYTES_PER_RING_ELEMENT, PUBLIC_KEY_SIZE, >(public_key); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] instantiations::portable::validate_public_key::< K, RANKED_BYTES_PER_RING_ELEMENT, PUBLIC_KEY_SIZE, >(public_key) } else if libcrux_platform::simd128_support() { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] return instantiations::neon::validate_public_key::< K, RANKED_BYTES_PER_RING_ELEMENT, @@ -55,7 +55,7 @@ pub(crate) fn generate_keypair< ) -> MlKemKeyPair { // Runtime feature detection. if libcrux_platform::simd256_support() { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] return instantiations::avx2::generate_keypair::< K, CPA_PRIVATE_KEY_SIZE, @@ -65,7 +65,7 @@ pub(crate) fn generate_keypair< ETA1, ETA1_RANDOMNESS_SIZE, >(randomness); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] instantiations::portable::generate_keypair::< K, CPA_PRIVATE_KEY_SIZE, @@ -76,7 +76,7 @@ pub(crate) fn generate_keypair< ETA1_RANDOMNESS_SIZE, >(randomness) } else if libcrux_platform::simd128_support() { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] return instantiations::neon::generate_keypair::< K, CPA_PRIVATE_KEY_SIZE, @@ -128,7 +128,7 @@ pub(crate) fn encapsulate< randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKemCiphertext, MlKemSharedSecret) { if libcrux_platform::simd256_support() { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] return instantiations::avx2::encapsulate::< K, CIPHERTEXT_SIZE, @@ -144,7 +144,7 @@ pub(crate) fn encapsulate< ETA2, ETA2_RANDOMNESS_SIZE, >(public_key, randomness); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] instantiations::portable::encapsulate::< K, CIPHERTEXT_SIZE, @@ -234,7 +234,7 @@ pub(crate) fn decapsulate< ciphertext: &MlKemCiphertext, ) -> MlKemSharedSecret { if libcrux_platform::simd256_support() { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] return instantiations::avx2::decapsulate::< K, SECRET_KEY_SIZE, @@ -253,7 +253,7 @@ pub(crate) fn decapsulate< ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, >(private_key, ciphertext); - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] return instantiations::portable::decapsulate::< K, SECRET_KEY_SIZE, @@ -273,7 +273,7 @@ pub(crate) fn decapsulate< IMPLICIT_REJECTION_HASH_INPUT_SIZE, >(private_key, ciphertext); } else if libcrux_platform::simd128_support() { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] return instantiations::neon::decapsulate::< K, SECRET_KEY_SIZE, diff --git a/libcrux-sha3/build.rs b/libcrux-sha3/build.rs index ef1138666..91a6fae70 100644 --- a/libcrux-sha3/build.rs +++ b/libcrux-sha3/build.rs @@ -2,21 +2,20 @@ use std::env; fn main() { let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let disable_simd128 = match env::var("LIBCRUX_DISABLE_SIMD128") { - Ok(s) => s == "1" || s == "y" || s == "Y", - Err(_) => false, - }; + let disable_simd128 = read_env("LIBCRUX_DISABLE_SIMD128"); + let disable_simd256 = read_env("LIBCRUX_DISABLE_SIMD256"); - let disable_simd256 = match env::var("LIBCRUX_DISABLE_SIMD256") { - Ok(s) => s == "1" || s == "y" || s == "Y", - Err(_) => false, - }; + // Force a simd build. Make sure you know what you're doing. + let enable_simd128 = read_env("LIBCRUX_ENABLE_SIMD128"); + let enable_simd256 = read_env("LIBCRUX_ENABLE_SIMD256"); - if target_arch == "aarch64" && !disable_simd128 { + let simd128_possible = target_arch == "aarch64"; + if (simd128_possible || enable_simd128) && !disable_simd128 { // We enable simd128 on all aarch64 builds. println!("cargo:rustc-cfg=feature=\"simd128\""); } - if target_arch == "x86_64" && !disable_simd256 { + let simd126_possible = target_arch == "x86_64"; + if (simd126_possible || enable_simd256) && !disable_simd256 { // We enable simd256 on all x86_64 builds. // Note that this doesn't mean the required CPU features are available. // But the compiler will support them and the runtime checks ensure that @@ -26,3 +25,10 @@ fn main() { println!("cargo:rustc-cfg=feature=\"simd256\""); } } + +fn read_env(key: &str) -> bool { + match env::var(key) { + Ok(s) => s == "1" || s == "y" || s == "Y", + Err(_) => false, + } +} diff --git a/libcrux-sha3/src/lib.rs b/libcrux-sha3/src/lib.rs index 42379f871..42a95a52d 100644 --- a/libcrux-sha3/src/lib.rs +++ b/libcrux-sha3/src/lib.rs @@ -274,10 +274,10 @@ pub mod portable { /// /// Feature `simd128` enables the implementations in this module. pub mod neon { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] use crate::generic_keccak::keccak; - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] #[inline(always)] fn keccakx2(data: [&[u8]; 2], out: [&mut [u8]; 2]) { keccak::<2, crate::simd::arm64::uint64x2_t, RATE, DELIM>(data, out) @@ -287,9 +287,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn sha224(digest: &mut [u8], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; 28]; keccakx2::<144, 0x06u8>([data, data], [digest, &mut dummy]); @@ -300,9 +300,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn sha256(digest: &mut [u8], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; 32]; keccakx2::<136, 0x06u8>([data, data], [digest, &mut dummy]); @@ -313,9 +313,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn sha384(digest: &mut [u8], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; 48]; keccakx2::<104, 0x06u8>([data, data], [digest, &mut dummy]); @@ -326,9 +326,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn sha512(digest: &mut [u8], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; 64]; keccakx2::<72, 0x06u8>([data, data], [digest, &mut dummy]); @@ -339,9 +339,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn shake128(digest: &mut [u8; LEN], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; LEN]; keccakx2::<168, 0x1fu8>([data, data], [digest, &mut dummy]); @@ -352,9 +352,9 @@ pub mod neon { #[allow(unused_variables)] #[inline(always)] pub fn shake256(digest: &mut [u8; LEN], data: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] { let mut dummy = [0u8; LEN]; keccakx2::<136, 0x1fu8>([data, data], [digest, &mut dummy]); @@ -363,7 +363,7 @@ pub mod neon { /// Performing 2 operations in parallel pub mod x2 { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] use super::*; /// Run SHAKE256 on both inputs in parallel. @@ -373,9 +373,9 @@ pub mod neon { #[inline(always)] pub fn shake256(input0: &[u8], input1: &[u8], out0: &mut [u8], out1: &mut [u8]) { // TODO: make argument ordering consistent - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] keccakx2::<136, 0x1fu8>([input0, input1], [out0, out1]); } @@ -414,19 +414,19 @@ pub mod neon { /// An incremental API to perform 2 operations in parallel pub mod incremental { - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] use crate::generic_keccak::{ absorb_final, squeeze_first_three_blocks, squeeze_next_block, KeccakState, }; - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] pub struct KeccakState2 { state: KeccakState<2, crate::simd::arm64::uint64x2_t>, } - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] type KeccakState2Internal = KeccakState<2, crate::simd::arm64::uint64x2_t>; #[allow(dead_code)] - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] pub struct KeccakState2 { state: [crate::portable::KeccakState1; 2], } @@ -434,7 +434,7 @@ pub mod neon { /// Initialise the `KeccakState2`. #[inline(always)] pub fn shake128_init() -> KeccakState2 { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation @@ -443,7 +443,7 @@ pub mod neon { // let s1 = KeccakState1::new(); // [s0, s1] // } - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] KeccakState2 { state: KeccakState2Internal::new(), } @@ -452,7 +452,7 @@ pub mod neon { #[inline(always)] #[allow(unused_variables)] pub fn shake128_absorb_final(s: &mut KeccakState2, data0: &[u8], data1: &[u8]) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation @@ -461,7 +461,7 @@ pub mod neon { // shake128_absorb_final(&mut s0, data0); // shake128_absorb_final(&mut s1, data1); // } - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] absorb_final::<2, crate::simd::arm64::uint64x2_t, 168, 0x1fu8>( &mut s.state, [data0, data1], @@ -503,7 +503,7 @@ pub mod neon { out0: &mut [u8], out1: &mut [u8], ) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation @@ -512,7 +512,7 @@ pub mod neon { // shake128_squeeze_first_three_blocks(&mut s0, out0); // shake128_squeeze_first_three_blocks(&mut s1, out1); // } - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] squeeze_first_three_blocks::<2, crate::simd::arm64::uint64x2_t, 168>( &mut s.state, [out0, out1], @@ -582,7 +582,7 @@ pub mod neon { out0: &mut [u8], out1: &mut [u8], ) { - #[cfg(not(all(feature = "simd128", target_arch = "aarch64")))] + #[cfg(not(feature = "simd128"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation @@ -591,7 +591,7 @@ pub mod neon { // shake128_squeeze_next_block(&mut s0, out0); // shake128_squeeze_next_block(&mut s1, out1); // } - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(feature = "simd128")] squeeze_next_block::<2, crate::simd::arm64::uint64x2_t, 168>( &mut s.state, [out0, out1], @@ -660,7 +660,7 @@ pub mod avx2 { /// Performing 4 operations in parallel pub mod x4 { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] use crate::generic_keccak::keccak; /// Perform 4 SHAKE256 operations in parallel @@ -676,11 +676,11 @@ pub mod avx2 { out2: &mut [u8], out3: &mut [u8], ) { - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation - // #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + // #[cfg(feature = "simd128")] // { // keccakx2::<136, 0x1fu8>([input0, input1], [out0, out1]); // keccakx2::<136, 0x1fu8>([input2, input3], [out2, out3]); @@ -691,7 +691,7 @@ pub mod avx2 { // keccakx1::<136, 0x1fu8>([input2], [out2]); // keccakx1::<136, 0x1fu8>([input3], [out3]); // } - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] keccak::<4, core::arch::x86_64::__m256i, 136, 0x1fu8>( [input0, input1, input2, input3], [out0, out1, out2, out3], @@ -760,40 +760,37 @@ pub mod avx2 { /// An incremental API to perform 4 operations in parallel pub mod incremental { - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] use crate::generic_keccak::{ absorb_final, squeeze_first_three_blocks, squeeze_next_block, KeccakState, }; - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] pub struct KeccakState4 { state: KeccakState<4, core::arch::x86_64::__m256i>, } #[allow(dead_code)] - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + #[cfg(all(feature = "simd128", not(feature = "simd256")))] pub struct KeccakState4 { state: [crate::neon::x2::incremental::KeccakState2; 2], } - #[cfg(not(any( - all(feature = "simd256", target_arch = "x86_64"), - all(feature = "simd128", target_arch = "aarch64") - )))] + #[cfg(not(any(feature = "simd256", feature = "simd128")))] pub type KeccakState4 = [crate::portable::KeccakState1; 4]; /// Initialise the [`KeccakState4`]. #[inline(always)] pub fn shake128_init() -> KeccakState4 { - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation - // #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + // #[cfg(feature = "simd128")] // { // let s0 = KeccakState2::new(); // let s1 = KeccakState2::new(); // [s0, s1] // } - // #[cfg(not(any(all(feature = "simd128", target_arch = "aarch64"), all(feature = "simd256", target_arch = "x86_64"))))] + // #[cfg(not(any(feature = "simd128", feature = "simd256")))] // { // let s0 = KeccakState1::new(); // let s1 = KeccakState1::new(); @@ -801,7 +798,7 @@ pub mod avx2 { // let s3 = KeccakState1::new(); // [s0, s1, s2, s3] // } - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] KeccakState4 { state: KeccakState::new(), } @@ -816,11 +813,11 @@ pub mod avx2 { data2: &[u8], data3: &[u8], ) { - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation - // #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + // #[cfg(feature = "simd128")] // { // let [mut s0, mut s1] = s; // absorb_final::<2, crate::simd::arm64::uint64x2_t, 168, 0x1fu8>( @@ -832,7 +829,7 @@ pub mod avx2 { // [data2, data3], // ); // } - // #[cfg(not(any(all(feature = "simd128", target_arch = "aarch64"), all(feature = "simd256", target_arch = "x86_64"))))] + // #[cfg(not(any(feature = "simd128", feature = "simd256")))] // { // let [mut s0, mut s1, mut s2, mut s3] = s; // shake128_absorb_final(&mut s0, data0); @@ -840,7 +837,7 @@ pub mod avx2 { // shake128_absorb_final(&mut s2, data2); // shake128_absorb_final(&mut s3, data3); // } - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] absorb_final::<4, core::arch::x86_64::__m256i, 168, 0x1fu8>( &mut s.state, [data0, data1, data2, data3], @@ -888,11 +885,11 @@ pub mod avx2 { out2: &mut [u8], out3: &mut [u8], ) { - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation - // #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + // #[cfg(feature = "simd128")] // { // let [mut s0, mut s1] = s; // squeeze_first_three_blocks::<2, crate::simd::arm64::uint64x2_t, 168>( @@ -904,7 +901,7 @@ pub mod avx2 { // [out2, out3], // ); // } - // #[cfg(not(any(all(feature = "simd128", target_arch = "aarch64"), all(feature = "simd256", target_arch = "x86_64"))))] + // #[cfg(not(any(feature = "simd128", feature = "simd256")))] // { // let [mut s0, mut s1, mut s2, mut s3] = s; // shake128_squeeze_first_three_blocks(&mut s0, out0); @@ -912,7 +909,7 @@ pub mod avx2 { // shake128_squeeze_first_three_blocks(&mut s2, out2); // shake128_squeeze_first_three_blocks(&mut s3, out3); // } - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] squeeze_first_three_blocks::<4, core::arch::x86_64::__m256i, 168>( &mut s.state, [out0, out1, out2, out3], @@ -982,11 +979,11 @@ pub mod avx2 { out2: &mut [u8], out3: &mut [u8], ) { - #[cfg(not(all(feature = "simd256", target_arch = "x86_64")))] + #[cfg(not(feature = "simd256"))] unimplemented!("The target architecture does not support neon instructions."); // XXX: These functions could alternatively implement the same with // the portable implementation - // #[cfg(all(feature = "simd128", target_arch = "aarch64"))] + // #[cfg(feature = "simd128")] // { // let [mut s0, mut s1] = s; // squeeze_next_block::<2, crate::simd::arm64::uint64x2_t, 168>( @@ -998,7 +995,7 @@ pub mod avx2 { // [out2, out3], // ); // } - // #[cfg(not(any(all(feature = "simd128", target_arch = "aarch64"), all(feature = "simd256", target_arch = "x86_64"))))] + // #[cfg(not(any(feature = "simd128", feature = "simd256")))] // { // let [mut s0, mut s1, mut s2, mut s3] = s; // shake128_squeeze_next_block(&mut s0, out0); @@ -1006,7 +1003,7 @@ pub mod avx2 { // shake128_squeeze_next_block(&mut s2, out2); // shake128_squeeze_next_block(&mut s3, out3); // } - #[cfg(all(feature = "simd256", target_arch = "x86_64"))] + #[cfg(feature = "simd256")] squeeze_next_block::<4, core::arch::x86_64::__m256i, 168>( &mut s.state, [out0, out1, out2, out3], From bf04d417302ab5f6608479124fc7cd0d8da25372 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 15:39:11 -0700 Subject: [PATCH 11/84] Improved bundling --- libcrux-ml-kem/c.yaml | 106 +++++++++++++------ libcrux-ml-kem/c/libcrux_platform.c | 8 ++ libcrux-ml-kem/src/ind_cca/instantiations.rs | 2 +- libcrux-ml-kem/src/vector.rs | 34 +++--- 4 files changed, 103 insertions(+), 47 deletions(-) create mode 100644 libcrux-ml-kem/c/libcrux_platform.c diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 83cf038bf..72fa642cd 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -106,7 +106,7 @@ files: - [libcrux_sha3, "*"] inline_static: true - # MLKEM + # MLKEM: HASH FUNCTIONS (as used by mlkem) - name: libcrux_mlkem_neon api: @@ -132,6 +132,25 @@ files: - [libcrux_ml_kem, vector, avx2, "*"] - [libcrux_ml_kem, hash_functions, avx2, "*"] + # This covers slightly more than the two bundles above, but this greatly + # simplifies our lives. + - name: libcrux_mlkem_portable + api: + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + private: + patterns: + - [ libcrux_ml_kem, polynomial, "*" ] + monomorphizations_using: + - [ libcrux_ml_kem, polynomial, "*" ] + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + monomorphizations_of: + - [ libcrux_ml_kem, polynomial, "*" ] + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + + # MLKEM: MISC NON-ARCHITECTURE SPECIFIC HEADERS - name: libcrux_core private: monomorphizations_of: @@ -159,24 +178,7 @@ files: api: - [Eurydice, "*"] - - name: libcrux_polynomial - private: - patterns: - - [ libcrux_ml_kem, polynomial, "*" ] - - [ libcrux_ml_kem, vector, "*" ] - monomorphizations_of: - - [ libcrux_ml_kem, polynomial, "*" ] - - [ libcrux_ml_kem, vector, "*" ] - monomorphizations_using: - - [ libcrux_ml_kem, polynomial, "*" ] - - [ libcrux_ml_kem, vector, traits, "*" ] - - - name: libcrux_mlkem_sha3_avx2 - private: - monomorphizations_using: - - [libcrux_ml_kem, hash_functions, avx2, "*"] - api: - - [libcrux_ml_kem, hash_functions, avx2, "*"] + # MLKEM-512 - name: libcrux_mlkem512_avx2 api: @@ -187,6 +189,15 @@ files: - [libcrux_ml_kem, mlkem512, avx2] - [libcrux_ml_kem, ind_cca, instantiations, avx2] + - name: libcrux_mlkem512_neon + api: + patterns: + - [libcrux_ml_kem, mlkem512, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] + monomorphizations_of: + - [libcrux_ml_kem, mlkem512, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] + - name: libcrux_mlkem512_portable api: patterns: @@ -200,6 +211,8 @@ files: api: - [libcrux_ml_kem, mlkem512] + # MLKEM-768 + - name: libcrux_mlkem768_avx2 api: patterns: @@ -209,6 +222,15 @@ files: - [libcrux_ml_kem, mlkem768, avx2] - [libcrux_ml_kem, ind_cca, instantiations, avx2] + - name: libcrux_mlkem768_neon + api: + patterns: + - [libcrux_ml_kem, mlkem768, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] + monomorphizations_of: + - [libcrux_ml_kem, mlkem768, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] + - name: libcrux_mlkem768_portable api: patterns: @@ -222,34 +244,50 @@ files: api: - [libcrux_ml_kem, mlkem768] + # MLKEM-1024 + - name: libcrux_mlkem1024_avx2 api: - - [libcrux_ml_kem, mlkem1024, avx2] - - [libcrux_ml_kem, ind_cca, instantiations, avx2] + patterns: + - [libcrux_ml_kem, mlkem1024, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + monomorphizations_of: + - [libcrux_ml_kem, mlkem1024, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + + - name: libcrux_mlkem1024_neon + api: + patterns: + - [libcrux_ml_kem, mlkem1024, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] + monomorphizations_of: + - [libcrux_ml_kem, mlkem1024, neon] + - [libcrux_ml_kem, ind_cca, instantiations, neon] - name: libcrux_mlkem1024_portable api: - - [libcrux_ml_kem, mlkem1024, portable] - - [libcrux_ml_kem, ind_cca, instantiations, portable] + patterns: + - [libcrux_ml_kem, mlkem1024, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] + monomorphizations_of: + - [libcrux_ml_kem, mlkem1024, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable] - name: libcrux_mlkem1024 api: - [libcrux_ml_kem, mlkem1024] + # Multiplexing API. + - name: libcrux_mlkem_multiplexing - private: - - [libcrux_ml_kem, ind_cca, multiplexing] + api: + patterns: + - [libcrux_ml_kem, ind_cca, multiplexing] inline_static: true - - name: libcrux_mlkem_ind_cca + # Just a few constants not caught by anything above. Most likely can go into + # core or polynomial (TODO: try it). + - name: libcrux_mlkem_common private: - - [libcrux_ml_kem, ind_cca] - [libcrux_ml_kem, "*"] inline_static: true - - # # Just a few constants not caught by anything above. Most likely can go into - # # core or polynomial (TODO: try it). - # - name: libcrux_mlkem_common - # private: - # - [libcrux_ml_kem, "*"] - # inline_static: true diff --git a/libcrux-ml-kem/c/libcrux_platform.c b/libcrux-ml-kem/c/libcrux_platform.c new file mode 100644 index 000000000..b1f487d73 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_platform.c @@ -0,0 +1,8 @@ +// HAND-WRITTEN FILE + +#include + +bool libcrux_platform_platform_simd256_support(void) { + // TODO: query cpuid and cache the results!! + return true; +} diff --git a/libcrux-ml-kem/src/ind_cca/instantiations.rs b/libcrux-ml-kem/src/ind_cca/instantiations.rs index 0df88acef..72f17a93a 100644 --- a/libcrux-ml-kem/src/ind_cca/instantiations.rs +++ b/libcrux-ml-kem/src/ind_cca/instantiations.rs @@ -133,7 +133,7 @@ macro_rules! instantiate { } // Portable generic implementations. -instantiate! {portable, crate::vector::PortableVector, crate::hash_functions::portable::PortableHash} +instantiate! {portable, crate::vector::portable::PortableVector, crate::hash_functions::portable::PortableHash} // AVX2 generic implementation. #[cfg(feature = "simd256")] diff --git a/libcrux-ml-kem/src/vector.rs b/libcrux-ml-kem/src/vector.rs index ceae95450..bc7cc7c0e 100644 --- a/libcrux-ml-kem/src/vector.rs +++ b/libcrux-ml-kem/src/vector.rs @@ -203,28 +203,36 @@ pub(crate) fn compress_ciphertext_coefficient(coefficient_bits: u8, fe: u16) -> get_n_least_significant_bits(coefficient_bits, compressed as u32) as FieldElement } -#[derive(Clone, Copy)] -pub struct PortableVector { - elements: [FieldElement; FIELD_ELEMENTS_IN_VECTOR], +pub(crate) mod portable { + + use super::*; + + #[derive(Clone, Copy)] + pub(crate) struct PortableVector { + pub(crate) elements: [FieldElement; FIELD_ELEMENTS_IN_VECTOR], + } + } +use portable::*; + #[allow(non_snake_case)] #[inline(always)] -fn zero() -> PortableVector { +pub fn zero() -> PortableVector { PortableVector { elements: [0i16; FIELD_ELEMENTS_IN_VECTOR], } } #[inline(always)] -fn from_i16_array(array: &[i16]) -> PortableVector { +pub fn from_i16_array(array: &[i16]) -> PortableVector { PortableVector { elements: array[0..16].try_into().unwrap(), } } #[inline(always)] -fn add(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { +pub fn add(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { lhs.elements[i] += rhs.elements[i]; } @@ -233,7 +241,7 @@ fn add(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { } #[inline(always)] -fn sub(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { +pub fn sub(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { lhs.elements[i] -= rhs.elements[i]; } @@ -242,7 +250,7 @@ fn sub(mut lhs: PortableVector, rhs: &PortableVector) -> PortableVector { } #[inline(always)] -fn multiply_by_constant(mut v: PortableVector, c: i16) -> PortableVector { +pub fn multiply_by_constant(mut v: PortableVector, c: i16) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { v.elements[i] *= c; } @@ -251,7 +259,7 @@ fn multiply_by_constant(mut v: PortableVector, c: i16) -> PortableVector { } #[inline(always)] -fn bitwise_and_with_constant(mut v: PortableVector, c: i16) -> PortableVector { +pub fn bitwise_and_with_constant(mut v: PortableVector, c: i16) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { v.elements[i] &= c; } @@ -260,7 +268,7 @@ fn bitwise_and_with_constant(mut v: PortableVector, c: i16) -> PortableVector { } #[inline(always)] -fn shift_right(mut v: PortableVector) -> PortableVector { +pub fn shift_right(mut v: PortableVector) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { v.elements[i] = v.elements[i] >> SHIFT_BY; } @@ -269,7 +277,7 @@ fn shift_right(mut v: PortableVector) -> PortableVector { } // #[inline(always)] -// fn shift_left(mut lhs: PortableVector) -> PortableVector { +// pub fn shift_left(mut lhs: PortableVector) -> PortableVector { // for i in 0..FIELD_ELEMENTS_IN_VECTOR { // lhs.elements[i] = lhs.elements[i] << SHIFT_BY; // } @@ -278,7 +286,7 @@ fn shift_right(mut v: PortableVector) -> PortableVector { // } #[inline(always)] -fn cond_subtract_3329(mut v: PortableVector) -> PortableVector { +pub fn cond_subtract_3329(mut v: PortableVector) -> PortableVector { for i in 0..FIELD_ELEMENTS_IN_VECTOR { debug_assert!(v.elements[i] >= 0 && v.elements[i] < 4096); if v.elements[i] >= 3329 { @@ -288,6 +296,8 @@ fn cond_subtract_3329(mut v: PortableVector) -> PortableVector { v } +use portable::*; + /// Signed Barrett Reduction /// /// Given an input `value`, `barrett_reduce` outputs a representative `result` From 9304e0ebec8d43aaa86fd63cdef8df170f02483b Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 15:50:08 -0700 Subject: [PATCH 12/84] Seems to do proper packaging on neon, at least --- libcrux-ml-kem/c/CMakeLists.txt | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 939dc09e9..ce387e474 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -42,12 +42,12 @@ file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_portable.c ${PROJECT_SOURCE_DIR}/libcrux_polynomial.c ) -# file(GLOB VEC128_SOURCES -# ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_neon.c -# ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_neon.c -# ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_neon.c -# ${PROJECT_SOURCE_DIR}/libcrux_sha3_neon.c -# ) +file(GLOB SOURCES_vec128 + ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_neon.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_neon.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_neon.c + ${PROJECT_SOURCE_DIR}/libcrux_sha3_neon.c +) file(GLOB SOURCES_vec256 ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_avx2.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_avx2.c @@ -65,12 +65,20 @@ add_library(ml_kem SHARED ${SOURCES}) add_library(ml_kem_static STATIC ${SOURCES}) # if(LIBCRUX_VEC256) -add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) -target_sources(ml_kem_static PRIVATE $) -target_sources(ml_kem PRIVATE $) -target_compile_options(ml_kem_vec256 PRIVATE - -mavx - -mavx2 +# add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) +# target_sources(ml_kem_static PRIVATE $) +# target_sources(ml_kem PRIVATE $) +# target_compile_options(ml_kem_vec256 PRIVATE +# -mavx +# -mavx2 +# ) +# endif() + +# if(LIBCRUX_VEC128) +add_library(ml_kem_vec128 OBJECT ${SOURCES_vec128}) +target_sources(ml_kem_static PRIVATE $) +target_sources(ml_kem PRIVATE $) +target_compile_options(ml_kem_vec128 PRIVATE ) # endif() From e0d26d24ebb9e552fcb828283fb16dfaa3f1508f Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 15:50:21 -0700 Subject: [PATCH 13/84] With the freshly-generated C --- libcrux-ml-kem/c/eurydice_glue.h | 296 + libcrux-ml-kem/c/internal/libcrux_core.h | 256 + .../c/internal/libcrux_mlkem_neon.h | 94 + .../c/internal/libcrux_mlkem_portable.h | 98 + .../c/internal/libcrux_sha3_internal.h | 286 + libcrux-ml-kem/c/libcrux_core.c | 467 + libcrux-ml-kem/c/libcrux_core.h | 175 + libcrux-ml-kem/c/libcrux_mlkem1024.c | 203 + libcrux-ml-kem/c/libcrux_mlkem1024.h | 104 + libcrux-ml-kem/c/libcrux_mlkem1024_neon.c | 77 + libcrux-ml-kem/c/libcrux_mlkem1024_neon.h | 45 + libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 77 + libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 45 + libcrux-ml-kem/c/libcrux_mlkem512.c | 203 + libcrux-ml-kem/c/libcrux_mlkem512.h | 104 + libcrux-ml-kem/c/libcrux_mlkem512_neon.c | 223 + libcrux-ml-kem/c/libcrux_mlkem512_neon.h | 113 + libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 223 + libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 113 + libcrux-ml-kem/c/libcrux_mlkem768.c | 203 + libcrux-ml-kem/c/libcrux_mlkem768.h | 104 + libcrux-ml-kem/c/libcrux_mlkem768_neon.c | 77 + libcrux-ml-kem/c/libcrux_mlkem768_neon.h | 45 + libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 77 + libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 45 + libcrux-ml-kem/c/libcrux_mlkem_neon.c | 9690 +++++++++++++++++ libcrux-ml-kem/c/libcrux_mlkem_neon.h | 418 + libcrux-ml-kem/c/libcrux_mlkem_portable.c | 8858 +++++++++++++++ libcrux-ml-kem/c/libcrux_mlkem_portable.h | 418 + libcrux-ml-kem/c/libcrux_platform.h | 26 + libcrux-ml-kem/c/libcrux_sha3.h | 118 + libcrux-ml-kem/c/libcrux_sha3_avx2.c | 123 + libcrux-ml-kem/c/libcrux_sha3_avx2.h | 75 + libcrux-ml-kem/c/libcrux_sha3_internal.h | 3003 +++++ libcrux-ml-kem/c/libcrux_sha3_neon.c | 3689 +++++++ libcrux-ml-kem/c/libcrux_sha3_neon.h | 71 + 36 files changed, 30242 insertions(+) create mode 100644 libcrux-ml-kem/c/eurydice_glue.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_core.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_internal.h create mode 100644 libcrux-ml-kem/c/libcrux_core.c create mode 100644 libcrux-ml-kem/c/libcrux_core.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_portable.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_portable.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_portable.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_portable.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_portable.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_portable.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_portable.h create mode 100644 libcrux-ml-kem/c/libcrux_platform.h create mode 100644 libcrux-ml-kem/c/libcrux_sha3.h create mode 100644 libcrux-ml-kem/c/libcrux_sha3_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_sha3_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_sha3_internal.h create mode 100644 libcrux-ml-kem/c/libcrux_sha3_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_sha3_neon.h diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h new file mode 100644 index 000000000..f798f970b --- /dev/null +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -0,0 +1,296 @@ +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#include "krml/internal/target.h" +#include "krml/lowstar_endianness.h" + +#define LowStar_Ignore_ignore(e, t, _ret_t) ((void)e) + +// SLICES, ARRAYS, ETC. + +// We represent a slice as a pair of an (untyped) pointer, along with the length +// of the slice, i.e. the number of elements in the slice (this is NOT the +// number of bytes). This design choice has two important consequences. +// - if you need to use `ptr`, you MUST cast it to a proper type *before* +// performing pointer +// arithmetic on it (remember that C desugars pointer arithmetic based on the +// type of the address) +// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you +// need to multiply it +// by sizeof t, where t is the type of the elements. +typedef struct { + void *ptr; + size_t len; +} Eurydice_slice; + +// Helper macro to create a slice out of a pointer x, a start index in x +// (included), and an end index in x (excluded). The argument x must be suitably +// cast to something that can decay (see remark above about how pointer +// arithmetic works in C), meaning either pointer or array type. +#define EURYDICE_SLICE(x, start, end) \ + ((Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) +#define EURYDICE_SLICE_LEN(s, _) s.len +// This macro is a pain because in case the dereferenced element type is an +// array, you cannot simply write `t x` as it would yield `int[4] x` instead, +// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that +// adds an extra argument to this macro at the last minute so that we have the +// correct type of *pointers* to elements. +#define Eurydice_slice_index(s, i, t, t_ptr_t, _ret_t) (((t_ptr_t)s.ptr)[i]) +#define Eurydice_slice_subslice(s, r, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, r.start, r.end) +#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) +#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) +#define Eurydice_array_to_slice(end, x, t, _ret_t) \ + EURYDICE_SLICE(x, 0, \ + end) /* x is already at an array type, no need for cast */ +#define Eurydice_array_to_subslice(_arraylen, x, r, t, _, _ret_t) \ + EURYDICE_SLICE((t *)x, r.start, r.end) +#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t, _ret_t) \ + EURYDICE_SLICE((t *)x, 0, r) +#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t, _ret_t) \ + EURYDICE_SLICE((t *)x, r, size) +#define Eurydice_array_repeat(dst, len, init, t, _ret_t) \ + ERROR "should've been desugared" +#define core_slice___Slice_T___len(s, t, _ret_t) EURYDICE_SLICE_LEN(s, t) +#define core_slice___Slice_T___copy_from_slice(dst, src, t, _ret_t) \ + memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) +#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ + ((Eurydice_slice){.ptr = ptr_, .len = len_}) + +#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ + len, src, dst, elem_type, _ret_t) \ + (memcpy(dst, src, len * sizeof(elem_type))) +#define core_array_TryFromSliceError uint8_t + +#define Eurydice_array_eq(sz, a1, a2, t, _, _ret_t) \ + (memcmp(a1, a2, sz * sizeof(t)) == 0) +#define core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq \ + Eurydice_array_eq + +#define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ + ((ret_t){.fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) +#define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ + ((ret_t){.fst = {.ptr = slice.ptr, .len = mid}, \ + .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ + .len = slice.len - mid}}) + +// Can't have a flexible array as a member of a union -- this violates strict +// aliasing rules. +typedef struct { + uint8_t tag; + uint8_t case_Ok[]; +} result_tryfromslice_flexible; + +// See note in karamel/lib/Inlining.ml if you change this +#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) \ + Eurydice_slice_to_array3((result_tryfromslice_flexible *)dst, src, \ + sizeof(t_arr)) + +static inline void Eurydice_slice_to_array3(result_tryfromslice_flexible *dst, + Eurydice_slice src, size_t sz) { + dst->tag = 0; + memcpy(dst->case_Ok, src.ptr, sz); +} + +// CORE STUFF (conversions, endianness, ...) + +static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { + uint32_t x = htobe32(src); + memcpy(dst, &x, 4); +} + +static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { + store64_le(buf, v); +} +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + return load64_le(buf); +} + +static inline int64_t +core_convert_num___core__convert__From_i32__for_i64__59__from(int32_t x) { + return x; +} + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { + return __builtin_popcount(x0); +} + +// unsigned overflow wraparound semantics in C +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { + return x + y; +} +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { + return x - y; +} + +static inline void core_ops_arith__i32_319__add_assign(int32_t *x0, + int32_t *x1) { + *x0 = *x0 + *x1; +} + +static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v) { + return (*p) & v; +} +static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { + return (*p) >> v; +} + +// ITERATORS + +#define core_num_nonzero_NonZeroUsize size_t +#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ + (((iter_ptr)->start == (iter_ptr)->end) \ + ? ((ret_t){.tag = core_option_None}) \ + : ((ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) + +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ + Eurydice_range_iter_next + +// See note in karamel/lib/Inlining.ml if you change this +#define Eurydice_into_iter(x, t, _ret_t) (x) +#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \ + Eurydice_into_iter + +typedef struct { + Eurydice_slice slice; + size_t chunk_size; +} Eurydice_chunks; + +// Can't use macros Eurydice_slice_subslice_{to,from} because they require a +// type, and this static inline function cannot receive a type as an argument. +// Instead, we receive the element size and use it to peform manual offset +// computations rather than going through the macros. +static inline Eurydice_slice chunk_next(Eurydice_chunks *chunks, + size_t element_size) { + size_t chunk_size = chunks->slice.len >= chunks->chunk_size + ? chunks->chunk_size + : chunks->slice.len; + Eurydice_slice curr_chunk = + ((Eurydice_slice){.ptr = chunks->slice.ptr, .len = chunk_size}); + chunks->slice = ((Eurydice_slice){ + .ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size, + .len = chunks->slice.len - chunk_size}); + return curr_chunk; +} + +#define core_slice___Slice_T___chunks(slice_, sz_, t, _ret_t) \ + ((Eurydice_chunks){.slice = slice_, .chunk_size = sz_}) +#define core_slice___Slice_T___chunks_exact(slice_, sz_, t, _ret_t) \ + ((Eurydice_chunks){ \ + .slice = {.ptr = slice_.ptr, .len = slice_.len - (slice_.len % sz_)}, \ + .chunk_size = sz_}) +#define core_slice_iter_Chunks Eurydice_chunks +#define core_slice_iter_ChunksExact Eurydice_chunks +#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( \ + iter, t, ret_t) \ + (((iter)->slice.len == 0) ? ((ret_t){.tag = core_option_None}) \ + : ((ret_t){.tag = core_option_Some, \ + .f0 = chunk_next(iter, sizeof(t))})) +#define core_slice_iter__core__slice__iter__ChunksExact__a__T__89__next( \ + iter, t, _ret_t) \ + core_slice_iter__core__slice__iter__Chunks__a__T__70__next(iter, t) + +typedef struct { + Eurydice_slice s; + size_t index; +} Eurydice_slice_iterator; + +#define core_slice___Slice_T___iter(x, t, _ret_t) \ + ((Eurydice_slice_iterator){.s = x, .index = 0}) +#define core_slice_iter_Iter Eurydice_slice_iterator +#define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, \ + ret_t) \ + (((iter)->index == (iter)->s.len) \ + ? ((ret_t){.tag = core_option_None}) \ + : ((ret_t){.tag = core_option_Some, \ + .f0 = ((iter)->index++, \ + &((t *)((iter)->s.ptr))[(iter)->index - 1])})) + +// STRINGS + +typedef const char *Prims_string; + +// MISC (UNTESTED) + +typedef void *core_fmt_Formatter; +typedef void *core_fmt_Arguments; +typedef void *core_fmt_rt_Argument; +#define core_fmt_rt__core__fmt__rt__Argument__a__1__new_display(x1, x2, x3, \ + x4) \ + NULL + +// VECTORS (ANCIENT, POSSIBLY UNTESTED) + +/* For now these are passed by value -- three words. We could conceivably change + * the representation to heap-allocate this struct and only pass around the + * pointer (one word). */ +typedef struct { + void *ptr; + size_t len; /* the number of elements */ + size_t alloc_size; /* the size of the allocation, in number of BYTES */ +} Eurydice_vec_s, *Eurydice_vec; + +/* Here, we set everything to zero rather than use a non-standard GCC + * statement-expression -- this suitably initializes ptr to NULL and len and + * size to 0. */ +#define EURYDICE_VEC_NEW(_) calloc(1, sizeof(Eurydice_vec_s)) +#define EURYDICE_VEC_PUSH(v, x, t) \ + do { \ + /* Grow the vector if capacity has been reached. */ \ + if (v->len == v->alloc_size / sizeof(t)) { \ + /* Assuming that this does not exceed SIZE_MAX, because code proven \ + * correct by Aeneas. Would this even happen in practice? */ \ + size_t new_size; \ + if (v->alloc_size == 0) \ + new_size = 8 * sizeof(t); \ + else if (v->alloc_size <= SIZE_MAX / 2) \ + /* TODO: discuss growth policy */ \ + new_size = 2 * v->alloc_size; \ + else \ + new_size = (SIZE_MAX / sizeof(t)) * sizeof(t); \ + v->ptr = realloc(v->ptr, new_size); \ + v->alloc_size = new_size; \ + } \ + ((t *)v->ptr)[v->len] = x; \ + v->len++; \ + } while (0) + +#define EURYDICE_VEC_DROP(v, t) \ + do { \ + free(v->ptr); \ + free(v); \ + } while (0) + +#define EURYDICE_VEC_INDEX(v, i, t) &((t *)v->ptr)[i] +#define EURYDICE_VEC_LEN(v, t) (v)->len + +/* TODO: remove GCC-isms */ +#define EURYDICE_BOX_NEW(x, t) \ + ({ \ + t *p = malloc(sizeof(t)); \ + *p = x; \ + p; \ + }) + +#define EURYDICE_REPLACE(ptr, new_v, t) \ + ({ \ + t old_v = *ptr; \ + *ptr = new_v; \ + old_v; \ + }) + +#if defined(__cplusplus) +} +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h new file mode 100644 index 000000000..6deb05bb9 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -0,0 +1,256 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_core_H +#define __internal_libcrux_core_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_core.h" +#include "eurydice_glue.h" + +extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none(core_fmt_rt_Argument x0[0U]); + +extern core_fmt_Arguments +core_fmt__core__fmt__Arguments__a__2__new_v1(Eurydice_slice x0, Eurydice_slice x1); + +#define CORE_NUM__U32_8__BITS (32U) + +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]); + +#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) + +void +libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, + Eurydice_slice rhs, + uint8_t selector, + uint8_t ret[32U] +); + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT ((size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT ((size_t)256U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) + +#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) + +libcrux_ml_kem_types_MlKemPublicKey____1568size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uint8_t value[1568U] +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk +); + +libcrux_ml_kem_types_MlKemPrivateKey____3168size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uint8_t value[3168U] +); + +typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s +{ + uint8_t fst[1536U]; + uint8_t snd[1568U]; +} +K___uint8_t_1536size_t__uint8_t_1568size_t_; + +libcrux_ml_kem_types_MlKemCiphertext____1568size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uint8_t value[1568U] +); + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self +); + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +); + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self +); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, uint8_t ret[1600U]); + +libcrux_ml_kem_types_MlKemPublicKey____1184size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uint8_t value[1184U] +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk +); + +libcrux_ml_kem_types_MlKemPrivateKey____2400size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uint8_t value[2400U] +); + +typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s +{ + uint8_t fst[1152U]; + uint8_t snd[1184U]; +} +K___uint8_t_1152size_t__uint8_t_1184size_t_; + +libcrux_ml_kem_types_MlKemCiphertext____1088size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uint8_t value[1088U] +); + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self +); + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +); + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self +); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]); + +typedef struct K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s +{ + Eurydice_slice fst; + Eurydice_slice snd; +} +K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; + +typedef struct K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s +{ + Eurydice_slice fst; + Eurydice_slice snd; +} +K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; + +typedef struct K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s +{ + Eurydice_slice fst; + Eurydice_slice snd; +} +K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; + +libcrux_ml_kem_types_MlKemPublicKey____800size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uint8_t value[800U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk +); + +libcrux_ml_kem_types_MlKemPrivateKey____1632size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uint8_t value[1632U] +); + +typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s +{ + uint8_t fst[768U]; + uint8_t snd[800U]; +} +K___uint8_t_768size_t__uint8_t_800size_t_; + +libcrux_ml_kem_types_MlKemCiphertext____768size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uint8_t value[768U] +); + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self +); + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]); + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self +); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, uint8_t ret[800U]); + +void +libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]); + +typedef struct core_option_Option__Eurydice_slice_uint8_t_s +{ + core_option_Option__size_t_tags tag; + Eurydice_slice f0; +} +core_option_Option__Eurydice_slice_uint8_t; + +typedef struct core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s +{ + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; + union { + int16_t case_Ok[16U]; + core_array_TryFromSliceError case_Err; + } + val; +} +core_result_Result__int16_t_16size_t__core_array_TryFromSliceError; + +void +core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, + int16_t ret[16U] +); + +typedef struct K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t__s +{ + Eurydice_slice fst[2U]; + Eurydice_slice snd[2U]; +} +K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_; + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_core_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h new file mode 100644 index 000000000..5a3e6df8f --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h @@ -0,0 +1,94 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_mlkem_neon_H +#define __internal_libcrux_mlkem_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_core.h" +#include "../libcrux_mlkem_neon.h" +#include "eurydice_glue.h" + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_mlkem_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h new file mode 100644 index 000000000..e740ee1d0 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -0,0 +1,98 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_mlkem_portable_H +#define __internal_libcrux_mlkem_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "internal/libcrux_sha3_internal.h" +#include "internal/libcrux_core.h" +#include "../libcrux_mlkem_portable.h" +#include "eurydice_glue.h" + +extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U]; + +#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_mlkem_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h new file mode 100644 index 000000000..2471ee04f --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -0,0 +1,286 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_sha3_internal_H +#define __internal_libcrux_sha3_internal_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_sha3_internal.h" +#include "eurydice_glue.h" + +typedef libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_portable_KeccakState1; + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_portable_incremental_shake128_init(void) +{ + return + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice data0 +) +{ + Eurydice_slice buf[1U] = { data0 }; + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(s, buf); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0 +) +{ + Eurydice_slice buf[1U] = { out0 }; + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, buf); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o10, + (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o2[1U]; + memcpy(o2, uu____1.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o1); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o2); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0 +) +{ + Eurydice_slice buf[1U] = { out0 }; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t(s, buf); +} + +#define libcrux_sha3_Sha224 0 +#define libcrux_sha3_Sha256 1 +#define libcrux_sha3_Sha384 2 +#define libcrux_sha3_Sha512 3 + +typedef uint8_t libcrux_sha3_Algorithm; + +static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) +{ + size_t uu____0; + switch (mode) + { + case libcrux_sha3_Sha224: + { + uu____0 = (size_t)28U; + break; + } + case libcrux_sha3_Sha256: + { + uu____0 = (size_t)32U; + break; + } + case libcrux_sha3_Sha384: + { + uu____0 = (size_t)48U; + break; + } + case libcrux_sha3_Sha512: + { + uu____0 = (size_t)64U; + break; + } + default: + { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +static const +size_t +libcrux_sha3_generic_keccak__PI[24U] = + { + (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, (size_t)9U, (size_t)10U, + (size_t)16U, (size_t)22U, (size_t)1U, (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, + (size_t)4U, (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, (size_t)8U, + (size_t)14U, (size_t)15U, (size_t)21U + }; + +static const +size_t +libcrux_sha3_generic_keccak__ROTC[24U] = + { + (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, (size_t)44U, (size_t)6U, + (size_t)55U, (size_t)20U, (size_t)3U, (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, + (size_t)41U, (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, (size_t)2U, + (size_t)61U, (size_t)56U, (size_t)14U + }; + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o10, + (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o20[1U]; + memcpy(o20, uu____1.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o1); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o20, + (size_t)168U); + Eurydice_slice o2[1U]; + memcpy(o2, uu____2.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o30[1U]; + memcpy(o30, uu____2.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o2); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o30, + (size_t)168U); + Eurydice_slice o3[1U]; + memcpy(o3, uu____3.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o4[1U]; + memcpy(o4, uu____3.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o3); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o4); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0 +) +{ + Eurydice_slice buf[1U] = { out0 }; + libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t(s, buf); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self +) +{ + return self[0U]; +} + +static inline uint32_t +libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( + libcrux_sha3_Algorithm v +) +{ + uint32_t uu____0; + switch (v) + { + case libcrux_sha3_Sha224: + { + uu____0 = 1U; + break; + } + case libcrux_sha3_Sha256: + { + uu____0 = 2U; + break; + } + case libcrux_sha3_Sha384: + { + uu____0 = 3U; + break; + } + case libcrux_sha3_Sha512: + { + uu____0 = 4U; + break; + } + default: + { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +static inline libcrux_sha3_Algorithm +libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from(uint32_t v) +{ + libcrux_sha3_Algorithm uu____0; + switch (v) + { + case 1U: + { + uu____0 = libcrux_sha3_Sha224; + break; + } + case 2U: + { + uu____0 = libcrux_sha3_Sha256; + break; + } + case 3U: + { + uu____0 = libcrux_sha3_Sha384; + break; + } + case 4U: + { + uu____0 = libcrux_sha3_Sha512; + break; + } + default: + { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); + } + } + return uu____0; +} + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_sha3_internal_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c new file mode 100644 index 000000000..8730222c6 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -0,0 +1,467 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_core.h" + +typedef size_t RangeTo__size_t; + +typedef size_t RangeFrom__size_t; + +typedef struct Option__int32_t_s +{ + core_option_Option__size_t_tags tag; + int32_t f0; +} +Option__int32_t; + +typedef struct Option__uint32_t_s +{ + core_option_Option__size_t_tags tag; + uint32_t f0; +} +Option__uint32_t; + +static uint8_t is_non_zero(uint8_t value) +{ + uint16_t value0 = (uint16_t)value; + uint16_t uu____0 = value0; + uint16_t + result = + (((uint32_t)uu____0 | (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & 0xFFFFU) + >> 8U + & 1U; + return (uint8_t)result; +} + +void +libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, + Eurydice_slice rhs, + uint8_t selector, + uint8_t ret[32U] +) +{ + uint8_t mask = core_num__u8_6__wrapping_sub(is_non_zero(selector), 1U); + uint8_t out[32U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; i++) + { + size_t i0 = i; + uint8_t + uu____0 = (uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t) & (uint32_t)mask; + uint8_t *uu____1 = &Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t); + out[i0] = (uint32_t)uu____0 | ((uint32_t)uu____1[0U] & (uint32_t)~mask); + } + memcpy(ret, out, (size_t)32U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemPublicKey____1568size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uint8_t value[1568U] +) +{ + uint8_t uu____0[1568U]; + memcpy(uu____0, value, (size_t)1568U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t lit; + memcpy(lit.value, uu____0, (size_t)1568U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk +) +{ + return ((libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t){ .sk = sk, .pk = pk }); +} + +libcrux_ml_kem_types_MlKemPrivateKey____3168size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uint8_t value[3168U] +) +{ + uint8_t uu____0[3168U]; + memcpy(uu____0, value, (size_t)3168U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t lit; + memcpy(lit.value, uu____0, (size_t)3168U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemCiphertext____1568size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uint8_t value[1568U] +) +{ + uint8_t uu____0[1568U]; + memcpy(uu____0, value, (size_t)1568U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t lit; + memcpy(lit.value, uu____0, (size_t)1568U * sizeof (uint8_t)); + return lit; +} + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self +) +{ + return self->value; +} + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +) +{ + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < (size_t)1568U; i++) + { + size_t i0 = i; + uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = + (uint32_t)r + | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + } + return is_non_zero(r); +} + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self +) +{ + return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t, Eurydice_slice); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, uint8_t ret[1600U]) +{ + uint8_t out[1600U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1600U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)1600U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemPublicKey____1184size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uint8_t value[1184U] +) +{ + uint8_t uu____0[1184U]; + memcpy(uu____0, value, (size_t)1184U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t lit; + memcpy(lit.value, uu____0, (size_t)1184U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk +) +{ + return ((libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t){ .sk = sk, .pk = pk }); +} + +libcrux_ml_kem_types_MlKemPrivateKey____2400size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uint8_t value[2400U] +) +{ + uint8_t uu____0[2400U]; + memcpy(uu____0, value, (size_t)2400U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t lit; + memcpy(lit.value, uu____0, (size_t)2400U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemCiphertext____1088size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uint8_t value[1088U] +) +{ + uint8_t uu____0[1088U]; + memcpy(uu____0, value, (size_t)1088U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t lit; + memcpy(lit.value, uu____0, (size_t)1088U * sizeof (uint8_t)); + return lit; +} + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self +) +{ + return self->value; +} + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +) +{ + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < (size_t)1088U; i++) + { + size_t i0 = i; + uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = + (uint32_t)r + | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + } + return is_non_zero(r); +} + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self +) +{ + return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, Eurydice_slice); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]) +{ + uint8_t out[1120U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1120U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)1120U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemPublicKey____800size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uint8_t value[800U] +) +{ + uint8_t uu____0[800U]; + memcpy(uu____0, value, (size_t)800U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey____800size_t lit; + memcpy(lit.value, uu____0, (size_t)800U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk +) +{ + return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ .sk = sk, .pk = pk }); +} + +libcrux_ml_kem_types_MlKemPrivateKey____1632size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uint8_t value[1632U] +) +{ + uint8_t uu____0[1632U]; + memcpy(uu____0, value, (size_t)1632U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t lit; + memcpy(lit.value, uu____0, (size_t)1632U * sizeof (uint8_t)); + return lit; +} + +libcrux_ml_kem_types_MlKemCiphertext____768size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uint8_t value[768U] +) +{ + uint8_t uu____0[768U]; + memcpy(uu____0, value, (size_t)768U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t lit; + memcpy(lit.value, uu____0, (size_t)768U * sizeof (uint8_t)); + return lit; +} + +uint8_t +*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self +) +{ + return self->value; +} + +uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + Eurydice_slice lhs, + Eurydice_slice rhs +) +{ + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < (size_t)768U; i++) + { + size_t i0 = i; + uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = + (uint32_t)r + | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + } + return is_non_zero(r); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]) +{ + uint8_t out[33U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)33U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)33U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]) +{ + uint8_t out[34U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)34U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)34U * sizeof (uint8_t)); +} + +Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self +) +{ + return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, Eurydice_slice); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, uint8_t ret[800U]) +{ + uint8_t out[800U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)800U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)800U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]) +{ + uint8_t out[64U] = { 0U }; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)64U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + slice, + uint8_t, + void *); + memcpy(ret, out, (size_t)64U * sizeof (uint8_t)); +} + +void +core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, + int16_t ret[16U] +) +{ + if (self.tag == core_result_Ok) + { + int16_t f0[16U]; + memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof (int16_t)); + memcpy(ret, f0, (size_t)16U * sizeof (int16_t)); + } + else + { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +void +core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, + uint8_t ret[8U] +) +{ + if (self.tag == core_result_Ok) + { + uint8_t f0[8U]; + memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof (uint8_t)); + memcpy(ret, f0, (size_t)8U * sizeof (uint8_t)); + } + else + { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h new file mode 100644 index 000000000..0df3058ed --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -0,0 +1,175 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_core_H +#define __libcrux_core_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" + +typedef struct core_ops_range_Range__size_t_s +{ + size_t start; + size_t end; +} +core_ops_range_Range__size_t; + +extern uint8_t Eurydice_bitand_pv_u8(uint8_t *x, uint8_t y); + +extern uint8_t Eurydice_shr_pv_u8(uint8_t *x, int32_t y); + +#define core_option_None 0 +#define core_option_Some 1 + +typedef uint8_t core_option_Option__size_t_tags; + +typedef struct core_option_Option__size_t_s +{ + core_option_Option__size_t_tags tag; + size_t f0; +} +core_option_Option__size_t; + +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); + +static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); + +typedef struct libcrux_ml_kem_types_MlKemPublicKey____1568size_t_s { uint8_t value[1568U]; } +libcrux_ml_kem_types_MlKemPublicKey____1568size_t; + +typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t___s +{ + core_option_Option__size_t_tags tag; + libcrux_ml_kem_types_MlKemPublicKey____1568size_t f0; +} +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__; + +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____3168size_t_s { uint8_t value[3168U]; } +libcrux_ml_kem_types_MlKemPrivateKey____3168size_t; + +typedef struct libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t_s +{ + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk; + libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk; +} +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t; + +typedef struct libcrux_ml_kem_types_MlKemCiphertext____1568size_t_s { uint8_t value[1568U]; } +libcrux_ml_kem_types_MlKemCiphertext____1568size_t; + +typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t__s +{ + libcrux_ml_kem_types_MlKemCiphertext____1568size_t fst; + uint8_t snd[32U]; +} +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_; + +typedef struct libcrux_ml_kem_types_MlKemPublicKey____1184size_t_s { uint8_t value[1184U]; } +libcrux_ml_kem_types_MlKemPublicKey____1184size_t; + +typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t___s +{ + core_option_Option__size_t_tags tag; + libcrux_ml_kem_types_MlKemPublicKey____1184size_t f0; +} +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__; + +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { uint8_t value[2400U]; } +libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; + +typedef struct libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t_s +{ + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk; + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk; +} +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t; + +typedef struct libcrux_ml_kem_types_MlKemCiphertext____1088size_t_s { uint8_t value[1088U]; } +libcrux_ml_kem_types_MlKemCiphertext____1088size_t; + +typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s +{ + libcrux_ml_kem_types_MlKemCiphertext____1088size_t fst; + uint8_t snd[32U]; +} +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; + +typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { uint8_t value[800U]; } +libcrux_ml_kem_types_MlKemPublicKey____800size_t; + +typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s +{ + core_option_Option__size_t_tags tag; + libcrux_ml_kem_types_MlKemPublicKey____800size_t f0; +} +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; + +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { uint8_t value[1632U]; } +libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; + +typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s +{ + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk; + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk; +} +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; + +typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { uint8_t value[768U]; } +libcrux_ml_kem_types_MlKemCiphertext____768size_t; + +typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s +{ + libcrux_ml_kem_types_MlKemCiphertext____768size_t fst; + uint8_t snd[32U]; +} +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; + +#define core_result_Ok 0 +#define core_result_Err 1 + +typedef uint8_t core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags; + +typedef struct core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s +{ + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[8U]; + core_array_TryFromSliceError case_Err; + } + val; +} +core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; + +void +core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, + uint8_t ret[8U] +); + +typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s +{ + Eurydice_slice fst; + Eurydice_slice snd; +} +K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; + +typedef struct K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s +{ + Eurydice_slice fst[1U]; + Eurydice_slice snd[1U]; +} +K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_core_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c new file mode 100644 index 000000000..806b58c57 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.c @@ -0,0 +1,203 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem1024.h" + +#include "internal/libcrux_core.h" + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + uu____0); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + uu____0); + } + else + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + return; + } + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_mlkem1024_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ uu____0; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____1, + uu____2); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____3, + uu____4); + } + else + { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6); + } + return uu____0; +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____1); + } + else if (libcrux_platform_platform_simd128_support()) + { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____2); + return uu____0; + } + else + { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____3); + } + return uu____0; +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); +} + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +) +{ + bool uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key); + } + else if (libcrux_platform_platform_simd128_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t(public_key); + return uu____0; + } + else + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key); + } + return uu____0; +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h new file mode 100644 index 000000000..8478e2e63 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -0,0 +1,104 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_H +#define __libcrux_mlkem1024_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_platform.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_mlkem512_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 ((size_t)11U) + +#define LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 ((size_t)4U) + +#define LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 * LIBCRUX_ML_KEM_MLKEM1024_RANK_1024) + +#define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 ((size_t)5U) + +#define LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 + LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024) + +#define LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 + (size_t)32U) + +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM1024_ETA1 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM1024_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM1024_ETA1 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM1024_ETA2 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM1024_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM1024_ETA2 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM1024_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024) + +#define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +void +libcrux_ml_kem_mlkem1024_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c new file mode 100644 index 000000000..b86a77759 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c @@ -0,0 +1,77 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem1024_neon.h" + +void +libcrux_ml_kem_mlkem1024_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h new file mode 100644 index 000000000..73b4dfddf --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h @@ -0,0 +1,45 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_neon_H +#define __libcrux_mlkem1024_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_mlkem512_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_mlkem1024_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c new file mode 100644 index 000000000..989347491 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -0,0 +1,77 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem1024_portable.h" + +void +libcrux_ml_kem_mlkem1024_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h new file mode 100644 index 000000000..3b80960f2 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -0,0 +1,45 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_portable_H +#define __libcrux_mlkem1024_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_mlkem512_portable.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_mlkem1024_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c new file mode 100644 index 000000000..30acdca01 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512.c @@ -0,0 +1,203 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem512.h" + +#include "internal/libcrux_core.h" + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + uu____0); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + uu____0); + } + else + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + return; + } + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_mlkem512_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ uu____0; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____1, + uu____2); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____3, + uu____4); + } + else + { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, + uu____6); + } + return uu____0; +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +) +{ + libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____1); + } + else if (libcrux_platform_platform_simd128_support()) + { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____2); + return uu____0; + } + else + { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____3); + } + return uu____0; +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); +} + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +) +{ + bool uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key); + } + else if (libcrux_platform_platform_simd128_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t(public_key); + return uu____0; + } + else + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key); + } + return uu____0; +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h new file mode 100644 index 000000000..5141914df --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -0,0 +1,104 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_H +#define __libcrux_mlkem512_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_platform.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_mlkem512_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +#define LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 ((size_t)10U) + +#define LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM512_RANK_512 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 * LIBCRUX_ML_KEM_MLKEM512_RANK_512) + +#define LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 ((size_t)4U) + +#define LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512) + +#define LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 + (size_t)32U) + +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM512_ETA1 ((size_t)3U) + +#define LIBCRUX_ML_KEM_MLKEM512_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM512_ETA1 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM512_ETA2 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM512_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM512_ETA2 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM512_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512) + +#define LIBCRUX_ML_KEM_MLKEM512_RANKED_BYTES_PER_RING_ELEMENT_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM512_SECRET_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +void +libcrux_ml_kem_mlkem512_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c new file mode 100644 index 000000000..ee559d69b --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c @@ -0,0 +1,223 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem512_neon.h" + +#include "internal/libcrux_mlkem_neon.h" + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_mlkem512_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, + uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); +} + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h new file mode 100644 index 000000000..dc33f9084 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h @@ -0,0 +1,113 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_neon_H +#define __libcrux_mlkem512_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +void +libcrux_ml_kem_mlkem512_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]); + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +); + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c new file mode 100644 index 000000000..1259ebf65 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -0,0 +1,223 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem512_portable.h" + +#include "internal/libcrux_mlkem_portable.h" + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_mlkem512_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, + uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_portable_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); +} + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +) +{ + return + libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h new file mode 100644 index 000000000..3e5778778 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -0,0 +1,113 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_portable_H +#define __libcrux_mlkem512_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +void +libcrux_ml_kem_mlkem512_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_portable_generate_key_pair(uint8_t randomness[64U]); + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key +); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key +); + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +); + +bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c new file mode 100644 index 000000000..7f07572a4 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768.c @@ -0,0 +1,203 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768.h" + +#include "internal/libcrux_core.h" + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t uu____0[32U]; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + uu____0); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + uu____0); + } + else + { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + return; + } + memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_mlkem768_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ uu____0; + if (libcrux_platform_platform_simd256_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____1 = public_key; + uint8_t uu____2[32U]; + memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____1, + uu____2); + } + else if (libcrux_platform_platform_simd128_support()) + { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; + uint8_t uu____4[32U]; + memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____3, + uu____4); + } + else + { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6); + } + return uu____0; +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uint8_t uu____1[64U]; + memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____1); + } + else if (libcrux_platform_platform_simd128_support()) + { + uint8_t uu____2[64U]; + memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____2); + return uu____0; + } + else + { + uint8_t uu____3[64U]; + memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____3); + } + return uu____0; +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); +} + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +) +{ + bool uu____0; + if (libcrux_platform_platform_simd256_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key); + } + else if (libcrux_platform_platform_simd128_support()) + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t(public_key); + return uu____0; + } + else + { + uu____0 = + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key); + } + return uu____0; +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h new file mode 100644 index 000000000..aa62f65ff --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -0,0 +1,104 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_H +#define __libcrux_mlkem768_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_platform.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_mlkem512_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) + +#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) + +#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) + +#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +void +libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +void +libcrux_ml_kem_mlkem768_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); + +bool +libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key +); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c new file mode 100644 index 000000000..c9dd6730d --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c @@ -0,0 +1,77 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768_neon.h" + +void +libcrux_ml_kem_mlkem768_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h new file mode 100644 index 000000000..4edf95c59 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h @@ -0,0 +1,45 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_neon_H +#define __libcrux_mlkem768_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_mlkem512_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_mlkem768_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c new file mode 100644 index 000000000..e0363174d --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -0,0 +1,77 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768_portable.h" + +void +libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, + ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, + uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) +{ + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); + return + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +) +{ + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; + if + ( + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) + ) + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, + .f0 = public_key + } + ); + } + else + { + uu____0 = + ( + (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None + } + ); + } + return uu____0; +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h new file mode 100644 index 000000000..d5b0efcba --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -0,0 +1,45 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_portable_H +#define __libcrux_mlkem768_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_mlkem512_portable.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.c b/libcrux-ml-kem/c/libcrux_mlkem_neon.c new file mode 100644 index 000000000..c7a62ef71 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.c @@ -0,0 +1,9690 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_mlkem_neon.h" + +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_core.h" + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ZERO(void) +{ + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0); + return + ( + (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, + .high = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0) + } + ); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( + void +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_ZERO(); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array) +{ + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice(array, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + return + ( + (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, + .high = libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice(array, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)) + } + ); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( + Eurydice_slice array +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(array); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +) +{ + lhs.low = libcrux_intrinsics_arm64__vaddq_s16(lhs.low, rhs->low); + lhs.high = libcrux_intrinsics_arm64__vaddq_s16(lhs.high, rhs->high); + return lhs; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_add(lhs, rhs); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +) +{ + lhs.low = libcrux_intrinsics_arm64__vsubq_s16(lhs.low, rhs->low); + lhs.high = libcrux_intrinsics_arm64__vsubq_s16(lhs.high, rhs->high); + return lhs; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_sub(lhs, rhs); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + v.low = libcrux_intrinsics_arm64__vmulq_n_s16(v.low, c); + v.high = libcrux_intrinsics_arm64__vmulq_n_s16(v.high, c); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant(v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + core_core_arch_arm_shared_neon_int16x8_t c0 = libcrux_intrinsics_arm64__vdupq_n_s16(c); + v.low = libcrux_intrinsics_arm64__vandq_s16(v.low, c0); + v.high = libcrux_intrinsics_arm64__vandq_s16(v.high, c0); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant(v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_int16x8_t + c = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)3329); + core_core_arch_arm_shared_neon_uint16x8_t m0 = libcrux_intrinsics_arm64__vcgeq_s16(v.low, c); + core_core_arch_arm_shared_neon_uint16x8_t m1 = libcrux_intrinsics_arm64__vcgeq_s16(v.high, c); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = c; + core_core_arch_arm_shared_neon_int16x8_t + c0 = + libcrux_intrinsics_arm64__vandq_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m0)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = c; + core_core_arch_arm_shared_neon_int16x8_t + c1 = + libcrux_intrinsics_arm64__vandq_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m1)); + v.low = libcrux_intrinsics_arm64__vsubq_s16(v.low, c0); + v.high = libcrux_intrinsics_arm64__vsubq_s16(v.high, c1); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329(v); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v +) +{ + core_core_arch_arm_shared_neon_int16x8_t + adder = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1024); + core_core_arch_arm_shared_neon_int16x8_t + vec = + libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, + LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER); + core_core_arch_arm_shared_neon_int16x8_t + vec0 = libcrux_intrinsics_arm64__vaddq_s16(vec, adder); + core_core_arch_arm_shared_neon_int16x8_t + quotient = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)11, + vec0, + core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t + sub = + libcrux_intrinsics_arm64__vmulq_n_s16(quotient, + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_intrinsics_arm64__vsubq_s16(v, sub); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + v.low = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.low); + v.high = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.high); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce(v); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t low, + core_core_arch_arm_shared_neon_int16x8_t high +) +{ + core_core_arch_arm_shared_neon_int16x8_t + k = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vmulq_n_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(low), + (uint16_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_arm_shared_neon_int16x8_t + c = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, + libcrux_intrinsics_arm64__vqdmulhq_n_s16(k, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_intrinsics_arm64__vsubq_s16(high, c); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + int16_t c +) +{ + core_core_arch_arm_shared_neon_int16x8_t v_low = libcrux_intrinsics_arm64__vmulq_n_s16(v, c); + core_core_arch_arm_shared_neon_int16x8_t + v_high = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, + libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, c), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(v_low, v_high); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + v.low = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t(v.low, + c); + v.high = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t(v.high, + c); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant(v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_int16x8_t + half = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1664); + core_core_arch_arm_shared_neon_int16x8_t + quarter = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)832); + core_core_arch_arm_shared_neon_int16x8_t + shifted = libcrux_intrinsics_arm64__vsubq_s16(half, v.low); + core_core_arch_arm_shared_neon_int16x8_t + mask0 = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, + shifted, + core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t + shifted_to_positive = libcrux_intrinsics_arm64__veorq_s16(mask0, shifted); + core_core_arch_arm_shared_neon_int16x8_t + shifted_positive_in_range = libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive, quarter); + v.low = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vshrq_n_u16((int32_t)15, + libcrux_intrinsics_arm64__vreinterpretq_u16_s16(shifted_positive_in_range), + core_core_arch_arm_shared_neon_uint16x8_t)); + core_core_arch_arm_shared_neon_int16x8_t + shifted0 = libcrux_intrinsics_arm64__vsubq_s16(half, v.high); + core_core_arch_arm_shared_neon_int16x8_t + mask = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, + shifted0, + core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t + shifted_to_positive0 = libcrux_intrinsics_arm64__veorq_s16(mask, shifted0); + core_core_arch_arm_shared_neon_int16x8_t + shifted_positive_in_range0 = libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive0, quarter); + v.high = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vshrq_n_u16((int32_t)15, + libcrux_intrinsics_arm64__vreinterpretq_u16_s16(shifted_positive_in_range0), + core_core_arch_arm_shared_neon_uint16x8_t)); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_compress_1(v); +} + +inline int16_t +libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits(int16_t coefficient_bits) +{ + int16_t uu____0; + switch (coefficient_bits) + { + case 4: + { + uu____0 = (int16_t)15; + break; + } + case 5: + { + uu____0 = (int16_t)31; + break; + } + case 10: + { + uu____0 = (int16_t)1023; + break; + } + case 11: + { + uu____0 = (int16_t)2047; + break; + } + default: + { + int16_t x = coefficient_bits; + uu____0 = ((int16_t)1 << (uint32_t)x) - (int16_t)1; + } + } + return uu____0; +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + core_core_arch_arm_shared_neon_int16x8_t c +) +{ + core_core_arch_arm_shared_neon_int16x8_t v_low = libcrux_intrinsics_arm64__vmulq_s16(v, c); + core_core_arch_arm_shared_neon_int16x8_t + v_high = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, + libcrux_intrinsics_arm64__vqdmulhq_s16(v, c), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(v_low, v_high); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + int16_t zetas[8U] = { zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4 }; + core_core_arch_arm_shared_neon_int16x8_t + zeta = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + zetas, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int32x4_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + dup_a = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int32x4_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + dup_b = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t + t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, zeta); + core_core_arch_arm_shared_neon_int16x8_t b = libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int32x4_t + uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); + v.low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____2, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + core_core_arch_arm_shared_neon_int32x4_t + uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); + v.high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____3, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step(a, zeta1, zeta2, zeta3, zeta4); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2 +) +{ + int16_t zetas[8U] = { zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2 }; + core_core_arch_arm_shared_neon_int16x8_t + zeta = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + zetas, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int64x2_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + dup_a = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int64x2_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + dup_b = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t + t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, zeta); + core_core_arch_arm_shared_neon_int16x8_t b = libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int64x2_t + uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____2, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + core_core_arch_arm_shared_neon_int64x2_t + uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____3, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2 +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step(a, zeta1, zeta2); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta +) +{ + core_core_arch_arm_shared_neon_int16x8_t zeta0 = libcrux_intrinsics_arm64__vdupq_n_s16(zeta); + core_core_arch_arm_shared_neon_int16x8_t + t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(v.high, zeta0); + v.high = libcrux_intrinsics_arm64__vsubq_s16(v.low, t); + v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, t); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step(a, zeta); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + int16_t zetas[8U] = { zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4 }; + core_core_arch_arm_shared_neon_int16x8_t + zeta = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + zetas, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int32x4_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + a0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int32x4_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + b0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t + b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(b0, a0); + core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(a0, b0); + core_core_arch_arm_shared_neon_int16x8_t + a1 = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(a); + core_core_arch_arm_shared_neon_int16x8_t + b = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta); + core_core_arch_arm_shared_neon_int32x4_t + uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); + v.low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____2, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + core_core_arch_arm_shared_neon_int32x4_t + uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); + v.high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____3, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + return + libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step(a, + zeta1, + zeta2, + zeta3, + zeta4); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2 +) +{ + int16_t zetas[8U] = { zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2 }; + core_core_arch_arm_shared_neon_int16x8_t + zeta = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + zetas, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int64x2_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + a0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int64x2_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t + b0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t + b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(b0, a0); + core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(a0, b0); + core_core_arch_arm_shared_neon_int16x8_t + b = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta); + core_core_arch_arm_shared_neon_int64x2_t + uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____2, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + core_core_arch_arm_shared_neon_int64x2_t + uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____3, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2 +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step(a, zeta1, zeta2); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta +) +{ + core_core_arch_arm_shared_neon_int16x8_t zeta0 = libcrux_intrinsics_arm64__vdupq_n_s16(zeta); + core_core_arch_arm_shared_neon_int16x8_t + b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(v.high, v.low); + v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, v.high); + v.high = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta0); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step(a, zeta); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + int16_t zetas[8U] = { zeta1, zeta3, -zeta1, -zeta3, zeta2, zeta4, -zeta2, -zeta4 }; + core_core_arch_arm_shared_neon_int16x8_t + zeta = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + zetas, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t + a0 = libcrux_intrinsics_arm64__vtrn1q_s16(lhs->low, lhs->high); + core_core_arch_arm_shared_neon_int16x8_t + a1 = libcrux_intrinsics_arm64__vtrn2q_s16(lhs->low, lhs->high); + core_core_arch_arm_shared_neon_int16x8_t + b0 = libcrux_intrinsics_arm64__vtrn1q_s16(rhs->low, rhs->high); + core_core_arch_arm_shared_neon_int16x8_t + b1 = libcrux_intrinsics_arm64__vtrn2q_s16(rhs->low, rhs->high); + core_core_arch_arm_shared_neon_int16x8_t + a1b1 = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(a1, b1); + core_core_arch_arm_shared_neon_int16x4_t + uu____0 = libcrux_intrinsics_arm64__vget_low_s16(a1b1); + core_core_arch_arm_shared_neon_int32x4_t + a1b1_low = + libcrux_intrinsics_arm64__vmull_s16(uu____0, + libcrux_intrinsics_arm64__vget_low_s16(zeta)); + core_core_arch_arm_shared_neon_int32x4_t + a1b1_high = libcrux_intrinsics_arm64__vmull_high_s16(a1b1, zeta); + core_core_arch_arm_shared_neon_int32x4_t uu____1 = a1b1_low; + core_core_arch_arm_shared_neon_int16x4_t uu____2 = libcrux_intrinsics_arm64__vget_low_s16(a0); + core_core_arch_arm_shared_neon_int16x8_t + fst_low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_s16(uu____1, + uu____2, + libcrux_intrinsics_arm64__vget_low_s16(b0))); + core_core_arch_arm_shared_neon_int16x8_t + fst_high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_high_s16(a1b1_high, + a0, + b0)); + core_core_arch_arm_shared_neon_int16x4_t uu____3 = libcrux_intrinsics_arm64__vget_low_s16(a0); + core_core_arch_arm_shared_neon_int32x4_t + a0b1_low = + libcrux_intrinsics_arm64__vmull_s16(uu____3, + libcrux_intrinsics_arm64__vget_low_s16(b1)); + core_core_arch_arm_shared_neon_int32x4_t + a0b1_high = libcrux_intrinsics_arm64__vmull_high_s16(a0, b1); + core_core_arch_arm_shared_neon_int32x4_t uu____4 = a0b1_low; + core_core_arch_arm_shared_neon_int16x4_t uu____5 = libcrux_intrinsics_arm64__vget_low_s16(a1); + core_core_arch_arm_shared_neon_int16x8_t + snd_low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_s16(uu____4, + uu____5, + libcrux_intrinsics_arm64__vget_low_s16(b0))); + core_core_arch_arm_shared_neon_int16x8_t + snd_high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_high_s16(a0b1_high, + a1, + b0)); + core_core_arch_arm_shared_neon_int16x8_t + fst_low16 = libcrux_intrinsics_arm64__vtrn1q_s16(fst_low, fst_high); + core_core_arch_arm_shared_neon_int16x8_t + fst_high16 = libcrux_intrinsics_arm64__vtrn2q_s16(fst_low, fst_high); + core_core_arch_arm_shared_neon_int16x8_t + snd_low16 = libcrux_intrinsics_arm64__vtrn1q_s16(snd_low, snd_high); + core_core_arch_arm_shared_neon_int16x8_t + snd_high16 = libcrux_intrinsics_arm64__vtrn2q_s16(snd_low, snd_high); + core_core_arch_arm_shared_neon_int16x8_t + fst = libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(fst_low16, fst_high16); + core_core_arch_arm_shared_neon_int16x8_t + snd = libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(snd_low16, snd_high16); + core_core_arch_arm_shared_neon_int32x4_t + low0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(fst, snd)); + core_core_arch_arm_shared_neon_int32x4_t + high0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(fst, snd)); + core_core_arch_arm_shared_neon_int16x8_t + low1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(low0, + high0)); + core_core_arch_arm_shared_neon_int16x8_t + high1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(low0, + high0)); + uint8_t + indexes[16U] = { 0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U }; + core_core_arch_arm_shared_neon_uint8x16_t + index = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, + indexes, + uint8_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t + low2 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(libcrux_intrinsics_arm64__vreinterpretq_u8_s16(low1), + index)); + core_core_arch_arm_shared_neon_int16x8_t + high2 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(libcrux_intrinsics_arm64__vreinterpretq_u8_s16(high1), + index)); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ .low = low2, .high = high2 }); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +) +{ + return + libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply(lhs, + rhs, + zeta1, + zeta2, + zeta3, + zeta4); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[2U] +) +{ + int16_t + shifter[8U] = + { + (int16_t)0, (int16_t)1, (int16_t)2, (int16_t)3, (int16_t)4, (int16_t)5, (int16_t)6, (int16_t)7 + }; + core_core_arch_arm_shared_neon_int16x8_t + shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + shifter, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t + low0 = libcrux_intrinsics_arm64__vshlq_s16(v.low, shift); + core_core_arch_arm_shared_neon_int16x8_t + high0 = libcrux_intrinsics_arm64__vshlq_s16(v.high, shift); + int16_t low = libcrux_intrinsics_arm64__vaddvq_s16(low0); + int16_t high = libcrux_intrinsics_arm64__vaddvq_s16(high0); + ret[0U] = (uint8_t)low; + ret[1U] = (uint8_t)high; +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[2U] +) +{ + uint8_t ret0[2U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_1(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a) +{ + core_core_arch_arm_shared_neon_int16x8_t + one = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1); + core_core_arch_arm_shared_neon_int16x8_t + low0 = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index(a, + (size_t)0U, + uint8_t, + uint8_t *, + uint8_t)); + core_core_arch_arm_shared_neon_int16x8_t + high0 = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index(a, + (size_t)1U, + uint8_t, + uint8_t *, + uint8_t)); + int16_t + shifter[8U] = + { + (int16_t)0, (int16_t)255, (int16_t)-2, (int16_t)-3, (int16_t)-4, (int16_t)-5, (int16_t)-6, + (int16_t)-7 + }; + core_core_arch_arm_shared_neon_int16x8_t + shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + shifter, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t + low = libcrux_intrinsics_arm64__vshlq_s16(low0, shift); + core_core_arch_arm_shared_neon_int16x8_t + high = libcrux_intrinsics_arm64__vshlq_s16(high0, shift); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vandq_s16(low, one); + return + ( + (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, + .high = libcrux_intrinsics_arm64__vandq_s16(high, one) + } + ); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(a); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[8U] +) +{ + int16_t + shifter[8U] = + { + (int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12, (int16_t)0, (int16_t)4, (int16_t)8, + (int16_t)12 + }; + core_core_arch_arm_shared_neon_int16x8_t + shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + shifter, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t + lowt = + libcrux_intrinsics_arm64__vshlq_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.low), + shift); + core_core_arch_arm_shared_neon_uint16x8_t + hight = + libcrux_intrinsics_arm64__vshlq_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.high), + shift); + uint64_t + sum0 = + (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_low_u16(lowt)); + uint64_t + sum1 = + (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_high_u16(lowt)); + uint64_t + sum2 = + (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_low_u16(hight)); + uint64_t + sum3 = + (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_high_u16(hight)); + uint64_t sum = ((sum0 | sum1 << 16U) | sum2 << 32U) | sum3 << 48U; + uint8_t ret0[8U]; + core_num__u64_9__to_le_bytes(sum, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[8U] +) +{ + uint8_t ret0[8U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_4(a, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v) +{ + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, v, Eurydice_slice, uint8_t [8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t input = core_num__u64_9__from_le_bytes(ret); + int16_t low[8U] = { 0U }; + int16_t high[8U] = { 0U }; + low[0U] = (int16_t)(input & 15ULL); + low[1U] = (int16_t)(input >> 4U & 15ULL); + low[2U] = (int16_t)(input >> 8U & 15ULL); + low[3U] = (int16_t)(input >> 12U & 15ULL); + low[4U] = (int16_t)(input >> 16U & 15ULL); + low[5U] = (int16_t)(input >> 20U & 15ULL); + low[6U] = (int16_t)(input >> 24U & 15ULL); + low[7U] = (int16_t)(input >> 28U & 15ULL); + high[0U] = (int16_t)(input >> 32U & 15ULL); + high[1U] = (int16_t)(input >> 36U & 15ULL); + high[2U] = (int16_t)(input >> 40U & 15ULL); + high[3U] = (int16_t)(input >> 44U & 15ULL); + high[4U] = (int16_t)(input >> 48U & 15ULL); + high[5U] = (int16_t)(input >> 52U & 15ULL); + high[6U] = (int16_t)(input >> 56U & 15ULL); + high[7U] = (int16_t)(input >> 60U & 15ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + low, + int16_t, + Eurydice_slice)); + lit.high = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + high, + int16_t, + Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(a); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t ret[16U] +) +{ + int16_t out[16U] = { 0U }; + libcrux_intrinsics_arm64__vst1q_s16(Eurydice_array_to_subslice((size_t)16U, + out, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v.low); + libcrux_intrinsics_arm64__vst1q_s16(Eurydice_array_to_subslice((size_t)16U, + out, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v.high); + memcpy(ret, out, (size_t)16U * sizeof (int16_t)); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[10U] +) +{ + uint8_t res[10U] = { 0U }; + int16_t out[16U]; + libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, out); + res[0U] = (uint8_t)(out[0U] | out[1U] << 5U); + res[1U] = (uint8_t)((out[1U] >> 3U | out[2U] << 2U) | out[3U] << 7U); + res[2U] = (uint8_t)(out[3U] >> 1U | out[4U] << 4U); + res[3U] = (uint8_t)((out[4U] >> 4U | out[5U] << 1U) | out[6U] << 6U); + res[4U] = (uint8_t)(out[6U] >> 2U | out[7U] << 3U); + res[5U] = (uint8_t)(out[(size_t)8U + (size_t)0U] | out[(size_t)8U + (size_t)1U] << 5U); + res[6U] = + (uint8_t)((out[(size_t)8U + (size_t)1U] >> 3U | out[(size_t)8U + (size_t)2U] << 2U) + | out[(size_t)8U + (size_t)3U] << 7U); + res[7U] = (uint8_t)(out[(size_t)8U + (size_t)3U] >> 1U | out[(size_t)8U + (size_t)4U] << 4U); + res[8U] = + (uint8_t)((out[(size_t)8U + (size_t)4U] >> 4U | out[(size_t)8U + (size_t)5U] << 1U) + | out[(size_t)8U + (size_t)6U] << 6U); + res[9U] = (uint8_t)(out[(size_t)8U + (size_t)6U] >> 2U | out[(size_t)8U + (size_t)7U] << 3U); + memcpy(ret, res, (size_t)10U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[10U] +) +{ + uint8_t ret0[10U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_5(a, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v) +{ + uint8_t input0[8U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)8U, + input0, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + uint8_t uu____1[8U]; + memcpy(uu____1, input0, (size_t)8U * sizeof (uint8_t)); + uint64_t low64 = core_num__u64_9__from_le_bytes(uu____1); + uint8_t input1[8U] = { 0U }; + Eurydice_slice + uu____2 = + Eurydice_array_to_subslice((size_t)8U, + input1, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)5U, .end = (size_t)10U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input1, (size_t)8U * sizeof (uint8_t)); + uint64_t high64 = core_num__u64_9__from_le_bytes(uu____3); + int16_t low[8U] = { 0U }; + int16_t high[8U] = { 0U }; + low[0U] = (int16_t)(low64 & 31ULL); + low[1U] = (int16_t)(low64 >> 5U & 31ULL); + low[2U] = (int16_t)(low64 >> 10U & 31ULL); + low[3U] = (int16_t)(low64 >> 15U & 31ULL); + low[4U] = (int16_t)(low64 >> 20U & 31ULL); + low[5U] = (int16_t)(low64 >> 25U & 31ULL); + low[6U] = (int16_t)(low64 >> 30U & 31ULL); + low[7U] = (int16_t)(low64 >> 35U & 31ULL); + high[0U] = (int16_t)(high64 & 31ULL); + high[1U] = (int16_t)(high64 >> 5U & 31ULL); + high[2U] = (int16_t)(high64 >> 10U & 31ULL); + high[3U] = (int16_t)(high64 >> 15U & 31ULL); + high[4U] = (int16_t)(high64 >> 20U & 31ULL); + high[5U] = (int16_t)(high64 >> 25U & 31ULL); + high[6U] = (int16_t)(high64 >> 30U & 31ULL); + high[7U] = (int16_t)(high64 >> 35U & 31ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + low, + int16_t, + Eurydice_slice)); + lit.high = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + high, + int16_t, + Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(a); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[20U] +) +{ + core_core_arch_arm_shared_neon_int32x4_t + low00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.low, + v.low)); + core_core_arch_arm_shared_neon_int32x4_t + low10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.low, + v.low)); + core_core_arch_arm_shared_neon_int32x4_t + mixt = + libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)10, + low00, + low10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t + low0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt, + mixt)); + core_core_arch_arm_shared_neon_int64x2_t + low1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt, + mixt)); + core_core_arch_arm_shared_neon_int64x2_t + low_mix = + libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)20, + low0, + low1, + core_core_arch_arm_shared_neon_int64x2_t); + core_core_arch_arm_shared_neon_int32x4_t + high00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.high, + v.high)); + core_core_arch_arm_shared_neon_int32x4_t + high10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.high, + v.high)); + core_core_arch_arm_shared_neon_int32x4_t + mixt0 = + libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)10, + high00, + high10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t + high0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, + mixt0)); + core_core_arch_arm_shared_neon_int64x2_t + high1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, + mixt0)); + core_core_arch_arm_shared_neon_int64x2_t + high_mix = + libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)20, + high0, + high1, + core_core_arch_arm_shared_neon_int64x2_t); + uint8_t result32[32U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); + Eurydice_slice + uu____1 = + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)32U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); + uint8_t result[20U] = { 0U }; + Eurydice_slice + uu____2 = + Eurydice_array_to_subslice((size_t)20U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____3 = + Eurydice_array_to_subslice((size_t)20U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)5U, .end = (size_t)10U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____3, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)13U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice((size_t)20U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)10U, .end = (size_t)15U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)21U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____5 = + Eurydice_array_to_subslice((size_t)20U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)15U, .end = (size_t)20U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____5, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)29U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + memcpy(ret, result, (size_t)20U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[20U] +) +{ + uint8_t ret0[20U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_10(a, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v) +{ + uint8_t input0[8U] = { 0U }; + uint8_t input1[8U] = { 0U }; + uint8_t input2[4U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)4U, input2, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)20U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input0, (size_t)8U * sizeof (uint8_t)); + uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); + uint8_t uu____4[8U]; + memcpy(uu____4, input1, (size_t)8U * sizeof (uint8_t)); + uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); + uint8_t uu____5[4U]; + memcpy(uu____5, input2, (size_t)4U * sizeof (uint8_t)); + uint32_t input20 = core_num__u32_8__from_le_bytes(uu____5); + int16_t low[8U] = { 0U }; + int16_t high[8U] = { 0U }; + low[0U] = (int16_t)(input00 & 1023ULL); + low[1U] = (int16_t)(input00 >> 10U & 1023ULL); + low[2U] = (int16_t)(input00 >> 20U & 1023ULL); + low[3U] = (int16_t)(input00 >> 30U & 1023ULL); + low[4U] = (int16_t)(input00 >> 40U & 1023ULL); + low[5U] = (int16_t)(input00 >> 50U & 1023ULL); + low[6U] = (int16_t)((input00 >> 60U | input10 << 4U) & 1023ULL); + low[7U] = (int16_t)(input10 >> 6U & 1023ULL); + high[0U] = (int16_t)(input10 >> 16U & 1023ULL); + high[1U] = (int16_t)(input10 >> 26U & 1023ULL); + high[2U] = (int16_t)(input10 >> 36U & 1023ULL); + high[3U] = (int16_t)(input10 >> 46U & 1023ULL); + high[4U] = (int16_t)(((uint32_t)(input10 >> 56U) | input20 << 8U) & 1023U); + high[5U] = (int16_t)(input20 >> 2U & 1023U); + high[6U] = (int16_t)(input20 >> 12U & 1023U); + high[7U] = (int16_t)(input20 >> 22U & 1023U); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + low, + int16_t, + Eurydice_slice)); + lit.high = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + high, + int16_t, + Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(a); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[22U] +) +{ + int16_t input[16U]; + libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, input); + uint8_t result[22U] = { 0U }; + result[0U] = (uint8_t)input[0U]; + result[1U] = (uint8_t)(input[0U] >> 8U | input[1U] << 3U); + result[2U] = (uint8_t)(input[1U] >> 5U | input[2U] << 6U); + result[3U] = (uint8_t)(input[2U] >> 2U); + result[4U] = (uint8_t)(input[2U] >> 10U | input[3U] << 1U); + result[5U] = (uint8_t)(input[3U] >> 7U | input[4U] << 4U); + result[6U] = (uint8_t)(input[4U] >> 4U | input[5U] << 7U); + result[7U] = (uint8_t)(input[5U] >> 1U); + result[8U] = (uint8_t)(input[5U] >> 9U | input[6U] << 2U); + result[9U] = (uint8_t)(input[6U] >> 6U | input[7U] << 5U); + result[10U] = (uint8_t)(input[7U] >> 3U); + result[(size_t)11U + (size_t)0U] = (uint8_t)input[(size_t)8U + (size_t)0U]; + result[(size_t)11U + (size_t)1U] = + (uint8_t)(input[(size_t)8U + (size_t)0U] >> 8U | input[(size_t)8U + (size_t)1U] << 3U); + result[(size_t)11U + (size_t)2U] = + (uint8_t)(input[(size_t)8U + (size_t)1U] >> 5U | input[(size_t)8U + (size_t)2U] << 6U); + result[(size_t)11U + (size_t)3U] = (uint8_t)(input[(size_t)8U + (size_t)2U] >> 2U); + result[(size_t)11U + (size_t)4U] = + (uint8_t)(input[(size_t)8U + (size_t)2U] >> 10U | input[(size_t)8U + (size_t)3U] << 1U); + result[(size_t)11U + (size_t)5U] = + (uint8_t)(input[(size_t)8U + (size_t)3U] >> 7U | input[(size_t)8U + (size_t)4U] << 4U); + result[(size_t)11U + (size_t)6U] = + (uint8_t)(input[(size_t)8U + (size_t)4U] >> 4U | input[(size_t)8U + (size_t)5U] << 7U); + result[(size_t)11U + (size_t)7U] = (uint8_t)(input[(size_t)8U + (size_t)5U] >> 1U); + result[(size_t)11U + (size_t)8U] = + (uint8_t)(input[(size_t)8U + (size_t)5U] >> 9U | input[(size_t)8U + (size_t)6U] << 2U); + result[(size_t)11U + (size_t)9U] = + (uint8_t)(input[(size_t)8U + (size_t)6U] >> 6U | input[(size_t)8U + (size_t)7U] << 5U); + result[(size_t)11U + (size_t)10U] = (uint8_t)(input[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[22U] +) +{ + uint8_t ret0[22U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_11(a, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v) +{ + uint8_t input0[8U] = { 0U }; + uint8_t input1[8U] = { 0U }; + uint8_t input2[8U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_array_to_subslice((size_t)8U, + input2, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)22U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input0, (size_t)8U * sizeof (uint8_t)); + uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); + uint8_t uu____4[8U]; + memcpy(uu____4, input1, (size_t)8U * sizeof (uint8_t)); + uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); + uint8_t uu____5[8U]; + memcpy(uu____5, input2, (size_t)8U * sizeof (uint8_t)); + uint64_t input20 = core_num__u64_9__from_le_bytes(uu____5); + int16_t low[8U] = { 0U }; + int16_t high[8U] = { 0U }; + low[0U] = (int16_t)(input00 & 2047ULL); + low[1U] = (int16_t)(input00 >> 11U & 2047ULL); + low[2U] = (int16_t)(input00 >> 22U & 2047ULL); + low[3U] = (int16_t)(input00 >> 33U & 2047ULL); + low[4U] = (int16_t)(input00 >> 44U & 2047ULL); + low[5U] = (int16_t)((input00 >> 55U | input10 << 9U) & 2047ULL); + low[6U] = (int16_t)(input10 >> 2U & 2047ULL); + low[7U] = (int16_t)(input10 >> 13U & 2047ULL); + high[0U] = (int16_t)(input10 >> 24U & 2047ULL); + high[1U] = (int16_t)(input10 >> 35U & 2047ULL); + high[2U] = (int16_t)(input10 >> 46U & 2047ULL); + high[3U] = (int16_t)((input10 >> 57U | input20 << 7U) & 2047ULL); + high[4U] = (int16_t)(input20 >> 4U & 2047ULL); + high[5U] = (int16_t)(input20 >> 15U & 2047ULL); + high[6U] = (int16_t)(input20 >> 26U & 2047ULL); + high[7U] = (int16_t)(input20 >> 37U & 2047ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + low, + int16_t, + Eurydice_slice)); + lit.high = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + high, + int16_t, + Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(a); +} + +inline void +libcrux_ml_kem_vector_neon_simd128ops_serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[24U] +) +{ + core_core_arch_arm_shared_neon_int32x4_t + low00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.low, + v.low)); + core_core_arch_arm_shared_neon_int32x4_t + low10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.low, + v.low)); + core_core_arch_arm_shared_neon_int32x4_t + mixt = + libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)12, + low00, + low10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t + low0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt, + mixt)); + core_core_arch_arm_shared_neon_int64x2_t + low1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt, + mixt)); + core_core_arch_arm_shared_neon_int64x2_t + low_mix = + libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)24, + low0, + low1, + core_core_arch_arm_shared_neon_int64x2_t); + core_core_arch_arm_shared_neon_int32x4_t + high00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.high, + v.high)); + core_core_arch_arm_shared_neon_int32x4_t + high10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.high, + v.high)); + core_core_arch_arm_shared_neon_int32x4_t + mixt0 = + libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)12, + high00, + high10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t + high0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, + mixt0)); + core_core_arch_arm_shared_neon_int64x2_t + high1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, + mixt0)); + core_core_arch_arm_shared_neon_int64x2_t + high_mix = + libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)24, + high0, + high1, + core_core_arch_arm_shared_neon_int64x2_t); + uint8_t result32[32U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); + Eurydice_slice + uu____1 = + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)32U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); + uint8_t result[24U] = { 0U }; + Eurydice_slice + uu____2 = + Eurydice_array_to_subslice((size_t)24U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____3 = + Eurydice_array_to_subslice((size_t)24U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)6U, .end = (size_t)12U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____3, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)14U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice((size_t)24U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)12U, .end = (size_t)18U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)22U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____5 = + Eurydice_array_to_subslice((size_t)24U, + result, + ((core_ops_range_Range__size_t){ .start = (size_t)18U, .end = (size_t)24U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____5, + Eurydice_array_to_subslice((size_t)32U, + result32, + ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)30U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + memcpy(ret, result, (size_t)24U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[24U] +) +{ + uint8_t ret0[24U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_12(a, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v) +{ + uint8_t indexes[16U] = { 0U, 1U, 1U, 2U, 3U, 4U, 4U, 5U, 6U, 7U, 7U, 8U, 9U, 10U, 10U, 11U }; + core_core_arch_arm_shared_neon_uint8x16_t + index_vec = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, + indexes, + uint8_t, + Eurydice_slice)); + int16_t + shifts[8U] = + { + (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, (int16_t)0, + (int16_t)-4 + }; + core_core_arch_arm_shared_neon_int16x8_t + shift_vec = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, + shifts, + int16_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t + mask12 = libcrux_intrinsics_arm64__vdupq_n_u16(4095U); + uint8_t input0[16U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)16U, + input0, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + core_core_arch_arm_shared_neon_uint8x16_t + input_vec0 = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, + input0, + uint8_t, + Eurydice_slice)); + uint8_t input1[16U] = { 0U }; + Eurydice_slice + uu____1 = + Eurydice_array_to_subslice((size_t)16U, + input1, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ .start = (size_t)12U, .end = (size_t)24U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + core_core_arch_arm_shared_neon_uint8x16_t + input_vec1 = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, + input1, + uint8_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t + moved0 = + libcrux_intrinsics_arm64__vreinterpretq_u16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec0, + index_vec)); + core_core_arch_arm_shared_neon_uint16x8_t + shifted0 = libcrux_intrinsics_arm64__vshlq_u16(moved0, shift_vec); + core_core_arch_arm_shared_neon_int16x8_t + low = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vandq_u16(shifted0, + mask12)); + core_core_arch_arm_shared_neon_uint16x8_t + moved1 = + libcrux_intrinsics_arm64__vreinterpretq_u16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec1, + index_vec)); + core_core_arch_arm_shared_neon_uint16x8_t + shifted1 = libcrux_intrinsics_arm64__vshlq_u16(moved1, shift_vec); + core_core_arch_arm_shared_neon_int16x8_t + high = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vandq_u16(shifted1, + mask12)); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ .low = low, .high = high }); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(a); +} + +inline size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, Eurydice_slice result) +{ + size_t sampled = (size_t)0U; + core_slice_iter_Chunks + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(core_slice___Slice_T___chunks(a, + (size_t)3U, + uint8_t, + core_slice_iter_Chunks), + core_slice_iter_Chunks, + core_slice_iter_Chunks); + while (true) + { + core_option_Option__Eurydice_slice_uint8_t + uu____0 = + core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next(&iter, + uint8_t, + core_option_Option__Eurydice_slice_uint8_t); + if (uu____0.tag == core_option_None) + { + break; + } + else + { + Eurydice_slice bytes = uu____0.f0; + int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____1; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) + { + uu____1 = sampled < (size_t)16U; + } + else + { + uu____1 = false; + } + if (uu____1) + { + int16_t uu____2 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____2; + sampled++; + } + bool uu____3; + if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) + { + uu____3 = sampled < (size_t)16U; + } + else + { + uu____3 = false; + } + if (uu____3) + { + int16_t uu____4 = d2; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____4; + sampled++; + } + } + } + return sampled; +} + +size_t +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + Eurydice_slice a, + Eurydice_slice out +) +{ + return libcrux_ml_kem_vector_neon_rej_sample(a, out); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self +) +{ + return self[0U]; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(void) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12(bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +shift_right___15int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + v.low = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, + v.low, + core_core_arch_arm_shared_neon_int16x8_t); + v.high = + libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, + v.high, + core_core_arch_arm_shared_neon_int16x8_t); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +shift_right___15int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + return shift_right___15int32_t(v); +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a +) +{ + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = shift_right___15int32_t0(a); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fm = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant(t, + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, + &fm); +} + +static inline void +serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[384U] +) +{ + uint8_t serialized[384U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)384U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof (uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[4U], + uint8_t ret[1536U] +) +{ + uint8_t out[1536U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1536U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)1536U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U], + Eurydice_slice seed_for_a, + uint8_t ret[1568U] +) +{ + uint8_t public_key_serialized[1568U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1568U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1536U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[4U]; + memcpy(uu____1, + t_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1568U, + public_key_serialized, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t(Eurydice_array_to_subslice_to((size_t)1568U, + public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[4U]; + memcpy(uu____0, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, + public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1568U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy(ret, + ret0, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +typedef struct Simd128Hash_s +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + shake128_state[2U]; +} +Simd128Hash; + +static inline Simd128Hash shake128_init_absorb___4size_t(uint8_t input[4U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, + uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = &state[1U]; + Eurydice_slice + uu____4 = Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____3, + uu____4, + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy(lit.shake128_state, + state, + (size_t)2U + * + sizeof ( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + )); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___4size_t(Simd128Hash *self, uint8_t ret[4U][504U]) +{ + uint8_t out[4U][504U] = { { 0U } }; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)4U, + out, + uint8_t [504U], + Eurydice_slice), + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = + core_slice___Slice_T___split_at_mut(out123, + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = + core_slice___Slice_T___split_at_mut(out23, + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = self->shake128_state; + Eurydice_slice + uu____4 = + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____3, + uu____4, + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____5 = &self->shake128_state[1U]; + Eurydice_slice + uu____6 = + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____5, + uu____6, + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void shake128_squeeze_block___4size_t(Simd128Hash *self, uint8_t ret[4U][168U]) +{ + uint8_t out[4U][168U] = { { 0U } }; + uint8_t out0[168U] = { 0U }; + uint8_t out1[168U] = { 0U }; + uint8_t out2[168U] = { 0U }; + uint8_t out3[168U] = { 0U }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, + uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &self->shake128_state[1U]; + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____2, + uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof (uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof (uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof (uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____7[168U]; + memcpy(uu____7, out3, (size_t)168U * sizeof (uint8_t)); + memcpy(out[3U], uu____7, (size_t)168U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_slice a) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array(Eurydice_slice_subslice(a, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + size_t sampled_coefficients[4U] = { 0U }; + int16_t out[4U][272U] = { { 0U } }; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof (uint8_t [34U])); + Simd128Hash xof_state = shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U][4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0(A_transpose[i]);); + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[4U][34U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[4U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) +{ + uint8_t out[4U][128U] = { { 0U } }; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)4U, + out, + uint8_t [128U], + Eurydice_slice), + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = + core_slice___Slice_T___split_at_mut(out123, + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = + core_slice___Slice_T___split_at_mut(out23, + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + Eurydice_slice + uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____4 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____5 = + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____3, + uu____4, + uu____5, + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice)); + Eurydice_slice + uu____6 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____7 = Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____8 = + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____6, + uu____7, + uu____8, + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice randomness +) +{ + int16_t sampled_i16s[256U] = { 0U }; + for + (size_t + i0 = (size_t)0U; + i0 + < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) + { + size_t chunk_number = i0; + Eurydice_slice + byte_chunk = + Eurydice_slice_subslice(randomness, + ( + (core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint32_t + uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t + uu____1 = + uu____0 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; + uint32_t + uu____2 = + uu____1 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; + uint32_t + random_bits_as_u32 = + uu____2 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) + { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return + from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_slice((size_t)256U, + sampled_i16s, + int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice randomness +) +{ + int16_t sampled_i16s[256U] = { 0U }; + for + (size_t + i0 = (size_t)0U; + i0 + < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) + { + size_t chunk_number = i0; + Eurydice_slice + byte_chunk = + Eurydice_slice_subslice(randomness, + ( + (core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint32_t + uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t + uu____1 = + uu____0 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; + uint32_t + random_bits_as_u24 = + uu____1 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) + { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t + outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + (int32_t)3) & 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return + from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_slice((size_t)256U, + sampled_i16s, + int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_slice randomness +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(randomness); + return uu____0; +} + +static inline void +ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) + { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant(re->coefficients[j + + step], + (int16_t)-1600); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(re->coefficients[j], + &t); + re->coefficients[j + step] = uu____0; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(re->coefficients[j], + &t); + re->coefficients[j] = uu____1; + } +} + +typedef struct +__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s +{ + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector snd; +} +__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t fer +) +{ + return + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(v, + fer); +} + +static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, + int16_t zeta_r +) +{ + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t = montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(b, zeta_r); + b = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(a, + &t); + a = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, + &t); + return + ( + (__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .fst = a, + .snd = b + } + ); +} + +static inline void +ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + size_t layer +) +{ + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) + { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) + { + size_t j = i; + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[j], + re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void +ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void +ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)3U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); + size_t zeta_i = (size_t)1U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[4U]; + memcpy(uu____2, + re_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + out = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply(&self->coefficients[i0], + &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(v, + LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(self->coefficients[j]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___4size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[4U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____3, + domain_separator).fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[4U]; + memcpy(uu____4, + t_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[4U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof (uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof (uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[3168U] +) +{ + uint8_t out[3168U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)3168U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___4size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)3168U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof (uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t(uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[4U]; + memcpy(uu____2, + error_1, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + uint8_t dummy[128U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)3U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, + int16_t zeta_r +) +{ + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + a_minus_b = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(b, + &a); + a = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, + &b)); + b = + montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_minus_b, + zeta_r); + return + ( + (__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .fst = a, + .snd = b + } + ); +} + +static inline void +invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + size_t layer +) +{ + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) + { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) + { + size_t j = i; + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[j], + re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(self->coefficients[j], + (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, + &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_1[i1]); + } + memcpy(ret, + result, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + uint8_t serialized[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_compressed = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1(Eurydice_array_to_subslice((size_t)32U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(result.coefficients[i0], + (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + tmp = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], + &message->coefficients[i0]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + tmp0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, + &tmp); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, + message, + result); + return result; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t + compressed = + libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)10, + v, + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t + compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t + compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, + compressed1, + core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___10int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + core_core_arch_arm_shared_neon_int16x8_t + mask = + libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)10)); + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___10int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___10int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___10int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___10int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t + low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t + high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___10int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + return compress___10int32_t(v); +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U] +) +{ + uint8_t serialized[352U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)352U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t + compressed = + libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)11, + v, + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t + compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t + compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, + compressed1, + core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___11int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + core_core_arch_arm_shared_neon_int16x8_t + mask = + libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)11)); + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___11int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___11int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___11int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___11int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t + low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t + high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___11int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + return compress___11int32_t(v); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U] +) +{ + uint8_t serialized[352U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)352U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U] +) +{ + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t(re, + uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof (uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[4U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t + compressed = + libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)4, + v, + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t + compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t + compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, + compressed1, + core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___4int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + core_core_arch_arm_shared_neon_int16x8_t + mask = + libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)4)); + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___4int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___4int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___4int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___4int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t + low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t + high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___4int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + return compress___4int32_t(v); +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice serialized +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + compress___4int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t + compressed = + libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)5, + v, + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t + compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t + compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, + compressed1, + core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___5int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + core_core_arch_arm_shared_neon_int16x8_t + mask = + libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)5)); + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___5int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___5int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___5int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___5int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t + low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t + high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___5int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) +{ + return compress___5int32_t(v); +} + +static inline void +compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice serialized +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficients = + compress___5int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5(coefficients, + bytes); + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice out +) +{ + compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[1568U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t(Eurydice_slice_subslice_to(public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[4U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[4U]; + memcpy(error_1, + uu____3.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___4size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[1568U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[4U]; + memcpy(uu____5, + u, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t(uu____5, + Eurydice_array_to_subslice((size_t)1568U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1408U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, + ciphertext, + (size_t)1408U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___4size_t(Eurydice_array_to_slice((size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t + coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)10 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32(v, + (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)10, + decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___10int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___10int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___10int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___10int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___10int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___10int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return decompress_ciphertext_coefficient___10int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10(bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = decompress_ciphertext_coefficient___10int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t + coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)11 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32(v, + (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)11, + decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___11int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___11int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___11int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___11int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___11int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___11int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return decompress_ciphertext_coefficient___11int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11(bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = decompress_ciphertext_coefficient___11int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1568U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)1568U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t + coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)4 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32(v, + (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, + decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___4int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___4int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___4int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___4int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___4int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___4int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return decompress_ciphertext_coefficient___4int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4(bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = decompress_ciphertext_coefficient___4int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) +{ + core_core_arch_arm_shared_neon_uint32x4_t + coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)5 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32(v, + (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t + decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)5, + decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___5int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + core_core_arch_arm_shared_neon_uint32x4_t + mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t + low00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + low10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t + high00 = + libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + mask16); + core_core_arch_arm_shared_neon_uint32x4_t + high10 = + libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___5int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___5int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___5int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___5int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t + uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t + uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = + libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___5int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +) +{ + return decompress_ciphertext_coefficient___5int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5(bytes); + re.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12(bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + b +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(b.coefficients[i0], + (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(self->coefficients[i0], + &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); + return result; +} + +static inline void +compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + uint8_t ret[32U] +) +{ + uint8_t serialized[32U] = { 0U }; + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient_compressed = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1(coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1(coefficient_compressed, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)32U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *);); + memcpy(ret, serialized, (size_t)32U * sizeof (uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t(Eurydice_array_to_subslice_from((size_t)1568U, + ciphertext, + (size_t)1408U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + uint8_t dummy[32U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)3168U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)1536U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)1568U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)1600U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___4size_t_32size_t(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t(uu____7, + Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[3U], + uint8_t ret[1152U] +) +{ + uint8_t out[1152U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1152U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)1152U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U], + Eurydice_slice seed_for_a, + uint8_t ret[1184U] +) +{ + uint8_t public_key_serialized[1184U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1184U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1152U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[3U]; + memcpy(uu____1, + t_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1184U, + public_key_serialized, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t(Eurydice_array_to_subslice_to((size_t)1184U, + public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[3U]; + memcpy(uu____0, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, + public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1184U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy(ret, + ret0, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline Simd128Hash shake128_init_absorb___3size_t(uint8_t input[3U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, + uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = &state[1U]; + Eurydice_slice + uu____4 = Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____3, + uu____4, + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy(lit.shake128_state, + state, + (size_t)2U + * + sizeof ( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + )); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___3size_t(Simd128Hash *self, uint8_t ret[3U][504U]) +{ + uint8_t out[3U][504U] = { { 0U } }; + uint8_t extra[504U] = { 0U }; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)3U, + out, + uint8_t [504U], + Eurydice_slice), + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = + core_slice___Slice_T___split_at_mut(out12, + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = self->shake128_state; + Eurydice_slice + uu____3 = + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____2, + uu____3, + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____4 = &self->shake128_state[1U]; + Eurydice_slice + uu____5 = + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____4, + uu____5, + Eurydice_array_to_slice((size_t)504U, extra, uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void shake128_squeeze_block___3size_t(Simd128Hash *self, uint8_t ret[3U][168U]) +{ + uint8_t out[3U][168U] = { { 0U } }; + uint8_t out0[168U] = { 0U }; + uint8_t out1[168U] = { 0U }; + uint8_t out2[168U] = { 0U }; + uint8_t out3[168U] = { 0U }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, + uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &self->shake128_state[1U]; + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____2, + uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof (uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof (uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof (uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + size_t sampled_coefficients[3U] = { 0U }; + int16_t out[3U][272U] = { { 0U } }; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof (uint8_t [34U])); + Simd128Hash xof_state = shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U][3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0(A_transpose[i]);); + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[3U][34U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[3U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) +{ + uint8_t out[3U][128U] = { { 0U } }; + uint8_t extra[128U] = { 0U }; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)3U, + out, + uint8_t [128U], + Eurydice_slice), + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = + core_slice___Slice_T___split_at_mut(out12, + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____3 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____4 = + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____2, + uu____3, + uu____4, + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice)); + Eurydice_slice + uu____5 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____6 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____7 = + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____5, + uu____6, + uu____7, + Eurydice_array_to_slice((size_t)128U, extra, uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[3U]; + memcpy(uu____2, + re_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[3U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____3, + domain_separator).fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[3U]; + memcpy(uu____4, + t_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[3U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof (uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof (uint8_t)); + return lit; +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[2400U] +) +{ + uint8_t out[2400U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)2400U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)2400U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof (uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t(uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[3U]; + memcpy(uu____2, + error_1, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + uint8_t dummy[128U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, + &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_1[i1]); + } + memcpy(ret, + result, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, + message, + result); + return result; +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U] +) +{ + uint8_t serialized[320U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)320U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U] +) +{ + uint8_t serialized[320U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + coefficient = + compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)320U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U] +) +{ + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t(re, + uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof (uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[3U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice out +) +{ + compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[1088U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t(Eurydice_slice_subslice_to(public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[3U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[3U]; + memcpy(error_1, + uu____3.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[1088U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[3U]; + memcpy(uu____5, + u, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t(uu____5, + Eurydice_array_to_subslice((size_t)1088U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)960U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, + ciphertext, + (size_t)960U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___3size_t(Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1088U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)1088U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(Eurydice_array_to_subslice_from((size_t)1088U, + ciphertext, + (size_t)960U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + uint8_t dummy[32U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)2400U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)1152U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)1184U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)1120U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t(uu____7, + Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[2U], + uint8_t ret[768U] +) +{ + uint8_t out[768U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)768U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)768U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U], + Eurydice_slice seed_for_a, + uint8_t ret[800U] +) +{ + uint8_t public_key_serialized[800U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)800U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)768U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[2U]; + memcpy(uu____1, + t_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)800U, + public_key_serialized, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t(Eurydice_array_to_subslice_to((size_t)800U, + public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[2U]; + memcpy(uu____0, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)800U, + public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)800U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy(ret, + ret0, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline Simd128Hash shake128_init_absorb___2size_t(uint8_t input[2U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, + uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy(lit.shake128_state, + state, + (size_t)2U + * + sizeof ( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + )); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___2size_t(Simd128Hash *self, uint8_t ret[2U][504U]) +{ + uint8_t out[2U][504U] = { { 0U } }; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, + out, + uint8_t [504U], + Eurydice_slice), + (size_t)1U, + uint8_t [504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = self->shake128_state; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____1, + uu____2, + Eurydice_array_to_slice((size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), + uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( + uint8_t randomness[2U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void shake128_squeeze_block___2size_t(Simd128Hash *self, uint8_t ret[2U][168U]) +{ + uint8_t out[2U][168U] = { { 0U } }; + uint8_t out0[168U] = { 0U }; + uint8_t out1[168U] = { 0U }; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, + uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + uint8_t uu____2[168U]; + memcpy(uu____2, out0, (size_t)168U * sizeof (uint8_t)); + memcpy(out[0U], uu____2, (size_t)168U * sizeof (uint8_t)); + uint8_t uu____3[168U]; + memcpy(uu____3, out1, (size_t)168U * sizeof (uint8_t)); + memcpy(out[1U], uu____3, (size_t)168U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( + uint8_t randomness[2U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + size_t sampled_coefficients[2U] = { 0U }; + int16_t out[2U][272U] = { { 0U } }; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof (uint8_t [34U])); + Simd128Hash xof_state = shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U][2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0(A_transpose[i]);); + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[2U][34U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[2U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) +{ + uint8_t out[2U][192U] = { { 0U } }; + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, + out, + uint8_t [192U], + Eurydice_slice), + (size_t)1U, + uint8_t [192U], + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____3 = + Eurydice_array_to_slice((size_t)192U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [192U], uint8_t (*)[192U], uint8_t [192U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____1, + uu____2, + uu____3, + Eurydice_array_to_slice((size_t)192U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [192U], uint8_t (*)[192U], uint8_t [192U]), + uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [192U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + Eurydice_slice randomness +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(Eurydice_array_to_slice((size_t)192U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[2U]; + memcpy(uu____2, + re_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___2size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[2U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____3, + domain_separator).fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[2U]; + memcpy(uu____4, + t_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[2U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof (uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof (uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof (uint8_t)); + return lit; +} + +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[1632U] +) +{ + uint8_t out[1632U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)1632U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___2size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)1632U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof (uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t(uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) +{ + uint8_t out[2U][128U] = { { 0U } }; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = + core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, + out, + uint8_t [128U], + Eurydice_slice), + (size_t)1U, + uint8_t [128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice + uu____3 = + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____1, + uu____2, + uu____3, + Eurydice_array_to_slice((size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), + uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[2U]; + memcpy(uu____2, + error_1, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___2size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + uint8_t dummy[128U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice + uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + (*a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, + &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], + &error_1[i1]); + } + memcpy(ret, + result, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, + message, + result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[2U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[768U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t(Eurydice_slice_subslice_to(public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[2U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[2U]; + memcpy(error_1, + uu____3.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___2size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[768U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[2U]; + memcpy(uu____5, + u, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t(uu____5, + Eurydice_array_to_subslice((size_t)768U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)640U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)768U, + ciphertext, + (size_t)640U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___2size_t(Eurydice_array_to_slice((size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)768U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)768U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result, + &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(Eurydice_array_to_subslice_from((size_t)768U, + ciphertext, + (size_t)640U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + uint8_t dummy[32U] = { 0U }; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256(uu____0, + uu____1, + uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)1632U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)768U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)800U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)800U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___2size_t_32size_t(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t(uu____7, + Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/libcrux_mlkem_neon.h new file mode 100644 index 000000000..55e374569 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.h @@ -0,0 +1,418 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem_neon_H +#define __libcrux_mlkem_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_sha3_neon.h" +#include "libcrux_mlkem_portable.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +typedef struct libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s +{ + core_core_arch_arm_shared_neon_int16x8_t low; + core_core_arch_arm_shared_neon_int16x8_t high; +} +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ZERO(void); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( + void +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( + Eurydice_slice array +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +#define LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER ((int16_t)20159) + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t low, + core_core_arch_arm_shared_neon_int16x8_t high +); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v +); + +int16_t +libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits(int16_t coefficient_bits); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + core_core_arch_arm_shared_neon_int16x8_t c +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta1, + int16_t zeta2 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta1, + int16_t zeta2 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t zeta +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + int16_t zeta +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3, + int16_t zeta4 +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[2U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[2U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[8U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[8U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + int16_t ret[16U] +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[10U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[10U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[20U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[20U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[22U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[22U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_neon_simd128ops_serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, + uint8_t ret[24U] +); + +void +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + uint8_t ret[24U] +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + Eurydice_slice a +); + +size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, Eurydice_slice result); + +size_t +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + Eurydice_slice a, + Eurydice_slice out +); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self +); + +typedef struct +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s +{ libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients[16U]; } +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c new file mode 100644 index 000000000..9b58ec04e --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -0,0 +1,8858 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_mlkem_portable.h" + +#include "internal/libcrux_sha3_internal.h" +#include "internal/libcrux_core.h" + +const +int16_t +libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = + { + (int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, (int16_t)1493, (int16_t)1422, + (int16_t)287, (int16_t)202, (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, + (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, (int16_t)573, (int16_t)-1325, + (int16_t)264, (int16_t)383, (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, + (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, (int16_t)-1542, (int16_t)411, + (int16_t)-205, (int16_t)-1571, (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, + (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, (int16_t)516, (int16_t)-8, + (int16_t)-320, (int16_t)-666, (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, + (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, (int16_t)107, (int16_t)-1421, + (int16_t)-247, (int16_t)-951, (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, + (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, (int16_t)-1103, (int16_t)430, + (int16_t)555, (int16_t)843, (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, + (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, (int16_t)-291, (int16_t)-460, + (int16_t)1574, (int16_t)1653, (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, + (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, (int16_t)-1590, (int16_t)644, + (int16_t)-872, (int16_t)349, (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, + (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, (int16_t)1322, (int16_t)-1285, + (int16_t)-1465, (int16_t)384, (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, + (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, (int16_t)-1185, (int16_t)-1530, + (int16_t)-1278, (int16_t)794, (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, + (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, (int16_t)958, (int16_t)-1460, + (int16_t)1522, (int16_t)1628 + }; + +inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero(void) +{ + libcrux_ml_kem_vector_portable_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO( + void +) +{ + return libcrux_ml_kem_vector_zero(); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) +{ + libcrux_ml_kem_vector_portable_PortableVector lit; + int16_t ret[16U]; + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(array, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + int16_t [16U], + void *); + core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError(dst, + ret); + memcpy(lit.elements, ret, (size_t)16U * sizeof (int16_t)); + return lit; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( + Eurydice_slice array +) +{ + return libcrux_ml_kem_vector_from_i16_array(array); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; + } + return lhs; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +) +{ + return libcrux_ml_kem_vector_add(lhs, rhs); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; + } + return lhs; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +) +{ + return libcrux_ml_kem_vector_sub(lhs, rhs); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] * c; + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +) +{ + return libcrux_ml_kem_vector_multiply_by_constant(v, c); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] & c; + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +) +{ + return libcrux_ml_kem_vector_bitwise_and_with_constant(v, c); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_cond_subtract_3329(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + if (v.elements[i0] >= (int16_t)3329) + { + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] - (int16_t)3329; + } + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v +) +{ + return libcrux_ml_kem_vector_cond_subtract_3329(v); +} + +int16_t libcrux_ml_kem_vector_barrett_reduce_element(int16_t value) +{ + int32_t + t = + (int32_t)value + * LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER + + (LIBCRUX_ML_KEM_VECTOR_BARRETT_R >> 1U); + int16_t quotient = (int16_t)(t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT); + return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_barrett_reduce(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v +) +{ + return libcrux_ml_kem_vector_barrett_reduce(v); +} + +int16_t libcrux_ml_kem_vector_montgomery_reduce_element(int32_t value) +{ + int32_t + k = + (int32_t)(int16_t)value + * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; + int32_t + k_times_modulus = (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int16_t c = (int16_t)(k_times_modulus >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); + int16_t value_high = (int16_t)(value >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); + return value_high - c; +} + +inline int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(int16_t fe, int16_t fer) +{ + return libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)fe * (int32_t)fer); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[i0], c); + v.elements[i0] = uu____0; + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t r +) +{ + return libcrux_ml_kem_vector_montgomery_multiply_by_constant(v, r); +} + +uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe) +{ + int16_t shifted = (int16_t)1664 - (int16_t)fe; + int16_t mask = shifted >> 15U; + int16_t shifted_to_positive = mask ^ shifted; + int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; + return (uint8_t)(shifted_positive_in_range >> 15U & (int16_t)1); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress_1(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + uint8_t uu____0 = libcrux_ml_kem_vector_compress_message_coefficient((uint16_t)v.elements[i0]); + v.elements[i0] = (int16_t)uu____0; + } + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( + libcrux_ml_kem_vector_portable_PortableVector v +) +{ + return libcrux_ml_kem_vector_compress_1(v); +} + +inline uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits(uint8_t n, uint32_t value) +{ + return value & ((1U << (uint32_t)n) - 1U); +} + +int16_t +libcrux_ml_kem_vector_compress_ciphertext_coefficient(uint8_t coefficient_bits, uint16_t fe) +{ + uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; + compressed = compressed + 1664ULL; + compressed = compressed * 10321340ULL; + compressed = compressed >> 35U; + return + (int16_t)libcrux_ml_kem_vector_get_n_least_significant_bits(coefficient_bits, + (uint32_t)compressed); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[2U], zeta0); + v.elements[2U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[3U], zeta0); + v.elements[3U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[6U], zeta1); + v.elements[6U] = v.elements[4U] - t1; + v.elements[4U] = v.elements[4U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[7U], zeta1); + v.elements[7U] = v.elements[5U] - t2; + v.elements[5U] = v.elements[5U] + t2; + int16_t + t3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)2U], + zeta2); + v.elements[(size_t)8U + (size_t)2U] = v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t + t4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)3U], + zeta2); + v.elements[(size_t)8U + (size_t)3U] = v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t + t5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], + zeta3); + v.elements[(size_t)8U + (size_t)6U] = v.elements[(size_t)8U + (size_t)4U] - t5; + v.elements[(size_t)8U + (size_t)4U] = v.elements[(size_t)8U + (size_t)4U] + t5; + int16_t + t6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], + zeta3); + v.elements[(size_t)8U + (size_t)7U] = v.elements[(size_t)8U + (size_t)5U] - t6; + v.elements[(size_t)8U + (size_t)5U] = v.elements[(size_t)8U + (size_t)5U] + t6; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + return libcrux_ml_kem_vector_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1 +) +{ + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[4U], zeta0); + v.elements[4U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[5U], zeta0); + v.elements[5U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[6U], zeta0); + v.elements[6U] = v.elements[2U] - t1; + v.elements[2U] = v.elements[2U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[7U], zeta0); + v.elements[7U] = v.elements[3U] - t2; + v.elements[3U] = v.elements[3U] + t2; + int16_t + t3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)4U], + zeta1); + v.elements[(size_t)8U + (size_t)4U] = v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t + t4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)5U], + zeta1); + v.elements[(size_t)8U + (size_t)5U] = v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t + t5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], + zeta1); + v.elements[(size_t)8U + (size_t)6U] = v.elements[(size_t)8U + (size_t)2U] - t5; + v.elements[(size_t)8U + (size_t)2U] = v.elements[(size_t)8U + (size_t)2U] + t5; + int16_t + t6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], + zeta1); + v.elements[(size_t)8U + (size_t)7U] = v.elements[(size_t)8U + (size_t)3U] - t6; + v.elements[(size_t)8U + (size_t)3U] = v.elements[(size_t)8U + (size_t)3U] + t6; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1 +) +{ + return libcrux_ml_kem_vector_ntt_layer_2_step(a, zeta0, zeta1); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta +) +{ + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[8U], zeta); + v.elements[8U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[9U], zeta); + v.elements[9U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[10U], zeta); + v.elements[10U] = v.elements[2U] - t1; + v.elements[2U] = v.elements[2U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[11U], zeta); + v.elements[11U] = v.elements[3U] - t2; + v.elements[3U] = v.elements[3U] + t2; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[12U], zeta); + v.elements[12U] = v.elements[4U] - t3; + v.elements[4U] = v.elements[4U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[13U], zeta); + v.elements[13U] = v.elements[5U] - t4; + v.elements[5U] = v.elements[5U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[14U], zeta); + v.elements[14U] = v.elements[6U] - t5; + v.elements[6U] = v.elements[6U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[15U], zeta); + v.elements[15U] = v.elements[7U] - t6; + v.elements[7U] = v.elements[7U] + t6; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta +) +{ + return libcrux_ml_kem_vector_ntt_layer_3_step(a, zeta); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + int16_t a_minus_b = v.elements[2U] - v.elements[0U]; + int16_t + uu____0 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[0U] + v.elements[2U]); + v.elements[0U] = uu____0; + int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + v.elements[2U] = uu____1; + int16_t a_minus_b0 = v.elements[3U] - v.elements[1U]; + int16_t + uu____2 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[1U] + v.elements[3U]); + v.elements[1U] = uu____2; + int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + v.elements[3U] = uu____3; + int16_t a_minus_b1 = v.elements[6U] - v.elements[4U]; + int16_t + uu____4 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[4U] + v.elements[6U]); + v.elements[4U] = uu____4; + int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta1); + v.elements[6U] = uu____5; + int16_t a_minus_b2 = v.elements[7U] - v.elements[5U]; + int16_t + uu____6 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[5U] + v.elements[7U]); + v.elements[5U] = uu____6; + int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta1); + v.elements[7U] = uu____7; + int16_t a_minus_b3 = v.elements[(size_t)8U + (size_t)2U] - v.elements[(size_t)8U + (size_t)0U]; + int16_t + uu____8 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U + + (size_t)0U] + + v.elements[(size_t)8U + (size_t)2U]); + v.elements[(size_t)8U + (size_t)0U] = uu____8; + int16_t uu____9 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta2); + v.elements[(size_t)8U + (size_t)2U] = uu____9; + int16_t a_minus_b4 = v.elements[(size_t)8U + (size_t)3U] - v.elements[(size_t)8U + (size_t)1U]; + int16_t + uu____10 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U + + (size_t)1U] + + v.elements[(size_t)8U + (size_t)3U]); + v.elements[(size_t)8U + (size_t)1U] = uu____10; + int16_t uu____11 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta2); + v.elements[(size_t)8U + (size_t)3U] = uu____11; + int16_t a_minus_b5 = v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)4U]; + int16_t + uu____12 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U + + (size_t)4U] + + v.elements[(size_t)8U + (size_t)6U]); + v.elements[(size_t)8U + (size_t)4U] = uu____12; + int16_t uu____13 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta3); + v.elements[(size_t)8U + (size_t)6U] = uu____13; + int16_t a_minus_b6 = v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)5U]; + int16_t + uu____14 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U + + (size_t)5U] + + v.elements[(size_t)8U + (size_t)7U]); + v.elements[(size_t)8U + (size_t)5U] = uu____14; + int16_t uu____15 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta3); + v.elements[(size_t)8U + (size_t)7U] = uu____15; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + return libcrux_ml_kem_vector_inv_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1 +) +{ + int16_t a_minus_b = v.elements[4U] - v.elements[0U]; + v.elements[0U] = v.elements[0U] + v.elements[4U]; + int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + v.elements[4U] = uu____0; + int16_t a_minus_b0 = v.elements[5U] - v.elements[1U]; + v.elements[1U] = v.elements[1U] + v.elements[5U]; + int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + v.elements[5U] = uu____1; + int16_t a_minus_b1 = v.elements[6U] - v.elements[2U]; + v.elements[2U] = v.elements[2U] + v.elements[6U]; + int16_t uu____2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta0); + v.elements[6U] = uu____2; + int16_t a_minus_b2 = v.elements[7U] - v.elements[3U]; + v.elements[3U] = v.elements[3U] + v.elements[7U]; + int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta0); + v.elements[7U] = uu____3; + int16_t a_minus_b3 = v.elements[(size_t)8U + (size_t)4U] - v.elements[(size_t)8U + (size_t)0U]; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + + (size_t)0U] + + v.elements[(size_t)8U + (size_t)4U]; + int16_t uu____4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta1); + v.elements[(size_t)8U + (size_t)4U] = uu____4; + int16_t a_minus_b4 = v.elements[(size_t)8U + (size_t)5U] - v.elements[(size_t)8U + (size_t)1U]; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + + (size_t)1U] + + v.elements[(size_t)8U + (size_t)5U]; + int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta1); + v.elements[(size_t)8U + (size_t)5U] = uu____5; + int16_t a_minus_b5 = v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)2U]; + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + + (size_t)2U] + + v.elements[(size_t)8U + (size_t)6U]; + int16_t uu____6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta1); + v.elements[(size_t)8U + (size_t)6U] = uu____6; + int16_t a_minus_b6 = v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)3U]; + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + + (size_t)3U] + + v.elements[(size_t)8U + (size_t)7U]; + int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta1); + v.elements[(size_t)8U + (size_t)7U] = uu____7; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1 +) +{ + return libcrux_ml_kem_vector_inv_ntt_layer_2_step(a, zeta0, zeta1); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta +) +{ + int16_t a_minus_b = v.elements[8U] - v.elements[0U]; + v.elements[0U] = v.elements[0U] + v.elements[8U]; + int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta); + v.elements[8U] = uu____0; + int16_t a_minus_b0 = v.elements[9U] - v.elements[1U]; + v.elements[1U] = v.elements[1U] + v.elements[9U]; + int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta); + v.elements[9U] = uu____1; + int16_t a_minus_b1 = v.elements[10U] - v.elements[2U]; + v.elements[2U] = v.elements[2U] + v.elements[10U]; + int16_t uu____2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta); + v.elements[10U] = uu____2; + int16_t a_minus_b2 = v.elements[11U] - v.elements[3U]; + v.elements[3U] = v.elements[3U] + v.elements[11U]; + int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta); + v.elements[11U] = uu____3; + int16_t a_minus_b3 = v.elements[12U] - v.elements[4U]; + v.elements[4U] = v.elements[4U] + v.elements[12U]; + int16_t uu____4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta); + v.elements[12U] = uu____4; + int16_t a_minus_b4 = v.elements[13U] - v.elements[5U]; + v.elements[5U] = v.elements[5U] + v.elements[13U]; + int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta); + v.elements[13U] = uu____5; + int16_t a_minus_b5 = v.elements[14U] - v.elements[6U]; + v.elements[6U] = v.elements[6U] + v.elements[14U]; + int16_t uu____6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta); + v.elements[14U] = uu____6; + int16_t a_minus_b6 = v.elements[15U] - v.elements[7U]; + v.elements[7U] = v.elements[7U] + v.elements[15U]; + int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta); + v.elements[15U] = uu____7; + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta +) +{ + return libcrux_ml_kem_vector_inv_ntt_layer_3_step(a, zeta); +} + +inline K___int16_t_int16_t +libcrux_ml_kem_vector_ntt_multiply_binomials( + K___int16_t_int16_t _, + K___int16_t_int16_t _0, + int16_t zeta +) +{ + int16_t a0 = _.fst; + int16_t a1 = _.snd; + int16_t b0 = _0.fst; + int16_t b1 = _0.snd; + int32_t uu____0 = (int32_t)a0 * (int32_t)b0; + int16_t + uu____1 = + libcrux_ml_kem_vector_montgomery_reduce_element(uu____0 + + + (int32_t)libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)a1 * (int32_t)b1) + * (int32_t)zeta); + return + ( + (K___int16_t_int16_t){ + .fst = uu____1, + .snd = libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)a0 + * (int32_t)b1 + + (int32_t)a1 * (int32_t)b0) + } + ); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + libcrux_ml_kem_vector_portable_PortableVector out = libcrux_ml_kem_vector_zero(); + K___int16_t_int16_t lit0; + lit0.fst = lhs->elements[0U]; + lit0.snd = lhs->elements[1U]; + K___int16_t_int16_t lit1; + lit1.fst = rhs->elements[0U]; + lit1.snd = rhs->elements[1U]; + K___int16_t_int16_t product = libcrux_ml_kem_vector_ntt_multiply_binomials(lit0, lit1, zeta0); + out.elements[0U] = product.fst; + out.elements[1U] = product.snd; + K___int16_t_int16_t lit2; + lit2.fst = lhs->elements[2U]; + lit2.snd = lhs->elements[3U]; + K___int16_t_int16_t lit3; + lit3.fst = rhs->elements[2U]; + lit3.snd = rhs->elements[3U]; + K___int16_t_int16_t + product0 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit2, lit3, -zeta0); + out.elements[2U] = product0.fst; + out.elements[3U] = product0.snd; + K___int16_t_int16_t lit4; + lit4.fst = lhs->elements[4U]; + lit4.snd = lhs->elements[5U]; + K___int16_t_int16_t lit5; + lit5.fst = rhs->elements[4U]; + lit5.snd = rhs->elements[5U]; + K___int16_t_int16_t product1 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit4, lit5, zeta1); + out.elements[4U] = product1.fst; + out.elements[5U] = product1.snd; + K___int16_t_int16_t lit6; + lit6.fst = lhs->elements[6U]; + lit6.snd = lhs->elements[7U]; + K___int16_t_int16_t lit7; + lit7.fst = rhs->elements[6U]; + lit7.snd = rhs->elements[7U]; + K___int16_t_int16_t + product2 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit6, lit7, -zeta1); + out.elements[6U] = product2.fst; + out.elements[7U] = product2.snd; + K___int16_t_int16_t lit8; + lit8.fst = lhs->elements[(size_t)8U + (size_t)0U]; + lit8.snd = lhs->elements[(size_t)8U + (size_t)1U]; + K___int16_t_int16_t lit9; + lit9.fst = rhs->elements[(size_t)8U + (size_t)0U]; + lit9.snd = rhs->elements[(size_t)8U + (size_t)1U]; + K___int16_t_int16_t product3 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit8, lit9, zeta2); + out.elements[(size_t)8U + (size_t)0U] = product3.fst; + out.elements[(size_t)8U + (size_t)1U] = product3.snd; + K___int16_t_int16_t lit10; + lit10.fst = lhs->elements[(size_t)8U + (size_t)2U]; + lit10.snd = lhs->elements[(size_t)8U + (size_t)3U]; + K___int16_t_int16_t lit11; + lit11.fst = rhs->elements[(size_t)8U + (size_t)2U]; + lit11.snd = rhs->elements[(size_t)8U + (size_t)3U]; + K___int16_t_int16_t + product4 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit10, lit11, -zeta2); + out.elements[(size_t)8U + (size_t)2U] = product4.fst; + out.elements[(size_t)8U + (size_t)3U] = product4.snd; + K___int16_t_int16_t lit12; + lit12.fst = lhs->elements[(size_t)8U + (size_t)4U]; + lit12.snd = lhs->elements[(size_t)8U + (size_t)5U]; + K___int16_t_int16_t lit13; + lit13.fst = rhs->elements[(size_t)8U + (size_t)4U]; + lit13.snd = rhs->elements[(size_t)8U + (size_t)5U]; + K___int16_t_int16_t + product5 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit12, lit13, zeta3); + out.elements[(size_t)8U + (size_t)4U] = product5.fst; + out.elements[(size_t)8U + (size_t)5U] = product5.snd; + K___int16_t_int16_t lit14; + lit14.fst = lhs->elements[(size_t)8U + (size_t)6U]; + lit14.snd = lhs->elements[(size_t)8U + (size_t)7U]; + K___int16_t_int16_t lit; + lit.fst = rhs->elements[(size_t)8U + (size_t)6U]; + lit.snd = rhs->elements[(size_t)8U + (size_t)7U]; + K___int16_t_int16_t + product6 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit14, lit, -zeta3); + out.elements[(size_t)8U + (size_t)6U] = product6.fst; + out.elements[(size_t)8U + (size_t)7U] = product6.snd; + return out; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +) +{ + return libcrux_ml_kem_vector_ntt_multiply(lhs, rhs, zeta0, zeta1, zeta2, zeta3); +} + +inline void +libcrux_ml_kem_vector_serialize_1( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[2U] +) +{ + uint8_t result[2U] = { 0U }; + KRML_MAYBE_FOR8(i, + (size_t)0U, + (size_t)8U, + (size_t)1U, + size_t i0 = i; + size_t uu____0 = (size_t)0U; + result[uu____0] = (uint32_t)result[uu____0] | (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;); + KRML_MAYBE_FOR8(i, + (size_t)8U, + (size_t)16U, + (size_t)1U, + size_t i0 = i; + size_t uu____1 = (size_t)1U; + result[uu____1] = + (uint32_t)result[uu____1] + | (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)(i0 - (size_t)8U);); + memcpy(ret, result, (size_t)2U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[2U] +) +{ + uint8_t ret0[2U]; + libcrux_ml_kem_vector_serialize_1(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v) +{ + libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); + KRML_MAYBE_FOR8(i, + (size_t)0U, + (size_t)8U, + (size_t)1U, + size_t i0 = i; + uint8_t *uu____0 = &Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = (int16_t)((uint32_t)uu____0[0U] >> (uint32_t)i0 & 1U);); + for (size_t i = (size_t)8U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + uint8_t *uu____1 = &Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = (int16_t)((uint32_t)uu____1[0U] >> (uint32_t)(i0 - (size_t)8U) & 1U); + } + return result; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_1(a); +} + +inline void +libcrux_ml_kem_vector_serialize_4( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[8U] +) +{ + uint8_t result[8U] = { 0U }; + result[0U] = (uint32_t)(uint8_t)v.elements[1U] << 4U | (uint32_t)(uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)v.elements[3U] << 4U | (uint32_t)(uint8_t)v.elements[2U]; + result[2U] = (uint32_t)(uint8_t)v.elements[5U] << 4U | (uint32_t)(uint8_t)v.elements[4U]; + result[3U] = (uint32_t)(uint8_t)v.elements[7U] << 4U | (uint32_t)(uint8_t)v.elements[6U]; + result[4U] = + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)1U] + << 4U + | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[5U] = + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)3U] + << 4U + | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)2U]; + result[6U] = + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)5U] + << 4U + | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)4U]; + result[7U] = + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)7U] + << 4U + | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)6U]; + memcpy(ret, result, (size_t)8U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[8U] +) +{ + uint8_t ret0[8U]; + libcrux_ml_kem_vector_serialize_4(a, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes) +{ + libcrux_ml_kem_vector_portable_PortableVector v = libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 15U); + uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[1U] = (int16_t)((uint32_t)uu____1[0U] >> 4U & 15U); + uint8_t *uu____2 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[2U] = (int16_t)((uint32_t)uu____2[0U] & 15U); + uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[3U] = (int16_t)((uint32_t)uu____3[0U] >> 4U & 15U); + uint8_t *uu____4 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[4U] = (int16_t)((uint32_t)uu____4[0U] & 15U); + uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[5U] = (int16_t)((uint32_t)uu____5[0U] >> 4U & 15U); + uint8_t *uu____6 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[6U] = (int16_t)((uint32_t)uu____6[0U] & 15U); + uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[7U] = (int16_t)((uint32_t)uu____7[0U] >> 4U & 15U); + uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[8U] = (int16_t)((uint32_t)uu____8[0U] & 15U); + uint8_t *uu____9 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[9U] = (int16_t)((uint32_t)uu____9[0U] >> 4U & 15U); + uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + v.elements[10U] = (int16_t)((uint32_t)uu____10[0U] & 15U); + uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + v.elements[11U] = (int16_t)((uint32_t)uu____11[0U] >> 4U & 15U); + uint8_t *uu____12 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + v.elements[12U] = (int16_t)((uint32_t)uu____12[0U] & 15U); + uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + v.elements[13U] = (int16_t)((uint32_t)uu____13[0U] >> 4U & 15U); + uint8_t *uu____14 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + v.elements[14U] = (int16_t)((uint32_t)uu____14[0U] & 15U); + uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + v.elements[15U] = (int16_t)((uint32_t)uu____15[0U] >> 4U & 15U); + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_4(a); +} + +inline void +libcrux_ml_kem_vector_serialize_5( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[10U] +) +{ + uint8_t result[10U] = { 0U }; + result[0U] = (uint8_t)((v.elements[1U] & (int16_t)7) << 5U | v.elements[0U]); + result[1U] = + (uint8_t)(((v.elements[3U] & (int16_t)1) << 7U | v.elements[2U] << 2U) | v.elements[1U] >> 3U); + result[2U] = (uint8_t)((v.elements[4U] & (int16_t)15) << 4U | v.elements[3U] >> 1U); + result[3U] = + (uint8_t)(((v.elements[6U] & (int16_t)3) << 6U | v.elements[5U] << 1U) | v.elements[4U] >> 4U); + result[4U] = (uint8_t)(v.elements[7U] << 3U | v.elements[6U] >> 2U); + result[5U] = + (uint8_t)((v.elements[(size_t)8U + (size_t)1U] & (int16_t)7) + << 5U + | v.elements[(size_t)8U + (size_t)0U]); + result[6U] = + (uint8_t)(((v.elements[(size_t)8U + (size_t)3U] & (int16_t)1) + << 7U + | v.elements[(size_t)8U + (size_t)2U] << 2U) + | v.elements[(size_t)8U + (size_t)1U] >> 3U); + result[7U] = + (uint8_t)((v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U + | v.elements[(size_t)8U + (size_t)3U] >> 1U); + result[8U] = + (uint8_t)(((v.elements[(size_t)8U + (size_t)6U] & (int16_t)3) + << 6U + | v.elements[(size_t)8U + (size_t)5U] << 1U) + | v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[9U] = + (uint8_t)(v.elements[(size_t)8U + + (size_t)7U] + << 3U + | v.elements[(size_t)8U + (size_t)6U] >> 2U); + memcpy(ret, result, (size_t)10U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[10U] +) +{ + uint8_t ret0[10U]; + libcrux_ml_kem_vector_serialize_5(a, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes) +{ + libcrux_ml_kem_vector_portable_PortableVector v = libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 31U); + uint8_t + uu____1 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & 3U) + << 3U; + uint8_t *uu____2 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[1U] = (int16_t)((uint32_t)uu____1 | (uint32_t)uu____2[0U] >> 5U); + uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[2U] = (int16_t)((uint32_t)uu____3[0U] >> 2U & 31U); + uint8_t + uu____4 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & 15U) + << 1U; + uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[3U] = (int16_t)((uint32_t)uu____4 | (uint32_t)uu____5[0U] >> 7U); + uint8_t + uu____6 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) & 1U) + << 4U; + uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[4U] = (int16_t)((uint32_t)uu____6 | (uint32_t)uu____7[0U] >> 4U); + uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[5U] = (int16_t)((uint32_t)uu____8[0U] >> 1U & 31U); + uint8_t + uu____9 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) & 7U) + << 2U; + uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[6U] = (int16_t)((uint32_t)uu____9 | (uint32_t)uu____10[0U] >> 6U); + uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[7U] = (int16_t)((uint32_t)uu____11[0U] >> 3U); + uint8_t + *uu____12 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[8U] = (int16_t)((uint32_t)uu____12[0U] & 31U); + uint8_t + uu____13 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t) + & 3U) + << 3U; + uint8_t + *uu____14 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[9U] = (int16_t)((uint32_t)uu____13 | (uint32_t)uu____14[0U] >> 5U); + uint8_t + *uu____15 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[10U] = (int16_t)((uint32_t)uu____15[0U] >> 2U & 31U); + uint8_t + uu____16 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, uint8_t *, uint8_t) + & 15U) + << 1U; + uint8_t + *uu____17 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[11U] = (int16_t)((uint32_t)uu____16 | (uint32_t)uu____17[0U] >> 7U); + uint8_t + uu____18 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t) + & 1U) + << 4U; + uint8_t + *uu____19 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[12U] = (int16_t)((uint32_t)uu____18 | (uint32_t)uu____19[0U] >> 4U); + uint8_t + *uu____20 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[13U] = (int16_t)((uint32_t)uu____20[0U] >> 1U & 31U); + uint8_t + uu____21 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, uint8_t *, uint8_t) + & 7U) + << 2U; + uint8_t + *uu____22 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[14U] = (int16_t)((uint32_t)uu____21 | (uint32_t)uu____22[0U] >> 6U); + uint8_t + *uu____23 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[15U] = (int16_t)((uint32_t)uu____23[0U] >> 3U); + return v; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_5(a); +} + +inline void +libcrux_ml_kem_vector_serialize_10( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[20U] +) +{ + uint8_t result[20U] = { 0U }; + result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); + result[1U] = + (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[0U] >> 8U & (int16_t)3); + result[2U] = + (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[1U] >> 6U & (int16_t)15); + result[3U] = + (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[2U] >> 4U & (int16_t)63); + result[4U] = (uint8_t)(v.elements[3U] >> 2U & (int16_t)255); + result[5U] = (uint8_t)(v.elements[4U] & (int16_t)255); + result[6U] = + (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[4U] >> 8U & (int16_t)3); + result[7U] = + (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[5U] >> 6U & (int16_t)15); + result[8U] = + (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[6U] >> 4U & (int16_t)63); + result[9U] = (uint8_t)(v.elements[7U] >> 2U & (int16_t)255); + result[10U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); + result[11U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U & (int16_t)3); + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 6U & (int16_t)15); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 4U & (int16_t)63); + result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 2U & (int16_t)255); + result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U & (int16_t)3); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 6U & (int16_t)15); + result[18U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 4U & (int16_t)63); + result[19U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 2U & (int16_t)255); + memcpy(ret, result, (size_t)20U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[20U] +) +{ + uint8_t ret0[20U]; + libcrux_ml_kem_vector_serialize_10(a, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes) +{ + libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); + int16_t + uu____0 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) + << 8U; + uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | ((int16_t)uu____1[0U] & (int16_t)255); + int16_t + uu____2 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) + << 6U; + uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 2U; + int16_t + uu____4 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) + << 4U; + uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____4 | (int16_t)uu____5[0U] >> 4U; + int16_t + uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) << 2U; + uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____6 | (int16_t)uu____7[0U] >> 6U; + int16_t + uu____8 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) + << 8U; + uint8_t *uu____9 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____8 | ((int16_t)uu____9[0U] & (int16_t)255); + int16_t + uu____10 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) + << 6U; + uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____10 | (int16_t)uu____11[0U] >> 2U; + int16_t + uu____12 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) + << 4U; + uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____12 | (int16_t)uu____13[0U] >> 4U; + int16_t + uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t) << 2U; + uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____14 | (int16_t)uu____15[0U] >> 6U; + int16_t + uu____16 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, uint8_t *, uint8_t) + & (int16_t)3) + << 8U; + uint8_t + *uu____17 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____16 | ((int16_t)uu____17[0U] & (int16_t)255); + int16_t + uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, uint8_t *, uint8_t) + & (int16_t)15) + << 6U; + uint8_t + *uu____19 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____18 | (int16_t)uu____19[0U] >> 2U; + int16_t + uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, uint8_t *, uint8_t) + & (int16_t)63) + << 4U; + uint8_t + *uu____21 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____20 | (int16_t)uu____21[0U] >> 4U; + int16_t + uu____22 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)4U, uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t + *uu____23 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____22 | (int16_t)uu____23[0U] >> 6U; + int16_t + uu____24 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, uint8_t *, uint8_t) + & (int16_t)3) + << 8U; + uint8_t + *uu____25 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____24 | ((int16_t)uu____25[0U] & (int16_t)255); + int16_t + uu____26 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, uint8_t *, uint8_t) + & (int16_t)15) + << 6U; + uint8_t + *uu____27 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____26 | (int16_t)uu____27[0U] >> 2U; + int16_t + uu____28 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, uint8_t *, uint8_t) + & (int16_t)63) + << 4U; + uint8_t + *uu____29 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____28 | (int16_t)uu____29[0U] >> 4U; + int16_t + uu____30 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)9U, uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t + *uu____31 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____30 | (int16_t)uu____31[0U] >> 6U; + return result; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_10(a); +} + +inline void +libcrux_ml_kem_vector_serialize_11( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[22U] +) +{ + uint8_t result[22U] = { 0U }; + result[0U] = (uint8_t)v.elements[0U]; + result[1U] = + (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) + << 3U + | (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = + (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); + result[4U] = + (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) + << 1U + | (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = + (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = + (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) + << 7U + | (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); + result[8U] = + (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = + (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) + << 5U + | (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[10U] = (uint8_t)(v.elements[7U] >> 3U); + result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + result[15U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + result[19U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + result[20U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U + | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[22U] +) +{ + uint8_t ret0[22U]; + libcrux_ml_kem_vector_serialize_11(a, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes) +{ + libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); + int16_t + uu____0 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & (int16_t)7) + << 8U; + uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; + int16_t + uu____2 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) + << 5U; + uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; + int16_t + uu____4 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) & (int16_t)1) + << 10U; + int16_t + uu____5 = + uu____4 + | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 2U; + uint8_t *uu____6 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; + int16_t + uu____7 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) + << 7U; + uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; + int16_t + uu____9 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t) & (int16_t)127) + << 4U; + uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; + int16_t + uu____11 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) + << 9U; + int16_t + uu____12 = + uu____11 + | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t) << 1U; + uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; + int16_t + uu____14 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t) & (int16_t)31) + << 6U; + uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; + int16_t + uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *, uint8_t) << 3U; + uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; + int16_t + uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, uint8_t *, uint8_t) + & (int16_t)7) + << 8U; + uint8_t + *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; + int16_t + uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, uint8_t *, uint8_t) + & (int16_t)63) + << 5U; + uint8_t + *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; + int16_t + uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, uint8_t *, uint8_t) + & (int16_t)1) + << 10U; + int16_t + uu____23 = + uu____22 + | + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t + *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; + int16_t + uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, uint8_t *, uint8_t) + & (int16_t)15) + << 7U; + uint8_t + *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; + int16_t + uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, uint8_t *, uint8_t) + & (int16_t)127) + << 4U; + uint8_t + *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; + int16_t + uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, uint8_t *, uint8_t) + & (int16_t)3) + << 9U; + int16_t + uu____30 = + uu____29 + | + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t + *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; + int16_t + uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, uint8_t *, uint8_t) + & (int16_t)31) + << 6U; + uint8_t + *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; + int16_t + uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, uint8_t *, uint8_t) + << 3U; + uint8_t + *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; + return result; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_11(a); +} + +inline void +libcrux_ml_kem_vector_serialize_12( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[24U] +) +{ + uint8_t result[24U] = { 0U }; + result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); + result[1U] = (uint8_t)(v.elements[0U] >> 8U | (v.elements[1U] & (int16_t)15) << 4U); + result[2U] = (uint8_t)(v.elements[1U] >> 4U & (int16_t)255); + result[3U] = (uint8_t)(v.elements[2U] & (int16_t)255); + result[4U] = (uint8_t)(v.elements[2U] >> 8U | (v.elements[3U] & (int16_t)15) << 4U); + result[5U] = (uint8_t)(v.elements[3U] >> 4U & (int16_t)255); + result[6U] = (uint8_t)(v.elements[4U] & (int16_t)255); + result[7U] = (uint8_t)(v.elements[4U] >> 8U | (v.elements[5U] & (int16_t)15) << 4U); + result[8U] = (uint8_t)(v.elements[5U] >> 4U & (int16_t)255); + result[9U] = (uint8_t)(v.elements[6U] & (int16_t)255); + result[10U] = (uint8_t)(v.elements[6U] >> 8U | (v.elements[7U] & (int16_t)15) << 4U); + result[11U] = (uint8_t)(v.elements[7U] >> 4U & (int16_t)255); + result[12U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); + result[13U] = + (uint8_t)(v.elements[(size_t)8U + + (size_t)0U] + >> 8U + | (v.elements[(size_t)8U + (size_t)1U] & (int16_t)15) << 4U); + result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 4U & (int16_t)255); + result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)255); + result[16U] = + (uint8_t)(v.elements[(size_t)8U + + (size_t)2U] + >> 8U + | (v.elements[(size_t)8U + (size_t)3U] & (int16_t)15) << 4U); + result[17U] = (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 4U & (int16_t)255); + result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); + result[19U] = + (uint8_t)(v.elements[(size_t)8U + + (size_t)4U] + >> 8U + | (v.elements[(size_t)8U + (size_t)5U] & (int16_t)15) << 4U); + result[20U] = (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 4U & (int16_t)255); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)255); + result[22U] = + (uint8_t)(v.elements[(size_t)8U + + (size_t)6U] + >> 8U + | (v.elements[(size_t)8U + (size_t)7U] & (int16_t)15) << 4U); + result[23U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 4U & (int16_t)255); + memcpy(ret, result, (size_t)24U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[24U] +) +{ + uint8_t ret0[24U]; + libcrux_ml_kem_vector_serialize_12(a, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof (uint8_t)); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) +{ + libcrux_ml_kem_vector_portable_PortableVector re = libcrux_ml_kem_vector_zero(); + int16_t byte0 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + int16_t byte1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t byte2 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t byte3 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + int16_t byte4 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + int16_t byte5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + int16_t byte6 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + int16_t byte7 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + int16_t byte8 = (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + int16_t byte9 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + int16_t + byte10 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *, uint8_t); + int16_t + byte11 = (int16_t)Eurydice_slice_index(bytes, (size_t)11U, uint8_t, uint8_t *, uint8_t); + re.elements[0U] = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); + re.elements[1U] = byte2 << 4U | (byte1 >> 4U & (int16_t)15); + re.elements[2U] = (byte4 & (int16_t)15) << 8U | (byte3 & (int16_t)255); + re.elements[3U] = byte5 << 4U | (byte4 >> 4U & (int16_t)15); + re.elements[4U] = (byte7 & (int16_t)15) << 8U | (byte6 & (int16_t)255); + re.elements[5U] = byte8 << 4U | (byte7 >> 4U & (int16_t)15); + re.elements[6U] = (byte10 & (int16_t)15) << 8U | (byte9 & (int16_t)255); + re.elements[7U] = byte11 << 4U | (byte10 >> 4U & (int16_t)15); + int16_t + byte12 = (int16_t)Eurydice_slice_index(bytes, (size_t)12U, uint8_t, uint8_t *, uint8_t); + int16_t + byte13 = (int16_t)Eurydice_slice_index(bytes, (size_t)13U, uint8_t, uint8_t *, uint8_t); + int16_t + byte14 = (int16_t)Eurydice_slice_index(bytes, (size_t)14U, uint8_t, uint8_t *, uint8_t); + int16_t + byte15 = (int16_t)Eurydice_slice_index(bytes, (size_t)15U, uint8_t, uint8_t *, uint8_t); + int16_t + byte16 = (int16_t)Eurydice_slice_index(bytes, (size_t)16U, uint8_t, uint8_t *, uint8_t); + int16_t + byte17 = (int16_t)Eurydice_slice_index(bytes, (size_t)17U, uint8_t, uint8_t *, uint8_t); + int16_t + byte18 = (int16_t)Eurydice_slice_index(bytes, (size_t)18U, uint8_t, uint8_t *, uint8_t); + int16_t + byte19 = (int16_t)Eurydice_slice_index(bytes, (size_t)19U, uint8_t, uint8_t *, uint8_t); + int16_t + byte20 = (int16_t)Eurydice_slice_index(bytes, (size_t)20U, uint8_t, uint8_t *, uint8_t); + int16_t + byte21 = (int16_t)Eurydice_slice_index(bytes, (size_t)21U, uint8_t, uint8_t *, uint8_t); + int16_t + byte22 = (int16_t)Eurydice_slice_index(bytes, (size_t)22U, uint8_t, uint8_t *, uint8_t); + int16_t + byte23 = (int16_t)Eurydice_slice_index(bytes, (size_t)23U, uint8_t, uint8_t *, uint8_t); + re.elements[8U] = (byte13 & (int16_t)15) << 8U | (byte12 & (int16_t)255); + re.elements[9U] = byte14 << 4U | (byte13 >> 4U & (int16_t)15); + re.elements[10U] = (byte16 & (int16_t)15) << 8U | (byte15 & (int16_t)255); + re.elements[11U] = byte17 << 4U | (byte16 >> 4U & (int16_t)15); + re.elements[12U] = (byte19 & (int16_t)15) << 8U | (byte18 & (int16_t)255); + re.elements[13U] = byte20 << 4U | (byte19 >> 4U & (int16_t)15); + re.elements[14U] = (byte22 & (int16_t)15) << 8U | (byte21 & (int16_t)255); + re.elements[15U] = byte23 << 4U | (byte22 >> 4U & (int16_t)15); + return re; +} + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + Eurydice_slice a +) +{ + return libcrux_ml_kem_vector_deserialize_12(a); +} + +inline size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, Eurydice_slice result) +{ + size_t sampled = (size_t)0U; + core_slice_iter_Chunks + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(core_slice___Slice_T___chunks(a, + (size_t)3U, + uint8_t, + core_slice_iter_Chunks), + core_slice_iter_Chunks, + core_slice_iter_Chunks); + while (true) + { + core_option_Option__Eurydice_slice_uint8_t + uu____0 = + core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next(&iter, + uint8_t, + core_option_Option__Eurydice_slice_uint8_t); + if (uu____0.tag == core_option_None) + { + break; + } + else + { + Eurydice_slice bytes = uu____0.f0; + int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____1; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) + { + uu____1 = sampled < (size_t)16U; + } + else + { + uu____1 = false; + } + if (uu____1) + { + int16_t uu____2 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____2; + sampled++; + } + bool uu____3; + if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) + { + uu____3 = sampled < (size_t)16U; + } + else + { + uu____3 = false; + } + if (uu____3) + { + int16_t uu____4 = d2; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____4; + sampled++; + } + } + } + return sampled; +} + +size_t +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + Eurydice_slice a, + Eurydice_slice out +) +{ + return libcrux_ml_kem_vector_rej_sample(a, out); +} + +inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_portable___core__clone__Clone_for_libcrux_ml_kem__vector__portable__PortableVector___clone( + libcrux_ml_kem_vector_portable_PortableVector *self +) +{ + return self[0U]; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +ZERO__libcrux_ml_kem_vector_portable_PortableVector(void) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12(bytes); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +shift_right___15int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +shift_right___15int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return shift_right___15int32_t(v); +} + +static libcrux_ml_kem_vector_portable_PortableVector +to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a +) +{ + libcrux_ml_kem_vector_portable_PortableVector t = shift_right___15int32_t0(a); + libcrux_ml_kem_vector_portable_PortableVector + fm = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant(t, + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, + &fm); +} + +static inline void +serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[384U] +) +{ + uint8_t serialized[384U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)384U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof (uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[4U], + uint8_t ret[1536U] +) +{ + uint8_t out[1536U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1536U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)1536U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U], + Eurydice_slice seed_for_a, + uint8_t ret[1568U] +) +{ + uint8_t public_key_serialized[1568U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1568U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1536U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[4U]; + memcpy(uu____1, + t_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1568U, + public_key_serialized, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t(Eurydice_array_to_subslice_to((size_t)1568U, + public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[4U]; + memcpy(uu____0, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, + public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1568U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static void +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy(ret, + ret0, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +typedef struct PortableHash____4size_t_s +{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[4U]; } +PortableHash____4size_t; + +static inline PortableHash____4size_t shake128_init_absorb___4size_t(uint8_t input[4U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, + Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[4U]; + memcpy(uu____1, + state, + (size_t)4U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + PortableHash____4size_t lit; + memcpy(lit.shake128_state, + uu____1, + (size_t)4U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___4size_t(PortableHash____4size_t *self, uint8_t ret[4U][504U]) +{ + uint8_t out[4U][504U] = { { 0U } }; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, + Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_504size_t( + uint8_t randomness[4U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void +shake128_squeeze_block___4size_t(PortableHash____4size_t *self, uint8_t ret[4U][168U]) +{ + uint8_t out[4U][168U] = { { 0U } }; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, + Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_168size_t( + uint8_t randomness[4U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_slice a) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array(Eurydice_slice_subslice(a, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + size_t sampled_coefficients[4U] = { 0U }; + int16_t out[4U][272U] = { { 0U } }; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof (uint8_t [34U])); + PortableHash____4size_t xof_state = shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U][4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0(A_transpose[i]);); + KRML_MAYBE_FOR4(i0, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[4U][34U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + fst[4U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) +{ + uint8_t out[4U][128U] = { { 0U } }; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256(uu____0, + Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof (uint8_t [128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice randomness +) +{ + int16_t sampled_i16s[256U] = { 0U }; + for + (size_t + i0 = (size_t)0U; + i0 + < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) + { + size_t chunk_number = i0; + Eurydice_slice + byte_chunk = + Eurydice_slice_subslice(randomness, + ( + (core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint32_t + uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t + uu____1 = + uu____0 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; + uint32_t + uu____2 = + uu____1 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; + uint32_t + random_bits_as_u32 = + uu____2 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) + { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return + from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_slice((size_t)256U, + sampled_i16s, + int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice randomness +) +{ + int16_t sampled_i16s[256U] = { 0U }; + for + (size_t + i0 = (size_t)0U; + i0 + < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) + { + size_t chunk_number = i0; + Eurydice_slice + byte_chunk = + Eurydice_slice_subslice(randomness, + ( + (core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint32_t + uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t + uu____1 = + uu____0 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; + uint32_t + random_bits_as_u24 = + uu____1 + | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) + { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t + outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + (int32_t)3) & 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return + from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_slice((size_t)256U, + sampled_i16s, + int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_slice randomness +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector(randomness); + return uu____0; +} + +static inline void +ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) + { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector + t = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant(re->coefficients[j + + step], + (int16_t)-1600); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(re->coefficients[j], + &t); + re->coefficients[j + step] = uu____0; + libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(re->coefficients[j], + &t); + re->coefficients[j] = uu____1; + } +} + +typedef struct +__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector_s +{ + libcrux_ml_kem_vector_portable_PortableVector fst; + libcrux_ml_kem_vector_portable_PortableVector snd; +} +__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector; + +static libcrux_ml_kem_vector_portable_PortableVector +montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t fer +) +{ + return + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(v, + fer); +} + +static inline __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, + int16_t zeta_r +) +{ + libcrux_ml_kem_vector_portable_PortableVector + t = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector(b, zeta_r); + b = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(a, + &t); + a = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, + &t); + return + ( + (__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, + .snd = b + } + ); +} + +static inline void +ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer +) +{ + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) + { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) + { + size_t j = i; + __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[j], + re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void +ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void +ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)3U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector(re); + size_t zeta_i = (size_t)1U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[4U]; + memcpy(uu____2, + re_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + out = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply(&self->coefficients[i0], + &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static libcrux_ml_kem_vector_portable_PortableVector +to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v +) +{ + return + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(v, + LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector(self->coefficients[j]); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___4size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[4U][4U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[4U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____3, + domain_separator).fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[4U]; + memcpy(uu____4, + t_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[4U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof (uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof (uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[3168U] +) +{ + uint8_t out[3168U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)3168U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___4size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)3168U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof (uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t(uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[4U]; + memcpy(uu____2, + error_1, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)3U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U]); + re->coefficients[round] = uu____0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step(re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, + int16_t zeta_r +) +{ + libcrux_ml_kem_vector_portable_PortableVector + a_minus_b = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(b, + &a); + a = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, + &b)); + b = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector(a_minus_b, zeta_r); + return + ( + (__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, + .snd = b + } + ); +} + +static inline void +invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer +) +{ + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) + { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) + { + size_t j = i; + __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[j], + re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline void +add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(self->coefficients[j], + (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + } + memcpy(ret, + result, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static libcrux_ml_kem_vector_portable_PortableVector +decompress_1__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v +) +{ + return + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uint8_t serialized[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1(Eurydice_array_to_subslice((size_t)32U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = decompress_1__libcrux_ml_kem_vector_portable_PortableVector(coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(result.coefficients[i0], + (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector + tmp = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], + &message->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector + tmp0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, + &tmp); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, + message, + result); + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +compress___10int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t + uu____0 = + libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)10, + (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +compress___10int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return compress___10int32_t(v); +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U] +) +{ + uint8_t serialized[352U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)352U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +compress___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t + uu____0 = + libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)11, + (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +compress___11int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return compress___11int32_t(v); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U] +) +{ + uint8_t serialized[352U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)352U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U] +) +{ + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352size_t(re, + uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof (uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[4U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t_352size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +compress___4int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t + uu____0 = + libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)4, + (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +compress___4int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return compress___4int32_t(v); +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + compress___4int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +compress___5int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int16_t + uu____0 = + libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)5, + (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +compress___5int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return compress___5int32_t(v); +} + +static inline void +compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficients = + compress___5int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5(coefficients, + bytes); + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t_160size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice out +) +{ + compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[1568U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t(Eurydice_slice_subslice_to(public_key, + (size_t)1536U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[4U][4U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[4U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[4U]; + memcpy(error_1, + uu____3.fst, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___4size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[1568U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[4U]; + memcpy(uu____5, + u, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t(uu____5, + Eurydice_array_to_subslice((size_t)1568U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1408U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t_160size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, + ciphertext, + (size_t)1408U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___4size_t(Eurydice_array_to_slice((size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___10int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int32_t + decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); + decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___10int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return decompress_ciphertext_coefficient___10int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10(bytes); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = decompress_ciphertext_coefficient___10int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int32_t + decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); + decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___11int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return decompress_ciphertext_coefficient___11int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11(bytes); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = decompress_ciphertext_coefficient___11int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector(serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1568U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)1568U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___4int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int32_t + decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); + decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___4int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return decompress_ciphertext_coefficient___4int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4(bytes); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = decompress_ciphertext_coefficient___4int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___5int32_t(libcrux_ml_kem_vector_portable_PortableVector v) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) + { + size_t i0 = i; + int32_t + decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); + decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static libcrux_ml_kem_vector_portable_PortableVector +decompress_ciphertext_coefficient___5int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) +{ + return decompress_ciphertext_coefficient___5int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5(bytes); + re.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_portable_PortableVector + uu____1 = decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector(serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) + { + size_t i0 = i; + Eurydice_slice + bytes = + Eurydice_slice_subslice(serialized, + ( + (core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12(bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)4U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + b +) +{ + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(b.coefficients[i0], + (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(self->coefficients[i0], + &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_message__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR4(i, + (size_t)0U, + (size_t)4U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + return result; +} + +static inline void +compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + uint8_t ret[32U] +) +{ + uint8_t serialized[32U] = { 0U }; + KRML_MAYBE_FOR16(i, + (size_t)0U, + (size_t)16U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector + coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1(coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1(coefficient_compressed, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)32U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *);); + memcpy(ret, serialized, (size_t)32U * sizeof (uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t(Eurydice_array_to_subslice_from((size_t)1568U, + ciphertext, + (size_t)1408U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)3168U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)1536U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)1568U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)1600U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___4size_t_32size_t(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t(uu____7, + Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[3U], + uint8_t ret[1152U] +) +{ + uint8_t out[1152U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1152U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)1152U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U], + Eurydice_slice seed_for_a, + uint8_t ret[1184U] +) +{ + uint8_t public_key_serialized[1184U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)1184U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1152U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[3U]; + memcpy(uu____1, + t_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1184U, + public_key_serialized, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t(Eurydice_array_to_subslice_to((size_t)1184U, + public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[3U]; + memcpy(uu____0, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, + public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1184U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static void +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy(ret, + ret0, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +typedef struct PortableHash____3size_t_s +{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; } +PortableHash____3size_t; + +static inline PortableHash____3size_t shake128_init_absorb___3size_t(uint8_t input[3U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, + Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; + memcpy(uu____1, + state, + (size_t)3U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + PortableHash____3size_t lit; + memcpy(lit.shake128_state, + uu____1, + (size_t)3U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___3size_t(PortableHash____3size_t *self, uint8_t ret[3U][504U]) +{ + uint8_t out[3U][504U] = { { 0U } }; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, + Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t( + uint8_t randomness[3U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void +shake128_squeeze_block___3size_t(PortableHash____3size_t *self, uint8_t ret[3U][168U]) +{ + uint8_t out[3U][168U] = { { 0U } }; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, + Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t( + uint8_t randomness[3U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + size_t sampled_coefficients[3U] = { 0U }; + int16_t out[3U][272U] = { { 0U } }; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof (uint8_t [34U])); + PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U][3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0(A_transpose[i]);); + KRML_MAYBE_FOR3(i0, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[3U][34U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + fst[3U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) +{ + uint8_t out[3U][128U] = { { 0U } }; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256(uu____0, + Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof (uint8_t [128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy(uu____2, + re_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[3U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____3, + domain_separator).fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[3U]; + memcpy(uu____4, + t_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof (uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof (uint8_t)); + return lit; +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[2400U] +) +{ + uint8_t out[2400U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)2400U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)2400U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof (uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t(uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy(uu____2, + error_1, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + } + memcpy(ret, + result, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, + message, + result); + return result; +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U] +) +{ + uint8_t serialized[320U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)320U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U] +) +{ + uint8_t serialized[320U] = { 0U }; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + coefficient = + compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11(coefficient, + bytes); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)320U, + serialized, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U] +) +{ + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t(re, + uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof (uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[3U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice out +) +{ + compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[1088U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t(Eurydice_slice_subslice_to(public_key, + (size_t)1152U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[3U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + memcpy(error_1, + uu____3.fst, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[1088U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy(uu____5, + u, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t(uu____5, + Eurydice_array_to_subslice((size_t)1088U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)960U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, + ciphertext, + (size_t)960U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___3size_t(Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector(serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1088U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)1088U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_slice serialized +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector(serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)3U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3(i, + (size_t)0U, + (size_t)3U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(Eurydice_array_to_subslice_from((size_t)1088U, + ciphertext, + (size_t)960U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)2400U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)1152U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)1184U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)1120U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t(uu____7, + Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[2U], + uint8_t ret[768U] +) +{ + uint8_t out[768U] = { 0U }; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = key[i0]; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)768U, + out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + } + memcpy(ret, out, (size_t)768U * sizeof (uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U], + Eurydice_slice seed_for_a, + uint8_t ret[800U] +) +{ + uint8_t public_key_serialized[800U] = { 0U }; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)800U, + public_key_serialized, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)768U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[2U]; + memcpy(uu____1, + t_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t(uu____1, + ret0); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)800U, + public_key_serialized, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + seed_for_a, + uint8_t, + void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof (uint8_t)); +} + +bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uint8_t *public_key +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(Eurydice_array_to_subslice_to((size_t)800U, + public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[2U]; + memcpy(uu____0, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(uu____0, + Eurydice_array_to_subslice_from((size_t)800U, + public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + public_key_serialized); + return + core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)800U, + public_key, + public_key_serialized, + uint8_t, + uint8_t, + bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) +{ + uint8_t digest[64U] = { 0U }; + libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static void +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy(ret, + ret0, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +typedef struct PortableHash____2size_t_s +{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[2U]; } +PortableHash____2size_t; + +static inline PortableHash____2size_t shake128_init_absorb___2size_t(uint8_t input[2U][34U]) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, + Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[2U]; + memcpy(uu____1, + state, + (size_t)2U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + PortableHash____2size_t lit; + memcpy(lit.shake128_state, + uu____1, + (size_t)2U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void +shake128_squeeze_three_blocks___2size_t(PortableHash____2size_t *self, uint8_t ret[2U][504U]) +{ + uint8_t out[2U][504U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, + Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_504size_t( + uint8_t randomness[2U][504U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)504U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static inline void +shake128_squeeze_block___2size_t(PortableHash____2size_t *self, uint8_t ret[2U][168U]) +{ + uint8_t out[2U][168U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + *uu____0 = &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, + Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_168size_t( + uint8_t randomness[2U][168U], + size_t *sampled_coefficients, + int16_t (*out)[272U] +) +{ + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) + { + size_t r = i; + if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)168U, + randomness[i1], + ( + (core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + size_t + sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, + Eurydice_array_to_subslice((size_t)272U, + out[i1], + ( + (core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U + } + ), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) + { + sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } + else + { + done = false; + }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( + int16_t s[272U] +) +{ + return + from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, + s, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), + int16_t, + core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + size_t sampled_coefficients[2U] = { 0U }; + int16_t out[2U][272U] = { { 0U } }; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof (uint8_t [34U])); + PortableHash____2size_t xof_state = shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof (uint8_t [504U])); + bool + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_504size_t(uu____1, + sampled_coefficients, + out); + while (true) + { + if (!!done) + { + break; + } + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof (uint8_t [168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_168size_t(uu____2, + sampled_coefficients, + out); + } + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof (int16_t [272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1(uu____3[i]);); + memcpy(ret, + ret0, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + uint8_t seed[34U], + bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U][2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0(A_transpose[i]);); + KRML_MAYBE_FOR2(i0, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); + uint8_t seeds[2U][34U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof (uint8_t [34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(uu____1, + sampled); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) + { + A_transpose[j][i1] = sample; + } + else + { + A_transpose[i1][j] = sample; + } + }); + memcpy(ret, + A_transpose, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U] + )); +} + +typedef struct +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t_s +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + fst[2U]; + uint8_t snd; +} +__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) +{ + uint8_t out[2U][192U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)192U, out[i0], uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256(uu____0, + Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [192U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + Eurydice_slice randomness +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector(randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_3size_t(Eurydice_array_to_slice((size_t)192U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[2U]; + memcpy(uu____2, + re_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, + self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = matrix_A[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, + &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1], + &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], + &error_as_ntt[i1]); + } + memcpy(ret, + result, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + Eurydice_slice key_generation_seed +) +{ + uint8_t hashed[64U]; + G___2size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + (size_t)32U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[2U][2U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(ret, + true, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____1, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + memcpy(secret_as_ntt, + uu____2.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[2U]; + memcpy(error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____3, + domain_separator).fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t(A_transpose, + secret_as_ntt, + error_as_ntt, + t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[2U]; + memcpy(uu____4, + t_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(uu____4, + seed_for_A, + public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[2U]; + memcpy(uu____5, + secret_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t(uu____5, + secret_key_serialized); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof (uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof (uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof (uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof (uint8_t)); + return lit; +} + +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t( + Eurydice_slice private_key, + Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, + uint8_t ret[1632U] +) +{ + uint8_t out[1632U] = { 0U }; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____0, + ( + (core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + private_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____3, + ( + (core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + public_key, + uint8_t, + void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice + uu____6 = + Eurydice_array_to_subslice((size_t)1632U, + out, + ( + (core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret0[32U]; + H___2size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice(uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, + void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, + uu____7, + ( + (core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + implicit_rejection_value, + uint8_t, + void *); + memcpy(ret, out, (size_t)1632U * sizeof (uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U] +) +{ + Eurydice_slice + ind_cpa_keypair_randomness = + Eurydice_array_to_subslice((size_t)64U, + randomness, + ( + (core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + Eurydice_slice + implicit_rejection_value = + Eurydice_array_to_subslice_from((size_t)64U, + randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, + uint8_t, + size_t, + Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ + uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof (uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof (uint8_t)); + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t(uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, Eurydice_slice), + implicit_rejection_value, + secret_key_serialized); + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t + private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t(uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof (uint8_t)); + return + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t(uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t(uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(public_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + ring_element = + Eurydice_slice_subslice(public_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy(ret, + deserialized_pk, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( + void +) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) +{ + uint8_t out[2U][128U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256(uu____0, + Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof (uint8_t [128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( + uint8_t prf_input[33U], + uint8_t domain_separator +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_outputs[i0], + uint8_t, + Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[2U]; + memcpy(uu____2, + error_1, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t + lit; + memcpy(lit.fst, + uu____2, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___2size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) +{ + uint8_t digest[128U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t0(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re +) +{ + size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re, + (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + (*a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i0 = (size_t)0U; + i0 + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], + size_t); + i0++) + { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = a_as_ntt[i1]; + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1], + &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + } + memcpy(ret, + result, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], + &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, + message, + result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[2U], + Eurydice_slice out +) +{ + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, + input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) + { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = input[i0]; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out, + ( + (core_ops_range_Range__size_t){ + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t(&re, + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[768U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(Eurydice_slice_subslice_to(public_key, + (size_t)768U, + uint8_t, + size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice + seed = Eurydice_slice_subslice_from(public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[2U][2U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(ret0, + false, + A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____0, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[2U]; + memcpy(r_as_ntt, + uu____1.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t(uu____2, + domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[2U]; + memcpy(error_1, + uu____3.fst, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___2size_t_128size_t(Eurydice_array_to_slice((size_t)33U, + prf_input, + uint8_t, + Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, + prf_output, + uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t(A_transpose, + r_as_ntt, + error_1, + u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_2size_t(t_as_ntt, + r_as_ntt, + &error_2, + &message_as_ring_element); + uint8_t ciphertext[768U] = { 0U }; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[2U]; + memcpy(uu____5, + u, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t(uu____5, + Eurydice_array_to_subslice((size_t)768U, + ciphertext, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)640U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t(uu____6, + Eurydice_array_to_subslice_from((size_t)768U, + ciphertext, + (size_t)640U, + uint8_t, + size_t, + Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof (uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U] +) +{ + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + randomness, + uint8_t, + Eurydice_slice), + to_hash); + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice_from((size_t)64U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + size_t, + Eurydice_slice); + uint8_t ret[32U]; + H___2size_t(Eurydice_array_to_slice((size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), + uint8_t, + Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + uint8_t hashed[64U]; + G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice + uu____2 = + Eurydice_array_to_slice((size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), + uint8_t, + Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____2, + uu____3, + pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = { 0U }; + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, + shared_secret_array, + uint8_t, + Eurydice_slice), + shared_secret, + uint8_t, + void *); + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof (uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t + uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t(uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)768U, + ciphertext, + uint8_t, + Eurydice_slice), + uint8_t, + size_t) + / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); + i++) + { + size_t i0 = i; + Eurydice_slice + u_bytes = + Eurydice_array_to_subslice((size_t)768U, + ciphertext, + ( + (core_ops_range_Range__size_t){ + .start = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), + .end = i0 + * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(&u_as_ntt[i0]); + } + memcpy(ret, + u_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t1(void) +{ + return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for + (size_t + i = (size_t)0U; + i + < + core_slice___Slice_T___len(secret_key, + uint8_t, + size_t) + / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) + { + size_t i0 = i; + Eurydice_slice + secret_bytes = + Eurydice_slice_subslice(secret_key, + ( + (core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 + * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy(ret, + secret_as_ntt, + (size_t)2U + * + sizeof ( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + )); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +compute_message__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], + &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result); + result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( + Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U] +) +{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t(ciphertext, + u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = + deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(Eurydice_array_to_subslice_from((size_t)768U, + ciphertext, + (size_t)640U, + uint8_t, + size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t(secret_key, + secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&v, + secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) +{ + uint8_t digest[32U] = { 0U }; + libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, + digest, + uint8_t, + Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +} + +void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U] +) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)1632U, + private_key->value, + uint8_t, + Eurydice_slice), + (size_t)768U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at(secret_key0, + (size_t)800U, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____2 = + core_slice___Slice_T___split_at(secret_key, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t(ind_cpa_secret_key, + ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, + decrypted, + uint8_t, + Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, + to_hash0, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice), + ind_cpa_public_key_hash, + uint8_t, + void *); + uint8_t hashed[64U]; + G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____3 = + core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, + hashed, + uint8_t, + Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, to_hash); + Eurydice_slice + uu____4 = + Eurydice_array_to_subslice_from((size_t)800U, + to_hash, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, + size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext), + uint8_t, + void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___2size_t_32size_t(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, + uu____6, + pseudorandomness, + expected_ciphertext); + Eurydice_slice + uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext); + uint8_t + selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t(uu____7, + Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), + selector, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); +} + diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h new file mode 100644 index 000000000..665a98126 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -0,0 +1,418 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem_portable_H +#define __libcrux_mlkem_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_sha3_internal.h" +#include "libcrux_sha3.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS ((int16_t)1353) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R (62209U) + +typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { int16_t elements[16U]; } +libcrux_ml_kem_vector_portable_PortableVector; + +libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero(void); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO( + void +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( + Eurydice_slice array +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_cond_subtract_3329(libcrux_ml_kem_vector_portable_PortableVector v); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v +); + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER ((int32_t)20159) + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT ((int32_t)26) + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_R ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT) + +int16_t libcrux_ml_kem_vector_barrett_reduce_element(int16_t value); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_barrett_reduce(libcrux_ml_kem_vector_portable_PortableVector v); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v +); + +#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT (16U) + +#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_R ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT) + +int16_t libcrux_ml_kem_vector_montgomery_reduce_element(int32_t value); + +int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(int16_t fe, int16_t fer); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t c +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t r +); + +uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress_1(libcrux_ml_kem_vector_portable_PortableVector v); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( + libcrux_ml_kem_vector_portable_PortableVector v +); + +uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits(uint8_t n, uint32_t value); + +int16_t +libcrux_ml_kem_vector_compress_ciphertext_coefficient(uint8_t coefficient_bits, uint16_t fe); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta0, + int16_t zeta1 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta0, + int16_t zeta1 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, + int16_t zeta +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, + int16_t zeta +); + +typedef struct K___int16_t_int16_t_s +{ + int16_t fst; + int16_t snd; +} +K___int16_t_int16_t; + +K___int16_t_int16_t +libcrux_ml_kem_vector_ntt_multiply_binomials( + K___int16_t_int16_t _, + K___int16_t_int16_t _0, + int16_t zeta +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, + int16_t zeta0, + int16_t zeta1, + int16_t zeta2, + int16_t zeta3 +); + +void +libcrux_ml_kem_vector_serialize_1( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[2U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[2U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_serialize_4( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[8U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[8U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_serialize_5( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[10U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[10U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_serialize_10( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[20U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[20U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_serialize_11( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[22U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[22U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( + Eurydice_slice a +); + +void +libcrux_ml_kem_vector_serialize_12( + libcrux_ml_kem_vector_portable_PortableVector v, + uint8_t ret[24U] +); + +void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + libcrux_ml_kem_vector_portable_PortableVector a, + uint8_t ret[24U] +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + Eurydice_slice a +); + +size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, Eurydice_slice result); + +size_t +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + Eurydice_slice a, + Eurydice_slice out +); + +libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_portable___core__clone__Clone_for_libcrux_ml_kem__vector__portable__PortableVector___clone( + libcrux_ml_kem_vector_portable_PortableVector *self +); + +typedef struct +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_s +{ libcrux_ml_kem_vector_portable_PortableVector coefficients[16U]; } +libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h new file mode 100644 index 000000000..7a55e8bf5 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -0,0 +1,26 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_platform_H +#define __libcrux_platform_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" + +extern bool libcrux_platform_platform_simd256_support(void); + +extern bool libcrux_platform_platform_simd128_support(void); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_platform_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h new file mode 100644 index 000000000..d7cdba78b --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -0,0 +1,118 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_sha3_H +#define __libcrux_sha3_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_sha3_internal.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +static inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___72size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___136size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___136size_t_31uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___144size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___104size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, Eurydice_slice payload) +{ + libcrux_sha3_portable_sha224(digest, payload); +} + +static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) +{ + uint8_t out[28U] = { 0U }; + libcrux_sha3_sha224_ema(Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), + data); + memcpy(ret, out, (size_t)28U * sizeof (uint8_t)); +} + +static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, Eurydice_slice payload) +{ + libcrux_sha3_portable_sha256(digest, payload); +} + +static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) +{ + uint8_t out[32U] = { 0U }; + libcrux_sha3_sha256_ema(Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), + data); + memcpy(ret, out, (size_t)32U * sizeof (uint8_t)); +} + +static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, Eurydice_slice payload) +{ + libcrux_sha3_portable_sha384(digest, payload); +} + +static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) +{ + uint8_t out[48U] = { 0U }; + libcrux_sha3_sha384_ema(Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), + data); + memcpy(ret, out, (size_t)48U * sizeof (uint8_t)); +} + +static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, Eurydice_slice payload) +{ + libcrux_sha3_portable_sha512(digest, payload); +} + +static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) +{ + uint8_t out[64U] = { 0U }; + libcrux_sha3_sha512_ema(Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), + data); + memcpy(ret, out, (size_t)64U * sizeof (uint8_t)); +} + +static inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, Eurydice_slice data) +{ + Eurydice_slice buf0[1U] = { data }; + Eurydice_slice buf[1U] = { digest }; + libcrux_sha3_portable_keccakx1___168size_t_31uint8_t(buf0, buf); +} + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c new file mode 100644 index 000000000..d7a2ff7c5 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -0,0 +1,123 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_sha3_avx2.h" + +#include "internal/libcrux_core.h" + +inline void +libcrux_sha3_avx2_x4_shake256( + Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice input2, + Eurydice_slice input3, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +) +{ + Prims_string + buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, + Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, + void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); +} + +inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +libcrux_sha3_avx2_x4_incremental_shake128_init(void) +{ + Prims_string + buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, + Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, + void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void +libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice data0, + Eurydice_slice data1, + Eurydice_slice data2, + Eurydice_slice data3 +) +{ + Prims_string + buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, + Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, + void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +) +{ + Prims_string + buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, + Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, + void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +) +{ + Prims_string + buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; + Eurydice_slice + uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, + Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, + void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); + KRML_HOST_EXIT(255U); +} + diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h new file mode 100644 index 000000000..1889ad419 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -0,0 +1,75 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_sha3_avx2_H +#define __libcrux_sha3_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "intrinsics/libcrux_intrinsics_avx2.h" + +#include "libcrux_sha3_neon.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +void +libcrux_sha3_avx2_x4_shake256( + Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice input2, + Eurydice_slice input3, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +); + +typedef struct libcrux_sha3_avx2_x4_incremental_KeccakState4_s +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U]; +} +libcrux_sha3_avx2_x4_incremental_KeccakState4; + +libcrux_sha3_avx2_x4_incremental_KeccakState4 +libcrux_sha3_avx2_x4_incremental_shake128_init(void); + +void +libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice data0, + Eurydice_slice data1, + Eurydice_slice data2, + Eurydice_slice data3 +); + +void +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +); + +void +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, + Eurydice_slice out0, + Eurydice_slice out1, + Eurydice_slice out2, + Eurydice_slice out3 +); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h new file mode 100644 index 000000000..f8ef58186 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -0,0 +1,3003 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_sha3_internal_H +#define __libcrux_sha3_internal_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "libcrux_core.h" +#include "eurydice_glue.h" + +static const +uint64_t +libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = + { + 1ULL, 32898ULL, 9223372036854808714ULL, 9223372039002292224ULL, 32907ULL, 2147483649ULL, + 9223372039002292353ULL, 9223372036854808585ULL, 138ULL, 136ULL, 2147516425ULL, 2147483658ULL, + 2147516555ULL, 9223372036854775947ULL, 9223372036854808713ULL, 9223372036854808579ULL, + 9223372036854808578ULL, 9223372036854775936ULL, 32778ULL, 9223372039002259466ULL, + 9223372039002292353ULL, 9223372036854808704ULL, 2147483649ULL, 9223372039002292232ULL + }; + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(void) +{ + return 0ULL; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__veor5q_u64( + uint64_t a, + uint64_t b, + uint64_t c, + uint64_t d, + uint64_t e +) +{ + uint64_t ab = a ^ b; + uint64_t cd = c ^ d; + uint64_t abcd = ab ^ cd; + return abcd ^ e; +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + uint64_t a, + uint64_t b, + uint64_t c, + uint64_t d, + uint64_t e +) +{ + return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; +} + +static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b) +{ + uint64_t uu____0 = a; + return uu____0 ^ libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) +{ + return a ^ (b & ~c); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( + uint64_t a, + uint64_t b, + uint64_t c +) +{ + return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); +} + +static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) +{ + return a ^ c; +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( + uint64_t a, + uint64_t c +) +{ + return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( + uint64_t a, + uint64_t b +) +{ + return a ^ b; +} + +static inline void +libcrux_sha3_portable_keccak_slice_1( + Eurydice_slice a[1U], + size_t start, + size_t len, + Eurydice_slice ret[1U] +) +{ + ret[0U] = + Eurydice_slice_subslice(a[0U], + ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + Eurydice_slice a[1U], + size_t start, + size_t len, + Eurydice_slice ret[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, a, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret0[1U]; + libcrux_sha3_portable_keccak_slice_1(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ +libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], size_t mid) +{ + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at_mut(out[0U], + mid, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ lit; + lit.fst[0U] = out00; + lit.snd[0U] = out01; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + Eurydice_slice a[1U], + size_t mid +) +{ + return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); +} + +typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s +{ uint64_t st[5U][5U]; } +libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( + void +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; + lit.st[0U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + return lit; +} + +static inline void +libcrux_sha3_portable_keccak_load_block___168size_t( + uint64_t (*s)[5U], + Eurydice_slice blocks[1U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) + { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak_load_block_full___168size_t( + uint64_t (*s)[5U], + uint8_t blocks[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( + uint64_t (*a)[5U], + uint8_t b[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak_load_block_full___168size_t(uu____0, uu____1); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) +{ + return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, uint64_t b) +{ + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( + uint64_t a, + uint64_t b +) +{ + return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s +) +{ + uint64_t + uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][0U], + s->st[1U][0U], + s->st[2U][0U], + s->st[3U][0U], + s->st[4U][0U]); + uint64_t + uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][1U], + s->st[1U][1U], + s->st[2U][1U], + s->st[3U][1U], + s->st[4U][1U]); + uint64_t + uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][2U], + s->st[1U][2U], + s->st[2U][2U], + s->st[3U][2U], + s->st[4U][2U]); + uint64_t + uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][3U], + s->st[1U][3U], + s->st[2U][3U], + s->st[3U][3U], + s->st[4U][3U]); + uint64_t + c[5U] = + { + uu____0, uu____1, uu____2, uu____3, + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][4U], + s->st[1U][4U], + s->st[2U][4U], + s->st[3U][4U], + s->st[4U][4U]) + }; + uint64_t + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)0U + + (size_t)4U) + % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + uint64_t + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)1U + + (size_t)4U) + % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + uint64_t + uu____6 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)2U + + (size_t)4U) + % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + uint64_t + uu____7 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)3U + + (size_t)4U) + % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + uint64_t + t[5U] = + { + uu____4, uu____5, uu____6, uu____7, + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)4U + + (size_t)4U) + % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U]) + }; + uint64_t + uu____8 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor(s->st[0U][0U], + t[0U]); + s->st[0U][0U] = uu____8; + uint64_t + uu____9 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], + t[0U]); + s->st[1U][0U] = uu____9; + uint64_t + uu____10 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], + t[0U]); + s->st[2U][0U] = uu____10; + uint64_t + uu____11 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], + t[0U]); + s->st[3U][0U] = uu____11; + uint64_t + uu____12 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], + t[0U]); + s->st[4U][0U] = uu____12; + uint64_t + uu____13 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], + t[1U]); + s->st[0U][1U] = uu____13; + uint64_t + uu____14 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], + t[1U]); + s->st[1U][1U] = uu____14; + uint64_t + uu____15 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], + t[1U]); + s->st[2U][1U] = uu____15; + uint64_t + uu____16 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], + t[1U]); + s->st[3U][1U] = uu____16; + uint64_t + uu____17 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], + t[1U]); + s->st[4U][1U] = uu____17; + uint64_t + uu____18 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], + t[2U]); + s->st[0U][2U] = uu____18; + uint64_t + uu____19 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], + t[2U]); + s->st[1U][2U] = uu____19; + uint64_t + uu____20 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], + t[2U]); + s->st[2U][2U] = uu____20; + uint64_t + uu____21 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], + t[2U]); + s->st[3U][2U] = uu____21; + uint64_t + uu____22 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], + t[2U]); + s->st[4U][2U] = uu____22; + uint64_t + uu____23 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], + t[3U]); + s->st[0U][3U] = uu____23; + uint64_t + uu____24 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], + t[3U]); + s->st[1U][3U] = uu____24; + uint64_t + uu____25 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], + t[3U]); + s->st[2U][3U] = uu____25; + uint64_t + uu____26 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], + t[3U]); + s->st[3U][3U] = uu____26; + uint64_t + uu____27 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], + t[3U]); + s->st[4U][3U] = uu____27; + uint64_t + uu____28 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], + t[4U]); + s->st[0U][4U] = uu____28; + uint64_t + uu____29 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], + t[4U]); + s->st[1U][4U] = uu____29; + uint64_t + uu____30 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], + t[4U]); + s->st[2U][4U] = uu____30; + uint64_t + uu____31 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], + t[4U]); + s->st[3U][4U] = uu____31; + uint64_t + uu____32 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], + t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void +libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s +) +{ + uint64_t old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, + s->st, + old, + uint64_t [5U], + void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void +libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s +) +{ + uint64_t old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof (uint64_t [5U])); + KRML_MAYBE_FOR5(i0, + (size_t)0U, + (size_t)5U, + (size_t)1U, + size_t i1 = i0; + KRML_MAYBE_FOR5(i, + (size_t)0U, + (size_t)5U, + (size_t)1U, + size_t j = i; + uint64_t + uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor(s->st[i1][j], + old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void +libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + size_t i +) +{ + uint64_t + uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant(s->st[0U][0U], + libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void +libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s +) +{ + for (size_t i = (size_t)0U; i < (size_t)24U; i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_pi__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_chi__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_iota__uint64_t_1size_t(s, i0); + } +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 31U; + blocks[i][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i][(size_t)168U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block___168size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) +{ + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) + { + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + libcrux_sha3_portable_keccak_store_block___168size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, + out); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + uint64_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U] +) +{ + uint64_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t(uu____0, + uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block_full___168size_t( + uint64_t (*s)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t out[200U] = { 0U }; + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_store_block___168size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + uint64_t (*a)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s->st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s.st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)168U, + (size_t)168U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)168U; + size_t last = outlen - outlen % (size_t)168U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)168U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t(uu____0, out); +} + +static inline void +libcrux_sha3_portable_keccak_load_block___104size_t( + uint64_t (*s)[5U], + Eurydice_slice blocks[1U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) + { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + uint64_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U] +) +{ + uint64_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t(uu____0, + uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_load_block_full___104size_t( + uint64_t (*s)[5U], + uint8_t blocks[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( + uint64_t (*a)[5U], + uint8_t b[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak_load_block_full___104size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)104U - (size_t)1U] = (uint32_t)blocks[i][(size_t)104U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block___104size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) +{ + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) + { + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak_store_block_full___104size_t( + uint64_t (*s)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t out[200U] = { 0U }; + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_store_block___104size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + uint64_t (*a)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s->st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + libcrux_sha3_portable_keccak_store_block___104size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s.st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)104U, + (size_t)104U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)104U; + size_t last = outlen - outlen % (size_t)104U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)104U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)104U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t(uu____0, out); +} + +static inline void +libcrux_sha3_portable_keccak_load_block___144size_t( + uint64_t (*s)[5U], + Eurydice_slice blocks[1U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) + { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + uint64_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U] +) +{ + uint64_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t(uu____0, + uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_load_block_full___144size_t( + uint64_t (*s)[5U], + uint8_t blocks[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( + uint64_t (*a)[5U], + uint8_t b[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak_load_block_full___144size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)144U - (size_t)1U] = (uint32_t)blocks[i][(size_t)144U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block___144size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) +{ + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) + { + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak_store_block_full___144size_t( + uint64_t (*s)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t out[200U] = { 0U }; + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_store_block___144size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + uint64_t (*a)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s->st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + libcrux_sha3_portable_keccak_store_block___144size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s.st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)144U, + (size_t)144U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)144U; + size_t last = outlen - outlen % (size_t)144U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)144U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)144U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t(uu____0, out); +} + +static inline void +libcrux_sha3_portable_keccak_load_block___136size_t( + uint64_t (*s)[5U], + Eurydice_slice blocks[1U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) + { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + uint64_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U] +) +{ + uint64_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t(uu____0, + uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_load_block_full___136size_t( + uint64_t (*s)[5U], + uint8_t blocks[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uint64_t (*a)[5U], + uint8_t b[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak_load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 31U; + blocks[i][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block___136size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) +{ + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) + { + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak_store_block_full___136size_t( + uint64_t (*s)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t out[200U] = { 0U }; + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_store_block___136size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + uint64_t (*a)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s->st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + libcrux_sha3_portable_keccak_store_block___136size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s.st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)136U, + (size_t)136U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t(uu____0, out); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)136U, + (size_t)136U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t(uu____0, out); +} + +static inline void +libcrux_sha3_portable_keccak_load_block___72size_t( + uint64_t (*s)[5U], + Eurydice_slice blocks[1U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) + { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + uint64_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U] +) +{ + uint64_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t(uu____0, + uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_load_block_full___72size_t( + uint64_t (*s)[5U], + uint8_t blocks[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( + uint64_t (*a)[5U], + uint8_t b[1U][200U] +) +{ + uint64_t (*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak_load_block_full___72size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = { { 0U } }; + { + size_t i = (size_t)0U; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)72U - (size_t)1U] = (uint32_t)blocks[i][(size_t)72U - (size_t)1U] | 128U; + } + uint64_t (*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t(uu____1, + uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_portable_keccak_store_block___72size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) +{ + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) + { + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak_store_block_full___72size_t( + uint64_t (*s)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t out[200U] = { 0U }; + uint64_t (*uu____0)[5U] = s; + Eurydice_slice + buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; + libcrux_sha3_portable_keccak_store_block___72size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + uint64_t (*a)[5U], + uint8_t ret[1U][200U] +) +{ + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s->st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( + uint64_t (*a)[5U], + Eurydice_slice b[1U] +) +{ + libcrux_sha3_portable_keccak_store_block___72size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, + out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s.st, + b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, + i0 * (size_t)72U, + (size_t)72U, + ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, + core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t(uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) + { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, + (size_t)72U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ + uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, + (size_t)72U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, o1); + } + } +} + +static inline void +libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( + Eurydice_slice data[1U], + Eurydice_slice out[1U] +) +{ + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t(uu____0, out); +} + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_internal_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c new file mode 100644 index 000000000..a0b803a00 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -0,0 +1,3689 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_sha3_neon.h" + +#include "internal/libcrux_core.h" + +static inline core_core_arch_arm_shared_neon_uint64x2_t zero(void) +{ + return libcrux_intrinsics_arm64__vdupq_n_u64(0ULL); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_veor5q_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c, + core_core_arch_arm_shared_neon_uint64x2_t d, + core_core_arch_arm_shared_neon_uint64x2_t e +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + core_core_arch_arm_shared_neon_uint64x2_t cd = libcrux_intrinsics_arm64__veorq_u64(c, d); + core_core_arch_arm_shared_neon_uint64x2_t abcd = libcrux_intrinsics_arm64__veorq_u64(ab, cd); + return libcrux_intrinsics_arm64__veorq_u64(abcd, e); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor5( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c, + core_core_arch_arm_shared_neon_uint64x2_t d, + core_core_arch_arm_shared_neon_uint64x2_t e +) +{ + return _veor5q_u64(a, b, c, d, e); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)1, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)63, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vrax1q_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; + return libcrux_intrinsics_arm64__veorq_u64(uu____0, rotate_left___1int32_t_63int32_t(b)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left1_and_xor( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vrax1q_u64(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vbcaxq_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c +) +{ + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; + return libcrux_intrinsics_arm64__veorq_u64(uu____0, libcrux_intrinsics_arm64__vbicq_u64(b, c)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +and_not_xor( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c +) +{ + return _vbcaxq_u64(a, b, c); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_veorq_n_u64(core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) +{ + core_core_arch_arm_shared_neon_uint64x2_t c0 = libcrux_intrinsics_arm64__vdupq_n_u64(c); + return libcrux_intrinsics_arm64__veorq_u64(a, c0); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_constant(core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) +{ + return _veorq_n_u64(a, c); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor0(core_core_arch_arm_shared_neon_uint64x2_t a, core_core_arch_arm_shared_neon_uint64x2_t b) +{ + return libcrux_intrinsics_arm64__veorq_u64(a, b); +} + +static inline void +slice_2(Eurydice_slice a[2U], size_t start, size_t len, Eurydice_slice ret[2U]) +{ + Eurydice_slice + uu____0 = + Eurydice_slice_subslice(a[0U], + ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + ret[0U] = uu____0; + ret[1U] = + Eurydice_slice_subslice(a[1U], + ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); +} + +static inline void +slice_n(Eurydice_slice a[2U], size_t start, size_t len, Eurydice_slice ret[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, a, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret0[2U]; + slice_2(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ +split_at_mut_2(Eurydice_slice out[2U], size_t mid) +{ + Eurydice_slice out0 = out[0U]; + Eurydice_slice out1 = out[1U]; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____0 = + core_slice___Slice_T___split_at_mut(out0, + mid, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t + uu____1 = + core_slice___Slice_T___split_at_mut(out1, + mid, + uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out10 = uu____1.fst; + Eurydice_slice out11 = uu____1.snd; + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ lit; + lit.fst[0U] = out00; + lit.fst[1U] = out10; + lit.snd[0U] = out01; + lit.snd[1U] = out11; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ +split_at_mut_n(Eurydice_slice a[2U], size_t mid) +{ + return split_at_mut_2(a, mid); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(void) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + lit; + lit.st[0U][0U] = zero(); + lit.st[0U][1U] = zero(); + lit.st[0U][2U] = zero(); + lit.st[0U][3U] = zero(); + lit.st[0U][4U] = zero(); + lit.st[1U][0U] = zero(); + lit.st[1U][1U] = zero(); + lit.st[1U][2U] = zero(); + lit.st[1U][3U] = zero(); + lit.st[1U][4U] = zero(); + lit.st[2U][0U] = zero(); + lit.st[2U][1U] = zero(); + lit.st[2U][2U] = zero(); + lit.st[2U][3U] = zero(); + lit.st[2U][4U] = zero(); + lit.st[3U][0U] = zero(); + lit.st[3U][1U] = zero(); + lit.st[3U][2U] = zero(); + lit.st[3U][3U] = zero(); + lit.st[3U][4U] = zero(); + lit.st[4U][0U] = zero(); + lit.st[4U][1U] = zero(); + lit.st[4U][2U] = zero(); + lit.st[4U][3U] = zero(); + lit.st[4U][4U] = zero(); + return lit; +} + +static inline void +load_block___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = + s[((size_t)2U * i0 + (size_t)1U) + / (size_t)5U][((size_t)2U * i0 + (size_t)1U) + % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = + libcrux_intrinsics_arm64__veorq_u64(uu____2, + libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = + uu____3; + } + if ((size_t)72U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = { 0U }; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2(&dst0, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, + ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t + uvec = + libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, + u, + uint64_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void +load_block___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); + load_block___72size_t(uu____0, uu____1); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)36, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)28, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___36int32_t_28int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___36int32_t_28int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___36int32_t_28int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)3, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)61, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___3int32_t_61int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___3int32_t_61int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___3int32_t_61int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)41, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)23, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___41int32_t_23int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___41int32_t_23int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___41int32_t_23int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)18, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)46, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___18int32_t_46int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___18int32_t_46int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___18int32_t_46int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___1int32_t_63int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___1int32_t_63int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___1int32_t_63int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)44, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)20, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___44int32_t_20int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___44int32_t_20int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___44int32_t_20int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)10, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)54, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___10int32_t_54int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___10int32_t_54int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___10int32_t_54int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)45, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)19, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___45int32_t_19int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___45int32_t_19int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___45int32_t_19int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)2, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)62, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___2int32_t_62int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___2int32_t_62int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___2int32_t_62int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)62, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)2, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___62int32_t_2int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___62int32_t_2int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___62int32_t_2int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)6, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)58, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___6int32_t_58int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___6int32_t_58int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___6int32_t_58int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)43, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)21, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___43int32_t_21int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___43int32_t_21int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___43int32_t_21int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)15, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)49, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___15int32_t_49int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___15int32_t_49int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___15int32_t_49int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)61, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)3, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___61int32_t_3int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___61int32_t_3int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___61int32_t_3int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)28, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)36, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___28int32_t_36int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___28int32_t_36int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___28int32_t_36int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)55, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)9, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___55int32_t_9int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___55int32_t_9int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___55int32_t_9int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)25, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)39, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___25int32_t_39int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___25int32_t_39int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___25int32_t_39int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)21, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)43, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___21int32_t_43int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___21int32_t_43int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___21int32_t_43int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)56, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)8, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___56int32_t_8int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___56int32_t_8int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___56int32_t_8int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)27, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)37, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___27int32_t_37int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___27int32_t_37int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___27int32_t_37int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)20, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)44, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___20int32_t_44int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___20int32_t_44int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___20int32_t_44int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)39, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)25, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___39int32_t_25int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___39int32_t_25int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___39int32_t_25int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)8, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)56, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___8int32_t_56int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___8int32_t_56int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___8int32_t_56int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)14, + x, + core_core_arch_arm_shared_neon_uint64x2_t); + return + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)50, + x, + core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___14int32_t_50int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___14int32_t_50int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___14int32_t_50int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b +) +{ + return _vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void +theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s +) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], s->st[4U][0U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], s->st[4U][1U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], s->st[4U][2U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], s->st[4U][3U]); + core_core_arch_arm_shared_neon_uint64x2_t + c[5U] = + { + uu____0, uu____1, uu____2, uu____3, + xor5(s->st[0U][4U], + s->st[1U][4U], + s->st[2U][4U], + s->st[3U][4U], + s->st[4U][4U]) + }; + core_core_arch_arm_shared_neon_uint64x2_t + uu____4 = + rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____5 = + rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = + rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + uu____7 = + rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + t[5U] = + { + uu____4, uu____5, uu____6, uu____7, + rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U]) + }; + core_core_arch_arm_shared_neon_uint64x2_t uu____8 = xor0(s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + core_core_arch_arm_shared_neon_uint64x2_t + uu____9 = xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + core_core_arch_arm_shared_neon_uint64x2_t + uu____10 = xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + core_core_arch_arm_shared_neon_uint64x2_t + uu____11 = xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + core_core_arch_arm_shared_neon_uint64x2_t + uu____12 = xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + core_core_arch_arm_shared_neon_uint64x2_t + uu____13 = xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + core_core_arch_arm_shared_neon_uint64x2_t + uu____14 = xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + core_core_arch_arm_shared_neon_uint64x2_t + uu____15 = xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + core_core_arch_arm_shared_neon_uint64x2_t + uu____16 = xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + core_core_arch_arm_shared_neon_uint64x2_t + uu____17 = xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + core_core_arch_arm_shared_neon_uint64x2_t + uu____18 = xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + core_core_arch_arm_shared_neon_uint64x2_t + uu____19 = xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + core_core_arch_arm_shared_neon_uint64x2_t + uu____20 = xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + core_core_arch_arm_shared_neon_uint64x2_t + uu____21 = xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + core_core_arch_arm_shared_neon_uint64x2_t + uu____22 = xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + core_core_arch_arm_shared_neon_uint64x2_t + uu____23 = xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + core_core_arch_arm_shared_neon_uint64x2_t + uu____24 = xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + core_core_arch_arm_shared_neon_uint64x2_t + uu____25 = xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + core_core_arch_arm_shared_neon_uint64x2_t + uu____26 = xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + core_core_arch_arm_shared_neon_uint64x2_t + uu____27 = xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + core_core_arch_arm_shared_neon_uint64x2_t + uu____28 = xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + core_core_arch_arm_shared_neon_uint64x2_t + uu____29 = xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + core_core_arch_arm_shared_neon_uint64x2_t + uu____30 = xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + core_core_arch_arm_shared_neon_uint64x2_t + uu____31 = xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + core_core_arch_arm_shared_neon_uint64x2_t + uu____32 = xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void +pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s +) +{ + core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, + s->st, + old, + core_core_arch_arm_shared_neon_uint64x2_t [5U], + void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void +chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s +) +{ + core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof (core_core_arch_arm_shared_neon_uint64x2_t [5U])); + KRML_MAYBE_FOR5(i0, + (size_t)0U, + (size_t)5U, + (size_t)1U, + size_t i1 = i0; + KRML_MAYBE_FOR5(i, + (size_t)0U, + (size_t)5U, + (size_t)1U, + size_t j = i; + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = + and_not_xor(s->st[i1][j], + old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void +iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + size_t i +) +{ + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = xor_constant(s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void +keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s +) +{ + for (size_t i = (size_t)0U; i < (size_t)24U; i++) + { + size_t i0 = i; + theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s, i0); + } +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice blocks[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); + load_block___72size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +load_block_full___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = + { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; + load_block___72size_t(uu____0, buf); +} + +static inline void +load_block_full___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t b[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___72size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)72U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)72U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___72size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +store_block___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)72U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice + uu____1 = + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +store_block_full___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t out0[200U] = { 0U }; + uint8_t out1[200U] = { 0U }; + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; + store_block___72size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +store_block_full___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t ret0[2U][200U]; + store_block_full___72size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + uint8_t b[2U][200U]; + store_block_full___72size_t0(s->st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +store_block___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + store_block___72size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + store_block___72size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___72size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___72size_t0(s.st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + Eurydice_slice data[2U], + Eurydice_slice out[2U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)72U, (size_t)72U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) + { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)72U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)72U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, o); + memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(s, o1); + } + } +} + +static inline void +keccakx2___72size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t(uu____0, out); +} + +void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) +{ + uint8_t dummy[64U] = { 0U }; + Eurydice_slice uu____0[2U] = { data, data }; + Eurydice_slice uu____1 = digest; + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)64U, dummy, uint8_t, Eurydice_slice) }; + keccakx2___72size_t_6uint8_t(uu____0, buf); +} + +static inline void +load_block___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = + s[((size_t)2U * i0 + (size_t)1U) + / (size_t)5U][((size_t)2U * i0 + (size_t)1U) + % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = + libcrux_intrinsics_arm64__veorq_u64(uu____2, + libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = + uu____3; + } + if ((size_t)136U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = { 0U }; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2(&dst0, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, + ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t + uvec = + libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, + u, + uint64_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void +load_block___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); + load_block___136size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice blocks[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); + load_block___136size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +load_block_full___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = + { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; + load_block___136size_t(uu____0, buf); +} + +static inline void +load_block_full___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t b[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +store_block___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)136U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice + uu____1 = + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +store_block_full___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t out0[200U] = { 0U }; + uint8_t out1[200U] = { 0U }; + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; + store_block___136size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +store_block_full___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t ret0[2U][200U]; + store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + uint8_t b[2U][200U]; + store_block_full___136size_t0(s->st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +store_block___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + store_block___136size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___136size_t0(s.st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + Eurydice_slice data[2U], + Eurydice_slice out[2U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) + { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(s, o1); + } + } +} + +static inline void +keccakx2___136size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t(uu____0, out); +} + +void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) +{ + uint8_t dummy[32U] = { 0U }; + Eurydice_slice uu____0[2U] = { data, data }; + Eurydice_slice uu____1 = digest; + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice) }; + keccakx2___136size_t_6uint8_t(uu____0, buf); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + Eurydice_slice data[2U], + Eurydice_slice out[2U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) + { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(s, o1); + } + } +} + +static inline void +keccakx2___136size_t_31uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t(uu____0, out); +} + +void +libcrux_sha3_neon_x2_shake256( + Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1 +) +{ + Eurydice_slice buf0[2U] = { input0, input1 }; + Eurydice_slice buf[2U] = { out0, out1 }; + keccakx2___136size_t_31uint8_t(buf0, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +KeccakState2; + +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +libcrux_sha3_neon_x2_incremental_shake128_init(void) +{ + return new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); +} + +static inline void +load_block___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = + s[((size_t)2U * i0 + (size_t)1U) + / (size_t)5U][((size_t)2U * i0 + (size_t)1U) + % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = + libcrux_intrinsics_arm64__veorq_u64(uu____2, + libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = + uu____3; + } + if ((size_t)168U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = { 0U }; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2(&dst0, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, + ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t + uvec = + libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, + u, + uint64_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void +load_block_full___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = + { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; + load_block___168size_t(uu____0, buf); +} + +static inline void +load_block_full___168size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t b[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___168size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___168size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +void +libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice data0, + Eurydice_slice data1 +) +{ + Eurydice_slice buf[2U] = { data0, data1 }; + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t(s, buf); +} + +static inline void +store_block___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)168U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice + uu____1 = + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +store_block___168size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + store_block___168size_t(a, b); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___168size_t0(s->st, out); +} + +void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out0, + Eurydice_slice out1 +) +{ + Eurydice_slice buf[2U] = { out0, out1 }; + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, buf); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + store_block___168size_t0(s->st, out); +} + +static inline void +squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____0 = split_at_mut_n(out, (size_t)168U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____0.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o10[2U]; + memcpy(o10, uu____0.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o0); + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____1 = split_at_mut_n(o10, (size_t)168U); + Eurydice_slice o1[2U]; + memcpy(o1, uu____1.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o2[2U]; + memcpy(o2, uu____1.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o1); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o2); +} + +void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out0, + Eurydice_slice out1 +) +{ + Eurydice_slice buf[2U] = { out0, out1 }; + squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, + buf); +} + +static inline void +load_block___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = + s[((size_t)2U * i0 + (size_t)1U) + / (size_t)5U][((size_t)2U * i0 + (size_t)1U) + % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = + libcrux_intrinsics_arm64__veorq_u64(uu____2, + libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = + uu____3; + } + if ((size_t)144U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = { 0U }; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2(&dst0, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, + ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t + uvec = + libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, + u, + uint64_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void +load_block___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); + load_block___144size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice blocks[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); + load_block___144size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +load_block_full___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = + { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; + load_block___144size_t(uu____0, buf); +} + +static inline void +load_block_full___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t b[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___144size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)144U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)144U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___144size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +store_block___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)144U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice + uu____1 = + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +store_block_full___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t out0[200U] = { 0U }; + uint8_t out1[200U] = { 0U }; + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; + store_block___144size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +store_block_full___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t ret0[2U][200U]; + store_block_full___144size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + uint8_t b[2U][200U]; + store_block_full___144size_t0(s->st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +store_block___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + store_block___144size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + store_block___144size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___144size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___144size_t0(s.st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + Eurydice_slice data[2U], + Eurydice_slice out[2U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)144U, (size_t)144U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)144U; + size_t last = outlen - outlen % (size_t)144U; + if (blocks == (size_t)0U) + { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)144U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)144U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, o); + memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(s, o1); + } + } +} + +static inline void +keccakx2___144size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t(uu____0, out); +} + +inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) +{ + uint8_t dummy[28U] = { 0U }; + Eurydice_slice uu____0[2U] = { data, data }; + Eurydice_slice uu____1 = digest; + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)28U, dummy, uint8_t, Eurydice_slice) }; + keccakx2___144size_t_6uint8_t(uu____0, buf); +} + +static inline void +load_block___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____1 = + libcrux_intrinsics_arm64__veorq_u64(uu____0, + libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t + uu____2 = + s[((size_t)2U * i0 + (size_t)1U) + / (size_t)5U][((size_t)2U * i0 + (size_t)1U) + % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t + uu____3 = + libcrux_intrinsics_arm64__veorq_u64(uu____2, + libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = + uu____3; + } + if ((size_t)104U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = { 0U }; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2(&dst0, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, + ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, + uint8_t [8U], + void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, + ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t + uvec = + libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, + u, + uint64_t, + Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t + uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void +load_block___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); + load_block___104size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice blocks[2U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); + load_block___104size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +load_block_full___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice + uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = + { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; + load_block___104size_t(uu____0, buf); +} + +static inline void +load_block_full___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t b[2U][200U] +) +{ + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___104size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice last[2U] +) +{ + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = { { 0U } }; + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice + uu____0 = + Eurydice_array_to_subslice((size_t)200U, + blocks[i0], + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)104U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)104U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); + load_block_full___104size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +store_block___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U] +) +{ + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) + { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t + v0 = + libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t + v1 = + libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U + * i0 + / (size_t)5U][(size_t)2U + * i0 + % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], + ( + (core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U) + } + ), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)104U % (size_t)16U != (size_t)0U) + { + size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = { 0U }; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice + uu____1 = + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____1, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + Eurydice_slice + uu____2 = + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____2, + Eurydice_array_to_subslice((size_t)16U, + u, + ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *); + } +} + +static inline void +store_block_full___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t out0[200U] = { 0U }; + uint8_t out1[200U] = { 0U }; + core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; + store_block___104size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); +} + +static inline void +store_block_full___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + uint8_t ret[2U][200U] +) +{ + uint8_t ret0[2U][200U]; + store_block_full___104size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + uint8_t b[2U][200U]; + store_block_full___104size_t0(s->st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +store_block___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], + Eurydice_slice b[2U] +) +{ + store_block___104size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + store_block___104size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___104size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, + Eurydice_slice out[2U] +) +{ + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___104size_t0(s.st, b); + KRML_MAYBE_FOR2(i, + (size_t)0U, + (size_t)2U, + (size_t)1U, + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice(uu____0, + Eurydice_array_to_subslice((size_t)200U, + uu____1, + lit, + uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, + void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + Eurydice_slice data[2U], + Eurydice_slice out[2U] +) +{ + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for + (size_t + i = (size_t)0U; + i + < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; + i++) + { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)104U, (size_t)104U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(uu____0, ret); + } + size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)104U; + size_t last = outlen - outlen % (size_t)104U; + if (blocks == (size_t)0U) + { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, out); + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)104U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, o0); + core_ops_range_Range__size_t + iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( + (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } + ), + core_ops_range_Range__size_t, + core_ops_range_Range__size_t); + while (true) + { + if + ( + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, + size_t, + core_option_Option__size_t).tag + == core_option_None + ) + { + break; + } + else + { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)104U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, o); + memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); + } + } + if (last < outlen) + { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(s, o1); + } + } +} + +static inline void +keccakx2___104size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) +{ + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t(uu____0, out); +} + +inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) +{ + uint8_t dummy[48U] = { 0U }; + Eurydice_slice uu____0[2U] = { data, data }; + Eurydice_slice uu____1 = digest; + Eurydice_slice + buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)48U, dummy, uint8_t, Eurydice_slice) }; + keccakx2___104size_t_6uint8_t(uu____0, buf); +} + diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h new file mode 100644 index 000000000..921691e48 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -0,0 +1,71 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc + F* version: b5cb71b8 + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_sha3_neon_H +#define __libcrux_sha3_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "intrinsics/libcrux_intrinsics_arm64.h" + +#include "libcrux_sha3_internal.h" +#include "libcrux_core.h" +#include "eurydice_glue.h" + +typedef struct +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t_s +{ core_core_arch_arm_shared_neon_uint64x2_t st[5U][5U]; } +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t; + +void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); + +void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); + +void +libcrux_sha3_neon_x2_shake256( + Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1 +); + +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +libcrux_sha3_neon_x2_incremental_shake128_init(void); + +void +libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice data0, + Eurydice_slice data1 +); + +void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out0, + Eurydice_slice out1 +); + +void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, + Eurydice_slice out0, + Eurydice_slice out1 +); + +void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); + +void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_neon_H_DEFINED +#endif From dad7ccc50cb7d9c8b31bf52fe9d5c99ee153324e Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 16:08:39 -0700 Subject: [PATCH 14/84] Refresh for AVX2 --- libcrux-ml-kem/c.sh | 2 + libcrux-ml-kem/c/CMakeLists.txt | 28 +- libcrux-ml-kem/c/eurydice_glue.h | 4 + libcrux-ml-kem/c/internal/libcrux_core.h | 283 +- .../c/internal/libcrux_mlkem_avx2.h | 77 + .../c/internal/libcrux_mlkem_neon.h | 94 - .../c/internal/libcrux_mlkem_portable.h | 98 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 38 + .../c/internal/libcrux_sha3_internal.h | 357 +- libcrux-ml-kem/c/libcrux_core.c | 540 +- libcrux-ml-kem/c/libcrux_core.h | 161 +- libcrux-ml-kem/c/libcrux_mlkem1024.c | 225 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 107 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 55 + libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 41 + libcrux-ml-kem/c/libcrux_mlkem1024_neon.c | 77 - libcrux-ml-kem/c/libcrux_mlkem1024_neon.h | 45 - libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 86 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 30 +- libcrux-ml-kem/c/libcrux_mlkem512.c | 222 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 105 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 164 + libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 91 + libcrux-ml-kem/c/libcrux_mlkem512_neon.c | 223 - libcrux-ml-kem/c/libcrux_mlkem512_neon.h | 113 - libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 251 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 106 +- libcrux-ml-kem/c/libcrux_mlkem768.c | 225 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 105 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 55 + libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 41 + libcrux-ml-kem/c/libcrux_mlkem768_neon.c | 77 - libcrux-ml-kem/c/libcrux_mlkem768_neon.h | 45 - libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 86 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 30 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 7623 ++++++++++ libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 294 + libcrux-ml-kem/c/libcrux_mlkem_neon.c | 9690 ------------ libcrux-ml-kem/c/libcrux_mlkem_neon.h | 418 - libcrux-ml-kem/c/libcrux_mlkem_portable.c | 12268 +++++++--------- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 348 +- libcrux-ml-kem/c/libcrux_platform.c | 5 + libcrux-ml-kem/c/libcrux_platform.h | 8 +- libcrux-ml-kem/c/libcrux_sha3.h | 120 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 2119 ++- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 83 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 2961 ++-- libcrux-ml-kem/c/libcrux_sha3_neon.c | 3858 +---- libcrux-ml-kem/c/libcrux_sha3_neon.h | 60 +- 49 files changed, 18977 insertions(+), 25165 deletions(-) create mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.h diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index fdd1dba86..1017995a1 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -52,6 +52,8 @@ mkdir -p c cd c rm -rf *.c *.h +# HAND_WRITTEN FILE +git checkout libcrux_platform.c rm -rf internal/*.h echo "Running eurydice ..." $EURYDICE_HOME/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index ce387e474..ef65b149d 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -37,18 +37,20 @@ file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/libcrux_mlkem512.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024.c + ${PROJECT_SOURCE_DIR}/libcrux_mlkem_portable.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_portable.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_portable.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_portable.c - ${PROJECT_SOURCE_DIR}/libcrux_polynomial.c ) file(GLOB SOURCES_vec128 + ${PROJECT_SOURCE_DIR}/libcrux_mlkem_neon.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_neon.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_neon.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_neon.c ${PROJECT_SOURCE_DIR}/libcrux_sha3_neon.c ) file(GLOB SOURCES_vec256 + ${PROJECT_SOURCE_DIR}/libcrux_mlkem_avx2.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem512_avx2.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem768_avx2.c ${PROJECT_SOURCE_DIR}/libcrux_mlkem1024_avx2.c @@ -65,21 +67,21 @@ add_library(ml_kem SHARED ${SOURCES}) add_library(ml_kem_static STATIC ${SOURCES}) # if(LIBCRUX_VEC256) -# add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) -# target_sources(ml_kem_static PRIVATE $) -# target_sources(ml_kem PRIVATE $) -# target_compile_options(ml_kem_vec256 PRIVATE -# -mavx -# -mavx2 -# ) +add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) +target_sources(ml_kem_static PRIVATE $) +target_sources(ml_kem PRIVATE $) +target_compile_options(ml_kem_vec256 PRIVATE + -mavx + -mavx2 +) # endif() # if(LIBCRUX_VEC128) -add_library(ml_kem_vec128 OBJECT ${SOURCES_vec128}) -target_sources(ml_kem_static PRIVATE $) -target_sources(ml_kem PRIVATE $) -target_compile_options(ml_kem_vec128 PRIVATE -) +# add_library(ml_kem_vec128 OBJECT ${SOURCES_vec128}) +# target_sources(ml_kem_static PRIVATE $) +# target_sources(ml_kem PRIVATE $) +# target_compile_options(ml_kem_vec128 PRIVATE +# ) # endif() # --- Tests diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index f798f970b..bd794c456 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -155,9 +155,13 @@ static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { ? ((ret_t){.tag = core_option_None}) \ : ((ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) +// Old name (TODO: remove once everyone has upgraded to the latest Charon) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ Eurydice_range_iter_next +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ + Eurydice_range_iter_next + // See note in karamel/lib/Inlining.ml if you change this #define Eurydice_into_iter(x, t, _ret_t) (x) #define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \ diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 6deb05bb9..d449e80ba 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_core_H @@ -15,32 +15,30 @@ extern "C" { #include "../libcrux_core.h" #include "eurydice_glue.h" -extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none(core_fmt_rt_Argument x0[0U]); +extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( + core_fmt_rt_Argument x0[0U]); -extern core_fmt_Arguments -core_fmt__core__fmt__Arguments__a__2__new_v1(Eurydice_slice x0, Eurydice_slice x1); +extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( + Eurydice_slice x0, Eurydice_slice x1); #define CORE_NUM__U32_8__BITS (32U) -static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]); +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); #define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) -void -libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - Eurydice_slice lhs, - Eurydice_slice rhs, - uint8_t selector, - uint8_t ret[32U] -); +void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, uint8_t ret[32U]); #define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT ((size_t)12U) #define LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT ((size_t)256U) -#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) -#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) +#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) #define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) @@ -48,205 +46,210 @@ libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uint8_t value[1568U] -); + uint8_t value[1568U]); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk -); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk); libcrux_ml_kem_types_MlKemPrivateKey____3168size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uint8_t value[3168U] -); + uint8_t value[3168U]); -typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s -{ +typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s { uint8_t fst[1536U]; uint8_t snd[1568U]; -} -K___uint8_t_1536size_t__uint8_t_1568size_t_; +} K___uint8_t_1536size_t__uint8_t_1568size_t_; libcrux_ml_kem_types_MlKemCiphertext____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uint8_t value[1568U] -); + uint8_t value[1568U]); -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self -); +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self); uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -); + Eurydice_slice lhs, Eurydice_slice rhs); Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self -); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self); -void -libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, uint8_t ret[1600U]); +void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, + uint8_t ret[1600U]); libcrux_ml_kem_types_MlKemPublicKey____1184size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uint8_t value[1184U] -); + uint8_t value[1184U]); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk -); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk); libcrux_ml_kem_types_MlKemPrivateKey____2400size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uint8_t value[2400U] -); + uint8_t value[2400U]); -typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s -{ +typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s { uint8_t fst[1152U]; uint8_t snd[1184U]; -} -K___uint8_t_1152size_t__uint8_t_1184size_t_; +} K___uint8_t_1152size_t__uint8_t_1184size_t_; libcrux_ml_kem_types_MlKemCiphertext____1088size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uint8_t value[1088U] -); + uint8_t value[1088U]); -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self -); +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self); uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -); + Eurydice_slice lhs, Eurydice_slice rhs); Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self -); - -void -libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]); - -typedef struct K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s -{ - Eurydice_slice fst; - Eurydice_slice snd; -} -K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self); -typedef struct K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s -{ - Eurydice_slice fst; - Eurydice_slice snd; -} -K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - -typedef struct K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s -{ - Eurydice_slice fst; - Eurydice_slice snd; -} -K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; +void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]); libcrux_ml_kem_types_MlKemPublicKey____800size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U] -); + uint8_t value[800U]); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk -); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk); libcrux_ml_kem_types_MlKemPrivateKey____1632size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U] -); + uint8_t value[1632U]); -typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s -{ +typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s { uint8_t fst[768U]; uint8_t snd[800U]; -} -K___uint8_t_768size_t__uint8_t_800size_t_; +} K___uint8_t_768size_t__uint8_t_800size_t_; libcrux_ml_kem_types_MlKemCiphertext____768size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U] -); + uint8_t value[768U]); -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self -); +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self); uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -); + Eurydice_slice lhs, Eurydice_slice rhs); -void -libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); +typedef struct + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; -void -libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]); +void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, + uint8_t ret[33U]); + +void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, + uint8_t ret[34U]); + +typedef struct + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self -); + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); + +void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]); + +void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, + uint8_t ret[64U]); + +typedef struct + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[24U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, + uint8_t ret[24U]); -void -libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, uint8_t ret[800U]); +typedef struct + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[20U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError; -void -libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]); +void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, + uint8_t ret[20U]); -typedef struct core_option_Option__Eurydice_slice_uint8_t_s -{ +typedef struct + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[10U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, + uint8_t ret[10U]); + +typedef struct core_option_Option__Eurydice_slice_uint8_t_s { core_option_Option__size_t_tags tag; Eurydice_slice f0; -} -core_option_Option__Eurydice_slice_uint8_t; +} core_option_Option__Eurydice_slice_uint8_t; -typedef struct core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s -{ - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; +typedef struct + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; union { int16_t case_Ok[16U]; core_array_TryFromSliceError case_Err; - } - val; -} -core_result_Result__int16_t_16size_t__core_array_TryFromSliceError; - -void -core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, - int16_t ret[16U] -); - -typedef struct K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t__s -{ - Eurydice_slice fst[2U]; - Eurydice_slice snd[2U]; -} -K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_; + } val; +} core_result_Result__int16_t_16size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, + int16_t ret[16U]); + +typedef struct + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s { + Eurydice_slice fst[4U]; + Eurydice_slice snd[4U]; +} K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h new file mode 100644 index 000000000..b95276a30 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -0,0 +1,77 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __internal_libcrux_mlkem_avx2_H +#define __internal_libcrux_mlkem_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_mlkem_avx2.h" +#include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_sha3_avx2.h" + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_mlkem_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h deleted file mode 100644 index 5a3e6df8f..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_mlkem_neon_H -#define __internal_libcrux_mlkem_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "internal/libcrux_mlkem_portable.h" -#include "internal/libcrux_core.h" -#include "../libcrux_mlkem_neon.h" -#include "eurydice_glue.h" - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key -); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key -); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uint8_t *public_key -); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_mlkem_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index e740ee1d0..8d67ca22e 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H @@ -12,83 +12,67 @@ extern "C" { #endif -#include "internal/libcrux_sha3_internal.h" -#include "internal/libcrux_core.h" #include "../libcrux_mlkem_portable.h" #include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "internal/libcrux_sha3_internal.h" extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U]; -#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) +#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / \ + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( - uint8_t *public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( - uint8_t *public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h new file mode 100644 index 000000000..405e13161 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -0,0 +1,38 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __internal_libcrux_sha3_avx2_H +#define __internal_libcrux_sha3_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_sha3_avx2.h" +#include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "intrinsics/libcrux_intrinsics_avx2.h" + +typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + libcrux_sha3_avx2_x4_incremental_KeccakState4; + +void libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]); + +void libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_sha3_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 2471ee04f..391656b64 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H @@ -16,70 +16,63 @@ extern "C" { #include "eurydice_glue.h" typedef libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_KeccakState1; + libcrux_sha3_portable_KeccakState1; static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_incremental_shake128_init(void) -{ - return - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); +libcrux_sha3_portable_incremental_shake128_init(void) { + return libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); } -static inline void -libcrux_sha3_portable_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice data0 -) -{ - Eurydice_slice buf[1U] = { data0 }; - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(s, buf); +static inline void libcrux_sha3_portable_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice data0) { + Eurydice_slice buf[1U] = {data0}; + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + s, buf); } static inline void libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -) -{ - Eurydice_slice buf[1U] = { out0 }; - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, buf); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, buf); } static inline void libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)168U); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o10, - (size_t)168U); + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o10, (size_t)168U); Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o2[1U]; - memcpy(o2, uu____1.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o1); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o2); + memcpy(o2, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o1); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o2); } static inline void libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -) -{ - Eurydice_slice buf[1U] = { out0 }; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t(s, buf); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( + s, buf); } #define libcrux_sha3_Sha224 0 @@ -89,191 +82,163 @@ libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( typedef uint8_t libcrux_sha3_Algorithm; -static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) -{ +static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { size_t uu____0; - switch (mode) - { - case libcrux_sha3_Sha224: - { - uu____0 = (size_t)28U; - break; - } - case libcrux_sha3_Sha256: - { - uu____0 = (size_t)32U; - break; - } - case libcrux_sha3_Sha384: - { - uu____0 = (size_t)48U; - break; - } - case libcrux_sha3_Sha512: - { - uu____0 = (size_t)64U; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); - KRML_HOST_EXIT(253U); - } + switch (mode) { + case libcrux_sha3_Sha224: { + uu____0 = (size_t)28U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = (size_t)32U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = (size_t)48U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = (size_t)64U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } } return uu____0; } -static const -size_t -libcrux_sha3_generic_keccak__PI[24U] = - { - (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, (size_t)9U, (size_t)10U, - (size_t)16U, (size_t)22U, (size_t)1U, (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, - (size_t)4U, (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, (size_t)8U, - (size_t)14U, (size_t)15U, (size_t)21U - }; +static const size_t libcrux_sha3_generic_keccak__PI[24U] = { + (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, + (size_t)9U, (size_t)10U, (size_t)16U, (size_t)22U, (size_t)1U, + (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, (size_t)4U, + (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, + (size_t)8U, (size_t)14U, (size_t)15U, (size_t)21U}; -static const -size_t -libcrux_sha3_generic_keccak__ROTC[24U] = - { - (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, (size_t)44U, (size_t)6U, - (size_t)55U, (size_t)20U, (size_t)3U, (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, - (size_t)41U, (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, (size_t)2U, - (size_t)61U, (size_t)56U, (size_t)14U - }; +static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { + (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, + (size_t)44U, (size_t)6U, (size_t)55U, (size_t)20U, (size_t)3U, + (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, (size_t)41U, + (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, + (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; static inline void libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)168U); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o10, - (size_t)168U); + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o10, (size_t)168U); Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o20[1U]; - memcpy(o20, uu____1.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o1); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o20, - (size_t)168U); + memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o1); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o20, (size_t)168U); Eurydice_slice o2[1U]; - memcpy(o2, uu____2.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o30[1U]; - memcpy(o30, uu____2.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o2); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o30, - (size_t)168U); + memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o2); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o30, (size_t)168U); Eurydice_slice o3[1U]; - memcpy(o3, uu____3.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o4[1U]; - memcpy(o4, uu____3.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o3); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o4); + memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o3); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o4); } static inline void libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -) -{ - Eurydice_slice buf[1U] = { out0 }; - libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t(s, buf); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + s, buf); } static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self) { return self[0U]; } static inline uint32_t libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( - libcrux_sha3_Algorithm v -) -{ + libcrux_sha3_Algorithm v) { uint32_t uu____0; - switch (v) - { - case libcrux_sha3_Sha224: - { - uu____0 = 1U; - break; - } - case libcrux_sha3_Sha256: - { - uu____0 = 2U; - break; - } - case libcrux_sha3_Sha384: - { - uu____0 = 3U; - break; - } - case libcrux_sha3_Sha512: - { - uu____0 = 4U; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); - KRML_HOST_EXIT(253U); - } + switch (v) { + case libcrux_sha3_Sha224: { + uu____0 = 1U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = 2U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = 3U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = 4U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } } return uu____0; } static inline libcrux_sha3_Algorithm -libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from(uint32_t v) -{ +libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from( + uint32_t v) { libcrux_sha3_Algorithm uu____0; - switch (v) - { - case 1U: - { - uu____0 = libcrux_sha3_Sha224; - break; - } - case 2U: - { - uu____0 = libcrux_sha3_Sha256; - break; - } - case 3U: - { - uu____0 = libcrux_sha3_Sha384; - break; - } - case 4U: - { - uu____0 = libcrux_sha3_Sha512; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); - } + switch (v) { + case 1U: { + uu____0 = libcrux_sha3_Sha224; + break; + } + case 2U: { + uu____0 = libcrux_sha3_Sha256; + break; + } + case 3U: { + uu____0 = libcrux_sha3_Sha384; + break; + } + case 4U: { + uu____0 = libcrux_sha3_Sha512; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); + } } return uu____0; } diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 8730222c6..b114068a3 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_core.h" @@ -11,457 +11,399 @@ typedef size_t RangeTo__size_t; typedef size_t RangeFrom__size_t; -typedef struct Option__int32_t_s -{ +typedef struct Option__int32_t_s { core_option_Option__size_t_tags tag; int32_t f0; -} -Option__int32_t; +} Option__int32_t; -typedef struct Option__uint32_t_s -{ +typedef struct Option__uint32_t_s { core_option_Option__size_t_tags tag; uint32_t f0; -} -Option__uint32_t; +} Option__uint32_t; -static uint8_t is_non_zero(uint8_t value) -{ +static uint8_t is_non_zero(uint8_t value) { uint16_t value0 = (uint16_t)value; uint16_t uu____0 = value0; - uint16_t - result = - (((uint32_t)uu____0 | (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & 0xFFFFU) - >> 8U - & 1U; + uint16_t result = (((uint32_t)uu____0 | + (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & + 0xFFFFU) >> + 8U & + 1U; return (uint8_t)result; } -void -libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - Eurydice_slice lhs, - Eurydice_slice rhs, - uint8_t selector, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, + uint8_t ret[32U]) { uint8_t mask = core_num__u8_6__wrapping_sub(is_non_zero(selector), 1U); - uint8_t out[32U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; i++) - { + uint8_t out[32U] = {0U}; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; + i++) { size_t i0 = i; - uint8_t - uu____0 = (uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t) & (uint32_t)mask; - uint8_t *uu____1 = &Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t); + uint8_t uu____0 = + (uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t) & + (uint32_t)mask; + uint8_t *uu____1 = + &Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t); out[i0] = (uint32_t)uu____0 | ((uint32_t)uu____1[0U] & (uint32_t)~mask); } - memcpy(ret, out, (size_t)32U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uint8_t value[1568U] -) -{ + uint8_t value[1568U]) { uint8_t uu____0[1568U]; - memcpy(uu____0, value, (size_t)1568U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)1568U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPublicKey____1568size_t lit; - memcpy(lit.value, uu____0, (size_t)1568U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)1568U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk -) -{ - return ((libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t){ .sk = sk, .pk = pk }); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk) { + return ((libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t){ + .sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____3168size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uint8_t value[3168U] -) -{ + uint8_t value[3168U]) { uint8_t uu____0[3168U]; - memcpy(uu____0, value, (size_t)3168U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)3168U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey____3168size_t lit; - memcpy(lit.value, uu____0, (size_t)3168U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)3168U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemCiphertext____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uint8_t value[1568U] -) -{ + uint8_t value[1568U]) { uint8_t uu____0[1568U]; - memcpy(uu____0, value, (size_t)1568U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)1568U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext____1568size_t lit; - memcpy(lit.value, uu____0, (size_t)1568U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)1568U * sizeof(uint8_t)); return lit; } -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self -) -{ +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *self) { return self->value; } uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -) -{ + Eurydice_slice lhs, Eurydice_slice rhs) { uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)1568U; i++) - { + for (size_t i = (size_t)0U; i < (size_t)1568U; i++) { size_t i0 = i; - uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = - (uint32_t)r - | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + uint8_t uu____0 = + Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = (uint32_t)r | + ((uint32_t)uu____0 ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); } return is_non_zero(r); } Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self -) -{ - return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t, Eurydice_slice); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self) { + return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t, + Eurydice_slice); } -void -libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, uint8_t ret[1600U]) -{ - uint8_t out[1600U] = { 0U }; +void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, + uint8_t ret[1600U]) { + uint8_t out[1600U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1600U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)1600U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1600U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)1600U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemPublicKey____1184size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uint8_t value[1184U] -) -{ + uint8_t value[1184U]) { uint8_t uu____0[1184U]; - memcpy(uu____0, value, (size_t)1184U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)1184U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPublicKey____1184size_t lit; - memcpy(lit.value, uu____0, (size_t)1184U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)1184U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk -) -{ - return ((libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t){ .sk = sk, .pk = pk }); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk) { + return ((libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t){ + .sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____2400size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uint8_t value[2400U] -) -{ + uint8_t value[2400U]) { uint8_t uu____0[2400U]; - memcpy(uu____0, value, (size_t)2400U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey____2400size_t lit; - memcpy(lit.value, uu____0, (size_t)2400U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)2400U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemCiphertext____1088size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uint8_t value[1088U] -) -{ + uint8_t value[1088U]) { uint8_t uu____0[1088U]; - memcpy(uu____0, value, (size_t)1088U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext____1088size_t lit; - memcpy(lit.value, uu____0, (size_t)1088U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)1088U * sizeof(uint8_t)); return lit; } -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self -) -{ +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self) { return self->value; } uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -) -{ + Eurydice_slice lhs, Eurydice_slice rhs) { uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)1088U; i++) - { + for (size_t i = (size_t)0U; i < (size_t)1088U; i++) { size_t i0 = i; - uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = - (uint32_t)r - | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + uint8_t uu____0 = + Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = (uint32_t)r | + ((uint32_t)uu____0 ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); } return is_non_zero(r); } Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self -) -{ - return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, Eurydice_slice); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self) { + return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, + Eurydice_slice); } -void -libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]) -{ - uint8_t out[1120U] = { 0U }; +void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]) { + uint8_t out[1120U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1120U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)1120U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1120U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemPublicKey____800size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uint8_t value[800U] -) -{ + uint8_t value[800U]) { uint8_t uu____0[800U]; - memcpy(uu____0, value, (size_t)800U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)800U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPublicKey____800size_t lit; - memcpy(lit.value, uu____0, (size_t)800U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)800U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, - libcrux_ml_kem_types_MlKemPublicKey____800size_t pk -) -{ - return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ .sk = sk, .pk = pk }); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____800size_t pk) { + return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ + .sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____1632size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uint8_t value[1632U] -) -{ + uint8_t value[1632U]) { uint8_t uu____0[1632U]; - memcpy(uu____0, value, (size_t)1632U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)1632U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey____1632size_t lit; - memcpy(lit.value, uu____0, (size_t)1632U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)1632U * sizeof(uint8_t)); return lit; } libcrux_ml_kem_types_MlKemCiphertext____768size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uint8_t value[768U] -) -{ + uint8_t value[768U]) { uint8_t uu____0[768U]; - memcpy(uu____0, value, (size_t)768U * sizeof (uint8_t)); + memcpy(uu____0, value, (size_t)768U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext____768size_t lit; - memcpy(lit.value, uu____0, (size_t)768U * sizeof (uint8_t)); + memcpy(lit.value, uu____0, (size_t)768U * sizeof(uint8_t)); return lit; } -uint8_t -*libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *self -) -{ +uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *self) { return self->value; } uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - Eurydice_slice lhs, - Eurydice_slice rhs -) -{ + Eurydice_slice lhs, Eurydice_slice rhs) { uint8_t r = 0U; - for (size_t i = (size_t)0U; i < (size_t)768U; i++) - { + for (size_t i = (size_t)0U; i < (size_t)768U; i++) { size_t i0 = i; - uint8_t uu____0 = Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); - r = - (uint32_t)r - | ((uint32_t)uu____0 ^ (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + uint8_t uu____0 = + Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = (uint32_t)r | + ((uint32_t)uu____0 ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); } return is_non_zero(r); } -void -libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]) -{ - uint8_t out[33U] = { 0U }; +void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, + uint8_t ret[33U]) { + uint8_t out[33U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)33U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)33U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]) -{ - uint8_t out[34U] = { 0U }; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)33U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, + uint8_t ret[34U]) { + uint8_t out[34U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)34U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)34U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)34U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)34U * sizeof(uint8_t)); } Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - libcrux_ml_kem_types_MlKemCiphertext____768size_t *self -) -{ - return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, Eurydice_slice); + libcrux_ml_kem_types_MlKemCiphertext____768size_t *self) { + return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t, + Eurydice_slice); } -void -libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, uint8_t ret[800U]) -{ - uint8_t out[800U] = { 0U }; +void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]) { + uint8_t out[800U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)800U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)800U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]) -{ - uint8_t out[64U] = { 0U }; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)800U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)800U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, + uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; uint8_t *uu____0 = out; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)64U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = core_slice___Slice_T___len(slice, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - slice, - uint8_t, - void *); - memcpy(ret, out, (size_t)64U * sizeof (uint8_t)); -} - -void -core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, - int16_t ret[16U] -) -{ - if (self.tag == core_result_Ok) - { - int16_t f0[16U]; - memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof (int16_t)); - memcpy(ret, f0, (size_t)16U * sizeof (int16_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)64U, uu____0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); +} + +void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, + uint8_t ret[24U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[24U]; + memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); } - else - { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "unwrap not Ok"); +} + +void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, + uint8_t ret[20U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[20U]; + memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); KRML_HOST_EXIT(255U); } } -void -core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U] -) -{ - if (self.tag == core_result_Ok) - { - uint8_t f0[8U]; - memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof (uint8_t)); - memcpy(ret, f0, (size_t)8U * sizeof (uint8_t)); +void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, + uint8_t ret[10U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[10U]; + memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); } - else - { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "unwrap not Ok"); +} + +void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, + int16_t ret[16U]) { + if (self.tag == core_result_Ok) { + int16_t f0[16U]; + memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t)); + memcpy(ret, f0, (size_t)16U * sizeof(int16_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); KRML_HOST_EXIT(255U); } } +void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, + uint8_t ret[8U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[8U]; + memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)8U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 0df3058ed..07f553e38 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_core_H @@ -14,12 +14,10 @@ extern "C" { #include "eurydice_glue.h" -typedef struct core_ops_range_Range__size_t_s -{ +typedef struct core_ops_range_Range__size_t_s { size_t start; size_t end; -} -core_ops_range_Range__size_t; +} core_ops_range_Range__size_t; extern uint8_t Eurydice_bitand_pv_u8(uint8_t *x, uint8_t y); @@ -30,142 +28,131 @@ extern uint8_t Eurydice_shr_pv_u8(uint8_t *x, int32_t y); typedef uint8_t core_option_Option__size_t_tags; -typedef struct core_option_Option__size_t_s -{ +typedef struct core_option_Option__size_t_s { core_option_Option__size_t_tags tag; size_t f0; -} -core_option_Option__size_t; +} core_option_Option__size_t; static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); -typedef struct libcrux_ml_kem_types_MlKemPublicKey____1568size_t_s { uint8_t value[1568U]; } -libcrux_ml_kem_types_MlKemPublicKey____1568size_t; +typedef struct libcrux_ml_kem_types_MlKemPublicKey____1568size_t_s { + uint8_t value[1568U]; +} libcrux_ml_kem_types_MlKemPublicKey____1568size_t; -typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t___s -{ +typedef struct + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t___s { core_option_Option__size_t_tags tag; libcrux_ml_kem_types_MlKemPublicKey____1568size_t f0; -} -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__; +} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__; -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____3168size_t_s { uint8_t value[3168U]; } -libcrux_ml_kem_types_MlKemPrivateKey____3168size_t; +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____3168size_t_s { + uint8_t value[3168U]; +} libcrux_ml_kem_types_MlKemPrivateKey____3168size_t; -typedef struct libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t_s -{ +typedef struct libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t_s { libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk; libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk; -} -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t; +} libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t; -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1568size_t_s { uint8_t value[1568U]; } -libcrux_ml_kem_types_MlKemCiphertext____1568size_t; +typedef struct libcrux_ml_kem_types_MlKemCiphertext____1568size_t_s { + uint8_t value[1568U]; +} libcrux_ml_kem_types_MlKemCiphertext____1568size_t; -typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t__s -{ +typedef struct + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t__s { libcrux_ml_kem_types_MlKemCiphertext____1568size_t fst; uint8_t snd[32U]; -} -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_; +} K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_; -typedef struct libcrux_ml_kem_types_MlKemPublicKey____1184size_t_s { uint8_t value[1184U]; } -libcrux_ml_kem_types_MlKemPublicKey____1184size_t; +typedef struct libcrux_ml_kem_types_MlKemPublicKey____1184size_t_s { + uint8_t value[1184U]; +} libcrux_ml_kem_types_MlKemPublicKey____1184size_t; -typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t___s -{ +typedef struct + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t___s { core_option_Option__size_t_tags tag; libcrux_ml_kem_types_MlKemPublicKey____1184size_t f0; -} -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__; +} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__; -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { uint8_t value[2400U]; } -libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { + uint8_t value[2400U]; +} libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; -typedef struct libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t_s -{ +typedef struct libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t_s { libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk; libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk; -} -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t; +} libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t; -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1088size_t_s { uint8_t value[1088U]; } -libcrux_ml_kem_types_MlKemCiphertext____1088size_t; +typedef struct libcrux_ml_kem_types_MlKemCiphertext____1088size_t_s { + uint8_t value[1088U]; +} libcrux_ml_kem_types_MlKemCiphertext____1088size_t; -typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s -{ +typedef struct + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s { libcrux_ml_kem_types_MlKemCiphertext____1088size_t fst; uint8_t snd[32U]; -} -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; +} K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; -typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { uint8_t value[800U]; } -libcrux_ml_kem_types_MlKemPublicKey____800size_t; +typedef struct libcrux_ml_kem_types_MlKemPublicKey____800size_t_s { + uint8_t value[800U]; +} libcrux_ml_kem_types_MlKemPublicKey____800size_t; -typedef struct core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s -{ +typedef struct + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t___s { core_option_Option__size_t_tags tag; libcrux_ml_kem_types_MlKemPublicKey____800size_t f0; -} -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; +} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__; -typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { uint8_t value[1632U]; } -libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____1632size_t_s { + uint8_t value[1632U]; +} libcrux_ml_kem_types_MlKemPrivateKey____1632size_t; -typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s -{ +typedef struct libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t_s { libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk; libcrux_ml_kem_types_MlKemPublicKey____800size_t pk; -} -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; +} libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t; -typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { uint8_t value[768U]; } -libcrux_ml_kem_types_MlKemCiphertext____768size_t; +typedef struct libcrux_ml_kem_types_MlKemCiphertext____768size_t_s { + uint8_t value[768U]; +} libcrux_ml_kem_types_MlKemCiphertext____768size_t; -typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s -{ +typedef struct + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t__s { libcrux_ml_kem_types_MlKemCiphertext____768size_t fst; uint8_t snd[32U]; -} -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; +} K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_; #define core_result_Ok 0 #define core_result_Err 1 -typedef uint8_t core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags; +typedef uint8_t + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags; -typedef struct core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s -{ - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; +typedef struct + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; union { uint8_t case_Ok[8U]; core_array_TryFromSliceError case_Err; - } - val; -} -core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; + } val; +} core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; -void -core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U] -); +void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, + uint8_t ret[8U]); -typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s -{ +typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s { Eurydice_slice fst; Eurydice_slice snd; -} -K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; +} K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; -typedef struct K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s -{ +typedef struct + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s { Eurydice_slice fst[1U]; Eurydice_slice snd[1U]; -} -K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; +} K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c index 806b58c57..e2cad594d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.c @@ -1,203 +1,154 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024.h" #include "internal/libcrux_core.h" -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - uu____0); - } - else if (libcrux_platform_platform_simd128_support()) - { - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - uu____0); - } - else - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } -void -libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_mlkem1024_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ uu____0; - if (libcrux_platform_platform_simd256_support()) - { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ + uu____0; + if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____1 = public_key; uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____1, - uu____2); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____3, - uu____4); - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + } else { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6); + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6); + return uu____0; } return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____1); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____1); + } else if (libcrux_platform_platform_simd128_support()) { uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____2); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____2); + } else { uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____3); + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____3); } return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); } -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -) -{ +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { bool uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); + } else if (libcrux_platform_platform_simd128_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t(public_key); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); + } else { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key); + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key); } return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None - } - ); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None}); } return uu____0; } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 8478e2e63..31fd6b6b2 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H @@ -12,89 +12,104 @@ extern "C" { #endif -#include "libcrux_platform.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_mlkem512_neon.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 ((size_t)11U) -#define LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 ((size_t)4U) -#define LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 * LIBCRUX_ML_KEM_MLKEM1024_RANK_1024) +#define LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_C1_BLOCK_SIZE_1024 * \ + LIBCRUX_ML_KEM_MLKEM1024_RANK_1024) #define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 ((size_t)5U) -#define LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM1024_VECTOR_V_COMPRESSION_FACTOR_1024 / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 + LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024) +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_C1_SIZE_1024 + \ + LIBCRUX_ML_KEM_MLKEM1024_C2_SIZE_1024) -#define LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 + (size_t)32U) +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_T_AS_NTT_ENCODED_SIZE_1024 + (size_t)32U) -#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM1024_ETA1 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM1024_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM1024_ETA1 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM1024_ETA1_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM1024_ETA1 * (size_t)64U) #define LIBCRUX_ML_KEM_MLKEM1024_ETA2 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM1024_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM1024_ETA2 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM1024_ETA2_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM1024_ETA2 * (size_t)64U) -#define LIBCRUX_ML_KEM_MLKEM1024_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024) +#define LIBCRUX_ML_KEM_MLKEM1024_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024) -#define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024 (LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +#define LIBCRUX_ML_KEM_MLKEM1024_SECRET_KEY_SIZE_1024 \ + (LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_SECRET_KEY_SIZE_1024 + \ + LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_PUBLIC_KEY_SIZE_1024 + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); -void -libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem1024_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c new file mode 100644 index 000000000..894a6e5aa --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -0,0 +1,55 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#include "libcrux_mlkem1024_avx2.h" + +void libcrux_ml_kem_mlkem1024_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h new file mode 100644 index 000000000..76826f781 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -0,0 +1,41 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_avx2_H +#define __libcrux_mlkem1024_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" + +void libcrux_ml_kem_mlkem1024_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c deleted file mode 100644 index b86a77759..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem1024_neon.h" - -void -libcrux_ml_kem_mlkem1024_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None - } - ); - } - return uu____0; -} - diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h deleted file mode 100644 index 73b4dfddf..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem1024_neon_H -#define __libcrux_mlkem1024_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_mlkem512_neon.h" -#include "libcrux_core.h" -#include "eurydice_glue.h" - -void -libcrux_ml_kem_mlkem1024_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem1024_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index 989347491..89def0e0e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,77 +1,55 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" -void -libcrux_ml_kem_mlkem1024_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_mlkem1024_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ libcrux_ml_kem_mlkem1024_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None - } - ); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None}); } return uu____0; } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 3b80960f2..889adcd1b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H @@ -12,30 +12,26 @@ extern "C" { #endif -#include "libcrux_mlkem512_portable.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_portable.h" -void -libcrux_ml_kem_mlkem1024_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem1024_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ libcrux_ml_kem_mlkem1024_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c index 30acdca01..89cd6e786 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512.c @@ -1,203 +1,153 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512.h" #include "internal/libcrux_core.h" -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - uu____0); - } - else if (libcrux_platform_platform_simd128_support()) - { - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - uu____0); - } - else - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } -void -libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_mlkem512_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ uu____0; - if (libcrux_platform_platform_simd256_support()) - { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ + uu____0; + if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____1 = public_key; uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____1, - uu____2); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____3, - uu____4); - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____3, uu____4); + } else { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, - uu____6); + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6); + return uu____0; } return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____1); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____1); + } else if (libcrux_platform_platform_simd128_support()) { uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____2); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____2); + } else { uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____3); + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____3); } return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); } -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -) -{ +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { bool uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + public_key); + } else if (libcrux_platform_platform_simd128_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t(public_key); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key); + } else { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key); + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key); } return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None - } - ); + if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None}); } return uu____0; } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 5141914df..9e99eb873 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_H @@ -12,89 +12,102 @@ extern "C" { #endif -#include "libcrux_platform.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_mlkem512_neon.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 ((size_t)10U) -#define LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM512_RANK_512 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 * LIBCRUX_ML_KEM_MLKEM512_RANK_512) +#define LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_C1_BLOCK_SIZE_512 * LIBCRUX_ML_KEM_MLKEM512_RANK_512) #define LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 ((size_t)4U) -#define LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM512_VECTOR_V_COMPRESSION_FACTOR_512 / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512) +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_C1_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_C2_SIZE_512) -#define LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 + (size_t)32U) +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_T_AS_NTT_ENCODED_SIZE_512 + (size_t)32U) -#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM512_ETA1 ((size_t)3U) -#define LIBCRUX_ML_KEM_MLKEM512_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM512_ETA1 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM512_ETA1_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM512_ETA1 * (size_t)64U) #define LIBCRUX_ML_KEM_MLKEM512_ETA2 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM512_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM512_ETA2 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM512_ETA2_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM512_ETA2 * (size_t)64U) -#define LIBCRUX_ML_KEM_MLKEM512_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512) +#define LIBCRUX_ML_KEM_MLKEM512_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512) -#define LIBCRUX_ML_KEM_MLKEM512_RANKED_BYTES_PER_RING_ELEMENT_512 (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM512_RANKED_BYTES_PER_RING_ELEMENT_512 \ + (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM512_SECRET_KEY_SIZE_512 (LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +#define LIBCRUX_ML_KEM_MLKEM512_SECRET_KEY_SIZE_512 \ + (LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_SECRET_KEY_SIZE_512 + \ + LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_PUBLIC_KEY_SIZE_512 + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); -void -libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem512_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c new file mode 100644 index 000000000..3ecf05aa4 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -0,0 +1,164 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#include "libcrux_mlkem512_avx2.h" + +#include "internal/libcrux_mlkem_avx2.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem512_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None}); + } + return uu____0; +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h new file mode 100644 index 000000000..ef22b8ed1 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -0,0 +1,91 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_avx2_H +#define __libcrux_mlkem512_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_mlkem512_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c deleted file mode 100644 index ee559d69b..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem512_neon.h" - -#include "internal/libcrux_mlkem_neon.h" - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_mlkem512_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, - uu____1); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, - uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); -} - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(public_key); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None - } - ); - } - return uu____0; -} - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(public_key); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(public_key); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h deleted file mode 100644 index dc33f9084..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem512_neon_H -#define __libcrux_mlkem512_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_core.h" -#include "eurydice_glue.h" - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); - -void -libcrux_ml_kem_mlkem512_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]); - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -); - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -); - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem512_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 1259ebf65..f19b1cfda 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,223 +1,164 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" #include "internal/libcrux_mlkem_portable.h" -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_mlkem512_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem512_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_portable_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem512_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); } -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(public_key); +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + public_key); } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None - } - ); + if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None}); } return uu____0; } -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(public_key); +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + public_key); } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -) -{ - return - libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(public_key); +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + public_key); } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); } +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 3e5778778..60635a57b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H @@ -12,98 +12,76 @@ extern "C" { #endif -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); -void -libcrux_ml_kem_mlkem512_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem512_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem512_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_mlkem512_portable_generate_key_pair(uint8_t randomness[64U]); -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -); - -bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); - -void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c index 7f07572a4..5e87a108d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768.c @@ -1,203 +1,154 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768.h" #include "internal/libcrux_core.h" -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - uu____0); - } - else if (libcrux_platform_platform_simd128_support()) - { - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - uu____0); - } - else - { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + if (libcrux_platform_platform_simd256_support()) { + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + } else if (libcrux_platform_platform_simd128_support()) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + } else { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, uu____0); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); return; } - memcpy(ret, uu____0, (size_t)32U * sizeof (uint8_t)); + memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); } -void -libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_mlkem768_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ uu____0; - if (libcrux_platform_platform_simd256_support()) - { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ + uu____0; + if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____1 = public_key; uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____1, - uu____2); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____1, uu____2); + } else if (libcrux_platform_platform_simd128_support()) { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____3, - uu____4); - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____3, uu____4); + } else { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6); + libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6); + return uu____0; } return uu____0; } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ + uint8_t randomness[64U]) { libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____1); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____1); + } else if (libcrux_platform_platform_simd128_support()) { uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____2); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____2); + } else { uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____3); + libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____3); } return uu____0; } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); } -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -) -{ +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { bool uu____0; - if (libcrux_platform_platform_simd256_support()) - { + if (libcrux_platform_platform_simd256_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key); - } - else if (libcrux_platform_platform_simd128_support()) - { + libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); + } else if (libcrux_platform_platform_simd128_support()) { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t(public_key); - return uu____0; - } - else - { + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); + } else { uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key); + libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key); } return uu____0; } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None - } - ); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); } return uu____0; } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index aa62f65ff..7916e6736 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_H @@ -12,89 +12,102 @@ extern "C" { #endif -#include "libcrux_platform.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_mlkem512_neon.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" +#include "libcrux_mlkem512_portable.h" +#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) -#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) -#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) +#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) #define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) -#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) -#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) #define LIBCRUX_ML_KEM_MLKEM768_ETA2 ((size_t)2U) -#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) +#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) -#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) +#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) -#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) +#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void -libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); -void -libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem768_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -); + uint8_t randomness[64U]); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); -bool -libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key -); +bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c new file mode 100644 index 000000000..cccf06957 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -0,0 +1,55 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#include "libcrux_mlkem768_avx2.h" + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h new file mode 100644 index 000000000..e15872cb4 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -0,0 +1,41 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_avx2_H +#define __libcrux_mlkem768_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c deleted file mode 100644 index c9dd6730d..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem768_neon.h" - -void -libcrux_ml_kem_mlkem768_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]) -{ - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None - } - ); - } - return uu____0; -} - diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h deleted file mode 100644 index 4edf95c59..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_neon_H -#define __libcrux_mlkem768_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_mlkem512_neon.h" -#include "libcrux_core.h" -#include "eurydice_glue.h" - -void -libcrux_ml_kem_mlkem768_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index e0363174d..0ef5f5d17 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,77 +1,55 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" -void -libcrux_ml_kem_mlkem768_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ +void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t(private_key, - ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____0, - uu____1); + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) -{ +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof (uint8_t)); - return - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t(uu____0); + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); } core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -) -{ - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ uu____0; - if - ( - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t(public_key.value) - ) - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, - .f0 = public_key - } - ); - } - else - { - uu____0 = - ( - (core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None - } - ); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); } return uu____0; } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index d5b0efcba..78ac0fdb0 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H @@ -12,30 +12,26 @@ extern "C" { #endif -#include "libcrux_mlkem512_portable.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_portable.h" -void -libcrux_ml_kem_mlkem768_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -); +void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ libcrux_ml_kem_mlkem768_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key -); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c new file mode 100644 index 000000000..21208bcad --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -0,0 +1,7623 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#include "internal/libcrux_mlkem_avx2.h" + +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_sha3_avx2.h" + +typedef core_core_arch_x86___m256i SIMD256Vector; + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void) { + return libcrux_intrinsics_avx2_mm256_setzero_si256(); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( + void) { + return libcrux_ml_kem_vector_avx2_zero(); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_slice array) { + return libcrux_intrinsics_avx2_mm256_loadu_si256_i16(array); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice array) { + return libcrux_ml_kem_vector_avx2_from_i16_array(array); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_add(lhs, rhs[0U]); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_sub_epi16(lhs, rhs); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_sub(lhs, rhs[0U]); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + core_core_arch_x86___m256i v, int16_t c) { + return libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant(v, c); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + vector, constant); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i v_minus_field_modulus = + libcrux_intrinsics_avx2_mm256_sub_epi16(vector, field_modulus); + core_core_arch_x86___m256i sign_mask = + libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, v_minus_field_modulus, core_core_arch_x86___m256i); + core_core_arch_x86___m256i conditional_add_field_modulus = + libcrux_intrinsics_avx2_mm256_and_si256(sign_mask, field_modulus); + return libcrux_intrinsics_avx2_mm256_add_epi16(v_minus_field_modulus, + conditional_add_field_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329(vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i t = libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER)); + core_core_arch_x86___m256i uu____1 = t; + core_core_arch_x86___m256i t0 = libcrux_intrinsics_avx2_mm256_add_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16((int16_t)512)); + core_core_arch_x86___m256i quotient = + libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)10, t0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = quotient; + core_core_arch_x86___m256i quotient_times_field_modulus = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + return libcrux_intrinsics_avx2_mm256_sub_epi16(vector, + quotient_times_field_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i constant0 = + libcrux_intrinsics_avx2_mm256_set1_epi16(constant); + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(vector, constant0); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(vector, constant0); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + vector, constant); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)2); + core_core_arch_x86___m256i field_modulus_quartered = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)4); + core_core_arch_x86___m256i shifted = + libcrux_intrinsics_avx2_mm256_sub_epi16(field_modulus_halved, vector); + core_core_arch_x86___m256i mask = libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, shifted, core_core_arch_x86___m256i); + core_core_arch_x86___m256i shifted_to_positive = + libcrux_intrinsics_avx2_mm256_xor_si256(mask, shifted); + core_core_arch_x86___m256i shifted_to_positive_in_range = + libcrux_intrinsics_avx2_mm256_sub_epi16(shifted_to_positive, + field_modulus_quartered); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, shifted_to_positive_in_range, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + core_core_arch_x86___m256i prod02 = + libcrux_intrinsics_avx2_mm256_mul_epu32(lhs, rhs); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi32((int32_t)245, lhs, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i prod13 = libcrux_intrinsics_avx2_mm256_mul_epu32( + uu____0, libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, rhs, core_core_arch_x86___m256i)); + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi32(prod02, prod13); + return libcrux_intrinsics_avx2_mm256_unpackhi_epi64( + uu____1, libcrux_intrinsics_avx2_mm256_unpackhi_epi32(prod02, prod13)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + core_core_arch_x86___m256i v, core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(v, c); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta3, -zeta3, zeta3, zeta3, -zeta2, -zeta2, zeta2, zeta2, -zeta1, + -zeta1, zeta1, zeta1, -zeta0, -zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step(vector, zeta0, zeta1, + zeta2, zeta3); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta1, -zeta1, -zeta1, -zeta1, zeta1, zeta1, zeta1, zeta1, -zeta0, + -zeta0, -zeta0, -zeta0, zeta0, zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)238, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)68, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step(vector, zeta0, zeta1); +} + +inline core_core_arch_x86___m128i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + core_core_arch_x86___m128i v, core_core_arch_x86___m128i c) { + core_core_arch_x86___m128i value_low = + libcrux_intrinsics_avx2_mm_mullo_epi16(v, c); + core_core_arch_x86___m128i uu____0 = value_low; + core_core_arch_x86___m128i k = libcrux_intrinsics_avx2_mm_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m128i uu____1 = k; + core_core_arch_x86___m128i k_times_modulus = + libcrux_intrinsics_avx2_mm_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m128i value_high = + libcrux_intrinsics_avx2_mm_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm_sub_epi16(value_high, k_times_modulus); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i uu____0 = rhs; + core_core_arch_x86___m128i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs0); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs0); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients, core_core_arch_x86___m256i); + return combined0; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step(vector, zeta); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum0 = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum0; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta3, zeta3, (int16_t)0, (int16_t)0, zeta2, zeta2, + (int16_t)0, (int16_t)0, zeta1, zeta1, (int16_t)0, + (int16_t)0, zeta0, zeta0, (int16_t)0, (int16_t)0)); + core_core_arch_x86___m256i sum = + libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(sum0); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)204, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + vector, zeta0, zeta1, zeta2, zeta3); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i lhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)-1, + (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)-1, + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)1, + (int16_t)1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta1, zeta1, zeta1, zeta1, (int16_t)0, (int16_t)0, + (int16_t)0, (int16_t)0, zeta0, zeta0, zeta0, zeta0, + (int16_t)0, (int16_t)0, (int16_t)0, (int16_t)0)); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)240, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step(vector, zeta0, + zeta1); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs); + core_core_arch_x86___m128i uu____0 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients0, + core_core_arch_x86___m256i); + return combined0; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step(vector, zeta); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + core_core_arch_x86___m256i v) { + core_core_arch_x86___m256i uu____0 = v; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)16, v, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i result = + libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); + core_core_arch_x86___m256i result0 = libcrux_intrinsics_avx2_mm256_slli_epi32( + (int32_t)16, result, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_srai_epi32((int32_t)16, result0, + core_core_arch_x86___m256i); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i shuffle_with = + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, + (int8_t)5, (int8_t)4, (int8_t)1, (int8_t)0, (int8_t)15, (int8_t)14, + (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, (int8_t)3, (int8_t)2, + (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, + (int8_t)1, (int8_t)0); + core_core_arch_x86___m256i lhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(lhs, shuffle_with); + core_core_arch_x86___m256i lhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, lhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lhs_shuffled0); + core_core_arch_x86___m256i lhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_evens); + core_core_arch_x86___m128i lhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i lhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_odds); + core_core_arch_x86___m256i rhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(rhs, shuffle_with); + core_core_arch_x86___m256i rhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, rhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i rhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(rhs_shuffled0); + core_core_arch_x86___m256i rhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_evens); + core_core_arch_x86___m128i rhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, rhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i rhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_odds); + core_core_arch_x86___m256i left = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_evens0, rhs_evens0); + core_core_arch_x86___m256i right = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_odds0, rhs_odds0); + core_core_arch_x86___m256i right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s(right); + core_core_arch_x86___m256i uu____0 = right0; + core_core_arch_x86___m256i right1 = libcrux_intrinsics_avx2_mm256_mullo_epi32( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi32( + -(int32_t)zeta3, (int32_t)zeta3, -(int32_t)zeta2, (int32_t)zeta2, + -(int32_t)zeta1, (int32_t)zeta1, -(int32_t)zeta0, (int32_t)zeta0)); + core_core_arch_x86___m256i products_left = + libcrux_intrinsics_avx2_mm256_add_epi32(left, right1); + core_core_arch_x86___m256i products_left0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_left); + core_core_arch_x86___m256i uu____1 = rhs; + core_core_arch_x86___m256i rhs_adjacent_swapped = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)13, (int8_t)12, (int8_t)15, (int8_t)14, + (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, (int8_t)5, + (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, (int8_t)0, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)15, + (int8_t)14, (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, + (int8_t)5, (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, + (int8_t)0, (int8_t)3, (int8_t)2)); + core_core_arch_x86___m256i products_right = + libcrux_intrinsics_avx2_mm256_madd_epi16(lhs, rhs_adjacent_swapped); + core_core_arch_x86___m256i products_right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_right); + core_core_arch_x86___m256i products_right1 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)16, products_right0, + core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_blend_epi16((int32_t)170, products_left0, + products_right1, + core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(lhs[0U], rhs[0U], zeta0, + zeta1, zeta2, zeta3); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + core_core_arch_x86___m256i lsb_to_msb = + libcrux_intrinsics_avx2_mm256_slli_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i low_msbs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lsb_to_msb); + core_core_arch_x86___m128i high_msbs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lsb_to_msb, core_core_arch_x86___m128i); + core_core_arch_x86___m128i msbs = + libcrux_intrinsics_avx2_mm_packs_epi16(low_msbs, high_msbs); + int32_t bits_packed = libcrux_intrinsics_avx2_mm_movemask_epi8(msbs); + uint8_t serialized[2U] = {0U}; + serialized[0U] = (uint8_t)bits_packed; + serialized[1U] = (uint8_t)(bits_packed >> 8U); + memcpy(ret, serialized, (size_t)2U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(vector, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_1(Eurydice_slice bytes) { + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i shift_lsb_to_msb = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 8U, (int16_t)1 << 9U, (int16_t)1 << 10U, + (int16_t)1 << 11U, (int16_t)1 << 12U, (int16_t)1 << 13U, + (int16_t)1 << 14U, (int16_t)1 << 15U, (int16_t)1 << 8U, + (int16_t)1 << 9U, (int16_t)1 << 10U, (int16_t)1 << 11U, + (int16_t)1 << 12U, (int16_t)1 << 13U, (int16_t)1 << 14U, + (int16_t)1 << 15U); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsb_to_msb); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, coefficients_in_msb, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_1(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t serialized[16U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, (int8_t)4, + (int8_t)0, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, + (int8_t)4, (int8_t)0)); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0, + (int32_t)0, (int32_t)0, (int32_t)4, (int32_t)0)); + core_core_arch_x86___m128i combined0 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(combined); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_slice((size_t)16U, serialized, uint8_t, Eurydice_slice), + combined0); + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)16U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_4(vector, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients_in_lsb = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients_in_msb, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_in_lsb; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____15, libcrux_intrinsics_avx2_mm256_set1_epi16(((int16_t)1 << 4U) - + (int16_t)1)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_4(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22, + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)22, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)8, adjacent_4_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i adjacent_8_combined0 = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_8_combined1 = + libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)5U, .end = (size_t)21U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[10U]; + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[10U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t ret0[10U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_5(vector, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_5(Eurydice_slice bytes) { + uint8_t uu____0 = + Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____1 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____2 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____3 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____4 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____5 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____6 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____7 = + Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____8 = + Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____9 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____10 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____11 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____12 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____13 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____14 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + core_core_arch_x86___m128i coefficients = libcrux_intrinsics_avx2_mm_set_epi8( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, uu____14, + Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); + core_core_arch_x86___m256i coefficients_loaded = + libcrux_intrinsics_avx2_mm256_castsi128_si256(coefficients); + core_core_arch_x86___m256i coefficients_loaded0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients_loaded, coefficients, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_loaded0; + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____15, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)15, (int8_t)14, (int8_t)13, + (int8_t)12, (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)9, + (int8_t)8, (int8_t)7, (int8_t)6, (int8_t)7, (int8_t)6, (int8_t)5, + (int8_t)4, (int8_t)5, (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m256i uu____16 = coefficients0; + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____16, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 5U, (int16_t)1 << 2U, + (int16_t)1 << 7U, (int16_t)1 << 4U, (int16_t)1 << 9U, + (int16_t)1 << 6U, (int16_t)1 << 11U, (int16_t)1 << 0U, + (int16_t)1 << 5U, (int16_t)1 << 2U, (int16_t)1 << 7U, + (int16_t)1 << 4U, (int16_t)1 << 9U, (int16_t)1 << 6U, + (int16_t)1 << 11U)); + return libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)11, coefficients1, + core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_5(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)12, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)11, + (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)12, (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)10U, .end = (size_t)26U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[20U]; + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[20U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_10(vector, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U, (int16_t)1 << 0U, (int16_t)1 << 2U, + (int16_t)1 << 4U, (int16_t)1 << 6U, (int16_t)1 << 0U, + (int16_t)1 << 2U, (int16_t)1 << 4U, (int16_t)1 << 6U, + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(9U, 8U, 8U, 7U, 7U, 6U, 6U, 5U, + 4U, 3U, 3U, 2U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)4U, + .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 13U, + 12U, 12U, 11U, 10U, 9U, + 9U, 8U, 8U, 7U, 7U, 6U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)6, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 10U) - (int16_t)1)); + return coefficients3; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_10(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_to_i16_array( + core_core_arch_x86___m256i v, int16_t ret[16U]) { + int16_t output[16U] = {0U}; + libcrux_intrinsics_avx2_mm256_storeu_si256_i16( + Eurydice_array_to_slice((size_t)16U, output, int16_t, Eurydice_slice), v); + memcpy(ret, output, (size_t)16U * sizeof(int16_t)); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]) { + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + memcpy(lit.elements, uu____0, (size_t)16U * sizeof(int16_t)); + return lit; +} + +inline void libcrux_ml_kem_vector_avx2_portable_serialize_11( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]) { + uint8_t result[22U] = {0U}; + result[0U] = (uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); + result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | + (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | + (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); + result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | + (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[10U] = (uint8_t)(v.elements[7U] >> 3U); + result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + result[15U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + result[19U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + result[20U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + int16_t array[16U]; + libcrux_ml_kem_vector_avx2_to_i16_array(vector, array); + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector input = + libcrux_ml_kem_vector_avx2_portable_from_i16_array(uu____0); + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_portable_serialize_11(input, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_11(vector, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_zero(void) { + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector result = + libcrux_ml_kem_vector_avx2_portable_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____5 = + uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; + int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; + int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; + int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____12 = + uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) + << 1U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; + int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; + int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____17 = + &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; + int16_t uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____23 = + uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; + int16_t uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; + int16_t uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; + int16_t uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____30 = + uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, + uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; + int16_t uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; + int16_t uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, + uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; + return result; +} + +inline void libcrux_ml_kem_vector_avx2_portable_to_i16_array( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]) { + memcpy(ret, v.elements, (size_t)16U * sizeof(int16_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector output = + libcrux_ml_kem_vector_avx2_portable_deserialize_11(bytes); + int16_t ret[16U]; + libcrux_ml_kem_vector_avx2_portable_to_i16_array(output, ret); + return libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_array_to_slice((size_t)16U, ret, int16_t, Eurydice_slice)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_11(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8, + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)13, (int8_t)12, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)5, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)12U, .end = (size_t)28U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[24U]; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[24U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_12(vector, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(11U, 10U, 10U, 9U, 8U, 7U, 7U, 6U, + 5U, 4U, 4U, 3U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 12U, + 11U, 11U, 10U, 9U, 8U, + 8U, 7U, 6U, 5U, 5U, 4U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 12U) - (int16_t)1)); + return coefficients3; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_12(bytes); +} + +inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( + Eurydice_slice input, Eurydice_slice output) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i potential_coefficients = + libcrux_ml_kem_vector_avx2_serialize_deserialize_12(input); + core_core_arch_x86___m256i compare_with_field_modulus = + libcrux_intrinsics_avx2_mm256_cmpgt_epi16(field_modulus, + potential_coefficients); + uint8_t good[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(compare_with_field_modulus, + good); + uint8_t lower_shuffles[16U]; + memcpy(lower_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[0U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i lower_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, lower_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm256_castsi256_si128(potential_coefficients); + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(lower_coefficients, + lower_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128(output, lower_coefficients0); + size_t sampled_count = (size_t)core_num__u8_6__count_ones(good[0U]); + uint8_t upper_shuffles[16U]; + memcpy(upper_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[1U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i upper_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, upper_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, potential_coefficients, core_core_arch_x86___m128i); + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(upper_coefficients, + upper_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128( + Eurydice_slice_subslice( + output, + ((core_ops_range_Range__size_t){.start = sampled_count, + .end = sampled_count + (size_t)8U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice), + upper_coefficients0); + size_t uu____0 = sampled_count; + return uu____0 + (size_t)core_num__u8_6__count_ones(good[1U]); +} + +size_t +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + Eurydice_slice input, Eurydice_slice output) { + return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( + libcrux_ml_kem_vector_avx2_portable_PortableVector *self) { + return self[0U]; +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( + core_core_arch_x86___m256i *self) { + return self[0U]; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline core_core_arch_x86___m256i shift_right___15int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i shift_right___15int32_t0( + core_core_arch_x86___m256i vector) { + return shift_right___15int32_t(vector); +} + +static core_core_arch_x86___m256i +to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a) { + core_core_arch_x86___m256i t = shift_right___15int32_t0(a); + core_core_arch_x86___m256i fm = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &fm); +} + +static inline void +serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1536U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1568U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[4U]; + memcpy( + uu____1, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[4U]; + memcpy( + uu____0, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 Simd256Hash; + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___4size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___4size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], + uint8_t(*)[168U], uint8_t[168U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice_subslice( + a, + ((core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U][4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[4U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____9 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +static inline void ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + core_core_arch_x86___m256i t = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +typedef struct + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i fst; + core_core_arch_x86___m256i snd; +} __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector; + +static core_core_arch_x86___m256i +montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v, int16_t fer) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, fer); +} + +static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i t = + montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector(b, + zeta_r); + b = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + a, &t); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &t); + return (( + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +static inline void +ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); + size_t zeta_i = (size_t)1U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[4U]; + memcpy( + uu____2, re_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + out = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static core_core_arch_x86___m256i +to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + self->coefficients[j]); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___4size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[4U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[4U]; + memcpy( + uu____4, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[4U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)3168U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___4size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[4U]; + memcpy( + uu____2, error_1, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___4size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i a_minus_b = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + b, &a); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &b)); + b = montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_minus_b, zeta_r); + return (( + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +static inline void +invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static core_core_arch_x86___m256i +decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i uu____0 = + decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i tmp = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &message->coefficients[i0]); + core_core_arch_x86___m256i tmp0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &tmp); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___10int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)10) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___10int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___10int32_t(vector); +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___10int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___11int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)11) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___11int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___11int32_t(vector); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___11int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[352U]) { + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[4U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___4int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)4) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___4int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___4int32_t(vector); +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___4int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___5int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)5) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___5int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___5int32_t(vector); +} + +static inline void +compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficients = compress___5int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice out) { + compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1568U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[4U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[4U]; + memcpy( + error_1, uu____3.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___4size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1568U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[4U]; + memcpy( + uu____5, u, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1408U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___4size_t( + Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___10int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)10); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i +decompress_ciphertext_coefficient___10int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___10int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___10int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___11int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)11); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i +decompress_ciphertext_coefficient___11int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___11int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___11int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___4int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)4); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i decompress_ciphertext_coefficient___4int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___4int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___4int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___5int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)5); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i decompress_ciphertext_coefficient___5int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___5int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + core_core_arch_x86___m256i uu____1 = + decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + self->coefficients[i0], &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static inline void +compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0]); + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1536U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1568U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[3U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, + Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___10int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___11int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice out) { + compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[2U], + uint8_t ret[768U]) { + uint8_t out[768U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)768U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U], + Eurydice_slice seed_for_a, uint8_t ret[800U]) { + uint8_t public_key_serialized[800U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)800U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[2U]; + memcpy( + uu____1, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, + (size_t)768U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( + Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[2U]; + memcpy( + uu____0, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___2size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[2U][504U]) { + uint8_t out[2U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; + uint8_t dummy_out1[504U] = {0U}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + uint8_t randomness[2U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___2size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[2U][168U]) { + uint8_t out[2U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; + uint8_t dummy_out1[168U] = {0U}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uint8_t randomness[2U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + size_t sampled_coefficients[2U] = {0U}; + int16_t out[2U][272U] = {{0U}}; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U][2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[2U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], + uint8_t ret[2U][192U]) { + uint8_t out[2U][192U] = {{0U}}; + uint8_t dummy_out0[192U] = {0U}; + uint8_t dummy_out1[192U] = {0U}; + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], + Eurydice_slice), + (size_t)1U, uint8_t[192U], + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[2U]; + memcpy( + uu____2, re_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___2size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[2U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____3, domain_separator) + .fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[2U]; + memcpy( + uu____4, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[2U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); + return lit; +} + +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)1632U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___2size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( + uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[2U][128U]) { + uint8_t out[2U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; + uint8_t dummy_out1[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[2U]; + memcpy( + uu____2, error_1, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___2size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t0(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[2U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[768U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( + Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[2U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[2U]; + memcpy( + error_1, uu____3.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___2size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[768U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[2U]; + memcpy( + uu____5, u, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)640U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___2size_t( + Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t1(void) { + return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, + (size_t)640U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)768U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)800U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___2size_t_32size_t( + Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h new file mode 100644 index 000000000..e4349f2b1 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -0,0 +1,294 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 + */ + +#ifndef __libcrux_mlkem_avx2_H +#define __libcrux_mlkem_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem_portable.h" +#include "libcrux_sha3.h" +#include "libcrux_sha3_avx2.h" + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( + void); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_slice array); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice array); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + core_core_arch_x86___m256i v, int16_t c); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + core_core_arch_x86___m256i vector); + +#define LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER \ + ((int16_t)20159) + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + core_core_arch_x86___m256i v, core_core_arch_x86___m256i c); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m128i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + core_core_arch_x86___m128i v, core_core_arch_x86___m128i c); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + core_core_arch_x86___m256i v); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_1( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_4( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_5( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_10( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_to_i16_array(core_core_arch_x86___m256i v, + int16_t ret[16U]); + +typedef struct libcrux_ml_kem_vector_avx2_portable_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_avx2_portable_PortableVector; + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]); + +void libcrux_ml_kem_vector_avx2_portable_serialize_11( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_zero(void); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_portable_to_i16_array( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_11( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_12( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + Eurydice_slice bytes); + +size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( + Eurydice_slice input, Eurydice_slice output); + +size_t +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + Eurydice_slice input, Eurydice_slice output); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( + libcrux_ml_kem_vector_avx2_portable_PortableVector *self); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( + core_core_arch_x86___m256i *self); + +typedef struct + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.c b/libcrux-ml-kem/c/libcrux_mlkem_neon.c deleted file mode 100644 index c7a62ef71..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.c +++ /dev/null @@ -1,9690 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_mlkem_neon.h" - -#include "internal/libcrux_mlkem_portable.h" -#include "internal/libcrux_core.h" - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ZERO(void) -{ - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0); - return - ( - (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, - .high = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0) - } - ); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( - void -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_ZERO(); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array) -{ - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice(array, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - return - ( - (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, - .high = libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice(array, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)) - } - ); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( - Eurydice_slice array -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(array); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -) -{ - lhs.low = libcrux_intrinsics_arm64__vaddq_s16(lhs.low, rhs->low); - lhs.high = libcrux_intrinsics_arm64__vaddq_s16(lhs.high, rhs->high); - return lhs; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_add(lhs, rhs); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -) -{ - lhs.low = libcrux_intrinsics_arm64__vsubq_s16(lhs.low, rhs->low); - lhs.high = libcrux_intrinsics_arm64__vsubq_s16(lhs.high, rhs->high); - return lhs; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_sub(lhs, rhs); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - v.low = libcrux_intrinsics_arm64__vmulq_n_s16(v.low, c); - v.high = libcrux_intrinsics_arm64__vmulq_n_s16(v.high, c); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant(v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - core_core_arch_arm_shared_neon_int16x8_t c0 = libcrux_intrinsics_arm64__vdupq_n_s16(c); - v.low = libcrux_intrinsics_arm64__vandq_s16(v.low, c0); - v.high = libcrux_intrinsics_arm64__vandq_s16(v.high, c0); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant(v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_int16x8_t - c = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)3329); - core_core_arch_arm_shared_neon_uint16x8_t m0 = libcrux_intrinsics_arm64__vcgeq_s16(v.low, c); - core_core_arch_arm_shared_neon_uint16x8_t m1 = libcrux_intrinsics_arm64__vcgeq_s16(v.high, c); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = c; - core_core_arch_arm_shared_neon_int16x8_t - c0 = - libcrux_intrinsics_arm64__vandq_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m0)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = c; - core_core_arch_arm_shared_neon_int16x8_t - c1 = - libcrux_intrinsics_arm64__vandq_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m1)); - v.low = libcrux_intrinsics_arm64__vsubq_s16(v.low, c0); - v.high = libcrux_intrinsics_arm64__vsubq_s16(v.high, c1); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329(v); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v -) -{ - core_core_arch_arm_shared_neon_int16x8_t - adder = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1024); - core_core_arch_arm_shared_neon_int16x8_t - vec = - libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, - LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER); - core_core_arch_arm_shared_neon_int16x8_t - vec0 = libcrux_intrinsics_arm64__vaddq_s16(vec, adder); - core_core_arch_arm_shared_neon_int16x8_t - quotient = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)11, - vec0, - core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t - sub = - libcrux_intrinsics_arm64__vmulq_n_s16(quotient, - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_intrinsics_arm64__vsubq_s16(v, sub); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - v.low = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.low); - v.high = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.high); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce(v); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t low, - core_core_arch_arm_shared_neon_int16x8_t high -) -{ - core_core_arch_arm_shared_neon_int16x8_t - k = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vmulq_n_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(low), - (uint16_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_arm_shared_neon_int16x8_t - c = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, - libcrux_intrinsics_arm64__vqdmulhq_n_s16(k, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_intrinsics_arm64__vsubq_s16(high, c); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - int16_t c -) -{ - core_core_arch_arm_shared_neon_int16x8_t v_low = libcrux_intrinsics_arm64__vmulq_n_s16(v, c); - core_core_arch_arm_shared_neon_int16x8_t - v_high = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, - libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, c), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(v_low, v_high); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - v.low = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t(v.low, - c); - v.high = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t(v.high, - c); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant(v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_int16x8_t - half = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1664); - core_core_arch_arm_shared_neon_int16x8_t - quarter = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)832); - core_core_arch_arm_shared_neon_int16x8_t - shifted = libcrux_intrinsics_arm64__vsubq_s16(half, v.low); - core_core_arch_arm_shared_neon_int16x8_t - mask0 = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, - shifted, - core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t - shifted_to_positive = libcrux_intrinsics_arm64__veorq_s16(mask0, shifted); - core_core_arch_arm_shared_neon_int16x8_t - shifted_positive_in_range = libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive, quarter); - v.low = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vshrq_n_u16((int32_t)15, - libcrux_intrinsics_arm64__vreinterpretq_u16_s16(shifted_positive_in_range), - core_core_arch_arm_shared_neon_uint16x8_t)); - core_core_arch_arm_shared_neon_int16x8_t - shifted0 = libcrux_intrinsics_arm64__vsubq_s16(half, v.high); - core_core_arch_arm_shared_neon_int16x8_t - mask = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, - shifted0, - core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t - shifted_to_positive0 = libcrux_intrinsics_arm64__veorq_s16(mask, shifted0); - core_core_arch_arm_shared_neon_int16x8_t - shifted_positive_in_range0 = libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive0, quarter); - v.high = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vshrq_n_u16((int32_t)15, - libcrux_intrinsics_arm64__vreinterpretq_u16_s16(shifted_positive_in_range0), - core_core_arch_arm_shared_neon_uint16x8_t)); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_compress_1(v); -} - -inline int16_t -libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits(int16_t coefficient_bits) -{ - int16_t uu____0; - switch (coefficient_bits) - { - case 4: - { - uu____0 = (int16_t)15; - break; - } - case 5: - { - uu____0 = (int16_t)31; - break; - } - case 10: - { - uu____0 = (int16_t)1023; - break; - } - case 11: - { - uu____0 = (int16_t)2047; - break; - } - default: - { - int16_t x = coefficient_bits; - uu____0 = ((int16_t)1 << (uint32_t)x) - (int16_t)1; - } - } - return uu____0; -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - core_core_arch_arm_shared_neon_int16x8_t c -) -{ - core_core_arch_arm_shared_neon_int16x8_t v_low = libcrux_intrinsics_arm64__vmulq_s16(v, c); - core_core_arch_arm_shared_neon_int16x8_t - v_high = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)1, - libcrux_intrinsics_arm64__vqdmulhq_s16(v, c), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(v_low, v_high); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - int16_t zetas[8U] = { zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4 }; - core_core_arch_arm_shared_neon_int16x8_t - zeta = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - zetas, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int32x4_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - dup_a = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int32x4_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - dup_b = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t - t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, zeta); - core_core_arch_arm_shared_neon_int16x8_t b = libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int32x4_t - uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); - v.low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____2, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - core_core_arch_arm_shared_neon_int32x4_t - uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); - v.high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____3, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step(a, zeta1, zeta2, zeta3, zeta4); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2 -) -{ - int16_t zetas[8U] = { zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2 }; - core_core_arch_arm_shared_neon_int16x8_t - zeta = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - zetas, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int64x2_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - dup_a = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int64x2_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - dup_b = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t - t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, zeta); - core_core_arch_arm_shared_neon_int16x8_t b = libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int64x2_t - uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____2, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - core_core_arch_arm_shared_neon_int64x2_t - uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____3, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2 -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step(a, zeta1, zeta2); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta -) -{ - core_core_arch_arm_shared_neon_int16x8_t zeta0 = libcrux_intrinsics_arm64__vdupq_n_s16(zeta); - core_core_arch_arm_shared_neon_int16x8_t - t = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(v.high, zeta0); - v.high = libcrux_intrinsics_arm64__vsubq_s16(v.low, t); - v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, t); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step(a, zeta); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - int16_t zetas[8U] = { zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4 }; - core_core_arch_arm_shared_neon_int16x8_t - zeta = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - zetas, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int32x4_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - a0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int32x4_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - b0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t - b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(b0, a0); - core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(a0, b0); - core_core_arch_arm_shared_neon_int16x8_t - a1 = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(a); - core_core_arch_arm_shared_neon_int16x8_t - b = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta); - core_core_arch_arm_shared_neon_int32x4_t - uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); - v.low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(uu____2, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - core_core_arch_arm_shared_neon_int32x4_t - uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); - v.high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(uu____3, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - return - libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step(a, - zeta1, - zeta2, - zeta3, - zeta4); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2 -) -{ - int16_t zetas[8U] = { zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2 }; - core_core_arch_arm_shared_neon_int16x8_t - zeta = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - zetas, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int64x2_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - a0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int64x2_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t - b0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t - b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(b0, a0); - core_core_arch_arm_shared_neon_int16x8_t a = libcrux_intrinsics_arm64__vaddq_s16(a0, b0); - core_core_arch_arm_shared_neon_int16x8_t - b = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta); - core_core_arch_arm_shared_neon_int64x2_t - uu____2 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn1q_s64(uu____2, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - core_core_arch_arm_shared_neon_int64x2_t - uu____3 = libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64(libcrux_intrinsics_arm64__vtrn2q_s64(uu____3, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2 -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step(a, zeta1, zeta2); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta -) -{ - core_core_arch_arm_shared_neon_int16x8_t zeta0 = libcrux_intrinsics_arm64__vdupq_n_s16(zeta); - core_core_arch_arm_shared_neon_int16x8_t - b_minus_a = libcrux_intrinsics_arm64__vsubq_s16(v.high, v.low); - v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, v.high); - v.high = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(b_minus_a, zeta0); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step(a, zeta); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - int16_t zetas[8U] = { zeta1, zeta3, -zeta1, -zeta3, zeta2, zeta4, -zeta2, -zeta4 }; - core_core_arch_arm_shared_neon_int16x8_t - zeta = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - zetas, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t - a0 = libcrux_intrinsics_arm64__vtrn1q_s16(lhs->low, lhs->high); - core_core_arch_arm_shared_neon_int16x8_t - a1 = libcrux_intrinsics_arm64__vtrn2q_s16(lhs->low, lhs->high); - core_core_arch_arm_shared_neon_int16x8_t - b0 = libcrux_intrinsics_arm64__vtrn1q_s16(rhs->low, rhs->high); - core_core_arch_arm_shared_neon_int16x8_t - b1 = libcrux_intrinsics_arm64__vtrn2q_s16(rhs->low, rhs->high); - core_core_arch_arm_shared_neon_int16x8_t - a1b1 = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(a1, b1); - core_core_arch_arm_shared_neon_int16x4_t - uu____0 = libcrux_intrinsics_arm64__vget_low_s16(a1b1); - core_core_arch_arm_shared_neon_int32x4_t - a1b1_low = - libcrux_intrinsics_arm64__vmull_s16(uu____0, - libcrux_intrinsics_arm64__vget_low_s16(zeta)); - core_core_arch_arm_shared_neon_int32x4_t - a1b1_high = libcrux_intrinsics_arm64__vmull_high_s16(a1b1, zeta); - core_core_arch_arm_shared_neon_int32x4_t uu____1 = a1b1_low; - core_core_arch_arm_shared_neon_int16x4_t uu____2 = libcrux_intrinsics_arm64__vget_low_s16(a0); - core_core_arch_arm_shared_neon_int16x8_t - fst_low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_s16(uu____1, - uu____2, - libcrux_intrinsics_arm64__vget_low_s16(b0))); - core_core_arch_arm_shared_neon_int16x8_t - fst_high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_high_s16(a1b1_high, - a0, - b0)); - core_core_arch_arm_shared_neon_int16x4_t uu____3 = libcrux_intrinsics_arm64__vget_low_s16(a0); - core_core_arch_arm_shared_neon_int32x4_t - a0b1_low = - libcrux_intrinsics_arm64__vmull_s16(uu____3, - libcrux_intrinsics_arm64__vget_low_s16(b1)); - core_core_arch_arm_shared_neon_int32x4_t - a0b1_high = libcrux_intrinsics_arm64__vmull_high_s16(a0, b1); - core_core_arch_arm_shared_neon_int32x4_t uu____4 = a0b1_low; - core_core_arch_arm_shared_neon_int16x4_t uu____5 = libcrux_intrinsics_arm64__vget_low_s16(a1); - core_core_arch_arm_shared_neon_int16x8_t - snd_low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_s16(uu____4, - uu____5, - libcrux_intrinsics_arm64__vget_low_s16(b0))); - core_core_arch_arm_shared_neon_int16x8_t - snd_high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vmlal_high_s16(a0b1_high, - a1, - b0)); - core_core_arch_arm_shared_neon_int16x8_t - fst_low16 = libcrux_intrinsics_arm64__vtrn1q_s16(fst_low, fst_high); - core_core_arch_arm_shared_neon_int16x8_t - fst_high16 = libcrux_intrinsics_arm64__vtrn2q_s16(fst_low, fst_high); - core_core_arch_arm_shared_neon_int16x8_t - snd_low16 = libcrux_intrinsics_arm64__vtrn1q_s16(snd_low, snd_high); - core_core_arch_arm_shared_neon_int16x8_t - snd_high16 = libcrux_intrinsics_arm64__vtrn2q_s16(snd_low, snd_high); - core_core_arch_arm_shared_neon_int16x8_t - fst = libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(fst_low16, fst_high16); - core_core_arch_arm_shared_neon_int16x8_t - snd = libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t(snd_low16, snd_high16); - core_core_arch_arm_shared_neon_int32x4_t - low0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(fst, snd)); - core_core_arch_arm_shared_neon_int32x4_t - high0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(fst, snd)); - core_core_arch_arm_shared_neon_int16x8_t - low1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn1q_s32(low0, - high0)); - core_core_arch_arm_shared_neon_int16x8_t - high1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32(libcrux_intrinsics_arm64__vtrn2q_s32(low0, - high0)); - uint8_t - indexes[16U] = { 0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U }; - core_core_arch_arm_shared_neon_uint8x16_t - index = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, - indexes, - uint8_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t - low2 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(libcrux_intrinsics_arm64__vreinterpretq_u8_s16(low1), - index)); - core_core_arch_arm_shared_neon_int16x8_t - high2 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(libcrux_intrinsics_arm64__vreinterpretq_u8_s16(high1), - index)); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ .low = low2, .high = high2 }); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -) -{ - return - libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply(lhs, - rhs, - zeta1, - zeta2, - zeta3, - zeta4); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[2U] -) -{ - int16_t - shifter[8U] = - { - (int16_t)0, (int16_t)1, (int16_t)2, (int16_t)3, (int16_t)4, (int16_t)5, (int16_t)6, (int16_t)7 - }; - core_core_arch_arm_shared_neon_int16x8_t - shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - shifter, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t - low0 = libcrux_intrinsics_arm64__vshlq_s16(v.low, shift); - core_core_arch_arm_shared_neon_int16x8_t - high0 = libcrux_intrinsics_arm64__vshlq_s16(v.high, shift); - int16_t low = libcrux_intrinsics_arm64__vaddvq_s16(low0); - int16_t high = libcrux_intrinsics_arm64__vaddvq_s16(high0); - ret[0U] = (uint8_t)low; - ret[1U] = (uint8_t)high; -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[2U] -) -{ - uint8_t ret0[2U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_1(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a) -{ - core_core_arch_arm_shared_neon_int16x8_t - one = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1); - core_core_arch_arm_shared_neon_int16x8_t - low0 = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index(a, - (size_t)0U, - uint8_t, - uint8_t *, - uint8_t)); - core_core_arch_arm_shared_neon_int16x8_t - high0 = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index(a, - (size_t)1U, - uint8_t, - uint8_t *, - uint8_t)); - int16_t - shifter[8U] = - { - (int16_t)0, (int16_t)255, (int16_t)-2, (int16_t)-3, (int16_t)-4, (int16_t)-5, (int16_t)-6, - (int16_t)-7 - }; - core_core_arch_arm_shared_neon_int16x8_t - shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - shifter, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t - low = libcrux_intrinsics_arm64__vshlq_s16(low0, shift); - core_core_arch_arm_shared_neon_int16x8_t - high = libcrux_intrinsics_arm64__vshlq_s16(high0, shift); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vandq_s16(low, one); - return - ( - (libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, - .high = libcrux_intrinsics_arm64__vandq_s16(high, one) - } - ); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(a); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[8U] -) -{ - int16_t - shifter[8U] = - { - (int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12, (int16_t)0, (int16_t)4, (int16_t)8, - (int16_t)12 - }; - core_core_arch_arm_shared_neon_int16x8_t - shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - shifter, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t - lowt = - libcrux_intrinsics_arm64__vshlq_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.low), - shift); - core_core_arch_arm_shared_neon_uint16x8_t - hight = - libcrux_intrinsics_arm64__vshlq_u16(libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.high), - shift); - uint64_t - sum0 = - (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_low_u16(lowt)); - uint64_t - sum1 = - (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_high_u16(lowt)); - uint64_t - sum2 = - (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_low_u16(hight)); - uint64_t - sum3 = - (uint64_t)libcrux_intrinsics_arm64__vaddv_u16(libcrux_intrinsics_arm64__vget_high_u16(hight)); - uint64_t sum = ((sum0 | sum1 << 16U) | sum2 << 32U) | sum3 << 48U; - uint8_t ret0[8U]; - core_num__u64_9__to_le_bytes(sum, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[8U] -) -{ - uint8_t ret0[8U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_4(a, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v) -{ - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, v, Eurydice_slice, uint8_t [8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t input = core_num__u64_9__from_le_bytes(ret); - int16_t low[8U] = { 0U }; - int16_t high[8U] = { 0U }; - low[0U] = (int16_t)(input & 15ULL); - low[1U] = (int16_t)(input >> 4U & 15ULL); - low[2U] = (int16_t)(input >> 8U & 15ULL); - low[3U] = (int16_t)(input >> 12U & 15ULL); - low[4U] = (int16_t)(input >> 16U & 15ULL); - low[5U] = (int16_t)(input >> 20U & 15ULL); - low[6U] = (int16_t)(input >> 24U & 15ULL); - low[7U] = (int16_t)(input >> 28U & 15ULL); - high[0U] = (int16_t)(input >> 32U & 15ULL); - high[1U] = (int16_t)(input >> 36U & 15ULL); - high[2U] = (int16_t)(input >> 40U & 15ULL); - high[3U] = (int16_t)(input >> 44U & 15ULL); - high[4U] = (int16_t)(input >> 48U & 15ULL); - high[5U] = (int16_t)(input >> 52U & 15ULL); - high[6U] = (int16_t)(input >> 56U & 15ULL); - high[7U] = (int16_t)(input >> 60U & 15ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - low, - int16_t, - Eurydice_slice)); - lit.high = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - high, - int16_t, - Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(a); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t ret[16U] -) -{ - int16_t out[16U] = { 0U }; - libcrux_intrinsics_arm64__vst1q_s16(Eurydice_array_to_subslice((size_t)16U, - out, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v.low); - libcrux_intrinsics_arm64__vst1q_s16(Eurydice_array_to_subslice((size_t)16U, - out, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v.high); - memcpy(ret, out, (size_t)16U * sizeof (int16_t)); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[10U] -) -{ - uint8_t res[10U] = { 0U }; - int16_t out[16U]; - libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, out); - res[0U] = (uint8_t)(out[0U] | out[1U] << 5U); - res[1U] = (uint8_t)((out[1U] >> 3U | out[2U] << 2U) | out[3U] << 7U); - res[2U] = (uint8_t)(out[3U] >> 1U | out[4U] << 4U); - res[3U] = (uint8_t)((out[4U] >> 4U | out[5U] << 1U) | out[6U] << 6U); - res[4U] = (uint8_t)(out[6U] >> 2U | out[7U] << 3U); - res[5U] = (uint8_t)(out[(size_t)8U + (size_t)0U] | out[(size_t)8U + (size_t)1U] << 5U); - res[6U] = - (uint8_t)((out[(size_t)8U + (size_t)1U] >> 3U | out[(size_t)8U + (size_t)2U] << 2U) - | out[(size_t)8U + (size_t)3U] << 7U); - res[7U] = (uint8_t)(out[(size_t)8U + (size_t)3U] >> 1U | out[(size_t)8U + (size_t)4U] << 4U); - res[8U] = - (uint8_t)((out[(size_t)8U + (size_t)4U] >> 4U | out[(size_t)8U + (size_t)5U] << 1U) - | out[(size_t)8U + (size_t)6U] << 6U); - res[9U] = (uint8_t)(out[(size_t)8U + (size_t)6U] >> 2U | out[(size_t)8U + (size_t)7U] << 3U); - memcpy(ret, res, (size_t)10U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[10U] -) -{ - uint8_t ret0[10U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_5(a, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v) -{ - uint8_t input0[8U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)8U, - input0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - uint8_t uu____1[8U]; - memcpy(uu____1, input0, (size_t)8U * sizeof (uint8_t)); - uint64_t low64 = core_num__u64_9__from_le_bytes(uu____1); - uint8_t input1[8U] = { 0U }; - Eurydice_slice - uu____2 = - Eurydice_array_to_subslice((size_t)8U, - input1, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)5U, .end = (size_t)10U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input1, (size_t)8U * sizeof (uint8_t)); - uint64_t high64 = core_num__u64_9__from_le_bytes(uu____3); - int16_t low[8U] = { 0U }; - int16_t high[8U] = { 0U }; - low[0U] = (int16_t)(low64 & 31ULL); - low[1U] = (int16_t)(low64 >> 5U & 31ULL); - low[2U] = (int16_t)(low64 >> 10U & 31ULL); - low[3U] = (int16_t)(low64 >> 15U & 31ULL); - low[4U] = (int16_t)(low64 >> 20U & 31ULL); - low[5U] = (int16_t)(low64 >> 25U & 31ULL); - low[6U] = (int16_t)(low64 >> 30U & 31ULL); - low[7U] = (int16_t)(low64 >> 35U & 31ULL); - high[0U] = (int16_t)(high64 & 31ULL); - high[1U] = (int16_t)(high64 >> 5U & 31ULL); - high[2U] = (int16_t)(high64 >> 10U & 31ULL); - high[3U] = (int16_t)(high64 >> 15U & 31ULL); - high[4U] = (int16_t)(high64 >> 20U & 31ULL); - high[5U] = (int16_t)(high64 >> 25U & 31ULL); - high[6U] = (int16_t)(high64 >> 30U & 31ULL); - high[7U] = (int16_t)(high64 >> 35U & 31ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - low, - int16_t, - Eurydice_slice)); - lit.high = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - high, - int16_t, - Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(a); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[20U] -) -{ - core_core_arch_arm_shared_neon_int32x4_t - low00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.low, - v.low)); - core_core_arch_arm_shared_neon_int32x4_t - low10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.low, - v.low)); - core_core_arch_arm_shared_neon_int32x4_t - mixt = - libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)10, - low00, - low10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t - low0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt, - mixt)); - core_core_arch_arm_shared_neon_int64x2_t - low1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt, - mixt)); - core_core_arch_arm_shared_neon_int64x2_t - low_mix = - libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)20, - low0, - low1, - core_core_arch_arm_shared_neon_int64x2_t); - core_core_arch_arm_shared_neon_int32x4_t - high00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.high, - v.high)); - core_core_arch_arm_shared_neon_int32x4_t - high10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.high, - v.high)); - core_core_arch_arm_shared_neon_int32x4_t - mixt0 = - libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)10, - high00, - high10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t - high0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, - mixt0)); - core_core_arch_arm_shared_neon_int64x2_t - high1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, - mixt0)); - core_core_arch_arm_shared_neon_int64x2_t - high_mix = - libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)20, - high0, - high1, - core_core_arch_arm_shared_neon_int64x2_t); - uint8_t result32[32U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); - Eurydice_slice - uu____1 = - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); - uint8_t result[20U] = { 0U }; - Eurydice_slice - uu____2 = - Eurydice_array_to_subslice((size_t)20U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)5U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____3 = - Eurydice_array_to_subslice((size_t)20U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)5U, .end = (size_t)10U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____3, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)13U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice((size_t)20U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)10U, .end = (size_t)15U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)21U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____5 = - Eurydice_array_to_subslice((size_t)20U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)15U, .end = (size_t)20U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____5, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)29U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - memcpy(ret, result, (size_t)20U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[20U] -) -{ - uint8_t ret0[20U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_10(a, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v) -{ - uint8_t input0[8U] = { 0U }; - uint8_t input1[8U] = { 0U }; - uint8_t input2[4U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)4U, input2, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)20U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input0, (size_t)8U * sizeof (uint8_t)); - uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); - uint8_t uu____4[8U]; - memcpy(uu____4, input1, (size_t)8U * sizeof (uint8_t)); - uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); - uint8_t uu____5[4U]; - memcpy(uu____5, input2, (size_t)4U * sizeof (uint8_t)); - uint32_t input20 = core_num__u32_8__from_le_bytes(uu____5); - int16_t low[8U] = { 0U }; - int16_t high[8U] = { 0U }; - low[0U] = (int16_t)(input00 & 1023ULL); - low[1U] = (int16_t)(input00 >> 10U & 1023ULL); - low[2U] = (int16_t)(input00 >> 20U & 1023ULL); - low[3U] = (int16_t)(input00 >> 30U & 1023ULL); - low[4U] = (int16_t)(input00 >> 40U & 1023ULL); - low[5U] = (int16_t)(input00 >> 50U & 1023ULL); - low[6U] = (int16_t)((input00 >> 60U | input10 << 4U) & 1023ULL); - low[7U] = (int16_t)(input10 >> 6U & 1023ULL); - high[0U] = (int16_t)(input10 >> 16U & 1023ULL); - high[1U] = (int16_t)(input10 >> 26U & 1023ULL); - high[2U] = (int16_t)(input10 >> 36U & 1023ULL); - high[3U] = (int16_t)(input10 >> 46U & 1023ULL); - high[4U] = (int16_t)(((uint32_t)(input10 >> 56U) | input20 << 8U) & 1023U); - high[5U] = (int16_t)(input20 >> 2U & 1023U); - high[6U] = (int16_t)(input20 >> 12U & 1023U); - high[7U] = (int16_t)(input20 >> 22U & 1023U); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - low, - int16_t, - Eurydice_slice)); - lit.high = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - high, - int16_t, - Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(a); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[22U] -) -{ - int16_t input[16U]; - libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, input); - uint8_t result[22U] = { 0U }; - result[0U] = (uint8_t)input[0U]; - result[1U] = (uint8_t)(input[0U] >> 8U | input[1U] << 3U); - result[2U] = (uint8_t)(input[1U] >> 5U | input[2U] << 6U); - result[3U] = (uint8_t)(input[2U] >> 2U); - result[4U] = (uint8_t)(input[2U] >> 10U | input[3U] << 1U); - result[5U] = (uint8_t)(input[3U] >> 7U | input[4U] << 4U); - result[6U] = (uint8_t)(input[4U] >> 4U | input[5U] << 7U); - result[7U] = (uint8_t)(input[5U] >> 1U); - result[8U] = (uint8_t)(input[5U] >> 9U | input[6U] << 2U); - result[9U] = (uint8_t)(input[6U] >> 6U | input[7U] << 5U); - result[10U] = (uint8_t)(input[7U] >> 3U); - result[(size_t)11U + (size_t)0U] = (uint8_t)input[(size_t)8U + (size_t)0U]; - result[(size_t)11U + (size_t)1U] = - (uint8_t)(input[(size_t)8U + (size_t)0U] >> 8U | input[(size_t)8U + (size_t)1U] << 3U); - result[(size_t)11U + (size_t)2U] = - (uint8_t)(input[(size_t)8U + (size_t)1U] >> 5U | input[(size_t)8U + (size_t)2U] << 6U); - result[(size_t)11U + (size_t)3U] = (uint8_t)(input[(size_t)8U + (size_t)2U] >> 2U); - result[(size_t)11U + (size_t)4U] = - (uint8_t)(input[(size_t)8U + (size_t)2U] >> 10U | input[(size_t)8U + (size_t)3U] << 1U); - result[(size_t)11U + (size_t)5U] = - (uint8_t)(input[(size_t)8U + (size_t)3U] >> 7U | input[(size_t)8U + (size_t)4U] << 4U); - result[(size_t)11U + (size_t)6U] = - (uint8_t)(input[(size_t)8U + (size_t)4U] >> 4U | input[(size_t)8U + (size_t)5U] << 7U); - result[(size_t)11U + (size_t)7U] = (uint8_t)(input[(size_t)8U + (size_t)5U] >> 1U); - result[(size_t)11U + (size_t)8U] = - (uint8_t)(input[(size_t)8U + (size_t)5U] >> 9U | input[(size_t)8U + (size_t)6U] << 2U); - result[(size_t)11U + (size_t)9U] = - (uint8_t)(input[(size_t)8U + (size_t)6U] >> 6U | input[(size_t)8U + (size_t)7U] << 5U); - result[(size_t)11U + (size_t)10U] = (uint8_t)(input[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[22U] -) -{ - uint8_t ret0[22U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_11(a, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v) -{ - uint8_t input0[8U] = { 0U }; - uint8_t input1[8U] = { 0U }; - uint8_t input2[8U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_array_to_subslice((size_t)8U, - input2, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)22U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input0, (size_t)8U * sizeof (uint8_t)); - uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); - uint8_t uu____4[8U]; - memcpy(uu____4, input1, (size_t)8U * sizeof (uint8_t)); - uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); - uint8_t uu____5[8U]; - memcpy(uu____5, input2, (size_t)8U * sizeof (uint8_t)); - uint64_t input20 = core_num__u64_9__from_le_bytes(uu____5); - int16_t low[8U] = { 0U }; - int16_t high[8U] = { 0U }; - low[0U] = (int16_t)(input00 & 2047ULL); - low[1U] = (int16_t)(input00 >> 11U & 2047ULL); - low[2U] = (int16_t)(input00 >> 22U & 2047ULL); - low[3U] = (int16_t)(input00 >> 33U & 2047ULL); - low[4U] = (int16_t)(input00 >> 44U & 2047ULL); - low[5U] = (int16_t)((input00 >> 55U | input10 << 9U) & 2047ULL); - low[6U] = (int16_t)(input10 >> 2U & 2047ULL); - low[7U] = (int16_t)(input10 >> 13U & 2047ULL); - high[0U] = (int16_t)(input10 >> 24U & 2047ULL); - high[1U] = (int16_t)(input10 >> 35U & 2047ULL); - high[2U] = (int16_t)(input10 >> 46U & 2047ULL); - high[3U] = (int16_t)((input10 >> 57U | input20 << 7U) & 2047ULL); - high[4U] = (int16_t)(input20 >> 4U & 2047ULL); - high[5U] = (int16_t)(input20 >> 15U & 2047ULL); - high[6U] = (int16_t)(input20 >> 26U & 2047ULL); - high[7U] = (int16_t)(input20 >> 37U & 2047ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - low, - int16_t, - Eurydice_slice)); - lit.high = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - high, - int16_t, - Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(a); -} - -inline void -libcrux_ml_kem_vector_neon_simd128ops_serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[24U] -) -{ - core_core_arch_arm_shared_neon_int32x4_t - low00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.low, - v.low)); - core_core_arch_arm_shared_neon_int32x4_t - low10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.low, - v.low)); - core_core_arch_arm_shared_neon_int32x4_t - mixt = - libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)12, - low00, - low10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t - low0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt, - mixt)); - core_core_arch_arm_shared_neon_int64x2_t - low1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt, - mixt)); - core_core_arch_arm_shared_neon_int64x2_t - low_mix = - libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)24, - low0, - low1, - core_core_arch_arm_shared_neon_int64x2_t); - core_core_arch_arm_shared_neon_int32x4_t - high00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn1q_s16(v.high, - v.high)); - core_core_arch_arm_shared_neon_int32x4_t - high10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(libcrux_intrinsics_arm64__vtrn2q_s16(v.high, - v.high)); - core_core_arch_arm_shared_neon_int32x4_t - mixt0 = - libcrux_intrinsics_arm64__vsliq_n_s32((int32_t)12, - high00, - high10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t - high0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, - mixt0)); - core_core_arch_arm_shared_neon_int64x2_t - high1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32(libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, - mixt0)); - core_core_arch_arm_shared_neon_int64x2_t - high_mix = - libcrux_intrinsics_arm64__vsliq_n_s64((int32_t)24, - high0, - high1, - core_core_arch_arm_shared_neon_int64x2_t); - uint8_t result32[32U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); - Eurydice_slice - uu____1 = - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); - uint8_t result[24U] = { 0U }; - Eurydice_slice - uu____2 = - Eurydice_array_to_subslice((size_t)24U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)6U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____3 = - Eurydice_array_to_subslice((size_t)24U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)6U, .end = (size_t)12U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____3, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)14U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice((size_t)24U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)12U, .end = (size_t)18U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)22U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____5 = - Eurydice_array_to_subslice((size_t)24U, - result, - ((core_ops_range_Range__size_t){ .start = (size_t)18U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____5, - Eurydice_array_to_subslice((size_t)32U, - result32, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)30U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - memcpy(ret, result, (size_t)24U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[24U] -) -{ - uint8_t ret0[24U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_12(a, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof (uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v) -{ - uint8_t indexes[16U] = { 0U, 1U, 1U, 2U, 3U, 4U, 4U, 5U, 6U, 7U, 7U, 8U, 9U, 10U, 10U, 11U }; - core_core_arch_arm_shared_neon_uint8x16_t - index_vec = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, - indexes, - uint8_t, - Eurydice_slice)); - int16_t - shifts[8U] = - { - (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, (int16_t)0, - (int16_t)-4 - }; - core_core_arch_arm_shared_neon_int16x8_t - shift_vec = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice((size_t)8U, - shifts, - int16_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t - mask12 = libcrux_intrinsics_arm64__vdupq_n_u16(4095U); - uint8_t input0[16U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)16U, - input0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_arm_shared_neon_uint8x16_t - input_vec0 = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, - input0, - uint8_t, - Eurydice_slice)); - uint8_t input1[16U] = { 0U }; - Eurydice_slice - uu____1 = - Eurydice_array_to_subslice((size_t)16U, - input1, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)12U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ .start = (size_t)12U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_arm_shared_neon_uint8x16_t - input_vec1 = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice((size_t)16U, - input1, - uint8_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t - moved0 = - libcrux_intrinsics_arm64__vreinterpretq_u16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec0, - index_vec)); - core_core_arch_arm_shared_neon_uint16x8_t - shifted0 = libcrux_intrinsics_arm64__vshlq_u16(moved0, shift_vec); - core_core_arch_arm_shared_neon_int16x8_t - low = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vandq_u16(shifted0, - mask12)); - core_core_arch_arm_shared_neon_uint16x8_t - moved1 = - libcrux_intrinsics_arm64__vreinterpretq_u16_u8(libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec1, - index_vec)); - core_core_arch_arm_shared_neon_uint16x8_t - shifted1 = libcrux_intrinsics_arm64__vshlq_u16(moved1, shift_vec); - core_core_arch_arm_shared_neon_int16x8_t - high = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16(libcrux_intrinsics_arm64__vandq_u16(shifted1, - mask12)); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ .low = low, .high = high }); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - Eurydice_slice a -) -{ - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(a); -} - -inline size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, Eurydice_slice result) -{ - size_t sampled = (size_t)0U; - core_slice_iter_Chunks - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(core_slice___Slice_T___chunks(a, - (size_t)3U, - uint8_t, - core_slice_iter_Chunks), - core_slice_iter_Chunks, - core_slice_iter_Chunks); - while (true) - { - core_option_Option__Eurydice_slice_uint8_t - uu____0 = - core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next(&iter, - uint8_t, - core_option_Option__Eurydice_slice_uint8_t); - if (uu____0.tag == core_option_None) - { - break; - } - else - { - Eurydice_slice bytes = uu____0.f0; - int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - int16_t d1 = (b2 & (int16_t)15) << 8U | b1; - int16_t d2 = b3 << 4U | b2 >> 4U; - bool uu____1; - if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) - { - uu____1 = sampled < (size_t)16U; - } - else - { - uu____1 = false; - } - if (uu____1) - { - int16_t uu____2 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____2; - sampled++; - } - bool uu____3; - if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) - { - uu____3 = sampled < (size_t)16U; - } - else - { - uu____3 = false; - } - if (uu____3) - { - int16_t uu____4 = d2; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____4; - sampled++; - } - } - } - return sampled; -} - -size_t -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - Eurydice_slice a, - Eurydice_slice out -) -{ - return libcrux_ml_kem_vector_neon_rej_sample(a, out); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self -) -{ - return self[0U]; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(void) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - lit; - lit.coefficients[0U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[1U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[2U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[3U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[4U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[5U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[6U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[7U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[8U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[9U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[10U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[11U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[12U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[13U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[14U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[15U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12(bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -shift_right___15int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - v.low = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, - v.low, - core_core_arch_arm_shared_neon_int16x8_t); - v.high = - libcrux_intrinsics_arm64__vshrq_n_s16((int32_t)15, - v.high, - core_core_arch_arm_shared_neon_int16x8_t); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -shift_right___15int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - return shift_right___15int32_t(v); -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a -) -{ - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = shift_right___15int32_t0(a); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fm = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant(t, - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, - &fm); -} - -static inline void -serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[384U] -) -{ - uint8_t serialized[384U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)384U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof (uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[4U], - uint8_t ret[1536U] -) -{ - uint8_t out[1536U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1536U, - out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, out, (size_t)1536U * sizeof (uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, - uint8_t ret[1568U] -) -{ - uint8_t public_key_serialized[1568U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1568U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1536U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[4U]; - memcpy(uu____1, - t_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1568U, - public_key_serialized, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t(Eurydice_array_to_subslice_to((size_t)1568U, - public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[4U]; - memcpy(uu____0, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, - public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1568U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy(ret, - ret0, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -typedef struct Simd128Hash_s -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - shake128_state[2U]; -} -Simd128Hash; - -static inline Simd128Hash shake128_init_absorb___4size_t(uint8_t input[4U][34U]) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, - uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = &state[1U]; - Eurydice_slice - uu____4 = Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____3, - uu____4, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy(lit.shake128_state, - state, - (size_t)2U - * - sizeof ( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - )); - return lit; -} - -static inline void -shake128_squeeze_three_blocks___4size_t(Simd128Hash *self, uint8_t ret[4U][504U]) -{ - uint8_t out[4U][504U] = { { 0U } }; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)4U, - out, - uint8_t [504U], - Eurydice_slice), - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = - core_slice___Slice_T___split_at_mut(out123, - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = - core_slice___Slice_T___split_at_mut(out23, - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = self->shake128_state; - Eurydice_slice - uu____4 = - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____3, - uu____4, - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____5 = &self->shake128_state[1U]; - Eurydice_slice - uu____6 = - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____5, - uu____6, - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static inline void shake128_squeeze_block___4size_t(Simd128Hash *self, uint8_t ret[4U][168U]) -{ - uint8_t out[4U][168U] = { { 0U } }; - uint8_t out0[168U] = { 0U }; - uint8_t out1[168U] = { 0U }; - uint8_t out2[168U] = { 0U }; - uint8_t out3[168U] = { 0U }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, - uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &self->shake128_state[1U]; - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____2, - uu____3, - Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); - uint8_t uu____4[168U]; - memcpy(uu____4, out0, (size_t)168U * sizeof (uint8_t)); - memcpy(out[0U], uu____4, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____5[168U]; - memcpy(uu____5, out1, (size_t)168U * sizeof (uint8_t)); - memcpy(out[1U], uu____5, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____6[168U]; - memcpy(uu____6, out2, (size_t)168U * sizeof (uint8_t)); - memcpy(out[2U], uu____6, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____7[168U]; - memcpy(uu____7, out3, (size_t)168U * sizeof (uint8_t)); - memcpy(out[3U], uu____7, (size_t)168U * sizeof (uint8_t)); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_slice a) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array(Eurydice_slice_subslice(a, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - result.coefficients[i0] = uu____0; - } - return result; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - size_t sampled_coefficients[4U] = { 0U }; - int16_t out[4U][272U] = { { 0U } }; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof (uint8_t [34U])); - Simd128Hash xof_state = shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { - break; - } - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t(uu____2, - sampled_coefficients, - out); - } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U][4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0(A_transpose[i]);); - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[4U][34U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U] - )); -} - -typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t_s -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[4U]; - uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) -{ - uint8_t out[4U][128U] = { { 0U } }; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)4U, - out, - uint8_t [128U], - Eurydice_slice), - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = - core_slice___Slice_T___split_at_mut(out123, - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = - core_slice___Slice_T___split_at_mut(out23, - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice - uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____4 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____5 = - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____3, - uu____4, - uu____5, - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice)); - Eurydice_slice - uu____6 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____7 = Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____8 = - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____6, - uu____7, - uu____8, - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice randomness -) -{ - int16_t sampled_i16s[256U] = { 0U }; - for - (size_t - i0 = (size_t)0U; - i0 - < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) - { - size_t chunk_number = i0; - Eurydice_slice - byte_chunk = - Eurydice_slice_subslice(randomness, - ( - (core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint32_t - uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t - uu____1 = - uu____0 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; - uint32_t - uu____2 = - uu____1 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; - uint32_t - random_bits_as_u32 = - uu____2 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) - { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return - from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_slice((size_t)256U, - sampled_i16s, - int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice randomness -) -{ - int16_t sampled_i16s[256U] = { 0U }; - for - (size_t - i0 = (size_t)0U; - i0 - < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) - { - size_t chunk_number = i0; - Eurydice_slice - byte_chunk = - Eurydice_slice_subslice(randomness, - ( - (core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint32_t - uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t - uu____1 = - uu____0 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; - uint32_t - random_bits_as_u24 = - uu____1 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) - { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t - outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + (int32_t)3) & 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return - from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_slice((size_t)256U, - sampled_i16s, - int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_slice randomness -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(randomness); - return uu____0; -} - -static inline void -ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) - { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant(re->coefficients[j - + step], - (int16_t)-1600); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(re->coefficients[j], - &t); - re->coefficients[j + step] = uu____0; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(re->coefficients[j], - &t); - re->coefficients[j] = uu____1; - } -} - -typedef struct -__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s -{ - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector snd; -} -__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t fer -) -{ - return - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(v, - fer); -} - -static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, - int16_t zeta_r -) -{ - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t = montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(b, zeta_r); - b = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(a, - &t); - a = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, - &t); - return - ( - (__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .fst = a, - .snd = b - } - ); -} - -static inline void -ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - size_t layer -) -{ - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) - { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) - { - size_t j = i; - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[j], - re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline void -ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -static inline void -ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)3U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -static inline void -poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(self->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); - size_t zeta_i = (size_t)1U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[4U]; - memcpy(uu____2, - re_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - out = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply(&self->coefficients[i0], - &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)3U]); - out.coefficients[i0] = uu____0; - } - return out; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], - &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(v, - LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); -} - -static inline void -add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(self->coefficients[j]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, - &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1], - &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_as_ntt[i1]); - } - memcpy(ret, - result, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed -) -{ - uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(ret, - true, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[4U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____3, - domain_separator).fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[4U]; - memcpy(uu____4, - t_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[4U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t(uu____5, - secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof (uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof (uint8_t)); - return lit; -} - -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[3168U] -) -{ - uint8_t out[3168U] = { 0U }; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)3168U, - out, - ( - (core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[32U]; - H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)3168U * sizeof (uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t(ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof (uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t(uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t(uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t(uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[4U]; - memcpy(uu____2, - error_1, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - uint8_t dummy[128U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t0(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)3U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -static inline void -invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -static inline void -invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, - int16_t zeta_r -) -{ - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - a_minus_b = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(b, - &a); - a = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(a, - &b)); - b = - montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_minus_b, - zeta_r); - return - ( - (__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .fst = a, - .snd = b - } - ); -} - -static inline void -invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - size_t layer -) -{ - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) - { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) - { - size_t j = i; - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[j], - re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(self->coefficients[j], - (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, - &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [4U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, - &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1], - &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_1[i1]); - } - memcpy(ret, - result, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(), - &v), - (int16_t)1665); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - uint8_t serialized[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_compressed = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1(Eurydice_array_to_subslice((size_t)32U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(result.coefficients[i0], - (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - tmp = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], - &message->coefficients[i0]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - tmp0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(coefficient_normal_form, - &tmp); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, - message, - result); - return result; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t - compressed = - libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)10, - v, - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t - compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t - compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, - compressed1, - core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___10int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - core_core_arch_arm_shared_neon_int16x8_t - mask = - libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)10)); - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___10int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___10int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___10int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___10int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t - low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t - high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___10int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - return compress___10int32_t(v); -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U] -) -{ - uint8_t serialized[352U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)352U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t - compressed = - libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)11, - v, - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t - compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t - compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, - compressed1, - core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___11int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - core_core_arch_arm_shared_neon_int16x8_t - mask = - libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)11)); - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___11int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___11int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___11int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___11int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t - low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t - high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___11int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - return compress___11int32_t(v); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U] -) -{ - uint8_t serialized[352U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)352U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U] -) -{ - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t(re, - uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof (uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[4U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t - compressed = - libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)4, - v, - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t - compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t - compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, - compressed1, - core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___4int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - core_core_arch_arm_shared_neon_int16x8_t - mask = - libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)4)); - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___4int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___4int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___4int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___4int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t - low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t - high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___4int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - return compress___4int32_t(v); -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice serialized -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - compress___4int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t half = libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t - compressed = - libcrux_intrinsics_arm64__vshlq_n_u32((int32_t)5, - v, - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - compressed0 = libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t - compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32(libcrux_intrinsics_arm64__vqdmulhq_n_s32(libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t - compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, - compressed1, - core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___5int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - core_core_arch_arm_shared_neon_int16x8_t - mask = - libcrux_intrinsics_arm64__vdupq_n_s16(libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits((int16_t)(int32_t)5)); - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = compress_int32x4_t___5int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = compress_int32x4_t___5int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = compress_int32x4_t___5int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = compress_int32x4_t___5int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t - low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t - high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___5int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) -{ - return compress___5int32_t(v); -} - -static inline void -compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice serialized -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficients = - compress___5int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5(coefficients, - bytes); - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice out -) -{ - compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[1568U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t(Eurydice_slice_subslice_to(public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t(ret0, - false, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[4U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[4U]; - memcpy(error_1, - uu____3.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___4size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(A_transpose, - r_as_ntt, - error_1, - u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[1568U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[4U]; - memcpy(uu____5, - u, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t(uu____5, - Eurydice_array_to_subslice((size_t)1568U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1408U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, - ciphertext, - (size_t)1408U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); - uint8_t ret[32U]; - H___4size_t(Eurydice_array_to_slice((size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - uint8_t hashed[64U]; - G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), - uint8_t, - Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t(uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t - coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)10 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32(v, - (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)10, - decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___10int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___10int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___10int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___10int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___10int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___10int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return decompress_ciphertext_coefficient___10int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10(bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = decompress_ciphertext_coefficient___10int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t - coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)11 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32(v, - (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)11, - decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___11int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___11int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___11int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___11int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___11int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___11int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return decompress_ciphertext_coefficient___11int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11(bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = decompress_ciphertext_coefficient___11int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1568U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U); - i++) - { - size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)1568U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t(u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t(&u_as_ntt[i0]); - } - memcpy(ret, - u_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t - coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)4 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32(v, - (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)4, - decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___4int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___4int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___4int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___4int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___4int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___4int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return decompress_ciphertext_coefficient___4int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4(bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = decompress_ciphertext_coefficient___4int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) -{ - core_core_arch_arm_shared_neon_uint32x4_t - coeff = libcrux_intrinsics_arm64__vdupq_n_u32(1U << (uint32_t)((int32_t)5 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32(v, - (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed0 = libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t - decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)5, - decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___5int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - core_core_arch_arm_shared_neon_uint32x4_t - mask16 = libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t - low00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - low10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t - high00 = - libcrux_intrinsics_arm64__vandq_u32(libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - mask16); - core_core_arch_arm_shared_neon_uint32x4_t - high10 = - libcrux_intrinsics_arm64__vshrq_n_u32((int32_t)16, - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = decompress_uint32x4_t___5int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = decompress_uint32x4_t___5int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = decompress_uint32x4_t___5int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = decompress_uint32x4_t___5int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t - uu____0 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t - uu____1 = libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = - libcrux_intrinsics_arm64__vtrn1q_s16(uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___5int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -) -{ - return decompress_ciphertext_coefficient___5int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5(bytes); - re.coefficients[i0] = uu____0; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t1(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) - { - size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12(bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy(ret, - secret_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - b -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant(b.coefficients[i0], - (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce(libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub(self->coefficients[i0], - &coefficient_normal_form)); - b.coefficients[i0] = uu____0; - } - return b; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); - return result; -} - -static inline void -compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - uint8_t ret[32U] -) -{ - uint8_t serialized[32U] = { 0U }; - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re.coefficients[i0]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient_compressed = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1(coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1(coefficient_compressed, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)32U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *);); - memcpy(ret, serialized, (size_t)32U * sizeof (uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t(Eurydice_array_to_subslice_from((size_t)1568U, - ciphertext, - (size_t)1408U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(&v, - secret_as_ntt, - u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - uint8_t dummy[32U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)3168U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)1536U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)1568U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); - uint8_t hashed[64U]; - G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)1600U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext), - uint8_t, - void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t(uu____7, - Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[3U], - uint8_t ret[1152U] -) -{ - uint8_t out[1152U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1152U, - out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, out, (size_t)1152U * sizeof (uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, - uint8_t ret[1184U] -) -{ - uint8_t public_key_serialized[1184U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1184U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1152U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[3U]; - memcpy(uu____1, - t_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1184U, - public_key_serialized, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t(Eurydice_array_to_subslice_to((size_t)1184U, - public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[3U]; - memcpy(uu____0, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, - public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1184U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy(ret, - ret0, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline Simd128Hash shake128_init_absorb___3size_t(uint8_t input[3U][34U]) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, - uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = &state[1U]; - Eurydice_slice - uu____4 = Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____3, - uu____4, - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy(lit.shake128_state, - state, - (size_t)2U - * - sizeof ( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - )); - return lit; -} - -static inline void -shake128_squeeze_three_blocks___3size_t(Simd128Hash *self, uint8_t ret[3U][504U]) -{ - uint8_t out[3U][504U] = { { 0U } }; - uint8_t extra[504U] = { 0U }; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)3U, - out, - uint8_t [504U], - Eurydice_slice), - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = - core_slice___Slice_T___split_at_mut(out12, - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = self->shake128_state; - Eurydice_slice - uu____3 = - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____2, - uu____3, - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____4 = &self->shake128_state[1U]; - Eurydice_slice - uu____5 = - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____4, - uu____5, - Eurydice_array_to_slice((size_t)504U, extra, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static inline void shake128_squeeze_block___3size_t(Simd128Hash *self, uint8_t ret[3U][168U]) -{ - uint8_t out[3U][168U] = { { 0U } }; - uint8_t out0[168U] = { 0U }; - uint8_t out1[168U] = { 0U }; - uint8_t out2[168U] = { 0U }; - uint8_t out3[168U] = { 0U }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, - uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &self->shake128_state[1U]; - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____2, - uu____3, - Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); - uint8_t uu____4[168U]; - memcpy(uu____4, out0, (size_t)168U * sizeof (uint8_t)); - memcpy(out[0U], uu____4, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____5[168U]; - memcpy(uu____5, out1, (size_t)168U * sizeof (uint8_t)); - memcpy(out[1U], uu____5, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____6[168U]; - memcpy(uu____6, out2, (size_t)168U * sizeof (uint8_t)); - memcpy(out[2U], uu____6, (size_t)168U * sizeof (uint8_t)); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - size_t sampled_coefficients[3U] = { 0U }; - int16_t out[3U][272U] = { { 0U } }; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof (uint8_t [34U])); - Simd128Hash xof_state = shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { - break; - } - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t(uu____2, - sampled_coefficients, - out); - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U][3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0(A_transpose[i]);); - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[3U][34U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U] - )); -} - -typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t_s -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[3U]; - uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) -{ - uint8_t out[3U][128U] = { { 0U } }; - uint8_t extra[128U] = { 0U }; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)3U, - out, - uint8_t [128U], - Eurydice_slice), - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = - core_slice___Slice_T___split_at_mut(out12, - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____3 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____4 = - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____2, - uu____3, - uu____4, - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice)); - Eurydice_slice - uu____5 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____6 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____7 = - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____5, - uu____6, - uu____7, - Eurydice_array_to_slice((size_t)128U, extra, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[3U]; - memcpy(uu____2, - re_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], - &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1], - &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_as_ntt[i1]); - } - memcpy(ret, - result, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed -) -{ - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(ret, - true, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[3U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____3, - domain_separator).fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[3U]; - memcpy(uu____4, - t_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[3U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t(uu____5, - secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof (uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof (uint8_t)); - return lit; -} - -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[2400U] -) -{ - uint8_t out[2400U] = { 0U }; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)2400U, - out, - ( - (core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)2400U * sizeof (uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t(ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof (uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t(uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t(uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t(uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[3U]; - memcpy(uu____2, - error_1, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - uint8_t dummy[128U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t0(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [3U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, - &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1], - &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_1[i1]); - } - memcpy(ret, - result, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, - message, - result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U] -) -{ - uint8_t serialized[320U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)320U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U] -) -{ - uint8_t serialized[320U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - coefficient = - compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)320U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U] -) -{ - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t(re, - uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof (uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[3U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice out -) -{ - compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[1088U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t(Eurydice_slice_subslice_to(public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t(ret0, - false, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[3U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[3U]; - memcpy(error_1, - uu____3.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(A_transpose, - r_as_ntt, - error_1, - u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[1088U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[3U]; - memcpy(uu____5, - u, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t(uu____5, - Eurydice_array_to_subslice((size_t)1088U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)960U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, - ciphertext, - (size_t)960U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); - uint8_t ret[32U]; - H___3size_t(Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - uint8_t hashed[64U]; - G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), - uint8_t, - Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t(uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1088U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); - i++) - { - size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)1088U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(&u_as_ntt[i0]); - } - memcpy(ret, - u_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t1(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy(ret, - secret_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(Eurydice_array_to_subslice_from((size_t)1088U, - ciphertext, - (size_t)960U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(&v, - secret_as_ntt, - u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - uint8_t dummy[32U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)2400U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)1152U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)1184U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); - uint8_t hashed[64U]; - G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)1120U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext), - uint8_t, - void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t(uu____7, - Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[2U], - uint8_t ret[768U] -) -{ - uint8_t out[768U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)768U, - out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - } - memcpy(ret, out, (size_t)768U * sizeof (uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U], - Eurydice_slice seed_for_a, - uint8_t ret[800U] -) -{ - uint8_t public_key_serialized[800U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)800U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)768U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[2U]; - memcpy(uu____1, - t_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)800U, - public_key_serialized, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t(Eurydice_array_to_subslice_to((size_t)800U, - public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[2U]; - memcpy(uu____0, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)800U, - public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)800U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_neon_sha512(Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy(ret, - ret0, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline Simd128Hash shake128_init_absorb___2size_t(uint8_t input[2U][34U]) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = { uu____0, libcrux_sha3_neon_x2_incremental_shake128_init() }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final(uu____1, - uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy(lit.shake128_state, - state, - (size_t)2U - * - sizeof ( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - )); - return lit; -} - -static inline void -shake128_squeeze_three_blocks___2size_t(Simd128Hash *self, uint8_t ret[2U][504U]) -{ - uint8_t out[2U][504U] = { { 0U } }; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, - out, - uint8_t [504U], - Eurydice_slice), - (size_t)1U, - uint8_t [504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = self->shake128_state; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(uu____1, - uu____2, - Eurydice_array_to_slice((size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [504U], uint8_t (*)[504U], uint8_t [504U]), - uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( - uint8_t randomness[2U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static inline void shake128_squeeze_block___2size_t(Simd128Hash *self, uint8_t ret[2U][168U]) -{ - uint8_t out[2U][168U] = { { 0U } }; - uint8_t out0[168U] = { 0U }; - uint8_t out1[168U] = { 0U }; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(uu____0, - uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - uint8_t uu____2[168U]; - memcpy(uu____2, out0, (size_t)168U * sizeof (uint8_t)); - memcpy(out[0U], uu____2, (size_t)168U * sizeof (uint8_t)); - uint8_t uu____3[168U]; - memcpy(uu____3, out1, (size_t)168U * sizeof (uint8_t)); - memcpy(out[1U], uu____3, (size_t)168U * sizeof (uint8_t)); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( - uint8_t randomness[2U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - size_t sampled_coefficients[2U] = { 0U }; - int16_t out[2U][272U] = { { 0U } }; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof (uint8_t [34U])); - Simd128Hash xof_state = shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { - break; - } - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t(uu____2, - sampled_coefficients, - out); - } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U][2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0(A_transpose[i]);); - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[2U][34U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U] - )); -} - -typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t_s -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[2U]; - uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) -{ - uint8_t out[2U][192U] = { { 0U } }; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, - out, - uint8_t [192U], - Eurydice_slice), - (size_t)1U, - uint8_t [192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____3 = - Eurydice_array_to_slice((size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [192U], uint8_t (*)[192U], uint8_t [192U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____1, - uu____2, - uu____3, - Eurydice_array_to_slice((size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [192U], uint8_t (*)[192U], uint8_t [192U]), - uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [192U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - Eurydice_slice randomness -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(randomness); - return uu____0; -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(Eurydice_array_to_slice((size_t)192U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[2U]; - memcpy(uu____2, - re_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add(self->coefficients[i0], - &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1], - &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_as_ntt[i1]); - } - memcpy(ret, - result, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed -) -{ - uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(ret, - true, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[2U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____3, - domain_separator).fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[2U]; - memcpy(uu____4, - t_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[2U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t(uu____5, - secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof (uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof (uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof (uint8_t)); - return lit; -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_neon_sha256(Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[1632U] -) -{ - uint8_t out[1632U] = { 0U }; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)1632U, - out, - ( - (core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret0[32U]; - H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)1632U * sizeof (uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t(ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof (uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t(uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t(uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t(uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy(ret, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( - void -) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) -{ - uint8_t out[2U][128U] = { { 0U } }; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = - core_slice___Slice_T___split_at_mut(Eurydice_array_to_slice((size_t)2U, - out, - uint8_t [128U], - Eurydice_slice), - (size_t)1U, - uint8_t [128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____3 = - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____1, - uu____2, - uu____3, - Eurydice_array_to_slice((size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t [128U], uint8_t (*)[128U], uint8_t [128U]), - uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[2U]; - memcpy(uu____2, - error_1, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___2size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - uint8_t dummy[128U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t0(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re, - (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - (*a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector [2U], - size_t); - i0++) - { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(a_element, - &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1], - &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&result[i1], - &error_1[i1]); - } - memcpy(ret, - result, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(error_2, - message, - result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[2U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) - { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[768U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t(Eurydice_slice_subslice_to(public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t(ret0, - false, - A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[2U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[2U]; - memcpy(error_1, - uu____3.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___2size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(A_transpose, - r_as_ntt, - error_1, - u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[768U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[2U]; - memcpy(uu____5, - u, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t(uu____5, - Eurydice_array_to_subslice((size_t)768U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)640U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)768U, - ciphertext, - (size_t)640U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof (uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); - uint8_t ret[32U]; - H___2size_t(Eurydice_array_to_slice((size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - uint8_t hashed[64U]; - G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), - uint8_t, - Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t(uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)768U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); - i++) - { - size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)768U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t(&u_as_ntt[i0]); - } - memcpy(ret, - u_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t1(void) -{ - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { - size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy(ret, - secret_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - )); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result, - &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(Eurydice_array_to_subslice_from((size_t)768U, - ciphertext, - (size_t)640U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(&v, - secret_as_ntt, - u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(message, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - uint8_t dummy[32U] = { 0U }; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256(uu____0, - uu____1, - uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)1632U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)768U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)800U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); - uint8_t hashed[64U]; - G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)800U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext), - uint8_t, - void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t(uu____7, - Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/libcrux_mlkem_neon.h deleted file mode 100644 index 55e374569..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem_neon_H -#define __libcrux_mlkem_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_sha3_neon.h" -#include "libcrux_mlkem_portable.h" -#include "libcrux_core.h" -#include "eurydice_glue.h" - -typedef struct libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s -{ - core_core_arch_arm_shared_neon_int16x8_t low; - core_core_arch_arm_shared_neon_int16x8_t high; -} -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ZERO(void); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( - void -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( - Eurydice_slice array -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -#define LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER ((int16_t)20159) - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t low, - core_core_arch_arm_shared_neon_int16x8_t high -); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v -); - -int16_t -libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits(int16_t coefficient_bits); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - core_core_arch_arm_shared_neon_int16x8_t c -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta1, - int16_t zeta2 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta1, - int16_t zeta2 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t zeta -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - int16_t zeta -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3, - int16_t zeta4 -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[2U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[2U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( - Eurydice_slice a -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[8U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[8U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( - Eurydice_slice a -); - -void -libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - int16_t ret[16U] -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[10U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[10U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( - Eurydice_slice a -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[20U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[20U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( - Eurydice_slice a -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[22U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[22U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( - Eurydice_slice a -); - -void -libcrux_ml_kem_vector_neon_simd128ops_serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, - uint8_t ret[24U] -); - -void -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - uint8_t ret[24U] -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - Eurydice_slice a -); - -size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, Eurydice_slice result); - -size_t -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - Eurydice_slice a, - Eurydice_slice out -); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self -); - -typedef struct -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s -{ libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients[16U]; } -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 9b58ec04e..17854d7fc 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,45 +1,566 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" -#include "internal/libcrux_sha3_internal.h" #include "internal/libcrux_core.h" +#include "internal/libcrux_sha3_internal.h" -const -int16_t -libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = - { - (int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, (int16_t)1493, (int16_t)1422, - (int16_t)287, (int16_t)202, (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, - (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, (int16_t)573, (int16_t)-1325, - (int16_t)264, (int16_t)383, (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, - (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, (int16_t)-1542, (int16_t)411, - (int16_t)-205, (int16_t)-1571, (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, - (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, (int16_t)516, (int16_t)-8, - (int16_t)-320, (int16_t)-666, (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, - (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, (int16_t)107, (int16_t)-1421, - (int16_t)-247, (int16_t)-951, (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, - (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, (int16_t)-1103, (int16_t)430, - (int16_t)555, (int16_t)843, (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, - (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, (int16_t)-291, (int16_t)-460, - (int16_t)1574, (int16_t)1653, (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, - (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, (int16_t)-1590, (int16_t)644, - (int16_t)-872, (int16_t)349, (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, - (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, (int16_t)1322, (int16_t)-1285, - (int16_t)-1465, (int16_t)384, (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, - (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, (int16_t)-1185, (int16_t)-1530, - (int16_t)-1278, (int16_t)794, (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, - (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, (int16_t)958, (int16_t)-1460, - (int16_t)1522, (int16_t)1628 - }; - -inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero(void) -{ +const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = { + (int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, + (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, + (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, + (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, + (int16_t)573, (int16_t)-1325, (int16_t)264, (int16_t)383, + (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, + (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, + (int16_t)-1542, (int16_t)411, (int16_t)-205, (int16_t)-1571, + (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, + (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, + (int16_t)516, (int16_t)-8, (int16_t)-320, (int16_t)-666, + (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, + (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, + (int16_t)107, (int16_t)-1421, (int16_t)-247, (int16_t)-951, + (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, + (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, + (int16_t)-1103, (int16_t)430, (int16_t)555, (int16_t)843, + (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, + (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, + (int16_t)-291, (int16_t)-460, (int16_t)1574, (int16_t)1653, + (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, + (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, + (int16_t)-1590, (int16_t)644, (int16_t)-872, (int16_t)349, + (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, + (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, + (int16_t)1322, (int16_t)-1285, (int16_t)-1465, (int16_t)384, + (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, + (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, + (int16_t)-1185, (int16_t)-1530, (int16_t)-1278, (int16_t)794, + (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, + (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, + (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; + +const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE + [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, + 255U, 255U, 255U}, + {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 255U, 255U}, + {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, + 15U, 255U, 255U}, + {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 14U, 15U}}; + +inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero( + void) { libcrux_ml_kem_vector_portable_PortableVector lit; lit.elements[0U] = (int16_t)0; lit.elements[1U] = (int16_t)0; @@ -62,49 +583,40 @@ inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO( - void -) -{ + void) { return libcrux_ml_kem_vector_zero(); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) -{ +libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) { libcrux_ml_kem_vector_portable_PortableVector lit; int16_t ret[16U]; core_result_Result__int16_t_16size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(array, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - int16_t [16U], - void *); - core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError(dst, - ret); - memcpy(lit.elements, ret, (size_t)16U * sizeof (int16_t)); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice(array, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, int16_t[16U], void *); + core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + dst, ret); + memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); return lit; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( - Eurydice_slice array -) -{ + Eurydice_slice array) { return libcrux_ml_kem_vector_from_i16_array(array); } -inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_add( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; size_t uu____0 = i0; lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; @@ -114,21 +626,16 @@ libcrux_ml_kem_vector_add( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -) -{ + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { return libcrux_ml_kem_vector_add(lhs, rhs); } -inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_sub( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; size_t uu____0 = i0; lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; @@ -138,21 +645,16 @@ libcrux_ml_kem_vector_sub( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -) -{ + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { return libcrux_ml_kem_vector_sub(lhs, rhs); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; size_t uu____0 = i0; v.elements[uu____0] = v.elements[uu____0] * c; @@ -162,21 +664,15 @@ libcrux_ml_kem_vector_multiply_by_constant( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { return libcrux_ml_kem_vector_multiply_by_constant(v, c); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_bitwise_and_with_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; size_t uu____0 = i0; v.elements[uu____0] = v.elements[uu____0] & c; @@ -186,54 +682,57 @@ libcrux_ml_kem_vector_bitwise_and_with_constant( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { return libcrux_ml_kem_vector_bitwise_and_with_constant(v, c); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_cond_subtract_3329(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { - size_t i0 = i; - if (v.elements[i0] >= (int16_t)3329) - { - size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] - (int16_t)3329; +libcrux_ml_kem_vector_cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v) { + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + core_option_Option__size_t uu____0 = + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t); + if (!(uu____0.tag == core_option_None)) { + size_t i = uu____0.f0; + if (v.elements[i] >= (int16_t)3329) { + size_t uu____1 = i; + v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; + } + continue; } + return v; } - return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( - libcrux_ml_kem_vector_portable_PortableVector v -) -{ + libcrux_ml_kem_vector_portable_PortableVector v) { return libcrux_ml_kem_vector_cond_subtract_3329(v); } -int16_t libcrux_ml_kem_vector_barrett_reduce_element(int16_t value) -{ - int32_t - t = - (int32_t)value - * LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER - + (LIBCRUX_ML_KEM_VECTOR_BARRETT_R >> 1U); - int16_t quotient = (int16_t)(t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT); +int16_t libcrux_ml_kem_vector_barrett_reduce_element(int16_t value) { + int32_t t = (int32_t)value * LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER + + (LIBCRUX_ML_KEM_VECTOR_BARRETT_R >> 1U); + int16_t quotient = + (int16_t)(t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT); return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_barrett_reduce(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +libcrux_ml_kem_vector_barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t uu____0 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[i0]); + int16_t uu____0 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[i0]); v.elements[i0] = uu____0; } return v; @@ -241,40 +740,37 @@ libcrux_ml_kem_vector_barrett_reduce(libcrux_ml_kem_vector_portable_PortableVect libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( - libcrux_ml_kem_vector_portable_PortableVector v -) -{ + libcrux_ml_kem_vector_portable_PortableVector v) { return libcrux_ml_kem_vector_barrett_reduce(v); } -int16_t libcrux_ml_kem_vector_montgomery_reduce_element(int32_t value) -{ - int32_t - k = - (int32_t)(int16_t)value - * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; - int32_t - k_times_modulus = (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - int16_t c = (int16_t)(k_times_modulus >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); - int16_t value_high = (int16_t)(value >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); +int16_t libcrux_ml_kem_vector_montgomery_reduce_element(int32_t value) { + int32_t k = + (int32_t)(int16_t)value * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; + int32_t k_times_modulus = + (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int16_t c = (int16_t)(k_times_modulus >> + (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); + int16_t value_high = + (int16_t)(value >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); return value_high - c; } -inline int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(int16_t fe, int16_t fer) -{ - return libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)fe * (int32_t)fer); +inline int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + int16_t fe, int16_t fer) { + return libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)fe * + (int32_t)fer); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[i0], c); + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[i0], c); v.elements[i0] = uu____0; } return v; @@ -282,15 +778,11 @@ libcrux_ml_kem_vector_montgomery_multiply_by_constant( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t r -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t r) { return libcrux_ml_kem_vector_montgomery_multiply_by_constant(v, r); } -uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe) -{ +uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe) { int16_t shifted = (int16_t)1664 - (int16_t)fe; int16_t mask = shifted >> 15U; int16_t shifted_to_positive = mask ^ shifted; @@ -299,12 +791,13 @@ uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe) } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_compress_1(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +libcrux_ml_kem_vector_compress_1( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - uint8_t uu____0 = libcrux_ml_kem_vector_compress_message_coefficient((uint16_t)v.elements[i0]); + uint8_t uu____0 = libcrux_ml_kem_vector_compress_message_coefficient( + (uint16_t)v.elements[i0]); v.elements[i0] = (int16_t)uu____0; } return v; @@ -312,173 +805,166 @@ libcrux_ml_kem_vector_compress_1(libcrux_ml_kem_vector_portable_PortableVector v libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( - libcrux_ml_kem_vector_portable_PortableVector v -) -{ + libcrux_ml_kem_vector_portable_PortableVector v) { return libcrux_ml_kem_vector_compress_1(v); } -inline uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits(uint8_t n, uint32_t value) -{ +inline uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits( + uint8_t n, uint32_t value) { return value & ((1U << (uint32_t)n) - 1U); } -int16_t -libcrux_ml_kem_vector_compress_ciphertext_coefficient(uint8_t coefficient_bits, uint16_t fe) -{ +int16_t libcrux_ml_kem_vector_compress_ciphertext_coefficient( + uint8_t coefficient_bits, uint16_t fe) { uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; compressed = compressed + 1664ULL; compressed = compressed * 10321340ULL; compressed = compressed >> 35U; - return - (int16_t)libcrux_ml_kem_vector_get_n_least_significant_bits(coefficient_bits, - (uint32_t)compressed); + return (int16_t)libcrux_ml_kem_vector_get_n_least_significant_bits( + coefficient_bits, (uint32_t)compressed); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ - int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[2U], zeta0); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[2U], zeta0); v.elements[2U] = v.elements[0U] - t; v.elements[0U] = v.elements[0U] + t; - int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[3U], zeta0); + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[3U], zeta0); v.elements[3U] = v.elements[1U] - t0; v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[6U], zeta1); + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[6U], zeta1); v.elements[6U] = v.elements[4U] - t1; v.elements[4U] = v.elements[4U] + t1; - int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[7U], zeta1); + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[7U], zeta1); v.elements[7U] = v.elements[5U] - t2; v.elements[5U] = v.elements[5U] + t2; - int16_t - t3 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)2U], - zeta2); - v.elements[(size_t)8U + (size_t)2U] = v.elements[(size_t)8U + (size_t)0U] - t3; - v.elements[(size_t)8U + (size_t)0U] = v.elements[(size_t)8U + (size_t)0U] + t3; - int16_t - t4 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)3U], - zeta2); - v.elements[(size_t)8U + (size_t)3U] = v.elements[(size_t)8U + (size_t)1U] - t4; - v.elements[(size_t)8U + (size_t)1U] = v.elements[(size_t)8U + (size_t)1U] + t4; - int16_t - t5 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], - zeta3); - v.elements[(size_t)8U + (size_t)6U] = v.elements[(size_t)8U + (size_t)4U] - t5; - v.elements[(size_t)8U + (size_t)4U] = v.elements[(size_t)8U + (size_t)4U] + t5; - int16_t - t6 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], - zeta3); - v.elements[(size_t)8U + (size_t)7U] = v.elements[(size_t)8U + (size_t)5U] - t6; - v.elements[(size_t)8U + (size_t)5U] = v.elements[(size_t)8U + (size_t)5U] + t6; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)2U], zeta2); + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)3U], zeta2); + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)6U], zeta3); + v.elements[(size_t)8U + (size_t)6U] = + v.elements[(size_t)8U + (size_t)4U] - t5; + v.elements[(size_t)8U + (size_t)4U] = + v.elements[(size_t)8U + (size_t)4U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)7U], zeta3); + v.elements[(size_t)8U + (size_t)7U] = + v.elements[(size_t)8U + (size_t)5U] - t6; + v.elements[(size_t)8U + (size_t)5U] = + v.elements[(size_t)8U + (size_t)5U] + t6; return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { return libcrux_ml_kem_vector_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1 -) -{ - int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[4U], zeta0); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1) { + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[4U], zeta0); v.elements[4U] = v.elements[0U] - t; v.elements[0U] = v.elements[0U] + t; - int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[5U], zeta0); + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[5U], zeta0); v.elements[5U] = v.elements[1U] - t0; v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[6U], zeta0); + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[6U], zeta0); v.elements[6U] = v.elements[2U] - t1; v.elements[2U] = v.elements[2U] + t1; - int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[7U], zeta0); + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[7U], zeta0); v.elements[7U] = v.elements[3U] - t2; v.elements[3U] = v.elements[3U] + t2; - int16_t - t3 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)4U], - zeta1); - v.elements[(size_t)8U + (size_t)4U] = v.elements[(size_t)8U + (size_t)0U] - t3; - v.elements[(size_t)8U + (size_t)0U] = v.elements[(size_t)8U + (size_t)0U] + t3; - int16_t - t4 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)5U], - zeta1); - v.elements[(size_t)8U + (size_t)5U] = v.elements[(size_t)8U + (size_t)1U] - t4; - v.elements[(size_t)8U + (size_t)1U] = v.elements[(size_t)8U + (size_t)1U] + t4; - int16_t - t5 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)6U], - zeta1); - v.elements[(size_t)8U + (size_t)6U] = v.elements[(size_t)8U + (size_t)2U] - t5; - v.elements[(size_t)8U + (size_t)2U] = v.elements[(size_t)8U + (size_t)2U] + t5; - int16_t - t6 = - libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[(size_t)8U + (size_t)7U], - zeta1); - v.elements[(size_t)8U + (size_t)7U] = v.elements[(size_t)8U + (size_t)3U] - t6; - v.elements[(size_t)8U + (size_t)3U] = v.elements[(size_t)8U + (size_t)3U] + t6; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)4U], zeta1); + v.elements[(size_t)8U + (size_t)4U] = + v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)5U], zeta1); + v.elements[(size_t)8U + (size_t)5U] = + v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)6U], zeta1); + v.elements[(size_t)8U + (size_t)6U] = + v.elements[(size_t)8U + (size_t)2U] - t5; + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + (size_t)2U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)7U], zeta1); + v.elements[(size_t)8U + (size_t)7U] = + v.elements[(size_t)8U + (size_t)3U] - t6; + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + (size_t)3U] + t6; return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1 -) -{ + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1) { return libcrux_ml_kem_vector_ntt_layer_2_step(a, zeta0, zeta1); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta -) -{ - int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[8U], zeta); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta) { + int16_t t = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[8U], zeta); v.elements[8U] = v.elements[0U] - t; v.elements[0U] = v.elements[0U] + t; - int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[9U], zeta); + int16_t t0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[9U], zeta); v.elements[9U] = v.elements[1U] - t0; v.elements[1U] = v.elements[1U] + t0; - int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[10U], zeta); + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[10U], zeta); v.elements[10U] = v.elements[2U] - t1; v.elements[2U] = v.elements[2U] + t1; - int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[11U], zeta); + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[11U], zeta); v.elements[11U] = v.elements[3U] - t2; v.elements[3U] = v.elements[3U] + t2; - int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[12U], zeta); + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[12U], zeta); v.elements[12U] = v.elements[4U] - t3; v.elements[4U] = v.elements[4U] + t3; - int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[13U], zeta); + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[13U], zeta); v.elements[13U] = v.elements[5U] - t4; v.elements[5U] = v.elements[5U] + t4; - int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[14U], zeta); + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[14U], zeta); v.elements[14U] = v.elements[6U] - t5; v.elements[6U] = v.elements[6U] + t5; - int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[15U], zeta); + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[15U], zeta); v.elements[15U] = v.elements[7U] - t6; v.elements[7U] = v.elements[7U] + t6; return v; @@ -486,258 +972,235 @@ libcrux_ml_kem_vector_ntt_layer_3_step( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta -) -{ + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta) { return libcrux_ml_kem_vector_ntt_layer_3_step(a, zeta); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { int16_t a_minus_b = v.elements[2U] - v.elements[0U]; - int16_t - uu____0 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[0U] + v.elements[2U]); + int16_t uu____0 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[0U] + v.elements[2U]); v.elements[0U] = uu____0; - int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); v.elements[2U] = uu____1; int16_t a_minus_b0 = v.elements[3U] - v.elements[1U]; - int16_t - uu____2 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[1U] + v.elements[3U]); + int16_t uu____2 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[1U] + v.elements[3U]); v.elements[1U] = uu____2; - int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); v.elements[3U] = uu____3; int16_t a_minus_b1 = v.elements[6U] - v.elements[4U]; - int16_t - uu____4 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[4U] + v.elements[6U]); + int16_t uu____4 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[4U] + v.elements[6U]); v.elements[4U] = uu____4; - int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta1); + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta1); v.elements[6U] = uu____5; int16_t a_minus_b2 = v.elements[7U] - v.elements[5U]; - int16_t - uu____6 = libcrux_ml_kem_vector_barrett_reduce_element(v.elements[5U] + v.elements[7U]); + int16_t uu____6 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[5U] + v.elements[7U]); v.elements[5U] = uu____6; - int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta1); + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta1); v.elements[7U] = uu____7; - int16_t a_minus_b3 = v.elements[(size_t)8U + (size_t)2U] - v.elements[(size_t)8U + (size_t)0U]; - int16_t - uu____8 = - libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U - + (size_t)0U] - + v.elements[(size_t)8U + (size_t)2U]); + int16_t a_minus_b3 = + v.elements[(size_t)8U + (size_t)2U] - v.elements[(size_t)8U + (size_t)0U]; + int16_t uu____8 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)0U] + + v.elements[(size_t)8U + (size_t)2U]); v.elements[(size_t)8U + (size_t)0U] = uu____8; - int16_t uu____9 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta2); + int16_t uu____9 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta2); v.elements[(size_t)8U + (size_t)2U] = uu____9; - int16_t a_minus_b4 = v.elements[(size_t)8U + (size_t)3U] - v.elements[(size_t)8U + (size_t)1U]; - int16_t - uu____10 = - libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U - + (size_t)1U] - + v.elements[(size_t)8U + (size_t)3U]); + int16_t a_minus_b4 = + v.elements[(size_t)8U + (size_t)3U] - v.elements[(size_t)8U + (size_t)1U]; + int16_t uu____10 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)1U] + + v.elements[(size_t)8U + (size_t)3U]); v.elements[(size_t)8U + (size_t)1U] = uu____10; - int16_t uu____11 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta2); + int16_t uu____11 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta2); v.elements[(size_t)8U + (size_t)3U] = uu____11; - int16_t a_minus_b5 = v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)4U]; - int16_t - uu____12 = - libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U - + (size_t)4U] - + v.elements[(size_t)8U + (size_t)6U]); + int16_t a_minus_b5 = + v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)4U]; + int16_t uu____12 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)4U] + + v.elements[(size_t)8U + (size_t)6U]); v.elements[(size_t)8U + (size_t)4U] = uu____12; - int16_t uu____13 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta3); + int16_t uu____13 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta3); v.elements[(size_t)8U + (size_t)6U] = uu____13; - int16_t a_minus_b6 = v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)5U]; - int16_t - uu____14 = - libcrux_ml_kem_vector_barrett_reduce_element(v.elements[(size_t)8U - + (size_t)5U] - + v.elements[(size_t)8U + (size_t)7U]); + int16_t a_minus_b6 = + v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)5U]; + int16_t uu____14 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)5U] + + v.elements[(size_t)8U + (size_t)7U]); v.elements[(size_t)8U + (size_t)5U] = uu____14; - int16_t uu____15 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta3); + int16_t uu____15 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta3); v.elements[(size_t)8U + (size_t)7U] = uu____15; return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ - return libcrux_ml_kem_vector_inv_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_inv_ntt_layer_1_step(a, zeta0, zeta1, zeta2, + zeta3); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1 -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1) { int16_t a_minus_b = v.elements[4U] - v.elements[0U]; v.elements[0U] = v.elements[0U] + v.elements[4U]; - int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); v.elements[4U] = uu____0; int16_t a_minus_b0 = v.elements[5U] - v.elements[1U]; v.elements[1U] = v.elements[1U] + v.elements[5U]; - int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); v.elements[5U] = uu____1; int16_t a_minus_b1 = v.elements[6U] - v.elements[2U]; v.elements[2U] = v.elements[2U] + v.elements[6U]; - int16_t uu____2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta0); + int16_t uu____2 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta0); v.elements[6U] = uu____2; int16_t a_minus_b2 = v.elements[7U] - v.elements[3U]; v.elements[3U] = v.elements[3U] + v.elements[7U]; - int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta0); + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta0); v.elements[7U] = uu____3; - int16_t a_minus_b3 = v.elements[(size_t)8U + (size_t)4U] - v.elements[(size_t)8U + (size_t)0U]; + int16_t a_minus_b3 = + v.elements[(size_t)8U + (size_t)4U] - v.elements[(size_t)8U + (size_t)0U]; v.elements[(size_t)8U + (size_t)0U] = - v.elements[(size_t)8U - + (size_t)0U] - + v.elements[(size_t)8U + (size_t)4U]; - int16_t uu____4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta1); + v.elements[(size_t)8U + (size_t)0U] + v.elements[(size_t)8U + (size_t)4U]; + int16_t uu____4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta1); v.elements[(size_t)8U + (size_t)4U] = uu____4; - int16_t a_minus_b4 = v.elements[(size_t)8U + (size_t)5U] - v.elements[(size_t)8U + (size_t)1U]; + int16_t a_minus_b4 = + v.elements[(size_t)8U + (size_t)5U] - v.elements[(size_t)8U + (size_t)1U]; v.elements[(size_t)8U + (size_t)1U] = - v.elements[(size_t)8U - + (size_t)1U] - + v.elements[(size_t)8U + (size_t)5U]; - int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta1); + v.elements[(size_t)8U + (size_t)1U] + v.elements[(size_t)8U + (size_t)5U]; + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta1); v.elements[(size_t)8U + (size_t)5U] = uu____5; - int16_t a_minus_b5 = v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)2U]; + int16_t a_minus_b5 = + v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)2U]; v.elements[(size_t)8U + (size_t)2U] = - v.elements[(size_t)8U - + (size_t)2U] - + v.elements[(size_t)8U + (size_t)6U]; - int16_t uu____6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta1); + v.elements[(size_t)8U + (size_t)2U] + v.elements[(size_t)8U + (size_t)6U]; + int16_t uu____6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta1); v.elements[(size_t)8U + (size_t)6U] = uu____6; - int16_t a_minus_b6 = v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)3U]; + int16_t a_minus_b6 = + v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)3U]; v.elements[(size_t)8U + (size_t)3U] = - v.elements[(size_t)8U - + (size_t)3U] - + v.elements[(size_t)8U + (size_t)7U]; - int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta1); + v.elements[(size_t)8U + (size_t)3U] + v.elements[(size_t)8U + (size_t)7U]; + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta1); v.elements[(size_t)8U + (size_t)7U] = uu____7; return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1 -) -{ + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1) { return libcrux_ml_kem_vector_inv_ntt_layer_2_step(a, zeta0, zeta1); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta -) -{ + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta) { int16_t a_minus_b = v.elements[8U] - v.elements[0U]; v.elements[0U] = v.elements[0U] + v.elements[8U]; - int16_t uu____0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta); + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta); v.elements[8U] = uu____0; int16_t a_minus_b0 = v.elements[9U] - v.elements[1U]; v.elements[1U] = v.elements[1U] + v.elements[9U]; - int16_t uu____1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta); + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta); v.elements[9U] = uu____1; int16_t a_minus_b1 = v.elements[10U] - v.elements[2U]; v.elements[2U] = v.elements[2U] + v.elements[10U]; - int16_t uu____2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta); + int16_t uu____2 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta); v.elements[10U] = uu____2; int16_t a_minus_b2 = v.elements[11U] - v.elements[3U]; v.elements[3U] = v.elements[3U] + v.elements[11U]; - int16_t uu____3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta); + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta); v.elements[11U] = uu____3; int16_t a_minus_b3 = v.elements[12U] - v.elements[4U]; v.elements[4U] = v.elements[4U] + v.elements[12U]; - int16_t uu____4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta); + int16_t uu____4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta); v.elements[12U] = uu____4; int16_t a_minus_b4 = v.elements[13U] - v.elements[5U]; v.elements[5U] = v.elements[5U] + v.elements[13U]; - int16_t uu____5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta); + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta); v.elements[13U] = uu____5; int16_t a_minus_b5 = v.elements[14U] - v.elements[6U]; v.elements[6U] = v.elements[6U] + v.elements[14U]; - int16_t uu____6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta); + int16_t uu____6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta); v.elements[14U] = uu____6; int16_t a_minus_b6 = v.elements[15U] - v.elements[7U]; v.elements[7U] = v.elements[7U] + v.elements[15U]; - int16_t uu____7 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta); + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta); v.elements[15U] = uu____7; return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta -) -{ + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta) { return libcrux_ml_kem_vector_inv_ntt_layer_3_step(a, zeta); } -inline K___int16_t_int16_t -libcrux_ml_kem_vector_ntt_multiply_binomials( - K___int16_t_int16_t _, - K___int16_t_int16_t _0, - int16_t zeta -) -{ +inline K___int16_t_int16_t libcrux_ml_kem_vector_ntt_multiply_binomials( + K___int16_t_int16_t _, K___int16_t_int16_t _0, int16_t zeta) { int16_t a0 = _.fst; int16_t a1 = _.snd; int16_t b0 = _0.fst; int16_t b1 = _0.snd; int32_t uu____0 = (int32_t)a0 * (int32_t)b0; - int16_t - uu____1 = - libcrux_ml_kem_vector_montgomery_reduce_element(uu____0 - + - (int32_t)libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)a1 * (int32_t)b1) - * (int32_t)zeta); - return - ( - (K___int16_t_int16_t){ - .fst = uu____1, - .snd = libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)a0 - * (int32_t)b1 - + (int32_t)a1 * (int32_t)b0) - } - ); + int16_t uu____1 = libcrux_ml_kem_vector_montgomery_reduce_element( + uu____0 + (int32_t)libcrux_ml_kem_vector_montgomery_reduce_element( + (int32_t)a1 * (int32_t)b1) * + (int32_t)zeta); + return ((K___int16_t_int16_t){ + .fst = uu____1, + .snd = libcrux_ml_kem_vector_montgomery_reduce_element( + (int32_t)a0 * (int32_t)b1 + (int32_t)a1 * (int32_t)b0)}); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_multiply( - libcrux_ml_kem_vector_portable_PortableVector *lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ - libcrux_ml_kem_vector_portable_PortableVector out = libcrux_ml_kem_vector_zero(); + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_PortableVector out = + libcrux_ml_kem_vector_zero(); K___int16_t_int16_t lit0; lit0.fst = lhs->elements[0U]; lit0.snd = lhs->elements[1U]; K___int16_t_int16_t lit1; lit1.fst = rhs->elements[0U]; lit1.snd = rhs->elements[1U]; - K___int16_t_int16_t product = libcrux_ml_kem_vector_ntt_multiply_binomials(lit0, lit1, zeta0); + K___int16_t_int16_t product = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit0, lit1, zeta0); out.elements[0U] = product.fst; out.elements[1U] = product.snd; K___int16_t_int16_t lit2; @@ -746,8 +1209,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit3; lit3.fst = rhs->elements[2U]; lit3.snd = rhs->elements[3U]; - K___int16_t_int16_t - product0 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit2, lit3, -zeta0); + K___int16_t_int16_t product0 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit2, lit3, -zeta0); out.elements[2U] = product0.fst; out.elements[3U] = product0.snd; K___int16_t_int16_t lit4; @@ -756,7 +1219,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit5; lit5.fst = rhs->elements[4U]; lit5.snd = rhs->elements[5U]; - K___int16_t_int16_t product1 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit4, lit5, zeta1); + K___int16_t_int16_t product1 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit4, lit5, zeta1); out.elements[4U] = product1.fst; out.elements[5U] = product1.snd; K___int16_t_int16_t lit6; @@ -765,8 +1229,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit7; lit7.fst = rhs->elements[6U]; lit7.snd = rhs->elements[7U]; - K___int16_t_int16_t - product2 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit6, lit7, -zeta1); + K___int16_t_int16_t product2 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit6, lit7, -zeta1); out.elements[6U] = product2.fst; out.elements[7U] = product2.snd; K___int16_t_int16_t lit8; @@ -775,7 +1239,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit9; lit9.fst = rhs->elements[(size_t)8U + (size_t)0U]; lit9.snd = rhs->elements[(size_t)8U + (size_t)1U]; - K___int16_t_int16_t product3 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit8, lit9, zeta2); + K___int16_t_int16_t product3 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit8, lit9, zeta2); out.elements[(size_t)8U + (size_t)0U] = product3.fst; out.elements[(size_t)8U + (size_t)1U] = product3.snd; K___int16_t_int16_t lit10; @@ -784,8 +1249,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit11; lit11.fst = rhs->elements[(size_t)8U + (size_t)2U]; lit11.snd = rhs->elements[(size_t)8U + (size_t)3U]; - K___int16_t_int16_t - product4 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit10, lit11, -zeta2); + K___int16_t_int16_t product4 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit10, lit11, -zeta2); out.elements[(size_t)8U + (size_t)2U] = product4.fst; out.elements[(size_t)8U + (size_t)3U] = product4.snd; K___int16_t_int16_t lit12; @@ -794,8 +1259,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit13; lit13.fst = rhs->elements[(size_t)8U + (size_t)4U]; lit13.snd = rhs->elements[(size_t)8U + (size_t)5U]; - K___int16_t_int16_t - product5 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit12, lit13, zeta3); + K___int16_t_int16_t product5 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit12, lit13, zeta3); out.elements[(size_t)8U + (size_t)4U] = product5.fst; out.elements[(size_t)8U + (size_t)5U] = product5.snd; K___int16_t_int16_t lit14; @@ -804,8 +1269,8 @@ libcrux_ml_kem_vector_ntt_multiply( K___int16_t_int16_t lit; lit.fst = rhs->elements[(size_t)8U + (size_t)6U]; lit.snd = rhs->elements[(size_t)8U + (size_t)7U]; - K___int16_t_int16_t - product6 = libcrux_ml_kem_vector_ntt_multiply_binomials(lit14, lit, -zeta3); + K___int16_t_int16_t product6 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit14, lit, -zeta3); out.elements[(size_t)8U + (size_t)6U] = product6.fst; out.elements[(size_t)8U + (size_t)7U] = product6.snd; return out; @@ -813,818 +1278,778 @@ libcrux_ml_kem_vector_ntt_multiply( libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( - libcrux_ml_kem_vector_portable_PortableVector *lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -) -{ - return libcrux_ml_kem_vector_ntt_multiply(lhs, rhs, zeta0, zeta1, zeta2, zeta3); -} - -inline void -libcrux_ml_kem_vector_serialize_1( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[2U] -) -{ - uint8_t result[2U] = { 0U }; - KRML_MAYBE_FOR8(i, - (size_t)0U, - (size_t)8U, - (size_t)1U, - size_t i0 = i; - size_t uu____0 = (size_t)0U; - result[uu____0] = (uint32_t)result[uu____0] | (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;); - KRML_MAYBE_FOR8(i, - (size_t)8U, - (size_t)16U, - (size_t)1U, - size_t i0 = i; - size_t uu____1 = (size_t)1U; - result[uu____1] = - (uint32_t)result[uu____1] - | (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)(i0 - (size_t)8U);); - memcpy(ret, result, (size_t)2U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[2U] -) -{ + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_ntt_multiply(lhs, rhs, zeta0, zeta1, zeta2, + zeta3); +} + +inline void libcrux_ml_kem_vector_serialize_1( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[2U]) { + uint8_t result[2U] = {0U}; + KRML_MAYBE_FOR8( + i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; + size_t uu____0 = (size_t)0U; + result[uu____0] = (uint32_t)result[uu____0] | + (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;); + KRML_MAYBE_FOR8(i, (size_t)8U, (size_t)16U, (size_t)1U, size_t i0 = i; + size_t uu____1 = (size_t)1U; + result[uu____1] = (uint32_t)result[uu____1] | + (uint32_t)(uint8_t)v.elements[i0] + << (uint32_t)(i0 - (size_t)8U);); + memcpy(ret, result, (size_t)2U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[2U]) { uint8_t ret0[2U]; libcrux_ml_kem_vector_serialize_1(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v) -{ - libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); - KRML_MAYBE_FOR8(i, - (size_t)0U, - (size_t)8U, - (size_t)1U, - size_t i0 = i; - uint8_t *uu____0 = &Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[i0] = (int16_t)((uint32_t)uu____0[0U] >> (uint32_t)i0 & 1U);); - for (size_t i = (size_t)8U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + KRML_MAYBE_FOR8(i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; + uint8_t *uu____0 = &Eurydice_slice_index( + v, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = + (int16_t)((uint32_t)uu____0[0U] >> (uint32_t)i0 & 1U);); + for (size_t i = (size_t)8U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - uint8_t *uu____1 = &Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[i0] = (int16_t)((uint32_t)uu____1[0U] >> (uint32_t)(i0 - (size_t)8U) & 1U); + uint8_t *uu____1 = + &Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = + (int16_t)((uint32_t)uu____1[0U] >> (uint32_t)(i0 - (size_t)8U) & 1U); } return result; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_1(a); } -inline void -libcrux_ml_kem_vector_serialize_4( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[8U] -) -{ - uint8_t result[8U] = { 0U }; - result[0U] = (uint32_t)(uint8_t)v.elements[1U] << 4U | (uint32_t)(uint8_t)v.elements[0U]; - result[1U] = (uint32_t)(uint8_t)v.elements[3U] << 4U | (uint32_t)(uint8_t)v.elements[2U]; - result[2U] = (uint32_t)(uint8_t)v.elements[5U] << 4U | (uint32_t)(uint8_t)v.elements[4U]; - result[3U] = (uint32_t)(uint8_t)v.elements[7U] << 4U | (uint32_t)(uint8_t)v.elements[6U]; - result[4U] = - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)1U] - << 4U - | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)0U]; - result[5U] = - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)3U] - << 4U - | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)2U]; - result[6U] = - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)5U] - << 4U - | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)4U]; - result[7U] = - (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)7U] - << 4U - | (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)6U]; - memcpy(ret, result, (size_t)8U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[8U] -) -{ +inline void libcrux_ml_kem_vector_serialize_4( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[8U]) { + uint8_t result[8U] = {0U}; + result[0U] = (uint32_t)(uint8_t)v.elements[1U] << 4U | + (uint32_t)(uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)v.elements[3U] << 4U | + (uint32_t)(uint8_t)v.elements[2U]; + result[2U] = (uint32_t)(uint8_t)v.elements[5U] << 4U | + (uint32_t)(uint8_t)v.elements[4U]; + result[3U] = (uint32_t)(uint8_t)v.elements[7U] << 4U | + (uint32_t)(uint8_t)v.elements[6U]; + result[4U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)1U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[5U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)3U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)2U]; + result[6U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)5U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)4U]; + result[7U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)7U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)6U]; + memcpy(ret, result, (size_t)8U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[8U]) { uint8_t ret0[8U]; libcrux_ml_kem_vector_serialize_4(a, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes) -{ - libcrux_ml_kem_vector_portable_PortableVector v = libcrux_ml_kem_vector_zero(); - uint8_t *uu____0 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); +libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector v = + libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 15U); - uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); v.elements[1U] = (int16_t)((uint32_t)uu____1[0U] >> 4U & 15U); - uint8_t *uu____2 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____2 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); v.elements[2U] = (int16_t)((uint32_t)uu____2[0U] & 15U); - uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); v.elements[3U] = (int16_t)((uint32_t)uu____3[0U] >> 4U & 15U); - uint8_t *uu____4 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____4 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); v.elements[4U] = (int16_t)((uint32_t)uu____4[0U] & 15U); - uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); v.elements[5U] = (int16_t)((uint32_t)uu____5[0U] >> 4U & 15U); - uint8_t *uu____6 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); v.elements[6U] = (int16_t)((uint32_t)uu____6[0U] & 15U); - uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); v.elements[7U] = (int16_t)((uint32_t)uu____7[0U] >> 4U & 15U); - uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); v.elements[8U] = (int16_t)((uint32_t)uu____8[0U] & 15U); - uint8_t *uu____9 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____9 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); v.elements[9U] = (int16_t)((uint32_t)uu____9[0U] >> 4U & 15U); - uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); v.elements[10U] = (int16_t)((uint32_t)uu____10[0U] & 15U); - uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); v.elements[11U] = (int16_t)((uint32_t)uu____11[0U] >> 4U & 15U); - uint8_t *uu____12 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____12 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); v.elements[12U] = (int16_t)((uint32_t)uu____12[0U] & 15U); - uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); v.elements[13U] = (int16_t)((uint32_t)uu____13[0U] >> 4U & 15U); - uint8_t *uu____14 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____14 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); v.elements[14U] = (int16_t)((uint32_t)uu____14[0U] & 15U); - uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); v.elements[15U] = (int16_t)((uint32_t)uu____15[0U] >> 4U & 15U); return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_4(a); } -inline void -libcrux_ml_kem_vector_serialize_5( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[10U] -) -{ - uint8_t result[10U] = { 0U }; +inline void libcrux_ml_kem_vector_serialize_5( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[10U]) { + uint8_t result[10U] = {0U}; result[0U] = (uint8_t)((v.elements[1U] & (int16_t)7) << 5U | v.elements[0U]); result[1U] = - (uint8_t)(((v.elements[3U] & (int16_t)1) << 7U | v.elements[2U] << 2U) | v.elements[1U] >> 3U); - result[2U] = (uint8_t)((v.elements[4U] & (int16_t)15) << 4U | v.elements[3U] >> 1U); + (uint8_t)(((v.elements[3U] & (int16_t)1) << 7U | v.elements[2U] << 2U) | + v.elements[1U] >> 3U); + result[2U] = + (uint8_t)((v.elements[4U] & (int16_t)15) << 4U | v.elements[3U] >> 1U); result[3U] = - (uint8_t)(((v.elements[6U] & (int16_t)3) << 6U | v.elements[5U] << 1U) | v.elements[4U] >> 4U); + (uint8_t)(((v.elements[6U] & (int16_t)3) << 6U | v.elements[5U] << 1U) | + v.elements[4U] >> 4U); result[4U] = (uint8_t)(v.elements[7U] << 3U | v.elements[6U] >> 2U); result[5U] = - (uint8_t)((v.elements[(size_t)8U + (size_t)1U] & (int16_t)7) - << 5U - | v.elements[(size_t)8U + (size_t)0U]); + (uint8_t)((v.elements[(size_t)8U + (size_t)1U] & (int16_t)7) << 5U | + v.elements[(size_t)8U + (size_t)0U]); result[6U] = - (uint8_t)(((v.elements[(size_t)8U + (size_t)3U] & (int16_t)1) - << 7U - | v.elements[(size_t)8U + (size_t)2U] << 2U) - | v.elements[(size_t)8U + (size_t)1U] >> 3U); + (uint8_t)(((v.elements[(size_t)8U + (size_t)3U] & (int16_t)1) << 7U | + v.elements[(size_t)8U + (size_t)2U] << 2U) | + v.elements[(size_t)8U + (size_t)1U] >> 3U); result[7U] = - (uint8_t)((v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) - << 4U - | v.elements[(size_t)8U + (size_t)3U] >> 1U); + (uint8_t)((v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) << 4U | + v.elements[(size_t)8U + (size_t)3U] >> 1U); result[8U] = - (uint8_t)(((v.elements[(size_t)8U + (size_t)6U] & (int16_t)3) - << 6U - | v.elements[(size_t)8U + (size_t)5U] << 1U) - | v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[9U] = - (uint8_t)(v.elements[(size_t)8U - + (size_t)7U] - << 3U - | v.elements[(size_t)8U + (size_t)6U] >> 2U); - memcpy(ret, result, (size_t)10U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[10U] -) -{ + (uint8_t)(((v.elements[(size_t)8U + (size_t)6U] & (int16_t)3) << 6U | + v.elements[(size_t)8U + (size_t)5U] << 1U) | + v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[9U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] << 3U | + v.elements[(size_t)8U + (size_t)6U] >> 2U); + memcpy(ret, result, (size_t)10U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[10U]) { uint8_t ret0[10U]; libcrux_ml_kem_vector_serialize_5(a, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes) -{ - libcrux_ml_kem_vector_portable_PortableVector v = libcrux_ml_kem_vector_zero(); - uint8_t *uu____0 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); +libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector v = + libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 31U); - uint8_t - uu____1 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & 3U) - << 3U; - uint8_t *uu____2 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____1 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + 3U) + << 3U; + uint8_t *uu____2 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); v.elements[1U] = (int16_t)((uint32_t)uu____1 | (uint32_t)uu____2[0U] >> 5U); - uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); v.elements[2U] = (int16_t)((uint32_t)uu____3[0U] >> 2U & 31U); - uint8_t - uu____4 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & 15U) - << 1U; - uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____4 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + 15U) + << 1U; + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); v.elements[3U] = (int16_t)((uint32_t)uu____4 | (uint32_t)uu____5[0U] >> 7U); - uint8_t - uu____6 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) & 1U) - << 4U; - uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____6 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + 1U) + << 4U; + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); v.elements[4U] = (int16_t)((uint32_t)uu____6 | (uint32_t)uu____7[0U] >> 4U); - uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); v.elements[5U] = (int16_t)((uint32_t)uu____8[0U] >> 1U & 31U); - uint8_t - uu____9 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) & 7U) - << 2U; - uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____9 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + 7U) + << 2U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); v.elements[6U] = (int16_t)((uint32_t)uu____9 | (uint32_t)uu____10[0U] >> 6U); - uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); v.elements[7U] = (int16_t)((uint32_t)uu____11[0U] >> 3U); - uint8_t - *uu____12 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____12 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); v.elements[8U] = (int16_t)((uint32_t)uu____12[0U] & 31U); - uint8_t - uu____13 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t) - & 3U) - << 3U; - uint8_t - *uu____14 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____13 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + 3U) + << 3U; + uint8_t *uu____14 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); v.elements[9U] = (int16_t)((uint32_t)uu____13 | (uint32_t)uu____14[0U] >> 5U); - uint8_t - *uu____15 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); v.elements[10U] = (int16_t)((uint32_t)uu____15[0U] >> 2U & 31U); - uint8_t - uu____16 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, uint8_t *, uint8_t) - & 15U) - << 1U; - uint8_t - *uu____17 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, uint8_t *, uint8_t); - v.elements[11U] = (int16_t)((uint32_t)uu____16 | (uint32_t)uu____17[0U] >> 7U); - uint8_t - uu____18 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t) - & 1U) - << 4U; - uint8_t - *uu____19 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, uint8_t *, uint8_t); - v.elements[12U] = (int16_t)((uint32_t)uu____18 | (uint32_t)uu____19[0U] >> 4U); - uint8_t - *uu____20 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____16 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + 15U) + << 1U; + uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + v.elements[11U] = + (int16_t)((uint32_t)uu____16 | (uint32_t)uu____17[0U] >> 7U); + uint8_t uu____18 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + 1U) + << 4U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + v.elements[12U] = + (int16_t)((uint32_t)uu____18 | (uint32_t)uu____19[0U] >> 4U); + uint8_t *uu____20 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); v.elements[13U] = (int16_t)((uint32_t)uu____20[0U] >> 1U & 31U); - uint8_t - uu____21 = - ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, uint8_t *, uint8_t) - & 7U) - << 2U; - uint8_t - *uu____22 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, uint8_t *, uint8_t); - v.elements[14U] = (int16_t)((uint32_t)uu____21 | (uint32_t)uu____22[0U] >> 6U); - uint8_t - *uu____23 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____21 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + 7U) + << 2U; + uint8_t *uu____22 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); + v.elements[14U] = + (int16_t)((uint32_t)uu____21 | (uint32_t)uu____22[0U] >> 6U); + uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); v.elements[15U] = (int16_t)((uint32_t)uu____23[0U] >> 3U); return v; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_5(a); } -inline void -libcrux_ml_kem_vector_serialize_10( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[20U] -) -{ - uint8_t result[20U] = { 0U }; +inline void libcrux_ml_kem_vector_serialize_10( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[20U]) { + uint8_t result[20U] = {0U}; result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); - result[1U] = - (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[0U] >> 8U & (int16_t)3); - result[2U] = - (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[1U] >> 6U & (int16_t)15); - result[3U] = - (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[2U] >> 4U & (int16_t)63); + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U & (int16_t)3); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[1U] >> 6U & (int16_t)15); + result[3U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[2U] >> 4U & (int16_t)63); result[4U] = (uint8_t)(v.elements[3U] >> 2U & (int16_t)255); result[5U] = (uint8_t)(v.elements[4U] & (int16_t)255); - result[6U] = - (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[4U] >> 8U & (int16_t)3); - result[7U] = - (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[5U] >> 6U & (int16_t)15); - result[8U] = - (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[6U] >> 4U & (int16_t)63); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[4U] >> 8U & (int16_t)3); + result[7U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[5U] >> 6U & (int16_t)15); + result[8U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[6U] >> 4U & (int16_t)63); result[9U] = (uint8_t)(v.elements[7U] >> 2U & (int16_t)255); result[10U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); result[11U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U & (int16_t)3); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U & + (int16_t)3); result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 6U & (int16_t)15); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 6U & + (int16_t)15); result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 4U & (int16_t)63); - result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 2U & (int16_t)255); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 4U & + (int16_t)63); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 2U & (int16_t)255); result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U & (int16_t)3); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U & + (int16_t)3); result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 6U & (int16_t)15); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 6U & + (int16_t)15); result[18U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 4U & (int16_t)63); - result[19U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 2U & (int16_t)255); - memcpy(ret, result, (size_t)20U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[20U] -) -{ + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 4U & + (int16_t)63); + result[19U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 2U & (int16_t)255); + memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[20U]) { uint8_t ret0[20U]; libcrux_ml_kem_vector_serialize_10(a, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes) -{ - libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); - int16_t - uu____0 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) - << 8U; - uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); +libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); result.elements[0U] = uu____0 | ((int16_t)uu____1[0U] & (int16_t)255); - int16_t - uu____2 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) - << 6U; - uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 2U; - int16_t - uu____4 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) - << 4U; - uint8_t *uu____5 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); result.elements[2U] = uu____4 | (int16_t)uu____5[0U] >> 4U; - int16_t - uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) << 2U; - uint8_t *uu____7 = &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); result.elements[3U] = uu____6 | (int16_t)uu____7[0U] >> 6U; - int16_t - uu____8 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) - << 8U; - uint8_t *uu____9 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + int16_t uu____8 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____9 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); result.elements[4U] = uu____8 | ((int16_t)uu____9[0U] & (int16_t)255); - int16_t - uu____10 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) - << 6U; - uint8_t *uu____11 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + int16_t uu____10 = ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); result.elements[5U] = uu____10 | (int16_t)uu____11[0U] >> 2U; - int16_t - uu____12 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) - << 4U; - uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + int16_t uu____12 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); result.elements[6U] = uu____12 | (int16_t)uu____13[0U] >> 4U; - int16_t - uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t) << 2U; - uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); result.elements[7U] = uu____14 | (int16_t)uu____15[0U] >> 6U; - int16_t - uu____16 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, uint8_t *, uint8_t) - & (int16_t)3) - << 8U; - uint8_t - *uu____17 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + int16_t uu____16 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); result.elements[8U] = uu____16 | ((int16_t)uu____17[0U] & (int16_t)255); - int16_t - uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, uint8_t *, uint8_t) - & (int16_t)15) - << 6U; - uint8_t - *uu____19 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); result.elements[9U] = uu____18 | (int16_t)uu____19[0U] >> 2U; - int16_t - uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, uint8_t *, uint8_t) - & (int16_t)63) - << 4U; - uint8_t - *uu____21 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); result.elements[10U] = uu____20 | (int16_t)uu____21[0U] >> 4U; - int16_t - uu____22 = - (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)4U, uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t - *uu____23 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, uint8_t *, uint8_t); + int16_t uu____22 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); result.elements[11U] = uu____22 | (int16_t)uu____23[0U] >> 6U; - int16_t - uu____24 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, uint8_t *, uint8_t) - & (int16_t)3) - << 8U; - uint8_t - *uu____25 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)5U, uint8_t, uint8_t *, uint8_t); + int16_t uu____24 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____25 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); result.elements[12U] = uu____24 | ((int16_t)uu____25[0U] & (int16_t)255); - int16_t - uu____26 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, uint8_t *, uint8_t) - & (int16_t)15) - << 6U; - uint8_t - *uu____27 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, uint8_t *, uint8_t); + int16_t uu____26 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____27 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); result.elements[13U] = uu____26 | (int16_t)uu____27[0U] >> 2U; - int16_t - uu____28 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, uint8_t *, uint8_t) - & (int16_t)63) - << 4U; - uint8_t - *uu____29 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, uint8_t *, uint8_t); + int16_t uu____28 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____29 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, + uint8_t, uint8_t *, uint8_t); result.elements[14U] = uu____28 | (int16_t)uu____29[0U] >> 4U; - int16_t - uu____30 = - (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)9U, uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t - *uu____31 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, uint8_t *, uint8_t); + int16_t uu____30 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); result.elements[15U] = uu____30 | (int16_t)uu____31[0U] >> 6U; return result; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_10(a); } -inline void -libcrux_ml_kem_vector_serialize_11( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[22U] -) -{ - uint8_t result[22U] = { 0U }; +inline void libcrux_ml_kem_vector_serialize_11( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[22U]) { + uint8_t result[22U] = {0U}; result[0U] = (uint8_t)v.elements[0U]; - result[1U] = - (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) - << 3U - | (uint32_t)(uint8_t)(v.elements[0U] >> 8U); - result[2U] = - (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[1U] >> 5U); result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); - result[4U] = - (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) - << 1U - | (uint32_t)(uint8_t)(v.elements[2U] >> 10U); - result[5U] = - (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[3U] >> 7U); - result[6U] = - (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) - << 7U - | (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | + (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | + (uint32_t)(uint8_t)(v.elements[4U] >> 4U); result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); - result[8U] = - (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[5U] >> 9U); - result[9U] = - (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) - << 5U - | (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | + (uint32_t)(uint8_t)(v.elements[6U] >> 6U); result[10U] = (uint8_t)(v.elements[7U] >> 3U); result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) - << 3U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) - << 6U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); - result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); result[15U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) - << 1U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) - << 4U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) - << 7U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); result[19U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) - << 2U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); result[20U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) - << 5U - | (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof (uint8_t)); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); } -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[22U] -) -{ +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[22U]) { uint8_t ret0[22U]; libcrux_ml_kem_vector_serialize_11(a, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes) -{ - libcrux_ml_kem_vector_portable_PortableVector result = libcrux_ml_kem_vector_zero(); - int16_t - uu____0 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t) & (int16_t)7) - << 8U; - uint8_t *uu____1 = &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); +libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; - int16_t - uu____2 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t) & (int16_t)63) - << 5U; - uint8_t *uu____3 = &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; - int16_t - uu____4 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t) & (int16_t)1) - << 10U; - int16_t - uu____5 = - uu____4 - | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 2U; - uint8_t *uu____6 = &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____5 = + uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; - int16_t - uu____7 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t) & (int16_t)15) - << 7U; - uint8_t *uu____8 = &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; - int16_t - uu____9 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t) & (int16_t)127) - << 4U; - uint8_t *uu____10 = &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; - int16_t - uu____11 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t) & (int16_t)3) - << 9U; - int16_t - uu____12 = - uu____11 - | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t) << 1U; - uint8_t *uu____13 = &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____12 = + uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) + << 1U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; - int16_t - uu____14 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t) & (int16_t)31) - << 6U; - uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; - int16_t - uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *, uint8_t) << 3U; - uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____17 = + &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; - int16_t - uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, uint8_t *, uint8_t) - & (int16_t)7) - << 8U; - uint8_t - *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, uint8_t, uint8_t *, uint8_t); + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; - int16_t - uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, uint8_t *, uint8_t) - & (int16_t)63) - << 5U; - uint8_t - *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, uint8_t *, uint8_t); + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; - int16_t - uu____22 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, uint8_t *, uint8_t) - & (int16_t)1) - << 10U; - int16_t - uu____23 = - uu____22 - | - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t - *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____23 = + uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; - int16_t - uu____25 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, uint8_t *, uint8_t) - & (int16_t)15) - << 7U; - uint8_t - *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, uint8_t *, uint8_t); + int16_t uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; - int16_t - uu____27 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, uint8_t *, uint8_t) - & (int16_t)127) - << 4U; - uint8_t - *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, uint8_t *, uint8_t); + int16_t uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; - int16_t - uu____29 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, uint8_t *, uint8_t) - & (int16_t)3) - << 9U; - int16_t - uu____30 = - uu____29 - | - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, uint8_t, uint8_t *, uint8_t) - << 1U; - uint8_t - *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, uint8_t *, uint8_t); + int16_t uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____30 = + uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, + uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; - int16_t - uu____32 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, uint8_t *, uint8_t) - & (int16_t)31) - << 6U; - uint8_t - *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, uint8_t *, uint8_t); + int16_t uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; - int16_t - uu____34 = - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, uint8_t *, uint8_t) - << 3U; - uint8_t - *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, uint8_t *, uint8_t); + int16_t uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, + uint8_t, uint8_t *, uint8_t); result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; return result; } libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_11(a); } -inline void -libcrux_ml_kem_vector_serialize_12( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[24U] -) -{ - uint8_t result[24U] = { 0U }; +inline void libcrux_ml_kem_vector_serialize_12( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[24U]) { + uint8_t result[24U] = {0U}; result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); - result[1U] = (uint8_t)(v.elements[0U] >> 8U | (v.elements[1U] & (int16_t)15) << 4U); + result[1U] = + (uint8_t)(v.elements[0U] >> 8U | (v.elements[1U] & (int16_t)15) << 4U); result[2U] = (uint8_t)(v.elements[1U] >> 4U & (int16_t)255); result[3U] = (uint8_t)(v.elements[2U] & (int16_t)255); - result[4U] = (uint8_t)(v.elements[2U] >> 8U | (v.elements[3U] & (int16_t)15) << 4U); + result[4U] = + (uint8_t)(v.elements[2U] >> 8U | (v.elements[3U] & (int16_t)15) << 4U); result[5U] = (uint8_t)(v.elements[3U] >> 4U & (int16_t)255); result[6U] = (uint8_t)(v.elements[4U] & (int16_t)255); - result[7U] = (uint8_t)(v.elements[4U] >> 8U | (v.elements[5U] & (int16_t)15) << 4U); + result[7U] = + (uint8_t)(v.elements[4U] >> 8U | (v.elements[5U] & (int16_t)15) << 4U); result[8U] = (uint8_t)(v.elements[5U] >> 4U & (int16_t)255); result[9U] = (uint8_t)(v.elements[6U] & (int16_t)255); - result[10U] = (uint8_t)(v.elements[6U] >> 8U | (v.elements[7U] & (int16_t)15) << 4U); + result[10U] = + (uint8_t)(v.elements[6U] >> 8U | (v.elements[7U] & (int16_t)15) << 4U); result[11U] = (uint8_t)(v.elements[7U] >> 4U & (int16_t)255); result[12U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); result[13U] = - (uint8_t)(v.elements[(size_t)8U - + (size_t)0U] - >> 8U - | (v.elements[(size_t)8U + (size_t)1U] & (int16_t)15) << 4U); - result[14U] = (uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 4U & (int16_t)255); + (uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U | + (v.elements[(size_t)8U + (size_t)1U] & (int16_t)15) << 4U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 4U & (int16_t)255); result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)255); result[16U] = - (uint8_t)(v.elements[(size_t)8U - + (size_t)2U] - >> 8U - | (v.elements[(size_t)8U + (size_t)3U] & (int16_t)15) << 4U); - result[17U] = (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 4U & (int16_t)255); + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 8U | + (v.elements[(size_t)8U + (size_t)3U] & (int16_t)15) << 4U); + result[17U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 4U & (int16_t)255); result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); result[19U] = - (uint8_t)(v.elements[(size_t)8U - + (size_t)4U] - >> 8U - | (v.elements[(size_t)8U + (size_t)5U] & (int16_t)15) << 4U); - result[20U] = (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 4U & (int16_t)255); + (uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U | + (v.elements[(size_t)8U + (size_t)5U] & (int16_t)15) << 4U); + result[20U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 4U & (int16_t)255); result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)255); result[22U] = - (uint8_t)(v.elements[(size_t)8U - + (size_t)6U] - >> 8U - | (v.elements[(size_t)8U + (size_t)7U] & (int16_t)15) << 4U); - result[23U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 4U & (int16_t)255); - memcpy(ret, result, (size_t)24U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[24U] -) -{ + (uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 8U | + (v.elements[(size_t)8U + (size_t)7U] & (int16_t)15) << 4U); + result[23U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 4U & (int16_t)255); + memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[24U]) { uint8_t ret0[24U]; libcrux_ml_kem_vector_serialize_12(a, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof (uint8_t)); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); } inline libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) -{ - libcrux_ml_kem_vector_portable_PortableVector re = libcrux_ml_kem_vector_zero(); - int16_t byte0 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - int16_t byte1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - int16_t byte2 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - int16_t byte3 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - int16_t byte4 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - int16_t byte5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - int16_t byte6 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - int16_t byte7 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - int16_t byte8 = (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - int16_t byte9 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - int16_t - byte10 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *, uint8_t); - int16_t - byte11 = (int16_t)Eurydice_slice_index(bytes, (size_t)11U, uint8_t, uint8_t *, uint8_t); +libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector re = + libcrux_ml_kem_vector_zero(); + int16_t byte0 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t byte1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t byte2 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t byte3 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t byte4 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t byte5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t byte6 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t byte7 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t byte8 = (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t); + int16_t byte9 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t); + int16_t byte10 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t); + int16_t byte11 = (int16_t)Eurydice_slice_index(bytes, (size_t)11U, uint8_t, + uint8_t *, uint8_t); re.elements[0U] = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); re.elements[1U] = byte2 << 4U | (byte1 >> 4U & (int16_t)15); re.elements[2U] = (byte4 & (int16_t)15) << 8U | (byte3 & (int16_t)255); @@ -1633,30 +2058,30 @@ libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) re.elements[5U] = byte8 << 4U | (byte7 >> 4U & (int16_t)15); re.elements[6U] = (byte10 & (int16_t)15) << 8U | (byte9 & (int16_t)255); re.elements[7U] = byte11 << 4U | (byte10 >> 4U & (int16_t)15); - int16_t - byte12 = (int16_t)Eurydice_slice_index(bytes, (size_t)12U, uint8_t, uint8_t *, uint8_t); - int16_t - byte13 = (int16_t)Eurydice_slice_index(bytes, (size_t)13U, uint8_t, uint8_t *, uint8_t); - int16_t - byte14 = (int16_t)Eurydice_slice_index(bytes, (size_t)14U, uint8_t, uint8_t *, uint8_t); - int16_t - byte15 = (int16_t)Eurydice_slice_index(bytes, (size_t)15U, uint8_t, uint8_t *, uint8_t); - int16_t - byte16 = (int16_t)Eurydice_slice_index(bytes, (size_t)16U, uint8_t, uint8_t *, uint8_t); - int16_t - byte17 = (int16_t)Eurydice_slice_index(bytes, (size_t)17U, uint8_t, uint8_t *, uint8_t); - int16_t - byte18 = (int16_t)Eurydice_slice_index(bytes, (size_t)18U, uint8_t, uint8_t *, uint8_t); - int16_t - byte19 = (int16_t)Eurydice_slice_index(bytes, (size_t)19U, uint8_t, uint8_t *, uint8_t); - int16_t - byte20 = (int16_t)Eurydice_slice_index(bytes, (size_t)20U, uint8_t, uint8_t *, uint8_t); - int16_t - byte21 = (int16_t)Eurydice_slice_index(bytes, (size_t)21U, uint8_t, uint8_t *, uint8_t); - int16_t - byte22 = (int16_t)Eurydice_slice_index(bytes, (size_t)22U, uint8_t, uint8_t *, uint8_t); - int16_t - byte23 = (int16_t)Eurydice_slice_index(bytes, (size_t)23U, uint8_t, uint8_t *, uint8_t); + int16_t byte12 = (int16_t)Eurydice_slice_index(bytes, (size_t)12U, uint8_t, + uint8_t *, uint8_t); + int16_t byte13 = (int16_t)Eurydice_slice_index(bytes, (size_t)13U, uint8_t, + uint8_t *, uint8_t); + int16_t byte14 = (int16_t)Eurydice_slice_index(bytes, (size_t)14U, uint8_t, + uint8_t *, uint8_t); + int16_t byte15 = (int16_t)Eurydice_slice_index(bytes, (size_t)15U, uint8_t, + uint8_t *, uint8_t); + int16_t byte16 = (int16_t)Eurydice_slice_index(bytes, (size_t)16U, uint8_t, + uint8_t *, uint8_t); + int16_t byte17 = (int16_t)Eurydice_slice_index(bytes, (size_t)17U, uint8_t, + uint8_t *, uint8_t); + int16_t byte18 = (int16_t)Eurydice_slice_index(bytes, (size_t)18U, uint8_t, + uint8_t *, uint8_t); + int16_t byte19 = (int16_t)Eurydice_slice_index(bytes, (size_t)19U, uint8_t, + uint8_t *, uint8_t); + int16_t byte20 = (int16_t)Eurydice_slice_index(bytes, (size_t)20U, uint8_t, + uint8_t *, uint8_t); + int16_t byte21 = (int16_t)Eurydice_slice_index(bytes, (size_t)21U, uint8_t, + uint8_t *, uint8_t); + int16_t byte22 = (int16_t)Eurydice_slice_index(bytes, (size_t)22U, uint8_t, + uint8_t *, uint8_t); + int16_t byte23 = (int16_t)Eurydice_slice_index(bytes, (size_t)23U, uint8_t, + uint8_t *, uint8_t); re.elements[8U] = (byte13 & (int16_t)15) << 8U | (byte12 & (int16_t)255); re.elements[9U] = byte14 << 4U | (byte13 >> 4U & (int16_t)15); re.elements[10U] = (byte16 & (int16_t)15) << 8U | (byte15 & (int16_t)255); @@ -1670,71 +2095,79 @@ libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( - Eurydice_slice a -) -{ + Eurydice_slice a) { return libcrux_ml_kem_vector_deserialize_12(a); } -inline size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, Eurydice_slice result) -{ +inline size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, + Eurydice_slice result) { size_t sampled = (size_t)0U; - core_slice_iter_Chunks - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(core_slice___Slice_T___chunks(a, - (size_t)3U, - uint8_t, - core_slice_iter_Chunks), - core_slice_iter_Chunks, - core_slice_iter_Chunks); - while (true) - { - core_option_Option__Eurydice_slice_uint8_t - uu____0 = - core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next(&iter, - uint8_t, - core_option_Option__Eurydice_slice_uint8_t); - if (uu____0.tag == core_option_None) - { + core_slice_iter_Chunks iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + core_slice___Slice_T___chunks(a, (size_t)3U, uint8_t, + core_slice_iter_Chunks), + core_slice_iter_Chunks, core_slice_iter_Chunks); + while (true) { + core_option_Option__Eurydice_slice_uint8_t uu____0 = + core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( + &iter, uint8_t, core_option_Option__Eurydice_slice_uint8_t); + if (uu____0.tag == core_option_None) { break; - } - else - { + } else { Eurydice_slice bytes = uu____0.f0; - int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); int16_t d1 = (b2 & (int16_t)15) << 8U | b1; int16_t d2 = b3 << 4U | b2 >> 4U; bool uu____1; - if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) - { - uu____1 = sampled < (size_t)16U; - } - else - { - uu____1 = false; - } - if (uu____1) - { - int16_t uu____2 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____2; - sampled++; - } + int16_t uu____2; bool uu____3; - if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) - { - uu____3 = sampled < (size_t)16U; - } - else - { - uu____3 = false; + size_t uu____4; + int16_t uu____5; + size_t uu____6; + int16_t uu____7; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + int16_t uu____8 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = + uu____8; + sampled++; + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; + if (uu____1) { + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, + int16_t) = uu____5; + sampled++; + continue; + } + } + continue; + } } - if (uu____3) - { - int16_t uu____4 = d2; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = uu____4; - sampled++; + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; + if (uu____1) { + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = + uu____5; + sampled++; + continue; + } } } } @@ -1743,100 +2176,82 @@ inline size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, Eurydice_slice size_t libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( - Eurydice_slice a, - Eurydice_slice out -) -{ + Eurydice_slice a, Eurydice_slice out) { return libcrux_ml_kem_vector_rej_sample(a, out); } inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_portable___core__clone__Clone_for_libcrux_ml_kem__vector__portable__PortableVector___clone( - libcrux_ml_kem_vector_portable_PortableVector *self -) -{ + libcrux_ml_kem_vector_portable_PortableVector *self) { return self[0U]; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -ZERO__libcrux_ml_kem_vector_portable_PortableVector(void) -{ +ZERO__libcrux_ml_kem_vector_portable_PortableVector(void) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - lit; + lit; lit.coefficients[0U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[1U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[2U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[3U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[4U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[5U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[6U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[7U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[8U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[9U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[10U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[11U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[12U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[13U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[14U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); lit.coefficients[15U] = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12(bytes); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329(coefficient); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( + coefficient); re.coefficients[i0] = uu____0; } return re; @@ -1844,515 +2259,373 @@ deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVect static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_vector_portable_PortableVector -shift_right___15int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +shift_right___15int32_t(libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; } return v; } -static libcrux_ml_kem_vector_portable_PortableVector -shift_right___15int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +static libcrux_ml_kem_vector_portable_PortableVector shift_right___15int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return shift_right___15int32_t(v); } static libcrux_ml_kem_vector_portable_PortableVector to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector a -) -{ + libcrux_ml_kem_vector_portable_PortableVector a) { libcrux_ml_kem_vector_portable_PortableVector t = shift_right___15int32_t0(a); - libcrux_ml_kem_vector_portable_PortableVector - fm = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant(t, - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, - &fm); + libcrux_ml_kem_vector_portable_PortableVector fm = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &fm); } static inline void serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[384U] -) -{ - uint8_t serialized[384U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0]); uint8_t bytes[24U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)384U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, serialized, (size_t)384U * sizeof (uint8_t)); + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); } static inline void serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - key[4U], - uint8_t ret[1536U] -) -{ - uint8_t out[1536U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1536U, - out, - ( - (core_ops_range_Range__size_t){ + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1536U, out, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, out, (size_t)1536U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); } static inline void serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[4U], - Eurydice_slice seed_for_a, - uint8_t ret[1568U] -) -{ - uint8_t public_key_serialized[1568U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1568U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1536U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1[4U]; - memcpy(uu____1, - t_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1568U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[4U]; + memcpy( + uu____1, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1568U, - public_key_serialized, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t(Eurydice_array_to_subslice_to((size_t)1568U, - public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0[4U]; - memcpy(uu____0, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[4U]; + memcpy( + uu____0, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, - public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1568U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static void closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - memcpy(ret, - ret0, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -typedef struct PortableHash____4size_t_s -{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[4U]; } -PortableHash____4size_t; +typedef struct PortableHash____4size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[4U]; +} PortableHash____4size_t; -static inline PortableHash____4size_t shake128_init_absorb___4size_t(uint8_t input[4U][34U]) -{ +static inline PortableHash____4size_t shake128_init_absorb___4size_t( + uint8_t input[4U][34U]) { libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, - Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[4U]; - memcpy(uu____1, - state, - (size_t)4U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + uu____1, state, + (size_t)4U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); PortableHash____4size_t lit; - memcpy(lit.shake128_state, - uu____1, - (size_t)4U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + lit.shake128_state, uu____1, + (size_t)4U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); return lit; } -static inline void -shake128_squeeze_three_blocks___4size_t(PortableHash____4size_t *self, uint8_t ret[4U][504U]) -{ - uint8_t out[4U][504U] = { { 0U } }; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, - Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [504U])); +static inline void shake128_squeeze_three_blocks___4size_t( + PortableHash____4size_t *self, uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_504size_t( - uint8_t randomness[4U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[4U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } -static inline void -shake128_squeeze_block___4size_t(PortableHash____4size_t *self, uint8_t ret[4U][168U]) -{ - uint8_t out[4U][168U] = { { 0U } }; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, - Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [168U])); +static inline void shake128_squeeze_block___4size_t( + PortableHash____4size_t *self, uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_168size_t( - uint8_t randomness[4U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[4U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_slice a) -{ +from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice a) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array(Eurydice_slice_subslice(a, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( + Eurydice_slice_subslice( + a, + ((core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); result.coefficients[i0] = uu____0; } return result; @@ -2360,405 +2633,317 @@ from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_slice a) static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); } static inline void sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - size_t sampled_coefficients[4U] = { 0U }; - int16_t out[4U][272U] = { { 0U } }; + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof (uint8_t [34U])); + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); PortableHash____4size_t xof_state = shake128_init_absorb___4size_t(uu____0); uint8_t randomness0[4U][504U]; shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_4size_t_168size_t(uu____2, - sampled_coefficients, - out); } int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline void sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U][4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0(A_transpose[i]);); - KRML_MAYBE_FOR4(i0, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[4U][34U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { - size_t j = i; + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U][4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U] - )); + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [4U])); } typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t_s -{ + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - fst[4U]; + fst[4U]; uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) -{ - uint8_t out[4U][128U] = { { 0U } }; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256(uu____0, - Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)4U * sizeof (uint8_t [128U])); +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice randomness -) -{ - int16_t sampled_i16s[256U] = { 0U }; - for - (size_t - i0 = (size_t)0U; - i0 - < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) - { + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { size_t chunk_number = i0; - Eurydice_slice - byte_chunk = - Eurydice_slice_subslice(randomness, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint32_t - uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t - uu____1 = - uu____0 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; - uint32_t - uu____2 = - uu____1 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; - uint32_t - random_bits_as_u32 = - uu____2 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, uint8_t *, uint8_t) << 24U; + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; uint32_t even_bits = random_bits_as_u32 & 1431655765U; uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) - { + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { uint32_t outcome_set = i; uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); size_t offset = (size_t)(outcome_set0 >> 2U); sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; } } - return - from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_slice((size_t)256U, - sampled_i16s, - int16_t, - Eurydice_slice)); + return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice randomness -) -{ - int16_t sampled_i16s[256U] = { 0U }; - for - (size_t - i0 = (size_t)0U; - i0 - < core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) - { + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { size_t chunk_number = i0; - Eurydice_slice - byte_chunk = - Eurydice_slice_subslice(randomness, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint32_t - uu____0 = (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t - uu____1 = - uu____0 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, uint8_t *, uint8_t) << 8U; - uint32_t - random_bits_as_u24 = - uu____1 - | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, uint8_t *, uint8_t) << 16U; + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; uint32_t first_bits = random_bits_as_u24 & 2396745U; uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) - { + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { int32_t outcome_set = i; int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t - outcome_2 = (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + (int32_t)3) & 7U); + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); size_t offset = (size_t)(outcome_set0 / (int32_t)6); sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; } } - return - from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_slice((size_t)256U, - sampled_i16s, - int16_t, - Eurydice_slice)); + return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - Eurydice_slice randomness -) -{ + Eurydice_slice randomness) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector(randomness); + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector( + randomness); return uu____0; } static inline void ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) - { + for (size_t i = (size_t)0U; i < step; i++) { size_t j = i; - libcrux_ml_kem_vector_portable_PortableVector - t = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant(re->coefficients[j - + step], - (int16_t)-1600); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(re->coefficients[j], - &t); + libcrux_ml_kem_vector_portable_PortableVector t = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + re->coefficients[j], &t); re->coefficients[j + step] = uu____0; - libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(re->coefficients[j], - &t); + libcrux_ml_kem_vector_portable_PortableVector uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + re->coefficients[j], &t); re->coefficients[j] = uu____1; } } typedef struct -__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector_s -{ + __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector_s { libcrux_ml_kem_vector_portable_PortableVector fst; libcrux_ml_kem_vector_portable_PortableVector snd; -} -__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector; +} __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector; static libcrux_ml_kem_vector_portable_PortableVector montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t fer -) -{ - return - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(v, - fer); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t fer) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + v, fer); } static inline __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector a, - libcrux_ml_kem_vector_portable_PortableVector b, - int16_t zeta_r -) -{ - libcrux_ml_kem_vector_portable_PortableVector - t = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector(b, zeta_r); - b = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(a, - &t); - a = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, - &t); - return - ( - (__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ - .fst = a, - .snd = b - } - ); + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_portable_PortableVector t = + montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + b, zeta_r); + b = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + a, &t); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &t); + return (( + __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, .snd = b}); } static inline void ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - size_t layer -) -{ + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer) { size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) - { + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { size_t round = i0; zeta_i[0U] = zeta_i[0U] + (size_t)1U; size_t offset = round * step * (size_t)2U; size_t offset_vec = offset / (size_t)16U; size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) - { + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { size_t j = i; __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[j], - re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; re->coefficients[j] = x; @@ -2769,97 +2954,83 @@ ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( static inline void ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); } static inline void ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); } static inline void ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + (size_t)3U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] + (size_t)3U;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); } static inline void poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(self->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + self->coefficients[i0]); self->coefficients[i0] = uu____0; } } static inline void ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector(re); size_t zeta_i = (size_t)1U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); @@ -2868,102 +3039,81 @@ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVect static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[4U][128U]; PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[4U]; - memcpy(uu____2, - re_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[4U]; + memcpy( + uu____2, re_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *rhs -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - out = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + out = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply(&self->coefficients[i0], - &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U - + (size_t)4U * i0 - + (size_t)3U]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); out.coefficients[i0] = uu____0; } return out; @@ -2971,645 +3121,504 @@ ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( static inline void add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, size_t); + i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], - &rhs->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &rhs->coefficients[i0]); self->coefficients[i0] = uu____0; } } static libcrux_ml_kem_vector_portable_PortableVector to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector v -) -{ - return - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(v, - LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); } static inline void add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t j = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector(self->coefficients[j]); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, - &error->coefficients[j])); + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector( + self->coefficients[j]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &error->coefficients[j])); self->coefficients[j] = uu____0; } } static inline void compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [4U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - row, + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *matrix_element = &row[j]; + *matrix_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result[i1], &product); } - add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], - &error_as_ntt[i1]); + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_as_ntt[i1]); } - memcpy(ret, - result, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static K___uint8_t_1536size_t__uint8_t_1568size_t_ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed -) -{ + Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[4U][4U]; + A_transpose[4U][4U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(ret, - true, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[4U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_as_ntt[4U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____3, - domain_separator).fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____4[4U]; - memcpy(uu____4, - t_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[4U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[4U]; + memcpy( + uu____4, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[4U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[4U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t(uu____5, - secret_key_serialized); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t( + uu____5, secret_key_serialized); uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof (uint8_t)); + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof (uint8_t)); + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof (uint8_t)); + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; } -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } static inline void serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[3168U] -) -{ - uint8_t out[3168U] = { 0U }; + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); uint8_t *uu____3 = out; size_t uu____4 = pointer; size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)3168U, - out, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)3168U, out, + ((core_ops_range_Range__size_t){ .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; uint8_t *uu____7 = out; size_t uu____8 = pointer; size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)3168U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)3168U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof (uint8_t)); + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t(uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t( + uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t(uu____2); + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uu____2); libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t(uu____4)); + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[4U][128U]; PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[4U]; - memcpy(uu____2, - error_1, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[4U]; + memcpy( + uu____2, error_1, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } -static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +static inline void PRF___4size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t0(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t0(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)3U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] - (size_t)3U;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); } static inline void invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - (size_t)1U]); - re->coefficients[round] = uu____0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); } static inline void invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step(re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); } static inline __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector a, - libcrux_ml_kem_vector_portable_PortableVector b, - int16_t zeta_r -) -{ - libcrux_ml_kem_vector_portable_PortableVector - a_minus_b = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(b, - &a); - a = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(a, - &b)); - b = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector(a_minus_b, zeta_r); - return - ( - (__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ - .fst = a, - .snd = b - } - ); + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_portable_PortableVector a_minus_b = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + b, &a); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &b)); + b = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + a_minus_b, zeta_r); + return (( + __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, .snd = b}); } static inline void invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - size_t layer -) -{ + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer) { size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) - { + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { size_t round = i0; zeta_i[0U] = zeta_i[0U] - (size_t)1U; size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) - { + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { size_t j = i; __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[j], - re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; re->coefficients[j] = x; @@ -3620,190 +3629,165 @@ invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)7U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); } static inline void add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t j = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient_normal_form = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(self->coefficients[j], - (int16_t)1441); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, - &error->coefficients[j])); + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &error->coefficients[j])); self->coefficients[j] = uu____0; } } static inline void compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [4U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [4U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - row, + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *a_element = &row[j]; + *a_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_1[i1]); } - memcpy(ret, - result, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static libcrux_ml_kem_vector_portable_PortableVector decompress_1__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_vector_portable_PortableVector v -) -{ - return - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(), - &v), + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(), + &v), (int16_t)1665); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( - uint8_t serialized[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1(Eurydice_array_to_subslice((size_t)32U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = decompress_1__libcrux_ml_kem_vector_portable_PortableVector(coefficient_compressed); - re.coefficients[i0] = uu____0;); + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + decompress_1__libcrux_ml_kem_vector_portable_PortableVector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); return re; } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient_normal_form = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(result.coefficients[i0], - (int16_t)1441); - libcrux_ml_kem_vector_portable_PortableVector - tmp = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], - &message->coefficients[i0]); - libcrux_ml_kem_vector_portable_PortableVector - tmp0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(coefficient_normal_form, - &tmp); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(tmp0); + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector tmp = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &message->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector tmp0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &tmp); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + tmp0); result.coefficients[i0] = uu____0; } return result; @@ -3811,543 +3795,436 @@ add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result); + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result); result = - add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, - message, - result); + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + error_2, message, result); return result; } static inline libcrux_ml_kem_vector_portable_PortableVector -compress___10int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +compress___10int32_t(libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t - uu____0 = - libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)10, - (uint16_t)v.elements[i0]); + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)10, (uint16_t)v.elements[i0]); v.elements[i0] = uu____0; } return v; } -static libcrux_ml_kem_vector_portable_PortableVector -compress___10int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +static libcrux_ml_kem_vector_portable_PortableVector compress___10int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return compress___10int32_t(v); } static inline void compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[352U] -) -{ - uint8_t serialized[352U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + compress___10int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)352U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline libcrux_ml_kem_vector_portable_PortableVector -compress___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +compress___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t - uu____0 = - libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)11, - (uint16_t)v.elements[i0]); + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)11, (uint16_t)v.elements[i0]); v.elements[i0] = uu____0; } return v; } -static libcrux_ml_kem_vector_portable_PortableVector -compress___11int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +static libcrux_ml_kem_vector_portable_PortableVector compress___11int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return compress___11int32_t(v); } static inline void compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[352U] -) -{ - uint8_t serialized[352U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + compress___11int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)352U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof (uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline void compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[352U] -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[352U]) { uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352size_t(re, - uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof (uint8_t)); + compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); } static void compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - input[4U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)4U, - input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[4U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t_352size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t_352size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline libcrux_ml_kem_vector_portable_PortableVector -compress___4int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +static inline libcrux_ml_kem_vector_portable_PortableVector compress___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t - uu____0 = - libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)4, - (uint16_t)v.elements[i0]); + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)4, (uint16_t)v.elements[i0]); v.elements[i0] = uu____0; } return v; } -static libcrux_ml_kem_vector_portable_PortableVector -compress___4int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +static libcrux_ml_kem_vector_portable_PortableVector compress___4int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return compress___4int32_t(v); } static inline void compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re, - Eurydice_slice serialized -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - compress___4int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + compress___4int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0])); uint8_t bytes[8U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline libcrux_ml_kem_vector_portable_PortableVector -compress___5int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +static inline libcrux_ml_kem_vector_portable_PortableVector compress___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t - uu____0 = - libcrux_ml_kem_vector_compress_ciphertext_coefficient((uint8_t)(int32_t)5, - (uint16_t)v.elements[i0]); + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)5, (uint16_t)v.elements[i0]); v.elements[i0] = uu____0; } return v; } -static libcrux_ml_kem_vector_portable_PortableVector -compress___5int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +static libcrux_ml_kem_vector_portable_PortableVector compress___5int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return compress___5int32_t(v); } static inline void compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re, - Eurydice_slice serialized -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficients = - compress___5int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficients = + compress___5int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0])); uint8_t bytes[10U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5(coefficients, - bytes); - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } } static inline void compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re, - Eurydice_slice out -) -{ - compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector(re, out); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice out) { + compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector(re, + out); } static void encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[1568U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t(Eurydice_slice_subslice_to(public_key, - (size_t)1536U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[4U][4U]; + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1568U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[4U][4U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t(ret0, - false, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( + ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - r_as_ntt[4U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[4U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[4U]; - memcpy(error_1, - uu____3.fst, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[4U]; + memcpy( + error_1, uu____3.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___4size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t(A_transpose, - r_as_ntt, - error_1, - u); + PRF___4size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[1568U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[4U]; - memcpy(uu____5, - u, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t(uu____5, - Eurydice_array_to_subslice((size_t)1568U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1408U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t_160size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, - ciphertext, - (size_t)1408U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof (uint8_t)); + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1568U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[4U]; + memcpy( + uu____5, u, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1408U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t_160size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); uint8_t ret[32U]; - H___4size_t(Eurydice_array_to_slice((size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + H___4size_t( + Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); uint8_t hashed[64U]; - G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t(public_key), - uint8_t, - Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice); uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t(uu____4); + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uu____4); uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___10int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +decompress_ciphertext_coefficient___10int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t - decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); v.elements[i0] = (int16_t)decompressed; @@ -4356,56 +4233,44 @@ decompress_ciphertext_coefficient___10int32_t(libcrux_ml_kem_vector_portable_Por } static libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___10int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +decompress_ciphertext_coefficient___10int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return decompress_ciphertext_coefficient___10int32_t(v); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10(bytes); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = decompress_ciphertext_coefficient___10int32_t0(coefficient); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + decompress_ciphertext_coefficient___10int32_t0(coefficient); re.coefficients[i0] = uu____0; } return re; } static inline libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +decompress_ciphertext_coefficient___11int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t - decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); v.elements[i0] = (int16_t)decompressed; @@ -4414,43 +4279,31 @@ decompress_ciphertext_coefficient___11int32_t(libcrux_ml_kem_vector_portable_Por } static libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___11int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +decompress_ciphertext_coefficient___11int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return decompress_ciphertext_coefficient___11int32_t(v); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11(bytes); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = decompress_ciphertext_coefficient___11int32_t0(coefficient); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + decompress_ciphertext_coefficient___11int32_t0(coefficient); re.coefficients[i0] = uu____0; } return re; @@ -4458,27 +4311,28 @@ deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( - Eurydice_slice serialized -) -{ + Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector(serialized); + deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( + serialized); return uu____0; } static inline void ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); @@ -4487,72 +4341,57 @@ ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( static inline void deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1568U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U); - i++) - { + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U); + i++) { size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)1568U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t(u_bytes); + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( + u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t(&u_as_ntt[i0]); + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_11size_t( + &u_as_ntt[i0]); } - memcpy(ret, - u_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, u_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___4int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +decompress_ciphertext_coefficient___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t - decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); v.elements[i0] = (int16_t)decompressed; @@ -4561,56 +4400,43 @@ decompress_ciphertext_coefficient___4int32_t(libcrux_ml_kem_vector_portable_Port } static libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___4int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +decompress_ciphertext_coefficient___4int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return decompress_ciphertext_coefficient___4int32_t(v); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4(bytes); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = decompress_ciphertext_coefficient___4int32_t0(coefficient); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + decompress_ciphertext_coefficient___4int32_t0(coefficient); re.coefficients[i0] = uu____0; } return re; } static inline libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___5int32_t(libcrux_ml_kem_vector_portable_PortableVector v) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) - { +decompress_ciphertext_coefficient___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t - decompressed = (int32_t)v.elements[i0] * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); v.elements[i0] = (int16_t)decompressed; @@ -4619,44 +4445,32 @@ decompress_ciphertext_coefficient___5int32_t(libcrux_ml_kem_vector_portable_Port } static libcrux_ml_kem_vector_portable_PortableVector -decompress_ciphertext_coefficient___5int32_t0(libcrux_ml_kem_vector_portable_PortableVector v) -{ +decompress_ciphertext_coefficient___5int32_t0( + libcrux_ml_kem_vector_portable_PortableVector v) { return decompress_ciphertext_coefficient___5int32_t(v); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5(bytes); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( + bytes); re.coefficients[i0] = uu____0; - libcrux_ml_kem_vector_portable_PortableVector - uu____1 = decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector uu____1 = + decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); re.coefficients[i0] = uu____1; } return re; @@ -4664,52 +4478,38 @@ deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t( - Eurydice_slice serialized -) -{ + Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector(serialized); + deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( + serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t1(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t1(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( - Eurydice_slice serialized -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) - { + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { size_t i0 = i; - Eurydice_slice - bytes = - Eurydice_slice_subslice(serialized, - ( - (core_ops_range_Range__size_t){ - .start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12(bytes); + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + bytes); re.coefficients[i0] = uu____0; } return re; @@ -4717,77 +4517,55 @@ deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_Portabl static inline void deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[4U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + secret_bytes); secret_as_ntt[i0] = uu____0; } - memcpy(ret, - secret_as_ntt, - (size_t)4U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - b -) -{ - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient_normal_form = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant(b.coefficients[i0], - (int16_t)1441); - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce(libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub(self->coefficients[i0], - &coefficient_normal_form)); + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + self->coefficients[i0], &coefficient_normal_form)); b.coefficients[i0] = uu____0; } return b; @@ -4795,1886 +4573,1463 @@ subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector( static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_message__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR4(i, - (size_t)0U, - (size_t)4U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &result); + result = + subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); return result; } static inline void compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re, - uint8_t ret[32U] -) -{ - uint8_t serialized[32U] = { 0U }; - KRML_MAYBE_FOR16(i, - (size_t)0U, - (size_t)16U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re.coefficients[i0]); - libcrux_ml_kem_vector_portable_PortableVector - coefficient_compressed = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1(coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1(coefficient_compressed, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)32U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *);); - memcpy(ret, serialized, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); } static void decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t(Eurydice_array_to_subslice_from((size_t)1568U, - ciphertext, - (size_t)1408U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message = - compute_message__libcrux_ml_kem_vector_portable_PortableVector_4size_t(&v, - secret_as_ntt, - u_as_ntt); + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)3168U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)1536U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1536U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)1568U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1568U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); + decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___4size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)1600U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext), - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext), + uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t(uu____7, - Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline void serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - key[3U], - uint8_t ret[1152U] -) -{ - uint8_t out[1152U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1152U, - out, - ( - (core_ops_range_Range__size_t){ + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, out, (size_t)1152U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); } static inline void serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[3U], - Eurydice_slice seed_for_a, - uint8_t ret[1184U] -) -{ - uint8_t public_key_serialized[1184U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)1184U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)1152U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1[3U]; - memcpy(uu____1, - t_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)1184U, - public_key_serialized, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t(Eurydice_array_to_subslice_to((size_t)1184U, - public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0[3U]; - memcpy(uu____0, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, - public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)1184U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static void closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - memcpy(ret, - ret0, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -typedef struct PortableHash____3size_t_s -{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; } -PortableHash____3size_t; +typedef struct PortableHash____3size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; +} PortableHash____3size_t; -static inline PortableHash____3size_t shake128_init_absorb___3size_t(uint8_t input[3U][34U]) -{ +static inline PortableHash____3size_t shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, - Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; - memcpy(uu____1, - state, - (size_t)3U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + uu____1, state, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); PortableHash____3size_t lit; - memcpy(lit.shake128_state, - uu____1, - (size_t)3U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + lit.shake128_state, uu____1, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); return lit; } -static inline void -shake128_squeeze_three_blocks___3size_t(PortableHash____3size_t *self, uint8_t ret[3U][504U]) -{ - uint8_t out[3U][504U] = { { 0U } }; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, - Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [504U])); +static inline void shake128_squeeze_three_blocks___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t( - uint8_t randomness[3U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } -static inline void -shake128_squeeze_block___3size_t(PortableHash____3size_t *self, uint8_t ret[3U][168U]) -{ - uint8_t out[3U][168U] = { { 0U } }; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, - Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [168U])); +static inline void shake128_squeeze_block___3size_t( + PortableHash____3size_t *self, uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t( - uint8_t randomness[3U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); } static inline void sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - size_t sampled_coefficients[3U] = { 0U }; - int16_t out[3U][272U] = { { 0U } }; + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof (uint8_t [34U])); + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); PortableHash____3size_t xof_state = shake128_init_absorb___3size_t(uu____0); uint8_t randomness0[3U][504U]; shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t(uu____2, - sampled_coefficients, - out); } int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline void sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U][3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0(A_transpose[i]);); - KRML_MAYBE_FOR3(i0, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[3U][34U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { - size_t j = i; + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U] - )); + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U])); } typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t_s -{ + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - fst[3U]; + fst[3U]; uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) -{ - uint8_t out[3U][128U] = { { 0U } }; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256(uu____0, - Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)3U * sizeof (uint8_t [128U])); +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); } static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[3U][128U]; PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[3U]; - memcpy(uu____2, - re_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, size_t); + i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], - &rhs->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &rhs->coefficients[i0]); self->coefficients[i0] = uu____0; } } static inline void compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - row, + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *matrix_element = &row[j]; + *matrix_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1], &product); } - add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], - &error_as_ntt[i1]); + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_as_ntt[i1]); } - memcpy(ret, - result, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static K___uint8_t_1152size_t__uint8_t_1184size_t_ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed -) -{ + Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[3U][3U]; + A_transpose[3U][3U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(ret, - true, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[3U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_as_ntt[3U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____3, - domain_separator).fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____4[3U]; - memcpy(uu____4, - t_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[3U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t(uu____5, - secret_key_serialized); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + uu____5, secret_key_serialized); uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof (uint8_t)); + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof (uint8_t)); + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof (uint8_t)); + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; } -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } static inline void serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[2400U] -) -{ - uint8_t out[2400U] = { 0U }; + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); uint8_t *uu____3 = out; size_t uu____4 = pointer; size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)2400U, - out, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; uint8_t *uu____7 = out; size_t uu____8 = pointer; size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)2400U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)2400U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t(ind_cpa_keypair_randomness); + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof (uint8_t)); + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t(uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t(uu____2); + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t(uu____4)); + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[3U][128U]; PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[3U]; - memcpy(uu____2, - error_1, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } -static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t0(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t0(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)7U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); } static inline void compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [3U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - row, + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *a_element = &row[j]; + *a_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_1[i1]); } - memcpy(ret, - result, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result); + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result); result = - add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, - message, - result); + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + error_2, message, result); return result; } static inline void compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[320U] -) -{ - uint8_t serialized[320U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - compress___10int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + compress___10int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)320U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline void compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[320U] -) -{ - uint8_t serialized[320U] = { 0U }; - for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - coefficient = - compress___11int32_t0(to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector(re->coefficients[i0])); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + compress___11int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11(coefficient, - bytes); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)320U, - serialized, - ( - (core_ops_range_Range__size_t){ - .start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, - void *); + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof (uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline void compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[320U] -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t(re, - uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof (uint8_t)); + compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); } static void compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - input[3U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)3U, - input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } static inline void compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re, - Eurydice_slice out -) -{ - compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector(re, out); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice out) { + compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector(re, + out); } static void encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[1088U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t(Eurydice_slice_subslice_to(public_key, - (size_t)1152U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[3U][3U]; + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t(ret0, - false, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - r_as_ntt[3U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[3U]; - memcpy(error_1, - uu____3.fst, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___3size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t(A_transpose, - r_as_ntt, - error_1, - u); + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[1088U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[3U]; - memcpy(uu____5, - u, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t(uu____5, - Eurydice_array_to_subslice((size_t)1088U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)960U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, - ciphertext, - (size_t)960U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof (uint8_t)); + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); uint8_t ret[32U]; - H___3size_t(Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); uint8_t hashed[64U]; - G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t(public_key), - uint8_t, - Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t(uu____4); + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( - Eurydice_slice serialized -) -{ + Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector(serialized); + deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( + serialized); return uu____0; } static inline void ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re, (size_t)4U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); @@ -6683,2176 +6038,1675 @@ ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( static inline void deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)1088U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); - i++) - { + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)1088U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(u_bytes); + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(&u_as_ntt[i0]); + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + &u_as_ntt[i0]); } - memcpy(ret, - u_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( - Eurydice_slice serialized -) -{ + Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector(serialized); + deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( + serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t1(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t1(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[3U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + secret_bytes); secret_as_ntt[i0] = uu____0; } - memcpy(ret, - secret_as_ntt, - (size_t)3U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR3(i, - (size_t)0U, - (size_t)3U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result); + result = + subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); return result; } static void decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(Eurydice_array_to_subslice_from((size_t)1088U, - ciphertext, - (size_t)960U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message = - compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t(&v, - secret_as_ntt, - u_as_ntt); + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)2400U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)1152U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)1184U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); + decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___3size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)1120U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext), - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t(uu____7, - Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline void serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - key[2U], - uint8_t ret[768U] -) -{ - uint8_t out[768U] = { 0U }; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[2U], + uint8_t ret[768U]) { + uint8_t out[768U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = key[i0]; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)768U, - out, - ( - (core_ops_range_Range__size_t){ + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)768U, out, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re, ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); } - memcpy(ret, out, (size_t)768U * sizeof (uint8_t)); + memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); } static inline void serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[2U], - Eurydice_slice seed_for_a, - uint8_t ret[800U] -) -{ - uint8_t public_key_serialized[800U] = { 0U }; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)800U, - public_key_serialized, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)768U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1[2U]; - memcpy(uu____1, - t_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U], + Eurydice_slice seed_for_a, uint8_t ret[800U]) { + uint8_t public_key_serialized[800U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)800U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[2U]; + memcpy( + uu____1, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t(uu____1, - ret0); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)800U, - public_key_serialized, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - seed_for_a, - uint8_t, - void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof (uint8_t)); -} - -bool -libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( - uint8_t *public_key -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(Eurydice_array_to_subslice_to((size_t)800U, - public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0[2U]; - memcpy(uu____0, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, + (size_t)768U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t( + Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[2U]; + memcpy( + uu____0, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(uu____0, - Eurydice_array_to_subslice_from((size_t)800U, - public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - public_key_serialized); - return - core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq((size_t)800U, - public_key, - public_key_serialized, - uint8_t, - uint8_t, - bool); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) -{ - uint8_t digest[64U] = { 0U }; - libcrux_sha3_portable_sha512(Eurydice_array_to_slice((size_t)64U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof (uint8_t)); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static void closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - memcpy(ret, - ret0, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -typedef struct PortableHash____2size_t_s -{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[2U]; } -PortableHash____2size_t; +typedef struct PortableHash____2size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[2U]; +} PortableHash____2size_t; -static inline PortableHash____2size_t shake128_init_absorb___2size_t(uint8_t input[2U][34U]) -{ +static inline PortableHash____2size_t shake128_init_absorb___2size_t( + uint8_t input[2U][34U]) { libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - state[i] = libcrux_sha3_portable_incremental_shake128_init();); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &state[i0]; - libcrux_sha3_portable_incremental_shake128_absorb_final(uu____0, - Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, Eurydice_slice));); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[2U]; - memcpy(uu____1, - state, - (size_t)2U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + uu____1, state, + (size_t)2U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); PortableHash____2size_t lit; - memcpy(lit.shake128_state, - uu____1, - (size_t)2U * sizeof (libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + memcpy( + lit.shake128_state, uu____1, + (size_t)2U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); return lit; } -static inline void -shake128_squeeze_three_blocks___2size_t(PortableHash____2size_t *self, uint8_t ret[2U][504U]) -{ - uint8_t out[2U][504U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(uu____0, - Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [504U])); +static inline void shake128_squeeze_three_blocks___2size_t( + PortableHash____2size_t *self, uint8_t ret[2U][504U]) { + uint8_t out[2U][504U] = {{0U}}; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_504size_t( - uint8_t randomness[2U][504U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)504U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[2U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } -static inline void -shake128_squeeze_block___2size_t(PortableHash____2size_t *self, uint8_t ret[2U][168U]) -{ - uint8_t out[2U][168U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - *uu____0 = &self->shake128_state[i0]; - libcrux_sha3_portable_incremental_shake128_squeeze_next_block(uu____0, - Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [168U])); +static inline void shake128_squeeze_block___2size_t( + PortableHash____2size_t *self, uint8_t ret[2U][168U]) { + uint8_t out[2U][168U] = {{0U}}; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); } static inline bool sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_168size_t( - uint8_t randomness[2U][168U], - size_t *sampled_coefficients, - int16_t (*out)[272U] -) -{ - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) - { - size_t r = i; - if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)168U, - randomness[i1], - ( - (core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - size_t - sampled = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample(uu____0, - Eurydice_array_to_subslice((size_t)272U, - out[i1], - ( - (core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U - } - ), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; - } - }); + uint8_t randomness[2U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); bool done = true; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) - { - sampled_coefficients[i0] = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } - else - { - done = false; - }); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); return done; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( - int16_t s[272U] -) -{ - return - from_i16_array__libcrux_ml_kem_vector_portable_PortableVector(Eurydice_array_to_subslice((size_t)272U, - s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U }), - int16_t, - core_ops_range_Range__size_t, - Eurydice_slice)); + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); } static inline void sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - size_t sampled_coefficients[2U] = { 0U }; - int16_t out[2U][272U] = { { 0U } }; + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + size_t sampled_coefficients[2U] = {0U}; + int16_t out[2U][272U] = {{0U}}; uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof (uint8_t [34U])); + memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); PortableHash____2size_t xof_state = shake128_init_absorb___2size_t(uu____0); uint8_t randomness0[2U][504U]; shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof (uint8_t [504U])); - bool - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_504size_t(uu____1, - sampled_coefficients, - out); - while (true) - { - if (!!done) - { + memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_168size_t( + uu____2, sampled_coefficients, out); } - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof (uint8_t [168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_2size_t_168size_t(uu____2, - sampled_coefficients, - out); } int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof (int16_t [272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret0[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1(uu____3[i]);); - memcpy(ret, - ret0, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline void sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - uint8_t seed[34U], - bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U][2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0(A_transpose[i]);); - KRML_MAYBE_FOR2(i0, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof (uint8_t)); - uint8_t seeds[2U][34U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t j = i; - seeds[j][32U] = (uint8_t)i1; - seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof (uint8_t [34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(uu____1, - sampled); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { - size_t j = i; + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U][2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - sample = sampled[j]; - if (transpose) - { - A_transpose[j][i1] = sample; - } - else - { - A_transpose[i1][j] = sample; - } - }); - memcpy(ret, - A_transpose, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U] - )); + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [2U])); } typedef struct -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t_s -{ + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - fst[2U]; + fst[2U]; uint8_t snd; -} -__libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) -{ - uint8_t out[2U][192U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)192U, out[i0], uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256(uu____0, - Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [192U])); +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], + uint8_t ret[2U][192U]) { + uint8_t out[2U][192U] = {{0U}}; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)192U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_3size_t( - Eurydice_slice randomness -) -{ + Eurydice_slice randomness) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0; + uu____0; uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector(randomness); + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector( + randomness); return uu____0; } static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[2U][192U]; PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_3size_t(Eurydice_array_to_slice((size_t)192U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector(&re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[2U]; - memcpy(uu____2, - re_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[2U]; + memcpy( + uu____2, re_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *rhs -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)16U, - self->coefficients, - libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, size_t); + i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add(self->coefficients[i0], - &rhs->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &rhs->coefficients[i0]); self->coefficients[i0] = uu____0; } } static inline void compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [2U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = matrix_A[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - row, + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *matrix_element = &row[j]; + *matrix_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(matrix_element, - &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result[i1], &product); } - add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], - &error_as_ntt[i1]); + add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_as_ntt[i1]); } - memcpy(ret, - result, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static K___uint8_t_768size_t__uint8_t_800size_t_ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed -) -{ + Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - (size_t)32U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[2U][2U]; + A_transpose[2U][2U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(ret, - true, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____1, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[2U]; - memcpy(secret_as_ntt, - uu____2.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_as_ntt[2U]; - memcpy(error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____3, - domain_separator).fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t(A_transpose, - secret_as_ntt, - error_as_ntt, - t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____4[2U]; - memcpy(uu____4, - t_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[2U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( + uu____3, domain_separator) + .fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[2U]; + memcpy( + uu____4, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t(uu____4, - seed_for_A, - public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[2U]; - memcpy(uu____5, - secret_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[2U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t(uu____5, - secret_key_serialized); + serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t( + uu____5, secret_key_serialized); uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof (uint8_t)); + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof (uint8_t)); + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof (uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof (uint8_t)); + memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; } -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_sha256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } static inline void serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t( - Eurydice_slice private_key, - Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, - uint8_t ret[1632U] -) -{ - uint8_t out[1632U] = { 0U }; + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____0, - ( - (core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - private_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); uint8_t *uu____3 = out; size_t uu____4 = pointer; size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____3, - ( - (core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - public_key, - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)1632U, - out, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)1632U, out, + ((core_ops_range_Range__size_t){ .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; uint8_t *uu____7 = out; size_t uu____8 = pointer; size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice((size_t)1632U, - uu____7, - ( - (core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len(implicit_rejection_value, uint8_t, size_t) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - implicit_rejection_value, - uint8_t, - void *); - memcpy(ret, out, (size_t)1632U * sizeof (uint8_t)); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); } libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U] -) -{ - Eurydice_slice - ind_cpa_keypair_randomness = - Eurydice_array_to_subslice((size_t)64U, - randomness, - ( - (core_ops_range_Range__size_t){ + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - implicit_rejection_value = - Eurydice_array_to_subslice_from((size_t)64U, - randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, - uint8_t, - size_t, - Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ - uu____0 = - generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t(ind_cpa_keypair_randomness); + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof (uint8_t)); + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof (uint8_t)); - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t(uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, Eurydice_slice), - implicit_rejection_value, - secret_key_serialized); + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t( + uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t - private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t(uu____2); + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uu____2); libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof (uint8_t)); - return - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t(uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t(uu____4)); + memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - deserialized_pk[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(public_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - ring_element = - Eurydice_slice_subslice(public_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector(ring_element); + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); deserialized_pk[i0] = uu____0; } - memcpy(ret, - deserialized_pk, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - void -) -{ + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) -{ - uint8_t out[2U][128U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t, Eurydice_slice); - libcrux_sha3_portable_shake256(uu____0, - Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, Eurydice_slice));); - memcpy(ret, out, (size_t)2U * sizeof (uint8_t [128U])); +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[2U][128U]) { + uint8_t out[2U][128U] = {{0U}}; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); } static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - uint8_t prf_input[33U], - uint8_t domain_separator -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof (uint8_t));); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); uint8_t prf_outputs[2U][128U]; PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_outputs[i0], - uint8_t, - Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____2[2U]; - memcpy(uu____2, - error_1, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[2U]; + memcpy( + uu____2, error_1, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t - lit; - memcpy(lit.fst, - uu____2, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); lit.snd = domain_separator; return lit; } -static inline void PRF___2size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) -{ - uint8_t digest[128U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)128U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof (uint8_t)); +static inline void PRF___2size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t0(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t0(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re -) -{ - size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, - re, - (size_t)7U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector(&zeta_i, + re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector(re); } static inline void compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - (*a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i0 = (size_t)0U; - i0 - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector [2U], - size_t); - i0++) - { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [2U], + size_t); + i0++) { size_t i1 = i0; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *row = a_as_ntt[i1]; - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - row, + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t j = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *a_element = &row[j]; + *a_element = &row[j]; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1], - &product); + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result[i1]); - add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(&result[i1], &error_1[i1]); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_1[i1]); } - memcpy(ret, - result, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *message -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&t_as_ntt[i0], - &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result); + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result); result = - add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector(error_2, - message, - result); + add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + error_2, message, result); return result; } static void compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - input[2U], - Eurydice_slice out -) -{ - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)2U, - input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[2U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, - size_t); - i++) - { + size_t); + i++) { size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - re = input[i0]; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out, - ( - (core_ops_range_Range__size_t){ + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t(&re, - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } static void encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[768U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(Eurydice_slice_subslice_to(public_key, - (size_t)768U, - uint8_t, - size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice - seed = Eurydice_slice_subslice_from(public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - A_transpose[2U][2U]; + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[768U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t( + Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[2U][2U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t(ret0, - false, - A_transpose); + sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( + ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t(uu____0, - 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - r_as_ntt[2U]; - memcpy(r_as_ntt, - uu____1.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[2U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof (uint8_t)); + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t(uu____2, - domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_1[2U]; - memcpy(error_1, - uu____3.fst, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[2U]; + memcpy( + error_1, uu____3.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___2size_t_128size_t(Eurydice_array_to_slice((size_t)33U, - prf_input, - uint8_t, - Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t(Eurydice_array_to_slice((size_t)128U, - prf_output, - uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t(A_transpose, - r_as_ntt, - error_1, - u); + PRF___2size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof (uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector(uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_2size_t(t_as_ntt, - r_as_ntt, - &error_2, - &message_as_ring_element); - uint8_t ciphertext[768U] = { 0U }; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____5[2U]; - memcpy(uu____5, - u, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); - compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t(uu____5, - Eurydice_array_to_subslice((size_t)768U, - ciphertext, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)640U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t(uu____6, - Eurydice_array_to_subslice_from((size_t)768U, - ciphertext, - (size_t)640U, - uint8_t, - size_t, - Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof (uint8_t)); + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[768U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[2U]; + memcpy( + uu____5, u, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)640U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); } K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U] -) -{ + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - randomness, - uint8_t, - Eurydice_slice), - to_hash); - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice_from((size_t)64U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - size_t, - Eurydice_slice); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); uint8_t ret[32U]; - H___2size_t(Eurydice_array_to_slice((size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), - uint8_t, - Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + H___2size_t( + Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); uint8_t hashed[64U]; - G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice - uu____2 = - Eurydice_array_to_slice((size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t(public_key), - uint8_t, - Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice); uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____2, - uu____3, - pseudorandomness, - ciphertext); - uint8_t shared_secret_array[32U] = { 0U }; - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_slice((size_t)32U, - shared_secret_array, - uint8_t, - Eurydice_slice), - shared_secret, - uint8_t, - void *); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof (uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t - uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t(uu____4); + memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uu____4); uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof (uint8_t)); + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( + void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(Eurydice_array_to_slice((size_t)768U, - ciphertext, - uint8_t, - Eurydice_slice), - uint8_t, - size_t) - / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U); - i++) - { + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { size_t i0 = i; - Eurydice_slice - u_bytes = - Eurydice_array_to_subslice((size_t)768U, - ciphertext, - ( - (core_ops_range_Range__size_t){ - .start = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), - .end = i0 - * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U) - + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(u_bytes); + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t(&u_as_ntt[i0]); + ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + &u_as_ntt[i0]); } - memcpy(ret, - u_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, u_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t1(void) -{ +closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t1(void) { return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); } static inline void deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - ret[2U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_portable_PortableVector();); - for - (size_t - i = (size_t)0U; - i - < - core_slice___Slice_T___len(secret_key, - uint8_t, - size_t) - / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) - { + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { size_t i0 = i; - Eurydice_slice - secret_bytes = - Eurydice_slice_subslice(secret_key, - ( - (core_ops_range_Range__size_t){ + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 - * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector(secret_bytes); + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + secret_bytes); secret_as_ntt[i0] = uu____0; } - memcpy(ret, - secret_as_ntt, - (size_t)2U - * - sizeof ( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - )); + memcpy( + ret, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector compute_message__libcrux_ml_kem_vector_portable_PortableVector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *u_as_ntt -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - product = - ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector(&secret_as_ntt[i0], - &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&result); - result = subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &result); + result = + subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector(v, result); return result; } static void decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U] -) -{ - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t(ciphertext, - u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - v = - deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t(Eurydice_array_to_subslice_from((size_t)768U, - ciphertext, - (size_t)640U, - uint8_t, - size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t(secret_key, - secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - message = - compute_message__libcrux_ml_kem_vector_portable_PortableVector_2size_t(&v, - secret_as_ntt, - u_as_ntt); + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, + (size_t)640U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + compute_message__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector(message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) -{ - uint8_t digest[32U] = { 0U }; - libcrux_sha3_portable_shake256(Eurydice_array_to_slice((size_t)32U, - digest, - uint8_t, - Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof (uint8_t)); -} - -void -libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U] -) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)1632U, - private_key->value, - uint8_t, - Eurydice_slice), - (size_t)768U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)768U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at(secret_key0, - (size_t)800U, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)800U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at(secret_key, - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t(ind_cpa_secret_key, - ciphertext->value, - decrypted); + decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_array_to_slice((size_t)32U, - decrypted, - uint8_t, - Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice(Eurydice_array_to_subslice_from((size_t)64U, - to_hash0, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice), - ind_cpa_public_key_hash, - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___2size_t(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at(Eurydice_array_to_slice((size_t)64U, - hashed, - uint8_t, - Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, to_hash); - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice_from((size_t)800U, - to_hash, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, - size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext), - uint8_t, - void *); + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext), + uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); + PRF___2size_t_32size_t( + Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof (uint8_t)); + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t(uu____5, - uu____6, - pseudorandomness, - expected_ciphertext); - Eurydice_slice - uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t(ciphertext); - uint8_t - selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t(uu____7, - Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t, Eurydice_slice)); + encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, + uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, uint8_t, Eurydice_slice), - selector, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof (uint8_t)); + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } - diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index 665a98126..02b989972 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H @@ -12,403 +12,303 @@ extern "C" { #endif -#include "libcrux_sha3_internal.h" -#include "libcrux_sha3.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_sha3.h" +#include "libcrux_sha3_internal.h" #define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) #define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS ((int16_t)1353) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ + ((int16_t)1353) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ + (62209U) -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R (62209U) +extern const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[256U] + [16U]; -typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { int16_t elements[16U]; } -libcrux_ml_kem_vector_portable_PortableVector; +typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_portable_PortableVector; libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero(void); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO( - void -); + void); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( - Eurydice_slice array -); + Eurydice_slice array); -libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_add( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -); +libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -); + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs); -libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_sub( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -); +libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( - libcrux_ml_kem_vector_portable_PortableVector lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs -); + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_bitwise_and_with_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c); libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_cond_subtract_3329(libcrux_ml_kem_vector_portable_PortableVector v); +libcrux_ml_kem_vector_cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( - libcrux_ml_kem_vector_portable_PortableVector v -); + libcrux_ml_kem_vector_portable_PortableVector v); #define LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER ((int32_t)20159) #define LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT ((int32_t)26) -#define LIBCRUX_ML_KEM_VECTOR_BARRETT_R ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT) +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_R \ + ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT) int16_t libcrux_ml_kem_vector_barrett_reduce_element(int16_t value); libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_barrett_reduce(libcrux_ml_kem_vector_portable_PortableVector v); +libcrux_ml_kem_vector_barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( - libcrux_ml_kem_vector_portable_PortableVector v -); + libcrux_ml_kem_vector_portable_PortableVector v); #define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT (16U) -#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_R ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT) +#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_R \ + ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT) int16_t libcrux_ml_kem_vector_montgomery_reduce_element(int32_t value); -int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(int16_t fe, int16_t fer); +int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(int16_t fe, + int16_t fer); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t c -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t r -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t r); uint8_t libcrux_ml_kem_vector_compress_message_coefficient(uint16_t fe); -libcrux_ml_kem_vector_portable_PortableVector -libcrux_ml_kem_vector_compress_1(libcrux_ml_kem_vector_portable_PortableVector v); +libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_compress_1( + libcrux_ml_kem_vector_portable_PortableVector v); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( - libcrux_ml_kem_vector_portable_PortableVector v -); + libcrux_ml_kem_vector_portable_PortableVector v); -uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits(uint8_t n, uint32_t value); +uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits(uint8_t n, + uint32_t value); -int16_t -libcrux_ml_kem_vector_compress_ciphertext_coefficient(uint8_t coefficient_bits, uint16_t fe); +int16_t libcrux_ml_kem_vector_compress_ciphertext_coefficient( + uint8_t coefficient_bits, uint16_t fe); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1 -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1 -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta0, - int16_t zeta1 -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta0, - int16_t zeta1 -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector v, - int16_t zeta -); + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_PortableVector a, - int16_t zeta -); + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta); -typedef struct K___int16_t_int16_t_s -{ +typedef struct K___int16_t_int16_t_s { int16_t fst; int16_t snd; -} -K___int16_t_int16_t; +} K___int16_t_int16_t; -K___int16_t_int16_t -libcrux_ml_kem_vector_ntt_multiply_binomials( - K___int16_t_int16_t _, - K___int16_t_int16_t _0, - int16_t zeta -); +K___int16_t_int16_t libcrux_ml_kem_vector_ntt_multiply_binomials( + K___int16_t_int16_t _, K___int16_t_int16_t _0, int16_t zeta); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_ntt_multiply( - libcrux_ml_kem_vector_portable_PortableVector *lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( - libcrux_ml_kem_vector_portable_PortableVector *lhs, - libcrux_ml_kem_vector_portable_PortableVector *rhs, - int16_t zeta0, - int16_t zeta1, - int16_t zeta2, - int16_t zeta3 -); - -void -libcrux_ml_kem_vector_serialize_1( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[2U] -); - -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[2U] -); + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3); + +void libcrux_ml_kem_vector_serialize_1( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[2U]); + +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[2U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( - Eurydice_slice a -); + Eurydice_slice a); -void -libcrux_ml_kem_vector_serialize_4( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[8U] -); +void libcrux_ml_kem_vector_serialize_4( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[8U]); -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[8U] -); +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[8U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( - Eurydice_slice a -); + Eurydice_slice a); -void -libcrux_ml_kem_vector_serialize_5( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[10U] -); +void libcrux_ml_kem_vector_serialize_5( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[10U]); -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[10U] -); +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[10U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( - Eurydice_slice a -); + Eurydice_slice a); -void -libcrux_ml_kem_vector_serialize_10( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[20U] -); +void libcrux_ml_kem_vector_serialize_10( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[20U]); -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[20U] -); +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[20U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( - Eurydice_slice a -); + Eurydice_slice a); -void -libcrux_ml_kem_vector_serialize_11( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[22U] -); +void libcrux_ml_kem_vector_serialize_11( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[22U]); -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[22U] -); +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[22U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( - Eurydice_slice a -); + Eurydice_slice a); -void -libcrux_ml_kem_vector_serialize_12( - libcrux_ml_kem_vector_portable_PortableVector v, - uint8_t ret[24U] -); +void libcrux_ml_kem_vector_serialize_12( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[24U]); -void -libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( - libcrux_ml_kem_vector_portable_PortableVector a, - uint8_t ret[24U] -); +void libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[24U]); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( - Eurydice_slice a -); + Eurydice_slice a); -size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, Eurydice_slice result); +size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, + Eurydice_slice result); size_t libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( - Eurydice_slice a, - Eurydice_slice out -); + Eurydice_slice a, Eurydice_slice out); libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_portable___core__clone__Clone_for_libcrux_ml_kem__vector__portable__PortableVector___clone( - libcrux_ml_kem_vector_portable_PortableVector *self -); + libcrux_ml_kem_vector_portable_PortableVector *self); typedef struct -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_s -{ libcrux_ml_kem_vector_portable_PortableVector coefficients[16U]; } -libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_s { + libcrux_ml_kem_vector_portable_PortableVector coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector; #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_platform.c b/libcrux-ml-kem/c/libcrux_platform.c index b1f487d73..d3ad8da95 100644 --- a/libcrux-ml-kem/c/libcrux_platform.c +++ b/libcrux-ml-kem/c/libcrux_platform.c @@ -2,6 +2,11 @@ #include +bool libcrux_platform_platform_simd128_support(void) { + // TODO: query cpuid and cache the results!! + return true; +} + bool libcrux_platform_platform_simd256_support(void) { // TODO: query cpuid and cache the results!! return true; diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index 7a55e8bf5..ef41683e2 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index d7cdba78b..36ca19e89 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_H @@ -12,101 +12,97 @@ extern "C" { #endif -#include "libcrux_sha3_internal.h" -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_sha3_internal.h" -static inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___72size_t_6uint8_t(buf0, buf); } -static inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___136size_t_6uint8_t(buf0, buf); } -static inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___136size_t_31uint8_t(buf0, buf); } -static inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___144size_t_6uint8_t(buf0, buf); } -static inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___104size_t_6uint8_t(buf0, buf); } -static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, Eurydice_slice payload) -{ +static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha224(digest, payload); } -static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) -{ - uint8_t out[28U] = { 0U }; - libcrux_sha3_sha224_ema(Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)28U * sizeof (uint8_t)); +static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) { + uint8_t out[28U] = {0U}; + libcrux_sha3_sha224_ema( + Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)28U * sizeof(uint8_t)); } -static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, Eurydice_slice payload) -{ +static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha256(digest, payload); } -static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) -{ - uint8_t out[32U] = { 0U }; - libcrux_sha3_sha256_ema(Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)32U * sizeof (uint8_t)); +static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + libcrux_sha3_sha256_ema( + Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } -static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, Eurydice_slice payload) -{ +static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha384(digest, payload); } -static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) -{ - uint8_t out[48U] = { 0U }; - libcrux_sha3_sha384_ema(Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)48U * sizeof (uint8_t)); +static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) { + uint8_t out[48U] = {0U}; + libcrux_sha3_sha384_ema( + Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)48U * sizeof(uint8_t)); } -static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, Eurydice_slice payload) -{ +static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha512(digest, payload); } -static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) -{ - uint8_t out[64U] = { 0U }; - libcrux_sha3_sha512_ema(Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)64U * sizeof (uint8_t)); +static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; + libcrux_sha3_sha512_ema( + Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); } -static inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; +static inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; libcrux_sha3_portable_keccakx1___168size_t_31uint8_t(buf0, buf); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index d7a2ff7c5..5df798795 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,123 +1,2028 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ -#include "libcrux_sha3_avx2.h" +#include "internal/libcrux_sha3_avx2.h" #include "internal/libcrux_core.h" -inline void -libcrux_sha3_avx2_x4_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice input2, - Eurydice_slice input3, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -libcrux_sha3_avx2_x4_incremental_shake128_init(void) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); +static inline core_core_arch_x86___m256i zero(void) { + return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); } -inline void -libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice data0, - Eurydice_slice data1, - Eurydice_slice data2, - Eurydice_slice data3 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); +static inline core_core_arch_x86___m256i _veor5q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); + core_core_arch_x86___m256i abcd = + libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); + return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); +} + +static inline core_core_arch_x86___m256i xor5(core_core_arch_x86___m256i a, + core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, + core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + return _veor5q_u64(a, b, c, d, e); +} + +static inline core_core_arch_x86___m256i rotate_left___1int32_t_63int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)1, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)63, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vrax1q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, rotate_left___1int32_t_63int32_t(b)); +} + +static inline core_core_arch_x86___m256i rotate_left1_and_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vrax1q_u64(a, b); +} + +static inline core_core_arch_x86___m256i _vbcaxq_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); +} + +static inline core_core_arch_x86___m256i and_not_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + return _vbcaxq_u64(a, b, c); +} + +static inline core_core_arch_x86___m256i _veorq_n_u64( + core_core_arch_x86___m256i a, uint64_t c) { + core_core_arch_x86___m256i c0 = + libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); + return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); +} + +static inline core_core_arch_x86___m256i xor_constant( + core_core_arch_x86___m256i a, uint64_t c) { + return _veorq_n_u64(a, c); +} + +static inline core_core_arch_x86___m256i xor0(core_core_arch_x86___m256i a, + core_core_arch_x86___m256i b) { + return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); +} + +static inline void slice_4(Eurydice_slice a[4U], size_t start, size_t len, + Eurydice_slice ret[4U]) { + Eurydice_slice uu____0 = Eurydice_slice_subslice( + a[0U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + a[1U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + a[2U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[0U] = uu____0; + ret[1U] = uu____1; + ret[2U] = uu____2; + ret[3U] = Eurydice_slice_subslice( + a[3U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); +} + +static inline void slice_n(Eurydice_slice a[4U], size_t start, size_t len, + Eurydice_slice ret[4U]) { + Eurydice_slice uu____0[4U]; + memcpy(uu____0, a, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[4U]; + slice_4(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +split_at_mut_4(Eurydice_slice out[4U], size_t mid) { + Eurydice_slice out0 = out[0U]; + Eurydice_slice out1 = out[1U]; + Eurydice_slice out2 = out[2U]; + Eurydice_slice out3 = out[3U]; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out0, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at_mut( + out1, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out10 = uu____1.fst; + Eurydice_slice out11 = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at_mut( + out2, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out20 = uu____2.fst; + Eurydice_slice out21 = uu____2.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at_mut( + out3, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out30 = uu____3.fst; + Eurydice_slice out31 = uu____3.snd; + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; + lit.fst[0U] = out00; + lit.fst[1U] = out10; + lit.fst[2U] = out20; + lit.fst[3U] = out30; + lit.snd[0U] = out01; + lit.snd[1U] = out11; + lit.snd[2U] = out21; + lit.snd[3U] = out31; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +split_at_mut_n(Eurydice_slice a[4U], size_t mid) { + return split_at_mut_4(a, mid); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +new__core_core_arch_x86___m256i_4size_t(void) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + lit; + lit.st[0U][0U] = zero(); + lit.st[0U][1U] = zero(); + lit.st[0U][2U] = zero(); + lit.st[0U][3U] = zero(); + lit.st[0U][4U] = zero(); + lit.st[1U][0U] = zero(); + lit.st[1U][1U] = zero(); + lit.st[1U][2U] = zero(); + lit.st[1U][3U] = zero(); + lit.st[1U][4U] = zero(); + lit.st[2U][0U] = zero(); + lit.st[2U][1U] = zero(); + lit.st[2U][2U] = zero(); + lit.st[2U][3U] = zero(); + lit.st[2U][4U] = zero(); + lit.st[3U][0U] = zero(); + lit.st[3U][1U] = zero(); + lit.st[3U][2U] = zero(); + lit.st[3U][3U] = zero(); + lit.st[3U][4U] = zero(); + lit.st[4U][0U] = zero(); + lit.st[4U][1U] = zero(); + lit.st[4U][2U] = zero(); + lit.st[4U][3U] = zero(); + lit.st[4U][4U] = zero(); + return lit; +} + +static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +static inline void load_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, b, (size_t)4U * sizeof(Eurydice_slice)); + load_block___136size_t(uu____0, uu____1); +} + +static inline core_core_arch_x86___m256i rotate_left___36int32_t_28int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___36int32_t_28int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___3int32_t_61int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___3int32_t_61int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___41int32_t_23int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)41, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)23, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___41int32_t_23int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___18int32_t_46int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)18, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)46, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___18int32_t_46int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___1int32_t_63int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___44int32_t_20int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___44int32_t_20int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___10int32_t_54int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)10, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)54, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___10int32_t_54int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___45int32_t_19int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)45, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)19, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___45int32_t_19int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___2int32_t_62int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___2int32_t_62int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___62int32_t_2int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___62int32_t_2int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___6int32_t_58int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)6, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)58, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___6int32_t_58int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___43int32_t_21int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___43int32_t_21int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___15int32_t_49int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)15, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)49, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___15int32_t_49int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___61int32_t_3int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___61int32_t_3int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___28int32_t_36int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___28int32_t_36int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___55int32_t_9int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)55, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)9, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___55int32_t_9int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___25int32_t_39int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___25int32_t_39int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___21int32_t_43int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___21int32_t_43int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___56int32_t_8int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___56int32_t_8int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___27int32_t_37int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)27, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)37, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___27int32_t_37int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___20int32_t_44int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___20int32_t_44int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___39int32_t_25int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___39int32_t_25int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___8int32_t_56int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___8int32_t_56int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___14int32_t_50int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)14, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)50, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___14int32_t_50int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void theta_rho__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i uu____0 = + xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + core_core_arch_x86___m256i uu____1 = + xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + core_core_arch_x86___m256i uu____2 = + xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + core_core_arch_x86___m256i uu____3 = + xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + core_core_arch_x86___m256i c[5U] = { + uu____0, uu____1, uu____2, uu____3, + xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + core_core_arch_x86___m256i uu____4 = + rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____5 = + rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____6 = + rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____7 = + rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i t[5U] = { + uu____4, uu____5, uu____6, uu____7, + rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + core_core_arch_x86___m256i uu____8 = xor0(s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + core_core_arch_x86___m256i uu____9 = + xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + core_core_arch_x86___m256i uu____10 = + xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + core_core_arch_x86___m256i uu____11 = + xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + core_core_arch_x86___m256i uu____12 = + xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + core_core_arch_x86___m256i uu____13 = + xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + core_core_arch_x86___m256i uu____14 = + xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + core_core_arch_x86___m256i uu____15 = + xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + core_core_arch_x86___m256i uu____16 = + xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + core_core_arch_x86___m256i uu____17 = + xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + core_core_arch_x86___m256i uu____18 = + xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + core_core_arch_x86___m256i uu____19 = + xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + core_core_arch_x86___m256i uu____20 = + xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + core_core_arch_x86___m256i uu____21 = + xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + core_core_arch_x86___m256i uu____22 = + xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + core_core_arch_x86___m256i uu____23 = + xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + core_core_arch_x86___m256i uu____24 = + xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + core_core_arch_x86___m256i uu____25 = + xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + core_core_arch_x86___m256i uu____26 = + xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + core_core_arch_x86___m256i uu____27 = + xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + core_core_arch_x86___m256i uu____28 = + xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + core_core_arch_x86___m256i uu____29 = + xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + core_core_arch_x86___m256i uu____30 = + xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + core_core_arch_x86___m256i uu____31 = + xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + core_core_arch_x86___m256i uu____32 = + xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void pi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, core_core_arch_x86___m256i[5U], void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void chi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(core_core_arch_x86___m256i[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR5(i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + core_core_arch_x86___m256i uu____0 = and_not_xor( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void iota__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + size_t i) { + core_core_arch_x86___m256i uu____0 = xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void keccakf1600__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + theta_rho__core_core_arch_x86___m256i_4size_t(s); + pi__core_core_arch_x86___m256i_4size_t(s); + chi__core_core_arch_x86___m256i_4size_t(s); + iota__core_core_arch_x86___m256i_4size_t(s, i0); + } +} + +static inline void absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice blocks[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, blocks, (size_t)4U * sizeof(Eurydice_slice)); + load_block___136size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +static inline void load_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + load_block___136size_t(uu____0, buf); +} + +static inline void load_block_full___136size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t ret[4U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + uint8_t out2[200U] = {0U}; + uint8_t out3[200U] = {0U}; + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = { + uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, out3, uint8_t, Eurydice_slice)}; + store_block___136size_t(uu____0, buf); + uint8_t uu____4[200U]; + memcpy(uu____4, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____5[200U]; + memcpy(uu____5, out1, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____6[200U]; + memcpy(uu____6, out2, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____7[200U]; + memcpy(uu____7, out3, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____4, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____5, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[2U], uu____6, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[3U], uu____7, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___136size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t ret[4U][200U]) { + uint8_t ret0[4U][200U]; + store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + uint8_t b[4U][200U]; + store_block_full___136size_t0(s->st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + store_block___136size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(s); + store_block___136size_t0(s->st, out); +} + +static inline void squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(&s); + uint8_t b[4U][200U]; + store_block_full___136size_t0(s.st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + Eurydice_slice data[4U], Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + s = new__core_core_arch_x86___m256i_4size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &s; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_x86___m256i_4size_t_136size_t(uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = &s; + Eurydice_slice uu____3[4U]; + memcpy(uu____3, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t(&s, + out); + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____4.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o1[4U]; + memcpy(o1, uu____4.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[4U]; + memcpy(o, uu____5.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice orest[4U]; + memcpy(orest, uu____5.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)4U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t(s, o1); + } + } +} + +void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, + Eurydice_slice input2, Eurydice_slice input3, + Eurydice_slice out0, Eurydice_slice out1, + Eurydice_slice out2, Eurydice_slice out3) { + Eurydice_slice buf0[4U] = {input0, input1, input2, input3}; + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(buf0, buf); +} + +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +libcrux_sha3_avx2_x4_incremental_shake128_init(void) { + return new__core_core_arch_x86___m256i_4size_t(); +} + +static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +static inline void load_block_full___168size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + load_block___168size_t(uu____0, buf); +} + +static inline void load_block_full___168size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___168size_t(uu____0, uu____1); } inline void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); +libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___168size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, + Eurydice_slice data3) { + Eurydice_slice buf[4U] = {data0, data1, data2, data3}; + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + s, buf); +} + +static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block___168size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + store_block___168size_t(a, b); +} + +static inline void +squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(s); + store_block___168size_t0(s->st, out); +} + +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, buf); +} + +static inline void +squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + store_block___168size_t0(s->st, out); } inline void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); +libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____0 = + split_at_mut_n(out, (size_t)168U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____0.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o10[4U]; + memcpy(o10, uu____0.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o0); + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____1 = + split_at_mut_n(o10, (size_t)168U); + Eurydice_slice o1[4U]; + memcpy(o1, uu____1.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o2[4U]; + memcpy(o2, uu____1.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o1); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o2); } +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + s, buf); +} diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 1889ad419..28d49028b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H @@ -12,60 +12,41 @@ extern "C" { #endif +#include "eurydice_glue.h" #include "intrinsics/libcrux_intrinsics_avx2.h" - -#include "libcrux_sha3_neon.h" #include "libcrux_core.h" -#include "eurydice_glue.h" +#include "libcrux_sha3_internal.h" -void -libcrux_sha3_avx2_x4_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice input2, - Eurydice_slice input3, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); +typedef struct + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { + core_core_arch_x86___m256i st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; -typedef struct libcrux_sha3_avx2_x4_incremental_KeccakState4_s -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U]; -} -libcrux_sha3_avx2_x4_incremental_KeccakState4; +void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, + Eurydice_slice input2, Eurydice_slice input3, + Eurydice_slice out0, Eurydice_slice out1, + Eurydice_slice out2, Eurydice_slice out3); -libcrux_sha3_avx2_x4_incremental_KeccakState4 +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t libcrux_sha3_avx2_x4_incremental_shake128_init(void); -void -libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice data0, - Eurydice_slice data1, - Eurydice_slice data2, - Eurydice_slice data3 -); - -void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); - -void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); +void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, + Eurydice_slice data3); + +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3); + +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index f8ef58186..86ffaa430 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H @@ -12,35 +12,43 @@ extern "C" { #endif -#include "libcrux_core.h" #include "eurydice_glue.h" +#include "libcrux_core.h" -static const -uint64_t -libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = - { - 1ULL, 32898ULL, 9223372036854808714ULL, 9223372039002292224ULL, 32907ULL, 2147483649ULL, - 9223372039002292353ULL, 9223372036854808585ULL, 138ULL, 136ULL, 2147516425ULL, 2147483658ULL, - 2147516555ULL, 9223372036854775947ULL, 9223372036854808713ULL, 9223372036854808579ULL, - 9223372036854808578ULL, 9223372036854775936ULL, 32778ULL, 9223372039002259466ULL, - 9223372039002292353ULL, 9223372036854808704ULL, 2147483649ULL, 9223372039002292232ULL - }; - -static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(void) -{ +static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { + 1ULL, + 32898ULL, + 9223372036854808714ULL, + 9223372039002292224ULL, + 32907ULL, + 2147483649ULL, + 9223372039002292353ULL, + 9223372036854808585ULL, + 138ULL, + 136ULL, + 2147516425ULL, + 2147483658ULL, + 2147516555ULL, + 9223372036854775947ULL, + 9223372036854808713ULL, + 9223372036854808579ULL, + 9223372036854808578ULL, + 9223372036854775936ULL, + 32778ULL, + 9223372039002259466ULL, + 9223372039002292353ULL, + 9223372036854808704ULL, + 2147483649ULL, + 9223372039002292232ULL}; + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero( + void) { return 0ULL; } -static inline uint64_t -libcrux_sha3_portable_keccak__veor5q_u64( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -) -{ +static inline uint64_t libcrux_sha3_portable_keccak__veor5q_u64( + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { uint64_t ab = a ^ b; uint64_t cd = c ^ d; uint64_t abcd = ab ^ cd; @@ -49,116 +57,82 @@ libcrux_sha3_portable_keccak__veor5q_u64( static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -) -{ + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) { return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; } -static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b) -{ +static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, + uint64_t b) { uint64_t uu____0 = a; - return uu____0 ^ libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); + return uu____0 ^ + libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); } -static inline uint64_t -libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) -{ +static inline uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, + uint64_t b, + uint64_t c) { return a ^ (b & ~c); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( - uint64_t a, - uint64_t b, - uint64_t c -) -{ + uint64_t a, uint64_t b, uint64_t c) { return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); } -static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) -{ +static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, + uint64_t c) { return a ^ c; } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( - uint64_t a, - uint64_t c -) -{ + uint64_t a, uint64_t c) { return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return a ^ b; } -static inline void -libcrux_sha3_portable_keccak_slice_1( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -) -{ - ret[0U] = - Eurydice_slice_subslice(a[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); +static inline void libcrux_sha3_portable_keccak_slice_1( + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { + ret[0U] = Eurydice_slice_subslice( + a[0U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -) -{ + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, a, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____0, a, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret0[1U]; libcrux_sha3_portable_keccak_slice_1(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice)); } static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], size_t mid) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at_mut(out[0U], - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); +libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], + size_t mid) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out[0U], mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice out00 = uu____0.fst; Eurydice_slice out01 = uu____0.snd; K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ lit; @@ -169,103 +143,87 @@ libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], size_t mid) static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - Eurydice_slice a[1U], - size_t mid -) -{ + Eurydice_slice a[1U], size_t mid) { return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); } -typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s -{ uint64_t st[5U][5U]; } -libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; +typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s { + uint64_t st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( - void -) -{ + void) { libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; lit.st[0U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); return lit; } -static inline void -libcrux_sha3_portable_keccak_load_block___168size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_load_block___168size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { size_t i0 = i; uint8_t ret[8U]; core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); size_t uu____1 = i0 / (size_t)5U; size_t uu____2 = i0 % (size_t)5U; @@ -273,766 +231,601 @@ libcrux_sha3_portable_keccak_load_block___168size_t( } } -static inline void -libcrux_sha3_portable_keccak_load_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_load_block_full___168size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, buf); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); libcrux_sha3_portable_keccak_load_block_full___168size_t(uu____0, uu____1); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) { return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) { return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) { return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) { return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) { return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) { return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) { return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) { return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) { return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) { return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) { return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) { return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) { return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) { return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) { return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) { return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) { return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) { return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) { return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) { return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) { return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) { return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); } static inline uint64_t -libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) -{ +libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) { return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; } static inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, uint64_t b) -{ +libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, + uint64_t b) { uint64_t ab = a ^ b; return libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(ab); } static inline uint64_t libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( - uint64_t a, - uint64_t b -) -{ + uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); } -static inline void -libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][0U], - s->st[1U][0U], - s->st[2U][0U], - s->st[3U][0U], - s->st[4U][0U]); - uint64_t - uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][1U], - s->st[1U][1U], - s->st[2U][1U], - s->st[3U][1U], - s->st[4U][1U]); - uint64_t - uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][2U], - s->st[1U][2U], - s->st[2U][2U], - s->st[3U][2U], - s->st[4U][2U]); - uint64_t - uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][3U], - s->st[1U][3U], - s->st[2U][3U], - s->st[3U][3U], - s->st[4U][3U]); - uint64_t - c[5U] = - { +static inline void libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + uint64_t uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + uint64_t uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + uint64_t uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + uint64_t c[5U] = { uu____0, uu____1, uu____2, uu____3, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][4U], - s->st[1U][4U], - s->st[2U][4U], - s->st[3U][4U], - s->st[4U][4U]) - }; - uint64_t - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)0U - + (size_t)4U) - % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)1U - + (size_t)4U) - % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____6 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)2U - + (size_t)4U) - % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____7 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)3U - + (size_t)4U) - % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - uint64_t - t[5U] = - { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + uint64_t uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + uint64_t uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + uint64_t uu____6 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + uint64_t uu____7 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + uint64_t t[5U] = { uu____4, uu____5, uu____6, uu____7, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)4U - + (size_t)4U) - % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U]) - }; - uint64_t - uu____8 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor(s->st[0U][0U], - t[0U]); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + uint64_t uu____8 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( + s->st[0U][0U], t[0U]); s->st[0U][0U] = uu____8; - uint64_t - uu____9 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], - t[0U]); + uint64_t uu____9 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( + s->st[1U][0U], t[0U]); s->st[1U][0U] = uu____9; - uint64_t - uu____10 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], - t[0U]); + uint64_t uu____10 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( + s->st[2U][0U], t[0U]); s->st[2U][0U] = uu____10; - uint64_t - uu____11 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], - t[0U]); + uint64_t uu____11 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( + s->st[3U][0U], t[0U]); s->st[3U][0U] = uu____11; - uint64_t - uu____12 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], - t[0U]); + uint64_t uu____12 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( + s->st[4U][0U], t[0U]); s->st[4U][0U] = uu____12; - uint64_t - uu____13 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], - t[1U]); + uint64_t uu____13 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( + s->st[0U][1U], t[1U]); s->st[0U][1U] = uu____13; - uint64_t - uu____14 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], - t[1U]); + uint64_t uu____14 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( + s->st[1U][1U], t[1U]); s->st[1U][1U] = uu____14; - uint64_t - uu____15 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], - t[1U]); + uint64_t uu____15 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( + s->st[2U][1U], t[1U]); s->st[2U][1U] = uu____15; - uint64_t - uu____16 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], - t[1U]); + uint64_t uu____16 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( + s->st[3U][1U], t[1U]); s->st[3U][1U] = uu____16; - uint64_t - uu____17 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], - t[1U]); + uint64_t uu____17 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( + s->st[4U][1U], t[1U]); s->st[4U][1U] = uu____17; - uint64_t - uu____18 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], - t[2U]); + uint64_t uu____18 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( + s->st[0U][2U], t[2U]); s->st[0U][2U] = uu____18; - uint64_t - uu____19 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], - t[2U]); + uint64_t uu____19 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( + s->st[1U][2U], t[2U]); s->st[1U][2U] = uu____19; - uint64_t - uu____20 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], - t[2U]); + uint64_t uu____20 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( + s->st[2U][2U], t[2U]); s->st[2U][2U] = uu____20; - uint64_t - uu____21 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], - t[2U]); + uint64_t uu____21 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( + s->st[3U][2U], t[2U]); s->st[3U][2U] = uu____21; - uint64_t - uu____22 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], - t[2U]); + uint64_t uu____22 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( + s->st[4U][2U], t[2U]); s->st[4U][2U] = uu____22; - uint64_t - uu____23 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], - t[3U]); + uint64_t uu____23 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( + s->st[0U][3U], t[3U]); s->st[0U][3U] = uu____23; - uint64_t - uu____24 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], - t[3U]); + uint64_t uu____24 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( + s->st[1U][3U], t[3U]); s->st[1U][3U] = uu____24; - uint64_t - uu____25 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], - t[3U]); + uint64_t uu____25 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( + s->st[2U][3U], t[3U]); s->st[2U][3U] = uu____25; - uint64_t - uu____26 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], - t[3U]); + uint64_t uu____26 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( + s->st[3U][3U], t[3U]); s->st[3U][3U] = uu____26; - uint64_t - uu____27 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], - t[3U]); + uint64_t uu____27 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( + s->st[4U][3U], t[3U]); s->st[4U][3U] = uu____27; - uint64_t - uu____28 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], - t[4U]); + uint64_t uu____28 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( + s->st[0U][4U], t[4U]); s->st[0U][4U] = uu____28; - uint64_t - uu____29 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], - t[4U]); + uint64_t uu____29 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( + s->st[1U][4U], t[4U]); s->st[1U][4U] = uu____29; - uint64_t - uu____30 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], - t[4U]); + uint64_t uu____30 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( + s->st[2U][4U], t[4U]); s->st[2U][4U] = uu____30; - uint64_t - uu____31 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], - t[4U]); + uint64_t uu____31 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( + s->st[3U][4U], t[4U]); s->st[3U][4U] = uu____31; - uint64_t - uu____32 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], - t[4U]); + uint64_t uu____32 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( + s->st[4U][4U], t[4U]); s->st[4U][4U] = uu____32; } -static inline void -libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ +static inline void libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { uint64_t old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, - s->st, - old, - uint64_t [5U], - void *); + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, uint64_t[5U], void *); s->st[0U][1U] = old[1U][1U]; s->st[0U][2U] = old[2U][2U]; s->st[0U][3U] = old[3U][3U]; @@ -1059,51 +852,31 @@ libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( s->st[4U][4U] = old[4U][1U]; } -static inline void -libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ +static inline void libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { uint64_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof (uint64_t [5U])); - KRML_MAYBE_FOR5(i0, - (size_t)0U, - (size_t)5U, - (size_t)1U, - size_t i1 = i0; - KRML_MAYBE_FOR5(i, - (size_t)0U, - (size_t)5U, - (size_t)1U, - size_t j = i; - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor(s->st[i1][j], - old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void -libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - size_t i -) -{ - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant(s->st[0U][0U], - libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( + i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, size_t i) { + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); s->st[0U][0U] = uu____0; } -static inline void -libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - for (size_t i = (size_t)0U; i < (size_t)24U; i++) - { +static inline void libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { size_t i0 = i; libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t(s); libcrux_sha3_generic_keccak_pi__uint64_t_1size_t(s); @@ -1114,153 +887,118 @@ libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; - blocks[i][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i][(size_t)168U - (size_t)1U] | 128U; + blocks[i][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)168U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block___168size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_store_block___168size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ + uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___168size_t(a, b); } static inline void libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, - out); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, - out); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( + s->st, out); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t(uu____0, - uu____1); + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( + uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_store_block_full___168size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_store_block___168size_t(uu____0, buf); uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); } static inline void libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s->st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + s->st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -1268,28 +1006,23 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s.st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + s.st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -1297,151 +1030,114 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)168U, - (size_t)168U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)168U, (size_t)168U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( + uu____0, ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)168U; size_t last = outlen - outlen % (size_t)168U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)168U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)168U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)168U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( + uu____0, out); } -static inline void -libcrux_sha3_portable_keccak_load_block___104size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_load_block___104size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { size_t i0 = i; uint8_t ret[8U]; core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); size_t uu____1 = i0 / (size_t)5U; size_t uu____2 = i0 % (size_t)5U; @@ -1451,147 +1147,112 @@ libcrux_sha3_portable_keccak_load_block___104size_t( static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t(uu____0, - uu____1); + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( + uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_load_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_load_block_full___104size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, buf); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); libcrux_sha3_portable_keccak_load_block_full___104size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; - blocks[i][(size_t)104U - (size_t)1U] = (uint32_t)blocks[i][(size_t)104U - (size_t)1U] | 128U; + blocks[i][(size_t)104U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)104U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block___104size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_store_block___104size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline void -libcrux_sha3_portable_keccak_store_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_store_block_full___104size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_store_block___104size_t(uu____0, buf); uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); } static inline void libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s->st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + s->st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -1599,58 +1260,46 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ + uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___104size_t(a, b); } static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, - out); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, - out); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s.st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + s.st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -1658,151 +1307,114 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)104U, - (size_t)104U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)104U, (size_t)104U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( + uu____0, ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)104U; size_t last = outlen - outlen % (size_t)104U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)104U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)104U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)104U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)104U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( + uu____0, out); } -static inline void -libcrux_sha3_portable_keccak_load_block___144size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_load_block___144size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { size_t i0 = i; uint8_t ret[8U]; core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); size_t uu____1 = i0 / (size_t)5U; size_t uu____2 = i0 % (size_t)5U; @@ -1812,147 +1424,112 @@ libcrux_sha3_portable_keccak_load_block___144size_t( static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t(uu____0, - uu____1); + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( + uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_load_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_load_block_full___144size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, buf); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); libcrux_sha3_portable_keccak_load_block_full___144size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; - blocks[i][(size_t)144U - (size_t)1U] = (uint32_t)blocks[i][(size_t)144U - (size_t)1U] | 128U; + blocks[i][(size_t)144U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)144U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block___144size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_store_block___144size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline void -libcrux_sha3_portable_keccak_store_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_store_block_full___144size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_store_block___144size_t(uu____0, buf); uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); } static inline void libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s->st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + s->st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -1960,58 +1537,46 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ + uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___144size_t(a, b); } static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, - out); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, - out); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s.st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + s.st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -2019,151 +1584,114 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)144U, - (size_t)144U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)144U, (size_t)144U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( + uu____0, ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)144U; size_t last = outlen - outlen % (size_t)144U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)144U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)144U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)144U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)144U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( + uu____0, out); } -static inline void -libcrux_sha3_portable_keccak_load_block___136size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_load_block___136size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { size_t i0 = i; uint8_t ret[8U]; core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); size_t uu____1 = i0 / (size_t)5U; size_t uu____2 = i0 % (size_t)5U; @@ -2173,147 +1701,112 @@ libcrux_sha3_portable_keccak_load_block___136size_t( static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t(uu____0, - uu____1); + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( + uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_load_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_load_block_full___136size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, buf); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); libcrux_sha3_portable_keccak_load_block_full___136size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; - blocks[i][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + blocks[i][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block___136size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_store_block___136size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline void -libcrux_sha3_portable_keccak_store_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_store_block_full___136size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_store_block___136size_t(uu____0, buf); uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); } static inline void libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s->st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + s->st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -2321,58 +1814,46 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ + uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___136size_t(a, b); } static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, - out); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, - out); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s.st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + s.st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -2380,287 +1861,222 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)136U, - (size_t)136U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + uu____0, ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)136U; size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)136U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)136U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)136U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)136U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( + uu____0, out); } static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; - blocks[i][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + blocks[i][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)136U, - (size_t)136U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + uu____0, ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)136U; size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)136U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)136U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)136U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)136U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( + uu____0, out); } -static inline void -libcrux_sha3_portable_keccak_load_block___72size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_load_block___72size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { size_t i0 = i; uint8_t ret[8U]; core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); size_t uu____1 = i0 / (size_t)5U; size_t uu____2 = i0 % (size_t)5U; @@ -2670,147 +2086,112 @@ libcrux_sha3_portable_keccak_load_block___72size_t( static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t(uu____0, - uu____1); + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( + uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_load_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_load_block_full___72size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, buf); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); libcrux_sha3_portable_keccak_load_block_full___72size_t(uu____0, uu____1); } static inline void libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; + uint8_t blocks[1U][200U] = {{0U}}; { size_t i = (size_t)0U; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; - blocks[i][(size_t)72U - (size_t)1U] = (uint32_t)blocks[i][(size_t)72U - (size_t)1U] | 128U; + blocks[i][(size_t)72U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)72U - (size_t)1U] | 128U; } - uint64_t (*uu____1)[5U] = s->st; + uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t(uu____1, - uu____2); + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( + uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } -static inline void -libcrux_sha3_portable_keccak_store_block___72size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) - { +static inline void libcrux_sha3_portable_keccak_store_block___72size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); } } -static inline void -libcrux_sha3_portable_keccak_store_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; +static inline void libcrux_sha3_portable_keccak_store_block_full___72size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; libcrux_sha3_portable_keccak_store_block___72size_t(uu____0, buf); uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); } static inline void libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s->st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + s->st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -2818,58 +2199,46 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ + uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___72size_t(a, b); } static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, - out); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, - out); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( + s->st, out); } static inline void libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s.st, - b); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + s.st, b); { size_t i = (size_t)0U; Eurydice_slice uu____0 = out[i]; @@ -2877,122 +2246,96 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( core_ops_range_Range__size_t lit; lit.start = (size_t)0U; lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); } } static inline void libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; - i++) - { + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; + i++) { size_t i0 = i; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)72U, - (size_t)72U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)72U, (size_t)72U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, + ret); } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t(uu____2, ret); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( + uu____2, ret); size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); size_t blocks = outlen / (size_t)72U; size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)72U); + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)72U); Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)72U); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)72U); Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); } } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, o1); + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, + o1); } } } -static inline void -libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ +static inline void libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t(uu____0, out); + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( + uu____0, out); } #if defined(__cplusplus) diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index a0b803a00..b9aa5c77b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,3689 +1,187 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_sha3_neon.h" #include "internal/libcrux_core.h" -static inline core_core_arch_arm_shared_neon_uint64x2_t zero(void) -{ - return libcrux_intrinsics_arm64__vdupq_n_u64(0ULL); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_veor5q_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c, - core_core_arch_arm_shared_neon_uint64x2_t d, - core_core_arch_arm_shared_neon_uint64x2_t e -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - core_core_arch_arm_shared_neon_uint64x2_t cd = libcrux_intrinsics_arm64__veorq_u64(c, d); - core_core_arch_arm_shared_neon_uint64x2_t abcd = libcrux_intrinsics_arm64__veorq_u64(ab, cd); - return libcrux_intrinsics_arm64__veorq_u64(abcd, e); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor5( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c, - core_core_arch_arm_shared_neon_uint64x2_t d, - core_core_arch_arm_shared_neon_uint64x2_t e -) -{ - return _veor5q_u64(a, b, c, d, e); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)1, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)63, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vrax1q_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; - return libcrux_intrinsics_arm64__veorq_u64(uu____0, rotate_left___1int32_t_63int32_t(b)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left1_and_xor( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vrax1q_u64(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vbcaxq_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c -) -{ - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; - return libcrux_intrinsics_arm64__veorq_u64(uu____0, libcrux_intrinsics_arm64__vbicq_u64(b, c)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -and_not_xor( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c -) -{ - return _vbcaxq_u64(a, b, c); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_veorq_n_u64(core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) -{ - core_core_arch_arm_shared_neon_uint64x2_t c0 = libcrux_intrinsics_arm64__vdupq_n_u64(c); - return libcrux_intrinsics_arm64__veorq_u64(a, c0); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_constant(core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) -{ - return _veorq_n_u64(a, c); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor0(core_core_arch_arm_shared_neon_uint64x2_t a, core_core_arch_arm_shared_neon_uint64x2_t b) -{ - return libcrux_intrinsics_arm64__veorq_u64(a, b); -} - -static inline void -slice_2(Eurydice_slice a[2U], size_t start, size_t len, Eurydice_slice ret[2U]) -{ - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(a[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - ret[0U] = uu____0; - ret[1U] = - Eurydice_slice_subslice(a[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); -} - -static inline void -slice_n(Eurydice_slice a[2U], size_t start, size_t len, Eurydice_slice ret[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, a, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret0[2U]; - slice_2(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (Eurydice_slice)); -} - -static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ -split_at_mut_2(Eurydice_slice out[2U], size_t mid) -{ - Eurydice_slice out0 = out[0U]; - Eurydice_slice out1 = out[1U]; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at_mut(out0, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at_mut(out1, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out10 = uu____1.fst; - Eurydice_slice out11 = uu____1.snd; - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ lit; - lit.fst[0U] = out00; - lit.fst[1U] = out10; - lit.snd[0U] = out01; - lit.snd[1U] = out11; - return lit; -} - -static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ -split_at_mut_n(Eurydice_slice a[2U], size_t mid) -{ - return split_at_mut_2(a, mid); -} - -static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t -new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(void) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - lit; - lit.st[0U][0U] = zero(); - lit.st[0U][1U] = zero(); - lit.st[0U][2U] = zero(); - lit.st[0U][3U] = zero(); - lit.st[0U][4U] = zero(); - lit.st[1U][0U] = zero(); - lit.st[1U][1U] = zero(); - lit.st[1U][2U] = zero(); - lit.st[1U][3U] = zero(); - lit.st[1U][4U] = zero(); - lit.st[2U][0U] = zero(); - lit.st[2U][1U] = zero(); - lit.st[2U][2U] = zero(); - lit.st[2U][3U] = zero(); - lit.st[2U][4U] = zero(); - lit.st[3U][0U] = zero(); - lit.st[3U][1U] = zero(); - lit.st[3U][2U] = zero(); - lit.st[3U][3U] = zero(); - lit.st[3U][4U] = zero(); - lit.st[4U][0U] = zero(); - lit.st[4U][1U] = zero(); - lit.st[4U][2U] = zero(); - lit.st[4U][3U] = zero(); - lit.st[4U][4U] = zero(); - return lit; -} - -static inline void -load_block___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = - s[((size_t)2U * i0 + (size_t)1U) - / (size_t)5U][((size_t)2U * i0 + (size_t)1U) - % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = - libcrux_intrinsics_arm64__veorq_u64(uu____2, - libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = - uu____3; - } - if ((size_t)72U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = { 0U }; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2(&dst0, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, - ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t - uvec = - libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, - u, - uint64_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void -load_block___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); - load_block___72size_t(uu____0, uu____1); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)36, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)28, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___36int32_t_28int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___36int32_t_28int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___36int32_t_28int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___36int32_t_28int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)3, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)61, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___3int32_t_61int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___3int32_t_61int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___3int32_t_61int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___3int32_t_61int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)41, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)23, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___41int32_t_23int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___41int32_t_23int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___41int32_t_23int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___41int32_t_23int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)18, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)46, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___18int32_t_46int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___18int32_t_46int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___18int32_t_46int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___18int32_t_46int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___1int32_t_63int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___1int32_t_63int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___1int32_t_63int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___1int32_t_63int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)44, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)20, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___44int32_t_20int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___44int32_t_20int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___44int32_t_20int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___44int32_t_20int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)10, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)54, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___10int32_t_54int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___10int32_t_54int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___10int32_t_54int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___10int32_t_54int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)45, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)19, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___45int32_t_19int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___45int32_t_19int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___45int32_t_19int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___45int32_t_19int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)2, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)62, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___2int32_t_62int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___2int32_t_62int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___2int32_t_62int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___2int32_t_62int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)62, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)2, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___62int32_t_2int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___62int32_t_2int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___62int32_t_2int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___62int32_t_2int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)6, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)58, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___6int32_t_58int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___6int32_t_58int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___6int32_t_58int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___6int32_t_58int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)43, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)21, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___43int32_t_21int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___43int32_t_21int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___43int32_t_21int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___43int32_t_21int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)15, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)49, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___15int32_t_49int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___15int32_t_49int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___15int32_t_49int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___15int32_t_49int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)61, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)3, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___61int32_t_3int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___61int32_t_3int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___61int32_t_3int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___61int32_t_3int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)28, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)36, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___28int32_t_36int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___28int32_t_36int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___28int32_t_36int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___28int32_t_36int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)55, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)9, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___55int32_t_9int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___55int32_t_9int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___55int32_t_9int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___55int32_t_9int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)25, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)39, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___25int32_t_39int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___25int32_t_39int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___25int32_t_39int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___25int32_t_39int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)21, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)43, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___21int32_t_43int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___21int32_t_43int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___21int32_t_43int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___21int32_t_43int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)56, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)8, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___56int32_t_8int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___56int32_t_8int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___56int32_t_8int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___56int32_t_8int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)27, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)37, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___27int32_t_37int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___27int32_t_37int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___27int32_t_37int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___27int32_t_37int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)20, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)44, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___20int32_t_44int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___20int32_t_44int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___20int32_t_44int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___20int32_t_44int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)39, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)25, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___39int32_t_25int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___39int32_t_25int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___39int32_t_25int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___39int32_t_25int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)8, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)56, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___8int32_t_56int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___8int32_t_56int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___8int32_t_56int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___8int32_t_56int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64((int32_t)14, - x, - core_core_arch_arm_shared_neon_uint64x2_t); - return - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vshrq_n_u64((int32_t)50, - x, - core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___14int32_t_50int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - core_core_arch_arm_shared_neon_uint64x2_t ab = libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___14int32_t_50int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___14int32_t_50int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b -) -{ - return _vxarq_u64___14int32_t_50int32_t(a, b); -} - -static inline void -theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s -) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], s->st[4U][0U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], s->st[4U][1U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], s->st[4U][2U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], s->st[4U][3U]); - core_core_arch_arm_shared_neon_uint64x2_t - c[5U] = - { - uu____0, uu____1, uu____2, uu____3, - xor5(s->st[0U][4U], - s->st[1U][4U], - s->st[2U][4U], - s->st[3U][4U], - s->st[4U][4U]) - }; - core_core_arch_arm_shared_neon_uint64x2_t - uu____4 = - rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____5 = - rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = - rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - uu____7 = - rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - t[5U] = - { - uu____4, uu____5, uu____6, uu____7, - rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U]) - }; - core_core_arch_arm_shared_neon_uint64x2_t uu____8 = xor0(s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - core_core_arch_arm_shared_neon_uint64x2_t - uu____9 = xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); - s->st[1U][0U] = uu____9; - core_core_arch_arm_shared_neon_uint64x2_t - uu____10 = xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); - s->st[2U][0U] = uu____10; - core_core_arch_arm_shared_neon_uint64x2_t - uu____11 = xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); - s->st[3U][0U] = uu____11; - core_core_arch_arm_shared_neon_uint64x2_t - uu____12 = xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); - s->st[4U][0U] = uu____12; - core_core_arch_arm_shared_neon_uint64x2_t - uu____13 = xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); - s->st[0U][1U] = uu____13; - core_core_arch_arm_shared_neon_uint64x2_t - uu____14 = xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); - s->st[1U][1U] = uu____14; - core_core_arch_arm_shared_neon_uint64x2_t - uu____15 = xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); - s->st[2U][1U] = uu____15; - core_core_arch_arm_shared_neon_uint64x2_t - uu____16 = xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); - s->st[3U][1U] = uu____16; - core_core_arch_arm_shared_neon_uint64x2_t - uu____17 = xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); - s->st[4U][1U] = uu____17; - core_core_arch_arm_shared_neon_uint64x2_t - uu____18 = xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); - s->st[0U][2U] = uu____18; - core_core_arch_arm_shared_neon_uint64x2_t - uu____19 = xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); - s->st[1U][2U] = uu____19; - core_core_arch_arm_shared_neon_uint64x2_t - uu____20 = xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); - s->st[2U][2U] = uu____20; - core_core_arch_arm_shared_neon_uint64x2_t - uu____21 = xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); - s->st[3U][2U] = uu____21; - core_core_arch_arm_shared_neon_uint64x2_t - uu____22 = xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); - s->st[4U][2U] = uu____22; - core_core_arch_arm_shared_neon_uint64x2_t - uu____23 = xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); - s->st[0U][3U] = uu____23; - core_core_arch_arm_shared_neon_uint64x2_t - uu____24 = xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); - s->st[1U][3U] = uu____24; - core_core_arch_arm_shared_neon_uint64x2_t - uu____25 = xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); - s->st[2U][3U] = uu____25; - core_core_arch_arm_shared_neon_uint64x2_t - uu____26 = xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); - s->st[3U][3U] = uu____26; - core_core_arch_arm_shared_neon_uint64x2_t - uu____27 = xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); - s->st[4U][3U] = uu____27; - core_core_arch_arm_shared_neon_uint64x2_t - uu____28 = xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); - s->st[0U][4U] = uu____28; - core_core_arch_arm_shared_neon_uint64x2_t - uu____29 = xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); - s->st[1U][4U] = uu____29; - core_core_arch_arm_shared_neon_uint64x2_t - uu____30 = xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); - s->st[2U][4U] = uu____30; - core_core_arch_arm_shared_neon_uint64x2_t - uu____31 = xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); - s->st[3U][4U] = uu____31; - core_core_arch_arm_shared_neon_uint64x2_t - uu____32 = xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____32; -} - -static inline void -pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s -) -{ - core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, - s->st, - old, - core_core_arch_arm_shared_neon_uint64x2_t [5U], - void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -static inline void -chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s -) -{ - core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof (core_core_arch_arm_shared_neon_uint64x2_t [5U])); - KRML_MAYBE_FOR5(i0, - (size_t)0U, - (size_t)5U, - (size_t)1U, - size_t i1 = i0; - KRML_MAYBE_FOR5(i, - (size_t)0U, - (size_t)5U, - (size_t)1U, - size_t j = i; - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = - and_not_xor(s->st[i1][j], - old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void -iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - size_t i -) -{ - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = xor_constant(s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -static inline void -keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s -) -{ - for (size_t i = (size_t)0U; i < (size_t)24U; i++) - { - size_t i0 = i; - theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s, i0); - } -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice blocks[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); - load_block___72size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -load_block_full___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = - { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; - load_block___72size_t(uu____0, buf); -} - -static inline void -load_block_full___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t b[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___72size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)72U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)72U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___72size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -store_block___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)72U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)72U - (size_t)8U, .end = (size_t)72U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -store_block_full___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t out0[200U] = { 0U }; - uint8_t out1[200U] = { 0U }; - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; - store_block___72size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); -} - -static inline void -store_block_full___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t ret0[2U][200U]; - store_block_full___72size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - uint8_t b[2U][200U]; - store_block_full___72size_t0(s->st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -store_block___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - store_block___72size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - store_block___72size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___72size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___72size_t0(s.st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - Eurydice_slice data[2U], - Eurydice_slice out[2U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)72U, (size_t)72U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)72U; - size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) - { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)72U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)72U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(&s, o); - memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t(s, o1); - } - } -} - -static inline void -keccakx2___72size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t(uu____0, out); -} - -void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) -{ - uint8_t dummy[64U] = { 0U }; - Eurydice_slice uu____0[2U] = { data, data }; - Eurydice_slice uu____1 = digest; - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)64U, dummy, uint8_t, Eurydice_slice) }; - keccakx2___72size_t_6uint8_t(uu____0, buf); -} - -static inline void -load_block___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = - s[((size_t)2U * i0 + (size_t)1U) - / (size_t)5U][((size_t)2U * i0 + (size_t)1U) - % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = - libcrux_intrinsics_arm64__veorq_u64(uu____2, - libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = - uu____3; - } - if ((size_t)136U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = { 0U }; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2(&dst0, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, - ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t - uvec = - libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, - u, - uint64_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void -load_block___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); - load_block___136size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice blocks[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); - load_block___136size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -load_block_full___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = - { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; - load_block___136size_t(uu____0, buf); -} - -static inline void -load_block_full___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t b[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___136size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -store_block___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)136U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)136U - (size_t)8U, .end = (size_t)136U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -store_block_full___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t out0[200U] = { 0U }; - uint8_t out1[200U] = { 0U }; - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; - store_block___136size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); -} - -static inline void -store_block_full___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t ret0[2U][200U]; - store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - uint8_t b[2U][200U]; - store_block_full___136size_t0(s->st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -store_block___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - store_block___136size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___136size_t0(s.st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - Eurydice_slice data[2U], - Eurydice_slice out[2U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(s, o1); - } - } -} - -static inline void -keccakx2___136size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t(uu____0, out); -} - -void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) -{ - uint8_t dummy[32U] = { 0U }; - Eurydice_slice uu____0[2U] = { data, data }; - Eurydice_slice uu____1 = digest; - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice) }; - keccakx2___136size_t_6uint8_t(uu____0, buf); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - Eurydice_slice data[2U], - Eurydice_slice out[2U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t(s, o1); - } - } -} - -static inline void -keccakx2___136size_t_31uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t(uu____0, out); -} - -void -libcrux_sha3_neon_x2_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Eurydice_slice buf0[2U] = { input0, input1 }; - Eurydice_slice buf[2U] = { out0, out1 }; - keccakx2___136size_t_31uint8_t(buf0, buf); -} - -typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t -KeccakState2; - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t -libcrux_sha3_neon_x2_incremental_shake128_init(void) -{ - return new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); -} - -static inline void -load_block___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = - s[((size_t)2U * i0 + (size_t)1U) - / (size_t)5U][((size_t)2U * i0 + (size_t)1U) - % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = - libcrux_intrinsics_arm64__veorq_u64(uu____2, - libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = - uu____3; - } - if ((size_t)168U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = { 0U }; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2(&dst0, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, - ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t - uvec = - libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, - u, - uint64_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void -load_block_full___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = - { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; - load_block___168size_t(uu____0, buf); -} - -static inline void -load_block_full___168size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t b[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___168size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___168size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -void -libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice data0, - Eurydice_slice data1 -) -{ - Eurydice_slice buf[2U] = { data0, data1 }; - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t(s, buf); -} - -static inline void -store_block___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)168U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)168U - (size_t)8U, .end = (size_t)168U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -store_block___168size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - store_block___168size_t(a, b); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___168size_t0(s->st, out); -} - -void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Eurydice_slice buf[2U] = { out0, out1 }; - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, buf); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - store_block___168size_t0(s->st, out); -} - -static inline void -squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____0 = split_at_mut_n(out, (size_t)168U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____0.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o10[2U]; - memcpy(o10, uu____0.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____1 = split_at_mut_n(o10, (size_t)168U); - Eurydice_slice o1[2U]; - memcpy(o1, uu____1.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o2[2U]; - memcpy(o2, uu____1.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o1); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, o2); -} - -void +inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline libcrux_sha3_neon_x2_incremental_KeccakState2 +libcrux_sha3_neon_x2_incremental_shake128_init(void) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, + Eurydice_slice data1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Eurydice_slice buf[2U] = { out0, out1 }; - squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t(s, - buf); -} - -static inline void -load_block___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = - s[((size_t)2U * i0 + (size_t)1U) - / (size_t)5U][((size_t)2U * i0 + (size_t)1U) - % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = - libcrux_intrinsics_arm64__veorq_u64(uu____2, - libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = - uu____3; - } - if ((size_t)144U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = { 0U }; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2(&dst0, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, - ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t - uvec = - libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, - u, - uint64_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void -load_block___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); - load_block___144size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice blocks[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); - load_block___144size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -load_block_full___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = - { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; - load_block___144size_t(uu____0, buf); -} - -static inline void -load_block_full___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t b[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___144size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)144U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)144U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___144size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -store_block___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)144U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)144U - (size_t)8U, .end = (size_t)144U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -store_block_full___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t out0[200U] = { 0U }; - uint8_t out1[200U] = { 0U }; - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; - store_block___144size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); -} - -static inline void -store_block_full___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t ret0[2U][200U]; - store_block_full___144size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - uint8_t b[2U][200U]; - store_block_full___144size_t0(s->st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -store_block___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - store_block___144size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - store_block___144size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___144size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___144size_t0(s.st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - Eurydice_slice data[2U], - Eurydice_slice out[2U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)144U, (size_t)144U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)144U; - size_t last = outlen - outlen % (size_t)144U; - if (blocks == (size_t)0U) - { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)144U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)144U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(&s, o); - memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t(s, o1); - } - } -} - -static inline void -keccakx2___144size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) -{ - uint8_t dummy[28U] = { 0U }; - Eurydice_slice uu____0[2U] = { data, data }; - Eurydice_slice uu____1 = digest; - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)28U, dummy, uint8_t, Eurydice_slice) }; - keccakx2___144size_t_6uint8_t(uu____0, buf); -} - -static inline void -load_block___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____0 = s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____1 = - libcrux_intrinsics_arm64__veorq_u64(uu____0, - libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t - uu____2 = - s[((size_t)2U * i0 + (size_t)1U) - / (size_t)5U][((size_t)2U * i0 + (size_t)1U) - % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t - uu____3 = - libcrux_intrinsics_arm64__veorq_u64(uu____2, - libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = - uu____3; - } - if ((size_t)104U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = { 0U }; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2(&dst0, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst0, - ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t - uvec = - libcrux_intrinsics_arm64__vld1q_u64(Eurydice_array_to_slice((size_t)2U, - u, - uint64_t, - Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t - uu____6 = libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void -load_block___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof (Eurydice_slice)); - load_block___104size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice blocks[2U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof (Eurydice_slice)); - load_block___104size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -load_block_full___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = - { uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice) }; - load_block___104size_t(uu____0, buf); -} - -static inline void -load_block_full___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t b[2U][200U] -) -{ - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___104size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice last[2U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = { { 0U } }; - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)104U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)104U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t (*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof (uint8_t [200U])); - load_block_full___104size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -store_block___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) - { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t - v0 = - libcrux_intrinsics_arm64__vtrn1q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t - v1 = - libcrux_intrinsics_arm64__vtrn2q_u64(s[(size_t)2U - * i0 - / (size_t)5U][(size_t)2U - * i0 - % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U][((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)104U % (size_t)16U != (size_t)0U) - { - size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = { 0U }; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = (size_t)104U - (size_t)8U, .end = (size_t)104U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)16U, - u, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -static inline void -store_block_full___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t out0[200U] = { 0U }; - uint8_t out1[200U] = { 0U }; - core_core_arch_arm_shared_neon_uint64x2_t (*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice) }; - store_block___104size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof (uint8_t)); -} - -static inline void -store_block_full___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - uint8_t ret[2U][200U] -) -{ - uint8_t ret0[2U][200U]; - store_block_full___104size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof (uint8_t [200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - uint8_t b[2U][200U]; - store_block_full___104size_t0(s->st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -store_block___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], - Eurydice_slice b[2U] -) -{ - store_block___104size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - store_block___104size_t0(s->st, out); + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___104size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t s, - Eurydice_slice out[2U] -) -{ - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___104size_t0(s.st, b); - KRML_MAYBE_FOR2(i, - (size_t)0U, - (size_t)2U, - (size_t)1U, - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - Eurydice_slice data[2U], - Eurydice_slice out[2U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)104U, (size_t)104U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)104U; - size_t last = outlen - outlen % (size_t)104U; - if (blocks == (size_t)0U) - { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)104U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)104U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof (Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof (Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(&s, o); - memcpy(o1, orest, (size_t)2U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t(s, o1); - } - } -} - -static inline void -keccakx2___104size_t_6uint8_t(Eurydice_slice data[2U], Eurydice_slice out[2U]) -{ - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof (Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) -{ - uint8_t dummy[48U] = { 0U }; - Eurydice_slice uu____0[2U] = { data, data }; - Eurydice_slice uu____1 = digest; - Eurydice_slice - buf[2U] = { uu____1, Eurydice_array_to_slice((size_t)48U, dummy, uint8_t, Eurydice_slice) }; - keccakx2___104size_t_6uint8_t(uu____0, buf); -} - diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 921691e48..0861469fa 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ -/* +/* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc - F* version: b5cb71b8 - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H @@ -12,52 +12,36 @@ extern "C" { #endif +#include "eurydice_glue.h" #include "intrinsics/libcrux_intrinsics_arm64.h" - -#include "libcrux_sha3_internal.h" #include "libcrux_core.h" -#include "eurydice_glue.h" - -typedef struct -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t_s -{ core_core_arch_arm_shared_neon_uint64x2_t st[5U][5U]; } -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t; +#include "libcrux_sha3_internal.h" void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); -void -libcrux_sha3_neon_x2_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1 -); +void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, + Eurydice_slice out0, Eurydice_slice out1); + +typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; +} libcrux_sha3_neon_x2_incremental_KeccakState2; -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +libcrux_sha3_neon_x2_incremental_KeccakState2 libcrux_sha3_neon_x2_incremental_shake128_init(void); -void -libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice data0, - Eurydice_slice data1 -); +void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, + Eurydice_slice data1); -void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out0, - Eurydice_slice out1 -); +void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1); -void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t *s, - Eurydice_slice out0, - Eurydice_slice out1 -); +void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1); void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); From 3be01512d9a9f96a0caa591ddc8f8569342db07c Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 16:36:08 -0700 Subject: [PATCH 15/84] Don't return when in a void function --- libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_avx2.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_avx2.h b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_avx2.h index 099dfb82e..d7ebcbe67 100644 --- a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_avx2.h +++ b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_avx2.h @@ -118,22 +118,22 @@ static inline core_core_arch_x86___m128i libcrux_intrinsics_avx2_mm_loadu_si128( static inline void libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_slice a, core_core_arch_x86___m128i b) { - return _mm_storeu_si128((__m128i*)a.ptr, b); + _mm_storeu_si128((__m128i*)a.ptr, b); } static inline void libcrux_intrinsics_avx2_mm256_storeu_si256_i16( Eurydice_slice a, core_core_arch_x86___m256i b) { - return _mm256_storeu_si256((__m256i*)a.ptr, b); + _mm256_storeu_si256((__m256i*)a.ptr, b); } static inline void libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice a, core_core_arch_x86___m256i b) { - return _mm256_storeu_si256((__m256i*)a.ptr, b); + _mm256_storeu_si256((__m256i*)a.ptr, b); } static inline void libcrux_intrinsics_avx2_mm_storeu_si128( Eurydice_slice a, core_core_arch_x86___m128i b) { - return _mm_storeu_si128((__m128i*)a.ptr, b); + _mm_storeu_si128((__m128i*)a.ptr, b); } // Arithmetic: Add, Sub From 603b3d8288044edbaf5221813473b65cb8dc155a Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Wed, 5 Jun 2024 16:36:20 -0700 Subject: [PATCH 16/84] Refresh with upcoming type alias change --- libcrux-ml-kem/c/eurydice_glue.h | 8 +++++++ libcrux-ml-kem/c/internal/libcrux_core.h | 12 +++++----- .../c/internal/libcrux_mlkem_avx2.h | 10 ++++----- .../c/internal/libcrux_mlkem_portable.h | 10 ++++----- .../c/internal/libcrux_sha3_internal.h | 8 +++++++ libcrux-ml-kem/c/libcrux_core.c | 22 +++++++++---------- libcrux-ml-kem/c/libcrux_core.h | 20 ++++++++--------- libcrux-ml-kem/c/libcrux_mlkem1024.c | 10 ++++----- libcrux-ml-kem/c/libcrux_mlkem1024.h | 16 +++++++++----- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 4 ++-- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 4 ++-- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem512.h | 12 ++++++++++ libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 9 ++++---- libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 10 ++++----- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 9 ++++---- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 10 ++++----- libcrux-ml-kem/c/libcrux_mlkem768.c | 12 +++++----- libcrux-ml-kem/c/libcrux_mlkem768.h | 16 +++++++++----- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 5 ++--- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 13 +++++------ libcrux-ml-kem/c/libcrux_mlkem_portable.c | 13 +++++------ 26 files changed, 136 insertions(+), 122 deletions(-) diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index bd794c456..ef21a5003 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -10,6 +10,10 @@ extern "C" { #include #include +#ifdef _MSC_VER +#include +#endif + #include "krml/internal/target.h" #include "krml/lowstar_endianness.h" @@ -124,7 +128,11 @@ core_convert_num___core__convert__From_i32__for_i64__59__from(int32_t x) { } static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +#ifdef _MSC_VER + return __popcnt(x0); +#else return __builtin_popcount(x0); +#endif } // unsigned overflow wraparound semantics in C diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index d449e80ba..5ca28c79c 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -48,7 +48,7 @@ libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uint8_t value[1568U]); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk); @@ -62,7 +62,7 @@ typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s { uint8_t snd[1568U]; } K___uint8_t_1536size_t__uint8_t_1568size_t_; -libcrux_ml_kem_types_MlKemCiphertext____1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uint8_t value[1568U]); @@ -76,7 +76,7 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *self); void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, uint8_t ret[1600U]); @@ -85,7 +85,7 @@ libcrux_ml_kem_types_MlKemPublicKey____1184size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( uint8_t value[1184U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk); @@ -99,7 +99,7 @@ typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s { uint8_t snd[1184U]; } K___uint8_t_1152size_t__uint8_t_1184size_t_; -libcrux_ml_kem_types_MlKemCiphertext____1088size_t +libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uint8_t value[1088U]); @@ -113,7 +113,7 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self); void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index b95276a30..4332f30ed 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -21,7 +21,7 @@ extern "C" { bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -32,13 +32,12 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -49,8 +48,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uint8_t *public_key); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 8d67ca22e..4fa834a92 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -26,7 +26,7 @@ extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U]; bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536size_t_1568size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -37,13 +37,12 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -54,8 +53,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_800size_t( uint8_t *public_key); diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 391656b64..32b53c527 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -243,6 +243,14 @@ libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from( return uu____0; } +typedef uint8_t libcrux_sha3_Sha3_512Digest[64U]; + +typedef uint8_t libcrux_sha3_Sha3_384Digest[48U]; + +typedef uint8_t libcrux_sha3_Sha3_256Digest[32U]; + +typedef uint8_t libcrux_sha3_Sha3_224Digest[28U]; + #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index b114068a3..6f32affcf 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -60,12 +60,11 @@ libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem_ return lit; } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t){ - .sk = sk, .pk = pk}); + return ((libcrux_ml_kem_mlkem1024_MlKem1024KeyPair){.sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____3168size_t @@ -78,12 +77,12 @@ libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem_ return lit; } -libcrux_ml_kem_types_MlKemCiphertext____1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uint8_t value[1568U]) { uint8_t uu____0[1568U]; memcpy(uu____0, value, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t lit; + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext lit; memcpy(lit.value, uu____0, (size_t)1568U * sizeof(uint8_t)); return lit; } @@ -111,7 +110,7 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *self) { + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *self) { return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t, Eurydice_slice); } @@ -141,12 +140,11 @@ libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem_ return lit; } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t){ - .sk = sk, .pk = pk}); + return ((libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____2400size_t @@ -159,12 +157,12 @@ libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem_ return lit; } -libcrux_ml_kem_types_MlKemCiphertext____1088size_t +libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uint8_t value[1088U]) { uint8_t uu____0[1088U]; memcpy(uu____0, value, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t lit; + libcrux_ml_kem_mlkem768_MlKem768Ciphertext lit; memcpy(lit.value, uu____0, (size_t)1088U * sizeof(uint8_t)); return lit; } @@ -192,7 +190,7 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *self) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, Eurydice_slice); } diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 07f553e38..6d6e8dcac 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -51,18 +51,18 @@ typedef struct libcrux_ml_kem_types_MlKemPrivateKey____3168size_t_s { uint8_t value[3168U]; } libcrux_ml_kem_types_MlKemPrivateKey____3168size_t; -typedef struct libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t_s { +typedef struct libcrux_ml_kem_mlkem1024_MlKem1024KeyPair_s { libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk; libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t; +} libcrux_ml_kem_mlkem1024_MlKem1024KeyPair; -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1568size_t_s { +typedef struct libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext_s { uint8_t value[1568U]; -} libcrux_ml_kem_types_MlKemCiphertext____1568size_t; +} libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext; typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____1568size_t fst; + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext fst; uint8_t snd[32U]; } K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_; @@ -80,18 +80,18 @@ typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { uint8_t value[2400U]; } libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; -typedef struct libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t_s { +typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk; libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk; -} libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t; +} libcrux_ml_kem_mlkem768_MlKem768KeyPair; -typedef struct libcrux_ml_kem_types_MlKemCiphertext____1088size_t_s { +typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { uint8_t value[1088U]; -} libcrux_ml_kem_types_MlKemCiphertext____1088size_t; +} libcrux_ml_kem_mlkem768_MlKem768Ciphertext; typedef struct K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s { - libcrux_ml_kem_types_MlKemCiphertext____1088size_t fst; + libcrux_ml_kem_mlkem768_MlKem768Ciphertext fst; uint8_t snd[32U]; } K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c index e2cad594d..75a91f769 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.c @@ -11,7 +11,7 @@ void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t uu____0[32U]; if (libcrux_platform_platform_simd256_support()) { @@ -31,7 +31,7 @@ void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536si void libcrux_ml_kem_mlkem1024_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( @@ -82,10 +82,10 @@ libcrux_ml_kem_mlkem1024_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t uu____0; + libcrux_ml_kem_mlkem1024_MlKem1024KeyPair uu____0; if (libcrux_platform_platform_simd256_support()) { uint8_t uu____1[64U]; memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); @@ -108,7 +108,7 @@ libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168si return uu____0; } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 31fd6b6b2..622d719a3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -67,6 +67,12 @@ extern "C" { (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ LIBCRUX_ML_KEM_MLKEM1024_CPA_PKE_CIPHERTEXT_SIZE_1024) +typedef libcrux_ml_kem_types_MlKemPrivateKey____3168size_t + libcrux_ml_kem_mlkem1024_MlKem1024PrivateKey; + +typedef libcrux_ml_kem_types_MlKemPublicKey____1568size_t + libcrux_ml_kem_mlkem1024_MlKem1024PublicKey; + #define LIBCRUX_ML_KEM_MLKEM1024_RANKED_BYTES_PER_RING_ELEMENT_1024 \ (LIBCRUX_ML_KEM_MLKEM1024_RANK_1024 * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) @@ -79,13 +85,11 @@ extern "C" { void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); void libcrux_ml_kem_mlkem1024_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( @@ -97,11 +101,11 @@ libcrux_ml_kem_mlkem1024_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index 894a6e5aa..78a35d9d3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -9,7 +9,7 @@ void libcrux_ml_kem_mlkem1024_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( @@ -28,7 +28,7 @@ libcrux_ml_kem_mlkem1024_avx2_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index 76826f781..22172d3c4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -18,15 +18,14 @@ extern "C" { void libcrux_ml_kem_mlkem1024_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_avx2_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index 89def0e0e..f977e74be 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -9,7 +9,7 @@ void libcrux_ml_kem_mlkem1024_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( @@ -28,7 +28,7 @@ libcrux_ml_kem_mlkem1024_portable_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 889adcd1b..5f38c1f52 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -18,15 +18,14 @@ extern "C" { void libcrux_ml_kem_mlkem1024_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem1024_portable_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_mlkem1024_portable_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 9e99eb873..e3a0d8f74 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -65,6 +65,18 @@ extern "C" { (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ LIBCRUX_ML_KEM_MLKEM512_CPA_PKE_CIPHERTEXT_SIZE_512) +typedef libcrux_ml_kem_types_MlKemCiphertext____768size_t + libcrux_ml_kem_mlkem512_MlKem512Ciphertext; + +typedef libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t + libcrux_ml_kem_mlkem512_MlKem512KeyPair; + +typedef libcrux_ml_kem_types_MlKemPrivateKey____1632size_t + libcrux_ml_kem_mlkem512_MlKem512PrivateKey; + +typedef libcrux_ml_kem_types_MlKemPublicKey____800size_t + libcrux_ml_kem_mlkem512_MlKem512PublicKey; + #define LIBCRUX_ML_KEM_MLKEM512_RANKED_BYTES_PER_RING_ELEMENT_512 \ (LIBCRUX_ML_KEM_MLKEM512_RANK_512 * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index 3ecf05aa4..ffdf90bad 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -97,7 +97,7 @@ bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_15 public_key); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -119,7 +119,7 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568 void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( @@ -133,7 +133,7 @@ bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_11 public_key); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -155,8 +155,7 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184 void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index ef22b8ed1..034e05ffa 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -52,7 +52,7 @@ libcrux_ml_kem_mlkem512_avx2_validate_public_key( bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -63,13 +63,12 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568 void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -80,8 +79,7 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184 void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index f19b1cfda..437161657 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -97,7 +97,7 @@ bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_ public_key); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -119,7 +119,7 @@ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_ void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( @@ -133,7 +133,7 @@ bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_ public_key); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; @@ -155,8 +155,7 @@ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_ void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 60635a57b..ec949dc4d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -52,7 +52,7 @@ libcrux_ml_kem_mlkem512_portable_validate_public_key( bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -63,13 +63,12 @@ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_ void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); bool libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]); @@ -80,8 +79,7 @@ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_ void libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c index 5e87a108d..fbcc3e1be 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768.c @@ -11,8 +11,7 @@ void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t uu____0[32U]; if (libcrux_platform_platform_simd256_support()) { libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( @@ -31,8 +30,7 @@ void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152si void libcrux_ml_kem_mlkem768_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); @@ -82,10 +80,10 @@ libcrux_ml_kem_mlkem768_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t uu____0; + libcrux_ml_kem_mlkem768_MlKem768KeyPair uu____0; if (libcrux_platform_platform_simd256_support()) { uint8_t uu____1[64U]; memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); @@ -108,7 +106,7 @@ libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400si return uu____0; } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 7916e6736..566ce5499 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -65,6 +65,12 @@ extern "C" { (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) +typedef libcrux_ml_kem_types_MlKemPrivateKey____2400size_t + libcrux_ml_kem_mlkem768_MlKem768PrivateKey; + +typedef libcrux_ml_kem_types_MlKemPublicKey____1184size_t + libcrux_ml_kem_mlkem768_MlKem768PublicKey; + #define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) @@ -77,13 +83,11 @@ extern "C" { void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); void libcrux_ml_kem_mlkem768_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( @@ -95,11 +99,11 @@ libcrux_ml_kem_mlkem768_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index cccf06957..ba858e6f0 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -9,8 +9,7 @@ void libcrux_ml_kem_mlkem768_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); @@ -28,7 +27,7 @@ libcrux_ml_kem_mlkem768_avx2_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index e15872cb4..2354c986e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -18,15 +18,14 @@ extern "C" { void libcrux_ml_kem_mlkem768_avx2_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_avx2_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 0ef5f5d17..76de52009 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -9,8 +9,7 @@ void libcrux_ml_kem_mlkem768_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); @@ -28,7 +27,7 @@ libcrux_ml_kem_mlkem768_portable_encapsulate( uu____0, uu____1); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 78ac0fdb0..2e8dd612b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -18,15 +18,14 @@ extern "C" { void libcrux_ml_kem_mlkem768_portable_decapsulate( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ libcrux_ml_kem_mlkem768_portable_encapsulate( libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]); -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]); core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index 21208bcad..1f4239112 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -2811,7 +2811,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( @@ -3802,7 +3802,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib shared_secret, uint8_t, void *); uint8_t uu____4[1568U]; memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uu____4); uint8_t uu____6[32U]; @@ -4420,7 +4420,7 @@ static inline void PRF___4size_t_32size_t(Eurydice_slice input, void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( @@ -5310,7 +5310,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( @@ -5821,7 +5821,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib shared_secret, uint8_t, void *); uint8_t uu____4[1088U]; memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uu____4); uint8_t uu____6[32U]; @@ -6024,8 +6024,7 @@ static inline void PRF___3size_t_32size_t(Eurydice_slice input, void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 17854d7fc..c995aa8b6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -3378,7 +3378,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____3168size_t__1568size_t +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( @@ -4200,7 +4200,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto shared_secret, uint8_t, void *); uint8_t uu____4[1568U]; memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1568size_t uu____5 = + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uu____4); uint8_t uu____6[32U]; @@ -4661,7 +4661,7 @@ static inline void PRF___4size_t_32size_t(Eurydice_slice input, void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1568size_t *ciphertext, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( @@ -5470,7 +5470,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } -libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t +libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( @@ -5989,7 +5989,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto shared_secret, uint8_t, void *); uint8_t uu____4[1088U]; memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____1088size_t uu____5 = + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uu____4); uint8_t uu____6[32U]; @@ -6193,8 +6193,7 @@ static inline void PRF___3size_t_32size_t(Eurydice_slice input, void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____1088size_t *ciphertext, - uint8_t ret[32U]) { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, From 546349a2a5893d79d1b474a3e94217b2a342f19b Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 6 Jun 2024 11:31:39 +0200 Subject: [PATCH 17/84] fix crane warning --- flake.lock | 27 ++++----------------------- flake.nix | 1 + 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/flake.lock b/flake.lock index c06ddd613..0221dd945 100644 --- a/flake.lock +++ b/flake.lock @@ -2,7 +2,9 @@ "nodes": { "charon": { "inputs": { - "crane": "crane", + "crane": [ + "crane" + ], "flake-compat": "flake-compat", "flake-utils": "flake-utils", "nixpkgs": [ @@ -26,27 +28,6 @@ } }, "crane": { - "inputs": { - "nixpkgs": [ - "charon", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1717535930, - "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", - "owner": "ipetkov", - "repo": "crane", - "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "crane_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -314,7 +295,7 @@ "root": { "inputs": { "charon": "charon", - "crane": "crane_2", + "crane": "crane", "eurydice": "eurydice", "flake-utils": "flake-utils_5", "fstar": [ diff --git a/flake.nix b/flake.nix index 7af9a4342..7a9aa60aa 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,7 @@ charon = { url = "github:aeneasverif/charon"; inputs.nixpkgs.follows = "eurydice/nixpkgs"; + inputs.crane.follows = "crane"; }; eurydice = { url = "github:aeneasverif/eurydice"; From 4ac22dae1134fec780608cf3ef94b35d1c74339b Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 6 Jun 2024 11:33:20 +0200 Subject: [PATCH 18/84] Revert "fix crane warning" This reverts commit 546349a2a5893d79d1b474a3e94217b2a342f19b. --- flake.lock | 27 +++++++++++++++++++++++---- flake.nix | 1 - 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/flake.lock b/flake.lock index 0221dd945..c06ddd613 100644 --- a/flake.lock +++ b/flake.lock @@ -2,9 +2,7 @@ "nodes": { "charon": { "inputs": { - "crane": [ - "crane" - ], + "crane": "crane", "flake-compat": "flake-compat", "flake-utils": "flake-utils", "nixpkgs": [ @@ -28,6 +26,27 @@ } }, "crane": { + "inputs": { + "nixpkgs": [ + "charon", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717535930, + "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -295,7 +314,7 @@ "root": { "inputs": { "charon": "charon", - "crane": "crane", + "crane": "crane_2", "eurydice": "eurydice", "flake-utils": "flake-utils_5", "fstar": [ diff --git a/flake.nix b/flake.nix index 7a9aa60aa..7af9a4342 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,6 @@ charon = { url = "github:aeneasverif/charon"; inputs.nixpkgs.follows = "eurydice/nixpkgs"; - inputs.crane.follows = "crane"; }; eurydice = { url = "github:aeneasverif/eurydice"; From 1b3de363df8106e1ceef888b189729c19c070d7e Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 6 Jun 2024 12:01:39 +0200 Subject: [PATCH 19/84] fix linking --- flake.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 7af9a4342..117b6c0a1 100644 --- a/flake.nix +++ b/flake.nix @@ -36,8 +36,13 @@ src = ./.; cargoArtifacts = craneLib.buildDepsOnly { inherit src; }; ml-kem = craneLib.buildPackage { - inherit src cargoArtifacts; name = "ml-kem"; + inherit src cargoArtifacts; + postPatch = '' + substituteInPlace libcrux-ml-kem/c/CMakeLists.txt \ + --replace " -flto" " # -flto" \ + --replace "add_link_options(-flto)" "#add_link_options(-flto)" + ''; nativeBuildInputs = [ pkgs.clang pkgs.cmake From 256060124a95a1af2660ab58d784aa4027c1fc64 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 6 Jun 2024 12:04:57 +0200 Subject: [PATCH 20/84] nix: run tests --- flake.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 117b6c0a1..689231107 100644 --- a/flake.nix +++ b/flake.nix @@ -53,8 +53,6 @@ buildPhase = '' cd libcrux-ml-kem bash c.sh - ''; - checkPhase = '' cd c cmake \ -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ @@ -62,6 +60,10 @@ -G "Ninja Multi-Config" -B build cmake --build build --config Release ''; + checkPhase = '' + build/Release/ml_kem_test + build/Release/ml_kem_bench + ''; installPhase = "cp -r . $out"; CHARON_HOME = inputs.charon.packages.${system}.default; EURYDICE_HOME = pkgs.runCommand "eurydice-home" { } '' From 7f1003053fd0d4fa1231368f6355105f871a3b44 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Thu, 6 Jun 2024 12:06:41 +0200 Subject: [PATCH 21/84] attempt at separation extracing everywhere doesn't work because of types are extracted to C and fail there. We have a portable and avx2 version now in C. Portable fails all tests --- libcrux-intrinsics/src/arm64_extract.rs | 348 ++++ libcrux-intrinsics/src/avx2.rs | 137 +- libcrux-intrinsics/src/avx2_extract.rs | 334 ++++ libcrux-intrinsics/src/lib.rs | 12 + libcrux-ml-kem/c/CMakeLists.txt | 60 +- libcrux-ml-kem/c/benches/mlkem768.cc | 17 +- libcrux-ml-kem/c/benches/mlkem768_encaps.cc | 7 +- libcrux-ml-kem/c/benches/mlkem768_keygen.cc | 5 +- libcrux-ml-kem/c/internal/libcrux_core.h | 6 +- .../c/internal/libcrux_mlkem_avx2.h | 38 +- .../c/internal/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 6 +- .../c/internal/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_core.c | 6 +- libcrux-ml-kem/c/libcrux_core.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024.c | 154 -- libcrux-ml-kem/c/libcrux_mlkem1024.h | 41 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512.c | 153 -- libcrux-ml-kem/c/libcrux_mlkem512.h | 43 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 64 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 38 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768.c | 152 -- libcrux-ml-kem/c/libcrux_mlkem768.h | 41 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 1766 ++++++++--------- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/libcrux_platform.h | 6 +- libcrux-ml-kem/c/libcrux_sha3.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_neon.c | 6 +- libcrux-ml-kem/c/libcrux_sha3_neon.h | 6 +- libcrux-ml-kem/c/tests/mlkem768.cc | 103 +- libcrux-ml-kem/c/tests/sha3.cc | 25 - libcrux-ml-kem/src/ind_cca/multiplexing.rs | 163 +- libcrux-ml-kem/src/mlkem1024.rs | 8 +- libcrux-ml-kem/src/mlkem512.rs | 4 + libcrux-ml-kem/src/mlkem768.rs | 4 + libcrux-ml-kem/src/vector.rs | 3 - libcrux-sha3/src/lib.rs | 20 +- libcrux-sha3/src/simd/avx2.rs | 27 +- 53 files changed, 1984 insertions(+), 1939 deletions(-) create mode 100644 libcrux-intrinsics/src/arm64_extract.rs create mode 100644 libcrux-intrinsics/src/avx2_extract.rs delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768.c diff --git a/libcrux-intrinsics/src/arm64_extract.rs b/libcrux-intrinsics/src/arm64_extract.rs new file mode 100644 index 000000000..13bb20d73 --- /dev/null +++ b/libcrux-intrinsics/src/arm64_extract.rs @@ -0,0 +1,348 @@ +//! This file does not contain correct function signatures! +//! Replace with a hand-written file after extraction. + +#![allow(non_camel_case_types, unsafe_code, unused_variables)] + +pub type _int16x8_t = u8; +pub type _uint32x4_t = u8; +pub type _uint64x2_t = u8; + +#[inline(always)] +pub fn _vdupq_n_s16(i: i16) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vdupq_n_u64(i: u64) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vst1q_s16(out: &mut [i16], v: int16x8_t) { + unimplemented!() +} + +#[inline(always)] +pub fn _vld1q_s16(array: &[i16]) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vld1q_bytes_u64(array: &[int16x8_t]) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vld1q_u64(array: &[u64]) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vst1q_u64(out: &mut [u64], v: _uint64x2_t) { + unimplemented!() +} + +#[inline(always)] +pub fn _vst1q_bytes_u64(out: &mut [int16x8_t], v: _uint64x2_t) { + unimplemented!() +} + +#[inline(always)] +pub fn _vaddq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vsubq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vmulq_n_s16(v: int16x8_t, c: i16) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vmulq_n_u16(v: uu8, c: u16) -> uu8 { + unimplemented!() +} + +#[inline(always)] +pub fn _vshrq_n_s16(v: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vshrq_n_u16(v: uu8) -> uu8 { + unimplemented!() +} + +#[inline(always)] +pub fn _vshrq_n_u64(v: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vshlq_n_u64(v: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vshlq_n_s16(v: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vshlq_n_u32(v: _uint32x4_t) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vqdmulhq_n_s16(k: int16x8_t, b: i16) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vqdmulhq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vcgeq_s16(v: int16x8_t, c: int16x8_t) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vandq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vbicq_u64(a: _uint64x2_t, b: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vreinterpretq_s16_u16(m0: uu8) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_u16_s16(m0: int16x8_t) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vmulq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _veorq_s16(mask: int16x8_t, shifted: int16x8_t) -> int16x8_t { + unimplemented!() +} + +#[inline(always)] +pub fn _veorq_u64(mask: _uint64x2_t, shifted: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vdupq_n_u32(value: u32) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vaddq_u32(compressed: _uint32x4_t, half: _uint32x4_t) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s32_u32(compressed: _uint32x4_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vqdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vreinterpretq_u32_s32(a: int32x4_t) -> _uint32x4_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vshrq_n_u32(a: _uint32x4_t) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vandq_u32(a: _uint32x4_t, b: _uint32x4_t) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_u32_s16(a: int16x8_t) -> _uint32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s16_u32(a: _uint32x4_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vtrn1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vtrn2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vmulq_n_u32(a: _uint32x4_t, b: u32) -> _uint32x4_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vtrn1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vtrn2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vtrn1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vtrn1q_u64(a: _uint64x2_t, b: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t { + unimplemented!() +} +#[inline(always)] +pub fn _vtrn2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vtrn2q_u64(a: _uint64x2_t, b: _uint64x2_t) -> _uint64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vmull_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vget_low_s16(a: int16x8_t) -> int16x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vld1q_u8(ptr: &[int16x8_t]) -> uint8x16_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t { + unimplemented!() +} +#[inline(always)] +pub fn _vqtbl1q_u8(t: uint8x16_t, idx: uint8x16_t) -> uint8x16_t { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unimplemented!() +} +#[inline(always)] +pub fn _vshlq_u16(a: uu8, b: int16x8_t) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vaddv_u16(a: uint16x4_t) -> u16 { + unimplemented!() +} +#[inline(always)] +pub fn _vget_low_u16(a: uu8) -> uint16x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vget_high_u16(a: uu8) -> uint16x4_t { + unimplemented!() +} +#[inline(always)] +pub fn _vaddvq_s16(a: int16x8_t) -> i16 { + unimplemented!() +} + +#[inline(always)] +pub fn _vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t { + unimplemented!() +} + +#[inline(always)] +pub fn _vst1q_u8(out: &mut [int16x8_t], v: uint8x16_t) { + unimplemented!() +} +#[inline(always)] +pub fn _vdupq_n_u16(value: u16) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vandq_u16(a: uu8, b: uu8) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vreinterpretq_u16_u8(a: uint8x16_t) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vld1q_u16(ptr: &[u16]) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vcleq_s16(a: int16x8_t, b: int16x8_t) -> uu8 { + unimplemented!() +} +#[inline(always)] +pub fn _vaddvq_u16(a: uu8) -> u16 { + unimplemented!() +} diff --git a/libcrux-intrinsics/src/avx2.rs b/libcrux-intrinsics/src/avx2.rs index 4d2b81e1e..966654c97 100644 --- a/libcrux-intrinsics/src/avx2.rs +++ b/libcrux-intrinsics/src/avx2.rs @@ -6,49 +6,49 @@ pub use core::arch::x86_64::*; pub type Vec256 = __m256i; pub type Vec128 = __m128i; -pub fn mm256_storeu_si256_i16(output: &mut [i16], vector: __m256i) { +pub fn mm256_storeu_si256_i16(output: &mut [i16], vector: Vec256) { debug_assert_eq!(output.len(), 16); unsafe { - _mm256_storeu_si256(output.as_mut_ptr() as *mut __m256i, vector); + _mm256_storeu_si256(output.as_mut_ptr() as *mut Vec256, vector); } } -pub fn mm256_storeu_si256_u8(output: &mut [u8], vector: __m256i) { +pub fn mm256_storeu_si256_u8(output: &mut [u8], vector: Vec256) { debug_assert_eq!(output.len(), 32); unsafe { - _mm256_storeu_si256(output.as_mut_ptr() as *mut __m256i, vector); + _mm256_storeu_si256(output.as_mut_ptr() as *mut Vec256, vector); } } -pub fn mm_storeu_si128(output: &mut [i16], vector: __m128i) { +pub fn mm_storeu_si128(output: &mut [i16], vector: Vec128) { // debug_assert_eq!(output.len(), 8); unsafe { - _mm_storeu_si128(output.as_mut_ptr() as *mut __m128i, vector); + _mm_storeu_si128(output.as_mut_ptr() as *mut Vec128, vector); } } -pub fn mm_storeu_bytes_si128(output: &mut [u8], vector: __m128i) { +pub fn mm_storeu_bytes_si128(output: &mut [u8], vector: Vec128) { debug_assert_eq!(output.len(), 16); unsafe { - _mm_storeu_si128(output.as_mut_ptr() as *mut __m128i, vector); + _mm_storeu_si128(output.as_mut_ptr() as *mut Vec128, vector); } } -pub fn mm_loadu_si128(input: &[u8]) -> __m128i { +pub fn mm_loadu_si128(input: &[u8]) -> Vec128 { debug_assert_eq!(input.len(), 16); - unsafe { _mm_loadu_si128(input.as_ptr() as *const __m128i) } + unsafe { _mm_loadu_si128(input.as_ptr() as *const Vec128) } } -pub fn mm256_loadu_si256_u8(input: &[u8]) -> __m256i { +pub fn mm256_loadu_si256_u8(input: &[u8]) -> Vec256 { debug_assert_eq!(input.len(), 32); - unsafe { _mm256_loadu_si256(input.as_ptr() as *const __m256i) } + unsafe { _mm256_loadu_si256(input.as_ptr() as *const Vec256) } } -pub fn mm256_loadu_si256_i16(input: &[i16]) -> __m256i { +pub fn mm256_loadu_si256_i16(input: &[i16]) -> Vec256 { debug_assert_eq!(input.len(), 16); - unsafe { _mm256_loadu_si256(input.as_ptr() as *const __m256i) } + unsafe { _mm256_loadu_si256(input.as_ptr() as *const Vec256) } } -pub fn mm256_setzero_si256() -> __m256i { +pub fn mm256_setzero_si256() -> Vec256 { unsafe { _mm256_setzero_si256() } } @@ -69,7 +69,7 @@ pub fn mm_set_epi8( byte2: u8, byte1: u8, byte0: u8, -) -> __m128i { +) -> Vec128 { unsafe { _mm_set_epi8( byte15 as i8, @@ -125,7 +125,7 @@ pub fn mm256_set_epi8( byte2: i8, byte1: i8, byte0: i8, -) -> __m256i { +) -> Vec256 { unsafe { _mm256_set_epi8( byte31, byte30, byte29, byte28, byte27, byte26, byte25, byte24, byte23, byte22, byte21, @@ -135,7 +135,7 @@ pub fn mm256_set_epi8( } } -pub fn mm256_set1_epi16(constant: i16) -> __m256i { +pub fn mm256_set1_epi16(constant: i16) -> Vec256 { unsafe { _mm256_set1_epi16(constant) } } pub fn mm256_set_epi16( @@ -155,7 +155,7 @@ pub fn mm256_set_epi16( input2: i16, input1: i16, input0: i16, -) -> __m256i { +) -> Vec256 { unsafe { _mm256_set_epi16( input15, input14, input13, input12, input11, input10, input9, input8, input7, input6, @@ -164,11 +164,11 @@ pub fn mm256_set_epi16( } } -pub fn mm_set1_epi16(constant: i16) -> __m128i { +pub fn mm_set1_epi16(constant: i16) -> Vec128 { unsafe { _mm_set1_epi16(constant) } } -pub fn mm256_set1_epi32(constant: i32) -> __m256i { +pub fn mm256_set1_epi32(constant: i32) -> Vec256 { unsafe { _mm256_set1_epi32(constant) } } pub fn mm256_set_epi32( @@ -180,7 +180,7 @@ pub fn mm256_set_epi32( input2: i32, input1: i32, input0: i32, -) -> __m256i { +) -> Vec256 { unsafe { _mm256_set_epi32( input7, input6, input5, input4, input3, input2, input1, input0, @@ -188,192 +188,189 @@ pub fn mm256_set_epi32( } } -pub fn mm_add_epi16(lhs: __m128i, rhs: __m128i) -> __m128i { +pub fn mm_add_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unsafe { _mm_add_epi16(lhs, rhs) } } -pub fn mm256_add_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_add_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_add_epi16(lhs, rhs) } } -pub fn mm256_madd_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_madd_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_madd_epi16(lhs, rhs) } } -pub fn mm256_add_epi32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_add_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_add_epi32(lhs, rhs) } } -pub fn mm256_sub_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_sub_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_sub_epi16(lhs, rhs) } } -pub fn mm_sub_epi16(lhs: __m128i, rhs: __m128i) -> __m128i { +pub fn mm_sub_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unsafe { _mm_sub_epi16(lhs, rhs) } } -pub fn mm256_mullo_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_mullo_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_mullo_epi16(lhs, rhs) } } -pub fn mm_mullo_epi16(lhs: __m128i, rhs: __m128i) -> __m128i { +pub fn mm_mullo_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unsafe { _mm_mullo_epi16(lhs, rhs) } } -pub fn mm256_cmpgt_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_cmpgt_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_cmpgt_epi16(lhs, rhs) } } -pub fn mm_mulhi_epi16(lhs: __m128i, rhs: __m128i) -> __m128i { +pub fn mm_mulhi_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unsafe { _mm_mulhi_epi16(lhs, rhs) } } -pub fn mm256_mullo_epi32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_mullo_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_mullo_epi32(lhs, rhs) } } -pub fn mm256_mulhi_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_mulhi_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_mulhi_epi16(lhs, rhs) } } -pub fn mm256_mul_epu32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_mul_epu32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_mul_epu32(lhs, rhs) } } -pub fn mm256_and_si256(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_and_si256(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_and_si256(lhs, rhs) } } -pub fn mm256_xor_si256(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_xor_si256(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_xor_si256(lhs, rhs) } } -pub fn mm256_srai_epi16(vector: __m256i) -> __m256i { +pub fn mm256_srai_epi16(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); unsafe { _mm256_srai_epi16(vector, SHIFT_BY) } } -pub fn mm256_srai_epi32(vector: __m256i) -> __m256i { +pub fn mm256_srai_epi32(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); unsafe { _mm256_srai_epi32(vector, SHIFT_BY) } } -pub fn mm256_srli_epi16(vector: __m256i) -> __m256i { +pub fn mm256_srli_epi16(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); unsafe { _mm256_srli_epi16(vector, SHIFT_BY) } } -pub fn mm256_srli_epi32(vector: __m256i) -> __m256i { +pub fn mm256_srli_epi32(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); unsafe { _mm256_srli_epi32(vector, SHIFT_BY) } } -pub fn mm256_srli_epi64(vector: __m256i) -> __m256i { +pub fn mm256_srli_epi64(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 64); unsafe { _mm256_srli_epi64(vector, SHIFT_BY) } } -pub fn mm256_slli_epi16(vector: __m256i) -> __m256i { +pub fn mm256_slli_epi16(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); unsafe { _mm256_slli_epi16(vector, SHIFT_BY) } } -pub fn mm256_slli_epi32(vector: __m256i) -> __m256i { +pub fn mm256_slli_epi32(vector: Vec256) -> Vec256 { debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); unsafe { _mm256_slli_epi32(vector, SHIFT_BY) } } -pub fn mm_shuffle_epi8(vector: __m128i, control: __m128i) -> __m128i { +pub fn mm_shuffle_epi8(vector: Vec128, control: Vec128) -> Vec128 { unsafe { _mm_shuffle_epi8(vector, control) } } -pub fn mm256_shuffle_epi8(vector: __m256i, control: __m256i) -> __m256i { +pub fn mm256_shuffle_epi8(vector: Vec256, control: Vec256) -> Vec256 { unsafe { _mm256_shuffle_epi8(vector, control) } } -pub fn mm256_shuffle_epi32(vector: __m256i) -> __m256i { +pub fn mm256_shuffle_epi32(vector: Vec256) -> Vec256 { debug_assert!(CONTROL >= 0 && CONTROL < 256); unsafe { _mm256_shuffle_epi32(vector, CONTROL) } } -pub fn mm256_permute4x64_epi64(vector: __m256i) -> __m256i { +pub fn mm256_permute4x64_epi64(vector: Vec256) -> Vec256 { debug_assert!(CONTROL >= 0 && CONTROL < 256); unsafe { _mm256_permute4x64_epi64(vector, CONTROL) } } -pub fn mm256_unpackhi_epi64(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_unpackhi_epi64(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_unpackhi_epi64(lhs, rhs) } } -pub fn mm256_unpacklo_epi32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_unpacklo_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_unpacklo_epi32(lhs, rhs) } } -pub fn mm256_unpackhi_epi32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_unpackhi_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_unpackhi_epi32(lhs, rhs) } } -pub fn mm256_castsi256_si128(vector: __m256i) -> __m128i { +pub fn mm256_castsi256_si128(vector: Vec256) -> Vec128 { unsafe { _mm256_castsi256_si128(vector) } } -pub fn mm256_castsi128_si256(vector: __m128i) -> __m256i { +pub fn mm256_castsi128_si256(vector: Vec128) -> Vec256 { unsafe { _mm256_castsi128_si256(vector) } } -pub fn mm256_cvtepi16_epi32(vector: __m128i) -> __m256i { +pub fn mm256_cvtepi16_epi32(vector: Vec128) -> Vec256 { unsafe { _mm256_cvtepi16_epi32(vector) } } -pub fn mm_packs_epi16(lhs: __m128i, rhs: __m128i) -> __m128i { +pub fn mm_packs_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unsafe { _mm_packs_epi16(lhs, rhs) } } -pub fn mm256_packs_epi32(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_packs_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { unsafe { _mm256_packs_epi32(lhs, rhs) } } -pub fn mm256_extracti128_si256(vector: __m256i) -> __m128i { +pub fn mm256_extracti128_si256(vector: Vec256) -> Vec128 { debug_assert!(CONTROL == 0 || CONTROL == 1); unsafe { _mm256_extracti128_si256(vector, CONTROL) } } -pub fn mm256_inserti128_si256( - vector: __m256i, - vector_i128: __m128i, -) -> __m256i { +pub fn mm256_inserti128_si256(vector: Vec256, vector_i128: Vec128) -> Vec256 { debug_assert!(CONTROL == 0 || CONTROL == 1); unsafe { _mm256_inserti128_si256(vector, vector_i128, CONTROL) } } -pub fn mm256_blend_epi16(lhs: __m256i, rhs: __m256i) -> __m256i { +pub fn mm256_blend_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { debug_assert!(CONTROL >= 0 && CONTROL < 256); unsafe { _mm256_blend_epi16(lhs, rhs, CONTROL) } } -pub fn mm_movemask_epi8(vector: __m128i) -> i32 { +pub fn mm_movemask_epi8(vector: Vec128) -> i32 { unsafe { _mm_movemask_epi8(vector) } } -pub fn mm256_permutevar8x32_epi32(vector: __m256i, control: __m256i) -> __m256i { +pub fn mm256_permutevar8x32_epi32(vector: Vec256, control: Vec256) -> Vec256 { unsafe { _mm256_permutevar8x32_epi32(vector, control) } } -pub fn mm256_sllv_epi32(vector: __m256i, counts: __m256i) -> __m256i { +pub fn mm256_sllv_epi32(vector: Vec256, counts: Vec256) -> Vec256 { unsafe { _mm256_sllv_epi32(vector, counts) } } #[inline(always)] -pub fn mm256_slli_epi64(x: __m256i) -> __m256i { +pub fn mm256_slli_epi64(x: Vec256) -> Vec256 { unsafe { _mm256_slli_epi64::(x) } } #[inline(always)] -pub fn mm256_andnot_si256(a: __m256i, b: __m256i) -> __m256i { +pub fn mm256_andnot_si256(a: Vec256, b: Vec256) -> Vec256 { unsafe { _mm256_andnot_si256(a, b) } } #[inline(always)] -pub fn mm256_set1_epi64x(a: i64) -> __m256i { +pub fn mm256_set1_epi64x(a: i64) -> Vec256 { unsafe { _mm256_set1_epi64x(a) } } #[inline(always)] -pub fn mm256_unpacklo_epi64(a: __m256i, b: __m256i) -> __m256i { +pub fn mm256_unpacklo_epi64(a: Vec256, b: Vec256) -> Vec256 { unsafe { _mm256_unpacklo_epi64(a, b) } } #[inline(always)] -pub fn mm256_permute2x128_si256(a: __m256i, b: __m256i) -> __m256i { +pub fn mm256_permute2x128_si256(a: Vec256, b: Vec256) -> Vec256 { unsafe { _mm256_permute2x128_si256::(a, b) } } diff --git a/libcrux-intrinsics/src/avx2_extract.rs b/libcrux-intrinsics/src/avx2_extract.rs new file mode 100644 index 000000000..f1d42e188 --- /dev/null +++ b/libcrux-intrinsics/src/avx2_extract.rs @@ -0,0 +1,334 @@ +//! This file does not contain correct function signatures! +//! Replace with a hand-written file after extraction. + +#![allow(unused_variables, non_camel_case_types)] + +pub type Vec256 = u8; +pub type Vec128 = u8; + +pub fn mm256_storeu_si256_i16(output: &mut [i16], vector: Vec256) { + debug_assert_eq!(output.len(), 16); + unimplemented!() +} + +pub fn mm256_storeu_si256_u8(output: &mut [u8], vector: Vec256) { + debug_assert_eq!(output.len(), 32); + unimplemented!() +} +pub fn mm_storeu_si128(output: &mut [i16], vector: Vec128) { + // debug_assert_eq!(output.len(), 8); + unimplemented!() +} + +pub fn mm_storeu_bytes_si128(output: &mut [u8], vector: Vec128) { + debug_assert_eq!(output.len(), 16); + unimplemented!() +} + +pub fn mm_loadu_si128(input: &[u8]) -> Vec128 { + debug_assert_eq!(input.len(), 16); + unimplemented!() +} + +pub fn mm256_loadu_si256_u8(input: &[u8]) -> Vec256 { + debug_assert_eq!(input.len(), 32); + unimplemented!() +} + +pub fn mm256_loadu_si256_i16(input: &[i16]) -> Vec256 { + debug_assert_eq!(input.len(), 16); + unimplemented!() +} + +pub fn mm256_setzero_si256() -> Vec256 { + unimplemented!() +} + +pub fn mm_set_epi8( + byte15: u8, + byte14: u8, + byte13: u8, + byte12: u8, + byte11: u8, + byte10: u8, + byte9: u8, + byte8: u8, + byte7: u8, + byte6: u8, + byte5: u8, + byte4: u8, + byte3: u8, + byte2: u8, + byte1: u8, + byte0: u8, +) -> Vec128 { + unimplemented!() +} + +pub fn mm256_set_epi8( + byte31: i8, + byte30: i8, + byte29: i8, + byte28: i8, + byte27: i8, + byte26: i8, + byte25: i8, + byte24: i8, + byte23: i8, + byte22: i8, + byte21: i8, + byte20: i8, + byte19: i8, + byte18: i8, + byte17: i8, + byte16: i8, + byte15: i8, + byte14: i8, + byte13: i8, + byte12: i8, + byte11: i8, + byte10: i8, + byte9: i8, + byte8: i8, + byte7: i8, + byte6: i8, + byte5: i8, + byte4: i8, + byte3: i8, + byte2: i8, + byte1: i8, + byte0: i8, +) -> Vec256 { + unimplemented!() +} + +pub fn mm256_set1_epi16(constant: i16) -> Vec256 { + unimplemented!() +} +pub fn mm256_set_epi16( + input15: i16, + input14: i16, + input13: i16, + input12: i16, + input11: i16, + input10: i16, + input9: i16, + input8: i16, + input7: i16, + input6: i16, + input5: i16, + input4: i16, + input3: i16, + input2: i16, + input1: i16, + input0: i16, +) -> Vec256 { + unimplemented!() +} + +pub fn mm_set1_epi16(constant: i16) -> Vec128 { + unimplemented!() +} + +pub fn mm256_set1_epi32(constant: i32) -> Vec256 { + unimplemented!() +} +pub fn mm256_set_epi32( + input7: i32, + input6: i32, + input5: i32, + input4: i32, + input3: i32, + input2: i32, + input1: i32, + input0: i32, +) -> Vec256 { + unimplemented!() +} + +pub fn mm_add_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { + unimplemented!() +} +pub fn mm256_add_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} +pub fn mm256_madd_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} +pub fn mm256_add_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_sub_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} +pub fn mm_sub_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { + unimplemented!() +} + +pub fn mm256_mullo_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm_mullo_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { + unimplemented!() +} + +pub fn mm256_cmpgt_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm_mulhi_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { + unimplemented!() +} + +pub fn mm256_mullo_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_mulhi_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_mul_epu32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_and_si256(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_xor_si256(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_srai_epi16(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); + unimplemented!() +} +pub fn mm256_srai_epi32(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); + unimplemented!() +} + +pub fn mm256_srli_epi16(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); + unimplemented!() +} +pub fn mm256_srli_epi32(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); + unimplemented!() +} + +pub fn mm256_srli_epi64(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 64); + unimplemented!() +} + +pub fn mm256_slli_epi16(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 16); + unimplemented!() +} + +pub fn mm256_slli_epi32(vector: Vec256) -> Vec256 { + debug_assert!(SHIFT_BY >= 0 && SHIFT_BY < 32); + unimplemented!() +} + +pub fn mm_shuffle_epi8(vector: Vec128, control: Vec128) -> Vec128 { + unimplemented!() +} +pub fn mm256_shuffle_epi8(vector: Vec256, control: Vec256) -> Vec256 { + unimplemented!() +} +pub fn mm256_shuffle_epi32(vector: Vec256) -> Vec256 { + debug_assert!(CONTROL >= 0 && CONTROL < 256); + unimplemented!() +} + +pub fn mm256_permute4x64_epi64(vector: Vec256) -> Vec256 { + debug_assert!(CONTROL >= 0 && CONTROL < 256); + unimplemented!() +} + +pub fn mm256_unpackhi_epi64(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_unpacklo_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_unpackhi_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_castsi256_si128(vector: Vec256) -> Vec128 { + unimplemented!() +} +pub fn mm256_castsi128_si256(vector: Vec128) -> Vec256 { + unimplemented!() +} + +pub fn mm256_cvtepi16_epi32(vector: Vec128) -> Vec256 { + unimplemented!() +} + +pub fn mm_packs_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { + unimplemented!() +} +pub fn mm256_packs_epi32(lhs: Vec256, rhs: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_extracti128_si256(vector: Vec256) -> Vec128 { + debug_assert!(CONTROL == 0 || CONTROL == 1); + unimplemented!() +} + +pub fn mm256_inserti128_si256(vector: Vec256, vector_i128: Vec128) -> Vec256 { + debug_assert!(CONTROL == 0 || CONTROL == 1); + unimplemented!() +} + +pub fn mm256_blend_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { + debug_assert!(CONTROL >= 0 && CONTROL < 256); + unimplemented!() +} + +pub fn mm_movemask_epi8(vector: Vec128) -> i32 { + unimplemented!() +} + +pub fn mm256_permutevar8x32_epi32(vector: Vec256, control: Vec256) -> Vec256 { + unimplemented!() +} + +pub fn mm256_sllv_epi32(vector: Vec256, counts: Vec256) -> Vec256 { + unimplemented!() +} + +#[inline(always)] +pub fn mm256_slli_epi64(x: Vec256) -> Vec256 { + unimplemented!() +} + +#[inline(always)] +pub fn mm256_andnot_si256(a: Vec256, b: Vec256) -> Vec256 { + unimplemented!() +} + +#[inline(always)] +pub fn mm256_set1_epi64x(a: i64) -> Vec256 { + unimplemented!() +} + +#[inline(always)] +pub fn mm256_unpacklo_epi64(a: Vec256, b: Vec256) -> Vec256 { + unimplemented!() +} + +#[inline(always)] +pub fn mm256_permute2x128_si256(a: Vec256, b: Vec256) -> Vec256 { + unimplemented!() +} diff --git a/libcrux-intrinsics/src/lib.rs b/libcrux-intrinsics/src/lib.rs index 984c70fa3..f87d4fa6c 100644 --- a/libcrux-intrinsics/src/lib.rs +++ b/libcrux-intrinsics/src/lib.rs @@ -1,4 +1,16 @@ +// #[cfg(all(feature = "simd128", not(eurydice), not(hax)))] #[cfg(feature = "simd128")] pub mod arm64; +// #[cfg(all(feature = "simd256", not(eurydice), not(hax)))] #[cfg(feature = "simd256")] pub mod avx2; + +// // When extracting C or F* we only want dummy files here. +// #[cfg(all(feature = "simd128", any(eurydice, hax)))] +// pub mod arm64_extract; +// #[cfg(all(feature = "simd128", any(eurydice, hax)))] +// pub use arm64_extrat as arm64; +// #[cfg(all(feature = "simd256", any(eurydice, hax)))] +// pub mod avx2_extract; +// #[cfg(all(feature = "simd256", any(eurydice, hax)))] +// pub use avx2_extract as avx2; diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index ef65b149d..6d941994e 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -22,7 +22,6 @@ add_compile_options( $<$:-Og> $<$:-g> $<$:-O3> - -flto ) add_link_options(-flto) set(CMAKE_COLOR_DIAGNOSTICS "ON") @@ -60,29 +59,36 @@ file(GLOB SOURCES_vec256 if(${CMAKE_SYSTEM_NAME} MATCHES Linux) add_compile_options( -fPIC + -flto ) endif(${CMAKE_SYSTEM_NAME} MATCHES Linux) add_library(ml_kem SHARED ${SOURCES}) add_library(ml_kem_static STATIC ${SOURCES}) -# if(LIBCRUX_VEC256) -add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) -target_sources(ml_kem_static PRIVATE $) -target_sources(ml_kem PRIVATE $) -target_compile_options(ml_kem_vec256 PRIVATE - -mavx - -mavx2 -) -# endif() +# This is only for local testing and we assume avx2 on x64. +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") + message(STATUS "Detected an x64 architecture") + add_compile_definitions(LIBCRUX_X64) + + add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) + target_sources(ml_kem_static PRIVATE $) + target_sources(ml_kem PRIVATE $) + target_compile_options(ml_kem_vec256 PRIVATE + -mavx + -mavx2 + ) +endif() -# if(LIBCRUX_VEC128) -# add_library(ml_kem_vec128 OBJECT ${SOURCES_vec128}) -# target_sources(ml_kem_static PRIVATE $) -# target_sources(ml_kem PRIVATE $) -# target_compile_options(ml_kem_vec128 PRIVATE -# ) -# endif() +# This is only for local testing and we assume neon on arm64. +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8") + message(STATUS "Detected an arm64 architecture") + add_compile_definitions(LIBCRUX_AARCH64) + + add_library(ml_kem_vec128 OBJECT ${SOURCES_vec128}) + target_sources(ml_kem_static PRIVATE $) + target_sources(ml_kem PRIVATE $) +endif() # --- Tests @@ -140,10 +146,7 @@ target_link_libraries(ml_kem_bench PRIVATE benchmark::benchmark ) target_compile_definitions(ml_kem_bench PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_bench PRIVATE - -mavx - -mavx2 -) +target_compile_options(ml_kem_bench PRIVATE) add_executable(ml_kem_keygen ${PROJECT_SOURCE_DIR}/benches/mlkem768_keygen.cc @@ -153,10 +156,7 @@ target_link_libraries(ml_kem_keygen PRIVATE benchmark::benchmark ) target_compile_definitions(ml_kem_keygen PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_keygen PRIVATE - -mavx - -mavx2 -) +target_compile_options(ml_kem_keygen PRIVATE) add_executable(ml_kem_encaps ${PROJECT_SOURCE_DIR}/benches/mlkem768_encaps.cc @@ -166,10 +166,7 @@ target_link_libraries(ml_kem_encaps PRIVATE benchmark::benchmark ) target_compile_definitions(ml_kem_encaps PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_encaps PRIVATE - -mavx - -mavx2 -) +target_compile_options(ml_kem_encaps PRIVATE) add_executable(sha3_bench ${PROJECT_SOURCE_DIR}/benches/sha3.cc @@ -179,7 +176,4 @@ target_link_libraries(sha3_bench PRIVATE benchmark::benchmark ) target_compile_definitions(sha3_bench PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(sha3_bench PRIVATE - -mavx - -mavx2 -) +target_compile_options(sha3_bench PRIVATE) diff --git a/libcrux-ml-kem/c/benches/mlkem768.cc b/libcrux-ml-kem/c/benches/mlkem768.cc index 680f648e7..217ead8bf 100644 --- a/libcrux-ml-kem/c/benches/mlkem768.cc +++ b/libcrux-ml-kem/c/benches/mlkem768.cc @@ -10,6 +10,7 @@ #include "libcrux_sha3.h" #include "libcrux_mlkem768.h" +#include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" void generate_random(uint8_t *output, uint32_t output_len) @@ -23,11 +24,11 @@ kyber768_key_generation(benchmark::State &state) { uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); for (auto _ : state) { - key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); } } @@ -37,13 +38,13 @@ kyber768_encapsulation(benchmark::State &state) uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); generate_random(randomness, 32); - auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); for (auto _ : state) { - ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); } } @@ -53,15 +54,15 @@ kyber768_decapsulation(benchmark::State &state) uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); generate_random(randomness, 32); - auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; for (auto _ : state) { - libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); } } diff --git a/libcrux-ml-kem/c/benches/mlkem768_encaps.cc b/libcrux-ml-kem/c/benches/mlkem768_encaps.cc index 53ae6af1d..4831e07eb 100644 --- a/libcrux-ml-kem/c/benches/mlkem768_encaps.cc +++ b/libcrux-ml-kem/c/benches/mlkem768_encaps.cc @@ -10,6 +10,7 @@ #include "libcrux_sha3.h" #include "libcrux_mlkem768.h" +#include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" void generate_random(uint8_t *output, uint32_t output_len) @@ -23,13 +24,13 @@ int main(int argc, char const *argv[]) uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); generate_random(randomness, 32); - auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); for (size_t i = 0; i < 100000; i++) { - ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); } return 0; diff --git a/libcrux-ml-kem/c/benches/mlkem768_keygen.cc b/libcrux-ml-kem/c/benches/mlkem768_keygen.cc index 37eb855d2..fd3432f93 100644 --- a/libcrux-ml-kem/c/benches/mlkem768_keygen.cc +++ b/libcrux-ml-kem/c/benches/mlkem768_keygen.cc @@ -10,6 +10,7 @@ #include "libcrux_sha3.h" #include "libcrux_mlkem768.h" +#include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" void generate_random(uint8_t *output, uint32_t output_len) @@ -22,11 +23,11 @@ int main(int argc, char const *argv[]) { uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); for (size_t i = 0; i < 100000; i++) { - key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); } return 0; } diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 5ca28c79c..39db7b956 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_core_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 4332f30ed..10a2cb5a5 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_avx2_H @@ -18,22 +18,6 @@ extern "C" { #include "internal/libcrux_mlkem_portable.h" #include "internal/libcrux_sha3_avx2.h" -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key); @@ -50,6 +34,22 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( uint8_t *public_key); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 4fa834a92..5773bba52 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index 405e13161..11ada5b26 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 32b53c527..c897dae9f 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 6f32affcf..95547276e 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 6d6e8dcac..52b97c825 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.c b/libcrux-ml-kem/c/libcrux_mlkem1024.c deleted file mode 100644 index 75a91f769..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem1024.h" - -#include "internal/libcrux_core.h" - -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_mlkem1024_MlKem1024KeyPair uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 622d719a3..40b2e232a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H @@ -14,9 +14,6 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM1024_VECTOR_U_COMPRESSION_FACTOR_1024 ((size_t)11U) @@ -83,38 +80,6 @@ typedef libcrux_ml_kem_types_MlKemPublicKey____1568size_t LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem1024_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); - #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index 78a35d9d3..9dbf4e203 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem1024_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index 22172d3c4..d3da0c00c 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index f977e74be..b63311db9 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 5f38c1f52..2479e6391 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.c b/libcrux-ml-kem/c/libcrux_mlkem512.c deleted file mode 100644 index 89cd6e786..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem512.h" - -#include "internal/libcrux_core.h" - -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index e3a0d8f74..5256458eb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_H @@ -14,9 +14,6 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM512_VECTOR_U_COMPRESSION_FACTOR_512 ((size_t)10U) @@ -87,40 +84,6 @@ typedef libcrux_ml_kem_types_MlKemPublicKey____800size_t LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem512_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); - #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index ffdf90bad..14cd4287a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem512_avx2.h" @@ -91,73 +91,73 @@ libcrux_ml_kem_mlkem512_avx2_validate_public_key( return uu____0; } -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( public_key); } -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uu____0); } -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; uint8_t uu____1[32U]; memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____0, uu____1); } -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( private_key, ciphertext, ret0); memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( public_key); } -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { uint8_t uu____0[64U]; memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uu____0); } -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; uint8_t uu____1[32U]; memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____0, uu____1); } -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( private_key, ciphertext, ret0); memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index 034e05ffa..34801018a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_avx2_H @@ -49,22 +49,6 @@ core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ libcrux_ml_kem_mlkem512_avx2_validate_public_key( libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( uint8_t *public_key); @@ -81,6 +65,22 @@ void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 437161657..8a1a92703 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index ec949dc4d..9ad10a424 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.c b/libcrux-ml-kem/c/libcrux_mlkem768.c deleted file mode 100644 index fbcc3e1be..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem768.h" - -#include "internal/libcrux_core.h" - -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t uu____0[32U]; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - } else { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, uu____0); - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); - return; - } - memcpy(ret, uu____0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ - uu____0; - if (libcrux_platform_platform_simd256_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____1 = public_key; - uint8_t uu____2[32U]; - memcpy(uu____2, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____1, uu____2); - } else if (libcrux_platform_platform_simd128_support()) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____3 = public_key; - uint8_t uu____4[32U]; - memcpy(uu____4, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____3, uu____4); - } else { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____5 = public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, randomness, (size_t)32U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6); - return uu____0; - } - return uu____0; -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - libcrux_ml_kem_mlkem768_MlKem768KeyPair uu____0; - if (libcrux_platform_platform_simd256_support()) { - uint8_t uu____1[64U]; - memcpy(uu____1, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____1); - } else if (libcrux_platform_platform_simd128_support()) { - uint8_t uu____2[64U]; - memcpy(uu____2, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____2); - } else { - uint8_t uu____3[64U]; - memcpy(uu____3, randomness, (size_t)64U * sizeof(uint8_t)); - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____3); - } - return uu____0; -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - bool uu____0; - if (libcrux_platform_platform_simd256_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } else if (libcrux_platform_platform_simd128_support()) { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } else { - uu____0 = - libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( - public_key); - } - return uu____0; -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 566ce5499..c69fb58ac 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_H @@ -14,9 +14,6 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" -#include "libcrux_mlkem512_portable.h" -#include "libcrux_platform.h" #define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) @@ -81,38 +78,6 @@ typedef libcrux_ml_kem_types_MlKemPublicKey____1184size_t LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) -void libcrux_ml_kem_ind_cca_multiplexing_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem768_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_multiplexing_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_multiplexing_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_multiplexing_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index ba858e6f0..4497d2302 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem768_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index 2354c986e..373792504 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 76de52009..06ce4a50d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 2e8dd612b..d7b8a5c6f 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index 1f4239112..23df04b2d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_mlkem_avx2.h" @@ -1561,7 +1561,7 @@ ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -1592,14 +1592,14 @@ deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -1621,7 +1621,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568 } memcpy( ret, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -1677,17 +1677,17 @@ serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, key, + (size_t)3U, key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -1697,7 +1697,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, + (size_t)1152U, out, ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * @@ -1711,68 +1711,68 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); } static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, + (size_t)1184U, public_key_serialized, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), + .end = (size_t)1152U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[4U]; + uu____1[3U]; memcpy( uu____1, t_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( uu____1, ret0); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, Eurydice_slice), seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), deserialized_pk); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[4U]; + uu____0[3U]; memcpy( uu____0, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), public_key_serialized); return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), @@ -1781,22 +1781,22 @@ static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); memcpy( ret, ret0, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -1804,7 +1804,7 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 Simd256Hash; static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { +shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t state = libcrux_sha3_avx2_x4_incremental_shake128_init(); libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t @@ -1817,67 +1817,59 @@ shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); return state; } -static inline void shake128_squeeze_three_blocks___4size_t( +static inline void shake128_squeeze_three_blocks___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], Eurydice_slice), (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], + out12, (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + Eurydice_slice out2 = uu____1.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -1903,8 +1895,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -1913,63 +1905,55 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ return done; } -static inline void shake128_squeeze_block___4size_t( +static inline void shake128_squeeze_block___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], Eurydice_slice), (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[168U], + out12, (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + Eurydice_slice out2 = uu____1.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], - uint8_t(*)[168U], uint8_t[168U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -1995,8 +1979,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -2026,7 +2010,7 @@ from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -2037,84 +2021,84 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seeds[4U][34U], +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seeds[3U][34U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { if (done) { break; } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( uu____2, sampled_coefficients, out); } } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( uu____3[i]);); memcpy( ret, ret0, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( uint8_t seed[34U], bool transpose, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U][4U]) { + ret[3U][3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; uint8_t uu____0[34U]; memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( uu____1, sampled); for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, sampled, + (size_t)3U, sampled, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -2131,79 +2115,71 @@ sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu }); memcpy( ret, A_transpose, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U])); + [3U])); } typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[4U]; + fst[3U]; uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], + Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], Eurydice_slice), (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; + Eurydice_slice out12 = uu____0.snd; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], + out12, (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( + Eurydice_slice uu____7 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____9 = Eurydice_array_to_slice( + Eurydice_slice uu____8 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); + uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, + Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -2471,27 +2447,27 @@ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -2501,17 +2477,17 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( &re_as_ntt[i0]);); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; + uu____2[3U]; memcpy( uu____2, re_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; @@ -2519,7 +2495,7 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -2554,7 +2530,7 @@ ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -2602,31 +2578,31 @@ add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[4U], + *matrix_A)[3U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *s_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, matrix_A, + (size_t)3U, matrix_A, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], size_t); i0++) { size_t i1 = i0; @@ -2637,7 +2613,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, row, + (size_t)3U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -2649,7 +2625,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1], &product); } add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -2657,16 +2633,16 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } memcpy( ret, result, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); + G___3size_t(key_generation_seed, hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), @@ -2675,75 +2651,75 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; + A_transpose[3U][3U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret, true, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____1, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; + secret_as_ntt[3U]; memcpy( secret_as_ntt, uu____2.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[4U]; + error_as_ntt[3U]; memcpy( error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____3, domain_separator) .fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[4U]; + uu____4[3U]; memcpy( uu____4, t_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( uu____4, seed_for_A, public_key_serialized); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; + uu____5[3U]; memcpy( uu____5, secret_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; } -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), @@ -2752,17 +2728,17 @@ static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { } static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____0, + (size_t)2400U, uu____0, ((core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + @@ -2775,7 +2751,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t size_t uu____5 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____3, + (size_t)2400U, uu____3, ((core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + @@ -2784,13 +2760,13 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, + (size_t)2400U, out, ((core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; - H___4size_t(public_key, ret0); + H___3size_t(public_key, ret0); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), @@ -2801,18 +2777,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t size_t uu____9 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)3168U, uu____7, + (size_t)2400U, uu____7, ((core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, @@ -2824,49 +2800,49 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, Eurydice_slice), implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -2888,38 +2864,38 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536 } memcpy( ret, deserialized_pk, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -2927,24 +2903,24 @@ sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem uint8_t, Eurydice_slice)); error_1[i0] = uu____1;); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; + uu____2[3U]; memcpy( uu____2, error_1, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; return lit; } -static inline void PRF___4size_t_128size_t(Eurydice_slice input, +static inline void PRF___3size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -2954,7 +2930,7 @@ static inline void PRF___4size_t_128size_t(Eurydice_slice input, } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -3060,7 +3036,7 @@ invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = @@ -3099,31 +3075,31 @@ static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[4U], + *a_as_ntt)[3U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *r_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_1, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, + (size_t)3U, a_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], + [3U], size_t); i0++) { size_t i1 = i0; @@ -3134,7 +3110,7 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, row, + (size_t)3U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -3146,17 +3122,17 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result[i1]); add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -3222,7 +3198,7 @@ add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *t_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -3233,14 +3209,14 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( *message) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result); result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( error_2, message, result); @@ -3310,11 +3286,11 @@ static core_core_arch_x86___m256i compress___10int32_t( } static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -3325,7 +3301,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, + (size_t)320U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3334,7 +3310,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline core_core_arch_x86___m256i @@ -3400,11 +3376,11 @@ static core_core_arch_x86___m256i compress___11int32_t( } static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -3415,7 +3391,7 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, + (size_t)320U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3424,31 +3400,31 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); } static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[4U], + input[3U], Eurydice_slice out) { for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)4U, input, + (size_t)3U, input, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -3460,15 +3436,15 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408 Eurydice_slice uu____0 = Eurydice_slice_subslice( out, ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( &re, ret); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), uint8_t, void *); } } @@ -3650,64 +3626,64 @@ compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re, Eurydice_slice out) { - compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); + compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); } static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { + uint8_t ret[1088U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice), t_as_ntt); Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; + A_transpose[3U][3U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( uu____0, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[4U]; + r_as_ntt[3U]; memcpy( r_as_ntt, uu____1.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( uu____2, domain_separator0); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; + error_1[3U]; memcpy( error_1, uu____3.fst, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___4size_t_128size_t( + PRF___3size_t_128size_t( Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), prf_output); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -3716,8 +3692,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); @@ -3726,34 +3702,34 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( uu____4); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; + uint8_t ciphertext[1088U] = {0U}; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; + uu____5[3U]; memcpy( uu____5, u, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, + (size_t)1088U, ciphertext, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), + .end = (size_t)960U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -3763,10 +3739,10 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, size_t, Eurydice_slice); uint8_t ret[32U]; - H___4size_t( + H___3size_t( Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( public_key), uint8_t, Eurydice_slice), ret); @@ -3775,7 +3751,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), uint8_t, void *); uint8_t hashed[64U]; - G___4size_t( + G___3size_t( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = @@ -3786,35 +3762,35 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( public_key), uint8_t, Eurydice_slice); uint8_t uu____3[32U]; memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____2, uu____3, pseudorandomness, ciphertext); uint8_t shared_secret_array[32U] = {0U}; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, Eurydice_slice), shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uu____4); uint8_t uu____6[32U]; memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -3992,18 +3968,18 @@ deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = (size_t)0U; @@ -4022,46 +3998,46 @@ ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( } static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( uint8_t *ciphertext, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, Eurydice_slice), uint8_t, size_t) / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); + (size_t)10U / (size_t)8U); i++) { size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, + (size_t)1088U, ciphertext, ((core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), + (size_t)10U / (size_t)8U), .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + + (size_t)10U / (size_t)8U) + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), + (size_t)10U / (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( &u_as_ntt[i0]); } memcpy( ret, u_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -4237,18 +4213,18 @@ deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } @@ -4276,14 +4252,14 @@ deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vect } static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( Eurydice_slice secret_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { + ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / @@ -4305,7 +4281,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( } memcpy( ret, secret_as_ntt, - (size_t)4U * + (size_t)3U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } @@ -4332,7 +4308,7 @@ subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *v, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -4341,14 +4317,14 @@ compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( *u_as_ntt) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &result); result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); return result; @@ -4384,24 +4360,24 @@ compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( } static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( secret_key, secret_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -4409,7 +4385,7 @@ decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_ memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void PRF___4size_t_32size_t(Eurydice_slice input, +static inline void PRF___3size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -4418,21 +4394,20 @@ static inline void PRF___4size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, Eurydice_slice), - (size_t)1536U, uint8_t, + (size_t)1152U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, + secret_key0, (size_t)1184U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; @@ -4443,7 +4418,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -4455,7 +4430,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t, size_t, Eurydice_slice), ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___4size_t( + G___3size_t( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = @@ -4465,33 +4440,33 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( implicit_rejection_value, to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( ciphertext), uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( uu____5, uu____6, pseudorandomness, expected_ciphertext); Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( ciphertext); uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; @@ -4504,19 +4479,19 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -4538,23 +4513,23 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184 } memcpy( ret, deserialized_pk, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, key, + (size_t)4U, key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -4564,7 +4539,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, + (size_t)1536U, out, ((core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * @@ -4578,68 +4553,68 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); } static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, + (size_t)1568U, public_key_serialized, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), + .end = (size_t)1536U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[3U]; + uu____1[4U]; memcpy( uu____1, t_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( uu____1, ret0); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), uint8_t, void *); core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, Eurydice_slice), seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); } -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uint8_t *public_key) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), deserialized_pk); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[3U]; + uu____0[4U]; memcpy( uu____0, deserialized_pk, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), public_key_serialized); return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); } -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), @@ -4648,28 +4623,28 @@ static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); memcpy( ret, ret0, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { +shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t state = libcrux_sha3_avx2_x4_incremental_shake128_init(); libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t @@ -4682,59 +4657,67 @@ shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); return state; } -static inline void shake128_squeeze_three_blocks___3size_t( +static inline void shake128_squeeze_three_blocks___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; + uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], Eurydice_slice), (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; + Eurydice_slice out123 = uu____0.snd; K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], + out123, (size_t)1U, uint8_t[504U], K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____6 = Eurydice_array_to_slice( (size_t)504U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], uint8_t[504U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -4760,8 +4743,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -4770,55 +4753,63 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ return done; } -static inline void shake128_squeeze_block___3size_t( +static inline void shake128_squeeze_block___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; + uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], Eurydice_slice), (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; + Eurydice_slice out123 = uu____0.snd; K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[168U], + out123, (size_t)1U, uint8_t[168U], K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( + Eurydice_slice uu____5 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( + Eurydice_slice uu____6 = Eurydice_array_to_slice( (size_t)168U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], uint8_t[168U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], + uint8_t(*)[168U], uint8_t[168U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); } static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { size_t r = i; if (sampled_coefficients[i1] < @@ -4844,8 +4835,8 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } }); bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; if (sampled_coefficients[i0] >= LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { sampled_coefficients[i0] = @@ -4855,7 +4846,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -4866,84 +4857,84 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ } static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seeds[3U][34U], +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seeds[4U][34U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( uu____1, sampled_coefficients, out); while (true) { if (done) { break; } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( uu____2, sampled_coefficients, out); } } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( uu____3[i]);); memcpy( ret, ret0, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( uint8_t seed[34U], bool transpose, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U][3U]) { + ret[4U][4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; uint8_t uu____0[34U]; memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( uu____1, sampled); for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, sampled, + (size_t)4U, sampled, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -4960,94 +4951,102 @@ sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_fu }); memcpy( ret, A_transpose, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U])); + [4U])); } typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[3U]; + fst[4U]; uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], + Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], Eurydice_slice), (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; + Eurydice_slice out123 = uu____0.snd; K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], + out123, (size_t)1U, uint8_t[128U], K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( + Eurydice_slice uu____8 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( + Eurydice_slice uu____9 = Eurydice_array_to_slice( (size_t)128U, Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], uint8_t[128U]), uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, - Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); + uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -5057,17 +5056,17 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( &re_as_ntt[i0]);); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; + uu____2[4U]; memcpy( uu____2, re_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; @@ -5075,12 +5074,12 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_ } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *self, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5101,31 +5100,31 @@ add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[3U], + *matrix_A)[4U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *s_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, matrix_A, + (size_t)4U, matrix_A, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [4U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [4U], size_t); i0++) { size_t i1 = i0; @@ -5136,7 +5135,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, row, + (size_t)4U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5148,7 +5147,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1], &product); } add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -5156,16 +5155,16 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } memcpy( ret, result, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); + G___4size_t(key_generation_seed, hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), @@ -5174,75 +5173,75 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; + A_transpose[4U][4U]; uint8_t ret[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret, true, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____1, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; + secret_as_ntt[4U]; memcpy( secret_as_ntt, uu____2.fst, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____2.snd; uint8_t uu____3[33U]; memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[3U]; + error_as_ntt[4U]; memcpy( error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____3, domain_separator) .fst, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[3U]; + uu____4[4U]; memcpy( uu____4, t_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( uu____4, seed_for_A, public_key_serialized); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; + uu____5[4U]; memcpy( uu____5, secret_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; } -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), @@ -5251,17 +5250,17 @@ static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { } static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; size_t pointer = (size_t)0U; uint8_t *uu____0 = out; size_t uu____1 = pointer; size_t uu____2 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____0, + (size_t)3168U, uu____0, ((core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + @@ -5274,7 +5273,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t size_t uu____5 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____3, + (size_t)3168U, uu____3, ((core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + @@ -5283,13 +5282,13 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t public_key, uint8_t, void *); pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, + (size_t)3168U, out, ((core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret0[32U]; - H___3size_t(public_key, ret0); + H___4size_t(public_key, ret0); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), @@ -5300,18 +5299,18 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t size_t uu____9 = pointer; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( - (size_t)2400U, uu____7, + (size_t)3168U, uu____7, ((core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, @@ -5323,49 +5322,49 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, Eurydice_slice), implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uu____4)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( Eurydice_slice public_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / @@ -5387,38 +5386,38 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152 } memcpy( ret, deserialized_pk, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; prf_inputs[i0][32U] = domain_separator; domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1 = sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( @@ -5426,24 +5425,24 @@ sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem uint8_t, Eurydice_slice)); error_1[i0] = uu____1;); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; + uu____2[4U]; memcpy( uu____2, error_1, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t lit; memcpy( lit.fst, uu____2, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); lit.snd = domain_separator; return lit; } -static inline void PRF___3size_t_128size_t(Eurydice_slice input, +static inline void PRF___4size_t_128size_t(Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -5453,12 +5452,12 @@ static inline void PRF___3size_t_128size_t(Eurydice_slice input, } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = @@ -5478,31 +5477,31 @@ invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[3U], + *a_as_ntt)[4U], libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *r_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *error_1, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for ( size_t i0 = (size_t)0U; i0 < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, + (size_t)4U, a_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [4U], Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], + [4U], size_t); i0++) { size_t i1 = i0; @@ -5513,7 +5512,7 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, row, + (size_t)4U, row, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5525,23 +5524,23 @@ compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1], &product); } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result[i1]); add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *t_as_ntt, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5552,14 +5551,14 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( *message) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result); result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( error_2, message, result); @@ -5567,11 +5566,11 @@ compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -5582,7 +5581,7 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, + (size_t)352U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5591,15 +5590,15 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; @@ -5610,7 +5609,7 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, + (size_t)352U, serialized, ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5619,31 +5618,31 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), uint8_t, void *); } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); } static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + uint8_t ret[352U]) { + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); } static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[3U], + input[4U], Eurydice_slice out) { for ( size_t i = (size_t)0U; i < core_slice___Slice_T___len( Eurydice_array_to_slice( - (size_t)3U, input, + (size_t)4U, input, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, Eurydice_slice), libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -5655,78 +5654,78 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960s Eurydice_slice uu____0 = Eurydice_slice_subslice( out, ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( &re, ret); core_slice___Slice_T___copy_from_slice( uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), uint8_t, void *); } } static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector re, Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); + compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); } static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { + uint8_t ret[1568U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice), t_as_ntt); Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; + A_transpose[4U][4U]; uint8_t ret0[34U]; libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( uu____0, 0U); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[3U]; + r_as_ntt[4U]; memcpy( r_as_ntt, uu____1.fst, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator0 = uu____1.snd; uint8_t uu____2[33U]; memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( uu____2, domain_separator0); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; + error_1[4U]; memcpy( error_1, uu____3.fst, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); uint8_t domain_separator = uu____3.snd; prf_input[32U] = domain_separator; uint8_t prf_output[128U]; - PRF___3size_t_128size_t( + PRF___4size_t_128size_t( Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), prf_output); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5735,8 +5734,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( A_transpose, r_as_ntt, error_1, u); uint8_t uu____4[32U]; memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); @@ -5745,34 +5744,34 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( uu____4); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; + uint8_t ciphertext[1568U] = {0U}; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; + uu____5[4U]; memcpy( uu____5, u, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, + (size_t)1568U, ciphertext, ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), + .end = (size_t)1408U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); } -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -5782,10 +5781,10 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, size_t, Eurydice_slice); uint8_t ret[32U]; - H___3size_t( + H___4size_t( Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( public_key), uint8_t, Eurydice_slice), ret); @@ -5794,7 +5793,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), uint8_t, void *); uint8_t hashed[64U]; - G___3size_t( + G___4size_t( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = @@ -5805,52 +5804,52 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( public_key), uint8_t, Eurydice_slice); uint8_t uu____3[32U]; memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____2, uu____3, pseudorandomness, ciphertext); uint8_t shared_secret_array[32U] = {0U}; core_slice___Slice_T___copy_from_slice( Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, Eurydice_slice), shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uu____4); uint8_t uu____6[32U]; memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; lit.fst = uu____5; memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); return lit; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *re) { size_t zeta_i = (size_t)0U; @@ -5869,75 +5868,75 @@ ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( } static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( uint8_t *ciphertext, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, Eurydice_slice), uint8_t, size_t) / (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); + (size_t)11U / (size_t)8U); i++) { size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, + (size_t)1568U, ciphertext, ((core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), + (size_t)11U / (size_t)8U), .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + + (size_t)11U / (size_t)8U) + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), + (size_t)11U / (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( u_bytes); u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( &u_as_ntt[i0]); } memcpy( ret, u_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( Eurydice_slice serialized) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____0; uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( serialized); return uu____0; } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); } static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( Eurydice_slice secret_key, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { + ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); for (size_t i = (size_t)0U; i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / @@ -5959,13 +5958,13 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( } memcpy( ret, secret_as_ntt, - (size_t)3U * + (size_t)4U * sizeof( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector *v, libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -5974,38 +5973,38 @@ compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( *u_as_ntt) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &result); result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); return result; } static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( secret_key, secret_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( &v, secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( @@ -6013,7 +6012,7 @@ decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_1 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static inline void PRF___3size_t_32size_t(Eurydice_slice input, +static inline void PRF___4size_t_32size_t(Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -6022,20 +6021,21 @@ static inline void PRF___3size_t_32size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, Eurydice_slice), - (size_t)1152U, uint8_t, + (size_t)1536U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_secret_key = uu____0.fst; Eurydice_slice secret_key0 = uu____0.snd; K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, + secret_key0, (size_t)1568U, uint8_t, K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice ind_cpa_public_key = uu____1.fst; Eurydice_slice secret_key = uu____1.snd; @@ -6046,7 +6046,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; Eurydice_slice implicit_rejection_value = uu____2.snd; uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( @@ -6058,7 +6058,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t, size_t, Eurydice_slice), ind_cpa_public_key_hash, uint8_t, void *); uint8_t hashed[64U]; - G___3size_t( + G___4size_t( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), hashed); K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = @@ -6068,33 +6068,33 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( implicit_rejection_value, to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( ciphertext), uint8_t, void *); uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), implicit_rejection_shared_secret); Eurydice_slice uu____5 = ind_cpa_public_key; uint8_t uu____6[32U]; memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( uu____5, uu____6, pseudorandomness, expected_ciphertext); Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( ciphertext); uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t, Eurydice_slice)); Eurydice_slice uu____8 = shared_secret; uint8_t ret0[32U]; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index e4349f2b1..5ae63072a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index c995aa8b6..813f4fac4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index 02b989972..078c0cbd3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index ef41683e2..988a2e7f2 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 36ca19e89..87bfd1a1a 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 5df798795..49e0302b8 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_sha3_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 28d49028b..2f9e86a7b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 86ffaa430..e796057eb 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index b9aa5c77b..3d3d86bf4 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 0861469fa..0a665654b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index d6227f283..b03897d91 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -12,8 +12,12 @@ #include "libcrux_sha3.h" #include "libcrux_mlkem768.h" +#include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" -// #include "util.h" + +#ifdef LIBCRUX_X64 +#include "libcrux_mlkem768_avx2.h" +#endif using namespace std; @@ -156,27 +160,46 @@ read_kats(string path) // return sharedSecret; // } -TEST(MlKem768Test, ConsistencyTest) +#ifdef LIBCRUX_X64 +TEST(MlKem768TestAvx2, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + randomness[i] = 13; + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} +#endif + +TEST(MlKem768TestPortable, ConsistencyTest) { uint8_t randomness[64]; for (int i = 0; i < 64; i++) randomness[i] = 13; // generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); // printf("pk: "); // print_hex_ln(1184, key_pair.pk.value); // printf("sk: "); // print_hex_ln(2400, key_pair.sk.value); // generate_random(randomness, 32); - auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); // printf("ctxt: "); // print_hex_ln(1088U, ctxt.fst.value); // printf("secret: "); // print_hex_ln(32, ctxt.snd); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); // printf("secret2: "); // print_hex_ln(32, sharedSecret2); @@ -262,38 +285,52 @@ TEST(MlKem768Test, NISTKnownAnswerTest) for (auto kat : kats) { - auto key_pair = - libcrux_ml_kem_mlkem768_generate_key_pair(kat.key_generation_seed.data()); + // auto key_pair = + // libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); + +#ifdef LIBCRUX_X64 + auto key_pair_avx2 = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); +#endif + uint8_t pk_hash[32]; + // libcrux_sha3_sha256( + // EURYDICE_SLICE(key_pair.pk.value, 0, + // LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + // pk_hash); + // EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + +#ifdef LIBCRUX_X64 libcrux_sha3_sha256( - EURYDICE_SLICE(key_pair.pk.value, 0, + EURYDICE_SLICE(key_pair_avx2.pk.value, 0, LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), pk_hash); EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); - uint8_t sk_hash[32]; - libcrux_sha3_sha256( - EURYDICE_SLICE(key_pair.sk.value, 0, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); - EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); - - auto ctxt = libcrux_ml_kem_mlkem768_encapsulate( - &key_pair.pk, kat.encapsulation_seed.data()); - uint8_t ct_hash[32]; - libcrux_sha3_sha256( - EURYDICE_SLICE(ctxt.fst.value, 0, - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), - ct_hash); - EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); - EXPECT_EQ(0, - memcmp(ctxt.snd, - kat.shared_secret.data(), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); - - uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - - EXPECT_EQ(0, - memcmp(ctxt.snd, - sharedSecret2, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +#endif + + // uint8_t sk_hash[32]; + // libcrux_sha3_sha256( + // EURYDICE_SLICE(key_pair.sk.value, 0, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + // EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + // auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( + // &key_pair.pk, kat.encapsulation_seed.data()); + // uint8_t ct_hash[32]; + // libcrux_sha3_sha256( + // EURYDICE_SLICE(ctxt.fst.value, 0, + // LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + // ct_hash); + // EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + // EXPECT_EQ(0, + // memcmp(ctxt.snd, + // kat.shared_secret.data(), + // LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + // uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + // libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + // EXPECT_EQ(0, + // memcmp(ctxt.snd, + // sharedSecret2, + // LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } } diff --git a/libcrux-ml-kem/c/tests/sha3.cc b/libcrux-ml-kem/c/tests/sha3.cc index 7184a6754..2801612a0 100644 --- a/libcrux-ml-kem/c/tests/sha3.cc +++ b/libcrux-ml-kem/c/tests/sha3.cc @@ -57,28 +57,3 @@ TEST(Sha3Test, ConsistencyTest) 32), 0); } - -#define KYBER768_SECRETKEYBYTES 2400 -#define KYBER768_PUBLICKEYBYTES 1184 -#define KYBER768_CIPHERTEXTBYTES 1088 -#define KYBER768_SHAREDSECRETBYTES 32 - -TEST(Kyber768Test, ConsistencyTest) -{ - uint8_t randomness[64] = { 0 }; - uint8_t publicKey[KYBER768_PUBLICKEYBYTES]; - uint8_t secretKey[KYBER768_SECRETKEYBYTES]; - - libcrux_ml_kem_types_MlKemKeyPair____2400size_t__1184size_t kp = - libcrux_ml_kem_mlkem768_generate_key_pair(randomness); - - uint8_t ciphertext[KYBER768_CIPHERTEXTBYTES]; - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ cipher_and_shared_secret = - libcrux_ml_kem_mlkem768_encapsulate(&kp.pk, randomness); - - uint8_t sharedSecret2[KYBER768_SHAREDSECRETBYTES]; - libcrux_ml_kem_mlkem768_decapsulate(&kp.sk, &cipher_and_shared_secret.fst, sharedSecret2); - - EXPECT_EQ(0, memcmp(cipher_and_shared_secret.snd, sharedSecret2, KYBER768_SHAREDSECRETBYTES)); -} - diff --git a/libcrux-ml-kem/src/ind_cca/multiplexing.rs b/libcrux-ml-kem/src/ind_cca/multiplexing.rs index 54542df86..4a49471c3 100644 --- a/libcrux-ml-kem/src/ind_cca/multiplexing.rs +++ b/libcrux-ml-kem/src/ind_cca/multiplexing.rs @@ -1,5 +1,30 @@ use super::*; +// For the case where we didn't compile with the simd128/simd256 features but +// have a CPU that has it and thus tries to call the simd128/simd256 version, +// we fall back to the portable version in this case. + +#[cfg(feature = "simd256")] +use instantiations::avx2::{ + decapsulate as decapsulate_avx2, encapsulate as encapsulate_avx2, + generate_keypair as generate_keypair_avx2, validate_public_key as validate_public_key_avx2, +}; +#[cfg(feature = "simd128")] +use instantiations::neon::{ + decapsulate as decapsulate_neon, encapsulate as encapsulate_neon, + generate_keypair as generate_keypair_neon, validate_public_key as validate_public_key_neon, +}; +#[cfg(not(feature = "simd256"))] +use instantiations::portable::{ + decapsulate as decapsulate_avx2, encapsulate as encapsulate_avx2, + generate_keypair as generate_keypair_avx2, validate_public_key as validate_public_key_avx2, +}; +#[cfg(not(feature = "simd128"))] +use instantiations::portable::{ + decapsulate as decapsulate_neon, encapsulate as encapsulate_neon, + generate_keypair as generate_keypair_neon, validate_public_key as validate_public_key_neon, +}; + pub(crate) fn validate_public_key< const K: usize, const RANKED_BYTES_PER_RING_ELEMENT: usize, @@ -8,31 +33,9 @@ pub(crate) fn validate_public_key< public_key: &[u8; PUBLIC_KEY_SIZE], ) -> bool { if libcrux_platform::simd256_support() { - #[cfg(feature = "simd256")] - return instantiations::avx2::validate_public_key::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key); - #[cfg(not(feature = "simd256"))] - instantiations::portable::validate_public_key::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key) + validate_public_key_avx2::(public_key) } else if libcrux_platform::simd128_support() { - #[cfg(feature = "simd128")] - return instantiations::neon::validate_public_key::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key); - #[cfg(not(feature = "simd128"))] - instantiations::portable::validate_public_key::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(public_key) + validate_public_key_neon::(public_key) } else { instantiations::portable::validate_public_key::< K, @@ -55,18 +58,7 @@ pub(crate) fn generate_keypair< ) -> MlKemKeyPair { // Runtime feature detection. if libcrux_platform::simd256_support() { - #[cfg(feature = "simd256")] - return instantiations::avx2::generate_keypair::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness); - #[cfg(not(feature = "simd256"))] - instantiations::portable::generate_keypair::< + generate_keypair_avx2::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -76,18 +68,7 @@ pub(crate) fn generate_keypair< ETA1_RANDOMNESS_SIZE, >(randomness) } else if libcrux_platform::simd128_support() { - #[cfg(feature = "simd128")] - return instantiations::neon::generate_keypair::< - K, - CPA_PRIVATE_KEY_SIZE, - PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness); - #[cfg(not(feature = "simd128"))] - instantiations::portable::generate_keypair::< + generate_keypair_neon::< K, CPA_PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE, @@ -128,24 +109,7 @@ pub(crate) fn encapsulate< randomness: [u8; SHARED_SECRET_SIZE], ) -> (MlKemCiphertext, MlKemSharedSecret) { if libcrux_platform::simd256_support() { - #[cfg(feature = "simd256")] - return instantiations::avx2::encapsulate::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness); - #[cfg(not(feature = "simd256"))] - instantiations::portable::encapsulate::< + encapsulate_avx2::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -161,24 +125,7 @@ pub(crate) fn encapsulate< ETA2_RANDOMNESS_SIZE, >(public_key, randomness) } else if libcrux_platform::simd128_support() { - #[cfg(not(feature = "simd128"))] - return instantiations::portable::encapsulate::< - K, - CIPHERTEXT_SIZE, - PUBLIC_KEY_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness); - #[cfg(all(feature = "simd128", target_arch = "aarch64"))] - instantiations::neon::encapsulate::< + encapsulate_neon::< K, CIPHERTEXT_SIZE, PUBLIC_KEY_SIZE, @@ -234,8 +181,7 @@ pub(crate) fn decapsulate< ciphertext: &MlKemCiphertext, ) -> MlKemSharedSecret { if libcrux_platform::simd256_support() { - #[cfg(feature = "simd256")] - return instantiations::avx2::decapsulate::< + decapsulate_avx2::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -252,29 +198,9 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - #[cfg(not(feature = "simd256"))] - return instantiations::portable::decapsulate::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); + >(private_key, ciphertext) } else if libcrux_platform::simd128_support() { - #[cfg(feature = "simd128")] - return instantiations::neon::decapsulate::< + decapsulate_neon::< K, SECRET_KEY_SIZE, CPA_SECRET_KEY_SIZE, @@ -291,26 +217,7 @@ pub(crate) fn decapsulate< ETA2, ETA2_RANDOMNESS_SIZE, IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); - #[cfg(not(feature = "simd128"))] - return instantiations::portable::decapsulate::< - K, - SECRET_KEY_SIZE, - CPA_SECRET_KEY_SIZE, - PUBLIC_KEY_SIZE, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(private_key, ciphertext); + >(private_key, ciphertext) } else { instantiations::portable::decapsulate::< K, diff --git a/libcrux-ml-kem/src/mlkem1024.rs b/libcrux-ml-kem/src/mlkem1024.rs index 5a3a8b520..79fb38507 100644 --- a/libcrux-ml-kem/src/mlkem1024.rs +++ b/libcrux-ml-kem/src/mlkem1024.rs @@ -55,7 +55,9 @@ macro_rules! instantiate { /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. - pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option { + pub fn validate_public_key( + public_key: MlKem1024PublicKey, + ) -> Option { if p::validate_public_key::< RANK_1024, RANKED_BYTES_PER_RING_ELEMENT_1024, @@ -151,6 +153,7 @@ instantiate! {neon, ind_cca::instantiations::neon} /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. +#[cfg(not(eurydice))] pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option { if multiplexing::validate_public_key::< RANK_1024, @@ -170,6 +173,7 @@ pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option MlKemKeyPair { @@ -189,6 +193,7 @@ pub fn generate_key_pair( /// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`] /// bytes of `randomness`. +#[cfg(not(eurydice))] pub fn encapsulate( public_key: &MlKem1024PublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -214,6 +219,7 @@ pub fn encapsulate( /// /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. +#[cfg(not(eurydice))] pub fn decapsulate( private_key: &MlKem1024PrivateKey, ciphertext: &MlKem1024Ciphertext, diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index 3ec606dd7..caf50dda5 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -149,6 +149,7 @@ instantiate! {neon, ind_cca::instantiations::neon} /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. +#[cfg(not(eurydice))] pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option { if multiplexing::validate_public_key::< RANK_512, @@ -168,6 +169,7 @@ pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option MlKem512KeyPair { multiplexing::generate_keypair::< RANK_512, @@ -185,6 +187,7 @@ pub fn generate_key_pair(randomness: [u8; KEY_GENERATION_SEED_SIZE]) -> MlKem512 /// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`] /// bytes of `randomness`. +#[cfg(not(eurydice))] pub fn encapsulate( public_key: &MlKem512PublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -210,6 +213,7 @@ pub fn encapsulate( /// /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. +#[cfg(not(eurydice))] pub fn decapsulate( private_key: &MlKem512PrivateKey, ciphertext: &MlKem512Ciphertext, diff --git a/libcrux-ml-kem/src/mlkem768.rs b/libcrux-ml-kem/src/mlkem768.rs index 9fa1b03f3..3bd9333f4 100644 --- a/libcrux-ml-kem/src/mlkem768.rs +++ b/libcrux-ml-kem/src/mlkem768.rs @@ -150,6 +150,7 @@ instantiate! {neon, ind_cca::instantiations::neon} /// Validate a public key. /// /// Returns `Some(public_key)` if valid, and `None` otherwise. +#[cfg(not(eurydice))] pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option { if multiplexing::validate_public_key::< RANK_768, @@ -176,6 +177,7 @@ pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option MlKem768KeyPair { multiplexing::generate_keypair::< RANK_768, @@ -193,6 +195,7 @@ pub fn generate_key_pair(randomness: [u8; KEY_GENERATION_SEED_SIZE]) -> MlKem768 /// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] /// bytes of `randomness`. +#[cfg(not(eurydice))] pub fn encapsulate( public_key: &MlKem768PublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -218,6 +221,7 @@ pub fn encapsulate( /// /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. +#[cfg(not(eurydice))] pub fn decapsulate( private_key: &MlKem768PrivateKey, ciphertext: &MlKem768Ciphertext, diff --git a/libcrux-ml-kem/src/vector.rs b/libcrux-ml-kem/src/vector.rs index bc7cc7c0e..7f2ca8acb 100644 --- a/libcrux-ml-kem/src/vector.rs +++ b/libcrux-ml-kem/src/vector.rs @@ -211,7 +211,6 @@ pub(crate) mod portable { pub(crate) struct PortableVector { pub(crate) elements: [FieldElement; FIELD_ELEMENTS_IN_VECTOR], } - } use portable::*; @@ -296,8 +295,6 @@ pub fn cond_subtract_3329(mut v: PortableVector) -> PortableVector { v } -use portable::*; - /// Signed Barrett Reduction /// /// Given an input `value`, `barrett_reduce` outputs a representative `result` diff --git a/libcrux-sha3/src/lib.rs b/libcrux-sha3/src/lib.rs index 42a95a52d..5ec1e2605 100644 --- a/libcrux-sha3/src/lib.rs +++ b/libcrux-sha3/src/lib.rs @@ -662,6 +662,8 @@ pub mod avx2 { pub mod x4 { #[cfg(feature = "simd256")] use crate::generic_keccak::keccak; + #[cfg(feature = "simd256")] + use libcrux_intrinsics::avx2::*; /// Perform 4 SHAKE256 operations in parallel #[allow(unused_variables)] // TODO: decide if we want to fall back here @@ -692,7 +694,7 @@ pub mod avx2 { // keccakx1::<136, 0x1fu8>([input3], [out3]); // } #[cfg(feature = "simd256")] - keccak::<4, core::arch::x86_64::__m256i, 136, 0x1fu8>( + keccak::<4, Vec256, 136, 0x1fu8>( [input0, input1, input2, input3], [out0, out1, out2, out3], ); @@ -764,10 +766,12 @@ pub mod avx2 { use crate::generic_keccak::{ absorb_final, squeeze_first_three_blocks, squeeze_next_block, KeccakState, }; + #[cfg(feature = "simd256")] + use libcrux_intrinsics::avx2::*; #[cfg(feature = "simd256")] pub struct KeccakState4 { - state: KeccakState<4, core::arch::x86_64::__m256i>, + state: KeccakState<4, Vec256>, } #[allow(dead_code)] #[cfg(all(feature = "simd128", not(feature = "simd256")))] @@ -838,10 +842,7 @@ pub mod avx2 { // shake128_absorb_final(&mut s3, data3); // } #[cfg(feature = "simd256")] - absorb_final::<4, core::arch::x86_64::__m256i, 168, 0x1fu8>( - &mut s.state, - [data0, data1, data2, data3], - ); + absorb_final::<4, Vec256, 168, 0x1fu8>(&mut s.state, [data0, data1, data2, data3]); } /// Initialise the state and perform up to 4 absorbs at the same time, @@ -910,7 +911,7 @@ pub mod avx2 { // shake128_squeeze_first_three_blocks(&mut s3, out3); // } #[cfg(feature = "simd256")] - squeeze_first_three_blocks::<4, core::arch::x86_64::__m256i, 168>( + squeeze_first_three_blocks::<4, Vec256, 168>( &mut s.state, [out0, out1, out2, out3], ); @@ -1004,10 +1005,7 @@ pub mod avx2 { // shake128_squeeze_next_block(&mut s3, out3); // } #[cfg(feature = "simd256")] - squeeze_next_block::<4, core::arch::x86_64::__m256i, 168>( - &mut s.state, - [out0, out1, out2, out3], - ); + squeeze_next_block::<4, Vec256, 168>(&mut s.state, [out0, out1, out2, out3]); } /// Squeeze up to 4 (N) blocks in parallel, using two [`KeccakState4`]. diff --git a/libcrux-sha3/src/simd/avx2.rs b/libcrux-sha3/src/simd/avx2.rs index a22d2ac2d..04005c483 100644 --- a/libcrux-sha3/src/simd/avx2.rs +++ b/libcrux-sha3/src/simd/avx2.rs @@ -1,17 +1,15 @@ -use core::arch::x86_64::*; - use crate::traits::*; use libcrux_intrinsics::avx2::*; #[inline(always)] -fn rotate_left(x: __m256i) -> __m256i { +fn rotate_left(x: Vec256) -> Vec256 { debug_assert!(LEFT + RIGHT == 64); // XXX: This could be done more efficiently, if the shift values are multiples of 8. mm256_xor_si256(mm256_slli_epi64::(x), mm256_srli_epi64::(x)) } #[inline(always)] -fn _veor5q_u64(a: __m256i, b: __m256i, c: __m256i, d: __m256i, e: __m256i) -> __m256i { +fn _veor5q_u64(a: Vec256, b: Vec256, c: Vec256, d: Vec256, e: Vec256) -> Vec256 { let ab = mm256_xor_si256(a, b); let cd = mm256_xor_si256(c, d); let abcd = mm256_xor_si256(ab, cd); @@ -19,30 +17,30 @@ fn _veor5q_u64(a: __m256i, b: __m256i, c: __m256i, d: __m256i, e: __m256i) -> __ } #[inline(always)] -fn _vrax1q_u64(a: __m256i, b: __m256i) -> __m256i { +fn _vrax1q_u64(a: Vec256, b: Vec256) -> Vec256 { mm256_xor_si256(a, rotate_left::<1, 63>(b)) } #[inline(always)] -fn _vxarq_u64(a: __m256i, b: __m256i) -> __m256i { +fn _vxarq_u64(a: Vec256, b: Vec256) -> Vec256 { let ab = mm256_xor_si256(a, b); rotate_left::(ab) } #[inline(always)] -fn _vbcaxq_u64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +fn _vbcaxq_u64(a: Vec256, b: Vec256, c: Vec256) -> Vec256 { mm256_xor_si256(a, mm256_andnot_si256(c, b)) } #[inline(always)] -fn _veorq_n_u64(a: __m256i, c: u64) -> __m256i { +fn _veorq_n_u64(a: Vec256, c: u64) -> Vec256 { // Casting here is required, doesn't change the value. let c = mm256_set1_epi64x(c as i64); mm256_xor_si256(a, c) } #[inline(always)] -pub(crate) fn load_block(s: &mut [[__m256i; 5]; 5], blocks: [&[u8]; 4]) { +pub(crate) fn load_block(s: &mut [[Vec256; 5]; 5], blocks: [&[u8]; 4]) { debug_assert!(RATE <= blocks[0].len() && RATE % 8 == 0 && (RATE % 32 == 8 || RATE % 32 == 16)); for i in 0..RATE / 32 { let v0 = mm256_loadu_si256_u8(&blocks[0][32 * i..32 * (i + 1)]); @@ -94,10 +92,7 @@ pub(crate) fn load_block(s: &mut [[__m256i; 5]; 5], blocks: [ } #[inline(always)] -pub(crate) fn load_block_full( - s: &mut [[__m256i; 5]; 5], - blocks: [[u8; 200]; 4], -) { +pub(crate) fn load_block_full(s: &mut [[Vec256; 5]; 5], blocks: [[u8; 200]; 4]) { load_block::( s, [ @@ -110,7 +105,7 @@ pub(crate) fn load_block_full( } #[inline(always)] -pub(crate) fn store_block(s: &[[__m256i; 5]; 5], out: [&mut [u8]; 4]) { +pub(crate) fn store_block(s: &[[Vec256; 5]; 5], out: [&mut [u8]; 4]) { for i in 0..RATE / 32 { let v0l = mm256_permute2x128_si256::<0x20>( s[(4 * i) / 5][(4 * i) % 5], @@ -164,7 +159,7 @@ pub(crate) fn store_block(s: &[[__m256i; 5]; 5], out: [&mut [ } #[inline(always)] -pub(crate) fn store_block_full(s: &[[__m256i; 5]; 5]) -> [[u8; 200]; 4] { +pub(crate) fn store_block_full(s: &[[Vec256; 5]; 5]) -> [[u8; 200]; 4] { let mut out0 = [0u8; 200]; let mut out1 = [0u8; 200]; let mut out2 = [0u8; 200]; @@ -193,7 +188,7 @@ fn split_at_mut_4(out: [&mut [u8]; 4], mid: usize) -> ([&mut [u8]; 4], [&mut [u8 ([out00, out10, out20, out30], [out01, out11, out21, out31]) } -impl KeccakItem<4> for __m256i { +impl KeccakItem<4> for Vec256 { #[inline(always)] fn zero() -> Self { mm256_set1_epi64x(0) From 822f616daf9669bbe37ee065dd7dca124353dc92 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Thu, 6 Jun 2024 15:12:33 +0200 Subject: [PATCH 22/84] nix: link using mold --- flake.nix | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 689231107..d4c2c238b 100644 --- a/flake.nix +++ b/flake.nix @@ -38,15 +38,11 @@ ml-kem = craneLib.buildPackage { name = "ml-kem"; inherit src cargoArtifacts; - postPatch = '' - substituteInPlace libcrux-ml-kem/c/CMakeLists.txt \ - --replace " -flto" " # -flto" \ - --replace "add_link_options(-flto)" "#add_link_options(-flto)" - ''; nativeBuildInputs = [ pkgs.clang pkgs.cmake pkgs.gbenchmark + pkgs.mold-wrapped pkgs.ninja pkgs.python3 ]; @@ -57,6 +53,8 @@ cmake \ -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ -DFETCHCONTENT_SOURCE_DIR_JSON=${json} \ + -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" \ -G "Ninja Multi-Config" -B build cmake --build build --config Release ''; From a1eea98a98288b29e8c53d85eb8acf9983240a5d Mon Sep 17 00:00:00 2001 From: karthikbhargavan Date: Fri, 7 Jun 2024 09:09:01 +0200 Subject: [PATCH 23/84] manual C fix for portable --- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 813f4fac4..ed7e13445 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -602,7 +602,8 @@ libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) { Eurydice_slice, int16_t[16U], void *); core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( dst, ret); - memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); + // XXX KB modified this line + memcpy(lit.elements, array.ptr, (size_t)16U * sizeof(int16_t)); return lit; } From cb80541540d071056798e81de3e976952aa2e521 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Fri, 7 Jun 2024 09:36:36 +0200 Subject: [PATCH 24/84] making the C code build on arm --- libcrux-ml-kem/c/benches/sha3.cc | 7 ++++++- libcrux-ml-kem/c/libcrux_core.c | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libcrux-ml-kem/c/benches/sha3.cc b/libcrux-ml-kem/c/benches/sha3.cc index fa077330f..9c5b88fb1 100644 --- a/libcrux-ml-kem/c/benches/sha3.cc +++ b/libcrux-ml-kem/c/benches/sha3.cc @@ -14,11 +14,14 @@ // This is only broken in C++ #define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) -#include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_sha3.h" #include "libcrux_mlkem768.h" #include "internal/libcrux_core.h" + +#ifdef LIBCRUX_X64 +#include "intrinsics/libcrux_intrinsics_avx2.h" #include "internal/libcrux_sha3_avx2.h" +#endif void generate_random(uint8_t *output, uint32_t output_len) { @@ -56,6 +59,7 @@ sha3_512_64(benchmark::State &state) } } +#ifdef LIBCRUX_X64 static void shake128_34_504(benchmark::State &state) { @@ -132,5 +136,6 @@ BENCHMARK(sha3_512_64); BENCHMARK(shake128_34_504); BENCHMARK(shake256_1120_32); BENCHMARK(shake256_33_128); +#endif BENCHMARK_MAIN(); diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 95547276e..f3c81cf0c 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -405,3 +405,10 @@ void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_arra KRML_HOST_EXIT(255U); } } + +void core_fmt_rt__core__fmt__rt__Argument__a__1__none( + core_fmt_rt_Argument x0[0U]){} + +core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( + Eurydice_slice x0, Eurydice_slice x1) {return NULL;} + From dcc3ebae1494941054b2277223f553d7cf82d1f2 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 7 Jun 2024 12:38:11 +0200 Subject: [PATCH 25/84] more tests --- libcrux-ml-kem/c/tests/mlkem768.cc | 343 ++++++++++++++++++----------- 1 file changed, 213 insertions(+), 130 deletions(-) diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index b03897d91..2d07d800e 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -23,6 +23,24 @@ using namespace std; typedef vector bytes; +template +Eurydice_slice mk_slice(T *x, size_t len) +{ + Eurydice_slice s; + s.ptr = (void *)x; + s.len = len; + return s; +} + +// Not really random +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (size_t i = 0; i < output_len; i++) + { + output[i] = 13; + } +} + vector from_hex(const string &hex) { @@ -95,70 +113,72 @@ read_kats(string path) return kats; } -// void -// modify_ciphertext(uint8_t* ciphertext, size_t ciphertext_size) -// { -// uint8_t randomness[3]; -// generate_random(randomness, 3); +void modify_ciphertext(uint8_t *ciphertext, size_t ciphertext_size) +{ + uint8_t randomness[3]; + generate_random(randomness, 3); -// uint8_t random_byte = randomness[0]; -// if (random_byte == 0) { -// random_byte += 1; -// } + uint8_t random_byte = randomness[0]; + if (random_byte == 0) + { + random_byte += 1; + } -// uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; + uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; -// uint16_t random_position = random_u16 % ciphertext_size; + uint16_t random_position = random_u16 % ciphertext_size; -// ciphertext[random_position] ^= random_byte; -// } + ciphertext[random_position] ^= random_byte; +} -// void -// modify_secret_key(uint8_t* secret_key, -// size_t secret_key_size, -// bool modify_implicit_rejection_value) -// { -// uint8_t randomness[3]; -// generate_random(randomness, 3); +void modify_secret_key(uint8_t *secret_key, + size_t secret_key_size, + bool modify_implicit_rejection_value) +{ + uint8_t randomness[3]; + generate_random(randomness, 3); -// uint8_t random_byte = randomness[0]; -// if (random_byte == 0) { -// random_byte += 1; -// } + uint8_t random_byte = randomness[0]; + if (random_byte == 0) + { + random_byte += 1; + } -// uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; + uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; -// uint16_t random_position = 0; + uint16_t random_position = 0; -// if (modify_implicit_rejection_value == true) { -// random_position = (secret_key_size - 32) + (random_u16 % 32); -// } else { -// random_position = random_u16 % (secret_key_size - 32); -// } + if (modify_implicit_rejection_value == true) + { + random_position = (secret_key_size - 32) + (random_u16 % 32); + } + else + { + random_position = random_u16 % (secret_key_size - 32); + } -// secret_key[random_position] ^= random_byte; -// } + secret_key[random_position] ^= random_byte; +} -// uint8_t* -// compute_implicit_rejection_shared_secret(uint8_t* ciphertext, -// size_t ciphertext_size, -// uint8_t* secret_key, -// size_t secret_key_size) -// { -// uint8_t* hashInput = new uint8_t[32 + ciphertext_size]; -// uint8_t* sharedSecret = new uint8_t[32]; +uint8_t * +compute_implicit_rejection_shared_secret(uint8_t *ciphertext, + size_t ciphertext_size, + uint8_t *secret_key, + size_t secret_key_size) +{ + uint8_t *hashInput = new uint8_t[32 + ciphertext_size]; + uint8_t *sharedSecret = new uint8_t[32]; -// std::copy(secret_key + (secret_key_size - 32), -// secret_key + secret_key_size, -// hashInput); -// std::copy(ciphertext, ciphertext + ciphertext_size, hashInput + 32); + std::copy(secret_key + (secret_key_size - 32), + secret_key + secret_key_size, + hashInput); + std::copy(ciphertext, ciphertext + ciphertext_size, hashInput + 32); -// Hacl_Hash_SHA3_shake256_hacl( -// 32 + ciphertext_size, hashInput, 32, sharedSecret); + libcrux_sha3_sha256(mk_slice(hashInput, 32 + ciphertext_size), sharedSecret); -// delete[] hashInput; -// return sharedSecret; -// } + delete[] hashInput; + return sharedSecret; +} #ifdef LIBCRUX_X64 TEST(MlKem768TestAvx2, ConsistencyTest) @@ -183,25 +203,15 @@ TEST(MlKem768TestPortable, ConsistencyTest) { uint8_t randomness[64]; for (int i = 0; i < 64; i++) + { randomness[i] = 13; - // generate_random(randomness, 64); + } auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); - // printf("pk: "); - // print_hex_ln(1184, key_pair.pk.value); - // printf("sk: "); - // print_hex_ln(2400, key_pair.sk.value); - // generate_random(randomness, 32); auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); - // printf("ctxt: "); - // print_hex_ln(1088U, ctxt.fst.value); - // printf("secret: "); - // print_hex_ln(32, ctxt.snd); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - // printf("secret2: "); - // print_hex_ln(32, sharedSecret2); EXPECT_EQ(0, memcmp(ctxt.snd, @@ -209,38 +219,77 @@ TEST(MlKem768TestPortable, ConsistencyTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } -// TEST(Kyber768Test, ModifiedCiphertextTest) -// { -// uint8_t randomness[64]; -// generate_random(randomness, 64); -// auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); +TEST(Kyber768TestPortable, ModifiedCiphertextTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); -// generate_random(randomness, 32); -// auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); -// uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; -// modify_ciphertext(ctxt.fst.value, -// LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); -// libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_ciphertext(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); -// EXPECT_NE(0, -// memcmp(ctxt.snd, -// sharedSecret2, -// LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); -// uint8_t* implicitRejectionSharedSecret = -// compute_implicit_rejection_shared_secret( -// ctxt.fst.value, -// LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, -// key_pair.sk.value, -// LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); -// EXPECT_EQ(0, -// memcmp(implicitRejectionSharedSecret, -// sharedSecret2, -// LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); -// delete[] implicitRejectionSharedSecret; -// } + cout << "implicitRejectionSS: " << bytes_to_hex(bytes(implicitRejectionSharedSecret, implicitRejectionSharedSecret + 32)) << endl; + cout << "sharedSecret2: " << bytes_to_hex(bytes(sharedSecret2, sharedSecret2 + 32)) << endl; + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +#ifdef LIBCRUX_X64 +TEST(Kyber768TestAvx2, ModifiedCiphertextTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_ciphertext(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + + cout << "implicitRejectionSS: " << bytes_to_hex(bytes(implicitRejectionSharedSecret, implicitRejectionSharedSecret + 32)) << endl; + cout << "sharedSecret2: " << bytes_to_hex(bytes(sharedSecret2, sharedSecret2 + 32)) << endl; + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} +#endif // LIBCRUX_X64 // TEST(Kyber768Test, ModifiedSecretKeyTest) // { @@ -278,59 +327,93 @@ TEST(MlKem768TestPortable, ConsistencyTest) // delete[] implicitRejectionSharedSecret; // } -TEST(MlKem768Test, NISTKnownAnswerTest) +#ifdef LIBCRUX_X64 +TEST(MlKem768TestAvx2, NISTKnownAnswerTest) { // XXX: This should be done in a portable way. auto kats = read_kats("tests/mlkem768_nistkats.json"); for (auto kat : kats) { - // auto key_pair = - // libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); - -#ifdef LIBCRUX_X64 - auto key_pair_avx2 = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); -#endif + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); uint8_t pk_hash[32]; - // libcrux_sha3_sha256( - // EURYDICE_SLICE(key_pair.pk.value, 0, - // LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), - // pk_hash); - // EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + libcrux_sha3_sha256( + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + pk_hash); + EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); -#ifdef LIBCRUX_X64 + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + } +} +#endif // LIBCRUX_X64 + +TEST(MlKem768TestPortable, NISTKnownAnswerTest) +{ + // XXX: This should be done in a portable way. + auto kats = read_kats("tests/mlkem768_nistkats.json"); + + for (auto kat : kats) + { + auto key_pair = + libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); + + uint8_t pk_hash[32]; libcrux_sha3_sha256( - EURYDICE_SLICE(key_pair_avx2.pk.value, 0, - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), pk_hash); EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); -#endif - // uint8_t sk_hash[32]; - // libcrux_sha3_sha256( - // EURYDICE_SLICE(key_pair.sk.value, 0, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); - // EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); - - // auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( - // &key_pair.pk, kat.encapsulation_seed.data()); - // uint8_t ct_hash[32]; - // libcrux_sha3_sha256( - // EURYDICE_SLICE(ctxt.fst.value, 0, - // LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), - // ct_hash); - // EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); - // EXPECT_EQ(0, - // memcmp(ctxt.snd, - // kat.shared_secret.data(), - // LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); - - // uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - // libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - - // EXPECT_EQ(0, - // memcmp(ctxt.snd, - // sharedSecret2, - // LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } } From 582b342ab5c6d30ab05b676969e77fd981a397a2 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Fri, 7 Jun 2024 19:33:20 +0200 Subject: [PATCH 26/84] fixed test --- libcrux-ml-kem/c/tests/mlkem768.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index 2d07d800e..5244f046b 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -168,13 +168,16 @@ compute_implicit_rejection_shared_secret(uint8_t *ciphertext, { uint8_t *hashInput = new uint8_t[32 + ciphertext_size]; uint8_t *sharedSecret = new uint8_t[32]; + Eurydice_slice ss; + ss.ptr = (void*) sharedSecret; + ss.len = 32; std::copy(secret_key + (secret_key_size - 32), secret_key + secret_key_size, hashInput); std::copy(ciphertext, ciphertext + ciphertext_size, hashInput + 32); - libcrux_sha3_sha256(mk_slice(hashInput, 32 + ciphertext_size), sharedSecret); + libcrux_sha3_portable_shake256(ss,mk_slice(hashInput, 32 + ciphertext_size)); delete[] hashInput; return sharedSecret; @@ -245,8 +248,7 @@ TEST(Kyber768TestPortable, ModifiedCiphertextTest) key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); - cout << "implicitRejectionSS: " << bytes_to_hex(bytes(implicitRejectionSharedSecret, implicitRejectionSharedSecret + 32)) << endl; - cout << "sharedSecret2: " << bytes_to_hex(bytes(sharedSecret2, sharedSecret2 + 32)) << endl; + EXPECT_EQ(0, memcmp(implicitRejectionSharedSecret, sharedSecret2, From f52bb2a837c3cb84ef1480ed253a53afd7ce7198 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 7 Jun 2024 19:44:30 +0200 Subject: [PATCH 27/84] enable all tests --- libcrux-ml-kem/c/tests/mlkem768.cc | 195 ++++++++++++++++------------- 1 file changed, 111 insertions(+), 84 deletions(-) diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index 5244f046b..69b874e92 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -15,10 +15,6 @@ #include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" -#ifdef LIBCRUX_X64 -#include "libcrux_mlkem768_avx2.h" -#endif - using namespace std; typedef vector bytes; @@ -169,7 +165,7 @@ compute_implicit_rejection_shared_secret(uint8_t *ciphertext, uint8_t *hashInput = new uint8_t[32 + ciphertext_size]; uint8_t *sharedSecret = new uint8_t[32]; Eurydice_slice ss; - ss.ptr = (void*) sharedSecret; + ss.ptr = (void *)sharedSecret; ss.len = 32; std::copy(secret_key + (secret_key_size - 32), @@ -177,31 +173,12 @@ compute_implicit_rejection_shared_secret(uint8_t *ciphertext, hashInput); std::copy(ciphertext, ciphertext + ciphertext_size, hashInput + 32); - libcrux_sha3_portable_shake256(ss,mk_slice(hashInput, 32 + ciphertext_size)); + libcrux_sha3_portable_shake256(ss, mk_slice(hashInput, 32 + ciphertext_size)); delete[] hashInput; return sharedSecret; } -#ifdef LIBCRUX_X64 -TEST(MlKem768TestAvx2, ConsistencyTest) -{ - uint8_t randomness[64]; - for (int i = 0; i < 64; i++) - randomness[i] = 13; - auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); - auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); - - uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - - EXPECT_EQ(0, - memcmp(ctxt.snd, - sharedSecret2, - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); -} -#endif - TEST(MlKem768TestPortable, ConsistencyTest) { uint8_t randomness[64]; @@ -248,7 +225,6 @@ TEST(Kyber768TestPortable, ModifiedCiphertextTest) key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); - EXPECT_EQ(0, memcmp(implicitRejectionSharedSecret, sharedSecret2, @@ -256,88 +232,51 @@ TEST(Kyber768TestPortable, ModifiedCiphertextTest) delete[] implicitRejectionSharedSecret; } -#ifdef LIBCRUX_X64 -TEST(Kyber768TestAvx2, ModifiedCiphertextTest) +TEST(Kyber768TestPortable, ModifiedSecretKeyTest) { uint8_t randomness[64]; generate_random(randomness, 64); - auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); generate_random(randomness, 32); - auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - modify_ciphertext(ctxt.fst.value, - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); - libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + modify_secret_key( + key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, false); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); EXPECT_NE(0, memcmp(ctxt.snd, sharedSecret2, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + modify_secret_key( + ctxt.snd, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, true); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + uint8_t *implicitRejectionSharedSecret = compute_implicit_rejection_shared_secret( ctxt.fst.value, LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); - - cout << "implicitRejectionSS: " << bytes_to_hex(bytes(implicitRejectionSharedSecret, implicitRejectionSharedSecret + 32)) << endl; - cout << "sharedSecret2: " << bytes_to_hex(bytes(sharedSecret2, sharedSecret2 + 32)) << endl; EXPECT_EQ(0, memcmp(implicitRejectionSharedSecret, sharedSecret2, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); delete[] implicitRejectionSharedSecret; } -#endif // LIBCRUX_X64 - -// TEST(Kyber768Test, ModifiedSecretKeyTest) -// { -// uint8_t randomness[64]; -// generate_random(randomness, 64); -// auto key_pair = libcrux_ml_kem_mlkem768_generate_key_pair(randomness); - -// generate_random(randomness, 32); -// auto ctxt = libcrux_ml_kem_mlkem768_encapsulate(&key_pair.pk, randomness); - -// uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; -// modify_secret_key( -// key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, false); -// libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - -// EXPECT_NE(0, -// memcmp(ctxt.snd, -// sharedSecret2, -// LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); - -// modify_secret_key( -// ctxt.snd, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, true); -// libcrux_ml_kem_mlkem768_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); - -// uint8_t* implicitRejectionSharedSecret = -// compute_implicit_rejection_shared_secret( -// ctxt.fst.value, -// LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, -// key_pair.sk.value, -// LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); -// EXPECT_EQ(0, -// memcmp(implicitRejectionSharedSecret, -// sharedSecret2, -// LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); -// delete[] implicitRejectionSharedSecret; -// } -#ifdef LIBCRUX_X64 -TEST(MlKem768TestAvx2, NISTKnownAnswerTest) +TEST(MlKem768TestPortable, NISTKnownAnswerTest) { // XXX: This should be done in a portable way. auto kats = read_kats("tests/mlkem768_nistkats.json"); for (auto kat : kats) { - auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); + auto key_pair = + libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); uint8_t pk_hash[32]; libcrux_sha3_sha256( @@ -351,7 +290,7 @@ TEST(MlKem768TestAvx2, NISTKnownAnswerTest) mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); - auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate( + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( &key_pair.pk, kat.encapsulation_seed.data()); uint8_t ct_hash[32]; libcrux_sha3_sha256( @@ -365,7 +304,7 @@ TEST(MlKem768TestAvx2, NISTKnownAnswerTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); EXPECT_EQ(0, memcmp(ctxt.snd, @@ -373,17 +312,104 @@ TEST(MlKem768TestAvx2, NISTKnownAnswerTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } } -#endif // LIBCRUX_X64 -TEST(MlKem768TestPortable, NISTKnownAnswerTest) +#ifdef LIBCRUX_X64 +#include "libcrux_mlkem768_avx2.h" + +TEST(MlKem768TestAvx2, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + randomness[i] = 13; + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} + +TEST(Kyber768TestAvx2, ModifiedCiphertextTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_ciphertext(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(Kyber768TestAvx2, ModifiedSecretKeyTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_secret_key( + key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, false); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + modify_secret_key( + ctxt.snd, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, true); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(MlKem768TestAvx2, NISTKnownAnswerTest) { // XXX: This should be done in a portable way. auto kats = read_kats("tests/mlkem768_nistkats.json"); for (auto kat : kats) { - auto key_pair = - libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); uint8_t pk_hash[32]; libcrux_sha3_sha256( @@ -397,7 +423,7 @@ TEST(MlKem768TestPortable, NISTKnownAnswerTest) mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); - auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate( &key_pair.pk, kat.encapsulation_seed.data()); uint8_t ct_hash[32]; libcrux_sha3_sha256( @@ -411,7 +437,7 @@ TEST(MlKem768TestPortable, NISTKnownAnswerTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; - libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); EXPECT_EQ(0, memcmp(ctxt.snd, @@ -419,3 +445,4 @@ TEST(MlKem768TestPortable, NISTKnownAnswerTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } } +#endif // LIBCRUX_X64 From 5c93ae41992a6988312d4ac79ca77767bca35b71 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 7 Jun 2024 20:18:16 +0200 Subject: [PATCH 28/84] drop libcrux-sha3/c --- libcrux-sha3/c/core.c | 28 - libcrux-sha3/c/core.h | 33 - libcrux-sha3/c/eurydice_glue.h | 240 -- libcrux-sha3/c/internal/core.h | 66 - libcrux-sha3/c/internal/libcrux_sha3.h | 31 - libcrux-sha3/c/internal/libcrux_sha3_avx2.h | 463 --- libcrux-sha3/c/libcrux_sha3.c | 3268 ------------------- libcrux-sha3/c/libcrux_sha3.h | 951 ------ libcrux-sha3/c/libcrux_sha3_avx2.c | 2721 --------------- libcrux-sha3/c/libcrux_sha3_avx2.h | 170 - libcrux-sha3/c/libcrux_sha3_neon.c | 179 - libcrux-sha3/c/libcrux_sha3_neon.h | 68 - 12 files changed, 8218 deletions(-) delete mode 100644 libcrux-sha3/c/core.c delete mode 100644 libcrux-sha3/c/core.h delete mode 100644 libcrux-sha3/c/eurydice_glue.h delete mode 100644 libcrux-sha3/c/internal/core.h delete mode 100644 libcrux-sha3/c/internal/libcrux_sha3.h delete mode 100644 libcrux-sha3/c/internal/libcrux_sha3_avx2.h delete mode 100644 libcrux-sha3/c/libcrux_sha3.c delete mode 100644 libcrux-sha3/c/libcrux_sha3.h delete mode 100644 libcrux-sha3/c/libcrux_sha3_avx2.c delete mode 100644 libcrux-sha3/c/libcrux_sha3_avx2.h delete mode 100644 libcrux-sha3/c/libcrux_sha3_neon.c delete mode 100644 libcrux-sha3/c/libcrux_sha3_neon.h diff --git a/libcrux-sha3/c/core.c b/libcrux-sha3/c/core.c deleted file mode 100644 index 7275df06c..000000000 --- a/libcrux-sha3/c/core.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#include "internal/core.h" - -void -core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U] -) -{ - if (self.tag == core_result_Ok) - { - uint8_t f0[8U]; - memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof (uint8_t)); - memcpy(ret, f0, (size_t)8U * sizeof (uint8_t)); - } - else - { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - diff --git a/libcrux-sha3/c/core.h b/libcrux-sha3/c/core.h deleted file mode 100644 index 35544bbd3..000000000 --- a/libcrux-sha3/c/core.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __core_H -#define __core_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" - -typedef struct core_ops_range_Range__size_t_s -{ - size_t start; - size_t end; -} -core_ops_range_Range__size_t; - -extern uint8_t Eurydice_bitand_pv_u8(uint8_t *x, uint8_t y); - -extern uint8_t Eurydice_shr_pv_u8(uint8_t *x, int32_t y); - -#if defined(__cplusplus) -} -#endif - -#define __core_H_DEFINED -#endif diff --git a/libcrux-sha3/c/eurydice_glue.h b/libcrux-sha3/c/eurydice_glue.h deleted file mode 100644 index 0235fbeea..000000000 --- a/libcrux-sha3/c/eurydice_glue.h +++ /dev/null @@ -1,240 +0,0 @@ -#pragma once - -#if defined(__cplusplus) -extern "C" { -#endif - -#include -#include -#include -#include -#include - -#include "krml/lowstar_endianness.h" -#include "krml/internal/target.h" - -#define LowStar_Ignore_ignore(e, t, _ret_t) ((void)e) - -// SLICES, ARRAYS, ETC. - -// We represent a slice as a pair of an (untyped) pointer, along with the length of the slice, i.e. -// the number of elements in the slice (this is NOT the number of bytes). This design choice has two -// important consequences. -// - if you need to use `ptr`, you MUST cast it to a proper type *before* performing pointer -// arithmetic on it (remember that C desugars pointer arithmetic based on the type of the address) -// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you need to multiply it -// by sizeof t, where t is the type of the elements. -typedef struct { - void *ptr; - size_t len; -} Eurydice_slice; - -// Helper macro to create a slice out of a pointer x, a start index in x (included), and an end -// index in x (excluded). The argument x must be suitably cast to something that can decay (see -// remark above about how pointer arithmetic works in C), meaning either pointer or array type. -#define EURYDICE_SLICE(x, start, end) ((Eurydice_slice){ .ptr = (void*)(x + start), .len = end - start }) -#define EURYDICE_SLICE_LEN(s, _) s.len -#define Eurydice_slice_index(s, i, t, _ret_t) (((t*) s.ptr)[i]) -#define Eurydice_slice_index_outparam(s, i, dst, t, _ret_t) (memcpy(dst, ((t*) s.ptr)[i], sizeof(t))) -#define Eurydice_slice_subslice(s, r, t, _, _ret_t) EURYDICE_SLICE((t*)s.ptr, r.start, r.end) -#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _, _ret_t) EURYDICE_SLICE((t*)s.ptr, 0, subslice_end_pos) -#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _, _ret_t) EURYDICE_SLICE((t*)s.ptr, subslice_start_pos, s.len) -#define Eurydice_array_to_slice(end, x, t, _ret_t) EURYDICE_SLICE(x, 0, end) /* x is already at an array type, no need for cast */ -#define Eurydice_array_to_subslice(_arraylen, x, r, t, _, _ret_t) EURYDICE_SLICE((t*)x, r.start, r.end) -#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t, _ret_t) EURYDICE_SLICE((t*)x, 0, r) -#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t, _ret_t) EURYDICE_SLICE((t*)x, r, size) -#define Eurydice_array_repeat(dst, len, init, t, _ret_t) ERROR "should've been desugared" -#define core_slice___Slice_T___len(s, t, _ret_t) EURYDICE_SLICE_LEN(s, t) -#define core_slice___Slice_T___copy_from_slice(dst, src, t, _ret_t) memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) -#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) ((Eurydice_slice){ .ptr = ptr_, .len = len_ }) - -#define core_array___core__clone__Clone_for__Array_T__N___20__clone(len, src, dst, elem_type, _ret_t) \ - (memcpy(dst, src, len * sizeof(elem_type))) -#define core_array_TryFromSliceError uint8_t - -#define Eurydice_array_eq(sz, a1, a2, t, _, _ret_t) (memcmp(a1, a2, sz * sizeof(t)) == 0) -#define core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq Eurydice_array_eq - -#define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ - ((ret_t){ \ - .fst = EURYDICE_SLICE((element_type*)slice.ptr, 0, mid), \ - .snd = EURYDICE_SLICE((element_type*)slice.ptr, mid, slice.len)}) -#define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ - ((ret_t){ \ - .fst = EURYDICE_SLICE((element_type*)slice.ptr, 0, mid), \ - .snd = EURYDICE_SLICE((element_type*)slice.ptr, mid, slice.len)}) - - -// Can't have a flexible array as a member of a union -- this violates strict aliasing rules. -typedef struct -{ - uint8_t tag; - uint8_t case_Ok[]; -} -result_tryfromslice_flexible; - -// See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) Eurydice_slice_to_array3((result_tryfromslice_flexible *)dst, src, sizeof(t_arr)) - -static inline void Eurydice_slice_to_array3(result_tryfromslice_flexible *dst, Eurydice_slice src, size_t sz) { - dst->tag = 0; - memcpy(dst->case_Ok, src.ptr, sz); -} - -// CORE STUFF (conversions, endianness, ...) - -static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { - uint32_t x = htobe32(src); - memcpy(dst, &x, 4); -} - -static inline void core_num__u64_9__to_le_bytes(uint64_t v,uint8_t buf[8]) { - store64_le(buf,v); -} -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { - return load64_le(buf); -} - -static inline int64_t -core_convert_num___core__convert__From_i32__for_i64__59__from(int32_t x) { - return x; -} - -// unsigned overflow wraparound semantics in C -static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { return x + y; } -static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { return x - y; } - -static inline void core_ops_arith__i32_319__add_assign(int32_t *x0, int32_t *x1) { - *x0 = *x0 + *x1; -} - -static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v) { return (*p) & v; } -static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { return (*p) >> v; } - -// ITERATORS - -#define core_num_nonzero_NonZeroUsize size_t -#define Eurydice_range_iter_next(iter_ptr, t, ret_t) ( \ - ((iter_ptr)->start == (iter_ptr)->end) ? \ - ((ret_t) { .tag = core_option_None }) : \ - ((ret_t) { .tag = core_option_Some, .f0 = (iter_ptr)->start++ }) \ - ) - -#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next Eurydice_range_iter_next - -// See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_into_iter(x, t, _ret_t) (x) -#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter Eurydice_into_iter - -typedef struct { - Eurydice_slice slice; - size_t chunk_size; -} Eurydice_chunks; - - -// Can't use macros Eurydice_slice_subslice_{to,from} because they require a type, and this static -// inline function cannot receive a type as an argument. Instead, we receive the element size and -// use it to peform manual offset computations rather than going through the macros. -static inline Eurydice_slice chunk_next(Eurydice_chunks *chunks, size_t element_size) { - size_t chunk_size = chunks->slice.len >= chunks->chunk_size ? chunks->chunk_size : chunks->slice.len; - Eurydice_slice curr_chunk = ((Eurydice_slice) { .ptr = chunks->slice.ptr, .len = chunk_size }); - chunks->slice = ((Eurydice_slice) { - .ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size, - .len = chunks->slice.len - chunk_size - }); - return curr_chunk; -} - -#define core_slice___Slice_T___chunks(slice_, sz_, t, _ret_t) ((Eurydice_chunks){ .slice = slice_, .chunk_size = sz_ }) -#define core_slice___Slice_T___chunks_exact(slice_, sz_, t, _ret_t) ((Eurydice_chunks){ \ - .slice = { .ptr = slice_.ptr, .len = slice_.len - (slice_.len % sz_) }, \ - .chunk_size = sz_ }) -#define core_slice_iter_Chunks Eurydice_chunks -#define core_slice_iter_ChunksExact Eurydice_chunks -#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next(iter, t, ret_t) \ - (((iter)->slice.len == 0) ? \ - ((ret_t) { .tag = core_option_None }) : \ - ((ret_t){ \ - .tag = core_option_Some, \ - .f0 = chunk_next(iter, sizeof(t)) })) -#define core_slice_iter__core__slice__iter__ChunksExact__a__T__89__next(iter, t, _ret_t) \ - core_slice_iter__core__slice__iter__Chunks__a__T__70__next(iter, t) - -typedef struct { - Eurydice_slice s; - size_t index; -} Eurydice_slice_iterator; - -#define core_slice___Slice_T___iter(x, t, _ret_t) ((Eurydice_slice_iterator){ .s = x, .index = 0 }) -#define core_slice_iter_Iter Eurydice_slice_iterator -#define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, ret_t) \ - (((iter)->index == (iter)->s.len) ? \ - ((ret_t) { .tag = core_option_None }) : \ - ((ret_t){ \ - .tag = core_option_Some, \ - .f0 = ((iter)->index++, &((t*)((iter)->s.ptr))[(iter)->index-1]) })) - -// STRINGS - -typedef const char *Prims_string; - -// MISC (UNTESTED) - -typedef void *core_fmt_Formatter; -typedef void *core_fmt_Arguments; -typedef void *core_fmt_rt_Argument; -#define core_fmt_rt__core__fmt__rt__Argument__a__1__new_display(x1, x2, x3, x4) NULL - -// VECTORS (ANCIENT, POSSIBLY UNTESTED) - -/* For now these are passed by value -- three words. We could conceivably change - * the representation to heap-allocate this struct and only pass around the - * pointer (one word). */ -typedef struct { - void *ptr; - size_t len; /* the number of elements */ - size_t alloc_size; /* the size of the allocation, in number of BYTES */ -} Eurydice_vec_s, *Eurydice_vec; - -/* Here, we set everything to zero rather than use a non-standard GCC - * statement-expression -- this suitably initializes ptr to NULL and len and - * size to 0. */ -#define EURYDICE_VEC_NEW(_) calloc(1, sizeof(Eurydice_vec_s)) -#define EURYDICE_VEC_PUSH(v, x, t) \ - do { \ - /* Grow the vector if capacity has been reached. */ \ - if (v->len == v->alloc_size/sizeof(t)) { \ - /* Assuming that this does not exceed SIZE_MAX, because code proven \ - * correct by Aeneas. Would this even happen in practice? */ \ - size_t new_size; \ - if (v->alloc_size == 0) \ - new_size = 8 * sizeof(t); \ - else if (v->alloc_size <= SIZE_MAX/2) \ - /* TODO: discuss growth policy */ \ - new_size = 2 * v->alloc_size; \ - else \ - new_size = (SIZE_MAX/sizeof(t))*sizeof(t); \ - v->ptr = realloc(v->ptr, new_size); \ - v->alloc_size = new_size; \ - } \ - ((t*)v->ptr)[v->len] = x; \ - v->len++; \ - } while (0) - -#define EURYDICE_VEC_DROP(v, t) \ - do { \ - free(v->ptr); \ - free(v); \ - } while (0) - -#define EURYDICE_VEC_INDEX(v, i, t) &((t*) v->ptr)[i] -#define EURYDICE_VEC_LEN(v, t) (v)->len - -/* TODO: remove GCC-isms */ -#define EURYDICE_BOX_NEW(x, t) ({ t *p = malloc(sizeof(t)); *p = x; p; }) - -#define EURYDICE_REPLACE(ptr, new_v, t) ({ t old_v = *ptr; *ptr = new_v; old_v; }) - -#if defined(__cplusplus) -} -#endif diff --git a/libcrux-sha3/c/internal/core.h b/libcrux-sha3/c/internal/core.h deleted file mode 100644 index 168229151..000000000 --- a/libcrux-sha3/c/internal/core.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __internal_core_H -#define __internal_core_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../core.h" -#include "eurydice_glue.h" - -#define core_option_None 0 -#define core_option_Some 1 - -typedef uint8_t core_option_Option__size_t_tags; - -typedef struct core_option_Option__size_t_s -{ - core_option_Option__size_t_tags tag; - size_t f0; -} -core_option_Option__size_t; - -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); - -static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); - -extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none(core_fmt_rt_Argument x0[0U]); - -extern core_fmt_Arguments -core_fmt__core__fmt__Arguments__a__2__new_v1(Eurydice_slice x0, Eurydice_slice x1); - -#define core_result_Ok 0 -#define core_result_Err 1 - -typedef uint8_t core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_tags; - -typedef struct core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s -{ - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[8U]; - core_array_TryFromSliceError case_Err; - } - val; -} -core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; - -void -core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, - uint8_t ret[8U] -); - -#if defined(__cplusplus) -} -#endif - -#define __internal_core_H_DEFINED -#endif diff --git a/libcrux-sha3/c/internal/libcrux_sha3.h b/libcrux-sha3/c/internal/libcrux_sha3.h deleted file mode 100644 index 5ca4022b5..000000000 --- a/libcrux-sha3/c/internal/libcrux_sha3.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __internal_libcrux_sha3_H -#define __internal_libcrux_sha3_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "internal/core.h" -#include "../libcrux_sha3.h" -#include "eurydice_glue.h" - -typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s -{ - Eurydice_slice fst; - Eurydice_slice snd; -} -K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_sha3_H_DEFINED -#endif diff --git a/libcrux-sha3/c/internal/libcrux_sha3_avx2.h b/libcrux-sha3/c/internal/libcrux_sha3_avx2.h deleted file mode 100644 index 8bf44a565..000000000 --- a/libcrux-sha3/c/internal/libcrux_sha3_avx2.h +++ /dev/null @@ -1,463 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __internal_libcrux_sha3_avx2_H -#define __internal_libcrux_sha3_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "internal/libcrux_sha3.h" -#include "internal/core.h" -#include "../libcrux_sha3_avx2.h" -#include "eurydice_glue.h" - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -); - -void -libcrux_sha3_simd_avx2_store_block___168size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U] -); - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___168size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t b[4U][200U] -); - -void -libcrux_sha3_simd_avx2_load_block_full___168size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t blocks[4U][200U] -); - -void -libcrux_sha3_simd_avx2_load_block___168size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U] -); - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -); - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t ret[4U][200U] -); - -void -libcrux_sha3_simd_avx2_store_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t ret[4U][200U] -); - -void -libcrux_sha3_simd_avx2_store_block___136size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U] -); - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___136size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t b[4U][200U] -); - -void -libcrux_sha3_simd_avx2_load_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t blocks[4U][200U] -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___14int32_t_50int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___14int32_t_50int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___14int32_t_50int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___8int32_t_56int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___8int32_t_56int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___8int32_t_56int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___39int32_t_25int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___39int32_t_25int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___39int32_t_25int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___20int32_t_44int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___20int32_t_44int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___20int32_t_44int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___27int32_t_37int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___27int32_t_37int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___27int32_t_37int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___56int32_t_8int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___56int32_t_8int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___56int32_t_8int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___21int32_t_43int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___21int32_t_43int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___21int32_t_43int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___25int32_t_39int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___25int32_t_39int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___25int32_t_39int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___55int32_t_9int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___55int32_t_9int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___55int32_t_9int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___28int32_t_36int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___28int32_t_36int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___28int32_t_36int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___61int32_t_3int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___61int32_t_3int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___61int32_t_3int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___15int32_t_49int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___15int32_t_49int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___15int32_t_49int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___43int32_t_21int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___43int32_t_21int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___43int32_t_21int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___6int32_t_58int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___6int32_t_58int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___6int32_t_58int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___62int32_t_2int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___62int32_t_2int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___62int32_t_2int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___2int32_t_62int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___2int32_t_62int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___2int32_t_62int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___45int32_t_19int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___45int32_t_19int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___45int32_t_19int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___10int32_t_54int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___10int32_t_54int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___10int32_t_54int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___44int32_t_20int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___44int32_t_20int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___44int32_t_20int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___1int32_t_63int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___1int32_t_63int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___18int32_t_46int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___18int32_t_46int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___18int32_t_46int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___41int32_t_23int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___41int32_t_23int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___41int32_t_23int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___3int32_t_61int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___3int32_t_61int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___3int32_t_61int32_t(core_core_arch_x86___m256i x); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___36int32_t_28int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___36int32_t_28int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___36int32_t_28int32_t(core_core_arch_x86___m256i x); - -void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block___136size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -); - -void -libcrux_sha3_simd_avx2_load_block___136size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U] -); - -core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(core_core_arch_x86___m256i x); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_sha3_avx2_H_DEFINED -#endif diff --git a/libcrux-sha3/c/libcrux_sha3.c b/libcrux-sha3/c/libcrux_sha3.c deleted file mode 100644 index c82f8da13..000000000 --- a/libcrux-sha3/c/libcrux_sha3.c +++ /dev/null @@ -1,3268 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#include "internal/libcrux_sha3.h" - -#include "internal/core.h" - -size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) -{ - size_t uu____0; - switch (mode) - { - case libcrux_sha3_Sha224: - { - uu____0 = (size_t)28U; - break; - } - case libcrux_sha3_Sha256: - { - uu____0 = (size_t)32U; - break; - } - case libcrux_sha3_Sha384: - { - uu____0 = (size_t)48U; - break; - } - case libcrux_sha3_Sha512: - { - uu____0 = (size_t)64U; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); - KRML_HOST_EXIT(253U); - } - } - return uu____0; -} - -inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, Eurydice_slice payload) -{ - libcrux_sha3_portable_sha224(digest, payload); -} - -inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) -{ - uint8_t out[28U] = { 0U }; - libcrux_sha3_sha224_ema(Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)28U * sizeof (uint8_t)); -} - -inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, Eurydice_slice payload) -{ - libcrux_sha3_portable_sha256(digest, payload); -} - -inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) -{ - uint8_t out[32U] = { 0U }; - libcrux_sha3_sha256_ema(Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)32U * sizeof (uint8_t)); -} - -inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, Eurydice_slice payload) -{ - libcrux_sha3_portable_sha384(digest, payload); -} - -inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) -{ - uint8_t out[48U] = { 0U }; - libcrux_sha3_sha384_ema(Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)48U * sizeof (uint8_t)); -} - -inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, Eurydice_slice payload) -{ - libcrux_sha3_portable_sha512(digest, payload); -} - -inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) -{ - uint8_t out[64U] = { 0U }; - libcrux_sha3_sha512_ema(Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), - data); - memcpy(ret, out, (size_t)64U * sizeof (uint8_t)); -} - -const -size_t -libcrux_sha3_generic_keccak__ROTC[24U] = - { - (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, (size_t)44U, (size_t)6U, - (size_t)55U, (size_t)20U, (size_t)3U, (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, - (size_t)41U, (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, (size_t)2U, - (size_t)61U, (size_t)56U, (size_t)14U - }; - -const -size_t -libcrux_sha3_generic_keccak__PI[24U] = - { - (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, (size_t)9U, (size_t)10U, - (size_t)16U, (size_t)22U, (size_t)1U, (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, - (size_t)4U, (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, (size_t)8U, - (size_t)14U, (size_t)15U, (size_t)21U - }; - -const -uint64_t -libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = - { - 1ULL, 32898ULL, 9223372036854808714ULL, 9223372039002292224ULL, 32907ULL, 2147483649ULL, - 9223372039002292353ULL, 9223372036854808585ULL, 138ULL, 136ULL, 2147516425ULL, 2147483658ULL, - 2147516555ULL, 9223372036854775947ULL, 9223372036854808713ULL, 9223372036854808579ULL, - 9223372036854808578ULL, 9223372036854775936ULL, 32778ULL, 9223372039002259466ULL, - 9223372039002292353ULL, 9223372036854808704ULL, 2147483649ULL, 9223372039002292232ULL - }; - -inline uint64_t -libcrux_sha3_portable_keccak__veor5q_u64( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -) -{ - uint64_t ab = a ^ b; - uint64_t cd = c ^ d; - uint64_t abcd = ab ^ cd; - return abcd ^ e; -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; -} - -inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b) -{ - uint64_t uu____0 = a; - return uu____0 ^ libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); -} - -inline uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) -{ - return a ^ (b & ~c); -} - -inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) -{ - return a ^ c; -} - -inline void -libcrux_sha3_portable_keccak_slice_1( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -) -{ - ret[0U] = - Eurydice_slice_subslice(a[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); -} - -inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], size_t mid) -{ - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at_mut(out[0U], - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ lit; - lit.fst[0U] = out00; - lit.snd[0U] = out01; - return lit; -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(void) -{ - return 0ULL; -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -) -{ - return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( - uint64_t a, - uint64_t b, - uint64_t c -) -{ - return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( - uint64_t a, - uint64_t c -) -{ - return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( - uint64_t a, - uint64_t b -) -{ - return a ^ b; -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, a, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret0[1U]; - libcrux_sha3_portable_keccak_slice_1(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (Eurydice_slice)); -} - -inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - Eurydice_slice a[1U], - size_t mid -) -{ - return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); -} - -libcrux_sha3_Algorithm -libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from(uint32_t v) -{ - libcrux_sha3_Algorithm uu____0; - switch (v) - { - case 1U: - { - uu____0 = libcrux_sha3_Sha224; - break; - } - case 2U: - { - uu____0 = libcrux_sha3_Sha256; - break; - } - case 3U: - { - uu____0 = libcrux_sha3_Sha384; - break; - } - case 4U: - { - uu____0 = libcrux_sha3_Sha512; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); - } - } - return uu____0; -} - -uint32_t -libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( - libcrux_sha3_Algorithm v -) -{ - uint32_t uu____0; - switch (v) - { - case libcrux_sha3_Sha224: - { - uu____0 = 1U; - break; - } - case libcrux_sha3_Sha256: - { - uu____0 = 2U; - break; - } - case libcrux_sha3_Sha384: - { - uu____0 = 3U; - break; - } - case libcrux_sha3_Sha512: - { - uu____0 = 4U; - break; - } - default: - { - KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); - KRML_HOST_EXIT(253U); - } - } - return uu____0; -} - -inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( - void -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; - lit.st[0U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[0U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[1U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[2U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[3U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - lit.st[4U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); - return lit; -} - -inline void -libcrux_sha3_portable_keccak_load_block___72size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) - { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, uu____1); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); -} - -inline uint64_t libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) -{ - return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; -} - -inline uint64_t -libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, uint64_t b) -{ - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(ab); -} - -inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( - uint64_t a, - uint64_t b -) -{ - return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][0U], - s->st[1U][0U], - s->st[2U][0U], - s->st[3U][0U], - s->st[4U][0U]); - uint64_t - uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][1U], - s->st[1U][1U], - s->st[2U][1U], - s->st[3U][1U], - s->st[4U][1U]); - uint64_t - uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][2U], - s->st[1U][2U], - s->st[2U][2U], - s->st[3U][2U], - s->st[4U][2U]); - uint64_t - uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][3U], - s->st[1U][3U], - s->st[2U][3U], - s->st[3U][3U], - s->st[4U][3U]); - uint64_t - c[5U] = - { - uu____0, uu____1, uu____2, uu____3, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5(s->st[0U][4U], - s->st[1U][4U], - s->st[2U][4U], - s->st[3U][4U], - s->st[4U][4U]) - }; - uint64_t - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)0U - + (size_t)4U) - % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)1U - + (size_t)4U) - % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____6 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)2U - + (size_t)4U) - % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - uint64_t - uu____7 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)3U - + (size_t)4U) - % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - uint64_t - t[5U] = - { - uu____4, uu____5, uu____6, uu____7, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor(c[((size_t)4U - + (size_t)4U) - % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U]) - }; - uint64_t - uu____8 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor(s->st[0U][0U], - t[0U]); - s->st[0U][0U] = uu____8; - uint64_t - uu____9 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], - t[0U]); - s->st[1U][0U] = uu____9; - uint64_t - uu____10 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], - t[0U]); - s->st[2U][0U] = uu____10; - uint64_t - uu____11 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], - t[0U]); - s->st[3U][0U] = uu____11; - uint64_t - uu____12 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], - t[0U]); - s->st[4U][0U] = uu____12; - uint64_t - uu____13 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], - t[1U]); - s->st[0U][1U] = uu____13; - uint64_t - uu____14 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], - t[1U]); - s->st[1U][1U] = uu____14; - uint64_t - uu____15 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], - t[1U]); - s->st[2U][1U] = uu____15; - uint64_t - uu____16 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], - t[1U]); - s->st[3U][1U] = uu____16; - uint64_t - uu____17 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], - t[1U]); - s->st[4U][1U] = uu____17; - uint64_t - uu____18 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], - t[2U]); - s->st[0U][2U] = uu____18; - uint64_t - uu____19 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], - t[2U]); - s->st[1U][2U] = uu____19; - uint64_t - uu____20 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], - t[2U]); - s->st[2U][2U] = uu____20; - uint64_t - uu____21 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], - t[2U]); - s->st[3U][2U] = uu____21; - uint64_t - uu____22 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], - t[2U]); - s->st[4U][2U] = uu____22; - uint64_t - uu____23 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], - t[3U]); - s->st[0U][3U] = uu____23; - uint64_t - uu____24 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], - t[3U]); - s->st[1U][3U] = uu____24; - uint64_t - uu____25 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], - t[3U]); - s->st[2U][3U] = uu____25; - uint64_t - uu____26 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], - t[3U]); - s->st[3U][3U] = uu____26; - uint64_t - uu____27 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], - t[3U]); - s->st[4U][3U] = uu____27; - uint64_t - uu____28 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], - t[4U]); - s->st[0U][4U] = uu____28; - uint64_t - uu____29 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], - t[4U]); - s->st[1U][4U] = uu____29; - uint64_t - uu____30 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], - t[4U]); - s->st[2U][4U] = uu____30; - uint64_t - uu____31 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], - t[4U]); - s->st[3U][4U] = uu____31; - uint64_t - uu____32 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], - t[4U]); - s->st[4U][4U] = uu____32; -} - -inline void -libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - uint64_t old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, - s->st, - old, - uint64_t [5U], - void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -inline void -libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - uint64_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof (uint64_t [5U])); - for (size_t i0 = (size_t)0U; i0 < (size_t)5U; i0++) - { - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)5U; i++) - { - size_t j = i; - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor(s->st[i1][j], - old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0; - } - } -} - -inline void -libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - size_t i -) -{ - uint64_t - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant(s->st[0U][0U], - libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -inline void -libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -) -{ - for (size_t i = (size_t)0U; i < (size_t)24U; i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_pi__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_chi__uint64_t_1size_t(s); - libcrux_sha3_generic_keccak_iota__uint64_t_1size_t(s, i0); - } -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_load_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, buf); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak_load_block_full___72size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)72U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)72U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_store_block___72size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak_store_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_store_block___72size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - libcrux_sha3_portable_keccak_store_block___72size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)72U, - (size_t)72U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)72U; - size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)72U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)72U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___72size_t_6uint8_t(buf0, buf); -} - -inline void -libcrux_sha3_portable_keccak_load_block___144size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) - { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_load_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, buf); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak_load_block_full___144size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)144U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)144U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_store_block___144size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak_store_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_store_block___144size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - libcrux_sha3_portable_keccak_store_block___144size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)144U, - (size_t)144U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)144U; - size_t last = outlen - outlen % (size_t)144U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)144U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)144U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___144size_t_6uint8_t(buf0, buf); -} - -inline void -libcrux_sha3_portable_keccak_load_block___136size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) - { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_load_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, buf); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak_load_block_full___136size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_store_block___136size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak_store_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_store_block___136size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - libcrux_sha3_portable_keccak_store_block___136size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)136U, - (size_t)136U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___136size_t_6uint8_t(buf0, buf); -} - -inline void -libcrux_sha3_portable_keccak_load_block___104size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) - { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_load_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, buf); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak_load_block_full___104size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)104U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)104U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_store_block___104size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak_store_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_store_block___104size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - libcrux_sha3_portable_keccak_store_block___104size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)104U, - (size_t)104U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)104U; - size_t last = outlen - outlen % (size_t)104U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)104U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)104U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___104size_t_6uint8_t(buf0, buf); -} - -inline void -libcrux_sha3_portable_keccak_load_block___168size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) - { - size_t i0 = i; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, - Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, - uint8_t [8U], - void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError(dst, - ret); - uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - uint64_t (*uu____0)[5U] = a; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, b, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -) -{ - uint64_t (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_load_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, buf); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -) -{ - uint64_t (*uu____0)[5U] = a; - uint8_t uu____1[1U][200U]; - memcpy(uu____1, b, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak_load_block_full___168size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_portable_keccak_store_block___168size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak_store_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t out[200U] = { 0U }; - uint64_t (*uu____0)[5U] = s; - Eurydice_slice - buf[1U] = { Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice) }; - libcrux_sha3_portable_keccak_store_block___168size_t(uu____0, buf); - uint8_t uu____1[200U]; - memcpy(uu____1, out, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____1, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -) -{ - uint8_t ret0[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -) -{ - libcrux_sha3_portable_keccak_store_block___168size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)168U, - (size_t)168U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)168U; - size_t last = outlen - outlen % (size_t)168U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)168U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___168size_t_31uint8_t(buf0, buf); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[1U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U; - } - uint64_t (*uu____1)[5U] = s->st; - uint8_t uu____2[1U][200U]; - memcpy(uu____2, blocks, (size_t)1U * sizeof (uint8_t [200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); -} - -inline void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____1, - i0 * (size_t)136U, - (size_t)136U, - ret); - libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t(uu____0, ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, data, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n(uu____3, - core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, - ret); - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t(uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t(&s, out); - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t(&s, o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o1, - (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -) -{ - Eurydice_slice uu____0[1U]; - memcpy(uu____0, data, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t(uu____0, out); -} - -inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, Eurydice_slice data) -{ - Eurydice_slice buf0[1U] = { data }; - Eurydice_slice buf[1U] = { digest }; - libcrux_sha3_portable_keccakx1___136size_t_31uint8_t(buf0, buf); -} - -inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self -) -{ - return self[0U]; -} - -inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_incremental_shake128_init(void) -{ - return - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); -} - -inline void -libcrux_sha3_portable_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice data0 -) -{ - Eurydice_slice buf[1U] = { data0 }; - libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t(s, buf); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -) -{ - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(out, - (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ - uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n(o10, - (size_t)168U); - Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof (Eurydice_slice)); - Eurydice_slice o2[1U]; - memcpy(o2, uu____1.snd, (size_t)1U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o1); - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, o2); -} - -inline void -libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -) -{ - Eurydice_slice buf[1U] = { out0 }; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t(s, buf); -} - -inline void -libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -) -{ - Eurydice_slice buf[1U] = { out0 }; - libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t(s, buf); -} - diff --git a/libcrux-sha3/c/libcrux_sha3.h b/libcrux-sha3/c/libcrux_sha3.h deleted file mode 100644 index 66384185c..000000000 --- a/libcrux-sha3/c/libcrux_sha3.h +++ /dev/null @@ -1,951 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __libcrux_sha3_H -#define __libcrux_sha3_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "core.h" -#include "eurydice_glue.h" - -#define libcrux_sha3_Sha224 0 -#define libcrux_sha3_Sha256 1 -#define libcrux_sha3_Sha384 2 -#define libcrux_sha3_Sha512 3 - -typedef uint8_t libcrux_sha3_Algorithm; - -size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode); - -void libcrux_sha3_sha224_ema(Eurydice_slice digest, Eurydice_slice payload); - -void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]); - -void libcrux_sha3_sha256_ema(Eurydice_slice digest, Eurydice_slice payload); - -void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]); - -void libcrux_sha3_sha384_ema(Eurydice_slice digest, Eurydice_slice payload); - -void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]); - -void libcrux_sha3_sha512_ema(Eurydice_slice digest, Eurydice_slice payload); - -void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]); - -extern const size_t libcrux_sha3_generic_keccak__ROTC[24U]; - -extern const size_t libcrux_sha3_generic_keccak__PI[24U]; - -extern const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U]; - -uint64_t -libcrux_sha3_portable_keccak__veor5q_u64( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b); - -uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c); - -uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c); - -void -libcrux_sha3_portable_keccak_slice_1( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -); - -typedef struct K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s -{ - Eurydice_slice fst[1U]; - Eurydice_slice snd[1U]; -} -K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; - -K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], size_t mid); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(void); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( - uint64_t a, - uint64_t b, - uint64_t c, - uint64_t d, - uint64_t e -); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( - uint64_t a, - uint64_t b -); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( - uint64_t a, - uint64_t b, - uint64_t c -); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( - uint64_t a, - uint64_t c -); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( - uint64_t a, - uint64_t b -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( - Eurydice_slice a[1U], - size_t start, - size_t len, - Eurydice_slice ret[1U] -); - -K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( - Eurydice_slice a[1U], - size_t mid -); - -libcrux_sha3_Algorithm -libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from(uint32_t v); - -uint32_t -libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( - libcrux_sha3_Algorithm v -); - -typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s -{ uint64_t st[5U][5U]; } -libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; - -libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( - void -); - -void -libcrux_sha3_portable_keccak_load_block___72size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( - uint64_t a, - uint64_t b -); - -uint64_t libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x); - -uint64_t libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, uint64_t b); - -uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( - uint64_t a, - uint64_t b -); - -void -libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -); - -void -libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -); - -void -libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -); - -void -libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - size_t i -); - -void -libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s -); - -void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak_load_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_portable_keccak_store_block___72size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]); - -void -libcrux_sha3_portable_keccak_store_block_full___72size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_sha512(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_portable_keccak_load_block___144size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak_load_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_portable_keccak_store_block___144size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]); - -void -libcrux_sha3_portable_keccak_store_block_full___144size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_sha224(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_portable_keccak_load_block___136size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak_load_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_portable_keccak_store_block___136size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]); - -void -libcrux_sha3_portable_keccak_store_block_full___136size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_sha256(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_portable_keccak_load_block___104size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak_load_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_portable_keccak_store_block___104size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]); - -void -libcrux_sha3_portable_keccak_store_block_full___104size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_sha384(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_portable_keccak_load_block___168size_t( - uint64_t (*s)[5U], - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice blocks[1U] -); - -void -libcrux_sha3_portable_keccak_load_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t blocks[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t b[1U][200U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_portable_keccak_store_block___168size_t(uint64_t (*s)[5U], Eurydice_slice out[1U]); - -void -libcrux_sha3_portable_keccak_store_block_full___168size_t( - uint64_t (*s)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( - uint64_t (*a)[5U], - uint8_t ret[1U][200U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( - uint64_t (*a)[5U], - Eurydice_slice b[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_shake128(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice last[1U] -); - -void -libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( - Eurydice_slice data[1U], - Eurydice_slice out[1U] -); - -void libcrux_sha3_portable_shake256(Eurydice_slice digest, Eurydice_slice data); - -typedef libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_KeccakState1; - -libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self -); - -libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t -libcrux_sha3_portable_incremental_shake128_init(void); - -void -libcrux_sha3_portable_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice data0 -); - -void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out[1U] -); - -void -libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -); - -void -libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, - Eurydice_slice out0 -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_H_DEFINED -#endif diff --git a/libcrux-sha3/c/libcrux_sha3_avx2.c b/libcrux-sha3/c/libcrux_sha3_avx2.c deleted file mode 100644 index c8c762d2a..000000000 --- a/libcrux-sha3/c/libcrux_sha3_avx2.c +++ /dev/null @@ -1,2721 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#include "intrinsics/libcrux_intrinsics_avx2.h" - -#include "internal/libcrux_sha3_avx2.h" - -#include "internal/libcrux_sha3.h" -#include "internal/core.h" - -static inline core_core_arch_x86___m256i -_veor5q_u64( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, - core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); - core_core_arch_x86___m256i abcd = libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); - return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); -} - -static inline core_core_arch_x86___m256i -_vrax1q_u64(core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) -{ - core_core_arch_x86___m256i uu____0 = a; - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(b)); -} - -static inline core_core_arch_x86___m256i -_vbcaxq_u64( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c -) -{ - core_core_arch_x86___m256i uu____0 = a; - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); -} - -static inline core_core_arch_x86___m256i _veorq_n_u64(core_core_arch_x86___m256i a, uint64_t c) -{ - core_core_arch_x86___m256i c0 = libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); - return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); -} - -static inline void -slice_4(Eurydice_slice a[4U], size_t start, size_t len, Eurydice_slice ret[4U]) -{ - Eurydice_slice - uu____0 = - Eurydice_slice_subslice(a[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(a[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(a[2U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - ret[0U] = uu____0; - ret[1U] = uu____1; - ret[2U] = uu____2; - ret[3U] = - Eurydice_slice_subslice(a[3U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); -} - -typedef struct __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s -{ - Eurydice_slice fst[4U]; - Eurydice_slice snd[4U]; -} -__Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; - -static inline __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_4(Eurydice_slice out[4U], size_t mid) -{ - Eurydice_slice out0 = out[0U]; - Eurydice_slice out1 = out[1U]; - Eurydice_slice out2 = out[2U]; - Eurydice_slice out3 = out[3U]; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____0 = - core_slice___Slice_T___split_at_mut(out0, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____1 = - core_slice___Slice_T___split_at_mut(out1, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out10 = uu____1.fst; - Eurydice_slice out11 = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____2 = - core_slice___Slice_T___split_at_mut(out2, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out20 = uu____2.fst; - Eurydice_slice out21 = uu____2.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t - uu____3 = - core_slice___Slice_T___split_at_mut(out3, - mid, - uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out30 = uu____3.fst; - Eurydice_slice out31 = uu____3.snd; - __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; - lit.fst[0U] = out00; - lit.fst[1U] = out10; - lit.fst[2U] = out20; - lit.fst[3U] = out30; - lit.snd[0U] = out01; - lit.snd[1U] = out11; - lit.snd[2U] = out21; - lit.snd[3U] = out31; - return lit; -} - -static inline core_core_arch_x86___m256i zero(void) -{ - return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); -} - -static inline core_core_arch_x86___m256i -xor5( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, - core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e -) -{ - return _veor5q_u64(a, b, c, d, e); -} - -static inline core_core_arch_x86___m256i -rotate_left1_and_xor(core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) -{ - return _vrax1q_u64(a, b); -} - -static inline core_core_arch_x86___m256i -and_not_xor( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c -) -{ - return _vbcaxq_u64(a, b, c); -} - -static inline core_core_arch_x86___m256i xor_constant(core_core_arch_x86___m256i a, uint64_t c) -{ - return _veorq_n_u64(a, c); -} - -static inline core_core_arch_x86___m256i -xor0(core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) -{ - return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); -} - -static inline void -slice_n(Eurydice_slice a[4U], size_t start, size_t len, Eurydice_slice ret[4U]) -{ - Eurydice_slice uu____0[4U]; - memcpy(uu____0, a, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice ret0[4U]; - slice_4(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof (Eurydice_slice)); -} - -static inline __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_n(Eurydice_slice a[4U], size_t mid) -{ - return split_at_mut_4(a, mid); -} - -inline void -libcrux_sha3_avx2_x4_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice input2, - Eurydice_slice input3, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Eurydice_slice buf0[4U] = { input0, input1, input2, input3 }; - Eurydice_slice buf[4U] = { out0, out1, out2, out3 }; - libcrux_sha3_generic_keccak_keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(buf0, - buf); -} - -inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_avx2_x4_incremental_shake128_init(void) -{ - return - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t(); -} - -inline void -libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice data0, - Eurydice_slice data1, - Eurydice_slice data2, - Eurydice_slice data3 -) -{ - Eurydice_slice buf[4U] = { data0, data1, data2, data3 }; - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(s, - buf); -} - -inline void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Eurydice_slice buf[4U] = { out0, out1, out2, out3 }; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(s, - buf); -} - -inline void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -) -{ - Eurydice_slice buf[4U] = { out0, out1, out2, out3 }; - libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, - buf); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____0 = split_at_mut_n(out, (size_t)168U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____0.fst, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice o10[4U]; - memcpy(o10, uu____0.snd, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t(s, - o0); - __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____1 = split_at_mut_n(o10, (size_t)168U); - Eurydice_slice o1[4U]; - memcpy(o1, uu____1.fst, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice o2[4U]; - memcpy(o2, uu____1.snd, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, - o1); - libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, - o2); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(s); - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t(s->st, - out); -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -) -{ - libcrux_sha3_simd_avx2_store_block___168size_t(a, b); -} - -inline void -libcrux_sha3_simd_avx2_store_block___168size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) - { - size_t i0 = i; - core_core_arch_x86___m256i - v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[2U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[3U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = { 0U }; - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____3 = - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____3, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____4 = - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - if (rem == (size_t)16U) - { - uint8_t u8s0[32U] = { 0U }; - size_t i = ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice - uu____6 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____7 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____7, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____8 = - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____8, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____9 = - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____9, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice last[4U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)4U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U; - } - core_core_arch_x86___m256i (*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof (uint8_t [200U])); - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___168size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___168size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t b[4U][200U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof (uint8_t [200U])); - libcrux_sha3_simd_avx2_load_block_full___168size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_simd_avx2_load_block_full___168size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t blocks[4U][200U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[4U] = - { - uu____1, - uu____2, - uu____3, - Eurydice_array_to_slice((size_t)200U, - blocks[3U], - uint8_t, - Eurydice_slice) - }; - libcrux_sha3_simd_avx2_load_block___168size_t(uu____0, buf); -} - -inline void -libcrux_sha3_simd_avx2_load_block___168size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) - { - size_t i0 = i; - core_core_arch_x86___m256i - v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[2U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[3U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i v0l = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i - v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - v0l, - v2l, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - v1h, - v3h, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - v0l, - v2l, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - v1h, - v3h, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[(size_t)4U - * i0 - / (size_t)5U][(size_t)4U - * i0 - % (size_t)5U], - v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i - uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)1U) - / (size_t)5U][((size_t)4U * i0 + (size_t)1U) - % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = - uu____1; - core_core_arch_x86___m256i - uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)2U) - / (size_t)5U][((size_t)4U * i0 + (size_t)2U) - % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = - uu____2; - core_core_arch_x86___m256i - uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)3U) - / (size_t)5U][((size_t)4U * i0 + (size_t)3U) - % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = - uu____3; - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = { 0U }; - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____5 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____7 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_x86___m256i - u = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(core_array___Array_T__N__23__as_slice((size_t)32U, - u8s, - uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) - { - uint8_t u8s0[32U] = { 0U }; - Eurydice_slice - uu____9 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____9, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____10 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____10, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____11 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____11, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____12 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____12, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_x86___m256i - u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(core_array___Array_T__N__23__as_slice((size_t)32U, - u8s0, - uint8_t, - Eurydice_slice)); - size_t i = ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -inline void -libcrux_sha3_generic_keccak_keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - Eurydice_slice data[4U], - Eurydice_slice out[4U] -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - s = - libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t(); - for - (size_t - i = (size_t)0U; - i - < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *uu____0 = &s; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, data, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - libcrux_sha3_generic_keccak_absorb_block__core_core_arch_x86___m256i_4size_t_136size_t(uu____0, - ret); - } - size_t rem = core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *uu____2 = &s; - Eurydice_slice uu____3[4U]; - memcpy(uu____3, data, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) - { - libcrux_sha3_generic_keccak_squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t(&s, - out); - } - else - { - __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____4.fst, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice o1[4U]; - memcpy(o1, uu____4.snd, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, - o0); - core_ops_range_Range__size_t - iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter(( - (core_ops_range_Range__size_t){ .start = (size_t)1U, .end = blocks } - ), - core_ops_range_Range__size_t, - core_ops_range_Range__size_t); - while (true) - { - if - ( - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next(&iter, - size_t, - core_option_Option__size_t).tag - == core_option_None - ) - { - break; - } - else - { - __Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[4U]; - memcpy(o, uu____5.fst, (size_t)4U * sizeof (Eurydice_slice)); - Eurydice_slice orest[4U]; - memcpy(orest, uu____5.snd, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, - o); - memcpy(o1, orest, (size_t)4U * sizeof (Eurydice_slice)); - } - } - if (last < outlen) - { - libcrux_sha3_generic_keccak_squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t(s, o1); - } - } -} - -inline void -libcrux_sha3_generic_keccak_squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t s, - Eurydice_slice out[4U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(&s); - uint8_t b[4U][200U]; - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t(s.st, - b); - for (size_t i = (size_t)0U; i < (size_t)4U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(s); - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t(s->st, - out); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t(s->st, - out); -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -) -{ - libcrux_sha3_simd_avx2_store_block___136size_t(a, b); -} - -inline void -libcrux_sha3_generic_keccak_squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -) -{ - uint8_t b[4U][200U]; - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t(s->st, - b); - for (size_t i = (size_t)0U; i < (size_t)4U; i++) - { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; - lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice(uu____0, - Eurydice_array_to_subslice((size_t)200U, - uu____1, - lit, - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t ret[4U][200U] -) -{ - uint8_t ret0[4U][200U]; - libcrux_sha3_simd_avx2_store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof (uint8_t [200U])); -} - -inline void -libcrux_sha3_simd_avx2_store_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t ret[4U][200U] -) -{ - uint8_t out0[200U] = { 0U }; - uint8_t out1[200U] = { 0U }; - uint8_t out2[200U] = { 0U }; - uint8_t out3[200U] = { 0U }; - core_core_arch_x86___m256i (*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); - Eurydice_slice - buf[4U] = - { - uu____1, - uu____2, - uu____3, - Eurydice_array_to_slice((size_t)200U, - out3, - uint8_t, - Eurydice_slice) - }; - libcrux_sha3_simd_avx2_store_block___136size_t(uu____0, buf); - uint8_t uu____4[200U]; - memcpy(uu____4, out0, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____5[200U]; - memcpy(uu____5, out1, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____6[200U]; - memcpy(uu____6, out2, (size_t)200U * sizeof (uint8_t)); - uint8_t uu____7[200U]; - memcpy(uu____7, out3, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[0U], uu____4, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[1U], uu____5, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[2U], uu____6, (size_t)200U * sizeof (uint8_t)); - memcpy(ret[3U], uu____7, (size_t)200U * sizeof (uint8_t)); -} - -inline void -libcrux_sha3_simd_avx2_store_block___136size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) - { - size_t i0 = i; - core_core_arch_x86___m256i - v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[2U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(Eurydice_slice_subslice(out[3U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = { 0U }; - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; - Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice - uu____1 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____1, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____2 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____2, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____3 = - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____3, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____4 = - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - if (rem == (size_t)16U) - { - uint8_t u8s0[32U] = { 0U }; - size_t i = ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice - uu____6 = - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____7 = - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____7, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____8 = - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____8, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____9 = - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____9, - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - } -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice last[4U] -) -{ - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = { { 0U } }; - for (size_t i = (size_t)0U; i < (size_t)4U; i++) - { - size_t i0 = i; - Eurydice_slice - uu____0 = - Eurydice_array_to_subslice((size_t)200U, - blocks[i0], - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = last_len }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U; - } - core_core_arch_x86___m256i (*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof (uint8_t [200U])); - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___136size_t(uu____1, - uu____2); - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___136size_t( - core_core_arch_x86___m256i (*a)[5U], - uint8_t b[4U][200U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof (uint8_t [200U])); - libcrux_sha3_simd_avx2_load_block_full___136size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_simd_avx2_load_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], - uint8_t blocks[4U][200U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = s; - Eurydice_slice - uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, Eurydice_slice); - Eurydice_slice - uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], uint8_t, Eurydice_slice); - Eurydice_slice - buf[4U] = - { - uu____1, - uu____2, - uu____3, - Eurydice_array_to_slice((size_t)200U, - blocks[3U], - uint8_t, - Eurydice_slice) - }; - libcrux_sha3_simd_avx2_load_block___136size_t(uu____0, buf); -} - -inline void -libcrux_sha3_generic_keccak_absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice blocks[4U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = s->st; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, blocks, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block___136size_t(uu____0, - uu____1); - libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -inline void -libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -) -{ - for (size_t i = (size_t)0U; i < (size_t)24U; i++) - { - size_t i0 = i; - libcrux_sha3_generic_keccak_theta_rho__core_core_arch_x86___m256i_4size_t(s); - libcrux_sha3_generic_keccak_pi__core_core_arch_x86___m256i_4size_t(s); - libcrux_sha3_generic_keccak_chi__core_core_arch_x86___m256i_4size_t(s); - libcrux_sha3_generic_keccak_iota__core_core_arch_x86___m256i_4size_t(s, i0); - } -} - -inline void -libcrux_sha3_generic_keccak_iota__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - size_t i -) -{ - core_core_arch_x86___m256i - uu____0 = xor_constant(s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -inline void -libcrux_sha3_generic_keccak_chi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -) -{ - core_core_arch_x86___m256i old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof (core_core_arch_x86___m256i [5U])); - for (size_t i0 = (size_t)0U; i0 < (size_t)5U; i0++) - { - size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)5U; i++) - { - size_t j = i; - core_core_arch_x86___m256i - uu____0 = - and_not_xor(s->st[i1][j], - old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0; - } - } -} - -inline void -libcrux_sha3_generic_keccak_pi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -) -{ - core_core_arch_x86___m256i old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone((size_t)5U, - s->st, - old, - core_core_arch_x86___m256i [5U], - void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -inline void -libcrux_sha3_generic_keccak_theta_rho__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -) -{ - core_core_arch_x86___m256i - uu____0 = xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], s->st[4U][0U]); - core_core_arch_x86___m256i - uu____1 = xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], s->st[4U][1U]); - core_core_arch_x86___m256i - uu____2 = xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], s->st[4U][2U]); - core_core_arch_x86___m256i - uu____3 = xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], s->st[4U][3U]); - core_core_arch_x86___m256i - c[5U] = - { - uu____0, uu____1, uu____2, uu____3, - xor5(s->st[0U][4U], - s->st[1U][4U], - s->st[2U][4U], - s->st[3U][4U], - s->st[4U][4U]) - }; - core_core_arch_x86___m256i - uu____4 = - rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i - uu____5 = - rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i - uu____6 = - rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i - uu____7 = - rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i - t[5U] = - { - uu____4, uu____5, uu____6, uu____7, - rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U]) - }; - core_core_arch_x86___m256i uu____8 = xor0(s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - core_core_arch_x86___m256i - uu____9 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], - t[0U]); - s->st[1U][0U] = uu____9; - core_core_arch_x86___m256i - uu____10 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], - t[0U]); - s->st[2U][0U] = uu____10; - core_core_arch_x86___m256i - uu____11 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], - t[0U]); - s->st[3U][0U] = uu____11; - core_core_arch_x86___m256i - uu____12 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], - t[0U]); - s->st[4U][0U] = uu____12; - core_core_arch_x86___m256i - uu____13 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], - t[1U]); - s->st[0U][1U] = uu____13; - core_core_arch_x86___m256i - uu____14 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], - t[1U]); - s->st[1U][1U] = uu____14; - core_core_arch_x86___m256i - uu____15 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], - t[1U]); - s->st[2U][1U] = uu____15; - core_core_arch_x86___m256i - uu____16 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], - t[1U]); - s->st[3U][1U] = uu____16; - core_core_arch_x86___m256i - uu____17 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], - t[1U]); - s->st[4U][1U] = uu____17; - core_core_arch_x86___m256i - uu____18 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], - t[2U]); - s->st[0U][2U] = uu____18; - core_core_arch_x86___m256i - uu____19 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], - t[2U]); - s->st[1U][2U] = uu____19; - core_core_arch_x86___m256i - uu____20 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], - t[2U]); - s->st[2U][2U] = uu____20; - core_core_arch_x86___m256i - uu____21 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], - t[2U]); - s->st[3U][2U] = uu____21; - core_core_arch_x86___m256i - uu____22 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], - t[2U]); - s->st[4U][2U] = uu____22; - core_core_arch_x86___m256i - uu____23 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], - t[3U]); - s->st[0U][3U] = uu____23; - core_core_arch_x86___m256i - uu____24 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], - t[3U]); - s->st[1U][3U] = uu____24; - core_core_arch_x86___m256i - uu____25 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], - t[3U]); - s->st[2U][3U] = uu____25; - core_core_arch_x86___m256i - uu____26 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], - t[3U]); - s->st[3U][3U] = uu____26; - core_core_arch_x86___m256i - uu____27 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], - t[3U]); - s->st[4U][3U] = uu____27; - core_core_arch_x86___m256i - uu____28 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], - t[4U]); - s->st[0U][4U] = uu____28; - core_core_arch_x86___m256i - uu____29 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], - t[4U]); - s->st[1U][4U] = uu____29; - core_core_arch_x86___m256i - uu____30 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], - t[4U]); - s->st[2U][4U] = uu____30; - core_core_arch_x86___m256i - uu____31 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], - t[4U]); - s->st[3U][4U] = uu____31; - core_core_arch_x86___m256i - uu____32 = - libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], - t[4U]); - s->st[4U][4U] = uu____32; -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___14int32_t_50int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___14int32_t_50int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___14int32_t_50int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___14int32_t_50int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___14int32_t_50int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)14, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)50, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___8int32_t_56int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___8int32_t_56int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___8int32_t_56int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___8int32_t_56int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___8int32_t_56int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)8, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)56, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___39int32_t_25int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___39int32_t_25int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___39int32_t_25int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___39int32_t_25int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___39int32_t_25int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)39, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)25, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___20int32_t_44int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___20int32_t_44int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___20int32_t_44int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___20int32_t_44int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___20int32_t_44int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)20, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)44, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___27int32_t_37int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___27int32_t_37int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___27int32_t_37int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___27int32_t_37int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___27int32_t_37int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)27, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)37, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___56int32_t_8int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___56int32_t_8int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___56int32_t_8int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___56int32_t_8int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___56int32_t_8int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)56, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___21int32_t_43int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___21int32_t_43int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___21int32_t_43int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___21int32_t_43int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___21int32_t_43int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)21, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)43, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___25int32_t_39int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___25int32_t_39int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___25int32_t_39int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___25int32_t_39int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___25int32_t_39int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)25, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)39, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___55int32_t_9int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___55int32_t_9int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___55int32_t_9int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___55int32_t_9int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___55int32_t_9int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)55, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)9, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___28int32_t_36int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___28int32_t_36int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___28int32_t_36int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___28int32_t_36int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___28int32_t_36int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)28, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)36, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___61int32_t_3int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___61int32_t_3int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___61int32_t_3int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___61int32_t_3int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___61int32_t_3int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)61, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)3, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___15int32_t_49int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___15int32_t_49int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___15int32_t_49int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___15int32_t_49int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___15int32_t_49int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)15, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)49, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___43int32_t_21int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___43int32_t_21int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___43int32_t_21int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___43int32_t_21int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___43int32_t_21int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)43, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)21, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___6int32_t_58int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___6int32_t_58int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___6int32_t_58int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___6int32_t_58int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___6int32_t_58int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)6, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)58, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___62int32_t_2int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___62int32_t_2int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___62int32_t_2int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___62int32_t_2int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___62int32_t_2int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)62, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)2, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___2int32_t_62int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___2int32_t_62int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___2int32_t_62int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___2int32_t_62int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___2int32_t_62int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)2, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)62, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___45int32_t_19int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___45int32_t_19int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___45int32_t_19int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___45int32_t_19int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___45int32_t_19int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)45, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)19, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___10int32_t_54int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___10int32_t_54int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___10int32_t_54int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___10int32_t_54int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___10int32_t_54int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)10, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)54, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___44int32_t_20int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___44int32_t_20int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___44int32_t_20int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___44int32_t_20int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___44int32_t_20int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)44, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)20, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___1int32_t_63int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___1int32_t_63int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___1int32_t_63int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___18int32_t_46int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___18int32_t_46int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___18int32_t_46int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___18int32_t_46int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___18int32_t_46int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)18, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)46, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___41int32_t_23int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___41int32_t_23int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___41int32_t_23int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___41int32_t_23int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___41int32_t_23int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)41, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)23, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___3int32_t_61int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___3int32_t_61int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___3int32_t_61int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___3int32_t_61int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___3int32_t_61int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)3, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)61, x, core_core_arch_x86___m256i)); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___36int32_t_28int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - return libcrux_sha3_simd_avx2__vxarq_u64___36int32_t_28int32_t(a, b); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2__vxarq_u64___36int32_t_28int32_t( - core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b -) -{ - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return libcrux_sha3_simd_avx2_rotate_left___36int32_t_28int32_t(ab); -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___36int32_t_28int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)36, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)28, x, core_core_arch_x86___m256i)); -} - -inline void -libcrux_sha3_simd_avx2___libcrux_sha3__traits__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block___136size_t( - core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U] -) -{ - core_core_arch_x86___m256i (*uu____0)[5U] = a; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, b, (size_t)4U * sizeof (Eurydice_slice)); - libcrux_sha3_simd_avx2_load_block___136size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_simd_avx2_load_block___136size_t( - core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U] -) -{ - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) - { - size_t i0 = i; - core_core_arch_x86___m256i - v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[0U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[1U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[2U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i - v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice(blocks[3U], - ( - (core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U) - } - ), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice)); - core_core_arch_x86___m256i v0l = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i - v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - v0l, - v2l, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)32, - v1h, - v3h, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - v0l, - v2l, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256((int32_t)49, - v1h, - v3h, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i - uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[(size_t)4U - * i0 - / (size_t)5U][(size_t)4U - * i0 - % (size_t)5U], - v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i - uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)1U) - / (size_t)5U][((size_t)4U * i0 + (size_t)1U) - % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U][((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = - uu____1; - core_core_arch_x86___m256i - uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)2U) - / (size_t)5U][((size_t)4U * i0 + (size_t)2U) - % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U][((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = - uu____2; - core_core_arch_x86___m256i - uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[((size_t)4U * i0 + (size_t)3U) - / (size_t)5U][((size_t)4U * i0 + (size_t)3U) - % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U][((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = - uu____3; - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = { 0U }; - Eurydice_slice - uu____4 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____5 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____6 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____7 = - Eurydice_array_to_subslice((size_t)32U, - u8s, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_x86___m256i - u = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(core_array___Array_T__N__23__as_slice((size_t)32U, - u8s, - uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) - { - uint8_t u8s0[32U] = { 0U }; - Eurydice_slice - uu____9 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____9, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____10 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____10, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____11 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____11, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - Eurydice_slice - uu____12 = - Eurydice_array_to_subslice((size_t)32U, - u8s0, - ((core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____12, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ .start = start + (size_t)8U, .end = start + (size_t)16U }), - uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, - void *); - core_core_arch_x86___m256i - u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(core_array___Array_T__N__23__as_slice((size_t)32U, - u8s0, - uint8_t, - Eurydice_slice)); - size_t i = ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t( - void -) -{ - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t lit; - lit.st[0U][0U] = zero(); - lit.st[0U][1U] = zero(); - lit.st[0U][2U] = zero(); - lit.st[0U][3U] = zero(); - lit.st[0U][4U] = zero(); - lit.st[1U][0U] = zero(); - lit.st[1U][1U] = zero(); - lit.st[1U][2U] = zero(); - lit.st[1U][3U] = zero(); - lit.st[1U][4U] = zero(); - lit.st[2U][0U] = zero(); - lit.st[2U][1U] = zero(); - lit.st[2U][2U] = zero(); - lit.st[2U][3U] = zero(); - lit.st[2U][4U] = zero(); - lit.st[3U][0U] = zero(); - lit.st[3U][1U] = zero(); - lit.st[3U][2U] = zero(); - lit.st[3U][3U] = zero(); - lit.st[3U][4U] = zero(); - lit.st[4U][0U] = zero(); - lit.st[4U][1U] = zero(); - lit.st[4U][2U] = zero(); - lit.st[4U][3U] = zero(); - lit.st[4U][4U] = zero(); - return lit; -} - -inline core_core_arch_x86___m256i -libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(core_core_arch_x86___m256i x) -{ - core_core_arch_x86___m256i - uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64((int32_t)1, x, core_core_arch_x86___m256i); - return - libcrux_intrinsics_avx2_mm256_xor_si256(uu____0, - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)63, x, core_core_arch_x86___m256i)); -} - diff --git a/libcrux-sha3/c/libcrux_sha3_avx2.h b/libcrux-sha3/c/libcrux_sha3_avx2.h deleted file mode 100644 index c4d2c773c..000000000 --- a/libcrux-sha3/c/libcrux_sha3_avx2.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __libcrux_sha3_avx2_H -#define __libcrux_sha3_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_sha3.h" -#include "core.h" -#include "eurydice_glue.h" - -typedef struct libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s -{ core_core_arch_x86___m256i st[5U][5U]; } -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; - -void -libcrux_sha3_avx2_x4_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice input2, - Eurydice_slice input3, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); - -typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_avx2_x4_incremental_KeccakState4; - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_avx2_x4_incremental_shake128_init(void); - -void -libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice data0, - Eurydice_slice data1, - Eurydice_slice data2, - Eurydice_slice data3 -); - -void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); - -void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out0, - Eurydice_slice out1, - Eurydice_slice out2, - Eurydice_slice out3 -); - -void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice last[4U] -); - -void -libcrux_sha3_generic_keccak_keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - Eurydice_slice data[4U], - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice out[4U] -); - -void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice last[4U] -); - -void -libcrux_sha3_generic_keccak_absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - Eurydice_slice blocks[4U] -); - -void -libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -); - -void -libcrux_sha3_generic_keccak_iota__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s, - size_t i -); - -void -libcrux_sha3_generic_keccak_chi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -); - -void -libcrux_sha3_generic_keccak_pi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -); - -void -libcrux_sha3_generic_keccak_theta_rho__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t *s -); - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t( - void -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_avx2_H_DEFINED -#endif diff --git a/libcrux-sha3/c/libcrux_sha3_neon.c b/libcrux-sha3/c/libcrux_sha3_neon.c deleted file mode 100644 index 010c580b9..000000000 --- a/libcrux-sha3/c/libcrux_sha3_neon.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#include "intrinsics/libcrux_intrinsics_arm64.h" - -#include "libcrux_sha3_neon.h" - -#include "internal/core.h" - -inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline libcrux_sha3_neon_x2_incremental_KeccakState2 -libcrux_sha3_neon_x2_incremental_shake128_init(void) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice data0, - Eurydice_slice data1 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice out0, - Eurydice_slice out1 -) -{ - Prims_string - buf[1U] = { "not implemented: The target architecture does not support neon instructions." }; - Eurydice_slice - uu____0 = Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore(core_fmt__core__fmt__Arguments__a__2__new_v1(uu____0, - Eurydice_array_to_slice((size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, - void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); - KRML_HOST_EXIT(255U); -} - diff --git a/libcrux-sha3/c/libcrux_sha3_neon.h b/libcrux-sha3/c/libcrux_sha3_neon.h deleted file mode 100644 index ec2948001..000000000 --- a/libcrux-sha3/c/libcrux_sha3_neon.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_sha3.llbc - F* version: 58c915a8 - KaRaMeL version: 04cb86b9 - */ - -#ifndef __libcrux_sha3_neon_H -#define __libcrux_sha3_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "libcrux_sha3.h" -#include "core.h" -#include "eurydice_glue.h" - -void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data); - -void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); - -void -libcrux_sha3_neon_x2_shake256( - Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1 -); - -typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s -{ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; } -libcrux_sha3_neon_x2_incremental_KeccakState2; - -libcrux_sha3_neon_x2_incremental_KeccakState2 -libcrux_sha3_neon_x2_incremental_shake128_init(void); - -void -libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice data0, - Eurydice_slice data1 -); - -void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice out0, - Eurydice_slice out1 -); - -void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, - Eurydice_slice out0, - Eurydice_slice out1 -); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_sha3_neon_H_DEFINED -#endif From ed823bc641b7152c9e2fe03691839a13fbce7a43 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 7 Jun 2024 21:05:59 +0200 Subject: [PATCH 29/84] neon extract --- libcrux-ml-kem/c/CMakeLists.txt | 17 +- libcrux-ml-kem/c/eurydice_glue.h | 14 +- libcrux-ml-kem/c/internal/libcrux_core.h | 99 +- .../c/internal/libcrux_mlkem_portable.h | 6 +- .../c/internal/libcrux_sha3_internal.h | 6 +- .../c/intrinsics/libcrux_intrinsics_arm64.h | 22 +- libcrux-ml-kem/c/libcrux_core.c | 55 +- libcrux-ml-kem/c/libcrux_core.h | 10 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 521 +-- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 10 +- libcrux-ml-kem/c/libcrux_platform.h | 6 +- libcrux-ml-kem/c/libcrux_sha3.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_neon.c | 3039 ++++++++++++++++- libcrux-ml-kem/c/libcrux_sha3_neon.h | 32 +- libcrux-ml-kem/c/tests/mlkem768.cc | 68 + 25 files changed, 3071 insertions(+), 900 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 6d941994e..91e64d534 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -11,9 +11,11 @@ project(libcrux-ml-kem ) set(CMAKE_C_STANDARD 11) -#FIXME: Windows? + +# FIXME: Windows? add_compile_options( -Wall + # -Wextra # -pedantic # -Wconversion @@ -23,7 +25,7 @@ add_compile_options( $<$:-g> $<$:-O3> ) -add_link_options(-flto) + set(CMAKE_COLOR_DIAGNOSTICS "ON") include_directories( ${PROJECT_SOURCE_DIR} @@ -61,6 +63,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES Linux) -fPIC -flto ) + add_link_options(-flto) endif(${CMAKE_SYSTEM_NAME} MATCHES Linux) add_library(ml_kem SHARED ${SOURCES}) @@ -95,7 +98,7 @@ endif() # Get gtests include(FetchContent) FetchContent_Declare(googletest -DOWNLOAD_EXTRACT_TIMESTAMP TRUE + DOWNLOAD_EXTRACT_TIMESTAMP TRUE URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip ) @@ -105,7 +108,7 @@ FetchContent_MakeAvailable(googletest) # Get nlohmann json FetchContent_Declare(json -DOWNLOAD_EXTRACT_TIMESTAMP TRUE + DOWNLOAD_EXTRACT_TIMESTAMP TRUE URL https://github.com/nlohmann/json/archive/refs/tags/v3.10.3.zip ) FetchContent_MakeAvailable(json) @@ -129,12 +132,12 @@ target_link_libraries(sha3_test PRIVATE ) # --- Benchmarks - FetchContent_Populate(benchmark - GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_REPOSITORY https://github.com/google/benchmark.git + # The latest release 1.7.1 is broken due to https://github.com/google/benchmark/pull/1517 # But also: need the fix for https://github.com/google/benchmark/pull/1669 - GIT_TAG bc946b919cac6f25a199a526da571638cfde109f + GIT_TAG bc946b919cac6f25a199a526da571638cfde109f ) add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR}) diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index ef21a5003..4c12dcdb7 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -115,6 +115,10 @@ static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { memcpy(dst, &x, 4); } +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]) { + return (uint32_t)x0[0] << 24 | (uint32_t)x0[1] << 16 | (uint32_t)x0[2] << 8 | (uint32_t)x0[3]; +} + static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { store64_le(buf, v); } @@ -189,11 +193,11 @@ static inline Eurydice_slice chunk_next(Eurydice_chunks *chunks, size_t chunk_size = chunks->slice.len >= chunks->chunk_size ? chunks->chunk_size : chunks->slice.len; - Eurydice_slice curr_chunk = - ((Eurydice_slice){.ptr = chunks->slice.ptr, .len = chunk_size}); - chunks->slice = ((Eurydice_slice){ - .ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size, - .len = chunks->slice.len - chunk_size}); + Eurydice_slice curr_chunk; + curr_chunk.ptr = chunks->slice.ptr; + curr_chunk.len = chunk_size; + chunks->slice.ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size; + chunks->slice.len = chunks->slice.len - chunk_size; return curr_chunk; } diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 39db7b956..bf7077b43 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_core_H @@ -23,7 +23,7 @@ extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( #define CORE_NUM__U32_8__BITS (32U) -static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]); #define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) @@ -118,6 +118,24 @@ libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__type void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]); +typedef struct + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; + libcrux_ml_kem_types_MlKemPublicKey____800size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( uint8_t value[800U]); @@ -148,36 +166,12 @@ uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( Eurydice_slice lhs, Eurydice_slice rhs); -typedef struct - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]); -typedef struct - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; - Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); @@ -188,45 +182,6 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]); -typedef struct - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[24U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, - uint8_t ret[24U]); - -typedef struct - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[20U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, - uint8_t ret[20U]); - -typedef struct - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; - union { - uint8_t case_Ok[10U]; - core_array_TryFromSliceError case_Err; - } val; -} core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError; - -void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, - uint8_t ret[10U]); - typedef struct core_option_Option__Eurydice_slice_uint8_t_s { core_option_Option__size_t_tags tag; Eurydice_slice f0; @@ -234,7 +189,7 @@ typedef struct core_option_Option__Eurydice_slice_uint8_t_s { typedef struct core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; union { int16_t case_Ok[16U]; core_array_TryFromSliceError case_Err; @@ -246,10 +201,10 @@ void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_arr int16_t ret[16U]); typedef struct - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s { - Eurydice_slice fst[4U]; - Eurydice_slice snd[4U]; -} K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t__s { + Eurydice_slice fst[2U]; + Eurydice_slice snd[2U]; +} K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_; #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 5773bba52..21c931d0e 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index c897dae9f..063929aab 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h index 4f6a5f8c7..011676868 100644 --- a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h +++ b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h @@ -132,7 +132,9 @@ libcrux_intrinsics_arm64__vdupq_n_u32(uint32_t a) { } static inline core_core_arch_arm_shared_neon_uint16x8_t -libcrux_intrinsics_arm64__vdupq_n_u16(uint16_t value); +libcrux_intrinsics_arm64__vdupq_n_u16(uint16_t value) { + return vdupq_n_u16(value); +} static inline core_core_arch_arm_shared_neon_int16x8_t libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice slice) { @@ -245,7 +247,9 @@ libcrux_intrinsics_arm64__vqdmulhq_s16( static inline core_core_arch_arm_shared_neon_int32x4_t libcrux_intrinsics_arm64__vmull_s16(core_core_arch_arm_shared_neon_int16x4_t a, - core_core_arch_arm_shared_neon_int16x4_t b); + core_core_arch_arm_shared_neon_int16x4_t b) { + return vmull_s16(a, b); +} static inline core_core_arch_arm_shared_neon_int32x4_t libcrux_intrinsics_arm64__vmull_high_s16( @@ -317,17 +321,17 @@ libcrux_intrinsics_arm64__vandq_u16( // Shift Operations -#define libcrux_intrinsics_arm64__vshrq_n_s16(SHIFT_BY, a) \ +#define libcrux_intrinsics_arm64__vshrq_n_s16(SHIFT_BY, a, _ret_t) \ (vshrq_n_s16(a, SHIFT_BY)) -#define libcrux_intrinsics_arm64__vshrq_n_u16(SHIFT_BY, a) \ +#define libcrux_intrinsics_arm64__vshrq_n_u16(SHIFT_BY, a, _ret_t) \ (vshrq_n_u16(a, SHIFT_BY)) -#define libcrux_intrinsics_arm64__vshrq_n_u32(N, a) (vshrq_n_u32(a, N)) +#define libcrux_intrinsics_arm64__vshrq_n_u32(N, a, _ret_t) (vshrq_n_u32(a, N)) -#define libcrux_intrinsics_arm64__vshlq_n_u32(N, a) (vshlq_n_u32(a, N)) +#define libcrux_intrinsics_arm64__vshlq_n_u32(N, a, _ret_t) (vshlq_n_u32(a, N)) -#define libcrux_intrinsics_arm64__vshlq_n_s16(SHIFT_BY, a) \ +#define libcrux_intrinsics_arm64__vshlq_n_s16(SHIFT_BY, a, _ret_t) \ (vshlq_n_s16(a, SHIFT_BY)) static inline core_core_arch_arm_shared_neon_int16x8_t @@ -344,9 +348,9 @@ libcrux_intrinsics_arm64__vshlq_u16( return vshlq_u16(a, b); } -#define libcrux_intrinsics_arm64__vsliq_n_s32(N, a, b) (vsliq_n_s16(a, b, N)) +#define libcrux_intrinsics_arm64__vsliq_n_s32(N, a, b, _ret_t) (vsliq_n_s16(a, b, N)) -#define libcrux_intrinsics_arm64__vsliq_n_s64(N, a, b) (vsliq_n_s64(a, b, N)) +#define libcrux_intrinsics_arm64__vsliq_n_s64(N, a, b, _ret_t) (vsliq_n_s64(a, b, N)) // Transpose and Vector Manipulations diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index f3c81cf0c..d9b04551d 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "internal/libcrux_core.h" @@ -336,48 +336,6 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); } -void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, - uint8_t ret[24U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[24U]; - memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, - uint8_t ret[20U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[20U]; - memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - -void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, - uint8_t ret[10U]) { - if (self.tag == core_result_Ok) { - uint8_t f0[10U]; - memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } -} - void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, int16_t ret[16U]) { @@ -405,10 +363,3 @@ void core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_arra KRML_HOST_EXIT(255U); } } - -void core_fmt_rt__core__fmt__rt__Argument__a__1__none( - core_fmt_rt_Argument x0[0U]){} - -core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( - Eurydice_slice x0, Eurydice_slice x1) {return NULL;} - diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 52b97c825..bc228c092 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_core_H @@ -128,11 +128,11 @@ typedef struct #define core_result_Err 1 typedef uint8_t - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags; + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags; typedef struct core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s { - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; union { uint8_t case_Ok[8U]; core_array_TryFromSliceError case_Err; diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 40b2e232a..85dd66606 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index b63311db9..4884311cd 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 2479e6391..0b75d194b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 5256458eb..3f77765f7 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 8a1a92703..74e84b66d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 9ad10a424..f4ff7b78e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index c69fb58ac..9b31997bd 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 06ce4a50d..1849e09a4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index d7b8a5c6f..abf96805f 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index ed7e13445..6567e2b46 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" @@ -44,521 +44,6 @@ const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = { (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; -const uint8_t - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE - [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, - 255U, 255U, 255U}, - {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 255U, 255U}, - {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, - 15U, 255U, 255U}, - {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 14U, 15U}}; - inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero( void) { libcrux_ml_kem_vector_portable_PortableVector lit; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index 078c0cbd3..a9def0a13 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H @@ -27,10 +27,6 @@ extern "C" { #define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ (62209U) -extern const uint8_t - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[256U] - [16U]; - typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { int16_t elements[16U]; } libcrux_ml_kem_vector_portable_PortableVector; diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index 988a2e7f2..9ae0f07cd 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 87bfd1a1a..0543a8e19 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index e796057eb..be1a83910 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 3d3d86bf4..f138d7a8c 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,187 +1,2888 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #include "libcrux_sha3_neon.h" #include "internal/libcrux_core.h" -inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, - Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline libcrux_sha3_neon_x2_incremental_KeccakState2 +static inline core_core_arch_arm_shared_neon_uint64x2_t zero(void) { + return libcrux_intrinsics_arm64__vdupq_n_u64(0ULL); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t _veor5q_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c, + core_core_arch_arm_shared_neon_uint64x2_t d, + core_core_arch_arm_shared_neon_uint64x2_t e) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + core_core_arch_arm_shared_neon_uint64x2_t cd = + libcrux_intrinsics_arm64__veorq_u64(c, d); + core_core_arch_arm_shared_neon_uint64x2_t abcd = + libcrux_intrinsics_arm64__veorq_u64(ab, cd); + return libcrux_intrinsics_arm64__veorq_u64(abcd, e); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t xor5( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c, + core_core_arch_arm_shared_neon_uint64x2_t d, + core_core_arch_arm_shared_neon_uint64x2_t e) { + return _veor5q_u64(a, b, c, d, e); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)1, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)63, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t _vrax1q_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, rotate_left___1int32_t_63int32_t(b)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t rotate_left1_and_xor( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vrax1q_u64(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t _vbcaxq_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vbicq_u64(b, c)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t and_not_xor( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b, + core_core_arch_arm_shared_neon_uint64x2_t c) { + return _vbcaxq_u64(a, b, c); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t _veorq_n_u64( + core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) { + core_core_arch_arm_shared_neon_uint64x2_t c0 = + libcrux_intrinsics_arm64__vdupq_n_u64(c); + return libcrux_intrinsics_arm64__veorq_u64(a, c0); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t xor_constant( + core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) { + return _veorq_n_u64(a, c); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t xor0( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return libcrux_intrinsics_arm64__veorq_u64(a, b); +} + +static inline void slice_2(Eurydice_slice a[2U], size_t start, size_t len, + Eurydice_slice ret[2U]) { + Eurydice_slice uu____0 = Eurydice_slice_subslice( + a[0U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[0U] = uu____0; + ret[1U] = Eurydice_slice_subslice( + a[1U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); +} + +static inline void slice_n(Eurydice_slice a[2U], size_t start, size_t len, + Eurydice_slice ret[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, a, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[2U]; + slice_2(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ +split_at_mut_2(Eurydice_slice out[2U], size_t mid) { + Eurydice_slice out0 = out[0U]; + Eurydice_slice out1 = out[1U]; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out0, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at_mut( + out1, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out10 = uu____1.fst; + Eurydice_slice out11 = uu____1.snd; + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ lit; + lit.fst[0U] = out00; + lit.fst[1U] = out10; + lit.snd[0U] = out01; + lit.snd[1U] = out11; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ +split_at_mut_n(Eurydice_slice a[2U], size_t mid) { + return split_at_mut_2(a, mid); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(void) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + lit; + lit.st[0U][0U] = zero(); + lit.st[0U][1U] = zero(); + lit.st[0U][2U] = zero(); + lit.st[0U][3U] = zero(); + lit.st[0U][4U] = zero(); + lit.st[1U][0U] = zero(); + lit.st[1U][1U] = zero(); + lit.st[1U][2U] = zero(); + lit.st[1U][3U] = zero(); + lit.st[1U][4U] = zero(); + lit.st[2U][0U] = zero(); + lit.st[2U][1U] = zero(); + lit.st[2U][2U] = zero(); + lit.st[2U][3U] = zero(); + lit.st[2U][4U] = zero(); + lit.st[3U][0U] = zero(); + lit.st[3U][1U] = zero(); + lit.st[3U][2U] = zero(); + lit.st[3U][3U] = zero(); + lit.st[3U][4U] = zero(); + lit.st[4U][0U] = zero(); + lit.st[4U][1U] = zero(); + lit.st[4U][2U] = zero(); + lit.st[4U][3U] = zero(); + lit.st[4U][4U] = zero(); + return lit; +} + +static inline void load_block___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + libcrux_intrinsics_arm64__veorq_u64( + uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; + } + if ((size_t)72U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = {0U}; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2( + &dst0, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, + .end = (size_t)72U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst0, ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, + .end = (size_t)72U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t uvec = + libcrux_intrinsics_arm64__vld1q_u64( + Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void load_block___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); + load_block___72size_t(uu____0, uu____1); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)36, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)28, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___36int32_t_28int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___36int32_t_28int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)3, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)61, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___3int32_t_61int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___3int32_t_61int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)41, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)23, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___41int32_t_23int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___41int32_t_23int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)18, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)46, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___18int32_t_46int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___18int32_t_46int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___1int32_t_63int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___1int32_t_63int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)44, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)20, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___44int32_t_20int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___44int32_t_20int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)10, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)54, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___10int32_t_54int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___10int32_t_54int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)45, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)19, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___45int32_t_19int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___45int32_t_19int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)2, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)62, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___2int32_t_62int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___2int32_t_62int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)62, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)2, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___62int32_t_2int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___62int32_t_2int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)6, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)58, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___6int32_t_58int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___6int32_t_58int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)43, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)21, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___43int32_t_21int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___43int32_t_21int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)15, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)49, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___15int32_t_49int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___15int32_t_49int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)61, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)3, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___61int32_t_3int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___61int32_t_3int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)28, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)36, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___28int32_t_36int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___28int32_t_36int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)55, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)9, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___55int32_t_9int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___55int32_t_9int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)25, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)39, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___25int32_t_39int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___25int32_t_39int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)21, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)43, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___21int32_t_43int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___21int32_t_43int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)56, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)8, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___56int32_t_8int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___56int32_t_8int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)27, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)37, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___27int32_t_37int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___27int32_t_37int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)20, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)44, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___20int32_t_44int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___20int32_t_44int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)39, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)25, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___39int32_t_25int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___39int32_t_25int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)8, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)56, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___8int32_t_56int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___8int32_t_56int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +rotate_left___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + libcrux_intrinsics_arm64__vshlq_n_u64( + (int32_t)14, x, core_core_arch_arm_shared_neon_uint64x2_t); + return libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( + (int32_t)50, x, core_core_arch_arm_shared_neon_uint64x2_t)); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +_vxarq_u64___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + core_core_arch_arm_shared_neon_uint64x2_t ab = + libcrux_intrinsics_arm64__veorq_u64(a, b); + return rotate_left___14int32_t_50int32_t(ab); +} + +static inline core_core_arch_arm_shared_neon_uint64x2_t +xor_and_rotate___14int32_t_50int32_t( + core_core_arch_arm_shared_neon_uint64x2_t a, + core_core_arch_arm_shared_neon_uint64x2_t b) { + return _vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + core_core_arch_arm_shared_neon_uint64x2_t c[5U] = { + uu____0, uu____1, uu____2, uu____3, + xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + core_core_arch_arm_shared_neon_uint64x2_t uu____4 = + rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____5 = + rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t uu____7 = + rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t t[5U] = { + uu____4, uu____5, uu____6, uu____7, + rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + core_core_arch_arm_shared_neon_uint64x2_t uu____8 = + xor0(s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + core_core_arch_arm_shared_neon_uint64x2_t uu____9 = + xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + core_core_arch_arm_shared_neon_uint64x2_t uu____10 = + xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + core_core_arch_arm_shared_neon_uint64x2_t uu____11 = + xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + core_core_arch_arm_shared_neon_uint64x2_t uu____12 = + xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + core_core_arch_arm_shared_neon_uint64x2_t uu____13 = + xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + core_core_arch_arm_shared_neon_uint64x2_t uu____14 = + xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + core_core_arch_arm_shared_neon_uint64x2_t uu____15 = + xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + core_core_arch_arm_shared_neon_uint64x2_t uu____16 = + xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + core_core_arch_arm_shared_neon_uint64x2_t uu____17 = + xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + core_core_arch_arm_shared_neon_uint64x2_t uu____18 = + xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + core_core_arch_arm_shared_neon_uint64x2_t uu____19 = + xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + core_core_arch_arm_shared_neon_uint64x2_t uu____20 = + xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + core_core_arch_arm_shared_neon_uint64x2_t uu____21 = + xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + core_core_arch_arm_shared_neon_uint64x2_t uu____22 = + xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + core_core_arch_arm_shared_neon_uint64x2_t uu____23 = + xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + core_core_arch_arm_shared_neon_uint64x2_t uu____24 = + xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + core_core_arch_arm_shared_neon_uint64x2_t uu____25 = + xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + core_core_arch_arm_shared_neon_uint64x2_t uu____26 = + xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + core_core_arch_arm_shared_neon_uint64x2_t uu____27 = + xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + core_core_arch_arm_shared_neon_uint64x2_t uu____28 = + xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + core_core_arch_arm_shared_neon_uint64x2_t uu____29 = + xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + core_core_arch_arm_shared_neon_uint64x2_t uu____30 = + xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + core_core_arch_arm_shared_neon_uint64x2_t uu____31 = + xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + core_core_arch_arm_shared_neon_uint64x2_t uu____32 = + xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s) { + core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, core_core_arch_arm_shared_neon_uint64x2_t[5U], + void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s) { + core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; + memcpy(old, s->st, + (size_t)5U * sizeof(core_core_arch_arm_shared_neon_uint64x2_t[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( + i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + and_not_xor(s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + size_t i) { + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void +keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s, i0); + } +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice blocks[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); + load_block___72size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void load_block_full___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, + Eurydice_slice)}; + load_block___72size_t(uu____0, buf); +} + +static inline void load_block_full___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___72size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)72U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)72U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___72size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void store_block___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vtrn1q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vtrn2q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)72U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, + .end = (size_t)72U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)16U, u, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, + .end = (size_t)72U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice( + (size_t)16U, u, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___72size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; + store_block___72size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { + uint8_t ret0[2U][200U]; + store_block_full___72size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + uint8_t b[2U][200U]; + store_block_full___72size_t0(s->st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___72size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + store_block___72size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + store_block___72size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___72size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___72size_t0(s.st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + Eurydice_slice data[2U], Eurydice_slice out[2U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)72U, (size_t)72U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)72U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)72U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + &s, o); + memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( + s, o1); + } + } +} + +static inline void keccakx2___72size_t_6uint8_t(Eurydice_slice data[2U], + Eurydice_slice out[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( + uu____0, out); +} + +void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) { + uint8_t dummy[64U] = {0U}; + Eurydice_slice uu____0[2U] = {data, data}; + Eurydice_slice uu____1 = digest; + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)64U, dummy, uint8_t, Eurydice_slice)}; + keccakx2___72size_t_6uint8_t(uu____0, buf); +} + +static inline void load_block___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + libcrux_intrinsics_arm64__veorq_u64( + uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; + } + if ((size_t)136U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = {0U}; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2( + &dst0, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, + .end = (size_t)136U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst0, ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, + .end = (size_t)136U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t uvec = + libcrux_intrinsics_arm64__vld1q_u64( + Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void load_block___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); + load_block___136size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice blocks[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); + load_block___136size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void load_block_full___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, + Eurydice_slice)}; + load_block___136size_t(uu____0, buf); +} + +static inline void load_block_full___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void store_block___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vtrn1q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vtrn2q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)136U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, + .end = (size_t)136U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)16U, u, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, + .end = (size_t)136U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice( + (size_t)16U, u, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___136size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; + store_block___136size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { + uint8_t ret0[2U][200U]; + store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + uint8_t b[2U][200U]; + store_block_full___136size_t0(s->st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___136size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + store_block___136size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___136size_t0(s.st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + Eurydice_slice data[2U], Eurydice_slice out[2U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + s, o1); + } + } +} + +static inline void keccakx2___136size_t_6uint8_t(Eurydice_slice data[2U], + Eurydice_slice out[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( + uu____0, out); +} + +void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) { + uint8_t dummy[32U] = {0U}; + Eurydice_slice uu____0[2U] = {data, data}; + Eurydice_slice uu____1 = digest; + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)}; + keccakx2___136size_t_6uint8_t(uu____0, buf); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + Eurydice_slice data[2U], Eurydice_slice out[2U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( + s, o1); + } + } +} + +static inline void keccakx2___136size_t_31uint8_t(Eurydice_slice data[2U], + Eurydice_slice out[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( + uu____0, out); +} + +void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, + Eurydice_slice out0, Eurydice_slice out1) { + Eurydice_slice buf0[2U] = {input0, input1}; + Eurydice_slice buf[2U] = {out0, out1}; + keccakx2___136size_t_31uint8_t(buf0, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + KeccakState2; + +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t libcrux_sha3_neon_x2_incremental_shake128_init(void) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, - Eurydice_slice data1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); + return new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); +} + +static inline void load_block___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + libcrux_intrinsics_arm64__veorq_u64( + uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; + } + if ((size_t)168U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = {0U}; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2( + &dst0, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, + .end = (size_t)168U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst0, ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, + .end = (size_t)168U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t uvec = + libcrux_intrinsics_arm64__vld1q_u64( + Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void load_block_full___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, + Eurydice_slice)}; + load_block___168size_t(uu____0, buf); +} + +static inline void load_block_full___168size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___168size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___168size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice data0, Eurydice_slice data1) { + Eurydice_slice buf[2U] = {data0, data1}; + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( + s, buf); +} + +static inline void store_block___168size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vtrn1q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vtrn2q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)168U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, + .end = (size_t)168U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)16U, u, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, + .end = (size_t)168U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice( + (size_t)16U, u, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block___168size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + store_block___168size_t(a, b); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___168size_t0(s->st, out); +} + +void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out0, Eurydice_slice out1) { + Eurydice_slice buf[2U] = {out0, out1}; + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + s, buf); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + store_block___168size_t0(s->st, out); +} + +static inline void +squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ uu____0 = + split_at_mut_n(out, (size_t)168U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____0.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o10[2U]; + memcpy(o10, uu____0.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ uu____1 = + split_at_mut_n(o10, (size_t)168U); + Eurydice_slice o1[2U]; + memcpy(o1, uu____1.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o2[2U]; + memcpy(o2, uu____1.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + s, o1); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + s, o2); +} + +void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out0, Eurydice_slice out1) { + Eurydice_slice buf[2U] = {out0, out1}; + squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( + s, buf); +} + +static inline void load_block___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + libcrux_intrinsics_arm64__veorq_u64( + uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; + } + if ((size_t)144U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = {0U}; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2( + &dst0, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, + .end = (size_t)144U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst0, ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, + .end = (size_t)144U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t uvec = + libcrux_intrinsics_arm64__vld1q_u64( + Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void load_block___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); + load_block___144size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice blocks[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); + load_block___144size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void load_block_full___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, + Eurydice_slice)}; + load_block___144size_t(uu____0, buf); +} + +static inline void load_block_full___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___144size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)144U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)144U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___144size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void store_block___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vtrn1q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vtrn2q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)144U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, + .end = (size_t)144U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)16U, u, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, + .end = (size_t)144U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice( + (size_t)16U, u, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___144size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; + store_block___144size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { + uint8_t ret0[2U][200U]; + store_block_full___144size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + uint8_t b[2U][200U]; + store_block_full___144size_t0(s->st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___144size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + store_block___144size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + store_block___144size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___144size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___144size_t0(s.st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + Eurydice_slice data[2U], Eurydice_slice out[2U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)144U, (size_t)144U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)144U; + size_t last = outlen - outlen % (size_t)144U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)144U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)144U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + &s, o); + memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( + s, o1); + } + } +} + +static inline void keccakx2___144size_t_6uint8_t(Eurydice_slice data[2U], + Eurydice_slice out[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( + uu____0, out); } inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); + uint8_t dummy[28U] = {0U}; + Eurydice_slice uu____0[2U] = {data, data}; + Eurydice_slice uu____1 = digest; + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)28U, dummy, uint8_t, Eurydice_slice)}; + keccakx2___144size_t_6uint8_t(uu____0, buf); +} + +static inline void load_block___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice blocks[2U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____0 = + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____1 = + libcrux_intrinsics_arm64__veorq_u64( + uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; + core_core_arch_arm_shared_neon_uint64x2_t uu____2 = + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; + core_core_arch_arm_shared_neon_uint64x2_t uu____3 = + libcrux_intrinsics_arm64__veorq_u64( + uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; + } + if ((size_t)104U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint64_t u[2U] = {0U}; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; + Eurydice_slice_to_array2( + &dst0, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, + .end = (size_t)104U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst0, ret); + uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); + u[0U] = uu____4; + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, + .end = (size_t)104U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); + u[1U] = uu____5; + core_core_arch_arm_shared_neon_uint64x2_t uvec = + libcrux_intrinsics_arm64__vld1q_u64( + Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint64x2_t uu____6 = + libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); + s[i][j] = uu____6; + } +} + +static inline void load_block___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); + load_block___104size_t(uu____0, uu____1); +} + +static inline void +absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice blocks[2U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); + load_block___104size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void load_block_full___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + uint8_t blocks[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, + Eurydice_slice)}; + load_block___104size_t(uu____0, buf); +} + +static inline void load_block_full___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; + uint8_t uu____1[2U][200U]; + memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___104size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice last[2U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[2U][200U] = {{0U}}; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 6U; + blocks[i0][(size_t)104U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)104U - (size_t)1U] | 128U;); + core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; + uint8_t uu____2[2U][200U]; + memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); + load_block_full___104size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); +} + +static inline void store_block___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], + Eurydice_slice out[2U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) { + size_t i0 = i; + core_core_arch_arm_shared_neon_uint64x2_t v0 = + libcrux_intrinsics_arm64__vtrn1q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + core_core_arch_arm_shared_neon_uint64x2_t v1 = + libcrux_intrinsics_arm64__vtrn2q_u64( + s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], + s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_arm64__vst1q_bytes_u64( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)16U * i0, + .end = (size_t)16U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + } + if ((size_t)104U % (size_t)16U != (size_t)0U) { + size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; + size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; + uint8_t u[16U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, + .end = (size_t)104U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)16U, u, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, + .end = (size_t)104U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice( + (size_t)16U, u, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___104size_t( + core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; + store_block___104size_t(uu____0, buf); + uint8_t uu____2[200U]; + memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____3[200U]; + memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { + uint8_t ret0[2U][200U]; + store_block_full___104size_t(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + uint8_t b[2U][200U]; + store_block_full___104size_t0(s->st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___104size_t0( + core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { + store_block___104size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + store_block___104size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); + store_block___104size_t0(s->st, out); +} + +static inline void +squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s, + Eurydice_slice out[2U]) { + keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); + uint8_t b[2U][200U]; + store_block_full___104size_t0(s.st, b); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + Eurydice_slice data[2U], Eurydice_slice out[2U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = &s; + Eurydice_slice uu____1[2U]; + memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____1, i0 * (size_t)104U, (size_t)104U, ret); + absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &s; + Eurydice_slice uu____3[2U]; + memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice ret[2U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)104U; + size_t last = outlen - outlen % (size_t)104U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____4 = split_at_mut_n(out, (size_t)104U); + Eurydice_slice o0[2U]; + memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice o1[2U]; + memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ + uu____5 = split_at_mut_n(o1, (size_t)104U); + Eurydice_slice o[2U]; + memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); + Eurydice_slice orest[2U]; + memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + &s, o); + memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( + s, o1); + } + } +} + +static inline void keccakx2___104size_t_6uint8_t(Eurydice_slice data[2U], + Eurydice_slice out[2U]) { + Eurydice_slice uu____0[2U]; + memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); + keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( + uu____0, out); } inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); + uint8_t dummy[48U] = {0U}; + Eurydice_slice uu____0[2U] = {data, data}; + Eurydice_slice uu____1 = digest; + Eurydice_slice buf[2U] = { + uu____1, + Eurydice_array_to_slice((size_t)48U, dummy, uint8_t, Eurydice_slice)}; + keccakx2___104size_t_6uint8_t(uu____0, buf); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 0a665654b..2478907d2 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config + ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + a32b316e KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H @@ -17,6 +17,11 @@ extern "C" { #include "libcrux_core.h" #include "libcrux_sha3_internal.h" +typedef struct + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t_s { + core_core_arch_arm_shared_neon_uint64x2_t st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t; + void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); @@ -24,24 +29,23 @@ void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice out0, Eurydice_slice out1); -typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s { - libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; -} libcrux_sha3_neon_x2_incremental_KeccakState2; - -libcrux_sha3_neon_x2_incremental_KeccakState2 +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t libcrux_sha3_neon_x2_incremental_shake128_init(void); void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, - Eurydice_slice data1); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice data0, Eurydice_slice data1); void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out0, Eurydice_slice out1); void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, - Eurydice_slice out1); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *s, + Eurydice_slice out0, Eurydice_slice out1); void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index 69b874e92..3ccc1bad9 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -446,3 +446,71 @@ TEST(MlKem768TestAvx2, NISTKnownAnswerTest) } } #endif // LIBCRUX_X64 + +#ifdef LIBCRUX_AARCH64 +#include "libcrux_mlkem768_neon.h" + +TEST(MlKem768TestNeon, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + randomness[i] = 13; + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + cout << "key pair: " << bytes_to_hex(bytes(key_pair.pk.value, key_pair.pk.value + 1184U)) << endl; + + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} + +TEST(MlKem768TestNeon, NISTKnownAnswerTest) +{ + // XXX: This should be done in a portable way. + auto kats = read_kats("tests/mlkem768_nistkats.json"); + + for (auto kat : kats) + { + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(kat.key_generation_seed.data()); + + uint8_t pk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + pk_hash); + EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + } +} + +#endif // LIBCRUX_AARCH64 From 5863515b461d4c78a4cf17a3f8b5cf8c3c2c39b7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Fri, 7 Jun 2024 22:53:11 +0200 Subject: [PATCH 30/84] arm intrinsics fix --- .../c/intrinsics/libcrux_intrinsics_arm64.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h index 011676868..ebcd5e2ad 100644 --- a/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h +++ b/libcrux-ml-kem/c/intrinsics/libcrux_intrinsics_arm64.h @@ -184,7 +184,7 @@ static inline int16_t libcrux_intrinsics_arm64__vaddvq_s16( static inline uint16_t libcrux_intrinsics_arm64__vaddv_u16( core_core_arch_arm_shared_neon_uint16x4_t a) { - return vaddv_s16(a); + return vaddv_u16(a); } static inline uint16_t libcrux_intrinsics_arm64__vaddvq_u16( @@ -216,7 +216,7 @@ libcrux_intrinsics_arm64__vqdmulhq_n_s16( static inline core_core_arch_arm_shared_neon_uint16x8_t libcrux_intrinsics_arm64__vmulq_n_u16( core_core_arch_arm_shared_neon_uint16x8_t a, uint16_t c) { - return vmulq_n_s16(a, c); + return vmulq_n_u16(a, c); } static inline core_core_arch_arm_shared_neon_int32x4_t @@ -246,8 +246,9 @@ libcrux_intrinsics_arm64__vqdmulhq_s16( } static inline core_core_arch_arm_shared_neon_int32x4_t -libcrux_intrinsics_arm64__vmull_s16(core_core_arch_arm_shared_neon_int16x4_t a, - core_core_arch_arm_shared_neon_int16x4_t b) { +libcrux_intrinsics_arm64__vmull_s16( + core_core_arch_arm_shared_neon_int16x4_t a, + core_core_arch_arm_shared_neon_int16x4_t b) { return vmull_s16(a, b); } @@ -348,9 +349,11 @@ libcrux_intrinsics_arm64__vshlq_u16( return vshlq_u16(a, b); } -#define libcrux_intrinsics_arm64__vsliq_n_s32(N, a, b, _ret_t) (vsliq_n_s16(a, b, N)) +#define libcrux_intrinsics_arm64__vsliq_n_s32(N, a, b, _ret_t) \ + (vsliq_n_s32(a, b, N)) -#define libcrux_intrinsics_arm64__vsliq_n_s64(N, a, b, _ret_t) (vsliq_n_s64(a, b, N)) +#define libcrux_intrinsics_arm64__vsliq_n_s64(N, a, b, _ret_t) \ + (vsliq_n_s64(a, b, N)) // Transpose and Vector Manipulations From eaf785e1d95eaf31bb6a4618fe961c450e3fadc8 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Fri, 7 Jun 2024 22:58:20 +0200 Subject: [PATCH 31/84] fixes for neon --- libcrux-ml-kem/c/eurydice_glue.h | 5 +- .../c/internal/libcrux_mlkem_neon.h | 74 + libcrux-ml-kem/c/libcrux_mlkem1024_neon.c | 55 + libcrux-ml-kem/c/libcrux_mlkem1024_neon.h | 40 + libcrux-ml-kem/c/libcrux_mlkem512_neon.c | 163 + libcrux-ml-kem/c/libcrux_mlkem512_neon.h | 89 + libcrux-ml-kem/c/libcrux_mlkem768_neon.c | 54 + libcrux-ml-kem/c/libcrux_mlkem768_neon.h | 40 + libcrux-ml-kem/c/libcrux_mlkem_neon.c | 7727 +++++++++++++++++ libcrux-ml-kem/c/libcrux_mlkem_neon.h | 301 + libcrux-ml-kem/c/libcrux_sha3_neon.c | 6 +- libcrux-ml-kem/c/libcrux_sha3_neon.h | 6 +- libcrux-ml-kem/c/tests/mlkem768.cc | 7 +- 13 files changed, 8555 insertions(+), 12 deletions(-) create mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.h diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index 4c12dcdb7..76e9907ca 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -114,9 +114,8 @@ static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { uint32_t x = htobe32(src); memcpy(dst, &x, 4); } - -static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]) { - return (uint32_t)x0[0] << 24 | (uint32_t)x0[1] << 16 | (uint32_t)x0[2] << 8 | (uint32_t)x0[3]; +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { + return load32_le(buf); } static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h new file mode 100644 index 000000000..ae166d10e --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h @@ -0,0 +1,74 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_mlkem_neon_H +#define __internal_libcrux_mlkem_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_mlkem_neon.h" +#include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_mlkem_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c new file mode 100644 index 000000000..8233b1102 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c @@ -0,0 +1,55 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem1024_neon.h" + +void libcrux_ml_kem_mlkem1024_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h new file mode 100644 index 000000000..f95883a91 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h @@ -0,0 +1,40 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_neon_H +#define __libcrux_mlkem1024_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_neon.h" + +void libcrux_ml_kem_mlkem1024_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c new file mode 100644 index 000000000..12687fb50 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c @@ -0,0 +1,163 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem512_neon.h" + +#include "internal/libcrux_mlkem_neon.h" + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem512_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None}); + } + return uu____0; +} + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + public_key); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h new file mode 100644 index 000000000..817d7efee --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h @@ -0,0 +1,89 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_neon_H +#define __libcrux_mlkem512_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_mlkem512_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]); + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c new file mode 100644 index 000000000..ebf906e3a --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c @@ -0,0 +1,54 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768_neon.h" + +void libcrux_ml_kem_mlkem768_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h new file mode 100644 index 000000000..69680d2ce --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h @@ -0,0 +1,40 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_neon_H +#define __libcrux_mlkem768_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_neon.h" + +void libcrux_ml_kem_mlkem768_neon_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_neon_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_neon_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.c b/libcrux-ml-kem/c/libcrux_mlkem_neon.c new file mode 100644 index 000000000..06a1b3d76 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.c @@ -0,0 +1,7727 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_mlkem_neon.h" + +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ZERO(void) { + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, + .high = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0)}); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( + void) { + return libcrux_ml_kem_vector_neon_simd128ops_ZERO(); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array) { + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice( + array, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, + .high = libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice( + array, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice))}); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( + Eurydice_slice array) { + return libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(array); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { + lhs.low = libcrux_intrinsics_arm64__vaddq_s16(lhs.low, rhs->low); + lhs.high = libcrux_intrinsics_arm64__vaddq_s16(lhs.high, rhs->high); + return lhs; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { + return libcrux_ml_kem_vector_neon_simd128ops_add(lhs, rhs); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { + lhs.low = libcrux_intrinsics_arm64__vsubq_s16(lhs.low, rhs->low); + lhs.high = libcrux_intrinsics_arm64__vsubq_s16(lhs.high, rhs->high); + return lhs; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { + return libcrux_ml_kem_vector_neon_simd128ops_sub(lhs, rhs); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + v.low = libcrux_intrinsics_arm64__vmulq_n_s16(v.low, c); + v.high = libcrux_intrinsics_arm64__vmulq_n_s16(v.high, c); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + return libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant(v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + core_core_arch_arm_shared_neon_int16x8_t c0 = + libcrux_intrinsics_arm64__vdupq_n_s16(c); + v.low = libcrux_intrinsics_arm64__vandq_s16(v.low, c0); + v.high = libcrux_intrinsics_arm64__vandq_s16(v.high, c0); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + return libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant(v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t c = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)3329); + core_core_arch_arm_shared_neon_uint16x8_t m0 = + libcrux_intrinsics_arm64__vcgeq_s16(v.low, c); + core_core_arch_arm_shared_neon_uint16x8_t m1 = + libcrux_intrinsics_arm64__vcgeq_s16(v.high, c); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = c; + core_core_arch_arm_shared_neon_int16x8_t c0 = + libcrux_intrinsics_arm64__vandq_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m0)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = c; + core_core_arch_arm_shared_neon_int16x8_t c1 = + libcrux_intrinsics_arm64__vandq_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m1)); + v.low = libcrux_intrinsics_arm64__vsubq_s16(v.low, c0); + v.high = libcrux_intrinsics_arm64__vsubq_s16(v.high, c1); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329(v); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v) { + core_core_arch_arm_shared_neon_int16x8_t adder = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1024); + core_core_arch_arm_shared_neon_int16x8_t vec = + libcrux_intrinsics_arm64__vqdmulhq_n_s16( + v, LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER); + core_core_arch_arm_shared_neon_int16x8_t vec0 = + libcrux_intrinsics_arm64__vaddq_s16(vec, adder); + core_core_arch_arm_shared_neon_int16x8_t quotient = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)11, vec0, core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t sub = + libcrux_intrinsics_arm64__vmulq_n_s16( + quotient, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_intrinsics_arm64__vsubq_s16(v, sub); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + v.low = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.low); + v.high = + libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.high); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce(v); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t low, + core_core_arch_arm_shared_neon_int16x8_t high) { + core_core_arch_arm_shared_neon_int16x8_t k = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16( + libcrux_intrinsics_arm64__vmulq_n_u16( + libcrux_intrinsics_arm64__vreinterpretq_u16_s16(low), + (uint16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_arm_shared_neon_int16x8_t c = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)1, + libcrux_intrinsics_arm64__vqdmulhq_n_s16( + k, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_intrinsics_arm64__vsubq_s16(high, c); +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, int16_t c) { + core_core_arch_arm_shared_neon_int16x8_t v_low = + libcrux_intrinsics_arm64__vmulq_n_s16(v, c); + core_core_arch_arm_shared_neon_int16x8_t v_high = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)1, libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, c), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + v_low, v_high); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + v.low = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + v.low, c); + v.high = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + v.high, c); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( + v, c); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t half = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1664); + core_core_arch_arm_shared_neon_int16x8_t quarter = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)832); + core_core_arch_arm_shared_neon_int16x8_t shifted = + libcrux_intrinsics_arm64__vsubq_s16(half, v.low); + core_core_arch_arm_shared_neon_int16x8_t mask0 = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)15, shifted, core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t shifted_to_positive = + libcrux_intrinsics_arm64__veorq_s16(mask0, shifted); + core_core_arch_arm_shared_neon_int16x8_t shifted_positive_in_range = + libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive, quarter); + v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_u16( + libcrux_intrinsics_arm64__vshrq_n_u16( + (int32_t)15, + libcrux_intrinsics_arm64__vreinterpretq_u16_s16( + shifted_positive_in_range), + core_core_arch_arm_shared_neon_uint16x8_t)); + core_core_arch_arm_shared_neon_int16x8_t shifted0 = + libcrux_intrinsics_arm64__vsubq_s16(half, v.high); + core_core_arch_arm_shared_neon_int16x8_t mask = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)15, shifted0, core_core_arch_arm_shared_neon_int16x8_t); + core_core_arch_arm_shared_neon_int16x8_t shifted_to_positive0 = + libcrux_intrinsics_arm64__veorq_s16(mask, shifted0); + core_core_arch_arm_shared_neon_int16x8_t shifted_positive_in_range0 = + libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive0, quarter); + v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_u16( + libcrux_intrinsics_arm64__vshrq_n_u16( + (int32_t)15, + libcrux_intrinsics_arm64__vreinterpretq_u16_s16( + shifted_positive_in_range0), + core_core_arch_arm_shared_neon_uint16x8_t)); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return libcrux_ml_kem_vector_neon_simd128ops_compress_1(v); +} + +inline int16_t +libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + int16_t coefficient_bits) { + int16_t uu____0; + switch (coefficient_bits) { + case 4: { + uu____0 = (int16_t)15; + break; + } + case 5: { + uu____0 = (int16_t)31; + break; + } + case 10: { + uu____0 = (int16_t)1023; + break; + } + case 11: { + uu____0 = (int16_t)2047; + break; + } + default: { + int16_t x = coefficient_bits; + uu____0 = ((int16_t)1 << (uint32_t)x) - (int16_t)1; + } + } + return uu____0; +} + +inline core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + core_core_arch_arm_shared_neon_int16x8_t c) { + core_core_arch_arm_shared_neon_int16x8_t v_low = + libcrux_intrinsics_arm64__vmulq_s16(v, c); + core_core_arch_arm_shared_neon_int16x8_t v_high = + libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)1, libcrux_intrinsics_arm64__vqdmulhq_s16(v, c), + core_core_arch_arm_shared_neon_int16x8_t); + return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + v_low, v_high); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + int16_t zetas[8U] = {zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4}; + core_core_arch_arm_shared_neon_int16x8_t zeta = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int32x4_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t dup_a = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn1q_s32( + uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int32x4_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t dup_b = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn2q_s32( + uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t t = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, + zeta); + core_core_arch_arm_shared_neon_int16x8_t b = + libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int16x8_t a = + libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int32x4_t uu____2 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); + v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn1q_s32( + uu____2, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + core_core_arch_arm_shared_neon_int32x4_t uu____3 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); + v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn2q_s32( + uu____3, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step(a, zeta1, zeta2, + zeta3, zeta4); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2) { + int16_t zetas[8U] = {zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2}; + core_core_arch_arm_shared_neon_int16x8_t zeta = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int64x2_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t dup_a = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn1q_s64( + uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int64x2_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t dup_b = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn2q_s64( + uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t t = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, + zeta); + core_core_arch_arm_shared_neon_int16x8_t b = + libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int16x8_t a = + libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); + core_core_arch_arm_shared_neon_int64x2_t uu____2 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn1q_s64( + uu____2, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + core_core_arch_arm_shared_neon_int64x2_t uu____3 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn2q_s64( + uu____3, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2) { + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step(a, zeta1, + zeta2); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta) { + core_core_arch_arm_shared_neon_int16x8_t zeta0 = + libcrux_intrinsics_arm64__vdupq_n_s16(zeta); + core_core_arch_arm_shared_neon_int16x8_t t = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + v.high, zeta0); + v.high = libcrux_intrinsics_arm64__vsubq_s16(v.low, t); + v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, t); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta) { + return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step(a, zeta); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + int16_t zetas[8U] = {zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4}; + core_core_arch_arm_shared_neon_int16x8_t zeta = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int32x4_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t a0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn1q_s32( + uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int32x4_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t b0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn2q_s32( + uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t b_minus_a = + libcrux_intrinsics_arm64__vsubq_s16(b0, a0); + core_core_arch_arm_shared_neon_int16x8_t a = + libcrux_intrinsics_arm64__vaddq_s16(a0, b0); + core_core_arch_arm_shared_neon_int16x8_t a1 = + libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(a); + core_core_arch_arm_shared_neon_int16x8_t b = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + b_minus_a, zeta); + core_core_arch_arm_shared_neon_int32x4_t uu____2 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); + v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn1q_s32( + uu____2, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + core_core_arch_arm_shared_neon_int32x4_t uu____3 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); + v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn2q_s32( + uu____3, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( + a, zeta1, zeta2, zeta3, zeta4); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2) { + int16_t zetas[8U] = {zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2}; + core_core_arch_arm_shared_neon_int16x8_t zeta = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int64x2_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t a0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn1q_s64( + uu____0, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int64x2_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); + core_core_arch_arm_shared_neon_int16x8_t b0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn2q_s64( + uu____1, + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); + core_core_arch_arm_shared_neon_int16x8_t b_minus_a = + libcrux_intrinsics_arm64__vsubq_s16(b0, a0); + core_core_arch_arm_shared_neon_int16x8_t a = + libcrux_intrinsics_arm64__vaddq_s16(a0, b0); + core_core_arch_arm_shared_neon_int16x8_t b = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + b_minus_a, zeta); + core_core_arch_arm_shared_neon_int64x2_t uu____2 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn1q_s64( + uu____2, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + core_core_arch_arm_shared_neon_int64x2_t uu____3 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); + v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( + libcrux_intrinsics_arm64__vtrn2q_s64( + uu____3, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2) { + return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step(a, zeta1, + zeta2); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta) { + core_core_arch_arm_shared_neon_int16x8_t zeta0 = + libcrux_intrinsics_arm64__vdupq_n_s16(zeta); + core_core_arch_arm_shared_neon_int16x8_t b_minus_a = + libcrux_intrinsics_arm64__vsubq_s16(v.high, v.low); + v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, v.high); + v.high = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + b_minus_a, zeta0); + return v; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta) { + return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step(a, zeta); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + int16_t zetas[8U] = {zeta1, zeta3, -zeta1, -zeta3, + zeta2, zeta4, -zeta2, -zeta4}; + core_core_arch_arm_shared_neon_int16x8_t zeta = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t a0 = + libcrux_intrinsics_arm64__vtrn1q_s16(lhs->low, lhs->high); + core_core_arch_arm_shared_neon_int16x8_t a1 = + libcrux_intrinsics_arm64__vtrn2q_s16(lhs->low, lhs->high); + core_core_arch_arm_shared_neon_int16x8_t b0 = + libcrux_intrinsics_arm64__vtrn1q_s16(rhs->low, rhs->high); + core_core_arch_arm_shared_neon_int16x8_t b1 = + libcrux_intrinsics_arm64__vtrn2q_s16(rhs->low, rhs->high); + core_core_arch_arm_shared_neon_int16x8_t a1b1 = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(a1, + b1); + core_core_arch_arm_shared_neon_int16x4_t uu____0 = + libcrux_intrinsics_arm64__vget_low_s16(a1b1); + core_core_arch_arm_shared_neon_int32x4_t a1b1_low = + libcrux_intrinsics_arm64__vmull_s16( + uu____0, libcrux_intrinsics_arm64__vget_low_s16(zeta)); + core_core_arch_arm_shared_neon_int32x4_t a1b1_high = + libcrux_intrinsics_arm64__vmull_high_s16(a1b1, zeta); + core_core_arch_arm_shared_neon_int32x4_t uu____1 = a1b1_low; + core_core_arch_arm_shared_neon_int16x4_t uu____2 = + libcrux_intrinsics_arm64__vget_low_s16(a0); + core_core_arch_arm_shared_neon_int16x8_t fst_low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vmlal_s16( + uu____1, uu____2, libcrux_intrinsics_arm64__vget_low_s16(b0))); + core_core_arch_arm_shared_neon_int16x8_t fst_high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vmlal_high_s16(a1b1_high, a0, b0)); + core_core_arch_arm_shared_neon_int16x4_t uu____3 = + libcrux_intrinsics_arm64__vget_low_s16(a0); + core_core_arch_arm_shared_neon_int32x4_t a0b1_low = + libcrux_intrinsics_arm64__vmull_s16( + uu____3, libcrux_intrinsics_arm64__vget_low_s16(b1)); + core_core_arch_arm_shared_neon_int32x4_t a0b1_high = + libcrux_intrinsics_arm64__vmull_high_s16(a0, b1); + core_core_arch_arm_shared_neon_int32x4_t uu____4 = a0b1_low; + core_core_arch_arm_shared_neon_int16x4_t uu____5 = + libcrux_intrinsics_arm64__vget_low_s16(a1); + core_core_arch_arm_shared_neon_int16x8_t snd_low = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vmlal_s16( + uu____4, uu____5, libcrux_intrinsics_arm64__vget_low_s16(b0))); + core_core_arch_arm_shared_neon_int16x8_t snd_high = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vmlal_high_s16(a0b1_high, a1, b0)); + core_core_arch_arm_shared_neon_int16x8_t fst_low16 = + libcrux_intrinsics_arm64__vtrn1q_s16(fst_low, fst_high); + core_core_arch_arm_shared_neon_int16x8_t fst_high16 = + libcrux_intrinsics_arm64__vtrn2q_s16(fst_low, fst_high); + core_core_arch_arm_shared_neon_int16x8_t snd_low16 = + libcrux_intrinsics_arm64__vtrn1q_s16(snd_low, snd_high); + core_core_arch_arm_shared_neon_int16x8_t snd_high16 = + libcrux_intrinsics_arm64__vtrn2q_s16(snd_low, snd_high); + core_core_arch_arm_shared_neon_int16x8_t fst = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + fst_low16, fst_high16); + core_core_arch_arm_shared_neon_int16x8_t snd = + libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + snd_low16, snd_high16); + core_core_arch_arm_shared_neon_int32x4_t low0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn1q_s16(fst, snd)); + core_core_arch_arm_shared_neon_int32x4_t high0 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn2q_s16(fst, snd)); + core_core_arch_arm_shared_neon_int16x8_t low1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn1q_s32(low0, high0)); + core_core_arch_arm_shared_neon_int16x8_t high1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_s32( + libcrux_intrinsics_arm64__vtrn2q_s32(low0, high0)); + uint8_t indexes[16U] = {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, + 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U}; + core_core_arch_arm_shared_neon_uint8x16_t index = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( + (size_t)16U, indexes, uint8_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t low2 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u8( + libcrux_intrinsics_arm64__vqtbl1q_u8( + libcrux_intrinsics_arm64__vreinterpretq_u8_s16(low1), index)); + core_core_arch_arm_shared_neon_int16x8_t high2 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u8( + libcrux_intrinsics_arm64__vqtbl1q_u8( + libcrux_intrinsics_arm64__vreinterpretq_u8_s16(high1), index)); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){.low = low2, + .high = high2}); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4) { + return libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( + lhs, rhs, zeta1, zeta2, zeta3, zeta4); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[2U]) { + int16_t shifter[8U] = {(int16_t)0, (int16_t)1, (int16_t)2, (int16_t)3, + (int16_t)4, (int16_t)5, (int16_t)6, (int16_t)7}; + core_core_arch_arm_shared_neon_int16x8_t shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( + (size_t)8U, shifter, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t low0 = + libcrux_intrinsics_arm64__vshlq_s16(v.low, shift); + core_core_arch_arm_shared_neon_int16x8_t high0 = + libcrux_intrinsics_arm64__vshlq_s16(v.high, shift); + int16_t low = libcrux_intrinsics_arm64__vaddvq_s16(low0); + int16_t high = libcrux_intrinsics_arm64__vaddvq_s16(high0); + ret[0U] = (uint8_t)low; + ret[1U] = (uint8_t)high; +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_1(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a) { + core_core_arch_arm_shared_neon_int16x8_t one = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1); + core_core_arch_arm_shared_neon_int16x8_t low0 = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index( + a, (size_t)0U, uint8_t, uint8_t *, uint8_t)); + core_core_arch_arm_shared_neon_int16x8_t high0 = + libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index( + a, (size_t)1U, uint8_t, uint8_t *, uint8_t)); + int16_t shifter[8U] = {(int16_t)0, (int16_t)255, (int16_t)-2, (int16_t)-3, + (int16_t)-4, (int16_t)-5, (int16_t)-6, (int16_t)-7}; + core_core_arch_arm_shared_neon_int16x8_t shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( + (size_t)8U, shifter, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vshlq_s16(low0, shift); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vshlq_s16(high0, shift); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vandq_s16(low, one); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .low = uu____0, .high = libcrux_intrinsics_arm64__vandq_s16(high, one)}); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(a); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[8U]) { + int16_t shifter[8U] = {(int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12, + (int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12}; + core_core_arch_arm_shared_neon_int16x8_t shift = + libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( + (size_t)8U, shifter, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t lowt = + libcrux_intrinsics_arm64__vshlq_u16( + libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.low), shift); + core_core_arch_arm_shared_neon_uint16x8_t hight = + libcrux_intrinsics_arm64__vshlq_u16( + libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.high), shift); + uint64_t sum0 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( + libcrux_intrinsics_arm64__vget_low_u16(lowt)); + uint64_t sum1 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( + libcrux_intrinsics_arm64__vget_high_u16(lowt)); + uint64_t sum2 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( + libcrux_intrinsics_arm64__vget_low_u16(hight)); + uint64_t sum3 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( + libcrux_intrinsics_arm64__vget_high_u16(hight)); + uint64_t sum = ((sum0 | sum1 << 16U) | sum2 << 32U) | sum3 << 48U; + uint8_t ret0[8U]; + core_num__u64_9__to_le_bytes(sum, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_4(a, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v) { + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2(&dst, v, Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t input = core_num__u64_9__from_le_bytes(ret); + int16_t low[8U] = {0U}; + int16_t high[8U] = {0U}; + low[0U] = (int16_t)(input & 15ULL); + low[1U] = (int16_t)(input >> 4U & 15ULL); + low[2U] = (int16_t)(input >> 8U & 15ULL); + low[3U] = (int16_t)(input >> 12U & 15ULL); + low[4U] = (int16_t)(input >> 16U & 15ULL); + low[5U] = (int16_t)(input >> 20U & 15ULL); + low[6U] = (int16_t)(input >> 24U & 15ULL); + low[7U] = (int16_t)(input >> 28U & 15ULL); + high[0U] = (int16_t)(input >> 32U & 15ULL); + high[1U] = (int16_t)(input >> 36U & 15ULL); + high[2U] = (int16_t)(input >> 40U & 15ULL); + high[3U] = (int16_t)(input >> 44U & 15ULL); + high[4U] = (int16_t)(input >> 48U & 15ULL); + high[5U] = (int16_t)(input >> 52U & 15ULL); + high[6U] = (int16_t)(input >> 56U & 15ULL); + high[7U] = (int16_t)(input >> 60U & 15ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); + lit.high = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(a); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t ret[16U]) { + int16_t out[16U] = {0U}; + libcrux_intrinsics_arm64__vst1q_s16( + Eurydice_array_to_subslice((size_t)16U, out, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice), + v.low); + libcrux_intrinsics_arm64__vst1q_s16( + Eurydice_array_to_subslice((size_t)16U, out, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice), + v.high); + memcpy(ret, out, (size_t)16U * sizeof(int16_t)); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[10U]) { + uint8_t res[10U] = {0U}; + int16_t out[16U]; + libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, out); + res[0U] = (uint8_t)(out[0U] | out[1U] << 5U); + res[1U] = (uint8_t)((out[1U] >> 3U | out[2U] << 2U) | out[3U] << 7U); + res[2U] = (uint8_t)(out[3U] >> 1U | out[4U] << 4U); + res[3U] = (uint8_t)((out[4U] >> 4U | out[5U] << 1U) | out[6U] << 6U); + res[4U] = (uint8_t)(out[6U] >> 2U | out[7U] << 3U); + res[5U] = (uint8_t)(out[(size_t)8U + (size_t)0U] | + out[(size_t)8U + (size_t)1U] << 5U); + res[6U] = (uint8_t)((out[(size_t)8U + (size_t)1U] >> 3U | + out[(size_t)8U + (size_t)2U] << 2U) | + out[(size_t)8U + (size_t)3U] << 7U); + res[7U] = (uint8_t)(out[(size_t)8U + (size_t)3U] >> 1U | + out[(size_t)8U + (size_t)4U] << 4U); + res[8U] = (uint8_t)((out[(size_t)8U + (size_t)4U] >> 4U | + out[(size_t)8U + (size_t)5U] << 1U) | + out[(size_t)8U + (size_t)6U] << 6U); + res[9U] = (uint8_t)(out[(size_t)8U + (size_t)6U] >> 2U | + out[(size_t)8U + (size_t)7U] << 3U); + memcpy(ret, res, (size_t)10U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[10U]) { + uint8_t ret0[10U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_5(a, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v) { + uint8_t input0[8U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)8U, input0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)5U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + uint8_t uu____1[8U]; + memcpy(uu____1, input0, (size_t)8U * sizeof(uint8_t)); + uint64_t low64 = core_num__u64_9__from_le_bytes(uu____1); + uint8_t input1[8U] = {0U}; + Eurydice_slice uu____2 = Eurydice_array_to_subslice( + (size_t)8U, input1, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)5U, .end = (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input1, (size_t)8U * sizeof(uint8_t)); + uint64_t high64 = core_num__u64_9__from_le_bytes(uu____3); + int16_t low[8U] = {0U}; + int16_t high[8U] = {0U}; + low[0U] = (int16_t)(low64 & 31ULL); + low[1U] = (int16_t)(low64 >> 5U & 31ULL); + low[2U] = (int16_t)(low64 >> 10U & 31ULL); + low[3U] = (int16_t)(low64 >> 15U & 31ULL); + low[4U] = (int16_t)(low64 >> 20U & 31ULL); + low[5U] = (int16_t)(low64 >> 25U & 31ULL); + low[6U] = (int16_t)(low64 >> 30U & 31ULL); + low[7U] = (int16_t)(low64 >> 35U & 31ULL); + high[0U] = (int16_t)(high64 & 31ULL); + high[1U] = (int16_t)(high64 >> 5U & 31ULL); + high[2U] = (int16_t)(high64 >> 10U & 31ULL); + high[3U] = (int16_t)(high64 >> 15U & 31ULL); + high[4U] = (int16_t)(high64 >> 20U & 31ULL); + high[5U] = (int16_t)(high64 >> 25U & 31ULL); + high[6U] = (int16_t)(high64 >> 30U & 31ULL); + high[7U] = (int16_t)(high64 >> 35U & 31ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); + lit.high = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(a); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[20U]) { + core_core_arch_arm_shared_neon_int32x4_t low00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn1q_s16(v.low, v.low)); + core_core_arch_arm_shared_neon_int32x4_t low10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn2q_s16(v.low, v.low)); + core_core_arch_arm_shared_neon_int32x4_t mixt = + libcrux_intrinsics_arm64__vsliq_n_s32( + (int32_t)10, low00, low10, core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t low0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn1q_s32(mixt, mixt)); + core_core_arch_arm_shared_neon_int64x2_t low1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn2q_s32(mixt, mixt)); + core_core_arch_arm_shared_neon_int64x2_t low_mix = + libcrux_intrinsics_arm64__vsliq_n_s64( + (int32_t)20, low0, low1, core_core_arch_arm_shared_neon_int64x2_t); + core_core_arch_arm_shared_neon_int32x4_t high00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn1q_s16(v.high, v.high)); + core_core_arch_arm_shared_neon_int32x4_t high10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn2q_s16(v.high, v.high)); + core_core_arch_arm_shared_neon_int32x4_t mixt0 = + libcrux_intrinsics_arm64__vsliq_n_s32( + (int32_t)10, high00, high10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t high0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, mixt0)); + core_core_arch_arm_shared_neon_int64x2_t high1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, mixt0)); + core_core_arch_arm_shared_neon_int64x2_t high_mix = + libcrux_intrinsics_arm64__vsliq_n_s64( + (int32_t)20, high0, high1, core_core_arch_arm_shared_neon_int64x2_t); + uint8_t result32[32U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, result32, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); + Eurydice_slice uu____1 = Eurydice_array_to_subslice( + (size_t)32U, result32, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); + uint8_t result[20U] = {0U}; + Eurydice_slice uu____2 = Eurydice_array_to_subslice( + (size_t)20U, result, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)5U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_array_to_subslice( + (size_t)20U, result, + ((core_ops_range_Range__size_t){.start = (size_t)5U, .end = (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)13U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)20U, result, + ((core_ops_range_Range__size_t){.start = (size_t)10U, + .end = (size_t)15U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)21U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)20U, result, + ((core_ops_range_Range__size_t){.start = (size_t)15U, + .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)29U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_10(a, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v) { + uint8_t input0[8U] = {0U}; + uint8_t input1[8U] = {0U}; + uint8_t input2[4U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)4U, input2, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input0, (size_t)8U * sizeof(uint8_t)); + uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); + uint8_t uu____4[8U]; + memcpy(uu____4, input1, (size_t)8U * sizeof(uint8_t)); + uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); + uint8_t uu____5[4U]; + memcpy(uu____5, input2, (size_t)4U * sizeof(uint8_t)); + uint32_t input20 = core_num__u32_8__from_le_bytes(uu____5); + int16_t low[8U] = {0U}; + int16_t high[8U] = {0U}; + low[0U] = (int16_t)(input00 & 1023ULL); + low[1U] = (int16_t)(input00 >> 10U & 1023ULL); + low[2U] = (int16_t)(input00 >> 20U & 1023ULL); + low[3U] = (int16_t)(input00 >> 30U & 1023ULL); + low[4U] = (int16_t)(input00 >> 40U & 1023ULL); + low[5U] = (int16_t)(input00 >> 50U & 1023ULL); + low[6U] = (int16_t)((input00 >> 60U | input10 << 4U) & 1023ULL); + low[7U] = (int16_t)(input10 >> 6U & 1023ULL); + high[0U] = (int16_t)(input10 >> 16U & 1023ULL); + high[1U] = (int16_t)(input10 >> 26U & 1023ULL); + high[2U] = (int16_t)(input10 >> 36U & 1023ULL); + high[3U] = (int16_t)(input10 >> 46U & 1023ULL); + high[4U] = (int16_t)(((uint32_t)(input10 >> 56U) | input20 << 8U) & 1023U); + high[5U] = (int16_t)(input20 >> 2U & 1023U); + high[6U] = (int16_t)(input20 >> 12U & 1023U); + high[7U] = (int16_t)(input20 >> 22U & 1023U); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); + lit.high = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(a); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[22U]) { + int16_t input[16U]; + libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, input); + uint8_t result[22U] = {0U}; + result[0U] = (uint8_t)input[0U]; + result[1U] = (uint8_t)(input[0U] >> 8U | input[1U] << 3U); + result[2U] = (uint8_t)(input[1U] >> 5U | input[2U] << 6U); + result[3U] = (uint8_t)(input[2U] >> 2U); + result[4U] = (uint8_t)(input[2U] >> 10U | input[3U] << 1U); + result[5U] = (uint8_t)(input[3U] >> 7U | input[4U] << 4U); + result[6U] = (uint8_t)(input[4U] >> 4U | input[5U] << 7U); + result[7U] = (uint8_t)(input[5U] >> 1U); + result[8U] = (uint8_t)(input[5U] >> 9U | input[6U] << 2U); + result[9U] = (uint8_t)(input[6U] >> 6U | input[7U] << 5U); + result[10U] = (uint8_t)(input[7U] >> 3U); + result[(size_t)11U + (size_t)0U] = (uint8_t)input[(size_t)8U + (size_t)0U]; + result[(size_t)11U + (size_t)1U] = + (uint8_t)(input[(size_t)8U + (size_t)0U] >> 8U | + input[(size_t)8U + (size_t)1U] << 3U); + result[(size_t)11U + (size_t)2U] = + (uint8_t)(input[(size_t)8U + (size_t)1U] >> 5U | + input[(size_t)8U + (size_t)2U] << 6U); + result[(size_t)11U + (size_t)3U] = + (uint8_t)(input[(size_t)8U + (size_t)2U] >> 2U); + result[(size_t)11U + (size_t)4U] = + (uint8_t)(input[(size_t)8U + (size_t)2U] >> 10U | + input[(size_t)8U + (size_t)3U] << 1U); + result[(size_t)11U + (size_t)5U] = + (uint8_t)(input[(size_t)8U + (size_t)3U] >> 7U | + input[(size_t)8U + (size_t)4U] << 4U); + result[(size_t)11U + (size_t)6U] = + (uint8_t)(input[(size_t)8U + (size_t)4U] >> 4U | + input[(size_t)8U + (size_t)5U] << 7U); + result[(size_t)11U + (size_t)7U] = + (uint8_t)(input[(size_t)8U + (size_t)5U] >> 1U); + result[(size_t)11U + (size_t)8U] = + (uint8_t)(input[(size_t)8U + (size_t)5U] >> 9U | + input[(size_t)8U + (size_t)6U] << 2U); + result[(size_t)11U + (size_t)9U] = + (uint8_t)(input[(size_t)8U + (size_t)6U] >> 6U | + input[(size_t)8U + (size_t)7U] << 5U); + result[(size_t)11U + (size_t)10U] = + (uint8_t)(input[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[22U]) { + uint8_t ret0[22U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_11(a, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v) { + uint8_t input0[8U] = {0U}; + uint8_t input1[8U] = {0U}; + uint8_t input2[8U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_array_to_subslice( + (size_t)8U, input2, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)6U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + uint8_t uu____3[8U]; + memcpy(uu____3, input0, (size_t)8U * sizeof(uint8_t)); + uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); + uint8_t uu____4[8U]; + memcpy(uu____4, input1, (size_t)8U * sizeof(uint8_t)); + uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); + uint8_t uu____5[8U]; + memcpy(uu____5, input2, (size_t)8U * sizeof(uint8_t)); + uint64_t input20 = core_num__u64_9__from_le_bytes(uu____5); + int16_t low[8U] = {0U}; + int16_t high[8U] = {0U}; + low[0U] = (int16_t)(input00 & 2047ULL); + low[1U] = (int16_t)(input00 >> 11U & 2047ULL); + low[2U] = (int16_t)(input00 >> 22U & 2047ULL); + low[3U] = (int16_t)(input00 >> 33U & 2047ULL); + low[4U] = (int16_t)(input00 >> 44U & 2047ULL); + low[5U] = (int16_t)((input00 >> 55U | input10 << 9U) & 2047ULL); + low[6U] = (int16_t)(input10 >> 2U & 2047ULL); + low[7U] = (int16_t)(input10 >> 13U & 2047ULL); + high[0U] = (int16_t)(input10 >> 24U & 2047ULL); + high[1U] = (int16_t)(input10 >> 35U & 2047ULL); + high[2U] = (int16_t)(input10 >> 46U & 2047ULL); + high[3U] = (int16_t)((input10 >> 57U | input20 << 7U) & 2047ULL); + high[4U] = (int16_t)(input20 >> 4U & 2047ULL); + high[5U] = (int16_t)(input20 >> 15U & 2047ULL); + high[6U] = (int16_t)(input20 >> 26U & 2047ULL); + high[7U] = (int16_t)(input20 >> 37U & 2047ULL); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; + lit.low = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); + lit.high = libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); + return lit; +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(a); +} + +inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[24U]) { + core_core_arch_arm_shared_neon_int32x4_t low00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn1q_s16(v.low, v.low)); + core_core_arch_arm_shared_neon_int32x4_t low10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn2q_s16(v.low, v.low)); + core_core_arch_arm_shared_neon_int32x4_t mixt = + libcrux_intrinsics_arm64__vsliq_n_s32( + (int32_t)12, low00, low10, core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t low0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn1q_s32(mixt, mixt)); + core_core_arch_arm_shared_neon_int64x2_t low1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn2q_s32(mixt, mixt)); + core_core_arch_arm_shared_neon_int64x2_t low_mix = + libcrux_intrinsics_arm64__vsliq_n_s64( + (int32_t)24, low0, low1, core_core_arch_arm_shared_neon_int64x2_t); + core_core_arch_arm_shared_neon_int32x4_t high00 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn1q_s16(v.high, v.high)); + core_core_arch_arm_shared_neon_int32x4_t high10 = + libcrux_intrinsics_arm64__vreinterpretq_s32_s16( + libcrux_intrinsics_arm64__vtrn2q_s16(v.high, v.high)); + core_core_arch_arm_shared_neon_int32x4_t mixt0 = + libcrux_intrinsics_arm64__vsliq_n_s32( + (int32_t)12, high00, high10, + core_core_arch_arm_shared_neon_int32x4_t); + core_core_arch_arm_shared_neon_int64x2_t high0 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, mixt0)); + core_core_arch_arm_shared_neon_int64x2_t high1 = + libcrux_intrinsics_arm64__vreinterpretq_s64_s32( + libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, mixt0)); + core_core_arch_arm_shared_neon_int64x2_t high_mix = + libcrux_intrinsics_arm64__vsliq_n_s64( + (int32_t)24, high0, high1, core_core_arch_arm_shared_neon_int64x2_t); + uint8_t result32[32U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, result32, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); + Eurydice_slice uu____1 = Eurydice_array_to_subslice( + (size_t)32U, result32, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_intrinsics_arm64__vst1q_u8( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); + uint8_t result[24U] = {0U}; + Eurydice_slice uu____2 = Eurydice_array_to_subslice( + (size_t)24U, result, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)6U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)6U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_array_to_subslice( + (size_t)24U, result, + ((core_ops_range_Range__size_t){.start = (size_t)6U, .end = (size_t)12U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)14U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)24U, result, + ((core_ops_range_Range__size_t){.start = (size_t)12U, + .end = (size_t)18U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)24U, result, + ((core_ops_range_Range__size_t){.start = (size_t)18U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_array_to_subslice((size_t)32U, result32, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)30U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_neon_simd128ops_serialize_12(a, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v) { + uint8_t indexes[16U] = {0U, 1U, 1U, 2U, 3U, 4U, 4U, 5U, + 6U, 7U, 7U, 8U, 9U, 10U, 10U, 11U}; + core_core_arch_arm_shared_neon_uint8x16_t index_vec = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( + (size_t)16U, indexes, uint8_t, Eurydice_slice)); + int16_t shifts[8U] = {(int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, + (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4}; + core_core_arch_arm_shared_neon_int16x8_t shift_vec = + libcrux_intrinsics_arm64__vld1q_s16( + Eurydice_array_to_slice((size_t)8U, shifts, int16_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t mask12 = + libcrux_intrinsics_arm64__vdupq_n_u16(4095U); + uint8_t input0[16U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)16U, input0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)12U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)12U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_arm_shared_neon_uint8x16_t input_vec0 = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( + (size_t)16U, input0, uint8_t, Eurydice_slice)); + uint8_t input1[16U] = {0U}; + Eurydice_slice uu____1 = Eurydice_array_to_subslice( + (size_t)16U, input1, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)12U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_slice_subslice(v, + ((core_ops_range_Range__size_t){ + .start = (size_t)12U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_arm_shared_neon_uint8x16_t input_vec1 = + libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( + (size_t)16U, input1, uint8_t, Eurydice_slice)); + core_core_arch_arm_shared_neon_uint16x8_t moved0 = + libcrux_intrinsics_arm64__vreinterpretq_u16_u8( + libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec0, index_vec)); + core_core_arch_arm_shared_neon_uint16x8_t shifted0 = + libcrux_intrinsics_arm64__vshlq_u16(moved0, shift_vec); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16( + libcrux_intrinsics_arm64__vandq_u16(shifted0, mask12)); + core_core_arch_arm_shared_neon_uint16x8_t moved1 = + libcrux_intrinsics_arm64__vreinterpretq_u16_u8( + libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec1, index_vec)); + core_core_arch_arm_shared_neon_uint16x8_t shifted1 = + libcrux_intrinsics_arm64__vshlq_u16(moved1, shift_vec); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vreinterpretq_s16_u16( + libcrux_intrinsics_arm64__vandq_u16(shifted1, mask12)); + return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){.low = low, + .high = high}); +} + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + Eurydice_slice a) { + return libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(a); +} + +inline size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, + Eurydice_slice result) { + size_t sampled = (size_t)0U; + core_slice_iter_Chunks iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + core_slice___Slice_T___chunks(a, (size_t)3U, uint8_t, + core_slice_iter_Chunks), + core_slice_iter_Chunks, core_slice_iter_Chunks); + while (true) { + core_option_Option__Eurydice_slice_uint8_t uu____0 = + core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( + &iter, uint8_t, core_option_Option__Eurydice_slice_uint8_t); + if (uu____0.tag == core_option_None) { + break; + } else { + Eurydice_slice bytes = uu____0.f0; + int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____1; + int16_t uu____2; + bool uu____3; + size_t uu____4; + int16_t uu____5; + size_t uu____6; + int16_t uu____7; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + int16_t uu____8 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = + uu____8; + sampled++; + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; + if (uu____1) { + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, + int16_t) = uu____5; + sampled++; + continue; + } + } + continue; + } + } + uu____2 = d2; + uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____1 = uu____2 < uu____7; + if (uu____1) { + uu____4 = sampled; + uu____3 = uu____4 < (size_t)16U; + if (uu____3) { + uu____5 = d2; + uu____6 = sampled; + Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = + uu____5; + sampled++; + continue; + } + } + } + } + return sampled; +} + +size_t +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + Eurydice_slice a, Eurydice_slice out) { + return libcrux_ml_kem_vector_neon_rej_sample(a, out); +} + +inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self) { + return self[0U]; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +shift_right___15int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + v.low = libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)15, v.low, core_core_arch_arm_shared_neon_int16x8_t); + v.high = libcrux_intrinsics_arm64__vshrq_n_s16( + (int32_t)15, v.high, core_core_arch_arm_shared_neon_int16x8_t); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +shift_right___15int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return shift_right___15int32_t(v); +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a) { + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = + shift_right___15int32_t0(a); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fm = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + a, &fm); +} + +static inline void +serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_neon_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +typedef struct Simd128Hash_s { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + shake128_state[2U]; +} Simd128Hash; + +static inline Simd128Hash shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + uu____1, uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = &state[1U]; + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + uu____3, uu____4, + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy( + lit.shake128_state, state, + (size_t)2U * + sizeof( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); + return lit; +} + +static inline void shake128_squeeze_three_blocks___3size_t( + Simd128Hash *self, uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t extra[504U] = {0U}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = self->shake128_state; + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + uu____2, uu____3, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____4 = &self->shake128_state[1U]; + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + uu____4, uu____5, + Eurydice_array_to_slice((size_t)504U, extra, uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___3size_t(Simd128Hash *self, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + uu____0, uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &self->shake128_state[1U]; + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( + Eurydice_slice_subslice( + a, + ((core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + Simd128Hash xof_state = shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [3U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[3U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t extra[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____2, uu____3, uu____4, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)128U, extra, uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + randomness); + return uu____0; +} + +static inline void +ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____1 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +typedef struct + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector snd; +} __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t fer) { + return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + v, fer); +} + +static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, int16_t zeta_r) { + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = + montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + b, zeta_r); + b = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + a, &t); + a = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + a, &t); + return (( + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .fst = a, .snd = b}); +} + +static inline void +ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void +ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void +ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); + size_t zeta_i = (size_t)1U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + out = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs) { + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + self->coefficients[j]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_neon_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + uint8_t dummy[128U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t0(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, int16_t zeta_r) { + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a_minus_b = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + b, &a); + a = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + a, &b)); + b = montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + a_minus_b, zeta_r); + return (( + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ + .fst = a, .snd = b}); +} + +static inline void +invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_compressed = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector tmp = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + self->coefficients[i0], &message->coefficients[i0]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector tmp0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + coefficient_normal_form, &tmp); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + error_2, message, result); + return result; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t half = + libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t compressed = + libcrux_intrinsics_arm64__vshlq_n_u32( + (int32_t)10, v, core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t compressed0 = + libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32( + libcrux_intrinsics_arm64__vqdmulhq_n_s32( + libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___10int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t mask = + libcrux_intrinsics_arm64__vdupq_n_s16( + libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + (int16_t)(int32_t)10)); + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + compress_int32x4_t___10int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + compress_int32x4_t___10int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + compress_int32x4_t___10int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + compress_int32x4_t___10int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___10int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return compress___10int32_t(v); +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + compress___10int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t half = + libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t compressed = + libcrux_intrinsics_arm64__vshlq_n_u32( + (int32_t)11, v, core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t compressed0 = + libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32( + libcrux_intrinsics_arm64__vqdmulhq_n_s32( + libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___11int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t mask = + libcrux_intrinsics_arm64__vdupq_n_s16( + libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + (int16_t)(int32_t)11)); + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + compress_int32x4_t___11int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + compress_int32x4_t___11int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + compress_int32x4_t___11int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + compress_int32x4_t___11int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___11int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return compress___11int32_t(v); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + compress___11int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t half = + libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t compressed = + libcrux_intrinsics_arm64__vshlq_n_u32( + (int32_t)4, v, core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t compressed0 = + libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32( + libcrux_intrinsics_arm64__vqdmulhq_n_s32( + libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___4int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t mask = + libcrux_intrinsics_arm64__vdupq_n_s16( + libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + (int16_t)(int32_t)4)); + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + compress_int32x4_t___4int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + compress_int32x4_t___4int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + compress_int32x4_t___4int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + compress_int32x4_t___4int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector compress___4int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return compress___4int32_t(v); +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + compress___4int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +compress_int32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t half = + libcrux_intrinsics_arm64__vdupq_n_u32(1664U); + core_core_arch_arm_shared_neon_uint32x4_t compressed = + libcrux_intrinsics_arm64__vshlq_n_u32( + (int32_t)5, v, core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t compressed0 = + libcrux_intrinsics_arm64__vaddq_u32(compressed, half); + core_core_arch_arm_shared_neon_uint32x4_t compressed1 = + libcrux_intrinsics_arm64__vreinterpretq_u32_s32( + libcrux_intrinsics_arm64__vqdmulhq_n_s32( + libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), + (int32_t)10321340)); + core_core_arch_arm_shared_neon_uint32x4_t compressed2 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); + return compressed2; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compress___5int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_int16x8_t mask = + libcrux_intrinsics_arm64__vdupq_n_s16( + libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + (int16_t)(int32_t)5)); + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + compress_int32x4_t___5int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + compress_int32x4_t___5int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + compress_int32x4_t___5int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + compress_int32x4_t___5int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + core_core_arch_arm_shared_neon_int16x8_t low = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + core_core_arch_arm_shared_neon_int16x8_t high = + libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); + v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector compress___5int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return compress___5int32_t(v); +} + +static inline void +compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients = + compress___5int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice out) { + compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + /* + printf("pk:"); + for (int i = 0; i < 16; i++) + printf("%02x, ",public_key->value[i]); + printf("\n"); + printf("hashed:"); + for (int i = 0; i < 32; i++) + printf("%02x, ",ret[i]); + printf("\n"); + */ + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t coeff = + libcrux_intrinsics_arm64__vdupq_n_u32( + 1U << (uint32_t)((int32_t)10 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32( + v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = + libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)10, decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___10int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + decompress_uint32x4_t___10int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + decompress_uint32x4_t___10int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + decompress_uint32x4_t___10int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + decompress_uint32x4_t___10int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___10int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return decompress_ciphertext_coefficient___10int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( + bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + decompress_ciphertext_coefficient___10int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t coeff = + libcrux_intrinsics_arm64__vdupq_n_u32( + 1U << (uint32_t)((int32_t)11 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32( + v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = + libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)11, decompressed0, + core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___11int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + decompress_uint32x4_t___11int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + decompress_uint32x4_t___11int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + decompress_uint32x4_t___11int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + decompress_uint32x4_t___11int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___11int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return decompress_ciphertext_coefficient___11int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( + bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + decompress_ciphertext_coefficient___11int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t coeff = + libcrux_intrinsics_arm64__vdupq_n_u32( + 1U << (uint32_t)((int32_t)4 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32( + v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = + libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)4, decompressed0, core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___4int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + decompress_uint32x4_t___4int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + decompress_uint32x4_t___4int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + decompress_uint32x4_t___4int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + decompress_uint32x4_t___4int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___4int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return decompress_ciphertext_coefficient___4int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( + bytes); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + decompress_ciphertext_coefficient___4int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_arm_shared_neon_uint32x4_t +decompress_uint32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { + core_core_arch_arm_shared_neon_uint32x4_t coeff = + libcrux_intrinsics_arm64__vdupq_n_u32( + 1U << (uint32_t)((int32_t)5 - (int32_t)1)); + core_core_arch_arm_shared_neon_uint32x4_t decompressed = + libcrux_intrinsics_arm64__vmulq_n_u32( + v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = + libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); + core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)5, decompressed0, core_core_arch_arm_shared_neon_uint32x4_t); + return decompressed1; +} + +static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___5int32_t( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + core_core_arch_arm_shared_neon_uint32x4_t mask16 = + libcrux_intrinsics_arm64__vdupq_n_u32(65535U); + core_core_arch_arm_shared_neon_uint32x4_t low00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); + core_core_arch_arm_shared_neon_uint32x4_t low10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t high00 = + libcrux_intrinsics_arm64__vandq_u32( + libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); + core_core_arch_arm_shared_neon_uint32x4_t high10 = + libcrux_intrinsics_arm64__vshrq_n_u32( + (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), + core_core_arch_arm_shared_neon_uint32x4_t); + core_core_arch_arm_shared_neon_uint32x4_t low0 = + decompress_uint32x4_t___5int32_t(low00); + core_core_arch_arm_shared_neon_uint32x4_t low1 = + decompress_uint32x4_t___5int32_t(low10); + core_core_arch_arm_shared_neon_uint32x4_t high0 = + decompress_uint32x4_t___5int32_t(high00); + core_core_arch_arm_shared_neon_uint32x4_t high1 = + decompress_uint32x4_t___5int32_t(high10); + core_core_arch_arm_shared_neon_int16x8_t uu____0 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); + v.low = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); + core_core_arch_arm_shared_neon_int16x8_t uu____1 = + libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); + v.high = libcrux_intrinsics_arm64__vtrn1q_s16( + uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); + return v; +} + +static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +decompress_ciphertext_coefficient___5int32_t0( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { + return decompress_ciphertext_coefficient___5int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____1 = + decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t1(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + self->coefficients[i0], &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + v, result); + return result; +} + +static inline void +compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re.coefficients[i0]); + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_compressed = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + uint8_t dummy[32U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1536U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1568U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[4U]; + memcpy( + uu____1, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[4U]; + memcpy( + uu____0, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_neon_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline Simd128Hash shake128_init_absorb___4size_t( + uint8_t input[4U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + uu____1, uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = &state[1U]; + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + uu____3, uu____4, + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy( + lit.shake128_state, state, + (size_t)2U * + sizeof( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); + return lit; +} + +static inline void shake128_squeeze_three_blocks___4size_t( + Simd128Hash *self, uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____3 = self->shake128_state; + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + uu____3, uu____4, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____5 = &self->shake128_state[1U]; + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___4size_t(Simd128Hash *self, + uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + uu____0, uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____2 = &self->shake128_state[1U]; + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____7[168U]; + memcpy(uu____7, out3, (size_t)168U * sizeof(uint8_t)); + memcpy(out[3U], uu____7, (size_t)168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); + Simd128Hash xof_state = shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U][4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [4U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[4U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____3, uu____4, uu____5, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = + Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____6, uu____7, uu____8, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[4U]; + memcpy( + uu____2, re_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs) { + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___4size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[4U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[4U]; + memcpy( + uu____4, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[4U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_neon_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)3168U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___4size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( + uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[4U]; + memcpy( + uu____2, error_1, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___4size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + uint8_t dummy[128U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t0(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + error_2, message, result); + return result; +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + compress___10int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = + compress___11int32_t0( + to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re, + uint8_t ret[352U]) { + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[4U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re, + Eurydice_slice out) { + compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1568U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[4U][4U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[4U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[4U]; + memcpy( + error_1, uu____3.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___4size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1568U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[4U]; + memcpy( + uu____5, u, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1408U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___4size_t( + Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, + re); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + serialized); + return uu____0; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t1(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + uint8_t dummy[32U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1536U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1568U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + key[2U], + uint8_t ret[768U]) { + uint8_t out[768U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)768U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U], + Eurydice_slice seed_for_a, uint8_t ret[800U]) { + uint8_t public_key_serialized[800U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)800U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1[2U]; + memcpy( + uu____1, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, + (size_t)768U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( + Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0[2U]; + memcpy( + uu____0, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_neon_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static void +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline Simd128Hash shake128_init_absorb___2size_t( + uint8_t input[2U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = state; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + uu____1, uu____2, + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); + Simd128Hash lit; + memcpy( + lit.shake128_state, state, + (size_t)2U * + sizeof( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); + return lit; +} + +static inline void shake128_squeeze_three_blocks___2size_t( + Simd128Hash *self, uint8_t ret[2U][504U]) { + uint8_t out[2U][504U] = {{0U}}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____1 = self->shake128_state; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + uu____1, uu____2, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( + uint8_t randomness[2U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___2size_t(Simd128Hash *self, + uint8_t ret[2U][168U]) { + uint8_t out[2U][168U] = {{0U}}; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + *uu____0 = self->shake128_state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + uu____0, uu____1, + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); + uint8_t uu____2[168U]; + memcpy(uu____2, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____2, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____3[168U]; + memcpy(uu____3, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____3, (size_t)168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( + uint8_t randomness[2U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + size_t sampled_coefficients[2U] = {0U}; + int16_t out[2U][272U] = {{0U}}; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); + Simd128Hash xof_state = shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U][2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( + A_transpose[i]);); + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [2U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + fst[2U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t; + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], + uint8_t ret[2U][192U]) { + uint8_t out[2U][192U] = {{0U}}; + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], + Eurydice_slice), + (size_t)1U, uint8_t[192U], + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____1, uu____2, uu____3, + Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], + uint8_t(*)[192U], uint8_t[192U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + re_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( + Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[2U]; + memcpy( + uu____2, re_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *rhs) { + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = + libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___2size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_as_ntt[2U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + uu____3, domain_separator) + .fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____4[2U]; + memcpy( + uu____4, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[2U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); + return lit; +} + +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_neon_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)1632U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___2size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( + uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uu____4)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[2U][128U]) { + uint8_t out[2U][128U] = {{0U}}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____1, uu____2, uu____3, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + error_1[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____2[2U]; + memcpy( + uu____2, error_1, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___2size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + uint8_t dummy[128U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t0(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( + *a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result); + result = + add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + error_2, message, result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + input[2U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[768U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( + Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + A_transpose[2U][2U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + r_as_ntt[2U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_1[2U]; + memcpy( + error_1, uu____3.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___2size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[768U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____5[2U]; + memcpy( + uu____5, u, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)640U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___2size_t( + Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( + void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + u_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t1(void) { + return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + secret_as_ntt[i] = + ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + product = + ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, + (size_t)640U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector + message = + compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + uint8_t dummy[32U] = {0U}; + Eurydice_slice uu____0 = input; + Eurydice_slice uu____1 = input; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); + libcrux_sha3_neon_x2_shake256( + uu____0, uu____1, uu____2, + Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)768U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)800U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___2size_t_32size_t( + Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/libcrux_mlkem_neon.h new file mode 100644 index 000000000..426ef9f47 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.h @@ -0,0 +1,301 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem_neon_H +#define __libcrux_mlkem_neon_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem_portable.h" +#include "libcrux_sha3_neon.h" + +typedef struct libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { + core_core_arch_arm_shared_neon_int16x8_t low; + core_core_arch_arm_shared_neon_int16x8_t high; +} libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ZERO(void); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( + void); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( + Eurydice_slice array); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +#define LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER \ + ((int16_t)20159) + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t low, + core_core_arch_arm_shared_neon_int16x8_t high); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); + +int16_t libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( + int16_t coefficient_bits); + +core_core_arch_arm_shared_neon_int16x8_t +libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( + core_core_arch_arm_shared_neon_int16x8_t v, + core_core_arch_arm_shared_neon_int16x8_t c); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, + int16_t zeta2); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, + int16_t zeta2); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, + int16_t zeta2, int16_t zeta3, int16_t zeta4); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[2U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[2U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( + Eurydice_slice a); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[8U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[8U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( + Eurydice_slice a); + +void libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t ret[16U]); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[10U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[10U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( + Eurydice_slice a); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[20U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[20U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( + Eurydice_slice a); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[22U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[22U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( + Eurydice_slice a); + +void libcrux_ml_kem_vector_neon_simd128ops_serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[24U]); + +void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[24U]); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( + Eurydice_slice a); + +size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, + Eurydice_slice result); + +size_t +libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( + Eurydice_slice a, Eurydice_slice out); + +libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector +libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self); + +typedef struct + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { + libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem_neon_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index f138d7a8c..8c8485739 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 2478907d2..c6b0120ec 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* + version: 0e2a116d KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H diff --git a/libcrux-ml-kem/c/tests/mlkem768.cc b/libcrux-ml-kem/c/tests/mlkem768.cc index 3ccc1bad9..ced40395b 100644 --- a/libcrux-ml-kem/c/tests/mlkem768.cc +++ b/libcrux-ml-kem/c/tests/mlkem768.cc @@ -187,9 +187,13 @@ TEST(MlKem768TestPortable, ConsistencyTest) randomness[i] = 13; } auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + // cout << "key pair.pk: " << bytes_to_hex(bytes(key_pair.pk.value, key_pair.pk.value + 16U)) << endl; + // cout << "key pair.sk: " << bytes_to_hex(bytes(key_pair.sk.value, key_pair.sk.value + 16U)) << endl; auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + // cout << "ctxt: " << bytes_to_hex(bytes(ctxt.fst.value, ctxt.fst.value + 16U)) << endl; + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); @@ -456,8 +460,6 @@ TEST(MlKem768TestNeon, ConsistencyTest) for (int i = 0; i < 64; i++) randomness[i] = 13; auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); - cout << "key pair: " << bytes_to_hex(bytes(key_pair.pk.value, key_pair.pk.value + 1184U)) << endl; - auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; @@ -512,5 +514,4 @@ TEST(MlKem768TestNeon, NISTKnownAnswerTest) LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); } } - #endif // LIBCRUX_AARCH64 From 56765bb400cbc350740a7445ab8f2eaee83dd1b7 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Fri, 7 Jun 2024 14:46:25 -0700 Subject: [PATCH 32/84] Regenerate code on NEON, remove unused functions --- libcrux-ml-kem/c/CMakeLists.txt | 1 + libcrux-ml-kem/c/eurydice_glue.h | 2 + libcrux-ml-kem/c/internal/libcrux_core.h | 6 +- .../c/internal/libcrux_mlkem_avx2.h | 75 - .../c/internal/libcrux_mlkem_neon.h | 6 +- .../c/internal/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 38 - .../c/internal/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_core.c | 20 +- libcrux-ml-kem/c/libcrux_core.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 55 - libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 40 - libcrux-ml-kem/c/libcrux_mlkem1024_neon.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_neon.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 163 - libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 89 - libcrux-ml-kem/c/libcrux_mlkem512_neon.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_neon.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 54 - libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 40 - libcrux-ml-kem/c/libcrux_mlkem768_neon.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_neon.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 7622 ----------------- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 294 - libcrux-ml-kem/c/libcrux_mlkem_neon.c | 251 +- libcrux-ml-kem/c/libcrux_mlkem_neon.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 242 +- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/libcrux_platform.h | 6 +- libcrux-ml-kem/c/libcrux_sha3.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 2111 +---- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 38 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_neon.c | 9 +- libcrux-ml-kem/c/libcrux_sha3_neon.h | 6 +- 44 files changed, 231 insertions(+), 11069 deletions(-) delete mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h delete mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.h diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 91e64d534..b8f4f983f 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -11,6 +11,7 @@ project(libcrux-ml-kem ) set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 11) # FIXME: Windows? add_compile_options( diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index 76e9907ca..e00c11543 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -111,9 +111,11 @@ static inline void Eurydice_slice_to_array3(result_tryfromslice_flexible *dst, // CORE STUFF (conversions, endianness, ...) static inline void core_num__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4]) { + // TODO: why not store32_be? uint32_t x = htobe32(src); memcpy(dst, &x, 4); } + static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { return load32_le(buf); } diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index bf7077b43..f03cb2277 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_core_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h deleted file mode 100644 index 10a2cb5a5..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_mlkem_avx2_H -#define __internal_libcrux_mlkem_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_mlkem_avx2.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_portable.h" -#include "internal/libcrux_sha3_avx2.h" - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_mlkem_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h index ae166d10e..ab47ba59d 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_neon_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 21c931d0e..0f14466d1 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h deleted file mode 100644 index 11ada5b26..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __internal_libcrux_sha3_avx2_H -#define __internal_libcrux_sha3_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_sha3_avx2.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "intrinsics/libcrux_intrinsics_avx2.h" - -typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - libcrux_sha3_avx2_x4_incremental_KeccakState4; - -void libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]); - -void libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_sha3_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 063929aab..46e81d5c3 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index d9b04551d..a3accd24c 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,26 +1,12 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_core.h" -typedef size_t RangeTo__size_t; - -typedef size_t RangeFrom__size_t; - -typedef struct Option__int32_t_s { - core_option_Option__size_t_tags tag; - int32_t f0; -} Option__int32_t; - -typedef struct Option__uint32_t_s { - core_option_Option__size_t_tags tag; - uint32_t f0; -} Option__uint32_t; - static uint8_t is_non_zero(uint8_t value) { uint16_t value0 = (uint16_t)value; uint16_t uu____0 = value0; diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index bc228c092..d9a0b80fa 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 85dd66606..9fef0fd8b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c deleted file mode 100644 index 9dbf4e203..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem1024_avx2.h" - -void libcrux_ml_kem_mlkem1024_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h deleted file mode 100644 index d3da0c00c..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem1024_avx2_H -#define __libcrux_mlkem1024_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" - -void libcrux_ml_kem_mlkem1024_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem1024_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c index 8233b1102..84791f55e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h index f95883a91..e68f4c51b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_neon_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index 4884311cd..f292fbfbd 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 0b75d194b..321bfbf6e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 3f77765f7..5d00daade 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c deleted file mode 100644 index 14cd4287a..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem512_avx2.h" - -#include "internal/libcrux_mlkem_avx2.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem512_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - public_key); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None}); - } - return uu____0; -} - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - public_key); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - public_key); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h deleted file mode 100644 index 34801018a..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem512_avx2_H -#define __libcrux_mlkem512_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem512_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem512_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c index 12687fb50..2c021222d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h index 817d7efee..0074c9469 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_neon_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 74e84b66d..126402c11 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index f4ff7b78e..607fa0ae7 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 9b31997bd..59e587f22 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c deleted file mode 100644 index 4497d2302..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "libcrux_mlkem768_avx2.h" - -void libcrux_ml_kem_mlkem768_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h deleted file mode 100644 index 373792504..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_avx2_H -#define __libcrux_mlkem768_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem512_avx2.h" - -void libcrux_ml_kem_mlkem768_avx2_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_avx2_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_avx2_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c index ebf906e3a..c2d9494e3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h index 69680d2ce..175e2827b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_neon_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 1849e09a4..6b485ab48 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index abf96805f..03b200b57 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c deleted file mode 100644 index 23df04b2d..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ /dev/null @@ -1,7622 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#include "internal/libcrux_mlkem_avx2.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_portable.h" -#include "internal/libcrux_sha3_avx2.h" - -typedef core_core_arch_x86___m256i SIMD256Vector; - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void) { - return libcrux_intrinsics_avx2_mm256_setzero_si256(); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( - void) { - return libcrux_ml_kem_vector_avx2_zero(); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_slice array) { - return libcrux_intrinsics_avx2_mm256_loadu_si256_i16(array); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice array) { - return libcrux_ml_kem_vector_avx2_from_i16_array(array); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { - return libcrux_ml_kem_vector_avx2_arithmetic_add(lhs, rhs[0U]); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - return libcrux_intrinsics_avx2_mm256_sub_epi16(lhs, rhs); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { - return libcrux_ml_kem_vector_avx2_arithmetic_sub(lhs, rhs[0U]); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i uu____0 = vector; - return libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - core_core_arch_x86___m256i v, int16_t c) { - return libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant(v, c); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i uu____0 = vector; - return libcrux_intrinsics_avx2_mm256_and_si256( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - return libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - vector, constant); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i v_minus_field_modulus = - libcrux_intrinsics_avx2_mm256_sub_epi16(vector, field_modulus); - core_core_arch_x86___m256i sign_mask = - libcrux_intrinsics_avx2_mm256_srai_epi16( - (int32_t)15, v_minus_field_modulus, core_core_arch_x86___m256i); - core_core_arch_x86___m256i conditional_add_field_modulus = - libcrux_intrinsics_avx2_mm256_and_si256(sign_mask, field_modulus); - return libcrux_intrinsics_avx2_mm256_add_epi16(v_minus_field_modulus, - conditional_add_field_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329(vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i t = libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER)); - core_core_arch_x86___m256i uu____1 = t; - core_core_arch_x86___m256i t0 = libcrux_intrinsics_avx2_mm256_add_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16((int16_t)512)); - core_core_arch_x86___m256i quotient = - libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)10, t0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = quotient; - core_core_arch_x86___m256i quotient_times_field_modulus = - libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - return libcrux_intrinsics_avx2_mm256_sub_epi16(vector, - quotient_times_field_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - core_core_arch_x86___m256i constant0 = - libcrux_intrinsics_avx2_mm256_set1_epi16(constant); - core_core_arch_x86___m256i value_low = - libcrux_intrinsics_avx2_mm256_mullo_epi16(vector, constant0); - core_core_arch_x86___m256i uu____0 = value_low; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_mulhi_epi16(vector, constant0); - return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant) { - return libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - vector, constant); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi16( - (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / - (int16_t)2); - core_core_arch_x86___m256i field_modulus_quartered = - libcrux_intrinsics_avx2_mm256_set1_epi16( - (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / - (int16_t)4); - core_core_arch_x86___m256i shifted = - libcrux_intrinsics_avx2_mm256_sub_epi16(field_modulus_halved, vector); - core_core_arch_x86___m256i mask = libcrux_intrinsics_avx2_mm256_srai_epi16( - (int32_t)15, shifted, core_core_arch_x86___m256i); - core_core_arch_x86___m256i shifted_to_positive = - libcrux_intrinsics_avx2_mm256_xor_si256(mask, shifted); - core_core_arch_x86___m256i shifted_to_positive_in_range = - libcrux_intrinsics_avx2_mm256_sub_epi16(shifted_to_positive, - field_modulus_quartered); - return libcrux_intrinsics_avx2_mm256_srli_epi16( - (int32_t)15, shifted_to_positive_in_range, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - core_core_arch_x86___m256i vector) { - return libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - vector); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { - core_core_arch_x86___m256i prod02 = - libcrux_intrinsics_avx2_mm256_mul_epu32(lhs, rhs); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_shuffle_epi32((int32_t)245, lhs, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i prod13 = libcrux_intrinsics_avx2_mm256_mul_epu32( - uu____0, libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, rhs, core_core_arch_x86___m256i)); - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi32(prod02, prod13); - return libcrux_intrinsics_avx2_mm256_unpackhi_epi64( - uu____1, libcrux_intrinsics_avx2_mm256_unpackhi_epi32(prod02, prod13)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - core_core_arch_x86___m256i v, core_core_arch_x86___m256i c) { - core_core_arch_x86___m256i value_low = - libcrux_intrinsics_avx2_mm256_mullo_epi16(v, c); - core_core_arch_x86___m256i uu____0 = value_low; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_mulhi_epi16(v, c); - return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( - -zeta3, -zeta3, zeta3, zeta3, -zeta2, -zeta2, zeta2, zeta2, -zeta1, - -zeta1, zeta1, zeta1, -zeta0, -zeta0, zeta0, zeta0); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - rhs, zetas); - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)160, vector, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step(vector, zeta0, zeta1, - zeta2, zeta3); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( - -zeta1, -zeta1, -zeta1, -zeta1, zeta1, zeta1, zeta1, zeta1, -zeta0, - -zeta0, -zeta0, -zeta0, zeta0, zeta0, zeta0, zeta0); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)238, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - rhs, zetas); - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)68, vector, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step(vector, zeta0, zeta1); -} - -inline core_core_arch_x86___m128i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - core_core_arch_x86___m128i v, core_core_arch_x86___m128i c) { - core_core_arch_x86___m128i value_low = - libcrux_intrinsics_avx2_mm_mullo_epi16(v, c); - core_core_arch_x86___m128i uu____0 = value_low; - core_core_arch_x86___m128i k = libcrux_intrinsics_avx2_mm_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm_set1_epi16( - (int16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m128i uu____1 = k; - core_core_arch_x86___m128i k_times_modulus = - libcrux_intrinsics_avx2_mm_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m128i value_high = - libcrux_intrinsics_avx2_mm_mulhi_epi16(v, c); - return libcrux_intrinsics_avx2_mm_sub_epi16(value_high, k_times_modulus); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - core_core_arch_x86___m128i rhs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m128i uu____0 = rhs; - core_core_arch_x86___m128i rhs0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); - core_core_arch_x86___m128i lhs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs0); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs0); - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); - core_core_arch_x86___m256i combined0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, combined, upper_coefficients, core_core_arch_x86___m256i); - return combined0; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step(vector, zeta); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)160, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = rhs; - core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, - (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1)); - core_core_arch_x86___m256i sum0 = - libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); - core_core_arch_x86___m256i uu____1 = sum0; - core_core_arch_x86___m256i sum_times_zetas = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( - zeta3, zeta3, (int16_t)0, (int16_t)0, zeta2, zeta2, - (int16_t)0, (int16_t)0, zeta1, zeta1, (int16_t)0, - (int16_t)0, zeta0, zeta0, (int16_t)0, (int16_t)0)); - core_core_arch_x86___m256i sum = - libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(sum0); - return libcrux_intrinsics_avx2_mm256_blend_epi16( - (int32_t)204, sum, sum_times_zetas, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - vector, zeta0, zeta1, zeta2, zeta3); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - core_core_arch_x86___m256i lhs = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)245, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i rhs = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)160, vector, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = rhs; - core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)-1, - (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)-1, - (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)1, - (int16_t)1, (int16_t)1, (int16_t)1)); - core_core_arch_x86___m256i sum = - libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); - core_core_arch_x86___m256i uu____1 = sum; - core_core_arch_x86___m256i sum_times_zetas = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( - zeta1, zeta1, zeta1, zeta1, (int16_t)0, (int16_t)0, - (int16_t)0, (int16_t)0, zeta0, zeta0, zeta0, zeta0, - (int16_t)0, (int16_t)0, (int16_t)0, (int16_t)0)); - return libcrux_intrinsics_avx2_mm256_blend_epi16( - (int32_t)240, sum, sum_times_zetas, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step(vector, zeta0, - zeta1); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - core_core_arch_x86___m128i lhs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m128i rhs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs); - core_core_arch_x86___m128i uu____0 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); - core_core_arch_x86___m256i combined0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, combined, upper_coefficients0, - core_core_arch_x86___m256i); - return combined0; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta) { - return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step(vector, zeta); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - core_core_arch_x86___m256i v) { - core_core_arch_x86___m256i uu____0 = v; - core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_x86___m256i uu____1 = k; - core_core_arch_x86___m256i k_times_modulus = - libcrux_intrinsics_avx2_mm256_mulhi_epi16( - uu____1, libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); - core_core_arch_x86___m256i value_high = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)16, v, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i result = - libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); - core_core_arch_x86___m256i result0 = libcrux_intrinsics_avx2_mm256_slli_epi32( - (int32_t)16, result, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_srai_epi32((int32_t)16, result0, - core_core_arch_x86___m256i); -} - -inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { - core_core_arch_x86___m256i shuffle_with = - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)15, (int8_t)14, (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, - (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, - (int8_t)5, (int8_t)4, (int8_t)1, (int8_t)0, (int8_t)15, (int8_t)14, - (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, (int8_t)3, (int8_t)2, - (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, - (int8_t)1, (int8_t)0); - core_core_arch_x86___m256i lhs_shuffled = - libcrux_intrinsics_avx2_mm256_shuffle_epi8(lhs, shuffle_with); - core_core_arch_x86___m256i lhs_shuffled0 = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, lhs_shuffled, core_core_arch_x86___m256i); - core_core_arch_x86___m128i lhs_evens = - libcrux_intrinsics_avx2_mm256_castsi256_si128(lhs_shuffled0); - core_core_arch_x86___m256i lhs_evens0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_evens); - core_core_arch_x86___m128i lhs_odds = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, lhs_shuffled0, core_core_arch_x86___m128i); - core_core_arch_x86___m256i lhs_odds0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_odds); - core_core_arch_x86___m256i rhs_shuffled = - libcrux_intrinsics_avx2_mm256_shuffle_epi8(rhs, shuffle_with); - core_core_arch_x86___m256i rhs_shuffled0 = - libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, rhs_shuffled, core_core_arch_x86___m256i); - core_core_arch_x86___m128i rhs_evens = - libcrux_intrinsics_avx2_mm256_castsi256_si128(rhs_shuffled0); - core_core_arch_x86___m256i rhs_evens0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_evens); - core_core_arch_x86___m128i rhs_odds = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, rhs_shuffled0, core_core_arch_x86___m128i); - core_core_arch_x86___m256i rhs_odds0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_odds); - core_core_arch_x86___m256i left = - libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_evens0, rhs_evens0); - core_core_arch_x86___m256i right = - libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_odds0, rhs_odds0); - core_core_arch_x86___m256i right0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s(right); - core_core_arch_x86___m256i uu____0 = right0; - core_core_arch_x86___m256i right1 = libcrux_intrinsics_avx2_mm256_mullo_epi32( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi32( - -(int32_t)zeta3, (int32_t)zeta3, -(int32_t)zeta2, (int32_t)zeta2, - -(int32_t)zeta1, (int32_t)zeta1, -(int32_t)zeta0, (int32_t)zeta0)); - core_core_arch_x86___m256i products_left = - libcrux_intrinsics_avx2_mm256_add_epi32(left, right1); - core_core_arch_x86___m256i products_left0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - products_left); - core_core_arch_x86___m256i uu____1 = rhs; - core_core_arch_x86___m256i rhs_adjacent_swapped = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)13, (int8_t)12, (int8_t)15, (int8_t)14, - (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, (int8_t)5, - (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, (int8_t)0, - (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)15, - (int8_t)14, (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, - (int8_t)5, (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, - (int8_t)0, (int8_t)3, (int8_t)2)); - core_core_arch_x86___m256i products_right = - libcrux_intrinsics_avx2_mm256_madd_epi16(lhs, rhs_adjacent_swapped); - core_core_arch_x86___m256i products_right0 = - libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - products_right); - core_core_arch_x86___m256i products_right1 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)16, products_right0, - core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_blend_epi16((int32_t)170, products_left0, - products_right1, - core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { - return libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(lhs[0U], rhs[0U], zeta0, - zeta1, zeta2, zeta3); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]) { - core_core_arch_x86___m256i lsb_to_msb = - libcrux_intrinsics_avx2_mm256_slli_epi16((int32_t)15, vector, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i low_msbs = - libcrux_intrinsics_avx2_mm256_castsi256_si128(lsb_to_msb); - core_core_arch_x86___m128i high_msbs = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, lsb_to_msb, core_core_arch_x86___m128i); - core_core_arch_x86___m128i msbs = - libcrux_intrinsics_avx2_mm_packs_epi16(low_msbs, high_msbs); - int32_t bits_packed = libcrux_intrinsics_avx2_mm_movemask_epi8(msbs); - uint8_t serialized[2U] = {0U}; - serialized[0U] = (uint8_t)bits_packed; - serialized[1U] = (uint8_t)(bits_packed >> 8U); - memcpy(ret, serialized, (size_t)2U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]) { - uint8_t ret0[2U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_1(vector, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_1(Eurydice_slice bytes) { - int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_set_epi16( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, - uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, - uu____14, - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, - uint8_t)); - core_core_arch_x86___m256i shift_lsb_to_msb = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 8U, (int16_t)1 << 9U, (int16_t)1 << 10U, - (int16_t)1 << 11U, (int16_t)1 << 12U, (int16_t)1 << 13U, - (int16_t)1 << 14U, (int16_t)1 << 15U, (int16_t)1 << 8U, - (int16_t)1 << 9U, (int16_t)1 << 10U, (int16_t)1 << 11U, - (int16_t)1 << 12U, (int16_t)1 << 13U, (int16_t)1 << 14U, - (int16_t)1 << 15U); - core_core_arch_x86___m256i coefficients_in_msb = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsb_to_msb); - return libcrux_intrinsics_avx2_mm256_srli_epi16( - (int32_t)15, coefficients_in_msb, core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_1(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]) { - uint8_t serialized[16U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, - (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____1, - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, (int8_t)4, - (int8_t)0, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, - (int8_t)4, (int8_t)0)); - core_core_arch_x86___m256i uu____2 = adjacent_8_combined; - core_core_arch_x86___m256i combined = - libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0, - (int32_t)0, (int32_t)0, (int32_t)4, (int32_t)0)); - core_core_arch_x86___m128i combined0 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(combined); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_slice((size_t)16U, serialized, uint8_t, Eurydice_slice), - combined0); - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)16U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]) { - uint8_t ret0[8U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_4(vector, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U); - int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_set_epi16( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, - uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, - uu____14, - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, - uint8_t)); - core_core_arch_x86___m256i coefficients_in_msb = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients_in_lsb = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients_in_msb, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____15 = coefficients_in_lsb; - return libcrux_intrinsics_avx2_mm256_and_si256( - uu____15, libcrux_intrinsics_avx2_mm256_set1_epi16(((int16_t)1 << 4U) - - (int16_t)1)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_4(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, - (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22, - (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)22, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi32( - (int32_t)8, adjacent_4_combined0, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_8_combined; - core_core_arch_x86___m256i adjacent_8_combined0 = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); - core_core_arch_x86___m256i adjacent_8_combined1 = - libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)5U, .end = (size_t)21U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[10U]; - core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[10U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]) { - uint8_t ret0[10U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_5(vector, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_5(Eurydice_slice bytes) { - uint8_t uu____0 = - Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____1 = - Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____2 = - Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____3 = - Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____4 = - Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____5 = - Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____6 = - Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____7 = - Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____8 = - Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____9 = - Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____10 = - Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____11 = - Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____12 = - Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____13 = - Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - uint8_t uu____14 = - Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - core_core_arch_x86___m128i coefficients = libcrux_intrinsics_avx2_mm_set_epi8( - uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, uu____14, - Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); - core_core_arch_x86___m256i coefficients_loaded = - libcrux_intrinsics_avx2_mm256_castsi128_si256(coefficients); - core_core_arch_x86___m256i coefficients_loaded0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients_loaded, coefficients, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____15 = coefficients_loaded0; - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____15, - libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)15, (int8_t)14, (int8_t)15, (int8_t)14, (int8_t)13, - (int8_t)12, (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, - (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)9, - (int8_t)8, (int8_t)7, (int8_t)6, (int8_t)7, (int8_t)6, (int8_t)5, - (int8_t)4, (int8_t)5, (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m256i uu____16 = coefficients0; - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16( - uu____16, libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 5U, (int16_t)1 << 2U, - (int16_t)1 << 7U, (int16_t)1 << 4U, (int16_t)1 << 9U, - (int16_t)1 << 6U, (int16_t)1 << 11U, (int16_t)1 << 0U, - (int16_t)1 << 5U, (int16_t)1 << 2U, (int16_t)1 << 7U, - (int16_t)1 << 4U, (int16_t)1 << 9U, (int16_t)1 << 6U, - (int16_t)1 << 11U)); - return libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)11, coefficients1, - core_core_arch_x86___m256i); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_5(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, - (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)12, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)11, - (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)4, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)12, (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, - (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)10U, .end = (size_t)26U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[20U]; - core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[20U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]) { - uint8_t ret0[20U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_10(vector, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, - (int16_t)1 << 6U, (int16_t)1 << 0U, (int16_t)1 << 2U, - (int16_t)1 << 4U, (int16_t)1 << 6U, (int16_t)1 << 0U, - (int16_t)1 << 2U, (int16_t)1 << 4U, (int16_t)1 << 6U, - (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, - (int16_t)1 << 6U); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____0 = lower_coefficients; - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____0, - libcrux_intrinsics_avx2_mm_set_epi8(9U, 8U, 8U, 7U, 7U, 6U, 6U, 5U, - 4U, 3U, 3U, 2U, 2U, 1U, 1U, 0U)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)4U, - .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____1 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 13U, - 12U, 12U, 11U, 10U, 9U, - 9U, 8U, 8U, 7U, 7U, 6U)); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients, upper_coefficients0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients2 = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)6, coefficients1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = coefficients2; - core_core_arch_x86___m256i coefficients3 = - libcrux_intrinsics_avx2_mm256_and_si256( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - ((int16_t)1 << 10U) - (int16_t)1)); - return coefficients3; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_10(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_to_i16_array( - core_core_arch_x86___m256i v, int16_t ret[16U]) { - int16_t output[16U] = {0U}; - libcrux_intrinsics_avx2_mm256_storeu_si256_i16( - Eurydice_array_to_slice((size_t)16U, output, int16_t, Eurydice_slice), v); - memcpy(ret, output, (size_t)16U * sizeof(int16_t)); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]) { - int16_t uu____0[16U]; - memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); - libcrux_ml_kem_vector_avx2_portable_PortableVector lit; - memcpy(lit.elements, uu____0, (size_t)16U * sizeof(int16_t)); - return lit; -} - -inline void libcrux_ml_kem_vector_avx2_portable_serialize_11( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]) { - uint8_t result[22U] = {0U}; - result[0U] = (uint8_t)v.elements[0U]; - result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | - (uint32_t)(uint8_t)(v.elements[0U] >> 8U); - result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | - (uint32_t)(uint8_t)(v.elements[1U] >> 5U); - result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); - result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | - (uint32_t)(uint8_t)(v.elements[2U] >> 10U); - result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | - (uint32_t)(uint8_t)(v.elements[3U] >> 7U); - result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | - (uint32_t)(uint8_t)(v.elements[4U] >> 4U); - result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); - result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | - (uint32_t)(uint8_t)(v.elements[5U] >> 9U); - result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | - (uint32_t)(uint8_t)(v.elements[6U] >> 6U); - result[10U] = (uint8_t)(v.elements[7U] >> 3U); - result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; - result[12U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) - << 3U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); - result[13U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); - result[14U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); - result[15U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) - << 1U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); - result[16U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); - result[17U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) - << 7U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); - result[18U] = - (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); - result[19U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); - result[20U] = - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) - << 5U | - (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); - result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]) { - int16_t array[16U]; - libcrux_ml_kem_vector_avx2_to_i16_array(vector, array); - int16_t uu____0[16U]; - memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); - libcrux_ml_kem_vector_avx2_portable_PortableVector input = - libcrux_ml_kem_vector_avx2_portable_from_i16_array(uu____0); - uint8_t ret0[22U]; - libcrux_ml_kem_vector_avx2_portable_serialize_11(input, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]) { - uint8_t ret0[22U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_11(vector, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_zero(void) { - libcrux_ml_kem_vector_avx2_portable_PortableVector lit; - lit.elements[0U] = (int16_t)0; - lit.elements[1U] = (int16_t)0; - lit.elements[2U] = (int16_t)0; - lit.elements[3U] = (int16_t)0; - lit.elements[4U] = (int16_t)0; - lit.elements[5U] = (int16_t)0; - lit.elements[6U] = (int16_t)0; - lit.elements[7U] = (int16_t)0; - lit.elements[8U] = (int16_t)0; - lit.elements[9U] = (int16_t)0; - lit.elements[10U] = (int16_t)0; - lit.elements[11U] = (int16_t)0; - lit.elements[12U] = (int16_t)0; - lit.elements[13U] = (int16_t)0; - lit.elements[14U] = (int16_t)0; - lit.elements[15U] = (int16_t)0; - return lit; -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes) { - libcrux_ml_kem_vector_avx2_portable_PortableVector result = - libcrux_ml_kem_vector_avx2_portable_zero(); - int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____1 = - &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); - result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; - int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____3 = - &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); - result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; - int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____5 = - uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, - uint8_t *, uint8_t) - << 2U; - uint8_t *uu____6 = - &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); - result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; - int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____8 = - &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); - result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; - int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____10 = - &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); - result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; - int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____12 = - uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, - uint8_t *, uint8_t) - << 1U; - uint8_t *uu____13 = - &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); - result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; - int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____15 = - &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); - result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; - int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____17 = - &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); - result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; - int16_t uu____18 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)7) - << 8U; - uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, - uint8_t, uint8_t *, uint8_t); - result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; - int16_t uu____20 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)63) - << 5U; - uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, - uint8_t, uint8_t *, uint8_t); - result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; - int16_t uu____22 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)1) - << 10U; - int16_t uu____23 = - uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 2U; - uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, - uint8_t, uint8_t *, uint8_t); - result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; - int16_t uu____25 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)15) - << 7U; - uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, - uint8_t, uint8_t *, uint8_t); - result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; - int16_t uu____27 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)127) - << 4U; - uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, - uint8_t, uint8_t *, uint8_t); - result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; - int16_t uu____29 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)3) - << 9U; - int16_t uu____30 = - uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, - uint8_t, uint8_t *, uint8_t) - << 1U; - uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, - uint8_t, uint8_t *, uint8_t); - result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; - int16_t uu____32 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, - uint8_t *, uint8_t) & - (int16_t)31) - << 6U; - uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, - uint8_t, uint8_t *, uint8_t); - result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; - int16_t uu____34 = - (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, - uint8_t *, uint8_t) - << 3U; - uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, - uint8_t, uint8_t *, uint8_t); - result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; - return result; -} - -inline void libcrux_ml_kem_vector_avx2_portable_to_i16_array( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]) { - memcpy(ret, v.elements, (size_t)16U * sizeof(int16_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_11(Eurydice_slice bytes) { - libcrux_ml_kem_vector_avx2_portable_PortableVector output = - libcrux_ml_kem_vector_avx2_portable_deserialize_11(bytes); - int16_t ret[16U]; - libcrux_ml_kem_vector_avx2_portable_to_i16_array(output, ret); - return libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_array_to_slice((size_t)16U, ret, int16_t, Eurydice_slice)); -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_11(bytes); -} - -inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]) { - uint8_t serialized[32U] = {0U}; - core_core_arch_x86___m256i uu____0 = vector; - core_core_arch_x86___m256i adjacent_2_combined = - libcrux_intrinsics_avx2_mm256_madd_epi16( - uu____0, - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, - (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1)); - core_core_arch_x86___m256i uu____1 = adjacent_2_combined; - core_core_arch_x86___m256i adjacent_4_combined = - libcrux_intrinsics_avx2_mm256_sllv_epi32( - uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8, - (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8)); - core_core_arch_x86___m256i adjacent_4_combined0 = - libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, adjacent_4_combined, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; - core_core_arch_x86___m256i adjacent_8_combined = - libcrux_intrinsics_avx2_mm256_shuffle_epi8( - uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( - (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, - (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, - (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, (int8_t)3, - (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, - (int8_t)-1, (int8_t)-1, (int8_t)13, (int8_t)12, - (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)5, - (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); - core_core_arch_x86___m128i lower_8 = - libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - lower_8); - libcrux_intrinsics_avx2_mm_storeu_bytes_si128( - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)12U, .end = (size_t)28U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - upper_8); - uint8_t ret0[24U]; - core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - Eurydice_slice, uint8_t[24U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( - dst, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]) { - uint8_t ret0[24U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_12(vector, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____0 = lower_coefficients; - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____0, - libcrux_intrinsics_avx2_mm_set_epi8(11U, 10U, 10U, 9U, 8U, 7U, 7U, 6U, - 5U, 4U, 4U, 3U, 2U, 1U, 1U, 0U)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( - bytes, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m128i uu____1 = upper_coefficients; - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8( - uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 12U, - 11U, 11U, 10U, 9U, 8U, - 8U, 7U, 6U, 5U, 5U, 4U)); - core_core_arch_x86___m256i coefficients = - libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); - core_core_arch_x86___m256i coefficients0 = - libcrux_intrinsics_avx2_mm256_inserti128_si256( - (int32_t)1, coefficients, upper_coefficients0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i coefficients1 = - libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, - shift_lsbs_to_msbs); - core_core_arch_x86___m256i coefficients2 = - libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____2 = coefficients2; - core_core_arch_x86___m256i coefficients3 = - libcrux_intrinsics_avx2_mm256_and_si256( - uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( - ((int16_t)1 << 12U) - (int16_t)1)); - return coefficients3; -} - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - Eurydice_slice bytes) { - return libcrux_ml_kem_vector_avx2_serialize_deserialize_12(bytes); -} - -inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( - Eurydice_slice input, Eurydice_slice output) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi16( - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i potential_coefficients = - libcrux_ml_kem_vector_avx2_serialize_deserialize_12(input); - core_core_arch_x86___m256i compare_with_field_modulus = - libcrux_intrinsics_avx2_mm256_cmpgt_epi16(field_modulus, - potential_coefficients); - uint8_t good[2U]; - libcrux_ml_kem_vector_avx2_serialize_serialize_1(compare_with_field_modulus, - good); - uint8_t lower_shuffles[16U]; - memcpy(lower_shuffles, - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( - size_t)good[0U]], - (size_t)16U * sizeof(uint8_t)); - core_core_arch_x86___m128i lower_shuffles0 = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( - (size_t)16U, lower_shuffles, uint8_t, Eurydice_slice)); - core_core_arch_x86___m128i lower_coefficients = - libcrux_intrinsics_avx2_mm256_castsi256_si128(potential_coefficients); - core_core_arch_x86___m128i lower_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8(lower_coefficients, - lower_shuffles0); - libcrux_intrinsics_avx2_mm_storeu_si128(output, lower_coefficients0); - size_t sampled_count = (size_t)core_num__u8_6__count_ones(good[0U]); - uint8_t upper_shuffles[16U]; - memcpy(upper_shuffles, - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( - size_t)good[1U]], - (size_t)16U * sizeof(uint8_t)); - core_core_arch_x86___m128i upper_shuffles0 = - libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( - (size_t)16U, upper_shuffles, uint8_t, Eurydice_slice)); - core_core_arch_x86___m128i upper_coefficients = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, potential_coefficients, core_core_arch_x86___m128i); - core_core_arch_x86___m128i upper_coefficients0 = - libcrux_intrinsics_avx2_mm_shuffle_epi8(upper_coefficients, - upper_shuffles0); - libcrux_intrinsics_avx2_mm_storeu_si128( - Eurydice_slice_subslice( - output, - ((core_ops_range_Range__size_t){.start = sampled_count, - .end = sampled_count + (size_t)8U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice), - upper_coefficients0); - size_t uu____0 = sampled_count; - return uu____0 + (size_t)core_num__u8_6__count_ones(good[1U]); -} - -size_t -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - Eurydice_slice input, Eurydice_slice output) { - return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); -} - -inline libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( - libcrux_ml_kem_vector_avx2_portable_PortableVector *self) { - return self[0U]; -} - -inline core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( - core_core_arch_x86___m256i *self) { - return self[0U]; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - lit; - lit.coefficients[0U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[1U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[2U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[3U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[4U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[5U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[6U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[7U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[8U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[9U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[10U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[11U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[12U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[13U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[14U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - lit.coefficients[15U] = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - bytes); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline core_core_arch_x86___m256i shift_right___15int32_t( - core_core_arch_x86___m256i vector) { - return libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)15, vector, - core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i shift_right___15int32_t0( - core_core_arch_x86___m256i vector) { - return shift_right___15int32_t(vector); -} - -static core_core_arch_x86___m256i -to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a) { - core_core_arch_x86___m256i t = shift_right___15int32_t0(a); - core_core_arch_x86___m256i fm = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &fm); -} - -static inline void -serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 Simd256Hash; - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice_subslice( - a, - ((core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - result.coefficients[i0] = uu____0; - } - return result; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[3U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, - Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t uu____2 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t random_bits_as_u32 = - uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = - (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t random_bits_as_u24 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - randomness); - return uu____0; -} - -static inline void ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) { - size_t j = i; - core_core_arch_x86___m256i t = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - re->coefficients[j + step], (int16_t)-1600); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - re->coefficients[j], &t); - re->coefficients[j + step] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - re->coefficients[j], &t); - re->coefficients[j] = uu____1; - } -} - -typedef struct - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector_s { - core_core_arch_x86___m256i fst; - core_core_arch_x86___m256i snd; -} __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector; - -static core_core_arch_x86___m256i -montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v, int16_t fer) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - v, fer); -} - -static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - int16_t zeta_r) { - core_core_arch_x86___m256i t = - montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector(b, - zeta_r); - b = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - a, &t); - a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &t); - return (( - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ - .fst = a, .snd = b}); -} - -static inline void -ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - core_core_arch_x86___m256i x = uu____0.fst; - core_core_arch_x86___m256i y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline void ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -static inline void ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -static inline void -poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - self->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); - size_t zeta_i = (size_t)1U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - out = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - &self->coefficients[i0], &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)3U]); - out.coefficients[i0] = uu____0; - } - return out; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static core_core_arch_x86___m256i -to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); -} - -static inline void -add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - core_core_arch_x86___m256i coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( - self->coefficients[j]); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -static inline void -invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -static inline void -invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - int16_t zeta_r) { - core_core_arch_x86___m256i a_minus_b = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - b, &a); - a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - a, &b)); - b = montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_minus_b, zeta_r); - return (( - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ - .fst = a, .snd = b}); -} - -static inline void -invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = - offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = - step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - core_core_arch_x86___m256i x = uu____0.fst; - core_core_arch_x86___m256i y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - self->coefficients[j], (int16_t)1441); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static core_core_arch_x86___m256i -decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - core_core_arch_x86___m256i v) { - return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(), - &v), - (int16_t)1665); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - core_core_arch_x86___m256i coefficient_compressed = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i uu____0 = - decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( - coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - result.coefficients[i0], (int16_t)1441); - core_core_arch_x86___m256i tmp = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &message->coefficients[i0]); - core_core_arch_x86___m256i tmp0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - coefficient_normal_form, &tmp); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___10int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)10) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___10int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___10int32_t(vector); -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___10int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___11int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)11) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___11int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___11int32_t(vector); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___11int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___4int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)4) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___4int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___4int32_t(vector); -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___4int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_x86___m256i -compress_ciphertext_coefficient___5int32_t(core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus_halved = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / - (int32_t)2); - core_core_arch_x86___m256i compression_factor = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); - core_core_arch_x86___m256i coefficient_bits_mask = - libcrux_intrinsics_avx2_mm256_set1_epi32( - ((int32_t)1 << (uint32_t)(int32_t)5) - (int32_t)1); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i compressed_low = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_low0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, - field_modulus_halved); - core_core_arch_x86___m256i compressed_low1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, - compression_factor); - core_core_arch_x86___m256i compressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_low3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, - coefficient_bits_mask); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i compressed_high = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_high0, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high0 = - libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, - field_modulus_halved); - core_core_arch_x86___m256i compressed_high1 = - libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, - compression_factor); - core_core_arch_x86___m256i compressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed_high3 = - libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, - coefficient_bits_mask); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, - compressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i compress___5int32_t( - core_core_arch_x86___m256i vector) { - return compress_ciphertext_coefficient___5int32_t(vector); -} - -static inline void -compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficients = compress___5int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - coefficients, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___10int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)10); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i -decompress_ciphertext_coefficient___10int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___10int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___10int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___11int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)11); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i -decompress_ciphertext_coefficient___11int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___11int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___11int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___4int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)4); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i decompress_ciphertext_coefficient___4int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___4int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i coefficient = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - bytes); - core_core_arch_x86___m256i uu____0 = - decompress_ciphertext_coefficient___4int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_x86___m256i -decompress_ciphertext_coefficient___5int32_t( - core_core_arch_x86___m256i vector) { - core_core_arch_x86___m256i field_modulus = - libcrux_intrinsics_avx2_mm256_set1_epi32( - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_x86___m256i two_pow_coefficient_bits = - libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 - << (uint32_t)(int32_t)5); - core_core_arch_x86___m128i coefficients_low = - libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); - core_core_arch_x86___m256i coefficients_low0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); - core_core_arch_x86___m256i decompressed_low = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, - field_modulus); - core_core_arch_x86___m256i decompressed_low0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_low2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_low1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_low3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, - core_core_arch_x86___m256i); - core_core_arch_x86___m128i coefficients_high = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, vector, core_core_arch_x86___m128i); - core_core_arch_x86___m256i coefficients_high0 = - libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); - core_core_arch_x86___m256i decompressed_high = - libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, - field_modulus); - core_core_arch_x86___m256i decompressed_high0 = - libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high1 = - libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, - two_pow_coefficient_bits); - core_core_arch_x86___m256i decompressed_high2 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_high1, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i decompressed_high3 = - libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, - core_core_arch_x86___m256i); - core_core_arch_x86___m256i compressed = - libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, - decompressed_high3); - return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( - (int32_t)216, compressed, core_core_arch_x86___m256i); -} - -static core_core_arch_x86___m256i decompress_ciphertext_coefficient___5int32_t0( - core_core_arch_x86___m256i vector) { - return decompress_ciphertext_coefficient___5int32_t(vector); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - bytes); - re.coefficients[i0] = uu____0; - core_core_arch_x86___m256i uu____1 = - decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - b) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient_normal_form = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - b.coefficients[i0], (int16_t)1441); - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - self->coefficients[i0], &coefficient_normal_form)); - b.coefficients[i0] = uu____0; - } - return b; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static inline void -compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - uint8_t ret[32U]) { - uint8_t serialized[32U] = {0U}; - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - core_core_arch_x86___m256i coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re.coefficients[i0]); - core_core_arch_x86___m256i coefficient_compressed = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *);); - memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[4U]; - memcpy( - uu____1, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[4U]; - memcpy( - uu____0, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___4size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___4size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], - uint8_t(*)[168U], uint8_t[168U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U][4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[4U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____9 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; - memcpy( - uu____2, re_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[4U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[4U]; - memcpy( - uu____4, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( - uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[4U]; - memcpy( - uu____2, error_1, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___4size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___10int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - core_core_arch_x86___m256i coefficient = compress___11int32_t( - to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[4U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re, - Eurydice_slice out) { - compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[4U][4U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[4U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[4U]; - memcpy( - error_1, uu____3.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___4size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[4U]; - memcpy( - uu____5, u, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___4size_t( - Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, - (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( - serialized); - return uu____0; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1536U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - key[2U], - uint8_t ret[768U]) { - uint8_t out[768U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)768U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U], - Eurydice_slice seed_for_a, uint8_t ret[800U]) { - uint8_t public_key_serialized[800U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1[2U]; - memcpy( - uu____1, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, - (size_t)768U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( - Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0[2U]; - memcpy( - uu____0, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_portable_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static void -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 -shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - state = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - uu____0, uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); - return state; -} - -static inline void shake128_squeeze_three_blocks___2size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][504U]) { - uint8_t out[2U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - uint8_t dummy_out1[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( - uint8_t randomness[2U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___2size_t( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, - uint8_t ret[2U][168U]) { - uint8_t out[2U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - uint8_t dummy_out1[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uint8_t randomness[2U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - size_t sampled_coefficients[2U] = {0U}; - int16_t out[2U][272U] = {{0U}}; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = - shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t1( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U][2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( - A_transpose[i]);); - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - fst[2U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], - uint8_t ret[2U][192U]) { - uint8_t out[2U][192U] = {{0U}}; - uint8_t dummy_out0[192U] = {0U}; - uint8_t dummy_out1[192U] = {0U}; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], - Eurydice_slice), - (size_t)1U, uint8_t[192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( - randomness); - return uu____0; -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( - Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; - memcpy( - uu____2, re_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *rhs) { - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)16U, self->coefficients, - core_core_arch_x86___m256i, Eurydice_slice), - core_core_arch_x86___m256i, size_t); - i++) { - size_t i0 = i; - core_core_arch_x86___m256i uu____0 = - libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_as_ntt[2U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____3, domain_separator) - .fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____4[2U]; - memcpy( - uu____4, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)1632U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( - uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uu____4)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[2U][128U]) { - uint8_t out[2U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - uint8_t dummy_out1[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, - uint8_t, Eurydice_slice); - libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, - Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____2[2U]; - memcpy( - uu____2, error_1, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___2size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t0(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( - *a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], - &error_1[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result); - result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( - error_2, message, result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - input[2U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[768U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( - Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - A_transpose[2U][2U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - r_as_ntt[2U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_1[2U]; - memcpy( - error_1, uu____3.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___2size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[768U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____5[2U]; - memcpy( - uu____5, u, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___2size_t( - Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t1(void) { - return ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector -compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, - (size_t)640U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector - message = - compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_portable_shake256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)768U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)800U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t( - Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h deleted file mode 100644 index 5ae63072a..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_mlkem_avx2_H -#define __libcrux_mlkem_avx2_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem_portable.h" -#include "libcrux_sha3.h" -#include "libcrux_sha3_avx2.h" - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( - void); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( - Eurydice_slice array); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( - Eurydice_slice array); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( - core_core_arch_x86___m256i v, int16_t c); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( - core_core_arch_x86___m256i vector); - -#define LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER \ - ((int16_t)20159) - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( - core_core_arch_x86___m256i vector, int16_t constant); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( - core_core_arch_x86___m256i vector); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( - core_core_arch_x86___m256i v, core_core_arch_x86___m256i c); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m128i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( - core_core_arch_x86___m128i v, core_core_arch_x86___m128i c); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, - int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( - core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( - core_core_arch_x86___m256i vector, int16_t zeta); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( - core_core_arch_x86___m256i v); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( - core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( - core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, - int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( - core_core_arch_x86___m256i vector, uint8_t ret[2U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_1( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( - core_core_arch_x86___m256i vector, uint8_t ret[8U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_4( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( - core_core_arch_x86___m256i vector, uint8_t ret[10U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_5( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( - core_core_arch_x86___m256i vector, uint8_t ret[20U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_10( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_to_i16_array(core_core_arch_x86___m256i v, - int16_t ret[16U]); - -typedef struct libcrux_ml_kem_vector_avx2_portable_PortableVector_s { - int16_t elements[16U]; -} libcrux_ml_kem_vector_avx2_portable_PortableVector; - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]); - -void libcrux_ml_kem_vector_avx2_portable_serialize_11( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( - core_core_arch_x86___m256i vector, uint8_t ret[22U]); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_zero(void); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_portable_to_i16_array( - libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_11( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( - Eurydice_slice bytes); - -void libcrux_ml_kem_vector_avx2_serialize_serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]); - -void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( - core_core_arch_x86___m256i vector, uint8_t ret[24U]); - -core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_12( - Eurydice_slice bytes); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( - Eurydice_slice bytes); - -size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( - Eurydice_slice input, Eurydice_slice output); - -size_t -libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( - Eurydice_slice input, Eurydice_slice output); - -libcrux_ml_kem_vector_avx2_portable_PortableVector -libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( - libcrux_ml_kem_vector_avx2_portable_PortableVector *self); - -core_core_arch_x86___m256i -libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( - core_core_arch_x86___m256i *self); - -typedef struct - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_s { - core_core_arch_x86___m256i coefficients[16U]; -} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem_avx2_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.c b/libcrux-ml-kem/c/libcrux_mlkem_neon.c index 06a1b3d76..09fd7ca96 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_mlkem_neon.h" @@ -1540,12 +1540,6 @@ ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(void) { return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( Eurydice_slice serialized) { @@ -1767,14 +1761,8 @@ static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -2005,7 +1993,7 @@ from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -2052,7 +2040,7 @@ sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t1( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -2070,7 +2058,7 @@ sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ A_transpose[3U][3U]; KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( A_transpose[i]);); KRML_MAYBE_FOR3( i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; @@ -2122,12 +2110,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) { uint8_t out[3U][128U] = {{0U}}; @@ -2497,11 +2479,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_ return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -2834,12 +2811,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_S uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( Eurydice_slice public_key, @@ -2876,12 +2847,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128 libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { @@ -2942,11 +2907,6 @@ static inline void PRF___3size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t0(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( size_t *zeta_i, @@ -3412,35 +3372,6 @@ compress___11int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { return compress___11int32_t(v); } -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - compress___11int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - static inline void compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -3803,16 +3734,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD12 public_key), uint8_t, Eurydice_slice), ret); - /* - printf("pk:"); - for (int i = 0; i < 16; i++) - printf("%02x, ",public_key->value[i]); - printf("\n"); - printf("hashed:"); - for (int i = 0; i < 32; i++) - printf("%02x, ",ret[i]); - printf("\n"); - */ core_slice___Slice_T___copy_from_slice( uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), @@ -3856,12 +3777,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD12 return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline core_core_arch_arm_shared_neon_uint32x4_t decompress_uint32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { core_core_arch_arm_shared_neon_uint32x4_t coeff = @@ -4294,11 +4209,6 @@ deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128op return uu____0; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t1(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( Eurydice_slice serialized) { @@ -4557,12 +4467,6 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_S memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( Eurydice_slice public_key, @@ -4703,14 +4607,8 @@ static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -4927,7 +4825,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIM } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -4974,7 +4872,7 @@ sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t1( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -4992,7 +4890,7 @@ sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ A_transpose[4U][4U]; KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( A_transpose[i]);); KRML_MAYBE_FOR4( i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; @@ -5044,12 +4942,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) { uint8_t out[4U][128U] = {{0U}}; @@ -5156,11 +5048,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_ return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -5436,12 +5323,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_S uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( Eurydice_slice public_key, @@ -5478,12 +5359,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128 libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { @@ -5544,11 +5419,6 @@ static inline void PRF___4size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t0(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -5664,35 +5534,6 @@ compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4siz return result; } -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - compress___10int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - static inline void compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -5933,12 +5774,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD12 return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( Eurydice_slice serialized) { @@ -6029,11 +5864,6 @@ deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128op return uu____0; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t1(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( Eurydice_slice secret_key, @@ -6220,12 +6050,6 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_S memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( Eurydice_slice public_key, @@ -6366,14 +6190,8 @@ static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -6542,7 +6360,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIM } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( +closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( Eurydice_array_to_subslice((size_t)272U, s, @@ -6589,7 +6407,7 @@ sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t1( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -6607,7 +6425,7 @@ sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_ A_transpose[2U][2U]; KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( + closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( A_transpose[i]);); KRML_MAYBE_FOR2( i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; @@ -6659,12 +6477,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) { uint8_t out[2U][192U] = {{0U}}; @@ -6754,11 +6566,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_ return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -7034,12 +6841,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_S uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( Eurydice_slice public_key, @@ -7076,12 +6877,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128 libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) { uint8_t out[2U][128U] = {{0U}}; @@ -7172,11 +6967,6 @@ static inline void PRF___2size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t0(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector @@ -7483,12 +7273,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD12 return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( uint8_t *ciphertext, @@ -7535,11 +7319,6 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vect libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t1(void) { - return ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); -} - static inline void deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( Eurydice_slice secret_key, diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/libcrux_mlkem_neon.h index 426ef9f47..172520803 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem_neon_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 6567e2b46..876d3b5bb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" @@ -87,8 +87,7 @@ libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) { Eurydice_slice, int16_t[16U], void *); core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( dst, ret); - // XXX KB modified this line - memcpy(lit.elements, array.ptr, (size_t)16U * sizeof(int16_t)); + memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); return lit; } @@ -1711,12 +1710,6 @@ ZERO__libcrux_ml_kem_vector_portable_PortableVector(void) { return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1568size_t_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_slice serialized) { @@ -1936,14 +1929,8 @@ static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static void -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ret[4U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -2118,7 +2105,7 @@ from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, @@ -2165,7 +2152,7 @@ sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t1( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -2183,7 +2170,7 @@ sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha A_transpose[4U][4U]; KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t0( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( A_transpose[i]);); KRML_MAYBE_FOR4( i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; @@ -2235,12 +2222,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) { uint8_t out[4U][128U] = {{0U}}; @@ -2570,11 +2551,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcru return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -2906,12 +2882,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1536size_t_4size_t( Eurydice_slice public_key, @@ -2947,12 +2917,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { @@ -3007,11 +2971,6 @@ static inline void PRF___4size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t0(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( size_t *zeta_i, @@ -3323,35 +3282,6 @@ static libcrux_ml_kem_vector_portable_PortableVector compress___10int32_t0( return compress___10int32_t(v); } -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector coefficient = - compress___10int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - static inline libcrux_ml_kem_vector_portable_PortableVector compress___11int32_t(libcrux_ml_kem_vector_portable_PortableVector v) { for (size_t i = (size_t)0U; @@ -3697,12 +3627,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_11size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline libcrux_ml_kem_vector_portable_PortableVector decompress_ciphertext_coefficient___10int32_t( libcrux_ml_kem_vector_portable_PortableVector v) { @@ -3973,11 +3897,6 @@ deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_Porta return uu____0; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_4size_t1(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_slice serialized) { @@ -4230,12 +4149,6 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( Eurydice_slice public_key, @@ -4375,14 +4288,8 @@ static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static void -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ret[3U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -4536,7 +4443,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, @@ -4583,7 +4490,7 @@ sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t1( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -4601,7 +4508,7 @@ sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha A_transpose[3U][3U]; KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t0( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( A_transpose[i]);); KRML_MAYBE_FOR3( i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; @@ -4653,12 +4560,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) { uint8_t out[3U][128U] = {{0U}}; @@ -4719,11 +4620,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcru return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -4998,12 +4894,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( Eurydice_slice public_key, @@ -5039,12 +4929,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( uint8_t prf_input[33U], uint8_t domain_separator) { @@ -5099,11 +4983,6 @@ static inline void PRF___3size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t0(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -5246,35 +5125,6 @@ compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320siz memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_PortableVector coefficient = - compress___11int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - static inline void compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -5486,12 +5336,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( Eurydice_slice serialized) { @@ -5578,11 +5422,6 @@ deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_Porta return uu____0; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t1(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( Eurydice_slice secret_key, @@ -5761,11 +5600,6 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_800size_t_2size_t( Eurydice_slice public_key, @@ -5905,14 +5739,8 @@ static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static void -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ret[2U]) { libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -6066,7 +5894,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe } static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( +closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, @@ -6113,7 +5941,7 @@ sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, ret0[i] = - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t1( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( uu____3[i]);); memcpy( ret, ret0, @@ -6131,7 +5959,7 @@ sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_ha A_transpose[2U][2U]; KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t0( + closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( A_transpose[i]);); KRML_MAYBE_FOR2( i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; @@ -6183,12 +6011,6 @@ typedef struct uint8_t snd; } __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t; -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_3size_t_192size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) { uint8_t out[2U][192U] = {{0U}}; @@ -6260,11 +6082,6 @@ sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcru return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -6539,11 +6356,6 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uu____4)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_768size_t_2size_t( Eurydice_slice public_key, @@ -6579,12 +6391,6 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_128size_t_2size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) { uint8_t out[2U][128U] = {{0U}}; @@ -6652,11 +6458,6 @@ static inline void PRF___2size_t_128size_t(Eurydice_slice input, memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t0(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector @@ -6961,12 +6762,6 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto return lit; } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( - void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_10size_t( uint8_t *ciphertext, @@ -7012,11 +6807,6 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2si libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector -closure__libcrux_ml_kem_vector_portable_PortableVector_2size_t1(void) { - return ZERO__libcrux_ml_kem_vector_portable_PortableVector(); -} - static inline void deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t( Eurydice_slice secret_key, diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index a9def0a13..c2a28afa5 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index 9ae0f07cd..13d7131d4 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 0543a8e19..f143434fa 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 49e0302b8..08549e08a 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,2028 +1,111 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ -#include "internal/libcrux_sha3_avx2.h" +#include "libcrux_sha3_avx2.h" #include "internal/libcrux_core.h" -static inline core_core_arch_x86___m256i zero(void) { - return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); -} - -static inline core_core_arch_x86___m256i _veor5q_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); - core_core_arch_x86___m256i abcd = - libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); - return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); -} - -static inline core_core_arch_x86___m256i xor5(core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c, - core_core_arch_x86___m256i d, - core_core_arch_x86___m256i e) { - return _veor5q_u64(a, b, c, d, e); -} - -static inline core_core_arch_x86___m256i rotate_left___1int32_t_63int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)1, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)63, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vrax1q_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i uu____0 = a; - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, rotate_left___1int32_t_63int32_t(b)); -} - -static inline core_core_arch_x86___m256i rotate_left1_and_xor( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vrax1q_u64(a, b); -} - -static inline core_core_arch_x86___m256i _vbcaxq_u64( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c) { - core_core_arch_x86___m256i uu____0 = a; - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); -} - -static inline core_core_arch_x86___m256i and_not_xor( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, - core_core_arch_x86___m256i c) { - return _vbcaxq_u64(a, b, c); -} - -static inline core_core_arch_x86___m256i _veorq_n_u64( - core_core_arch_x86___m256i a, uint64_t c) { - core_core_arch_x86___m256i c0 = - libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); - return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); -} - -static inline core_core_arch_x86___m256i xor_constant( - core_core_arch_x86___m256i a, uint64_t c) { - return _veorq_n_u64(a, c); -} - -static inline core_core_arch_x86___m256i xor0(core_core_arch_x86___m256i a, - core_core_arch_x86___m256i b) { - return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); -} - -static inline void slice_4(Eurydice_slice a[4U], size_t start, size_t len, - Eurydice_slice ret[4U]) { - Eurydice_slice uu____0 = Eurydice_slice_subslice( - a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - a[1U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - a[2U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - ret[0U] = uu____0; - ret[1U] = uu____1; - ret[2U] = uu____2; - ret[3U] = Eurydice_slice_subslice( - a[3U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); -} - -static inline void slice_n(Eurydice_slice a[4U], size_t start, size_t len, - Eurydice_slice ret[4U]) { - Eurydice_slice uu____0[4U]; - memcpy(uu____0, a, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret0[4U]; - slice_4(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof(Eurydice_slice)); -} - -static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_4(Eurydice_slice out[4U], size_t mid) { - Eurydice_slice out0 = out[0U]; - Eurydice_slice out1 = out[1U]; - Eurydice_slice out2 = out[2U]; - Eurydice_slice out3 = out[3U]; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at_mut( - out0, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at_mut( - out1, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out10 = uu____1.fst; - Eurydice_slice out11 = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at_mut( - out2, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out20 = uu____2.fst; - Eurydice_slice out21 = uu____2.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at_mut( - out3, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out30 = uu____3.fst; - Eurydice_slice out31 = uu____3.snd; - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; - lit.fst[0U] = out00; - lit.fst[1U] = out10; - lit.fst[2U] = out20; - lit.fst[3U] = out30; - lit.snd[0U] = out01; - lit.snd[1U] = out11; - lit.snd[2U] = out21; - lit.snd[3U] = out31; - return lit; -} - -static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ -split_at_mut_n(Eurydice_slice a[4U], size_t mid) { - return split_at_mut_4(a, mid); -} - -static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t -new__core_core_arch_x86___m256i_4size_t(void) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - lit; - lit.st[0U][0U] = zero(); - lit.st[0U][1U] = zero(); - lit.st[0U][2U] = zero(); - lit.st[0U][3U] = zero(); - lit.st[0U][4U] = zero(); - lit.st[1U][0U] = zero(); - lit.st[1U][1U] = zero(); - lit.st[1U][2U] = zero(); - lit.st[1U][3U] = zero(); - lit.st[1U][4U] = zero(); - lit.st[2U][0U] = zero(); - lit.st[2U][1U] = zero(); - lit.st[2U][2U] = zero(); - lit.st[2U][3U] = zero(); - lit.st[2U][4U] = zero(); - lit.st[3U][0U] = zero(); - lit.st[3U][1U] = zero(); - lit.st[3U][2U] = zero(); - lit.st[3U][3U] = zero(); - lit.st[3U][4U] = zero(); - lit.st[4U][0U] = zero(); - lit.st[4U][1U] = zero(); - lit.st[4U][2U] = zero(); - lit.st[4U][3U] = zero(); - lit.st[4U][4U] = zero(); - return lit; -} - -static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; - core_core_arch_x86___m256i uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; - core_core_arch_x86___m256i uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - Eurydice_slice uu____9 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____10 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____10, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____11 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____11, - Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____12 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____12, - Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, - Eurydice_slice)); - size_t i = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -static inline void load_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, b, (size_t)4U * sizeof(Eurydice_slice)); - load_block___136size_t(uu____0, uu____1); -} - -static inline core_core_arch_x86___m256i rotate_left___36int32_t_28int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)36, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)28, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___36int32_t_28int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___36int32_t_28int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___36int32_t_28int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___36int32_t_28int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___3int32_t_61int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)3, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)61, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___3int32_t_61int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___3int32_t_61int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___3int32_t_61int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___3int32_t_61int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___41int32_t_23int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)41, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)23, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___41int32_t_23int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___41int32_t_23int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___41int32_t_23int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___41int32_t_23int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___18int32_t_46int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)18, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)46, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___18int32_t_46int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___18int32_t_46int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___18int32_t_46int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___18int32_t_46int32_t(a, b); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___1int32_t_63int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___1int32_t_63int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___1int32_t_63int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___1int32_t_63int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___44int32_t_20int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)44, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)20, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___44int32_t_20int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___44int32_t_20int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___44int32_t_20int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___44int32_t_20int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___10int32_t_54int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)10, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)54, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___10int32_t_54int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___10int32_t_54int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___10int32_t_54int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___10int32_t_54int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___45int32_t_19int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)45, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)19, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___45int32_t_19int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___45int32_t_19int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___45int32_t_19int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___45int32_t_19int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___2int32_t_62int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)2, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)62, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___2int32_t_62int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___2int32_t_62int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___2int32_t_62int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___2int32_t_62int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___62int32_t_2int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)62, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)2, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___62int32_t_2int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___62int32_t_2int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___62int32_t_2int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___62int32_t_2int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___6int32_t_58int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)6, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)58, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___6int32_t_58int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___6int32_t_58int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___6int32_t_58int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___6int32_t_58int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___43int32_t_21int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)43, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)21, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___43int32_t_21int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___43int32_t_21int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___43int32_t_21int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___43int32_t_21int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___15int32_t_49int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)15, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)49, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___15int32_t_49int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___15int32_t_49int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___15int32_t_49int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___15int32_t_49int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___61int32_t_3int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)61, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)3, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___61int32_t_3int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___61int32_t_3int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___61int32_t_3int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___61int32_t_3int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___28int32_t_36int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)28, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)36, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___28int32_t_36int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___28int32_t_36int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___28int32_t_36int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___28int32_t_36int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___55int32_t_9int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)55, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)9, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___55int32_t_9int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___55int32_t_9int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___55int32_t_9int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___55int32_t_9int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___25int32_t_39int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)25, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)39, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___25int32_t_39int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___25int32_t_39int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___25int32_t_39int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___25int32_t_39int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___21int32_t_43int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)21, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)43, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___21int32_t_43int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___21int32_t_43int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___21int32_t_43int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___21int32_t_43int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___56int32_t_8int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)56, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)8, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___56int32_t_8int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___56int32_t_8int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___56int32_t_8int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___56int32_t_8int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___27int32_t_37int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)27, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)37, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___27int32_t_37int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___27int32_t_37int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___27int32_t_37int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___27int32_t_37int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___20int32_t_44int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)20, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)44, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___20int32_t_44int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___20int32_t_44int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___20int32_t_44int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___20int32_t_44int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___39int32_t_25int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)39, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)25, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___39int32_t_25int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___39int32_t_25int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___39int32_t_25int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___39int32_t_25int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___8int32_t_56int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)8, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)56, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___8int32_t_56int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___8int32_t_56int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___8int32_t_56int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___8int32_t_56int32_t(a, b); -} - -static inline core_core_arch_x86___m256i rotate_left___14int32_t_50int32_t( - core_core_arch_x86___m256i x) { - core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( - (int32_t)14, x, core_core_arch_x86___m256i); - return libcrux_intrinsics_avx2_mm256_xor_si256( - uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( - (int32_t)50, x, core_core_arch_x86___m256i)); -} - -static inline core_core_arch_x86___m256i _vxarq_u64___14int32_t_50int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); - return rotate_left___14int32_t_50int32_t(ab); -} - -static inline core_core_arch_x86___m256i xor_and_rotate___14int32_t_50int32_t( - core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { - return _vxarq_u64___14int32_t_50int32_t(a, b); -} - -static inline void theta_rho__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i uu____0 = - xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], - s->st[4U][0U]); - core_core_arch_x86___m256i uu____1 = - xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], - s->st[4U][1U]); - core_core_arch_x86___m256i uu____2 = - xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], - s->st[4U][2U]); - core_core_arch_x86___m256i uu____3 = - xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], - s->st[4U][3U]); - core_core_arch_x86___m256i c[5U] = { - uu____0, uu____1, uu____2, uu____3, - xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], - s->st[4U][4U])}; - core_core_arch_x86___m256i uu____4 = - rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____5 = - rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____6 = - rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i uu____7 = - rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - core_core_arch_x86___m256i t[5U] = { - uu____4, uu____5, uu____6, uu____7, - rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U])}; - core_core_arch_x86___m256i uu____8 = xor0(s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - core_core_arch_x86___m256i uu____9 = - xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); - s->st[1U][0U] = uu____9; - core_core_arch_x86___m256i uu____10 = - xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); - s->st[2U][0U] = uu____10; - core_core_arch_x86___m256i uu____11 = - xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); - s->st[3U][0U] = uu____11; - core_core_arch_x86___m256i uu____12 = - xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); - s->st[4U][0U] = uu____12; - core_core_arch_x86___m256i uu____13 = - xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); - s->st[0U][1U] = uu____13; - core_core_arch_x86___m256i uu____14 = - xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); - s->st[1U][1U] = uu____14; - core_core_arch_x86___m256i uu____15 = - xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); - s->st[2U][1U] = uu____15; - core_core_arch_x86___m256i uu____16 = - xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); - s->st[3U][1U] = uu____16; - core_core_arch_x86___m256i uu____17 = - xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); - s->st[4U][1U] = uu____17; - core_core_arch_x86___m256i uu____18 = - xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); - s->st[0U][2U] = uu____18; - core_core_arch_x86___m256i uu____19 = - xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); - s->st[1U][2U] = uu____19; - core_core_arch_x86___m256i uu____20 = - xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); - s->st[2U][2U] = uu____20; - core_core_arch_x86___m256i uu____21 = - xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); - s->st[3U][2U] = uu____21; - core_core_arch_x86___m256i uu____22 = - xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); - s->st[4U][2U] = uu____22; - core_core_arch_x86___m256i uu____23 = - xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); - s->st[0U][3U] = uu____23; - core_core_arch_x86___m256i uu____24 = - xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); - s->st[1U][3U] = uu____24; - core_core_arch_x86___m256i uu____25 = - xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); - s->st[2U][3U] = uu____25; - core_core_arch_x86___m256i uu____26 = - xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); - s->st[3U][3U] = uu____26; - core_core_arch_x86___m256i uu____27 = - xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); - s->st[4U][3U] = uu____27; - core_core_arch_x86___m256i uu____28 = - xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); - s->st[0U][4U] = uu____28; - core_core_arch_x86___m256i uu____29 = - xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); - s->st[1U][4U] = uu____29; - core_core_arch_x86___m256i uu____30 = - xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); - s->st[2U][4U] = uu____30; - core_core_arch_x86___m256i uu____31 = - xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); - s->st[3U][4U] = uu____31; - core_core_arch_x86___m256i uu____32 = - xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____32; -} - -static inline void pi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone( - (size_t)5U, s->st, old, core_core_arch_x86___m256i[5U], void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -static inline void chi__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - core_core_arch_x86___m256i old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof(core_core_arch_x86___m256i[5U])); - KRML_MAYBE_FOR5( - i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; - KRML_MAYBE_FOR5(i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; - core_core_arch_x86___m256i uu____0 = and_not_xor( - s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void iota__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - size_t i) { - core_core_arch_x86___m256i uu____0 = xor_constant( - s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -static inline void keccakf1600__core_core_arch_x86___m256i_4size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s) { - for (size_t i = (size_t)0U; i < (size_t)24U; i++) { - size_t i0 = i; - theta_rho__core_core_arch_x86___m256i_4size_t(s); - pi__core_core_arch_x86___m256i_4size_t(s); - chi__core_core_arch_x86___m256i_4size_t(s); - iota__core_core_arch_x86___m256i_4size_t(s, i0); - } -} - -static inline void absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice blocks[4U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, blocks, (size_t)4U * sizeof(Eurydice_slice)); - load_block___136size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -static inline void load_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, blocks[3U], - uint8_t, Eurydice_slice)}; - load_block___136size_t(uu____0, buf); -} - -static inline void load_block_full___136size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___136size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = {{0U}}; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_x86___m256i(*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)136U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; +inline void libcrux_sha3_avx2_x4_shake256( + Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice input2, + Eurydice_slice input3, Eurydice_slice out0, Eurydice_slice out1, + Eurydice_slice out2, Eurydice_slice out3) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - size_t i = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice uu____6 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____8 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____8, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____9 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___136size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t ret[4U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - uint8_t out2[200U] = {0U}; - uint8_t out3[200U] = {0U}; - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = { - uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, out3, uint8_t, Eurydice_slice)}; - store_block___136size_t(uu____0, buf); - uint8_t uu____4[200U]; - memcpy(uu____4, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____5[200U]; - memcpy(uu____5, out1, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____6[200U]; - memcpy(uu____6, out2, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____7[200U]; - memcpy(uu____7, out3, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____4, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____5, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[2U], uu____6, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[3U], uu____7, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___136size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t ret[4U][200U]) { - uint8_t ret0[4U][200U]; - store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)4U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - uint8_t b[4U][200U]; - store_block_full___136size_t0(s->st, b); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - store_block___136size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(s); - store_block___136size_t0(s->st, out); -} - -static inline void squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(&s); - uint8_t b[4U][200U]; - store_block_full___136size_t0(s.st, b); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( - Eurydice_slice data[4U], Eurydice_slice out[4U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - s = new__core_core_arch_x86___m256i_4size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____0 = &s; - Eurydice_slice uu____1[4U]; - memcpy(uu____1, data, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_x86___m256i_4size_t_136size_t(uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = &s; - Eurydice_slice uu____3[4U]; - memcpy(uu____3, data, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice ret[4U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(uu____2, - ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t(&s, - out); - } else { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____4.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o1[4U]; - memcpy(o1, uu____4.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[4U]; - memcpy(o, uu____5.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice orest[4U]; - memcpy(orest, uu____5.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o); - memcpy(o1, orest, (size_t)4U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t(s, o1); - } - } -} - -void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, - Eurydice_slice input2, Eurydice_slice input3, - Eurydice_slice out0, Eurydice_slice out1, - Eurydice_slice out2, Eurydice_slice out3) { - Eurydice_slice buf0[4U] = {input0, input1, input2, input3}; - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(buf0, buf); -} - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline libcrux_sha3_avx2_x4_incremental_KeccakState4 libcrux_sha3_avx2_x4_incremental_shake128_init(void) { - return new__core_core_arch_x86___m256i_4size_t(); -} - -static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice blocks[4U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v00 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v10 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v20 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v30 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); - core_core_arch_x86___m256i uu____0 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; - core_core_arch_x86___m256i uu____1 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - v1); - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; - core_core_arch_x86___m256i uu____2 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - v2); - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; - core_core_arch_x86___m256i uu____3 = - libcrux_intrinsics_avx2_mm256_xor_si256( - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - v3); - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_array_to_subslice( - (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ - .start = start, .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, - Eurydice_slice)); - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; - core_core_arch_x86___m256i uu____8 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); - s[i0][j0] = uu____8; - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - Eurydice_slice uu____9 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____10 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____10, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____11 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____11, - Eurydice_slice_subslice( - blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____12 = Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____12, - Eurydice_slice_subslice( - blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - core_core_arch_x86___m256i u0 = - libcrux_intrinsics_avx2_mm256_loadu_si256_u8( - core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, - Eurydice_slice)); - size_t i = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - core_core_arch_x86___m256i uu____13 = - libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); - s[i][j] = uu____13; - } -} - -static inline void load_block_full___168size_t( - core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, - Eurydice_array_to_slice((size_t)200U, blocks[3U], - uint8_t, Eurydice_slice)}; - load_block___168size_t(uu____0, buf); -} - -static inline void load_block_full___168size_t0( - core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { - core_core_arch_x86___m256i(*uu____0)[5U] = a; - uint8_t uu____1[4U][200U]; - memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___168size_t(uu____0, uu____1); -} - -inline void -libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice last[4U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[4U][200U] = {{0U}}; - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); - core_core_arch_x86___m256i(*uu____1)[5U] = s->st; - uint8_t uu____2[4U][200U]; - memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); - load_block_full___168size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_x86___m256i_4size_t(s); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, - Eurydice_slice data3) { - Eurydice_slice buf[4U] = {data0, data1, data2, data3}; - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( - s, buf); -} - -static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], - Eurydice_slice out[4U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { - size_t i0 = i; - core_core_arch_x86___m256i v0l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v1h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)32, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v2l = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], - s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v3h = - libcrux_intrinsics_avx2_mm256_permute2x128_si256( - (int32_t)49, - s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], - s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] - [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], - core_core_arch_x86___m256i); - core_core_arch_x86___m256i v0 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); - core_core_arch_x86___m256i v1 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); - core_core_arch_x86___m256i v2 = - libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); - core_core_arch_x86___m256i v3 = - libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v2); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8( - Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ - .start = (size_t)32U * i0, - .end = (size_t)32U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v3); - } - size_t rem = (size_t)168U % (size_t)32U; - size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); - uint8_t u8s[32U] = {0U}; - size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; - size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - if (rem == (size_t)16U) { - uint8_t u8s0[32U] = {0U}; - size_t i = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; - size_t j = - ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); - libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); - Eurydice_slice uu____6 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____7 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____7, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____8 = Eurydice_slice_subslice( - out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____8, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____9 = Eurydice_slice_subslice( - out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____9, - Eurydice_array_to_subslice( - (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block___168size_t0(core_core_arch_x86___m256i (*a)[5U], - Eurydice_slice b[4U]) { - store_block___168size_t(a, b); -} - -static inline void -squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - keccakf1600__core_core_arch_x86___m256i_4size_t(s); - store_block___168size_t0(s->st, out); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3) { - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, buf); -} - -static inline void -squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - store_block___168size_t0(s->st, out); + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice data0, + Eurydice_slice data1, Eurydice_slice data2, Eurydice_slice data3) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, + Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } inline void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out[4U]) { - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____0 = - split_at_mut_n(out, (size_t)168U); - Eurydice_slice o0[4U]; - memcpy(o0, uu____0.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o10[4U]; - memcpy(o10, uu____0.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o0); - K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____1 = - split_at_mut_n(o10, (size_t)168U); - Eurydice_slice o1[4U]; - memcpy(o1, uu____1.fst, (size_t)4U * sizeof(Eurydice_slice)); - Eurydice_slice o2[4U]; - memcpy(o2, uu____1.snd, (size_t)4U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o1); - squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o2); -} - -void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3) { - Eurydice_slice buf[4U] = {out0, out1, out2, out3}; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( - s, buf); +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, + Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 2f9e86a7b..7fbdbc8a2 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H @@ -15,38 +15,32 @@ extern "C" { #include "eurydice_glue.h" #include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_core.h" -#include "libcrux_sha3_internal.h" - -typedef struct - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { - core_core_arch_x86___m256i st[5U][5U]; -} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; +#include "libcrux_sha3_neon.h" void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice input2, Eurydice_slice input3, Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +typedef struct libcrux_sha3_avx2_x4_incremental_KeccakState4_s { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t + state[2U]; +} libcrux_sha3_avx2_x4_incremental_KeccakState4; + +libcrux_sha3_avx2_x4_incremental_KeccakState4 libcrux_sha3_avx2_x4_incremental_shake128_init(void); void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, - Eurydice_slice data3); + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice data0, + Eurydice_slice data1, Eurydice_slice data2, Eurydice_slice data3); void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3); + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, + Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *s, - Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, - Eurydice_slice out3); + libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, + Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index be1a83910..9428aa94d 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/franziskus/repos/eurydice//eurydice --config - ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - a32b316e KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 8c8485739..8d215805c 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #include "libcrux_sha3_neon.h" @@ -1839,9 +1839,6 @@ void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, keccakx2___136size_t_31uint8_t(buf0, buf); } -typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - KeccakState2; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t libcrux_sha3_neon_x2_incremental_shake128_init(void) { return new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index c6b0120ec..0e8477b26 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/bhargava/Desktop/repositories/eurydice/eurydice - --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* - version: 0e2a116d KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_neon_H From be1905d93c84aa6321e331a7642764b4961f745c Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Fri, 7 Jun 2024 15:07:51 -0700 Subject: [PATCH 33/84] Refresh with correct implementation of macro --- libcrux-ml-kem/c/eurydice_glue.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index e00c11543..d9e6cec67 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -90,22 +90,17 @@ typedef struct { .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ .len = slice.len - mid}}) -// Can't have a flexible array as a member of a union -- this violates strict -// aliasing rules. -typedef struct { - uint8_t tag; - uint8_t case_Ok[]; -} result_tryfromslice_flexible; - -// See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) \ - Eurydice_slice_to_array3((result_tryfromslice_flexible *)dst, src, \ +// Conversion of slice to an array, rewritten (by Eurydice) to name the +// destination array, since arrays are not values in C. +// N.B.: see note in karamel/lib/Inlining.ml if you change this. +#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) \ + Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ sizeof(t_arr)) -static inline void Eurydice_slice_to_array3(result_tryfromslice_flexible *dst, +static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, Eurydice_slice src, size_t sz) { - dst->tag = 0; - memcpy(dst->case_Ok, src.ptr, sz); + *dst_tag = 0; + memcpy(dst_ok, src.ptr, sz); } // CORE STUFF (conversions, endianness, ...) From 86dd6f6f20341246e864e02b3268fadb0f30a32c Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Sat, 8 Jun 2024 13:06:08 +0200 Subject: [PATCH 34/84] neon bench --- libcrux-ml-kem/c/benches/mlkem768.cc | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/libcrux-ml-kem/c/benches/mlkem768.cc b/libcrux-ml-kem/c/benches/mlkem768.cc index 217ead8bf..c88c747f4 100644 --- a/libcrux-ml-kem/c/benches/mlkem768.cc +++ b/libcrux-ml-kem/c/benches/mlkem768.cc @@ -70,4 +70,59 @@ BENCHMARK(kyber768_key_generation); BENCHMARK(kyber768_encapsulation); BENCHMARK(kyber768_decapsulation); +#ifdef LIBCRUX_AARCH64 +#include "libcrux_mlkem768_neon.h" + +static void +kyber768_key_generation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + + for (auto _ : state) + { + key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + } +} + +static void +kyber768_encapsulation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + for (auto _ : state) + { + ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + } +} + +static void +kyber768_decapsulation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + + for (auto _ : state) + { + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + } +} + +BENCHMARK(kyber768_key_generation_neon); +BENCHMARK(kyber768_encapsulation_neon); +BENCHMARK(kyber768_decapsulation_neon); +#endif + BENCHMARK_MAIN(); From 54b814edca76a57ff8b4edf4c94806207d04bc81 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Mon, 10 Jun 2024 11:11:03 +0200 Subject: [PATCH 35/84] nix: use `clang-tools` for `clang-format` --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index d4c2c238b..90b35d678 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,7 @@ name = "ml-kem"; inherit src cargoArtifacts; nativeBuildInputs = [ - pkgs.clang + pkgs.clang-tools pkgs.cmake pkgs.gbenchmark pkgs.mold-wrapped From 51d838e3e0eba386be1ec5a3589ffe56a86259e7 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 11:28:44 +0200 Subject: [PATCH 36/84] add avx2 code again --- libcrux-ml-kem/c/internal/libcrux_core.h | 99 +- .../c/internal/libcrux_mlkem_avx2.h | 75 + .../c/internal/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 38 + .../c/internal/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_core.c | 48 +- libcrux-ml-kem/c/libcrux_core.h | 10 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 55 + libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 40 + libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 163 + libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 89 + libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 54 + libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 40 + libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 7415 +++++++++++++++++ libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 294 + libcrux-ml-kem/c/libcrux_mlkem_portable.c | 521 +- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 10 +- libcrux-ml-kem/c/libcrux_platform.h | 6 +- libcrux-ml-kem/c/libcrux_sha3.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 2111 ++++- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 38 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 6 +- 31 files changed, 10988 insertions(+), 196 deletions(-) create mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h create mode 100644 libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_avx2.h create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.c create mode 100644 libcrux-ml-kem/c/libcrux_mlkem_avx2.h diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index f03cb2277..39db7b956 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_core_H @@ -23,7 +23,7 @@ extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( #define CORE_NUM__U32_8__BITS (32U) -static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t x0[4U]); +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); #define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) @@ -118,24 +118,6 @@ libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__type void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, uint8_t ret[1120U]); -typedef struct - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; - libcrux_ml_kem_types_MlKemPublicKey____800size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( uint8_t value[800U]); @@ -166,12 +148,36 @@ uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( Eurydice_slice lhs, Eurydice_slice rhs); +typedef struct + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; + void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]); +typedef struct + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_; + +typedef struct + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; + Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); @@ -182,6 +188,45 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, uint8_t ret[64U]); +typedef struct + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[24U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, + uint8_t ret[24U]); + +typedef struct + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[20U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, + uint8_t ret[20U]); + +typedef struct + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[10U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError; + +void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, + uint8_t ret[10U]); + typedef struct core_option_Option__Eurydice_slice_uint8_t_s { core_option_Option__size_t_tags tag; Eurydice_slice f0; @@ -189,7 +234,7 @@ typedef struct core_option_Option__Eurydice_slice_uint8_t_s { typedef struct core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; union { int16_t case_Ok[16U]; core_array_TryFromSliceError case_Err; @@ -201,10 +246,10 @@ void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_arr int16_t ret[16U]); typedef struct - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t__s { - Eurydice_slice fst[2U]; - Eurydice_slice snd[2U]; -} K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_; + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s { + Eurydice_slice fst[4U]; + Eurydice_slice snd[4U]; +} K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h new file mode 100644 index 000000000..10a2cb5a5 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -0,0 +1,75 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_mlkem_avx2_H +#define __internal_libcrux_mlkem_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_mlkem_avx2.h" +#include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_sha3_avx2.h" + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t *public_key); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_mlkem_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 0f14466d1..5773bba52 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h new file mode 100644 index 000000000..11ada5b26 --- /dev/null +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -0,0 +1,38 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __internal_libcrux_sha3_avx2_H +#define __internal_libcrux_sha3_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../libcrux_sha3_avx2.h" +#include "eurydice_glue.h" +#include "internal/libcrux_core.h" +#include "intrinsics/libcrux_intrinsics_avx2.h" + +typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + libcrux_sha3_avx2_x4_incremental_KeccakState4; + +void libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]); + +void libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]); + +#if defined(__cplusplus) +} +#endif + +#define __internal_libcrux_sha3_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 46e81d5c3..c897dae9f 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index a3accd24c..3863ca9dc 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_core.h" @@ -322,6 +322,48 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); } +void core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, + uint8_t ret[24U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[24U]; + memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +void core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, + uint8_t ret[20U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[20U]; + memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, + uint8_t ret[10U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[10U]; + memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + void core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, int16_t ret[16U]) { diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index d9a0b80fa..52b97c825 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_core_H @@ -128,11 +128,11 @@ typedef struct #define core_result_Err 1 typedef uint8_t - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags; typedef struct core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s { - core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_tags tag; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; union { uint8_t case_Ok[8U]; core_array_TryFromSliceError case_Err; diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 9fef0fd8b..40b2e232a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c new file mode 100644 index 000000000..9dbf4e203 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -0,0 +1,55 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem1024_avx2.h" + +void libcrux_ml_kem_mlkem1024_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h new file mode 100644 index 000000000..d3da0c00c --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -0,0 +1,40 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem1024_avx2_H +#define __libcrux_mlkem1024_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" + +void libcrux_ml_kem_mlkem1024_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem1024_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_mlkem1024_avx2_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ +libcrux_ml_kem_mlkem1024_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem1024_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index f292fbfbd..b63311db9 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 321bfbf6e..2479e6391 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 5d00daade..5256458eb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c new file mode 100644 index 000000000..14cd4287a --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -0,0 +1,163 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem512_avx2.h" + +#include "internal/libcrux_mlkem_avx2.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_mlkem512_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uu____0); +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + public_key); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ + .tag = core_option_None}); + } + return uu____0; +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + public_key); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uu____0); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h new file mode 100644 index 000000000..34801018a --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -0,0 +1,89 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem512_avx2_H +#define __libcrux_mlkem512_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +void libcrux_ml_kem_mlkem512_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem512_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]); + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_mlkem512_avx2_generate_key_pair(uint8_t randomness[64U]); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( + uint8_t *public_key); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ +libcrux_ml_kem_mlkem512_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +bool libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( + uint8_t *public_key); + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]); + +void libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem512_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 126402c11..8a1a92703 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 607fa0ae7..9ad10a424 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 59e587f22..c69fb58ac 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c new file mode 100644 index 000000000..4497d2302 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -0,0 +1,54 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "libcrux_mlkem768_avx2.h" + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h new file mode 100644 index 000000000..373792504 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -0,0 +1,40 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem768_avx2_H +#define __libcrux_mlkem768_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem512_avx2.h" + +void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]); + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]); + +core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 6b485ab48..06ce4a50d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 03b200b57..d7b8a5c6f 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c new file mode 100644 index 000000000..2cfe23c30 --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -0,0 +1,7415 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#include "internal/libcrux_mlkem_avx2.h" + +#include "internal/libcrux_core.h" +#include "internal/libcrux_mlkem_portable.h" +#include "internal/libcrux_sha3_avx2.h" + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void) { + return libcrux_intrinsics_avx2_mm256_setzero_si256(); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( + void) { + return libcrux_ml_kem_vector_avx2_zero(); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_slice array) { + return libcrux_intrinsics_avx2_mm256_loadu_si256_i16(array); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice array) { + return libcrux_ml_kem_vector_avx2_from_i16_array(array); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_add(lhs, rhs[0U]); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_sub_epi16(lhs, rhs); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_sub(lhs, rhs[0U]); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + core_core_arch_x86___m256i v, int16_t c) { + return libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant(v, c); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + vector, constant); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i v_minus_field_modulus = + libcrux_intrinsics_avx2_mm256_sub_epi16(vector, field_modulus); + core_core_arch_x86___m256i sign_mask = + libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, v_minus_field_modulus, core_core_arch_x86___m256i); + core_core_arch_x86___m256i conditional_add_field_modulus = + libcrux_intrinsics_avx2_mm256_and_si256(sign_mask, field_modulus); + return libcrux_intrinsics_avx2_mm256_add_epi16(v_minus_field_modulus, + conditional_add_field_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329(vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i t = libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER)); + core_core_arch_x86___m256i uu____1 = t; + core_core_arch_x86___m256i t0 = libcrux_intrinsics_avx2_mm256_add_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16((int16_t)512)); + core_core_arch_x86___m256i quotient = + libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)10, t0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = quotient; + core_core_arch_x86___m256i quotient_times_field_modulus = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + return libcrux_intrinsics_avx2_mm256_sub_epi16(vector, + quotient_times_field_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i constant0 = + libcrux_intrinsics_avx2_mm256_set1_epi16(constant); + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(vector, constant0); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(vector, constant0); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + vector, constant); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)2); + core_core_arch_x86___m256i field_modulus_quartered = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)4); + core_core_arch_x86___m256i shifted = + libcrux_intrinsics_avx2_mm256_sub_epi16(field_modulus_halved, vector); + core_core_arch_x86___m256i mask = libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, shifted, core_core_arch_x86___m256i); + core_core_arch_x86___m256i shifted_to_positive = + libcrux_intrinsics_avx2_mm256_xor_si256(mask, shifted); + core_core_arch_x86___m256i shifted_to_positive_in_range = + libcrux_intrinsics_avx2_mm256_sub_epi16(shifted_to_positive, + field_modulus_quartered); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, shifted_to_positive_in_range, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + vector); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + core_core_arch_x86___m256i prod02 = + libcrux_intrinsics_avx2_mm256_mul_epu32(lhs, rhs); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi32((int32_t)245, lhs, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i prod13 = libcrux_intrinsics_avx2_mm256_mul_epu32( + uu____0, libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, rhs, core_core_arch_x86___m256i)); + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi32(prod02, prod13); + return libcrux_intrinsics_avx2_mm256_unpackhi_epi64( + uu____1, libcrux_intrinsics_avx2_mm256_unpackhi_epi32(prod02, prod13)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + core_core_arch_x86___m256i v, core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(v, c); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta3, -zeta3, zeta3, zeta3, -zeta2, -zeta2, zeta2, zeta2, -zeta1, + -zeta1, zeta1, zeta1, -zeta0, -zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step(vector, zeta0, zeta1, + zeta2, zeta3); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta1, -zeta1, -zeta1, -zeta1, zeta1, zeta1, zeta1, zeta1, -zeta0, + -zeta0, -zeta0, -zeta0, zeta0, zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)238, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)68, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step(vector, zeta0, zeta1); +} + +inline core_core_arch_x86___m128i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + core_core_arch_x86___m128i v, core_core_arch_x86___m128i c) { + core_core_arch_x86___m128i value_low = + libcrux_intrinsics_avx2_mm_mullo_epi16(v, c); + core_core_arch_x86___m128i uu____0 = value_low; + core_core_arch_x86___m128i k = libcrux_intrinsics_avx2_mm_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m128i uu____1 = k; + core_core_arch_x86___m128i k_times_modulus = + libcrux_intrinsics_avx2_mm_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m128i value_high = + libcrux_intrinsics_avx2_mm_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm_sub_epi16(value_high, k_times_modulus); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i uu____0 = rhs; + core_core_arch_x86___m128i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs0); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs0); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients, core_core_arch_x86___m256i); + return combined0; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step(vector, zeta); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum0 = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum0; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta3, zeta3, (int16_t)0, (int16_t)0, zeta2, zeta2, + (int16_t)0, (int16_t)0, zeta1, zeta1, (int16_t)0, + (int16_t)0, zeta0, zeta0, (int16_t)0, (int16_t)0)); + core_core_arch_x86___m256i sum = + libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(sum0); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)204, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + vector, zeta0, zeta1, zeta2, zeta3); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i lhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)-1, + (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)-1, + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)1, + (int16_t)1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta1, zeta1, zeta1, zeta1, (int16_t)0, (int16_t)0, + (int16_t)0, (int16_t)0, zeta0, zeta0, zeta0, zeta0, + (int16_t)0, (int16_t)0, (int16_t)0, (int16_t)0)); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)240, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step(vector, zeta0, + zeta1); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs); + core_core_arch_x86___m128i uu____0 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients0, + core_core_arch_x86___m256i); + return combined0; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step(vector, zeta); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + core_core_arch_x86___m256i v) { + core_core_arch_x86___m256i uu____0 = v; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)16, v, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i result = + libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); + core_core_arch_x86___m256i result0 = libcrux_intrinsics_avx2_mm256_slli_epi32( + (int32_t)16, result, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_srai_epi32((int32_t)16, result0, + core_core_arch_x86___m256i); +} + +inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i shuffle_with = + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, + (int8_t)5, (int8_t)4, (int8_t)1, (int8_t)0, (int8_t)15, (int8_t)14, + (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, (int8_t)3, (int8_t)2, + (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, + (int8_t)1, (int8_t)0); + core_core_arch_x86___m256i lhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(lhs, shuffle_with); + core_core_arch_x86___m256i lhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, lhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lhs_shuffled0); + core_core_arch_x86___m256i lhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_evens); + core_core_arch_x86___m128i lhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i lhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_odds); + core_core_arch_x86___m256i rhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(rhs, shuffle_with); + core_core_arch_x86___m256i rhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, rhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i rhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(rhs_shuffled0); + core_core_arch_x86___m256i rhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_evens); + core_core_arch_x86___m128i rhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, rhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i rhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_odds); + core_core_arch_x86___m256i left = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_evens0, rhs_evens0); + core_core_arch_x86___m256i right = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_odds0, rhs_odds0); + core_core_arch_x86___m256i right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s(right); + core_core_arch_x86___m256i uu____0 = right0; + core_core_arch_x86___m256i right1 = libcrux_intrinsics_avx2_mm256_mullo_epi32( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi32( + -(int32_t)zeta3, (int32_t)zeta3, -(int32_t)zeta2, (int32_t)zeta2, + -(int32_t)zeta1, (int32_t)zeta1, -(int32_t)zeta0, (int32_t)zeta0)); + core_core_arch_x86___m256i products_left = + libcrux_intrinsics_avx2_mm256_add_epi32(left, right1); + core_core_arch_x86___m256i products_left0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_left); + core_core_arch_x86___m256i uu____1 = rhs; + core_core_arch_x86___m256i rhs_adjacent_swapped = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)13, (int8_t)12, (int8_t)15, (int8_t)14, + (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, (int8_t)5, + (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, (int8_t)0, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)15, + (int8_t)14, (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, + (int8_t)5, (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, + (int8_t)0, (int8_t)3, (int8_t)2)); + core_core_arch_x86___m256i products_right = + libcrux_intrinsics_avx2_mm256_madd_epi16(lhs, rhs_adjacent_swapped); + core_core_arch_x86___m256i products_right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_right); + core_core_arch_x86___m256i products_right1 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)16, products_right0, + core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_blend_epi16((int32_t)170, products_left0, + products_right1, + core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(lhs[0U], rhs[0U], zeta0, + zeta1, zeta2, zeta3); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + core_core_arch_x86___m256i lsb_to_msb = + libcrux_intrinsics_avx2_mm256_slli_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i low_msbs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lsb_to_msb); + core_core_arch_x86___m128i high_msbs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lsb_to_msb, core_core_arch_x86___m128i); + core_core_arch_x86___m128i msbs = + libcrux_intrinsics_avx2_mm_packs_epi16(low_msbs, high_msbs); + int32_t bits_packed = libcrux_intrinsics_avx2_mm_movemask_epi8(msbs); + uint8_t serialized[2U] = {0U}; + serialized[0U] = (uint8_t)bits_packed; + serialized[1U] = (uint8_t)(bits_packed >> 8U); + memcpy(ret, serialized, (size_t)2U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(vector, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_1(Eurydice_slice bytes) { + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i shift_lsb_to_msb = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 8U, (int16_t)1 << 9U, (int16_t)1 << 10U, + (int16_t)1 << 11U, (int16_t)1 << 12U, (int16_t)1 << 13U, + (int16_t)1 << 14U, (int16_t)1 << 15U, (int16_t)1 << 8U, + (int16_t)1 << 9U, (int16_t)1 << 10U, (int16_t)1 << 11U, + (int16_t)1 << 12U, (int16_t)1 << 13U, (int16_t)1 << 14U, + (int16_t)1 << 15U); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsb_to_msb); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, coefficients_in_msb, core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_1(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t serialized[16U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, (int8_t)4, + (int8_t)0, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, + (int8_t)4, (int8_t)0)); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0, + (int32_t)0, (int32_t)0, (int32_t)4, (int32_t)0)); + core_core_arch_x86___m128i combined0 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(combined); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_slice((size_t)16U, serialized, uint8_t, Eurydice_slice), + combined0); + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)16U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_4(vector, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients_in_lsb = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients_in_msb, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_in_lsb; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____15, libcrux_intrinsics_avx2_mm256_set1_epi16(((int16_t)1 << 4U) - + (int16_t)1)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_4(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22, + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)22, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)8, adjacent_4_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i adjacent_8_combined0 = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_8_combined1 = + libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)5U, .end = (size_t)21U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[10U]; + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[10U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t ret0[10U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_5(vector, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_5(Eurydice_slice bytes) { + uint8_t uu____0 = + Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____1 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____2 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____3 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____4 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____5 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____6 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____7 = + Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____8 = + Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____9 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____10 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____11 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____12 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____13 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____14 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + core_core_arch_x86___m128i coefficients = libcrux_intrinsics_avx2_mm_set_epi8( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, uu____14, + Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); + core_core_arch_x86___m256i coefficients_loaded = + libcrux_intrinsics_avx2_mm256_castsi128_si256(coefficients); + core_core_arch_x86___m256i coefficients_loaded0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients_loaded, coefficients, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_loaded0; + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____15, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)15, (int8_t)14, (int8_t)13, + (int8_t)12, (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)9, + (int8_t)8, (int8_t)7, (int8_t)6, (int8_t)7, (int8_t)6, (int8_t)5, + (int8_t)4, (int8_t)5, (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m256i uu____16 = coefficients0; + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____16, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 5U, (int16_t)1 << 2U, + (int16_t)1 << 7U, (int16_t)1 << 4U, (int16_t)1 << 9U, + (int16_t)1 << 6U, (int16_t)1 << 11U, (int16_t)1 << 0U, + (int16_t)1 << 5U, (int16_t)1 << 2U, (int16_t)1 << 7U, + (int16_t)1 << 4U, (int16_t)1 << 9U, (int16_t)1 << 6U, + (int16_t)1 << 11U)); + return libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)11, coefficients1, + core_core_arch_x86___m256i); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_5(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)12, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)11, + (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)12, (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)10U, .end = (size_t)26U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[20U]; + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[20U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_10(vector, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U, (int16_t)1 << 0U, (int16_t)1 << 2U, + (int16_t)1 << 4U, (int16_t)1 << 6U, (int16_t)1 << 0U, + (int16_t)1 << 2U, (int16_t)1 << 4U, (int16_t)1 << 6U, + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(9U, 8U, 8U, 7U, 7U, 6U, 6U, 5U, + 4U, 3U, 3U, 2U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)4U, + .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 13U, + 12U, 12U, 11U, 10U, 9U, + 9U, 8U, 8U, 7U, 7U, 6U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)6, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 10U) - (int16_t)1)); + return coefficients3; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_10(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_to_i16_array( + core_core_arch_x86___m256i v, int16_t ret[16U]) { + int16_t output[16U] = {0U}; + libcrux_intrinsics_avx2_mm256_storeu_si256_i16( + Eurydice_array_to_slice((size_t)16U, output, int16_t, Eurydice_slice), v); + memcpy(ret, output, (size_t)16U * sizeof(int16_t)); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]) { + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + memcpy(lit.elements, uu____0, (size_t)16U * sizeof(int16_t)); + return lit; +} + +inline void libcrux_ml_kem_vector_avx2_portable_serialize_11( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]) { + uint8_t result[22U] = {0U}; + result[0U] = (uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); + result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | + (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | + (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); + result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | + (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[10U] = (uint8_t)(v.elements[7U] >> 3U); + result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + result[15U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + result[19U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + result[20U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + int16_t array[16U]; + libcrux_ml_kem_vector_avx2_to_i16_array(vector, array); + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector input = + libcrux_ml_kem_vector_avx2_portable_from_i16_array(uu____0); + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_portable_serialize_11(input, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_11(vector, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_zero(void) { + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector result = + libcrux_ml_kem_vector_avx2_portable_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____5 = + uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; + int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; + int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; + int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____12 = + uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) + << 1U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; + int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; + int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____17 = + &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; + int16_t uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____23 = + uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; + int16_t uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; + int16_t uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; + int16_t uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____30 = + uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, + uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; + int16_t uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; + int16_t uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, + uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; + return result; +} + +inline void libcrux_ml_kem_vector_avx2_portable_to_i16_array( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]) { + memcpy(ret, v.elements, (size_t)16U * sizeof(int16_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector output = + libcrux_ml_kem_vector_avx2_portable_deserialize_11(bytes); + int16_t ret[16U]; + libcrux_ml_kem_vector_avx2_portable_to_i16_array(output, ret); + return libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_array_to_slice((size_t)16U, ret, int16_t, Eurydice_slice)); +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_11(bytes); +} + +inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8, + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)13, (int8_t)12, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)5, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)12U, .end = (size_t)28U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[24U]; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[24U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_12(vector, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(11U, 10U, 10U, 9U, 8U, 7U, 7U, 6U, + 5U, 4U, 4U, 3U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 12U, + 11U, 11U, 10U, 9U, 8U, + 8U, 7U, 6U, 5U, 5U, 4U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 12U) - (int16_t)1)); + return coefficients3; +} + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_12(bytes); +} + +inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( + Eurydice_slice input, Eurydice_slice output) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i potential_coefficients = + libcrux_ml_kem_vector_avx2_serialize_deserialize_12(input); + core_core_arch_x86___m256i compare_with_field_modulus = + libcrux_intrinsics_avx2_mm256_cmpgt_epi16(field_modulus, + potential_coefficients); + uint8_t good[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(compare_with_field_modulus, + good); + uint8_t lower_shuffles[16U]; + memcpy(lower_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[0U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i lower_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, lower_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm256_castsi256_si128(potential_coefficients); + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(lower_coefficients, + lower_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128(output, lower_coefficients0); + size_t sampled_count = (size_t)core_num__u8_6__count_ones(good[0U]); + uint8_t upper_shuffles[16U]; + memcpy(upper_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[1U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i upper_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, upper_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, potential_coefficients, core_core_arch_x86___m128i); + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(upper_coefficients, + upper_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128( + Eurydice_slice_subslice( + output, + ((core_ops_range_Range__size_t){.start = sampled_count, + .end = sampled_count + (size_t)8U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice), + upper_coefficients0); + size_t uu____0 = sampled_count; + return uu____0 + (size_t)core_num__u8_6__count_ones(good[1U]); +} + +size_t +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + Eurydice_slice input, Eurydice_slice output) { + return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); +} + +inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( + libcrux_ml_kem_vector_avx2_portable_PortableVector *self) { + return self[0U]; +} + +inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( + core_core_arch_x86___m256i *self) { + return self[0U]; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + return lit; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline core_core_arch_x86___m256i shift_right___15int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i shift_right___15int32_t0( + core_core_arch_x86___m256i vector) { + return shift_right___15int32_t(vector); +} + +static core_core_arch_x86___m256i +to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a) { + core_core_arch_x86___m256i t = shift_right___15int32_t0(a); + core_core_arch_x86___m256i fm = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &fm); +} + +static inline void +serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, + .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___3size_t(uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = self; + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____2, uu____3, uu____4, uu____5, + Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice_subslice( + a, + ((core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___3size_t(uu____0); + uint8_t randomness0[3U][504U]; + shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + shake128_squeeze_block___3size_t(&xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t0( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[3U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[3U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; + +static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out12 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out12, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out2 = uu____1.snd; + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, + Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + ((core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +static inline void ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + core_core_arch_x86___m256i t = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +typedef struct + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i fst; + core_core_arch_x86___m256i snd; +} __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector; + +static core_core_arch_x86___m256i +montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v, int16_t fer) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, fer); +} + +static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i t = + montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector(b, + zeta_r); + b = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + a, &t); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &t); + return (( + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +static inline void +ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); + size_t zeta_i = (size_t)1U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + out = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static core_core_arch_x86___m256i +to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + self->coefficients[j]); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_1152size_t__uint8_t_1184size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___3size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[1152U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___3size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___3size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static inline void +invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i a_minus_b = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + b, &a); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &b)); + b = montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_minus_b, zeta_r); + return (( + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +static inline void +invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static core_core_arch_x86___m256i +decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i uu____0 = + decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i tmp = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &message->coefficients[i0]); + core_core_arch_x86___m256i tmp0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &tmp); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___10int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)10) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___10int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___10int32_t(vector); +} + +static inline void +compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___10int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, + .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___11int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)11) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___11int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___11int32_t(vector); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___4int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)4) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___4int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___4int32_t(vector); +} + +static inline void +compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___4int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline core_core_arch_x86___m256i +compress_ciphertext_coefficient___5int32_t(core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)5) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i compress___5int32_t( + core_core_arch_x86___m256i vector) { + return compress_ciphertext_coefficient___5int32_t(vector); +} + +static inline void +compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficients = compress___5int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, + .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice out) { + compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[3U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___10int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)10); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i +decompress_ciphertext_coefficient___10int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___10int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, + .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___10int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___11int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)11); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i +decompress_ciphertext_coefficient___11int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___11int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, + .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___11int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___4int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)4); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i decompress_ciphertext_coefficient___4int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___4int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, + .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + bytes); + core_core_arch_x86___m256i uu____0 = + decompress_ciphertext_coefficient___4int32_t0(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline core_core_arch_x86___m256i +decompress_ciphertext_coefficient___5int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)5); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +static core_core_arch_x86___m256i decompress_ciphertext_coefficient___5int32_t0( + core_core_arch_x86___m256i vector) { + return decompress_ciphertext_coefficient___5int32_t(vector); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, + .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + core_core_arch_x86___m256i uu____1 = + decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, + .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + self->coefficients[i0], &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static inline void +compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient = + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0]); + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___3size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[4U], + uint8_t ret[1536U]) { + uint8_t out[1536U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1536U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U], + Eurydice_slice seed_for_a, uint8_t ret[1568U]) { + uint8_t public_key_serialized[1568U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1568U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[4U]; + memcpy( + uu____1, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, + (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568size_t_4size_t( + Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[4U]; + memcpy( + uu____0, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[4U]; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___4size_t(uint8_t input[4U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___4size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[4U][504U]) { + uint8_t out[4U][504U] = {{0U}}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], + uint8_t(*)[504U], uint8_t[504U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uint8_t randomness[4U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___4size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[4U][168U]) { + uint8_t out[4U][168U] = {{0U}}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____3 = self; + Eurydice_slice uu____4 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], + uint8_t(*)[168U], uint8_t[168U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uint8_t randomness[4U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seeds[4U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + size_t sampled_coefficients[4U] = {0U}; + int16_t out[4U][272U] = {{0U}}; + uint8_t uu____0[4U][34U]; + memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___4size_t(uu____0); + uint8_t randomness0[4U][504U]; + shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); + uint8_t uu____1[4U][504U]; + memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[4U][168U]; + shake128_squeeze_block___4size_t(&xof_state, randomness); + uint8_t uu____2[4U][168U]; + memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[4U][272U]; + memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t0( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U][4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + A_transpose[i]);); + KRML_MAYBE_FOR4( + i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[4U][34U]; + memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[4U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[4U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t; + +static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[4U][128U]) { + uint8_t out[4U][128U] = {{0U}}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out123 = uu____0.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____1 = core_slice___Slice_T___split_at_mut( + out123, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out1 = uu____1.fst; + Eurydice_slice out23 = uu____1.snd; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____2 = core_slice___Slice_T___split_at_mut( + out23, (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out2 = uu____2.fst; + Eurydice_slice out3 = uu____2.snd; + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____8 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____9 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, + Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], + uint8_t(*)[128U], uint8_t[128U]), + uint8_t, Eurydice_slice)); + memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[4U]; + memcpy( + uu____2, re_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_1536size_t__uint8_t_1568size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___4size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[4U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[4U]; + memcpy( + uu____4, t_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1568U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t_1568size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[4U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[1536U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1536U]; + memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); + uint8_t uu____7[1568U]; + memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); + K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); + return lit; +} + +static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)3168U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___4size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)3168U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); +} + +libcrux_ml_kem_mlkem1024_MlKem1024KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1536U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); + uint8_t public_key[1568U]; + memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[3168U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t( + uu____1, + Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[3168U]; + memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; + uint8_t uu____4[1568U]; + memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( + uu____4)); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[4U][33U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[4U][128U]; + PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[4U]; + memcpy( + uu____2, error_1, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___4size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[4U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [4U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static inline void +compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[352U]) { + uint8_t serialized[352U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = compress___11int32_t( + to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)352U, serialized, + ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, + .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); +} + +static inline void +compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[352U]) { + uint8_t uu____0[352U]; + compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[4U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)4U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)1408U / (size_t)4U), + .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[352U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t_352size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice out) { + compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector(re, out); +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1568U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[4U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536size_t_4size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[4U][4U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[4U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[4U]; + memcpy( + error_1, uu____3.fst, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___4size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[4U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1568U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[4U]; + memcpy( + uu____5, u, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1408U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t_160size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___4size_t( + Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1568U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1568U]; + memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline void +ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = (size_t)0U; + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)7U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)6U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)5U); + ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re, + (size_t)4U); + ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1568U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)11U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_11size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[4U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)4U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[4U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_11size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_5size_t( + Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, + (size_t)1408U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[4U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___4size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( + libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, + libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1536U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1568U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___4size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1600U]; + libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( + implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___4size_t_32size_t( + Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1568U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( + uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[2U], + uint8_t ret[768U]) { + uint8_t out[768U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)768U, out, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); +} + +static inline void +serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U], + Eurydice_slice seed_for_a, uint8_t ret[800U]) { + uint8_t public_key_serialized[800U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)800U, public_key_serialized, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[2U]; + memcpy( + uu____1, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, + (size_t)768U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); +} + +bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800size_t_2size_t( + Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[2U]; + memcpy( + uu____0, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static void +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[2U]; + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +shake128_init_absorb___2size_t(uint8_t input[2U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + return state; +} + +static inline void shake128_squeeze_three_blocks___2size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[2U][504U]) { + uint8_t out[2U][504U] = {{0U}}; + uint8_t dummy_out0[504U] = {0U}; + uint8_t dummy_out1[504U] = {0U}; + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], + Eurydice_slice), + (size_t)1U, uint8_t[504U], + K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)504U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], + uint8_t[504U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + uint8_t randomness[2U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void shake128_squeeze_block___2size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[2U][168U]) { + uint8_t out[2U][168U] = {{0U}}; + uint8_t dummy_out0[168U] = {0U}; + uint8_t dummy_out1[168U] = {0U}; + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], + Eurydice_slice), + (size_t)1U, uint8_t[168U], + K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____1 = self; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice( + (size_t)168U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], + uint8_t[168U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); +} + +static inline bool +sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uint8_t randomness[2U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + ((core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + ((core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( + int16_t s[272U]) { + return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uint8_t seeds[2U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + size_t sampled_coefficients[2U] = {0U}; + int16_t out[2U][272U] = {{0U}}; + uint8_t uu____0[2U][34U]; + memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + shake128_init_absorb___2size_t(uu____0); + uint8_t randomness0[2U][504U]; + shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); + uint8_t uu____1[2U][504U]; + memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); + bool done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[2U][168U]; + shake128_squeeze_block___2size_t(&xof_state, randomness); + uint8_t uu____2[2U][168U]; + memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); + done = + sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[2U][272U]; + memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + ret0[i] = + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t0( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U][2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + A_transpose[i]);); + KRML_MAYBE_FOR2( + i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[2U][34U]; + memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[2U]; + sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U])); +} + +typedef struct + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[2U]; + uint8_t snd; +} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t; + +static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], + uint8_t ret[2U][192U]) { + uint8_t out[2U][192U] = {{0U}}; + uint8_t dummy_out0[192U] = {0U}; + uint8_t dummy_out1[192U] = {0U}; + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], + Eurydice_slice), + (size_t)1U, uint8_t[192U], + K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)192U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], + uint8_t[192U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + re_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][192U]; + PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[2U]; + memcpy( + uu____2, re_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void +add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1], &product); + } + add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static K___uint8_t_768size_t__uint8_t_800size_t_ +generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + G___2size_t(key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + uint8_t ret[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____2 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[2U]; + memcpy( + error_as_ntt, + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____3, domain_separator) + .fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U]; + compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[2U]; + memcpy( + uu____4, t_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[800U]; + serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_800size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[2U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[768U]; + serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[768U]; + memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); + uint8_t uu____7[800U]; + memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); + K___uint8_t_768size_t__uint8_t_800size_t_ lit; + memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); + return lit; +} + +static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____0, + ((core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____3, + ((core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)1632U, out, + ((core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + H___2size_t(public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1632U, uu____7, + ((core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); +} + +libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[768U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); + uint8_t public_key[800U]; + memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[1632U]; + serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t( + uu____1, + Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[1632U]; + memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; + uint8_t uu____4[800U]; + memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( + uu____4)); +} + +static inline void +deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + deserialized_pk[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], + uint8_t ret[2U][128U]) { + uint8_t out[2U][128U] = {{0U}}; + uint8_t dummy_out0[128U] = {0U}; + uint8_t dummy_out1[128U] = {0U}; + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ + uu____0 = core_slice___Slice_T___split_at_mut( + Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], + Eurydice_slice), + (size_t)1U, uint8_t[128U], + K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); + Eurydice_slice out0 = uu____0.fst; + Eurydice_slice out1 = uu____0.snd; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = Eurydice_array_to_slice( + (size_t)128U, + Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], + uint8_t[128U]), + uint8_t, Eurydice_slice); + Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, + uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, + Eurydice_slice)); + memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); +} + +static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t +sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + error_1[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[2U][33U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[2U][128U]; + PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[2U]; + memcpy( + uu____2, error_1, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +static inline void PRF___2size_t_128size_t(Eurydice_slice input, + uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static inline void +invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector(&zeta_i, re); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(re); +} + +static inline void +compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[2U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + result[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [2U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1], &product); + } + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result[i1]); + add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(&result[i1], + &error_1[i1]); + } + memcpy( + ret, result, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result); + result = add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +static void +compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[2U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)2U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + ((core_ops_range_Range__size_t){ + .start = i0 * ((size_t)640U / (size_t)2U), + .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static void +encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[768U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[2U]; + deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768size_t_2size_t( + Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[2U][2U]; + uint8_t ret0[34U]; + libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____1 = + sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_3size_t_192size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[2U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t + uu____3 = + sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[2U]; + memcpy( + error_1, uu____3.fst, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + PRF___2size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[2U]; + compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[768U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[2U]; + memcpy( + uu____5, u, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)640U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); +} + +K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + H___2size_t( + Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)800U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[768U]; + memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static inline void +deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + u_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)768U, ciphertext, + ((core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline void +deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[2U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, + secret_as_ntt[i] = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + ((core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)2U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR2( + i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result, &product);); + invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &result); + result = subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector(v, result); + return result; +} + +static void +decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[2U]; + deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)768U, ciphertext, + (size_t)640U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[2U]; + deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void PRF___2size_t_32size_t(Eurydice_slice input, + uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( + libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, + libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, + uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)768U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)800U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + G___2size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[800U]; + libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + PRF___2size_t_32size_t( + Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[768U]; + encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( + uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h new file mode 100644 index 000000000..5ae63072a --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -0,0 +1,294 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 + */ + +#ifndef __libcrux_mlkem_avx2_H +#define __libcrux_mlkem_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem_portable.h" +#include "libcrux_sha3.h" +#include "libcrux_sha3_avx2.h" + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( + void); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_slice array); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice array); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + core_core_arch_x86___m256i v, int16_t c); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + core_core_arch_x86___m256i vector); + +#define LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER \ + ((int16_t)20159) + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + core_core_arch_x86___m256i vector); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + core_core_arch_x86___m256i v, core_core_arch_x86___m256i c); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m128i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + core_core_arch_x86___m128i v, core_core_arch_x86___m128i c); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + core_core_arch_x86___m256i v); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_ntt_ntt_multiply( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_1( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_4( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_5( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_10( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_to_i16_array(core_core_arch_x86___m256i v, + int16_t ret[16U]); + +typedef struct libcrux_ml_kem_vector_avx2_portable_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_avx2_portable_PortableVector; + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]); + +void libcrux_ml_kem_vector_avx2_portable_serialize_11( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_zero(void); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_portable_to_i16_array( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_11( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + Eurydice_slice bytes); + +void libcrux_ml_kem_vector_avx2_serialize_serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]); + +void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]); + +core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_12( + Eurydice_slice bytes); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + Eurydice_slice bytes); + +size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( + Eurydice_slice input, Eurydice_slice output); + +size_t +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + Eurydice_slice input, Eurydice_slice output); + +libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( + libcrux_ml_kem_vector_avx2_portable_PortableVector *self); + +core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( + core_core_arch_x86___m256i *self); + +typedef struct + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 876d3b5bb..30688d413 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" @@ -44,6 +44,521 @@ const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = { (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; +const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE + [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, + 255U, 255U, 255U}, + {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 255U, 255U}, + {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, + 15U, 255U, 255U}, + {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 14U, 15U}}; + inline libcrux_ml_kem_vector_portable_PortableVector libcrux_ml_kem_vector_zero( void) { libcrux_ml_kem_vector_portable_PortableVector lit; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index c2a28afa5..078c0cbd3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H @@ -27,6 +27,10 @@ extern "C" { #define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ (62209U) +extern const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[256U] + [16U]; + typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { int16_t elements[16U]; } libcrux_ml_kem_vector_portable_PortableVector; diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h index 13d7131d4..988a2e7f2 100644 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ b/libcrux-ml-kem/c/libcrux_platform.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_platform_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index f143434fa..87bfd1a1a 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 08549e08a..49e0302b8 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,111 +1,2028 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ -#include "libcrux_sha3_avx2.h" +#include "internal/libcrux_sha3_avx2.h" #include "internal/libcrux_core.h" -inline void libcrux_sha3_avx2_x4_shake256( - Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice input2, - Eurydice_slice input3, Eurydice_slice out0, Eurydice_slice out1, - Eurydice_slice out2, Eurydice_slice out3) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; +static inline core_core_arch_x86___m256i zero(void) { + return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); +} + +static inline core_core_arch_x86___m256i _veor5q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); + core_core_arch_x86___m256i abcd = + libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); + return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); +} + +static inline core_core_arch_x86___m256i xor5(core_core_arch_x86___m256i a, + core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, + core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + return _veor5q_u64(a, b, c, d, e); +} + +static inline core_core_arch_x86___m256i rotate_left___1int32_t_63int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)1, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)63, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vrax1q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, rotate_left___1int32_t_63int32_t(b)); +} + +static inline core_core_arch_x86___m256i rotate_left1_and_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vrax1q_u64(a, b); +} + +static inline core_core_arch_x86___m256i _vbcaxq_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); +} + +static inline core_core_arch_x86___m256i and_not_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + return _vbcaxq_u64(a, b, c); +} + +static inline core_core_arch_x86___m256i _veorq_n_u64( + core_core_arch_x86___m256i a, uint64_t c) { + core_core_arch_x86___m256i c0 = + libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); + return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); +} + +static inline core_core_arch_x86___m256i xor_constant( + core_core_arch_x86___m256i a, uint64_t c) { + return _veorq_n_u64(a, c); +} + +static inline core_core_arch_x86___m256i xor0(core_core_arch_x86___m256i a, + core_core_arch_x86___m256i b) { + return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); +} + +static inline void slice_4(Eurydice_slice a[4U], size_t start, size_t len, + Eurydice_slice ret[4U]) { + Eurydice_slice uu____0 = Eurydice_slice_subslice( + a[0U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + a[1U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + a[2U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[0U] = uu____0; + ret[1U] = uu____1; + ret[2U] = uu____2; + ret[3U] = Eurydice_slice_subslice( + a[3U], + ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); +} + +static inline void slice_n(Eurydice_slice a[4U], size_t start, size_t len, + Eurydice_slice ret[4U]) { + Eurydice_slice uu____0[4U]; + memcpy(uu____0, a, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[4U]; + slice_4(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +split_at_mut_4(Eurydice_slice out[4U], size_t mid) { + Eurydice_slice out0 = out[0U]; + Eurydice_slice out1 = out[1U]; + Eurydice_slice out2 = out[2U]; + Eurydice_slice out3 = out[3U]; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out0, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at_mut( + out1, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out10 = uu____1.fst; + Eurydice_slice out11 = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at_mut( + out2, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out20 = uu____2.fst; + Eurydice_slice out21 = uu____2.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at_mut( + out3, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out30 = uu____3.fst; + Eurydice_slice out31 = uu____3.snd; + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; + lit.fst[0U] = out00; + lit.fst[1U] = out10; + lit.fst[2U] = out20; + lit.fst[3U] = out30; + lit.snd[0U] = out01; + lit.snd[1U] = out11; + lit.snd[2U] = out21; + lit.snd[3U] = out31; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +split_at_mut_n(Eurydice_slice a[4U], size_t mid) { + return split_at_mut_4(a, mid); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +new__core_core_arch_x86___m256i_4size_t(void) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + lit; + lit.st[0U][0U] = zero(); + lit.st[0U][1U] = zero(); + lit.st[0U][2U] = zero(); + lit.st[0U][3U] = zero(); + lit.st[0U][4U] = zero(); + lit.st[1U][0U] = zero(); + lit.st[1U][1U] = zero(); + lit.st[1U][2U] = zero(); + lit.st[1U][3U] = zero(); + lit.st[1U][4U] = zero(); + lit.st[2U][0U] = zero(); + lit.st[2U][1U] = zero(); + lit.st[2U][2U] = zero(); + lit.st[2U][3U] = zero(); + lit.st[2U][4U] = zero(); + lit.st[3U][0U] = zero(); + lit.st[3U][1U] = zero(); + lit.st[3U][2U] = zero(); + lit.st[3U][3U] = zero(); + lit.st[3U][4U] = zero(); + lit.st[4U][0U] = zero(); + lit.st[4U][1U] = zero(); + lit.st[4U][2U] = zero(); + lit.st[4U][3U] = zero(); + lit.st[4U][4U] = zero(); + return lit; +} + +static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +static inline void load_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, b, (size_t)4U * sizeof(Eurydice_slice)); + load_block___136size_t(uu____0, uu____1); +} + +static inline core_core_arch_x86___m256i rotate_left___36int32_t_28int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___36int32_t_28int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___3int32_t_61int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___3int32_t_61int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___41int32_t_23int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)41, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)23, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___41int32_t_23int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___18int32_t_46int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)18, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)46, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___18int32_t_46int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___1int32_t_63int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___44int32_t_20int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___44int32_t_20int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___10int32_t_54int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)10, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)54, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___10int32_t_54int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___45int32_t_19int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)45, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)19, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___45int32_t_19int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___2int32_t_62int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___2int32_t_62int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___62int32_t_2int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___62int32_t_2int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___6int32_t_58int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)6, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)58, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___6int32_t_58int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___43int32_t_21int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___43int32_t_21int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___15int32_t_49int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)15, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)49, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___15int32_t_49int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___61int32_t_3int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___61int32_t_3int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___28int32_t_36int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___28int32_t_36int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___55int32_t_9int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)55, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)9, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___55int32_t_9int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___25int32_t_39int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___25int32_t_39int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___21int32_t_43int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___21int32_t_43int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___56int32_t_8int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___56int32_t_8int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___27int32_t_37int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)27, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)37, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___27int32_t_37int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___20int32_t_44int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___20int32_t_44int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___39int32_t_25int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___39int32_t_25int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___8int32_t_56int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___8int32_t_56int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline core_core_arch_x86___m256i rotate_left___14int32_t_50int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)14, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)50, x, core_core_arch_x86___m256i)); +} + +static inline core_core_arch_x86___m256i _vxarq_u64___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return rotate_left___14int32_t_50int32_t(ab); +} + +static inline core_core_arch_x86___m256i xor_and_rotate___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return _vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void theta_rho__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i uu____0 = + xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + core_core_arch_x86___m256i uu____1 = + xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + core_core_arch_x86___m256i uu____2 = + xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + core_core_arch_x86___m256i uu____3 = + xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + core_core_arch_x86___m256i c[5U] = { + uu____0, uu____1, uu____2, uu____3, + xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + core_core_arch_x86___m256i uu____4 = + rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____5 = + rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____6 = + rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____7 = + rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i t[5U] = { + uu____4, uu____5, uu____6, uu____7, + rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + core_core_arch_x86___m256i uu____8 = xor0(s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + core_core_arch_x86___m256i uu____9 = + xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + core_core_arch_x86___m256i uu____10 = + xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + core_core_arch_x86___m256i uu____11 = + xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + core_core_arch_x86___m256i uu____12 = + xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + core_core_arch_x86___m256i uu____13 = + xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + core_core_arch_x86___m256i uu____14 = + xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + core_core_arch_x86___m256i uu____15 = + xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + core_core_arch_x86___m256i uu____16 = + xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + core_core_arch_x86___m256i uu____17 = + xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + core_core_arch_x86___m256i uu____18 = + xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + core_core_arch_x86___m256i uu____19 = + xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + core_core_arch_x86___m256i uu____20 = + xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + core_core_arch_x86___m256i uu____21 = + xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + core_core_arch_x86___m256i uu____22 = + xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + core_core_arch_x86___m256i uu____23 = + xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + core_core_arch_x86___m256i uu____24 = + xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + core_core_arch_x86___m256i uu____25 = + xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + core_core_arch_x86___m256i uu____26 = + xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + core_core_arch_x86___m256i uu____27 = + xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + core_core_arch_x86___m256i uu____28 = + xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + core_core_arch_x86___m256i uu____29 = + xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + core_core_arch_x86___m256i uu____30 = + xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + core_core_arch_x86___m256i uu____31 = + xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + core_core_arch_x86___m256i uu____32 = + xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void pi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, core_core_arch_x86___m256i[5U], void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void chi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(core_core_arch_x86___m256i[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; + KRML_MAYBE_FOR5(i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + core_core_arch_x86___m256i uu____0 = and_not_xor( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void iota__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + size_t i) { + core_core_arch_x86___m256i uu____0 = xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void keccakf1600__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + theta_rho__core_core_arch_x86___m256i_4size_t(s); + pi__core_core_arch_x86___m256i_4size_t(s); + chi__core_core_arch_x86___m256i_4size_t(s); + iota__core_core_arch_x86___m256i_4size_t(s, i0); + } +} + +static inline void absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice blocks[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, blocks, (size_t)4U * sizeof(Eurydice_slice)); + load_block___136size_t0(uu____0, uu____1); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +static inline void load_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + load_block___136size_t(uu____0, buf); +} + +static inline void load_block_full___136size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___136size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline libcrux_sha3_avx2_x4_incremental_KeccakState4 + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t ret[4U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + uint8_t out2[200U] = {0U}; + uint8_t out3[200U] = {0U}; + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = { + uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, out3, uint8_t, Eurydice_slice)}; + store_block___136size_t(uu____0, buf); + uint8_t uu____4[200U]; + memcpy(uu____4, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____5[200U]; + memcpy(uu____5, out1, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____6[200U]; + memcpy(uu____6, out2, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____7[200U]; + memcpy(uu____7, out3, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____4, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____5, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[2U], uu____6, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[3U], uu____7, (size_t)200U * sizeof(uint8_t)); +} + +static inline void store_block_full___136size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t ret[4U][200U]) { + uint8_t ret0[4U][200U]; + store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(uint8_t[200U])); +} + +static inline void +squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + uint8_t b[4U][200U]; + store_block_full___136size_t0(s->st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void store_block___136size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + store_block___136size_t(a, b); +} + +static inline void +squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + store_block___136size_t0(s->st, out); +} + +static inline void +squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(s); + store_block___136size_t0(s->st, out); +} + +static inline void squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(&s); + uint8_t b[4U][200U]; + store_block_full___136size_t0(s.st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +static inline void +keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + Eurydice_slice data[4U], Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + s = new__core_core_arch_x86___m256i_4size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &s; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); + absorb_block__core_core_arch_x86___m256i_4size_t_136size_t(uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = &s; + Eurydice_slice uu____3[4U]; + memcpy(uu____3, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, + rem, ret); + absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(uu____2, + ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t(&s, + out); + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ + uu____4 = split_at_mut_n(out, (size_t)136U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____4.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o1[4U]; + memcpy(o1, uu____4.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + ((core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ + uu____5 = split_at_mut_n(o1, (size_t)136U); + Eurydice_slice o[4U]; + memcpy(o, uu____5.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice orest[4U]; + memcpy(orest, uu____5.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o); + memcpy(o1, orest, (size_t)4U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t(s, o1); + } + } +} + +void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, + Eurydice_slice input2, Eurydice_slice input3, + Eurydice_slice out0, Eurydice_slice out1, + Eurydice_slice out2, Eurydice_slice out3) { + Eurydice_slice buf0[4U] = {input0, input1, input2, input3}; + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t(buf0, buf); +} + +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t libcrux_sha3_avx2_x4_incremental_shake128_init(void) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice data0, - Eurydice_slice data1, Eurydice_slice data2, Eurydice_slice data3) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -inline void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, - Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); + return new__core_core_arch_x86___m256i_4size_t(); +} + +static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + ((core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +static inline void load_block_full___168size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + load_block___168size_t(uu____0, buf); +} + +static inline void load_block_full___168size_t0( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___168size_t(uu____0, uu____1); } inline void -libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, - Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; +libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + ((core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + load_block_full___168size_t0(uu____1, uu____2); + keccakf1600__core_core_arch_x86___m256i_4size_t(s); +} + +void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, + Eurydice_slice data3) { + Eurydice_slice buf[4U] = {data0, data1, data2, data3}; + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + s, buf); +} + +static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], + Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + ((core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + ((core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + ((core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + ((core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + ((core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void store_block___168size_t0(core_core_arch_x86___m256i (*a)[5U], + Eurydice_slice b[4U]) { + store_block___168size_t(a, b); +} + +static inline void +squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + keccakf1600__core_core_arch_x86___m256i_4size_t(s); + store_block___168size_t0(s->st, out); +} + +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, buf); +} + +static inline void +squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + store_block___168size_t0(s->st, out); +} + +inline void +libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____0 = + split_at_mut_n(out, (size_t)168U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____0.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o10[4U]; + memcpy(o10, uu____0.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o0); + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____1 = + split_at_mut_n(o10, (size_t)168U); + Eurydice_slice o1[4U]; + memcpy(o1, uu____1.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o2[4U]; + memcpy(o2, uu____1.snd, (size_t)4U * sizeof(Eurydice_slice)); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o1); + squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t(s, o2); +} + +void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + s, buf); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 7fbdbc8a2..2f9e86a7b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H @@ -15,32 +15,38 @@ extern "C" { #include "eurydice_glue.h" #include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_core.h" -#include "libcrux_sha3_neon.h" +#include "libcrux_sha3_internal.h" + +typedef struct + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { + core_core_arch_x86___m256i st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; void libcrux_sha3_avx2_x4_shake256(Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice input2, Eurydice_slice input3, Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); -typedef struct libcrux_sha3_avx2_x4_incremental_KeccakState4_s { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U]; -} libcrux_sha3_avx2_x4_incremental_KeccakState4; - -libcrux_sha3_avx2_x4_incremental_KeccakState4 +libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t libcrux_sha3_avx2_x4_incremental_shake128_init(void); void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice data0, - Eurydice_slice data1, Eurydice_slice data2, Eurydice_slice data3); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, + Eurydice_slice data3); void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, - Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3); void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_avx2_x4_incremental_KeccakState4 *s, Eurydice_slice out0, - Eurydice_slice out1, Eurydice_slice out2, Eurydice_slice out3); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3); #if defined(__cplusplus) } diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 9428aa94d..e796057eb 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H From bac336ba8eeb7764b8d9968048aa362f25a2c7d5 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 11:33:21 +0200 Subject: [PATCH 37/84] don't always clean in c.sh --- libcrux-ml-kem/c.sh | 16 +++++++++++----- libcrux-ml-kem/c/profile-macos.sh | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100755 libcrux-ml-kem/c/profile-macos.sh diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index 1017995a1..7edb43093 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -15,6 +15,7 @@ fi portable_only=0 no_hacl=0 no_charon=0 +clean=0 # Parse command line arguments. all_args=("$@") @@ -23,6 +24,7 @@ while [ $# -gt 0 ]; do -p | --portable) portable_only=1 ;; --no-hacl) no_hacl=1 ;; --no-charon) no_charon=1 ;; + -c | --clean) clean=1 ;; esac shift done @@ -39,7 +41,7 @@ if [[ "$no_charon" = 0 ]]; then (cd ../libcrux-sha3 && RUSTFLAGS="--cfg eurydice" $CHARON_HOME/bin/charon --errors-as-warnings) if ! [[ -f ../libcrux_sha3.llbc ]]; then echo "😱😱😱 You are the victim of this bug: https://hacspec.zulipchat.com/#narrow/stream/433829-Circus/topic/charon.20declines.20to.20generate.20an.20llbc.20file" - echo "Suggestion: rm -rf ../target" + echo "Suggestion: rm -rf ../target or cargo clean" exit 1 fi echo "Running charon (ml-kem) ..." @@ -51,10 +53,14 @@ fi mkdir -p c cd c -rm -rf *.c *.h -# HAND_WRITTEN FILE -git checkout libcrux_platform.c -rm -rf internal/*.h +# Clean only when requesting it. +# Note that we can not extract for all platforms on any platform right now. +# Make sure to keep files from other platforms. +if [[ "$clean" = 1 ]]; then + rm -rf *.c *.h + rm -rf internal/*.h +fi + echo "Running eurydice ..." $EURYDICE_HOME/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc cp $EURYDICE_HOME/include/eurydice_glue.h . diff --git a/libcrux-ml-kem/c/profile-macos.sh b/libcrux-ml-kem/c/profile-macos.sh new file mode 100755 index 000000000..3e1c52415 --- /dev/null +++ b/libcrux-ml-kem/c/profile-macos.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +if [ "$#" -lt 1 ] +then + echo "Usage $0 [arguments...]" 1>&2 + exit 1 +fi + +PROGRAM="$(realpath "$1")" +shift + +OUTPUT="/tmp/cpu_profile_$(whoami)_$(basename "$PROGRAM").trace" +echo "Profiling $PROGRAM into $OUTPUT" 1>&2 +# Delete potential previous traces +rm -rf "$OUTPUT" +xcrun xctrace record \ + --template 'CPU Profiler' \ + --no-prompt \ + --output "$OUTPUT" \ + --target-stdout - \ + --launch -- "$PROGRAM" "$@" +open "$OUTPUT" From 77dad6a336d92d561a56f93c173268fa782a361f Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 11:33:47 +0200 Subject: [PATCH 38/84] drop unused platform files --- libcrux-ml-kem/c/libcrux_platform.c | 13 ------------- libcrux-ml-kem/c/libcrux_platform.h | 26 -------------------------- 2 files changed, 39 deletions(-) delete mode 100644 libcrux-ml-kem/c/libcrux_platform.c delete mode 100644 libcrux-ml-kem/c/libcrux_platform.h diff --git a/libcrux-ml-kem/c/libcrux_platform.c b/libcrux-ml-kem/c/libcrux_platform.c deleted file mode 100644 index d3ad8da95..000000000 --- a/libcrux-ml-kem/c/libcrux_platform.c +++ /dev/null @@ -1,13 +0,0 @@ -// HAND-WRITTEN FILE - -#include - -bool libcrux_platform_platform_simd128_support(void) { - // TODO: query cpuid and cache the results!! - return true; -} - -bool libcrux_platform_platform_simd256_support(void) { - // TODO: query cpuid and cache the results!! - return true; -} diff --git a/libcrux-ml-kem/c/libcrux_platform.h b/libcrux-ml-kem/c/libcrux_platform.h deleted file mode 100644 index 988a2e7f2..000000000 --- a/libcrux-ml-kem/c/libcrux_platform.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 - */ - -#ifndef __libcrux_platform_H -#define __libcrux_platform_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" - -extern bool libcrux_platform_platform_simd256_support(void); - -extern bool libcrux_platform_platform_simd128_support(void); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_platform_H_DEFINED -#endif From b3a1293210d523df60544ebe095ca7c1024a6689 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 11:39:14 +0200 Subject: [PATCH 39/84] run C mlkem on ci --- .github/workflows/c.yml | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/c.yml diff --git a/.github/workflows/c.yml b/.github/workflows/c.yml new file mode 100644 index 000000000..9233265e0 --- /dev/null +++ b/.github/workflows/c.yml @@ -0,0 +1,50 @@ +name: Build & Test C + +on: + push: + branches: ["main", "dev"] + pull_request: + branches: ["main", "dev"] + workflow_dispatch: + merge_group: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + strategy: + fail-fast: false + matrix: + bits: [32, 64] + os: + - macos-latest + - ubuntu-latest + - windows-latest + exclude: + - bits: 32 + os: "macos-latest" + + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + working-directory: libcrux-ml-kem/c + + steps: + - uses: actions/checkout@v4 + + - name: 🔨 Build + run: | + cmake -B build -G "Ninja Multi-Config" + cmake --build build + + - name: 🏃🏻‍♀️ Test + run: ./build/Debug/ml_kem_test + + - name: 🔨 Build Release + run: cmake --build build --config Release + + - name: 🏃🏻‍♀️ Benchmark + run: ./build/Release/ml_kem_bench From f6fb4860bf607efc324be1e67101c4a7f18a1685 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 11:52:29 +0200 Subject: [PATCH 40/84] don't use ninja on ci for now --- .github/workflows/c.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/c.yml b/.github/workflows/c.yml index 9233265e0..a4137eeef 100644 --- a/.github/workflows/c.yml +++ b/.github/workflows/c.yml @@ -17,14 +17,10 @@ jobs: strategy: fail-fast: false matrix: - bits: [32, 64] os: - macos-latest - ubuntu-latest - windows-latest - exclude: - - bits: 32 - os: "macos-latest" runs-on: ${{ matrix.os }} defaults: @@ -37,14 +33,16 @@ jobs: - name: 🔨 Build run: | - cmake -B build -G "Ninja Multi-Config" + cmake -B build cmake --build build - name: 🏃🏻‍♀️ Test run: ./build/Debug/ml_kem_test - name: 🔨 Build Release - run: cmake --build build --config Release + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build --config Release - name: 🏃🏻‍♀️ Benchmark run: ./build/Release/ml_kem_bench From 7829dd11ba7cd8f1255c3296d18fc7767940cc5b Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 12:51:49 +0200 Subject: [PATCH 41/84] fixup windows --- libcrux-ml-kem/c/CMakeLists.txt | 43 ++++++++-------- libcrux-ml-kem/c/benches/mlkem768.cc | 56 ++++++++++++++++++++- libcrux-ml-kem/c/benches/mlkem768_encaps.cc | 1 - libcrux-ml-kem/c/benches/mlkem768_keygen.cc | 1 - libcrux-ml-kem/c/eurydice_glue.h | 20 +++++--- libcrux-ml-kem/c/internal/libcrux_core.h | 3 -- libcrux-ml-kem/c/libcrux_sha3_internal.h | 46 ++++++++--------- 7 files changed, 113 insertions(+), 57 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index b8f4f983f..017924161 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -11,21 +11,22 @@ project(libcrux-ml-kem ) set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) -# FIXME: Windows? -add_compile_options( - -Wall - - # -Wextra - # -pedantic - # -Wconversion - # -Wsign-conversion - $<$:-g> - $<$:-Og> - $<$:-g> - $<$:-O3> -) +if(NOT MSVC) + # TODO: Clean up + add_compile_options( + -Wall + # -Wextra + # -pedantic + # -Wconversion + # -Wsign-conversion + $<$:-g> + $<$:-Og> + $<$:-g> + $<$:-O3> + ) +endif(NOT MSVC) set(CMAKE_COLOR_DIAGNOSTICS "ON") include_directories( @@ -78,14 +79,16 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) target_sources(ml_kem_static PRIVATE $) target_sources(ml_kem PRIVATE $) - target_compile_options(ml_kem_vec256 PRIVATE - -mavx - -mavx2 - ) + if(NOT MSVC) + target_compile_options(ml_kem_vec256 PRIVATE + -mavx + -mavx2 + ) + endif(NOT MSVC) endif() # This is only for local testing and we assume neon on arm64. -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8") +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED $ENV{LIBCRUX_NEON}) message(STATUS "Detected an arm64 architecture") add_compile_definitions(LIBCRUX_AARCH64) @@ -179,5 +182,3 @@ target_link_libraries(sha3_bench PRIVATE ml_kem_static benchmark::benchmark ) -target_compile_definitions(sha3_bench PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(sha3_bench PRIVATE) diff --git a/libcrux-ml-kem/c/benches/mlkem768.cc b/libcrux-ml-kem/c/benches/mlkem768.cc index c88c747f4..5d9160fea 100644 --- a/libcrux-ml-kem/c/benches/mlkem768.cc +++ b/libcrux-ml-kem/c/benches/mlkem768.cc @@ -8,7 +8,6 @@ #include -#include "libcrux_sha3.h" #include "libcrux_mlkem768.h" #include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" @@ -125,4 +124,59 @@ BENCHMARK(kyber768_encapsulation_neon); BENCHMARK(kyber768_decapsulation_neon); #endif +#ifdef LIBCRUX_X64 +#include "libcrux_mlkem768_avx2.h" + +static void +kyber768_key_generation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + for (auto _ : state) + { + key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + } +} + +static void +kyber768_encapsulation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + for (auto _ : state) + { + ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + } +} + +static void +kyber768_decapsulation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + + for (auto _ : state) + { + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + } +} + +BENCHMARK(kyber768_key_generation_avx2); +BENCHMARK(kyber768_encapsulation_avx2); +BENCHMARK(kyber768_decapsulation_avx2); +#endif + BENCHMARK_MAIN(); diff --git a/libcrux-ml-kem/c/benches/mlkem768_encaps.cc b/libcrux-ml-kem/c/benches/mlkem768_encaps.cc index 4831e07eb..d7c2a5076 100644 --- a/libcrux-ml-kem/c/benches/mlkem768_encaps.cc +++ b/libcrux-ml-kem/c/benches/mlkem768_encaps.cc @@ -8,7 +8,6 @@ #include -#include "libcrux_sha3.h" #include "libcrux_mlkem768.h" #include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/benches/mlkem768_keygen.cc b/libcrux-ml-kem/c/benches/mlkem768_keygen.cc index fd3432f93..a7271277f 100644 --- a/libcrux-ml-kem/c/benches/mlkem768_keygen.cc +++ b/libcrux-ml-kem/c/benches/mlkem768_keygen.cc @@ -8,7 +8,6 @@ #include -#include "libcrux_sha3.h" #include "libcrux_mlkem768.h" #include "libcrux_mlkem768_portable.h" #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index d9e6cec67..edfffa601 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -21,6 +21,12 @@ extern "C" { // SLICES, ARRAYS, ETC. +#if defined(__cplusplus) + #define CLITERAL(type) type +#else + #define CLITERAL(type) (type) +#endif + // We represent a slice as a pair of an (untyped) pointer, along with the length // of the slice, i.e. the number of elements in the slice (this is NOT the // number of bytes). This design choice has two important consequences. @@ -41,7 +47,7 @@ typedef struct { // cast to something that can decay (see remark above about how pointer // arithmetic works in C), meaning either pointer or array type. #define EURYDICE_SLICE(x, start, end) \ - ((Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) + (CLITERAL(Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) #define EURYDICE_SLICE_LEN(s, _) s.len // This macro is a pain because in case the dereferenced element type is an // array, you cannot simply write `t x` as it would yield `int[4] x` instead, @@ -83,10 +89,10 @@ typedef struct { Eurydice_array_eq #define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ - ((ret_t){.fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + (CLITERAL(ret_t){.fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) #define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ - ((ret_t){.fst = {.ptr = slice.ptr, .len = mid}, \ + (CLITERAL(ret_t){.fst = {.ptr = slice.ptr, .len = mid}, \ .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ .len = slice.len - mid}}) @@ -160,8 +166,8 @@ static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { #define core_num_nonzero_NonZeroUsize size_t #define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ (((iter_ptr)->start == (iter_ptr)->end) \ - ? ((ret_t){.tag = core_option_None}) \ - : ((ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) + ? (CLITERAL(ret_t){.tag = core_option_None}) \ + : (CLITERAL(ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) // Old name (TODO: remove once everyone has upgraded to the latest Charon) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ @@ -225,8 +231,8 @@ typedef struct { #define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, \ ret_t) \ (((iter)->index == (iter)->s.len) \ - ? ((ret_t){.tag = core_option_None}) \ - : ((ret_t){.tag = core_option_Some, \ + ? (CLITERAL(ret_t){.tag = core_option_None}) \ + : (CLITERAL(ret_t){.tag = core_option_Some, \ .f0 = ((iter)->index++, \ &((t *)((iter)->s.ptr))[(iter)->index - 1])})) diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 39db7b956..b826ad544 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -15,9 +15,6 @@ extern "C" { #include "../libcrux_core.h" #include "eurydice_glue.h" -extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( - core_fmt_rt_Argument x0[0U]); - extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( Eurydice_slice x0, Eurydice_slice x1); diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index e796057eb..360486d5e 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -112,7 +112,7 @@ static inline void libcrux_sha3_portable_keccak_slice_1( Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { ret[0U] = Eurydice_slice_subslice( a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, .end = start + len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); } @@ -218,7 +218,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___168size_t( &dst, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), Eurydice_slice, uint8_t[8U], void *); @@ -895,7 +895,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; @@ -916,7 +916,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___168size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; @@ -1086,7 +1086,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { @@ -1132,7 +1132,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___104size_t( &dst, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), Eurydice_slice, uint8_t[8U], void *); @@ -1193,7 +1193,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -1214,7 +1214,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___104size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; @@ -1363,7 +1363,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { @@ -1409,7 +1409,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___144size_t( &dst, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), Eurydice_slice, uint8_t[8U], void *); @@ -1470,7 +1470,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -1491,7 +1491,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___144size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; @@ -1640,7 +1640,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { @@ -1686,7 +1686,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___136size_t( &dst, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), Eurydice_slice, uint8_t[8U], void *); @@ -1747,7 +1747,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; @@ -1768,7 +1768,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___136size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; @@ -1917,7 +1917,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { @@ -1963,7 +1963,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -2025,7 +2025,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { @@ -2071,7 +2071,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___72size_t( &dst, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), Eurydice_slice, uint8_t[8U], void *); @@ -2132,7 +2132,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -2153,7 +2153,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___72size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; @@ -2302,7 +2302,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( &s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { From c851d5b614a0e8f34e84010fdca56caca5da11f7 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 13:13:19 +0200 Subject: [PATCH 42/84] more build fixes --- .github/workflows/c.yml | 12 ++++++++++++ libcrux-ml-kem/c/CMakeLists.txt | 18 +++++++++++------- libcrux-ml-kem/c/benches/sha3.cc | 16 +++++++--------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/.github/workflows/c.yml b/.github/workflows/c.yml index a4137eeef..b70951dfb 100644 --- a/.github/workflows/c.yml +++ b/.github/workflows/c.yml @@ -38,11 +38,23 @@ jobs: - name: 🏃🏻‍♀️ Test run: ./build/Debug/ml_kem_test + if: ${{ matrix.os == 'windows-latest' }} + + - name: 🏃🏻‍♀️ Test + run: ./build/ml_kem_test + if: ${{ matrix.os != 'windows-latest' }} - name: 🔨 Build Release run: | + rm -rf build cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release - name: 🏃🏻‍♀️ Benchmark run: ./build/Release/ml_kem_bench + if: ${{ matrix.os == 'windows-latest' }} + + - name: 🏃🏻‍♀️ Benchmark + run: ./build/ml_kem_bench + if: ${{ matrix.os != 'windows-latest' }} + diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 017924161..f74d91c71 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -175,10 +175,14 @@ target_link_libraries(ml_kem_encaps PRIVATE target_compile_definitions(ml_kem_encaps PUBLIC HACL_CAN_COMPILE_VEC256) target_compile_options(ml_kem_encaps PRIVATE) -add_executable(sha3_bench - ${PROJECT_SOURCE_DIR}/benches/sha3.cc -) -target_link_libraries(sha3_bench PRIVATE - ml_kem_static - benchmark::benchmark -) +if(NOT MSVC) + # We benchmark internal functions here that are inlined and thus not available + # in MSVC. + add_executable(sha3_bench + ${PROJECT_SOURCE_DIR}/benches/sha3.cc + ) + target_link_libraries(sha3_bench PRIVATE + ml_kem_static + benchmark::benchmark + ) +endif(NOT MSVC) diff --git a/libcrux-ml-kem/c/benches/sha3.cc b/libcrux-ml-kem/c/benches/sha3.cc index 9c5b88fb1..b2712feae 100644 --- a/libcrux-ml-kem/c/benches/sha3.cc +++ b/libcrux-ml-kem/c/benches/sha3.cc @@ -6,7 +6,6 @@ * - http://opensource.org/licenses/MIT */ - #include // TODO: FIXME: why is the macro definition in @@ -70,18 +69,17 @@ shake128_34_504(benchmark::State &state) uint8_t input[34]; generate_random(input, 34); - Eurydice_slice last[4] = {EURYDICE_SLICE(input,0,34),EURYDICE_SLICE(input,0,34),EURYDICE_SLICE(input,0,34),EURYDICE_SLICE(input,0,34)}; - Eurydice_slice out[4] = {EURYDICE_SLICE(digest0,0,504),EURYDICE_SLICE(digest1,0,504),EURYDICE_SLICE(digest2,0,504),EURYDICE_SLICE(digest3,0,504)}; - // libcrux_sha3_portable_sha256(EURYDICE_SLICE(input, 0, 32), EURYDICE_SLICE(digest, 0, 32)); + Eurydice_slice last[4] = {EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34)}; + Eurydice_slice out[4] = {EURYDICE_SLICE(digest0, 0, 504), EURYDICE_SLICE(digest1, 0, 504), EURYDICE_SLICE(digest2, 0, 504), EURYDICE_SLICE(digest3, 0, 504)}; libcrux_sha3_avx2_x4_incremental_KeccakState4 st = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st,last); - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st,out); + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st, last); + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st, out); for (auto _ : state) { - libcrux_sha3_avx2_x4_incremental_KeccakState4 st = libcrux_sha3_avx2_x4_incremental_shake128_init(); - libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st,last); - libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st,out); + libcrux_sha3_avx2_x4_incremental_KeccakState4 st = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st, last); + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st, out); } } From 51b0d8c697fe7e4edc8fb0f012a231d6ffdcd5c6 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Mon, 10 Jun 2024 16:48:51 +0200 Subject: [PATCH 43/84] nix: use `fetchFromGitHub` --- flake.nix | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 90b35d678..ff94c2893 100644 --- a/flake.nix +++ b/flake.nix @@ -24,12 +24,16 @@ system: let pkgs = import inputs.nixpkgs { inherit system; }; - googletest = pkgs.fetchzip { - url = "https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip"; + googletest = pkgs.fetchFromGitHub { + owner = "google"; + repo = "googletest"; + rev = "release-1.11.0"; sha256 = "SjlJxushfry13RGA7BCjYC9oZqV4z6x8dOiHfl/wpF0="; }; - json = pkgs.fetchzip { - url = "https://github.com/nlohmann/json/archive/refs/tags/v3.10.3.zip"; + json = pkgs.fetchFromGitHub { + owner = "nlohmann"; + repo = "json"; + rev = "v3.10.3"; sha256 = "EBzwaHyDWF8h/z3Zfq4p/n5Vpz7Ozlc3eoWDKXWv2YY="; }; craneLib = inputs.crane.mkLib pkgs; From a9bfdc984f834f1f27287e205c814b0e94e4b1b7 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Mon, 10 Jun 2024 18:09:47 +0200 Subject: [PATCH 44/84] fetch `benchmark` with `FetchContent` --- flake.nix | 8 +++++++- libcrux-ml-kem/c/CMakeLists.txt | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index ff94c2893..a694e47c0 100644 --- a/flake.nix +++ b/flake.nix @@ -30,6 +30,12 @@ rev = "release-1.11.0"; sha256 = "SjlJxushfry13RGA7BCjYC9oZqV4z6x8dOiHfl/wpF0="; }; + benchmark = pkgs.fetchFromGitHub { + owner = "google"; + repo = "benchmark"; + rev = "v1.8.4"; + sha256 = "O+1ZHaNHSkKz3PlKDyI94LqiLtjyrKxjOIi8Q236/MI="; + }; json = pkgs.fetchFromGitHub { owner = "nlohmann"; repo = "json"; @@ -45,7 +51,6 @@ nativeBuildInputs = [ pkgs.clang-tools pkgs.cmake - pkgs.gbenchmark pkgs.mold-wrapped pkgs.ninja pkgs.python3 @@ -56,6 +61,7 @@ cd c cmake \ -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ + -DFETCHCONTENT_SOURCE_DIR_BENCHMARK=${benchmark} \ -DFETCHCONTENT_SOURCE_DIR_JSON=${json} \ -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" \ -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" \ diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 25829913a..b464228e0 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -108,7 +108,11 @@ target_link_libraries(sha3_test PRIVATE # --- Benchmarks -find_package(benchmark) +FetchContent_Declare(benchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.8.4 +) +FetchContent_MakeAvailable(benchmark) add_executable(ml_kem_bench ${PROJECT_SOURCE_DIR}/benches/mlkem768.cc From 9418eef81ae38ed13952d2480c39ddfe4ba8f413 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Mon, 10 Jun 2024 10:30:57 -0700 Subject: [PATCH 45/84] Regenerate code with the C++ tweak --- libcrux-ml-kem/c.yaml | 2 +- libcrux-ml-kem/c/eurydice_glue.h | 28 +- libcrux-ml-kem/c/internal/libcrux_core.h | 9 +- .../c/internal/libcrux_mlkem_avx2.h | 6 +- .../c/internal/libcrux_mlkem_neon.h | 74 - .../c/internal/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 6 +- .../c/internal/libcrux_sha3_internal.h | 6 +- libcrux-ml-kem/c/libcrux_core.c | 26 +- libcrux-ml-kem/c/libcrux_core.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem1024_neon.c | 55 - libcrux-ml-kem/c/libcrux_mlkem1024_neon.h | 40 - libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem512_neon.c | 163 - libcrux-ml-kem/c/libcrux_mlkem512_neon.h | 89 - libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem768_neon.c | 54 - libcrux-ml-kem/c/libcrux_mlkem768_neon.h | 40 - libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 10 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 258 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_mlkem_neon.c | 7506 ----------------- libcrux-ml-kem/c/libcrux_mlkem_neon.h | 301 - libcrux-ml-kem/c/libcrux_mlkem_portable.c | 192 +- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 6 +- libcrux-ml-kem/c/libcrux_sha3.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 284 +- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 6 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 65 +- libcrux-ml-kem/c/libcrux_sha3_neon.c | 3032 +------ libcrux-ml-kem/c/libcrux_sha3_neon.h | 28 +- 43 files changed, 707 insertions(+), 11707 deletions(-) delete mode 100644 libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem1024_neon.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem512_neon.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem768_neon.h delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.c delete mode 100644 libcrux-ml-kem/c/libcrux_mlkem_neon.h diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 72fa642cd..205d9ea99 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -14,7 +14,7 @@ files: - [libcrux_intrinsics, avx2] - name: libcrux_platform - api: + private: - [libcrux_platform, "*"] # SHA3 (no mention of libcrux_mlkem in this section, please) diff --git a/libcrux-ml-kem/c/eurydice_glue.h b/libcrux-ml-kem/c/eurydice_glue.h index edfffa601..0e51e219d 100644 --- a/libcrux-ml-kem/c/eurydice_glue.h +++ b/libcrux-ml-kem/c/eurydice_glue.h @@ -22,9 +22,9 @@ extern "C" { // SLICES, ARRAYS, ETC. #if defined(__cplusplus) - #define CLITERAL(type) type +#define CLITERAL(type) type #else - #define CLITERAL(type) (type) +#define CLITERAL(type) (type) #endif // We represent a slice as a pair of an (untyped) pointer, along with the length @@ -89,12 +89,14 @@ typedef struct { Eurydice_array_eq #define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ - (CLITERAL(ret_t){.fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ - .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) + (CLITERAL(ret_t){ \ + .fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) #define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ - (CLITERAL(ret_t){.fst = {.ptr = slice.ptr, .len = mid}, \ - .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ - .len = slice.len - mid}}) + (CLITERAL(ret_t){ \ + .fst = {.ptr = slice.ptr, .len = mid}, \ + .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ + .len = slice.len - mid}}) // Conversion of slice to an array, rewritten (by Eurydice) to name the // destination array, since arrays are not values in C. @@ -166,8 +168,9 @@ static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { #define core_num_nonzero_NonZeroUsize size_t #define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ (((iter_ptr)->start == (iter_ptr)->end) \ - ? (CLITERAL(ret_t){.tag = core_option_None}) \ - : (CLITERAL(ret_t){.tag = core_option_Some, .f0 = (iter_ptr)->start++})) + ? (CLITERAL(ret_t){.tag = core_option_None}) \ + : (CLITERAL(ret_t){.tag = core_option_Some, \ + .f0 = (iter_ptr)->start++})) // Old name (TODO: remove once everyone has upgraded to the latest Charon) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \ @@ -232,9 +235,10 @@ typedef struct { ret_t) \ (((iter)->index == (iter)->s.len) \ ? (CLITERAL(ret_t){.tag = core_option_None}) \ - : (CLITERAL(ret_t){.tag = core_option_Some, \ - .f0 = ((iter)->index++, \ - &((t *)((iter)->s.ptr))[(iter)->index - 1])})) + : (CLITERAL(ret_t){ \ + .tag = core_option_Some, \ + .f0 = ((iter)->index++, \ + &((t *)((iter)->s.ptr))[(iter)->index - 1])})) // STRINGS diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index b826ad544..5ca28c79c 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_core_H @@ -15,6 +15,9 @@ extern "C" { #include "../libcrux_core.h" #include "eurydice_glue.h" +extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( + core_fmt_rt_Argument x0[0U]); + extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( Eurydice_slice x0, Eurydice_slice x1); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 10a2cb5a5..fcda100f7 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h deleted file mode 100644 index ab47ba59d..000000000 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_neon.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#ifndef __internal_libcrux_mlkem_neon_H -#define __internal_libcrux_mlkem_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "../libcrux_mlkem_neon.h" -#include "eurydice_glue.h" -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_portable.h" - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uint8_t *public_key); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -#if defined(__cplusplus) -} -#endif - -#define __internal_libcrux_mlkem_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 5773bba52..4fa834a92 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index 11ada5b26..405e13161 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index c897dae9f..32b53c527 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 3863ca9dc..518634a6f 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_core.h" @@ -50,7 +50,8 @@ libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( libcrux_ml_kem_types_MlKemPrivateKey____3168size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1568size_t pk) { - return ((libcrux_ml_kem_mlkem1024_MlKem1024KeyPair){.sk = sk, .pk = pk}); + return ( + CLITERAL(libcrux_ml_kem_mlkem1024_MlKem1024KeyPair){.sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____3168size_t @@ -108,7 +109,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1600U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -130,7 +131,8 @@ libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk) { - return ((libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); + return ( + CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); } libcrux_ml_kem_types_MlKemPrivateKey____2400size_t @@ -188,7 +190,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1120U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -210,7 +212,7 @@ libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( libcrux_ml_kem_types_MlKemPrivateKey____1632size_t sk, libcrux_ml_kem_types_MlKemPublicKey____800size_t pk) { - return ((libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ + return (CLITERAL(libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t){ .sk = sk, .pk = pk}); } @@ -262,7 +264,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)33U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -277,7 +279,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)34U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -299,7 +301,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)800U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -314,7 +316,7 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)64U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 52b97c825..6d6e8dcac 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 40b2e232a..1399bdf00 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index 9dbf4e203..e42d25b96 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024_avx2.h" @@ -43,11 +43,11 @@ libcrux_ml_kem_mlkem1024_avx2_validate_public_key( uu____0; if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___4size_t_1536size_t_1568size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index d3da0c00c..22172d3c4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c deleted file mode 100644 index 84791f55e..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem1024_neon.h" - -void libcrux_ml_kem_mlkem1024_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h b/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h deleted file mode 100644 index e68f4c51b..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_neon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#ifndef __libcrux_mlkem1024_neon_H -#define __libcrux_mlkem1024_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem512_neon.h" - -void libcrux_ml_kem_mlkem1024_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem1024_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_mlkem1024_neon_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__ -libcrux_ml_kem_mlkem1024_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem1024_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index b63311db9..66d7f407e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem1024_portable.h" @@ -43,11 +43,11 @@ libcrux_ml_kem_mlkem1024_portable_validate_public_key( uu____0; if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___4size_t_1536size_t_1568size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1568size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 2479e6391..5f38c1f52 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 5256458eb..8cdf081a1 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index 14cd4287a..c5d115c11 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512_avx2.h" @@ -80,11 +80,11 @@ libcrux_ml_kem_mlkem512_avx2_validate_public_key( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___2size_t_768size_t_800size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index 34801018a..28682ce54 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c b/libcrux-ml-kem/c/libcrux_mlkem512_neon.c deleted file mode 100644 index 2c021222d..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem512_neon.h" - -#include "internal/libcrux_mlkem_neon.h" - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_mlkem512_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____800size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uu____0); -} - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - public_key); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ - .tag = core_option_None}); - } - return uu____0; -} - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - public_key); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - public_key); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uu____0); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h b/libcrux-ml-kem/c/libcrux_mlkem512_neon.h deleted file mode 100644 index 0074c9469..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem512_neon.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#ifndef __libcrux_mlkem512_neon_H -#define __libcrux_mlkem512_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -void libcrux_ml_kem_mlkem512_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem512_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]); - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_mlkem512_neon_generate_key_pair(uint8_t randomness[64U]); - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___2size_t_768size_t_800size_t( - uint8_t *public_key); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ -libcrux_ml_kem_mlkem512_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____800size_t public_key); - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -bool libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___4size_t_1536size_t_1568size_t( - uint8_t *public_key); - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]); - -void libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem512_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 8a1a92703..2c66e4f9e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem512_portable.h" @@ -80,11 +80,11 @@ libcrux_ml_kem_mlkem512_portable_validate_public_key( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__ uu____0; if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___2size_t_768size_t_800size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___800size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 9ad10a424..ec949dc4d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index c69fb58ac..19cf733d3 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index 4497d2302..79ab93993 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768_avx2.h" @@ -42,11 +42,11 @@ libcrux_ml_kem_mlkem768_avx2_validate_public_key( uu____0; if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index 373792504..2354c986e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c b/libcrux-ml-kem/c/libcrux_mlkem768_neon.c deleted file mode 100644 index c2d9494e3..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#include "libcrux_mlkem768_neon.h" - -void libcrux_ml_kem_mlkem768_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cca_instantiations_neon_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - private_key, ciphertext, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; - uint8_t uu____1[32U]; - memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____0, uu____1); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]) { - uint8_t uu____0[64U]; - memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_neon_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uu____0); -} - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ - uu____0; - if (libcrux_ml_kem_ind_cca_instantiations_neon_validate_public_key___3size_t_1152size_t_1184size_t( - public_key.value)) { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_Some, .f0 = public_key}); - } else { - uu____0 = (( - core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ - .tag = core_option_None}); - } - return uu____0; -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h b/libcrux-ml-kem/c/libcrux_mlkem768_neon.h deleted file mode 100644 index 175e2827b..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem768_neon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#ifndef __libcrux_mlkem768_neon_H -#define __libcrux_mlkem768_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem512_neon.h" - -void libcrux_ml_kem_mlkem768_neon_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]); - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_mlkem768_neon_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]); - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_neon_generate_key_pair(uint8_t randomness[64U]); - -core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ -libcrux_ml_kem_mlkem768_neon_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key); - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem768_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 06ce4a50d..8bac4c0fe 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "libcrux_mlkem768_portable.h" @@ -42,11 +42,11 @@ libcrux_ml_kem_mlkem768_portable_validate_public_key( uu____0; if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( public_key.value)) { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ .tag = core_option_Some, .f0 = public_key}); } else { - uu____0 = (( + uu____0 = (CLITERAL( core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ .tag = core_option_None}); } diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index d7b8a5c6f..2e8dd612b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index 2cfe23c30..a4c6c077c 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_mlkem_avx2.h" @@ -674,7 +674,7 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( Eurydice_slice_to_array2( &dst, Eurydice_array_to_subslice((size_t)16U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -693,14 +693,6 @@ void libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { - core_core_arch_x86___m256i shift_lsbs_to_msbs = - libcrux_intrinsics_avx2_mm256_set_epi16( - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, - (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, - (int16_t)1 << 4U); int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, @@ -738,6 +730,14 @@ libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { uu____14, (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); core_core_arch_x86___m256i coefficients_in_msb = libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsbs_to_msbs); @@ -784,26 +784,26 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( core_core_arch_x86___m256i adjacent_8_combined0 = libcrux_intrinsics_avx2_mm256_sllv_epi32( uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, - (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)12)); core_core_arch_x86___m256i adjacent_8_combined1 = libcrux_intrinsics_avx2_mm256_srli_epi64( (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); core_core_arch_x86___m128i lower_8 = libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), lower_8); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)5U, .end = (size_t)21U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -813,7 +813,7 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( Eurydice_slice_to_array2( &dst, Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)10U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -937,19 +937,19 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); core_core_arch_x86___m128i lower_8 = libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); - core_core_arch_x86___m128i upper_8 = - libcrux_intrinsics_avx2_mm256_extracti128_si256( - (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), lower_8); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)10U, .end = (size_t)26U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -959,7 +959,7 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( Eurydice_slice_to_array2( &dst, Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -989,8 +989,8 @@ libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { core_core_arch_x86___m128i lower_coefficients = libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m128i uu____0 = lower_coefficients; core_core_arch_x86___m128i lower_coefficients0 = @@ -1001,8 +1001,8 @@ libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { core_core_arch_x86___m128i upper_coefficients = libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( bytes, - ((core_ops_range_Range__size_t){.start = (size_t)4U, - .end = (size_t)20U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)4U, + .end = (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m128i uu____1 = upper_coefficients; core_core_arch_x86___m128i upper_coefficients0 = @@ -1354,14 +1354,14 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), lower_8); libcrux_intrinsics_avx2_mm_storeu_bytes_si128( Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)12U, .end = (size_t)28U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -1371,7 +1371,7 @@ inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( Eurydice_slice_to_array2( &dst, Eurydice_array_to_subslice((size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -1401,8 +1401,8 @@ libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { core_core_arch_x86___m128i lower_coefficients = libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( bytes, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m128i uu____0 = lower_coefficients; core_core_arch_x86___m128i lower_coefficients0 = @@ -1413,8 +1413,8 @@ libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { core_core_arch_x86___m128i upper_coefficients = libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( bytes, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m128i uu____1 = upper_coefficients; core_core_arch_x86___m128i upper_coefficients0 = @@ -1493,8 +1493,8 @@ inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( libcrux_intrinsics_avx2_mm_storeu_si128( Eurydice_slice_subslice( output, - ((core_ops_range_Range__size_t){.start = sampled_count, - .end = sampled_count + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_count, .end = sampled_count + (size_t)8U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice), upper_coefficients0); size_t uu____0 = sampled_count; @@ -1570,8 +1570,8 @@ deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i coefficient = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( @@ -1601,7 +1601,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184 size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -1658,8 +1658,8 @@ serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, .end = (size_t)24U * i0 + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -1691,7 +1691,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1152U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -1715,8 +1715,8 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_ uint8_t public_key_serialized[1184U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1[3U]; @@ -1861,7 +1861,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -1870,7 +1870,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -1945,7 +1945,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -1954,7 +1954,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -1985,7 +1985,7 @@ from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector(Eurydice_slice a) { libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( Eurydice_slice_subslice( a, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (size_t)16U, .end = (i0 + (size_t)1U) * (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -1999,7 +1999,7 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -2172,7 +2172,7 @@ sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t chunk_number = i0; Eurydice_slice byte_chunk = Eurydice_slice_subslice( randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = chunk_number * (size_t)4U, .end = chunk_number * (size_t)4U + (size_t)4U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2220,7 +2220,7 @@ sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t chunk_number = i0; Eurydice_slice byte_chunk = Eurydice_slice_subslice( randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = chunk_number * (size_t)3U, .end = chunk_number * (size_t)3U + (size_t)3U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2310,7 +2310,7 @@ ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( a, &t); a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( a, &t); - return (( + return (CLITERAL( __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ .fst = a, .snd = b}); } @@ -2713,7 +2713,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -2726,7 +2726,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -2735,7 +2735,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)2400U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2752,7 +2752,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -2766,7 +2766,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2820,7 +2820,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152 size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -2957,7 +2957,7 @@ inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( a, &b)); b = montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( a_minus_b, zeta_r); - return (( + return (CLITERAL( __libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ .fst = a, .snd = b}); } @@ -3116,7 +3116,7 @@ deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( Eurydice_array_to_subslice( (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -3260,8 +3260,8 @@ compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -3365,7 +3365,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960s re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)960U / (size_t)3U), .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3457,8 +3457,8 @@ compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -3545,8 +3545,8 @@ compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( coefficients, bytes); Eurydice_slice uu____0 = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, .end = (size_t)10U * i0 + (size_t)10U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -3645,8 +3645,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)960U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; @@ -3792,8 +3792,8 @@ deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, .end = i0 * (size_t)20U + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i coefficient = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( @@ -3878,8 +3878,8 @@ deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, .end = i0 * (size_t)22U + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i coefficient = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( @@ -3942,7 +3942,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_ size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), @@ -4037,8 +4037,8 @@ deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, .end = i0 * (size_t)8U + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i coefficient = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( @@ -4122,8 +4122,8 @@ deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, .end = i0 * (size_t)10U + (size_t)10U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i uu____0 = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( @@ -4159,8 +4159,8 @@ deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vect size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_core_arch_x86___m256i uu____0 = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( @@ -4187,7 +4187,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4268,8 +4268,8 @@ compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( coefficient_compressed, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -4414,7 +4414,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1568 size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4454,7 +4454,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1536U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4478,8 +4478,8 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1536size_ uint8_t public_key_serialized[1568U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1[4U]; @@ -4632,7 +4632,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -4641,7 +4641,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -4724,7 +4724,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -4733,7 +4733,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -4758,7 +4758,7 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -5158,7 +5158,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -5171,7 +5171,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -5180,7 +5180,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)3168U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5197,7 +5197,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -5211,7 +5211,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5265,7 +5265,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1536 size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -5463,8 +5463,8 @@ compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_352size_t( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -5506,7 +5506,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408 re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)1408U / (size_t)4U), .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5610,8 +5610,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1408size_t_11size_t_352size_t( uu____5, Eurydice_array_to_subslice( (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)1408U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; @@ -5735,7 +5735,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_ size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), @@ -5787,7 +5787,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -5965,7 +5965,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_800s size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -6005,7 +6005,7 @@ serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)768U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -6029,8 +6029,8 @@ serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t uint8_t public_key_serialized[800U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____1[2U]; @@ -6167,7 +6167,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6176,7 +6176,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6243,7 +6243,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6252,7 +6252,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_ uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6277,7 +6277,7 @@ closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6672,7 +6672,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -6685,7 +6685,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -6694,7 +6694,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)1632U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6711,7 +6711,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -6725,7 +6725,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6779,7 +6779,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768s size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -7021,7 +7021,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640s re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)640U / (size_t)2U), .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -7117,8 +7117,8 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_640size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)640U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector uu____6 = v; @@ -7212,7 +7212,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_ size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), @@ -7253,7 +7253,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index 5ae63072a..e4349f2b1 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.c b/libcrux-ml-kem/c/libcrux_mlkem_neon.c deleted file mode 100644 index 09fd7ca96..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.c +++ /dev/null @@ -1,7506 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#include "internal/libcrux_mlkem_neon.h" - -#include "internal/libcrux_core.h" -#include "internal/libcrux_mlkem_portable.h" - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ZERO(void) { - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, - .high = libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)0)}); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( - void) { - return libcrux_ml_kem_vector_neon_simd128ops_ZERO(); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array) { - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice( - array, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, - .high = libcrux_intrinsics_arm64__vld1q_s16(Eurydice_slice_subslice( - array, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice))}); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( - Eurydice_slice array) { - return libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(array); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { - lhs.low = libcrux_intrinsics_arm64__vaddq_s16(lhs.low, rhs->low); - lhs.high = libcrux_intrinsics_arm64__vaddq_s16(lhs.high, rhs->high); - return lhs; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { - return libcrux_ml_kem_vector_neon_simd128ops_add(lhs, rhs); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { - lhs.low = libcrux_intrinsics_arm64__vsubq_s16(lhs.low, rhs->low); - lhs.high = libcrux_intrinsics_arm64__vsubq_s16(lhs.high, rhs->high); - return lhs; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs) { - return libcrux_ml_kem_vector_neon_simd128ops_sub(lhs, rhs); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - v.low = libcrux_intrinsics_arm64__vmulq_n_s16(v.low, c); - v.high = libcrux_intrinsics_arm64__vmulq_n_s16(v.high, c); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - return libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant(v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - core_core_arch_arm_shared_neon_int16x8_t c0 = - libcrux_intrinsics_arm64__vdupq_n_s16(c); - v.low = libcrux_intrinsics_arm64__vandq_s16(v.low, c0); - v.high = libcrux_intrinsics_arm64__vandq_s16(v.high, c0); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - return libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant(v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t c = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)3329); - core_core_arch_arm_shared_neon_uint16x8_t m0 = - libcrux_intrinsics_arm64__vcgeq_s16(v.low, c); - core_core_arch_arm_shared_neon_uint16x8_t m1 = - libcrux_intrinsics_arm64__vcgeq_s16(v.high, c); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = c; - core_core_arch_arm_shared_neon_int16x8_t c0 = - libcrux_intrinsics_arm64__vandq_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m0)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = c; - core_core_arch_arm_shared_neon_int16x8_t c1 = - libcrux_intrinsics_arm64__vandq_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u16(m1)); - v.low = libcrux_intrinsics_arm64__vsubq_s16(v.low, c0); - v.high = libcrux_intrinsics_arm64__vsubq_s16(v.high, c1); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329(v); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v) { - core_core_arch_arm_shared_neon_int16x8_t adder = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1024); - core_core_arch_arm_shared_neon_int16x8_t vec = - libcrux_intrinsics_arm64__vqdmulhq_n_s16( - v, LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER); - core_core_arch_arm_shared_neon_int16x8_t vec0 = - libcrux_intrinsics_arm64__vaddq_s16(vec, adder); - core_core_arch_arm_shared_neon_int16x8_t quotient = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)11, vec0, core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t sub = - libcrux_intrinsics_arm64__vmulq_n_s16( - quotient, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_intrinsics_arm64__vsubq_s16(v, sub); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - v.low = libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.low); - v.high = - libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(v.high); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce(v); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t low, - core_core_arch_arm_shared_neon_int16x8_t high) { - core_core_arch_arm_shared_neon_int16x8_t k = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16( - libcrux_intrinsics_arm64__vmulq_n_u16( - libcrux_intrinsics_arm64__vreinterpretq_u16_s16(low), - (uint16_t) - LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); - core_core_arch_arm_shared_neon_int16x8_t c = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)1, - libcrux_intrinsics_arm64__vqdmulhq_n_s16( - k, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_intrinsics_arm64__vsubq_s16(high, c); -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, int16_t c) { - core_core_arch_arm_shared_neon_int16x8_t v_low = - libcrux_intrinsics_arm64__vmulq_n_s16(v, c); - core_core_arch_arm_shared_neon_int16x8_t v_high = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)1, libcrux_intrinsics_arm64__vqdmulhq_n_s16(v, c), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - v_low, v_high); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - v.low = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - v.low, c); - v.high = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - v.high, c); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c) { - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( - v, c); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t half = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1664); - core_core_arch_arm_shared_neon_int16x8_t quarter = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)832); - core_core_arch_arm_shared_neon_int16x8_t shifted = - libcrux_intrinsics_arm64__vsubq_s16(half, v.low); - core_core_arch_arm_shared_neon_int16x8_t mask0 = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)15, shifted, core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t shifted_to_positive = - libcrux_intrinsics_arm64__veorq_s16(mask0, shifted); - core_core_arch_arm_shared_neon_int16x8_t shifted_positive_in_range = - libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive, quarter); - v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_u16( - libcrux_intrinsics_arm64__vshrq_n_u16( - (int32_t)15, - libcrux_intrinsics_arm64__vreinterpretq_u16_s16( - shifted_positive_in_range), - core_core_arch_arm_shared_neon_uint16x8_t)); - core_core_arch_arm_shared_neon_int16x8_t shifted0 = - libcrux_intrinsics_arm64__vsubq_s16(half, v.high); - core_core_arch_arm_shared_neon_int16x8_t mask = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)15, shifted0, core_core_arch_arm_shared_neon_int16x8_t); - core_core_arch_arm_shared_neon_int16x8_t shifted_to_positive0 = - libcrux_intrinsics_arm64__veorq_s16(mask, shifted0); - core_core_arch_arm_shared_neon_int16x8_t shifted_positive_in_range0 = - libcrux_intrinsics_arm64__vsubq_s16(shifted_to_positive0, quarter); - v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_u16( - libcrux_intrinsics_arm64__vshrq_n_u16( - (int32_t)15, - libcrux_intrinsics_arm64__vreinterpretq_u16_s16( - shifted_positive_in_range0), - core_core_arch_arm_shared_neon_uint16x8_t)); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return libcrux_ml_kem_vector_neon_simd128ops_compress_1(v); -} - -inline int16_t -libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - int16_t coefficient_bits) { - int16_t uu____0; - switch (coefficient_bits) { - case 4: { - uu____0 = (int16_t)15; - break; - } - case 5: { - uu____0 = (int16_t)31; - break; - } - case 10: { - uu____0 = (int16_t)1023; - break; - } - case 11: { - uu____0 = (int16_t)2047; - break; - } - default: { - int16_t x = coefficient_bits; - uu____0 = ((int16_t)1 << (uint32_t)x) - (int16_t)1; - } - } - return uu____0; -} - -inline core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - core_core_arch_arm_shared_neon_int16x8_t c) { - core_core_arch_arm_shared_neon_int16x8_t v_low = - libcrux_intrinsics_arm64__vmulq_s16(v, c); - core_core_arch_arm_shared_neon_int16x8_t v_high = - libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)1, libcrux_intrinsics_arm64__vqdmulhq_s16(v, c), - core_core_arch_arm_shared_neon_int16x8_t); - return libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - v_low, v_high); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - int16_t zetas[8U] = {zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4}; - core_core_arch_arm_shared_neon_int16x8_t zeta = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int32x4_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t dup_a = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn1q_s32( - uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int32x4_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t dup_b = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn2q_s32( - uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t t = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, - zeta); - core_core_arch_arm_shared_neon_int16x8_t b = - libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int16x8_t a = - libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int32x4_t uu____2 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); - v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn1q_s32( - uu____2, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - core_core_arch_arm_shared_neon_int32x4_t uu____3 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a); - v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn2q_s32( - uu____3, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step(a, zeta1, zeta2, - zeta3, zeta4); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2) { - int16_t zetas[8U] = {zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2}; - core_core_arch_arm_shared_neon_int16x8_t zeta = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int64x2_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t dup_a = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn1q_s64( - uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int64x2_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t dup_b = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn2q_s64( - uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t t = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(dup_b, - zeta); - core_core_arch_arm_shared_neon_int16x8_t b = - libcrux_intrinsics_arm64__vsubq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int16x8_t a = - libcrux_intrinsics_arm64__vaddq_s16(dup_a, t); - core_core_arch_arm_shared_neon_int64x2_t uu____2 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn1q_s64( - uu____2, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - core_core_arch_arm_shared_neon_int64x2_t uu____3 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn2q_s64( - uu____3, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2) { - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step(a, zeta1, - zeta2); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta) { - core_core_arch_arm_shared_neon_int16x8_t zeta0 = - libcrux_intrinsics_arm64__vdupq_n_s16(zeta); - core_core_arch_arm_shared_neon_int16x8_t t = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - v.high, zeta0); - v.high = libcrux_intrinsics_arm64__vsubq_s16(v.low, t); - v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, t); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta) { - return libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step(a, zeta); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - int16_t zetas[8U] = {zeta1, zeta1, zeta3, zeta3, zeta2, zeta2, zeta4, zeta4}; - core_core_arch_arm_shared_neon_int16x8_t zeta = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int32x4_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t a0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn1q_s32( - uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int32x4_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t b0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn2q_s32( - uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t b_minus_a = - libcrux_intrinsics_arm64__vsubq_s16(b0, a0); - core_core_arch_arm_shared_neon_int16x8_t a = - libcrux_intrinsics_arm64__vaddq_s16(a0, b0); - core_core_arch_arm_shared_neon_int16x8_t a1 = - libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t(a); - core_core_arch_arm_shared_neon_int16x8_t b = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - b_minus_a, zeta); - core_core_arch_arm_shared_neon_int32x4_t uu____2 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); - v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn1q_s32( - uu____2, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - core_core_arch_arm_shared_neon_int32x4_t uu____3 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16(a1); - v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn2q_s32( - uu____3, libcrux_intrinsics_arm64__vreinterpretq_s32_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( - a, zeta1, zeta2, zeta3, zeta4); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2) { - int16_t zetas[8U] = {zeta1, zeta1, zeta1, zeta1, zeta2, zeta2, zeta2, zeta2}; - core_core_arch_arm_shared_neon_int16x8_t zeta = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int64x2_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t a0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn1q_s64( - uu____0, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int64x2_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.low); - core_core_arch_arm_shared_neon_int16x8_t b0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn2q_s64( - uu____1, - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(v.high))); - core_core_arch_arm_shared_neon_int16x8_t b_minus_a = - libcrux_intrinsics_arm64__vsubq_s16(b0, a0); - core_core_arch_arm_shared_neon_int16x8_t a = - libcrux_intrinsics_arm64__vaddq_s16(a0, b0); - core_core_arch_arm_shared_neon_int16x8_t b = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - b_minus_a, zeta); - core_core_arch_arm_shared_neon_int64x2_t uu____2 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.low = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn1q_s64( - uu____2, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - core_core_arch_arm_shared_neon_int64x2_t uu____3 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s16(a); - v.high = libcrux_intrinsics_arm64__vreinterpretq_s16_s64( - libcrux_intrinsics_arm64__vtrn2q_s64( - uu____3, libcrux_intrinsics_arm64__vreinterpretq_s64_s16(b))); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2) { - return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step(a, zeta1, - zeta2); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta) { - core_core_arch_arm_shared_neon_int16x8_t zeta0 = - libcrux_intrinsics_arm64__vdupq_n_s16(zeta); - core_core_arch_arm_shared_neon_int16x8_t b_minus_a = - libcrux_intrinsics_arm64__vsubq_s16(v.high, v.low); - v.low = libcrux_intrinsics_arm64__vaddq_s16(v.low, v.high); - v.high = libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - b_minus_a, zeta0); - return v; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta) { - return libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step(a, zeta); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - int16_t zetas[8U] = {zeta1, zeta3, -zeta1, -zeta3, - zeta2, zeta4, -zeta2, -zeta4}; - core_core_arch_arm_shared_neon_int16x8_t zeta = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, zetas, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t a0 = - libcrux_intrinsics_arm64__vtrn1q_s16(lhs->low, lhs->high); - core_core_arch_arm_shared_neon_int16x8_t a1 = - libcrux_intrinsics_arm64__vtrn2q_s16(lhs->low, lhs->high); - core_core_arch_arm_shared_neon_int16x8_t b0 = - libcrux_intrinsics_arm64__vtrn1q_s16(rhs->low, rhs->high); - core_core_arch_arm_shared_neon_int16x8_t b1 = - libcrux_intrinsics_arm64__vtrn2q_s16(rhs->low, rhs->high); - core_core_arch_arm_shared_neon_int16x8_t a1b1 = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t(a1, - b1); - core_core_arch_arm_shared_neon_int16x4_t uu____0 = - libcrux_intrinsics_arm64__vget_low_s16(a1b1); - core_core_arch_arm_shared_neon_int32x4_t a1b1_low = - libcrux_intrinsics_arm64__vmull_s16( - uu____0, libcrux_intrinsics_arm64__vget_low_s16(zeta)); - core_core_arch_arm_shared_neon_int32x4_t a1b1_high = - libcrux_intrinsics_arm64__vmull_high_s16(a1b1, zeta); - core_core_arch_arm_shared_neon_int32x4_t uu____1 = a1b1_low; - core_core_arch_arm_shared_neon_int16x4_t uu____2 = - libcrux_intrinsics_arm64__vget_low_s16(a0); - core_core_arch_arm_shared_neon_int16x8_t fst_low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vmlal_s16( - uu____1, uu____2, libcrux_intrinsics_arm64__vget_low_s16(b0))); - core_core_arch_arm_shared_neon_int16x8_t fst_high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vmlal_high_s16(a1b1_high, a0, b0)); - core_core_arch_arm_shared_neon_int16x4_t uu____3 = - libcrux_intrinsics_arm64__vget_low_s16(a0); - core_core_arch_arm_shared_neon_int32x4_t a0b1_low = - libcrux_intrinsics_arm64__vmull_s16( - uu____3, libcrux_intrinsics_arm64__vget_low_s16(b1)); - core_core_arch_arm_shared_neon_int32x4_t a0b1_high = - libcrux_intrinsics_arm64__vmull_high_s16(a0, b1); - core_core_arch_arm_shared_neon_int32x4_t uu____4 = a0b1_low; - core_core_arch_arm_shared_neon_int16x4_t uu____5 = - libcrux_intrinsics_arm64__vget_low_s16(a1); - core_core_arch_arm_shared_neon_int16x8_t snd_low = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vmlal_s16( - uu____4, uu____5, libcrux_intrinsics_arm64__vget_low_s16(b0))); - core_core_arch_arm_shared_neon_int16x8_t snd_high = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vmlal_high_s16(a0b1_high, a1, b0)); - core_core_arch_arm_shared_neon_int16x8_t fst_low16 = - libcrux_intrinsics_arm64__vtrn1q_s16(fst_low, fst_high); - core_core_arch_arm_shared_neon_int16x8_t fst_high16 = - libcrux_intrinsics_arm64__vtrn2q_s16(fst_low, fst_high); - core_core_arch_arm_shared_neon_int16x8_t snd_low16 = - libcrux_intrinsics_arm64__vtrn1q_s16(snd_low, snd_high); - core_core_arch_arm_shared_neon_int16x8_t snd_high16 = - libcrux_intrinsics_arm64__vtrn2q_s16(snd_low, snd_high); - core_core_arch_arm_shared_neon_int16x8_t fst = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - fst_low16, fst_high16); - core_core_arch_arm_shared_neon_int16x8_t snd = - libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - snd_low16, snd_high16); - core_core_arch_arm_shared_neon_int32x4_t low0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn1q_s16(fst, snd)); - core_core_arch_arm_shared_neon_int32x4_t high0 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn2q_s16(fst, snd)); - core_core_arch_arm_shared_neon_int16x8_t low1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn1q_s32(low0, high0)); - core_core_arch_arm_shared_neon_int16x8_t high1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_s32( - libcrux_intrinsics_arm64__vtrn2q_s32(low0, high0)); - uint8_t indexes[16U] = {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, - 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U}; - core_core_arch_arm_shared_neon_uint8x16_t index = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( - (size_t)16U, indexes, uint8_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t low2 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u8( - libcrux_intrinsics_arm64__vqtbl1q_u8( - libcrux_intrinsics_arm64__vreinterpretq_u8_s16(low1), index)); - core_core_arch_arm_shared_neon_int16x8_t high2 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u8( - libcrux_intrinsics_arm64__vqtbl1q_u8( - libcrux_intrinsics_arm64__vreinterpretq_u8_s16(high1), index)); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){.low = low2, - .high = high2}); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4) { - return libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( - lhs, rhs, zeta1, zeta2, zeta3, zeta4); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[2U]) { - int16_t shifter[8U] = {(int16_t)0, (int16_t)1, (int16_t)2, (int16_t)3, - (int16_t)4, (int16_t)5, (int16_t)6, (int16_t)7}; - core_core_arch_arm_shared_neon_int16x8_t shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( - (size_t)8U, shifter, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t low0 = - libcrux_intrinsics_arm64__vshlq_s16(v.low, shift); - core_core_arch_arm_shared_neon_int16x8_t high0 = - libcrux_intrinsics_arm64__vshlq_s16(v.high, shift); - int16_t low = libcrux_intrinsics_arm64__vaddvq_s16(low0); - int16_t high = libcrux_intrinsics_arm64__vaddvq_s16(high0); - ret[0U] = (uint8_t)low; - ret[1U] = (uint8_t)high; -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[2U]) { - uint8_t ret0[2U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_1(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a) { - core_core_arch_arm_shared_neon_int16x8_t one = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)1); - core_core_arch_arm_shared_neon_int16x8_t low0 = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index( - a, (size_t)0U, uint8_t, uint8_t *, uint8_t)); - core_core_arch_arm_shared_neon_int16x8_t high0 = - libcrux_intrinsics_arm64__vdupq_n_s16((int16_t)Eurydice_slice_index( - a, (size_t)1U, uint8_t, uint8_t *, uint8_t)); - int16_t shifter[8U] = {(int16_t)0, (int16_t)255, (int16_t)-2, (int16_t)-3, - (int16_t)-4, (int16_t)-5, (int16_t)-6, (int16_t)-7}; - core_core_arch_arm_shared_neon_int16x8_t shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( - (size_t)8U, shifter, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vshlq_s16(low0, shift); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vshlq_s16(high0, shift); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vandq_s16(low, one); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .low = uu____0, .high = libcrux_intrinsics_arm64__vandq_s16(high, one)}); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(a); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[8U]) { - int16_t shifter[8U] = {(int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12, - (int16_t)0, (int16_t)4, (int16_t)8, (int16_t)12}; - core_core_arch_arm_shared_neon_int16x8_t shift = - libcrux_intrinsics_arm64__vld1q_s16(Eurydice_array_to_slice( - (size_t)8U, shifter, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t lowt = - libcrux_intrinsics_arm64__vshlq_u16( - libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.low), shift); - core_core_arch_arm_shared_neon_uint16x8_t hight = - libcrux_intrinsics_arm64__vshlq_u16( - libcrux_intrinsics_arm64__vreinterpretq_u16_s16(v.high), shift); - uint64_t sum0 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( - libcrux_intrinsics_arm64__vget_low_u16(lowt)); - uint64_t sum1 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( - libcrux_intrinsics_arm64__vget_high_u16(lowt)); - uint64_t sum2 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( - libcrux_intrinsics_arm64__vget_low_u16(hight)); - uint64_t sum3 = (uint64_t)libcrux_intrinsics_arm64__vaddv_u16( - libcrux_intrinsics_arm64__vget_high_u16(hight)); - uint64_t sum = ((sum0 | sum1 << 16U) | sum2 << 32U) | sum3 << 48U; - uint8_t ret0[8U]; - core_num__u64_9__to_le_bytes(sum, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[8U]) { - uint8_t ret0[8U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_4(a, ret0); - memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v) { - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2(&dst, v, Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret); - uint64_t input = core_num__u64_9__from_le_bytes(ret); - int16_t low[8U] = {0U}; - int16_t high[8U] = {0U}; - low[0U] = (int16_t)(input & 15ULL); - low[1U] = (int16_t)(input >> 4U & 15ULL); - low[2U] = (int16_t)(input >> 8U & 15ULL); - low[3U] = (int16_t)(input >> 12U & 15ULL); - low[4U] = (int16_t)(input >> 16U & 15ULL); - low[5U] = (int16_t)(input >> 20U & 15ULL); - low[6U] = (int16_t)(input >> 24U & 15ULL); - low[7U] = (int16_t)(input >> 28U & 15ULL); - high[0U] = (int16_t)(input >> 32U & 15ULL); - high[1U] = (int16_t)(input >> 36U & 15ULL); - high[2U] = (int16_t)(input >> 40U & 15ULL); - high[3U] = (int16_t)(input >> 44U & 15ULL); - high[4U] = (int16_t)(input >> 48U & 15ULL); - high[5U] = (int16_t)(input >> 52U & 15ULL); - high[6U] = (int16_t)(input >> 56U & 15ULL); - high[7U] = (int16_t)(input >> 60U & 15ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); - lit.high = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(a); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t ret[16U]) { - int16_t out[16U] = {0U}; - libcrux_intrinsics_arm64__vst1q_s16( - Eurydice_array_to_subslice((size_t)16U, out, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice), - v.low); - libcrux_intrinsics_arm64__vst1q_s16( - Eurydice_array_to_subslice((size_t)16U, out, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice), - v.high); - memcpy(ret, out, (size_t)16U * sizeof(int16_t)); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[10U]) { - uint8_t res[10U] = {0U}; - int16_t out[16U]; - libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, out); - res[0U] = (uint8_t)(out[0U] | out[1U] << 5U); - res[1U] = (uint8_t)((out[1U] >> 3U | out[2U] << 2U) | out[3U] << 7U); - res[2U] = (uint8_t)(out[3U] >> 1U | out[4U] << 4U); - res[3U] = (uint8_t)((out[4U] >> 4U | out[5U] << 1U) | out[6U] << 6U); - res[4U] = (uint8_t)(out[6U] >> 2U | out[7U] << 3U); - res[5U] = (uint8_t)(out[(size_t)8U + (size_t)0U] | - out[(size_t)8U + (size_t)1U] << 5U); - res[6U] = (uint8_t)((out[(size_t)8U + (size_t)1U] >> 3U | - out[(size_t)8U + (size_t)2U] << 2U) | - out[(size_t)8U + (size_t)3U] << 7U); - res[7U] = (uint8_t)(out[(size_t)8U + (size_t)3U] >> 1U | - out[(size_t)8U + (size_t)4U] << 4U); - res[8U] = (uint8_t)((out[(size_t)8U + (size_t)4U] >> 4U | - out[(size_t)8U + (size_t)5U] << 1U) | - out[(size_t)8U + (size_t)6U] << 6U); - res[9U] = (uint8_t)(out[(size_t)8U + (size_t)6U] >> 2U | - out[(size_t)8U + (size_t)7U] << 3U); - memcpy(ret, res, (size_t)10U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[10U]) { - uint8_t ret0[10U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_5(a, ret0); - memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v) { - uint8_t input0[8U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)8U, input0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)5U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - uint8_t uu____1[8U]; - memcpy(uu____1, input0, (size_t)8U * sizeof(uint8_t)); - uint64_t low64 = core_num__u64_9__from_le_bytes(uu____1); - uint8_t input1[8U] = {0U}; - Eurydice_slice uu____2 = Eurydice_array_to_subslice( - (size_t)8U, input1, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)5U, .end = (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input1, (size_t)8U * sizeof(uint8_t)); - uint64_t high64 = core_num__u64_9__from_le_bytes(uu____3); - int16_t low[8U] = {0U}; - int16_t high[8U] = {0U}; - low[0U] = (int16_t)(low64 & 31ULL); - low[1U] = (int16_t)(low64 >> 5U & 31ULL); - low[2U] = (int16_t)(low64 >> 10U & 31ULL); - low[3U] = (int16_t)(low64 >> 15U & 31ULL); - low[4U] = (int16_t)(low64 >> 20U & 31ULL); - low[5U] = (int16_t)(low64 >> 25U & 31ULL); - low[6U] = (int16_t)(low64 >> 30U & 31ULL); - low[7U] = (int16_t)(low64 >> 35U & 31ULL); - high[0U] = (int16_t)(high64 & 31ULL); - high[1U] = (int16_t)(high64 >> 5U & 31ULL); - high[2U] = (int16_t)(high64 >> 10U & 31ULL); - high[3U] = (int16_t)(high64 >> 15U & 31ULL); - high[4U] = (int16_t)(high64 >> 20U & 31ULL); - high[5U] = (int16_t)(high64 >> 25U & 31ULL); - high[6U] = (int16_t)(high64 >> 30U & 31ULL); - high[7U] = (int16_t)(high64 >> 35U & 31ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); - lit.high = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(a); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[20U]) { - core_core_arch_arm_shared_neon_int32x4_t low00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn1q_s16(v.low, v.low)); - core_core_arch_arm_shared_neon_int32x4_t low10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn2q_s16(v.low, v.low)); - core_core_arch_arm_shared_neon_int32x4_t mixt = - libcrux_intrinsics_arm64__vsliq_n_s32( - (int32_t)10, low00, low10, core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t low0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn1q_s32(mixt, mixt)); - core_core_arch_arm_shared_neon_int64x2_t low1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn2q_s32(mixt, mixt)); - core_core_arch_arm_shared_neon_int64x2_t low_mix = - libcrux_intrinsics_arm64__vsliq_n_s64( - (int32_t)20, low0, low1, core_core_arch_arm_shared_neon_int64x2_t); - core_core_arch_arm_shared_neon_int32x4_t high00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn1q_s16(v.high, v.high)); - core_core_arch_arm_shared_neon_int32x4_t high10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn2q_s16(v.high, v.high)); - core_core_arch_arm_shared_neon_int32x4_t mixt0 = - libcrux_intrinsics_arm64__vsliq_n_s32( - (int32_t)10, high00, high10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t high0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, mixt0)); - core_core_arch_arm_shared_neon_int64x2_t high1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, mixt0)); - core_core_arch_arm_shared_neon_int64x2_t high_mix = - libcrux_intrinsics_arm64__vsliq_n_s64( - (int32_t)20, high0, high1, core_core_arch_arm_shared_neon_int64x2_t); - uint8_t result32[32U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, result32, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); - Eurydice_slice uu____1 = Eurydice_array_to_subslice( - (size_t)32U, result32, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); - uint8_t result[20U] = {0U}; - Eurydice_slice uu____2 = Eurydice_array_to_subslice( - (size_t)20U, result, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)5U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)5U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_array_to_subslice( - (size_t)20U, result, - ((core_ops_range_Range__size_t){.start = (size_t)5U, .end = (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)13U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)20U, result, - ((core_ops_range_Range__size_t){.start = (size_t)10U, - .end = (size_t)15U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)21U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)20U, result, - ((core_ops_range_Range__size_t){.start = (size_t)15U, - .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)29U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[20U]) { - uint8_t ret0[20U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_10(a, ret0); - memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v) { - uint8_t input0[8U] = {0U}; - uint8_t input1[8U] = {0U}; - uint8_t input2[4U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)4U, input2, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input0, (size_t)8U * sizeof(uint8_t)); - uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); - uint8_t uu____4[8U]; - memcpy(uu____4, input1, (size_t)8U * sizeof(uint8_t)); - uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); - uint8_t uu____5[4U]; - memcpy(uu____5, input2, (size_t)4U * sizeof(uint8_t)); - uint32_t input20 = core_num__u32_8__from_le_bytes(uu____5); - int16_t low[8U] = {0U}; - int16_t high[8U] = {0U}; - low[0U] = (int16_t)(input00 & 1023ULL); - low[1U] = (int16_t)(input00 >> 10U & 1023ULL); - low[2U] = (int16_t)(input00 >> 20U & 1023ULL); - low[3U] = (int16_t)(input00 >> 30U & 1023ULL); - low[4U] = (int16_t)(input00 >> 40U & 1023ULL); - low[5U] = (int16_t)(input00 >> 50U & 1023ULL); - low[6U] = (int16_t)((input00 >> 60U | input10 << 4U) & 1023ULL); - low[7U] = (int16_t)(input10 >> 6U & 1023ULL); - high[0U] = (int16_t)(input10 >> 16U & 1023ULL); - high[1U] = (int16_t)(input10 >> 26U & 1023ULL); - high[2U] = (int16_t)(input10 >> 36U & 1023ULL); - high[3U] = (int16_t)(input10 >> 46U & 1023ULL); - high[4U] = (int16_t)(((uint32_t)(input10 >> 56U) | input20 << 8U) & 1023U); - high[5U] = (int16_t)(input20 >> 2U & 1023U); - high[6U] = (int16_t)(input20 >> 12U & 1023U); - high[7U] = (int16_t)(input20 >> 22U & 1023U); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); - lit.high = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(a); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[22U]) { - int16_t input[16U]; - libcrux_ml_kem_vector_neon_simd128ops_to_i16_array(v, input); - uint8_t result[22U] = {0U}; - result[0U] = (uint8_t)input[0U]; - result[1U] = (uint8_t)(input[0U] >> 8U | input[1U] << 3U); - result[2U] = (uint8_t)(input[1U] >> 5U | input[2U] << 6U); - result[3U] = (uint8_t)(input[2U] >> 2U); - result[4U] = (uint8_t)(input[2U] >> 10U | input[3U] << 1U); - result[5U] = (uint8_t)(input[3U] >> 7U | input[4U] << 4U); - result[6U] = (uint8_t)(input[4U] >> 4U | input[5U] << 7U); - result[7U] = (uint8_t)(input[5U] >> 1U); - result[8U] = (uint8_t)(input[5U] >> 9U | input[6U] << 2U); - result[9U] = (uint8_t)(input[6U] >> 6U | input[7U] << 5U); - result[10U] = (uint8_t)(input[7U] >> 3U); - result[(size_t)11U + (size_t)0U] = (uint8_t)input[(size_t)8U + (size_t)0U]; - result[(size_t)11U + (size_t)1U] = - (uint8_t)(input[(size_t)8U + (size_t)0U] >> 8U | - input[(size_t)8U + (size_t)1U] << 3U); - result[(size_t)11U + (size_t)2U] = - (uint8_t)(input[(size_t)8U + (size_t)1U] >> 5U | - input[(size_t)8U + (size_t)2U] << 6U); - result[(size_t)11U + (size_t)3U] = - (uint8_t)(input[(size_t)8U + (size_t)2U] >> 2U); - result[(size_t)11U + (size_t)4U] = - (uint8_t)(input[(size_t)8U + (size_t)2U] >> 10U | - input[(size_t)8U + (size_t)3U] << 1U); - result[(size_t)11U + (size_t)5U] = - (uint8_t)(input[(size_t)8U + (size_t)3U] >> 7U | - input[(size_t)8U + (size_t)4U] << 4U); - result[(size_t)11U + (size_t)6U] = - (uint8_t)(input[(size_t)8U + (size_t)4U] >> 4U | - input[(size_t)8U + (size_t)5U] << 7U); - result[(size_t)11U + (size_t)7U] = - (uint8_t)(input[(size_t)8U + (size_t)5U] >> 1U); - result[(size_t)11U + (size_t)8U] = - (uint8_t)(input[(size_t)8U + (size_t)5U] >> 9U | - input[(size_t)8U + (size_t)6U] << 2U); - result[(size_t)11U + (size_t)9U] = - (uint8_t)(input[(size_t)8U + (size_t)6U] >> 6U | - input[(size_t)8U + (size_t)7U] << 5U); - result[(size_t)11U + (size_t)10U] = - (uint8_t)(input[(size_t)8U + (size_t)7U] >> 3U); - memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[22U]) { - uint8_t ret0[22U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_11(a, ret0); - memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v) { - uint8_t input0[8U] = {0U}; - uint8_t input1[8U] = {0U}; - uint8_t input2[8U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)8U, input0, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)8U, input1, uint8_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_array_to_subslice( - (size_t)8U, input2, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)6U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - uint8_t uu____3[8U]; - memcpy(uu____3, input0, (size_t)8U * sizeof(uint8_t)); - uint64_t input00 = core_num__u64_9__from_le_bytes(uu____3); - uint8_t uu____4[8U]; - memcpy(uu____4, input1, (size_t)8U * sizeof(uint8_t)); - uint64_t input10 = core_num__u64_9__from_le_bytes(uu____4); - uint8_t uu____5[8U]; - memcpy(uu____5, input2, (size_t)8U * sizeof(uint8_t)); - uint64_t input20 = core_num__u64_9__from_le_bytes(uu____5); - int16_t low[8U] = {0U}; - int16_t high[8U] = {0U}; - low[0U] = (int16_t)(input00 & 2047ULL); - low[1U] = (int16_t)(input00 >> 11U & 2047ULL); - low[2U] = (int16_t)(input00 >> 22U & 2047ULL); - low[3U] = (int16_t)(input00 >> 33U & 2047ULL); - low[4U] = (int16_t)(input00 >> 44U & 2047ULL); - low[5U] = (int16_t)((input00 >> 55U | input10 << 9U) & 2047ULL); - low[6U] = (int16_t)(input10 >> 2U & 2047ULL); - low[7U] = (int16_t)(input10 >> 13U & 2047ULL); - high[0U] = (int16_t)(input10 >> 24U & 2047ULL); - high[1U] = (int16_t)(input10 >> 35U & 2047ULL); - high[2U] = (int16_t)(input10 >> 46U & 2047ULL); - high[3U] = (int16_t)((input10 >> 57U | input20 << 7U) & 2047ULL); - high[4U] = (int16_t)(input20 >> 4U & 2047ULL); - high[5U] = (int16_t)(input20 >> 15U & 2047ULL); - high[6U] = (int16_t)(input20 >> 26U & 2047ULL); - high[7U] = (int16_t)(input20 >> 37U & 2047ULL); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lit; - lit.low = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, low, int16_t, Eurydice_slice)); - lit.high = libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, high, int16_t, Eurydice_slice)); - return lit; -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(a); -} - -inline void libcrux_ml_kem_vector_neon_simd128ops_serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[24U]) { - core_core_arch_arm_shared_neon_int32x4_t low00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn1q_s16(v.low, v.low)); - core_core_arch_arm_shared_neon_int32x4_t low10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn2q_s16(v.low, v.low)); - core_core_arch_arm_shared_neon_int32x4_t mixt = - libcrux_intrinsics_arm64__vsliq_n_s32( - (int32_t)12, low00, low10, core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t low0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn1q_s32(mixt, mixt)); - core_core_arch_arm_shared_neon_int64x2_t low1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn2q_s32(mixt, mixt)); - core_core_arch_arm_shared_neon_int64x2_t low_mix = - libcrux_intrinsics_arm64__vsliq_n_s64( - (int32_t)24, low0, low1, core_core_arch_arm_shared_neon_int64x2_t); - core_core_arch_arm_shared_neon_int32x4_t high00 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn1q_s16(v.high, v.high)); - core_core_arch_arm_shared_neon_int32x4_t high10 = - libcrux_intrinsics_arm64__vreinterpretq_s32_s16( - libcrux_intrinsics_arm64__vtrn2q_s16(v.high, v.high)); - core_core_arch_arm_shared_neon_int32x4_t mixt0 = - libcrux_intrinsics_arm64__vsliq_n_s32( - (int32_t)12, high00, high10, - core_core_arch_arm_shared_neon_int32x4_t); - core_core_arch_arm_shared_neon_int64x2_t high0 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn1q_s32(mixt0, mixt0)); - core_core_arch_arm_shared_neon_int64x2_t high1 = - libcrux_intrinsics_arm64__vreinterpretq_s64_s32( - libcrux_intrinsics_arm64__vtrn2q_s32(mixt0, mixt0)); - core_core_arch_arm_shared_neon_int64x2_t high_mix = - libcrux_intrinsics_arm64__vsliq_n_s64( - (int32_t)24, high0, high1, core_core_arch_arm_shared_neon_int64x2_t); - uint8_t result32[32U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, result32, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(low_mix)); - Eurydice_slice uu____1 = Eurydice_array_to_subslice( - (size_t)32U, result32, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)32U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_u8( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_u8_s64(high_mix)); - uint8_t result[24U] = {0U}; - Eurydice_slice uu____2 = Eurydice_array_to_subslice( - (size_t)24U, result, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)6U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)6U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____3 = Eurydice_array_to_subslice( - (size_t)24U, result, - ((core_ops_range_Range__size_t){.start = (size_t)6U, .end = (size_t)12U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____3, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)8U, .end = (size_t)14U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____4 = Eurydice_array_to_subslice( - (size_t)24U, result, - ((core_ops_range_Range__size_t){.start = (size_t)12U, - .end = (size_t)18U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)16U, .end = (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____5 = Eurydice_array_to_subslice( - (size_t)24U, result, - ((core_ops_range_Range__size_t){.start = (size_t)18U, - .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____5, - Eurydice_array_to_subslice((size_t)32U, result32, - ((core_ops_range_Range__size_t){ - .start = (size_t)24U, .end = (size_t)30U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[24U]) { - uint8_t ret0[24U]; - libcrux_ml_kem_vector_neon_simd128ops_serialize_12(a, ret0); - memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v) { - uint8_t indexes[16U] = {0U, 1U, 1U, 2U, 3U, 4U, 4U, 5U, - 6U, 7U, 7U, 8U, 9U, 10U, 10U, 11U}; - core_core_arch_arm_shared_neon_uint8x16_t index_vec = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( - (size_t)16U, indexes, uint8_t, Eurydice_slice)); - int16_t shifts[8U] = {(int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4, - (int16_t)0, (int16_t)-4, (int16_t)0, (int16_t)-4}; - core_core_arch_arm_shared_neon_int16x8_t shift_vec = - libcrux_intrinsics_arm64__vld1q_s16( - Eurydice_array_to_slice((size_t)8U, shifts, int16_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t mask12 = - libcrux_intrinsics_arm64__vdupq_n_u16(4095U); - uint8_t input0[16U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)16U, input0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)12U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)12U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_arm_shared_neon_uint8x16_t input_vec0 = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( - (size_t)16U, input0, uint8_t, Eurydice_slice)); - uint8_t input1[16U] = {0U}; - Eurydice_slice uu____1 = Eurydice_array_to_subslice( - (size_t)16U, input1, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)12U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_slice_subslice(v, - ((core_ops_range_Range__size_t){ - .start = (size_t)12U, .end = (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - core_core_arch_arm_shared_neon_uint8x16_t input_vec1 = - libcrux_intrinsics_arm64__vld1q_u8(Eurydice_array_to_slice( - (size_t)16U, input1, uint8_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint16x8_t moved0 = - libcrux_intrinsics_arm64__vreinterpretq_u16_u8( - libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec0, index_vec)); - core_core_arch_arm_shared_neon_uint16x8_t shifted0 = - libcrux_intrinsics_arm64__vshlq_u16(moved0, shift_vec); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16( - libcrux_intrinsics_arm64__vandq_u16(shifted0, mask12)); - core_core_arch_arm_shared_neon_uint16x8_t moved1 = - libcrux_intrinsics_arm64__vreinterpretq_u16_u8( - libcrux_intrinsics_arm64__vqtbl1q_u8(input_vec1, index_vec)); - core_core_arch_arm_shared_neon_uint16x8_t shifted1 = - libcrux_intrinsics_arm64__vshlq_u16(moved1, shift_vec); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vreinterpretq_s16_u16( - libcrux_intrinsics_arm64__vandq_u16(shifted1, mask12)); - return ((libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){.low = low, - .high = high}); -} - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - Eurydice_slice a) { - return libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(a); -} - -inline size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, - Eurydice_slice result) { - size_t sampled = (size_t)0U; - core_slice_iter_Chunks iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - core_slice___Slice_T___chunks(a, (size_t)3U, uint8_t, - core_slice_iter_Chunks), - core_slice_iter_Chunks, core_slice_iter_Chunks); - while (true) { - core_option_Option__Eurydice_slice_uint8_t uu____0 = - core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( - &iter, uint8_t, core_option_Option__Eurydice_slice_uint8_t); - if (uu____0.tag == core_option_None) { - break; - } else { - Eurydice_slice bytes = uu____0.f0; - int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t d1 = (b2 & (int16_t)15) << 8U | b1; - int16_t d2 = b3 << 4U | b2 >> 4U; - bool uu____1; - int16_t uu____2; - bool uu____3; - size_t uu____4; - int16_t uu____5; - size_t uu____6; - int16_t uu____7; - if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { - if (sampled < (size_t)16U) { - int16_t uu____8 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = - uu____8; - sampled++; - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, - int16_t) = uu____5; - sampled++; - continue; - } - } - continue; - } - } - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = - uu____5; - sampled++; - continue; - } - } - } - } - return sampled; -} - -size_t -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - Eurydice_slice a, Eurydice_slice out) { - return libcrux_ml_kem_vector_neon_rej_sample(a, out); -} - -inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self) { - return self[0U]; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(void) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - lit; - lit.coefficients[0U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[1U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[2U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[3U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[4U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[5U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[6U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[7U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[8U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[9U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[10U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[11U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[12U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[13U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[14U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - lit.coefficients[15U] = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(); - return lit; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -shift_right___15int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - v.low = libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)15, v.low, core_core_arch_arm_shared_neon_int16x8_t); - v.high = libcrux_intrinsics_arm64__vshrq_n_s16( - (int32_t)15, v.high, core_core_arch_arm_shared_neon_int16x8_t); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -shift_right___15int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return shift_right___15int32_t(v); -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a) { - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = - shift_right___15int32_t0(a); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fm = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - a, &fm); -} - -static inline void -serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[3U], - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1152U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U], - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[3U]; - memcpy( - uu____1, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t ret0[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1184size_t_3size_t( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[3U]; - memcpy( - uu____0, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___3size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_neon_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -typedef struct Simd128Hash_s { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - shake128_state[2U]; -} Simd128Hash; - -static inline Simd128Hash shake128_init_absorb___3size_t( - uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - uu____1, uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = &state[1U]; - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - uu____3, uu____4, - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy( - lit.shake128_state, state, - (size_t)2U * - sizeof( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___3size_t( - Simd128Hash *self, uint8_t ret[3U][504U]) { - uint8_t out[3U][504U] = {{0U}}; - uint8_t extra[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = self->shake128_state; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____4 = &self->shake128_state[1U]; - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, extra, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___3size_t(Simd128Hash *self, - uint8_t ret[3U][168U]) { - uint8_t out[3U][168U] = {{0U}}; - uint8_t out0[168U] = {0U}; - uint8_t out1[168U] = {0U}; - uint8_t out2[168U] = {0U}; - uint8_t out3[168U] = {0U}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - uu____0, uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &self->shake128_state[1U]; - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - uu____2, uu____3, - Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); - uint8_t uu____4[168U]; - memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); - memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____5[168U]; - memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); - memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____6[168U]; - memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); - memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice a) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( - Eurydice_slice_subslice( - a, - ((core_ops_range_Range__size_t){ - .start = i0 * (size_t)16U, - .end = (i0 + (size_t)1U) * (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - result.coefficients[i0] = uu____0; - } - return result; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - size_t sampled_coefficients[3U] = {0U}; - int16_t out[3U][272U] = {{0U}}; - uint8_t uu____0[3U][34U]; - memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); - Simd128Hash xof_state = shake128_init_absorb___3size_t(uu____0); - uint8_t randomness0[3U][504U]; - shake128_squeeze_three_blocks___3size_t(&xof_state, randomness0); - uint8_t uu____1[3U][504U]; - memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[3U][168U]; - shake128_squeeze_block___3size_t(&xof_state, randomness); - uint8_t uu____2[3U][168U]; - memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[3U][272U]; - memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t0( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - A_transpose[i]);); - KRML_MAYBE_FOR3( - i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[3U][34U]; - memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[3U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [3U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[3U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t; - -static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[3U][128U]) { - uint8_t out[3U][128U] = {{0U}}; - uint8_t extra[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____2, uu____3, uu____4, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - Eurydice_slice uu____5 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)128U, extra, uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)4U, - .end = chunk_number * (size_t)4U + (size_t)4U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t uu____2 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t random_bits_as_u32 = - uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, - uint8_t, uint8_t *, uint8_t) - << 24U; - uint32_t even_bits = random_bits_as_u32 & 1431655765U; - uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; - uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { - uint32_t outcome_set = i; - uint32_t outcome_set0 = outcome_set * 4U; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); - int16_t outcome_2 = - (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); - size_t offset = (size_t)(outcome_set0 >> 2U); - sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; - i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice( - randomness, - ((core_ops_range_Range__size_t){ - .start = chunk_number * (size_t)3U, - .end = chunk_number * (size_t)3U + (size_t)3U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint32_t uu____0 = (uint32_t)Eurydice_slice_index( - byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); - uint32_t uu____1 = - uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, - uint8_t, uint8_t *, uint8_t) - << 8U; - uint32_t random_bits_as_u24 = - uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, - uint8_t, uint8_t *, uint8_t) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, - Eurydice_slice)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - randomness); - return uu____0; -} - -static inline void -ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; - for (size_t i = (size_t)0U; i < step; i++) { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( - re->coefficients[j + step], (int16_t)-1600); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - re->coefficients[j], &t); - re->coefficients[j + step] = uu____0; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____1 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - re->coefficients[j], &t); - re->coefficients[j] = uu____1; - } -} - -typedef struct - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector snd; -} __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t fer) { - return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - v, fer); -} - -static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, int16_t zeta_r) { - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector t = - montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - b, zeta_r); - b = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - a, &t); - a = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - a, &t); - return (( - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .fst = a, .snd = b}); -} - -static inline void -ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = offset / (size_t)16U; - size_t step_vec = step / (size_t)16U; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - ntt_layer_int_vec_step__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline void -ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); -} - -static inline void -ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] + (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); -} - -static inline void -poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - self->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - ntt_at_layer_7__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); - size_t zeta_i = (size_t)1U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - re_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[3U]; - memcpy( - uu____2, re_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - out = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( - &self->coefficients[i0], &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)3U]); - out.coefficients[i0] = uu____0; - } - return out; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)16U, self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); -} - -static inline void -add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = - to_standard_domain__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - self->coefficients[j]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static K___uint8_t_1152size_t__uint8_t_1184size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___3size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[3U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[3U]; - memcpy( - uu____4, t_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[1184U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t_1184size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[3U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t secret_key_serialized[1152U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1152size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1152U]; - memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); - uint8_t uu____7[1184U]; - memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - -static inline void H___3size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_neon_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)2400U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___3size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); -} - -libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1152U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[2400U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t( - uu____1, - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[2400U]; - memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; - uint8_t uu____4[1184U]; - memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( - uu____4)); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - error_1[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[3U][33U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[3U][128U]; - PRFxN___3size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[3U]; - memcpy( - uu____2, error_1, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___3size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - uint8_t dummy[128U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static inline void -invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); -} - -static inline void -invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); - re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); -} - -static inline void -invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); - re->coefficients[round] = uu____0;); -} - -static inline __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector b, int16_t zeta_r) { - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a_minus_b = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - b, &a); - a = libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - a, &b)); - b = montgomery_multiply_fe__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - a_minus_b, zeta_r); - return (( - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector){ - .fst = a, .snd = b}); -} - -static inline void -invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - size_t *zeta_i, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - size_t layer) { - size_t step = (size_t)1U << (uint32_t)layer; - for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { - size_t round = i0; - zeta_i[0U] = zeta_i[0U] - (size_t)1U; - size_t offset = round * step * (size_t)2U; - size_t offset_vec = - offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - size_t step_vec = - step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; - for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { - size_t j = i; - __libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R - [zeta_i[0U]]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector x = uu____0.fst; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector y = uu____0.snd; - re->coefficients[j] = x; - re->coefficients[j + step_vec] = y; - } - } -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t j = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - self->coefficients[j], (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - coefficient_normal_form, &error->coefficients[j])); - self->coefficients[j] = uu____0; - } -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [3U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [3U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO(), - &v), - (int16_t)1665); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_compressed = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( - Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ - .start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - decompress_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - coefficient_compressed); - re.coefficients[i0] = uu____0;); - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - result.coefficients[i0], (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector tmp = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - self->coefficients[i0], &message->coefficients[i0]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector tmp0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - coefficient_normal_form, &tmp); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - error_2, message, result); - return result; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t half = - libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t compressed = - libcrux_intrinsics_arm64__vshlq_n_u32( - (int32_t)10, v, core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t compressed0 = - libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32( - libcrux_intrinsics_arm64__vqdmulhq_n_s32( - libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___10int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t mask = - libcrux_intrinsics_arm64__vdupq_n_s16( - libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - (int16_t)(int32_t)10)); - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - compress_int32x4_t___10int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - compress_int32x4_t___10int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - compress_int32x4_t___10int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - compress_int32x4_t___10int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___10int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return compress___10int32_t(v); -} - -static inline void -compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - compress___10int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[i0])); - uint8_t bytes[20U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t half = - libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t compressed = - libcrux_intrinsics_arm64__vshlq_n_u32( - (int32_t)11, v, core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t compressed0 = - libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32( - libcrux_intrinsics_arm64__vqdmulhq_n_s32( - libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___11int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t mask = - libcrux_intrinsics_arm64__vdupq_n_s16( - libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - (int16_t)(int32_t)11)); - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - compress_int32x4_t___11int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - compress_int32x4_t___11int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - compress_int32x4_t___11int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - compress_int32x4_t___11int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___11int32_t0(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return compress___11int32_t(v); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[320U]) { - uint8_t uu____0[320U]; - compress_then_serialize_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_320size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[3U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)960U / (size_t)3U), - .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t half = - libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t compressed = - libcrux_intrinsics_arm64__vshlq_n_u32( - (int32_t)4, v, core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t compressed0 = - libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32( - libcrux_intrinsics_arm64__vqdmulhq_n_s32( - libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___4int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t mask = - libcrux_intrinsics_arm64__vdupq_n_s16( - libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - (int16_t)(int32_t)4)); - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - compress_int32x4_t___4int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - compress_int32x4_t___4int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - compress_int32x4_t___4int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - compress_int32x4_t___4int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector compress___4int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return compress___4int32_t(v); -} - -static inline void -compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - compress___4int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -compress_int32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t half = - libcrux_intrinsics_arm64__vdupq_n_u32(1664U); - core_core_arch_arm_shared_neon_uint32x4_t compressed = - libcrux_intrinsics_arm64__vshlq_n_u32( - (int32_t)5, v, core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t compressed0 = - libcrux_intrinsics_arm64__vaddq_u32(compressed, half); - core_core_arch_arm_shared_neon_uint32x4_t compressed1 = - libcrux_intrinsics_arm64__vreinterpretq_u32_s32( - libcrux_intrinsics_arm64__vqdmulhq_n_s32( - libcrux_intrinsics_arm64__vreinterpretq_s32_u32(compressed0), - (int32_t)10321340)); - core_core_arch_arm_shared_neon_uint32x4_t compressed2 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)4, compressed1, core_core_arch_arm_shared_neon_uint32x4_t); - return compressed2; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compress___5int32_t(libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_int16x8_t mask = - libcrux_intrinsics_arm64__vdupq_n_s16( - libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - (int16_t)(int32_t)5)); - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - compress_int32x4_t___5int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - compress_int32x4_t___5int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - compress_int32x4_t___5int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - compress_int32x4_t___5int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - core_core_arch_arm_shared_neon_int16x8_t low = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - core_core_arch_arm_shared_neon_int16x8_t high = - libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - v.low = libcrux_intrinsics_arm64__vandq_s16(low, mask); - v.high = libcrux_intrinsics_arm64__vandq_s16(high, mask); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector compress___5int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return compress___5int32_t(v); -} - -static inline void -compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients = - compress___5int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( - coefficients, bytes); - Eurydice_slice uu____0 = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice out) { - compress_then_serialize_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[3U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1152size_t_3size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___3size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[3U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[3U]; - memcpy( - uu____5, u, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_960size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___3size_t( - Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1088U]; - memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___10int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t coeff = - libcrux_intrinsics_arm64__vdupq_n_u32( - 1U << (uint32_t)((int32_t)10 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32( - v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = - libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)10, decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___10int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - decompress_uint32x4_t___10int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - decompress_uint32x4_t___10int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - decompress_uint32x4_t___10int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - decompress_uint32x4_t___10int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___10int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return decompress_ciphertext_coefficient___10int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( - bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - decompress_ciphertext_coefficient___10int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___11int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t coeff = - libcrux_intrinsics_arm64__vdupq_n_u32( - 1U << (uint32_t)((int32_t)11 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32( - v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = - libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)11, decompressed0, - core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___11int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - decompress_uint32x4_t___11int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - decompress_uint32x4_t___11int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - decompress_uint32x4_t___11int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - decompress_uint32x4_t___11int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___11int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return decompress_ciphertext_coefficient___11int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( - bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - decompress_ciphertext_coefficient___11int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_10__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - u_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___4int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t coeff = - libcrux_intrinsics_arm64__vdupq_n_u32( - 1U << (uint32_t)((int32_t)4 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32( - v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = - libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)4, decompressed0, core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___4int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - decompress_uint32x4_t___4int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - decompress_uint32x4_t___4int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - decompress_uint32x4_t___4int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - decompress_uint32x4_t___4int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___4int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return decompress_ciphertext_coefficient___4int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( - bytes); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - decompress_ciphertext_coefficient___4int32_t0(coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline core_core_arch_arm_shared_neon_uint32x4_t -decompress_uint32x4_t___5int32_t(core_core_arch_arm_shared_neon_uint32x4_t v) { - core_core_arch_arm_shared_neon_uint32x4_t coeff = - libcrux_intrinsics_arm64__vdupq_n_u32( - 1U << (uint32_t)((int32_t)5 - (int32_t)1)); - core_core_arch_arm_shared_neon_uint32x4_t decompressed = - libcrux_intrinsics_arm64__vmulq_n_u32( - v, (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - core_core_arch_arm_shared_neon_uint32x4_t decompressed0 = - libcrux_intrinsics_arm64__vaddq_u32(decompressed, coeff); - core_core_arch_arm_shared_neon_uint32x4_t decompressed1 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)5, decompressed0, core_core_arch_arm_shared_neon_uint32x4_t); - return decompressed1; -} - -static inline libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___5int32_t( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - core_core_arch_arm_shared_neon_uint32x4_t mask16 = - libcrux_intrinsics_arm64__vdupq_n_u32(65535U); - core_core_arch_arm_shared_neon_uint32x4_t low00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), mask16); - core_core_arch_arm_shared_neon_uint32x4_t low10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.low), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t high00 = - libcrux_intrinsics_arm64__vandq_u32( - libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), mask16); - core_core_arch_arm_shared_neon_uint32x4_t high10 = - libcrux_intrinsics_arm64__vshrq_n_u32( - (int32_t)16, libcrux_intrinsics_arm64__vreinterpretq_u32_s16(v.high), - core_core_arch_arm_shared_neon_uint32x4_t); - core_core_arch_arm_shared_neon_uint32x4_t low0 = - decompress_uint32x4_t___5int32_t(low00); - core_core_arch_arm_shared_neon_uint32x4_t low1 = - decompress_uint32x4_t___5int32_t(low10); - core_core_arch_arm_shared_neon_uint32x4_t high0 = - decompress_uint32x4_t___5int32_t(high00); - core_core_arch_arm_shared_neon_uint32x4_t high1 = - decompress_uint32x4_t___5int32_t(high10); - core_core_arch_arm_shared_neon_int16x8_t uu____0 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low0); - v.low = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____0, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(low1)); - core_core_arch_arm_shared_neon_int16x8_t uu____1 = - libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high0); - v.high = libcrux_intrinsics_arm64__vtrn1q_s16( - uu____1, libcrux_intrinsics_arm64__vreinterpretq_s16_u32(high1)); - return v; -} - -static libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -decompress_ciphertext_coefficient___5int32_t0( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v) { - return decompress_ciphertext_coefficient___5int32_t(v); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( - bytes); - re.coefficients[i0] = uu____0; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____1 = - decompress_ciphertext_coefficient___5int32_t0(re.coefficients[i0]); - re.coefficients[i0] = uu____1; - } - return re; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_4__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - serialized); - return uu____0; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - for (size_t i = (size_t)0U; - i < - core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; - i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice( - serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - bytes); - re.coefficients[i0] = uu____0; - } - return re; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, - secret_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)3U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - b) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_normal_form = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - b.coefficients[i0], (int16_t)1441); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - self->coefficients[i0], &coefficient_normal_form)); - b.coefficients[i0] = uu____0; - } - return b; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR3( - i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - v, result); - return result; -} - -static inline void -compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - uint8_t ret[32U]) { - uint8_t serialized[32U] = {0U}; - KRML_MAYBE_FOR16( - i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re.coefficients[i0]); - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient_compressed = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( - coefficient); - uint8_t bytes[2U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( - coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *);); - memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[3U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[3U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___3size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - uint8_t dummy[32U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( - libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1152U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1184U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___3size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___3size_t_32size_t( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( - uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[4U], - uint8_t ret[1536U]) { - uint8_t out[1536U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1536U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)1536U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U], - Eurydice_slice seed_for_a, uint8_t ret[1568U]) { - uint8_t public_key_serialized[1568U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[4U]; - memcpy( - uu____1, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t ret0[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized, - (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1568size_t_4size_t( - Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[4U]; - memcpy( - uu____0, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___4size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_neon_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline Simd128Hash shake128_init_absorb___4size_t( - uint8_t input[4U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - uu____1, uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = &state[1U]; - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - uu____3, uu____4, - Eurydice_array_to_slice((size_t)34U, input[3U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy( - lit.shake128_state, state, - (size_t)2U * - sizeof( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___4size_t( - Simd128Hash *self, uint8_t ret[4U][504U]) { - uint8_t out[4U][504U] = {{0U}}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____3 = self->shake128_state; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____5 = &self->shake128_state[1U]; - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( - uint8_t randomness[4U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___4size_t(Simd128Hash *self, - uint8_t ret[4U][168U]) { - uint8_t out[4U][168U] = {{0U}}; - uint8_t out0[168U] = {0U}; - uint8_t out1[168U] = {0U}; - uint8_t out2[168U] = {0U}; - uint8_t out3[168U] = {0U}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - uu____0, uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &self->shake128_state[1U]; - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - uu____2, uu____3, - Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); - uint8_t uu____4[168U]; - memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); - memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____5[168U]; - memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); - memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____6[168U]; - memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); - memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____7[168U]; - memcpy(uu____7, out3, (size_t)168U * sizeof(uint8_t)); - memcpy(out[3U], uu____7, (size_t)168U * sizeof(uint8_t)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( - uint8_t randomness[4U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - uint8_t seeds[4U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - size_t sampled_coefficients[4U] = {0U}; - int16_t out[4U][272U] = {{0U}}; - uint8_t uu____0[4U][34U]; - memcpy(uu____0, seeds, (size_t)4U * sizeof(uint8_t[34U])); - Simd128Hash xof_state = shake128_init_absorb___4size_t(uu____0); - uint8_t randomness0[4U][504U]; - shake128_squeeze_three_blocks___4size_t(&xof_state, randomness0); - uint8_t uu____1[4U][504U]; - memcpy(uu____1, randomness0, (size_t)4U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[4U][168U]; - shake128_squeeze_block___4size_t(&xof_state, randomness); - uint8_t uu____2[4U][168U]; - memcpy(uu____2, randomness, (size_t)4U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[4U][272U]; - memcpy(uu____3, out, (size_t)4U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t0( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U][4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - A_transpose[i]);); - KRML_MAYBE_FOR4( - i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[4U][34U]; KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[4U][34U]; - memcpy(uu____1, seeds, (size_t)4U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[4U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [4U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[4U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t; - -static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[4U][128U]) { - uint8_t out[4U][128U] = {{0U}}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____3, uu____4, uu____5, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - Eurydice_slice uu____6 = - Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = - Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____6, uu____7, uu____8, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - re_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[4U]; - memcpy( - uu____2, re_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)16U, self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *matrix_A)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static K___uint8_t_1536size_t__uint8_t_1568size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___4size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[4U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - uu____3, domain_separator) - .fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[4U]; - memcpy( - uu____4, t_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[1568U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t_1568size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[4U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t secret_key_serialized[1536U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1536size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[1536U]; - memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); - uint8_t uu____7[1568U]; - memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - -static inline void H___4size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_neon_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)3168U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___4size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); -} - -libcrux_ml_kem_mlkem1024_MlKem1024KeyPair -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_3168size_t_1568size_t_1536size_t_2size_t_128size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[1536U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); - uint8_t public_key[1568U]; - memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)1536U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[3168U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t( - uu____1, - Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[3168U]; - memcpy(uu____2, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t uu____3 = private_key; - uint8_t uu____4[1568U]; - memcpy(uu____4, public_key, (size_t)1568U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___3168size_t_1568size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( - uu____4)); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - error_1[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[4U][33U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[4U][128U]; - PRFxN___4size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[4U]; - memcpy( - uu____2, error_1, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___4size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - uint8_t dummy[128U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *a_as_ntt)[4U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [4U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [4U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - error_2, message, result); - return result; -} - -static inline void -compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U]) { - uint8_t serialized[352U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficient = - compress___11int32_t0( - to_unsigned_representative__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); -} - -static inline void -compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re, - uint8_t ret[352U]) { - uint8_t uu____0[352U]; - compress_then_serialize_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_352size_t( - re, uu____0); - memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[4U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)4U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)1408U / (size_t)4U), - .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[352U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t_352size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)352U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void -compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re, - Eurydice_slice out) { - compress_then_serialize_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - re, out); -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[1568U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[4U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_1536size_t_4size_t( - Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)1536U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[4U][4U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_2size_t_128size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[4U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[4U]; - memcpy( - error_1, uu____3.fst, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___4size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[4U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[1568U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[4U]; - memcpy( - uu____5, u, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1408size_t_11size_t_352size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t_160size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___4size_t( - Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1568U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1568size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[1568U]; - memcpy(uu____4, ciphertext, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___1568size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_11__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - serialized); - return uu____0; -} - -static inline void -ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t zeta_i = (size_t)0U; - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)7U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(&zeta_i, - re); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - u_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)11U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_11size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - deserialize_then_decompress_5__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - serialized); - return uu____0; -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[4U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, - secret_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)4U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR4( - i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[4U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_11size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_5size_t( - Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, - (size_t)1408U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[4U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___4size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - uint8_t dummy[32U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_3168size_t_1536size_t_1568size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t_1600size_t( - libcrux_ml_kem_types_MlKemPrivateKey____3168size_t *private_key, - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)1536U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)1568U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___4size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___4size_t_32size_t( - Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1568U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_4size_t_1568size_t_1536size_t_1408size_t_160size_t_11size_t_5size_t_352size_t_2size_t_128size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1568size_t( - uu____7, Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - key[2U], - uint8_t ret[768U]) { - uint8_t out[768U] = {0U}; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)768U, out, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = (i0 + (size_t)1U) * - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[384U]; - serialize_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - } - memcpy(ret, out, (size_t)768U * sizeof(uint8_t)); -} - -static inline void -serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U], - Eurydice_slice seed_for_a, uint8_t ret[800U]) { - uint8_t public_key_serialized[800U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1[2U]; - memcpy( - uu____1, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t ret0[768U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( - uu____1, ret0); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)768U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized, - (size_t)768U, uint8_t, size_t, - Eurydice_slice), - seed_for_a, uint8_t, void *); - memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t)); -} - -bool libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_800size_t_2size_t( - Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0[2U]; - memcpy( - uu____0, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uu____0, - Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U, - uint8_t, size_t, Eurydice_slice), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( - (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool); -} - -static inline void G___2size_t(Eurydice_slice input, uint8_t ret[64U]) { - uint8_t digest[64U] = {0U}; - libcrux_sha3_neon_sha512( - Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); -} - -static void -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline Simd128Hash shake128_init_absorb___2size_t( - uint8_t input[2U][34U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - uu____0 = libcrux_sha3_neon_x2_incremental_shake128_init(); - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - state[2U] = {uu____0, libcrux_sha3_neon_x2_incremental_shake128_init()}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = state; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - uu____1, uu____2, - Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice)); - Simd128Hash lit; - memcpy( - lit.shake128_state, state, - (size_t)2U * - sizeof( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t)); - return lit; -} - -static inline void shake128_squeeze_three_blocks___2size_t( - Simd128Hash *self, uint8_t ret[2U][504U]) { - uint8_t out[2U][504U] = {{0U}}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____1 = self->shake128_state; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - uu____1, uu____2, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( - uint8_t randomness[2U][504U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static inline void shake128_squeeze_block___2size_t(Simd128Hash *self, - uint8_t ret[2U][168U]) { - uint8_t out[2U][168U] = {{0U}}; - uint8_t out0[168U] = {0U}; - uint8_t out1[168U] = {0U}; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = self->shake128_state; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - uu____0, uu____1, - Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice)); - uint8_t uu____2[168U]; - memcpy(uu____2, out0, (size_t)168U * sizeof(uint8_t)); - memcpy(out[0U], uu____2, (size_t)168U * sizeof(uint8_t)); - uint8_t uu____3[168U]; - memcpy(uu____3, out1, (size_t)168U * sizeof(uint8_t)); - memcpy(out[1U], uu____3, (size_t)168U * sizeof(uint8_t)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); -} - -static inline bool -sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( - uint8_t randomness[2U][168U], size_t *sampled_coefficients, - int16_t (*out)[272U]) { - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { - size_t r = i; - if (sampled_coefficients[i1] < - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ - .start = r * (size_t)24U, - .end = r * (size_t)24U + (size_t)24U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - size_t sampled = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - uu____0, - Eurydice_array_to_subslice( - (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ - .start = sampled_coefficients[i1], - .end = sampled_coefficients[i1] + (size_t)16U}), - int16_t, core_ops_range_Range__size_t, Eurydice_slice)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = - sampled_coefficients[uu____1] + sampled; - } - }); - bool done = true; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - if (sampled_coefficients[i0] >= - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - sampled_coefficients[i0] = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; - } else { done = false; }); - return done; -} - -static libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( - int16_t s[272U]) { - return from_i16_array__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)256U}), - int16_t, core_ops_range_Range__size_t, - Eurydice_slice)); -} - -static inline void -sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - uint8_t seeds[2U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - size_t sampled_coefficients[2U] = {0U}; - int16_t out[2U][272U] = {{0U}}; - uint8_t uu____0[2U][34U]; - memcpy(uu____0, seeds, (size_t)2U * sizeof(uint8_t[34U])); - Simd128Hash xof_state = shake128_init_absorb___2size_t(uu____0); - uint8_t randomness0[2U][504U]; - shake128_squeeze_three_blocks___2size_t(&xof_state, randomness0); - uint8_t uu____1[2U][504U]; - memcpy(uu____1, randomness0, (size_t)2U * sizeof(uint8_t[504U])); - bool done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_504size_t( - uu____1, sampled_coefficients, out); - while (true) { - if (done) { - break; - } else { - uint8_t randomness[2U][168U]; - shake128_squeeze_block___2size_t(&xof_state, randomness); - uint8_t uu____2[2U][168U]; - memcpy(uu____2, randomness, (size_t)2U * sizeof(uint8_t[168U])); - done = - sample_from_uniform_distribution_next__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_168size_t( - uu____2, sampled_coefficients, out); - } - } - int16_t uu____3[2U][272U]; - memcpy(uu____3, out, (size_t)2U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret0[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - ret0[i] = - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t0( - uu____3[i]);); - memcpy( - ret, ret0, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U][2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - closure__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - A_transpose[i]);); - KRML_MAYBE_FOR2( - i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0; - uint8_t uu____0[34U]; - memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); - uint8_t seeds[2U][34U]; KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t j = i; - seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); - uint8_t uu____1[2U][34U]; - memcpy(uu____1, seeds, (size_t)2U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sampled[2U]; - sample_from_xof__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - uu____1, sampled); - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - sample = sampled[j]; - if (transpose) { - A_transpose[j][i1] = sample; - } else { - A_transpose[i1][j] = sample; - } - }); - memcpy( - ret, A_transpose, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [2U])); -} - -typedef struct - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t_s { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - fst[2U]; - uint8_t snd; -} __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t; - -static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], - uint8_t ret[2U][192U]) { - uint8_t out[2U][192U] = {{0U}}; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], - Eurydice_slice), - (size_t)1U, uint8_t[192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____1, uu____2, uu____3, - Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], - uint8_t(*)[192U], uint8_t[192U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - Eurydice_slice randomness) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0; - uu____0 = - sample_from_binomial_distribution_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - randomness); - return uu____0; -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t -sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - re_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][192U]; - PRFxN___2size_t_192size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_3size_t( - Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - re_as_ntt[i0] = uu____1; - ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &re_as_ntt[i0]);); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[2U]; - memcpy( - uu____2, re_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void -add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *self, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *rhs) { - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)16U, self->coefficients, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector uu____0 = - libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - self->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; - } -} - -static inline void -compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *matrix_A)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = matrix_A[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *matrix_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - matrix_element, &s_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result[i1], &product); - } - add_standard_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static K___uint8_t_768size_t__uint8_t_800size_t_ -generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - G___2size_t(key_generation_seed, hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - (size_t)32U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice seed_for_A = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); - uint8_t uu____1[33U]; - memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____2 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - uu____1, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____2.snd; - uint8_t uu____3[33U]; - memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_as_ntt[2U]; - memcpy( - error_as_ntt, - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - uu____3, domain_separator) - .fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U]; - compute_As_plus_e__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____4[2U]; - memcpy( - uu____4, t_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t public_key_serialized[800U]; - serialize_public_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_800size_t( - uu____4, seed_for_A, public_key_serialized); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[2U]; - memcpy( - uu____5, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t secret_key_serialized[768U]; - serialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t( - uu____5, secret_key_serialized); - uint8_t uu____6[768U]; - memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); - uint8_t uu____7[800U]; - memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; - memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); - memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); - return lit; -} - -static inline void H___2size_t(Eurydice_slice input, uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - libcrux_sha3_neon_sha256( - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), - input); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -static inline void -serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( - Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; - size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; - size_t uu____1 = pointer; - size_t uu____2 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ - .start = uu____1, - .end = uu____2 + - core_slice___Slice_T___len(private_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - private_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); - uint8_t *uu____3 = out; - size_t uu____4 = pointer; - size_t uu____5 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ - .start = uu____4, - .end = uu____5 + - core_slice___Slice_T___len(public_key, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - public_key, uint8_t, void *); - pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice( - (size_t)1632U, out, - ((core_ops_range_Range__size_t){ - .start = pointer, - .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret0[32U]; - H___2size_t(public_key, ret0); - core_slice___Slice_T___copy_from_slice( - uu____6, - Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), - uint8_t, void *); - pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; - size_t uu____8 = pointer; - size_t uu____9 = pointer; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice( - (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ - .start = uu____8, - .end = uu____9 + core_slice___Slice_T___len( - implicit_rejection_value, uint8_t, size_t)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - implicit_rejection_value, uint8_t, void *); - memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); -} - -libcrux_ml_kem_types_MlKemKeyPair____1632size_t__800size_t -libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_1632size_t_800size_t_768size_t_3size_t_192size_t( - uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( - (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = - generate_keypair__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( - ind_cpa_keypair_randomness); - uint8_t ind_cpa_private_key[768U]; - memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t)); - uint8_t public_key[800U]; - memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t)); - Eurydice_slice uu____1 = Eurydice_array_to_slice( - (size_t)768U, ind_cpa_private_key, uint8_t, Eurydice_slice); - uint8_t secret_key_serialized[1632U]; - serialize_kem_secret_key__libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t( - uu____1, - Eurydice_array_to_slice((size_t)800U, public_key, uint8_t, - Eurydice_slice), - implicit_rejection_value, secret_key_serialized); - uint8_t uu____2[1632U]; - memcpy(uu____2, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t private_key = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( - uu____2); - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t uu____3 = private_key; - uint8_t uu____4[800U]; - memcpy(uu____4, public_key, (size_t)800U * sizeof(uint8_t)); - return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___1632size_t_800size_t( - uu____3, - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( - uu____4)); -} - -static inline void -deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - deserialized_pk[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - deserialized_pk[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice( - public_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], - uint8_t ret[2U][128U]) { - uint8_t out[2U][128U] = {{0U}}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____1, uu____2, uu____3, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); - memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); -} - -static inline __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t -sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( - uint8_t prf_input[33U], uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - error_1[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - uint8_t prf_inputs[2U][33U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); - uint8_t prf_outputs[2U][128U]; - PRFxN___2size_t_128size_t(prf_inputs, prf_outputs); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____1 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], - uint8_t, Eurydice_slice)); - error_1[i0] = uu____1;); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____2[2U]; - memcpy( - uu____2, error_1, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - lit; - memcpy( - lit.fst, uu____2, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - lit.snd = domain_separator; - return lit; -} - -static inline void PRF___2size_t_128size_t(Eurydice_slice input, - uint8_t ret[128U]) { - uint8_t digest[128U] = {0U}; - uint8_t dummy[128U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)128U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); -} - -static inline void -invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *re) { - size_t zeta_i = - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - invert_ntt_at_layer_1__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_2__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_3__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)4U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)5U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)6U); - invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &zeta_i, re, (size_t)7U); - poly_barrett_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(re); -} - -static inline void -compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector ( - *a_as_ntt)[2U], - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - result[i] = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for ( - size_t i0 = (size_t)0U; - i0 < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [2U], - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - [2U], - size_t); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *row = a_as_ntt[i1]; - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - a_element, &r_as_ntt[j]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result[i1], &product); - } - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result[i1]); - add_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &result[i1], &error_1[i1]); - } - memcpy( - ret, result, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &t_as_ntt[i0], &r_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result); - result = - add_message_error_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - error_2, message, result); - return result; -} - -static void -compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - input[2U], - Eurydice_slice out) { - for ( - size_t i = (size_t)0U; - i < - core_slice___Slice_T___len( - Eurydice_array_to_slice( - (size_t)2U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - Eurydice_slice), - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector, - size_t); - i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice( - out, - ((core_ops_range_Range__size_t){ - .start = i0 * ((size_t)640U / (size_t)2U), - .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - uint8_t ret[320U]; - compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t_320size_t( - &re, ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - } -} - -static void -encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, - uint8_t ret[768U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - t_as_ntt[2U]; - deserialize_ring_elements_reduced__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_768size_t_2size_t( - Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t, - Eurydice_slice), - t_as_ntt); - Eurydice_slice seed = Eurydice_slice_subslice_from( - public_key, (size_t)768U, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - A_transpose[2U][2U]; - uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); - sample_matrix_A__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t( - ret0, false, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); - uint8_t uu____0[33U]; - memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____1 = - sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_3size_t_192size_t( - uu____0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - r_as_ntt[2U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator0 = uu____1.snd; - uint8_t uu____2[33U]; - memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); - __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t__uint8_t - uu____3 = - sample_ring_element_cbd__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_128size_t_2size_t( - uu____2, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_1[2U]; - memcpy( - error_1, uu____3.fst, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - PRF___2size_t_128size_t( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), - prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - error_2 = - sample_from_binomial_distribution__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u[2U]; - compute_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - A_transpose, r_as_ntt, error_1, u); - uint8_t uu____4[32U]; - memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message_as_ring_element = - deserialize_then_decompress_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - uu____4); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = compute_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); - uint8_t ciphertext[768U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____5[2U]; - memcpy( - uu____5, u, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); - compress_then_serialize_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_640size_t_10size_t_320size_t( - uu____5, Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____6 = v; - compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t_128size_t( - uu____6, - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, - uint8_t, size_t, Eurydice_slice)); - memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); -} - -K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ -libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_800size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, - uint8_t randomness[32U]) { - uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), - to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t, Eurydice_slice); - uint8_t ret[32U]; - H___2size_t( - Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice), - ret); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), - uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)800U, - libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___800size_t( - public_key), - uint8_t, Eurydice_slice); - uint8_t uu____3[32U]; - memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); - uint8_t ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____2, uu____3, pseudorandomness, ciphertext); - uint8_t shared_secret_array[32U] = {0U}; - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, - Eurydice_slice), - shared_secret, uint8_t, void *); - uint8_t uu____4[768U]; - memcpy(uu____4, ciphertext, (size_t)768U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemCiphertext____768size_t uu____5 = - libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( - uu____4); - uint8_t uu____6[32U]; - memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - K___libcrux_ml_kem_types_MlKemCiphertext___768size_t___uint8_t_32size_t_ lit; - lit.fst = uu____5; - memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); - return lit; -} - -static inline void -deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( - uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - u_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len( - Eurydice_array_to_slice((size_t)768U, ciphertext, uint8_t, - Eurydice_slice), - uint8_t, size_t) / - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U); - i++) { - size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice( - (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ - .start = - i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U), - .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U) + - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * - (size_t)10U / (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - u_bytes); - u_as_ntt[i0] = uu____0; - ntt_vector_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_10size_t( - &u_as_ntt[i0]); - } - memcpy( - ret, u_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline void -deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - ret[2U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, - secret_as_ntt[i] = - ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector();); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice( - secret_key, - ((core_ops_range_Range__size_t){ - .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - uu____0 = - deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - secret_bytes); - secret_as_ntt[i0] = uu____0; - } - memcpy( - ret, secret_as_ntt, - (size_t)2U * - sizeof( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector)); -} - -static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *v, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - result = ZERO__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector(); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - product = - ntt_multiply__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - &secret_as_ntt[i0], &u_as_ntt[i0]); - add_to_ring_element__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result, &product);); - invert_ntt_montgomery__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &result); - result = subtract_reduce__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - v, result); - return result; -} - -static void -decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - u_as_ntt[2U]; - deserialize_then_decompress_u__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_10size_t( - ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - v = deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_4size_t( - Eurydice_array_to_subslice_from((size_t)768U, ciphertext, - (size_t)640U, uint8_t, size_t, - Eurydice_slice)); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - secret_as_ntt[2U]; - deserialize_secret_key__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - secret_key, secret_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector - message = - compute_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t( - &v, secret_as_ntt, u_as_ntt); - uint8_t ret0[32U]; - compress_then_serialize_message__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector( - message, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} - -static inline void PRF___2size_t_32size_t(Eurydice_slice input, - uint8_t ret[32U]) { - uint8_t digest[32U] = {0U}; - uint8_t dummy[32U] = {0U}; - Eurydice_slice uu____0 = input; - Eurydice_slice uu____1 = input; - Eurydice_slice uu____2 = - Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice); - libcrux_sha3_neon_x2_shake256( - uu____0, uu____1, uu____2, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)); - memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); -} - -void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_1632size_t_768size_t_800size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t_800size_t( - libcrux_ml_kem_types_MlKemPrivateKey____1632size_t *private_key, - libcrux_ml_kem_types_MlKemCiphertext____768size_t *ciphertext, - uint8_t ret[32U]) { - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t, - Eurydice_slice), - (size_t)768U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at( - secret_key0, (size_t)800U, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = - core_slice___Slice_T___split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - decrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_2size_t_768size_t_640size_t_10size_t_4size_t( - ind_cpa_secret_key, ciphertext->value, decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), - to_hash0); - core_slice___Slice_T___copy_from_slice( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice), - ind_cpa_public_key_hash, uint8_t, void *); - uint8_t hashed[64U]; - G___2size_t( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), - hashed); - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = - core_slice___Slice_T___split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice shared_secret = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____4, - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext), - uint8_t, void *); - uint8_t implicit_rejection_shared_secret[32U]; - PRF___2size_t_32size_t( - Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t, Eurydice_slice), - implicit_rejection_shared_secret); - Eurydice_slice uu____5 = ind_cpa_public_key; - uint8_t uu____6[32U]; - memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[768U]; - encrypt__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_libcrux_ml_kem_hash_functions_neon_Simd128Hash_2size_t_768size_t_768size_t_640size_t_128size_t_10size_t_4size_t_320size_t_3size_t_192size_t_2size_t_128size_t( - uu____5, uu____6, pseudorandomness, expected_ciphertext); - Eurydice_slice uu____7 = - libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( - ciphertext); - uint8_t selector = - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( - uu____7, Eurydice_array_to_slice((size_t)768U, expected_ciphertext, - uint8_t, Eurydice_slice)); - Eurydice_slice uu____8 = shared_secret; - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( - uu____8, - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t, Eurydice_slice), - selector, ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); -} diff --git a/libcrux-ml-kem/c/libcrux_mlkem_neon.h b/libcrux-ml-kem/c/libcrux_mlkem_neon.h deleted file mode 100644 index 172520803..000000000 --- a/libcrux-ml-kem/c/libcrux_mlkem_neon.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL - version: 40e3a603 - */ - -#ifndef __libcrux_mlkem_neon_H -#define __libcrux_mlkem_neon_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include "eurydice_glue.h" -#include "libcrux_core.h" -#include "libcrux_mlkem_portable.h" -#include "libcrux_sha3_neon.h" - -typedef struct libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { - core_core_arch_arm_shared_neon_int16x8_t low; - core_core_arch_arm_shared_neon_int16x8_t high; -} libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ZERO(void); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ZERO( - void); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_from_i16_array(Eurydice_slice array); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___from_i16_array( - Eurydice_slice array); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___add( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___sub( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___bitwise_and_with_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___cond_subtract_3329( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -#define LIBCRUX_ML_KEM_VECTOR_NEON_SIMD128OPS_BARRETT_MULTIPLIER \ - ((int16_t)20159) - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___barrett_reduce( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_reduce_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t low, - core_core_arch_arm_shared_neon_int16x8_t high); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___montgomery_multiply_by_constant( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___compress_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v); - -int16_t libcrux_ml_kem_vector_neon_simd128ops_mask_n_least_significant_bits( - int16_t coefficient_bits); - -core_core_arch_arm_shared_neon_int16x8_t -libcrux_ml_kem_vector_neon_simd128ops_montgomery_multiply_int16x8_t( - core_core_arch_arm_shared_neon_int16x8_t v, - core_core_arch_arm_shared_neon_int16x8_t c); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_1_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta1, - int16_t zeta2); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_2_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta1, - int16_t zeta2); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t zeta); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___inv_ntt_layer_3_step( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, int16_t zeta); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___ntt_multiply( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *lhs, - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *rhs, int16_t zeta1, - int16_t zeta2, int16_t zeta3, int16_t zeta4); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[2U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_1( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[2U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_1(Eurydice_slice a); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_1( - Eurydice_slice a); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[8U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_4( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[8U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_4(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_4( - Eurydice_slice a); - -void libcrux_ml_kem_vector_neon_simd128ops_to_i16_array( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, int16_t ret[16U]); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[10U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_5( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[10U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_5(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_5( - Eurydice_slice a); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[20U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_10( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[20U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_10(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_10( - Eurydice_slice a); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[22U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_11( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[22U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_11(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_11( - Eurydice_slice a); - -void libcrux_ml_kem_vector_neon_simd128ops_serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector v, uint8_t ret[24U]); - -void libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___serialize_12( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector a, uint8_t ret[24U]); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops_deserialize_12(Eurydice_slice v); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___deserialize_12( - Eurydice_slice a); - -size_t libcrux_ml_kem_vector_neon_rej_sample(Eurydice_slice a, - Eurydice_slice result); - -size_t -libcrux_ml_kem_vector_neon___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___rej_sample( - Eurydice_slice a, Eurydice_slice out); - -libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector -libcrux_ml_kem_vector_neon_simd128ops___core__clone__Clone_for_libcrux_ml_kem__vector__neon__simd128ops__SIMD128Vector___clone( - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector *self); - -typedef struct - libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector_s { - libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector coefficients[16U]; -} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_neon_simd128ops_SIMD128Vector; - -#if defined(__cplusplus) -} -#endif - -#define __libcrux_mlkem_neon_H_DEFINED -#endif diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 30688d413..eeba8ebb1 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_mlkem_portable.h" @@ -595,7 +595,7 @@ libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) { Eurydice_slice_to_array2( &dst, Eurydice_slice_subslice(array, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -691,7 +691,7 @@ libcrux_ml_kem_vector_cond_subtract_3329( libcrux_ml_kem_vector_portable_PortableVector v) { core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); @@ -1180,7 +1180,7 @@ inline K___int16_t_int16_t libcrux_ml_kem_vector_ntt_multiply_binomials( uu____0 + (int32_t)libcrux_ml_kem_vector_montgomery_reduce_element( (int32_t)a1 * (int32_t)b1) * (int32_t)zeta); - return ((K___int16_t_int16_t){ + return (CLITERAL(K___int16_t_int16_t){ .fst = uu____1, .snd = libcrux_ml_kem_vector_montgomery_reduce_element( (int32_t)a0 * (int32_t)b1 + (int32_t)a1 * (int32_t)b0)}); @@ -2237,8 +2237,8 @@ deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVect size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector coefficient = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( @@ -2268,7 +2268,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -2329,8 +2329,8 @@ serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVect coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)384U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)24U * i0, - .end = (size_t)24U * i0 + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, .end = (size_t)24U * i0 + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -2362,7 +2362,7 @@ serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536 re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1536U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -2386,8 +2386,8 @@ serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1536 uint8_t public_key_serialized[1568U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1568U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1536U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1536U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____1[4U]; @@ -2515,7 +2515,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2524,7 +2524,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -2569,7 +2569,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2578,7 +2578,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -2610,7 +2610,7 @@ from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( Eurydice_slice_subslice( a, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (size_t)16U, .end = (i0 + (size_t)1U) * (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -2624,7 +2624,7 @@ closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -2761,7 +2761,7 @@ sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVect size_t chunk_number = i0; Eurydice_slice byte_chunk = Eurydice_slice_subslice( randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = chunk_number * (size_t)4U, .end = chunk_number * (size_t)4U + (size_t)4U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2809,7 +2809,7 @@ sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVect size_t chunk_number = i0; Eurydice_slice byte_chunk = Eurydice_slice_subslice( randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = chunk_number * (size_t)3U, .end = chunk_number * (size_t)3U + (size_t)3U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -2900,7 +2900,7 @@ ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( a, &t); a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( a, &t); - return (( + return (CLITERAL( __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ .fst = a, .snd = b}); } @@ -3307,7 +3307,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -3320,7 +3320,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -3329,7 +3329,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)3168U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3346,7 +3346,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)3168U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -3360,7 +3360,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3414,7 +3414,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -3551,7 +3551,7 @@ inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector a, &b)); b = montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( a_minus_b, zeta_r); - return (( + return (CLITERAL( __libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ .fst = a, .snd = b}); } @@ -3714,7 +3714,7 @@ deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVect libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( Eurydice_array_to_subslice( (size_t)32U, serialized, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -3832,8 +3832,8 @@ compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_352siz coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)352U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)22U * i0, - .end = (size_t)22U * i0 + (size_t)22U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -3875,7 +3875,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)1408U / (size_t)4U), .end = (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -3923,8 +3923,8 @@ compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector( coefficient, bytes); Eurydice_slice uu____0 = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -3967,8 +3967,8 @@ compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector( coefficients, bytes); Eurydice_slice uu____0 = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = (size_t)10U * i0, - .end = (size_t)10U * i0 + (size_t)10U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, .end = (size_t)10U * i0 + (size_t)10U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -4068,8 +4068,8 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1408size_t_11size_t_352size_t( uu____5, Eurydice_array_to_subslice( (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1408U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)1408U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____6 = v; @@ -4175,8 +4175,8 @@ deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)20U, - .end = i0 * (size_t)20U + (size_t)20U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, .end = i0 * (size_t)20U + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector coefficient = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( @@ -4221,8 +4221,8 @@ deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)22U, - .end = i0 * (size_t)22U + (size_t)22U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, .end = i0 * (size_t)22U + (size_t)22U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector coefficient = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( @@ -4285,7 +4285,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_4si size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)1568U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)11U / (size_t)8U), @@ -4341,8 +4341,8 @@ deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)8U, - .end = i0 * (size_t)8U + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, .end = i0 * (size_t)8U + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector coefficient = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( @@ -4387,8 +4387,8 @@ deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)10U, - .end = i0 * (size_t)10U + (size_t)10U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, .end = i0 * (size_t)10U + (size_t)10U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector uu____0 = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( @@ -4424,8 +4424,8 @@ deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_Portabl size_t i0 = i; Eurydice_slice bytes = Eurydice_slice_subslice( serialized, - ((core_ops_range_Range__size_t){.start = i0 * (size_t)24U, - .end = i0 * (size_t)24U + (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_vector_portable_PortableVector uu____0 = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( @@ -4452,7 +4452,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_4size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4534,8 +4534,8 @@ compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( coefficient_compressed, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)32U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)2U * i0, - .end = (size_t)2U * i0 + (size_t)2U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -4681,7 +4681,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4721,7 +4721,7 @@ serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152 re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1152U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -4745,8 +4745,8 @@ serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152 uint8_t public_key_serialized[1184U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)1184U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)1152U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____1[3U]; @@ -4874,7 +4874,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -4883,7 +4883,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -4928,7 +4928,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -4937,7 +4937,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -4962,7 +4962,7 @@ closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -5319,7 +5319,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -5332,7 +5332,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -5341,7 +5341,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)2400U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5358,7 +5358,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)2400U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -5372,7 +5372,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5426,7 +5426,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -5629,8 +5629,8 @@ compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320siz coefficient, bytes); Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)320U, serialized, - ((core_ops_range_Range__size_t){.start = (size_t)20U * i0, - .end = (size_t)20U * i0 + (size_t)20U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____0, @@ -5672,7 +5672,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)960U / (size_t)3U), .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -5777,8 +5777,8 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)960U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)960U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____6 = v; @@ -5902,7 +5902,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3si size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)1088U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), @@ -5954,7 +5954,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -6132,7 +6132,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -6172,7 +6172,7 @@ serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768s re = key[i0]; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)768U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -6196,8 +6196,8 @@ serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768s uint8_t public_key_serialized[800U] = {0U}; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)800U, public_key_serialized, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)768U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)768U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____1[2U]; @@ -6325,7 +6325,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)504U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6334,7 +6334,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6379,7 +6379,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)168U, randomness[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = r * (size_t)24U, .end = r * (size_t)24U + (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6388,7 +6388,7 @@ sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVe uu____0, Eurydice_array_to_subslice( (size_t)272U, out[i1], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = sampled_coefficients[i1], .end = sampled_coefficients[i1] + (size_t)16U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6413,7 +6413,7 @@ closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct int16_t s[272U]) { return from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( Eurydice_array_to_subslice((size_t)272U, s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)256U}), int16_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -6781,7 +6781,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____1, .end = uu____2 + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), @@ -6794,7 +6794,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____3, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____4, .end = uu____5 + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), @@ -6803,7 +6803,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)1632U, out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = pointer, .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6820,7 +6820,7 @@ serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___ core_slice___Slice_T___copy_from_slice( Eurydice_array_to_subslice( (size_t)1632U, uu____7, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = uu____8, .end = uu____9 + core_slice___Slice_T___len( implicit_rejection_value, uint8_t, size_t)}), @@ -6834,7 +6834,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable uint8_t randomness[64U]) { Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( (size_t)64U, randomness, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -6888,7 +6888,7 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector size_t i0 = i; Eurydice_slice ring_element = Eurydice_slice_subslice( public_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), @@ -7107,7 +7107,7 @@ compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t re = input[i0]; Eurydice_slice uu____0 = Eurydice_slice_subslice( out, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * ((size_t)640U / (size_t)2U), .end = (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); @@ -7203,8 +7203,8 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_2size_t_640size_t_10size_t_320size_t( uu____5, Eurydice_array_to_subslice( (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)640U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)640U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector uu____6 = v; @@ -7298,7 +7298,7 @@ deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_2si size_t i0 = i; Eurydice_slice u_bytes = Eurydice_array_to_subslice( (size_t)768U, ciphertext, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), @@ -7339,7 +7339,7 @@ deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_2size_t( size_t i0 = i; Eurydice_slice secret_bytes = Eurydice_slice_subslice( secret_key, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index 078c0cbd3..02b989972 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 87bfd1a1a..36ca19e89 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 49e0302b8..456891376 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #include "internal/libcrux_sha3_avx2.h" @@ -88,23 +88,27 @@ static inline void slice_4(Eurydice_slice a[4U], size_t start, size_t len, Eurydice_slice ret[4U]) { Eurydice_slice uu____0 = Eurydice_slice_subslice( a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); Eurydice_slice uu____1 = Eurydice_slice_subslice( a[1U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); Eurydice_slice uu____2 = Eurydice_slice_subslice( a[2U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); ret[0U] = uu____0; ret[1U] = uu____1; ret[2U] = uu____2; - ret[3U] = Eurydice_slice_subslice( - a[3U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[3U] = Eurydice_slice_subslice(a[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice); } static inline void slice_n(Eurydice_slice a[4U], size_t start, size_t len, @@ -202,28 +206,28 @@ static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], core_core_arch_x86___m256i v00 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v10 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v20 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v30 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -278,50 +282,52 @@ static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], uint8_t u8s[32U] = {0U}; Eurydice_slice uu____4 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____5 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____5, Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____7 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____7, Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -338,54 +344,54 @@ static inline void load_block___136size_t(core_core_arch_x86___m256i (*s)[5U], uint8_t u8s0[32U] = {0U}; Eurydice_slice uu____9 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____9, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____10 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____10, Eurydice_slice_subslice( blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____11 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____11, Eurydice_slice_subslice( blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____12 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____12, Eurydice_slice_subslice( blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); core_core_arch_x86___m256i u0 = @@ -1103,8 +1109,8 @@ absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); @@ -1162,7 +1168,7 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1170,7 +1176,7 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], v0); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1178,7 +1184,7 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], v1); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1186,7 +1192,7 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], v2); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1203,52 +1209,52 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); Eurydice_slice uu____1 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____1, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____2 = Eurydice_slice_subslice( out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____2, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____3 = Eurydice_slice_subslice( out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____3, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____4 = Eurydice_slice_subslice( out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -1264,54 +1270,54 @@ static inline void store_block___136size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); Eurydice_slice uu____6 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____7 = Eurydice_slice_subslice( out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____7, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____8 = Eurydice_slice_subslice( out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____8, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____9 = Eurydice_slice_subslice( out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____9, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); } @@ -1461,8 +1467,8 @@ keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t(&s, o0); core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -1507,28 +1513,28 @@ static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], core_core_arch_x86___m256i v00 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v10 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v20 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); core_core_arch_x86___m256i v30 = libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( blocks[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); @@ -1583,50 +1589,52 @@ static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], uint8_t u8s[32U] = {0U}; Eurydice_slice uu____4 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)0U, .end = (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, Eurydice_slice_subslice(blocks[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____5 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)8U, .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____5, Eurydice_slice_subslice(blocks[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____6 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_slice_subslice(blocks[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____7 = Eurydice_array_to_subslice( (size_t)32U, u8s, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____7, Eurydice_slice_subslice(blocks[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = start, .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -1643,54 +1651,54 @@ static inline void load_block___168size_t(core_core_arch_x86___m256i (*s)[5U], uint8_t u8s0[32U] = {0U}; Eurydice_slice uu____9 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____9, Eurydice_slice_subslice( blocks[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____10 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____10, Eurydice_slice_subslice( blocks[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____11 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____11, Eurydice_slice_subslice( blocks[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____12 = Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____12, Eurydice_slice_subslice( blocks[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); core_core_arch_x86___m256i u0 = @@ -1740,8 +1748,8 @@ libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i0], uint8_t, void *); @@ -1809,7 +1817,7 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1817,7 +1825,7 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], v0); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1825,7 +1833,7 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], v1); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[2U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1833,7 +1841,7 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], v2); libcrux_intrinsics_avx2_mm256_storeu_si256_u8( Eurydice_slice_subslice(out[3U], - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)32U * i0, .end = (size_t)32U * (i0 + (size_t)1U)}), uint8_t, core_ops_range_Range__size_t, @@ -1850,52 +1858,52 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); Eurydice_slice uu____1 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____1, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____2 = Eurydice_slice_subslice( out[1U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____2, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)8U, .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____3 = Eurydice_slice_subslice( out[2U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____3, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)16U, .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____4 = Eurydice_slice_subslice( out[3U], - ((core_ops_range_Range__size_t){.start = start, - .end = start + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____4, Eurydice_array_to_subslice((size_t)32U, u8s, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)24U, .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), @@ -1911,54 +1919,54 @@ static inline void store_block___168size_t(core_core_arch_x86___m256i (*s)[5U], libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); Eurydice_slice uu____6 = Eurydice_slice_subslice( out[0U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____6, Eurydice_array_to_subslice((size_t)32U, u8s0, - ((core_ops_range_Range__size_t){ + (CLITERAL(core_ops_range_Range__size_t){ .start = (size_t)0U, .end = (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____7 = Eurydice_slice_subslice( out[1U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____7, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____8 = Eurydice_slice_subslice( out[2U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____8, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)16U, - .end = (size_t)24U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); Eurydice_slice uu____9 = Eurydice_slice_subslice( out[3U], - ((core_ops_range_Range__size_t){.start = start + (size_t)8U, - .end = start + (size_t)16U}), + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice( uu____9, Eurydice_array_to_subslice( (size_t)32U, u8s0, - ((core_ops_range_Range__size_t){.start = (size_t)24U, - .end = (size_t)32U}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice), uint8_t, void *); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 2f9e86a7b..28d49028b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 360486d5e..ec88e43b6 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: - KaRaMeL version: 40e3a603 + KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL + version: 40e3a603 */ #ifndef __libcrux_sha3_internal_H @@ -110,10 +110,11 @@ libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u6 static inline void libcrux_sha3_portable_keccak_slice_1( Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { - ret[0U] = Eurydice_slice_subslice( - a[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[0U] = Eurydice_slice_subslice(a[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice); } static inline void @@ -895,7 +896,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; @@ -916,8 +918,8 @@ static inline void libcrux_sha3_portable_keccak_store_block___168size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); @@ -1087,7 +1089,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -1193,7 +1195,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -1214,8 +1217,8 @@ static inline void libcrux_sha3_portable_keccak_store_block___104size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); @@ -1364,7 +1367,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -1470,7 +1473,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -1491,8 +1495,8 @@ static inline void libcrux_sha3_portable_keccak_store_block___144size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); @@ -1641,7 +1645,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -1747,7 +1751,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 31U; @@ -1768,8 +1773,8 @@ static inline void libcrux_sha3_portable_keccak_store_block___136size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); @@ -1918,7 +1923,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -1963,7 +1968,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -2026,7 +2032,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( @@ -2132,7 +2138,8 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( size_t i = (size_t)0U; Eurydice_slice uu____0 = Eurydice_array_to_subslice( (size_t)200U, blocks[i], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, .end = last_len}), + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); blocks[i][last_len] = 6U; @@ -2153,8 +2160,8 @@ static inline void libcrux_sha3_portable_keccak_store_block___72size_t( size_t i0 = i; Eurydice_slice uu____0 = Eurydice_slice_subslice( out[0U], - (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U * i0, - .end = (size_t)8U * i0 + (size_t)8U}), + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), uint8_t, core_ops_range_Range__size_t, Eurydice_slice); uint8_t ret[8U]; core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); @@ -2303,7 +2310,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( core_ops_range_Range__size_t iter = core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), + .end = blocks}), core_ops_range_Range__size_t, core_ops_range_Range__size_t); while (true) { if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 8d215805c..b9aa5c77b 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,7 +1,7 @@ /* This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL version: 40e3a603 */ @@ -9,2877 +9,179 @@ #include "internal/libcrux_core.h" -static inline core_core_arch_arm_shared_neon_uint64x2_t zero(void) { - return libcrux_intrinsics_arm64__vdupq_n_u64(0ULL); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t _veor5q_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c, - core_core_arch_arm_shared_neon_uint64x2_t d, - core_core_arch_arm_shared_neon_uint64x2_t e) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - core_core_arch_arm_shared_neon_uint64x2_t cd = - libcrux_intrinsics_arm64__veorq_u64(c, d); - core_core_arch_arm_shared_neon_uint64x2_t abcd = - libcrux_intrinsics_arm64__veorq_u64(ab, cd); - return libcrux_intrinsics_arm64__veorq_u64(abcd, e); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t xor5( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c, - core_core_arch_arm_shared_neon_uint64x2_t d, - core_core_arch_arm_shared_neon_uint64x2_t e) { - return _veor5q_u64(a, b, c, d, e); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)1, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)63, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t _vrax1q_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, rotate_left___1int32_t_63int32_t(b)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t rotate_left1_and_xor( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vrax1q_u64(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t _vbcaxq_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = a; - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vbicq_u64(b, c)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t and_not_xor( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b, - core_core_arch_arm_shared_neon_uint64x2_t c) { - return _vbcaxq_u64(a, b, c); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t _veorq_n_u64( - core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) { - core_core_arch_arm_shared_neon_uint64x2_t c0 = - libcrux_intrinsics_arm64__vdupq_n_u64(c); - return libcrux_intrinsics_arm64__veorq_u64(a, c0); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t xor_constant( - core_core_arch_arm_shared_neon_uint64x2_t a, uint64_t c) { - return _veorq_n_u64(a, c); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t xor0( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return libcrux_intrinsics_arm64__veorq_u64(a, b); -} - -static inline void slice_2(Eurydice_slice a[2U], size_t start, size_t len, - Eurydice_slice ret[2U]) { - Eurydice_slice uu____0 = Eurydice_slice_subslice( - a[0U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - ret[0U] = uu____0; - ret[1U] = Eurydice_slice_subslice( - a[1U], - ((core_ops_range_Range__size_t){.start = start, .end = start + len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); -} - -static inline void slice_n(Eurydice_slice a[2U], size_t start, size_t len, - Eurydice_slice ret[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, a, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret0[2U]; - slice_2(uu____0, start, len, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(Eurydice_slice)); -} - -static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ -split_at_mut_2(Eurydice_slice out[2U], size_t mid) { - Eurydice_slice out0 = out[0U]; - Eurydice_slice out1 = out[1U]; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = - core_slice___Slice_T___split_at_mut( - out0, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = - core_slice___Slice_T___split_at_mut( - out1, mid, uint8_t, - K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); - Eurydice_slice out10 = uu____1.fst; - Eurydice_slice out11 = uu____1.snd; - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ lit; - lit.fst[0U] = out00; - lit.fst[1U] = out10; - lit.snd[0U] = out01; - lit.snd[1U] = out11; - return lit; -} - -static inline K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ -split_at_mut_n(Eurydice_slice a[2U], size_t mid) { - return split_at_mut_2(a, mid); -} - -static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t -new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(void) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - lit; - lit.st[0U][0U] = zero(); - lit.st[0U][1U] = zero(); - lit.st[0U][2U] = zero(); - lit.st[0U][3U] = zero(); - lit.st[0U][4U] = zero(); - lit.st[1U][0U] = zero(); - lit.st[1U][1U] = zero(); - lit.st[1U][2U] = zero(); - lit.st[1U][3U] = zero(); - lit.st[1U][4U] = zero(); - lit.st[2U][0U] = zero(); - lit.st[2U][1U] = zero(); - lit.st[2U][2U] = zero(); - lit.st[2U][3U] = zero(); - lit.st[2U][4U] = zero(); - lit.st[3U][0U] = zero(); - lit.st[3U][1U] = zero(); - lit.st[3U][2U] = zero(); - lit.st[3U][3U] = zero(); - lit.st[3U][4U] = zero(); - lit.st[4U][0U] = zero(); - lit.st[4U][1U] = zero(); - lit.st[4U][2U] = zero(); - lit.st[4U][3U] = zero(); - lit.st[4U][4U] = zero(); - return lit; -} - -static inline void load_block___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U]) { - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - libcrux_intrinsics_arm64__veorq_u64( - uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; - } - if ((size_t)72U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = {0U}; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2( - &dst0, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, - .end = (size_t)72U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst0, ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, - .end = (size_t)72U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t uvec = - libcrux_intrinsics_arm64__vld1q_u64( - Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void load_block___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); - load_block___72size_t(uu____0, uu____1); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)36, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)28, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___36int32_t_28int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___36int32_t_28int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___36int32_t_28int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___36int32_t_28int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)3, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)61, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___3int32_t_61int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___3int32_t_61int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___3int32_t_61int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___3int32_t_61int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)41, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)23, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___41int32_t_23int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___41int32_t_23int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___41int32_t_23int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___41int32_t_23int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)18, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)46, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___18int32_t_46int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___18int32_t_46int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___18int32_t_46int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___18int32_t_46int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___1int32_t_63int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___1int32_t_63int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___1int32_t_63int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___1int32_t_63int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)44, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)20, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___44int32_t_20int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___44int32_t_20int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___44int32_t_20int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___44int32_t_20int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)10, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)54, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___10int32_t_54int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___10int32_t_54int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___10int32_t_54int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___10int32_t_54int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)45, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)19, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___45int32_t_19int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___45int32_t_19int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___45int32_t_19int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___45int32_t_19int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)2, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)62, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___2int32_t_62int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___2int32_t_62int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___2int32_t_62int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___2int32_t_62int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)62, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)2, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___62int32_t_2int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___62int32_t_2int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___62int32_t_2int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___62int32_t_2int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)6, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)58, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___6int32_t_58int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___6int32_t_58int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___6int32_t_58int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___6int32_t_58int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)43, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)21, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___43int32_t_21int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___43int32_t_21int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___43int32_t_21int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___43int32_t_21int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)15, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)49, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___15int32_t_49int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___15int32_t_49int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___15int32_t_49int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___15int32_t_49int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)61, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)3, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___61int32_t_3int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___61int32_t_3int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___61int32_t_3int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___61int32_t_3int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)28, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)36, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___28int32_t_36int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___28int32_t_36int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___28int32_t_36int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___28int32_t_36int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)55, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)9, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___55int32_t_9int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___55int32_t_9int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___55int32_t_9int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___55int32_t_9int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)25, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)39, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___25int32_t_39int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___25int32_t_39int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___25int32_t_39int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___25int32_t_39int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)21, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)43, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___21int32_t_43int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___21int32_t_43int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___21int32_t_43int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___21int32_t_43int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)56, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)8, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___56int32_t_8int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___56int32_t_8int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___56int32_t_8int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___56int32_t_8int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)27, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)37, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___27int32_t_37int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___27int32_t_37int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___27int32_t_37int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___27int32_t_37int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)20, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)44, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___20int32_t_44int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___20int32_t_44int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___20int32_t_44int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___20int32_t_44int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)39, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)25, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___39int32_t_25int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___39int32_t_25int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___39int32_t_25int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___39int32_t_25int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)8, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)56, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___8int32_t_56int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___8int32_t_56int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___8int32_t_56int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___8int32_t_56int32_t(a, b); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -rotate_left___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t x) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - libcrux_intrinsics_arm64__vshlq_n_u64( - (int32_t)14, x, core_core_arch_arm_shared_neon_uint64x2_t); - return libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vshrq_n_u64( - (int32_t)50, x, core_core_arch_arm_shared_neon_uint64x2_t)); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -_vxarq_u64___14int32_t_50int32_t(core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - core_core_arch_arm_shared_neon_uint64x2_t ab = - libcrux_intrinsics_arm64__veorq_u64(a, b); - return rotate_left___14int32_t_50int32_t(ab); -} - -static inline core_core_arch_arm_shared_neon_uint64x2_t -xor_and_rotate___14int32_t_50int32_t( - core_core_arch_arm_shared_neon_uint64x2_t a, - core_core_arch_arm_shared_neon_uint64x2_t b) { - return _vxarq_u64___14int32_t_50int32_t(a, b); -} - -static inline void theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - xor5(s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], - s->st[4U][0U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - xor5(s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], - s->st[4U][1U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - xor5(s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], - s->st[4U][2U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - xor5(s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], - s->st[4U][3U]); - core_core_arch_arm_shared_neon_uint64x2_t c[5U] = { - uu____0, uu____1, uu____2, uu____3, - xor5(s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], - s->st[4U][4U])}; - core_core_arch_arm_shared_neon_uint64x2_t uu____4 = - rotate_left1_and_xor(c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____5 = - rotate_left1_and_xor(c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - rotate_left1_and_xor(c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t uu____7 = - rotate_left1_and_xor(c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t t[5U] = { - uu____4, uu____5, uu____6, uu____7, - rotate_left1_and_xor(c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U])}; - core_core_arch_arm_shared_neon_uint64x2_t uu____8 = - xor0(s->st[0U][0U], t[0U]); - s->st[0U][0U] = uu____8; - core_core_arch_arm_shared_neon_uint64x2_t uu____9 = - xor_and_rotate___36int32_t_28int32_t(s->st[1U][0U], t[0U]); - s->st[1U][0U] = uu____9; - core_core_arch_arm_shared_neon_uint64x2_t uu____10 = - xor_and_rotate___3int32_t_61int32_t(s->st[2U][0U], t[0U]); - s->st[2U][0U] = uu____10; - core_core_arch_arm_shared_neon_uint64x2_t uu____11 = - xor_and_rotate___41int32_t_23int32_t(s->st[3U][0U], t[0U]); - s->st[3U][0U] = uu____11; - core_core_arch_arm_shared_neon_uint64x2_t uu____12 = - xor_and_rotate___18int32_t_46int32_t(s->st[4U][0U], t[0U]); - s->st[4U][0U] = uu____12; - core_core_arch_arm_shared_neon_uint64x2_t uu____13 = - xor_and_rotate___1int32_t_63int32_t(s->st[0U][1U], t[1U]); - s->st[0U][1U] = uu____13; - core_core_arch_arm_shared_neon_uint64x2_t uu____14 = - xor_and_rotate___44int32_t_20int32_t(s->st[1U][1U], t[1U]); - s->st[1U][1U] = uu____14; - core_core_arch_arm_shared_neon_uint64x2_t uu____15 = - xor_and_rotate___10int32_t_54int32_t(s->st[2U][1U], t[1U]); - s->st[2U][1U] = uu____15; - core_core_arch_arm_shared_neon_uint64x2_t uu____16 = - xor_and_rotate___45int32_t_19int32_t(s->st[3U][1U], t[1U]); - s->st[3U][1U] = uu____16; - core_core_arch_arm_shared_neon_uint64x2_t uu____17 = - xor_and_rotate___2int32_t_62int32_t(s->st[4U][1U], t[1U]); - s->st[4U][1U] = uu____17; - core_core_arch_arm_shared_neon_uint64x2_t uu____18 = - xor_and_rotate___62int32_t_2int32_t(s->st[0U][2U], t[2U]); - s->st[0U][2U] = uu____18; - core_core_arch_arm_shared_neon_uint64x2_t uu____19 = - xor_and_rotate___6int32_t_58int32_t(s->st[1U][2U], t[2U]); - s->st[1U][2U] = uu____19; - core_core_arch_arm_shared_neon_uint64x2_t uu____20 = - xor_and_rotate___43int32_t_21int32_t(s->st[2U][2U], t[2U]); - s->st[2U][2U] = uu____20; - core_core_arch_arm_shared_neon_uint64x2_t uu____21 = - xor_and_rotate___15int32_t_49int32_t(s->st[3U][2U], t[2U]); - s->st[3U][2U] = uu____21; - core_core_arch_arm_shared_neon_uint64x2_t uu____22 = - xor_and_rotate___61int32_t_3int32_t(s->st[4U][2U], t[2U]); - s->st[4U][2U] = uu____22; - core_core_arch_arm_shared_neon_uint64x2_t uu____23 = - xor_and_rotate___28int32_t_36int32_t(s->st[0U][3U], t[3U]); - s->st[0U][3U] = uu____23; - core_core_arch_arm_shared_neon_uint64x2_t uu____24 = - xor_and_rotate___55int32_t_9int32_t(s->st[1U][3U], t[3U]); - s->st[1U][3U] = uu____24; - core_core_arch_arm_shared_neon_uint64x2_t uu____25 = - xor_and_rotate___25int32_t_39int32_t(s->st[2U][3U], t[3U]); - s->st[2U][3U] = uu____25; - core_core_arch_arm_shared_neon_uint64x2_t uu____26 = - xor_and_rotate___21int32_t_43int32_t(s->st[3U][3U], t[3U]); - s->st[3U][3U] = uu____26; - core_core_arch_arm_shared_neon_uint64x2_t uu____27 = - xor_and_rotate___56int32_t_8int32_t(s->st[4U][3U], t[3U]); - s->st[4U][3U] = uu____27; - core_core_arch_arm_shared_neon_uint64x2_t uu____28 = - xor_and_rotate___27int32_t_37int32_t(s->st[0U][4U], t[4U]); - s->st[0U][4U] = uu____28; - core_core_arch_arm_shared_neon_uint64x2_t uu____29 = - xor_and_rotate___20int32_t_44int32_t(s->st[1U][4U], t[4U]); - s->st[1U][4U] = uu____29; - core_core_arch_arm_shared_neon_uint64x2_t uu____30 = - xor_and_rotate___39int32_t_25int32_t(s->st[2U][4U], t[4U]); - s->st[2U][4U] = uu____30; - core_core_arch_arm_shared_neon_uint64x2_t uu____31 = - xor_and_rotate___8int32_t_56int32_t(s->st[3U][4U], t[4U]); - s->st[3U][4U] = uu____31; - core_core_arch_arm_shared_neon_uint64x2_t uu____32 = - xor_and_rotate___14int32_t_50int32_t(s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____32; -} - -static inline void pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s) { - core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; - core_array___core__clone__Clone_for__Array_T__N___20__clone( - (size_t)5U, s->st, old, core_core_arch_arm_shared_neon_uint64x2_t[5U], - void *); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -static inline void chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s) { - core_core_arch_arm_shared_neon_uint64x2_t old[5U][5U]; - memcpy(old, s->st, - (size_t)5U * sizeof(core_core_arch_arm_shared_neon_uint64x2_t[5U])); - KRML_MAYBE_FOR5( - i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( - i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - and_not_xor(s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); - s->st[i1][j] = uu____0;);); -} - -static inline void iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - size_t i) { - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = xor_constant( - s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); - s->st[0U][0U] = uu____0; -} - -static inline void -keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s) { - for (size_t i = (size_t)0U; i < (size_t)24U; i++) { - size_t i0 = i; - theta_rho__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - pi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - chi__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - iota__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s, i0); - } -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice blocks[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); - load_block___72size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void load_block_full___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, - Eurydice_slice)}; - load_block___72size_t(uu____0, buf); -} - -static inline void load_block_full___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___72size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)72U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)72U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___72size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void store_block___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U]) { - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vtrn1q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vtrn2q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)72U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)72U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)72U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, - .end = (size_t)72U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)16U, u, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = (size_t)72U - (size_t)8U, - .end = (size_t)72U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice( - (size_t)16U, u, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___72size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; - store_block___72size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { - uint8_t ret0[2U][200U]; - store_block_full___72size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - uint8_t b[2U][200U]; - store_block_full___72size_t0(s->st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___72size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - store_block___72size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - store_block___72size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___72size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___72size_t0(s.st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - Eurydice_slice data[2U], Eurydice_slice out[2U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)72U, (size_t)72U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)72U; - size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)72U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)72U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - &s, o); - memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t( - s, o1); - } - } -} - -static inline void keccakx2___72size_t_6uint8_t(Eurydice_slice data[2U], - Eurydice_slice out[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_72size_t_6uint8_t( - uu____0, out); -} - -void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) { - uint8_t dummy[64U] = {0U}; - Eurydice_slice uu____0[2U] = {data, data}; - Eurydice_slice uu____1 = digest; - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)64U, dummy, uint8_t, Eurydice_slice)}; - keccakx2___72size_t_6uint8_t(uu____0, buf); -} - -static inline void load_block___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - libcrux_intrinsics_arm64__veorq_u64( - uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; - } - if ((size_t)136U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = {0U}; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2( - &dst0, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, - .end = (size_t)136U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst0, ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, - .end = (size_t)136U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t uvec = - libcrux_intrinsics_arm64__vld1q_u64( - Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void load_block___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); - load_block___136size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice blocks[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); - load_block___136size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void load_block_full___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, - Eurydice_slice)}; - load_block___136size_t(uu____0, buf); -} - -static inline void load_block_full___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___136size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void store_block___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vtrn1q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vtrn2q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)136U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)136U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)136U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, - .end = (size_t)136U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)16U, u, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = (size_t)136U - (size_t)8U, - .end = (size_t)136U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice( - (size_t)16U, u, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___136size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; - store_block___136size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { - uint8_t ret0[2U][200U]; - store_block_full___136size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - uint8_t b[2U][200U]; - store_block_full___136size_t0(s->st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___136size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - store_block___136size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___136size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___136size_t0(s.st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - Eurydice_slice data[2U], Eurydice_slice out[2U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, o); - memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - s, o1); - } - } -} - -static inline void keccakx2___136size_t_6uint8_t(Eurydice_slice data[2U], - Eurydice_slice out[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_6uint8_t( - uu____0, out); -} - -void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) { - uint8_t dummy[32U] = {0U}; - Eurydice_slice uu____0[2U] = {data, data}; - Eurydice_slice uu____1 = digest; - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)32U, dummy, uint8_t, Eurydice_slice)}; - keccakx2___136size_t_6uint8_t(uu____0, buf); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)136U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___136size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - Eurydice_slice data[2U], Eurydice_slice out[2U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)136U, (size_t)136U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)136U; - size_t last = outlen - outlen % (size_t)136U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)136U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)136U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - &s, o); - memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t( - s, o1); - } - } -} - -static inline void keccakx2___136size_t_31uint8_t(Eurydice_slice data[2U], - Eurydice_slice out[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_136size_t_31uint8_t( - uu____0, out); -} - -void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, - Eurydice_slice out0, Eurydice_slice out1) { - Eurydice_slice buf0[2U] = {input0, input1}; - Eurydice_slice buf[2U] = {out0, out1}; - keccakx2___136size_t_31uint8_t(buf0, buf); -} - -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, + Eurydice_slice data) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline libcrux_sha3_neon_x2_incremental_KeccakState2 libcrux_sha3_neon_x2_incremental_shake128_init(void) { - return new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); -} - -static inline void load_block___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - libcrux_intrinsics_arm64__veorq_u64( - uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; - } - if ((size_t)168U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = {0U}; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2( - &dst0, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, - .end = (size_t)168U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst0, ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, - .end = (size_t)168U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t uvec = - libcrux_intrinsics_arm64__vld1q_u64( - Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void load_block_full___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, - Eurydice_slice)}; - load_block___168size_t(uu____0, buf); -} - -static inline void load_block_full___168size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___168size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 31U; - blocks[i0][(size_t)168U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___168size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice data0, Eurydice_slice data1) { - Eurydice_slice buf[2U] = {data0, data1}; - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t_31uint8_t( - s, buf); -} - -static inline void store_block___168size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vtrn1q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vtrn2q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)168U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)168U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)168U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, - .end = (size_t)168U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)16U, u, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = (size_t)168U - (size_t)8U, - .end = (size_t)168U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice( - (size_t)16U, u, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block___168size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - store_block___168size_t(a, b); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___168size_t0(s->st, out); -} - -void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out0, Eurydice_slice out1) { - Eurydice_slice buf[2U] = {out0, out1}; - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - s, buf); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - store_block___168size_t0(s->st, out); -} - -static inline void -squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ uu____0 = - split_at_mut_n(out, (size_t)168U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____0.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o10[2U]; - memcpy(o10, uu____0.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - s, o0); - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ uu____1 = - split_at_mut_n(o10, (size_t)168U); - Eurydice_slice o1[2U]; - memcpy(o1, uu____1.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o2[2U]; - memcpy(o2, uu____1.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - s, o1); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - s, o2); -} - -void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out0, Eurydice_slice out1) { - Eurydice_slice buf[2U] = {out0, out1}; - squeeze_first_three_blocks__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_168size_t( - s, buf); -} - -static inline void load_block___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U]) { - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - libcrux_intrinsics_arm64__veorq_u64( - uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; - } - if ((size_t)144U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = {0U}; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2( - &dst0, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, - .end = (size_t)144U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst0, ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, - .end = (size_t)144U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t uvec = - libcrux_intrinsics_arm64__vld1q_u64( - Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void load_block___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); - load_block___144size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice blocks[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); - load_block___144size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void load_block_full___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, - Eurydice_slice)}; - load_block___144size_t(uu____0, buf); -} - -static inline void load_block_full___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___144size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)144U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)144U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___144size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void store_block___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U]) { - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vtrn1q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vtrn2q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)144U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)144U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)144U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, - .end = (size_t)144U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)16U, u, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = (size_t)144U - (size_t)8U, - .end = (size_t)144U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice( - (size_t)16U, u, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___144size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; - store_block___144size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { - uint8_t ret0[2U][200U]; - store_block_full___144size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - uint8_t b[2U][200U]; - store_block_full___144size_t0(s->st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___144size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - store_block___144size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - store_block___144size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___144size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___144size_t0(s.st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - Eurydice_slice data[2U], Eurydice_slice out[2U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)144U, (size_t)144U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)144U; - size_t last = outlen - outlen % (size_t)144U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)144U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)144U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - &s, o); - memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t( - s, o1); - } - } -} - -static inline void keccakx2___144size_t_6uint8_t(Eurydice_slice data[2U], - Eurydice_slice out[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_144size_t_6uint8_t( - uu____0, out); + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, + Eurydice_slice data1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +inline void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) { - uint8_t dummy[28U] = {0U}; - Eurydice_slice uu____0[2U] = {data, data}; - Eurydice_slice uu____1 = digest; - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)28U, dummy, uint8_t, Eurydice_slice)}; - keccakx2___144size_t_6uint8_t(uu____0, buf); -} - -static inline void load_block___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice blocks[2U]) { - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vld1q_bytes_u64(Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____0 = - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____1 = - libcrux_intrinsics_arm64__veorq_u64( - uu____0, libcrux_intrinsics_arm64__vtrn1q_u64(v0, v1)); - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U] = uu____1; - core_core_arch_arm_shared_neon_uint64x2_t uu____2 = - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]; - core_core_arch_arm_shared_neon_uint64x2_t uu____3 = - libcrux_intrinsics_arm64__veorq_u64( - uu____2, libcrux_intrinsics_arm64__vtrn2q_u64(v0, v1)); - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U] = uu____3; - } - if ((size_t)104U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint64_t u[2U] = {0U}; - uint8_t ret[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst0; - Eurydice_slice_to_array2( - &dst0, - Eurydice_slice_subslice( - blocks[0U], - ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, - .end = (size_t)104U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst0, ret); - uint64_t uu____4 = core_num__u64_9__from_le_bytes(ret); - u[0U] = uu____4; - uint8_t ret0[8U]; - core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; - Eurydice_slice_to_array2( - &dst, - Eurydice_slice_subslice( - blocks[1U], - ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, - .end = (size_t)104U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - Eurydice_slice, uint8_t[8U], void *); - core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( - dst, ret0); - uint64_t uu____5 = core_num__u64_9__from_le_bytes(ret0); - u[1U] = uu____5; - core_core_arch_arm_shared_neon_uint64x2_t uvec = - libcrux_intrinsics_arm64__vld1q_u64( - Eurydice_array_to_slice((size_t)2U, u, uint64_t, Eurydice_slice)); - core_core_arch_arm_shared_neon_uint64x2_t uu____6 = - libcrux_intrinsics_arm64__veorq_u64(s[i][j], uvec); - s[i][j] = uu____6; - } -} - -static inline void load_block___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, b, (size_t)2U * sizeof(Eurydice_slice)); - load_block___104size_t(uu____0, uu____1); -} - -static inline void -absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice blocks[2U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, blocks, (size_t)2U * sizeof(Eurydice_slice)); - load_block___104size_t0(uu____0, uu____1); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void load_block_full___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - uint8_t blocks[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], - uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, Eurydice_array_to_slice((size_t)200U, blocks[1U], uint8_t, - Eurydice_slice)}; - load_block___104size_t(uu____0, buf); -} - -static inline void load_block_full___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t b[2U][200U]) { - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = a; - uint8_t uu____1[2U][200U]; - memcpy(uu____1, b, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___104size_t(uu____0, uu____1); -} - -static inline void -absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice last[2U]) { - size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); - uint8_t blocks[2U][200U] = {{0U}}; - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_array_to_subslice( - (size_t)200U, blocks[i0], - ((core_ops_range_Range__size_t){.start = (size_t)0U, - .end = last_len}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice(uu____0, last[i0], - uint8_t, void *); - blocks[i0][last_len] = 6U; - blocks[i0][(size_t)104U - (size_t)1U] = - (uint32_t)blocks[i0][(size_t)104U - (size_t)1U] | 128U;); - core_core_arch_arm_shared_neon_uint64x2_t(*uu____1)[5U] = s->st; - uint8_t uu____2[2U][200U]; - memcpy(uu____2, blocks, (size_t)2U * sizeof(uint8_t[200U])); - load_block_full___104size_t0(uu____1, uu____2); - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); -} - -static inline void store_block___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], - Eurydice_slice out[2U]) { - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)16U; i++) { - size_t i0 = i; - core_core_arch_arm_shared_neon_uint64x2_t v0 = - libcrux_intrinsics_arm64__vtrn1q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - core_core_arch_arm_shared_neon_uint64x2_t v1 = - libcrux_intrinsics_arm64__vtrn2q_u64( - s[(size_t)2U * i0 / (size_t)5U][(size_t)2U * i0 % (size_t)5U], - s[((size_t)2U * i0 + (size_t)1U) / (size_t)5U] - [((size_t)2U * i0 + (size_t)1U) % (size_t)5U]); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[0U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v0); - libcrux_intrinsics_arm64__vst1q_bytes_u64( - Eurydice_slice_subslice(out[1U], - ((core_ops_range_Range__size_t){ - .start = (size_t)16U * i0, - .end = (size_t)16U * (i0 + (size_t)1U)}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - v1); - } - if ((size_t)104U % (size_t)16U != (size_t)0U) { - size_t i = ((size_t)104U / (size_t)8U - (size_t)1U) / (size_t)5U; - size_t j = ((size_t)104U / (size_t)8U - (size_t)1U) % (size_t)5U; - uint8_t u[16U] = {0U}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)16U, u, uint8_t, Eurydice_slice); - libcrux_intrinsics_arm64__vst1q_bytes_u64(uu____0, s[i][j]); - Eurydice_slice uu____1 = Eurydice_slice_subslice( - out[0U], - ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, - .end = (size_t)104U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____1, - Eurydice_array_to_subslice((size_t)16U, u, - ((core_ops_range_Range__size_t){ - .start = (size_t)0U, .end = (size_t)8U}), - uint8_t, core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *); - Eurydice_slice uu____2 = Eurydice_slice_subslice( - out[1U], - ((core_ops_range_Range__size_t){.start = (size_t)104U - (size_t)8U, - .end = (size_t)104U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice); - core_slice___Slice_T___copy_from_slice( - uu____2, - Eurydice_array_to_subslice( - (size_t)16U, u, - ((core_ops_range_Range__size_t){.start = (size_t)8U, - .end = (size_t)16U}), - uint8_t, core_ops_range_Range__size_t, Eurydice_slice), - uint8_t, void *); - } -} - -static inline void store_block_full___104size_t( - core_core_arch_arm_shared_neon_uint64x2_t (*s)[5U], uint8_t ret[2U][200U]) { - uint8_t out0[200U] = {0U}; - uint8_t out1[200U] = {0U}; - core_core_arch_arm_shared_neon_uint64x2_t(*uu____0)[5U] = s; - Eurydice_slice uu____1 = - Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice)}; - store_block___104size_t(uu____0, buf); - uint8_t uu____2[200U]; - memcpy(uu____2, out0, (size_t)200U * sizeof(uint8_t)); - uint8_t uu____3[200U]; - memcpy(uu____3, out1, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], uu____2, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[1U], uu____3, (size_t)200U * sizeof(uint8_t)); -} - -static inline void store_block_full___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], uint8_t ret[2U][200U]) { - uint8_t ret0[2U][200U]; - store_block_full___104size_t(a, ret0); - memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t[200U])); -} - -static inline void -squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - uint8_t b[2U][200U]; - store_block_full___104size_t0(s->st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void store_block___104size_t0( - core_core_arch_arm_shared_neon_uint64x2_t (*a)[5U], Eurydice_slice b[2U]) { - store_block___104size_t(a, b); -} - -static inline void -squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - store_block___104size_t0(s->st, out); -} - -static inline void -squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(s); - store_block___104size_t0(s->st, out); -} - -static inline void -squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s, - Eurydice_slice out[2U]) { - keccakf1600__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(&s); - uint8_t b[2U][200U]; - store_block_full___104size_t0(s.st, b); - KRML_MAYBE_FOR2( - i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; - core_ops_range_Range__size_t lit; lit.start = (size_t)0U; - lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); - core_slice___Slice_T___copy_from_slice( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range__size_t, - Eurydice_slice), - uint8_t, void *);); -} - -static inline void -keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - Eurydice_slice data[2U], Eurydice_slice out[2U]) { - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - s = new__core_core_arch_arm_shared_neon_uint64x2_t_2size_t(); - for (size_t i = (size_t)0U; - i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; - i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____0 = &s; - Eurydice_slice uu____1[2U]; - memcpy(uu____1, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____1, i0 * (size_t)104U, (size_t)104U, ret); - absorb_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - uu____0, ret); - } - size_t rem = - core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *uu____2 = &s; - Eurydice_slice uu____3[2U]; - memcpy(uu____3, data, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice ret[2U]; - slice_n(uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, - rem, ret); - absorb_final__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - uu____2, ret); - size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); - size_t blocks = outlen / (size_t)104U; - size_t last = outlen - outlen % (size_t)104U; - if (blocks == (size_t)0U) { - squeeze_first_and_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - &s, out); - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____4 = split_at_mut_n(out, (size_t)104U); - Eurydice_slice o0[2U]; - memcpy(o0, uu____4.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice o1[2U]; - memcpy(o1, uu____4.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_first_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - &s, o0); - core_ops_range_Range__size_t iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - ((core_ops_range_Range__size_t){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range__size_t, core_ops_range_Range__size_t); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, core_option_Option__size_t) - .tag == core_option_None) { - break; - } else { - K___Eurydice_slice_uint8_t_2size_t__Eurydice_slice_uint8_t_2size_t_ - uu____5 = split_at_mut_n(o1, (size_t)104U); - Eurydice_slice o[2U]; - memcpy(o, uu____5.fst, (size_t)2U * sizeof(Eurydice_slice)); - Eurydice_slice orest[2U]; - memcpy(orest, uu____5.snd, (size_t)2U * sizeof(Eurydice_slice)); - squeeze_next_block__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - &s, o); - memcpy(o1, orest, (size_t)2U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - squeeze_last__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t( - s, o1); - } - } -} - -static inline void keccakx2___104size_t_6uint8_t(Eurydice_slice data[2U], - Eurydice_slice out[2U]) { - Eurydice_slice uu____0[2U]; - memcpy(uu____0, data, (size_t)2U * sizeof(Eurydice_slice)); - keccak__core_core_arch_arm_shared_neon_uint64x2_t_2size_t_104size_t_6uint8_t( - uu____0, out); + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) { - uint8_t dummy[48U] = {0U}; - Eurydice_slice uu____0[2U] = {data, data}; - Eurydice_slice uu____1 = digest; - Eurydice_slice buf[2U] = { - uu____1, - Eurydice_array_to_slice((size_t)48U, dummy, uint8_t, Eurydice_slice)}; - keccakx2___104size_t_6uint8_t(uu____0, buf); + Prims_string buf[1U] = { + "not implemented: The target architecture does not support neon " + "instructions."}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); + core_fmt_rt_Argument ret[0U]; + core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); + LowStar_Ignore_ignore( + core_fmt__core__fmt__Arguments__a__2__new_v1( + uu____0, Eurydice_array_to_slice( + (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), + core_fmt_Arguments, void *); + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 0e8477b26..0861469fa 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,7 +1,7 @@ /* This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: b5cb71b8 KaRaMeL + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL version: 40e3a603 */ @@ -17,11 +17,6 @@ extern "C" { #include "libcrux_core.h" #include "libcrux_sha3_internal.h" -typedef struct - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t_s { - core_core_arch_arm_shared_neon_uint64x2_t st[5U][5U]; -} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t; - void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); @@ -29,23 +24,24 @@ void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data); void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice out0, Eurydice_slice out1); -libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t +typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; +} libcrux_sha3_neon_x2_incremental_KeccakState2; + +libcrux_sha3_neon_x2_incremental_KeccakState2 libcrux_sha3_neon_x2_incremental_shake128_init(void); void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice data0, Eurydice_slice data1); + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, + Eurydice_slice data1); void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out0, Eurydice_slice out1); + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1); void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState__core_core_arch_arm_shared_neon_uint64x2_t__2size_t - *s, - Eurydice_slice out0, Eurydice_slice out1); + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1); void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data); From 48db367dd187e04f6ba06e9572951cec3275b895 Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Mon, 10 Jun 2024 10:38:10 -0700 Subject: [PATCH 46/84] Regenerate the code with a fresh code-gen change to deal with an MSVC oddity --- libcrux-ml-kem/c/internal/libcrux_core.h | 4 ++-- libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h | 2 +- libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h | 2 +- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 2 +- libcrux-ml-kem/c/internal/libcrux_sha3_internal.h | 2 +- libcrux-ml-kem/c/libcrux_core.c | 2 +- libcrux-ml-kem/c/libcrux_core.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem512.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem768.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 2 +- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 2 +- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 2 +- libcrux-ml-kem/c/libcrux_sha3.h | 2 +- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 2 +- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 2 +- libcrux-ml-kem/c/libcrux_sha3_internal.h | 2 +- libcrux-ml-kem/c/libcrux_sha3_neon.c | 2 +- libcrux-ml-kem/c/libcrux_sha3_neon.h | 2 +- 32 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 5ca28c79c..6245ba78c 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __internal_libcrux_core_H @@ -16,7 +16,7 @@ extern "C" { #include "eurydice_glue.h" extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( - core_fmt_rt_Argument x0[0U]); + core_fmt_rt_Argument *x0); extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( Eurydice_slice x0, Eurydice_slice x1); diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index fcda100f7..58155643c 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __internal_libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index 4fa834a92..b7caa27e1 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index 405e13161..05fe23ee6 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 32b53c527..22e02bd6d 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 518634a6f..3f65bcf58 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 6d6e8dcac..62ceebc2c 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 1399bdf00..9fcadba75 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index e42d25b96..bef973b2c 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem1024_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index 22172d3c4..7c71dabe4 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem1024_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index 66d7f407e..f96a815a6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 5f38c1f52..83fc5be46 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 8cdf081a1..80d9dd3f8 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index c5d115c11..db169fa82 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem512_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index 28682ce54..ec92a98ea 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem512_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 2c66e4f9e..4d79fb75e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index ec949dc4d..fea44f677 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 19cf733d3..1ee6f610a 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index 79ab93993..4a14c563e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem768_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index 2354c986e..0d5024551 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem768_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 8bac4c0fe..00b723c9f 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 2e8dd612b..17f457d06 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index a4c6c077c..ac52e4bbb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "internal/libcrux_mlkem_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index e4349f2b1..01d55d083 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index eeba8ebb1..def6d0fb7 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "internal/libcrux_mlkem_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index 02b989972..f9c6b1bc5 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 36ca19e89..189a64804 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 456891376..e8210950d 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "internal/libcrux_sha3_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index 28d49028b..bc53c956a 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index ec88e43b6..6511292a8 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index b9aa5c77b..9e9a598e9 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 0861469fa..6a3cf4a83 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -2,7 +2,7 @@ This file was generated by KaRaMeL KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 40e3a603 + version: 6bb7cd3e */ #ifndef __libcrux_sha3_neon_H From e29b810282f14b8c3c9f3e0b867bf22fd21a487c Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 20:17:25 +0200 Subject: [PATCH 47/84] allow symcrypt benches --- libcrux-ml-kem/c/CMakeLists.txt | 14 +++--- libcrux-ml-kem/c/README.md | 20 +++++++++ libcrux-ml-kem/c/benches/mlkem768.cc | 65 ++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index f74d91c71..15c2f93cd 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -79,6 +79,7 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") add_library(ml_kem_vec256 OBJECT ${SOURCES_vec256}) target_sources(ml_kem_static PRIVATE $) target_sources(ml_kem PRIVATE $) + if(NOT MSVC) target_compile_options(ml_kem_vec256 PRIVATE -mavx @@ -152,8 +153,13 @@ target_link_libraries(ml_kem_bench PRIVATE ml_kem_static benchmark::benchmark ) -target_compile_definitions(ml_kem_bench PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_bench PRIVATE) + +if(DEFINED $ENV{SYMCRYPT_PATH}) + add_compile_definitions(LIBCRUX_SYMCRYPT) + target_include_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}) + target_link_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}/build/module/generic/) + target_link_libraries(ml_kem_bench PRIVATE symcrypt) +endif(DEFINED $ENV{SYMCRYPT_PATH}) add_executable(ml_kem_keygen ${PROJECT_SOURCE_DIR}/benches/mlkem768_keygen.cc @@ -162,8 +168,6 @@ target_link_libraries(ml_kem_keygen PRIVATE ml_kem_static benchmark::benchmark ) -target_compile_definitions(ml_kem_keygen PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_keygen PRIVATE) add_executable(ml_kem_encaps ${PROJECT_SOURCE_DIR}/benches/mlkem768_encaps.cc @@ -172,8 +176,6 @@ target_link_libraries(ml_kem_encaps PRIVATE ml_kem_static benchmark::benchmark ) -target_compile_definitions(ml_kem_encaps PUBLIC HACL_CAN_COMPILE_VEC256) -target_compile_options(ml_kem_encaps PRIVATE) if(NOT MSVC) # We benchmark internal functions here that are inlined and thus not available diff --git a/libcrux-ml-kem/c/README.md b/libcrux-ml-kem/c/README.md index 9652f89c6..a60aa4a53 100644 --- a/libcrux-ml-kem/c/README.md +++ b/libcrux-ml-kem/c/README.md @@ -12,11 +12,31 @@ the script sets all necessary configuration flags. ## Build +Make sure to use `CC=clang CXX=clang++` when benchmarking on Linux to get full performance. + ```bash cmake -B build -G "Ninja Multi-Config" cmake --build build ``` +### Symcrypt benchmarks + +First get and build symcrypt and set `SYMCRYPT_PATH` for the build. +Ensure you have `elftools` installed (`pip install pyelftools`). + +```bash +git clone https://github.com/microsoft/symcrypt +cd symcrypt +git checkout b070a5d236a4d40aa90524cb5b492463c5452b40 +scripts/build.py cmake build --config Release +``` + +```bash +SYMCRYPT_PATH= CC=clang CXX=clang++ cmake -B build -G Ninja Multi-Config" +cmake --build build --config Release +./build/Release/ml_kem_bench +``` + ### Test ```bash diff --git a/libcrux-ml-kem/c/benches/mlkem768.cc b/libcrux-ml-kem/c/benches/mlkem768.cc index 5d9160fea..583caa385 100644 --- a/libcrux-ml-kem/c/benches/mlkem768.cc +++ b/libcrux-ml-kem/c/benches/mlkem768.cc @@ -179,4 +179,69 @@ BENCHMARK(kyber768_encapsulation_avx2); BENCHMARK(kyber768_decapsulation_avx2); #endif +#ifdef LIBCRUX_SYMCRYPT +#include "inc/symcrypt.h" + +static void +symcrypt_kyber768_key_generation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + + for (auto _ : state) + { + pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + } +} + +static void +symcrypt_kyber768_encapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + generate_random(randomness, 32); + + BYTE secret[32]; + BYTE cipher[1088]; + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + + for (auto _ : state) + { + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + } +} + +static void +symcrypt_kyber768_decapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + + generate_random(randomness, 32); + BYTE secret[32]; + BYTE cipher[1088]; + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + + BYTE sharedSecret2[32]; + + for (auto _ : state) + { + SymCryptMlKemDecapsulate(pKey, cipher, 1088, sharedSecret2, 32); + } +} + +BENCHMARK(symcrypt_kyber768_key_generation); +BENCHMARK(symcrypt_kyber768_encapsulation); +BENCHMARK(symcrypt_kyber768_decapsulation); +#endif + BENCHMARK_MAIN(); From a2be70edd974a77c6a06b9f10bddec5e2e6a1892 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Mon, 10 Jun 2024 20:51:11 +0200 Subject: [PATCH 48/84] fix envs in cmakelists --- libcrux-ml-kem/c/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index 15c2f93cd..c15e11bf7 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -89,7 +89,7 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") endif() # This is only for local testing and we assume neon on arm64. -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED $ENV{LIBCRUX_NEON}) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED ENV{LIBCRUX_NEON}) message(STATUS "Detected an arm64 architecture") add_compile_definitions(LIBCRUX_AARCH64) @@ -154,12 +154,13 @@ target_link_libraries(ml_kem_bench PRIVATE benchmark::benchmark ) -if(DEFINED $ENV{SYMCRYPT_PATH}) +if(DEFINED ENV{SYMCRYPT_PATH}) + message("Symcrypt path: $ENV{SYMCRYPT_PATH}") add_compile_definitions(LIBCRUX_SYMCRYPT) target_include_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}) - target_link_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}/build/module/generic/) + target_link_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}/bin/lib) target_link_libraries(ml_kem_bench PRIVATE symcrypt) -endif(DEFINED $ENV{SYMCRYPT_PATH}) +endif(DEFINED ENV{SYMCRYPT_PATH}) add_executable(ml_kem_keygen ${PROJECT_SOURCE_DIR}/benches/mlkem768_keygen.cc From 3b31006037373a79c6b87de0b4bf00d5fd84e74c Mon Sep 17 00:00:00 2001 From: Jonathan Protzenko Date: Mon, 10 Jun 2024 14:44:59 -0700 Subject: [PATCH 49/84] Code quality improvement: leverage extraction of type aliases (thanks @nadrieril) to place monomorphized definitions in utils.rs, which is hella more convenient than listing them manually via the config --- libcrux-ml-kem/c.yaml | 13 +--- libcrux-ml-kem/c/internal/libcrux_core.h | 54 ++++++++--------- libcrux-ml-kem/c/libcrux_core.c | 24 ++++---- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 72 +++++++++++------------ libcrux-ml-kem/c/libcrux_mlkem_portable.c | 72 +++++++++++------------ libcrux-ml-kem/src/ind_cca.rs | 3 +- libcrux-ml-kem/src/ind_cpa.rs | 10 +--- libcrux-ml-kem/src/lib.rs | 1 + libcrux-ml-kem/src/utils.rs | 25 ++++++++ 9 files changed, 143 insertions(+), 131 deletions(-) create mode 100644 libcrux-ml-kem/src/utils.rs diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 205d9ea99..4dbc5b102 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -63,6 +63,7 @@ files: monomorphizations_using: # Should this also include the monomorphizations using # core.arch.x86.__m256i? + - [libcrux_sha3, avx2, "*"] - [libcrux_sha3, simd, avx2, "*"] monomorphizations_exact: - [libcrux_sha3, generic_keccak, "KeccakState__core_core_arch_x86___m256i_$4size_t"] @@ -157,24 +158,16 @@ files: - [ core, "*"] - [ libcrux_ml_kem, types, "*"] - [ libcrux_ml_kem, constant_time_ops, "*"] + - [ libcrux_ml_kem, utils ] monomorphizations_using: - [ Eurydice, "*" ] - [ libcrux_ml_kem, types, "*"] - monomorphizations_exact: - - [ K, "__uint8_t[1536size_t]_uint8_t[1568size_t]" ] - - [ K, "__uint8_t[1152size_t]_uint8_t[1184size_t]" ] - - [ K, "__uint8_t[768size_t]_uint8_t[800size_t]" ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___33size_t ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___34size_t ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___64size_t ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___800size_t ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___1120size_t ] - - [ libcrux_ml_kem, ind_cpa, into_padded_array___1600size_t ] patterns: - [ core, "*"] - [ libcrux_ml_kem, types ] - [ libcrux_ml_kem, constants ] - [ libcrux_ml_kem, constant_time_ops, "*"] + - [ libcrux_ml_kem, utils ] api: - [Eurydice, "*"] diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 6245ba78c..63c1e03ed 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -44,6 +44,21 @@ void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( #define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) +typedef struct libcrux_ml_kem_utils_Keypair1024_s { + uint8_t fst[1536U]; + uint8_t snd[1568U]; +} libcrux_ml_kem_utils_Keypair1024; + +typedef struct libcrux_ml_kem_utils_Keypair512_s { + uint8_t fst[768U]; + uint8_t snd[800U]; +} libcrux_ml_kem_utils_Keypair512; + +typedef struct libcrux_ml_kem_utils_Keypair768_s { + uint8_t fst[1152U]; + uint8_t snd[1184U]; +} libcrux_ml_kem_utils_Keypair768; + libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( uint8_t value[1568U]); @@ -57,11 +72,6 @@ libcrux_ml_kem_types_MlKemPrivateKey____3168size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___3168size_t( uint8_t value[3168U]); -typedef struct K___uint8_t_1536size_t__uint8_t_1568size_t__s { - uint8_t fst[1536U]; - uint8_t snd[1568U]; -} K___uint8_t_1536size_t__uint8_t_1568size_t_; - libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1568size_t( uint8_t value[1568U]); @@ -78,8 +88,8 @@ Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1568size_t( libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *self); -void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, - uint8_t ret[1600U]); +void libcrux_ml_kem_utils_into_padded_array___1600size_t(Eurydice_slice slice, + uint8_t ret[1600U]); libcrux_ml_kem_types_MlKemPublicKey____1184size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( @@ -94,11 +104,6 @@ libcrux_ml_kem_types_MlKemPrivateKey____2400size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( uint8_t value[2400U]); -typedef struct K___uint8_t_1152size_t__uint8_t_1184size_t__s { - uint8_t fst[1152U]; - uint8_t snd[1184U]; -} K___uint8_t_1152size_t__uint8_t_1184size_t_; - libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( uint8_t value[1088U]); @@ -115,8 +120,8 @@ Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self); -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]); +void libcrux_ml_kem_utils_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]); libcrux_ml_kem_types_MlKemPublicKey____800size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___800size_t( @@ -131,11 +136,6 @@ libcrux_ml_kem_types_MlKemPrivateKey____1632size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___1632size_t( uint8_t value[1632U]); -typedef struct K___uint8_t_768size_t__uint8_t_800size_t__s { - uint8_t fst[768U]; - uint8_t snd[800U]; -} K___uint8_t_768size_t__uint8_t_800size_t_; - libcrux_ml_kem_types_MlKemCiphertext____768size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___768size_t( uint8_t value[768U]); @@ -160,11 +160,11 @@ typedef struct Eurydice_slice snd; } K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; -void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, - uint8_t ret[33U]); +void libcrux_ml_kem_utils_into_padded_array___33size_t(Eurydice_slice slice, + uint8_t ret[33U]); -void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, - uint8_t ret[34U]); +void libcrux_ml_kem_utils_into_padded_array___34size_t(Eurydice_slice slice, + uint8_t ret[34U]); typedef struct K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { @@ -182,11 +182,11 @@ Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]); +void libcrux_ml_kem_utils_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]); -void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, - uint8_t ret[64U]); +void libcrux_ml_kem_utils_into_padded_array___64size_t(Eurydice_slice slice, + uint8_t ret[64U]); typedef struct core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 3f65bcf58..cbcc3017b 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -102,8 +102,8 @@ libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__type Eurydice_slice); } -void libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t(Eurydice_slice slice, - uint8_t ret[1600U]) { +void libcrux_ml_kem_utils_into_padded_array___1600size_t(Eurydice_slice slice, + uint8_t ret[1600U]) { uint8_t out[1600U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( @@ -183,8 +183,8 @@ libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__type Eurydice_slice); } -void libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t(Eurydice_slice slice, - uint8_t ret[1120U]) { +void libcrux_ml_kem_utils_into_padded_array___1120size_t(Eurydice_slice slice, + uint8_t ret[1120U]) { uint8_t out[1120U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( @@ -257,8 +257,8 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_ return is_non_zero(r); } -void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, - uint8_t ret[33U]) { +void libcrux_ml_kem_utils_into_padded_array___33size_t(Eurydice_slice slice, + uint8_t ret[33U]) { uint8_t out[33U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( @@ -272,8 +272,8 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(Eurydice_slice slice, memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(Eurydice_slice slice, - uint8_t ret[34U]) { +void libcrux_ml_kem_utils_into_padded_array___34size_t(Eurydice_slice slice, + uint8_t ret[34U]) { uint8_t out[34U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( @@ -294,8 +294,8 @@ libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__type Eurydice_slice); } -void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, - uint8_t ret[800U]) { +void libcrux_ml_kem_utils_into_padded_array___800size_t(Eurydice_slice slice, + uint8_t ret[800U]) { uint8_t out[800U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( @@ -309,8 +309,8 @@ void libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(Eurydice_slice slice, memcpy(ret, out, (size_t)800U * sizeof(uint8_t)); } -void libcrux_ml_kem_ind_cpa_into_padded_array___64size_t(Eurydice_slice slice, - uint8_t ret[64U]) { +void libcrux_ml_kem_utils_into_padded_array___64size_t(Eurydice_slice slice, + uint8_t ret[64U]) { uint8_t out[64U] = {0U}; uint8_t *uu____0 = out; core_slice___Slice_T___copy_from_slice( diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index ac52e4bbb..a9e1357cc 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -2612,7 +2612,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1152size_t__uint8_t_1184size_t_ +static libcrux_ml_kem_utils_Keypair768 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -2627,12 +2627,12 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[3U][3U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t @@ -2687,7 +2687,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); uint8_t uu____7[1184U]; memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + libcrux_ml_kem_utils_Keypair768 lit; memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; @@ -2774,7 +2774,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair768 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; @@ -3578,11 +3578,11 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[3U][3U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t @@ -3662,7 +3662,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -4340,7 +4340,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -4360,8 +4360,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); + libcrux_ml_kem_utils_into_padded_array___1120size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); @@ -5057,7 +5057,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_1536size_t__uint8_t_1568size_t_ +static libcrux_ml_kem_utils_Keypair1024 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -5072,12 +5072,12 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[4U][4U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t @@ -5132,7 +5132,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); uint8_t uu____7[1568U]; memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + libcrux_ml_kem_utils_Keypair1024 lit; memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; @@ -5219,7 +5219,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair1024 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1536U]; @@ -5543,11 +5543,11 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[4U][4U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t__uint8_t @@ -5627,7 +5627,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -5891,7 +5891,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_1568size_t_1408size_t_11size_t_5size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -5911,8 +5911,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); + libcrux_ml_kem_utils_into_padded_array___1600size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); @@ -6571,7 +6571,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static K___uint8_t_768size_t__uint8_t_800size_t_ +static libcrux_ml_kem_utils_Keypair512 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -6586,12 +6586,12 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[2U][2U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t @@ -6646,7 +6646,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); uint8_t uu____7[800U]; memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; + libcrux_ml_kem_utils_Keypair512 lit; memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; @@ -6733,7 +6733,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair512 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[768U]; @@ -7050,11 +7050,11 @@ encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_ libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector A_transpose[2U][2U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t__uint8_t @@ -7134,7 +7134,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_lib libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -7357,7 +7357,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t_768size_t_640size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -7377,8 +7377,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vecto Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); + libcrux_ml_kem_utils_into_padded_array___800size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index def6d0fb7..c56a9bb7b 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -3206,7 +3206,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static K___uint8_t_1536size_t__uint8_t_1568size_t_ +static libcrux_ml_kem_utils_Keypair1024 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -3221,12 +3221,12 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[4U][4U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t @@ -3281,7 +3281,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); uint8_t uu____7[1568U]; memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - K___uint8_t_1536size_t__uint8_t_1568size_t_ lit; + libcrux_ml_kem_utils_Keypair1024 lit; memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; @@ -3368,7 +3368,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1536size_t__uint8_t_1568size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair1024 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1536U]; @@ -4001,11 +4001,11 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[4U][4U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_4size_t__uint8_t @@ -4085,7 +4085,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto libcrux_ml_kem_types_MlKemPublicKey____1568size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -4607,7 +4607,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable decrypt__libcrux_ml_kem_vector_portable_PortableVector_4size_t_1568size_t_1408size_t_11size_t_5size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -4627,8 +4627,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1600U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1600size_t( - implicit_rejection_value, to_hash); + libcrux_ml_kem_utils_into_padded_array___1600size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); @@ -5218,7 +5218,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static K___uint8_t_1152size_t__uint8_t_1184size_t_ +static libcrux_ml_kem_utils_Keypair768 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -5233,12 +5233,12 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[3U][3U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t @@ -5293,7 +5293,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); uint8_t uu____7[1184U]; memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - K___uint8_t_1152size_t__uint8_t_1184size_t_ lit; + libcrux_ml_kem_utils_Keypair768 lit; memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; @@ -5380,7 +5380,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_1152size_t__uint8_t_1184size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair768 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; @@ -5710,11 +5710,11 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[3U][3U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t @@ -5794,7 +5794,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -6058,7 +6058,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -6078,8 +6078,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[1120U]; - libcrux_ml_kem_ind_cpa_into_padded_array___1120size_t( - implicit_rejection_value, to_hash); + libcrux_ml_kem_utils_into_padded_array___1120size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); @@ -6680,7 +6680,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static K___uint8_t_768size_t__uint8_t_800size_t_ +static libcrux_ml_kem_utils_Keypair512 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -6695,12 +6695,12 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[2U][2U]; uint8_t ret[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( ret, true, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(seed_for_secret_and_error, - prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); uint8_t uu____1[33U]; memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t @@ -6755,7 +6755,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); uint8_t uu____7[800U]; memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - K___uint8_t_768size_t__uint8_t_800size_t_ lit; + libcrux_ml_kem_utils_Keypair512 lit; memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; @@ -6842,7 +6842,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - K___uint8_t_768size_t__uint8_t_800size_t_ uu____0 = + libcrux_ml_kem_utils_Keypair512 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[768U]; @@ -7136,11 +7136,11 @@ encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_funct libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector A_transpose[2U][2U]; uint8_t ret0[34U]; - libcrux_ml_kem_ind_cpa_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t( ret0, false, A_transpose); uint8_t prf_input[33U]; - libcrux_ml_kem_ind_cpa_into_padded_array___33size_t(randomness, prf_input); + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); uint8_t uu____0[33U]; memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); __libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_2size_t__uint8_t @@ -7220,7 +7220,7 @@ libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVecto libcrux_ml_kem_types_MlKemPublicKey____800size_t *public_key, uint8_t randomness[32U]) { uint8_t to_hash[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( @@ -7444,7 +7444,7 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable decrypt__libcrux_ml_kem_vector_portable_PortableVector_2size_t_768size_t_640size_t_10size_t_4size_t( ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_ind_cpa_into_padded_array___64size_t( + libcrux_ml_kem_utils_into_padded_array___64size_t( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), to_hash0); core_slice___Slice_T___copy_from_slice( @@ -7464,8 +7464,8 @@ void libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_Portable Eurydice_slice shared_secret = uu____3.fst; Eurydice_slice pseudorandomness = uu____3.snd; uint8_t to_hash[800U]; - libcrux_ml_kem_ind_cpa_into_padded_array___800size_t(implicit_rejection_value, - to_hash); + libcrux_ml_kem_utils_into_padded_array___800size_t(implicit_rejection_value, + to_hash); Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t, Eurydice_slice); diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index 3c67ef508..ff2f8c759 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -4,7 +4,8 @@ use crate::{ }, constants::{CPA_PKE_KEY_GENERATION_SEED_SIZE, H_DIGEST_SIZE, SHARED_SECRET_SIZE}, hash_functions::Hash, - ind_cpa::{into_padded_array, serialize_public_key}, + utils::into_padded_array, + ind_cpa::serialize_public_key, serialize::deserialize_ring_elements_reduced, types::{MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey}, vector::Operations, diff --git a/libcrux-ml-kem/src/ind_cpa.rs b/libcrux-ml-kem/src/ind_cpa.rs index 5014f06da..195ecd43c 100644 --- a/libcrux-ml-kem/src/ind_cpa.rs +++ b/libcrux-ml-kem/src/ind_cpa.rs @@ -14,17 +14,9 @@ use crate::{ serialize_uncompressed_ring_element, }, vector::Operations, + utils::into_padded_array, }; -/// Pad the `slice` with `0`s at the end. -#[inline(always)] -pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { - debug_assert!(slice.len() <= LEN); - let mut out = [0u8; LEN]; - out[0..slice.len()].copy_from_slice(slice); - out -} - /// Concatenate `t` and `ρ` into the public key. #[inline(always)] pub(crate) fn serialize_public_key< diff --git a/libcrux-ml-kem/src/lib.rs b/libcrux-ml-kem/src/lib.rs index e0687c7f8..2a431fdb5 100644 --- a/libcrux-ml-kem/src/lib.rs +++ b/libcrux-ml-kem/src/lib.rs @@ -57,6 +57,7 @@ pub(crate) mod constants; /// Helpers for verification and extraction mod helper; +mod utils; mod constant_time_ops; mod hash_functions; diff --git a/libcrux-ml-kem/src/utils.rs b/libcrux-ml-kem/src/utils.rs new file mode 100644 index 000000000..ea5e4734f --- /dev/null +++ b/libcrux-ml-kem/src/utils.rs @@ -0,0 +1,25 @@ +// A couple helper functions and definitions -- this file ends up being bundled in +// libcrux_core.{c,h}, so if you need something that has to be shared across multiple mlkem +// instances / implementations, it can go in here. + +/// Pad the `slice` with `0`s at the end. +#[inline(always)] +pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { + debug_assert!(slice.len() <= LEN); + let mut out = [0u8; LEN]; + out[0..slice.len()].copy_from_slice(slice); + out +} + +// Without these type abbreviations, the monomorphized definitions end up being inserted at the +// first location that they are used, which might be, e.g., the avx2 impl of mlkem512, resulting in +// the portable impl of mlkem512 including the header for the avx2 impl of mlkem512 to have this +// type definition in scope! +// +// To avoid that, we manually place those definitions in this file, which ends up in a shared +// header. +// +// TODO: use proper constants +type Keypair512 = ([u8; 768], [u8;800]); +type Keypair768 = ([u8; 1152], [u8;1184]); +type Keypair1024 = ([u8; 1536], [u8;1568]); From 496e7bfc2245c4d84263fb95f79e7c023673699b Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 11 Jun 2024 10:43:47 +0200 Subject: [PATCH 50/84] fixups --- .github/workflows/c.yml | 7 ++++--- libcrux-ml-kem/c.sh | 12 ++++++++++++ libcrux-ml-kem/c.yaml | 8 ++------ libcrux-ml-kem/c/CMakeLists.txt | 2 +- libcrux-ml-kem/c/README.md | 2 ++ libcrux-ml-kem/src/ind_cca.rs | 2 +- libcrux-ml-kem/src/ind_cpa.rs | 2 +- libcrux-ml-kem/src/mlkem1024.rs | 4 ++-- libcrux-ml-kem/src/mlkem512.rs | 4 ++-- libcrux-ml-kem/src/mlkem768.rs | 2 +- libcrux-ml-kem/src/utils.rs | 16 ++++++++++++---- 11 files changed, 40 insertions(+), 21 deletions(-) diff --git a/.github/workflows/c.yml b/.github/workflows/c.yml index b70951dfb..384e13a30 100644 --- a/.github/workflows/c.yml +++ b/.github/workflows/c.yml @@ -50,9 +50,10 @@ jobs: cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release - - name: 🏃🏻‍♀️ Benchmark - run: ./build/Release/ml_kem_bench - if: ${{ matrix.os == 'windows-latest' }} + # FIXME: Benchmarks on Windows CI are not working right now. + # - name: 🏃🏻‍♀️ Benchmark + # run: ./build/Release/ml_kem_bench + # if: ${{ matrix.os == 'windows-latest' }} - name: 🏃🏻‍♀️ Benchmark run: ./build/ml_kem_bench diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index 7edb43093..11488924c 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -68,3 +68,15 @@ cp $EURYDICE_HOME/include/eurydice_glue.h . clang-format --style=Google -i *.c *.h clang-format --style=Google -i internal/*.h clang-format --style=Google -i intrinsics/*.h + +# Write out infos about the used tools +rm -f code_gen.txt +echo "This code was generated with the following tools:" >> code_gen.txt +echo -n "Charon: " >> code_gen.txt +git -C $CHARON_HOME rev-parse HEAD >> code_gen.txt +echo -n "Eurydice: " >> code_gen.txt +git -C $EURYDICE_HOME rev-parse HEAD >> code_gen.txt +echo -n "Karamel: " >> code_gen.txt +git -C $KRML_HOME rev-parse HEAD >> code_gen.txt +echo -n "F*: " >> code_gen.txt +git -C $FSTAR_HOME rev-parse HEAD >> code_gen.txt diff --git a/libcrux-ml-kem/c.yaml b/libcrux-ml-kem/c.yaml index 4dbc5b102..e6b1e9bb3 100644 --- a/libcrux-ml-kem/c.yaml +++ b/libcrux-ml-kem/c.yaml @@ -13,10 +13,6 @@ files: api: - [libcrux_intrinsics, avx2] - - name: libcrux_platform - private: - - [libcrux_platform, "*"] - # SHA3 (no mention of libcrux_mlkem in this section, please) # Keep the per-target seperation idea: each SHA3 variant in its own file @@ -158,7 +154,7 @@ files: - [ core, "*"] - [ libcrux_ml_kem, types, "*"] - [ libcrux_ml_kem, constant_time_ops, "*"] - - [ libcrux_ml_kem, utils ] + - [ libcrux_ml_kem, utils, "*" ] monomorphizations_using: - [ Eurydice, "*" ] - [ libcrux_ml_kem, types, "*"] @@ -167,7 +163,7 @@ files: - [ libcrux_ml_kem, types ] - [ libcrux_ml_kem, constants ] - [ libcrux_ml_kem, constant_time_ops, "*"] - - [ libcrux_ml_kem, utils ] + - [ libcrux_ml_kem, utils, "*" ] api: - [Eurydice, "*"] diff --git a/libcrux-ml-kem/c/CMakeLists.txt b/libcrux-ml-kem/c/CMakeLists.txt index f74d91c71..89c427918 100644 --- a/libcrux-ml-kem/c/CMakeLists.txt +++ b/libcrux-ml-kem/c/CMakeLists.txt @@ -88,7 +88,7 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") endif() # This is only for local testing and we assume neon on arm64. -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED $ENV{LIBCRUX_NEON}) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED ENV{LIBCRUX_NEON}) message(STATUS "Detected an arm64 architecture") add_compile_definitions(LIBCRUX_AARCH64) diff --git a/libcrux-ml-kem/c/README.md b/libcrux-ml-kem/c/README.md index 9652f89c6..3997bb316 100644 --- a/libcrux-ml-kem/c/README.md +++ b/libcrux-ml-kem/c/README.md @@ -17,6 +17,8 @@ cmake -B build -G "Ninja Multi-Config" cmake --build build ``` +To enable neon builds, set `LIBCRUX_NEON=1`. + ### Test ```bash diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index ff2f8c759..719f009b9 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -4,10 +4,10 @@ use crate::{ }, constants::{CPA_PKE_KEY_GENERATION_SEED_SIZE, H_DIGEST_SIZE, SHARED_SECRET_SIZE}, hash_functions::Hash, - utils::into_padded_array, ind_cpa::serialize_public_key, serialize::deserialize_ring_elements_reduced, types::{MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey}, + utils::into_padded_array, vector::Operations, }; diff --git a/libcrux-ml-kem/src/ind_cpa.rs b/libcrux-ml-kem/src/ind_cpa.rs index 195ecd43c..dbe59a37c 100644 --- a/libcrux-ml-kem/src/ind_cpa.rs +++ b/libcrux-ml-kem/src/ind_cpa.rs @@ -13,8 +13,8 @@ use crate::{ deserialize_then_decompress_ring_element_v, deserialize_to_uncompressed_ring_element, serialize_uncompressed_ring_element, }, - vector::Operations, utils::into_padded_array, + vector::Operations, }; /// Concatenate `t` and `ρ` into the public key. diff --git a/libcrux-ml-kem/src/mlkem1024.rs b/libcrux-ml-kem/src/mlkem1024.rs index 79fb38507..2a1a28a3a 100644 --- a/libcrux-ml-kem/src/mlkem1024.rs +++ b/libcrux-ml-kem/src/mlkem1024.rs @@ -21,9 +21,9 @@ const VECTOR_V_COMPRESSION_FACTOR_1024: usize = 5; const C2_SIZE_1024: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_1024) / 8; const CPA_PKE_SECRET_KEY_SIZE_1024: usize = (RANK_1024 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_1024: usize = T_AS_NTT_ENCODED_SIZE_1024 + 32; +pub(crate) const CPA_PKE_PUBLIC_KEY_SIZE_1024: usize = T_AS_NTT_ENCODED_SIZE_1024 + 32; const CPA_PKE_CIPHERTEXT_SIZE_1024: usize = C1_SIZE_1024 + C2_SIZE_1024; -const SECRET_KEY_SIZE_1024: usize = CPA_PKE_SECRET_KEY_SIZE_1024 +pub(crate) const SECRET_KEY_SIZE_1024: usize = CPA_PKE_SECRET_KEY_SIZE_1024 + CPA_PKE_PUBLIC_KEY_SIZE_1024 + H_DIGEST_SIZE + SHARED_SECRET_SIZE; diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index caf50dda5..f457e551a 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -21,9 +21,9 @@ const VECTOR_V_COMPRESSION_FACTOR_512: usize = 4; const C2_SIZE_512: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_512) / 8; const CPA_PKE_SECRET_KEY_SIZE_512: usize = (RANK_512 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_512: usize = T_AS_NTT_ENCODED_SIZE_512 + 32; +pub(crate) const CPA_PKE_PUBLIC_KEY_SIZE_512: usize = T_AS_NTT_ENCODED_SIZE_512 + 32; const CPA_PKE_CIPHERTEXT_SIZE_512: usize = C1_SIZE_512 + C2_SIZE_512; -const SECRET_KEY_SIZE_512: usize = +pub(crate) const SECRET_KEY_SIZE_512: usize = CPA_PKE_SECRET_KEY_SIZE_512 + CPA_PKE_PUBLIC_KEY_SIZE_512 + H_DIGEST_SIZE + SHARED_SECRET_SIZE; const ETA1: usize = 3; diff --git a/libcrux-ml-kem/src/mlkem768.rs b/libcrux-ml-kem/src/mlkem768.rs index 3bd9333f4..a7030cb0c 100644 --- a/libcrux-ml-kem/src/mlkem768.rs +++ b/libcrux-ml-kem/src/mlkem768.rs @@ -21,7 +21,7 @@ const VECTOR_V_COMPRESSION_FACTOR_768: usize = 4; const C2_SIZE_768: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_768) / 8; const CPA_PKE_SECRET_KEY_SIZE_768: usize = (RANK_768 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_768: usize = T_AS_NTT_ENCODED_SIZE_768 + 32; +pub(crate) const CPA_PKE_PUBLIC_KEY_SIZE_768: usize = T_AS_NTT_ENCODED_SIZE_768 + 32; // These two are used in the hybrid kem. This could probably be improved. pub(crate) const CPA_PKE_CIPHERTEXT_SIZE_768: usize = C1_SIZE_768 + C2_SIZE_768; pub(crate) const SECRET_KEY_SIZE_768: usize = diff --git a/libcrux-ml-kem/src/utils.rs b/libcrux-ml-kem/src/utils.rs index ea5e4734f..67300d163 100644 --- a/libcrux-ml-kem/src/utils.rs +++ b/libcrux-ml-kem/src/utils.rs @@ -1,3 +1,4 @@ +// C extraction: // A couple helper functions and definitions -- this file ends up being bundled in // libcrux_core.{c,h}, so if you need something that has to be shared across multiple mlkem // instances / implementations, it can go in here. @@ -11,6 +12,10 @@ pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { out } +// C extraction: +// +// This is only enabled when extracting. +// // Without these type abbreviations, the monomorphized definitions end up being inserted at the // first location that they are used, which might be, e.g., the avx2 impl of mlkem512, resulting in // the portable impl of mlkem512 including the header for the avx2 impl of mlkem512 to have this @@ -19,7 +24,10 @@ pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { // To avoid that, we manually place those definitions in this file, which ends up in a shared // header. // -// TODO: use proper constants -type Keypair512 = ([u8; 768], [u8;800]); -type Keypair768 = ([u8; 1152], [u8;1184]); -type Keypair1024 = ([u8; 1536], [u8;1568]); +// TODO: use proper constants. They don't work right now ... +#[cfg(eurydice)] +mod extraction_helper { + type Keypair512 = ([u8; 768], [u8; 800]); + type Keypair768 = ([u8; 1152], [u8; 1184]); + type Keypair1024 = ([u8; 1536], [u8; 1568]); +} From ad7b9cbbb60dc6b311ffcd9f64174d601adf3844 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 11 Jun 2024 10:55:16 +0200 Subject: [PATCH 51/84] C update --- libcrux-ml-kem/c/code_gen.txt | 5 ++++ libcrux-ml-kem/c/internal/libcrux_core.h | 18 ++++++------- .../c/internal/libcrux_mlkem_avx2.h | 6 ++--- .../c/internal/libcrux_mlkem_portable.h | 6 ++--- libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h | 6 ++--- .../c/internal/libcrux_sha3_internal.h | 6 ++--- libcrux-ml-kem/c/libcrux_core.c | 6 ++--- libcrux-ml-kem/c/libcrux_core.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem1024.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem1024_portable.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem1024_portable.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem512.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem512_avx2.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem512_avx2.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem512_portable.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem512_portable.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem768.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem768_avx2.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem768_avx2.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem768_portable.c | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem768_portable.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 24 ++++++++--------- libcrux-ml-kem/c/libcrux_mlkem_avx2.h | 6 ++--- libcrux-ml-kem/c/libcrux_mlkem_portable.c | 24 ++++++++--------- libcrux-ml-kem/c/libcrux_mlkem_portable.h | 6 ++--- libcrux-ml-kem/c/libcrux_sha3.h | 6 ++--- libcrux-ml-kem/c/libcrux_sha3_avx2.c | 6 ++--- libcrux-ml-kem/c/libcrux_sha3_avx2.h | 6 ++--- libcrux-ml-kem/c/libcrux_sha3_internal.h | 6 ++--- .../c/libcrux_sha3_libcrux_ml_kem.h | 26 +++++++++++++++++++ libcrux-ml-kem/c/libcrux_sha3_neon.c | 6 ++--- libcrux-ml-kem/c/libcrux_sha3_neon.h | 6 ++--- 34 files changed, 151 insertions(+), 120 deletions(-) create mode 100644 libcrux-ml-kem/c/code_gen.txt create mode 100644 libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h diff --git a/libcrux-ml-kem/c/code_gen.txt b/libcrux-ml-kem/c/code_gen.txt new file mode 100644 index 000000000..511c010db --- /dev/null +++ b/libcrux-ml-kem/c/code_gen.txt @@ -0,0 +1,5 @@ +This code was generated with the following tools: +Charon: 0b8b7a82c2a18f65ab9df16f222d52594c17f59c +Eurydice: f5a2305081d09f3b45ed272e5388e542f4c4a7c1 +Karamel: 22425a93c68d9e3794909f98854aaffdc0560510 +F*: \ No newline at end of file diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index 63c1e03ed..b4f7dd467 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __internal_libcrux_core_H @@ -44,20 +44,20 @@ void libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( #define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) -typedef struct libcrux_ml_kem_utils_Keypair1024_s { +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair1024_s { uint8_t fst[1536U]; uint8_t snd[1568U]; -} libcrux_ml_kem_utils_Keypair1024; +} libcrux_ml_kem_utils_extraction_helper_Keypair1024; -typedef struct libcrux_ml_kem_utils_Keypair512_s { +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair512_s { uint8_t fst[768U]; uint8_t snd[800U]; -} libcrux_ml_kem_utils_Keypair512; +} libcrux_ml_kem_utils_extraction_helper_Keypair512; -typedef struct libcrux_ml_kem_utils_Keypair768_s { +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { uint8_t fst[1152U]; uint8_t snd[1184U]; -} libcrux_ml_kem_utils_Keypair768; +} libcrux_ml_kem_utils_extraction_helper_Keypair768; libcrux_ml_kem_types_MlKemPublicKey____1568size_t libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1568size_t( diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 58155643c..ffea50616 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __internal_libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index b7caa27e1..e33f8010e 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __internal_libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index 05fe23ee6..524d2bd7e 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index 22e02bd6d..d31a0635a 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index cbcc3017b..030415b38 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "internal/libcrux_core.h" diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 62ceebc2c..e139b26ab 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 9fcadba75..fd54f0af6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index bef973b2c..dd3a50e17 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem1024_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index 7c71dabe4..e147197b9 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem1024_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index f96a815a6..5bc2ce976 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem1024_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index 83fc5be46..1178c18f8 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem1024_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 80d9dd3f8..923a244ca 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index db169fa82..848b46be2 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem512_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index ec92a98ea..4fc0e2978 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem512_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index 4d79fb75e..58a1c1e90 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem512_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index fea44f677..40bd5b724 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem512_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 1ee6f610a..6ae2774e6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index 4a14c563e..b4ded9ed6 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem768_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index 0d5024551..9d0c5e1f2 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem768_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 00b723c9f..1981d0c6c 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_mlkem768_portable.h" diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index 17f457d06..190d95aa7 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index a9e1357cc..ea61181bb 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "internal/libcrux_mlkem_avx2.h" @@ -2612,7 +2612,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static libcrux_ml_kem_utils_Keypair768 +static libcrux_ml_kem_utils_extraction_helper_Keypair768 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -2687,7 +2687,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); uint8_t uu____7[1184U]; memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair768 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; @@ -2774,7 +2774,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair768 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; @@ -5057,7 +5057,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static libcrux_ml_kem_utils_Keypair1024 +static libcrux_ml_kem_utils_extraction_helper_Keypair1024 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -5132,7 +5132,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); uint8_t uu____7[1568U]; memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair1024 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair1024 lit; memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; @@ -5219,7 +5219,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair1024 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair1024 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1536U]; @@ -6571,7 +6571,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); } -static libcrux_ml_kem_utils_Keypair512 +static libcrux_ml_kem_utils_extraction_helper_Keypair512 generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -6646,7 +6646,7 @@ generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_f memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); uint8_t uu____7[800U]; memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair512 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair512 lit; memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; @@ -6733,7 +6733,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vecto (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair512 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair512 uu____0 = generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[768U]; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index 01d55d083..1a43363a5 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index c56a9bb7b..95917c799 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "internal/libcrux_mlkem_portable.h" @@ -3206,7 +3206,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_4size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_utils_Keypair1024 +static libcrux_ml_kem_utils_extraction_helper_Keypair1024 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -3281,7 +3281,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)1536U * sizeof(uint8_t)); uint8_t uu____7[1568U]; memcpy(uu____7, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair1024 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair1024 lit; memcpy(lit.fst, uu____6, (size_t)1536U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1568U * sizeof(uint8_t)); return lit; @@ -3368,7 +3368,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair1024 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair1024 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___4size_t___4size_t_1536size_t_1568size_t_1536size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1536U]; @@ -5218,7 +5218,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_utils_Keypair768 +static libcrux_ml_kem_utils_extraction_helper_Keypair768 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -5293,7 +5293,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); uint8_t uu____7[1184U]; memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair768 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); return lit; @@ -5380,7 +5380,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair768 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; @@ -6680,7 +6680,7 @@ compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_2size_t( libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); } -static libcrux_ml_kem_utils_Keypair512 +static libcrux_ml_kem_utils_extraction_helper_Keypair512 generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( Eurydice_slice key_generation_seed) { uint8_t hashed[64U]; @@ -6755,7 +6755,7 @@ generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_h memcpy(uu____6, secret_key_serialized, (size_t)768U * sizeof(uint8_t)); uint8_t uu____7[800U]; memcpy(uu____7, public_key_serialized, (size_t)800U * sizeof(uint8_t)); - libcrux_ml_kem_utils_Keypair512 lit; + libcrux_ml_kem_utils_extraction_helper_Keypair512 lit; memcpy(lit.fst, uu____6, (size_t)768U * sizeof(uint8_t)); memcpy(lit.snd, uu____7, (size_t)800U * sizeof(uint8_t)); return lit; @@ -6842,7 +6842,7 @@ libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_Portable (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, size_t, Eurydice_slice); - libcrux_ml_kem_utils_Keypair512 uu____0 = + libcrux_ml_kem_utils_extraction_helper_Keypair512 uu____0 = generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___2size_t___2size_t_768size_t_800size_t_768size_t_3size_t_192size_t( ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[768U]; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index f9c6b1bc5..2afec0115 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index 189a64804..90e660fac 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index e8210950d..2d0336282 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "internal/libcrux_sha3_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index bc53c956a..0e5d15b71 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 6511292a8..ff9426779 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h b/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h new file mode 100644 index 000000000..ef0b3e58e --- /dev/null +++ b/libcrux-ml-kem/c/libcrux_sha3_libcrux_ml_kem.h @@ -0,0 +1,26 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 + */ + +#ifndef __libcrux_sha3_libcrux_ml_kem_H +#define __libcrux_sha3_libcrux_ml_kem_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" + +extern bool libcrux_platform_platform_simd256_support(void); + +extern bool libcrux_platform_platform_simd128_support(void); + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_libcrux_ml_kem_H_DEFINED +#endif diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 9e9a598e9..d8c40c084 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 6a3cf4a83..5e1a4a79d 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -1,8 +1,8 @@ /* This file was generated by KaRaMeL - KaRaMeL invocation: /Users/jonathan/Code/eurydice/eurydice --config ../c.yaml - ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: 58c915a8 KaRaMeL - version: 6bb7cd3e + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../c.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 22425a93 */ #ifndef __libcrux_sha3_neon_H From cb59dcead2ea5e4e49fb96ca36ef8c3c1013fe6c Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 11 Jun 2024 11:04:23 +0200 Subject: [PATCH 52/84] drop old polynomial code --- Cargo.toml | 1 - kyber-c.yaml | 50 - kyber-crate-tests/kyber.rs | 19 - kyber-crate-tests/kyber_kats/README.md | 1 - kyber-crate-tests/kyber_kats/generate_kats.py | 91 - kyber-crate-tests/kyber_kats/kyber.py | 363 --- .../kyber_kats/nistkats_1024.json | 802 ------- .../kyber_kats/nistkats_512.json | 802 ------- .../kyber_kats/nistkats_768.json | 802 ------- kyber-crate-tests/kyber_nistkats.rs | 78 - kyber-crate.sh | 95 - libcrux-simd/Cargo.toml | 16 - libcrux-simd/src/aarch64.rs | 130 - libcrux-simd/src/lib.rs | 12 - libcrux-simd/src/scalar.rs | 61 - polynomials-aarch64/src/neon.rs | 282 --- polynomials-aarch64/src/rejsample.rs | 797 ------- .../Libcrux_polynomials_avx2.Arithmetic.fst | 159 -- .../Libcrux_polynomials_avx2.Compress.fst | 192 -- ...polynomials_avx2.Intrinsics_extraction.fst | 549 ----- .../Libcrux_polynomials_avx2.Ntt.fst | 192 -- .../Libcrux_polynomials_avx2.Portable.fst | 429 ---- .../Libcrux_polynomials_avx2.Sampling.fst | 2111 ----------------- .../Libcrux_polynomials_avx2.Serialize.fst | 557 ----- .../extraction/Libcrux_polynomials_avx2.fst | 412 ---- polynomials-avx2/src/sampling.rs | 814 ------- 26 files changed, 9817 deletions(-) delete mode 100644 kyber-c.yaml delete mode 100644 kyber-crate-tests/kyber.rs delete mode 100644 kyber-crate-tests/kyber_kats/README.md delete mode 100755 kyber-crate-tests/kyber_kats/generate_kats.py delete mode 100644 kyber-crate-tests/kyber_kats/kyber.py delete mode 100644 kyber-crate-tests/kyber_kats/nistkats_1024.json delete mode 100644 kyber-crate-tests/kyber_kats/nistkats_512.json delete mode 100644 kyber-crate-tests/kyber_kats/nistkats_768.json delete mode 100644 kyber-crate-tests/kyber_nistkats.rs delete mode 100755 kyber-crate.sh delete mode 100644 libcrux-simd/Cargo.toml delete mode 100644 libcrux-simd/src/aarch64.rs delete mode 100644 libcrux-simd/src/lib.rs delete mode 100644 libcrux-simd/src/scalar.rs delete mode 100644 polynomials-aarch64/src/neon.rs delete mode 100644 polynomials-aarch64/src/rejsample.rs delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Intrinsics_extraction.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst delete mode 100644 polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.fst delete mode 100644 polynomials-avx2/src/sampling.rs diff --git a/Cargo.toml b/Cargo.toml index 30e7e1f9d..881de10d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "benchmarks", "fuzz", "libcrux-ml-kem", - "libcrux-simd", "libcrux-sha3", "libcrux-ml-dsa", "libcrux-intrinsics", diff --git a/kyber-c.yaml b/kyber-c.yaml deleted file mode 100644 index 62bd1b3df..000000000 --- a/kyber-c.yaml +++ /dev/null @@ -1,50 +0,0 @@ -files: - - name: libcrux_digest - api: - - [libcrux, digest] - - [libcrux, digest, "*"] - include_in_h: - - '"libcrux_hacl_glue.h"' - - - name: libcrux_platform - api: - - [libcrux_platform] - - - name: libcrux_kyber512 - api: - - [libcrux_kyber, kyber512] - include_in_c: - - '"libcrux_hacl_glue.h"' - - - name: libcrux_kyber768 - api: - - [libcrux_kyber, kyber768] - include_in_c: - - '"libcrux_hacl_glue.h"' - - - name: libcrux_kyber1024 - api: - - [libcrux_kyber, kyber1024] - include_in_c: - - '"libcrux_hacl_glue.h"' - - - name: libcrux_kyber_common - private: - - [libcrux_kyber, "*"] - include_in_h: - - '"libcrux_hacl_glue.h"' - inline_static: true - - - name: core - private: - - [core, "*"] - # NOTE: putting Eurydice in core prevent eurydice from detecting spurious calls - # across C translation units from Eurydice to core (notably related to the - # result type), and thus prevents eurydice from flipping some result types - # being public, which pollutes the header. - # NOTE: putting Eurydice as public (api) is required, since some compilation - # passes produce calls to Eurydice.slice_to_array2 *after* reachability - # analysis, meaning that we cannot let reachability analysis eliminate - # Eurydice definitions on an as-needed basis - api: - - [Eurydice, "*"] diff --git a/kyber-crate-tests/kyber.rs b/kyber-crate-tests/kyber.rs deleted file mode 100644 index d30e7b266..000000000 --- a/kyber-crate-tests/kyber.rs +++ /dev/null @@ -1,19 +0,0 @@ -use libcrux_kyber::kyber768::*; -use rand::rngs::OsRng; -use rand::RngCore; - -#[test] -fn consistency_768() { - let mut rng = OsRng; - let mut randomness = [0u8; 64]; - rng.fill_bytes(&mut randomness); - - let kp = generate_key_pair(randomness); - let mut randomness = [0u8; 32]; - rng.fill_bytes(&mut randomness); - - let ct = encapsulate(kp.public_key(), randomness); - let shared_secret_decapsulated = decapsulate(kp.private_key(), &ct.0); - - assert_eq!(shared_secret_decapsulated, ct.1); -} diff --git a/kyber-crate-tests/kyber_kats/README.md b/kyber-crate-tests/kyber_kats/README.md deleted file mode 100644 index 17024363b..000000000 --- a/kyber-crate-tests/kyber_kats/README.md +++ /dev/null @@ -1 +0,0 @@ -In order to regenerate the JSON KAT files for all parameter sets, simply run `./generate_kats.py`. diff --git a/kyber-crate-tests/kyber_kats/generate_kats.py b/kyber-crate-tests/kyber_kats/generate_kats.py deleted file mode 100755 index 7dd7530df..000000000 --- a/kyber-crate-tests/kyber_kats/generate_kats.py +++ /dev/null @@ -1,91 +0,0 @@ -#! /usr/bin/env python3 - -# This file is a modified version of: -# https://github.com/bwesterb/draft-schwabe-cfrg-kyber/blob/main/kyber_test.py - -from kyber import * - -import hashlib -import json - -import Crypto -from Crypto.Cipher import AES - - -class NistDRBG: - """NIST's DRBG used to generate NIST's Known Answer Tests (KATs), - see PQCgenKAT.c.""" - - def __init__(self, seed): - self.key = b"\0" * 32 - self.v = 0 - assert len(seed) == 48 - self._update(seed) - - def _update(self, seed): - b = AES.new(self.key, AES.MODE_ECB) - buf = b"" - for i in range(3): - self.v += 1 - buf += b.encrypt(self.v.to_bytes(16, "big")) - if seed is not None: - buf = bytes([x ^ y for x, y in zip(seed, buf)]) - self.key = buf[:32] - self.v = int.from_bytes(buf[32:], "big") - - def read(self, length): - b = AES.new(self.key, AES.MODE_ECB) - ret = b"" - while len(ret) < length: - self.v += 1 - block = b.encrypt(self.v.to_bytes(16, "big")) - ret += block - self._update(None) - return ret[:length] - - -for params in [params512, params768, params1024]: - kats_formatted = [] - seed = bytes(range(48)) - g = NistDRBG(seed) - - print("Generating KATs for {} parameter set.".format(params)) - - for i in range(100): - seed = g.read(48) - g2 = NistDRBG(seed) - - kseed = g2.read(32) + g2.read(32) - eseed = g2.read(32) - - pk, sk = KeyGen(kseed, params) - ct, ss = Enc(pk, eseed, params) - - Dec(sk, ct, params) - - kats_formatted.append( - { - "key_generation_seed": bytes(kseed).hex(), - "sha3_256_hash_of_public_key": bytes( - hashlib.sha3_256(pk).digest() - ).hex(), - "sha3_256_hash_of_secret_key": bytes( - hashlib.sha3_256(sk).digest() - ).hex(), - "encapsulation_seed": bytes(eseed).hex(), - "sha3_256_hash_of_ciphertext": bytes( - hashlib.sha3_256(ct).digest() - ).hex(), - "shared_secret": bytes(ss).hex(), - } - ) - - if params == params512: - output_suffix = "512" - elif params == params768: - output_suffix = "768" - else: - output_suffix = "1024" - - with open("nistkats_{}.json".format(output_suffix), "w") as f: - json.dump(kats_formatted, f, ensure_ascii=False, indent=4) diff --git a/kyber-crate-tests/kyber_kats/kyber.py b/kyber-crate-tests/kyber_kats/kyber.py deleted file mode 100644 index 60b6463fe..000000000 --- a/kyber-crate-tests/kyber_kats/kyber.py +++ /dev/null @@ -1,363 +0,0 @@ -# This file is: -# https://github.com/bwesterb/draft-schwabe-cfrg-kyber/blob/a03ab13c241a1a0b6adc676d27be79843b03abc8/kyber.py -# with changes made to match the FIPS-203 draft as well as formatting changes -# made by the black formatter. - -# WARNING This is a specification of Kyber; not a production ready -# implementation. It is slow and does not run in constant time. - -# Requires the CryptoDome for SHAKE. To install, run -# -# pip install pycryptodome pytest -from Crypto.Hash import SHAKE128, SHAKE256 - -import io -import hashlib -import functools -import collections - -from math import floor - -q = 3329 -nBits = 8 -zeta = 17 -eta2 = 2 - -n = 2**nBits -inv2 = (q + 1) // 2 # inverse of 2 - -params = collections.namedtuple("params", ("k", "du", "dv", "eta1")) - -params512 = params(k=2, du=10, dv=4, eta1=3) -params768 = params(k=3, du=10, dv=4, eta1=2) -params1024 = params(k=4, du=11, dv=5, eta1=2) - - -def smod(x): - r = x % q - if r > (q - 1) // 2: - r -= q - return r - - -# Rounds to nearest integer with ties going up -def Round(x): - return int(floor(x + 0.5)) - - -def Compress(x, d): - return Round((2**d / q) * x) % (2**d) - - -def Decompress(y, d): - assert 0 <= y and y <= 2**d - return Round((q / 2**d) * y) - - -def BitsToWords(bs, w): - assert len(bs) % w == 0 - return [sum(bs[i + j] * 2**j for j in range(w)) for i in range(0, len(bs), w)] - - -def WordsToBits(bs, w): - return sum([[(b >> i) % 2 for i in range(w)] for b in bs], []) - - -def Encode(a, w): - return bytes(BitsToWords(WordsToBits(a, w), 8)) - - -def Decode(a, w): - return BitsToWords(WordsToBits(a, 8), w) - - -def brv(x): - """Reverses a 7-bit number""" - return int("".join(reversed(bin(x)[2:].zfill(nBits - 1))), 2) - - -class Poly: - def __init__(self, cs=None): - self.cs = (0,) * n if cs is None else tuple(cs) - assert len(self.cs) == n - - def __add__(self, other): - return Poly((a + b) % q for a, b in zip(self.cs, other.cs)) - - def __neg__(self): - return Poly(q - a for a in self.cs) - - def __sub__(self, other): - return self + -other - - def __str__(self): - return f"Poly({self.cs}" - - def __eq__(self, other): - return self.cs == other.cs - - def NTT(self): - cs = list(self.cs) - layer = n // 2 - zi = 0 - while layer >= 2: - for offset in range(0, n - layer, 2 * layer): - zi += 1 - z = pow(zeta, brv(zi), q) - - for j in range(offset, offset + layer): - t = (z * cs[j + layer]) % q - cs[j + layer] = (cs[j] - t) % q - cs[j] = (cs[j] + t) % q - layer //= 2 - return Poly(cs) - - def RefNTT(self): - # Slower, but simpler, version of the NTT. - cs = [0] * n - for i in range(0, n, 2): - for j in range(n // 2): - z = pow(zeta, (2 * brv(i // 2) + 1) * j, q) - cs[i] = (cs[i] + self.cs[2 * j] * z) % q - cs[i + 1] = (cs[i + 1] + self.cs[2 * j + 1] * z) % q - return Poly(cs) - - def InvNTT(self): - cs = list(self.cs) - layer = 2 - zi = n // 2 - while layer < n: - for offset in range(0, n - layer, 2 * layer): - zi -= 1 - z = pow(zeta, brv(zi), q) - - for j in range(offset, offset + layer): - t = (cs[j + layer] - cs[j]) % q - cs[j] = (inv2 * (cs[j] + cs[j + layer])) % q - cs[j + layer] = (inv2 * z * t) % q - layer *= 2 - return Poly(cs) - - def MulNTT(self, other): - """Computes self o other, the multiplication of self and other - in the NTT domain.""" - cs = [None] * n - for i in range(0, n, 2): - a1 = self.cs[i] - a2 = self.cs[i + 1] - b1 = other.cs[i] - b2 = other.cs[i + 1] - z = pow(zeta, 2 * brv(i // 2) + 1, q) - cs[i] = (a1 * b1 + z * a2 * b2) % q - cs[i + 1] = (a2 * b1 + a1 * b2) % q - return Poly(cs) - - def Compress(self, d): - return Poly(Compress(c, d) for c in self.cs) - - def Decompress(self, d): - return Poly(Decompress(c, d) for c in self.cs) - - def Encode(self, d): - return Encode(self.cs, d) - - -def sampleUniform(stream): - cs = [] - while True: - b = stream.read(3) - d1 = b[0] + 256 * (b[1] % 16) - d2 = (b[1] >> 4) + 16 * b[2] - assert d1 + 2**12 * d2 == b[0] + 2**8 * b[1] + 2**16 * b[2] - for d in [d1, d2]: - if d >= q: - continue - cs.append(d) - if len(cs) == n: - return Poly(cs) - - -def CBD(a, eta): - assert len(a) == 64 * eta - b = WordsToBits(a, 8) - cs = [] - for i in range(n): - cs.append((sum(b[:eta]) - sum(b[eta : 2 * eta])) % q) - b = b[2 * eta :] - return Poly(cs) - - -def XOF(seed, j, i): - h = SHAKE128.new() - h.update(seed + bytes([j, i])) - return h - - -def PRF1(seed, nonce): - assert len(seed) == 32 - h = SHAKE256.new() - h.update(seed + bytes([nonce])) - return h - - -def PRF2(seed, msg): - assert len(seed) == 32 - h = SHAKE256.new() - h.update(seed + msg) - return h.read(32) - - -def G(seed): - h = hashlib.sha3_512(seed).digest() - return h[:32], h[32:] - - -def H(msg): - return hashlib.sha3_256(msg).digest() - - -class Vec: - def __init__(self, ps): - self.ps = tuple(ps) - - def NTT(self): - return Vec(p.NTT() for p in self.ps) - - def InvNTT(self): - return Vec(p.InvNTT() for p in self.ps) - - def DotNTT(self, other): - """Computes the dot product in NTT domain.""" - return sum((a.MulNTT(b) for a, b in zip(self.ps, other.ps)), Poly()) - - def __add__(self, other): - return Vec(a + b for a, b in zip(self.ps, other.ps)) - - def Compress(self, d): - return Vec(p.Compress(d) for p in self.ps) - - def Decompress(self, d): - return Vec(p.Decompress(d) for p in self.ps) - - def Encode(self, d): - return Encode(sum((p.cs for p in self.ps), ()), d) - - def __eq__(self, other): - return self.ps == other.ps - - -def EncodeVec(vec, w): - return Encode(sum([p.cs for p in vec.ps], ()), w) - - -def DecodeVec(bs, k, w): - cs = Decode(bs, w) - return Vec(Poly(cs[n * i : n * (i + 1)]) for i in range(k)) - - -def DecodePoly(bs, w): - return Poly(Decode(bs, w)) - - -class Matrix: - def __init__(self, cs): - """Samples the matrix uniformly from seed rho""" - self.cs = tuple(tuple(row) for row in cs) - - def MulNTT(self, vec): - """Computes matrix multiplication A*vec in the NTT domain.""" - return Vec(Vec(row).DotNTT(vec) for row in self.cs) - - def T(self): - """Returns transpose of matrix""" - k = len(self.cs) - return Matrix((self.cs[j][i] for j in range(k)) for i in range(k)) - - -def sampleMatrix(rho, k): - return Matrix([[sampleUniform(XOF(rho, j, i)) for j in range(k)] for i in range(k)]) - - -def sampleNoise(sigma, eta, offset, k): - return Vec(CBD(PRF1(sigma, i + offset).read(64 * eta), eta) for i in range(k)) - - -def constantTimeSelectOnEquality(a, b, ifEq, ifNeq): - # WARNING! In production code this must be done in a - # data-independent constant-time manner, which this implementation - # is not. In fact, many more lines of code in this - # file are not constant-time. - return ifEq if a == b else ifNeq - - -def InnerKeyGen(seed, params): - assert len(seed) == 32 - rho, sigma = G(seed) - A = sampleMatrix(rho, params.k) - s = sampleNoise(sigma, params.eta1, 0, params.k) - e = sampleNoise(sigma, params.eta1, params.k, params.k) - sHat = s.NTT() - eHat = e.NTT() - tHat = A.MulNTT(sHat) + eHat - pk = EncodeVec(tHat, 12) + rho - sk = EncodeVec(sHat, 12) - return (pk, sk) - - -def InnerEnc(pk, msg, seed, params): - assert len(msg) == 32 - tHat = DecodeVec(pk[:-32], params.k, 12) - rho = pk[-32:] - A = sampleMatrix(rho, params.k) - r = sampleNoise(seed, params.eta1, 0, params.k) - e1 = sampleNoise(seed, eta2, params.k, params.k) - e2 = sampleNoise(seed, eta2, 2 * params.k, 1).ps[0] - rHat = r.NTT() - u = A.T().MulNTT(rHat).InvNTT() + e1 - m = Poly(Decode(msg, 1)).Decompress(1) - v = tHat.DotNTT(rHat).InvNTT() + e2 + m - c1 = u.Compress(params.du).Encode(params.du) - c2 = v.Compress(params.dv).Encode(params.dv) - return c1 + c2 - - -def InnerDec(sk, ct, params): - split = params.du * params.k * n // 8 - c1, c2 = ct[:split], ct[split:] - u = DecodeVec(c1, params.k, params.du).Decompress(params.du) - v = DecodePoly(c2, params.dv).Decompress(params.dv) - sHat = DecodeVec(sk, params.k, 12) - return (v - sHat.DotNTT(u.NTT()).InvNTT()).Compress(1).Encode(1) - - -def KeyGen(seed, params): - assert len(seed) == 64 - z = seed[32:] - pk, sk2 = InnerKeyGen(seed[:32], params) - h = H(pk) - return (pk, sk2 + pk + h + z) - - -def Enc(pk, seed, params): - assert len(seed) == 32 - - m = seed - K, r = G(m + H(pk)) - ct = InnerEnc(pk, m, r, params) - return (ct, K) - - -def Dec(sk, ct, params): - sk2 = sk[: 12 * params.k * n // 8] - pk = sk[12 * params.k * n // 8 : 24 * params.k * n // 8 + 32] - h = sk[24 * params.k * n // 8 + 32 : 24 * params.k * n // 8 + 64] - z = sk[24 * params.k * n // 8 + 64 : 24 * params.k * n // 8 + 96] - m2 = InnerDec(sk, ct, params) - K2, r2 = G(m2 + h) - ct2 = InnerEnc(pk, m2, r2, params) - return constantTimeSelectOnEquality( - ct2, - ct, - K2, # if ct == ct2 - PRF2(z, ct), # if ct != ct2 - ) diff --git a/kyber-crate-tests/kyber_kats/nistkats_1024.json b/kyber-crate-tests/kyber_kats/nistkats_1024.json deleted file mode 100644 index 3d5739981..000000000 --- a/kyber-crate-tests/kyber_kats/nistkats_1024.json +++ /dev/null @@ -1,802 +0,0 @@ -[ - { - "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", - "sha3_256_hash_of_public_key": "8a39e87d531f3527c207edcc1db7faddcf9628391879b335c707839a0db051a8", - "sha3_256_hash_of_secret_key": "ed1f6cb687c37931ea2aa80d9c956f277a9df532649661035c6e2f9872132638", - "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", - "sha3_256_hash_of_ciphertext": "5ef5d180bf8d4493ef8e8ddc23c22e428840c362a05a25fd306c6c528bd90f8c", - "shared_secret": "63a1039074f01f2651213ad9350d6561cb03a60400e74118bb4464d87b9db205" - }, - { - "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", - "sha3_256_hash_of_public_key": "c9ede13be3dbb0edc3ab08226cae11771ff4c0b04a564b64a0d9ff10e373e986", - "sha3_256_hash_of_secret_key": "9b5876610793ae42f683d94f736d8d7e0e033bee588bab07a31c9cdb4ab99a5d", - "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", - "sha3_256_hash_of_ciphertext": "bef440cb5a14bfa652ff69fc431b59980147a2408df8a893f0fafded11d6cfa3", - "shared_secret": "856d56ee09279a13f9abdca14ecbe8ca9968495f09a0758b6d1c8376099365eb" - }, - { - "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", - "sha3_256_hash_of_public_key": "ff2546623aee72025fb6746fba736bae0e80e257e66edbf09d8d4dc11049cda4", - "sha3_256_hash_of_secret_key": "57155298b53d3af5d6db214dfa91a9e16f8d5de570bbff5dba5f4cd84098f255", - "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", - "sha3_256_hash_of_ciphertext": "28e308a6f91068b01a7065b8579fcb6234ecd9bb8d3172b6dfc5a3a470050ea7", - "shared_secret": "c33a4432cc441b7683605c29afdecc81922cf234e02be8c2fbc4e2a7a3b4b078" - }, - { - "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", - "sha3_256_hash_of_public_key": "25b786a67de17d61b2fc0e85a13924398aab931896b6174089569f08b7260687", - "sha3_256_hash_of_secret_key": "d188a2637dfe80dbd0fc25165eb4898923888a82c10f6ff0b8ddb5bf251c0650", - "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", - "sha3_256_hash_of_ciphertext": "8427a1684769e63ec43e97ecbe7b7e654b6e63433bccd23340849904e02767dd", - "shared_secret": "7c14fb353ba421705de44f2a12ddc5ad9b11e30e7b0e163cebebe2da79a7293f" - }, - { - "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", - "sha3_256_hash_of_public_key": "d35e259a200d16048302df38d8e7f9e1c3352502c43f086fe166325048fdce9c", - "sha3_256_hash_of_secret_key": "020ba30e5832867a6db83cdb1e60ddf0b0a88fb33919edb84b246a345d11da6c", - "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", - "sha3_256_hash_of_ciphertext": "b52dc0a41015132b3e7a1ae6f544f12601869bf0673625964e5c4e05cbe656e0", - "shared_secret": "35d2a2ab0e91d365a3e2e99bbe3f5121f2eeb528305cc7730f679e10ec1c9b8a" - }, - { - "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", - "sha3_256_hash_of_public_key": "5a5db7d619be642bd87294527b3f859372b279a1e6074824d9632b5d7f616e42", - "sha3_256_hash_of_secret_key": "630f093cb1ff96bff76ede70e970a009a9e5d28fed660e68127d31c3b6dbdb2a", - "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", - "sha3_256_hash_of_ciphertext": "4714a5497351399718258f490da0ce28ce8211aad6975546cb4351c8ebe61917", - "shared_secret": "8084cfff3d54b7680e737ed71c37e449f1f9d74bf6735696c46910b13d42d1f1" - }, - { - "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", - "sha3_256_hash_of_public_key": "f0d1acd4fe1bd3bad938c23ec5a7f320766e01005e32769724abb4ebac578def", - "sha3_256_hash_of_secret_key": "664f3632f56ebc5c509931ff3b7e1845265e42a76e20550b683527d7d24e8df8", - "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", - "sha3_256_hash_of_ciphertext": "4ebd3e44b82b03c01ec2aa9e8805e53b8c8022e987fc9eca59c9a5cfcb1c4a84", - "shared_secret": "3e94b68a80291e957f9dd0a15b112ad75bfa07951ccb36c2de610e6755a4a0d6" - }, - { - "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", - "sha3_256_hash_of_public_key": "7008db565f7ab9c362dc38dcd3e30e5da873c559e9a9222710e8d2e7f6417ce6", - "sha3_256_hash_of_secret_key": "9e774cb57c18575de3ec6a9677e40626c2026e47c389c7a3dc5422d8a83b747b", - "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", - "sha3_256_hash_of_ciphertext": "1cb3879c49c65c184d605bc6daa22f63affd2a005e145103e6c1ac1ad683d976", - "shared_secret": "900649130f9c28082eab5ce3d128593eeaae89667d7fa4da23fcdfc1573995fa" - }, - { - "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", - "sha3_256_hash_of_public_key": "143b9c53320cdb1b7e8d71efd1f0a1ad5ad1e1ce84dd9fe7c92f19c926388e3c", - "sha3_256_hash_of_secret_key": "63707e33c30114732374ac21fd5be61e6dfa7dd85a36eef2e2bae6b3d0599a71", - "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", - "sha3_256_hash_of_ciphertext": "780162548f2d85c00f0276f1db2d6566421cf718679147740d279660fb742544", - "shared_secret": "084aafffcc38ac80dfc02548df07f6e7809eb0644385abce0fc569821a907011" - }, - { - "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", - "sha3_256_hash_of_public_key": "f2d009cde4abd55a2c7417c9341792e60eaa8e26b53a3aae805746401c4c446f", - "sha3_256_hash_of_secret_key": "2a53faa8053fa21b7b07a96ea259c052ef78746c5d53e2857e9f30bd20d3f2b6", - "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", - "sha3_256_hash_of_ciphertext": "9b7ead45e0e00c615fce96105720d82ba431692f92e1a73e14b490219c8dda2b", - "shared_secret": "a7fd777a337219e1d0ad2cdb47fa18f4685ac343bc537dba6c97326340ab3ebb" - }, - { - "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", - "sha3_256_hash_of_public_key": "1f06190bdfd692cf499be99bacc4beccf048c89926769f1b254cca9a9a44089a", - "sha3_256_hash_of_secret_key": "faa641eaff01077bd2fc261ccb91d5c3b468a940e25e8d5d794d564b663315c3", - "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", - "sha3_256_hash_of_ciphertext": "3a22350624e9ffcfeaf0a68c265dc03036e7d5bdbb102474fd2aed257fce04ed", - "shared_secret": "17672805d3953f1f374dc8671137dabb0136de43700fea82a2ca23292bd0d562" - }, - { - "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", - "sha3_256_hash_of_public_key": "cc20155074cd7cbd43ec2380dc6a71b3a88c9a4bf168ab2bf426a899706fa597", - "sha3_256_hash_of_secret_key": "6084f1eb2fe4b9055d6004bfccadad7bd64f623595dd0b5e0c0100d647313279", - "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", - "sha3_256_hash_of_ciphertext": "43291afa9c1a8098770d5ed9dd4cd71688c52d616e9e68798f8718e4555e0caa", - "shared_secret": "8813fdb7bcec5369e6238322be653d920ba26e0aa63a3c3b4e4218c48c1d6dfb" - }, - { - "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", - "sha3_256_hash_of_public_key": "77fbe004761fc37fe7597638e5dae8b44bd44c8d6efa2893a0a84b104ace6ac4", - "sha3_256_hash_of_secret_key": "608099f3fa437094212b3aa2696d592a9ba45f697b9c1020b69ec1d6e178b76c", - "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", - "sha3_256_hash_of_ciphertext": "368fcbdfa009642b3ca8fe0261d10d18db5566bc43938e193d9dae45adf2d41e", - "shared_secret": "b00167b499d5130ef82a91f83d1f1563185de735e74f89afea0b45ae1b90cea8" - }, - { - "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", - "sha3_256_hash_of_public_key": "49cbe8daa7dac02d7795e907b037e2ae56624fdc8d7c6320f9e1e69dd0f6286f", - "sha3_256_hash_of_secret_key": "de7838a99458b56d0f1de343315d1a7d460269ded85551f70335b1e002742b5f", - "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", - "sha3_256_hash_of_ciphertext": "04c5a66da97cec8a22bca38de71927b176310004175b3496c5a2737e91b18e00", - "shared_secret": "c55179382eb5d4bbd91e45f4b3dcc5d1022110aa209c002600fe0d55a5b3333d" - }, - { - "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", - "sha3_256_hash_of_public_key": "a333d474be9bacbea4c301148be2ddf13c3c25d7e4f52447a549a27b6d12710d", - "sha3_256_hash_of_secret_key": "731e7c1597fcea477249114301154b9fda1050e71617827da0c9cc149c1cb99b", - "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", - "sha3_256_hash_of_ciphertext": "841415e768ab08549533578cdb506a9f72e8d01b472b64746322328c0c035080", - "shared_secret": "91c0a23c78351e8f8de8e38c5a10e41e5290ef96266f93839169c05842820e41" - }, - { - "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", - "sha3_256_hash_of_public_key": "35d109f57ea2764642ea3473a4f192cedfbe153a37f131cdf447b60e92310eea", - "sha3_256_hash_of_secret_key": "0420ee0853629da644872d3e2a9b0a89c9dece1a6748247d2f8f39721af21e12", - "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", - "sha3_256_hash_of_ciphertext": "82c120326a2ab109d5c3910a95ec69dc3b1c1c05570728164791870d9c9c1a3f", - "shared_secret": "ffd93f9141d4b2abf600c1c258ee78e0f752513bb002677221060cca3ff1e5a6" - }, - { - "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", - "sha3_256_hash_of_public_key": "cd65fd07a78e48c1a02e235ec76fdb509cf9903a4f5a850c51d9d3fda383cc67", - "sha3_256_hash_of_secret_key": "951cf21e37dcba710b581e49a6df1c75c65186e9672d647e9cd7239eb4bb975d", - "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", - "sha3_256_hash_of_ciphertext": "0217f113b6d5786c3995b366adff6984d0c8d91a388f798a9556d7d3a8252b9c", - "shared_secret": "550b4e8c00bb5ece74059879fd14f5a0a89073d8a54f8bf1597f1ebf198a61fc" - }, - { - "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", - "sha3_256_hash_of_public_key": "376f022313718aba325ef4c3b720e2c3ab314ace74e983948ba2e43ee3a6ebde", - "sha3_256_hash_of_secret_key": "e697899409d15ce13113a2ad86448157a248ff0701b40eec11fb4afac7b9f2fe", - "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", - "sha3_256_hash_of_ciphertext": "26c5a91a627899cf23122c5881bd00b0a4f76e0aaf5de60d1d273e8e635b574e", - "shared_secret": "e5b98a3c32a5563c49df725e661a9f44a20390cf83a9779ecf5e7d9f5aff0143" - }, - { - "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", - "sha3_256_hash_of_public_key": "7944e5d79dabf7b7259df5ced02669c81b7dc4590e0b10764729d812f6bd85d7", - "sha3_256_hash_of_secret_key": "301fb18a9ec0d975414abc4d41ed0c553e2b9aa2b03bf2765476e3288f760ee7", - "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", - "sha3_256_hash_of_ciphertext": "c7474d6b8d9b3677b39b69030f40415e2234e637e200c689f90d6b37da3c4a8d", - "shared_secret": "169929e655f214d7ddca31eae7ecd2e01d9ee0601fd4a2c3a59eb701ed9522ab" - }, - { - "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", - "sha3_256_hash_of_public_key": "692176b38737a053dce0551b63e3eca81884bbf95e1d8975671a2f7f1dfae251", - "sha3_256_hash_of_secret_key": "1ae55a55d87ea8d58b51f842c7d6990a1ae6932eccf5c39e97f56bb481a16b7d", - "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", - "sha3_256_hash_of_ciphertext": "7509dec8c1dd6f29855e08d61a56ade71c6bd9a47102a12b3d4c9784010bc5d0", - "shared_secret": "be36ca6f5e0d3da0b5c144ebccd725900a06782fae7b2707ce7c5cb6818c8991" - }, - { - "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", - "sha3_256_hash_of_public_key": "2f54bedb19919171eca777186dd743b11ec9489aea09534c157faa75adf1c77c", - "sha3_256_hash_of_secret_key": "4bea180ffc80875ac731f18365224bd3eefc8d11fad63c7376adc1a37adc67bc", - "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", - "sha3_256_hash_of_ciphertext": "def0451ac37ac39a0ef5b94406de4e313b3d12d899d6a4e92f3ee37c84869efe", - "shared_secret": "9769b7f3571089f1a086606f3545dcd094097befd492e3c9889f9a97c7b181a4" - }, - { - "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", - "sha3_256_hash_of_public_key": "7a9232085a0222b9c863931ec3bdbdd51be3f16d6cab3009c138e0c8cb692563", - "sha3_256_hash_of_secret_key": "a01d03ab913ef4672c49664d2c95fecdd98fcfc19e8d8b839e79a8f6fb9bdf42", - "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", - "sha3_256_hash_of_ciphertext": "45c35e22eaa9d63a6b57f60ad2e6a35290b290c01761030dea1c9aa7947c965f", - "shared_secret": "7a190640b245b6b4de7ac38fa6d4c50e935c0062c2089c926e4e8c31f233fbba" - }, - { - "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", - "sha3_256_hash_of_public_key": "1642d52117145ea2956bd5e446b895609be84a9344ff0f5cd1ec62af9ea9e3c0", - "sha3_256_hash_of_secret_key": "e2d190c6c423252af301186a3e49892da8c22e4c0fb61586d119119fb7b07447", - "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", - "sha3_256_hash_of_ciphertext": "0e67bf478bf93c925eee2cdfc285161c1b6dd2ba3a479dfb5fd9203ffdcd3c85", - "shared_secret": "5de71ca6710d2d588f53059a15e3a266eab4ed2230502b597f088014fbe9b659" - }, - { - "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", - "sha3_256_hash_of_public_key": "0163017a26dba83777c4c0f46f31375ba02680ffaba588a9fe91f97ccb99c445", - "sha3_256_hash_of_secret_key": "5d101bd4f51fad047a1161e7a95197f6307e7cb88e57fcf9fb28a2be43e9f4a0", - "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", - "sha3_256_hash_of_ciphertext": "7e38f78738ad21d1015a2e79860e8108e807a3e7070515185ae581345e08f6e4", - "shared_secret": "42ffbb3ae86b744b00f36a01f9cb34e8a08916f455c9ea0e5e6ce81bb5042cae" - }, - { - "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", - "sha3_256_hash_of_public_key": "fb21cf5cc9a8a47a07cb2a154f73676d39a98a7d12a4abbd37378595c6332f46", - "sha3_256_hash_of_secret_key": "3c5041ff25ab5e854e792eccf12721be4f820020ed7895d5ccb7b1ba4bb7b193", - "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", - "sha3_256_hash_of_ciphertext": "e2b8a6842755e5a408a47a32c2093dcf3aa0d32448ddb1f1a154315634f1b701", - "shared_secret": "90ca5a797490eb35c3cc24af19fca6dc71d41aa58d68e0061c1bdb8481e691d7" - }, - { - "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", - "sha3_256_hash_of_public_key": "591aa9c81277503a34441fbd6cb59c6d1ecd5e00298fa56be9df562576250c52", - "sha3_256_hash_of_secret_key": "2e9c26235e0db1383671ad4ef147c1cbe3724bf800be90e356a5a381e3d9aa12", - "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", - "sha3_256_hash_of_ciphertext": "02f85b52a3684cab8bc416b74de36ac686cf3a3a495440cd444c1fe7d84b2e07", - "shared_secret": "bd58345e9e19483cde256be650975b954e167bd8b0a9036a95c98ebf037e87ec" - }, - { - "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", - "sha3_256_hash_of_public_key": "1c6c4009e28f6a20aad0c0b14b7cc0a01aeca507c366913ba5cadefe6656881b", - "sha3_256_hash_of_secret_key": "a9d3487d20af12309fb8d12b71a3fc3ad9109a9cc2720a0fa409ec5a491943b4", - "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", - "sha3_256_hash_of_ciphertext": "7a5d4cb38e9fb2beefd925d54155ae91d60bd95696db2de45e2307658341f2e7", - "shared_secret": "53d22dbfb623f5282ac68ff607b69b9ce559ec3b70aae668c684d90dcbbca13d" - }, - { - "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", - "sha3_256_hash_of_public_key": "4576536d1bace29aa7c31f7681222ddd15a3cf6ea6bbd3528d2ec8610d68d134", - "sha3_256_hash_of_secret_key": "0f1d74d5cd2fd6a9aa7022a0f06bdb6272a0bc23f115796d6e04692aa44de4ab", - "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", - "sha3_256_hash_of_ciphertext": "8448f623dc438ea4a849544c4fbcf3dc493b18dbacb911b83ed651155a145c53", - "shared_secret": "cdca5387453ba0f0fe9f126702ada05c3612388b70185b6c2e69dbf98c2803ec" - }, - { - "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", - "sha3_256_hash_of_public_key": "eea5db7a82254d19c0a0c552ccc92db9c3eef74cd73a9937b7b7298171313f12", - "sha3_256_hash_of_secret_key": "d4d3196a516686b8da051e915241f141b04af55e83effb968c52f23a19ccf79d", - "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", - "sha3_256_hash_of_ciphertext": "84e87b27235041a1815c98ca4cf9ce031d7700a48f602bc9dcc98f876ae50c62", - "shared_secret": "b15db77dc79f2d64e13445c4dfa997afb191e0bb2bbf6a210a5d64263b2408f5" - }, - { - "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", - "sha3_256_hash_of_public_key": "72998cc3abc79487ca0a4db5b17514e9961916d30ab9b500430ba748c5c79226", - "sha3_256_hash_of_secret_key": "362b40ba4e015b703f639f4c784fa9f114f2cf65de5f6645e8f9d37fb33fd044", - "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", - "sha3_256_hash_of_ciphertext": "44b60f83deff617231e92c5ece08a24243841d3df34de2517c29bdc89ff51400", - "shared_secret": "8ca9424860c35214636855849bb039cdcb4c722c5b81ce18ac1a1090034dafc1" - }, - { - "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", - "sha3_256_hash_of_public_key": "e9631b6d4237dd6884ae3647dd8622fc13d1cc689f3c8ed94ec6bcd4bbdb6980", - "sha3_256_hash_of_secret_key": "96736bf10a73d079e56f5812f65e3465957b8228423fdae4059feaf918fba361", - "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", - "sha3_256_hash_of_ciphertext": "eda93794649d2ba24fb277e8cb0e5788102a4796cb21388caa25eb10bafefc5f", - "shared_secret": "b056e2904d66c51dc817acf961f141c2de7d201ca8e52d19564d0fb4e1310aa9" - }, - { - "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", - "sha3_256_hash_of_public_key": "847db13de94d97a88d5a3deae31c246f5f04d0c7d7f337859e024764337a08f2", - "sha3_256_hash_of_secret_key": "7fc950abb115ea2236036c300c95c76015606539ddd2409ff1b39a99b86a179f", - "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", - "sha3_256_hash_of_ciphertext": "af6d97857d131ebccf9d356e78a4fbbb66c7d5ad68fd42d356c3ef14aa756d47", - "shared_secret": "663bcd21601942f0ce47640325c9efcfc3eb3b022f0cfaed168893b1b6e5dcfc" - }, - { - "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", - "sha3_256_hash_of_public_key": "f122b76b83c343de27054985634387fb7138f6f6f105cd4cd3f5b02698a964b0", - "sha3_256_hash_of_secret_key": "620b4d0dc53a26e175c69ae7a8f2d749d4adf1d0429852b84839d334e024ab06", - "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", - "sha3_256_hash_of_ciphertext": "51f8a50f2dbcb1255619a7a9868eece507b55d2138707a0550a4113a7e162d5c", - "shared_secret": "cad5816f1b2057a410cf917f52040aad9cdef2122ce59211ccef77c4a7c23a6b" - }, - { - "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", - "sha3_256_hash_of_public_key": "4c3182ca7a48afe60eb85790dcb50b8005b568921dbc724130b0ce83f1278454", - "sha3_256_hash_of_secret_key": "44b1c2b3487cdda8a8e9205d95dca710093e981e7bf2ea30d1d2502b164375fd", - "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", - "sha3_256_hash_of_ciphertext": "f231d9b8e3cb86e9daddae8d4555779a9125a16a6d2984ef55914a27d7912fbb", - "shared_secret": "e8f4dd3d2bb2c2f110bd410b2c37beee6d3bc7c7c4dc477c358234c54bbbd4ca" - }, - { - "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", - "sha3_256_hash_of_public_key": "4359601c371b50b50b5306de33cfd476d3b5f811700dc4918beb345840244e3a", - "sha3_256_hash_of_secret_key": "6f2d2c913b4a19bb07b531d74edb549659a35d1330b1ddd62c74dac4bc5f061c", - "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", - "sha3_256_hash_of_ciphertext": "a6130d387a04846c8b920f94f59d6c65b4954b6ced0f0d6a8566a0110c198a08", - "shared_secret": "249855eb724db68f7367385c45a3206fa19c521644f8841b7a73f536ca47c26c" - }, - { - "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", - "sha3_256_hash_of_public_key": "e1f6c5a99a49d6b1b4aa18089439bb4c56ca465785bb36594ef2ebd3af20d564", - "sha3_256_hash_of_secret_key": "fcc14cdacdcebc6d1933f1ec9d430c643ff5fdbd78d2fe053a8880e6ee8ef129", - "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", - "sha3_256_hash_of_ciphertext": "73a09eadd34a8be74772db44187ab49a2bc086b91848c6ff09f1306c264f6fe4", - "shared_secret": "f1be516b31ed89cb70bcf428a2ba2c22b3919f8a9824a59b875ff1e697095ae2" - }, - { - "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", - "sha3_256_hash_of_public_key": "b8aa8568431ffc4681caacecd4475c838cf7348402a06413e7a9590ba405ea5e", - "sha3_256_hash_of_secret_key": "f1e4bb0178d949637c06e252493235480d3ed16687e9a1c36df0721b29a7573c", - "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", - "sha3_256_hash_of_ciphertext": "24392701d3f5204f5cad5662bd6526a178567186cc070d951e03593e5722eb46", - "shared_secret": "6ec4f71386c0f0c16294e4d76966c69c512d4e5e00a6e05c5aa544e542454225" - }, - { - "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", - "sha3_256_hash_of_public_key": "984f4c4ef2371654067ce0f22bbe4648dc9d87eee23842f31affcdc36328e8db", - "sha3_256_hash_of_secret_key": "240fe3ab98047b1985b22240622da9669f7ecec81801861ea0859704f3263f6c", - "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", - "sha3_256_hash_of_ciphertext": "f190fb70fe762db7125e3ba3b459e32bf99775c3c1efb84ae1776b50206db7df", - "shared_secret": "464274dd39f2862a97833631ac446642b3c3dd6467c7d2404aaa46a8f5f65b3f" - }, - { - "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", - "sha3_256_hash_of_public_key": "74841a59db1202eb2e3744bb36b9c5a229a33cf9eeafca4b3d02d155d870b6bf", - "sha3_256_hash_of_secret_key": "e808e7b999c5bedc14a1763428a3f2b3eb9c3f90743f8a1922c87b5874acd79a", - "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", - "sha3_256_hash_of_ciphertext": "675ff34f87383d52203c979d1502e2fd35d9da09cc095b44caa073cf58562ba1", - "shared_secret": "99dd968e1f5c94c6c4d92e7eee393c802d8ea4a34d39de2048eebfb21a0a4b9c" - }, - { - "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", - "sha3_256_hash_of_public_key": "f7243d71bcbb46b9a423431b3b30947eda5fd81b526cce79a36730d8ee1be42c", - "sha3_256_hash_of_secret_key": "b1e6993caef04e00ffcf42c81ae97c6d89c5c19bc3b3e1235c48829151f8b4cd", - "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", - "sha3_256_hash_of_ciphertext": "319744b03f01b7676b3975b70d20698972d5492a2b0c8e0833837de36945c699", - "shared_secret": "0642533fe87a2913a37847843f7336a0e4c47f778afe5cc95433948a76ee7ecb" - }, - { - "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", - "sha3_256_hash_of_public_key": "4092d5afa2f038f879184f7344800ea49a63543be9600bdc2b18420744588290", - "sha3_256_hash_of_secret_key": "18b8bfec268d6e1d6edd376689f2bc5ffbcdc859cee0a26ccf550fb42863d57d", - "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", - "sha3_256_hash_of_ciphertext": "4fb1c5f9a918a9077f822c79ec0697dd6dd7b23ff3cfffafaa272dfb1233bf8a", - "shared_secret": "a226b83601ae0e6f76f9f08b0a2f6eb30a3afaa39ecf5c5671e988a354fde9a7" - }, - { - "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", - "sha3_256_hash_of_public_key": "ad7166f31b2650d125c8ef23b5825fe11afe25d0cda306fa6c7a824b4c2d31d4", - "sha3_256_hash_of_secret_key": "0124d8202fcb0c40d7a6cbc1570df65602f376854abd55ea664f66e3923b3d56", - "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", - "sha3_256_hash_of_ciphertext": "74501710705cbe8837e88dc8986d78310ea57196185e3ee3ecc8d17d8cafa7ac", - "shared_secret": "3040e7e4eeb844c1385a78dc3c8a6375880ce8fab92827460de1825a4915c3b6" - }, - { - "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", - "sha3_256_hash_of_public_key": "37933cfd8c0e61085f2ae264d85c4ae05f8bd40bf29976c6d52e4f1c7ff709cc", - "sha3_256_hash_of_secret_key": "e9a6c0af326ca00c7f8ee0b6ef5661be3a84c39165ff60fea5510cb219b8f788", - "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", - "sha3_256_hash_of_ciphertext": "3fc676cfc433cccd2d248824c4f51406491cfd99bd05f863cb4200155ac471c0", - "shared_secret": "d990008c5eceab7097524d6755c663ba04599eda80560d59088b21cd73243462" - }, - { - "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", - "sha3_256_hash_of_public_key": "ae96ec4edc7ee08108fe6c0411a96f48731066ae4be12edeb7fc667039c9c1de", - "sha3_256_hash_of_secret_key": "7110c8c6d14a3cf5dba3e5f2ecda1ed1490e62b032f798139b779054da20985b", - "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", - "sha3_256_hash_of_ciphertext": "9b33f0f26252a0e1b92f55f4c0f979efd5ef68ef1ed6f23bf23e5eab1c732ba2", - "shared_secret": "bd50423b4ef27559d67532abbfad2a3a388e3dbf4d7b6488c2b48f19cee07ad4" - }, - { - "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", - "sha3_256_hash_of_public_key": "4e23909b028699d6677eabe6bac4bc4e8437acbc52b0b17f1df5760c0455c2b5", - "sha3_256_hash_of_secret_key": "63ace19297953d106cbc1df1a25143a15772197c05aefb070825ef568eafcf23", - "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", - "sha3_256_hash_of_ciphertext": "7747110bc34f1a35fea13d10fffb950a85bd6d9247c89b2071afce7544b312bf", - "shared_secret": "38e3d97b0547e648b2b722c4844f59ed43dcc4b40fa7dcfe6184c2fe62ab3530" - }, - { - "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", - "sha3_256_hash_of_public_key": "513906f5bef81445bd210d63fc4c9b9ef0b61c17b0cd5b229a45908fcbaddcec", - "sha3_256_hash_of_secret_key": "11added546dd697edc51e8ed16ca3ccc9da9629c4ce0c8404d04de1aa8b8114c", - "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", - "sha3_256_hash_of_ciphertext": "569f8e9da2051bde67bd3ff8e81e3b4e749b198586e2ec8d0544e6a8793aa782", - "shared_secret": "cca4f1d172212f8c23eb5da77144640d821d2671f66f0b3015d0b46e274e193c" - }, - { - "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", - "sha3_256_hash_of_public_key": "4f8b3e9ae47d3b5b95c080d4f18440c24b0691c19f06f5547554697bdfe97b01", - "sha3_256_hash_of_secret_key": "cf4be19205cf0c2bd0eb0c1e7aabd40e265792bfc302bb0f28716c406585ca37", - "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", - "sha3_256_hash_of_ciphertext": "ce6e0b8523fc48a54f1b10be23b1e990a390e4e823d4483681ffbd2ad09f4977", - "shared_secret": "dd7816a8a015b2001258e665dc0e576ae19b10dba9704be9c484e4c8ba645522" - }, - { - "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", - "sha3_256_hash_of_public_key": "c1b4fdc4929c2c7e4501ba7a9feb0be571e27c43fa96f9a7f934636ed9a86110", - "sha3_256_hash_of_secret_key": "5b475ff0aeb273c017d1e7d7cd380e41d50e634840e443a762608c09282f3007", - "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", - "sha3_256_hash_of_ciphertext": "556aebca384b3876ec2c00d446239855602625800bd1ecf1b7eb3411d101d442", - "shared_secret": "e911f73a4c23637a2708739bd5ef842ccc57d32993f30d6ee1f88acf5093ebcc" - }, - { - "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", - "sha3_256_hash_of_public_key": "df4f164c11041dbe981d8ff2008757b7e694f564a298b92cd182129ade5e72bc", - "sha3_256_hash_of_secret_key": "1f836ed803ea8abe63224c016dc15468719599e06564c11e9f641eeb3634350c", - "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", - "sha3_256_hash_of_ciphertext": "5dec68120c8c2182ac2b2995eac56b91df2ee9c9bce8e801853e2cee14c0d8a2", - "shared_secret": "572994fb967815fe8bf36cf41560dc69aeba8e32b13e1d25128585dbb0e71068" - }, - { - "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", - "sha3_256_hash_of_public_key": "ed722667caf175df48a3a346ec7cb1bcc37d67d3137ff7b7c70a07f202893a33", - "sha3_256_hash_of_secret_key": "272df80631771996565e673a4dd92318e87e625097f74fae14c688a24b558216", - "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", - "sha3_256_hash_of_ciphertext": "4214ca50c6c732d34dab0b460d7cd9e0ae97346fa50a67386fc35ca0ac8223fe", - "shared_secret": "92c63dee4666bfb34fe3095f65cd458654df578f6eac0ec75f5235e5da6a926a" - }, - { - "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", - "sha3_256_hash_of_public_key": "0c4dc82d723965476a518ea0915c1554bcc61c814c80ff120c37e7e8ed6d5c40", - "sha3_256_hash_of_secret_key": "d9e7fabffb14d620ccf618a1e25375d4cf58875c38ecc73587cd09b17621ade4", - "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", - "sha3_256_hash_of_ciphertext": "651834fb53362a4c4af0b141885056f9db913c4be968c1aed3d7d3f5bd1048ec", - "shared_secret": "0e2179fc3d310aca496244699b05da9b7bbb7891ed41b675e5dd48355a586360" - }, - { - "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", - "sha3_256_hash_of_public_key": "c934c11e2eaa7c3c4e764863e436ff12fc9f517c79df6344ab98611f57fe7296", - "sha3_256_hash_of_secret_key": "4f502a9abdfece85347362ac4c7e2beedb137e29a4b638c9bfd710de432b5e5a", - "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", - "sha3_256_hash_of_ciphertext": "06786544f2ea24bcbb677092f4602d59f9cc9d2d8211614dbb5b87edc6edc46f", - "shared_secret": "573a8fd5e5935badcf974c50cc36e191f0ae2c1458fb00d4117e675424d4e37d" - }, - { - "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", - "sha3_256_hash_of_public_key": "5b07c8359e6ec4989c34b31293f4df965b5d95802afa5836beabb001d5cd4dae", - "sha3_256_hash_of_secret_key": "73973aaa43538874f8b16d44faefbd26dee5389a05fad2d4f966662ea9eb1df3", - "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", - "sha3_256_hash_of_ciphertext": "2d6085e31726d74e2ce2a28088ef3247b68b39d0d51c225df2521ba327bb3154", - "shared_secret": "c8d5e0dd64b4f3c6450fd24ed2918887d3ea2806479d3fcd5a19894f4fe401ea" - }, - { - "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", - "sha3_256_hash_of_public_key": "37f1d7e636b4ab366dd5725957b9e5d2498e4ee1929f2213f9d05c882d96a106", - "sha3_256_hash_of_secret_key": "1b150644ef3edff5c406fc9a85e16fbc87cfcf8a6ac726284483947cc2fffd63", - "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", - "sha3_256_hash_of_ciphertext": "37d80e33f5bde211a9a3f634f8505a816e46195616c34a51d62b031822201337", - "shared_secret": "f0691ad2fe875e3f0993f25452c70f0c40891b998deb6a7f7aa3c0bacc59bfce" - }, - { - "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", - "sha3_256_hash_of_public_key": "a5383897314d60ae0ab1a8b50d6f5de454a2eb8b0502d57001e6e19223a82ef2", - "sha3_256_hash_of_secret_key": "38e8404120bbd346e0483ff7eeb758bd655ed94f6c02e427468f0c5fdbd957f5", - "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", - "sha3_256_hash_of_ciphertext": "3e819dc1fbc939e49bf5935fc8ac8c36d8c16da057091442df74a76fc3125fa0", - "shared_secret": "bec215c6bb33e83574319c839db1ca6793931d35a7239bf4ad3c4a493fe5c5ea" - }, - { - "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", - "sha3_256_hash_of_public_key": "500dd7b94b28b5b650d90962962bb9a3ae96e70d35723217f3f178cbe5659051", - "sha3_256_hash_of_secret_key": "5930b10cb88d66ad1ec117d2b134f921fe4ec980ed9c351951d47d33510585bf", - "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", - "sha3_256_hash_of_ciphertext": "cb20903e6ba3a41f594cd09056c0a7af4dea86039677761e88dd6818db0d0e88", - "shared_secret": "18a505a0543800a93ab6e2fc1d866e22337fc8387d32541008ff82a73ce7dd31" - }, - { - "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", - "sha3_256_hash_of_public_key": "3c4467b507971523509bf97d2bdd733ad9eb94f312e4226d036e8fe827a20533", - "sha3_256_hash_of_secret_key": "76e696d5d7ebb4e2035507601f66f38d74db35d3c76b3622678a2c65ec7b0f69", - "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", - "sha3_256_hash_of_ciphertext": "df6a835ca5253cb64d669990a60fe03b44a4a2229beade86a2f3f2381d33f09b", - "shared_secret": "f155d993eadba79e6c2376daeb7f935d39286b10615ab42c5803d43f15960a66" - }, - { - "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", - "sha3_256_hash_of_public_key": "69ffbf2275f12c29cbb69f90a8c881721ce39b49dbba550ab93a2c4c94bfc669", - "sha3_256_hash_of_secret_key": "76d6db646c55687ff9eeb3f359093a7105a7ef711bd60a4ef7f1a1bbd70ea24a", - "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", - "sha3_256_hash_of_ciphertext": "677fe79386a26743faa6fa1c79576e3f898da432af70e1f45a73b582b4c976b9", - "shared_secret": "4cc8728603d51b14fca46ebaf01e6b6347ee9c71d192591ee857c206d131886d" - }, - { - "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", - "sha3_256_hash_of_public_key": "41bbd3f5c241a6d65b510dee6662e2a8f35757b0403dcd375e7a15991a7873c2", - "sha3_256_hash_of_secret_key": "256673d5b2a0225515bee64da0105c167d031405098819b6992d01c3cc711bdd", - "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", - "sha3_256_hash_of_ciphertext": "9306db283ad2a844ad6d266ff6c7bd8e9b4ffddef78d656c9bd06d52cdc52c74", - "shared_secret": "fe5dab115160a7200005216d7e6e7dd8527f9c2eec34f60c6710ee21f7f91730" - }, - { - "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", - "sha3_256_hash_of_public_key": "290261ff6a1d2fabc75feab002d16cdc44bdbdd0967c728ebef0e9814c60b5e5", - "sha3_256_hash_of_secret_key": "beb5d2dc34b1dba8c87e4ca2659ed8ebec2d93be0e2d78285efeb9fd998f5805", - "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", - "sha3_256_hash_of_ciphertext": "7f94b2d97c0821593745e9b5301a66a81b75e71b15c8c21558c8b8b077d7af5b", - "shared_secret": "ba33ea19873105ed9690d40426b2cd24073c822eb86120a4fe8617b5201f9494" - }, - { - "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", - "sha3_256_hash_of_public_key": "7ffefda144195d79e581c91cdf0247f4346e811f890f54f25226b4ab835871a4", - "sha3_256_hash_of_secret_key": "7b85555898660cb43a060e367d9a97112b48e3b8f99d437161cf6ba44b5c6922", - "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", - "sha3_256_hash_of_ciphertext": "310c7f22a80995c6e375122f1395604faf5f72fb9fd6819597aba8f370327647", - "shared_secret": "2baf80269b225c66a8c35c6f835f15bd6949ae2814cd8c405a0aed313a637701" - }, - { - "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", - "sha3_256_hash_of_public_key": "13dd780ec5347c512cfabf4c2e6a44cb2b17993c7c746f93c1400a5db9f12511", - "sha3_256_hash_of_secret_key": "7732b2a074d1c0aa93106ca84711edcb7b8a369f3873cf89fbcebf0d32176f1c", - "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", - "sha3_256_hash_of_ciphertext": "b0003e684b9ce6f284d9a746cb806442e5443430bed95f2e8ad7ee824fb3db2e", - "shared_secret": "07318e8edf0ca8f30f49fa906ec814e40ec52922f2c0ace243386ef2bf650000" - }, - { - "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", - "sha3_256_hash_of_public_key": "d5acaf411ccb64500879102d9cdf6d9fcad673d874a4153383806fe174b2fc1e", - "sha3_256_hash_of_secret_key": "e5c3fdb9d8e92c42ad48684f0fe13aece244d116f8a6d09a764aaa090b3375f2", - "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", - "sha3_256_hash_of_ciphertext": "9ada65c57d8292e9a999ac102ef855d5da932a54f80f3d976fe1ca834eee5964", - "shared_secret": "38b5d71f3a64feb2cd41d6b7a4ac5440707770dc4c472c3ed141165fb7e8818f" - }, - { - "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", - "sha3_256_hash_of_public_key": "152641a683dd690d4ac3edf0261200cd9244ae7dab962eca2f3d22a554d0802e", - "sha3_256_hash_of_secret_key": "7afdb84b3806783db52ef1f5f0ff89ccdb051704cfd19eec3e2f0830c3b27550", - "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", - "sha3_256_hash_of_ciphertext": "499ffb9a28fcc692e7d61df4696b538f1bbb205ff82d604512220a9e19d87254", - "shared_secret": "368a5e417f4fc728f5080e8fe206ca7558909f6537f1012a58b2d9d45b7c6a8e" - }, - { - "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", - "sha3_256_hash_of_public_key": "9cc95efe512c84010ccd7118a92522cead44cff28d6e223f76702a47694c8f05", - "sha3_256_hash_of_secret_key": "d9a18ebc4b027c9590d0e4eeed88705aaf5d166cc016cf6e0baa07f678f1f0d1", - "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", - "sha3_256_hash_of_ciphertext": "d202a577a7acba1801e03c446279da6dce6f262a6b1bf06d3c15283bf69fca47", - "shared_secret": "7d36e561b501a687939aa880285d32cd6d8b66e2e65b2a076d5aa516cb5b2e6c" - }, - { - "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", - "sha3_256_hash_of_public_key": "8b12f00bf09aec2b492cf53686beb31c558d0493cc7b2b9a9dc7265fa9edb685", - "sha3_256_hash_of_secret_key": "9979de3ecfacdc04e1229773f36d7b4bdfd731ea0f1fc2f9d56ee1d07e9bb075", - "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", - "sha3_256_hash_of_ciphertext": "53f97fd2a138ceae2b327344c4947cbee6d6563a48d9bc5d8373c4bac5233a5c", - "shared_secret": "6be99cc08c8bf10372f7d5c27bc3ecd17ade8afb967aad41a1b33c0ff848a1be" - }, - { - "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", - "sha3_256_hash_of_public_key": "3c98fa4af17fd014a60d11ca5e929e4fa2524f7db289ce0947ad90657990c153", - "sha3_256_hash_of_secret_key": "2c370afe3301b0481b50ae72e21cbb1be37d2877cd802a1d40e05d9b4e6be502", - "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", - "sha3_256_hash_of_ciphertext": "c134910358575ee3e211603b58b3d6085cebcb91f32a355ff437fe87ee812e3e", - "shared_secret": "f6fec6f62257d9a7041f119fff60f734c928e945fe131bf70338f273c0614ae9" - }, - { - "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", - "sha3_256_hash_of_public_key": "091210fb4f6fac00a24167d9bd2761e601db0a3734e3c835d1e9c5865b1e379c", - "sha3_256_hash_of_secret_key": "fb4bf08e0cd8d2f31969f75b420578f8d6dcd845824e427a6261931f1e1b820f", - "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", - "sha3_256_hash_of_ciphertext": "6076283588ebdb4630d85b2dc6dce53492e11dc8c9445597ec57042bf1e59634", - "shared_secret": "9c56f6d91af6741ac13f241f8c960433c0ed4adcc86130877ecc1dbc10573bc5" - }, - { - "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", - "sha3_256_hash_of_public_key": "6c206507b89f46c6e9cd5e78b6cc78fb3677ee609cc090cf3782c876fd5f941b", - "sha3_256_hash_of_secret_key": "c9123a2bac61c5fc4304da90862d8cb544a31da2cc8b8126ca16a71278f461e7", - "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", - "sha3_256_hash_of_ciphertext": "e57f70dde96de9e66ce28b7d1a3014cb095a8ad00d80ae7735fd499d57e2e6f8", - "shared_secret": "021b7e80dfd1258695b61aac785b0134ed6e9864d3cdf5ebd4b3ffdd9a5bbf06" - }, - { - "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", - "sha3_256_hash_of_public_key": "0560200b8d070d1db2cbeedf3cb322ebbab3edb80cf474b4178633c210b2fc74", - "sha3_256_hash_of_secret_key": "a2424d9992c7e999a5b18e638a22d65e1e5d5029e5fac62a5091095897b3543c", - "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", - "sha3_256_hash_of_ciphertext": "b5928a28fea0e5b0321439f9df86c6f10fa6203bcdac0cc94da7f7d6764d543d", - "shared_secret": "2c876ef4c2bd6464c5e4274d5360e210ff389325c1da4bda5495294d7cd126be" - }, - { - "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", - "sha3_256_hash_of_public_key": "3a2484828bce833f9262405b562bcade9ff04877838558409d2b60f1b689d137", - "sha3_256_hash_of_secret_key": "610db3251ec079ce8003a49d64ec03dd49d89e82ae9f12d26d50938f4a3992d9", - "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", - "sha3_256_hash_of_ciphertext": "723bebfc2e4e934fc9e35383c7f150d31d832e1516c66f8bb2effb449fefda23", - "shared_secret": "909b047e7f0fac27df2787ae406fdd66893a98d98e38a9f5b67bb5c8431a77c4" - }, - { - "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", - "sha3_256_hash_of_public_key": "bb8615509158b63be5f5e51a0e690f2ad6fd0c56fa886bd85902abd52598bc81", - "sha3_256_hash_of_secret_key": "3a4a1360d366376a56362fee0aa22756122e3c40226c770797c0baa82192bfa5", - "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", - "sha3_256_hash_of_ciphertext": "47cead6dc9f155f4e61afb233c6a8519f016c6f2bf7b1668ed9333daac257507", - "shared_secret": "dff8310ce364ba5686b9d42a17922b8d5e9259a176e38d39687a5269455939f7" - }, - { - "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", - "sha3_256_hash_of_public_key": "5cf14252096e4988d8ecc4ac6d29ff09c55d666865863d03a68db523728910a8", - "sha3_256_hash_of_secret_key": "404e6febba9802464a188007c2137fc25a4c437611babc8fa8248a0e42e45357", - "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", - "sha3_256_hash_of_ciphertext": "84765944d4602d3fca6333b699d98e4c8c9b3bc1570d428398a29cc5a7fb96c7", - "shared_secret": "faa9833781a7a41691f236feefa0c743bc141f458ecbba98eac4a51ee1ca001c" - }, - { - "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", - "sha3_256_hash_of_public_key": "345118a7b9bcc773f0ec10c3e353eb4365d2bbff3b812df4635d5c8265b5d8c5", - "sha3_256_hash_of_secret_key": "2eff0ff04aa2f95d9d2a877d2c3b4a09255fed2413da76e63506d0def33f42ff", - "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", - "sha3_256_hash_of_ciphertext": "602b3893213ac6168e24c7c20d22a9c9126a9f70b918df134860f394795836a6", - "shared_secret": "0f47139a8b007c4ba77c91ee885435dfcd38d38c0aa4f57fc147f08b4751aa44" - }, - { - "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", - "sha3_256_hash_of_public_key": "772f50f7047714627bf76bc098e0b919145fcd8df6922ebac383e5c556738390", - "sha3_256_hash_of_secret_key": "c48cd8eced0093133d3d083baae0f69ebc3e239c373a41db9557c1a46a40d480", - "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", - "sha3_256_hash_of_ciphertext": "84f212f6cac0f0e7a6a27630c0c33f98063bd57243b26fa086d6a37161d75f81", - "shared_secret": "182d34d0e83216d26a9d13301fe75a3aeb15ab145433965996255120cc9a5f86" - }, - { - "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", - "sha3_256_hash_of_public_key": "a9f015f625356a6bacbb5e565c70184940891589309a571b7166c2ee713b8fbb", - "sha3_256_hash_of_secret_key": "924859759e33e4100a02afca0ad0f0e631eeef3b4a70444267e921b0b6eb334d", - "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", - "sha3_256_hash_of_ciphertext": "935ed1ee90431bb81d67fa4c620c973f7354aa5dab63b51686501882e65a3961", - "shared_secret": "62a14f68d726235fc16e0ac57ad4ae0eb3fc029abb18567a4ee574b44924693b" - }, - { - "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", - "sha3_256_hash_of_public_key": "655d6f749b0a013bec99e017f5e13bff76680a2f9386f2ac6938d7950d5fa1f9", - "sha3_256_hash_of_secret_key": "0511490e76eaba3b276ebadd300c394490589dec54468855977e96a33025e06f", - "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", - "sha3_256_hash_of_ciphertext": "c28eea97d0767b408e58bbadfdff091ba468c26b585f22bde6f3eeb1fc7bb631", - "shared_secret": "4ceda11055991ce1e5d910a240981e39a6a903b20ea6ae6a21d9d56d0935efa8" - }, - { - "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", - "sha3_256_hash_of_public_key": "1c3c2aed0ff6944819c93f9a9fe77d14a16a385f644de118099fd4f7f57db9a0", - "sha3_256_hash_of_secret_key": "0fb711641d1830a3eb4ae1a4bc2fc610ea9a811fdc5274488dd31f9cf52ec04e", - "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", - "sha3_256_hash_of_ciphertext": "9fae0ef351454fb5c87cff7ed880d32dcc2f0654ab8c5a5b66b1e85d8e6feb06", - "shared_secret": "8d8257f05a4e76ad11783f7f6850c4f1c34017bf5ab47f89eae202132ada42ff" - }, - { - "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", - "sha3_256_hash_of_public_key": "357d61586f671648188f070899d2eb3408158adf5e8056ef37ab6d8817cd8275", - "sha3_256_hash_of_secret_key": "b22e39d960d7079015d70fba54ae860285f3c182bd5fc8d84c255f5e0f86f800", - "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", - "sha3_256_hash_of_ciphertext": "388d730604d16fff83eaa4e21a540b2ed8b3138f81b4c1c4cd7bb863325344eb", - "shared_secret": "08a60196adf66426b4e7b90be90160e196944d012cc34a524e1e73ca125ba407" - }, - { - "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", - "sha3_256_hash_of_public_key": "ef07b1f4886b895a3246241ddc084379eeb0f0ed84bdcd318fe72c9b546413be", - "sha3_256_hash_of_secret_key": "132633e3d33bcbc61ff70504e34bb033c92db5086bd924eab4ecbb8e4be983d5", - "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", - "sha3_256_hash_of_ciphertext": "ea130b782f8d0167bd57d1cbead18c1a5a65ac27681847b85d8e09030dee8738", - "shared_secret": "13f3b79bb1e5d20ed95c7165a610e122b5de6cb02444cc66e0f1f9ec44c27485" - }, - { - "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", - "sha3_256_hash_of_public_key": "1a2d9ea0d2280249d9d756975c6979a8770bf4b5f6addbd76d045a816bc1be38", - "sha3_256_hash_of_secret_key": "23678549b4e6e050b57ed1ad078705d33fe76ac976a9f70312b9cb45be554b0c", - "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", - "sha3_256_hash_of_ciphertext": "254058fc10c3327f551dfa143d17dcf4dc4319419050cb5e6841a8d5cb6ce9cb", - "shared_secret": "fcf4227a487e719499f86e44ff74a5339870e4238c20731e0c85f00229f2a1b4" - }, - { - "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", - "sha3_256_hash_of_public_key": "a57b333a2f41fda2ea72ea11d8bd642d911f6afe90e60492ebeefdc17a932192", - "sha3_256_hash_of_secret_key": "b59171816497ec0c34b963be3ef6366eb051cdebdb145fe445e16b72aa37356f", - "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", - "sha3_256_hash_of_ciphertext": "4bb877beb1b9dbe916e61f9d6d7442deb7483128b6db494a0724e081be74ded6", - "shared_secret": "3f8cf35d0ba76d75dec611e5fb059db5197862b7e5cc6b116a730734932441f3" - }, - { - "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", - "sha3_256_hash_of_public_key": "d3cd2febe168b1ddf776b954e96085a7d475e3c8cbde68f7c80ffc9fa46b0d43", - "sha3_256_hash_of_secret_key": "b41a159ad0a89e7a771ef11e68efc9d79e6add05b261d0e40620a6b667a6c6bd", - "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", - "sha3_256_hash_of_ciphertext": "62de1efed6f92fc50d8fdef1ff217cb04faf53196e5af3a7507cb6ea5f822e2d", - "shared_secret": "d48544c1ac452c0b821e080e02c9c83e95252fb033617ce270f58e2974679fc6" - }, - { - "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", - "sha3_256_hash_of_public_key": "9499c1b006a0ec2c299c41c3f728c3bb7848957fb2bbbcd05b65233b89a2b1b1", - "sha3_256_hash_of_secret_key": "bdf5c3beb39ae62a6e29e858962c322fe525a307a163d68f765779b7848bec3f", - "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", - "sha3_256_hash_of_ciphertext": "3a0a1742b1e27f14001e3457a00748f232f550687a232fa409c2098f97e72bb5", - "shared_secret": "6b8f4cbb3c4fda3c067d7ba48bf24e24258ca7e26bfaf918b784d01ae74ec57c" - }, - { - "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", - "sha3_256_hash_of_public_key": "aa14ea531df0a7f93225de1c75ace0d2692bc750b1b538cfd0d860ae9c5a8c13", - "sha3_256_hash_of_secret_key": "155cff081ef58459a00ae63a6ee0ed2698bdbd99c67b4c9dd09f8b0fc3de0120", - "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", - "sha3_256_hash_of_ciphertext": "8753aea7979a0d3f7aa35b9fab1b320d1b0965899bd51bfc8c1f6de79ff7d92f", - "shared_secret": "aa9878a81dd8165350b880c4af6a2adb9e50a48b9e0709f069c02184d3785181" - }, - { - "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", - "sha3_256_hash_of_public_key": "e0013ff7eb7b8266ee94659f3372f5981ce1d87584cb1f0e80da2c0c95c16b4e", - "sha3_256_hash_of_secret_key": "7eece78f3f97759d0cfc8a69481271a425c56e540704b2fdaab8b2d920d19e21", - "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", - "sha3_256_hash_of_ciphertext": "777253af58f65c8a85f3feca46f8d32eb5d3d5d0664ea59cfdf47b89be9f005d", - "shared_secret": "5a23296c84df3d660e7c2a973c4e6bddad3fd814e158028ff92b234cffb1afa4" - }, - { - "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", - "sha3_256_hash_of_public_key": "b503f8ec36d39fc7b4b8ada1cbb933b9db9ee118bf081ed75dd5dba7590f6c8c", - "sha3_256_hash_of_secret_key": "65d28565658fe991b77136b89255ec2d1cf65368e06f2b30bcedab87ffe39550", - "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", - "sha3_256_hash_of_ciphertext": "a7302707d52fc49f3e3637a742826bc8c8267e89c1fdf95b2ab7a0d8f1003c8f", - "shared_secret": "d790ec546719fb05125841bda9dd361e162ca4241e2b489a0f948b612309b649" - }, - { - "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", - "sha3_256_hash_of_public_key": "03341657b159925cedc8967872a45a3c1f0122979af87a878a2019b3f17c8ba6", - "sha3_256_hash_of_secret_key": "6bb236b9c7a818f9edec1e5da339755dcb7ca1b663a5a208c38c75e7ad7dc12d", - "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", - "sha3_256_hash_of_ciphertext": "9a9301ca946909c3ee5d2171bc36322179ab4bfa825ffc0b826517accbc78298", - "shared_secret": "10086d1a59c41f84a089c239fcd8f8eea3b22c7796f9c1f9b1867b709cb77704" - }, - { - "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", - "sha3_256_hash_of_public_key": "60c001172c4734a620c248654c58f1c10135657083de776116a6acf8a55f3610", - "sha3_256_hash_of_secret_key": "b10663e90392d6387c16dcad565bbe1fbc05f32495cf9878706bd0d61d289147", - "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", - "sha3_256_hash_of_ciphertext": "e4b3ce9e19c204a884f8a5adbe41acca97a22f1f5f2a13f1185021a8a36a131f", - "shared_secret": "82ad68065774eabcd6e78c027286ca7c7120987c4984e56f52abeb1ccc7a273b" - }, - { - "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", - "sha3_256_hash_of_public_key": "647a136f20b22c63afd2b88d14fe7677cf5c2b78223a587068377021f6edfe9b", - "sha3_256_hash_of_secret_key": "e70be83a7585618e7b91bc9930a581625e2441962c823a27eda9f6dfff8528ee", - "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", - "sha3_256_hash_of_ciphertext": "6287ca7c4d1eb3afb6ecfc456a4ca9ef5776177dbd5115165424c66e2db061d8", - "shared_secret": "2d56c88020d399532bada6516f9a1acc28a565cf252bafd40043879bcd6de1cd" - }, - { - "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", - "sha3_256_hash_of_public_key": "1cde599b2dfc69d59036434cc0423337513fb9506452bd8f42bb82661ad0065a", - "sha3_256_hash_of_secret_key": "aa80a266176a7ef8fb22fe21fcf3d3762cfc36734d8b6db3c6e1d4df1eecc1a3", - "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", - "sha3_256_hash_of_ciphertext": "31c85544389bc3163e6893d9298d947a6cd189b045eadf8dcc265e4b5c750fcf", - "shared_secret": "44052d0cc62801e0d9717c65ddcb560246cd901f104b4252eeaef903f7c26af2" - }, - { - "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", - "sha3_256_hash_of_public_key": "2a50c7a070b3dc7e107eb1e8b96d62305c13327d729bf9d97c69f1fe6eed2b52", - "sha3_256_hash_of_secret_key": "6df052019662b83b16b4da0a85b17f2fe56ad269b294438c8ad298d2e2269d2f", - "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", - "sha3_256_hash_of_ciphertext": "c485c6e392c29c231c9eb04861fefff1fc27544443ebb316c74f9d4d7d9be68c", - "shared_secret": "2e95f47543ff640e6384d65cede004c4fc47e9e2f05649e694c18c7faf975987" - }, - { - "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", - "sha3_256_hash_of_public_key": "5f166082ad3ab0c739cbf0a6bbe2707741d9b5f53a0e16199280a2376c9e5a17", - "sha3_256_hash_of_secret_key": "391b71e679b9a0a23a1aeba042ec7df439fa0a18c6442dbfe2bbe05d4fdb5fd6", - "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", - "sha3_256_hash_of_ciphertext": "499c37f74e94c6c724e218f339b8d60ab65190e0a56e39a6b4cf619db98bb57d", - "shared_secret": "42f1442e384b4e747794c944f4df154cde33cdff32bf35c2c5234919762030ca" - }, - { - "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", - "sha3_256_hash_of_public_key": "40b3a72c164432e6ca838693ef25b30013e5cf56c1e6142828107a10cabdd169", - "sha3_256_hash_of_secret_key": "6f970259ae97422f8698120bfa8e53f4f89589773243db6e7a1859c94181a3f6", - "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", - "sha3_256_hash_of_ciphertext": "55e508c96b8b7c06cc9a88b4c9f974abd3e2cdd96ba6f0cf330ccaa3641fbd29", - "shared_secret": "a50a07f6b01ee4429848806031637c8ef8da23f253874124452e3771ef98b6e0" - }, - { - "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", - "sha3_256_hash_of_public_key": "f475da2ec982c47d91b24bb5ec6c51910530eec26f38541b173b38927d23c568", - "sha3_256_hash_of_secret_key": "f8c836ce8a42d6d07f1ff40e2dbf16d264bb6ecd1cc0227ebf792a6bacd327ec", - "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", - "sha3_256_hash_of_ciphertext": "d63a88547104683878df29e59de826821fa3a95bdd668e5e838e08a671d887ee", - "shared_secret": "c299f650b03170f5cdef5da81e52c2a094b11aaf58426e8c41e06a26c7d5ccc1" - }, - { - "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", - "sha3_256_hash_of_public_key": "2b22f73a770cbdb80da84f97f27a14c5df5b3372d52503d3a20c3cb2bea8b404", - "sha3_256_hash_of_secret_key": "a111bb1797a3baeecc223e4fc4accf093d2e069cfd40d45346d2aefc09acb358", - "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", - "sha3_256_hash_of_ciphertext": "e9c030db90931ef3d2a61077dc33529aad87535e809d1a255fb5b5925f202893", - "shared_secret": "5e1ac468279cfe354c4d0df6ead070071b19c9707338158ff7dc133684afe2ba" - }, - { - "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", - "sha3_256_hash_of_public_key": "3d8fe8354d81146fd65af657da08926bd3a6ecbc2f81cb58d1aaacfe5b6e686f", - "sha3_256_hash_of_secret_key": "d1c524a715b2d05abc8e8729204b620f4551815cdeb00662b487d58e99c0ac7e", - "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", - "sha3_256_hash_of_ciphertext": "c256150127c8119ae42a62b90ac9a7119a3faa5442f058bbe5844d29c99c4eee", - "shared_secret": "7841501410e4158cf04f92b9d65d0cec732984ea66809130aeb594156829dd39" - }, - { - "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", - "sha3_256_hash_of_public_key": "36fc15e2340175a2a64ca1cf31a4b38ed5f797aaa8acb0c3d2ed9c19c7099f27", - "sha3_256_hash_of_secret_key": "0741ce5533316ef689bd966721b1ee57a272d5eb557dfa6fab6de770a2e7afa0", - "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", - "sha3_256_hash_of_ciphertext": "0c6a7cce80da6e6a3c17b46959124b8c26a8a74b5068f707f582cb5b811e282e", - "shared_secret": "6b3fe0dd082bf384c3e08497d380516e78ca778de627c112d02dc8c393334d11" - }, - { - "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", - "sha3_256_hash_of_public_key": "26a1b77ae8a807e9de16a9ede5da5aec3ca5f23f5ea00e455d4a091467e6ac6d", - "sha3_256_hash_of_secret_key": "2bb0f5318208eba32bfba206dfe174f976431dc12421bc7b3705fc7c0b4a06cd", - "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", - "sha3_256_hash_of_ciphertext": "ba2e94ce526ee4bdcd818855708af8173acac373696df4f910720fb296bc1076", - "shared_secret": "cb15c306ba8d5f4f8b723db93bfbcfd4fa02ef32ed8e39c2aeb706a463d9a40f" - }, - { - "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", - "sha3_256_hash_of_public_key": "2460170e6cf1da1e7b92037f51b4e7674d9abf74f5c225c5c6ce16a971691284", - "sha3_256_hash_of_secret_key": "a364a1f435a2d2a341b59a1886af0d0f3580e56306869bbab819de741ac9f642", - "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", - "sha3_256_hash_of_ciphertext": "ff21fac2cb15307ebb70ec04904f636bfac9ba968e86984b4a55dcac70430c1e", - "shared_secret": "8dc8bc55a907bcbad27aafbba2cbd957c30794e3770d0984a6323b641e5fe53d" - } -] \ No newline at end of file diff --git a/kyber-crate-tests/kyber_kats/nistkats_512.json b/kyber-crate-tests/kyber_kats/nistkats_512.json deleted file mode 100644 index 6a3125287..000000000 --- a/kyber-crate-tests/kyber_kats/nistkats_512.json +++ /dev/null @@ -1,802 +0,0 @@ -[ - { - "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", - "sha3_256_hash_of_public_key": "7ffad1bc8af73b7e874956b81c2a2ef0bfabe8dc93d77b2fbc9e0c64efa01e84", - "sha3_256_hash_of_secret_key": "26e1b5ea0f48b3c87d7ce87113b6a93a49d9f7ede7c5cb15b41382bd3243715a", - "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", - "sha3_256_hash_of_ciphertext": "a3856ee9fb112b154b397c91398576dda45391b89742603436588d81ce6d1b50", - "shared_secret": "c608777086ed9ffdf92cd4f1c999aedd0b42e5e8ef6732f4111246481e260463" - }, - { - "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", - "sha3_256_hash_of_public_key": "13f0970c03d32967b06cca4cf58e87559128d14cb3f876a1ed10eadfe03fc1a9", - "sha3_256_hash_of_secret_key": "9c613d0d3313af8169e65295e8c4f21f0b5d3e78de031e78a12ec864d71b6548", - "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", - "sha3_256_hash_of_ciphertext": "557c682bda01552173367f40bd2b2c1ed64aae3f083c80ce2f812d0b60acfacc", - "shared_secret": "9401f92689a452b5e58c35cf06690596faa4ec0937a04493a359b59ab3b0fdee" - }, - { - "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", - "sha3_256_hash_of_public_key": "083553153f7d65cd5cbe201e681245eda61e1ec2c7ee6b91a9ccdeb6b76943b7", - "sha3_256_hash_of_secret_key": "b4148d4bba0430ddca173618456704ddf440b9b5bdfd61ee46bd79590dd78ff3", - "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", - "sha3_256_hash_of_ciphertext": "7b7b882320575a3cfa5f0ca2165ed39383921da042f7bce896896fa90fef2aef", - "shared_secret": "f2c689c7a8180baf27a4573d3e6154d4f2bff7b3f34d44576e777e2ac1249e8c" - }, - { - "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", - "sha3_256_hash_of_public_key": "9df5746a44b10c1886f62b068d18152a85792781160e1a1a19a25b5ca00555f4", - "sha3_256_hash_of_secret_key": "75a93307372e001d4fb028125dad61c4412ac864bf7eac7a213ad3dca6599981", - "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", - "sha3_256_hash_of_ciphertext": "72782e8ee6fe4e4442723e727b5d415f66fda7c363fe6dc7be22d9b8741852f2", - "shared_secret": "1dac4f6f8d96ffd931f67b03cee8c4e4bcb42eb8bbda5cb702dadde8340d1524" - }, - { - "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", - "sha3_256_hash_of_public_key": "9415ce164fadececacd75fdad3284af20c52fa576699029d6e0ce77bf347d520", - "sha3_256_hash_of_secret_key": "97f1f85233dba2a50848add15f8f0e60f4ccf3542dc6da5f59e06f6b27c59c67", - "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", - "sha3_256_hash_of_ciphertext": "80f49e8f6f8d442a7678f2c33881a5264b58a5998b7d9a8e10b2febf59ba868d", - "shared_secret": "01adaecc8cd981e7f00187622defc0cbb8934464ca4675d86bc7d9b69148c85f" - }, - { - "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", - "sha3_256_hash_of_public_key": "ca2232297ba8b986dacd401896cb6239f557720d91a2cfb7a73274bac7a0f6de", - "sha3_256_hash_of_secret_key": "17446e8436a68423ba4e22a57135d470c7e91fbe0a4da065bdc34897fda89b2f", - "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", - "sha3_256_hash_of_ciphertext": "a08cfd7a6374d902e153b862449efdee9f912234f3e7a7d2697ebf1909f59dfc", - "shared_secret": "6f13bdb1452d9e672c8fedaf9450c436e5fa77e8d58ce83300b8e539f20e9dfa" - }, - { - "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", - "sha3_256_hash_of_public_key": "34486689b387ba25dd0e9aedbc53034924ea4ef9497b5772f10ca4d091e9e846", - "sha3_256_hash_of_secret_key": "94419fc5d865a97586b71a3414721f04473d4d30e5a8d6a1c438752f19504209", - "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", - "sha3_256_hash_of_ciphertext": "6b930dced8da8c0353569fe807e383e2d04836680fb78881ffc6974802131eca", - "shared_secret": "c81a637f63a802a5d2b336dd960175176b2b838ffb6de5adc501bef984fed26d" - }, - { - "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", - "sha3_256_hash_of_public_key": "39d1850f7acb36ed2a35e9af6f94a06c31afadaae3545a069f892ecd8929f766", - "sha3_256_hash_of_secret_key": "98a2ef35596f2fbc7e462d5ee536f30d8bc3a5272d78cb14c0ce816fbb180396", - "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", - "sha3_256_hash_of_ciphertext": "2d277dbc8b03bbec796e778c74b4c3f408f3e47835398039236d7cd861762a9f", - "shared_secret": "3031994f1365446186b4a4d6190ac89f928f6706d08c6316d6f522cd7605adfd" - }, - { - "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", - "sha3_256_hash_of_public_key": "edc8db1ca35744a75ca14516abe07472d0d1b723f70ca8cf0e5c9341fd2e8c26", - "sha3_256_hash_of_secret_key": "fa6de16f50b0c04b8be10d3262005227715f69de5089f0f6bafc1fe26603e525", - "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", - "sha3_256_hash_of_ciphertext": "c20e526b8837092f1847b40f9b5fda528dfb72780aceb510635b490acb5f7686", - "shared_secret": "61419eeacf26714b028d2f7e1e3769ae2f181a7e9311f3312911ead00486bcd5" - }, - { - "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", - "sha3_256_hash_of_public_key": "b1eef6e8c88ff8da9cc4a9b01d4c08b6b585beb5bb9e084c6c47a717b51feea3", - "sha3_256_hash_of_secret_key": "bce9d6b2e45918ea5798910aa9baf289b04d8a5bcfa7e08235dccfc8b9479f55", - "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", - "sha3_256_hash_of_ciphertext": "811bf647ebaad03c81a84c6a82b4cab108267b1e9c1add3dff1803623471f9bc", - "shared_secret": "3871c9637cbea04a2ccd3b62c9399b0a7277a31caba8a8f015d59b0fed845bb1" - }, - { - "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", - "sha3_256_hash_of_public_key": "f581c2fec9055830b38cb68fb506aa927443b1afd1b2b6faa6f92a325985c6ce", - "sha3_256_hash_of_secret_key": "9567f27ef67c3ada92a02cf25d8ee4a6db69744d3f6de5a0026dac023d04f37c", - "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", - "sha3_256_hash_of_ciphertext": "c855f0a4521640b9136035b5d02770dbe864b85a6f54f422ccf2b512e1c07b33", - "shared_secret": "3775b12681d854b7ff2eec05cd4ac2db91bf06f3c14db2eb35287129a960ab03" - }, - { - "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", - "sha3_256_hash_of_public_key": "f12f3ecad62bd327f1c44ae86c0be6e7f15112b7f6f6d5ec7b13f4dfab718965", - "sha3_256_hash_of_secret_key": "32a666c02a41f7b9408c570a3304a80e947a1be650f5f164e376b8b34b72254b", - "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", - "sha3_256_hash_of_ciphertext": "632b389d951d4a4e570d2fee62dd87c3aa2cf0c036dc63462f3ee7e4543ef8b7", - "shared_secret": "87662dcdee8b176e2dc60d079be188f63501274bde0829f3595c99d1e564c2d0" - }, - { - "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", - "sha3_256_hash_of_public_key": "4cae8b58e0434fb1475312355a8b40145043bed4b269aaddd654d2e562324bc7", - "sha3_256_hash_of_secret_key": "53793d47a6e9e527f109b7611f33063dbe0b8a1423ac02178934f59c3d47ddb2", - "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", - "sha3_256_hash_of_ciphertext": "6f88eea1ec597548ec3c0d22c60a92ac4b0c3e17e332983d01a0bdda1157ecf6", - "shared_secret": "c5676cf0cc81871d677bd7f5982e6493aa3ea4dffbb30dbaf59e90e4977d2f12" - }, - { - "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", - "sha3_256_hash_of_public_key": "b899475c1802b1dd76a9783d93b4225dc558eea558ddc598cdc45a898b7bbfb3", - "sha3_256_hash_of_secret_key": "278b448b48a14a9be1ed211228cfab37d07e5f1e502478e3ad059c83a7c83894", - "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", - "sha3_256_hash_of_ciphertext": "36f6daad6b98df3f8e26456d06f112ca69231333e4ebd86e04fe7b8fd8c1bf26", - "shared_secret": "c5b03a417c10715a53f3a1efc044a81e266b40a1b16c87aa1f754146ac39b80e" - }, - { - "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", - "sha3_256_hash_of_public_key": "1a7e0760c345cb5875303e20e4c72076c794e56ab75231750a190b45f374d979", - "sha3_256_hash_of_secret_key": "eb53a36a9f50baac64b4c7bcb97fecae54d3f66b8311b5a67c5daaefaa63f209", - "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", - "sha3_256_hash_of_ciphertext": "1b4728ec7c6e90ad99dbee3b83438050df88887de2e6d7a6ec55e7a2f7f1bbc3", - "shared_secret": "38daf9348e4d89149e4968131370ce3d38a4028727fb85d27f87a95b341340fd" - }, - { - "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", - "sha3_256_hash_of_public_key": "0f96fb9e146a1c22cc5d23e9108af0dc5e13b7810b8f5598bbd5f8d4b54c8af7", - "sha3_256_hash_of_secret_key": "d494ee913886be1398be54856ebc83eb8cd7aab4268b976583be2e097edc2d64", - "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", - "sha3_256_hash_of_ciphertext": "3934a38f7c11d237b46c9d93a8ab8d3dfc76b3e020b5cfcd0344eae35a333e45", - "shared_secret": "60bc23845c0b116208c0ea02849cea3d8025a7220337c617c4bd304aedcdc1af" - }, - { - "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", - "sha3_256_hash_of_public_key": "0bb63b48b8cdd1c7242bd4f017c519b43502656e23817bfd683150488f8b0b44", - "sha3_256_hash_of_secret_key": "195207c9e44942d5cfbf338fb9f20317d3ae8be85dac5f10dd60abd802a3caa9", - "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", - "sha3_256_hash_of_ciphertext": "ddcc4d878447ee699abdb85f1463b113784be6d4e42c46379b31c02715243f17", - "shared_secret": "2eb03b010e291fca1bb6ed09d22d50b9c7bec93c556f1f273e57048c9c56bb3c" - }, - { - "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", - "sha3_256_hash_of_public_key": "2d19bf7937eeab0d2a7570d43cf965547542a519be85bdd4921f7d710747ec6f", - "sha3_256_hash_of_secret_key": "cd59ca5c7954d87bc8d025683563aab0f9272d6c12cc03914220aa6ee392e6b3", - "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", - "sha3_256_hash_of_ciphertext": "86184bc66edef41a25ca3350698277f4e49713b821fd0745d276fe490ac636d9", - "shared_secret": "be892649db60b2ce07ef18c4a709714933542ab94ee3250cea6e7c6f5eee5d5f" - }, - { - "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", - "sha3_256_hash_of_public_key": "6907e1096410ab332e10f37c93d86d9b4657159eac1faffcd1688d182d127844", - "sha3_256_hash_of_secret_key": "250d27ac4dc4447520c4c1193ac57d239857ecbeac2b1009dc08dca2114299ed", - "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", - "sha3_256_hash_of_ciphertext": "51c6ca6d7536a183416b16b1716cecd3d994dba4b5ba019bced87bb51f9cef0a", - "shared_secret": "75556d5854c44805ca5c4bb927c837ff635feaae939220592d89caf74592a0be" - }, - { - "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", - "sha3_256_hash_of_public_key": "379c9176059f3a7ddfe021041301bcebbc91e997a0d5bf2ed1d9d125a7129834", - "sha3_256_hash_of_secret_key": "57df17dd8b9b1411af66d82f61dd61c4f5235f48d503c164ad0da02a598a69b2", - "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", - "sha3_256_hash_of_ciphertext": "a5773e0569d9e26225b05bd61591d1722c4c1396789ce3156ef749c115949ace", - "shared_secret": "469d60c303b10f517a932d9fc090e61802003e9cba3630224f2c43a4727230e1" - }, - { - "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", - "sha3_256_hash_of_public_key": "f5515b23187af5dac6d1d090bc7bc01df34ec781561e3d3b8b62164f74946802", - "sha3_256_hash_of_secret_key": "2ab40ea093450e534152efb278b45038f1f2cccf13a654f1c5c27b8c389f6129", - "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", - "sha3_256_hash_of_ciphertext": "d1b469613c872181c4428440cec1ccf87b82303e4979de6eddd437decd8afecd", - "shared_secret": "b545dc066355b91cef05e65107fa11070c455209c55573cc549cd053c8e4155a" - }, - { - "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", - "sha3_256_hash_of_public_key": "9dc0d69094efe63d751e6f9c1e92d2107a7b45fabb820222d30b11595c351643", - "sha3_256_hash_of_secret_key": "00f4a04ab804f2fa3ed80a0fa4530fd45ebff8afadf5f5b7d46a672c690ac3ac", - "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", - "sha3_256_hash_of_ciphertext": "774abc2c6dc9570eb781a39f79f49f2cc6870a43e8812559d89d1c59bb1aa5ef", - "shared_secret": "2c42bc4a172c928bc6ec7480785d63f7281a9e5acfd3f94335d6d7fe5fb9c5d4" - }, - { - "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", - "sha3_256_hash_of_public_key": "16829a8aa9f8c4e949d4e6388448c2c4ec6a977f8c5fb80bd75d93a723bc9bbe", - "sha3_256_hash_of_secret_key": "659cb66f989532fdf5a741fd03862fb142a05a0fb43ae20bffc5116de1a66d57", - "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", - "sha3_256_hash_of_ciphertext": "ff53eb11ffac30f45bc8327d7e7d518f1c2d71bae0052ce8e15903c8d14978e7", - "shared_secret": "230a69c53e2192eed6c9b876d6b228fb666b19448e0a2ef8601910d624bc173f" - }, - { - "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", - "sha3_256_hash_of_public_key": "90fe22b38a4fafc045cdbe0c9689745fb45760cb2f0f94f7d13cf8c834c4df3c", - "sha3_256_hash_of_secret_key": "10a89c990c7676890a65e1c776cf892ef1431d56fc115ef3115c0b8f91db0690", - "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", - "sha3_256_hash_of_ciphertext": "3d1fa5720670ea284567d32beaca2e56853f7b6268e32af381034f13e4cd4853", - "shared_secret": "327c548d7df90d813f3b3c92e908c4c55fe4c7277f91b6fa2271c0f149dfb273" - }, - { - "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", - "sha3_256_hash_of_public_key": "c277a9588d9a781ddff6aa9ea8d259e5599d0adaba2f459598ebd5bc72786023", - "sha3_256_hash_of_secret_key": "40609cf26d205ce694ca8baa097bc1342d2462a26678eab90893da147e389d3e", - "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", - "sha3_256_hash_of_ciphertext": "bd274d905deacefc3d90a9ed76d59af4e814cfc06c118ec17662afa4f6b4fdd6", - "shared_secret": "0d95796efa11ef2b4f05d0cd9e1d8db26f3e5839fbba7cd84e00d468decc088c" - }, - { - "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", - "sha3_256_hash_of_public_key": "d3c8cc315c4054d09deac08c6d5d364fd5d47a3c09041bee42c561f978e2d98f", - "sha3_256_hash_of_secret_key": "3e1b23ca9dc111c4a3cb0a585c7f4e5d1f27a71533eaa5347e285c7c35e81990", - "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", - "sha3_256_hash_of_ciphertext": "c866f33265de001b3308ec41682803d46dc61d423d61565aa5ab2f1367c93e3d", - "shared_secret": "cc047c6cad36dd056b84e6b9a4fb6b1b349d593e104ba94a67b107b291ca4633" - }, - { - "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", - "sha3_256_hash_of_public_key": "dd1a07043fa0c6452500249601f25de742ab44213e2718cf0ddc5ff6a2a9aa6a", - "sha3_256_hash_of_secret_key": "2cfeaf5c1b4195f0374256027d3a888e9a093de8ff9181296d5b1b94048de38a", - "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", - "sha3_256_hash_of_ciphertext": "6dad2899c49ef32329180b6b8749c28a24e070fe989027061dea25f0b05490b3", - "shared_secret": "2faf2dd50be618b025cd2b53365221f5258e175e4a445cf053c66b3d3a998c8a" - }, - { - "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", - "sha3_256_hash_of_public_key": "f2a8cad42c743eb61aa338049ce917616899c803358541de1e58cbbdcf3c6328", - "sha3_256_hash_of_secret_key": "7a9ebb792c7193ffefe6e4760ebd0dec6f67c3f3b0fddb5abb4b7e931ee827e6", - "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", - "sha3_256_hash_of_ciphertext": "125f7da90bdf4bbeecc54e47e065b221a6ce42d0569530c136ce2c9415b17e79", - "shared_secret": "cd890d2eee7f747441ca9448c7192bcc274e8b0c3c80005cb6fdb4691186d85d" - }, - { - "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", - "sha3_256_hash_of_public_key": "3394e8401245fd6348bfa697f6990b6671577ec7b35a45b0101730a801942643", - "sha3_256_hash_of_secret_key": "3ecbb219e90e2250ad5ba87f53975439cacc030c3e1641b87ba8c5b3d89a4aba", - "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", - "sha3_256_hash_of_ciphertext": "6cd30cb202554c18809da0819ced4cfe83021874fa9c48c3374b7544e3256f5b", - "shared_secret": "e7942359dfb015d5022b790b5e777a93a5963260ae352567d3fb7e27b2ef0bab" - }, - { - "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", - "sha3_256_hash_of_public_key": "ec9c0d68c84cf3804f14e8daffdd1e28c28d3d55ee782c98c498b0d9bd4ebb23", - "sha3_256_hash_of_secret_key": "24a2b3c3efd979a1406e92d5c504d5004079965b5fd0492469f1b4250f7023ff", - "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", - "sha3_256_hash_of_ciphertext": "a2c6cfb957639661086b02d9a312e7483150fae87d84f21f56e48850af7e3b62", - "shared_secret": "5d7b6ecaadbae69fbaa9e004634ea609df6ec80801bbe73671f4e52169cc9683" - }, - { - "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", - "sha3_256_hash_of_public_key": "a9d7d5a52aa2dc226832f6e4603322f60b1dc21207e3360712f9c6445d37e64d", - "sha3_256_hash_of_secret_key": "2e5342a1c2f58a48e044a26673799c63f88656f6d350a0d7e57bbf8811b2a5e9", - "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", - "sha3_256_hash_of_ciphertext": "b79a2fbd2e63aa66a526fbb42440224fad7ce91206df3684d1deb4a3e57bfafa", - "shared_secret": "547666f6c72c97a8f06fbd7cda4279165dc82489aba2119416e0dc46795bc464" - }, - { - "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", - "sha3_256_hash_of_public_key": "fa7ba132b5dfa2e3ce67b64bc72d551f3290d428cfbd45ec026f44c8dc28334d", - "sha3_256_hash_of_secret_key": "34306d06720216257691fc65054ed32decd609312f5c5f061e7763ae73fe0aba", - "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", - "sha3_256_hash_of_ciphertext": "acd7944297fc3b0d2daa3b0cbc999a43de7e9f948d39b9c6a4746873e285f8a8", - "shared_secret": "88c80381cde3db2c1d40aedf8cf923b79b18cf76efe0e46edc3e25e17c7cd8c6" - }, - { - "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", - "sha3_256_hash_of_public_key": "29f8a01ba71d04d6831c03d1ff294fb58ef6f4041772cc071074829c32a3ac9d", - "sha3_256_hash_of_secret_key": "95f9b4063bf05f89ca9f99e393b11c0f2105eafe40abb313f345b58e10519955", - "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", - "sha3_256_hash_of_ciphertext": "096f7946c01dc61a13dac8b85d9c377f9c86aaf8ddc02163a74169854046a1b0", - "shared_secret": "ccda9f28bb09dc0017a1df8e1796a3489c66afd2c3898a39027c843cf022b790" - }, - { - "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", - "sha3_256_hash_of_public_key": "357376de9843d74252466888727f9dc1ef48d028c0f52c902aa0dfc3de374c83", - "sha3_256_hash_of_secret_key": "b8d675ce213c73f9792f328448850047f4410fc500212939ab2e234b619c9104", - "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", - "sha3_256_hash_of_ciphertext": "a0810d28d2dec44499bc47d48ae22984c17728547c3ff0cc859702d2a6962f88", - "shared_secret": "caea7e78e6f80e126a9f41ddc0ae5946a80cdf617635934b22c9097c5090ce59" - }, - { - "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", - "sha3_256_hash_of_public_key": "30382cb59feee1b6b0fc129fecb8c74034da92987249bc20cc8ad4a2cfc1bfe0", - "sha3_256_hash_of_secret_key": "2600203271549828d0979adea52e2e976b7d9f85bfa6931d6c79e14137fad51c", - "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", - "sha3_256_hash_of_ciphertext": "4d20b7665cdea726a3240782143beb60585d4ae39bf18f4ab5343d4f44c7acd6", - "shared_secret": "431bba421ea89647d815a16f440d47f1604b67d9a2d33f2dcd21dae7e65bd5ce" - }, - { - "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", - "sha3_256_hash_of_public_key": "f4e474fd64a6d945e85eb4ee7509cc99fd4054de99f819fdbbb05c54ca6e36da", - "sha3_256_hash_of_secret_key": "d8a3a0edc73fee057281add9e7cb328566fb22c5082978c69088d76e98ffff90", - "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", - "sha3_256_hash_of_ciphertext": "0f18bede2f42d6fdf32dcd2cf8937ee8d2909eef0aaca8586c3892d608712a98", - "shared_secret": "cc0a7809cf6787a4587e090249709f694b709ec8475a42b4705bd1ba312c098e" - }, - { - "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", - "sha3_256_hash_of_public_key": "50688de263a82386f39a7b82592247bf5499f1836a3a941413c75f6331ce4031", - "sha3_256_hash_of_secret_key": "ff207007724ca5d696ba44cb106f525858111d55323c9fc0fb98d64d4f8de8d8", - "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", - "sha3_256_hash_of_ciphertext": "9dcc43fabf94918ed4f7936960d8c732deb2209090d1303d62d5ba591b51a142", - "shared_secret": "cf21da86b3e09c38ce5799637b1492a1a268dbf0ac716499c68bac11a774f41c" - }, - { - "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", - "sha3_256_hash_of_public_key": "1a29c0f2dc4089a85db6865ec90faf2f4ddd25f210eb56e49741866bbca8cf81", - "sha3_256_hash_of_secret_key": "477dbc28e4f21587f274e7a3b673f743840da1501c35f0e9ceb8972970de6f86", - "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", - "sha3_256_hash_of_ciphertext": "877f477beda55ed2a7c34408c04b4a90596b4d94ac1830bc04a0ac9b73761ffe", - "shared_secret": "b56f557eb758ae10d22b5d65847cd811475b96f5a46b0ed3bc2f1b9b371fef0f" - }, - { - "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", - "sha3_256_hash_of_public_key": "3fffc419d3d8a887ff789eb661b2af1ee5b32a302ca267b33eac2ea7e3340b97", - "sha3_256_hash_of_secret_key": "0f42068d2885e1a44b2ce4042675118f4fa35f58c1206b965b57ccb52c4f25f8", - "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", - "sha3_256_hash_of_ciphertext": "d8f7b4a0047c18a84ed13e3057e240cb578cdd2ac1e57dbbd6253eca9208d6df", - "shared_secret": "aec1264f12ddd2ee8e51b71d703ca5c2718dbd79858240635f9b076c749a5ffb" - }, - { - "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", - "sha3_256_hash_of_public_key": "f1de70b1072881eb659a5e890a92c9313c7378d2e960a060b9c918260d4c2458", - "sha3_256_hash_of_secret_key": "ecd9d757d80352b4fb51c71976d7b2ddeb927052f9f7a7cc61fa67662d4dc86f", - "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", - "sha3_256_hash_of_ciphertext": "10b2b1dfe168aace0dce3776456c2e2605f99fdeaadfa3ff5e7a81f6bafcb76d", - "shared_secret": "6514a3b97760070116c64014c5695df60d0345b29ada92fe24b672586f5bf06e" - }, - { - "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", - "sha3_256_hash_of_public_key": "b0c77b5407577a9a9cd8864efb80974aae107fa2801b6ccaf341d5456a86621f", - "sha3_256_hash_of_secret_key": "0feade68babcf09673bf843c59379520c19081f2bc33940a8dfcee07832ec66d", - "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", - "sha3_256_hash_of_ciphertext": "b204aa70efa18e31a11b6b92e6c7dab4b2f4766ec5d302a0e93e4feb05fe4843", - "shared_secret": "52344e5e173fc6088c9dc555cc90d8e5de19bdfa0d657ad8de1a3c24ea679bb3" - }, - { - "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", - "sha3_256_hash_of_public_key": "255d2e2fe01c87cf70bc30703644fc255f83fb47cc5cc5ae2c0e49d6198cae03", - "sha3_256_hash_of_secret_key": "1b1050f38bdb785ed43daa264b60c7946d93f135c65e93c95c39fd1f2d7b5311", - "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", - "sha3_256_hash_of_ciphertext": "55165f35498250256c30d0f0fba6ec57db352a6ebc05ac42eaa8982b2d48af5c", - "shared_secret": "ce80f65731c8fac072f7153bbdc425f76189d01bacee8462060c62dfeddfaf64" - }, - { - "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", - "sha3_256_hash_of_public_key": "63b304a19162abdc4234e6046109f99f955695580a8b782017e107e45575bd78", - "sha3_256_hash_of_secret_key": "19aba21e57d4b3aca7209fd5cbd15f9e7cb9f6777960d9452fed866e9e9234f0", - "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", - "sha3_256_hash_of_ciphertext": "5eddd27af25f9553e3a5b20e4de86280c65eb689ffa7773dbb5d24640bf51248", - "shared_secret": "3b23a3cfe57897fa9cb691ee9805739f40d2bf22930ca9ee48ebb7163cd66bb0" - }, - { - "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", - "sha3_256_hash_of_public_key": "3c598a48b06d7474da19ca85aff6b2b3303b5d25b96088c52a08cc7f1e87c5fd", - "sha3_256_hash_of_secret_key": "03c563426eb21d277421a30ca8980d4de86f7aedead9ab9aefb3d7362104ec50", - "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", - "sha3_256_hash_of_ciphertext": "244dfd0105b643caafe35fdc184b8e23c7538370d545e6f08357e83f413de258", - "shared_secret": "272ecae17c3d107a8b008f60c8844ac01e09b8bee17eb4972f5f71774af2d54c" - }, - { - "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", - "sha3_256_hash_of_public_key": "9911b6283fc6dee66e16d411fe39bbc9f53c30bb54f05044b96c740ca051c61c", - "sha3_256_hash_of_secret_key": "06751acd0a50beca92428cf8c803af429068d4e5c4f74cc59e6d3275ea6da737", - "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", - "sha3_256_hash_of_ciphertext": "dc8797dfa40479e4edee48d320320ca4a84c55789c94c34ce4f0a4be83ae0568", - "shared_secret": "eb456d8919c7e96c4e18d7a0ae27d47996e4f94c46c60b4649b327903acdc0c0" - }, - { - "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", - "sha3_256_hash_of_public_key": "e78d350d2836d1d17e6ec375a0cbe0d6b2afe1ac036272dd41f8aa769c9d0668", - "sha3_256_hash_of_secret_key": "f74b8f9343146c1551a3cf9fb3d4e88febba4e98db745f36678d854230a8d7f2", - "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", - "sha3_256_hash_of_ciphertext": "400cda4e51c1eb539625bbe6679fc13b009e72cd442a1385759e7090e54d31bc", - "shared_secret": "3f92ab2eb867d4e2e658917fe95b19042cd768dbbcd895e83b7bfda621fc428b" - }, - { - "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", - "sha3_256_hash_of_public_key": "5820c7564d087683c0a4864844335bcbd62afa1ee542c3c1dcd8b72c80824b50", - "sha3_256_hash_of_secret_key": "11212a895ad32958d25d2ad32e917bd5bfda9dfcf08e316f733b74479469f9b2", - "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", - "sha3_256_hash_of_ciphertext": "fad3a5efa62eabac076fd38f84e91f3c20f7b263408366c476695a9665972ddc", - "shared_secret": "5890e86b38f7fb11708a63f5e98ad65d10db5916e6669e1b0161142e6d30d017" - }, - { - "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", - "sha3_256_hash_of_public_key": "c56eb5880e9d9d0fe7901747f75eca1996c722ac47b76f34a4dbaaee0ef8a611", - "sha3_256_hash_of_secret_key": "8a90ed45b5910904e2e9f6a6e410d4caf024ef6436fbb75fdd179eaf09f6f362", - "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", - "sha3_256_hash_of_ciphertext": "16f18c8dfcb9aa496f8c6f8a76af4cf2405407e0f0467deb4adb7049595b0df6", - "shared_secret": "3b09c4579ad60b17eba6029141a6d9765e1abae72ec32f1b329a5e2af761a087" - }, - { - "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", - "sha3_256_hash_of_public_key": "717823f0b58cdfacafc795aea529561d11374f02964cf635c27848671043766c", - "sha3_256_hash_of_secret_key": "f3c47ab6b2f2a0962faf49bbc31f3101d6f4b867952aa3bbee32408c1b88ee82", - "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", - "sha3_256_hash_of_ciphertext": "fd6a149b033707358fc07243d95b0256153c30e65cbc9479ce05ad2f96204a37", - "shared_secret": "f15864351fe8e878ad66b402f012668e8bdf21525f09d5bcf4a4dad656d2e480" - }, - { - "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", - "sha3_256_hash_of_public_key": "7a13afefbba39ad59c088825380398f43f1251b83b0ca9debba0102f902d7190", - "sha3_256_hash_of_secret_key": "da94e15b824e73150a408df01cf1c5e4128739524831a4c2f45d0724144010fa", - "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", - "sha3_256_hash_of_ciphertext": "9193450ad037d38d8e85a46a522d4f6562ef7c7aa1372a2ebbc7ecefd1286bfc", - "shared_secret": "1f1a7f0d0d86a52a6679c431c322263b185b0c90ce40db054928be438f38d47f" - }, - { - "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", - "sha3_256_hash_of_public_key": "dd4cfbc29de3568663a3a044c3f897714363b0fdd3b6ee55f796292d34c7c79b", - "sha3_256_hash_of_secret_key": "6142d02fd4501c7bffac124bb8f26813009d2bfb91023a3fadea9506a40e1467", - "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", - "sha3_256_hash_of_ciphertext": "bb6e0249218f8bb4712d60e59f51cde2dfecfc1f828eff42f2707aa59f12164c", - "shared_secret": "aae9ca8c35deddcfd7dbaa7780fe31c102aa90cc594eb56edc782fdc4eb53b41" - }, - { - "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", - "sha3_256_hash_of_public_key": "9ca90d64e28a5bbc54c36053ed333c530f72549c2afd77b10c2944fc833408fa", - "sha3_256_hash_of_secret_key": "510f84cae4d4307d7848f4c9665061657ae81526139a8b6a4076ad3df919abfb", - "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", - "sha3_256_hash_of_ciphertext": "36b3567939ee624d5088c4daa597c73349270a754d3c272ec3ca5e08bf896fec", - "shared_secret": "970fe36e57a253e88cc80c9da6867dd66fd8da1dc15c85a480a1a45eed708ff5" - }, - { - "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", - "sha3_256_hash_of_public_key": "da073c98794493ec169c78eb75a39c1594ccfa635b8707325e0ab6cb8576e30c", - "sha3_256_hash_of_secret_key": "7829ef884941abc63f66889c3d44381f5450de1b95c6b6f79f909d74b27125a3", - "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", - "sha3_256_hash_of_ciphertext": "43f8a2c466c09c915fdbf0d0dc5069ae5333790e7efce86c163d360dd0fdc0cd", - "shared_secret": "8eb310431276a31c1913cfa2e2d6b0dedc8a208c7470251daebc5b1bb6ee78ec" - }, - { - "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", - "sha3_256_hash_of_public_key": "c2aa254714dac09b9e712572b24154be391063afd3cd8cf4cc4ed8ef21f0cfe5", - "sha3_256_hash_of_secret_key": "2e552fd01c00cf43110aacac37d01c02e5f59c87133e3769d3b2bf0fd2e4431d", - "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", - "sha3_256_hash_of_ciphertext": "854806aa3266473aa5fa6097095d5f21707ab4df857d927e8848146bc4cc2bb2", - "shared_secret": "425a88aa4cbb6b6de122f1730aee536f1cdb8fc84751fc6eb2b42bcde5febcb1" - }, - { - "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", - "sha3_256_hash_of_public_key": "8aaca951e0573f28d50831960a28dd11126f0eb080afc55f394e8eaf6379f6eb", - "sha3_256_hash_of_secret_key": "45592f0d94666d8201247fad4d0acdfdb4635a5e4fa85b7e25b2391639451bdf", - "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", - "sha3_256_hash_of_ciphertext": "035223323ac02f2a52f9c19da46b31a7e189073fd5ef5ceee6ab8dd1b062b6d7", - "shared_secret": "457efc40f2e99aa599ac1ef92f9efbfc93d17fcd793837857f6a5c91a8dd7da2" - }, - { - "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", - "sha3_256_hash_of_public_key": "f15a8fc937b12ff78c54fc273fcd7dd5611e5835472ed377652ae64495f9cf52", - "sha3_256_hash_of_secret_key": "dcdb853d17884fb04396dc10d34bc84d594343ceadda564fcdfa9b4d47dd4e3b", - "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", - "sha3_256_hash_of_ciphertext": "a94ff1a0c62792c0e1dbe578210ba5a7f3cf8a9f9763a16362d66a3082e4753e", - "shared_secret": "99b58031465868d0617fa795e6be1c33a870a1e154a85a2bf61346f7c55f3b76" - }, - { - "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", - "sha3_256_hash_of_public_key": "ef7ef8d7d81aa907fece4c1920c7ca9dda3bb9d57f09193487bb89d6422f10cb", - "sha3_256_hash_of_secret_key": "2bef3558b547044290d1232a580a6a473cfcd8d87ced6305f996d4db4f46e6af", - "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", - "sha3_256_hash_of_ciphertext": "0b60d83d562b66153e07bffb5bb05b7d268351377381b04f1e59201f961f1907", - "shared_secret": "387705c2ed600492a0b06f5587ae3c40be55e6d5592597e57cb8015de9e9271b" - }, - { - "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", - "sha3_256_hash_of_public_key": "99b151aa6b4654589afc36b8343fcbdc09a3e5255b378d6ee5629cd8b3cfd555", - "sha3_256_hash_of_secret_key": "b7a7d95034017d523ae23e29fc400e9a0b320f9778ba1587b69dd012f2aa47bd", - "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", - "sha3_256_hash_of_ciphertext": "3a4ba04bec2aee99c5e4e2459f1aec52fc950ab67b61570d57a17c4f3d9031d5", - "shared_secret": "2a426534e3c23e28a237047aec83d24abcef8c7f77d85d8b27aedd7c50263010" - }, - { - "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", - "sha3_256_hash_of_public_key": "339ba63f705606d8c7fbbd6e66dadbf23f532d5423802c836f2105a636e9e6da", - "sha3_256_hash_of_secret_key": "60aa684e7cbf79e9c70504608a4c0f2cf8dc207f71b1d0ef5e3a99013ee866cc", - "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", - "sha3_256_hash_of_ciphertext": "f5d1973f7c10d3ff7cdb66195ce52e182f40ce5b9f16ef67e31ce8632cf617e8", - "shared_secret": "ffaf18d4fdb39a4aedc80c7985843f6b87a02e36c69dcb00f3cb01a619a77779" - }, - { - "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", - "sha3_256_hash_of_public_key": "1f9e26333b637ef9beb8881c63f9412b07c47a276af0e242062a54026bcee2bd", - "sha3_256_hash_of_secret_key": "f7f38ae2caba6d7e87b7bee8b127a9aecbc0b795345952d65bb4435e3720f89d", - "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", - "sha3_256_hash_of_ciphertext": "c42f9beac87086ca603d95377c5e539735752eee043653fbacef0d2824b91d86", - "shared_secret": "1b37c256820ae408a0005a1fe7461d54e53813e6e7ad58ca3dde46a53a44590c" - }, - { - "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", - "sha3_256_hash_of_public_key": "64b9f8198bab9b3b2f2a1704cd4ddf6b3cbc216ddc0f062a72ef40115917fd21", - "sha3_256_hash_of_secret_key": "a3cf5841bedd9be95061b910333190834063e5cbcf0fd32673f8cf3f6b548d17", - "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", - "sha3_256_hash_of_ciphertext": "056998cb46e48667cb4bda6dfcff9321219b13fb1a682e90bfba6ca025bbe6df", - "shared_secret": "12871c83c35db351c2c0b4afe0f0ce9fe1f21fdfbe8c18a485d5c1292faa531c" - }, - { - "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", - "sha3_256_hash_of_public_key": "de4ce515b882c849717a1ab34f2ac0238c868f415630c1155bcfb302d346dc91", - "sha3_256_hash_of_secret_key": "4b917d9daddcdc932fe0448063a24a592edbb0e6e40b5b53812f20a4cff7a0a3", - "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", - "sha3_256_hash_of_ciphertext": "e4eec4f31749692984bee94c59e2947afc769197fc18b20d2e34ec92e7d15ae1", - "shared_secret": "adf49431dcdeb29f729459cbf3c2b94151005c7b841eac921a71262d65dcff99" - }, - { - "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", - "sha3_256_hash_of_public_key": "93b60f0d00c09af885b5a0cbe942fde6afc4841428104710823bdcc12319eb35", - "sha3_256_hash_of_secret_key": "953ab28bf8cf18e86b8c80efae0bb47582d720e787fd2af27d9789c1ffb7ea1c", - "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", - "sha3_256_hash_of_ciphertext": "ed5b2ff1ee4222029e7c0d858da6ff1a1417a74a501b80d1b5b6a4941329e892", - "shared_secret": "35e1521271e7ab9931b2c25d75f0f09a89b3f83a6bb62ceb99e8e00c5cf78afb" - }, - { - "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", - "sha3_256_hash_of_public_key": "167a2fec4d72cac2ffd844246eebabdac0c074e4f984433744e31d299faa389c", - "sha3_256_hash_of_secret_key": "9afc4ddea68ca10e36d9b12d3c34595912eaafed49d8ffce01cbed09501f7527", - "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", - "sha3_256_hash_of_ciphertext": "a076b58fa98a7282c2cedc1e93c1473dd15b15c1ecef192955d8a813180b3217", - "shared_secret": "715519f07b29bbecfc0776e35417558e3bc50c76b8da6fd4c99391b7bc7873cf" - }, - { - "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", - "sha3_256_hash_of_public_key": "955468734662471c953fa516b35b3a53053ff396b7e2798fe07a2ecd549d6c06", - "sha3_256_hash_of_secret_key": "8bbc886fcb7516e7888880921abfaa72823ace9d50cf0afc2f68c4a7c3dd2e53", - "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", - "sha3_256_hash_of_ciphertext": "87914dbce6a365f7335188d83f2394b0fdafc9b0676c022608401cd93d294f36", - "shared_secret": "5a4ba3737140bf227c0e618f74191b3de1c1b8e24b032036942de66a13ef5a91" - }, - { - "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", - "sha3_256_hash_of_public_key": "f7310c0531060051469ffcd2f88e3200bec6c721bca1fa4c9e7bf1773d7ccb19", - "sha3_256_hash_of_secret_key": "16c976495bbd05ee6715f30a9323aa41ecc320e2e63479148ab3a51132afd7b5", - "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", - "sha3_256_hash_of_ciphertext": "37ff2acef57d0665358cc5ec7f489160d602d41c21cbb3332670f3cf0044fc39", - "shared_secret": "87528a4a961de06d5856004eba20a44590a1bd88318fcd1ae1dbfbfd41f152b0" - }, - { - "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", - "sha3_256_hash_of_public_key": "152c13a9a4dfbade0f98e8a5136358f69c93f0722addc008952cf72e1bf350b1", - "sha3_256_hash_of_secret_key": "b93c3fb9dbddaa560dd52c6a1c37f6aeb2111e46b7b746419e3c27fa43a27211", - "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", - "sha3_256_hash_of_ciphertext": "b62ee0b20daf3a87406f7f8428d6dac79ad5f95c225956a564f896658ed51eee", - "shared_secret": "3652a13e36459a324958a2c45328fe4ca6163ba833400e643b0a6e51bbc594fe" - }, - { - "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", - "sha3_256_hash_of_public_key": "97e5b18cff525ef46fd8a6aa6e5e4b8d953fe1e67b5771d1b99ff18e754553be", - "sha3_256_hash_of_secret_key": "55102f3a620209b46e41531919a1b6f091c86bbcc5bdcb52b18f9a070680bd66", - "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", - "sha3_256_hash_of_ciphertext": "6d20fbb0cf418e91e295f391160df696348b3fa99542d12584c0da554b96153d", - "shared_secret": "c07d965e4a87e89e9fd5db44cdf225b20157a6842e2862ecb4f72d8aac933c2b" - }, - { - "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", - "sha3_256_hash_of_public_key": "7b5c67fa6e0ff374f691540fff0b4d14d4ed8a8a8c48b14b2a35facb413a5ee6", - "sha3_256_hash_of_secret_key": "449e7b1644520512fa25ea48f468ce9f866ea08178e814f11561efd4e4aad792", - "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", - "sha3_256_hash_of_ciphertext": "e4f728484e23e99dcd35c5d3ca6d62e3a829e60a784faec5dd9fbb2d0cfa8bd7", - "shared_secret": "a502041eee317af1e9e6f9a9c12cc98415b358ff179d4d64ba5b7463a1f33b0d" - }, - { - "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", - "sha3_256_hash_of_public_key": "8e49b73bae3b0285bbe1676eb6fad2641e7354e4c0a4feb0b74bb16708b01351", - "sha3_256_hash_of_secret_key": "23a598fad0141bdf07257c662d22549343a01d75eea9c1ebcdeb4a138c6e215c", - "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", - "sha3_256_hash_of_ciphertext": "cb2c217f6ad9c504c9fec4750db44d2c339017542da415ad81094290006e9273", - "shared_secret": "a354e870cd600e5a5951aad3491c31a80b0545c1662f830d7f0b6d144ed3733b" - }, - { - "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", - "sha3_256_hash_of_public_key": "f5de62d662f480d4ed8ba235b4aaa4bfff19edebbbfbd96e5a9b7c4e89365c3e", - "sha3_256_hash_of_secret_key": "583ad55aa14bd6a4310d3ab7aa619cf59c93906251f5721a0bf880a866517f70", - "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", - "sha3_256_hash_of_ciphertext": "a9f97b3e253dcb15c8ef4c5576786d967e504e8f76c0bf46e051b8f123fce22d", - "shared_secret": "cd98ddb938549cc7c4fe56cda7f3ef213f1aea49fed4fb81b940c7e894be1e54" - }, - { - "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", - "sha3_256_hash_of_public_key": "ec2fc5834e128c5e1460d8cb0c35ab340d706a6c8b52070a7e41a6405fada53f", - "sha3_256_hash_of_secret_key": "954a43f78ef0b5a279c0d020c08d930cc5e83a385c09afed508f9ef6f1a27920", - "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", - "sha3_256_hash_of_ciphertext": "f137abde6208e2c014a5a7eb1aac7b910a21df3a7dff68dcc40cba4f34b839d1", - "shared_secret": "e0d0d574b1287716bd7e0a44feea36ec28469bd36713fa8a53b0a104f322016f" - }, - { - "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", - "sha3_256_hash_of_public_key": "5e7f49b87bb2319dba8d3485fe814aedb0b43173bc48f3a793554c3e8bf90c17", - "sha3_256_hash_of_secret_key": "74eb7c05fedc78406453b8f021f8a71cce4b3ad0c4d38bc8d581000a38908574", - "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", - "sha3_256_hash_of_ciphertext": "2018b7eddcf255f6a171af914ef44153fd60976c5c7368998a218b1d81e34e33", - "shared_secret": "bd97eac1e35a06536e713a2ca5e71e35277b948172cafef0c35e1558efb61676" - }, - { - "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", - "sha3_256_hash_of_public_key": "e3f73c56254fac37209f5a59818fbaabf5abff3320b0b3ee00e20679b5728c12", - "sha3_256_hash_of_secret_key": "1e1cff1c4e09318bdc174bff8ef0817d6e7414355adf930bb35e71a7a0b95abf", - "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", - "sha3_256_hash_of_ciphertext": "d641fde487a3659350dc41f329e0d41741bd4389346da9270eda4f5829ce9ee3", - "shared_secret": "2ed540764a77b17c6b9608bf86d8d8703f80718044d52dc79cbc1838f91fdd7a" - }, - { - "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", - "sha3_256_hash_of_public_key": "bc0a40ba03d27bbbfb91654fdcfab2dfb3e94d9607b99c1d7da1f2663bfa2598", - "sha3_256_hash_of_secret_key": "dd55c195b92ff410b9ea37577ddba0385bbf067b3053b0a678e8106c07b98c9e", - "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", - "sha3_256_hash_of_ciphertext": "7387b045cefcf3d2c659171ee41acf3857b9f63f1ba20c3f0832cfe41a26ef75", - "shared_secret": "1e5ba1b64fa8ad0494c96ba27e288ee2b479c24634285f8919e58e9b9c8be78b" - }, - { - "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", - "sha3_256_hash_of_public_key": "e16da7f99bb7bceb75a6468a921ab9fe53aab2972ca616ee10697c204df1e350", - "sha3_256_hash_of_secret_key": "2db70f5bb4e8927fd7696a4d802817fa58c43f9b2618ed27c7584cce8acf3506", - "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", - "sha3_256_hash_of_ciphertext": "0159f5e60336eec1fda83aeffbee92eddfcac6f92b0fef7a4a38fb20d1a771ca", - "shared_secret": "96ba12c7f8a0d864ce1434b789c09753c2d1f7ade6a5a0e679ce2ea0b6d66c83" - }, - { - "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", - "sha3_256_hash_of_public_key": "fb80edf4f67823ff4e53a8963a9c9937fa9f8e014b750e11b4c4bb1a361d6484", - "sha3_256_hash_of_secret_key": "fe67beff69ea75d4953d71c038559591b2a0349ddcdfeaf7596dcd02f57db2b9", - "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", - "sha3_256_hash_of_ciphertext": "6e68fe27fe416c12819fa8a48eb29351d1d74a9200c408b55294ea374046c3d3", - "shared_secret": "07dfc04ebbb7ae537b594210a9180f647d3d385d1c1bb56abb8174111eb246df" - }, - { - "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", - "sha3_256_hash_of_public_key": "d9f630c3838eb161374710d9f01bc70d4ef928fcb1c38bed93e30f3633a05e01", - "sha3_256_hash_of_secret_key": "ca4a4ab954c3a4c8b960fdfb7dd7cf5e8d103f7936f31e720e5043010926829f", - "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", - "sha3_256_hash_of_ciphertext": "3b6a1f5d06cd55c98ce6f4dc5b17fce8cb05b33b1d89b618a027e4478d8b5e69", - "shared_secret": "81fdb9267988ad39ab57e2fc8d4c280e0000dac3471b0936083aec68b49fd92b" - }, - { - "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", - "sha3_256_hash_of_public_key": "5c27fa929adc826f98fbf0a7fdce33c8f215b34e70450da0767240741894ffa4", - "sha3_256_hash_of_secret_key": "0116eb35f3138aa7371a058661a92a4bde258f823747b70ad40767c27d7bc7f4", - "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", - "sha3_256_hash_of_ciphertext": "83f17a1e23402e14a58a32343e1083434eb10b90a8080d01ba112b83ba15f7f4", - "shared_secret": "703958ce09d7d6a5bb09e88de8df95c8ee2598544d50193be50534947530fa37" - }, - { - "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", - "sha3_256_hash_of_public_key": "dd8aa653122eb5e3a4c3c877e95e8ecfcfef1ac9e0e6af92cce8ee89d09188fa", - "sha3_256_hash_of_secret_key": "8a5fbb715cf44c86b736227e56b53d91ebbea432fb1f1d6d7cafe42da8457b2c", - "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", - "sha3_256_hash_of_ciphertext": "862f660f11fb4252070e948ea2c141202246d5117ec151e6d5fcd0783bd76bb9", - "shared_secret": "c86d221cbc5ff6a994d9111acbfff23f7dc0cd934412b17d89f0f27e3cbd1a15" - }, - { - "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", - "sha3_256_hash_of_public_key": "b7c80e434104e9838cb08529592a5f81b0e8ead186663db8facc569b09e75c9a", - "sha3_256_hash_of_secret_key": "c5f84c36f3b8af4b4d90a040d929b116b402840f487d437f9b330f6ff3ec36fc", - "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", - "sha3_256_hash_of_ciphertext": "a372aefe804077da915a423dad55b76ff08a58d222aa66305599ff301128ae13", - "shared_secret": "c0146ba47b3d4178919879721f69ac896d6911d6e86de1e8f05797d467053222" - }, - { - "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", - "sha3_256_hash_of_public_key": "e619285c692532735f1582d227b9a9e77b1eae4aab9eaa79f6ce7ac2fcac8318", - "sha3_256_hash_of_secret_key": "2d4ae4f98c61bd104fbc1ef512b946202f95ecaa0ad7353a686141be5fe18116", - "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", - "sha3_256_hash_of_ciphertext": "462b78ef50b2c1ce761fa7750ab5ed2a7315e474a92ddae74bd23013b0d9ad0a", - "shared_secret": "a33f72941e0947735925e5be668b3481e0cece75ef48ae6db0d66f0fb2ec428e" - }, - { - "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", - "sha3_256_hash_of_public_key": "dd3761c0e96678a959f30997e96d6a59858528c5e10234398e2da2e50ffcc517", - "sha3_256_hash_of_secret_key": "c6f5f9285f93d2ee6d180353799df5fea713870ca06de901e9c12e8a01ead6b6", - "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", - "sha3_256_hash_of_ciphertext": "2e552ce25fe0771bfa135939d85bd68ed07959709da470df50be36aa8ab2890d", - "shared_secret": "3d77b9b4ade74443fc573c393b82c0cfd2bc2769327f273c14e66eab9f8d9ebc" - }, - { - "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", - "sha3_256_hash_of_public_key": "6d9e513a7cd137583507ad7256844bcb9775ca82ef5f411331a7c37ce451181f", - "sha3_256_hash_of_secret_key": "1dd2623a7413ff14549690b642fe90ce16ebe7acea38be795a4936b8d86b93aa", - "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", - "sha3_256_hash_of_ciphertext": "b4c64b73ba056f9ee7c3587ba0825bcc7172a6da749cdd86c1ef60cf84515883", - "shared_secret": "812d6c4becfdd4a95f234e8fcae1d9b316266d1c519545bbb7fab8a19f3519e0" - }, - { - "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", - "sha3_256_hash_of_public_key": "b252e5abf757e116a92518eb72df9f9ce66b07edf4d31be225585a6a827a35b8", - "sha3_256_hash_of_secret_key": "45ac74f2a699f1e3559e2d1442638290029688cec3da96c58ea697e1ed1d4178", - "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", - "sha3_256_hash_of_ciphertext": "4dae8b2d08afb311ef727118966c6c17652f1464e6cdd26ac23551d31b013415", - "shared_secret": "c8757f45a1e334ad99a0d2adf12e79ef2bcb96ea1876bc29a4ec5cd660923d82" - }, - { - "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", - "sha3_256_hash_of_public_key": "18c081231277f424c5f3f1f6b4db91958611fa28bcf09ccb2573da64547e1958", - "sha3_256_hash_of_secret_key": "f32167b39e19dbc0db58a5eb79e735337ffe154c75b0f2c091e009d0cec366d2", - "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", - "sha3_256_hash_of_ciphertext": "3a246e10c7c20d77a9e4bd6d3a90d73ae456501dc989210c798293d0b449852c", - "shared_secret": "be765dc236062da9d3fef68c645b9a8a5494c351d37790c1e7cd1089d97971b3" - }, - { - "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", - "sha3_256_hash_of_public_key": "0ac7db13184d6ae6e21a14a63a2ab3d6d5d1ee7f4a6011413a0295b752fd2c28", - "sha3_256_hash_of_secret_key": "f69bacdf5992e64369aa4325b70af9f0e8a399cadafe48d854c288cc4eec627e", - "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", - "sha3_256_hash_of_ciphertext": "d4200c5ed5cb4e30e8e74a5c8c30eacd48014d326ae72f73618c5680f04999d8", - "shared_secret": "e72888e8dc5fe30f0a9c01e2e4599a7046147a81da280c393a48bee1b43bbb5b" - }, - { - "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", - "sha3_256_hash_of_public_key": "27ea5a76294070ab10a6edc502d82be3d240672e5fa61377e73e5e19d11f64a3", - "sha3_256_hash_of_secret_key": "33161a2b269ff022ff4699b05ac7fac1374d733e46800447164d3e528ff89dc4", - "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", - "sha3_256_hash_of_ciphertext": "8995a8a9b59bd5adbe1fa10cc20da5348737cce9088be7eb0ba1f6215d68b9a9", - "shared_secret": "e3f13c77fa9eb329c218e1bd5823d6e07249fa1b455770ae57b2a00aa8c69c5d" - }, - { - "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", - "sha3_256_hash_of_public_key": "9898462f05bea461adb40faacdfdde363c06f58bc756f0a8417df63a66d3a544", - "sha3_256_hash_of_secret_key": "e10192b72796b2da465303c0bbe16f1e23e08f9680ba92fc22d568ac84352113", - "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", - "sha3_256_hash_of_ciphertext": "573aa757ef6fa5110ba7b948c325718f87c6bc9ccd596debff4e6c7dac1fa8f5", - "shared_secret": "a8498502e012b5cd006e77fcbb9fab801dc3748a0da37587dcd41310fa945e09" - }, - { - "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", - "sha3_256_hash_of_public_key": "a24e6203d9b1aa5cd06c44f048da7225e33952617f12b4289494b3969857c2ff", - "sha3_256_hash_of_secret_key": "61f1e3b3a9ce59d25480d88dac106cebc81272c0c9449c9b22048f67419d940a", - "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", - "sha3_256_hash_of_ciphertext": "7f92312ab16635c5e90a6d41ac65e594e37754359331b0814e09da9c7eb945e7", - "shared_secret": "780b2d0ea585a6ea41dcf43197b9ca4648454e30a3057f0d47f6e79a2bbc365e" - }, - { - "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", - "sha3_256_hash_of_public_key": "cb2e9159ab5225a75d02268af2dac89a0afb33fe83a45f552e2bf542868c0683", - "sha3_256_hash_of_secret_key": "d2ce7cdfbe3ac715b2c87b1231fe46d5385a77caab367570a955bb562d23183c", - "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", - "sha3_256_hash_of_ciphertext": "1113b9a38ec4629ad20ecb594b64ba242a5a4db7bdf32914f9eb34ecc76c4a1c", - "shared_secret": "7832b351d71984cb60e6e548e5b4edeedf9749f8b3bc96fd208b6bb557251de8" - }, - { - "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", - "sha3_256_hash_of_public_key": "7f8d36076b3a8aa13b633650726f7e907806a0573402ef3af129f611def1a813", - "sha3_256_hash_of_secret_key": "0b38e04daf35259696487ffaad947f481756bc3e94dd1a73b81bf8a6da4a43c3", - "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", - "sha3_256_hash_of_ciphertext": "eefa4d255cbd39fb5686d14a6a574d4c75c6b138a45a09cec12287c281cc00e8", - "shared_secret": "468ee020867cb766cd0a9ce1bfe9e7dbb56ae66c131a4540f211837c1779e11f" - }, - { - "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", - "sha3_256_hash_of_public_key": "ff2044ee6a3bfd4f7033dc4bbd6283b534cd3fbbf1c4af072fea1ba37d3262d5", - "sha3_256_hash_of_secret_key": "ed62dbd78c007d385c786f2607715a69a44804c4e88111861d175875bc0b09ee", - "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", - "sha3_256_hash_of_ciphertext": "d16b23897beae9fb1a6ca746d3c15ef52c8ac454cd518d5a90a561cb588a0260", - "shared_secret": "f04a17a3737285f2257a6374a0057776ea24bd731724851d12ac2e06e959fa26" - }, - { - "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", - "sha3_256_hash_of_public_key": "c7ca6ebbe17f30f8ce49e15c40c1ea5456f43624148eaecc9f3018f7beb96bdf", - "sha3_256_hash_of_secret_key": "7886dadfd208ab926afd2376dc11a004d8b793d7a30623df27109f9a4d4b0916", - "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", - "sha3_256_hash_of_ciphertext": "4fdbbb522c23abd8a69c583c2c68ddc28fa4da85a6bf208a22d19e7ef40d98b3", - "shared_secret": "fcfab6cb3daf0c64b4ce007499f097f6421e00905fd4daca7da7a29b9c8f6325" - }, - { - "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", - "sha3_256_hash_of_public_key": "61fb6cfc0f388e34fb28ed783c2733453005eea03d3fee4b01bb6364abc01c30", - "sha3_256_hash_of_secret_key": "b724f25cf64bdaab1cd29c9cd1f8ee6cf4104c26fa3caf53b77d61cb5c35222e", - "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", - "sha3_256_hash_of_ciphertext": "5ce7558ab39d932fd35fc346aaea5aff4bc90e65c17b5760996e84687dcb5402", - "shared_secret": "dbf4cd1f5cddf15322449ddfe147ae0605d0315ff9da6421069b47c3a67a65c4" - }, - { - "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", - "sha3_256_hash_of_public_key": "9333445958cf50f9cfba453f058f562158bc253e535e4e2f07715531a1c6289e", - "sha3_256_hash_of_secret_key": "9bb80f6928e0d09847b4c7e77ba6bf2cd0f75bdd147e884b92d3c3f2e9d839d6", - "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", - "sha3_256_hash_of_ciphertext": "57651b24ece777c321c6e59ba774951e2a3c4720d370e3af928238ff60c9565d", - "shared_secret": "3f4848a2de1cdd8a0403da22f609809a20c2cfc0ae619be0cac350897fead710" - }, - { - "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", - "sha3_256_hash_of_public_key": "ee6cb12a54341aeedc99f1040b01603c35f07c5487ffac7b4fc1925f49026916", - "sha3_256_hash_of_secret_key": "4e498a0606b1f9cd72b9d2493428730712bdaa4a7fed8099b15d9e2873bbdf7e", - "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", - "sha3_256_hash_of_ciphertext": "1fb55bc4e6d95931087b23945ce9448207fbbc14bd284f6bcda65fcf31d68fdc", - "shared_secret": "eed5b71764da1763a01184a1eb51dedb4eaa9dae7890b1c7dbc7e7132c30e737" - }, - { - "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", - "sha3_256_hash_of_public_key": "42ad42d6d3b13c72b16287909bc4c0da04900536a1e48a1a28db4f5ee2d2e771", - "sha3_256_hash_of_secret_key": "d6f909b6679487a8718c843c4b894785ee046c4d86ad2794c22ee912113dad1f", - "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", - "sha3_256_hash_of_ciphertext": "54043d4b2be7ecb264847dd0bcde9076523e798aeee942be82d61d51ef0253c1", - "shared_secret": "4218fc9abb402e67ac946c7a7c6f9029108f67de469e1a9987d570f011b685c3" - }, - { - "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", - "sha3_256_hash_of_public_key": "5b70c5bb1b7af3b643588aa7c20567d4259dbe6abd7617a61b48185de8f21e1c", - "sha3_256_hash_of_secret_key": "f03297b8577b131e39946a288f7ca9070e70c1e00e6ff126543556f60dbafead", - "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", - "sha3_256_hash_of_ciphertext": "c3d51c14b28feb48ee67945a2f9e2ababb8682a839ca1148ddc99f909e8c0bc1", - "shared_secret": "95a33968866dadc1fd8748768a99f6bb444e3d76a65ec5fee0c8a833978d4585" - }, - { - "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", - "sha3_256_hash_of_public_key": "01782fce09e644e310c9286f1e381be9ea8c54a1804e61f2958c1f975aec185a", - "sha3_256_hash_of_secret_key": "3d1b220e747de4ca99a9882a00860ed00abcf2e6eea60cba5194977f97c87770", - "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", - "sha3_256_hash_of_ciphertext": "8dbc778809c9cb1de5301be5bce766f1acd7d8f74ecf30619c398250def57d74", - "shared_secret": "c9423277519ab439fca3f5fab4c29c8123a55eaf37d94d70e27afffeec1b3b9b" - } -] \ No newline at end of file diff --git a/kyber-crate-tests/kyber_kats/nistkats_768.json b/kyber-crate-tests/kyber_kats/nistkats_768.json deleted file mode 100644 index 7b668915c..000000000 --- a/kyber-crate-tests/kyber_kats/nistkats_768.json +++ /dev/null @@ -1,802 +0,0 @@ -[ - { - "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", - "sha3_256_hash_of_public_key": "d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee86", - "sha3_256_hash_of_secret_key": "245bc1d8cdd4893e4c471e8fccfa7019df0fd10f2d5375f36b4af5f4222aca6a", - "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", - "sha3_256_hash_of_ciphertext": "bb62281b4aacc5a90a5ccdc5cd3dbe3867c502e8e6ec963ab329a9da0a20a75a", - "shared_secret": "729fa06ac93c5efdfbf1272a96cef167a393947ab7dc2d11ed7de8ac3c947fa8" - }, - { - "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", - "sha3_256_hash_of_public_key": "2cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c", - "sha3_256_hash_of_secret_key": "0a84cc895da138b944accbef3ff1a0004b8a0d8af5d426d2b82ea4c0e585cc6a", - "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", - "sha3_256_hash_of_ciphertext": "c15158a536d89bf3bafaea44cd442827a82f6eb772849015f3fec68a29d589dc", - "shared_secret": "c00e4ede0a4fa212980e6736686bf73585a0adf8d38fec212c860a0d3d055d1c" - }, - { - "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", - "sha3_256_hash_of_public_key": "3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8", - "sha3_256_hash_of_secret_key": "0ffced333b5d13fff22b81e66d57b6e2a6dba0285fe2a82d5537df51a8d3eac3", - "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", - "sha3_256_hash_of_ciphertext": "aec80e6fe21e2616352b4c148f9fa0e30986541fb0969df7873b1336b23a8de0", - "shared_secret": "8f50401bc9b1f857fd870902d4065f6cec8cb825db3eb22573c6167442b6e19b" - }, - { - "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", - "sha3_256_hash_of_public_key": "94391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4c", - "sha3_256_hash_of_secret_key": "e3904266e186b34a397014c95f6d314cd6e1c813348b02e977d0fd21d9bb681b", - "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", - "sha3_256_hash_of_ciphertext": "39fa8e1d0a5e4bb987618734ee4903771886030b2d8bea4b5a9b0cb672ebb279", - "shared_secret": "3221d7b046caccbded38e369625f69bac60c2d7efacad8f24170b10c5d222830" - }, - { - "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", - "sha3_256_hash_of_public_key": "c5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082", - "sha3_256_hash_of_secret_key": "b3fa7958f4b7ccb68712ae948c3f08740c8b89a69e53ad4e9959234e6869d8fe", - "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", - "sha3_256_hash_of_ciphertext": "ca9f95c38dc95f51b6b62ec709539f0d1e9fa64e49ce4ad10bbe62868f35cfc5", - "shared_secret": "1d746afc4160c75aaa6c6967f4eee941e09546a039027f05f0f8a483710ac334" - }, - { - "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", - "sha3_256_hash_of_public_key": "62e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1", - "sha3_256_hash_of_secret_key": "1a3249c268754c86d2e02ba9d87c2b60b220bf2406b71037cfaf6b089477ffb4", - "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", - "sha3_256_hash_of_ciphertext": "ec7bb1327a69aeaf626a76d344be1156eac160262128a64477a194805b926233", - "shared_secret": "722fccef7142c46f74eb57a10b13e420d6554e9d18507f660bd1be96d3cebbcc" - }, - { - "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", - "sha3_256_hash_of_public_key": "0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c2", - "sha3_256_hash_of_secret_key": "fd6b5d3f120ca009871ca24552a6118917ea882f12f30dc8097f6614d9d36080", - "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", - "sha3_256_hash_of_ciphertext": "da36cb6137a777acb4afbc0932811f75ef1d6732031309ae7e2de1543aaf5c2c", - "shared_secret": "ee7c5fb6a63ace944e1eae1bd4b182263d918754c33753b904853551b2b46cb8" - }, - { - "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", - "sha3_256_hash_of_public_key": "2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe", - "sha3_256_hash_of_secret_key": "27dbbc7918c31e9ab57808f439c4f4189cc318a62422457f4fed733be959c816", - "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", - "sha3_256_hash_of_ciphertext": "85efbfd0b096fa921711ea66b17bcf7c9a6240711b38a88830dbd9d716f07195", - "shared_secret": "77cfbdae47854e9e10765cf397eca9ab2bf2b7522817152b22e18b6e09795016" - }, - { - "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", - "sha3_256_hash_of_public_key": "53b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757", - "sha3_256_hash_of_secret_key": "f4b964b7ab3e09fdf3d91527da06a4d29ef28344709a41739ef56f18bd5b984b", - "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", - "sha3_256_hash_of_ciphertext": "379a57a8f19110d5e0d747a2c184877d71f00fea95cd815b4c0e8782b12bec6f", - "shared_secret": "8be7a417efbdd3587c6f82ddd1d29956789d28c2413b8383590c5b80cc53e04a" - }, - { - "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", - "sha3_256_hash_of_public_key": "9cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb63", - "sha3_256_hash_of_secret_key": "a2e37a55c9b80fb423f40585180b011f32402d0320259285b6e278df6c20ba60", - "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", - "sha3_256_hash_of_ciphertext": "44053f01ecb88811b9ee7a9ddd4234f94507c7cf64b6803b28c54bc605ec4e31", - "shared_secret": "79fcd201101e7e277c1b6cdc4475d63ea1dbc42ab94cf873bf0163c2aab0b5ff" - }, - { - "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", - "sha3_256_hash_of_public_key": "9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f", - "sha3_256_hash_of_secret_key": "837eb6ce037f235273d7686fd9d01bea14026e0a0f5f943884f18409cc4bc70a", - "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", - "sha3_256_hash_of_ciphertext": "02798b5af1a76a2b478ee05c630e62618e5e2d7ee0c411a82ed2bf888706fe28", - "shared_secret": "6c4484b6d7b0a376f52abb1811c712368a9f34bd108ffe7ca31c36a6ec8140f3" - }, - { - "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", - "sha3_256_hash_of_public_key": "241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401", - "sha3_256_hash_of_secret_key": "95c79c2a867b3e8a4e4e545ff626cd49893b8e87eb188ed1516b159a24736c97", - "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", - "sha3_256_hash_of_ciphertext": "cf3b2e2dc822949eb13638299fc2d5102c7132aa6cd54dd7834b13f05a4dece2", - "shared_secret": "8554d6af350f13471cfd45c23882e43dc81d8a094f6299e2ad33ef4c01a32058" - }, - { - "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", - "sha3_256_hash_of_public_key": "6ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e4685", - "sha3_256_hash_of_secret_key": "1ef733faa4f2cb53cb5d8975aa6797b5f37fd918aeda02178a40584475cdf667", - "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", - "sha3_256_hash_of_ciphertext": "1706e6983032950b47cb6c8586178b42d515ce929c1434c1a8c9e36d8b4db7a3", - "shared_secret": "f9646f73de3d93d8e5dc5beeaa65a30d8f3a1f8d6392190ee66ff28693fbadfa" - }, - { - "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", - "sha3_256_hash_of_public_key": "9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a58", - "sha3_256_hash_of_secret_key": "0bcfa8078582f60e218047d0016437601da8431f34ae6da12921f53958f32819", - "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", - "sha3_256_hash_of_ciphertext": "f9341d26e39b38a88ddef1708c96ee2068f569a59a4010745730d8290d637718", - "shared_secret": "1ee252e97b69445f7f109187645cd2879f55e10eb8361ab43b3492ff51f01815" - }, - { - "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", - "sha3_256_hash_of_public_key": "cfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75a", - "sha3_256_hash_of_secret_key": "09b118f7c4d059baf27284d127d4e85d55b84e4c92bf3127eeb318d2f5765401", - "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", - "sha3_256_hash_of_ciphertext": "94a8c287238191a107e74e31ec099086d83f198e6b0f3321da4d8f46ce01a0b2", - "shared_secret": "1e1ea5d6a18873c5c7fc8da79093f6d3db5b28fdd0aaa42726ad130c78e9bb88" - }, - { - "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", - "sha3_256_hash_of_public_key": "a19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2ae", - "sha3_256_hash_of_secret_key": "f1c00070780a7a2ac5b57ff3ff765ca75278bb661d1635cac92792f9454fe8ba", - "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", - "sha3_256_hash_of_ciphertext": "56e0b8ab3b302fae682938a45d9931e092d78877d1f8834bb43cd5c85582a205", - "shared_secret": "24619bb17c912fc992bd8272969cd5b6fd6b030122ee5af9365cac8b38e569fc" - }, - { - "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", - "sha3_256_hash_of_public_key": "e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872", - "sha3_256_hash_of_secret_key": "f3f3a292f5cf01d6f7266461c9e8cd44bfc8f17e16035ab8d10af8177f389b86", - "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", - "sha3_256_hash_of_ciphertext": "5f878ca21c8c27ae9c41c43aaf1f3a2af62c73296e165c08b88c5b22592867be", - "shared_secret": "a990af801ddcf2009c82fe657fe3f068bae7e6bfc661e3e588354ba7d1b176e6" - }, - { - "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", - "sha3_256_hash_of_public_key": "2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f4", - "sha3_256_hash_of_secret_key": "7334d4a1755e1e639b3e9eadb5996cd910b55d1de5790469f229231d3bfb1528", - "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", - "sha3_256_hash_of_ciphertext": "c2079637916c089b2afb9d6e9c6fa51308ab7720d5c2fca484c34ce614a14fc0", - "shared_secret": "11a2ceaa0c77f0602c4b2be3499e6df6b0339d9de90d04b2b12829f4758afaa5" - }, - { - "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", - "sha3_256_hash_of_public_key": "631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f", - "sha3_256_hash_of_secret_key": "3d4d2c680a1e6aa83861ad95043ded260e720ae80060320feffa309b4281ba3d", - "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", - "sha3_256_hash_of_ciphertext": "2e9d6551050e32e204d7c062a4c18b8abdb91346e9f2c2708776827e0be4c514", - "shared_secret": "7571990ef1ef7e15cc920318fb75fd38c4ceb9abf7a4b1adc2175f99d1a0a275" - }, - { - "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", - "sha3_256_hash_of_public_key": "87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce", - "sha3_256_hash_of_secret_key": "9aa6c0546cf02085e2b3af65a7d7fd32d0f6d8080e1e7fbff6c39bcf3086ece4", - "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", - "sha3_256_hash_of_ciphertext": "14da42e207477f4383faf4004e58675f0380e7d621421b3c36b877acf3a45d5a", - "shared_secret": "27ba4cb50ae44cd938585e0a4905d76053dd851e5b6af4fd787446079aa5a4ab" - }, - { - "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", - "sha3_256_hash_of_public_key": "699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f619", - "sha3_256_hash_of_secret_key": "421f16805b1ceffcd64128b1296521ef812d3a8f4c5e3875a049f8de456b021a", - "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", - "sha3_256_hash_of_ciphertext": "b2485ef56c39d468193e387e72794e0ddc9b5404c1a6d90c3b94a5f3e13ba7b4", - "shared_secret": "d17b2738213a98f29ee46747c93308ee7000fa404b9a0c1acf3f89654ca2446e" - }, - { - "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", - "sha3_256_hash_of_public_key": "d3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7", - "sha3_256_hash_of_secret_key": "7b546a42ffe6b65cd9c5b8857c2518f4f8e0bf835c894a68d1743691fc9aad9d", - "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", - "sha3_256_hash_of_ciphertext": "8290f3c4bec7c3b93f3d26e0be3b3fbfdd9c3f5806188fcf0fa1339133f29c7d", - "shared_secret": "954af53b4add522514b34cd2ab96669a76ca13f82aa2fd70826bc8ee790ccefb" - }, - { - "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", - "sha3_256_hash_of_public_key": "e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a", - "sha3_256_hash_of_secret_key": "5fac243c82807d7357a61023226a7c270525d96932162ca5c09fc8f7b9ec6cb3", - "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", - "sha3_256_hash_of_ciphertext": "f1b10c800a42ae606c72eaad76accf059cccc02299fbd78a5d091f183f6c3f0e", - "shared_secret": "d0bbc576fb1aa43b6e76db0e87bc4ee3fa057c31642b37f3339217a1b041b521" - }, - { - "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", - "sha3_256_hash_of_public_key": "c74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fa", - "sha3_256_hash_of_secret_key": "5c6998a20960109a4c9808f8f8575697b2b8d18c44c7e9dff97585ae43e6004c", - "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", - "sha3_256_hash_of_ciphertext": "e9ef0852ee47744b8c3e12cd728d9017465014eef51edf83a4502cb5218cee20", - "shared_secret": "91fbc37d4749ec6175c12f0d8eb6b6a8621e693c79f85f5cd2f557cafec5e7e9" - }, - { - "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", - "sha3_256_hash_of_public_key": "7378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0", - "sha3_256_hash_of_secret_key": "30bd5f16c3f242248a4c4cddc43508bf54535958657bda4dcf105216ddf47eb0", - "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", - "sha3_256_hash_of_ciphertext": "37843616c8a4f7ea9480740b6624f41650da2bb1664cf228d85d6d71a0624528", - "shared_secret": "d586b441b8eaf7d053cc96b6835f093426677a7c3acc51aaa3ddbb66dd14a623" - }, - { - "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", - "sha3_256_hash_of_public_key": "16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189", - "sha3_256_hash_of_secret_key": "873c94f8bee9fe37265d5dc0c5d3bc1c706057c7efb3cd2cd5ca9ba45498d0d1", - "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", - "sha3_256_hash_of_ciphertext": "cc677a81c73ea5139eed8d85782978d06192715933bc5aef560e737f6d57d0a7", - "shared_secret": "409bfd9102bd4632c6b5d3610eb349fe3e3bc51e73acc78a8e994a070e20e10c" - }, - { - "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", - "sha3_256_hash_of_public_key": "633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f4", - "sha3_256_hash_of_secret_key": "3c3cff5f49a802cec693efbfc264f6a385210b1eed20f7bc5b07b51839961d14", - "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", - "sha3_256_hash_of_ciphertext": "6d94a31cff4761e3993308cb3e812a4a7f04f64d02ed3b46b418c2fc16189dfa", - "shared_secret": "5dd151a8015c0b16d79822832ff4cc0da7fd38eb73b7da59bc519d4d2374b808" - }, - { - "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", - "sha3_256_hash_of_public_key": "3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d8303", - "sha3_256_hash_of_secret_key": "1503bc141825d523c9505d34f50dc0a01d7bc91cdaee6b99f4a85a24ce800496", - "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", - "sha3_256_hash_of_ciphertext": "a63613ccfd2ecf8aa3adf0103ddd9eeedbde3282443bcf02513b4ab87360cabb", - "shared_secret": "1c729b8e580e124e715f19ea6f2409fc6de741afa3d9919b2b8bf3e54c053b51" - }, - { - "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", - "sha3_256_hash_of_public_key": "d1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af", - "sha3_256_hash_of_secret_key": "a21acea0fd4354eb0c78d47caaf93c9f2434f1cf2d6b2194871ccd98f9522ced", - "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", - "sha3_256_hash_of_ciphertext": "3b322134b37fe8f5d7268fb74d1634ab8b35d456a973f7b0b427fb40a93b6db2", - "shared_secret": "b95ac8b73c703ab1154152b3ac73f054596ed23d3be328fbe20f936ea95fa926" - }, - { - "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", - "sha3_256_hash_of_public_key": "1b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c509", - "sha3_256_hash_of_secret_key": "3e214f25fbf4d1bb670a87367399e1b2a9da3491cac5a22a2c18dcc44f3f1bae", - "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", - "sha3_256_hash_of_ciphertext": "a2cd589c24c4c75bc0a3864dc84a85a7f0f3ac11c8578757f8e94054a7c186aa", - "shared_secret": "8c3851393e5c5997cc95f06da96300f6dd85c041343c98db2e742aaa5f78b298" - }, - { - "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", - "sha3_256_hash_of_public_key": "2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68", - "sha3_256_hash_of_secret_key": "c6bc9c9e797a02684d3ad8de47919b8d8fdbee09258d084c7a9dc963c80401ac", - "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", - "sha3_256_hash_of_ciphertext": "0cd687f1c3e0d67c46cebf93c1217ddc972ad8662dd05830db350e1292542c1c", - "shared_secret": "4b681fff6a755e1dda908d070f0d9ac610d85c73079c1022fc67d255e36f1f71" - }, - { - "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", - "sha3_256_hash_of_public_key": "bdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a7", - "sha3_256_hash_of_secret_key": "c96e176b19f4135add434d0dd219024587d49fdb649bf470e84d9518bbfa2879", - "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", - "sha3_256_hash_of_ciphertext": "b38711e358893a864b475f35328b2450fffd5087d631844f7ab0995de2b8310d", - "shared_secret": "bbaa67f1dad879f2fb33bd4ead45aec354bc8f05c7cbea1e433509faac022edf" - }, - { - "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", - "sha3_256_hash_of_public_key": "61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f", - "sha3_256_hash_of_secret_key": "8baa58b1d3fab8ec5cee8841c9012506cad40bf58a677adac88f1a6400506d40", - "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", - "sha3_256_hash_of_ciphertext": "7d47a21d95483a5845a4fddbb07b3435c29a56b5cf26f5d0abfa21bc39a2f2e6", - "shared_secret": "2c7b983d66978be80250c12bf723eb0300a744e80ad075c903fce95fae9e41a2" - }, - { - "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", - "sha3_256_hash_of_public_key": "672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec330", - "sha3_256_hash_of_secret_key": "4c72f0a7ef5c3274c49365cca5e6770bc709ef12bdbd4fd7c2eb5faa296cdfe8", - "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", - "sha3_256_hash_of_ciphertext": "167b4e8b7517cad82ae0f49795918c4d33c79137a9c3e16000c4c55b30b1d382", - "shared_secret": "bbc58d06cc14f9e96a10acb1789d93b93933f1429cc53a1735b3cd995f086ce7" - }, - { - "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", - "sha3_256_hash_of_public_key": "b86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b", - "sha3_256_hash_of_secret_key": "c25f2e16a0e6fbf0729e5ee89fbbdd71f00ff9a1abbb00cb47f26e9989eaf678", - "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", - "sha3_256_hash_of_ciphertext": "8919940aeb732930c496fa9832b0c09382663accda45be1ee22930c545eb3a37", - "shared_secret": "e045e0391e15a66d6208467078f2ba5e429cc586c410ca6c5f3c032c21761955" - }, - { - "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", - "sha3_256_hash_of_public_key": "85441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be624", - "sha3_256_hash_of_secret_key": "93b65d2df33d3e3ab0d53c1d0a21f3752e2c5962f7d960b888b2a8c495b1b133", - "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", - "sha3_256_hash_of_ciphertext": "422509b01b8fff9468e867a2b5ebe5d3e27314de5c058b2c79a61ccf464f4df7", - "shared_secret": "0b8584b75838e084839d58c89cb1749e82ec06a0e85464c7546dd96870547d29" - }, - { - "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", - "sha3_256_hash_of_public_key": "065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e2", - "sha3_256_hash_of_secret_key": "0121afcc6aeb8be9f1c5b06d5b65cc1c03e9366ed7b85fc511d853c5eee230cc", - "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", - "sha3_256_hash_of_ciphertext": "f1d3b745d86f860e508ad8b6d5c8a72ef833c280ec11e99516f4ead3c42509be", - "shared_secret": "3547a15b5748990a5436bdc4db283738eb7d64bdb6ff566c96f7edec607ccc9b" - }, - { - "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", - "sha3_256_hash_of_public_key": "ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd129", - "sha3_256_hash_of_secret_key": "16e06287bd8d71c78f1657bbd6d5d12c22f6bad7658e68dd849d7751da950860", - "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", - "sha3_256_hash_of_ciphertext": "fdfd351fbb15c92843b44489fee162d40ce2eea4856059731490afda1268b985", - "shared_secret": "852ba9be42763c5a74a75778eb839a3738a8ceed1520b0588f9dccdd91907228" - }, - { - "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", - "sha3_256_hash_of_public_key": "2fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c72", - "sha3_256_hash_of_secret_key": "ffdb52b23a9ca4b71ec882031ebcb33a0ecc6731c13c817b24f3a06e48273778", - "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", - "sha3_256_hash_of_ciphertext": "215d83f872221c5fd4ee4da557e17299dc102c52dba1fc4bc3f8c16805da7f1e", - "shared_secret": "618a8496b8850609c09dd1d18798ee2bfff3ed7ef6f8b8034fffcec98f291d69" - }, - { - "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", - "sha3_256_hash_of_public_key": "86bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e", - "sha3_256_hash_of_secret_key": "5d46659798d268f1314ad1e7c1735c480301f5877773403966e928bc3fd33d1b", - "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", - "sha3_256_hash_of_ciphertext": "5ff5d6bdb110bac57e58a4e288d056a1384f9823606a42daef2ae82e0b7574b2", - "shared_secret": "cbb8b7a05f48b47d163cf8c2fad32bc586f47f2c2e0911da349f29b1e3286c22" - }, - { - "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", - "sha3_256_hash_of_public_key": "29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c", - "sha3_256_hash_of_secret_key": "aadce411f3708e9727e4a7e4e198781e1ef5e8f4c4c14add1e25f5758649e265", - "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", - "sha3_256_hash_of_ciphertext": "675039d66fcb631a050a8b24415b50f331350bd6697f9c977eef15c15d4cacca", - "shared_secret": "1eef87404f318351413d52ba8a07cfa5e72f235d6f91afd7fb8ad3e683ce0a55" - }, - { - "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", - "sha3_256_hash_of_public_key": "286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611d", - "sha3_256_hash_of_secret_key": "a6b53edf9efd7fa67a478456a5b6a379876c248f623ea45f4b541a8db00c524e", - "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", - "sha3_256_hash_of_ciphertext": "f03d44bd9bdf3bfd486919fec2177b8b685a9981de4cbc2a9e98b7e9b0a528fd", - "shared_secret": "ca2c0bba56645e4fce4b7e38a7bb4b839e754bf2834a302a2614377eddd6ae60" - }, - { - "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", - "sha3_256_hash_of_public_key": "029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585e", - "sha3_256_hash_of_secret_key": "413ae41ee83e17b74ac654c2aca57abe8f8ed0409acf7cc8b301e3d6bb049cfe", - "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", - "sha3_256_hash_of_ciphertext": "e8992f7b7b619c03cb9f0c991e3a9c20f91beb707c177ad4e02a5808d10d8769", - "shared_secret": "9155619e28de6cc0670ce70e0ad270f0e885e5f5f8d6d38426938ae1036d6ffa" - }, - { - "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", - "sha3_256_hash_of_public_key": "e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d", - "sha3_256_hash_of_secret_key": "93bf696bf0671c3845c4b246f29701a0978eec5b49de81589009e235903061e0", - "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", - "sha3_256_hash_of_ciphertext": "6634bd840d2dbb01463cfe5b4e3e54d1eabc081cfbdc14d0bc118911ed8d3cce", - "shared_secret": "d1f24383d5b8d0c3c0a6a5f8f7d38ccce13ec179a84b0b09bcda4c9988f3eb4e" - }, - { - "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", - "sha3_256_hash_of_public_key": "79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52", - "sha3_256_hash_of_secret_key": "65deb55fea451375ef335e7faac73917d32220fc70c95f371fdb16e712beeb26", - "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", - "sha3_256_hash_of_ciphertext": "ba79883ad64a6f2b256004233d87809a8c390327a23c739334f773507e003aa7", - "shared_secret": "d2dab0b39b7f62de3ca9826f9dd15a4201191a0e0c690d3e52b305a9d3af2d0f" - }, - { - "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", - "sha3_256_hash_of_public_key": "0c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3", - "sha3_256_hash_of_secret_key": "d37f172803739d074d71a2be32125eb1ba4250128342e34b882fcba38b259248", - "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", - "sha3_256_hash_of_ciphertext": "13d437b2fd9d67ca0699a3dacd977fba5d072fa6b482043d63e8a9548ba6a3fb", - "shared_secret": "6869ca370a496af2dbaa866265d91ba6be54b9686b1b8dd5714f6ba861b0d1e8" - }, - { - "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", - "sha3_256_hash_of_public_key": "5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d", - "sha3_256_hash_of_secret_key": "280e4774d1b2401580216fa70fb24c2c214ac5dc7f3841710a42e14d6aa09663", - "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", - "sha3_256_hash_of_ciphertext": "51eb70249a1abebd5159f1069b1acda2304f25fc9cbd9f4a625b58df448b47dc", - "shared_secret": "502d92b2a7e1804892ffb8ff009987a58f35baa30c0392c83859fde82105a9aa" - }, - { - "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", - "sha3_256_hash_of_public_key": "172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147f", - "sha3_256_hash_of_secret_key": "31136804b6c14f3a0a00a3295a5fed8d606369e64d272d432c59d7fe0ccc3e47", - "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", - "sha3_256_hash_of_ciphertext": "9b38b66fdfe80acab82bf9577676f6566b4429f78a14f7486b07c96ae7be921b", - "shared_secret": "48eb4b840c0d957f28808e434786c02a8f99d3464ccb3caf91cef4a0f8e70c4f" - }, - { - "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", - "sha3_256_hash_of_public_key": "268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2f", - "sha3_256_hash_of_secret_key": "3bf02cee24670ca40b7280d8047fa147b24c5e286dcae9c24bace9465bb19f61", - "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", - "sha3_256_hash_of_ciphertext": "fe8c3fcee4be152aff29e55f42f2fb1354ae55ccbe38400bc901ca032ede1ef6", - "shared_secret": "f9507f70421be90f21138a1e135329ee8228682cc948a6914ea58624d396df0b" - }, - { - "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", - "sha3_256_hash_of_public_key": "4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead", - "sha3_256_hash_of_secret_key": "5de91ca73756eee74da3cac78a1fb329a02f8587f212bb9bc0b29e0e654a5795", - "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", - "sha3_256_hash_of_ciphertext": "805ce0ab06c568b614cacbfa4cce5e65929e2846932a90e9418513dd48cf3358", - "shared_secret": "24caabaafe2063f812eaf57c58b6c0376ed8ff778cec1980ee9c3228801a75a5" - }, - { - "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", - "sha3_256_hash_of_public_key": "72be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb", - "sha3_256_hash_of_secret_key": "a68ca31b91491a129af9f280cb4c60c046e7a7ccddf41c9bd98663f8512ca34b", - "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", - "sha3_256_hash_of_ciphertext": "d27a36808f09d6165aefc5d253090027eeff0653268c55a0b3de2a751ec765be", - "shared_secret": "9f734b15fc7dd99bc10d6cc7de5d2c93ac789a5665e508a95d075dffbad25abb" - }, - { - "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", - "sha3_256_hash_of_public_key": "0831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67e", - "sha3_256_hash_of_secret_key": "2b983d7cb50880cff761441b6a2c66b7a41642cfd2a8cc297a5df53f0ed1947f", - "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", - "sha3_256_hash_of_ciphertext": "0892527da24957468b1b8fab49ad2d7dd6d238eca54624fce6a3c2dbbbe8d194", - "shared_secret": "d27e55f2a1f9ef336c8537f11da9875e03cc7dde8951d81b0740457609654107" - }, - { - "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", - "sha3_256_hash_of_public_key": "b30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68", - "sha3_256_hash_of_secret_key": "a49a7533c671e533deec55af218ee511c57014070e138c7059853e08c34b0a78", - "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", - "sha3_256_hash_of_ciphertext": "390b3b6f9a0f9d97ccd452c83bf47416b22fd06b4d8968c44ee6effa7980e68c", - "shared_secret": "ed5903d1cf02861444cad7fc3793b4e1b9b6d0324bf6babfb768bb2f84300086" - }, - { - "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", - "sha3_256_hash_of_public_key": "ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b49648", - "sha3_256_hash_of_secret_key": "9e865967f0d1e7d3f6a49f2bb623ced2a7b1408a945e02adbdca35846b70e7b9", - "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", - "sha3_256_hash_of_ciphertext": "6858db6eafd97259e6d775d881f7a877010179d4f827680426946b9ac4571261", - "shared_secret": "0d301028c1cb31dedc8a702a9e95b7d3589f68a6a1f600af84ae0f543e625361" - }, - { - "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", - "sha3_256_hash_of_public_key": "e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474", - "sha3_256_hash_of_secret_key": "91051a381626e9465fc7ab20a1944eca64be461330bda53e7d1838a74597392d", - "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", - "sha3_256_hash_of_ciphertext": "42bfb5584610497fbc8080a664139afa534b39a417cb69ab0d2a16c8737eb1cb", - "shared_secret": "354d86b389021a3196b75c6582927b3a005fbfee0951f34d9cd5c8f415fa50f9" - }, - { - "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", - "sha3_256_hash_of_public_key": "a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb", - "sha3_256_hash_of_secret_key": "cf7e797f8f7229a08206034737e54fe46645ab2fabdbfc8662b45a2604876b65", - "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", - "sha3_256_hash_of_ciphertext": "ce7b65856502b280e02a36d906e018c6a23cae99f27ef6d65762c87ddfedff56", - "shared_secret": "3afcfdc446f93a8169024a24fc0383692843cfd6b4854a8e490892fc35aad4cb" - }, - { - "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", - "sha3_256_hash_of_public_key": "aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce", - "sha3_256_hash_of_secret_key": "1e7f3f1e5632d1df538b564304f56689742d1f652d8d32f019b45183af68a20e", - "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", - "sha3_256_hash_of_ciphertext": "b6c40fd53bcd9ee1e70bc6783b402ae34c24dec724e63262d8583c90cd10256b", - "shared_secret": "ebba9a8bae936c829c1445c68595da96919041ee3d9b0fe27ca93db691146874" - }, - { - "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", - "sha3_256_hash_of_public_key": "cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5", - "sha3_256_hash_of_secret_key": "928592604aa44df8f2072f26e9511129f61da0b7f57acb3f6896635a9764ea87", - "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", - "sha3_256_hash_of_ciphertext": "a4b50ad169b436877652a6c64dbbffdd63f53274ddcf58f3c96c3929215aa956", - "shared_secret": "f063c0908deb2e61faa0c4c0f5051b2c8af7265060681df14bacb30f0228b3b3" - }, - { - "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", - "sha3_256_hash_of_public_key": "3a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a1523", - "sha3_256_hash_of_secret_key": "28ee987bc4ae5a321d2669950dbf87596fc4b35c29f192836005064aa3dadee1", - "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", - "sha3_256_hash_of_ciphertext": "126b64a28d82d06ca81f7e86d33f4949634924e04528d1142061320eaadcb841", - "shared_secret": "02d2e466e170bf45d3e9d357e2f04c34cda408cf147e9ff7a6e8c715f2c88ace" - }, - { - "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", - "sha3_256_hash_of_public_key": "da43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc646", - "sha3_256_hash_of_secret_key": "b204cd1c3122b29a3d99cb77e11427fc102375699928c5a6fe816f96bb212627", - "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", - "sha3_256_hash_of_ciphertext": "228dfe300e3fabe4d4e550754ebcbbf72a796209c1d24e7ae93abb79e1cf17dd", - "shared_secret": "6a5b0842c122ab6ee251399492b061d2ab3e40843f4dc01c12fbd5bd545c600c" - }, - { - "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", - "sha3_256_hash_of_public_key": "6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff9358", - "sha3_256_hash_of_secret_key": "b9dee52055b1f9a2b25a0c1be4d9f30d2ecd7c5a09f0f5294de2d49a55ac9fe0", - "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", - "sha3_256_hash_of_ciphertext": "2d7e8fbd6f2257b05eaaa2ca1643c452b4e0b623c9ad72027cca8dd8b7b5b91d", - "shared_secret": "2486c0a6cf17d9635dbca1f8395784cde54dccb7df10fced92183f983478fac1" - }, - { - "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", - "sha3_256_hash_of_public_key": "e2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1", - "sha3_256_hash_of_secret_key": "68eaa8143a71bd5f6df29b128781e3f2a5fbc5d20534afb223ddcc64bc767f5a", - "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", - "sha3_256_hash_of_ciphertext": "b5b2de55cfaea8fe543f67c4f45a69780c3e2d932e56e0b574d9b40b56ddc1f1", - "shared_secret": "85690ee044e4d8e0540ff984775b59bb5134383c4e229e79e37d7d77632fadaa" - }, - { - "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", - "sha3_256_hash_of_public_key": "d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf", - "sha3_256_hash_of_secret_key": "5f9a14a9c41fc228306d79417015408f31bc9c3d97579616bd68a3d3444f9bd2", - "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", - "sha3_256_hash_of_ciphertext": "99fb7b7767fa94e74936a6678acfd5a2306b156f90f4608d507768a25403a16f", - "shared_secret": "d179d901a0570bd23aa52570c5c233a2240d4724e81d98c9ceedb74187eb75a6" - }, - { - "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", - "sha3_256_hash_of_public_key": "65f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0", - "sha3_256_hash_of_secret_key": "e4513cfd1dd2153d30d15b023421cb8e8456e6a40e612847e1713e915a29a87c", - "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", - "sha3_256_hash_of_ciphertext": "4cd7f0af86623b34c0b137a0516b876daa73ffd65d75871ddc828f86a7e9b224", - "shared_secret": "6d574af7fcb241fed8763b2d0a352870baf85ef686e90eea31f8500c35945ef7" - }, - { - "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", - "sha3_256_hash_of_public_key": "b8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef45793", - "sha3_256_hash_of_secret_key": "1f7cdadf3d4707efe1b7a6173d8f7b8a9f864ab388c3271d79ec424d9da3e896", - "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", - "sha3_256_hash_of_ciphertext": "1ca889a71a087ccee4ee1a178c3c55ce3649583f3db924e5c1003ccabc44091d", - "shared_secret": "b1090cf26276a81c22ef0e4479a4c705fe294d3b892051ddce7eab16495e0783" - }, - { - "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", - "sha3_256_hash_of_public_key": "46fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719", - "sha3_256_hash_of_secret_key": "3177ed170e84ff15fa1e744adc9ce806e431a68f15a7a026c6092bf593dec6a1", - "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", - "sha3_256_hash_of_ciphertext": "aa9a0ea1823a84bc84649d26e249899437844827fe7c63d4828a5144929fa00a", - "shared_secret": "2fda9fa72321be3a0946d6d914c7ae714b9cc175619ab8abfd1f1fd499e0dc27" - }, - { - "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", - "sha3_256_hash_of_public_key": "a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ce", - "sha3_256_hash_of_secret_key": "8f9b3f631d0fb04477846ae09aea725f1cc65b2cdefe2108cdb399c36db9b487", - "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", - "sha3_256_hash_of_ciphertext": "a4fb01f55eb2986c1f90cece43330bee1b16d7bda48d617fc94aa14fc540ec4e", - "shared_secret": "23798e8b9eaa0b369842cad83a2bc32206f791229c830d7593b9150161168011" - }, - { - "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", - "sha3_256_hash_of_public_key": "26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9ed", - "sha3_256_hash_of_secret_key": "5e3f83cb08ff80183879af9ade3631bed2a468e429ad027a5afeafd9a6f66362", - "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", - "sha3_256_hash_of_ciphertext": "6a4204db4803d26d7b8a769033e047f3b4cb616bf5451b88a1fb3ff219bba9cd", - "shared_secret": "d5c63d2bd297e2d8beb6755d6aefe7234dea8ecfba9acda48e643d89a4b95869" - }, - { - "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", - "sha3_256_hash_of_public_key": "2ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf374516336", - "sha3_256_hash_of_secret_key": "2798448395f6ae3223550e7d5255e6a605b430229f5809b6efd0683a6b9ca402", - "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", - "sha3_256_hash_of_ciphertext": "dbd5fc0e1df33ff8af9efd5e281a2b98160f98653803cbd54e3a07292b37fcc7", - "shared_secret": "29d6a229adf49a1139794209307b0ca24be5825b2771809232fb718660162475" - }, - { - "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", - "sha3_256_hash_of_public_key": "de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7e", - "sha3_256_hash_of_secret_key": "6766cef3fe644a233caddf208074b58e6e83f8a78aecd00911c29a08f6f0b0f3", - "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", - "sha3_256_hash_of_ciphertext": "4c669e33b0227c9c2040cdacdbcb7d22b9984372587985ed8f860ffc8d037e79", - "shared_secret": "2a56a7a6d5b4c0500ec00a92e322e69be9e93006240889552072482966c54f56" - }, - { - "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", - "sha3_256_hash_of_public_key": "66f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656", - "sha3_256_hash_of_secret_key": "2237f6cbb452d375878b82c474a7c948ff587a5f3ed02bbba1459fa7ff8ef802", - "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", - "sha3_256_hash_of_ciphertext": "8a2453a21a031cb8966924607a28882426fab2018826192e9bf833bdd38e0631", - "shared_secret": "ecb62b03f640ae4a9d89685fa0070efa93c24dfcff0d555142f9de25b62f861c" - }, - { - "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", - "sha3_256_hash_of_public_key": "7537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2", - "sha3_256_hash_of_secret_key": "bd8e44337eef01251217c4702c99232c001b33870953473d83a7486fd25484cf", - "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", - "sha3_256_hash_of_ciphertext": "6077c60641c03aa8b36213dddf938311ce6b7b8801f967d42713e73249fe7c55", - "shared_secret": "6cc30699701927e07b559d708f93126ed70af254cf37e9056ec9a8d72bfbfc79" - }, - { - "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", - "sha3_256_hash_of_public_key": "82f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335", - "sha3_256_hash_of_secret_key": "fd483ddc211c5c27f453bca56158e1f8084f075a7b06f5098cc3204427bf8197", - "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", - "sha3_256_hash_of_ciphertext": "5c6cfa16f63b1aa93a2b5edc2f4b14c9782f286f53deedf3153f329a2ae2d57a", - "shared_secret": "250e7f67bb34dd5477471e3a701fb71a8138a1920eb807824380f88a944a6fa3" - }, - { - "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", - "sha3_256_hash_of_public_key": "104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4", - "sha3_256_hash_of_secret_key": "73fb93953ae666a9df1bf933ba56b8655ea9e319c0110c78d49f8480ae1aa3fd", - "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", - "sha3_256_hash_of_ciphertext": "e51772e769f778067916e81a561ba6f64fae6096a2b4d4b945d9117e7c36e2b1", - "shared_secret": "0210935a18f1add5ebc2e1107bf40a628ef9cf8f6e7cdac81dc0291bb50a5a3f" - }, - { - "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", - "sha3_256_hash_of_public_key": "0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3", - "sha3_256_hash_of_secret_key": "8a9edd6278707108652f3a5bc244592cb7a82c24634583ed2d3eb6a176b216b8", - "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", - "sha3_256_hash_of_ciphertext": "a00c37bd326205575fcbbc100ed54630aa0f2d6dd9e69807d49151ac9a81c429", - "shared_secret": "34169fc520e944f94ff1fa3799db802a4c1b26cb2971bf196259a937ab8362ca" - }, - { - "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", - "sha3_256_hash_of_public_key": "12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee6385", - "sha3_256_hash_of_secret_key": "bc13b19f01d4cab36dac2154e0fd8fb7d2fa012596363942847f1b0bb3715f90", - "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", - "sha3_256_hash_of_ciphertext": "aed1a4ee810b81cb8ee49ee00e94ff4553f0ad2176fe4d27a09f4e68157fcc3b", - "shared_secret": "b5901e97eb656a09d2dd132528148ad07a0a89f638717eb53516a9ad19aa36bf" - }, - { - "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", - "sha3_256_hash_of_public_key": "2fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85", - "sha3_256_hash_of_secret_key": "2743b7a9dd83a6b9bb5c2685f28b5629b2e31132ac64788a0929557d3449dfc0", - "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", - "sha3_256_hash_of_ciphertext": "7a039d19c45cc557036189cbbc63445b3504a689db56845ece99d593f165c6af", - "shared_secret": "df5117706beedfb521f0f021069fe9650d0844194339033de6997dced05268c8" - }, - { - "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", - "sha3_256_hash_of_public_key": "3eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192", - "sha3_256_hash_of_secret_key": "398ae3423ba5c6bb05920e83e8939a104c3e4ad91647edc7db1667efe438cbfa", - "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", - "sha3_256_hash_of_ciphertext": "05c9617befed785811fcc44d0fce5ae3a1ec66c4d1217ab42e4b754d0ef6207e", - "shared_secret": "eed6ecb831c881508f99ea115745448a7b312a4fa97f65044ebcede172dee2fa" - }, - { - "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", - "sha3_256_hash_of_public_key": "306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47b", - "sha3_256_hash_of_secret_key": "88b28cf6fe19424ff82fc2bb096423b71f0cb8cf985af31bc15ceb4ed18a5e62", - "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", - "sha3_256_hash_of_ciphertext": "315ef84926802ecbbb437f8f50927d3a391b55ee6e47dbd19aa9adeebb808008", - "shared_secret": "d6cb77dc96f9ae4bf8b2fc0e277935b3b7b7a59f749ff2c08ad42659dbce386b" - }, - { - "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", - "sha3_256_hash_of_public_key": "9bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b1", - "sha3_256_hash_of_secret_key": "d8c2492023fb1175a84c19b3ce20f03dd12b1c26b65176d5582c319124bc0e24", - "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", - "sha3_256_hash_of_ciphertext": "ae36e333ece7ca60c9bc2c4ddd01ca88443fd73bab08502656873b703af8925d", - "shared_secret": "1592f1413331f1871b41ff298bfa669bca667241790370d81163c9050b8ac365" - }, - { - "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", - "sha3_256_hash_of_public_key": "6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b3273", - "sha3_256_hash_of_secret_key": "0f2c7bd16d9289c3c27136df0cb6ebc624e80144cb92e6f0c897f58a53617ac3", - "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", - "sha3_256_hash_of_ciphertext": "f8a85f106c6144edf1c7906ec26e292f0390aa9d45a22e67ba2ea018ff565c4d", - "shared_secret": "966f35c6bc47b4525d9af1ba350e8f44ea448cd1d90cf4e9c55ae5878920b7cd" - }, - { - "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", - "sha3_256_hash_of_public_key": "64c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a", - "sha3_256_hash_of_secret_key": "e85b62236d5c6c691a9076dc58bd5da80999eccc8df973c7d0e7e65d8465ea7d", - "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", - "sha3_256_hash_of_ciphertext": "e9149359cc37143b0b565bd413a04f41a7833c5b76012a9263a086ac34071684", - "shared_secret": "aa333af0226492126c6985130ac7df2226a64d6d5c5314ce3f7a99add6696d49" - }, - { - "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", - "sha3_256_hash_of_public_key": "db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf7", - "sha3_256_hash_of_secret_key": "be98d62e4724c0d960ad4839298d4571f9871033b63bdf10d3b0e589db376ffa", - "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", - "sha3_256_hash_of_ciphertext": "9f9368ba712cfee95f28a808cb2c23116a0c8da3910c0def2ef4e55947d7101b", - "shared_secret": "9535303e6035e30c6605c9e0f10c553dcd73828d8525cb190fea79937e093331" - }, - { - "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", - "sha3_256_hash_of_public_key": "c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec", - "sha3_256_hash_of_secret_key": "7a5e854bad628be7b99f524f52a97b0959c0ee67a7a10ad24b970e6e3aeeeb80", - "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", - "sha3_256_hash_of_ciphertext": "31b04a4127558df57844413928b29b11547de5afc088d568a962fe080c97f190", - "shared_secret": "0caa79e0054182c15e54159fbe36d9fb09481331a560ccd9714fff81db5615c4" - }, - { - "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", - "sha3_256_hash_of_public_key": "f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dc", - "sha3_256_hash_of_secret_key": "b6ef04e6acbcd1bb072d1cd28412cdb00ee40d04ce5b39442a2efd6756292167", - "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", - "sha3_256_hash_of_ciphertext": "d8fac8ffc3d8dfebe66c219f4189b780d5ba8fe28d5ab79264345639740913b0", - "shared_secret": "744ce1aa5a9c515c6571ad6e2f5985df8434e35e9f714cf3659f184b5db4086f" - }, - { - "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", - "sha3_256_hash_of_public_key": "10e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012", - "sha3_256_hash_of_secret_key": "2b5c6d5fe9b09ab5a027522e699401223ae9d304ac912f1b15f0f647dd9a0a7f", - "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", - "sha3_256_hash_of_ciphertext": "e8b01628c7d63f16c59e67352399a760581f341ed41535013490502e884733be", - "shared_secret": "726f7d790df4c860a0b2c40de9d62c85d0ff70c704ce5a1b3f6bf1b3e3f66cd8" - }, - { - "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", - "sha3_256_hash_of_public_key": "7c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851c", - "sha3_256_hash_of_secret_key": "72e786018ae9ab8293fa51cb7ca3ff0435e7cccbd5ae02b4680b92c148590265", - "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", - "sha3_256_hash_of_ciphertext": "5b2e8a3e38c13b53393c8654e92eeb6251ddbe50de4b3c5203a06977491f2fbc", - "shared_secret": "68f3e22d1b2d8c57bff32160e550becfce535fdcb327394aabeb60eede263213" - }, - { - "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", - "sha3_256_hash_of_public_key": "8aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d", - "sha3_256_hash_of_secret_key": "f7399dbf35fcc57a9bff87b0087755faa75267788cd0921b9ebc5cde8b656271", - "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", - "sha3_256_hash_of_ciphertext": "aac868f2299bcd272afacf50f1ab0db3d092d33565cffb5645d8b92271e7e893", - "shared_secret": "7f6085840a30c6b1fb9dca782e0c78a2264d54726c04c3127956f131165426c8" - }, - { - "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", - "sha3_256_hash_of_public_key": "149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75", - "sha3_256_hash_of_secret_key": "6dfa4d29af6a0e8413d5591339c15d2e2cfac3f502f49acca3efb53b53624666", - "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", - "sha3_256_hash_of_ciphertext": "ced7a64ce643faebac8ffd39c6a4594732b35f1d6899978ba192b87003d3ad27", - "shared_secret": "96e30641ea4280168da37291a3063342ced8e77b33b5415819938c0bd7264ffc" - }, - { - "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", - "sha3_256_hash_of_public_key": "29b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf", - "sha3_256_hash_of_secret_key": "762a61eb847c017ece920f51d5da7a9036ed8b835bfd7793527321ec635e2fd0", - "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", - "sha3_256_hash_of_ciphertext": "bf49310a35f9ba7994645f12949e658b0dd43d3de76386dc20d08c650522f86c", - "shared_secret": "47e54c85cc0e2503629a8bfdcfe038c3cf692d723d462bab733c7c8e0aa37b02" - }, - { - "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", - "sha3_256_hash_of_public_key": "b990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5", - "sha3_256_hash_of_secret_key": "37a044795bd330e4dc60a6d84bc6e99664d1be418b0239661d2ff16d1501573f", - "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", - "sha3_256_hash_of_ciphertext": "329115908d0763110a387c99778e4746861e80367ee90fd821cda9acdb93fd64", - "shared_secret": "8569bd042465a2c4af628425cb102b15ed4f5feee16090e2234f3a884a0fa938" - }, - { - "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", - "sha3_256_hash_of_public_key": "175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5", - "sha3_256_hash_of_secret_key": "1993d7639b79f5e4871a7c58a69fec50f96c1424c2c0ee030ac054ae1b88a56f", - "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", - "sha3_256_hash_of_ciphertext": "8f4225838f2964a986336bacddc40836a98c32cca68c6afcbcf9ef68d9a3760b", - "shared_secret": "c184e0b019c2db772e2c1ca6f97f47478d99cf0c4c5ae1406f51d15815022123" - }, - { - "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", - "sha3_256_hash_of_public_key": "9bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd3", - "sha3_256_hash_of_secret_key": "3db4ab1393cfc8b1c708cf8efdb1c443c975878898b60182c22af66375cba13a", - "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", - "sha3_256_hash_of_ciphertext": "f1c85f9530d4471eb1401fcf422a29533738c485a6be25f0b554ebf40b49d49d", - "shared_secret": "6d72e23c8a4cc60b2f14adc788a5c480033bbf6eb111070912bc83ad7b89280b" - }, - { - "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", - "sha3_256_hash_of_public_key": "7ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26d", - "sha3_256_hash_of_secret_key": "77431cb18010a604d56fe5a623bed2ffd028a741f176fa09546e9a45a48caa5e", - "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", - "sha3_256_hash_of_ciphertext": "83ddab2e25614544649a1e497b5b21c40a3e154e8a22c270f63cb0c40aa868fd", - "shared_secret": "29e6b1edac0a9aa33066c113167e42c64d70215ed04963d8be2d4c2dcd0f6589" - }, - { - "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", - "sha3_256_hash_of_public_key": "2c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b20411", - "sha3_256_hash_of_secret_key": "09844e203f4d8fa30728ab388b9d654847febbf5c9cd939cdc11c9c9be24ce9c", - "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", - "sha3_256_hash_of_ciphertext": "a2108ea2c446b566a50c228928893e2e4bde5fafb2184af92eb1314113bde0d6", - "shared_secret": "cfd1b82181543656807880f6e2576f0b095bf84629b3367e9bdede24662ee42e" - }, - { - "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", - "sha3_256_hash_of_public_key": "aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22", - "sha3_256_hash_of_secret_key": "3880f7ca8fc33575a7a6d8bb46fec86a3f12e0068630507ed245d8bc278fbe5d", - "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", - "sha3_256_hash_of_ciphertext": "ec48b3ec403609a0ce2d1268cadda8184ab9629cc5913135ffdecd420eed1aa9", - "shared_secret": "f7331b0a4674969838482b7184fa92e5246f11f5b5e284c3e179effff7eb6329" - }, - { - "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", - "sha3_256_hash_of_public_key": "64e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d3", - "sha3_256_hash_of_secret_key": "0bfbc25d9df751f4c30907095eb6d9a75ed07fa23218ad0fffc469f0e55553c2", - "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", - "sha3_256_hash_of_ciphertext": "fb74b727ad120c18915dca475f3082cd34ded7ae20a308106384ffb5caa029d3", - "shared_secret": "c89d62938a5caabfd5b30d82ea88aced52ef5f8ec0528e59a654e1f6aff1cc2f" - }, - { - "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", - "sha3_256_hash_of_public_key": "8dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964c", - "sha3_256_hash_of_secret_key": "7c53072fd98ea7bd8c5e873688b1a5650fe7e11c791407ac8c118b7958cf414b", - "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", - "sha3_256_hash_of_ciphertext": "a1f1579c4ce8eb725e697623321b3d9f55f4b1d0def10b898535ef6614e9923e", - "shared_secret": "204d9272682710b52fb39b1176af3ff737848978770310df0c67996f6cb596c3" - }, - { - "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", - "sha3_256_hash_of_public_key": "919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463", - "sha3_256_hash_of_secret_key": "cb1d7301f15951883cc3f287d4dd8fdf5c9b7022f558dff551c2ade5f5065755", - "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", - "sha3_256_hash_of_ciphertext": "f02654803493821dd9c2ed23f9e46a36addd5fca0da706bbeeda87a2df9fec4f", - "shared_secret": "76e5f7623e3e867fd12f28dfda4311f7cd90a405b73e994e857f693573fd2b8a" - }, - { - "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", - "sha3_256_hash_of_public_key": "cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76", - "sha3_256_hash_of_secret_key": "a85e24cc2eafdfe40d82f46471112e1359628b9955f3feae9955b48d563ac952", - "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", - "sha3_256_hash_of_ciphertext": "17336b9ede3a1c26abe725828a5afbe746035a73dfd4a8fbde5040fbabeb2b8d", - "shared_secret": "874ac966970f29935db73c231e71a3559b2504e5446151b99c199276617b3824" - } -] \ No newline at end of file diff --git a/kyber-crate-tests/kyber_nistkats.rs b/kyber-crate-tests/kyber_nistkats.rs deleted file mode 100644 index 5f7ef9005..000000000 --- a/kyber-crate-tests/kyber_nistkats.rs +++ /dev/null @@ -1,78 +0,0 @@ -use serde::Deserialize; -use serde_json; - -use std::path::Path; -use std::{fs::File, io::BufReader}; - -use libcrux::digest; - -use libcrux_kyber::kyber768::*; - -#[derive(Deserialize)] -struct KyberNISTKAT { - #[serde(with = "hex::serde")] - key_generation_seed: [u8; 64], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_public_key: [u8; 32], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_secret_key: [u8; 32], - - #[serde(with = "hex::serde")] - encapsulation_seed: [u8; 32], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_ciphertext: [u8; 32], - - #[serde(with = "hex::serde")] - shared_secret: [u8; 32], -} - -macro_rules! impl_nist_known_answer_tests { - ($name:ident, $parameter_set: literal, $key_gen_derand:expr, $encapsulate_derand:expr, $decapsulate_derand: expr) => { - #[test] - fn $name() { - let katfile_path = Path::new("tests") - .join("kyber_kats") - .join(format!("nistkats_{}.json", $parameter_set)); - let katfile = File::open(katfile_path).expect("Could not open KAT file."); - let reader = BufReader::new(katfile); - - let nist_kats: Vec = - serde_json::from_reader(reader).expect("Could not deserialize KAT file."); - - for kat in nist_kats { - eprintln!("seed: {}", hex::encode(kat.key_generation_seed)); - let key_pair = $key_gen_derand(kat.key_generation_seed); - - eprintln!("pk: {}", hex::encode(key_pair.pk())); - eprintln!("sk: {}", hex::encode(key_pair.sk())); - let public_key_hash = digest::sha3_256(key_pair.pk()); - let secret_key_hash = digest::sha3_256(key_pair.sk()); - - assert_eq!(public_key_hash, kat.sha3_256_hash_of_public_key, "public keys don't match"); - assert_eq!(secret_key_hash, kat.sha3_256_hash_of_secret_key, "secret keys don't match"); - - let (ciphertext, shared_secret) = - $encapsulate_derand(key_pair.public_key(), kat.encapsulation_seed); - let ciphertext_hash = digest::sha3_256(ciphertext.as_ref()); - - assert_eq!(ciphertext_hash, kat.sha3_256_hash_of_ciphertext, "ciphertexts don't match"); - assert_eq!(shared_secret.as_ref(), kat.shared_secret, "shared secret produced by encapsulate does not match"); - - let shared_secret_from_decapsulate = - $decapsulate_derand(key_pair.private_key(), &ciphertext); - assert_eq!(shared_secret_from_decapsulate, shared_secret.as_ref(), "shared secret produced by decapsulate doesn't match the one produced by encapsulate"); - } - } - }; -} - -impl_nist_known_answer_tests!( - kyber768_nist_known_answer_tests, - 768, - generate_key_pair, - encapsulate, - decapsulate -); diff --git a/kyber-crate.sh b/kyber-crate.sh deleted file mode 100755 index 289058737..000000000 --- a/kyber-crate.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -set -e - -rm -rf kyber-crate -mkdir -p kyber-crate/src -cp -r src/kem/kyber* kyber-crate/src -cd kyber-crate -mv src/kyber.rs src/lib.rs -mv src/kyber/* src - -SED=$(which gsed &>/dev/null && echo gsed || echo sed) - -cat >Cargo.toml <src/hax_utils.rs < {}; -} - -pub(crate) use hax_debug_assert; -EOF - -$SED -i '1ipub(crate) mod hax_utils;' src/lib.rs - -mkdir -p tests -cp -r ../kyber-crate-tests/* tests/ -rm src/kyber512.rs -rm src/kyber1024.rs - -# Build & test -cargo test - -# Extract -if [[ -z "$CHARON_HOME" ]]; then - echo "Please set CHARON_HOME to the Charon directory" 1>&2 - exit 1 -fi -if [[ -z "$EURYDICE_HOME" ]]; then - echo "Please set EURYDICE_HOME to the Eurydice directory" 1>&2 - exit 1 -fi - -echo "Running charon ..." -$CHARON_HOME/bin/charon --errors-as-warnings -mkdir -p c -cd c - -echo "Running eurydice ..." -$EURYDICE_HOME/eurydice --config ../../kyber-c.yaml ../libcrux_kyber.llbc -cp $EURYDICE_HOME/include/eurydice_glue.h . - -if [[ -n "$HACL_PACKAGES_HOME" ]]; then - clang-format --style=Mozilla -i libcrux_kyber.c libcrux_kyber.h - cp internal/*.h $HACL_PACKAGES_HOME/libcrux/include/internal/ - cp *.h $HACL_PACKAGES_HOME/libcrux/include - cp *.c $HACL_PACKAGES_HOME/libcrux/src -else - echo "Please set HACL_PACKAGES_HOME to the hacl-packages directory to copy the code over" 1>&2 -fi diff --git a/libcrux-simd/Cargo.toml b/libcrux-simd/Cargo.toml deleted file mode 100644 index 42d4846bf..000000000 --- a/libcrux-simd/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "libcrux-simd" -version.workspace = true -authors.workspace = true -license.workspace = true -homepage.workspace = true -edition.workspace = true -repository.workspace = true -readme.workspace = true - -[dependencies] -libcrux-platform = { version = "0.0.2-pre.2", path = "../sys/platform" } - -[features] -simd128 = [] -simd256 = [] diff --git a/libcrux-simd/src/aarch64.rs b/libcrux-simd/src/aarch64.rs deleted file mode 100644 index 325dc3014..000000000 --- a/libcrux-simd/src/aarch64.rs +++ /dev/null @@ -1,130 +0,0 @@ -use core::arch::aarch64::*; - -/// A 128-bit integer type for SIMD instructions. -pub type Vec128 = uint32x4_t; - -/// We can't compute on a const `N`. So this is a little ugly. -/// Ensure that the `N` you provide is handled here. -/// -/// 16 is handled differently because it's more efficient this way. -#[inline(always)] -pub fn rotate_left128_u32(a: Vec128, n: u32) -> Vec128 { - assert!(n >= 1 && n <= 32); - match n { - 7 => unsafe { vsriq_n_u32(vshlq_n_u32(a, 7), a, 32 - 7) }, - 8 => unsafe { vsriq_n_u32(vshlq_n_u32(a, 8), a, 32 - 8) }, - 12 => unsafe { vsriq_n_u32(vshlq_n_u32(a, 12), a, 32 - 12) }, - 16 => unsafe { vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(a))) }, - _ => unimplemented!(), - } -} - -#[inline(always)] -pub fn rotate_left128_u32_16(a: Vec128) -> Vec128 { - unsafe { vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(a))) } -} - -#[inline(always)] -pub fn rotate_left128_u32_12(a: Vec128) -> Vec128 { - unsafe { vsriq_n_u32(vshlq_n_u32(a, 12), a, 32 - 12) } -} - -#[inline(always)] -pub fn rotate_left128_u32_8(a: Vec128) -> Vec128 { - unsafe { vsriq_n_u32(vshlq_n_u32(a, 8), a, 32 - 8) } -} - -#[inline(always)] -pub fn rotate_left128_u32_7(a: Vec128) -> Vec128 { - unsafe { vsriq_n_u32(vshlq_n_u32(a, 7), a, 32 - 7) } -} - -#[inline(always)] -pub fn add32(a: Vec128, b: Vec128) -> Vec128 { - unsafe { vaddq_u32(a, b) } -} - -#[inline(always)] -pub fn xor32(a: Vec128, b: Vec128) -> Vec128 { - unsafe { veorq_u32(a, b) } -} - -#[inline(always)] -pub fn load32(x: u32) -> Vec128 { - unsafe { vdupq_n_u32(x) } -} - -#[inline(always)] -// 16 u8, interpreted as 4 u32 -pub fn load8_32_le(value: &[u8]) -> Vec128 { - unsafe { vld1q_u32(value.as_ptr() as *const u32) } -} - -/// Load a `u8` slice into 4 `u32`. -/// -/// The slice must be `value.len() <= 4 * 4`. -/// When the slice is shorter, it is padded with `0`s. -#[inline(always)] -pub fn u32_from_le_bytes(value: &[u8]) -> Vec128 { - let mut padded = [0u8; 16]; - padded[0..value.len()].copy_from_slice(value); - load8_32_le(&padded) -} - -#[inline(always)] -// 4 u32, interpreted as 4 u32 -pub fn load32_le(values: [u32; 4]) -> Vec128 { - unsafe { vld1q_u32(values.as_ptr() as *const u32) } -} - -#[inline(always)] -// store vec128 into u8 slice -pub fn store8_32_le(value: Vec128, out: &mut [u8; 16]) { - unsafe { vst1q_u32(out.as_mut_ptr() as *mut u32, value) } -} - -/// Store 4 `u32` into little endian bytes. -/// -/// When the output has less than 16 bytes left to write in, only the available -/// number of bytes are written. -#[inline(always)] -pub fn u32_to_le_bytes(out: &mut [u8], value: Vec128) { - let mut padded = [0u8; 16]; - store8_32_le_ip(&mut padded, value); - out.copy_from_slice(&padded[0..out.len()]); -} - -#[inline(always)] -pub fn store8_32_le_ip(out: &mut [u8], value: Vec128) { - unsafe { vst1q_u32(out.as_mut_ptr() as *mut u32, value) } -} - -#[inline(always)] -pub fn interleave_low64(x1: Vec128, x2: Vec128) -> Vec128 { - unsafe { - vreinterpretq_u32_u64(vzip1q_u64( - vreinterpretq_u64_u32(x1), - vreinterpretq_u64_u32(x2), - )) - } -} - -#[inline(always)] -pub fn interleave_high64(x1: Vec128, x2: Vec128) -> Vec128 { - unsafe { - vreinterpretq_u32_u64(vzip2q_u64( - vreinterpretq_u64_u32(x1), - vreinterpretq_u64_u32(x2), - )) - } -} - -#[inline(always)] -pub fn interleave_low32(x1: Vec128, x2: Vec128) -> Vec128 { - unsafe { vzip1q_u32(x1, x2) } -} - -#[inline(always)] -pub fn interleave_high32(x1: Vec128, x2: Vec128) -> Vec128 { - unsafe { vzip2q_u32(x1, x2) } -} diff --git a/libcrux-simd/src/lib.rs b/libcrux-simd/src/lib.rs deleted file mode 100644 index 6e98921d3..000000000 --- a/libcrux-simd/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! # Hardware abstraction -//! -//! This crate implements hardware abstraction for 128-bit and 256-bit SIMD on -//! x64 and aarch64. - -#![no_std] - -/// When we build for aarch64 and the simd128 config is enabled. -#[cfg(all(target_arch = "aarch64", feature = "simd128"))] -pub use aarch64; - -pub mod scalar; diff --git a/libcrux-simd/src/scalar.rs b/libcrux-simd/src/scalar.rs deleted file mode 100644 index 1903d1548..000000000 --- a/libcrux-simd/src/scalar.rs +++ /dev/null @@ -1,61 +0,0 @@ -#[inline(always)] -pub fn rotate_left128_u32(a: u32, n: u32) -> u32 { - a.rotate_left(n) -} - -#[inline(always)] -pub fn add32(a: u32, b: u32) -> u32 { - a.wrapping_add(b) -} - -#[inline(always)] -pub fn xor32(a: u32, b: u32) -> u32 { - a ^ b -} - -#[inline(always)] -pub fn load32(x: u32) -> u32 { - x -} - -#[inline(always)] -/// No-op -pub fn load32_le(values: [u32; 1]) -> u32 { - values[0] -} - -/// Load a `u8` slice into a `u32`. -/// -/// The slice must be `value.len() <= 4`. -/// When the slice is shorter, it is padded with `0`s. -#[inline(always)] -pub fn u32_from_le_bytes(value: &[u8]) -> u32 { - let mut padded = [0u8; 4]; - padded[0..value.len()].copy_from_slice(value); - load8_32_le(&padded) -} - -/// u32 from u8s le -#[inline(always)] -pub fn load8_32_le(value: &[u8]) -> u32 { - u32::from_le_bytes(value.try_into().unwrap()) -} - -/// Store a `u32` into little endian bytes. -/// -/// When the output has less than 4 bytes left to write in, only the available -/// number of bytes are written. -#[inline(always)] -pub fn u32_to_le_bytes(out: &mut [u8], value: u32) { - let mut padded = [0u8; 4]; - store8_32_le_ip(&mut padded, value); - out.copy_from_slice(&padded[0..out.len()]); -} - -#[inline(always)] -pub fn store8_32_le_ip(out: &mut [u8], value: u32) { - let tmp = value.to_le_bytes(); - for j in 0..4 { - out[j] = tmp[j]; - } -} diff --git a/polynomials-aarch64/src/neon.rs b/polynomials-aarch64/src/neon.rs deleted file mode 100644 index 88157fdf3..000000000 --- a/polynomials-aarch64/src/neon.rs +++ /dev/null @@ -1,282 +0,0 @@ -#![allow(non_camel_case_types)] -pub(crate) use core::arch::aarch64::*; - -#[inline(always)] -pub(crate) fn _vdupq_n_s16(i: i16) -> int16x8_t { - unsafe { vdupq_n_s16(i) } -} - -#[inline(always)] -pub(crate) fn _vst1q_s16(out: &mut [i16], v: int16x8_t) { - unsafe { vst1q_s16(out.as_mut_ptr(), v) } -} - -#[inline(always)] -pub(crate) fn _vld1q_s16(array: &[i16]) -> int16x8_t { - unsafe { vld1q_s16(array.as_ptr()) } -} - -#[inline(always)] -pub(crate) fn _vaddq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { - unsafe { vaddq_s16(lhs, rhs) } -} - -#[inline(always)] -pub(crate) fn _vsubq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { - unsafe { vsubq_s16(lhs, rhs) } -} - -#[inline(always)] -pub(crate) fn _vmulq_n_s16(v: int16x8_t, c: i16) -> int16x8_t { - unsafe { vmulq_n_s16(v, c) } -} - -#[inline(always)] -pub(crate) fn _vmulq_n_u16(v: uint16x8_t, c: u16) -> uint16x8_t { - unsafe { vmulq_n_u16(v, c) } -} - -#[inline(always)] -pub(crate) fn _vshrq_n_s16(v: int16x8_t) -> int16x8_t { - unsafe { vshrq_n_s16::(v) } -} - -#[inline(always)] -pub(crate) fn _vshrq_n_u16(v: uint16x8_t) -> uint16x8_t { - unsafe { vshrq_n_u16::(v) } -} - -#[inline(always)] -pub(crate) fn _vshlq_n_s16(v: int16x8_t) -> int16x8_t { - unsafe { vshlq_n_s16::(v) } -} - -#[inline(always)] -pub(crate) fn _vshlq_n_u32(v: uint32x4_t) -> uint32x4_t { - unsafe { vshlq_n_u32::(v) } -} -#[inline(always)] -pub(crate) fn _vqdmulhq_n_s16(k: int16x8_t, b: i16) -> int16x8_t { - unsafe { vqdmulhq_n_s16(k, b) } -} -#[inline(always)] -pub(crate) fn _vqdmulhq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { - unsafe { vqdmulhq_s16(v, c) } -} -#[inline(always)] -pub(crate) fn _vcgeq_s16(v: int16x8_t, c: int16x8_t) -> uint16x8_t { - unsafe { vcgeq_s16(v, c) } -} -#[inline(always)] -pub(crate) fn _vandq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { - unsafe { vandq_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s16_u16(m0: uint16x8_t) -> int16x8_t { - unsafe { vreinterpretq_s16_u16(m0) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_u16_s16(m0: int16x8_t) -> uint16x8_t { - unsafe { vreinterpretq_u16_s16(m0) } -} -#[inline(always)] -pub(crate) fn _vmulq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { - unsafe { vmulq_s16(v, c) } -} -#[inline(always)] -pub(crate) fn _veorq_s16(mask: int16x8_t, shifted: int16x8_t) -> int16x8_t { - unsafe { veorq_s16(mask, shifted) } -} -#[inline(always)] -pub(crate) fn _vdupq_n_u32(value: u32) -> uint32x4_t { - unsafe { vdupq_n_u32(value) } -} -#[inline(always)] -pub(crate) fn _vaddq_u32(compressed: uint32x4_t, half: uint32x4_t) -> uint32x4_t { - unsafe { vaddq_u32(compressed, half) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s32_u32(compressed: uint32x4_t) -> int32x4_t { - unsafe { vreinterpretq_s32_u32(compressed) } -} -#[inline(always)] -pub(crate) fn _vqdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t { - unsafe { vqdmulhq_n_s32(a, b) } -} - -#[inline(always)] -pub(super) fn _vreinterpretq_u32_s32(a: int32x4_t) -> uint32x4_t { - unsafe { vreinterpretq_u32_s32(a) } -} - -#[inline(always)] -pub(super) fn _vshrq_n_u32(a: uint32x4_t) -> uint32x4_t { - unsafe { vshrq_n_u32::(a) } -} -#[inline(always)] -pub(crate) fn _vandq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { - unsafe { vandq_u32(a, b) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_u32_s16(a: int16x8_t) -> uint32x4_t { - unsafe { vreinterpretq_u32_s16(a) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s16_u32(a: uint32x4_t) -> int16x8_t { - unsafe { vreinterpretq_s16_u32(a) } -} -#[inline(always)] -pub(crate) fn _vtrn1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { - unsafe { vtrn1q_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vtrn2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { - unsafe { vtrn2q_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vmulq_n_u32(a: uint32x4_t, b: u32) -> uint32x4_t { - unsafe { vmulq_n_u32(a, b) } -} - -#[inline(always)] -pub(super) fn _vtrn1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { - unsafe { vtrn1q_s32(a, b) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t { - unsafe { vreinterpretq_s16_s32(a) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t { - unsafe { vreinterpretq_s32_s16(a) } -} - -#[inline(always)] -pub(super) fn _vtrn2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { - unsafe { vtrn2q_s32(a, b) } -} -#[inline(always)] -pub(crate) fn _vtrn1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { - unsafe { vtrn1q_s64(a, b) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t { - unsafe { vreinterpretq_s16_s64(a) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t { - unsafe { vreinterpretq_s64_s16(a) } -} -#[inline(always)] -pub(crate) fn _vtrn2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { - unsafe { vtrn2q_s64(a, b) } -} -#[inline(always)] -pub(crate) fn _vmull_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { - unsafe { vmull_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vget_low_s16(a: int16x8_t) -> int16x4_t { - unsafe { vget_low_s16(a) } -} -#[inline(always)] -pub(crate) fn _vmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t { - unsafe { vmull_high_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t { - unsafe { vmlal_s16(a, b, c) } -} -#[inline(always)] -pub(crate) fn _vmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t { - unsafe { vmlal_high_s16(a, b, c) } -} -#[inline(always)] -pub(crate) fn _vld1q_u8(ptr: &[u8]) -> uint8x16_t { - unsafe { vld1q_u8(ptr.as_ptr()) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t { - unsafe { vreinterpretq_u8_s16(a) } -} -#[inline(always)] -pub(crate) fn _vqtbl1q_u8(t: uint8x16_t, idx: uint8x16_t) -> uint8x16_t { - unsafe { vqtbl1q_u8(t, idx) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t { - unsafe { vreinterpretq_s16_u8(a) } -} -#[inline(always)] -pub(crate) fn _vshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { - unsafe { vshlq_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t { - unsafe { vshlq_u16(a, b) } -} -#[inline(always)] -pub(crate) fn _vaddv_u16(a: uint16x4_t) -> u16 { - unsafe { vaddv_u16(a) } -} -#[inline(always)] -pub(crate) fn _vget_low_u16(a: uint16x8_t) -> uint16x4_t { - unsafe { vget_low_u16(a) } -} -#[inline(always)] -pub(crate) fn _vget_high_u16(a: uint16x8_t) -> uint16x4_t { - unsafe { vget_high_u16(a) } -} -#[inline(always)] -pub(crate) fn _vaddvq_s16(a: int16x8_t) -> i16 { - unsafe { vaddvq_s16(a) } -} - -#[inline(always)] -pub(super) fn _vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { - unsafe { vsliq_n_s32::(a, b) } -} - -#[inline(always)] -pub(super) fn _vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t { - unsafe { vreinterpretq_s64_s32(a) } -} - -#[inline(always)] -pub(super) fn _vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { - unsafe { vsliq_n_s64::(a, b) } -} - -#[inline(always)] -pub(super) fn _vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t { - unsafe { vreinterpretq_u8_s64(a) } -} - -#[inline(always)] -pub(super) fn _vst1q_u8(out: &mut [u8], v: uint8x16_t) { - unsafe { vst1q_u8(out.as_mut_ptr(), v) } -} -#[inline(always)] -pub(crate) fn _vdupq_n_u16(value: u16) -> uint16x8_t { - unsafe { vdupq_n_u16(value) } -} -#[inline(always)] -pub(crate) fn _vandq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { - unsafe { vandq_u16(a, b) } -} -#[inline(always)] -pub(crate) fn _vreinterpretq_u16_u8(a: uint8x16_t) -> uint16x8_t { - unsafe { vreinterpretq_u16_u8(a) } -} -#[inline(always)] -pub(crate) fn _vld1q_u16(ptr: &[u16]) -> uint16x8_t { - unsafe { vld1q_u16(ptr.as_ptr()) } -} -#[inline(always)] -pub(crate) fn _vcleq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t { - unsafe { vcleq_s16(a, b) } -} -#[inline(always)] -pub(crate) fn _vaddvq_u16(a: uint16x8_t) -> u16 { - unsafe { vaddvq_u16(a) } -} diff --git a/polynomials-aarch64/src/rejsample.rs b/polynomials-aarch64/src/rejsample.rs deleted file mode 100644 index 64e64a0dc..000000000 --- a/polynomials-aarch64/src/rejsample.rs +++ /dev/null @@ -1,797 +0,0 @@ -#![forbid(unsafe_code)] - -use crate::neon::*; - -/// This table is taken from PQClean. It is used in rej_sample -// It implements the following logic: -// let mut index : [u8;16] = [0u8; 16]; -// let mut idx = 0; -// for i in 0..8 { -// if used > 0 { -// let next = used.trailing_zeros(); -// idx = idx + next; -// index[i*2] = (idx*2) as u8; -// index[i*2+1] = (idx*2 + 1) as u8; -// idx = idx + 1; -// used = used >> (next+1); -// } -// } -// let index_vec = unsafe { vld1q_u8(index.as_ptr() as *const u8) }; -// End of index table lookup calculation - -const IDX_TABLE: [[u8; 16]; 256] = [ - [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, - ], // 0 - [ - 0, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 1 - [ - 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 2 - [ - 0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 3 - [ - 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 4 - [ - 0, 1, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 5 - [ - 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 6 - [ - 0, 1, 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 7 - [ - 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 8 - [ - 0, 1, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 9 - [ - 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 10 - [ - 0, 1, 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 11 - [ - 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 12 - [ - 0, 1, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 13 - [ - 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 14 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 15 - [ - 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 16 - [ - 0, 1, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 17 - [ - 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 18 - [ - 0, 1, 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 19 - [ - 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 20 - [ - 0, 1, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 21 - [ - 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 22 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 23 - [ - 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 24 - [ - 0, 1, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 25 - [ - 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 26 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 27 - [ - 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 28 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 29 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 30 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 31 - [ - 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 32 - [ - 0, 1, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 33 - [ - 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 34 - [ - 0, 1, 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 35 - [ - 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 36 - [ - 0, 1, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 37 - [ - 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 38 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 39 - [ - 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 40 - [ - 0, 1, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 41 - [ - 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 42 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 43 - [ - 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 44 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 45 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 46 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 47 - [ - 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 48 - [ - 0, 1, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 49 - [ - 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 50 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 51 - [ - 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 52 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 53 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 54 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 55 - [ - 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 56 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 57 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 58 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 59 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 60 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 61 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 62 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff], // 63 - [ - 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 64 - [ - 0, 1, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 65 - [ - 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 66 - [ - 0, 1, 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 67 - [ - 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 68 - [ - 0, 1, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 69 - [ - 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 70 - [ - 0, 1, 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 71 - [ - 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 72 - [ - 0, 1, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 73 - [ - 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 74 - [ - 0, 1, 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 75 - [ - 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 76 - [ - 0, 1, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 77 - [ - 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 78 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 79 - [ - 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 80 - [ - 0, 1, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 81 - [ - 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 82 - [ - 0, 1, 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 83 - [ - 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 84 - [ - 0, 1, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 85 - [ - 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 86 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 87 - [ - 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 88 - [ - 0, 1, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 89 - [ - 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 90 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 91 - [ - 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 92 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 93 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 94 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff], // 95 - [ - 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 96 - [ - 0, 1, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 97 - [ - 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 98 - [ - 0, 1, 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 99 - [ - 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 100 - [ - 0, 1, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 101 - [ - 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 102 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 103 - [ - 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 104 - [ - 0, 1, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 105 - [ - 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 106 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 107 - [ - 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 108 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 109 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 110 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 111 - [ - 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 112 - [ - 0, 1, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 113 - [ - 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 114 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 115 - [ - 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 116 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 117 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 118 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 119 - [ - 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 120 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 121 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 122 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 123 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 124 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 125 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 126 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff], // 127 - [ - 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 128 - [ - 0, 1, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 129 - [ - 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 130 - [ - 0, 1, 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 131 - [ - 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 132 - [ - 0, 1, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 133 - [ - 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 134 - [ - 0, 1, 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 135 - [ - 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 136 - [ - 0, 1, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 137 - [ - 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 138 - [ - 0, 1, 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 139 - [ - 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 140 - [ - 0, 1, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 141 - [ - 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 142 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 143 - [ - 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 144 - [ - 0, 1, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 145 - [ - 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 146 - [ - 0, 1, 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 147 - [ - 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 148 - [ - 0, 1, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 149 - [ - 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 150 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 151 - [ - 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 152 - [ - 0, 1, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 153 - [ - 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 154 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 155 - [ - 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 156 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 157 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 158 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff], // 159 - [ - 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 160 - [ - 0, 1, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 161 - [ - 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 162 - [ - 0, 1, 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 163 - [ - 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 164 - [ - 0, 1, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 165 - [ - 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 166 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 167 - [ - 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 168 - [ - 0, 1, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 169 - [ - 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 170 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 171 - [ - 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 172 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 173 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 174 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 175 - [ - 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 176 - [ - 0, 1, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 177 - [ - 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 178 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 179 - [ - 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 180 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 181 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 182 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 183 - [ - 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 184 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 185 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 186 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 187 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 188 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 189 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 190 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff], // 191 - [ - 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 192 - [ - 0, 1, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 193 - [ - 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 194 - [ - 0, 1, 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 195 - [ - 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 196 - [ - 0, 1, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 197 - [ - 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 198 - [ - 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 199 - [ - 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 200 - [ - 0, 1, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 201 - [ - 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 202 - [ - 0, 1, 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 203 - [ - 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 204 - [ - 0, 1, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 205 - [ - 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 206 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 207 - [ - 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 208 - [ - 0, 1, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 209 - [ - 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 210 - [ - 0, 1, 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 211 - [ - 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 212 - [ - 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 213 - [ - 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 214 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 215 - [ - 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 216 - [ - 0, 1, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 217 - [ - 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 218 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 219 - [ - 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 220 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 221 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 222 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff], // 223 - [ - 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 224 - [ - 0, 1, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 225 - [ - 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 226 - [ - 0, 1, 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 227 - [ - 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 228 - [ - 0, 1, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 229 - [ - 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 230 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 231 - [ - 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 232 - [ - 0, 1, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 233 - [ - 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 234 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 235 - [ - 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 236 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 237 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 238 - [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 239 - [ - 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 240 - [ - 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 241 - [ - 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 242 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 243 - [ - 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 244 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 245 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 246 - [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 247 - [ - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 248 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 249 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 250 - [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 251 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 252 - [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 253 - [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 254 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // 255 -]; - -#[inline(always)] -pub(crate) fn rej_sample(a: &[u8], out: &mut [i16]) -> usize { - let neon_bits: [u16; 8] = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80]; - let bits = _vld1q_u16(&neon_bits); - let fm = _vdupq_n_s16(3328); - - let input = super::simd128ops::deserialize_12(a); - let mask0 = _vcleq_s16(input.low, fm); - let mask1 = _vcleq_s16(input.high, fm); - let masked = _vandq_u16(mask0, bits); - let used0 = _vaddvq_u16(masked); - let masked = _vandq_u16(mask1, bits); - let used1 = _vaddvq_u16(masked); - let pick0 = used0.count_ones(); - let pick1 = used1.count_ones(); - - // XXX: the indices used0 and used1 must be < 256. - let index_vec0 = _vld1q_u8(&IDX_TABLE[(used0 as u8) as usize]); - let shifted0 = _vreinterpretq_s16_u8(_vqtbl1q_u8(_vreinterpretq_u8_s16(input.low), index_vec0)); - let index_vec1 = _vld1q_u8(&IDX_TABLE[(used1 as u8) as usize]); - let shifted1 = - _vreinterpretq_s16_u8(_vqtbl1q_u8(_vreinterpretq_u8_s16(input.high), index_vec1)); - - let idx0 = usize::try_from(pick0).unwrap(); - _vst1q_s16(&mut out[0..8], shifted0); - _vst1q_s16(&mut out[idx0..idx0 + 8], shifted1); - (pick0 + pick1) as usize -} diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst deleted file mode 100644 index cd19825be..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst +++ /dev/null @@ -1,159 +0,0 @@ -module Libcrux_polynomials_avx2.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -let v_BARRETT_MULTIPLIER: i16 = 20159s - -let add (lhs rhs: u8) : u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs - -let bitwise_and_with_constant (vector: u8) (constant: i16) : u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_and_si256 vector - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant <: u8) - -let multiply_by_constant (vector: u8) (constant: i16) : u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 vector - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant <: u8) - -let shift_left (v_SHIFT_BY: i32) (vector: u8) : u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi16 v_SHIFT_BY vector - -let shift_right (v_SHIFT_BY: i32) (vector: u8) : u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 v_SHIFT_BY vector - -/// See Section 3.2 of the implementation notes document for an explanation -/// of this code. -let barrett_reduce (vector: u8) : u8 = - let t:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 vector - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 v_BARRETT_MULTIPLIER <: u8) - in - let t:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 t - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 512s <: u8) - in - let quotient:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 10l t in - let quotient_times_field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 quotient - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - - <: - u8) - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 vector quotient_times_field_modulus - -let cond_subtract_3329_ (vector: u8) : u8 = - let field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - in - let vv_minus_field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 vector field_modulus - in - let sign_mask:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 15l vv_minus_field_modulus - in - let conditional_add_field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_and_si256 sign_mask field_modulus - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 vv_minus_field_modulus - conditional_add_field_modulus - -let montgomery_multiply_by_constant (vector: u8) (constant: i16) : u8 = - let constant:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant in - let value_low:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 vector constant - in - let k:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 value_low - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R - <: - u32) - <: - i16) - <: - u8) - in - let k_times_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - - <: - u8) - in - let value_high:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 vector constant - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus - -let montgomery_multiply_by_constants (v c: u8) : u8 = - let value_low:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 v c in - let k:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 value_low - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R - <: - u32) - <: - i16) - <: - u8) - in - let k_times_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - - <: - u8) - in - let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 v c in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus - -let montgomery_reduce_i32s (v: u8) : u8 = - let k:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 v - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R - <: - u32) - <: - i32) - <: - u8) - in - let k_times_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_FIELD_MODULUS - <: - i16) - <: - i32) - <: - u8) - in - let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srli_epi32 16l v in - let result:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus - in - let result:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi32 16l result in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi32 16l result - -let sub (lhs rhs: u8) : u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 lhs rhs - -let montgomery_multiply_m128i_by_constants (v c: u8) : u8 = - let value_low:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mullo_epi16 v c in - let k:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mullo_epi16 value_low - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R - <: - u32) - <: - i16) - <: - u8) - in - let k_times_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mulhi_epi16 k - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - <: - u8) - in - let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mulhi_epi16 v c in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 value_high k_times_modulus diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst deleted file mode 100644 index 252e284a9..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst +++ /dev/null @@ -1,192 +0,0 @@ -module Libcrux_polynomials_avx2.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -let decompress_ciphertext_coefficient (v_COEFFICIENT_BITS: i32) (vector: u8) : u8 = - let field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_FIELD_MODULUS - <: - i16) - <: - i32) - in - let two_pow_coefficient_bits:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (1l <=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_castsi128_si256 (vector: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_castsi256_si128 (vector: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_cmpgt_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_cvtepi16_epi32 (vector: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_extracti128_si256 (v_CONTROL: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_CONTROL =. 0l <: bool) || (v_CONTROL =. 1l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL == 0 || CONTROL == 1" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_inserti128_si256 (v_CONTROL: i32) (vector vector_i128: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_CONTROL =. 0l <: bool) || (v_CONTROL =. 1l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL == 0 || CONTROL == 1" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_loadu_si256 (input: t_Slice i16) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - match Core.Slice.impl__len input, sz 16 <: (usize & usize) with - | left_val, right_val -> - if ~.(left_val =. right_val <: bool) - then - let kind:Core.Panicking.t_AssertKind = - Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind - in - Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind - left_val - right_val - (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_madd_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_mul_epu32 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_mulhi_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_mullo_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_mullo_epi32 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_packs_epi32 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_permute4x64_epi64 (v_CONTROL: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_CONTROL >=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_permutevar8x32_epi32 (vector control: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_set1_epi16 (constant: i16) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_set1_epi32 (constant: i32) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_set_epi16 - (input15 input14 input13 input12 input11 input10 input9 input8 input7 input6 input5 input4 input3 input2 input1 input0: - i16) - : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_set_epi32 (input7 input6 input5 input4 input3 input2 input1 input0: i32) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_set_epi8 - (byte31 byte30 byte29 byte28 byte27 byte26 byte25 byte24 byte23 byte22 byte21 byte20 byte19 byte18 byte17 byte16 byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: - i8) - : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_setzero_si256 (_: Prims.unit) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_shuffle_epi32 (v_CONTROL: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_CONTROL >=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_shuffle_epi8 (vector control: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_slli_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_slli_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_sllv_epi32 (vector counts: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_srai_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_srai_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_srli_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_srli_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_srli_epi64 (v_SHIFT_BY: i32) (vector: u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 64l <: bool)) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 64" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_storeu_si256 (output: t_Slice i16) (vector: u8) : t_Slice i16 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - match Core.Slice.impl__len output, sz 16 <: (usize & usize) with - | left_val, right_val -> - if ~.(left_val =. right_val <: bool) - then - let kind:Core.Panicking.t_AssertKind = - Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind - in - Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind - left_val - right_val - (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) - in - () - in - let hax_temp_output:Prims.unit = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - in - output - -let mm256_sub_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_unpackhi_epi32 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_unpackhi_epi64 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_unpacklo_epi32 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm256_xor_si256 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_add_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_loadu_si128 (input: t_Slice u8) : u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - match Core.Slice.impl__len input, sz 16 <: (usize & usize) with - | left_val, right_val -> - if ~.(left_val =. right_val <: bool) - then - let kind:Core.Panicking.t_AssertKind = - Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind - in - Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind - left_val - right_val - (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) - in - () - in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_movemask_epi8 (vector: u8) : i32 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_mulhi_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_mullo_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_packs_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_set1_epi16 (constant: i16) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_set_epi8 - (byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: - u8) - : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_shuffle_epi8 (vector control: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - -let mm_storeu_bytes_si128 (output: t_Slice u8) (vector: u8) : t_Slice u8 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - match Core.Slice.impl__len output, sz 16 <: (usize & usize) with - | left_val, right_val -> - if ~.(left_val =. right_val <: bool) - then - let kind:Core.Panicking.t_AssertKind = - Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind - in - Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind - left_val - right_val - (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) - in - () - in - let hax_temp_output:Prims.unit = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - in - output - -let mm_storeu_si128 (output: t_Slice i16) (vector: u8) : t_Slice i16 = - let _:Prims.unit = - if true - then - let _:Prims.unit = - match Core.Slice.impl__len output, sz 8 <: (usize & usize) with - | left_val, right_val -> - if ~.(left_val =. right_val <: bool) - then - let kind:Core.Panicking.t_AssertKind = - Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind - in - Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind - left_val - right_val - (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) - in - () - in - let hax_temp_output:Prims.unit = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) - in - output - -let mm_sub_epi16 (lhs rhs: u8) : u8 = - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" - <: - Rust_primitives.Hax.t_Never) diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst deleted file mode 100644 index 5b788b5ad..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst +++ /dev/null @@ -1,192 +0,0 @@ -module Libcrux_polynomials_avx2.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -let ntt_multiply__PERMUTE_WITH: i32 = 216l - -let inv_ntt_layer_1_step (vector: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 245l vector in - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 160l vector in - let rhs:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 rhs - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (-1s) (-1s) 1s 1s (-1s) (-1s) - 1s 1s (-1s) (-1s) 1s 1s (-1s) (-1s) 1s 1s - <: - u8) - in - let sum:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs in - let sum_times_zetas:u8 = - Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants sum - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 zeta3 zeta3 0s 0s zeta2 zeta2 - 0s 0s zeta1 zeta1 0s 0s zeta0 zeta0 0s 0s - <: - u8) - in - let sum:u8 = Libcrux_polynomials_avx2.Arithmetic.barrett_reduce sum in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 204l sum sum_times_zetas - -let inv_ntt_layer_2_step (vector: u8) (zeta0 zeta1: i16) : u8 = - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 245l vector in - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 160l vector in - let rhs:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 rhs - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (-1s) (-1s) (-1s) (-1s) 1s 1s - 1s 1s (-1s) (-1s) (-1s) (-1s) 1s 1s 1s 1s - <: - u8) - in - let sum:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs in - let sum_times_zetas:u8 = - Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants sum - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 zeta1 zeta1 zeta1 zeta1 0s 0s - 0s 0s zeta0 zeta0 zeta0 zeta0 0s 0s 0s 0s - <: - u8) - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 240l sum sum_times_zetas - -let inv_ntt_layer_3_step (vector: u8) (zeta: i16) : u8 = - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l vector in - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 vector in - let lower_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_add_epi16 lhs rhs in - let upper_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 lhs rhs in - let upper_coefficients:u8 = - Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_m128i_by_constants upper_coefficients - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 zeta <: u8) - in - let combined:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi128_si256 lower_coefficients - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_inserti128_si256 1l - combined - upper_coefficients - -let ntt_layer_1_step (vector: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = - let zetas:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta3 - <: - i16) (Core.Ops.Arith.Neg.neg zeta3 <: i16) zeta3 zeta3 (Core.Ops.Arith.Neg.neg zeta2 <: i16) - (Core.Ops.Arith.Neg.neg zeta2 <: i16) zeta2 zeta2 (Core.Ops.Arith.Neg.neg zeta1 <: i16) - (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 (Core.Ops.Arith.Neg.neg zeta0 <: i16) - (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 - in - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 245l vector in - let rhs:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas in - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 160l vector in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs - -let ntt_layer_2_step (vector: u8) (zeta0 zeta1: i16) : u8 = - let zetas:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta1 - <: - i16) (Core.Ops.Arith.Neg.neg zeta1 <: i16) (Core.Ops.Arith.Neg.neg zeta1 <: i16) - (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 zeta1 zeta1 - (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) - (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 zeta0 - zeta0 - in - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 238l vector in - let rhs:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas in - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 68l vector in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs - -let ntt_layer_3_step (vector: u8) (zeta: i16) : u8 = - let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l vector in - let rhs:u8 = - Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_m128i_by_constants rhs - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 zeta <: u8) - in - let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 vector in - let lower_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_add_epi16 lhs rhs in - let upper_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 lhs rhs in - let combined:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi128_si256 lower_coefficients - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_inserti128_si256 1l - combined - upper_coefficients - -let ntt_multiply (lhs rhs: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = - let shuffle_with:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi8 15y 14y 11y 10y 7y 6y 3y 2y 13y - 12y 9y 8y 5y 4y 1y 0y 15y 14y 11y 10y 7y 6y 3y 2y 13y 12y 9y 8y 5y 4y 1y 0y - in - let lhs_shuffled:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 lhs shuffle_with - in - let lhs_shuffled:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 216l lhs_shuffled - in - let lhs_evens:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 lhs_shuffled - in - let lhs_evens:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 lhs_evens - in - let lhs_odds:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l lhs_shuffled - in - let lhs_odds:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 lhs_odds in - let rhs_shuffled:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 rhs shuffle_with - in - let rhs_shuffled:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 216l rhs_shuffled - in - let rhs_evens:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 rhs_shuffled - in - let rhs_evens:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 rhs_evens - in - let rhs_odds:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l rhs_shuffled - in - let rhs_odds:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 rhs_odds in - let left:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 lhs_evens rhs_evens - in - let right:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 lhs_odds rhs_odds - in - let right:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s right in - let right:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 right - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi32 (Core.Ops.Arith.Neg.neg (cast ( - zeta3 <: i16) - <: - i32) - <: - i32) - (cast (zeta3 <: i16) <: i32) - (Core.Ops.Arith.Neg.neg (cast (zeta2 <: i16) <: i32) <: i32) - (cast (zeta2 <: i16) <: i32) - (Core.Ops.Arith.Neg.neg (cast (zeta1 <: i16) <: i32) <: i32) - (cast (zeta1 <: i16) <: i32) - (Core.Ops.Arith.Neg.neg (cast (zeta0 <: i16) <: i32) <: i32) - (cast (zeta0 <: i16) <: i32) - <: - u8) - in - let products_left:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi32 left right - in - let products_left:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s products_left in - let rhs_adjacent_swapped:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 rhs - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi8 13y 12y 15y 14y 9y 8y 11y 10y - 5y 4y 7y 6y 1y 0y 3y 2y 13y 12y 15y 14y 9y 8y 11y 10y 5y 4y 7y 6y 1y 0y 3y 2y - <: - u8) - in - let products_right:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_madd_epi16 lhs rhs_adjacent_swapped - in - let products_right:u8 = - Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s products_right - in - let products_right:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi32 16l products_right - in - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 170l products_left products_right diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst deleted file mode 100644 index 541e25541..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst +++ /dev/null @@ -1,429 +0,0 @@ -module Libcrux_polynomials_avx2.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -unfold -let t_FieldElement = i16 - -type t_PortableVector = { f_elements:t_Array i16 (sz 16) } - -let from_i16_array (array: t_Array i16 (sz 16)) : t_PortableVector = - { f_elements = array } <: t_PortableVector - -let serialize_11_ (v: t_PortableVector) : t_Array u8 (sz 22) = - let result:t_Array u8 (sz 22) = Rust_primitives.Hax.repeat 0uy (sz 22) in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 0) - (cast (v.f_elements.[ sz 0 ] <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 1) - (((cast ((v.f_elements.[ sz 1 ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 2) - (((cast ((v.f_elements.[ sz 2 ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 3) - (cast (((v.f_elements.[ sz 2 ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 4) - (((cast ((v.f_elements.[ sz 3 ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 5) - (((cast ((v.f_elements.[ sz 4 ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 6) - (((cast ((v.f_elements.[ sz 5 ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 7) - (cast (((v.f_elements.[ sz 5 ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 8) - (((cast ((v.f_elements.[ sz 6 ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 9) - (((cast ((v.f_elements.[ sz 7 ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 10) - (cast ((v.f_elements.[ sz 7 ] <: i16) >>! 3l <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 11) - (cast (v.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 12) - (((cast ((v.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 13) - (((cast ((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 14) - (cast (((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 15) - (((cast ((v.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 16) - (((cast ((v.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 17) - (((cast ((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 18) - (cast (((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 19) - (((cast ((v.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 20) - (((cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) - <: - u8) - in - let result:t_Array u8 (sz 22) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - (sz 21) - (cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) >>! 3l <: i16) <: u8) - in - result - -let to_i16_array (v: t_PortableVector) : t_Array i16 (sz 16) = v.f_elements - -let zero (_: Prims.unit) : t_PortableVector = - { f_elements = Rust_primitives.Hax.repeat 0s (sz 16) } <: t_PortableVector - -let deserialize_11_ (bytes: t_Slice u8) : t_PortableVector = - let result:t_PortableVector = zero () in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 0) - ((((cast (bytes.[ sz 1 ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 2) - (((((cast (bytes.[ sz 4 ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 3) - ((((cast (bytes.[ sz 5 ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 4) - ((((cast (bytes.[ sz 6 ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 5) - (((((cast (bytes.[ sz 8 ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 6) - ((((cast (bytes.[ sz 9 ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 7) - (((cast (bytes.[ sz 10 ] <: u8) <: i16) <>! 5l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 8) - ((((cast (bytes.[ sz 11 +! sz 1 <: usize ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 10) - (((((cast (bytes.[ sz 11 +! sz 4 <: usize ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 11) - ((((cast (bytes.[ sz 11 +! sz 5 <: usize ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 12) - ((((cast (bytes.[ sz 11 +! sz 6 <: usize ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 13) - (((((cast (bytes.[ sz 11 +! sz 8 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 14) - ((((cast (bytes.[ sz 11 +! sz 9 <: usize ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) - <: - i16) - } - <: - t_PortableVector - in - let result:t_PortableVector = - { - result with - f_elements - = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements - (sz 15) - (((cast (bytes.[ sz 11 +! sz 10 <: usize ] <: u8) <: i16) <>! 5l <: i16) - <: - i16) - } - <: - t_PortableVector - in - result diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst deleted file mode 100644 index 65ce23750..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst +++ /dev/null @@ -1,2111 +0,0 @@ -module Libcrux_polynomials_avx2.Sampling -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -let v_REJECTION_SAMPLE_SHUFFLE_TABLE: t_Array (t_Array u8 (sz 16)) (sz 256) = - let list = - [ - (let list = - [ - 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; - 255uy; 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [ - 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; - 255uy - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - (let list = - [2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list); - let list = - [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); - Rust_primitives.Hax.array_of_list 16 list - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 256); - Rust_primitives.Hax.array_of_list 256 list - -let rejection_sample (input: t_Slice u8) (output: t_Slice i16) : (t_Slice i16 & usize) = - let field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS - in - let potential_coefficients:u8 = Libcrux_polynomials_avx2.Serialize.deserialize_12_ input in - let compare_with_field_modulus:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cmpgt_epi16 field_modulus - potential_coefficients - in - let good:t_Array u8 (sz 2) = - Libcrux_polynomials_avx2.Serialize.serialize_1_ compare_with_field_modulus - in - let lower_shuffles:t_Array u8 (sz 16) = - v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 0 ] <: u8) <: usize ] - in - let lower_shuffles:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_loadu_si128 (Rust_primitives.unsize lower_shuffles - - <: - t_Slice u8) - in - let lower_coefficients:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 potential_coefficients - in - let lower_coefficients:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_shuffle_epi8 lower_coefficients lower_shuffles - in - let output:t_Slice i16 = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range output - ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } - <: - Core.Ops.Range.t_Range usize) - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_storeu_si128 (output.[ { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 8 - } - <: - Core.Ops.Range.t_Range usize ] - <: - t_Slice i16) - lower_coefficients - <: - t_Slice i16) - in - let sampled_count:usize = - cast (Core.Num.impl__u8__count_ones (good.[ sz 0 ] <: u8) <: u32) <: usize - in - let upper_shuffles:t_Array u8 (sz 16) = - v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 1 ] <: u8) <: usize ] - in - let upper_shuffles:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_loadu_si128 (Rust_primitives.unsize upper_shuffles - - <: - t_Slice u8) - in - let upper_coefficients:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l potential_coefficients - in - let upper_coefficients:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm_shuffle_epi8 upper_coefficients upper_shuffles - in - let output:t_Slice i16 = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range output - ({ - Core.Ops.Range.f_start = sampled_count; - Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize - } - <: - Core.Ops.Range.t_Range usize) - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_storeu_si128 (output.[ { - Core.Ops.Range.f_start = sampled_count; - Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize - } - <: - Core.Ops.Range.t_Range usize ] - <: - t_Slice i16) - upper_coefficients - <: - t_Slice i16) - in - let hax_temp_output:usize = - sampled_count +! (cast (Core.Num.impl__u8__count_ones (good.[ sz 1 ] <: u8) <: u32) <: usize) - in - output, hax_temp_output <: (t_Slice i16 & usize) diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst deleted file mode 100644 index f951730a4..000000000 --- a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst +++ /dev/null @@ -1,557 +0,0 @@ -module Libcrux_polynomials_avx2.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -let deserialize_1_ (bytes: t_Slice u8) : u8 = - let coefficients:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (cast (bytes.[ sz 1 ] <: u8) - <: - i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) - (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) - (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) - (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) - (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) - (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) - (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) - (cast (bytes.[ sz 0 ] <: u8) <: i16) - in - let shift_lsb_to_msb:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (1s <>! 8l <: i32) <: u8) - in - serialized - -let serialize_10_ (vector: u8) : t_Array u8 (sz 20) = - let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in - let adjacent_2_combined:u8 = - Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_madd_epi16 vector - (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (1s < true); - f_ZERO_post = (fun (_: Prims.unit) (out: t_SIMD256Vector) -> true); - f_ZERO = (fun (_: Prims.unit) -> zero ()); - f_to_i16_array_pre = (fun (v: t_SIMD256Vector) -> true); - f_to_i16_array_post = (fun (v: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> true); - f_to_i16_array = (fun (v: t_SIMD256Vector) -> to_i16_array v); - f_from_i16_array_pre = (fun (array: t_Slice i16) -> true); - f_from_i16_array_post = (fun (array: t_Slice i16) (out: t_SIMD256Vector) -> true); - f_from_i16_array = (fun (array: t_Slice i16) -> from_i16_array array); - f_add_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); - f_add_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_add - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.add lhs.f_elements rhs.f_elements } - <: - t_SIMD256Vector); - f_sub_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); - f_sub_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_sub - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.sub lhs.f_elements rhs.f_elements } - <: - t_SIMD256Vector); - f_multiply_by_constant_pre = (fun (v: t_SIMD256Vector) (c: i16) -> true); - f_multiply_by_constant_post = (fun (v: t_SIMD256Vector) (c: i16) (out: t_SIMD256Vector) -> true); - f_multiply_by_constant - = - (fun (v: t_SIMD256Vector) (c: i16) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.multiply_by_constant v.f_elements c } - <: - t_SIMD256Vector); - f_bitwise_and_with_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); - f_bitwise_and_with_constant_post - = - (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); - f_bitwise_and_with_constant - = - (fun (vector: t_SIMD256Vector) (constant: i16) -> - { - f_elements - = - Libcrux_polynomials_avx2.Arithmetic.bitwise_and_with_constant vector.f_elements constant - } - <: - t_SIMD256Vector); - f_shift_right_pre = (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> true); - f_shift_right_post - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_shift_right - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> - { - f_elements = Libcrux_polynomials_avx2.Arithmetic.shift_right v_SHIFT_BY vector.f_elements - } - <: - t_SIMD256Vector); - f_shift_left_pre = (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> true); - f_shift_left_post - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_shift_left - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.shift_left v_SHIFT_BY vector.f_elements } - <: - t_SIMD256Vector); - f_cond_subtract_3329_pre = (fun (vector: t_SIMD256Vector) -> true); - f_cond_subtract_3329_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_cond_subtract_3329_ - = - (fun (vector: t_SIMD256Vector) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.cond_subtract_3329_ vector.f_elements } - <: - t_SIMD256Vector); - f_barrett_reduce_pre = (fun (vector: t_SIMD256Vector) -> true); - f_barrett_reduce_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_barrett_reduce - = - (fun (vector: t_SIMD256Vector) -> - { f_elements = Libcrux_polynomials_avx2.Arithmetic.barrett_reduce vector.f_elements } - <: - t_SIMD256Vector); - f_montgomery_multiply_by_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); - f_montgomery_multiply_by_constant_post - = - (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); - f_montgomery_multiply_by_constant - = - (fun (vector: t_SIMD256Vector) (constant: i16) -> - { - f_elements - = - Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constant vector.f_elements - constant - } - <: - t_SIMD256Vector); - f_compress_1_pre = (fun (vector: t_SIMD256Vector) -> true); - f_compress_1_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_compress_1_ - = - (fun (vector: t_SIMD256Vector) -> - { - f_elements - = - Libcrux_polynomials_avx2.Compress.compress_message_coefficient vector.f_elements - } - <: - t_SIMD256Vector); - f_compress_pre = (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); - f_compress_post - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_compress - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - { - f_elements - = - Libcrux_polynomials_avx2.Compress.compress_ciphertext_coefficient v_COEFFICIENT_BITS - vector.f_elements - } - <: - t_SIMD256Vector); - f_decompress_ciphertext_coefficient_pre - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); - f_decompress_ciphertext_coefficient_post - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_decompress_ciphertext_coefficient - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - { - f_elements - = - Libcrux_polynomials_avx2.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS - vector.f_elements - } - <: - t_SIMD256Vector); - f_ntt_layer_1_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); - f_ntt_layer_1_step_post - = - (fun - (vector: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - true); - f_ntt_layer_1_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - { - f_elements - = - Libcrux_polynomials_avx2.Ntt.ntt_layer_1_step vector.f_elements zeta0 zeta1 zeta2 zeta3 - } - <: - t_SIMD256Vector); - f_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); - f_ntt_layer_2_step_post - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); - f_ntt_layer_2_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - { f_elements = Libcrux_polynomials_avx2.Ntt.ntt_layer_2_step vector.f_elements zeta0 zeta1 } - <: - t_SIMD256Vector); - f_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); - f_ntt_layer_3_step_post - = - (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); - f_ntt_layer_3_step - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - { f_elements = Libcrux_polynomials_avx2.Ntt.ntt_layer_3_step vector.f_elements zeta } - <: - t_SIMD256Vector); - f_inv_ntt_layer_1_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); - f_inv_ntt_layer_1_step_post - = - (fun - (vector: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - true); - f_inv_ntt_layer_1_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - { - f_elements - = - Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_1_step vector.f_elements - zeta0 - zeta1 - zeta2 - zeta3 - } - <: - t_SIMD256Vector); - f_inv_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); - f_inv_ntt_layer_2_step_post - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); - f_inv_ntt_layer_2_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - { - f_elements - = - Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_2_step vector.f_elements zeta0 zeta1 - } - <: - t_SIMD256Vector); - f_inv_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); - f_inv_ntt_layer_3_step_post - = - (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); - f_inv_ntt_layer_3_step - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - { f_elements = Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_3_step vector.f_elements zeta } - <: - t_SIMD256Vector); - f_ntt_multiply_pre - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - true); - f_ntt_multiply_post - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - true); - f_ntt_multiply - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - { - f_elements - = - Libcrux_polynomials_avx2.Ntt.ntt_multiply lhs.f_elements - rhs.f_elements - zeta0 - zeta1 - zeta2 - zeta3 - } - <: - t_SIMD256Vector); - f_serialize_1_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_1_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 2)) -> true); - f_serialize_1_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_1_ vector.f_elements); - f_deserialize_1_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_1_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_1_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_1_ bytes } <: t_SIMD256Vector); - f_serialize_4_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_4_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 8)) -> true); - f_serialize_4_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_4_ vector.f_elements); - f_deserialize_4_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_4_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_4_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_4_ bytes } <: t_SIMD256Vector); - f_serialize_5_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_5_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 10)) -> true); - f_serialize_5_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_5_ vector.f_elements); - f_deserialize_5_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_5_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_5_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_5_ bytes } <: t_SIMD256Vector); - f_serialize_10_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_10_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 20)) -> true); - f_serialize_10_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_10_ vector.f_elements); - f_deserialize_10_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_10_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_10_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_10_ bytes } <: t_SIMD256Vector - ); - f_serialize_11_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_11_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 22)) -> true); - f_serialize_11_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_11_ vector.f_elements); - f_deserialize_11_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_11_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_11_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_11_ bytes } <: t_SIMD256Vector - ); - f_serialize_12_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_12_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 24)) -> true); - f_serialize_12_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_polynomials_avx2.Serialize.serialize_12_ vector.f_elements); - f_deserialize_12_pre = (fun (bytes: t_Slice u8) -> true); - f_deserialize_12_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_12_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_12_ bytes } <: t_SIMD256Vector - ); - f_rej_sample_pre = (fun (input: t_Slice u8) (output: t_Slice i16) -> true); - f_rej_sample_post - = - (fun (input: t_Slice u8) (output: t_Slice i16) (out1: (t_Slice i16 & usize)) -> true); - f_rej_sample - = - fun (input: t_Slice u8) (output: t_Slice i16) -> - let tmp0, out:(t_Slice i16 & usize) = - Libcrux_polynomials_avx2.Sampling.rejection_sample input output - in - let output:t_Slice i16 = tmp0 in - let hax_temp_output:usize = out in - output, hax_temp_output <: (t_Slice i16 & usize) - } diff --git a/polynomials-avx2/src/sampling.rs b/polynomials-avx2/src/sampling.rs deleted file mode 100644 index b4de11b48..000000000 --- a/polynomials-avx2/src/sampling.rs +++ /dev/null @@ -1,814 +0,0 @@ -use crate::{ - serialize::{deserialize_12, serialize_1}, - *, -}; - -use libcrux_traits::FIELD_MODULUS; - -const REJECTION_SAMPLE_SHUFFLE_TABLE: [[u8; 16]; 256] = [ - [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, - ], // 0 - [ - 0, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 1 - [ - 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 2 - [ - 0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 3 - [ - 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 4 - [ - 0, 1, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 5 - [ - 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 6 - [ - 0, 1, 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 7 - [ - 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 8 - [ - 0, 1, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 9 - [ - 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 10 - [ - 0, 1, 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 11 - [ - 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 12 - [ - 0, 1, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 13 - [ - 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 14 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 15 - [ - 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 16 - [ - 0, 1, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 17 - [ - 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 18 - [ - 0, 1, 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 19 - [ - 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 20 - [ - 0, 1, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 21 - [ - 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 22 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 23 - [ - 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 24 - [ - 0, 1, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 25 - [ - 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 26 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 27 - [ - 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 28 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 29 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 30 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 31 - [ - 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 32 - [ - 0, 1, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 33 - [ - 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 34 - [ - 0, 1, 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 35 - [ - 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 36 - [ - 0, 1, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 37 - [ - 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 38 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 39 - [ - 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 40 - [ - 0, 1, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 41 - [ - 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 42 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 43 - [ - 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 44 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 45 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 46 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 47 - [ - 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 48 - [ - 0, 1, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 49 - [ - 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 50 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 51 - [ - 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 52 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 53 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 54 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 55 - [ - 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 56 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 57 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 58 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 59 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 60 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 61 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 62 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff], // 63 - [ - 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 64 - [ - 0, 1, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 65 - [ - 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 66 - [ - 0, 1, 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 67 - [ - 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 68 - [ - 0, 1, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 69 - [ - 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 70 - [ - 0, 1, 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 71 - [ - 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 72 - [ - 0, 1, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 73 - [ - 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 74 - [ - 0, 1, 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 75 - [ - 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 76 - [ - 0, 1, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 77 - [ - 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 78 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 79 - [ - 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 80 - [ - 0, 1, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 81 - [ - 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 82 - [ - 0, 1, 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 83 - [ - 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 84 - [ - 0, 1, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 85 - [ - 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 86 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 87 - [ - 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 88 - [ - 0, 1, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 89 - [ - 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 90 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 91 - [ - 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 92 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 93 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 94 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff], // 95 - [ - 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 96 - [ - 0, 1, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 97 - [ - 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 98 - [ - 0, 1, 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 99 - [ - 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 100 - [ - 0, 1, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 101 - [ - 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 102 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 103 - [ - 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 104 - [ - 0, 1, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 105 - [ - 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 106 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 107 - [ - 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 108 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 109 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 110 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 111 - [ - 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 112 - [ - 0, 1, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 113 - [ - 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 114 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 115 - [ - 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 116 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 117 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 118 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 119 - [ - 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 120 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 121 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 122 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 123 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 124 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 125 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, - ], // 126 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff], // 127 - [ - 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 128 - [ - 0, 1, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 129 - [ - 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 130 - [ - 0, 1, 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 131 - [ - 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 132 - [ - 0, 1, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 133 - [ - 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 134 - [ - 0, 1, 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 135 - [ - 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 136 - [ - 0, 1, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 137 - [ - 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 138 - [ - 0, 1, 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 139 - [ - 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 140 - [ - 0, 1, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 141 - [ - 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 142 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 143 - [ - 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 144 - [ - 0, 1, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 145 - [ - 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 146 - [ - 0, 1, 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 147 - [ - 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 148 - [ - 0, 1, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 149 - [ - 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 150 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 151 - [ - 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 152 - [ - 0, 1, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 153 - [ - 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 154 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 155 - [ - 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 156 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 157 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 158 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff], // 159 - [ - 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 160 - [ - 0, 1, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 161 - [ - 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 162 - [ - 0, 1, 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 163 - [ - 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 164 - [ - 0, 1, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 165 - [ - 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 166 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 167 - [ - 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 168 - [ - 0, 1, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 169 - [ - 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 170 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 171 - [ - 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 172 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 173 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 174 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 175 - [ - 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 176 - [ - 0, 1, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 177 - [ - 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 178 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 179 - [ - 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 180 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 181 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 182 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 183 - [ - 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 184 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 185 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 186 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 187 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 188 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 189 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 190 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff], // 191 - [ - 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 192 - [ - 0, 1, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 193 - [ - 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 194 - [ - 0, 1, 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 195 - [ - 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 196 - [ - 0, 1, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 197 - [ - 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 198 - [ - 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 199 - [ - 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 200 - [ - 0, 1, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 201 - [ - 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 202 - [ - 0, 1, 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 203 - [ - 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 204 - [ - 0, 1, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 205 - [ - 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 206 - [ - 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 207 - [ - 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 208 - [ - 0, 1, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 209 - [ - 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 210 - [ - 0, 1, 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 211 - [ - 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 212 - [ - 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 213 - [ - 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 214 - [ - 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 215 - [ - 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 216 - [ - 0, 1, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 217 - [ - 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 218 - [ - 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 219 - [ - 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 220 - [ - 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 221 - [ - 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 222 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff], // 223 - [ - 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 224 - [ - 0, 1, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 225 - [ - 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 226 - [ - 0, 1, 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 227 - [ - 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 228 - [ - 0, 1, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 229 - [ - 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 230 - [ - 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 231 - [ - 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 232 - [ - 0, 1, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 233 - [ - 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 234 - [ - 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 235 - [ - 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 236 - [ - 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 237 - [ - 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 238 - [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 239 - [ - 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 240 - [ - 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 241 - [ - 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 242 - [ - 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 243 - [ - 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 244 - [ - 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 245 - [ - 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 246 - [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 247 - [ - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], // 248 - [ - 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 249 - [ - 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 250 - [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 251 - [ - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, - ], // 252 - [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 253 - [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 254 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // 255 -]; - -#[inline(always)] -pub(crate) fn rejection_sample(input: &[u8], output: &mut [i16]) -> usize { - let field_modulus = mm256_set1_epi16(FIELD_MODULUS); - - // The input bytes can be interpreted as a sequence of serialized - // 12-bit (i.e. uncompressed) coefficients. Not all coefficients may be - // less than FIELD_MODULUS though. - let potential_coefficients = deserialize_12(input); - - // Suppose we view |potential_coefficients| as follows (grouping 64-bit elements): - // - // A B C D | E F G H | .... - // - // and A < 3329, D < 3329 and H < 3329, |compare_with_field_modulus| will look like: - // - // 0xFF 0 0 0xFF | 0 0 0 0xFF | ... - let compare_with_field_modulus = mm256_cmpgt_epi16(field_modulus, potential_coefficients); - - // Since every bit in each lane is either 0 or 1, we only need one bit from - // each lane in the register to tell us what coefficients to keep and what - // to throw-away. Combine all the bits (there are 16) into two bytes. - let good = serialize_1(compare_with_field_modulus); - - // Each bit (and its corresponding position) represents an element we - // want to sample. We'd like all such elements to be next to each other starting - // at index 0, so that they can be read from the vector easily. - // |REJECTION_SAMPLE_SHUFFLE_TABLE| encodes the byte-level shuffling indices - // needed to make this happen. - // - // For e.g. if good[0] = 0b0_0_0_0_0_0_1_0, we need to move the element in - // the 2-nd 16-bit lane to the first. To do this, we need the byte-level - // shuffle indices to be 2 3 X X X X ... - let lower_shuffles = REJECTION_SAMPLE_SHUFFLE_TABLE[good[0] as usize]; - - // Shuffle the lower 8 16-bits accordingly ... - let lower_shuffles = mm_loadu_si128(&lower_shuffles); - let lower_coefficients = mm256_castsi256_si128(potential_coefficients); - let lower_coefficients = mm_shuffle_epi8(lower_coefficients, lower_shuffles); - - // ... then write them out ... - mm_storeu_si128(&mut output[0..8], lower_coefficients); - - // ... and finally count the number of bits of |good[0]| so we know how many - // were actually sampled - let sampled_count = good[0].count_ones() as usize; - - // Do the same for |goood[1]| - let upper_shuffles = REJECTION_SAMPLE_SHUFFLE_TABLE[good[1] as usize]; - let upper_shuffles = mm_loadu_si128(&upper_shuffles); - let upper_coefficients = mm256_extracti128_si256::<1>(potential_coefficients); - let upper_coefficients = mm_shuffle_epi8(upper_coefficients, upper_shuffles); - - mm_storeu_si128( - &mut output[sampled_count..sampled_count + 8], - upper_coefficients, - ); - - sampled_count + (good[1].count_ones() as usize) -} From bc325018794e1fb6a85b951ed8a9a8bd79aea7f4 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 11 Jun 2024 11:24:09 +0200 Subject: [PATCH 53/84] re-extract F* --- .../extraction/Libcrux_intrinsics.Avx2.fsti | 199 + libcrux-ml-kem/hax.py | 97 +- .../Libcrux_ml_kem.Constant_time_ops.fst | 11 +- .../Libcrux_ml_kem.Constant_time_ops.fsti | 18 +- .../extraction/Libcrux_ml_kem.Constants.fsti | 22 +- .../Libcrux_ml_kem.Hash_functions.Avx2.fsti | 37 +- .../Libcrux_ml_kem.Hash_functions.Neon.fsti | 53 +- ...ibcrux_ml_kem.Hash_functions.Portable.fsti | 61 +- .../Libcrux_ml_kem.Hash_functions.fsti | 6 +- ...rux_ml_kem.Ind_cca.Instantiations.Avx2.fst | 56 + ...ux_ml_kem.Ind_cca.Instantiations.Avx2.fsti | 37 + ...ml_kem.Ind_cca.Instantiations.Portable.fst | 56 + ...l_kem.Ind_cca.Instantiations.Portable.fsti | 37 + .../Libcrux_ml_kem.Ind_cca.Multiplexing.fst | 116 + .../Libcrux_ml_kem.Ind_cca.Multiplexing.fsti | 33 + .../extraction/Libcrux_ml_kem.Ind_cca.fst | 407 +- .../extraction/Libcrux_ml_kem.Ind_cca.fsti | 69 +- .../extraction/Libcrux_ml_kem.Ind_cpa.fst | 286 +- .../extraction/Libcrux_ml_kem.Ind_cpa.fsti | 211 +- .../extraction/Libcrux_ml_kem.Invert_ntt.fst | 129 +- .../extraction/Libcrux_ml_kem.Invert_ntt.fsti | 30 +- .../extraction/Libcrux_ml_kem.Matrix.fst | 184 +- .../extraction/Libcrux_ml_kem.Matrix.fsti | 53 +- .../Libcrux_ml_kem.Mlkem1024.Avx2.fst | 44 + .../Libcrux_ml_kem.Mlkem1024.Avx2.fsti | 36 + .../Libcrux_ml_kem.Mlkem1024.Portable.fst | 44 + .../Libcrux_ml_kem.Mlkem1024.Portable.fsti | 36 + .../extraction/Libcrux_ml_kem.Mlkem1024.fst | 24 +- .../extraction/Libcrux_ml_kem.Mlkem1024.fsti | 73 +- .../Libcrux_ml_kem.Mlkem512.Avx2.fst | 42 + .../Libcrux_ml_kem.Mlkem512.Avx2.fsti | 36 + .../Libcrux_ml_kem.Mlkem512.Portable.fst | 42 + .../Libcrux_ml_kem.Mlkem512.Portable.fsti | 36 + .../extraction/Libcrux_ml_kem.Mlkem512.fst | 23 +- .../extraction/Libcrux_ml_kem.Mlkem512.fsti | 73 +- .../Libcrux_ml_kem.Mlkem768.Avx2.fst | 44 + .../Libcrux_ml_kem.Mlkem768.Avx2.fsti | 36 + .../Libcrux_ml_kem.Mlkem768.Portable.fst | 44 + .../Libcrux_ml_kem.Mlkem768.Portable.fsti | 36 + .../extraction/Libcrux_ml_kem.Mlkem768.fst | 24 +- .../extraction/Libcrux_ml_kem.Mlkem768.fsti | 79 +- .../fstar/extraction/Libcrux_ml_kem.Ntt.fst | 176 +- .../fstar/extraction/Libcrux_ml_kem.Ntt.fsti | 38 +- .../extraction/Libcrux_ml_kem.Polynomial.fst | 195 +- .../extraction/Libcrux_ml_kem.Polynomial.fsti | 72 +- .../extraction/Libcrux_ml_kem.Sampling.fst | 124 +- .../extraction/Libcrux_ml_kem.Sampling.fsti | 45 +- .../extraction/Libcrux_ml_kem.Serialize.fst | 386 +- .../extraction/Libcrux_ml_kem.Serialize.fsti | 98 +- .../Libcrux_ml_kem.Types.Index_impls.fsti | 679 +++ .../fstar/extraction/Libcrux_ml_kem.Types.fst | 18 +- .../extraction/Libcrux_ml_kem.Types.fsti | 24 +- .../fstar/extraction/Libcrux_ml_kem.Utils.fst | 42 + .../extraction/Libcrux_ml_kem.Utils.fsti | 8 + .../Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst | 150 + ...Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti | 41 + .../Libcrux_ml_kem.Vector.Avx2.Compress.fst | 178 + .../Libcrux_ml_kem.Vector.Avx2.Compress.fsti | 20 + .../Libcrux_ml_kem.Vector.Avx2.Ntt.fst | 211 + .../Libcrux_ml_kem.Vector.Avx2.Ntt.fsti | 27 + .../Libcrux_ml_kem.Vector.Avx2.Portable.fst | 423 ++ .../Libcrux_ml_kem.Vector.Avx2.Portable.fsti | 23 + .../Libcrux_ml_kem.Vector.Avx2.Sampling.fst | 78 + .../Libcrux_ml_kem.Vector.Avx2.Sampling.fsti | 7 + .../Libcrux_ml_kem.Vector.Avx2.Serialize.fst | 537 ++ .../Libcrux_ml_kem.Vector.Avx2.Serialize.fsti | 40 + .../extraction/Libcrux_ml_kem.Vector.Avx2.fst | 17 + .../Libcrux_ml_kem.Vector.Avx2.fsti | 394 ++ .../Libcrux_ml_kem.Vector.Portable.fsti | 6 + ...ibcrux_ml_kem.Vector.Rej_sample_table.fsti | 7 + .../Libcrux_ml_kem.Vector.Traits.fst | 32 + .../Libcrux_ml_kem.Vector.Traits.fsti | 202 + .../extraction/Libcrux_ml_kem.Vector.fst | 4871 +++++++++++++++++ .../extraction/Libcrux_ml_kem.Vector.fsti | 729 +++ .../Libcrux_sha3.Avx2.X4.Incremental.fsti | 46 + .../extraction/Libcrux_sha3.Avx2.X4.fsti | 15 + .../Libcrux_sha3.Generic_keccak.fst | 255 + .../Libcrux_sha3.Generic_keccak.fsti | 13 + .../Libcrux_sha3.Neon.X2.Incremental.fsti | 40 + .../extraction/Libcrux_sha3.Neon.X2.fsti | 14 + .../fstar/extraction/Libcrux_sha3.Neon.fsti | 24 + .../Libcrux_sha3.Portable.Incremental.fsti | 30 + .../extraction/Libcrux_sha3.Portable.fst | 34 + .../extraction/Libcrux_sha3.Portable.fsti | 26 + .../Libcrux_sha3.Portable_keccak.fst | 187 + .../Libcrux_sha3.Portable_keccak.fsti | 218 + .../extraction/Libcrux_sha3.Simd.Avx2.fst | 214 + .../extraction/Libcrux_sha3.Simd.Avx2.fsti | 256 + .../fstar/extraction/Libcrux_sha3.Traits.fst | 61 + .../fstar/extraction/Libcrux_sha3.Traits.fsti | 27 + .../proofs/fstar/extraction/Libcrux_sha3.fsti | 66 +- libcrux-sha3/src/generic_keccak.rs | 47 +- libcrux-sha3/src/portable_keccak.rs | 2 +- libcrux-sha3/src/simd/avx2.rs | 2 +- libcrux-sha3/src/traits.rs | 39 +- .../extraction/Libcrux_platform.X86.fsti | 51 + 96 files changed, 12947 insertions(+), 1598 deletions(-) create mode 100644 libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.Index_impls.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fst create mode 100644 libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fst create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.Incremental.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fst create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fst create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fst create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fsti create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fst create mode 100644 libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fsti create mode 100644 sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti diff --git a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2.fsti b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2.fsti new file mode 100644 index 000000000..2a049de11 --- /dev/null +++ b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2.fsti @@ -0,0 +1,199 @@ +module Libcrux_intrinsics.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +unfold +let t_Vec128 = Core.Core_arch.X86.t____m128i + +unfold +let t_Vec256 = Core.Core_arch.X86.t____m256i + +val mm256_add_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_add_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_and_si256 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_andnot_si256 (a b: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_blend_epi16 (v_CONTROL: i32) (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_castsi128_si256 (vector: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_castsi256_si128 (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_cmpgt_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_cvtepi16_epi32 (vector: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_extracti128_si256 (v_CONTROL: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_inserti128_si256 + (v_CONTROL: i32) + (vector: Core.Core_arch.X86.t____m256i) + (vector_i128: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_loadu_si256_i16 (input: t_Slice i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_loadu_si256_u8 (input: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_madd_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_mul_epu32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_mulhi_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_mullo_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_mullo_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_packs_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_permute2x128_si256 (v_IMM8: i32) (a b: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_permute4x64_epi64 (v_CONTROL: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_permutevar8x32_epi32 (vector control: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set1_epi16 (constant: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set1_epi32 (constant: i32) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set1_epi64x (a: i64) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set_epi16 + (input15 input14 input13 input12 input11 input10 input9 input8 input7 input6 input5 input4 input3 input2 input1 input0: + i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set_epi32 (input7 input6 input5 input4 input3 input2 input1 input0: i32) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_set_epi8 + (byte31 byte30 byte29 byte28 byte27 byte26 byte25 byte24 byte23 byte22 byte21 byte20 byte19 byte18 byte17 byte16 byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: + i8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_setzero_si256: Prims.unit + -> Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_shuffle_epi32 (v_CONTROL: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_shuffle_epi8 (vector control: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_slli_epi16 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_slli_epi32 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_slli_epi64 (v_LEFT: i32) (x: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_sllv_epi32 (vector counts: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_srai_epi16 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_srai_epi32 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_srli_epi16 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_srli_epi32 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_srli_epi64 (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_storeu_si256_i16 (output: t_Slice i16) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Slice i16) Prims.l_True (fun _ -> Prims.l_True) + +val mm256_storeu_si256_u8 (output: t_Slice u8) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +val mm256_sub_epi16 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_unpackhi_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_unpackhi_epi64 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_unpacklo_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_unpacklo_epi64 (a b: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm256_xor_si256 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mm_add_epi16 (lhs rhs: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_loadu_si128 (input: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_movemask_epi8 (vector: Core.Core_arch.X86.t____m128i) + : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val mm_mulhi_epi16 (lhs rhs: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_mullo_epi16 (lhs rhs: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_packs_epi16 (lhs rhs: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_set1_epi16 (constant: i16) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_set_epi8 + (byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: + u8) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_shuffle_epi8 (vector control: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val mm_storeu_bytes_si128 (output: t_Slice u8) (vector: Core.Core_arch.X86.t____m128i) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +val mm_storeu_si128 (output: t_Slice i16) (vector: Core.Core_arch.X86.t____m128i) + : Prims.Pure (t_Slice i16) Prims.l_True (fun _ -> Prims.l_True) + +val mm_sub_epi16 (lhs rhs: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/hax.py b/libcrux-ml-kem/hax.py index 4f919a746..dfe92840c 100755 --- a/libcrux-ml-kem/hax.py +++ b/libcrux-ml-kem/hax.py @@ -28,57 +28,81 @@ def shell(command, expect=0, cwd=None, env={}): class extractAction(argparse.Action): + def __call__(self, parser, args, values, option_string=None) -> None: - # Extract platform and sha3 interfaces - # include_str = "+:libcrux_sha3::** -libcrux_sha3::x4::internal::**" - # interface_include = "+!**" - # cargo_hax_into = [ - # "cargo", - # "hax", - # "into", - # "-i", - # include_str, - # "fstar", - # "--interfaces", - # interface_include, - # ] - # hax_env = {} - # shell( - # cargo_hax_into, - # cwd="../libcrux-sha3", - # env=hax_env, - # ) - - # Extract avx2 - # include_str = "+:libcrux_sha3::** -libcrux_sha3::x4::internal::**" - # interface_include = "+!**" + # Extract sha3 interfaces + includes = [ + "+:**", + "-libcrux_sha3::generic_keccak::**", + "+libcrux_sha3::generic_keccak::KeccakState", + "-libcrux_sha3::simd::**", + "-libcrux_sha3::portable_keccak::**", + "-libcrux_sha3::neon::keccakx2", + "-libcrux_sha3::portable::keccakx1", + "-libcrux_sha3::traits::internal::**", + ] + include_str = " ".join(includes) + interface_include = "+**" cargo_hax_into = [ "cargo", "hax", "into", + "-i", + include_str, "fstar", + "--interfaces", + interface_include, ] hax_env = {} shell( cargo_hax_into, - cwd="../polynomials-avx2", + cwd="../libcrux-sha3", env=hax_env, ) - # Extract ml-kem - includes = [ - "-libcrux_platform::macos_arm::*", - "+!libcrux_platform::platform::*", - "-libcrux_ml_kem::types::index_impls::**", + # Extract platform interfaces + include_str = "+:**" + interface_include = "+**" + cargo_hax_into = [ + "cargo", + "hax", + "into", + "-i", + include_str, + "fstar", + "--interfaces", + interface_include, ] - include_str = " ".join(includes) - interfaces = [ - "+*", - "-libcrux::kem::kyber::types", - "+!libcrux_platform::**", - "+!libcrux::digest::**", + hax_env = {} + shell( + cargo_hax_into, + cwd="../sys/platform", + env=hax_env, + ) + + # Extract intrinsics interfaces + include_str = "+:**" + interface_include = "+**" + cargo_hax_into = [ + "cargo", + "hax", + "into", + "-i", + include_str, + "fstar", + "--interfaces", + interface_include, ] - interface_include = " ".join(interfaces) + hax_env = {} + shell( + cargo_hax_into, + cwd="../libcrux-intrinsics", + env=hax_env, + ) + + # Extract ml-kem + include_str = "+:** -libcrux_ml_kem::types::index_impls::**" + interface_include = "+*" cargo_hax_into = [ "cargo", "hax", @@ -99,6 +123,7 @@ def __call__(self, parser, args, values, option_string=None) -> None: class proveAction(argparse.Action): + def __call__(self, parser, args, values, option_string=None) -> None: admit_env = {} if args.admit: diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst index e1d961468..410036b86 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst @@ -14,10 +14,9 @@ let is_non_zero (value: u8) = let compare_ciphertexts_in_constant_time (v_CIPHERTEXT_SIZE: usize) (lhs rhs: t_Slice u8) = let (r: u8):u8 = 0uy in let r:u8 = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_CIPHERTEXT_SIZE - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_CIPHERTEXT_SIZE } <: Core.Ops.Range.t_Range usize) <: @@ -34,7 +33,9 @@ let select_shared_secret_in_constant_time (lhs rhs: t_Slice u8) (selector: u8) = let mask:u8 = Core.Num.impl__u8__wrapping_sub (is_non_zero selector <: u8) 1uy in let out:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in let out:t_Array u8 (sz 32) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti index fa256358d..560d2964d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti @@ -3,35 +3,35 @@ module Libcrux_ml_kem.Constant_time_ops open Core open FStar.Mul -/// Return 1 if `value` is not zero and 0 otherwise. -val is_non_zero (value: u8) +/// Return 1 if the bytes of `lhs` and `rhs` do not exactly +/// match and 0 otherwise. +val compare_ciphertexts_in_constant_time (v_CIPHERTEXT_SIZE: usize) (lhs rhs: t_Slice u8) : Prims.Pure u8 Prims.l_True (ensures fun result -> let result:u8 = result in - Hax_lib.implies (value =. 0uy <: bool) + Hax_lib.implies (lhs =. rhs <: bool) (fun temp_0_ -> let _:Prims.unit = temp_0_ in result =. 0uy <: bool) && - Hax_lib.implies (value <>. 0uy <: bool) + Hax_lib.implies (lhs <>. rhs <: bool) (fun temp_0_ -> let _:Prims.unit = temp_0_ in result =. 1uy <: bool)) -/// Return 1 if the bytes of `lhs` and `rhs` do not exactly -/// match and 0 otherwise. -val compare_ciphertexts_in_constant_time (v_CIPHERTEXT_SIZE: usize) (lhs rhs: t_Slice u8) +/// Return 1 if `value` is not zero and 0 otherwise. +val is_non_zero (value: u8) : Prims.Pure u8 Prims.l_True (ensures fun result -> let result:u8 = result in - Hax_lib.implies (lhs =. rhs <: bool) + Hax_lib.implies (value =. 0uy <: bool) (fun temp_0_ -> let _:Prims.unit = temp_0_ in result =. 0uy <: bool) && - Hax_lib.implies (lhs <>. rhs <: bool) + Hax_lib.implies (value <>. 0uy <: bool) (fun temp_0_ -> let _:Prims.unit = temp_0_ in result =. 1uy <: bool)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti index 775204a6c..690228f5a 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti @@ -4,27 +4,27 @@ open Core open FStar.Mul /// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent -let v_BITS_PER_COEFFICIENT: usize = sz 12 - -/// Coefficients per ring element -let v_COEFFICIENTS_IN_RING_ELEMENT: usize = sz 256 +let v_BITS_PER_COEFFICIENT: usize = Rust_primitives.Hax.dropped_body /// Bits required per (uncompressed) ring element -let v_BITS_PER_RING_ELEMENT: usize = v_COEFFICIENTS_IN_RING_ELEMENT *! sz 12 +let v_BITS_PER_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body /// Bytes required per (uncompressed) ring element -let v_BYTES_PER_RING_ELEMENT: usize = v_BITS_PER_RING_ELEMENT /! sz 8 +let v_BYTES_PER_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body + +/// Coefficients per ring element +let v_COEFFICIENTS_IN_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = sz 32 +let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = Rust_primitives.Hax.dropped_body /// SHA3 512 digest size -let v_G_DIGEST_SIZE: usize = sz 64 +let v_G_DIGEST_SIZE: usize = Rust_primitives.Hax.dropped_body /// SHA3 256 digest size -let v_H_DIGEST_SIZE: usize = sz 32 +let v_H_DIGEST_SIZE: usize = Rust_primitives.Hax.dropped_body /// The size of an ML-KEM shared secret. -let v_SHARED_SECRET_SIZE: usize = sz 32 +let v_SHARED_SECRET_SIZE: usize = Rust_primitives.Hax.dropped_body /// Field modulus: 3329 -let v__FIELD_MODULUS: i16 = 3329s +let v__FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti index a1c8ed093..2a2d9ad5f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti @@ -6,9 +6,7 @@ open FStar.Mul /// The state. /// It's only used for SHAKE128. /// All other functions don't actually use any members. -type t_Simd256Hash = { - f_shake128_state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) Core.Core_arch.X86.t____m256i -} +type t_Simd256Hash = { f_shake128_state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 } [@@ FStar.Tactics.Typeclasses.tcinstance] let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = @@ -35,7 +33,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = = (fun (v_LEN: usize) (input: t_Slice u8) -> let digest:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in - let digest:t_Array u8 v_LEN = Libcrux_sha3.Portable.shake256 v_LEN digest input in + let digest:t_Array u8 v_LEN = Libcrux_sha3.Portable.shake256 digest input in digest); f_PRFxN_pre = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> true); f_PRFxN_post @@ -43,7 +41,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) - (out: t_Array (t_Array u8 v_LEN) v_K) + (out1: t_Array (t_Array u8 v_LEN) v_K) -> true); f_PRFxN @@ -62,7 +60,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = in () in - Libcrux_sha3.Avx2.X4.shake256xN v_LEN v_K input); + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K + in + let _:Prims.unit = "failure" in + out); f_shake128_init_absorb_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); f_shake128_init_absorb_post = @@ -83,9 +85,10 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = in () in - let state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) Core.Core_arch.X86.t____m256i = - Libcrux_sha3.Avx2.X4.Incremental.shake128_absorb_finalxN v_K input + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = + Libcrux_sha3.Avx2.X4.Incremental.shake128_init () in + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = "failure" in { f_shake128_state = state } <: t_Simd256Hash); f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd256Hash) -> true); f_shake128_squeeze_three_blocks_post @@ -107,12 +110,12 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = in () in - let tmp0, out:(Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) - Core.Core_arch.X86.t____m256i & - t_Array (t_Array u8 (sz 504)) v_K) = - Libcrux_sha3.Avx2.X4.Incremental.shake128_squeeze3xN (sz 504) v_K self.f_shake128_state + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 504) <: t_Array u8 (sz 504) + ) + v_K in - let self:t_Simd256Hash = { self with f_shake128_state = tmp0 } <: t_Simd256Hash in + let _:Prims.unit = "failure" in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)); f_shake128_squeeze_block_pre = (fun (self: t_Simd256Hash) -> true); @@ -135,11 +138,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = in () in - let tmp0, out:(Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) Core.Core_arch.X86.t____m256i & - t_Array (t_Array u8 (sz 168)) v_K) = - Libcrux_sha3.Avx2.X4.Incremental.shake128_squeezexN (sz 168) v_K self.f_shake128_state + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) + v_K in - let self:t_Simd256Hash = { self with f_shake128_state = tmp0 } <: t_Simd256Hash in + let _:Prims.unit = "failure" in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti index 9b65ef28b..73dfe8d29 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti @@ -7,8 +7,7 @@ open FStar.Mul /// It's only used for SHAKE128. /// All other functions don't actually use any members. type t_Simd128Hash = { - f_shake128_state:t_Array (t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) (sz 2)) - (sz 2) + f_shake128_state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) } [@@ FStar.Tactics.Typeclasses.tcinstance] @@ -36,7 +35,13 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = = (fun (v_LEN: usize) (input: t_Slice u8) -> let digest:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in - let digest:t_Array u8 v_LEN = Libcrux_sha3.Neon.shake256 v_LEN digest input in + let dummy:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 input input digest dummy + in + let digest:t_Array u8 v_LEN = tmp0 in + let dummy:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in digest); f_PRFxN_pre = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> true); f_PRFxN_post @@ -44,7 +49,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) - (out: t_Array (t_Array u8 v_LEN) v_K) + (out1: t_Array (t_Array u8 v_LEN) v_K) -> true); f_PRFxN @@ -63,7 +68,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = in () in - Libcrux_sha3.Neon.X2.shake256xN v_LEN v_K input); + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K + in + let _:Prims.unit = "failure" in + out); f_shake128_init_absorb_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); f_shake128_init_absorb_post = @@ -84,10 +93,17 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = in () in - let state:t_Array (t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) (sz 2)) - (sz 2) = - Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_finalxN v_K input + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + let list = + [ + Libcrux_sha3.Neon.X2.Incremental.shake128_init (); + Libcrux_sha3.Neon.X2.Incremental.shake128_init () + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 2); + Rust_primitives.Hax.array_of_list 2 list in + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = "failure" in { f_shake128_state = state } <: t_Simd128Hash); f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd128Hash) -> true); f_shake128_squeeze_three_blocks_post @@ -109,18 +125,18 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = in () in - let tmp0, out:(t_Array - (t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) (sz 2)) (sz 2) & - t_Array (t_Array u8 (sz 504)) v_K) = - Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze3xN (sz 504) v_K self.f_shake128_state + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 504) <: t_Array u8 (sz 504) + ) + v_K in - let self:t_Simd128Hash = { self with f_shake128_state = tmp0 } <: t_Simd128Hash in + let _:Prims.unit = "failure" in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)); f_shake128_squeeze_block_pre = (fun (self: t_Simd128Hash) -> true); f_shake128_squeeze_block_post = - (fun (self: t_Simd128Hash) (out1: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); + (fun (self: t_Simd128Hash) (out4: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); f_shake128_squeeze_block = fun (self: t_Simd128Hash) -> @@ -137,12 +153,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = in () in - let tmp0, out:(t_Array (t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) (sz 2)) - (sz 2) & - t_Array (t_Array u8 (sz 168)) v_K) = - Libcrux_sha3.Neon.X2.Incremental.shake128_squeezexN (sz 168) v_K self.f_shake128_state + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) + v_K in - let self:t_Simd128Hash = { self with f_shake128_state = tmp0 } <: t_Simd128Hash in + let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) = "failure" in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti index 8e0d569e7..d76d909e8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti @@ -7,7 +7,7 @@ open FStar.Mul /// It's only used for SHAKE128. /// All other functions don't actually use any members. type t_PortableHash (v_K: usize) = { - f_shake128_state:t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) v_K + f_shake128_state:t_Array Libcrux_sha3.Portable.t_KeccakState1 v_K } [@@ FStar.Tactics.Typeclasses.tcinstance] @@ -35,7 +35,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K = (fun (v_LEN: usize) (input: t_Slice u8) -> let digest:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in - let digest:t_Array u8 v_LEN = Libcrux_sha3.Portable.shake256 v_LEN digest input in + let digest:t_Array u8 v_LEN = Libcrux_sha3.Portable.shake256 digest input in digest); f_PRFxN_pre = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> true); f_PRFxN_post @@ -66,10 +66,9 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K in let out:t_Array (t_Array u8 v_LEN) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -80,8 +79,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K let i:usize = i in Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out i - (Libcrux_sha3.Portable.shake256 v_LEN - (out.[ i ] <: t_Array u8 v_LEN) + (Libcrux_sha3.Portable.shake256 (out.[ i ] <: t_Array u8 v_LEN) (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 33)) <: t_Slice u8) <: t_Array u8 v_LEN) @@ -109,37 +107,34 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K in () in - let state:t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) v_K = + let state:t_Array Libcrux_sha3.Portable.t_KeccakState1 v_K = Rust_primitives.Hax.repeat (Libcrux_sha3.Portable.Incremental.shake128_init () <: - Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) + Libcrux_sha3.Portable.t_KeccakState1) v_K in - let state:t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + let state:t_Array Libcrux_sha3.Portable.t_KeccakState1 v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: Core.Ops.Range.t_Range usize) state (fun state i -> - let state:t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) v_K = - state - in + let state:t_Array Libcrux_sha3.Portable.t_KeccakState1 v_K = state in let i:usize = i in Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state i (Libcrux_sha3.Portable.Incremental.shake128_absorb_final (state.[ i ] <: - Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) + Libcrux_sha3.Portable.t_KeccakState1) (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 34)) <: t_Slice u8) <: - Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) + Libcrux_sha3.Portable.t_KeccakState1) <: - t_Array (Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) v_K) + t_Array Libcrux_sha3.Portable.t_KeccakState1 v_K) in { f_shake128_state = state } <: t_PortableHash v_K); f_shake128_squeeze_three_blocks_pre = (fun (self: t_PortableHash v_K) -> true); @@ -172,10 +167,9 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K v_K in let out, self:(t_Array (t_Array u8 (sz 504)) v_K & t_PortableHash v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -184,12 +178,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K (fun temp_0_ i -> let out, self:(t_Array (t_Array u8 (sz 504)) v_K & t_PortableHash v_K) = temp_0_ in let i:usize = i in - let tmp0, tmp1:(Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64 & - t_Array u8 (sz 504)) = + let tmp0, tmp1:(Libcrux_sha3.Portable.t_KeccakState1 & t_Array u8 (sz 504)) = Libcrux_sha3.Portable.Incremental.shake128_squeeze_first_three_blocks (self .f_shake128_state.[ i ] <: - Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) + Libcrux_sha3.Portable.t_KeccakState1) (out.[ i ] <: t_Array u8 (sz 504)) in let self:t_PortableHash v_K = @@ -241,10 +234,9 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K v_K in let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_PortableHash v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -253,12 +245,11 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K (fun temp_0_ i -> let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_PortableHash v_K) = temp_0_ in let i:usize = i in - let tmp0, tmp1:(Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64 & - t_Array u8 (sz 168)) = + let tmp0, tmp1:(Libcrux_sha3.Portable.t_KeccakState1 & t_Array u8 (sz 168)) = Libcrux_sha3.Portable.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ i ] <: - Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64) + Libcrux_sha3.Portable.t_KeccakState1) (out.[ i ] <: t_Array u8 (sz 168)) in let self:t_PortableHash v_K = diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti index 6c37b4454..9c5c2c468 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti @@ -9,7 +9,7 @@ open FStar.Mul /// - AVX2 /// - NEON /// - Portable -class t_Hash (v_Self: Type) (v_K: usize) = { +class t_Hash (v_Self: Type0) (v_K: usize) = { f_G_pre:t_Slice u8 -> bool; f_G_post:t_Slice u8 -> t_Array u8 (sz 64) -> bool; f_G:x0: t_Slice u8 @@ -51,7 +51,7 @@ class t_Hash (v_Self: Type) (v_K: usize) = { } /// The SHA3 block size. -let v_BLOCK_SIZE: usize = sz 168 +let v_BLOCK_SIZE: usize = Rust_primitives.Hax.dropped_body /// The size of 3 SHA3 blocks. -let v_THREE_BLOCKS: usize = v_BLOCK_SIZE *! sz 3 +let v_THREE_BLOCKS: usize = Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst new file mode 100644 index 000000000..1b7adcd0d --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst @@ -0,0 +1,56 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions.Avx2 in + let open Libcrux_ml_kem.Vector.Avx2 in + () + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + Libcrux_ml_kem.Ind_cca.decapsulate v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE + v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + private_key ciphertext + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE + v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR + v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + public_key randomness + +let validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + = + Libcrux_ml_kem.Ind_cca.validate_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + public_key + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + = + Libcrux_ml_kem.Ind_cca.generate_keypair v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti new file mode 100644 index 000000000..5c35e7373 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti @@ -0,0 +1,37 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Portable public key validation +val validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +/// Portable decapsulate +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Portable encapsualte +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Portable generate key pair. +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst new file mode 100644 index 000000000..e94abdbc5 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst @@ -0,0 +1,56 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions.Portable in + let open Libcrux_ml_kem.Vector in + () + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + Libcrux_ml_kem.Ind_cca.decapsulate v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE + v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + #Libcrux_ml_kem.Vector.Portable.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) private_key ciphertext + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE + v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR + v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Portable.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) public_key randomness + +let validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + = + Libcrux_ml_kem.Ind_cca.validate_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #Libcrux_ml_kem.Vector.Portable.t_PortableVector + public_key + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + = + Libcrux_ml_kem.Ind_cca.generate_keypair v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Portable.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti new file mode 100644 index 000000000..417351f41 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti @@ -0,0 +1,37 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Portable public key validation +val validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +/// Portable decapsulate +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Portable encapsualte +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Portable generate key pair. +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst new file mode 100644 index 000000000..681fc0e37 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst @@ -0,0 +1,116 @@ +module Libcrux_ml_kem.Ind_cca.Multiplexing +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.decapsulate v_K v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + private_key ciphertext + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.decapsulate v_K v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + private_key ciphertext + else + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.decapsulate v_K v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + private_key ciphertext + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE + v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE public_key randomness + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.encapsulate v_K v_CIPHERTEXT_SIZE + v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE public_key randomness + else + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.encapsulate v_K v_CIPHERTEXT_SIZE + v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE public_key randomness + +let validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + public_key + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + public_key + else + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + public_key + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.generate_keypair v_K + v_CPA_PRIVATE_KEY_SIZE + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_ETA1 + v_ETA1_RANDOMNESS_SIZE + randomness + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.generate_keypair v_K + v_CPA_PRIVATE_KEY_SIZE + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_ETA1 + v_ETA1_RANDOMNESS_SIZE + randomness + else + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.generate_keypair v_K + v_CPA_PRIVATE_KEY_SIZE + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_ETA1 + v_ETA1_RANDOMNESS_SIZE + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti new file mode 100644 index 000000000..f94109b2d --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti @@ -0,0 +1,33 @@ +module Libcrux_ml_kem.Ind_cca.Multiplexing +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +val validate_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst index 9b5b0ea1c..0b2ab9311 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst @@ -3,9 +3,17 @@ module Libcrux_ml_kem.Ind_cca open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Types in + let open Libcrux_ml_kem.Vector.Traits in + () + let serialize_kem_secret_key (v_K v_SERIALIZED_KEY_LEN: usize) - (#v_Hasher: Type) + (#v_Hasher: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -17,15 +25,16 @@ let serialize_kem_secret_key Rust_primitives.Hax.Monomorphized_update_at.update_at_range out ({ Core.Ops.Range.f_start = pointer; - Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len private_key <: usize) <: usize + Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len #u8 private_key <: usize) <: usize } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = - pointer +! (Core.Slice.impl__len private_key <: usize) <: usize + pointer +! (Core.Slice.impl__len #u8 private_key <: usize) <: usize } <: Core.Ops.Range.t_Range usize ] @@ -35,20 +44,21 @@ let serialize_kem_secret_key <: t_Slice u8) in - let pointer:usize = pointer +! (Core.Slice.impl__len private_key <: usize) in + let pointer:usize = pointer +! (Core.Slice.impl__len #u8 private_key <: usize) in let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.Monomorphized_update_at.update_at_range out ({ Core.Ops.Range.f_start = pointer; - Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len public_key <: usize) <: usize + Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len #u8 public_key <: usize) <: usize } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = - pointer +! (Core.Slice.impl__len public_key <: usize) <: usize + pointer +! (Core.Slice.impl__len #u8 public_key <: usize) <: usize } <: Core.Ops.Range.t_Range usize ] @@ -58,7 +68,7 @@ let serialize_kem_secret_key <: t_Slice u8) in - let pointer:usize = pointer +! (Core.Slice.impl__len public_key <: usize) in + let pointer:usize = pointer +! (Core.Slice.impl__len #u8 public_key <: usize) in let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.Monomorphized_update_at.update_at_range out ({ @@ -67,7 +77,8 @@ let serialize_kem_secret_key } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = pointer +! Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE <: usize } @@ -75,7 +86,7 @@ let serialize_kem_secret_key Core.Ops.Range.t_Range usize ] <: t_Slice u8) - (Rust_primitives.unsize (Libcrux_ml_kem.Hash_functions.f_H v_K public_key + (Rust_primitives.unsize (Libcrux_ml_kem.Hash_functions.f_H #v_Hasher v_K public_key <: t_Array u8 (sz 32)) <: @@ -90,15 +101,16 @@ let serialize_kem_secret_key Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = - pointer +! (Core.Slice.impl__len implicit_rejection_value <: usize) <: usize + pointer +! (Core.Slice.impl__len #u8 implicit_rejection_value <: usize) <: usize } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = - pointer +! (Core.Slice.impl__len implicit_rejection_value <: usize) <: usize + pointer +! (Core.Slice.impl__len #u8 implicit_rejection_value <: usize) <: usize } <: Core.Ops.Range.t_Range usize ] @@ -110,15 +122,18 @@ let serialize_kem_secret_key in out -let validate_public_key_generic +let validate_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) = let deserialized_pk:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Libcrux_ml_kem.Serialize.deserialize_ring_elements_reduced v_PUBLIC_KEY_SIZE v_K + #v_Vector (public_key.[ { Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } <: Core.Ops.Range.t_RangeTo usize ] @@ -129,6 +144,7 @@ let validate_public_key_generic Libcrux_ml_kem.Ind_cpa.serialize_public_key v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE + #v_Vector deserialized_pk (public_key.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } <: @@ -138,50 +154,13 @@ let validate_public_key_generic in public_key =. public_key_serialized -let validate_public_key - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) - = - Rust_primitives.Hax.Control_flow_monad.Mexception.run (if - true && true && (Libcrux_platform.Platform.simd256_support () <: bool) - then - let! hoist2:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (validate_public_key_generic v_K - v_RANKED_BYTES_PER_RING_ELEMENT - v_PUBLIC_KEY_SIZE - public_key) - <: - Core.Ops.Control_flow.t_ControlFlow bool Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist2) - <: - Core.Ops.Control_flow.t_ControlFlow bool bool - else - Core.Ops.Control_flow.ControlFlow_Continue - (if false && false && (Libcrux_platform.Platform.simd128_support () <: bool) - then - validate_public_key_generic v_K - v_RANKED_BYTES_PER_RING_ELEMENT - v_PUBLIC_KEY_SIZE - public_key - <: - bool - else - validate_public_key_generic v_K - v_RANKED_BYTES_PER_RING_ELEMENT - v_PUBLIC_KEY_SIZE - public_key - <: - bool) - <: - Core.Ops.Control_flow.t_ControlFlow bool bool) - -let decapsulate_generic +let decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -189,13 +168,15 @@ let decapsulate_generic (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = - Libcrux_ml_kem.Types.impl_12__split_at v_SECRET_KEY_SIZE private_key v_CPA_SECRET_KEY_SIZE + Core.Slice.impl__split_at #u8 + (Rust_primitives.unsize private_key.Libcrux_ml_kem.Types.f_value <: t_Slice u8) + v_CPA_SECRET_KEY_SIZE in let ind_cpa_public_key, secret_key:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at secret_key v_PUBLIC_KEY_SIZE + Core.Slice.impl__split_at #u8 secret_key v_PUBLIC_KEY_SIZE in let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE + Core.Slice.impl__split_at #u8 secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE in let decrypted:t_Array u8 (sz 32) = Libcrux_ml_kem.Ind_cpa.decrypt v_K @@ -203,21 +184,20 @@ let decapsulate_generic v_C1_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR + #v_Vector ind_cpa_secret_key ciphertext.Libcrux_ml_kem.Types.f_value in let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = - Libcrux_ml_kem.Ind_cpa.into_padded_array (sz 64) - (Rust_primitives.unsize decrypted <: t_Slice u8) + Libcrux_ml_kem.Utils.into_padded_array (sz 64) (Rust_primitives.unsize decrypted <: t_Slice u8) in let to_hash:t_Array u8 (sz 64) = Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash ({ Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE } <: Core.Ops.Range.t_RangeFrom usize) - (Core.Slice.impl__copy_from_slice (to_hash.[ { - Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE - } + (Core.Slice.impl__copy_from_slice #u8 + (to_hash.[ { Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE } <: Core.Ops.Range.t_RangeFrom usize ] <: @@ -227,15 +207,16 @@ let decapsulate_generic t_Slice u8) in let hashed:t_Array u8 (sz 64) = - Libcrux_ml_kem.Hash_functions.f_G v_K (Rust_primitives.unsize to_hash <: t_Slice u8) + Libcrux_ml_kem.Hash_functions.f_G #v_Hasher v_K (Rust_primitives.unsize to_hash <: t_Slice u8) in let shared_secret, pseudorandomness:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) + Core.Slice.impl__split_at #u8 + (Rust_primitives.unsize hashed <: t_Slice u8) Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE in let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = - Libcrux_ml_kem.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + Libcrux_ml_kem.Utils.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE implicit_rejection_value in let to_hash:t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = @@ -243,94 +224,52 @@ let decapsulate_generic ({ Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE } <: Core.Ops.Range.t_RangeFrom usize) - (Core.Slice.impl__copy_from_slice (to_hash.[ { - Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE - } + (Core.Slice.impl__copy_from_slice #u8 + (to_hash.[ { Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE } <: Core.Ops.Range.t_RangeFrom usize ] <: t_Slice u8) - (Core.Convert.f_as_ref ciphertext <: t_Slice u8) + (Core.Convert.f_as_ref #(Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + #(t_Slice u8) + ciphertext + <: + t_Slice u8) <: t_Slice u8) in let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = - Libcrux_ml_kem.Hash_functions.f_PRF v_K (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) + Libcrux_ml_kem.Hash_functions.f_PRF #v_Hasher + v_K + (sz 32) + (Rust_primitives.unsize to_hash <: t_Slice u8) in let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = Libcrux_ml_kem.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ind_cpa_public_key decrypted - pseudorandomness + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE #v_Vector #v_Hasher ind_cpa_public_key + decrypted pseudorandomness in let selector:u8 = Libcrux_ml_kem.Constant_time_ops.compare_ciphertexts_in_constant_time v_CIPHERTEXT_SIZE - (Core.Convert.f_as_ref ciphertext <: t_Slice u8) + (Core.Convert.f_as_ref #(Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + #(t_Slice u8) + ciphertext + <: + t_Slice u8) (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) in Libcrux_ml_kem.Constant_time_ops.select_shared_secret_in_constant_time shared_secret (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) selector -let decapsulate - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) - (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) - (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - = - Rust_primitives.Hax.Control_flow_monad.Mexception.run (if - true && true && (Libcrux_platform.Platform.simd256_support () <: bool) - then - let! hoist3:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (decapsulate_generic v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE - v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE - v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - v_IMPLICIT_REJECTION_HASH_INPUT_SIZE private_key ciphertext) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist3) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) (t_Array u8 (sz 32)) - else - Core.Ops.Control_flow.ControlFlow_Continue - (if false && false && (Libcrux_platform.Platform.simd128_support () <: bool) - then - let! hoist4:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (decapsulate_generic v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE - v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE - v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - v_IMPLICIT_REJECTION_HASH_INPUT_SIZE private_key ciphertext) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist4) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) (t_Array u8 (sz 32)) - else - Core.Ops.Control_flow.ControlFlow_Continue - (decapsulate_generic v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE - v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE - v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - v_IMPLICIT_REJECTION_HASH_INPUT_SIZE private_key ciphertext - <: - t_Array u8 (sz 32)) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) (t_Array u8 (sz 32))) - <: - Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) - (Core.Ops.Control_flow.t_ControlFlow (t_Array u8 (sz 32)) (t_Array u8 (sz 32)))) - -let encapsulate_generic +let encapsulate (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -338,22 +277,21 @@ let encapsulate_generic (randomness: t_Array u8 (sz 32)) = let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = - Libcrux_ml_kem.Ind_cpa.into_padded_array (sz 64) - (Rust_primitives.unsize randomness <: t_Slice u8) + Libcrux_ml_kem.Utils.into_padded_array (sz 64) (Rust_primitives.unsize randomness <: t_Slice u8) in let to_hash:t_Array u8 (sz 64) = Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash ({ Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE } <: Core.Ops.Range.t_RangeFrom usize) - (Core.Slice.impl__copy_from_slice (to_hash.[ { - Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE - } + (Core.Slice.impl__copy_from_slice #u8 + (to_hash.[ { Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE } <: Core.Ops.Range.t_RangeFrom usize ] <: t_Slice u8) - (Rust_primitives.unsize (Libcrux_ml_kem.Hash_functions.f_H v_K + (Rust_primitives.unsize (Libcrux_ml_kem.Hash_functions.f_H #v_Hasher + v_K (Rust_primitives.unsize (Libcrux_ml_kem.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE public_key <: @@ -368,16 +306,17 @@ let encapsulate_generic t_Slice u8) in let hashed:t_Array u8 (sz 64) = - Libcrux_ml_kem.Hash_functions.f_G v_K (Rust_primitives.unsize to_hash <: t_Slice u8) + Libcrux_ml_kem.Hash_functions.f_G #v_Hasher v_K (Rust_primitives.unsize to_hash <: t_Slice u8) in let shared_secret, pseudorandomness:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) + Core.Slice.impl__split_at #u8 + (Rust_primitives.unsize hashed <: t_Slice u8) Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE in let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = Libcrux_ml_kem.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE #v_Vector #v_Hasher (Rust_primitives.unsize (Libcrux_ml_kem.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE public_key <: t_Array u8 v_PUBLIC_KEY_SIZE) @@ -386,86 +325,42 @@ let encapsulate_generic in let shared_secret_array:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in let shared_secret_array:t_Array u8 (sz 32) = - Core.Slice.impl__copy_from_slice shared_secret_array shared_secret + Core.Slice.impl__copy_from_slice #u8 shared_secret_array shared_secret in - Core.Convert.f_into ciphertext, shared_secret_array + Core.Convert.f_from #(Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + #(t_Array u8 v_CIPHERTEXT_SIZE) + ciphertext, + shared_secret_array <: (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -let encapsulate - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) - (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) - (randomness: t_Array u8 (sz 32)) - = - Rust_primitives.Hax.Control_flow_monad.Mexception.run (if - true && true && (Libcrux_platform.Platform.simd256_support () <: bool) - then - let! hoist5:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (encapsulate_generic v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE - v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR - v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - public_key randomness) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist5) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - else - Core.Ops.Control_flow.ControlFlow_Continue - (if false && false && (Libcrux_platform.Platform.simd128_support () <: bool) - then - let! hoist6:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (encapsulate_generic v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE - v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR - v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - public_key randomness) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist6) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - else - Core.Ops.Control_flow.ControlFlow_Continue - (encapsulate_generic v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE - v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR - v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - public_key randomness - <: - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32))) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32))) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - (Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)))) - -let generate_keypair_generic +let generate_keypair (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (ind_cpa_keypair_randomness implicit_rejection_value: t_Slice u8) + (randomness: t_Array u8 (sz 64)) = + let ind_cpa_keypair_randomness:t_Slice u8 = + randomness.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + <: + Core.Ops.Range.t_Range usize ] + in + let implicit_rejection_value:t_Slice u8 = + randomness.[ { + Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + <: + Core.Ops.Range.t_RangeFrom usize ] + in let ind_cpa_private_key, public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) = Libcrux_ml_kem.Ind_cpa.generate_keypair v_K @@ -474,91 +369,29 @@ let generate_keypair_generic v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #v_Vector + #v_Hasher ind_cpa_keypair_randomness in let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = serialize_kem_secret_key v_K v_PRIVATE_KEY_SIZE + #v_Hasher (Rust_primitives.unsize ind_cpa_private_key <: t_Slice u8) (Rust_primitives.unsize public_key <: t_Slice u8) implicit_rejection_value in let (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE):Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = - Core.Convert.f_from secret_key_serialized + Core.Convert.f_from #(Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + #(t_Array u8 v_PRIVATE_KEY_SIZE) + secret_key_serialized in Libcrux_ml_kem.Types.impl__from v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE private_key - (Core.Convert.f_into public_key <: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) - -let generate_keypair - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) - (randomness: t_Array u8 (sz 64)) - = - Rust_primitives.Hax.Control_flow_monad.Mexception.run (let ind_cpa_keypair_randomness:t_Slice u8 = - randomness.[ { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - <: - Core.Ops.Range.t_Range usize ] - in - let implicit_rejection_value:t_Slice u8 = - randomness.[ { - Core.Ops.Range.f_start = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - <: - Core.Ops.Range.t_RangeFrom usize ] - in - if true && true && Libcrux_platform.Platform.simd256_support () - then - let! hoist7:Rust_primitives.Hax.t_Never = - Core.Ops.Control_flow.ControlFlow_Break - (generate_keypair_generic v_K - v_CPA_PRIVATE_KEY_SIZE - v_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - v_BYTES_PER_RING_ELEMENT - v_ETA1 - v_ETA1_RANDOMNESS_SIZE - ind_cpa_keypair_randomness - implicit_rejection_value) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - Rust_primitives.Hax.t_Never - in - Core.Ops.Control_flow.ControlFlow_Continue (Rust_primitives.Hax.never_to_any hoist7) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - else - Core.Ops.Control_flow.ControlFlow_Continue - (if false && false && Libcrux_platform.Platform.simd128_support () - then - generate_keypair_generic v_K - v_CPA_PRIVATE_KEY_SIZE - v_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - v_BYTES_PER_RING_ELEMENT - v_ETA1 - v_ETA1_RANDOMNESS_SIZE - ind_cpa_keypair_randomness - implicit_rejection_value - else - generate_keypair_generic v_K - v_CPA_PRIVATE_KEY_SIZE - v_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - v_BYTES_PER_RING_ELEMENT - v_ETA1 - v_ETA1_RANDOMNESS_SIZE - ind_cpa_keypair_randomness - implicit_rejection_value) - <: - Core.Ops.Control_flow.t_ControlFlow - (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE)) + (Core.Convert.f_from #(Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + #(t_Array u8 v_PUBLIC_KEY_SIZE) + public_key + <: + Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti index 0b669d301..2731071c5 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti @@ -3,91 +3,70 @@ module Libcrux_ml_kem.Ind_cca open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () + /// An ML-KEM shared secret. /// A byte array of size [`SHARED_SECRET_SIZE`]. unfold let t_MlKemSharedSecret = t_Array u8 (sz 32) /// Seed size for encapsulation -let v_ENCAPS_SEED_SIZE: usize = Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +let v_ENCAPS_SEED_SIZE: usize = Rust_primitives.Hax.dropped_body /// Seed size for key generation -let v_KEY_GENERATION_SEED_SIZE: usize = - Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +let v_KEY_GENERATION_SEED_SIZE: usize = Rust_primitives.Hax.dropped_body /// Serialize the secret key. val serialize_kem_secret_key (v_K v_SERIALIZED_KEY_LEN: usize) - (#v_Hasher: Type) + (#v_Hasher: Type0) {| i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (private_key public_key implicit_rejection_value: t_Slice u8) : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) Prims.l_True (fun _ -> Prims.l_True) -val validate_public_key_generic - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) - : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) - val validate_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) -val decapsulate_generic - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} - {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} - (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) - (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - val decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -val encapsulate_generic - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} - {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} - (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) - (randomness: t_Array u8 (sz 32)) - : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - Prims.l_True - (fun _ -> Prims.l_True) - val encapsulate (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) (randomness: t_Array u8 (sz 32)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -val generate_keypair_generic - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} - {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} - (ind_cpa_keypair_randomness implicit_rejection_value: t_Slice u8) - : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - Prims.l_True - (fun _ -> Prims.l_True) - +/// Generate a key pair. +/// Depending on the `Vector` and `Hasher` used, this requires different hardware +/// features val generate_keypair (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (randomness: t_Array u8 (sz 64)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) Prims.l_True diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst index 97b66b4f4..bf1e03308 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst @@ -3,44 +3,19 @@ module Libcrux_ml_kem.Ind_cpa open Core open FStar.Mul -let into_padded_array (v_LEN: usize) (slice: t_Slice u8) = - let _:Prims.unit = - if true - then - let _:Prims.unit = - if ~.((Core.Slice.impl__len slice <: usize) <=. v_LEN <: bool) - then - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: slice.len() <= LEN" - - <: - Rust_primitives.Hax.t_Never) - in - () - in - let out:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in - let out:t_Array u8 v_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out - ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Core.Slice.impl__len slice <: usize } - <: - Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Core.Slice.impl__len slice <: usize - } - <: - Core.Ops.Range.t_Range usize ] - <: - t_Slice u8) - slice - <: - t_Slice u8) - in - out +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () let sample_ring_element_cbd (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -48,19 +23,19 @@ let sample_ring_element_cbd (domain_separator: u8) = let error_1_:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__i -> let v__i:usize = v__i in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = Rust_primitives.Hax.repeat prf_input v_K in let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -85,13 +60,12 @@ let sample_ring_element_cbd in let (prf_outputs: t_Array (t_Array u8 v_ETA2_RANDOMNESS_SIZE) v_K):t_Array (t_Array u8 v_ETA2_RANDOMNESS_SIZE) v_K = - Libcrux_ml_kem.Hash_functions.f_PRFxN v_K v_ETA2_RANDOMNESS_SIZE prf_inputs + Libcrux_ml_kem.Hash_functions.f_PRFxN #v_Hasher v_K v_ETA2_RANDOMNESS_SIZE prf_inputs in let error_1_:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -105,6 +79,7 @@ let sample_ring_element_cbd Rust_primitives.Hax.Monomorphized_update_at.update_at_usize error_1_ i (Libcrux_ml_kem.Sampling.sample_from_binomial_distribution v_ETA2 + #v_Vector (Rust_primitives.unsize (prf_outputs.[ i ] <: t_Array u8 v_ETA2_RANDOMNESS_SIZE) <: t_Slice u8) @@ -119,8 +94,10 @@ let sample_ring_element_cbd let sample_vector_cbd_then_ntt (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -128,19 +105,19 @@ let sample_vector_cbd_then_ntt (domain_separator: u8) = let re_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__i -> let v__i:usize = v__i in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = Rust_primitives.Hax.repeat prf_input v_K in let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -165,13 +142,12 @@ let sample_vector_cbd_then_ntt in let (prf_outputs: t_Array (t_Array u8 v_ETA_RANDOMNESS_SIZE) v_K):t_Array (t_Array u8 v_ETA_RANDOMNESS_SIZE) v_K = - Libcrux_ml_kem.Hash_functions.f_PRFxN v_K v_ETA_RANDOMNESS_SIZE prf_inputs + Libcrux_ml_kem.Hash_functions.f_PRFxN #v_Hasher v_K v_ETA_RANDOMNESS_SIZE prf_inputs in let re_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -186,6 +162,7 @@ let sample_vector_cbd_then_ntt Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re_as_ntt i (Libcrux_ml_kem.Sampling.sample_from_binomial_distribution v_ETA + #v_Vector (Rust_primitives.unsize (prf_outputs.[ i ] <: t_Array u8 v_ETA_RANDOMNESS_SIZE) <: t_Slice u8) @@ -195,9 +172,8 @@ let sample_vector_cbd_then_ntt let re_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re_as_ntt i - (Libcrux_ml_kem.Ntt.ntt_binomially_sampled_ring_element (re_as_ntt.[ i ] - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + (Libcrux_ml_kem.Ntt.ntt_binomially_sampled_ring_element #v_Vector + (re_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in @@ -209,14 +185,22 @@ let sample_vector_cbd_then_ntt let compress_then_serialize_u (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (input: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) (out: t_Slice u8) = let out, hax_temp_output:t_Slice u8 = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Iter.Traits.Collect.f_into_iter input + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Array.Iter.t_IntoIter (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Array.Iter.t_IntoIter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (Core.Iter.Traits.Collect.f_into_iter #(t_Array + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + input <: Core.Array.Iter.t_IntoIter (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) @@ -241,7 +225,8 @@ let compress_then_serialize_u } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = i *! (v_OUT_LEN /! v_K <: usize) <: usize; Core.Ops.Range.f_end = @@ -254,6 +239,7 @@ let compress_then_serialize_u (Rust_primitives.unsize (Libcrux_ml_kem.Serialize.compress_then_serialize_ring_element_u v_COMPRESSION_FACTOR v_BLOCK_LEN + #v_Vector re <: t_Array u8 v_BLOCK_LEN) @@ -268,21 +254,27 @@ let compress_then_serialize_u let deserialize_then_decompress_u (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = let u_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun temp_0_ -> let _:usize = temp_0_ in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let u_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact (Rust_primitives.unsize ciphertext <: t_Slice u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 + (Rust_primitives.unsize ciphertext <: t_Slice u8) ((Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_U_COMPRESSION_FACTOR <: @@ -306,6 +298,7 @@ let deserialize_then_decompress_u Rust_primitives.Hax.Monomorphized_update_at.update_at_usize u_as_ntt i (Libcrux_ml_kem.Serialize.deserialize_then_decompress_ring_element_u v_U_COMPRESSION_FACTOR + #v_Vector u_bytes <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -314,6 +307,7 @@ let deserialize_then_decompress_u Rust_primitives.Hax.Monomorphized_update_at.update_at_usize u_as_ntt i (Libcrux_ml_kem.Ntt.ntt_vector_u v_U_COMPRESSION_FACTOR + #v_Vector (u_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -325,8 +319,10 @@ let deserialize_then_decompress_u let encrypt (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -337,6 +333,7 @@ let encrypt let tt_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Libcrux_ml_kem.Serialize.deserialize_ring_elements_reduced v_T_AS_NTT_ENCODED_SIZE v_K + #v_Vector (public_key.[ { Core.Ops.Range.f_end = v_T_AS_NTT_ENCODED_SIZE } <: Core.Ops.Range.t_RangeTo usize ] @@ -351,40 +348,53 @@ let encrypt let v_A_transpose:t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K = Libcrux_ml_kem.Matrix.sample_matrix_A v_K - (into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) + #v_Vector + #v_Hasher + (Libcrux_ml_kem.Utils.into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) false in - let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = into_padded_array (sz 33) randomness in + let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = + Libcrux_ml_kem.Utils.into_padded_array (sz 33) randomness + in let r_as_ntt, domain_separator:(t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) = - sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy + sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE #v_Vector #v_Hasher prf_input 0uy in let error_1_, domain_separator:(t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) = - sample_ring_element_cbd v_K v_ETA2_RANDOMNESS_SIZE v_ETA2 prf_input domain_separator + sample_ring_element_cbd v_K + v_ETA2_RANDOMNESS_SIZE + v_ETA2 + #v_Vector + #v_Hasher + prf_input + domain_separator in let prf_input:t_Array u8 (sz 33) = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_input (sz 32) domain_separator in let (prf_output: t_Array u8 v_ETA2_RANDOMNESS_SIZE):t_Array u8 v_ETA2_RANDOMNESS_SIZE = - Libcrux_ml_kem.Hash_functions.f_PRF v_K + Libcrux_ml_kem.Hash_functions.f_PRF #v_Hasher + v_K v_ETA2_RANDOMNESS_SIZE (Rust_primitives.unsize prf_input <: t_Slice u8) in let error_2_:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = Libcrux_ml_kem.Sampling.sample_from_binomial_distribution v_ETA2 + #v_Vector (Rust_primitives.unsize prf_output <: t_Slice u8) in let u:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Libcrux_ml_kem.Matrix.compute_vector_u v_K v_A_transpose r_as_ntt error_1_ + Libcrux_ml_kem.Matrix.compute_vector_u v_K #v_Vector v_A_transpose r_as_ntt error_1_ in let message_as_ring_element:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Serialize.deserialize_then_decompress_message message + Libcrux_ml_kem.Serialize.deserialize_then_decompress_message #v_Vector message in let v:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = Libcrux_ml_kem.Matrix.compute_ring_element_v v_K + #v_Vector tt_as_ntt r_as_ntt error_2_ @@ -400,6 +410,7 @@ let encrypt v_C1_LEN v_U_COMPRESSION_FACTOR v_BLOCK_LEN + #v_Vector u (ciphertext.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_C1_LEN } <: @@ -414,6 +425,7 @@ let encrypt ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) (Libcrux_ml_kem.Serialize.compress_then_serialize_ring_element_v v_V_COMPRESSION_FACTOR v_C2_LEN + #v_Vector v (ciphertext.[ { Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize ] <: @@ -425,21 +437,27 @@ let encrypt let deserialize_secret_key (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (secret_key: t_Slice u8) = let secret_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun temp_0_ -> let _:usize = temp_0_ in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let secret_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact secret_key + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 + secret_key Libcrux_ml_kem.Constants.v_BYTES_PER_RING_ELEMENT <: Core.Slice.Iter.t_ChunksExact u8) @@ -456,7 +474,8 @@ let deserialize_secret_key let i, secret_bytes:(usize & t_Slice u8) = temp_1_ in Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt i - (Libcrux_ml_kem.Serialize.deserialize_to_uncompressed_ring_element secret_bytes + (Libcrux_ml_kem.Serialize.deserialize_to_uncompressed_ring_element #v_Vector + secret_bytes <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: @@ -467,16 +486,19 @@ let deserialize_secret_key let decrypt (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (secret_key: t_Slice u8) (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = let u_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - deserialize_then_decompress_u v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR ciphertext + deserialize_then_decompress_u v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR #v_Vector ciphertext in let v:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = Libcrux_ml_kem.Serialize.deserialize_then_decompress_ring_element_v v_V_COMPRESSION_FACTOR + #v_Vector (ciphertext.[ { Core.Ops.Range.f_start = v_VECTOR_U_ENCODED_SIZE } <: Core.Ops.Range.t_RangeFrom usize ] @@ -484,23 +506,31 @@ let decrypt t_Slice u8) in let secret_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - deserialize_secret_key v_K secret_key + deserialize_secret_key v_K #v_Vector secret_key in let message:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Matrix.compute_message v_K v secret_as_ntt u_as_ntt + Libcrux_ml_kem.Matrix.compute_message v_K #v_Vector v secret_as_ntt u_as_ntt in - Libcrux_ml_kem.Serialize.compress_then_serialize_message message + Libcrux_ml_kem.Serialize.compress_then_serialize_message #v_Vector message let serialize_secret_key (v_K v_OUT_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (key: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) = let out:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in let out:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Iter.Traits.Collect.f_into_iter key + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Array.Iter.t_IntoIter (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Array.Iter.t_IntoIter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (Core.Iter.Traits.Collect.f_into_iter #(t_Array + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + key <: Core.Array.Iter.t_IntoIter (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) @@ -529,7 +559,8 @@ let serialize_secret_key } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { Core.Ops.Range.f_start = i *! Libcrux_ml_kem.Constants.v_BYTES_PER_RING_ELEMENT <: usize; @@ -544,6 +575,7 @@ let serialize_secret_key <: t_Slice u8) (Rust_primitives.unsize (Libcrux_ml_kem.Serialize.serialize_uncompressed_ring_element + #v_Vector re <: t_Array u8 (sz 384)) @@ -558,8 +590,10 @@ let serialize_secret_key let serialize_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (tt_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) (seed_for_a: t_Slice u8) = @@ -571,7 +605,8 @@ let serialize_public_key ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (public_key_serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (public_key_serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } @@ -581,6 +616,7 @@ let serialize_public_key t_Slice u8) (Rust_primitives.unsize (serialize_secret_key v_K v_RANKED_BYTES_PER_RING_ELEMENT + #v_Vector tt_as_ntt <: t_Array u8 v_RANKED_BYTES_PER_RING_ELEMENT) @@ -594,9 +630,8 @@ let serialize_public_key ({ Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } <: Core.Ops.Range.t_RangeFrom usize) - (Core.Slice.impl__copy_from_slice (public_key_serialized.[ { - Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT - } + (Core.Slice.impl__copy_from_slice #u8 + (public_key_serialized.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } <: Core.Ops.Range.t_RangeFrom usize ] <: @@ -610,43 +645,60 @@ let serialize_public_key let generate_keypair (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) (key_generation_seed: t_Slice u8) = - let hashed:t_Array u8 (sz 64) = Libcrux_ml_kem.Hash_functions.f_G v_K key_generation_seed in + let hashed:t_Array u8 (sz 64) = + Libcrux_ml_kem.Hash_functions.f_G #v_Hasher v_K key_generation_seed + in let seed_for_A, seed_for_secret_and_error:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) (sz 32) + Core.Slice.impl__split_at #u8 (Rust_primitives.unsize hashed <: t_Slice u8) (sz 32) in let v_A_transpose:t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K = Libcrux_ml_kem.Matrix.sample_matrix_A v_K - (into_padded_array (sz 34) seed_for_A <: t_Array u8 (sz 34)) + #v_Vector + #v_Hasher + (Libcrux_ml_kem.Utils.into_padded_array (sz 34) seed_for_A <: t_Array u8 (sz 34)) true in let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = - into_padded_array (sz 33) seed_for_secret_and_error + Libcrux_ml_kem.Utils.into_padded_array (sz 33) seed_for_secret_and_error in let secret_as_ntt, domain_separator:(t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) = - sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy + sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE #v_Vector #v_Hasher prf_input 0uy in let error_as_ntt, _:(t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8 ) = - sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input domain_separator + sample_vector_cbd_then_ntt v_K + v_ETA1 + v_ETA1_RANDOMNESS_SIZE + #v_Vector + #v_Hasher + prf_input + domain_separator in let tt_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Libcrux_ml_kem.Matrix.compute_As_plus_e v_K v_A_transpose secret_as_ntt error_as_ntt + Libcrux_ml_kem.Matrix.compute_As_plus_e v_K #v_Vector v_A_transpose secret_as_ntt error_as_ntt in let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = - serialize_public_key v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE tt_as_ntt seed_for_A + serialize_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #v_Vector + tt_as_ntt + seed_for_A in let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = - serialize_secret_key v_K v_PRIVATE_KEY_SIZE secret_as_ntt + serialize_secret_key v_K v_PRIVATE_KEY_SIZE #v_Vector secret_as_ntt in secret_key_serialized, public_key_serialized <: diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti index ca613d980..7b73f0062 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti @@ -3,54 +3,39 @@ module Libcrux_ml_kem.Ind_cpa open Core open FStar.Mul -/// Pad the `slice` with `0`s at the end. -val into_padded_array (v_LEN: usize) (slice: t_Slice u8) - : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () -/// Sample a vector of ring elements from a centered binomial distribution. -val sample_ring_element_cbd - (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} - {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} - (prf_input: t_Array u8 (sz 33)) - (domain_separator: u8) - : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) - Prims.l_True - (fun _ -> Prims.l_True) - -/// Sample a vector of ring elements from a centered binomial distribution and -/// convert them into their NTT representations. -val sample_vector_cbd_then_ntt - (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} - {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} - (prf_input: t_Array u8 (sz 33)) - (domain_separator: u8) - : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) - Prims.l_True - (fun _ -> Prims.l_True) - -/// Call [`compress_then_serialize_ring_element_u`] on each ring element. -val compress_then_serialize_u - (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (input: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - (out: t_Slice u8) - : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) - -/// Call [`deserialize_then_decompress_ring_element_u`] on each ring element -/// in the `ciphertext`. -val deserialize_then_decompress_u - (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} +/// This function implements Algorithm 14 of the +/// NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. +/// Algorithm 14 is reproduced below: +/// ```plaintext +/// Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. +/// Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. +/// Output: message m ∈ 𝔹^{32}. +/// c₁ ← c[0 : 32dᵤk] +/// c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] +/// u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) +/// v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) +/// ŝ ← ByteDecode₁₂(dkₚₖₑ) +/// w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) +/// m ← ByteEncode₁(Compress₁(w)) +/// return m +/// ``` +/// The NIST FIPS 203 standard can be found at +/// . +val decrypt + (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: + usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (secret_key: t_Slice u8) (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) - : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - Prims.l_True - (fun _ -> Prims.l_True) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) /// This function implements Algorithm 13 of the /// NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. @@ -90,68 +75,14 @@ val deserialize_then_decompress_u val encrypt (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (public_key: t_Slice u8) (message: t_Array u8 (sz 32)) (randomness: t_Slice u8) : Prims.Pure (t_Array u8 v_CIPHERTEXT_SIZE) Prims.l_True (fun _ -> Prims.l_True) -/// Call [`deserialize_to_uncompressed_ring_element`] for each ring element. -val deserialize_secret_key - (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (secret_key: t_Slice u8) - : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - Prims.l_True - (fun _ -> Prims.l_True) - -/// This function implements Algorithm 14 of the -/// NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. -/// Algorithm 14 is reproduced below: -/// ```plaintext -/// Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. -/// Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. -/// Output: message m ∈ 𝔹^{32}. -/// c₁ ← c[0 : 32dᵤk] -/// c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] -/// u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) -/// v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) -/// ŝ ← ByteDecode₁₂(dkₚₖₑ) -/// w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) -/// m ← ByteEncode₁(Compress₁(w)) -/// return m -/// ``` -/// The NIST FIPS 203 standard can be found at -/// . -val decrypt - (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: - usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (secret_key: t_Slice u8) - (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - -/// Call [`serialize_uncompressed_ring_element`] for each ring element. -val serialize_secret_key - (v_K v_OUT_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (key: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) - -/// Concatenate `t` and `ρ` into the public key. -val serialize_public_key - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (tt_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - (seed_for_a: t_Slice u8) - : Prims.Pure (t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) - /// This function implements most of Algorithm 12 of the /// NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation algorithm. /// We say "most of" since Algorithm 12 samples the required randomness within @@ -188,10 +119,82 @@ val serialize_public_key val generate_keypair (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (key_generation_seed: t_Slice u8) : Prims.Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +/// Call [`compress_then_serialize_ring_element_u`] on each ring element. +val compress_then_serialize_u + (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (input: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (out: t_Slice u8) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// Call [`deserialize_to_uncompressed_ring_element`] for each ring element. +val deserialize_secret_key + (v_K: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (secret_key: t_Slice u8) + : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Call [`deserialize_then_decompress_ring_element_u`] on each ring element +/// in the `ciphertext`. +val deserialize_then_decompress_u + (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sample a vector of ring elements from a centered binomial distribution. +val sample_ring_element_cbd + (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) + : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sample a vector of ring elements from a centered binomial distribution and +/// convert them into their NTT representations. +val sample_vector_cbd_then_ntt + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) + : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K & u8) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Concatenate `t` and `ρ` into the public key. +val serialize_public_key + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (tt_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (seed_for_a: t_Slice u8) + : Prims.Pure (t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +/// Call [`serialize_uncompressed_ring_element`] for each ring element. +val serialize_secret_key + (v_K v_OUT_LEN: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (key: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst index 68da4db0b..34e6fbf5e 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst @@ -3,30 +3,42 @@ module Libcrux_ml_kem.Invert_ntt open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + let inv_ntt_layer_int_vec_step_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (a b: v_Vector) (zeta_r: i16) = - let a_minus_b:v_Vector = Libcrux_traits.f_sub b a in - let a:v_Vector = Libcrux_traits.f_barrett_reduce (Libcrux_traits.f_add a b <: v_Vector) in - let b:v_Vector = Libcrux_traits.f_montgomery_multiply_fe_by_fer a_minus_b zeta_r in + let a_minus_b:v_Vector = Libcrux_ml_kem.Vector.Traits.f_sub #v_Vector b a in + let a:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector + (Libcrux_ml_kem.Vector.Traits.f_add #v_Vector a b <: v_Vector) + in + let b:v_Vector = Libcrux_ml_kem.Vector.Traits.montgomery_multiply_fe #v_Vector a_minus_b zeta_r in a, b <: (v_Vector & v_Vector) let invert_ntt_at_layer_1_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -46,10 +58,8 @@ let invert_ntt_at_layer_1_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_inv_ntt_layer_1_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - round ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_inv_ntt_layer_1_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i -! sz 1 <: usize ] @@ -75,18 +85,19 @@ let invert_ntt_at_layer_1_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let invert_ntt_at_layer_2_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -106,10 +117,8 @@ let invert_ntt_at_layer_2_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_inv_ntt_layer_2_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - round ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_inv_ntt_layer_2_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i -! sz 1 <: usize ] @@ -127,18 +136,19 @@ let invert_ntt_at_layer_2_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let invert_ntt_at_layer_3_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -158,10 +168,8 @@ let invert_ntt_at_layer_3_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_inv_ntt_layer_3_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - round ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_inv_ntt_layer_3_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) <: v_Vector) @@ -174,8 +182,10 @@ let invert_ntt_at_layer_3_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let invert_ntt_at_layer_4_plus - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (layer: usize) @@ -183,10 +193,9 @@ let invert_ntt_at_layer_4_plus let step:usize = sz 1 <>! layer <: usize - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 128 >>! layer <: usize } <: Core.Ops.Range.t_Range usize) <: @@ -199,10 +208,14 @@ let invert_ntt_at_layer_4_plus let round:usize = round in let zeta_i:usize = zeta_i -! sz 1 in let offset:usize = (round *! step <: usize) *! sz 2 in - let offset_vec:usize = offset /! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR in - let step_vec:usize = step /! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR in + let offset_vec:usize = + offset /! Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + in + let step_vec:usize = step /! Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = offset_vec; Core.Ops.Range.f_end = offset_vec +! step_vec <: usize } @@ -215,10 +228,8 @@ let invert_ntt_at_layer_4_plus let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let j:usize = j in let x, y:(v_Vector & v_Vector) = - inv_ntt_layer_int_vec_step_reduce (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - j ] - <: - v_Vector) + inv_ntt_layer_int_vec_step_reduce #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector) (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j +! step_vec <: usize ] <: v_Vector) @@ -258,56 +269,58 @@ let invert_ntt_at_layer_4_plus let invert_ntt_montgomery (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let zeta_i:usize = Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT /! sz 2 in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_1_ zeta_i re (sz 1) + invert_ntt_at_layer_1_ #v_Vector zeta_i re (sz 1) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_2_ zeta_i re (sz 2) + invert_ntt_at_layer_2_ #v_Vector zeta_i re (sz 2) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_3_ zeta_i re (sz 3) + invert_ntt_at_layer_3_ #v_Vector zeta_i re (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_4_plus zeta_i re (sz 4) + invert_ntt_at_layer_4_plus #v_Vector zeta_i re (sz 4) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_4_plus zeta_i re (sz 5) + invert_ntt_at_layer_4_plus #v_Vector zeta_i re (sz 5) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_4_plus zeta_i re (sz 6) + invert_ntt_at_layer_4_plus #v_Vector zeta_i re (sz 6) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - invert_ntt_at_layer_4_plus zeta_i re (sz 7) + invert_ntt_at_layer_4_plus #v_Vector zeta_i re (sz 7) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let hax_temp_output, re:(Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce re + (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce #v_Vector re <: (Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti index a000597eb..ffe255831 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti @@ -3,16 +3,22 @@ module Libcrux_ml_kem.Invert_ntt open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + val inv_ntt_layer_int_vec_step_reduce - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (a b: v_Vector) (zeta_r: i16) : Prims.Pure (v_Vector & v_Vector) Prims.l_True (fun _ -> Prims.l_True) val invert_ntt_at_layer_1_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) @@ -21,8 +27,8 @@ val invert_ntt_at_layer_1_ (fun _ -> Prims.l_True) val invert_ntt_at_layer_2_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) @@ -31,8 +37,8 @@ val invert_ntt_at_layer_2_ (fun _ -> Prims.l_True) val invert_ntt_at_layer_3_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer: usize) @@ -41,8 +47,8 @@ val invert_ntt_at_layer_3_ (fun _ -> Prims.l_True) val invert_ntt_at_layer_4_plus - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (layer: usize) @@ -52,8 +58,8 @@ val invert_ntt_at_layer_4_plus val invert_ntt_montgomery (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst index f12b7df16..cb7647bee 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst @@ -3,26 +3,42 @@ module Libcrux_ml_kem.Matrix open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () + let compute_As_plus_e (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (matrix_A: t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K) (s_as_ntt error_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) = let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__i -> let v__i:usize = v__i in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__iter (Rust_primitives.unsize matrix_A + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Iter + (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K))) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Iter + (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K)) + (Core.Slice.impl__iter #(t_Array + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (Rust_primitives.unsize matrix_A <: t_Slice (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K)) @@ -47,8 +63,14 @@ let compute_As_plus_e temp_1_ in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__iter (Rust_primitives.unsize row + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Iter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector))) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Iter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector)) + (Core.Slice.impl__iter #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement + v_Vector) + (Rust_primitives.unsize row <: t_Slice (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector)) <: @@ -73,14 +95,16 @@ let compute_As_plus_e temp_1_ in let product:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ntt_multiply matrix_element + Libcrux_ml_kem.Polynomial.impl__ntt_multiply #v_Vector + matrix_element (s_as_ntt.[ j ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result i - (Libcrux_ml_kem.Polynomial.impl__add_to_ring_element v_K + (Libcrux_ml_kem.Polynomial.impl__add_to_ring_element #v_Vector + v_K (result.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -93,9 +117,8 @@ let compute_As_plus_e let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result i - (Libcrux_ml_kem.Polynomial.impl__add_standard_error_reduce (result.[ i ] - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + (Libcrux_ml_kem.Polynomial.impl__add_standard_error_reduce #v_Vector + (result.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (error_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -106,19 +129,20 @@ let compute_As_plus_e let compute_ring_element_v (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (tt_as_ntt r_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) (error_2_ message: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -128,43 +152,51 @@ let compute_ring_element_v let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = result in let i:usize = i in let product:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ntt_multiply (tt_as_ntt.[ i ] - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + Libcrux_ml_kem.Polynomial.impl__ntt_multiply #v_Vector + (tt_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (r_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__add_to_ring_element v_K result product + Libcrux_ml_kem.Polynomial.impl__add_to_ring_element #v_Vector v_K result product in result) in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Invert_ntt.invert_ntt_montgomery v_K result + Libcrux_ml_kem.Invert_ntt.invert_ntt_montgomery v_K #v_Vector result in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__add_message_error_reduce error_2_ message result + Libcrux_ml_kem.Polynomial.impl__add_message_error_reduce #v_Vector error_2_ message result in result let compute_vector_u (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (a_as_ntt: t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K) (r_as_ntt error_1_: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) = let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__i -> let v__i:usize = v__i in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__iter (Rust_primitives.unsize a_as_ntt + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Iter + (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K))) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Iter + (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K)) + (Core.Slice.impl__iter #(t_Array + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (Rust_primitives.unsize a_as_ntt <: t_Slice (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K)) @@ -189,8 +221,14 @@ let compute_vector_u temp_1_ in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__iter (Rust_primitives.unsize row + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Iter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector))) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Iter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector)) + (Core.Slice.impl__iter #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement + v_Vector) + (Rust_primitives.unsize row <: t_Slice (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector)) <: @@ -215,14 +253,16 @@ let compute_vector_u temp_1_ in let product:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ntt_multiply a_element + Libcrux_ml_kem.Polynomial.impl__ntt_multiply #v_Vector + a_element (r_as_ntt.[ j ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result i - (Libcrux_ml_kem.Polynomial.impl__add_to_ring_element v_K + (Libcrux_ml_kem.Polynomial.impl__add_to_ring_element #v_Vector + v_K (result.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -236,6 +276,7 @@ let compute_vector_u Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result i (Libcrux_ml_kem.Invert_ntt.invert_ntt_montgomery v_K + #v_Vector (result.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -243,9 +284,8 @@ let compute_vector_u let result:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result i - (Libcrux_ml_kem.Polynomial.impl__add_error_reduce (result.[ i ] - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + (Libcrux_ml_kem.Polynomial.impl__add_error_reduce #v_Vector + (result.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (error_1_.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -256,20 +296,21 @@ let compute_vector_u let compute_message (v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (v: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (secret_as_ntt u_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) = let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -279,28 +320,29 @@ let compute_message let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = result in let i:usize = i in let product:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ntt_multiply (secret_as_ntt.[ i ] - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + Libcrux_ml_kem.Polynomial.impl__ntt_multiply #v_Vector + (secret_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (u_as_ntt.[ i ] <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__add_to_ring_element v_K result product + Libcrux_ml_kem.Polynomial.impl__add_to_ring_element #v_Vector v_K result product in result) in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Invert_ntt.invert_ntt_montgomery v_K result + Libcrux_ml_kem.Invert_ntt.invert_ntt_montgomery v_K #v_Vector result in let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__subtract_reduce v result + Libcrux_ml_kem.Polynomial.impl__subtract_reduce #v_Vector v result in result let sample_matrix_A (v_K: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -309,13 +351,15 @@ let sample_matrix_A = let v_A_transpose:t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + v_K (fun v__i -> let v__i:usize = v__i in - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__j -> let v__j:usize = v__j in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: @@ -323,10 +367,9 @@ let sample_matrix_A in let v_A_transpose:t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -340,10 +383,9 @@ let sample_matrix_A let i:usize = i in let seeds:t_Array (t_Array u8 (sz 34)) v_K = Rust_primitives.Hax.repeat seed v_K in let seeds:t_Array (t_Array u8 (sz 34)) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -377,10 +419,16 @@ let sample_matrix_A seeds) in let sampled:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Libcrux_ml_kem.Sampling.sample_from_xof v_K seeds + Libcrux_ml_kem.Sampling.sample_from_xof v_K #v_Vector #v_Hasher seeds in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Iter.Traits.Collect.f_into_iter sampled + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Array.Iter.t_IntoIter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Array.Iter.t_IntoIter + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (Core.Iter.Traits.Collect.f_into_iter #(t_Array + (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + sampled <: Core.Array.Iter.t_IntoIter (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti index 959f17ca0..9b53942d2 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti @@ -3,11 +3,18 @@ module Libcrux_ml_kem.Matrix open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () + /// Compute  ◦ ŝ + ê val compute_As_plus_e (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (matrix_A: t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K) (s_as_ntt error_as_ntt: @@ -16,11 +23,26 @@ val compute_As_plus_e Prims.l_True (fun _ -> Prims.l_True) +/// The following functions compute various expressions involving +/// vectors and matrices. The computation of these expressions has been +/// abstracted away into these functions in order to save on loop iterations. +/// Compute v − InverseNTT(sᵀ ◦ NTT(u)) +val compute_message + (v_K: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (v: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + (secret_as_ntt u_as_ntt: + t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + Prims.l_True + (fun _ -> Prims.l_True) + /// Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message val compute_ring_element_v (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (tt_as_ntt r_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) (error_2_ message: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) @@ -30,8 +52,8 @@ val compute_ring_element_v /// Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ val compute_vector_u (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (a_as_ntt: t_Array (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) v_K) (r_as_ntt error_1_: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) @@ -39,25 +61,10 @@ val compute_vector_u Prims.l_True (fun _ -> Prims.l_True) -/// The following functions compute various expressions involving -/// vectors and matrices. The computation of these expressions has been -/// abstracted away into these functions in order to save on loop iterations. -/// Compute v − InverseNTT(sᵀ ◦ NTT(u)) -val compute_message - (v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (v: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - (secret_as_ntt u_as_ntt: - t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - Prims.l_True - (fun _ -> Prims.l_True) - val sample_matrix_A (v_K: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (seed: t_Array u8 (sz 34)) (transpose: bool) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst new file mode 100644 index 000000000..a6c49635b --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst @@ -0,0 +1,44 @@ +module Libcrux_ml_kem.Mlkem1024.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) + (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) + (sz 1600) private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) + (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_public_key (sz 4) + (sz 1536) + (sz 1568) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + else + Core.Option.Option_None + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.generate_keypair (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + (sz 2) + (sz 128) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti new file mode 100644 index 000000000..b3c9a6920 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem1024.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 1024 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 1024 +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst new file mode 100644 index 000000000..65878c0fb --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst @@ -0,0 +1,44 @@ +module Libcrux_ml_kem.Mlkem1024.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) + (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) + (sz 1600) private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) + (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_public_key (sz 4) + (sz 1536) + (sz 1568) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + else + Core.Option.Option_None + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.generate_keypair (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + (sz 2) + (sz 128) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti new file mode 100644 index 000000000..e09969dff --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem1024.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 1024 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 1024 +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst index c7a2eaafa..a0e43d2ca 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst @@ -7,13 +7,20 @@ let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) = - Libcrux_ml_kem.Ind_cca.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) - (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) private_key - ciphertext + Libcrux_ml_kem.Ind_cca.Multiplexing.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) + (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) + private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Multiplexing.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) + (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) = if - Libcrux_ml_kem.Ind_cca.validate_public_key (sz 4) + Libcrux_ml_kem.Ind_cca.Multiplexing.validate_public_key (sz 4) (sz 1536) (sz 1568) public_key.Libcrux_ml_kem.Types.f_value @@ -26,15 +33,8 @@ let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1 <: Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) -let encapsulate - (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) - (randomness: t_Array u8 (sz 32)) - = - Libcrux_ml_kem.Ind_cca.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) - (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness - let generate_key_pair (randomness: t_Array u8 (sz 64)) = - Libcrux_ml_kem.Ind_cca.generate_keypair (sz 4) + Libcrux_ml_kem.Ind_cca.Multiplexing.generate_keypair (sz 4) (sz 1536) (sz 3168) (sz 1568) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti index 34785554b..f8c25b6fe 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti @@ -3,64 +3,39 @@ module Libcrux_ml_kem.Mlkem1024 open Core open FStar.Mul -let v_ETA1: usize = sz 2 +let v_C1_BLOCK_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_ETA1_RANDOMNESS_SIZE: usize = v_ETA1 *! sz 64 +let v_C1_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2: usize = sz 2 +let v_C2_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2_RANDOMNESS_SIZE: usize = v_ETA2 *! sz 64 +let v_CPA_PKE_CIPHERTEXT_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_RANK_1024_: usize = sz 4 +let v_CPA_PKE_PUBLIC_KEY_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_SECRET_KEY_SIZE_1024_: usize = - ((v_RANK_1024_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_CPA_PKE_SECRET_KEY_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_RANKED_BYTES_PER_RING_ELEMENT_1024_: usize = - (v_RANK_1024_ *! Libcrux_ml_kem.Constants.v_BITS_PER_RING_ELEMENT <: usize) /! sz 8 +let v_ETA1: usize = Rust_primitives.Hax.dropped_body -let v_T_AS_NTT_ENCODED_SIZE_1024_: usize = - ((v_RANK_1024_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_ETA1_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_PUBLIC_KEY_SIZE_1024_: usize = v_T_AS_NTT_ENCODED_SIZE_1024_ +! sz 32 +let v_ETA2: usize = Rust_primitives.Hax.dropped_body -let v_SECRET_KEY_SIZE_1024_: usize = - ((v_CPA_PKE_SECRET_KEY_SIZE_1024_ +! v_CPA_PKE_PUBLIC_KEY_SIZE_1024_ <: usize) +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE - <: - usize) +! - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +let v_ETA2_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_U_COMPRESSION_FACTOR_1024_: usize = sz 11 +let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_C1_BLOCK_SIZE_1024_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_U_COMPRESSION_FACTOR_1024_ - <: - usize) /! - sz 8 +let v_RANKED_BYTES_PER_RING_ELEMENT_1024_: usize = Rust_primitives.Hax.dropped_body -let v_C1_SIZE_1024_: usize = v_C1_BLOCK_SIZE_1024_ *! v_RANK_1024_ +let v_RANK_1024_: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_V_COMPRESSION_FACTOR_1024_: usize = sz 5 +let v_SECRET_KEY_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_C2_SIZE_1024_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_V_COMPRESSION_FACTOR_1024_ - <: - usize) /! - sz 8 +let v_T_AS_NTT_ENCODED_SIZE_1024_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_CIPHERTEXT_SIZE_1024_: usize = v_C1_SIZE_1024_ +! v_C2_SIZE_1024_ +let v_VECTOR_U_COMPRESSION_FACTOR_1024_: usize = Rust_primitives.Hax.dropped_body -let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_1024_ +let v_VECTOR_V_COMPRESSION_FACTOR_1024_: usize = Rust_primitives.Hax.dropped_body /// An ML-KEM 1024 Ciphertext unfold @@ -82,13 +57,6 @@ val decapsulate unfold let t_MlKem1024PublicKey = Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) -/// Validate a public key. -/// Returns `Some(public_key)` if valid, and `None` otherwise. -val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) - : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568))) - Prims.l_True - (fun _ -> Prims.l_True) - /// Encapsulate ML-KEM 1024 /// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`] @@ -100,6 +68,13 @@ val encapsulate Prims.l_True (fun _ -> Prims.l_True) +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568))) + Prims.l_True + (fun _ -> Prims.l_True) + /// Am ML-KEM 1024 Key pair unfold let t_MlKem1024KeyPair = Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst new file mode 100644 index 000000000..671c9d2ba --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst @@ -0,0 +1,42 @@ +module Libcrux_ml_kem.Mlkem512.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) + (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) + private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) + (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_public_key (sz 2) + (sz 768) + (sz 800) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + else + Core.Option.Option_None <: Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.generate_keypair (sz 2) + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + (sz 3) + (sz 192) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti new file mode 100644 index 000000000..8504c458d --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem512.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 512 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 512 +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst new file mode 100644 index 000000000..021b912b0 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst @@ -0,0 +1,42 @@ +module Libcrux_ml_kem.Mlkem512.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) + (sz 768) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) + (sz 800) private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) + (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_public_key (sz 2) + (sz 768) + (sz 800) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + else + Core.Option.Option_None <: Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.generate_keypair (sz 2) + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + (sz 3) + (sz 192) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti new file mode 100644 index 000000000..a069aea6f --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem512.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 512 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 512 +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst index 520065dfa..b3252faa0 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst @@ -7,12 +7,20 @@ let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) = - Libcrux_ml_kem.Ind_cca.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) (sz 640) - (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) private_key ciphertext + Libcrux_ml_kem.Ind_cca.Multiplexing.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) + (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) + private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Multiplexing.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) + (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = if - Libcrux_ml_kem.Ind_cca.validate_public_key (sz 2) + Libcrux_ml_kem.Ind_cca.Multiplexing.validate_public_key (sz 2) (sz 768) (sz 800) public_key.Libcrux_ml_kem.Types.f_value @@ -23,15 +31,8 @@ let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 8 else Core.Option.Option_None <: Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) -let encapsulate - (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) - (randomness: t_Array u8 (sz 32)) - = - Libcrux_ml_kem.Ind_cca.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) (sz 128) (sz 10) - (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness - let generate_key_pair (randomness: t_Array u8 (sz 64)) = - Libcrux_ml_kem.Ind_cca.generate_keypair (sz 2) + Libcrux_ml_kem.Ind_cca.Multiplexing.generate_keypair (sz 2) (sz 768) (sz 1632) (sz 800) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti index da84a9270..155d70c2a 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti @@ -3,64 +3,39 @@ module Libcrux_ml_kem.Mlkem512 open Core open FStar.Mul -let v_ETA1: usize = sz 3 +let v_C1_BLOCK_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_ETA1_RANDOMNESS_SIZE: usize = v_ETA1 *! sz 64 +let v_C1_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2: usize = sz 2 +let v_C2_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2_RANDOMNESS_SIZE: usize = v_ETA2 *! sz 64 +let v_CPA_PKE_CIPHERTEXT_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_RANK_512_: usize = sz 2 +let v_CPA_PKE_PUBLIC_KEY_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_SECRET_KEY_SIZE_512_: usize = - ((v_RANK_512_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_CPA_PKE_SECRET_KEY_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_RANKED_BYTES_PER_RING_ELEMENT_512_: usize = - (v_RANK_512_ *! Libcrux_ml_kem.Constants.v_BITS_PER_RING_ELEMENT <: usize) /! sz 8 +let v_ETA1: usize = Rust_primitives.Hax.dropped_body -let v_T_AS_NTT_ENCODED_SIZE_512_: usize = - ((v_RANK_512_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_ETA1_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_PUBLIC_KEY_SIZE_512_: usize = v_T_AS_NTT_ENCODED_SIZE_512_ +! sz 32 +let v_ETA2: usize = Rust_primitives.Hax.dropped_body -let v_SECRET_KEY_SIZE_512_: usize = - ((v_CPA_PKE_SECRET_KEY_SIZE_512_ +! v_CPA_PKE_PUBLIC_KEY_SIZE_512_ <: usize) +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE - <: - usize) +! - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +let v_ETA2_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_U_COMPRESSION_FACTOR_512_: usize = sz 10 +let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_C1_BLOCK_SIZE_512_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_U_COMPRESSION_FACTOR_512_ - <: - usize) /! - sz 8 +let v_RANKED_BYTES_PER_RING_ELEMENT_512_: usize = Rust_primitives.Hax.dropped_body -let v_C1_SIZE_512_: usize = v_C1_BLOCK_SIZE_512_ *! v_RANK_512_ +let v_RANK_512_: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_V_COMPRESSION_FACTOR_512_: usize = sz 4 +let v_SECRET_KEY_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_C2_SIZE_512_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_V_COMPRESSION_FACTOR_512_ - <: - usize) /! - sz 8 +let v_T_AS_NTT_ENCODED_SIZE_512_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_CIPHERTEXT_SIZE_512_: usize = v_C1_SIZE_512_ +! v_C2_SIZE_512_ +let v_VECTOR_U_COMPRESSION_FACTOR_512_: usize = Rust_primitives.Hax.dropped_body -let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_512_ +let v_VECTOR_V_COMPRESSION_FACTOR_512_: usize = Rust_primitives.Hax.dropped_body /// An ML-KEM 512 Ciphertext unfold @@ -82,13 +57,6 @@ val decapsulate unfold let t_MlKem512PublicKey = Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800) -/// Validate a public key. -/// Returns `Some(public_key)` if valid, and `None` otherwise. -val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) - : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800))) - Prims.l_True - (fun _ -> Prims.l_True) - /// Encapsulate ML-KEM 512 /// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`] @@ -100,6 +68,13 @@ val encapsulate Prims.l_True (fun _ -> Prims.l_True) +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800))) + Prims.l_True + (fun _ -> Prims.l_True) + /// Am ML-KEM 512 Key pair unfold let t_MlKem512KeyPair = Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst new file mode 100644 index 000000000..ae68d3994 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst @@ -0,0 +1,44 @@ +module Libcrux_ml_kem.Mlkem768.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) + (sz 1088) (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) + (sz 1120) private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) + (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_public_key (sz 3) + (sz 1152) + (sz 1184) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + else + Core.Option.Option_None + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.generate_keypair (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + (sz 2) + (sz 128) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti new file mode 100644 index 000000000..4c9e0045a --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem768.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 768 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 768 +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst new file mode 100644 index 000000000..9c5cf8365 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst @@ -0,0 +1,44 @@ +module Libcrux_ml_kem.Mlkem768.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) + (sz 1088) (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) + (sz 1120) private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) + (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness + +let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) = + if + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_public_key (sz 3) + (sz 1152) + (sz 1184) + public_key.Libcrux_ml_kem.Types.f_value + then + Core.Option.Option_Some public_key + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + else + Core.Option.Option_None + <: + Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.generate_keypair (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + (sz 2) + (sz 128) + randomness diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti new file mode 100644 index 000000000..644446ed8 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_kem.Mlkem768.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Decapsulate ML-KEM 768 +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. +val decapsulate + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +/// Encapsulate ML-KEM 768 +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] +/// bytes of `randomness`. +val encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst index dd9dd13cf..a8cefb121 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst @@ -7,13 +7,20 @@ let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) = - Libcrux_ml_kem.Ind_cca.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) - (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) private_key - ciphertext + Libcrux_ml_kem.Ind_cca.Multiplexing.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) + (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) + private_key ciphertext + +let encapsulate + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Multiplexing.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) + (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) = if - Libcrux_ml_kem.Ind_cca.validate_public_key (sz 3) + Libcrux_ml_kem.Ind_cca.Multiplexing.validate_public_key (sz 3) (sz 1152) (sz 1184) public_key.Libcrux_ml_kem.Types.f_value @@ -26,15 +33,8 @@ let validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1 <: Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) -let encapsulate - (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) - (randomness: t_Array u8 (sz 32)) - = - Libcrux_ml_kem.Ind_cca.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) (sz 128) (sz 10) - (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness - let generate_key_pair (randomness: t_Array u8 (sz 64)) = - Libcrux_ml_kem.Ind_cca.generate_keypair (sz 3) + Libcrux_ml_kem.Ind_cca.Multiplexing.generate_keypair (sz 3) (sz 1152) (sz 2400) (sz 1184) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti index 06774d878..6260bb2fe 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti @@ -3,64 +3,39 @@ module Libcrux_ml_kem.Mlkem768 open Core open FStar.Mul -let v_ETA1: usize = sz 2 +let v_C1_BLOCK_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_ETA1_RANDOMNESS_SIZE: usize = v_ETA1 *! sz 64 +let v_C1_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2: usize = sz 2 +let v_C2_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_ETA2_RANDOMNESS_SIZE: usize = v_ETA2 *! sz 64 +let v_CPA_PKE_CIPHERTEXT_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_RANK_768_: usize = sz 3 +let v_CPA_PKE_PUBLIC_KEY_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_SECRET_KEY_SIZE_768_: usize = - ((v_RANK_768_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_CPA_PKE_SECRET_KEY_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_RANKED_BYTES_PER_RING_ELEMENT_768_: usize = - (v_RANK_768_ *! Libcrux_ml_kem.Constants.v_BITS_PER_RING_ELEMENT <: usize) /! sz 8 +let v_ETA1: usize = Rust_primitives.Hax.dropped_body -let v_T_AS_NTT_ENCODED_SIZE_768_: usize = - ((v_RANK_768_ *! Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) *! - Libcrux_ml_kem.Constants.v_BITS_PER_COEFFICIENT - <: - usize) /! - sz 8 +let v_ETA1_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_PUBLIC_KEY_SIZE_768_: usize = v_T_AS_NTT_ENCODED_SIZE_768_ +! sz 32 +let v_ETA2: usize = Rust_primitives.Hax.dropped_body -let v_SECRET_KEY_SIZE_768_: usize = - ((v_CPA_PKE_SECRET_KEY_SIZE_768_ +! v_CPA_PKE_PUBLIC_KEY_SIZE_768_ <: usize) +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE - <: - usize) +! - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +let v_ETA2_RANDOMNESS_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_U_COMPRESSION_FACTOR_768_: usize = sz 10 +let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = Rust_primitives.Hax.dropped_body -let v_C1_BLOCK_SIZE_768_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_U_COMPRESSION_FACTOR_768_ - <: - usize) /! - sz 8 +let v_RANKED_BYTES_PER_RING_ELEMENT_768_: usize = Rust_primitives.Hax.dropped_body -let v_C1_SIZE_768_: usize = v_C1_BLOCK_SIZE_768_ *! v_RANK_768_ +let v_RANK_768_: usize = Rust_primitives.Hax.dropped_body -let v_VECTOR_V_COMPRESSION_FACTOR_768_: usize = sz 4 +let v_SECRET_KEY_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_C2_SIZE_768_: usize = - (Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_VECTOR_V_COMPRESSION_FACTOR_768_ - <: - usize) /! - sz 8 +let v_T_AS_NTT_ENCODED_SIZE_768_: usize = Rust_primitives.Hax.dropped_body -let v_CPA_PKE_CIPHERTEXT_SIZE_768_: usize = v_C1_SIZE_768_ +! v_C2_SIZE_768_ +let v_VECTOR_U_COMPRESSION_FACTOR_768_: usize = Rust_primitives.Hax.dropped_body -let v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = - Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_768_ +let v_VECTOR_V_COMPRESSION_FACTOR_768_: usize = Rust_primitives.Hax.dropped_body /// An ML-KEM 768 Ciphertext unfold @@ -82,13 +57,6 @@ val decapsulate unfold let t_MlKem768PublicKey = Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) -/// Validate a public key. -/// Returns `Some(public_key)` if valid, and `None` otherwise. -val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) - : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184))) - Prims.l_True - (fun _ -> Prims.l_True) - /// Encapsulate ML-KEM 768 /// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. /// The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] @@ -100,6 +68,13 @@ val encapsulate Prims.l_True (fun _ -> Prims.l_True) +/// Validate a public key. +/// Returns `Some(public_key)` if valid, and `None` otherwise. +val validate_public_key (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Core.Option.t_Option (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184))) + Prims.l_True + (fun _ -> Prims.l_True) + /// Am ML-KEM 768 Key pair unfold let t_MlKem768KeyPair = Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184) @@ -107,6 +82,12 @@ let t_MlKem768KeyPair = Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184) /// Generate ML-KEM 768 Key Pair /// Generate an ML-KEM key pair. The input is a byte array of size /// [`KEY_GENERATION_SEED_SIZE`]. +/// This function uses CPU feature detection to pick the most efficient version +/// on each platform. To use a specific version with your own feature detection +/// use one of the following +/// - [`generate_key_pair_avx2`] +/// - [`generate_key_pair_neon`] +/// - [`generate_key_pair_portable`] /// This function returns an [`MlKem768KeyPair`]. val generate_key_pair (randomness: t_Array u8 (sz 64)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst index 228560bc0..b68155e06 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst @@ -3,30 +3,39 @@ module Libcrux_ml_kem.Ntt open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + let ntt_layer_int_vec_step - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (a b: v_Vector) (zeta_r: i16) = - let t:v_Vector = Libcrux_traits.f_montgomery_multiply_fe_by_fer b zeta_r in - let b:v_Vector = Libcrux_traits.f_sub a t in - let a:v_Vector = Libcrux_traits.f_add a t in + let t:v_Vector = Libcrux_ml_kem.Vector.Traits.montgomery_multiply_fe #v_Vector b zeta_r in + let b:v_Vector = Libcrux_ml_kem.Vector.Traits.f_sub #v_Vector a t in + let a:v_Vector = Libcrux_ml_kem.Vector.Traits.f_add #v_Vector a t in a, b <: (v_Vector & v_Vector) let ntt_at_layer_1_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -46,10 +55,8 @@ let ntt_at_layer_1_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_ntt_layer_1_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round - ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_ntt_layer_1_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i +! sz 1 <: usize ] @@ -75,18 +82,19 @@ let ntt_at_layer_1_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let ntt_at_layer_2_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -106,10 +114,8 @@ let ntt_at_layer_2_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_ntt_layer_2_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round - ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_ntt_layer_2_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i +! sz 1 <: usize ] @@ -127,18 +133,19 @@ let ntt_at_layer_2_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let ntt_at_layer_3_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) = let (re, zeta_i), hax_temp_output:(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector & usize) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -158,10 +165,8 @@ let ntt_at_layer_3_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients round - (Libcrux_traits.f_ntt_layer_3_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round - ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_ntt_layer_3_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ round ] <: v_Vector) (Libcrux_ml_kem.Polynomial.v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i16) <: v_Vector) @@ -174,8 +179,10 @@ let ntt_at_layer_3_ zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let ntt_at_layer_4_plus - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (layer v__initial_coefficient_bound: usize) @@ -195,10 +202,9 @@ let ntt_at_layer_4_plus let step:usize = sz 1 <>! layer <: usize - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 128 >>! layer <: usize } <: Core.Ops.Range.t_Range usize) <: @@ -211,10 +217,12 @@ let ntt_at_layer_4_plus let round:usize = round in let zeta_i:usize = zeta_i +! sz 1 in let offset:usize = (round *! step <: usize) *! sz 2 in - let offset_vec:usize = offset /! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR in - let step_vec:usize = step /! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR in + let offset_vec:usize = offset /! sz 16 in + let step_vec:usize = step /! sz 16 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = offset_vec; Core.Ops.Range.f_end = offset_vec +! step_vec <: usize } @@ -227,9 +235,8 @@ let ntt_at_layer_4_plus let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let j:usize = j in let x, y:(v_Vector & v_Vector) = - ntt_layer_int_vec_step (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] - <: - v_Vector) + ntt_layer_int_vec_step #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector) (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j +! step_vec <: usize ] <: v_Vector) @@ -268,16 +275,17 @@ let ntt_at_layer_4_plus zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) let ntt_at_layer_7_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let step:usize = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT /! sz 2 in let re, hax_temp_output:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = step - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = step } <: Core.Ops.Range.t_Range usize) <: @@ -287,12 +295,8 @@ let ntt_at_layer_7_ let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let j:usize = j in let t:v_Vector = - Libcrux_traits.f_multiply_by_constant (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j +! - step - <: - usize ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_multiply_by_constant #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j +! step <: usize ] <: v_Vector) (-1600s) in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = @@ -303,8 +307,8 @@ let ntt_at_layer_7_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients (j +! step <: usize) - (Libcrux_traits.f_sub (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector - ) + (Libcrux_ml_kem.Vector.Traits.f_sub #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector) t <: v_Vector) @@ -320,8 +324,8 @@ let ntt_at_layer_7_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients j - (Libcrux_traits.f_add (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector - ) + (Libcrux_ml_kem.Vector.Traits.f_add #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ j ] <: v_Vector) t <: v_Vector) @@ -334,51 +338,55 @@ let ntt_at_layer_7_ re let ntt_binomially_sampled_ring_element - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = ntt_at_layer_7_ re in + let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = + ntt_at_layer_7_ #v_Vector re + in let zeta_i:usize = sz 1 in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 6) (sz 3) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 6) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 5) (sz 3) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 5) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 4) (sz 3) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 4) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_3_ zeta_i re (sz 3) (sz 3) + ntt_at_layer_3_ #v_Vector zeta_i re (sz 3) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_2_ zeta_i re (sz 2) (sz 3) + ntt_at_layer_2_ #v_Vector zeta_i re (sz 2) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_1_ zeta_i re (sz 1) (sz 3) + ntt_at_layer_1_ #v_Vector zeta_i re (sz 1) (sz 3) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let hax_temp_output, re:(Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce re + (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce #v_Vector re <: (Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in @@ -386,56 +394,58 @@ let ntt_binomially_sampled_ring_element let ntt_vector_u (v_VECTOR_U_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let zeta_i:usize = sz 0 in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 7) (sz 3328) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 7) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 6) (sz 3328) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 6) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 5) (sz 3328) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 5) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_4_plus zeta_i re (sz 4) (sz 3328) + ntt_at_layer_4_plus #v_Vector zeta_i re (sz 4) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_3_ zeta_i re (sz 3) (sz 3328) + ntt_at_layer_3_ #v_Vector zeta_i re (sz 3) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_2_ zeta_i re (sz 2) (sz 3328) + ntt_at_layer_2_ #v_Vector zeta_i re (sz 2) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let tmp0, tmp1:(usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - ntt_at_layer_1_ zeta_i re (sz 1) (sz 3328) + ntt_at_layer_1_ #v_Vector zeta_i re (sz 1) (sz 3328) in let zeta_i:usize = tmp0 in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = tmp1 in let _:Prims.unit = () in let hax_temp_output, re:(Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = - (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce re + (), Libcrux_ml_kem.Polynomial.impl__poly_barrett_reduce #v_Vector re <: (Prims.unit & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti index 8d23fbd07..2e535adc9 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti @@ -3,16 +3,22 @@ module Libcrux_ml_kem.Ntt open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + val ntt_layer_int_vec_step - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (a b: v_Vector) (zeta_r: i16) : Prims.Pure (v_Vector & v_Vector) Prims.l_True (fun _ -> Prims.l_True) val ntt_at_layer_1_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) @@ -21,8 +27,8 @@ val ntt_at_layer_1_ (fun _ -> Prims.l_True) val ntt_at_layer_2_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) @@ -31,8 +37,8 @@ val ntt_at_layer_2_ (fun _ -> Prims.l_True) val ntt_at_layer_3_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (v__layer v__initial_coefficient_bound: usize) @@ -41,8 +47,8 @@ val ntt_at_layer_3_ (fun _ -> Prims.l_True) val ntt_at_layer_4_plus - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (zeta_i: usize) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (layer v__initial_coefficient_bound: usize) @@ -51,16 +57,16 @@ val ntt_at_layer_4_plus (fun _ -> Prims.l_True) val ntt_at_layer_7_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val ntt_binomially_sampled_ring_element - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True @@ -68,8 +74,8 @@ val ntt_binomially_sampled_ring_element val ntt_vector_u (v_VECTOR_U_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst index 3644f27f6..472c8b1ba 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst @@ -3,25 +3,39 @@ module Libcrux_ml_kem.Polynomial open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + let impl__ZERO - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (_: Prims.unit) = - { f_coefficients = Rust_primitives.Hax.repeat (Libcrux_traits.f_ZERO () <: v_Vector) (sz 16) } + { + f_coefficients + = + Rust_primitives.Hax.repeat (Libcrux_ml_kem.Vector.Traits.f_ZERO #v_Vector () <: v_Vector) + (sz 16) + } <: t_PolynomialRingElement v_Vector let impl__add_error_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self error: t_PolynomialRingElement v_Vector) = let self, hax_temp_output:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -31,7 +45,8 @@ let impl__add_error_reduce let self:t_PolynomialRingElement v_Vector = self in let j:usize = j in let coefficient_normal_form:v_Vector = - Libcrux_traits.f_montgomery_multiply_by_constant (self.f_coefficients.[ j ] <: v_Vector) + Libcrux_ml_kem.Vector.Traits.f_montgomery_multiply_by_constant #v_Vector + (self.f_coefficients.[ j ] <: v_Vector) 1441s in let self:t_PolynomialRingElement v_Vector = @@ -41,7 +56,9 @@ let impl__add_error_reduce = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_coefficients j - (Libcrux_traits.f_barrett_reduce (Libcrux_traits.f_add coefficient_normal_form + (Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector + (Libcrux_ml_kem.Vector.Traits.f_add #v_Vector + coefficient_normal_form (error.f_coefficients.[ j ] <: v_Vector) <: v_Vector) @@ -56,15 +73,16 @@ let impl__add_error_reduce self let impl__add_message_error_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self message result: t_PolynomialRingElement v_Vector) = let result:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -74,11 +92,18 @@ let impl__add_message_error_reduce let result:t_PolynomialRingElement v_Vector = result in let i:usize = i in let coefficient_normal_form:v_Vector = - Libcrux_traits.f_montgomery_multiply_by_constant (result.f_coefficients.[ i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_montgomery_multiply_by_constant #v_Vector + (result.f_coefficients.[ i ] <: v_Vector) 1441s in + let tmp:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_add #v_Vector + (self.f_coefficients.[ i ] <: v_Vector) + (message.f_coefficients.[ i ] <: v_Vector) + in + let tmp:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_add #v_Vector coefficient_normal_form tmp + in let result:t_PolynomialRingElement v_Vector = { result with @@ -86,15 +111,7 @@ let impl__add_message_error_reduce = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_coefficients i - (Libcrux_traits.f_barrett_reduce (Libcrux_traits.f_add coefficient_normal_form - (Libcrux_traits.f_add (self.f_coefficients.[ i ] <: v_Vector) - (message.f_coefficients.[ i ] <: v_Vector) - <: - v_Vector) - <: - v_Vector) - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector tmp <: v_Vector) } <: t_PolynomialRingElement v_Vector @@ -104,15 +121,16 @@ let impl__add_message_error_reduce result let impl__add_standard_error_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self error: t_PolynomialRingElement v_Vector) = let self, hax_temp_output:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -122,7 +140,8 @@ let impl__add_standard_error_reduce let self:t_PolynomialRingElement v_Vector = self in let j:usize = j in let coefficient_normal_form:v_Vector = - Libcrux_traits.f_to_standard_domain (self.f_coefficients.[ j ] <: v_Vector) + Libcrux_ml_kem.Vector.Traits.to_standard_domain #v_Vector + (self.f_coefficients.[ j ] <: v_Vector) in let self:t_PolynomialRingElement v_Vector = { @@ -131,7 +150,9 @@ let impl__add_standard_error_reduce = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_coefficients j - (Libcrux_traits.f_barrett_reduce (Libcrux_traits.f_add coefficient_normal_form + (Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector + (Libcrux_ml_kem.Vector.Traits.f_add #v_Vector + coefficient_normal_form (error.f_coefficients.[ j ] <: v_Vector) <: v_Vector) @@ -146,17 +167,22 @@ let impl__add_standard_error_reduce self let impl__add_to_ring_element - (#v_Vector: Type) + (#v_Vector: Type0) (v_K: usize) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self rhs: t_PolynomialRingElement v_Vector) = let self, hax_temp_output:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = - Core.Slice.impl__len (Rust_primitives.unsize self.f_coefficients <: t_Slice v_Vector) + Core.Slice.impl__len #v_Vector + (Rust_primitives.unsize self.f_coefficients <: t_Slice v_Vector) <: usize } @@ -174,7 +200,8 @@ let impl__add_to_ring_element = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_coefficients i - (Libcrux_traits.f_add (self.f_coefficients.[ i ] <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_add #v_Vector + (self.f_coefficients.[ i ] <: v_Vector) (rhs.f_coefficients.[ i ] <: v_Vector) <: v_Vector) @@ -187,16 +214,17 @@ let impl__add_to_ring_element self let impl__from_i16_array - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (a: t_Slice i16) = - let result:t_PolynomialRingElement v_Vector = impl__ZERO () in + let result:t_PolynomialRingElement v_Vector = impl__ZERO #v_Vector () in let result:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -211,13 +239,10 @@ let impl__from_i16_array = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_coefficients i - (Libcrux_traits.f_from_i16_array (a.[ { - Core.Ops.Range.f_start - = - i *! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR <: usize; - Core.Ops.Range.f_end - = - (i +! sz 1 <: usize) *! Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR <: usize + (Libcrux_ml_kem.Vector.Traits.f_from_i16_array #v_Vector + (a.[ { + Core.Ops.Range.f_start = i *! sz 16 <: usize; + Core.Ops.Range.f_end = (i +! sz 1 <: usize) *! sz 16 <: usize } <: Core.Ops.Range.t_Range usize ] @@ -234,16 +259,17 @@ let impl__from_i16_array result let impl__ntt_multiply - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self rhs: t_PolynomialRingElement v_Vector) = - let out:t_PolynomialRingElement v_Vector = impl__ZERO () in + let out:t_PolynomialRingElement v_Vector = impl__ZERO #v_Vector () in let out:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -258,7 +284,8 @@ let impl__ntt_multiply = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out.f_coefficients i - (Libcrux_traits.f_ntt_multiply (self.f_coefficients.[ i ] <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_ntt_multiply #v_Vector + (self.f_coefficients.[ i ] <: v_Vector) (rhs.f_coefficients.[ i ] <: v_Vector) (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! (sz 4 *! i <: usize) <: usize ] <: i16) (v_ZETAS_TIMES_MONTGOMERY_R.[ (sz 64 +! (sz 4 *! i <: usize) <: usize) +! sz 1 @@ -287,15 +314,16 @@ let impl__ntt_multiply out let impl__poly_barrett_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self: t_PolynomialRingElement v_Vector) = let self, hax_temp_output:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -310,7 +338,10 @@ let impl__poly_barrett_reduce = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_coefficients i - (Libcrux_traits.f_barrett_reduce (self.f_coefficients.[ i ] <: v_Vector) <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector + (self.f_coefficients.[ i ] <: v_Vector) + <: + v_Vector) <: t_Array v_Vector (sz 16) } @@ -320,15 +351,16 @@ let impl__poly_barrett_reduce self let impl__subtract_reduce - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self b: t_PolynomialRingElement v_Vector) = let b:t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_VECTORS_IN_RING_ELEMENT } <: Core.Ops.Range.t_Range usize) <: @@ -338,7 +370,8 @@ let impl__subtract_reduce let b:t_PolynomialRingElement v_Vector = b in let i:usize = i in let coefficient_normal_form:v_Vector = - Libcrux_traits.f_montgomery_multiply_by_constant (b.f_coefficients.[ i ] <: v_Vector) + Libcrux_ml_kem.Vector.Traits.f_montgomery_multiply_by_constant #v_Vector + (b.f_coefficients.[ i ] <: v_Vector) 1441s in let b:t_PolynomialRingElement v_Vector = @@ -348,9 +381,9 @@ let impl__subtract_reduce = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize b.f_coefficients i - (Libcrux_traits.f_barrett_reduce (Libcrux_traits.f_sub (self.f_coefficients.[ i ] - <: - v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_barrett_reduce #v_Vector + (Libcrux_ml_kem.Vector.Traits.f_sub #v_Vector + (self.f_coefficients.[ i ] <: v_Vector) coefficient_normal_form <: v_Vector) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti index 3e4da8720..80bc1336c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti @@ -3,66 +3,56 @@ module Libcrux_ml_kem.Polynomial open Core open FStar.Mul -let v_ZETAS_TIMES_MONTGOMERY_R: t_Array i16 (sz 128) = - let list = - [ - (-1044s); (-758s); (-359s); (-1517s); 1493s; 1422s; 287s; 202s; (-171s); 622s; 1577s; 182s; - 962s; (-1202s); (-1474s); 1468s; 573s; (-1325s); 264s; 383s; (-829s); 1458s; (-1602s); (-130s); - (-681s); 1017s; 732s; 608s; (-1542s); 411s; (-205s); (-1571s); 1223s; 652s; (-552s); 1015s; - (-1293s); 1491s; (-282s); (-1544s); 516s; (-8s); (-320s); (-666s); (-1618s); (-1162s); 126s; - 1469s; (-853s); (-90s); (-271s); 830s; 107s; (-1421s); (-247s); (-951s); (-398s); 961s; - (-1508s); (-725s); 448s; (-1065s); 677s; (-1275s); (-1103s); 430s; 555s; 843s; (-1251s); 871s; - 1550s; 105s; 422s; 587s; 177s; (-235s); (-291s); (-460s); 1574s; 1653s; (-246s); 778s; 1159s; - (-147s); (-777s); 1483s; (-602s); 1119s; (-1590s); 644s; (-872s); 349s; 418s; 329s; (-156s); - (-75s); 817s; 1097s; 603s; 610s; 1322s; (-1285s); (-1465s); 384s; (-1215s); (-136s); 1218s; - (-1335s); (-874s); 220s; (-1187s); (-1659s); (-1185s); (-1530s); (-1278s); 794s; (-1510s); - (-854s); (-870s); 478s; (-108s); (-308s); 996s; 991s; 958s; (-1460s); 1522s; 1628s - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 128); - Rust_primitives.Hax.array_of_list 128 list +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () -let v_VECTORS_IN_RING_ELEMENT: usize = - Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT /! - Libcrux_traits.v_FIELD_ELEMENTS_IN_VECTOR +let v_VECTORS_IN_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body -type t_PolynomialRingElement (v_Vector: Type) {| i1: Libcrux_traits.t_Operations v_Vector |} = { - f_coefficients:t_Array v_Vector (sz 16) -} +let v_ZETAS_TIMES_MONTGOMERY_R: t_Array i16 (sz 128) = Rust_primitives.Hax.dropped_body -val impl__ZERO: #v_Vector: Type -> {| i1: Libcrux_traits.t_Operations v_Vector |} -> Prims.unit +type t_PolynomialRingElement + (v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + = { f_coefficients:t_Array v_Vector (sz 16) } + +val impl__ZERO: + #v_Vector: Type0 -> + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} -> + Prims.unit -> Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__add_error_reduce - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self error: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__add_message_error_reduce - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self message result: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__add_standard_error_reduce - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self error: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) /// Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise /// sum of their constituent coefficients. val impl__add_to_ring_element - (#v_Vector: Type) + (#v_Vector: Type0) (v_K: usize) - {| i2: Libcrux_traits.t_Operations v_Vector |} + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self rhs: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__from_i16_array - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (a: t_Slice i16) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) @@ -87,19 +77,19 @@ val impl__from_i16_array /// The NIST FIPS 203 standard can be found at /// . val impl__ntt_multiply - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self rhs: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__poly_barrett_reduce - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val impl__subtract_reduce - (#v_Vector: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (self b: t_PolynomialRingElement v_Vector) : Prims.Pure (t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst index 7c18a83f4..5005f1d87 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst @@ -3,19 +3,27 @@ module Libcrux_ml_kem.Sampling open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () + let sample_from_uniform_distribution_next - (#v_Vector: Type) + (#v_Vector: Type0) (v_K v_N: usize) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (randomness: t_Array (t_Array u8 v_N) v_K) (sampled_coefficients: t_Array usize v_K) (out: t_Array (t_Array i16 (sz 272)) v_K) = let out, sampled_coefficients:(t_Array (t_Array i16 (sz 272)) v_K & t_Array usize v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -26,10 +34,9 @@ let sample_from_uniform_distribution_next temp_0_ in let i:usize = i in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_N /! sz 24 <: usize - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_N /! sz 24 <: usize } <: Core.Ops.Range.t_Range usize) <: @@ -48,7 +55,8 @@ let sample_from_uniform_distribution_next bool then let tmp0, out1:(t_Slice i16 & usize) = - Libcrux_traits.f_rej_sample ((randomness.[ i ] <: t_Array u8 v_N).[ { + Libcrux_ml_kem.Vector.Traits.f_rej_sample #v_Vector + ((randomness.[ i ] <: t_Array u8 v_N).[ { Core.Ops.Range.f_start = r *! sz 24 <: usize; Core.Ops.Range.f_end = (r *! sz 24 <: usize) +! sz 24 <: usize } @@ -103,10 +111,9 @@ let sample_from_uniform_distribution_next in let done:bool = true in let done, sampled_coefficients:(bool & t_Array usize v_K) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = v_K } <: Core.Ops.Range.t_Range usize) <: @@ -135,14 +142,20 @@ let sample_from_uniform_distribution_next (t_Array usize v_K & t_Array (t_Array i16 (sz 272)) v_K & bool) let sample_from_binomial_distribution_2_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (randomness: t_Slice u8) = let sampled_i16s:t_Array i16 (sz 256) = Rust_primitives.Hax.repeat 0s (sz 256) in let sampled_i16s:t_Array i16 (sz 256) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact randomness (sz 4) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 randomness (sz 4) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -164,7 +177,9 @@ let sample_from_binomial_distribution_2_ let even_bits:u32 = random_bits_as_u32 &. 1431655765ul in let odd_bits:u32 = (random_bits_as_u32 >>! 1l <: u32) &. 1431655765ul in let coin_toss_outcomes:u32 = even_bits +! odd_bits in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Step_by.t_StepBy + (Core.Ops.Range.t_Range u32)) + (Core.Iter.Traits.Iterator.f_step_by #(Core.Ops.Range.t_Range u32) ({ Core.Ops.Range.f_start = 0ul; Core.Ops.Range.f_end = Core.Num.impl__u32__BITS @@ -196,18 +211,24 @@ let sample_from_binomial_distribution_2_ in sampled_i16s)) in - Libcrux_ml_kem.Polynomial.impl__from_i16_array (Rust_primitives.unsize sampled_i16s <: t_Slice i16 - ) + Libcrux_ml_kem.Polynomial.impl__from_i16_array #v_Vector + (Rust_primitives.unsize sampled_i16s <: t_Slice i16) let sample_from_binomial_distribution_3_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (randomness: t_Slice u8) = let sampled_i16s:t_Array i16 (sz 256) = Rust_primitives.Hax.repeat 0s (sz 256) in let sampled_i16s:t_Array i16 (sz 256) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact randomness (sz 3) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 randomness (sz 3) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -227,7 +248,9 @@ let sample_from_binomial_distribution_3_ let second_bits:u32 = (random_bits_as_u24 >>! 1l <: u32) &. 2396745ul in let third_bits:u32 = (random_bits_as_u24 >>! 2l <: u32) &. 2396745ul in let coin_toss_outcomes:u32 = (first_bits +! second_bits <: u32) +! third_bits in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Step_by.t_StepBy + (Core.Ops.Range.t_Range i32)) + (Core.Iter.Traits.Iterator.f_step_by #(Core.Ops.Range.t_Range i32) ({ Core.Ops.Range.f_start = 0l; Core.Ops.Range.f_end = 24l } <: Core.Ops.Range.t_Range i32) @@ -256,18 +279,20 @@ let sample_from_binomial_distribution_3_ in sampled_i16s)) in - Libcrux_ml_kem.Polynomial.impl__from_i16_array (Rust_primitives.unsize sampled_i16s <: t_Slice i16 - ) + Libcrux_ml_kem.Polynomial.impl__from_i16_array #v_Vector + (Rust_primitives.unsize sampled_i16s <: t_Slice i16) let sample_from_binomial_distribution (v_ETA: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (randomness: t_Slice u8) = match cast (v_ETA <: usize) <: u32 with - | 2ul -> sample_from_binomial_distribution_2_ randomness - | 3ul -> sample_from_binomial_distribution_3_ randomness + | 2ul -> sample_from_binomial_distribution_2_ #v_Vector randomness + | 3ul -> sample_from_binomial_distribution_3_ #v_Vector randomness | _ -> Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" @@ -276,8 +301,10 @@ let sample_from_binomial_distribution let sample_from_xof (v_K: usize) - (#v_Vector #v_Hasher: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Libcrux_traits.t_Operations v_Vector) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (#[FStar.Tactics.Typeclasses.tcresolve ()] i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) @@ -289,14 +316,16 @@ let sample_from_xof let (out: t_Array (t_Array i16 (sz 272)) v_K):t_Array (t_Array i16 (sz 272)) v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0s (sz 272) <: t_Array i16 (sz 272)) v_K in - let xof_state:v_Hasher = Libcrux_ml_kem.Hash_functions.f_shake128_init_absorb v_K seeds in + let xof_state:v_Hasher = + Libcrux_ml_kem.Hash_functions.f_shake128_init_absorb #v_Hasher v_K seeds + in let tmp0, out1:(v_Hasher & t_Array (t_Array u8 (sz 504)) v_K) = - Libcrux_ml_kem.Hash_functions.f_shake128_squeeze_three_blocks v_K xof_state + Libcrux_ml_kem.Hash_functions.f_shake128_squeeze_three_blocks #v_Hasher v_K xof_state in let xof_state:v_Hasher = tmp0 in let randomness:t_Array (t_Array u8 (sz 504)) v_K = out1 in let tmp0, tmp1, out1:(t_Array usize v_K & t_Array (t_Array i16 (sz 272)) v_K & bool) = - sample_from_uniform_distribution_next v_K (sz 504) randomness sampled_coefficients out + sample_from_uniform_distribution_next #v_Vector v_K (sz 504) randomness sampled_coefficients out in let sampled_coefficients:t_Array usize v_K = tmp0 in let out:t_Array (t_Array i16 (sz 272)) v_K = tmp1 in @@ -321,12 +350,17 @@ let sample_from_xof temp_0_ in let tmp0, out1:(v_Hasher & t_Array (t_Array u8 (sz 168)) v_K) = - Libcrux_ml_kem.Hash_functions.f_shake128_squeeze_block v_K xof_state + Libcrux_ml_kem.Hash_functions.f_shake128_squeeze_block #v_Hasher v_K xof_state in let xof_state:v_Hasher = tmp0 in let randomness:t_Array (t_Array u8 (sz 168)) v_K = out1 in let tmp0, tmp1, out1:(t_Array usize v_K & t_Array (t_Array i16 (sz 272)) v_K & bool) = - sample_from_uniform_distribution_next v_K (sz 168) randomness sampled_coefficients out + sample_from_uniform_distribution_next #v_Vector + v_K + (sz 168) + randomness + sampled_coefficients + out in let sampled_coefficients:t_Array usize v_K = tmp0 in let out:t_Array (t_Array i16 (sz 272)) v_K = tmp1 in @@ -335,14 +369,14 @@ let sample_from_xof <: (bool & t_Array (t_Array i16 (sz 272)) v_K & t_Array usize v_K & v_Hasher)) in - Core.Array.impl_23__map v_K + Core.Array.impl_23__map #(t_Array i16 (sz 272)) + v_K + #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) out (fun s -> let s:t_Array i16 (sz 272) = s in - Libcrux_ml_kem.Polynomial.impl__from_i16_array (s.[ { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 256 - } + Libcrux_ml_kem.Polynomial.impl__from_i16_array #v_Vector + (s.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 256 } <: Core.Ops.Range.t_Range usize ] <: diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti index 52b52d986..2f9d5a51d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti @@ -3,6 +3,13 @@ module Libcrux_ml_kem.Sampling open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Vector.Traits in + () + /// If `bytes` contains a set of uniformly random bytes, this function /// uniformly samples a ring element `â` that is treated as being the NTT representation /// of the corresponding polynomial `a`. @@ -37,9 +44,9 @@ open FStar.Mul /// The NIST FIPS 203 standard can be found at /// . val sample_from_uniform_distribution_next - (#v_Vector: Type) + (#v_Vector: Type0) (v_K v_N: usize) - {| i1: Libcrux_traits.t_Operations v_Vector |} + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (randomness: t_Array (t_Array u8 v_N) v_K) (sampled_coefficients: t_Array usize v_K) (out: t_Array (t_Array i16 (sz 272)) v_K) @@ -47,6 +54,15 @@ val sample_from_uniform_distribution_next Prims.l_True (fun _ -> Prims.l_True) +val sample_from_binomial_distribution + (v_ETA: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (randomness: t_Slice u8) + : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + Prims.l_True + (fun _ -> Prims.l_True) + /// Given a series of uniformly random bytes in `randomness`, for some number `eta`, /// the `sample_from_binomial_distribution_{eta}` functions sample /// a ring element from a binomial distribution centered at 0 that uses two sets @@ -86,34 +102,25 @@ val sample_from_uniform_distribution_next /// The NIST FIPS 203 standard can be found at /// . val sample_from_binomial_distribution_2_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (randomness: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - (requires (Core.Slice.impl__len randomness <: usize) =. (sz 2 *! sz 64 <: usize)) + (requires (Core.Slice.impl__len #u8 randomness <: usize) =. (sz 2 *! sz 64 <: usize)) (fun _ -> Prims.l_True) val sample_from_binomial_distribution_3_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (randomness: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - (requires (Core.Slice.impl__len randomness <: usize) =. (sz 3 *! sz 64 <: usize)) - (fun _ -> Prims.l_True) - -val sample_from_binomial_distribution - (v_ETA: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (randomness: t_Slice u8) - : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - Prims.l_True + (requires (Core.Slice.impl__len #u8 randomness <: usize) =. (sz 3 *! sz 64 <: usize)) (fun _ -> Prims.l_True) val sample_from_xof (v_K: usize) - (#v_Vector #v_Hasher: Type) - {| i2: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} (seeds: t_Array (t_Array u8 (sz 34)) v_K) : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst index 916404d64..7f311ebd3 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst @@ -3,15 +3,25 @@ module Libcrux_ml_kem.Serialize open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + let compress_then_serialize_10_ (v_OUT_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in let serialized:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT } @@ -24,15 +34,16 @@ let compress_then_serialize_10_ let serialized:t_Array u8 v_OUT_LEN = serialized in let i:usize = i in let coefficient:v_Vector = - Libcrux_traits.f_compress 10l - (Libcrux_traits.f_to_unsigned_representative (re - .Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_compress #v_Vector + 10l + (Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) <: v_Vector) in - let bytes:t_Array u8 (sz 20) = Libcrux_traits.f_serialize_10_ coefficient in + let bytes:t_Array u8 (sz 20) = + Libcrux_ml_kem.Vector.Traits.f_serialize_10_ #v_Vector coefficient + in let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -41,7 +52,8 @@ let compress_then_serialize_10_ } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 20 *! i <: usize; Core.Ops.Range.f_end = (sz 20 *! i <: usize) +! sz 20 <: usize } @@ -59,13 +71,17 @@ let compress_then_serialize_10_ let compress_then_serialize_11_ (v_OUT_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in let serialized:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT } @@ -78,15 +94,16 @@ let compress_then_serialize_11_ let serialized:t_Array u8 v_OUT_LEN = serialized in let i:usize = i in let coefficient:v_Vector = - Libcrux_traits.f_compress 11l - (Libcrux_traits.f_to_unsigned_representative (re - .Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_compress #v_Vector + 11l + (Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) <: v_Vector) in - let bytes:t_Array u8 (sz 22) = Libcrux_traits.f_serialize_11_ coefficient in + let bytes:t_Array u8 (sz 22) = + Libcrux_ml_kem.Vector.Traits.f_serialize_11_ #v_Vector coefficient + in let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -95,7 +112,8 @@ let compress_then_serialize_11_ } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 22 *! i <: usize; Core.Ops.Range.f_end = (sz 22 *! i <: usize) +! sz 22 <: usize } @@ -112,13 +130,17 @@ let compress_then_serialize_11_ serialized let compress_then_serialize_4_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (serialized: t_Slice u8) = let serialized, hax_temp_output:t_Slice u8 = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT } @@ -131,15 +153,16 @@ let compress_then_serialize_4_ let serialized:t_Slice u8 = serialized in let i:usize = i in let coefficient:v_Vector = - Libcrux_traits.f_compress 4l - (Libcrux_traits.f_to_unsigned_representative (re - .Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_compress #v_Vector + 4l + (Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) <: v_Vector) in - let bytes:t_Array u8 (sz 8) = Libcrux_traits.f_serialize_4_ coefficient in + let bytes:t_Array u8 (sz 8) = + Libcrux_ml_kem.Vector.Traits.f_serialize_4_ #v_Vector coefficient + in let serialized:t_Slice u8 = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -148,7 +171,8 @@ let compress_then_serialize_4_ } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 8 *! i <: usize; Core.Ops.Range.f_end = (sz 8 *! i <: usize) +! sz 8 <: usize } @@ -165,13 +189,17 @@ let compress_then_serialize_4_ serialized let compress_then_serialize_5_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (serialized: t_Slice u8) = let serialized, hax_temp_output:t_Slice u8 = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT } @@ -184,15 +212,16 @@ let compress_then_serialize_5_ let serialized:t_Slice u8 = serialized in let i:usize = i in let coefficients:v_Vector = - Libcrux_traits.f_compress 5l - (Libcrux_traits.f_to_unsigned_representative (re - .Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.f_compress #v_Vector + 5l + (Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) <: v_Vector) in - let bytes:t_Array u8 (sz 10) = Libcrux_traits.f_serialize_5_ coefficients in + let bytes:t_Array u8 (sz 10) = + Libcrux_ml_kem.Vector.Traits.f_serialize_5_ #v_Vector coefficients + in let serialized:t_Slice u8 = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -201,7 +230,8 @@ let compress_then_serialize_5_ } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 10 *! i <: usize; Core.Ops.Range.f_end = (sz 10 *! i <: usize) +! sz 10 <: usize } @@ -218,16 +248,17 @@ let compress_then_serialize_5_ serialized let compress_then_serialize_message - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in let serialized:t_Array u8 (sz 32) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -237,13 +268,15 @@ let compress_then_serialize_message let serialized:t_Array u8 (sz 32) = serialized in let i:usize = i in let coefficient:v_Vector = - Libcrux_traits.f_to_unsigned_representative (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) + in + let coefficient_compressed:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_compress_1_ #v_Vector coefficient + in + let bytes:t_Array u8 (sz 2) = + Libcrux_ml_kem.Vector.Traits.f_serialize_1_ #v_Vector coefficient_compressed in - let coefficient_compressed:v_Vector = Libcrux_traits.f_compress_1_ coefficient in - let bytes:t_Array u8 (sz 2) = Libcrux_traits.f_serialize_1_ coefficient_compressed in let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -252,7 +285,8 @@ let compress_then_serialize_message } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 2 *! i <: usize; Core.Ops.Range.f_end = (sz 2 *! i <: usize) +! sz 2 <: usize } @@ -270,13 +304,15 @@ let compress_then_serialize_message let compress_then_serialize_ring_element_u (v_COMPRESSION_FACTOR v_OUT_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 10ul -> compress_then_serialize_10_ v_OUT_LEN re - | 11ul -> compress_then_serialize_11_ v_OUT_LEN re + | 10ul -> compress_then_serialize_10_ v_OUT_LEN #v_Vector re + | 11ul -> compress_then_serialize_11_ v_OUT_LEN #v_Vector re | _ -> Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" @@ -285,15 +321,17 @@ let compress_then_serialize_ring_element_u let compress_then_serialize_ring_element_v (v_COMPRESSION_FACTOR v_OUT_LEN: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (out: t_Slice u8) = let out, hax_temp_output:(t_Slice u8 & Prims.unit) = match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 4ul -> compress_then_serialize_4_ re out, () <: (t_Slice u8 & Prims.unit) - | 5ul -> compress_then_serialize_5_ re out, () <: (t_Slice u8 & Prims.unit) + | 4ul -> compress_then_serialize_4_ #v_Vector re out, () <: (t_Slice u8 & Prims.unit) + | 5ul -> compress_then_serialize_5_ #v_Vector re out, () <: (t_Slice u8 & Prims.unit) | _ -> out, Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" @@ -306,16 +344,22 @@ let compress_then_serialize_ring_element_v out let deserialize_then_decompress_10_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 20) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 20) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -324,7 +368,9 @@ let deserialize_then_decompress_10_ (fun re temp_1_ -> let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let i, bytes:(usize & t_Slice u8) = temp_1_ in - let coefficient:v_Vector = Libcrux_traits.f_deserialize_10_ bytes in + let coefficient:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_deserialize_10_ #v_Vector bytes + in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = { re with @@ -333,7 +379,11 @@ let deserialize_then_decompress_10_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_decompress_ciphertext_coefficient 10l coefficient <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_decompress_ciphertext_coefficient #v_Vector + 10l + coefficient + <: + v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -343,16 +393,22 @@ let deserialize_then_decompress_10_ re let deserialize_then_decompress_11_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 22) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 22) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -361,7 +417,9 @@ let deserialize_then_decompress_11_ (fun re temp_1_ -> let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let i, bytes:(usize & t_Slice u8) = temp_1_ in - let coefficient:v_Vector = Libcrux_traits.f_deserialize_11_ bytes in + let coefficient:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_deserialize_11_ #v_Vector bytes + in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = { re with @@ -370,7 +428,11 @@ let deserialize_then_decompress_11_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_decompress_ciphertext_coefficient 11l coefficient <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_decompress_ciphertext_coefficient #v_Vector + 11l + coefficient + <: + v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -380,16 +442,22 @@ let deserialize_then_decompress_11_ re let deserialize_then_decompress_4_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 8) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 8) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -398,7 +466,9 @@ let deserialize_then_decompress_4_ (fun re temp_1_ -> let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let i, bytes:(usize & t_Slice u8) = temp_1_ in - let coefficient:v_Vector = Libcrux_traits.f_deserialize_4_ bytes in + let coefficient:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_deserialize_4_ #v_Vector bytes + in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = { re with @@ -407,7 +477,11 @@ let deserialize_then_decompress_4_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_decompress_ciphertext_coefficient 4l coefficient <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_decompress_ciphertext_coefficient #v_Vector + 4l + coefficient + <: + v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -417,16 +491,22 @@ let deserialize_then_decompress_4_ re let deserialize_then_decompress_5_ - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 10) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 10) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -443,7 +523,7 @@ let deserialize_then_decompress_5_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_deserialize_5_ bytes <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_deserialize_5_ #v_Vector bytes <: v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -456,7 +536,8 @@ let deserialize_then_decompress_5_ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_decompress_ciphertext_coefficient 5l + (Libcrux_ml_kem.Vector.Traits.f_decompress_ciphertext_coefficient #v_Vector + 5l (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) <: v_Vector) @@ -469,18 +550,19 @@ let deserialize_then_decompress_5_ re let deserialize_then_decompress_message - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Array u8 (sz 32)) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 16 - } + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } <: Core.Ops.Range.t_Range usize) <: @@ -490,7 +572,8 @@ let deserialize_then_decompress_message let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let i:usize = i in let coefficient_compressed:v_Vector = - Libcrux_traits.f_deserialize_1_ (serialized.[ { + Libcrux_ml_kem.Vector.Traits.f_deserialize_1_ #v_Vector + (serialized.[ { Core.Ops.Range.f_start = sz 2 *! i <: usize; Core.Ops.Range.f_end = (sz 2 *! i <: usize) +! sz 2 <: usize } @@ -507,7 +590,9 @@ let deserialize_then_decompress_message Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_decompress_1_ coefficient_compressed <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.decompress_1_ #v_Vector coefficient_compressed + <: + v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -518,13 +603,15 @@ let deserialize_then_decompress_message let deserialize_then_decompress_ring_element_u (v_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 10ul -> deserialize_then_decompress_10_ serialized - | 11ul -> deserialize_then_decompress_11_ serialized + | 10ul -> deserialize_then_decompress_10_ #v_Vector serialized + | 11ul -> deserialize_then_decompress_11_ #v_Vector serialized | _ -> Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" @@ -533,13 +620,15 @@ let deserialize_then_decompress_ring_element_u let deserialize_then_decompress_ring_element_v (v_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 4ul -> deserialize_then_decompress_4_ serialized - | 5ul -> deserialize_then_decompress_5_ serialized + | 4ul -> deserialize_then_decompress_4_ #v_Vector serialized + | 5ul -> deserialize_then_decompress_5_ #v_Vector serialized | _ -> Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" @@ -547,16 +636,22 @@ let deserialize_then_decompress_ring_element_v Rust_primitives.Hax.t_Never) let deserialize_to_reduced_ring_element - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 24) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 24) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -565,7 +660,9 @@ let deserialize_to_reduced_ring_element (fun re temp_1_ -> let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re in let i, bytes:(usize & t_Slice u8) = temp_1_ in - let coefficient:v_Vector = Libcrux_traits.f_deserialize_12_ bytes in + let coefficient:v_Vector = + Libcrux_ml_kem.Vector.Traits.f_deserialize_12_ #v_Vector bytes + in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = { re with @@ -574,7 +671,9 @@ let deserialize_to_reduced_ring_element Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_cond_subtract_3329_ coefficient <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_cond_subtract_3329_ #v_Vector coefficient + <: + v_Vector) } <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector @@ -585,21 +684,27 @@ let deserialize_to_reduced_ring_element let deserialize_ring_elements_reduced (v_PUBLIC_KEY_SIZE v_K: usize) - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (public_key: t_Slice u8) = let deserialized_pk:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Array.from_fn v_K + Core.Array.from_fn #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K (fun v__i -> let v__i:usize = v__i in - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) in let deserialized_pk:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact public_key + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 + public_key Libcrux_ml_kem.Constants.v_BYTES_PER_RING_ELEMENT <: Core.Slice.Iter.t_ChunksExact u8) @@ -616,7 +721,7 @@ let deserialize_ring_elements_reduced let i, ring_element:(usize & t_Slice u8) = temp_1_ in Rust_primitives.Hax.Monomorphized_update_at.update_at_usize deserialized_pk i - (deserialize_to_reduced_ring_element ring_element + (deserialize_to_reduced_ring_element #v_Vector ring_element <: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) <: @@ -625,16 +730,22 @@ let deserialize_ring_elements_reduced deserialized_pk let deserialize_to_uncompressed_ring_element - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (serialized: t_Slice u8) = let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Polynomial.impl__ZERO () + Libcrux_ml_kem.Polynomial.impl__ZERO #v_Vector () in let re:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact serialized (sz 24) <: Core.Slice.Iter.t_ChunksExact u8) + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_ChunksExact u8)) + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_ChunksExact u8) + (Core.Slice.impl__chunks_exact #u8 serialized (sz 24) + <: + Core.Slice.Iter.t_ChunksExact u8) <: Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) <: @@ -650,7 +761,7 @@ let deserialize_to_uncompressed_ring_element Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux_ml_kem.Polynomial.f_coefficients i - (Libcrux_traits.f_deserialize_12_ bytes <: v_Vector) + (Libcrux_ml_kem.Vector.Traits.f_deserialize_12_ #v_Vector bytes <: v_Vector) <: t_Array v_Vector (sz 16) } @@ -660,13 +771,17 @@ let deserialize_to_uncompressed_ring_element re let serialize_uncompressed_ring_element - (#v_Vector: Type) - (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_traits.t_Operations v_Vector) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) = let serialized:t_Array u8 (sz 384) = Rust_primitives.Hax.repeat 0uy (sz 384) in let serialized:t_Array u8 (sz 384) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = Libcrux_ml_kem.Polynomial.v_VECTORS_IN_RING_ELEMENT } @@ -679,12 +794,12 @@ let serialize_uncompressed_ring_element let serialized:t_Array u8 (sz 384) = serialized in let i:usize = i in let coefficient:v_Vector = - Libcrux_traits.f_to_unsigned_representative (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ - i ] - <: - v_Vector) + Libcrux_ml_kem.Vector.Traits.to_unsigned_representative #v_Vector + (re.Libcrux_ml_kem.Polynomial.f_coefficients.[ i ] <: v_Vector) + in + let bytes:t_Array u8 (sz 24) = + Libcrux_ml_kem.Vector.Traits.f_serialize_12_ #v_Vector coefficient in - let bytes:t_Array u8 (sz 24) = Libcrux_traits.f_serialize_12_ coefficient in let serialized:t_Array u8 (sz 384) = Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ @@ -693,7 +808,8 @@ let serialize_uncompressed_ring_element } <: Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (serialized.[ { + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { Core.Ops.Range.f_start = sz 24 *! i <: usize; Core.Ops.Range.f_end = (sz 24 *! i <: usize) +! sz 24 <: usize } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti index aa98844c8..b7aa994d8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti @@ -3,90 +3,108 @@ module Libcrux_ml_kem.Serialize open Core open FStar.Mul +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + val compress_then_serialize_10_ (v_OUT_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_11_ (v_OUT_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_4_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (serialized: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_5_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (serialized: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_message - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_ring_element_u (v_COMPRESSION_FACTOR v_OUT_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) val compress_then_serialize_ring_element_v (v_COMPRESSION_FACTOR v_OUT_LEN: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (out: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) +/// This function deserializes ring elements and reduces the result by the field +/// modulus. +/// This function MUST NOT be used on secret inputs. +val deserialize_ring_elements_reduced + (v_PUBLIC_KEY_SIZE v_K: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (public_key: t_Slice u8) + : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + Prims.l_True + (fun _ -> Prims.l_True) + val deserialize_then_decompress_10_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val deserialize_then_decompress_11_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val deserialize_then_decompress_4_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val deserialize_then_decompress_5_ - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val deserialize_then_decompress_message - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Array u8 (sz 32)) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True @@ -94,8 +112,8 @@ val deserialize_then_decompress_message val deserialize_then_decompress_ring_element_u (v_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True @@ -103,8 +121,8 @@ val deserialize_then_decompress_ring_element_u val deserialize_then_decompress_ring_element_v (v_COMPRESSION_FACTOR: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True @@ -113,35 +131,23 @@ val deserialize_then_decompress_ring_element_v /// Only use with public values. /// This MUST NOT be used with secret inputs, like its caller `deserialize_ring_elements_reduced`. val deserialize_to_reduced_ring_element - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) -/// This function deserializes ring elements and reduces the result by the field -/// modulus. -/// This function MUST NOT be used on secret inputs. -val deserialize_ring_elements_reduced - (v_PUBLIC_KEY_SIZE v_K: usize) - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} - (public_key: t_Slice u8) - : Prims.Pure (t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - Prims.l_True - (fun _ -> Prims.l_True) - val deserialize_to_uncompressed_ring_element - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) Prims.l_True (fun _ -> Prims.l_True) val serialize_uncompressed_ring_element - (#v_Vector: Type) - {| i1: Libcrux_traits.t_Operations v_Vector |} + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) : Prims.Pure (t_Array u8 (sz 384)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.Index_impls.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.Index_impls.fsti new file mode 100644 index 000000000..2ff16f73c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.Index_impls.fsti @@ -0,0 +1,679 @@ +module Libcrux_ml_kem.Types.Index_impls +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) usize = + { + f_Output = u8; + f_index_pre = (fun (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) (index: usize) -> true); + f_index_post + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) (index: usize) (out: u8) -> true); + f_index + = + fun (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) (index: usize) -> + self.Libcrux_ml_kem.Types.f_value.[ index ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_1 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) usize = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) (range: usize) -> true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) (range: usize) -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut int = {\n &mut (deref({\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::types::f_value(self),\n range,\n )),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_2 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_3 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_Range,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_4 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_5 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeTo,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_6 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_7 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemCiphertext v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeFrom,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_8 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) usize = + { + f_Output = u8; + f_index_pre = (fun (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) (index: usize) -> true); + f_index_post + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) (index: usize) (out: u8) -> true); + f_index + = + fun (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) (index: usize) -> + self.Libcrux_ml_kem.Types.f_value.[ index ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_9 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) usize = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) (range: usize) -> true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) (range: usize) -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut int = {\n &mut (deref({\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::types::f_value(self),\n range,\n )),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_10 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_11 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_Range,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_12 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_13 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeTo,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_14 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_15 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeFrom,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_16 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) usize = + { + f_Output = u8; + f_index_pre = (fun (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) (index: usize) -> true); + f_index_post + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) (index: usize) (out: u8) -> true); + f_index + = + fun (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) (index: usize) -> + self.Libcrux_ml_kem.Types.f_value.[ index ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_17 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) usize = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) (range: usize) -> true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) (range: usize) -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut int = {\n &mut (deref({\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::types::f_value(self),\n range,\n )),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_18 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_19 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_Range usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_Range usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_Range,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_20 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_21 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_RangeTo usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeTo usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeTo,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_22 (v_SIZE: usize) + : Core.Ops.Index.t_Index (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + f_Output = t_Slice u8; + f_index_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: t_Slice u8) + -> + true); + f_index + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + self.Libcrux_ml_kem.Types.f_value.[ range ] + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_23 (v_SIZE: usize) + : Core.Ops.Index.t_IndexMut (Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (Core.Ops.Range.t_RangeFrom usize) = + { + _super_1797189408337550814 = FStar.Tactics.Typeclasses.solve; + f_index_mut_pre + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + true); + f_index_mut_post + = + (fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + (out: Rust_primitives.Hax.t_failure) + -> + true); + f_index_mut + = + fun + (self: Libcrux_ml_kem.Types.t_MlKemPublicKey v_SIZE) + (range: Core.Ops.Range.t_RangeFrom usize) + -> + Rust_primitives.Hax.failure "(RefMut) The mutation of this &mut is not allowed here.\n" + "{\n let hax_temp_output: &mut [int] = {\n &mut (deref({\n &mut (deref(\n &mut (deref(core::ops::index::f_index_mut::<\n [int; SIZE],\n core::ops::range::t_RangeFrom,\n >(\n &mut (proj_libcrux_ml_kem::types::f_value(self)), range\n ))),\n ))\n }))\n };\n Tuple2(self, hax_temp_output)\n }" + + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst index 2520d935c..8ef0918fa 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst @@ -5,19 +5,10 @@ open FStar.Mul let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) = self.f_value -let impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid - let impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) = self.f_value -let impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid - let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) = self.f_value -let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid - let impl__from (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) (sk: t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) @@ -29,7 +20,14 @@ let impl__new (sk: t_Array u8 v_PRIVATE_KEY_SIZE) (pk: t_Array u8 v_PUBLIC_KEY_SIZE) = - { f_sk = Core.Convert.f_into sk; f_pk = Core.Convert.f_into pk } + { + f_sk + = + Core.Convert.f_into #(t_Array u8 v_PRIVATE_KEY_SIZE) #(t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) sk; + f_pk + = + Core.Convert.f_into #(t_Array u8 v_PUBLIC_KEY_SIZE) #(t_MlKemPublicKey v_PUBLIC_KEY_SIZE) pk + } <: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti index e53c97941..9cdbe7435 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti @@ -30,7 +30,7 @@ let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_A f_from = fun (value: t_Array u8 v_SIZE) -> - { f_value = Core.Clone.f_clone value } <: t_MlKemCiphertext v_SIZE + { f_value = Core.Clone.f_clone #(t_Array u8 v_SIZE) value } <: t_MlKemCiphertext v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] @@ -45,10 +45,6 @@ let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemCip val impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) Prims.l_True (fun _ -> Prims.l_True) -/// Split this value and return the raw byte slices. -val impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) - : Prims.Pure (t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) - ///An ML-KEM Private key type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } @@ -76,7 +72,7 @@ let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_A f_from = fun (value: t_Array u8 v_SIZE) -> - { f_value = Core.Clone.f_clone value } <: t_MlKemPrivateKey v_SIZE + { f_value = Core.Clone.f_clone #(t_Array u8 v_SIZE) value } <: t_MlKemPrivateKey v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] @@ -91,10 +87,6 @@ let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPr val impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) Prims.l_True (fun _ -> Prims.l_True) -/// Split this value and return the raw byte slices. -val impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) - : Prims.Pure (t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) - ///An ML-KEM Public key type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } @@ -122,7 +114,7 @@ let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_A f_from = fun (value: t_Array u8 v_SIZE) -> - { f_value = Core.Clone.f_clone value } <: t_MlKemPublicKey v_SIZE + { f_value = Core.Clone.f_clone #(t_Array u8 v_SIZE) value } <: t_MlKemPublicKey v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] @@ -137,10 +129,6 @@ let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPu val impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) Prims.l_True (fun _ -> Prims.l_True) -/// Split this value and return the raw byte slices. -val impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) - : Prims.Pure (t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) - [@@ FStar.Tactics.Typeclasses.tcinstance] let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = { @@ -156,7 +144,7 @@ let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) ( f_try_from = fun (value: t_Slice u8) -> - match Core.Convert.f_try_into value with + match Core.Convert.f_try_into #(t_Slice u8) #(t_Array u8 v_SIZE) value with | Core.Result.Result_Ok value -> Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) <: @@ -182,7 +170,7 @@ let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) f_try_from = fun (value: t_Slice u8) -> - match Core.Convert.f_try_into value with + match Core.Convert.f_try_into #(t_Slice u8) #(t_Array u8 v_SIZE) value with | Core.Result.Result_Ok value -> Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) <: @@ -208,7 +196,7 @@ let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) ( f_try_from = fun (value: t_Slice u8) -> - match Core.Convert.f_try_into value with + match Core.Convert.f_try_into #(t_Slice u8) #(t_Array u8 v_SIZE) value with | Core.Result.Result_Ok value -> Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPublicKey v_SIZE) <: diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst new file mode 100644 index 000000000..dcd78722e --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst @@ -0,0 +1,42 @@ +module Libcrux_ml_kem.Utils +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let into_padded_array (v_LEN: usize) (slice: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((Core.Slice.impl__len #u8 slice <: usize) <=. v_LEN <: bool) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: slice.len() <= LEN" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + let out:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out:t_Array u8 v_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Core.Slice.impl__len #u8 slice <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Core.Slice.impl__len #u8 slice <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + slice + <: + t_Slice u8) + in + out diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti new file mode 100644 index 000000000..4a1043b8e --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti @@ -0,0 +1,8 @@ +module Libcrux_ml_kem.Utils +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Pad the `slice` with `0`s at the end. +val into_padded_array (v_LEN: usize) (slice: t_Slice u8) + : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst new file mode 100644 index 000000000..98b81af64 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst @@ -0,0 +1,150 @@ +module Libcrux_ml_kem.Vector.Avx2.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let add (lhs rhs: Core.Core_arch.X86.t____m256i) = Libcrux_intrinsics.Avx2.mm256_add_epi16 lhs rhs + +let bitwise_and_with_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) = + Libcrux_intrinsics.Avx2.mm256_and_si256 vector + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 constant <: Core.Core_arch.X86.t____m256i) + +let multiply_by_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 vector + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 constant <: Core.Core_arch.X86.t____m256i) + +let shift_right (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) = + Libcrux_intrinsics.Avx2.mm256_srai_epi16 v_SHIFT_BY vector + +let sub (lhs rhs: Core.Core_arch.X86.t____m256i) = Libcrux_intrinsics.Avx2.mm256_sub_epi16 lhs rhs + +let barrett_reduce (vector: Core.Core_arch.X86.t____m256i) = + let t:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 vector + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 v_BARRETT_MULTIPLIER + <: + Core.Core_arch.X86.t____m256i) + in + let t:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_add_epi16 t + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 512s <: Core.Core_arch.X86.t____m256i) + in + let quotient:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_srai_epi16 10l t in + let quotient_times_field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 quotient + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + Core.Core_arch.X86.t____m256i) + in + Libcrux_intrinsics.Avx2.mm256_sub_epi16 vector quotient_times_field_modulus + +let cond_subtract_3329_ (vector: Core.Core_arch.X86.t____m256i) = + let field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + in + let vv_minus_field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_sub_epi16 vector field_modulus + in + let sign_mask:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_srai_epi16 15l vv_minus_field_modulus + in + let conditional_add_field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_and_si256 sign_mask field_modulus + in + Libcrux_intrinsics.Avx2.mm256_add_epi16 vv_minus_field_modulus conditional_add_field_modulus + +let montgomery_multiply_by_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) = + let constant:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_set1_epi16 constant in + let value_low:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 vector constant + in + let k:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 value_low + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 (cast (Libcrux_ml_kem.Vector.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + Core.Core_arch.X86.t____m256i) + in + let k_times_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 k + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + Core.Core_arch.X86.t____m256i) + in + let value_high:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 vector constant + in + Libcrux_intrinsics.Avx2.mm256_sub_epi16 value_high k_times_modulus + +let montgomery_multiply_by_constants (v c: Core.Core_arch.X86.t____m256i) = + let value_low:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_mullo_epi16 v c in + let k:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 value_low + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 (cast (Libcrux_ml_kem.Vector.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + Core.Core_arch.X86.t____m256i) + in + let k_times_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 k + (Libcrux_intrinsics.Avx2.mm256_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + Core.Core_arch.X86.t____m256i) + in + let value_high:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 v c in + Libcrux_intrinsics.Avx2.mm256_sub_epi16 value_high k_times_modulus + +let montgomery_multiply_m128i_by_constants (v c: Core.Core_arch.X86.t____m128i) = + let value_low:Core.Core_arch.X86.t____m128i = Libcrux_intrinsics.Avx2.mm_mullo_epi16 v c in + let k:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_mullo_epi16 value_low + (Libcrux_intrinsics.Avx2.mm_set1_epi16 (cast (Libcrux_ml_kem.Vector.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + Core.Core_arch.X86.t____m128i) + in + let k_times_modulus:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_mulhi_epi16 k + (Libcrux_intrinsics.Avx2.mm_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + Core.Core_arch.X86.t____m128i) + in + let value_high:Core.Core_arch.X86.t____m128i = Libcrux_intrinsics.Avx2.mm_mulhi_epi16 v c in + Libcrux_intrinsics.Avx2.mm_sub_epi16 value_high k_times_modulus + +let montgomery_reduce_i32s (v: Core.Core_arch.X86.t____m256i) = + let k:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 v + (Libcrux_intrinsics.Avx2.mm256_set1_epi32 (cast (Libcrux_ml_kem.Vector.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i32) + <: + Core.Core_arch.X86.t____m256i) + in + let k_times_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mulhi_epi16 k + (Libcrux_intrinsics.Avx2.mm256_set1_epi32 (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + i16) + <: + i32) + <: + Core.Core_arch.X86.t____m256i) + in + let value_high:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_srli_epi32 16l v in + let result:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_sub_epi16 value_high k_times_modulus + in + let result:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_slli_epi32 16l result in + Libcrux_intrinsics.Avx2.mm256_srai_epi32 16l result diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti new file mode 100644 index 000000000..b808a037f --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti @@ -0,0 +1,41 @@ +module Libcrux_ml_kem.Vector.Avx2.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let v_BARRETT_MULTIPLIER: i16 = Rust_primitives.Hax.dropped_body + +val add (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +/// See Section 3.2 of the implementation notes document for an explanation +/// of this code. +val barrett_reduce (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val bitwise_and_with_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val cond_subtract_3329_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_by_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_by_constants (v c: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_m128i_by_constants (v c: Core.Core_arch.X86.t____m128i) + : Prims.Pure Core.Core_arch.X86.t____m128i Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_reduce_i32s (v: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val multiply_by_constant (vector: Core.Core_arch.X86.t____m256i) (constant: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val shift_right (v_SHIFT_BY: i32) (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val sub (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst new file mode 100644 index 000000000..4f3a8bf4c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst @@ -0,0 +1,178 @@ +module Libcrux_ml_kem.Vector.Avx2.Compress +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let mulhi_mm256_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) = + let prod02:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_mul_epu32 lhs rhs in + let prod13:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mul_epu32 (Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 245l lhs + <: + Core.Core_arch.X86.t____m256i) + (Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 245l rhs <: Core.Core_arch.X86.t____m256i) + in + Libcrux_intrinsics.Avx2.mm256_unpackhi_epi64 (Libcrux_intrinsics.Avx2.mm256_unpacklo_epi32 prod02 + prod13 + <: + Core.Core_arch.X86.t____m256i) + (Libcrux_intrinsics.Avx2.mm256_unpackhi_epi32 prod02 prod13 <: Core.Core_arch.X86.t____m256i) + +let compress_ciphertext_coefficient + (v_COEFFICIENT_BITS: i32) + (vector: Core.Core_arch.X86.t____m256i) + = + let field_modulus_halved:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set1_epi32 (((cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + <: + i16) + <: + i32) -! + 1l + <: + i32) /! + 2l + <: + i32) + in + let compression_factor:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set1_epi32 10321340l + in + let coefficient_bits_mask:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set1_epi32 ((1l < Prims.l_True) + +val compress_message_coefficient (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val decompress_ciphertext_coefficient + (v_COEFFICIENT_BITS: i32) + (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val mulhi_mm256_epi32 (lhs rhs: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst new file mode 100644 index 000000000..e91e3563f --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst @@ -0,0 +1,211 @@ +module Libcrux_ml_kem.Vector.Avx2.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let inv_ntt_layer_1_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) = + let lhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 245l vector in + let rhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 160l vector in + let rhs:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 rhs + (Libcrux_intrinsics.Avx2.mm256_set_epi16 (-1s) (-1s) 1s 1s (-1s) (-1s) 1s 1s (-1s) (-1s) 1s 1s + (-1s) (-1s) 1s 1s + <: + Core.Core_arch.X86.t____m256i) + in + let sum:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_add_epi16 lhs rhs in + let sum_times_zetas:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constants sum + (Libcrux_intrinsics.Avx2.mm256_set_epi16 zeta3 zeta3 0s 0s zeta2 zeta2 0s 0s zeta1 zeta1 0s 0s + zeta0 zeta0 0s 0s + <: + Core.Core_arch.X86.t____m256i) + in + let sum:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.barrett_reduce sum + in + Libcrux_intrinsics.Avx2.mm256_blend_epi16 204l sum sum_times_zetas + +let inv_ntt_layer_2_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1: i16) = + let lhs:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_permute4x64_epi64 245l vector + in + let rhs:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_permute4x64_epi64 160l vector + in + let rhs:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi16 rhs + (Libcrux_intrinsics.Avx2.mm256_set_epi16 (-1s) (-1s) (-1s) (-1s) 1s 1s 1s 1s (-1s) (-1s) (-1s) + (-1s) 1s 1s 1s 1s + <: + Core.Core_arch.X86.t____m256i) + in + let sum:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_add_epi16 lhs rhs in + let sum_times_zetas:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constants sum + (Libcrux_intrinsics.Avx2.mm256_set_epi16 zeta1 zeta1 zeta1 zeta1 0s 0s 0s 0s zeta0 zeta0 zeta0 + zeta0 0s 0s 0s 0s + <: + Core.Core_arch.X86.t____m256i) + in + Libcrux_intrinsics.Avx2.mm256_blend_epi16 240l sum sum_times_zetas + +let inv_ntt_layer_3_step (vector: Core.Core_arch.X86.t____m256i) (zeta: i16) = + let lhs:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_extracti128_si256 1l vector + in + let rhs:Core.Core_arch.X86.t____m128i = Libcrux_intrinsics.Avx2.mm256_castsi256_si128 vector in + let lower_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_add_epi16 lhs rhs + in + let upper_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_sub_epi16 lhs rhs + in + let upper_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_m128i_by_constants upper_coefficients + (Libcrux_intrinsics.Avx2.mm_set1_epi16 zeta <: Core.Core_arch.X86.t____m128i) + in + let combined:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_castsi128_si256 lower_coefficients + in + Libcrux_intrinsics.Avx2.mm256_inserti128_si256 1l combined upper_coefficients + +let ntt_layer_1_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) = + let zetas:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta3 <: i16) + (Core.Ops.Arith.Neg.neg zeta3 <: i16) zeta3 zeta3 (Core.Ops.Arith.Neg.neg zeta2 <: i16) + (Core.Ops.Arith.Neg.neg zeta2 <: i16) zeta2 zeta2 (Core.Ops.Arith.Neg.neg zeta1 <: i16) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 (Core.Ops.Arith.Neg.neg zeta0 <: i16) + (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 + in + let rhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 245l vector in + let rhs:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas + in + let lhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 160l vector in + Libcrux_intrinsics.Avx2.mm256_add_epi16 lhs rhs + +let ntt_layer_2_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1: i16) = + let zetas:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta1 <: i16) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) (Core.Ops.Arith.Neg.neg zeta1 <: i16) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 zeta1 zeta1 + (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) + (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 zeta0 + zeta0 + in + let rhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 238l vector in + let rhs:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas + in + let lhs:Core.Core_arch.X86.t____m256i = Libcrux_intrinsics.Avx2.mm256_shuffle_epi32 68l vector in + Libcrux_intrinsics.Avx2.mm256_add_epi16 lhs rhs + +let ntt_layer_3_step (vector: Core.Core_arch.X86.t____m256i) (zeta: i16) = + let rhs:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_extracti128_si256 1l vector + in + let rhs:Core.Core_arch.X86.t____m128i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_m128i_by_constants rhs + (Libcrux_intrinsics.Avx2.mm_set1_epi16 zeta <: Core.Core_arch.X86.t____m128i) + in + let lhs:Core.Core_arch.X86.t____m128i = Libcrux_intrinsics.Avx2.mm256_castsi256_si128 vector in + let lower_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_add_epi16 lhs rhs + in + let upper_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_sub_epi16 lhs rhs + in + let combined:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_castsi128_si256 lower_coefficients + in + Libcrux_intrinsics.Avx2.mm256_inserti128_si256 1l combined upper_coefficients + +let ntt_multiply (lhs rhs: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) = + let shuffle_with:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set_epi8 15y 14y 11y 10y 7y 6y 3y 2y 13y 12y 9y 8y 5y 4y 1y 0y 15y + 14y 11y 10y 7y 6y 3y 2y 13y 12y 9y 8y 5y 4y 1y 0y + in + let lhs_shuffled:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_shuffle_epi8 lhs shuffle_with + in + let lhs_shuffled:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_permute4x64_epi64 216l lhs_shuffled + in + let lhs_evens:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_castsi256_si128 lhs_shuffled + in + let lhs_evens:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_cvtepi16_epi32 lhs_evens + in + let lhs_odds:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_extracti128_si256 1l lhs_shuffled + in + let lhs_odds:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_cvtepi16_epi32 lhs_odds + in + let rhs_shuffled:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_shuffle_epi8 rhs shuffle_with + in + let rhs_shuffled:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_permute4x64_epi64 216l rhs_shuffled + in + let rhs_evens:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_castsi256_si128 rhs_shuffled + in + let rhs_evens:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_cvtepi16_epi32 rhs_evens + in + let rhs_odds:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_extracti128_si256 1l rhs_shuffled + in + let rhs_odds:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_cvtepi16_epi32 rhs_odds + in + let left:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi32 lhs_evens rhs_evens + in + let right:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi32 lhs_odds rhs_odds + in + let right:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_reduce_i32s right + in + let right:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_mullo_epi32 right + (Libcrux_intrinsics.Avx2.mm256_set_epi32 (Core.Ops.Arith.Neg.neg (cast (zeta3 <: i16) <: i32) + <: + i32) + (cast (zeta3 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta2 <: i16) <: i32) <: i32) + (cast (zeta2 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta1 <: i16) <: i32) <: i32) + (cast (zeta1 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta0 <: i16) <: i32) <: i32) + (cast (zeta0 <: i16) <: i32) + <: + Core.Core_arch.X86.t____m256i) + in + let products_left:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_add_epi32 left right + in + let products_left:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_reduce_i32s products_left + in + let rhs_adjacent_swapped:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_shuffle_epi8 rhs + (Libcrux_intrinsics.Avx2.mm256_set_epi8 13y 12y 15y 14y 9y 8y 11y 10y 5y 4y 7y 6y 1y 0y 3y 2y + 13y 12y 15y 14y 9y 8y 11y 10y 5y 4y 7y 6y 1y 0y 3y 2y + <: + Core.Core_arch.X86.t____m256i) + in + let products_right:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_madd_epi16 lhs rhs_adjacent_swapped + in + let products_right:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_reduce_i32s products_right + in + let products_right:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_slli_epi32 16l products_right + in + Libcrux_intrinsics.Avx2.mm256_blend_epi16 170l products_left products_right diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti new file mode 100644 index 000000000..75b8e11b7 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti @@ -0,0 +1,27 @@ +module Libcrux_ml_kem.Vector.Avx2.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +val inv_ntt_layer_1_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val inv_ntt_layer_2_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val inv_ntt_layer_3_step (vector: Core.Core_arch.X86.t____m256i) (zeta: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val ntt_layer_1_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val ntt_layer_2_step (vector: Core.Core_arch.X86.t____m256i) (zeta0 zeta1: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val ntt_layer_3_step (vector: Core.Core_arch.X86.t____m256i) (zeta: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val ntt_multiply (lhs rhs: Core.Core_arch.X86.t____m256i) (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +let ntt_multiply__PERMUTE_WITH: i32 = Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fst new file mode 100644 index 000000000..0c920b70f --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fst @@ -0,0 +1,423 @@ +module Libcrux_ml_kem.Vector.Avx2.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let from_i16_array (array: t_Array i16 (sz 16)) = { f_elements = array } <: t_PortableVector + +let serialize_11_ (v: t_PortableVector) = + let result:t_Array u8 (sz 22) = Rust_primitives.Hax.repeat 0uy (sz 22) in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + (cast (v.f_elements.[ sz 0 ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 1) + (((cast ((v.f_elements.[ sz 1 ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 2) + (((cast ((v.f_elements.[ sz 2 ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (cast (((v.f_elements.[ sz 2 ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (((cast ((v.f_elements.[ sz 3 ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 5) + (((cast ((v.f_elements.[ sz 4 ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 6) + (((cast ((v.f_elements.[ sz 5 ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (cast (((v.f_elements.[ sz 5 ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 8) + (((cast ((v.f_elements.[ sz 6 ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (((cast ((v.f_elements.[ sz 7 ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 10) + (cast ((v.f_elements.[ sz 7 ] <: i16) >>! 3l <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 11) + (cast (v.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 12) + (((cast ((v.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 13) + (((cast ((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 14) + (cast (((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 15) + (((cast ((v.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 16) + (((cast ((v.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 17) + (((cast ((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 18) + (cast (((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 19) + (((cast ((v.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 20) + (((cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 21) + (cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) >>! 3l <: i16) <: u8) + in + result + +let to_i16_array (v: t_PortableVector) = v.f_elements + +let zero (_: Prims.unit) = + { f_elements = Rust_primitives.Hax.repeat 0s (sz 16) } <: t_PortableVector + +let deserialize_11_ (bytes: t_Slice u8) = + let result:t_PortableVector = zero () in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 0) + ((((cast (bytes.[ sz 1 ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 2) + (((((cast (bytes.[ sz 4 ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 3) + ((((cast (bytes.[ sz 5 ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 4) + ((((cast (bytes.[ sz 6 ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 5) + (((((cast (bytes.[ sz 8 ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 6) + ((((cast (bytes.[ sz 9 ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 7) + (((cast (bytes.[ sz 10 ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 8) + ((((cast (bytes.[ sz 11 +! sz 1 <: usize ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 10) + (((((cast (bytes.[ sz 11 +! sz 4 <: usize ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 11) + ((((cast (bytes.[ sz 11 +! sz 5 <: usize ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 12) + ((((cast (bytes.[ sz 11 +! sz 6 <: usize ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 13) + (((((cast (bytes.[ sz 11 +! sz 8 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 14) + ((((cast (bytes.[ sz 11 +! sz 9 <: usize ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 15) + (((cast (bytes.[ sz 11 +! sz 10 <: usize ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + t_PortableVector + in + result diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fsti new file mode 100644 index 000000000..ec0c98177 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Portable.fsti @@ -0,0 +1,23 @@ +module Libcrux_ml_kem.Vector.Avx2.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +unfold +let t_FieldElement = i16 + +type t_PortableVector = { f_elements:t_Array i16 (sz 16) } + +val deserialize_11_ (bytes: t_Slice u8) + : Prims.Pure t_PortableVector Prims.l_True (fun _ -> Prims.l_True) + +val from_i16_array (array: t_Array i16 (sz 16)) + : Prims.Pure t_PortableVector Prims.l_True (fun _ -> Prims.l_True) + +val serialize_11_ (v: t_PortableVector) + : Prims.Pure (t_Array u8 (sz 22)) Prims.l_True (fun _ -> Prims.l_True) + +val to_i16_array (v: t_PortableVector) + : Prims.Pure (t_Array i16 (sz 16)) Prims.l_True (fun _ -> Prims.l_True) + +val zero: Prims.unit -> Prims.Pure t_PortableVector Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst new file mode 100644 index 000000000..c8b83fae6 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst @@ -0,0 +1,78 @@ +module Libcrux_ml_kem.Vector.Avx2.Sampling +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let rejection_sample (input: t_Slice u8) (output: t_Slice i16) = + let field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set1_epi16 Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS + in + let potential_coefficients:Core.Core_arch.X86.t____m256i = + Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_12_ input + in + let compare_with_field_modulus:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_cmpgt_epi16 field_modulus potential_coefficients + in + let good:t_Array u8 (sz 2) = + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_1_ compare_with_field_modulus + in + let lower_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_kem.Vector.Rej_sample_table.v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 0 ] + <: + u8) + <: + usize ] + in + let lower_shuffles:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_loadu_si128 (Rust_primitives.unsize lower_shuffles <: t_Slice u8) + in + let lower_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_castsi256_si128 potential_coefficients + in + let lower_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_shuffle_epi8 lower_coefficients lower_shuffles + in + let output:t_Slice i16 = Libcrux_intrinsics.Avx2.mm_storeu_si128 output lower_coefficients in + let sampled_count:usize = + cast (Core.Num.impl__u8__count_ones (good.[ sz 0 ] <: u8) <: u32) <: usize + in + let upper_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_kem.Vector.Rej_sample_table.v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 1 ] + <: + u8) + <: + usize ] + in + let upper_shuffles:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_loadu_si128 (Rust_primitives.unsize upper_shuffles <: t_Slice u8) + in + let upper_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm256_extracti128_si256 1l potential_coefficients + in + let upper_coefficients:Core.Core_arch.X86.t____m128i = + Libcrux_intrinsics.Avx2.mm_shuffle_epi8 upper_coefficients upper_shuffles + in + let output:t_Slice i16 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range output + ({ + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2.mm_storeu_si128 (output.[ { + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i16) + upper_coefficients + <: + t_Slice i16) + in + let hax_temp_output:usize = + sampled_count +! (cast (Core.Num.impl__u8__count_ones (good.[ sz 1 ] <: u8) <: u32) <: usize) + in + output, hax_temp_output <: (t_Slice i16 & usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti new file mode 100644 index 000000000..361ba6196 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti @@ -0,0 +1,7 @@ +module Libcrux_ml_kem.Vector.Avx2.Sampling +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +val rejection_sample (input: t_Slice u8) (output: t_Slice i16) + : Prims.Pure (t_Slice i16 & usize) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst new file mode 100644 index 000000000..068b98360 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst @@ -0,0 +1,537 @@ +module Libcrux_ml_kem.Vector.Avx2.Serialize +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let deserialize_1_ (bytes: t_Slice u8) = + let coefficients:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set_epi16 (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) + in + let shift_lsb_to_msb:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_set_epi16 (1s <>! 8l <: i32) <: u8) + in + serialized + +let serialize_10_ (vector: Core.Core_arch.X86.t____m256i) = + let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let adjacent_2_combined:Core.Core_arch.X86.t____m256i = + Libcrux_intrinsics.Avx2.mm256_madd_epi16 vector + (Libcrux_intrinsics.Avx2.mm256_set_epi16 (1s < Prims.l_True) + +val deserialize_10_ (bytes: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_11_ (bytes: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_12_ (bytes: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_4_ (bytes: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_5_ (bytes: t_Slice u8) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val serialize_1_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 2)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_10_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 20)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_11_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 22)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_12_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 24)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_4_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 8)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_5_ (vector: Core.Core_arch.X86.t____m256i) + : Prims.Pure (t_Array u8 (sz 10)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst new file mode 100644 index 000000000..37cc8b8fd --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst @@ -0,0 +1,17 @@ +module Libcrux_ml_kem.Vector.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let from_i16_array (array: t_Slice i16) = + { f_elements = Libcrux_intrinsics.Avx2.mm256_loadu_si256_i16 array } <: t_SIMD256Vector + +let to_i16_array (v: t_SIMD256Vector) = + let output:t_Array i16 (sz 16) = Rust_primitives.Hax.repeat 0s (sz 16) in + let output:t_Array i16 (sz 16) = + Libcrux_intrinsics.Avx2.mm256_storeu_si256_i16 output v.f_elements + in + output + +let zero (_: Prims.unit) = + { f_elements = Libcrux_intrinsics.Avx2.mm256_setzero_si256 () } <: t_SIMD256Vector diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti new file mode 100644 index 000000000..7d65a411a --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti @@ -0,0 +1,394 @@ +module Libcrux_ml_kem.Vector.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +type t_SIMD256Vector = { f_elements:Core.Core_arch.X86.t____m256i } + +val from_i16_array (array: t_Slice i16) + : Prims.Pure t_SIMD256Vector Prims.l_True (fun _ -> Prims.l_True) + +val to_i16_array (v: t_SIMD256Vector) + : Prims.Pure (t_Array i16 (sz 16)) Prims.l_True (fun _ -> Prims.l_True) + +val zero: Prims.unit -> Prims.Pure t_SIMD256Vector Prims.l_True (fun _ -> Prims.l_True) + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_kem.Vector.Traits.t_Operations t_SIMD256Vector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post = (fun (_: Prims.unit) (out: t_SIMD256Vector) -> true); + f_ZERO = (fun (_: Prims.unit) -> zero ()); + f_from_i16_array_pre = (fun (array: t_Slice i16) -> true); + f_from_i16_array_post = (fun (array: t_Slice i16) (out: t_SIMD256Vector) -> true); + f_from_i16_array = (fun (array: t_Slice i16) -> from_i16_array array); + f_add_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); + f_add_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_add + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.add lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_sub_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); + f_sub_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_sub + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.sub lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_multiply_by_constant_pre = (fun (v: t_SIMD256Vector) (c: i16) -> true); + f_multiply_by_constant_post = (fun (v: t_SIMD256Vector) (c: i16) (out: t_SIMD256Vector) -> true); + f_multiply_by_constant + = + (fun (v: t_SIMD256Vector) (c: i16) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.multiply_by_constant v.f_elements c } + <: + t_SIMD256Vector); + f_bitwise_and_with_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); + f_bitwise_and_with_constant_post + = + (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); + f_bitwise_and_with_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.bitwise_and_with_constant vector.f_elements constant + } + <: + t_SIMD256Vector); + f_shift_right_pre = (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> true); + f_shift_right_post + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.shift_right v_SHIFT_BY vector.f_elements + } + <: + t_SIMD256Vector); + f_cond_subtract_3329_pre = (fun (vector: t_SIMD256Vector) -> true); + f_cond_subtract_3329_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_cond_subtract_3329_ + = + (fun (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.cond_subtract_3329_ vector.f_elements } + <: + t_SIMD256Vector); + f_barrett_reduce_pre = (fun (vector: t_SIMD256Vector) -> true); + f_barrett_reduce_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_barrett_reduce + = + (fun (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.barrett_reduce vector.f_elements } + <: + t_SIMD256Vector); + f_montgomery_multiply_by_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); + f_montgomery_multiply_by_constant_post + = + (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); + f_montgomery_multiply_by_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constant vector.f_elements + constant + } + <: + t_SIMD256Vector); + f_compress_1_pre = (fun (vector: t_SIMD256Vector) -> true); + f_compress_1_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_compress_1_ + = + (fun (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.compress_message_coefficient vector.f_elements + } + <: + t_SIMD256Vector); + f_compress_pre = (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); + f_compress_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_compress + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.compress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_decompress_ciphertext_coefficient_pre + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); + f_decompress_ciphertext_coefficient_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_decompress_ciphertext_coefficient + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); + f_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_1_step vector.f_elements zeta0 zeta1 zeta2 zeta3 + } + <: + t_SIMD256Vector); + f_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); + f_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); + f_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + { + f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_2_step vector.f_elements zeta0 zeta1 + } + <: + t_SIMD256Vector); + f_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); + f_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); + f_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_inv_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); + f_inv_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_inv_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_1_step vector.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); + f_inv_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); + f_inv_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_2_step vector.f_elements zeta0 zeta1 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); + f_inv_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); + f_inv_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_ntt_multiply_pre + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + true); + f_ntt_multiply_post + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_ntt_multiply + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_multiply lhs.f_elements + rhs.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_serialize_1_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_1_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 2)) -> true); + f_serialize_1_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_1_ vector.f_elements); + f_deserialize_1_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_1_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_1_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_1_ bytes } + <: + t_SIMD256Vector); + f_serialize_4_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_4_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 8)) -> true); + f_serialize_4_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_4_ vector.f_elements); + f_deserialize_4_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_4_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_4_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_4_ bytes } + <: + t_SIMD256Vector); + f_serialize_5_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_5_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 10)) -> true); + f_serialize_5_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_5_ vector.f_elements); + f_deserialize_5_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_5_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_5_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_5_ bytes } + <: + t_SIMD256Vector); + f_serialize_10_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_10_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 20)) -> true); + f_serialize_10_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_10_ vector.f_elements); + f_deserialize_10_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_10_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_10_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_10_ bytes } + <: + t_SIMD256Vector); + f_serialize_11_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_11_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 22)) -> true); + f_serialize_11_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_11_ vector.f_elements); + f_deserialize_11_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_11_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_11_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_11_ bytes } + <: + t_SIMD256Vector); + f_serialize_12_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_12_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 24)) -> true); + f_serialize_12_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_12_ vector.f_elements); + f_deserialize_12_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_12_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_12_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_12_ bytes } + <: + t_SIMD256Vector); + f_rej_sample_pre = (fun (input: t_Slice u8) (output: t_Slice i16) -> true); + f_rej_sample_post + = + (fun (input: t_Slice u8) (output: t_Slice i16) (out1: (t_Slice i16 & usize)) -> true); + f_rej_sample + = + fun (input: t_Slice u8) (output: t_Slice i16) -> + let tmp0, out:(t_Slice i16 & usize) = + Libcrux_ml_kem.Vector.Avx2.Sampling.rejection_sample input output + in + let output:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out in + output, hax_temp_output <: (t_Slice i16 & usize) + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti new file mode 100644 index 000000000..931341051 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti @@ -0,0 +1,6 @@ +module Libcrux_ml_kem.Vector.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +type t_PortableVector = { f_elements:t_Array i16 (sz 16) } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti new file mode 100644 index 000000000..fbf536a4b --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti @@ -0,0 +1,7 @@ +module Libcrux_ml_kem.Vector.Rej_sample_table +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let v_REJECTION_SAMPLE_SHUFFLE_TABLE: t_Array (t_Array u8 (sz 16)) (sz 256) = + Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst new file mode 100644 index 000000000..97eee7c1d --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst @@ -0,0 +1,32 @@ +module Libcrux_ml_kem.Vector.Traits +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decompress_1_ + (#v_T: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: t_Operations v_T) + (v: v_T) + = f_bitwise_and_with_constant #v_T (f_sub #v_T (f_ZERO #v_T () <: v_T) v <: v_T) 1665s + +let montgomery_multiply_fe + (#v_T: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: t_Operations v_T) + (v: v_T) + (fer: i16) + = f_montgomery_multiply_by_constant #v_T v fer + +let to_standard_domain + (#v_T: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: t_Operations v_T) + (v: v_T) + = f_montgomery_multiply_by_constant #v_T v v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS + +let to_unsigned_representative + (#v_T: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: t_Operations v_T) + (a: v_T) + = + let t:v_T = f_shift_right #v_T 15l a in + let fm:v_T = f_bitwise_and_with_constant #v_T t v_FIELD_MODULUS in + f_add #v_T a fm diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti new file mode 100644 index 000000000..5c09d7209 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti @@ -0,0 +1,202 @@ +module Libcrux_ml_kem.Vector.Traits +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +class t_Operations (v_Self: Type0) = { + [@@@ FStar.Tactics.Typeclasses.no_method]_super_11581440318597584651:Core.Marker.t_Copy v_Self; + [@@@ FStar.Tactics.Typeclasses.no_method]_super_9442900250278684536:Core.Clone.t_Clone v_Self; + f_ZERO_pre:Prims.unit -> bool; + f_ZERO_post:Prims.unit -> v_Self -> bool; + f_ZERO:x0: Prims.unit -> Prims.Pure v_Self (f_ZERO_pre x0) (fun result -> f_ZERO_post x0 result); + f_from_i16_array_pre:t_Slice i16 -> bool; + f_from_i16_array_post:t_Slice i16 -> v_Self -> bool; + f_from_i16_array:x0: t_Slice i16 + -> Prims.Pure v_Self (f_from_i16_array_pre x0) (fun result -> f_from_i16_array_post x0 result); + f_add_pre:v_Self -> v_Self -> bool; + f_add_post:v_Self -> v_Self -> v_Self -> bool; + f_add:x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self (f_add_pre x0 x1) (fun result -> f_add_post x0 x1 result); + f_sub_pre:v_Self -> v_Self -> bool; + f_sub_post:v_Self -> v_Self -> v_Self -> bool; + f_sub:x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self (f_sub_pre x0 x1) (fun result -> f_sub_post x0 x1 result); + f_multiply_by_constant_pre:v_Self -> i16 -> bool; + f_multiply_by_constant_post:v_Self -> i16 -> v_Self -> bool; + f_multiply_by_constant:x0: v_Self -> x1: i16 + -> Prims.Pure v_Self + (f_multiply_by_constant_pre x0 x1) + (fun result -> f_multiply_by_constant_post x0 x1 result); + f_bitwise_and_with_constant_pre:v_Self -> i16 -> bool; + f_bitwise_and_with_constant_post:v_Self -> i16 -> v_Self -> bool; + f_bitwise_and_with_constant:x0: v_Self -> x1: i16 + -> Prims.Pure v_Self + (f_bitwise_and_with_constant_pre x0 x1) + (fun result -> f_bitwise_and_with_constant_post x0 x1 result); + f_shift_right_pre:v_SHIFT_BY: i32 -> v_Self -> bool; + f_shift_right_post:v_SHIFT_BY: i32 -> v_Self -> v_Self -> bool; + f_shift_right:v_SHIFT_BY: i32 -> x0: v_Self + -> Prims.Pure v_Self + (f_shift_right_pre v_SHIFT_BY x0) + (fun result -> f_shift_right_post v_SHIFT_BY x0 result); + f_cond_subtract_3329_pre:v_Self -> bool; + f_cond_subtract_3329_post:v_Self -> v_Self -> bool; + f_cond_subtract_3329_:x0: v_Self + -> Prims.Pure v_Self + (f_cond_subtract_3329_pre x0) + (fun result -> f_cond_subtract_3329_post x0 result); + f_barrett_reduce_pre:v_Self -> bool; + f_barrett_reduce_post:v_Self -> v_Self -> bool; + f_barrett_reduce:x0: v_Self + -> Prims.Pure v_Self (f_barrett_reduce_pre x0) (fun result -> f_barrett_reduce_post x0 result); + f_montgomery_multiply_by_constant_pre:v_Self -> i16 -> bool; + f_montgomery_multiply_by_constant_post:v_Self -> i16 -> v_Self -> bool; + f_montgomery_multiply_by_constant:x0: v_Self -> x1: i16 + -> Prims.Pure v_Self + (f_montgomery_multiply_by_constant_pre x0 x1) + (fun result -> f_montgomery_multiply_by_constant_post x0 x1 result); + f_compress_1_pre:v_Self -> bool; + f_compress_1_post:v_Self -> v_Self -> bool; + f_compress_1_:x0: v_Self + -> Prims.Pure v_Self (f_compress_1_pre x0) (fun result -> f_compress_1_post x0 result); + f_compress_pre:v_COEFFICIENT_BITS: i32 -> v_Self -> bool; + f_compress_post:v_COEFFICIENT_BITS: i32 -> v_Self -> v_Self -> bool; + f_compress:v_COEFFICIENT_BITS: i32 -> x0: v_Self + -> Prims.Pure v_Self + (f_compress_pre v_COEFFICIENT_BITS x0) + (fun result -> f_compress_post v_COEFFICIENT_BITS x0 result); + f_decompress_ciphertext_coefficient_pre:v_COEFFICIENT_BITS: i32 -> v_Self -> bool; + f_decompress_ciphertext_coefficient_post:v_COEFFICIENT_BITS: i32 -> v_Self -> v_Self -> bool; + f_decompress_ciphertext_coefficient:v_COEFFICIENT_BITS: i32 -> x0: v_Self + -> Prims.Pure v_Self + (f_decompress_ciphertext_coefficient_pre v_COEFFICIENT_BITS x0) + (fun result -> f_decompress_ciphertext_coefficient_post v_COEFFICIENT_BITS x0 result); + f_ntt_layer_1_step_pre:v_Self -> i16 -> i16 -> i16 -> i16 -> bool; + f_ntt_layer_1_step_post:v_Self -> i16 -> i16 -> i16 -> i16 -> v_Self -> bool; + f_ntt_layer_1_step:x0: v_Self -> x1: i16 -> x2: i16 -> x3: i16 -> x4: i16 + -> Prims.Pure v_Self + (f_ntt_layer_1_step_pre x0 x1 x2 x3 x4) + (fun result -> f_ntt_layer_1_step_post x0 x1 x2 x3 x4 result); + f_ntt_layer_2_step_pre:v_Self -> i16 -> i16 -> bool; + f_ntt_layer_2_step_post:v_Self -> i16 -> i16 -> v_Self -> bool; + f_ntt_layer_2_step:x0: v_Self -> x1: i16 -> x2: i16 + -> Prims.Pure v_Self + (f_ntt_layer_2_step_pre x0 x1 x2) + (fun result -> f_ntt_layer_2_step_post x0 x1 x2 result); + f_ntt_layer_3_step_pre:v_Self -> i16 -> bool; + f_ntt_layer_3_step_post:v_Self -> i16 -> v_Self -> bool; + f_ntt_layer_3_step:x0: v_Self -> x1: i16 + -> Prims.Pure v_Self + (f_ntt_layer_3_step_pre x0 x1) + (fun result -> f_ntt_layer_3_step_post x0 x1 result); + f_inv_ntt_layer_1_step_pre:v_Self -> i16 -> i16 -> i16 -> i16 -> bool; + f_inv_ntt_layer_1_step_post:v_Self -> i16 -> i16 -> i16 -> i16 -> v_Self -> bool; + f_inv_ntt_layer_1_step:x0: v_Self -> x1: i16 -> x2: i16 -> x3: i16 -> x4: i16 + -> Prims.Pure v_Self + (f_inv_ntt_layer_1_step_pre x0 x1 x2 x3 x4) + (fun result -> f_inv_ntt_layer_1_step_post x0 x1 x2 x3 x4 result); + f_inv_ntt_layer_2_step_pre:v_Self -> i16 -> i16 -> bool; + f_inv_ntt_layer_2_step_post:v_Self -> i16 -> i16 -> v_Self -> bool; + f_inv_ntt_layer_2_step:x0: v_Self -> x1: i16 -> x2: i16 + -> Prims.Pure v_Self + (f_inv_ntt_layer_2_step_pre x0 x1 x2) + (fun result -> f_inv_ntt_layer_2_step_post x0 x1 x2 result); + f_inv_ntt_layer_3_step_pre:v_Self -> i16 -> bool; + f_inv_ntt_layer_3_step_post:v_Self -> i16 -> v_Self -> bool; + f_inv_ntt_layer_3_step:x0: v_Self -> x1: i16 + -> Prims.Pure v_Self + (f_inv_ntt_layer_3_step_pre x0 x1) + (fun result -> f_inv_ntt_layer_3_step_post x0 x1 result); + f_ntt_multiply_pre:v_Self -> v_Self -> i16 -> i16 -> i16 -> i16 -> bool; + f_ntt_multiply_post:v_Self -> v_Self -> i16 -> i16 -> i16 -> i16 -> v_Self -> bool; + f_ntt_multiply:x0: v_Self -> x1: v_Self -> x2: i16 -> x3: i16 -> x4: i16 -> x5: i16 + -> Prims.Pure v_Self + (f_ntt_multiply_pre x0 x1 x2 x3 x4 x5) + (fun result -> f_ntt_multiply_post x0 x1 x2 x3 x4 x5 result); + f_serialize_1_pre:v_Self -> bool; + f_serialize_1_post:v_Self -> t_Array u8 (sz 2) -> bool; + f_serialize_1_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 2)) + (f_serialize_1_pre x0) + (fun result -> f_serialize_1_post x0 result); + f_deserialize_1_pre:t_Slice u8 -> bool; + f_deserialize_1_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_1_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_1_pre x0) (fun result -> f_deserialize_1_post x0 result); + f_serialize_4_pre:v_Self -> bool; + f_serialize_4_post:v_Self -> t_Array u8 (sz 8) -> bool; + f_serialize_4_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 8)) + (f_serialize_4_pre x0) + (fun result -> f_serialize_4_post x0 result); + f_deserialize_4_pre:t_Slice u8 -> bool; + f_deserialize_4_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_4_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_4_pre x0) (fun result -> f_deserialize_4_post x0 result); + f_serialize_5_pre:v_Self -> bool; + f_serialize_5_post:v_Self -> t_Array u8 (sz 10) -> bool; + f_serialize_5_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 10)) + (f_serialize_5_pre x0) + (fun result -> f_serialize_5_post x0 result); + f_deserialize_5_pre:t_Slice u8 -> bool; + f_deserialize_5_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_5_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_5_pre x0) (fun result -> f_deserialize_5_post x0 result); + f_serialize_10_pre:v_Self -> bool; + f_serialize_10_post:v_Self -> t_Array u8 (sz 20) -> bool; + f_serialize_10_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 20)) + (f_serialize_10_pre x0) + (fun result -> f_serialize_10_post x0 result); + f_deserialize_10_pre:t_Slice u8 -> bool; + f_deserialize_10_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_10_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_10_pre x0) (fun result -> f_deserialize_10_post x0 result); + f_serialize_11_pre:v_Self -> bool; + f_serialize_11_post:v_Self -> t_Array u8 (sz 22) -> bool; + f_serialize_11_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 22)) + (f_serialize_11_pre x0) + (fun result -> f_serialize_11_post x0 result); + f_deserialize_11_pre:t_Slice u8 -> bool; + f_deserialize_11_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_11_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_11_pre x0) (fun result -> f_deserialize_11_post x0 result); + f_serialize_12_pre:v_Self -> bool; + f_serialize_12_post:v_Self -> t_Array u8 (sz 24) -> bool; + f_serialize_12_:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 24)) + (f_serialize_12_pre x0) + (fun result -> f_serialize_12_post x0 result); + f_deserialize_12_pre:t_Slice u8 -> bool; + f_deserialize_12_post:t_Slice u8 -> v_Self -> bool; + f_deserialize_12_:x0: t_Slice u8 + -> Prims.Pure v_Self (f_deserialize_12_pre x0) (fun result -> f_deserialize_12_post x0 result); + f_rej_sample_pre:t_Slice u8 -> t_Slice i16 -> bool; + f_rej_sample_post:t_Slice u8 -> t_Slice i16 -> (t_Slice i16 & usize) -> bool; + f_rej_sample:x0: t_Slice u8 -> x1: t_Slice i16 + -> Prims.Pure (t_Slice i16 & usize) + (f_rej_sample_pre x0 x1) + (fun result -> f_rej_sample_post x0 x1 result) +} + +let v_FIELD_ELEMENTS_IN_VECTOR: usize = Rust_primitives.Hax.dropped_body + +let v_FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body + +let v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R: u32 = Rust_primitives.Hax.dropped_body + +let v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body + +val decompress_1_ (#v_T: Type0) {| i1: t_Operations v_T |} (v: v_T) + : Prims.Pure v_T Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_fe (#v_T: Type0) {| i1: t_Operations v_T |} (v: v_T) (fer: i16) + : Prims.Pure v_T Prims.l_True (fun _ -> Prims.l_True) + +val to_standard_domain (#v_T: Type0) {| i1: t_Operations v_T |} (v: v_T) + : Prims.Pure v_T Prims.l_True (fun _ -> Prims.l_True) + +val to_unsigned_representative (#v_T: Type0) {| i1: t_Operations v_T |} (a: v_T) + : Prims.Pure v_T Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fst new file mode 100644 index 000000000..c80c01c5c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fst @@ -0,0 +1,4871 @@ +module Libcrux_ml_kem.Vector +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + () + +let barrett_reduce_element (value: i16) = + let t:i32 = + ((Core.Convert.f_from #i32 #i16 value <: i32) *! v_BARRETT_MULTIPLIER <: i32) +! + (v_BARRETT_R >>! 1l <: i32) + in + let quotient:i16 = cast (t >>! v_BARRETT_SHIFT <: i32) <: i16 in + value -! (quotient *! Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) + +let compress_message_coefficient (fe: u16) = + let (shifted: i16):i16 = 1664s -! (cast (fe <: u16) <: i16) in + let mask:i16 = shifted >>! 15l in + let shifted_to_positive:i16 = mask ^. shifted in + let shifted_positive_in_range:i16 = shifted_to_positive -! 832s in + cast ((shifted_positive_in_range >>! 15l <: i16) &. 1s <: i16) <: u8 + +let get_n_least_significant_bits (n: u8) (value: u32) = value &. ((1ul <>! 35l in + cast (get_n_least_significant_bits coefficient_bits (cast (compressed <: u64) <: u32) <: u32) + <: + i16 + +let montgomery_reduce_element (value: i32) = + let _:i32 = v_MONTGOMERY_R in + let k:i32 = + (cast (cast (value <: i32) <: i16) <: i32) *! + (cast (Libcrux_ml_kem.Vector.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R <: u32) <: i32) + in + let k_times_modulus:i32 = + (cast (cast (k <: i32) <: i16) <: i32) *! + (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) + in + let c:i16 = cast (k_times_modulus >>! v_MONTGOMERY_SHIFT <: i32) <: i16 in + let value_high:i16 = cast (value >>! v_MONTGOMERY_SHIFT <: i32) <: i16 in + value_high -! c + +let montgomery_multiply_fe_by_fer (fe fer: i16) = + montgomery_reduce_element ((cast (fe <: i16) <: i32) *! (cast (fer <: i16) <: i32) <: i32) + +let ntt_multiply_binomials (a0, a1: (i16 & i16)) (b0, b1: (i16 & i16)) (zeta: i16) = + montgomery_reduce_element (((cast (a0 <: i16) <: i32) *! (cast (b0 <: i16) <: i32) <: i32) +! + ((cast (montgomery_reduce_element ((cast (a1 <: i16) <: i32) *! (cast (b1 <: i16) <: i32) + <: + i32) + <: + i16) + <: + i32) *! + (cast (zeta <: i16) <: i32) + <: + i32) + <: + i32), + montgomery_reduce_element (((cast (a0 <: i16) <: i32) *! (cast (b1 <: i16) <: i32) <: i32) +! + ((cast (a1 <: i16) <: i32) *! (cast (b0 <: i16) <: i32) <: i32) + <: + i32) + <: + (i16 & i16) + +let rej_sample (a: t_Slice u8) (result: t_Slice i16) = + let sampled:usize = sz 0 in + let result, sampled:(t_Slice i16 & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Chunks + u8) + (Core.Slice.impl__chunks #u8 a (sz 3) <: Core.Slice.Iter.t_Chunks u8) + <: + Core.Slice.Iter.t_Chunks u8) + (result, sampled <: (t_Slice i16 & usize)) + (fun temp_0_ bytes -> + let result, sampled:(t_Slice i16 & usize) = temp_0_ in + let bytes:t_Slice u8 = bytes in + let b1:i16 = cast (bytes.[ sz 0 ] <: u8) <: i16 in + let b2:i16 = cast (bytes.[ sz 1 ] <: u8) <: i16 in + let b3:i16 = cast (bytes.[ sz 2 ] <: u8) <: i16 in + let d1:i16 = ((b2 &. 15s <: i16) <>! 4l <: i16) in + let result, sampled:(t_Slice i16 & usize) = + if d1 <. Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS && sampled <. sz 16 + then + let result:t_Slice i16 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result sampled d1 + in + result, sampled +! sz 1 <: (t_Slice i16 & usize) + else result, sampled <: (t_Slice i16 & usize) + in + if d2 <. Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS && sampled <. sz 16 + then + let result:t_Slice i16 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result sampled d2 + in + result, sampled +! sz 1 <: (t_Slice i16 & usize) + else result, sampled <: (t_Slice i16 & usize)) + in + let hax_temp_output:usize = sampled in + result, hax_temp_output <: (t_Slice i16 & usize) + +let add (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let lhs:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + lhs + (fun lhs i -> + let lhs:Libcrux_ml_kem.Vector.Portable.t_PortableVector = lhs in + let i:usize = i in + { + lhs with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize lhs + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) +! + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + lhs + +let barrett_reduce (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (barrett_reduce_element (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let bitwise_and_with_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) &. c <: i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let compress (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (compress_ciphertext_coefficient (cast (v_COEFFICIENT_BITS <: i32) <: u8) + (cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) <: u16) + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let compress_1_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (cast (compress_message_coefficient (cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ + i ] + <: + i16) + <: + u16) + <: + u8) + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let cond_subtract_3329_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + let _:Prims.unit = + if true + then + let _:Prims.unit = + if + ~.(((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) >=. 0s <: bool) && + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) <. 4096s <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: v.elements[i] >= 0 && v.elements[i] < 4096" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + if (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) >=. 3329s + then + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) -! 3329s <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + else v) + in + v + +let decompress_ciphertext_coefficient + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + let decompressed:i32 = + (cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) <: i32) *! + (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) + in + let decompressed:i32 = + (decompressed <>! (v_COEFFICIENT_BITS +! 1l <: i32) in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (cast (decompressed <: i32) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v) + in + v + +let from_i16_array (array: t_Slice i16) = + { + Libcrux_ml_kem.Vector.Portable.f_elements + = + Core.Result.impl__unwrap #(t_Array i16 (sz 16)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice i16) + #(t_Array i16 (sz 16)) + (array.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i16) + <: + Core.Result.t_Result (t_Array i16 (sz 16)) Core.Array.t_TryFromSliceError) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + +let inv_ntt_layer_1_step + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + = + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 0 <: usize) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 + <: + usize ] + <: + i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 2 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta2 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 1 <: usize) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 + <: + usize ] + <: + i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 3 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta2 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 4 <: usize) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 + <: + usize ] + <: + i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 6 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta3 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 5 <: usize) + (barrett_reduce_element ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 + <: + usize ] + <: + i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) + <: + i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 7 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta3 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let inv_ntt_layer_2_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0 zeta1: i16) = + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (montgomery_multiply_fe_by_fer a_minus_b zeta0 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 0 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 4 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 1 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 5 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 2 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 6 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 3 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 7 <: usize) + (montgomery_multiply_fe_by_fer a_minus_b zeta1 <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let inv_ntt_layer_3_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) = + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 9 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 9 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 9) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 10 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 10 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 11 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 11 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 12 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 12 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 13 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 13 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 13) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 14 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 14 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let a_minus_b:i16 = + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 15 ] <: i16) -! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) +! + (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 15 ] <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + (montgomery_multiply_fe_by_fer a_minus_b zeta <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let montgomery_multiply_by_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] + <: + i16) + c + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let multiply_by_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) *! c <: i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let ntt_layer_1_step + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + = + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 + <: + usize ] + <: + i16) + zeta2 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 2 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 0 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 + <: + usize ] + <: + i16) + zeta2 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 3 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 1 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 + <: + usize ] + <: + i16) + zeta3 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 6 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 4 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 + <: + usize ] + <: + i16) + zeta3 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 7 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 5 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let ntt_layer_2_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0 zeta1: i16) = + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + zeta0 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 + <: + usize ] + <: + i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 4 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 0 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 + <: + usize ] + <: + i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 5 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 1 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 + <: + usize ] + <: + i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 6 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 2 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 + <: + usize ] + <: + i16) + zeta1 + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 7 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 3 <: usize) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let ntt_layer_3_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) = + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 ] <: i16) zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 9 ] <: i16) zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 9) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 10 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 11 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 12 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 13 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 13) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 14 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let t:i16 = + montgomery_multiply_fe_by_fer (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 15 ] <: i16) + zeta + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) -! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) +! t <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let serialize_1_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let result:t_Array u8 (sz 2) = Rust_primitives.Hax.repeat 0uy (sz 2) in + let result:t_Array u8 (sz 2) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + result + (fun result i -> + let result:t_Array u8 (sz 2) = result in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + ((result.[ sz 0 ] <: u8) |. + ((cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) <: u8) < + let result:t_Array u8 (sz 2) = result in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 1) + ((result.[ sz 1 ] <: u8) |. + ((cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) <: u8) <>! 8l <: i16) &. 3s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 2) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) &. 15s <: i16) <: u8) <>! 6l <: i16) &. 15s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) &. 3s <: i16) <: u8) <>! 4l <: i16) &. 63s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) >>! 2l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 5) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 6) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) &. 63s <: i16) <: u8) <>! 8l <: i16) &. 3s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) &. 15s <: i16) <: u8) <>! 6l <: i16) &. 15s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 8) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) &. 3s <: i16) <: u8) <>! 4l <: i16) &. 63s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) >>! 2l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 10) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 11) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 63s + <: + i16) + <: + u8) <>! + 8l + <: + i16) &. + 3s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 12) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 15s + <: + i16) + <: + u8) <>! + 6l + <: + i16) &. + 15s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 13) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. 3s + <: + i16) + <: + u8) <>! + 4l + <: + i16) &. + 63s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 14) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) >>! 2l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 15) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 16) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 63s + <: + i16) + <: + u8) <>! + 8l + <: + i16) &. + 3s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 17) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 15s + <: + i16) + <: + u8) <>! + 6l + <: + i16) &. + 15s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 18) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 3s + <: + i16) + <: + u8) <>! + 4l + <: + i16) &. + 63s + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 20) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 19) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) >>! 2l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + result + +let serialize_11_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let result:t_Array u8 (sz 22) = Rust_primitives.Hax.repeat 0uy (sz 22) in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + (cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 1) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 2) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) >>! 2l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 5) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 6) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) >>! 1l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 8) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 10) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) >>! 3l <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 11) + (cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 12) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 31s + <: + i16) + <: + u8) <>! 8l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 13) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 3s + <: + i16) + <: + u8) <>! 5l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 14) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) >>! 2l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 15) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. + 127s + <: + i16) + <: + u8) <>! + 10l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 16) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 15s + <: + i16) + <: + u8) <>! 7l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 17) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 1s + <: + i16) + <: + u8) <>! 4l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 18) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) >>! 1l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 19) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 63s + <: + i16) + <: + u8) <>! 9l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 20) + (((cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 7s + <: + i16) + <: + u8) <>! 6l + <: + i16) + <: + u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 21) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) >>! 3l + <: + i16) + <: + u8) + in + result + +let serialize_12_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let result:t_Array u8 (sz 24) = Rust_primitives.Hax.repeat 0uy (sz 24) in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 1) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16) >>! 8l <: i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) &. 15s <: i16) <>! 4l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16) >>! 8l <: i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) &. 15s <: i16) <>! 4l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 6) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) >>! 8l <: i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) &. 15s <: i16) <>! 4l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 10) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) >>! 8l <: i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) &. 15s <: i16) <>! 4l <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 12) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 13) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) >>! 8l + <: + i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 15s + <: + i16) <>! 4l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 15) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 16) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) >>! 8l + <: + i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. 15s + <: + i16) <>! 4l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 18) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 19) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) >>! 8l + <: + i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 15s + <: + i16) <>! 4l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 21) + (cast ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 255s + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 22) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) >>! 8l + <: + i16) |. + (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 15s + <: + i16) <>! 4l + <: + i16) &. + 255s + <: + i16) + <: + u8) + in + result + +let serialize_4_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let result:t_Array u8 (sz 8) = Rust_primitives.Hax.repeat 0uy (sz 8) in + let result:t_Array u8 (sz 8) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + (((cast (v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) <: u8) <>! 3l <: i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 2) + (cast ((((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (cast (((((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16) &. 3s <: i16) <>! 4l <: i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) <>! 2l <: i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 5) + (cast ((((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 7s + <: + i16) <>! 3l + <: + i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (cast ((((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 15s + <: + i16) <>! 1l + <: + i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 8) + (cast (((((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 3s + <: + i16) <>! 4l + <: + i16) + <: + i16) + <: + u8) + in + let result:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (cast (((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) <>! 2l + <: + i16) + <: + i16) + <: + u8) + in + result + +let shift_right (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + v + (fun v i -> + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = v in + let i:usize = i in + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((v.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) >>! v_SHIFT_BY <: i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + v + +let sub (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) = + let lhs:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + lhs + (fun lhs i -> + let lhs:Libcrux_ml_kem.Vector.Portable.t_PortableVector = lhs in + let i:usize = i in + { + lhs with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize lhs + .Libcrux_ml_kem.Vector.Portable.f_elements + i + ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) -! + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ i ] <: i16) + <: + i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + lhs + +let zero (_: Prims.unit) = + { Libcrux_ml_kem.Vector.Portable.f_elements = Rust_primitives.Hax.repeat 0s (sz 16) } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + +let deserialize_1_ (v: t_Slice u8) = + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + result + (fun result i -> + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = result in + let i:usize = i in + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (cast (((v.[ sz 0 ] <: u8) >>! i <: u8) &. 1uy <: u8) <: i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Ops.Range.t_Range + usize) + ({ + Core.Ops.Range.f_start = sz 8; + Core.Ops.Range.f_end = Libcrux_ml_kem.Vector.Traits.v_FIELD_ELEMENTS_IN_VECTOR + } + <: + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + result + (fun result i -> + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = result in + let i:usize = i in + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + i + (cast (((v.[ sz 1 ] <: u8) >>! (i -! sz 8 <: usize) <: u8) &. 1uy <: u8) <: i16) + <: + t_Array i16 (sz 16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector) + in + result + +let deserialize_10_ (bytes: t_Slice u8) = + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((((cast (bytes.[ sz 1 ] <: u8) <: i16) &. 3s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + ((((cast (bytes.[ sz 3 ] <: u8) <: i16) &. 63s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + (((cast (bytes.[ sz 4 ] <: u8) <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((((cast (bytes.[ sz 6 ] <: u8) <: i16) &. 3s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((((cast (bytes.[ sz 8 ] <: u8) <: i16) &. 63s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (((cast (bytes.[ sz 9 ] <: u8) <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + ((((cast (bytes.[ sz 10 +! sz 1 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + ((((cast (bytes.[ sz 10 +! sz 3 <: usize ] <: u8) <: i16) &. 63s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + (((cast (bytes.[ sz 10 +! sz 4 <: usize ] <: u8) <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + ((((cast (bytes.[ sz 10 +! sz 6 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + ((((cast (bytes.[ sz 10 +! sz 8 <: usize ] <: u8) <: i16) &. 63s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + (((cast (bytes.[ sz 10 +! sz 9 <: usize ] <: u8) <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + result + +let deserialize_11_ (bytes: t_Slice u8) = + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + ((((cast (bytes.[ sz 1 ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + (((((cast (bytes.[ sz 4 ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + ((((cast (bytes.[ sz 5 ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + ((((cast (bytes.[ sz 6 ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + (((((cast (bytes.[ sz 8 ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + ((((cast (bytes.[ sz 9 ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (((cast (bytes.[ sz 10 ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + ((((cast (bytes.[ sz 11 +! sz 1 <: usize ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + (((((cast (bytes.[ sz 11 +! sz 4 <: usize ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + ((((cast (bytes.[ sz 11 +! sz 5 <: usize ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + ((((cast (bytes.[ sz 11 +! sz 6 <: usize ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 13) + (((((cast (bytes.[ sz 11 +! sz 8 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + ((((cast (bytes.[ sz 11 +! sz 9 <: usize ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let result:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + result with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + (((cast (bytes.[ sz 11 +! sz 10 <: usize ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + result + +let deserialize_12_ (bytes: t_Slice u8) = + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let byte0:i16 = cast (bytes.[ sz 0 ] <: u8) <: i16 in + let byte1:i16 = cast (bytes.[ sz 1 ] <: u8) <: i16 in + let byte2:i16 = cast (bytes.[ sz 2 ] <: u8) <: i16 in + let byte3:i16 = cast (bytes.[ sz 3 ] <: u8) <: i16 in + let byte4:i16 = cast (bytes.[ sz 4 ] <: u8) <: i16 in + let byte5:i16 = cast (bytes.[ sz 5 ] <: u8) <: i16 in + let byte6:i16 = cast (bytes.[ sz 6 ] <: u8) <: i16 in + let byte7:i16 = cast (bytes.[ sz 7 ] <: u8) <: i16 in + let byte8:i16 = cast (bytes.[ sz 8 ] <: u8) <: i16 in + let byte9:i16 = cast (bytes.[ sz 9 ] <: u8) <: i16 in + let byte10:i16 = cast (bytes.[ sz 10 ] <: u8) <: i16 in + let byte11:i16 = cast (bytes.[ sz 11 ] <: u8) <: i16 in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + (((byte1 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + (((byte4 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + (((byte7 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + (((byte10 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let byte12:i16 = cast (bytes.[ sz 12 ] <: u8) <: i16 in + let byte13:i16 = cast (bytes.[ sz 13 ] <: u8) <: i16 in + let byte14:i16 = cast (bytes.[ sz 14 ] <: u8) <: i16 in + let byte15:i16 = cast (bytes.[ sz 15 ] <: u8) <: i16 in + let byte16:i16 = cast (bytes.[ sz 16 ] <: u8) <: i16 in + let byte17:i16 = cast (bytes.[ sz 17 ] <: u8) <: i16 in + let byte18:i16 = cast (bytes.[ sz 18 ] <: u8) <: i16 in + let byte19:i16 = cast (bytes.[ sz 19 ] <: u8) <: i16 in + let byte20:i16 = cast (bytes.[ sz 20 ] <: u8) <: i16 in + let byte21:i16 = cast (bytes.[ sz 21 ] <: u8) <: i16 in + let byte22:i16 = cast (bytes.[ sz 22 ] <: u8) <: i16 in + let byte23:i16 = cast (bytes.[ sz 23 ] <: u8) <: i16 in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + (((byte13 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + (((byte16 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + (((byte19 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let re:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + re with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + (((byte22 &. 15s <: i16) <>! 4l <: i16) &. 15s <: i16) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + re + +let deserialize_4_ (bytes: t_Slice u8) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + (cast ((bytes.[ sz 0 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + (cast (((bytes.[ sz 0 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + (cast ((bytes.[ sz 1 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + (cast (((bytes.[ sz 1 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + (cast ((bytes.[ sz 2 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + (cast (((bytes.[ sz 2 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + (cast ((bytes.[ sz 3 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (cast (((bytes.[ sz 3 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + (cast ((bytes.[ sz 4 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 9) + (cast (((bytes.[ sz 4 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + (cast ((bytes.[ sz 5 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + (cast (((bytes.[ sz 5 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + (cast ((bytes.[ sz 6 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 13) + (cast (((bytes.[ sz 6 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + (cast ((bytes.[ sz 7 ] <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + (cast (((bytes.[ sz 7 ] <: u8) >>! 4l <: u8) &. 15uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let deserialize_5_ (bytes: t_Slice u8) = + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + (cast ((bytes.[ sz 0 ] <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + (cast ((((bytes.[ sz 1 ] <: u8) &. 3uy <: u8) <>! 5l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + (cast (((bytes.[ sz 1 ] <: u8) >>! 2l <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + (cast ((((bytes.[ sz 2 ] <: u8) &. 15uy <: u8) <>! 7l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + (cast ((((bytes.[ sz 3 ] <: u8) &. 1uy <: u8) <>! 4l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + (cast (((bytes.[ sz 3 ] <: u8) >>! 1l <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + (cast ((((bytes.[ sz 4 ] <: u8) &. 7uy <: u8) <>! 6l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + (cast ((bytes.[ sz 4 ] <: u8) >>! 3l <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8) + (cast ((bytes.[ sz 5 +! sz 0 <: usize ] <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 9) + (cast ((((bytes.[ sz 5 +! sz 1 <: usize ] <: u8) &. 3uy <: u8) <>! 5l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 10) + (cast (((bytes.[ sz 5 +! sz 1 <: usize ] <: u8) >>! 2l <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 11) + (cast ((((bytes.[ sz 5 +! sz 2 <: usize ] <: u8) &. 15uy <: u8) <>! 7l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 12) + (cast ((((bytes.[ sz 5 +! sz 3 <: usize ] <: u8) &. 1uy <: u8) <>! 4l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 13) + (cast (((bytes.[ sz 5 +! sz 3 <: usize ] <: u8) >>! 1l <: u8) &. 31uy <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 14) + (cast ((((bytes.[ sz 5 +! sz 4 <: usize ] <: u8) &. 7uy <: u8) <>! 6l <: u8) + <: + u8) + <: + i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let v:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + v with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 15) + (cast ((bytes.[ sz 5 +! sz 4 <: usize ] <: u8) >>! 3l <: u8) <: i16) + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + v + +let ntt_multiply + (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + = + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = zero () in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 0 ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 1 ] <: i16) + <: + (i16 & i16)) + zeta0 + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 0) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 1) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 2 ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 3 ] <: i16) + <: + (i16 & i16)) + (Core.Ops.Arith.Neg.neg zeta0 <: i16) + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 2) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 3) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 4 ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 5 ] <: i16) + <: + (i16 & i16)) + zeta1 + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 4) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 5) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 6 ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 7 ] <: i16) + <: + (i16 & i16)) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 6) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 7) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] + <: + i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) + <: + (i16 & i16)) + zeta2 + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 0 <: usize) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 1 <: usize) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] + <: + i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) + <: + (i16 & i16)) + (Core.Ops.Arith.Neg.neg zeta2 <: i16) + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 2 <: usize) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 3 <: usize) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] + <: + i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) + <: + (i16 & i16)) + zeta3 + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 4 <: usize) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 5 <: usize) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let product:(i16 & i16) = + ntt_multiply_binomials ((lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] + <: + i16), + (lhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) + <: + (i16 & i16)) + ((rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16), + (rhs.Libcrux_ml_kem.Vector.Portable.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) + <: + (i16 & i16)) + (Core.Ops.Arith.Neg.neg zeta3 <: i16) + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 6 <: usize) + product._1 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + let out:Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + out with + Libcrux_ml_kem.Vector.Portable.f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_kem.Vector.Portable.f_elements + (sz 8 +! sz 7 <: usize) + product._2 + } + <: + Libcrux_ml_kem.Vector.Portable.t_PortableVector + in + out diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti new file mode 100644 index 000000000..d5b86c87e --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti @@ -0,0 +1,729 @@ +module Libcrux_ml_kem.Vector +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + () + +/// Values having this type hold a representative 'x' of the Kyber field. +/// We use 'fe' as a shorthand for this type. +unfold +let t_FieldElement = i16 + +/// If 'x' denotes a value of type `fe`, values having this type hold a +/// representative y ≡ x·MONTGOMERY_R (mod FIELD_MODULUS). +/// We use 'fer' as a shorthand for this type. +unfold +let t_FieldElementTimesMontgomeryR = i16 + +/// If 'x' denotes a value of type `fe`, values having this type hold a +/// representative y ≡ x·MONTGOMERY_R^(-1) (mod FIELD_MODULUS). +/// We use 'mfe' as a shorthand for this type +unfold +let t_MontgomeryFieldElement = i16 + +/// This is calculated as ⌊(BARRETT_R / FIELD_MODULUS) + 1/2⌋ +let v_BARRETT_MULTIPLIER: i32 = Rust_primitives.Hax.dropped_body + +let v_BARRETT_R: i32 = Rust_primitives.Hax.dropped_body + +let v_BARRETT_SHIFT: i32 = Rust_primitives.Hax.dropped_body + +let v_MONTGOMERY_R: i32 = Rust_primitives.Hax.dropped_body + +let v_MONTGOMERY_SHIFT: u8 = Rust_primitives.Hax.dropped_body + +/// Signed Barrett Reduction +/// Given an input `value`, `barrett_reduce` outputs a representative `result` +/// such that: +/// - result ≡ value (mod FIELD_MODULUS) +/// - the absolute value of `result` is bound as follows: +/// `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1) +/// In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`. +val barrett_reduce_element (value: i16) + : Prims.Pure i16 + (requires + (Core.Convert.f_from #i32 #i16 value <: i32) >. (Core.Ops.Arith.Neg.neg v_BARRETT_R <: i32) && + (Core.Convert.f_from #i32 #i16 value <: i32) <. v_BARRETT_R) + (ensures + fun result -> + let result:i16 = result in + result >. (Core.Ops.Arith.Neg.neg Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) && + result <. Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS) + +val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) + : Prims.Pure i16 + (requires + Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"55\"; line = \"182\" };\n lo = { Types.col = \"4\"; line = \"177\" } };\n ty = Types.Never }" + ) + (ensures + fun result -> + let result:i16 = result in + result >=. 0s && + result <. (Core.Num.impl__i16__pow 2s (cast (coefficient_bits <: u8) <: u32) <: i16)) + +/// The `compress_*` functions implement the `Compress` function specified in the NIST FIPS +/// 203 standard (Page 18, Expression 4.5), which is defined as: +/// ```plaintext +/// Compress_d: ℤq -> ℤ_{2ᵈ} +/// Compress_d(x) = ⌈(2ᵈ/q)·x⌋ +/// ``` +/// Since `⌈x⌋ = ⌊x + 1/2⌋` we have: +/// ```plaintext +/// Compress_d(x) = ⌊(2ᵈ/q)·x + 1/2⌋ +/// = ⌊(2^{d+1}·x + q) / 2q⌋ +/// ``` +/// For further information about the function implementations, consult the +/// `implementation_notes.pdf` document in this directory. +/// The NIST FIPS 203 standard can be found at +/// . +val compress_message_coefficient (fe: u16) + : Prims.Pure u8 + (requires + Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"80\"; line = \"146\" };\n lo = { Types.col = \"16\"; line = \"146\" } };\n ty = Types.Never }" + ) + (ensures + fun result -> + let result:u8 = result in + Hax_lib.implies ((833us <=. fe <: bool) && (fe <=. 2596us <: bool)) + (fun temp_0_ -> + let _:Prims.unit = temp_0_ in + result =. 1uy <: bool) && + Hax_lib.implies (~.((833us <=. fe <: bool) && (fe <=. 2596us <: bool)) <: bool) + (fun temp_0_ -> + let _:Prims.unit = temp_0_ in + result =. 0uy <: bool)) + +val get_n_least_significant_bits (n: u8) (value: u32) + : Prims.Pure u32 + (requires n =. 4uy || n =. 5uy || n =. 10uy || n =. 11uy || n =. v_MONTGOMERY_SHIFT) + (ensures + fun result -> + let result:u32 = result in + result <. (Core.Num.impl__u32__pow 2ul (Core.Convert.f_into #u8 #u32 n <: u32) <: u32)) + +/// If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to +/// `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to +/// `x · y`, as follows: +/// `fe · fer ≡ x · y · MONTGOMERY_R (mod FIELD_MODULUS)` +/// `montgomery_reduce` takes the value `x · y · MONTGOMERY_R` and outputs a representative +/// `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod FIELD_MODULUS)`. +val montgomery_multiply_fe_by_fer (fe fer: i16) + : Prims.Pure i16 Prims.l_True (fun _ -> Prims.l_True) + +/// Signed Montgomery Reduction +/// Given an input `value`, `montgomery_reduce` outputs a representative `o` +/// such that: +/// - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS) +/// - the absolute value of `o` is bound as follows: +/// `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2) +/// In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 · FIELD_MODULUS) / 2`. +val montgomery_reduce_element (value: i32) + : Prims.Pure i16 + (requires + Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"114\"; line = \"80\" };\n lo = { Types.col = \"16\"; line = \"80\" } };\n ty = Types.Never }" + ) + (ensures + fun result -> + let result:i16 = result in + result >=. + ((Core.Ops.Arith.Neg.neg (3s *! Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) + <: + i16) /! + 2s + <: + i16) && + result <=. ((3s *! Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) /! 2s <: i16)) + +/// Compute the product of two Kyber binomials with respect to the +/// modulus `X² - zeta`. +/// This function almost implements Algorithm 11 of the +/// NIST FIPS 203 standard, which is reproduced below: +/// ```plaintext +/// Input: a₀, a₁, b₀, b₁ ∈ ℤq. +/// Input: γ ∈ ℤq. +/// Output: c₀, c₁ ∈ ℤq. +/// c₀ ← a₀·b₀ + a₁·b₁·γ +/// c₁ ← a₀·b₁ + a₁·b₀ +/// return c₀, c₁ +/// ``` +/// We say "almost" because the coefficients output by this function are in +/// the Montgomery domain (unlike in the specification). +/// The NIST FIPS 203 standard can be found at +/// . +val ntt_multiply_binomials: (i16 & i16) -> (i16 & i16) -> zeta: i16 + -> Prims.Pure (i16 & i16) Prims.l_True (fun _ -> Prims.l_True) + +val rej_sample (a: t_Slice u8) (result: t_Slice i16) + : Prims.Pure (t_Slice i16 & usize) Prims.l_True (fun _ -> Prims.l_True) + +val add (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val barrett_reduce (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val bitwise_and_with_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val compress (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val compress_1_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val cond_subtract_3329_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val decompress_ciphertext_coefficient + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_1_ (v: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_10_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_11_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_12_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_4_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_5_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val from_i16_array (array: t_Slice i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val inv_ntt_layer_1_step + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val inv_ntt_layer_2_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0 zeta1: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val inv_ntt_layer_3_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val montgomery_multiply_by_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val multiply_by_constant (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_layer_1_step + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_layer_2_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0 zeta1: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_layer_3_step (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_multiply + (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0 zeta1 zeta2 zeta3: i16) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize_1_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 2)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_10_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 20)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_11_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 22)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_12_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 24)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_4_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 8)) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_5_ (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure (t_Array u8 (sz 10)) Prims.l_True (fun _ -> Prims.l_True) + +val shift_right (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val sub (lhs rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + : Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector + Prims.l_True + (fun _ -> Prims.l_True) + +val zero: Prims.unit + -> Prims.Pure Libcrux_ml_kem.Vector.Portable.t_PortableVector Prims.l_True (fun _ -> Prims.l_True) + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_kem.Vector.Traits.t_Operations Libcrux_ml_kem.Vector.Portable.t_PortableVector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_ZERO = (fun (_: Prims.unit) -> zero ()); + f_from_i16_array_pre = (fun (array: t_Slice i16) -> true); + f_from_i16_array_post + = + (fun (array: t_Slice i16) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_from_i16_array = (fun (array: t_Slice i16) -> from_i16_array array); + f_add_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_add_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_add + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + add lhs rhs); + f_sub_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_sub_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_sub + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + sub lhs rhs); + f_multiply_by_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) -> true); + f_multiply_by_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_multiply_by_constant + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) -> multiply_by_constant v c); + f_bitwise_and_with_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) -> true); + f_bitwise_and_with_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_bitwise_and_with_constant + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (c: i16) -> + bitwise_and_with_constant v c); + f_shift_right_pre + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_shift_right_post + = + (fun + (v_SHIFT_BY: i32) + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> + shift_right v_SHIFT_BY v); + f_cond_subtract_3329_pre = (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_cond_subtract_3329_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_cond_subtract_3329_ + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> cond_subtract_3329_ v); + f_barrett_reduce_pre = (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_barrett_reduce_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_barrett_reduce + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> barrett_reduce v); + f_montgomery_multiply_by_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (r: i16) -> true); + f_montgomery_multiply_by_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (r: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_montgomery_multiply_by_constant + = + (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (r: i16) -> + montgomery_multiply_by_constant v r); + f_compress_1_pre = (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_compress_1_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_compress_1_ = (fun (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> compress_1_ v); + f_compress_pre + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_compress_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_compress + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> + compress v_COEFFICIENT_BITS v); + f_decompress_ciphertext_coefficient_pre + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_decompress_ciphertext_coefficient_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_decompress_ciphertext_coefficient + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> + decompress_ciphertext_coefficient v_COEFFICIENT_BITS v); + f_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + true); + f_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); + f_ntt_layer_2_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0: i16) (zeta1: i16) -> true); + f_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_ntt_layer_2_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0: i16) (zeta1: i16) -> + ntt_layer_2_step a zeta0 zeta1); + f_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) -> true); + f_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) -> ntt_layer_3_step a zeta + ); + f_inv_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + true); + f_inv_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_inv_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + inv_ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); + f_inv_ntt_layer_2_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0: i16) (zeta1: i16) -> true); + f_inv_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_inv_ntt_layer_2_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta0: i16) (zeta1: i16) -> + inv_ntt_layer_2_step a zeta0 zeta1); + f_inv_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) -> true); + f_inv_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_inv_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (zeta: i16) -> + inv_ntt_layer_3_step a zeta); + f_ntt_multiply_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + true); + f_ntt_multiply_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + -> + true); + f_ntt_multiply + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + ntt_multiply lhs rhs zeta0 zeta1 zeta2 zeta3); + f_serialize_1_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_1_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 2)) -> true); + f_serialize_1_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_1_ a); + f_deserialize_1_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_1_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_1_ = (fun (a: t_Slice u8) -> deserialize_1_ a); + f_serialize_4_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_4_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 8)) -> true); + f_serialize_4_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_4_ a); + f_deserialize_4_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_4_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_4_ = (fun (a: t_Slice u8) -> deserialize_4_ a); + f_serialize_5_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_5_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 10)) -> true); + f_serialize_5_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_5_ a); + f_deserialize_5_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_5_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_5_ = (fun (a: t_Slice u8) -> deserialize_5_ a); + f_serialize_10_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_10_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 20)) -> true); + f_serialize_10_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_10_ a); + f_deserialize_10_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_10_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_10_ = (fun (a: t_Slice u8) -> deserialize_10_ a); + f_serialize_11_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_11_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 22)) -> true); + f_serialize_11_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_11_ a); + f_deserialize_11_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_11_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_11_ = (fun (a: t_Slice u8) -> deserialize_11_ a); + f_serialize_12_pre = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_serialize_12_post + = + (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) (out: t_Array u8 (sz 24)) -> true); + f_serialize_12_ = (fun (a: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> serialize_12_ a); + f_deserialize_12_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_12_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.t_PortableVector) -> true); + f_deserialize_12_ = (fun (a: t_Slice u8) -> deserialize_12_ a); + f_rej_sample_pre = (fun (a: t_Slice u8) (out: t_Slice i16) -> true); + f_rej_sample_post + = + (fun (a: t_Slice u8) (out: t_Slice i16) (out2: (t_Slice i16 & usize)) -> true); + f_rej_sample + = + fun (a: t_Slice u8) (out: t_Slice i16) -> + let tmp0, out1:(t_Slice i16 & usize) = rej_sample a out in + let out:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i16 & usize) + } diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti new file mode 100644 index 000000000..061612251 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti @@ -0,0 +1,46 @@ +module Libcrux_sha3.Avx2.X4.Incremental +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +type t_KeccakState4 = { + f_state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) Core.Core_arch.X86.t____m256i +} + +/// Initialise the state and perform up to 4 absorbs at the same time, +/// using two [`KeccakState4`]. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_absorb_finalxN (v_N: usize) (input: t_Array (t_Array u8 (sz 34)) v_N) + : Prims.Pure t_KeccakState4 Prims.l_True (fun _ -> Prims.l_True) + +/// Squeeze up to 3 x 4 (N) blocks in parallel, using two [`KeccakState4`]. +/// Each block is of size `LEN`. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_squeeze3xN (v_LEN v_N: usize) (state: t_KeccakState4) + : Prims.Pure (t_KeccakState4 & t_Array (t_Array u8 v_LEN) v_N) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Squeeze up to 4 (N) blocks in parallel, using two [`KeccakState4`]. +/// Each block is of size `LEN`. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_squeezexN (v_LEN v_N: usize) (state: t_KeccakState4) + : Prims.Pure (t_KeccakState4 & t_Array (t_Array u8 v_LEN) v_N) + Prims.l_True + (fun _ -> Prims.l_True) + +val shake128_absorb_final (s: t_KeccakState4) (data0 data1 data2 data3: t_Slice u8) + : Prims.Pure t_KeccakState4 Prims.l_True (fun _ -> Prims.l_True) + +/// Initialise the [`KeccakState4`]. +val shake128_init: Prims.unit -> Prims.Pure t_KeccakState4 Prims.l_True (fun _ -> Prims.l_True) + +val shake128_squeeze_first_three_blocks (s: t_KeccakState4) (out0 out1 out2 out3: t_Slice u8) + : Prims.Pure (t_KeccakState4 & t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) + +val shake128_squeeze_next_block (s: t_KeccakState4) (out0 out1 out2 out3: t_Slice u8) + : Prims.Pure (t_KeccakState4 & t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.fsti new file mode 100644 index 000000000..91f8501c5 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.fsti @@ -0,0 +1,15 @@ +module Libcrux_sha3.Avx2.X4 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Run up to 4 SHAKE256 operations in parallel. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake256xN (v_LEN v_N: usize) (input: t_Array (t_Array u8 (sz 33)) v_N) + : Prims.Pure (t_Array (t_Array u8 v_LEN) v_N) Prims.l_True (fun _ -> Prims.l_True) + +/// Perform 4 SHAKE256 operations in parallel +val shake256 (input0 input1 input2 input3 out0 out1 out2 out3: t_Slice u8) + : Prims.Pure (t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fst b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fst new file mode 100644 index 000000000..cea4f9ac0 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fst @@ -0,0 +1,255 @@ +module Libcrux_sha3.Generic_keccak +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_sha3.Traits in + () + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn keccak( + data: [&[int]; N], + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "keccak"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_first_and_last( + s: &libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_first_and_last"); + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_first_block( + s: &libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_first_block"); + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_first_five_blocks( + mut s: libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + { + let hax_temp_output: tuple0 = { rust_primitives::hax::dropped_body }; + s + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_first_five_blocks"); + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_first_three_blocks( + mut s: libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + { + let hax_temp_output: tuple0 = { rust_primitives::hax::dropped_body }; + s + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_first_three_blocks"); + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_last( + mut s: libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_last"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn squeeze_next_block( + mut s: libcrux_sha3::generic_keccak::t_KeccakState, + out: [&mut [int]; N], +) -> tuple0 +where + _: libcrux_sha3::traits::t_KeccakItem, +{ + { + let hax_temp_output: tuple0 = { rust_primitives::hax::dropped_body }; + s + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "generic_keccak"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "squeeze_next_block"); + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fsti new file mode 100644 index 000000000..a7245528f --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Generic_keccak.fsti @@ -0,0 +1,13 @@ +module Libcrux_sha3.Generic_keccak +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_sha3.Traits in + () + +val t_KeccakState (v_N: usize) (#v_T: Type0) {| i1: Libcrux_sha3.Traits.t_KeccakStateItem v_T v_N |} + : Type0 diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti new file mode 100644 index 000000000..30113dfaf --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti @@ -0,0 +1,40 @@ +module Libcrux_sha3.Neon.X2.Incremental +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +type t_KeccakState2 = { f_state:t_Array Libcrux_sha3.Portable.t_KeccakState1 (sz 2) } + +/// Initialise the state and perform up to 4 absorbs at the same time, +/// using two [`KeccakState2`]. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_absorb_finalxN (v_N: usize) (input: t_Array (t_Array u8 (sz 34)) v_N) + : Prims.Pure (t_Array t_KeccakState2 (sz 2)) Prims.l_True (fun _ -> Prims.l_True) + +/// Squeeze up to 3 x 4 (N) blocks in parallel, using two [`KeccakState2`]. +/// Each block is of size `LEN`. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_squeeze3xN (v_LEN v_N: usize) (state: t_Array t_KeccakState2 (sz 2)) + : Prims.Pure (t_Array t_KeccakState2 (sz 2) & t_Array (t_Array u8 v_LEN) v_N) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Squeeze up to 4 (N) blocks in parallel, using two [`KeccakState2`]. +/// Each block is of size `LEN`. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake128_squeezexN (v_LEN v_N: usize) (state: t_Array t_KeccakState2 (sz 2)) + : Prims.Pure (t_Array t_KeccakState2 (sz 2) & t_Array (t_Array u8 v_LEN) v_N) + Prims.l_True + (fun _ -> Prims.l_True) + +val shake128_absorb_final (s: t_KeccakState2) (data0 data1: t_Slice u8) + : Prims.Pure t_KeccakState2 Prims.l_True (fun _ -> Prims.l_True) + +/// Initialise the `KeccakState2`. +val shake128_init: Prims.unit -> Prims.Pure t_KeccakState2 Prims.l_True (fun _ -> Prims.l_True) + +val shake128_squeeze_first_three_blocks (s: t_KeccakState2) (out0 out1: t_Slice u8) + : Prims.Pure (t_KeccakState2 & t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +val shake128_squeeze_next_block (s: t_KeccakState2) (out0 out1: t_Slice u8) + : Prims.Pure (t_KeccakState2 & t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.fsti new file mode 100644 index 000000000..521b0ebf2 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.fsti @@ -0,0 +1,14 @@ +module Libcrux_sha3.Neon.X2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Run up to 4 SHAKE256 operations in parallel. +/// **PANICS** when `N` is not 2, 3, or 4. +val v__shake256xN (v_LEN v_N: usize) (input: t_Array (t_Array u8 (sz 33)) v_N) + : Prims.Pure (t_Array (t_Array u8 v_LEN) v_N) Prims.l_True (fun _ -> Prims.l_True) + +/// Run SHAKE256 on both inputs in parallel. +/// Writes the two results into `out0` and `out1` +val shake256 (input0 input1 out0 out1: t_Slice u8) + : Prims.Pure (t_Slice u8 & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.fsti new file mode 100644 index 000000000..28b47c4f9 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.fsti @@ -0,0 +1,24 @@ +module Libcrux_sha3.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// A portable SHA3 224 implementation. +val sha224 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 256 implementation. +val sha256 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 384 implementation. +val sha384 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 512 implementation. +val sha512 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHAKE128 implementation. +val shake128 (v_LEN: usize) (digest: t_Array u8 v_LEN) (data: t_Slice u8) + : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHAKE256 implementation. +val shake256 (v_LEN: usize) (digest: t_Array u8 v_LEN) (data: t_Slice u8) + : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.Incremental.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.Incremental.fsti new file mode 100644 index 000000000..1bf58e63e --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.Incremental.fsti @@ -0,0 +1,30 @@ +module Libcrux_sha3.Portable.Incremental +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// Absorb +val shake128_absorb_final (s: Libcrux_sha3.Portable.t_KeccakState1) (data0: t_Slice u8) + : Prims.Pure Libcrux_sha3.Portable.t_KeccakState1 Prims.l_True (fun _ -> Prims.l_True) + +/// Initialise the SHAKE state. +val shake128_init: Prims.unit + -> Prims.Pure Libcrux_sha3.Portable.t_KeccakState1 Prims.l_True (fun _ -> Prims.l_True) + +/// Squeeze five blocks +val shake128_squeeze_first_five_blocks (s: Libcrux_sha3.Portable.t_KeccakState1) (out0: t_Slice u8) + : Prims.Pure (Libcrux_sha3.Portable.t_KeccakState1 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Squeeze three blocks +val shake128_squeeze_first_three_blocks (s: Libcrux_sha3.Portable.t_KeccakState1) (out0: t_Slice u8) + : Prims.Pure (Libcrux_sha3.Portable.t_KeccakState1 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Squeeze another block +val shake128_squeeze_next_block (s: Libcrux_sha3.Portable.t_KeccakState1) (out0: t_Slice u8) + : Prims.Pure (Libcrux_sha3.Portable.t_KeccakState1 & t_Slice u8) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fst b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fst new file mode 100644 index 000000000..47ead7e32 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fst @@ -0,0 +1,34 @@ +module Libcrux_sha3.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn keccakx1( + data: [&[int]; 1], + out: [&mut [int]; 1], +) -> tuple0 { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "keccakx1"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fsti new file mode 100644 index 000000000..4e914abbc --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable.fsti @@ -0,0 +1,26 @@ +module Libcrux_sha3.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +/// A portable SHA3 224 implementation. +val sha224 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 256 implementation. +val sha256 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 384 implementation. +val sha384 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHA3 512 implementation. +val sha512 (digest data: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHAKE128 implementation. +val shake128 (digest data: t_Slice u8) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A portable SHAKE256 implementation. +val shake256 (digest data: t_Slice u8) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +type t_KeccakState1 = { f_state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 1) u64 } diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fst b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fst new file mode 100644 index 000000000..9e2f1444c --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fst @@ -0,0 +1,187 @@ +module Libcrux_sha3.Portable_keccak +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn split_at_mut_1_( + out: [&mut [int]; 1], + mid: int, +) -> tuple2<[&mut [int]; 1], [&mut [int]; 1]> { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "split_at_mut_1"); disambiguator = 0 + } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn store_block( + s: &[[int; 5]; 5], + out: [&mut [int]; 1], +) -> tuple0 { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "store_block"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +impl libcrux_sha3::traits::t_KeccakItem for int { + fn f_zero(_: tuple0) -> int { + { + 0 + } + } + fn f_xor5(a: int, b: int, c: int, d: int, e: int) -> int { + { + libcrux_sha3::portable_keccak::v__veor5q_u64(a, b, c, d, e) + } + } + fn f_rotate_left1_and_xor(a: int, b: int) -> int { + { + libcrux_sha3::portable_keccak::v__vrax1q_u64(a, b) + } + } + fn f_xor_and_rotate(a: int, b: int) -> int { + { + libcrux_sha3::portable_keccak::v__vxarq_u64::( + a, b, + ) + } + } + fn f_and_not_xor(a: int, b: int, c: int) -> int { + { + libcrux_sha3::portable_keccak::v__vbcaxq_u64(a, b, c) + } + } + fn f_xor_constant(a: int, c: int) -> int { + { + libcrux_sha3::portable_keccak::v__veorq_n_u64(a, c) + } + } + fn f_xor(a: int, b: int) -> int { + { + core::ops::bit::BitXor::bitxor(a, b) + } + } + fn f_load_block( + mut a: [[int; 5]; 5], + b: [&[int]; 1], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::portable_keccak::load_block::(&mut (a), b) + } + }; + a + } + } + fn f_store_block( + a: &[[int; 5]; 5], + b: [&mut [int]; 1], + ) -> tuple0 { + { + libcrux_sha3::portable_keccak::store_block::(&(deref(a)), b) + } + } + fn f_load_block_full( + mut a: [[int; 5]; 5], + b: [[int; 200]; 1], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::portable_keccak::load_block_full::( + &mut (a), + b, + ) + } + }; + a + } + } + fn f_store_block_full( + a: &[[int; 5]; 5], + ) -> [[int; 200]; 1] { + { + libcrux_sha3::portable_keccak::store_block_full::(&(deref(a))) + } + } + fn f_slice_n(a: [&[int]; 1], start: int, len: int) -> [&[int]; 1] { + { + libcrux_sha3::portable_keccak::slice_1_(a, start, len) + } + } + fn f_split_at_mut_n( + a: [&mut [int]; 1], + mid: int, + ) -> tuple2<[&mut [int]; 1], [&mut [int]; 1]> { + { + libcrux_sha3::portable_keccak::split_at_mut_1_(a, mid) + } + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = Concrete_ident.Imported.Impl; + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fsti new file mode 100644 index 000000000..8eeae34d6 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Portable_keccak.fsti @@ -0,0 +1,218 @@ +module Libcrux_sha3.Portable_keccak +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +val v__vbcaxq_u64 (a b c: u64) : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val v__veor5q_u64 (a b c d e: u64) : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val v__veorq_n_u64 (a c: u64) : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val v__vrax1q_u64 (a b: u64) : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val v__vxarq_u64 (v_LEFT v_RIGHT: i32) (a b: u64) + : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val load_block + (v_RATE: usize) + (s: t_Array (t_Array u64 (sz 5)) (sz 5)) + (blocks: t_Array (t_Slice u8) (sz 1)) + : Prims.Pure (t_Array (t_Array u64 (sz 5)) (sz 5)) Prims.l_True (fun _ -> Prims.l_True) + +val load_block_full + (v_RATE: usize) + (s: t_Array (t_Array u64 (sz 5)) (sz 5)) + (blocks: t_Array (t_Array u8 (sz 200)) (sz 1)) + : Prims.Pure (t_Array (t_Array u64 (sz 5)) (sz 5)) Prims.l_True (fun _ -> Prims.l_True) + +val rotate_left (v_LEFT v_RIGHT: i32) (x: u64) : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val slice_1_ (a: t_Array (t_Slice u8) (sz 1)) (start len: usize) + : Prims.Pure (t_Array (t_Slice u8) (sz 1)) Prims.l_True (fun _ -> Prims.l_True) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn split_at_mut_1_( + out: [&mut [int]; 1], + mid: int, +) -> tuple2<[&mut [int]; 1], [&mut [int]; 1]> { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "split_at_mut_1"); disambiguator = 0 + } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn store_block( + s: &[[int; 5]; 5], + out: [&mut [int]; 1], +) -> tuple0 { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "store_block"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +val store_block_full (v_RATE: usize) (s: t_Array (t_Array u64 (sz 5)) (sz 5)) + : Prims.Pure (t_Array (t_Array u8 (sz 200)) (sz 1)) Prims.l_True (fun _ -> Prims.l_True) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +impl libcrux_sha3::traits::t_KeccakItem for int { + fn f_zero(_: tuple0) -> int { + { + 0 + } + } + fn f_xor5(a: int, b: int, c: int, d: int, e: int) -> int { + { + libcrux_sha3::portable_keccak::v__veor5q_u64(a, b, c, d, e) + } + } + fn f_rotate_left1_and_xor(a: int, b: int) -> int { + { + libcrux_sha3::portable_keccak::v__vrax1q_u64(a, b) + } + } + fn f_xor_and_rotate(a: int, b: int) -> int { + { + libcrux_sha3::portable_keccak::v__vxarq_u64::( + a, b, + ) + } + } + fn f_and_not_xor(a: int, b: int, c: int) -> int { + { + libcrux_sha3::portable_keccak::v__vbcaxq_u64(a, b, c) + } + } + fn f_xor_constant(a: int, c: int) -> int { + { + libcrux_sha3::portable_keccak::v__veorq_n_u64(a, c) + } + } + fn f_xor(a: int, b: int) -> int { + { + core::ops::bit::BitXor::bitxor(a, b) + } + } + fn f_load_block( + mut a: [[int; 5]; 5], + b: [&[int]; 1], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::portable_keccak::load_block::(&mut (a), b) + } + }; + a + } + } + fn f_store_block( + a: &[[int; 5]; 5], + b: [&mut [int]; 1], + ) -> tuple0 { + { + libcrux_sha3::portable_keccak::store_block::(&(deref(a)), b) + } + } + fn f_load_block_full( + mut a: [[int; 5]; 5], + b: [[int; 200]; 1], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::portable_keccak::load_block_full::( + &mut (a), + b, + ) + } + }; + a + } + } + fn f_store_block_full( + a: &[[int; 5]; 5], + ) -> [[int; 200]; 1] { + { + libcrux_sha3::portable_keccak::store_block_full::(&(deref(a))) + } + } + fn f_slice_n(a: [&[int]; 1], start: int, len: int) -> [&[int]; 1] { + { + libcrux_sha3::portable_keccak::slice_1_(a, start, len) + } + } + fn f_split_at_mut_n( + a: [&mut [int]; 1], + mid: int, + ) -> tuple2<[&mut [int]; 1], [&mut [int]; 1]> { + { + libcrux_sha3::portable_keccak::split_at_mut_1_(a, mid) + } + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "portable_keccak"); disambiguator = 0 + }; + { Concrete_ident.Imported.data = Concrete_ident.Imported.Impl; + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fst b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fst new file mode 100644 index 000000000..d3a7b18d9 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fst @@ -0,0 +1,214 @@ +module Libcrux_sha3.Simd.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn split_at_mut_4_( + out: [&mut [int]; 4], + mid: int, +) -> tuple2<[&mut [int]; 4], [&mut [int]; 4]> { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "split_at_mut_4"); disambiguator = 0 + } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn store_block( + s: &[[core::core_arch::x86::t____m256i; 5]; 5], + out: [&mut [int]; 4], +) -> tuple0 { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "store_block"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +impl libcrux_sha3::traits::t_KeccakItem + for core::core_arch::x86::t____m256i +{ + fn f_zero(_: tuple0) -> core::core_arch::x86::t____m256i { + { + libcrux_intrinsics::avx2::mm256_set1_epi64x(0) + } + } + fn f_xor5( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + c: core::core_arch::x86::t____m256i, + d: core::core_arch::x86::t____m256i, + e: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__veor5q_u64(a, b, c, d, e) + } + } + fn f_rotate_left1_and_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vrax1q_u64(a, b) + } + } + fn f_xor_and_rotate( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vxarq_u64::( + a, b, + ) + } + } + fn f_and_not_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + c: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vbcaxq_u64(a, b, c) + } + } + fn f_xor_constant( + a: core::core_arch::x86::t____m256i, + c: int, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__veorq_n_u64(a, c) + } + } + fn f_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_intrinsics::avx2::mm256_xor_si256(a, b) + } + } + fn f_load_block( + mut a: [[core::core_arch::x86::t____m256i; 5]; 5], + b: [&[int]; 4], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::simd::avx2::load_block::(&mut (a), b) + } + }; + a + } + } + fn f_store_block( + a: &[[core::core_arch::x86::t____m256i; 5]; 5], + b: [&mut [int]; 4], + ) -> tuple0 { + { + libcrux_sha3::simd::avx2::store_block::(&(deref(a)), b) + } + } + fn f_load_block_full( + mut a: [[core::core_arch::x86::t____m256i; 5]; 5], + b: [[int; 200]; 4], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::simd::avx2::load_block_full::(&mut (a), b) + } + }; + a + } + } + fn f_store_block_full( + a: &[[core::core_arch::x86::t____m256i; 5]; 5], + ) -> [[int; 200]; 4] { + { + libcrux_sha3::simd::avx2::store_block_full::(&(deref(a))) + } + } + fn f_slice_n(a: [&[int]; 4], start: int, len: int) -> [&[int]; 4] { + { + libcrux_sha3::simd::avx2::slice_4_(a, start, len) + } + } + fn f_split_at_mut_n( + a: [&mut [int]; 4], + mid: int, + ) -> tuple2<[&mut [int]; 4], [&mut [int]; 4]> { + { + libcrux_sha3::simd::avx2::split_at_mut_4_(a, mid) + } + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = Concrete_ident.Imported.Impl; + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fsti new file mode 100644 index 000000000..e0f54aaa9 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Simd.Avx2.fsti @@ -0,0 +1,256 @@ +module Libcrux_sha3.Simd.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +val v__vbcaxq_u64 (a b c: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val v__veor5q_u64 (a b c d e: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val v__veorq_n_u64 (a: Core.Core_arch.X86.t____m256i) (c: u64) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val v__vrax1q_u64 (a b: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val v__vxarq_u64 (v_LEFT v_RIGHT: i32) (a b: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val load_block + (v_RATE: usize) + (s: t_Array (t_Array Core.Core_arch.X86.t____m256i (sz 5)) (sz 5)) + (blocks: t_Array (t_Slice u8) (sz 4)) + : Prims.Pure (t_Array (t_Array Core.Core_arch.X86.t____m256i (sz 5)) (sz 5)) + Prims.l_True + (fun _ -> Prims.l_True) + +val load_block_full + (v_RATE: usize) + (s: t_Array (t_Array Core.Core_arch.X86.t____m256i (sz 5)) (sz 5)) + (blocks: t_Array (t_Array u8 (sz 200)) (sz 4)) + : Prims.Pure (t_Array (t_Array Core.Core_arch.X86.t____m256i (sz 5)) (sz 5)) + Prims.l_True + (fun _ -> Prims.l_True) + +val rotate_left (v_LEFT v_RIGHT: i32) (x: Core.Core_arch.X86.t____m256i) + : Prims.Pure Core.Core_arch.X86.t____m256i Prims.l_True (fun _ -> Prims.l_True) + +val slice_4_ (a: t_Array (t_Slice u8) (sz 4)) (start len: usize) + : Prims.Pure (t_Array (t_Slice u8) (sz 4)) Prims.l_True (fun _ -> Prims.l_True) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn split_at_mut_4_( + out: [&mut [int]; 4], + mid: int, +) -> tuple2<[&mut [int]; 4], [&mut [int]; 4]> { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "split_at_mut_4"); disambiguator = 0 + } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[inline(always)] +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +fn store_block( + s: &[[core::core_arch::x86::t____m256i; 5]; 5], + out: [&mut [int]; 4], +) -> tuple0 { + rust_primitives::hax::dropped_body +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.ValueNs "store_block"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) + +val store_block_full + (v_RATE: usize) + (s: t_Array (t_Array Core.Core_arch.X86.t____m256i (sz 5)) (sz 5)) + : Prims.Pure (t_Array (t_Array u8 (sz 200)) (sz 4)) Prims.l_True (fun _ -> Prims.l_True) + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +#[cfg(feature = "simd256")] +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +impl libcrux_sha3::traits::t_KeccakItem + for core::core_arch::x86::t____m256i +{ + fn f_zero(_: tuple0) -> core::core_arch::x86::t____m256i { + { + libcrux_intrinsics::avx2::mm256_set1_epi64x(0) + } + } + fn f_xor5( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + c: core::core_arch::x86::t____m256i, + d: core::core_arch::x86::t____m256i, + e: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__veor5q_u64(a, b, c, d, e) + } + } + fn f_rotate_left1_and_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vrax1q_u64(a, b) + } + } + fn f_xor_and_rotate( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vxarq_u64::( + a, b, + ) + } + } + fn f_and_not_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + c: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__vbcaxq_u64(a, b, c) + } + } + fn f_xor_constant( + a: core::core_arch::x86::t____m256i, + c: int, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_sha3::simd::avx2::v__veorq_n_u64(a, c) + } + } + fn f_xor( + a: core::core_arch::x86::t____m256i, + b: core::core_arch::x86::t____m256i, + ) -> core::core_arch::x86::t____m256i { + { + libcrux_intrinsics::avx2::mm256_xor_si256(a, b) + } + } + fn f_load_block( + mut a: [[core::core_arch::x86::t____m256i; 5]; 5], + b: [&[int]; 4], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::simd::avx2::load_block::(&mut (a), b) + } + }; + a + } + } + fn f_store_block( + a: &[[core::core_arch::x86::t____m256i; 5]; 5], + b: [&mut [int]; 4], + ) -> tuple0 { + { + libcrux_sha3::simd::avx2::store_block::(&(deref(a)), b) + } + } + fn f_load_block_full( + mut a: [[core::core_arch::x86::t____m256i; 5]; 5], + b: [[int; 200]; 4], + ) -> tuple0 { + { + let hax_temp_output: tuple0 = { + { + libcrux_sha3::simd::avx2::load_block_full::(&mut (a), b) + } + }; + a + } + } + fn f_store_block_full( + a: &[[core::core_arch::x86::t____m256i; 5]; 5], + ) -> [[int; 200]; 4] { + { + libcrux_sha3::simd::avx2::store_block_full::(&(deref(a))) + } + } + fn f_slice_n(a: [&[int]; 4], start: int, len: int) -> [&[int]; 4] { + { + libcrux_sha3::simd::avx2::slice_4_(a, start, len) + } + } + fn f_split_at_mut_n( + a: [&mut [int]; 4], + mid: int, + ) -> tuple2<[&mut [int]; 4], [&mut [int]; 4]> { + { + libcrux_sha3::simd::avx2::split_at_mut_4_(a, mid) + } + } +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "simd"); + disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "avx2"); disambiguator = 0 }; + { Concrete_ident.Imported.data = Concrete_ident.Imported.Impl; + disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fst b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fst new file mode 100644 index 000000000..af3a30a98 --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fst @@ -0,0 +1,61 @@ +module Libcrux_sha3.Traits +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +(* item error backend: (RefMut) The mutation of this &mut is not allowed here. + +Last available AST for this item: + +/** A trait for multiplexing implementations.*/ +#[no_std()] +#[forbid(unsafe_code)] +#[feature(register_tool)] +#[register_tool(_hax)] +trait t_KeccakItem +where + _: core::clone::t_Clone, + _: core::marker::t_Copy, +{ + fn f_zero(_: tuple0) -> Self; + fn f_xor5(_: Self, _: Self, _: Self, _: Self, _: Self) -> Self; + fn f_rotate_left1_and_xor(_: Self, _: Self) -> Self; + fn f_xor_and_rotate(_: Self, _: Self) -> Self; + fn f_and_not_xor(_: Self, _: Self, _: Self) -> Self; + fn f_xor_constant(_: Self, _: int) -> Self; + fn f_xor(_: Self, _: Self) -> Self; + fn f_load_block( + _: [[Self; 5]; 5], + _: [&[int]; N], + ) -> [[Self; 5]; 5]; + fn f_store_block( + _: &[[Self; 5]; 5], + _: [&mut [int]; N], + ) -> tuple0; + fn f_load_block_full( + _: [[Self; 5]; 5], + _: [[int; 200]; N], + ) -> [[Self; 5]; 5]; + fn f_store_block_full( + _: &[[Self; 5]; 5], + ) -> [[int; 200]; N]; + fn f_slice_n(_: [&[int]; N], _: int, _: int) -> [&[int]; N]; + fn f_split_at_mut_n( + _: [&mut [int]; N], + _: int, + ) -> tuple2<[&mut [int]; N], [&mut [int]; N]>; +} + + +Last AST: +/* print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = +{ Concrete_ident.Imported.krate = "libcrux_sha3"; + path = + [{ Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "traits"); disambiguator = 0 }; + { Concrete_ident.Imported.data = + (Concrete_ident.Imported.TypeNs "KeccakItem"); disambiguator = 0 } + ] + }; +kind = Concrete_ident.Kind.Value }) */ + *) diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fsti new file mode 100644 index 000000000..60af4096d --- /dev/null +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Traits.fsti @@ -0,0 +1,27 @@ +module Libcrux_sha3.Traits +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_sha3.Traits.Internal in + () + +/// A Keccak Item +/// This holds the internal state and depends on the architecture. +class t_KeccakStateItem (v_Self: Type0) (v_N: usize) = { + [@@@ FStar.Tactics.Typeclasses.no_method]_super_7919791445461910775:Libcrux_sha3.Traits.Internal.t_KeccakItem + v_Self v_N +} + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl + (v_N: usize) + (#v_T: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_sha3.Traits.Internal.t_KeccakItem v_T v_N) + : t_KeccakStateItem v_T v_N = + { _super_7919791445461910775 = FStar.Tactics.Typeclasses.solve; __marker_trait = () } diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.fsti index fb67a8888..9f4daa21b 100644 --- a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.fsti +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.fsti @@ -3,18 +3,18 @@ module Libcrux_sha3 open Core open FStar.Mul -let discriminant_Algorithm_Sha3_224_: u32 = 1ul +let discriminant_Algorithm_Sha224: u32 = 1ul -let discriminant_Algorithm_Sha3_256_: u32 = 2ul +let discriminant_Algorithm_Sha256: u32 = 2ul -let discriminant_Algorithm_Sha3_384_: u32 = 3ul +let discriminant_Algorithm_Sha384: u32 = 3ul /// The Digest Algorithm. type t_Algorithm = - | Algorithm_Sha3_224_ : t_Algorithm - | Algorithm_Sha3_256_ : t_Algorithm - | Algorithm_Sha3_384_ : t_Algorithm - | Algorithm_Sha3_512_ : t_Algorithm + | Algorithm_Sha224 : t_Algorithm + | Algorithm_Sha256 : t_Algorithm + | Algorithm_Sha384 : t_Algorithm + | Algorithm_Sha512 : t_Algorithm [@@ FStar.Tactics.Typeclasses.tcinstance] let impl_1: Core.Convert.t_From u32 t_Algorithm = @@ -25,25 +25,29 @@ let impl_1: Core.Convert.t_From u32 t_Algorithm = = fun (v: t_Algorithm) -> match v with - | Algorithm_Sha3_224_ -> 1ul - | Algorithm_Sha3_256_ -> 2ul - | Algorithm_Sha3_384_ -> 3ul - | Algorithm_Sha3_512_ -> 4ul + | Algorithm_Sha224 -> 1ul + | Algorithm_Sha256 -> 2ul + | Algorithm_Sha384 -> 3ul + | Algorithm_Sha512 -> 4ul } -let discriminant_Algorithm_Sha3_512_: u32 = 4ul +let discriminant_Algorithm_Sha512: u32 = 4ul val t_Algorithm_cast_to_repr (x: t_Algorithm) : Prims.Pure u32 Prims.l_True (fun _ -> Prims.l_True) +/// A SHA3 224 Digest unfold let t_Sha3_224Digest = t_Array u8 (sz 28) +/// A SHA3 256 Digest unfold let t_Sha3_256Digest = t_Array u8 (sz 32) +/// A SHA3 384 Digest unfold let t_Sha3_384Digest = t_Array u8 (sz 48) +/// A SHA3 512 Digest unfold let t_Sha3_512Digest = t_Array u8 (sz 64) @@ -55,32 +59,30 @@ val hash (v_LEN: usize) (algorithm: t_Algorithm) (payload: t_Slice u8) : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 224 -val sha224 (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 28)) Prims.l_True (fun _ -> Prims.l_True) +val sha224 (data: t_Slice u8) : Prims.Pure (t_Array u8 (sz 28)) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 224 +/// Preconditions: +/// - `digest.len() == 28` val sha224_ema (digest payload: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 256 -val sha256 (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +val sha256 (data: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 256 val sha256_ema (digest payload: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 384 -val sha384 (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 48)) Prims.l_True (fun _ -> Prims.l_True) +val sha384 (data: t_Slice u8) : Prims.Pure (t_Array u8 (sz 48)) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 384 val sha384_ema (digest payload: t_Slice u8) : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 512 -val sha512 (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) +val sha512 (data: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) /// SHA3 512 val sha512_ema (digest payload: t_Slice u8) @@ -105,26 +107,12 @@ let impl: Core.Convert.t_From t_Algorithm u32 = = fun (v: u32) -> match v with - | 1ul -> Algorithm_Sha3_224_ <: t_Algorithm - | 2ul -> Algorithm_Sha3_256_ <: t_Algorithm - | 3ul -> Algorithm_Sha3_384_ <: t_Algorithm - | 4ul -> Algorithm_Sha3_512_ <: t_Algorithm + | 1ul -> Algorithm_Sha224 <: t_Algorithm + | 2ul -> Algorithm_Sha256 <: t_Algorithm + | 3ul -> Algorithm_Sha384 <: t_Algorithm + | 4ul -> Algorithm_Sha512 <: t_Algorithm | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize - (let list = ["Unknown Digest mode "] in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice string) - (Rust_primitives.unsize (let list = - [Core.Fmt.Rt.impl_1__new_display v <: Core.Fmt.Rt.t_Argument] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice Core.Fmt.Rt.t_Argument) - <: - Core.Fmt.t_Arguments) + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "explicit panic" <: Rust_primitives.Hax.t_Never) } diff --git a/libcrux-sha3/src/generic_keccak.rs b/libcrux-sha3/src/generic_keccak.rs index 0737e2581..ef63a654a 100644 --- a/libcrux-sha3/src/generic_keccak.rs +++ b/libcrux-sha3/src/generic_keccak.rs @@ -7,11 +7,11 @@ use crate::traits::*; #[cfg_attr(hax, hax_lib::opaque_type)] #[derive(Clone, Copy)] -pub(crate) struct KeccakState> { +pub(crate) struct KeccakState> { st: [[T; 5]; 5], } -impl> Index for KeccakState { +impl> Index for KeccakState { type Output = [T; 5]; fn index(&self, index: usize) -> &Self::Output { @@ -19,7 +19,7 @@ impl> Index for KeccakState { } } -impl> KeccakState { +impl> KeccakState { /// Create a new Shake128 x4 state. #[inline(always)] pub(crate) fn new() -> Self { @@ -36,7 +36,7 @@ const _ROTC: [usize; 24] = [ ]; #[inline(always)] -pub(crate) fn theta_rho>(s: &mut KeccakState) { +pub(crate) fn theta_rho>(s: &mut KeccakState) { let c: [T; 5] = [ T::xor5(s.st[0][0], s.st[1][0], s.st[2][0], s.st[3][0], s.st[4][0]), T::xor5(s.st[0][1], s.st[1][1], s.st[2][1], s.st[3][1], s.st[4][1]), @@ -88,7 +88,7 @@ const _PI: [usize; 24] = [ ]; #[inline(always)] -pub(crate) fn pi>(s: &mut KeccakState) { +pub(crate) fn pi>(s: &mut KeccakState) { let old = s.st.clone(); s.st[0][1] = old[1][1]; s.st[0][2] = old[2][2]; @@ -117,7 +117,7 @@ pub(crate) fn pi>(s: &mut KeccakState) { } #[inline(always)] -pub(crate) fn chi>(s: &mut KeccakState) { +pub(crate) fn chi>(s: &mut KeccakState) { let old = s.st; for i in 0..5 { for j in 0..5 { @@ -154,12 +154,12 @@ const ROUNDCONSTANTS: [u64; 24] = [ ]; #[inline(always)] -pub(crate) fn iota>(s: &mut KeccakState, i: usize) { +pub(crate) fn iota>(s: &mut KeccakState, i: usize) { s.st[0][0] = T::xor_constant(s.st[0][0], ROUNDCONSTANTS[i]); } #[inline(always)] -pub(crate) fn keccakf1600>(s: &mut KeccakState) { +pub(crate) fn keccakf1600>(s: &mut KeccakState) { for i in 0..24 { theta_rho(s); pi(s); @@ -169,7 +169,7 @@ pub(crate) fn keccakf1600>(s: &mut KeccakState< } #[inline(always)] -pub(crate) fn absorb_block, const RATE: usize>( +pub(crate) fn absorb_block, const RATE: usize>( s: &mut KeccakState, blocks: [&[u8]; N], ) { @@ -178,7 +178,12 @@ pub(crate) fn absorb_block, const RATE: usize>( } #[inline(always)] -pub(crate) fn absorb_final, const RATE: usize, const DELIM: u8>( +pub(crate) fn absorb_final< + const N: usize, + T: KeccakStateItem, + const RATE: usize, + const DELIM: u8, +>( s: &mut KeccakState, last: [&[u8]; N], ) { @@ -195,7 +200,7 @@ pub(crate) fn absorb_final, const RATE: usize, } #[inline(always)] -pub(crate) fn squeeze_first_block, const RATE: usize>( +pub(crate) fn squeeze_first_block, const RATE: usize>( s: &KeccakState, out: [&mut [u8]; N], ) { @@ -203,7 +208,7 @@ pub(crate) fn squeeze_first_block, const RATE: } #[inline(always)] -pub(crate) fn squeeze_next_block, const RATE: usize>( +pub(crate) fn squeeze_next_block, const RATE: usize>( s: &mut KeccakState, out: [&mut [u8]; N], ) { @@ -212,7 +217,11 @@ pub(crate) fn squeeze_next_block, const RATE: u } #[inline(always)] -pub(crate) fn squeeze_first_three_blocks, const RATE: usize>( +pub(crate) fn squeeze_first_three_blocks< + const N: usize, + T: KeccakStateItem, + const RATE: usize, +>( s: &mut KeccakState, out: [&mut [u8]; N], ) { @@ -224,7 +233,11 @@ pub(crate) fn squeeze_first_three_blocks, const } #[inline(always)] -pub(crate) fn squeeze_first_five_blocks, const RATE: usize>( +pub(crate) fn squeeze_first_five_blocks< + const N: usize, + T: KeccakStateItem, + const RATE: usize, +>( s: &mut KeccakState, out: [&mut [u8]; N], ) { @@ -243,7 +256,7 @@ pub(crate) fn squeeze_first_five_blocks, const } #[inline(always)] -pub(crate) fn squeeze_last, const RATE: usize>( +pub(crate) fn squeeze_last, const RATE: usize>( mut s: KeccakState, out: [&mut [u8]; N], ) { @@ -255,7 +268,7 @@ pub(crate) fn squeeze_last, const RATE: usize>( } #[inline(always)] -pub(crate) fn squeeze_first_and_last, const RATE: usize>( +pub(crate) fn squeeze_first_and_last, const RATE: usize>( s: &KeccakState, out: [&mut [u8]; N], ) { @@ -266,7 +279,7 @@ pub(crate) fn squeeze_first_and_last, const RAT } #[inline(always)] -pub(crate) fn keccak, const RATE: usize, const DELIM: u8>( +pub(crate) fn keccak, const RATE: usize, const DELIM: u8>( data: [&[u8]; N], out: [&mut [u8]; N], ) { diff --git a/libcrux-sha3/src/portable_keccak.rs b/libcrux-sha3/src/portable_keccak.rs index fd0015804..382a9e483 100644 --- a/libcrux-sha3/src/portable_keccak.rs +++ b/libcrux-sha3/src/portable_keccak.rs @@ -1,6 +1,6 @@ //! A portable SHA3 implementation using the generic implementation. -use crate::traits::*; +use crate::traits::internal::*; #[inline(always)] fn rotate_left(x: u64) -> u64 { diff --git a/libcrux-sha3/src/simd/avx2.rs b/libcrux-sha3/src/simd/avx2.rs index 04005c483..f55de7ffb 100644 --- a/libcrux-sha3/src/simd/avx2.rs +++ b/libcrux-sha3/src/simd/avx2.rs @@ -1,4 +1,4 @@ -use crate::traits::*; +use crate::traits::internal::*; use libcrux_intrinsics::avx2::*; #[inline(always)] diff --git a/libcrux-sha3/src/traits.rs b/libcrux-sha3/src/traits.rs index f8dc30c79..fa3f5f846 100644 --- a/libcrux-sha3/src/traits.rs +++ b/libcrux-sha3/src/traits.rs @@ -1,16 +1,25 @@ -/// A trait for multiplexing implementations. -pub trait KeccakItem: Clone + Copy { - fn zero() -> Self; - fn xor5(a: Self, b: Self, c: Self, d: Self, e: Self) -> Self; - fn rotate_left1_and_xor(a: Self, b: Self) -> Self; - fn xor_and_rotate(a: Self, b: Self) -> Self; - fn and_not_xor(a: Self, b: Self, c: Self) -> Self; - fn xor_constant(a: Self, c: u64) -> Self; - fn xor(a: Self, b: Self) -> Self; - fn load_block(a: &mut [[Self; 5]; 5], b: [&[u8]; N]); - fn store_block(a: &[[Self; 5]; 5], b: [&mut [u8]; N]); - fn load_block_full(a: &mut [[Self; 5]; 5], b: [[u8; 200]; N]); - fn store_block_full(a: &[[Self; 5]; 5]) -> [[u8; 200]; N]; - fn slice_n(a: [&[u8]; N], start: usize, len: usize) -> [&[u8]; N]; - fn split_at_mut_n(a: [&mut [u8]; N], mid: usize) -> ([&mut [u8]; N], [&mut [u8]; N]); +/// A Keccak Item +/// This holds the internal state and depends on the architecture. +pub trait KeccakStateItem: internal::KeccakItem {} + +// Implement the public trait for all items. +impl> KeccakStateItem for T {} + +pub(crate) mod internal { + /// A trait for multiplexing implementations. + pub trait KeccakItem: Clone + Copy { + fn zero() -> Self; + fn xor5(a: Self, b: Self, c: Self, d: Self, e: Self) -> Self; + fn rotate_left1_and_xor(a: Self, b: Self) -> Self; + fn xor_and_rotate(a: Self, b: Self) -> Self; + fn and_not_xor(a: Self, b: Self, c: Self) -> Self; + fn xor_constant(a: Self, c: u64) -> Self; + fn xor(a: Self, b: Self) -> Self; + fn load_block(a: &mut [[Self; 5]; 5], b: [&[u8]; N]); + fn store_block(a: &[[Self; 5]; 5], b: [&mut [u8]; N]); + fn load_block_full(a: &mut [[Self; 5]; 5], b: [[u8; 200]; N]); + fn store_block_full(a: &[[Self; 5]; 5]) -> [[u8; 200]; N]; + fn slice_n(a: [&[u8]; N], start: usize, len: usize) -> [&[u8]; N]; + fn split_at_mut_n(a: [&mut [u8]; N], mid: usize) -> ([&mut [u8]; N], [&mut [u8]; N]); + } } diff --git a/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti b/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti new file mode 100644 index 000000000..35516c01f --- /dev/null +++ b/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti @@ -0,0 +1,51 @@ +module Libcrux_platform.X86 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +type t_Feature = + | Feature_mmx : t_Feature + | Feature_sse : t_Feature + | Feature_sse2 : t_Feature + | Feature_sse3 : t_Feature + | Feature_pclmulqdq : t_Feature + | Feature_ssse3 : t_Feature + | Feature_fma : t_Feature + | Feature_movbe : t_Feature + | Feature_sse4_1_ : t_Feature + | Feature_sse4_2_ : t_Feature + | Feature_popcnt : t_Feature + | Feature_aes : t_Feature + | Feature_xsave : t_Feature + | Feature_osxsave : t_Feature + | Feature_avx : t_Feature + | Feature_rdrand : t_Feature + | Feature_sgx : t_Feature + | Feature_bmi1 : t_Feature + | Feature_avx2 : t_Feature + | Feature_bmi2 : t_Feature + | Feature_avx512f : t_Feature + | Feature_avx512dq : t_Feature + | Feature_rdseed : t_Feature + | Feature_adx : t_Feature + | Feature_avx512ifma : t_Feature + | Feature_avx512pf : t_Feature + | Feature_avx512er : t_Feature + | Feature_avx512cd : t_Feature + | Feature_sha : t_Feature + | Feature_avx512bw : t_Feature + | Feature_avx512vl : t_Feature + +val t_Feature_cast_to_repr (x: t_Feature) : Prims.Pure isize Prims.l_True (fun _ -> Prims.l_True) + +/// Initialize CPU detection. +val init: Prims.unit -> Prims.Pure Prims.unit Prims.l_True (fun _ -> Prims.l_True) + +val init__cpuid (leaf: u32) + : Prims.Pure Core.Core_arch.X86.Cpuid.t_CpuidResult Prims.l_True (fun _ -> Prims.l_True) + +val init__cpuid_count (leaf sub_leaf: u32) + : Prims.Pure Core.Core_arch.X86.Cpuid.t_CpuidResult Prims.l_True (fun _ -> Prims.l_True) + +/// Check hardware [`Feature`] support. +val supported (feature: t_Feature) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) From f12b8942fecc42c0a70570d03cbf622f7e7f06f8 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 13:15:16 +0200 Subject: [PATCH 54/84] fix for arm --- libcrux-sha3/src/simd/arm64.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcrux-sha3/src/simd/arm64.rs b/libcrux-sha3/src/simd/arm64.rs index bc32dea34..773c5e036 100644 --- a/libcrux-sha3/src/simd/arm64.rs +++ b/libcrux-sha3/src/simd/arm64.rs @@ -1,6 +1,6 @@ use libcrux_intrinsics::arm64::*; -use crate::traits::KeccakItem; +use crate::traits::internal::KeccakItem; #[allow(non_camel_case_types)] pub type uint64x2_t = _uint64x2_t; From ed51c08096bda3db3841ce5c896886eeb15ea8d7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 13:34:57 +0200 Subject: [PATCH 55/84] fixed branching on usize --- .../Libcrux_ml_kem.Hash_functions.Avx2.fsti | 110 +++++- .../Libcrux_ml_kem.Hash_functions.Neon.fsti | 313 +++++++++++++++++- .../extraction/Libcrux_ml_kem.Vector.fsti | 6 +- libcrux-ml-kem/src/hash_functions.rs | 14 +- .../Libcrux_sha3.Avx2.X4.Incremental.fsti | 4 +- .../Libcrux_sha3.Neon.X2.Incremental.fsti | 9 +- 6 files changed, 435 insertions(+), 21 deletions(-) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti index 2a2d9ad5f..100fd31e0 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti @@ -88,7 +88,37 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = Libcrux_sha3.Avx2.X4.Incremental.shake128_init () in - let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = "failure" in + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = + Libcrux_sha3.Avx2.X4.Incremental.shake128_absorb_final state + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + in + state + | 3uy -> + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = + Libcrux_sha3.Avx2.X4.Incremental.shake128_absorb_final state + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + in + state + | 4uy -> + let state:Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 = + Libcrux_sha3.Avx2.X4.Incremental.shake128_absorb_final state + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + in + state + | _ -> state + in { f_shake128_state = state } <: t_Simd256Hash); f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd256Hash) -> true); f_shake128_squeeze_three_blocks_post @@ -115,7 +145,44 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = ) v_K in - let _:Prims.unit = "failure" in + let _:Prims.unit = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let dummy_out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let dummy_out1:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(self)),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out1)))),\n )\n };\n Tuple0\n }\n }" + + | 3uy -> + let dummy_out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n )\n };\n Tuple0\n }\n }\n }" + + | 4uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out3), 0)))),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }" + + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize + (let list = + [ + "internal error: entered unreachable code: This function must only be called with N = 2, 3, 4" + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice string) + (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () + <: + t_Array Core.Fmt.Rt.t_Argument (sz 0)) + <: + t_Slice Core.Fmt.Rt.t_Argument) + <: + Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)); f_shake128_squeeze_block_pre = (fun (self: t_Simd256Hash) -> true); @@ -142,7 +209,44 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K in - let _:Prims.unit = "failure" in + let _:Prims.unit = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let dummy_out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let dummy_out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(self)),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out1)))),\n )\n };\n Tuple0\n }\n }" + + | 3uy -> + let dummy_out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n )\n };\n Tuple0\n }\n }\n }" + + | 4uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out3), 0)))),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }" + + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize + (let list = + [ + "internal error: entered unreachable code: This function is only called with 2, 3, 4" + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice string) + (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () + <: + t_Array Core.Fmt.Rt.t_Argument (sz 0)) + <: + t_Slice Core.Fmt.Rt.t_Argument) + <: + Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti index 73dfe8d29..84710b508 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti @@ -71,7 +71,42 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = let out:t_Array (t_Array u8 v_LEN) v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K in - let _:Prims.unit = "failure" in + let _:Prims.unit = + match cast (v_K <: usize) <: u8 with + | 2uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out1): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n Tuple0\n }\n }" + + | 3uy -> + let extra:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out12): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (extra)))),\n )\n };\n Tuple0\n }\n }\n }\n }" + + | 4uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out123): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 3)))),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out2), 0)),\n )),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out3), 0)),\n )),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }\n }" + + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize + (let list = + [ + "internal error: entered unreachable code: Only 2, 3, or 4 are supported for N" + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice string) + (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () + <: + t_Array Core.Fmt.Rt.t_Argument (sz 0)) + <: + t_Slice Core.Fmt.Rt.t_Argument) + <: + Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in out); f_shake128_init_absorb_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); f_shake128_init_absorb_post @@ -103,7 +138,71 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 2); Rust_primitives.Hax.array_of_list 2 list in - let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = "failure" in + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state + (sz 0) + (Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_final (state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + in + state + | 3uy -> + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state + (sz 0) + (Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_final (state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + in + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state + (sz 1) + (Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_final (state.[ sz 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + in + state + | 4uy -> + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state + (sz 0) + (Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_final (state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + in + let state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize state + (sz 1) + (Libcrux_sha3.Neon.X2.Incremental.shake128_absorb_final (state.[ sz 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 34)) <: t_Slice u8) + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + in + state + | _ -> state + in { f_shake128_state = state } <: t_Simd128Hash); f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd128Hash) -> true); f_shake128_squeeze_three_blocks_post @@ -130,7 +229,42 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = ) v_K in - let _:Prims.unit = "failure" in + let _:Prims.unit = + match cast (v_K <: usize) <: u8 with + | 2uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(self),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n Tuple0\n }\n }" + + | 3uy -> + let extra:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(self),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 1,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (extra)))),\n )\n };\n Tuple0\n }\n }\n }\n }" + + | 4uy -> + Rust_primitives.Hax.failure "" + "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 1,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out2), 0)),\n )),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out3), 0)),\n )),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }\n }" + + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize + (let list = + [ + "internal error: entered unreachable code: This function can only called be called with N = 2, 3, 4" + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice string) + (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () + <: + t_Array Core.Fmt.Rt.t_Argument (sz 0)) + <: + t_Slice Core.Fmt.Rt.t_Argument) + <: + Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)); f_shake128_squeeze_block_pre = (fun (self: t_Simd128Hash) -> true); @@ -157,7 +291,178 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K in - let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) = "failure" in + let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ sz + 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 168) = tmp1 in + let out1:t_Array u8 (sz 168) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + | 3uy -> + let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ sz + 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 168) = tmp1 in + let out1:t_Array u8 (sz 168) = tmp2 in + let _:Prims.unit = () in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ sz + 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out2 + out3 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 1) + tmp0 + } + <: + t_Simd128Hash + in + let out2:t_Array u8 (sz 168) = tmp1 in + let out3:t_Array u8 (sz 168) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + | 4uy -> + let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ sz + 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 168) = tmp1 in + let out1:t_Array u8 (sz 168) = tmp2 in + let _:Prims.unit = () in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_next_block (self.f_shake128_state.[ sz + 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out2 + out3 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 1) + tmp0 + } + <: + t_Simd128Hash + in + let out2:t_Array u8 (sz 168) = tmp1 in + let out3:t_Array u8 (sz 168) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + | _ -> out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti index d5b86c87e..801b2d38e 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti @@ -58,7 +58,7 @@ val barrett_reduce_element (value: i16) val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) : Prims.Pure i16 (requires - Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + Rust_primitives.Hax.failure "" "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"55\"; line = \"182\" };\n lo = { Types.col = \"4\"; line = \"177\" } };\n ty = Types.Never }" ) (ensures @@ -85,7 +85,7 @@ val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) val compress_message_coefficient (fe: u16) : Prims.Pure u8 (requires - Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + Rust_primitives.Hax.failure "" "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"80\"; line = \"146\" };\n lo = { Types.col = \"16\"; line = \"146\" } };\n ty = Types.Never }" ) (ensures @@ -127,7 +127,7 @@ val montgomery_multiply_fe_by_fer (fe fer: i16) val montgomery_reduce_element (value: i32) : Prims.Pure i16 (requires - Rust_primitives.Hax.failure "(AST import) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub!\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.\n" + Rust_primitives.Hax.failure "" "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"114\"; line = \"80\" };\n lo = { Types.col = \"16\"; line = \"80\" } };\n ty = Types.Never }" ) (ensures diff --git a/libcrux-ml-kem/src/hash_functions.rs b/libcrux-ml-kem/src/hash_functions.rs index 5b0a163b2..e34f23e0c 100644 --- a/libcrux-ml-kem/src/hash_functions.rs +++ b/libcrux-ml-kem/src/hash_functions.rs @@ -227,7 +227,7 @@ pub(crate) mod avx2 { debug_assert!(K == 2 || K == 3 || K == 4); let mut state = x4::incremental::shake128_init(); - match K { + match K as u8 { 2 => { x4::incremental::shake128_absorb_final( &mut state, &input[0], &input[1], &input[0], &input[0], @@ -255,7 +255,7 @@ pub(crate) mod avx2 { fn shake128_squeeze_three_blocks(&mut self) -> [[u8; THREE_BLOCKS]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; THREE_BLOCKS]; K]; - match K { + match K as u8 { 2 => { let mut dummy_out0 = [0u8; THREE_BLOCKS]; let mut dummy_out1 = [0u8; THREE_BLOCKS]; @@ -301,7 +301,7 @@ pub(crate) mod avx2 { fn shake128_squeeze_block(&mut self) -> [[u8; BLOCK_SIZE]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; BLOCK_SIZE]; K]; - match K { + match K as u8 { 2 => { let mut dummy_out0 = [0u8; BLOCK_SIZE]; let mut dummy_out1 = [0u8; BLOCK_SIZE]; @@ -385,7 +385,7 @@ pub(crate) mod neon { fn PRFxN(input: &[[u8; 33]; K]) -> [[u8; LEN]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; LEN]; K]; - match K { + match K as u8 { 2 => { let (out0, out1) = out.split_at_mut(1); x2::shake256(&input[0], &input[1], &mut out0[0], &mut out1[0]); @@ -416,7 +416,7 @@ pub(crate) mod neon { x2::incremental::shake128_init(), x2::incremental::shake128_init(), ]; - match K { + match K as u8 { 2 => { x2::incremental::shake128_absorb_final(&mut state[0], &input[0], &input[1]); } @@ -441,7 +441,7 @@ pub(crate) mod neon { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; THREE_BLOCKS]; K]; - match K { + match K as u8 { 2 => { let (out0, out1) = out.split_at_mut(1); x2::incremental::shake128_squeeze_first_three_blocks( @@ -490,7 +490,7 @@ pub(crate) mod neon { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; BLOCK_SIZE]; K]; - match K { + match K as u8 { 2 => { let mut out0 = [0u8; BLOCK_SIZE]; let mut out1 = [0u8; BLOCK_SIZE]; diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti index 061612251..9fdd87ec7 100644 --- a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Avx2.X4.Incremental.fsti @@ -3,9 +3,7 @@ module Libcrux_sha3.Avx2.X4.Incremental open Core open FStar.Mul -type t_KeccakState4 = { - f_state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 4) Core.Core_arch.X86.t____m256i -} +type t_KeccakState4 = { f_state:t_Array Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 (sz 2) } /// Initialise the state and perform up to 4 absorbs at the same time, /// using two [`KeccakState4`]. diff --git a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti index 30113dfaf..c9ca03f55 100644 --- a/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti +++ b/libcrux-sha3/proofs/fstar/extraction/Libcrux_sha3.Neon.X2.Incremental.fsti @@ -3,7 +3,14 @@ module Libcrux_sha3.Neon.X2.Incremental open Core open FStar.Mul -type t_KeccakState2 = { f_state:t_Array Libcrux_sha3.Portable.t_KeccakState1 (sz 2) } +unfold +let t_KeccakState2Internal = + Libcrux_sha3.Generic_keccak.t_KeccakState (sz 2) Core.Core_arch.Arm_shared.Neon.t_uint64x2_t + +type t_KeccakState2 = { + f_state:Libcrux_sha3.Generic_keccak.t_KeccakState (sz 2) + Core.Core_arch.Arm_shared.Neon.t_uint64x2_t +} /// Initialise the state and perform up to 4 absorbs at the same time, /// using two [`KeccakState2`]. From 19ff422fef38f8066652996a659921f46cf06255 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 13:36:46 +0200 Subject: [PATCH 56/84] fixed branching on usize --- libcrux-ml-kem/src/hash_functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcrux-ml-kem/src/hash_functions.rs b/libcrux-ml-kem/src/hash_functions.rs index e34f23e0c..0bad7db06 100644 --- a/libcrux-ml-kem/src/hash_functions.rs +++ b/libcrux-ml-kem/src/hash_functions.rs @@ -171,7 +171,7 @@ pub(crate) mod avx2 { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; LEN]; K]; - match K { + match K as u8 { 2 => { let mut dummy_out0 = [0u8; LEN]; let mut dummy_out1 = [0u8; LEN]; From 4f3b7e72292761393f6853c1dae1e5ff352fe529 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 13:38:58 +0200 Subject: [PATCH 57/84] restored FIELD_MODULUS --- libcrux-ml-kem/src/constants.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcrux-ml-kem/src/constants.rs b/libcrux-ml-kem/src/constants.rs index cf89e9348..751e310d7 100644 --- a/libcrux-ml-kem/src/constants.rs +++ b/libcrux-ml-kem/src/constants.rs @@ -1,5 +1,5 @@ /// Field modulus: 3329 -pub(crate) const _FIELD_MODULUS: i16 = 3329; +pub(crate) const FIELD_MODULUS: i16 = 3329; /// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent pub(crate) const BITS_PER_COEFFICIENT: usize = 12; From 25b2b5745a13b12121f0755ba6aa33c2e55aca0d Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 13:40:38 +0200 Subject: [PATCH 58/84] restored FIELD_MODULUS --- libcrux-ml-kem/src/constants.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libcrux-ml-kem/src/constants.rs b/libcrux-ml-kem/src/constants.rs index 751e310d7..13a5d7856 100644 --- a/libcrux-ml-kem/src/constants.rs +++ b/libcrux-ml-kem/src/constants.rs @@ -1,3 +1,4 @@ +#[cfg(hax)] /// Field modulus: 3329 pub(crate) const FIELD_MODULUS: i16 = 3329; From 24eed5407e5685671c2eb8a38c11f507af3b9c0a Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 13:40:40 +0200 Subject: [PATCH 59/84] update `Cargo.lock` --- Cargo.lock | 65 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afa7a0389..0b33d0864 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,9 +180,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" dependencies = [ "jobserver", "libc", @@ -279,9 +279,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -289,9 +289,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", @@ -301,9 +301,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", "proc-macro2", @@ -313,9 +313,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" @@ -681,7 +681,7 @@ dependencies = [ [[package]] name = "hax-lib" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/?branch=main#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", "num-bigint", @@ -691,7 +691,7 @@ dependencies = [ [[package]] name = "hax-lib" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", "num-bigint", @@ -701,7 +701,7 @@ dependencies = [ [[package]] name = "hax-lib-macros" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/?branch=main#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", "proc-macro-error", @@ -713,7 +713,7 @@ dependencies = [ [[package]] name = "hax-lib-macros" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", "proc-macro-error", @@ -725,7 +725,7 @@ dependencies = [ [[package]] name = "hax-lib-macros-types" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/?branch=main#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "proc-macro2", "quote", @@ -737,7 +737,7 @@ dependencies = [ [[package]] name = "hax-lib-macros-types" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#3444df704959e5a0865bad11894fc95ada97ee5e" +source = "git+https://github.com/hacspec/hax/#46bb5c19fb6f6397e15d9a4ff86c556482f81802" dependencies = [ "proc-macro2", "quote", @@ -916,6 +916,8 @@ dependencies = [ "hex", "libcrux", "libcrux-hacl", + "libcrux-hkdf", + "libcrux-hmac", "libcrux-platform", "log", "pretty_env_logger", @@ -949,6 +951,21 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "libcrux-hkdf" +version = "0.0.2-pre.2" +dependencies = [ + "libcrux-hacl", +] + +[[package]] +name = "libcrux-hmac" +version = "0.0.2-pre.2" +dependencies = [ + "libcrux-hacl", + "libcrux-hkdf", +] + [[package]] name = "libcrux-intrinsics" version = "0.0.2-pre.2" @@ -1431,9 +1448,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1443,9 +1460,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1454,9 +1471,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rfc6979" @@ -1725,9 +1742,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" From cc817e833cd783b91626543a6f3fad4fa9f5ed15 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 14:11:15 +0200 Subject: [PATCH 60/84] got rid of split-at-mut --- .../extraction/Libcrux_ml_kem.Constants.fsti | 6 +- .../Libcrux_ml_kem.Hash_functions.Avx2.fsti | 296 ++++++++++--- .../Libcrux_ml_kem.Hash_functions.Neon.fsti | 415 ++++++++++++++---- .../extraction/Libcrux_ml_kem.Vector.fsti | 11 +- libcrux-ml-kem/src/hash_functions.rs | 234 +++++----- 5 files changed, 684 insertions(+), 278 deletions(-) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti index 690228f5a..7078563cf 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti @@ -17,6 +17,9 @@ let v_COEFFICIENTS_IN_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = Rust_primitives.Hax.dropped_body +/// Field modulus: 3329 +let v_FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body + /// SHA3 512 digest size let v_G_DIGEST_SIZE: usize = Rust_primitives.Hax.dropped_body @@ -25,6 +28,3 @@ let v_H_DIGEST_SIZE: usize = Rust_primitives.Hax.dropped_body /// The size of an ML-KEM shared secret. let v_SHARED_SECRET_SIZE: usize = Rust_primitives.Hax.dropped_body - -/// Field modulus: 3329 -let v__FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti index 100fd31e0..2a80b014d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti @@ -41,7 +41,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) - (out1: t_Array (t_Array u8 v_LEN) v_K) + (out4: t_Array (t_Array u8 v_LEN) v_K) -> true); f_PRFxN @@ -63,7 +63,123 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = let out:t_Array (t_Array u8 v_LEN) v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K in - let _:Prims.unit = "failure" in + let out0:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out1:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out2:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out3:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out, out0, out1, out2, out3:(t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & + t_Array u8 v_LEN & + t_Array u8 v_LEN & + t_Array u8 v_LEN) = + match cast (v_K <: usize) <: u8 with + | 2uy -> + let tmp0, tmp1, tmp2, tmp3:(t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) = + Libcrux_sha3.Avx2.X4.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + out2 + out3 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let out2:t_Array u8 v_LEN = tmp2 in + let out3:t_Array u8 v_LEN = tmp3 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) + | 3uy -> + let tmp0, tmp1, tmp2, tmp3:(t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) = + Libcrux_sha3.Avx2.X4.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + out2 + out3 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let out2:t_Array u8 v_LEN = tmp2 in + let out3:t_Array u8 v_LEN = tmp3 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) + | 4uy -> + let tmp0, tmp1, tmp2, tmp3:(t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) = + Libcrux_sha3.Avx2.X4.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + out2 + out3 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let out2:t_Array u8 v_LEN = tmp2 in + let out3:t_Array u8 v_LEN = tmp3 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) + | _ -> + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) + in out); f_shake128_init_absorb_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); f_shake128_init_absorb_post @@ -123,7 +239,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd256Hash) -> true); f_shake128_squeeze_three_blocks_post = - (fun (self: t_Simd256Hash) (out1: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); + (fun (self: t_Simd256Hash) (out4: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); f_shake128_squeeze_three_blocks = (fun (self: t_Simd256Hash) -> @@ -145,50 +261,70 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = ) v_K in - let _:Prims.unit = + let out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out1:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out2:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out3:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let tmp0, tmp1, tmp2, tmp3, tmp4:(Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Avx2.X4.Incremental.shake128_squeeze_first_three_blocks self.f_shake128_state + out0 + out1 + out2 + out3 + in + let self:t_Simd256Hash = { self with f_shake128_state = tmp0 } <: t_Simd256Hash in + let out0:t_Array u8 (sz 504) = tmp1 in + let out1:t_Array u8 (sz 504) = tmp2 in + let out2:t_Array u8 (sz 504) = tmp3 in + let out3:t_Array u8 (sz 504) = tmp4 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 504)) v_K = match cast (v_K <: usize) <: u8 with | 2uy -> - let dummy_out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in - let dummy_out1:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(self)),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out1)))),\n )\n };\n Tuple0\n }\n }" - + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out | 3uy -> - let dummy_out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n )\n };\n Tuple0\n }\n }\n }" - + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out | 4uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out3), 0)))),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }" - - | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize - (let list = - [ - "internal error: entered unreachable code: This function must only be called with N = 2, 3, 4" - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice string) - (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () - <: - t_Array Core.Fmt.Rt.t_Argument (sz 0)) - <: - t_Slice Core.Fmt.Rt.t_Argument) - <: - Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out + | _ -> out in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)); f_shake128_squeeze_block_pre = (fun (self: t_Simd256Hash) -> true); f_shake128_squeeze_block_post = - (fun (self: t_Simd256Hash) (out1: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); + (fun (self: t_Simd256Hash) (out4: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); f_shake128_squeeze_block = fun (self: t_Simd256Hash) -> @@ -209,43 +345,63 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K in - let _:Prims.unit = + let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let tmp0, tmp1, tmp2, tmp3, tmp4:(Libcrux_sha3.Avx2.X4.Incremental.t_KeccakState4 & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + Libcrux_sha3.Avx2.X4.Incremental.shake128_squeeze_next_block self.f_shake128_state + out0 + out1 + out2 + out3 + in + let self:t_Simd256Hash = { self with f_shake128_state = tmp0 } <: t_Simd256Hash in + let out0:t_Array u8 (sz 168) = tmp1 in + let out1:t_Array u8 (sz 168) = tmp2 in + let out2:t_Array u8 (sz 168) = tmp3 in + let out3:t_Array u8 (sz 168) = tmp4 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 168)) v_K = match cast (v_K <: usize) <: u8 with | 2uy -> - let dummy_out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let dummy_out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(self)),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out1)))),\n )\n };\n Tuple0\n }\n }" - + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out | 3uy -> - let dummy_out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (dummy_out0)))),\n )\n };\n Tuple0\n }\n }\n }" - + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out | 4uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 168]], &mut [[int; 168]]> = {\n core::slice::impl__split_at_mut::<[int; 168]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 168]], &mut [[int; 168]]> =\n { core::slice::impl__split_at_mut::<[int; 168]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::avx2::x4::incremental::shake128_squeeze_next_block(\n &mut (deref(\n &mut (proj_libcrux_ml_kem::hash_functions::avx2::f_shake128_state(\n self,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out3), 0)))),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }" - - | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize - (let list = - [ - "internal error: entered unreachable code: This function is only called with 2, 3, 4" - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice string) - (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () - <: - t_Array Core.Fmt.Rt.t_Argument (sz 0)) - <: - t_Slice Core.Fmt.Rt.t_Argument) - <: - Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 (sz 168)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out + | _ -> out in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti index 84710b508..6fda7a42c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti @@ -49,7 +49,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) - (out1: t_Array (t_Array u8 v_LEN) v_K) + (out4: t_Array (t_Array u8 v_LEN) v_K) -> true); f_PRFxN @@ -71,41 +71,127 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = let out:t_Array (t_Array u8 v_LEN) v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy v_LEN <: t_Array u8 v_LEN) v_K in - let _:Prims.unit = + let out0:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out1:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out2:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out3:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out, out0, out1, out2, out3:(t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & + t_Array u8 v_LEN & + t_Array u8 v_LEN & + t_Array u8 v_LEN) = match cast (v_K <: usize) <: u8 with | 2uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out1): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n Tuple0\n }\n }" - + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) | 3uy -> - let extra:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out12): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (extra)))),\n )\n };\n Tuple0\n }\n }\n }\n }" - + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 (Rust_primitives.unsize (input.[ sz 2 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out2 + out3 + in + let out2:t_Array u8 v_LEN = tmp0 in + let out3:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) | 4uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out123): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> = {\n core::slice::impl__split_at_mut::<[int; LEN]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; LEN]], &mut [[int; LEN]]> =\n { core::slice::impl__split_at_mut::<[int; LEN]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 0)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 1)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::shake256(\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 2)))),\n ),\n rust_primitives::unsize(\n &(deref(&(core::ops::index::Index::index(deref(input), 3)))),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out2), 0)),\n )),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out3), 0)),\n )),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }\n }" - + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 (Rust_primitives.unsize (input.[ sz 0 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out0 + out1 + in + let out0:t_Array u8 v_LEN = tmp0 in + let out1:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in + let tmp0, tmp1:(t_Array u8 v_LEN & t_Array u8 v_LEN) = + Libcrux_sha3.Neon.X2.shake256 (Rust_primitives.unsize (input.[ sz 2 ] + <: + t_Array u8 (sz 33)) + <: + t_Slice u8) + (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 33)) <: t_Slice u8) + out2 + out3 + in + let out2:t_Array u8 v_LEN = tmp0 in + let out3:t_Array u8 v_LEN = tmp1 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 v_LEN) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize - (let list = - [ - "internal error: entered unreachable code: Only 2, 3, or 4 are supported for N" - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice string) - (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () - <: - t_Array Core.Fmt.Rt.t_Argument (sz 0)) - <: - t_Slice Core.Fmt.Rt.t_Argument) - <: - Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) + out, out0, out1, out2, out3 + <: + (t_Array (t_Array u8 v_LEN) v_K & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & + t_Array u8 v_LEN) in out); f_shake128_init_absorb_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); @@ -207,7 +293,7 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = f_shake128_squeeze_three_blocks_pre = (fun (self: t_Simd128Hash) -> true); f_shake128_squeeze_three_blocks_post = - (fun (self: t_Simd128Hash) (out1: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); + (fun (self: t_Simd128Hash) (out4: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); f_shake128_squeeze_three_blocks = (fun (self: t_Simd128Hash) -> @@ -229,41 +315,197 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = ) v_K in - let _:Prims.unit = + let out0:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out1:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out2:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out3:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in + let out, out0, out1, out2, out3, self:(t_Array (t_Array u8 (sz 504)) v_K & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Simd128Hash) = match cast (v_K <: usize) <: u8 with | 2uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out1): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(self),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n Tuple0\n }\n }" - + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_first_three_blocks (self + .f_shake128_state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 504) = tmp1 in + let out1:t_Array u8 (sz 504) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 504)) v_K & t_Array u8 (sz 504) & t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Simd128Hash) | 3uy -> - let extra:t_Array u8 (sz 504) = Rust_primitives.Hax.repeat 0uy (sz 504) in - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out12): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out2): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out12)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(self),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 1,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out2), 0)))),\n ),\n rust_primitives::unsize(&mut (deref(&mut (extra)))),\n )\n };\n Tuple0\n }\n }\n }\n }" - + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_first_three_blocks (self + .f_shake128_state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 504) = tmp1 in + let out1:t_Array u8 (sz 504) = tmp2 in + let _:Prims.unit = () in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_first_three_blocks (self + .f_shake128_state.[ sz 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out2 + out3 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 1) + tmp0 + } + <: + t_Simd128Hash + in + let out2:t_Array u8 (sz 504) = tmp1 in + let out3:t_Array u8 (sz 504) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 504)) v_K & t_Array u8 (sz 504) & t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Simd128Hash) | 4uy -> - Rust_primitives.Hax.failure "" - "{\n let Tuple2(out0, out123): tuple2<&mut [[int; 504]], &mut [[int; 504]]> = {\n core::slice::impl__split_at_mut::<[int; 504]>(rust_primitives::unsize(&mut (out)), 1)\n };\n {\n let Tuple2(out1, out23): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out123)), 1) };\n {\n let Tuple2(out2, out3): tuple2<&mut [[int; 504]], &mut [[int; 504]]> =\n { core::slice::impl__split_at_mut::<[int; 504]>(&mut (deref(out23)), 1) };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 0,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out0), 0)))),\n ),\n rust_primitives::unsize(\n &mut (deref(&mut (core::ops::index::Index::index(deref(out1), 0)))),\n ),\n )\n };\n {\n let _: tuple0 = {\n libcrux_sha3::neon::x2::incremental::shake128_squeeze_first_three_blocks(\n &mut (deref(\n &mut (core::ops::index::Index::index(\n proj_libcrux_ml_kem::hash_functions::neon::f_shake128_state(\n self,\n ),\n 1,\n )),\n )),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out2), 0)),\n )),\n ),\n rust_primitives::unsize(\n &mut (deref(\n &mut (core::ops::index::Index::index(deref(out3), 0)),\n )),\n ),\n )\n };\n Tuple0\n }\n }\n }\n }\n }" - + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_first_three_blocks (self + .f_shake128_state.[ sz 0 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out0 + out1 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 0) + tmp0 + } + <: + t_Simd128Hash + in + let out0:t_Array u8 (sz 504) = tmp1 in + let out1:t_Array u8 (sz 504) = tmp2 in + let _:Prims.unit = () in + let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & + t_Array u8 (sz 504) & + t_Array u8 (sz 504)) = + Libcrux_sha3.Neon.X2.Incremental.shake128_squeeze_first_three_blocks (self + .f_shake128_state.[ sz 1 ] + <: + Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2) + out2 + out3 + in + let self:t_Simd128Hash = + { + self with + f_shake128_state + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize self.f_shake128_state + (sz 1) + tmp0 + } + <: + t_Simd128Hash + in + let out2:t_Array u8 (sz 504) = tmp1 in + let out3:t_Array u8 (sz 504) = tmp2 in + let _:Prims.unit = () in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) out0 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 + in + let out:t_Array (t_Array u8 (sz 504)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 + in + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 504)) v_K & t_Array u8 (sz 504) & t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Simd128Hash) | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic_fmt (Core.Fmt.impl_2__new_v1 (Rust_primitives.unsize - (let list = - [ - "internal error: entered unreachable code: This function can only called be called with N = 2, 3, 4" - ] - in - FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); - Rust_primitives.Hax.array_of_list 1 list) - <: - t_Slice string) - (Rust_primitives.unsize (Core.Fmt.Rt.impl_1__none () - <: - t_Array Core.Fmt.Rt.t_Argument (sz 0)) - <: - t_Slice Core.Fmt.Rt.t_Argument) - <: - Core.Fmt.t_Arguments) - <: - Rust_primitives.Hax.t_Never) + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 504)) v_K & t_Array u8 (sz 504) & t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Array u8 (sz 504) & + t_Simd128Hash) in let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)); @@ -291,11 +533,17 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K in - let out, self:(t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) = + let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in + let out, out0, out1, out2, out3, self:(t_Array (t_Array u8 (sz 168)) v_K & t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Simd128Hash) = match cast (v_K <: usize) <: u8 with | 2uy -> - let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & t_Array u8 (sz 168) & t_Array u8 (sz 168)) = @@ -327,12 +575,13 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = let out:t_Array (t_Array u8 (sz 168)) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) out1 in - out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 168)) v_K & t_Array u8 (sz 168) & t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Simd128Hash) | 3uy -> - let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & t_Array u8 (sz 168) & t_Array u8 (sz 168)) = @@ -392,12 +641,13 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = let out:t_Array (t_Array u8 (sz 168)) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) out2 in - out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 168)) v_K & t_Array u8 (sz 168) & t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Simd128Hash) | 4uy -> - let out0:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out1:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out2:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in - let out3:t_Array u8 (sz 168) = Rust_primitives.Hax.repeat 0uy (sz 168) in let tmp0, tmp1, tmp2:(Libcrux_sha3.Neon.X2.Incremental.t_KeccakState2 & t_Array u8 (sz 168) & t_Array u8 (sz 168)) = @@ -460,8 +710,19 @@ let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = let out:t_Array (t_Array u8 (sz 168)) v_K = Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) out3 in - out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) - | _ -> out, self <: (t_Array (t_Array u8 (sz 168)) v_K & t_Simd128Hash) + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 168)) v_K & t_Array u8 (sz 168) & t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Simd128Hash) + | _ -> + out, out0, out1, out2, out3, self + <: + (t_Array (t_Array u8 (sz 168)) v_K & t_Array u8 (sz 168) & t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Array u8 (sz 168) & + t_Simd128Hash) in let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti index 801b2d38e..2fb81e560 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti @@ -58,9 +58,9 @@ val barrett_reduce_element (value: i16) val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) : Prims.Pure i16 (requires - Rust_primitives.Hax.failure "" - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"55\"; line = \"182\" };\n lo = { Types.col = \"4\"; line = \"177\" } };\n ty = Types.Never }" - ) + (coefficient_bits =. 4uy || coefficient_bits =. 5uy || coefficient_bits =. 10uy || + coefficient_bits =. 11uy) && + fe <. (cast (Libcrux_ml_kem.Constants.v_FIELD_MODULUS <: i16) <: u16)) (ensures fun result -> let result:i16 = result in @@ -84,10 +84,7 @@ val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) /// . val compress_message_coefficient (fe: u16) : Prims.Pure u8 - (requires - Rust_primitives.Hax.failure "" - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"80\"; line = \"146\" };\n lo = { Types.col = \"16\"; line = \"146\" } };\n ty = Types.Never }" - ) + (requires fe <. (cast (Libcrux_ml_kem.Constants.v_FIELD_MODULUS <: i16) <: u16)) (ensures fun result -> let result:u8 = result in diff --git a/libcrux-ml-kem/src/hash_functions.rs b/libcrux-ml-kem/src/hash_functions.rs index 0bad7db06..97e345336 100644 --- a/libcrux-ml-kem/src/hash_functions.rs +++ b/libcrux-ml-kem/src/hash_functions.rs @@ -170,52 +170,56 @@ pub(crate) mod avx2 { fn PRFxN(input: &[[u8; 33]; K]) -> [[u8; LEN]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; LEN]; K]; - + let mut out0 = [0u8; LEN]; + let mut out1 = [0u8; LEN]; + let mut out2 = [0u8; LEN]; + let mut out3 = [0u8; LEN]; + match K as u8 { 2 => { - let mut dummy_out0 = [0u8; LEN]; - let mut dummy_out1 = [0u8; LEN]; - let (out0, out1) = out.split_at_mut(1); x4::shake256( &input[0], &input[1], &input[0], &input[0], - &mut out0[0], - &mut out1[0], - &mut dummy_out0, - &mut dummy_out1, + &mut out0, + &mut out1, + &mut out2, + &mut out3, ); + out[0] = out0; + out[1] = out1; } 3 => { - let mut dummy_out0 = [0u8; LEN]; - let (out0, out12) = out.split_at_mut(1); - let (out1, out2) = out12.split_at_mut(1); x4::shake256( &input[0], &input[1], &input[2], &input[0], - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut dummy_out0, + &mut out0, + &mut out1, + &mut out2, + &mut out3, ); + out[0] = out0; + out[1] = out1; + out[2] = out2; } 4 => { - let (out0, out123) = out.split_at_mut(1); - let (out1, out23) = out123.split_at_mut(1); - let (out2, out3) = out23.split_at_mut(1); x4::shake256( &input[0], &input[1], &input[2], &input[3], - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut out3[0], + &mut out0, + &mut out1, + &mut out2, + &mut out3, ); + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; } _ => unreachable!("This function must only be called with N = 2, 3, 4"), } @@ -255,42 +259,32 @@ pub(crate) mod avx2 { fn shake128_squeeze_three_blocks(&mut self) -> [[u8; THREE_BLOCKS]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; THREE_BLOCKS]; K]; + let mut out0 = [0u8; THREE_BLOCKS]; + let mut out1 = [0u8; THREE_BLOCKS]; + let mut out2 = [0u8; THREE_BLOCKS]; + let mut out3 = [0u8; THREE_BLOCKS]; + x4::incremental::shake128_squeeze_first_three_blocks( + &mut self.shake128_state, + &mut out0, + &mut out1, + &mut out2, + &mut out3, + ); match K as u8 { 2 => { - let mut dummy_out0 = [0u8; THREE_BLOCKS]; - let mut dummy_out1 = [0u8; THREE_BLOCKS]; - let (out0, out1) = out.split_at_mut(1); - x4::incremental::shake128_squeeze_first_three_blocks( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut dummy_out0, - &mut dummy_out1, - ); + out[0] = out0; + out[1] = out1; } 3 => { - let mut dummy_out0 = [0u8; THREE_BLOCKS]; - let (out0, out12) = out.split_at_mut(1); - let (out1, out2) = out12.split_at_mut(1); - x4::incremental::shake128_squeeze_first_three_blocks( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut dummy_out0, - ); + out[0] = out0; + out[1] = out1; + out[2] = out2; } 4 => { - let (out0, out123) = out.split_at_mut(1); - let (out1, out23) = out123.split_at_mut(1); - let (out2, out3) = out23.split_at_mut(1); - x4::incremental::shake128_squeeze_first_three_blocks( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut out3[0], - ); + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; } _ => unreachable!("This function must only be called with N = 2, 3, 4"), } @@ -301,42 +295,32 @@ pub(crate) mod avx2 { fn shake128_squeeze_block(&mut self) -> [[u8; BLOCK_SIZE]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; BLOCK_SIZE]; K]; + let mut out0 = [0u8; BLOCK_SIZE]; + let mut out1 = [0u8; BLOCK_SIZE]; + let mut out2 = [0u8; BLOCK_SIZE]; + let mut out3 = [0u8; BLOCK_SIZE]; + x4::incremental::shake128_squeeze_next_block( + &mut self.shake128_state, + &mut out0, + &mut out1, + &mut out2, + &mut out3, + ); match K as u8 { 2 => { - let mut dummy_out0 = [0u8; BLOCK_SIZE]; - let mut dummy_out1 = [0u8; BLOCK_SIZE]; - let (out0, out1) = out.split_at_mut(1); - x4::incremental::shake128_squeeze_next_block( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut dummy_out0, - &mut dummy_out1, - ); + out[0] = out0; + out[1] = out1; } 3 => { - let mut dummy_out0 = [0u8; BLOCK_SIZE]; - let (out0, out12) = out.split_at_mut(1); - let (out1, out2) = out12.split_at_mut(1); - x4::incremental::shake128_squeeze_next_block( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut dummy_out0, - ); + out[0] = out0; + out[1] = out1; + out[2] = out2; } 4 => { - let (out0, out123) = out.split_at_mut(1); - let (out1, out23) = out123.split_at_mut(1); - let (out2, out3) = out23.split_at_mut(1); - x4::incremental::shake128_squeeze_next_block( - &mut self.shake128_state, - &mut out0[0], - &mut out1[0], - &mut out2[0], - &mut out3[0], - ); + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; } _ => unreachable!("This function is only called with 2, 3, 4"), } @@ -385,24 +369,30 @@ pub(crate) mod neon { fn PRFxN(input: &[[u8; 33]; K]) -> [[u8; LEN]; K] { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; LEN]; K]; + let mut out0 = [0u8; LEN]; + let mut out1 = [0u8; LEN]; + let mut out2 = [0u8; LEN]; + let mut out3 = [0u8; LEN]; match K as u8 { 2 => { - let (out0, out1) = out.split_at_mut(1); - x2::shake256(&input[0], &input[1], &mut out0[0], &mut out1[0]); + x2::shake256(&input[0], &input[1], &mut out0, &mut out1); + out[0] = out0; + out[1] = out1; } 3 => { - let mut extra = [0u8; LEN]; - let (out0, out12) = out.split_at_mut(1); - let (out1, out2) = out12.split_at_mut(1); - x2::shake256(&input[0], &input[1], &mut out0[0], &mut out1[0]); - x2::shake256(&input[2], &input[2], &mut out2[0], &mut extra); + x2::shake256(&input[0], &input[1], &mut out0, &mut out1); + x2::shake256(&input[2], &input[2], &mut out2, &mut out3); + out[0] = out0; + out[1] = out1; + out[2] = out2; } 4 => { - let (out0, out123) = out.split_at_mut(1); - let (out1, out23) = out123.split_at_mut(1); - let (out2, out3) = out23.split_at_mut(1); - x2::shake256(&input[0], &input[1], &mut out0[0], &mut out1[0]); - x2::shake256(&input[2], &input[3], &mut out2[0], &mut out3[0]); + x2::shake256(&input[0], &input[1], &mut out0, &mut out1); + x2::shake256(&input[2], &input[3], &mut out2, &mut out3); + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; } _ => unreachable!("Only 2, 3, or 4 are supported for N"), } @@ -441,44 +431,51 @@ pub(crate) mod neon { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; THREE_BLOCKS]; K]; + let mut out0 = [0u8; THREE_BLOCKS]; + let mut out1 = [0u8; THREE_BLOCKS]; + let mut out2 = [0u8; THREE_BLOCKS]; + let mut out3 = [0u8; THREE_BLOCKS]; + match K as u8 { 2 => { - let (out0, out1) = out.split_at_mut(1); x2::incremental::shake128_squeeze_first_three_blocks( &mut self.shake128_state[0], - &mut out0[0], - &mut out1[0], + &mut out0, + &mut out1, ); + out[0] = out0; + out[1] = out1; } 3 => { - let mut extra = [0u8; THREE_BLOCKS]; - let (out0, out12) = out.split_at_mut(1); - let (out1, out2) = out12.split_at_mut(1); x2::incremental::shake128_squeeze_first_three_blocks( &mut self.shake128_state[0], - &mut out0[0], - &mut out1[0], + &mut out0, + &mut out1, ); x2::incremental::shake128_squeeze_first_three_blocks( &mut self.shake128_state[1], - &mut out2[0], - &mut extra, + &mut out2, + &mut out3, ); + out[0] = out0; + out[1] = out1; + out[2] = out2; } 4 => { - let (out0, out123) = out.split_at_mut(1); - let (out1, out23) = out123.split_at_mut(1); - let (out2, out3) = out23.split_at_mut(1); x2::incremental::shake128_squeeze_first_three_blocks( &mut self.shake128_state[0], - &mut out0[0], - &mut out1[0], + &mut out0, + &mut out1, ); x2::incremental::shake128_squeeze_first_three_blocks( &mut self.shake128_state[1], - &mut out2[0], - &mut out3[0], + &mut out2, + &mut out3, ); + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; } _ => unreachable!("This function can only called be called with N = 2, 3, 4"), } @@ -490,10 +487,13 @@ pub(crate) mod neon { debug_assert!(K == 2 || K == 3 || K == 4); let mut out = [[0u8; BLOCK_SIZE]; K]; + let mut out0 = [0u8; BLOCK_SIZE]; + let mut out1 = [0u8; BLOCK_SIZE]; + let mut out2 = [0u8; BLOCK_SIZE]; + let mut out3 = [0u8; BLOCK_SIZE]; + match K as u8 { 2 => { - let mut out0 = [0u8; BLOCK_SIZE]; - let mut out1 = [0u8; BLOCK_SIZE]; x2::incremental::shake128_squeeze_next_block( &mut self.shake128_state[0], &mut out0, @@ -503,10 +503,6 @@ pub(crate) mod neon { out[1] = out1; } 3 => { - let mut out0 = [0u8; BLOCK_SIZE]; - let mut out1 = [0u8; BLOCK_SIZE]; - let mut out2 = [0u8; BLOCK_SIZE]; - let mut out3 = [0u8; BLOCK_SIZE]; x2::incremental::shake128_squeeze_next_block( &mut self.shake128_state[0], &mut out0, @@ -522,10 +518,6 @@ pub(crate) mod neon { out[2] = out2; } 4 => { - let mut out0 = [0u8; BLOCK_SIZE]; - let mut out1 = [0u8; BLOCK_SIZE]; - let mut out2 = [0u8; BLOCK_SIZE]; - let mut out3 = [0u8; BLOCK_SIZE]; x2::incremental::shake128_squeeze_next_block( &mut self.shake128_state[0], &mut out0, From 463f84c328485e2785cb34fc88abc00de7c90266 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 14:42:11 +0200 Subject: [PATCH 61/84] extracts without errors --- .../fstar/extraction/Libcrux_ml_kem.Vector.fsti | 12 +++++++++--- libcrux-ml-kem/src/vector.rs | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti index 2fb81e560..1e7c0ce96 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti @@ -124,9 +124,15 @@ val montgomery_multiply_fe_by_fer (fe fer: i16) val montgomery_reduce_element (value: i32) : Prims.Pure i16 (requires - Rust_primitives.Hax.failure "" - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node = Types.Err;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-ml-kem/src/vector.rs\"));\n hi = { Types.col = \"114\"; line = \"80\" };\n lo = { Types.col = \"16\"; line = \"80\" } };\n ty = Types.Never }" - ) + value >=. + ((cast (Core.Ops.Arith.Neg.neg Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) *! + v_MONTGOMERY_R + <: + i32) && + value <=. + ((cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) *! v_MONTGOMERY_R + <: + i32)) (ensures fun result -> let result:i16 = result in diff --git a/libcrux-ml-kem/src/vector.rs b/libcrux-ml-kem/src/vector.rs index 7f2ca8acb..7834b3d72 100644 --- a/libcrux-ml-kem/src/vector.rs +++ b/libcrux-ml-kem/src/vector.rs @@ -77,7 +77,7 @@ pub(crate) fn get_n_least_significant_bits(n: u8, value: u32) -> u32 { /// `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2) /// /// In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 · FIELD_MODULUS) / 2`. -#[cfg_attr(hax, hax_lib::requires(value >= -FIELD_MODULUS * MONTGOMERY_R && value <= FIELD_MODULUS * MONTGOMERY_R))] +#[cfg_attr(hax, hax_lib::requires(value >= -(FIELD_MODULUS as i32) * MONTGOMERY_R && value <= (FIELD_MODULUS as i32) * MONTGOMERY_R))] #[cfg_attr(hax, hax_lib::ensures(|result| result >= -(3 * FIELD_MODULUS) / 2 && result <= (3 * FIELD_MODULUS) / 2))] pub(crate) fn montgomery_reduce_element(value: i32) -> MontgomeryFieldElement { // This forces hax to extract code for MONTGOMERY_R before it extracts code From 04bb2fcfd69d0606fb95f2cf846bdde91bb5cb2b Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 15:53:03 +0200 Subject: [PATCH 62/84] ci: run `nix.yml` on `dev` --- .github/workflows/nix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 29db314d8..1e07d3497 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -2,7 +2,7 @@ name: Nix on: push: - branches: [main] + branches: [main, dev] jobs: nix: From ccc7d28a98c7d55686b43aefe3440dd201f45976 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Tue, 11 Jun 2024 16:04:28 +0200 Subject: [PATCH 63/84] fixed fmt --- .../extraction/Libcrux_ml_kem.Constants.fsti | 3 -- .../extraction/Libcrux_ml_kem.Vector.fsti | 8 +++-- libcrux-ml-kem/src/constants.rs | 4 --- libcrux-ml-kem/src/hash_functions.rs | 32 ++++--------------- libcrux-ml-kem/src/vector.rs | 4 +-- 5 files changed, 14 insertions(+), 37 deletions(-) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti index 7078563cf..210ffc329 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti @@ -17,9 +17,6 @@ let v_COEFFICIENTS_IN_RING_ELEMENT: usize = Rust_primitives.Hax.dropped_body let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = Rust_primitives.Hax.dropped_body -/// Field modulus: 3329 -let v_FIELD_MODULUS: i16 = Rust_primitives.Hax.dropped_body - /// SHA3 512 digest size let v_G_DIGEST_SIZE: usize = Rust_primitives.Hax.dropped_body diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti index 1e7c0ce96..39f142807 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.fsti @@ -60,7 +60,7 @@ val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) (requires (coefficient_bits =. 4uy || coefficient_bits =. 5uy || coefficient_bits =. 10uy || coefficient_bits =. 11uy) && - fe <. (cast (Libcrux_ml_kem.Constants.v_FIELD_MODULUS <: i16) <: u16)) + fe <. (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: u16)) (ensures fun result -> let result:i16 = result in @@ -84,7 +84,7 @@ val compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) /// . val compress_message_coefficient (fe: u16) : Prims.Pure u8 - (requires fe <. (cast (Libcrux_ml_kem.Constants.v_FIELD_MODULUS <: i16) <: u16)) + (requires fe <. (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: u16)) (ensures fun result -> let result:u8 = result in @@ -125,7 +125,9 @@ val montgomery_reduce_element (value: i32) : Prims.Pure i16 (requires value >=. - ((cast (Core.Ops.Arith.Neg.neg Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) *! + ((Core.Ops.Arith.Neg.neg (cast (Libcrux_ml_kem.Vector.Traits.v_FIELD_MODULUS <: i16) <: i32) + <: + i32) *! v_MONTGOMERY_R <: i32) && diff --git a/libcrux-ml-kem/src/constants.rs b/libcrux-ml-kem/src/constants.rs index 13a5d7856..885a3eaec 100644 --- a/libcrux-ml-kem/src/constants.rs +++ b/libcrux-ml-kem/src/constants.rs @@ -1,7 +1,3 @@ -#[cfg(hax)] -/// Field modulus: 3329 -pub(crate) const FIELD_MODULUS: i16 = 3329; - /// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent pub(crate) const BITS_PER_COEFFICIENT: usize = 12; diff --git a/libcrux-ml-kem/src/hash_functions.rs b/libcrux-ml-kem/src/hash_functions.rs index 97e345336..d22029642 100644 --- a/libcrux-ml-kem/src/hash_functions.rs +++ b/libcrux-ml-kem/src/hash_functions.rs @@ -174,32 +174,20 @@ pub(crate) mod avx2 { let mut out1 = [0u8; LEN]; let mut out2 = [0u8; LEN]; let mut out3 = [0u8; LEN]; - + match K as u8 { 2 => { x4::shake256( - &input[0], - &input[1], - &input[0], - &input[0], - &mut out0, - &mut out1, - &mut out2, - &mut out3, + &input[0], &input[1], &input[0], &input[0], &mut out0, &mut out1, + &mut out2, &mut out3, ); out[0] = out0; out[1] = out1; } 3 => { x4::shake256( - &input[0], - &input[1], - &input[2], - &input[0], - &mut out0, - &mut out1, - &mut out2, - &mut out3, + &input[0], &input[1], &input[2], &input[0], &mut out0, &mut out1, + &mut out2, &mut out3, ); out[0] = out0; out[1] = out1; @@ -207,14 +195,8 @@ pub(crate) mod avx2 { } 4 => { x4::shake256( - &input[0], - &input[1], - &input[2], - &input[3], - &mut out0, - &mut out1, - &mut out2, - &mut out3, + &input[0], &input[1], &input[2], &input[3], &mut out0, &mut out1, + &mut out2, &mut out3, ); out[0] = out0; out[1] = out1; diff --git a/libcrux-ml-kem/src/vector.rs b/libcrux-ml-kem/src/vector.rs index 7834b3d72..010cba802 100644 --- a/libcrux-ml-kem/src/vector.rs +++ b/libcrux-ml-kem/src/vector.rs @@ -143,7 +143,7 @@ fn montgomery_multiply_by_constant(mut v: PortableVector, c: i16) -> PortableVec /// /// The NIST FIPS 203 standard can be found at /// . -#[cfg_attr(hax, hax_lib::requires(fe < (crate::constants::FIELD_MODULUS as u16)))] +#[cfg_attr(hax, hax_lib::requires(fe < (FIELD_MODULUS as u16)))] #[cfg_attr(hax, hax_lib::ensures(|result| hax_lib::implies(833 <= fe && fe <= 2596, || result == 1) && hax_lib::implies(!(833 <= fe && fe <= 2596), || result == 0) @@ -179,7 +179,7 @@ pub(crate) fn compress_message_coefficient(fe: u16) -> u8 { coefficient_bits == 5 || coefficient_bits == 10 || coefficient_bits == 11) && - fe < (crate::constants::FIELD_MODULUS as u16)))] + fe < (FIELD_MODULUS as u16)))] #[cfg_attr(hax, hax_lib::ensures( |result| result >= 0 && result < 2i16.pow(coefficient_bits as u32)))] From 9d957d6e3b57fd20d1e72e09c9d680efafc5756a Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 16:00:00 +0200 Subject: [PATCH 64/84] ml-kem: enable overriding dependencies' revisions --- flake.nix | 4 ++++ libcrux-ml-kem/c.sh | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index a694e47c0..e07434444 100644 --- a/flake.nix +++ b/flake.nix @@ -81,6 +81,10 @@ ''; FSTAR_HOME = inputs.fstar.packages.${system}.default; KRML_HOME = inputs.karamel.packages.${system}.default.home; + CHARON_REV = inputs.charon.rev; + EURYDICE_REV = inputs.eurydice.rev; + KRML_REV = inputs.karamel.rev; + FSTAR_REV = inputs.fstar.rev; }; in { diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index 11488924c..a597cded9 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -70,13 +70,17 @@ clang-format --style=Google -i internal/*.h clang-format --style=Google -i intrinsics/*.h # Write out infos about the used tools +[ -z "$CHARON_REV" ] && export CHARON_REV=$(git -C $CHARON_HOME rev-parse HEAD) +[ -z "$EURYDICE_REV" ] && export EURYDICE_REV=$(git -C $EURYDICE_HOME rev-parse HEAD) +[ -z "$KRML_REV" ] && export KRML_REV=$(git -C $KRML_HOME rev-parse HEAD) +[ -z "$FSTAR_REV" ] && export FSTAR_REV=$(git -C $FSTAR_HOME rev-parse HEAD) rm -f code_gen.txt echo "This code was generated with the following tools:" >> code_gen.txt echo -n "Charon: " >> code_gen.txt -git -C $CHARON_HOME rev-parse HEAD >> code_gen.txt +echo "$CHARON_REV" >> code_gen.txt echo -n "Eurydice: " >> code_gen.txt -git -C $EURYDICE_HOME rev-parse HEAD >> code_gen.txt +echo "$EURYDICE_REV" >> code_gen.txt echo -n "Karamel: " >> code_gen.txt -git -C $KRML_HOME rev-parse HEAD >> code_gen.txt +echo "$KRML_REV" >> code_gen.txt echo -n "F*: " >> code_gen.txt -git -C $FSTAR_HOME rev-parse HEAD >> code_gen.txt +echo "$FSTAR_REV" >> code_gen.txt From 729d07b76d188e64f7aadc17de9356f6dbeaf83d Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 16:09:34 +0200 Subject: [PATCH 65/84] format --- flake.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flake.nix b/flake.nix index e07434444..35be04a13 100644 --- a/flake.nix +++ b/flake.nix @@ -48,6 +48,7 @@ ml-kem = craneLib.buildPackage { name = "ml-kem"; inherit src cargoArtifacts; + nativeBuildInputs = [ pkgs.clang-tools pkgs.cmake @@ -73,6 +74,7 @@ build/Release/ml_kem_bench ''; installPhase = "cp -r . $out"; + CHARON_HOME = inputs.charon.packages.${system}.default; EURYDICE_HOME = pkgs.runCommand "eurydice-home" { } '' mkdir -p $out @@ -81,6 +83,7 @@ ''; FSTAR_HOME = inputs.fstar.packages.${system}.default; KRML_HOME = inputs.karamel.packages.${system}.default.home; + CHARON_REV = inputs.charon.rev; EURYDICE_REV = inputs.eurydice.rev; KRML_REV = inputs.karamel.rev; From 9cb5580922921208ccdf69668fbb733a771abc4a Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 16:23:00 +0200 Subject: [PATCH 66/84] update `flake.lock` --- flake.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index c06ddd613..42da119bd 100644 --- a/flake.lock +++ b/flake.lock @@ -12,11 +12,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1717577599, - "narHash": "sha256-5LxkX4sCtd82/h3WXkbDP4eWQMP+7Wd2xhg6xLQXQV4=", + "lastModified": 1718091767, + "narHash": "sha256-H5yk4492tRc638LvFGQGva2yjQPbWt71Aj7OAhT57KU=", "owner": "aeneasverif", "repo": "charon", - "rev": "a00876a9cd94e9ac63dbb71dae3df337b568dba3", + "rev": "0b8b7a82c2a18f65ab9df16f222d52594c17f59c", "type": "github" }, "original": { @@ -33,11 +33,11 @@ ] }, "locked": { - "lastModified": 1717535930, - "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "lastModified": 1701622587, + "narHash": "sha256-o3XhxCCyrUHZ0tlta2W7/MuXzy+n0+BUt3rKFK3DIK4=", "owner": "ipetkov", "repo": "crane", - "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "rev": "c09d2cbe84cc2adfe1943cb2a0b55a71c835ca9a", "type": "github" }, "original": { @@ -81,11 +81,11 @@ ] }, "locked": { - "lastModified": 1717520324, - "narHash": "sha256-w20SD6lKSjE5Zc7dLnCceF9EOHCZbWxyMDgqVds4f28=", + "lastModified": 1718042534, + "narHash": "sha256-h5qZeZYmTF+rAj5JdZQWcbt3V+IQs8QRS+BFnm3Bay8=", "owner": "aeneasverif", "repo": "eurydice", - "rev": "9f8d759db7e7c8dfb406e1b373d316aadc5cdd98", + "rev": "f5a2305081d09f3b45ed272e5388e542f4c4a7c1", "type": "github" }, "original": { @@ -203,11 +203,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1716897445, - "narHash": "sha256-Ytz9l3PjhBHULVZphHoUj15Ad8Wq3cIK6Paus32NB1w=", + "lastModified": 1717456679, + "narHash": "sha256-GjDR+YhmIBHJ/1WotSwcHYmXP1VvkZS5I2YpPJlzWDc=", "owner": "FStarLang", "repo": "fstar", - "rev": "9820798dcc31cd1ea5c164611a67f58ade0b7655", + "rev": "6d124af2bda315ae20f9fe974ffc668f8bd5791d", "type": "github" }, "original": { @@ -222,11 +222,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1716897445, - "narHash": "sha256-Ytz9l3PjhBHULVZphHoUj15Ad8Wq3cIK6Paus32NB1w=", + "lastModified": 1717456679, + "narHash": "sha256-GjDR+YhmIBHJ/1WotSwcHYmXP1VvkZS5I2YpPJlzWDc=", "owner": "fstarlang", "repo": "fstar", - "rev": "9820798dcc31cd1ea5c164611a67f58ade0b7655", + "rev": "6d124af2bda315ae20f9fe974ffc668f8bd5791d", "type": "github" }, "original": { @@ -252,11 +252,11 @@ ] }, "locked": { - "lastModified": 1717454922, - "narHash": "sha256-3yseAxgtqchKisDIWvU2hxC5rqNbQd7HDAPo28Gnzpk=", + "lastModified": 1718042424, + "narHash": "sha256-6rpa26YdxXiV+PftX11ODFu1yiUAWHHRNgtOhf9mFoY=", "owner": "FStarLang", "repo": "karamel", - "rev": "749859845fed65d9391f4ba318c8cf27292a85ce", + "rev": "22425a93c68d9e3794909f98854aaffdc0560510", "type": "github" }, "original": { From fe3086825f2f9e9975bb2882cc08fce847dfe7c7 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 16:35:51 +0200 Subject: [PATCH 67/84] fix --- libcrux-ml-kem/c.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index a597cded9..e1129e50c 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -70,10 +70,10 @@ clang-format --style=Google -i internal/*.h clang-format --style=Google -i intrinsics/*.h # Write out infos about the used tools -[ -z "$CHARON_REV" ] && export CHARON_REV=$(git -C $CHARON_HOME rev-parse HEAD) -[ -z "$EURYDICE_REV" ] && export EURYDICE_REV=$(git -C $EURYDICE_HOME rev-parse HEAD) -[ -z "$KRML_REV" ] && export KRML_REV=$(git -C $KRML_HOME rev-parse HEAD) -[ -z "$FSTAR_REV" ] && export FSTAR_REV=$(git -C $FSTAR_HOME rev-parse HEAD) +[ -n "$CHARON_REV" ] || export CHARON_REV=$(git -C $CHARON_HOME rev-parse HEAD) +[ -n "$EURYDICE_REV" ] || export EURYDICE_REV=$(git -C $EURYDICE_HOME rev-parse HEAD) +[ -n "$KRML_REV" ] || export KRML_REV=$(git -C $KRML_HOME rev-parse HEAD) +[ -n "$FSTAR_REV" ] || export FSTAR_REV=$(git -C $FSTAR_HOME rev-parse HEAD) rm -f code_gen.txt echo "This code was generated with the following tools:" >> code_gen.txt echo -n "Charon: " >> code_gen.txt From a21496bcb066c23c24fb1d22c073f140f9bda2ea Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Tue, 11 Jun 2024 21:55:45 +0200 Subject: [PATCH 68/84] ci: fix `hax.yml` --- .github/workflows/hax.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/hax.yml b/.github/workflows/hax.yml index c6f4f4748..9f7b6fc2d 100644 --- a/.github/workflows/hax.yml +++ b/.github/workflows/hax.yml @@ -28,9 +28,6 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main - - name: Update dependencies - run: cargo update - - name: ⤵ Install FStar run: nix profile install github:FStarLang/FStar/v2024.01.13 From 5b13693f4c4e2df8991f2d5816fd1eede3e602c9 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 12 Jun 2024 08:06:39 +0200 Subject: [PATCH 69/84] update C extration --- libcrux-ml-kem/c/code_gen.txt | 2 +- libcrux-ml-kem/c/internal/libcrux_core.h | 24 - .../c/internal/libcrux_sha3_internal.h | 12 +- libcrux-ml-kem/c/libcrux_mlkem_avx2.c | 569 +++++++----------- libcrux-ml-kem/c/libcrux_sha3_internal.h | 338 +++++------ libcrux-ml-kem/c/mach | 75 +++ 6 files changed, 478 insertions(+), 542 deletions(-) create mode 100755 libcrux-ml-kem/c/mach diff --git a/libcrux-ml-kem/c/code_gen.txt b/libcrux-ml-kem/c/code_gen.txt index 511c010db..0da0e1229 100644 --- a/libcrux-ml-kem/c/code_gen.txt +++ b/libcrux-ml-kem/c/code_gen.txt @@ -1,5 +1,5 @@ This code was generated with the following tools: Charon: 0b8b7a82c2a18f65ab9df16f222d52594c17f59c -Eurydice: f5a2305081d09f3b45ed272e5388e542f4c4a7c1 +Eurydice: ec9da30ba3723647ca6f03810cfcfd418bd48bf8 Karamel: 22425a93c68d9e3794909f98854aaffdc0560510 F*: \ No newline at end of file diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index b4f7dd467..9e3db79d7 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -148,36 +148,12 @@ uint8_t libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___768size_t( Eurydice_slice lhs, Eurydice_slice rhs); -typedef struct - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_; - void libcrux_ml_kem_utils_into_padded_array___33size_t(Eurydice_slice slice, uint8_t ret[33U]); void libcrux_ml_kem_utils_into_padded_array___34size_t(Eurydice_slice slice, uint8_t ret[34U]); -typedef struct - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_; - -typedef struct - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t__s { - Eurydice_slice fst; - Eurydice_slice snd; -} K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_; - Eurydice_slice libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___768size_t( libcrux_ml_kem_types_MlKemCiphertext____768size_t *self); diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index d31a0635a..e7c8658a4 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -45,7 +45,7 @@ libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)168U); Eurydice_slice o0[1U]; memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -54,7 +54,7 @@ libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( s, o0); K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o10, (size_t)168U); Eurydice_slice o1[1U]; memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -129,7 +129,7 @@ libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_ libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)168U); Eurydice_slice o0[1U]; memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -138,7 +138,7 @@ libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_ libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( s, o0); K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o10, (size_t)168U); Eurydice_slice o1[1U]; memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -147,7 +147,7 @@ libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( s, o1); K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o20, (size_t)168U); Eurydice_slice o2[1U]; memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -156,7 +156,7 @@ libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( s, o2); K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o30, (size_t)168U); Eurydice_slice o3[1U]; memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index ea61181bb..8445a7bbe 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -1810,42 +1810,30 @@ static inline void shake128_squeeze_three_blocks___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[3U][504U]) { uint8_t out[3U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + uint8_t out0[504U] = {0U}; + uint8_t out1[504U] = {0U}; + uint8_t out2[504U] = {0U}; + uint8_t out3[504U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)504U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)504U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)504U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)504U, dummy_out0, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)504U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[504U]; + memcpy(uu____4, out0, (size_t)504U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____5[504U]; + memcpy(uu____5, out1, (size_t)504U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____6[504U]; + memcpy(uu____6, out2, (size_t)504U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)504U * sizeof(uint8_t)); memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); } @@ -1894,42 +1882,30 @@ static inline void shake128_squeeze_block___3size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[3U][168U]) { uint8_t out[3U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____2 = self; - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____2, uu____3, uu____4, uu____5, - Eurydice_array_to_slice((size_t)168U, dummy_out0, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); } @@ -2116,48 +2092,36 @@ typedef struct static inline void PRFxN___3size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[3U][128U]) { uint8_t out[3U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)3U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out12 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out12, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out2 = uu____1.snd; - Eurydice_slice uu____2 = + uint8_t out0[128U] = {0U}; + uint8_t out1[128U] = {0U}; + uint8_t out2[128U] = {0U}; + uint8_t out3[128U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)128U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)128U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)128U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, - Eurydice_array_to_slice((size_t)128U, dummy_out0, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice((size_t)128U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____7[128U]; + memcpy(uu____7, out0, (size_t)128U * sizeof(uint8_t)); + memcpy(out[0U], uu____7, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____8[128U]; + memcpy(uu____8, out1, (size_t)128U * sizeof(uint8_t)); + memcpy(out[1U], uu____8, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____9[128U]; + memcpy(uu____9, out2, (size_t)128U * sizeof(uint8_t)); + memcpy(out[2U], uu____9, (size_t)128U * sizeof(uint8_t)); memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); } @@ -4573,50 +4537,33 @@ static inline void shake128_squeeze_three_blocks___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[4U][504U]) { uint8_t out[4U][504U] = {{0U}}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + uint8_t out0[504U] = {0U}; + uint8_t out1[504U] = {0U}; + uint8_t out2[504U] = {0U}; + uint8_t out3[504U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)504U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)504U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)504U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[504U], - uint8_t(*)[504U], uint8_t[504U]), - uint8_t, Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)504U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[504U]; + memcpy(uu____4, out0, (size_t)504U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____5[504U]; + memcpy(uu____5, out1, (size_t)504U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____6[504U]; + memcpy(uu____6, out2, (size_t)504U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____7[504U]; + memcpy(uu____7, out3, (size_t)504U * sizeof(uint8_t)); + memcpy(out[3U], uu____7, (size_t)504U * sizeof(uint8_t)); memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); } @@ -4665,50 +4612,33 @@ static inline void shake128_squeeze_block___4size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[4U][168U]) { uint8_t out[4U][168U] = {{0U}}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____3 = self; - Eurydice_slice uu____4 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____3, uu____4, uu____5, uu____6, - Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[168U], - uint8_t(*)[168U], uint8_t[168U]), - uint8_t, Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____7[168U]; + memcpy(uu____7, out3, (size_t)168U * sizeof(uint8_t)); + memcpy(out[3U], uu____7, (size_t)168U * sizeof(uint8_t)); memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); } @@ -4875,56 +4805,39 @@ typedef struct static inline void PRFxN___4size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[4U][128U]) { uint8_t out[4U][128U] = {{0U}}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)4U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out123 = uu____0.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____1 = core_slice___Slice_T___split_at_mut( - out123, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out1 = uu____1.fst; - Eurydice_slice out23 = uu____1.snd; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____2 = core_slice___Slice_T___split_at_mut( - out23, (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out2 = uu____2.fst; - Eurydice_slice out3 = uu____2.snd; - Eurydice_slice uu____3 = + uint8_t out0[128U] = {0U}; + uint8_t out1[128U] = {0U}; + uint8_t out2[128U] = {0U}; + uint8_t out3[128U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[3U], uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____8 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____9 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out2, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)128U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)128U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)128U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____3, uu____4, uu____5, uu____6, uu____7, uu____8, uu____9, - Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out3, (size_t)0U, uint8_t[128U], - uint8_t(*)[128U], uint8_t[128U]), - uint8_t, Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice((size_t)128U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____7[128U]; + memcpy(uu____7, out0, (size_t)128U * sizeof(uint8_t)); + memcpy(out[0U], uu____7, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____8[128U]; + memcpy(uu____8, out1, (size_t)128U * sizeof(uint8_t)); + memcpy(out[1U], uu____8, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____9[128U]; + memcpy(uu____9, out2, (size_t)128U * sizeof(uint8_t)); + memcpy(out[2U], uu____9, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____10[128U]; + memcpy(uu____10, out3, (size_t)128U * sizeof(uint8_t)); + memcpy(out[3U], uu____10, (size_t)128U * sizeof(uint8_t)); memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); } @@ -6124,34 +6037,27 @@ static inline void shake128_squeeze_three_blocks___2size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[2U][504U]) { uint8_t out[2U][504U] = {{0U}}; - uint8_t dummy_out0[504U] = {0U}; - uint8_t dummy_out1[504U] = {0U}; - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[504U], - Eurydice_slice), - (size_t)1U, uint8_t[504U], - K___Eurydice_slice_uint8_t_504size_t__Eurydice_slice_uint8_t_504size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; + uint8_t out0[504U] = {0U}; + uint8_t out1[504U] = {0U}; + uint8_t out2[504U] = {0U}; + uint8_t out3[504U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)504U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[504U], uint8_t(*)[504U], - uint8_t[504U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)504U, dummy_out0, - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)504U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)504U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)504U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)504U, dummy_out1, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)504U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[504U]; + memcpy(uu____4, out0, (size_t)504U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____5[504U]; + memcpy(uu____5, out1, (size_t)504U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)504U * sizeof(uint8_t)); memcpy(ret, out, (size_t)2U * sizeof(uint8_t[504U])); } @@ -6200,34 +6106,27 @@ static inline void shake128_squeeze_block___2size_t( libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, uint8_t ret[2U][168U]) { uint8_t out[2U][168U] = {{0U}}; - uint8_t dummy_out0[168U] = {0U}; - uint8_t dummy_out1[168U] = {0U}; - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[168U], - Eurydice_slice), - (size_t)1U, uint8_t[168U], - K___Eurydice_slice_uint8_t_168size_t__Eurydice_slice_uint8_t_168size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t - *uu____1 = self; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____3 = Eurydice_array_to_slice( - (size_t)168U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[168U], uint8_t(*)[168U], - uint8_t[168U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____4 = Eurydice_array_to_slice((size_t)168U, dummy_out0, - uint8_t, Eurydice_slice); + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( - uu____1, uu____2, uu____3, uu____4, - Eurydice_array_to_slice((size_t)168U, dummy_out1, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); memcpy(ret, out, (size_t)2U * sizeof(uint8_t[168U])); } @@ -6394,40 +6293,33 @@ typedef struct static inline void PRFxN___2size_t_192size_t(uint8_t (*input)[33U], uint8_t ret[2U][192U]) { uint8_t out[2U][192U] = {{0U}}; - uint8_t dummy_out0[192U] = {0U}; - uint8_t dummy_out1[192U] = {0U}; - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[192U], - Eurydice_slice), - (size_t)1U, uint8_t[192U], - K___Eurydice_slice_uint8_t_192size_t__Eurydice_slice_uint8_t_192size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = + uint8_t out0[192U] = {0U}; + uint8_t out1[192U] = {0U}; + uint8_t out2[192U] = {0U}; + uint8_t out3[192U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)192U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[192U], uint8_t(*)[192U], - uint8_t[192U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)192U, dummy_out0, - uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)192U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)192U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)192U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)192U, dummy_out1, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice((size_t)192U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____7[192U]; + memcpy(uu____7, out0, (size_t)192U * sizeof(uint8_t)); + memcpy(out[0U], uu____7, (size_t)192U * sizeof(uint8_t)); + uint8_t uu____8[192U]; + memcpy(uu____8, out1, (size_t)192U * sizeof(uint8_t)); + memcpy(out[1U], uu____8, (size_t)192U * sizeof(uint8_t)); memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U])); } @@ -6800,40 +6692,33 @@ deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_768s static inline void PRFxN___2size_t_128size_t(uint8_t (*input)[33U], uint8_t ret[2U][128U]) { uint8_t out[2U][128U] = {{0U}}; - uint8_t dummy_out0[128U] = {0U}; - uint8_t dummy_out1[128U] = {0U}; - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_ - uu____0 = core_slice___Slice_T___split_at_mut( - Eurydice_array_to_slice((size_t)2U, out, uint8_t[128U], - Eurydice_slice), - (size_t)1U, uint8_t[128U], - K___Eurydice_slice_uint8_t_128size_t__Eurydice_slice_uint8_t_128size_t_); - Eurydice_slice out0 = uu____0.fst; - Eurydice_slice out1 = uu____0.snd; - Eurydice_slice uu____1 = + uint8_t out0[128U] = {0U}; + uint8_t out1[128U] = {0U}; + uint8_t out2[128U] = {0U}; + uint8_t out3[128U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____2 = + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); Eurydice_slice uu____4 = - Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); - Eurydice_slice uu____5 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out0, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____6 = Eurydice_array_to_slice( - (size_t)128U, - Eurydice_slice_index(out1, (size_t)0U, uint8_t[128U], uint8_t(*)[128U], - uint8_t[128U]), - uint8_t, Eurydice_slice); - Eurydice_slice uu____7 = Eurydice_array_to_slice((size_t)128U, dummy_out0, - uint8_t, Eurydice_slice); + Eurydice_array_to_slice((size_t)128U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)128U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)128U, out2, uint8_t, Eurydice_slice); libcrux_sha3_avx2_x4_shake256( - uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, - Eurydice_array_to_slice((size_t)128U, dummy_out1, uint8_t, - Eurydice_slice)); + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice((size_t)128U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____7[128U]; + memcpy(uu____7, out0, (size_t)128U * sizeof(uint8_t)); + memcpy(out[0U], uu____7, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____8[128U]; + memcpy(uu____8, out1, (size_t)128U * sizeof(uint8_t)); + memcpy(out[1U], uu____8, (size_t)128U * sizeof(uint8_t)); memcpy(ret, out, (size_t)2U * sizeof(uint8_t[128U])); } diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index ff9426779..a2e760d8e 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -42,7 +42,7 @@ static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { 9223372039002292232ULL}; static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero( void) { return 0ULL; } @@ -56,7 +56,7 @@ static inline uint64_t libcrux_sha3_portable_keccak__veor5q_u64( } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); } @@ -74,7 +74,7 @@ static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); } @@ -86,7 +86,7 @@ static inline uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___and_not_xor( uint64_t a, uint64_t b, uint64_t c) { return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); } @@ -97,13 +97,13 @@ static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_constant( uint64_t a, uint64_t c) { return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor( uint64_t a, uint64_t b) { return a ^ b; } @@ -118,7 +118,7 @@ static inline void libcrux_sha3_portable_keccak_slice_1( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { Eurydice_slice uu____0[1U]; memcpy(uu____0, a, (size_t)1U * sizeof(Eurydice_slice)); @@ -143,7 +143,7 @@ libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], } static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( Eurydice_slice a[1U], size_t mid) { return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); } @@ -157,55 +157,55 @@ libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__Tra void) { libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; lit.st[0U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[0U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[1U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[2U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[3U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][0U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][1U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][2U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][3U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); lit.st[4U][4U] = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___zero(); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); return lit; } @@ -241,7 +241,7 @@ static inline void libcrux_sha3_portable_keccak_load_block_full___168size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___168size_t( uint64_t (*a)[5U], uint8_t b[1U][200U]) { uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; @@ -262,7 +262,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); } @@ -280,7 +280,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); } @@ -298,7 +298,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); } @@ -316,7 +316,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); } @@ -329,7 +329,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); } @@ -347,7 +347,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); } @@ -365,7 +365,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); } @@ -383,7 +383,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); } @@ -401,7 +401,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); } @@ -419,7 +419,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); } @@ -437,7 +437,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); } @@ -455,7 +455,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); } @@ -473,7 +473,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); } @@ -491,7 +491,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); } @@ -509,7 +509,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); } @@ -527,7 +527,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); } @@ -545,7 +545,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); } @@ -563,7 +563,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); } @@ -581,7 +581,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); } @@ -599,7 +599,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); } @@ -617,7 +617,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); } @@ -635,7 +635,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); } @@ -653,7 +653,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); } @@ -671,7 +671,7 @@ libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, } static inline uint64_t -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( uint64_t a, uint64_t b) { return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); } @@ -679,145 +679,145 @@ libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u6 static inline void libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], s->st[4U][0U]); uint64_t uu____1 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], s->st[4U][1U]); uint64_t uu____2 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], s->st[4U][2U]); uint64_t uu____3 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], s->st[4U][3U]); uint64_t c[5U] = { uu____0, uu____1, uu____2, uu____3, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor5( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], s->st[4U][4U])}; uint64_t uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( c[((size_t)0U + (size_t)4U) % (size_t)5U], c[((size_t)0U + (size_t)1U) % (size_t)5U]); uint64_t uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( c[((size_t)1U + (size_t)4U) % (size_t)5U], c[((size_t)1U + (size_t)1U) % (size_t)5U]); uint64_t uu____6 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( c[((size_t)2U + (size_t)4U) % (size_t)5U], c[((size_t)2U + (size_t)1U) % (size_t)5U]); uint64_t uu____7 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( c[((size_t)3U + (size_t)4U) % (size_t)5U], c[((size_t)3U + (size_t)1U) % (size_t)5U]); uint64_t t[5U] = { uu____4, uu____5, uu____6, uu____7, - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( c[((size_t)4U + (size_t)4U) % (size_t)5U], c[((size_t)4U + (size_t)1U) % (size_t)5U])}; uint64_t uu____8 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor( s->st[0U][0U], t[0U]); s->st[0U][0U] = uu____8; uint64_t uu____9 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( s->st[1U][0U], t[0U]); s->st[1U][0U] = uu____9; uint64_t uu____10 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( s->st[2U][0U], t[0U]); s->st[2U][0U] = uu____10; uint64_t uu____11 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( s->st[3U][0U], t[0U]); s->st[3U][0U] = uu____11; uint64_t uu____12 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( s->st[4U][0U], t[0U]); s->st[4U][0U] = uu____12; uint64_t uu____13 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( s->st[0U][1U], t[1U]); s->st[0U][1U] = uu____13; uint64_t uu____14 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( s->st[1U][1U], t[1U]); s->st[1U][1U] = uu____14; uint64_t uu____15 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( s->st[2U][1U], t[1U]); s->st[2U][1U] = uu____15; uint64_t uu____16 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( s->st[3U][1U], t[1U]); s->st[3U][1U] = uu____16; uint64_t uu____17 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( s->st[4U][1U], t[1U]); s->st[4U][1U] = uu____17; uint64_t uu____18 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( s->st[0U][2U], t[2U]); s->st[0U][2U] = uu____18; uint64_t uu____19 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( s->st[1U][2U], t[2U]); s->st[1U][2U] = uu____19; uint64_t uu____20 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( s->st[2U][2U], t[2U]); s->st[2U][2U] = uu____20; uint64_t uu____21 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( s->st[3U][2U], t[2U]); s->st[3U][2U] = uu____21; uint64_t uu____22 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( s->st[4U][2U], t[2U]); s->st[4U][2U] = uu____22; uint64_t uu____23 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( s->st[0U][3U], t[3U]); s->st[0U][3U] = uu____23; uint64_t uu____24 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( s->st[1U][3U], t[3U]); s->st[1U][3U] = uu____24; uint64_t uu____25 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( s->st[2U][3U], t[3U]); s->st[2U][3U] = uu____25; uint64_t uu____26 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( s->st[3U][3U], t[3U]); s->st[3U][3U] = uu____26; uint64_t uu____27 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( s->st[4U][3U], t[3U]); s->st[4U][3U] = uu____27; uint64_t uu____28 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( s->st[0U][4U], t[4U]); s->st[0U][4U] = uu____28; uint64_t uu____29 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( s->st[1U][4U], t[4U]); s->st[1U][4U] = uu____29; uint64_t uu____30 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( s->st[2U][4U], t[4U]); s->st[2U][4U] = uu____30; uint64_t uu____31 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( s->st[3U][4U], t[4U]); s->st[3U][4U] = uu____31; uint64_t uu____32 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( s->st[4U][4U], t[4U]); s->st[4U][4U] = uu____32; } @@ -861,7 +861,7 @@ static inline void libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___and_not_xor( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___and_not_xor( s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], old[i1][(j + (size_t)1U) % (size_t)5U]); s->st[i1][j] = uu____0;);); @@ -870,7 +870,7 @@ static inline void libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( static inline void libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, size_t i) { uint64_t uu____0 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___xor_constant( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_constant( s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); s->st[0U][0U] = uu____0; } @@ -907,7 +907,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___168size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -931,7 +931,7 @@ static inline void libcrux_sha3_portable_keccak_store_block___168size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___168size_t(a, b); } @@ -941,7 +941,7 @@ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( s->st, out); } @@ -949,12 +949,12 @@ static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( s->st, out); } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___168size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; @@ -969,7 +969,7 @@ libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___168size_t( uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -987,7 +987,7 @@ static inline void libcrux_sha3_portable_keccak_store_block_full___168size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); @@ -999,7 +999,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( s->st, b); { size_t i = (size_t)0U; @@ -1023,7 +1023,7 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( s.st, b); { size_t i = (size_t)0U; @@ -1054,7 +1054,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)168U, (size_t)168U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( uu____0, ret); @@ -1065,7 +1065,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( @@ -1078,7 +1078,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)168U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1098,7 +1098,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)168U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1148,7 +1148,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___104size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___104size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; @@ -1163,7 +1163,7 @@ libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___104size_t( uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1177,7 +1177,7 @@ static inline void libcrux_sha3_portable_keccak_load_block_full___104size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___104size_t( uint64_t (*a)[5U], uint8_t b[1U][200U]) { uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; @@ -1206,7 +1206,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___104size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1242,7 +1242,7 @@ static inline void libcrux_sha3_portable_keccak_store_block_full___104size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); @@ -1254,7 +1254,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( s->st, b); { size_t i = (size_t)0U; @@ -1273,7 +1273,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___104size_t(a, b); } @@ -1282,7 +1282,7 @@ static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( s->st, out); } @@ -1291,7 +1291,7 @@ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( s->st, out); } @@ -1301,7 +1301,7 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( s.st, b); { size_t i = (size_t)0U; @@ -1332,7 +1332,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)104U, (size_t)104U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( uu____0, ret); @@ -1343,7 +1343,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( @@ -1356,7 +1356,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)104U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1376,7 +1376,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)104U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1426,7 +1426,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___144size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___144size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; @@ -1441,7 +1441,7 @@ libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___144size_t( uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1455,7 +1455,7 @@ static inline void libcrux_sha3_portable_keccak_load_block_full___144size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___144size_t( uint64_t (*a)[5U], uint8_t b[1U][200U]) { uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; @@ -1484,7 +1484,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___144size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1520,7 +1520,7 @@ static inline void libcrux_sha3_portable_keccak_store_block_full___144size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); @@ -1532,7 +1532,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( s->st, b); { size_t i = (size_t)0U; @@ -1551,7 +1551,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___144size_t(a, b); } @@ -1560,7 +1560,7 @@ static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( s->st, out); } @@ -1569,7 +1569,7 @@ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( s->st, out); } @@ -1579,7 +1579,7 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( s.st, b); { size_t i = (size_t)0U; @@ -1610,7 +1610,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)144U, (size_t)144U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( uu____0, ret); @@ -1621,7 +1621,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( @@ -1634,7 +1634,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)144U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1654,7 +1654,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)144U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1704,7 +1704,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___136size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___136size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; @@ -1719,7 +1719,7 @@ libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___136size_t( uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1733,7 +1733,7 @@ static inline void libcrux_sha3_portable_keccak_load_block_full___136size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( uint64_t (*a)[5U], uint8_t b[1U][200U]) { uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; @@ -1762,7 +1762,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1798,7 +1798,7 @@ static inline void libcrux_sha3_portable_keccak_store_block_full___136size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); @@ -1810,7 +1810,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( s->st, b); { size_t i = (size_t)0U; @@ -1829,7 +1829,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___136size_t(a, b); } @@ -1838,7 +1838,7 @@ static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( s->st, out); } @@ -1847,7 +1847,7 @@ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( s->st, out); } @@ -1857,7 +1857,7 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( s.st, b); { size_t i = (size_t)0U; @@ -1888,7 +1888,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)136U, (size_t)136U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( uu____0, ret); @@ -1899,7 +1899,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( @@ -1912,7 +1912,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)136U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1932,7 +1932,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)136U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -1979,7 +1979,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -1997,7 +1997,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)136U, (size_t)136U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( uu____0, ret); @@ -2008,7 +2008,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( @@ -2021,7 +2021,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)136U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -2041,7 +2041,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)136U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -2091,7 +2091,7 @@ static inline void libcrux_sha3_portable_keccak_load_block___72size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___72size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { uint64_t(*uu____0)[5U] = a; Eurydice_slice uu____1[1U]; @@ -2106,7 +2106,7 @@ libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( uint64_t(*uu____0)[5U] = s->st; Eurydice_slice uu____1[1U]; memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___72size_t( uu____0, uu____1); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -2120,7 +2120,7 @@ static inline void libcrux_sha3_portable_keccak_load_block_full___72size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___72size_t( uint64_t (*a)[5U], uint8_t b[1U][200U]) { uint64_t(*uu____0)[5U] = a; uint8_t uu____1[1U][200U]; @@ -2149,7 +2149,7 @@ libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( uint64_t(*uu____1)[5U] = s->st; uint8_t uu____2[1U][200U]; memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___load_block_full___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___72size_t( uu____1, uu____2); libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); } @@ -2185,7 +2185,7 @@ static inline void libcrux_sha3_portable_keccak_store_block_full___72size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( uint64_t (*a)[5U], uint8_t ret[1U][200U]) { uint8_t ret0[1U][200U]; libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); @@ -2197,7 +2197,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( s->st, b); { size_t i = (size_t)0U; @@ -2216,7 +2216,7 @@ libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( } static inline void -libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( uint64_t (*a)[5U], Eurydice_slice b[1U]) { libcrux_sha3_portable_keccak_store_block___72size_t(a, b); } @@ -2225,7 +2225,7 @@ static inline void libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( s->st, out); } @@ -2234,7 +2234,7 @@ libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( s->st, out); } @@ -2244,7 +2244,7 @@ libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( Eurydice_slice out[1U]) { libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( s.st, b); { size_t i = (size_t)0U; @@ -2275,7 +2275,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( Eurydice_slice uu____1[1U]; memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____1, i0 * (size_t)72U, (size_t)72U, ret); libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, ret); @@ -2286,7 +2286,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( Eurydice_slice uu____3[1U]; memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___slice_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, ret); libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( @@ -2299,7 +2299,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( &s, out); } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( out, (size_t)72U); Eurydice_slice o0[1U]; memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); @@ -2319,7 +2319,7 @@ libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( break; } else { K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = - libcrux_sha3_portable_keccak___libcrux_sha3__traits__KeccakItem_1__usize__for_u64___split_at_mut_n( + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( o1, (size_t)72U); Eurydice_slice o[1U]; memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); diff --git a/libcrux-ml-kem/c/mach b/libcrux-ml-kem/c/mach new file mode 100755 index 000000000..7fa343011 --- /dev/null +++ b/libcrux-ml-kem/c/mach @@ -0,0 +1,75 @@ +#! /usr/bin/env python3 + +import os +import argparse +import platform +import subprocess +import sys + + +def shell(command, expect=0, cwd=None, env={}): + subprocess_stdout = subprocess.DEVNULL + + print("Env:", env) + print("Command: ", end="") + for i, word in enumerate(command): + if i == 4: + print("'{}' ".format(word), end="") + else: + print("{} ".format(word), end="") + + print("\nDirectory: {}".format(cwd)) + + os_env = os.environ + os_env.update(env) + + ret = subprocess.run(command, cwd=cwd, env=os_env) + if ret.returncode != expect: + raise Exception("Error {}. Expected {}.".format(ret, expect)) + + +class buildAction(argparse.Action): + def __call__(self, parser, args, values, option_string=None) -> None: + if platform.system() == "Windows": + # On Windows we use MSVC etc. by default. + # There's no multi config here. The type needs to be set when configuring. + cmake_args = [] + if args.release: + cmake_args.append("-DCMAKE_BUILD_TYPE=Release") + shell(["cmake", "-B", "build"] + cmake_args) + else: + # By default we use ninja with a multi config and set the build type + # during the build. + cmake_build_args = [] + if args.release: + cmake_build_args.append("--config Release") + shell(["cmake", "-B", "build", "-GNinja Multi-Config"]) + shell(["cmake", "--build", "build"] + cmake_build_args) + return None + + +def parse_arguments(): + parser = argparse.ArgumentParser(description="Libcrux C build helper.") + subparsers = parser.add_subparsers() + + build_parser = subparsers.add_parser("build", help="Build the C code.") + build_parser.add_argument("build", nargs="*", action=buildAction) + build_parser.add_argument( + "--release", action="store_true", help="Build in relase mode" + ) + + if len(sys.argv) == 1: + parser.print_help(sys.stderr) + sys.exit(1) + + return parser.parse_args() + + +def main(): + # Don't print unnecessary Python stack traces. + sys.tracebacklimit = 0 + parse_arguments() + + +if __name__ == "__main__": + main() From 20402d5d1551471f0e4afad2e964963335c3c876 Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Wed, 12 Jun 2024 08:29:14 +0200 Subject: [PATCH 70/84] CI fixes --- .github/workflows/hax.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/hax.yml b/.github/workflows/hax.yml index 9f7b6fc2d..e25b27e4b 100644 --- a/.github/workflows/hax.yml +++ b/.github/workflows/hax.yml @@ -59,11 +59,11 @@ jobs: rm -f sys/platform/proofs/fstar/extraction/*.fst* ./hax-driver.py --kyber-reference - - name: 🏃 Regenerate `extraction-*` folders - run: ./proofs/fstar/patches.sh apply +# - name: 🏃 Regenerate `extraction-*` folders +# run: ./proofs/fstar/patches.sh apply - - name: 🏃 Make sure snapshots are up-to-date - run: git diff --exit-code +# - name: 🏃 Make sure snapshots are up-to-date +# run: git diff --exit-code - name: 🏃 Verify the Kyber reference code run: | @@ -92,7 +92,7 @@ jobs: - name: 🏃 Extract & Verify ML-KEM crate (lax) run: | cd libcrux-ml-kem - # ./hax.py extract + ./hax.py extract # env FSTAR_HOME=${{ github.workspace }}/fstar \ # HACL_HOME=${{ github.workspace }}/hacl-star \ # HAX_HOME=${{ github.workspace }}/hax \ From e9e60676928364e1c485ed0a8755c5e5f1b055e5 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 12 Jun 2024 08:48:17 +0200 Subject: [PATCH 71/84] drop unnecessary hax jobs --- .github/workflows/hax.yml | 60 +-------------------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/.github/workflows/hax.yml b/.github/workflows/hax.yml index e25b27e4b..784c063cf 100644 --- a/.github/workflows/hax.yml +++ b/.github/workflows/hax.yml @@ -52,44 +52,7 @@ jobs: run: | nix profile install ./hax - - name: 🏃 Extract the Kyber reference code - run: | - eval $(opam env) - (cd proofs/fstar/extraction/ && ./clean.sh) - rm -f sys/platform/proofs/fstar/extraction/*.fst* - ./hax-driver.py --kyber-reference - -# - name: 🏃 Regenerate `extraction-*` folders -# run: ./proofs/fstar/patches.sh apply - -# - name: 🏃 Make sure snapshots are up-to-date -# run: git diff --exit-code - - - name: 🏃 Verify the Kyber reference code - run: | - env FSTAR_HOME=${{ github.workspace }}/fstar \ - HACL_HOME=${{ github.workspace }}/hacl-star \ - HAX_HOME=${{ github.workspace }}/hax \ - PATH="${PATH}:${{ github.workspace }}/fstar/bin" \ - ./hax-driver.py --verify-extraction - - - name: 🏃 Verify Kyber `extraction-edited` F* code - run: | - env FSTAR_HOME=${{ github.workspace }}/fstar \ - HACL_HOME=${{ github.workspace }}/hacl-star \ - HAX_HOME=${{ github.workspace }}/hax \ - PATH="${PATH}:${{ github.workspace }}/fstar/bin" \ - make -C proofs/fstar/extraction-edited - - - name: 🏃 Verify Kyber `extraction-secret-independent` F* code - run: | - env FSTAR_HOME=${{ github.workspace }}/fstar \ - HACL_HOME=${{ github.workspace }}/hacl-star \ - HAX_HOME=${{ github.workspace }}/hax \ - PATH="${PATH}:${{ github.workspace }}/fstar/bin" \ - make -C proofs/fstar/extraction-secret-independent - - - name: 🏃 Extract & Verify ML-KEM crate (lax) + - name: 🏃 Extract ML-KEM crate run: | cd libcrux-ml-kem ./hax.py extract @@ -98,24 +61,3 @@ jobs: # HAX_HOME=${{ github.workspace }}/hax \ # PATH="${PATH}:${{ github.workspace }}/fstar/bin" \ # ./hax.py prove --admit - - - name: 🏃 Extract the Kyber specification - run: | - eval $(opam env) - # Extract the functions in the compress module individually to test - # the function-extraction code. - # Extract functions from the remaining modules to test the - # module-extraction code. - ./hax-driver.py --crate-path specs/kyber \ - --functions hacspec_kyber::compress::compress \ - hacspec_kyber::compress::decompress \ - hacspec_kyber::compress::compress_d \ - hacspec::kyber::compress::decompress_d \ - --modules ind_cpa \ - hacspec_kyber \ - matrix \ - ntt \ - parameters \ - sampling \ - serialize \ - --exclude-modules libcrux::hacl::sha3 libcrux::digest From 3c9bba322ccdc01d04cb08b6398f231802d5f1be Mon Sep 17 00:00:00 2001 From: Karthikeyan Bhargavan Date: Wed, 12 Jun 2024 09:36:37 +0200 Subject: [PATCH 72/84] fixing hax.py to generate .fst files --- libcrux-ml-kem/hax.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcrux-ml-kem/hax.py b/libcrux-ml-kem/hax.py index dfe92840c..037f0ae47 100755 --- a/libcrux-ml-kem/hax.py +++ b/libcrux-ml-kem/hax.py @@ -101,8 +101,8 @@ def __call__(self, parser, args, values, option_string=None) -> None: ) # Extract ml-kem - include_str = "+:** -libcrux_ml_kem::types::index_impls::**" - interface_include = "+*" + include_str = "+** -libcrux_ml_kem::types::index_impls::**" + interface_include = "+**" cargo_hax_into = [ "cargo", "hax", From 3df9ae975ca3e0b6bd1e33c57c7ad8e5af8215c5 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 12 Jun 2024 09:54:14 +0200 Subject: [PATCH 73/84] update `flake.lock` --- flake.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/flake.lock b/flake.lock index 42da119bd..336a2fcb4 100644 --- a/flake.lock +++ b/flake.lock @@ -12,11 +12,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1718091767, - "narHash": "sha256-H5yk4492tRc638LvFGQGva2yjQPbWt71Aj7OAhT57KU=", + "lastModified": 1718119153, + "narHash": "sha256-/7Lv10doYagB+h9LzoT8hG9ns5ejEsAXBnii2kNDSoQ=", "owner": "aeneasverif", "repo": "charon", - "rev": "0b8b7a82c2a18f65ab9df16f222d52594c17f59c", + "rev": "0d3ba218b611b31cd9b800c237f15f7ffc787845", "type": "github" }, "original": { @@ -53,11 +53,11 @@ ] }, "locked": { - "lastModified": 1717535930, - "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "lastModified": 1718078026, + "narHash": "sha256-LbQabH6h86ZzTvDnaZHmMwedRZNB2jYtUQzmoqWQoJ8=", "owner": "ipetkov", "repo": "crane", - "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "rev": "a3f0c63eed74a516298932b9b1627dd80b9c3892", "type": "github" }, "original": { @@ -81,11 +81,11 @@ ] }, "locked": { - "lastModified": 1718042534, - "narHash": "sha256-h5qZeZYmTF+rAj5JdZQWcbt3V+IQs8QRS+BFnm3Bay8=", + "lastModified": 1718124394, + "narHash": "sha256-1sYQb6Oy/BtMBiWJ7X+nOf8+ZVWBmmm+29NtrIj3w2s=", "owner": "aeneasverif", "repo": "eurydice", - "rev": "f5a2305081d09f3b45ed272e5388e542f4c4a7c1", + "rev": "b2b62fffab78f91de07c20a7fa7385242fd54a0d", "type": "github" }, "original": { @@ -297,11 +297,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1717196966, - "narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=", + "lastModified": 1717974879, + "narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", + "rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3", "type": "github" }, "original": { From 650d1993a2308e03bbbd4bcf9a42cde654a87fa8 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 12 Jun 2024 10:27:00 +0200 Subject: [PATCH 74/84] nix: run hax --- flake.lock | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++++- flake.nix | 8 +- 2 files changed, 216 insertions(+), 2 deletions(-) diff --git a/flake.lock b/flake.lock index 336a2fcb4..4f2422f00 100644 --- a/flake.lock +++ b/flake.lock @@ -66,6 +66,33 @@ "type": "github" } }, + "crane_3": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": [ + "hax", + "flake-utils" + ], + "nixpkgs": [ + "hax", + "nixpkgs" + ], + "rust-overlay": "rust-overlay_2" + }, + "locked": { + "lastModified": 1693787605, + "narHash": "sha256-rwq5U8dy+a9JFny/73L0SJu1GfWwATMPMTp7D+mjHy8=", + "owner": "ipetkov", + "repo": "crane", + "rev": "8b4f7a4dab2120cf41e7957a28a853f45016bd9d", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "eurydice": { "inputs": { "charon": [ @@ -109,6 +136,22 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -197,6 +240,24 @@ "type": "github" } }, + "flake-utils_6": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1692799911, + "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "fstar": { "inputs": { "flake-utils": "flake-utils_3", @@ -235,6 +296,71 @@ "type": "github" } }, + "fstar_3": { + "inputs": { + "flake-utils": [ + "hax", + "flake-utils" + ], + "nixpkgs": [ + "hax", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1705191588, + "narHash": "sha256-xjSWDP8mSjLcn+0hsRpEdzsBgBR+mKCZB8yLmHl+WqE=", + "owner": "FStarLang", + "repo": "FStar", + "rev": "a32b316e521fa4f239b610ec8f1d15e78d62cbe8", + "type": "github" + }, + "original": { + "owner": "FStarLang", + "ref": "v2024.01.13", + "repo": "FStar", + "type": "github" + } + }, + "hacl-star": { + "flake": false, + "locked": { + "lastModified": 1699634660, + "narHash": "sha256-/mAi8wdlO1HHYKVj8pN/y5FUM/AwVPNazYFSy9pDlpY=", + "owner": "hacl-star", + "repo": "hacl-star", + "rev": "7f42aba60b37bc011d19472284bfcd3b95c1538e", + "type": "github" + }, + "original": { + "owner": "hacl-star", + "repo": "hacl-star", + "type": "github" + } + }, + "hax": { + "inputs": { + "crane": "crane_3", + "flake-utils": "flake-utils_6", + "fstar": "fstar_3", + "hacl-star": "hacl-star", + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay_3" + }, + "locked": { + "lastModified": 1717675342, + "narHash": "sha256-ZeBd/7OFaw5QXdHhMbspSrc2QiEYKKxtWHIZ6mHsCBY=", + "owner": "hacspec", + "repo": "hax", + "rev": "46bb5c19fb6f6397e15d9a4ff86c556482f81802", + "type": "github" + }, + "original": { + "owner": "hacspec", + "repo": "hax", + "type": "github" + } + }, "karamel": { "inputs": { "flake-utils": [ @@ -296,6 +422,20 @@ } }, "nixpkgs_3": { + "locked": { + "lastModified": 1694343207, + "narHash": "sha256-jWi7OwFxU5Owi4k2JmiL1sa/OuBCQtpaAesuj5LXC8w=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "78058d810644f5ed276804ce7ea9e82d92bee293", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_4": { "locked": { "lastModified": 1717974879, "narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=", @@ -321,11 +461,12 @@ "eurydice", "fstar" ], + "hax": "hax", "karamel": [ "eurydice", "karamel" ], - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_4" } }, "rust-overlay": { @@ -353,6 +494,58 @@ "type": "github" } }, + "rust-overlay_2": { + "inputs": { + "flake-utils": [ + "hax", + "crane", + "flake-utils" + ], + "nixpkgs": [ + "hax", + "crane", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1693707092, + "narHash": "sha256-HR1EnynBSPqbt+04/yxxqsG1E3n6uXrOl7SPco/UnYo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "98ccb73e6eefc481da6039ee57ad8818d1ca8d56", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_3": { + "inputs": { + "flake-utils": [ + "hax", + "flake-utils" + ], + "nixpkgs": [ + "hax", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1716862669, + "narHash": "sha256-7oTPM9lcdwiI1cpRC313B+lHawocgpY5F07N+Rbm5Uk=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "47b2d15658b37716393b2463a019000dbd6ce4bc", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "systems": { "locked": { "lastModified": 1681028828, @@ -427,6 +620,21 @@ "repo": "default", "type": "github" } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 35be04a13..433908416 100644 --- a/flake.nix +++ b/flake.nix @@ -16,6 +16,7 @@ }; fstar.follows = "eurydice/fstar"; karamel.follows = "eurydice/karamel"; + hax.url = "github:hacspec/hax"; }; outputs = @@ -55,9 +56,11 @@ pkgs.mold-wrapped pkgs.ninja pkgs.python3 + inputs.hax.packages.${system}.default ]; buildPhase = '' cd libcrux-ml-kem + python hax.py extract bash c.sh cd c cmake \ @@ -73,7 +76,10 @@ build/Release/ml_kem_test build/Release/ml_kem_bench ''; - installPhase = "cp -r . $out"; + installPhase = '' + cd ./.. + cp -r . $out + ''; CHARON_HOME = inputs.charon.packages.${system}.default; EURYDICE_HOME = pkgs.runCommand "eurydice-home" { } '' From 95b4a48868d86c5e2fdfe7d485ca341c9a1ea7a3 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Wed, 12 Jun 2024 11:04:24 +0200 Subject: [PATCH 75/84] ci: update `nix.yml` --- .github/workflows/nix.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 1e07d3497..4259aca31 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -3,11 +3,18 @@ name: Nix on: push: branches: [main, dev] + pull_request: jobs: nix: runs-on: ubuntu-latest steps: - uses: DeterminateSystems/nix-installer-action@v12 + - uses: DeterminateSystems/magic-nix-cache-action@v7 + - name: Install & configure Cachix + shell: bash + run: | + nix-env --quiet -j8 -iA cachix -f https://cachix.org/api/v1/install + cachix use hax - uses: actions/checkout@v4 - run: nix build -L .#ml-kem From f231c8599a057a13e35d1f15176d03c477b9b3cf Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 12 Jun 2024 11:17:58 +0200 Subject: [PATCH 76/84] update lock --- Cargo.lock | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b33d0864..a8e8f334e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1028,13 +1028,6 @@ dependencies = [ "rand", ] -[[package]] -name = "libcrux-simd" -version = "0.0.2-pre.2" -dependencies = [ - "libcrux-platform", -] - [[package]] name = "libfuzzer-sys" version = "0.4.7" From d0ad3512229acb4a32af26bbdd2e5a1cc9d9a46e Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Wed, 12 Jun 2024 16:10:27 +0200 Subject: [PATCH 77/84] Move P256 ECDSA signature API back to libcrux --- libcrux-ecdh/src/ecdh.rs | 9 --- libcrux-ecdh/src/hacl/p256.rs | 81 ------------------- src/hacl.rs | 8 ++ src/hacl/p256.rs | 147 ++-------------------------------- src/signature.rs | 14 ++-- 5 files changed, 21 insertions(+), 238 deletions(-) diff --git a/libcrux-ecdh/src/ecdh.rs b/libcrux-ecdh/src/ecdh.rs index dcd2e0a7f..3b9f11fe5 100644 --- a/libcrux-ecdh/src/ecdh.rs +++ b/libcrux-ecdh/src/ecdh.rs @@ -357,15 +357,6 @@ pub mod p256 { pub use hacl::p256::validate_point; pub use hacl::p256::validate_scalar_slice; pub use hacl::p256::Error; - pub mod ecdsa { - use super::hacl; - pub use hacl::p256::ecdsa::sign_sha256; - pub use hacl::p256::ecdsa::sign_sha384; - pub use hacl::p256::ecdsa::sign_sha512; - pub use hacl::p256::ecdsa::verify_sha256; - pub use hacl::p256::ecdsa::verify_sha384; - pub use hacl::p256::ecdsa::verify_sha512; - } } pub use p256_internal::generate_secret as p256_generate_secret; diff --git a/libcrux-ecdh/src/hacl/p256.rs b/libcrux-ecdh/src/hacl/p256.rs index 572d02b35..c3035f46c 100644 --- a/libcrux-ecdh/src/hacl/p256.rs +++ b/libcrux-ecdh/src/hacl/p256.rs @@ -137,84 +137,3 @@ pub fn secret_to_public(s: impl AsRef<[u8; 32]>) -> Result<[u8; 64], Error> { Err(Error::InvalidScalar) } } - -/// ECDSA on P256 -pub mod ecdsa { - use super::*; - use libcrux_hacl::{ - Hacl_P256_ecdsa_sign_p256_sha2, Hacl_P256_ecdsa_sign_p256_sha384, - Hacl_P256_ecdsa_sign_p256_sha512, Hacl_P256_ecdsa_verif_p256_sha2, - Hacl_P256_ecdsa_verif_p256_sha384, Hacl_P256_ecdsa_verif_p256_sha512, - }; - - macro_rules! implement { - ($sign:ident, $fun_sign:expr, $verify:ident, $fun_verify:expr) => { - /// Sign - /// - /// * private key validation must be performed before calling this function - pub fn $sign( - payload: &[u8], - private_key: &[u8; 32], - nonce: &[u8; 32], - ) -> Result<[u8; 64], Error> { - let mut result = [0u8; 64]; - if unsafe { - $fun_sign( - result.as_mut_ptr(), - payload.len().try_into().map_err(|_| Error::InvalidInput)?, - payload.as_ptr() as _, - private_key.as_ptr() as _, - nonce.as_ptr() as _, - ) - } { - Ok(result) - } else { - Err(Error::SigningError) - } - } - - /// Verification - /// - /// * public key validation must be performed before calling this function - pub fn $verify( - payload: &[u8], - public_key: &[u8; 64], - signature_r: &[u8; 32], - signature_s: &[u8; 32], - ) -> Result<(), Error> { - if unsafe { - $fun_verify( - payload.len().try_into().map_err(|_| Error::InvalidInput)?, - payload.as_ptr() as _, - public_key.as_ptr() as _, - signature_r.as_ptr() as _, - signature_s.as_ptr() as _, - ) - } { - Ok(()) - } else { - Err(Error::SigningError) - } - } - }; - } - - implement!( - sign_sha256, - Hacl_P256_ecdsa_sign_p256_sha2, - verify_sha256, - Hacl_P256_ecdsa_verif_p256_sha2 - ); - implement!( - sign_sha384, - Hacl_P256_ecdsa_sign_p256_sha384, - verify_sha384, - Hacl_P256_ecdsa_verif_p256_sha384 - ); - implement!( - sign_sha512, - Hacl_P256_ecdsa_sign_p256_sha512, - verify_sha512, - Hacl_P256_ecdsa_verif_p256_sha512 - ); -} diff --git a/src/hacl.rs b/src/hacl.rs index a27a61edf..bc8498fad 100644 --- a/src/hacl.rs +++ b/src/hacl.rs @@ -16,6 +16,7 @@ pub(crate) mod chacha20_poly1305; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod drbg; pub(crate) mod ed25519; +pub(crate) mod p256; pub(crate) mod sha2; pub(crate) mod sha3; @@ -26,6 +27,7 @@ pub enum Error { ChaCha20Poly1305(chacha20_poly1305::Error), Curve25519(libcrux_ecdh::curve25519::Error), P256(libcrux_ecdh::p256::Error), + P256ECDSA(p256::ecdsa::Error), Ed25519(ed25519::Error), Hkdf(libcrux_hkdf::Error), } @@ -59,3 +61,9 @@ impl From for Error { Error::Ed25519(val) } } + +impl From for Error { + fn from(val: p256::ecdsa::Error) -> Self { + Error::P256ECDSA(val) + } +} diff --git a/src/hacl/p256.rs b/src/hacl/p256.rs index cbb0c3302..ac3cfe27a 100644 --- a/src/hacl/p256.rs +++ b/src/hacl/p256.rs @@ -1,152 +1,17 @@ -use libcrux_hacl::{ - Hacl_P256_compressed_to_raw, Hacl_P256_dh_initiator, Hacl_P256_dh_responder, - Hacl_P256_uncompressed_to_raw, Hacl_P256_validate_private_key, Hacl_P256_validate_public_key, -}; - -use crate::ecdh::p256::PrivateKey; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Error { - InvalidInput, - InvalidScalar, - InvalidPoint, - NoCompressedPoint, - NoUnCompressedPoint, - SigningError, - InvalidSignature, -} - -/// Parse an uncompressed P256 point and return the 64 byte array with the -/// concatenation of X||Y -pub fn uncompressed_to_coordinates(point: &[u8]) -> Result<[u8; 64], Error> { - let mut concat_point = [0u8; 64]; - if point.len() >= 65 { - let ok = unsafe { - Hacl_P256_uncompressed_to_raw(point.as_ptr() as _, concat_point.as_mut_ptr()) - }; - if ok { - Ok(concat_point) - } else { - Err(Error::InvalidInput) - } - } else { - Err(Error::NoCompressedPoint) - } -} - -/// Parse an compressed P256 point and return the 64 byte array with the -/// concatenation of `X` and `Y`. -pub fn compressed_to_coordinates(point: &[u8]) -> Result<[u8; 64], Error> { - let mut concat_point = [0u8; 64]; - if point.len() >= 33 { - let ok = - unsafe { Hacl_P256_compressed_to_raw(point.as_ptr() as _, concat_point.as_mut_ptr()) }; - if ok { - Ok(concat_point) - } else { - Err(Error::InvalidInput) - } - } else { - Err(Error::NoUnCompressedPoint) - } -} - -/// Validate a P256 point, where `point` is a 64 byte array with the -/// concatenation of `X` and `Y`. -/// -/// Returns [`Error::InvalidPoint`] if the `point` is not valid. -pub fn validate_point(point: impl AsRef<[u8; 64]>) -> Result<(), Error> { - if unsafe { Hacl_P256_validate_public_key(point.as_ref().as_ptr() as _) } { - Ok(()) - } else { - Err(Error::InvalidPoint) - } -} - -/// Validate a P256 secret key (scalar). -/// -/// Returns [`Error::InvalidScalar`] if the `scalar` is not valid. -pub fn validate_scalar(scalar: &impl AsRef<[u8; 32]>) -> Result<(), Error> { - validate_scalar_(scalar.as_ref()) -} - -/// Validate a P256 secret key (scalar). -/// -/// Returns [`Error::InvalidScalar`] if the `scalar` is not valid. -pub fn validate_scalar_(scalar: &[u8; 32]) -> Result<(), Error> { - if scalar.as_ref().iter().all(|b| *b == 0) { - return Err(Error::InvalidScalar); - } - - // Ensure that the key is in range [1, p-1] - if unsafe { Hacl_P256_validate_private_key(scalar.as_ref().as_ptr() as _) } { - Ok(()) - } else { - Err(Error::InvalidScalar) - } -} - -/// Validate a P256 secret key (scalar). -pub fn validate_scalar_slice(scalar: &[u8]) -> Result { - if scalar.is_empty() { - return Err(Error::InvalidScalar); - } - - let mut private = [0u8; 32]; - // Force the length of `sk` to 32 bytes. - let sk_len = if scalar.len() >= 32 { 32 } else { scalar.len() }; - for i in 0..sk_len { - private[31 - i] = scalar[scalar.len() - 1 - i]; - } - - validate_scalar_(&private).map(|_| PrivateKey(private)) -} - -/// Compute the ECDH with the `private_key` and `public_key`. -/// -/// Returns the 64 bytes shared key. -pub fn ecdh( - private_key: impl AsRef<[u8; 32]>, - public_key: impl AsRef<[u8; 64]>, -) -> Result<[u8; 64], Error> { - let mut shared = [0u8; 64]; - let ok = unsafe { - Hacl_P256_dh_responder( - shared.as_mut_ptr(), - public_key.as_ref().as_ptr() as _, - private_key.as_ref().as_ptr() as _, - ) - }; - if !ok { - Err(Error::InvalidInput) - } else { - Ok(shared) - } -} - -/// Compute the public key for the provided `private_key`. -/// -/// Returns the 64 bytes public key. -pub fn secret_to_public(s: impl AsRef<[u8; 32]>) -> Result<[u8; 64], Error> { - validate_scalar(&s)?; - - let mut out = [0u8; 64]; - if unsafe { Hacl_P256_dh_initiator(out.as_mut_ptr(), s.as_ref().as_ptr() as _) } { - Ok(out) - } else { - Err(Error::InvalidScalar) - } -} - /// ECDSA on P256 pub mod ecdsa { - use super::*; + use libcrux_hacl::{ Hacl_P256_ecdsa_sign_p256_sha2, Hacl_P256_ecdsa_sign_p256_sha384, Hacl_P256_ecdsa_sign_p256_sha512, Hacl_P256_ecdsa_verif_p256_sha2, Hacl_P256_ecdsa_verif_p256_sha384, Hacl_P256_ecdsa_verif_p256_sha512, }; + #[derive(Debug, PartialEq, Eq, Clone, Copy)] + pub enum Error { + InvalidInput, + SigningError, + } macro_rules! implement { ($sign:ident, $fun_sign:expr, $verify:ident, $fun_verify:expr) => { /// Sign diff --git a/src/signature.rs b/src/signature.rs index 186c0cf6a..4a140cccc 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -373,7 +373,7 @@ pub fn sign( Algorithm::EcDsaP256(DigestAlgorithm::Sha256) => { let (private_key, nonce) = ecdsa_p256_sign_prep(private_key, rng)?; ecdsa_p256_sign_post( - libcrux_ecdh::p256::ecdsa::sign_sha256(payload, private_key.as_ref(), &nonce) + crate::hacl::p256::ecdsa::sign_sha256(payload, private_key.as_ref(), &nonce) .map_err(into_signing_error)?, alg, )? @@ -381,7 +381,7 @@ pub fn sign( Algorithm::EcDsaP256(DigestAlgorithm::Sha384) => { let (private_key, nonce) = ecdsa_p256_sign_prep(private_key, rng)?; ecdsa_p256_sign_post( - libcrux_ecdh::p256::ecdsa::sign_sha384(payload, private_key.as_ref(), &nonce) + crate::hacl::p256::ecdsa::sign_sha384(payload, private_key.as_ref(), &nonce) .map_err(into_signing_error)?, alg, )? @@ -389,7 +389,7 @@ pub fn sign( Algorithm::EcDsaP256(DigestAlgorithm::Sha512) => { let (private_key, nonce) = ecdsa_p256_sign_prep(private_key, rng)?; ecdsa_p256_sign_post( - libcrux_ecdh::p256::ecdsa::sign_sha512(payload, private_key.as_ref(), &nonce) + crate::hacl::p256::ecdsa::sign_sha512(payload, private_key.as_ref(), &nonce) .map_err(into_signing_error)?, alg, )? @@ -446,17 +446,17 @@ pub fn verify(payload: &[u8], signature: &Signature, public_key: &[u8]) -> Resul Signature::EcDsaP256(signature) => match signature.alg { Algorithm::EcDsaP256(DigestAlgorithm::Sha256) => { let pk = ecdsa_p256_verify_prep(public_key)?; - libcrux_ecdh::p256::ecdsa::verify_sha256(payload, &pk, &signature.r, &signature.s) + crate::hacl::p256::ecdsa::verify_sha256(payload, &pk, &signature.r, &signature.s) } Algorithm::EcDsaP256(DigestAlgorithm::Sha384) => { let pk = ecdsa_p256_verify_prep(public_key)?; - libcrux_ecdh::p256::ecdsa::verify_sha384(payload, &pk, &signature.r, &signature.s) + crate::hacl::p256::ecdsa::verify_sha384(payload, &pk, &signature.r, &signature.s) } Algorithm::EcDsaP256(DigestAlgorithm::Sha512) => { let pk = ecdsa_p256_verify_prep(public_key)?; - libcrux_ecdh::p256::ecdsa::verify_sha512(payload, &pk, &signature.r, &signature.s) + crate::hacl::p256::ecdsa::verify_sha512(payload, &pk, &signature.r, &signature.s) } - _ => Err(libcrux_ecdh::p256::Error::InvalidInput), + _ => Err(crate::hacl::p256::ecdsa::Error::InvalidInput), } .map_err(into_verify_error), Signature::Ed25519(signature) => { From b11939646899af3609229e54ea1af0fb98045b72 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Wed, 12 Jun 2024 16:21:01 +0200 Subject: [PATCH 78/84] Move ECDH tests to the `libcrux-ecdh` crate --- libcrux-ecdh/Cargo.toml | 7 + {tests => libcrux-ecdh/tests}/p256.rs | 24 +- libcrux-ecdh/tests/test_util.rs | 46 + .../tests/wycheproof/x25519_test.json | 5248 +++++++++++++++++ {tests => libcrux-ecdh/tests}/x25519.rs | 0 5 files changed, 5316 insertions(+), 9 deletions(-) rename {tests => libcrux-ecdh/tests}/p256.rs (71%) create mode 100644 libcrux-ecdh/tests/test_util.rs create mode 100644 libcrux-ecdh/tests/wycheproof/x25519_test.json rename {tests => libcrux-ecdh/tests}/x25519.rs (100%) diff --git a/libcrux-ecdh/Cargo.toml b/libcrux-ecdh/Cargo.toml index 407c8a1b3..68ed71519 100644 --- a/libcrux-ecdh/Cargo.toml +++ b/libcrux-ecdh/Cargo.toml @@ -14,3 +14,10 @@ path = "src/ecdh.rs" [dependencies] rand = { version = "0.8" } libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } + +[dev-dependencies] +libcrux = { version = "=0.0.2-pre.2", path = "../", features = ["rand"] } +hex = { version = "0.4.3", features = ["serde"] } +serde_json = { version = "1.0" } +serde = { version = "1.0", features = ["derive"] } +pretty_env_logger = "0.5" diff --git a/tests/p256.rs b/libcrux-ecdh/tests/p256.rs similarity index 71% rename from tests/p256.rs rename to libcrux-ecdh/tests/p256.rs index 28ac6e734..17b9a1344 100644 --- a/tests/p256.rs +++ b/libcrux-ecdh/tests/p256.rs @@ -1,6 +1,6 @@ #[cfg(not(target_arch = "wasm32"))] use libcrux::drbg; -use libcrux::ecdh::{self, key_gen}; +use libcrux_ecdh::{self, key_gen}; #[cfg(target_arch = "wasm32")] use rand_core::OsRng; @@ -12,11 +12,13 @@ fn derive_rand() { #[cfg(target_arch = "wasm32")] let mut rng = OsRng; - let (private_a, public_a) = key_gen(ecdh::Algorithm::P256, &mut rng).unwrap(); - let (private_b, public_b) = key_gen(ecdh::Algorithm::P256, &mut rng).unwrap(); + let (private_a, public_a) = key_gen(libcrux_ecdh::Algorithm::P256, &mut rng).unwrap(); + let (private_b, public_b) = key_gen(libcrux_ecdh::Algorithm::P256, &mut rng).unwrap(); - let shared_a = ecdh::derive(ecdh::Algorithm::P256, &public_b, &private_a).unwrap(); - let shared_b = ecdh::derive(ecdh::Algorithm::P256, &public_a, &private_b).unwrap(); + let shared_a = + libcrux_ecdh::derive(libcrux_ecdh::Algorithm::P256, &public_b, &private_a).unwrap(); + let shared_b = + libcrux_ecdh::derive(libcrux_ecdh::Algorithm::P256, &public_a, &private_b).unwrap(); eprintln!("a = {}", hex::encode(&private_a)); eprintln!("A = {}", hex::encode(&public_a)); eprintln!("b = {}", hex::encode(&private_b)); @@ -36,15 +38,19 @@ fn derive() { hex::decode("17e1ebef41df589d0483aa0ec4302abbe2dcc3da2e87211e09f36eb40131f304").unwrap(); let public_b = hex::decode("de9d41b163a0804b968b37ba21caec240e8191977ddf4d0594d656289a6cf96b260caee19e0e3b03bfa11361c9f02027c625a9f1ad4c832e0eb4684a8b32237b").unwrap(); - let public_a_comp = ecdh::secret_to_public(ecdh::Algorithm::P256, &private_a).unwrap(); + let public_a_comp = + libcrux_ecdh::secret_to_public(libcrux_ecdh::Algorithm::P256, &private_a).unwrap(); assert_eq!(public_a, public_a_comp); - let public_b_comp = ecdh::secret_to_public(ecdh::Algorithm::P256, &private_b).unwrap(); + let public_b_comp = + libcrux_ecdh::secret_to_public(libcrux_ecdh::Algorithm::P256, &private_b).unwrap(); assert_eq!(public_b, public_b_comp); let expected_shared = hex::decode("9839a5cf9b295e385e274dad44a3acf9d285bfc7ba8cfbe36c132f1c6967ab081ce2d1405f436ba09810a9c89b6a407ca3aec13519dec058d487e89520d3ac5e").unwrap(); - let shared_a = ecdh::derive(ecdh::Algorithm::P256, &public_b, &private_a).unwrap(); - let shared_b = ecdh::derive(ecdh::Algorithm::P256, &public_a, &private_b).unwrap(); + let shared_a = + libcrux_ecdh::derive(libcrux_ecdh::Algorithm::P256, &public_b, &private_a).unwrap(); + let shared_b = + libcrux_ecdh::derive(libcrux_ecdh::Algorithm::P256, &public_a, &private_b).unwrap(); eprintln!("a = {}", hex::encode(&private_a)); eprintln!("A = {}", hex::encode(&public_a)); eprintln!("b = {}", hex::encode(&private_b)); diff --git a/libcrux-ecdh/tests/test_util.rs b/libcrux-ecdh/tests/test_util.rs new file mode 100644 index 000000000..1ad11a902 --- /dev/null +++ b/libcrux-ecdh/tests/test_util.rs @@ -0,0 +1,46 @@ +#![allow(dead_code)] + +pub use serde::{self, de::DeserializeOwned}; +pub use std::fs::File; +pub use std::io::BufReader; + +use std::num::ParseIntError; + +pub(crate) trait ReadFromFile { + fn from_file(file_str: &'static str) -> T { + let file = match File::open(file_str) { + Ok(f) => f, + Err(_) => panic!("Couldn't open file {file_str}."), + }; + let reader = BufReader::new(file); + match serde_json::from_reader(reader) { + Ok(r) => r, + Err(e) => { + println!("{:?}", e); + panic!("Error reading file {file_str}.") + } + } + } +} + +pub(crate) fn hex_str_to_bytes(val: &str) -> Vec { + let b: Result, ParseIntError> = (0..val.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&val[i..i + 2], 16)) + .collect(); + b.expect("Error parsing hex string") +} + +pub(crate) fn hex_str_to_array(val: &str) -> A +where + A: Default + AsMut<[u8]>, +{ + let b: Result, ParseIntError> = (0..val.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&val[i..i + 2], 16)) + .collect(); + let b = b.expect("Error parsing hex string"); + let mut out = A::default(); + A::as_mut(&mut out).clone_from_slice(&b); + out +} diff --git a/libcrux-ecdh/tests/wycheproof/x25519_test.json b/libcrux-ecdh/tests/wycheproof/x25519_test.json new file mode 100644 index 000000000..431b434bd --- /dev/null +++ b/libcrux-ecdh/tests/wycheproof/x25519_test.json @@ -0,0 +1,5248 @@ +{ + "algorithm" : "XDH", + "generatorVersion" : "0.8r12", + "numberOfTests" : 518, + "header" : [ + "Test vectors of type XdhComp are intended for tests that verify the", + "computation of and Xdh key exchange." + ], + "notes" : { + "LowOrderPublic" : "The curves and its twists contain some points of low order. This test vector contains a public key with such a point. While many libraries reject such public keys, doing so is not a strict requirement according to RFC 7748.", + "NonCanonicalPublic" : "The public key is in non-canonical form. RFC 7749, section 5 defines the value that this public key represents. Section 7 of the same RFC recommends accepting such keys. If a non-canonical key is accepted then it must follow the RFC.", + "SmallPublicKey" : "The public key is insecure and does not belong to a valid private key. Some libraries reject such keys.", + "Twist" : "Public keys are either points on a given curve or points on its twist. The functions X25519 and X448 are defined for points on a twist with the goal that the output of computations do not leak private keys. Implementations may accept or reject points on a twist. If a point multiplication is performed then it is important that the result is correct, since otherwise attacks with invalid keys are possible.", + "ZeroSharedSecret" : "Some libraries include a check that the shared secret is not all-zero. This check is described in Section 6.1 of RFC 7748. " + }, + "schema" : "xdh_comp_schema.json", + "testGroups" : [ + { + "curve" : "curve25519", + "type" : "XdhComp", + "tests" : [ + { + "tcId" : 1, + "comment" : "normal case", + "public" : "504a36999f489cd2fdbc08baff3d88fa00569ba986cba22548ffde80f9806829", + "private" : "c8a9d5a91091ad851c668b0736c1c9a02936c0d3ad62670858088047ba057475", + "shared" : "436a2c040cf45fea9b29a0cb81b1f41458f863d0d61b453d0a982720d6d61320", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 2, + "comment" : "public key on twist", + "public" : "63aa40c6e38346c5caf23a6df0a5e6c80889a08647e551b3563449befcfc9733", + "private" : "d85d8c061a50804ac488ad774ac716c3f5ba714b2712e048491379a500211958", + "shared" : "279df67a7c4611db4708a0e8282b195e5ac0ed6f4b2f292c6fbd0acac30d1332", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 3, + "comment" : "public key on twist", + "public" : "0f83c36fded9d32fadf4efa3ae93a90bb5cfa66893bc412c43fa7287dbb99779", + "private" : "c8b45bfd32e55325d9fd648cb302848039000b390e44d521e58aab3b29a6964b", + "shared" : "4bc7e01e7d83d6cf67632bf90033487a5fc29eba5328890ea7b1026d23b9a45f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 4, + "comment" : "public key on twist", + "public" : "0b8211a2b6049097f6871c6c052d3c5fc1ba17da9e32ae458403b05bb283092a", + "private" : "f876e34bcbe1f47fbc0fddfd7c1e1aa53d57bfe0f66d243067b424bb6210be51", + "shared" : "119d37ed4b109cbd6418b1f28dea83c836c844715cdf98a3a8c362191debd514", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 5, + "comment" : "public key on twist", + "public" : "343ac20a3b9c6a27b1008176509ad30735856ec1c8d8fcae13912d08d152f46c", + "private" : "006ac1f3a653a4cdb1d37bba94738f8b957a57beb24d646e994dc29a276aad45", + "shared" : "cc4873aed3fcee4b3aaea7f0d20716b4276359081f634b7bea4b705bfc8a4d3e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 6, + "comment" : "public key on twist", + "public" : "fa695fc7be8d1be5bf704898f388c452bafdd3b8eae805f8681a8d15c2d4e142", + "private" : "08da77b26d06dff9d9f7fd4c5b3769f8cdd5b30516a5ab806be324ff3eb69e60", + "shared" : "b6f8e2fcb1affc79e2ff798319b2701139b95ad6dd07f05cbac78bd83edfd92e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 7, + "comment" : "public key on twist", + "public" : "0200000000000000000000000000000000000000000000000000000000000000", + "private" : "d03edde9f3e7b799045f9ac3793d4a9277dadeadc41bec0290f81f744f73775f", + "shared" : "b87a1722cc6c1e2feecb54e97abd5a22acc27616f78f6e315fd2b73d9f221e57", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 8, + "comment" : "public key on twist", + "public" : "0300000000000000000000000000000000000000000000000000000000000000", + "private" : "e09d57a914e3c29036fd9a442ba526b5cdcdf28216153e636c10677acab6bd6a", + "shared" : "a29d8dad28d590cd3017aa97a4761f851bf1d3672b042a4256a45881e2ad9035", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 9, + "comment" : "public key on twist", + "public" : "ff00000000000000000000000000000000000000000000000000000000000000", + "private" : "e0ed78e6ee02f08bec1c15d66fbbe5b83ffc37ea14e1512cc1bd4b2ea6d8066f", + "shared" : "e703bc8aa94b7d87ba34e2678353d12cdaaa1a97b5ca3e1b8c060c4636087f07", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 10, + "comment" : "public key on twist", + "public" : "ffff000000000000000000000000000000000000000000000000000000000000", + "private" : "a8a1a2ec9fa9915ae7aace6a37c68591d39e15995c4ef5ebd3561c02f72dda41", + "shared" : "ff5cf041e924dbe1a64ac9bdba96bdcdfaf7d59d91c7e33e76ed0e4c8c836446", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 11, + "comment" : "public key on twist", + "public" : "0000010000000000000000000000000000000000000000000000000000000000", + "private" : "a8c9df5820eb399d471dfa3215d96055b3c7d0f4ea49f8ab028d6a6e3194517b", + "shared" : "a92a96fa029960f9530e6fe37e2429cd113be4d8f3f4431f8546e6c76351475d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 12, + "comment" : "public key on twist", + "public" : "ffffff0f00000000000000000000000000000000000000000000000000000000", + "private" : "d0d31c491cbd39271859b4a63a316826507b1db8c701709fd0ffe3eb21c4467c", + "shared" : "9f8954868158ec62b6b586b8cae1d67d1b9f4c03d5b3ca0393cee71accc9ab65", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 13, + "comment" : "public key on twist", + "public" : "ffffffff00000000000000000000000000000000000000000000000000000000", + "private" : "d053e7bf1902619cd61c9c739e09d54c4147f46d190720966f7de1d9cffbbd4e", + "shared" : "6cbf1dc9af97bc148513a18be4a257de1a3b065584df94e8b43c1ab89720b110", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 14, + "comment" : "public key on twist", + "public" : "0000000000001000000000000000000000000000000000000000000000000000", + "private" : "a021d75009a4596e5a33f12921c10f3670933bc80dde3bba22881b6120582144", + "shared" : "38284b7086095a9406028c1f800c071ea106039ad7a1d7f82fe00906fd90594b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 15, + "comment" : "public key on twist", + "public" : "0000000000000001000000000000000000000000000000000000000000000000", + "private" : "a89c6687f99bd569a01fd8bd438236160d15ce2c57c1d71ebaa3f2da88233863", + "shared" : "c721041df0244071794a8db06b9f7eaeec690c257265343666f4416f4166840f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 16, + "comment" : "public key on twist", + "public" : "ffffffffffffffff000000000000000000000000000000000000000000000000", + "private" : "68964bca51465bf0f5ba524b1482ceff0e960a1ed9f48dcc30f1608d0e501a50", + "shared" : "25ff9a6631b143dbdbdc207b38e38f832ae079a52a618c534322e77345fd9049", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 17, + "comment" : "public key on twist", + "public" : "0000000000000000000000000000000000000000000000000100000000000000", + "private" : "a8e56bb13a9f2b33b8e6750b4a6e6621dc26ae8c5c624a0992c8f0d5b910f170", + "shared" : "f294e7922c6cea587aefe72911630d50f2456a2ba7f21207d57f1ecce04f6213", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 18, + "comment" : "public key on twist", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000", + "private" : "e045f55c159451e97814d747050fd7769bd478434a01876a56e553f66384a74c", + "shared" : "ff4715bd8cf847b77c244ce2d9b008b19efaa8e845feb85ce4889b5b2c6a4b4d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 19, + "comment" : "public key on twist", + "public" : "ffffff030000f8ffff1f0000c0ffffff000000feffff070000f0ffff3f000000", + "private" : "105d621e1ef339c3d99245cfb77cd3a5bd0c4427a0e4d8752c3b51f045889b4f", + "shared" : "61eace52da5f5ecefafa4f199b077ff64f2e3d2a6ece6f8ec0497826b212ef5f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 20, + "comment" : "public key on twist", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000", + "private" : "d88a441e706f606ae7f630f8b21f3c2554739e3e549f804118c03771f608017b", + "shared" : "ff1b509a0a1a54726086f1e1c0acf040ab463a2a542e5d54e92c6df8126cf636", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 21, + "comment" : "public key on twist", + "public" : "0000000000000000000000000000000000000000000000000000000000800000", + "private" : "80bbad168222276200aafd36f7f25fdc025632d8bf9f6354bb762e06fb63e250", + "shared" : "f134e6267bf93903085117b99932cc0c7ba26f25fca12102a26d7533d9c4272a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 22, + "comment" : "public key on twist", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "private" : "68e134092e94e622c8a0cd18aff55be23dabd994ebdee982d90601f6f0f4b369", + "shared" : "74bfc15e5597e9f5193f941e10a5c008fc89f051392723886a4a8fe5093a7354", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 23, + "comment" : "public key on twist", + "public" : "0000000000000000000000000000000000000000000000000000000000000020", + "private" : "e8e43fc1ebac0bbc9b99c8035ee1ac59b90f19a16c42c0b90f96adfcc5fdee78", + "shared" : "0d41a5b3af770bf2fcd34ff7972243a0e2cf4d34f2046a144581ae1ec68df03b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 24, + "comment" : "public key on twist", + "public" : "000000fcffff070000e0ffff3f000000ffffff010000f8ffff0f0000c0ffff7f", + "private" : "18bffb16f92680a9e267473e43c464476d5372ddd1f664f3d0678efe7c98bc79", + "shared" : "5894e0963583ae14a0b80420894167f4b759c8d2eb9b69cb675543f66510f646", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 25, + "comment" : "public key on twist", + "public" : "ffffffffffffff00000000000000ffffffffffffff00000000000000ffffff7f", + "private" : "300305eb002bf86c71fe9c0b311993727b9dc618d0ce7251d0dfd8552d17905d", + "shared" : "f8624d6e35e6c548ac47832f2e5d151a8e53b9290363b28d2ab8d84ab7cb6a72", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 26, + "comment" : "public key on twist", + "public" : "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffff7f", + "private" : "80da9f02842247d4ade5ddbac51dbce55ea7dca2844e7f97ab8987ce7fd8bc71", + "shared" : "bfe183ba3d4157a7b53ef178613db619e27800f85359c0b39a9fd6e32152c208", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 27, + "comment" : "public key on twist", + "public" : "edfffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f", + "private" : "806e7f26ca3246de8182946cbed09f52b95da626c823c7b50450001a47b7b252", + "shared" : "bca4a0724f5c1feb184078448c898c8620e7caf81f64cca746f557dff2498859", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 28, + "comment" : "public key on twist", + "public" : "edfffffffffffffeffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "58354fd64bc022cba3a71b2ae64281e4ea7bf6d65fdbaead1440eeb18604fe62", + "shared" : "b3418a52464c15ab0cacbbd43887a1199206d59229ced49202300638d7a40f04", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 29, + "comment" : "public key on twist", + "public" : "edffffffffffefffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "f0019cf05159794cc8052b00c2e75b7f46fb6693c4b38c02b12a4fe272e8556a", + "shared" : "fcde6e0a3d5fd5b63f10c2d3aad4efa05196f26bc0cb26fd6d9d3bd015eaa74f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 30, + "comment" : "public key on twist", + "public" : "edfeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "d0fca64cc5f3a0c8e75c824e8b09d1615aa79aeba139bb7302e2bb2fcbe54b40", + "shared" : "7d62f189444c6231a48afab10a0af2eee4a52e431ea05ff781d616af2114672f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 31, + "comment" : "public key on twist", + "public" : "eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "d02456e456911d3c6cd054933199807732dfdc958642ad1aebe900c793bef24a", + "shared" : "07ba5fcbda21a9a17845c401492b10e6de0a168d5c94b606694c11bac39bea41", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 32, + "comment" : "public key = 0", + "public" : "0000000000000000000000000000000000000000000000000000000000000000", + "private" : "88227494038f2bb811d47805bcdf04a2ac585ada7f2f23389bfd4658f9ddd45e", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 33, + "comment" : "public key = 1", + "public" : "0100000000000000000000000000000000000000000000000000000000000000", + "private" : "48232e8972b61c7e61930eb9450b5070eae1c670475685541f0476217e48184f", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 34, + "comment" : "edge case public key", + "public" : "0400000000000000000000000000000000000000000000000000000000000000", + "private" : "a8386f7f16c50731d64f82e6a170b142a4e34f31fd7768fcb8902925e7d1e25a", + "shared" : "34b7e4fa53264420d9f943d15513902342b386b172a0b0b7c8b8f2dd3d669f59", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 35, + "comment" : "edge case public key", + "public" : "0001000000000000000000000000000000000000000000000000000000000000", + "private" : "d05abd08bf5e62538cb9a5ed105dbedd6de38d07940085072b4311c2678ed77d", + "shared" : "3aa227a30781ed746bd4b3365e5f61461b844d09410c70570abd0d75574dfc77", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 36, + "comment" : "edge case public key", + "public" : "0000001000000000000000000000000000000000000000000000000000000000", + "private" : "f0b8b0998c8394364d7dcb25a3885e571374f91615275440db0645ee7c0a6f6b", + "shared" : "97755e7e775789184e176847ffbc2f8ef98799d46a709c6a1c0ffd29081d7039", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 37, + "comment" : "edge case public key", + "public" : "0000000001000000000000000000000000000000000000000000000000000000", + "private" : "d00c35dc17460f360bfae7b94647bc4e9a7ad9ce82abeadb50a2f1a0736e2175", + "shared" : "c212bfceb91f8588d46cd94684c2c9ee0734087796dc0a9f3404ff534012123d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 38, + "comment" : "edge case public key", + "public" : "ffffffffffff0f00000000000000000000000000000000000000000000000000", + "private" : "385fc8058900a85021dd92425d2fb39a62d4e23aef1d5104c4c2d88712d39e4d", + "shared" : "388faffb4a85d06702ba3e479c6b216a8f33efce0542979bf129d860f93b9f02", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 39, + "comment" : "edge case public key", + "public" : "ffffffffffffff00000000000000000000000000000000000000000000000000", + "private" : "e0614b0c408af24d9d24c0a72f9137fbd6b16f02ccc94797ea3971ab16073a7f", + "shared" : "877fec0669d8c1a5c866641420eea9f6bd1dfd38d36a5d55a8c0ab2bf3105c68", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 40, + "comment" : "edge case public key", + "public" : "0000000000000000010000000000000000000000000000000000000000000000", + "private" : "f004b8fd05d9fffd853cdc6d2266389b737e8dfc296ad00b5a69b2a9dcf72956", + "shared" : "180373ea0f23ea73447e5a90398a97d490b541c69320719d7dd733fb80d5480f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 41, + "comment" : "edge case public key", + "public" : "ffffffffffffffffffffffffffff000000000000000000000000000000000000", + "private" : "e80bf0e609bf3b035b552f9db7e9ecbc44a04b7910b1493661a524f46c3c2277", + "shared" : "208142350af938aba52a156dce19d3c27ab1628729683cf4ef2667c3dc60cf38", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 42, + "comment" : "edge case public key", + "public" : "0000000000000000000000000000010000000000000000000000000000000000", + "private" : "48890e95d1b03e603bcb51fdf6f296f1f1d10f5df10e00b8a25c9809f9aa1a54", + "shared" : "1c3263890f7a081cefe50cb92abd496582d90dcc2b9cb858bd286854aa6b0a7e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 43, + "comment" : "edge case public key", + "public" : "ffffffffffffffffffffffffffffffff00000000000000000000000000000000", + "private" : "a806f1e39b742615a7dde3b29415ed827c68f07d4a47a4d9595c40c7fccb9263", + "shared" : "56128e78d7c66f48e863e7e6f2caa9c0988fd439deac11d4aac9664083087f7a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 44, + "comment" : "edge case public key", + "public" : "0000000000000000000000000000000001000000000000000000000000000000", + "private" : "9899d5e265e1fc7c32345227d6699a6d6b5517cf33b43ab156ee20df4878794e", + "shared" : "30eca56f1f1c2e8ff780134e0e9382c5927d305d86b53477e9aeca79fc9ced05", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 45, + "comment" : "edge case public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000", + "private" : "d842316e5476aeaee838204258a06f15de011ba40b9962705e7f6e889fe71f40", + "shared" : "cb21b7aa3f992ecfc92954849154b3af6b96a01f17bf21c612da748db38eb364", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 46, + "comment" : "edge case public key", + "public" : "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000", + "private" : "a0933ee30512b25ee4e900aaa07f73e507a8ec53b53a44626e0f589af4e0356c", + "shared" : "c5caf8cabc36f086deaf1ab226434098c222abdf8acd3ce75c75e9debb271524", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 47, + "comment" : "edge case public key", + "public" : "0000000000000000000000000000000000000000000000000000000001000000", + "private" : "38d6403e1377734cdce98285e820f256ad6b769d6b5612bcf42cf2b97945c073", + "shared" : "4d46052c7eabba215df8d91327e0c4610421d2d9129b1486d914c766cf104c27", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 48, + "comment" : "edge case public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03", + "private" : "182191b7052e9cd630ef08007fc6b43bc7652913be6774e2fd271b71b962a641", + "shared" : "a0e0315175788362d4ebe05e6ac76d52d40187bd687492af05abc7ba7c70197d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 49, + "comment" : "edge case public key", + "public" : "ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f", + "private" : "106221fe5694a710d6e147696c5d5b93d6887d584f24f228182ebe1b1d2db85d", + "shared" : "5e64924b91873b499a5402fa64337c65d4b2ed54beeb3fa5d7347809e43aef1c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 50, + "comment" : "edge case public key", + "public" : "000000fcffff030000e0ffff1f000000ffffff000000f8ffff070000c0ffff3f", + "private" : "d035de9456080d85a912083b2e3c7ddd7971f786f25a96c5e782cf6f4376e362", + "shared" : "c052466f9712d9ec4ef40f276bb7e6441c5434a83efd8e41d20ce83f2dbf5952", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 51, + "comment" : "edge case public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "private" : "a8f37318a4c760f3cb2d894822918735683cb1edacf3e666e15694154978fd6d", + "shared" : "d151b97cba9c25d48e6d576338b97d53dd8b25e84f65f7a2091a17016317c553", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 52, + "comment" : "edge case public key", + "public" : "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", + "private" : "20d4d624cf732f826f09e8088017742f13f2da98f4dcf4b40519adb790cebf64", + "shared" : "5716296baf2b1a6b9cd15b23ba86829743d60b0396569be1d5b40014c06b477d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 53, + "comment" : "edge case public key", + "public" : "edffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fff7f", + "private" : "d806a735d138efb3b404683c9d84485ab4af540d0af253b574323d8913003c66", + "shared" : "ddbd56d0454b794c1d1d4923f023a51f6f34ef3f4868e3d6659307c683c74126", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 54, + "comment" : "edge case public key", + "public" : "fffffffffeffff7ffffffffffeffff7ffffffffffeffff7ffffffffffeffff7f", + "private" : "184198c6228177f3ef41dc9a341258f8181ae365fe9ec98d93639b0bbee1467d", + "shared" : "8039eebed1a4f3b811ea92102a6267d4da412370f3f0d6b70f1faaa2e8d5236d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 55, + "comment" : "edge case public key", + "public" : "edfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff7f", + "private" : "f0a46a7f4b989fe515edc441109346ba746ec1516896ec5b7e4f4d903064b463", + "shared" : "b69524e3955da23df6ad1a7cd38540047f50860f1c8fded9b1fdfcc9e812a035", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 56, + "comment" : "edge case public key", + "public" : "edfffffffffffffffffffffffffffffffffffffffffffffffeffffffffffff7f", + "private" : "881874fda3a99c0f0216e1172fbd07ab1c7df78602cc6b11264e57aab5f23a49", + "shared" : "e417bb8854f3b4f70ecea557454c5c4e5f3804ae537960a8097b9f338410d757", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 57, + "comment" : "edge case public key", + "public" : "edfffffffffffffffffffffffffffffffeffffffffffffffffffffffffffff7f", + "private" : "b8d0f1ae05a5072831443150e202ac6db00322cdf341f467e9f296588b04db72", + "shared" : "afca72bb8ef727b60c530c937a2f7d06bb39c39b903a7f4435b3f5d8fc1ca810", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 58, + "comment" : "edge case public key", + "public" : "edfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "c8619ba988859db7d6f20fbf3ffb8b113418cc278065b4e8bb6d4e5b3e7cb569", + "shared" : "7e41c2886fed4af04c1641a59af93802f25af0f9cba7a29ae72e2a92f35a1e5a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 59, + "comment" : "edge case public key", + "public" : "edfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "f8d4ca1f37a30ec9acd6dbe5a6e150e5bc447d22b355d80ba002c5b05c26935d", + "shared" : "dd3abd4746bf4f2a0d93c02a7d19f76d921c090d07e6ea5abae7f28848355947", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 60, + "comment" : "edge case public key", + "public" : "edffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "88037ac8e33c72c2c51037c7c8c5288bba9265c82fd8c31796dd7ea5df9aaa4a", + "shared" : "8c27b3bff8d3c1f6daf2d3b7b3479cf9ad2056e2002be247992a3b29de13a625", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 61, + "comment" : "edge case public key", + "public" : "edfffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "5034ee7bf83a13d9167df86b0640294f3620f4f4d9030e5e293f9190824ae562", + "shared" : "8e1d2207b47432f881677448b9d426a30de1a1f3fd38cad6f4b23dbdfe8a2901", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 62, + "comment" : "edge case public key", + "public" : "ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "40bd4e1caf39d9def7663823502dad3e7d30eb6eb01e9b89516d4f2f45b7cd7f", + "shared" : "2cf6974b0c070e3707bf92e721d3ea9de3db6f61ed810e0a23d72d433365f631", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 63, + "comment" : "public key with low order", + "public" : "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", + "private" : "e0f978dfcd3a8f1a5093418de54136a584c20b7b349afdf6c0520886f95b1272", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 64, + "comment" : "public key with low order", + "public" : "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", + "private" : "387355d995616090503aafad49da01fb3dc3eda962704eaee6b86f9e20c92579", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 65, + "comment" : "public key with low order", + "public" : "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "c8fe0df92ae68a03023fc0c9adb9557d31be7feed0d3ab36c558143daf4dbb40", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "Twist", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 66, + "comment" : "public key with low order", + "public" : "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880", + "private" : "c8d74acde5934e64b9895d5ff7afbffd7f704f7dfccff7ac28fa62a1e6410347", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "NonCanonicalPublic", + "Twist", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 67, + "comment" : "public key with low order", + "public" : "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7", + "private" : "b85649d5120e01e8ccaf7b2fb8d81b62e8ad6f3d5c0553fdde1906cb9d79c050", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "NonCanonicalPublic", + "Twist", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 68, + "comment" : "public key with low order", + "public" : "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "2064b2f4c9dc97ec7cf58932fdfa3265ba6ea4d11f0259b8efc8afb35db88c48", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "NonCanonicalPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 69, + "comment" : "public key with low order", + "public" : "0000000000000000000000000000000000000000000000000000000000000000", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 70, + "comment" : "public key with low order", + "public" : "0100000000000000000000000000000000000000000000000000000000000000", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 71, + "comment" : "public key with low order", + "public" : "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 72, + "comment" : "public key with low order", + "public" : "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 73, + "comment" : "public key with low order", + "public" : "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 74, + "comment" : "public key with low order", + "public" : "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 75, + "comment" : "public key with low order", + "public" : "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 76, + "comment" : "public key with low order", + "public" : "0000000000000000000000000000000000000000000000000000000000000080", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 77, + "comment" : "public key with low order", + "public" : "0100000000000000000000000000000000000000000000000000000000000080", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 78, + "comment" : "public key with low order", + "public" : "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 79, + "comment" : "public key with low order", + "public" : "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 80, + "comment" : "public key with low order", + "public" : "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 81, + "comment" : "public key with low order", + "public" : "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 82, + "comment" : "public key with low order", + "public" : "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 83, + "comment" : "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819949", + "public" : "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "40ff586e73d61f0960dc2d763ac19e98225f1194f6fe43d5dd97ad55b3d35961", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 84, + "comment" : "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819950", + "public" : "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "584fceaebae944bfe93b2e0d0a575f706ce5ada1da2b1311c3b421f9186c7a6f", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "NonCanonicalPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 85, + "comment" : "non-canonical public key", + "public" : "efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "0016b62af5cabde8c40938ebf2108e05d27fa0533ed85d70015ad4ad39762d54", + "shared" : "b4d10e832714972f96bd3382e4d082a21a8333a16315b3ffb536061d2482360d", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic", + "Twist" + ] + }, + { + "tcId" : 86, + "comment" : "non-canonical public key", + "public" : "f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "d83650ba7cec115881916255e3fa5fa0d6b8dcf968731bd2c9d2aec3f561f649", + "shared" : "515eac8f1ed0b00c70762322c3ef86716cd2c51fe77cec3d31b6388bc6eea336", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic", + "Twist" + ] + }, + { + "tcId" : 87, + "comment" : "non-canonical public key", + "public" : "f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "88dd14e2711ebd0b0026c651264ca965e7e3da5082789fbab7e24425e7b4377e", + "shared" : "6919992d6a591e77b3f2bacbd74caf3aea4be4802b18b2bc07eb09ade3ad6662", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 88, + "comment" : "non-canonical public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "98c2b08cbac14e15953154e3b558d42bb1268a365b0ef2f22725129d8ac5cb7f", + "shared" : "9c034fcd8d3bf69964958c0105161fcb5d1ea5b8f8abb371491e42a7684c2322", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 89, + "comment" : "non-canonical public key", + "public" : "0200000000000000000000000000000000000000000000000000000000000080", + "private" : "c0697b6f05e0f3433b44ea352f20508eb0623098a7770853af5ca09727340c4e", + "shared" : "ed18b06da512cab63f22d2d51d77d99facd3c4502e4abf4e97b094c20a9ddf10", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic", + "Twist" + ] + }, + { + "tcId" : 90, + "comment" : "non-canonical public key", + "public" : "0300000000000000000000000000000000000000000000000000000000000080", + "private" : "18422b58a18e0f4519b7a887b8cfb649e0bfe4b34d75963350a9944e5b7f5b7e", + "shared" : "448ce410fffc7e6149c5abec0ad5f3607dfde8a34e2ac3243c3009176168b432", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic", + "Twist" + ] + }, + { + "tcId" : 91, + "comment" : "non-canonical public key", + "public" : "0400000000000000000000000000000000000000000000000000000000000080", + "private" : "20620d82487707bedf9ee3549e95cb9390d2618f50cf6acba47ffaa103224a6f", + "shared" : "03a633df01480d0d5048d92f51b20dc1d11f73e9515c699429b90a4f6903122a", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 92, + "comment" : "non-canonical public key", + "public" : "daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "285a6a7ceeb7122f2c78d99c53b2a902b490892f7dff326f89d12673c3101b53", + "shared" : "9b01287717d72f4cfb583ec85f8f936849b17d978dbae7b837db56a62f100a68", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 93, + "comment" : "non-canonical public key", + "public" : "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "c8e0330ae9dceeff887fba761225879a4bd2e0db08799244136e4721b2c88970", + "shared" : "dfe60831c9f4f96c816e51048804dbdc27795d760eced75ef575cbe3b464054b", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 94, + "comment" : "non-canonical public key", + "public" : "dcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "10db6210fc1fb13382472fa1787b004b5d11868ab3a79510e0cee30f4a6df26b", + "shared" : "50bfa826ca77036dd2bbfd092c3f78e2e4a1f980d7c8e78f2f14dca3cce5cc3c", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic", + "Twist" + ] + }, + { + "tcId" : 95, + "comment" : "non-canonical public key", + "public" : "eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "9041c6e044a277df8466275ca8b5ee0da7bc028648054ade5c592add3057474e", + "shared" : "13da5695a4c206115409b5277a934782fe985fa050bc902cba5616f9156fe277", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 96, + "comment" : "non-canonical public key", + "public" : "ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "b8d499041a6713c0f6f876db7406587fdb44582f9542356ae89cfa958a34d266", + "shared" : "63483b5d69236c63cddbed33d8e22baecc2b0ccf886598e863c844d2bf256704", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 97, + "comment" : "non-canonical public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "private" : "c85f08e60c845f82099141a66dc4583d2b1040462c544d33d0453b20b1a6377e", + "shared" : "e9db74bc88d0d9bf046ddd13f943bccbe6dbb47d49323f8dfeedc4a694991a3c", + "result" : "acceptable", + "flags" : [ + "NonCanonicalPublic" + ] + }, + { + "tcId" : 98, + "comment" : "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819968", + "public" : "0000000000000000000000000000000000000000000000000000000000000080", + "private" : "7887889bac4c629a101d3724f2ed8b98d936fde79e1a1f77d86779626bf8f263", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "NonCanonicalPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 99, + "comment" : "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819969", + "public" : "0100000000000000000000000000000000000000000000000000000000000080", + "private" : "e07971ee820e48b0b266d8be3cdbbb5e900a43f59ee8535c6572418615de4962", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "NonCanonicalPublic", + "Twist", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 100, + "comment" : "RFC 7748", + "public" : "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c", + "private" : "a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44", + "shared" : "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 101, + "comment" : "RFC 7748", + "public" : "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a413", + "private" : "4866e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba4d", + "shared" : "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 102, + "comment" : "RFC 8037, Section A.6", + "public" : "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", + "private" : "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", + "shared" : "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 103, + "comment" : "edge case for shared secret", + "public" : "b7b6d39c765cb60c0c8542f4f3952ffb51d3002d4aeb9f8ff988b192043e6d0a", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "0200000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 104, + "comment" : "edge case for shared secret", + "public" : "3b18df1e50b899ebd588c3161cbd3bf98ebcc2c1f7df53b811bd0e91b4d5153d", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "0900000000000000000000000000000000000000000000000000000000000000", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 105, + "comment" : "edge case for shared secret", + "public" : "cab6f9e7d8ce00dfcea9bbd8f069ef7fb2ac504abf83b87db601b5ae0a7f7615", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "1000000000000000000000000000000000000000000000000000000000000000", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 106, + "comment" : "edge case for shared secret", + "public" : "4977d0d897e1ba566590f60f2eb0db6f7b24c13d436918ccfd32708dfad7e247", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 107, + "comment" : "edge case for shared secret", + "public" : "98730bc03e29e8b057fb1d20ef8c0bffc822485d3db7f45f4e3cc2c3c6d1d14c", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 108, + "comment" : "edge case for shared secret", + "public" : "97b4fff682df7f096cd1756569e252db482d45406a3198a1aff282a5da474c49", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 109, + "comment" : "edge case for shared secret", + "public" : "317781b0163bae74accc06c0d44ef9a911a22b0d37faf7726621591f9343ea2f", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 110, + "comment" : "edge case for shared secret", + "public" : "7e26f8f24cb590027f9d1bc49b0e1a242c7d8f43624d3e8fab28ee08e02cb45e", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 111, + "comment" : "edge case for shared secret", + "public" : "e96d2780e5469a74620ab5aa2f62151d140c473320dbe1b028f1a48f8e76f95f", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "e5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 112, + "comment" : "edge case for shared secret", + "public" : "8d612c5831aa64b057300e7e310f3aa332af34066fefcab2b089c9592878f832", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 113, + "comment" : "edge case for shared secret", + "public" : "8d44108d05d940d3dfe5647ea7a87be24d0d036c9f0a95a2386b839e7b7bf145", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 114, + "comment" : "edge case for shared secret", + "public" : "21a35d5db1b6237c739b56345a930aeee373cdcfb4701266782a8ac594913b29", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 115, + "comment" : "edge case for shared secret", + "public" : "3e5efb63c352ce942762482bc9337a5d35ba55664743ac5e93d11f957336cb10", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "0000000000000000000000000000000000000000000000000000000000000002", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 116, + "comment" : "edge case for shared secret", + "public" : "8e41f05ea3c76572be104ad8788e970863c6e2ca3daae64d1c2f46decfffa571", + "private" : "60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f", + "shared" : "0000000000000000000000000000000000000000000000000000000000008000", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 117, + "comment" : "special case public key", + "public" : "0000000000000000000000000000000000000000000000000000000000000000", + "private" : "c8d07c46bbfb827753b92c70e49583ce8bfa44641a7382258ea903d6a832c96b", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 118, + "comment" : "special case public key", + "public" : "0100000000000000000000000000000000000000000000000000000000000000", + "private" : "90b7ef237a055f348dcb4c4364a59d7d31edc7ab78f2ca254e2c810975c3f543", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "SmallPublicKey", + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 119, + "comment" : "special case public key", + "public" : "0200000000000000000000000000000000000000000000000000000000000000", + "private" : "e0a8be63315c4f0f0a3fee607f44d30a55be63f09561d9af93e0a1c9cf0ed751", + "shared" : "0c50ac2bfb6815b47d0734c5981379882a24a2de6166853c735329d978baee4d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 120, + "comment" : "special case public key", + "public" : "1200000000000000000000000000000000000000000000000000000000000000", + "private" : "0840a8af5bc4c48da8850e973d7e14220f45c192cea4020d377eecd25c7c3643", + "shared" : "77557137a2a2a651c49627a9b239ac1f2bf78b8a3e72168ccecc10a51fc5ae66", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 121, + "comment" : "special case public key", + "public" : "1400000000000000000000000000000000000000000000000000000000000000", + "private" : "0092229c753a71284d0853909470ad847ab62f439ea51482fb41d30cc3b44743", + "shared" : "c88e719ae5c2248b5f90da346a92ae214f44a5d129fd4e9c26cf6a0da1efe077", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 122, + "comment" : "special case public key", + "public" : "0000000000000000000000000080000000000000000000000000000000000000", + "private" : "b8da2bd2d7cf25a3e54e5f87ee15911effb9ff86baec4076d56c8e953670bf5b", + "shared" : "4bf6789c7ea036f973cde0af02d6fdb9b64a0b957022111439570fad7d7a453f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 123, + "comment" : "special case public key", + "public" : "ffffffffffffffffffffffffffff000000000000000000000000000000000000", + "private" : "684cd420af41abb3d10c61e773238cf729c2155f941ac27e15f4c37f49b29576", + "shared" : "bcac235ae15cc7148372e11f9315e3bc76ceb904b3d2a8246bd9d9be2082bb62", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 124, + "comment" : "special case public key", + "public" : "0100000000000000000000000000010000000000000000000000000000000000", + "private" : "38cfacaa4460796b4de434bdd6739f0d043671f97fa829517511e6b47aa93474", + "shared" : "5dd7d16fff25cc5fdf9e03c3157cb0a235cea17d618f36e6f13461567edeb943", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 125, + "comment" : "special case public key", + "public" : "0000000000000000000000000000000000000000000000000000004000000000", + "private" : "30832e8cb627ac195f77b1105258e4bb18b99a5ed944404bfacb3a039fbdb14b", + "shared" : "2816fd031d51d6750f9225ede950625cca47441ca97e43092650396991afcb6d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 126, + "comment" : "special case public key", + "public" : "0000000000000000000000000000000000000000000000000000008000000000", + "private" : "d818fd6971e546447f361d33d3dbb3eadcf02fb28f246f1d5107b9073a93cd4f", + "shared" : "7ed8f2d5424e7ebb3edbdf4abe455447e5a48b658e64abd06c218f33bd151f64", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 127, + "comment" : "special case public key", + "public" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000", + "private" : "1021cd8682bdc3f5da9100adff5b2230b3acd836b3a455db8352a2c27e69d17e", + "shared" : "e8620ed5ca89c72c5ea5503e6dcd01131cd5e875c30e13d5dc619ce28ec7d559", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 128, + "comment" : "special case public key", + "public" : "0100000000000000000000000000000000000000000000000000000001000000", + "private" : "20e4c9247102292655d6765d7d84c6fce5309b8004045daea6d7d7dcad462871", + "shared" : "ceadb264379dcadd6e3bb8ad24dd653d2a609dd703d41da6caf3ad00f001862c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 129, + "comment" : "special case public key", + "public" : "a8b9c7372118a53a9de9eaf0868e3b1a3d88e81cb2e407ff7125e9f5c5088715", + "private" : "90b150d462de512056d5bd55173074969b496f262fb6916b733f6263a8078971", + "shared" : "f86cc7bf1be49574fc97a074282e9bb5cd238e002bc8e9a7b8552b2d60eccb52", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 130, + "comment" : "special case public key", + "public" : "aab9c7372118a53a9de9eaf0868e3b1a3d88e81cb2e407ff7125e9f5c5088715", + "private" : "9887286b3261c8d857a16f6db21277f75d88d4e861b3ebe7596699047e816668", + "shared" : "ccbb8fd9dee165a398b2dbd7c8396f81736c1b3da36b35fbec8f326f38f92767", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 131, + "comment" : "special case public key", + "public" : "585007a5930d77623cf29756038ca197d3ebfd9e4c80a69585efe0274092c115", + "private" : "20ca2c85cc8762e96b7047bf15c71c050ffe0ed1616040a953ae32a1297ad871", + "shared" : "46add6f48ffff461777d4f89b6fdf1155aa051a96387d45f3e5e371a236b6e52", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 132, + "comment" : "special case public key", + "public" : "fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f", + "private" : "d027656605b10bf18dea28bc52546f9f1f08cef06cafd200fc84f87dbb4ebe46", + "shared" : "1adbe32207e21f71e1af53884d2a2276481e298e557f4dacb3720f2458e3082d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 133, + "comment" : "special case public key", + "public" : "0000000000000000000000000000000000000000000000000000000000000020", + "private" : "4867a83ee9d01b7510840867db1af6a6049bdbb056b74443f70c358e162c8867", + "shared" : "e12cc58fbeb70a5e35c861c33710be6516a6a92e52376060211b2487db542b4f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 134, + "comment" : "special case public key", + "public" : "afa00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b", + "private" : "a015970a8add940fca5b1b5d23875397d547d8d494fcb314f2045a67a2d12c4b", + "shared" : "421bed1b26da1e9adbeada1f32b91a0fb4ced0f1110e0a4a88e735a19ee4571e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 135, + "comment" : "special case public key", + "public" : "b1a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b", + "private" : "4058cb6b9aaba02a338aaa392dbc10039e26e9e444117e758e24c5d8b232ea5e", + "shared" : "d7b47463e2f4ca9a1a7deea098da8e74ac3b4a109083d997259b12992e7e7e06", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 136, + "comment" : "special case public key", + "public" : "fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2f", + "private" : "b876b05daff0530b139d9e11250563418077178246c5fa7005ba00e9b6647763", + "shared" : "686eb910a937211b9147c8a051a1197906818fdc626668eb5f5d394afd86d41b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 137, + "comment" : "special case public key", + "public" : "22231c64ef73ad62318b8a87bc38e272e1bb8bf1a60d7c00476d0b059d7b3c35", + "private" : "d87fd6aa5d8deef6dee9619a56846a0829620590f2da40835d8e251597e39078", + "shared" : "09559733b35bcc6bb8ac574b5abe3a4d8841deff051c294a07487e3eec3c5558", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 138, + "comment" : "special case public key", + "public" : "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "private" : "90036321b63751f7622aa93da34d85e59ce81009ac5b9a068921d83bc4715b57", + "shared" : "f7d5cbcf39eb722b01ed20c85563ebb81d076511aead4ccc429027866b9fd270", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 139, + "comment" : "special case public key", + "public" : "f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "private" : "a06781fd4c4a0874e00e72ba131b9dd87a83b2904e294de176e8a9af1f695d67", + "shared" : "e995ad6a1ec6c5ab32922cff9d204721704673143c4a11deaa203f3c81989b3f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 140, + "comment" : "special case public key", + "public" : "feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "private" : "b822d72d8b68bdb4fbf67e56a61d672b2c7747e94479fe5ae4072d0accdd6571", + "shared" : "32b6dabe01d13867f3b5b0892fefd80dca666f2edc5afb43cd0baf703c3e6926", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 141, + "comment" : "special case public key", + "public" : "0000000000000000000000000000000000000000000000000000000000000040", + "private" : "d08ce1237e248d02cdf619d20bea5848ade4f6ffd171b8dee8793fc67c459640", + "shared" : "a93d83fc9ea0f6cb0cc8b631da600019b76cbb2ec57222f2e42dd540e3da850b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 142, + "comment" : "special case public key", + "public" : "cbdce39b108c529dce74757843c71d8d1e44740e59f283ffb892f4fa6284c34a", + "private" : "180ae3c928514cfb9edd06e7dc1d5d066160e967445a5c58e4463b69ed205e6d", + "shared" : "017cbfa2b38e9ef3297a339ecce1a917bdcf7e910036086a41d1e22d04241870", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 143, + "comment" : "special case public key", + "public" : "3c5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54", + "private" : "e881d806a110560cd8fee899d59c0249f1233a4322c41aa369c7a2a99f5b5962", + "shared" : "71133905b8a57ea8c38de0ecf213699a75b096c2df21f07f7e9eb03e9fa53f5c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 144, + "comment" : "special case public key", + "public" : "3e5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54", + "private" : "08e410e1d7e8b9411236af4a35d6b62a5d8931478e4c62197cfafb491467b162", + "shared" : "3dc7b70e110766b2bf525252ebed98a100b2e532dc69544464da1bbab8625f6d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 145, + "comment" : "special case public key", + "public" : "f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", + "private" : "e02fdf7e0ee3d55b4440f01432dd253c949793bc04da44ddece83e54c8c39b40", + "shared" : "e317e5cc438b5f79ead5533ac7c45519a117b31033cc2140b19edf8572011240", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 146, + "comment" : "special case public key", + "public" : "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", + "private" : "f05d18f68ef7a5865c14db3a9c255fdf2dabea2aa36581e94f68b727b582867b", + "shared" : "d86810516aeddc18061036f599a9eb84d1c6146b0f543652dd4526743ba42c04", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 147, + "comment" : "special case public key", + "public" : "95aff85a6cf2889dc30d68a9fc735e682c140261b37f596a7a101fd8bf6d3e6a", + "private" : "00c103578d5c079d7bcc22c1c31e787c1b15c57fcb493fdafefa20371cfc746b", + "shared" : "dfa988a477003be125b95ccbf2223d97729577d25e1d6e89e3da0afabdd0ae71", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 148, + "comment" : "special case public key", + "public" : "434638c8dee75ac56216150f7971c4e5c27717e34d1bf8008eda160a3af7786a", + "private" : "7005bb927485c435642b424a3dde014bcf76345e5be64ae6e9b24db39e1cdb51", + "shared" : "d450af45b8ed5fe140cc5263ffb7b52e66736899a8b872b6e28552129819b25b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 149, + "comment" : "special case public key", + "public" : "454638c8dee75ac56216150f7971c4e5c27717e34d1bf8008eda160a3af7786a", + "private" : "0822039a5dc13c40fcccf346e2a7769b4fd272052d43260ad626468a50d44162", + "shared" : "58002c89bf8bc32ae6fc205b796acd13ef7f8476f6492ae4b2be47f1095e8a4f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 150, + "comment" : "special case public key", + "public" : "ecfffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f", + "private" : "40a6349c03f0dc0a42358f6353ca67632af687b14c9dff626c54e211e8fc355a", + "shared" : "7773aad6e72eb1735b65ad51f7dad258c11d7bfff53094424cb103cd6bfb4368", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 151, + "comment" : "special case public key", + "public" : "eefffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f", + "private" : "50696d4d05209971d6ba0676ea274262ba639aac74fa75e5df4570768ad8ae74", + "shared" : "c118ddf6462fbea80f14ef1f2972a1ab12cafa511d1323d4d22d0d426d651b5b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 152, + "comment" : "special case public key", + "public" : "edffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffff7f", + "private" : "68bb680c853f4e4daa47c586dc886cf4568d7b0383770f6df439a53be4a3236d", + "shared" : "cc0775bfd970a2706b11c7222a4436a3d17160382c83b76f89b66192c81b4408", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 153, + "comment" : "special case public key", + "public" : "ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "b0f6c28dbdc647068a76d71805ef770f087cf76b82afdc0d26c45b71ace49768", + "shared" : "f0097fa0ba70d019126277ab15c56ecc170ca88180b2bf9d80fcda3d7d74552a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 154, + "comment" : "special case public key", + "public" : "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "private" : "18630f93598637c35da623a74559cf944374a559114c7937811041fc8605564a", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "Twist", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 155, + "comment" : "special case for E in multiplication by 2", + "public" : "0000000000000000000008000000000000000000000000000000000000000000", + "private" : "581ecbda5a4a228044fefd6e03df234558c3c79152c6e2c5e60b142c4f26a851", + "shared" : "59e7b1e6f47065a48bd34913d910176b6792a1372aad22e73cd7df45fcf91a0e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 156, + "comment" : "special case for E in multiplication by 2", + "public" : "77af0d3897a715dfe25df5d538cf133bc9ab7ad52df6bd922a2fb75621d59901", + "private" : "b0561a38000795b7cb537b55e975ea452c2118506295d5eb15fd9c83b67f7a50", + "shared" : "179f6b020748acba349133eaa4518f1bd8bab7bfc4fb05fd4c24e7553da1e960", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 157, + "comment" : "special case for E in multiplication by 2", + "public" : "4e39866127b6a12a54914e106aab86464af55631f3cb61766d5999aa8d2e070e", + "private" : "b00f7df2d47128441c7270b9a87eee45b6056fc64236a57bdf81dbcccf5f5d42", + "shared" : "43c5ee1451f213ef7624729e595a0fee7c9af7ee5d27eb03278ee9f94c202352", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 158, + "comment" : "special case for E in multiplication by 2", + "public" : "adc6799ed8495ed5ab6eb1ef955479b9b50aa9ce0c349e8992a6665572d1f811", + "private" : "c8f7a0c0bfb1e9c72576c534f86854fbe4af521d4fa807f67e2440e100ec8852", + "shared" : "2f350bcf0b40784d1d756c9ca3e38ec9dd68ba80faf1f9847de50779c0d4902a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 159, + "comment" : "special case for E in multiplication by 2", + "public" : "770f4218ef234f5e185466e32442c302bbec21bbb6cd28c979e783fe5013333f", + "private" : "58181f581aa37022ff71c56c6e68e6175d967c5c995a249885f66565074ded4d", + "shared" : "d5d650dc621072eca952e4344efc7320b2b1459aba48f5e2480db881c50cc650", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 160, + "comment" : "special case for E in multiplication by 2", + "public" : "5c6118c4c74cfb842d9a87449f9d8db8b992d46c5a9093ce2fcb7a49b535c451", + "private" : "301c935cae4357070b0adaf9cd6192830b2c989c153729eed99f589eb45f884b", + "shared" : "909cc57275d54f20c67b45f9af9484fd67581afb7d887bee1db5461f303ef257", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 161, + "comment" : "special case for E in multiplication by 2", + "public" : "4039866127b6a12a54914e106aab86464af55631f3cb61766d5999aa8d2e076e", + "private" : "d002292d4359a3d42bc8767f1380009332e7a0df2f3379011ab78f789f6baa54", + "shared" : "4a7e2c5caf1d8180eb1c4f22692f29a14b4cdc9b193bd1d16e2f27438eef1448", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 162, + "comment" : "special case for E in multiplication by 2", + "public" : "078fa523498fb51cba1112d83b20af448b8009d8eea14368564d01b8f9b6086f", + "private" : "d0c2c49e644ab738270707ff9917065942687e2f12886d961161db46c05b565f", + "shared" : "c0ee59d3685fc2c3c803608b5ee39a7f8da30b48e4293ae011f0ea1e5aeb7173", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 163, + "comment" : "special case for E in multiplication by 2", + "public" : "9fc6799ed8495ed5ab6eb1ef955479b9b50aa9ce0c349e8992a6665572d1f871", + "private" : "f087d38b274c1dad1bce6eaa36b48e2190b90b9bf8ca59669cc5e00464534342", + "shared" : "b252bc8eabfaa68c56e54d61b99061a35d11e3a7b9bda417d90f69b1119bcf45", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 164, + "comment" : "special case for E in multiplication by 2", + "public" : "7650f2c76858ea201da2022ac730ecc43654852ad209426dd5d048a9de2a667e", + "private" : "48dbcc5a695f1514bbbaa6ad00842b69d9ae5216b1963add07fb2947c97b8447", + "shared" : "fbda33bc930c08df837208e19afdc1cfe3fd0f8f0e3976be34775e58a4a7771f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 165, + "comment" : "D = 0 in multiplication by 2", + "public" : "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", + "private" : "5891c9272cf9a197735b701e5715268d36d7436b7e351a3e997a0862e4807d4d", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 166, + "comment" : "D = 0 in multiplication by 2", + "public" : "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", + "private" : "c0f9c60aea73731d92ab5ed9f4cea122f9a6eb2577bda72f94948fea4d4cc65d", + "shared" : "0000000000000000000000000000000000000000000000000000000000000000", + "result" : "acceptable", + "flags" : [ + "LowOrderPublic", + "ZeroSharedSecret" + ] + }, + { + "tcId" : 167, + "comment" : "special case for DA - CB in multiplication by 2", + "public" : "b0224e7134cf92d40a31515f2f0e89c2a2777e8ac2fe741db0dc39399fdf2702", + "private" : "0066dd7674fe51f9326c1e239b875f8ac0701aae69a804c25fe43595e8660b45", + "shared" : "8dacfe7beaaa62b94bf6e50ee5214d99ad7cda5a431ea0c62f2b20a89d73c62e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 168, + "comment" : "special case for DA - CB in multiplication by 2", + "public" : "601e3febb848ec3e57fce64588aad82afc9c2af99bbcdffcc4cd58d4b3d15c07", + "private" : "80067f30f40d61318b420c859fce128c9017ab81b47b76028a57bc30d5856846", + "shared" : "20f1d3fe90e08bc6f152bf5dacc3ed35899785333f1470e6a62c3b8cbe28d260", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 169, + "comment" : "special case for DA - CB in multiplication by 2", + "public" : "82a3807bbdec2fa9938fb4141e27dc57456606301f78ff7133cf24f3d13ee117", + "private" : "584577669d21ce0ae3e30b02c9783ffe97709cbfe396889aa31e8ee43352dc52", + "shared" : "2b28cc5140b816add5ad3a77a81b1c073d67bf51bf95bda2064a14eb12d5f766", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 170, + "comment" : "special case for DA - CB in multiplication by 2", + "public" : "f329ab2376462e5f3128a2682086253c19222ac1e2bca45692f0c3b528f4c428", + "private" : "18e597a4e2ccdb5e8052d57c9009938c2d4c43d6d8c9f93c98727b7311035953", + "shared" : "8392160083b9af9e0ef44fcfce53ba8ff7282ee7a6c71ab66f8843a55d09cd68", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 171, + "comment" : "special case for DA in multiplication by 2", + "public" : "4fce3bb6c8aaf022dbd100e3cde3941b37d543f00401dba7da9bc143dfc55709", + "private" : "88281cc51d5512d8814ea5249b879dcbad0323d38512dafbdc7ba85bba8c8d5d", + "shared" : "42184e22c535530c457bd3b4f1084cbf5e297f502fe136b8d1daecf5334cc96c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 172, + "comment" : "special case for DA in multiplication by 2", + "public" : "15c68851c1db844b5a1ef3456a659f188854b1a75fbdb2f68f514c9289ce711f", + "private" : "d0e795450df0a813c6573496ec5793ca02e1bdbad10ed08df83fdaed68b3385f", + "shared" : "f654d78e5945b24bc63e3e6d790e0ae986e53937764068b1bce920e1d79b756f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 173, + "comment" : "special case for DA in multiplication by 2", + "public" : "4200a242434337b8914f49345301ed782b13594f9ede089c41fb1e7ea82c9053", + "private" : "30b69a1cc1eb2d0b83ea213846e90a2c922088bdf294a6995bf6e6e77c646c41", + "shared" : "cd8a09b04795edcc7061867373981aa748651ebdce5ec218a335b878cefe4872", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 174, + "comment" : "special case for DA in multiplication by 2", + "public" : "baabf0174aaaea4de48cc83adfb0401461a741903ea6fb130d7d64b7bf03a966", + "private" : "78b30bb63cd8ade71b7a77d426f4419d05f199ffef349e89faa9d9a5f21f6654", + "shared" : "c9f8258f237db1c80702c5c4d9048dfba9dfe259da4aeee90dc2945526961275", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 175, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "f12f18bd59c126348f6a7a9f4a5fdd9fcaf581345073a851fba098e5d64b4a0c", + "private" : "c0b386f4ef0d4698686404977e7b60cb6c1f8b6012a22e29d6224c5947439041", + "shared" : "6600cbe900616a770a126b8b19156d5e27e1174bd538d0944eb3c0be4899c758", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 176, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "bee386527b772490aeb96fc4d23b9304037cb4430f64b228f3d8b3b498319f22", + "private" : "9886602e719bacafea092bb75b51ae7258abe1a364c176857f3dc188c03e6759", + "shared" : "3fe710d6344ff0cb342e52349e1c5b57b7a271f2a133bb5249bbe40dc86e1b40", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 177, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "cf911ac91b0d944049cec66ae5ef0c4549d1e612e107c68e87263a2fbcf8323f", + "private" : "b83960f5d0613cdaac6dda690351666e9f277bba6bd406b0e27a1886bb2d3e46", + "shared" : "71373ebe67f39a2c230027c7db4b3b74bab80ed212b232679785ee10f47c304e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 178, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "1e6ee536e4f26bbfb63139951a10f3bab62e19ed1ef8397178d9c5d04307cd40", + "private" : "d03b75f09ac807dfd2ee352c04a1f25984720f785ffaa0af88bc5db6ff9c3453", + "shared" : "238eef43c589822e1d3de41c1cc46dcfec7a93febf37c8546b6625e1a123815d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 179, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "2f1c79ad8488db6f5146903b2dc46cfbfc834bbcf09b4dd70c274c4b67ce605d", + "private" : "d036948c0ec223f0ee577e390dbf87222358ed199f2823345ad154bbc4cbcc47", + "shared" : "87a79c9c231d3b9526b49bf3d683bf38c3c319af7c7c5d1456487398da535010", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 180, + "comment" : "special case for x_2 in multiplication by 2", + "public" : "fccfe742a63ed9cb70958560b5a02260350a7ecbaf8c57ae045f671a29b4b573", + "private" : "d054ded613febf2950ac5c927fcb120c387de0ba61b331cd33024c8b6e737048", + "shared" : "d683ca6194452d878c12d7da35f22833f99728bba89931a51274f61210336a5f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 181, + "comment" : "special case for AA in multiplication by 2", + "public" : "cb3d4a90f86b3011da3369d9988597c7fff1499273b4a04f84d0e26ed1683c0d", + "private" : "e82c480631fb153ba2211fe603032b3e71b162dbd3c11bec03208ffcd510655f", + "shared" : "dbf6203516635840cf69a02db87cf0d95dae315da7fc1ec7ce2b29e1f2db6666", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 182, + "comment" : "special case for AA in multiplication by 2", + "public" : "101e13f7bc0570fa2638caa20a67c6e0c21dab132f4b456191590264c493d018", + "private" : "c0c01d28c1cab01f59700aca5f18d2697658b37fdd54a339ff391c0a1a1b1645", + "shared" : "1fe314744390d525278b1f5fbf108101b8ded587081375ed4ac4ac690d92414f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 183, + "comment" : "special case for AA in multiplication by 2", + "public" : "dce1ec0843fa8f05d9c7355df598391f3de254ecd0b4ba9e6ea6fd9b3b6c2f67", + "private" : "c82bde72df36479688c485a8bf442f4a34412e429c02db97704f03daf4dfd542", + "shared" : "ad454395ee392be677be7b9cb914038d57d2d87ec56cc98678dd84f19920912b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 184, + "comment" : "special case for AA in multiplication by 2", + "public" : "21c2b56f0794cfee25cc9626677a6838000eb66d8c4b5fb07b2f1d912e97c372", + "private" : "503f697617fb02a7b8ef00ba34e7fc8ce93f9ec3e1cbfe4bf2c05bcee0cb9757", + "shared" : "c6d6499255133398f9dd7f32525db977a538118800bfaf3aad8bcd26f02c3863", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 185, + "comment" : "special case for BB in multiplication by 2", + "public" : "cc3d4a90f86b3011da3369d9988597c7fff1499273b4a04f84d0e26ed1683c0d", + "private" : "58cd4ca1e4331188de2b2889419ce20ec5ef88a0e93af092099065551b904e41", + "shared" : "0d74214da1344b111d59dfad3713eb56effe7c560c59cbbb99ec313962dbba58", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 186, + "comment" : "special case for BB in multiplication by 2", + "public" : "111e13f7bc0570fa2638caa20a67c6e0c21dab132f4b456191590264c493d018", + "private" : "004ea3448b84ca509efec5fcc24c63ee984def63b29deb9037894709709c0957", + "shared" : "7b9dbf8d6c6d65898b518167bf4011d54ddc265d953c0743d7868e22d9909e67", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 187, + "comment" : "special case for BB in multiplication by 2", + "public" : "dde1ec0843fa8f05d9c7355df598391f3de254ecd0b4ba9e6ea6fd9b3b6c2f67", + "private" : "c8a6eb00a4d74bbdff239522c3c891ed7ce1904be2a329cd0ae0061a253c9542", + "shared" : "fb0e0209c5b9d51b401183d7e56a59081d37a62ab1e05753a0667eebd377fd39", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 188, + "comment" : "special case for BB in multiplication by 2", + "public" : "22c2b56f0794cfee25cc9626677a6838000eb66d8c4b5fb07b2f1d912e97c372", + "private" : "50322ff0d0dcdd6b14f307c04dfecefe5b7cdeaf92bffb919e9d62ed27079040", + "shared" : "dbe7a1fe3b337c9720123e6fcc02cf96953a17dc9b395a2206cb1bf91d41756e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 189, + "comment" : "special case for D in multiplication by 2", + "public" : "e58baccede32bcf33b3b6e3d69c02af8284a9631de74b6af3f046a9369df040f", + "private" : "e0328c7d188d98faf2ac72d728b7d14f2bbbd7a94d0fbd8e8f79abe0b1fe1055", + "shared" : "97bd42093e0d48f973f059dd7ab9f97d13d5b0d5eedffdf6da3c3c432872c549", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 190, + "comment" : "special case for D in multiplication by 2", + "public" : "c6d5c693fc0a4e2df6b290026860566a166b6d7aebe3c98828d492745c8df936", + "private" : "5017679a17bd23adf95ad47e310fc6526f4ba9ca3b0839b53bd0d92839eb5b4f", + "shared" : "99bcbc7b9aa5e25580f92bf589e95dae874b83e420225d8a93e18e96dac00b63", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 191, + "comment" : "special case for D in multiplication by 2", + "public" : "d15f4bf2ef5c7bda4ee95196f3c0df710df5d3d206360fc3174ea75c3aa3a743", + "private" : "2864aaf61c146df06cc256b065f66b34985cc015da5b1d647a6ed4e2c76bfc43", + "shared" : "afa2adb52a670aa9c3ec3020d5fda285474ede5c4f4c30e9238b884a77969443", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 192, + "comment" : "special case for D in multiplication by 2", + "public" : "6dffb0a25888bf23cf1ac701bfbdede8a18e323b9d4d3d31e516a05fce7ce872", + "private" : "184a6cfbabcbd1507a2ea41f52796583dbdb851b88a85781ee8e3c28782c3349", + "shared" : "e6a2fc8ed93ce3530178fef94bb0056f43118e5be3a6eabee7d2ed384a73800c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 193, + "comment" : "special case for D in multiplication by 2", + "public" : "21f86d123c923a92aaf2563df94b5b5c93874f5b7ab9954aaa53e3d72f0ff67e", + "private" : "c85f954b85bc102aca799671793452176538d077862ee45e0b253619767dff42", + "shared" : "7fc28781631410c5a6f25c9cfd91ec0a848adb7a9eb40bc5b495d0f4753f2260", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 194, + "comment" : "special case for D in multiplication by 2", + "public" : "587c347c8cb249564ab77383de358cc2a19fe7370a8476d43091123598941c7f", + "private" : "50e3e5a9a19be2ee3548b0964672fb5e3134cb0d2f7adf000e4556d0ffa37643", + "shared" : "314d8a2b5c76cc7ee1217df2283b7e6724436e273aeb80628dce0600ab478a63", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 195, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "f5c6311a1dd1b9e0f8cfd034ac6d01bf28d9d0f962a1934ae2cb97cb173dd810", + "private" : "08ece580bb6ddf96559b81d7a97dd4531def6cc78d448a70cebabdd26caab146", + "shared" : "2bfd8e5308c34498eb2b4daf9ed51cf623da3beaeb0efd3d687f2b8becbf3101", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 196, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "9316c06d27b24abc673ffb5105c5b9a89bdfaa79e81cdbb89556074377c70320", + "private" : "a886033e9dc2b6a913fffbc2bd402e8c11ec34d49c0dc0fa1429329b694a285f", + "shared" : "d53c3d6f538c126b9336785d1d4e6935dc8b21f3d7e9c25bc240a03e39023363", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 197, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "8a4179807b07649e04f711bf9473a79993f84293e4a8b9afee44a22ef1000b21", + "private" : "98b1cc2020a8ec575d5c46c76024cf7c7ad7628eb909730bc4f460aaf0e6da4b", + "shared" : "4531881ad9cf011693ddf02842fbdab86d71e27680e9b4b3f93b4cf15e737e50", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 198, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "a773277ae1029f854749137b0f3a02b5b3560b9c4ca4dbdeb3125ec896b81841", + "private" : "c8e193de162aa349a3432c7a0c0521d92cbc5e3bf82615e42955dd67ec12345f", + "shared" : "7ba4d3de697aa11addf3911e93c94b7e943beff3e3b1b56b7de4461f9e48be6b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 199, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "1eceb2b3763231bc3c99dc62266a09ab5d3661c756524cddc5aabcedee92da61", + "private" : "88e01237b336014075676082afbde51d595d47e1fa5214b51a351abbf6491442", + "shared" : "bcf0884052f912a63bbab8c5c674b91c4989ae051fa07fcf30cb5317fb1f2e72", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 200, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "9a2acbb3b5a386a6102e3728be3a97de03981d5c71fd2d954604bee3d3d0ce62", + "private" : "e82313e451a198dce4ae95c6832a8281d847fc87b28db00fe43757c16cc49c4a", + "shared" : "e5772a92b103ee696a999705cf07110c460f0545682db3fac5d875d69648bc68", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 201, + "comment" : "special case for DA + CB in multiplication by 2", + "public" : "27430e1c2d3089708bca56d7a5ad03792828d47685b6131e023dd0808716b863", + "private" : "2828594d16768e586df39601ecc86d3fad6389d872b53fca3edcaf6fb958f653", + "shared" : "378c29e3be97a21b9f81afca0d0f5c242fd4f896114f77a77155d06ce5fbfa5e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 202, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "4ef367901aac8ba90a50e0cf86ca4e4a3ff164fb121605be346e2e48d04ac912", + "private" : "a84f488e193139f986b0e5b249635b137d385e420342aef1f194fcde1fe5e850", + "shared" : "7eb48a60b14fb9ea5728f6410aef627d1522fad481b934af64e2c483b64d585f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 203, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "d1de303c4ddd05d57c29df92ad172dd8c8f424e63ec93445beaea44f9d124b17", + "private" : "30fd2a781e095c34a483907b3dd2d8bd2736e279617bfa6b8b4e0e1cf90fbd46", + "shared" : "b71bdbed78023a06deed1c182e14c98f7cf46bc627a4a2c102ad23c41cf32454", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 204, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "5bccd739fd7517d9344bf6b2b0f19a1e0c38d9349a25ad1f94af4a2cdcf5e837", + "private" : "28312e17b47dd32d90561168245187963c7469a31c881e4a5c94384262b71959", + "shared" : "5bb56877caf2cdac98611b60367fbb74265984614e5e73996e8ea1bd6f749f1a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 205, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "8a7a939310df7ea768454df51bcd0dfbd7be4fcbb2ffc98429d913ec6911f337", + "private" : "a87640cf8237b473c638b3e9df08644e8607e563b5964363ccc42133b2996742", + "shared" : "b568ed46d04f6291f8c176dca8aff6d221de4c9cce4b404d5401fbe70a324501", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 206, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "fe3590fc382da7a82e28d07fafe40d4afc91183a4536e3e6b550fee84a4b7b4b", + "private" : "780c5b882720d85e5ddfaf1033e9a1385df9e21689eeda4dcc7444ad28330a50", + "shared" : "11fb44e810bce8536a957eaa56e02d04dd866700298f13b04ebeb48e20d93647", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 207, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "fad9ab3e803b49fc81b27ee69db6fc9fdb82e35453b59ef8fab2a3beb5e1134c", + "private" : "209e5e0ae1994bd859ce8992b62ec3a66df2eb50232bcc3a3d27b6614f6b014d", + "shared" : "85d9db8f182bc68db67de3471f786b45b1619aec0f32b108ace30ee7b2624305", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 208, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "98bed955f1516c7a442751ac590046d7d52ca64f76df82be09d32e5d33b49073", + "private" : "806d1dee5ff6aea84a848916991a89ef3625583e1bd4ae0b3dd25c2524a4ff46", + "shared" : "61d4ef71cbe7be3128be829ab26ed3463eb4ab25937c309788e876b23412aa7c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 209, + "comment" : "special case for z_2 in multiplication by 2", + "public" : "e59be4917b3f05b6fc8748c9b90f1b910273c9c6e17ff96ef415ff3d927d987e", + "private" : "00f98b02ae0df5274cc899f526eb1b877289e0963440a57dd97e414cdd2f7c51", + "shared" : "5ba4394ed1a664811b01557944becf7585652a8acbdbf806742911207bd79346", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 210, + "comment" : "special case for A in multiplication by 2", + "public" : "8c9885a26cb334054700a270f7a5f4aac06bad8263b651ebf0712eca1ebb6416", + "private" : "d86c18f2be396b3bb72f22e6ece22e273af6e1506a1c09ad4d01bdd2f439f843", + "shared" : "a5952588613eb7a5cd49dd526f1f20a4f0ffe9423e82cea302c2dd90ce559955", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 211, + "comment" : "special case for A in multiplication by 2", + "public" : "f6135fe9741c2c9de7dcf7627ef08832f351cb325dbb3a26f93a2b48620e1727", + "private" : "f81aadb9053eb698996d0f781d9cda67f82ddefa3987d276ff5a94ffdf5d255f", + "shared" : "cb6fb623084b6197443ec9ba1050c0923332e5e829ae0194269cfaf920a43601", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 212, + "comment" : "special case for A in multiplication by 2", + "public" : "f6ffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffff3f", + "private" : "305b4db4321b4923fc559bf91df677d0e12c3a31b16ec655cb708b759d7c114d", + "shared" : "9e526079c2fcf12426ae6c2a54b5ffb70f2ec662e29ea5ce0c8385c3b21cd162", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 213, + "comment" : "special case for A in multiplication by 2", + "public" : "f6ffffffffffffffffffffffffffff3f00000000000000000000000000000040", + "private" : "900638d1979802db9b52e4dd84fa19579f61cd7bef3c0b62fcccaeaa15fa484d", + "shared" : "6329c7dc2318ec36153ef4f6f91bc6e7d1e008f5293065d9586ab88abb58f241", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 214, + "comment" : "special case for A in multiplication by 2", + "public" : "f6eba0168be3d3621823089d810f77cd0cae34cda244c5d906c5d4b79df1e858", + "private" : "38575cf7c8691ecc79cd5f8d7d4703aa48592ff6e7f64731c2d98a19aeae514f", + "shared" : "603f4fc410081f880944e0e13d56fc542a430eec813fad302b7c5ac380576f1c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 215, + "comment" : "special case for A in multiplication by 2", + "public" : "60677a5d934ccbfab8ff5d8f085a0b553f94527d9c49ae140f8ed135e1449b69", + "private" : "e88bd02c7016547a24f428bc2a9dcccad6c6f880c17bffcf66fc68459627af4e", + "shared" : "834bbad5470e1498c4b0148782dfe630e8bfadff1997de802ac8ce302a1bda28", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 216, + "comment" : "special case for B in multiplication by 2", + "public" : "8d9885a26cb334054700a270f7a5f4aac06bad8263b651ebf0712eca1ebb6416", + "private" : "9036ed7d68f7448ac440dc51216b49840dcabd3d5e32e3b4ffc32a5fe9e96742", + "shared" : "ec9070ad3491a5ff50d7d0db6c9c844783dde1c6fbd4fe163e9ade1ce9cd041d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 217, + "comment" : "special case for B in multiplication by 2", + "public" : "f7135fe9741c2c9de7dcf7627ef08832f351cb325dbb3a26f93a2b48620e1727", + "private" : "90c55e77aa0fe4afb1287109fd010f526364dea18d88e2fd870ac01b66e3fa4e", + "shared" : "dc6d05b92edcdb5dc334b1fc3dff58fe5b24a5c5f0b2d4311555d0fc945d7759", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 218, + "comment" : "special case for B in multiplication by 2", + "public" : "f7ffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffff3f", + "private" : "a021ba2fd4e3ad57bcbf204d6f6c3e8018d8978552633b6dff1b7447bf529459", + "shared" : "1b174b189981d81bc6887932083e8488df8bbbed57f9214c9cfa59d59b572359", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 219, + "comment" : "special case for B in multiplication by 2", + "public" : "f7ffffffffffffffffffffffffffff3f00000000000000000000000000000040", + "private" : "3035083e984837587f6b7346af871bf3fc9581c50eb55c83aefabeed68cee349", + "shared" : "15a052148abaad1b0f2e7481a34edb61403589439b5bd5e5646cecebe2a1be2b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 220, + "comment" : "special case for B in multiplication by 2", + "public" : "f7eba0168be3d3621823089d810f77cd0cae34cda244c5d906c5d4b79df1e858", + "private" : "30435ce187f2723f9a3bdea0eef892207e152e4cee8985fa72d2db4147bd2a53", + "shared" : "1d048cbe2f8df07c233a8f93706f307d17130c2497fb752eeaa31fe3edfc725a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 221, + "comment" : "special case for B in multiplication by 2", + "public" : "61677a5d934ccbfab8ff5d8f085a0b553f94527d9c49ae140f8ed135e1449b69", + "private" : "580f0a9bba7281a30fb033490e0f429f22e3f267852caeacefa3e5291f0e614e", + "shared" : "cb92a98b6aa99ac9e3c5750cea6f0846b0181faa5992845b798923d419e82756", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 222, + "comment" : "special case for C in multiplication by 2", + "public" : "c8239b710136fe431fb4d98436157e47c9e78a10f09ff92e98baff159926061c", + "private" : "709098feb2e25c67b4bfd3be0a01af409adb6da52b3fbe3d970642dd2c983856", + "shared" : "f1bd12d9d32c6f4c5b2dcb3a5c52d9fd454d52ca704c2c137956ec8ad9aef107", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 223, + "comment" : "special case for C in multiplication by 2", + "public" : "b7a2f79e0de9b58147691b5546d9ec463da8325e1440e58bb20aa129d1b97327", + "private" : "185ac62e729f88528950926c0de7c481c924bf9cf26a122f443b861e8b6af640", + "shared" : "e6f1c494c9e4bd2325c17183e82d31ab0bbee6c847d4b0e4a99c7c6891117c3f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 224, + "comment" : "special case for C in multiplication by 2", + "public" : "2dc624e1663f42a7b9336350f277541b50b8ddc7ee0d86133ad53273aed4e62e", + "private" : "f03743eead7c2f7719794324f271072817d1a04cbda42b232f3bee43f397cc40", + "shared" : "aa2a12edf752d279bdb000fb1405a5df8c5f1d41309b4f2bd41aed7ac1ed0149", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 225, + "comment" : "special case for C in multiplication by 2", + "public" : "0e5eceee9104a64f82c9093b9bf7b4076ee5bc70815af7ee9f942ef015756176", + "private" : "a8fbb4f90da45794981405d59ef310621e3c3b6b7760b5e30308c7822c88ae5f", + "shared" : "74d5606ba0b6ad1d8ba36ae6f264d6315f479b3984de573e9b001e0555247c32", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 226, + "comment" : "special case for CB in multiplication by 2", + "public" : "737d45477e2beb77a6c38b98e2a19b05c395df7da998cb91f6dfab5819614f27", + "private" : "c887886fd07107c7221f6d9dd36c305ec779ceca132ac933ff77dab2beac6345", + "shared" : "8cf4538ae5f445cc6d273df4ad300a45d7bb2f6e373a562440f1b37773904e32", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 227, + "comment" : "special case for CB in multiplication by 2", + "public" : "873f8b260ea9d9ddac08b7b030727bf0072315ab54075ecc393a37a975882b7e", + "private" : "58096ee29361978f630ad1fb00c1267c5a901f99c502f9569b933ad0dcce0f50", + "shared" : "d5766753211d9968de4ac2559998f22ef44e8aa879f3328cbc46aa858dcb433c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 228, + "comment" : "special case for CB in multiplication by 2", + "public" : "75e1587c5eefc83715d71020aa6be5347bb9ec9d91ce5b28a9bbb74c92ef407e", + "private" : "0829a49046dce2c07ab28440dbad146453e128960e85dd2e6a69a1512873dd44", + "shared" : "761d8cecf13f93b379a772e5fac5b9ffe996cad9af06152580afe87ff9651c71", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 229, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "f85a06065ea2527238fc5ec1b75ead9262e6b1aed61feff83b91230aeb4b7d01", + "private" : "587ac36b9a23594632679adea1a826f2f62d79738220fb487464039f36ca2372", + "shared" : "f12acd36f6299a4d192c03aa4efeea7df51e2d15d763172e68accf7bc6f5c230", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 230, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "6e0f1d00b1099d2a71f7be86655feb8988bba5577b02f964043a49f00c749613", + "private" : "a8a442b7c0a99227b4cb5c75fb9e5a72cea25eba8a0bdf07271bb4a93c2b6665", + "shared" : "b2bbbd173f41d952d329251da973a9500300628177ad0fb79d01e2e263905b38", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 231, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "696757ced3097fa960c8390a09e8bd6d390dbde8d1fa170261f3422edc192929", + "private" : "d8f7233e9612c00c9dca2c751ec1d3f5f67bad77c2e714a20e71eb3f220a6671", + "shared" : "45ecfa275f1daa25d3fadf33cdf89a152afea25eae37e68e00b30c367789887a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 232, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "fd84b3f2fbfa16aebf40c27f46e18d77bafa0c7971bedde4909212e771bd3c35", + "private" : "d80c7c7557c9907e1b11e844bf1369cba669bc38e9b7b253e51f239bda322374", + "shared" : "595e144e07bbe65b38e0e4163d02ad75a65e422e74067db35c90dfa6e055d456", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 233, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "805485703ccfc4a221ef281267f52b61cebc879f0f13b1e5f521c17352a0784f", + "private" : "8002a85115ad7b41c50f84f35fac750ee8e19734807102830ff6a306beed4464", + "shared" : "226e16a279ac81e268437eb3e09e07406324cb72a9d4ee58e4cf009147497201", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 234, + "comment" : "special case for x_2 in multiplication by 3", + "public" : "80642a3279da6bf5fc13db14a569c7089db014225cfcae7dff5a0d25ecc9235b", + "private" : "782db0c8e3e68f106fe0c56415e0bd13d812dea0e94cbd18bdf6761295613a6d", + "shared" : "790d09b1726d210957ce8f65869ca1ec8fa0b2b06b6bcf9483b3eb55e49e9272", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 235, + "comment" : "special case for z_2 in multiplication by 3", + "public" : "84e827f78cae0cf063e4340198f788c284e07430b3a94a3873df38b1f872ce02", + "private" : "909fb0bdbf53a69a2fe39c8b2497abd4fa57d2d54e046b5f514595e2c0f33d63", + "shared" : "684cc83af806bcd9cd251e1858f3c10f0166e0a0cd2be154339a886b13e7c76f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 236, + "comment" : "special case for z_2 in multiplication by 3", + "public" : "d445e1df0083bb6b8e886e6632251807171d4e88c41816fc684373c09d7e5d6e", + "private" : "78a67909757248665f79371eb014825ab6bd4af3571f140389c636e004bcf46b", + "shared" : "e426e4a3c54d3e77f4f157301e0ac7d9e12337a2b58df16780041cf6d6198c5a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 237, + "comment" : "special case for z_2 in multiplication by 3", + "public" : "f26aa6151a4b22390176f6233e742f40f2ecd5137166fb2e1ec9b2f2454ac277", + "private" : "286a302d5b076d2aba7c2a4daf9e7cc9d8539b7c0391307db65a2f4220d30f70", + "shared" : "862df92e25277bd94f9af2e1dda51f905a6e2a3f6068a92fabfc6c53da21ec11", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 238, + "comment" : "special case for DA - CB in multiplication by 3", + "public" : "2b02db3c82477fe21aa7a94d85df379f571c8449b43cbd0605d0acc53c472f05", + "private" : "a838b70d17161cb38222f7bc69a3c8576032d580275b3b7d63fba08908cb4879", + "shared" : "3f438dbf03947995c99fd4cb366ca7e00e8cfbce64c3039c26d9fad00fa49c70", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 239, + "comment" : "special case for DA - CB in multiplication by 3", + "public" : "d71dd7db122330c9bbaab5da6cf1f6e1c25345ee6a66b17512b1804ace287359", + "private" : "b0733b4203267ab3c94c506acadb949a76cc600486fcd601478fcdef79c29d6c", + "shared" : "95f3f1849b0a070184e6077c92ae36ba3324bf1441168b89bb4b9167edd67308", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 240, + "comment" : "special case for BB in multiplication by 3", + "public" : "737bc07de0729bbcfbee3a08e696f97f3770577e4b01ec108f59caf46406d205", + "private" : "d844a36b58aefdb08b981796029a2766101884b348f70eed947c2541064caf6a", + "shared" : "6a969af6d236aba08fa83160f699e9ed76fb6355f0662f03dbc5915a3c23063e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 241, + "comment" : "special case for BB in multiplication by 3", + "public" : "9758061a7b3e2c02fb5c20875ae6b55b11fb6795990a0f4fdcd1147be5521607", + "private" : "a0b7d312d9b832e124d1bc8cb21db545440e3cf14e7473ee9ccbe9b682f2156c", + "shared" : "ab39db4aa29ac4017c7446f1ad0c7daa9a37f1b6b4f2e9d2902ccefb84839d28", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 242, + "comment" : "special case for BB in multiplication by 3", + "public" : "37cd65d33036205f3449e8655a50d4b0c86fec02100b4f2db7da92dcf5e3aa0a", + "private" : "787f1ddd78cc6473d3e63949409ad3f35bfe0ce0738f255dee682f2bfbc80f7f", + "shared" : "13de41659e3e308d6e26c94282fcc3e0364ddf0809ddee6c8e7abb5091b02b00", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 243, + "comment" : "special case for BB in multiplication by 3", + "public" : "a9b6e8081460383adc587c8f91a02c59a7a35576ca62436ccd1b5fef1b92545d", + "private" : "4080ae60a85c1fa95aad9beabd98b405e7f28141bf08f2c9a4fdbde1c5680265", + "shared" : "69ed8a0a27812ae6741474bd5c6a4e683a126649f7245aa0f91a3a384bcde25a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 244, + "comment" : "special case for E in multiplication by 3", + "public" : "fd1a2cd17a93f850deb8c45a2d34539232dfd8a558304209781c6cb58229870e", + "private" : "08f9f4a4fac4db413315f74a59818b2452fc7b7685592e26556775f9b86d907f", + "shared" : "010218bd67b1b92fee3e7fa4578c13617d73195de10279747e53ba01a254525a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 245, + "comment" : "special case for E in multiplication by 3", + "public" : "b88119e5ae6d9e6b912d52524739e612ef19ab7e5dd3d946cb9bc003c378f81f", + "private" : "1888cfae3085867657b09435c42b74cc762457839451a3659db218d4214fdd63", + "shared" : "e6b298de9cb6358fbbb00f11890f5714a3858e8f05a2a8d1cf39fe78cc55dd4e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 246, + "comment" : "special case for E in multiplication by 3", + "public" : "7b70e29dce0479cde4a36c7f9786582f104bc0788f046b48af495e67bdb88f36", + "private" : "789ce13ed007818d7a5181e629eed944a20a058cfe39669c9831bfa5215a1269", + "shared" : "967bbe298494b4a5f95853cfde9dc85970b2a4b5dd2c92782901e853957f5809", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 247, + "comment" : "special case for E in multiplication by 3", + "public" : "2a209e2ace0e3d6973ffbf7403f9857ff97a5fdcd27f2c7098b444fc3c166738", + "private" : "00022b43775ab2f4b91bc1cb54c97f78026289eaaf02abeed04ca84f736c686c", + "shared" : "9f66848681d534e52b659946ea2c92d2fabed43fe6e69032c11153db43dca75b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 248, + "comment" : "special case for E in multiplication by 3", + "public" : "f50709aca7f314e8d05b5ff97a427e427bd5e85c4e86712125076a771be21448", + "private" : "8097a52fc562e8a516682f5363cc5e7c88e9c78e308df0deef40497b35cc127d", + "shared" : "ea7572e27a9120de1f13b85710ba69a3471b7b3f5d12bc430c12c4bbf8aa3957", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 249, + "comment" : "special case for E in multiplication by 3", + "public" : "0f13955978b93d7b9f9a2e70d96df922850a8ffd8412e236fb074aef99d37d54", + "private" : "4028802030d8a8221a7160eebbf1846116c1c253abc467d6e43cb850f1459860", + "shared" : "e23d63a46be67c7443c07b9371ff6a06afcd7a5794bf2537926074b88190307a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 250, + "comment" : "special case for E in multiplication by 3", + "public" : "18ffe992a729ce70c3b7cdc55bab55f2210d279134b3082a9f682d3a0b131273", + "private" : "d8515d45c7ab2b9529816543150068b8e4bb614cf2b68a8a99363975af503d74", + "shared" : "33ccaf24e1e26290ed7e462093e9f77607ef52a0626b2cd2511c41cd24c13849", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 251, + "comment" : "special case for AA in multiplication by 3", + "public" : "c3ba28057728d0533965ec34979fe7bd93cf6cb644e8da038baa87997b8dc20e", + "private" : "d8815bd144518fa526befdd373f5f9cff254d5d3c4660e8a90ef2a22c6876a74", + "shared" : "74f95b4700f0185f33c5b5528ed5012a3363f8bbd6f6a840aa1f0f3bdb7c9650", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 252, + "comment" : "special case for AA in multiplication by 3", + "public" : "4eb095a86d1e781bb182233075ebf1db109d57135bf91d54fdb18eb371427640", + "private" : "a82d996093eefdaf283f4049bba4f5af6ecc2e64894f325ee1f9ca1e156d0567", + "shared" : "e9677b854851c41cc489e03981ae78690be6cbf0054ea9834759de3e27bcf03e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 253, + "comment" : "special case for AA in multiplication by 3", + "public" : "83f67d7c92b11c8fb072484642a01f43deb022b54d94a4015e39849a2e2e9555", + "private" : "c02609df3d5436c123dcd7ee11f23f1da321666c09f379d37914203340510861", + "shared" : "f148716ebe7269a7076f0cf1f22b6978d3c7e3607b0bcc87a8c7a85b9fd20c2f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 254, + "comment" : "special case for AA in multiplication by 3", + "public" : "20cc75d376d8453b9d049c84f58eafcf61126c08a03661e735f0a8be228fd466", + "private" : "a0e3b78c0f3be2a760b2c916f244df219624fdda2e9e31b15328f4a77690296a", + "shared" : "1d5c123e88e9dc7a3b16ec90b60578dfca7e11eab9b88c6eca7bc33d91fde83b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 255, + "comment" : "special case for AA in multiplication by 3", + "public" : "ef31b43d19c0a5434deb56129c16298a394a7032a2e52cb997476bdeca325b73", + "private" : "701f130a290584cb28c7d6539506a1a054f926a17ef7c568ae43047c05e10f60", + "shared" : "2fc065ba8f5040a0a659f6f7330554bd1b9d7c893b91e316e0af90c37af4f135", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 256, + "comment" : "special case for AA in multiplication by 3", + "public" : "d8c8e2c6f33a98525df3767d1d04430dab0bda41f1f904c95bc61cc122caca74", + "private" : "d0e67f68183a4c1aed9c56864b36278bb7bb75d57a78321bc7c24ff61636607a", + "shared" : "ef7612c156078dae3a81e50ef33951cab661fb07731d8f419bc0105c4d6d6050", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 257, + "comment" : "special case for AA in multiplication by 3", + "public" : "1833619516b80db0c05b225509e6698df028d83b66ed6bac6f0f6308970d2c7d", + "private" : "88eb7775dacc32b045ceb35f261b3616315efa98b780e08c79d544edadb5467d", + "shared" : "a3cf3d81ec56896a68fca0da6335171d0c622568738c0db26fe117033726a049", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 258, + "comment" : "special case for AA in multiplication by 3", + "public" : "e2e989aad2397fc34b6cbe2db27d5ab69b28048383c91d9e8226d548253fab7e", + "private" : "7055b1c0576e7ab6c89fcc1ce49e79c8c371bf9fc2b22b8f8396a9b64c5ae26d", + "shared" : "e7f45823a45b6a46192b37d73e8609b5bda68cd7cfbdccaa49082080993e640f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 259, + "comment" : "special case for D in multiplication by 4", + "public" : "b9bd793624d6a7e808486110058853edb25e136bd4d6a795d6d2ef53b25e3804", + "private" : "906a9bfcfd71014d18967680d4509eaa41c666424af98bf9ff7ff49eb1baba41", + "shared" : "7c6148134c9e8b2ba5daeca41e6a1f3a82d8f75d0b292b23c40fe7f5ce0a2b7a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 260, + "comment" : "special case for D in multiplication by 4", + "public" : "e3f444e208da9043f3f74c20e28d7f404bb687a346709abcd555156f88607820", + "private" : "28392b1b035a8465aa22aabb571061c6effeed40cc2530b628e4fd40395ae04a", + "shared" : "ea5e772bac4693ce69ea3ac761011fa7674037653a433c7f05456e7291cd3c4e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 261, + "comment" : "special case for D in multiplication by 4", + "public" : "87b43f90f76d12fb3a469fa8687c27e369d4a82f95cf95e8dc3970de8f86d92b", + "private" : "78cbb35204cc88676c14e0ff18171392e998411b23d905d4c4dceab70511f442", + "shared" : "81c395aed5cc5f5e2a206a8a4cacecd501df5b81e49433835ad8a3779edffb30", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 262, + "comment" : "special case for D in multiplication by 4", + "public" : "86441ea06c5cd2a34c6b51261e93a2f30ea7db0f74e14c42f0fc443c6735973c", + "private" : "a8225b49ef7b7330e3de787cbc40479644db7ab126370295c94189673430d745", + "shared" : "513eba5870dc5187e2552fe3ba8292b516d2af9ecb9a9bdc51eac2ce2de40112", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 263, + "comment" : "special case for D in multiplication by 4", + "public" : "4624aa4ae9d12725bf92b85f93e3e8cea16b7bd83fda0eb18fab2dbe0e8bf742", + "private" : "0841e1a5c7420b94b6cc6991316ebdd608626339c09d0f67b24088588b9d0d49", + "shared" : "983b7e236ffaddb4b759b7353fe87846f59fb6f28a3ed65c256176b6609b7c6e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 264, + "comment" : "special case for D in multiplication by 4", + "public" : "a625a5b7a04cea462d123b485c39ea44a8079aa223c59e9ca97abcd30b500e4b", + "private" : "08ecf76e31a23039ea8a15ee474b6251a9d725bff1a5751eb5ecde9d7d4e2f49", + "shared" : "c941369b085c7465d50d23ceaf6717ab06e24638f217a7b8055ce8ebd3ca1225", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 265, + "comment" : "special case for D in multiplication by 4", + "public" : "8a5f2063f259f3317ae3e0b459f82c4677666e49a2eb9bf0369aee663631265b", + "private" : "6038fb0a830d1001ca8ea74a613ea98f6ab8512644e55e8d45a29071bd4bef45", + "shared" : "a3f7e169db44d0d179c242e66347364ab92744dc6ad80e4775aef7f4ff9d5f34", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 266, + "comment" : "special case for D in multiplication by 4", + "public" : "54cfb6ad0d03e3115acafee12606397f2bb46a8c5f326a255c494118aead3b62", + "private" : "c04cf129f0b33332e2654f8e45225c042d7fa6cbc793c88bd4c731985289b045", + "shared" : "401aabfbb73fe6694c446ecfffb43006427a9d4756e049a1ffc79578d62f1660", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 267, + "comment" : "special case for E in multiplication by 4", + "public" : "0ee3bee8cb3a0afcec22fa2233706e8ec29ccf1af212c0a674745ebba34f9d08", + "private" : "3806b036c92d7bc0771998d24dbda2945b601d42449bd3ec4bbf3757d01b894d", + "shared" : "20322dd024fb5a40f327cf7c00da203734c2a279b9666a9ff7d8527c927b675e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 268, + "comment" : "special case for E in multiplication by 4", + "public" : "797ec7512afbf0ad918d0e4947903be95234f3abf36750a8f854888d117b774e", + "private" : "380d9056b5a2f4b3dffb30e6ceb722ac4684245f1befafb5661bc8c7a9ad4c43", + "shared" : "46152d59c2d2f3ecf03ce652d2b6978d401d5ede4570a6c911771bdcfb37cd41", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 269, + "comment" : "special case for E in multiplication by 4", + "public" : "d570c7810f69e502b355253afa7c667bfa5060d90dc86e358ab445f6381e415d", + "private" : "384929a42c8d8df146db9508e2f21a4e8cd4d99c1b1338df17a457e88afb0043", + "shared" : "37567f7ec0449c7b823cf7b0e219e9dd880e56a1464d0417a9e67eff42332866", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 270, + "comment" : "special case for E in multiplication by 4", + "public" : "2c611cb94448f1c7822425a4cf5356236b90a555b1ed4747820ba7f739c8f57d", + "private" : "48a986825b2680e2f2547ba75a9599b04ed57f8ed18d98e7099c544efbdf284b", + "shared" : "fbf6587ec181116cf1ace7dcd548029d69c130e50fcf6ad5dfcd25c23ee9f939", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 271, + "comment" : "special case for B in multiplication by 4", + "public" : "e559c417da7fd5851352f508b90031d49b5d2d0aac88a9c8b5fb6e80165ac10b", + "private" : "98452ad7df4e26bc4b3d403f9ebf72bb2d7b6b7d5860dbf6fb9a4f78dc02704a", + "shared" : "c7c6f6d7ce1e4f54c727e5900686c34e6a6953254bd470bbbf0c7c18bbddad73", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 272, + "comment" : "special case for B in multiplication by 4", + "public" : "746d97e7774292a3d703f604e79d8764c99a6a2fe280eaa9811115f5e038f21a", + "private" : "a8dbc9be5034ed7fe7f469264f2135e9c67cd30f525570d2d841e4bdeac52349", + "shared" : "cf7d2a66ea4dfed94469b2d343533ff302a576f8402ed2187904437038e54665", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 273, + "comment" : "special case for B in multiplication by 4", + "public" : "1f354aa8ffc4eae2b40dad2ebf830db3feb07e2a1a2da39e55df87c8c613de1d", + "private" : "f8d26878dff25ced02d3b27ce74002695bb879b3c4328930934315ecae842b47", + "shared" : "b204d3bbcbdc624f9f1a743fa3daa8f4c8785ed088d37d08cd13c601170a461b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 274, + "comment" : "special case for B in multiplication by 4", + "public" : "9c3f0023e1a4832586af2483bbec64ce9f06f3ea806d4019a5e4abb1b5627029", + "private" : "d0f5e9c43c95b1ffc36f832b943601d5e17647f7d78e2e7710ace63ff274d447", + "shared" : "b9f21465615f39dddcc37520ce9b956f7de9883ac93a870d74e388b8e1775463", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 275, + "comment" : "special case for B in multiplication by 4", + "public" : "d05656aa014d476022dfc55e8d3b4884ed0bdf85209be8b55351394d52be684b", + "private" : "700679e8c24df828f2e5212a3263d5e93ea61679988298bab3b480f46f961a48", + "shared" : "20f1fc613874495f20562c10b7a8be47bfc12c168d829d6321aa2de17060e40d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 276, + "comment" : "special case for B in multiplication by 4", + "public" : "c4a19b8686e18c29359aa548427f06a368d55a8737483d4893523adac6795a4c", + "private" : "d0d077c9461f747e5660be85cc620428b4cefe805de0fd254adaa465ea5e784f", + "shared" : "652b18ffd41cfb7d1f0b6dc79baa3b2a392ef1617f5cf6259b5b4ff065916a16", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 277, + "comment" : "special case for B in multiplication by 4", + "public" : "4989de79853ff35be8c9f92fc94674feef38a0e65788471c521f8e259adf015d", + "private" : "00711ac08ef88c3d43a3cbda67b6fe5f34f54723dbe6d725c8a3569070ab9a4e", + "shared" : "679825c259392d86f8edb15328d4faf52300779d979a503a76e27be3d7a85e03", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 278, + "comment" : "special case for B in multiplication by 4", + "public" : "a981483cb0ea4385ffbb552826c3dd110d4ae89ff52ed0cd6018f99d3387987b", + "private" : "989a75b40451139ec36ca6aa043765c61a18be323a5987fcb025c2dad8d4bd40", + "shared" : "9cadc14ac153fa383ef66d1833f589100dff90523272e32b06e2c6f1f4424040", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 279, + "comment" : "special case for BB in multiplication by 4", + "public" : "1df3dfdab74ff38177dac294b2da2f49a348bc3b3bc6ce9312bea5ef3ecdd30b", + "private" : "90c3cfedd919a2ccd51fb455649e3ad2da1ef0ff619b59a7f9c55a68a8219645", + "shared" : "bcc95fb4890ed311f3fb4f44c2b60866cdddec97db820a7f79f475337e16284a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 280, + "comment" : "special case for BB in multiplication by 4", + "public" : "fc6b718ba8b47d24b1cfd6b5d0dd8b20fd920960fabc302dbe4f93bd2a06e933", + "private" : "e8fef5c9b60f84984e8836d535acb372096ba8159824a0b49a17eccda843bd41", + "shared" : "06f1b495b04a0010845c9d39b13bf2784ade860d9632c8847618c0b34297c249", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 281, + "comment" : "special case for BB in multiplication by 4", + "public" : "b279b6c065f95c7040f148bcb4a3d310e34bdb005931a879be469573deedd041", + "private" : "c0e05bde7727db4e352b5e7f035327b4d86a42d513ca116e22d64a4ede56434a", + "shared" : "cce7bb644df94501421db49d15e821c7b0aaabecdf8837ab989b1f23bac08f35", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 282, + "comment" : "special case for BB in multiplication by 4", + "public" : "98e2cd4c10554e41b0a3e41082c8b6b61b55447d26c0aa97f9a06baeeb54b55b", + "private" : "d87308bf753573f596ac8330b204014b2152dbdfc9881a0d9975058582bdf646", + "shared" : "71fdd3405c30805701ae4dfad98c493aecfcf2e3b563e7068373c1b19137c268", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 283, + "comment" : "special case for BB in multiplication by 4", + "public" : "872897f1bd1885da08b9d03e46811044fbb04186ba30c806f38b94ebdc27186a", + "private" : "d80059a8a387e16f6ded6e7e980e806d1f78b470bb61103d0ca70623ccee8b4f", + "shared" : "bf280aeecb74ab34e1310aa6fe8dc972f94dc40c7f88b72137ccfe34ed343c13", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 284, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "c08f72760d9cb4a542aad6e2af777920c44563bd90356168c3608c6b9af2ef0f", + "private" : "b0a4fe63515169bd82639b515ff7e5c4ac85bba0a53bbaca80477eb3b4250d44", + "shared" : "72566a91ccd2bcf38cf639e4a5fcb296f0b67de192c6091242a62fae467fb635", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 285, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "4f03849c24d584534d74302220cfdc90e1bc360bb5e297c0fd0fd5f8d799e416", + "private" : "984256b12ef154ff6c2e1d030826164cba3614e3df7688d82b59e16201c9114d", + "shared" : "24acb4afa63919621df795206c3929b599ec9d253693895d51a0555072e89a34", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 286, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "4959771a931e242d5713d5cb76f33310c6a283df16645604289553809cda6518", + "private" : "6847141d5d4377af96a2a647c642ee81600fe48d3467e3a70f3ee312bb621742", + "shared" : "5ba2112a41b5bb381f202446fa9f23c54d2de149f9ad233753417263840ea432", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 287, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "f6fe690cf547049635bb3a7785537b4379c9ee06b46120493b8bdb152e09c81d", + "private" : "e85f1164e2ab6faf62667c74b03ce529b49a0e2041b1ac0fa242e522d2b7694c", + "shared" : "a87c9fdf40c409b9edab481b2cc69687ee1ab92e340c3db0107d40b5de6e7a20", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 288, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "b468681a1275850c11d37ec736af939a75a7098514e04cfc1c6ca78239a88426", + "private" : "281e1bbfa711de69921a64c5d2183c338db5504606ce2b6b4ce1cdd54b41e14a", + "shared" : "3be98798f01e71639f3cb8fd4a17bf273e10c67f8974dd9802eed59d847d4020", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 289, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "2d71e8457099e3f445f9e2a14f18b0f5914bb35f482f9c069b64bf63710d4228", + "private" : "20aacf1902b3cd609d7ee15cc96453cc22e2899d7d17852680f2a728bac6dc4a", + "shared" : "338c9917dbf11a0cabe8ad4a65959229bc00f99c211e752b20b8b49b87756d0b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 290, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "fa8f24e944de5d003746d4630350c0f4f6175a3269c19184824105398fbdd329", + "private" : "009e8e9fa993804dce94cecb96b1de2568245a97059e4d7ae116ecdb1badd141", + "shared" : "56e2bfc7f6ab7da8fc734afc515e57d0794d002434f9bc8e18bd0b72c0df3c4a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 291, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "ae4e37ef53c79e25e8275a60f2fc1dfc277ebc5d3b88428c6432c3f98494212c", + "private" : "f01574643f231ffac055bd235ee74dd416b94c8e55a2ab2b4d13a8b788d90148", + "shared" : "17fa1276d9fd5025172736449a1c0ae33512e5037014a18db5903e47bb3bc950", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 292, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "95e56a830792478f7c42504043a9cab8e2eebff5fd90983709e29e03c0a41b64", + "private" : "3800a42659954281ca266d7cf1ea9db6d79891a406a70f9e84c3570a6a12d24e", + "shared" : "167a3b2fdce9413c89ee892daf9f839a2eea80ea8044924035db1724a5b0217c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 293, + "comment" : "special case for x_2 in multiplication by 4", + "public" : "5f16aa7ccabf4da6b686bd28c7460e106bb1b97a823792527765c29a9ad8fc71", + "private" : "70a826b186962218dbafca113319daefb5ddf3cf14e15fe3faadc4c0a2e46648", + "shared" : "30a4ba793f2dffe1700c61428b4d84b5fcd0aa99a23b903f84a48eca5cc9fb0a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 294, + "comment" : "special case for DA + CB in multiplication by 4", + "public" : "47fb78111805a11982a3d6c5d83e8e189e7fcc462c9abf805d3625be7a6eac11", + "private" : "a85a5eda0a269500b3ab0b58495fc254c2691028ac533494b5f86d44e9dc654c", + "shared" : "2bf9ab750bd58ff6f877b783eda45a71a65cc9b7c037fcfef4cb5f4c8842f529", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 295, + "comment" : "special case for DA + CB in multiplication by 4", + "public" : "03b8ca5efd1777d6d625a945db52b81f11214daf015d09fdc9df7d47b9850e31", + "private" : "183f28ec867624ef5eca4827ed0714a5525ef21d5e35038b24d307a3391a2846", + "shared" : "35e9289234bd5e531da65d161a065a14f785076088d741c9a2d886efd7d17921", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 296, + "comment" : "special case for DA + CB in multiplication by 4", + "public" : "4eca5f8731b0fa0c106acf578b83a350fa8173a290f1eba803956de34eeb7671", + "private" : "888c6444ff5eb482b2b10bd4e8a01bdccb65f32934d8026106f16a91349f484c", + "shared" : "833afb867054b8b9ac70d6013c163e8b7676fd45ae49a1325f3acb75975d8c13", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 297, + "comment" : "special case for A in multiplication by 4", + "public" : "a5562b4ba86b464dff4c2cfae85b384be211771efe8a9697e51d84de47f1eb14", + "private" : "c8a85d140ba150f5c6a8d3cb363bcbcb75365e51c61640e974a0725b5e9d5940", + "shared" : "8a914760129575c8ab3270d04b0465fc2f327acaf1676463113803bbb2ec8021", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 298, + "comment" : "special case for A in multiplication by 4", + "public" : "88ae1631cd08ab54c24a31e1fec860391fe29bc50db23eb66709362ec4264929", + "private" : "90a3aeb1417c3d61c1efef1ac052218fb55d3a59c4fe930b5a33cc5183b48547", + "shared" : "c1988b6e1f020151ec913b4fb2695bae2c21cc553d0f91cf0c668623a3e5a43d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 299, + "comment" : "special case for A in multiplication by 4", + "public" : "cbc4d55d5bfddd0bc5c5edbe3a04836b2c701d25195b26221cbea19311e55a3d", + "private" : "b858d7414bd9ab9a3ebea79064ab87bc050e74407f4d4748f62fa4d9d203b640", + "shared" : "bb24817bd9fff423dc0972908e2c03fddf4dbe100016b459f28fe9594adb3714", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 300, + "comment" : "special case for A in multiplication by 4", + "public" : "d66a2f9f7577e2df4a56cb51962b3056ff5cc0494c60f39511782e79923edd41", + "private" : "f825edf1f79eddd715a72b3ac267d6b2e97e18bb13bcafdac5940370b85ba64b", + "shared" : "b3b4513f8a3102e1ae782fbc69888177f2c24c569303a5d01ab1c3c5e285524a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 301, + "comment" : "special case for DA - CB in multiplication by 4", + "public" : "de0fed2fab6e01492675bc75cbe45d7b45b0306cec8dc67611699811c9aaef16", + "private" : "b0a710b470e324bb56a7d8ff8788d05eb327616129b84972482425ea4ad4f34b", + "shared" : "471ba91a99634f9acf34fd7fd58f72682be97ee1c821486d62ba4e448cbc0417", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 302, + "comment" : "special case for DA - CB in multiplication by 4", + "public" : "6418d49fe440a755c9ff1a3582d35dc9b44c818498f15782c95284fe868a914c", + "private" : "b898f0329794747d33269a3989b67e43a7ab5a55fa1210b0e5dba193f4fa094e", + "shared" : "cdb3ca02d5fdb536dbc7395bab12bdcfd55b1ae771a4176dedb55eb4d755c752", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 303, + "comment" : "special case for DA - CB in multiplication by 4", + "public" : "a89bcfa236bbccf07c434b59f8655fb085b6cbe5ed6376281df813afba22b752", + "private" : "a0528ed9a8ec22ebe9cc2e32fafc3f467500a9a22f5377382df6604edcdf4f44", + "shared" : "cd3245403fd9edfcf91c9581ebb2eb7c77ad6837fca372479e78de9faf60a34a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 304, + "comment" : "special case for DA - CB in multiplication by 4", + "public" : "cdb1f95f6eacc24b6d029c6ed976666dc51794db8e4aa966ba850fd7f5048965", + "private" : "f06888bde75d689d056874f6436000497d22d8ad9b95a1c67de1dda4ada3164d", + "shared" : "ab7c47ecb0c0167156f44f66a527264b958fc992c21ce98cef3ae214d66bd82d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 305, + "comment" : "special case for DA - CB in multiplication by 4", + "public" : "9491a82744f1cb6105b76b0442e54e605ac67f47a1b2b3b552d486f75bd98e6a", + "private" : "e034fcaa3ae40603f9b22af159fd67ef009380946de92cb1d83cc489e8b35041", + "shared" : "1bfa264a7c7229147a20dd021211891e61f5d8c76cd83f0be24bc70e466a815b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 306, + "comment" : "special case for C in multiplication by 4", + "public" : "4d19e156e084fe582a0eb79b2f12b61d0b03f3f229227e798a933eea5a1b6129", + "private" : "702a7448c0ed58e1f4e0e332d096a36360beca2f6955c815bc120b3a691d7742", + "shared" : "c46057fcf63088b3a80e0be5ce24c8026dfadd341b5d8215b8afcb2a5a02bb2b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 307, + "comment" : "special case for C in multiplication by 4", + "public" : "cc4729c4eae292e431ec3a5cf5020e19f9bea50ef3218d9a790034526c3ee14a", + "private" : "50025cb508ad4faa06fafd0f4a33b747ccf1b3573885d3426500d51b56300144", + "shared" : "d4361e26127adfbe37c2ed8f42cce4ebab8ab74ed9e74f14c3435d612c1a992a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 308, + "comment" : "special case for C in multiplication by 4", + "public" : "4a474249af8f771f0cfb1116f24fda4c42f4136d2afb766d1b291c73c6668d5a", + "private" : "7082fc53299a4d30e5d0c383c035935b1eeebd9408fe4d04b93eec24be52eb47", + "shared" : "80dfae7a28bb13d9e51ff199267cec2a19dfc8b6f4974e3446b2f62fe9b62470", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 309, + "comment" : "special case for C in multiplication by 4", + "public" : "0f2a5cbbe503139531ac0529183da8e624d25286f6e35d1407ab1f4d76ebc260", + "private" : "98ff7e711d65cc7fd9d0ac12dfe8b894e0a93602ca9e75bf0eabbf0bfe670148", + "shared" : "7a5c373065e339b26ee537cff1cf4597cfcb4bf2dc7c4bcfec9884443281c273", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 310, + "comment" : "special case for z_2 in multiplication by 4", + "public" : "2fe11d723dba63559e1b96147893cb7ec862711806316daa86cd4da769d4b22d", + "private" : "b080f4ac1e758bbfbfa888a78cb8d624d97b8688002b2017e35f52f3d7c79649", + "shared" : "c5edcc5d447071c08dfa8281414ae6a02de753e2f7bb80af5f6253e56db43422", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 311, + "comment" : "special case for z_2 in multiplication by 4", + "public" : "98e1211dcf6651fa9f2d00eb083ae5855869a2a53e835f2e03b30c0a19ba8051", + "private" : "e815bf9a967e1208af8e74ce9af6d113dab17c01c90f1ae2bc25e3e2f9e3a44a", + "shared" : "263a38fe538b50e8e988bf07ae86f33d49886b14c7143efd1d2025c840e36a25", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 312, + "comment" : "special case for z_2 in multiplication by 4", + "public" : "2f1b938b81a4c90e1251135ad7fabe835f6a8bc5e22d4b2ab119f6f677877677", + "private" : "4051b01cdf90af38f0a96ffb83f8d4133abe4fb035b6fe6f65276447caa7314f", + "shared" : "340acf2801de71c18f4c79cfea372bc354e4c8a5eb5c2cce8b45d885df162f45", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 313, + "comment" : "special case for CB in multiplication by 4", + "public" : "340b9f613550d14e3c6256caf029b31cad3fe6db588294e2d3af37605a68d837", + "private" : "98c092363184e58ad6ce510bd32b309c9d5a46f8d9ee6f64a69d8180bbc6cb45", + "shared" : "9efe5cd71102d899a333a45ea6d2c089604b926db8c2645ce5ff21492f27a314", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 314, + "comment" : "special case for CB in multiplication by 4", + "public" : "edfbd6f09aa32435440b0ca8ba436308319613f8f2d501133c526c3ff55c7b3d", + "private" : "686e51c00116d1c191aa9d5823b96e5956102e8fe75f5cf2376d99989f6f4342", + "shared" : "196182095bcd2ef46b18f64c63607e0ab162a0869e6265ac8ae35e358c3d8a63", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 315, + "comment" : "special case for CB in multiplication by 4", + "public" : "9b0538cd618b0a4de09e45420f84d54d74514fbb1a31c1a4aa1e93306f20723f", + "private" : "208af2c9442b36b521fc3a1ecefe342aac308bd6e6296ee091c196dc02e7ae40", + "shared" : "a3c6b75168211e8e0a49ca815bfe3f469f29864dc8166152b456e7074afa9b5b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 316, + "comment" : "special case for CB in multiplication by 4", + "public" : "ae8cf2fcdde710c2c1184524bc32430874dfa08c125f61d6919daf8e66db415a", + "private" : "c0d861a6d5ff91f91e3bd05934161ff0ab0f3ce7e4a2b5b4fcb31ae34b46664f", + "shared" : "deaae6c9952844a3a1d01688e7105b0bbeadc160763c2002b6d0bcf35c22d123", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 317, + "comment" : "special case for AA in multiplication by 4", + "public" : "2a59f478402d2829cd3b62e9f7cc01445e8e73a42cb11af00b6b9a9f0e44cb3b", + "private" : "70785cad160972b711318659b47b574f6941ef6da1ea06508b2650f57ec9e54a", + "shared" : "c204bd15f01a11a2efdabe2e902b7cd0aa079316f60e911b3ee5d46262e98631", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 318, + "comment" : "special case for AA in multiplication by 4", + "public" : "836c8e45dd890e658c33e69b6f578a5a774c48b435bc3b91ac693df94a055857", + "private" : "60afc8eb1f87df4b55287f3c4698c5f8b997b28a73c573fc273e9c467fb7e44c", + "shared" : "c5457487e90932f57b94af2e8750403e09c9ac727e2bd213590462b6937b0753", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 319, + "comment" : "special case for AA in multiplication by 4", + "public" : "59519ead7995a6df89bb54c840d61a8481881098b8a4f83c6a2f6ba800338257", + "private" : "a83c11b2834136b9aaf0152d90e76e3c27177693a2834e8beda0a3571bce6947", + "shared" : "4ed6f8d62932541c6bea16e03835f1f758a5c41722b5c9989c9c7cc08e34e37b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 320, + "comment" : "special case for AA in multiplication by 4", + "public" : "32f34da84ab4bfca369c4b884691becf54be7fbed16449dc86969da7ea9abf62", + "private" : "b80d8795735806579e71759894939d758853592127efe84fc82eb7cdee45014f", + "shared" : "521a5b8149a132d155e6b4ed113900506cfc2f76d2a3e14196d69eb85db3c952", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 321, + "comment" : "special case for AA in multiplication by 4", + "public" : "82ae48dcf59bc5e469f9a11b18a32d4753ac818692dfae27d675411a2272b363", + "private" : "e08ffa45efbe1f96584c76254554adb9177b58ed09609a6ce499e5bd22d35c45", + "shared" : "e831d6cee95ca1b4c96bb89457562fff36cb4d08b81da89b810b425ecdbafd78", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 322, + "comment" : "special case for AA in multiplication by 4", + "public" : "b33bd3ad14b66896f971cbdf27785fc3aa3cfb39adc6c29257d22ea4df8cbf63", + "private" : "688e1bbb5114f34e8531c278b2d9714ba07c32a7aea6e627135bd1fc65238045", + "shared" : "350e3ab9d0dbff78f3f2157428beba189333be274827c10d59673f21c0c48a24", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 323, + "comment" : "special case for AA in multiplication by 4", + "public" : "18e58df6bfbe184b0e3c7c4bf2a051ed055b793501c0d4fc47bc8a95c4deec7c", + "private" : "8036a4e2e93e9ed82d99d71a522aac9289bd9905fe41d01d08a499376a258442", + "shared" : "ade71d6460287fe808e947560e67a9d6ff2f96eaa1355d2e9fbbe549e883381b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 324, + "comment" : "special case for DA in multiplication by 4", + "public" : "772e31e776e8d4f23b7af2037af28a37e68f61e740b3904f4ec4c90157be1478", + "private" : "901b20f0cda74076c3d4bf4e02653cd406ed480c355159e22ca44b984f10764f", + "shared" : "91a9bec28cf18c7094e2d80d2764df59ada0cb1946be422864bd7ad0e533b663", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 325, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "a8d55d5c1137e9bb626557f9d6eea8d3120e9364f8bcd9b67934260b1a091801", + "private" : "d83eb7affd1bcc1ec0b4823cee5cf0b15b5f57085aa2708ed437a2925329b550", + "shared" : "6c1b8e240edfa5db2abb3dc12bcf9e8ac9ca10dd3507083746f6f36dc035d755", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 326, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "33c94be58b0f0e6cf363e1b12a2ebfb93040715be91518f21df2953eeab5fb01", + "private" : "989eee317b9c254dc023f9e35eff0224bc2e0bc871996b946a96970e7506a85e", + "shared" : "d4c3b3467714f2d105904a84cc7e81d7f291304e908041682d8906a683c12125", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 327, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "a218ae9624b07ce05178b9d0cc1b71dee21f27852a2ceb18610b4052b244f00f", + "private" : "b8355455d358f2dd7c5707b2c6973c9c27b99e7d8ac1650c791e5fdbcbea4957", + "shared" : "1ebe6ca711a649ae487b332747e3dc0306340560cab6bc6029e44f6a7e0ee41c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 328, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "d7067faeafd3e966e57525f930b3317c9e8b9c9a9ae946e76c1e4602a59a7e33", + "private" : "8065567ef082b16c20853487f54893012ba4762224e5c59f250dfbf82581e85a", + "shared" : "03e7a777e648bdc612189f3cd42d34e35736d3e52e6edc8ac873a58e244a6073", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 329, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "8df9682cbe8802478a8531377e752cdde54738d528d639bea9eaf47702f8bf3b", + "private" : "00b51448139a61fe6c5fbf9395877d53d820ef59da3be856458b5eb90985ba53", + "shared" : "308ef99dae1064a444fa90775b5dd5b1952d7224a0e5ae031df432640f416208", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 330, + "comment" : "special case for z_2 in multiplication by 5", + "public" : "7d92706868aa09538638d633c255f333b9da03bc74b49b35941c57820cd3fd47", + "private" : "e8eb9f6f62f93dbc325b833aa763a90f13f0acb2c2c4b8b33decd471ce70c45f", + "shared" : "f33e2e86443a2c68823b72a2b59d6a028e0a8e283cfe29fea4f7aa22bd1afe72", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 331, + "comment" : "special case for E in multiplication by 5", + "public" : "dfb1ffc176aff84db30182d2378f83728f83dd1b33d79856f3da5459cf9df907", + "private" : "68a1a7ccc50bab4b01e55e18cbd464aff43131fb0741e68d53cdebfc54f33051", + "shared" : "7b535fc31c6c2a3803d8bd45410a1781bd90a09205da28c9df120df23a9fa32d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 332, + "comment" : "special case for E in multiplication by 5", + "public" : "12e81e838b21eac96dc130432571216d7a9b4a817f1938721d2267dd150ebf20", + "private" : "e075bcfc165a471b2f76c3003fb0172c82f707137de2fa7082e43a87a255935c", + "shared" : "ca23a781da0911e4115a29a9f56447157c23bee187b0c17369c4f7730d781718", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 333, + "comment" : "special case for E in multiplication by 5", + "public" : "832a46aec02240d716fe22dea94ad566a3fafbeedcce35c83e41e58076c99749", + "private" : "c0e19634dbf6460e1486930c46e8556b3c16d6de959904600549bb3e08603455", + "shared" : "cd0686b32ea4cddb8e13ff20a78d380749a5d4f6a3dc55d72f4813d949a0ea57", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 334, + "comment" : "special case for E in multiplication by 5", + "public" : "8c8033432bcc12d479f67d6d876b1c8e89f16a234b9b093322effa9dee94554d", + "private" : "b84caa18acc3db37225d32cab4f60e6fba4acab1277e20425d30f94cab2e2c55", + "shared" : "a950aa57bb2beb9ed5d3228c7ef448dab69552f3d3b1e466accf41bfb6d5b874", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 335, + "comment" : "special case for E in multiplication by 5", + "public" : "6df799bba6cdf5f46a57ab227f93fba491dad296a2fdb7e491921d610cce8f5e", + "private" : "2896818cddf572521943e9f0c5e845f530b740427588a0f6de2504bd5bf40c53", + "shared" : "54f5ae57e676d08c8f8a3cf891e36ddaab751093f92f409060c57e745941700e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 336, + "comment" : "special case for AA in multiplication by 5", + "public" : "0c8090e1cfe7f761cfdf08d944d4aeb7a509a07a6101645b9a4c7c9e9c3d4609", + "private" : "a01f0cad98cf2905b812d3530531bb3ac899391abd1eaf4a3ebed96ac6126f58", + "shared" : "2d49b09f81f3f6fab2c67e32f1bcead2ad09ac9e0d642b0873becfb64de2ab23", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 337, + "comment" : "special case for AA in multiplication by 5", + "public" : "08352936c8afd8543ac95f24bce9a07e3e3235763ea512a584298967b83c070a", + "private" : "106b36344cc4a5a389d8168137786806ff03cd4a00f8636bb7e758d456151d59", + "shared" : "a199368e683c3036a48f4c5f32b32a547dd39f3d1007ca0a0bebcad0a8ac6f5c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 338, + "comment" : "special case for AA in multiplication by 5", + "public" : "73bdeef8cc044f5ad8d6a241273e1995e0007dc9e6579046df86aa6cd97f5d2a", + "private" : "88f9a0d2354adfcbab2d12a0e09b3c7719c944384edfbaa27fe0731cb9c6fc5a", + "shared" : "5aa750de4207869ec7fddab34c639559b1eb27ef244aaf2a702c84963b6d6e7c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 339, + "comment" : "special case for AA in multiplication by 5", + "public" : "7fdd399b6ef4a3f5cade62e74113b29c27db15203f9b8e398d2c6f230051cd2b", + "private" : "0811f2e560a205e96e28bc312bcad45fe8befefb7f6da5faa035311eed80b251", + "shared" : "a6947ee089ff28ce3644ea4c6eb33dbb20c7974fb8d853f4e146e2466177502d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 340, + "comment" : "special case for DA - CB in multiplication by 5", + "public" : "f0173a96273c646fb63d13b0c686b89e37676fcc7178faf4a6f4601f3068150d", + "private" : "40ad984066a69080fb4a315878e736096cc577dae4c42c40d893d8c2173b785a", + "shared" : "230b6aa1f24df90a60839179ba5e9de673cff11cab59e8020b20626c22090b0a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 341, + "comment" : "special case for DA - CB in multiplication by 5", + "public" : "255bbe7230cd2bee90d283f418a474ab30146ce5e801a0f5ed60ee8def3e6558", + "private" : "48b10cd45639bbbf83a0b28f0dd3ad0b7b00caf48d05534480556a8278116d59", + "shared" : "2299e384958bedd2c3d367759155136d1ff76e4434dc1d9e8212cdca52ea8421", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 342, + "comment" : "special case for DA - CB in multiplication by 5", + "public" : "21accf97b7fee173001ccfcab21637c175ef5186ff0002502b3d52fa8c51e766", + "private" : "e8fad77946e0de4cf4236798490b838948b82cfb29f8e7686001b11e8d961657", + "shared" : "97fca065acd3b943c654997c0f125767f9abc4b7c9d8b7246942f12be65d9231", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 343, + "comment" : "special case for BB in multiplication by 5", + "public" : "5b40777e80ff6efe378b5e81959ccdcbb4ca04b9d77edc6b3006deb99926fa22", + "private" : "d07babed90b27c4eacafdc871703bd036b720a82b5c094dceb4749eeaeb81052", + "shared" : "f482531e523d058d6e3fe3a427fc40dbce6dd6f18defbc097bfd7d0cdd2f710d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 344, + "comment" : "special case for BB in multiplication by 5", + "public" : "48d952a2924ff167f037707469ec715da72bb65f49aaf4dce7ec5a17039ddb42", + "private" : "68a3049aef8c069b906cf743286d3952a888bf2b9b93bc8775fb5adde06e9f53", + "shared" : "de88af905d37417d8331105345dabaab9fd2d3cb1ee902911c1c8eae2991d911", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 345, + "comment" : "special case for BB in multiplication by 5", + "public" : "a5ef265ccbc5c54021d34f82364a4624030f5b9d5ff7e63d7a379e533de5e742", + "private" : "18d8c3d2a4e366185a85c38698d937e13bbbafdbdab1a0a83dbbe89badf70756", + "shared" : "075d18ccc984761b70752279e7f6a757208f6c11e29480c32b40aba128a4d52b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 346, + "comment" : "special case for x_2 in multiplication by 5", + "public" : "9051e55a4050ef4dce0b0c40811f16371e8b16932541da37f069406d848ea424", + "private" : "18efcd5fe345be4985316695391d2c952eee13b0e1ee7584721fbe8b19d4fc5f", + "shared" : "212dbf9bc89b6873a60dfc8731a10be11ab2dca4b172142e6c9f06614cd72852", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 347, + "comment" : "special case for x_2 in multiplication by 5", + "public" : "419adb8b1f2f87de016b0c78d1029a210492eb8cadd164b12cd65b1d57bf3634", + "private" : "28ec7c693e222c72ac0815f1fd36661357e0a8da7bc996daeeeafcd21c013451", + "shared" : "379f9221abebf3582681a0e857f3da578a1b0121982b96f14b94de5dc8b24528", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 348, + "comment" : "special case for x_2 in multiplication by 5", + "public" : "13e00dae3b1ccc97ccd649088c4a7f32ca9976214d645667bd082039bbd9ab7a", + "private" : "78b35e7ae549308b6414bb610196c04f2af79d4266c86e8a9ce0c02bbdb88d59", + "shared" : "cff2596b7afe36f4cab9c70133d7aa0f9914f9abc6c3b9895472e2a5894a8037", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 349, + "comment" : "special case for C in multiplication by 6", + "public" : "441c487a48f0a4989d931cd77a6142a0a13d1aabad82623ba8d94b5c374f4f08", + "private" : "f0de9c5f8a9372f30c41ca47a55743ce697d46e32e7a9ae26d32503fd5222767", + "shared" : "d47c46b4329bedcbc1986b3c6d2aa9bcd027d6b68925175d35bbb536b3440801", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 350, + "comment" : "special case for C in multiplication by 6", + "public" : "0e67ee5c6b65aa802259810b2605f8d7accf9b49bf14cb4a536928e883172915", + "private" : "686be5a12b310420f9bfb209381fd459a5ccd55c752b88337ebe89e1921ae765", + "shared" : "1d730158da880533dbf1e6c64a8e99f9169611660969b0a84fb42dd8dc2efa3d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 351, + "comment" : "special case for C in multiplication by 6", + "public" : "dc9d7ef1cb49c191e258663a94e731b9c066c11a17d8b5fdea1987f5d9a00568", + "private" : "a0c0337c5bec5ca24dea2f1d701498ae2bad87b8269ac23be113929fe4eb1963", + "shared" : "07732529a628badeb8d74946775ba457c700bf8390f46bc523fb64e471c86a7e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 352, + "comment" : "special case for C in multiplication by 6", + "public" : "556b3ee7cd0d37979056ecc1f56a5677a4935be6e49ce28e394f8bfb73d13b6a", + "private" : "b8824cfce5550b5e17b12f74e28459cab34eb49895cc36bf645a0cf00e3d2d67", + "shared" : "9e3aae35fa1cc80a359878e212180294ff6608dcb4929e91901abbf976f39c16", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 353, + "comment" : "special case for C in multiplication by 6", + "public" : "1211be5809605b54f5727d233c783a2a199a3db24ed4499d7b48c7603e4ad371", + "private" : "e02dba7335af8fb9168de2fcd310c2e2df4a3e25263e0ab9ada87bfb8258a66b", + "shared" : "880f6dc73220307a597670f3282fc366aa66f04a0a9ca30d895fdde337afe825", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 354, + "comment" : "special case for CB in multiplication by 6", + "public" : "505e7851e2352e311ca9536a1fe6c0d95d648197374ce08e4b8a0fbddf62910b", + "private" : "30ce71f856ceb874fe580039ca67e896e6d08207a73cd55db7059127c1342b67", + "shared" : "ea62b0eda2d7b249a42417675a2b82b1e6c0d69a4e7cef336448844d2f432251", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 355, + "comment" : "special case for CB in multiplication by 6", + "public" : "ddf4e90503dd82610c3a034b925a880b72dbde30c626009202b358c6eb00f418", + "private" : "e881f46d4141ea69a671649b93b63e97dc67c12521d445862f087b2626fa2b6f", + "shared" : "302c4f83b5c5bf30c1e3afd9f643f65bfe56ca1628ee042b1ab7393bafe36c06", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 356, + "comment" : "special case for CB in multiplication by 6", + "public" : "0e9c4431999ef1ce177e900d37ec6ae665e387e2d4fa27cba8e7baebc65c6520", + "private" : "e879752683cd73a834251c65749135e06eb9064d3ae35095d88cde14a02ba366", + "shared" : "8ff2ac65c85ee2fe9452fce460f8c87f9570d769cadddc87fe93ef8b7657c726", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 357, + "comment" : "special case for CB in multiplication by 6", + "public" : "5761d6c08624104d4117ff17c75e9211a591c9ca9aecca3a665a7ed844195225", + "private" : "20576ab456da26c18da5fbf06ec4d16564e111bfae2a92b9f6e1927c15770a62", + "shared" : "97c91a23c3e4f3ff727d188a352b67ad490b62381566fb3e111cb67aa9e3435c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 358, + "comment" : "special case for CB in multiplication by 6", + "public" : "e92d45b3ec56531266303c5113c46310c41650001065b4d87b02b382fc82662e", + "private" : "a8467418b924c2c003c56e1610a35469356360c29d52aa557a2bb30fb8a9a464", + "shared" : "24346bb133dd9ae3ff02d2f50510b3a92d9030834d60e5af08b0eebbf1d4dd6f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 359, + "comment" : "special case for CB in multiplication by 6", + "public" : "f38b63459d05e422ad024c2dcea5029a0a7a6b6c4c1d2093ce556aab331e2540", + "private" : "f0f5e162923d7c299388bed781199417ade097475515162d9590976a196fb16f", + "shared" : "b3453c9c82a2d1d956156de2399cb70dd4e1ec53aea967e035753c1cdae13c39", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 360, + "comment" : "special case for CB in multiplication by 6", + "public" : "a7ded0eea45a400b8f5637154d42974aa98c92962314d822ef88b01383a9da4d", + "private" : "608fcf787fe789644a09bcab958f0737aa81a9e29d505f51035c78e374b9e46b", + "shared" : "ebeb0c7b7a4165cd02a278f3a222c236eed83266b806d13494c1c3f98a2f3425", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 361, + "comment" : "special case for CB in multiplication by 6", + "public" : "7b0ecb4c72ee147789d74813ced3ebe40f45c3da526ed1272952e453e43b796d", + "private" : "58a3396d291eb23571b52d98a31549e514e501e8d0958ad9f25fe5a76c503e69", + "shared" : "9213a53f22ff0cb5eca87b27b193c773bfdf4c01a193a11f37c157474e15cb07", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 362, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "a244413ddc3a205d038d64266833eea1efba51ba62c9c6cdcdbe943be52bb00c", + "private" : "d805a7014755dd656f98d2b331f2d2d4912725ef3d03752f26f74dc1ad61666a", + "shared" : "66484a4120e0eb0c7e0505e1d2c5d15de9b52b72e094c9bac88634200c557267", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 363, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "ec3c8b0c10b1fa65dbbd17cf1ba5f86381284765709b07c5f0428e3d5bcd3920", + "private" : "40cb1fe06b08f068f7080ba07c695eda91a2bebeadd4db95c97dd7c91af2566d", + "shared" : "384f2221618e71d456b1551651efdb708a161d7f89f5604b27eb872d4aa93276", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 364, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "6330d3e28a8b6126ace165a9dfccc6e4bd40dbc9768cfb16330cb7f27f906230", + "private" : "8021464c64c9d6d3c0c852f6972d11969b04c9e066562fa7f0d5fa0d98ebad62", + "shared" : "8daf5f4b84730144ea8a53ce39cc907e39a89ed09f0202e7be0d3bda38da663b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 365, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "8678aa29cbc06e78b218d22a3e66c38ec0da8fdb0f2570c585c62517c9704f37", + "private" : "707a2d710b32f55c6eba34898020a2fb981d61b1e822fca84c47d9321e279268", + "shared" : "da8b7eba6f72c3f3ef33d8982093492e06be39bb0db29c465d95a8e52ef64341", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 366, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "303289c2b1079ea59412faccfeba8c113d2299b9dcfedeabc42697b0829c4658", + "private" : "204a43dea79d779577581b8c2a51be66e1effce96425b7422b9ca65bdf1a4867", + "shared" : "0419a71a08d3fdd574cbc932e8f1605933ddcdd9774f5614269b7ed850c8650e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 367, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "3e6e16e02d44ebd94680832e065aeddcbb74af64fbb7c6d8367e7605be13ff5b", + "private" : "58e4741735d2589322151947a1ce2f5829908626886941cb1631d25a8a684169", + "shared" : "9f2fcd0c756288c1716ecd1f2a74864b93a7717bfaf5248858dcb6fdbea12864", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 368, + "comment" : "special case for x_2 in multiplication by 6", + "public" : "a7c1716a41ed23a8870438714ff9745fb0e46f7a5baeb37c9a2d83fe477d146c", + "private" : "d0af3428ea5205f6bf8d4f1b4e4903cd76f04236a1c0b3ecfdcaf28b21348e63", + "shared" : "261ab6267c35a9755359e957473870522b7f923fe839f2b155408649cc5e8004", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 369, + "comment" : "special case for DA - CB in multiplication by 6", + "public" : "dad981552c57541c57ef395ed770ce5edc48f8015461b2ba7aa831ec593ceb15", + "private" : "c0ea97e442e5dc1c8142bfab7089ecb9bb9c5ae372f9907c2825e678defae567", + "shared" : "9093bfa3ed3491d0891f02ae466e5e13c980df229db7404c5b9d34e4ed21c653", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 370, + "comment" : "special case for DA - CB in multiplication by 6", + "public" : "c588dfe6e733d90581cbe112079749d8eb30ab8631134ec29abfb98b32e76522", + "private" : "b0333f09ac1eaacd3cd617eb8832e9de488b458b735cb4b5345f517130c25d6b", + "shared" : "6e88bb6bf75596bbe5f1fbe91e365a527a156f4f1b57c13ac1e3e6db93191239", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 371, + "comment" : "special case for DA - CB in multiplication by 6", + "public" : "0670116a435e8d9b7a12ffc4322fd6b149d0b1dc799b5c0957d9d6e42546e824", + "private" : "10719099dc63bcc282ef525845c108897ac9fae9590b593e0d505d1cf167c061", + "shared" : "e6de74d2c5cea54094d7a70af03c768afe05d52a038bb72d56dcacf0ba502d74", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 372, + "comment" : "special case for DA - CB in multiplication by 6", + "public" : "8b200dd226c5c0f7e116e5388ba162438caf1dddf4edc3b6ba838c21b5929737", + "private" : "10e20e4fda57084ca90f7ad572a78aa8e6575c659cd01f30c43c58040c20e860", + "shared" : "78c9c3aff9416a538ce3ea8fa553244528d1fbecbcf91695a33ca464ef76b85a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 373, + "comment" : "special case for DA - CB in multiplication by 6", + "public" : "419a076b179f79720096eaabaf03477e8f89d61f885c8d7f58f6eaa4fa77df5f", + "private" : "a8312df473adfec7171e1635f5bad44f0753a88a6b3174ec5ae762703ae25e60", + "shared" : "c1a96ccba08bdd82d0fc12e8cde4cc1f25cfd5276dce7f18e407ed0e4a898466", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 374, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "aa34d772e9ace43c4d92f4f85596ab9ccd8c36c4f4cbddc819afe2a33cb8b216", + "private" : "109697f400210f9a92de80a8bed264097199bc240e22767b54d8bb22050b7a61", + "shared" : "2533b845bb83e3d48cffa8dbd1edd5d601778662d5da03759152a5e0a84b357d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 375, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "1f06cfe464ccc0e27a5ec5f9edd9bc7bc822ad2ff5068ca5c963d20edd1a2d22", + "private" : "d036308a53c11bebcb02e83688ad74fec43f8462ef4d806272676637d99b3765", + "shared" : "eb40a3974b1b0310b1597d1f1f4101c08dca727455a9d8224cd061a7aa3cb628", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 376, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "9d4b2ed7817132af5830e899627ea97dc39bd3772e82f2d05769a918273dc02e", + "private" : "786e5a5ff37405c769d0d3788c3c1b05a62a8442c385570e4438bc5f2eaacd67", + "shared" : "9509757e289553cfa2cc71313473c3ff1eebce484ee237eae554fda3d3d22f0e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 377, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "4e056b317a31dd96f8ec14b48474af587d195efcc2a70f01f052ef882d7b3a45", + "private" : "c01f66cb094289d728421dd46c6f9718412e1c546dad70e586851be4da58bf67", + "shared" : "bad9f7b27dac64b0fc980a41f1cefa50c5ca40c714296c0c4042095c2db60e11", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 378, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "72c60535e9c423f302d6a10796d954d778032cd4dbd40ca0f359e204d67b6f4c", + "private" : "3877d9ce25cededeb572604f2d123df685690c26e181f777ed33302b82082966", + "shared" : "51c359768ab0219003af193e2bdb8e5cc9f8e176b8db49e597afca3e7125e370", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 379, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "5856358ed420047cd084f17ae696bad79a4d26c6d5bb79bfb82bbc6332442d51", + "private" : "50b84618d073c4618f9aa69a3b8518da76dbb2127286214fb43a2b44503b9969", + "shared" : "fa9fb0df4cfbacd0fbf3262d3a1bf8d7aacb45f73bf94671775e509c8043df7d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 380, + "comment" : "special case for DA + CB in multiplication by 6", + "public" : "c31e37b04332abca8315f317171566aef38111f622d8bffa29c23c0151cdad6e", + "private" : "109acfa638e112f6bbec21e352a74e8fc9b7ffe5d9dc28634eeb516e59830a63", + "shared" : "91ac72b0ed8d7fc4c8846b8a2530d9fb8f0532064880c00dab100c977697db28", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 381, + "comment" : "special case for z_2 in multiplication by 6", + "public" : "b775e016b32a97f49971121906763f3a0b41689092b9583b6710cf7dee03a61c", + "private" : "685c0784aa6d194c1b859bda44c4e27cd1dfdf34776e498dd03d09f87ae68a65", + "shared" : "11393bb548813e04fb54133edbe0626458e80981885e1fe5f3377e8ebe9afa52", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 382, + "comment" : "special case for z_2 in multiplication by 6", + "public" : "f8bd0e7cf6ec6186f205ab03ab72c8f6b3cde8f6ad9b166916a04d43d1d6d546", + "private" : "18e9a05a20436cf0dbc3d5b92dac8d996e62ea11fbb3445f29195fc75a8beb69", + "shared" : "0a83a224fbfcbc5d0f07f6dd8ebb2e9bbee8134f0fab268002ce837f5495d833", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 383, + "comment" : "special case for z_2 in multiplication by 6", + "public" : "8dfee48ad8b367488ea4dafcf7086e305356a80901f87c720149a5f522337453", + "private" : "00e099eb23125dab5ec35a419d455d0ba8c01da160f9354e9fb21e6a55d55c64", + "shared" : "45dc39831f3471d7466bbe29c8142b1a6d6b00c47fea021be2ffc452d9046806", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 384, + "comment" : "special case for z_2 in multiplication by 6", + "public" : "8f68bfc57d792c322ebb27f44a37c1c93e7eb15c5d5fcedffc1de850487b3372", + "private" : "b0ca251e0dbae7324a6ca0c2c8d6a888edd12d1447d400a47bcba004b648716e", + "shared" : "a29005c6b9dbf1707dc2adce4506b55831e8675b7d2d54b0c1037741e3bc611b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 385, + "comment" : "special case for D in multiplication by 6", + "public" : "ff0f15adeab334afeda3916785ddd38d252dce9876c2357b643b5dc2c06a3b1d", + "private" : "a8b64b8ed397773b8290425ca5c2f7c3e50fac7a4781bd4a54c133781c9a1360", + "shared" : "9f04e42c1b2f311d87e1470a4708bba25ac6ffd3f7b486f9b6b502ecbb2c004e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 386, + "comment" : "special case for D in multiplication by 6", + "public" : "1076fdc827f2550ee95ff9a15d044aedfac65b5e9ba809f62438ccea54637a29", + "private" : "d0cd0db51ff232afa0919d3106fcb3a8ae581ef12d09c877aa6f31ef74eed068", + "shared" : "688000bd60af375b4eeac4a7d0e0782c0e6188eabdc608b732f49b4d6ccab44f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 387, + "comment" : "special case for D in multiplication by 6", + "public" : "ed1c82082b74cc2aaebf3dc772ba09557c0fc14139a8814fc5f9370bb8e98858", + "private" : "204a3b5652854ff48e25cd385cabe6360f64ce44fea5621db1fa2f6e219f3063", + "shared" : "e0a82f313046024b3cea93b98e2f8ecf228cbfab8ae10b10292c32feccff1603", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 388, + "comment" : "special case for D in multiplication by 6", + "public" : "12e1589a34094af5f121c9bd3c1119f2b1f05264c573f667a748683c5633a47e", + "private" : "88109b1d0e7bace44d41a15d5bcbcd36968c5b8b47c0a2c606b57c4a68cc5f66", + "shared" : "1fcc50333eb90706935f25b02f437bfd22b6b16cc375afff8a1aa7432fb86251", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 389, + "comment" : "special case for DA in multiplication by 6", + "public" : "151f54a8a899711757b3b118fc5501779d621d25227af53d0af00b7583ba8824", + "private" : "5082e497c42979cdbfdd1b3b0653cfea6f2ceb7d07639ebf3541866bb60edb62", + "shared" : "fac30a74f4ca99f6cf233065e9acd826690cab364bf69320b58095783ed76e11", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 390, + "comment" : "special case for DA in multiplication by 6", + "public" : "a819c667ed466bd9a69ea0b38642ee8e53f40a50377b051eb590142dd27e3431", + "private" : "f85a8db44f9e56b11729f51682a9769fc504f93597cbe39444616b224532106e", + "shared" : "17f6543c4727e7f129ee82477655577635c125a20c3dc8ba206ca3cc4854ca6c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 391, + "comment" : "special case for DA in multiplication by 6", + "public" : "40b053d056668982a1f550be95e16348e303945f53a3ac64491a9a56d4095b71", + "private" : "505a076641fac398fc7d8c629937f42db559db5e12052ad366d46d7b20e95769", + "shared" : "889a8d611e0a7da71475e7c93a2d7f6f7228c787a00ee5cf55474adc376ff762", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 392, + "comment" : "special case for DA in multiplication by 6", + "public" : "e7dd0549a765bbef34be2e8da18a1bc1b989a8b0614d358ebf38c12a9ca64079", + "private" : "e8db2bf1af5b8907420789c56e71414706aef0d9f6ffaed0c249c3b7ab14bf65", + "shared" : "37232fb397af27f5fb5ca493284ff1c5d25786b0d716c73b33aca8d42265f318", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 393, + "comment" : "special case for z_2 in multiplication by 7", + "public" : "1ee1b9a74604ac31c3db83280170e3811504fcc78c7626b5b2c07a99d80daa0a", + "private" : "c006ab1762720882017d106b9a4675fdd47005657155c90ca61d4cbf7cc4f973", + "shared" : "a1b30418436ba1908804ffcce1be2cdcf50c61a8e3938d95c790abdb786b8022", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 394, + "comment" : "special case for z_2 in multiplication by 7", + "public" : "f226c2d6bd7831eda1b51ee5aec29443a507ef9f7a04e2340f349dbf14933844", + "private" : "d071807d607953da432d8574d5f3f420676dafdbc6a285a36e1d737624d77c75", + "shared" : "a5976fda89954a81e442107f9e416a2b4b481bbd4654ebc0c7b57a78b45b4979", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 395, + "comment" : "special case for z_2 in multiplication by 7", + "public" : "c5197312de3a7a3ee11b29873bae3fc8c85109c66784804f89435db210fcc24b", + "private" : "304b526f6fe994731980c0975529bca4d061017fbec56f6070d42678d3e11177", + "shared" : "55b5b5eb38b127617ffe00056d84d35a5071d18783e3a82b5f4e131b1538b150", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 396, + "comment" : "special case for z_2 in multiplication by 7", + "public" : "590ed0b879319c38a19962a5d216ff2bfaf33555518877969c20c054cbe43e56", + "private" : "982ddf2c035789379b8a58917d5c3c6c061b503b19a0028e01894c2eb371d079", + "shared" : "0080e5b9985a960a832133812a7ab9951c6b2c75894deb3e35509190a6bdf457", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 397, + "comment" : "special case for z_2 in multiplication by 7", + "public" : "7c5f0143a6682f60ccad16f21150c7bb5bc6f807254d08b353fc96ce07bceb6f", + "private" : "78cc3ec0687e3e53d9cec56b79d11bf049d173f127f5b40fae122a6d0016cd76", + "shared" : "5241222226638c4bbbc98792cdbd74882ca2e08aa2edf313070425031009e925", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 398, + "comment" : "special case for BB in multiplication by 7", + "public" : "010850a0974d3e89c029d252b46f739548294c0f9a23183863f9455b9559c211", + "private" : "c86fc76650cf3b58837aa0f0633560415241c6c4f8f293ba0222b7d6a3875773", + "shared" : "63788190b10d7451f5fc2b82c421151db4f3e22782e392da6d8d3aba2c344306", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 399, + "comment" : "special case for BB in multiplication by 7", + "public" : "ad1dd82c23d6a0d5fe0f2a4561d1c16733a3e1e6afa6d902dd077dc43a961628", + "private" : "888d51c0a2230369e5b65a814b3213dde2e62f2eb95d0971486b733e4f90c174", + "shared" : "e4b40974a166ac49ed831715c071c751752744b891465e6c45001855aacdc362", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 400, + "comment" : "special case for BB in multiplication by 7", + "public" : "d0c0d6393c41f4d7e0d5e850b7716f401eda1e028a4ed4a05bea8bf81acfd930", + "private" : "68bed425d534315584d80f79da6eab9b7e6036b51fe62e1ad933e266640b4673", + "shared" : "514a4cd0676f1c3101c8c45c17ad416bd33e20a405544fc1a60449abb22fa104", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 401, + "comment" : "special case for E in multiplication by 7", + "public" : "0f460100d88a1d316dff02d1b22ffb2e42d99d0b92474fc3ec7d62567d0cf112", + "private" : "98ff2856ef44b4fa14d86782ea793828bdf6f1ef9b669cac1aae338a7bb69376", + "shared" : "ed83e810ce5ff0868f8589623bb13478dec1c22326c92765ae5e48c84bbabb24", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 402, + "comment" : "special case for E in multiplication by 7", + "public" : "13756a411ff3ae0c39222dde0810f08c432463162d81ef061071249a48439e15", + "private" : "b0cdbfdd98bd988d7c6a530455c51c57dd33fd2c7aee3961971bd3a31388fc71", + "shared" : "ff94862117d3c6edc9dd5f4852fa8a589452b924ca8a75cb23b3d68dfed88c4b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 403, + "comment" : "special case for E in multiplication by 7", + "public" : "8fc1fae969a6185404db22749ef6d225de86773a4d1bf3857eb8fbbd829a1b47", + "private" : "e0677644ed4935f01e052e9967302d0fb78ff22bb92fbae0605f3ee54e2f6878", + "shared" : "1c94868bc8acb3137498209b2812feb53501389f5aa37fecbfd5cb54e1358e0e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 404, + "comment" : "special case for E in multiplication by 7", + "public" : "7bab0891ecb9e72a15771f0a4fff90547024206339c340b1a2fdb53bcfb86b59", + "private" : "887b61553843ca99ad1ca92253a6fe082b82494752513fd53ff6530f54c40572", + "shared" : "adbf3b439b16dbc653578f53374ed3a86f9c0bf1f736573349773bc3b8d60734", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 405, + "comment" : "special case for AA in multiplication by 7", + "public" : "102e95eadca7c3c28e5d52336c857bad99ea246f299b06334f401276f49ca814", + "private" : "00615e4697014fc12484ef53a1440206410a8df78caa0bfff82161db83fea574", + "shared" : "3952efb93573ae9ce2162d10e4b8c46435859f3f2778db89f72bc579e695cb51", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 406, + "comment" : "special case for AA in multiplication by 7", + "public" : "3548c16bf31afdcd445ad9bef0e60d7bd6195aa591ca8c82813cd7d446226720", + "private" : "58175113550faad56458fb375a6cb3f05df2f6ff3c4ee09d4a6ba643e022d17a", + "shared" : "96128f929fc03c1269d429f609a1a8acac7a758e3446a125ecf4a359a0e37b73", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 407, + "comment" : "special case for AA in multiplication by 7", + "public" : "ba74e766d44855ec93bd441aa41058a4c4ad2be63c639a3f9a87bde51eeaba20", + "private" : "009738e1e6efef9e2cad8b416fe90a098eb5cb0199f2df5218166c7b181ea079", + "shared" : "fec3e94cb5f316625b090c2c820828ce0f3ee431e8d6e12abccc7ef2bd0be81a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 408, + "comment" : "special case for AA in multiplication by 7", + "public" : "9a5a1d37e5010c356aa80afb347c3d613542ddfa0be7abb8e8cdcd6674411449", + "private" : "c82019159be792747a39f388ea48a8c568594e3383273e51100721b376e8ba73", + "shared" : "96903bac9dc60b6178d734890c25db4bed9ea4dbcf6fcbcdc90e6f5694c8b21c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 409, + "comment" : "special case for AA in multiplication by 7", + "public" : "630847e28274dbae5491210303c85a359074ee742957b0fc3c9ff55d9e019a50", + "private" : "10ac9f8383262ef280faac1e4da15a7de4f2cb74af33b50e0d82dcb85d8bcb70", + "shared" : "50050d0ab1ddd2dd90c460ab8f09e1f80e37cae57d4231adae10c10a4a2b003e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 410, + "comment" : "special case for AA in multiplication by 7", + "public" : "11749b00a45067af2c7e7d50f8d178d5a9fedb8f1b69b239763885bc611b136c", + "private" : "b84c098382f6e37d510cc33e62ddc664e02c8bb6ed9ed0e5fa78cc099a26fe73", + "shared" : "9170c4c628d5fcfd0ec719cf6e1796dab0a69e46d6379fffa247d444a0056041", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 411, + "comment" : "special case for AA in multiplication by 7", + "public" : "df1021d8f95950afde77c86ba5ee2f5876ef778376a7fdc7efb8dff0e4836e7b", + "private" : "78cde8930a1d81aef6601f71409728854987578b0f8349588c04adbe2c1f6e74", + "shared" : "d7d2a82953f680cee0c81c4d00fe628ac530ce682eb7fb3b0af24f804a58ef5c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 412, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "2743ba408d5f68c65324a485086a004b6bbf784cc9e8b1a7dbeb8c4b9414b018", + "private" : "b0fe7b06b9950600b3a7ce1d7bb2a1d984194cc9d6c8964504c364dd5c875b74", + "shared" : "a6b97da989dccf730f122d455152328051c8ed9abc1815c19eec6501d6cfc77c", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 413, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "cc275a2cdd9125e52f20ce2abad41f920afa5a643fb7f276ef416f761d689f1e", + "private" : "f0c9c3984854d5bd599d3819738a023eb795e93586dc0e5e29b1c870c612d178", + "shared" : "b210e368729501d9f9b6ebefbebae38f195f91eaf2a5a3a49288bb615ff2216c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 414, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "4929543101ee7ae239059cd134c35d400e50d0821441351d0fa6c3d54efb342e", + "private" : "906c2f12be89702db26fa7ee905ce36525d2dee4e96a879ca07da097a6aa5075", + "shared" : "b9e3796c58701ded4237c52994501cee14e18f2fb02b781a8400923484bd4a6c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 415, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "1324e0368597b3181555bb5b2cc7b7ebba46931aeabb6f05ababd4240f0fb933", + "private" : "f026031ea373e1d16e6e7e0357bc96bc093f4b6bb76a738cbb54fe6cfd2ea271", + "shared" : "6dcdf8e86903b0caded124d8a7da18e623430ca869aaf267d31029d93de99e66", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 416, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "c7f3842297d6941cac63d6f1bdaea0709437c82dbc9161fc1bae6c79d668eb44", + "private" : "703f4ac8667d77f9536045cf748f18d42345e39ccab10c18dde0f5170d307f73", + "shared" : "385ddbf2505ebf537bf5e976b61a4b69d190ae965b7e4a81ae4e1c16b7148748", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 417, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "1e4660ba865fb8085afd4692885d74237fa3bca5af4b84ba3de400f16a5ac45c", + "private" : "c8a96ae4e77271a0680dd24fcb09f9c5d3ee8316536eec7cc2276597e50fe37f", + "shared" : "0fbaea73f9518795e026c1fc1079c3738aeb9ee9c8dc9761d65bbf8f94e30154", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 418, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "2488bb6fadb79d46585ff01c160c5b4172799d92bd168edceb65cededc492762", + "private" : "d0dde8eda38c3783442864c0cb46a0e9832dcf784c21268a21bed2cace87cd70", + "shared" : "510c64151e5d0737fc324bd15fb5d3966908751cd1a06954b556196655ee5540", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 419, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "a0c1087811af1491171bc51691b8ca84716af36c4baa764ec536280cc1983d6d", + "private" : "c09cd47e1ce53604f14e4e13426c8f08962f556bcd81f8d75375b1507c6fda78", + "shared" : "23ef825e1c8e6e64428001a7463e32a9701c81cf78203e6ae753740c91570e6b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 420, + "comment" : "special case for x_2 in multiplication by 7", + "public" : "cc5c97934607d8b981bce1d6a232bb3aecc3001f698ae1ae84938fbf2861077b", + "private" : "e09a5f74f318f02303857aa0208d76913d9e240a80549d12013118bad620597f", + "shared" : "0e55a7ec1a2ddbea1ac5981200812232f7f4c3a60ee3c9ab09f2163bd13da329", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 421, + "comment" : "special case for DA - CB in multiplication by 7", + "public" : "238de7fcc8a3f194c3554c328efb1215d0640ac674b61a98ef934ec004cfd73b", + "private" : "706cee5f9b357c03b2f1913294f6e4f0ca5a190a87d30268327d0cb6bdd5bc79", + "shared" : "0681036a0d27583ba6f2be7630613171a33fb8a6c8991c53b379999f0f15923b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 422, + "comment" : "special case for DA - CB in multiplication by 7", + "public" : "ac9fd80a45da109fa2329390e5a951cfc03065d7bb4a7855826ccb22c3bfeb3d", + "private" : "40e300cb1ff260574f85b3f04aac478464a86e6203b3d4656418f4305157877b", + "shared" : "67b88774f19bd1081d6f23656a135803e34ae1cdcae10818124a78569c299f42", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 423, + "comment" : "special case for DA - CB in multiplication by 7", + "public" : "a45ab1dc2fa2c50718fb4985d9791401e8d2d34ffe3cd93cffb4e870cce5e855", + "private" : "882f78b4558b7faa835904c9235e32f300fc8b5ef0a718406a5c8520ca54d071", + "shared" : "a512e864bd898a5ba6551adcebd836c6a78e7871728e1b8ee528d483af276104", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 424, + "comment" : "special case for DA - CB in multiplication by 7", + "public" : "1761d3d50ba46b446655aa6a8d9b8b75aa5bb24a7953208d5b69fcc38f18ec7a", + "private" : "d8649b735590a17d0fc4c378fbf4c2f7d6600569b2e84cbe0ff7bcdbac0b5f71", + "shared" : "518b778cf5e976c60235abcf6211a18bad2a8e693ab261074c7fab43dbb5da27", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 425, + "comment" : "special case for D in multiplication by 8", + "public" : "dc99ad0031463e4537c01e16629966d1b962c0b4e4872f067ca3c26ccc957001", + "private" : "a8edec59ae6ba23813ec54d66df152e0626762b97d4b0c20e0dd8a5695d86e47", + "shared" : "6cfa935f24b031ff261a7cd3526660fd6b396c5c30e299575f6a322281191e03", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 426, + "comment" : "special case for D in multiplication by 8", + "public" : "b32750fd80d2d7c62c6b8e39670654baea5719a3e072e99507fd5bcb23898264", + "private" : "1098723ffe567ea6dcc8d04ecc01efafeea0aee44e1c733be8b1e5d97c8b8041", + "shared" : "c623e2d2083f18110a525f2b66d89ed82d313b6a2dd082f6b7a6e733134f5a06", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 427, + "comment" : "special case for D in multiplication by 8", + "public" : "e7b3205777b375f1b1515a50a16a6067953ff221e12b4f416d74fb28c1c85865", + "private" : "a0f20df98b49218ac832f26fa8c218a0d6872eb7aea07c1d43c9ff699b465b47", + "shared" : "388ea421650a8d837bad8904018195e99ef494c2d170b93ee721a67d2c108729", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 428, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "21cc338d7869e5863349cc739c8a6946cfc797cb82fbf62dcd2154844b106003", + "private" : "30473a77a98374f67d5bd43df231ce142916aea0d271e72333fa47dc441a0247", + "shared" : "b9e5728b37435b1d339988f93267d59f3bd1c517851c5a258e74cb64aea73d2d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 429, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "c34217c02072d7e2bca0454525030780cfb60215d7ca82dbec8f4a59034c5f43", + "private" : "d8657be3a30fc85fb2f3a68e92ace1b31b26e76e6bdb6727aea507cb7c10dc45", + "shared" : "20b67b205e22ce87fd44a8e8fd10a6d8890b9270b60e1c6a68b4aa78e6e37961", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 430, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "8abb8cfd60c6f8a4d84d0750d3b40a4f846b30edf2052fef7df84142cd0d9e47", + "private" : "882f5578ae4a13d8f5af473bdde1709bf2e059df809ee05b505f34de857c3447", + "shared" : "5faba645fc21f9421ebd35c69bdb1d85b46f95e3746ff7f4886bc280a9ab2522", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 431, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "9fd7b49a08f206688d72db737df8e517aa7b764f5de7c9a2b1c3fcbaa985f64c", + "private" : "98294db7cbf4958bfb3ed21d5d5c91e13cc8dc27b3c716c86f7167a4819f8741", + "shared" : "9cb8a0f4ad86a27b96ca61242eab198db2767d3862dd323e41368fcdcc5fab68", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 432, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "c4fefac7acd448e8fd4d6ac4f5dd1bc21f2c67d638444060918fb344aa77e757", + "private" : "789bc4047ad81b9b6656eef298b766e8763a2f8ea64e374a603dc1fdf2eee146", + "shared" : "4b42fcf84b51b2b82f1f70b3cf49bd9dc6ab2672920a8de37e81ba7e99acf734", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 433, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "a8341deecc0be6db11401ef7f884ac3ade35650cc21f14b5cdb0a5cf0ee6b15a", + "private" : "801ffe4e0f6eeb8a50c8fe79663ff585f9d6aebcfbf4b7edc676c693900cb141", + "shared" : "e55fc931669bd02d1c64689eda62648212b1078c43b5caf97cf9763ff87a3455", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 434, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "55a0e6631a52f29fb90a1777ccbc69ff94547459d541f72e8316e4d616535a67", + "private" : "e04e412383a63b338b70e1be5fd75995350321dee428aa4f3ba62a50a3b0de44", + "shared" : "87f7976a17f3e03a7f1eb74e6db950b8c0994f40b7903495599d227725809e01", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 435, + "comment" : "special case for DA + CB in multiplication by 8", + "public" : "7976d520f1a2512d564af41c68313f5351b0156d5118be4817f192798ae9777d", + "private" : "382dbe9f10158bfbb7d1d79a35a7809214899a6b8572b35b55875d79bd2f1640", + "shared" : "3bb3e30105a71901b115065e39bdb3e053d387b39027b12c92cdf4c638adf00d", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 436, + "comment" : "special case for AA in multiplication by 8", + "public" : "a26a722f7ba71ccfc96ed8e108d7c9f842d17f92051ee7d429ea7fa7908ab907", + "private" : "60c9af7f4d03136a6034ae52deadfd9d4f274ad8122812eb92a53169c8354141", + "shared" : "f5cb3a1b76185a29a6360b2142feebb11f3d08f4fd8d73df3a5228624a521c02", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 437, + "comment" : "special case for AA in multiplication by 8", + "public" : "ca3a2d96f5dda482b002324cbbdcf1dacc9815eab797c7151c3a88c75cded621", + "private" : "283fae8bd8b294de2848056449751965abb5c7fa86ba4c2c5cdc3bb524dad140", + "shared" : "b0b47868e70465ee2dd737f1ba5a6399e09cd813d72da7585ab45c946cc28d4d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 438, + "comment" : "special case for AA in multiplication by 8", + "public" : "eebd858850b56febb707f27a7aad5ff5ab4b0e0c73b9c86ec4ca0f42e7f38e75", + "private" : "401539703ca4980db4ba42c59fc29e83b4189f2ddea53ba54ca966c06898a640", + "shared" : "581e4b12b0f39a7cc42dee4513ecfdd20b595f905f17ad8c1fbf1b5cb2068b31", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 439, + "comment" : "special case for z_2 in multiplication by 8", + "public" : "c800bf799783275eb93312b43dc032ccdfb00a4b77c8b3772cd2fec8db7e4a09", + "private" : "c8eb056286e098e6b2c79e42f007ebc6ab3705346cdbdace949b5de1e8c36743", + "shared" : "6bf264532fc70a6a7e459f4579eca6b84f8f76ab85c3264b20bca725a6eb6c40", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 440, + "comment" : "special case for z_2 in multiplication by 8", + "public" : "7bbc504e04d134eedc13f06dfdfc69c518257a3f374040a49a8d21dac109110c", + "private" : "487882956c49c69fd0e2d7277a24fb1dbe4b0365b36a13f63440248bca2fbb42", + "shared" : "690305c9e192cd8a513f705b3f101ecdf3db1ea15a09c4a1bce3a8cdc3a1a93f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 441, + "comment" : "special case for z_2 in multiplication by 8", + "public" : "132533db62aff4fa06e96314383bf58ebdec5183a19f2e4cb17552ae19a3366e", + "private" : "9876010f4d64c77ffc4d7dccd72b9ac82078deb883609650b8cff8a686719d46", + "shared" : "c58591b33e490e4766ff7addff570ce4e89a98338015a55df3d2f232aea3fc4f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 442, + "comment" : "special case for B in multiplication by 8", + "public" : "ceb90c56508cf330c7f25bab42b05b5612a8310690107ac63a404c0ade788009", + "private" : "a8a5d4f7894a519537babfac736de36054f508dae434b4fe63cd5633846a2647", + "shared" : "3d145851b6ff2b92b5807ed1df21eb50c9f24c4474d4721db3abb7356df7b764", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 443, + "comment" : "special case for B in multiplication by 8", + "public" : "66a09767a0d83bb18d404e1200375a745d1f1f749d5dc6f84a205efa6a11bc65", + "private" : "f83e4647e82c560aa082c59641e13bf366be8f24dc01d14801e67841160bed47", + "shared" : "1401829aac4e64bcfa297a7effc60477090d3627a64a35b872ae055d2091785f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 444, + "comment" : "special case for B in multiplication by 8", + "public" : "39d431316307c85747bd2bcf4f9e0f8892ee45df15f7806ce65147d97f503478", + "private" : "58c6b94bce9b15f64946c2aa6a4e383b0b2d4365b7997eb2310ac4eef1803145", + "shared" : "a0ebe6908c5472f937769b9aeb313224437fc5d73f4f866fe7ef41f30e359e09", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 445, + "comment" : "special case for C in multiplication by 8", + "public" : "84c92d8ecf3d0cb22dde7d721f04140c2d9c179cc813ce6cf8db2dce6168880d", + "private" : "786a97207adbd4b0d6bfc9f49b18660ad3606c12e325044b8690b4fa07874641", + "shared" : "07538f1b6583041c4949fafae3349d62f9dd302d3d86857af0dedc0d5ad6741f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 446, + "comment" : "special case for C in multiplication by 8", + "public" : "a9cedb9e942a47221e4296953220d10007db327d2acb68da6ef3a4f877b8ef1e", + "private" : "282310210e575a59393cf19bbe6e24752dc247706f1e0031e5d39b2de4fff745", + "shared" : "1223505fbb534c1bc6108e6b98b4f0af29e11158c02d333d6559beecd6d3e558", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 447, + "comment" : "special case for C in multiplication by 8", + "public" : "64e1c0c5f59405bbc6c7db41a3485cc9f91c183b0f2b7e1894a7abd8fbbeeb23", + "private" : "c8bf2fd4c40d00f1465aada682b12fa92dec10343484ab62b8871337de1d3345", + "shared" : "ee031868165f456f75907bf39742b820e0f8e6df9f9768d757d408e1cc92ff7b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 448, + "comment" : "special case for C in multiplication by 8", + "public" : "a68d2f55e60eac7983926310f4fae13f95b2bbf140be5ea91751884d900ab44d", + "private" : "c06a4a4b70f613136f18c0f88e2245086c3d1a52717210a21ac9d63682f2e740", + "shared" : "c954fa7b042c32943e03191e367d54be0085fa8950ef2bec99620df79ecbea4b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 449, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "6d3cd623f26a7453fa05a01ae758ba84d3c58d93d60ce32735a15e0d053d5b12", + "private" : "20596e1dc56596823d37698dfa699c79874aaefde797f863ef92135980fb2043", + "shared" : "7c3219b3c1fae1f95590ac843efd2084a1f4bd3efa2f592f022032db64ebcd77", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 450, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "8f195547346b3d53b7ea4f742b22f1ef7b3cc01a7d3dcd19aa7c5b03f31bd214", + "private" : "38141518e8e5efa1d031c6c4d95480239f6c30b8ccd8c751a9e04bd3aec17342", + "shared" : "a31f6b249d64a87c4aed329c6c05c3f2240b3ca938ccdc920ba8016c1aeaeb45", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 451, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "ffc4fe2c2127a309c739565651e9812f834a86dbadbb78776977f786ecdb0217", + "private" : "207147f2b68fef1efc10a04f988f0eb18b273b0b5ed17aa7af32c90480e19b43", + "shared" : "4cff9f53ce82064882329a18ea4e4d0bc6d80a631c87c9e6fdc918f9c1bda34a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 452, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "8475babeeab9980d426abd5323dfb335b219e129bddae4d6cebcda50754a6825", + "private" : "488084537b840f9c93ca57b3ee80491418d44221113e03f56355302604d03547", + "shared" : "248d3d1a49b7d173eb080ab716ac8fde6bd1c3ed8e7fd5b448af21bcdc2c1616", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 453, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "81f90a2f6633d30c2b72a25795d2a49463a80b6b0edc5aa68bae4bf738185539", + "private" : "28cfc1d03f5c7428ff3e20b137268b33ccc74db03582d2127c566df4ac99f441", + "shared" : "66c6e70cf630be90a2c88fcde7f58cff3868660fa96406e8df4ac677dbd85f50", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 454, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "41626e33b3c8f48bd19e49ded307f2b63bde705c4f3cdf9d4f92bf37c48cba42", + "private" : "c8e37d10f3d03db3f43e467bddf98f595cb529ad253c20d491282d1400b9e740", + "shared" : "06283fcf69dc83e99d92e5336f499a1d8fa75ed2c819b5ae6ea8094454324b27", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 455, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "ebb32f781c0e89b252e611f9d8f79f8567874c966598314b2f16aa44cfc07843", + "private" : "00237e91406a7b4db61e780c5976fbb926cdace2fbdfdbcfce65e6dbe7782a42", + "shared" : "7d2affb43355f5db1294daff55f59b1f17e7d25bca20746f12484d78e5015517", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 456, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "fa75e6f08ca815b4e42af24a8e057c9e00e828e33d12c0e94d1012a758336744", + "private" : "489c4184a23a8f5eec68a31b41aa2c0392cd6fb123f10acdb4de75292b4b9a43", + "shared" : "ef8e78cab091d667888489fd3a2ec93fb633427d02eb77b328d556f2b2b0e266", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 457, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "4d96320cdb0ca52655e91118c33f93afe4ae69e9e513ff4506750b8ea784ce46", + "private" : "c05957fbc3a0e2c22a2aef627651ca1e99307b82a0c6170f7950a334f3004941", + "shared" : "c8d85bfa74b4b26461297b350c975183fea9d33ba29c3a4934509c2ecda58a79", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 458, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "c0ef1b7c20237db370501f24274e4eba91998ae4545f937007e1c4a2eab63365", + "private" : "60111c6629f73635985be964b845f87a88ae5652d45bb1451ce8cfd2ea45fe41", + "shared" : "22557e0d8741ed2a63afd5e313aa1579fc0c88c7772e23a676c94b60c89df577", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 459, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "d534d8ff4d56a73ef7615e94523b17e35edb3d0fb87e98c68536f63f114a8d6c", + "private" : "58785889a216d15456582d4e1e3de9e9ca4a432954416d81caf52b2b434c1746", + "shared" : "54d7fc17bad00296ba50b0f3d5bf8fb83f82d571952a5fdb5a494120cc61446b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 460, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "733a711ba01b6e9b64a0be4cdca8c7cf3c66df2435d5248fb4413fec6ee03f70", + "private" : "60bef38a3890ec1ed05c299fceb77db5ead4b88d9e931b0f21d664f77df9b544", + "shared" : "db6851b12585bc11be9362c96a545c6f2ba55f04009792463b96a38cb9b3f07c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 461, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "35738dd539d60f69cd1a1cffc8a42b6af68fe7de45392d02831e2a77500ea278", + "private" : "5854ee566878ef8b7ebaf5a058306f250edf0c84fd52af2d74b7ce3c1edda746", + "shared" : "f6d1a664257fa5de3d4d57f04eda2976bf1e35cc3ac513e1ee84d57d2135ed13", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 462, + "comment" : "special case for x_2 in multiplication by 8", + "public" : "ce932b5af4be4721f96f7b79ba1c43b20687d4af49c37b58dc894279e04bb578", + "private" : "985b551261fce38ddc8ff3add32f5c26811d271b9a1794e249dd76a38df28446", + "shared" : "f8f7625ac5bde63f753a9bb4aefbfb9c4647207708af9d774ef08ff1b1e5a354", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 463, + "comment" : "special case for E in multiplication by 8", + "public" : "e3655448339e4850806eb58abba0c89185511ea72c37c49e9583ee6dd235d213", + "private" : "8815052344dcad97efd1341e9072a808cf999e46e52cf04e0cfbcd9901e18d43", + "shared" : "5e10dfbff4443efcae2ccc78c289a41460d5a82f79df726b8824ccbef7146d40", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 464, + "comment" : "special case for E in multiplication by 8", + "public" : "4d16965b1637e9d7ae8feb499ed0553962a9aa0022d1620c928072f6501bc41b", + "private" : "b8e032e9e5ffbaa004390f3a0b900bc7cf5d11238b7ec964afc4bda2aa6c3444", + "shared" : "19d7b44c1847c44e8f37a22ab69c180fd9d787f204123013e1b16800b9cd0f57", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 465, + "comment" : "special case for E in multiplication by 8", + "public" : "c6b9e6288737ad40452cec1022871d90af1642d10bd0a97792b1a9c8998e2220", + "private" : "7012852211f6536fca79937e7e316c9149b0e20ea03f951e1bb072895ca0e044", + "shared" : "db990d979f4f22f766e7826d93554e771b361de461274d6c37baadeb8ef7be4e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 466, + "comment" : "special case for E in multiplication by 8", + "public" : "d566fab505ac4c7a3dc3b9403ef121392cbbe21216e5bcb8eab2dc9408986e34", + "private" : "d039c1b9ec4763e0ad8a0ef2b0870297d0f8b487e660595a484105d180e14a47", + "shared" : "6d7fc5d4a8f534b1bc0fa5e078104234675c02664736957abdb27df6faf07c00", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 467, + "comment" : "special case for E in multiplication by 8", + "public" : "468d35ecfb6d9b7272523276cc5e13760519667f0e1e3888da4c56955fe91151", + "private" : "58efcbc8777c1b54f09c61a216efd427292eb12312dbb3b32bd45254a6683e47", + "shared" : "539c8d629ab51c2f3ea7278fd5f1c31b6c150a82fe3f786b93ffa159fd6d9316", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 468, + "comment" : "special case for E in multiplication by 8", + "public" : "1929538743977dfea20bf4927ddabb2f3bb15cac2461054508849718854b5568", + "private" : "c8d73446026cd0ea795773c2eb7b16348cd5f228e352dbc77328c2d8b9cde240", + "shared" : "dee3fd19c8f296415448b21af44385ec46727bbe67d4839b93efe2f680e76d34", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 469, + "comment" : "special case for E in multiplication by 8", + "public" : "2d7ab4c6f59865355ee8e9de57db19aadf7708b7c1d1a818487c340623badc6d", + "private" : "98b559523bc778b0418af53c0c32f6ff5cf771ff5df8ae7cbf7c3b72aedb5b43", + "shared" : "2a0340aaafa05d00529c09057ed0145f34d2de66a3e149cf084ea97168914f39", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 470, + "comment" : "special case for E in multiplication by 8", + "public" : "43839f4a6aa206c82c5a73f49d8c9e573826b3ba7235d312987c17aebee62776", + "private" : "589815027caf82714e96c9f91bace66ec4ba3e92df3fa14b9b8fe503556e4543", + "shared" : "00313717d33e3b41a0865986157582e053502a172b88d01bb7b10831a9fc4e6c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 471, + "comment" : "special case for E in multiplication by 8", + "public" : "3c321e7f0b9e555bc264a2cea617e6b2b562ebab21fe0c226c3e487b7df9a27d", + "private" : "80715f67270c99789855ceaea99b9957ccda33326f76bb4474ab52ab1ec37041", + "shared" : "9b6be9e6f2fdb5d3321842225d3e91d14828cc53ba6654dabe190b0c3edeb309", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 472, + "comment" : "special case for DA - CB in multiplication by 8", + "public" : "42e5a6b8e9654bb4ad624af3f491877977513cc8775c8fb312ad19dbf3903a28", + "private" : "101b990bd83d684126ff047d930c27d086a588dd19683d2629f0e34f4374ab41", + "shared" : "223f1eb552308373026d11c954684ce6db870b638b190b9443e50aae219f4e3e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 473, + "comment" : "special case for DA - CB in multiplication by 8", + "public" : "0a51dd90ab985f6deaf72f16c45014da26df848697f6582d75688f5223342b51", + "private" : "200089b712d9a2050597779d463712fcd223e3d67879c0fb7606f8f5f0efee40", + "shared" : "fb95ce4a3c1f325638b7d47f4216d39a7c6c5da9a01caa297c37b62816555b2a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 474, + "comment" : "special case for DA - CB in multiplication by 8", + "public" : "8842317357bde825ef438a1c53906fb8b04ea360f7ef338c78e668586047936a", + "private" : "f04f87f4e623af4c31ceca0bb87fac2d5b12517b5a7284902ad75838e65f1e41", + "shared" : "488b8341c9cb1bbf124510b9f8dae4faf2e0dca9b84e00e952a63b5aa328a860", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 475, + "comment" : "special case for DA - CB in multiplication by 8", + "public" : "c71d92d3c92dbfaed755fb32797b667cc86b0e79362498e2aca38c689713b16e", + "private" : "383cbd5a3dd0901d09a3cac3d3a77a979cecf15e206a553e4ca3f24b90783945", + "shared" : "1129eae97bf75f7314f2e1b403b18737ad830c80429e2ba0d4866b362399855f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 476, + "comment" : "special case for DA - CB in multiplication by 8", + "public" : "3a21d1cf7b3744d1ad26197335844982c2a0c6a5aa835492bd03c401a4fe6778", + "private" : "701df09e57b98aec375745df147b72949a6b2bb2ca3a34881512ee31e790ad42", + "shared" : "072f51d94727f392d59dc7caff1f4460452352ec39c32a1c9f071e388833da56", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 477, + "comment" : "special case for CB in multiplication by 8", + "public" : "d128ea3e13325ed6ebd6533a9fd3045a55f25ad8b67def30912843504c1aab29", + "private" : "b0ffa5f4922bb117ad75ff43acac62331efaa45536fe88306e4a4cb58db73a47", + "shared" : "30512142d3e3a4cad6726d9d35f2e043fca9dfb750884ae22b2547c840f3587b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 478, + "comment" : "special case for CB in multiplication by 8", + "public" : "e079c8f8423165c7e0a2c48b4abe90aece4e6d903d7a5a1625fad0410cd55b32", + "private" : "685e3271d2015741756612a930e858b930acf2018145f382c83d8cced2e22044", + "shared" : "5b81b3761a66d199e8ef99d2494bd57a0229d4564a7f6d6055f22aa48681bd3a", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 479, + "comment" : "special case for BB in multiplication by 8", + "public" : "65922a06e9be4e8a5e8aceb1a4e08fe90f01e10ef2dd27315427cedfcf95ec32", + "private" : "f8e161d69297e017d7c51b1b1ff3ba703d4c4cf8fc2b8ff47f74c3ff8c7d3541", + "shared" : "038de7fdb9cc0030f5c11dda00589f0a95f65658815b06ed013553a02b6c5017", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 480, + "comment" : "special case for BB in multiplication by 8", + "public" : "d36a240e972dc16e9b97a997ada337f02760d05c46d7f8d7b4e9ea9a635c7c64", + "private" : "105d7589f8abef0acf0940da84a69e8f2f306fa73c9afd27342287c1dba80044", + "shared" : "22b0dea3b3b7ca55eceeaae6443426548c7c15cc7ddf31780318d1c23879c16a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 481, + "comment" : "special case for BB in multiplication by 8", + "public" : "4f5b8b9892b8a46df08d76a4745b1c58d4e7a394905435875688ca11f1e9d86a", + "private" : "1893d4388b0e90f0b50208aa8f0cc24f576d03641baf1c3eddb2a3efa69c9d40", + "shared" : "a25e1306684ad7870a31f0404566e8d28f2d83d4b9497822c57f8781b18fec20", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 482, + "comment" : "special case for BB in multiplication by 8", + "public" : "aa2f02628269139a7a8a16fde95c9bad7da7ffbd5439c396a7d77b6c3213e67f", + "private" : "0065171301bf6b90fb16efa35509161f1bd6b3b93130d490af9fe224dd155f45", + "shared" : "bb4431bea7a5871c1be27a2674094627eaaa4425c99cd3fa41bd7e13cbd7bf7e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 483, + "comment" : "special case for A in multiplication by 8", + "public" : "d995cb287e9a9c5791f3cae3d494a5b516a1e26cbc930f43e73c8b70b69d783b", + "private" : "10c81a4e78d82145b266e1d74b3869bf1c27427803ebb11c92ff8073d1e4cc46", + "shared" : "330f5d0b5bccc90f7694dfdd9c6449a62d93af8840eaf571e3e0610e0198b03f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 484, + "comment" : "special case for A in multiplication by 8", + "public" : "479afb1e73dc77c3743e51e9ec0bcc61ce66ed084dc10bfa2794b4c3e4953769", + "private" : "48b98b4a99eadd73012c07fe5c4a0b9590ac55e821353b41d5f665e17188bc41", + "shared" : "bdef00caa514b2f8ab1fb2241e83787a02601ecdff6cf166c4210f8c1ade4211", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 485, + "comment" : "special case for DA in multiplication by 8", + "public" : "378eda41470b0f238a200f80809ad562ca41e62411a61feb7f7e9b752b554642", + "private" : "1897678e38222a61fe105dc6643c1eb5940e8dbc73ed6c00f25a34328f43a641", + "shared" : "bfd5b5acd2d89f213a26caf54062f9a24e6f6fd8ddd0cd2e5e47b7fea4a9c537", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 486, + "comment" : "special case for DA in multiplication by 8", + "public" : "0cad7545ade2fd93fcae007c97648348f26d85829bdb7223a63eccb84e56d475", + "private" : "a898af8138e11ae45bbcefa737182a571885f92d515c32056c7cb0d7deac4741", + "shared" : "c8085877800c175e949cdd88e196eb9c4841da2ac446dfed9085bda5bbec265d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 487, + "comment" : "special case for AA in multiplication by 9", + "public" : "60f27ed0a27804ced237cf3c1cc776650fb320bae6d5acb564e97b56cba25210", + "private" : "b0bfef6ec095b5a1f93917d32f16a21d0462c1fde17446f5a590232d9c895f4a", + "shared" : "4c300895827382a9d1079028bd6f694a7a12ddac9c76abac6fdf5d29457a3310", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 488, + "comment" : "special case for AA in multiplication by 9", + "public" : "f93a73270ac19194b8e4ffd02be4b1438525f84a76224688ea89a9dd6a1bd623", + "private" : "60497d4464ed8823c50fbc6b68620826c4f629c1d9193058df6bf857c6aecc4b", + "shared" : "7285fbb3f76340a979ab6e288727a2113332cf933809b018b8739a796a09d00b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 489, + "comment" : "special case for AA in multiplication by 9", + "public" : "cf80c30fcbfd535666ca1da499e2e99cc537063e2de19458fcf92f5ee34acf47", + "private" : "08c6cbe03792a3829f06e8ad54c55db113236ac0dcc9ab6a9a6b10eed1041b48", + "shared" : "dabc3bd49f19cf7071802e43c863ed0b1d93a841588098b98a0c581bf4fe0a11", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 490, + "comment" : "special case for AA in multiplication by 9", + "public" : "698effe0ad42e15ee1f46fde6fc5074ffda183bcf1b2db8647f561ddd191dd60", + "private" : "50044da3315dd082e9dfb6a1994aabb331f53e0d1c12633383b2a3c8678cfe4c", + "shared" : "a61a3b150b4770532373676298c9a5da28adcc4365b06fe07c959ca80e477a57", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 491, + "comment" : "special case for AA in multiplication by 9", + "public" : "bd1565b4a3f8515dff577be6dcb414511d3d4ec2de15e0bd45b28e9cc4caef60", + "private" : "285640da7a48252e35ddce60c14addb73097fbc9ac2f87c8d2772ce89aa6be4d", + "shared" : "916ab4f3bfc8321e1087d9c5444f8f7a43e9ca6d29e7ba98a19dc05fff34ed4c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 492, + "comment" : "special case for AA in multiplication by 9", + "public" : "b8649e13843f80cf5702398e4a9a8c378f29da96dfd6579f1eb4f7ea34df6765", + "private" : "783271c21199ba2e94ead92cd9dd79f70aab378b59497455d327a5907dafcb4a", + "shared" : "844a5dd5139554ca7b41cbe6a4796193912e7aa4e201cc68944ce2a55774a10f", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 493, + "comment" : "special case for AA in multiplication by 9", + "public" : "c396938737abdf791e09a97eba577c437d9b67c2dae94e13eab7296ec0fc737e", + "private" : "d0676a0b9a046c62d5b2e740d9cc43fa37965dea93c23254f7bf569f2bebaa4a", + "shared" : "10780333b2a6170136265bb5ebc6c818817f2e48ae372528c8f34433fdd6215a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 494, + "comment" : "special case for DA - CB in multiplication by 9", + "public" : "557b825012d98f065bb95a2ab9b2d2d8b83fd2037912508c263f86d7e36c4f24", + "private" : "608c84d2b76fccda579e974db3d3b2ce39a6bc0dad440599db22411b60467849", + "shared" : "5ce84842dbae8b795b3d545343558045508f271383bfb3dd3943f4101398c864", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 495, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "ae98296d4a2fbcbb40b472f4063231608bb1465c226c8a4a2dff29afd915882a", + "private" : "80f233936a8821936d39114c84d929e79760b27680779e5009e1709410dd8e4f", + "shared" : "4f11aa0c313195f96f25cadcbf49f06a932d8b051879ea537d1c6dfee7f36d35", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 496, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "8b9d249829fbe81333d85050da88998f63fac665679e27dbbe21b745dd14e145", + "private" : "c8d80b1a34f21194f047a6f0328bb947e2e7aff6a043553aa07f2abf99aaf048", + "shared" : "1d619070bf5626064be10025e74e336c81ef3166b743f99c751fb90587c31d7e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 497, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "61896093e2697c78230afdda12639cbe4342827b8d2b093281f148eb60b9034b", + "private" : "9021477b452361580059364c6f94f4981ee94ea3f9b7d37439bc82ae45816f4d", + "shared" : "532e797861db56b9d5db8825fb72f8629c2422f8abea721ad2d7b9e77a95b576", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 498, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "ccc1dc186229dba9a9360a0f7ff00247a3732625acaacd18ea13a9a8b40fac4f", + "private" : "6079dae04c40a59ea4e0c8c17092e4c85ea9133d143307363487836df4e30349", + "shared" : "4f678b64fd1f85cbbd5f7e7f3c8ac95ec7500e102e9006d6d42f48fb2473ab02", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 499, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "69e368c0b7e78eb9f3a53bf458f6e79dc4883bf9458f04a8c12c4ddd94d62151", + "private" : "281db6a5ac9a47d4a7b2b91a87f6536ce62d4e5129b8d647b97f9c504014894c", + "shared" : "e069fd06702f10f33adb8cf0766880634865b510e2da409241fb5f178050514a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 500, + "comment" : "special case for z_2 in multiplication by 9", + "public" : "f21f9badd98dd8a103cc2ab5484fac6c2bfdd2671ee6e674134a86b89cee9160", + "private" : "d830f3c4785829a0f945857e0e85e0ae723702b57783b933cd2a2ad05484fe49", + "shared" : "fee218eb1f92864486e83c1731f04bb8c7e6d7143e3915bcbf80fe03ff69dc77", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 501, + "comment" : "special case for E in multiplication by 9", + "public" : "e853062b2d6f38d021d645163ea208d0e193a479f11f99971b98e21188fd0b2c", + "private" : "10230bd0721f4c8c4b921881dd88c603af501ee80e2102f8acc30cf8b2acd349", + "shared" : "64bdfa0207a174ca17eeba8df74d79b25f54510e6174923034a4d6ee0c167e7b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 502, + "comment" : "special case for E in multiplication by 9", + "public" : "362eb92dab9fb29f7ed0e03843dcc15797928c2b4e51ec260204179c1c12945f", + "private" : "f0a34d6d76896e17cb8f66feda23115ffb96f246b823bb63dec08335787de74c", + "shared" : "d7f4583ee4fe86af3a3f1dfcb295ba3a3e37bced7b9c6f000a95336530318902", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 503, + "comment" : "special case for E in multiplication by 9", + "public" : "ff543f1e81996e88631f030ceba7e603b13033efd205e68bd36b28468134aa73", + "private" : "9073c1d0a173c7ff02dc966a165993d9c4c9357514f7a6bb7aaa4b0827718948", + "shared" : "c1b5e5f4401c98fa14eba8aafae30a641bfd8fb132be03413f3bf29290d49e0b", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 504, + "comment" : "special case for x_2 in multiplication by 9", + "public" : "90ef70844ead1613f69df7d78c057813f866c0d95e6d22caee4a012b9c1c4b33", + "private" : "b0c1822566e016c12ae35ec035edd09af3cb7a48f55c9028e05e1178a8c3824e", + "shared" : "9369ebb3d2b744341cba77302719a4b2d63aff612872f86d9877a76bc919ca1c", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 505, + "comment" : "special case for x_2 in multiplication by 9", + "public" : "88c1ae575ad073dda66c6eacb7b7f436e1f8ad72a0db5c04e5660b7b719e4c4b", + "private" : "e06fe64e2117796f997bbcd3bcad3067cf1291640a3a643fb359809a4016834d", + "shared" : "335394be9c154901c0b4063300001804b1cd01b27fa562e44f3302168837166e", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 506, + "comment" : "special case for x_2 in multiplication by 9", + "public" : "dcffc4c1e1fba5fda9d5c98421d99c257afa90921bc212a046d90f6683e8a467", + "private" : "707ee81f113a244c9d87608b12158c50f9ac1f2c8948d170ad16ab0ad866d74b", + "shared" : "7ecdd54c5e15f7b4061be2c30b5a4884a0256581f87df60d579a3345653eb641", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 507, + "comment" : "special case for BB in multiplication by 9", + "public" : "6c0044cd10578c5aff1ff4917b041b76c9a9ae23664eb8cf978bd7aa192cf249", + "private" : "7089654baacbb65bd00cd8cb9de4680e748075e8842ca69d448fb50fea85e74e", + "shared" : "0d8c21fa800ee63ce5e473d4c2975495062d8afa655091122cb41799d374594f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 508, + "comment" : "special case for BB in multiplication by 9", + "public" : "d9089de902e143dcd9107e5a3393a3f7fe05d926c357b47e307a236cb590fd64", + "private" : "8089784c52cd67e4536e568218c7b7033b28413f942fca24ed69e43496efa14b", + "shared" : "db6fec44bf118316a6bdfbae9af447baede4d82daa16bed596ea6f05d4a51400", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 509, + "comment" : "special case for BB in multiplication by 9", + "public" : "8c4a26aa319c2cc4a4158c2bc69a0d5b340b60628a14cf31bb0ae5ddc38ae866", + "private" : "00e73e4e013148b9f05273bad626bb126a40ec4558f5425096b48947e0a9de4a", + "shared" : "ecc1204bc753c4cec4c9059fd7b504944ebf995ab1b1d49f0b3b325353be3a15", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 510, + "comment" : "special case for BB in multiplication by 9", + "public" : "ce7295d1227c9062aab9cf02fc5671fb81632e725367f131d4122824a6132d68", + "private" : "78ed4c9bf9f44db8d93388985191ecf59226b9c1205fe7e762c327581c75884e", + "shared" : "3740de297ff0122067951e8985247123440e0f27171da99e263d5b4450f59f3d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 511, + "comment" : "private key == -1 (mod order)", + "public" : "6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376", + "private" : "a023cdd083ef5bb82f10d62e59e15a6800000000000000000000000000000050", + "shared" : "6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 512, + "comment" : "private key == 1 (mod order) on twist", + "public" : "2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035", + "private" : "58083dd261ad91eff952322ec824c682ffffffffffffffffffffffffffffff5f", + "shared" : "2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035", + "result" : "acceptable", + "flags" : [ + "Twist" + ] + }, + { + "tcId" : 513, + "comment" : "special case private key", + "public" : "3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666", + "private" : "4855555555555555555555555555555555555555555555555555555555555555", + "shared" : "63ef7d1c586476ec78bb7f747e321e01102166bf967a9ea9ba9741f49d439510", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 514, + "comment" : "special case private key", + "public" : "9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a", + "private" : "4855555555555555555555555555555555555555555555555555555555555555", + "shared" : "8b98ef4d6bf30df7f88e58d51505d37ed6845a969fe598747c033dcd08014065", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 515, + "comment" : "special case private key", + "public" : "be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308", + "private" : "4855555555555555555555555555555555555555555555555555555555555555", + "shared" : "cfa83e098829fe82fd4c14355f70829015219942c01e2b85bdd9ac4889ec2921", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 516, + "comment" : "special case private key", + "public" : "3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666", + "private" : "b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a", + "shared" : "4782036d6b136ca44a2fd7674d8afb0169943230ac8eab5160a212376c06d778", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 517, + "comment" : "special case private key", + "public" : "9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a", + "private" : "b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a", + "shared" : "65fc1e7453a3f8c7ebcd577ade4b8efe1035efc181ab3bdb2fcc7484cbcf1e4e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 518, + "comment" : "special case private key", + "public" : "be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308", + "private" : "b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a", + "shared" : "e3c649beae7cc4a0698d519a0a61932ee5493cbb590dbe14db0274cc8611f914", + "result" : "valid", + "flags" : [] + } + ] + } + ] +} diff --git a/tests/x25519.rs b/libcrux-ecdh/tests/x25519.rs similarity index 100% rename from tests/x25519.rs rename to libcrux-ecdh/tests/x25519.rs From fbdd7edd9a4d811413d76fa383a03d63c8b17773 Mon Sep 17 00:00:00 2001 From: Goutam Tamvada Date: Wed, 12 Jun 2024 11:23:49 -0400 Subject: [PATCH 79/84] Laying groundwork for implementing ML-DSA signing. (#309) --- libcrux-ml-dsa/src/arithmetic.rs | 84 +++++++--- libcrux-ml-dsa/src/deserialize.rs | 221 +++++++++++++++++++++++++++ libcrux-ml-dsa/src/lib.rs | 1 + libcrux-ml-dsa/src/matrix.rs | 22 ++- libcrux-ml-dsa/src/ml_dsa_44.rs | 4 +- libcrux-ml-dsa/src/ml_dsa_65.rs | 19 ++- libcrux-ml-dsa/src/ml_dsa_87.rs | 4 +- libcrux-ml-dsa/src/ml_dsa_generic.rs | 26 ++++ libcrux-ml-dsa/src/notes.md | 4 + libcrux-ml-dsa/src/sample.rs | 134 +++++++++++++++- libcrux-ml-dsa/src/serialize.rs | 108 +++++++++++++ 11 files changed, 596 insertions(+), 31 deletions(-) create mode 100644 libcrux-ml-dsa/src/deserialize.rs create mode 100644 libcrux-ml-dsa/src/notes.md diff --git a/libcrux-ml-dsa/src/arithmetic.rs b/libcrux-ml-dsa/src/arithmetic.rs index 6263884e2..661472d18 100644 --- a/libcrux-ml-dsa/src/arithmetic.rs +++ b/libcrux-ml-dsa/src/arithmetic.rs @@ -72,37 +72,74 @@ pub(crate) fn montgomery_multiply_fe_by_fer( // // We assume the input t is in the signed representative range and convert it // to the standard unsigned range. -// -// This approach has been taken from: -// https://github.com/cloudflare/circl/blob/main/sign/dilithium/internal/common/field.go#L35 pub(crate) fn power2round(t: i32) -> (i32, i32) { debug_assert!(t > -FIELD_MODULUS && t < FIELD_MODULUS, "t is {}", t); // Convert the signed representative to the standard unsigned one. let t = t + ((t >> 31) & FIELD_MODULUS); - // Compute t mod 2ᵈ - // t0 is now one of 0, 1, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹, 2ᵈ⁻¹+1, ..., 2ᵈ-1 - let mut t0 = t & ((1 << BITS_IN_LOWER_PART_OF_T) - 1); + // t0 = t - (2^{BITS_IN_LOWER_PART_OF_T} * t1) + // t1 = ⌊(t - 1)/2^{BITS_IN_LOWER_PART_OF_T} + 1/2⌋ + // + // See Lemma 10 of the implementation notes document for more information + // on what these compute. + let t1 = (t - 1 + (1 << (BITS_IN_LOWER_PART_OF_T - 1))) >> BITS_IN_LOWER_PART_OF_T; + let t0 = t - (t1 << BITS_IN_LOWER_PART_OF_T); - // now t0 is -2ᵈ⁻¹-1, -2ᵈ⁻¹, ..., -2, -1, 0, ..., 2ᵈ⁻¹-2 - t0 -= (1 << (BITS_IN_LOWER_PART_OF_T - 1)) + 1; + (t0, t1) +} - // Next, we add 2ᴰ to those t0 that are negative - // now a0 is 2ᵈ⁻¹-1, 2ᵈ⁻¹, ..., 2ᵈ-2, 2ᵈ-1, 0, ..., 2ᵈ⁻¹-2 - t0 += (t0 >> 31) & (1 << BITS_IN_LOWER_PART_OF_T); +pub(crate) fn t0_to_unsigned_representative(t0: i32) -> i32 { + (1 << (BITS_IN_LOWER_PART_OF_T - 1)) - t0 +} + +// Splits 0 ≤ r < q into r₀ and r₁ such that: +// +// - r = r₁*α + r₀ +// - -α/2 < r₀ ≤ α/2 +// +// except when r₁ = (q-1)/α; in this case: +// +// - r₁ is set to 0 is taken +// - α/2 ≤ r₀ < 0. +// +// Note that 0 ≤ r₁ < (q-1)/α. +pub(crate) fn decompose(r: i32) -> (i32, i32) { + let r1 = { + // Compute ⌈r / 128⌉ + let ceil_of_r_by_128 = (r + 127) >> 7; + + match ALPHA { + 190_464 => { + // 1488/2²⁴ is an approximation of 1/1488 + let result = ((ceil_of_r_by_128 * 11_275) + (1 << 23)) >> 24; + + // For the corner-case a₁ = (q-1)/α = 44, we have to set a₁=0. + (result ^ (43 - result) >> 31) & result + } + 523_776 => { + // 1025/2²² is an approximation of 1/4092 + let result = (ceil_of_r_by_128 * 1025 + (1 << 21)) >> 22; + + // For the corner-case a₁ = (q-1)/α = 16, we have to set a₁=0. + result & 15 + } + _ => unreachable!(), + } + }; - // now t0 is 0, 1, 2, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹-1, -2ᵈ⁻¹-1, ... - // which is what we want. - t0 -= (1 << (BITS_IN_LOWER_PART_OF_T - 1)) - 1; + let mut r0 = r - (r1 * ALPHA); - let t1 = (t - t0) >> BITS_IN_LOWER_PART_OF_T; + // In the corner-case, when we set a₁=0, we will incorrectly + // have a₀ > (q-1)/2 and we'll need to subtract q. As we + // return a₀ + q, that comes down to adding q if a₀ < (q-1)/2. + r0 -= (((FIELD_MODULUS - 1) / 2 - r0) >> 31) & FIELD_MODULUS; - (t0, t1) + (r0, r1) } -pub(crate) fn t0_to_unsigned_representative(t0: i32) -> i32 { - (1 << (BITS_IN_LOWER_PART_OF_T - 1)) - t0 +pub(crate) fn make_hint(low: i32, high: i32) -> bool { + (low > GAMMA2) || (low < -GAMMA2) || (low == -GAMMA2 && high != 0) } #[cfg(test)] @@ -124,4 +161,15 @@ mod tests { assert_eq!(power2round(-1568816), (4049, 831)); assert_eq!(power2round(-4022142), (131, 532)); } + + #[test] + fn test_decompose() { + assert_eq!(decompose::<190_464>(3574899), (-43917, 19)); + assert_eq!(decompose::<190_464>(7368323), (-59773, 39)); + assert_eq!(decompose::<190_464>(3640854), (22038, 19)); + + assert_eq!(decompose::<523_776>(563751), (39975, 1)); + assert_eq!(decompose::<523_776>(6645076), (-164012, 13)); + assert_eq!(decompose::<523_776>(7806985), (-49655, 15)); + } } diff --git a/libcrux-ml-dsa/src/deserialize.rs b/libcrux-ml-dsa/src/deserialize.rs new file mode 100644 index 000000000..e15f8d625 --- /dev/null +++ b/libcrux-ml-dsa/src/deserialize.rs @@ -0,0 +1,221 @@ +use crate::arithmetic::PolynomialRingElement; + +#[inline(always)] +fn deserialize_to_mask_when_gamma1_is_2_pow_17(serialized: &[u8]) -> PolynomialRingElement { + const GAMMA1: i32 = 1 << 17; + const GAMMA1_TIMES_2_BITMASK: i32 = (GAMMA1 << 1) - 1; + + let mut re = PolynomialRingElement::ZERO; + + for (i, bytes) in serialized.chunks_exact(9).enumerate() { + re.coefficients[4 * i + 0] = bytes[0] as i32; + re.coefficients[4 * i + 0] |= (bytes[1] as i32) << 8; + re.coefficients[4 * i + 0] |= (bytes[2] as i32) << 16; + re.coefficients[4 * i + 0] &= GAMMA1_TIMES_2_BITMASK; + + re.coefficients[4 * i + 1] = (bytes[2] as i32) >> 2; + re.coefficients[4 * i + 1] |= (bytes[3] as i32) << 6; + re.coefficients[4 * i + 1] |= (bytes[4] as i32) << 14; + re.coefficients[4 * i + 1] &= GAMMA1_TIMES_2_BITMASK; + + re.coefficients[4 * i + 2] = (bytes[4] as i32) >> 4; + re.coefficients[4 * i + 2] |= (bytes[5] as i32) << 4; + re.coefficients[4 * i + 2] |= (bytes[6] as i32) << 12; + re.coefficients[4 * i + 2] &= GAMMA1_TIMES_2_BITMASK; + + re.coefficients[4 * i + 3] = (bytes[6] as i32) >> 6; + re.coefficients[4 * i + 3] |= (bytes[7] as i32) << 2; + re.coefficients[4 * i + 3] |= (bytes[8] as i32) << 10; + re.coefficients[4 * i + 3] &= GAMMA1_TIMES_2_BITMASK; + + re.coefficients[4 * i + 0] = GAMMA1 - re.coefficients[4 * i + 0]; + re.coefficients[4 * i + 1] = GAMMA1 - re.coefficients[4 * i + 1]; + re.coefficients[4 * i + 2] = GAMMA1 - re.coefficients[4 * i + 2]; + re.coefficients[4 * i + 3] = GAMMA1 - re.coefficients[4 * i + 3]; + } + + re +} + +#[inline(always)] +fn deserialize_to_mask_when_gamma1_is_2_pow_19(serialized: &[u8]) -> PolynomialRingElement { + const GAMMA1: i32 = 1 << 19; + const GAMMA1_TIMES_2_BITMASK: i32 = (GAMMA1 << 1) - 1; + + let mut re = PolynomialRingElement::ZERO; + + for (i, bytes) in serialized.chunks_exact(5).enumerate() { + re.coefficients[2 * i + 0] = bytes[0] as i32; + re.coefficients[2 * i + 0] |= (bytes[1] as i32) << 8; + re.coefficients[2 * i + 0] |= (bytes[2] as i32) << 16; + re.coefficients[2 * i + 0] &= GAMMA1_TIMES_2_BITMASK; + + re.coefficients[2 * i + 1] = (bytes[2] as i32) >> 4; + re.coefficients[2 * i + 1] |= (bytes[3] as i32) << 4; + re.coefficients[2 * i + 1] |= (bytes[4] as i32) << 12; + + re.coefficients[2 * i + 0] = GAMMA1 - re.coefficients[2 * i + 0]; + re.coefficients[2 * i + 1] = GAMMA1 - re.coefficients[2 * i + 1]; + } + + re +} + +#[inline(always)] +pub(crate) fn deserialize_to_mask_ring_element( + serialized: &[u8], +) -> PolynomialRingElement { + match GAMMA1_EXPONENT { + 17 => deserialize_to_mask_when_gamma1_is_2_pow_17(serialized), + 19 => deserialize_to_mask_when_gamma1_is_2_pow_19(serialized), + _ => unreachable!(), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_to_mask_when_gamma1_is_2_pow_17() { + let bytes = [ + 198, 32, 33, 79, 53, 132, 46, 198, 17, 233, 84, 94, 175, 136, 13, 127, 137, 254, 113, + 82, 68, 239, 94, 176, 179, 22, 102, 177, 253, 142, 176, 250, 96, 201, 11, 213, 230, 41, + 207, 14, 252, 247, 44, 197, 61, 57, 233, 239, 7, 173, 48, 253, 53, 43, 107, 174, 112, + 33, 144, 137, 117, 234, 75, 181, 150, 72, 158, 193, 130, 225, 136, 17, 65, 227, 146, + 207, 208, 228, 176, 164, 158, 62, 142, 193, 250, 109, 210, 52, 182, 254, 148, 179, 247, + 164, 167, 177, 209, 148, 189, 86, 221, 208, 92, 28, 51, 228, 176, 249, 12, 142, 124, + 187, 37, 164, 131, 203, 222, 228, 211, 250, 222, 114, 123, 183, 44, 125, 14, 97, 12, + 64, 154, 168, 11, 96, 112, 93, 225, 58, 8, 110, 164, 69, 246, 67, 102, 109, 227, 41, + 170, 254, 3, 137, 7, 0, 7, 12, 89, 123, 133, 155, 52, 14, 80, 211, 96, 229, 7, 100, + 208, 68, 109, 222, 122, 84, 80, 163, 240, 121, 126, 235, 54, 72, 124, 163, 195, 30, + 207, 194, 158, 106, 46, 181, 90, 251, 232, 201, 121, 115, 110, 225, 245, 38, 111, 109, + 248, 202, 9, 161, 220, 240, 202, 155, 72, 236, 80, 97, 168, 67, 128, 160, 37, 56, 211, + 167, 71, 73, 215, 92, 101, 148, 227, 207, 180, 155, 233, 42, 144, 30, 28, 236, 184, 13, + 133, 206, 47, 170, 205, 59, 29, 209, 245, 226, 66, 69, 144, 146, 168, 83, 66, 233, 193, + 59, 79, 41, 167, 246, 246, 95, 161, 50, 105, 109, 255, 137, 188, 210, 189, 142, 91, 73, + 139, 24, 228, 30, 36, 133, 202, 123, 206, 244, 9, 229, 227, 255, 94, 198, 149, 5, 193, + 37, 72, 129, 16, 205, 245, 177, 242, 241, 120, 66, 137, 39, 20, 111, 197, 64, 89, 9, + 238, 114, 4, 212, 146, 75, 206, 58, 232, 33, 231, 186, 90, 202, 95, 49, 233, 209, 177, + 195, 88, 253, 80, 103, 112, 163, 245, 31, 6, 78, 119, 131, 17, 240, 77, 210, 72, 61, 1, + 104, 110, 70, 49, 83, 172, 187, 39, 53, 235, 40, 4, 19, 170, 110, 153, 249, 52, 6, 122, + 225, 235, 40, 196, 149, 80, 184, 69, 148, 61, 158, 255, 145, 72, 129, 51, 16, 2, 196, + 156, 146, 128, 107, 76, 122, 194, 42, 99, 240, 12, 213, 57, 55, 232, 145, 61, 45, 160, + 136, 168, 6, 128, 210, 250, 114, 174, 126, 230, 8, 228, 207, 143, 146, 135, 161, 201, + 156, 182, 241, 219, 217, 69, 27, 35, 156, 194, 91, 192, 115, 201, 22, 197, 145, 240, + 132, 11, 206, 138, 128, 139, 222, 212, 13, 212, 22, 92, 232, 216, 16, 69, 109, 55, 230, + 217, 210, 95, 192, 242, 193, 250, 91, 217, 140, 11, 98, 111, 8, 117, 91, 212, 63, 24, + 93, 161, 48, 241, 55, 11, 5, 171, 199, 212, 161, 230, 156, 205, 103, 171, 11, 226, 125, + 213, 216, 76, 17, 229, 56, 203, 30, 43, 39, 212, 232, 96, 198, 217, 109, 81, 125, 22, + 180, 195, 249, 20, 18, 57, 153, 132, 63, 206, 40, 137, 240, 149, 189, 220, 75, 227, + 142, 178, 214, 215, 101, 232, 204, 94, 189, 109, 236, 173, 200, 39, 114, 203, 136, 152, + 114, 173, 199, 38, 195, 46, 224, 68, 92, 129, 184, 157, 35, + ]; + + let expected_coefficients = [ + 57146, 44088, -59459, 112872, -21737, -11223, -127192, -129573, 109967, -113617, + -80645, 26534, -64945, -44067, 92657, -87087, -76262, -66483, -53119, 67820, -125241, + -82427, -119562, 86825, 86421, 128932, -88217, 53335, 92491, 104558, -6188, 113117, + -58177, 117788, -69197, -31378, 29122, -97968, -85286, -129752, -111508, 5827, 58598, + -63059, 74410, -71476, -17201, -124611, 94708, 37153, 116158, -97070, -54244, 84034, + -96183, 2894, 106226, -36867, 83319, 16000, -57693, -98830, 107962, 61479, -93542, + -35448, 114710, 123356, 129280, -54851, 18345, 116526, 76976, 1704, 63936, 19181, + 99618, 76779, -106250, -110073, 112586, 71457, 69140, -31499, 53654, -54957, 90481, + 12825, 7826, -117181, -100054, 121045, 74591, -62140, -50313, 31421, 113752, 38880, + 52350, 57697, 75959, 59049, 65991, -28371, 120087, -67492, -102081, -5174, -12238, + -62314, 60973, -101335, 113342, -9380, 121542, -67493, 45253, 22070, 145, 79227, + -93545, -74367, -122155, 37318, 95415, -112902, 110015, 4310, 2866, 67262, 4098, + -22297, 16123, 110071, 77560, -51159, 69134, -20638, 48520, -71100, 42688, 83070, + 49081, 53685, 116018, 14214, 21586, 32983, 5839, 70540, -120204, 25277, 23696, 30723, + -95456, 113139, -19952, -86580, -32787, 58951, 109775, 4373, -45906, 126813, -43539, + -26203, 105649, -99816, 120597, 121487, 107643, 68015, 98, 110044, 64712, -69640, + 93540, -72416, 120924, 29525, 62224, 12683, 57725, 84746, 96096, 130646, -109864, + -47563, 72066, -129282, 55044, -34334, -40137, -64621, 107107, 95123, -115356, 69610, + 37737, -18196, -99568, -45954, 83960, -86906, -54285, -5893, 62066, 19180, 6601, + -128182, -76805, -125703, 75429, 97565, 96522, 37420, 114732, 108730, -70410, 119585, + -109317, 101071, 12694, 24778, -2987, 41096, 78451, -103493, -52024, 13625, -36162, + -72067, 37415, 24748, 115903, 109593, 50926, -123174, -36067, -115236, 82539, 77065, + -76014, -89946, 71579, -87987, -50907, -74423, -94759, -8754, -55081, 91362, 119101, + -69944, -100373, 94602, + ]; + + assert_eq!( + deserialize_to_mask_ring_element::<17>(&bytes).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_deserialize_to_mask_when_gamma1_is_2_pow_19() { + let bytes: [u8; 640] = [ + 253, 11, 216, 60, 251, 71, 79, 187, 242, 250, 209, 44, 72, 206, 98, 3, 22, 91, 184, 22, + 197, 50, 249, 184, 253, 104, 8, 3, 9, 116, 147, 157, 110, 167, 67, 218, 30, 79, 58, 12, + 2, 72, 239, 104, 6, 162, 57, 195, 128, 18, 93, 245, 0, 132, 218, 172, 178, 214, 243, + 53, 171, 128, 90, 13, 126, 226, 148, 153, 238, 106, 146, 46, 220, 184, 140, 28, 167, + 18, 38, 212, 17, 6, 136, 251, 94, 47, 164, 196, 66, 120, 204, 45, 111, 37, 45, 51, 38, + 109, 32, 32, 144, 122, 13, 52, 144, 108, 75, 152, 73, 164, 139, 91, 26, 37, 76, 237, + 211, 47, 124, 0, 210, 175, 145, 149, 28, 19, 81, 38, 3, 121, 106, 191, 144, 129, 93, + 118, 202, 8, 163, 27, 182, 42, 148, 249, 166, 67, 198, 69, 164, 49, 157, 40, 230, 39, + 126, 108, 93, 96, 211, 185, 61, 99, 30, 83, 183, 241, 30, 16, 91, 76, 200, 55, 228, 22, + 33, 142, 114, 240, 217, 138, 155, 223, 136, 77, 216, 181, 102, 56, 218, 49, 91, 223, + 67, 68, 190, 216, 214, 180, 230, 199, 165, 17, 171, 151, 156, 33, 125, 248, 0, 56, 104, + 184, 150, 91, 83, 138, 61, 162, 255, 96, 168, 189, 86, 60, 76, 36, 163, 207, 76, 227, + 76, 180, 145, 125, 229, 251, 212, 77, 115, 88, 177, 134, 20, 122, 27, 211, 207, 254, + 233, 226, 31, 112, 10, 181, 117, 97, 56, 188, 176, 229, 156, 140, 97, 31, 64, 139, 249, + 217, 172, 100, 70, 121, 130, 94, 182, 245, 239, 138, 4, 65, 64, 228, 118, 200, 128, 94, + 143, 59, 53, 12, 185, 209, 191, 52, 91, 170, 161, 200, 12, 223, 221, 54, 151, 218, 3, + 156, 49, 176, 78, 50, 117, 16, 36, 179, 203, 91, 222, 181, 53, 151, 211, 229, 22, 49, + 247, 223, 195, 241, 1, 44, 157, 56, 48, 158, 25, 246, 231, 54, 106, 197, 107, 199, 252, + 60, 182, 216, 27, 129, 32, 149, 8, 239, 44, 176, 119, 104, 207, 77, 206, 150, 220, 18, + 172, 54, 140, 37, 235, 243, 23, 220, 149, 241, 197, 149, 240, 41, 223, 179, 98, 188, + 135, 231, 56, 176, 102, 173, 39, 46, 236, 79, 177, 224, 17, 164, 88, 227, 108, 214, + 234, 106, 253, 242, 27, 120, 44, 44, 63, 117, 135, 97, 90, 239, 81, 138, 112, 203, 188, + 13, 239, 224, 37, 53, 1, 27, 33, 26, 213, 36, 129, 146, 254, 82, 106, 111, 179, 25, + 199, 217, 243, 188, 250, 141, 136, 148, 154, 241, 152, 195, 225, 82, 174, 149, 124, + 237, 3, 81, 218, 90, 157, 6, 243, 34, 62, 141, 211, 164, 2, 103, 45, 46, 253, 115, 244, + 216, 191, 245, 177, 121, 216, 86, 131, 66, 63, 18, 167, 41, 199, 241, 195, 117, 168, + 134, 193, 73, 201, 83, 197, 85, 147, 217, 45, 162, 18, 203, 166, 95, 166, 159, 8, 1, + 110, 125, 113, 228, 180, 78, 194, 174, 60, 172, 124, 151, 23, 202, 247, 189, 206, 204, + 101, 51, 35, 8, 196, 85, 237, 64, 222, 81, 143, 182, 205, 105, 110, 173, 197, 239, 196, + 5, 108, 128, 248, 191, 247, 43, 25, 180, 246, 154, 125, 142, 227, 246, 17, 2, 207, 193, + 89, 244, 159, 82, 218, 117, 78, 191, 40, 49, 154, 160, 83, 246, 93, 94, 52, 85, 45, + 140, 99, 40, 23, 179, 141, 10, 143, 62, 176, 84, 19, 94, 79, 72, 58, 138, 7, 87, 196, + 2, 87, 0, 191, 226, 2, 224, 187, 150, 199, 217, 211, 51, 114, 228, 71, 54, 23, 17, 9, + 212, 195, 125, 236, 213, 254, 189, 203, 232, 161, 50, 81, 174, 129, 117, + ]; + + let expected_coefficients = [ + -3069, -504781, -216903, -503595, -11473, 119580, -202243, 431227, -78533, -514959, + 325528, 49008, -433555, 247178, -466650, 474204, -477186, 498034, 312926, 448500, + 461475, -370752, 85332, 303299, -164011, 7979, -103650, 86295, -274066, -52109, 350436, + -344673, -1553, 135240, 220113, 31700, -470476, 339370, -337459, 392698, -359056, + -66368, -19308, -148633, -154507, 212399, -513005, 522302, 413742, 407207, 110317, + 28622, 475286, 141287, -51830, 411088, 251210, -159641, 145853, 320956, 120675, 7554, + 500372, -236854, -418621, -226609, 516367, 211535, 247864, 388754, 494962, -44447, + -57243, -361688, -26293, 320093, 270501, -255044, 207144, -294507, -201125, -117114, + -32033, 294897, 83864, 182855, 377462, 126982, 82520, 212027, -500516, -406732, 412596, + -415705, -382203, 161996, 227663, 411743, -446419, -405151, -159775, 42160, -276577, + -416523, 422756, 261642, -129419, 111923, 362170, -222696, -192501, 257976, 72640, + -3207, -233310, 474285, -512441, 150709, -41386, -389324, 51491, 508503, 511588, + 318229, 257931, -310066, 139685, -95067, 72237, -488209, 408609, 344033, 509795, + 419357, 71690, -284323, -313195, -222159, 451624, -86536, -323336, 34046, -380776, + -93412, -266972, -50026, 267483, -377215, 134763, -461148, 270551, -247339, -59271, + 103677, -403373, 196926, 401231, 161215, 103197, 86355, -258813, 342143, 180436, + 124809, 397478, 63323, -376011, -397040, 445147, 388688, 207590, -75794, -152318, + -210678, -116505, -249661, -36346, -108872, 288527, 184804, -300462, 508201, -186961, + 497195, -402163, -342227, 64860, 335146, 232451, -261519, -111093, 168569, -475779, + -160035, 407767, 41921, 424280, -300188, 146093, -366901, 351699, -158897, -501343, + 520055, 426642, -216647, -442958, -181194, 26756, -490657, -315069, 313764, 260061, + -447836, 401856, -223477, -420301, -285398, 146193, -1728, 16392, 421185, -194228, + -59353, 395549, -323617, 239167, 185857, -423386, 357388, 484815, -484666, 237987, + 338605, -25484, -209266, -461453, -197608, -398164, 228107, 30150, -279920, 502014, + -404464, -253954, -293227, 273447, -411427, 51641, 487151, -377812, -351943, -245246, + -138892, -414002, 42982, + ]; + + assert_eq!( + deserialize_to_mask_ring_element::<19>(&bytes).coefficients, + expected_coefficients + ); + } +} diff --git a/libcrux-ml-dsa/src/lib.rs b/libcrux-ml-dsa/src/lib.rs index 7f7fe2db9..32e111662 100644 --- a/libcrux-ml-dsa/src/lib.rs +++ b/libcrux-ml-dsa/src/lib.rs @@ -1,5 +1,6 @@ mod arithmetic; mod constants; +mod deserialize; mod hash_functions; mod matrix; mod ml_dsa_generic; diff --git a/libcrux-ml-dsa/src/matrix.rs b/libcrux-ml-dsa/src/matrix.rs index 33451c0fe..16d5a8fe5 100644 --- a/libcrux-ml-dsa/src/matrix.rs +++ b/libcrux-ml-dsa/src/matrix.rs @@ -1,7 +1,7 @@ use crate::{ arithmetic::{add_to_ring_element, power2round, PolynomialRingElement}, ntt::{invert_ntt_montgomery, ntt, ntt_multiply_montgomery}, - sample::{sample_error_ring_element_uniform, sample_ring_element_uniform}, + sample::{sample_error_ring_element, sample_mask_ring_element, sample_ring_element_uniform}, }; pub(crate) fn power2round_vector( @@ -36,7 +36,25 @@ pub(crate) fn sample_error_vector( seed[65] = (*domain_separator >> 8) as u8; *domain_separator += 1; - error[i] = sample_error_ring_element_uniform::(seed); + error[i] = sample_error_ring_element::(seed); + } + + error +} + +#[inline(always)] +pub(crate) fn sample_mask_vector( + mut seed: [u8; 66], + signing_attempt_counter: u16, +) -> [PolynomialRingElement; COLUMNS_IN_A] { + let mut error = [PolynomialRingElement::ZERO; COLUMNS_IN_A]; + + for i in 0..COLUMNS_IN_A { + let domain_separator = signing_attempt_counter + (i as u16); + seed[64] = domain_separator as u8; + seed[65] = (domain_separator >> 8) as u8; + + error[i] = sample_mask_ring_element::(seed); } error diff --git a/libcrux-ml-dsa/src/ml_dsa_44.rs b/libcrux-ml-dsa/src/ml_dsa_44.rs index b251b4eb0..70096d8cc 100644 --- a/libcrux-ml-dsa/src/ml_dsa_44.rs +++ b/libcrux-ml-dsa/src/ml_dsa_44.rs @@ -6,10 +6,10 @@ const ROWS_IN_A: usize = 4; const COLUMNS_IN_A: usize = 4; const ETA: usize = 2; -const TWO_TIMES_ETA_BIT_SIZE: usize = 3; // ⌊log_2(2 * 2)⌋ + 1 +const BITS_PER_ERROR_COEFFICIENT: usize = 3; const BYTES_FOR_ERROR_RING_ELEMENT: usize = - (TWO_TIMES_ETA_BIT_SIZE * COEFFICIENTS_IN_RING_ELEMENT) / 8; + (BITS_PER_ERROR_COEFFICIENT * COEFFICIENTS_IN_RING_ELEMENT) / 8; const VERIFICATION_KEY_SIZE: usize = SEED_FOR_A_SIZE + (COEFFICIENTS_IN_RING_ELEMENT diff --git a/libcrux-ml-dsa/src/ml_dsa_65.rs b/libcrux-ml-dsa/src/ml_dsa_65.rs index 60bc95dfd..9f0049e04 100644 --- a/libcrux-ml-dsa/src/ml_dsa_65.rs +++ b/libcrux-ml-dsa/src/ml_dsa_65.rs @@ -6,10 +6,25 @@ const ROWS_IN_A: usize = 6; const COLUMNS_IN_A: usize = 5; const ETA: usize = 4; -const TWO_TIMES_ETA_BIT_SIZE: usize = 4; // ⌊log_2(2 * 4)⌋ + 1 +const GAMMA1_EXPONENT: usize = 19; + +// To sample a value in the interval [-ETA, ETA], we can sample a value (say 'v') +// in the interval [0, 2 * ETA] and then compute ETA - v. This can be done in +// 4 bits when ETA is 4. +const BITS_PER_ERROR_COEFFICIENT: usize = 4; const BYTES_FOR_ERROR_RING_ELEMENT: usize = - (TWO_TIMES_ETA_BIT_SIZE * COEFFICIENTS_IN_RING_ELEMENT) / 8; + (BITS_PER_ERROR_COEFFICIENT * COEFFICIENTS_IN_RING_ELEMENT) / 8; + +// To sample a value in the interval [-(GAMMA - 1), GAMMA], we can sample a +// value (say 'v') in the interval [0, (2 * GAMMA) - 1] and then compute +// GAMMA - v. This can be done in 20 bits when GAMMA is 2^{19}. +const BITS_PER_MASK_COEFFICIENT: usize = 20; + +const MAX_NUMBER_OF_ONES_IN_HINT: usize = 55; + +const BYTES_PER_MASK_RING_ELEMENT: usize = + (BITS_PER_MASK_COEFFICIENT * COEFFICIENTS_IN_RING_ELEMENT) / 8; const VERIFICATION_KEY_SIZE: usize = SEED_FOR_A_SIZE + (COEFFICIENTS_IN_RING_ELEMENT diff --git a/libcrux-ml-dsa/src/ml_dsa_87.rs b/libcrux-ml-dsa/src/ml_dsa_87.rs index 1778ca333..34b9e63fc 100644 --- a/libcrux-ml-dsa/src/ml_dsa_87.rs +++ b/libcrux-ml-dsa/src/ml_dsa_87.rs @@ -6,10 +6,10 @@ const ROWS_IN_A: usize = 8; const COLUMNS_IN_A: usize = 7; const ETA: usize = 2; -const TWO_TIMES_ETA_BIT_SIZE: usize = 3; // ⌊log_2(2 * 2)⌋ + 1 +const BITS_PER_ERROR_COEFFICIENT: usize = 3; const BYTES_FOR_ERROR_RING_ELEMENT: usize = - (TWO_TIMES_ETA_BIT_SIZE * COEFFICIENTS_IN_RING_ELEMENT) / 8; + (BITS_PER_ERROR_COEFFICIENT * COEFFICIENTS_IN_RING_ELEMENT) / 8; const VERIFICATION_KEY_SIZE: usize = SEED_FOR_A_SIZE + (COEFFICIENTS_IN_RING_ELEMENT diff --git a/libcrux-ml-dsa/src/ml_dsa_generic.rs b/libcrux-ml-dsa/src/ml_dsa_generic.rs index 14bf832e1..04f63e328 100644 --- a/libcrux-ml-dsa/src/ml_dsa_generic.rs +++ b/libcrux-ml-dsa/src/ml_dsa_generic.rs @@ -141,3 +141,29 @@ pub(crate) fn generate_key_pair< (signing_key_serialized, verification_key_serialized) } + +#[allow(non_snake_case)] +pub(crate) fn sign< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const BYTES_FOR_ERROR_RING_ELEMENT: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, +>( + signing_key: [u8; SIGNING_KEY_SIZE], + message: &[u8], + randomness: [u8; 32], +) -> [u8; SIGNATURE_SIZE] { + let (rho, remaining_signing_key) = signing_key.split_at(SEED_FOR_A_SIZE); + let (seed_for_signing, remaining_signing_key) = + remaining_signing_key.split_at(SEED_FOR_SIGNING_SIZE); + let (verification_key_hash, remaining_signing_key) = + remaining_signing_key.split_at(BYTES_FOR_VERIFICATION_KEY_HASH); + + let (s1_serialized, remaining_signing_key) = + remaining_signing_key.split_at(BYTES_FOR_ERROR_RING_ELEMENT); + let (s2_serializd, t0_serialized) = + remaining_signing_key.split_at(BYTES_FOR_ERROR_RING_ELEMENT); + + todo!(); +} diff --git a/libcrux-ml-dsa/src/notes.md b/libcrux-ml-dsa/src/notes.md new file mode 100644 index 000000000..5d4f5f5d0 --- /dev/null +++ b/libcrux-ml-dsa/src/notes.md @@ -0,0 +1,4 @@ +The constants and arrays used in the unit tests in this directory have been +generated by printing the inputs and outputs produced by the corresponding +functions from the `ref` version under the `standard` branch of the +[PQ-Crystals implementation](https://github.com/pq-crystals/dilithium) of ML-DSA. diff --git a/libcrux-ml-dsa/src/sample.rs b/libcrux-ml-dsa/src/sample.rs index 579b19e87..44d72057b 100644 --- a/libcrux-ml-dsa/src/sample.rs +++ b/libcrux-ml-dsa/src/sample.rs @@ -1,6 +1,7 @@ use crate::{ arithmetic::PolynomialRingElement, constants::{COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}, + deserialize::deserialize_to_mask_ring_element, hash_functions::{H, H_128}, }; @@ -133,9 +134,7 @@ pub(crate) fn rejection_sample_less_than_eta( } #[allow(non_snake_case)] -pub(crate) fn sample_error_ring_element_uniform( - seed: [u8; 66], -) -> PolynomialRingElement { +pub(crate) fn sample_error_ring_element(seed: [u8; 66]) -> PolynomialRingElement { // TODO: Use incremental API to squeeze one block at a time. let randomness = H::<272>(&seed); @@ -152,6 +151,53 @@ pub(crate) fn sample_error_ring_element_uniform( out } +pub(crate) fn sample_mask_ring_element( + seed: [u8; 66], +) -> PolynomialRingElement { + match GAMMA1_EXPONENT { + 17 => deserialize_to_mask_ring_element::(&H::<576>(&seed)), + 19 => deserialize_to_mask_ring_element::(&H::<640>(&seed)), + _ => unreachable!(), + } +} + +pub(crate) fn sample_challenge_ring_element( + seed: [u8; 32], +) -> PolynomialRingElement { + // TODO: Use incremental API to squeeze one block at a time. + let mut randomness = H::<136>(&seed).into_iter(); + + let mut signs: u64 = 0; + for i in 0..8 { + signs |= (randomness.next().unwrap() as u64) << (8 * i); + } + + let mut out = PolynomialRingElement::ZERO; + + for index in (out.coefficients.len() - TAU)..out.coefficients.len() { + // TODO: Rewrite this without using `break`. It's doable, just probably + // not as nice. + let sample_at = loop { + let i = match randomness.next() { + Some(byte) => byte as usize, + + // TODO: We need to incrementally sample here instead of panicking. + None => panic!("Insufficient randomness to sample challenge ring element."), + }; + + if i <= index { + break i; + } + }; + + out.coefficients[index] = out.coefficients[sample_at]; + out.coefficients[sample_at] = 1 - 2 * ((signs & 1) as i32); + signs >>= 1; + } + + out +} + #[cfg(test)] mod tests { use super::*; @@ -225,7 +271,7 @@ mod tests { ]; assert_eq!( - sample_error_ring_element_uniform::<2>(seed).coefficients, + sample_error_ring_element::<2>(seed).coefficients, expected_coefficients ); } @@ -254,7 +300,85 @@ mod tests { ]; assert_eq!( - sample_error_ring_element_uniform::<4>(seed).coefficients, + sample_error_ring_element::<4>(seed).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_sample_challenge_ring_element_when_tau_is_39() { + let seed: [u8; 32] = [ + 3, 9, 159, 119, 236, 6, 207, 7, 103, 108, 187, 137, 222, 35, 37, 30, 79, 224, 204, 186, + 41, 38, 148, 188, 201, 50, 105, 155, 129, 217, 124, 57, + ]; + + let expected_coefficients: [i32; COEFFICIENTS_IN_RING_ELEMENT] = [ + 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, + -1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, + -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 1, + 0, 0, 0, 1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + 0, + ]; + + assert_eq!( + sample_challenge_ring_element::<39>(seed).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_sample_challenge_ring_element_when_tau_is_49() { + let seed: [u8; 32] = [ + 147, 7, 165, 152, 200, 20, 4, 38, 107, 110, 111, 176, 108, 84, 109, 201, 232, 125, 52, + 83, 160, 120, 106, 44, 76, 41, 76, 144, 8, 184, 4, 74, + ]; + + let expected_coefficients: [i32; COEFFICIENTS_IN_RING_ELEMENT] = [ + 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1, -1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, + -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, + -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, + 0, -1, 0, 0, 0, + ]; + + assert_eq!( + sample_challenge_ring_element::<49>(seed).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_sample_challenge_ring_element_when_tau_is_60() { + let seed: [u8; 32] = [ + 188, 193, 17, 175, 172, 179, 13, 23, 90, 238, 237, 230, 143, 113, 24, 65, 250, 86, 234, + 229, 251, 57, 199, 158, 9, 4, 102, 249, 11, 68, 140, 107, + ]; + + let expected_coefficients: [i32; COEFFICIENTS_IN_RING_ELEMENT] = [ + 0, 0, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, 0, 0, -1, + 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, + 0, 1, 0, -1, 1, 0, 0, 0, 0, 0, 1, 1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, + 0, 0, 0, 1, -1, 0, + ]; + + assert_eq!( + sample_challenge_ring_element::<60>(seed).coefficients, expected_coefficients ); } diff --git a/libcrux-ml-dsa/src/serialize.rs b/libcrux-ml-dsa/src/serialize.rs index 7354b1ba4..5b5f07260 100644 --- a/libcrux-ml-dsa/src/serialize.rs +++ b/libcrux-ml-dsa/src/serialize.rs @@ -126,6 +126,48 @@ pub(crate) fn serialize_error_ring_element( + re: PolynomialRingElement, +) -> [u8; BYTES_FOR_OUTPUT] { + let mut out = [0u8; BYTES_FOR_OUTPUT]; + + match GAMMA2 { + // 95,232 = (FIELD_MODULUS - 1) / 88 + 95_232 => { + // w1 has coefficients in [0,43] => each coefficient occupies + // 6 bits. + for (i, coefficients) in re.coefficients.chunks_exact(4).enumerate() { + let coefficient0 = coefficients[0] as u8; + let coefficient1 = coefficients[1] as u8; + let coefficient2 = coefficients[2] as u8; + let coefficient3 = coefficients[3] as u8; + + out[3 * i + 0] = (coefficient1 << 6) | coefficient0; + out[3 * i + 1] = (coefficient2 << 4) | coefficient1 >> 2; + out[3 * i + 2] = (coefficient3 << 2) | coefficient2 >> 4; + } + + out + } + + // 261,888 = (FIELD_MODULUS - 1) / 32 + 261_888 => { + // w1 has coefficients in [0,15] => each coefficient occupies + // 4 bits. + for (i, coefficients) in re.coefficients.chunks_exact(2).enumerate() { + let coefficient0 = coefficients[0] as u8; + let coefficient1 = coefficients[1] as u8; + + out[i] = (coefficient1 << 4) | coefficient0; + } + + out + } + + _ => unreachable!(), + } +} + #[cfg(test)] mod tests { use super::*; @@ -233,4 +275,70 @@ mod tests { assert_eq!(serialize_ring_element_of_t0s(re), expected_re_serialized); } + + #[test] + fn test_serialize_ring_element_w1() { + // Test serialization when GAMMA2 = 95_232 + let re = PolynomialRingElement { + coefficients: [ + 42, 38, 3, 37, 37, 40, 2, 36, 11, 43, 37, 40, 1, 39, 20, 41, 38, 24, 41, 32, 7, 10, + 21, 21, 25, 11, 21, 22, 33, 43, 8, 11, 20, 23, 24, 30, 22, 42, 11, 37, 31, 39, 9, + 22, 27, 14, 39, 11, 3, 17, 25, 17, 17, 20, 32, 43, 17, 20, 23, 2, 38, 19, 16, 14, + 38, 34, 35, 8, 39, 12, 9, 4, 4, 1, 21, 37, 22, 10, 20, 3, 36, 1, 42, 39, 18, 17, 3, + 1, 38, 1, 5, 20, 0, 21, 39, 20, 10, 42, 10, 26, 6, 22, 12, 1, 20, 1, 43, 37, 33, + 37, 6, 24, 32, 8, 42, 2, 32, 16, 13, 3, 33, 2, 0, 29, 4, 3, 23, 36, 6, 42, 1, 37, + 7, 3, 12, 36, 19, 41, 42, 20, 36, 12, 11, 39, 23, 35, 29, 9, 31, 11, 19, 11, 14, 1, + 32, 5, 6, 31, 4, 30, 8, 24, 22, 39, 8, 10, 26, 11, 25, 10, 36, 17, 43, 25, 20, 2, + 37, 11, 21, 4, 24, 25, 5, 26, 29, 39, 3, 10, 8, 15, 40, 28, 26, 4, 30, 42, 14, 17, + 41, 27, 8, 19, 19, 0, 3, 5, 41, 34, 39, 14, 1, 39, 9, 10, 41, 12, 24, 16, 2, 5, 33, + 27, 27, 32, 4, 3, 9, 5, 37, 40, 38, 43, 32, 27, 34, 27, 15, 24, 4, 2, 42, 15, 9, 3, + 17, 35, 0, 22, 43, 13, 15, 6, 38, 10, 20, 37, + ], + }; + + let serialized = [ + 170, 57, 148, 37, 42, 144, 203, 90, 162, 193, 73, 165, 38, 150, 130, 135, 82, 85, 217, + 82, 89, 225, 138, 44, 212, 133, 121, 150, 186, 148, 223, 153, 88, 155, 115, 46, 67, + 148, 69, 17, 5, 174, 17, 117, 9, 230, 4, 57, 166, 56, 34, 39, 147, 16, 68, 80, 149, + 150, 66, 13, 100, 160, 158, 82, 52, 4, 102, 80, 80, 64, 117, 82, 138, 170, 104, 134, + 197, 4, 84, 176, 150, 97, 105, 96, 32, 162, 10, 32, 212, 12, 161, 0, 116, 196, 112, + 145, 134, 26, 148, 199, 192, 144, 83, 170, 82, 36, 179, 156, 215, 216, 37, 223, 50, 45, + 78, 0, 22, 198, 71, 120, 8, 102, 157, 136, 162, 45, 153, 66, 70, 107, 70, 9, 229, 82, + 17, 88, 86, 104, 221, 57, 40, 200, 131, 114, 26, 225, 169, 78, 148, 110, 200, 52, 1, + 67, 145, 138, 167, 19, 156, 137, 146, 50, 24, 36, 20, 225, 182, 129, 196, 144, 20, 37, + 106, 174, 224, 38, 110, 15, 70, 8, 234, 147, 12, 209, 8, 88, 107, 243, 24, 166, 66, + 149, + ]; + + assert_eq!(serialize_ring_element_w1::<95_232, 192>(re), serialized); + + // Test serialization when GAMMA2 = 261,888 + let re = PolynomialRingElement { + coefficients: [ + 2, 4, 8, 3, 14, 3, 10, 7, 4, 15, 13, 3, 1, 2, 9, 12, 8, 11, 12, 4, 7, 14, 9, 4, 4, + 2, 5, 15, 14, 11, 6, 11, 10, 13, 3, 13, 9, 15, 10, 8, 14, 4, 8, 11, 11, 10, 13, 8, + 4, 9, 3, 8, 8, 3, 4, 5, 14, 9, 13, 12, 0, 4, 4, 2, 9, 11, 7, 11, 9, 14, 1, 7, 13, + 12, 0, 15, 14, 8, 6, 15, 15, 7, 11, 1, 11, 2, 4, 11, 10, 3, 15, 6, 7, 3, 1, 12, 0, + 15, 7, 13, 13, 1, 9, 14, 3, 5, 0, 8, 5, 7, 5, 8, 10, 13, 13, 11, 11, 13, 1, 4, 10, + 14, 15, 14, 12, 6, 13, 1, 7, 7, 15, 4, 2, 5, 6, 2, 7, 14, 2, 2, 4, 11, 7, 1, 5, 8, + 9, 5, 4, 13, 8, 8, 13, 13, 15, 5, 6, 11, 11, 4, 13, 7, 11, 15, 15, 3, 12, 4, 12, + 14, 2, 6, 9, 10, 6, 13, 15, 12, 11, 12, 2, 7, 6, 9, 9, 5, 6, 3, 4, 2, 8, 3, 10, 2, + 8, 1, 13, 10, 12, 8, 14, 0, 5, 12, 5, 3, 7, 15, 12, 13, 3, 4, 10, 1, 13, 3, 9, 6, + 10, 13, 4, 4, 2, 9, 0, 4, 5, 7, 14, 11, 2, 6, 3, 11, 6, 2, 0, 5, 8, 5, 9, 5, 9, 0, + 2, 2, 3, 15, 0, 8, 11, 13, 2, 6, 11, 0, + ], + }; + + let serialized = [ + 66, 56, 62, 122, 244, 61, 33, 201, 184, 76, 231, 73, 36, 245, 190, 182, 218, 211, 249, + 138, 78, 184, 171, 141, 148, 131, 56, 84, 158, 205, 64, 36, 185, 183, 233, 113, 205, + 240, 142, 246, 127, 27, 43, 180, 58, 111, 55, 193, 240, 215, 29, 233, 83, 128, 117, + 133, 218, 189, 219, 65, 234, 239, 108, 29, 119, 79, 82, 38, 231, 34, 180, 23, 133, 89, + 212, 136, 221, 95, 182, 75, 125, 251, 63, 76, 236, 98, 169, 214, 207, 203, 114, 150, + 89, 54, 36, 56, 42, 24, 173, 140, 14, 197, 53, 247, 220, 67, 26, 61, 105, 218, 68, 146, + 64, 117, 190, 98, 179, 38, 80, 88, 89, 9, 34, 243, 128, 219, 98, 11, + ]; + + assert_eq!(serialize_ring_element_w1::<261_888, 128>(re), serialized); + } } From debd4e75ec1b8e096f26fe50d1f03b4cf4882827 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Thu, 13 Jun 2024 08:07:21 +0200 Subject: [PATCH 80/84] Update Cargo.lock --- Cargo.lock | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index a8e8f334e..ee84451dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -915,6 +915,7 @@ dependencies = [ "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", "hex", "libcrux", + "libcrux-ecdh", "libcrux-hacl", "libcrux-hkdf", "libcrux-hmac", @@ -931,6 +932,19 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "libcrux-ecdh" +version = "0.0.2-pre.2" +dependencies = [ + "hex", + "libcrux", + "libcrux-hacl", + "pretty_env_logger", + "rand", + "serde", + "serde_json", +] + [[package]] name = "libcrux-fuzz" version = "0.0.0" @@ -973,6 +987,17 @@ dependencies = [ "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", ] +[[package]] +name = "libcrux-kem" +version = "0.0.2-pre.2" +dependencies = [ + "libcrux", + "libcrux-ecdh", + "libcrux-ml-kem", + "libcrux-sha3", + "rand", +] + [[package]] name = "libcrux-ml-dsa" version = "0.0.2-pre.2" From 304479263f24d92c1b279d8e3ca253965767ed59 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Thu, 13 Jun 2024 09:13:09 +0200 Subject: [PATCH 81/84] Make `libcrux` depend on `libcrux-kem` --- Cargo.lock | 4 + Cargo.toml | 2 + libcrux-kem/Cargo.toml | 2 + libcrux-kem/tests/kats/README.md | 1 + libcrux-kem/tests/kats/generate_kats.py | 91 + .../kats/invalid_modulus/ML-KEM-1024.txt | 1040 ++++++++++ .../tests/kats/invalid_modulus/ML-KEM-512.txt | 775 +++++++ .../tests/kats/invalid_modulus/ML-KEM-768.txt | 780 +++++++ libcrux-kem/tests/kats/kyber.py | 363 ++++ libcrux-kem/tests/kats/nistkats_1024.json | 802 +++++++ libcrux-kem/tests/kats/nistkats_512.json | 802 +++++++ libcrux-kem/tests/kats/nistkats_768.json | 802 +++++++ .../kats/wycheproof_early/decaps1024draft | 1830 ++++++++++++++++ .../kats/wycheproof_early/decaps512draft | 1830 ++++++++++++++++ .../kats/wycheproof_early/decaps768draft | 1830 ++++++++++++++++ .../kats/wycheproof_early/encaps1024draft | 1841 +++++++++++++++++ .../kats/wycheproof_early/encaps512draft | 1841 +++++++++++++++++ .../kats/wycheproof_early/encaps768draft | 1841 +++++++++++++++++ .../kats/wycheproof_early/keygen1024draft | 500 +++++ .../kats/wycheproof_early/keygen512draft | 500 +++++ .../kats/wycheproof_early/keygen768draft | 500 +++++ .../tests}/ml_kem_wycheproof_early.rs | 30 +- src/hpke/hpke.rs | 14 +- src/hpke/kem.rs | 23 +- src/kem.rs | 712 +------ tests/kyber.rs | 248 --- tests/kyber_nistkats.rs | 89 - 27 files changed, 18026 insertions(+), 1067 deletions(-) create mode 100644 libcrux-kem/tests/kats/README.md create mode 100755 libcrux-kem/tests/kats/generate_kats.py create mode 100644 libcrux-kem/tests/kats/invalid_modulus/ML-KEM-1024.txt create mode 100644 libcrux-kem/tests/kats/invalid_modulus/ML-KEM-512.txt create mode 100644 libcrux-kem/tests/kats/invalid_modulus/ML-KEM-768.txt create mode 100644 libcrux-kem/tests/kats/kyber.py create mode 100644 libcrux-kem/tests/kats/nistkats_1024.json create mode 100644 libcrux-kem/tests/kats/nistkats_512.json create mode 100644 libcrux-kem/tests/kats/nistkats_768.json create mode 100644 libcrux-kem/tests/kats/wycheproof_early/decaps1024draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/decaps512draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/decaps768draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/encaps1024draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/encaps512draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/encaps768draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/keygen1024draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/keygen512draft create mode 100644 libcrux-kem/tests/kats/wycheproof_early/keygen768draft rename {tests => libcrux-kem/tests}/ml_kem_wycheproof_early.rs (90%) delete mode 100644 tests/kyber.rs delete mode 100644 tests/kyber_nistkats.rs diff --git a/Cargo.lock b/Cargo.lock index ee84451dc..82ba8d5dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -919,6 +919,8 @@ dependencies = [ "libcrux-hacl", "libcrux-hkdf", "libcrux-hmac", + "libcrux-kem", + "libcrux-ml-kem", "libcrux-platform", "log", "pretty_env_logger", @@ -991,8 +993,10 @@ dependencies = [ name = "libcrux-kem" version = "0.0.2-pre.2" dependencies = [ + "hex", "libcrux", "libcrux-ecdh", + "libcrux-kem", "libcrux-ml-kem", "libcrux-sha3", "rand", diff --git a/Cargo.toml b/Cargo.toml index bf7e035ca..cb0053d51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,8 @@ libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } libcrux-hkdf = { version = "=0.0.2-pre.2", path = "libcrux-hkdf" } libcrux-hmac = { version = "=0.0.2-pre.2", path = "libcrux-hmac" } libcrux-ecdh = { version = "=0.0.2-pre.2", path = "libcrux-ecdh" } +libcrux-ml-kem = { version = "=0.0.2-pre.2", path = "libcrux-ml-kem" } +libcrux-kem = { version = "=0.0.2-pre.2", path = "libcrux-kem" } rand = { version = "0.8" } log = { version = "0.4", optional = true } # WASM API diff --git a/libcrux-kem/Cargo.toml b/libcrux-kem/Cargo.toml index 29bc9841a..1b194f3b6 100644 --- a/libcrux-kem/Cargo.toml +++ b/libcrux-kem/Cargo.toml @@ -22,4 +22,6 @@ rand = { version = "0.8" } tests = [] # Expose functions for testing. [dev-dependencies] +libcrux-kem = { version = "0.0.2-pre.2", path = "./", features = ["tests"] } libcrux = { version = "0.0.2-pre.2", path = "../", features = ["rand"] } +hex = { version = "0.4.3", features = ["serde"] } diff --git a/libcrux-kem/tests/kats/README.md b/libcrux-kem/tests/kats/README.md new file mode 100644 index 000000000..17024363b --- /dev/null +++ b/libcrux-kem/tests/kats/README.md @@ -0,0 +1 @@ +In order to regenerate the JSON KAT files for all parameter sets, simply run `./generate_kats.py`. diff --git a/libcrux-kem/tests/kats/generate_kats.py b/libcrux-kem/tests/kats/generate_kats.py new file mode 100755 index 000000000..7dd7530df --- /dev/null +++ b/libcrux-kem/tests/kats/generate_kats.py @@ -0,0 +1,91 @@ +#! /usr/bin/env python3 + +# This file is a modified version of: +# https://github.com/bwesterb/draft-schwabe-cfrg-kyber/blob/main/kyber_test.py + +from kyber import * + +import hashlib +import json + +import Crypto +from Crypto.Cipher import AES + + +class NistDRBG: + """NIST's DRBG used to generate NIST's Known Answer Tests (KATs), + see PQCgenKAT.c.""" + + def __init__(self, seed): + self.key = b"\0" * 32 + self.v = 0 + assert len(seed) == 48 + self._update(seed) + + def _update(self, seed): + b = AES.new(self.key, AES.MODE_ECB) + buf = b"" + for i in range(3): + self.v += 1 + buf += b.encrypt(self.v.to_bytes(16, "big")) + if seed is not None: + buf = bytes([x ^ y for x, y in zip(seed, buf)]) + self.key = buf[:32] + self.v = int.from_bytes(buf[32:], "big") + + def read(self, length): + b = AES.new(self.key, AES.MODE_ECB) + ret = b"" + while len(ret) < length: + self.v += 1 + block = b.encrypt(self.v.to_bytes(16, "big")) + ret += block + self._update(None) + return ret[:length] + + +for params in [params512, params768, params1024]: + kats_formatted = [] + seed = bytes(range(48)) + g = NistDRBG(seed) + + print("Generating KATs for {} parameter set.".format(params)) + + for i in range(100): + seed = g.read(48) + g2 = NistDRBG(seed) + + kseed = g2.read(32) + g2.read(32) + eseed = g2.read(32) + + pk, sk = KeyGen(kseed, params) + ct, ss = Enc(pk, eseed, params) + + Dec(sk, ct, params) + + kats_formatted.append( + { + "key_generation_seed": bytes(kseed).hex(), + "sha3_256_hash_of_public_key": bytes( + hashlib.sha3_256(pk).digest() + ).hex(), + "sha3_256_hash_of_secret_key": bytes( + hashlib.sha3_256(sk).digest() + ).hex(), + "encapsulation_seed": bytes(eseed).hex(), + "sha3_256_hash_of_ciphertext": bytes( + hashlib.sha3_256(ct).digest() + ).hex(), + "shared_secret": bytes(ss).hex(), + } + ) + + if params == params512: + output_suffix = "512" + elif params == params768: + output_suffix = "768" + else: + output_suffix = "1024" + + with open("nistkats_{}.json".format(output_suffix), "w") as f: + json.dump(kats_formatted, f, ensure_ascii=False, indent=4) diff --git a/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-1024.txt b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-1024.txt new file mode 100644 index 000000000..faf83043a --- /dev/null +++ b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-1024.txt @@ -0,0 +1,1040 @@ +01cd9c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f518d04204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +ffcf9c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f5f8ff4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af010dbd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c34112d0df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568afff0fbd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341f2ffdf1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9011dcab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a19d08ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9ff1fcab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737af9ff8ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a894101ad03d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bd14d04a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a8941ffaf03d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdf4ff4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +01cd9c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +3629d06874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c037db42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6844d02683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b4058d550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42663d00244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b4268355074da579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550284d079ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a509cd3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579aad0db4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3b0b4dac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdbcbd01658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac0d5d603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac16e8d03bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658600fcdc8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603b00d1afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c811dd35d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8af20d1d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd03513ad415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d045d15e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a541152d4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e6cd110d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4317dd47b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c431086d1b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d64719ad984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3d14244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3981b4dc3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a39842c4d1e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c31d4d6af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7e5d1f0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456a1fed80d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af001d2d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180215d240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d423d20477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d45324237d461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240447d21f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d45324047746254dcdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f69d2c6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cd271d1e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc681d247cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e29cdbf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47aad282fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf2bfdaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82cbd236880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa2d8d0c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36e8d2869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c2f9d62103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c8602d3103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262313d4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262102ad320cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a33cdc30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a204ad30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac3353d4ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c60d3e6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304c379d0999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce689d399039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce69909390d9e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999a3d37ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e3bfd48d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ec6d3d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef6483d8d53bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d0e2d3bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d082533f1d5c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc09d4980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c410d71e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c9820d4e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071431d959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e64cd49f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c95450db409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f62d409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b447bdb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b4098cd437098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb7490d8af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737a9d4f3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098a4bcdacc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6d4c98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6ac4d8d579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc9ebd49c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b574f9d521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c09d51d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c9952517d1295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d29d595153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d7912531d3b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d79129545d5672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b552d2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b676ad517d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d57dd12d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d1781d5d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d11259ed7d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5a8d54878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d5b7d274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d48c8d54e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878275d0d568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274ee1d58f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01565f9d81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f0bd6ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b8161dd0fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81cc25d6a8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50f63ed34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa84ad6bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea3465fd5fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bb61d6c892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15f679dc82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc882d62ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c869dd6a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82aa4d621a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a6bad0eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21c6d6ef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60e6d6d5aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eefe3d6a89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635a6f9da8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa80cd7c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca871bdcf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c928d7944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf734d5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944ad773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5775cd01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a57736ad7488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01778d0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488bd7d35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0a795da9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad3aad7ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa97b5dabe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9abcbd7e4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5bab7dcdcd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4e0d763a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd7fad0bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd6309d8c929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90b812dbc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929d83f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc839d0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f4ad890851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a02858d1b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a029065d879626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b876d6229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b7982d829c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626289cd4603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229a5d803b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c5468bbd83120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603c8d8120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b8838d0d0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b88312ecd818c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c038fcd113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c031807d93077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c711917daa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113027d94d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa935d7a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d40d9366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a956d06c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a3665d9c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506979d6b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c683d956d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b99dd883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56a1d93f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1889b0d9918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883fc1d918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f01999d1d2f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918e3d987592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f9f5d2b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f8709da5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592ba16d43e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b23dae842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343a34d323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842da3ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e84232a5bd713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323a63da3681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab371a78db0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681dade78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0a97dae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0dea8da607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78aeab7d65de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae60c3dade49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365ad4d267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365dee9da7fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de4926afad1d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267f06db5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61db19dae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b20db69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90aeb3dd78ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae6943dbab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378b52d626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab65db6791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab2562b79da71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626781db1dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a7b9fd93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dabdbea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93bb0d002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93eac6db2cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea0600bdddc32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002ce8db2ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c3bffd8d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32e02dc7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28dc13d587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e28dc7924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e3858c32d363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587944dc3c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e3858792436c51d55554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c60dc554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055c74d4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055558bdc7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4dc96d2b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7ca3dc144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632bcb4d958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b14cadc8a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a95cd9d39a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958ae1dca9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139cfcd61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a90add523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61d13d7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61522add4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7ed3bd8385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4c43dd85f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb383d5fd547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb3838562dd7aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f254d7ad12c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547a88ddc3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812d9ddb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3abdd7ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb9dbad9e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ec4dd7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49edddd3815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7ce8dd15a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd838dfad86a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd8381504dea6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486e13d3e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a627de179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373ee39d29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e174bdea65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29e55d005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a66ade5df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a00e7fd2b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005d83de4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32be97dbcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4fa2deb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcebadc5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2c5de371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5ed1d2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c537ecdecf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bef8d41bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf04dfbea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441f1ad2fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441be29dfe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92ff3cd183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe842df3c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c218f56da97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6cdf7b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca9f76d3480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b84df80d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b6434f9ddcd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480a8df62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cdfbdd4fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62c8dfe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84ffd7d99f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe1e5dff568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599ff6daf4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f508e04204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af010ebd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4224e09a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd031eba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a4be0594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba054eb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba596ce0668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5078e3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668be0c44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3f094e79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc4aae0397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a790b7e052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a7939cae02faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a050dae0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052feae069436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa050f4e6c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa056903e16515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c111ec5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6525e1098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5138e9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5094ae1c25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9b155e93cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc265e1cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc2559317aeb694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593ce83e194d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b619de2ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694a8e1c65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82a1b5e16268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac6c5e1268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac655161d8e58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac6551626ebe1a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b581ffea5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a000e2cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a521fe073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5ca2be23cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb0723fe43099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073c49e2099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943259e558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943096be28f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b55276e519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f8ce29a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c51290e96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519aabe2fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b962b4e93dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fcc0e2dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc40932dfe362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbe2e22c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362f2e7872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c03e372160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c2378311e0d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c23787226e37ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d33aeb627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7c47e327606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b6356e6ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b62760e3d1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606a37ce169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad188e39320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c816392e285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c81693a0e35b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320283b1e3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285bcae3deb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3d3dbe0d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddee9e37806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d3f0e183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806e43b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d780618412ecce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2be4e6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcc432e8cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce642e4b5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228c45ae66904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb561e4904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166474e6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166908ae481c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6149ce89041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181a7e4041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c7894b1e12af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c78904c6e4af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c7890416124d8eb2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612afe3e4c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b24f3e26aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c003e5aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c0332651fec468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aa28e568c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c453cea2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c46846e5fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2552ec2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa6ae5d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2571e2da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d888e5a2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182d599e1d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2a4e57f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d5b3e265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7fc4e55ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265dde4a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ee5e50ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a5fceb8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0a06e6f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8611ec997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f829e697a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c963ae6c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c99746e626d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c65de8c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c2664e616086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c670e6a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c1688e69d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a697eb25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9da7e65d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b26b8e705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25dc0e65da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80706daebf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705de2e6198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf6f8e05ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf1903e7ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305713e15a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba21e7a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115730ec655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a54ae755253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac6752e3044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac65565e744c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253077ce261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac65525304484e71e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c426791e1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261eabe772876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d7b8e6aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72c7e7ae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876a7d5eb1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aaee9e7e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b17f3e87bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e607e8bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787812eb0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ae8773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0833e95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0774ce8d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95857e7321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d060e821ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707387ae91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d07073218be8b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91892e6d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5a1e8937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d8b7e06b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d93c5e8b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d9375068deeb3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3e8e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b38f9e18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e40ce9c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c1891febbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c121e9d0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bb93eec1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd044e9b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1950e5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b16ae92f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c971ecf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f83e9496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf996e69cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf49a7e9cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf4967699b4e3f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769ccc6e965e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f9deecd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6e926953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd9f9e3692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd2605ea92722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd269536a17e2218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd2695369222ea18005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd269536927222a30e5bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd2695369272221840eadcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005ba5be5f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdc62ea165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25fa75e9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f168ceabbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9aa9ce18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbaceab06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18ab6e8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b0cbea50cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b80adce58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050ebea550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58af0e319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550ceb9cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c31b1fe43c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319c28ebc560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843b36e583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c540eb3d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c56058b50e499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d6beb9750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b49b75e231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499780eb1234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b49975023b93ec65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b4997502312a4eb5b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c6bb2e3055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65bc4eb55c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b2430bdce8d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055e6eb16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68dbf8e4d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d1603ec2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834dc16eaf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a2bec14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6bafc3fe6186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf1449ec86a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f961c5ae5d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f9618666ec5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65dc7ee5eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5d80ecaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05ec90e5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaaabec5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5acbfe76d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5ac0ecd574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076cd7ea1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d5e4ecda7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1cf7e34ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da03edee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334d14e489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee25ed9e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee4548d33e7e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e43ed147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337ed57e297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e146bed7e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b29d79e3936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e86ed36fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e9639d9fe084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936aced4f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc08db3e7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084fcbed8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7add3e4406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8ae2ed06422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a3244df4e2d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a32440602ee3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422de16e7a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f27ee4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677ae35e37965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a44ee965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437e55e5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437966bee15730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b51e77e0e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b511583ee949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730ee99e53ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e94a3eeac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353eb0e858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353acc4ee8d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac0485ed0e56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858deaeeaf7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56ef7ecf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af0cef340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccff10e93ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf3420efee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093f30e309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee45ef9736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee0530f53e799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309766ef9e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee0530973679f78e92018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e87ef018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792f98e33bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e879201a4efbf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433fb5e901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bfc5ef1574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf5590fd7ec341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf559015e4ef41b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c3ffbea9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c34102f0df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9011fcab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df2cf0b2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1cca039f5624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab245f024e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955605ef8f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab295562465f00413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f071f074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0483f04b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f041307091f10f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074ba8f0f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b18100b5fbd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f9c7f0202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd0d2f728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd20eaf08855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a720f5fba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728805f11c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba111f3a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c22f10d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a133fc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d4bf18855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc8155fc59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88865f19c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c5178f8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8af1afc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8b19cf329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafa6f19db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6321bbf79b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329dc7f1b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db7791d1fc5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b8e5f1d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c51f8f97c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d002f2c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d0829721efb328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c820f228c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b323cf8fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b32840f2a526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08f252faba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa566f2a4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526ab27afb6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba48af2c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6291f8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c2abf2653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c2b3f5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c65ccf20b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b2d1f5b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0be3f299ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b2fef24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b990cf3c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24311f9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c12bf3dccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9e33cf4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edc4cf3c3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4c35df31efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc362f3efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d23137bfa045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231ef87f345b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a039bf1af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045a6f3f546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61a3b4fc24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af5c6f34458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c23d5fac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c244e8f3876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac3f6f151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac870cf41626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c15412fcf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626f43a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf430f02f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a45f4f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502454f3d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f266f4850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d470f9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d858cf4038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a498f200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a03aaf40211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a204b1fabc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a2002c1f4c7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211ab4dcf85d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7e0f4d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c0854f9f12e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d208f5e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812513f5ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e029f5bff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395e53ffc236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebf43f536a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c255af4f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c23663f544c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f57cf4153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f4486f553e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64159ef9a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153a4f52ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a5bdf02f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ac0f5f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad0025def6976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e1f576b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e1695fbfc18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e1697601f68766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c1616f706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18726f66fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c187667063dfb7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706f43f6dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b765ef9d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dd66f629834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d678f4bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d2983f6ee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834b691f6f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834beea8f64bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f6bffb7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bc4f6abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b76def07175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe2f6175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe2076f5f89d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe2071703f7d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe20717538971bfb5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d121f7c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b573cf74e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c946f7e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c67475ffcdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e66af7d93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facd773f58f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd981f7f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158797f28e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f1a6f7e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f176287baf1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ccf797b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac117dbf0902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197e3f702b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b3097fbf277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b3090203f87366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b327816faf0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277326f80702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af830fa0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0742f8576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0856f12cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a05762f8cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a057621287df707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cf89f87b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd970894f424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707ba7f84971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47428b7fbfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b474249c1f8bb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bf8d7f011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbbe5f81cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75018fbf31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011c0af9b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba3191af8ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b225f9a062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58c936fa479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca042f979586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a4955f6aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a47968f9ad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586a974fa5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad8cf9890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5990f8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca589aaf9d805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8f9b0f151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd8c5f91d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805159d5f94df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151de2f9df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d52949f4f9803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df07fa03f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df4798a1ffb80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df47980324fa0d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b8a30f5b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d45fa19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055ba5afb7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b1961fac483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7a78fb280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483fa80c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b2a9cf2064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280a1fa64213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c120ab2f3b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064c1fa2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213badbf78eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ae2faeecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278afcfa661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278ee0cfb61ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca6b1af635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca6612bfb5fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab63b3bfc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635f4cfb36fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc4b5ff8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc4366afb12861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa84b78f1171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa841286fb71f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa84128611b9ffcc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171a8fb49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8ccbbbf56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49ccfbcf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56bd1fa8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cfebfb050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8bf0f07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050cfcfc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07c18f670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc2cfc0886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c67c38fae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670846fc29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886aec5df5762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae2960fc62c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d057c7cf6540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d0576282fc40d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c265c9dfc63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540a1fc3888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c6cb8fb7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c638c8fcd6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7cdcf047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6e9fc7cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c904cfdfcbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047c02fde8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbd1ffaa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe829fd378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aad38f14722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa3741fd722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114d52f1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114726bfd2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1dd7af7ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2c88fde2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87cd95f9dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2a9fdce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599ddb5f4ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dcec2fda6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524eddcfb83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6e4fd3cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b8dfdf2133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83c03fe33c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd321e1cf6db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd3213323feb8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36de31f2e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db846fe3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162ee53f681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c64fe1fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c3468e7df8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681f8afea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ee9cfc9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2a7fee80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9eb0f87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e8ccfed34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87ed4f73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d3eafee4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73ef8f2aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e401ffad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812af14faf218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad20ff218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40aff38f75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af214cffc2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75f55f1cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c265fff86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf76f07d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf886ffd43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607f93f9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d4acff3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9ffb0fa9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f37c6ffc30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9fd0f737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c3ecff7a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c73ff8f418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a19d08ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a894102ad03d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418c37d0d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca70304bda015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d251d015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a0067d8ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a01572d0cb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728c083d3e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb91d09d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e0a0d117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9db4d07aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04110ced8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117adbd084f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb820efd012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8d02fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f80110ad777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012f1bd17640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab77124dbe1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777630d11ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be14fd592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1e52d12f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef259165d3468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f73d168851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f5334188d1f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f53346895d18ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f1aad0087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8cb7d187a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca7001cad3b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087d8d168bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b1ebd67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68fbd1cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67209d47334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd19d2334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947224d75e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd99473339d2e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975243d5a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e655d29e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a265dbc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e70d232418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc284d8801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc3291d201458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc3241882a4d8b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801b5d23aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b2cad0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3adbd27b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d2e6d542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7bf8d22b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b6854305d1ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b18d3e5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581e32ed5990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee536d390897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e659348d7830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e6599059d330d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897836dd7a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e6599089783073d372a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a38adb849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a7296d349bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b83abd61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bbd3e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb613ccd1cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8d5d3ee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51c3e5d832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51ceef6d32793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee5683409d642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832713d42f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee5683279364420d3a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f35d429f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a44fd6bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a2950d4c1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06b46ad16b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc176d4b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616481d943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b992d43deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912944aed1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943dbbd490a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb104cadcb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090d9d4671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb4e1d904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb67fad44b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a90505d3f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b10d545fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f52fd052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f453ad52f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa05541d0cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f54d5f0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140c56cd57ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf075d5ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557588d3c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee94d52d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c5a8d18472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2db8d5472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d88185c2d102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d881847dcd52a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c105e9dcd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102af1d57afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd60fd5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7a1cd6fd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5a629d87a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd36d6a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687641d65676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a657d6676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765666d08de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a617656775d6de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508681d50a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de90d6a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de10506afdb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0bcd6bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb76cad2d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bbd8d60740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d6e4d063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d07f0d63ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d07400670cd01eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063a10d7eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001723d6e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb33d781fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e74fd5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e815bd760c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a76cda7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a6074d7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7783daafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7149ad7faf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaa7afd3a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafab9d762218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a7c2d8e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62d1d7760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e7e0d9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e76fbd7ded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9d80ddc44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dde18d84a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c4826d4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a3bd8e9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4d843d7d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de959d89c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d866d7badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c77d8add9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677b88dd942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677bad99d82f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9948a3d6f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942fb4d85b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f8c8d22ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5bd0d8ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b80228e8d2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022acfcd854c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a90cd3856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a5415d956224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c538922d4bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c5385632d9dae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224b94ed146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bda50d96136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae014963d636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146176d96acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae01461366398cd0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636a9cd94815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b9a1dbd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b48b5d9908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd9c8d6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd90dbd9c525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6b9e2dc0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc5f5d9f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0a06d32034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f017da034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732a24d8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732033bda42c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b81a4cd6490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b814251da90d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c164a6dd19fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c1649074dafc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419a88d873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc95da3eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc8587aaed56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873ebbdaf2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56accd02f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2d0daf1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002ae1d6bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1f2dab3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb00d5f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb317db5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075fb2bd6c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5b31db99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16cb46d2e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c9954db80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642eb6fd7b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e8075db4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57bb8fd479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4d90db9a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df047ba5d4e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479ab6db50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564ebccd8833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50d7db33485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c788be4d5936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833f8db36a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c788334859c0ad3c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c7883348593616dc38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63cc2ddcb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c3831dc8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cbc43dc9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8952dc050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9c60d0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9057adc7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0ac8dd4a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7a97dc54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74acafda28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54b2dc8788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a2cc8dbae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a287d8dce082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bace8dc946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae0f2dc46da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c9d0dd9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c9461add8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9ed27d7afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d35ddfe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757ad41d80b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe58ddb5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880d6dd747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b575dd7717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d574d81d698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747797dd8103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d574771769da0d538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d57477176981b3dd8098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d574771769810353dc9db177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d57477176981035380d8dd77386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b1de3d6d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177f8dd36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386de0ddbfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d3617deb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfe26da1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb93cdea6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1e4bd8d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a656de6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68de6bdbc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6a7ade5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababce84d31ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a95deea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea3dcb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531eab3de053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cbec3d79b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb05d2deb81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279ee1d84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b8fcdec6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84f0dd5bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c614dfb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bf2dd4aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb131dfa12258fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14af42d58fc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa152dffc407de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258f64d7de6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc70dfe6a9a5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407df8ada5dd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de699dfdd66a9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5fa6da9e16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5ddb6dfe16b6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9fc6d6bd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e1dbdfd6b9b3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bfebdb3bdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6f9dfbdb45a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b300be5a4a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 +36c99c6874b42683550244a579ca3bdb4bac1658603bc0c8afd035d0a5415e2c4310d647b6a3984244c3e7456af0e180d453240477461f49cdc6111e47cabf82fbaa36880c869262103a4a20cac30c304ce6990999039e7ef648d08253bc195c980071e61c959f02b409bcb737098af3c6acc98b579c99521d791295153b672a2d17d112d5e87d4878274e01568f9b81ccd50fa8ea34bbf15fc892c82ad46a21a60eef635aa89ca8c9b8cf944a5773ca01488b0ad35aa9ab5babe4c0cd63a90bc929bc3f9a0290851b79626229c54603b883120c0318c7113077aa4d507a366506c6936b56d1883f019918132f87592b5b6343e842323ab3713681b0de78ae607365de49267fa61d5b90ae69d378ab25626791a71dfb93ea06002cd8c32ef28d7e38587924363c1055554b4d7c632b144a958a9139a9ca61523a7e4cb38385f2547aa812c3dbb97ea49e7cd83815a486a6373e179b29a65a005df32b4f72bcb2a5c5371c2bcf8441bea92fe8c2183c6ca97b643480d8cd62d84fe17599f568af4204bd9a1bba594cb5668b3fc44a79397a052faa0569436c6515c5098a9bc25593cea3b694d82ac65516268b58a0f0a5cafb073cf943099b558f6c519a0b96fc4093dbf2362c237872160d7ca7b627606ad1c8169320285b1a3ddeb90d7806183b2bcce6228cb5a166904a6181c789041612af83b2c03326aaf8c468c6a2fa2ac2d8182da2941d7f34265ed54a0ac6b8f819c997a66c26d48c16086a9d77b25d80705da2bf198305ba3115a50ac655253044c4261e1b1d72876aae59b1e63787bf2ab0773c95d0707321ab91b5216d937506b4e3b3e49c18c1f1bbd0e4c1b10a5c2f13cf496769cc463f65e6cd26953692722218005bdcb25f165c9abbcc18b06b8050cb58550c319cf843c560583d0b499750231234c65b243055c68d16834d2a6baf14f96186a65d5de05eaa0b5a5af076d574a1da7334ee45489e337e147b297e963936fc084f3b7a8a324406422d3f677a4a5437965b5115730e949353ac04858d0a56af7ccf340093ee05309736799e8792018433bf55901574c341b2a9df1ccab2955624e58f0413074b1810f957bd202a728855ba1c123a0d3bc88855c59c8a8bafc6329db779b815c5d08297c8e0b328c08fa526aba4aab6c21b8c653c5b0b135b99ec24c11b9edccc4cc3d231efb7a045b61af546c24458ac876c151626cf3a0502f2463d850c9a038a200211abc7c085d29812e0395ebff3c236a34f44c64153e49a2ad002f1e16976b1c18766706fd3b7dde69d29834bee186f4bf4b7abe207175389d1b1b5c9c674e6facdd93158f17628e1ac1197b30902b3277366af0702a0576212cfd9707b47424971bfbb75011cba31b2a58ca062a479586aad4ca5890a8fd805151d5294df479803f4b80d055b19a1b7c483b280c12064213b2ab278eecca661ab635fbcc436fa8412861171f8cc49bc56cf1ba8050c07fc8c670886ae29d05762c26540d1c63888b7d6c9047cd2cbe8f9aa378114722b1d2ca87ce2599dce524ea6c4b83cd32133c36db8162e3c34681fda8ea2c7c9e80c87d34a73e4812aad40af218c75c2551cf86607d43c9f3706a9c30c737a89418ca703d2b1a015728ccb313e9d04117aeb8284f8012fab777640be1ef2592f533468851f8ca70087a83b68bb67cd9947334975e6355a9e50bc32418801458b3aab0d7b68542b581ee5e65990897830d37a72a6b849bb61e8c51cee56832793642f053a29f06bc1a616b912943deb1090a9cb671a904b503f45fa052f140cf0c557ee843c2d8818472c102a91cd7afc5afd9687a61765676508de1050a0fcb7bba82d0740063ac001eb336e81fb5a60c4a7143aaafaf93a62218e760b9dded8c44a6b4de9397d9c677badd9942f346f5b8022ac8c2a54c53856224bdae0146136636acc0b4815bd908b6bc525c0f06732034b8142c16490d419fc85873eeb56f2c002f1126bb3075f5bb16c99642e80f57b4df0479a564e50c78833485936a63c38d1cb8932c9050a0a7ad74a54f2a28788bae082c946da9e8d757afe1880b5d5747717698103538098b177386d36d7bfb96ca1a6b68d6ababc5a4531ea33cb053279b81c84c6d45bb1d14aa12258fc407de6a9a5dd66a9e16b6bd6b9b3bd14e04a06d763455b4da200013e681c43ea7c943eb186edf29664c5dd42fb0f240f61 diff --git a/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-512.txt b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-512.txt new file mode 100644 index 000000000..beefc9f75 --- /dev/null +++ b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-512.txt @@ -0,0 +1,775 @@ +01ad7a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a89912d05e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +ffaf7a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899f2ff5e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a249015d5123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892b11d0686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a249ff5f5123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bf1ff686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +01ad7a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d528d00eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a03ad81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0e4bd0e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab8105ad9135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e665d035d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59107dd8ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a5913586d0e46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68c096d5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce4aad0d0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5f0bcd49c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c6d0c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c6490dcdabf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7e7d0f2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7ab0f1d0394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf203d194465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf21303114d5cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf213039426d1c70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465c130d80ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc744d1ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480158d2b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba69d138834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b178d4a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b3883d13574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a197da3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a35a4d1897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a31b7d68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a389cbd1d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b681d0d7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d7ead129b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a781fbd5244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a782902d244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b252213d2aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b2524428d2ede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382a23ed73d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aed43d2d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373252d4e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d269d23d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e276d6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d8ad247da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6129dd6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147aad254d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c2bdd978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54c3d28851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3972d5d037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d39788e1d27fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851032fdd4ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037f05d3cd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54e315d4fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd20d3c450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504f335da27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc440d37067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a2356d145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067d35f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a2706714371d69f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f84d3f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f146939dd7a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8a1d31a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a3b7d5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1acad301b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a553dbd5c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501e7d36b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c3f1db12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b07d42a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b1410d9d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a26d49a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d438da2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a4ad4535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2455d3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2536cd485d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3347dd604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c338588d44f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d860495d2badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604fa9d4adcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592b4bcd2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcbd407f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb254dfd327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507e9d47a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9324f3d5a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a03d539d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a51dd9f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a3924d52e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f536d7076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e43d576ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637055edc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e6370766bd54612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc3571daa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34682d5137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa597d84213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa13a7d5213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa1377845b3d63b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa13778421c7d5b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa1377842137635d2d9f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9e5d5171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f5f1d05a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f1704d6a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f17140561ddb6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a928d6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6639d4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f04ad663953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a43659d3fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a436365d6c5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953f67ed6035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc587d635238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e760692d8c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035a3d605a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c6bad0afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05c2d6fe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20a6d4dc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afeebd6c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc26f8d567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c302d77709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c38256710da0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567729d7ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0734d5a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee46d72dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a75ed0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2d6ad715ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d77bd768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d158ad78f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba76790d73cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768fa3d7cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f03737b4d6c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cdc7d788e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c7ded16575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2d7575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2167f5d52ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2165709d8ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952819d1c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea21d8928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c838d28ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c9248d8ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828852d0d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae67d82cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d87fdb9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2c81d8c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9898d888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c0acd88226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888b2d196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c8882c6d86254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226198d5dce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c8882261962e4d80dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce8ffdbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0d0bd9ac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbe918d01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac2ad9ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01932d16b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee41d9b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116957db4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b969d9c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4977d612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c384d92fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c3746199dd04ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fa5d9ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd5049b5d3586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504acc5d986975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac55359d9d5cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586e7d9ff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975c9f1d2485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff08da85f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff1824a1fd0fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff18248529daa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa32d146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa340da6e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa32014a51d5cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e69daf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195ca77d4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf18cda59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4ea9cd87c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59a8dac5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887ab2d2f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5c8da2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282fad9da738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f22e4da38f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a7affdb7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a73807db267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7b17d37c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b72623dbc55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337b35da6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c54bdba83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6b53da640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a86adb40f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa6b7fd753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa64086db3700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f675b90da061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f67537a0db61e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a0bbed26448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061c0db448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026bd8d63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e02644eadbebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63bfad36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63eb0adcdcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36c1bd2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dc2bdc03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2ec3fd64d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e0342dcd84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264c54dab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d86bdc9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84babc79dc5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f81dccca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5c9ad0e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca4dc92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40ecbfd57324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92c8dc324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857cd4d74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f85732ecdcfa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74cf1dc02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa01dd2e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c0d11d5dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e29ddcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dd37d02deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc42dddeb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202d5bd3635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202de60dd35a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb036d7ad7340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb0363587dd40b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a773d9bd0b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340a3dd314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30bdb4d7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b31cbdd09ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b72ddcd4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209eadd26926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca44df9d6138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca442602de38c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca44269261e1cdaf8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca442692613826de8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6afe3dd95e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8a48dee8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e5cdbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e86cded74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbee74d39ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed785deac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539e93d884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539acabde4bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b88ebbd343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bcade3b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba34ed4d8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343bebded467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8aef6dc281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad407df81587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c2f15d7369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c28128df69a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c2815873f3ad29515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c28158736942df515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229f55d38bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a2295165dfbce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538f7ed7b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bc84df855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47bf95d42ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b85a7dfef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742fb2d3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742efccdfc756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3efd5da899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec7e6df99a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a8ffad495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a89902e05e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a249015e5123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e27e023eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575103ee18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e5751234be0619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18059e54beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb186166e0beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb1861965407de9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654be8ae03d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c093e74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3dace0111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c740b1e04968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c7411c0e0968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c741110040d8e36f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c7411100496e5e0f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c741110049685360fde25d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f702e1d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d22511ee2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d82ce15d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d138e1aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d46e1a1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861a15ee10fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa163e1fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e31017de99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fb8ae1c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda9919ae4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aae179c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c1bce742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3e12fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3741dce5a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fe2e114613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a1f6e3137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a1401e237db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613121de9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a146131372be2652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c232eafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c654ce2b1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652caf25ce5d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb165e2998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d278e47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998be2639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47299e57066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b4763a2e2066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b476392572b6e3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b4763925706cbe256948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b342d9e8e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456e4e243c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e2fce69d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e4301e3d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c16931fe985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d728e35f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f898336ea7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f49e3eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a735ae9c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eb63e32dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c37be930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2d8be30c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb93390e6eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930ca0e3b0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006e3b3e6129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0c3e329a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb033613dae78fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129e1e3fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a1783f7e454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb00e44a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb7045419e9ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a25e4e6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959c433e4d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce647e442c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d45ce2d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d4265e4439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d479e668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d438ae48b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a66493e2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668baae414870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a214b8e0bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114c7e4d36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870b4d6e1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd3eae428495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e4f4e5f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e2809e50c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f519e87884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c20e5884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087534e03d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c90878840e5d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c908788400355ae89b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d165e5b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a58957de0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b68ce5ee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0c591e8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0ceeabe5c25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8f5b5e9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc2cce52ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a5dceadb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ee6e5b78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6ad5f8e22d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb705e6d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb7852261de6f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d523e639d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f63de4ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f3948e6f6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84e65aea28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef662e68dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a267de012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28d87e62de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd70169ee961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012da7e61ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7966bce3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccce6099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c6d9e3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c09ece6b7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3a6fde67fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab709e7fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967714e1db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa26e7b129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461d732ebc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db149e76ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc75cecb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6e62e70d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb773ea6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d82e7e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a679fe748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0a0e78cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0747bcecbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8e7c8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cb7d9e6b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8e9e730e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b7feebe51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b3008e851108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be811e8add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be5120e8dd83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108a838eb9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add43e8863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9853ec3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9866ce8907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3877e10237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc39082e8237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210897e99df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc390721023a4e8df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc39072102374998b0e0b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499dfc4e855955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b8d9e5561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55e5e861359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b5595558f3e9ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b5595556105e9d10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359e910e29a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed122e9a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed1022993fe4eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a148e9b93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84e953e49b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb961e9b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb9314997febe29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b781e929aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be99aea12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29ace92ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca19bfeb10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12fc7e90201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b19d0e916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b102e1e96c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201919f8ea60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c03ea0b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a6a10e8c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b20ea10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008ca3ae3ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c1042eae81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ca51e7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce86ceadf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7aa73e7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf8cea7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7aa93eb8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a74a9ead068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8ab6ecad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d0c8ead1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068caadce81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1eaeae4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81afee4baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e406ebaef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64bb1fe6384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64bae24eb84c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef463b3ceb0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef4638440ebe59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0b59e56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e56bebeea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56b7ae6d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56ee86eb1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66db90ea644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1eabeb44108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba6bb1e8bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644c0ebfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bbd0e83e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfae4ebe92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483bf2e4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e90ceca91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fc11e83a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa923eca36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383c36e52b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a340ecb8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052c5ee7fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b862ecde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fc70e93719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde89ec719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993c99e4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde099371acec84787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c43cb7e7f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384c8ec2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787fcdae44e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ce2ece663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244cf6e134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e603ed4d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e66313d18e0dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d26edcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dd38eb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd4bed2166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb0d56eb58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166ed8180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b5d78e740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180ed0b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b5818074d97e600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740babed0b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b60db1e6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600bcaedd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bdd3e405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd0e5ed5bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd03540dfde09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405b0beebf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09e10eb5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf28ee550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5e30e56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5554aeee237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e53eabf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e267eef3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abe79e7851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf388ee51dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf39878e9dea5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851aceed841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5eb4e071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d8c1ee1739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d84107ed3e694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d8410717e9ee4ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d84107173969efce1afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694e05effa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51af19ec9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa28efcb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9f36e01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb4cefd1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01f52e1e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d169ef2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291ef7ae0d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2c84ef34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40df93e1dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34a8efc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dfb2e93eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc4c7efeab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793fdbe892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eae9ef2bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab989ffbe8a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892b01f0686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +01af7a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d528f00eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a03af81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0e4bf0e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab8105af9135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e665f035d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59107df8ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a5913586f0e46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68c096f5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce4aaf0d0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5f0bcf49c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c6f0c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c6490dcfabf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7e7f0f2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7ab0f1f0394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf203f194465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf21303114f5cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf213039426f1c70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465c130f80ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc744f1ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480158f2b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba69f138834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b178f4a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b3883f13574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a197fa3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a35a4f1897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a31b7f68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a389cbf1d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b681d0f7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d7eaf129b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a781fbf5244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a782902f244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b252213f2aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b2524428f2ede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382a23ef73d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aed43f2d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373252f4e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d269f23d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e276f6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d8af247da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6129df6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147aaf254d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c2bdf978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54c3f28851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3972d5f037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d39788e1f27fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851032fdf4ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037f05f3cd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54e315f4fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd20f3c450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504f335fa27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc440f37067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a2356f145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067f35f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a2706714371f69f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f84f3f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f146939df7a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8a1f31a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a3b7f5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1acaf301b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a553dbf5c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501e7f36b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c3f1fb12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b07f42a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b1410f9d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a26f49a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d438fa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a4af4535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2455f3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2536cf485d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3347df604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c338588f44f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d860495f2badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604fa9f4adcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592b4bcf2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcbf407f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb254dff327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507e9f47a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9324f3f5a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a03f539d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a51df9f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a3924f52e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f536f7076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e43f576ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637055efc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e6370766bf54612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc3571faa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34682f5137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa597f84213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa13a7f5213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa1377845b3f63b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa13778421c7f5b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa1377842137635d2f9f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9e5f5171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f5f1f05a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f1704f6a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f17140561dfb6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a928f6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6639f4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f04af663953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a43659f3fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a436365f6c5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953f67ef6035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc587f635238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e760692f8c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035a3f605a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c6baf0afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05c2f6fe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20a6d4fc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afeebf6c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc26f8f567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c302f77709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c38256710fa0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567729f7ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0734f5a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee46f72dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a75ef0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2d6af715ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d77bf768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d158af78f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba76790f73cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768fa3f7cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f03737b4f6c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cdc7f788e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c7def16575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2f7575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2167f5f52ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e2165709f8ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952819f1c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea21f8928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c838f28ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c9248f8ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828852f0d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae67f82cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d87ffb9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2c81f8c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9898f888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c0acf88226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888b2f196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c8882c6f86254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226198d5fce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c8882261962e4f80dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce8fffbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0d0bf9ac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbe918f01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac2af9ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01932f16b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee41f9b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116957fb4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b969f9c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4977f612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c384f92fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c3746199df04ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fa5f9ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd5049b5f3586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504acc5f986975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac55359d9f5cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586e7f9ff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975c9f1f2485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff08fa85f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff1824a1ff0fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff18248529faa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa32f146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa340fa6e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa32014a51f5cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e69faf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195ca77f4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf18cfa59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4ea9cf87c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59a8fac5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887ab2f2f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5c8fa2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282fad9fa738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f22e4fa38f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a7afffb7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a73807fb267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7b17f37c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b72623fbc55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337b35fa6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c54bfba83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6b53fa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a86afb40f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa6b7ff753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa64086fb3700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f675b90fa061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f67537a0fb61e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a0bbef26448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061c0fb448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026bd8f63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e02644eafbebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63bfaf36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63eb0afcdcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36c1bf2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dc2bfc03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2ec3ff64d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e0342fcd84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264c54fab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d86bfc9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84babc79fc5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f81fccca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5c9af0e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca4fc92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40ecbff57324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92c8fc324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857cd4f74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f85732ecfcfa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74cf1fc02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa01fd2e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c0d11f5dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e29fdcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dd37f02deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc42fddeb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202d5bf3635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202de60fd35a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb036d7af7340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb0363587fd40b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a773d9bf0b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340a3fd314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30bdb4f7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b31cbfd09ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b72ddcf4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209eafd26926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca44df9f6138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca442602fe38c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca44269261e1cfaf8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca442692613826fe8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6afe3df95e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8a48fee8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e5cfbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e86cfed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbee74f39ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed785feac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539e93f884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539acabfe4bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b88ebbf343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bcafe3b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba34ed4f8ad467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343bebfed467c281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8aef6fc281587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad407ff81587369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c2f15f7369a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c28128ff69a229515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c2815873f3af29515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c28158736942ff515538bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229f55f38bce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a2295165ffbce47b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538f7ef7b855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bc84ff855742ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47bf95f42ef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b85a7ffef2c3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742fb2f3ec756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742efccffc756a899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3efd5fa899a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec7e6ff99a2495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 +d5a87a0eab81e6a59135d68ce46a5fd0c649c7c7abf2130394465cc70480ba892b38834a3574a3897b68d70a7829b25244382aede373d2294e3d6a6147da6c54d3978851037fd54ecd504fc450a27067145f1469f8d17a1a7a5501b75c6b17b12a069d9a8aa2535c3385d8604f592badcb2507f9327a335a39d49f2e637076ebc34612aa137784213763b9259f171405a9d8b6f09a4363953fc5e76035238c05a20afe4bc2c382567709a0ee465a2dea0d15ba768f0373cd476c88e216575952ea911c928828ae270d2cf1b9c08c888226196254ce0dfbbeac8a01ee2116b979b4c374612fd504ac553586975cff182485f90fa320146e195cf17c4e59c887c5282f2294a738f7b7267337c55ba6a83aa640f6753700a061e026448a63ebaa36dcbb2e03f264d84bab9f91c5cca40e92f857324c74fa11c02e195dcc7202deb03635a77340b30b314b7209ca4426926138c6af8ad895e8ccbed74539ac3b884bba343b4b8ad467c281587369a229515538bce47b855742ef2c3ec756a8ffaf495e575123eb18619654beda9c3d3c74111004968536f7d225d8ec2d5d861aa1e310fbda99c1aa4c79c3742fc25a14613137db9c652cafb1c55d998b47639257066b3456948e43c169d7f8985f69a7eba39c2dbb930c006eb0336129a178fb70454a959ce6374d42c52d439a668b3a2114870bd36a1e28495f0c9087884003d1a589b6dc0cee1b8fc25c9a2ec6adb78522d5d36f39d84ef6a2a28dd7012de7961ccc3c099c3ab7d967fa461db129bc6ec2cb0d32a6e0f0748cc8cbc8996b30e8be51108add83b9863cc3907210237499df040b55955561359ed10229a1f84eb93149b7f1be29aca12ff7b10201916c83a60b008c10a23ce81c7adf3c7a7439b8d068cad1ca81e4e64baef46384c0b0e59b56eea66d1e0ba644108bfa0483e92c4fa91383a36052b8e27fde0993719c4384787f2ca244e663134d860dcd8bb02166b58180740b7b600b1a6bd035405bdb09bf08b5550a56e237abf3987851dca5d841071739694ec51afa98c9cb6c01d1291e2ca40d34381dc42793eab9892bb18a686ddad47c11870708ba4b868576f99751170f40db41b41aa3cd1eb8605d8b66 diff --git a/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-768.txt b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-768.txt new file mode 100644 index 000000000..a4c4e54b9 --- /dev/null +++ b/libcrux-kem/tests/kats/invalid_modulus/ML-KEM-768.txt @@ -0,0 +1,780 @@ +01ed5aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabff16d072a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +ffef5aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabfff6ff72a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65701adb671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338312d08256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe657ffafb671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d41513383f2ff8256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d415133836213015db6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d413d0b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d415133836213ff5fb6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d4f3ffb18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +01ed5aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +5624d0a4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45a034d7cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa442d0d3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427c05ddb1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd364d0db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1072d7c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db87d06322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c092db268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c63a2d068627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b20b6d7ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268c2d0e708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627c0d0dcb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce7e8d0397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb0f7d8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb390cd15dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a11dd14959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5d27d1959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714139d5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714954ad10eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e15adba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0e6bd15958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba175db23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5988d13950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b2195dc2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b239a0d1ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c21bfd86b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccc3d1b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf3861d8d8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b1ead139ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a851fed79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a85390cd2c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79210da61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c428d21002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a6230d206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61042d26e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a6100220256da063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68d263304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a0273d4f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a06380d2607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f297d41cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f60a9d2cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f6079412b9d4a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941ccc0d285d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a2ddd39c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85e6d2c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d6392f7d850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c702d30dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c7728531cd95d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850d29d3d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc99533ed18e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d146d3e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e61835fd28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e36cd3880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28370d4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28888bd306187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b45391d7157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506a8d357c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b450618713bcd05e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c0d3e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c0053dcdbc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7e0d35f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc3f2d136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f03d46020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f2313412dcb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020d48a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb434d07c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a40d4c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a400745ad177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c06cd47b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac17471d51f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b81d4f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151494d6f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6a2d47ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f4bcd2441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec3d441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec3244d3d4aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441e8d4a96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384a4f6d316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa90ad56dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a3151dd850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316d23d50b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd385533d13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b4ad5d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a1355bda81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d063d51bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a857dd2378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81b83d578c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32359cd4e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378a3d5015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e5b5d6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e01ccd586dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a5ddd7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86ecd5b7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7f5fcd398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb70cd68b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc39618dc1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b26d6ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1638d687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee4ad67329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a68652da80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687369d60b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a8679d83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b8bd6ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83697d7e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ada8d65e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e6b2d6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5ecad60369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f6d6d698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f03e9d68de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369696fed4bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698d06d7b17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64b717d63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb12cd7600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63730d78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63604ad7007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78757d82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78006ad7f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82778da301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98cd701502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca3795d2b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301a0d75247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b7b4dc379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b52c7d779434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c37d4d4aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379e3d7a0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434a7fbd9a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa001d89b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a817d0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b2bd88d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b838db39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d48d89dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b385ed4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39d6cd8b9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4e87bd622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb986d82c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b662898d895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622ca9d85468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89898b6d111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c898954c8d81c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468118d1da03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111ce9d83ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a08ffda837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03f0bd937e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba891eda17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba83725d97c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a1937d4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c4ad965372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a44953d2679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a446567d979b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372697bd0ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a446537267986d9cbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60c99cd7fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccba2d9ab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27f9b0d31ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fabc2d9ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab02319d8d677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231adebd97852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b679f5dc628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677802da28d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c6a1dd4d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c62826da5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64da39d0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c4bda0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0ca51db0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0265dad67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0a77d53dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d682dadea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253a9adb0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0dab4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0abed0baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4c0daaa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00bad4d8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baaeada89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8faf1d5a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f8906db3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165ab1ad431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3a28db1ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa843b3ed80d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431c49dbd2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980b58d8934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d269db34cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d28989b7cd2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d28989348cdb32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2fb9ddbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32abdb146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbfbb6d636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf14cadb6a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a63bd6d3416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636ae2db16947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a6234bf9d7acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a62341604dccb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947ac15d8c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb21dc2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518cc36d90212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d49dc212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990c52d949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990216cdc9ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c94c7ed400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949c89dc0f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce940c97d68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400facdcced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68cbddc233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68cec4dc33168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c2cd1d8c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233e6dc9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168ccf2da11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b07dd1157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a1d15dbd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11127dd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bdd31d27ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c46ddebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627d5fd8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627eb6addf1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8ad7fd117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af18bdd7cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb11d9fd02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cacddff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02db1d3ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ffc9dda3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193bdd1d3f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3e3dd73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133fdffd8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f730ade00802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa80e18d2532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa800020de32fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa80008025e3fdb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa80008025324cde2dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb4e5cd90cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42d64decc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490e71d8009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc82de09f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc1280e9fdb2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009a2deab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2eb4d10eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2abc1deeb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110ed7db04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110ebe7de4bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b0efdd7716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04b02df16d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd277f1dd649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd2771620df9b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d064f34dae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49df4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49aef52da9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e68df782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9f72d06eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a97885dfeb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506f95d7e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eba1df9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517efbed14e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9bc5dfe5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514fdcdabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5eadfffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffed5772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabff06e072a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65701aeb671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe6577226e071163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b6031e3f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b67146e056e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f05ee2e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f5664e056852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e078e2357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e5685e057dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852309de123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357ace03f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc120b1e8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123fcbe026f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b820dfe4cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226e9e0d35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94c0f5e54e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd307e1e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754119e517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e026e17ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e0965113fe28e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517e42e1e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228154e95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e36ae1f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95173e6cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f288e1c9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386c193e6765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9a9e165dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc939671bde9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765cce10cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e1dbe23fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0ce3e1fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb3231fee072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fd04e22992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde407219ea51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072922e21c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a5236e5bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c44e2c592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645b259e749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc562e29bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc5927427fe403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749b81e23dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf14029ceb62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403da7e22e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62b6ea5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62ec3e2e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a52dbe31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9ebe2ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb312fbe0c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ff00e38dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c31ceb168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8d2ae368714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab1337e4b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab16841e3845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b355e11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b846ce3e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11371e3f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e286e399d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f39de924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99a3e34809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3923b0e746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d39248c9e36c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809743d4e3608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746ce0e308a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c40363fae6c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c40360802e47a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c412e2d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a28e402f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d43fea622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d0248e422277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a6452e7ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a62267e4bc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277e478e957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8ce47b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c95498e409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957ba9e49d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89404b7e6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409dcbe481d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b674dde42fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781e0e4fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d0424f3eab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb0be568e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab51eea868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab6821e568d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a853deb4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a86840e5ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b455de2864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ea68e564831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead828578e1d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead8286483e540a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d59ae5d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a9e568da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d5bde0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68cae5a813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0c5d1eadcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca8e3e5caf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813ad5ffebd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adca06e61b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd610ea100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b22e600f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a163fea0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a10045e6ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0658e642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea6ce62485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c64678e785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485e65d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c64248578696ec0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785da5e6c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c06b1e96d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c3c6e6d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c316966d3eb7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d8e9e6fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b76f6e90ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc01e7ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190717ebe1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae23e71732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be733eaa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1742e71a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa758e90801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a61e7801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190771e9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190808ce7781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a791e03b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a78a1e7b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a7811037b0eb2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b3c3e7626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b27d6e03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b262ece7b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c037fce522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b209e82c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c952813eb499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c22e899babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b483bebf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b4994ae85bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf85ee0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5b6ae8a4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0a87aeae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa485e8527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae897e410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae52abe80be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b418beea52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410bc2e82d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a58d5ec58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52de4e88ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58fce78d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58a09e9d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978918e8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d32be94d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c932e9a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d44e920f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a95fe10294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a2064e9294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410974e938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410298ce98e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c93990e22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938eabe9ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b229b6e7649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ffc2e949f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff62769dfe8fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649e6e9ef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68f9f8e0825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef08ea25faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef8808a1fea57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef8808252aea7207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa5a30e401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57247ea1bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa5720740a5feaefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401b69eafb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aea70e542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb87ea2fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb0754a9aebcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6eafac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcabce94cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac4eacd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494ad1e77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cdebea133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77af3e34e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b771300ebe8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034b1ae481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e82ceb1224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac48b32e059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481244eb9d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac48122405b54e6ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d68ebf640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486fb74ebce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff680ebe7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bcb91e1013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7a1eb13f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce71110bbfe8177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013c3eb77db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f381bdde64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177ebebfef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64bffe89c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fe07ecc205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c10ea4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c225ecbb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4c30e3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb4aecd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fc54e35dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd566ecdbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635c7ce4f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635db81ec5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14fc9de2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cabeca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ccbdebaba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9c9ecba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9bacd6e7fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9babae5ecc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fcfbe83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc10bed847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83d17e0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83842ced44981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c01d39e1dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c014448edc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dd5de8f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc362ed9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28fd7de760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9e83ed0a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed376d91ea5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760aa3edd61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5db1e3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d6ccede8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3add2e4f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8e9ed8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294fdf5ec5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8700eeb8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5e1ee6faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b822eeaf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26fe35ec3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf41eeff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3e57e39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff6cee986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39e76e81862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c399883ee862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381e92e33f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c3998638186a5eef7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533ebdece3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7c8ee3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ceed7e1781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3ce9ee81a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c7917efae95e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c79178108efe683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895f18ec08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e623ef8384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c0f38eaf211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08344ef211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384aff51e4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af216bef57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4cf77e3d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c5785ef84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753df9ee9f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84a3ef64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39ffb6e6d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64c0ef4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606dfd5e338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d41e1ef8362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d415133ff6e138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338302f08256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d415133836213015fb6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138226f0be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6037fad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be43f06faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad05af2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6f6af0902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c072f684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c908cf04b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c68098f794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684baaf04690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a790b9fa1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a7946c0f0a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a10ddf39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7ecf0770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc390f0f2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770cf139cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2711cf0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c27392bf10dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e13df53aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0d46f1aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653152fa334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa66f134fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a317ff21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a3348cf1506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21196f44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc2150acf1716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c441b6fcbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c4471ccf1e5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccb1dcfa74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5ebf14d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba71f7fcab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d08f2b1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78ca217f9e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab125f26b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e239fc24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b48f24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c2252fc8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24360f2d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8273f0592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d588f292579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d53805295f9adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592a7f2dfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579a2bcf1e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc9f259398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e2d3f8f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59e9f2785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f2f5f9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f780bf30103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a310fcdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0123f3cd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cd331f140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd4cf30040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c14354fcb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140060f37b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb370fc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b8bf3f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1397f50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f6acf3ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c503b3f6ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50eec5f3b40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356a3d0f5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab4ecf34096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b3f9f237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4006f47283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b409623418f758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237223f48bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b40962372837543bf71596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758b41f4596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171456f7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596cf4d028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7e472fc6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed088f4d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6492f475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d2a6f45928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226474b2fa7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d2264759c8f4485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a74d5f44895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a748e6f4895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a74856444f5f36acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a74856448909f5acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a748564489593651ff41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936ac2bf5e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41538f0b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e540f55959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b555fb10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5969f50a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b1575f3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a8bf577645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b38596f5f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877a4f54b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f5b8f9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4bccf52275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b5d7fbbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b22e5f5d8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bb5f9f6b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd800f69631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b613f972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9621f62b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b963197637fc240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b40f640f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c265ff406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c24069f66c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f940678f0668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c85f668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850669af54ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a1f6ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a1546b7f672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154acc7f62890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77676d9fc6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac776728e0f6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c66f4f4efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f304f7fed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444e71df418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efe29f78e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed941733fc79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e4af79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac775afc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79f6cf7da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1770f6b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da83f75cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b79bf8442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5ca1f742ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb1847bef9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442caf7195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c7d5f53b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c19e3f7b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c1953537f7f86c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b404f8c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486818fa67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c72cf87bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca683ff0f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67b43f84fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f85dfa1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4f61f8a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1879f6efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a884f8fa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946e893f2ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efaa5f8e02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352c8b2f36f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce0c3f8f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce023368d3f2c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4e3f81e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c8f4fbbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e0af9bd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abb911f610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd29f90acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd196193cfa1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610a4cf9eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca195af255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eb62f95de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba22597ef4121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255d81f921c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14199cf878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121a1f98e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1879b7f04236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878ec7f9236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e77049d6f20a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e770423e7f9a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e77042367209f4f74d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a808fad391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874a19f302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d321fa2b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d39130a33f5e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b40fa3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305ea58f9237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d65fa37532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d8592a75f2f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d85923783fa00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532fa9ff727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00a8fa7536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f872ab3f921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f87275c6fa1289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f872753692ad8fc4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f87275369212e9faa9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4afdf8dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a904fbcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48db15f61b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb22fbb5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b3ef03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b54afbfaac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03b5af113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03fa6cfb3c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac11b73f91a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c83fba4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391b9ff005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4a8fb5deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f800bbef4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005dcbfb99fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb49bdffb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999ecfb0f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb1bf8fb88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f01fc8b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b8c12f53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2bfcadc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53c3cf71130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53ad47fc130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771c50f24d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc7711367fcd376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724c77f079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d386fc9616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d37607c91f736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d3760796a6fc6d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d37607961673cb1f5c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736dc2fc8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125ccd0f933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c85e9fc3174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c850993cf7f638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933104fd8884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c850993317463d18fc5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638824fda9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5d3ffc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a94cfda2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9d5df2ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a266fde1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62cd7ffcb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce18cfd98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccbd98f6824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98a5fd24f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb988568dbffbff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824c4fdf36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bfdd6f39e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff3e7fde8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739dfafc0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e803feb6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0e1bf2daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b623feaa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32de32f2f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa42fe6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222fe53f840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6962fe0fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f693284e7cf526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840f85fe6d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc552e98f6e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526da6fe4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866eeb7f2daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4ac7feaa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772ded1faab13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daae0feb13896b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aaef3f96b0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab108ffb0138fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896f11f8fee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b023ffee6430e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138ff36f30e769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee44ffe769ce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430f56fce475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ff475a418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769cef75f418b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce478aff8b653fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a41f96f3fbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418ba5ffbbec4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653ffbef4954a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbccff54a400d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec49fdaf00d44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954e4ffd44323b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400ff4f23b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 +56e45aa4427cd3d4b1db277c6322b268627ce708cb397c8a5dd714959a5e0eabba5958b23950c2ccf386b18a8539ec79c408a61002206e68a063304f607941cc904a85d639c772850dc995d1e618e3fc28880b4506187157c005e7c0bc5f23136020cb8a4007c0ac177b1151f6426f7ec32441384aa96a316dd3850b3a13d0b3a81bd32378c34e015c6a86dc7fb7cc398b86c1ee8a687329a80b9b83ad787e5e2a6f0369698de64bb17c63600a78007a82f98ca301502b5247c379434aa0b19a9b7b0b8d88b39dec4eb9b6622c89895468111c19a03ffba837e5a17c7a4465372679b60ccbc27fab0231ad8b677852c628d64d5c9b0c0215b0d67253dea0b0b4e00baa4a8f89165a3aa8431ce980d2898934cc2f32dbbf146a636a623416947acb518c2d6990212c949ce9400f7c68ced4c233168c9b27a11157bd4c1627ebfa8af1fb117cfc02ff193ba3133f73fa8000802532fcb42dc490cc128009f2b2ab4110eb77b04bd27716d0649b49ae4e28a9782506eb517e9be514e5caabffe65772a6b671163f56e42e56852357dc123f1b8226f94cd35754e096517ef228e34a95f2386cc9396765dc9e0cb323fde4072992a51c645bc592749bf1403dc7b62e63a5e9bb31ffb00c8dcab168714b845c11e2163f99d3924809746c403608a26c7a282d02f8a622277ebc8c957b89409d7b6781d042fb3bab68e1a868d0b4ead82864831d40a95d68da0ca813adcaf6bd1b02a100f5a0ea8c642485785d65c0c31696d839b7fc6190ae73be1732aa1a8190801c9a781103b303b2626c03b2c9522c32b499babf5bea0aa4a5ae527b410be2a52d54c58ac978d38b8c4d249a20f410294c938e0b22ff627649f68fef880825faa57207401bf9aefb07542fa6bcfac494cd1b77133034e8ac481224059d486ff640bce7111013f38177db64fef789c205a4bb0a3fd54635dbc14f5cdb2ca9d9baba657fc1bb83847c0144981dc3d28f9ed3760a13a5d61c3ae8294f8750c5b8e26faf51c3ff7c39986381862533f7d8ce3c791781a895e683c08384af211b4c57753d84e39f64606d4151338362138256b6be73ad6faa2c902c684b8a794690a1a7dc39770c2739cb0e0dd653aa26a334fc21506c44716ccbe5cba74d78cab1759e6b98c24320c8d5380592579adfc91e59398f785b9a0103cdcd1c140040cb7b0bc1f67c50ee356ab40c5b4096237283758bb171596c7ed028c6d226475928a7485644895936acfb41e5800b5959b10a5b3877645f4b8c9b2275bbd8906b9631972b70c240f9406c850668a154ac77672890c6f3444efed9418e3ac79facc1da036b5cb18442ea9c195353b47486c78ca67bf30f4fd1a1a8946efa352ce02336f4332c1e4abbbd19610acca1eba2255de14121c1878e7704236720a84874d391302b305e3d859237532f00f8727536921289c4a9d48dcb5261b5ea03faac113c3391a4f8005deb4999fcb10f81b88b2b53adc771130724d376079616736d125c8509933174638884c5a9fcc9a2d62ce1fccb98856824f4bff36739e8a3c0b6b32daa222f6932840fc5526d866e4a772daa10aab13896b0138fee6430e769ce475a418b653fbbec4954a400d413d0b18a1fc09e8d8e659c09c820a9f01b67bf9c0ed59f7f83d130821ba275165a86 diff --git a/libcrux-kem/tests/kats/kyber.py b/libcrux-kem/tests/kats/kyber.py new file mode 100644 index 000000000..60b6463fe --- /dev/null +++ b/libcrux-kem/tests/kats/kyber.py @@ -0,0 +1,363 @@ +# This file is: +# https://github.com/bwesterb/draft-schwabe-cfrg-kyber/blob/a03ab13c241a1a0b6adc676d27be79843b03abc8/kyber.py +# with changes made to match the FIPS-203 draft as well as formatting changes +# made by the black formatter. + +# WARNING This is a specification of Kyber; not a production ready +# implementation. It is slow and does not run in constant time. + +# Requires the CryptoDome for SHAKE. To install, run +# +# pip install pycryptodome pytest +from Crypto.Hash import SHAKE128, SHAKE256 + +import io +import hashlib +import functools +import collections + +from math import floor + +q = 3329 +nBits = 8 +zeta = 17 +eta2 = 2 + +n = 2**nBits +inv2 = (q + 1) // 2 # inverse of 2 + +params = collections.namedtuple("params", ("k", "du", "dv", "eta1")) + +params512 = params(k=2, du=10, dv=4, eta1=3) +params768 = params(k=3, du=10, dv=4, eta1=2) +params1024 = params(k=4, du=11, dv=5, eta1=2) + + +def smod(x): + r = x % q + if r > (q - 1) // 2: + r -= q + return r + + +# Rounds to nearest integer with ties going up +def Round(x): + return int(floor(x + 0.5)) + + +def Compress(x, d): + return Round((2**d / q) * x) % (2**d) + + +def Decompress(y, d): + assert 0 <= y and y <= 2**d + return Round((q / 2**d) * y) + + +def BitsToWords(bs, w): + assert len(bs) % w == 0 + return [sum(bs[i + j] * 2**j for j in range(w)) for i in range(0, len(bs), w)] + + +def WordsToBits(bs, w): + return sum([[(b >> i) % 2 for i in range(w)] for b in bs], []) + + +def Encode(a, w): + return bytes(BitsToWords(WordsToBits(a, w), 8)) + + +def Decode(a, w): + return BitsToWords(WordsToBits(a, 8), w) + + +def brv(x): + """Reverses a 7-bit number""" + return int("".join(reversed(bin(x)[2:].zfill(nBits - 1))), 2) + + +class Poly: + def __init__(self, cs=None): + self.cs = (0,) * n if cs is None else tuple(cs) + assert len(self.cs) == n + + def __add__(self, other): + return Poly((a + b) % q for a, b in zip(self.cs, other.cs)) + + def __neg__(self): + return Poly(q - a for a in self.cs) + + def __sub__(self, other): + return self + -other + + def __str__(self): + return f"Poly({self.cs}" + + def __eq__(self, other): + return self.cs == other.cs + + def NTT(self): + cs = list(self.cs) + layer = n // 2 + zi = 0 + while layer >= 2: + for offset in range(0, n - layer, 2 * layer): + zi += 1 + z = pow(zeta, brv(zi), q) + + for j in range(offset, offset + layer): + t = (z * cs[j + layer]) % q + cs[j + layer] = (cs[j] - t) % q + cs[j] = (cs[j] + t) % q + layer //= 2 + return Poly(cs) + + def RefNTT(self): + # Slower, but simpler, version of the NTT. + cs = [0] * n + for i in range(0, n, 2): + for j in range(n // 2): + z = pow(zeta, (2 * brv(i // 2) + 1) * j, q) + cs[i] = (cs[i] + self.cs[2 * j] * z) % q + cs[i + 1] = (cs[i + 1] + self.cs[2 * j + 1] * z) % q + return Poly(cs) + + def InvNTT(self): + cs = list(self.cs) + layer = 2 + zi = n // 2 + while layer < n: + for offset in range(0, n - layer, 2 * layer): + zi -= 1 + z = pow(zeta, brv(zi), q) + + for j in range(offset, offset + layer): + t = (cs[j + layer] - cs[j]) % q + cs[j] = (inv2 * (cs[j] + cs[j + layer])) % q + cs[j + layer] = (inv2 * z * t) % q + layer *= 2 + return Poly(cs) + + def MulNTT(self, other): + """Computes self o other, the multiplication of self and other + in the NTT domain.""" + cs = [None] * n + for i in range(0, n, 2): + a1 = self.cs[i] + a2 = self.cs[i + 1] + b1 = other.cs[i] + b2 = other.cs[i + 1] + z = pow(zeta, 2 * brv(i // 2) + 1, q) + cs[i] = (a1 * b1 + z * a2 * b2) % q + cs[i + 1] = (a2 * b1 + a1 * b2) % q + return Poly(cs) + + def Compress(self, d): + return Poly(Compress(c, d) for c in self.cs) + + def Decompress(self, d): + return Poly(Decompress(c, d) for c in self.cs) + + def Encode(self, d): + return Encode(self.cs, d) + + +def sampleUniform(stream): + cs = [] + while True: + b = stream.read(3) + d1 = b[0] + 256 * (b[1] % 16) + d2 = (b[1] >> 4) + 16 * b[2] + assert d1 + 2**12 * d2 == b[0] + 2**8 * b[1] + 2**16 * b[2] + for d in [d1, d2]: + if d >= q: + continue + cs.append(d) + if len(cs) == n: + return Poly(cs) + + +def CBD(a, eta): + assert len(a) == 64 * eta + b = WordsToBits(a, 8) + cs = [] + for i in range(n): + cs.append((sum(b[:eta]) - sum(b[eta : 2 * eta])) % q) + b = b[2 * eta :] + return Poly(cs) + + +def XOF(seed, j, i): + h = SHAKE128.new() + h.update(seed + bytes([j, i])) + return h + + +def PRF1(seed, nonce): + assert len(seed) == 32 + h = SHAKE256.new() + h.update(seed + bytes([nonce])) + return h + + +def PRF2(seed, msg): + assert len(seed) == 32 + h = SHAKE256.new() + h.update(seed + msg) + return h.read(32) + + +def G(seed): + h = hashlib.sha3_512(seed).digest() + return h[:32], h[32:] + + +def H(msg): + return hashlib.sha3_256(msg).digest() + + +class Vec: + def __init__(self, ps): + self.ps = tuple(ps) + + def NTT(self): + return Vec(p.NTT() for p in self.ps) + + def InvNTT(self): + return Vec(p.InvNTT() for p in self.ps) + + def DotNTT(self, other): + """Computes the dot product in NTT domain.""" + return sum((a.MulNTT(b) for a, b in zip(self.ps, other.ps)), Poly()) + + def __add__(self, other): + return Vec(a + b for a, b in zip(self.ps, other.ps)) + + def Compress(self, d): + return Vec(p.Compress(d) for p in self.ps) + + def Decompress(self, d): + return Vec(p.Decompress(d) for p in self.ps) + + def Encode(self, d): + return Encode(sum((p.cs for p in self.ps), ()), d) + + def __eq__(self, other): + return self.ps == other.ps + + +def EncodeVec(vec, w): + return Encode(sum([p.cs for p in vec.ps], ()), w) + + +def DecodeVec(bs, k, w): + cs = Decode(bs, w) + return Vec(Poly(cs[n * i : n * (i + 1)]) for i in range(k)) + + +def DecodePoly(bs, w): + return Poly(Decode(bs, w)) + + +class Matrix: + def __init__(self, cs): + """Samples the matrix uniformly from seed rho""" + self.cs = tuple(tuple(row) for row in cs) + + def MulNTT(self, vec): + """Computes matrix multiplication A*vec in the NTT domain.""" + return Vec(Vec(row).DotNTT(vec) for row in self.cs) + + def T(self): + """Returns transpose of matrix""" + k = len(self.cs) + return Matrix((self.cs[j][i] for j in range(k)) for i in range(k)) + + +def sampleMatrix(rho, k): + return Matrix([[sampleUniform(XOF(rho, j, i)) for j in range(k)] for i in range(k)]) + + +def sampleNoise(sigma, eta, offset, k): + return Vec(CBD(PRF1(sigma, i + offset).read(64 * eta), eta) for i in range(k)) + + +def constantTimeSelectOnEquality(a, b, ifEq, ifNeq): + # WARNING! In production code this must be done in a + # data-independent constant-time manner, which this implementation + # is not. In fact, many more lines of code in this + # file are not constant-time. + return ifEq if a == b else ifNeq + + +def InnerKeyGen(seed, params): + assert len(seed) == 32 + rho, sigma = G(seed) + A = sampleMatrix(rho, params.k) + s = sampleNoise(sigma, params.eta1, 0, params.k) + e = sampleNoise(sigma, params.eta1, params.k, params.k) + sHat = s.NTT() + eHat = e.NTT() + tHat = A.MulNTT(sHat) + eHat + pk = EncodeVec(tHat, 12) + rho + sk = EncodeVec(sHat, 12) + return (pk, sk) + + +def InnerEnc(pk, msg, seed, params): + assert len(msg) == 32 + tHat = DecodeVec(pk[:-32], params.k, 12) + rho = pk[-32:] + A = sampleMatrix(rho, params.k) + r = sampleNoise(seed, params.eta1, 0, params.k) + e1 = sampleNoise(seed, eta2, params.k, params.k) + e2 = sampleNoise(seed, eta2, 2 * params.k, 1).ps[0] + rHat = r.NTT() + u = A.T().MulNTT(rHat).InvNTT() + e1 + m = Poly(Decode(msg, 1)).Decompress(1) + v = tHat.DotNTT(rHat).InvNTT() + e2 + m + c1 = u.Compress(params.du).Encode(params.du) + c2 = v.Compress(params.dv).Encode(params.dv) + return c1 + c2 + + +def InnerDec(sk, ct, params): + split = params.du * params.k * n // 8 + c1, c2 = ct[:split], ct[split:] + u = DecodeVec(c1, params.k, params.du).Decompress(params.du) + v = DecodePoly(c2, params.dv).Decompress(params.dv) + sHat = DecodeVec(sk, params.k, 12) + return (v - sHat.DotNTT(u.NTT()).InvNTT()).Compress(1).Encode(1) + + +def KeyGen(seed, params): + assert len(seed) == 64 + z = seed[32:] + pk, sk2 = InnerKeyGen(seed[:32], params) + h = H(pk) + return (pk, sk2 + pk + h + z) + + +def Enc(pk, seed, params): + assert len(seed) == 32 + + m = seed + K, r = G(m + H(pk)) + ct = InnerEnc(pk, m, r, params) + return (ct, K) + + +def Dec(sk, ct, params): + sk2 = sk[: 12 * params.k * n // 8] + pk = sk[12 * params.k * n // 8 : 24 * params.k * n // 8 + 32] + h = sk[24 * params.k * n // 8 + 32 : 24 * params.k * n // 8 + 64] + z = sk[24 * params.k * n // 8 + 64 : 24 * params.k * n // 8 + 96] + m2 = InnerDec(sk, ct, params) + K2, r2 = G(m2 + h) + ct2 = InnerEnc(pk, m2, r2, params) + return constantTimeSelectOnEquality( + ct2, + ct, + K2, # if ct == ct2 + PRF2(z, ct), # if ct != ct2 + ) diff --git a/libcrux-kem/tests/kats/nistkats_1024.json b/libcrux-kem/tests/kats/nistkats_1024.json new file mode 100644 index 000000000..3d5739981 --- /dev/null +++ b/libcrux-kem/tests/kats/nistkats_1024.json @@ -0,0 +1,802 @@ +[ + { + "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "sha3_256_hash_of_public_key": "8a39e87d531f3527c207edcc1db7faddcf9628391879b335c707839a0db051a8", + "sha3_256_hash_of_secret_key": "ed1f6cb687c37931ea2aa80d9c956f277a9df532649661035c6e2f9872132638", + "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", + "sha3_256_hash_of_ciphertext": "5ef5d180bf8d4493ef8e8ddc23c22e428840c362a05a25fd306c6c528bd90f8c", + "shared_secret": "63a1039074f01f2651213ad9350d6561cb03a60400e74118bb4464d87b9db205" + }, + { + "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "sha3_256_hash_of_public_key": "c9ede13be3dbb0edc3ab08226cae11771ff4c0b04a564b64a0d9ff10e373e986", + "sha3_256_hash_of_secret_key": "9b5876610793ae42f683d94f736d8d7e0e033bee588bab07a31c9cdb4ab99a5d", + "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", + "sha3_256_hash_of_ciphertext": "bef440cb5a14bfa652ff69fc431b59980147a2408df8a893f0fafded11d6cfa3", + "shared_secret": "856d56ee09279a13f9abdca14ecbe8ca9968495f09a0758b6d1c8376099365eb" + }, + { + "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "sha3_256_hash_of_public_key": "ff2546623aee72025fb6746fba736bae0e80e257e66edbf09d8d4dc11049cda4", + "sha3_256_hash_of_secret_key": "57155298b53d3af5d6db214dfa91a9e16f8d5de570bbff5dba5f4cd84098f255", + "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", + "sha3_256_hash_of_ciphertext": "28e308a6f91068b01a7065b8579fcb6234ecd9bb8d3172b6dfc5a3a470050ea7", + "shared_secret": "c33a4432cc441b7683605c29afdecc81922cf234e02be8c2fbc4e2a7a3b4b078" + }, + { + "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "sha3_256_hash_of_public_key": "25b786a67de17d61b2fc0e85a13924398aab931896b6174089569f08b7260687", + "sha3_256_hash_of_secret_key": "d188a2637dfe80dbd0fc25165eb4898923888a82c10f6ff0b8ddb5bf251c0650", + "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", + "sha3_256_hash_of_ciphertext": "8427a1684769e63ec43e97ecbe7b7e654b6e63433bccd23340849904e02767dd", + "shared_secret": "7c14fb353ba421705de44f2a12ddc5ad9b11e30e7b0e163cebebe2da79a7293f" + }, + { + "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "sha3_256_hash_of_public_key": "d35e259a200d16048302df38d8e7f9e1c3352502c43f086fe166325048fdce9c", + "sha3_256_hash_of_secret_key": "020ba30e5832867a6db83cdb1e60ddf0b0a88fb33919edb84b246a345d11da6c", + "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", + "sha3_256_hash_of_ciphertext": "b52dc0a41015132b3e7a1ae6f544f12601869bf0673625964e5c4e05cbe656e0", + "shared_secret": "35d2a2ab0e91d365a3e2e99bbe3f5121f2eeb528305cc7730f679e10ec1c9b8a" + }, + { + "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "sha3_256_hash_of_public_key": "5a5db7d619be642bd87294527b3f859372b279a1e6074824d9632b5d7f616e42", + "sha3_256_hash_of_secret_key": "630f093cb1ff96bff76ede70e970a009a9e5d28fed660e68127d31c3b6dbdb2a", + "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", + "sha3_256_hash_of_ciphertext": "4714a5497351399718258f490da0ce28ce8211aad6975546cb4351c8ebe61917", + "shared_secret": "8084cfff3d54b7680e737ed71c37e449f1f9d74bf6735696c46910b13d42d1f1" + }, + { + "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "sha3_256_hash_of_public_key": "f0d1acd4fe1bd3bad938c23ec5a7f320766e01005e32769724abb4ebac578def", + "sha3_256_hash_of_secret_key": "664f3632f56ebc5c509931ff3b7e1845265e42a76e20550b683527d7d24e8df8", + "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", + "sha3_256_hash_of_ciphertext": "4ebd3e44b82b03c01ec2aa9e8805e53b8c8022e987fc9eca59c9a5cfcb1c4a84", + "shared_secret": "3e94b68a80291e957f9dd0a15b112ad75bfa07951ccb36c2de610e6755a4a0d6" + }, + { + "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "sha3_256_hash_of_public_key": "7008db565f7ab9c362dc38dcd3e30e5da873c559e9a9222710e8d2e7f6417ce6", + "sha3_256_hash_of_secret_key": "9e774cb57c18575de3ec6a9677e40626c2026e47c389c7a3dc5422d8a83b747b", + "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", + "sha3_256_hash_of_ciphertext": "1cb3879c49c65c184d605bc6daa22f63affd2a005e145103e6c1ac1ad683d976", + "shared_secret": "900649130f9c28082eab5ce3d128593eeaae89667d7fa4da23fcdfc1573995fa" + }, + { + "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "sha3_256_hash_of_public_key": "143b9c53320cdb1b7e8d71efd1f0a1ad5ad1e1ce84dd9fe7c92f19c926388e3c", + "sha3_256_hash_of_secret_key": "63707e33c30114732374ac21fd5be61e6dfa7dd85a36eef2e2bae6b3d0599a71", + "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", + "sha3_256_hash_of_ciphertext": "780162548f2d85c00f0276f1db2d6566421cf718679147740d279660fb742544", + "shared_secret": "084aafffcc38ac80dfc02548df07f6e7809eb0644385abce0fc569821a907011" + }, + { + "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "sha3_256_hash_of_public_key": "f2d009cde4abd55a2c7417c9341792e60eaa8e26b53a3aae805746401c4c446f", + "sha3_256_hash_of_secret_key": "2a53faa8053fa21b7b07a96ea259c052ef78746c5d53e2857e9f30bd20d3f2b6", + "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", + "sha3_256_hash_of_ciphertext": "9b7ead45e0e00c615fce96105720d82ba431692f92e1a73e14b490219c8dda2b", + "shared_secret": "a7fd777a337219e1d0ad2cdb47fa18f4685ac343bc537dba6c97326340ab3ebb" + }, + { + "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "sha3_256_hash_of_public_key": "1f06190bdfd692cf499be99bacc4beccf048c89926769f1b254cca9a9a44089a", + "sha3_256_hash_of_secret_key": "faa641eaff01077bd2fc261ccb91d5c3b468a940e25e8d5d794d564b663315c3", + "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", + "sha3_256_hash_of_ciphertext": "3a22350624e9ffcfeaf0a68c265dc03036e7d5bdbb102474fd2aed257fce04ed", + "shared_secret": "17672805d3953f1f374dc8671137dabb0136de43700fea82a2ca23292bd0d562" + }, + { + "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "sha3_256_hash_of_public_key": "cc20155074cd7cbd43ec2380dc6a71b3a88c9a4bf168ab2bf426a899706fa597", + "sha3_256_hash_of_secret_key": "6084f1eb2fe4b9055d6004bfccadad7bd64f623595dd0b5e0c0100d647313279", + "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", + "sha3_256_hash_of_ciphertext": "43291afa9c1a8098770d5ed9dd4cd71688c52d616e9e68798f8718e4555e0caa", + "shared_secret": "8813fdb7bcec5369e6238322be653d920ba26e0aa63a3c3b4e4218c48c1d6dfb" + }, + { + "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "sha3_256_hash_of_public_key": "77fbe004761fc37fe7597638e5dae8b44bd44c8d6efa2893a0a84b104ace6ac4", + "sha3_256_hash_of_secret_key": "608099f3fa437094212b3aa2696d592a9ba45f697b9c1020b69ec1d6e178b76c", + "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", + "sha3_256_hash_of_ciphertext": "368fcbdfa009642b3ca8fe0261d10d18db5566bc43938e193d9dae45adf2d41e", + "shared_secret": "b00167b499d5130ef82a91f83d1f1563185de735e74f89afea0b45ae1b90cea8" + }, + { + "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "sha3_256_hash_of_public_key": "49cbe8daa7dac02d7795e907b037e2ae56624fdc8d7c6320f9e1e69dd0f6286f", + "sha3_256_hash_of_secret_key": "de7838a99458b56d0f1de343315d1a7d460269ded85551f70335b1e002742b5f", + "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", + "sha3_256_hash_of_ciphertext": "04c5a66da97cec8a22bca38de71927b176310004175b3496c5a2737e91b18e00", + "shared_secret": "c55179382eb5d4bbd91e45f4b3dcc5d1022110aa209c002600fe0d55a5b3333d" + }, + { + "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "sha3_256_hash_of_public_key": "a333d474be9bacbea4c301148be2ddf13c3c25d7e4f52447a549a27b6d12710d", + "sha3_256_hash_of_secret_key": "731e7c1597fcea477249114301154b9fda1050e71617827da0c9cc149c1cb99b", + "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", + "sha3_256_hash_of_ciphertext": "841415e768ab08549533578cdb506a9f72e8d01b472b64746322328c0c035080", + "shared_secret": "91c0a23c78351e8f8de8e38c5a10e41e5290ef96266f93839169c05842820e41" + }, + { + "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "sha3_256_hash_of_public_key": "35d109f57ea2764642ea3473a4f192cedfbe153a37f131cdf447b60e92310eea", + "sha3_256_hash_of_secret_key": "0420ee0853629da644872d3e2a9b0a89c9dece1a6748247d2f8f39721af21e12", + "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", + "sha3_256_hash_of_ciphertext": "82c120326a2ab109d5c3910a95ec69dc3b1c1c05570728164791870d9c9c1a3f", + "shared_secret": "ffd93f9141d4b2abf600c1c258ee78e0f752513bb002677221060cca3ff1e5a6" + }, + { + "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "sha3_256_hash_of_public_key": "cd65fd07a78e48c1a02e235ec76fdb509cf9903a4f5a850c51d9d3fda383cc67", + "sha3_256_hash_of_secret_key": "951cf21e37dcba710b581e49a6df1c75c65186e9672d647e9cd7239eb4bb975d", + "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", + "sha3_256_hash_of_ciphertext": "0217f113b6d5786c3995b366adff6984d0c8d91a388f798a9556d7d3a8252b9c", + "shared_secret": "550b4e8c00bb5ece74059879fd14f5a0a89073d8a54f8bf1597f1ebf198a61fc" + }, + { + "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "sha3_256_hash_of_public_key": "376f022313718aba325ef4c3b720e2c3ab314ace74e983948ba2e43ee3a6ebde", + "sha3_256_hash_of_secret_key": "e697899409d15ce13113a2ad86448157a248ff0701b40eec11fb4afac7b9f2fe", + "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", + "sha3_256_hash_of_ciphertext": "26c5a91a627899cf23122c5881bd00b0a4f76e0aaf5de60d1d273e8e635b574e", + "shared_secret": "e5b98a3c32a5563c49df725e661a9f44a20390cf83a9779ecf5e7d9f5aff0143" + }, + { + "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "sha3_256_hash_of_public_key": "7944e5d79dabf7b7259df5ced02669c81b7dc4590e0b10764729d812f6bd85d7", + "sha3_256_hash_of_secret_key": "301fb18a9ec0d975414abc4d41ed0c553e2b9aa2b03bf2765476e3288f760ee7", + "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", + "sha3_256_hash_of_ciphertext": "c7474d6b8d9b3677b39b69030f40415e2234e637e200c689f90d6b37da3c4a8d", + "shared_secret": "169929e655f214d7ddca31eae7ecd2e01d9ee0601fd4a2c3a59eb701ed9522ab" + }, + { + "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "sha3_256_hash_of_public_key": "692176b38737a053dce0551b63e3eca81884bbf95e1d8975671a2f7f1dfae251", + "sha3_256_hash_of_secret_key": "1ae55a55d87ea8d58b51f842c7d6990a1ae6932eccf5c39e97f56bb481a16b7d", + "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", + "sha3_256_hash_of_ciphertext": "7509dec8c1dd6f29855e08d61a56ade71c6bd9a47102a12b3d4c9784010bc5d0", + "shared_secret": "be36ca6f5e0d3da0b5c144ebccd725900a06782fae7b2707ce7c5cb6818c8991" + }, + { + "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "sha3_256_hash_of_public_key": "2f54bedb19919171eca777186dd743b11ec9489aea09534c157faa75adf1c77c", + "sha3_256_hash_of_secret_key": "4bea180ffc80875ac731f18365224bd3eefc8d11fad63c7376adc1a37adc67bc", + "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", + "sha3_256_hash_of_ciphertext": "def0451ac37ac39a0ef5b94406de4e313b3d12d899d6a4e92f3ee37c84869efe", + "shared_secret": "9769b7f3571089f1a086606f3545dcd094097befd492e3c9889f9a97c7b181a4" + }, + { + "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "sha3_256_hash_of_public_key": "7a9232085a0222b9c863931ec3bdbdd51be3f16d6cab3009c138e0c8cb692563", + "sha3_256_hash_of_secret_key": "a01d03ab913ef4672c49664d2c95fecdd98fcfc19e8d8b839e79a8f6fb9bdf42", + "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", + "sha3_256_hash_of_ciphertext": "45c35e22eaa9d63a6b57f60ad2e6a35290b290c01761030dea1c9aa7947c965f", + "shared_secret": "7a190640b245b6b4de7ac38fa6d4c50e935c0062c2089c926e4e8c31f233fbba" + }, + { + "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "sha3_256_hash_of_public_key": "1642d52117145ea2956bd5e446b895609be84a9344ff0f5cd1ec62af9ea9e3c0", + "sha3_256_hash_of_secret_key": "e2d190c6c423252af301186a3e49892da8c22e4c0fb61586d119119fb7b07447", + "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", + "sha3_256_hash_of_ciphertext": "0e67bf478bf93c925eee2cdfc285161c1b6dd2ba3a479dfb5fd9203ffdcd3c85", + "shared_secret": "5de71ca6710d2d588f53059a15e3a266eab4ed2230502b597f088014fbe9b659" + }, + { + "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "sha3_256_hash_of_public_key": "0163017a26dba83777c4c0f46f31375ba02680ffaba588a9fe91f97ccb99c445", + "sha3_256_hash_of_secret_key": "5d101bd4f51fad047a1161e7a95197f6307e7cb88e57fcf9fb28a2be43e9f4a0", + "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", + "sha3_256_hash_of_ciphertext": "7e38f78738ad21d1015a2e79860e8108e807a3e7070515185ae581345e08f6e4", + "shared_secret": "42ffbb3ae86b744b00f36a01f9cb34e8a08916f455c9ea0e5e6ce81bb5042cae" + }, + { + "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "sha3_256_hash_of_public_key": "fb21cf5cc9a8a47a07cb2a154f73676d39a98a7d12a4abbd37378595c6332f46", + "sha3_256_hash_of_secret_key": "3c5041ff25ab5e854e792eccf12721be4f820020ed7895d5ccb7b1ba4bb7b193", + "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", + "sha3_256_hash_of_ciphertext": "e2b8a6842755e5a408a47a32c2093dcf3aa0d32448ddb1f1a154315634f1b701", + "shared_secret": "90ca5a797490eb35c3cc24af19fca6dc71d41aa58d68e0061c1bdb8481e691d7" + }, + { + "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "sha3_256_hash_of_public_key": "591aa9c81277503a34441fbd6cb59c6d1ecd5e00298fa56be9df562576250c52", + "sha3_256_hash_of_secret_key": "2e9c26235e0db1383671ad4ef147c1cbe3724bf800be90e356a5a381e3d9aa12", + "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", + "sha3_256_hash_of_ciphertext": "02f85b52a3684cab8bc416b74de36ac686cf3a3a495440cd444c1fe7d84b2e07", + "shared_secret": "bd58345e9e19483cde256be650975b954e167bd8b0a9036a95c98ebf037e87ec" + }, + { + "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "sha3_256_hash_of_public_key": "1c6c4009e28f6a20aad0c0b14b7cc0a01aeca507c366913ba5cadefe6656881b", + "sha3_256_hash_of_secret_key": "a9d3487d20af12309fb8d12b71a3fc3ad9109a9cc2720a0fa409ec5a491943b4", + "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", + "sha3_256_hash_of_ciphertext": "7a5d4cb38e9fb2beefd925d54155ae91d60bd95696db2de45e2307658341f2e7", + "shared_secret": "53d22dbfb623f5282ac68ff607b69b9ce559ec3b70aae668c684d90dcbbca13d" + }, + { + "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "sha3_256_hash_of_public_key": "4576536d1bace29aa7c31f7681222ddd15a3cf6ea6bbd3528d2ec8610d68d134", + "sha3_256_hash_of_secret_key": "0f1d74d5cd2fd6a9aa7022a0f06bdb6272a0bc23f115796d6e04692aa44de4ab", + "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", + "sha3_256_hash_of_ciphertext": "8448f623dc438ea4a849544c4fbcf3dc493b18dbacb911b83ed651155a145c53", + "shared_secret": "cdca5387453ba0f0fe9f126702ada05c3612388b70185b6c2e69dbf98c2803ec" + }, + { + "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "sha3_256_hash_of_public_key": "eea5db7a82254d19c0a0c552ccc92db9c3eef74cd73a9937b7b7298171313f12", + "sha3_256_hash_of_secret_key": "d4d3196a516686b8da051e915241f141b04af55e83effb968c52f23a19ccf79d", + "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", + "sha3_256_hash_of_ciphertext": "84e87b27235041a1815c98ca4cf9ce031d7700a48f602bc9dcc98f876ae50c62", + "shared_secret": "b15db77dc79f2d64e13445c4dfa997afb191e0bb2bbf6a210a5d64263b2408f5" + }, + { + "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "sha3_256_hash_of_public_key": "72998cc3abc79487ca0a4db5b17514e9961916d30ab9b500430ba748c5c79226", + "sha3_256_hash_of_secret_key": "362b40ba4e015b703f639f4c784fa9f114f2cf65de5f6645e8f9d37fb33fd044", + "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", + "sha3_256_hash_of_ciphertext": "44b60f83deff617231e92c5ece08a24243841d3df34de2517c29bdc89ff51400", + "shared_secret": "8ca9424860c35214636855849bb039cdcb4c722c5b81ce18ac1a1090034dafc1" + }, + { + "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "sha3_256_hash_of_public_key": "e9631b6d4237dd6884ae3647dd8622fc13d1cc689f3c8ed94ec6bcd4bbdb6980", + "sha3_256_hash_of_secret_key": "96736bf10a73d079e56f5812f65e3465957b8228423fdae4059feaf918fba361", + "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", + "sha3_256_hash_of_ciphertext": "eda93794649d2ba24fb277e8cb0e5788102a4796cb21388caa25eb10bafefc5f", + "shared_secret": "b056e2904d66c51dc817acf961f141c2de7d201ca8e52d19564d0fb4e1310aa9" + }, + { + "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "sha3_256_hash_of_public_key": "847db13de94d97a88d5a3deae31c246f5f04d0c7d7f337859e024764337a08f2", + "sha3_256_hash_of_secret_key": "7fc950abb115ea2236036c300c95c76015606539ddd2409ff1b39a99b86a179f", + "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", + "sha3_256_hash_of_ciphertext": "af6d97857d131ebccf9d356e78a4fbbb66c7d5ad68fd42d356c3ef14aa756d47", + "shared_secret": "663bcd21601942f0ce47640325c9efcfc3eb3b022f0cfaed168893b1b6e5dcfc" + }, + { + "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "sha3_256_hash_of_public_key": "f122b76b83c343de27054985634387fb7138f6f6f105cd4cd3f5b02698a964b0", + "sha3_256_hash_of_secret_key": "620b4d0dc53a26e175c69ae7a8f2d749d4adf1d0429852b84839d334e024ab06", + "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", + "sha3_256_hash_of_ciphertext": "51f8a50f2dbcb1255619a7a9868eece507b55d2138707a0550a4113a7e162d5c", + "shared_secret": "cad5816f1b2057a410cf917f52040aad9cdef2122ce59211ccef77c4a7c23a6b" + }, + { + "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "sha3_256_hash_of_public_key": "4c3182ca7a48afe60eb85790dcb50b8005b568921dbc724130b0ce83f1278454", + "sha3_256_hash_of_secret_key": "44b1c2b3487cdda8a8e9205d95dca710093e981e7bf2ea30d1d2502b164375fd", + "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", + "sha3_256_hash_of_ciphertext": "f231d9b8e3cb86e9daddae8d4555779a9125a16a6d2984ef55914a27d7912fbb", + "shared_secret": "e8f4dd3d2bb2c2f110bd410b2c37beee6d3bc7c7c4dc477c358234c54bbbd4ca" + }, + { + "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "sha3_256_hash_of_public_key": "4359601c371b50b50b5306de33cfd476d3b5f811700dc4918beb345840244e3a", + "sha3_256_hash_of_secret_key": "6f2d2c913b4a19bb07b531d74edb549659a35d1330b1ddd62c74dac4bc5f061c", + "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", + "sha3_256_hash_of_ciphertext": "a6130d387a04846c8b920f94f59d6c65b4954b6ced0f0d6a8566a0110c198a08", + "shared_secret": "249855eb724db68f7367385c45a3206fa19c521644f8841b7a73f536ca47c26c" + }, + { + "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "sha3_256_hash_of_public_key": "e1f6c5a99a49d6b1b4aa18089439bb4c56ca465785bb36594ef2ebd3af20d564", + "sha3_256_hash_of_secret_key": "fcc14cdacdcebc6d1933f1ec9d430c643ff5fdbd78d2fe053a8880e6ee8ef129", + "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", + "sha3_256_hash_of_ciphertext": "73a09eadd34a8be74772db44187ab49a2bc086b91848c6ff09f1306c264f6fe4", + "shared_secret": "f1be516b31ed89cb70bcf428a2ba2c22b3919f8a9824a59b875ff1e697095ae2" + }, + { + "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "sha3_256_hash_of_public_key": "b8aa8568431ffc4681caacecd4475c838cf7348402a06413e7a9590ba405ea5e", + "sha3_256_hash_of_secret_key": "f1e4bb0178d949637c06e252493235480d3ed16687e9a1c36df0721b29a7573c", + "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", + "sha3_256_hash_of_ciphertext": "24392701d3f5204f5cad5662bd6526a178567186cc070d951e03593e5722eb46", + "shared_secret": "6ec4f71386c0f0c16294e4d76966c69c512d4e5e00a6e05c5aa544e542454225" + }, + { + "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "sha3_256_hash_of_public_key": "984f4c4ef2371654067ce0f22bbe4648dc9d87eee23842f31affcdc36328e8db", + "sha3_256_hash_of_secret_key": "240fe3ab98047b1985b22240622da9669f7ecec81801861ea0859704f3263f6c", + "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", + "sha3_256_hash_of_ciphertext": "f190fb70fe762db7125e3ba3b459e32bf99775c3c1efb84ae1776b50206db7df", + "shared_secret": "464274dd39f2862a97833631ac446642b3c3dd6467c7d2404aaa46a8f5f65b3f" + }, + { + "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "sha3_256_hash_of_public_key": "74841a59db1202eb2e3744bb36b9c5a229a33cf9eeafca4b3d02d155d870b6bf", + "sha3_256_hash_of_secret_key": "e808e7b999c5bedc14a1763428a3f2b3eb9c3f90743f8a1922c87b5874acd79a", + "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", + "sha3_256_hash_of_ciphertext": "675ff34f87383d52203c979d1502e2fd35d9da09cc095b44caa073cf58562ba1", + "shared_secret": "99dd968e1f5c94c6c4d92e7eee393c802d8ea4a34d39de2048eebfb21a0a4b9c" + }, + { + "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "sha3_256_hash_of_public_key": "f7243d71bcbb46b9a423431b3b30947eda5fd81b526cce79a36730d8ee1be42c", + "sha3_256_hash_of_secret_key": "b1e6993caef04e00ffcf42c81ae97c6d89c5c19bc3b3e1235c48829151f8b4cd", + "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", + "sha3_256_hash_of_ciphertext": "319744b03f01b7676b3975b70d20698972d5492a2b0c8e0833837de36945c699", + "shared_secret": "0642533fe87a2913a37847843f7336a0e4c47f778afe5cc95433948a76ee7ecb" + }, + { + "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "sha3_256_hash_of_public_key": "4092d5afa2f038f879184f7344800ea49a63543be9600bdc2b18420744588290", + "sha3_256_hash_of_secret_key": "18b8bfec268d6e1d6edd376689f2bc5ffbcdc859cee0a26ccf550fb42863d57d", + "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", + "sha3_256_hash_of_ciphertext": "4fb1c5f9a918a9077f822c79ec0697dd6dd7b23ff3cfffafaa272dfb1233bf8a", + "shared_secret": "a226b83601ae0e6f76f9f08b0a2f6eb30a3afaa39ecf5c5671e988a354fde9a7" + }, + { + "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "sha3_256_hash_of_public_key": "ad7166f31b2650d125c8ef23b5825fe11afe25d0cda306fa6c7a824b4c2d31d4", + "sha3_256_hash_of_secret_key": "0124d8202fcb0c40d7a6cbc1570df65602f376854abd55ea664f66e3923b3d56", + "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", + "sha3_256_hash_of_ciphertext": "74501710705cbe8837e88dc8986d78310ea57196185e3ee3ecc8d17d8cafa7ac", + "shared_secret": "3040e7e4eeb844c1385a78dc3c8a6375880ce8fab92827460de1825a4915c3b6" + }, + { + "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "sha3_256_hash_of_public_key": "37933cfd8c0e61085f2ae264d85c4ae05f8bd40bf29976c6d52e4f1c7ff709cc", + "sha3_256_hash_of_secret_key": "e9a6c0af326ca00c7f8ee0b6ef5661be3a84c39165ff60fea5510cb219b8f788", + "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", + "sha3_256_hash_of_ciphertext": "3fc676cfc433cccd2d248824c4f51406491cfd99bd05f863cb4200155ac471c0", + "shared_secret": "d990008c5eceab7097524d6755c663ba04599eda80560d59088b21cd73243462" + }, + { + "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "sha3_256_hash_of_public_key": "ae96ec4edc7ee08108fe6c0411a96f48731066ae4be12edeb7fc667039c9c1de", + "sha3_256_hash_of_secret_key": "7110c8c6d14a3cf5dba3e5f2ecda1ed1490e62b032f798139b779054da20985b", + "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", + "sha3_256_hash_of_ciphertext": "9b33f0f26252a0e1b92f55f4c0f979efd5ef68ef1ed6f23bf23e5eab1c732ba2", + "shared_secret": "bd50423b4ef27559d67532abbfad2a3a388e3dbf4d7b6488c2b48f19cee07ad4" + }, + { + "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "sha3_256_hash_of_public_key": "4e23909b028699d6677eabe6bac4bc4e8437acbc52b0b17f1df5760c0455c2b5", + "sha3_256_hash_of_secret_key": "63ace19297953d106cbc1df1a25143a15772197c05aefb070825ef568eafcf23", + "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", + "sha3_256_hash_of_ciphertext": "7747110bc34f1a35fea13d10fffb950a85bd6d9247c89b2071afce7544b312bf", + "shared_secret": "38e3d97b0547e648b2b722c4844f59ed43dcc4b40fa7dcfe6184c2fe62ab3530" + }, + { + "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "sha3_256_hash_of_public_key": "513906f5bef81445bd210d63fc4c9b9ef0b61c17b0cd5b229a45908fcbaddcec", + "sha3_256_hash_of_secret_key": "11added546dd697edc51e8ed16ca3ccc9da9629c4ce0c8404d04de1aa8b8114c", + "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", + "sha3_256_hash_of_ciphertext": "569f8e9da2051bde67bd3ff8e81e3b4e749b198586e2ec8d0544e6a8793aa782", + "shared_secret": "cca4f1d172212f8c23eb5da77144640d821d2671f66f0b3015d0b46e274e193c" + }, + { + "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "sha3_256_hash_of_public_key": "4f8b3e9ae47d3b5b95c080d4f18440c24b0691c19f06f5547554697bdfe97b01", + "sha3_256_hash_of_secret_key": "cf4be19205cf0c2bd0eb0c1e7aabd40e265792bfc302bb0f28716c406585ca37", + "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", + "sha3_256_hash_of_ciphertext": "ce6e0b8523fc48a54f1b10be23b1e990a390e4e823d4483681ffbd2ad09f4977", + "shared_secret": "dd7816a8a015b2001258e665dc0e576ae19b10dba9704be9c484e4c8ba645522" + }, + { + "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "sha3_256_hash_of_public_key": "c1b4fdc4929c2c7e4501ba7a9feb0be571e27c43fa96f9a7f934636ed9a86110", + "sha3_256_hash_of_secret_key": "5b475ff0aeb273c017d1e7d7cd380e41d50e634840e443a762608c09282f3007", + "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", + "sha3_256_hash_of_ciphertext": "556aebca384b3876ec2c00d446239855602625800bd1ecf1b7eb3411d101d442", + "shared_secret": "e911f73a4c23637a2708739bd5ef842ccc57d32993f30d6ee1f88acf5093ebcc" + }, + { + "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "sha3_256_hash_of_public_key": "df4f164c11041dbe981d8ff2008757b7e694f564a298b92cd182129ade5e72bc", + "sha3_256_hash_of_secret_key": "1f836ed803ea8abe63224c016dc15468719599e06564c11e9f641eeb3634350c", + "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", + "sha3_256_hash_of_ciphertext": "5dec68120c8c2182ac2b2995eac56b91df2ee9c9bce8e801853e2cee14c0d8a2", + "shared_secret": "572994fb967815fe8bf36cf41560dc69aeba8e32b13e1d25128585dbb0e71068" + }, + { + "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "sha3_256_hash_of_public_key": "ed722667caf175df48a3a346ec7cb1bcc37d67d3137ff7b7c70a07f202893a33", + "sha3_256_hash_of_secret_key": "272df80631771996565e673a4dd92318e87e625097f74fae14c688a24b558216", + "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", + "sha3_256_hash_of_ciphertext": "4214ca50c6c732d34dab0b460d7cd9e0ae97346fa50a67386fc35ca0ac8223fe", + "shared_secret": "92c63dee4666bfb34fe3095f65cd458654df578f6eac0ec75f5235e5da6a926a" + }, + { + "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "sha3_256_hash_of_public_key": "0c4dc82d723965476a518ea0915c1554bcc61c814c80ff120c37e7e8ed6d5c40", + "sha3_256_hash_of_secret_key": "d9e7fabffb14d620ccf618a1e25375d4cf58875c38ecc73587cd09b17621ade4", + "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", + "sha3_256_hash_of_ciphertext": "651834fb53362a4c4af0b141885056f9db913c4be968c1aed3d7d3f5bd1048ec", + "shared_secret": "0e2179fc3d310aca496244699b05da9b7bbb7891ed41b675e5dd48355a586360" + }, + { + "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "sha3_256_hash_of_public_key": "c934c11e2eaa7c3c4e764863e436ff12fc9f517c79df6344ab98611f57fe7296", + "sha3_256_hash_of_secret_key": "4f502a9abdfece85347362ac4c7e2beedb137e29a4b638c9bfd710de432b5e5a", + "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", + "sha3_256_hash_of_ciphertext": "06786544f2ea24bcbb677092f4602d59f9cc9d2d8211614dbb5b87edc6edc46f", + "shared_secret": "573a8fd5e5935badcf974c50cc36e191f0ae2c1458fb00d4117e675424d4e37d" + }, + { + "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "sha3_256_hash_of_public_key": "5b07c8359e6ec4989c34b31293f4df965b5d95802afa5836beabb001d5cd4dae", + "sha3_256_hash_of_secret_key": "73973aaa43538874f8b16d44faefbd26dee5389a05fad2d4f966662ea9eb1df3", + "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", + "sha3_256_hash_of_ciphertext": "2d6085e31726d74e2ce2a28088ef3247b68b39d0d51c225df2521ba327bb3154", + "shared_secret": "c8d5e0dd64b4f3c6450fd24ed2918887d3ea2806479d3fcd5a19894f4fe401ea" + }, + { + "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "sha3_256_hash_of_public_key": "37f1d7e636b4ab366dd5725957b9e5d2498e4ee1929f2213f9d05c882d96a106", + "sha3_256_hash_of_secret_key": "1b150644ef3edff5c406fc9a85e16fbc87cfcf8a6ac726284483947cc2fffd63", + "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", + "sha3_256_hash_of_ciphertext": "37d80e33f5bde211a9a3f634f8505a816e46195616c34a51d62b031822201337", + "shared_secret": "f0691ad2fe875e3f0993f25452c70f0c40891b998deb6a7f7aa3c0bacc59bfce" + }, + { + "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "sha3_256_hash_of_public_key": "a5383897314d60ae0ab1a8b50d6f5de454a2eb8b0502d57001e6e19223a82ef2", + "sha3_256_hash_of_secret_key": "38e8404120bbd346e0483ff7eeb758bd655ed94f6c02e427468f0c5fdbd957f5", + "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", + "sha3_256_hash_of_ciphertext": "3e819dc1fbc939e49bf5935fc8ac8c36d8c16da057091442df74a76fc3125fa0", + "shared_secret": "bec215c6bb33e83574319c839db1ca6793931d35a7239bf4ad3c4a493fe5c5ea" + }, + { + "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "sha3_256_hash_of_public_key": "500dd7b94b28b5b650d90962962bb9a3ae96e70d35723217f3f178cbe5659051", + "sha3_256_hash_of_secret_key": "5930b10cb88d66ad1ec117d2b134f921fe4ec980ed9c351951d47d33510585bf", + "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", + "sha3_256_hash_of_ciphertext": "cb20903e6ba3a41f594cd09056c0a7af4dea86039677761e88dd6818db0d0e88", + "shared_secret": "18a505a0543800a93ab6e2fc1d866e22337fc8387d32541008ff82a73ce7dd31" + }, + { + "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "sha3_256_hash_of_public_key": "3c4467b507971523509bf97d2bdd733ad9eb94f312e4226d036e8fe827a20533", + "sha3_256_hash_of_secret_key": "76e696d5d7ebb4e2035507601f66f38d74db35d3c76b3622678a2c65ec7b0f69", + "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", + "sha3_256_hash_of_ciphertext": "df6a835ca5253cb64d669990a60fe03b44a4a2229beade86a2f3f2381d33f09b", + "shared_secret": "f155d993eadba79e6c2376daeb7f935d39286b10615ab42c5803d43f15960a66" + }, + { + "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "sha3_256_hash_of_public_key": "69ffbf2275f12c29cbb69f90a8c881721ce39b49dbba550ab93a2c4c94bfc669", + "sha3_256_hash_of_secret_key": "76d6db646c55687ff9eeb3f359093a7105a7ef711bd60a4ef7f1a1bbd70ea24a", + "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", + "sha3_256_hash_of_ciphertext": "677fe79386a26743faa6fa1c79576e3f898da432af70e1f45a73b582b4c976b9", + "shared_secret": "4cc8728603d51b14fca46ebaf01e6b6347ee9c71d192591ee857c206d131886d" + }, + { + "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "sha3_256_hash_of_public_key": "41bbd3f5c241a6d65b510dee6662e2a8f35757b0403dcd375e7a15991a7873c2", + "sha3_256_hash_of_secret_key": "256673d5b2a0225515bee64da0105c167d031405098819b6992d01c3cc711bdd", + "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", + "sha3_256_hash_of_ciphertext": "9306db283ad2a844ad6d266ff6c7bd8e9b4ffddef78d656c9bd06d52cdc52c74", + "shared_secret": "fe5dab115160a7200005216d7e6e7dd8527f9c2eec34f60c6710ee21f7f91730" + }, + { + "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "sha3_256_hash_of_public_key": "290261ff6a1d2fabc75feab002d16cdc44bdbdd0967c728ebef0e9814c60b5e5", + "sha3_256_hash_of_secret_key": "beb5d2dc34b1dba8c87e4ca2659ed8ebec2d93be0e2d78285efeb9fd998f5805", + "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", + "sha3_256_hash_of_ciphertext": "7f94b2d97c0821593745e9b5301a66a81b75e71b15c8c21558c8b8b077d7af5b", + "shared_secret": "ba33ea19873105ed9690d40426b2cd24073c822eb86120a4fe8617b5201f9494" + }, + { + "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "sha3_256_hash_of_public_key": "7ffefda144195d79e581c91cdf0247f4346e811f890f54f25226b4ab835871a4", + "sha3_256_hash_of_secret_key": "7b85555898660cb43a060e367d9a97112b48e3b8f99d437161cf6ba44b5c6922", + "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", + "sha3_256_hash_of_ciphertext": "310c7f22a80995c6e375122f1395604faf5f72fb9fd6819597aba8f370327647", + "shared_secret": "2baf80269b225c66a8c35c6f835f15bd6949ae2814cd8c405a0aed313a637701" + }, + { + "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "sha3_256_hash_of_public_key": "13dd780ec5347c512cfabf4c2e6a44cb2b17993c7c746f93c1400a5db9f12511", + "sha3_256_hash_of_secret_key": "7732b2a074d1c0aa93106ca84711edcb7b8a369f3873cf89fbcebf0d32176f1c", + "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", + "sha3_256_hash_of_ciphertext": "b0003e684b9ce6f284d9a746cb806442e5443430bed95f2e8ad7ee824fb3db2e", + "shared_secret": "07318e8edf0ca8f30f49fa906ec814e40ec52922f2c0ace243386ef2bf650000" + }, + { + "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "sha3_256_hash_of_public_key": "d5acaf411ccb64500879102d9cdf6d9fcad673d874a4153383806fe174b2fc1e", + "sha3_256_hash_of_secret_key": "e5c3fdb9d8e92c42ad48684f0fe13aece244d116f8a6d09a764aaa090b3375f2", + "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", + "sha3_256_hash_of_ciphertext": "9ada65c57d8292e9a999ac102ef855d5da932a54f80f3d976fe1ca834eee5964", + "shared_secret": "38b5d71f3a64feb2cd41d6b7a4ac5440707770dc4c472c3ed141165fb7e8818f" + }, + { + "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "sha3_256_hash_of_public_key": "152641a683dd690d4ac3edf0261200cd9244ae7dab962eca2f3d22a554d0802e", + "sha3_256_hash_of_secret_key": "7afdb84b3806783db52ef1f5f0ff89ccdb051704cfd19eec3e2f0830c3b27550", + "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", + "sha3_256_hash_of_ciphertext": "499ffb9a28fcc692e7d61df4696b538f1bbb205ff82d604512220a9e19d87254", + "shared_secret": "368a5e417f4fc728f5080e8fe206ca7558909f6537f1012a58b2d9d45b7c6a8e" + }, + { + "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "sha3_256_hash_of_public_key": "9cc95efe512c84010ccd7118a92522cead44cff28d6e223f76702a47694c8f05", + "sha3_256_hash_of_secret_key": "d9a18ebc4b027c9590d0e4eeed88705aaf5d166cc016cf6e0baa07f678f1f0d1", + "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", + "sha3_256_hash_of_ciphertext": "d202a577a7acba1801e03c446279da6dce6f262a6b1bf06d3c15283bf69fca47", + "shared_secret": "7d36e561b501a687939aa880285d32cd6d8b66e2e65b2a076d5aa516cb5b2e6c" + }, + { + "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "sha3_256_hash_of_public_key": "8b12f00bf09aec2b492cf53686beb31c558d0493cc7b2b9a9dc7265fa9edb685", + "sha3_256_hash_of_secret_key": "9979de3ecfacdc04e1229773f36d7b4bdfd731ea0f1fc2f9d56ee1d07e9bb075", + "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", + "sha3_256_hash_of_ciphertext": "53f97fd2a138ceae2b327344c4947cbee6d6563a48d9bc5d8373c4bac5233a5c", + "shared_secret": "6be99cc08c8bf10372f7d5c27bc3ecd17ade8afb967aad41a1b33c0ff848a1be" + }, + { + "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "sha3_256_hash_of_public_key": "3c98fa4af17fd014a60d11ca5e929e4fa2524f7db289ce0947ad90657990c153", + "sha3_256_hash_of_secret_key": "2c370afe3301b0481b50ae72e21cbb1be37d2877cd802a1d40e05d9b4e6be502", + "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", + "sha3_256_hash_of_ciphertext": "c134910358575ee3e211603b58b3d6085cebcb91f32a355ff437fe87ee812e3e", + "shared_secret": "f6fec6f62257d9a7041f119fff60f734c928e945fe131bf70338f273c0614ae9" + }, + { + "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "sha3_256_hash_of_public_key": "091210fb4f6fac00a24167d9bd2761e601db0a3734e3c835d1e9c5865b1e379c", + "sha3_256_hash_of_secret_key": "fb4bf08e0cd8d2f31969f75b420578f8d6dcd845824e427a6261931f1e1b820f", + "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", + "sha3_256_hash_of_ciphertext": "6076283588ebdb4630d85b2dc6dce53492e11dc8c9445597ec57042bf1e59634", + "shared_secret": "9c56f6d91af6741ac13f241f8c960433c0ed4adcc86130877ecc1dbc10573bc5" + }, + { + "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "sha3_256_hash_of_public_key": "6c206507b89f46c6e9cd5e78b6cc78fb3677ee609cc090cf3782c876fd5f941b", + "sha3_256_hash_of_secret_key": "c9123a2bac61c5fc4304da90862d8cb544a31da2cc8b8126ca16a71278f461e7", + "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", + "sha3_256_hash_of_ciphertext": "e57f70dde96de9e66ce28b7d1a3014cb095a8ad00d80ae7735fd499d57e2e6f8", + "shared_secret": "021b7e80dfd1258695b61aac785b0134ed6e9864d3cdf5ebd4b3ffdd9a5bbf06" + }, + { + "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "sha3_256_hash_of_public_key": "0560200b8d070d1db2cbeedf3cb322ebbab3edb80cf474b4178633c210b2fc74", + "sha3_256_hash_of_secret_key": "a2424d9992c7e999a5b18e638a22d65e1e5d5029e5fac62a5091095897b3543c", + "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", + "sha3_256_hash_of_ciphertext": "b5928a28fea0e5b0321439f9df86c6f10fa6203bcdac0cc94da7f7d6764d543d", + "shared_secret": "2c876ef4c2bd6464c5e4274d5360e210ff389325c1da4bda5495294d7cd126be" + }, + { + "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "sha3_256_hash_of_public_key": "3a2484828bce833f9262405b562bcade9ff04877838558409d2b60f1b689d137", + "sha3_256_hash_of_secret_key": "610db3251ec079ce8003a49d64ec03dd49d89e82ae9f12d26d50938f4a3992d9", + "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", + "sha3_256_hash_of_ciphertext": "723bebfc2e4e934fc9e35383c7f150d31d832e1516c66f8bb2effb449fefda23", + "shared_secret": "909b047e7f0fac27df2787ae406fdd66893a98d98e38a9f5b67bb5c8431a77c4" + }, + { + "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "sha3_256_hash_of_public_key": "bb8615509158b63be5f5e51a0e690f2ad6fd0c56fa886bd85902abd52598bc81", + "sha3_256_hash_of_secret_key": "3a4a1360d366376a56362fee0aa22756122e3c40226c770797c0baa82192bfa5", + "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", + "sha3_256_hash_of_ciphertext": "47cead6dc9f155f4e61afb233c6a8519f016c6f2bf7b1668ed9333daac257507", + "shared_secret": "dff8310ce364ba5686b9d42a17922b8d5e9259a176e38d39687a5269455939f7" + }, + { + "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "sha3_256_hash_of_public_key": "5cf14252096e4988d8ecc4ac6d29ff09c55d666865863d03a68db523728910a8", + "sha3_256_hash_of_secret_key": "404e6febba9802464a188007c2137fc25a4c437611babc8fa8248a0e42e45357", + "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", + "sha3_256_hash_of_ciphertext": "84765944d4602d3fca6333b699d98e4c8c9b3bc1570d428398a29cc5a7fb96c7", + "shared_secret": "faa9833781a7a41691f236feefa0c743bc141f458ecbba98eac4a51ee1ca001c" + }, + { + "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "sha3_256_hash_of_public_key": "345118a7b9bcc773f0ec10c3e353eb4365d2bbff3b812df4635d5c8265b5d8c5", + "sha3_256_hash_of_secret_key": "2eff0ff04aa2f95d9d2a877d2c3b4a09255fed2413da76e63506d0def33f42ff", + "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", + "sha3_256_hash_of_ciphertext": "602b3893213ac6168e24c7c20d22a9c9126a9f70b918df134860f394795836a6", + "shared_secret": "0f47139a8b007c4ba77c91ee885435dfcd38d38c0aa4f57fc147f08b4751aa44" + }, + { + "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "sha3_256_hash_of_public_key": "772f50f7047714627bf76bc098e0b919145fcd8df6922ebac383e5c556738390", + "sha3_256_hash_of_secret_key": "c48cd8eced0093133d3d083baae0f69ebc3e239c373a41db9557c1a46a40d480", + "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", + "sha3_256_hash_of_ciphertext": "84f212f6cac0f0e7a6a27630c0c33f98063bd57243b26fa086d6a37161d75f81", + "shared_secret": "182d34d0e83216d26a9d13301fe75a3aeb15ab145433965996255120cc9a5f86" + }, + { + "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "sha3_256_hash_of_public_key": "a9f015f625356a6bacbb5e565c70184940891589309a571b7166c2ee713b8fbb", + "sha3_256_hash_of_secret_key": "924859759e33e4100a02afca0ad0f0e631eeef3b4a70444267e921b0b6eb334d", + "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", + "sha3_256_hash_of_ciphertext": "935ed1ee90431bb81d67fa4c620c973f7354aa5dab63b51686501882e65a3961", + "shared_secret": "62a14f68d726235fc16e0ac57ad4ae0eb3fc029abb18567a4ee574b44924693b" + }, + { + "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "sha3_256_hash_of_public_key": "655d6f749b0a013bec99e017f5e13bff76680a2f9386f2ac6938d7950d5fa1f9", + "sha3_256_hash_of_secret_key": "0511490e76eaba3b276ebadd300c394490589dec54468855977e96a33025e06f", + "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", + "sha3_256_hash_of_ciphertext": "c28eea97d0767b408e58bbadfdff091ba468c26b585f22bde6f3eeb1fc7bb631", + "shared_secret": "4ceda11055991ce1e5d910a240981e39a6a903b20ea6ae6a21d9d56d0935efa8" + }, + { + "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "sha3_256_hash_of_public_key": "1c3c2aed0ff6944819c93f9a9fe77d14a16a385f644de118099fd4f7f57db9a0", + "sha3_256_hash_of_secret_key": "0fb711641d1830a3eb4ae1a4bc2fc610ea9a811fdc5274488dd31f9cf52ec04e", + "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", + "sha3_256_hash_of_ciphertext": "9fae0ef351454fb5c87cff7ed880d32dcc2f0654ab8c5a5b66b1e85d8e6feb06", + "shared_secret": "8d8257f05a4e76ad11783f7f6850c4f1c34017bf5ab47f89eae202132ada42ff" + }, + { + "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "sha3_256_hash_of_public_key": "357d61586f671648188f070899d2eb3408158adf5e8056ef37ab6d8817cd8275", + "sha3_256_hash_of_secret_key": "b22e39d960d7079015d70fba54ae860285f3c182bd5fc8d84c255f5e0f86f800", + "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", + "sha3_256_hash_of_ciphertext": "388d730604d16fff83eaa4e21a540b2ed8b3138f81b4c1c4cd7bb863325344eb", + "shared_secret": "08a60196adf66426b4e7b90be90160e196944d012cc34a524e1e73ca125ba407" + }, + { + "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "sha3_256_hash_of_public_key": "ef07b1f4886b895a3246241ddc084379eeb0f0ed84bdcd318fe72c9b546413be", + "sha3_256_hash_of_secret_key": "132633e3d33bcbc61ff70504e34bb033c92db5086bd924eab4ecbb8e4be983d5", + "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", + "sha3_256_hash_of_ciphertext": "ea130b782f8d0167bd57d1cbead18c1a5a65ac27681847b85d8e09030dee8738", + "shared_secret": "13f3b79bb1e5d20ed95c7165a610e122b5de6cb02444cc66e0f1f9ec44c27485" + }, + { + "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "sha3_256_hash_of_public_key": "1a2d9ea0d2280249d9d756975c6979a8770bf4b5f6addbd76d045a816bc1be38", + "sha3_256_hash_of_secret_key": "23678549b4e6e050b57ed1ad078705d33fe76ac976a9f70312b9cb45be554b0c", + "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", + "sha3_256_hash_of_ciphertext": "254058fc10c3327f551dfa143d17dcf4dc4319419050cb5e6841a8d5cb6ce9cb", + "shared_secret": "fcf4227a487e719499f86e44ff74a5339870e4238c20731e0c85f00229f2a1b4" + }, + { + "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "sha3_256_hash_of_public_key": "a57b333a2f41fda2ea72ea11d8bd642d911f6afe90e60492ebeefdc17a932192", + "sha3_256_hash_of_secret_key": "b59171816497ec0c34b963be3ef6366eb051cdebdb145fe445e16b72aa37356f", + "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", + "sha3_256_hash_of_ciphertext": "4bb877beb1b9dbe916e61f9d6d7442deb7483128b6db494a0724e081be74ded6", + "shared_secret": "3f8cf35d0ba76d75dec611e5fb059db5197862b7e5cc6b116a730734932441f3" + }, + { + "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "sha3_256_hash_of_public_key": "d3cd2febe168b1ddf776b954e96085a7d475e3c8cbde68f7c80ffc9fa46b0d43", + "sha3_256_hash_of_secret_key": "b41a159ad0a89e7a771ef11e68efc9d79e6add05b261d0e40620a6b667a6c6bd", + "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", + "sha3_256_hash_of_ciphertext": "62de1efed6f92fc50d8fdef1ff217cb04faf53196e5af3a7507cb6ea5f822e2d", + "shared_secret": "d48544c1ac452c0b821e080e02c9c83e95252fb033617ce270f58e2974679fc6" + }, + { + "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "sha3_256_hash_of_public_key": "9499c1b006a0ec2c299c41c3f728c3bb7848957fb2bbbcd05b65233b89a2b1b1", + "sha3_256_hash_of_secret_key": "bdf5c3beb39ae62a6e29e858962c322fe525a307a163d68f765779b7848bec3f", + "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", + "sha3_256_hash_of_ciphertext": "3a0a1742b1e27f14001e3457a00748f232f550687a232fa409c2098f97e72bb5", + "shared_secret": "6b8f4cbb3c4fda3c067d7ba48bf24e24258ca7e26bfaf918b784d01ae74ec57c" + }, + { + "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "sha3_256_hash_of_public_key": "aa14ea531df0a7f93225de1c75ace0d2692bc750b1b538cfd0d860ae9c5a8c13", + "sha3_256_hash_of_secret_key": "155cff081ef58459a00ae63a6ee0ed2698bdbd99c67b4c9dd09f8b0fc3de0120", + "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", + "sha3_256_hash_of_ciphertext": "8753aea7979a0d3f7aa35b9fab1b320d1b0965899bd51bfc8c1f6de79ff7d92f", + "shared_secret": "aa9878a81dd8165350b880c4af6a2adb9e50a48b9e0709f069c02184d3785181" + }, + { + "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "sha3_256_hash_of_public_key": "e0013ff7eb7b8266ee94659f3372f5981ce1d87584cb1f0e80da2c0c95c16b4e", + "sha3_256_hash_of_secret_key": "7eece78f3f97759d0cfc8a69481271a425c56e540704b2fdaab8b2d920d19e21", + "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", + "sha3_256_hash_of_ciphertext": "777253af58f65c8a85f3feca46f8d32eb5d3d5d0664ea59cfdf47b89be9f005d", + "shared_secret": "5a23296c84df3d660e7c2a973c4e6bddad3fd814e158028ff92b234cffb1afa4" + }, + { + "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "sha3_256_hash_of_public_key": "b503f8ec36d39fc7b4b8ada1cbb933b9db9ee118bf081ed75dd5dba7590f6c8c", + "sha3_256_hash_of_secret_key": "65d28565658fe991b77136b89255ec2d1cf65368e06f2b30bcedab87ffe39550", + "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", + "sha3_256_hash_of_ciphertext": "a7302707d52fc49f3e3637a742826bc8c8267e89c1fdf95b2ab7a0d8f1003c8f", + "shared_secret": "d790ec546719fb05125841bda9dd361e162ca4241e2b489a0f948b612309b649" + }, + { + "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "sha3_256_hash_of_public_key": "03341657b159925cedc8967872a45a3c1f0122979af87a878a2019b3f17c8ba6", + "sha3_256_hash_of_secret_key": "6bb236b9c7a818f9edec1e5da339755dcb7ca1b663a5a208c38c75e7ad7dc12d", + "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", + "sha3_256_hash_of_ciphertext": "9a9301ca946909c3ee5d2171bc36322179ab4bfa825ffc0b826517accbc78298", + "shared_secret": "10086d1a59c41f84a089c239fcd8f8eea3b22c7796f9c1f9b1867b709cb77704" + }, + { + "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "sha3_256_hash_of_public_key": "60c001172c4734a620c248654c58f1c10135657083de776116a6acf8a55f3610", + "sha3_256_hash_of_secret_key": "b10663e90392d6387c16dcad565bbe1fbc05f32495cf9878706bd0d61d289147", + "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", + "sha3_256_hash_of_ciphertext": "e4b3ce9e19c204a884f8a5adbe41acca97a22f1f5f2a13f1185021a8a36a131f", + "shared_secret": "82ad68065774eabcd6e78c027286ca7c7120987c4984e56f52abeb1ccc7a273b" + }, + { + "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "sha3_256_hash_of_public_key": "647a136f20b22c63afd2b88d14fe7677cf5c2b78223a587068377021f6edfe9b", + "sha3_256_hash_of_secret_key": "e70be83a7585618e7b91bc9930a581625e2441962c823a27eda9f6dfff8528ee", + "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", + "sha3_256_hash_of_ciphertext": "6287ca7c4d1eb3afb6ecfc456a4ca9ef5776177dbd5115165424c66e2db061d8", + "shared_secret": "2d56c88020d399532bada6516f9a1acc28a565cf252bafd40043879bcd6de1cd" + }, + { + "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "sha3_256_hash_of_public_key": "1cde599b2dfc69d59036434cc0423337513fb9506452bd8f42bb82661ad0065a", + "sha3_256_hash_of_secret_key": "aa80a266176a7ef8fb22fe21fcf3d3762cfc36734d8b6db3c6e1d4df1eecc1a3", + "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", + "sha3_256_hash_of_ciphertext": "31c85544389bc3163e6893d9298d947a6cd189b045eadf8dcc265e4b5c750fcf", + "shared_secret": "44052d0cc62801e0d9717c65ddcb560246cd901f104b4252eeaef903f7c26af2" + }, + { + "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "sha3_256_hash_of_public_key": "2a50c7a070b3dc7e107eb1e8b96d62305c13327d729bf9d97c69f1fe6eed2b52", + "sha3_256_hash_of_secret_key": "6df052019662b83b16b4da0a85b17f2fe56ad269b294438c8ad298d2e2269d2f", + "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", + "sha3_256_hash_of_ciphertext": "c485c6e392c29c231c9eb04861fefff1fc27544443ebb316c74f9d4d7d9be68c", + "shared_secret": "2e95f47543ff640e6384d65cede004c4fc47e9e2f05649e694c18c7faf975987" + }, + { + "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "sha3_256_hash_of_public_key": "5f166082ad3ab0c739cbf0a6bbe2707741d9b5f53a0e16199280a2376c9e5a17", + "sha3_256_hash_of_secret_key": "391b71e679b9a0a23a1aeba042ec7df439fa0a18c6442dbfe2bbe05d4fdb5fd6", + "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", + "sha3_256_hash_of_ciphertext": "499c37f74e94c6c724e218f339b8d60ab65190e0a56e39a6b4cf619db98bb57d", + "shared_secret": "42f1442e384b4e747794c944f4df154cde33cdff32bf35c2c5234919762030ca" + }, + { + "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "sha3_256_hash_of_public_key": "40b3a72c164432e6ca838693ef25b30013e5cf56c1e6142828107a10cabdd169", + "sha3_256_hash_of_secret_key": "6f970259ae97422f8698120bfa8e53f4f89589773243db6e7a1859c94181a3f6", + "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", + "sha3_256_hash_of_ciphertext": "55e508c96b8b7c06cc9a88b4c9f974abd3e2cdd96ba6f0cf330ccaa3641fbd29", + "shared_secret": "a50a07f6b01ee4429848806031637c8ef8da23f253874124452e3771ef98b6e0" + }, + { + "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "sha3_256_hash_of_public_key": "f475da2ec982c47d91b24bb5ec6c51910530eec26f38541b173b38927d23c568", + "sha3_256_hash_of_secret_key": "f8c836ce8a42d6d07f1ff40e2dbf16d264bb6ecd1cc0227ebf792a6bacd327ec", + "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", + "sha3_256_hash_of_ciphertext": "d63a88547104683878df29e59de826821fa3a95bdd668e5e838e08a671d887ee", + "shared_secret": "c299f650b03170f5cdef5da81e52c2a094b11aaf58426e8c41e06a26c7d5ccc1" + }, + { + "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "sha3_256_hash_of_public_key": "2b22f73a770cbdb80da84f97f27a14c5df5b3372d52503d3a20c3cb2bea8b404", + "sha3_256_hash_of_secret_key": "a111bb1797a3baeecc223e4fc4accf093d2e069cfd40d45346d2aefc09acb358", + "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", + "sha3_256_hash_of_ciphertext": "e9c030db90931ef3d2a61077dc33529aad87535e809d1a255fb5b5925f202893", + "shared_secret": "5e1ac468279cfe354c4d0df6ead070071b19c9707338158ff7dc133684afe2ba" + }, + { + "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "sha3_256_hash_of_public_key": "3d8fe8354d81146fd65af657da08926bd3a6ecbc2f81cb58d1aaacfe5b6e686f", + "sha3_256_hash_of_secret_key": "d1c524a715b2d05abc8e8729204b620f4551815cdeb00662b487d58e99c0ac7e", + "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", + "sha3_256_hash_of_ciphertext": "c256150127c8119ae42a62b90ac9a7119a3faa5442f058bbe5844d29c99c4eee", + "shared_secret": "7841501410e4158cf04f92b9d65d0cec732984ea66809130aeb594156829dd39" + }, + { + "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "sha3_256_hash_of_public_key": "36fc15e2340175a2a64ca1cf31a4b38ed5f797aaa8acb0c3d2ed9c19c7099f27", + "sha3_256_hash_of_secret_key": "0741ce5533316ef689bd966721b1ee57a272d5eb557dfa6fab6de770a2e7afa0", + "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", + "sha3_256_hash_of_ciphertext": "0c6a7cce80da6e6a3c17b46959124b8c26a8a74b5068f707f582cb5b811e282e", + "shared_secret": "6b3fe0dd082bf384c3e08497d380516e78ca778de627c112d02dc8c393334d11" + }, + { + "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "sha3_256_hash_of_public_key": "26a1b77ae8a807e9de16a9ede5da5aec3ca5f23f5ea00e455d4a091467e6ac6d", + "sha3_256_hash_of_secret_key": "2bb0f5318208eba32bfba206dfe174f976431dc12421bc7b3705fc7c0b4a06cd", + "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", + "sha3_256_hash_of_ciphertext": "ba2e94ce526ee4bdcd818855708af8173acac373696df4f910720fb296bc1076", + "shared_secret": "cb15c306ba8d5f4f8b723db93bfbcfd4fa02ef32ed8e39c2aeb706a463d9a40f" + }, + { + "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "sha3_256_hash_of_public_key": "2460170e6cf1da1e7b92037f51b4e7674d9abf74f5c225c5c6ce16a971691284", + "sha3_256_hash_of_secret_key": "a364a1f435a2d2a341b59a1886af0d0f3580e56306869bbab819de741ac9f642", + "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", + "sha3_256_hash_of_ciphertext": "ff21fac2cb15307ebb70ec04904f636bfac9ba968e86984b4a55dcac70430c1e", + "shared_secret": "8dc8bc55a907bcbad27aafbba2cbd957c30794e3770d0984a6323b641e5fe53d" + } +] \ No newline at end of file diff --git a/libcrux-kem/tests/kats/nistkats_512.json b/libcrux-kem/tests/kats/nistkats_512.json new file mode 100644 index 000000000..6a3125287 --- /dev/null +++ b/libcrux-kem/tests/kats/nistkats_512.json @@ -0,0 +1,802 @@ +[ + { + "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "sha3_256_hash_of_public_key": "7ffad1bc8af73b7e874956b81c2a2ef0bfabe8dc93d77b2fbc9e0c64efa01e84", + "sha3_256_hash_of_secret_key": "26e1b5ea0f48b3c87d7ce87113b6a93a49d9f7ede7c5cb15b41382bd3243715a", + "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", + "sha3_256_hash_of_ciphertext": "a3856ee9fb112b154b397c91398576dda45391b89742603436588d81ce6d1b50", + "shared_secret": "c608777086ed9ffdf92cd4f1c999aedd0b42e5e8ef6732f4111246481e260463" + }, + { + "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "sha3_256_hash_of_public_key": "13f0970c03d32967b06cca4cf58e87559128d14cb3f876a1ed10eadfe03fc1a9", + "sha3_256_hash_of_secret_key": "9c613d0d3313af8169e65295e8c4f21f0b5d3e78de031e78a12ec864d71b6548", + "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", + "sha3_256_hash_of_ciphertext": "557c682bda01552173367f40bd2b2c1ed64aae3f083c80ce2f812d0b60acfacc", + "shared_secret": "9401f92689a452b5e58c35cf06690596faa4ec0937a04493a359b59ab3b0fdee" + }, + { + "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "sha3_256_hash_of_public_key": "083553153f7d65cd5cbe201e681245eda61e1ec2c7ee6b91a9ccdeb6b76943b7", + "sha3_256_hash_of_secret_key": "b4148d4bba0430ddca173618456704ddf440b9b5bdfd61ee46bd79590dd78ff3", + "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", + "sha3_256_hash_of_ciphertext": "7b7b882320575a3cfa5f0ca2165ed39383921da042f7bce896896fa90fef2aef", + "shared_secret": "f2c689c7a8180baf27a4573d3e6154d4f2bff7b3f34d44576e777e2ac1249e8c" + }, + { + "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "sha3_256_hash_of_public_key": "9df5746a44b10c1886f62b068d18152a85792781160e1a1a19a25b5ca00555f4", + "sha3_256_hash_of_secret_key": "75a93307372e001d4fb028125dad61c4412ac864bf7eac7a213ad3dca6599981", + "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", + "sha3_256_hash_of_ciphertext": "72782e8ee6fe4e4442723e727b5d415f66fda7c363fe6dc7be22d9b8741852f2", + "shared_secret": "1dac4f6f8d96ffd931f67b03cee8c4e4bcb42eb8bbda5cb702dadde8340d1524" + }, + { + "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "sha3_256_hash_of_public_key": "9415ce164fadececacd75fdad3284af20c52fa576699029d6e0ce77bf347d520", + "sha3_256_hash_of_secret_key": "97f1f85233dba2a50848add15f8f0e60f4ccf3542dc6da5f59e06f6b27c59c67", + "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", + "sha3_256_hash_of_ciphertext": "80f49e8f6f8d442a7678f2c33881a5264b58a5998b7d9a8e10b2febf59ba868d", + "shared_secret": "01adaecc8cd981e7f00187622defc0cbb8934464ca4675d86bc7d9b69148c85f" + }, + { + "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "sha3_256_hash_of_public_key": "ca2232297ba8b986dacd401896cb6239f557720d91a2cfb7a73274bac7a0f6de", + "sha3_256_hash_of_secret_key": "17446e8436a68423ba4e22a57135d470c7e91fbe0a4da065bdc34897fda89b2f", + "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", + "sha3_256_hash_of_ciphertext": "a08cfd7a6374d902e153b862449efdee9f912234f3e7a7d2697ebf1909f59dfc", + "shared_secret": "6f13bdb1452d9e672c8fedaf9450c436e5fa77e8d58ce83300b8e539f20e9dfa" + }, + { + "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "sha3_256_hash_of_public_key": "34486689b387ba25dd0e9aedbc53034924ea4ef9497b5772f10ca4d091e9e846", + "sha3_256_hash_of_secret_key": "94419fc5d865a97586b71a3414721f04473d4d30e5a8d6a1c438752f19504209", + "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", + "sha3_256_hash_of_ciphertext": "6b930dced8da8c0353569fe807e383e2d04836680fb78881ffc6974802131eca", + "shared_secret": "c81a637f63a802a5d2b336dd960175176b2b838ffb6de5adc501bef984fed26d" + }, + { + "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "sha3_256_hash_of_public_key": "39d1850f7acb36ed2a35e9af6f94a06c31afadaae3545a069f892ecd8929f766", + "sha3_256_hash_of_secret_key": "98a2ef35596f2fbc7e462d5ee536f30d8bc3a5272d78cb14c0ce816fbb180396", + "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", + "sha3_256_hash_of_ciphertext": "2d277dbc8b03bbec796e778c74b4c3f408f3e47835398039236d7cd861762a9f", + "shared_secret": "3031994f1365446186b4a4d6190ac89f928f6706d08c6316d6f522cd7605adfd" + }, + { + "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "sha3_256_hash_of_public_key": "edc8db1ca35744a75ca14516abe07472d0d1b723f70ca8cf0e5c9341fd2e8c26", + "sha3_256_hash_of_secret_key": "fa6de16f50b0c04b8be10d3262005227715f69de5089f0f6bafc1fe26603e525", + "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", + "sha3_256_hash_of_ciphertext": "c20e526b8837092f1847b40f9b5fda528dfb72780aceb510635b490acb5f7686", + "shared_secret": "61419eeacf26714b028d2f7e1e3769ae2f181a7e9311f3312911ead00486bcd5" + }, + { + "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "sha3_256_hash_of_public_key": "b1eef6e8c88ff8da9cc4a9b01d4c08b6b585beb5bb9e084c6c47a717b51feea3", + "sha3_256_hash_of_secret_key": "bce9d6b2e45918ea5798910aa9baf289b04d8a5bcfa7e08235dccfc8b9479f55", + "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", + "sha3_256_hash_of_ciphertext": "811bf647ebaad03c81a84c6a82b4cab108267b1e9c1add3dff1803623471f9bc", + "shared_secret": "3871c9637cbea04a2ccd3b62c9399b0a7277a31caba8a8f015d59b0fed845bb1" + }, + { + "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "sha3_256_hash_of_public_key": "f581c2fec9055830b38cb68fb506aa927443b1afd1b2b6faa6f92a325985c6ce", + "sha3_256_hash_of_secret_key": "9567f27ef67c3ada92a02cf25d8ee4a6db69744d3f6de5a0026dac023d04f37c", + "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", + "sha3_256_hash_of_ciphertext": "c855f0a4521640b9136035b5d02770dbe864b85a6f54f422ccf2b512e1c07b33", + "shared_secret": "3775b12681d854b7ff2eec05cd4ac2db91bf06f3c14db2eb35287129a960ab03" + }, + { + "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "sha3_256_hash_of_public_key": "f12f3ecad62bd327f1c44ae86c0be6e7f15112b7f6f6d5ec7b13f4dfab718965", + "sha3_256_hash_of_secret_key": "32a666c02a41f7b9408c570a3304a80e947a1be650f5f164e376b8b34b72254b", + "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", + "sha3_256_hash_of_ciphertext": "632b389d951d4a4e570d2fee62dd87c3aa2cf0c036dc63462f3ee7e4543ef8b7", + "shared_secret": "87662dcdee8b176e2dc60d079be188f63501274bde0829f3595c99d1e564c2d0" + }, + { + "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "sha3_256_hash_of_public_key": "4cae8b58e0434fb1475312355a8b40145043bed4b269aaddd654d2e562324bc7", + "sha3_256_hash_of_secret_key": "53793d47a6e9e527f109b7611f33063dbe0b8a1423ac02178934f59c3d47ddb2", + "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", + "sha3_256_hash_of_ciphertext": "6f88eea1ec597548ec3c0d22c60a92ac4b0c3e17e332983d01a0bdda1157ecf6", + "shared_secret": "c5676cf0cc81871d677bd7f5982e6493aa3ea4dffbb30dbaf59e90e4977d2f12" + }, + { + "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "sha3_256_hash_of_public_key": "b899475c1802b1dd76a9783d93b4225dc558eea558ddc598cdc45a898b7bbfb3", + "sha3_256_hash_of_secret_key": "278b448b48a14a9be1ed211228cfab37d07e5f1e502478e3ad059c83a7c83894", + "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", + "sha3_256_hash_of_ciphertext": "36f6daad6b98df3f8e26456d06f112ca69231333e4ebd86e04fe7b8fd8c1bf26", + "shared_secret": "c5b03a417c10715a53f3a1efc044a81e266b40a1b16c87aa1f754146ac39b80e" + }, + { + "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "sha3_256_hash_of_public_key": "1a7e0760c345cb5875303e20e4c72076c794e56ab75231750a190b45f374d979", + "sha3_256_hash_of_secret_key": "eb53a36a9f50baac64b4c7bcb97fecae54d3f66b8311b5a67c5daaefaa63f209", + "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", + "sha3_256_hash_of_ciphertext": "1b4728ec7c6e90ad99dbee3b83438050df88887de2e6d7a6ec55e7a2f7f1bbc3", + "shared_secret": "38daf9348e4d89149e4968131370ce3d38a4028727fb85d27f87a95b341340fd" + }, + { + "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "sha3_256_hash_of_public_key": "0f96fb9e146a1c22cc5d23e9108af0dc5e13b7810b8f5598bbd5f8d4b54c8af7", + "sha3_256_hash_of_secret_key": "d494ee913886be1398be54856ebc83eb8cd7aab4268b976583be2e097edc2d64", + "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", + "sha3_256_hash_of_ciphertext": "3934a38f7c11d237b46c9d93a8ab8d3dfc76b3e020b5cfcd0344eae35a333e45", + "shared_secret": "60bc23845c0b116208c0ea02849cea3d8025a7220337c617c4bd304aedcdc1af" + }, + { + "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "sha3_256_hash_of_public_key": "0bb63b48b8cdd1c7242bd4f017c519b43502656e23817bfd683150488f8b0b44", + "sha3_256_hash_of_secret_key": "195207c9e44942d5cfbf338fb9f20317d3ae8be85dac5f10dd60abd802a3caa9", + "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", + "sha3_256_hash_of_ciphertext": "ddcc4d878447ee699abdb85f1463b113784be6d4e42c46379b31c02715243f17", + "shared_secret": "2eb03b010e291fca1bb6ed09d22d50b9c7bec93c556f1f273e57048c9c56bb3c" + }, + { + "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "sha3_256_hash_of_public_key": "2d19bf7937eeab0d2a7570d43cf965547542a519be85bdd4921f7d710747ec6f", + "sha3_256_hash_of_secret_key": "cd59ca5c7954d87bc8d025683563aab0f9272d6c12cc03914220aa6ee392e6b3", + "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", + "sha3_256_hash_of_ciphertext": "86184bc66edef41a25ca3350698277f4e49713b821fd0745d276fe490ac636d9", + "shared_secret": "be892649db60b2ce07ef18c4a709714933542ab94ee3250cea6e7c6f5eee5d5f" + }, + { + "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "sha3_256_hash_of_public_key": "6907e1096410ab332e10f37c93d86d9b4657159eac1faffcd1688d182d127844", + "sha3_256_hash_of_secret_key": "250d27ac4dc4447520c4c1193ac57d239857ecbeac2b1009dc08dca2114299ed", + "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", + "sha3_256_hash_of_ciphertext": "51c6ca6d7536a183416b16b1716cecd3d994dba4b5ba019bced87bb51f9cef0a", + "shared_secret": "75556d5854c44805ca5c4bb927c837ff635feaae939220592d89caf74592a0be" + }, + { + "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "sha3_256_hash_of_public_key": "379c9176059f3a7ddfe021041301bcebbc91e997a0d5bf2ed1d9d125a7129834", + "sha3_256_hash_of_secret_key": "57df17dd8b9b1411af66d82f61dd61c4f5235f48d503c164ad0da02a598a69b2", + "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", + "sha3_256_hash_of_ciphertext": "a5773e0569d9e26225b05bd61591d1722c4c1396789ce3156ef749c115949ace", + "shared_secret": "469d60c303b10f517a932d9fc090e61802003e9cba3630224f2c43a4727230e1" + }, + { + "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "sha3_256_hash_of_public_key": "f5515b23187af5dac6d1d090bc7bc01df34ec781561e3d3b8b62164f74946802", + "sha3_256_hash_of_secret_key": "2ab40ea093450e534152efb278b45038f1f2cccf13a654f1c5c27b8c389f6129", + "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", + "sha3_256_hash_of_ciphertext": "d1b469613c872181c4428440cec1ccf87b82303e4979de6eddd437decd8afecd", + "shared_secret": "b545dc066355b91cef05e65107fa11070c455209c55573cc549cd053c8e4155a" + }, + { + "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "sha3_256_hash_of_public_key": "9dc0d69094efe63d751e6f9c1e92d2107a7b45fabb820222d30b11595c351643", + "sha3_256_hash_of_secret_key": "00f4a04ab804f2fa3ed80a0fa4530fd45ebff8afadf5f5b7d46a672c690ac3ac", + "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", + "sha3_256_hash_of_ciphertext": "774abc2c6dc9570eb781a39f79f49f2cc6870a43e8812559d89d1c59bb1aa5ef", + "shared_secret": "2c42bc4a172c928bc6ec7480785d63f7281a9e5acfd3f94335d6d7fe5fb9c5d4" + }, + { + "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "sha3_256_hash_of_public_key": "16829a8aa9f8c4e949d4e6388448c2c4ec6a977f8c5fb80bd75d93a723bc9bbe", + "sha3_256_hash_of_secret_key": "659cb66f989532fdf5a741fd03862fb142a05a0fb43ae20bffc5116de1a66d57", + "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", + "sha3_256_hash_of_ciphertext": "ff53eb11ffac30f45bc8327d7e7d518f1c2d71bae0052ce8e15903c8d14978e7", + "shared_secret": "230a69c53e2192eed6c9b876d6b228fb666b19448e0a2ef8601910d624bc173f" + }, + { + "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "sha3_256_hash_of_public_key": "90fe22b38a4fafc045cdbe0c9689745fb45760cb2f0f94f7d13cf8c834c4df3c", + "sha3_256_hash_of_secret_key": "10a89c990c7676890a65e1c776cf892ef1431d56fc115ef3115c0b8f91db0690", + "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", + "sha3_256_hash_of_ciphertext": "3d1fa5720670ea284567d32beaca2e56853f7b6268e32af381034f13e4cd4853", + "shared_secret": "327c548d7df90d813f3b3c92e908c4c55fe4c7277f91b6fa2271c0f149dfb273" + }, + { + "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "sha3_256_hash_of_public_key": "c277a9588d9a781ddff6aa9ea8d259e5599d0adaba2f459598ebd5bc72786023", + "sha3_256_hash_of_secret_key": "40609cf26d205ce694ca8baa097bc1342d2462a26678eab90893da147e389d3e", + "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", + "sha3_256_hash_of_ciphertext": "bd274d905deacefc3d90a9ed76d59af4e814cfc06c118ec17662afa4f6b4fdd6", + "shared_secret": "0d95796efa11ef2b4f05d0cd9e1d8db26f3e5839fbba7cd84e00d468decc088c" + }, + { + "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "sha3_256_hash_of_public_key": "d3c8cc315c4054d09deac08c6d5d364fd5d47a3c09041bee42c561f978e2d98f", + "sha3_256_hash_of_secret_key": "3e1b23ca9dc111c4a3cb0a585c7f4e5d1f27a71533eaa5347e285c7c35e81990", + "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", + "sha3_256_hash_of_ciphertext": "c866f33265de001b3308ec41682803d46dc61d423d61565aa5ab2f1367c93e3d", + "shared_secret": "cc047c6cad36dd056b84e6b9a4fb6b1b349d593e104ba94a67b107b291ca4633" + }, + { + "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "sha3_256_hash_of_public_key": "dd1a07043fa0c6452500249601f25de742ab44213e2718cf0ddc5ff6a2a9aa6a", + "sha3_256_hash_of_secret_key": "2cfeaf5c1b4195f0374256027d3a888e9a093de8ff9181296d5b1b94048de38a", + "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", + "sha3_256_hash_of_ciphertext": "6dad2899c49ef32329180b6b8749c28a24e070fe989027061dea25f0b05490b3", + "shared_secret": "2faf2dd50be618b025cd2b53365221f5258e175e4a445cf053c66b3d3a998c8a" + }, + { + "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "sha3_256_hash_of_public_key": "f2a8cad42c743eb61aa338049ce917616899c803358541de1e58cbbdcf3c6328", + "sha3_256_hash_of_secret_key": "7a9ebb792c7193ffefe6e4760ebd0dec6f67c3f3b0fddb5abb4b7e931ee827e6", + "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", + "sha3_256_hash_of_ciphertext": "125f7da90bdf4bbeecc54e47e065b221a6ce42d0569530c136ce2c9415b17e79", + "shared_secret": "cd890d2eee7f747441ca9448c7192bcc274e8b0c3c80005cb6fdb4691186d85d" + }, + { + "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "sha3_256_hash_of_public_key": "3394e8401245fd6348bfa697f6990b6671577ec7b35a45b0101730a801942643", + "sha3_256_hash_of_secret_key": "3ecbb219e90e2250ad5ba87f53975439cacc030c3e1641b87ba8c5b3d89a4aba", + "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", + "sha3_256_hash_of_ciphertext": "6cd30cb202554c18809da0819ced4cfe83021874fa9c48c3374b7544e3256f5b", + "shared_secret": "e7942359dfb015d5022b790b5e777a93a5963260ae352567d3fb7e27b2ef0bab" + }, + { + "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "sha3_256_hash_of_public_key": "ec9c0d68c84cf3804f14e8daffdd1e28c28d3d55ee782c98c498b0d9bd4ebb23", + "sha3_256_hash_of_secret_key": "24a2b3c3efd979a1406e92d5c504d5004079965b5fd0492469f1b4250f7023ff", + "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", + "sha3_256_hash_of_ciphertext": "a2c6cfb957639661086b02d9a312e7483150fae87d84f21f56e48850af7e3b62", + "shared_secret": "5d7b6ecaadbae69fbaa9e004634ea609df6ec80801bbe73671f4e52169cc9683" + }, + { + "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "sha3_256_hash_of_public_key": "a9d7d5a52aa2dc226832f6e4603322f60b1dc21207e3360712f9c6445d37e64d", + "sha3_256_hash_of_secret_key": "2e5342a1c2f58a48e044a26673799c63f88656f6d350a0d7e57bbf8811b2a5e9", + "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", + "sha3_256_hash_of_ciphertext": "b79a2fbd2e63aa66a526fbb42440224fad7ce91206df3684d1deb4a3e57bfafa", + "shared_secret": "547666f6c72c97a8f06fbd7cda4279165dc82489aba2119416e0dc46795bc464" + }, + { + "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "sha3_256_hash_of_public_key": "fa7ba132b5dfa2e3ce67b64bc72d551f3290d428cfbd45ec026f44c8dc28334d", + "sha3_256_hash_of_secret_key": "34306d06720216257691fc65054ed32decd609312f5c5f061e7763ae73fe0aba", + "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", + "sha3_256_hash_of_ciphertext": "acd7944297fc3b0d2daa3b0cbc999a43de7e9f948d39b9c6a4746873e285f8a8", + "shared_secret": "88c80381cde3db2c1d40aedf8cf923b79b18cf76efe0e46edc3e25e17c7cd8c6" + }, + { + "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "sha3_256_hash_of_public_key": "29f8a01ba71d04d6831c03d1ff294fb58ef6f4041772cc071074829c32a3ac9d", + "sha3_256_hash_of_secret_key": "95f9b4063bf05f89ca9f99e393b11c0f2105eafe40abb313f345b58e10519955", + "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", + "sha3_256_hash_of_ciphertext": "096f7946c01dc61a13dac8b85d9c377f9c86aaf8ddc02163a74169854046a1b0", + "shared_secret": "ccda9f28bb09dc0017a1df8e1796a3489c66afd2c3898a39027c843cf022b790" + }, + { + "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "sha3_256_hash_of_public_key": "357376de9843d74252466888727f9dc1ef48d028c0f52c902aa0dfc3de374c83", + "sha3_256_hash_of_secret_key": "b8d675ce213c73f9792f328448850047f4410fc500212939ab2e234b619c9104", + "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", + "sha3_256_hash_of_ciphertext": "a0810d28d2dec44499bc47d48ae22984c17728547c3ff0cc859702d2a6962f88", + "shared_secret": "caea7e78e6f80e126a9f41ddc0ae5946a80cdf617635934b22c9097c5090ce59" + }, + { + "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "sha3_256_hash_of_public_key": "30382cb59feee1b6b0fc129fecb8c74034da92987249bc20cc8ad4a2cfc1bfe0", + "sha3_256_hash_of_secret_key": "2600203271549828d0979adea52e2e976b7d9f85bfa6931d6c79e14137fad51c", + "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", + "sha3_256_hash_of_ciphertext": "4d20b7665cdea726a3240782143beb60585d4ae39bf18f4ab5343d4f44c7acd6", + "shared_secret": "431bba421ea89647d815a16f440d47f1604b67d9a2d33f2dcd21dae7e65bd5ce" + }, + { + "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "sha3_256_hash_of_public_key": "f4e474fd64a6d945e85eb4ee7509cc99fd4054de99f819fdbbb05c54ca6e36da", + "sha3_256_hash_of_secret_key": "d8a3a0edc73fee057281add9e7cb328566fb22c5082978c69088d76e98ffff90", + "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", + "sha3_256_hash_of_ciphertext": "0f18bede2f42d6fdf32dcd2cf8937ee8d2909eef0aaca8586c3892d608712a98", + "shared_secret": "cc0a7809cf6787a4587e090249709f694b709ec8475a42b4705bd1ba312c098e" + }, + { + "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "sha3_256_hash_of_public_key": "50688de263a82386f39a7b82592247bf5499f1836a3a941413c75f6331ce4031", + "sha3_256_hash_of_secret_key": "ff207007724ca5d696ba44cb106f525858111d55323c9fc0fb98d64d4f8de8d8", + "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", + "sha3_256_hash_of_ciphertext": "9dcc43fabf94918ed4f7936960d8c732deb2209090d1303d62d5ba591b51a142", + "shared_secret": "cf21da86b3e09c38ce5799637b1492a1a268dbf0ac716499c68bac11a774f41c" + }, + { + "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "sha3_256_hash_of_public_key": "1a29c0f2dc4089a85db6865ec90faf2f4ddd25f210eb56e49741866bbca8cf81", + "sha3_256_hash_of_secret_key": "477dbc28e4f21587f274e7a3b673f743840da1501c35f0e9ceb8972970de6f86", + "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", + "sha3_256_hash_of_ciphertext": "877f477beda55ed2a7c34408c04b4a90596b4d94ac1830bc04a0ac9b73761ffe", + "shared_secret": "b56f557eb758ae10d22b5d65847cd811475b96f5a46b0ed3bc2f1b9b371fef0f" + }, + { + "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "sha3_256_hash_of_public_key": "3fffc419d3d8a887ff789eb661b2af1ee5b32a302ca267b33eac2ea7e3340b97", + "sha3_256_hash_of_secret_key": "0f42068d2885e1a44b2ce4042675118f4fa35f58c1206b965b57ccb52c4f25f8", + "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", + "sha3_256_hash_of_ciphertext": "d8f7b4a0047c18a84ed13e3057e240cb578cdd2ac1e57dbbd6253eca9208d6df", + "shared_secret": "aec1264f12ddd2ee8e51b71d703ca5c2718dbd79858240635f9b076c749a5ffb" + }, + { + "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "sha3_256_hash_of_public_key": "f1de70b1072881eb659a5e890a92c9313c7378d2e960a060b9c918260d4c2458", + "sha3_256_hash_of_secret_key": "ecd9d757d80352b4fb51c71976d7b2ddeb927052f9f7a7cc61fa67662d4dc86f", + "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", + "sha3_256_hash_of_ciphertext": "10b2b1dfe168aace0dce3776456c2e2605f99fdeaadfa3ff5e7a81f6bafcb76d", + "shared_secret": "6514a3b97760070116c64014c5695df60d0345b29ada92fe24b672586f5bf06e" + }, + { + "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "sha3_256_hash_of_public_key": "b0c77b5407577a9a9cd8864efb80974aae107fa2801b6ccaf341d5456a86621f", + "sha3_256_hash_of_secret_key": "0feade68babcf09673bf843c59379520c19081f2bc33940a8dfcee07832ec66d", + "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", + "sha3_256_hash_of_ciphertext": "b204aa70efa18e31a11b6b92e6c7dab4b2f4766ec5d302a0e93e4feb05fe4843", + "shared_secret": "52344e5e173fc6088c9dc555cc90d8e5de19bdfa0d657ad8de1a3c24ea679bb3" + }, + { + "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "sha3_256_hash_of_public_key": "255d2e2fe01c87cf70bc30703644fc255f83fb47cc5cc5ae2c0e49d6198cae03", + "sha3_256_hash_of_secret_key": "1b1050f38bdb785ed43daa264b60c7946d93f135c65e93c95c39fd1f2d7b5311", + "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", + "sha3_256_hash_of_ciphertext": "55165f35498250256c30d0f0fba6ec57db352a6ebc05ac42eaa8982b2d48af5c", + "shared_secret": "ce80f65731c8fac072f7153bbdc425f76189d01bacee8462060c62dfeddfaf64" + }, + { + "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "sha3_256_hash_of_public_key": "63b304a19162abdc4234e6046109f99f955695580a8b782017e107e45575bd78", + "sha3_256_hash_of_secret_key": "19aba21e57d4b3aca7209fd5cbd15f9e7cb9f6777960d9452fed866e9e9234f0", + "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", + "sha3_256_hash_of_ciphertext": "5eddd27af25f9553e3a5b20e4de86280c65eb689ffa7773dbb5d24640bf51248", + "shared_secret": "3b23a3cfe57897fa9cb691ee9805739f40d2bf22930ca9ee48ebb7163cd66bb0" + }, + { + "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "sha3_256_hash_of_public_key": "3c598a48b06d7474da19ca85aff6b2b3303b5d25b96088c52a08cc7f1e87c5fd", + "sha3_256_hash_of_secret_key": "03c563426eb21d277421a30ca8980d4de86f7aedead9ab9aefb3d7362104ec50", + "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", + "sha3_256_hash_of_ciphertext": "244dfd0105b643caafe35fdc184b8e23c7538370d545e6f08357e83f413de258", + "shared_secret": "272ecae17c3d107a8b008f60c8844ac01e09b8bee17eb4972f5f71774af2d54c" + }, + { + "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "sha3_256_hash_of_public_key": "9911b6283fc6dee66e16d411fe39bbc9f53c30bb54f05044b96c740ca051c61c", + "sha3_256_hash_of_secret_key": "06751acd0a50beca92428cf8c803af429068d4e5c4f74cc59e6d3275ea6da737", + "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", + "sha3_256_hash_of_ciphertext": "dc8797dfa40479e4edee48d320320ca4a84c55789c94c34ce4f0a4be83ae0568", + "shared_secret": "eb456d8919c7e96c4e18d7a0ae27d47996e4f94c46c60b4649b327903acdc0c0" + }, + { + "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "sha3_256_hash_of_public_key": "e78d350d2836d1d17e6ec375a0cbe0d6b2afe1ac036272dd41f8aa769c9d0668", + "sha3_256_hash_of_secret_key": "f74b8f9343146c1551a3cf9fb3d4e88febba4e98db745f36678d854230a8d7f2", + "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", + "sha3_256_hash_of_ciphertext": "400cda4e51c1eb539625bbe6679fc13b009e72cd442a1385759e7090e54d31bc", + "shared_secret": "3f92ab2eb867d4e2e658917fe95b19042cd768dbbcd895e83b7bfda621fc428b" + }, + { + "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "sha3_256_hash_of_public_key": "5820c7564d087683c0a4864844335bcbd62afa1ee542c3c1dcd8b72c80824b50", + "sha3_256_hash_of_secret_key": "11212a895ad32958d25d2ad32e917bd5bfda9dfcf08e316f733b74479469f9b2", + "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", + "sha3_256_hash_of_ciphertext": "fad3a5efa62eabac076fd38f84e91f3c20f7b263408366c476695a9665972ddc", + "shared_secret": "5890e86b38f7fb11708a63f5e98ad65d10db5916e6669e1b0161142e6d30d017" + }, + { + "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "sha3_256_hash_of_public_key": "c56eb5880e9d9d0fe7901747f75eca1996c722ac47b76f34a4dbaaee0ef8a611", + "sha3_256_hash_of_secret_key": "8a90ed45b5910904e2e9f6a6e410d4caf024ef6436fbb75fdd179eaf09f6f362", + "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", + "sha3_256_hash_of_ciphertext": "16f18c8dfcb9aa496f8c6f8a76af4cf2405407e0f0467deb4adb7049595b0df6", + "shared_secret": "3b09c4579ad60b17eba6029141a6d9765e1abae72ec32f1b329a5e2af761a087" + }, + { + "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "sha3_256_hash_of_public_key": "717823f0b58cdfacafc795aea529561d11374f02964cf635c27848671043766c", + "sha3_256_hash_of_secret_key": "f3c47ab6b2f2a0962faf49bbc31f3101d6f4b867952aa3bbee32408c1b88ee82", + "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", + "sha3_256_hash_of_ciphertext": "fd6a149b033707358fc07243d95b0256153c30e65cbc9479ce05ad2f96204a37", + "shared_secret": "f15864351fe8e878ad66b402f012668e8bdf21525f09d5bcf4a4dad656d2e480" + }, + { + "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "sha3_256_hash_of_public_key": "7a13afefbba39ad59c088825380398f43f1251b83b0ca9debba0102f902d7190", + "sha3_256_hash_of_secret_key": "da94e15b824e73150a408df01cf1c5e4128739524831a4c2f45d0724144010fa", + "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", + "sha3_256_hash_of_ciphertext": "9193450ad037d38d8e85a46a522d4f6562ef7c7aa1372a2ebbc7ecefd1286bfc", + "shared_secret": "1f1a7f0d0d86a52a6679c431c322263b185b0c90ce40db054928be438f38d47f" + }, + { + "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "sha3_256_hash_of_public_key": "dd4cfbc29de3568663a3a044c3f897714363b0fdd3b6ee55f796292d34c7c79b", + "sha3_256_hash_of_secret_key": "6142d02fd4501c7bffac124bb8f26813009d2bfb91023a3fadea9506a40e1467", + "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", + "sha3_256_hash_of_ciphertext": "bb6e0249218f8bb4712d60e59f51cde2dfecfc1f828eff42f2707aa59f12164c", + "shared_secret": "aae9ca8c35deddcfd7dbaa7780fe31c102aa90cc594eb56edc782fdc4eb53b41" + }, + { + "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "sha3_256_hash_of_public_key": "9ca90d64e28a5bbc54c36053ed333c530f72549c2afd77b10c2944fc833408fa", + "sha3_256_hash_of_secret_key": "510f84cae4d4307d7848f4c9665061657ae81526139a8b6a4076ad3df919abfb", + "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", + "sha3_256_hash_of_ciphertext": "36b3567939ee624d5088c4daa597c73349270a754d3c272ec3ca5e08bf896fec", + "shared_secret": "970fe36e57a253e88cc80c9da6867dd66fd8da1dc15c85a480a1a45eed708ff5" + }, + { + "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "sha3_256_hash_of_public_key": "da073c98794493ec169c78eb75a39c1594ccfa635b8707325e0ab6cb8576e30c", + "sha3_256_hash_of_secret_key": "7829ef884941abc63f66889c3d44381f5450de1b95c6b6f79f909d74b27125a3", + "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", + "sha3_256_hash_of_ciphertext": "43f8a2c466c09c915fdbf0d0dc5069ae5333790e7efce86c163d360dd0fdc0cd", + "shared_secret": "8eb310431276a31c1913cfa2e2d6b0dedc8a208c7470251daebc5b1bb6ee78ec" + }, + { + "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "sha3_256_hash_of_public_key": "c2aa254714dac09b9e712572b24154be391063afd3cd8cf4cc4ed8ef21f0cfe5", + "sha3_256_hash_of_secret_key": "2e552fd01c00cf43110aacac37d01c02e5f59c87133e3769d3b2bf0fd2e4431d", + "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", + "sha3_256_hash_of_ciphertext": "854806aa3266473aa5fa6097095d5f21707ab4df857d927e8848146bc4cc2bb2", + "shared_secret": "425a88aa4cbb6b6de122f1730aee536f1cdb8fc84751fc6eb2b42bcde5febcb1" + }, + { + "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "sha3_256_hash_of_public_key": "8aaca951e0573f28d50831960a28dd11126f0eb080afc55f394e8eaf6379f6eb", + "sha3_256_hash_of_secret_key": "45592f0d94666d8201247fad4d0acdfdb4635a5e4fa85b7e25b2391639451bdf", + "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", + "sha3_256_hash_of_ciphertext": "035223323ac02f2a52f9c19da46b31a7e189073fd5ef5ceee6ab8dd1b062b6d7", + "shared_secret": "457efc40f2e99aa599ac1ef92f9efbfc93d17fcd793837857f6a5c91a8dd7da2" + }, + { + "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "sha3_256_hash_of_public_key": "f15a8fc937b12ff78c54fc273fcd7dd5611e5835472ed377652ae64495f9cf52", + "sha3_256_hash_of_secret_key": "dcdb853d17884fb04396dc10d34bc84d594343ceadda564fcdfa9b4d47dd4e3b", + "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", + "sha3_256_hash_of_ciphertext": "a94ff1a0c62792c0e1dbe578210ba5a7f3cf8a9f9763a16362d66a3082e4753e", + "shared_secret": "99b58031465868d0617fa795e6be1c33a870a1e154a85a2bf61346f7c55f3b76" + }, + { + "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "sha3_256_hash_of_public_key": "ef7ef8d7d81aa907fece4c1920c7ca9dda3bb9d57f09193487bb89d6422f10cb", + "sha3_256_hash_of_secret_key": "2bef3558b547044290d1232a580a6a473cfcd8d87ced6305f996d4db4f46e6af", + "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", + "sha3_256_hash_of_ciphertext": "0b60d83d562b66153e07bffb5bb05b7d268351377381b04f1e59201f961f1907", + "shared_secret": "387705c2ed600492a0b06f5587ae3c40be55e6d5592597e57cb8015de9e9271b" + }, + { + "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "sha3_256_hash_of_public_key": "99b151aa6b4654589afc36b8343fcbdc09a3e5255b378d6ee5629cd8b3cfd555", + "sha3_256_hash_of_secret_key": "b7a7d95034017d523ae23e29fc400e9a0b320f9778ba1587b69dd012f2aa47bd", + "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", + "sha3_256_hash_of_ciphertext": "3a4ba04bec2aee99c5e4e2459f1aec52fc950ab67b61570d57a17c4f3d9031d5", + "shared_secret": "2a426534e3c23e28a237047aec83d24abcef8c7f77d85d8b27aedd7c50263010" + }, + { + "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "sha3_256_hash_of_public_key": "339ba63f705606d8c7fbbd6e66dadbf23f532d5423802c836f2105a636e9e6da", + "sha3_256_hash_of_secret_key": "60aa684e7cbf79e9c70504608a4c0f2cf8dc207f71b1d0ef5e3a99013ee866cc", + "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", + "sha3_256_hash_of_ciphertext": "f5d1973f7c10d3ff7cdb66195ce52e182f40ce5b9f16ef67e31ce8632cf617e8", + "shared_secret": "ffaf18d4fdb39a4aedc80c7985843f6b87a02e36c69dcb00f3cb01a619a77779" + }, + { + "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "sha3_256_hash_of_public_key": "1f9e26333b637ef9beb8881c63f9412b07c47a276af0e242062a54026bcee2bd", + "sha3_256_hash_of_secret_key": "f7f38ae2caba6d7e87b7bee8b127a9aecbc0b795345952d65bb4435e3720f89d", + "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", + "sha3_256_hash_of_ciphertext": "c42f9beac87086ca603d95377c5e539735752eee043653fbacef0d2824b91d86", + "shared_secret": "1b37c256820ae408a0005a1fe7461d54e53813e6e7ad58ca3dde46a53a44590c" + }, + { + "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "sha3_256_hash_of_public_key": "64b9f8198bab9b3b2f2a1704cd4ddf6b3cbc216ddc0f062a72ef40115917fd21", + "sha3_256_hash_of_secret_key": "a3cf5841bedd9be95061b910333190834063e5cbcf0fd32673f8cf3f6b548d17", + "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", + "sha3_256_hash_of_ciphertext": "056998cb46e48667cb4bda6dfcff9321219b13fb1a682e90bfba6ca025bbe6df", + "shared_secret": "12871c83c35db351c2c0b4afe0f0ce9fe1f21fdfbe8c18a485d5c1292faa531c" + }, + { + "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "sha3_256_hash_of_public_key": "de4ce515b882c849717a1ab34f2ac0238c868f415630c1155bcfb302d346dc91", + "sha3_256_hash_of_secret_key": "4b917d9daddcdc932fe0448063a24a592edbb0e6e40b5b53812f20a4cff7a0a3", + "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", + "sha3_256_hash_of_ciphertext": "e4eec4f31749692984bee94c59e2947afc769197fc18b20d2e34ec92e7d15ae1", + "shared_secret": "adf49431dcdeb29f729459cbf3c2b94151005c7b841eac921a71262d65dcff99" + }, + { + "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "sha3_256_hash_of_public_key": "93b60f0d00c09af885b5a0cbe942fde6afc4841428104710823bdcc12319eb35", + "sha3_256_hash_of_secret_key": "953ab28bf8cf18e86b8c80efae0bb47582d720e787fd2af27d9789c1ffb7ea1c", + "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", + "sha3_256_hash_of_ciphertext": "ed5b2ff1ee4222029e7c0d858da6ff1a1417a74a501b80d1b5b6a4941329e892", + "shared_secret": "35e1521271e7ab9931b2c25d75f0f09a89b3f83a6bb62ceb99e8e00c5cf78afb" + }, + { + "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "sha3_256_hash_of_public_key": "167a2fec4d72cac2ffd844246eebabdac0c074e4f984433744e31d299faa389c", + "sha3_256_hash_of_secret_key": "9afc4ddea68ca10e36d9b12d3c34595912eaafed49d8ffce01cbed09501f7527", + "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", + "sha3_256_hash_of_ciphertext": "a076b58fa98a7282c2cedc1e93c1473dd15b15c1ecef192955d8a813180b3217", + "shared_secret": "715519f07b29bbecfc0776e35417558e3bc50c76b8da6fd4c99391b7bc7873cf" + }, + { + "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "sha3_256_hash_of_public_key": "955468734662471c953fa516b35b3a53053ff396b7e2798fe07a2ecd549d6c06", + "sha3_256_hash_of_secret_key": "8bbc886fcb7516e7888880921abfaa72823ace9d50cf0afc2f68c4a7c3dd2e53", + "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", + "sha3_256_hash_of_ciphertext": "87914dbce6a365f7335188d83f2394b0fdafc9b0676c022608401cd93d294f36", + "shared_secret": "5a4ba3737140bf227c0e618f74191b3de1c1b8e24b032036942de66a13ef5a91" + }, + { + "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "sha3_256_hash_of_public_key": "f7310c0531060051469ffcd2f88e3200bec6c721bca1fa4c9e7bf1773d7ccb19", + "sha3_256_hash_of_secret_key": "16c976495bbd05ee6715f30a9323aa41ecc320e2e63479148ab3a51132afd7b5", + "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", + "sha3_256_hash_of_ciphertext": "37ff2acef57d0665358cc5ec7f489160d602d41c21cbb3332670f3cf0044fc39", + "shared_secret": "87528a4a961de06d5856004eba20a44590a1bd88318fcd1ae1dbfbfd41f152b0" + }, + { + "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "sha3_256_hash_of_public_key": "152c13a9a4dfbade0f98e8a5136358f69c93f0722addc008952cf72e1bf350b1", + "sha3_256_hash_of_secret_key": "b93c3fb9dbddaa560dd52c6a1c37f6aeb2111e46b7b746419e3c27fa43a27211", + "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", + "sha3_256_hash_of_ciphertext": "b62ee0b20daf3a87406f7f8428d6dac79ad5f95c225956a564f896658ed51eee", + "shared_secret": "3652a13e36459a324958a2c45328fe4ca6163ba833400e643b0a6e51bbc594fe" + }, + { + "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "sha3_256_hash_of_public_key": "97e5b18cff525ef46fd8a6aa6e5e4b8d953fe1e67b5771d1b99ff18e754553be", + "sha3_256_hash_of_secret_key": "55102f3a620209b46e41531919a1b6f091c86bbcc5bdcb52b18f9a070680bd66", + "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", + "sha3_256_hash_of_ciphertext": "6d20fbb0cf418e91e295f391160df696348b3fa99542d12584c0da554b96153d", + "shared_secret": "c07d965e4a87e89e9fd5db44cdf225b20157a6842e2862ecb4f72d8aac933c2b" + }, + { + "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "sha3_256_hash_of_public_key": "7b5c67fa6e0ff374f691540fff0b4d14d4ed8a8a8c48b14b2a35facb413a5ee6", + "sha3_256_hash_of_secret_key": "449e7b1644520512fa25ea48f468ce9f866ea08178e814f11561efd4e4aad792", + "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", + "sha3_256_hash_of_ciphertext": "e4f728484e23e99dcd35c5d3ca6d62e3a829e60a784faec5dd9fbb2d0cfa8bd7", + "shared_secret": "a502041eee317af1e9e6f9a9c12cc98415b358ff179d4d64ba5b7463a1f33b0d" + }, + { + "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "sha3_256_hash_of_public_key": "8e49b73bae3b0285bbe1676eb6fad2641e7354e4c0a4feb0b74bb16708b01351", + "sha3_256_hash_of_secret_key": "23a598fad0141bdf07257c662d22549343a01d75eea9c1ebcdeb4a138c6e215c", + "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", + "sha3_256_hash_of_ciphertext": "cb2c217f6ad9c504c9fec4750db44d2c339017542da415ad81094290006e9273", + "shared_secret": "a354e870cd600e5a5951aad3491c31a80b0545c1662f830d7f0b6d144ed3733b" + }, + { + "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "sha3_256_hash_of_public_key": "f5de62d662f480d4ed8ba235b4aaa4bfff19edebbbfbd96e5a9b7c4e89365c3e", + "sha3_256_hash_of_secret_key": "583ad55aa14bd6a4310d3ab7aa619cf59c93906251f5721a0bf880a866517f70", + "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", + "sha3_256_hash_of_ciphertext": "a9f97b3e253dcb15c8ef4c5576786d967e504e8f76c0bf46e051b8f123fce22d", + "shared_secret": "cd98ddb938549cc7c4fe56cda7f3ef213f1aea49fed4fb81b940c7e894be1e54" + }, + { + "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "sha3_256_hash_of_public_key": "ec2fc5834e128c5e1460d8cb0c35ab340d706a6c8b52070a7e41a6405fada53f", + "sha3_256_hash_of_secret_key": "954a43f78ef0b5a279c0d020c08d930cc5e83a385c09afed508f9ef6f1a27920", + "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", + "sha3_256_hash_of_ciphertext": "f137abde6208e2c014a5a7eb1aac7b910a21df3a7dff68dcc40cba4f34b839d1", + "shared_secret": "e0d0d574b1287716bd7e0a44feea36ec28469bd36713fa8a53b0a104f322016f" + }, + { + "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "sha3_256_hash_of_public_key": "5e7f49b87bb2319dba8d3485fe814aedb0b43173bc48f3a793554c3e8bf90c17", + "sha3_256_hash_of_secret_key": "74eb7c05fedc78406453b8f021f8a71cce4b3ad0c4d38bc8d581000a38908574", + "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", + "sha3_256_hash_of_ciphertext": "2018b7eddcf255f6a171af914ef44153fd60976c5c7368998a218b1d81e34e33", + "shared_secret": "bd97eac1e35a06536e713a2ca5e71e35277b948172cafef0c35e1558efb61676" + }, + { + "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "sha3_256_hash_of_public_key": "e3f73c56254fac37209f5a59818fbaabf5abff3320b0b3ee00e20679b5728c12", + "sha3_256_hash_of_secret_key": "1e1cff1c4e09318bdc174bff8ef0817d6e7414355adf930bb35e71a7a0b95abf", + "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", + "sha3_256_hash_of_ciphertext": "d641fde487a3659350dc41f329e0d41741bd4389346da9270eda4f5829ce9ee3", + "shared_secret": "2ed540764a77b17c6b9608bf86d8d8703f80718044d52dc79cbc1838f91fdd7a" + }, + { + "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "sha3_256_hash_of_public_key": "bc0a40ba03d27bbbfb91654fdcfab2dfb3e94d9607b99c1d7da1f2663bfa2598", + "sha3_256_hash_of_secret_key": "dd55c195b92ff410b9ea37577ddba0385bbf067b3053b0a678e8106c07b98c9e", + "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", + "sha3_256_hash_of_ciphertext": "7387b045cefcf3d2c659171ee41acf3857b9f63f1ba20c3f0832cfe41a26ef75", + "shared_secret": "1e5ba1b64fa8ad0494c96ba27e288ee2b479c24634285f8919e58e9b9c8be78b" + }, + { + "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "sha3_256_hash_of_public_key": "e16da7f99bb7bceb75a6468a921ab9fe53aab2972ca616ee10697c204df1e350", + "sha3_256_hash_of_secret_key": "2db70f5bb4e8927fd7696a4d802817fa58c43f9b2618ed27c7584cce8acf3506", + "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", + "sha3_256_hash_of_ciphertext": "0159f5e60336eec1fda83aeffbee92eddfcac6f92b0fef7a4a38fb20d1a771ca", + "shared_secret": "96ba12c7f8a0d864ce1434b789c09753c2d1f7ade6a5a0e679ce2ea0b6d66c83" + }, + { + "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "sha3_256_hash_of_public_key": "fb80edf4f67823ff4e53a8963a9c9937fa9f8e014b750e11b4c4bb1a361d6484", + "sha3_256_hash_of_secret_key": "fe67beff69ea75d4953d71c038559591b2a0349ddcdfeaf7596dcd02f57db2b9", + "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", + "sha3_256_hash_of_ciphertext": "6e68fe27fe416c12819fa8a48eb29351d1d74a9200c408b55294ea374046c3d3", + "shared_secret": "07dfc04ebbb7ae537b594210a9180f647d3d385d1c1bb56abb8174111eb246df" + }, + { + "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "sha3_256_hash_of_public_key": "d9f630c3838eb161374710d9f01bc70d4ef928fcb1c38bed93e30f3633a05e01", + "sha3_256_hash_of_secret_key": "ca4a4ab954c3a4c8b960fdfb7dd7cf5e8d103f7936f31e720e5043010926829f", + "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", + "sha3_256_hash_of_ciphertext": "3b6a1f5d06cd55c98ce6f4dc5b17fce8cb05b33b1d89b618a027e4478d8b5e69", + "shared_secret": "81fdb9267988ad39ab57e2fc8d4c280e0000dac3471b0936083aec68b49fd92b" + }, + { + "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "sha3_256_hash_of_public_key": "5c27fa929adc826f98fbf0a7fdce33c8f215b34e70450da0767240741894ffa4", + "sha3_256_hash_of_secret_key": "0116eb35f3138aa7371a058661a92a4bde258f823747b70ad40767c27d7bc7f4", + "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", + "sha3_256_hash_of_ciphertext": "83f17a1e23402e14a58a32343e1083434eb10b90a8080d01ba112b83ba15f7f4", + "shared_secret": "703958ce09d7d6a5bb09e88de8df95c8ee2598544d50193be50534947530fa37" + }, + { + "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "sha3_256_hash_of_public_key": "dd8aa653122eb5e3a4c3c877e95e8ecfcfef1ac9e0e6af92cce8ee89d09188fa", + "sha3_256_hash_of_secret_key": "8a5fbb715cf44c86b736227e56b53d91ebbea432fb1f1d6d7cafe42da8457b2c", + "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", + "sha3_256_hash_of_ciphertext": "862f660f11fb4252070e948ea2c141202246d5117ec151e6d5fcd0783bd76bb9", + "shared_secret": "c86d221cbc5ff6a994d9111acbfff23f7dc0cd934412b17d89f0f27e3cbd1a15" + }, + { + "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "sha3_256_hash_of_public_key": "b7c80e434104e9838cb08529592a5f81b0e8ead186663db8facc569b09e75c9a", + "sha3_256_hash_of_secret_key": "c5f84c36f3b8af4b4d90a040d929b116b402840f487d437f9b330f6ff3ec36fc", + "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", + "sha3_256_hash_of_ciphertext": "a372aefe804077da915a423dad55b76ff08a58d222aa66305599ff301128ae13", + "shared_secret": "c0146ba47b3d4178919879721f69ac896d6911d6e86de1e8f05797d467053222" + }, + { + "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "sha3_256_hash_of_public_key": "e619285c692532735f1582d227b9a9e77b1eae4aab9eaa79f6ce7ac2fcac8318", + "sha3_256_hash_of_secret_key": "2d4ae4f98c61bd104fbc1ef512b946202f95ecaa0ad7353a686141be5fe18116", + "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", + "sha3_256_hash_of_ciphertext": "462b78ef50b2c1ce761fa7750ab5ed2a7315e474a92ddae74bd23013b0d9ad0a", + "shared_secret": "a33f72941e0947735925e5be668b3481e0cece75ef48ae6db0d66f0fb2ec428e" + }, + { + "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "sha3_256_hash_of_public_key": "dd3761c0e96678a959f30997e96d6a59858528c5e10234398e2da2e50ffcc517", + "sha3_256_hash_of_secret_key": "c6f5f9285f93d2ee6d180353799df5fea713870ca06de901e9c12e8a01ead6b6", + "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", + "sha3_256_hash_of_ciphertext": "2e552ce25fe0771bfa135939d85bd68ed07959709da470df50be36aa8ab2890d", + "shared_secret": "3d77b9b4ade74443fc573c393b82c0cfd2bc2769327f273c14e66eab9f8d9ebc" + }, + { + "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "sha3_256_hash_of_public_key": "6d9e513a7cd137583507ad7256844bcb9775ca82ef5f411331a7c37ce451181f", + "sha3_256_hash_of_secret_key": "1dd2623a7413ff14549690b642fe90ce16ebe7acea38be795a4936b8d86b93aa", + "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", + "sha3_256_hash_of_ciphertext": "b4c64b73ba056f9ee7c3587ba0825bcc7172a6da749cdd86c1ef60cf84515883", + "shared_secret": "812d6c4becfdd4a95f234e8fcae1d9b316266d1c519545bbb7fab8a19f3519e0" + }, + { + "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "sha3_256_hash_of_public_key": "b252e5abf757e116a92518eb72df9f9ce66b07edf4d31be225585a6a827a35b8", + "sha3_256_hash_of_secret_key": "45ac74f2a699f1e3559e2d1442638290029688cec3da96c58ea697e1ed1d4178", + "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", + "sha3_256_hash_of_ciphertext": "4dae8b2d08afb311ef727118966c6c17652f1464e6cdd26ac23551d31b013415", + "shared_secret": "c8757f45a1e334ad99a0d2adf12e79ef2bcb96ea1876bc29a4ec5cd660923d82" + }, + { + "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "sha3_256_hash_of_public_key": "18c081231277f424c5f3f1f6b4db91958611fa28bcf09ccb2573da64547e1958", + "sha3_256_hash_of_secret_key": "f32167b39e19dbc0db58a5eb79e735337ffe154c75b0f2c091e009d0cec366d2", + "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", + "sha3_256_hash_of_ciphertext": "3a246e10c7c20d77a9e4bd6d3a90d73ae456501dc989210c798293d0b449852c", + "shared_secret": "be765dc236062da9d3fef68c645b9a8a5494c351d37790c1e7cd1089d97971b3" + }, + { + "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "sha3_256_hash_of_public_key": "0ac7db13184d6ae6e21a14a63a2ab3d6d5d1ee7f4a6011413a0295b752fd2c28", + "sha3_256_hash_of_secret_key": "f69bacdf5992e64369aa4325b70af9f0e8a399cadafe48d854c288cc4eec627e", + "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", + "sha3_256_hash_of_ciphertext": "d4200c5ed5cb4e30e8e74a5c8c30eacd48014d326ae72f73618c5680f04999d8", + "shared_secret": "e72888e8dc5fe30f0a9c01e2e4599a7046147a81da280c393a48bee1b43bbb5b" + }, + { + "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "sha3_256_hash_of_public_key": "27ea5a76294070ab10a6edc502d82be3d240672e5fa61377e73e5e19d11f64a3", + "sha3_256_hash_of_secret_key": "33161a2b269ff022ff4699b05ac7fac1374d733e46800447164d3e528ff89dc4", + "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", + "sha3_256_hash_of_ciphertext": "8995a8a9b59bd5adbe1fa10cc20da5348737cce9088be7eb0ba1f6215d68b9a9", + "shared_secret": "e3f13c77fa9eb329c218e1bd5823d6e07249fa1b455770ae57b2a00aa8c69c5d" + }, + { + "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "sha3_256_hash_of_public_key": "9898462f05bea461adb40faacdfdde363c06f58bc756f0a8417df63a66d3a544", + "sha3_256_hash_of_secret_key": "e10192b72796b2da465303c0bbe16f1e23e08f9680ba92fc22d568ac84352113", + "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", + "sha3_256_hash_of_ciphertext": "573aa757ef6fa5110ba7b948c325718f87c6bc9ccd596debff4e6c7dac1fa8f5", + "shared_secret": "a8498502e012b5cd006e77fcbb9fab801dc3748a0da37587dcd41310fa945e09" + }, + { + "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "sha3_256_hash_of_public_key": "a24e6203d9b1aa5cd06c44f048da7225e33952617f12b4289494b3969857c2ff", + "sha3_256_hash_of_secret_key": "61f1e3b3a9ce59d25480d88dac106cebc81272c0c9449c9b22048f67419d940a", + "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", + "sha3_256_hash_of_ciphertext": "7f92312ab16635c5e90a6d41ac65e594e37754359331b0814e09da9c7eb945e7", + "shared_secret": "780b2d0ea585a6ea41dcf43197b9ca4648454e30a3057f0d47f6e79a2bbc365e" + }, + { + "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "sha3_256_hash_of_public_key": "cb2e9159ab5225a75d02268af2dac89a0afb33fe83a45f552e2bf542868c0683", + "sha3_256_hash_of_secret_key": "d2ce7cdfbe3ac715b2c87b1231fe46d5385a77caab367570a955bb562d23183c", + "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", + "sha3_256_hash_of_ciphertext": "1113b9a38ec4629ad20ecb594b64ba242a5a4db7bdf32914f9eb34ecc76c4a1c", + "shared_secret": "7832b351d71984cb60e6e548e5b4edeedf9749f8b3bc96fd208b6bb557251de8" + }, + { + "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "sha3_256_hash_of_public_key": "7f8d36076b3a8aa13b633650726f7e907806a0573402ef3af129f611def1a813", + "sha3_256_hash_of_secret_key": "0b38e04daf35259696487ffaad947f481756bc3e94dd1a73b81bf8a6da4a43c3", + "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", + "sha3_256_hash_of_ciphertext": "eefa4d255cbd39fb5686d14a6a574d4c75c6b138a45a09cec12287c281cc00e8", + "shared_secret": "468ee020867cb766cd0a9ce1bfe9e7dbb56ae66c131a4540f211837c1779e11f" + }, + { + "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "sha3_256_hash_of_public_key": "ff2044ee6a3bfd4f7033dc4bbd6283b534cd3fbbf1c4af072fea1ba37d3262d5", + "sha3_256_hash_of_secret_key": "ed62dbd78c007d385c786f2607715a69a44804c4e88111861d175875bc0b09ee", + "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", + "sha3_256_hash_of_ciphertext": "d16b23897beae9fb1a6ca746d3c15ef52c8ac454cd518d5a90a561cb588a0260", + "shared_secret": "f04a17a3737285f2257a6374a0057776ea24bd731724851d12ac2e06e959fa26" + }, + { + "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "sha3_256_hash_of_public_key": "c7ca6ebbe17f30f8ce49e15c40c1ea5456f43624148eaecc9f3018f7beb96bdf", + "sha3_256_hash_of_secret_key": "7886dadfd208ab926afd2376dc11a004d8b793d7a30623df27109f9a4d4b0916", + "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", + "sha3_256_hash_of_ciphertext": "4fdbbb522c23abd8a69c583c2c68ddc28fa4da85a6bf208a22d19e7ef40d98b3", + "shared_secret": "fcfab6cb3daf0c64b4ce007499f097f6421e00905fd4daca7da7a29b9c8f6325" + }, + { + "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "sha3_256_hash_of_public_key": "61fb6cfc0f388e34fb28ed783c2733453005eea03d3fee4b01bb6364abc01c30", + "sha3_256_hash_of_secret_key": "b724f25cf64bdaab1cd29c9cd1f8ee6cf4104c26fa3caf53b77d61cb5c35222e", + "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", + "sha3_256_hash_of_ciphertext": "5ce7558ab39d932fd35fc346aaea5aff4bc90e65c17b5760996e84687dcb5402", + "shared_secret": "dbf4cd1f5cddf15322449ddfe147ae0605d0315ff9da6421069b47c3a67a65c4" + }, + { + "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "sha3_256_hash_of_public_key": "9333445958cf50f9cfba453f058f562158bc253e535e4e2f07715531a1c6289e", + "sha3_256_hash_of_secret_key": "9bb80f6928e0d09847b4c7e77ba6bf2cd0f75bdd147e884b92d3c3f2e9d839d6", + "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", + "sha3_256_hash_of_ciphertext": "57651b24ece777c321c6e59ba774951e2a3c4720d370e3af928238ff60c9565d", + "shared_secret": "3f4848a2de1cdd8a0403da22f609809a20c2cfc0ae619be0cac350897fead710" + }, + { + "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "sha3_256_hash_of_public_key": "ee6cb12a54341aeedc99f1040b01603c35f07c5487ffac7b4fc1925f49026916", + "sha3_256_hash_of_secret_key": "4e498a0606b1f9cd72b9d2493428730712bdaa4a7fed8099b15d9e2873bbdf7e", + "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", + "sha3_256_hash_of_ciphertext": "1fb55bc4e6d95931087b23945ce9448207fbbc14bd284f6bcda65fcf31d68fdc", + "shared_secret": "eed5b71764da1763a01184a1eb51dedb4eaa9dae7890b1c7dbc7e7132c30e737" + }, + { + "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "sha3_256_hash_of_public_key": "42ad42d6d3b13c72b16287909bc4c0da04900536a1e48a1a28db4f5ee2d2e771", + "sha3_256_hash_of_secret_key": "d6f909b6679487a8718c843c4b894785ee046c4d86ad2794c22ee912113dad1f", + "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", + "sha3_256_hash_of_ciphertext": "54043d4b2be7ecb264847dd0bcde9076523e798aeee942be82d61d51ef0253c1", + "shared_secret": "4218fc9abb402e67ac946c7a7c6f9029108f67de469e1a9987d570f011b685c3" + }, + { + "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "sha3_256_hash_of_public_key": "5b70c5bb1b7af3b643588aa7c20567d4259dbe6abd7617a61b48185de8f21e1c", + "sha3_256_hash_of_secret_key": "f03297b8577b131e39946a288f7ca9070e70c1e00e6ff126543556f60dbafead", + "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", + "sha3_256_hash_of_ciphertext": "c3d51c14b28feb48ee67945a2f9e2ababb8682a839ca1148ddc99f909e8c0bc1", + "shared_secret": "95a33968866dadc1fd8748768a99f6bb444e3d76a65ec5fee0c8a833978d4585" + }, + { + "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "sha3_256_hash_of_public_key": "01782fce09e644e310c9286f1e381be9ea8c54a1804e61f2958c1f975aec185a", + "sha3_256_hash_of_secret_key": "3d1b220e747de4ca99a9882a00860ed00abcf2e6eea60cba5194977f97c87770", + "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", + "sha3_256_hash_of_ciphertext": "8dbc778809c9cb1de5301be5bce766f1acd7d8f74ecf30619c398250def57d74", + "shared_secret": "c9423277519ab439fca3f5fab4c29c8123a55eaf37d94d70e27afffeec1b3b9b" + } +] \ No newline at end of file diff --git a/libcrux-kem/tests/kats/nistkats_768.json b/libcrux-kem/tests/kats/nistkats_768.json new file mode 100644 index 000000000..7b668915c --- /dev/null +++ b/libcrux-kem/tests/kats/nistkats_768.json @@ -0,0 +1,802 @@ +[ + { + "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "sha3_256_hash_of_public_key": "d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee86", + "sha3_256_hash_of_secret_key": "245bc1d8cdd4893e4c471e8fccfa7019df0fd10f2d5375f36b4af5f4222aca6a", + "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", + "sha3_256_hash_of_ciphertext": "bb62281b4aacc5a90a5ccdc5cd3dbe3867c502e8e6ec963ab329a9da0a20a75a", + "shared_secret": "729fa06ac93c5efdfbf1272a96cef167a393947ab7dc2d11ed7de8ac3c947fa8" + }, + { + "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "sha3_256_hash_of_public_key": "2cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c", + "sha3_256_hash_of_secret_key": "0a84cc895da138b944accbef3ff1a0004b8a0d8af5d426d2b82ea4c0e585cc6a", + "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", + "sha3_256_hash_of_ciphertext": "c15158a536d89bf3bafaea44cd442827a82f6eb772849015f3fec68a29d589dc", + "shared_secret": "c00e4ede0a4fa212980e6736686bf73585a0adf8d38fec212c860a0d3d055d1c" + }, + { + "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "sha3_256_hash_of_public_key": "3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8", + "sha3_256_hash_of_secret_key": "0ffced333b5d13fff22b81e66d57b6e2a6dba0285fe2a82d5537df51a8d3eac3", + "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", + "sha3_256_hash_of_ciphertext": "aec80e6fe21e2616352b4c148f9fa0e30986541fb0969df7873b1336b23a8de0", + "shared_secret": "8f50401bc9b1f857fd870902d4065f6cec8cb825db3eb22573c6167442b6e19b" + }, + { + "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "sha3_256_hash_of_public_key": "94391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4c", + "sha3_256_hash_of_secret_key": "e3904266e186b34a397014c95f6d314cd6e1c813348b02e977d0fd21d9bb681b", + "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", + "sha3_256_hash_of_ciphertext": "39fa8e1d0a5e4bb987618734ee4903771886030b2d8bea4b5a9b0cb672ebb279", + "shared_secret": "3221d7b046caccbded38e369625f69bac60c2d7efacad8f24170b10c5d222830" + }, + { + "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "sha3_256_hash_of_public_key": "c5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082", + "sha3_256_hash_of_secret_key": "b3fa7958f4b7ccb68712ae948c3f08740c8b89a69e53ad4e9959234e6869d8fe", + "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", + "sha3_256_hash_of_ciphertext": "ca9f95c38dc95f51b6b62ec709539f0d1e9fa64e49ce4ad10bbe62868f35cfc5", + "shared_secret": "1d746afc4160c75aaa6c6967f4eee941e09546a039027f05f0f8a483710ac334" + }, + { + "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "sha3_256_hash_of_public_key": "62e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1", + "sha3_256_hash_of_secret_key": "1a3249c268754c86d2e02ba9d87c2b60b220bf2406b71037cfaf6b089477ffb4", + "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", + "sha3_256_hash_of_ciphertext": "ec7bb1327a69aeaf626a76d344be1156eac160262128a64477a194805b926233", + "shared_secret": "722fccef7142c46f74eb57a10b13e420d6554e9d18507f660bd1be96d3cebbcc" + }, + { + "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "sha3_256_hash_of_public_key": "0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c2", + "sha3_256_hash_of_secret_key": "fd6b5d3f120ca009871ca24552a6118917ea882f12f30dc8097f6614d9d36080", + "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", + "sha3_256_hash_of_ciphertext": "da36cb6137a777acb4afbc0932811f75ef1d6732031309ae7e2de1543aaf5c2c", + "shared_secret": "ee7c5fb6a63ace944e1eae1bd4b182263d918754c33753b904853551b2b46cb8" + }, + { + "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "sha3_256_hash_of_public_key": "2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe", + "sha3_256_hash_of_secret_key": "27dbbc7918c31e9ab57808f439c4f4189cc318a62422457f4fed733be959c816", + "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", + "sha3_256_hash_of_ciphertext": "85efbfd0b096fa921711ea66b17bcf7c9a6240711b38a88830dbd9d716f07195", + "shared_secret": "77cfbdae47854e9e10765cf397eca9ab2bf2b7522817152b22e18b6e09795016" + }, + { + "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "sha3_256_hash_of_public_key": "53b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757", + "sha3_256_hash_of_secret_key": "f4b964b7ab3e09fdf3d91527da06a4d29ef28344709a41739ef56f18bd5b984b", + "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", + "sha3_256_hash_of_ciphertext": "379a57a8f19110d5e0d747a2c184877d71f00fea95cd815b4c0e8782b12bec6f", + "shared_secret": "8be7a417efbdd3587c6f82ddd1d29956789d28c2413b8383590c5b80cc53e04a" + }, + { + "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "sha3_256_hash_of_public_key": "9cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb63", + "sha3_256_hash_of_secret_key": "a2e37a55c9b80fb423f40585180b011f32402d0320259285b6e278df6c20ba60", + "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", + "sha3_256_hash_of_ciphertext": "44053f01ecb88811b9ee7a9ddd4234f94507c7cf64b6803b28c54bc605ec4e31", + "shared_secret": "79fcd201101e7e277c1b6cdc4475d63ea1dbc42ab94cf873bf0163c2aab0b5ff" + }, + { + "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "sha3_256_hash_of_public_key": "9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f", + "sha3_256_hash_of_secret_key": "837eb6ce037f235273d7686fd9d01bea14026e0a0f5f943884f18409cc4bc70a", + "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", + "sha3_256_hash_of_ciphertext": "02798b5af1a76a2b478ee05c630e62618e5e2d7ee0c411a82ed2bf888706fe28", + "shared_secret": "6c4484b6d7b0a376f52abb1811c712368a9f34bd108ffe7ca31c36a6ec8140f3" + }, + { + "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "sha3_256_hash_of_public_key": "241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401", + "sha3_256_hash_of_secret_key": "95c79c2a867b3e8a4e4e545ff626cd49893b8e87eb188ed1516b159a24736c97", + "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", + "sha3_256_hash_of_ciphertext": "cf3b2e2dc822949eb13638299fc2d5102c7132aa6cd54dd7834b13f05a4dece2", + "shared_secret": "8554d6af350f13471cfd45c23882e43dc81d8a094f6299e2ad33ef4c01a32058" + }, + { + "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "sha3_256_hash_of_public_key": "6ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e4685", + "sha3_256_hash_of_secret_key": "1ef733faa4f2cb53cb5d8975aa6797b5f37fd918aeda02178a40584475cdf667", + "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", + "sha3_256_hash_of_ciphertext": "1706e6983032950b47cb6c8586178b42d515ce929c1434c1a8c9e36d8b4db7a3", + "shared_secret": "f9646f73de3d93d8e5dc5beeaa65a30d8f3a1f8d6392190ee66ff28693fbadfa" + }, + { + "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "sha3_256_hash_of_public_key": "9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a58", + "sha3_256_hash_of_secret_key": "0bcfa8078582f60e218047d0016437601da8431f34ae6da12921f53958f32819", + "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", + "sha3_256_hash_of_ciphertext": "f9341d26e39b38a88ddef1708c96ee2068f569a59a4010745730d8290d637718", + "shared_secret": "1ee252e97b69445f7f109187645cd2879f55e10eb8361ab43b3492ff51f01815" + }, + { + "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "sha3_256_hash_of_public_key": "cfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75a", + "sha3_256_hash_of_secret_key": "09b118f7c4d059baf27284d127d4e85d55b84e4c92bf3127eeb318d2f5765401", + "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", + "sha3_256_hash_of_ciphertext": "94a8c287238191a107e74e31ec099086d83f198e6b0f3321da4d8f46ce01a0b2", + "shared_secret": "1e1ea5d6a18873c5c7fc8da79093f6d3db5b28fdd0aaa42726ad130c78e9bb88" + }, + { + "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "sha3_256_hash_of_public_key": "a19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2ae", + "sha3_256_hash_of_secret_key": "f1c00070780a7a2ac5b57ff3ff765ca75278bb661d1635cac92792f9454fe8ba", + "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", + "sha3_256_hash_of_ciphertext": "56e0b8ab3b302fae682938a45d9931e092d78877d1f8834bb43cd5c85582a205", + "shared_secret": "24619bb17c912fc992bd8272969cd5b6fd6b030122ee5af9365cac8b38e569fc" + }, + { + "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "sha3_256_hash_of_public_key": "e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872", + "sha3_256_hash_of_secret_key": "f3f3a292f5cf01d6f7266461c9e8cd44bfc8f17e16035ab8d10af8177f389b86", + "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", + "sha3_256_hash_of_ciphertext": "5f878ca21c8c27ae9c41c43aaf1f3a2af62c73296e165c08b88c5b22592867be", + "shared_secret": "a990af801ddcf2009c82fe657fe3f068bae7e6bfc661e3e588354ba7d1b176e6" + }, + { + "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "sha3_256_hash_of_public_key": "2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f4", + "sha3_256_hash_of_secret_key": "7334d4a1755e1e639b3e9eadb5996cd910b55d1de5790469f229231d3bfb1528", + "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", + "sha3_256_hash_of_ciphertext": "c2079637916c089b2afb9d6e9c6fa51308ab7720d5c2fca484c34ce614a14fc0", + "shared_secret": "11a2ceaa0c77f0602c4b2be3499e6df6b0339d9de90d04b2b12829f4758afaa5" + }, + { + "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "sha3_256_hash_of_public_key": "631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f", + "sha3_256_hash_of_secret_key": "3d4d2c680a1e6aa83861ad95043ded260e720ae80060320feffa309b4281ba3d", + "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", + "sha3_256_hash_of_ciphertext": "2e9d6551050e32e204d7c062a4c18b8abdb91346e9f2c2708776827e0be4c514", + "shared_secret": "7571990ef1ef7e15cc920318fb75fd38c4ceb9abf7a4b1adc2175f99d1a0a275" + }, + { + "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "sha3_256_hash_of_public_key": "87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce", + "sha3_256_hash_of_secret_key": "9aa6c0546cf02085e2b3af65a7d7fd32d0f6d8080e1e7fbff6c39bcf3086ece4", + "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", + "sha3_256_hash_of_ciphertext": "14da42e207477f4383faf4004e58675f0380e7d621421b3c36b877acf3a45d5a", + "shared_secret": "27ba4cb50ae44cd938585e0a4905d76053dd851e5b6af4fd787446079aa5a4ab" + }, + { + "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "sha3_256_hash_of_public_key": "699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f619", + "sha3_256_hash_of_secret_key": "421f16805b1ceffcd64128b1296521ef812d3a8f4c5e3875a049f8de456b021a", + "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", + "sha3_256_hash_of_ciphertext": "b2485ef56c39d468193e387e72794e0ddc9b5404c1a6d90c3b94a5f3e13ba7b4", + "shared_secret": "d17b2738213a98f29ee46747c93308ee7000fa404b9a0c1acf3f89654ca2446e" + }, + { + "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "sha3_256_hash_of_public_key": "d3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7", + "sha3_256_hash_of_secret_key": "7b546a42ffe6b65cd9c5b8857c2518f4f8e0bf835c894a68d1743691fc9aad9d", + "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", + "sha3_256_hash_of_ciphertext": "8290f3c4bec7c3b93f3d26e0be3b3fbfdd9c3f5806188fcf0fa1339133f29c7d", + "shared_secret": "954af53b4add522514b34cd2ab96669a76ca13f82aa2fd70826bc8ee790ccefb" + }, + { + "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "sha3_256_hash_of_public_key": "e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a", + "sha3_256_hash_of_secret_key": "5fac243c82807d7357a61023226a7c270525d96932162ca5c09fc8f7b9ec6cb3", + "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", + "sha3_256_hash_of_ciphertext": "f1b10c800a42ae606c72eaad76accf059cccc02299fbd78a5d091f183f6c3f0e", + "shared_secret": "d0bbc576fb1aa43b6e76db0e87bc4ee3fa057c31642b37f3339217a1b041b521" + }, + { + "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "sha3_256_hash_of_public_key": "c74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fa", + "sha3_256_hash_of_secret_key": "5c6998a20960109a4c9808f8f8575697b2b8d18c44c7e9dff97585ae43e6004c", + "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", + "sha3_256_hash_of_ciphertext": "e9ef0852ee47744b8c3e12cd728d9017465014eef51edf83a4502cb5218cee20", + "shared_secret": "91fbc37d4749ec6175c12f0d8eb6b6a8621e693c79f85f5cd2f557cafec5e7e9" + }, + { + "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "sha3_256_hash_of_public_key": "7378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0", + "sha3_256_hash_of_secret_key": "30bd5f16c3f242248a4c4cddc43508bf54535958657bda4dcf105216ddf47eb0", + "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", + "sha3_256_hash_of_ciphertext": "37843616c8a4f7ea9480740b6624f41650da2bb1664cf228d85d6d71a0624528", + "shared_secret": "d586b441b8eaf7d053cc96b6835f093426677a7c3acc51aaa3ddbb66dd14a623" + }, + { + "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "sha3_256_hash_of_public_key": "16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189", + "sha3_256_hash_of_secret_key": "873c94f8bee9fe37265d5dc0c5d3bc1c706057c7efb3cd2cd5ca9ba45498d0d1", + "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", + "sha3_256_hash_of_ciphertext": "cc677a81c73ea5139eed8d85782978d06192715933bc5aef560e737f6d57d0a7", + "shared_secret": "409bfd9102bd4632c6b5d3610eb349fe3e3bc51e73acc78a8e994a070e20e10c" + }, + { + "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "sha3_256_hash_of_public_key": "633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f4", + "sha3_256_hash_of_secret_key": "3c3cff5f49a802cec693efbfc264f6a385210b1eed20f7bc5b07b51839961d14", + "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", + "sha3_256_hash_of_ciphertext": "6d94a31cff4761e3993308cb3e812a4a7f04f64d02ed3b46b418c2fc16189dfa", + "shared_secret": "5dd151a8015c0b16d79822832ff4cc0da7fd38eb73b7da59bc519d4d2374b808" + }, + { + "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "sha3_256_hash_of_public_key": "3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d8303", + "sha3_256_hash_of_secret_key": "1503bc141825d523c9505d34f50dc0a01d7bc91cdaee6b99f4a85a24ce800496", + "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", + "sha3_256_hash_of_ciphertext": "a63613ccfd2ecf8aa3adf0103ddd9eeedbde3282443bcf02513b4ab87360cabb", + "shared_secret": "1c729b8e580e124e715f19ea6f2409fc6de741afa3d9919b2b8bf3e54c053b51" + }, + { + "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "sha3_256_hash_of_public_key": "d1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af", + "sha3_256_hash_of_secret_key": "a21acea0fd4354eb0c78d47caaf93c9f2434f1cf2d6b2194871ccd98f9522ced", + "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", + "sha3_256_hash_of_ciphertext": "3b322134b37fe8f5d7268fb74d1634ab8b35d456a973f7b0b427fb40a93b6db2", + "shared_secret": "b95ac8b73c703ab1154152b3ac73f054596ed23d3be328fbe20f936ea95fa926" + }, + { + "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "sha3_256_hash_of_public_key": "1b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c509", + "sha3_256_hash_of_secret_key": "3e214f25fbf4d1bb670a87367399e1b2a9da3491cac5a22a2c18dcc44f3f1bae", + "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", + "sha3_256_hash_of_ciphertext": "a2cd589c24c4c75bc0a3864dc84a85a7f0f3ac11c8578757f8e94054a7c186aa", + "shared_secret": "8c3851393e5c5997cc95f06da96300f6dd85c041343c98db2e742aaa5f78b298" + }, + { + "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "sha3_256_hash_of_public_key": "2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68", + "sha3_256_hash_of_secret_key": "c6bc9c9e797a02684d3ad8de47919b8d8fdbee09258d084c7a9dc963c80401ac", + "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", + "sha3_256_hash_of_ciphertext": "0cd687f1c3e0d67c46cebf93c1217ddc972ad8662dd05830db350e1292542c1c", + "shared_secret": "4b681fff6a755e1dda908d070f0d9ac610d85c73079c1022fc67d255e36f1f71" + }, + { + "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "sha3_256_hash_of_public_key": "bdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a7", + "sha3_256_hash_of_secret_key": "c96e176b19f4135add434d0dd219024587d49fdb649bf470e84d9518bbfa2879", + "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", + "sha3_256_hash_of_ciphertext": "b38711e358893a864b475f35328b2450fffd5087d631844f7ab0995de2b8310d", + "shared_secret": "bbaa67f1dad879f2fb33bd4ead45aec354bc8f05c7cbea1e433509faac022edf" + }, + { + "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "sha3_256_hash_of_public_key": "61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f", + "sha3_256_hash_of_secret_key": "8baa58b1d3fab8ec5cee8841c9012506cad40bf58a677adac88f1a6400506d40", + "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", + "sha3_256_hash_of_ciphertext": "7d47a21d95483a5845a4fddbb07b3435c29a56b5cf26f5d0abfa21bc39a2f2e6", + "shared_secret": "2c7b983d66978be80250c12bf723eb0300a744e80ad075c903fce95fae9e41a2" + }, + { + "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "sha3_256_hash_of_public_key": "672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec330", + "sha3_256_hash_of_secret_key": "4c72f0a7ef5c3274c49365cca5e6770bc709ef12bdbd4fd7c2eb5faa296cdfe8", + "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", + "sha3_256_hash_of_ciphertext": "167b4e8b7517cad82ae0f49795918c4d33c79137a9c3e16000c4c55b30b1d382", + "shared_secret": "bbc58d06cc14f9e96a10acb1789d93b93933f1429cc53a1735b3cd995f086ce7" + }, + { + "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "sha3_256_hash_of_public_key": "b86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b", + "sha3_256_hash_of_secret_key": "c25f2e16a0e6fbf0729e5ee89fbbdd71f00ff9a1abbb00cb47f26e9989eaf678", + "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", + "sha3_256_hash_of_ciphertext": "8919940aeb732930c496fa9832b0c09382663accda45be1ee22930c545eb3a37", + "shared_secret": "e045e0391e15a66d6208467078f2ba5e429cc586c410ca6c5f3c032c21761955" + }, + { + "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "sha3_256_hash_of_public_key": "85441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be624", + "sha3_256_hash_of_secret_key": "93b65d2df33d3e3ab0d53c1d0a21f3752e2c5962f7d960b888b2a8c495b1b133", + "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", + "sha3_256_hash_of_ciphertext": "422509b01b8fff9468e867a2b5ebe5d3e27314de5c058b2c79a61ccf464f4df7", + "shared_secret": "0b8584b75838e084839d58c89cb1749e82ec06a0e85464c7546dd96870547d29" + }, + { + "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "sha3_256_hash_of_public_key": "065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e2", + "sha3_256_hash_of_secret_key": "0121afcc6aeb8be9f1c5b06d5b65cc1c03e9366ed7b85fc511d853c5eee230cc", + "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", + "sha3_256_hash_of_ciphertext": "f1d3b745d86f860e508ad8b6d5c8a72ef833c280ec11e99516f4ead3c42509be", + "shared_secret": "3547a15b5748990a5436bdc4db283738eb7d64bdb6ff566c96f7edec607ccc9b" + }, + { + "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "sha3_256_hash_of_public_key": "ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd129", + "sha3_256_hash_of_secret_key": "16e06287bd8d71c78f1657bbd6d5d12c22f6bad7658e68dd849d7751da950860", + "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", + "sha3_256_hash_of_ciphertext": "fdfd351fbb15c92843b44489fee162d40ce2eea4856059731490afda1268b985", + "shared_secret": "852ba9be42763c5a74a75778eb839a3738a8ceed1520b0588f9dccdd91907228" + }, + { + "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "sha3_256_hash_of_public_key": "2fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c72", + "sha3_256_hash_of_secret_key": "ffdb52b23a9ca4b71ec882031ebcb33a0ecc6731c13c817b24f3a06e48273778", + "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", + "sha3_256_hash_of_ciphertext": "215d83f872221c5fd4ee4da557e17299dc102c52dba1fc4bc3f8c16805da7f1e", + "shared_secret": "618a8496b8850609c09dd1d18798ee2bfff3ed7ef6f8b8034fffcec98f291d69" + }, + { + "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "sha3_256_hash_of_public_key": "86bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e", + "sha3_256_hash_of_secret_key": "5d46659798d268f1314ad1e7c1735c480301f5877773403966e928bc3fd33d1b", + "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", + "sha3_256_hash_of_ciphertext": "5ff5d6bdb110bac57e58a4e288d056a1384f9823606a42daef2ae82e0b7574b2", + "shared_secret": "cbb8b7a05f48b47d163cf8c2fad32bc586f47f2c2e0911da349f29b1e3286c22" + }, + { + "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "sha3_256_hash_of_public_key": "29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c", + "sha3_256_hash_of_secret_key": "aadce411f3708e9727e4a7e4e198781e1ef5e8f4c4c14add1e25f5758649e265", + "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", + "sha3_256_hash_of_ciphertext": "675039d66fcb631a050a8b24415b50f331350bd6697f9c977eef15c15d4cacca", + "shared_secret": "1eef87404f318351413d52ba8a07cfa5e72f235d6f91afd7fb8ad3e683ce0a55" + }, + { + "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "sha3_256_hash_of_public_key": "286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611d", + "sha3_256_hash_of_secret_key": "a6b53edf9efd7fa67a478456a5b6a379876c248f623ea45f4b541a8db00c524e", + "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", + "sha3_256_hash_of_ciphertext": "f03d44bd9bdf3bfd486919fec2177b8b685a9981de4cbc2a9e98b7e9b0a528fd", + "shared_secret": "ca2c0bba56645e4fce4b7e38a7bb4b839e754bf2834a302a2614377eddd6ae60" + }, + { + "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "sha3_256_hash_of_public_key": "029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585e", + "sha3_256_hash_of_secret_key": "413ae41ee83e17b74ac654c2aca57abe8f8ed0409acf7cc8b301e3d6bb049cfe", + "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", + "sha3_256_hash_of_ciphertext": "e8992f7b7b619c03cb9f0c991e3a9c20f91beb707c177ad4e02a5808d10d8769", + "shared_secret": "9155619e28de6cc0670ce70e0ad270f0e885e5f5f8d6d38426938ae1036d6ffa" + }, + { + "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "sha3_256_hash_of_public_key": "e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d", + "sha3_256_hash_of_secret_key": "93bf696bf0671c3845c4b246f29701a0978eec5b49de81589009e235903061e0", + "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", + "sha3_256_hash_of_ciphertext": "6634bd840d2dbb01463cfe5b4e3e54d1eabc081cfbdc14d0bc118911ed8d3cce", + "shared_secret": "d1f24383d5b8d0c3c0a6a5f8f7d38ccce13ec179a84b0b09bcda4c9988f3eb4e" + }, + { + "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "sha3_256_hash_of_public_key": "79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52", + "sha3_256_hash_of_secret_key": "65deb55fea451375ef335e7faac73917d32220fc70c95f371fdb16e712beeb26", + "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", + "sha3_256_hash_of_ciphertext": "ba79883ad64a6f2b256004233d87809a8c390327a23c739334f773507e003aa7", + "shared_secret": "d2dab0b39b7f62de3ca9826f9dd15a4201191a0e0c690d3e52b305a9d3af2d0f" + }, + { + "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "sha3_256_hash_of_public_key": "0c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3", + "sha3_256_hash_of_secret_key": "d37f172803739d074d71a2be32125eb1ba4250128342e34b882fcba38b259248", + "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", + "sha3_256_hash_of_ciphertext": "13d437b2fd9d67ca0699a3dacd977fba5d072fa6b482043d63e8a9548ba6a3fb", + "shared_secret": "6869ca370a496af2dbaa866265d91ba6be54b9686b1b8dd5714f6ba861b0d1e8" + }, + { + "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "sha3_256_hash_of_public_key": "5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d", + "sha3_256_hash_of_secret_key": "280e4774d1b2401580216fa70fb24c2c214ac5dc7f3841710a42e14d6aa09663", + "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", + "sha3_256_hash_of_ciphertext": "51eb70249a1abebd5159f1069b1acda2304f25fc9cbd9f4a625b58df448b47dc", + "shared_secret": "502d92b2a7e1804892ffb8ff009987a58f35baa30c0392c83859fde82105a9aa" + }, + { + "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "sha3_256_hash_of_public_key": "172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147f", + "sha3_256_hash_of_secret_key": "31136804b6c14f3a0a00a3295a5fed8d606369e64d272d432c59d7fe0ccc3e47", + "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", + "sha3_256_hash_of_ciphertext": "9b38b66fdfe80acab82bf9577676f6566b4429f78a14f7486b07c96ae7be921b", + "shared_secret": "48eb4b840c0d957f28808e434786c02a8f99d3464ccb3caf91cef4a0f8e70c4f" + }, + { + "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "sha3_256_hash_of_public_key": "268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2f", + "sha3_256_hash_of_secret_key": "3bf02cee24670ca40b7280d8047fa147b24c5e286dcae9c24bace9465bb19f61", + "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", + "sha3_256_hash_of_ciphertext": "fe8c3fcee4be152aff29e55f42f2fb1354ae55ccbe38400bc901ca032ede1ef6", + "shared_secret": "f9507f70421be90f21138a1e135329ee8228682cc948a6914ea58624d396df0b" + }, + { + "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "sha3_256_hash_of_public_key": "4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead", + "sha3_256_hash_of_secret_key": "5de91ca73756eee74da3cac78a1fb329a02f8587f212bb9bc0b29e0e654a5795", + "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", + "sha3_256_hash_of_ciphertext": "805ce0ab06c568b614cacbfa4cce5e65929e2846932a90e9418513dd48cf3358", + "shared_secret": "24caabaafe2063f812eaf57c58b6c0376ed8ff778cec1980ee9c3228801a75a5" + }, + { + "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "sha3_256_hash_of_public_key": "72be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb", + "sha3_256_hash_of_secret_key": "a68ca31b91491a129af9f280cb4c60c046e7a7ccddf41c9bd98663f8512ca34b", + "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", + "sha3_256_hash_of_ciphertext": "d27a36808f09d6165aefc5d253090027eeff0653268c55a0b3de2a751ec765be", + "shared_secret": "9f734b15fc7dd99bc10d6cc7de5d2c93ac789a5665e508a95d075dffbad25abb" + }, + { + "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "sha3_256_hash_of_public_key": "0831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67e", + "sha3_256_hash_of_secret_key": "2b983d7cb50880cff761441b6a2c66b7a41642cfd2a8cc297a5df53f0ed1947f", + "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", + "sha3_256_hash_of_ciphertext": "0892527da24957468b1b8fab49ad2d7dd6d238eca54624fce6a3c2dbbbe8d194", + "shared_secret": "d27e55f2a1f9ef336c8537f11da9875e03cc7dde8951d81b0740457609654107" + }, + { + "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "sha3_256_hash_of_public_key": "b30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68", + "sha3_256_hash_of_secret_key": "a49a7533c671e533deec55af218ee511c57014070e138c7059853e08c34b0a78", + "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", + "sha3_256_hash_of_ciphertext": "390b3b6f9a0f9d97ccd452c83bf47416b22fd06b4d8968c44ee6effa7980e68c", + "shared_secret": "ed5903d1cf02861444cad7fc3793b4e1b9b6d0324bf6babfb768bb2f84300086" + }, + { + "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "sha3_256_hash_of_public_key": "ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b49648", + "sha3_256_hash_of_secret_key": "9e865967f0d1e7d3f6a49f2bb623ced2a7b1408a945e02adbdca35846b70e7b9", + "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", + "sha3_256_hash_of_ciphertext": "6858db6eafd97259e6d775d881f7a877010179d4f827680426946b9ac4571261", + "shared_secret": "0d301028c1cb31dedc8a702a9e95b7d3589f68a6a1f600af84ae0f543e625361" + }, + { + "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "sha3_256_hash_of_public_key": "e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474", + "sha3_256_hash_of_secret_key": "91051a381626e9465fc7ab20a1944eca64be461330bda53e7d1838a74597392d", + "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", + "sha3_256_hash_of_ciphertext": "42bfb5584610497fbc8080a664139afa534b39a417cb69ab0d2a16c8737eb1cb", + "shared_secret": "354d86b389021a3196b75c6582927b3a005fbfee0951f34d9cd5c8f415fa50f9" + }, + { + "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "sha3_256_hash_of_public_key": "a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb", + "sha3_256_hash_of_secret_key": "cf7e797f8f7229a08206034737e54fe46645ab2fabdbfc8662b45a2604876b65", + "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", + "sha3_256_hash_of_ciphertext": "ce7b65856502b280e02a36d906e018c6a23cae99f27ef6d65762c87ddfedff56", + "shared_secret": "3afcfdc446f93a8169024a24fc0383692843cfd6b4854a8e490892fc35aad4cb" + }, + { + "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "sha3_256_hash_of_public_key": "aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce", + "sha3_256_hash_of_secret_key": "1e7f3f1e5632d1df538b564304f56689742d1f652d8d32f019b45183af68a20e", + "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", + "sha3_256_hash_of_ciphertext": "b6c40fd53bcd9ee1e70bc6783b402ae34c24dec724e63262d8583c90cd10256b", + "shared_secret": "ebba9a8bae936c829c1445c68595da96919041ee3d9b0fe27ca93db691146874" + }, + { + "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "sha3_256_hash_of_public_key": "cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5", + "sha3_256_hash_of_secret_key": "928592604aa44df8f2072f26e9511129f61da0b7f57acb3f6896635a9764ea87", + "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", + "sha3_256_hash_of_ciphertext": "a4b50ad169b436877652a6c64dbbffdd63f53274ddcf58f3c96c3929215aa956", + "shared_secret": "f063c0908deb2e61faa0c4c0f5051b2c8af7265060681df14bacb30f0228b3b3" + }, + { + "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "sha3_256_hash_of_public_key": "3a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a1523", + "sha3_256_hash_of_secret_key": "28ee987bc4ae5a321d2669950dbf87596fc4b35c29f192836005064aa3dadee1", + "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", + "sha3_256_hash_of_ciphertext": "126b64a28d82d06ca81f7e86d33f4949634924e04528d1142061320eaadcb841", + "shared_secret": "02d2e466e170bf45d3e9d357e2f04c34cda408cf147e9ff7a6e8c715f2c88ace" + }, + { + "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "sha3_256_hash_of_public_key": "da43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc646", + "sha3_256_hash_of_secret_key": "b204cd1c3122b29a3d99cb77e11427fc102375699928c5a6fe816f96bb212627", + "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", + "sha3_256_hash_of_ciphertext": "228dfe300e3fabe4d4e550754ebcbbf72a796209c1d24e7ae93abb79e1cf17dd", + "shared_secret": "6a5b0842c122ab6ee251399492b061d2ab3e40843f4dc01c12fbd5bd545c600c" + }, + { + "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "sha3_256_hash_of_public_key": "6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff9358", + "sha3_256_hash_of_secret_key": "b9dee52055b1f9a2b25a0c1be4d9f30d2ecd7c5a09f0f5294de2d49a55ac9fe0", + "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", + "sha3_256_hash_of_ciphertext": "2d7e8fbd6f2257b05eaaa2ca1643c452b4e0b623c9ad72027cca8dd8b7b5b91d", + "shared_secret": "2486c0a6cf17d9635dbca1f8395784cde54dccb7df10fced92183f983478fac1" + }, + { + "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "sha3_256_hash_of_public_key": "e2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1", + "sha3_256_hash_of_secret_key": "68eaa8143a71bd5f6df29b128781e3f2a5fbc5d20534afb223ddcc64bc767f5a", + "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", + "sha3_256_hash_of_ciphertext": "b5b2de55cfaea8fe543f67c4f45a69780c3e2d932e56e0b574d9b40b56ddc1f1", + "shared_secret": "85690ee044e4d8e0540ff984775b59bb5134383c4e229e79e37d7d77632fadaa" + }, + { + "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "sha3_256_hash_of_public_key": "d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf", + "sha3_256_hash_of_secret_key": "5f9a14a9c41fc228306d79417015408f31bc9c3d97579616bd68a3d3444f9bd2", + "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", + "sha3_256_hash_of_ciphertext": "99fb7b7767fa94e74936a6678acfd5a2306b156f90f4608d507768a25403a16f", + "shared_secret": "d179d901a0570bd23aa52570c5c233a2240d4724e81d98c9ceedb74187eb75a6" + }, + { + "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "sha3_256_hash_of_public_key": "65f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0", + "sha3_256_hash_of_secret_key": "e4513cfd1dd2153d30d15b023421cb8e8456e6a40e612847e1713e915a29a87c", + "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", + "sha3_256_hash_of_ciphertext": "4cd7f0af86623b34c0b137a0516b876daa73ffd65d75871ddc828f86a7e9b224", + "shared_secret": "6d574af7fcb241fed8763b2d0a352870baf85ef686e90eea31f8500c35945ef7" + }, + { + "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "sha3_256_hash_of_public_key": "b8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef45793", + "sha3_256_hash_of_secret_key": "1f7cdadf3d4707efe1b7a6173d8f7b8a9f864ab388c3271d79ec424d9da3e896", + "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", + "sha3_256_hash_of_ciphertext": "1ca889a71a087ccee4ee1a178c3c55ce3649583f3db924e5c1003ccabc44091d", + "shared_secret": "b1090cf26276a81c22ef0e4479a4c705fe294d3b892051ddce7eab16495e0783" + }, + { + "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "sha3_256_hash_of_public_key": "46fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719", + "sha3_256_hash_of_secret_key": "3177ed170e84ff15fa1e744adc9ce806e431a68f15a7a026c6092bf593dec6a1", + "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", + "sha3_256_hash_of_ciphertext": "aa9a0ea1823a84bc84649d26e249899437844827fe7c63d4828a5144929fa00a", + "shared_secret": "2fda9fa72321be3a0946d6d914c7ae714b9cc175619ab8abfd1f1fd499e0dc27" + }, + { + "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "sha3_256_hash_of_public_key": "a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ce", + "sha3_256_hash_of_secret_key": "8f9b3f631d0fb04477846ae09aea725f1cc65b2cdefe2108cdb399c36db9b487", + "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", + "sha3_256_hash_of_ciphertext": "a4fb01f55eb2986c1f90cece43330bee1b16d7bda48d617fc94aa14fc540ec4e", + "shared_secret": "23798e8b9eaa0b369842cad83a2bc32206f791229c830d7593b9150161168011" + }, + { + "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "sha3_256_hash_of_public_key": "26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9ed", + "sha3_256_hash_of_secret_key": "5e3f83cb08ff80183879af9ade3631bed2a468e429ad027a5afeafd9a6f66362", + "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", + "sha3_256_hash_of_ciphertext": "6a4204db4803d26d7b8a769033e047f3b4cb616bf5451b88a1fb3ff219bba9cd", + "shared_secret": "d5c63d2bd297e2d8beb6755d6aefe7234dea8ecfba9acda48e643d89a4b95869" + }, + { + "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "sha3_256_hash_of_public_key": "2ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf374516336", + "sha3_256_hash_of_secret_key": "2798448395f6ae3223550e7d5255e6a605b430229f5809b6efd0683a6b9ca402", + "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", + "sha3_256_hash_of_ciphertext": "dbd5fc0e1df33ff8af9efd5e281a2b98160f98653803cbd54e3a07292b37fcc7", + "shared_secret": "29d6a229adf49a1139794209307b0ca24be5825b2771809232fb718660162475" + }, + { + "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "sha3_256_hash_of_public_key": "de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7e", + "sha3_256_hash_of_secret_key": "6766cef3fe644a233caddf208074b58e6e83f8a78aecd00911c29a08f6f0b0f3", + "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", + "sha3_256_hash_of_ciphertext": "4c669e33b0227c9c2040cdacdbcb7d22b9984372587985ed8f860ffc8d037e79", + "shared_secret": "2a56a7a6d5b4c0500ec00a92e322e69be9e93006240889552072482966c54f56" + }, + { + "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "sha3_256_hash_of_public_key": "66f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656", + "sha3_256_hash_of_secret_key": "2237f6cbb452d375878b82c474a7c948ff587a5f3ed02bbba1459fa7ff8ef802", + "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", + "sha3_256_hash_of_ciphertext": "8a2453a21a031cb8966924607a28882426fab2018826192e9bf833bdd38e0631", + "shared_secret": "ecb62b03f640ae4a9d89685fa0070efa93c24dfcff0d555142f9de25b62f861c" + }, + { + "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "sha3_256_hash_of_public_key": "7537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2", + "sha3_256_hash_of_secret_key": "bd8e44337eef01251217c4702c99232c001b33870953473d83a7486fd25484cf", + "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", + "sha3_256_hash_of_ciphertext": "6077c60641c03aa8b36213dddf938311ce6b7b8801f967d42713e73249fe7c55", + "shared_secret": "6cc30699701927e07b559d708f93126ed70af254cf37e9056ec9a8d72bfbfc79" + }, + { + "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "sha3_256_hash_of_public_key": "82f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335", + "sha3_256_hash_of_secret_key": "fd483ddc211c5c27f453bca56158e1f8084f075a7b06f5098cc3204427bf8197", + "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", + "sha3_256_hash_of_ciphertext": "5c6cfa16f63b1aa93a2b5edc2f4b14c9782f286f53deedf3153f329a2ae2d57a", + "shared_secret": "250e7f67bb34dd5477471e3a701fb71a8138a1920eb807824380f88a944a6fa3" + }, + { + "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "sha3_256_hash_of_public_key": "104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4", + "sha3_256_hash_of_secret_key": "73fb93953ae666a9df1bf933ba56b8655ea9e319c0110c78d49f8480ae1aa3fd", + "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", + "sha3_256_hash_of_ciphertext": "e51772e769f778067916e81a561ba6f64fae6096a2b4d4b945d9117e7c36e2b1", + "shared_secret": "0210935a18f1add5ebc2e1107bf40a628ef9cf8f6e7cdac81dc0291bb50a5a3f" + }, + { + "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "sha3_256_hash_of_public_key": "0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3", + "sha3_256_hash_of_secret_key": "8a9edd6278707108652f3a5bc244592cb7a82c24634583ed2d3eb6a176b216b8", + "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", + "sha3_256_hash_of_ciphertext": "a00c37bd326205575fcbbc100ed54630aa0f2d6dd9e69807d49151ac9a81c429", + "shared_secret": "34169fc520e944f94ff1fa3799db802a4c1b26cb2971bf196259a937ab8362ca" + }, + { + "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "sha3_256_hash_of_public_key": "12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee6385", + "sha3_256_hash_of_secret_key": "bc13b19f01d4cab36dac2154e0fd8fb7d2fa012596363942847f1b0bb3715f90", + "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", + "sha3_256_hash_of_ciphertext": "aed1a4ee810b81cb8ee49ee00e94ff4553f0ad2176fe4d27a09f4e68157fcc3b", + "shared_secret": "b5901e97eb656a09d2dd132528148ad07a0a89f638717eb53516a9ad19aa36bf" + }, + { + "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "sha3_256_hash_of_public_key": "2fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85", + "sha3_256_hash_of_secret_key": "2743b7a9dd83a6b9bb5c2685f28b5629b2e31132ac64788a0929557d3449dfc0", + "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", + "sha3_256_hash_of_ciphertext": "7a039d19c45cc557036189cbbc63445b3504a689db56845ece99d593f165c6af", + "shared_secret": "df5117706beedfb521f0f021069fe9650d0844194339033de6997dced05268c8" + }, + { + "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "sha3_256_hash_of_public_key": "3eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192", + "sha3_256_hash_of_secret_key": "398ae3423ba5c6bb05920e83e8939a104c3e4ad91647edc7db1667efe438cbfa", + "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", + "sha3_256_hash_of_ciphertext": "05c9617befed785811fcc44d0fce5ae3a1ec66c4d1217ab42e4b754d0ef6207e", + "shared_secret": "eed6ecb831c881508f99ea115745448a7b312a4fa97f65044ebcede172dee2fa" + }, + { + "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "sha3_256_hash_of_public_key": "306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47b", + "sha3_256_hash_of_secret_key": "88b28cf6fe19424ff82fc2bb096423b71f0cb8cf985af31bc15ceb4ed18a5e62", + "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", + "sha3_256_hash_of_ciphertext": "315ef84926802ecbbb437f8f50927d3a391b55ee6e47dbd19aa9adeebb808008", + "shared_secret": "d6cb77dc96f9ae4bf8b2fc0e277935b3b7b7a59f749ff2c08ad42659dbce386b" + }, + { + "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "sha3_256_hash_of_public_key": "9bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b1", + "sha3_256_hash_of_secret_key": "d8c2492023fb1175a84c19b3ce20f03dd12b1c26b65176d5582c319124bc0e24", + "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", + "sha3_256_hash_of_ciphertext": "ae36e333ece7ca60c9bc2c4ddd01ca88443fd73bab08502656873b703af8925d", + "shared_secret": "1592f1413331f1871b41ff298bfa669bca667241790370d81163c9050b8ac365" + }, + { + "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "sha3_256_hash_of_public_key": "6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b3273", + "sha3_256_hash_of_secret_key": "0f2c7bd16d9289c3c27136df0cb6ebc624e80144cb92e6f0c897f58a53617ac3", + "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", + "sha3_256_hash_of_ciphertext": "f8a85f106c6144edf1c7906ec26e292f0390aa9d45a22e67ba2ea018ff565c4d", + "shared_secret": "966f35c6bc47b4525d9af1ba350e8f44ea448cd1d90cf4e9c55ae5878920b7cd" + }, + { + "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "sha3_256_hash_of_public_key": "64c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a", + "sha3_256_hash_of_secret_key": "e85b62236d5c6c691a9076dc58bd5da80999eccc8df973c7d0e7e65d8465ea7d", + "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", + "sha3_256_hash_of_ciphertext": "e9149359cc37143b0b565bd413a04f41a7833c5b76012a9263a086ac34071684", + "shared_secret": "aa333af0226492126c6985130ac7df2226a64d6d5c5314ce3f7a99add6696d49" + }, + { + "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "sha3_256_hash_of_public_key": "db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf7", + "sha3_256_hash_of_secret_key": "be98d62e4724c0d960ad4839298d4571f9871033b63bdf10d3b0e589db376ffa", + "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", + "sha3_256_hash_of_ciphertext": "9f9368ba712cfee95f28a808cb2c23116a0c8da3910c0def2ef4e55947d7101b", + "shared_secret": "9535303e6035e30c6605c9e0f10c553dcd73828d8525cb190fea79937e093331" + }, + { + "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "sha3_256_hash_of_public_key": "c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec", + "sha3_256_hash_of_secret_key": "7a5e854bad628be7b99f524f52a97b0959c0ee67a7a10ad24b970e6e3aeeeb80", + "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", + "sha3_256_hash_of_ciphertext": "31b04a4127558df57844413928b29b11547de5afc088d568a962fe080c97f190", + "shared_secret": "0caa79e0054182c15e54159fbe36d9fb09481331a560ccd9714fff81db5615c4" + }, + { + "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "sha3_256_hash_of_public_key": "f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dc", + "sha3_256_hash_of_secret_key": "b6ef04e6acbcd1bb072d1cd28412cdb00ee40d04ce5b39442a2efd6756292167", + "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", + "sha3_256_hash_of_ciphertext": "d8fac8ffc3d8dfebe66c219f4189b780d5ba8fe28d5ab79264345639740913b0", + "shared_secret": "744ce1aa5a9c515c6571ad6e2f5985df8434e35e9f714cf3659f184b5db4086f" + }, + { + "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "sha3_256_hash_of_public_key": "10e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012", + "sha3_256_hash_of_secret_key": "2b5c6d5fe9b09ab5a027522e699401223ae9d304ac912f1b15f0f647dd9a0a7f", + "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", + "sha3_256_hash_of_ciphertext": "e8b01628c7d63f16c59e67352399a760581f341ed41535013490502e884733be", + "shared_secret": "726f7d790df4c860a0b2c40de9d62c85d0ff70c704ce5a1b3f6bf1b3e3f66cd8" + }, + { + "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "sha3_256_hash_of_public_key": "7c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851c", + "sha3_256_hash_of_secret_key": "72e786018ae9ab8293fa51cb7ca3ff0435e7cccbd5ae02b4680b92c148590265", + "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", + "sha3_256_hash_of_ciphertext": "5b2e8a3e38c13b53393c8654e92eeb6251ddbe50de4b3c5203a06977491f2fbc", + "shared_secret": "68f3e22d1b2d8c57bff32160e550becfce535fdcb327394aabeb60eede263213" + }, + { + "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "sha3_256_hash_of_public_key": "8aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d", + "sha3_256_hash_of_secret_key": "f7399dbf35fcc57a9bff87b0087755faa75267788cd0921b9ebc5cde8b656271", + "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", + "sha3_256_hash_of_ciphertext": "aac868f2299bcd272afacf50f1ab0db3d092d33565cffb5645d8b92271e7e893", + "shared_secret": "7f6085840a30c6b1fb9dca782e0c78a2264d54726c04c3127956f131165426c8" + }, + { + "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "sha3_256_hash_of_public_key": "149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75", + "sha3_256_hash_of_secret_key": "6dfa4d29af6a0e8413d5591339c15d2e2cfac3f502f49acca3efb53b53624666", + "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", + "sha3_256_hash_of_ciphertext": "ced7a64ce643faebac8ffd39c6a4594732b35f1d6899978ba192b87003d3ad27", + "shared_secret": "96e30641ea4280168da37291a3063342ced8e77b33b5415819938c0bd7264ffc" + }, + { + "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "sha3_256_hash_of_public_key": "29b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf", + "sha3_256_hash_of_secret_key": "762a61eb847c017ece920f51d5da7a9036ed8b835bfd7793527321ec635e2fd0", + "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", + "sha3_256_hash_of_ciphertext": "bf49310a35f9ba7994645f12949e658b0dd43d3de76386dc20d08c650522f86c", + "shared_secret": "47e54c85cc0e2503629a8bfdcfe038c3cf692d723d462bab733c7c8e0aa37b02" + }, + { + "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "sha3_256_hash_of_public_key": "b990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5", + "sha3_256_hash_of_secret_key": "37a044795bd330e4dc60a6d84bc6e99664d1be418b0239661d2ff16d1501573f", + "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", + "sha3_256_hash_of_ciphertext": "329115908d0763110a387c99778e4746861e80367ee90fd821cda9acdb93fd64", + "shared_secret": "8569bd042465a2c4af628425cb102b15ed4f5feee16090e2234f3a884a0fa938" + }, + { + "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "sha3_256_hash_of_public_key": "175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5", + "sha3_256_hash_of_secret_key": "1993d7639b79f5e4871a7c58a69fec50f96c1424c2c0ee030ac054ae1b88a56f", + "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", + "sha3_256_hash_of_ciphertext": "8f4225838f2964a986336bacddc40836a98c32cca68c6afcbcf9ef68d9a3760b", + "shared_secret": "c184e0b019c2db772e2c1ca6f97f47478d99cf0c4c5ae1406f51d15815022123" + }, + { + "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "sha3_256_hash_of_public_key": "9bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd3", + "sha3_256_hash_of_secret_key": "3db4ab1393cfc8b1c708cf8efdb1c443c975878898b60182c22af66375cba13a", + "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", + "sha3_256_hash_of_ciphertext": "f1c85f9530d4471eb1401fcf422a29533738c485a6be25f0b554ebf40b49d49d", + "shared_secret": "6d72e23c8a4cc60b2f14adc788a5c480033bbf6eb111070912bc83ad7b89280b" + }, + { + "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "sha3_256_hash_of_public_key": "7ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26d", + "sha3_256_hash_of_secret_key": "77431cb18010a604d56fe5a623bed2ffd028a741f176fa09546e9a45a48caa5e", + "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", + "sha3_256_hash_of_ciphertext": "83ddab2e25614544649a1e497b5b21c40a3e154e8a22c270f63cb0c40aa868fd", + "shared_secret": "29e6b1edac0a9aa33066c113167e42c64d70215ed04963d8be2d4c2dcd0f6589" + }, + { + "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "sha3_256_hash_of_public_key": "2c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b20411", + "sha3_256_hash_of_secret_key": "09844e203f4d8fa30728ab388b9d654847febbf5c9cd939cdc11c9c9be24ce9c", + "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", + "sha3_256_hash_of_ciphertext": "a2108ea2c446b566a50c228928893e2e4bde5fafb2184af92eb1314113bde0d6", + "shared_secret": "cfd1b82181543656807880f6e2576f0b095bf84629b3367e9bdede24662ee42e" + }, + { + "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "sha3_256_hash_of_public_key": "aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22", + "sha3_256_hash_of_secret_key": "3880f7ca8fc33575a7a6d8bb46fec86a3f12e0068630507ed245d8bc278fbe5d", + "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", + "sha3_256_hash_of_ciphertext": "ec48b3ec403609a0ce2d1268cadda8184ab9629cc5913135ffdecd420eed1aa9", + "shared_secret": "f7331b0a4674969838482b7184fa92e5246f11f5b5e284c3e179effff7eb6329" + }, + { + "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "sha3_256_hash_of_public_key": "64e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d3", + "sha3_256_hash_of_secret_key": "0bfbc25d9df751f4c30907095eb6d9a75ed07fa23218ad0fffc469f0e55553c2", + "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", + "sha3_256_hash_of_ciphertext": "fb74b727ad120c18915dca475f3082cd34ded7ae20a308106384ffb5caa029d3", + "shared_secret": "c89d62938a5caabfd5b30d82ea88aced52ef5f8ec0528e59a654e1f6aff1cc2f" + }, + { + "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "sha3_256_hash_of_public_key": "8dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964c", + "sha3_256_hash_of_secret_key": "7c53072fd98ea7bd8c5e873688b1a5650fe7e11c791407ac8c118b7958cf414b", + "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", + "sha3_256_hash_of_ciphertext": "a1f1579c4ce8eb725e697623321b3d9f55f4b1d0def10b898535ef6614e9923e", + "shared_secret": "204d9272682710b52fb39b1176af3ff737848978770310df0c67996f6cb596c3" + }, + { + "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "sha3_256_hash_of_public_key": "919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463", + "sha3_256_hash_of_secret_key": "cb1d7301f15951883cc3f287d4dd8fdf5c9b7022f558dff551c2ade5f5065755", + "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", + "sha3_256_hash_of_ciphertext": "f02654803493821dd9c2ed23f9e46a36addd5fca0da706bbeeda87a2df9fec4f", + "shared_secret": "76e5f7623e3e867fd12f28dfda4311f7cd90a405b73e994e857f693573fd2b8a" + }, + { + "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "sha3_256_hash_of_public_key": "cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76", + "sha3_256_hash_of_secret_key": "a85e24cc2eafdfe40d82f46471112e1359628b9955f3feae9955b48d563ac952", + "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", + "sha3_256_hash_of_ciphertext": "17336b9ede3a1c26abe725828a5afbe746035a73dfd4a8fbde5040fbabeb2b8d", + "shared_secret": "874ac966970f29935db73c231e71a3559b2504e5446151b99c199276617b3824" + } +] \ No newline at end of file diff --git a/libcrux-kem/tests/kats/wycheproof_early/decaps1024draft b/libcrux-kem/tests/kats/wycheproof_early/decaps1024draft new file mode 100644 index 000000000..f126fe53d --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/decaps1024draft @@ -0,0 +1,1830 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +private_key = 07638fb69868f3d320e5862bd96933feb311b362093c9b5d50170bced43f1b536d9a204bb1f22695950ba1f2a9e8eb828b284488760b3fc84faba04275d5628e39c5b2471374283c503299c0ab49b66b8bbb56a4186624f919a2ba59bb08d8551880c2befc4f87f25f59ab587a79c327d792d54c974a69262ff8a78938289e9a87b688b083e0595fe218b6bb1505941ce2e81a5a64c5aac60417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3683c0b7b10029fc203418537e7466ba6385a8ff301ee12708f82aaa1e380fc7a88f8f205ab7e88d7e95952a55ba20d09b79a47141d62bf6eb7dd307b08eca13a5bc5f6b68581c6865b27bbcddab142f4b2cbff488c8a22705faa98a2b9eea3530c76662335cc7ea3a00777725ebcccd2a4636b2d9122ff3ab77123ce0883c1911115e50c9e8a94194e48dd0d09cffb3adcd2c1e92430903d07adbf00532031575aa7f9e7b5a1f3362dec936d4043c05f2476c07578bc9cbaf2ab4e382727ad41686a96b2548820bb03b32f11b2811ad62f489e951632aba0d1df89680cc8a8b53b481d92a68d70b4ea1c3a6a561c0692882b5ca8cc942a8d495afcb06de89498fb935b775908fe7a03e324d54cc19d4e1aabd3593b38b19ee1388fe492b43127e5a504253786a0d69ad32601c28e2c88504a5ba599706023a61363e17c6b9bb59bdc697452cd059451983d738ca3fd034e3f5988854ca05031db09611498988197c6b30d258dfe26265541c89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9790a26d17b0398a26767350909f84d57b6694df830664ca8b3c3c03ed2ae67b89006868a68527ccd666459ab7f056671000c6164d3a7f266a14d97cbd7004d6c92caca770b844a4fa9b182e7b18ca885082ac5646fcb4a14e1685feb0c9ce3372ab95365c04fd83084f80a23ff10a05bf15f7fa5acc6c0cb462c33ca524fa6b8bb359043ba68609eaa2536e81d08463b19653b5435ba946c9addeb202b04b031cc960dcc12e4518d428b32b257a4fc7313d3a7980d80082e934f9d95c32b0a0191a23604384dd9e079bbbaa266d14c3f756b9f2133107433a4e83fa7187282a809203a4faf841851833d121ac383843a5e55bc2381425e16c7db4cc9ab5c1b0d91a47e2b8de0e582c86b6b0d907bb360b97f40ab5d038f6b75c814b27d9b968d419832bc8c2bee605ef6e5059d33100d90485d378450014221736c07407cac260408aa64926619788b8601c2a752d1a6cbf820d7c7a04716203225b3895b9342d147a8185cfc1bb65ba06b4142339903c0ac4651385b45d98a8b19d28cd6bab088787f7ee1b12461766b43cbccb96434427d93c065550688f6948ed1b5475a425f1b85209d061c08b56c1cc069f6c0a7c6f29358cab911087732a649d27c9b98f9a48879387d9b00c25959a71654d6f6a946164513e47a75d005986c2363c09f6b537eca78b9303a5fa457608a586a653a347db04dfcc19175b3a301172536062a658a95277570c8852ca8973f4ae123a334047dd711c8927a634a03388a527b034bf7a8170fa702c1f7c23ec32d18a2374890be9c787a9409c82d192c4bb705a2f996ce405d85a4c1a1ab9b6aeb49cce1c2f8a97c3516c72a00a46263baa696bf25727719c3216423618ff33380934a6c10545c4c5c5155b12486181fc7a2319873978b6a2a67490f8256bd2196fe1792a4c00077b812eae8bed3572499684ab3371876761e450c9f9d2768a36806d7ab2046c91f17599e9ac592990808dcd7b4d0919072f14ec361773b7252444c323c308326f4a30f8680d2f748f56a132b82674ed0184620b82ad2cb182c97b481626647491290a011cc73828685a8c367a5b9cf8d621b0d5c1eff03172758bd004978c251cd51342228989cae6332ac486437cb5c57d4307462865253be217b3515c73df405b7f28217ad0b8cf60c2fffaa0a0048b1fb4acdcdc38b5250cfec356a6de26cfa7a588fdc86f98c854ac64c7bfaa96f5a32cc0610934baa6a586b9a2054f13ba274174aa0d2b3a81b96a940666f789b5a6bcdc0a6a0178a0c9a02578a493f6eea0d2e6c13951c9f249a5e8dd71dd49a742d451f1abba19af8c547855e0afc728e90abb499c9beeb766f4729cda22263e324d22302cbd3399facc630991fc8f28bdb4354762541527678bcf61f65c241146c426d23b9bfaa6b7df18c97f20c1b6125bf874b1d89475852c448215db0eb7737f91480e8cebd9a0871574f5ab62d9020175ec6927ca0b54c09818e42cf92a383172422c7dc1831d63b0c295de75159db8034e9e07f7b0b910c3c1e5fb66b3dc523f1fa6eb4910cb89a6c17562c83ab4c18d0cd7e0796592a372aa409b1c557347ccacdc4644a119064d06dd474929d1c6fb4d686e5491ce4bc89a30bb4b8c41bce5157dfc1360823b1ab618c14b10f98c25067398ea7018c278a4b3df31334d603b2044ef187cd9bc6ce42725bd962c264983e9e18155a8b9c47143d70460a26a56fe7658c1f150348c6087ef758ad167887860a007a5fc37358d43b5ebee820acea474f0ac07b76802866199c61231d5c747c93774d2c1e0c1c67e6c81b82752173e125baf39b4fd19a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a13322899af659cf1b3558c1b5001154b625809ed89aeebb89e6ea7d67f723d045ab05715c42355da6a5c8dd39c8abe3037751a01ed1c7374919f3121b5a52c53d1487316769f80721deeaaad3c90f76e7ae9e12ba92b32b5fd457e3c752c2650dfb885771cb77ac3c785a8c562e6a1c63c2a55ea47cf8b90eb8225c123c346452566235b2f31823a33521e087937a345d8d663eeaa05658917bbaa008c2e335f8850a90a326d0e66432f44ceb8289e4ecb2d12958e984072ecacb88e1348ff0b55654acba5b54971cbaeba88ec4b91a94c37192fa982becb9f3da421603b61a51bc8e36cbd053851c77b1b926b17a272aa9023246b02b3ed47f66a00bd5684823634e7ce58cf8f306e35b1e5322824d904801f0a2fa7c2bc9c252b0a56b7ba2ab0f636021745a70a9a43e2b0a8d615970b65309624b5184bcc30b911679aedd76025fe3908fd67897b0cf4be5a6f5413d7dd98564b23e42a93e4aa8821cd45054c643edc1158db6b3deb13fb5a51ebd1a8a78b87225a7338e101104c4a220d9bdedd48c85a1c2dae781a80c40e13b87eac73a764201c9b760ccfb1ae392699c7039d27c39362b27b8fc6f07a8a3d4410f1547c48a9997f62c61074452ef1515f8a649ebca9437205a4e8a61606b41daf6834d671f4d852c0c9c4096611648c6a3170678b1537cc1828d93580c9e5849a9653175acb753f2be7437be45f6c603e485f2ec301bb42b6c37c225d7495a584ae231890ab5c8c35c268cf4bbb0213c096019319561a8a6947637aa40d006b415bb2cfa2237e0890b6a3bc134abf8f6585e108d15940f91f4bf5b0c818055b21dea6e63b553988c47f4b94e7cf800a493b4734705edc56a4b6021c629500675876804cf0b951f038a5c7fe58e89774ef2992fd7c63099d352a7d21560b788b405709861817e59a96b3a3a83cba803b16934331071905bbec6532900155d8ac88cb32e4e21a3bd3a03fdec325a51cd2773964e6784fcf1853737aa64eb67564727272661abf84313a57a44b123c65509cfb7a6f6641cdcc3b57fe628c7b8192db44ffbf5796a8613b1fa126f6076883c783dc24e2a4464c40b3a41ca70ae87620866cf4fcb2bd204bf5c283812ba056ac0c345e379c4ba24d750901279bb2f3a16f612bfadb35703332c7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377bc200e4d315a30a6bcc3256f9734d06e9779caa5442a9a16069081377c76e75154368072dc446ed6c8b8e622a21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543546284eda2a26b47f05b735bcdb1202220076dc8b4e4b9f853533c8f6c7ff38817ba49712835785f17f14ca01d0c1c1e98810fe0b36e5b427157b9418449cedd641a4293c85c32700102acec22ebad98ed160a5f027bd4cda57f1f3720a12c134654dd5e73f829676495390d0e7929d6034e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7a0021535a6e25e437d49a780698be22ac9953949f571b85a685725f8207a2b0ae849b601ab91b159b3df4a154c2041e776070afc42969322380917c97510799f3149131477e16663d3174c7c1caea788535c6c005a64f2868631b31b66e205fd38c1d84542d0f1b578f58c9bf5a0faeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539228a39e87d531f3527c207edcc1db7faddcf9628391879b335c707839a0db051a88626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = b15696acabf3f5c71c09605df350f98ef9897474f241c7f7d16f7a69604358508458916d2c8552c704cb6e0da4305a11720a2b59a6d8190fc3e389e6551e7c59578fe2b05d7591bab326d894e23656c6b5fe4b7abd6505a8c26d1df8b44a0ed53affff9a585fce86da3b3ff22b1fdae2f6d255c26535f61694d50471f1d84d17673e481f4e824c82810ce8f2ecc9bb3f5f07bf1430e7bfd99fb98f3d2f941edf642d7b9e73bc1595a04cd949fa766468489f402f92325f6d9ec5d696e0fac2c6a37983a6451384ce9d9de448f15874e530943e8e0fe29960587a89b8052c9d0e6b0ea5dbb734d2a9c05cbb6d0c79f4a57db5afded6a7df0ecf47b7a31deaf37dfa1dc89722a47b40b4a50c7a2f32e8ab3da973aa683c0a698294ca3a045483175d87786b47f78ab0295b8267edfeeda442c351a38e95cf43b08342c67d0bc5dd5974f6c5c003ea31b5804a311c29eba17bdb547a629ec83974043bd03a37d0ec7ff39de1dfb8e632a86b26021e753e7dc731bc4ed7e7fece78b07dff5e8775b2223e19dfb3a06a1865ed4f08a84544492504f2962e005fde5de6e4ff48994d4ff811ce31e3909803c3534c1c6c6ddc9e1a43c845e7e7e2a1081186bede4b5bcf1b80b13d218a4ab446f479e38c1de4a594e0f20cdc23a9ea58778cb2fb104f1dc91ba5c17e74004c430aab1a3d1679daeb5082e517af6a4e28f564441b73235d084a5831cbb394cecd997fe08b1b4aa995bdd9726c04615859fffd1c9906fb2d0401ed6f591e13c6e79ec5e862079e6dfd3ca688fa5ac7f8d27907530549ac71fdeb5f869d2a9b235a0e54b3b866021d6b5c98d1c6c0c00489995e3c3496b69c76338ac422c9f94158ed5cf9cc6be93846034d4ba533a3422c29d675405ae853b8497dc912f4a83500c89db76bcdd7046d9832fa3d2bf3d02465ebb4168035118f087ddd47643d2db71f47419aed973ec4384866d45e1df216eda5bf6133f84a328c1129621ec1501fc46fe3eda460680b397a42a4368eb3dc88451b2b616eec5f1ec05e5bd2084b4945d20ea8630d81492c78cf06a78ec508a0c5713b486021643266a60d99744678e598b152cf1829897af720c18eb6893d8b1f81c8bbc55c8047391a9051a6d0d65471891ac2dfd8ac984aa7aff3974492b751fdc5dea1396886e8c94b9448e1ee633f6c2143552eb849c6d7e72b6a7c8121461544515e346d69973111c924acda06470b5df2320e06b8f1aff413f9e888436c31378025be66726a0ba559177b1137c431cce1a6fb00de36c6afce92f11bc75a885fbbd9b108e6ead43fee47da311230f922bab93a7677711e97ea4129802c5dff20d0d9db97f882c63379fc27d08a6fecc288cc06e257654b388e5018801ff19bac2c9487a5f47e073101dd37b10d43c935119b6f70eddf9ba5149ed64e8c129d978cbf2c1a306f83a6347bfc445e8fd645ab0e4b2a939328cb55a7951a3a938a06aed24ef32562149c8b7f2dadd75d2db3782b64f4cb1f56a0945277c9c5e1605a0c0eb65d7fe3421c90874bb9ccb945ea74c997eca73c94059b77c7c3f08dd6e5e494e3f23399f2fce056e9f130feb6cecbb3e8dece49e5673757515742094ac382563857b5d412d7191cdc5de0681c72c5daf833beedcd88e40123a617d2bd0d7595916a6894b9263b6eb91e2380154e0cfc52784258cf7320c4f02ead0b4471ea0dd0abeb5e63628f4836a23db269cee09e46f35b9de87ecb0422ad8ec6cb60b717eec21216f0b791c852a9f8a4c26167d7350e17fa3ec745b46311a671cb8d7f14885ff01bab0ef469d0850fe807e70d36a4b736b2c32c676258ae7d553dcab8ade6368aa23179778add214dd9154f510f50e5560c65fcec35e87882530edc65bee66b25a535da2146e14f8390bcf579c337bad974575d5f09a8768883f9393a144171feb3fc663eeef138b21bd557abbbad2c0224341fabfb6c6fdea6f3c265e5d8af169a964a7a86a1a0e222dd6371382079f838234aea8ff6e2b894e04a9a34cfacab81b0704b14d7d109949c68644c015bc2f26a9c294287ecf152d846f914c0745ceb7ec3d36ad9d723c15f89e2d8fe2c18e11180d0709d7002a50f87d1c73dbb616fd8de30339d83da5a8ed50321cc12f94dff84d9e544f17ec34a60eb414b2878cc1a05c264a066ddd37f0c504f0e6ccd0f311eb5212de32e9d655125e4f4 +expected_result = pass +expected_shared_secret = 63a1039074f01f2651213ad9350d6561cb03a60400e74118bb4464d87b9db205 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +private_key = 94b49ea42526935245c45a7d580b6aeff8bbe0f5342bb8bd2550212ad5935f45cba7caa6df914007fba79e9946c9433a86a2c4202bbdcea008af78975e6619d3582787530dbb7318a530b7b5a27d24258c7ccaaaf505ca92cb853a5818d4269be812becf169a05e71eb957557787c2f3b72315281dba87476b157a06095a30d52b388ac22840755b43440a931df8a709dc435b415a7babbb04ccd93cda00ca1fb090646b1d6514813368a794d38c907163b5917496b018c519b160c5144d6424495626e3a5ab9ffb8d8d3168d77599a88a1d12c07d86498d88dc1af7fa7de15073fd4b62801c1a902b215e7cc3eac350bb63adeaf9c7594844795a9a6274aa3eca0cd10891f05795a77b30add76b6b1a35338b8156690ca2ea1c9c3b602b23324925314f726535b36dfb355225d37e7c85be15a5976a8a6ad4e2c35d4c45acc954368ba6df88a47dbb8c782336f7ea507a6c2d26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b692729638af69b03e6db9b82e678a42969fbe770fef65723f77da6437c20b203601c884a9b9e08c0b1ddbbc1a66517dcfc76b3f125f7795e5ddabef0cb00119778575513e05ac38a7901a0e8c8794685c0f274050097bc50168818a74aba5d71980f5c76279ec0214cd51efa8a21391567fa052e6dc0cf9bf216cff9287c80693645a53d71b3d7509f6a432d51b2b0aad129b594278da74ffacbb713357d735a744b7c65e482b7e172c67a5b4edabaae11222b8bb6b4564ab4fb20c28b4981614b69bb188db6056607e089f64803d89210c7e604266b00548a2ae27996196a6d6f762c27b22731f7942543ccef3856edf9ad1b1b1652a33c3e038dd9b2cd9a4612ce174315e67b26dac767e50e68508d104bbae1a2b89b78266d27b109f90bce1581a8b8888c90c1c4ea5fc1f009d5073780cb4545087c88026b9b9abddab923db52620713c8b5ac3301e8715ac39d13084926e841fae41a7bbb7912e10680a78c0c363a251720b2d69467b6cac5d894f862595072a7c9b14bfefaa2fdcc75cc42892cec6184b52962b9b73d663b7d76c1ea499d538bb45a4caecee0c8eb93bba5ec1a8c936156382b10102e3211b2dc15663412805f60590ec33dbab80d2a3bc05fa8af5145644f712e004c20f799650159c40dc952c9a54c27e816c3a6a95efbab24a31f6c402300f9baf88a46644b4df8a24979e80dc30425b9e75a753a36510b87c5fa95cbf36e19a12245876003b54d4e008ef7ab9d83c5a2406014b5cc33b6167f4c452af45084b7412ec19556d82b0a6a90c1aea60a72312d8a7a8e5060189717094ff950af2b503988964f0aa227c523487471d3bc905b6672be20bc714729b7a71478b07a19f777dec546c624723af7b5f6c142274ac5652a7c2d7abbf1171f2bdb12f1ecc876681a600806d6fc229e6a8f6424419187bd22e49b8f27486db25371c169b3f61e81131b57659b1030a959790ba5d6424580b1f588326db9cd01a260b21b8c42062b883854fb173ea7613764d41dd6b89468c7ba6c4236d1a0436b945b8b340983023139293fc48c07659b955453bba07b0eb4e2a91f594232a47c65c66e1c5c8279f179925c55ee3a0b3f5423e20a8620572a687c2b64b6ceccb5944d07107648ba73a19fdf6bb3f57c5fa079536c675ff17a6dd22439c8d968f2e3136d3000dd70c5db6aa212a63c9e16222bd39201d9b64534c87aac3b53b357bbd522660caa73b02ae4f45e1b9868ed45cbf8533720f99a1282338a107647ecc8008ab2fed262512a059ac6073264817e08332f9c8031c9913f2339169851d7b746ad9a8f2f54633d470c3376302250a3255687dee61c2625aa9cda852d835ec95c4348c9be74473049abadd65ca055239d85dcb11e6297e1667ae548664d6bb19b347288d57e3de27369a52ea25150675507cd5282cc4875fd8c67bf29accbc296e26c4b4ac813877945de0a52c355526e2404d1f262a2505dd542bf3dcca6f0121a5a45b77b419094408f409261e3c25f90689a5680b146fc6b1b76099f6cad427c6ac4281db70b34cec467ae35186d6195574935a1387c5dc795523257482a7210e1009f5337d773b2708c694359a517152168775695acba0735be594c8390c760070c4912e37ce33b3bad965205d918331371de92c27a1a5ece876015a959e96aaf3b1a60e9e77e46d51d9d85aba374263bbc65ad78b2d5a53cb909682aa0bf37d49d172bb46a0271d30716cea8aa095992dbb1132e81265a29435ef2c51daa9f27fabf3a799813e67efca087ac12247b64cc0ba15a5486245dec1648cbc7aaf40805115d78f6687c47c553d050f1e6821b368f98da22f4aa7d738a81b298a81bc43e16c8ce1490147ca83d2dd98bb918300a26cb431c99a952471b84bf6118a4d5c0a898532cd277bb4443cd7b6924c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7d31921a66403c587c165bfdd341011d19ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fba176f9bb8dc7716cac344684334c5704d5a54c932535739948acc61bd67b581f75a2169a89a11076274b10563141722c9aa9a34bb28a69ad677292be84455b24559cbbc0f347e7b36a45555a8336b8adfa07e599633f5d1bb6adcaf86ac9e7885039a3c1d308996ab6c966f017f8297009c9b4b573b70da8921a0c256a9a03c0cd6a4f72c6edb5630b1219c4a3c30d1f1586cd936e3437684ac60efa62d0a345fbc4881b24372b5692c101195c66c3ad647ca04d37f91f813a7a6795b371a574565e14779772372cc4a79c40308eb1233ed643808e939f27571c72b2f719023e048c4d15c71b3e116482c413a816c6d3a3877f862559b4afaf04df9c62d02cb364aa2adc64078b8bcbefe043bd6f32ff62b9555fab5c1009cfc102b9b4b88b8a93b66e3a65a62b184bb5406dcae7b3ab6047754bd215251ebaf102356ba688095a8c9eb1a9d8771cf60e864b7b4a5588843922b6d4a7445476997a6e5620a528510439b02a4b0de9c147bb14433db144fc9ab4b4128f7291a637b7e609a7de058a3b58a17501c833be09143244cc7e2490eb01cd292454523ce413a6e8cbb67a464aef43912b4559651258b9b812989093540dc8d202c652c71cca1eac46eab3f9ec199eae025b153348a600b0e373b7cf2620f5560a3c64c15ec85b5e81c0bcc4840466c63cb124ca45994babc31f12486f3712d22b1f649a07b192a2451cfb079ba179c2b857c41c4f8842a916e06f9c6a07cc6a4d2821401a65060688713ced4bb72c08241aad91b50bc1b968bcf3bda76a8e1b20060975e8803dd7b762d9a49b988568cc575a6d34bca13a0ef701b823296ff114efec9031d79a20f6c640d4519a1906183099926d44e88703db7636e19394b2f65abe9a8712c868697b46871d830bbc09ae02487e8d59537c3841d5b080f503aea769b0335493b84b94c4a498b1a6e6acb578201bcbae6baf0e960aa975d3f14b5179051d933c4109361f03461f265274f72416df79d1187b6822a0c38177a02b4afdd635324eb6737c11a631784916452c700d09aac42ea2634abc68bd3f41a2ca679546414df2314d57c2b318bcb98d7b46fe1b5a7e3af1b2047d193883cfbc6e7d29049fc9c97b344736a0a48082b0a145aa8776125558df656718af59964d42f0704318db88d1e91b840690b96669c8851bdbeb6043f04c017b59b289bbf550a94d0aca4aff18ca84630a99b82711a661e8b202b976e65f53b5db52b255a88692852e06bba321b4de782b5d951ab02eb27098813c98b0f7cccb778b08704a068b4d48afb30274c0759fc5bb86fa59fe61688296846b2481e18a05fb9c02931570596ec436f570c187159b25c1f6341163b79670f62334c6b9a7139044a8bbd2b5183e0f82d3b6666735a94478784aa6168d0d3272876b5476b64f7932f3aa4151ca9b604bc7fd5d1395c3708908015b0d2c8cf04858eb23238458f70f964687bb2137a0c75c06a868c3490166cf2bc3afe9b3746e40c231b3638a3558974bfb0603cf4c28c21003dfe87b3eb959dfa715b78ecb71bf404cdb2b675160138a46501569918cb7deeb0489a72a4799a1a4ac625d5c6021f51c357895ccbf26fb5aa372343bb1c516ceea47683e5a4d094a3d5188270811751fb1e19d68ef637227e491cc6387760eb5a810b387f596aa20741c4627b1c13a303d160423bce1e422d929c06f067adb7d96112f1607d3c7e43e7aa09ea248526c6881901852123f1b734a8c1891261bae6e7a23dd5296858b6f7813196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2c9ede13be3dbb0edc3ab08226cae11771ff4c0b04a564b64a0d9ff10e373e986003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = e0f53f918f1b56e14a62744fef0e1f7a5a257ffd32d0657c3090cf56234d18b278df87a8c7d06693fc38ec3d913b77a7f21dcd876225f50b2775694f5446f6e9bf9f4f3fbba8c6f1bbe1ce5aea4f27a83338d7b8a89ae41842ef990b4d9fecf78bada42a9a61f192f08d7a34a9519a2e945213b34b4cd227ee9246e253a9d2edbbfcfe2f723ab3477e3d78e73b607ecc0b644a0bd15d6559ffad87d7bc49c92cb5e606bd8f7a634a105c15051486c58e1ebc0f21b68939c998eef4346a5d3b134279bd9fdfc5a2ef2507d0491718164ce3c8e03ea769475f3a419f01ea5b2469084d8ee605d6e4d2b346dd0e35904b40933a5ab3b3c6789c9c83bbb00cf2e328ebdf0f52ee1e5462f2399d68a798ca7b04951af96aeca32135a6572dd16360b9d9124e43f0b285197f31ca4454e22ba28963efd6cb22fd23b709c509c39ef20ff7a771ed8d53c2f130ec64a02ff0ea11fc456a42f703977e26e143d8e07d25147554081c0716ff78187484b4a4331ecea813f6851531a942552a342c4eebbe85697927d90734d83e2851a87defdabbaa247f1eb12ac2f6d6fc375bbe89abfe37c477eb47cf9d00084fb97d89ba8ee77fb9e16f459591d8e230840fceec0b653d06e01de59916061aaaa72ad3240c421494af68491d4bb2dd7934564b1c08964e22438ae9779bb72f22c120eddc24676e811afe4a38b9fddafc3787e9c43bd83bbff3cbc8872a94c3c84fc0aa2b6d561349bb5cad6ce202b0dfd6e9b65b54678332820b075e659909855c24be66aba5169650439014a5334520f74a6ecb117e247b37b5c44f92a3a2e030ff60dec5b0fef6389587d623c00a016ceccd0ff7081b1346da1af19b587d39f79fbb8c5584c6c8d1f776ce8de828fd6aaf0b7bbe7074acf01a3595b4bb8bf272fdbee1556c03db2ede1713b7f4a08ec16bb99d1e3cf17afe9426f3adae028d6f057be233a0ebf6dead93f1ebb4548f8c7da7cd0c5b9c131193545d164e51785c09e1fb8314cb874d5b8b408bb7aa47d74091d6ff60a237cc9b2e7a04a6982da853277bc59fe26f314dd63531e8675f28296d1b1903c360c09b38af11d065056a38f7d7f84d77503caf4197944e322f8b5e32b6fa856e05b850a77bf21d2d1875ffd970e325ebafca515e11732b117168ee814e7064eb005a1d90e1591c9fdf9fca1299f47c137c0a57c06cfb1172482b35aa6b7d30804f5b8ed71123b0c8bb49c1ac3e4548cb7e9e30f7fffb07a2278533908713a28833b9a5469e119082d705467ba1a0e626e607dffb03ce500f2be1398fc072f67c673d44b6f079d8005955e965dff4d8af1f36ac30eb20b91c9b5663fb1fc858e61c73dbb6bcffd2e8028b237129bc2ca003c3cda79e7d885787877bb5aaa25c91386331549c553d680bf2e9bd47ef502ecba1326b6bbdf6b75583e5d7b7f81ef037c8bc431df0bfb7509024ce05b21abfd25b4aa7a68eeeb0075a0aa85f6051e8a0f93832f1b049bc5a9dd44eee20032a76af3c475052bde457046d6c64004ef10e54b501a8407a0201dead9334209e0be7251c405594087178d8ba6ea13cfc36ff083159ed5ecfd0c72e99f3ece3660fe269efe32b55108ba712c43fc6d7bcabde4875b416c99035afa95efe1ccb2a1934efec2b15a70cf5fbb5b9465e88b339e4f95b2ddc3eca8b6e55a453345daa5ec70c05c69ca36def7d9024806f7849487338b4f86ed5fdfb3d5ce83ff868d88fa0b7f09370a1963b9cda1efbbdb7e14d5e1b46b3ff008a01970180570030f6b18f689b5e2de0d552fd596c81e0b2a7569d701576f86a5b84bd3c7633777a57d1f6ef39bcc8dcc777063b1035f95713e072a920a8a86f5327914eab7d1e13f35a1459423c1225acf6c658e68ca156abec8620f2c055c125d9140442d63d95406b389f3ccad86535ddf7e9b8b4f5fc61b406d97ba20c6b550117e166fc7e4b26555139154ace7157964e0be9b3a0df7dd6332b927ee3428809cfd35b7e72cf8cef5306e4533749c38296ee19d0bd9a36c2fe56fe3f0d6b7c31f28cce14ff407b8c944b5986e7439a9a2cb73e2f7b20c3b0a32d844b7bc529304d21fdaf56a00282909ea72d44116f61367a2d2f2ad888bac956b80ea070677edc04572f547b3e9debc96e2f983e0fafde0974d6241b28a75efda0441d60dcb90592f238b77c429e973480000952a3c4fdf6d2f2df2f6b99 +expected_result = pass +expected_shared_secret = 856d56ee09279a13f9abdca14ecbe8ca9968495f09a0758b6d1c8376099365eb + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +private_key = 72408d44c2be6e83c803da2846d852dec1848ee41504b5c91f774f6e512b51f71dd1520203c486f63240bab4c1dbb212299753b8627f9bf2117cd6a83be4075a385782ab804a420972eb25bc553eb981aae7d7a715111338529f6116c10b10bbc20b31c3161d4bc1a5f050220b5584abd6a546ab51a9a10120ecc131220502697e9d61bdbad346fc43824135692204b49b5b377b870b7b28c86946077a215acaa11abd851eca479988bc69ccc9975eb42a33523c525434bc594217912123957dcdc18e410a6d6a811bed8a0b4135b56f4562f343aaec34396bb0556d7962679a76934b016b4b4bacc14650c55c3aec9bc2e85b548b5d3eb891b6596f0c44009bd0982d98bf81ac77c8da98264a719cd8568e48279df9c8e9552b94aa773b43a70742c75f041915752551347f00447d72d934bec553bf1014f4276015e0b4db77cdf8c546af05861804a5b7d92838744511ac6c8be55e883acb7775b98c4b4c9c8789aee317f8f02b4127a6ae879d02c13772a003928041c53351d8d70ce59b14cab5ca31d717f69129c8fabe46582ca5298ed156209c25bc57870eea34255ce1b4c426211f957d74876dec169c4c516c8716b3ddec6c3e610c31f0c52e13650f0b1c70124dee27111a76abef82c8fd3172d554121e6a87e9d3b58e11379cb812b7f4b95d46104934ce75c715771204d7c46aa9439836453bda709cef3bc1c9341994f25c48b5c80fcc8a67e316c431bd302b20904456b3283e9ba1bdde494ce9f8a3f0b432dca69d0ba9c43c703e1616272cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b7631822c529fa48835f8a08f322615e96b9087c71c9f262b68851f00486489d25c92221c2759c89440ce733614b8c7a06f26b374cb4f8a6a7d67da521eba7232c0a4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d09f212c9330c83990ab2db7095d708b6c3589bf929fea31534646537d2ab023887fc286f00f46f8a360476998e4fe7315f03c234929247bba2a05297a5e01aa9cc6158458e2302513274a2e3359d66126f5fd44d348ba2b634642ea26c6cb616f64a2d2c819abaa48bc565ca0ab67e6cfab1129a0144c10a003b44bd3879b4e62e0ad3a58bd86a7030be34309f3309642b017b0aa03ffab4012b36adc49a95ddba67cd81306ef6bb20b546bcc55eac2b815fb38bae991d6ae7aa87d42ecbc740cc816a3ef42e9d204ca0177cdb30cdcb870386c320ff51b137578b029125ba518a5b887d7b9050dff113468608f6335ea81a59b87cb753724ed0e159fa4709ac018a31194247a6a9c65443a35ac36e11bfa6a8559cf20e50116ee5fb3780fa03dcaa77846b18c04894e50486acfc3b8feabb8cf860d79c2734a700ab731739244580653699b51b7fc440b8cb1d6bb1360291bda5b11aeda3c77a25b40f96763a372512561e0d52848fd6a3a8241dea49c4c24692cb43aa22067072fac2dff7898f298cbae17f9ca68a132321932295161a1f31c178932004d17854d7d9c69f6640ee216747102280191a5695433763b6cf3b86756aae22a37f9f6920c361c2ac68a7e11c8f5505af2100651595bf93b2644ddc8d68053cde98863922230f89371683bddca6bc63b8c61ff4932a0885213234d5004ee9223745117ebabc5e149a5184a69836c69670e81ebb94c5abb711abf91fe3970f805b9ed7d1648361153b2911c7e20186f90907f28602672cd6c383eb373375924e832a156241bc7c5b231d74c49430c1d5fb7dbe49c6f7e20baf245d43c9b356a1be2a63ba24d4757dfa960ea61a65611cddaca48d7aa88402b0fbe16279445c8e663db1d8ca70dcae63c120df1c9bda547272c396c29cc93f0c3f002642b9d18ba0b87198140c93b55965f8c15712319ec6a95b384182618e08f134dec88732407de7ab934555af4f267051e221c4d3a0471bc6e3166bc24270efc54b5f9358d83833c295b1a5791c6bcb0610fa33d49a70232488b27150f74cb99f3643d5c6acabf5c18166cbb5ba55b4b78400e0bcb7205ea5591df6f803c464c549729faa7c9b75985088c8cff068890425cba4a2aa617c7d416b77e6c618d3f9112f3b9546a99090a1a499dc613323c0770923a917b2aeac15aaf9a7042b035f126c4fca9e059972fe92c9f4b3755648b5b2b7784d55a62e9b101a7a059cdc2f3f4b8888fc3a56cbb1447673a406c78e9a045df1be84da17ee2350b64c0d3bb63965328d16b3c446214c58731ce3c405d3d251ac560d0d9108e3bbb268c6931fc49d7b454594444dae401b2fa3011bf3c697e67ad9c1540ea945ace6c98d49321dbc36447858d783bca93ca67132800672513e577d14607cc046af9bcb4896f2bb39a0208405b3734505b239967ec72f8e8b0c2bf06228bacf834029dd123c83fa3f8f83892b504c1a11b809a9acc494c5e5c79c18401a41a6af6632c11266ae5821b3dc7c263e1b5e33a1a7bf172d6d142c79782e20ea38d6e791ad3b86517681ce389620562bdba89898679ea0c748d90a963e738a3e9968f3648e984c99f0e04c952309111396d112523959b9baccc43df715dc94ba3253332ed27cccf56f5812200e8c7e2a11ae02087e0fdc4389e98eb0ba5693cbb79680a6124074d3c998d911ae4e142296c0ca245719467402124574f8d271624315359c7842c761bd6057b92b4640a1703200cedcacbfe0e475f7316ccea74b74257e37c63035f04a880910bc042802332ee8b3c3612290c45793cfc5581b92236b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab999031d470aa948665aef9974df5a2fdd93bccb74762a0b7c2fab58430942f900de1c835c8b9cd42d521e54c434fc240add0b23ca1aaab0581ed9a593487b95a16353c0c7adabb285c85105a667af674344c3666da142049413973051268d94cea41c3cc9682b791ae17f0696df29f7f559375965f817a8d9a3297639017f5624f9df1b259412f89a8c88a361940ec9c3045c4a78364e1e06fa95500f5ec0704a365f4698b2f26a7ee348806b74e1579c2a466ccea209e515302493443f8ba9e32d04e03a7557380c7bfc83f191b84093c98aed14286f762d3b5513f996481d5445c7a7c931c1b9b52bd86e0b3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7e40b93b5108861576b3594966c40860f74cc58b9bacf51a5db6ab2d4ca43d964ffd831130b21457a08af7d8060f847e3695b8a7e8c9858a70d521908ce1c38c0713469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af944165dc9597392a6fc2068297d11c39d8648f550a7d157ec4b64c631a7ba7b94c6cd7083e21b149b484817a6f93e011a8e76931da4921e08aa604756c0bb63f897afdb8c6112a4ce21b2cc1935dc6b38b6c4473e2b0639266386ca988456ac843a1084c220b74f72b18199ab17aadf0960f50db4dfc7bb3454a9b29e74b09c410362cb8a5516e0546a3b09356b520a303e284569b2df6d263ead36ce75c82f6d141bf7c3e5b87b3eec630fa7a65a4c58676181916cc23e0c6a0339827571930bb65089376ba4bf60f4ca71d7090614f468732e60989298384a93849031a989488e144be739a78e1c49cac60af115c55a6501f010c100dfabbb462b1b3b6469c8b0d8b91061bea5da74a28d17cba84f04d2232076cc91c8bb21fbd558426f99b00e13525e37c23520698e0310c8a53c6b36192d82837ba0d3ee27b059b3e8fa1a315b64ca5159de3d9be0fa0352b511d1a803c79668479a1c3561a8ee6f7aca9ab4c861554a5b81b5e6115c952b3239595b9782fee01b869380ff09cbb5784811966b864d0414249b7dd0b53a762155170990911192e37c6c7263be626084118266bf7271356bb66d35aea64c5ea913db432c3caf989b0ec702139504fea41fcc782808bbf26d3b12a962d2b1a142c755fd1acbb802ac9b93713ee71af9d4430f240c7fcab059cb435a8373633417e79106a274882f5d40a4bd732c1e8202e41131497721792ac464b3b26a6456a9374a5520054e50cdb06a32b3973aa948a37e4798544020a7ace817749cdaaab1c7713b467a77593c034c20de0a9c71c712d6529820a5b3bb4e76202080a5e5c7ca86bb78c392a39aa37a91b4e75b3c5f2e56211358cd5aa2781ebc548e21e5351209b7a7d871a782da1306883a4b6b070a06b97639a3ca3273d1218a8000b7e85d6011000ad018527a25059c2ca252e5726629b0800b85ffe02745e9199a705d0cf4879719a53d33a95b2cccb52c1c9655419543aa146241b98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751ddff2546623aee72025fb6746fba736bae0e80e257e66edbf09d8d4dc11049cda4e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = 56211694d62ff252a094b42aea2280838c673cf1dfaaf01971185b9a4b9cf6a313d0fa2a54b11469be2f0534e3e77c13a9af9504477becb0a49d54abbf3ee8572873fbf5c9ce30b9a4c9c5f7d145993bfb146400254335f4cd8099cce4b426ae51937c95a6465846552ec9a321df8434836961a8358909ad50a976ad4ed1d699c516166ea8861d0240692f47d876a618a4ac4868d6abc7843fd371f8437dd3fb66d914006226f4a528cd96100570a18bcbcd3435ac73a7c9a05855a878be5bf6f6d3d279843cbacf6fa788c4ef800b18747e10205698d294c42e32e7e325821da1acf774dbd7ef1e10e1b143a0be35259937ba479f2b16d708d511fe3bdefb290312996a78a106d11c5d060b61d99c59b35d62d402d8b36f04ce5776c53bda2b5e274f3ed41b82ea51a48eaf990f31453fbc12772fe780f53168ca3f25931c8b4a7746fd7777112dde693624acdce62eb21a0d1d3fb1208f4f1a7b8e13a6980bd621997a73ebd1ab38e5249d58e4a3f5162163a2d992a28239b2e3961e50d741187e0383ca185f1850c77cd6ac5121d2c5a740ae2882695f46ce169a7ada95c5e48e9299b2e9f0333b9985d24ba875799fdcb7b7e784903ee3b4f1e2f2b01f8058bdde42b958bf2e0fb36c5d933c1ea6871af0a9d3f37b9f23cc6533a66a5e543ccfaec7d6fa4a8b8ab76ae0d283df21d3c2ed3526ea0907a331c4363916faf394db5c6ac6b1e53721a0e4ffe2b15803cec8ef4cb29d288551fe1b493f89ad2f15474559177a7f919998f4c3d11a5741f1ad4c1a3ee3b4f27be7217918d70a0f43c4f5a409e41d90b5435e50a24ea28776d6bfef07ce60cedfbda357d828283c50162880dca807cbe8e37c50e5925c282defd6ac28110b40b51e951d4943f53a085ad3d040a061b5212e35d7eeb25be82a6d787bc86d5aab30f797f932166f46f6b41798695a188c92ed86f5a5e934c002497d824194beffa9fb82cb6e53a275cf7171f32e5ec91755b1f083773f970ce7b7b79d9af71c970f816b990e046ef30186356567fc3e4f1fecd8e4f50e8bb77f2615e6fbbc40b30d3dc596825c26a7b91787eee1ae8c019f636bbb65fdf32df8da0883449c20f6c02d8562de5d6544c55ff8826a1ecb976e28695403ac0c89a2f009d0532fcc6ca5780b423740c9f9ea896a5659e633ee04fa914b3a2e2092ef48ef13f685046bc6b354c1b26314420354ea3c07eb63b64e4e102bcb43782864e0f0ef991ef21366acf36db469c4eb23ace9b8d9de933ca5459bbb4cf1f31a64b4246e4bbaf2bfee841c4684e005a27503f56bfd8ca08251bc870caafc7f79c3b206f7b7fe5e989417608c24262832e359ab429b9d73b7357dcdbc57aa03c3572e2d7bd67c58f6c8a1546be3d815395fd4ab50a626b6f3b57dbcf40858382f93ebc9d8db4cd34275affb174d8bceb504ac81fc5741e082322fd32d9f08e05936b00e035c0582d310c586e03615efd9998da8ba8820bd7c7ade8fb918118af7fbc4d40f4e5739891e294d392b1d4e97aacc170b8378debdd5cb75ef2a60a61685e3f83469a8ae3185f057478363da5a1956807131fecb86f68f0884c2a746ee5fe4153b8b9477c56b412a4a82ba01da89c7bc25b8b047e7c78edc83f36220d2d91055f967339bf024cf168397991d58215543fb26fd5da4097c00d1c0a0807759a550ae4139c5015269d11fe013ae15cf60fe5cb2261f4413458f9e03b1d53d874cc2ba54a21b2b91fe81d2338da088e23f190a02ffd62de52d0e618011ad8e0c83426bf590158c16894350ab9f9e1db42d3bf455ade601caf40e38f2d2fac40094b74f99210d3d671c7b801aff1023c6b76453bcbacef25d164ed3109c7640e4bc8574088189930226adb6ec7ef902bcf0ac9df59e55c0c04b568408aaee63c181b3a5725c3a4fcc9003fcedd69ee93f7f1505a488ed929fb5e7706502ab1f518a3caa77de38cf42e50e958c79d0bc93aa2de53a1c16d683d14ece2b5fbe22f583034b2e463e46bdc0d31c850d6c5497d5464a0ce78942e20f4b3deeeb2adfe210d0a2873575448a6b58cec75268f83775beea3bc1c73e80ed529c99056b0824c1cfd7636571a972178295de1d7415ed14e64f361764f44bd3f0396db4972f146ac0779441d73d7a5905e890dd22619a3fcce078ba66b2dc8b63a79ddc9ae148974844d84f04bb509fb79c73fceac5 +expected_result = pass +expected_shared_secret = c33a4432cc441b7683605c29afdecc81922cf234e02be8c2fbc4e2a7a3b4b078 + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +private_key = 548a01803a231ca63843872abf16b2c4b9ab7407a093b354f8882c6775bacf2931de0a501c5a7ea7ea5c3baa067290b9fca059d69cc6de9b772cc058470544b64b11abb77f490746384b83283740f0702e17d046759b61e75030f187c2283045b22b4f9e222ca44980dcd0a42e5704504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac0f00a6f592770d8082f6157addb170a956456c7616c856657835970578b35fa87d8f79c2ae54ad36823c6a13a4207453ff324f17d13d43a400a2102b6f6224e6f2132bb14a32fa3f10a446d7944428b66e0e0a04b204c5993c03c294927c60540f836572793c8825376332b64d109bb7273147a878ff0b0bd2808b62104515d0824c90a4e249b4ec8c0f6b572bb621b7a74089de4b49eac5a3cfb61a5d6b420779a29e1c5ae98ab30e01a0b45538c9a14ce61c4dffa27a4e462757a3bdf00c0206c5bf5233132c47b7111771daac633e22132ae82cbd616ec92b4e9d1c88e7285b84d9a12e14897a020c06832e9cab42102ab999838a93a77141d12ff068ac13dc4c685328c7036ccfc2087bd92ca5a675cfe40ae4c32b28eb770da04234a456eb889ef92a93a0d3ada8061599d99cd8a96880a2b5e440766a9c81e7a24f14c295283c333a0576b49c569c99450f8714160c4cc49828090bc2ca390094e14bd6a3011a5c038f0927fb4bad38440ea9f96fee99141c564a91f9c86dc72498f89d05b047461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a45137881c691352f6240abd2298488299331cc03b1a3106f242d2871525587888e448d0f45a61480bd7e377dd5b63e143093fcc8bdaa563264baa458649ce7fa5826e4b9b49159e7541d432143c5093a2a5bc5b835535fe7395ec556bd467a10975ce26304bb892d056a6ea4c5ce08d033e9334cf7f6750cb62209ba21f6b147ac875c3f1195d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ef0ac4b32ba7d563af40228b2957b8a95063a65bafaf86609b4bfe1127c029c2eb224465e1c178c74cb5db4c0c2aa46456761ec4a528ab2bb8f92c120a1b78a9517a29c8ee408ae7fab4fdfb1941cbbae4c3630f407a2c23c4d10a58a8e64546727153d61766d0242c5132236f637b7323905f4a7811c1b8019a808946c11a54f8ca6c16e06ad9a685edb094616a80383a79e482c611760c249988547194266000722743346d13c80f72117c25cbb48490e05789c6a5e85ecbfbc73669f249c10a12eca037dfd15994cbc450eb40868abc2fea05b5058429b6b04dce2c4e2630a13dba2bec9be9c30b9f90b45a97040a1f227200ccb4a4413c8b0c5b169830d451bc7993eb3d5b4d914a02c3183b7423d61101b0e3ac0a2a18673126f69511f27ec55e28b975e22a8ce800c37473cac71788a42cd39c26c176c9c255c4355a62c0b84cda33819a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c392791b84bdb4580326f5128556d160100622affa2756e1cbd0a0a1f217a0c198a6dc043b1c50813bcfb3c2488a5c02c79393b65f39990b610274fa77b814ba93784562e0794c179549ea0927d9b4a9e2c128a339f73e3b9d3a99a151c873c555f5e3c3fd4a59823666e2bbb92e7522098240dea1b35fe2b13e103a020e504dcc1bab6b44b3d862c35c76f29d2bae150a5959b200563536ff6cec04a3b4e82c04788977f25a6d80c7807404c47a4697b1a6ed8c903d9b71ac45962d8d4cf7b71b0f54760a4799e76312d805a9b6e508f47734619e57c9ddc93fe345818615940386951a61d83248db78b669f596c2f652b92f18f51442b23a20682a34a08cc356785b20806952003354ac7ba31a355346ca63ce8030a022ffec604593496f05624e5aa41d5fa61e4e07b76a079bd4079e645435e5058a8148bc8fc8083162b38757637b72875c6a323f2bf01c95d89dc0dd6bb6a3b800df3d42481170510e6a94eb57c3dc1b6232446459625b6f93932ba11c3b2a8b9c6a203b129ece1a76f5c067e4b3bffca18be65a3b15ac638538c5ef51cd313b1c65a08e2492037b924c09b8536134f09733f5c2966588307ef8aca7a6cc5b9c27c86bac9f9754e6772096ff68b706ccfadd711d50b4a0ed155aea72a5c370048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f58987730d4becc9de18019e5142f94984fd0a6d84a8930bec6d96d413bbe97b14138e95e05cb05345c86b96aec66babab7cb8a2ad8f774086918795c39e95ea3e40384edfb1ad3aeb931419c1219286390b9cd2154348ba19ceb280c537353b701976236414f21939968190892001d10f8ea83ca16803d2ac4cc5a96cdee3a424c935b673732b312aa1d722f303bbd5175ed83087cf856c15364958b678e74b3618cabf82ca58befa00c6462b3c963edb4a4b509792f890b228c7ca68082a8f38c388839190942fe3ba6224c4c58fec51ecd52d044400f8eac86cfa6904aa99f47712ff29c3f73b02d2127f1c687a00e2c48bc032cad5b261b94fa44649c5b459fcd18d4014c34a3978f6ca6b9d667e5d93b87feab5c6f36472492b1dfc74cc9430d1818c0cc90dc947b01d33cb0c086849f81b570a407e5248a3527ab58074ee52313e678fd5876dce81860b4b06f22768e3e26a3ad450da516224e06bfee2235f8631f2f7697e3638d3911bea2bb486667336e4072c061180a886e45144fb266643ab524ab95baed92c1324045c7768465cc177a6543376be40e132e702318ba52eb10837f0bbbc64e10b5079a24564bb950915701a06bad9cf1f0662c63bcc1ba31985149c2cf79befb710528b3f3a1406869872be1c59bc011294ca50837852f6567f6cba9b5ed028bda8aa4ff26af2a4ae90eb03c65a7f03c61baa3008480b8a006c29d6a2b52e2278659ac2faa877422a3e0809736b576564d800f5287c5a73c27a9c1e1748b159dbcbe9f566cfb05fe76419c84321b8fb772597262d2b48f9c43bfd2a110bcc93aae57531c68bb222ccff36b2e8466fcceb237bdbc336e855755b25eb4784ade55cd54b644f6404b549a2103b31a0433363337ee7e520db9a8929f607368a090fc77aff437020109001b40de05035394a7032524cd8395916bc2fe12a7b9fa2a4ff93000cfb3077c23105ac40ed0162d8fa6e22a37f9670a4c686a93e556ad82509db3aa2074a47bd9605184a9a1f82bcdd033116e046ce58a9e639c8b506cb5c17129b3079fa96cb625115ea887c11a7aa7484c03ecb793a07adadcc25e2e876fc31766ef11379738a8bbacfd46c5d53f7091e6ab6108356d8ebcb45e6ba20d36d10b1aed4c2701f6b9924bcaba7934919c2a64d340c8e9a42a98001e75b09d902714bc47252b9b15c2a08f2345b78b97077bc989c662560e94f551c3aa7834830761dbee93d343a4089c8775ec85091dc1cccf91bdf30620cc3b92c6a25cf147385d1c60a5886cfb6bee5f30bde74c579689251199ea26a15a9388cca30ad565a83ce397e07a8665b0a9286d223402059a8238137306fdbbbc2f6e4c6707534559acfb4628f803250ed8c4ecf846d8aabca027b9471e4308d727987a49fdb68a11869adf57a6f786043243608810a6353c36cffd18e1ce8bf25512a04378e8dd7a01b5c2b563902288624c25c06ea881fea70390a039b82e162f61ba6c484bd09b703a4812535427a8843b41c405c7ca0abb8e17ef4c82589945e9bec2bbf348da0219160e50c54d965aaaa4a628079eea53898778331649a8851732618bf307491fefccc7074ca2a7a56f04309e39272b74a30e526a6db5c3ffac70ce46363fe596ad5c377c7f2464dba68d42851f6f70d4b8a0b0cd52d75c48a9cd31ed8f270b36b69244237f9da28e6b0512676145677b418309d1b491cd9cc1defd06cdf9c182ef4b33610b257d68ce0b12a3f024ae0f0113ad538ece90b4a3b85bdd99c495b0fad7780fa1804953041f643183bd7083c5969255406f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d80a0b153c8b8147676a212e6ed13687941132010a83457ca155888946c8bd8506e6301f1bb78cd9a0c4ecb73eafcb2fb7b02171885b6968ab52b89109bb2941e10683f30591c322261155d0dc7b0b1821eeb75abef6023ed67e16e0ba40c78109b45cd03bbe2c800fe4b19db4a960b3d11a45392c6b088cc6cc5d8de1275f035357d3a847313eda8c1c0a65c27a743a000063ac6a89754818ef7991469a39f39536a7b70964b33d25f01b7ad9cc4fea6546f82c3648751e2b41ac410e764255782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258125b786a67de17d61b2fc0e85a13924398aab931896b6174089569f08b7260687de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = 0bad1ae220239a1b88ed57737a4743fef2e3eb585e518ecb49bb8ad073973c6ba1a7b98d7d834c3e92c0d5851600556670c6e279f23ff0e8b257b9e0b8539130d0d01a06874347450c0e6c6c7e975ca591d8b5aaa01ecf5614295df5e767ba67b7033d4cd6c9a76c86ba83b4b47497b06e01896186521eae106485a71a2291c72956d9ece08c24e7f37c0b1feef1009a5aafcf53cc08cf19b74bbcef8e739606e6c3341d5af3206da79ccb7e1a107f5bb757d79be789531c57cc149ef6b8a4139f20c3338361aaa083f8e30331f603b6537a682bb395072503b583f4250692a406eead714f5e24be6b2f8508c4f98b349140bc6f5d9388f0153b4732beeb17a535fdc623774e6a70fde45b0485c3b186b287017f9b5e977a95671b681e949c258920a6cb4afd41af14f0baf5a199840a06253b221d78cbf3673741162ce5577854afad9380d09a984d9f3ad0c06fb5947195f78bbff51c9d2161279b4aba7bf711cd7b5f1ebb65e422421648ebde84e115f596e2158d995e48e2c21012089d6065aada81ad4d2faa0e655311fd72430651c61d4a40c77d74ce4509a22fc64856f060bb6cc1d6c546f81e8abb1748185b4feebd65001abb73e9802e389511cfa1c598f4713ed5f22aced8812f972a438612975b55cf59f2f9670c92e2985562f745ae2f9af9a40968daf4112a4a2bd18e1e13a0142393f743d19ca3511cf121aac9998e9978bec2a90977c6dc251a3191074c8fcfb547a1bfa1ed1341956d0c9e376d7a709c6526fc59f4546195670c8b36a39d8df3d8674cd9f3b78c1ec2683602d7aca3726967d20fe7154cd76c6c76b122cd98ea962b0aa5cf9c451c5fccbc77414bbaeda28f3ff3a5111f4b81aae471c12ee833b4173594f46da79410714f57c89bf32aace0493d8e1d7f982c9d07bb930cc65b542ee87b4b1eda9a8f5d173ef7966d0827f100d3f6017a96945dfd6f677a71d765fd10082e0fe82749a89950c8c46fd047e310066cd8b9bd0bc75e2f7a9afc416344fd8a584d85e1b531eaa5e6c36a521311d7faf1bd31db5497662d393ab4dabab9e74e52db1b490dd42a63cc9a439d1daa854d0f30c3c2ddb9d76495e5bd2cb51466b32010299d3e0d28724ecf1666bc07a22cbf73c816a2a3f5dcd84eccbfffc3bd16a168e90c008dc094c693c157cd9dfec2adeef804df20db85f6a5c2804ef1d85721514607d2fcbd988fd83a0166964259e9999ae991e00609e6f341f5001e5fd2c696e15d64432f8e27309080565b323beaf3bb9af047021d9900ef3a7c2ba113f48efd0efae554cec4464b9edd0f73bef2994582245381133173249beaeef4fe0e3c6abf3cc0d3f709fb93693b10de18f8094989044cb19080f64e42ae17997f724004a02f760c8627c5f408d8f46ba2e61e8ab1976205266b490e57e645abc6182351de1a7618c6fe8d80ba20e82a95efab6f2ca36fc3de204cf2d63515e497d0b06945fab49c72276d292de92d299af0e746286dbec3115213f6b33f73bb79fe55f49cdcc3b04af90fe4f38ee135fd1e3cce74a03f7f542129c766532732d154c879dd363c52da83c5a8d1ad0dca006f594f187650f8ed9b22dbba51f64c9bd52436aa6d49939e5e53c24934f474e320693d7a8236b8d46483ea9339378a2a2e0ca251e5fcb37a23b36ddc495c7974b7a648137642e3e3c38471244ee65e64843a70cd13501abb2727290a7de50086be6085a98d50144f5557b9725ffe2d968d264437d61354ce9b516c914358a398c314e3bc1b259fbd2aa47bd0dcfc7e384e7c95f01c9884c2db55e2e07d75d3aa1f8d1ca96de506d32503cbca39ba42a76839e3d716eabba954cf255333638751ed5d9ac8af41073abb018480262c53d1562abf58b2163e7045579428c71b6cfb9210c10777abaf40b6135a71c8fc6f9242a818599d03093fa5fb1cff0e0a43a732444cb2fe0be143b2146d9059b57a20136b4fefa558308562594f2bc49e3fc953367741a11af45c5d4fbab3c02def5c67cebc8f210ae208aaf0e2ecbddd50449b03c8c1912ceb6d1d2af72c86d22e0fc81b58818249be4c1d9f711e034e5f23dadb673931c0ab0acda5f569ad8354bb330b11744c09393a54979deb52ab6626177dd32c49f03d08f0a56187babf6eb750c8f1ec3ff0acdb820c112087d2fb17f466f7cd7cc7b96ee22d8e3039b634456618f2537d911c +expected_result = pass +expected_shared_secret = 7c14fb353ba421705de44f2a12ddc5ad9b11e30e7b0e163cebebe2da79a7293f + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +private_key = 944ab695c2345bb67894d451ea2a5c92561a5467c769352379950879899c9cac9d05e89cb2729b2bb47724923fca357623c69643569d66912b2f9b3249908090d4c5f68388a6141163c931df430d70290950b07de410af913c0e5a215c3059785ef05b824545aba0b95e7279d1c5726b59890b82131d5c62e8b3be33b8016ba0c321c248a5293c71eca570c9536f958b84663b1dd5bb6f272c3e201f014aa3ae05640ed92200274d45d9bf4410ce8ea72d680ace1eeb04cd8b002de72795db60681bc9ecd387fcea796ff7726fb29877f895e6832eb7eb179a5956499ca3bcf3283fc8489d494a88668e6614b1f49824f12a448b31a42861190ce3a9f73c6ffa25622d7a504e0694bb7c75ee71cc8e718ce9d57ac86a11721721e6181f157c333ae098f8a6823f765b60f0300f4733cf65240c779569620213b8a331731a7b31937104becc0995ef57255261ad9b246009f855ca82af2001b256760c1543074d70b3c578279b35137e16ac2089a4c60038b8671d308964b68a2211187154746c27f59c8105981c8c7d0ad58717978c01a66b5ee1697188bfaac9b927822c940c5380409f38459f5b302cf7dc9d6bd823a0308b0da45c35d541d2346bae4173fb0c677eec26a94c4158b28d4d7b4b0f62a4ab06bae0b42208b099a174bb4c482c7c321aaca49c4a517114a5cf408750e8588545134f83a67769cc6e0b413bb800c04093184625a7ee24134a721d5fb1571cd82dd1d7c5f9103e0c2c4416cb775aa28df48643084b391dd2caf39278e9a31d2254871b170ae1b60a4e39b1f5a8473f580c7153caa1369d8e9ca381660a57ca8d2523202816767ca8cac0914c16f1cec8ea4ea5da930e0403e7a876c390ba31fa250d946a2eeaa479888011db7942f7676a120338357bca38c4c95088a4a0884b8b4c14e9c09e831f8aa658ed77cc164124cb281f61856bd6c965b6b6cd60b1b1034888f3970555443f0f5cc29c800f578806beeb4730ab9af4b9beb89502ab48761e188cb9aa95ba06b28cf4b89c200b2145a4339a53406b6790a518f54902eba0230a8c2a45447125b7330f12645d935e00651cb4996e395543b7e643137abf3df59e042abd6fa11927062d73d0a107ba6fea0908ff6759a972c11e864ee7393254051bda558d4b272e6cb2c337747a7ef46f5ac872d5d5238521c09e21495ef98b59c22961e5a4967370efc4865f06a72a41464d37ce4dd1803bc117888b681d35195c857a47b764c6799a86e27327eb0403931e29f90fee8628aa43b333615bc0f251707024ad41a24e3c4f15b99e72f536dd989c0325225dc682e3611640d99c1552506e687e18a883f90882056c14385bc08be82616d811a4fb2dc93670945b7efa17593c4b7bffb76f9a805f5230c50b065dc77b409ca8cc0b7190aa61614c528af2d1ac130c19e4362e85a40693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fdf026207e3b207613d2ed74c085707edd555fe4c00b40b2a83aa219cd643f1d83ec0fc21bcf94fba6a8262d959c9fb345f2221082c40a1501c46c55082db2709230b04090558cb6d6815173525725d8cc0bc93c881c99a16041757d6a05ac71a15e887c1682d3300673d851fa1aa423c5b76a7330ee7041e7ae96c36cb6a2ec473d83096c122b9af6a16faa56505d156df9735dd3a82681637a1747eb48a0aecc8aebdb7a15000367a7b023bb414cb67587bb29d19182948c72b60b2cdd7e222a12713f6a6c3e13c782b23c494922f4ae07b346c1d52f94682c11a0d52b584f7c8d8c740d9e0353480bfedb3168774cb1ce31331e8cada805045a37c93cbbd28ec100e089003458cb2f09cc39640774c7767183a4ae4c974e305258a8d128ac84650bb044c60311bb2515703f9ea8ad3560c6f382c7d173f83d30ddc1b637de633ff357a28ca32ecd834e4698da363ce2380ceee401eee9b31df6967c7c15e94e765262134aae5719838ce9579c8406234a9963756fc83dae5427788bf98358da8b356a2944b7d8917cc0884a2c58481c8299f194f45e33c0b30cea23142287ab15c1a429e588fb3ba32b6897d771072266096c49576ff5cc537577b76ba6c6d993e01c30dfe519bae481aca72990a39711a60afd67c1b50d417883a44e1dc24b93421041a9057ebcd8df95cd5eabae5e776ba758d8ef9c8702406afeb9d82d91c06e8a27df57be2d2cec9893e9c0a678ec02e94c21181993cfd22c19a7620d9cc494394b2218a81f9cbc743047160b0a551b6c802e44d09e52ea613c5f60940d77c3aad232f9df0561f159ffc0c88ac9c2f1109a9d89ac87b4a756352289d241b8bd694a1e140f255163f7888ad1314e6208082c0bbdd72220fca50d57c65c3b05d701b567550316c440c6f90ba50a46ad9662f99c61ad6601a4a26874e30ca1cb97998a13e68683a28996933ba186f469dc903b0c46a348a1c307ab9a9a4d427730920ae296d725bc045d2807ce2cb325cbd5f6cc216a0c0bcda1e321c5b17565ed0028d68554c892a9755643a69cb721fe6296acb64b93966a1743ed298b5e348817d62a93c453318db713e95cc53f8bef7d6a5dc2a7001473851324ca0db3052448da3136347008ad8d8b6b95a62e8a48073d2634a58525dd663da939948d49da9b12b1d758bb6f328d0f42a38837675e487403148729c4ffaa2ccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63feb255360c4796bbc99d95461b30502b42ce4e6aa92120b61a283927184931fb6c98727cf4163284732d62216b653c633659045549a40bb0c7c0a64adeb841596516bcf97e6ca33892ca8fe6ebb45e58313fda81d164193bd711ab5b65e7f2611b4b558f3c03294336043884e8b92390d11903035ed46289925447d3ab1a53802376cb2ae1960e4a7a13d0d05a58c89f5d0499be72acb9fb7dc5468afd332f483b1dac2370a14326b52467a205638fd603d835a628ab940a0463eb93814237415397b5a8b062b915c3f4278ed1db16ed13b03002c158700852837657b94a4b5ac43da32a7179a4c1a4303350652693844949029aab4222ac62de266240fb48bec4bded28213d945c3626aba1856c5e702589738fb5574380b74071dbb401696deb422b9de3699a0949e20522a3782e20a6aa2c364868ca41e7202ce8ec8bbc2165a09019a898bd4615741dcb73fdac5fc7c35503a937eefc08cf88570ed41163bb7f2e9315f0249d2bf5cb93b74627041bfb79c2b26754c6f38f8b802f28d7a775aa7cb082cb5755a195d66371fbccd1678478c462ca1896b201098d66b3991b2e73c299674bc645d2737111cfdfe89b416a7da8ca182164bd708119297283de6a1ce84cbfce07c683783402539f88b6b071213732b7594052bda614c95860b57bd5ad5ed10d8139348ad549bb573e3549320e521c0aa3919eb0978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ef030c94b2e93ea67a081af3413aa6ad1c41091364e558cd561674340430bc490a52728cc188cd1281c7aac45223a341eb60c8eab4959701aef2120c891b5ce115bf8aa17cee2a980c6895ec5061ab49dfea7431d755015117a5f0a0f200921c4547abba8bf13b5cb7987b0250c2885a0507094795f7274af995647b5b6e559275115cd55cbcdc9b988073b2ea214551752baf467432904ae95182514e39b3b418a49c410e4832d5377b95227b3091b5f782aa431a1962d6a907d3c2371161d71a9640b177a488a1fcbe57f108900e8e08292f4cf97460893004f5f88222d059b162207ad739650537bcb8b813490ca702555f134406e9c04cd54bb85a7689a1316cdf3c401d9c49b22816f47ce750aac7455a222490940f030f108086262479b8489fa00a12d09cfb5d4b6a4176fa0f62b1288c46af76340d81eddec842a548be29a3994c53a7e631baeaca3a0f8afc4412b6d51426d496d2a04bf29934f17e668421899c6690853876434e87f8f10ab52e61ff35b54227ac0fb7313d2f1c308405e5d767541c8c3bb4664c594a257ba30fbe34bd182790045bc1bb377f9d54ea8db52a945642075b0df8b2e6ac87e71177a4860157f83829bf7003558b7f35a1690920d494b4391396dd61a7f221991a1c6856f7b1ae5147422742aa0ea005fc1549cc034b9c11267e00fc32c2b3cd172975397a3647a41b1c69f9bb663835db97314468540973c339ab0cb36a19b2ea807fa788402d48dae0ac01285a8c5f3725fa674d0418bfff98f6c64c2fe21a4c6a7cae7b014277413781b7c3da207badc70aaac10e684c42940705b8ac37ee7c0a101bb3b9bc233845ef75908a83108a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ad35e259a200d16048302df38d8e7f9e1c3352502c43f086fe166325048fdce9cbe2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = 20be7822cd6adaadab8ca2416907a677ec5a50e6a8e4b3449c5e097306024a43f0e3f9f225861d4d9606860ae79c17849b4548057817d0b706c7c1551137086edff26dafa6ea695901a8f0c1e80ac82d499f6e7fadb20bc1ce9889c7758f63358a47897efb315a60df56651c4fbb5ef563fa783e32735f005a24be4643f4ada0844712b36711ce5696828fa70feb1cece8ac2521637f118eb9893ee2a58ac8f6b8d417aff015f06324e7f36dbd901312a62b33beec72ffdf22ef3cd416823379d2a3f7fb76bd010078fd0e3273b79ede7b6fa9151d5fb3ba6d7227b373b2e05d3e13f36e9dbc747448f8b59b51e5e39ccd0919c2168da6c31b909d1b3579713478be503f3139c4d451b7efe17c5481a9a0b9acd6a68c7c94a3085f3c5f41ba436e0f6da69ee3fc1575602235e932cb618f6b41d52d756d37847229ed09290cf11e54c8535cc3c141f3f0e0954ff66cb74602afb44f811b32f5b1c827a3c087d0bfd775a4d15e5f967220324260cdfba577f4fa3b560242595d242f5783fef0bf9cc217851638dc265e42f575b67576f65ba33797b678e4f767af10cdaacd7fa09342976572ac926ddc9158836d4724adc577220ed75d1242b9b5df6c13594f29c0f2366fde1981a00e253a17b2b74291453910fe097fa1139f8ab3a0905e4097443b2643de6e80bbd7613f43b36846a65fde36d934482ac6d706757601b1e5afff7e5d2019e1d1525b982fc75f97ee31896678fe45f5f9b7619bedc611d59929508e34b0178dcf93634d6cc82f6b4857d6f161399d34932d869fb850efa819cc1859f24694665decf61bfeb4a82d499823928485e4c30568433eb3f9f916fc1ad9be0d3f5257a742e85fac12ad0f2cccb770e072ee55da1ba419be9f5c6078713e535f60dd875c9834d21a2d853dccf798ae6da06334bbbc3feef8702d0f08afb0a783cbe6a64df220a1ed012d4af7448485985ff0a9e7db204be96e04e1de7eae947e9873eede07e85daf9e4c41a45338f1517e4f5f7e8fd8956609cd49b4672ebb965089ae3dba3572a45ead681a5f9ac64f7515a4719d2cbf0ea5ec6c1ca7b3e464b1deb0194ecaf02a48731caf698cf4d626fb5790f754888dd7c2b3444b3e8e6a1af286069e805d787a5f8e28bdaa567205262f6e0a8c7f80d7e9dd1cf1927576b23284eebe841116b20cad132f0b1f8609cc8a8873c85dea2000f632655f1c311953e44bea148ded0e02e5b2ba61609538c04576b0c199b3af0643ebc92c740c4e0a501b97a0034db8ec623684d0c08a1c03e41356efc6be36046a5944fccda633383c19bd19af053b051b283e8da490d31a79cf6c2a3924201b9c8975b215b368a1ecec59b0c957c2c4b112d0ce662768759fa16d7e1cda01d507514c8493bfab36565335b7f33e59baa99b9e28f722e8fab080b8ae5352883e5cc576aed084a94b6a7fd93d1325cf05a179e6ad015ac119b409d207c6974db16c2d6115316bc6e3e924c0cab592f35daf15c29e76bcaacf7a294df4bd4b47733277029c393ec3aa81dbc7cdfe3d5e86e41a67f62d3e59e8ad66cbdffbf159ff57caf059ed46859d4354405ee79918a0390fc5a779e3496c12064fc5161289d77d2330f101a2f457105654f421791dfe61afd83bc628a47cd5ae579c0fbee3bd6f158bd1997255083ba658df1663988be5239605593551886470d7dbe1f28f2bdd65cffd8511c3ba0d6a06ac6aaf3d785216f19568ba67c3986857aef636eaa696c5e50fa9109f6128e456d8af149aa469e02a95c17c7eb11211b186d7d52d7d306e50d076b5d5446edba2d531e6868b9d519760303bd5ee4ddb7674b7607625205f329552a6b1dccc79d7cc6afc6d3f71dd226b2b1ddefd6223eac169640eaaf5662ec6eb50533e9f3e6d8b550379161eb4e9f0ea0cab074b5a44a5ce0b5393748c7da5769d892bf88f04a58e50851f148b45a095b20c85e6fb475cb126022b55d12c020dc3ec336828a8300173c977b251c848262b66892d6f25010e56e323f1ff8bc59a613661005b6f73303e1c7f56b8e8c6e42e8d43b63ba1d01f5fc5a490c47f3016a5987f9f2c808902818a092bb5bb940786043ce7d4d9a73a225e041038bf68a8fb41ad2ca7f1031656e2b3073d03497997604fd3494b5ff1c0cd212d0a9704212627de2b7d8c4f0084924c28226235cb949f6851439077b8371fe4fdaed8 +expected_result = pass +expected_shared_secret = 35d2a2ab0e91d365a3e2e99bbe3f5121f2eeb528305cc7730f679e10ec1c9b8a + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +private_key = ac65af9fc8b905d09638374e58c551da08ac4ef86a8ff04489ba462841a85d907ed0c70e1a790297ab2df7d6cdfc5c6af513144da105dda2c75f00736dd91564a79668e335fbdca1c9d31592e73d60066b959a2fcbf55474f9c21bf058f021457586766fda4fad521f64940d4932b07ad8ca7e1a06662730ea6c15aa1c2f9662552313176af04fa4a98962101492566adb8bbc3ec04f9cab9ebfe5860f886d57a2c73fa050a3607a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661cd000d10d6bc31ca1c249a9b3931a4d1c57904dc6df923839d9a90aa2b93a87c44b5f82e6a925d22e679428064ffcb9621067b75477fb7d51a1d3b9d9de4051cf874ccec12976562752cbfcfc59f56c2c60b8b4610a9bb36e9019b974502407d57289726ab8a38d7a6c880074a5686619abfffa5757dc79e1449408851502beb8196f493f4a724b9d681645a07b193586c5c05d8d10e2c968bd251b88691c368dc18cf8270dad3c22bf5093db4cf05668f8c6315c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af53141eb5e7534fac4de481741e48b414302e4743789e250c39c45c0a15cf42e7b3631b6a8c0971c8a34b8200bbfe11004ab06bfc5949c3615b02947c73e7a0717c6b60f2679daa21afe4c55768a08e70105868aa6ab4aaa848c79bf125883907b9daabe367afce273e2c168aab02acd27855e2944b67b938170a9258f67397770136e466758c260ccb7da226b5a95692514727fd48953c62959c88c8784a8a52131c4ba5a6d757b4311048b602b554e8ad509b0c12b0a64553cd4270ca92f36cec227e16a217c769a2bc1aa6c356a5a39c69f4963ba6273db9232f1d8a28ce65b5b9058f1b8a164ab0380c42a8eddb6c2b8b19f26b557c387e4db9aeb92c4d7d0a2ca1e35f97e05cf590bc511ac5efb2357e70525bd027b36c6781c4b86b0069e7b89c8ca643fb9990ecab2cc5a8a5a5b2b0441076ce934d96bca9ffc10eb6e7bb093675e97b68894bb030581d89123642c1118364115a76ad1c181eed4b691bbc15df182dcde00c71f8685b71883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5057a0886d760460cc4a3a713f4fd4bdebaa93b943c48e6348053703ed818fdd9cbd62e246c0b69a265aa381822d6a474c5aa530aa5306a0c8572c413718a278194367405789e1f749ab4a02af87b362067f3da12ec01a83acec26a390cb5419b351bc95e08c7338fb933b81476ea950881275a186c9e9f99dab63634e6b7314188bfd686d74ec203b71542b62b1c0c7712745940f7b9237551467470e5b1ba2f8e34cf585adbaf980317c9db1147382946c12223c3a45973b879a523855bef121151bce620216dedc6c3457ca03951ff45b662f79a1a7a5cefe9a846dd5774c7c2a22f842e4e465a94314e036bb55a2787a1a0f0f111143872dae74af706a369ca54259b80578bacd497700871842b98cae2ac3b572f98f145cbaaf54569779b616242060b30b2a482daf335c9a502cd318296958c696f7080c7a3926c7b62f36a5dbfb87ea0518358155e8e94390b6c0f808b91c166577037df60a21dbacb5cc0758ecfb20d4c38ca54c4248e07168b19f7d925a8ce8648f812a8c5b6ff69b8994e95859d2c5cb67259787739cfabab0c1b093e690c50632f7c336fb139700d43a04892db5220c28912a59ebad66bbbf0fe860e2e30d8eba9cf21c6c1156cde0b255a1a4507e3c880b749fe959470b684e03268b43a960f3d76ef1d4c4e7266f80792eb74959a12a6f1c91cde02b8d5c14a500ccc7224c8ce3a70b99557c87b9bf09b449341118b3f998509b1ab0492e0fb84340f81f8f51c08917319d9350055bb889ba2d6ec7b5e281a9ee84ba90ca4d33014f9cec2993915c7bc094e9b926ea086d84434c2748bba95569779947cc744dea189b2080afc548710b94a225799293090cb3a6c932336003990ff766493f4b17cb834cdc70a0b209b7a1fc42ba087d7c10c02c383b60b63ce4e44bee916920156de9ab95aabb44f28bbb3f0612338b0a5077c898e3ba0f197f7f31c467b8803abbb0a82a7897e7a39c0012049788d27b70c8503c719ac3df958a7a61affee0a2c79a1703d6527bd4ae7ac89ccf0180b971854b229829c15ed8119f77ea8c7a80a4b7290b92a4bd7ed21e3b317e15d2ae5593ae3b3413d4552b767b5c264a2e31c28164e18c424a00b013389663ca580ba5b94a5e3c3a9234f15de0f4aab90a240b55b6cf6c4bf5d29ba93480014023f25c66813996f674cad2f72c34882bc441a851413560f54df40146fe9c634ce98a8a659b38d71cbdf934d29bb4c469c660190fccb1820cc365490a8a79228b79d95c3850c536f7ced9ebaa92c159e5f9a28c9562beb95d9fa000371a2670e5b066d16e5af730c59a03b8d2364eb048df031618d09e8c07781957b3d06c6ad4534149fa65f8c513733b8b095b6badec8d0ec0cff1618f5b754e71f50f3f7c9a209acbff1505a7a40621b0aa817a9f7c6a1caa1441af16606376c845c473b89bc8cbf95460192632098bfbec366b1914d9216b16a19c8cb45204379a782c203614b37fe411dca18c20cc033cd6510b649c09431afe167826576e19d425026b02f628c92e389d884a8e5975c3a3a252e0443239305e30bc6e73d33fd3b0cc63a8484721157a491535ec1918a99584808e75c26de2535227a7120bf97b64f320743338c642bdc9d02b45a29903f22ef3e789e29c4119acb125347749f373c3f4156a2ba0bdaa51fdab2185bab69801055c1743e7f7541198cd6935598cd00ab2a051667ab0fc67b9751aa6cb76b38b51754d66296d8abea1e6268d410c68412424c780bf8198a9bbb1227771114baad6a63977163fd432131f96168131cbcb536b8d223d521583e9b31e025abdec005a6ec66396d94b17436609e6205f1610a805cb39240bf3d19f81b20cfb94cef7c10bc7b3110b2231c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63165c07a81e15d8a5313552728bc5c2b7ecbc3e35975a9bc5c341a7d6967757bb7c67eb279f7b34c33f95dfa49185f908686a55cba343af19635d07b3a23d6442d15cfe58c04ab586930029d072704b546a4af3aa9cdfa148018954a857b3c8992d1c567e3b20ec300ac438b53ec808ad0753cb8026703c1892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71387c09ae312e00368ed4198fd23884f1bba5651ccb94488166943b2972ac73615a21e32ea83b9b23596aefec1785329238e210fa1528243ab9fcfb974a6316e26217d278596d188c43684d8c349d91cb43d301c961e4b51b51b202c58ddaa10425412f13228d16fc0c75e2b8eba686fe5172768378f16785247b9c6e1ccd9929a8d17a829566b640f0744bf565ea512402707e78aaa6809b75c5154dcf70bdea1cc05902bed4bacc3a6c3518d2a605cb96e3cbc5209239f4994df6b503d5f16e04562ed689a2130334ffe99b093a5cbe2282321551e943ba7c988561d332663ac4e8b367427133cd216240f659d1542e54e4ac32c42da7c39c0b5c105ddb872a9b617bf386d7259661c2823522198802be252747381053ceac84c5f827339c90812615eeda92dd38c2e1db2268a3929087480f393643d17cdec6cd059c2b810b464646a26427cee030b311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b42099de3c6d252467c0525131128b18508aac196a8b45c013519d52950a16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f5a16a98857d7f57945f05925b45a55209895b7ccd7a9831d93ccffe55a8ee0c63cc57a10a0c8f905542856594bb41359fa9f5c312ae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3c9222c020280f77b9b731514d2ba49b1b0b0e6533684fc5ef2665c25840426563ec3a2aa0a01812186021d40c4f3519da9799feac06afbf04cd390c0a52a0b687a5ef0877f053c319fa51ce7e53aad0313ba3b6a7ba5892a50cead19356d8068d1a93681833ed4b8c975e99d969aafe1a6a5c2326c4e290d65eaae1323125238303719c545202178ba17eeaa1504f13cd96838b7560c1a35b1257a1672c599b1b993a55ca982a1ae29b6664998469f171865562ee027c4644234f7e3b14621c811caab7498b204a55c8b302033219d6b2b9bf7939e9fe4523aa9cc9a41a1ce11c18fd6bb9bcaa8970534a7106199b76975ea8af98233f031a371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc95a5db7d619be642bd87294527b3f859372b279a1e6074824d9632b5d7f616e42a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = 3a0a5b632ed69517af9feeedba86c25ebe6a1a73c852db53637c6616ea2a1e77c02d3330758a95e34454346f64f88782b959407df9286028dbdad2ceeeafed8863a1d10b200b32eef145eed3ce167440f908efd4a905008cdc275a3afc61c4e124978f7bcec7bc7a045bd514154ccb0332de24fb83e37237d6e24e76a7a9ec7461397a536985a1cc2ff710f659a3bbe89fd4d3927473ecc8a11186b4457ab2a68083acfc75f7442a315d8b0b2b034f89a39b29fbc96956dbdb5651a3f349cc598b2f11bcb8762f9106f3c50db6b74fba67d67c47f12f4b82d3f6a424c38fc71ee1d82db9dc83536d54233b3ed286b996451fadd4fba2545a3d0f08e35c733a6ba865417607545c0840deb556f5c6381971d9ec96531514ae7d957b11b99a22c795172e7a948be60376dde244e9f00a5e9faa5e2870f39dbc39b863f5841020e30cc908b9d762dfbfdb84c5477dd2cd5fb920611531ef17325bd1e5b284a931c29db3ad9a544f7ebad407396af4ac31834960499c637e7a0dad0800742d14f2d62a0565746ddbbc099f2f357c674a68afa3f9cd157e254f80c24225268d6ce9338ed1b60372de9d90f5b787255aa9c9db05f424e2d8552ae24f603c54455aada7b7e41f2b46c1c6c0746191cb6a86575859aed9170787831345e890057966b5e39fe827000b4f571075475b2a157281896d1c897e52b900bca93d0806e6f41fed04340d8c12b5e5aca961135bec95a87c2221389f4e4f728438201b37bf817c69ef070f0d6f683d3a5ae5a2b1c4ad2af523e04a5df0414de537c5501eb94d954f1203ad96c1744011e027da4db58ce64808809464b48d483cf37406affe1b1ab8a883fa30bd44d8b12a4091f00e2ee789b1657209025b1dc11ab20a5aac601cd053a6eaeaddc522907464a8b7f447e98a23863ea694e7d675f59850dcc1a2303b9c60a44a9093c6e6ef3f8e57c1c43d237630eeef60d8c4de2c1ed17c05762e9ac388682f8bc22d296cde5e301ae53f0a3537f3a1559e1e9ee1ffc56f6de4df77ea50ddb98b03060b342ffcb49411d332eebc366a8cb577523b487845294071cf84a7eb9aa4ee5ab9712a2949b45729a813e35a3669726bc8c470c51b42afa1bb7e85cbb7cc784d50d0736cc605acf9b7ec8ca31e681816424abfb1fdc64a0d2b55045edbd7eaa51c790d8073bd29701e378d131b51abd1a23ec799e7fb94a451ba63c3dadd061e9e6edd3de92f279238cb125dd57237c560a81e5f3788fa70e1ba3497985bbfb8ebded19f93d658e8cd70a47edd4adabbe33bcf1c8a95785901b7e5fea98637cb4d71e59133d64c16fb2f1cab7342878035b6cf25d312997dac69120faaae39fa8ad10c5354cbf0120e894a6f97de6e091c3ee9366ec2e13c6800a197eaebac9a75a515b9f0a23f20bfc704675b473858dd7e812125029dd3c91f2d86ef19b5d536f9fe345e6e38995eeeb0aa8adabf0fc2647f71f4d742cedc71f52a85f42a6cc65da3ea7e05c0d40be45a61c0c81a4e994c185bbdcec33bf81100c113dbdb8956db9a75b629bd3bdb72412c0c321b8406264ea50cc65c4a938e29f3dbb2cf910ccb3a7a1374ceac6c412233889f3189e093c6d11b92c01ca94506aff55e09cceca978aa14cb7fe511effdd33f2a296b482f5a34683f9e1c64168908dfe7626e2f8fc9dbc535bb353e8833e9a1c8ed51a4fce122b2c7fdb129a960ea642c3bdf4d03efc2a2397bdf19aeb17ceb6220c7031e0a5159173de6d8b7cb106654b37d669527934623f64d2bbacd617b708e6d1770deb3443f27deaa55c3e0659a37be0ce8d4cd87771f8d6a59e19858f0b674a2b7abf263f2d4e821cc72581e5a07f72b5295cec2e45f1c97ab33d174ca160328b0c968f69d2f08a1d4e37e6a3f36ac18d0ca50175ec38cd38d546815a2911571556fb7ccfbfe9b1473ff91c833314b773e8ead462227132979924a20010fe3b702023777b79fb0f3d413f2e3a97e85dddd1289c76a1d31fa131d0b75d74665336270833516ace2a5774f10018ea505ab947a896bed114ba5483b69ebc9cf3a70a5501451d9138bdb63e2dda78b1e1fe4a78ac7f204a5c0d40d6f38c17162d0825e0b358ed116717ede8b9b8c79694930b5b6d22d661ea42a22c9ac8f99937a77a22d88a4d55fd69ba328e3e96fa3b9e43b95ec0f732df91e245ebc0ae0de65f1f1129cab5aa56137 +expected_result = pass +expected_shared_secret = 8084cfff3d54b7680e737ed71c37e449f1f9d74bf6735696c46910b13d42d1f1 + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +private_key = 67a93bb27acd00c9b95aa03552809c38a08480dbaa67a9584a460345e20e5f381c9a82710ef1709ca51393f916345719bd3144b3121a8608c0a48017963387f7a31c5febc6b6749e6bd9be3c58a9a77b53d7762f5854a3467a85941ca2c03873c0458b940275e5ab85b83a5c2027894b92246dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451922761ac274b5cc8569ccb93917a748e93c190320e3f1381e08cccca70903975ae25689c12709c8e9096b16a26e4439c2552a088194368b36efe3871a6a1cd54ca0c70974ac936e45dca01de296a14c7d20652999e61841dcba6c0171fcb406e14a95b0c02517447bb9370996176bfdc5beb4316c0ed34a13431e34ab27d9dccd3ddaa49d314659bb8d89325099d0b06931796ce65c0628c817393bb1870f19a10cfe3546d8bbc2509058327626f490a1bbca6fbb653ee1c3555203353509ab14b64cf8a29c32b17096805b8d751848dc4494279266f2cc474228b2b703cff81f0f29152f4570151517995262d705afffc08dd413c12f37b605bc32ecc1292b9ac99e4a34f911c8db990ecc9a3dfb37517446908b91b1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d1929e5721bfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c8b20b3ec750b082bf2cec89a6f8c2881650e5b71a0135c865bb3fb12a4c2c3c917d655a2997984c8557ecf1943436a9fecc5c84808e38701cc26a251f458334f59bd40bb0d8f82e74071a5ae3c9439541aee59c6e46a5852834ce5712b3665018154c5339467d606af189ccf20c68c583c96d969815109cd3ecad4f5ab0a8bb8a7b68359b0319078a7405821c2709a615864422ba0a3970c8ea138ffc1522b1a53ed1c71d396a0ed6b782c6552c70216679bb4761a600634276d553cd703897c6943a859112caf9a7ac99517c23ce6457aa069b6fd2775efb262dbc27b02fe6923d14b047a25cdc6b86d20a55d85108ff276f121a352e098e5d4cc3ef92b3a1c4a38244621b055d5f812189f6941b492330fb1ab0a442a656655455b38b522ded5640cc4136df6cbf4c4b0651531cd8c95280e2af13fc57c977bbd1a8bdd253096ea98c3ab33a516448a8301a4b141ae213bad2f640b2d5846c99a25884360f604333197816ba9dd1d0c427c5b8d3a6b434207b8539ce5092ccda67a755d6a6d7e8bb6bb02af1ca7283e797f24a1042d29b64262f29b0482b840bd70a3d6d54205df412dd6490e3dc38c1236758f65e461b11ca480b476875c692508e7bb90c430797e1917041642d88506c07255aa92ea32508462c2f4a1661c05114c9361f651b7c5ff70b42659ffee71f58cb79e445536b8948142cb4ec16cfe5b21da659c2dce452346323f1632c37f128a6525f40e03d6c073e05476252b2b0483c4b87c1c1fd8c972cf651eb9684fafba3f862c8619c089f01277c14be7cf7790712ca1e8877a48909efa31d814c1c21f4a151b886076840546419a1c8b6ca4466389a3f6dbb69e8494d7b25a4e9b234a8d928a26b946ff305b8a33b0bf8b3eb992d68c312b4074788e69d1a5a211c3b55f8c654ae778fbada1d75fb23966a42c4f189d861760f7a5f30f358dfdc482014c25845706577763ba60ea00a378daa1b0cd1c15c5c04bf847babd0ccda7c61b0a956229bc992029dab7b05923c5deecc595d766c0040946a229259c75e9985bc0519218df44dad36abf20c2baa92c3c34cb911d77c0e7603e8639fd2870ce0f6bdecd193c8c261c53a9ec8d4767303480529ae2cd23561c9215476c617453274881092443076e731a459cf603a7cfe81804fd1c8293baec711a694f98f59d01cdf79827e777b9e452f0a388a7e7cb83ba37676d2b70afb02c7cc0fd2a05411f41732233bffd8917d9726657c68c4e34f1983b6007b43ceb87a6fa033b3c674a090999cc94a4f2889a8b71e5228c1f92c16db841099c57a73005f81a5cfc97a3a1bb6092ad60eae139d9bb174c9591ae20c5db48390c46bb456e49e124559dbb230cb6b5118078c8baac9e959277aa55b521a351bf34f9bf7b18dbb4120ebb60c914d84a80123f338035520620783824c676175cea40a812d896839993c4ce211118855e5349e84c8604d1c85202275f93924ffe79141ea0abf85a4c970c45e0acfb20c426cf545caeb594907a23be6cdcd38486ef2cc1234054fa47c50c629657c91e71103c029539e632089461effb67a0f8cbe74b91793ab033bd89a2a0a68ef390ac90669aec42530c785ec3a0dab424c8184bb051780b4e80838539c81a5097d42cb854cbf324a26f3cc65024a6404cc2a335378fd10adc8e10cb99c323ddc55e70b32a06cbfab829e53aa059163c46339b7fa1090244a358dc647d4b1783b59383a0988ace605ad979f655038aa422981ababaa0c2f28899a352572f4f6515d62649cf88591ab7da91ca2c0e44aefd16ed3f174cbd0bedb7736363c609eba4655b2a31ba20f05e412282b28e15125eb212596e0c54181028cec9b106849ac366f62e8c1c5ec9502f01ecfc1749fa3bd7b251b2a09c731c468dc2988f69649fa9b46e9d244df903ac9004f09cb1dbcc9c69b33ab9e928fd2072cfed1186f9799ee3c2ccc2b68a3d662c7fb4438240d6e0b70ce98478e6c28294047400b9088eb4aae3a5a076979af8ab4234164b0846a9904ade949742d7402c8516ccbfb1d30581a288c9d1c69360a2b06b21541382ac9b4101b96d4952e89725258cf7fd33ac4f522d12b6f65b884f33a0a4d1b0e41d660d0861beca59164f8760d3274d6643ef7d13043d63a4cec67961c808cd64b9728872f74412b8867a2e25cc58174653b2a1a0ac0a24316f4c14281a0a739bab2de26ba73c4921c50b909d188e8b3c4db1274491c792028515930ad45e667c9e6870d204554556bfff44d09f95fe9dcb7370320bc6740f3053ec5b7396db400ac671b01f33dbae59838741b59e4c7f076a92ce92c5213adadc47c8f50bcd4756de7642799d5477967339e01455e6898d2194a7aa724338946b7db70608c0337e305ac876f3d87c6ad857162e491e469bf62c26285f9b817858b149358cb67248a298cb21771f1504f4997965ea38036d274ad72849164262fb58f46cc96ffd75f23b4a0c990a9d59160e4365b07909f7874a22ef1362035312f43b6272bc47eec6ce9c0b4418b60c5022502485bd92730ee75a9bb4a8c81a03ad4b292f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe274c268a11afd003beabb50d12b8550eb3008ddbca593c7bbdf6768fb561ac452d32c77d74352310e4322ee53b9ba879d511368b445df20aa17a7ac8f205a302f75f3c679557f2a37de221cde6c8f7248e73ec25de603afbc5baf1b076dc3b304550c198b6b49159c12490bd964b661e6ac0eeb2b09a78941675a2132527d0016d89ea6b3cec5d19f1818e4501134947a547957a195807774a8c40a9c50833790aba5628c2eec2148dd0430294b331235d4246770c293046a237f03487993043573a71f250090aeb01dcecae4b878633c59b5403abb02151d8048dad408473d63cdd018d3d295a46ab556c8aca53495683976b2186c6c818b852005d20964cdbcb6061a50910b9c429ba9f10a06f4e053c9e1c4cbeaac35949c8f23c3e890234ca990b2bc890d43c2a4051aa058a402b7caf4a3925f52c95c6b6c7d26b4e3d43b21d7b0fff3b37e5d33e391b5e617785f52128c581969e094d82d062a8631a76b093703626d8708c5f310abc1951ee8984bf858a7b582038a6a624f5921257764890b73cc9af94e5aa82d831f341486aac17cf29ac351483f7f26c80111f6715634ab69ca71a6893b13bbf50cf58c16b29d6b7c9b58fb3c0b9295a6320210f1db8193bb8a57889a28ce3b196f32cef048a4d60466e3857c07847e3883c1b7bab89224c94fabb3fdb921ee3c7fb716ae8c520d547b1ac49cbad256ef43015fbd722b8b31d6db24937338e6614402d9272ed014710fc5b0a7105e6659de2513101b22c81dba972fabbf23756b5d524d41a15b6d682a1894e8439b6946c64d10732ac603992353f03e61c1a136011b52c624b0943a3464ee92b8a7b970ab5ba9713205e4a22b6a12e063c35e8c65470b32f9e29255d9847de80cae1091fa536213078bba0181fa33bad7f3003d2065b8d997a7207b595994e816a1979ac5174137ead82bd88295f2cbc77e01c0fc9119ffcf25d8f2044a16aca9ca052bf917746109320dc076e1895399741ee690702b477a2d07242e03dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518ff0d1acd4fe1bd3bad938c23ec5a7f320766e01005e32769724abb4ebac578def84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = 5f87f10c9a250dd54145314983d0bdf99d7c5ad004b950ee81798763ce02525da39e2fc6c3b09dc64287954539c76011a7a087e9e387ed105a17f478b1dd601026ef979241e53fed94ad15c9996fbfd8863c2f2c2ac100529acb319a0be562e28ffad82ca952774ac27f6cc8532ff3dab15c6dcee9c1a670f0228fdeaf5563ce7c9c053ca328891cd49e494ed4ab9642707c67222753c82e7255c1778fe549bbb334d4e2015a6ad18d4c6552f7be3b545797a233fbd1a8b57771cc1433f298b758c43354f0a6a63e399d958dd8abe0bc4a6badecece4f7652f1a3789739b20d777b7e606751bad09a18d5fb17383b677feb6c99a3b7e55791af134b2942e67c6ed6b39acc417080cea35a9f70ab9745fc329986fb1f5e155695307748b258346a6b71fb46be707f975c91115688d944a2274044661bb803e4ab5b0cd428a080fb023e826acdfd70bf66482a1cf18d020079b65314c5070b9394efcfe0dfae0ead326d0124d1d8b80cfc3a75ff7def710f7a0b758981dc0a385854a2556cf9cfb1194efa38eaeaf80617398c3208eefc0ad72393f6a5ed527806d4b8221e96d73f80ed1a421aa308dc4bb9c0c928757e9915c08b0d21de69918953c9c7bd0c71b36deb4d5939d798fbfca60b30249d8c97ba3c4c38d57f31fdbcde15427abe36204e34ff1e1690f3ee87a7ba5094a2f45940dc2403cab349808fbdacabccf6f4afadd798bf1ed09d5b39458a0d6e279b08e5d046bbc2f08e3ff4dc97f4f78e02b069745c69606f9fed93913c3b7c4c744722edfb9ab431b05d8c2e3e3ba677326b0dc70f07c5a519a01eb18c8df7e4441dd86c1f704ca6aa5c073101ea2c64f36620c5d692fa60ce347ab1c466f565142cf19d09926aced32dc5f1127d2baf35a718eba32c9666e38b3496a1294f28d3ceae78293cb82c0b7755b26cbacdbaef00b32460f0e1fc898a724448657bc658d6a847241f20f14fec5a7b8a9d7c7b5491d2e05cccc0c9ba11e501e51ade82e4582db34ced28171e68da79c7e008d5a99757b9cc1e9c99fdf6f919dd120435e9023b6d431566291329037f802ba51ced6dee11e10c762723db6a1063e01ca2222d604b78b2dee4f653a2e6e2d572c2cb934c019a5c12e608bf39414db933fe7e7d2822f0e4dd9604cff7326ed0bbac843e186ab1826dd3a76ee6e82138ced21b9cfd11d4da585634328fbf16930eb70e66ba11d2b893c63430bcf3d0e629d27f7b78478da35a61e81bea0d4089dea702fff9db2b9b7600c1080c566411128f9416e61a0b09828cf01054693e4624b1a3ee03589f5729e6c8a73fd2104eda181ddffde4daea2187df8f1d9843123d906cc847326012a1b6a465b0da9aec135b5ecbbf3378e22c5d2b2f9266f8f0537506fe45397d97721f7952543a105b232a5bf705bda55d390d80e8809194f7d3bbaa39ce2ab2c27bfad073c5801317e11a44c809c23126f1ebc6f3765a331f44c0fc1fb31e315fa4471cbd2e21c0937ba67c71e801239035da9484060f78cbd38ca11efe0bbe9bfd5a7ab7117c4b49004bef93f9b37ec78013064c6d5aba18ac380cc27c02cf90f6745d01f4f9fad5f1ff3e26d01ba8ec7325e06ec6171422147f4f52def5f074462ba28dc0f4997ee46adcab9dc62a50ee400f1ed5c2ea22dd25eb92f8557ccd1b5bb0ebf01a9561e551398eb4a9296c96b1e715aa1e223d18797de63f6f38a049e1e424f295d0a966789aac7d1b487dc51fe612fc210b768cf09dab2e0bf095fe3b420d31c7889bdaf046152bd0c268bef13f14107a448c144f75b3d4aeb366da3dd67f98766be43735d5d93c48e59d51cbd0fd2f6356d791f0b82198615a2ca0a1468a3c497da5a694f73eb90beceda55b34aa410a564c3596cb5621cca2f16f5043f20635b602bea75fba43e3e950cff76598a3cca481773b09edf9fe224c3ed588256dd49eee5dc1abee4cf6fa83f33bea1e8116ef235e8e540fc99224c9a781f62f16c73f7399d13fd9c44a19bd747e73eea512e2bbc87c8f8ead1eccd3f7888f67d60cc5dd8c601fe39bc6ce85279e63fb738499a08912e5895f98d25af90c8f0396e6f9f0221854caf8156ce2f231b38adba6e9ae1c1afec44649e859227526aca8f4139fd45e105f5a1492613ccaddb59f9b918c799d3b38e1b3ccfe50e10ee01dfd7ded945a40d76ca4643df86289511138cdfc8fe0141 +expected_result = pass +expected_shared_secret = 3e94b68a80291e957f9dd0a15b112ad75bfa07951ccb36c2de610e6755a4a0d6 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +private_key = 0fcbac2fd83a9eeace0215c784e20260f0991b225897e94ecf93368b79565b478731537eac74550cd599d5268e03a25cf327606686ab8864677907a3c3555018b478fbe125498652d5259a31c2b4649c14c89bbc5758a9b53c64e95bc9ce30c306372d431cbc642c0d60e25136c3919f3bb48b280b9d5ca0b21bb4e1510ac49aabdf02c9fd66420b475d0731918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f5604863ba6dca297ee29238ba79eeec5096e9b336cf0b24dbcc9feb8bfd77ac888554472d7732e7492c231302a073680c684870b86a05592355baf2620b51ddc7b17c9328d7a74da6367d9ec2b87e9221c297b5398cfb55c10e8a68323aabbed806c2272c192fb180e7a5b958a02dca5c55654a43c74216b192522bc2a2dc05bf865062cf56839831ebb837a3ed8c7368c15933730667b7463ab7026848bc9ba14616b2e88e17aca4109b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895400e245df8a324899273efb441b564305ec48ab305c69d37e846ac9b77a2917915e82286ddb397936769be7e37fa7f27a003090c7f2b9b395a41370b5a38c07c2d8314627267fa06bfc416d8ac1155df645c6150bee70c4cad8c6a5c564ba2571c9bc9bfaf0c2d12578c8198d49e1414cba5749d712556a537a4131f3f085f9047735482e23342b218101ad30122113060cca4196f778c77cad2ee58b6f23071a85b79c1215f0a7c8745abcdb768c3c26042d09a9a0355a5c45745d1acf52c205b949acf581ab75cac74f2364406a43a74269645166fe167642900d169a1e84929da4cb361e80c42dc702a79364f1d664528b6cec667bf230078af06a0b48466dc90b34ea7101512e37d8ba3a351d7023aee652351ae514b8d217faf09a07654b0cba1850041d7206cecb05c8f6703f762c97dbf82255daafcc3608e8891e3ad8b3d4e18dbcf6a1c2e74cdeb87d15236d70943daa722481692890a548d7c69a14fcc1155202ca4941c3900b57a452f281091a94781c64a9583c8d302c21484cc6159b88a931aedc4291e097982eeb0528c152a43b97dea2a0b36922fc60c226b61068c792f377b9f655940d73702d41bc515086e8f9266c53a4c15a35907cb2fc2a2f19bc5f974034677a33b648322cc9bfcc6b947b5346df2044249623e53430895295327c9b35f59ecd4a9521f4b93a4c031a624c12f40ba17b9f36908e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b5640d683b7a45009a1efcb5e50a35244c9431f21f1b6826311673832ccbc1794fea917268f5323726698f67bdb41bcc012218929649c972149393845dcbac7fb58582964405d4adeb814037a39e512c3fcf72a22ab70e21fba3822b493df9983866412f0439e1a613914042c982739031949b2780d8133e13e632fc4281de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09e304210d5cce3ca3dfef261a809bc5dc44787a20afff49f3e0156e7b428ae1cbd3292c9d818844d4767342708e4016eb9bb0f7099876c26729f443e7cb3b9666441dba01c8397953f586e3da4572ac12d00cda40b715e50422849aba436c1aed529a50a2448ad772495c6358c8050b323b6636871e092aaaaf75cc2d869dcd71e870384a6c2c51000cce0515a8c2459f3966c853749d27809905118cd897fe04a76f196a98b71a5b7405e72e9bb7b3b3f0638016bf15d45e60ea054834ef3af6d2817b59c1bb5740986d626fbb8a98af56ed2ca9828643e3bb604e256b6ff8830606a68779a659962b7837bc46fa9781a1a8ae398ab313c597a4b7070cb1b7dea82a6496f3d00adefeb361c980691ea7d261982eae4b80ac5550a91532f81971b05908dd84ba13544d2f00615bb9ffba14fbd4b6a5ee46f5b6701f064a25dcc4a8425073f63ac00f41a194409b4e12195b8910be7848ec8454da99c0a0c839371a1907183bbd926fd8a107e2160aa8443ace7c77743c5461c37b4712160d5b08aec019025651038c7fa975a261578a82865b1d034a7fb9785696ddea901b1dc3e07e18c456b85464a0a04d91b56311393f51c56f4763aaaa4daa788f9e631b8e92660d2850b738686706531f72bd5ba702b276804716279e61c4b3a599005270578414141c09d070d9302cbb10aac8b8483f11b1044cb83efb8315ff38feccb09d1775e1e29c59b1759d894ccafbc147b228debb52e83d2584552bd15b9b18f02ba12c6669ef94190126f6fe364d106a9d4762522f25a0298cb5e40cd6b89045f275456e8bc32e2c11835b31e6aa628e50e28a9a18226c73343479d0ac61e5a81c6a38c0506477e58001b6890155c3a71f21e1df151660c376cc61d90d93331801b31dba89b6853c2630d33578551399164db647665ad52f912831a956b8ab283f91c10209b0b055ba765cc75587df545b670ea13c6b917393666bd6a9e07a21ac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837b02600c03c9f8f1481414a241766df430a6dec7936db2374eba1dddcaa58c8a2984094c57349a78102a48e48c450ca7135a057eb2858a6176e67316ad21122c44643fd42cded7caa55a628a503366077058b286aea157e540c598822c3736aaba5298a41765fb949190977456e1b5c1810db1301342104b9526a82459a0f78b9a7e74808a49243a0902d8c6485f887ce62697a72474a1fab0d1342d5ab7a8d9ea38d3b129661c2ceac177d63a59d5b62be8a11379a51055b36ef78817b677ac30f05bd38c700cda17d52b02e8b19f09354ae074b4365ab379667744363b9d4ba17c061ef955631f1ca916a74cddf05160b82994c49688d71612676bb0d95f6fc58d92970fb71c3c2a250b4161b32b3405abd605d0a94ae017bb28801ea54588bbf0b9caa8cb5920bb02730454085871469cbccbbb26911d934680afda6ede5b29b0e4a0f9b15d13392647ec9ab1922943c88dca974af1c95d01866e906221c901319e2bb4db5807d3b22ebc077834c29aa555226903a4b53c7b5d29c226144095e03a4886a18a26b99f389a71c41849f10fafe816d213be109ab7ed104114678d16242547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fac2d2405bef464cc60c58efc595da6c1ada9200d8eb1631f119e99b38970db26be02333be37e661c2bcb483dd1156a7e016dbe39af9ba9a7a6fa8173033bf4283e5160b1b2d4914f453bcf3406304859205118c6056243209c87a76a7c3259258786e6c64b0405bb8ae22e33b1617bc9815bf57b182748cbc6c4e8cac9a9a22965e560fac66beee32f7b8248c241cb3213194221c704bc821185041ae5510689a8d7c4ce5a6c3720e9c845116d2b3b9de703937bf500c9249fd3b2b134998ca657562b19857f6acf575264eb1b0b27d50049542d3f87041ddb755cfb340fd122e4c46663a7b556921b41b50713d71cb20a7888955689fa4e43172f134b1a2b628119c22c391408b16092cd6c8fcd6cad8ef34e129c6d5fb8881725a3b8180a14ccb625a65ae7c59f8b7888afb126f2d8ae8457a273c453cfe69726d951b3a241df583af9995dcbd73223884560258459d0bca1e794c94214276547d3d740a8608c33662eda195f4e26b90d86955c2b4c8470592d1c075bba0fb49b6732b2954fe76d0dc3b3e840865fdac146f03ba0f336f0397c6fd450770a2bfa5837f46096d3c673c562c9ce79b5e978c2a40450ed36b43210386a769de3a9063b93455b694c5cb3837e865ae61b82aa96661e57c41e405d260bc7ac84cc0e1c7515c47c320c61723177f0f57f599958dec24a3f81ab7f1b759c61487a243ff13790de540bbd1b90af233d8658b2805152183bb220e1ce017795ba97753e9c06620a85d4e28591aa6c1f440240e9c22a9acbdb568a98eb745ef435805cc00c2722b0822c1a88b8b80cd05ad2a69c6a356889c2389ac128c49d627a1f3c844ec85b82a405a2e1834cb753b415e32629b7397713aac7c70ef01a7bb3db86ae13b4ed51cc77e2a90de08c77d6938b903e05913477d1c38c98a80dd034caa3746018bc32034b27602732bb0a9cca9dabdb795c6bbe181576e69413c419674b646386b62c0eb8251572a630b087851892bbf726fca0b7dd8a170f19100d6087c191ab56f066a3f61f973c47fc62c331287dec02518039b32e7c320376b0fd82788e2a8ef38b1dd977889c2712ad258d4feb5f7426a4ed147e742b0995a97c2ad876e1860aac6ccaa82287edc68267362ea53ba9d0d91549a448fbb43e3f90802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b7008db565f7ab9c362dc38dcd3e30e5da873c559e9a9222710e8d2e7f6417ce699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = 8859218dac402d756e7a282c88c77ff1c320193e436eeefeb6ed478ceea116b288467862926d741ad4b1074423ea57f8f1d6a7b751e34f88947d5c80476fcbb5385b8dbbd21ba11a69e646dbc24038abde3e8ac75ff1ae80097010ccbc99dcbc7d220ca8f1b5580e9585a0c193439b6de6d9d33379c24be96072ebad553105a3041c501483a34b2e27d81a3ea479b18df3d813db7c08d949cef6ef74daf1a96e2c2fc3a92f1d865e352f39e7a28c55c81acf68d41552c4ce3079ab0f797ee464eb213097cf08565bb689a4759d3dce560c460c2ea3d0bdcbff0998be2594f0cdcf25098d70776f6460e4f42a17575821565481e3570becbd44e9402b3db722bb2fd9bc6ff99270e5b6ac636346ac846e1e24f58d4f7d86691abee15e29f143ab5247100dbe772271acc19d263d737937ddd4408b6989364f9605c626a1ce9a5155dfa2719b0235a1d6fb3c9eb231f4144a114b26620574d29fb558d3b6b8e5bd07cf0a86905ab3846e56b7bf778279fec9768d6747014400b2b6641292ad225d18b23329f126c3e0e018c109760cfd5643f1b213144fec5d69e73ecd2f3d0209537473b92b35f69eebd7ad649fa435669da9ccfbac5f6d56cae98c92d2ff71cd08e4f7f2223290c9a2fa06ca83438e0ee184df2316b1b626c2104c68d778cf971a3504b38ff77d8d784e75d04e792ef0b54e5b933ee027d5e0015326be8618e35675949874ce976d39bd39080f8c9d03842e7dfe17e630df0379baf004735009b86b631d87f263ac14b0c018da9de19b24ba1b455cb71a4d4e88003ba9ff5b26d02e9592c55afc7761d98cff35df75665067af96f7dcd71587701a31295498c81886c38dc7e4ddc8077f5636ccca01040cdd9b80352cb638626c7a183a8e268f60830e24af051179b2c71fa9c41b61bd3a9e822ff619434e4a3b582c6e7dbfaa886622083a1af2e8c6e2c69762009d846563b82ec926a4852ba381e6abdd8e9fc0d29ec6b337bc71ae6cd3dcf9d10baf3d5dbc44c1ff54993b736e6fe3bf683e68a2634a77f8fd2297bd02366c5dbbcb80af4696b2ef13a6a841d6684b3fc127d9dc242c20d3d305db264555892e2ea0f9aea511c1308ecd6a4df93f1e8cb66e02f8c5a8ab94457bb656693c068f706b6205b729258b69561cca577ea435106487ba79e394a039a80d7f1f8f1bb16018aa28d0e1558ca9b9a52d7ba3465d93cc4fe1565b24b8a179ef08315e474bedf202657c52e552c6892aed26403a7b22c45e657ebe229f5fe6603462369ef07e82ec7f3c74db76de728fa92d9f73b7b141b4069eb3e8a4be72da94b84edd23c4a4682d2398f16722f17cb28ef635983a8f60276e5f2070c2da3525eed47449671663d5c5bc06e298d1b1ca5f409a336292be5c666ea295ed55f1bab1e9b59216875bb7abd34e2dd18d503f22ab66d402ce9393ae077028327d80973b4b11b1afd6975b55e41e331b127ef2f0b8626c5e0f2c83067309e15551fc5a76b2e353a702ac80391f84ce87d07ff77a4b7c528137de655d951d1b991da763a3a1116135c29707e74f29ac2b8d1682c1ea01cbaffcacab644654d9ee7485d41dabfa19aeaafc1f2b3c650c5b065c9f8a9c84d786c99d633607e3493da11790b853c37538fef57246dfd0605cde145e25d3b3d13441f2f3c6ea5005526e7c7a514547ab9bdfc40e46b017ce4f47aa417101b6acde4f8bc7891fe9b63b505d9d259ea0346253531638e35f5e992a7c662e96b296c91dabe688aa0061872ec39889451d1f8e237bf7cab21a1ff87503ef9d8e84b6cfb7e88661e38f4ba121135d2d9433e46d51a6b1c82ba8827cdc1c79b56692b03b3761092b983906beca37a675c22b2f11dae846880dc90b91efc690b1819743c4952fe9fa494a3cc6db7b056e04cc2b0859a869900d90a38f2556a09b7c0b5e8188e5415547f8ffccd7cf2b815e6117a2a1a5525a6a385d1444bbea0fdf4b889d3d71690e04df0a19e3e2128aee9634638da69bcb1f432e2fae59dcb23106250516aadfcb71a8a6dd3a7de9a298e581a7a0bcf2a7f12e1a31c3e0f806cf4836d1f6f93fb0805a433c7b311dadc784d4db480dd755386ba4c2e80e9c37d77350719429f5b6755681ab3932e8afcdb61198c95b46400e3eb893b2ffaaa5171fb4c94dbe7780777447239c956c7689ce17fca998e1e1ab4bde954f63c757f523487397 +expected_result = pass +expected_shared_secret = 900649130f9c28082eab5ce3d128593eeaae89667d7fa4da23fcdfc1573995fa + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +private_key = a5c7981510819ea27d27a945a0f6619d730dd196b6f3a158a4c48acfb82d1c348540160b0cc665c43c4c0e4567b46867ced06d2cf228d0b64706227593db7392395b7ea95360105c1bb05472787430654aa03b6e894c2add2a0467ea51b9486f3df18274c0a2079459df3b9aeab15d203b466ea426911572251b0c8fb51a31aa142bdc4142e393d3c527c841a03f796e0cf7cc71dacb47456fdd386527bccf6e43013eeb755924a22e3a55f74a8974b38e06908349fb3da5887d1a041c8acc6f07a75198462353942267d7600d5243095bb012d2a70be0a3fb2bb599832f8aa68652846ba501bab3aa574ad08bc991c8b86717b87a45041657d0264f35f0c2b70324eac43d591202cfdb9a7d357489f70f86d6308d3382cf9139106cb28d947ae3bc389ef18b728c1568436b3ef80644009a80f01ef550c794011e44f2812ef507bd55820a872b90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2053c037b87c51436cc83b884f7634a6950c419684af3b78d41006467105f753194144539df45ac7fa46e71815f53d2304b474a434b02517b083b058aed078dcf86746313bd8108148ea34658613560ca722a126dda147af8c5733705bc8343331bacc5b5b80e424ccf6114955056329a68a2a6403d65197c21da02a390c41ef713a814a798a434145b9e3a5c31a9614cdac8a8bcab6b5274490f5c45b2a307f492c28ff40ee39c2068a5826e8466542559e9409ff11b463e9a4eba0a2172ec8ea6332d3a5bb66531b670c52cc2f8b651b513e60a9e64795369e0c2cf56a9921669299b6b5399537e112ac358112810abc6945bde69aada92552a10219a630e26e4ac7d9b5c7469a960ac64a6d127971296c53a15df4c847d061e69cc030b9cabc6e58903c5adc88882cac147f2888263ecb6ae97a9b2aa245f131e2e2939f5c8bb8ffc012cb578b9babf90db062502b1923ca88b35c424fc6524128fd1d7b5ca719f5a9a538a51a97ababce07b006eb701ad8490b74462f93648fc39a2004db6e951b4c8219ce49395891594353b92b6b496d09376fb28711d87221851a5fdab80cc52a6352c062f06c80f891da2a07573b42bf0f6cd5d6b63fd4b1c5bf2572fc8460385a642e6290fb79a9b1cb18cbcb34bd87f7eb595f0598c67709d72011fbdd07a0eb6616a88b8e33571bfa7597be4cbd6976b93e32c2c088de3ab59dcf2234e553a5b2ab143c46df13211e816aed6d02bf6c13fa7f8b282237f249aaedbd3a6fe8771014c1b811c05fe86102c0b0e7e9b961c1000c82408d8a8aa381552920803418c49e1662c7ed8c3d35763c510585a78664ea0012a8a02f34b2bd7e96ee5c298dc296537c985577cac3e310568353ec2ca8eeab4bb1ee2393d5b3cdd25305b148fd8ab11f60b5871e9c9359a46a5da003e98b61d82c51cd9262764301c86268db87fa6273f9fa3c35b1c1fd822aaf2f74edf73ab5af9175070bdd7d5cc7600a516726c3e49348d138d19836391a54954ac4a0c029b1441c37965422019c2ca49cfca81317a211e22ea2297b865da163a0ae2a9dc25701e71847a05754cb733620a824f090d591c51c345420e226b8f3b846fd356e78b87f4555783dc39667349257c73fe78a616762278a8696eeb07871c96f9aa472ed463ce592bf0206d231a277ce2cdd00487e8307a97202e45755d6818cd5c9a82114b3bd9c00b9d9aa53ada6c5a4a0df518912a86c2483174ebf0c478e4cbae97b61a023e46528c1d917c230946a1aa76c1766d7e0259b4606f7fcb07579c54ca0424dedc1842d5307617225ffa8a9dfa03f46a596e343154aaa3ff6b2496b8b972b04f4c985fb7ea87d6e4cfc47490e130712155a88c1329c5119f91fa854e052dd8023a99c31612e791bd807f241227b9e54a9b6cc6421a9e038904b6565e3a91683a6891702ba4cfc576d24b58b0f64fea1325d0a6c67ee228c9c01b65470d79f086217bb5418109a0b5906b74a2dfc68b34797231c64bfae38958f636fc94b868961342c66017b8bb1d0b25409325e8012b75c08eb4c9a9735a570f3bb3ccc2838045a94473a65444bd2a783812e031382b5ebaf44279f3195a7c731f49a25c582d31a979a6076625811b62d809bcd23abbc8c923a888d9d3b875cb723fb52c707206a4b96ff9ac116a585f4394c4e83574bd16364b02bcc4c89dab6231e5ca7550517a335536b08665a136b47cf76ef816b037e91c3aec389b2411f3b397c70847a3f178509357db63a5d5caa882b2079644af11f01d18d9b79fc92744850a7e8b1c39e479c57b887e854cad028d17c84f5dd90dbb2042fdfc82db061afc7245c458b05f934d08849bef6bbd90349c4bac3ce44c1a51c622734265051787f7509a30d9ccf98250b42cc8e75c6d62a5a53944484578b262850e06b8717508c75d702783781290f64a412bc3f741312ecb795d15c17d198334816582209606210b73865fe79662943552b69b11bd141637b054a64497cea157e9156da70891da159c3e138f86c87e27376eab0204f8ec1edcf49ba47b1521870e46171d18268d277c1467b3be6c8c6895461166fc2c3f597fa6478348f640e44530f966c3008902c8625b46cc6120eb2d82506b01e45a9ed7a19f1c0df13c0346aab1f2cab8e01032b1f303147b5ea7e149b4bc19772408cb923e06614c9b1cb76e0b1d2eb1c4d1f6bd8294b280cb9ebae45cf0943c03b239677b7ea7c71265b04ca7c1580578768deb1cf10a2898143ef9d1c5d614b76a8322331a09c48422fd8b1c822384ae1886ff108e930692263965e949319ab94ee1b6763e460a0812780428aee4d446a61254722c9308c512711ab175312e39467aa21bcf454b8289803d85f33400d659dd8369dde71be20907651bae89d861def131ff805f56557cad430d22cb84a4aa65ae68c3f278b5816b86bdf57188240f60b54a8606b74cda0c47323639a578eda52575a32efe03b349b6938d763dbf4c44f13a0f92f75fc091658c60a32691a52c78569f322521799c91aa2cb550c9a683b061647cde186ea2ba57a8a1ca929420ef1895f2193cc6944a26e2688e611ec0124269f8c9e18c4032b731db827fe2930d3479528da2c2acd56a8182231b501b05c6383b070190782225d732f84273eb9655b2a4c5d04256a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd750bfbc28696808f52b13b09e43ff5cc098bb2a80b4c8f6a3c8a805cc6c69b7b02ec4f67651c65268431057fc7d1cadd8c4ba4965d67db44ab0c54926723a0842546fb0799e71483169ad17b60f9353777765157bc7e25d02ebcf9198c70a53bfc0fc7d51a42e260f7c5222a519937a48492ba079df30adaf127db4ccff100112e155501b3719a2a209983358771b05b38ceea677be4a4b086132c12f4594f427400f6ba5af4a07673464118cacd99a8ae5501ab22a235173412479cd759139d18900ce6ad44e0ca5ac230caeb82b6a98da48b318b620ef7093f06f20b5a0b4b95d986aada54891a00314094ca9478b790825a368f2f092d2978195ef2c52b64602929837d0b3efa65a61991ab61d8cd87f618cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a43272d8ff943261c5bda7a4f1092c9a6b7481f05bc3ff05ca5f1cd0b2bceb936233e0952f3380c4b7a1612c5628d5a6a05f837597c94ac061658c53f3da8ccae56adfa5a8156638be426cbee2025860c105da76b0e953c69957e649c5bf7151c77160a1d2ac9c541a80ab20c1b866c4fea987e30790b64b8aa5b12bf3429f47585ddc8780b9a6e1e7a3c030226ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf47186107219df88962b302010b755e002cce9d87781e4b717825fadc62a1a95589694581a18a188143d22f1bbf8769b3da59813fb963a78adb8d82b6155b02889371df684e3060134e738c682a03da9c62d2922c06425ffe8c2e18346e6f5296b7c4722e065d984cd17c8590b202865761162e6576a403e2806bcf618101fd5155702364f6920c45470bc9b1180b259c65bb552253406697e2371224a80045295a0e9b06899d06bf2b5824c9b2e6ca144647b01f45a811102afc4c7682e4b7ff8bb4464987757752942ac106389c847ab4dacc14c22b40cbed29d1e81c89704c21ea25747114f7b910ae8715b55671fdca0545007266f08851dc22446436e15827a1e834f270b38e5ec60222b1724c6054af281747739178c49ee04ce0fd39d5e7cc65644ae9a60303aa54a28a7c0ec4ac2ce7149fb8932ee26b67c2bce886a5fc9f321f5b06a03fa01d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165143b9c53320cdb1b7e8d71efd1f0a1ad5ad1e1ce84dd9fe7c92f19c926388e3cda1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 2043ec62ebe64855ce8a3c4dd252b9c6c7c7102b4a57b402a09f458f187cda36de17f2ba0f0702a7a49620d0a125036156a808953dabae6773b7085a9cc7df2487ce4d447828837c2647d01de3e84970a90c57ddec48def3e04281b88a6b45fdafc08172f024c563090691878a744ee6f372e798f06ee94b05933b58ae1147ccec96dfc76a6a9bff0fa662f5cc5a322292308300695fb8d4cb53912e7b4dca893970150ba93e6e3f1b6d8929c1a4da3748a6d3757c3e55e7a7f452af71ccccf0c5cfd4391f93d9ef0c415b164a3b205073d6633f07177ff9f533a40aafa084e05698b59207e2218d7003064b96d18f23ac12ca34fd6c652699340477b94f41ecb0480cfd1a71a550020a11485583a01bbd0ca04f29ce34fbba650f93c2098e7f0a925054949e9d31995ae05dceb5762f0fe32b2999e6e5a61d5ffc184cfa143e701d01b64744558e58926ea0ae3e8990a73008fa4ce137ecc722efcec77be0f9de7725544a9bbefb03af345a73b511cc0663f4d5980c97646dbc02abbf3553c9d4aa690026fbca616b7b290d3d67eec14dacc9566d7d0753098b76b0d7326018e8213a68eb5a129fcba227372468e04c2912b2e30391fe87abc25b9faea185117ee9fa4ba0efe0b4f01187919f45acc11b8c9c6f6323bab07beab92550a6cd62336a428052dbc55271687de791dd52ae20573302dbdd0e65750e931e19e56a612ebd3bf86cd95eb7dc5a25bb96ac2e0a374233ba0be71dcffbfd32fa861f05ea470bd8da19bef702925f31a9181b319c1c1c027139c643765b2fa9611adaebc723d06436f4923f2523780c0ac798d4a32f3e1a0269d23655238d38c24e597d20164b431f3645b792a809b508c0ab84363990efd5f7f0cfdef164de6801999fe9cea0293fad6d9e1a49b6fd03bc14d25e363754fb7f6352265b61817f65d7fd43d75eb5e50eba144d7c6f68b52724e3dd3a7ca118bdedc1f7e26bf722fb6f2fe962d1c2b03f8ac82f07a08b6c108d724e197ed65d0e5540bb0529b0cb1407fbf6e712bddd2744b54b1564b5aa789c65b9997f27257cc81affb85164bfd2b60aea2c4d31b71bb8a5f02cd0d1ae3909bd8f5d3fbf2177eba1492709e4f6c53af4619ac450a778bf416a66fe7b6327083434ede9bdc9a1ff624707cea766b53886f290b40999e342296439df4f1b8ce20832361dcdbd6429deaf3115186cc4677ed01da35e65001b53c711d8e8e83d12f41c8676fe0a3de5232ba0256f08ce3d80b500f5b88c9474ade0ee08d160946ce76e8320f8b2ee35e71b6af0f7361813d3b42cfe88cd79bb3864aa74747a579e7143a013acf903269d4a740b58f6390e804c51d87c0266afbc992e80b27a5ba512026091deab587f93ee9f73fb6dd7959b0422728183cbe14dbfe146a6dfe8553ad3ff708b411e2a2bdc6abd6500564e847b8fb447560d9d77bc402c8b131a2110ce92d936dade0f4cb59259b06cb021b681fb4db0cce6a7f8eb43aa9d569407bcd3e241b7b7047b2c91224610fb6acbc50306fb75f696bf8ca92cfc8e7f2bd5b9c5095f52a08acbb5939a206e392048e3946f10cf4f22a9c9365f9e475e09eb95e42b547fa06f6be566ea796fae62818c4627fcda9de3f1a49cd29b6ee2f538e5e92ef719a631a0ff80502698846f2a6454a5f8b34dcff2a19b924e49a71f57fa62819f1fcea60be197e7635802d5b2cfe3ba8d9a11eec184ece5d501da8525ae45ad2a2a23e4d7999bfacc24a8bdedf78b8619d0f13add32e8d078b3cea727d993004f5b51f978eb86c8b649f4890534e182eaf9040b26b788446e2736c07bdd707cc04f1756db88eef70b1122cbb96bc88c78b0c84c1fd11e7fdf546e5756119888e44d9e95609a0dd74fcd17708cc8bd4970d7a335c00d54430986be57cea04ac1d991a779b46249a061ea30300ac5dfcafa484f2f4e184c4389e3115bb4f7a36787f920d85bcbe3fbbf1450e61d6faa050b91a3374d2f5bc3c12f79e58a0c155ec89548812ebbc27dcb8f6ca73de92b216e5ecdcf6df67dd086c7f171d7d70af96e2db706e669ae153e62aec486f53e30115538832f8668ce478cfc75b5e5bfa43402f1c59db5c88012b56c7ea59f404f5dc5f438b06232160ad1619c23f81474a0bccc4ebb9c6b32a0297ac14be4af396ba9048231ef7de50bab59a300637517159fae0478351b333d6d7ed8676784 +expected_result = pass +expected_shared_secret = 084aafffcc38ac80dfc02548df07f6e7809eb0644385abce0fc569821a907011 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +private_key = b04c33b257b199352a85b55624f1a1a42b2ab72c4810b839b2bb2f51a502cd498aa258373eb3bd43e03973d129e4fcb61df58986809ec4ea4333659f03dc0fab236cd4e815d3f9524e90a28a3a0af869735b362fed9837855429700cb815c43a6e650e54d6267a832dc0385696274e1e73a12b5960a8409a4b4564de909b797771b4839782526fd69abf516a73f9eb8130f41cd6103a6e67c6724186d1c709d3d90141b1bc1c028e28324de4846bcc6837fc243c54dba144c40fcc6223fd19b8f54c11bc0982ffd366530abad387946e1495a3c05d9cfbb62b28778905ab7d576610a74b3daac9767a051b153af7c6bf0177a4074397be410411cb33ddcb895091990dfb85aee15e9f288d01ec5628034a4adb01da09283493baffd36d224b1efe096289a2afd427b82f8b04ea44319f4a16bb07bd21026f2ef550b919ad01cb3744b37103eb54e62400e03367001510776698e28b4fc367a77f1b4690cc2916e8ccf1fa55aa3495014724f1e66ef7ca8283d917b501c931274d9808a8103004176bb69783c094bbbbecd5b90ea14e7cdb9768498b22332283f6a079991988ac6a85bb591ef299bc57027b0ca9932a41c14c193467374f133bb8539c2d5164ef11b70b4a2cfcdacdf6841cd835c4f4e174be3c26b55770acf4137666a431d669fd5775a71749922c0b223abe36284fc880c3aa2a41f45a4a299c647d6738585287f7a47b88ea1c6c088c6207646d99cef5f56a2e02cd3ea85202c7725dfc99d04b2d52600f0f89366a3a83f8dc74e4a27fc58a622061a6332403ae8cbd0179149b841f5e0ba193ec237ac57a4cd5528c10545cb75e35a20c3ce63950c09a7b0810b84124f3a00c9ebb67bda9b2ab42113e631123b4a85897160637a32eb856d55c2905f7c655d40c84e92e773056d2392d43e33c4f9256dbfc7aa0683802d04d218139f829ae362c1f48096fe47b09756c36873cadc5300cea8094e6f8925c1b81ade69fee5420b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd53d1235800681dbc7657a777bc267637ca2954c09344110a05e2bb90a83f95990986fb559bb1282778933631701393b705a5c122ec3645c1b364367c83444d30fa438eb3a478a0bae14270cd49556399085c566d9e6c467dca66a3f36370693ad5f86a9932773ae5064e9bc73ff7979a5510c88198beea7ee2aa494eb046e4d70a3f9ca0f88b234f6918f7eb41db97a327654836510276e0154e7a4dfa088b8acc5f02f598d1494bfbd07c3132c5ef6c3b466606b3d93da2e69c96744095435fcacc2d24c3016002b5c4b988877ccdb9233c490a8b121ba7821b529de85e638168b0565d50f735d1cb54cba91cfc1b9eff882a643121e877c43b6147a2a8266196346859ce53340208253ca419276b884dbb3b7a30ac3de983c75ad73995a0b62de7563ec9a4a715bcdf376dfb6433de691c54e660f4aaa4b184015026b6189415e66c90dd32c0b015aee63b5d8b3cb9ea206e45ab4938bc86fc54c7598c6553c29ac34b2213b90afd144c8b4629a560382778b28d666667caaad49633a8f985730318eb033374b5cbebacc7f453ccd8e77c5a9abc12da1bc1733ebaf908ec85a79ce5c1e6653026011d5984546c99bda921087cbb63cadab07a18ad591899470582aaf443652c723d954f7e529579f4a65f9736ba1b34fbe728215b14ee450a89297c8ea15b0706314b269a8d88ca27210d94a7109f261dd7b6b2bdf32f94c9cf76fb196b6b60451246d97a2b34f05fa23c408782a93452a9ff43a8af57a59e8305d29237f58c1d2539b49d77284e5583169247b252bc5af5a9aa958846c0cc0ce76ebc8622013934d2e4a0ba1814da282312fc6fd9683048fb308b159205e7050f8b2cecfc0e136a623230711574901797826f02159aa69b45865f12712acb794acd187309c447deb51a81643f82945be8a864ea1ba348b48214e4c003a641d4d74e3000c5a4392ff7d65a5e02915d43c3fa8646e6119a5e23a099f0860039cbcaf82031948c65cca097633c27d11cef810936c4358bbabf9997948577b7504bc87dc53bdc96a68a4c5f9ee52ac66748beba0a4cb1654836895d795f45423b33d06f927aa53527a2d1c000c18a87f2cc0bb589284dea64e96c5083306092965daaf95fae22ab9782be28474bab8785f6030f9b360a861c741619619a74a96fd30cb6334b6fe379c9404f95c5571b2143657c956e031f2a5a03733aa24a73224f89106f7514a8db8515bb9c7fb4179b9b410b7197dd849c3a869c687705c692842aa8bdff5169cf0937a0d669bbf54c92651449252245476b4ea5126041b5721002ff129272fcb76952791b635b8bbc6867f051935508aea7bbcd722c693990e3e8078b1629d21c09e1b417795445fbb857e8fb4f0a1aa6f761657584165d38ce815307e6d778cd63a283e081a5372b0ef040b889cf8041cc324145a571031f5c218ca816354c2c41817f196272976c2ff6115f5257cd13b373bd2a757dab65d1e1863ca4b7ce559c73ca919198ba574a9ee64047b85a6afaecc043327e0800cb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a6fc2ef7d2c4d175c2c8bc812d5b3d54695027a91baf657a60d4befe7562bdf620bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b602b02cd036a24c23816c96deb45c2a8cc7d623bc31e8811468a7c2b85c209b27364c4956b6c30c8094af8401a233c5e4d348980491ad24b04dc2706b502a9c8390ba3f611344c44bf50241cfcaadb7851685c73603b429eac840c6b9a7ada53416470f13311c2218017681204e33a588981f66a02b4e97f1cb8ab61e6a7fe45232b5545a3a35eecf43e67a4c29948206088b062b81875b632c1767789563bc947a59305afc91ac53387925b4b3c7ba24d84ab126d3b88e852433dd0ca40892d3429962be6cbeaa85a3abc46a27b525a562670c801f5f0566a7558197600439a2b98b16009f87147c55f99fb109515b125963f7240b12a4535cfa22ab53a3c5eb8c2500ca5ef9b2d26d93115480863843656c59a85b4a40cf8059d063cd2e7115d862015d059d3577cc1803e6450b811ecce3cc83e039520d6b23ef8576bd342094ff2a908f42f4ad88e483229f4ab41db2107e48aaf1b32a275425492b7bb423632e42a6c31e320528327713a86b4e83e929b217c69b34ec3afce8628c23a6747666735360b7e70bffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c4756421ac51ec963493c2d72791cfa2c69b58bd5463c544a3ca679b43ddd13ae979bcb158744d45639586959d6ac5784c074d0ca20f326696b607a206895d495f61525793a839a5631cd94bb7e39b609db1caaa3144387c46a22b2ed393060a679bcb13a7c781aa7be1a9d4d3a58a9831f15372825a08d4e41d0e3371e9f796ef0ca50e128afbb5b83ca78ad7ba50276ca2244b3452d02d803b0e8854181ed57f04aab2bfbb1a48cb949f570eeb550a9352c3887a2c37341d8881beff0acd11a8714665a05274613fb168faf6c151277ce03b9f711034e642425aea6e37f536c27ab4c859a64b96baecfa10abe982fab01e82a48538c12f2f615abb815f7fbc46d20378c77626fd4447fc088a7cf626180b2443226c0d560d028b54f884825290cb5ffabc1e152626e62816069a8f9965d89a09b9a19b9c8734a2f71808733a49f30bae54659c375de1a1181b478e08fb7ad85983d7809a4c7bbf67721beb9447191a63a10c2cc709a2d9489dba469ad9c035664aaad90bb8b7846152218635816ec4b1b39ad3b1e37201fd468a134445e183bcc3430cb2a9015a10b0369c079e60a42d387675dbb292985dbcd4b954c75b56a1152942ad9ecb12c8074c1998710826b4b1044a1c368d4808d081d7be1658193c1c0f46739ef1043f1ee38e90ea989db0c9d6d8568eaaccf1e986e4f3b39b596f4bc11e32fa03e10418dbf464f435680dccb76e0bce29005950ea7762e0a86fa4cd5e8819f3c95ff713b006155438d9211350c317589a5c599619530b664070f3715bd3947427476124f328b850603533a651a38c4119c2da956383c0090bf31a378474992636eb10b079b319c821b4ba9336f413929850550c9271f547344e682780eb9d2dc84b742b49eab256b6d8149a904ba0293a0a40731b98751a71371059b84d323970a385408807bda11497c42478bca048b1c50ed3681aa8044e8884458085b4834e313825b3951e8b743a765a166bc1a133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75f2d009cde4abd55a2c7417c9341792e60eaa8e26b53a3aae805746401c4c446f56047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = 405a96bfd02c25f66daea1440e632c84fd0e021f62a71ef46f1806de1ebbeed0ce4eaca6c0c5792677a2ae3ef3e66f36536f3fd37b4a2840fb36901020d47095e73b0023d1ab420ad313b36e5d4628c99cbde76099ae1282a3434a7ff38bd5de115cfec4a56362dd68c7ac5818348b1aa3a595b724388388f3622f7ca0133fb235e6c82a28c1f4f49f45e654d3c455298a18c21dae8eeb5c2887cc258899395bf55d3e2bd75a74eac7ce9a01d806f4f5d3556d2725a10cbe44545fc0915aebf08ca5ab934ab247670ba701ae17063afb56f753987118ddfffb4337b5dd48a8cafc6b692115b9d8af156217c5f1440934491203607da68f9a90c5843264e893d8a872dc2c95c3d9fa93c8c05fce5022b39fa763c996a30897689147ff2b2a0379dc6318193d5ea90093d83abc3f51df9a263a3a7895c83c30720ae773ccb4e2e805e2f87c559d274401602642d7b992bbf63e6035d347d8d6300b345205bb0d6cbaa2bc61326f7be2afd0bc2238621b75e69b3292fa42e79980642eb4e17f77c5a797e7eff2fbe73c1cae2e5b5bbc548207fd7af48e443f259b6727b2f0297b62389bfca4c44aa3020e583efa081a71dc29ed739d30d48aee2474685625bb241e0bdadeed100931e65d6dedc94a54e6df203e702520234230b738edea749fd0a8cf9b2e2e0e13ab3dbdce8cce21b290bf0bf42493b10c1545775b3d1bab14ffb6aa26d5b1a0db66511ee75e57422c4eddaedb9b5c74d49376cbc6b9a1d6a6d1bc4854cef00a43bd4bb52a8d3fa6444064a11393dc1398a2c5af503cb97041f6de40ab849b5cf71887be298218821fd6aed1775bd27fee8a532e94ecd80733ea2099d84afda3fd65bd084a6d7ffcd4433a993af0551d580922bb0a8d3d23f9032d29450a2a34cc8eb123b95d9fe4bcd8ba7d4bd9eeea98279f02851d268aaa3de64db561acfa717657e905ec1ff6a31d1857976397ef4ffee04440e523f7cd75cdffc64fdae8bab29ab5eb0fa8f6de7cd5bfa072c1b4a63486238713e9e06e9a73a554232d5d6ab3e09652ea4434778180bc2427e7a544c90bc510f90f227ba29f6279f033a90b9063da5a596eba9acf7e627aef79eea6fd39075ed8112c7261587d941ae6cba3a19bb05492e11339d333622cf2396a3d41b3053752208766ed434c7649a1e3d348bf5857a48c0a7cea8e155d30a046169d10988ed0ccf09556ec47cfa37589a4b677c6d1e27d9742ad401cc98184328a395a70342234fcc219b5c0424dc61aa73db27177fe4f7f56d1dfef7c62f726c5b508f64d68ccd8c732fc06ce1fdb864c3f5401eda20576835d82d5b24b7e2013d8c5ccf1aa5f401566be406f7639ac38bf2c7f2389cbb966f6d1f5a493d6b5507d04e8515ccc0cc5410977816bb0310ae5d7e08ea3ae1166b230e0d3482b7a7af0761cde220694e2662bfdd29ddecce7bb8d912d9352458112a26ecbab3ecc647ed695e82e2c312b16c58665bf394410f4c5f0c422c39b6567b6805668e04712b3fe49289f3e40995bdc7f0e74b1c23ca1688a05c06688f45f4a65e945f06136cbc139469784428426e1f616f4e6016bf652fe155bd40341270e343503419d726481128ff7a263d70f0026f6f11c443be9f6d3ecc808c61369e8113c0fa0fdf49c92b9361c2667c7a9afdf8ba46feb32e7b78bea54898ea55bfe5c95b8d73641f53d5416c0f7bc38dd4281f3e09af70c9a7739b257d55edc7c7ac17bcfaeac7f21cc93807215f96996c1186d1f23e25040456332ed86d9613b91b689e5b20024f279608974d65d8419228d3bdcd70285d6a21305d23b1fb7ca4ed7e95b63eb3c63cd7670e25b8a0680b03642ffaddb65d5edc8a2fda9f164c2f2e5e3d8aa903f9488573c824ef049048770409c8e6091dd07885ba404cab3d07a8f6019866984641e4019f5266d11c4ab7432645aadb519b46dc8727bc0d33fef2f5f58fd32f1183171d797edf314923c027fc98e91ed652a57137fdd7c75167d51d150fa91a897805c4a28c15b6704b3ae1fa199ea42dfc6cf99ce3e91501db463151987c60690ac7f71644ad36c91d2c5162b6cf40119980e2093065afde74d46d4dbe83facf91b3104731a689cb8d539ccf042aa32cf47c2b085a37d1458fe2e8ff9adc78c88b17512dcd71bb6d6955436663373e66550674f567284cddc9926e6e53b16ed4d93c60c36c0718c155e +expected_result = pass +expected_shared_secret = a7fd777a337219e1d0ad2cdb47fa18f4685ac343bc537dba6c97326340ab3ebb + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +private_key = a5019e7b82405cac3c8f45bec4e70e20590bd7e543d465ba702cb1447c0f114cc44f404a31b091c638347cf5a464106a2f92a0b4e600a3d86ab9f57efff088d1887865c695c3aa29ba08356da1b4042146e8817f2bd56bc014071b896d5b2cba9fa124cba45e294a0f30fa01e4eb18262059cc987c64f9185aaa12d7ea1f2780308a91a3b2f171d9c41d166872bc7b070d44af8556a356b631a6eb2e804cc09c531eeca476adc8143eeba767298bf29c19fb2496e0c573938babcd749ee2d02e9817a3ee5a687f9324e7e1082892142c04ae9715c4a6980d73c6a54c16beea97a659da476e49c1dd1b8292e04321783e0a66a36267673e92c2c7463668b1742987405c1621f94b87ce88aebaeb7bfd787116b30a5b64a7e8956321463b351a9753a0389937b7aed431a5028d309cbed2d8ae67f859ce371cd1b3cb11a8a70d3b9b92e15530a260d1874118ec505fd451897712ae4104e67b1d2bb2676589aa4e8833e03b017aeb2666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb325144111c75e96a13b5566e8258e36d34a76096f9b013236b3036bda5e3d431aad3ca33e9a0916d8cedcd3466c75c1b5603a3e724c60a796e0844cc0d79686f086c510ca0cb11c2e936ecaba446560aaf0931c6a82298bdc7fa82aa6a0b32d361b3335cb83dda38417720e9e745bb9ca008908cf6931ab2b4a7b78036704153359dc4fdb5742ab3c39a346005374cf3107b95cb771ff1c9592d59c810a93e3593169ab26de85077dd79a3b3aa03c332a9d177d7ef88624c285a90099d1d0209a0bb0c425ce6ae9221613b2cd596aa77ba2bb98a385d2898d504d68117ed06233e69c43b541438b3274b579c1a5c27b0d85159836aa48907f768c97b6b2b19f475655022691182b2d9c80aec12eca0890c9e47bf764684ff1a94d1083d85905212431afe09342004b44a090cd71357d2431c923b3ce08bc836b3edb82ab2fa3c508867eae87bf2768ad61d4894b123b6f861db52b9b3eb77a8c99839e9108704c907e258f8d8001567078037aa1ab87b03a46ad3a0a30c753b8bd790923b7454f84c67ab6bbbcc105edc36ab6ab67c28c1d3a54bd06f9c09c12cac8483e015301db6650ca3228abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6600a0d40489d0534423776184c85057ae00e9636bfbfa76c2d329625747968f53d1eb26cf4f95d6cca45c60b2da0f1899a7a1fc651c12bc2c3a2ca16d8aba4e05c0cbcbb2b72c48ef55403462ab49cf6576d8c358a865de1f795cc0629f4b13837b6b1704250b8e97f7a116fb63a0dbc12c955b49a67094cfeeb0e8c7b23abe4bdabb787d3e45ead108a96d3206a4977aa128866e596dfca9d68996d82021a4380c0991561ae40a96bf490dd5538f0718098479a5763787939453a7a87a359643885bc5d6149ea048b5ef1adc65c78e4a9c917160bdc625352596034b3558f98637b33061f769cbe341f9c764238318882caa978996d1c321a92838d109c187011bf84d17fefa0271eac7d5ec90743130234e79089f5b9a6f0267813939b5a3b22321376fb1792d8bcf8b072f387305ee56b027908acb477e0e744d0413eabac316c13c242a818cf873533bc3714ba136d477a7ef0c8e620b9e18843f4932b6af212b566bdd93c74ce56abf92755cf136f79784aecc9770a136fd8e245efd79c99095d1225885df1a752063af9e45ce5e10634b817f31013acd13ecf16b7e023cd6c39869b98cb86ea5ab2e655e89b27ed83a65d7a849cb68346e216413239073bc7a5793584acc60f320524048bb9e99e02597eb5e68a7af1033c9603ecfc8c833061f5d27124e4be67752b39406c91d01d5b7c0e7889ae037bb338e64c69ab5d96296ddef899e54b72609105af54a9216890e842b0287bba2698a41f12705a68888b3397311bb9a60c894dc71acbc44f8450b2132962d0f8a6d992a26594a3e2589edd2460cb62a57adc71753a7a94d7134bab8fc1d9c688629a99b0860efccb33c8238c1abc54c11c8aa6c29aa62da3235d97f0c2f65092b551c9a9794c89716ebbd119a27a4382101a3e4b9bf540c1c0f05c3bd53c25f416a9ea3221c110dcec6262ab14114b566cb55b5e77c06784a223b9cd2d59478b608d2e79b1dd02803a272b54f2ac66498ab1f621abcc61afe10141eaa935897f89208acf9b3593aa90fc9081b8993d48a84aed0252d7f28dd48571f1b318f2d22ad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9c211f8e959f0d75b1e11486f197368188c8eeba30a0865711e046f9483d3e953a55802299f02968a35374e6a2b9251af66790b73c200f74b5fae2c6c4ec024feb61db55c28d2a99a67436bf5879835bb42fac07b9399ddcc01a6d5739c2c4c4ab217a3e28a06e6ab367354195c5080f334e0674397556047fb02d195736db39abf7c61e02c11e9da5b1c4829039f159ac3baaf5e47a2e6c2a17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd492bb4dcbabef3c20f83412a6940b78053e26227fbf7608f2b6233ce17db500641b295e9d4a468486818a9375e074b1de9124cd44c05fb975889192666a38ebb79f0e80a21d1c0358f24eb4167dc1bb2cc4fc076bc634e37421e0a5054490b6f45695e59cbd4e7947204c62cf0b61c2422f39b2a1abe24229e456cf9b374c8a17c85664f5c02b575a640074354e385e36a5b0d373bff3105cdd110cf0ca235f3bb18a051b4894c26b6c6b8a4a9d185a6be6127a1f172fa4e75971552ea357c891210cdedc7a0f3278e930a0529b056820c7dd699a436b80017354d106698401b6092a049eda3a07674d65956943b96c9191340046148aa8c6837acdbca06fce4a341d526d437657388ba7b7632085a921e447024c5b5ab9198b7b7a6b8380b4daacaa6b17bb508365c34b8145aa3b2f5b11722345d80554919489e49433bb558a3c332eb12b1a36746e5a531eb2a6afaa1532183550defacebf4c6bfdb0a035faad062b1cb2276505da77dd99935b1a3bb762666de6506d3cabcaf8b5dc876fbfe55feaf4acc4a628e0347a66f424ca2095e2a3605075786f9b728b5905ac09113e217e663a91f3430dd6d4244bd2cd50b69968d95bf9b07c0f352912e28fa9f0600943a0ea1578955b314ec1bcf13bb4cff6c1793b11cb1b08bd55bd850136e539cdcba0c8f8b1a1aeb183dfda8b64718bb1d8707889c74d92737ca3619e42b7d971783219882b14c671c5005c352540cb5621c6409366adfae73b79957539f15bba26166f181a407b5e7bbc14c54119588b630b782621eabe39567032d76716b9684e217895d82e0ce9473cda40e0065c2d91a846d7cf9e86b934381a36f130336c7eb7913d0aa466737c8aa34453e4c0c21d098906e0229afb13b96b6e717a02089a19d479826c585e1f8695f9586b696c805f0533970ac5dae753903044ce0cb180276c4caaccb71169080474b3003e0296271fd891c1a788a264482de92b47549bd2867a8024bd65287f80b25dc18771f8f697d8a830559b544dbbcc8c656db07ab70174855192362dac79783357b199b090840dd5d474227bb8502528cc5659fa1b1575c7798052393866a48a006ab2572d7b8635e71448b1d48f0175baf92bbf98e12660f6730845164fc42aab8480871c3b2f844cabac957f62aba397abd4aa1319e7adef132aa7f55abed6143efc5483e2c32b1aabfaf3161bb24c19e50e95673fe6668617111a38525fa76cc314f891c9520b88d7b82f5c415b7310d20b5935849ce2d138aa162bee6a5822c52c5704b1f1b6838dc88ecf0b3acf5a5868f2576a58730fc7b986361dee901f5e050841ab06364c72029b259a754f74a95b32179bdb35888b0872c844443faac6f9f67aee9055e4f909b3d424d6167725e960185738df3a30930b4d74dbae5a07463126b9c6ba257ab8cc893758759b4d24f75cf2f745bc6337e366218716bb4c5b8d7f0291488c8e20990faec84cad2616653104d621b3662838c0d2a27e4a3b85b25f22ec350469582e75408ed36141033043e459fd7b0087077aac13058519ba1c210f68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661e007a8484540363321a08975f024353d72a1b08252173c874e515e543ca12959235537cc4f314f7c81015d462e2182130c24d3f572de234441ce52e48aa67cd8b2941508edc9c421ed797b52343c6c792e4e8a4001936ad81108e4080fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a1f06190bdfd692cf499be99bacc4beccf048c89926769f1b254cca9a9a44089a8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = 64ce20892558f065ab2cb0e35bc0ab93b0549b77f257c05d6a21ef7277194c7aeef035a169e76c0400afcccee0e3025ab1f64ae4f6b23e7fdd77bff46158f505e55d5e153c68ab964e2e9d45ad06c96735ac0eb148d757b0a06fe10d1ab334083ab123e72b863998931997160f7d5d92081dbfe1f7b25830b0e70eecd49b2f3b43543ac221c981733f4797167704312fe150aabe2e981dacd7e1906b239de9fb2fbad87306cf6aa70286a787b240cded1d15b499654f80b9bf492b09c34fa7d39b1c7335def5100c78aabca92c3cc6626ebd4d7969a164bb9badf607cc0bd6e6d7a72415902040189dff9bfe6fc9df1bdcafcac77cdfa26fe099a61a3f6febd887cfc6f3a80ae3af13955f4459dda9613927b4a7efabaa9eb76a8747b6da218022f6aea23deda7997953a0b0e6c810799a673cb0fab21d9949519e8727d601b3bb0da61eee486e94fd666ea29f690f5b30a76fde6e906d9ae3835dec164e08a184d6437479ee2f52304710617ee7e27944991c62240dbc0b9a4f534af0c8f6829a6d3a55b5cae6db8fb8207ebc183f509f66ecb63059f1e2db1c56adca32b9a90d8e0aca443610d7ecad93561689093191da6457c6610347a8154e40d7420546a4b9dc89cb804e03f4e3ba1665680e801c61c6bcd08976bbff1680038b6b47a6bb00563df5ae9b82b406a2351452472236fc4fa85e04999ca25145416a7e63fced57bceb621158beb7192ae5b227bbb7e0392bf30199cb345382f63ef22c0253eae4cc33594870cd778b8eb65cda23f170b40d50acf9f97b31b784b4014560146a3769ffff748b29e05f39f89351afaef01daaafe7f98197eb47664523af79aa03a9cc7ac2bac603df9a258fd34b8329d4711d40cc6fd39ea90b6c0a6bc18b822997bbf1b00e9e87497ec154bd7b13300ae14a1aec21014f407701bbb7bc6f9520f08d05a30b1a75f057ce1c7af26fff07b55c9ae255c4f9cd9a5d92bd234283d158a272f68dc8387cdf7c81218045f241bb83d8fbddd2302a8d7e344af462086dade8c8e6b4584cf5b3b693ce317f23ac1d0a24b237eb07b00fa8fd4a5bd4680e89f5e011182b4200971ca09dff2e49b72fdda8134c0ce80d3c50fa274c7ac74c3ca8e2033bcbc836604471d9f11b0da84472d69474f03f62deaf8537686382c39a5b7a03cb64a948f325733fac7ac62511a1546eeb9b40fc34c0704f8e79ef639871072167fb3a11741ac8b57cf1101b66c20ebfc4223492005389ee9f782841315171754e5d8cc0d82823f2a8af73b415734c2505540858a17600d045d9becef38c6b015667fd6f98096094e2b55c820627fa56abf03cbdb374e86d8b4a4c11d66dfc9d1f65b3a127f489c56f1fe6b493b077d70ebde29b47a406f33d589547dc11c678994c33d9d96d5ef706bebb836657a00a16c9b0d65fc176d5bdd0bbea6030039d53fdaaef3881d805ba72a23e8bbd24401133ee085049e6c0b7c74d2531f171e4b86190b4ce31307eb474d5976fd0ec2d0dbb6d522c5d2b2ba7012ccf2b33248809b1669cae4d16c7a64dd354141d386e7bf63465cf13086fd13639146688c3972f41b8f1e071bf949cf3a94e909c452f741fd98a280cc9df4bdeaff30e43efcefded41db01de9bf30d934e746d76acbaa91bff2f08b20e8a24639e1eee0338664d224bbdb8feb10398c3d8bd90ef9a664cfdcf8e005ba51862268aa6947c58dc45530b201c4ae650c765bf5655661292d05d96e635de51e8b8b7ceabbe7c20c5e6acd44238568cfc127625461ec7c22ab034d847432cbfafd973460a373d7d588b0dd8c2dd960aaadea186d999aef4a87bfd58dc03c00836a9b7b3bd52597b6cfebde4dd523066b8a3ebc7ebc38f6742990dd30aa0d963577a5c160efe3ff8f30158dc2d4c5a2a83c6a701f45e5579510891fff52f059b27a3281cd9a3022b8e9784f2d1b75487deb48db743c4eacafa4f6d59b7b5a211470f559272545fcbeeab53358ddf209b5f8a846493373985a5b1a265f65465deccdd1702d0d3348243f6dcd57680979c442ae494e90ccf0855b9445768e2a6dfcda0e70be6896715e6445d3bfa242c1221e0672e734eb717c8e0f7978d62ee59145a87ff5a36d2d1552e01e89a9e67ed30df6984607b4b46c457ad13eccdbbe88e0fc9c12722737abc9916ee07b088e5dc7cbf7758f87e6bfe83ede7b9cb3dc256fff5c9 +expected_result = pass +expected_shared_secret = 17672805d3953f1f374dc8671137dabb0136de43700fea82a2ca23292bd0d562 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +private_key = 7ec737ebf52eb7905da8b3c58508928dd74462e8968a1265bb3b9780649210c8202e2950ac11863bd78af3123ae9899ceff1992608cf5bd1b4eb0ac1c13ccaab4ca89a869424bc1af777cfc7d90a071273f5aa5df310493fab17ce5b6477c773d8cc81d995509ff3a40ce80e734a9e8968b7fbe79a9900ab85f7b442077a890688dcba0bd5e64ae491ce5d39b554e6b82b7602a149a686c19fcee21b8e3b1792e7529f2307505c77ed84a63a68258e832bf0f118bc05c91a6b216ebcc051b90143b9748b365ec841b6098c4eece8aa8231bc24b03e732a0ec55aa5b0e3231efb7c7f0ab21e2544072c22b6b4075049b63fba05c68a936989baa2e55ad1846fd1e335568b01d4acc869e710357708bdc25db545447e41727224545ca8c16bca5458eb24d746a12e170ef191cc8dd840e26910cd9484b4e40d0c7446959a521618b9bc472c8001ad0d1c8428c43c0fb3230fa9b17694284375a0e1563fdaeab6cad367c9949c4723802d6931f0c212b03004675652b958518d31c8d4b06dfd99820702319e668dffb5c88622170b0c0eaba56ee7b77ef5d7600b9c0bbbea5b99e05a9443bb81a68c22c7904a1755d4c80a47ac148ed13c3981c6bf4122a7880fdd597429a32d6046981146743ae85cc8c0ccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398a9236d02bed9b951f6d43a67ea06f7fb803acc33e9552e7150c34003a2e2e11bfc0badfc537eb2b69122352ffb62b285b6cb0935adfa0385dda074f7a63adb76bcf4a80aa83a1c32f87be3a786537acaa32178b136c8bf817ac1cb1e25b44654266f4b2b14f33358b9b75a2d916d78e89d3cec68b782734fe052449598d847b2a02c3056a64e72c5a3b34685e9fb2c0037736e0a21df39a356310777a36fce908c243a4a50216b6199cd63c7bdb18b95fbe4615e9799757176fa4a88c93459bc3030e09889ede148890cc221362472586e3c026b0dc10ba5a823f07acc1c693e9bf31518b90359b7aaec54473552835b3590174109337b6171eac38de29bdef8095da13a8f7014b3f531fc152ca5eb19859673d52067e28c7513141245376baf368b07627fb1b844fc033361994ffb3b39822a2a2de17597d16601329866f42c3697a6f5132dcea2140b871480e50523c3c5227537a5089fb6742cbfca55ba9c307a321abe440241e34151b2c2aab6ad55817b115330c0b15891fa35bf344be7d93ad44bb27962101982902427242f5b06f85204e738aec7a333a15001252004b21b5e6fa95a41a4456f74c9522657a9a40f8c4a162f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4dfa173b96869fba6c72987f4b328a0e56a08c96a00d78854d6762ea2394c2a102162143cd40192749cfbc5031739711f1ea8c37db5b635bcfe9b6396e2902d56bb135eb8975e1b0a171258d39a7ae84aabd46baf4dc2a6ff18fb6002ce232b7a45a532dd54d3da8c580d6cea4209098930477d207622a7cdedc2e72c24eaf5787d4b2b461889d23ab93a4ba327c371eff58cff7f65738886abd046895834aa06a6cb57973f1011353fcc1452b015a324c406515e9290aff4356fb393b57f4066077b2152819b6a69d6072bd4baa364578557fc727a6519088a183e1818dce9c5bf808ba36e539b40440f1ec994b46a4a128ce3d8063f608cbba032ab13102cdb3c725603d14610c76f542ea4b641c411d8297033caa114d086d00ad711224c585f4ce74c401cdd3bd8a893a04aba0fec1625bb997ea24766b5a3059983436627718d83ca5499b7612919705ace8553d475c68530464e2745a82b1c2c7d152e3da60f0b26bda3324f751a40c5004bd510df886a8b6f488af3b36a3e50ba362250e34c333b4567b812960c8301fca1946d58a52e0847e164c780254ef75c0f3ccca27ca8afb711bc2a5100e535633d0115ae135b5464c33c7c4c614350b562fe8b641e92583d49546cc4b2b45fcce125acaddf67c786acefbc919cc70cbb8a2ca1b8353372c3894fcaadbe2693f09cbb0783c4df1635818cc06c5732b846b8024b9456307358212dd0649abeb4f83910f58f90fbbc855f86780cc85a48fa75aa6bb5b25050a15588c1ed63d107b7e4b6a9e3f025be483a52967c249e7413432816bc8ad6aa29e75da4a8045b8693056995a847dac15ff49b59a1b9aeb2188c46214fb86a8ff8138c5e8b63d6c29447bb60a56210ba594a3027f4d7667edd310b678523e87830a469e5a758024fcce5a7741a7368c790cbd86204f6ae2a71c2a6a0ce80d14f26e53c175318cca9fdc5fc0a110f6834e1a32986cbaa0f0283376b25276b304dd4c9debf7ccd4c98bb1e605abd84bf824a61f5218671b17918432b32359feda8cbf822c62e86061ebcaec22af3ddc83b45252166a55fa2b3942e346a688cff13272a092c22c5c156ae0b63214bc7919aa90847f9de579c6eacab9690c6281685f4184736092d7b365c2d0aa977b0999635cfb0c44a8193377205a49033fff2133853a4559ba895f0b5b36f2cced166f7dc4aa6d064e6223a114580b58128dcb30b5c8da30b97a497300061c9cb9c7eca6924b6c6b19469645a443851e59248a3759164c02a8a86a9d1e86c51907074c7003e1e0764ea650c9aa9f1ed14831363e56104d4126bf09207d5544c5696a69daf7a748ec7be4b2cdb3c628d5a302f1a82eeefaacf731c5ce3bb6a26a80e7414044087487648e62f9c5d9e29cebc8b5bf111995616b8677778a8cc6b55618a26c6ba74753a2d943fcfb838b6a14935a38cb96906fe2008d2ac8622b50ca4a79035a403946180fe69844020bcc093bdba58d1496ae7dc5741ff16b5b5185a86277ab65c92551b48180972ba55580cb8cd274bc58a83041c7c0349191cf7c9be0a24f23e81e9892c2e0fa979fb4aeb3648ac64534e6c3823ed28cb24569e0931506396140b72f059818bd483d70c8132bc38ad19b995cd9859bbb06342ccab0180e8471c77ebcce2cd9a09d32c7de1443f6c588ac2308612b3b3cc51c670c935a91b973063a31703047a630ec03375831a3357940d2285ec8363bee2b8626656669b36875875f32592e9fd5c1e48879e58746dae41a9e8043ad3975de6c0f59f6588376682c770bd2cc3e427ba50070a3d1572fc7a61f08773d60bc1dbcfb087d726372d23bf89647ce6792f1a12fb87298fff567e6ba833423c43bb157b507009d46c8bed6704e5b23e5c431206bc3d6ca5665db9051d882be08b714950054a6c0a341bf953c4936830a74db1e7236c5cc3b49ffb6230c02978b63020ff75e26f375621b26730aab7ed79dd7facf6bc7a038b779bfbc43866123ea910c4620363a8b885c7017741a22c35506fad12fa5e2360c55aa99528db32709b41c79e7a1730be27ade379ec986239cbc98c3e2bb818b3c33c29ce1b6cff56a58f97c0968e83156a5617a579e13fa208c840591ab630d942ff415479c8343230a9f150b39b1e8259a839eaa370b9a083f50a8992c2b90321549a15b482b752c65c11dbd5b302e630293d2463a47cc54a02c6b7784ebe8c6b487b185898887f1590ed21c1c757d248cb712b7449f712082b7591b34604af799f9b5ce2aab6ce9464528418b01b1abd3e4598ca45022809a708460eb72bcb708c5bb8c272ea187e0158778760b7ca864b0fa51347b4d7130a2ecf4140a8988b94498db660229f78852fc149dd9c5692c41123a6f1310743c892f761345d2f685e5f3a924e620d7122cfadb4f8fbcc95f5a65b31728624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a340100ad8384a2955462bd703237d331eb7742349876eab4c2c933133d3c833d185f129c5804aa1453b0947da3cf3bd44051f70de00b3cb28396c180b501e70157c22486f8a82282652bb21fc23c3bc123b6c3d6acdf079906b149ae2b52efdaaf3d9b0ecaa92ca9d8694bf07d4229835f3a0a21253877e1a39b4699039041abc8c0b3f6aec29bb22e847131670c0e7b5abeb2455a246d03b6066114552476a18c23b013a812d65a15d021c117f926607c076892499056c1bf058c52ca1703a0812678b4485b82814bb6960a86c3454b99b731cfe15ca5ec005f866b28235036e632b89cbd9aa4a6e70ac944ab82661134ec2ba3b871272864a85ef61f86f51337651eef063fc6f07a39d3ba7aaba5d7357506c550bed913788947a1863a25209cd01200272517adca5f1087c984e11f13404d046c5537711c56577adefaced330230a42cea4e13d0e899394f120ec34c2a6054e5d2ac90696115515345aa2125dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28cc20155074cd7cbd43ec2380dc6a71b3a88c9a4bf168ab2bf426a899706fa597812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = 65c9109d7c2eeeaa5ec2b4dae6fafac6f7e17093449f00a5319966bb022c49765023c6097d90f47d6e58b96c0c17d319a88c2819de8dd91cdef8817e354ca37a3e10853dbdd3231a2516df2dfd1f55e256ccf81e624c5c19c2df81e6311d02271fbd27de2f579014a06d2dfe32fc26cc5a45bd7575ccb8898e780aeb20d5c01145f1480c95a079fc6767523ff69f6858b2d56bfdbd3695d8a2101bf65cbbb28e347b2b528f2f01d630a035ad2802d087a676930c9ed741de8b0157423880998e655e20b6f4325b3f9e7fe36d1cca269f49412400f0ed498b9a7e699a968e41326f7c813cca95ee5b2bd5f5242de87609fb3d2e62ceb776486e7826e45b5ca6feee3114bdcf705c1979b96ff382c1f92be175e60b37e7885d18635b06183807d5f3ae5d3c9cb3df01aad1487bc93bbbc10d078fcddbe8a0ace94414d7af8a3cf0ee579b3782bfe8cf6b7f377f8170bf7fb8e7fdbd96a075b804140a65d034ee675fc3e156a12e261b50882875ad073e071295daa7743a9d581ab9096f679ed9f2cd7e36da05f435ddca26c0136676775a3f30ed0c800e51b7ae9dbbcd25d3fb9d6676a972a25fd7c4ca91859b175c98a933d84d1797427ea8c0aa1beef033a2a35a145d9dd59f7e29953c5bbfe6865bfebb558ffc747b52ff7b5f2e83d65dff3423328449d27fda0fce912a0b6ba78e2b66c9db821bd322b5081cddbeaac16f7ef2e41fd6b86e4490a2bc04fb697e09b3c543495fefcd999e6442a56ab49ee9fdde910a768d4f0bc51d797dd730f98de9edce163f685c0363e73ec6d235acbbd9e168b6152b0eb50b7276306c7efd42845b11cfa11de76163efc774e5c6ab2a44a6d117c7b80b2b14ecf1b1af7f8a09f3d23407cadf256061df3fa9d940ee92f3a80921f76f0f14d3e3e4b0a943bf6d6834d9d75d0c4ac931e59a98d4e53456bfe77a8f12637bab2e4db63fa8b47f9f26cf65c5421caf208e74dcdb98f1242320d900133a91769a5c9824a83a0e60cf78dbb8fec10dd1366c1a7bf75412da8072651e36ca8d0aaf464c3d4473cd396cd82207b20e2f5cd07b3cd1ae1a62d9ba86bc1cb81459975ee94ce5c1fae71d39fd2540d631cf6cdae1c60a3ce10b8732f9366a553333323a9a01c56a5a91267fdb6b3abd68f73377c2d10cafe7ab4af06b66c77dc30428105413a62ddd505b043b03e491520bd526e00ac068a64f115716f36f008d475b441a849617cf44c8e758726987ca48be6dc5f41f95933ac9f6a4b1a8e26092340108643003f0fc243ca8900e8cfc1b8a1910e2c75384d3653d3a47c619495837399e7668884138497c598b8fabbc5d406a00a8b89be59c44bcd8ad090be3c15efb1ae2f7417182fee2e68d0ccb865d81b23a4d5f2f54f4e91d89bb42a451f95d3f85dcada8d651147ea53b086175b52748f96ef432cb3b34e14a84139915cea2d3af6a33d2c9ef3e3004c516a2aa16be6dc5f1d07be3d5ceb3ff37c24d1d2c0edd91b9b29cb04b40311582d473d71e52bc707e9b0d497a3d6d6d96efae0f9b556358eb0b465a86f9cc10a37e5ef129ae64776ad2374649b388524825761a56d32e360124af0e2c63de5fc6719fcb13f9a664400b137c842d5b5c7776dc7adc6661567e8d62183a16f45840493d8a4b5eae39c3ecd40d60d2b0d015ae2b59dd6ac298ef11fa1c4477d2cfae2765182ed4a8625f3daab15f51712c3b9c2a33e8f09957807f419cc531e018dab3e7aba6348f1563eaf7c6bee397a813849a58f4eda0648727ef3d3594a171181a9153cf8eb02676cbe6f70b63eb998454edddb2ec074849720ede5a8f13d4c9f8e2f1ee6d95e87603e00731fce896f6bae80d5b01386427fc5602bf81d64b4ae3194a040af00b0038be7e8719b24b71aa884304cb1fcdd691ec6e5e4d07efcf683847e4b46946a7aa200d7c9fe5ecebc1f95182ad4c5ce44a5d0d92b8e511e5e9d2c0a74e2c5e9beff56e856a34905f20d0d97364b33596f7efacfeaf0c8f34fe76d9463fe972027a2157a0e6c2f4278f48227558ba3869acb0b06b724f08429e60cd52e2c7bd6db139f1b3200db659eda1b9d21329d8171e07049b7efbda98afbc49b53f51042b987b1afb8e99b8ee89500fd52e7d9db1dcb3ab5efbb5df6e084daa70e202fae574c0267a8b72b1ea174f0132ccf7abaf31cda71b4ebe9171a822bc2d3b44c739a24d51e85446a4 +expected_result = pass +expected_shared_secret = 8813fdb7bcec5369e6238322be653d920ba26e0aa63a3c3b4e4218c48c1d6dfb + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +private_key = d62c6ce5e7594be682a8167743106a44482e3a79ce257635773513f0b0bf77a161c8274a705b93d2eaa899d8c0126ac8adb7b3bbb5891711380da1a9de0541e4160dccabc13a165b5c54178da95b919457c684b9cef81e97637c73f22a3ce9295de79bedd83c3ff871087b9412301863e291b04779457807abe4687368c84b3408e26aa30bf58bbe4bbded32adb03607598714464222524b3c2cd4c15f98a2e6695463257bb8fa9a84131a64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51af611d4bc03e20cb12a216072d7834d996ae99e1cc6522a42b48c54282cd0ae8cfdd1b874fbb4ec17434ad584af5b4561bc1597aab63390b60fe7c052e57846e1a8c4f6c6758798b70503507554946382fa6e2004a616a40dbc2b0c596c2cb2873c38e6ff82ff159ba93563d23671dfc433949d3705f398b3752680169657623937a8c357864c39d82c16da5c1ee407fc7fab357c0b114965e89815409964ccdc54cd8d5b17039aa9283a59e746a45a2800e4806064683c292b425c18f73aa2f720a6521a050c5196bdabc9b094895b9527759c1a7210958e11a3411b05e67097fce2c11ed024a85a22684b51edd652ded89c23e1440ca5616bb754361c549776222b8b297f8f4bb7f818d3b29b16c369cc8ba9d91e6012bf006999c7057aa2a44c30237314079b2a55c63990c3ab657cb80d41022651097ed680d200195be82a9b9d08b24f039bffc42c66459b0c8889dda6714b63762494a5e6106f34223990772b1cc12dc660f5be62eb0a15c16d4a0303773d768c7dda7b749711f7c12720c150d30ec6b625624e3f94861483be03271d8b05780ab62e0294a8cb193238530b49455718c872428bea1d84955f54a3bb619dadc6106ea3ef27094a085634624377312648ac46559d7a7dd902497aa9f22879d131a08b9223a05e5b76a00807225b304480f6105cbec8a11cea18e8910a9bba691047c95676c9e2dc7ab76537691dbbee397738c613e1fb00a79f06698c10ec26c97dc00b82a54af572a02801aac20983311f42bca18699a2684e4b5aed83c7ad89a1705f1605a87cabefac499a56058d8b02bd597743524a90c3686d9405e33c3d70880b6449d41a76f83e23759664f1f301d3935998d690a7167afa11a59cf8b87624283a738c0d221b1b55453504ab64fb89824351a49ebbcc291465af92f50d7b53874c1190a766dac5e70706f88097be4500942534df5e5887c48b234c11992f32bf3f2867cc055d7d6c3a4d25d2a141be7d706bc1203814667552888e3bb13221a10dc3a4157d811a7ca23088ba5aa1a3fd60c0c6af29b3b52aa6da319d8e359d842c6dc65c29eccc0523115d15b19a7b90d1090c5949cc66a004f0a0513132640a284a87384c7ed06782607584bf5cdd8f099acb0229cc9588b024b0f3b5ba80b962218b3bce4c0f542bac9e8c235362e33ea30d789094fe82fbf64569907755ed7bfd00c3f6f446deb00a27b37bb92e454aaaacb69dc854532c718c85508ac8742c7180ea805a78999111915bd414275e92d75c1953c10968c802e4aa6429eca0a5ef49fb4046ed2c93914400b0d882b67c275c483037e859c8c01518ee49046e3594a311320e800ae2cb182553684d470df629b6c27a9cc5c17a0855443262983e800b9375e0fba1d393953f1da232c41bb30600e3f0596fd3c786223a165522bd60c8a2d404bdfc0a145f50b44fb1cf3e8ad9b1914f3264425627635bb9734807b408215fb0c6a617c695025bf43e225b1c54d261052f33a825d65730ec7519c9087ff5626a244a1e28669d84bc8216a09cd224dec7623425023d05a51f98b8c220cb7b2dc46b6aac461744a30a671eb828835dc32efe47fff21370e73123135ce2e02789a21b03e1c55167c3fcca2343db1cfa8d11e838948382084a7890e619c652ac49c64a3879658c419c8c813309aef9bb606d126a652bc331329501c61f97196f7db1a398a0b6d947cf903a9bb61119c2c45f8b440f29344fa22c2d9b1cecd5786089402c6b649d8563236fab8d208be6967b14074cefbc7aa44c02766ecca8f0673787b33c2dc2c7501be94770e68608ab06aa5410aceba544a6f8792c4db01c07c1bbf197e4d17388adb05fc910bb3bb0b947c21c482256db66dca0819602701895a6e3a2071623403b78438977211d33331312c8715e34929757ad52815c65806ea8b222ac2a5b4b718411732d6a0137c5c7ca8e285c02634130950e1143160f6a34cd64dee440b1b3b8d64458c78492095517892c5a169eb7ae87733aef3b16a5133788ace5fe57cb41ac0e5b13c403441d374aab997500533744714a84dd56ce547a10c782d6071bdcbdcbfba391dd44926022b9098e61d079b2198c4c4201295964aca9d703013341313a50a9b124427209bbb248aaf96ab9efc9028cb9a298838465984647aa1e2f4087c74ae23f2606194447e403ee45198e29c12aef2ccb0c4b07c98a02987068b4a4f14a778be34c362204ed4b31788e3b7d2e54d74e07a215c7eefbc3067f9c67e625bb43b9ce25179f58a113bd2cbbaf85c34ba8fe26a331e0b0610893e0947495cbb1e287047da04527cca1ac68a2ce1742d8c855576941b4d627f0d326a7e543497f09fe1fa536e997828c19977b0b82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e79501817d8894004c5586c78c1a54808c37d40fbe3171f6e950e287850ed19d975446fdcb1b0cac2d4a611d832acf1c20a28c164201638110e0997fb36b2d24c6b349c390d4a13e06aa95c40e878830827a440985870a4b6288f82dcbd9ae23175462fa054d2a9c6f6210a1a7cabb9a6ee8e37ff144043ec0123c2c0c4125ab48775529a86462c34c00b128a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a716a27b1576561f681e346ccb74a07b71938676c25eee2a83ead225afc408cbf085a4a342ddc2b058c6a138a94a819c737b6baf4a4493c38a52c1452a302535dee813f1dac31e09402cf720a3b16751451df057bf1b7519c8a62e1be69e339910e6024c59c13fbac116d6a6578ae40765f78a7147b5dcf93f4eea1436b559ae373888042c63c0a52cdb2777e8699afc229d575ccdf802c59c15bf3b6f028494594b53d2f3cce339229b3a03eaeb164f325686590f79dac06f482254838e5af209cdc31f9a5bb893961c5576c445a02034088e89140ec2b28cafcac58ad352d0ab34d0659332d9266db85bf57bccb67814bc74c107c41dc2f30e6330b17b4b710cd7ab0b1c01d9f82d3fa0216e51198d723f1e52314e850220052309a383e63b774370713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a85603fdd8b392a616f55c3783c28b5308a4b0a5c1c757b677c475c60516a65f656b4868cdec6bfa723c66e52931b738e18cc518cab93a7c942e7db127d239c11580c21c71031f20079e9506ec57119688e0df98e4045b77e87728496c2060c93f4819ad2a79ed10501498891828080f4841a8af6602e100981124f6a16c26f3380e4d3635fd3cb77cb6c8eac22ba212a804917b922218066241e848e3ba589569a5a6420019370ca04bc196e88cf2f428595f1912fe9670b9ac97c487ee2e7a77a621ab3b9b2e4c23c5d4c8657277951b55aae576524769ca5b83b37d84868367d7e9323d9ca4cb7071c352ac3da2b3ac58525a152a00ec268f85ab6559027ead8abaaa370751c64f51473b02126d7b3be27812bb008c45797c1b4b05b5cbb8c2dca419f85be36bc390ef5c4d3670c8ef7c00b59a44c65ad11d68c5af4b2b675cf40c002a1b7844fc9a6c32886c74a1892a2514cb930e4387904d1970168181f7b43c020a8071969b868a5b44729b8d04b3ea9716269cc005808bad63d0b063f21c23ad1377e80bb07d608786d849d79eaae94813435d602214075bde7bad770b28b380bd0d7139a7780588c01c8eb6622f1a874968c874b120ff81c988c5684f3c9ba677add2c23400283d6d325d8289473f557eb1c2977f04e95fba614ba7613720c704905f7a73a2834996a4232a8ac278a444fe5f7a9148b57124580b7b03df89ba646aa4233611da9b5327d61b6b1aa351d25988e0c25e6e2563168c005666ea90852183231ef5ba371935c4c0abe6b61c0a1da756ef390c120621af2ae243089f84551185616779c90ace0593b815dc5d8b2d5726a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa4a001c002374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33921c307c05f69f90cab5602a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f1326077fbe004761fc37fe7597638e5dae8b44bd44c8d6efa2893a0a84b104ace6ac48e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 13372ccab4d0d1364dd7d76cf4213269ff8332b39b15dcc8be813a16f36135139d49589788872472ca4629003ddc721a02d27eef1f842b2da4da148b9b83bdaa5f0f8ee1eed71391454394ec62f2fa18805cc78524db523debc3d9206871bed38b6d6e69dd74dacf6ba07889ad3d2d8cb1ee731b16120468ed3be436b8362e56ce66d1f1b9ce8b42323dc302ef37f732b9067d80b6e6b4be3acd2f4751234a5410d18c5972d32abf25c4922515005a89e03d310b8a76139fceeddaef9b37998412fa7ef24817861e6f210c1ffb2780f23de28f2de52205aeb9a64138dda4aa0edc91dd890c41e1e814939124efda4cd4a344cf1f3f046507822a726ac44acde42feedcc89e159571b2cd4450c370650fbae1b0a55aaeabb70e31300605b9ad5575ad05a2df9bf440f123dd1b4b2dad93da1dd0c7a2b7f03baa74b14c1b94e63fcc8cc3f173ff50f72570c5b3a65ab4520e3fe80b9479195f1c733a3e9059fb4186013ba9f64ba006ccdd270747f5e355b4a455a7197146bcb42604f7917503b86e818197fa78ce268e288fe3ab3a7d8678a01cc2dce86e77ce7bf49514867ac9cca6d722d374a9f0afbb51fea1c4f120c339160faa1f40103b3f84f69d8945d72d91ae9054c18f70d33676ef0f3c759973e25cd30c26fd3b823690b127f95a0b7d3999ec16ac645c181b264178bc7f11f64127800335890c31d7412a314ecd3d361d9ceb85d77494c20e465ef7c36a227bfb9104436fe95cb0050ea548ea22252394eee01c8ce8da5eaf4ccafc647b7ce956f1eb7b28c28cb05663aa5171412288679ba2d44d7de75a625667bfa865a3dd0f20cb92837dc383df5bb060fdb2f9457f1f8af77497d408da49d4510357f43ab7985ae03ff73bac3e9d2b2c2f3ff9190d5e928ec75a2fc0e2019c07ec2b4ca40da2fc16f7ccf3ff66cb06327ed9d2c73751e7ac34c062cfff2f6a98eae4e8e4f989dbaf648a7a23e5a9f336a5ef87dfc4b044384467eb7f63368daec721a1cc13ffca44b4a4bdc5c429b7e0466bd9d19ac0104879a629d124760427202c9cb325be4a7624593136254ffd5847e8f4cabdb2161178aedd4ff9a9e9622de100cab8523f75f885479965a7c4e8578c2bbc6d5db343d1e9e4b7b7b9006e8e63f8e636012dc66fbeadfdf1b94a4c4a58e61527e06fde7994a3a9edd9792af3352ed453307d8a5cdbd47cb2d7de1e78e13876ac46e7110418d3cdafaddca4e63b297dbdf79dec136fdd9cd66b2ffe04fdd541ba022493faf56b8c238e630e07274b0d2e7dba457ac1d2043f8181ecc8655c785105bd8635ef4b070774c21ed8fd1daa129b7bbb34c25b8aff031aa08635b69f021c5188e539b881eff8191b985c83d7d4465f99f9b6dbafe322c9b0359cc7d769ce3fe7e0df2c8de02e4676b5811908d2d29a270f8a7b33f70b270f5507c4398e7446dfea9331675ef9c32c73d5305492b8b3b5fa8b1e77d7ad3e2f566f0b17a7f2522ec38b28fb71b3fc9d2f0b6bb6adf50a0f779da14d43c387323b623160589970ee0fa10dc662d1aaf71632eed47064d523f04eb115d90f74a048529cf2e02143a788dc95e0d802cdc35a00952ce377954ab3b61b7fc2e03247576f2707569f50457df76e3b73cb20fa6d5b2fb716769154d4da9038d8f0dda0d93534dc42ef05de2c7815dcc97e0bf8e15acbb31c7fbc1063889e03a312d03c8d188c6423adbb20b6d49ed25cb0aff5452411914c61261f533ae1d8fe887b08db689f7e46e76176226fa75e41d9a4b700bae0ad7e7d1b7e2ea90c339ab143db4408bf00c79e506ef2adef8ff6d95a1800f725770be6d3438f46593e78920c4730859969c789d9068d830ec761a7c4d43b3e282c552993b232ec0f4251d5be3d9a743c4586439e7db125827a916a15fbf94eecc4af09eb109a7e27a45068458b02b475297de3f99521f3bc0a4c0eb5b5fb92fcc94bc520837168642017688a5aca19342dc342d624a02a30af36300fbe163f015e3e0c46d2af22cedcf9d98f350b40355ec0ef816652975b314800f3b0ecd2fead11d315700808f5aea0963088b008d048381336d7492999a5d29a36bd4d9d0e57c7bf870cdb9b75da48911a900c018cc5fb3f262c09cbd6032ee778c704500f2c6f88b20a6baa927eeb373cf490e3eda483dd0101dd2260d77e32d9e6088dc906b5a61fc4e2c22c8c37a82effb5b4c6 +expected_result = pass +expected_shared_secret = b00167b499d5130ef82a91f83d1f1563185de735e74f89afea0b45ae1b90cea8 + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +private_key = 212393fa68c40d1153ec29801f4472db30b8e6516647cccc6a160bdac4299d515717d46bb4248673d11558d8af5a6373720a9c96a4c51bf12ac506cbe51b560ab742ec684ddf86cb08121bdd412e2476842d051e3182c415c49b7184c9322242f70b63a960576296a8af5451f5d474019c47e1822e2b1503d30cb8ea20b3cec334a2114fc2381d910a98e633716ef9ca2f7939c7033bab756371d6c2e906061df822113c57dd5992c8826adecbc9ae381931473558ac94fe8a19c9c4bea3dc40defbcbde234a211623f8d80bdefc74f657a797098ebbe2b6b57438c2253f89d13bcbd5c0c4204def79bb37859e36e920768ca7d0651a7ec9bb63336698acbfb6c9a384084defc1bf5d9c050087b691d40344e107bef0241bd99463532a05b795f820213392cb16d668605ca86df134c03c4a7df581f8ca7daf732f5aa75146457163c3abfa9c655f966a607a69aa1234fd1ca2a97213f280a10e84c4aad26c0ea2cba6773d63b39ef7350f6d284830ec3275e5bb9a318b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bcc22d617aaf8b14c10d0037ab970b8cebbec0cb866be5057964b7cae6c9b3084a696602a25961dc53558c065d6d8b25248aba262b1b635322bb82165a8cbede60bbf6b72459d47b64a964b3c32ca563ba5aeaba8ed912d81b2e733b4b4587a99ae5037dd21dfc9aca5d869596e36547c0336ae774b8ba637622a597c05dcd43b092d938429886c708448b24a45a701ce9fb9db54c67bb531bcfb82ebc15c127409b02a3350d6168f1296784b86f7310b9160681f0133a66356843401b9c0414d7f687aae41a36857ccd3b26bf8c11def30769e30630169365aa3c3b53cc89d9cf47c2cc6c166f197c9e5c5b2408b03c41b0613703cc4872be78dcc4b28089d7118ca1186baeac1355d5b9d4e45515897ae233a26810356a373dcbf6cd5f02cdde8c468be006dbc67e60a69908d1171d4a5ec1643b87059cac80c259788eaf195f4fbccfc4c0284be822f94c2978fa119371291657b927f8b332124d61d17e21a36485d2c3f2893865f305589a8d048b06fba7bb9f087f96d5785678a7f2d16c892cbb2273677ed0cb70f5729af0a0403b0bf0608acec1ce32f2924535c16e8423be0c8854e439ea395dd792399dc98aeeb7493b64965858be35977dc053b3c0b3788fb4244cd3b49e40934f90b454c983da38b2b5c88521347788f832e9c64a6cd012511234275c9f6c251442a87b496743333a161d8c04e3d78be3097942aaccede09b9cb673e1fa261be71dbeb5c4e1049b2b2a00311acad4470f8afc85172476b949aefbc0110a261461291b5ff7a74697c88ad40c82770fccf68b9ad5382125879e637b7cebc1aae95b03219cf2488b2e3b2e51480c8cd8022c2092470236fe6042dcebca24cb9ee9379386d80e54c232dec93b99b694e99ab5e41cc8cfb8928d5c08edc7a707044b49b8a131986a3f37bcdbcab5255b64b4905a93a719d01a32384a87543b6ba1a22db75c9baad257bc8b9d8b78641b394c7ae064087454cfb17b307bc35a97cccb842602990747d60f30d220ed3171ffd7a2b77049dc210e2377607b817f24c011dd736d7918874aea4bccf017fe3b303eb7b30e426099bb2c90a0b269e88390b5879706b163e1b27194ad68b26204b512ea145c43b029ff20898ec589c6691c7fc5857b387bb1916b407a641ec14d01c82dc7f4a179a3558d8abc8af937a3b2682d638e3881329e484b28bb1ea4a9b6a20097f3bc145345b032ab8051d44a8615c9780521429bc1007a28e3659433ea295789a004002fe980c2d1043761eb7416338b68f688221ac004512c9dfc7889241311f78145699361cc1c46d55a0b5c1303789a3c0c4c57ea1fc14b8fee92798a188d165982de273cd9970be03279dbdba64838ac127b78ef4b16c3105fef180d0b936558aa005bfc0c2c5a2a00ca207a49675db34b0029ba77f76eef65646ed13bfea533e5536683b2402a380b1426b45e1b83e498758393907cd4999909812e823828752d4b956925892a0d038d2c695ccd22bbfe0062b5eb0b9c370c54e31229067df3d0b513667be7e54f520839af94c6d71a066309004de4cf7dc98802232b77b10dcfb266ded346770b8df09768a5099bbef238f72b853746054cc692001b531bc5a46a5cb02c910bf24519198c1a2f2023a4367e9d2ab4cf5887c756299efba70d9008fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9c9f228475e0a454639892d992503abfea8b82908a087761bec6ab7d60c1892f41bf1f99c6ed256b64c78c93a316b31272d6f236371ab2ab77123eb732ab303a5e89485f702f528a38e1920f12ea72bba8868c855e305425d84a5edd11918b4cbbe5c0001a5637bf8c022128b81de80509ea72a0f66ad870257e529a31cbaa39183f006a0fafac0fcd7781f1033257d766f78b4c4a9b10c5b8208a40368b393a39e7762467463b29a7baf4307285b898aa0bae485a63e739ba5a7a080215f4221217fb43177635aae61f218850a1d924052a9c0626a7f11646076176215152b5508db2c52da7477b7e2b0659b999148a214a12b9a3e770998b1a26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa94368429f763991911681c1ebce5ac515bd5663308361e2b068332763752047ee14ab31b914e2d28457395cf61c69ecf3834d305af9ca18decc6ed39ccf69a79c379044ced7440a248963c269b6b58a049a8077e0a0981639d581a8c38a16f4296af798cd2556889e9697ba8156714166f10a57c970c6131386d9154894d495deeca298e33de4b09a94dacc2cca1d816708fa1b1b5e0a7e8046143fda893f0b3eb2b60ca7a02878729768fc82d8b06a05f647916a9cb84b69ce532edb5a7ec4eccda5a5a4fe8c52ebec6584e6c0465529f57699706cb9a497c2e96757af06783a4aa6a00087079803a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401abc1b8d0c8eddf679a8ac0fde11917376a7063339f2c2507ac02ccc512c7a75b00de0701124ce3057a8c28687b2576c640bd0ea5422a534aa4bac9fde1735f35112c98528298218a1f051d54231f7ac5c4353be2205c3b6518df442775b9771ad19ba9252698bb6cda102cac759a5a0734cf07791a38c7ca940a86b584457559e7b933ac5750c4c43785ef61f5c121f8f4175570c7ccf864c4bb7c49c606ebdf7950e49433a841643f78273e117780a5e1e4cbf3e0016b45994c1821686d41133bb353dba0fb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb0e0baa50199d80050dae3266f228134a4c67ffc5241a757e0dc2485a64d4907934eea5fe503653311c4ef24bf09fc3f0388c88ed9cf965ca8a109297be60893559a0f3696e77b38d677a7e9f4c788d67046c28281c8a7f71ab250e77ad87b4f64237077d1a63b753a21b088c5149af5d40b928401e4c407e71b6896b840d8f717e627532f3cc604e64b84204730c8330ea35228580b4b886518e9670d6100826560f9623045291ebad1ae5fe6840c30cbe69ac54e62bad8010c98c513956534beb356cc6555c1c4225b7862c4651e55c4452448063b4c04e105b63daaa90f9a6b0769b161a32f49fb64010a91e0b4410d86b7bd4c91f421ceb091a88ed9ac5e01c81527886897a8e6697c7571ad95b818f942a5692459f9979ac7a8078883aa8a445a5af84b1b86c4c79a224a5c8f3a889eee0c768af29fd75a506ae75f9d578c26c8645bc8a8bf0441b6da2bb27b6baab43031047c6b826fc98766a1661be0626cd2c37864eb23f4240e5fb601dd645ffdd9898396273d3000d5486cdb67866751378350068a8439944ca11f9a5e7959ad43bc1f5cc8c741a220bee733aed2a41edc34fbcbc890a718f608794802bed150a0398b0a836a68cc0b58dd705353a41f28883cacb94c797b8cf8d23cad9bb9a18c53b372c50aaac124fcc07b310907988f38164f46d70305a381e4a1673145b0bfd8ab91a02c28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c45057dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c6a1c7e1589e98cc995a4a2b21288057fcca694c0c00e7ae05d861b90a520eb34002732a2812368931a18243ac62f34cd7027fd80436d0454aed978115034407e30dc19813c5100c3e13a26c3283d4a72e254ac3f7e637d9435281180dd6fb35f0433788d470b6216b310a63d5e11b373a073dc8098d3950819937e7f66ff954caae52b3bb86c80b5680851170140a1e59ba0b23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c49cbe8daa7dac02d7795e907b037e2ae56624fdc8d7c6320f9e1e69dd0f6286f8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = 65cd11c5fbfa837e85464c0dfcdac9724a25db17ea1f8631400187559d743cd8d29a811b0c159d777d234d3cf33a19b15bc8841e5434e28b752b865c3d1cd4f7ae70fe84d3f4dede9c515dbd7843cba1d29025a30070d3a1b841cd2cf1d76c4bdf6bc2d24d218959d180cfeba7a31c81e495baf9a1b313c2608b79452b2344e4c6f1960c530262085a5c9053456aed77daf70502a345c6bb3c147f8143f916f99754bb1ef31c4167bbf63c68b54ffe5fe459dc9679d080065e3b73a7b02f8bc1d1b996cb0069a36f9f04dc5aa3d00633c38b06404eea9a4af2f6144bb47c009a01df11accd962c20165a3ac6c27e5cf50691a58c45d68be6f5732df8e07e7bdbb2f58ecf171baf808dfbe151c00b576856e0ea7c292095c5000c9b77e21b7937953a38af0f53e7f4c65a70edd1396dab54df2967eeb7e02cc548597a6ffbd829dd72a2d18e7888cb0e3ec9049182301c1e6be6bb43f4130bb57b61138bc82720afafd061b3ad2c00896e7405e4063790a75d96e7b3c1fdc475388d488f4690e0c584a33efd2692f2f90c974b4a2498b847953e2f72c1aa2354d04c2fe61b561e29b7d37f164734bfbe96b0af480f4189b67c4889f1913497b55547a1b01a1b0adb944f75ca30145ddd8120bd7f09f7e36e479af5f50befce9bd15ade52d4b329854c62837cc0e64af3e908b9b47e61595f2f25ce78207d2331c183188d27b8e8f29661cd70216f491b886ff2afb018611176649c9488e6aee19fe6147a3c92e95fc1983ef5482d295e61ca2c8f4644447d0b918b443f3e6efa04e5651edc750a529cf33eea818242b45802773ab7e74840cfea962970ada0a2f906227f3733a72ead1295f78c0161cc91c448c9e150c565d022d194a7296911113ab1a550806edc6f1689be96da4cb11245f0c0fa93797a6d6dbe992e0e695209d010b3a728b0a647fa5990e78eff5aeb75870aecbd0e14cbad1b054c9fbaa5b86a00dc933789db11df313c39fa0e7b32e281173e5eb13be31e5c349709093c9125030e7e066ac38eb3d89e23833a08a66f7c0eb230d01ac83f792840db7de17adc7dcb828765f67e20ad5e4ead3d6f76302aa9a5b321d68971e07a1801f98544d6e1d5a68f8801872d099faac4c561e35d2b48036528a8a04c2033b4e2b018f1242bc6f8af436648730564629302cc5cbf1bd2214dc8b3e38a79aea4b67a52af232f23d0ee6f60b318736276986dbf567baef9c168c9331773cb1c32aa22dee8882d557f79da61171634a5a4e806939c3eb1d575712b3674f503e9199c6b1b630d20296fecfe4573ad43a266b8cabc22ebfb40717d781d4dee61591aafbe0a042c919a1804953d4b8c1a6cc5f8be7ed45bb1ee6f75671f102248d4dc63ad0e6098de0b4f3fc31bfb3164ab3701e51681993bf1a4bd78064b3fda30deb7d70c7ab35e64bd82f91da3b06688ca4a20d0b19849b72d2c342702a077e015ee10b277d5e1230b91c22d41085650549c9eec529f34caaae7de76bccc960bcb5b5c7e6156c6069e4b27a949ff8c9a1aaac2ee7625aa3f19568b14e883d3273311927ebc09dda978e1595b7f392ec8f896fc8c8f90ebe8dea1cbd54e8d061479656edd13dd69467a3adec9426f1e8adba7c80055a961d5f795d26268efbe41dd91f7ad4181bd6e6269bb348149654e2e12c94f5400f1f8b33de35db8a08dcd10b5e50e10def51cc062157effc7fdf2f1bc45cfbf600df322a7d711918468e3edea2ce05716dcd996e292de09a910962f64056fec1e8fd041dc26efd6e08b62fc943a84c6e8578eac778685515be6e24b07a204626acd3b43dcf2b95cfb41b366f1f283c1233c4c54d14024425a351cc057f07b861dbe48512e6e34b136484eb43fddb97778cdda81c4e294d740c6a2b124c1be3ec67c266be133506d35ec2a68e89d1eb4d16ca04066eab2978dc14171e8fb0d5591421b6852d4c2986057beaa96bd5e7b3ada56e3932b29bd1d4ddc4199a793faa47a7634029ebe81ce082efdca2761cc1c5a00d2a779e8b1548de89acf26787e7129ba62c445324249dfdedc6c6639d665eebc2c5cb475c89f8fda7ef4e88786d24ead0589567e82f0841bfe3e483b1af4fe488a5e8f42766f765e210ebee1b2380d082573aa423b3a5f41d46b61231fd9e1f7501a7b8cd2a56aa9d9e272df94d630630ee36fb35f1d968e2602e6cf16e4e38ea80529 +expected_result = pass +expected_shared_secret = c55179382eb5d4bbd91e45f4b3dcc5d1022110aa209c002600fe0d55a5b3333d + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +private_key = 69e774db244d05192a2e064257f3a7b9b08941a2018aca28c610b8bfab59176bad88b9a7781222cb03aabe6a4c2937be24645a28c3a7931240503769edd1865f72b44c4842114980ba64a59a647438c5476a700d0dc4a63277c4dc73a3dc9b59bfeb0ddf0817612ab73ab14378e93fa4982d15131c5016b36a639e4f689e9b6b2d2bb2501e130eedf72afe4861ae7cbe7e717b4c4001b78bac719c6afd40969392cfb1d918794b4988a7c03a23c8c5a751ed2c39d3e18474b43cf8b7814a5932224141fd543871ac102bb0a349153eb4a13ad57ac06602bfc6c1b4425284ead058572a1c7c0cafdc6756555b2033d2ce67f9155b16726625928ea26d13e2c0c0a66988eab99643b4cf23ac68724ce635188dd8b3f2f421e8e8a9f838b707a16fbf27445a7555cfc052982cb002130ca3500cc428aef14281564997d5f37d0a1c411cf73d3d2082e4c26c3bb7beb9fba2d9ec631f8953b3d03075318b4b720b4fb5b177d43c11e8979c640639136fa20b718c0846404b2f0604c55ca82f519241d811a697000dbce1c743410e92922e83446410a93150178a4a2b52123174db128b2eb97df4e8a617d5876ab9977daa8b7845537db0a2b6e0599c0cc165438329d1251d6aa09d5b30f27040082a135c2b831b7722c416072c655c4d511e1fdc0284932849126d49b5a03b3593894bca250b0d198601a02900c9406d8f5b69beda735a3512bd355dad587bca7330364031573b44eb9c2bd103bafb7283c1b923ac3a41f0607d4b7b7e1e681aac9b4090538b6b7975b9c5c64c6196577b7861cc88ed6c3365aabcc9b97a6a318a39a2ba8b17376509a563b58dfbf4584e6b00d56bbbec309164982d1b906635a146c04bad613c02c8e2c2d0597fc285779c628f3e290a84d8710745c444410f129a140358991d601fdc787faf4506c6003e2130c2e03b3ffed39ca3b9bbaaa34abae794d4266e59a80efb44528b2b234d70025767a5dea09032767722c61e53423417458de9e809a42257a27001e9c8ad43b775bc853d8475abdac86811d568e9e38747618aff0b0901283a3913b6595cb2a85b6d42101dcbc90146ab85ea5449850bc9d8b1356f820ef365731f176ec0a0a5b7f35d9848c426f32d6a37046574a93cfcc043614e8708026621a06ac00582da7b64421d4f50aaac1bb10d6bbaea31808712b891344b7b865243614cd706c2dc098b0a069fcedb89ecd67de8319c92f3aa0a9b92a1fa256302587a5859408b5cab563ef1814cea386becd756db669fdf87a003ea1e7654cab281220b21cb234ac1c4b459ee48517bc838082191de35b265d5264119c05cb500a05307c806ae8246128a8194f61024f5b2b7c410689150c0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73dd91e9733282fa2559ac53aa2819811190b5827000d98433241a3da2b77f4e588b0088e3d3318cfd049c4777f7b08678144618e2406b9b6b72698888c4529b7e3b272e92620bb36792266c3da4c9c403d1d49650b5530be017c3b99c068890f2705702440aa0bfca823059822c18981a03b16670e127386265487665aca4c171e023621a853965a629757148e37833d31e453dc9b20191c94230833a31089c41324a94010ec097210f45592630d6c1bc28e09551c85c4677b015a7b957b1b4e0eb8886cd77835351458700ef5f170d1d0c81dc920e4cb7d16ca9fb6b8cb6086527106b5508996d24250026470740586eac42011db626ee74a8d7b6dbdea073aeb5f6a8a9f9de70cecc03b203a5bdb2abfdce8798764a88cc84cf9ba31008470904c46c523748a4b39bd46cb527501f617c43c83adcadbad1812ab61aa7dcf71b3fe4128fd087766e87344acc8429743f5842784095d1dd3a43eb7a835044cb990165a8b52a9f43f6fcb3fd4e04ce699a4713c4ff2b19b7205c256f643ce050d467132d635170a4c6c854b45e3c65ac7c24f1fb70eb0b6ae852b3d526a527d41b8f562bf56ab9a44d4b00c371b4055cf36089c905bc8b42006098ca18c58b89cc5cce6a454b02c754f07045e274b3a2a647b17533215c6fee12e7e988fbe692c308866c3a133edbbbce1d4a06931b75c5561dbd87a74cc0197071f360185c680a14ce508bb280895cb2c4ce4007ddbb21a1907d2ac5d4e163c26a3c58f57212b9b824d071bdbc45143b4663ada61ea72608ea85b82b49075d3adebaa7d01bc9cd916728ce121c1fcba51e42732d76575607d3e574c654043d717afb96532da23924fc124b01026a8f8b859f4bcd1aca153133905904c3be8361200abc6e7ad42f236a0826c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f18042f2075e0a8c58a5c244e14119f5b6d5538385089400e23bc1c106b2cdb59f287c538f32917c202fb682b9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74096e0423db52e7c0099963c5147c2cdc7101b0d01cceb8ac64937186c23b0da108f58f5271e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af97c05041b0494ec11daa36facf034210383acf9089d371aeaea975c489211184d55db561c272cba9881acb88159c74bf9671147490fb7a4cbcde1689ee7cd777b3f83c54850e8082e884a7c3b3333d7cdc6318d5347b0160a4b67e46a24d756105c09ea0043b66a74f98599129b52eda51971b60b6c65867b3545139990aff9c088b7b114c03d10972bc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d6a1315c63136139ca954a86302ca788c27b4f82c57ea35bd7c31d5d543cad66bc4ec9b93df67d2b019e56e372fdd7808f4453ebfa3092676224670f79ec579307052832bb4f2150da4c06e8069855573378377c44a9508410cc62c60ad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f6152bb2845a3de24807102a274d2b33f84392648c6f64ac85d304a4c024d88c0a13f0874231cc6d2bc8d7c99c0530087f61856c000180e78939148212d2b065df99fa51a0e768995a8f3bd71ca82a1792afc7c05f8b07db30aa18dd25180b73d175382158a1c3d5135fdc40f2068c17ed11d32022caeb404c68418e7ba2f352a510cc203179366249385a2db3639809795cab6ac0c11450220d96356bc6b45ea943c5028771eb8c58097966b4821bd1504ba1a1836251047c8468089c58ac851999b7ba017267c3a6e20c5223fe5a41a52044bd5103f5b1d31fb9b0105ccba387cca72b6ff1bb27119005d6a29a6200de9dc2c19d85be067793ed476b0324c24f10a8d106b55c63bb346b9ddf44b9a5a5349b766132824cc955214315267d69f82093642b9c2360c2b57993b1ff2c52d8118d62375ac851f5eb181a24badfc165668e7a36817cf80f5873f87a6dbc3cd42c0b2bee57f0e06c93a9807b0bc32de588808ea0037db50b3bc14bf98affd4400dc9566ed8022a4c7c34fc4369987904b362b1d04cf3451914e5909ef750dbc56af138529a601a261932efd626510a528643693ee79284cc3987e3694cac828ba3964e637925b201e270744fd41190b3b1c088a79f31581b0641917dc161b000fb4a8281f6a6b7b1392949acd277b9901637c3454a058589299c48b3401a2e0f788744081cba76b5ec378bb83789f63962ae2af1175176ff353c1cb3632bc0e206194f4b7367779146df4acb6d89652b946a9b9c2b61c0553360616f90e97fcb190c43faa544891745ca9b97950384de8534626914ffcda63ad302c9f001a361ba7a94066c9d8b1f30111faba3728fb143bd788aaf04491951d541078aa1069741352fdf8c032964717ea1791472a2069cf43da46a40046c61c79cf4a7d1e093526d75b444a08b0ca984f2869026a4432244d662951df52ba655ac54c502e83e8587e21c4757166b78244da2b5364d3299981859cc61a67d02b32b19c8ab31b78146690690096d606befbad0ee628103712f0f81e5fb4bb22e65e9ad1410504ca75d29386f73b53b0be140a5b548a48b05313de873e18b030d6f691322a2409f4603c7bc24c103111fba7dd5acb3f019e7cc22bc3f6b1e6acca131364d0fa0694866e2322281cd229c16aa82116ce6fd0187d4034db33c2b3840db1f42c5df49825fa7c6bd62c31a625616270565a2fe3f4bb50c58597f70e6124c2f46a83c3fcb62ac65a5a66557b22ae31c7813243a1f0c4b905a31a40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a0825ea860af29b81586b25832356c1f976370496b6fe7493e482e0dd9483e51372b093d37f29b9d1a83c209bd98a363df8a3ae430ba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815da333d474be9bacbea4c301148be2ddf13c3c25d7e4f52447a549a27b6d12710da2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = 7a15ca405767bb90d0d9760073d0b132c61cab11bc4e0c7128cfe36a2c66f31aed86f7b1564eb5ada3a2dc244077f8b225dc3c11c14f01dadbd4a596f6331a1f35cabf199b357b635a9032a852a7b06c9ca27b77ab000780ddf16e2ab81ee06e41dff4282aa32848ee66deceb75e40f3cf72456f53ecb11f47ca808c05c9415fa6f07f24e6c87f2cdf2609e24df56c2875d62b12272cf673ec4e44db21893f1abee86fcd6a12d8bc34e80ebdba35ae88b8e48735058dcb1a0f7c423076fb16f33032e70acdda71af0fc5e7b0619f52e9f93d7471edc8e7b804964284943dad6cc162d1c8baa62d892450698e329c04b9bb6280a96a390121a6ddc339d6ee06e747f30f9610fff22fad8979a54d07678c245d00729ff1c5ce7ea1b553be1e4156d9a420a8b65b2888f9dd032d3dcbda9e0bd1c7a2454ac3a95ac3ae8384e062dd6875d3326a648e605e65f7302a9788ae8433d8c80ae86cbe77fb759ced8ffb6d62131e5a4568f15f2b0df40753d63fc20b99ff476a5fcc686b99a636c70a610980c3e403681369a41a952b49e0b7b0d3cf0fa14275a6427249de642f61a1062ecfb10bc59c2bbdca073ff786bbd35c98701a534cfbfa06f633ee19c3d9fa51080423da63915e34e8f6bd65a6d0dd54c627c01848681010aa5226890d707ef21b687b6bcd50a36c06f8d506b8bdfbdc47f2d21f4ff3b5f37b3bc99c7f7eb05f5853ec4ad4e9d7ed1ac8ea161806041698c2ababf591c41d5033c312df31c6ccfa0941aa307cc2614fab7a17555addbd6ddf5d3db269bf21f8a83e8160282033234cac43a6ac3b9e645343accdd7a0905c54ea2a9cca750e0d8edf10586134e9c63c61271067df91327e064c1f9dbab405149c116c8e5b31087513d2939e3756274bfe284222b17bb99a4ffa1d9c092d1ed2206f5c227ccd7feff9790da2b33a012d975097de5451b1bd2ebd1472437a58f52c5f581d44f97bede74476b810cb9b0ea47c190d147427ceee3d98b4355843d0e1239ad7a94c8cbf42e6c6cd0dc4d6b6177e32afb339abf2661860889c8d31b9fd984f75513d39f9b7e8da462b5ea7941440cdbde94ede2b6c50e53c9c83fab96736e82655c3dcac4fb5b1308dbccb81e869f9661dc68c7239fd2993e81c58ea5a203b31087862b0e9a5ae1abeb8dac43e66ecbf56c5734cd5e37cb5f9b8992ba3d36f89b3cac8960b092f5212c8cc54e1c842557860356e1ee6e3be44c5794bab7f291d2fd31de9e3177d218ae60e2a20291cf74c7244792b4bb33b471f0591da492c99f7deeb708e8cb29a187134f288938339f10d71c936805f39f1b0ff4d6562b4c7d8c4460ab6667570a4f806baed968f34455779efa411a7232983f8a9ebeac7a6b413b714f2b53386f8fe29d7a7d9a93f1264496c84df8c571508bdde65b31f82eb279ef312309694a8a98435e8ecdefe0256e55a85ce0b866f35d846db6aa786203bd1676436e9c398a1277dea0cabe668b9e92567bf5e9df2d99b0229dabd1dcf7908c858691b8b6241b4140d2488817a811004845648b7cfc9aab7ea513069a4a5c45830a286e8c0d922a5f0f181285b25d6263df9f5962b4f67f1fa1765afffd9e9f4204889bed16a4569c79a68147e8cf8e9162361f645c670d7b3cd0321ec6acaef224c7c11cb04ae086d34e11bcbbf01746f06b863615e3fd57a32274cb7781ef4eb7dc5ac4a7285d64c2bca6d5d5529c1781d3c43ccda706655c0252bfd7d49c1580e14bb558c91fbfd789cbc7e7f84baca72e0d42cb89034e8806e456436c6d893a7411dfc5820f9490b3a0390d696446bd6bffc3247acccd917e2a9246e3710b5c28c30bd0aa89724adea98886363443a81e702313f4df4cabbebccbc6b03aa6f15a2280ba828c6197443eccb034c6f6658662e56a102e38d0ed4d6e02efaec6e0fbf4daaaef3ac1dc7aedd17fdc1bbed4949891632e3938226f8ff8639915d5cce755ae463bc869d1fd519fb29b67743df797e20e034f800e598de4ad567f399f3e0714be08fbd55f038624fd9324361e793582dae656b2c9ad77a72b53231ebd8812c2f2d9ec5128f50da504e02ba2e4fb507d61c9ca805cbbd1a8ffd20367336735b8622209968d538f12c3102092062d8b9598953f3f4549f10656eec731cf4c26ba9f31c690bcb4fa2cd1583226c584fa5f1ce14626f1f8166cb84814b68528b9745955c +expected_result = pass +expected_shared_secret = 91c0a23c78351e8f8de8e38c5a10e41e5290ef96266f93839169c05842820e41 + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d56524122156503823b600236d3726edd9087504705cb4698a1515dc0d80b3f87c63d575170f45d121a848d897c3c0063dfe9b2d616a96552384fb72d6226a193f90e15b364ae667c34ba27fdd0ac0debcf450578c6d182da365d40786522c37b54e0126ed7b3c6bccf28f40770f23736b394210b67ebfa72f6b27799fb1f6e48cb7407261a86884621c529974635b35f5b4c530e68bee8cc213387b66a4127d01223180067a2ec24b2ebb579f74bfd5417fe995bbf816737722912b5b4dbb4c938d0686d1c2a44880fa7231944c195fbd67c67e60861d169ddc41f8150b52a68c14425190be2abbcf5babb734aa03538899678d4290738cc63eee611e4344ea73b9c41f36c712a4c6c72422000cb93e144f3c588a2299d5704cb347b90b2905cbf69cf1dc5c670909c478094e88c01bb3b3e4fe246f8dc3c62da37bb13b6e2046911d85d5790869fa4a54ff16794620480919c0dd74b9887bb5c125c34d76b3527a42a46b689fc4c57571af13c44b7d30a041028e97c0a1e50621567374de7a4207acd4cb18417c7984645cf4f2b5a5434be8f119798c0760229301e14431b0b652c643c0ea0ccaa13cbc6fa6dc8d348b908b78343978fd5a0eee90ca5104184f33f107837b3ec667eb207000570dd33856939bc8ba671b3731edb2a94596a8f2f37bbbf5048087091fd2ab164f5c6a8f92f65239f08844ed4f605e3bc1bf780877eeb3f4c85bf696c691f85a947461331aa33b15973ab4923f429c7913731bc025539232217f801ec7078e2f0af3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfc6165773a965e55034dd1094966694d7806f2f505cebc3b3dc307405431fca21614089c633b522510a5fca73462b32fd69200dc614c5e88454f181d845b19b8866259a2372bb3361b9abd5aa278b1773057e26108bb020a9610bc19af13454df46b4fb5a68c3e7aba6e7197ad63439c7252cf9507e32072e437296883c93902250165a1aee8be0ce6acc2029e10e97536eb958b691ae3e3aa9996986805c6d1f6356d26c1e63c550381b292fb1b95e183ca933d5be1baf6294c4b248b4264724712b2a2816ed3d09042287eb8a17ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb90c0456e1cd663137e11185536b02d8708644539701b193ba52258064b289d053404bc78a397ab86895baf1934e8b2f6cc3ae48869be7422e581a6ff748519bc30bc96c716b0a24a02679acd5151cb2a0fa127c81ea513c3ccc3b84a34025522486ce424bc04c860edc5758aa990fed372db324614fe91589d78acc88c43c2643d540a509f090ebfa6214832c76ca982faa1ca4465f9c14ab4e6459f072558946ceba113b5fc7024a364970c72933331a6a4b0d4196b9e6219595e229f3e28fb2d5c6c4c041db226ab611b04c3a80fb5a7f15e08df3347def02663aa39409ac4e8c8bb0934b46b6a8816cc70c8c0b11a7ec1cce57bf5baa30e69207d7e59c9e386d5cf7863c133ba1b510f5e06c4876ba7849611bacc369b039efe173df6b8a22469e1f200f2aa53ff84390b88302d9f9915c4b8257754b3423097e7c6b0df0a71b2162050a67be291b2dca0460a455a68068c3da2ec3c5c4fa3a272d45b55f58a01f2a8de5c243ae791c0fe643bcb35817c154ffd29315cc7b4c3843ca4419146422f63246d1fc543f24a884839b4788c10f0846b3fb87e98bc4ff634c05c60f250b8c2bfb46c50c8a5cca5ceed866badace5a8c88a2e2590674727f969056569b2b0615e641931c3b94a12a715925ce33716a985a5762544af3b442486b14316c9ad100396e9885c7b0ba8c67621b6c1e90c13a248a3bf6c0be9f96601572c87154041878891a2a5448ac965c2c7c283166ab39ab1576ad253491ab04a11b824fb6fa516b6709f57b98a610b94b2a2b87f50480640e1084a6eae10faea01c281b97b8eca8575cc00a2020e1533c3ec30d9a55883ea9c5b2681fda938f1536546cc474e5e37a05eb89ae4a822cc6a32b8c828ef782065695dd630063cb97e953b04911aaaea90abdc20af3695492b49b07c26f79f59f32d74674f37971d2668340a4803996358c59051685cf15410a72657355692816699cea982cb364eba27cb3f055c38ccb7a5a78348cc39e6039a1126d369495687342f9b7c7c88a5f0d1c2b15e68366532f17d6ca8fd85d8e9249ede8c5ce6572d816657d5755236ac059125743772ea7ea7f42785b48f62974a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33921384aa9737af3a3e2d881224629a76c50712ba306b60fc88b85da88b716a41509a95876355fdd49a2eb7130600abd277810301062b0b9be3c97343e345e8fe25f6b58cb16c90a36830452547f4f658110f0745329406dc8a698a71449888e2554c5b039076f67397a94cd13e4b9f9558bb0464a39074fb6e556494032b5433d3df005ce4a1145f0448af07a089447cee578c2ab5d090a2b9ceaab2b472420a56caaa04387d7969fd51a1923c14959834b905617c61a68645aa51150f0079ea64bb16a8a8fbf701c9f5ca74a1803519792ab169976f886cecc709aa90c408720fed90b58d006f2f50d23c4bac1432176a47627f6090a788403042efd5a7d1a22c793aa8dd9a91e381acb0b5625e0fc203fe0b4c7e816eafb87cd774a5053036afab5b293c23598932ed3658f8453b958c1846c61c4190386343435b04c14ea3597f84a22f70124cb293781accb8ba008425149643e52cc124969929721486b42ac9b592eb1c15c4f8c6bbf901b8dd419c17c38d68bcb9d519e16021e62b211c6ea00e5622486e41f81f6ab58c49ba5729c91b2396f7bc9cf8462af8b06d1c28b0cca2faeda8b829943f64456bd214b7ae57061a325bb9c097b656217d65b36f575d39c11f971157abba074ecc1ba302d5318085e13aed84ac8d16652361b67a02c41aab82d10fc339c53b3e096aec1e1276a572ce1a5700c034014884392cc6eb4f9ad80a52b711053e2245537e76acee36f530610b8ccc4caf241a0f3c1f8195cad80c69b644c45f68ba7c448431705b3e9bb84568c895b56351a09bdd8ab2763054384c116e272f5d0a7f1f158e5f68ed0f47f625ca3732729e53a87d223c1ca807d277b726d0c7ee938667ff1c4af519ab7e1446a077b6045995d3001ff289014e43c7ab738f422aeea3269c878b3a7d979aab698c4b57462339703386cb4d0bb0598272349b04230c6b6708c894bb409755dd4e09fb8a84e6ee678c896992e845908b963fbc407589acdec414546a92b1da98c294b23a53ca79a27859ba787a7689202833b87893fde1b230b936916bb038316b025a5b1039a775b055d6b26797482672f02985e39c88911a4540327e3680c574150b74331ec63076d645743c677abc255d0b11d9489a35d65448a2c1bde4228b4d0ca03441d90b57d5c16b6bc6562b4d22e61e167861cb62efb1a43f008877a2895e95b4e0428086c7c34c146f5fc2c9babcdb0f74c76680a62a5c8a82348e7b396b7d95bca26169ffb90125b765d104ecba32d3291a38079567a599644cbb4d36549f26615fd31a6232688bd1694d6c72cbf04c91638ac4e7c1d8be2cdbab51fae70093af3272b885e56f62bfd925b02d099602110914a50d3431f10a803608806d9257bde17123e939df7e1951883ca93e1820e852f2b511218152011012b8adb46d9c400ef099ad3e412eea953f7eb7e627a762de88e7af6ae0b832190b91950aa40713521e0f54955f2039213c16a604b29cb6dba67b89947bcd81b22700569efb06548944decd13bd133877e44ae8480c46b6b547d72bb1ffa0f88fc3b13e2a48e5b490301d00df251e5691d36295a16dacef03c7974341ec3289ffd87434854062ed9475e758b6c297acc679730e291cbb52562cb9408b07bd70215aed0a1034c6fccbccec88b72e44944ab79592e659865f019280b8723c578096220ce5a0930dab0075bbf09b952c217b4ad8b707b8106f9f5180eb514176aaedcc3bbe0a9bf876895ffb1565d61b01f0a3f2d9391c56b6e6a9363d434b1338456313472ad730cd9374c8d81788fac62d68694df05bb88a6613ee14d13cb6e18f69b372c2944a7a76d3a16157686ab6250a98b42d50b15aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce132814b26c0fb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d5d286d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781ede06a48c1383938a9f242264aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc35d109f57ea2764642ea3473a4f192cedfbe153a37f131cdf447b60e92310eeadf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = 57cbb1d2d65c141407b9576f9bca609316fc572f2d2cc947cd51b7767d46825c16d3df8b3552d9f04dcc0c946ff2413271393542b55f0399350d04e78f8b89c4bb1009042eae994fc42ab5950197dce9b7d33232f28b787b781be3ed876f7403c1aea44f281388d2aeb7ae9ab2a66797e0bbcf9d9475fc0b1df08dfec18a199f4f1591e347a290a1bed55b3ccd4e02713874bf240dc39daf1d871410b9e0b13301097a8b5f34c38df8739f5c36f587400ee712aea03640050cb0451d3ceef2dc252bcafcbb29b5e8d6fdfc9e54ac34af80f03bc660424317d07def719b8c7d3bcc73eb55be669109603df65238354ad81f6077d24fa8e8cb863048b43d1d7888c7f4b75587f91432192a570fd7d78b0a6b081ee51c4561e00e67a0b9c59fd5851b9783d16237f038de6d9a48f04d7eb5a705a479d5c9b8c15bf50509e1c8ab2d75a3c1374ad0163eec68f3edc973ea23bc0eea94e0e4055b30fb39ab6ae80d4b745eefac8fe1d8521be3acf3b18563e1c3e58cf719ca2abc170554732b4513e4195a46fe211482a066d9d24929a15a0b3368c99aaf2fa08206e4969531171fbd669cea343bff8176235988e799f2636a8ad5679064ede2447d3dfcef86ecd8183d5e307ecc39caf2cae06ce08ec7e68ad4a865373f630dec35c1348192acbe7f03d6f3409fdd6e90c6e93c8cbc1e72c1eb929222aa8976aae747712c336a2faa21496500781f43810c94e0b9103b3989943e77c5e9c0b47d86c0b13a3bf3ed76a7f280c491d8633631edcc64d0f0ab05bb3bd420a001675d3d8dbba207db055c87bb703d54485a4eab992c9a9f33679def6ca8e3f6e43218e175520054de072a971ce6d053e0d71ce4f5c3d013a986b7b534d2d1d6b77df2326e82ddc8fdd4b529d586e64c1f08ab916e84e169e2e7cb3e86bb2db3a70913f629a509c601ed34202c51d1233fa7083184da3f9c198c182a114688d51fff6950dd0210ebce437f16db5c71fc99a7a7ffbbce8e9daee1f01704b5ddac15aae9bd9ba22c9acd7e456d3ba4506f14410673c3cba52f1cea52856ee3aed64ab2333a08fdf84702de5ce353146eb79a8e2f213dbfdada91fb94ac2fc7e744572d43d310c978e7b35430e10f8fb069bb7973e1dd4fa55073dc00aa0e871d9cab4e258ef4507fb3a6ebb4bd3d7b881ed82e9962aaa37895669b2dacba11386be59b90952a0dbf323b8f9b14d86b89c22066f6396e5df81ae195e2b99fb5ff3dd3b216650a011bf55df026ce1c6bda80f740838c50608e6c0a80a75be65b64b4a4a8b0879625dbcec514b5fdcc6739573b03e1cf99f7abf9cc73b04f9c7a632343699257e15c836b65e1d3a402758a6af62073df90166d091f9c22214f137fb401ba00d9c072f1feeb88321549cb40d5b97d4ab9d76e3dcbe924b87714a05d43dbfd22d0b6710023af4a4e7239b4aae8d0268ce441ffc1556553e6fb694267867d5d3edca2fb720e383e4172944918c06c1a7b7e3ac57c667652556b3f59f076ec6eb26bb7d99f6c934317906cbd84b78564db3bab0f4461bb3b9f4eca7ae19d4e4fe85cfac56827aead0f748e68ec0cf2f3b2fc764a01743ceef75e64855e03f4708f7c0f72d68dabfac742706cfdf057ccf36e3220956a5d2b85ee8b46ddba4eedfcf447186ed3c85b5086cb8093eabc3e874239f3c017441a35dde66c71c984d131ccdda6a037a0f44c75d4c993045acbb2e4a1d7ea8604fb6c898fd9c5842fe6feadd2c21aee9956143ce4536477a550169ab36b382a65928474c3d545c44ba6b6b9faf2706f15e6380cad7d1a1617aa59b834f6e88dbf6153c28449fdb7739b8eb5b150a4149b0521098b112dbf1ff35d5aa034820ea3d427c48cf4d57cfe2a90dcc81e01d81a392772c1ac307b3f9c0d08304414dd1789748e6eb258bde4727b7c9f2c5de553fcd4210300bf6cbc4306e0e43ea222f4df44639bd9d905acdf5b44192f4b5fc48e371dda612bd8a242b0d344387f7617eab7992de8db81440ccbb68c54b08d1c8004bcc9f4c970d5199384351edba8d86683aef89f60f053b6a5aee7fcc64b30d79414da116cfa251c4e7e94f3e621e2ae92b08888e07e3c2264ce732a1052422f3c3d9d313f148110e81eb8929403a36f3817ed62e86e7ebb83e364933d8c34cd3ae1788e446a17c4c80699a3498b8ead65e27b6ff2f7f794f92333bc06f0abe657 +expected_result = pass +expected_shared_secret = ffd93f9141d4b2abf600c1c258ee78e0f752513bb002677221060cca3ff1e5a6 + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +private_key = 953b6e6f452ffab6b9e27b707f600992e228f5fac92680aaf31300154b218ae51a012a4cf53840cfd714cb63cb4c7aa0e8ea6e50803ca370bb38c7205d9365448b38308868c83348acc365be62b4fa763ecc5112a48558e57230d92b5869d77d99a5c0bef49819500b333300910117e05b082d15368ae529923c6bc9d3594ab33c91b81549829a2ee55ad152493e80aa80399f770899ec05417a698e6493aa647691fedc92854c23702caafc8ab3a3194ce8437b8e2a7f69454adf3170c282972abb93cf152dd85587f6272b0b71590c81b3a9f680d19445fff0c395310a17f55272cc3e1364a9aea7a67af4561cf10043b7b7eb4ab0791a8d62814f4b6536cfa69ca0493fec1a53d58709fbab9c87578d83c9441d62c267e7aa4ef0afc7106c9f834a5a13206c4b58d7378af90b85f7e05237559d6d7819f455aa01d68bc297a8dd760a0df971542919979218b4861a49e45aab12be67080d197c25ca53483d781ba27893d23baecd393dd1643dc2a53275c84a19900b364ccc94a8ba3b5768f8dbbe08a7b08fd2746bec62c98c5e5198695b12048ba5c98753aaba88bfbbc6c8de490afaa8343d334aaeb72532c63d60667079b41b6a287b04c797458acd9104c94e96bf18137b0868737dc00a8e2164e0980b9b2135dc7c0e80e1b930c22874fc2cdbe0b5542732e8fa80e407a1a6e5af0aa3168a963587379aa3e6a2b082a8a35604bad827bd6aa1fea76a608100ddc40b17283eddab2335b8796dc1bb57887787a4273c4185867368be581f6e5767bbf0580f07b003556ecffc3ae336260fa0a80a2c9e4c9914144551c89a9d68373ed9c7afa83c75c6b8affb54187d3b46abdc61d9e070b5584be7564f932985ea4c739cc906732a7cf79a65f0f7b0682caa5d2070b3e0699b1bb3ac0b38caf22ca4db9472d06b02954e36c0a3d8890473588c77e43990da1c7103985761ca711109bec0b805607d732a36baf897e93c6d9a988b94c67a4592b7583126fd452ff0b45a033824983715c60478685b9c2d013d41b47eb342a05fb76232554df30990d6f1b37ea9172020c66fac8f415615ebe07833a2588ef622034074b214ccd9395648071821d1109daa87c0e00cd9573254538ec3b8459ce56578c09ca66a508e88c4dbf6183a268b86fa4b7733a8cc89ac81619af8f56d8adb1f665a7ac413005be730aa41cef2b06a7fba535552c8cef73e90a8584a8b799c323f61faad4b8c25d06cb883493147069eb1c9c8fb262b699693d0601262e9ce5b383a0d27c1572c49547bc908c003490827343a690859a15b20119975c35aa991183052f117b53d06c5f4683d19ca5ba6f5595b8b269d96c1b3524cc8fc6eec750ca33b5518603f59b50741d246642bb88ef61a8bd4c54f48af3f573d4cdc5143ecbddab5a281400721544e16e35ea7a05f161003a6c3adaf690189bcb074f546bc2033b1e8b00d56cf32e0733dc81d05eb358d148a91faca963b814a9c5fdfdb4de79b729dfc26c3d9b48a4730337b0bac8c2a3628268159979f6b10aa9ab90adab98b9c0928fc4e3570ab01f02d5a64c5f605596e3498ea532472760f61cb2eb734c174e48237c656636645886b65c566bf95d927b692a02f0100ce756a60b508a18754d8f6bd8b884e0ac57f0c0b8f12347d40fa30f364121147263860825461bde41136af083b303ac118d685622cb7c4092bc0063328a2484d3392f8ac4d91b64c2d19a8d2a1936efb0ad83c76b51310afd878246c52a2b13e8d3719a6729bbf057365185e997603164c63495a651a65926ec96c7c54a03cf00a74a83fd59b1bb33c55711c4e268ac89c730f84858e67142f051c617e131bf1a66fe39c5ba4d12676549d6331b9ab32a10cd9ab9a686216e0cc652c981f74c3a070a2520a9f45336b955c46cab108365861e5c79bd4f92d36959804bcb458f8436241ab5b204bc9d48bae38bbfa500de53a7ad671bd4a29057951645a346c2f7b1e6573323cf6836433505cb116361919ac640a8e504307dc9b0641a2900313fda004a1c4a8f0eba7c42985472a57adc37d90139dd6f23e39b15db0736b8616603da46ecdb42be478b728519bfb1a95a33c9b7c2a52fa1a089d647fa6bcaf16b83f27791a59c89011739909dc13cd0a8e32381087ea4024189fea9213f8fb3af02330f61ab15d3a31cbf57898f016b419430d790f4ba8a594e2ccb6483e46e5474518ccd033543065cbe6a5755e97790c4109a5cb18b124992d885493e03a262c3da395b46a069b9154c81294a7dd59bd092b69aca326220475fc792aeb639ccfa62cb9c549d28736a944af91119ad865c8e13700ce9482ab6b89fa7794f9d273bab516d142455a78675e21a8e74cb13876c82c738a55a4649304cb8f9cb2dce220c1bc06ddb0c5291595bd5867fd105236a91d3d61b25950c4d991625d3aa711a2449d118a51a88a1c4c17ca680c3ca950d141a220a0271a2b0593db333c1ccbe6a1380e465fe60404055bbfc511895861a32433a7037a00cac8197ac11528011e4eca80bbd921f2bb8162c0580fb94207c89471da649ee7cffa4293c4b6baddcb88efca19ab6c6e71f54814b8a2eff67ed476088dc30727aa0a47b81f9390bdfb93c3a8281ef3b92be88b130fa739023aca492549d42103663b97d7318c01e0660696984aa5c5bb1019024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785a41a25703627f0a51bfa82344723c0ba43184a77556b8cb107232f480488cb24f8bf324be8116fb49c8c329bbaf00c9ac7751a39a222217979a83301c0528b87992b87cbd5c576c806b4e8c383d5fb025ce83104fc5abc9d235ea374588505018c167a78902adf24f33ac22811c612cc09b4ab1240fa18359134cf4f657fb5c96bc544f83b8b02620b5564694284452d8d0467716bf41504dbd6574f5ba2879b674e9ec858700213df91f5f9b18686669c9365d2f2cb9def360eda91272b876cc75a022724c7caa7e003cbd0b8bcb5b8656fa7255f0c8be4bf2398e3106e47ba27a934896370d52e0cffd9263cc85b6266018fd6303371969e7b78d326c9fc2c9a5b1c32e68e218ad278a8d5ca5629210ba342148e45217d594958bc0eb6a13b5910af6f616e290472ce203a7f76f1aeb4651f00397fa537fb419ef2ca0f28834ec0ac07b11bb22b3a1a1b1cfb4679586f720bf6151662303f6fa774ca020fc03cdcac3b74c319c5b23ceed4c24ebc48f067735cd5a02f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f6082965579be60a0812d34361695ee6282998219366628ed9575203d6652fb127074cbaebd2c1b25c520468a4abab0b550503cdd33851ecae8bb27726396a15a63dc26078368aa5a7c1b075e781fd231ec27cac42eb9e507a82751b7c8cb7b3547b0a1a58c82cb99da9cb926e311b5a9a1d682bb8da2c40fb679ae4c15ea0360a39eb6fd10719ae253aac91132938579d3616dff29ea1d33640e3b71cf2652e85c786873e1457762d230e99b81db1a99dd0a8ce052849e1f8a5ee050eb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02907032337720dda9b9f8174fc20afb4439a21fb979af288f7b7101b104e2c7a9002b353dc1c80bfb00797455640b603b65c4cdc89254014079fb33217a15c31f6262c1430002aa148ca251aa15981947d27951f24030f9abc3e49370a94d803094881f3017a8be248e2c9515822439ae537776949641513c99c695625134348172b76b8ed929d1063b05ac774d83a3a6b0482eba52b2f07bd17021e0fc4b7651347f4b95e72f0a6d676158ca191a5c9975b1bb5b5218093eb9716e350e2d340ace90956c05b5d874dd60a7c9716894f551dc5986e378c830af8ce327a027741431d48714223c83f7b1dca94ca5e99814e1311c69481f38ba87fac128ea30c19b2baab1a2383113e5d282bbf0c4175a69fb4db66fe4421bbb26b990203929b3a58a85245bacede19159d1ab21537cd7861191d15185cd5b4f07a2559110cb42bc0cba54cff480750b56933666cc470b2504895a1213db43c5c176590c9d97ac7279d6dc55ccc7b1d4d82bb33f240b4c635a936beb5d71f787c396371c088d65f7b2a395071a4e6c381a1708ec05a6e55959845b456794055864c566d445ad9091834b77a30228caec6a0829bc243a9330b42010d62149d672373812dd014873bc79f627b25b1ecc782384e0dc8accffbae88c0415f6cc03e7640895c744f4707e130a9c9ac6cbcb70729db69ea7c6d8c8a9e94c1438c96289b41419af6ab083219f8a88753ca8b6ff168d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2cd65fd07a78e48c1a02e235ec76fdb509cf9903a4f5a850c51d9d3fda383cc67df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = fcb50c168f3358b2232b2f566c1da4da98f6a5b62e228456823fcf38ccb848e3e29d856e87621f63a33287c2e48fb861dad773a832f9d80d677e3d6c4f93e2d46bba6d8523135daabc358ec800144fa4b22e64843c1844dcbac3cab2128094434e628282f04eb18e1694096d0e19e3924045cb1a4a7805d879eb4a66f201809d1ef6a5523237b361739de7f5ca4e8a4e026128712eb591d422831ab93410d5a0aad8a86be6e8051ebd4119fa2c57a74a0f5fe71453bd80cd1e779df5d2fbc380a035ffb50baabdec86302e32c18dd2dfece9670f02edc07328033e4bc543e1306097cfc121ae9172d39681464c124093dd853cbed8138b891b9baef4633251610a95005fc6065cf747c964369269871bd4aaeb147fba8410b9c2d3366fefaa6a23c850b6d5270bf95a9d1a0bff4023d0c1593ec0e178429c120d16c88092c846d5607d1e831c7cfc084971720c9eefe55af3efb2cf53c8611f71cb4e25bab3c3970aa4e1d5f71ab263508d3922f4c188fc2dd1430e968ec49cf18a73e0080f29b1228a735ee1c9eb404eeb345996fe6e18d4bb466dd324f51817a612502d9c269a53a0a03de09707f772dfff58204ea9056ef052413bbc2e5bb771c9228f1e6d6d0e317cc254f2196821233165b38cf1ed26a407a8d5550db26e210a79d153084d2c22dfdae1d19ecb815075e8b82db4377b037155171eb02a88dd8ae4e876f13199655b66904ae4f60bbde98388a64261866404feef743f1246c7cbfebc6430af76dd70fb2b4212306846c3b8e9e2513f5f9601ae4bd8e3b892d98cda10fbcf55264ddf3ea834a8bf0a770c71cc8111061fc693fc3bb42b8d098ac54582b4dfc0ba6a3c58aecee800323ba806feb47068bf23747b35f557e74f7fbaf554ffd81b1af5420b2a4ffa23f56f1c361a02b16cf87e196d1e581be1158aa0973102519663df840f1a1ab7d9a553246d2249b0d418008ac2666481716f9a4dccd25a3cb38bc4a87cf9260cc9705229a7195c7165033414715abc58f1cd74046f06045559fe3083ca8a461240811d5aa75ab314ca9cc44d4aa86f792da4e020d3a9fdf18626162bd9ed2bca008b2d136f2df5a9b00deeeb7e292773cac02cd69d07a03aa2236f86938052f22c643119a072952b8ddf88d83c727b33c7ab3a4e536e96b48fbf3d2511689754c2aebb50f6c7a3c8b2d64c630712b33f1fdf17e4a5a523de991c2419d0607d8d2975e503122de717aeb5782342cecfebf801492315e2660a00d222a3d275b7f17ef07ef6161e7262bcd9476b1e963ef6199bdea3613a19851d375fdba192563ae0c17cb30f7d0b9672eca4fd300f49a176d1852d976b94785c1ae13a0a3dfed4e08377247ea088e01fdcec464bc125eaf7a57bfd25fee500252491a952aa8adbd53188bcbcea3e53e1c22e95b731e8053ad8c25f1512ee943fb1e5b744bfe620f03ff709b93715bad814a5b32ecc8da867fdeff6fcde7dc131633c530ce98e552bc5a7566bc46705e565e33560a37112c451c6305a601e4f21b4293d773df5fa417f2af26b002cb88d50748334e2157fb0be868022163f332469b0abb2fd47c8f0b36de48662f0af98fb33d2b6d6dcd6b49d75372e9a5dc37e894fc946d21046bfbe1c30447b39b07a05692ed580c8be056929dde993baae59869f35db1c6cb9477834d8b5885ea4d9389ca3ed96dd2e9a32c824c167d80c3efa57de8805430e6ddce94e086c27c67081ea4efb12edb1e596d3e6464a7ca37e34ae9635cf3892d1a523ccbe6dfe9697cedfe50a0892d084ba31076be21632de72a70136e537f57716218d6c45ba3db7caa0719454741913a40998125fa5ab84a6b86bb3b02ee1847e2a8a76e8497aa092c4165701f894be5cf024329c17fd166dda767e6a8bce10834e6c24087ab22daf5bb17ba0a58fdcf989e829f158b817bfdb3d281a0220b51716a53da3a84da6af40d64f45939f0072f007b451461fedaf3582e0c42ba16a7222dea115df07775d5662b51442595a26311abe6805c45db04fe9cd449e187a2e6438b4ed9518a4c9a8b21ed4431d4068e3fe2ec34573d0713ee9320e43ec320119cc967b38941dc794f9460cc300b91f7b831e72a4dc34f607caa68f68b535995b9bbcf51ef0656787128a0242748f6a976af65bb431b6dc45dc99196c2877d2f56bb392533badb4d1eec1dce07e4f5a07b59e319f88 +expected_result = pass +expected_shared_secret = 550b4e8c00bb5ece74059879fd14f5a0a89073d8a54f8bf1597f1ebf198a61fc + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +private_key = 87c0b4d44cc9eb48c126c5877ff87929b08485fb81e479139c3299c70c43c3fc8c238a81d4e61e62a33db2499c866b7107d116b7fcb1b0530a7e758a8d487d11575079265b3158302a23732bd07330071bd7cb7199476c39b583a2446109e99fd5c95be21a292cf37490906e84a82605b8455825c82eca4b7e218644460ce581214c78ac4473688bd6a9a826217490ad791b7835a85935782847981ca97b6dfe88b63701cfbe3929a2dbab1628155506c353639d153656b90c5aff36baedf1b87da5bce2a108fb6c3b29e77dae803a0dcba48ac6882f6c1194e88387f30a47c27d02c37d988346a2a29584a55cb5d3c44c05a18619a4fd412babc31a046221b3994c8f22ce272c9e6e948c3d043295f413349796c38911f8dcadeae47351c15e9a1743eb65bdc7471f37fcc93cec867cd4808ecb281fc17efd004dd64ab432d664864b43f8a9b1e763529ae2c413abbcf30a4a478a30a0104d802037c4a8af01b534dd600e31a1630ff13b2f730924cb790166af3b7322baf4409cbba500c1bb32894e65445f04e4b4b4933de51267635037faa44e2775caa4212f4e0600e51069aba662c86145e2117347bb1748d63e412550c004237cf02b02aabb18d8533d19b1a879a079b31d529aacbf5258483c80738b380c83119c12b23cdcbc7d027506f3705ce1316dd24594a4bd32d10382f8ab47478f23763898398d7430264203a76b0c4455237f3e765ea5516388595ce9e2bce2dc2258b5b96c782865fb5354427a2d7806123b0cca782b1c329411c6c133934ba4a959da88a072bc6e2d63a007572e36b82c5643564bec47bc8953d4aaabd146ab5eb36e33f825fb9ca01e223253c320f76c98f810ca52a2c604622f7a60378809a59b19680aa69eed2003e272b8a1f3c8a55bca129640c5a00d187bcaf465204c73cee66a2feea414f02859c9988356d26665196674d25e64cc5689965cfdb2c0e47a531ce32b3daa9c649954342a3f62253fdf826aafca7dc85a7a8e15161435212d7a4a3bd4b57a2ccca3506999d407d9b6abcc97209fa97454b0974dc2c7cf3c3fa40306cd6239dc450536974a8ab773374504b9889cb42bce4ef4606bdaa559346f18d087bf8b7f0d9b21b0c9b75b5903194b0744a1c47483488eb4c1ca2c83d8198cc6a523d9329f6582863cac2951268c01770a8081c1c26587d7610088e6068e020e10472c825c395ac6783f074efa8597feac3734399bfa247e4e1531eac70fe49355e44b3ba5439ea1e65eda94485fb710124bb968490f1c8b68e87a4c4682156fc06a33275b6b202aa0d508b3789aaca627f0f0c19026cec38a95f7547d936b255be7a7525c97ab4282714c32a23c4723a82298f2ce90fcb4761b9eee869e4d3484ba2b222dc28bc612b1f41607cf57781990009f29617549c0b2179705a34916db154aa3747867c3ef6a0693bba5c1d42e14b3247b41059f92607a60afcdecc1c6f3839db943f5ebc4d340aabe21269095b3f7d9bde9ebc21de788794b63e1098cc2903a83ca2027e8bcb78b855fd56fcf16b45e47994aac71fc815c521ac1a1b697a18569ac2816f52640cf9059c4eb95e6fa1b32b77bd7cbcb6ab384de74b6a2708400e980eef5acdbe5733be895b64107266c565af2a204e98fff0058161637f5f0bc5e539bb0e12590a00f16f57fd0962b7c9589f6d3062d81860ccb94882c0a06d5965cc9bdf6213215867f1a0c30822046c985896f62684d95765ae1c25501186a3aad77820aaf43c955a83a259982c77b2904aa471bc683bcf97e65e27cd82c545b096e9b762bf3304d9d5c1f3e6663cfe80953a86abd0007e1f2628210b042f781bd59b2dbf2899b97a0cc345628c4c3bbb583d8807140c46bf8931ac3c34cfa78230882395fc1a51c1b50ba71274aa2383374b3ea238ce3b87247e0ceb0991ad9f74745698d06c1a5ee089e48d9cfe46a4fe733826462c188e8615aeaafa501b9d6c6a96ce24ca097187f618df5686513684ce2a9077e81a83068423a916fb4a8a47df2cb88572f8fb4405ae59391566c88872f8ac48e705b0634a370f0ebac6cfc66c4b536d3bc22459b2b3499acd921367459c4bb3a2babc2916e9b99e86a6c649c18c8e946eb106ec7a97595a503e42419a23109f1415e329290ec5581f96c8cf1564b86096399f0415e5b757e7a6f9ba5120dd8a938e06c7ad8581fecb46b60afbbb444ea375e53837827f80de1e3753a4aa255a4917f1c8af87923f8397c9750cbc7e5864049315e718aa2732b6bf7be35694468f55b45449934715e460c6eaf734f96a1adf87609f8551dca87a94f0217e4e507c2b637f368ccec681f36d6cdd469be9d0bc7828c1bf13a2d28b8093b59a174d271ae9736b6397a4b8c9e4ed085a705a4987bc56dc172caf58e543bb9d151b259e735ca851dbb685d5158596d61a411e7c542a240c4900bceeb6e6aa7acc7db5dbf60c178813051574dcdfaa38d6b8eb595712c8b758f7827a981944f550597d120e926486e623ecd029e92825ebae4b6d049011fa7216dd81c005b376bf6b1171654b5a3ba932bc98111b8213343b9e18c9e7479611606961b476adab27e457225351e2981a4e65b6a7f0b02078505d7d3b7dd671c1bb79610dac7c92518a8b851ea5c3115f5cadad3cb24923baa686542e83482b725474381409a4016e54066c32420e99349d0c5a32ccb0b010983b96f8c657018ac0014a34020888317a13c8296a5fda3937ebc61f2d1022b2b00e7a6341bdc70d1a11b9eb10673c07e612363e6f0413095561dc15c313138efe56c67877c51f216476ab182a233f34801205a9087ba56a938900a0cced6e16462a5bf746ab679aacebed1b1b62b78a1e2aeaaa336f5286a84fa76e1fab798749d8eaa1e71c48ef6a08977235ec54179cebcc349863a9e40b61d68c1ddda72d60b061f0c42e6c179c0228d8722ae90d022d9747ccf9326e4e27bc87257c24892043aba248c1ccb8405a66712779444ee39bf91292b9f926d1c99c65a7941bc7c1378f682f390b855d88273e56fc1067088232f679c5544a03b64cb2a8d9b8319d254c3b19aa6184b1db0529bb9750df0cc6cf5a39b7139383876f633763cd07feb86393f6053a25b043e6b736b0309e7743103f0262133a4b701028db889fedb88b0f5a49d77938c33a5af559468a91e6184bb9ee9bd71d060c6f0b2a2413bba67493fb9a12e7b8c4f35497ec192b4086b4741402e46c97dd85f12d79a9b915160c788bc552a00c8ab88b50506363ff3eab9f84b5aca7460c882015ec08b3b4155621558effa01b4e1c3ffc310a2405dd4d4561e8bce8af738cf65279fd56571bb2a76faa6b1ba9b0b9c7c8e8c9349d504952c8883a4bea1c2c7f0528840119bbff2b2887310a7f1030bcbb0b8002402c2c782c183853658fb374de5ac9bacc24dad86b088daac4b62640fbc5eb9990e089b1f49e95bf3471edfa0521fe910c0da89a1193d2acc253c9aa8ed15bb4bcb16d3c14d262895d594693825ac0ca0567acc11c94a6c27438d6a5403a320b2c4c47400a9817a2296be402dc688957c7494600870e84cbaa433076b201cc64b3a3a51311f7c5a3ab206fa37c0a1c98048271648b5a5384c119dd73ea44370358182c713ab2e399655a171670a5295773d2c36b6e4b934599656c7808f13044084a82666742eb6b605dd2751de5872df234694a84397aaaf3b894e0a7507c3a354dc3409ccba4cb16b5387406bf7d005a17352c4d331b7801596f031a7a15044e1bcc00c4a920a1ff7cc1b904847977261ede038c5c51841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c45c2471ee52019b952bf716a1bb4059549a8c0bba67519ad4f10cfee06bb34496f38f9491c172f2be413da1b0a7de20dcbc1aff4103e546c8fcbb20bdca475c9161dcea2aa3ad534fdf042b2776b04477b14f2c705c85b3a7c5ac3803b3548b132c6af8e90ba88ba49981729a8621f30c2aa0dab04b49bb28abc92d9cc8311faa8dab45d545611a36b86549760cbeb4ad464199a35811a63cfa00a8a1bfc202ba75d73560eadd235c2490c8e514ca29b30ddb0996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553035201e48c406382a842256162b067f887729e298436485f10236f67f96d263c9d0835171dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99393c1c35cba50014163c84977edc8f02ebc9b5ec5045c6b1091ba794303e8bb52c7b8238a635c23d3c13d9e918d29025474098419aada6720c70da55905c197c1114c60054fcc651ab6aa9876430d4d530ec7a7a734189a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a376f022313718aba325ef4c3b720e2c3ab314ace74e983948ba2e43ee3a6ebde0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = b2407a93eab248e03dd8b32b67d192b562144cfc3f6c221a1d79bf545efc25a585332391ea28202105a03af661b765c19b832b48f15b7d94ca69f8f60db0754811c749005ea0af732bb6e2ba28d81c6142b02dc19733a0ac36b775bd617e801ec4f2b2a4efa3779a76ad443f6b3ff9a362a7c08493d33462aad8776c4471bbb79824842b4757a1d884b457fad025bcc3bf29dc5aa61d922f78b128a627d5dd6c84986f2bcd22182c9de1eb77b0b2f7aa81207aa26ea0406bae3a9ad686ededf3fdf43e13eb6086a9e308bd108e05150d66ee98d04e1b549998a148ee54821aa2908ac5b10baea34b2407158313aa3a9dccb1acf1bc5e57292becf2844869e6f83a7b4871078cbe2b8760f0e5ce95fe02e2b2bb71640cc7a8ec7a23fe0d674279e52e4b860136cd359c5d07c2917c1c9ab1a30bd27d0611cc19f5ee7fcbb0b460e98d1ee4f4f69abdac6fc1c10fb43cac153d6585195d0268433430b343e78f7482403cb341d250f741f34508e343d43f233a87127fd6f13272e12a2b73eb390fd0c9500f5d36a5f8caa8e9ea69e13506b2b10d0c3c0c58fbcdad28dc83d806e656925b365c598860f72bf087345731ae2165eb46c0a5d44ac43c9f1745f8c2feb805afccf9b1ad24cad13639b7938097d9314ccb948aa45a8479904dac754fa3f1a24327252724492acc9c3d1b4ef4d4ed1d379495dcd3df5e3e5b8fc4739282622fd2b73c0b459259f9151c33395269713a78b5bb8285b75f33c35edc6857103c2ff5f9148e18faaa8a09b2eeeb2fa73b8ffe180777c69c8f4401cc59478936b279ebfa6432f02c01e01328e36650fb2f54b75a2ea0434ee460ac451bc828dae2681ba390d304c0ff083cc107f9d941279d1cb34a1fd13c7ea98ba108856d4aa22d6552563b05b55742a03b815c8dc04ec503a86a79c20385b472cae9e04e1d288532629048cd844184984fb1538867c14d7006fb11baf5c9630e739210494f6f4b0aaa20ed6adf3111ce159c6ff6d70862824881d29ff6e990bdd18c4caae9189d7fc4c7a32bf0edeb435279fe0b38c1d7f2ab231970a1cdf0364767dc92e730b6d757242d0addcda7e4ac1da31ea5a722be4687ca79637246a6ab01ddc699627939799e4889d078f268b100ac98f3ab248f7ea7e1a2f1cf92f9b107efa0aabc8deb3be2e108d99b5f113eb0430065bbd6c681b3ac9b28808ca224ce44399efc9791e7432ec64848b92ea2406d6dbd8ec60387a0cca37c9789d293efd841ad0c19b0253dc8f27185983219344c0e895b42741995f75e7ed74036024875acd12d1877f658a4cc4d2199bbc7a70c9bd61607ad1aa708a94bbd6132b7063ca77ffcc9ac433426112e960eb210e914f03d8f57c1e014045d9bf9c25cdc399e401c40d23d47e40f5c478a864cafcc3a27d39c927d9b6ae4cbad079bc984343ae0071f1a9123ba2335a02b49d1a51137164d3f8f92b9493d8b64e312f7774543906d5c5f6c545e4ecfc67ced611b01fc2c85fc33dd9eb3c287d196eb9464660c95a3a67cf8bbb3e0d72542836c53c6ed82b4cc0de8efc7689243b5b690bed176634abd962fef5a42df66b87a2ed6eabbdb94dca2298392acb3a1bfdbb6e254f10debaff731ad7990ef1e6702295b4240b625dce707cb27b86a5cfe4407ccb8c27c8deb14a6def5a187ffe1ad23450542775f87e0438ed4dad3eba330bc7d54503a531c668674d52dcc73485f25f9ab79c1ce33ae6b464a719a7bbde4865ac2e5a10dc2fd18b09dd19da0cfc7c46c4b2b7a99de777062e9298d5bd31238a381f8c565a93c5a105cefe6c76354e8231ca91d4b75505367af0b1b7a7a424208bbdf8c468be7c97dd1512e927945c4b3a4f594214b8140d7b1a7566fa0d9514d1b828da6beef5fbdbb1f09a1b759b4ce2ee18a474edd188b889c5a9af2cfa1ceebdbdd83dd5738480954fb4d19afdfa3b31dcd2a85315d6707899889188ef3a392ea331534536f7158950f5cfb79e90a4688bbb3d13adf46ab60e7d996cbdeff1b424eebbf41d35e92eb710b4f92fee4ca8791479c9bdbf8468ece24868c1c875c1e2c76f3ca24d582e93be11e00a7e58377d9b395ce9ba710746fe9eb78ca29de5bf92fa5703fd36d98711a9863b7aa40c0e95d488b6ec72680abaaa17e13b8fbe7dc30888ce5acbee633370ab5546612f4602a4d9242c91714024a98c1c3663d4cdbaa +expected_result = pass +expected_shared_secret = e5b98a3c32a5563c49df725e661a9f44a20390cf83a9779ecf5e7d9f5aff0143 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +private_key = 4dba785b32456e16a8e9a20fa7536f1b4555a9b403a09738657a148361788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c12c284f848b89585f76892fd65cb906d39b385a04d2f5b2154abd1e77ad9501abac73237780b33c601fac50ba3fc07e8525819593b7d7e69fdea46f14f1128a475e4784af38985501dca6d20bc8dc1c5c7740b33804358f71b6e97b2a0e7350f7608321736083dc54e0253c6e5c5665d0b7e68355d4e98daa753c1abc1429b397da773b043459e5aabd093a5b0210502bc2cab250041997861286924aa0a190307431719588cc2e6fb68711c964fc20393c73b7c967c603120a3cc11b2efca3dd6616d0e2c835fa92946a40c4cc2f4655301ecb09424286b3c7a07ad3c6ea37bf6132aae2d9a335e34b6c816d93cc7ede020ab723b272b70f494834ccd93bd7800bc39919dea4be4c585f827a4351e233026760dc83377329ccbff180a562ac50833c0f861e795c00ee74b584f693222b28eefcb445f19b06154abd0110c6a017ed525b5fa30c64e60663573b8691ba68e2bc580157f1c66ebe388aa2747c50919af644acd903a801a5c04a6a2eac686c89835cf59a791ad5642274a0f78244491670c66c9bce24ba5cf6b86967aefe6728dce8973fd29045db844dc80022297cf530c8eca4808f603a90a840ad70a803e6a0bfb44b38616816073c5d7ba26a64048f81a3bad3a0c9cb0672c7466e38824529298a7c0d82940540c312f429411b403f64e419cf720e1f73026184cee538b27cfb91f16186dcd3904ba6a34254155b3cb3157937d5618568f46f283c7c0e88696324a4fd77c3e6fa5b5dc0a13116274e5792fed69eaba973730a79878103bf63934d179143dc23ed39585d40c06a99aee0f4462f123b8a6b539dea9e05117b08338dd6754398e7496f612b4d892ca54a13ec9b2dc7022cf779668809ad6db97a6e8b15ff0a862e664d292c4af549195a23c19e2b9fcdb9b4a5b9ae517873ccc644993196de5c2716d58d50e7cf11558f44a16580c980654c8ca581671121cb2f8cc6f90529c9754cf0700b30943eea1a7b05f0bc8fdc1cf776b0cf2c2eab927dc83197a4071dabfc07f983bf4d2c613e087976eccaac031b88420ceceb6df0350f04ba61ab39cad4c6b2b32503d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5c40970c435508e26cba50705c6538686249d344bdb7c820a5c8869b371b8fe13922a5af390bbb7b809c392266541671c75cc2b7a7248d0234fca16da64265e5c70257d770d2e9982d5a1c6d19bf0ba48b53ab900fc8280c754c14774939b83c63592a12f35d198194679942ec227b46cc8f353a0547e929175c3585107239aaafca151df3c835e770921e5c9b134ca7e27a18c7656bfd6a4fd2431ce1743576e575dbba8905f4cc38108e3cdcbf0155b5300a100958aa99940bcb473ef64b05baf55e91952c46851d313b0990ebcf2148cf28130cf49c8d080841fb81384e73367c792a11099f5b898416946826714e252457b23a3a1e33a36ee2612372cb2c04030840a87f96a31913a428cccdd2817b38372da4637f46044f2218c28d525a57d9c0cd2864fd43aa5c9a003a09a35ba786a7520c9d9971d6258cf3c6695885684d1a5fb2b3818015ae887555fb1997b7a35a326481a566839712033a0ca13a844ac6f21a16269876a27b2d49458515b3ef0a77f933c9d0f1406121bc8bb666a1284798055595901488439150db602a5428ecd32109731bee5bb8de606ec8d227a432994dd912637bb0b3b198171a89daa720bb712cb598a75b4ab304a9468088a62d0059dac56e17bc95eeeb6c22db8d8ea3c6f272a793e0358e193d52029e2a4582cdc65848c06652e44310506868365012c9befb412d1a844e8c21a613627b4707873dca67ca5c0493a83eaa227fee44731d24938709680e1879b2a41b12e71fcfc39cfd81186250b6cf4b5796e831a49aca2b8c2931328ded15cf2d082643735ebdb8ab019609ecf95f5d093a147c3caa73946cd38b4e21073bd72ff958c7435088ad73a5d343ca768a4ad4b2a49b6b6e17a94d909837e872a05c815d18ebb4e817bdfb327cbcd46404060ddfdb92631b2e3e262283bc3292504cbfea8f30f085fa12270c834d6b6a5d2a46098f26029da3bf14b0961b350facf720ae691dfc4a847b143d9c9a2d2e7a35b6e33dd78b761125bd8c4b1d6994cb8e01186dfabe6270a51cd85b8b39678af4c337bcb4fbbbc0fc260d48aa801f86538eccbd3787a12a09b42e18afa2e8c77bdc11b13b5a8404cdd7b2ce364046ae059a4c950e1e4638ccabc8157b97a238a6fcba379bc6afda874335956d2325376fe1ce4405bee3e37ef818b9826743266c078c01c36fd62b1d17adf33467d9c1ca9f2ca28a2867bf7a8084daaed0a19d2d40a0979198135c229720205763401045879ed65b09825012e626a24118cee00216930d44a9bca32bc74a6683a8d1bae1701b189bcd8feba2da42cc3b572151e7243712789b2801043196bd8c15d972cf7674771dc55e74931fc0a55c434497a517c99ca3276d262ffd83cf66d87600d097b1ab5dd8dca86de94080da8c2aea980b3a1115b847786aa96b94ac818148e3e4c7fec633cbc6bd3104ccb216074a5b2a8c757a455ab38e1333435c3c30d94d8e922e8e77c0260b6128865bc37b82c7a6a276040edadcac335a10b569a2cc53a93b6729728b84b74b01d502b830330000aa1ccc9c4d7e7a74ed218d47ca60016411d7369248a261d6b6240d5b15d2fa5b3229373484c8d23bc8e78830062959d0504c92c0bac310967ec40af0c2902f82742efa78f57b70bcf54a73aa2aa93b0fb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad107711aa1729ccf857a14b0002f61575365f3ad9c18b947bbe9b3e31a7571a918728479710d64dabd569873461e12a9dc1103ba28028e001c8d5a79d24d30756cbb4a3ac9e48435ba09286ae89ac3c841e8909a4d94226a822c90b5a40f239cb0e8b98e86b5b06e20dd3764e42e8c8095052b1f66b76f164b3b867a98cb299e0995d44b5febc7a1f2c0cb2d0cd4f3ac5f9d5444797941666afd319a3c6713ed1e31338a41a6e2b548208cff5671a6fc7ab5df260c2d8a703a67eafa381c9d576c6c2b1177b6a66d951bd3c426fa79cc7b552ece197c92856b2c7064605079404a3b5d8b49afb9c87ea48e0811a61e81e2f101ca25a6a599947341040e381a52cec894dc9b6ad25b79dc903c35c450201071dba35ef8c11e17a1ae5ec7e13468c148a5946d928ed0321d717640e5a5767942ef2275e05e395321052e3e5059af77fb04271c2e511f450be168aba09d3b9eee1288ed1baef69ced005797982316e2c731f9581cd455300f35a6e1a5872552ac6eb68ccacaf636cc713516c275823e4a1a30a722f8c46a8932550db624dbb8b6e0bb51c3d54089fcc2042f38f5cb5988e56a1f42a65d5d788e2551f60487490b57904127433f685ad4bc53d6213cdf52d6b0991ae37882d37b5dc084e5a49bef660a4e8d03e24ac93e58bc05f8a759895074e156c09e73e6782c00a6cc80cd04829d270c7848d89bb2c321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a08314b29c81e31b63a008a51d283bc217adefe37d2d9b15c7257cf62a68751c2942c531bb55abfa321c581822c90c243d94b598fbb958e5950fd4c8b1f1cd06bacc30828fbf73a83f7387ca252e4f9805419c02d63189ee7b4661b5c1bd398ec82cc8da173ede64a38b3c1ed53a64db130564d2a54600bac8017d46507b3d56208975a70351a558d5774b249f7d634e6f21102310b6bf8c1544e217c68768400c3d721ba5c0f77b9d20795c8059145956ac7b7728222853a3c325d070a9eb256775c727118eb9cb7134748ccfd09f32c930881826d8e20af48b2e1ba10efc67ce0ee7730093a7305403eec951f59044a5f7317cb85caaaa2e2b5b90ab2b805a808c1be755f9a4c342a96e8ae83cc4394d73890f13bba0d35c45393730e4118d5345006ae62d38445666cbb7c25823c59a9d62e08bb8c7cd22b331be153af7c359091081fac67d96384100f44951422e83599763ab739fbb8ba2a064a41cbe1679a1c613815e9a51d5d6251ee73431cbad479cadeb64ac94f92a38d0798a4b6d3ef7233572b68d2a12d125a6d4e27939f341a4810f0c07bfaf993f8a74bf8e9710e7b29389ec3dfc498a4ff1839a1268db8b70e82670e689b5b3e333908b6e8b4a78fec249e798bf57b7ce985a42a5269435c81ba441230ea52319550476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd7944e5d79dabf7b7259df5ced02669c81b7dc4590e0b10764729d812f6bd85d74f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = c1a2cadd831afadab4b54857c7e1eab27eb6c7538d5d78622985384a68ff6d1bc4e8a792306ca33d26f5b26064703cad77063ffb3e55f9e1490397b7419c5906069f2551c993b0b7c913af47ed040735f45ea5a179a29bed28bd9bbd06ef9de5f8bba3cdd1470f533f69cbcf5cc473307862a5185ee4bdd08863032f6c38659980c11b05150311ce50e5dbec0e779142930d87b3ab966156f7f003c3ed6180a08be3bb52f9ea2e11008beae0502fd3c76d44b19cf1c1dceb7b076756485d446142ddd0ce1c6e5006ecd91214a6b735b2691ec0641625dd8d530f97ff0cc5134d59d17fcf612048af71e8f9544eff4e81281e100607f520bb7c7c6ccdbcf2bf68b1b406cffc7ecbc8d41e965d433314ab1e68df9620f5eb90a5eb73f00fb516185c8493d9b98cafbd6267c3f1ff25d5e03c41d0a862b37faa8fc3efd0fe2a979c7d2b4ef86e5f9e93ed1bf31f237db36bef649a4257e893e14ebdf6d1407488a2a80818a450316691641358438fef5e094b2469e0ebe4fb9bf4f503ac5b161ccab279d9535cea2e239475354019dff1a3c2274dc6d94eb9182de07e12d00ba1fee95ee31203d35536281279d9f7d0929fe5c7679ad8131c0036f5a7a9813c78186594d5ec9b2a0c1f8e5cb531c822cd2f4ba099991b910f95405c964bcd3779e23211148ed68cfba4851ed5fa80d601488c2a0611bb5a8ac49912a5fa6f250d360404ff5f3421504442fea844b90b9cf9f2269d210b33b72d31d2f163b3399477fa2c04a6d4ac0b57d9e7a964c3eb96155de04361c4fb6819a9c5c9073f47cbba4039779af6635ce90e8d5f5635e4391709bb13a57c5887bde69b34de173d14f52a70a9ea53e8ccf659a3c4af4b867a9127d0d84644259413fddb18875302bd9a99e195760724b3e06f6f17ffa1fb13b90cac5aab72abc5b1999bcc8004f6f9a29fe8dabcfeb6083c1e5c87d7eca5b9595d5d725889858c173a13ee943ca2666475aa7b90e043ede6792e56ffae6081e6fdcd10100440dbe8a3b3f7ebf6f531074e870d7c57b92621c02d8892e8b1c29880b822e6ca8904ac37efbe11995dc3865a5e443805f4429a972f1cd6cb8bacdd119f6fb2fe891939e4ffc4014f3bb5a083f6fa26b8b6c17b064f5f19fad8e4260ef2ee8d0f1c2b20a01aa53b245521a84b2ea891af2fb004ea5625c5b59ab515aa162fb0c512bd61fa485016906fafa77bd86c6cc46fe96448a8208ac5146ad32b14e3cb0b41209e9702276ddac1e5a261b9d1ee756d55d9eeacbba104c93f80f36f1adf279fc6cd73744421298ae6b7a5fe33e025fe3c83c72d21fa86fc6c2f1366582bddad8544f886ab61a8233877a342a033c8c16fc49aa721f5a9de13b139cbe37a1ae746df5dbd6963a844bb729f051ca000d101aee39d85177a3c708577c4743fcb250915006a7324024cbffd4342d7f4364851845723f16b5d87ff778f814fb1913996dfd1dd32364b2f9a4f025bdd5dde20251324f2edc9fd385d3f84ae4f071f866157d218ff48814ddf81100c59a018239365b22e267195363aa3548299a0aff4dc9febd6e5e9f59b24fb7767710591ffddfdc56f48dd07678152bd22440d6ae864bfd46da4299c1bdd22c5d87814982e9cc451c0bcafdc686c0424a84b012d75f27f7687195e8c934f7a6233fbd06a519c045d13eefbab26b414098bb384b5858d122f9235da4f21cd980b4ec1399f15643132ad31531134720ef8c0268a325b23d8d0c2a3c875e7bd817037013aab674e29efb2af86c3185b8eedb4fa1c89e5fd89fadcfd43a37f3e2517e978c522d4bec552fe22adf37c3df8aff7fc611e00494bb36bdd24fd4c508f30c097d6de9cc3f786b3f17db1ac06715ccab38b8825628b677aec1ad3ed8533eea31db6ca47fd6fab9f0f0a3c668b402b9099618f388a326746a4dcdde06d3f51f1106e805b6b0177c8883ece5530a52275c44c1ef25860053b6dfea49287c9ac4c94db1298cc1c782bdd5781bc62bc49490bbe130a60dc47779e8fa16b66b61a56577186e6395418c73a0d44ad453c1c96949818db8d2145d4f5e9621037f06093c3f932d3c5060835813c5682a3ca81c3513f3533673881de9973442818ea1a2407b67ab76b3472d54a99fc35c9dfc1bd50fe38ac3970d73aec2582220a658c71be9424d0f37ca2ac17674298651160b0f839ef7dc42db08692183b5fa10b +expected_result = pass +expected_shared_secret = 169929e655f214d7ddca31eae7ecd2e01d9ee0601fd4a2c3a59eb701ed9522ab + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +private_key = ed55584416844e1cb3c75acfb3771013d1aaf1fb3ca8a5b718a8ce02a15ae26bacc7534f8b084a665b0608780e532a161686b07faa83884c6a0efb490a8a3fcabb50add21f58ac43ef4355246b1a661c5937562fa6067e7aa66978e4b36ea1431ed41e4e4282d4003d5bbc06cdf7af225b6560c44f43a278677abba8c6b79741b3ce7c0d0769ab407c9b39c032f0e42d1866addf2115e2f3336384c61ce9319cc92ac1350b264cbc4059b94372631c8241ca376aa6f76111537018c01d1346019d628f1f00cdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc957716373460a7a94151cc548f0c78aa5a323581c192d00b4d96219806a04b1a0ac829002b7fcbc8cbf8a8e3abafd3dc2164d03a24c19d50133e967c7668aa8b81977b400067fad2ca802a76716b95e3d28be5603e4977c33d3ba5df2446f6265827464641204ed972286b58567ba129bec0cd6f1644c4032edd6239309aaa259a3d997b1ecc535f17d773ab1c5350e3c82c600175269700a56b0d4211dd02c13d4bc7c54238f40163441702613a1de34ba9b0b42ef0a29300098667e8003588577e64b031139dd2180db113623fc4b74e946eef86a1a6bb52764c6c12911765e37a685400888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2e818ae3b7480f500fb6bb03bd50019c33bd37b060bc2c45e8a2267d18927c0af66076619889ff6b1769fe59e5f131f5fe40db2815bb6886b7bca9da659935db493ded9a808157e4151b04c153e673333424b7aa939559e4ca973f7644a813b8d9c1db8c87cac6365c0e008e329403c69490976cd3f006f3138114a6b3e6b3c4f054451e5bbcb7d232f285a2ef5202b81740053512f8e4b33fda87ea61042d1f9736ed58e9047c8744735a728b636dba7abc33b2de0b1572a28b23c25a8668cef9291990a499bc8935f955e1cf0301a65be870b7f01f06099192431f3436aa5aa6564c4689c1d2e11540355138c91ba6e0182b6daba0e7a177ff320c6b04977d47da0d51672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca611893044460495d8a46b242201886cb52e38d91d25d7fa8262290628d91323dd2a51f8c7a33487232f4934133117699028381751d8594fd94910ee4115389c57262ba579220567a7b5b42441a641fd6630d7bc06802878c76bb9ea576965ee45acb90ba549a01b6e873a1d8c741662067a116e64c8897e83204170c9bf2676ef60c20f3450804c7a1b80725da17f9db18f715b7894ccbb53321cf01755d168d19a96356ec07efc62d9a8c3a8ffb15500433f915137ac42a474b8e43f283bdb2b46cd62d509a5aee8cbe23b74cd48079d82293bfc9cd931289a0aa27d8a930beb2000acc2019e3cce107a18e9c4408c516fbe19e45459ed77231851b88b6b73156ec820a4c097072c2fd61c83d23413ad510662894daeb238992138f98185042b53a637aefa83378b026fa7bc314516b25d343f0e0aa7772cd2da27f8b39a8becb44923792a7d586631b2ab963ae537768e45961f5f96cb42320e75738a964168b9403d5b3591ac5679a61857c818b2a486bb299019c7b03beb50d2d40a17e84712aac01895ac6f73c0e571b779f71c4691ca515592bf6270a32c58eb9a494c1a6bee0d86581135216441a8397b5be554c000342172728f4dcb504a11e7f594d7811c21b7a477f2526d817017e5c87c6b376d95c8c6ab628110762546188f3f602359a85b422aacba4802417ba44b98fbfe05121cc2c58515cf2f3979400784f6152925a2d52d07d15a69a3e223feba90ca1b3a112947299123912b54321344ca400cfbd996d523b72a505a8f0945e00a65025015c3f9c7132d48bae4129a0f0c4e22a1509c439c011a2e1cbada30453f6110dee9c7f4b0866aa92cf5a31667ce38f8d871f9902bd5e2a2b7af030367a6306d4c48387b694c7bb2169614a746fa783619f9c7264d32feda59ec37063d1f11c6f5183f0e9be5a493e5cb199358b19f1706d80844ff2968e95a24d72dbc348a88d0ec9bbd01c3018a8147291b34ec21290211304da40c46632b352810f0a2d73046417885cee0c231a495b7db834a1336980f2b34cf140c84ac878c558cd937b7e0a9982f99b3c8abddd441b79f621764ac38eb8491c75171340b7774793b7912bb4186a7e3837e33414af6aa211061f3831c4f4b16b753228e998a721385d7b14211d8a7096c54ac3101dda7668013cc1555163f822b1cc144e240c284dc87b5075a813872511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e39298872552f8bc4b0df1632255588ee99b4bd373a21c665574bcd3fbb35690237a6cc691f80523390485447be94b76fc219e7d75c6649ccbeb00271fdc1d666351f396c08eac20ecfa784d45bd4d64847ea126d9f0a23a3b1727396f299951f95a68efe55c5d4c792e136148aa35d0663d64f2c040586e44b6cdf60c54e0c08f365001513694e27569a3d6c6ed2538937a7afaa0bc2ceb6b18914ac77c65922ac49e47c74447b889a39344db09dcf1bd73ec5c48263c214a1e946b2cb806668a32b83c0c97ad547989836a53f1025348ac068a69357c7f46c69f963c5634908b9963bdea79689b9679223824faaa920439356c10786a646472372be8729c4f2ba1e2897728cbab136757ac5a75242608d6d10e20aa6446a4800eeb621ea822c1a61eb7c5b84e764d83452f60e5bbe79b275c4a4445715d21ecae5a569073475a74ba62383137974bc071c27cceb5bdcb1991d393784ea8b28f259b118089b4b77f9b68ab0ca953ff8257a3938482313f4c5963c4b101eb0321d608c2f3127cf451764e15636eeba98021c963f359d2c44a9e92357f2853821ba0c8105c488b242d9c02ae637b2002ce644132069a8babe23d4e9a056fa0b8be8095113b86e6b5c748706924f6aec490a46dd398444499b95289f13a84868188fcebb861a004254068f6d9b4b83aa81c9b5433c70868ab5364a80d870b841a216506663aae569b025c5cc43b2e5a6821fc300eb6574d0088bbfb7483959892703666da17797dba514a489376b19707a144b6f80423073efc608347ba2e639b0c8f2a52ac959592b0b0c1a5b4fba61483f225344051dcfc4ec124a9d10cc2c557339325c699f091319853ef7a445b4064d8e66895f8c0bc887786f5240b72c319fc0b55933b5864063d14c5f732472c71340ea26bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa110e2cfa9ea61287716f199af376b106fb097760b3f11237fced41eb95b798f2787b3039f9c213ca5699aabfb03af86adf5d52d6aaa1ea952bc04725a22b2a28f4006cac30e265c793018145573cd1c715a69d704217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbecbf25804a210daac80612972acf605e91303a2d59b1ac84ee217872bab85cddba9c6d1381e312b4c574097d95b8afb595bd91c46fc0df0a761f596569f99b7bc6505e922a1f90c045493cdfb9a3c650224bdcc26ca199849128945ca5f97e230d601283aba102a26818932004bb114879139ebd637ea035c20c3ae176b70999c3ffcb7951742c73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab4d07bd6921cbd95c18ac60e7ed35aaa352e143aa1fc49630cfc8a09845cffe260ad953b71074e42f08e265b7473db4d178c269f317ac035cc1124540a4a47886b6e5b04418a760777e73aacf8930f08c2ff10815559c1e04672bf4b851233011d7b3a84155d76279f9778a72ac9803d36506824a34524c835222224545deae1aaaf193b778751889957d5082a9e9a34e6e44840cb7ddd712ce9313c5033590e9ab54c25852aa8b2f09252bed793bf6b972b593ca9317ba278937a607c6b9b8f79069fbe452fddf01622465006373e2f661e366a90ad1483fdf76e04c388d61646f0162195d36966d75dcc89a3d96b2f98c79d9e0babd9816aa2084611ebb558735c076576e102b3857c1eb2876d53c5777f146876e55020641072010e7a1b773d357d81b52b4071b9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e768295192ac02bbc0acb70de25a27b724ae7d3121b1a4a869034e70f279c3914d882422e1785709599df782bae64316aca97d42846a52d03eaf423e813cbb3fc26c0e1134ddfaaa3275226f6416d9788ba2026c78e2bb1850c681825774213628a23494db886aa29892ec194791a84c73b36fd5cbb2b4bdd3d664ab10246cbc9bbdc97d8ea5528ca41924e240e544a747071caca25b05051587173c9fc851edf10fd0171c69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c692176b38737a053dce0551b63e3eca81884bbf95e1d8975671a2f7f1dfae2511c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 570b448d4f9e17ac98bf61e3947f0006e0530ed08513ffcc4a272c08f665e408e75ddac360496d3fb2d18820817c42db871efb3a0219503ca91feb86d681d331df81b488f55e1d8f2a0b8c81e7ee6f49817db829131227e2b3fc7f776e4857ffa2ff4c6b349563c4a478bbf4078a01c2e4ff8d6b55f8dbfd787cdb94b1dcc9139399cf0d91657678d74599426057f8f05dde9b5a4e2366362c6fc0ba11140e8962f2ccda15133b8acea41ad23e155579c43062ead9fcbf512e4af35882a359a9a3a2520e192ece2f253c79ff16b51dc8b0d835f10db442700b1914bed638aae549be39a8a7f6e165bc8992b253848e36924943abab0d416569126b478965fb1601f0b5bccf17a58b8b934494fa39d4f98dac08c0d500a67ea8bedc71fcdc55bbd05724c89df1a6e4f8ee235c17ec1e3c13d742aa58bace2cad2f905740ad852d1b2ec0b891ea9cbaf446668a1aba50b162368c4289278a7bb681deb4ecb093d31db7d1f9388deea21d9771bcf7d0a22716fe1b3088c5c8c812416d428c14c79865746f67182c4ea08dbb89f739814e80b373a518a8f1552bce620aac42ee35d70d8571969315ded3a2208aab7f719fa46d01b73d92ca1fcd7d34105651a7084a5c62892aa322cebdad8c69a200ae9287772a83b9d33e7e059549de6a45b08319bfde2bdc5f80594e18d8a3351ff0f1adc88859f796eedbf58cb2e5603494ae61cd23028a21e00ff0a58b3fb4715dbd56bde04e90232d421678dc3c4e0eec2b2abd451f3826987c302731e3181764c2dc413e2eda47a51965e7810d7569a66ea1f41d494ae02834081cbc46b854517125dff564ce5e4bf9c849190c3fd986ce05a09c8f1c746e557be72a7626dbe01a964a136a2f529454284ff615065c853b591960e71c293e376ee1aa16081251007b95f5d02d92715d4cf6cc07174f94d8b6b02ddbe02a0b0ef15e32a6d008f1335115632f1dbd70502bf0c0bdb9639a79b37db9177cd0336a46ad841c951b11a2ce05bbd7a85a6e7932b629cffd002e93033701c5449eadf68e722470de90615b33ef965d3b04f163b2783d38a96cbf2d4abec8e628f8b4c1fa11ba849941fd7b663e38675e88d5f9d130527d62509c6e488d463c5a0e522156d08e93ddd50ded499295e5c5803aee6e33b0f51754a5c2154fa6d806d6645a003ab09bf716472fa935ae260a23c19563c8f749705f68b987b8d8e323bb3fef9b7028740730df332740d6632d6149703d4cb74940d05b7588805e2c501d1f7e2d16ef5d0f41adf1ee368b3b678b282f592a4b8f02881861279a0f347ebe24b3a8c656545aeb38c16cf0f37ab103bdcb4d81b621cca4b461c8020cecd65ba79de82600230338b8bde69d5d4d3c79c6094535f5afb70736f2267227be333236ad70b4dc4ca92f99e0fcbdc7d53b79b94e8ad9a80f06feb965c0164e2a254503a66eb52bc8115e95a2f9975edfbcf0f8ca8942c5b4b74a90d4b64e9cf6de899d6397be16962175b0e0bf790de9baf06b9257cbfd8bd47dfc75ac68d6096b121b7519ca7b615a7ecbbad61c5894632c719c01e3d325c71fe097fefebfe9a734ee844ffe847ef7c85a3478978e4274b402f612515021d30e5a940dec1af24f52cdd7c22ed40a439f47aaefc6f77bdf124ea4a8e5a6d1a708195ecabddfedd7447eb82774cf231958b11fb6d152a560c78238c94b383c069805a93d6abe39533a26a7f2c44b0fc46e552a1f104f4c4a7e0273e5354500d797285659bbb9faa3cec81cc9ed64ab954ae6ca8c18bfb1655ae14c682059f637ed6b6355940f224a3b01a60cd28f03378d3268b9fb3dd335911569308fdb9267e3e5e1399218e2d691620948833741fb3480114f8a2cdd738d3d313644dd11e9930835f5e84a42aa2aed8ba4b852c56724a0986c319458ebd36d97b80ef8cf15571374bfc0524773f40e69d38cb56744099863c2c2da9d85092a343f60b27c725891b8492e0a85e5755c1241f27a93aeb48699543abb24585512628e70921de558bb1bc88c5616153d949acc31a7d3280f2dad7fd800504431d7e24b6491499f0e67c947cfbc362dc2fd4a16367e53319738b39f169c6f04e464c014800307eed443f83ed044b308ecd34433d29d012bc09632472563103c09c1920a5d5b5837baf5da6737a95ad26d7cf5c16d7525d6e7b3c1fd41e383827034df3550af31add3e8795c +expected_result = pass +expected_shared_secret = be36ca6f5e0d3da0b5c144ebccd725900a06782fae7b2707ce7c5cb6818c8991 + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +private_key = ffd8874d8b37c946409d69cb03529b7d1a43ddb24792d4773cc723643567671b8e0fc2b903d302679a530118ac453b0541a2389c46b38f317b43130972271d8146a66593b8fe659db570c941f1abb4f295493085a85277062c3d4db168e466015ea506b5b8a805a435ef6812a6b68afa9372776717c1042e24e7a10a842182e7c40c4cc547b98fe007a1d98804ac5bc3c31b6511425a558c73e5b1935c7a664ee224955b6d67ca54d47b04e1622716a27b21f12a2eb27c16d26a541cb0c1ba5a1a8629b7f2222b84cdfed9cb6f666b41c92fd0b074f42b5d2ee72e8c5443f34c5dc2920da165558af074e3ccae84c1cbf1f70624e1a3a30a7db045a2c4a79bb1a4b0f01187bbd8b29a8c60b07068a72264d9b305b5e391521bb945d53ce1d65436441932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542cd626637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356146c04bb8391197d54d0f4202f160824d900b27b36bf8abc7876ca331c2c3a8a161d98523adfc1ef9d538c9203a6729cfcf6089f7d72f57093ea3a34113749f23ec21c051ab2c836679b0210a549f2678c7187691de949994a25769d4647fd992be411e24e302c07569cf26c11f3942ca505391a794d42c77da0a324b05908aeb9c70b88b38a95f371b1902e06d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab967770465a056de9c4420662c046aa8ca32093ae23abd80406fe60bdcd1725daab0e50931c575a0c9137fa61442b1101b05686d398a6fdc0bbbbb25a073e99c3702b9268ca91420a1198b5c54501a03c878b6827e6d586ab42c2fa47258d1255711654968fc80e1364886f18e98fc10eb85645b399788dc225b1a233fe564604a86397a4483c102203188df667961bac9ef19b99432475c0a2c9978c81cf5314a2b2ab37479549b14c8d70ed8f0c6625938ca4a92bee5a7aadb286e507ee8890772c3353e35c2de8696041bcc8b81997f8c7800417c91c32e9b8b34b62a25e5c2af2854cf902269c3c5b50a5209dc1c63f8835b3a73137d855c69f9335fc66efb985933f4a66b084aa58909e658998a15ae8b087120f59a00426cf9a327dd48467f8c12cfbaacea7bca7407060c42950cf9543cac1edf9c296d978a2c36aad92b665d6c9513b59278ac1cc781204e555e27f81e976a74d3055a48035203472960e596c7c4c2d0158a006d884f40681c6610f1124574eb9ff5323e10480d0e306f1e398ad1e6cf8057024d072def4719e3a6be9aeaa07b56077be495a635c67066a2945376c9836ebf4c413a05a9b1348c31329884bc7d820a6bad7a63bd62518878a97fb525332433573973df74a00ec02d50198a2b1306005335e6a51191505fb244999cc333bcfa4e7845b766b050cf66607982014d28548a4454f86a06e9321c82781478cb938c709ec5cc81ea1a9269543dc8ebc6d253be1698990c81c587d7263e7445baf53316c23eb8863d151a4e5659928ad704c1c7b2bd2a1987907a05ccbd2f0c78232a10653452e3dabb7598ca83d37166791ef11a2524f371180984bf72a6e2291301606b7351a284a1a66866044f6088ba91217305bcf24c759bc348e75325aa7cb4c6b41077979a2b02b137966016868a66b1780ba90bc7d089b97c6bae2963a2ea3bc2072ea1841da115b83139401a9416db7c8722306d3a81bfb4d1cb5d964f04534f7f79c6de1789cd6767e1f6930c88b69b168cc6574e84c9c282f257d2200be0874392e12c57e6c989d8320b1c1135f88c97d824ebc82478cb4962ea409dfab7b61c1091b15072c18bc46838dba3c1f6aa00eba64545aba2d0ac9f44d3a2de976f62b8aba4396106f031adc4020d46c78d94350dc0ceb844af1bac32d1c27cd3e93c6d279cfd3c0d20255b8f11533dd387207c8a8a4c8fd51472fe21350f274a375a81aca592ad450091ab07facc360e528f7a6a6e41265d45f513a260605a2595a22c3ab5e8396fa033dd443da518c44a869218052a3fe06a20451ee4aca7928c521df980d73b2b7431ba37f485fc29b2974c1de5bb80d40708c5f869cefb8d24a56c72ba04892078a963753c105f088c8c326c1f82b3b246a75397d47435151fd314b9e5284385e9a58ffc4aacb3c476327b705515c6f1980b53b3654720296742b3a793258138d86728f4846ff1030f6f604d092847f011cd59165b9dcb400a8723ab79bd137566d709a5a7f62cc7a7948331920f75530c915b1bb086e422145dd74ea1b557f68b511ff8a1ec0a39845c0aa94c2bc05922e3cc52c7f59eabcac2d36b5535eb0d7737768d6322023a2ed2fb0128c2724442c794d794f302b89fe8b1a3e8326253362fc44bce193fe7725d1864acb29bcaf2c0bab9423dc593733bd99c077534cdda88f4bc2fd846b810ba71d2139fe1f50ace7821fcc5c9ad7c20baa4a430b8085441cdabf16251f8b686359c755981ec4c8fc834cf7f019e599051afa87584f2c41ce13aa9babab5aa20204974a10bc36d4aa1c7706a3838b8dfccb1fe16038d78aa78eb3594998a20c72337405e2f36683a01b87199764b533077688a9a755c2c38632cfa4c2047663e860a2998937703ba0f1780ff367918eb208b917cbd340b69577806e282401767c258b38b0c6b21a057f42b59a6dcb2eab48063116fd2b1ab64c0a864326e8683cb63e053fc03a5f6d6b58f0820f500ab1d78504dd80991e68fa6f91658fbc64c594d32a507be17b465684df8e65bd5745fa8d6512d382785ecb9b207746686aab683b0cfac43d07a0113317cc895a513776611b981f05bbf7e1bbf867923992441176135b394c6dedc8d64ea47971994cfb46bb7692f47e1b372994f3ef19a282799ca530ac7b82fca207537865ee0f4c73b0a0a84e1b2d2b058175780a287ba9a435a0fdc24fdf48ef579b55ce1b55531019060193fc5cbf013a8bf521c1f459afb125c78d2377722824736ce01901a16a54652d064e9058f918b5552936dbc77136b009b2108862f962244597386a2b078c6b46308436144b75b9926133a46ce1c44ca7b5f52a678463191d51953a516a1c937101fd236c962a8dcbb671bb1be92035910eb0b40d8672317aaabcb04bd8b716f104c3eb49c1e5bcba7e17d15861671950056e5278b845afd6cbcce9b2119d86fa1fa067f1c69bfcc7e693020cce979869588337aadd7d6ac7ac3ac67a3034a035a12750dc30c99c8692b9cd74ee2918a23248a3a6875e25bbce8c6902cfc81ae878fa4ba1df57523d3013fa79a9ab08894004042cfc00b0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b04034791ce31490459733ff1c7752864389ce3bcb826608f966342147d6a3626c4ab842480b571a9487bd8785c37a7ed10c8cada99aad1a19b144accc2be8a17be87111093189efc951d08799b5dc46e46e571b370b74e881326da687ea02e1088c400067ee3d885c0db3fbcb336416c74398132090971e2aa1fa9f6ca7ad186bd4c139be57665595337687742b1aec0da12922783c6aba7fed24d18d142392b26b3650731c07a15a987455986252b8234123e3a4a54c08b599f1948d1383183992e2cd17d3312cd9b3cb4149ac98ebc054f17cc516c67d8b26517316143c6640eab5134f41d6987c25454ca62070c985b2e0eeb24e05870667627ce5282f95635be4034d90232e997c18409b1d4991b7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54b9328cc492842238ccb6b652da6c037ac6afdae2be4b894dd66a70b5840f20fc18bbaac111486b9558137269732f2924ee050242329c0d1583bf890847b30d5921198814420b60475ce0047d973269424c54bc9e3b4c94633c1418db9a03a62f6cc224c59074809b9e023a5aca5757d3a789062bc3067698a5f216fb2c7355609a99aacb81b99087a087ed64cbc462301754931048999a2b9b0e06c9f251bc41b39092201ca3a727b5e498e4db782dd53846c7635ac12f6e89c30480bac297188338a58f338d6b7075003278cce876bbe18cdb00326e44745a4009209b04fa53ca742438336ac4f9cc337b1636898170a1d97c58661415dba67935162636a87f01bb87b66865d415360220edf89d0514663dd73a951070f68653b9c2b637259a395c500565b6b5a05b3f6555fb249946c9904ab40256d63b1d6c2344f80dbaa5b1be7b10299a7ddad03781983f8eccace5c85f3c3bb3a9d61c040141757a2e881c33a9784e48293374ca497cb59e12c07a4b6b420d3094400b24cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff2f54bedb19919171eca777186dd743b11ec9489aea09534c157faa75adf1c77c6590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 1c0150bd0c1a224e1de7d1c477f59517a9b46c570cacd48f189be2ee6ca1df6e5db2b93284f1100b3ddd47edbc5d29a8ce6e27e45d6bb7a58b4b0680b3fd9356b59d667bd9818a640735b7590fe7a99f1513d1c4637c6b5bc8e8128ca3101fbb5c71c6c50bdb475aa67f9c7e269580f41cbc0ab7dad00b9e36799827f13fd6e9f094f1e1c0ebf256cd5a56e60132796a05a4f7c2d2e6eadd842eb313933620e37108ea7c796e2ba2478d0d78ccdc66a09d14b7724f906bf4d57c919503faa5897eb33b0942366c3bdb45c3f9cef5e24454d66772778636f5261039abed24164fc831b7f0f4188b0bd392b2da8626c27d5c64c9167f86e9c20dd25b0b7315438607d7b66c27c3008bff089ae46a0b0aefaa71de7d0be42aff014179b998f6ddcba8e22294a33a535a6fb7719683af3fba951fa49351b641bdee63dd5b20d49e62f0f004a57220cd2701a6e489273dd5d1a37b35c5c6a2b86017655f0dbe5018319ce462a37aa9b6a068ccd5835261d33c195d6d98346b3dd49c14e70911a1ed705bb9d82c47f3bd2aaa5918b080ce8217dee1059c2bf0b81be3d1ad8969e1a15365f1803d56da5c60e6d227591547e1b7dfd60bb9cb3b32edbf8e7cebccbdd1c0964c88cf0ab5708b1670836fca72d4c457dde2a7d664bec8861b773805929b4e382256a615fcf693ba29e85f0fbd683b6d0a0a4af98e781ee946d430ddce6cfd62f23ff3d24af0e7c1e763b6f99233c8c80917a0e2b7afdedbd1cce32a1a8c959d47aaf7d1f92ea8559e0ecd2629cbf84844183484e46f386d4aaca70e276b1b4cb8703a6bb049c04120d129ce0b2de3914b3f50815b75ea850a54e14f8d9c8a8276a6ab50a2516f4b9487d2b91ef0234a269f78a8087568dc8f6b4320c7702370c6fb134ebc62f90328970d17b600688333a448e8cee00c998c23916f0f6063745639d330d496707caa9417d47a6731f4108b29ce419831a8d16783805841519b25a4c61d9696d4619dad0cc1ad3ec4e09b672ac2d68232ac9c768d5c0aa75de10031ae9e6a62d29e376afe2bf765213da0b4555e1b8969ba3eb37855cbd5251ad39f75601ff3dfe2bdb94f30f7ae51441bf8f39a32a3c1f173e3058068d8e83c0d1b3cc7835186d65f8383decfe3f11d9a4ed646e5b727ce18daedf4265f0dab11946a926a181b249cefd8aac2cd72f0c249108fdb3cca073b66ea1fd51cdd18e1175165ee41c3b51c8660495997442e74c782c95c464475ed6d7a3925fd15a6a0a623a93df1d57f4ce760de84c24e5ee00dba9f7df5a043fd6b2510c84b9653c278a5f8572583d4dc979a82a13517f1eebc4a00b3d7d4ff0f6b351bece612613dc4113c63786a995f27c13d0a9f997300bf5627e69428f2cda6771372b4f5a4108b282a5eac59422d9e25dee919d16524b9517d0a0ddc6732ccbf5c37b8dc372e0c295408e1592fa532f7fecb9c2ba2287e9825570c58322f5d8cfbcb708b504aac591e965948330c5fed5f5f9ca20f8c2ba1d813d4458b0d69e63e47ffc0ed13ce35b0ea48f2be3c1eae7721af145e451d1d7411f72fd237362500ba3f0d9b6c00762c58d37a5304f463e645418f83b0beec4a4fcbf03a6ea2306cd527268584173120e24f326e475abd09c78742c45b92eda33c239af4d635f2104510176cda3cf531b0bdc7e30b946b1349b123e03243fc1d19072ccfd3cb64fe0c25460be6bd4b2417cfa6292186e4eb8b9ecf7b534609539b29ad9c7b64e78f682822a03a16f5cdcba6b66a113fb8d4f092dd9136cafd896d2f2a87eaa0b351319ccb496edb346f885e3023ce6e1383d2009097b00a191b08ce3f317df080dff716554b4d5a91777cd3f41ce42c83b5c70a100f13c12e66bbce5a9164635020a4b0135d1ba08b45868f1cbaea1a5fc67acf36225bb09ae64e5a14b6fc827618cea4a805a2e7c30d9e20fff347370290b182a26440634c8941d67ddd7811f193684b330d961d0a336023bce514dfc912d6b7606d667f9bb17d055984f00ec2cfd675bf6fcb32f0be073d274e9d56aa3076d0c92bd8078220a2402dcd1dc51e10536e2e7fdcbff960ab06650634a1185d336bb9498213a144efeea84e9d8674b517753176075d48536dff17defcdc6e6a73386f30e77b5e8de17c0ccdb10bfe0868c50839575d5f7a33ac45d4a638ccd2260eaed4362ad7f63cd8967f3a91ed17393273 +expected_result = pass +expected_shared_secret = 9769b7f3571089f1a086606f3545dcd094097befd492e3c9889f9a97c7b181a4 + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +private_key = d32cbc1116ac88219f9af2c33beb59bb94b372f97815278f0fab2c690c94b8f209dd1575bd7c0bc7f48aa133bfa068cf1af1612c3325b8d08963bbc66d938f46843fee424357e535c2259ed958a75ca6203286190be53a9b46373f8b41cb38c1cae2bcb91898669a872f1a8d9cd21227e42ed655569202cc6b494cc6a6bdb08731cde417f48b86554ccaf953b8fb70aec727085510cdbaa7cd2a0ba853928886332fb1e3a419c49b34ec90fd31b716252acce7a79d05cc04074d69ab3cc9809102261a2191a086231dc70aa583e86912e5beb2c1a22e841f39db531d5c26cc333834a20480d6b1ccf19a654149045791d33b414696375dc3c7b0644626e8822c5325d52ba764f2361d853d244416cb9a5bc0540e1238ccb53438c90a196a45571f743894f060f6031fd623abebb4afea05190dd9452c981352a78e09579f05e24db2033aacfb10d9335986e8542d9480bf5603fa932d2d0878c3753e6524a809324ad6f169d7fb6d9c0264423a632996abf297707d8412a6b86160b69980e18add1c372faa406f540c00ed0a75c3544811759c3b5026e6c19102b7160883ed002de5807b5933934fa01559c4a790230ee93c215bd75aff117d0f170b4feb7aef5b007aca616e688161fc00cb037c8232cf2dca569f01a2e1dc2af7ecb6111181f2ebcb1df27c6ea84251d8a2b6b6582ef915e2b8c7f8fb6be8844478fc570b8054a067b34120b47fc6ac68125cca8514db4540b7796c9fd05523e7014db34b8ec94d5eb66c9f5cae2f838191d2234f43c72262a18deba17ab495b7f0529d89b8e1e407bd5a185eaa2444d20c6c9566526b8707b13bb0cc8d9589773db90952a5cd78e43bdc68cfa4401d7912618f456eb4f97ac1b49ab948592976233f962b1916531fd1672bb69be320a2985b38b80279572488c5f86bf3d55fb9fb90449b66fc874b94292000466786fb7e393765c7057051999711d234b4d277419320e0046ec0925b41d6b89c62133bd2734e296dcfe90bf6344219a6a22d2cb50c75bc02b07fd0da11fe0a0a0b9aad76001d5d7c8fede065dde87d5d47821e756a926638395883879a91b94c6164a40895476269917caeb12944dc956174b6cc5154944571a6f6553f604d3212728fb08af6e8c0ea00265ac0c5464595b31a9131871d79298867aab426d009480c0befc08ace14991399079cb62de9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e63c162ec911101c5a49b35475ae68634a7b0cefccfbee608cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687c92cda9ac9c03a9333a866a9639803c76b5b189294a269f389abb5010789d410b88215c554008cb10274f781ed6b0be3903576cd16934c4b6b65296c477aa174043f06792f3944efd0206e34042d827caffd2989b936b91694825c4bd8b10c0777b11971cc1efb93ec1b3674afb4fd07568ffe89c707b5785c140d51b433b7942d88a6ef9bc9d091472833004005aa803a050ce03b2bb551f62fb1fac6649d3e14f0141b2eaca73b700489b73a8d840834a7802a96864610b10ef5a030a6670a866b02e13c3fd48056c092b241513f1d498539b1d68f498cb049c99d33c32e1b491997697a0b6af529e63a85a0a7b8ed6c005d61963fc5acd1e609af8160d6f823063385065640452815aac2463ab8524e2713e3f584fd475a23e46bf79b97f83403fca999c1ceac629f47261e499e211051c7059e4aa14c2c4649e398add5b2ca1d070386b4f9c284f84c930610a3b22936090f3c03fe7a25ef323f2c326b3a7c9a7a5ceeb395cef08ca8009a810986f33164054b26bfa61489b38ac81390bc6ca863455c22b589e8a4bb5ba87aa0ae03fdb611b7f364387363e728a6de48aa47af676e73ab655396711e64777b27fe45474c3f29495939704d34e24661ca43aa94b71ceb2d3c008b135a7115762997879c2391cacadfa092779308080a1459b09ab16e411157abc386a0e8e322cae09a60fa290a91419d47513788980ed60a40bd86e6cb30481c65a853a188442004c93421c799402e639dfa3c73f9b227c64c0f8c17d4723a06c73a9ad02ad2571587058513122012df86d16e63cac8b2dd05a60cc593000322c9c566b472b375e8484843aac71e74bf0315af59a8a4f6104a43159e198716e239247204753f629c5202c7812c9ae2351d88b4256e7a82b42b15e54412e0130d5e25388240fc05b253e7b0c94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e67766301b386b088f71922ca370916319d8f099f263caac7d7c0f81959c4b13a0da0b5c269760036a552016f8b591f6b37177cfac940f706c975a59da7c04fc7210ae32508c28204ea204073c73b474d74b54cec08bd14361b144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613c917393761efe2c2e4dc73d4998a1cfd6a2ff278b6f68b1f108151b857ee913b3568171bdf1502953b81fb085650bd027c4b66a8276319201ac328604100ca4f684f2fc65f220cac1db9c434a218814a14cb630b5b18410e11c37c92b31600e37c8bf12c895b1f315f0da01cab250881966d3c8256f5513cfd68e383bb8ae248e27f3b479f7a82da2aa564b121586bade1ab522776b49a02a16e3a798acb005d70d3ff24a8ca3458a826788aa09889293e4d862572907111071f0d58d679a0c620155ffca45bf03a1778941d41776ea11cf3ee899912c703d50c8e88ac447b2bb0a0cc3bfd83ef3261ca592915bfcad6cd26409472e4be62ebfd65f003c59d39b7f9f710f6a76a1e8291c834323f145aa3b8a9e2e4c2e98621074c49fd0716d3d61a2787a0598e8096ae05fcd7aa4250a7ac4a5314c842b8dc8b563c6b8f626763d865c141474c72c1439ba7012661985a061ced9679ac94983957dc99c4bd4061ea43c893bb707c0f633787c1b11d8622dc08c47954ea907ac1513aa3c4420dc48366e4045c79cbfc3b52415324e8c6669e52c2c16b1722ddc7d521558180781898a2e681a55693398ba712712b9c515d72255453a3c4212bb7b3692b3998d1bc6781ca28fea483c276a92c219a62797a88702b2587005208512aab304799a99acaacedb1699993150b41aa3291423bccb6dfa31a7b42be4997581b9aa54716cd5d62cb1b9bea0e8165eab6a6300242bb5a711f36e9a43b12e24492ab95218e084e1d2976a222024263e4c87cb93cc4fe556812096686ac72152f1a8a12b93c6530d08c99b9be3634dab9c93d27f2a4099304b4c61a4bf0fd9cb28803d0824c5058a515dc69c81228687376865852fe9daa07e45a889e650e0c58fc2cb71846b5296e76d71105e87ab2714b2b82e06342218822642acea28700486709c43b2fc421eeda5070ccc8ad1367cf2834e88eb8ff8d2059f455c2da34843418cd3449497b753c92826c3174e5e304437c04c7f518fa2eab149762c916b1c6a676a8d5b3bff02b8ea9a366f1706be888fbc40285d6cbb924249ce963646595573b5a5d0079fb9b0275ff031797899ae0bccb3ecc32eb48ba3769bd5e56667cc02723c773ba00924a961102225f2b88ecef333302077c2c761f48991755a83e09b7c3406bc8784031754bbab6b49c361c93f5ab9778b39b9cb66501b63d8859af0a00bbed32947b92f49961c5fc38bafc9b0a763802c9709fad39f040c6736a4c45a110a08822e26d93bc6ccb566a687ddb786f5d31378505f5d575746c3cbfff55899c933f0052e1155b776b9201f0272bcf67c3fd26868bcc42b2b9361562bec56ce1991ac7347b6bd500065e990b257bf20e1537988a560dc21aa652e3bc8650d80870a1a4190014fd1c43229043bc1068a5fa074fb5087581a932ddb5923730ba05216895ba1e67947c71aad452861371a542325607a7752b8485c48fa9ce930793130996bc63d1b162517c34449f5263077a41f576150d8b062718e493242f57041f2da6f271c0c5ba3a00a8c8faa0aa9fd61073dd70adb7991df8a143e797a9cf6b0cf257ceb347dff45cbf6db25d5928074b3a6ed918fd35895bc7b93682897c0d322d46755962928f3390664499a14dcc025b1c0780858db32826679a923e20ff56755a26604a2c8606fd7087218232cdc3b488423fa9328f9eca8eaca9fb4311777592157b46e4476c885581f6ca524ad1cbf663a0591a7679e515de5b65cea3a0971c9139019735d421a25f7126a9bb66f67c177f3873bc5a8a7c06026913a631b1b370aaa17019a7cdcbc22a24f9e38a69637928788bed0560a235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb7a9232085a0222b9c863931ec3bdbdd51be3f16d6cab3009c138e0c8cb692563b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = fcf8147328a10f617dbd830a270d85e99322d550c48b8b7a79be3e8de132b1fd8a515f39b21a5ca46e319741a4425ac4f9dfc85ae47964fb68516cc9dd34a110a304d5a318a4f76166165766d108ec79440341f9424612975360eeda65bd7d2472331d430c9da35a17fc3b416fbe537469c6bd4de4a64478459e3df90971373421f6b53751cd482cb2b570b64c7db457b31d2505952345ddceb27f186bab6e06ddd164a4e3be2b0612cd4e8a7ab6efe050f1bde501185cdc6c7bafb33ea8630138e96cac4eebd50a32214cae082cbb9ef7ce1da7e5021c9691a6149a76d4584d154161e391e7a25108fc850a6bc26edda0cc107c4d810407a3fb9d1e364ee07172eef29d83bfe895d7c18b1f4486bfb5170bcf3f46ac0e478834e6cad1ae51447038cc8fe396cdc10c111593816bc3f08e103b93fb406ee9f24c4be1f24878f5da0c358ea14c321d4c7e6bfee0190f2afb4250c1803db72bff2f0fbb085fdcfe1df32e559e5be30fb1a9cadc7c4f34b40562cde97fe6a67681ae2c6c2a88d91e6c4feb7d30311d0ee0875babdb871322d9aa7d5e0c3bc50cae1c9809f3018961ac9b983a14857fe0d6ddf71506f592f9f6b465956d3ee2f4fb3cfa043b24b87e31514967c0c8d8d7c8256003d172e7393ee5a74b8113c53643b88a203cf30fb7be3f617696f3720711cf03f242269155162ba1a71644a2376b71eb50d98251c4e7a6ef953ac5d4e1d1ef41d146e31b82da436b41269b2521d56545d168ac1ee559a8fd3226a598fb1b383ba6bc61a14b2397e29352baa7c60b29daf8b3749e05d7d75703069411081350339727f283558d71ebf53b421e585e93c252f65338812b08ee74b7189576e44fb7f0d11d71eed724d41bbf373ca1d663955b7b7ef19198b5734909a582af72054848c366a9a519bafb8a532d28c6dc9ae2fa2aa98eaaab0d61eed5d888b4472a4c39f5128cda5f0ad11154a302ae70080e56c58d8dd94f7c2199694c91b1fdc087a9b78be41d4496a7895af00397bf5f1174a76eace20e6d243e7354b5ff570799297e9785522123c29884e97c1dcc303be462c7b6d6b1fe059d67dd90d0d3c410a54e155b24dfe25aaac5c1dff0f68c8401c02c76efc9bb9773876a845092443250cce94691d1244687ae5cea0f9fe1595c0d83fecbbf5febd6f7d18bf5b9b2b6ad4e606d67ae2c0a6ba994ecc35f1dc012fa21bb94d3f604f045124550e5b6b7710416087b19cfc7992e30376278ef39857414e8320499c958f7b8d20724cfa30d1e89fdbfbfb2fe132fbda5ebdc3712b96bdca5e9db036015ce27c44e960c2a78039f2fa9cff6e1663505e424d467352a734db0a2e0b61448e6c3428afac5094e7fb3d15c5c18763d18e68bb853b33084cd85c562fe2a989a0ca81c86e05b06972aca21491d64328621d3542a1b929624c6b703ab9294b9bb972396133c1f1f496332c7605099d092133ac127e0d0651f7f3568aacd520e56ff0a729c8d86ed7f78a18ae093edd0fc49fec84d34703cc8e6c1b12873988312918016946c9a35a3c8ec14203e617f4da8c798d01582134bebe3e8b629bf14baf518f9b5c170d5d3ba53910a10ae00dca87f5b0fe03a7b577b633a93e19323dcf68861b207a5acc69820caf616dca99de0b0c7d9a9dbd33dfee0faf482f11fb466650ab246157174b815a88547add371bd64f4ea6b5d1cef3a187a3ac09003e148e49f707ba4e365111860ea1901513cba013163a6a5e820bdff516c78bf8efd69c5407d5cb8db21b92788c21442eaa01bc459399dc89446b802591c30ca8799140c7c50907c1a2dbaafffab98bbab1d2ad387ab786f7630cefa20de4c7b576655410236c56b1078ebf8f658a3c0d64b7f08fd113631ef012ab95b2d7a280b8a58a1fa57358bc4db04a372c8484f13dc6a5dc1e510777214bb6eaebaa3bc6dc5babf00ad9b4c3fde76e7170b48fe93cda3b5ed09d16e43befefd436a6a790d2ee696422377fe27ffe0e2d978870929c809bd3c3185bba158eb9a2178a8ec139a1531dcc2b171d067cdf197919232e4216aa160a086b395f0016abbc74fd1a9a37dffbdf83f7e460bb86fe9a6f21a31ba32a9d137add40874811709db42932156c5a1270a056e654701fa1ef5cd9b000f710d3983639ee7097ab9893e955797968b1141a0ab7c22412fb4bf4aa2f425c8f1e38364b952eab9df825f62 +expected_result = pass +expected_shared_secret = 7a190640b245b6b4de7ac38fa6d4c50e935c0062c2089c926e4e8c31f233fbba + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +private_key = 818b55fa5ac30a81891f3a3643924b2b046feb6765a61cc81c9059d1f82f6a0067a102825c88a530d15f0dd95f0b4742d29abe7044c62d45a05bdac46130305e3c3417d67f60b92edeb6b2a398119ad160ee3cb0fb52144435a5bb5412c0512dc6121bf6e72d0f87a3834ab5338196fdc950a3cb1b7354c4e50369bd4364cee9066a221dfcd580f1b914c0c335f547748bb19264b7879f206a9c610573b8676bd0bdfd777a2a0ca5ec891a1317c5289784de114e84c53b983778bf8933805256c9a9bd05a11af8f5ac271ac3f1e635eb9a8263c855bb230f58ea3b7e8287d76258aa57646b97560e593944c4cb3567a2c382a795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b50722a144737ea38b14be51c41cc55c53340ed158ab4a0b0f0a2612962b89cc2aa8b29198f2e04b0f0cb586f271c6414f31a71a45eccda8c597c38415d262571bf0a7bfa17115e0c7731c70c2d01c492c85de16c511102c5a96973c724f3b58b504eb65f56116aa7779b76b2554736d9d6176dfc6ba007a590a311d4b86a7a6251fffe6086ab3319db48c4dcb91fe680f45a9480241242e4ac9861b62860837cc813fadf00751c8021f7a1c4d7a1e5f13bc3e8462f372cd7498197d172eff98b1f8bbc37974b025295a80e3525d282fba8467f8079d78fa6068e23bdbb3349a31506e474ea228c3927a554d7747bd3621a0343cb155bc786075c3015c3692c0fc65b194a12152a14153a03d5147b0cdb423a3b50ed6461813f9ae1fd63ab7a53031dac2d0f87cacd1cb81461c8c08bf367c4ccae7626343469d417acc705546293498035195240387fb1f2e7c005de000e530b9e21cc7dbe463e7d24adeac1127026843b87cf6fc1bb94674399b0636506b1acab72f623adef866f883762b5b4509cbb2be142c5c550046e10d29fa431f9b7d977253928a8d2d4c33add899ad736b40cb4fc656be02d90bf8d393d632a1ab509c432511f1ca16b01139cb0627f6503bba75440414af97a04bc5239567c060ef94c9ba7221d4612eaa640bdbb8b72e32a4668401aa79421ba68115261a8d94878c90a0468510b247968b7463ff49a0578044c5e9147f0739f6a17b18828bdcf56966b1caa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e742cacb74e1d45704fa4cfc91c142453ba5c08558de1321ad6a6a2804769a0bf69770a1264ba5148b40a3a9be3c513a382cfa3c244c9a138ea9cb8da7627b350cff87ab064a079876893d893250ef59f369c41f9ea40daa5a5984c19ce06cf9bec2947932133a4157bb8cc3c72a1fd25715962a9c88026c018b7202885224019466540c9eb5482a87e665157be7722bc64133c827c20b97d9e692342f23fdb1b75ab2ccb6fa5973820b92ef1bb45c2b5ed1330c1417ccfb39fc6301b8a749d3613b3803a6abba20990151305cb32ba6a5b558265c2e27d8d49aef3e91819920db20360355919d5f641922233a1c24c0045172cb10f9564a029f07578a48a4d215248f3ac7a912ef8e56e366b03c567ab978c750d85454c68a5806ac38b7b3395f19fe78a001c5867d3e90e9b54bd63954761ab7f4a57b1fa32b65f285742c1207aa06818fac83b928e3e14644dd6999f310fbfac9e372b576a0470a9f9c5d2293bfe5255826c534c1800bdf348b713766507674ad820dd0c7c570037c6da35edbc625ff0223cea7dba19bf044699183c1454c2c2318c14ea8c451cac1b585324c0f9489f94a9c14992abaaa393273e4c48b740b764216ab16df3b9eac38d04aa3bac2185f250a82be093d2359a1dfc7f2e60cbf05b4568c86824808f4e073641290513b247ec7585593389c5c0459173cc74918c7a93798802af77553b3ea32acd760b9008ad3851b2a5632ad41c11ba095131192f37a06975294662e4298302622a236f57f4119ce24e5e478098f20c108c0af3a3bd7aec511391cf77baaa9b427884b9aa88c17b81d387d65304d75b9e5d4006deb878bab34151b852a5757421b82090c44fbe85a81e076f4116c025977d9aab838624b340975f7ad16bc10678709a026ffa53748021d00bb7759579c6657183b6a67c3112bc6a8870d56dc329b483484af78a81b5f87edc200e4eb24386b6c882490a87d168a62818d6566b6bc5848b2755c2e64d1fd9b79f5a2c7072419b955ee69a6f453b862528bc78905bcbb44ed989b5e71b9126a6a920e67a074b2960d6a3ab50128fd9ce39137b03a66968616f134bc485770e87f01304a17c70d9adbd4159d67b888862b0b6052d9e8496084ba93d197766d10f6477679ca90fefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c398341a4810c6698351f7cc4fa59c2b0a86418145743d2b850cd47f32502e00d96b0a67cb3ababf62785b11a04de252813efa36bb83001ea322490a7dc5c54f32274b01fa71d40717ff917b81fc899e28adc5c4a0c41742c7d043195cbf8393a84206ca1e87032c553b68776f9153b4e2e0a445d2937fdca7539b8a2dc497a1f338802c073e891a3f834505a82a39f54544a49921e348934a028b7c54f11b26ed1a9cc2db7c58ecae2586168b120a2cf4487a6b34b8015e64816af26b864b7b30b19022d5038f89431056153dd03169a31a18c5f6649f6b638d4c249b712bb9563e4adab4f3e83c5bd05e2617b4530161b5264ee996abd5905e025820c7e1b1bc05188adc559fd0a0177473d816a166025bb4402d7e98b7f148ad42f72920d24e024a4d7a8a9dade92ae250bea3c519ab515fa2581b1f88c4caf62d59050e4ab1512c14b581d7c012645f89a0722ad2a1c2f2639b2b11051059549417d8f3ca8ae80fc241adede55999222b05b7b7101885cdc149be41cf9d2b9137e3bd0054ca89818e84811bc21944dd19bb2c1a54251992f2a51ba93a452c290272850225e9b2489324972cb6982c338f55192b4b87c2c91cc985ac9151c638aa741a476f25b3853afb4b106830d882a1e8a26b1b1305cd045e112a7e7a723ba9b801c48358e3004ba12b347d28a571f8a6c05b7c81fb3ef2e324b1819df549abfb871e25053d3e4676c9088d277688d9f85db7fba99fc62306c0414654509a086d0247aeb60a9924a2ba77f76d669c1880c302e67b1e1e638e4f74628ba73e0c565bf7766ea68206fc779f9c55b1b48c350dd095a5566fe1a611ee9507e729142b384306527c7928a7c09a74e7c03925e87d71c45896444522a63bb6b78615003d5cf37ca7e55e82888c17f171aeb440952328ebfb9eca10396b2044ce7275ee2709e917cee9425ea4c8a95b163876a2159907003355323d56b62e243cfdc714102a345af05f4e1052f9673ef57abd43e802744316642c26809a9f07805ead090a676204cfba52f4f04715e5788a08754d23b7c5db0d7d72ad20dab9ad776d52d1954a99407eabc44174237b127c4670aee6689100ab4e9e003a4157b69151431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb783115803170c1f8b2c84d0dbb801473084aa130d5c9c99eac4e00c2355a04556a26247a73b4a7121fd2cca08168d2399a1a45b685a921b9c0aa339390068348a3a8cb55653987c691e9c86cd67c385cd580892a01d160c9e86a65bcf63a50777b353b948e70061d03154e5ea518bc687a4a6b6c83372c0d16932accfcb13525457979218041af9ba2e012f82d79fc245356aa98b11f186fd2c538cb5159cf9562b5a5344cc1c44b3703a50850358c6ab4a5fcf830bcd2b1a0c932059f2c5a43b932e32a2fe9ab9f2f3b1ace7a3c1290cce509a5aba7d50a172fe51c65bb142b54ca6113baaacd44f3eb76aaff63a474a74614a0793cbbd7a1c822292bd75b2cd9d7b579fa995b9561a2ccccc1de89e861832522412753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dab154f96a4062751e79c4aed5a1c6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dfe021c47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc18a0b6591760576c819716560159908903a32111daa1339d8a8c66081894a52465f542b011bb607177d6af34d88ea80d7247ccbc269ad67a15df94f42a22bc1a525abc7480257694e9918597a8aabd1b537b163d6dca6dfb77fdba61949e3c15015b567fb88b509b43d4665abb834263a47c5a6007e2807b267aa50e8af44452b01a62b3034ba54ba910b018c629266e26514263820fcb3390dc117f9878c0ac4b3ff899d83d922184c42990088bcb03ba65993ca46c18bf1583f5599ad549801e934b8990fbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f6481642d52117145ea2956bd5e446b895609be84a9344ff0f5cd1ec62af9ea9e3c076eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = c105196ffe91f8ab509666645cf70a83220648cdc8d4565d622dcaa2cfd6f10168a7c22d7cd28d5f65024947fe9f98d01f7dde433c8610c768c73bc584c35061c283085d68581e3270eb0171bd0b736649b079c2db7fd076bca7cfb6a186b88cdb9d9899abcf9a0bda849769a045686cc751e48cfa006baf9799c50c143fe643e66ecd041552d3d8518290b5a968604c1a9ce404b6d768be6496184de90241412ac4d284880d5360349fe12a33bc6ac9e697924a13eded8ff49c0d295d22f89d07a2ddfa2f0c7f83e8f59ed5573a747120be3ff44fa616eca090776245d10d6c8126b035247abce9b79c737f0119498acaa2b796f57e37bdcfb2885d8cd9681367d386c5ee8b0e6e8d9010b6fcdab4736282034d4bf3a0df5636fd541055444f69a84c593df54ef98daa5f6dc3a372139f5735d5cad090b5e79e2fff17509d3892dc339788d8fd3d408392f00031b117eca35d5be3173e053f52f25c649add017b2962f0551960cbd959453fe679de209e54593938390765cf0982abde7c6cfd2a32623aa534209d7a90f4170b64e78a8580ee1ca84e5b64115c7b9fcb294ab14561ec36f27d6a5cd87772e072637483ed4be1825de437e8cc321f2dea21a15d5adb668596ecc4832e3d5a5414583a2562aee3fc6ada088988d31b5b9e7534f6d4a9ae91125bce9a69db45209f7f76d0a21a659e35b839dacd367e9998eedfae7c2221b32a315872e1e4b00cedb20872e19edac6ea11f6202034fde554934a1a36378baf39b1c598e2666fcff60880a6993ea8214b0af7bfb08339eb643edc706dfd95d5366ee6fa8b02983e4c1afb0f434902ac07e50024c45b21c9d585a92ac046f928ea53588a54dde77de6859e571bc6869fcda8a2a5253c6332fa276ae247a72b7bf76cb459f6d7af5847be8ed0f26c3bfcdc48699db4b20d016bbd6ed416af20a82cc2277c97d65e27cfc6b0601eb5c29235902ac129eaa82f12d9cc2a6bd917e125cbe7957bffff7edde73bcb674dd6df6613bdb11c8139948c7fb10ca79e7c812d1e5a4ac7348c33e825096573ef00b63604ebbd007d3ad5b6b4477ccc992ab7fa53d6d62c2390ed9f836396e0816e2ab26fd308ea2adbd3b08456331d595fda53c7439210ea3b0f6ed5bb5ffdc258c1c30f4ed8e261b4edb9d2f0a94f9263b6caa34e48fea279484d0e88e392f1b7055d3eff14eed541f02c742be56bb9e7f3ffe8439ff997de9037a8d239b042bae74a3331b1ac2a8b7d463485f80fa051c6f4078c7d4835213e4210d6c41e401aa82fe2fb90378d4b975af6011cfc4c3210b24e7666f469fcec5bbeddd42ee79ec8ee731ec96acc9f45f72ac19559a3d30f0a2fcc786ae3c717f813ed5264a39d0bbd8d2fa0f438693a5a2805d3a86129bde0da616a66764fb9acf86587026fbd236ae438ef6da440524be4adab42527924721b6dd00a19c5c8c2fc42f2a5536d6e2b962a671c06b2559b9e2101497df277384b0785c87b5a8ccb08b8b8b732bcf7a9a88220a54684726f1680f51e710860eb2de2b9a6ed30b3299047a3be82b62a9267dfe9c535278bece20dec0783147ac65bd695796aceb61b9aea1f40d2592bcdb50b3ad97f3712566d6285be09411e36f1a4d7f10ed14b52e31da1d09f1cd3d1a2f9f3016440ec725b11f15c5b619a53267b50c04bfa8e3c5dca1cb9e326791d02f3a4f44aed832a2796dc5fad97a85b718f6a2fdde7ba7db3a9d2e4c5f6f6aa1c01ca3269e022eae8867e28bfc54947e05e9614bd0b41a54cff3f40aede9a3a497688ee5a08345f705e05ef0429c3fb272b0f3fc2b4e65dd3f4bcbf278730240e665ea696c119b38f8839a9e03d7aa70ad7dc382bbcd96f8325a8e52bec023888a0a99c0b11d4cd3305f09f1b4dd0efb552696c0240c5f7ee90571d01f460eac11e03ae3654d8745222911db99a222a2fde74ad001a699038451a832bd8dfc2bddd62891a685b519254b611bfc5e6100e70a02ae0382a45a8ab5a99e3046584655f45cae8fa2a0dcd66cdcd022e764fe318adec9d482057bb0fe373090bfb712c979662a2f23245e2d94ce730a0578e2f01c34cdebd096d0b83d583e52a934ce2c90d52f8371a2ce7e96eaca80e6fa7e7b41a28bbe2b109cdb70493698b493be344c961f82b74266096dc06df7e5c04fcf213bc9ef98d006325430318236ecb1b691963da4f0fcedc34c6 +expected_result = pass +expected_shared_secret = 5de71ca6710d2d588f53059a15e3a266eab4ed2230502b597f088014fbe9b659 + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +private_key = 91c087e623025864c3c5d9049e865c6226cdd2b39f8a1578eb69a864ccb2fa155db32702def5b50e973495997e18c6c21756568802a4bbb86c5018016fcb0655b09e6a4b39a8ba2d70e32bbb255bdd296c998a21f5716d49968dd02a9c4f4cb9dc72c874c232011225f8e8840f7589c2d285c1e72c8588c0a33a502a385d0527186cc6809185408e9c7fe6262725528a439332f93a5ba2943e6dd7b30d79a25939a4c0802bf57c755a5a0ebbdc8390f8aee407a541c46cb1530fe1642215556d20ab942ddbcd1627826648acc3fa1367db0b45075470196b46697d9ec6974f477eda553f80b701e853398c69a6e4970a746534928631e6b811e533a4d1e89cdd6969bfe0c861d2cec3e16d0035bb50573ed61b5dbd45c8c5b223cef4266c5a6daf104949eabd27d3319bf12a7aaa4e5f636732b28e902a1098972977d98c00a267225b84af1c8c404a52472b8d1a793e370b17a9935ee590331256620e302e390474dd6a17d17a50291b6bb940bc43f89fdd22109a72c8ecf9acb1e67ef6a423396225e6acbff2880c35673135c5183ba37df968330ce992dae04e9455267a195a41893194bc51c67393251a11ed3c0829d99a3d23ceaa387208e00974e73178459bda539bcbe89f5eeb05ee21be3b1159018a3262120c21d4972aba1a1350231d3a646ba70fa5b641ebea1b130470a5ec7c40627035b03d15696be1313b458cc9ac8460cf281a6976a9d2ccaeb9fb157300b4289a55eca386d3d8a7d16c21102aacf361578010042c3a6397e2cb2ea5224141a1d451b38fac14d7b64bd7b72db17408b0a8906cec108bb926df54299261b6b5c6a636b395acb651ce6b6018ea9c92c1525de1624b5570f7000466cc09a909cf36f34687265b61db6bf2882514705fb37346385cbf4df33b98686e0189bddea7268f598db1b6cc7b32792d5546e242a807e760ece7080392823004453048c6f743b87c1670c6d10e3001008a24590294bc9ac899bd588197530fef9c2b85ac66520a195c77a7aff61672c8cb74c07d43a2bab7a764e750663091a005c9af8cc4b55d502169d4293e79b365f60085b1cc2f4900541588819b5edcaa3b80253178639f63a3091701c7e7b04e95435bdd2114bbd3abefb23355591b0ff102bc94b56b338083b82328712733f2762c5b1d0845073cb3b46aa28ce2cb282a4347f2118a6e062d7e8524147545488a01378a853d489c03eb0c6527307fb0ca5f7aab6c328438d33cedc10733ab8a68c7ab88e0b06fc51c92c557fd59488b6245796b7dc291728121bc7643aa5d56c483186cb55086d7e8654691cd5eb97580f0a553a2613c486c0b9566a6f05f9d2b82b57345aeec1368cc126ac53b9e794be471c16a498b743c1848a14d53478fc341a0ada42bc2e0717fb6965737876468515195050d64079d624da1596f88819fdf95653b8217f9885d151821a9529420ac95dd928fc429674025882c9758226194615304f1f5caaa456182c1bb11f0a02b6c758eec4ab6441879a42450a024559697c4494d8aac2f7045342234cd8081c0077c9232e66838460ea26274329988af3a82b898c4efb033ff4101f302a898e84bcedcc45e369cd1bb7f3517280d6655574c5a13f43e3f834632a041d31a7e01ab4e0f06458007063edc8e9d9b31c8ca7fee525656fa4ee9d36258a0bffa5a12922718df123e7ab52caff3845a801222f23eeb946ee00a4a78e0261a6c2a0c16279b5406bf7bbf4b7c3cde22a4beb9c6837c83aefc90c7b0bc21ea3d5854b37da36059dc4094181065d873469cc40db021474abbc8d80fc20a0ad1237dc13716c6a735899bbc68d71012b40505ca6c386ca92080b857a7bf8908476008c6c5fb7e30456e26a6a0c247a6a0a57049c1ce825154d2101f57a5c59dd44d71058423d6449327ae1fc3541ee73e31043ed194b89509bd7c113b77075ba694064dc442fff94a2607a0e25009920a438c537ea21477b39863f38903729875f4e5bf9b05baa0dc492e9b15fd729cbcec5de2d6ad727408e69a301649822e52681721a264696d8af076423babe37ac6c7676e74724804a04cf35ca840e206d99568bc393bf817a8c6a5ced2b9a76b036dc17996c6cab32223ae814338b7169ac1824f129a71eb50a554f8b684b929d9859ce8c019a7823bf24c9fed4588355033f5b22ace43a30478209a8965d587c91428b92fe034a1714535cc458c5146aa8b8c7b2c047ac76fb3d306174cc370873e25ec207dea86d8430a7ed130701c671697185c385dfe0410d91799ee546b4d6347ddc146947a9a5692c64445ac60a9259a7596ee8421eef78bac115dc95067e002aa89b814dfb1498ae7829517c8ab587afef52d4f4068eb21686e4416d93c51efc2ae6eb1cb1304228728769f08a4bb64893231c4be107a6de473afe6a1a3969b610a87fe2bbde35c31d1530b05aaae1afb69c07b6c6d4753b16588413aa588726f80cabafed3323f412abd2579096a44c30991eba87bb4d667bbab5e848a0bb178441aec4d00477310ec4e33677925985e1aa7b9965a103cf14fdb004a60406994e0a2fa5a5df0465cbb11a54298cfb109488564aea65b5eaef171716719916a4615d3ad708c8a825874b7cb671a5b61f5c3c9b9325ff964046cebc4991343b0eb199b9099f04c97e28aaaf0bacdeb4a007f956530c712ecd49017d73c8e498fab650608106174c7141a7373e27b3d11c2b06455b4f1c1471f8a0bc73c4299c47eadb75fa75210cd813798d84aea44a1303c95ec02cf4602a496a86ba364babeb7603195c7cad66d75b46d763094fb0b2760b048af1262954b5bf5833cbebc2ada183bc207290f094b6e9c2ba622914604aeba35237d17606d1b76330172f74a06821b07d8348979070b31ea32166568c261c91df097e41cc1ae4bcbd3e1525f179f8acb232bd056a5e18eca475f40e0cefea85d664bb87918339f407831c27da3ea42da34be7be4beed4c8a5ca805cb209d51a826d32c2125e204f5c87944372c3c1952d5f8b1873c1c6899b85748448116b3aa85156df381371763aab6c8b801b19ccaa1f87c4097c3c351c62ef1c697763915eec69389671081562e76701d805b2a62692b6f3a17fc163339f49edd205e65ac81fee42eb689726a960711e1b2ab7c15e385717946c27c86116b635873324bf2fa21a5c194492571ab5a7afa1427aed8245164a23f2518a4f4016bb9af0c14a16ab67675767d5a165948261f4df2bf1ad7cbd259cd31944cb7880920dcb227d62b17cba049388b340173221559f0b70baa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab32142888d6c070357b6e8500c43182240863b002bad191bc0e189c0a0f481afe268dd9abf93938d572cac462c710b67507a913936739e83407412db51ee778570692006a3399e12beed2c2bef5a43bf356a27d1222f267b2d6ca313315905b7550c7c150827c8eef97803159d86127029388fb3b733a6f1b83b638dc08778ae53bdb4751ede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e98952f410e774b520413a847046149e1a36339c8807cae45144180a2bb7445626f1b2bed9c0d9fdb5620450b69fbb972f6beccc9cd12591b22957f94f47ad7022acec4233cf86e25631b8e975eef2348776207b56acfcfc5b1e43c3e64591fa4129077c4028c7b5c54734945a7bc986a4f4719867f219978115aeaa06929812506a40426f43a899892de243da4e9940db29ccd421fde03c80c79ba1c1a1b163170abf21cc32130c19ba2c9f30d95b78d560344971ca8fc9cb899b082fa21aef5110b32dcb13a369364d44f3aea0c4e7c49f22cc0a3c07b0c134e9ca3bdff78283592050f8c99f0e467ed39cc32a9cff97cbebc90aff850a1b1a20837e02d516033ec9cb4337a1168e013587bc4db0a7a4cb52c3496c0371c1699520d05c68d81885920812af1841eeb8570783aa6cc0088d67ba2f7acb19370b1a9e2066528bf38830e9c72c3021b6e49640805979bbf662404236bfb74717659268d4129943120aeec2132c5a205b7b3a6b8bc6c944fbb035315c24666f1ae53451b52b9b850f15e0c71a086391741cba130d07b96faa70971a2d974bd6219a2339098356ba3b573a33b2837d3d186a26559b0d2325ab88ba9e0cccba484a14b2f73c54204c3111e846249a9cbbbeb8e7d1b448f353ff7a35d1600a6c8e87c06f653930bc1c3796fc0e8001a3cce3a37745382467f614af24c832757390cd0566f0c443c7c5539c72927ea1394005ce4b8bc223905639b1c7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a0163017a26dba83777c4c0f46f31375ba02680ffaba588a9fe91f97ccb99c445fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 929c5e294db4575a4c6c5ce5dad5b9280b0f44731782f874dff9c4df0c016422c8659d96f48bb8deb6cc2c083a6878004e4afb27400fc86b71e78ae91d14deea3bf125bd81f2e5490474119e3412d5da97b3cb6ee74e6a0665fc018145ddee19ccf3634855ca2992da96881d8cb457bfcd8050f6ac71849448d5a384e2ccde4e154cf6ffde159b34c6f9a04bf7f674787b3d561dd7a44493c5fc9b6968fef5e7cd4e39fcb6e325a491316469e1d8ceff045a6b1e750011b7b37498f46fe15bdb375681111a38a58155fd6a1ad37be5c58a5d33fee1d4f896a152097170abbdd766690792f3b8a5664e8ba9f271002fb4d59f005ae5a03853cd813ee3183f6ff32bb482d3615ea5af3314cacef1352f20e4416ae01b6f03627182736eec2e1a9cd092fc52b2d31df7bd8313e83b2c8a4e8e425841000083d83c8f07fc0a5f2a332deb838a31f1a1422e9083b690350410493e6964b69a01b1d8540eed1b590d7a63f29d32d3207b69e019aeb61bda5da0b6ed2fcd9791dbf2a8d6225e875870b60ef08047789b2586bd67a6974672c8e659c1f14b784d0458a599497ea78a9349096da0da59a66d9bdb798b4ba3f85c6536ffb1b1ff750ab24cc2d6c0d476f908671528fd1818d42fd172a110b668266c66b3ef2a9323ce5d26ab6b0981b1dd0f3a3f07a88c7ea2eca259d9fe4033af8134aebc6a0dc0e634c1728586d41eaf842bcc7ac403e57dccc5019535cb8e50e56e43902286cc58f10b83763c663c116f97e04ad0a67f873e05271a1554f4d10f7422bb4bdc5b1a0d49ad74bf1749683834ca7f4379dadfdac9a0a111fc908812988ecde205951a4a427f47b32fcf49fe9b6cdd14ea7428a463ecd4a22ba68cd05c8beb4480d4b7aa9a7eaf1f6aad0148b81a426269c8e8d1593a73bb6e802046987109dcc5af778f84744ebd3c7fce555f6b5d685cbc64d77c6518c19b5981cab55f81cdf2fe247303369794b15aa0b10e0d6b2c67e52c43725389776b8d666445da486e133b4131377cdf60cb4a7813b4f45f53bb576b9a35d56ab8587243b2c128796908e60beeff98cc0e10845a8d5311876a828d6862ade7087861b223e2bcf6796e2d19dfc5a6441b99eb7f267052e91282488637de81b3c033c1f5ecde939048f45c178d191c3dbd8e9e7ad0d597816a8bfd63f80971fb7f8cf77556d599db8fb02426dcbd3d982977bf7a4e22598c83880a45b2aa72fd8047d2c765d03efec2a09103688c8208ad9df23ebaf584e30c9f0695d76adeccd0ecf6058bf1bfb812e44e7f5d50851fecaaa0cd9a9321079d07668563fd85d6eb0556671723280944b003739e204f51f0c07ffaaf7af28dc9fa28076b15f5092a38762504710ddc78139bda1128541d2ceb29ce4a58a7176c624180dfbf257fc7cc685e35060dd1ddccd85a16caae2528a3bce60297fe68472544d1df6e6eb1453dbf0fbcb3449db5da8791761d8daae8fa4b0b82c695c11c8d57141b8453da367af090aa242afbe8fa1696db5ae73286eb5c72a5164237bb48a081a709437f4900c944d8655acffcb7554b151a7bfd5f430ab57c83b4954593b52ab8cb8affc466316de89aaaf6bc54729f5e6d6de1745325af0bf392e77988121a7a695489775bf8db0a4268612262ed68d8dba026c41a00d359288895b24b71d663ed815aaebb3ff62329a6973d3f7f79dc7ada4349c9308bfd91c9192545e05daca09454821bcbb2769adc6dc09526e9499f97d944126a9dc6a1a20f01599dcd2387bb130607bb3e84558ee7d781e4b591ae83af6ede35e91ab07e05dd3c1973d522399aa42a9034deb5de2b156e0b7aed374cf47a526d9e8751544f15564834f165d10dc24e0f56323ab373df8f021934dbe9838b8b55078823461f74e9ec52a3e38c31e578c84a5f21add911b18dabfcb060656d2da5e124511786616a67655f98d6f09394140928c0aca59b798af0528c046bcf21928f910c688adbff35d80c59d97c7cb352ea823e922f00eabb309d711b3b143afafd64fb600a5de7a0958b3e590ffb6c20aea00cbbe2e52cea27fa5d34a63012dfea9b38d1ae6585b2cfe3a63c9161793a12513293a3c7985e33c4081d6a4e740f501b3dfd54a86ff0498f0ea8ffa3be90e86f21d93f31706a794126d9b2b46231bb26e1102e8b6fa31f529cb23e6d131f0dea516e231e2d669562843b87e3563e5eff17 +expected_result = pass +expected_shared_secret = 42ffbb3ae86b744b00f36a01f9cb34e8a08916f455c9ea0e5e6ce81bb5042cae + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +private_key = 817471e55466b5babf92a2ad879c9c951ba60d230add630984b2528f9aa07ff755d7d79a2f9ab53d8986fd90895d5401dd97ad3f7a922516279b5858f2087e6491b7bc42b8a52a5952f23622d5603a0a3152990cfd6ab9cd863345d8be5e295c06b79332b0ac89282e61e5534fe0aac95aca140398b64175235b94417b8799a4b6d6933a8b815bfbdccf886664e7b8c5cb0b999bdcb2bdb288d569666c421e2a950d198158c0d36ced3a74d9032ab7a2b9f276be025296a773266e516826480e520b844eb69710120373a94705f9030ca200a7f85a94db1f55d46081570925a476099c3ebdb32c532a6d8f16be4de6416d0c30d450808cd3c08131a92551985b92255282be6087703f182156a13cd144aca3924fd15492dfd253ee5c9e78853590930521e843a0e37a26994197b3161ee1a60861c344720286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb3803f8053591b29bf64c2dc660ea9938200738e2c0c318b77ff86749c43c72f9667d80d462d549bdfea30cb0d9641b29308a461df72914b4b40213b62e68b161f83224c1a45472b5464f97c6d6371c69ca0d520426db8c1e938a934d50ae0b03be706b74cb8c674ea955a4d8ae1f6c0b56263041fca1871a5799921c45d9bbf13c01f0a9c5d973086b33acf923a2721c8b2fa7b058bb2e64f43bd80260b6bb19f26a4f55d53e7ccb1bfe3aa424976132c3b4b3a00908e722557a3657d285c8580ef45b76a207cb31a71402ba1ef280048378b80dc3312f78a74065b2dc873b22d37990e465e425b992722a25009a93a7a005d91b9460ab7c2336bd303883a151e829234c964265e42fbf8252cb89858d590cf0830e59c54021b83da94884a173be6bc454ad5a719252beb52a4f7544a7fbc03ce9091e9acc0568306e5bec2ed942b39a8455fa341b84571ac3fca43c14563f91395d117ab021c8f141a4ec7364ba4abdd8896bc6b281c751a66c767ac960ab52058335e14e7fd8a4e1d44de2670f9bbc67f682a0657530eba11c31381897d989bd392fae02d0afbaa5afa1748a80847af4b326f970c6161e15b212a1c66003a4317348374e66b29fe87f36d01af5f1c75be11bfea21dd8626765c46f0c153d0555b419227d50da5232810d8517b1a5e4147a52ad07012d8da23829f39a40c70d565937c58a11b1a25b27c8207246c4e1b40230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26eb251ab562c0e44bd238874e93a4d3b900a4b2b08a0b68c2b82c0cb56325548da3316279672913d2021d742c3619823c4391e64112b5b77e8d707f9c1a37d3464cd5f96543f720a0cc6c9631458cd9cedea7b6fcaa76d1e60c44f74b986a772cf593ae712214e21179519c39fa533a724fe8177ea59b1123e831e1dc561543a7e559697572157b60499c4c615d02099d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf7d25f49f61bd7363cbe3841aafab88524b0ca3381f5b22dc84c6a112979c3c39e45157c0749c04b022f83f53733a21e1f1842e0e72f78c6ae1e337b53215ae8563b16d99ebd6225766185a0d92f9a28bbf4e2b444b7c8225148f601d014bbb8839b4b8b21a2728268a0941d3a733170fa7606b5bf25739e5dca5da49c1bc01295d6b47faf3c2fbe8594c4f0ac085cbba4194ba0613f475b424e7ba1aed1c5a272062fd878b02644d3b90f66c12c4b64c870f806ccca4a36ba838d4799a861b3f32ac8dc9a403930b5c529c8ffa8038db52c5dd2a5a31ac425f835317589369631036b487f192fcfbc9ae2b4834135365f27cc57c1208204a2ce7c03f9467ba6688a9555476a935e6006b6912091c80ca777d9a0cc9274ca04366e9a967e047dde5105eb196f8e71694a01bab8c33e99e7acab053b4785bed85c9eab4276b24274a843048de5a49c289334fc0d447034ebeb5681d87ab1a8a5b938a27521cfb89212d6594af040719f344931704a74e294886ac351a4854eec2a01b0006e602bf6d0b545c78d88c7c76fb13547ba600ab07ce5c87770377c0868204df75ee4f84a1619ba335029b68278f45b6565029ba5cc8c0f1b900c845ff1619b7fd9a9ee148003e9b09ed4c7bba8a8873b8841bc20d1aa257f78ca54941bd0a0380a922eed8a226bb90f94c8b62859c31e146647948785b225ce860769fc51df7c4310984254f927b1c200834876b23a635869c90df39bbe36094bf6b4835750a6f3788bbb7a3140a7f85b1c5cc8bdb386a0f15297ca9c6462b21df7c11845788c130313c642ba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fc913ef440addb37107e3032476aadb55cc0cd93e317a8ce2439f2464278884915c54b97e882dc44817488994c0109adad13c5102847bec7730a57227158c4ad1b51afb66d5c01bb6d2cbd1a7083fa6b049912f736824ad40a1acb22f2cfc9c3d145545bb6494d0159c40c12bc84e8d22bb8e1a76c237020949698175b21410cd4c7bb567c52b08fa6253a50e4f1573abb18f74abb9837cce85545f8992c9cfab66f800525841948b18b7ef3a2b0961c4c7e8902acaccfc865b45a5209fd5a4db705f94122fc69196e3b56139173b32ec9063c4151b2819bf9c7b5d7626b01cc420c86d1070428d4a774177035269a46ada8ec0e02230fc6b066c57dbb875a8f294e66166f3d7b95edc3ab66b15d7b55dac16182c13b371d82c42b85313c65da7eba0920914acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c284f1589af30d00dd6893e70d571700b9a07baa6083b2c50ec4eb95e2236402f7b50c87a9305a8b5eb25664d74d4337af268b48bd1855574405ea6237bc057e191cc6743742dd5a66373b110d380bf7c03039296f56ca700ae07d1a826965d55d86c19902762e75f10cef33664f099f8440634b2299a474bb8af328a3e011bca75db90b90c52c1699c1bdcec31565e411fd1c6ad2d08eba8c50b66a57cf10a98e2335327b011a4c3e11f58415b6c38f1821a69671fc2481920c896b389cc5783c5fd3b7d974ce03375142815e86e13ed4e052b1e009a25a2097c02f3eb337c3c85551ba14e1c22036916cb993612c809bec807da4e25cd8094c36720d376982650a986396504893bb0d82389886942ed1aab5bacf3957aa8d191dc56c4049a0714d89bc3af9680ee602e154b5e1c35f1c0440eeb0ccab22103945623fc201939aa71f99ba8c409bff83276f84879e590d9a448e1f052188285de9668260282e8ecc630c15ab164271ace0c954f13944fa9f4eb3a848f11ce7f0a439ba07a469720d4506ecf6cfa241136b469c12e48f137601f39a5adacc54b094127d2c27fe38aa461c76003b9ecdcccaaa2b16d1e9a164122a0b1a1fb751bfefab4a1640a792d2381a74aae77084a4e3cc33275eaa595733fc4a99d43be88803244b449ac71da53b2cf30043c929811c9a558a165da241afaa8c45b07c27876c8ff77b721b21022c958323b41ffb606c656519875b8bc6e897854c08ec10611b954c693568070528824b509f83a3e6c505b6e3203afa863bca408403c0ae86a374c1613917bc06b94dda73a8e0c98cf54a60cea727cf1334b324343b2c47df4a843e467989e4160e1611c1558928717d794290cc3911eb70200f51152d04871ca46d2753836791ba98aaabf697adc925a827cb7f3ad01069f5748778b5946c78ef9688e16a5326577ad5a5773db939d2631b04545c530c9b99141f4d213158d213163bca141c7949f24958b9aa67089488a732189ca923301143a1728a6707a6e8aa5bfc4d05b6cd1971290114542386231cf04c2c80cb28e50026c66763a570d173612f142ef1ebc6cc9a82f7fc10b7104b7ed6b30c95c5a63a5e1e52450c1c26ca11613b2b3ceed10968e85c0a9539c28242f1b9a083c0109036c6aa9349f201648ef14d67094af9715422885c7d69627702943bf0955d90496dbb0c0f2b3137b89c62903af74b2783b11748bb6df46403b69701e1d9a1e8a63f01cb969fe9ce00d7b539159e75372dff7a85ba660aa8471ade291fc782403f16bc2bf1c4d1a138a0160cf44246fcea7666276318940624a32b4af5b15f8b4da5a05557bc819db8884825b8c2770d6636a16a296daec0752e961cc4d11d61826d883a61f74203006a83380a0f9e5280fc1b831567136d178a906363bb801411e069b461027a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a5401916b35e996e1336cf13249d0cc33ecf610f9811c27aab55c52944298c3a13158c38501813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516fb21cf5cc9a8a47a07cb2a154f73676d39a98a7d12a4abbd37378595c6332f46ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = 32321e07f03c470e7f512459b81f4f73ee87272c832c9d6c1aa1bb4f1ee06e7bb26edffbdd4a2895892183cd155487b1a3b8da76c38def6dff27c8d28f5c6c59e4c8ccebe41b55766b1f7cbc269e029c11036263536a0132d116d3d8868ece468e6eea88a30abcf98e5bf9b0a933264b79265de1f986cff311956bcc2b7c4288239c14a7ab629dfd754318159c49380ad43faa6fc26501612ab3d5403291d312de1e183909754bb0bd4fb3c1905e2fdcc6ab9f05b984cd093605e7fa082836a7cef37fd745dba9c2d1b381a139d31e5ef4fa2d19d0a37b732cf5b2d40104f37e35f57fda0763df9ac35b81ccdd6b5ae33c85e70be21935adc0e84e46bbcb1f1c06ec60e2ef862f442cf401d57453d3052153c917bedbffe7c00d82e8f502b22e2eac53b97742f9f03f0157e3b00a997bfe577fc58db3b84114ae7f29e2148661cd3136043a7a194953f45a7735685643d1d4e54373a2c9146db06ecb8db86e210ec22218bb8e70634f558720d6299de1f5b74b0935c97d9b5bcad726964766a42a18b6918bd9dbb290e65f28298b3d37c46e58239263bfc8558f4949d882d91ec4e553235bf18cb8c056db5565b7aa4e7e2c3b8267188fb5f3ae0c5e7b68494a17a17f51c7e4e7153954fd77067021ba82eeac97e54d5398ed4a0462118b9ff429e1fb3ea12f915b4105c2c089e6db8111e5acb42942ca67687748e24f1b4460dfa8457e0346fc54d5bfddae4e2dceb761d1bf33787d37c25ffd5d5c21338f388f5676560636d30e71da73fd7595843cb1d6e3b117e471efad1da518b4bb02feddcaff136cda7b640e259c8d9cf915f53e3d63643884d85daf87a5956ba7e3cf5b56588aa16dea2a1aa839deb8e1f10b404721f29f3163cdcd68f599ce325906d3d1f5bfbdd0e7b251faa8a3eb64396570bdb58d6f7d7a2129c0f3e45b3d876b3fde7a70dfe5b0b80f75c03f4f710e37f820937f8c2ca9ecc0f0b0b4256d754e24a5d1c544fde6a22a0b2eb69eab48808d940c09fedb315dfaa7a2f476df90b952bc8e799a2952168fc704b1e3603e5f84702d81a0bdf87695f971cb7629df72dae408f95635c1910314d9f973f52ab00c190e03e9a11cb93456186c41fc56ffc6e8005476a4c9377a08f406b0b116250ff4b29006ecea251e7b52d49a51dab8709267bdcd6241f487fc4ea2a75388d4ac15543ba1dcf99675dd03b5dd8ae49e28ae1b200b277e2075e169baae3217c62a2c8579f9588caf53eba32c62351dae4d963a750f8f3882dd97eaa7115d802c197a24232efb77eb499d25ccda398cf7111c59e137cb0125b2799ea89f60b6eb55acd3cd2dc95ff5eabf114fcde7b734aaaba78f4a8b6db55cb97dfbdba70fa9df336563406f0866177b71c411d96303a6176ed0387a9744de6c1e34f67682a9ee2bf0c619b79b02db5129f31afd2a09a74c4fee27874171517e4a33afdd8810e72cac1915c7a701236059b9d78588ffc27ad078c9aedcb6872518c5aa0538e9751219bddd322ad0e5586d16765de15c19a2d3c56304085b390932c8e75d1f24aeffb7ecee790c87047010fce2ed157366634324ac2579617f478715929afb1696ba2e965fc7a19fe956cf5a7faf163bfb662533a6f1dbb2d3a81259155349b8c7b861c6771210dfe361c2543e7380e4b16250099651175152c86d6e3d697dfb92d6d4654ee0e5dce5f835d3d9881fcd85313f431d3cf6e13a615371bddeb17abcec3e44952405a8150ade995597dfd190c8ace3d580fc01d928e584ad40f41da93e7e583c70f69f9adddec54a9fd7d03177632f7cc818bbbdcd048f7937393d159ae0d55ed3226c94a7fcdaf71c2cef76772fa3f0874081f4b9ac27e3a9da00968814f9c38407a77b03778731a69468ccb83fa20c0458a4fc4951282e6d5da2b9134064547ff41546e7db0bc81fe24e1af6e4bc4720636f6c956bf96bea23b2627ad7f09f3285b9d93111c381ba9ee649c503ba794105d8471e9340218c55bf16c63b845cb6501050ac0eceb2ffe24f725e6a04d5a3acb0e0d98d6256a769762215441875e03fb7e09d46cde7bcb05c2d7faffae7fb6749e480c17f68638c3aedf8573c284a0ef9701402dc956ee859f5aa2fb704d234c6294c14b7bb98f8d5b1b202a898b245fe9e9339ee1418146f2ddd5436f707ff461304910ac55364729dc52218bdfca3dd084b1435a341a464 +expected_result = pass +expected_shared_secret = 90ca5a797490eb35c3cc24af19fca6dc71d41aa58d68e0061c1bdb8481e691d7 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +private_key = 60e93beb5544294bbd612141956430cff041e0f969e954a48298c7b5f321b9e1b70b7c796a753cc5bb93722b20380abd6b8aac4f0b102ddab380b88ab9dc040fcaa8b775882a673864fb757a3453273627df0690c90000b54112dca50235ba14fea59a764736a018a091b822a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb792645325d6755d79b972ae993c9e3413ac040b3bcc85c4f98a2e185bf4ea1d19a4737dc78547847b7ef385d2a07bfe272764cc873be8cb1286a0e7c83539d2b9bad5a17f0893ccf41e2b5cab8f66706955c5e168a99e9820a8402cb25a434f1a149f0148761014d32a51bc73a8cdbcb104c29be554b2724107ef314c25d082c7252e0ce68833a47a619a611b08394960a64d8c22c25aa1121a8033605c9bf35221730b15e6269cc25febcb8e3336870b3c1c9d3a89de4a9042758f517b55f85133b403c501590a0f53542239118f93874b319be0d063ad82144eca6156051424235d785c92ac00c412f8ac0ff5b88f056142f8a0934734b09ba14c00089bba136279a5fe462082ab4b0709a6db3279f8e9544f3909ff78b264399c2ed129c803b341d816eae96bc531952d55059ef0233b0c18e1f7aee5498ff6f11dbe801dfe193bb61b870008ae57483daeb8ca7ccb460193c68a509e8dc738ff227fda89b21eba0053992a4d3a1f8767c0d3f3419838c8c7a2c0b3d68e737ba77221c68a8570948a322a143e5a03888c08a1bb7c42e9db9111819ed94523848bc32781a881a468d26aa7fa4acb926ab8695b24a094b8ccb0423192cea88c1fac818a6b0ca19e423b7afcb51b121d48ea44037963ec1a325dc0bf7555977f468feb49b8346338db983e512b2fdeb35a300495f437cba88c36d01536f7a56bc9dabd1000b77751031102caba7182e2c440919435a14bc1ae1b354499324862885c9c301b7258faf778cd0a4721f26ee32c5dcc7a7283dc10e3cb04713255d0044bf1d9234f5180f32483f7079b2c0558b95c622db01be885b2580931fc8617b6940ddfd54cb327712da02f90a6a8ddb6ba17a31fb1d7231d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fda08897ba1edf959f37029a84e707ef676b89fcb5e94b8997d95542e26cbd28a7d01b1fef76b1c91ac327874c04f01b2d6280fdc60cead3587bc0aa6ec76f064b3263b2419bf3120aa7791053bfa6e089f6cb8bb020b5c5e2517d4b2f34ec3c4237af98dab3f4d44ae161773ed53f391a689d7b38f01155fcd080869656e15baf9a2a6419b38c2ec39112b4216fbc5d94771fcc4369eb90aaccf3a752020e24f97c30c4c67632180e9b928a0941c23c03ce588f7d841aab91b74b7959bfd8b5b042294ebb094b523dfc425e9ef70bd2e2bcb2937eedba0ad018737ba91a3691030c1a6e54c0bd4336a4bbb7c5dc79057ef5c574c04dfcf9c8407cac999a54975b1a45519075ca167b8285b2d554eb81702e30626897413051aa546bc63a42723bb95f0dcc525944c967d7a5793c34c7638ee59608c8680f2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93378f15dcf2959d0e02a15e2277b7ab78cb2ba78703f13dab307ba1b663c8666252621ab1b9fa42dc69008881a2f0933c03c183d4b82cb149511f344cdfeb0adc0c9b0cd98240a7a7c97d6ad8eecb20a8a04119b8aee8ba273730965608d0ce921a6dc8b8cbb0098d722edcb88cedbbfefe2a04935b5d766577dba7c20a73e4a8b81d6b81bad326817f8b9d654b005d7437c73761c62a43412b39ea821f9547b433c57c2512268da14bbcb38b3906348fcc9facbcdb2f44e713125309515b6d4716088071b60861998115ec97d9cd99eb773c343942105b4926c14979fb62f7e6616d3ac1b0f12a96cdc7ad22ca6148800b9d1047a8358a1563cb310607108198c084215bc1630a002b96a74d92198e832710de036b0332bdbb2269e23417a82a1dffc57abb971dc0a34d04378308b90ad36064548c5480bb57384b7487c299a016be645958f64c712b75454532e4021ab21c55020b609e2e4a5dbda151f8a9cb9e9c552b73b8241445f97ac15e0a5e7a357c2a6608d388652848c066b5f345c7ee7a1410db478aa517fff742ba1965abb0687286273d9f993d7d730988a709532712120555db81fdb599de13109277a48d20b0b16db7c6fa73622acc63ab1036c9c07a48c73dcc4111e10c919d09b3a48b96be05e56d809efb66ea3bc97fc360b85533c4ad1a9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6582274b7559be1362ddcb91e5c857b0e836349d4023d461b1b24cc873c56e6404149026cdeea16affb5fd715766617b9a5058776b74b72075e25002131baa50ca093bfc909b6102e8e5ba2c748bdc5ebca2be715b2800abe643ed542a8f4c055a0c7122854af8460016ca079bb701db46b2b17d0013dba7d24685fb46966ce53b3842cc66c8baca0934efad619459888945759b3842e26a914c835bec4410fabd4c98350717ffc143b2ccac4e72b64d195fe1147fac6171ba8b213eb5724039d889620c70a55ff0145caa543bbba3f732ccae4b0846200ae7ac6c84396224474568c058fd4785347f077da03acf744005ac1cc02f93f2130386aa2b62275722e11589c625044335779d8bae917a632652536337db7c78272241b4710210cc7954b6622bfe1653f4788450900d3dc9bcad010f9429615d24c9a4bc80a2c078f5b6e3c6847af5b0791c27fc99950e77676aea63413a3b259051cf6a83f0f9c5952462ab315af64b978bc4154be10702d5b266ac524ca2b5570199ca7ec91064c0247b08e01a8ae7f194db11b88d584237b507e44b411d5c5112dd22c7acc8d6f3513cc8caa63342284e6bbb16b2f63b9acc9cab050a19fecb758ec455414992aec45bd453639564a0c2bd164c1604d035380b0c2350f530770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe542054094a450a8c9f7a686b7565a3036ba7126288ad157bdf172c5e772ce052689d2495d00159a920b68a86fc905364c20027f90171845347366053d8c718a444a1e60133fb954adb3a47a7242b8100a8f9784181a4e7e479ced14190a282feb98008c09ae2b124a8743a4230910dd612cc75bc0068a4d866ca871a48b071cced3336d5c01ca3b819fdb2c22acb71b2fc2cf61c95b6cc164cab078472658e5d19eeceb823a373b4097b4e83b0d86e9a50488c1a35418c497250bc90aadab70ad35a16facac83093570399e8f615933f48e7fe8c04e517736732d6792c59e400a228a7cf4896af6c6c4d2f3acf279c861c83100b2868cfb42bc75052b26b6920591c78aab2de99c2ac0971dc90c19b6072f388ffe054166d95a785b8eeb141a9eb0482ee6b57c896d8805a33756005978a98f3817ae53b09ab4bad0011218382269f062b9895697514f9ad872a49392166c72c380a86c711d1f00c9641a6a03083a3755a482ab70cc213cf6f1bf7699164998a96a8258e819652ecb01f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341a62631f0410bdc0fda9ba4710a21c8934d6132ac21bb4a9292b16f787dfc58ace7d69efaa67c3a5405b98a9a07b276bedb636c18a668a1c36acb7170ac82253a85d1524ed79bbef4f046649b9f6a31b924196c6f72b12f108b6d95af9b373e34489155da84b8a810cf005caffb8b28504739590fd6b2a5247a5139b39236a2a496a93717854b162584bc57044f510656906ddae771bc029a0473a481eb2bb95397fb903a36a2042a4327c8c54bea769c419cc5efb83e84692513936f8f8775a1b114c13a4318d522194b8f1f7b05a8408348b3ca877b0a59f34dda1169a8c12d716ab9f558ace0b72750c1b4b9f11be405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbd407d36457c291b4027a6ebed8003658619fc4cd617898e8ca2e77a505cbc70f20aace50f301bc16c398d30473619326e261e2713375a68d83cc719a381284216d1cd011445010a2d24379b8024c30ad70841eba93cb65621260f41125c8cc03fa2894e84bdcb06b4120371a610ade828beee4b3495b4e97e25ed28bbd50223ef0c6b5a6c53470d22abd74c26af08cd44ca194815bed9c58a1775cd0431b41553454cc892088bbaa51b26d37c25a1000a7f8c54abcb1f5c0c3c61c7f6d36bc45320a886280fe2ccc24c704a376294ac15d70f1a300a8ab1dac505f3b2281439b3f93c4d4f62f5883bc00d9589f5a89e3413f425248a8f7c011f616d65b857d2353c0d28bc574c1f2522c2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae591aa9c81277503a34441fbd6cb59c6d1ecd5e00298fa56be9df562576250c52e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = 8fadae443a93690d09a1783148006e46cbc537e90bc4201d319101de05c33bd3a917a7442f35b4f1c56acb4dd73dbd6be0d8a5cd47f0017a60eba182642e661b03bd988febc9ef27a96ebc1dda94853649786fa3707507154d4c3d6f07a0c0d059d0eb18a55467deb1f0a1ef776053b9856e7e4d6a432ee2b9717422445175c17aa576d0c3b26e715bfc654ea33835ed61fcc7e25f39e2009eab6dee957ca0f953141d1ccc9f6e887b512dee3f289139947d19fb3c035fcbe639a9ae1dda60ca47f45b033ac4dca01480654769e903771983322b756be853467cdb7ff2d8014fccee50e588af4e7cb79776242d036776b18df0ada02884d034e5af3829bf58eda38c280927c29e030dce8a4d8505205c059f9c054453d918685254ba0063c883b49c9623477e4b3ec0de7669b20b8357d8d1f6dc48479bbc1c35a661bdffe1f0bf6cf7e1abb5c78714db3bdb5d86ffd20c33806be106301eb53144a6ca2523a13997dc60e2cbc751acc36dc58b2a4cef33c5230e2d0a05b23d0705cfe0c4e638e7856887d866772abdc9ffe8950cc5a41365dc88085a9a9e51e340c8e4fa8388123e7442f17f9a647c40c90f7438026cc0fc18fa97bae1bb63fe49d745e1c219ae9ddde737a543afc8e38559ba8d65846041030b38e8a3b427b60fba15d87e15f477b355d5326d87066607ebeaa701c9a8d97884d68495211042e12d8cf7695b5c9baf136b064471c20602566257abdb5c77891bfd2e8f473f88eb8b5db0a70b9c4d338971cda283d50fa8dc0683068bdeccee3e0563b2c270e4d4e5bebe41c1fe84d6f8cc7673de8c70c2b18a4890be8255dfffa5866a5a039b38f2aa01984cd87f245a18fa16658b2efde81014e08a1452003ee5ce7530f61c0289c837315e593f64d75665c0c0a73d292a9efa16ceaec82854a58c9daa439b1ebc9681324a7e20ca86926236976a1ba362d33f7487a4f3d468f6b3f80e2ab541102f1368ad1da3a16fb3cc636df1cffad9ec70719cc395a7159542d64b7725a982ac5240b054ace33f4394dfd35480aa9ff5c8120407764ce390f0e8f8cb77ec0176f4ef6c9e64f2906d4841ce8d46192421778a3181f723722d6dbbf232e1ac9f2fbfb38a8169811782e267ee85f9b6cbe78ee9f75c224866fb318f271884cf1496724dde18bce61fb941c8d3fb21b160779671b0f14cad845aabe334c8ec30852cdd05d172d12a8d86d8e33c6067af227bbb3512de73145a1dc0d0e81a330131aec815f842233fc332605eb5576ca1b77a93bf02b0e94546bf7e887e996b1fc1522a8741f30d4d5456bb3d3de2efcd1648c41da7d73bfdea433fa60b2fb95084b1ef23c750416d5fdf3452b68eded81b4ecc636e9f4a973b0777e8fe15a62ca6399a41e9e92508297ac0c4d9be7e904481da8c1981f44322bcc987cc68703c27948badd76a5313ce40816612bc0f6c51399d810b62faaead5eebc32d9c9598a91efb8484a2ba009361de1318cb0f02796e827975cf0fe7137de63c2746c05e1d01fe2403b6fddb9615a9be91245a416532ce48f059a3053fcb6b9b6700a5f3ad6d6b88101eab3ab2c5d38250ed818cab52d152d4786502a48ca27269979f375948f0b1ab51fb6d9eb743364c683d3cf6af6423de3b3dc22fd45e2e561e122aa7ad2af8f65f5ce7d6b2877135e05a8eb233fdf6d2dde8430a59bb7665013ceca35121ce7015ecdc747b3a89fb60ebf7c05c587dea7c476e9295721ec45733605d6c94ea1ce7fa8e90dab6f8ab5457c90ee8afcdf25d901ebb34223c5db40e7768fcfdb3e85d3abda964b474bb432f0afef11c2ba80b381c6d6c009afad4b1601058617f0b24e76f6e3c36424f8c7f96fb9aaa80213e05caf90dba0e7c5a2361c1a54ab20adb6b5dcd8631c6b7540cb64fafa0ceeef7e4d8dd799aeea9225fdcfdd920360957c193fe1191e5f5901f04c7829bc50f35d8c5e2072c85d96b9a94605d7a1cd392a424054921fe9b0004dca6ae83214e3e4db55f839221b78cddc1eb8d5f5a2702cf6923f886850838a2f5e2fcf2a0afffc11cb42abcfb62baa4e42a47cf2290f824044affa377e0c2a58e325127fc2d0be21ad503b2efa5acd18856be477b62814efc047797fe15c6324d3b7afbff35062a8207f9de600ee3393bebf451a9dcd9eb51455ee5eb43bd1ad34ca52a7e63c9b43d3bc144906ca33992c33b18a07f +expected_result = pass +expected_shared_secret = bd58345e9e19483cde256be650975b954e167bd8b0a9036a95c98ebf037e87ec + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +private_key = 3a756d6dd157aba65d60721c41eb4edbec38834c22e9ac88f03119b472bda0961d1f5c3268ec6492f92d5d066dcba69ce9c20311e1c15fa81fa5014c6c956f88055fc2d35e6b295d05d6167e4375bff23257ba72c0f97f452b609f22b57f7c27f71a4f259938b5aa18097399a0d32c3602203bb6769015495b4bb7317c9e99c966215c58d3455efcd36003826c2c7b1bb437a66a968dcba35dad7098fce9133110a109c2b91764719ca25866c98550082e88f29e78b38b40a53c4d626fe63390a290b54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f59505809b1095405949cc55c109a1108649552d5f83a970083bffeb6550893b5c5106417b0cf1e44b6b05a9f9093e386c9d43f14d4cfbabd3b17efb49aa2c571ae99197d2e4b7d58775962570d528b8ebb8032e8065bdcaa391837d483a27239a4a8c0b8f13013f4aaa6bac0ca86e532523d9620bf9c2c3e2aed2365e90a1699a4cbf454c4d2e2c4273e93456142f737c8b3697b9821039142c3e25b346d020c829850d6ce2649087ab762c25baa2639c8c7a852bc76d456ee69747fe561e267844a7e51ae05c5820f0c2b880b05cc935a3bbade2c6a4881cac21938a304c4cd2c1cc1bfabd932b777cc459bae4be75389862464367c6318a0521dd62c5f070a139a95522d10d2e4134c06522cf52834562a208b22a95431014934f51ec49f5ec087d1435db935bb5223c3ec87bb7f7427a458232474ad9cc222b422149977c7f366f48b0b14ab260bd0a8c04623f9b12091ae049725064d0bb4a249075816aa249718f1a7768c3469aac7182d2f01d6373038d7c4ca24802693a354c19c66dba1c05eb180ad04c1fb095b42947d16b66139384c71206bd0ba9ad9bbb5dd7593d08616c214fd9013e792a5b4930122d1c571f1315d235562c167d7546c8ef7536a929982f6a55ce7209b0d5735f69ac6c52a824e508d2481a5be01075c54d8743bcd76767b69b5e350989e629c97ac1982a75806126245fa692def22b15a29499c82ef7f993eb3472f850527d900da2f513a9366a4fa978038b9e46752dbb8084fb12cbc591008d692544078343e9ad67909dbd77c18bf18f02607210f4a0f5dc749f8b0bf371309027968968678b0135af65138c5544abd57ed8a646409224d32052bb14bab4d51dac981ccd838b4a513a36a351b81a0785ca281d7106872583b8babbd62a5787bab8ec9019c7009130ec6be4e25d9992aa1dd13da9c1a7f1ca27fd78968741436003789b8c781c599c98d2465c7513cfe85154d7a655216e5b3b800deaa6b9dc7c0d998b9ce2b99da6afc27a5ef6c152eb16184d91cd038cba69835ab3500ac2e87368f37888ba90f219ce9da24109f0b3e1894db5f640a17b0e705195a350a61ec62b2c7a216231c530f557d4c5605346a6500b7c1484012fc87dd4526823c447b71a726d65753716b30c212565dac474ca3acee664218285a5c4a726f681e98619e2a289d08895bea26bd6a3bff3a5c5c1ea894cb6440d075004f879b41a14ebb82b74ab0131d0b3348742db7244e750ae2b7bb57f8a95379502827880f8a50ecb1394db2553c07627c113a300078db1bac7b50078d6e2443af5c1099633ebb4b9313c9f82cb967442211ccbb7dd9b4711f85e99e7b07601c07f10373b104fa849a9c9416c3304c09c1b2f22fa159bbb043a58415a11cbef06b85fd728b492bcfd0767571848652503a5a162e0d478d74cc05ba5160f398df7361b340226ed49a5449467a9a39cd5297c52bc0cb9634325854043617faa817ef2a94aec5a49f0579f085acfa164c3247959ade02dcefa8acb965705060b08499c33f70fc6055fe1752a06f0547f4c702f851b36d23da24c8ea79a942dfa6912cb00c8d892b244c765d0795545423233a6bfc01f38fb05b8f953ffa532b7b6c2d667913cc966f6b88f63c1bb06b3bce5310a8be69f0837b8a0494995844d65350502c061d65c563fdb6b82d41e76495ef15b56f3f53d5537cdb2e6c349844f02121ca9f404a19c6591600d88babd8ca4c25c973f89b0765ba6b4121358c1738e7c718f6cca0d6186594b265fd53106eca59d9ce51c1723cff7f7053fc6240a3718b0aa3d942084a97185701bb213d489c4801bfeb22463d9608b92053c614fd2510dbcdcade2f57004cc995db29139a713ec106607f815db318f03d2caf4a294caaccf34914106d463fe118bd0b65021f086f1f9a8f34a42e197525859767d89b0eb29cf54a93e76f13bf43344bab7578ce167796976e5c7a2626b76ca2222cb358904386a5485c67fd58f7027543185c71ba82cdeb93b619455cef931560452d7650b25617c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5960a08a6d8992a23aa5840c97adf727e698c990684d0c19ac71bb816ae30e71351c3300b2edc22601b6bb7545a87869b9712997aa5c3ce6080afa8333e6159c1de61333f4742e5c49e887a8a4ccae2df6c7e218a509124d151a711da99a11d7b5841752c498521c3c4699113dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b592327d0242ac68ba6d01369257c56427928aa5b0534200ff8a4a7263f9f955598a0980ee67337442df706360faa20dd6941195036831186dde104c5e6cd79a84afd6917c1122070ac6cfb120c7f22276afb4d51f52d0ef2bd4322164f938f66269703ca1db984bcbe337c710142d024ac0d7502579b1b804bcaa5fb551274ca547301fe6597cdb0754ba6af7d74bca789c6a7460ab599cb14825fffe28683267001e32ec6f7802826c3d5091f8c520ca52c51e1e2b649222bffe45d9d373f8224b9e3e973a852a0d6acafd22561aa1376e9842ab292a61c21308e209d3ea353d77a8d835a46e9315ee19bbafec09ed462269de56b36f6791f771922b49a51b3870ad0a0a2f3aa0122ab02648ece97c96ed24b9e99b6ac2c964cf356e4a39c21d0274eec6fcc8893e7cb425c68c8e99a89d22647a5522ffcbc46184ac181d556616503aefbad90966d2806b6bf26903b18b1bf5a89167a10d47cb4a6f101fb09473710559f39b3046bc7a55331e8da418bb34089793c2a7606112011e89318267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd85f815c9c15b36077e9971b4ecf7546c4486ab074e511b729ecc835c175b8304038550aec0c6c22eb76f866444859293d21b4743e0202a3b6db7d2342585a5c098ca66822f86f01a6a9c080b414144220c44054801c36199432870f8b39b08831c8623972b1ae3442d0fe409b47a5c22e67738008a71ecbb8016ce110794b1d313460650ceebaccaa637f9625429538dd1e00ae8930211063f3265ce4b7c6ece835faba9236cb228ed003cb22cc8b3c5811bd9c276944d929c5c67b26b8648be93a89396c2949e26866ed4121c3849bc6c15adf8942fd4ce8f12b5dd83cea1322ed4c0bd2bf9b591fb01a7dc49387c04e7c1416abbaadc2c183072ca13c31f8e964c2a9b56912571fbc07878584f7926a9cf13c0f4c114c59b1b44a94014c2963c596471f7771cd383c235aec594b61eeb17266a5ebbc4828805169d1a2e468448e73a1e3c919ce3f738d2e1242c0895b59c27e12cbeb10c591a54108a7b730d2b902185b9a8da9d2ae01807466c456c4eefab336c13c6e137b6cce922b1113e1cc862c8883eb69acb0667a68fc58fc5d6584af926b25159f4700c110c43bcdac03714714ad4c07afc4d54200cf0184e5e8a6e5df1ae6d13c9f9401ce38c6144d3b87dea304625cb8aaa6ea0695fbbb775c6d0b7f79a6fdc4c53c9ab072d027da097a0d69ac77a9cab23941aa160bf36d95b10167364a0c866e44be2930199a00972936275cb9f3340812d70968a95428b3000b21c68a237961b99a2c7f62c9988675f01b1604910b0d8942b21c49e676532603ddebc39876c8479603f9360a9538679c4a83dc1c33947b5c01a5c659d30187db308bd999d68e30c79e40b631bcb8725b72a414e3be0300e4c7a30f56abeb9588fe0292dfc23c4c994ca20726cebcce5942a3b376bda76a965179f56e66a2bf94ca35090af041607c18545472db1e71af96570538796418737b048859e676480727e71e3534510998402ad13d54284b76d6eb04715934fa6f05cadd2a6cd6683d981cb5f6a884d04ccb008657f990545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdb304558423f4a47961e230c9091f0519c15de10275da4757d40edf70ce729a5986724e8701101c208e4e3bcd4341098d8b07708a2c81eb6044b82ca3868a4752cf42f2596c7ba678723931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a61c6c4009e28f6a20aad0c0b14b7cc0a01aeca507c366913ba5cadefe6656881b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = 39325b915a27e67b4e189cd75ab85f09f90259a816b188c86bb83ea12072787ce1d920bf265a004055f378b980baca30a3e3d5583cfee57837793a58dec88478f9be1884c5b820bdf63511dec3ea3f502463230f410f3da014d1f1b2074573c4a981ce5d1407ef42efe250464e60992e361b1d8aa52a7ac920a43092ea68645bd7a859c15c5da7411fa82aac79b94eb0c7b0d20cb7d3457522165f2cc4c7e3702723b74b683851a7b22a2197b49993065bde97775240dae26f2c128bb9795312fe9c7b912521168cf6eb620aee6f4ccfaca57ca71726a20126cd8df821194242fb044ffb32c2ebfcee78401386ada4f9339d504d26c536d388c981537569056fb4d54742228e5363439656ba7f5f5b7a949ae60a73891d98b0c18b5b9d265504f7ffcd4b4443c7b40a927ed0a8db13ba7dc6a1f6f65d95f2930652f9b8e03bb81deb4205e2633d4d38073397574fcaf47132a9dc686246433867968fc3c0564f590e7becf5e77ac4feca88b73bb55fc1c7b88fe0f3cfaac080ea06ff8a58d52b7ab22c344ebd3de5690ac58a12b17afe32ee420241486b70a4941004a4122906d7644e3f1da0f5b2c0cf94a8ae411ca0a49431d3d4a9e0af53ba7d899d6084cbe3087bff51886232cbc64b184707fc968f1e0f412057f5c35c18a4edf3d8c374256c154019203bc8d0191393b216c08143ec31d236c6c8cc599edfe6c3280dab9e46e5bd87f5d39a1dd3c153050fd8f43605cfa0a13d62eda8e70abff019be852f7e179d78832997a39c5f9d64d15387ed5df9d2744703860deac9d71edd8b0557c77cd40566e3a4d750c1e81cef0d6605c61159e02583a103140dd5d1ed28e8b5195499b283c4fefeb59658b176245b6308c21c64703cf5125283b5062557ee3edce4b42fc47e1e5d502682160b02d4010b4d731c15300eb78caa8c59bc7479339450647280b6414a812478f8309637135a5e95147f113f57701c8882f389164c748bfb561d0e088efdd7402748aa56c8faae61cf0c73c2a0ba7a2c9cc91e190fab3c45c1e414cd5f3a67626cc1e217422ea31f374e26cf5f38e003777bcd85d699ec6072b74c796bba303e72a996830e08503cdc6c572d6e756ebdf9c75a6dc09446d104a186e2c1de5d123a4931d13f90a9d7947979ea2087c5bfa83af27057cf2d28c932ee2ef4cac3cb330cfcfd9467ec056f4a9cf1bd376ee99ff213709139bb3694505452247cba750e70cf0783f51485e9596778907800928baff28fe3d7a078f0acdaa2cb531568ff4ea55aede535d6655eada18dba94da7ac9f3dda16a4e26780bb69ef34322b763d96cfb4366e68effd984ddd2bcf88211fa25525e94dfc7340476a4a95d356984d58f7e909072068fbb955495b8a749a9da1d770c4864156c24c54a10bb95839bd990405a477314459abeee6880bb30e8ab6f7eac5e0c074d053af6746277eb9aeebdde930e39a91673e62d85b21f64816127435de3bb02571788fdd575b7398961d2bb30a7625695fe3ed468a78aaf58e9eb841739b1e4d557d9895753acc6fc18c1ddb13ed1497a2f9da1a7bffa8ede51036cd094d720604db03a58c85af1ab9c078e92d8eedc226f4e423554147fa6602e48d0e4698cd0fa6bc45113bd7fe8848345a4e6d0bfb0124af9efc748bed49a34455c6b4b18d02dd2e719e486c20d7f183629c4814d01eebb337deb5debcdf058ea815ab556fd478f2d44f099c9a66b043b00795639f92782ca1de0c4da31b2a3ddfb1b20dec2333ff9d2722f88d7aba5de0c6414fd3e6f9612d26bbb9e70ee8dda869d11e253ba7def491c60824217bcf6ae74b9db4fe986b9aca5e66d8e4252500728dc55d34e551ec3f3aed46813c7785674b56da68ead15d9b0d353fe167e5665f4d7b331f9a535718c3f15f31d647564669bfa8735d88ba234bbcf79e048f1edfc0dca2fb5a6860293d4497ac5409fab8c026ce8ac1f77e6235a20fc910d9ef5a99a2e115807ad70af2d50eda409475813531b5464966bfef31e145dfd341693e7bf2ad51d6d1c492b67bba82b120bae325003434d01b23ceaead993823d4032b6bfe8e6134480063b48483cbd8a80abb90d7f073128f9742a4a4762c8247325c7dbfd96d8f952f8db139212c15ae1525a8611289cb8875a4f06b626def6eca35956547a7e4b097781d6c041c7e232a83da13121f6ba642e038553c986fbe6 +expected_result = pass +expected_shared_secret = 53d22dbfb623f5282ac68ff607b69b9ce559ec3b70aae668c684d90dcbbca13d + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +private_key = 0baa531a985251b6b10153c8fce6938a280e93f9ace7a56dc7f44fa8bb2f88c09290888da8134a0fc43ccbb75b50b6a724d6812183acf876036dc252fc893419280314c7611750875821b2f3ac4f1c20b06365709bc07ad4161c94c41930568996f8cca58c4a0536cd5668488715593e66621f96c87a2178a36438dd4c390ca0532d30b88db712cd3c50d30baa91c98cf0bacf32c60c81468307ca35b47abfe59174e53467cf7b1d376758f1a5926fe225f0078ff288ae24d23241709e471624285c4fbd35a333088dd643cf6cb0ab6b27c8b679792ecb8ba4c28cd8b09677f0a7ebb692eca6777922c4ed6c20402533cbb9a3f1e0c10250209ef128a626b763b30b5e49c4c4691e3a13c2c2601b6666aba1d099987990bd1bb00ab5806390ce8088cae30a5b20567295aca7f0191cbdb4795e78bf150c7954f9a49880c218c23e59014620e18f18c536da0b7807b0c9e11b1e341c2e7e5ba799653fc669c1032aa014cb79769361b01091b5e000cbe100933c6d05714481f491b2355e72638831d0c4f4daa18c6b4ae6e825e688cb812490fa13b43d306e5bc857fbc18a61923f6b685e5fbb5be9c1871a9822ff07caeff40318482144143cecc5b0c579c84fc949ef359f0b24b20fc0a9f3300a3217a8058469c78b7998744024e275cd1c70a96a75fd86019ca031fec081dbdb796a56186d9a1df8c098940527d34a1df2db50b5136b6737829f0cb1da3b131ab238207a011f02bcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae81627011a2633f1c159c3870f7c69126b3c31f50d356888f9077fc207168cb075e0940fb7a0becc556de78089ed512a39a6adcda9c3c5126d874b50c163ba7b091656e52f9813cb318c87abab12a3f8996a4cb446d0793055ca177a1bf455cb956443e56c160f4788cdc6b008c086403bc910332d3e3274f9825e9964484d7a52c91c275e153a496801c0e6c8084b25b53c8eba77a9412291df78bd39895dfed82fd3c92947a1beab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5eca0c6b68090a338eab57a222fbb5a482837c097bd40141659a2a71d81e3bd38d60d0a903592b768b0ce60a7044350a75fb02f19482138603a9d8cb89ba6a32d37a15549548aace4636047d66ca4de6cf7643c2a5939478a39873820578150172f965d4dc6cc6d7adfc360568a53c97d268900b7b20122e50cc5e460304927333beb7bf73446064d76c3af1274b503203804774b00f02534772ccb83caa8475651460b156a7238da2a9847d445f55687a84baa06dd69d4a637efcc1c09f81bb97b541fd77a96883869731ac776913ed6c02ef03183b27b4655639509b1e8bba74837375628152814448f270b6dd865c888180aa071a2ab42740e93f05b32a9c85a069420be2ecc5335738f9d46c90c5af1625779f3a329dd693706618afb300b5c7099c220126c8398fbb8f32a2a35888bcaa187950365f022585c2e08243f53122b6c5ee9a95b84151afd10b2110135c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702e327b3e53555e24abb670ca6e505df0e0aecf7513f7e36374988dd8977a0d93af43a37e05a3463f2cb5f920b7fd117858380a96681229e87db5912cd91115bbc11712c690ac98c449e261bf959ce716ca4acc65704a5e93a7731d1a380dc9534a9611ed89c03e72210b1640fcac8003235d3f3a09da5b89c2eb0b7834142591a8a944a77bacb8ba6260ff3b0f434021502c0e97686c7feb6e3b6214e12030c05316fa89a474e49db8896284821f910a4490a40458a48ef0cb1639234c966609343a46c2f547aca939e4e471280c1009e34bf837180b8233a4a2901557b3d4e91b707414507449296ccbaec642470c8a51e6b7b759397f28c6e1163b0d6691322bad05ea09a4f17d3d19262d81b22c5b2009b80d3e4c23a33144e9cacf2dea1e496472e7e0922e4646c5f23c532a62a718c303e993dae41d7c1a2adb7c7cbaa8ad82b46f7784a71fe40d36681ef2fc2d1b757496ab547375415e5894f1a89d46a0206727570c8cb363343d0f4b73cbe08b3d639c79a808baab3791cb7fa51a546d39348e1a6e1162789c2a2a5890c3df94380e53085127c200b138a2685786391d97d3b6fec35d89553e3dc1289051a39501a814cc5efe04bda7d7ae7531ae70706277f71055ac32fa25abd26ac6ea6975d5a91618476d62e311a9fa3db53582462467b19a7a7f025a3b20a3b5e183eff249c855bdb3719d5934c3be5b64576b71ce525bb2874641a09c036bcab46684e6280b5806b74c4192d0a55a54a6329ee7715c88ac3f1112bf49b7cd642553b152a45366fc925a4f34c2f97646c51511c0c9899161914654c052a06c6311022023954c28bbcc22b4641bc327aa37f494383639aa3f8a4153127f28ba56837a198b604ddac05f82cb4c11834aa19637804c6643125c9465ac03516334679f36175b35c0c4da90797e7a0cc36173eb07b8c541ab501151d9331666267adfa60315305be5345c46f628746025e7959dbefa1fc0593ac94ace87fb515a03b00bc84b66507ed2c6ae4d931fd28186c396582a56a63cc35af5ea02e980ae2dd21badb02699d69e857334b1e96a5086bddd7152bbfb2c49a411085a94321a43e1491f0f0067b06688a5ab8d0aa17a9448004f25c1c5322b8d7b6563977fad0c70e7bb961ce84cc685aed34b25f0d30ec53a7a5ed943f6ea3dfc917b01985c609c995f765baa071b3749c89346805550ba19d958c535627e606b2f0c2706632fa466504c267dc7805e60a0680ecc158d6b4f75ebaa030292ed12cceab06d5c878cddca919050cc386386f5c8b3679b254959a06ebba5520646e65250ce8b7cca03227d1b43f49c9e9297269eeb64409712fb868cc47b406d9425868b6a304aa46e472acb0197a071ab9d1622861916cf31afc12466a4022a3a635ec89433635bb0afe2c5f73670ba532714803b1ed473608c5e00c1ad9fc90c91281d5e081692d85dbff0acaf5579e2b1b6c5c1b61c3579cd13a7c8011cf5c19709366bc9676cbb8b2271c784672200e6a0254bfcc9b6387d42993e275ab2da100301b11f7e4881cc5774d2f849e3d3ce63639ccf303a7f7914287079c6066525a4870b974d3da72a9290b96c6846eabbcbac2b730849a9b014100adb9c66d0b5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebbb136907a02eb5a351c94607fda4eb44458c9cb8b50da190e307fcd63885463523086036c5655e8e2621d4516a39084fa5b4f9744a921f497eee3a46eda05a4f1481ac5b4b819a66753b5b75a95640b0cfa07aa8a2033a8f51cc526cd1be8cee5677a78f18af9608da3a565bbe1a79c58691a45ade1aac936f15eb238bb4879af7da68ce2a106031a322c198527b94984a16d9b4a55bcb59e9eb4b2068182cc9b17a8cb2b8a776206b59258a2c9a19243c9925fb5d135604712baf09e2cdcbc6ed11fdd530d83a901f06c166130b912a53c075178195662d9212e4219c63271485ffcc9aaa6222c9aa2c4e64f5d686bd4874aadb456ed086ebdf151eea4be6bf57e2cca56edb04c0e68aa4deb1580d005d9da4fc1943c85f75208d0ba3b517f89a82a2fd8bb96ac07836391b2dc3b6b0533f0d91e170986cd245fa2a90d6a345679377b767086a1173dea82969fe3bfaa643af8f98b97a8432afa1a8c748ee7055630812bd2d80be782a726743627e707f7ba069931c9929b37a9b0b04bc23405e5b890700dbc419bbc635c12c390e0a8618ea01f2abc84eccca4b9f576664237355a40b7e931195b606c6759848c33a002b74b4706266aa93fdc2054d95e7ec30f1ef53f4730af8a31a757a55a9fc69765f67ce7ac0413dbbb12980028baa2ab2a378a55a283a6c5b73837f8462259c2aeaeb36c7be5447ea22a85a561e2477742c61dafebc969ea66ff992455db36b6029d863a8b896057251b8adc659f294707cc643a91f3aebd594b2d1c3c1168b474e011e7a280e316890d467b77732e48c7bb0216381ac8bbbf6a7d61b90c9266a33ec7744099b2e4d464f1a11e1d38883de5c89371585a2247c4b80110566817808e52dba03061848fd6338cf03992c1ab83f68a13e75c6565868dd419815a19983aa8d5c4123109a34fdcad5fbc3c37c87d1d4a6b1366906a97099df940b2564f00e37760786ef28c7896c09d04c0cd24820596e538ee3876b548667cb26dfb6073eaa5631b92c4bd05320c923b53552384d4afaa047a2241416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc4576536d1bace29aa7c31f7681222ddd15a3cf6ea6bbd3528d2ec8610d68d13471600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = 3bdda88aaf866064ceda7b317ae51b6746073e9fbeb38608155b75cfdb558f0e5f5c162c48cce778dbdfbdbca7b2e51681a59bb262238de3d4bbb812f7b0a58aac58dfe2adc4fb07a9f22809aeca5fb7c0d9c6f6a0d776990c71325a176e86e5326c599508e1cc4fe1e6cd62d991fd591111dbb553fef6f44cd11c122405b92c4eb814c91d9ab28cc49cc43570fd2cf1948b558209e74da1d221b3a4fef04b22dd4c0b200d7df252e1083e4418758e92017bf4e59be135b84a6ce14402d0731850115ddfe15af373ed3edc382393c38cbe579d28ef9dc7d9dc7a9514a4f84b7add3fe6a65d80e8ee9e084fae2eba4a3f26223fa94a1ab237d158da8b10c2109801be34d4b4de815996928c9bdfecffa52a432d054dd3efc775f264c682f27e309f6b45832f1797d393c77811564f5df892f82617b333ba5f1101817a8ca9937a64ad9044a28072f748ed94046b7d5d3e415e5958cca81c86f104faf5b85392f48579a082b8398029f82f17314cbb4a5c2b6316b5ddd9b2fa1520ef0619b3ba69b16d2143d5b46e829d3ab62d72c370345433446e98965c04011c3dd4b4d1079d868aa7c6f7a3b977b8201c5df17cf9783374199c2d629055dd03a3829e1e79ff41183a97c8ad42d283086015359015da9e0173ffa99d33f73bc1b62990124b3b6fc1f0d2eb45733079d25fcfeac076c648c7500ae14b4d15f4511825eed307a0da06e8ef7a294985b02ea50eb7c763782a712887ffc6bfac2ef3f1ee6e16ea92d70cda1f63a298cc9cd882db26b4870fca0c47d167f78d470cee95e03c76a589ad3d620fce2bae40857b24708cc5d7e3a62d2630870793d38643ab2011c2299e6b5dcf9ec0cb1270e8b276219a2b3cf7ce28a877fdd8cf6e758de1e49b13afa9096ab6a43b5fab52b12aba0aaae8e2afff23cbe63c2c1488f5213c7eeb46d9df443343c810e6d2645cbafc71ad920f13563a03345fed0335f838cf109a66feafd887c3410605f65f074511cb3e80eb456d344dcd4f79531802f64db35b3608fc5cbff5614eab43afb77326d7e0caa693b5969102562bb138fcabb89ca44c47c3ab42ebbec653aedd2f45d9e12a841dba293e5c4483509774d5daab33dc4f132a5c4dbdaa19af73c16137c16010996248d889280e5e1afb1a5c962f73fb797b8abcfaf505cf8e21699d2b80d310fbd3b053c1a25ab5ca288f49a6c4b672d6f3b83973681f51cd94bf8052fa6e5ccaaede64c2253bdec403c35e1f772b0c9ae00d99b35489904716cbcbb9a7dcb19b30bc3d236e8997ed3a49b6621046e1fe0681b89d3dd3208c519a4d2ec95d4493c465c3f4788e7cfe21ec561aa5a026b6846593b8eef6dcab4c04e5f34333a56c0dd65cc6c151900552f0332caf8961c89532838a61db0d5a2d129644ce64853baa0b390f3818f43df5333ed6c5c035844b8e1ad8c13f68727ed0e64e39df6520fa5852380fe063641847089ccf1ac32dec22b905b00793eb542e391eb3daa3919443be7379ccd59ba76892b27d8d47cd5ccfc6bbeb184c937e58662f0658b135a84ff45e98c14ee6f4f5f078778c93587dbdf00690db36428b49f83e0c16420a0b7444cb407e2e52c3718cf06803d3ace50e4f1cafd22c2b5d50bb4d13895bf8bb33e45d0017e142640ebafa5240e3768463dab2fcb76b34303c9f76a683e755f1ca001f5cfbd41a2ea3763213c298227ab6f6d64858ef688e1040bb6e4d621fed4b9a6aa7510feaeb79c970007aa29b1eae1f459a1b381ccd01a8ed09e5fcd8a3a63555a2dcbcacae0eab716803da8e2e018aa5a56120cdc85258588481a6db2fa8ac9d88dfd21f8ceb85c9ca22bff56147b8cf31dccb8720ee81f7ebab1306237992652a8674a15b969e61f1a9582f989b5bfbb98c46de614d429efa46cb1752fff04e91ecdbcbc5aee7b53938ff6d10bd8bc0b54fcdf09cee0ead24daae0288bced7fbc60a5cb8a249f0057d1a25143f408cd2782b6ba96e39c9529effb0eadc7b3f9cc3ff46c576e001b38fabe06ac3032b970caf1fd581f28d965b70a82ea3bb02108b003a856e7bddcbe3283c33fef8241c7b0bc2fc5738ea5e9d251b731ab2553e752ab656ef624572b77b03725241d6374b67719ef076d13f332a80fe5b0391ec95d2390ae70983e7fd3304d5b408d5c9f8c00f41b6ab9fc6889683342aea39ce80b33e5223073c3ee9b875f8888 +expected_result = pass +expected_shared_secret = cdca5387453ba0f0fe9f126702ada05c3612388b70185b6c2e69dbf98c2803ec + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +private_key = e0c2121f06048fbc565fdaa305202d439ab3a81b31fa257aa6f4273547c1465610ae51c2c1c8603aa36d1575754a86c9194b1cc6a9b8c9f77ce6484c5198a193ea4369293798943f7918142f849c8d7479eb0588e6e6b4abc4ce81a406642414eb4137c2da905ce4ad2b750e7d966d34a3b1bfa8ca5c8070456b1f6d5b71e582c9e1e2bf9dc37ab60a09e797a43f66b27b04c13c034fa6f594264c9d7da884c762b159d775f7750a1862216e8bc992c9b2e0d18513f409df8b0811ea89d2a69b66d34e59bc93f5c7bde25140a976a3195541ee22a7edfb7f9d647616b31399b6c924022f036225af7c34e6d221213ab5f7a20b908325835266da1b456f5649b895bb032142fc5c700cfac4c2a44cf1f96d57b8ba1ef2c9332a612e8bb9043559b5567090873d3f9450f37670b473a96f812ce1d71892e43c9fe61fa594601a27a98ec817dd822c625b98e0fa8f2d5a311a87a6c23b4dfdf44d7511373e64a4a18a833d654a946b0da9694329023086013a919971cc4c8a45916901b45c25c28eb6051600644660796935e65a4700496bc32204201d5c8708fdeccbfe949d1339947c6baabcc67ec901659d220fa4d1a3da1a4adc2b1b323bc4cabb6065d9032ccca3dd3c8689c9a35810bcb30b99b3f55cf2ac8258c5b85c696a372c7aab5b0dd62aba06804466fa4c22b2ca0e09b7d47c4644898aacf6899c79b5321110f010cd40253e40c5920db980a57c01b55c506a6662be1253ff171412820272613940704f63e70340414322b69b60b50bbb4459c1d6a0f25065da032455598edf678505f54b51713209565fc4812ad5f8a05a926340fc3853719146d049017475a09a1fd2d47b35371d715c455debb3a40a8a0e83247b6b8ffc05b2e857b5d8b201e56c109dc155b720b2528301c49237f7a629234231fba25c75d600bd360796a68991bc68cafb5b0b7c748ab7039d8c4fd1b3b4de76c193123e50109ba70956b9556f245ccd4330b888d43a84714e8cf17e5713b5ae5a9fc3a331718c227ef4bdce131f31028d68529f06a218ac32317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d790b0fa67cbcf36c0372c056c268e0c243132db5de7365310f5732151b80bc98a2bb76f9e8c616fb1c90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834ac0f2ac00e91b32e4e7aab452249d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c85823928877954c28d052a2c116bdc325b687d26d1ccb3386cac9bd4c10c3ac381e056f9060c89e25a910c78e677964d153b74554c8f38939f881543f820b6f11989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c5400cb1bbcffd2707be12c31acc9b5c94b806b71dafab1eaaa087efc1419cd2978ec1b973336d27b69af2fa85f6c33b73770c0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a3528de99cbd7a875bb5b299c8a6dfe416104a59aa9e958e3828d3c651b5a9a7e81d7738374692033c4c68254d5170204f83a9b8520016466fd9189efbacaa23ab8f962af7d66aec2e27e468b9c326711673839541262aadc49bc135edd11792dd9678da0991a017cd1239df3c9b21c57623362bbc1182ce6000217f6ab0eb9ad6344ac71aa30048b7bfac20ae1e97559109e45b5a9fd052594b4ce4c5c73fc105c9c8b63ccc7331b70662015b5e36057b4c71e4a510a55eb7fb039cfc9a8ca4b002a50966a158ba7d4d21449ab67dee747a7588b4a5b107e15a817658cd56927e84816c07ab3cd968c425a3431f65e25496fffe96e29214445eb2ac1e78a644305a9724761d0c51ac0c19b0b4839c94bc2fb5dae888e0b797506806c2fe27f1f4280427a34bef3643f022d05866bac17595906438c363c4d53422d994370b1c8d2084d25e101830a57be5c754196b75db44e84800281db3829d8a0fb519ae7c3c854650d09e232d993af718501f28c292b59c3f0d50d50d75bac422dbf23ccaee4466556a4cbbb8d60932016d63f90e4c84d12c62e4b0eb0176fe7012530b5baa8f531608241116c17868600bde858f9a9bd6078165bb34fd27273717b5cc5d423f19caa54ca4850ac896e163c70f9140432041857521a7c33d6425e068141b06c2ea57a010851a3b30ad021f6c0aa896e81f13f02d341faaba798a73a96d0b66b00bad5119a8d44797a1218b18224657573c9c556f5bc096f057f72fb749fe41fb9d290e76801b3712faadc58a1d3a8aaabbb996277d6902707a21ee099b5906854d2d45de78c1f134293d3dcced2296c5dd6b1469ac91c2508008951c7fc23eccb9a97f23501b21a625107a9c56ec39b724189ca111a935c3b58f262a29ff577f8459c74d9147dcb8eeb8689ee35aa131369cb805362289ae5973eff1420a8abacb650a1683104d2d82acbb28e54205404d68292f99c9c222bba8045769b73b890c33512c04af0cd86273234e31e94349a322aa13254484c3b99a2ac01f6ca00a77ba7b78711c73249eac054d34a1b0718814f407fd9d62a5d48212fb3afe5518e3a671bcf2cadcf4c8acb972603f960f194a4214cc8c9941fb31a6093a34c102ac18c26ba171a048d39860eec35e890149b9bbf510a4ff2270c72a507cd4a0500ba593841974c419a7ee37859a76f02463cb8303489e61ff21492afd03124368ae02c794642b7fe758f76219128ac75f19c41ab01adfa1a51b027c16e5b15279587e4f4a929f34ad51b06a060058521af6e4a24d54920a7e60c4174baec0b5fc4b498b23711c92bbba383556ea6169f558f5ad29443012c5b82524cec7ec43a448fe57d88c4ba220b56ebc2bf90a2471bc735e88c2e73a8771d669a1d76566ee80b78410d7cc02407091f4b6ac97cf2afbe67a02e445eb51389b8233080d42e74e20650a514f995395f8b23ece04e2a5930294b37c79aac8782ae62dc0d7fb60fff5c8d54e29fdda87562250a70038355a70d6bc0c3720726f0586acdc727d993988032cffcd5a9b909857be58c3b6a7c10041976a472d2bb7d3a0932a6c0cec9b68126b98b40d4041f5439f395cf6ea5213d39c69ac91b85696b009084e662aae8053df014720b5759c5f81b91f296bc4103c7dbbbb6248f87e8543e8a660bd6bbb9f81ad5721d7f36cfc776acbc8635e1910e4191730aa68e5e177d2d2234a645768d26cc069254daf0c94a09414a36a3d19ca05a5475378254ddb0890cab0e686438461a1d499aba23eb3dc2b61aa6a46c4afa2a262c6f09979f01fa1a98f62b8098be6416c6ca5b3f8ee79e28c07cbe2855bb64c88f67947a495e87f03361080cfa3c2aeb2791671729248b488278c72e85ba2dac1dd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb97e0274975323a7b20d27937f0c785152209060b05088243636039808c555ce29fd18a449a9a188afba922650f17102fb0a28381ec046164358e344fa250c05df6be895a5a0566b409f893e9d99cea7b3d71eac7a4d0081d951eb755cd39215c60c1a21de05217692bef3b8b4104608d198ab11c4c30941789919830cba4e7431dc127ac770957257c19eb80595ab9bb9d4a0ac266b7a37b94bc517139c904595c327f5c1430ac7d7e33bee0ba9c7bd7b266e290c3645821542f0e0a920fdb72707544a6d10c8a4c5a46148c2458b6c5ab06d42c2d7db03ceb0c00ca37303c67bae0038e0a373d539b918737116ed029a4d78a71d74f770ca53c9b4ecd19bfb172299c55a0cac83fcdc8c74400c5be76907679b48e0ac041987f96754588b83722b49159f92b41b82e6625a6108a957c34b2d0e30d536218acdc56a093ba9940c075362c1028c6ba42a775864bbbbabca70a5b7da5cf05821a9a81ad022784202362e587bce2a5b090530be4c51ef77a887af373637326f436c891304b72867dced161c2f0342f23aa15d69fa887652081a9c42b0669a689c5fa77649bab20eac8a16a51759ccd0f86c06c610a88162291e6cc1d911a88fa26e7ea4a23a224582807f20a8f1e2202a92495b6393036a25d4cd97fc72a741e006b7e919358f6ba3c5ab136823ceb955382bb6fe3f61b6228467f3c6f5de79531f11fe4f268b7f50f662c85a49b36a7213ae958a14e9bc45d0105ad13c591aaa7f1663301aaac45427da3c6a8873ba78e7c7473d41bd79534df8145d1749f94cc9c82377cb388129d0692f839942830c5814a8fca410e4cc754f7315fddc20fc1d588ac4c3cfe9c40277b3f6173809dc063f6813852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdeea5db7a82254d19c0a0c552ccc92db9c3eef74cd73a9937b7b7298171313f120e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = b9fe4bd50912df5228e9eae3f7d3cb113b2b3b80ea792ab437b9018fdefc174659f06d6d3ba49321e01685676d1306c2314f28aec295a9f136ec94b05dc6f333c886e02da664f0aad7877e84070f9e1ee2885c490630b69ca33a37e91b60f3a494242abd1cf1ff456315187279a08711c3f2c4a8b6718a031c2d1bce161bbec45ad8074996572d4bb2ca26197db8770243a0c6bc24e5c91504cee5618df95637f7cf913e062c12ce872c0ed43a38d4cd5f6389156ff1aef15e65287970f5963feb0e902f28f3e3ceee9cfde1140892dc69dd07b460dd8f3a9b41b34ffaada9a7ba82530cd5adc749d751d017c5e2a1a6802d955186ed07581cfff31825b5b5811542ff31ef774884d429249e4c0b66a9a35191922f302716d9cdb94bbf24692f23321a56e0797290fab5322b9156c7dc2e6e0fd9f20e320af281d7eb54f90e87b92ca5d9d7406bce4beb674db62b100a51340e93d5b47b533f66c68c2333dccb0e450ccfe02370ed5c4a377cefa3c2a69a0e48dd077e1b61d0a7af38349d0959d27510edb313ffa05a84d575f372e56f3e701dcbfc86214f5f66e7abd7a2c036e22e2521b6a0667ab623f160ded4d96f387b1a764758ab122b171c8b274e6294a6bab4cad72533e4356f3b578c05b0c5a7ee6e587d03b4c6e96f0b6e8c9c641144defa321600ba98ceee7ca29c1467d81a761438ae918f4161ae418969f2f30f8603f051b59ff636d6448be7fe4220caf2eec15dc671dc4e1d64eeac4b824f11536ae6fff0d66b49415da59dda35cbf2288dc6d5650b3685d02b81d12af0bb9ac5b1b34992c127b5062cd5a714a133583b3d9af35d4e6055b214f387485c59f8610d9ff7e9a548442229fa18f5b2e78dc2322c20023d886f32cb63a5cebd0f33c9877b3f7f19b8de870375ee386d2947a0c28b4f1e37e3cb39b5a9c9f3faae7c711bbd7432bc0ecb7b64dcc2203e8378be2b50a85333c6d2f14d89436ab3b7125e1e9392d6ee5f22a5789a49c7cea3731b513fa29e0879db8211c705d1f43a9f26559a95b30835bd26bd251fb9dc8259aab2f342f269773ba66317136f600e26bc39910f6a91858cd0afe36e5d7b54ff75a281d261deae9acd30e2882b0abd5513065aa58b5ca117d956967249154df5b8d5e2b2d458ae611014f633468981241731afe24d342dfbbf06419cf1e3129f5606336835c9501d67cf335bf5330a348b66d2470f68bd547d3a8aa7e7a4d560bbe20bf0be13babfd64c6277a772fc71eb085a26d4cdf9a0338c0640094b3c0b838d554a092b996d0eab4d6b27874a6b5b43f546f77eb93675e9abbf1daa2f4bbf76ea490148a261cf726ceeb3d9c586c92171124bfe6c5d33a6a0b7f95b09513d833fb9f47a0bf1dc822b38fb36c2e81967cd8d99266d8e62019ba0849c1d70340521025e6235012fb671b87a442ca3050c6b96283f1869854b5127ba4d8cffd336a866b9d4a6725404ca8acba96accadfc3d7b464398b67eea20b3721c769eb3a9127968dd0250e0e39f533482c306bea024c3ef0a840cdd50bc3dd57cb4c7770bb8a9e27f53b84d843a72224de499b641a2fc18b45acfd84c940ab189c3dbceccfc48f228038b095aadeecee2f805b1fb248a12c9d7ceeae2052a08c90565833dab3682511a057c420e7541f595e098b7c2724cd3bfb8979cf8d730a9c60e8a58a29ab64c414476d4c4496d393e6950e839bd9e8009f02b6c69538a0d35e619f321ca87f205aa2e5e417f7a6e55db244250e7ce3e5e4a9720156531b1d61526a712e8416fbc20a4ee2e7bbc97425dfbb4eb94bb9a0ff3f25f515dd017c4bb44550fa43aea7fd035e096d4e0056966b07fb4e2f4f40c612b5d25ab8c5bbc6d22f47d53a4964252de54bb4c973adb8cf4f0a6f2ce8d136109098ae90126d34460abd6ba895952e795b3bd5ddd4753179b21d6a54626c47d8abd4bf780177963961de0f915d0452c1a06febe965cac1d5ed0ad59ad52599a213d563defb30a4298b2d7f89e28208d141458739c719c18c9fab830f42c47ece180d458f4def3c878d7c9f16349a1a1ee157d4fc4bb005eaf1452c475c1e206ef7ffd87bc31a0b3b0486aa4e2b7129b9f69ff9f0252050a5a6cc1b1677f4544b640b911da9fc7c5b70077ba8cfadc0ed4558bf536608af410285d3da540899fe63139ad733f9d5d63d2c7730ca74f0051747d9ad4a8007a +expected_result = pass +expected_shared_secret = b15db77dc79f2d64e13445c4dfa997afb191e0bb2bbf6a210a5d64263b2408f5 + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +private_key = 25933617206ae881c4de291b4f269f2e51897ff29d3c6803e1a4c58e53051e879f1af333393c75b366cfe2e84cf9cc930d1928298897480571d7050751601bc119b1071412efe8873ad325bc00420d13a752d33087bb6f884628def98f4fd21d01113219203f93419875c91cd33c7976b7a45f510f70e6002957ac49b862cd35640ce84e6b989201a74eb76422f88b31c94acfa811605a32634199be1639a50b709e89683c5cb0c975d627b76223ea48a2352c8bcc254abc60812a6a5ab7747ca82073d1d31fef708866a9801ad067a6da0d848c409861c350db559a0ab1d91c9be0c149d6c241a13849d9eb2da4b9b9b30b348217491449a43ea4544467824ff954c4869c8dc0b2ba2744c8d38ba584cb78ea6f6188bcd090267ba46882f16964aa003e2c60105415f937cf13b9cd00456d3545bc5e48b6ddf61a14eccbac23bb1d071bb14361b4c9acb7b48805b7890c3676b550238391b388260cb0e2567f725b0382c7174440d82ba8a6d226d325cdd1c26abd510abb195b73d203f9db7db44abba87581a3c57f079b44a9455e3fa16ec87a0cc14368569b35517272220ba7760a8a0508bf0033031d42763fe89b611366b8b93d2d523d5c872bb99bbb099515a5911f1182404b7b4ccea91462c6a5abc16c64f55ab38a763a03ba48e0268819b6df8ba88704ab4c7bcd8f8a150ca434ab0632adc522a49c0e45997375d69901416792f845fcbc1a18789b22870401d6872374b15c851aba4c3cf5a8930d34c74fd444a2c87f90d9353cd77361e26c99c8027b50504bc5b3f2bc27f3978822113e13d71e19e3915a9a4f0646aef6d513e155b41237b2ab08bdf38322bf4c00706c0f22854d080bb8ecf58cc9b75d19a0185412a74b3c7d61a04dd8cb07bb37156c46221a7183beb9321c58a924048ab86032f54815da1bb33ad4312391c1a6778d9070b1a4542aae231aac97bb5e1a1cf42792c9921313c07aba3a8c15db5d1be417c3888a2e0921a7aa1926044ab865935a2738b4378484b44471da250e41925e976beeca9f93d191b0c85b487badfcec4be7c7683c508412e096ae888bafb97cebd3266ef7397004cc56741f53683034fc3160522e6bdabad190c51f31926aa94b2f2a4506d69705623e3047176b46169ab8a715b84848bb4fb9830be744cad7591dd8d128c1a40f8a5b2829a92177d73cb1f319c0f45557a69ad790c87a6b8314e618444081c221c07c4ba5c1c450b8080db278770a0c110dc386fb8411d4b983503964f7b6afa10ac5154ccea9e6222b4a70e5175f125b0a83010474311f8ef84fdf3aab6d508b313a93c29675abe12cde50bd4b5b7e13c7228d9ac9df569cc1bbc995eaacbc2290b0293a2bba70ae8757c5a7ce84386093e02b3201573c56bcc368a7dd404371453c38823ba4752edb663e5fb99c5e91ca9ba94caebc9d60a6318cf62168a86c0c419cad1bc4fe514a745bb2c81701b89ba371cc1f10b50d95086d99778383108dfed849a1f74696464aa1d67f7f40bbc69c1fd907696d6227cf20750d68a3d36c600448c91a523a16e5c84b40819bbb2bfabb2cb03b658fd0656f410752f52bfc9bba4a3a8d09d5835b1540f5dc673df71540f560d411b562f2b047e195e5c5baae8a93147c41d8f282128b8c455100865ca55516709ffb8f33d20eda56796324b6f3b249d982c7d49a84ff076be2187dd4a51efb5592f9549a27ea274959087d3c2a5e217ca3b73391505de8aa664288b95926ccd8028bb7a7c24562cf2ae14fbab852521978dd05bfb52885d8c86cdb6a8df1755f8ad12a7bd7b00b2a7bfa49693646653d1c50fe826cc9c39988e25d316975cac26108e5b9570979dea5843200c346e4c360e0b0f6ab71397999f4ab2f7af368d3218093d1c69853224f016fa11c408acc211858bc53c62ac6d395898b9a02eb0f80e5284031b39ad5409d9c28ee549d45712dcf080fc6bb5b08b526a615173f543b10baab4f9254ee7b7690c758d20861559c1fdff88c10a14eeeb2917fe47af7e63259c1154cdc4df1a56afec68855fca341451ba7f617e9595f009b0ddef81741d78bb2851c3bec505c070a8c9241e54b2a2f661b06323e62365a90e7b5d0d10704a184b1d5782967122d9864eedc852e592862dc868db21f70b83d3a482d0fb39b1e4b0c22871afffa785df48224d887a73cb9b9a68aa2a768b3ab087bd9cbf6253378885113bc6168d631121a5fad30cc822133161b0c39c0a2b30c5c33383555b415c6fb0588d16b3b890894026bb507d080f93e13327707a54725a3a859661e49184025f66f2eabc07c5072a21275440c9d520c9d0570cd4bf8752dfb37ca066ae450a3e5e6694b9581f6195b4b580fbf55b9f933c6f9867af36786fc8c24ca71b47127aa08798f99b113c1c661483a6ad196028b7752d9d4732622934a5b05c8b5095789999796039928b453e480f008a4bba7a49aa65462d71672450b56c441d2440fd4e151c9d0518d10534f24c1a355a5fe3aa1c4365493c7ad66f254300c373ac264b3339f3af02e2736b8023a270a20babe69cc15d494803bb515ec54719619bacac9ac2a58a4e67fe303ad9565b33c8472335710e0544c4a96bebdd98454058413db3bfc2958803a5963c725a4ca074ec9383dda1e892ac9e2210a60d19d5e4b3471f9519adb6bcb79c16742c07e933767ea4b20134ba8329c0c026da0e8a5e12770c8ba4ea7361bae91af0f953b47032da6640f202a8468a096bbe92cb8b02cd524b38a7a4c69d5b9818c8b88da78a7f2236746217a75a1f6e2805533a17996b7f972939a23c75c9023b715a714ac346f8102c2f8a04733495a4b456f179372202477e60b60ba210365274a393d999390628c7f63d2aa2b05cef68776db9150c39b6eca9ab32da9c6753208d74a2e7911af644a028d2c5a68494ea3da6b08a5b67d11090c587f580800e04c942445bfec357e33388a0bc328808624e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b350cb557bab3f87a05b22edb886812935402915e5ea51f41b70dea48aa2aab4f9f247d3f637efba51120a258cab867be231e67675ff29c83bf982e7b15b766a84cd9369ac28c29af664f5c7a7553ec9a0c3285caf26ce0b9c84d504ead34617f303f6d0ca807a7c0da1388f7407bc03c3111c8c87ee158e68b53ce8c668e8343b2303bcab6a4d98857c7070bb103c47c60cf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c38f028203357eb2a37967a60a95a1dd22b15f3d723f812890ffa105f1b9b2a238914f39975c1c0f49244e4db7728e15329f2ba8eca4cbe7b76029c9a6f721c72e27149807ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b37007fcf8486c6c5d0ffb3abed3cd8be0b87d1b2c80ab2d3e40949f94236e727b92e83a9ff0b40100b200b6519be545e893b60d09b881c2681d335f9f501b0910572645060bb8a141e910e6aa582f652ebaa79bf2f77b373459ce87c474213ef0257295abc192c05bf31ca3eb061648455fbf82710f8777636c229ef49c6986cba9816d11d636186b62d2b06212932e9e727954530182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968243289e1cc8460130c034b45660b3668863d719aa9c8e11df72084ae53c3b4d85a7860c42b2482c9a050b1065dda241b43ec996e368c6c7bcbab69a433040e56bcbd4f167a9d71c5d336234ba4a5e47a956459b4c0477b4780769530cb6c9b4a2cb6aa27423f76a58f89753196d8cd99107ec04741be761696c642cf6443bb72c5dbd336967c336672aeef98af9b203ee6f4096531034f890b1dd0862a0737777278167a2aead708533206b3624b906c57e4abc42bf61364e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f501104b9240cbc2c87b0531f6e008b38f1287be901af59a45ea19de5b2c4ce78ba4eb1abf4284ce0ea22f18c2a26f428bba481e54a1745702a8af06cab649bb5c7aed2342413157a811a35b162b6f444cf2ddb22a24bce8e2925d83313d0b760017b65b8867419c7a1f57cc785b26bbed63ec79b83feb60674e2497b87be24aa1f899ca59d6391c1f2ad9aa90806fb1c97dcbfe5b9934ba169386759532b1117115e77884623c84cfee522bc0735e1f34eaf4b452530418f652e6f15cc3cd88a52e98078424d486cccd38272a0819887d85811e6bf8dc3689a3112b1b86d77d2bd91a53d123a11b6eb4ce3a8471c35126c017053c8a8f46054bc9c92752631ab8a9100b04f79e14c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d21972998cc3abc79487ca0a4db5b17514e9961916d30ab9b500430ba748c5c7922650a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = de22f336102bed90db56dcf3c81080592ffed51e0d542b585cc15890ef83d4b2137d9a2c2c9d3b7a5008f13c9d9eaca44a97774491e0ec09f5fcc60f20ba8e727de47eb93bcc9c62c412c3f816015d39d052ce030da88e95975285220762837bd725eb1a5dc89986d74de1315a7f52d8bc763eea041d441c2629714560ab6505e7538a444291b61350e5898ba0d08cd82b2f7a15cb0c7961efd3e195a050619e6af964b2b27f55632474d257c7f00bc360a11187eef5fe21eef35b00964bf760693f179d9c086a21899b2f9c840dce611b4cc27ea2b1822efe7ee9ab30c822cbe90e37f7fec7b4dfb50ed0c6dc187fa3a9343e6c0fa0b6e6c6ac80d92e995999cdd5eaff5aac21dcfb45d195ac9d4e1c53696346a762d8a013550a882ef8f56b0894c3ee66a3ae4d0ba94f1c6eb276880172272ee958f44378ba23c461a7d79f5984364e1663ec4d403efabfc9dbb617c7c350ba5de146316b45b5f4bf06dbd3f6cb4ce48dae4025920cbf638cced37d9e7df698d1736ddcef51ea6dd0fbd9431aece193199a3911faa4f4585b88ae0a68f3d59f68766cff57dcc8cfc2b5da676af40555125c8b99ce911b41d1d44ac4b09aa5ef235f1c72e10c134ad457fb735db7202496807000fe76ca7221c72255d82fd538290d092fc518eaf0dc63d4079aab51fcd2306501decabad9d54b2b6313fe4d1e8585d55eb52523ca1451fa5151bc378637bb129e59cf8fa7192048672824a90d7e53b324df2d1cced582e003df5de8a51c1c7e14c63a83c2fd17a65c92d3be640751decba18aed1a47483c602b5f9a136c2a47c39837a84d3cd4e30e2d38b7599f62b2218a0ecff2159904d27d8cea620d873d00a96714699936ed0d1b3307c8b987d199de13622d51fc3342ab58c025ffb19cf90b42981cc86174bf6bebc8777f6c66da5b2ac85c778c6e47bb7bd60be9e17a7d7a3377143c36c876a15d115ed1f26353ee1bdfaa870dcffabb7a9ef8fe01067f93a681314e1ec0c8683e237433053d89879042f28bc41e7963d7b24076c40125aa65ff080a41d52b4059b6f01bd6b5583be37ddca124ecb8d7d68446acd30c2cfa9e696ff1ab4c0b16c86d4dc391e5c081d8b982e14c8ef163688591fdafe9554e45d286378a8ab2240ee550241efd0cb058edd0b4c861ffa751d0b69335f57a4bcd180a5119a3b76286179e04ac93ccfc1aa36d0b83320f9dce518802f5e7f4bf29a79ba3671bdb130ec01132b9fa24a2e8ab5058a7f790813ed175fe183c7c5393594488fffa734fbb154041bb569ccc2b81a5926f522ed4fafa4eb35643fa2c2abcb1e6559da7938714cdeced33b0ca4197f00b6b0cf9bce07e4138a1563e78959ad985776ef5af16bd0119f20635f6e6706a116d82a4bf1ea8dab7d3c47fa5699db9b4b006d4a2411f64645937df678e4acddb1caa089b1b0dd497da2fd4e2cb7eee47be2bd595b1dfb1f3fa0032200db31d7b49d7cb5b738e61e3e8824543548802342ffaadd4d21af36f65640bb1b42f2cac9063d05b334470f996fb13d0195ca47c675004eeffbe95aac706b27ad74d1e741e4a12ded0b4b1ffba5c09d3d9a3dab9a21e55fed670cd408c30516812e1729db8b5262e2fecfd91df70392733ea049d18aea68a02086d76f62b5427d07c40100ac75f766f4e2eaa32fcc7ff27d7fc9a526835ea0bb1a5483c1429e1e4ce370287173fcb0ceb8209c2496581d4e2ed15034723ee57ebc6a1f211a6fcb35e56f9348c2b83ddec9a008364da2b9ec95024a8f9be28f551509728d65b1ca1e77d36e9e1ff47f5a98eb569bd7deccc3263cddf76e2ca2b2019334fc06db81e82a3174aa8930eec28339ca30e5cb6529ffea5d0a1737083d9df4253baab48bbb8523afaff1f7c3ab8b071248cd888e65e92c89799a7e27464024c2f7d94755234001dd8749e913e91fab6ae3a3de7244126edb48ab1a85a21d3c19e55d54d468911c46438900844a6a50a9f28992b43b8283a02276c8dd4a6266f476ac7537afc03b6264f9bf39b8f9a922c85a890cedb11aa22344a7e17a7da87d156c26bc309c24fc3174899f9e283172048bffc8b1f1e1aecc2ca1976cbf83d482fa3cd4c511b73e3c45a66eed5db3fc1c9ad2ddbfc63324dd2a4a6350e02614d2cfa96429f6d7b703f4452d372fa53bb8304527b3edbef7c13cc91d44793a4e87ec7a034f657c6548526 +expected_result = pass +expected_shared_secret = 8ca9424860c35214636855849bb039cdcb4c722c5b81ce18ac1a1090034dafc1 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +private_key = 719950ed1960ff6c2d7d59bbecb83aabe1ccb569b76cd9b053389c552cb6bf847cf4fc1f18a03e66f02cdb284c15d656151644f78caeeafa8b12cb7c616256c032ce6112735a74285d66a90f3a745ed8733c195f6b1b9b272897520a02fafcb958a9669990b73420bcce373acf5a1c86a555c3c48f78166c0fbb023c49608592261060884b408c9fdb1f4b023506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa32c01ab64a6ab7491d50303b4e8a134086110d220462395b9d89d9651205aea9e1b88bc80c4c8bac44af4f1886ea788a0b259dda78116051059853d2cd073ed8cadad9ab04f7175d57c3224e953509588e788713d5a6714d0aa48e972f4fa55f16579d9bc6988f562ccf1286e87aa785929bf8266d7e340022c0221736c3cb372b85723042382092545a45032eb727bdc750449c786145acf42b85d4618b0d6f009d0224a816620f1db67f59713090b0849559a51b9589532ce2dc25df8f09aebda932073a2ac2115b12c5f94c64750220d645b34c14ac1b2208565377d61426d7f2a25cbd969a2705ea330b676ea6eefcbbc6cd40da9c0716d147b398b7d469a919d83baacca80f0e41414382804b0a321362e14e766db2450f599963cc2899e1048d839754858910d12c23f99158a9a3149362690a9c5540133e5f217a7b66b0d627321c810f7d1639cca948d708616047f85ba41cee9211df72731ac0986d1c3149854b71683faf68179799b12c031a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c048359481ca7a45cbaecbcf34407d8e378733f812926599df5c156a94945fc7911db26bef17074470a7bd6b60f771cc3f396e847195ce26444b641f91b468fa1670d0184942472667aa76e42976fac48e78da72ef0c207fc7400f92699b46345e4c9972a35daea31adbe87980438de4f211b005c8dcec1a6eecb56d891677f9006c49385e8ab20a19b74325a9a95083bc711537480db30719815352616b2c5721979bd4267fb134188a75b9cb303215a76a246d8f69acbd173d069b2b99b727829aa5469a0212c006a88aa4a6b614674674fa75500aa294711c178b741b0275280bda27813647a5dcac3a258991db4bf436c23f37c697115143a2755fdc199ff32b19209d7ff904feaabff7383884c1bae3c0cc20d019066653b99c1cafe366567c9238785b0f0b4d1432a9e02ca2d9a3b37d84646b157684d7ac720727af4533749a9ff99bad8f3877dbe5cff9c75b38c4002178ce30773ee36a14f1497ab386cb36420f04d85c8312ce25b357d3108226925f6b85c7a3729064f81aa66336163c00506bbfc82030f4f33a5be7330926bb3f849d1dcb09f5cb814ba8a722506d0a037e6eb26216aa3c4d4c05d5cbcf0358501936ad2beb3563c341e2315de6d68404acab0149bafa84491ab67a2dd82972220b0df528da7c4d441c8cdaf508cfa2c0224932e7e5215572aa433c9212022899e43a93cc7c8f4aac6ed5acbd0162e4da4b897b7bdcd72a0b2a2354f61a6c211089c11e476715f3369859c3021584b6593b5784344d53b40da0725a90804c45d02f6eb7670071660478c53281b5e290bfc77ac46602b530b1300628a7a4f20ce22768edd699c6bc5dbdf66064041e42329605e06dcb94207211c7bef41eb150aeccc90725dccc33eb762a92442dc02ae1555cf726a915240508e227e270a4932636a2806d8a5c15a40a3206ac91bc8a3cc7245f7b5b0438fb3dcfd112dff7bb01120087e09abf5580081008d43bb862f6283726992523acb1dc82fc260e64dc395c778d8ea7561382c9918b531cb8b0fc8b7a5a9634d3a7349475a8a117b0c2331ca0b7cc8e5a92f609b5b558435e15509fd78ba747be495b9e78ab178b03c117d4c679d13d5b07b58eb675a72a646763a9358b61ee31b1156866cfd7ab6e7498d3e5ca92799fda467dbd103a5e717e0f6b92a815546f8c221fb2c337e86142d8ae205594bb2c93e50b4503c80b5ab3a19de4ba63d918343260b5692296cb02efa77ead006bcb99013e317b5ed802e8e5209d87c7e584c1de051ada436044caafd0033f51f649d275a7bbe4455ce8035a97945f597d03a1740dc576f0225b8cac3ea76c49f5d6a183f3853138becb6949a158a5ec045512b74016fb841c8881035448319442d0786cba94aa139895eba98bff419a6b42644b68c5ce534b0f705225f4a7b28cbaf879b30fb633fdc2aa70c54639f180e76b927ca4622f086601a62afff5335ffbbbcb52075ab7681a55625e01cb31248e17708b7d728905b64976409d49583272fb6208e06ed7539fc4f87b1f0b821de4155b79531546824bb4a13e09cadf66b7889c6baa9679df6187690c9fea246226a7a405b997c322b4ab041d7fc0b24ab54400813a29c87204ea29414a7c80ac65d374998494b914467f44241251402adfa34616b021caf86b2adc690267a41c40b763c11506b658132c59c0e887888a2d5a8658bbe403758c84cf86611026a5bf802ae4e5031771c42d047ef42021a7c59c2c0a6e3f10b9adf716bba29d824b271d787379021ec44b4b39c3493bd980bfcbba73e5772e259ccdac1f062a887cf25887c30817da33ac19c2527239e7f6b434f0affd278130b1a480348aef2998924c684e3ca8f49694dfe149152b332128061c659cf2c5861ca003d1e8bf33dc06b197abfe2862362a9a15fb35f6009481d2a79eb18826581abcba4bbba6846238c5edf5b30d6830437714addb5f6751a7f6d79558148c0db07a7b2a784dc78c8176a2a36b4dbb7855602742ec2624d6c6c589c515b5224ebf92cd70b954c5190e4212a0542857a16cbffe060f56140e4f3b2e03b86ab0c8cdee1a3e2e95cb43c852c40b6cce660fe61bc7631a849ea28e6c93203bd55c4c4928d6ca777023264d2b2f96f99f3bc9b23d51ceadc713572542eb00b77ce79b2f0ac533198a60f03939ea1502e09807b5a7c19ba98396167b116c88e889b022195b016c58125de60708890793bc582717253b6608b0933b0b0d160c42bc3efb602e899555265189dc376b15c04cf5348753344f0e8349b4ea29a6b85110f81c247029ffe93ec5891194963bd9aca2ef5a3e912c255e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d4331ad5a30da5a57636e75f4900285b927289e7ba510216e73189b6d76db21c600e8c26488449041529700539c42195624bbdf1c19eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a645862416fbc92df042baba25ff1381f3c09b79e2c89410625462018ed38a8480afac4a313da239ba44090a7aa296c304dae24030db60bd376ecb7779f2f2414d144e624a9b0d2bc181268229ac1f92929d61c15250730d58b75e663a2a175b4b98a906c3871f1f9a46f0e842c7b48238722124e7c2882b7831576a03b1ca105333e4b004bf286e45d3a9188757faac58e8d995e7101129fc560c9021ba159d748619204b7963f957e7410592028f97d297e2a8042bb8b342f1cf1af6a843a1598b1a0e851cbe6452842762109eac773cf58fbcd5845545485eb47be86bb51522273bb7782223b855c221de3c3ce3290c3fb4c9dee73e23c06994fcb437a93ab885230ce5521f8224521a6ce6c5ac8f682353ec78f22cb133c1c48aca73a461aa128b96590b2b508832f9a04a1099b7775101fc349b6a686b9cc3c7954567f1c605ce1543a6e967857a19678b5e6a3b996fea65336794d36c3045a0ac514962c79a6b03342b2ef826b4e4a2aa4b8e2d66ac920557915058c551b82bc0134dc489d55742b59c143b88ac8903cf6ca8aec2c784c1dc15e3b46ea8d7bcd43ba3161564b6510459f7956949128d6373c1ea8b41b92396d124b3b978325b1d21c290b76a1504a01adb164b3a6cb9bf5422a6b571f209a4f18c31c3a647d8e3cfd335067c75308026c40c5ba20dca0317cc6954341758274330f35df38abb5f1b59806a831979bc985576ae6a8df2608d6305ae2f7406f347cff1415de856b859d8306271c716495ec273a2c96355e195326883c4f024943f54c35f0003e70c9dd5c412f6c260f18a6adf1435150abdf28084cdb13685881aab0c710fec5272417731a65eb9360684e170f6c7a13310686471b0e91b2002b789a5a465128043ce6b7c29bb5dba20200dfc69d242823e477e34e146c828022d78c37b8c8fea50294586cda2f728d9b10d0cb58e1b091b68dcca95e6ad22416e1c9a7b0a75047c72309a284426fa98b3c905f1491a44d1338e0cad6bf2ac3c845005c268eda736b1c997a64438323501b6ac5628455694573afd782ccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545ebe9631b6d4237dd6884ae3647dd8622fc13d1cc689f3c8ed94ec6bcd4bbdb6980f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 4f1b2fe882e53704f5883b1b8613c9d4a17f72b1500612c398b4715a1d43ad79c00f69c66e8c7afdac439207f66d163d40bfbfd7d96ee8ba5fa98b009d1dc306453eb1cecdca7eeed84a08fd29ae9d9b9d47f76f5428abc46b9ed9845b2685cec51559f0496bb1b0161b024633f05bf6ffd3455ca80f750aabd5c0d2bc3ed18d95b605c404d61074021f7c11ae279027ff48dbb89403f5eea50924a99a5f5a2ecba792b55842416a2dc21512ec75d7b8ae8f4c865b8ded35ff017658a57edceb87ddd9ca4b7df56aec4bd8ea02ca467e52c506273974f130b1e55f7250dd21c7c42f237753f5ec7f533c41b27206b3771189c85fe9d0184072a8d0b81e6f98fb8b4b4de9de9427c1fe368ad0e85c8acbd3c31ec17c3a071ca06a3bfb5df86b20d2eb3bc3f5adbd452d11e604f76395301f8e7b7ad5e884ac90ca7ecdd65363790b9b0e72616ae60d1b7153a891eb95de5ba6a4ba6789a03e20f1ce0be511d7c7c394202324ae0fc429d7a3dc27ac35cef64c01ee6fdde76c0ba59b03fafb57ed3ff38c26bfc095ea62cfaaa9e8dcb22bd26e779c0231e3332fbc0e5b24f06e63c74525bc14a6c4bfd72f6d8ee252fca1d8264e7a2f60079a3aa68a6ee11ab35a9c80e0203c01d62913edc91d3228107c95f2fb147612d974e6811c5fa307cb6617f0ddc5ac910577beff3fde9a7d082db41fe52f105cf338173717a73661da1e850c607c1e9aa9734d6ca90ef855879dbe535f9b144678eb7a78fd1a7d7e49f174782bc17925258a84d8fac64f74e58005d5a1931e9ebe55f2e9e4790b7d7a0b5d5bd687477c279e15dfba7eb38a928fec671a1f3cf5316458162f92c2df26bca3d98dd5d806e22d5fbf61d84e7b6e9a06e6edf5b01868f09bb13f921cbd8c70d1a6257f96e3b147802a5e995c20873f4d8c99ec7ba76d1885130a5df0deafe0461dbaa7d398286f18bc5abfd2fe03daae5ad101f16af01dc22a64b6b1210b55fd3269309d4bbea97d136db04ff04bf3095c053122ae29959bc3f157dcffad37fa6a6146cfec799f225bb576927bb6a291b9e52dfeeb6180f61d61567a764a3427c105f53c615d18b5b5a3f29943aa9226f890247560c6b14d830de714e041237e2b515ee275caab6383e8deb5bd417073ea524a49e485282f58aaac69999b63ba5436d5632311be74981f58bdc1b0f87b2474b1876a10e5d1add2a3b11c1202c439964ae85589c881d7c81899d1dc2efd50fad84e729a5ab4e6342a6749f44f277e52f83fda0411142c0eca549c5dcd85da7838a64eecb0e06f4a199637beae0ea839eb151d35a36d8902c357f02f61c1ee52387de35605509564ffe882df8193cfc15ec582564a4c824c069be5faae6d5ca3e4a91b242bebc52c6c6d98d8154472599a0e7c8cd9aeadb17b8dfe0b3a8562487d1f47cf87d4c4c4001199c7d192307c9a44dca16f7a4c8ff29b639f1be6839b48a51c3148304c15e68cbbb6225d9c3139544307a59120ce7e3c4451486b445baf6a31003a81bff820bea80cf66593919864452e9739d3e33fb354def95268c0f377bf49bb319457db78b1c73465b4cd8915b7453f39fe15c95c981a831d6b45032d05b2a14ef8787dde3ad7aa8eb0b37195465451c672d4c0a0d87905fec449600082b85638884488570932d28e7bac4086b787137dcde64676aadb80dd440e0953b67b7f5a369984a8cb473af2ae567b1c1aad0a2dce06fea6345155c084880a96e093f8e394c6d16c9eeafae80d1ff2d8f94f6ee77de3ed56e9146292113949f31f4f60a6483bd5c4b51d507d1c01d7ab7eafcccc0ae64409587e2fb2866cdfe94c3dcb047faa437c7fa7036351f59849fb4fb98cab19feab17ea32d3e8a7b1b0ec93be3d73040bc090931c6b40bc5e8b64e6768944306186f1d309ec0a950ded03a887373e201c0498ea5ee4d03adc2f0c00fcaf4fb487b1a4965667d263ec958a02edaa992e7bc5421044c44374db93eb1e7e0db56d79bfd97eb676c3c17fd652b4daa788ed71b3d96cf774b3fb4d5bf5ca2da108695abbbab29657e6cbe7c100198d076d8030282e63758cdbe521b60b8651c7ea370b5dedab33c659b60d9634e19dd20b5f387d9764284e28e35efbb7c419efe1bbad9a7bba3a36c8fea83c050da25334e5f3fa8140dcff62d89abf966cf9420f5d1b309566a797904c2923ad126793d65a1eedae40ef +expected_result = pass +expected_shared_secret = b056e2904d66c51dc817acf961f141c2de7d201ca8e52d19564d0fb4e1310aa9 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +private_key = 4da026f053c3ec1712c7f294dc891e26196894a1b620f97429574edee9568e113feb564d89a1883d5a0329929ca57ac001925c8d616791842dcd291627d61c7c2c3f842b547f074f46f082a06bb4282323a291c3cc07904079125cd5a854168d83ba8ab6b160b5e1881d25403b297c73048e3298287f51529a8ba2deda6b4d7665a373171b03b1c0baab6482c50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2ac0cc80c9d248b97ddc51d00a10ca3324fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48faa514319b8f9a0491f9212da443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995ef2aff817907de5c66899824889a760ca4a38a57b3afa880a3524e138b37487b2ee7332d2689f99a5a3748020fbca43ed6045a5aba65f6c67783cb74c217ba987ad381938b4a651b6908fa4f18e6d073a6992160438ba3c9547e4557e1e724192414c912648d25907bd8b069c845465616969161c483927f5d610c815638e242323465839d36a8149bad494b71f1336a3f0a954369d4265b6cab935f06694c482b500cb77bb32c4d805a295a692648a31611b206d06c2e86c61675577053a747bd3a748f452b480028edcbeca8a10eb843ea8a71e21e9b822d80860764d8c5a77ef0222f8004c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe59027fb424e6c580cc3b41c041984ea552bdd6396d52867887430a2534a44ba544a0b285c061d7d6618c76945a5c3b29bbbb09a724b1ac53e5954f66708c8c0b2d7da57c62fc8b80e73d737741f9141f7164b4eac08822a4c340b5b74cb5c2d407b9d63365c55c14c5e6ab43a8bc68908c34074a9bf4816e000ddb464656c379fdd829b6961c22e5345674243ca64705212d52e616664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1af828bb26263a8a898bf3b7b0ed07988e82dbe3c0405d46b1cdc37600570fc37ad9b2237e3032bab1a0ae420b6f011a653987305aacc8876ac4d014b7e619227b8b35ba2616c9575506870fad2585549a2f902b185d7a61139c027912ee2a00ee460328b16cceeb259149a0881f8152d563bc0243302d29fb98cc57a45369517640bf0bf63a555a900269878c4ba567f8d376176d6941d34957e1373b7520483394c3606089d14aee0917059227bd848bb22e088def4194bfcb36eaa81d4da713e37be79e52f51ba2c32f05d06405947838625e49f5f6bcda5e683d014a12fcc0c81601b52f80c39b6659606a8fea82c62e061a939cb4451869922083268561e16381b026152170104e11f30b2399f4097b94078adc66f23f85ba6651e861237700bcb1ae92e2bc652cbf19bc0fca0d7f7577c9c96dbc9b8b07b917f258c15661da17621db1287ebaa7714a54052fa660f034f227198ea14c2467b46cf9877f4e0c29962992b560a7db93c8ec13343f734d86bc548246a57473d1285463d0942f288245d933ddab7a09766a9f8c178ef539f9ce9a0e97364cac0366b5b08b4c1b081e01d198c2aa5288617a50019eb3a40a300af538119d733f2544d18b9094f387a3f4c17baf01523f1453f68a916436c8e6a80cd05472de7239ae15dbd52144a9609c1017e88c1a3fb301323b060242ac803133c9bc50f67c436de804e7e7b54a3489e5dec22c83a982b45160108535ea7b588018b0d3b0ccbb613a0716eaed8b61912073cf728c747bfc79741616750b8373235408aeca1abf7e09e72cb181bb09e8c31010e3ccd05db0f487c8a29c4c822c59cf447124c973f57392865ea82af9a15382bb68a708a6ce92e24484eaa252f97635e60d4bcbc8a403dfa166fe5c6a8500332624122a15e25d5041de8b88ee92e1b1b0762734e63ac80ce9227c43980d8bcadfe4caa420045b26173b6b953e3c97c7f655244d534b2963fabd264a33466dd79440f4361c8c77f1afa0a8f31c183a369993494480cbf7d13308bd58e78d88a53d45044026c7b620e0e8a7124b957f106aee02598ee190bdc68c53af48ebc5436adf0bf66227f2089aa4cf461f2d7bb990c3e530872c9d157a839a15b4ace0b2895fdda50d3caa18ee60fa11325946a689e96b651c6a9b4a41d0e83238d52990b5520f21c268ba428266b1dbf30553a10aa6c5118f85ab9daec1c521639b686bfc4b198c511939a039982cc774aa074d391bc5137419a22892005114f3132f22497ebc5316e190013325b2c0c1f23ac61ebf6875640c7f56c78df4937c883bc9da38d1f709a6df68026d8af0ba51f1f2c5ff0806cac1a396a7272a4065660906658a25c570c7067d1972417142b0b6bc244b8e52b1b7a4b915832486f8a7486230cc63a981b195431448671e71c38527effb2768ce1574baa6a23226563794e714c1c7f75c05fc4b2630a47ae24b2a1d3141516941d61a58b609808612064881347b4765e892438eaaf1c538e0baca4e6e1bb38821633a385b7c1cd285b6edef2739a675110387e6ec747016a6a1007c87949368d31cb7a63a50e210ce168c825b86695223fc1b8789bdc89545a3394f9c1bd943094546f640b0b129c4e78a9ca0b8107bb18923ce669da26268d57c7eee01f15d0454cb1cb7af05f2e787833bcc4d4996312c82714043907b30a8d250ece8aade970cbe463494e759f463131c12b636503c747f64249d2687b3301387620307503d9562e5a033d86eb23546b83b0f70937fc6b70db7c1d519fe1ca0b93137a41d89843a635fb5c389d420558746be267440e8aa996124ff97b163eb828fe492e96a367ee7c22e2f4031c44688935b0e6439776e34c2c525a31664386a5b6040116d487846f538e0da71fb17a750d4b0b8f4c37ba859810a8aa15b573eb029c8f7052124bcefbc48dc60743e7a455a0c4cfb7c57847c50afb1b5725d735d013441f7b1b43d93840cc4373dbaaa71035ae110955d9cb60ba5b5de5999b082335ebc1d3d5b6a6681e2e4714423b50d30aac28a4006869a85941247f0a8f8da236421b761315b6adacc513f5ae525373cc57482dfb15286546d106925adbc71f4cc1bd33641cf63035b7c02669ced392b0b8c70e776a768f859c04e3b1c1f05d9a909025f075bc0021b091b0bd29ae7e7c787a0a570cb99f9337986d714595023b53147913b72f7df50b6421319825304af61ee75765f44581eb0378ecc979f81950437ba7603b751dbcaf1261a17346cdf645a65cea895320211089a07101bf617b731e38a8114335e3267169d060a9c09e7e829d0168a21bc580087554a17688cd742ef7e4a2510779b666a2b613bf81d8060e06385398babcf2ce1ae7abd2e66ac06142a2f73598ca2a1ff769923a0aabcc22268710c0a2143b96269bbace0f69a25142bb9f1a0c05266003f7a69ab405dcbb3360290ba355c8c6f5b1035697865cbecf8a20209019ea08b6416c86a098af524a2dcb9b7d16253960670ea96897b406c5680b14de691fa5305405f35048865e549c3847b3bf01856a15a25dac28c5afcb6be3e8adaf3689a0e5bb056b000a1308ac643ccd94c28711acc4653b52cc87c7d6bde2dbac47678ddf7101484379de232cae6975b4ec02d6a043ae14a53632ab428666fcd98b9f702432018e783ba3c7d32079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4baf2a4083a91e3d58e89270ef4560669d555fb0444737c6dae111cd1e18f55f1780ca0bb8e7c1ac3e7168d0c9e4a515ca4f11c49c967bd78149af3abc3e692c4659b30851eb86ab41d575021fb146d60069d242569d111e510b731724e6eb456c5428754db8903f31b365c7aa9976c13210438b50ea3e778e5a60e25f85c42bb10b24b72bc820300c91547582fee167eff958894e4898c198a4f652f871c9b03234f98e7a237778c679b757db3225394a356991b2810cc6ca5c7ab888dc9e59529f3498ec40efc47051c03c75225187da36d3daa9f3f0977da80a14a13a990ab20dd415c2036003ffab31b7aa534ec7cddc40a9877ad6cc61d07b7b1d8b71db1d1a2b71923337532e464853357400aca0f6a883ed84b56e77b755594b7bef178115b18c68175dc2c390d462ab641ba14d80b1d36cf290c6afa532d8d7091da94703cfb7334d667f0e3150b60ae8bfcb56dd40e3a58bd4d09a5a3e8a167841118a51490a126d6b85ee90a7f3d5432f59635b1d5587821818afb74ce42569751512c9840f364b6370cb318c1677a304be1a2938234b56bd2632f768a93750158e844df96c720007228c2829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd847db13de94d97a88d5a3deae31c246f5f04d0c7d7f337859e024764337a08f25a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 8bfde9f50edc17447a32142caa59ccd778ad4fac7180926a6851c4236c118ca5a1af677ff00112e34a515791a02058ac7a784408a93e2e475a13d42ece94315e4495ee134aacc0e657de7864bc4f0aebbd4707e4b18000a10c94ce75ea91cfa9fdd629c29ff02a3b35c08b69f1600c094df1f87f8cb6714611c61559ca83ff20048fd2fb43bbffbb9c996302cd08fc36c56bc7da84b85a98b4a6fa7f4a4d1ebe4bb89a2f2944fe681743015f1b6c78f93221d08ad12d1220774d737df2ae3791bcbca602b724c27f57c90802b6ce86b374c582247f0ddca21f9c23f97192058869a433cf31ac318231e6c664645d66e18b0dd0fb548a3b85186699f43f9f4a2a15c9517e3ae66585922f844f09cbed5be15786f15061e4b5781934df2b317ebc9425872269ff5dd42bda30f3aa232f788eb78138d09b83e0609a5a0d3a1b22a37409ed21489545638194a81972f4667a4e1ebb517dcbfb607043b9a8658bd41a960301ad29c3c94797d2f0598f42394f57b40aab2bdd3aa0b156967a03d597359c187dd715e5d8290895f3f47273027b1f81fb3dcf992331ace69ead7d83502e569015d11533d704a5813cc88f74d39ee7d2ae492593c7d69d29899ed23ae6b5a7d2dc4c28dd8c6971a52cd6692b03409f1328738bfb1c1a8304229f46b02c1bb70aa23f0f9a6087bcc0c948ba291e63f56b306cd48e8a45352ec1f4e1125be5dca924231d8e8b6a7ba1d14d44d7b43eff0e6ce8c86061a27b84ee8a018d4accd3f2ac03f36f5b466e5f914f7eeda28f65d13a7ac5ea6718b4687875ebda9d67c9eb4634834f6bf4a145d9dedc96a3b118b026bd44b473e8839f86405982f33c70b21fae5e2824af14d610da2ce00cdb72f15f2ba3bbdbec777fa17c83a7293da0be926ef828e7e15c71efb579e72ed088a7408bd4034cb02511a44f6352cb44c7800279ae408c05ba7c9de63a5d16668e956771d580d5c4cc637ebdaa4d92c75fd3fda04c09882949ac85dc0356f210a538bc666c75a89c067cbc5ee5f7542712805be7147103acb203c8f99a5fcfb8ef874b6dd815e8b74e508a1fee87020d1a68b28358153d7b344918b5691ccc46d614b7606c2aefeeb623c4f367b7450a9fc6cb3ceb45139996d39e7afafc80c39ede56777f0e6c9bfae67a89db0aa2abb0a7d4cc24b6ca6e5da624c9f3a01cfb5e7039d5064245fad0c2273f7a33694b5be46adfae5afb1c05b93d7477e22cb2128b3312cf5c878953f8d4c4750e183849da2dab24c222a8173e6c1dec334532bd65bc0557fe85894abaef701cb660173dc1a02c64538b48bcb5f9d9ca5acbc53202faaf96f1d8281bc55788f72e64b99482fcb17c6315a9e48b661adeeecfe7339bcb709d70248e7daccaf9faef94bf769d26c4ecb231426c131fdf3ad9b744580508ed04b26508727def4e0e2003c0737bcfe26eafda4d8f261ab1dced0c88d08966b5a573e5efef88e1d332e1994c57783f189b16f99926035764db0f7d704300cf6ef23881abaa531a9902b03a3689207a80dc3f496e38e4a1560e6b0e71a93ff595e5c595e7e2cdf8e41e0a26dd24f850d6633f5ae45e0a694406e28b8fba10b7db3b710980de3f35f2aafaca276f59d7c3953d3dcdd82090fd988485a3373a7747884fc7e0dcb4c81018982fd3680a492aa40e1380f212c09e41ffe1a8952e6af7a9025bd2c3f385207f65c13b73ff15b062f0707c0c66baea4647019a0a16e24c21854e8d207dc99f3e58468f954a797cc672cbe2f3c898d0bc894fbb642ba3929232a00013570aa97b219e582058a3f4df92feab5c2ce14b2887a3bdfa4c63c93d7b476dadfc7e61aa156c523a87d7b1b38c99ea84ed417ccde7d1a5bde2524c118c9e3a491538e5b979529bd5e3d370e9208823aa0dd4f814e133553921945386b2a8d6c8847a94ecb8313bd51978c7ca65f7d52a0d8a1deba338b3aa9bf31755f68e19f11b7c19ea4f8c02fdc6974187c35d5f442aaa91a88f2b0b8a19febe41ce52898e616e5a016995419b7e1aae8e48794e5e245d0ef013e737ba64bd487f06ffd25536588cdde82bf10c26c1154e96b4f8bd83696f5d41e00bc6cd8d6073a1d98884c0e411d11e33e8a3f76a061562c1040a79127741b614b0a68d391c8d843df2e44136eec02186fe637cda6fe2c3abf3d821e9409ec5f4c17f76c8d4da5131ece03c095af052ace7 +expected_result = pass +expected_shared_secret = 663bcd21601942f0ce47640325c9efcfc3eb3b022f0cfaed168893b1b6e5dcfc + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +private_key = 1f83902bbb77a97b032277079cd0ca70d09d57385ce5c1b3c08b80ed95b2bbe70c101cc1912b71b29b87dd08254b593d616a31ff4957c7c0c325f82024f6a7b125b0ff799fff47afa6a9a7055382bca08cbfba71ea1b530bda5a4548922c90c6de8927494370efa6c96780086bf585ae6534dc05344dc1941ef793eae214312a371ecccea680c1a166ba97e128064748269922c9a19cee4b8a669abd146491abe31a57b724f3a173740269a33309f651c934e09a564627896150addb8ba181cf2503256512b0dd5588f4372781f35cfc0328c0dac842a1b3f418b6e8c567f410568f2c6be8eac9bab558deb08389ba08bbaa50e1ec5dce044efe5830743402402a167a9369e1d281d37713eb656662600840409c4fb971c0fa7771ba53b6c13ebffcbb85aab3316a3a99a9ced8bc4596932b3d052fbb13a5cbfb762ad7a08ca4aaf33862b6325baddb0e56d395e8f92ebc7347e847956b471695c978dc2431ef7286c0e0a880f7871bb05160209900c0c403da599b988a8ef0a716a9535b71002b3bcdade60053f5a8bc66419fc907f1ea718b7bad6bb76fd3f710e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edb500d884428be2c7cb6a6c86b807a6059739e23f70433d8a7a4aa768975aa6b0c3924cc8827cfc731a464121090a685820068019197f489315a2274a7133422b2968830271fc94b1c775c5a21e3b07bce543b32f00b7250cabd0d04a2529347848830c975261a54717324533ebc0ec627f2064ba693a9bf9a16fce87a8d7270759a06c00eaab71a5cc25034120445334a39d63baa2ab3254d77a921209750f6869e6971d05da1e1bb29cec9cb7b4962370e5c139ba472a75114b28bbb8e7069c5a8201b730db571c1ee0b10e1c42b4a97fb7f7ae54670d12859d68199443157ddea85760445895e7175ef8bb919c7213f427301c4f6561afffb0b03cf1ad05613c52dc5ca71a74545abe77d239576303bc9678272873d9b28f4a4aacfdb46940f59b0a82a75642a0cd794d63d03d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c7b05cf8293d3e23fdfda93506c831455b648e2017fd866c87683ab307c6fd9cf24212509d777f34b0618776864ebae9fa5318e739692c5aa86648d49778b67f81347b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464cd1801d02ab64bbba4f932c0003458ff73011282bf444961c54c5275408c4f79c3c553424aa4aa13a53d59b1b785c0ffb686fda185d5438af5c494d98b80381c821c493bc0e7797cd1995db681ec9e18859a9229c497cc251af12d9cfebc6a19c599c9d364e587c7d32245145a60ceeb54cc7ec5b541b71dae959c800a747eaab53f8cd24365c91f53b7b0b9d3630361d41ade4c82c85e04d8ba243763b3f9dd65d60921f962337a3421051d36889253a423939abeb0ad962ce1e1a9931c960d9f4948723ca17a731adfb4834615693f622470225cfa7b036b931a2240564cc35e59a7acae48707491576cc1410a304e0885534f577692c5a237344a5f674ec7c45bda3242d70b004d5ab620ca2b1ac0a56c0cd5b942529b054e0f840e3c1837e0053539b4a3eac9c6dc6283876c745fba8d505681b923e315a99ed34b04e558be2373cd3a07dc6a26ea98136bd197ad8cb1e695544fd93a23a29577e26114e5c8b4257ca7ec5a467d53fd9e037386c933799bc3ba921a50cc98db79f1f7b96da7a5ab4604498a223ebbc27aaa87ede5b4df226c6b5c382e5ea3545e50b9b0a7b30d15c77927713ba9b5fa52a64985128530a84003b1b867a6bc87f295bbb15814ad3bca5eb3240f72894f147092387cb072692bb62161ee3ca1f75ba423653c21582004d8c3ef207f55746e7338cc94c45ee5928702559f0c783cd16676a342ba9a652962c50c030983172a196ebc901a13ef6472c7e67230629a5ee8917e965cb0ff990dae8cff8d3a7f361c31130ad8cb43a9ad48bc46c51b9a56722c34f5681c71690cf5b746b0102c635171e4f1aa199fcc38f566a0275cef828534746ab958abaf2c8814b15961601cf13436ade37047d1c5497c74aab9a0015218c8a41c719328a0a272d96d63dc946124441ca20a8a30af11f07190639993d4cacb58c46754147313db4bcf2f3231e1aa3e81c7336e49c4d760454729e9a47c4550062afd77d971228863c24f1881d589c111b38a7e3f08788298e5cb26ccfe7a71b171fc504b86d4526a2c0a3e0251710a21fdd68047612cf215a46f1cb3d5376cdba14829ff67f7d4704f199ac398777c8ac0ed24c4f00715c976b0ef18a83dd177367078b43003c10e588dfb9c7c99c5164bc14755114d5138715721eb3022cf2d016f97011f37502c44a397aea0a7818546c831f2073a4697aa878d00c4b7ab8312233cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078293e11e43981f00a25988f076e20a7d69e25fbdf7030e8404ebe35f530a8cc5793cf3eb1aed34b3ea742f4fe853fc8b7aa77a2b17669a116c49a0a114770b14801a62868839ab199e3c02c810cb6e0489820f25c524969a57172811089c5c81659f6859a1e5197ca36a33da0e2ec00cd035b23973448d12b251793da4bc9039b11c4312cf3db1abdea0657467885191334fdc8f590973b201addd09cdbb545fe66a0aacf679f0b89d7914268084888d358b767a8475e85da48590f0809e0ccb2c7d286f12fb8c6fba2f1b16cafc97a0b9863b107826c197a7a6bb0bcec280c526ce18058e2d47bf92e7bc0d4031d4c8c8c8f57bd880c8b12c556d750eef27ac96fc47f37c2c26468a8d27b2bdab5483f241aad905c3a76fd82308d2938bf7a070e6dc56e100b99dba0e46f2729a52a365d732965875b020b82ab23de8f8807442ca89b31fcc76162961564060a119002b116a510b0c2e1f301c55992bc48519ec5a1abd49a4e9da97bba98bb4774c0e6b939ac720cc22b2df733bcb128c7d4165cce67710719c1c978cc49257ff741ea1c3b5a6479c4935447987bd61d99c1d80c833f671f6a44be835a8d8d733adf4af4dccba087c4b8681a8b49a863bc21887a0b1d50b05ae1513dbda0960bb156be96a1321b553f21aa0e14295d00b81096e1c557ad6c949bec43817a836f09b0ad0803ca072b488a1627ad2c017013492a955fc829df7d800c99b1ce02b1d35a68d3269cb322b4d66ca9ccd279fc738c4c3910a8a4a479bcba7b1a6ca8745505b80236b63244d54942305c3c0f89bb4e771a5b09dbb072d20417f469b47cb8b64380b1a99b6a83cd111a881af60ea3ae5a314dff60841592f46a39beb80234ea507b1c9233b898a33208d8c936294738cba7287c5ba7f2ab0b7b63a0d475ca3d6486858cc0de5580e95c56c635825bdac834c71337916055d1c9490e7977982945941b8ff196ba5c23f92553f9a1b962a56ac9498b69ce0c9393621f7a662c6074c9e93b44d099a0003390748547e10052506ac88dbc1d3523a16b0825b4656552383ecf067b2a423bd0aae22ec0971e52963241403438c3c254724e1565ee569b0d357b416bf3d770a729a277caba335519724b2098a107f3f4c1aa1f49796208e739304852c949debc717dc8430f23987d60f0a0a3fd5f97aae412907227fd2da078f1a1bf46c0b66e596839632b121c5eec37694809861541b223619850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcc805a0f4655c61a8564c3577273d198184a2b4443a11aa05931dd1827c0720214eb2798af1a83678808913c9c6dc57eea4c1f2f469bca44aa8a8082cd4082464a9e6ac0a86da0d1e0021dbd3196b726ad9b43dff34cda455c7a51ca343f1af8ce2c580c581e4ecb1517cb36959114a481a0e73718f07a8eacb71a7c2beb2654fea5a7e01a6c02f183686b89ca0c775d0605e17225a655a544838a60f252412fa5baf353d2d264c4e4c2cd31bb4f3075410c220632b3d605c7431479f5694870cb1b1724c0363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d6252c8733cb40627485df64a4e872cbc574134c319cf1464a6b69a6318038896111fb69d306a6c47a393069b0f27911255e0306bc4ca2e93ae71336daa3a8bc0517eff101989f9c19bda6751724e1bf816d4cc7397cb5a57a14c471aa511e42f18e4937001977d063a4ee855f326811ec26c8662b5825a95780a3d031948d53337a45679f5c328573c109e5944b68c0b4d2b466fc48f921328d6fc74705491077987e6cc936e2bb69b534ea97acf85e60f2522a55c115cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89adf122b76b83c343de27054985634387fb7138f6f6f105cd4cd3f5b02698a964b036b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = 9fd78c1122ebd395da508c0a171cd52d0bfa8af3e954152bd5f835dd9158052e9e65522850ba3bcfddfd2c204a48edcd3d4f5f3c6d7052933baf66b707006b0909a57638a99023926d0a4d8fb5f5a81cea061fa3914fce87d3f12c31633d1432e7c0f95480ef51aecdd02344acabdd33f7b258240aabd85c5a52537f1ad6adde693d08c2dd6633a194b83614f1962664e8b31b11ac70a4a710304866f7809d9ec1b60a64a20c0ec9c383186506bdb44cd5ae5ccaf2dc0643b6e23e5c2104bbfd4b83d22ccd88274f5678e416219bcb667fb749b9a936aa32fc64d50bb86c624678d283a7f93f57050c7b0cbeb695bc3c7a15c843ed99bcd0f9f74c99e3ac7239283571aa442f981b0c9a9a34869de8e707f1640003717ff0c4894e70d7bf3df2e017380e3c39e01d19c042121ffbd9519b4f4a8eb6114f2927c715bcba66129af881214dbeb83436908640dd4f56137a8ebc14239a3fd227869cfb998696a57a10ba9169c346670a6d503d751b6afe396edf421a11fb6316a0aa1285b6933bfc18077a125e2d1b12e841584c0aab9ae055123918fe18d74cb375c819b02d0fdf1507c2f3fa19e872a7c7d7e7eb4a919c3f5d55e08721339580342e3c1bd6de5cee43774c0760f58c1fd307ec6d6e84eb9f98dab5c3d39910c57fee65411e366b4a665f58c258c34f1d6bcbcc5a9729f19cda362576f8d1f61003c1bec90093e1703ac84900df5c304aee2e847efde6be48a85a491f7134fa6cb485264ce1d6dac67ed21a94ec4f50e1f13d9906d959448218d0ced49bc32623f0d078115101803fc528bf3860e5f82552000140efddd8a644e4a7b102ba4b9951b2334372b665820d6f4515c1e7e89b3de28241a69eae8c5bf9d86a4c3c31384820debc75b6e3bfacb54f4489e5b542303cfe7f068d30792edaec52ec931987a51ff6c61dc551aa29a387bd6fa0a6cce23d65eef6302b9e99e20be127ca7241c80ab3da3c73b328052e73a04a66eb9623077130394a08db2ae8e0566f44ea5e5294a5b03197c5e4202e93cc20406777b35d20114f814d0506f02af5aa36103b9f6f7507b4d261fa76680d8d43cd88ef7bd3c397a3a2af42422ae0565dcfdb223891511f2f1f0fe7d5f4181b72598edfbdd4e7b032ad715db6ebee82a678d89a44d9888a4d6a71cd8fcf6ab5fcfef50f392d1c3c5b2fb3a9a57118c9f3897287cc973030921dfb70421f4bd93f540b045da90e8e75b319a66c3dc08a8b8f75ef2ae4a0d5ec62313b3aa9ccb7400ba7a3c9d38e25f43f48838d9bdee604b0501862d6ed0a05ba9b16bc4d24e759fdc8b72f47d7cd807dcf917bdf979135d153ed612a1388a91f4d3817cd051877466523e67c79dab62237c501c9b14e7493290b2a19da5bbf399ea734948418c9202fe61deb9b229467ab88910613d2ed46ab72b74cb40d56afab6b8559fddeab6083d9d339dd766815915e9d0bfe6dd729ada70d0082db06b44ce7d9b8e2e95ff40dbfcdb7f96e48ed5e61386a3b9f98c27de7486f88912d34256ad3d69827213c734a8c3bc062dc666a6a425e3d2ec9e29614c08f37603bbcfa8a2e69e696f111edd85d36684ae58eaa006b212e31f8bf850bd2113b97264428cecc74f65502988c8c2909643d3a9c5d0af5a24924a0950a0e0e9fc48708bc87967a5c53deb73089e31bc90880a929245e2408c9ff102a09fee0f8ab1f6814b3758540f1516a789856a8c0551f9fd909640ac45c6f262dc9ce47508f2a711a9ee24252e8010c0637a29d52d6310822aeb7908ba4094ad81ed06e37e0362ec9a8cbb17902f21e3e9c1bc7398cddbfd7a88fa36aaf869279ac05e6903bde6269c642c22e5185c444998d4575342088dbad818e6ebcf51b1eff795784f0264ff4426b47033b76c1f3f86e6120b2bc2a0fdf14fff4757b6b25587d1dc95783f83b18bdf3481ff15870df6aa8ffee072e2df4aae4f3ff7eeb84476e0e83959d6675b81712160d640f57b2424c6ba169f858015be5688e295be442a6a555ea578bbc345a51c049c01c1e0fbab96fb946f7464af0ab2de717ad066d6a4d8ee3ab9a60d0647edfd741c6802fdad1f3a8c277f269f6901dd9a7145e2720d4c9456e81f463ce52f53d23bf0e7de5d90e54a16038d8d8009465da7dfee322b2f87e8de9053116010b1873d43c5db1638b857eb2338d8b4d2803a2830fd370e640b4b5046b0c +expected_result = pass +expected_shared_secret = cad5816f1b2057a410cf917f52040aad9cdef2122ce59211ccef77c4a7c23a6b + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +private_key = 8b78635ac351c94bb6b1d2b861e4914dcba415f66ccc465b370578e136330a2c5cb0ca2857e1cb733a75e5cc4fcdf7a12580017f1c0ff484401cb23318a98000637b3d065608678103940d8ba75ccbe58206c130ed62bbc0132317b6556a9c2ae8f71a43712002d795ca52007782652d291dfe535f75034b0d624277527a6ef623168aacfbf721a9e8753195b82eb9855467322aab0ab1701546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830df61fe9600ad5717bfa2c8e59e30c8a20179b27b59341c855677880330afd1a227b6c6313e17c46e87d109a4aec4c1795908db6046598483159907a667378f80bcb84472d5a748043b1bac10ba5bcf61b07a2b13b12c347f3253e26c25ef0af6a003a67b0bee98a7c5a489c9ec9ac1f042c6f2bc7585cb01bb4b55496a93de903ec974398e277ca7cc25e3265a879420ea0bd8451716ac21f1bb806c12b3488d408ebf18b89b79b1f8c09eaca235f1c165f9504ff987139590f9977513ee037249b4e25e51a296526ba76cd3295895a571cac279bc65642cba501c8f131eb52b5c7cb73b17757440b1ee4e9295d404177e542bd744aa587738bfac0ef3c1fa0f19b0a5c5e28b53c2340c7fa061ad354c85ad26993087b61ac2002795d5ada7a3e6747ab8110367c824988ca705b818d7a921dba33371405ad235b18e463a8ac88180c88f071579fa5ab6d904a2f53b03f7c7ec39c473632369f984f8cc66dbd1924206a6376706ca36601be7b16edd17e93cb9a0437b3615374329b0712794f5058790d88182be4863293133a83aa00e07c8e79c6f12c33fa9437ed984a1392903da89bd43184db6c8dace3789af5cbba092010b889ca98af99e5b0b3d4399bf61266e833a55a85e11784708b98efab223a27aea1a16e76a73c2027759fd97a7db870f9fc79afc89435d092db556e0a738c133b259f86c98d78a43a49744f306da8cc6c9098a5a9cb091c9bad94970f03b543d669a9aa4944e0c08ddfcc1d7d485fa414b0765a88f175ab6c94b12a2177dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f084277532841f51c3edc5c1873bce0f07a8871740c4aa82bb5ab164916082b795eb0660be32da9972840c927b7bb4061343d56757258ba4c91624f21da11cb265b00b9aafbb1665679c86eabbda12b74f1c5917101d0ea2bb293c71ad5b556369378a8d5b7297c9731705dd4493dbb173ad01458686a93287b6da0a6923b913989b69612a915a03a0962379bbc466a03f5517aaa0c0b030c6ca420636b2ee8821916e9c7f2ba228bb2aeabbc292f6c07ad85c6f43ca90d42629759536046394936c3ac5ab979d5cec1a1cc19b5c17edb47b0f47f34d616027b29a12725bf14b62fbac4f2cc6eece89ca0467d4868c11c17299373687b657d132c55785080f5b87f0e3c1504673825b98e8a0aa35f2c8d84f41b060ab43a930e7be1c9d04746169bb4ab403ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a9550ee494466a49617b541068f2c57ad4108ab813db58526c7647d55c1cb657ccd1143343aaa8421c23bd0c822f763b6a82b7d0041648a143bcc431a72b204e680a3bf11cb6652255143c4470b18ab27ba5e6cf2f1064c37ac2a446243442b0d2714d2d6c3208e303f974748012a7f0aa89dc01035ddc3685657d457a6cbe9c7a9e8aa5e522ab7dbcb1c646251bea398431339619b1ee972a46da3a063c909392c284b4c5ba840c235588ca640a54963252e45e33f51227b11700f135756b3567004216417f2beb77f9267e72e444f3a78ec649131ffb364b11bbf8ab6472996be20829011c3f32183fa1a39eb2bc0ac20478ec168e4e2ba66a01742d973bcec937a9383c62c725cd0528bcbab546179a6365819777412c5671def8cfbe9b27af037de11c268ff2c1814222664bc9a7059114511cbb5b361ee050634405f8d1908d6a9f3dfb3c1d888ca74bcd244313fda169b23345f2c804db569a12293883994940fa236a7a5df76c1d6c853207a04d2de7793c6a6bf5330bd31c285a923071c2331c23432c427791e17711f50688130c3daaaf532060ac0c9ae2e9cc338145d8a5787904c133817947430890361777818990c5780a4440b2202d24d25e62d57365c8c611f96ba675aae5a14164b5171d74146d792d6203ba384ca81ec71ed87b8ba40023ed8bc6ac54406263ca3d97c5bdc20d9e2cca82b0aa54586863d95d3ed0075cc897f6726caa441896e86e03711a3d109f5bc311e81a5194363f8bf735ac9a2caceb7ec4826f8af2b303c3914e9b7c3c5337432ca626970761900b44cc92630ac8469a6bd9d2b46d88c225223dfc405d6f1447f9878610d021cf3762c235c414025239ab3827ab5a4699c82e37b1a27b460f0264f4089a98e41c924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad0873935718bce46b2f19864e06486a4f5c8d689adec32a2e7c6b57071be67017fe25b8f52ca525f99be536a4c1468b5f9f418025450048692f961ab8feb5075b543e04a0564c26c58a72ec6433b623a2d5a086c85347e45ea7b99d03ab50664149414c3f81d219a5b5e732c0a52c060e90e64e14873c02167a21a67da6a0b945781341cb7c65aa2dc481b0998de5c8d893a548f055f8fe420f173b949862a5549b0ac1908f202ae0bec6b19c0b3e5178f4e40485ca33a93947522c1aa6c188ac2fc4cff214b995b1bd69229d01a8d3d2045af723a1de559abf78c09928d71aca3c0016038340ae715058c95cd33ca85709b2134f78b86a84ae764ae94b994acf1354e42126638b57ad207bad29f1e60471acb5b650332b4656ccc808c15ebb8df203ff0821bea62aa67967bfdd09535e7088ca98e3795aa1167be9126348a946507c08243a969b2f9238fd29f0370356288cb1708024ba7a9cd58a12d306d4f4579893c8a04a10c1872b6a602c155f70a8ba6987fd28dc842b9f60b4052890a4482a351533b4752061e30957f8a16b6f8502a1b4d8f91b56b71470ee2cef40648533bb1d9179b3e335e051115b817aa30b3707b64121179318593b0460bcf6e57a65e045d00353605d60a0705468c6b8e4db422c31476c8a0b54ec166ba59b75f9834633c0052757dc437005f653ed4c19ceb7c774eaa75ba0068f2a997a79a98bee42abf9a3b7597394d4907e430737f860454407b8fbb2da0a054c2a4c737c8724c02684a070da34388fe9927be4259859849ea9cb6ef5990eae176efa10154556ce5650cf264bd11780055b5931bd6c5f51816d135996757b386b76a03893efea95ef964b402079cad080b67098b2c092f1e9768782a8e3daccd82741cdc5c8575796d08e3180b34b4ce227e7593ae9264417e7b53daea2987a01fdd42150a4262441475370c1357a575288571996527c95a9fd62c3bf54a8c8ec0a335c3a31b934002443d07f27240860e8ea76c821a71e67132c9a5a1d4d3b5f29cc9a9924081fa3c33f4a11285458954042337701c392998da8ee556a544f0b49c9c2b83b58dd8d165e6751318363400d61652d7170ca44b3033bbb20b45072708e6453b1708b5b8206419e050d7c8843e0bcc227b9d6b426a9f693945d69ee98558bbe133fc6427a8f73981786f42dc03fb23621952ca8ae03810648b8cbab5c1d2816fd1c231e10f7eeaac9a798c2c3a4cbac428c6971851320191d3195fe4419ab69fe913280d0763a906c33c4a9d311c74d9459ee85a6599061f09376a14803e1ddc67d8328bef1c7f673b62bbc234b20a29802ca9c19c89b9b6628a6bac7ae29897b1136a0b8c28b0441bd00a9144c85c9897a48902d176b9b03a454f36885db61b5915811d60c170f74abf894bcde1a088195fda3043be6080b8b98dd48168c12a68d0b74242472ddff790608170c271a4bb19907288854cf1c4cd744d1eba1201fb643b805c7c7c1f6cc9437038bcaf6616f9a6a214785f5fe71071e4564d0070a401b457023685a65d63fc525bda14b26c1f5381885b24786a939669261b769068c3f97eee28aed3fc68d3b08d6a6b77ee2449030c0190c016394b0d9c8085bd550d12f5110e647b9a1549e8f67f5fd0580fb39358114aa668bfa3a202c0369ddbf5518d80aed20c403aa3cc7148119cba54ce1667c2654d9b5a833d5a552808ae72629a2da12498319a30113b314c870e8752e442af5ed67bf1481f071921191b2b21964fae23b33df528a22090e4bc6ec2911810e02e65758397b48d1906013cc0cc0c2c73944b45bef04c2781acf467336a107ff7cb12e6305ed85342d2355b047862be56057cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a69684c3182ca7a48afe60eb85790dcb50b8005b568921dbc724130b0ce83f127845475d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = ba3071a54dfaa0906f8ee42795eda8e49faad17e7ddc5667c5e4a10375bd75fcd52c555e82694b6562b862bf9eafa16c02fda81ccb4ee96e2ecf9f13528eb95e2dabb90876dc9018d48f137bb93182d83ce6290673264c46c6357dbd792d361ebc0aee118bc7596b58af225090d063950325f098f616016e259cb6056ccffd05c4ed8272866c555456d51d6e30052b8e920ba02975733cffcb02c1697668e518942d12485340b0696775c8f1ff7302f4025faedea28e39924f9006e5faad919a292e01a8b4255575d3b9f523283e474505ee0c34e8abf992808cbb23e64d44f5d62593200eb4afc6a6a5de98112b6dcd3cea483b741f82105bd56d6c21f6e4b4112b3767fefa5b67e42ec38963eab8108f5b31116be611708cc3e320d308aa8859c1eed3320012b800f38226f9617cfcd3e3f444c4b633fa4454722cbae119d03cd4b6d2fb8cfb0ba51c74f9e0859a6747c2241b9794b5991affe54209393858e85dbf0504d8215de1be359c63cbab55134c610d81ec0446b62e86e7f3a205ea621104f4681960e39f0b22492d62cc765ad9c72f1dc820752b2f4a23cb0518c7c299115d2c8ce14d799366715ab518283b31232d3806a81fb994b839673ecd987c7d95208e2d87a8c78b32adf938a2b99888a26f45ad655e4eefb8b3342d3862f00eaf129d0d660d5af10c2b30dfe64f87a4ee4450ca155ef2129095beac466a35269cfca6fb17ae3edc9959f3af90d1487e58cc1d62633ce0b2ad3e482a9005aeac77542cd14f3581300a2ad1aee5b3a99e4570dde81df5fe60675a8acd7c950ec15dd94c96f96cdff33e155427fa7d87bf47c2ceee2e4619f4163322c1140b1c0d3786bb065886dce73a16c4787692a0c974dda5ccee7741af8febd8a4a150d3e7e99663ad59b9482e064ea3c64382b1c7aa2fe8e9d3d763a33f2a89494c1552cdecf44461efe20b61167ca83c0e5fc890e58ee5c549b37db205e4368dac61bcf8c687eb32329865230cac0eadb9c41d998a34e3490015e275828a386d1e9fdf14273b94b0346aa6fb91e0ab3d64ceed7f2abf2bc5fc5d016a0a8a87d10e723aaa90d9b0b37d99483560be5fac144a4376d83925d312a065a9669e27ea4715d58c15564cfc50b8209120fe2db562f0b43119b378ddc5bd4fbad0fae538e279a998320131bc5d033177183977a637f9b0a590fedeaa6d70ca065969115f0f5523e22523164562339ed91e6b5e8cd3f480121f1d0a85c57e894d30176a8ee2eaa1069c5c7f6c2cf116780b59be89120dc9ce50afb6b85fa4737bb0bb2195b5a5db44b8eb0793281df1a64b89751fd0b8a06021ef95f01de2c8b5abbfd0f2202f63501cf019582ff1a60bd0b99cc78e355a9d5b5adc3e32a05c0503afc2f015bc6280117385c837a6dbf184949d179369d431a26d869b65d6ef0401246f8609393739e9435e9bfb6f48586d8b2a0debc0822332d97537e7b332eba4a61db9a093d844652c8cb8a32cb44f723aa07aa10551320e84ebe81f3e7d251bf40b7fefedfdfc0c7e5327206b51e34b6ec5c958c44b88c3ad6fa552d882baf129db0c34d5f57431f525275d72a1ee47725e0f3bfaec864d6812f270e58671e0f5bf3795db9c9d8d77d04d6025eaf2468ae90307a701ec72623feac4d0a7f91470a2da29058a3bfb18e60dbb5d8249172a495b31708058117a5b24c9130a0451f573d273faed048d4191b2dd2a8341d57933ba404200fd5aacb7ea7c3310ec54fe7764178d507ca302c773f53855296d094029e9f06e47ebe01d74604b8aa70c574f77ccac4e80f862144933b303627ff8effa189938c28263b64f57cf0e0810feb90b3eb94177735fc5a531d71257fe4fbec3a1f218316b35d1f5b7f8129e0c361ccd7180472aa07c91ac6b4b00c4e8fe91da9c4321b1824f7f7a87b059f02ef8b05a40b8e3c21d7834cc7f58180a4bbe8a03da4bc99bd37b2ce542ab0fe850e67f9afc9f00f41a0d38c75d345ffd28515f9a442b33b05f0eac1d0cf710540af1be81e7481dca72647d810dd7c9b851f8264ea21080d8eb5315ef5ef75f7d85e0b2fdf895883d9a285324ef7dcadce365ddbc0eb0e10bd25bbf34109cafc32d88384834e60249ffdbaaf72ecf6d02bd539d6734465eb5a176123155d743933dab89963f7ae1ea01ee9db1b7f038cb0cf7f9059e20a0acecfc357e4ebf3f016ede1019cf95 +expected_result = pass +expected_shared_secret = e8f4dd3d2bb2c2f110bd410b2c37beee6d3bc7c7c4dc477c358234c54bbbd4ca + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +private_key = bddb6a1bb704f8b530860b719752402098c84ae4809b01c8ec7583a66a3f4bc290bf2173abb41868225606d54991f5b547c2254c74391717045997a57ba534a97b3605e1ad9f7c6446ac08bbfb1999179bb8f67731a63ce1c717f30b57fd17bc00605e8e14127eb0c26e324aabd45138484a51a15dd2464440178ca7e966d4d58383f6bf9bb2a971729074781a8d978965f9a51eb2729ba8c308474d56089f2cc869b523c41c409507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373d5185426b7b3951256154a7b78cb1f5049df0371b840ab21b83944fb383cc84ad9e24ff42b2731276c1d26b6120534438b029c4ac7c0739453c2860d32acd75229c63a23a7201c303032bc0a410319035d38a3c9802d41a56a8c6c2496db10441a2bcd13a81f90cda2564cc9e4020a47595a30994888b383e996115aa282eac3e3594447110c2d07774f9312d796c6b74a7634b6c0da2291458a35d3022bee048483461cfeb152e1d2ca9195afd1f9aa82131804d35e739299c539b913c54a0c58683259b3137aa464b9c6e03b0eb751999b6c5354d6171c78cbbef1b456ec4c88199764a5761d18c0849c1b0a263ea401b86cba549c712e4a251830f7b6ee16b2bfabca3ce018c3833bb881385c272dee151ac35a2c9561b3c1266855219b0c6b485e669fcbc49b24c50c6c3237aa6b116085085405115e0422d956beaff9360b58bf915654b9b887ad9733f425a5c6990b3f0223d8099bc0e95c6a5702cf5667209ace08fb4697d02dc45caca8074185f54ec4641b35bacd2f0b770fc215fdc171c98baa7ab6c0450ba6e47a838575a528f7be221c3c91f02734269a9425a2edb76cb6d077ed76040a716d39c9c87a58ad8867954c752367a905aa158e0a9019dda50a6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aa9a0418c79a948199365a6a1045238104280ac704b33791e156a2377bc83e9b9c86d0a3d2aa3287272be6431bb4e598232312d10d03bcb13b4d838a9a624566c6a25fa44a0934ab6cc333e6d52af3ec26a6fb97615cc3c77102d1a315486bc69c555a3e8271660222a406022e8d97251308a90a15f748153c1168cb133593c1641e164c8a06cc008059c55449413c2b28667b99122ac42b8bffbc15fe395003249c676db7589d2896e7405bef8ac510782ff204454c8a0390c332ceb7a5a3123eb1a1ad0470096058358ba779df70106e24990da77aaf09705110993f16a2320a941d8865b387236cb8528babbf2d9196c15898bf71040d3ba500cb7b1ac85df11003a058d838c2652d4577306023c756ae9715136e91b20699fef425e48953fece15baf27489d929876803eb0b5764e6338bf5970c2f35d1e815bb5b0b1bab630138859b729923343c3d24922a8522e38e19868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5b71ea78c2819113fb3632d5d995b02926663f2ab8e3a73dd6ab93503192e0243f2593618e3a809684bb6a31674e77802828fefea3a50fcaeb1088f7edc036cb84329c988d965071e97c1311643bb1ca2b43cc57c84cd5ea9109ae36de2801cbdca3bb6f977959578954ac17d303841d5726631663f12816edab5c22b0286716d1da2b9ea03c5c23806e56679f43b33fb553ac921482f0b61db90acbca4b91ba19a22c5709ba48777979538519da6ac5e2b576c545b35e510b1a57bc651f69ddc4634588b19a31a481a216a365941bbf709679a9ef8a6324c20c6842818ba97cca6d26ca3fa79f3571e0cdc651ca753c5f2b8e8c247e9b064cd266d268ba3c18a30168452031b9458b3c4a084a7a9542fe7fb88fdd828f5d275cc1879fea43d84a38db1933298f6c98c08188b5aa96d9065e7a638d3746265652fe72a2d4623bc97c40b61a7124c899876c3aeb0d9cd2672795e0a65d44c0180436e8f4c2876e66cb8071262da0947a926c80c6b67e13697c7a200b55f576459478731ac9b62b7572442e04105a83134561ad9a71a9d4696f8fcb791c44593a680ad34b8096ba82434828c492638a9a870b14b611bc4fd43a005624895ab6760257d181954f3f934e3f6742dc54cec3cbbb8c229f8902d18517374cb6fa8a0cf6bca0487880d30173cbf6a0386f12ecbe135cb7b620a5b7b3999b947770401a917c6100d6d7952085257f692ad9173888f28bdae384635b2057a8183ca07853de05f72437d6872575ff4c0efb06259e397cda6a87a178498c9aac54b046a8219d98c48f113319984995f68b1affb863ff97dd8d14cace2921bc192e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e731e0a68940ee5b8307460b402651457ad1a7883d0165c8cab4d88f565008155ac009776500f3779530958c3003c7603c900e50148088b9420b78eac241dc0aa11454195a03998388ac747fc465dc140e9193a9294abb90b8022b493e069ae430ab3fc9307fc89358d3a88fb054e9836cefbe45c44569b285b01ec892d5ce8288ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc06a08f521b6063066788841964696a31547c851b578fd02434526c7e641fb9721cd390984bb121518a88633658c7c7c6b0830cb6800b2368cbe703cec33a4bdf319b49909b590a8bbc6542a108bf5927c49dbaa2c5c5009e002e242ba210a64f18b8542be1cb92a8293c56586b568b489ca697d6c4f819c399590472e8b9de9573a1d2934b86bf2d2b6f92ec8489430e0a681fee0a22bc3a705396ce6a74c1d5d3a91aa253da718757c875a1442fef4241f95b516d27220973c25e29b1d335846db494db4cac3a0b76388304b4252ac2362ff032a8b5c3322f6a0e5658799f1193ec69bf15c77e5ff2a3a2925690496af4320ec688450058b5727a0e66f98270267b3f49270e310714f353dd4b74410a9a0e778a1e030461113cfb05a142001cf39721215026cf84b1c0e706dcfc4d9ea80514061463a16e069750c026ad26ecca10f5830b2b756d515ef1c64d6d2c5e73818998aa9230d19d35842400c4568f62397eb0a42cf86c857c3ab009c8c831257d246b456996bc1bcc378a44bd88a0fc3469b0da0d22410218941431a12f37831653342f12206c56c4b3bf980a5017114b3112a6100b06a2a62104c48ce8639d1830e785cb3dab23f398691b48458d2acce79511ad276643476bd6c33d8d1c40fab1b81a96a7dfe36115e49a07f8c72240b9b3f24a2739b963609b0c2705f928c6ba7c2fcc0c164be46fdee5baa5730cd7a55e1221cd73305bff9b8ae5c126b8621bd6116c17286974002c88785c745bc32f0b86dba92e072a395e91acf7257ac5ec5ee88a7095acc39ad023a904b72c0ac845a318d18c7c72a0c4387cb470c8ba438498c5514398c70967b46109e18505543a98d51a3753bf3c657aef7264a91c2253f801641c609628a7f13a246d5aa13f3a4d1da22221ccba20091c6284452f376b32cc2d27d3869137a3fcfb06b7c93f70f3a20d84741b8a186d78af94c204bc0b6da175175bd819479485db23bf6eb2cbbb62a088f2bda7cb470c26b281e29e0f29a111688cc2e7cd61985eb39287546967ad991eccb99a6dd4b111861755964a77e3a7d2c5b9dc966e6f51bd53d72f9775a624f344fdf4bb3a9822d26b6db6b11efb527a2138c45f27c5e8a834ebc780e1e8210a9a7a4b7c3fc63b1757a22b8cab57bc07aa27a228cd30411ef407bc276ace8c05498cb641366b4ea0caf8101198b35a51d502a1c1894eeb700a832d70e627ac0b7a57543769991f007176cefb10c6e74a987c1d9b9750db5230317298a800b508d41c942b48c36035915c0504646726ab767a5059d39996a3e310ccbc610d878f9b7503b08822bc1541a359c807526d27a7abc1d78e3c0c3f67f0609c699e44ca8ce2c7a78e70042be21f4c569e9d0494a6e8c2f0592ba5060b365b57d1b03916e27fce04c42205803af0b213e27b21245e480b6330bc8533888e72e9bb2148059ac42ba2ba2550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de4898181422a34b9a239508878a0682eb2466a44a59542b268d31989f049f433a7a0225d556770f4391dfdf4432133a0d888436afc531f4584abc40022c36314757e79538cd1c67da58a049cd10baab7a7fa38293ca84403291372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc7e1c2e62a2616838d5d13674b832694975cf1396deb11a1cb5a1bcfda55ba86583884aa9593399a047f00e703cd458ad157333c349c46021b7ae1970bc2927f094c77970a7c9bacfb0a6e02108036f809c9ac23877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e4359601c371b50b50b5306de33cfd476d3b5f811700dc4918beb345840244e3a248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = c15dea8dc9b3e3c3f0f882baa4492c72701aec1c38c15825bd31c70ea9190b9f8dac474cffecc40a279208bd639ef51489b1de937e444a4efbcbdc4fa7672f5485f1f3155e913ef6e79de719e74c08cb86ae841cec022278cba60e42bdbb2c36db4f558d8d0755987773d960901daaf8ab6de00dab4a3d3f0b89871a1ebb51713c2c4e094ca0ecdfa1c4ce541b2eaa57b13c2c73bfd3062ebc9e313c9183d90f621f978b0e984d025ca549ef3a493e663daa6608ffaf322b5e073e0b0a432926755b8b2953ffb7072d1a9d007d84666f732cae69d58c3c5fc133e513f2ebc54f04ccf95e8dcc87f0448bde13e581c6ea196fe22b1fe2a3f036153f7d4adbfe39061d5a4f6cd33bda8a2d68f491cd4a287366c7f25a586940a23b08f893d24cd62335130e210c02b1f4185b7c0788e23117715e9ada8a65bf90251321c8bd7d335723977606aade969c34f346ecbb3680b4d27af6b6c718dcd434a61ddefa5d27b24e786633928e13e226f1d63c98c408110f6cadd667b5f4a7893fa9c0e037c0d54a138d106801ed57c059519a774193e09ceaf35f21f6e562bd93ac9c4b2f85391be1ef215d8a95350abb2aa05fa90407677cdc4b53bbf70086ccc8aefe333c82ddfb52f2ffc3b5b2484e1c7b51597f3e915beafa963dfa604643dac74ed40afc4d57161a050e70e9ec5bd460e919d8b385ba68e0ee842391aaa355edfa8b930bae45bc818dabe3935c40cd6ddfaa068897a5454319702e8e94b1e86176939e9dd6a6034600a9347d00a5b561060f2fb1fd89b7cd459ab76d8583171d95e74122dd9a1e8d9942dff9febe0b30af1c799d27db896abb738c06074781b192bcfc468bbc267021522bd2637cddfc937251dc0c61c8f61e6f7acc1c2d25bd2688a54d81a1bbcaa224cf818119ab78e1e8870bbdb21396e4f3c300d63037867a8c9fa61577e0ec11edc7126f0355d8c104a5aebe42defa7c9fed646a4708c4de81ceae2bd23ebdb4362293c442675f754716475256be312734579837973b7d6a7beebc5db3f08322e76d4d8e3824842a930c1db7595505b824c24209c994881dec2d81db4fdbb6267cee4c42722c15817a0770f8c84b2825dfa882a41eeb123e4719facaa0a4c1dbc0fcffea49eff0d478426e3ba5e6f6ab077d0aeb03d66c275fcd86e4c0fb4c3561834ad83cdb9663a77e10609cbe92d2e3289fb3fe0ebaf208bef6ff9021a95f86edfa20e8af937ecd483c60c5aa0bd948d93fe13dc6dc6f1f4740c0ea16918ba739bfd5294c8081d3c4e5fd2aea8674744738c9f5f221474f4500d3638ab4ddd06710ecb1cc4a8aa7fc52427352d68cbf723dcf8f5a3a9948c9e3cc37bfde685fe73407813753ac60b6e129ce3f432332cd2d1eb3caeb6e050698f90e82d76987e3588cd76245de5f0e7ae7856e760c39b3a6035c2a25f568f496ffca9ca83701db810f494968d550e3fc686b6388c808657c75ae01f41927b4149962c1b9b383b26705b8b54201aa2091e7c33d6aca433a36be9810eee0fa2bb8b5d0624c0d7bbd0403f4a0fa5444afce8d7df30a18aafedaa3397fcf02f2867b3d3895719b03e237c0105e5a5b4b6e31b10610383a5660dc630fa5633ea95e2e3eb0e92820087f5493c434d152ee5a781bd50a4f6bb2eb2c3c3b146cef5528031af3dfac925193ea62d5ba10a2ee26b600703b72592269c67c6a244cd7605a419b16f6e65035fab65db94ba1589801f831d27fe91371c6f8df759d0dc96012137a3348498c9f9e167de687ebad6b0213761965247379bb12e703c4dcd8c429aa35bf2abdc7dcf13c33c4da813dfa6732e8fe2edce3136be82e4e58ca2d620a599e925327cae64a38174a581b5a8c5c1e526c24f0ef70282271120b8edf6fd0ba1b31190c8a81128ac4c634072417f347c966ddb3b9393386fe80b15245b236a66c8310c82acc3ec9ff85b33282540a40522256188af8ce3a4f961555354421eb0cae489dfac24a4073d5853901819ee24f2b2bcde412d48656e6b517ce5a247385b598c293aa1baa8e6073b9344025392ccf33f14c7379732a3e421a5994b619bf2ce5c3988541d9588ad4d4fd00d1024308be3573e6be351c43350eb29f5a1cebb834dbe1e7d92dbc95743f3298c2c1f5474a10d73b5c7b097eedf174909b4102a194662e38474359ff4bd36f9f6d3797a1e0c6624139c47c30ad263769c9 +expected_result = pass +expected_shared_secret = 249855eb724db68f7367385c45a3206fa19c521644f8841b7a73f536ca47c26c + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +private_key = c6389f081ca0932ab66f658046c1278b38bc42b5c4e1a7c7a51b09d8a159773b67aae1c2aa8666000c6e6a014b5c0369dff147688ac6fd48c73d783e3025c92d782a479acbde8a7548384b763a868c46178345a773a9852016b9fe765db0bbaba5751e8056b7564c53fee8040d3c0125115d323c62a3f0a2b518330b6cc4abca84f62c792d07c1e1a0bbbd7c5b9a698cb683981f8828ee69912600311a0281dbf9c6c9e69daa26a446d136e8b0310f236d7a5a49b2bc616fd346c3462ab09544998c8d5ef641e7b48c35ba7a68f25414f703fb02b501c69c58a9b798c8c76923272ed9bf432208bab30f2db45e1cdc56f6ec11792a33ec1a62b3fc992441527e63328a46003db49b7dc07f73f705ca0220de94bea4967213d612b5a03b2c16a9bd4c66e0ac893263169a87aeae67843944628e6374b5518bf40919840b8e6c64172be3a35ee5a29777c035463380203072ea50e7daa4f906d01c502560621137b91649c97417cc2d3e1677006226d4621073cb1aa213525199bbbfa78f1899a53cb2b8d00819869867a41b2f48c615efe2c8da15a4e6965bef0c4207a499a2156ebfb611478182d85a71c9f8776d28051d1a6e4a104e54615992e0595ca9b0cb2a0ab0159575863f3145b3401498949502b2ea4392c77728215f8700c93f5846a1a8126eb6b72248bd1047bbe62aa58737268428509e53575f945735e75b42db2ba2f21b24c990a847241d2c3533b10d50847c85d98143fbb2eb5138accb055a8b8bcec8afd7b5697306165af982190821a14301ef0a90c3d829ed9035430725a99c67745ca415600d10d7c29b228998d7402efc1f0d0476c4d74c34754af9a1aa1213c9a0198065378de2d023eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c604760ca679b301ab08ef1a948a5a83debb39651310b368c736a56977f78af0916364f278a4e3973374213f7a28ba70296d1916fc65cad3b33c4e1597f818cbc489ba970680999c373dbc246740c07d97c5e1ea5aa1d627757f4467e84ab9c5bafd9ba484f1212706788cf5ac1829c7ff0a66f26c30aae327bb7e167bde95fb5829340b187162a5fde3a7cc6a0a05fdb6f26902bdb0c6c4f75692e67ab1c8b1b46a40e53fc901dd892a3e612afd1cb2cd52bc5b0c3191137e602b0a5872d3a961ef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2db29b637a5e22559a59971be46004fe2a40f7c330610377a5b0eacf79d85f3c86223a4c90c31c2495314748601431fa1f49abff2575410af33f7367c5540084b75d6736ecaa010290839ee2456ee16bbcb57c601f26aa104916254a689c24cae98296e4bcef8770ed7485511f55a46c75592c88d6f76005356c397eb1e61caa04bf55a05c8409e644055759a7e60c1c8210221fb97780b92c2c8aafb6b94c259a9ce6291e18a801a82456b93c221a625129a1720328f11574a5c35c3650a7b57619c61f47ed6319329f118f4c31358a26a7e9191cab61012a71b27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13d41256a0b442f0428de78f90609a11b8cbb475083712539e1ab034903c30f6b73bb8229ed50f901b142a597e7fe48b6333ac8e01205481b10eca15f509140987166d81cfb7417dac331ca141ccc61a446b285c05d9a68aac887aa23e17ba7deec8521aaa3088cb03cc7056560ac669772609c53153118b45d855f7dc44618b743c22c779145d58867d04f101904579ccb2cdacb28be7e019c01511644b3a9c288a1fc84658281ee2492124f609d4997765f315370176a0e3c327458027facf937a38eb88ad7c950db7eb5c49e17d48532822611d8625581b3b2425288872e00db25037542360cb5685bde15872a935069cc09d04395fd1a5ae62084f74b66da89263a11e8d177dffeb686a2445119065d8c59248f23e0d515ef2502177bb273ac62a9fea23e0e48c9224596c44ce974650dcc81ae7dbba062bcef017898beb0625c75eb2ec3444f20eba3195f5f9018309b026a32d4211430eb1c1eb2b7d87b0c282f0a04633499c3a9478a7b755e0b1904794f5a0b94f52c05300c838c67f4c26803c52a042812da9c8cac5650c3367a770220f43e3c039c3109a506731076c8dd1b1d99caafda48254a73ebfb66849548733578aa80987b45a404d892f45f83fe6260b4521181484a7ab65aed79a53f2e495ad444066d1108d14c4fa74847fda990a783fdb923734860238a94b8634217de964ea35a3d4c651a15c719301a2cad86352257c2ca1a87f329092e18c5c782ace76ba239c6001143f87a0406da9437d7b19144386b9687023a34a46814eae040c71673aca3993acc03879c9af60ca0e4eab9205b7ab65c33ff1295100d349f84694abe062672135865494ecf58db2912a3af380c228b78d329634f359008871769696bb357d552c3e9fc17d8b636e1b905303bb2a5b6a6f07f478d4229daac38ecf47c205371705b72092f7a438d01267783e24370080362c659796d7443354d92dfb9bca5ba5355e5c3608bb3d9b312fc7ac435b81cc1a6ba84a74283763a520381e9e3c998dfba80d8383d416495b42b7b6ca3e91789c8191b894350f52b6b7a3e38a45f50f39497794e0971650c446551d7d304c87515bb415773c10bf08cc20506c0f515428e8b9037c42a837469de6a3a37c695b602407a46b7796593623a9c840accb5a6b1175a30f62c8b9461c444eb73bf1e22418347af3d92742175bbfb41474156745eb0dcbc4077eeaad6c13c314d3188d3c9bf2f73784c0cd1a215c4623a8bbb19997d82be2b1719346190f054a1ad92819d9b812028633469c3661238fc66cab7c05bc5468a132c9b3a50ea5a4a8ea04800c97c3b391115725011e597312b7a0440ac2da794859776ca73b550d666a8f058477a1a0c9621ff6184f415114d35514909719234c166734b5535b863afbcbc5a2264a86b0642a41763b6d6da15447bc930f925415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da37862790a282b8db833ae37bc5a6940a8b95926f1f468853b288c9a4c7c128bcb56c7a218c3fc725ad1b89c829799b0a8a1f3718fb489b83b900f1cc9b1ee16369f18b207d022a35224330582bc4848e4634f3490c12c756246dc9f3cc27550057a1863ccb91a4b891820bc882c0e6024e1bb037677092c633f2cf68b96b666e1034339ca3e43f6ae7fdb22f9fc7649e559e5d22a07075bde79a82e62b5a5258a0e685a2cd1bc8566cdb4a19d5c581236f0cb4e7aad6f561ca9f6850d30a6fa0c1eca230a06e11cd6f26194f56f40bbcdc99bb4c1f32c851bbb7af48f19d813f89b01d9477861e128631b9b4d72c4c7ccbe59462a4519a8a34a44dd84586c4a542aeb6e1338b6836297a59283af07ccecec01ce074d8469c93f509f09f7230c092c63f2245ac2137a4349078a473d81cb3f87cbdf843645500b932bc326a85fa91095e4513e9dac02d92a69f5acc4200bb1dc0270b013b1f2372bc75aa609e291f0385bbe9376953cccb3f99971dc9747cb913760506fb051ed186454255fcd642aff73c32743158d467b0ad012aaa439c9335b4ee23a426cad3ddbc4ab882076c2bbe83321fb684825b032059838e3d43da29852309b1a7c15c08a5669a3ba2200b34b7f325a5f47b479aa49984060ace979e9db6bb68466973a3e0030c0bcfc4e6c6c13f734b1731ca956f89341d37b1cd5c40bec802a98c674869c04571993e461446b2e2a68ba71915bbefc2d40dc8756b9ad9bab639ff6985e03b5a861785981a7b1449594d584bc1cc4ef7a4333e5453944c61d0145a5b6c999900df26299ccea5cc1d36fbb80c1a5e9c619a4347669377d541519ca47f06884b1984408d43b4133bdcc488bddc599c4057b14a027d051420a5c17cc1671f18a2128b58e9b7a5e233a6ed2da288130b51e47038c9aa2751556ba24b284515af73a81a6881d665426d1d27a8a763fb3b2caa19bc310a9c10024b7d722606c3b6f19c8935b744e28333df8b9480a0083eb588380e6a12d777862e5c7d3e1874e8b1405a5787e92accdc798a873539c133502569e6de7a29c7025289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960750209ee517629ca2280bcb7df35793bf233fa074185a04894ac515b8985ddb5acab68ab379a639c49216a8ba4f9b125947150a907385e9729a7d621a5a9bf8c4a1234e6ce4411923c18ca0e925cb372c59220a502390e4c740571f71eea1083887a5797f5631f614f4e91184811892c6086b0f5bb6fc322afa31653509c8e11a8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2e1f6c5a99a49d6b1b4aa18089439bb4c56ca465785bb36594ef2ebd3af20d5641646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = a9bd39228fd0d5f72c71828ec1a4eb1d77b2171f65bb4e14c300c72db4510fd4d1aca62ef2260a8a014b3c7212101eb18b0fc78ec307f37e18bc0fbdf09328bc407960f5c850459a20fe17a9ac953874e4b19f75ec9c97287a4658f3bfa60917e20b17df6e662649f665d0b2da3b362acd21bfa020987f9918be06917c1ebae5fb91f445bf7dd1a5d25bbd488c9dd814fdc28972b069240f7c78073d551c6c07dc6dd643af417c00c4a23109083e9d82f68dfb49bf84a92f9d9fc948928ba7720b3ae0a9cb0a327460872a0cbe1086249712c0f3198a37bb1a438683a298980cdee25fd99ca87980551c8fa1d18d57c1658402d0ad8eabb57148f1f8c64f37fcfe613f191a0ff957aed38d7b873675847d4b885b2dcc3fe28d41c48caa7069eb650ab9a2ffa33cbf6f43072d6609dc4d2cb192a43b53fd67c0e549b65f5a0360aa6246ca44db675d77b7fd9ec15bcd1dceb6da84d7ee855ddb7dca7891c44055e4788009416b198f5a82f290533565c18f4889b77cbe66054edfc31efd33a639b539d0814be5b5756c5c06ab84be4df37cda9eae6aac88397134b3e97c0eb64639c29377aa216fb535ada2d86d7d441724b2298e6c76a41fc56250cab16477100ca437276d021c21215452db5215d749c568e9fe92f69a27e79797c95e421be93ae2497971ea1b318e71e706e66f293187502b2c788fdaa9dedddb8f24a7e767df6b4e8734a7cd988d33e52d149bdee4eb7578912624e2aa2d7206178ebc414fef841aaddc77e78a499341995a26e1166b288ee5adfd5b31813692cf0cdd365919fb11b3e566e6cf1003f1f7eafb9326ad6264383fbf698a66ac2ff656fed3c568f1e63b114a4549a30b633435a2f1b6b74b7ebbec9a9add304f6cc55c2976165990ad993c9bb7a86e90e9a3219b64e7ae8c73eed25ce1aef76afa9b7a5f58caccc904bbae8a51af94edff0353799ad64cbd70ac8a371090b7879ea360fe156c46d859dad7d89b1a444d647b6f93d17009562764a32c47924762c99b4f4c53990f7589f3a5d19a5010c3aac375c7b2faf5d1b9eebd6b0234a785db84baf242a99e409205a20c5a76822be5a364f89531195adc7fa4a10aa1beed267181c706371dfd4331e6638bbe762d7ca7a2e0123eca1a32041bbe27ac63cd8a87acaa09f96d6c399e1b06435a0cd80c0c1dda988891413a6a77f50c20e10d301541a989c2a7003aee10864b01019ec21a5b7b03a454b46e2297eed7d8436980a7bd16af924de74e9d12a49f895f8ac759a343103cbbb63f904bb9ac01ac6686c1f80b1f5ce3e1f7d991ada16b2f9a884ea44ee87f6de7b78ed45d77cbc93cdf98b668727b518b8865e9edd9e28f385c44ddd63ff1fbd123b3d6e16da6250172bcfb2d1bd5aff50c8f465fbe3797ae387f2cb003214773f9f162ba2a50aa285d101ead34f85c586bb0df460872bcb969db24821b64f94e6cd0d9d498b821e5d5ae5fb9efd604e3f15d0bc879e634ae325481fd9a401d895812add6b0614c87a28956feda8937944c61fe76c9f0733dc2b5878e7ebf95728c4eac151b80ed0b338167d528e435885d73cbbda79a3f9c0e3d074dbbca283b8a91445b9add3b7b0197e29cd4b52a69c6841df1fb2e6c4a10639d693cdd9db1aef487747825224757b08b9ff3e66d76c2bc1075c40241f5ef6cca4a2fbd5bf161ea978e8cf9943b8970af717deec6a16a835ed3c0e6106c82213d0a3c724c40ebbc4c7041f4e658ecfb5d9a97029b8f1fce55760be4a2eacff5d037e28102848095b942b0c1607bc8b9fd788e0194b3014803a974c5c69d315f2f8f889711eedd47c301b50f3c6d4f41794a01e0b9be3630b0dbb3999882439426c567a15585cdb869bfc4e8922599857789eb86d4df864722c85e0a1e16e544668aedf839576690e002b79dc6f8362827f55a7c9066f69978c1c0e927b740ce3a8b93551d816dea0d7604f00629aa8a3bad8449842b61aa8707401e24a34573a0540bf6ac645cbe5857b141fb559b89405964dc99779b3ba347f605fbb940e4c72f4557761ed73d3565043a38b1d136511708420cefc09a625ecae3b9631e858d22d3d355d055b9cca76df3085b15c8a0d80fea0519a67480a2d8182efbf49d957331954e372602b42a3ae09ea33f9bce9f40ef3e9b3ad6b6ec50880f78ae8a04de4175cac0d509dac33040889ba1ebc108f206 +expected_result = pass +expected_shared_secret = f1be516b31ed89cb70bcf428a2ba2c22b3919f8a9824a59b875ff1e697095ae2 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +private_key = f75196a57024be817edc544dbd552f6b42ba121c2b8ea95e55017856a10c5905a8bb2590e63b449364802c6b438fc19eefc875017acf652a8f0d6ab0f7f5aca1f1833ed3551d37419d906d2b55123ec14d5f109abcd9382e990628bb30d882cca8665957346c3a08553c870d32f77e66348ca9dc321960b7d50b09de64178411439c021899f2b8c583762043a4508c3160544ed2264735c600a6ab43c8515532130583298a11450ae3b7c99ff559a1d33115dc2d2489934518bd52fba1cb9a019d918464b59cc90941599253957364dcca9f95a08035f8be5bd36db6b19f1f191a6e4b7fcd493b7a41c90bc76fe882aa0f3b39b6f454785c5dd1d106c80960bbe5846d90bcde837cd277a039dc22427b86a6658f97a60101665f3f69125445647f3bb2d3125c80d89aae6096a01c24902321933909a8a2925faa1e7407b3c90c8a53d958c1c83465e557ab620e53509ee8c960b3c547fea08d4ffa215742113ed9661b57ae1b30ba5768645c632de76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0863273c345c4c7379cf3f873fa5953f53b9a026a4dc120c96e279085566c7d090eba276a0928693e639b5564a59c08aeafd25915f5478dd86e938a11529bb9a2b0b83487c696e79f1fd034ef000fa502328184be42b8959d9c0683f3bc20e71902423ab14a4744e162f6a2b474dbc4a6f21fc0432ca7422cfb253d0f952be9c13125458df8753f5d551caa38bcca1625b533051c5226c8768335854e7477064320cb765ab9eb311a1859b4b5a006d918bd8508a971205e6902897cf95e0b652e09030794b46fcf7a784560c0a18b8e6334a57ec177ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa0104063696f1020bd1b443419989798826e141a24a3533494391fa233cf848451cbd609d014508fe137534c42d6f22ed2cb82363c847865aa243ca993b14992572cbf5535845cc708bb09a1e8a7834c200d8036768755afab53aba85813eb859ee83efea7563ee4bc158599f0cb04033393c829aedbda289ed852e1eb1feda9484777051f967e048041ba3c313a1414d463cf3ec36801aaa1aa540deab122ab530ecaca30101a1089087311972b338b045a1637189020c3030e63f707feea9af844c7e1b20b4a5348c1a432f341bb9f598b8c0c2f6f55c4d2c2c22b187430748f82842daba92283dbc4bd20636b6754b20a7127f01fcfd4013a1155e4746dbf3ca1f34991fe7c39ed99bdf5760d39db8e6c428f2de8157be0139415aea96bcf6fab633f2257b582312d3c7acaf6a5f8e55ad699672160ca01246545059e58502e28199cd0f5505adcb91900a283f0b059f33d1a8b352010a3c815717fb3a9482c946df0c74a526353d5c9ecd2590c5050996393a02286841580ab599bfbc8838a53301bb11d5fd492af40ba26224505969d88f6b193ea42b0348954180e17124ec2c64b962a92aa9c3fe2d72f94301531c4aaf847243702bc8f9c37d64b54f20ac003b844c52417e1436d2e75ac09c313c83b8575e791a7c95d0412cc61521a6826997561485dec26ad7baa8e065e9a279add7301c5c74c5b95c1b6915e69c9a6d4b4679fa180aca9817d6817e17314da19501344231a58c8547148cbf38081a8889c00cdf77234d04169ece6bf0abca31517c986c44ce771a32feca99df60524380323b31d92c9c100749825f30e1f7c9c079907a5750e3f8b18ad040194092093e7934219a5b11b4028281030774818416d53854975241efc6bb8bb751c5069b7099671d0768f3bf74219142e88e08e58642b41b04eb66324392b094fd0740cd4585a27ccb3f25ef972cc26b9512c1900f8b61040ea7921d21f142c7e1a99b886e32bb80721e6c75f6a999328a2abbc3c797965c09b2081671346355b4bf8c78c72c6cd98d0116db3423a1b69a0f80515e423bc1bc6522b5fc77abe492740d6fa8227235e3b7226fd89064ca494e9012f1cc62b02f95523f147bb321938cc1fafa4323173a8df6264959a5a6052a3b218622007af0408c3227a053dcb71164c9a80cb844f59050b113f497aa3a65c11c317c9e6b6a6e8028c23fb4589046a70db1026f07aba9b45ec78ca14d9babcbc2e62ea6130d8414e98b85de8a908aa6ac1e96fd9ea9bf4595a7cd565d91416b583be0c3355ef18b9b4bc1ea59135d3701eed6bb0b66bb320572189525bf4804a8d75a5f973393cf53ebed81a1f2ca339016e35617e77b58a38e15d417043e6174888ea4408cc8583d196042317f3c9571e6347424c032dd459ecb873d7f9312fe891a0a81261136690363b816a3b538923e56741cccbc86d477c629a1713e99a4be8aae2b3516e863ef232755fa0025e40a664b714bb5c8b2a42568d824246d069ba2469ca370c1417a6a632978dd39503e433ac8566708c21ab04924d257e8002804e92147db57a8d39168c709563e7604674ae830c176914ca2ed38b9e793515231b7e15b5dbac4027daafb276099c0036f81621f7dbac5d24c5067023dc6b219881cdb9f290bb9454adb45a45eb1b975b1094aab8b2a9afe05a8240476753ba802c15495c5034f9348ec8c732724c9703e9a08220854a29598cf42b6777a19eb462c4907f0a7b5a3e991a5d7c4d8a70a78ed5cd35dacf9e98c19c596ccc1c4710ec9b029700acc002a1c661c13ba1c25a1d853a851054546c33b1f4032e1f089e9c4c8af9a99c3c72ae4077272c3a37839b817b55a31ba99b66580766fa2180c35a50462c0b98adc38c6ac1d72a7396b28e36cb6a601cdf7c9857f5413d380a1d031bb5801890182518ec414dd78a8ef86edfc0a1f10572205b5593623c41d873da21aa60e3870348032497b367bb50dc6176d415ba54f8809b4155462ac6d34593fbf57fc7d5bf64c10af1ba368d52afc8e2ca3ff8467528c625b26709122c6b1b34648247849338a24005aa9100a790b054640ed59383eccb6415f7a15f2aca63cac12609113d843aea83814691072ab8292b7c5db1d973aa6c7b2bd1a4aeb4bb1d58ca7da26b2e0296211042488c0dabc511308791d7a8ae725c922ef374acc53d76ba5a12fb2a5bb94c309824ee119c87a62f5786996800af28d11e59a83de0504413351651d0209e98b76513747d087333702cff8463db4c353557632c8c46c3667623e012e5d7937f6b004bb549960c5760d15d08d1a4e85c288a2044d1362aba2962d2b078b7854f997abf6072c390342536a8ae8f62385a5770d4752db9f979fa09037bcbae54d4583e17c4be538100349a379502dc69c283638ecda028ba0cb1d21426334c4789715cb39c79cf408c2d1720afc8986de03627b28efb773ee612630b2ca1a0a81239b6020e1380ac69be3cf3742014c52f9b22a118aae7092efe8c93705c0a7a1a8849c0216f776695840bb0a168d5b991e4ca78af08255646000fd16373831f8ed490724019aa15c57307bf06011392859167d0ca6fe88feedb49878c7bb0609aeb604429710db83b1fa592c7a5e911ce795e093a9602875700306d38234e2a70bfad422df30380986533bcec5d8c119bdf3b99e1596a05a123e2d3acca83031ff778c2181f75d268d6aa98520c969306cc80863789724c0ec5552eca57c3d84fa141c69e07b39d9518bcb52049ea04145c34ad355cdf65cf6c1014f511b9c6bb9281fa243000781a99301c06b77ed606c0fa1eb5987e76aa5bb346cc85c85aca114cd0a51c06448c1eab496299515d7a1598940c33c8bc58db4486867158a09080b97674cc9a9f7a176fd5034c139b19a50d4355011e2b65d47ab642c84812c74dc16a83fedc38873145ff3143564c4aacf969f34ba743a14595bb0b5000c30b47662a7b4eabc0980aeca368573550c3148811386ee589a88a53cbc6be1ab2755e58441b6c87e83baba58b63bfd097f0d4922ea7c0aff97143666d912199fc4307a3bc086ab13d6a6481f411bf780b10f5e04a41f27f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9630c2c0dc6bf3987789bb59195f416f8661e6f5395839c68a0d85d13d0ccff807956a28124e47b5b3c9f3aeb9537c3403671c03d28a09610c89c8c6c69d9733b320382a84a6cc2b9407743cc66611e84999d11356115060e6c2c5f9610fa820d18b355b64890b0a88fe784a39ac0c9e539732d79a36832492439944b643436b84d4bc870b5c21a5e224e321a5e7a6931e628342ed4616fb4b1997cb12fe6be06b20e7794437512be498aca2c532c3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bdb8aa8568431ffc4681caacecd4475c838cf7348402a06413e7a9590ba405ea5e79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = ea8abbfdb194d0c3034901ff96488866e79fb029a7765138a85feedccc7429ed2881a8193fb0b83b49adac508b6d4da1c816fcb4ca95c9c65f4cb761c7d0fe050f60c295a554930abd90ec1fcc151332849b488c9c506a3a704a1cbd74c56726dbf1d1da97d058382b158803a25aaf6229930cacda8e990d6b6b917c222667ee8d1580680f87dee5816de3d2af2b874bb5ecaff31673ee28a02b58c59761651fb776d8f8ed8534e9607de88ec36fd3ec9c041f4e2ea1918ae57a7cf676f381a27e9047e940fe6875647dbb6453740809aa067818d8b8f1e1df6bbd2cf8f2b1e3cbc7499466cc41ace193eda019729e4cb451643790f30f5fd05887ebe9e4250bb47005133b3392fe282bf569a6c69c96815a34fa9af0db7ba1cc8786f7f8ae095463601783907932ad5fc2e626b72217189b93fc390556f06232b9a5ec5760f4069b15ebc878c3050360103faa7355e81ea267094e9064fc550e0337462bc20bc511c044065dfd8f1b014945bcd9be4953b4d4b99ffc633947b0b19b3feacab69cfbb261d6ef365f9802e7be7528d718aa353b05a49b1ce782f8370852ec7589980d0e2dce9d90d76010ffa317bf50b49ff31ab4f4828de281d75c3644e63f383a91ccd3a2cbed9df8fffc533c8f380c80e6352da9a36527938f227395f38d1db181481c65e3fba3ff787e463b241323b05132da8c648b4c8e257b8770f5235120d1a47ba2e68fb5a7e3b96770c57cf8b4f7f86f568cc0b7715d584ddc7bbfdc2b7ed559b2ea88e44ef2c2af0c4e5c0686f37769474b4c714bbab23f12ad0f232777d528c2ee89be7cce992cabfa8aac02336f327c2275b63ef927b010bf29ee1ea7b54476c8a064cb928c3096fe722f93408426231ce9f59f8984caddb27e25bf2179307e666503de33dd6296e312c2e92a3f05af31e81e5ffd1719298401dd2b3f104dcdfbfc31f06cafd0841bd319e50434a7457363947e6ac60955fc8cf2f02bd518b3af0ad77bb6f0da7bcda27ff22d8203d5b3bac070375332cb42d6ef895e4c48b47737b607ed9c1f86de6f2c251683708c193297c353b9a2348daf4d35f4c56a9b87c70f6d32ab17b15f62efab893eca7d269c5505f229b360c604230fedecdd732c0fde78f5d7dc6b8f61655e7eacf9351cfe79ec3a6880f84fd5d09037562c7c30bde8b7db5e672f4210111dd773e27a346412c9a32ca6bbd992b5b7dbe0eefeec512d8a1ec547a8a429c0033f59999eadb257e671be8852095b487e3ce21dcc41aef7efe8c520c52d6aad34451feaa77da8a18546be3d5bd3a24a15c5a0efe090d11798ee1c378b181bfa78b9c79f9509ee94420b5383c51e1f21ef30f95c109dcc534febab2eddb8438da19360f1a5a9ad80e3bb4bdadb8f68d23db60ad9a948b17682ac706e30f64eaca334331f6e9f665ebca0bee9b3fe153437a6356cda49db7b30fdb23b55e0b52ca1b54a115a179309f4763e70c7edfe6fa8cb28d3ff9259397005d4ff4d23915e5698df64c19ad60f24163a4d0c03f682bbae2864e5a446a5ad9bd4cadb8c7e02e8ed83e646ddfba1aceb34eba2bdb6ce854e1aa40b7e75d5a365e774e1639e3230b9f6a4b25493798ee0116365687c13b8be2041c37d81007c66085625143a0b4776483dcd25f4cbfcd42894963241760c1d66371c21413273d8a3ddeaab5e9ab5e00cede4547a3442065b057a7011576a52e4f1c5411d432e94a516532e881a28f3519211e58c25acf0200c8a55f272fb190bdb8af0bcfc4a6867870d4d06494e6105ec386b970dd0cd942853fd98505c4c36676a1d3a986aaef6401c7d31aad6e425ad2047ea3964cb065e714e35891ab5ef5103744d43ed6c4f2f0f563ca3295f7d9bd58a3a2765dfa4a04a055b6ed1a610682139ad91def5a5e5545e526b690d49356b5b9c565501e1576e3873780ca61ecd2b6ecd89f9fd3384b18b0d5f90742f4cefb0516013151c77490fbb2621ef28bba3bd0ff6252d363c224bc27a5384c700005fa94d93ab17b5733dfe45b60fa9bea0168c617e15e37f99b538a9d4b03403913c385a963f2eeb46058709b285aa383b73b004cb89e5e735afeab81bd40d80b7ffd84df84a1bd414762f8312b44f1ffb2004194b9c34f3708059eeaa9c09cf67a98d7a3a35e87b9e18af7afa188c9eecb0a1d5e048b514cb446d6a4bc30e96ff244f07dca9f290699a650c +expected_result = pass +expected_shared_secret = 6ec4f71386c0f0c16294e4d76966c69c512d4e5e00a6e05c5aa544e542454225 + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +private_key = f8fb5ba9d24c8681558cd13593f0cebb335b6f65bd5dda6de6d19e09f15165051f981ac6472b263cec43883a79149707093066fc129ae148b04f860c2df119f8a51056eaa5dfd89bfc564226e56dc391ade1cc2a1df58edd4572c5a147bbe21283b97f1b213bc276a471b63a7df1cdc86c7a69a34ed17a425b37aef969c1cd079529ba29a2e2c3412c5615e23523f3124c00c778752bb9b3677b90885cc21b0e257bb7f335fd53928b737d19da3b3208219e6c898e96b45f801135a09a1425a0986c597e2b4042c1a4e6d7a4d0e30e729c73f2bbbe85b579c3c13a34344a7403b95d425936486c3b602804c08ef6f5ab22c400b9523ea3345abfe666023bce6a1b63a872c33e3aaf0ccac2c40a4d5a48107d0c7ab09001ea67ca6f4c1fa7137d259c860d032c396bcbcb4177f82439852463b640855ce604f91c8f2e4a0899b2102c6059dc077d5ee6054355c546c2148077b8defbc313c71f1a420dace126b16c21e40064e2522f9e224cc8e3526b1a99a2f4a81efc2dd3609043246d461c7c1af025b56a9c7e72adea57584cf044c2f0bb60352c32400d1631c034572ee46b71edbc0334031aed7bc26af543028c3918109da52a6abf3217a2219c0607ba9edab5b4daad5ec7948393c4a670c340688541aa713b596843e5ccb9616b54e92610539bfd39159fab36d4928ee9cc8b1291ac0134257e242faeb595100ac113ac416ff517866021b550b6d063512dc37477117d025964c95c13535c2f09a96740037fe1846efec4446ec03f93fa6b6fd8b539f0196444a61823b08cb74b7520618c08324f0667f142beb3a34c2c5286b3d159fce3b046079f07e558ba28a8893a8c94f9711c227fac6900114c8bb6aa5369b059dbbca008482a1843b62a1b06c68c6b2f40bac6f02b6cac1633055a178a396ef35f59f1a76543953d3b07e2b8be217c5d5b1a82f9c080f4119d22275958026280bb8c96626c1d0baea6658a29546e09418aaf85a121f8647cb4789484bee0189b9ab10852c397a2e25b9b15b71ef17440dc3554db740289ba05111979614aedcca79699021f4bc3a4c68b39d0256d88cdd7a24e3ac31dac35388720671a12a765d705f8429d0891c3e0d8062ad45a0b882bc53016dfb007d1c550998963d7e12fa51c7361d86156ea3a8ad7018c627a9ea18f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50e8170892a08fd15cf2913749d0c61305c4de45a1ba2550009726a0873c70049705009dc8327be3610f61f9bc60a26d14dc0c3e67cdae4b5ac0d5a0638804d6c6b4ceb351f0c19f0974324cfa28fab704b4677aa3f2bf65686c22100b74cb9ab5f7215452cbe8d6909754304573a9314b3c8362cfc34c6302b3cbd5dc482e76576fc5900b367016c03a860a88744928cae55413231ca8a5008d210cd2e317d1bb6bc8624ecb83002e66092d8aa77fa0c6766532178a8cfb532c70f1114e5156e91486c3c7658e2a22cf0a77873c944a5a4bd70ba1686146e18b328d30813c9850c3003698c5afa2082b3425c785200596592fbfd7b2ad5568f9d278fa24c523251bfc966a69ca882e707426563d2e099295305fe2e2a96f968a92e9423dc4a1f6662f68299850f81da13ac23e272a8b64be3ff3bfe61563fc98c555ecc6625b7a84c79c6550c399977ceea525b12a52f9098191b004cc6b83a8d89a63756ca9460fd21758a0701e5e71280055cd3ec2a218168d38e78861ca2d0ec6c56a880f5091ce656bc4dee3a8061801255865067982744439e83b893b3055f67466a8b722ee0339c46160d4c40cd92a2ed5601199e5b214c9c48d311e3b26032377b637ca10c5579b7bb381c25bb7bb82159b0b1ac9592a9e9817ccd8b85631adc7c44ca1f6a8e7529782302dd2266fb0a7b04fc16857f034b50b37b723b42e747947e1a6ffb1c8162181be23a1c82ace8d4a1bf522143e495c39bb9e63f17768411289087258e6a07192656c7269ad688bbc5cb66f094737dbb85ef146c0cb146c7010ccca769aab3d0e3b52fc61b637a02bf0c7bdab750bb7a9a367302a4f3115f352675b2b458eeba2db040db45abb314c5583785925bc833f82caf0d6687f87220652886aba525cf89900e0b6fe4493ca61cab752261a432cd34121ec58348f1aa59d4476ec8b5da936ad0edb0ae5a6b9a66bab5538cab0ac6e0430bebd798c474ba1ec345ea6d3ba9fa0377d46606e70c86dd1be281a9f46fbc0d890c607dc009f46b459958989852b5582566cd30d02317cd4e0b84e6b1917e692e45c9beae45bc8e8bf6a65587f206a67d93a4872c571200bbde620e2639659302068088bb2d8bddf33c98ef34541b4c2a22897815b809b060f86200aaea90376234860a66e9e8843bb52ca7033010e47c41d573fd9ba40c4faad88026eca797e80396a2ed5586f8109a44bcac355117a7a3f72950030cc506482aa0ce39369bb350fb07b1388981c89400ab5a632c172d159c6f0e126bec96e17c0c18c615be5110818e0cfc2900f76d706aec990021aad6eca787b453991a896f4622537051e3e4a11a0954995525b8f2b11583a3a3e594400ac97b82a4b5da822891910c721ab0bbb9942f2ba777a0c5d8c532393934b391fe5669850bab01740905b684aaa96be0cf50df463406b91a28149174b555c742c3f78569bf294681ca09a336531edb94bf30459893cb2de348330fc56a7304ae2f7cc33d13b7966751414420dd089a48a6036c1cd7c5608727b52612864b63694005590859aadd91b068b053453d1c6f9287c58aa042073087f7959fa932284231b39aa991c0523be599ce85b1f0fb52d465156c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eab32960332860e2a25b7a25e86d0a7aab0226e877f0488877d941fc0a0541461b8a4744de6456df6c5ae6c621a969a02f9c943f68a48809328a0ba3892d7af2fe169ee41554f0ac1a3836e151760c8472f60b77e274948ecb6748c404a74005bde6c5849401fe2d667748b9f3c19a41d659474b0b4a6829d848a898b93080c66aae85b3660d392f34a6ee9c6b10df567dce1892f4932b6babe31e0a50f8217985c6537188b817b3311c25e8c63ca265b568ba9cfdd451e6fd517e18317fb99c8204abfdc937134e845cfe00018e097022997653a8d5be32cfb07b34836c242b74ef9d30ba0d7ad8c2b2944c766c025804eab23a05b6fe6b85d331904c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2e70e1a63815c760da8195bfd431a9fd88443e26dde85c5b08091cb19349cfc73ba195923a38ab6a044d1c9cbe498195c1b5a27a2b07b627c141cac61d391ff1b88c9893327447d32234705d42f10374b77c86d83d71e3711893188310c45c51a5473003d8566d87fde99c67b962f6b4750d7851d3b6201a2faae68fcb1011404b252bcdb341e68702c8dd6a237813e049c42aac05977637cd3c81103e1973f6b45b8b0b56f69afffc9cb5e97bae9b6c5809abaf47b5b0b20471bd77ec7455e1dc25fbfaa7018e58133a44678083c06e06334452890a35240526225a33736a042b1595da8452c2eba086acc1a6cba45beccbdfa23acb2f01cbeb75ff179cb39242ceac33eb2889c4784cb970938ad336da5dc013aaa2973043372cb99657297e7ca05702992b578a65c00c867b43eaca93e975695f7625aa8240c0e5827e1636d72ec4a0480408f911ef631b48a1c4462665b230550924b23481bade7b43a1d76cbe6791e33874182f955313cbe69bab35aa59cd1b133fc326ba571713a1c4dbe2a662b514021bc7bae44343f39138444173dd7944c6291c50973ff0b9c0aacad9409881ac232306354d5362537b507e2ab84b4a0a3b5b9819e62c3b6dc1fcbba0224b48da7114dd4fa3103069caba17c09b7bbef8b94b6e15f58321b708c9c23a40288708ccec56f3fa2bcc7397101fb9e54fcb7e7e816f149356570a006f69779fa6e30b1310e6bc6d983599eb81c202c5e887659f5e7836fb7a72eb80474116c6659c24dfc4c38dc2e8d6a0787a3b6c170a23ba53865a53849f4c3f25b2363e582bdf079793bcb832878b0f7268f658b72b3417135684393a4b1f40322ba7fb147416ff0b58d3b62a7343a6c51b4c8f6894f0b05e33476ba24c61c276652048b009ccc1a768e48cac707a42f4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2ed2429d547b4da5176a7b621a38681ccb3e72d98f1f9926b1b30325d6cbd3862c7d044dc16b8a25dc59c2a53e295040d7627f744bcdafeb522cf8ca6eaca400106b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984984f4c4ef2371654067ce0f22bbe4648dc9d87eee23842f31affcdc36328e8db1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = f513d8cc0665dd76133ac4e7ea22b5056763fc59a9afaaf2b4f583c9ff4347a2b3dc968d66775ce0f71b8895e79f4925f984d20349967c0259734e87e2b2dd59f86a89c2dd4a7a16cd8c67c2ea4c0e863c0b6043a73651f0a7a927399ae7bd4a31cfd904c2293cda2f28cc16a3a3d0311e044b55c8a6a89e147833cc06b5ce9f9f8f745e8ed3e3499079d480c81546ea970ff389eb49e29bdc46f852732ed9cbba2cd47105d6b52c812d91492fa750556e73ed832c194b9bddab98e76e8d939b95984397da789125212bab18dea5ae3c22cdf029f9c0250cb12015f380b33ba45482bb10ebf412d10633d74f7e7a7f63d162ca1c51c14d8799ae2234b2396f38732ad355b7a173a7cbc229cb9d252f7fd6c5d09ab41d20395e5887cf586c63a21d76a4e3e00413bf0af8ac22378f6d87067a3090dcfd60d242719f8d7bce6a281af3c29685c453354eb4721c2ea92b5937742f0c68d2d2ca30fb459153e7a371a7515130c20ca816ecadcbc4ff4969c033c81e52d9249588e854f063a79d6aa181e31ff1cd8eaec38119cf051e84351a3b8570b43dc6d921ebbdcba47f30a7a237e3a74de67b5d59a7f06c8b6fb13e810a9895c9e4bebccd649793ace6f226f3fb9f04c39aeecc9a7f0c5a8d82d862954d7aafd945702464640ba5c16c4df0f1b9122f9dc6942bf9ab261d7b65139557e8dcad44ef29b5a96557c07a311dda243b4c9fed3344ca0b647617eef8d7fdd3942982958d599da0fa786b40b5830fb5e05e32a0d6bfa3141905d4a1b99b8dce6d0bf53212b72454817239dc1d4b8431d4a2acb087fafdb68a326ae4c28f372db791a9c654a079a1d915a25e2dfa117af68d9e0a8f624a298a390e688cc4e8356dd52fe42569f796daab5610c7b2ac4bc7e1e3801c91a49d420e661b9432d930a10dd1eaa04d283e05b3ec41f821cc56f9bfb1eae60338ba0eab94f02d4dd043eef6d6c651b4efc3fb3fd48ef2c420087719e68a790e1d5a7e60fc292a0be640993327a68e5d3423c6df76c51bdc3a787eb23b11a49067f66d2cda3bc4d0fe7c7235b75f00872647581b75afb0b2555e85b8455a0298580e4f0f5b20c57503f2bc541549ba7c72b9d24f28e4ae3f9e0930bda648a243f5c4f473f87d3777333c7571c4981c081992fce9755daed0a97fc4261ed48af7bd55dbc7172a296488acc6ba32db0c3e277c7785e9e78d79509add74de0d15131ea9d1a31817db156e275cbf3334b48c39c8a27387549a92ef80aed8a830cde142ef9109d0c7db8da348697915d91e0bf0a819657c1521ede55af68dd1bc7aca0e7c0feb04d34b89b93df3e591e508ac7f0e3cb4ac98e28d207f2a105a4779ad594af98ca35f1d4b9f2f6babca73ab0f33f4a3011e81d6d74d183cd9eb33bdd7683eeae9efd5f15d0a847db8464ce2d0510da5d8664c9e688a58016e9203f7a3e02eef0c19204fb083f20cfbfb574a3d7b5af99b4f698f0c6248a1c2b1d8989b792abdbb4cc14d04432d56b63f99711e234c3c8fbf26a61769e8f0a251635f0e8faf0eb99a0c2965f1b4ba9804d4090cc5adf1a8c5f9bbd1e7ff0065296dc99a9e6dbf5a4e0dce4b5538b0f1c48f02d0d66a77c3a0c1bcc87b1353a83214218d0be833f3caf5abb13000682b1148623c1cea256c1dc7becfe14b698cea823e58378e1ca704878da44c7a4364a8652cad214df0f6e7be10423f308ec0422000f911bc7c5038eca2d155876da42da83ab23b732251049c007d4f7e1ef7bb35aeb43dc3c730b8d70a9e2e04e5ab0cb1c31d5dccd158b1977208404f8405a6f7a0f48c29768897519f21a8bef1d0da7bf4512d34730bf4cd1fa80afb5034d662a6ac860ae39819d82c6bc7886358a15ff8183f6f3f76f601a1286ae7367e82cb7d4a5a7d814248bac54ad36e6624532536c0f9932fd88a5c79b5615bf42ceeda21129ebdd38297149e59df243500f6453b4886acb80ce1c9ef44ae7a54c8a6e8d4da7b9c34c2ecfe206b6a0537e63749ddeadb645fa1f937c9f7d19acc9119462cd7be43fdfb5efb350c9f59cbc12995d1428edeb0ea90582d985ed0381dc586dc5216fbb5bee11cf8547499f0783c318417a8f7ee101b3f01d99d489876ca4e094f8cab6f6158daacfc9f21e830e798d1e7fd91329f59344ed126df11862b8a355d1b7b567e5676d09e9a9e3dcba5f42e7989a761c26e2b391a8470 +expected_result = pass +expected_shared_secret = 464274dd39f2862a97833631ac446642b3c3dd6467c7d2404aaa46a8f5f65b3f + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +private_key = 5b47b61ce23572623c431a498e378c6b71a5cdccb58e225310217f6f2b1b7140b97349b965d9c95332a66d7a9879f24c479851a0ea485254755db347bff9a06d00502ae3a910c06771aacc0a51add07a291496ac10e2899b6562dcda7b6b9b7eb516335d222c43498859d87a44cb8ad589a06e609fc5798ca06744051533d5c6154608c790a8abd776cbd2984b57e1cf4e0638c77915dd89249d3c0775b45cc159b44bd32f49a51a1e398763e35dbf5c6ccb100929c9b91047a1ab98a140e00f77f5076310c33179a8c80449591c4156c244eb8c8b3009328139c18f8c59e1961a2b91c840d552c2e4b3897265b16c28de6abb72d218ef713a1d179cea38561663c9bf21b68166aaa45748316877a9a5bed6f5230d3015193aa5a9e1b34dc6576b57692b543fff321b14879a24728de3d6a297c06ac6cb28ec3482da708abab28fa815272624af6e26a879f65c6432812470c52de01edce20681db43a967069dc9bb34f9c540a21b8d7322a3675fee059f5f655cfc480ba31255e899c48a7c25588303d67055434702ecca24d31a9d69796df408328912ada084ab122c6ac53c3c349c105270c9aeac73923614ea9129ce4c9fd8d78bd33045d8557ad3d0a698b34a7c073b93783670662f8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dee04497c997c9e74044230690354b7af23bd94aa02cf599554391095c0d53f5c1db19ac33189b2b9aa3c48bc4e09bcdc5029bd3b45a370c59045abcbfb257ddf30085da053056c17dd0b5ddc6494524875ac189e6c7a7cd483288f03abc155bc2022eb427b7d5093f4616c124b7c29a0043181c7bded83de7592511e3617a75652d4568d7c7b3ab2b7464c514ce6ccf54fa8d73e61834e534966620dc59196ab44b736151a27c02e065a000611542fc296a69a24989331ef980f708142d7274ea863669a52039b59d48b90bcc75ce4b434f5751cef621cf3a29873c003a57276128e70bb4aa5de581834946741a8134890491d37b6051959739fa8eb81c6947141704683124136c1c382760e13f00c59ab5bcbcef98b973831b91ba87fec02216619f012859faa6b01b1649786b626348182398226cf794095681d1c25800b18bf33cc71123898ad2aee46905a8118916ba8651328a051697f8041667789c874394e96a0efcda8998d420684217952496ae9117c6c618513c147148979f5c8bfef8c7ca1836430c3cfb66b17cbca63ed1a2157961cee600617157aad986b5021f4f69c3bee6ae181a076c3cabf076903bd59814352f4ee2c04a138ae0eb018a2193ced58981caa3bb032317499e6ec4bc5cfab8b389467ef295dbe7305bd1cd099364d7596b1801008ed734d7775c5606af0f1a2978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad10a025f46af233512b126230cf928fac14d753160bad961bdcc4d5e1b4edd241609a0adc6b3c6cc9660e5371d6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aabe0bf05f75ed0b092f332aa83808f897ba21906af25e68a88b61a357a10ece1977199203e465ef9bc020e145f6421abd11b18ab198549b67b4f0c11fd7b001e43731f2383f62ab90adb3e13197db7279020d212105236fbd8746722a99606b522c69648543f9e65558162235ceca379905100a2b98f32824ba288aa3cb7dc1734bd49c0769cc5a44483e0317dc62961471b195483683f774243e689ff504c02ec73e04b5731c49d0853494adccd6608a575388d245a312a1a38f1f9a17d26073eb3b6fe41175f362dfc697ce5d2cda6b0145a739e7879c17e277de2750733c9b539a915585c237cbb66cd4b1afa425ac5f22f06724ea5783b579331928b57a9fc407c56541117c8665aaa2df1ad0dd20d6a2911faf73c9e653d6baa0ee73720dbfca1f5ba6a1db99e0f87955fb85a253105156a2b9fd3c35c8ab458023ce3d381132b488c122beaf1b740a526513b31b63cca1ca8389f9a26e22c3ff1d50b42e3c71cfbc4465745dcd28b3811bb29e52558735145ec799614926f5a55d57c640f673e4fb176e8f56f73aba60e60a4cf464373f5104416c6ceb386b4518c7d154b86e58a04b2337f1ab43660b312f0c905bc776461a7a463b8e40c03739a6b5fd196655871adb3c82ad10fb2b2b538e61e1b664fbaf761f09b4d5e358b518088b3206e1295bfd0461a2ff8553b40cb92e36f0f928af9fc7ef54c358d88280697ac3d5548029c3faf882ae2da732e0c47934b9c98232c40b84a344421e708226ca6524c062302765bf4d593e2d75d3a783f1dd7328767315dda868e685eabc18fdaec2ca8b037fdc3607629cc3ecc8e848c771b94c6a20a28e3003778ba68b923b711060bb6152554707d7e4c135ae8663d87643ec4921c6a5c20ac69e67b0b795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e7b03189abf9b4a91eb782fed97bc3a6314d0ccb528b313d165b2910859de867d7d6290bbc85185b0201561af34b9656a00b2ec32323b26a04888786f81007362814bcc82862a7280a5cee73a330e6c2e01fc9afe2741b12166949532c884ce8bf2281aa4b860756463bb49bd1524b8ccc6ecb6051ada819865b8bbe1bb01141b77fa3ff5713f95baac10866303939c07483b6bfc500d61b7ad494382c643e87508e410c30fe96b37960ad4e707421944b13b31d6686745c52ef6ca4fff3074f19c1695038367b1218e8b08d8e6180870b0fe5b5511e3b4641b6fa44156c561aa2aa9a1e163aacf73c24d84bb764004b3b329ddcb0f15716e17c51c6c432ba1407c0d063b0cf2c073763a790cd0312abe6d26b0d75390492a88772763fcf67e1bf28e1a01c0a5714bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5e80acca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f052450875a8997c335ae85d5b790377301f5a094a5b43b515206067e36fe51ab9af296583d47450a34a302844b0526a4ef891d01c287602453126557a876c583c2a06561a88f9651e39929d0b43fccba48595925c01adc0677200c39c64e44505aa58a9b5c88311c094dc3aa5314f167247b501798c4a0d5d9a04b77c6552369542e96172573e727890fa3b2e3551286113221fe92f81c481c125bfa7a6199ef8c0eeaa0a5b8973c9a33807a464fd4a50eb294741c5a8fd998171872c0fd44ec86112e19a707dec768f7245dd2a6f60a554490947e5152dc3eb9d9e7151ff7188127b5313757431d3a41c673e203c7e8e9963d0ab1276b5c1114c38ec8cc0ba0a94918cbccdcc7dc5366704415cd2ab9a7fe55ed49498b8b7105fb312f4a153e394a019749a23dcc180236468a47d96d47be66a0cdfd16a2dd15aef826041192b8028b1ea782fbf0a2cd5fab19011b219099f8e87c74cc69841f4a927e181e98ac6b3db7846ec38c0ba8aa9f50ba7a423a474060ef165299b12786bc8c05a384ef129b0f6c06c1047e582c02a54aa8713422bb6b9a6a4195fe6843d7c639916943b5793107cb8e63365dab357cc02a9f1b33e8da29f25f9839d862285864ba790bf965292470965e0a9c1d1f65b72139908d791a4d89e489a983279a703a0c34222786e123b45c793c925b1a146c006f15fb4a1c85e181f8b1c6983e1a1d7210c12091d83439ac8a15d965a386be47145bb946162cb8869b359654121092d81947ccb5717e805478a7c0ea924692b361ccb730f3180c8f79041f8d366757528b0828b7ff9531c76690c37cd8072ccb1c36a195a84197a8797446273d686aea96fefc153f1710d98229abf35b6e6127f2e5a5c9e88a33a85a1006a1383988e3c72692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f0362c1f84954408ba3c9284442b59c1a4904128c0bbb50b2e34c98b819a1d6793de75697cd814ee162ae3dacc0d50bade8b835c3f27126731d2721ab61802f544967df987b5b0b02efbc95847a5f06113737e55ca4db20c4400580b5c241016b50db710d7555d8f67cca13b2d86103d3870d5713b217d03b3984334a6ca272d43911ec23db3b5c15139efcd510a95c96d68a70d2988adbd048122678ac8a051282bb4fb47d6d5819a3a9866571cf53b78ed80a76ffecc971b221bfb917bc69018dc0177468357292495d98a022634ea7b0b1f517734ee40d0e927919221ce9eabfa05596a801a342b87267ac9047129995630271c1c2f02a4d1af2217b65c05609b8745306b6a90f86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a174841a59db1202eb2e3744bb36b9c5a229a33cf9eeafca4b3d02d155d870b6bf62d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = da9300af63d3c10ab2a839f3a2e3375613529a345f92182ec42f0212a041d741c6b0963202359ab3e443104a935086117a43bec2bea7ebb7e5f6151c39d2cef855c2f725ca7d4f4d1ffda1752f834636baf6ad31f4245077683ee725316bceae73a44012afa9e923e851a93a74f32d94c47617bb7cfd1f659d81b1c0e8ad2f3c5fa54eef5aaa1b763c573a2d1298055ee6623f31694078cd0a4ce9cd047e2a591377437741296c28773d4d711d7ee8fd4e5b376199d42d86482dcf9fc84af2354b858ff6ef1cc3692ca1e0ddacc17ce13c739544002cf8748dc3ce62418941533da39cde819215927fdf87c4e5f9da167d03dd8a1bf91c89b007cd0434b045ab4f09dbeabee5cb93aa90d59da49c1347d5e9464c6a07c1546f734852f486f9b06cecabc380bc09ff888ee90c4093eefd9354658a26270c0c4f5ec4a489fe6fcdc55f872e9f6443cba943636eebfc49c801a2434a16ae0edbab19c3da71fab90f2a48452532a914ef0034837cd1bc08d9ae64ca3110822aab9daa043658f666f38a913042db83b1a842e463cf9dd42277be70b240b2c4563bddda5d629913815c6c7fde5bac736151cc3a39c773a55190de33d233ada200850c3cda654a37adeb5b643c8daa3e39ba68edfee6ef904b1dde292fa197899bd5455bedff84bd504b48ba00beef905a1cf8bd512c79b847d5dc4489f1a3c0e1394a7edbf4468e8d1747d1fa9a877b4a06580e3126349312d28865c81d59a375311e081497f9fcb6f9ba2530a71ab2903c52cc7707c6269d3ef67918ffbef0aadbe002d60999a41c8634d5ac8e84b4bbe5292fbe735b58ee3bf8ebda070b58a5a699984eb1a5e15c35b49a3ac58d23cf8e472ee49a2b26ad0ad3fce13c18efd85e9fcd455fea61d135c2083b792b503f43f729b27b02d30864e60a8702b749e91c3493872a15d173844cf30cc9eeef4e2dfcaa7e8c30cbf5a72c871201a3394715ab2b0940ace5eb1eea0ec4f4f4e3db9537e4f47c48d48f0247ae78844c575443abd1d00cb5367586f512bbd25fd252a893edb265867f9ad24d70009f9a9449ac0198de1c496ad303d2905daa97b57cfe044cd2fe94a1e8f8460ccfda24b119d6190d80cbf5955148b1d24204029fe471b23df9f0d67b8ce5b67e7a3ab2b843cc07ddee4503d3df4f3ed5ee841f50101043ff92b446d7e3f651c607e22fc306c52d8e49e924ec0c3bc3023a54f6298da4a4cc311ce3ae5b771630a203eaf010e8dde0c302da59ea4b23f60d03aa8d64f16f188e21598c4e50381eed5ef49baa947cc025c7fb508efa602c09dbc7e991ed31f48cd9121ec4699d2f3f0fc259254221f9d40360a15513b292408e04a0d33b77eb517c2438439a9890326a6ba84f126d58a007f7ca0063bb1373a441f8ee3356cf281e2eb75b941818ff5371973aaddd6a4545b11744352a8a02fbec9f9c2f73854430ecbbc6b86936b63cc3e9cb3f5d8e608888005212e5664c14180d6cc1c86041f7c0b3d6434b1a11055c75e3a0c528ddfcd9b7dc81c07180ddb888acb09b338c1d4c905b5b2586581c0f21793b8c788d57c67a9345b3a66b80fe6d3231cd5e4bdf7a50a54dcbf3088fd41a081e8d9d77d580aa8a068fda445cc272e37eb6192fe4b0cee1edcc4e450aad693845c2645f26576320a82a4a2ff4b67eda5a25a401c50a8ed9a932fd2c114b3329a98fbf2ad9a9cce4f2042668eb406aa07c95b0c30c07c67f7442d67921b177c1da33d6d6118e80a1cbcd9352facd70b730a755c15e8ffbcb24caa8bdc2012a0224dacbc024aee430160cbfa260f631aba1271756d528319e699198617669856bbef5943931bc23b5a60e34b05e95139ded9d7b69f7d195cc762bfffe968b5fabb4782d4032707957da5e324d7e300fb1be97ed226c4bb2e518efe1eb8f828fc7b0851be18c8be61ca1f095ae567cef8ad9f5d280a33979d33cecc7a09fb2e9d628d91d498574b46379c9f441de209ddb44402479c2d5dda5fd4cee0b41ef34ff3e1f937f7a1ebc683192b9265a7a92c805f3bae38b5dca4bce307df1423a394f54072ce533f918cadf3a8161634b05746dde1b85918debf842c71c84f43c5643bcc25843940761d7ab0061118c88febfa6bb6f859e74b7c338c58b0ab741f5206fc9bab9692d30f39996571e2007ad0967d676a8b128d9f6bb90f80662f3046a46dded36ba9584c853 +expected_result = pass +expected_shared_secret = 99dd968e1f5c94c6c4d92e7eee393c802d8ea4a34d39de2048eebfb21a0a4b9c + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +private_key = 2c021f19322a908456f1677d31dc8a4a2a734a2571d19c421c47aecc507c3c53a931113290b693afd1b7ffeca87cc90b0419c48bc4359d64146d9932beec78766408f59216c692228fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c36828224c177d3a3ade3c2c20a907c830bc32906df70b021b47c38c606ef951acf7c1512ac15fc0d761c9057a7db1ac6c56198f9a8ed2f67a0f159a5ee6612109254d57745736cc3cdb634f5658fb684d805888fea8582135bd4890343a545e4e0a6f0c130b8539125ab06358f8bcc0a4b44a7a4903d018c960ca45779bb564a30cf1b340b4c317cb77da50bf899c10b4676f3c295b90e93c2540a9e17c3bde560f351c81c58b545306449585718e9199a6302e3b0ca1e737c07a4b7e21ec154604590d415f4b82778778905360cc2e49be4b08c94a744995f18959d4492f0b7a3f53a98f9a8d914863b9583d866712fe583fd2677e8a3b8ba5341902178824f4c41ba21cbf7a4b666acb413c31cfa744b9a5405efc5b53a2c64481270484134753c1b0407e23b95850a8c026843643e42b329bcbb7422df5cbb968b04f39210a4ec959e1b5c9cb32a180588b9baa690f7459b1282d9e9200bd1a0e910a3efd948c3bd0af04d866edc61c866b48d7aa22e6fb5025c6892c66116e271b998b888e0481abda592c8b36f7464704fc22c51b5ba995928fe03594a8073ad790798aa304579822255e61d11557092bc9b5bd4c94068c60b2940c180831c5167487b7538c9ab47dc268215c8c7f324563d3973fa73bbaf07c771b15070d880478d2693535425fccae0f8272cd7224f3795a70241d480425e4a74922309906e1c11c5107e9f34fac3536354100f911234d55769b763cf2408b9812aa6b7c2601161953cabf0733cd3af819f5158a136621fb159db3dc6c3f3220adb8acaa8cccb7cb2ee583b9909c903ff43612d178c568aa7e9217e345cf4daa9aaf17cca1b5a4a5a73ce9b0581e73bcc019bce2b68c8c273dfe588ba0861c5a73a6edd9bbdd66935af04e5ea81a55d62c9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddb425cb4189ed773d8adb91e2708f12b78a0105bffee30873c1b6d5d5469f6464705741ec4310a8185a1553372f6091c769109f19527e95a6802c2a49127077b21126e7531a5941298bae199309cbe00d97513bde1ac82292ca1a76957d20a306932f83994a00f21d89519e16138f0477667f338a67450e1248a682142a79d9ab6b58b88754362a32af3402d062a554ca8a40da0481ba721a9b023da71987b744c6b9ab5e80830f8b7200241007f0eb72ae3694ee92814df4b1db269f4404cd0c77a844d2b751f5a0bd1cb93d61a628098d0eebc941827f77139831575b98e47b7dc3676d887b56d0ad96bcaa1f280049776339cb3fef6489dbd26205530cb08c53fb0839b49909864ab06b2c3fe15957dda96ccda90c51904df02c6a1e5846f892a1683838b9760ab900664a1a039b6a1c75f9c4b05340ede9881f48869dc881da0191e24bb5aec448ea052e57e69edf254575fca87a1b50e6d39520630688b04328a70ca1a871ffbcb0a8823dfd4747dc859b3472cfa9e02ec7f2c5b3b9a08e4534a971ca46f7cd93547ed32c42dfe064577a5291db057df43d59741da0a12ad930a14319a0d7516a26b5cdf32ca566a6cfb1099b2da1a37b487ca950199f9212d14c83064742ae46985c398749f392046bbf13638b19b716e6fb94c8d5331b14bfdbc2be35699627641abe618880d8947ef059696185de186069cb9309552e256987b4f071f79a9687d85fc61292c19548c3272cc8e34bba918eeea5181a52b68344ba8656409f00426d28869e397f077a675cc169a17264634a0b2341b758a37d54f1c1fe154893a1560a7b10618094f8c060330cb03f978cf765133aa4c9482b0cc169802a8128b108b7ddc5718ed6377a6a11922b72d6f3bab633b3c820a42ae2825a43093f48bb73a0432c56b56565aaef028c2228be23618a6fb8b9d121700f8b25b79578bacc1d3d7a1ef5d16355a07dceda8a5b358f20641113ab967f75c3b2dc7f4c1c81f18b35f8e573d8039466f210b89baa4752af1b45b2f71b5642eca69f50789fb153c7f9b62dc29440b36ecc40bee26ac378d8b540992eed54b23676827aeb4bd44857c2c21d55d72d0db795b0b6c8bc9077aeb59b71588abfe926f7ca57d305141012a41eb063f5281018563eab7252c34aa832a4bc27dacffb008e6d255cd547a0ebab65f410035550297c50b1a637cdef9172b6d4ab96ac598ad7622c34c3b98890c77cb9a5a08e3411a235da946c92a81d7bc57998175531b203e21e3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2991def527fe6c838d3e1221bb7a48cf7a247895dc77328a07b8c342c731d24ca8a83b9cdd7a47025467aa81bbb0878ae5c8e6fc0ade2f88c68a328fa132a4b5a0298ac19f46098a451870993015360093bd7b0ebe3929a028333312361e07a7dac8c90b50019e73893f78d097028fc5714362c41dd42c4dd71cfbea58e5aa96d82b03f5ef65d572957ede919e094a70aeab998a55ae4b2988890c88ffa1095273b132550068337586284976a30b0c538474a25ec076960d1bee0620a2a875fc53054d28042674b1f51b7877629a1fa815e2ef578afe936dfe5c7cfe6472ae7c264809a3a1285f6a156448246e4e832c75439cef074f62bb4ab5a4bebf24a129c046b0cb215552d126c32ea74088a2a7da6bcbc380354a00642ddf9810ca8c0df8296c55c057df32a4aa14f45192846e31c38919185e2c77cfa199b2003b80a5d6a867cc6764fa4b907646cb923e39bff6a14f335392363890cf66a10026e7de62d09daa31a50a5458515dee1ac7e092dc19ca6ff506dddf67aeb26ba4d720a92310fb942581f69024ba975598c97c41a6112c812aa6a21258060badb32dde0a5eaaa4fec6983776b1348c06a7877bb1b44223cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a277625298f403114a018b8b78af433a15a69de14158657ba05855bce24402243746de13728b4c4359409a282b994f3053777a72e6c30686eb0e4746b88ab57fc9f2558a1a0820c59c2cfc801b97b0206833d4c389e415330ab87ff870c90f86218c3b2c058b97b1e595f87703f6d34118965cc88423e3bb4e182210c225902fe3229e4559ae8a231b34395989c732f54be1b90b3f846adcfb5a36089f1b057c70931921fb36207966666413c8998c509a6268a6bcc1271ead333060d9753820a0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040ab2773976ea3e6876590c152c897d59543fb576e6ba22f9b312995f9969c91cb9098aa2046ac4bc69a38ab5c7a206eed57514de7821e64aa6626299c99b2a7299dfe933ba386a19ee01cd7a24db661356a19a68f68018a6847f56c0247346e294158c36c3da5e51af8604c3ff26014648f310977ccf8bfb36316be8321c71a4e1745237f964b5df9b67f8699454a810fac4fc83493aa2a7e4af61728759a12a769fb751d0d2125413cc0d4e0b5aabbb63b8c8ac5d385a95094e0650d16009da134c36a7c8a59ba90260b9af69542add7a72922c8dbd2b9e1dcbf39e6b19a4815d1544d31547f9c336baa44c835805c1a03610c0ca2b33bc44557583da206ccdb50f1c7309de949996ac72fd9803ec5bb7a151fd8f0b4e78008e35c102a33a9412b40e4b7a247864277bac3c1409006a75596d0cebc52621e91a7af791672e29861533e765257beb06fabe44c20f0a44a288c42d22851433c2be639404aba3e6b356c4671906a375894954849431f71717dbc1a26b19258db8096138cf83894182c88c6d9a56d718f489040667184ad175ca0b02ecdb1b5fd0a2b785197bc696a68471c9b486d7596657318bfd1f46aa29414c436c0f69252ce96bc09837cb4325903bb15d81b3f5c62cbb8dbaced7421b4361a8c196601b002f79877158c97bbc80072ecbc8b69557a4c60c8e90d23427dc7ba806ba6234189bd874c30ec696710c53540f74bf61b2a777606721952f930358b55c183db4f1ea17a761a0cfa14c55ed47cfba737bc75725c3471aa8b563050bd424512df66b0684948d068b94765adacdc5a24e18035c5164c54ca64171143a023a7a07ad8b5ce3aa095c7307eadd6499d89cceffb00f635334a3c91785009fa6a93c1211854882e99b7a32306bcf053551bf99f99c8a458106a55ec98a0c06c7c58583ed757956a89533c6c7b2867b8d3a5fef526e13abe818919fb03a7f9f0cfa9025fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f7243d71bcbb46b9a423431b3b30947eda5fd81b526cce79a36730d8ee1be42c01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 5c55a11405874e124d98ffff57d1de80e558b530fca5f3b32e5a1dd9ee519ec1076b7a094d98a00689d20c2f9d02f2366331ecf9a38724c9535f5f28756c1ad9fa29b326deaaa3124b20e5c5431346405b624b45ac9b9d307b07d85239fc0babde057cfe3b149ddb91db18809727ace779d5c282677fce653180c032d650e5de3cf70f190723d3effe7ac29def3fdd3c6f24b92bc574eea5fd3bec978d94bb4415e0cc952cd66f09bbd66d625845f9a854b2008709dd1bf5a1df212c35e3b646dd3f4e79559ed2612dfcff7c7ec48e8be3acc1117e1cfc928249231d6c3e1e032e5422eedb5c4473147fffac7a9f536e6242a0fb768c61abfdccbe15e84f1127752ed12d2fdec88546cc3225db71edb9fd49ffda8470b08ba0673deef35f2c6f85ffcccc8333a4a4853979dfebac91f41af523f285b21bb23fa098b1687ff38bb40d92fb29520220b9a9e146cc8ba13cdb4820180caad1855973a0b589158b16b62e01148b4769f66424e66799e5e7bf50915e04fad2b709963a3e514c3273aaaa4616735b07672f44ad93a46d2d68efcbd63663f6dca1656385fa9c80e1d7937eea2a6a957ea5f60816578e90f356deb8aff0977c9a949e27af55231de9d61b6071b73b9f75d33c2e7c3840263b51919a6716c91d3b1f5ded6a6aef9d5ee539ce176020392148bcc920866eb5628a2afb4be07e61d21dcbed1d13d4cdccd25042b3ffe919f06ccc7334b78d86f157d5241af54897e89b7bb3b9fe1e27f6bf48df6e4cf9548f55214722bd6cc8bb13b158e1cfdba4441f469b9d1f0d22c3c57608be47315e2c907004a075a135e84d72e66d2c5a951ce5fe0092d717955b169f204242fb05d7c2c6a5c273f3471cfc2b1179a71a9034071668927d8ddde3e1f7a3741844b277880e9fa9c4338ebb147d2ed8de148736f4385d981190e2dfe70af1f4412478facb105a0280a2106b3a0bab252edc4e09382cefbdf79178f29c4beada55a936da110cca63e9ca18a4a5024b0225b4f4e30b47b494839b4b9905960d18f2b9fea9df5bd807f1f53b5488e487c7ca8339194d2c6733a07cdc8c226160c63ad4bf54c0ba2e9b7db082130dfa0ccc95563b9d25ebf54a2afb0b9fcbb3137e881ecec27ab78dcea4eb25b333c5ddc6b6ead196e948add01be8950cdfdc12caa7d741a9138dbefa1d09a5ca0ebb309fb7ade75eb07526b59061c12419fb309cc55f0f0fc5325dfeb42cd91585dcc189d07b3a1f460f907feb69f073d50086e650230f55498dc4f3a34867d7f91a64ec760289c209598f9a27ea49b841d7cb5be8a4f3373b3150911d3c09e53f54fead8b7d734c66f6175ff87d582f4394cb1984de474f365eb8ac8c9fdf3cc0c406de7b780c7bed74652d36077bae4e899b26603bc24718671422938e50fc5c6d7e5ab55f010ddd9d9e637a8de4d88de35a40deffb060636736a956bec000977729365385b758be15a3e86b7f5b175e00ec39399e5e2e227dc4129adc4f4a04dd0e80b74057d0ee4bf3c716ca87954fb0d16d55cd6d8080a9510c185d0a62f2a9b09a7978513ca0336c66c34ce7c8e3cab8f8c91f85e90796f7f71bafd636dacc005b38b9f8b3b81e21051660fd5fad3781f1d4df1753a658a4c22a9c89c1471bbef06052413034b25a5ff7f42a09e808ea68449a17e7ef8d0e8f99ec528931528f35db90d7b46c2cce8fa40928beac45d09685044a9d84ac56659fe0fb9cd889ffd1596585af2dcbabde87a97745acfeedd94022edfa18fed63e0e3f757ee1f8db7cf25ebe5f238ba9682de4faa5912f1c9c292e12ab59c45f01aaacf8b3ec3a461b13e723b160c69ff98c5352f00eba151d43930339eb52d0487d801a34e5cff52a824a5965061aafb77a58dbaaddcb18f6b403471f5c9819acdd4716b86bf167131ed5aee53311cb77d3fc4f1ace517ff7f2c430f0b912541fe35c3a8bfa15dba69e8ddda522b46b5cc0a74981ab2dc2a63755d6e1a17780d0cb003eb938e5a1b49b2116eb32abef130f86b0ef2166abb38e88106762dbe781a55baab6e2d6d4a406abd997d54529cc2ddecd0d4c283c8e2558b2c79cbcd9c03f08c9e3a0803083bf6cc50b5ad358214723a67da6ea2ec99f5869e01040459df692d1011c3ea53a215fa2d15d11611187bd16d07a9e9a6de9b5f8d30ecf08d503943e374fbe19530ff3b44c42e43b755bfc809a58b4 +expected_result = pass +expected_shared_secret = 0642533fe87a2913a37847843f7336a0e4c47f778afe5cc95433948a76ee7ecb + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +private_key = 47a7741316be87861aec518a9b38146b43aa54a98f47e242866b8d79f731d98c754b572a2a9170a7eb4b0d73b38d6665d1e43af0b61ab95cb54879707805bd787913ee369d231c600b76949bf86366579ab62724caa1beabbb02fc945bf007cf57a225afa67393cc58804a15016a12dfb90d5a52be41f907b1f2c4fe93712f555b0ae896e85931020089642a23e4c38581d4c40a46aa8ddb3c26db0e29fa5f7a12b6ca32cd2ab6b50327ad0dd8139ad83dce676ab2dc0c2774c86a2c72a5fa2d4dcab588a66d6551c040e91ae045698ac0a1dfb95048c545d08654c1b560384561ab07bd8c61182f99c79a2267c961ae66434321e8501d474ad84aa71286a948c5ad187232cf72576f167d63992f62d3423ce75577c2052ef84019404b0e1706ba704fe3d116a518293112b8b80708c094bde829ac38e362a404beb67026ea6782362035cae099302c5660931ce31b93b665059633699ec44c28c2bd230b1942421f12388900081618bb29e315beeaa090a06ac7feda567fd1a12d1a41eba931c279acdb875d9ddb7cd9a6adbfb32239e843012a8cb91776775408316b056fbc42758772c1e53ec0344479c2791b837a6a34aa77710d35593a55e57572fa99711bbe5a83454bca7990e834ba285a09aa11666cb2b2f39704904354687d0524888cf6461ef302139b042540138e322453619b3dd715b617230e08c4585478f9996798e9b47c712f82ba45857551ea4c79b4a0577938666403174e84585e684783d33f3b701420f66d48473fc6bb627b399e90697e760783a3e09d6531cc524568def8507f0437314488af7376bf2a6bacf783b632197d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85afc18dc81a8611bc4adaaaaa440471b530053adb874db67102b6a64ffca8bf8487e18b2f7582b71fd78d85f819c24b892741a83e67585b6b1ae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774e805e001b44c8194660a280d0d59bfeb35ebe9c943e626b98e488f8984275401bdc4959993345c38bc801b95d56bbb47a2b23f5f1223d5a0e2a827d4578948cfc5432627c9586275679202e3c970fcc980af56757912080072a4af234dd030ec481a6ed8030921691d6126839635c6b270497ca4a87d4bef47cac60752383712636752a4aa18af13bb36ef445fe653628704e4dc2cadd62839f9842f9b2c264ab4ff648c59d15708f55ae4a396d5f4bc75d20603c03cdec4252facc579a0cbd1f64a734e8350f03aceaa2734de2b486f6b93c36ac11803e564070aba97d2309078fb43768f98ef5d03b09fa10ffbb0beb3b5fe01310065508100206a640b93de87bd94a634907730e30800803b233b95d1cc7cce49c08ab143734347f3459a5be0230f9481d50b4b835a91736d6a7b351c8082a4d080967b43b0553835bf52943a380051f48c27823c5aa0b20b7b733dcb004b2a7819beba4b3fcb1f991789c2c57ca01b50523214af309fdf421187492c411c14128744bf4a83599a30b86194473c2bc9222fb4ba34108689aa8065aa24ff3559a76f759768c81a8cc5aa2a6792f3033b2437b05068bed096475d9280bf34980b1c478681e53190ef7165db8d7be89e82411a5cf76795d545b69feaa1a2065b7a5c00a50e6a0871393dd54af62e9b858e3453d9a86bcca62526837855324ba191f6c1914754ccfee7ca3be778ffed14646224d19ac50494a634392a7faf6b502772820a61de5bab6be04b7e2f2b8b05ccabb22cc4709a19ca96671b59f611350e4a5227503050ffa19c776b0bc26372049b8fe864e328798ec49c5e4128cb1498432061a5af628ea5c8922845b07300c49e7a929f76232ac2aef1cce07d9c7e8bbcce4f99f3b6b0b1912648784c69493c9e9201b8166c0725709bd56af241834d278152b5a96ce480c9c31c9af0a2711b58e8539b93037623dcb9561411d3c03c457f560b41ca23b2a7a8d66b1b686ba4566577a2a71448648ae3b988bd21829012d3cf3a18f4a596262a33579776b5a5b2c8a0e1a5c5e87c06cf9833c13269990719beeb2a0ee333012b8c1acb7321cca98f086aa4db73988cc49762ca541372566abb0ed081cf6201b4ee8a17c45b8ff6046317648bee9247b93b6013a405993b3dc543a4939519f942b982aa75743861387558fd01f3066af48080751346618e25c2501979f70cbd722528c713e9bf1b891043de54424f7022e45cc287b7a8138c842f1bcbad18795a382439c5c470a91309fcb8149039d0435b9b80a0773778111134c104cc5e7bbc455fc0f4d157f2afb40972c41fe85622825b5ac48c0e357cc2d953140015bef5cae1cd2bf7519398b610c9b191fa34767ee67880fd9ab6d5782350b176d3a7c318714f8208f71c80a1b189bf10827b763acf096b49cc5c0b2a21c268a6c69500ce889785825438890a6e7e399ede411d83a53bbf81fc0b0b472692db25b69396337b2724f1425aee7296fb29a399a16a13ce748995806cc5c64ac87783af77bc05329ba849a086304ebab9edfc5435b55503c2a6f9b996d75359e963077f4a88ee2e259a6b97635a3bc8670b9fbb94af2fa3046b51bee299bae327f1519ca170a1aa443ca323c1d336952a3d2342d481b10b4752e34c2f03866ee8c8508a77a4721c387054cd241bd54b8be0bba7be18616d3b649a452123e347f8f52c0c5ba2d9fe7560ad88f2bb77622212dff7474b2c250b0341d9ce6ae52dcbac5d3b99807af81744498031477b6178d4552d3e813483c3c6c4a73dd111e7874b7659b29db53946538cf3b51bd53d63dca591d16043469310c512cabc763b208a19099fba9f82b445c05bddea259a0156940e3099d97928c8079bb7846b566b4770c904b75b430151b3198bcce1830b9b8cd5381a1b255a880e49865297a801291f491201684c658d288ec63b8e6d423c4c9091f9552926253876629266969acd09a8c896ddac6bee964832bc0952b98a95ee54422da547ad9174503093835c74693047d782829f06327d11b6a646ae2e8703c3a6bfe9516e71915e7294a2d5a4ec8406792b55692c5591af95d3e7376f6ccc58caa2ff787a126193175162e6a084159e957d85383a0502bbbe091da6a62a7ec4441453306f74c40c483abe092a36a5876a60e1893c8c4fb3dbc946d781873d49cbad7ba431ee820f6e0246b5548f045ad65b0670c341d3edc40f331b59740ab0d167e02fa36cb23b10467084a63b9f1facabc9c86e6511f8cc6928de03913001927ec47e6b001264c9629343e10f945e4f9065e3985e8b4b3536b1aaac91a02a7b701c961a939388f57b310c4652d7649d604a0a7006686c5c0f467486e5248dc24be13f411fd524a6efb276bd75875d5cf7a18482dea41b4579f168486c3d87545b415ec495f37185b6762b754194f3f415f82628ed9884b658465ffec83f5213ec15264c454cb4cb46106c21bd8031d11fbceb50b7d897aa771748cc2e5a23fe99fa91347fa90c642b5410c2c4382b0a498f479aa94011959328eeb48e8222c5ca82930f5a4d40a7460a827c756c28e99a88440b0ca206241f4472c06ca74d48a5f565b8a85803e214f9a6cc92ab2b80bd16c0c5725a9c7bfc6067109600d8142a8bf681ee32b3d2bcba3ea21aefe0655fbe06c0c0c6b303c6b2efaa6e8e6b29fbb86cfd13c6e143d7b104ec625a6ab2c782bb88d4929ccf7528aee89947ecc33e5187bde373c21f2ad26252163a48bdfeb74841987e797048b506c8fa6c60f431294ab03ae304e1e64a1489a05976355f44b6bdbac7b81d2b003729f9ceab9190165677c81644a5820d8a158da62ce19657e947170472e67d87fc5c526b2db8fca728ef881198ff809b80bbb3c1652fb9a51c42aa89ce96844721a9da7274d52050b106c7505497629962b747e117c2970948fa1e6bbef069cf4da83314083f57455d9b031639202351bbc4631b080f936a1e017810632bcc19b41ac0fc7939d5bc6562b074eed4267b9f6a6d110ae51f2b6d9b39f46061031573c5a10c2f23b6879338889e05efdd4424820cd98298b59dbb720a101e8e62887303d5efb4ea99288199b54a3caa85476876d969b2ffa0b72754e85d3979c17155d784e3ed0a2874cbb9890b4bcf6334c8855f7ac45159a18e4f29ff5d8a5e5f34142c01e3fc53a2d07cc7f6c582718c434c062383bb60d4c54dd07a06d2642c8ca4920d5b7fa723f6f2540eaab1385eaa17b4339b8b3cd08f60e5727045fa947bec4c6e766b850f86b80d2b559507137234cd9856b7310aef4f50034ebbd5336c026530b5ff525c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c4092d5afa2f038f879184f7344800ea49a63543be9600bdc2b184207445882900e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = a5f7dc2067f18ae678977fa4f0138e96fefc96c1c9079b1b5ae3debab2464eb38b217d051cb15d87851322abf0e9256620d58f3d62084faf29daec595cc4eb768299e4c83f283fab2c58dc0a4b77c3672e14103e9721975bfd6138a0aca1ba792fd7f93699cd0c2196fb185ffbc8e5ace4e6192c1e431b78c88c21186f1c74747c4ef88ed223b9ceaa7785b94096e769ff0ebd5133e099a2cced0f21ebf34deb02ff3463a53f43590713cfcce43c8260eb6efaa0ec1eb3c1f1403f6d2be47d0695be1c8897e32787e7df4ca49f1544798ad874ffa44f2f98000106e9386bfbd874a700e5d95001b2bd45f7aa3bb343c80c79b7bb508a93fc6c077af870cde24fdabb1bd4fb34b68c8cefdc4198ab60f5abcd7d80ebb2fdbbe3f99448ed48840e7ba62c87d783f8f20c356b017c31e92be43dcd833fb885d51a94623aa24c732c7c81267a67341bd33ae8ab8940eebf9d5e704709400619e72989d4a67b8b48656143d47c5db50f415c0b726f7b8f5280b7a099f7b2fad0a48e82f0d00926f39f63671a212598a2b1d6cdaa9c693eb64d568739b2c8f2d875a519d7772c1af1438e130e2d232fb8b1ed25aafedb8adaa0ca5cf8a97b1cb6a16b93816b5db9698f8d984168c5926a8a7da376890d1b99e0d7d1692045c57cc1da67109c9e9a31983254c1c816f8129fde3fbe54fd4a2f589d5b7c1d9e53ff5e0204889b1598a4954eaf8e161ce562899b05994a614b66679544170b458f3bbfcefb6cc34c6b153f334329929fe96bc5b1534b786aaddc0d7528341f4ca557b7082c1677b04460e4461eee5b7433e4c426f7af796abe8a15a2ad4570f9a9b81c59f372c99033bfff6c74de930473d49dc126ba2bd5b271b8763d0bd5201b101bf10100f3e70d9bbe865c7d1cde804ba9b9811444b4219ceea6c395866ddbd4f715a471bfe79eeb5446964692bbf41a617937926b0637ef5fb0c1f21676ee2a3ba4e685c6246bfe206dbffad10f1461006eed4e7f3b7d7eb66e63e21ab02a2748b4f6819810fdc086e3df15cb2a77ba2c52699ac58731ac9464022fe124d55491999b3b6953b8e8ca6f0a822c3a16a90dae90d66cc6efd9bade18edbda4a22c49ede2616abdf7daae20e95778c22c1c9733d898d017af3e48b271c4b0b89b72a7faa262c898dfb81b417208489e14957ab999507df5e8de9400903bd2d20e401695295c9923c8965db1df1f6891a2c9468a24e078065ccef077a81c93fd1f5455c8c1b17d9e9b76404cdced260650d3f89d21e861da69cf60504f6434f19136a45c238ed0a69c85d01618bf2987d1f0e7d86ff0d950a249dae581275ad7ff76b3f2fe170bf5cbd3b77a729ca3c12a66ad6e6ce1e58f1f7d83025211898797ee20ba367b31f82ad1257362fb04dff88b128304a9a5e4efdff3187836cc7fbc9962c32fa9115e7250b42a48bd54e99576243e981e77a5461e81bed22fbbdffac5a5d4e054492b663071a6a6b2bdffe2e8af8c2c91a93cd67e39e5709d583b1345fbe04a7be14b444557e78201b9ae095f14e67f43829548a5d587d5fe032261c437d2bef3fdc533564bef450dde56948b94d603f86f49831f66556ac89b76ecb19287a74e74064c8534e021d9f62ccf84a9ed3a309d3931faf673aa04dcd2c06bcef92d07ddf3e840d10fddbce6454b25f684fa80317aec6390da75ea9bd5b33d729908f6efdb150d4d7f74e7a1f63750987183c8a2b47bf5f1256c14d3a49682dce5ce1b6875f3e87a5597d82cea0ec4accf0c152a04c6f337f934b8febb4d00e266dab16d2b352f27e40b055ef5e672d7466ff11c024bfcfe659a2a621ec9afe1a1e1de1473c3a7c6ccdd79db9ab384cadfb0e63efb855e79c1deee4630664462a24e12f3d954da6ac191747b16e18fd1caee0333fb013a680e5971b8678fad6a44e4232669b4787a47254f9a97004de7942a5d640bdcb69b04c6bf28d420b3ba1fdab6f9dd824c47255e6f2217f06080fad4bc1d210e125ac3330f2b748498960a9d12a770619f716a5a9b2041c3141c6e93fccfc7095d5569748666db7795e0c235ca25e68093d2ed8b1ce8c88d5898aa69711467b43f8990289156825d533633cfe67ac8bfab5b5e1604f1ecbbf303fa48f638adda11a5998e26023f639efd3ec34775ca4468b71e703ac664189821eac927d64d9333b58ad6dfaaebc8f8126d447dc2e5e6a74c +expected_result = pass +expected_shared_secret = a226b83601ae0e6f76f9f08b0a2f6eb30a3afaa39ecf5c5671e988a354fde9a7 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +private_key = 35e4451348cfb9a06f1836296178b6af41a1c0196f26525831c081ea779e6b8c4b3f150afe2963aa756968358bfcd47d76415ed4294f02a843f89b87d6803bad504a9165b9bedb0c946058965b64bbf953e719160b53552c100d251cc9c111837e0a7c4c043ba0777e53b39f658b41b5f8900d4721268a8ab868b15a12c3b8f41316dcbe117ab3a027b8fc2cbf3566569a130d6db132ddccc5eed69a392bae8e4a7bd6c9708a48badebaa79fa1ac1e729eee0399803a374d3733ae501f1a846cd2f5166dc31b4d53750bcccf937b1ca43c3a6cd5601eeac251f9aab8b2489e22ceff436f1142ccd1bb17dfc75db6125a1a433325a5599fd23b49bbc3d1b9195b984303735f9f2646efd050097ab23a8aa5569ab744a934c2991ba046cb012467d39c3936eba9cfec4268e1a0eea559980133b4121f9d5a603e092c199818c057b7c841a7dd00af2c0ab3637878a9ea90bf377874fa38bf290fea6131345340857a1a53d4bdd9201b99fb628d975a91001f907a2e9ad37c9b99b8af915070339fdf76125d9556b1716cb74a9f18092afd887880526fd82cb002ca49e879c50e33af2e747104674eb1f30859e3c22f3aaebfd30fd672b6ab855928c4085130488540c8cbdb832ae25249f46b7178af9769a4b359664ba48da4a746c215c58ac2752e43835b5c2a9ef0a3fca159d29038cd60cd60f5bf508521d3d59c4f083653264776501b4fc62337fc37562973a1f9bd9532b4bdb25c21597a11e17096b155cd43c76874c44f25c1aa1bbcea897367536ecf4124feb6cdf2360cd5a082ac03b5e94232dfb44e1f124fdf65a4bd03b16ed729884065d77135f1f730a7a91fc2eb43271c0b2bfb8e615c07df54041917a95b0544e8513e8c6060d14c0fb802c0f2680051341960654f3594c9972c08664b7bd30b2f031827307b95fc525a2632c2456041b1286d6f175bc0b41942e8b8be69bb364a11ab4cc199f20aeb516ced1acc1f4b2b91b860331677290c643bb9a00b4b65644592c5ca5bb19b25d2a7080cc32b08910c137946a3fab6c8e31a1e97a4735a5c0a239b073c6e056053cd6498117497870718d35235019b3ee6050dcaac31a27167fe35ce57586c364c13bcc7587ca066c6e05673e2ba0186281d94843df10bb3a93c05025c0c691a0c41b229a55b7b506724026c4f1b48313788a212b0c951783ec9447e64314e878734ab59401923ada0586225c7a5c00a5f97bb76632dec47c15c06c7c20090c790404b3044136c79f46181cb1123a7d3cf969b72f6cabe063a35774a60863267b1ba34b93a5d3db25fece84a02429a9d142ed897320bfcc114391bcc097a078b04bd9356113b3cb993c19384886df182e37ba659d5b8bee24445411e318cbd092b8f8e53c63bfa3896a2cdbdc66e27f25c83fa85c260a34fd6cfe6872172f1361aa125e6c5c6c902cdec68708c14c175e910cf002ad647a317f78f52f76bae006a3aa51780d37a00aa20c6a532281719c5ac88641a9d15549088b5a4dda23f443335abfc5c2f7c5be2a142740cbfd612a83af271af0aacb43833b56295b51a885d798825c3a2c04b399c528530ca24117b6e762c7b6527b0509b5963b68560015db4d489b5a93507e286539604cd0c35e6001127902a72ba3fb9d379833241bf849d2c11bf6dc5133c0c76e861909b375a930caa5dd105e8d96dd8698864678adf585c4ea072ae56990c25adac59ad0fa30b17d2a0ba16a444a16ead3c9f679c333cc97d830106a91a54d6e074c463bca12657bc91544d8a6e181c5b452229ca94bafdd02375d5a96de2b93030cfc93645c7282b082c29d4b466fea3c28d2b16ecc6cc5e584d35e45c5ec7233c723c7b2275abd41748a79f88797d9d03b8ae9b839ea935f5e13ff9e775af239c7c448eae6c7b407c42915c1c4cf3a1cb652b44b5acb746a5b2b576fda15fd1cb81396cc1a17752c2b5748e988649bc8caa98c2c2f09cb01b1153a59ced58a76738072a1b6a5a68b1825a062a223cf83913d77b5ba226076c939dcbaab624c712b51921b46098c48778ef46917c63a23a563a39d0c7d3ba5ef7b87857c8912a137f52026cb4628dbcc0ac53062b1b181821f65e4f622babe9882a69487407b0a715a68c110c1a20339eb559d47318dd255f4ff758db79be3c3830f0332f31f89ec458368a31cd2466203c2b510cd773d66c92cf2c95d7700d82b54faafc8931300f48563aa4cc976ad602d31c4b4b6c96c6f527a637231f1b94cc38767a608f44922a3f391b9e6c5f78a87bbf6cc19849ae619a2d84533441727e79e241efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ab71ce07276a78546859e21ba695953c8521a07bc8b4264bf1d3403eb8cbced71753b6619a4309599c4ecd32826e6609d7d09f976c02dd4143db7ccf9ff09365910757268f49141445b689a6dc0706c92fdd8382c63010f7a026abf217ce572256360a9a4ab2b7acb235f6929b8661dfd5bc4041813e657c95ca1a36535e97d6a56c7022dca5cbf8d121f24ab6df3002fd4b619b03ce2c4b57ab65732721901448b9c0136b1c72145b2b101fe1bb555ab2c0482caf3a1cedc926a007858e7a4ed9dc120eaa7e945275c4a847146c88a468ae23ec173ca76494732792d9a952178d83790b725ca63fe13ff7c5cf5096b3828b463aaa0ee913c390359c9e4346cdc063b8517dc5830a24e578f2053f33e5999fac5603ab62ea785080bc39e0aa206c98c560597d219746737015a5668ba4f0b06f45a7385c753a854c4d818f78466b5b9421fb84b0bad8b5b0cc3104ba8b9531b9033c52fe7c718ae81a3b06ced360a879d9cb3f73b8d6c09781462e6d7c13377006d95406329777e2651ef2803c69e984d4e719764ccc1307a64a1633e7516b2c5380c443a9bea049c91cbaa7bc385b989d1453676ecac1c2123f05e83ac0295c6e36ae6f0364ce5b35348037b7379bd2248af8fba3acc293479b24cd0a2b0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2940761e48e665461bf30c2e9702ac726ad1aa7cda90c5655b9904ac1699921ac4a3a1981b566c6015016ac84e7964f64c0b5eaf69fd5460b9a17686952951ef9a04a55926bd482e669bc6b731aad4465f9901337a0544f27ace61841a5c2b0efdb2e4b897bcbf1c032142b73f70cc0f7b509d6847f61ba4e209269acced24a0721ca6d9e634167622928b65447a5aab30765efb7c977a56020b56abfb82449614df3fbc118369e8aab020cf989015696140b6a5c960db2fcb5be3c41091a6729c62547db67307ace42760689c32c2388310d1269915470286433c5624fefe684a12957d90c8b61fb334bc56cfeccb229f01f0312a11449310e432e75037ba429adb4507fb74a293823364f81b756673adbdc063d030fbec029569c8db185a0ee8011000cc7b2118a046483fd975d9a0122fb0596aa8a6d9b99ce7303b1c8a4342696001167a742fb9374d4a20a8377e8a6495e21ca6eb106b2c680a48ca6c138673ed09897f4c731412ec536759a773a1e3aab3b335301eb2501a5cb48c33a1e026e4bb25e2f867271e48cd48a029039519b296cea8b04953bcf41b515429237e696503e9283ca4165355585be315f20266438523d41543194aa6aa476bb2c229f2f12648a179e46c1696581607b4585c5341359aab5c5f0b2ca96177010c892f8299042a880b9c281483ebf0a96ecd9cac2f13bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b09178f2883e8c6397c74352aa32a49468adf650441a73a2a0e7489fd7a42a9421c8366ec7b5a0ba8b0fe721190f825bf5ca839fcb22f425738e92b68608078316af96526965331d16a41052f2154faa17fa843a5e2278cd122aee688924e57029a8902a03186bc562f99b2e72b9cf8e578bf28c2f5a86b47b4555d50a1512ebc131280964165f139b7a8860120ca684cec34cec402552eb3b9063b7d8266735cb1be8a0b253c67710d80d5d1b128e38085d40cdc7e2cbf4b8c9e1861d2f41a79e1b49aca0668e4b9312003986045415b194f0f583811b181fc15f8cb5788bf14762095bab613f51f4351bf00f669102bd349b70c40549b75ecbe16394a3062c5316bcc4a1ff57cdc976950618c7d103248f4c4cc2087bca854fdf6840ae98238c26656615143f0538c960888f32bcabe935732b6a5c24372b438449812e4f125b07b836b1e076f7e629fd3578132c70776635c5fc0d4b435ce2e301703c20ec130a25657eb394013924bb88090b1599373c5b7624d59d2f2c3b2d71a308a25092d5b0eb6ba81c5b0c650104b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60aad7166f31b2650d125c8ef23b5825fe11afe25d0cda306fa6c7a824b4c2d31d4f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = a368cc5426a57b2426b82207a847039cd8d56199b28a9b5184b5868528d3774eceb24ef6d69a936fa15534ac8eeb16c279c3190c59dcdb808b62edcdf9301b36ef634e14a8433800b1be9d04c6cd781c9000aaa74f8b063561146b8c11b75af02fe5f4eeb852d5f53842ddf4f18ac33e317b5d3a7d4524f5037246df16d15c0c211f37a8bd1e6b35b6eb5153e740d85cdb248b78852253f2c156d405648668c700f7bd3ab1c7670fe8fcbc6eee04745abdd4320fa883d6535b7366336410823ead993a2a994e48553935a17ca6889be18bc2905194e365cec1cd1d75f309aa05f3ec3445c53ffac6361f8873cc1ab1d5ad2c44b72be01a86b828d5f9acd26eac49160fe941f263a82286574508debb2ff9cf8cc10e85dd4ce479c96a79f3915e085726334e4dc636a705175ee770fc9b463e34a2ccb04ac598608370c38936e36b6635e98fbc5fe9972a212d8ffdb93bf5c26092ca7ce699c4beef08b2c0d9fcad9985dbe35a95839420ff1fac408c914dfac719b6e329fe872d5b657907d056fe5eee7fc9f302e3d6bd23bf965dd7c5fc5943134e55459ff271166c3a15685c49961b0a7b7d5ae61b5fe6bba79a59de07c6e04c9541cfdf84c01685226c3c1b3f8de17747b9d44498593f2aca4d38597b766133d20b95ea15ed087bfef1612793c75f32169a3f366aa34a671ec2701a5b3eafeb687d60f3a4a022253444bf9e8fe98283c54e3e080925b26df9665c6e35618d29379745890f7fcb4ff6e66c45f1c1412888564b036ff10ba9650b4bc98f23a60eb1e17cc57841ccd44bb8db168fd2b0e52a384df522556d5d3cdb3d3f23d6c876fd8e627aa3644bca0ce0a49f982b69109f42163ae61293356bc5154c1dc5092bb50843583f72f8e9c8c5cca5d2343f5c3fe4f58debf45579a302c070b141033510a9605786e376704dbc6c6a748c844c41f2338cfc3d84aa1f7ed352dc47eb0a512357220714ffaa503647840a1105dd68c964efd899678319bb3375c8eb9047ff3d2eb98b1ad8ef50e55fe41fed5f2ef1b534e7dda5ff5e988f86e83a70ea5a8a99f822e2fe53500a87ac4705ed512f560498b17459e0e0e6114fb3e370ad38f0fde6a6e247a8ea81c6797b428f022113a0bbe97296165e151e40524268bd6729f969c2e988ee92cdd98ff945f9159e61603c10a39b107c1684069faf0516ccdebc4628510afd381b99f686610741a3931253ac2fdbd1f043e0b46919f420cdb188ed3c3bb11515532f2d029d8920545f8cfdf93a9a186b90afb9ee501d7af8eee89e7814efda71c02bceda251342f52bb115d3d4d4b6aa4a9a1957eb2c9229574644144a247107763294555c3a259f8ef07c73381b547b47d871f5d73ea0e2311fb29136a8f20d13a1d4968d0ee96d91d3b25d45a10f18acfcd5b30c45c779c1208e7a04b5d6cd6001a5fc900273e9553858ad746dd3256feadce32a5468f6de7126ff6df864c530107c6654d10b07c8338eab64d5c0e9747139820ff591e964e332ea357574509da4d7709ce2f163e999aad5c99687ee61881d6d8a7634aa5eb5d0130986517517ff45e764fc8ca00fb5b5f76fa2f89c011a5c5fb8e27f5e97bae00472338b1ee7e053f2529b3ae4d360ec408748cb81849958cea3926e934ca60c6c322bc7758c3f3de8dc6324a5157064ed137ed373c4bd2caa10c19c4d5db5741001ea2f20a7373524c0e31b126579db7a5e441444506a776768532433f7f6ae4ea1f708148a372b4ec0fb52e453c675c028201e4d3cd5cf0f815a9372d82528eeaa106ae2ccd0d9471215be33e5a45cbf58993b81e6360310b6476640940b1cdc8e79c65aaa5aeb906c3dac8e0a14f54a656aa138ce3bc2e3567ad6ce64f07e1dafa43bd022eef3e4972340e298835fb81618c3dadf88eb994373ee3e84107f8eb448dc31a4d33249cf3f02b2f42d810d89fd67355ca260cc1bc1c8c0d8103b94b9c67b705aab41facdca2819b8f591ef79dedb0905a44c2435ee41e488e538149ef3fa9cc44881620cdfecaf1583f186c5c229df8e62de3d414b30dd700a6fff2d4a013ce8b0ca52d7c0da2f24d21f65038a7cd11a90513c4812b1154891f898f8ab3a4d666d00fe98d8cf351b12580e36055f5f31d2a048b41fd0445cabf9f6f367361fc4a1706b7aea67dad68688af01cd1fedc893ffbfc6efd3b3acf38545538e0a4c0a155c30 +expected_result = pass +expected_shared_secret = 3040e7e4eeb844c1385a78dc3c8a6375880ce8fab92827460de1825a4915c3b6 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +private_key = 03a941a829c025261f44172acf806bea5b216b58bab845328c36cb925a5169d6b1ff141ba44010ff2c1a446113c443c6d98ca879e673cccb84d5519067619edf59c23798b9b6bbcdc0d49df5f4b21563ae54e287dcccbe4c53c62918a6a213c460eb8c92377cb57a1b6d6467d40297fb90c6907b6be5b03db314c3ad5b2f46999743ec7ff0b055af2b2753695395c6157c60115e183dda398d136806b7017bb4fb4f36b7653bd17cabd1bffeecbaf2eab65b853c710820818b05afb86388f327fea6c3562a027c610afd9c0bbb23a571489120c2baa0d7aeffd196b2dc8b40d4016fda16062512a64462fe806d5959c49dfc0c9b2955e6480b7af0011edb2d44c6a43d08b5f469656cb9396c9c640bb077cc24ac0f293bab4cbadd998ecdba31534408b74420cb432826cb5dc8224c48159626053096063841153f723761f83315629c945778a24f826a28a90a5854ba7e80c48e44929eeca17e28304babcd0af4198962a045292f09ab5b7197a685a67d07ec9769b69e64ea1457fb8e1a70b23ac4a797132b021244944143e936c6e5d840494b674fdc9aee84a091175f8e3121150b1375e028d0ab6b709a443f14c56ab67e3a8721a4b698eac9615fa12c0e5277e4a412508446ed4999687ac5ac626ccf5468f3e944b8d099fdc319337c85e5024a0798556cfabfd47a40146691d32c0f179b5bb3c3088f2cb29e2b961b630610d1528fab952dc75d23339c26a38f68421c12c2360f369abce128cd64551ca29455e02aec7c359cf9182f5642f1bab42814aea8f2844af15670421e0e113063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a6e070fb665756f98156c65a6f407e1014bd6540a92e8a09ef6c944db876250b951d16332251c5bb6b79f88928adf6bef819a241068b08337136b8bdc33476fddb0292b68ede75490db193e267bbf2f8459fabb17d10bef7018ae895995200453065ad45457e3e86a12c554db3617a99613767598031c86bd5815585444dfa41cbe068034fc0a1cc2636d010230870776d2645db640b409a292acc909aaa11d0d05a1b1469ea2673020bb7ebc7381190c271e2cf73d37f61f12c8389843b0540117c7ab924c140d1409f701ab0c0596103a1aef3c93a2a79be19c7870abe83232a7de265a1a1280d30490ff50c414a006d8a403c50948da4b1054b18be35a8f9252079c5acb2104bd42ccb51617839e07380fb3a62b3a5080295bcca410215ab5c30a89b727363185363027bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bb718dd7facf5f120303ea259fb2bc32a5269ab45e6bd8ab9f9456a68b869a4c13a0b6c98dd1bf276572efc9a31591acb33b9945919fd20495db284bd4ba7c66620754e58396c0a191f20304b545aa2279cbe62d08eb4c82e60569598147f9910ef70abf792d375420bb999e4a9cc28db0193a124d0cc78807a54d13933b25b350a16c842e4b31337bc7734104fe564c20f27ed6ab800717baac4a9c954c6ec5238bcdf309c6fc497a6a9b9e4973d7d44ea53b90db26912ac7796c327d24d3705db5bd0266b17b145fd8ca77624c8eccac1c209073b2a6399cc7704d25452a2a0dd6002020e51b0ae800f9e93250591bc01b7274927da637823cc69d3ab59f7a0194b5b653ef0a001cbb5d28284576bb0670aa0e6f94c06f7b2b0d6904d0615fd1831cd6800ba590816e06022b0502d165340c38bf824a35d6c227db3680a3c1964c4727aec40384d0c413731e85f2224bc9cd4fa24e93d0439ee97c9b0852aff733c2974fd6e4241b1a46a86a09b48a59acd13cacf617adf9b0bf835c20e9b05b8b58a5218587ab1d50800cbfc315c1814a8203c442158790515d83ba576c25ce9eb0539b26accf471d299b3cee6601bf711a1bc913c0f88f478ab072cac1541c892e314d733350c0566385a04bd8d759b6b81ba0370069d031e352266fbc8e9625c373c0c4c3a600f37c5576e678ede07fe17609c774bc28f2c7d7889dbda78b0b041acabc1997e93e1682393fc655daf227be808d9b395ddb659dae366c87b7b07f072b7fd9169474ce4fd0578952b4e926abb7e039d04cbc94371c0c967394a95aada9594a8cb4d5d1945ada7bb18a5e52ccc5ea5672a99ba278867903f11dce73ce433c475e3b7e0b3c65921b3c842b142e139fe1d15efe13b7bc3625177282f4a92ff5363027901e2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703ca521be85af4651c52ab82006c95fde5779c10ca73866911a4c48088742b8b2243f629fbea924b7d8968bfa6200361a9c344a45466de00b7bf0e5b78dabb1bac3278144a94b27193b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49944d161a9290b4ff328e4fcb2427292a01367c713806b37cf92649009c09416a915b84c23efdc41d7e7859dc81276042357663c0bb68282cb71d891177148a17c315b7cdaa9aff35b4a4369e83453097b88d61395da62431f19a7c8427a2cb15eefd30b810bb74342a306b1bf26a0490af566f5a17885baa8f4a60e1c9432cd02a15915cbc8d574cfb23399ca1d93b95bb1e7a68a798a9b9a6d4dc92bf1bb84ba1109db395dc4b59f1931087e4524a090ccd037be1be6237a6483ae1a21b859bedc7a5a57a46fc02b13f5a446f4997b310b14c734160c7a19a36507876cb4c0cb2bef3bbc5d26281f15ca5d7654de307b20f9b3ebe90dfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358db0784a9c7dc25cb6f6236ad96784759277f660c49130a8ed9377f85394ca90e1d59467ef98eb555956755aa51127a26f498f3a6a2d2f972357b0b40c1254f143042199bb380ad86a04c1a8a1c4fc68166606152c5950ca8b0b3b86d99167727f623927963770a1423a5cbc9629f248409183cb5a0d99e22c915991c7ec3e5288400add0c355a3f94e7a4962a513b05af268e31c7d1c4b3fe0f0b8be500812bcb66ffa0fcfe66928dc86d769ca1f4095ea3124c5e1c7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c1703a0b7b86a691935824299062c5bf927fd5573e413552a7731453171c945748e9943429da1c00588742c8c2acbace1ec1a290e3830006610d21b945647180075194db0170426087112764bc23718bac96281ced834396cc8d4d003d3246641577bd11a59a765001215760d8122eef819f2d1416f998c7a8a080718a11774072f3a563a0581b92e5aa24ec05ec9004d578438313913b176e783c01e4d313648123b9db69d9e7c648d2cbfd42587ef1a2dae065fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9cf818b938843f78ac68ef8349f37468e81c06044ad9a051585c34d33d76cb8ecab0c0886cfea5c725b3013c048db0b7efe3792c6777a0b8413481aa0ce5b58228479f90c941517631319415dd52eadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f5903163a9f45d681f0c637a5f53f7ec0cd30c270e3b78ee4d575a3040b71c30106c6831dab1f2c8515fa8a6c5477c311e7023d779365466228aa3d1fc2b819b51e0771c989720946aa19e6b28a463577214c58bd35237c33573a75a11cc1b5dd8595420cb87f9063bb7247d88789f40198a0395c001877cc35a5a5171e3360781bc3588930827339c24233747d9b5d96f6a31712cfd71cb962b7a1974c3ed85c05a525a21aac83af06c68136cc9bb8b7d74216da468d78f80153bb0cd2b2316dc975ed6c09b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df8117d8312093bb3363d02c72f727f3371c2c8491dd611ab24765fa2665f612517d1d66882056903a67fd4173575166255609a54a3245d74b46c075c04b702ac4bc88e71b757907091c228b0182e10305b7c1cab0df3447a93219df5390a0302f99a0ae8bc51108c7c3397590f4b241165414952840303606e6c1b98755264b01280a8caeeec25c0818840d494bc436279a939d96c6f9160a01233afbd576f46359b2c75097bf15c37047f31a186b7bacbf23aabe9b7ab649938b08687a4b1734a834d3fa62a8a7a180cca4fd0a74c32a76db42009daca9ad0c3a6f8a06699630f56a6c793927d155b229269b1e3c94e0d23be1ee3121e4b638216c5b722ba3aa3129dd49bf1f93e78d16d1e820485527564405df9fc6574b7809a8bc289a02ea0e455a3a7813c195921194756558a6d481ff86a0de4dc39a347ca01562454f589f953837a256cb2ba49f200a7d1b22ef801109e2a45e28c57e201354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44737933cfd8c0e61085f2ae264d85c4ae05f8bd40bf29976c6d52e4f1c7ff709cccd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 2bb76b2b172b91454827ee5680a5d60d98d45f08c3d4b549edb5deb2a20970567ca6ec9b2c634d436eb162a1d19d64f397dcbc8aac9867cd71586f70a336add2d101201a6872f943a49f13e6994c61bf51830e361605495e42c54968e7eb2d5e99df9f3e997c72644e10086ae5f1b424c6db7aaafa7f84d741ab9a23959e111f749696cffcaa7091c00ef5f8b66fdfad2b47a029249816c59155c3695ddfac0837fbb794cbaaf4961e00973173baa56522f65f6cbe7c7a17172f6af28a5169002a1fba98e763b74df20e7d0d0fb73c01ef35bd12ff9bd9bf6c3074cc571fdedc187cbd9a9b7b02b57e81f4dc62e0cda4fe8e942121eac58a64f561f8a4532bebe68879f551e5dfe9f60e7beb44531432d0593f41545740a860fbcc36ebaa22a490575c8d8356c1678853172d8ca769cf6791431a1ce3f1c46673a7a4d3fb534ad97d11e79a0023bc90c74dc392bf240a675acc777ce4452749d6faf47618a3394529868e2093de715b67d0bd441df6a47315e6323a091967c647cddd53ee4f96b17bcb20de94145176838934926746e267db99703cc5c259becd0c31eb8bfc6e303564712ea222f51045b1ef629eaedd8a9795fac4b33e554f6f0a223992eb7b77d095fb5df37a5ae525201f67583fc94537fd22238ca6383fdef8ee29766a5435b6cbe75676dbedafda4b2515b569e5f3dd3480665f66b834d6ba52d3102665dd9eee38a6c50c81ee0d779f6b5868e5430686cd0ab6d0a292293aa780e196a1a31bbb3a8091ec414f4714533f117eb0a58d021b136a01b5eb83d7e9c8837d4a395d2ad10c0c06788b358bc8adf8c3d7363e7b59f757e6251fe08d87a7331be195836a16a742725f68fdd7f841d92cf03961b58957b3f533627d8cecea3cf66650a6d903e6fe35e26f5de9ccfc163ed973756c2e54e2fcb06b53a45d2a6db06aff3babffc02ef9cd1a509219262889dd8e0e8dd69f27e92a8131b02822fc6798e0317ef68e2a081c9a7cddf207d23e27b1c629868801ccfd3931370a87334d404b5ce1cafba023555fabcd66867f211ad534c00dba25014af836022d153920b6dffeb1259ad53f94b9ca9e21e31c21903b5b957d74aaa84ac4a55d172759331b5a2bfcf25a0bb4a43cd45fd7e734c8c0a965356f70b106c33a4a53229ac8df8322f4e7066aa00be77e9c0a88fe3917b2e09c092e30140fcfd6f215fbbb57e1951ded774d91774fff041c247d56f7444777d3031b7c2a849026bf132dc40d7fb4a2895872a296a3b5018e28ececa5645719866cca58a7a960d6aca25fa3baa95d411c3123b5be1bf279ad8503d7b508d1768baff17a412a43db832b589a9045b3dd859104eb9a83e03f70acae016347fc85638fb35c66409be9a02350d2078fba28f7db1c233d3ed0fceb923e6f587e72f22239a0ab1c7a17774cf18660cbce046551227a4937ca1ab825c26a9ee4075c4178c6beec79b779c2466ac7702bea20be1b167ee52e24ba642c3b16855d02e40345cca41fb38f4e06cb11da2aa4564f12c5c6acca2a41a83e0d37f9c12ea52eb82f5ee91bae268a1ee60b5dbc239ec33905e0d52170e90f2fc0121aeaa59c971a4f91fdbe92d248074ab271aa790e63f97d8b9289df1a7b5aaf8c9b942ef43d2ee3e5a6cb938a0353c326f439dabc4902a095fe2caa4b105ebd8b0c208f0342f17dfe818136f0f627dfabad97f23ab33df3a37cbbb664a0458665c795cbd0da8854c3e66532e1af1d20bb4a21bb0d25e8bea9db9572df1ace3b6bbfec6c9c20d688dda913a0bb1eb7435915964696f760127039f83de95f4569105785109bacf9936c6eefa6979fe67e026e353d0221e36d1676dffafafd3d9cb51af0ed05ff3d1cde08388199cf2defb58698c6f2555b6f587dd4efb83b10a0737b82ce8027cc8b83dc5405e5a75a65266d7e8b2e6b35a49af0eb41e0b435617d2b4ac75a0ca56ef26f6bf771ab0d971fe5caa9be849af1d0326272bfd238a41bfcdc14eaf67832fbb293b19a4b1752ca1e27bd9e79e0607d5217f980a865fd436b0ce35c3225e3a04e578d04c9dfd82d5f203b4d113ee19b0d097c41747908fbc4dd16304b56139e5705f2574e00af4ac6bed23be79919f068f6f1c68e9f1ac4d2ec6fa6d89036b46f9511088239a3c125d7a96a7c8f06339e73e9d358169a56c2099936f4fdc7c963afca70586c1151c547bbd299 +expected_result = pass +expected_shared_secret = d990008c5eceab7097524d6755c663ba04599eda80560d59088b21cd73243462 + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +private_key = c842401604c8c4c78d8417c804c2723b14733044aa2755897f65987951218361a07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bc306f851c9e93ac266e3c9e9c939be422b07e512d28503a6efa9d3ea8861e39b1ad481b8ad1805a8c0d48179aa1203c2ed7bb59d5c8ef651281c77f83ac7b49eb997965b161db025b47ce6e2c09edd41f5eab1c8b7b4d20783d60c90dbfe6ac387b629be10351868186f6a0bf68905f8c1cf34303fb577c25212919533c7044697d9425bfb76bd9d367f43b2d3613351d95395f4c2bae63b2a4608c69364f41e85d542a08f35b940fbc3b48f63360b50aa88259c7cb4634e5a34300c5957a3644f6ae381389b53210110329fc61519113c17e64782239941cfbb11a647b814372e313205844592cc3c17319b41ff21a0bda3f5acac3f18bad085c8f27b7758b7519316653ba9c253dc94ccad37f98d00b9fe67e2a13662c77921e4a9a86c8089682811e53a60b1089a1038483e615e6eb109a3b7636e02a44c2c3a81b96d84336cf594d24172be1bbb9c7b3685ea45e45b81d731b9b75ccadbfdb768119b20a0c346156cbcd5bb107a00a0e3c6e949b9db0b4ae21026c915908c5f38413c648edb20623f35b382b0cd5f4a8d7062bebbbcc9e809bdbb5c84042bce2e81bb0d795c6786af95a7e7b0629f7978a03558f98709a86319570273bea71986aa92560260d022569d4c98a85bb98aa198deff63dc6bccd1e6032ebab8caee5cf4717b17d89125c67a8a472c371153a4fc9045fd3304a74b983936060f42c80454a005342c1318a284bc5b9a71a39e748a94739536b517dac1619c00db64c81001acbc2793f9f29b42214442fba962f331d48c300da2186d21a4de61c4b5948c7edd1b9fa5865caf2280a81b9f7171137d6a678c92745b1aeb9db686ba84d65f6beabe332ff036bd113161fa068e74032ca5736d3ea3a01f1acfe067dfe5a5b398575bb9b148ee6155be2b4b67b348420ce758c5855102fd06a1fe8d347ef1b073f064f1f7926be5b2343029e5b7468e93b8abec6be231b6bee714031e04ed23c6da37032ecc00374706eff7453dd931d80029382f17e82a85ad7a8b25ea97d1d2aa21238b25517008b0400281168328b02869889f7f142cbf1ae8ddba5ef2713de649aa9ac56229494db211b90b96ae3b2829ae528c634110a3bcd355a243f3654295b0b79b9b7d43272321959b3632313aac107c8b7aeb83172778b7b199e736307fdf5ac6aeb40cfe750b7227f46a00b9000880d405877b63ff6c616bf4a51ca11c863a79b0e099308b42cbb7997420008268a3b762b9a5e181da14a4a92a5b55e7950268a9a83402889a98835cb9562a5a627750a5348b3398b39783009a081a058bbabcc7740af00b8cdbb4e0842c7f14b47ff4cb424b6252ccccee30398023a9b50b4bb4a2c1ff0a007a0a54eaf421fc2113f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c3420bca7c865aa22461b3d95522e9792b37b78c5555a62a3439f3ba7646076111336079bb8352a286e542094bb58b07cb832e2b288021034ed4934469b1723e57e57e358942730196140f47658258a761edcbdc046c08bb897f349b2930214c105792df1b45ac18e1e05c136921935f40951fbace0acc5c7bacbcf34c35da30a90671b63e50525d08b94632709b119ff39925362149e5b7caeb6a0104046ed846b41bbbd9c6b7ee8f3ab4e672b9353a929764c239832d9f6604522072c964ac98196d8302275159b9ca71b19b75881d26ea3374fb74181d558812b602fdd094b9e40692697cd4cfb1d20570256c0bcbbdbbc8206476fd27c0d0cc624e839c32254c0d76c558999fc2779ac592dfe07a347e9316a3bad42b78a048071cc9b67e46ab223a138e747227f777ba8310c83d170c2cacd25fa391c08a6d35096c704cb3e275d53f32c592884b096a7ebcb04ed8812f5469306eb6166073dcca7a5bc26357a6702b51688a9c13353bb1883d47accc185d16227ec704a60e57186e3135521cdf8ab1382a7b70f80bc782cb75f28c494853175599290657552ca4b406b54a9e607230156e14667ce32a68c3938ab9b309a36ae9b524999812779c1aca66208242a188617469930212f23ce0ea81a6d63a509b0686c5a63f44a0e9b691f0a718f02246fc688a248e3c2f387a55c463f0d976af9a2399cd4845c22516e0b3c882625aa609b64195c90925afdeb2901075565db2562b11d2c07c8d0d94122462c25a794da3639879a409256018f7418af91608b63ab222069e31c2ac0233e8f73ba8be2b0ac0463c9bc79cb048ae517295e8a01d2e16437088d20168f135c4d63b41021060a557003bcc935c6c97b3859176807b5637659f1b5bc4b488d4e5657e9f7b37c320b5df12bf31330ad27a7f205907d6614949bc97f3c1e94f21dd235606602a5c13254f43ac1bca2a6269bc5e6a96c31e30c972067a6030665ca7b05a700c53c560860a11371505457196cb33152b10f9b99518d4ca6433724a93219db1bc834499a019c02665c650c7c0d22724bdc0bb852c9523d1a9e5b06570a6610bd1175a74b869cca729e8c17ed5101d43c814fb18838f840884a4159bac515f7b5a637b703385e5f7115cd187e2964be55828a33656ef0384896525d4511aa2fc40046729f54acc768353b8001201bf508b5904e3603abe5b426dfb77f213c54b443b7d5ca6998291b56c379ad5216056198bf5617e58977a0490c308bb5a6873ab980a1364b1d25f0b01c3acf3221528c942fdc83a9a9a60d819c015fe06d2c684194c56a98c286b2122ea3fb9b18d003cf91453fd09940f7722999af0645b67179bb11b35a4cc56c2fc1c581f168f1918983ea00693471f6e33144c642dc5a4c28b01ef514449213a4e4749f0b2c40e6e06052d6870dac120cfc54aba5143d8ba4fdfb946af9c90f99ca2eb158f001003517b9aa7a1306973deb713671a16ba714245ba96723e3453718a3bca2ae2c1b4d0265102ed901b3a1b6b6ec639a8900eaf67b5e500876137122a5284cf52de9881352770a9d20af5aa59c71189694590c549831021aa911948e550765f8897671621e5d3771f1263f87220c0f0b28804726c112a7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d4d0021633c9744440f0f9a309d1467cca4d67a917198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62006d29fdcb62526714cad2ca04fbc28983b54b6b037436917da15608759abbc316e8359a26c55e7df179a74c39269c02caea7e61ca571dc771e7679e611b9eda31bef53b11e3524ea3f600fdab967fc8a23b0b73407738955b20b76c75b971c4c1105b9c5a3557d57af4db036454a22093a570f0bb10038bb3a46a0c92866c707c28a91b9e6172314408dcd3b051f363775842274988340165887a027bfb629847b9271a5f66c15c286537c76c31f62b45e2995f0aa30dfcaa6bf2883d1deca9b7b2029515c564d3b970143c29956ceff588e99b8025a2343efa5233361bb2332afea2499656203cb712ac8cae4ce1489df2bd9223c3c65737c101c0dc5c2bfd83444a29c64d8812cd69a68f004d2596033e903d744abcb688ae65b0371d711b187b62e6c755f2f947d828446fb45f30c42da615b3c5f682f2157e940691ba674571573647c09225748416529653845a6944859dc3c62e7c0a9da78a4ea492f57386ec31b0c8730206e5adbbb0253113a173e20313610fbf696803718a0d393e7ce4165e004a450825d8935f7738aa7c6a1226640f3cf40ffa6644dae2280043c501635550bc76e8348d133a55cd73001fa3197c1a071bf30a1ff907813aa8b8986449918c08164817720f30e44828010aa6a11a378261e8b141d52779f73927d7f505dd99c7a43a2db1197ba33a2950c280549564733706009185a493b59bba67bd511e4dc55a4f458d9b1003b90a30aa87874fd83707f1cfaf11a4b9088bd41c8d69bcb77853b396c15e24948722943f0e28c4e896c56f7c9d3974144d43a4765392bdb0c2ef5bc72b27b11ff57d03a8214de0520dfcb3093b5ac72003c615c04f64693f68c0d17cbc34f8cb1ea068d681c917315836005dcb423c0695ad19a06801847e947b045e7b78c9728cd321579ea31e5d7633b121884ef65095354dfe63891945983d54cea2583ae4b64f54065cb5631272e1149c151ed0715e93a30c38c85c59415acf73ce76d9453697a3625a607a205204b307dc3c92cb140f1a75c671e916fcda070567b42a2aa12a2499e26293da440b664bb8337b6d5497471b002435c8b40872ab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923ae96ec4edc7ee08108fe6c0411a96f48731066ae4be12edeb7fc667039c9c1de8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = dccb4033246369cc996695589256e3fa1fe2702fbd5e0509fd02024cee12ee5507a2896d4d0aa03158ef904cae32b231b420c576d0db77d2e9a655b3ed9e26961036849742263244171a48c32015678f8830f08b904943256769255b0bfa71d5c9a727c617fcf7c3d029f2c090db9e53471c6934c94f0149b6e81c128b118235cacbc0d1ea91b79e9223eaa95248befab41078c39a3efdc033fa80fdbefbd4b72ffbfecd8a271f992afe5008ded37b98053449016d4c8c28ac834e63abe341e2602ad3873e5b543e8a4b53f6d824307d5baac7313a3f42e2dfe476dc2abf2b7230b4a71e04949bd08d77b420668ac0e78647be06552eb03ea83c56db72e4b0b41a2e1ed176ec7429d510516c6056a8c2dc35e017d8a9a71e2c0be30abf65994feb4a4ec45b4fee8377616aba107b8350cdf2ba10a1d01db9b9bb789753785ceae2bff11d0adf44b17e64beee6a233695d34ccad2fb1c4e36b5ce20185aef568216998d16c3cddd2e9e251800e4f1bfc9033e2baf0d2a594006e59341054a07be0968cea55839536e240b7a56c9e1ca5a6fbfd0bb23962a7e721bde72c25cec3ee610e0fa2c7ea175a355f7646363aebe34f6ce18d0267aec0cf27d91bfbd6b34a98d6167751fb98f0047b5d0a43943b90f19c0d459e78b46b568c5752361d3394ac4bc7c9ead6af89611786a99f26b64534f0f4157c4fb737a1787214d8044cfa0442815c5203adbe8d1888ad78eb9a1a29e98164a41226d356e48cd43cdadd19b3053d2c507ca4257a4c914552fe4f2ecaadf7313925a1da260498b3d430d6c960d3e8c1dd31dc0f583a6f2a013018ab04dc52fa00a80ada1022b818f313d9388b73edef561027c6981c7bdf98edf623571d3a37cb4f09a829316eff704335962160e333ee52fbb0dc67c8cf6ddf7e84f576e68e2ff6049d8d3341856abad05ad6223112a7e8056d679c5eeced4eb96821d040d283bfcca64fe5398b0d3b718731112862b681fec18af5368dab3f3dcf0cdc0a2311b25627db2aea98633c36c9e822c4b38602cbde7ab727b404f382fdd9a4052c7b57f4627d62a3920daa4f6edc5ff59cfec7ebee4eaaf0d3e89642a7de253084041ac44262ebf5e11ea9ed394d0ea16f326dba11b5759e69cc9e9acb0f963bc3703fedefaee9f7440cd6200cbab88f447e1c6475ec5dfb2debe34dd3c77bad7802cea500ec48952bb6e18b4e4f83a0fc3a5c59f7a06167996e9bd353586066f594b8a4d90fb027298b843e10b008ff66edb74aca345e475f1cf49b1106b9592f1f7263b713acf9e3a9a1c024ff44126166dd59977bd565902dae1ae0a788c1157343e045b0af00ab61fcbfc814e667039ddea20714a2fb49ad94b5dfd84da628d3f1119c440b6de841f0adadf874863ea4accb2fc0deb9de1dd18e3bfe372b92f0d72a9f61778c0daa54c0f6580ee0db7de48c09427190f3735051f06c83ec6a0425aaed68ac49a8e3725fed6bb1777f6beab59417f398ca66975cefce96b5775bbec006246dc8ecea177eabf074accd9b6661da939e55873cec5797bfdf579d38e80a7a2b5a3ee826ad69429a0d432d0b35fb0a51f84d418bb8b769a32deabd8b70c40d8c99b95a3ee7f5ff0bc243f76c6bbfed2fb72a4e5642bca96b0959601f3e7e4c029c0b04213fbb3582668b6e4561933aa1beb3ec12ad139af94b5f688b9c2da98ff4eaae3de57b0e2ca894114b969b8d2ca26e7af503db776635098b90039919d9b136124786aa1d123f1b9cc93afb6e4fb8ceef7e1fc18f6dc804f7a4b28432a689f98e67a123e177cb4a6b0178c3dc0c62ab19f93f624c2bf14ba6dc1702aa547e4bfc713ab95a40c9d8722044511ac4020c70a6f435f5566d08614ba112fc4ff8c2e5e1d13046a5a03a15ee834bc92cd63f0078fadf9aab21cc3f41eea633bd7f866b4701bd2da73674c8d3de6138035edeb47f5086f764c92679e62f0eca34c873e6317081705e69fe45331fcc807f4faef5f75f0dc054054e5e1aaf05f848f0d43ad9f456bd3ebfa809108aa1114f34b47e7fa34483982689cea633c541a243dd48b109922fc1277aacfa681d99c4879cfa4aa783272136c555be0be3149566a2ea5e11f994133220efbd7795f4975a7cebded59afbe539250099b2d78a11bfbaa136229abc4abab7cfc6b25a89b8b9bac53f1b5c4ffeee2b22641122e9c89f57b03d03e25 +expected_result = pass +expected_shared_secret = bd50423b4ef27559d67532abbfad2a3a388e3dbf4d7b6488c2b48f19cee07ad4 + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +private_key = 0c9c633ff39d1c6c29f8356aa02981dcf189d6535e2ac00750c30b111a88b21024e4823e7d543614f30112f7c78f1679dab68b71aa992538658fd0c8e2984abdc09647453b3fd99dd860238cf40c9112a7dcb57e06540148ea4ad6f97020474afb65c5c67ab4fdb1515c6592941b1e38d4097155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b470ca3fea3314b4bb404cb66e3bbf8f2953f2682cdb65cfb47906b3962443775796564d75cbb4b9bb24a8a98d7723269e8204ba89782f974ae591808e97cb2468252c8539c2454041c9232f33b43ed8359dd6856c98ba4fc09e92f9a4ad497f8f1159e159b5af795ab09c20aa753931f47764b6cbab6968c7a779802b469abb1e7f677a0a485ff5cab2f028112ee8c35152703bb14127b33fb00a0ce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78557b1d31686c6b4c3749958efc60891f12c9e0b7c19613823eeab1d8f672089339e46c16daf0c3b7d53727605c26a723518a2651d8762ac373817bbddbec1ebca2cf91fa2a66896c55a4c946a791e5502ff19aa21cb132322bbfd127c10d87563028bc49b222e5401acdc81991828e4c111a54566e5724b40a452c0f4632b7b85f0445c881938134d516113560b0065beb409fceb25f796c0ba0ab190fac0214007916ca93c2abb11bd88553aa34c3c518bfec423728c86e529c300a1f70225f2f683911040ff9405614e1baac070e0e90337e134e3c93081514a937f9798ea7b57b3a3a0b829a2697b0778c802116c067a5c368576395c43d33882f97c770519c16426284e19bac180a2a6cb85d65b1a115316b08541dc231c123c184e82c691f20749a4b92f2d1040d09519df7678ac282fff9cf5124acbe04388ccab61bf71b87ab3b830a3ef6700a68b06770012424031e89a895ae81c8aca9169d6495cf01cd8ba0c27ae132c16aab0ebc4b13abb37d67ced10a0246e87be1233ff09a6802f6371858972d21b48d410d8cf3a8a1e664f62028cf851a134037142c20e8eaad7de32581b39b5d93221cf72124a73daa2b61f3d7c8f25a973a815b351206800bbcba60ac8c2a86a7758b38339751c23ea5523d84ec982a260256c69af739349d206ce9c9a70dbb0a950a0b63815994a6878711578bc22942914df8489ec5a09258eba796e8a6ff5483a71887e55783a94201e5b88898870e67d32eaab132519624f4b28f22e80903e591331ca792c0cef824bc62168be6eb8f7ba299bc519b0c370509e38377f171761521f8fc882d1b8d0db3c2109a43d1754f75529f7b071b7492b753688feef12fda217ccba484ab79192b7933781811986430bcc010b50a5621ec15dc7bb545cabc77c336892a0df4436e732b905d70769865cdee0a9906438e9d921f521862a3227bab93202da0cd19f6221bb68fda8155ae38132cf2a30a4a5c3dc0b17df0016fac3bdd56cd9d06cc8f2c6b4ac41207fc1aead0cd87506caf5c043941513f0a4abf725818c7686f0745ece93c23f2951ee263f51a3fb3630076dca4ea80a156dc6b4248246f638024b8782c9757e076ceaf18cc27284c321ba91766454640ad32d97e65650b39c9b23fa80405f8cec82abf70ea4f4d24c87e8b253f708f9a563c78655877795c4f05024a788dd4bc7ec1190b606602aa40364692478b3b552c46b5720acc5042be92ba8760924c05a60032c52f63b40ac50086a62548dfe9b312f2904ab17da59842da877355360e217917d7a3c3f1a9b9f2466c8fea980be798d249ade8389e626a4693ac38a844294842382e0c5b92bc25b29abc3212543ec39eb2409858f9c8a22713b043713bc00f1a77bff5d269698b9c91706bf0326899791f161b481b531e77f95de95b45522b9a4f0423eca7afbe418848137b925a6ad13bc792194522f00661742f5e4a0e4d85aad8b36b6540a1b25a4a38c32305e543a6a13c37b48296fb84a3464ddd3016771b79e33251cecbc2ffccc6d3c06d4a660622d3630661543a001a3f9ca586c9354f513f3ba5c6de933db0d0690e4102c9918720437f437354a3107849775c95c4417bba787f172407fa0564498cff67c545b7323c442b3cfb11952079f1d11449bbb622630a6945c402c7008dc7a35f380c2df7c5edf8c9c64432afa34cf0547882f202b7572f8bd73104745eac83154707cf81c85377ba36b111c9504a180f01c880d08b55c3008a9594e75b3f026a103724064393351dfa7eb5ab9a1c774a59c47b31437011816abba42b75780c1ea8769a7bbd1ba60e686c726f2aa6c9101614c213a8147cabf658d5505aacb288f065bd31c5b7494b377ef1ab72925fe513c49ccc130cc542aa34abd31b5d99cb8f6e2b9a1c5417a4ac9c91011627e6353cb6529ac19697d05d076bb197790431f9ce62a31fb8154797583692ec9abf67b678e0c204a822e228b09bbb7b4cb3a5df788b0930841aba9e4f7c1212150c87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa500245acb15b7dbccf9a013326c2b0336b66c101aa499159a7c875eb6cebe292d266821bc193ced74b04e61845aa5b1ddc953699cbb7743cd76d930bff38efd943c34b01a8d973a81247d966825d1a9b3b2fbc5769c9d5ba883fc357946d54f3cc3090ee48eb2fa80b4d86dee07c57c215f07dc23aaf8c4aaf2c9e03ca2daa433fd9c584bf582793919449925f27786b6dc2de9c5cc08220feb501fb7e2900c243b1c357c8fc814cf87b233b70ce6f0938b56698c160ca893afa877bba49c0a8f606e30761d9dd14be7a40f8db95496865c2441a47aeba1ca7458256aa5a910948d4c920d32712c55cd8546809704c1760c8f8ed991d8ca570cab3441782b6e4035d82c24105397cfaa8ad86a385327873a228bb0c02801a50340b70e5483709ef03de0483bf08b940c4aab7a61c24e9947875c8e2b930dc208ace4752da4d0253ebb2bfb333a1ec9bdec73283d435c4d061df6b0692df903c6481179e07adaab8d69277958458f6ff5c6e4c92804ea47bc8a03bdd707c1a78d912467a83575fe74aa25c043feea0be5899210d7c8bc8b669fec5840f5b1782a5a9d947e78301eeff9b12635c9b15176499a3593362fe5a946fc98c7083bb185c2087b58b6d7caa3599427259a72c6f89fedf61f7e111c04f008053cbefca2ca13a06d09d9494cf29f82c5b93bfacac8d705e35874d0297aa15c7fb181878b32459cb09d6d489671e7700e4731e783c73c86b5b8731ae765a639b20f8c69844559b0763b5cfab7396c1aa09ce238227c29ba34a48891a39cfb37f1226cdb35517d354d422000c3709b7cf53bb9807e2ae7321b38bb29c327e5eb3d02036b1a4c61a2a66a3e91af4288875719496003988b488d84535cb66a4a1f1ac69952817fc13ffadaaff145780aa02ac41cbebfcc9d798cc4d9a090a4212f0fda861b8760ceba5f334c1a54d52567c2b51628455c85517f67baae5c694293c29a684984ac3e711501d5219fa8279bceda4d8aebcf17babe31fbbffe6c297dd27cd894be83b416ee182306d65d2a962f64811ad1faa4ce72a6cbb1c5d22a1c4a2c1eca36b38618afd0a928c4db55b991428ad72a40679ec7521a170929cf10a41cf63bf0dbb5f1316a23d2acce5c7c34c67f6b2450f36556bd987b525a009c77ac7e23355de3aacad177ab7538eb7b25d613a3e9c11c79e59fd9ea263c0178d47885c7384b492909fbc63ac0b2a4ae455dd3446b395c0bd001765f31c79649c53453252e02b98af51f23f8b2f5f2c8d3eba71ce67a95170237b7a408235429826637f8cbecb11a4dc351fd0134a0cc7869983a02a50ff3958e445a9dd35023900b7a3c41ccb66a54628741adba17da89cef8d83e8f66893bccb50918b6cfa1480b051dd0153fdf5a0561c2c782dca0a02861b87a8aeb304927716884905e1e0a004f3a119b3293fb0850cbba7581f1363598c1384ab228d8720b4c6124e2ad1a9774d7a16880542d30dab2f0796fe5536402bc10326c7577971c496083e0c24541e07c813a01989013ab9580abcc038284588294b743086357d50b01e93d841c6a7b929d32291e47d2419b464c3c692847f7706865a29335a4ff50c536991fcb790d0de50f68914d1ca5b438bc0a43393510fbcf15a895d5d546850c0fb1d970517819e841cc42dc279e8b398a563c174c57876605e1212be53ab714486588f96b8599262d67bbce891b90308959524355338355598b233aa89e4679749207f3ba1086ccccf836c7e3528989d0848b947487781a2b025955b2c748c700b479216c3caddcf63564392d6515767b771a21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e4e23909b028699d6677eabe6bac4bc4e8437acbc52b0b17f1df5760c0455c2b5e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = c688351c04b40d541e7da6b46d4d64ca90ae56db02257e9e64834e004827bee1b5b54c18e45c2ea9f379775f2280097b9b992547d209e01191328318d06aa7f34050ec2064da3f29e2c5e326c5aaf08f10bb8831cb81ad6640e5873cdee26f61311429a0c6432a1d2aae2c1bb40e2ecb57820c0634f242220c931ff3cbc13836cfad3517e39300f4c0f98eb3a533d4f35c5c98e14cb2c8d3ab3ea556fc9a03b09abfe1dd52199f33bf176324aa13f0c9fe138af8c84f889b547bc74539482f7f80245537573bdfba12c0fbd0ccc739fcf40e8f84f7f6b796af05b746ea4f33eb7977be3eab48722c195b1d4ef2b56112fb30d9f7ad31d31c8e7640c4ddeeada3ce4c7b6698d3e9b880a682d3d14317c04013ddc620d919dad419013e4813ca81ca9c2f3006d859f19689549ef64f2967e80295dc834bcb0c23bad006210ea8c38843de7983bb9c1e6735f853cbc559f121dd5ba19d4f7d98ac125d8efa03b858466827c6db2a2f0bd27740623341a691af087e416dac30a2e6d782c4c43e4a6993fd4222a8e2958c40d285ee743a9b32a82d1918b2eb216d6175ea69643d2843a32148b931b1d93a793165b282e29c2020ac05e2b0fa9d8ca9f76f5790cca5083ee17001f7f43fbc5f8429dc86f4849b1ca16ba588092fadd39b93d92e4d42aed9397acdbdb99e12f701231cb14800eaf02c948b93362e4d88c01f57e4ccff0d641fb2a209e706727d236cb089bf1de19e64ff0eae24a89a8661caf94e74310b1665e108a0317824b8de8a1a6978007bbc61971ec7c742a588b704f357ea8c22007b8b60feab7d9d78d6a5a89265d263f4468da1def7f165188ea05b9fbcd80431e21659e52870ca7865ade7d1f7d0a70373875c07ac1a23c0ac995f7d1ba610d0ed559083fcc437e1896ac73918b0c1dc290fe648eb84d9a8315e01709a80a559a7a54b4884472f0f785aafea6a69cfef57d460910a22bd1bcfe05e4e19ce109203e4711605fd982f32ac8152525b43cf9ad8a9500e7c90116cfd8e59fcdfd9aec7978ba333ffce54e2c4c6b145aa3fa905212df5e3e0e03339ae6c5b1130672fc0d3a98d4e2ee2d7550ffa0d360f77de309798d64dd805b3f4887d3b3810b44529c0b5fa39d7de88a772e6f9228755cd3bc05e5eb3acbb2f7c445e763fa463c54bc9681dc51585f2fb6203381c466f89f38108ba3c779e0794217f5154ab3534ed0627367cf8e7a8a6f76d3521b632b661429845f7b173b5f3e3232cc391eb8de1b0cca409a717222d2045124f9dbec51c7ac8177ff637dab056a0c649c5bef3f9460d2a4047c62fc1546eb291d2c968246533df79185cb9e26136651c5166d37e531a35aaa41f6c7edb7bf5f1092695c270693723fde78b2f36d79a109b225589c97db8db07343a6aa2fe2a43f2034ae315cbff869880a53aecddd9e31eb62dddb73a615a1dcf163e51423eab895311b303170aaa3658fd8eb6be92c3a377f197b00ec83e50ca8a0081a5280908547f9d373d7e1d54361bb7cb8a2d08ea054024b25b47365550fd9c9df1ae1bd2349990b776e350b3f371fb466813faa6b6b4e8d005d790cc69c77d7cfcad983aff636edb9fe06ffa0079059fab7d0e30b90c88779fbe65b203460b7455a08867c8840ff5cff27fdb33f8b81591503cdb3b0d1c61bf76be02b3259892f20393a1cedba43d7ff6b6a83c648ac6751c3f8e759223cbc1959400f09eef430d179ab0ab40840300afb19ef43d685a525b9ff44c49a5cc3ffad91b6a64049298e6b2322891162c21448f416484c45573d306153d7cde42251e79b15f03ec742cc62eff79b0af9ad84fa1621a083b97e51805c310483380661972e141eaf12032dcfff1991a38df720bfd3a2fc185f6edf150e873fc33cec05f8e6fcee6b7f2c62af3672844ed45b8237495d6b7be6feffdfa65e61cea2c70b9b4bc1716bac1d4ff28f80e9a3dfa7cdd559b3bd0322db1f5954b3fa0a25e7b5f4dbfed9ca6c7a917b596f323300863fcdef1102224942ead7e79646e67294cb3922609cd19d1f2e067df2f5a0a4317c7c50888af3417f55b5183b7331c85ab82293c5ec4a43d412dd6ad0bef34041e0bdb4ee9d6cec778441a7a088e368c7ddbb21456f7e4b2c16ac001b8ebe83981d9881b5f2fefe910ef66866dda7eeef28c474b66b72f3662d8063e770f073d03f4a88bceb10eb195f3c59128 +expected_result = pass +expected_shared_secret = 38e3d97b0547e648b2b722c4844f59ed43dcc4b40fa7dcfe6184c2fe62ab3530 + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +private_key = 2ecb7caa911a2f615a13cb82e5a8be85e1c2bcf06c71b9696682532639b57a91537e470e8514390949cfadc80b0e5c3ee3eca869e22250560d8896b5f6eb0fc6ec0a6d01760c9108b7a26cd79039bcb3cf9ea0432fe0581626cfedabc12f758b407c8e9dfa373f45c377fa6d41a7205a7322b737cdabc8114df437e864c4abbb3dd084964f971b36e24406a7a7544a260d917c0ef95ccf33b1833bb6d4232bfce37b96004ed7779258faaedd9abaeb5051d8f605eb85be0f9599ff28b40587488fa376729685a8336c0dd213f55447e2c4895111b98e73bd783b2d08960abce22f6f894ae5456577a81156c66f6f1bbebd9c04d1ac43b77936f13060d3305a3893a825781e47928fc492adc16b31b2669882fca10581603b400f297b7fe7525d20e82958099b2d118ed3a14a8a915731525c470b7852a9b0ef04b4a3b0b65b4c5d7d486366175540a91e752993ba979d8a446f94088c7c3a02fd5c051f900a141957e63cbd71aa012db60a02b3872f3a623218a6b1f628fe8580e8725d9fb647f128c2519a8a0cd0649671616b462b83904ce621c95ff44697ca71ce930eaf0b28a6448a1c6b38c14800427683b71c954e49b6a3b978417b78ddb1a1b9729b89160b4c7ba49f312e23632460913d82d655d6e00b5b17a635827d8a0781e12a68c536ab40909f46a7173fa9cc9990371dcbc0b8a433436133ac123a73664a14e1409b4476ab001c17f26ebe968ed8c6a9d491b92f234499435e2df615c849be5f6422c8bc9de8f148a7c0713d93642dc852b33652287010f02b1d7b77972c797add3a38651b4c11ea968ce53f10d38df4160101fb0ee557bcf5b3328e12150a7c0d769812abf2ad2c1c7661844e6b34b25e7a30ec64b6e7d4282f48344bfc6f33ab3c428c76705cb9b1e9637721c9ee60874017013374082892b4af174749041c606b3f6690146bf1b0c8d2844f80594f265a8fb639e209c9b7fc418a230aaf340bba34c1c66b7d570918ed6caf8f62768620058cc7cb4fe1c762aa96a5015b82216e204c5821022caa84af9b12b9c9bc683747a2724c88e650539779742edca6a6a6c5f5d68faaf73d4cc7aab9b105f3a1b46cc96c915912e807aa6c841f6be63812062ed1d07bc9164eccec7e6662056313cc32f63c6181cf3343adc9073888d5756f508d65025bf6490a5f6b164a942466e60c4410c72aa69d2ca10459b890a4cb22a7613d44e70ac96aca21169f932a6134d27a6c05582e830c0ba137df060c6249b360831cc6b993e3d455c2e61694b11b520c64078bb552a65a3bab407d46c0ee173bbb52a95c7cbd8612380fc0cf1655c8e691bb0493103ec80a5fc92b4951a0d78768504284ad52580f16247b3c44af0a397f28ce3d0c0e4d34cc48b26b3998b060f2a9a013889685446b6281b3341c08e8300a013390a881a3a4937b412bf4745b069acbf5315b9955aa4999ba827bccbbf776829291a9067272059104522d69d1834886bde76c078a6061305833fefa710ebbc0dd0729493a285acbcf2708cf93ecc76b85691e20bfa4379c8521420c231f68429bb5c76e69378f6ef3475fca5760a5be829c2b4fa955e0e0931423b0a615194c26225bc538e2db29e928c686892be81b1a04f94e9ba65ac12a68d013885a021d91cb21cd7b76f0138667b5ce8cb742e5a54bb34bc17b28c8af5c27bacc6c308cc127a0152120755dd61145970d3cb02c664c3fb8c5763ac841f845b7799c9cf7f61318511b6728499e843ce1a18093ea1caa879bc6f1c4aa5a279e80afedf5353c5121a5d0433ffb748c0790161b648886a87fb003380a1dc289ac2bd876262c90081470453b12f5970d939c6bb573263b902624b03e403395a3a9a3c8b897c2dc5a6b630ea4cc87b6f456b5616a008c8dffd6b970541117335189fa4ce92883b88b3a0917994974cf4837b7b31c16d36bcd867181411239086940c3a03dcdb612ca1411cf6038dbe35eb013658037b98d329d4a647d2fbb7983136480a722dc791e2281c251040155fa5b0c092d437576a4f055f1708c58e3611d3071eae9053c4bae4af8769494077912af5ffc129c7164749ba2eaca0676f02a8c4bc1545c405ab16e90012a4915c4b470c230587f0bbbbbdc3487387635e457c66e3ccbce8c75048527959651e7c99be7540833828e457c66edec8e201b07d8068bdf671086d6af0beb628685790487707b66be4c7341c654a8119774e8b262b2f34944898e42752149039356c1348eda779b526da7ac838551855a4a8af5780c5567295dd16011e3177e267948ba7643174391a34c5597b7af774256329f211518e1a67b2f35898e610f49500c2b4647297723004ab77f9b538524a9b96b1e5fca8f224c2e24701bb726735b408323784e9afaafde570b2f4c2bba88bb54808ee73aae69ba352612268e9b4460f004af4998a6c484474c0d04111f2d1091d31443ee2447be719e8f4c3a49e918eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523ae006853b5e09706259605e72e78ad6fa602bfbc7bfbb0d2d78b5155b3d2017c9086803be862ef501196ebc2af13b2b0569473e9620fab2c85fc23874ac14b59c0f082029b553184b01c76d856858475914f025df1914c16a209dc90a306914c3371a6cf68473a431b2886a8cd40a5302834a73359e001658b90725e02e63c27403fc0e1953b11ee6a6415815d2b2bda0b13e54511c96b801da22b5ae94b68dea940ea4787f3a1506e290696c3535b8ce73351a6e48bed272af5e456904aa03094210494c90b280c2942682dcacbec8c644e9a36d326816a42b23b96b751afb7b951a87d8e94db48932aa14bf73e92b06b85f7afb4387e949645c5838622ef7bb2fee0175914b3c931b25f80a010568a179a21727f52ce578aab6da1a88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e18fa294b7b8055e6acfac6242d671855f29979609b821566acbb381dfab0cff8bd47204fec023ef281226b63a7d0397091a9844e23b28f57a0dd205a520a48a3e517276977388b575522c5b78627c4253bd38840a7889fa75a7bacd10b8f27a3e13bc20aba3ddaeb88ae62b2930338cdda41e0770b4d2092da100aeda2b5f5600718d69b032a45bd677b8732965b82908b877f5f77446e4aa132d46044067b21090404d21d01231264651b38832137da53caba0865957f5af7ac4d640fef96702f853bb4a70767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5c81471539c42144b4cab5d8d53285f8c415cd8cfe2d30295d00dcb47b4ffd90282f6b582a57bd3f13eb41b088ba624575b355f8c7fc0f34f1e924fe7d653692c4f44e1c64f9cb145fbae9e789c029421793a4c43856469298b4ec648b21babc0167c04d90a3a8c554df46b80b407dfca54d5f68e2dca4e98a92ff38b427115c26aa33161503a83143714234fed912829bcb924d69049a1c958e6a3088cab51f956c87862e776320e78457cf31c20957158bb377460bfbf93a44c079e1f1bcb7b4268a0cb1cb8151512dc632252700cf06c988b2a3b254ac6422c73432ccb143819105897575c8672b7b0464e61a6a8891bccfbeb51f96120107cce8e950802b2c04650a1f264aba721541897538278bbac29b73f811940a47249035b04c0023084bf57806d51da03605c0ab0e6a6b65cab53cb26425666dd1b597418864211c6bec492d4577bc127369af391f8ec72c53302df5013c2c7c62d364b35508219749f131b7e2792cb206a9abe2c21a565bf05c1a7f8995c89549aa3120ffd83cc7a8b8a95bac3e7eaba48b57f55829f05bb265cbbb8b0b7983f7618f2511b3fe3ce9a0b735f2c1acd189f9115a1f1933ce19a8535958cba82464ed9829bc9a0c1405266f697d54128cb31cbd5b95c72740fe16219997210512a7343130e7dd00556948abc6c0dbd215e9db44a2d80c5606b930c6c8b949081bb453461a21026943929d3bdd3c942f8951aaff04276d2186cc052b6f67e84d5aa6be0c67ad74aace945ddd7c4b75248a0854593e8b27e971895b58c08e8107214afea3aa1b41a17ca121fb8308eea899e8cf04f7e884cd40746f2106a86164489ccc20f526154e613c565a282d5742f4953e963c42e878ab4d6668cb9c15f8629f537cdaa078db33191ee281a46ebc2a3036639e5cb1b201384b222af46873e1c946438125f060afd4734e21794a8da3d7b266c4125b60c9c480091874ae9c242f550898a30281380fa352c0d4466295a24653181e0e292ae099abec3275f8a89f22c983c8a0875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433513906f5bef81445bd210d63fc4c9b9ef0b61c17b0cd5b229a45908fcbaddcecded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 2929caddd4f0363b2578c242f3e6b4978d19f155c3de70cda974496e367811fbc606beac5c6462d68141dc06dd9a3e7fd30a4019c010f43b1830e197aa31df52362d0b969ea4d2abca78b3d2f9dd6ab72b5963b2bd469d4118337fe5792f49e424ff43c31dda4449ecf3988be6ec3e353ad357191264a54145eb5643730da691a4334d3895299bd3f18960ec2ae9a28f05f231e8935ebc4a9ed71752030f40b849ed7d5b81c64171ec4422793fd0a23e85283d59e8b0dd5931436bc37ad82594ef3f73d2c0e64e7c2f7e0cdd14a8ca835f8d2d0cd30b726a0d66f529c0236069f0b8e87cb2e022cb255157a77bdb49fadd8836010f301208d3a70d8b64a7df70d4a15b1ea9e3f15f91de9b934d3e4b17088037d282bfe89a2eb54fa17b1857d977286e238f1928ff0c2d200fd6122b2c85b80e75543d9814ffd2a90f4d7bd51bef826f8063ba56e1ac902ad4499d9025fec564f2f87c4fec9db6617b64dad6f35a8b552f7da029d5699fcf6c477201e36fb39b9f9cc40a5e44366ea7d894f579eff17a061f3d2861b38b21a25177fe658627b7a11e136e490810c9aaa3ce43a7700e7a30a014bbb13362657b479fc26b447b554db4de68dfb9e4912327a6f1c475497a5638ac334c5fd8b8a2c5a6d27e7f9c7e9e6dd53d5935811a20a24a46c6cd16912e6917946f5b59c47afae99d02c93778e755b6292c5bef16ed8fdbcd0ec0f8f27e2a4958ad98b4f4f78a21f6f4f96cf51d97fe0566ac95f01cba045685838f7db03d30ad856c4ecf5f1480e2fb60e55af50b8ca917e66e3b84cffa0dc50f620512d9139701be43810caaaf0c762ddb843fccbfb9205787ffcae3cde855013c5ecd5f64b68006ce2fa6dfdc416ab81328a478f2298e144cfc12f763daf2715652b22c1c20d7d1365f6d29cdae850364e32395960efb4d0064e96ccce5c4b089a3aa56ebc5d18595071b594024d392a536790f3dd1cdc0caa5f8367a5639c7586b09d3b1da545bda09422c9243d6f21b3a023ad806a0ef688d2df93d9f7aa05752356a90375b1a101b52ec1db9c196ab7532c44a1690f15fbfd2606a646592d44c647df10524167244a0b1623abb9f26fb068bcf72b42d09be0496c326d37ffedacc15265f7204d5892984c235e54cc4f3c0af4b412cdd51961fb30f4172965a54c2142e93d06e6486a61d748d138c71329990960c4d5b07d05d1f795b91b938f2f5f2e1b13f601be67bcc226ec1e595b4fa8ccc8dfc0f380454f1df747fe796fb6c26bdbec6ccb15d2fc5034f539bf2f843fc43a36405542ea6cd388a2b3d18c67308d6bc9bb379fa29dec50142db422ca575dff40fe21625dbc35bb3696f24099a920c6ad21dbe033bd851298edce552d73e0b77c81d7ee67b792150caa688a16d5a933545340025c60e95911002190327e62ba892eed528a5a4a4178a13fca93f203a54b53c5958a5dcb067e108b7b8ba1bfcffbb2412d0b86c6012a7792eee413443a372c09d4ecf3bc0c751911c33de3f003ca1645c4de0341192c6c5bc402f49fae10a7eaf3126260eb76c1c92f4629204c7bd70e7f26c8d6b3119fde18fb09d327b79bcc7b687dc352574b224977f1ec61c0dd0a6bf6cd527f24948a92ba5a61fd458450f045ddb8c86f3e925f5afe9302a5086bc0f09f759f8b59baa5f6cbffa93b5eb570fa0c5aa400e4164904940e94884824b28f2bbc7b4e79bf9b6e9002ebc9e017da0c49248065f37718ed74f9fb32ffba07266d599a989602b55d8a700a2108708de10f227a82d874be5f8b1489496970b6dd2a45df290227728e833be6f51bea9e22d186bcee723bd71d562b100da63164fbd38476a3aa305610ca3f3f96bac26a41cf884fc6b201602c7efa5097cf59a06707d7dd86ae4210016df94a2c9a59601a1b6d87db3b8d3da59d56032165c7499b6581548e8d69fb898acdbb28adfacf9604d47ad382d8b4b655cbf76c26f856ff28693b3c725f047bbb2fe72df9c38f58d8cee3435eb7beadf4450af322e3d837cce09d80f2c9e932d795d00a43c8359cac4f9d3e2b80d63144bed2559c9b733220c9ced94fea87409c42c7f5a6f2c8fe35e0389c195fe5c13a18aab1dbb97284a45d0bf87d7d004c264f8f687e93526a0b64632d6730a76d1869aa02ececcda1eeb1d05688782fb86c909b7ec128c081088992a7d6bb73f06644b9c8d6d12a6f88917ad29 +expected_result = pass +expected_shared_secret = cca4f1d172212f8c23eb5da77144640d821d2671f66f0b3015d0b46e274e193c + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +private_key = f3ac3178bc3e6b8002eb20046ee3288f9cc63c1abd0b14a118d52e2c9a998d4c67e2014415084f520945f55b985adac8c503079789aecc491eb7ba540f32be8823a4a837786be140d260cff5d46186588f4fe2419e0c4ba1b619567b9d8206b53ab1289640520f2259f5d6854871498b23696a321813d7a544e77fb3100b34c89af2c63856fb43bb0a74a6073958d1199b4098386984847962b353b4d81aaf4cf65349c8197db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b4820369799d352ce72415cf1c692537a48ab603b9dc741a08a66d874bf46daad570b6f1f4133067a1d900ca87cc25e91c4ce1c84b46d3c5baad46fed227268f1a9dba968eff27249b3c6e4c7c19e8a13046a2b45bc24f4304a80c09d37ac289f924f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773707046c362d94ea547c3050ab251953464f4e540764b08103a88e448446f6b82375c15e3ca9a98798639b83638ada857bdc1e3c6705471975c51b8087a26348babefd234d27d6c055d3aab7560b28dcc13d343a79530ac868b5f6ac83af04b8d7a20b64dabe9de32a5c1b2c2acaccc4588c1ba26f5462aaa5c1bdbc36467f346a1ab5c5840a07bd33ceb44093659bb0451c4c87ca4852172dc0bc3674b4275078cd2b9a3afd61bfe454107d092e5840c4968c547adc723c1970cfe705c5d33e3a4533f0028655c6ba44ab22c2a4c85a82b4b6dcc09765124e43c985459cb2ab1519db1ec6f348d017a785484802d90e0222ca2313b4fbc465dec0cd4f3a5675e33cf0db79145867d5f0b8f340526c8a744929728ceccd146b6e66d03f660aa4e2e15d200b5960f3a03b571bb2e59160048e498c15379027e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc789e062571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c8655503f2f970071b40f6ba3544c64c41887184828be6057a9e972631604901a7870733580c6ab8d4aa18b49cb4d567577aa8b0ca2490edc68b168583b8b38415d32f5558996cc911a9470951430c36f71712f1c579a12327c41c441c980c286b71a31748ea54df2a557fd1701c3173944b7b40117ef9cb08a7d03d45531b8de4c753f697ec4b4303448c260b0783c81ed599425d9b16806828bf795c8cf65a95f366bb90110cc75d3e6064bee17cf1497f36c48e68b46ec07417b2a876cb556c705c7ddc387d74f2b0aeec9070d227af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94a92388b1afbb5408cb1c0fcd3c945e2923acdb7e16a45c03ec3298b3c44e9c1e75d049b2ebbcf2f29a2d3b7fc68644530010e052a0d357809009cd786604a39898b385b70ad7b3be011ea83b93d4426f4f20a3d0836fc6fb532fa14536285013050c16d01c5752884e49a82a4a0bdbc8bc2c7598d548278703ab4c607a16b1bab64052f40a06d3915cd03825f12c069d956f2a5662e05804183932b5216ca66274214acf5c01a7f4c77ebf522db776068f94151f7ac33831259b53bc48e99c50b260faec0b7bd3cd4fa9b5a5c2588cf098fce5aaeeb15fe651355537953d9b8580313b56336f9e6a723f412123c51e942438fcf65f92cb91a0f99b3dc5b0d90a94d7f9b0d9d4ca42408750169540a2bcf2ca20f13bbff3ba60f6faa2df7c176f74cdc2090555c658f24273980c4d6c03461751b9e7e59e87062037433d2a79c72fa6307a77b3d0c42cd8d1aed464b90963c351b2648ab5bc113909ee6c15bb0189603194155051fa534d0e723f4e28cea0b7ad34b3767e1029598b16cd87181d9b8332f87b38795eecf1622f7955bc646e470b54bd3bc915c3bd2fe40eba8b31a21b79130a3ea50cbabe79b7370b5130695ed8a61291125f79122b8a19666fc571076361af26b1979a939d481b55b781baca19898119db5ab19cd22617a59851a04b5db78e1a532a4da80ed29c8bd11a5ff3609e9c6b4b2417155045af7edb0d91506a7bb5920a5095c3327b6182a74aa14bb4957597077e93c880283137d9b424f3c16357051c4bd88549c090ecf23bf7650941ac00234c0398c56d0e3608f1e348db9a0d4e252f78b05c9bda80dc01a7c0b720646cb3475514ca43b2254ba566c929d9d68fcf76c08745bcb7cb2c3478823c977ba1f3565d880d8e731337d798fd273bee2a03416cb6d11774e0b7c177e23a619509e04c334e486f97a963035c2952fa286c8108a3fa6857c080076143185603ef480c7ea135c76497ac2a4ea1c65c535385bb233c54b0326d415d2b01cb0fa60b969bcfd5578920a06659291b59e5100441b0e535b46294680627646c052d13404e486713fc460727f50677e48e64275e4e2b33da225686d920941277caea4d8f4a7c7b96b151b36836a76671c9010cc7546ed301866a694104169540a8620415037654a55ab132d56590663c21c267b94a2f1a162bd61808512c2e7c671247142c3cc54622697edb50514895276efcc21bb02d45c79a4549a501e79859361457047aba280f91c13556d06095a13ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a482afe97b508304b6140ca9da2c33f26522d51363662a0c437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fd927c2e3207cc77cc127790ff2634cc2220ad001e39ec393c5c5b5598193d628417b7bf5f903e9274c2a1a38f72db99e4c2aecd8b5b5b445d3d259057b2b3ac1b3a0657c2dffb6c75c93b20ec3358180f9c124fdac8a64d2b73ce6819bc1005602151f7e4c804bc89a81797ca8313650910c7b2a36ad2a690e3af7a99cb2bb09cb1eaca0891bc69d989cb7220faa3626342cd33438877799835c2782413a9f1ca29861752f294b7e3c2a3980618d0540a5cf00c01943db920bb4693436d3b7436593e7b9a83cd21cbdc692956cb3f7a17c41f46af94bb15059b8661349248235adf68b69d9944f2f30f93173ffda657c9d722d0521c12b2790e230afb49496a930c46a62a4d8c26601a4e783b73c2a465722401769365719681c5086d8a7bbcfff451e58b2cf32b363c501e978971d8c5ac6f41b458693c711765c7fc1ad7319f3481a68bc456eedc04fca898b0b3ab59a14b7fa1c148b6b792352e7ccb1456a86a5a0377ff98c08ac0bc4c997b0370baa76950bd0874f9478e6b8150770c4ef2885e88d119126492c09b8e93110616406e6bc7ab46ccb0b47587c0da1c54828f98941dae515d279308302b672ba10ffa0749395269f5c5a03581799eb3b60fd53355b3690efc291c3b77aec797fd09b1cccc8d5bdb8b4dbc18857c28ecf86ba3a654b8a351d0174df4ea4d7f4159656010f051462a3c4988e28e74c39cddb557566b7c757874d9061fa5f85693ca2124822891a4a0afb000a3887522326dbdf4a54e851cc775405938bdbbd39370c01ba010b8b3785e3880a54470546b617ad86bc984a70de844a510e6a14e241f18c765fd04c2006c6781ec90c9e16881b7bc4557945d68a4543a5f16968b39f38e8f5aa7699171d8567e35da662087aecea63aec3094bb4c88f08432b86780237218afc22ec78c96322a81b8060719fb6742c290ecd8664fd378a95341f3c326d992b3b7417c5f543249d57475b3b526b93307664217b8837c1c48ee6322df891cbf6943fdd445f2da71f8ac449c718e8412cbe0bc2efbe601ad08af68b48f7d2677dbe05914d9b1629b6cfb69a9f43a05b6fa560143a45f21405b25983115b537315964b3525117158013a434785fa13b30331148f028a2e3e299c9969fbba917cc27b851823630bbb930ab2336b59d1e0060e74230d6a0399087ace16894d1e4236f3b9b708645a3b27378a86c960bb038080f93e66bd1bcc3e57739591c386c45846cecbfc90ab3fd506ec50c0d0ec9a2422cbacacac17f62472b4ac6ccc645d48b0283a6c62136a60d62354a983d4ceb74eddbaae57711bd958614f054336a38630535f0dcbdaf918e5dfac711093974d2987dc1109ce7bf7429cfddda9e1826172114254ce0bc526ab358e359c35cba02e720c4611dc17122b8bb02702a962db3470e32620d62291ad8c9db86615e9ab48df3aefda4003f815a1157640e765afb2527b2c532011ca07e321673c721c3f32a2613394f68b687a042724c0207cc3b87675ab51a60b4f12d312a0fb5443cd0518b1f9788fef9a36752291647c234d49daf4a6a4bf420e990307f676271a47cfdc68182500a93c914ea348dbd544b3163780a2c2373282e319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e4f8b3e9ae47d3b5b95c080d4f18440c24b0691c19f06f5547554697bdfe97b011c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = e5f3a007c0d3a9ba2786ba555a8c3f419bdf9df35908e4690b22a7ce095253c994778662f9b1cc0c358f8118e13cd4eba3108b886bb5a97b33b6887c80d2cd131a774fe781433ddc0b9dd679689546546b1c013bd7d8904a8bfe85933bb1488c37d4ef74b9541084f835cbe9a4fd7387ea213369e2d862ed7a5f2b294d2cc77d644a63c9d05847178dd0ce695519a92a0451d6239fcbaa76a24ce6b32624c9e3814f7da3d29087a44fef74c9b88eec2ce7f46690c9243221a235dc929a1ce9e446544427fdee71f1ef91827e181924c3d8f70273605351682cf4dd81088d4fb259c86dc3b4548ec57412a2ebd8fa5db3be5795402ab5588823ec62ec2df6d4bf0282ecc973dd8ffce0c8ec62f53b69cdbfc98fea226824eb43bdbcdadea7581ea102896cc57e5cd279a01796e023eeabf45d7b7813b2eb92b5054cbc2833942bc4d3066fa41d5dd6e9ff78dee4ae7f12ad6840148d2123544ec23c2dc3518f0b8b2ae13031a11dfd91b9f145093faf6affda150674412e4765e8bf21edd066e3205ad01b2f1686e8b7269fb41d793835f331bf2b71e6a53c35bfdc267a68461fd4a006947e0883824762e32bf1c1f93b4f98f5e154e32aec66307509ea72f2f9249b6c27cd7962032ecb7502c53791cf79a680b70ec248fe491ad71e75ae89913c88d5807d00eedd55d4ee077041ffe686e82a6f8d0c726e8b0da57b8e23382e8262912c7f2ded964bf4872f71011d39b887ffdf17f86cc6e7cf90cef123bda28e234e6dc0980bea57b733aeff0fc8c5d740a44cc421ac0d0e55478664908d74005ca6ece53dc69449de276ad52bafba85b03ad44c07c5210a1d8fd0f95f7a0cc9c88fbc9f838ed57926256aba7432e75de13fdd99ea43d034d12ca369640b5097a878b483c1ae1195de6fdbbbccb6a15c7cc8207e6405493aeb238c0d39fb544135a3796e52d91470eef480bf4f8f2a0b03a4625cf87960260b4b7c491cf446ac4f757892e47dd85b2eae90bb9b03eda843dd2f9993baf08b7f9142af62bc432ca8a3f3b2e85b08715d25ab36c4500250e8b1e041e3798abac3914646e276ee9828280dd9542d8e5aa28b80b3966b139da0ebdf6260410401f02863a22986ce2cf1be953ba68eca4be543b840ca0bcfb492907628d66afe24a2376f6c886ff9f8ab09abadfa112c5a4b92365c57d615a17e41249d757a787ceef452b5ee386c773685a2b723749cf9dfee7c97f1f0e524427039522fd0481594d777f03f7d11da3c001f822bbdd33c95a096f8ab09eca4b588ff9a68435cabb2b2cc1f39ac5e146474505bd893f94e2b603e8caa82cdfeb15873cb12ff87c387c476e96960cc182f569ffcc418900e6eb9db6d90df3df01cecbcd1f6d2c6605cf343cdb814b78a513161cb074c5b164b8c0248123a68c7ad12769dbd290a9fff6b2035715934aa78582ace98f10190dddffe8cab28f97ac7cbeb02c9c854a7900a3d3b5a94c12f00d4074d4016b02abfd517e4621aa16360d05a38a4fb6f22f0fbfde41fd0c7ac0d7583900c51cdb62be446792f051b5f1c768cb91f829876315566c607b3d944043d723bb985669f157b5c7d5baff47e9973ffe89a1364d0bd8e2db2e6814afdd612e5965ada830cbfe22ac43da7c9e49aa54f9da4f88e8c0df1fb6dd2ea3a92db1069f344f6530c472c400006bf2bb137cd601c686a9684207a828de1c5f401667e1a83832501c4def21805da23c5d63355be52f7a55d1951218aed1aa23303298d81db3453c9c8502942137f57067697f67179b8b33d9bd7a98ebcf63bcf6f925abf063c2efb4d29fad0914a24aeb9ab16e0b8aa03bde1ad7299105b12e9f222186a3f52f8344c8fbecb8a410328f99ed5ddf3afbe2bf2f5aa8c4d3b3a593e7c3769863a6943981824c8d9da5d46f1ff2836c765f641e3bec4079b1bc3a4bd3792658a987faf9dec7b3728e33d2f28ac93d1060f6376c8571d8334db81489dbd09dfeb57f9917294bb7b482f430d090da5046e4e7d0e1610dd4e0181687e6fe2c8d8369ae2f3a88b02f4b435a70de1ab2b2f8c1f17990d623e2ea489a63aa21037230ae37919f1561c0212be8d5ed87e1a1c58ac5503ccf40b8229ce8be8e542985e3bbc9875249fcab3588bf7fd6b84825f744888224706e1d14737ab7e162cfc40eb65b8701a09b38e9a8dbdc8602675980f7ebec5538ce3bf92e8c299 +expected_result = pass +expected_shared_secret = dd7816a8a015b2001258e665dc0e576ae19b10dba9704be9c484e4c8ba645522 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +private_key = 37f7089480382622ac6687b4b15bbdbc1a9ad7467e8ff4cf44f0614de74b9591b9c5410d2d7084bb57ac27963aafac148de80dda6232f4a0c634d677a80c226fe67063191c05a54afc026080877538f63df93cc6fdecbbc0a9a0a4215488da1a2f7b1ea8f8b917f32f397b94c80170bcd423c1f1ba4c736449f84bafd6711b0070dae72de1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2cc1518fa4bad3c23438e06952c9317d198b0c112d79a89560dc3361f5732f820ce4d16ed448ac2ed221c8ea3601602c27f640dcc394a7ecb5079978cf52b80de15c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb524c2090a54ba793c845420a7c2c29e78a9b8c83c310d780f74127c02a59ab68c1b29952dff1196d0940edc338df3e1c1c8e34fd0dac4d5596f97a2afa98b1e8be46bc0a96df412639ae5b52229086229b5bc79ac020b61a56c04091c10cf9940f798a9c50ba1f5fb30bfa947f20b62a60215c5a88d23b70c0e299c53f49a1ed511ac5812558133d9f195e1fb5d77314559ea79e63a88e781c4224155abb5ca91f089c0c609cecca32e549b0cba167d9307a3a64681a815a69c5d7e787751162483e7701437034f0864d8d53201fab9763c7921eca6f11247e7ea364298c1c3ab893549572bec45c1a8c3b88659cfd526810b23f2095aa6c1424c7178187109f83063b52547b9c731f9933622a33c7a8b927a50191593488f9a0d12331017919159c7a027c3956fe109393a167a6475cebb49224736847319d161490ec52396d7babfb638bdea29f50c9ce37314fc858455f63fcc70cfcb751df12274feeb45a124ab1b997c917a550c3469a0c185eb0238ffcb4dcbf751e12ca17a71b807b1446ea7180ee302e6998ef8d12a857c84ffc377f5e42fd41238a54345229916a715977025b3b4a6060f778de7d426a2f95927335cb202bf4080b8510cc0da12c4eaec4bbfa42997e21504b8c5d32604f1d66e8d55b50c393f973acd37a236db595e3ef08239c42fb5e9243d967181b9b94f4521c104a8aa726dec057abd419bc8c6cf350c91acb78b0832144f409f78992652e30eed7ba2375b3245d877c8e8b873f0427071c956633495381a2c642b15282b9945c758910fe469cd091b4458218105da96a479be0ac6b3ba155d359b2815916e93e9bad3d431945b852e519df0129174b24a32cc9fb8a62de96733d153a799cb8fba3c86b9101cf3d4a97bd3b699467991a57129607c27274d3224cd1848c17f1550be47b71a119873045e215bb817cb92c12a7bdc6347df8b64dd686873d800b4672aade8af56d2995546cc37c06f9212a54745c5597184ea85cedca7b980386fb91b8ae677a035a4547b5848879c2567c8cd6ac285f6f2460dbc0b73f5ae0993c988418c234895380c556042acd15a6c015a13ebe16cdea4be38528a9d244230a0ab053c568e31c64d06a3d7bca0e5207b7669811a3512f8ac6887137b0b7627d2401ccd604ae786753fb6568cb522b28712211208c1849d1f75cc4fb951d2aa081ada952998b0b0e938b77359233a76c135897e91059cc5639e978c12c6bbfb735fef4bcb1d60180df21dd367c02e79916d697f20197d07e9980af13d3a0ac5d2e010a8bc850476630f5b8b37cb8a88c14a047a1afd576b6fd0aac283981457430cc62a900c7e81f47f2574802eb91707e54db0e77c223467ed07c29b7c5197a38b9cc7c77d99018faa271ed10b32843a92001be592afa651082a646858e4497f777c0f589913f50b0952669689bbdc033701042f32dc48fc26038a63142e17a6d7c711f5f058c2392a50779eaa221c811975d957c389513f39f42f7a58175cd1a6a50b730888102dc93f4f056bcb42710572b6ce36865c621a75d7717412a12cba792988517540a3d8493f3ea68858654c62807794cccc4102a9e24328cc722971012af19bb7ab6c97f4813ffe5a2f13403a37b7477d18bd35e4613b73b4ee15a3c639593c8530211a0a52d214b7d48dd93ab27ce23975f2cd9d8aa70c878fcf342cd8343488d7a0b75228dd3cc8ebc1148271af1526583603baaee2110c400ae5145cebfb63fd118f958081e9a652c322b793883144b96517c088f4237f9a067ad83bb3a59c1cadbbbd2e225b33d590a3bc60ff331f856884594944a1055f1ac6bbd5f7bbe0c7b5363c984d408b493b92bca2a9395b7dd9a46c17b632976324206179bf05406e629f86875573d05b0599b561dc5ee8f54a73690b5c3b414fcb7aade872a9489a5530025b442c94052d5e892cb47b7c7585547a72a9e3a3cda629aef1876c96c479063c49e94b952cf819af8b3bc39995d4563337bbcd419c17c4f5696a6002cbc6b760e344a7fc49c2d0c0ed52b54f16041e5c4ecf2426442b9d59ec05872190a80b4f341312f91b7737cc77696acc5e0323e02100563519ad3002fb95b0591aa126a70ecb708143c7a502c53a77a82ae915b25be77c68006f4ccb0252463dd668537c24bf4b0039cac4a4e6b3c19ad37301b595c504909d8a4b8af71c0fc2c905e26b5317703b3195712070b0d5677bd5101c4baf9186582a8b70d163ab01c6151177b7c83b6cca2bbf62f6abef41c6ad6764cd8392819a85cad945ebd210b9c08f1333a393b144a4782e683ca2c73c5875f20debe3ab59c8393f7caf4328a57618197450097d250e9a77266d15cbd7b3867dc49c0e83c7717513bda8235e8b89fde06cef1413ee0a0e42c814b4da9d0b0c5961f73e90c57c1dc614de43c396118979cba7144316607bb82e5451e9475c0cc4127c58a69fc47e6f02a3fbaa03949a9760573b2bd3c6606325c56a23cf4aadd8024bf9d1020332cba28c7fee610d45674e17281e047822138b04df69ce9e11aa644c47fffc688ba4b6c91b01e2747d2765b7d9579485a37e7090aeae19ae2773cb4cc17b998c9d25955a33a0a9c47117fba45f02611f1fb59d415a93aee26a2e4726e50c457c692766d55477546785f76a2ab7c5ab983a90771834da4016a755a2040ee3f6a24145cd2f827729bc74b17bc92032548b663f50b307ac511c47e24e4ac4957e552c4662915074373d83b34f468bd66091b984692dd32669332b0527b0a0bb3df41556aee9693eaacf97047516b6aa455311cf97135b697e7e9a2e147756e8fb0b657b41a6352fe6a17f4b031efe17926b7757fa74831257ce2442066c624bdb106d3330b99d730e7eac1d1528348156352e266475204c6e13b5dc06b2596097c1da6bb2d31e139c34f732a70bc09afd6a8e9700bb20fc78e3fb15eba8b2eca7bda0508b1d8c0c9393557e62836117219fc2201c79346949c53d8414c7e673106234e98cc1508c81317450670ca7de957bfeaab0e6780fbd755eeb08a441f983e3c81468a7bfcbb152bf6a581a901564f2cc6ac13423c32dad054e02e6509725bf13605f646922bcf84fcb4b456c7ca25457415c7275ba54ae8c4717157a299fa18b49fa6be7460f8427516649440d4c0dd42814b8c4692d71b7b6c0049473472e002a53392d183b4ab70b6582557f8ed067eebc00b670b517433466ec6b2f967ec1720b8c68c41d2923fae5c4285c63b03a8416926b93496dd57b6e241b14f2576e7b9a28076b2dcb8c2f475152a5fa7ec98c952a263cfc221282d57bf329a0dad122046a75399507574289a18226afa90ce4d7235ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fc817899375f890470238004cc7520be51feb8291cb8bc336813dd14a7bb24b2b8b8b425a969c4e410ac4876787f67ecb61409885518e0533884c613f70a22997b0b8cb1e2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db8614024778225b92d5826e1bcca780400e79b42e0fa3baacc5825bfc0f45cbc485d69c024ca504a975ada9a5a822cc0c11cb3fbabc64d07db6133a7e91223c3658725686ceab91eb74060bd039cf1488376660225b42db441ddbd437d5193bfe777b35513ac8d85e6da433faec55fe969fd3865eb9045589b09769a41c963596ce70238cf7b407b096ea546fd5f141ddd54ec001b76cf634871240d9f82f77f5153e84a6a5c41a3cd908e962c5b8898ebd4287fb2c97a0710b448c4ec93cc5ef1719c91b92ae77b35cf2628396160f0bc3263003e2e89243f073726a657b2386173115b778cfc842c67a4b71d5276a934aa94d92b452286a35913b0262af2a4007642a0b04f76ce58a31bc776d6f1b8966180e2ef026763a87519a10b8049d799a8a3d038d5be31eccd5676550482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc1b4fdc4929c2c7e4501ba7a9feb0be571e27c43fa96f9a7f934636ed9a86110bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 463d031123a2c978da1db90cce3787e657d434302d270680b17d83fc6a1d20f1ccd4187b401d849074362291c6428345717be577b5c466eb9de098fba1a8ec2983c82782d40c59d5aa38fe1c32c7d65f46733337dff0b10733925b6adb40f63e015b7d7648889dd504a5199814deecfb8f27c1d7adae37835a7e18717d1f0d990250e128e6de30796f0f5a70ffa5860ecc7dbce1456928af33cca30c8c6e66ff88d0f9fe07fdef98ac16875f05bcbfba2357744e405fc991cf4f79dd6a1e7ac820acbafcd3b6b08a0dbe6e6b25d462f4fed17fa26d682d456fe45bfb9bde018b207ade36fcdccfa00964a50d2933f5086fa51f8fd1d22880cc0e17b3050f69168c123e9622993213904a599fba68bebc1921bde537e30d179636fcc951a28b8e6ddac3876fd6b6b2be3cc6f63719899e2b0c0c241e9ac94853ad7a8378e12070f63a4a1d0f122043bdfeb1e98216cb31f26f6525cbb9fe2b2ff536c8bf5f6768f273cf507f5806605d086fd383f3eca5e20b0daa69d1c048ac30ac3d5327f166ef453d2f2ad3533d6ab83482a32a34fd2795131702e94358cdec743d702c64f40c1606a43c4a95c80d8a60636dd2be5ef48f2e58c8ea1d173ab2e64107703d827604fd276feaa32455d97301698abd9773438c8e1a22da3199a6699df6788b97e09a2ff174e78f6cb939c82a667fa28d647fab7c3177e21f1a25bb45f33a94f370ed15098ec34beab6e551b848773a2c01e5f47d32c997ddf41b7158fa768664f63294f1815dcafe8adc38c2835862c95b66bcc0397a79b950e48ad39df432458660e21120804d88ac56511a02e458d4ad0c9e280b58fbc595a651a27ba978535f740d5e3bea8249fa6325808472ed85fb5919784a826a402db695c24c8656a5b3e57f7f71cfe96fe42226edd6351e94df63022c466370c005846604e5d1d2e65d55cb3aa22bfe9c52fcb7cb8ec03190ac558be4f5c0c93dc3fea8348d211587cfa21d6592523c62f345327f881b911531ef970912608b86a56a7cdb6c7f2341f77c9e7dd83e83f554b68147fcb69ba149f37aa9ee5a13f9f4faa8205f16c74ed1ab56d94f7e7b8cbd287d5c0ab805e35ff9770b1dc6f8fb4a3b99ff24895af6d6aa664f5c52112481400046b3d76c0de2e7a59e46ead9cb6f36a4511a98e9bb85198503e4c9a6c154362bcbe153153d206988bc1d93610889d8c9a66f762bcc2e12755716ae22efd15933e11666da92ba74efcc1ecb234f265b895770c2d81c891a8baeaa573b433ca1472b1a99a186255d71576c2a11dcf82aad1bdbdbe76b685555de1e0c16f4f8f920085a08989462fdb055c66204d94f4c09cc10a9c98b367af509cff5c9bc175ca47213fb121b833114c9ff45ff85f3e9322c8a30feeb24ea684b744fc941e5eca51604632e31cda5ec04366d0df787aa8f8be1451bf783ab0bf582d0c04b05beb11e970a93c798fe8db58bfa28bc5659dffd605dd05155132f95b21ba865002b101a4143bc372a1c008ffb04bd06f38cdf9bf07eb3c1b0c45cc4f09b0db38b44f342b9adca8f2282c8c71a4ff8dbd47e6ace1444fa17e35fe3dabcaa9c2c3b9768b167fd0f0268bf14007e3cc06cb37dc422f9c0f3f5fbbfc55674bfb61413cd59a382f2a8195f4795031f0852ac2236851570c0254dfc90a8244fa25bd9ed40efaa27997dd9860e61a222268efd31aa09767a73d03f056b92207625c0962f9f8b2c58c1b6a9333f031f0e52a16971b6b016083b752d75af96b12b1eb4a31dc2e58fc60811616422ae613195beec540dfb85fa62c4c0a81203b2335fe4ef0054e18dc516d9ba15961d1b62474bb1c7322aa34ac9c24f79d62ab4b2590557db827e1066ec14c57a3a8ce650e1288f3d58461b29eab4748e6319b128d3059f3bef0978d74e7e4f5f666007731b16579ed28eb50e0b0c189f5e0e2347750378ca5fe08b04843c9d74de307b67e7862936e351afb4b8913f64f4226479ab763b8b1991945f4a87b7d7fe302000a365531655c8ef5719b4a97934e3ab8d9f55b459ee1c1914b31c4dd26e7c553bd62829cd2f1f678025514100a328f24947ab0b66020d10800678cf9f5944a7bf5496f3deeebb663377f140cb64f3057be389524934efaf66d81bd415f053d51221fda178857f1cba2b1c21cedfd18f30aac3cf48a721716747579c31e6d6c45a2e69c8427b05121cb3b190 +expected_result = pass +expected_shared_secret = e911f73a4c23637a2708739bd5ef842ccc57d32993f30d6ee1f88acf5093ebcc + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc85521d549b978b054a9b8949e519e3fc3a653607d794491341039713037d31c9824eace39e7127a974403441e25b714fafba4b98041e85b2fd8d8acc2a69aea9c80930306b46baf5245a505d48e293a77aa4174d1c095b0b4a45754a4a94bcb01d4543bf7c7def2ae2009408725c58bc76bde03abef3c4ee0831d3c6b2632609707b3b861f093e857902d52a2a48619b1ec20dde7a923412f79c22389601473076965959b2aa3c79dd31b98ca9847731c89b0929ef5174cc6b92972ce2c07c8139a62c901216245cfc92b2da158079e1c93c8e08ff438a02ddca4ca948f47a106d40ab6a5b0afaf52052f237e44f0765b3436271421308611845785e257cae691c39fb8c80bbc1c5fd687a547b7e8e3aa1d7c15a918984b6b359cd24711cbbbb95716ea54a8d3511c5dc983fa1b019e0b0d7de90c3c0a9e7652c18e72cad6f9c510e64f0cda8cbd86502a5880ee1536edd16ab36bcfd859ce879b3f5d6a0d90630668b7385c8599ecb1849a4942d87a91497129e196309156c9ab245f4c637080c963f9648fb2ba6f32d2566f88bce680203dfb827438295f8670c9bcc34a98497851bdb0e631ea06accc26373809986da62fa714012d2579d5d61443330e3b882c800b6c9d02c98e9859a4022db4a09510fc91a3b95bcbf73b3a09311cd13e52b61733e02dbb400e8a54a30668311ac02fae2b55fe05c95ac43875d92f3c2acb3d4a6b53d363d5d75a697061055a3a788bcdfa051edf97c3515ca920ebac9e7a998bb598b8436bdb63550e416d2aea5057562a901b609b129d92b27536e02c26ec6a3b2c5f6b733d0529330e9a89600b089dd30a0bb52530a3062be741b09818a78b4fb9f274b7262ca23b3f2a40542caa64fe38a6ed06beb5498733a38a7fd0b5aec2673aca2b07e00909e68d40aa207fb179cf7a60a9e13719635a15cb221d1cc88b921e950c94cee17d60f80ca5b4a656f501d7136d1245207479a1da42c26c48664297562a0bae0e7906e9d853fc7c490e4078b5b3b226b37101a31b5d05a26f1ca1f231a853f23f59d86a3fd269a0256eebd02cc0c6b77f1b1c613114e1084d8d1cbabd0c7702f43d2ee01db985382c562f1b7885a7015edf59bd8988b5bcea1cb04639bbf5b119e6293f908245455070da3013d2b6e2116776694b44e3a7e433407099a51940870b336f547677665c7066e181ce266ff0e508268731bd13afa2ecb4546276a5dc50772a6fa38541af968ae5c59e2d04c3b6002c7120a6a970ada2671590411552e48e7119c7b7f7ac97429e9b7cc0b5242df277cc10e7c48976266643a9b2308cf1799324780743f95e65851c03599fea7129d5552b86ac35aed10b5f00058a8742c02a3e4f6cbf5df61c66143ebe933060c98a4bb55318566184601bb395625fc86e4bd47377b54459b45e50c145596b9178d57d01bbbaa9a63bf444889fc810f1e40e07d289e0b04a58f84348463b9fca3176aaae6c1c119cf679bacc6eb685b9f443c2a9e304bba0adf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c16029e18d8493a524fc2a41738a25e735c665e79ac423aca37b5222d97030e794107262a30e76c2c712597527d92437800967c4ca2407d826ec5d0c1bfba5c96b82146320a7f74640100314b1b448db72ae1a57efc949034425da38c4fb03107a06c26e81773edfbc3eb265460d345375081bac591b3cc847a954ae1494f25190c84464141fc95c840c1b19aa0d700073f01381bf2b9c14249fb6719670460e0515d93507f5245b3dcb68e0f00c5e1b227e8608308280b4a54403b5a9df3d392ec3608eeacbc08e10c84158c97920ea670625f08658a17590c6575f41923027b637f2a881c3592271b3e3dfab7adc1a3596ca1c075167847a4c586394ec7735ca93266519c7ec49fc0c1964a47b00538025e1028ff304eded54d5f323cf5465c2fca52993352f70bc1289128ed702a4a6528ae7315d8f4bde361ab6865c182460e1f4a6e49ab5ac81b07c53800c65762aa0594b3c7cfbe449dfe238a63f35463c94b2dbbb18f9b33e6548dd7398f0cf833f1243e72d123918b35530414afa37cf88aba62003bd1f46b158b4a91c1c5eb3c851f513f8a760424a65002d87d6806cbedb0c2c364c98989815ee9081d132427943a0adb0da7197cc7430757f3868c49c045d39c8c085665d13bed825fd7cac7fc6933adf438a4cb6849b91a1c737d394c5e08649d88e9274009c4375a4fad4b164851540e43ac603ab6f488628fd7272bc1981ba03121c3a22e587ef30a793ba097d160025ec1b629a348fb8b854b54139d5b6af09a7515ac4ba457c8289108c7c316c069a8e454a8d1084504c2a4e03c0a321681d168933e0062bfe1635de39ec8c9aa2a5a48983c1bc34798fc64114c18ae77f13408f753da60cb892c52f811c8382b3c455c4c0f08248bf7278b9b4b927580a3e50930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c22529ec61343537944ac07cc5a1ae713ca8fcba73daa688c9ca369e8b8d99fb812489482a727d40c7aaa6290f5032ab8fb5b09ae4985d7558b8c55b9f0accb3781b9b2405f11c05e99cb3723922d0da4963e68487631722c0cc643b3920b8c2ac34b54e77c1fc748c96c186b3a5439fa2b3b2e1a75b16357e2210da4b3fb620407c4cb78f18178f2b6c4706b619f18dc0863c72794434978d20933fc79193894041183660f0437a2e309eee87bf538a2b8c7672833820805bc2cbda61e8f04b7839b1493372759aaed528980e02726eba914491b7317099215135175c41986858fa31cfb689a865375e8547932899867b987167115031f5b4dd263f0341395e1176bff3a69fc9b9c020ac8515af5e665a15f48a3cba1c4a96390ad7795f7695e654279802c46275bab1e32fb7111619c55c8787cc01140f0fc03fcaf4b6df9877e0f24971f06749bb343e1a5faafb66a75b4888a1c63f593bbf3906c324083f737a39247ca110279a677736e77eefd3b08f645100e249461657da00b365a58beeb48de3f96b6797850119145975388ab4c9025215dd4b0a0ec066c8a7a593fc0a1ca921c3c54659d40fdfaaa4f63a6b0d55a761e9a57843617ad6963087396a0187bdf593d98009ba825d056bab8e3b6ad5eb31b3f195a2c9b7cf9281c176b58346cdc24c580f23131213a08c4cc1c776c146893e8cd44983bc01494793028225f2161f916b888c923c8c30c43c41c1a2d12f18a4918216771cb992ff1abdbb33aa5f363e6cc044a0d68e6b36785951566e4a666af6cf9d3222fa17566966c734a364ce14933da00305930b47dc1e977b88e328296461c302c35f3e432e5d01243685c176e1b6876b03e341ce0a1c52ef32966d67004cb4abad9cc8a534b728db8c32811f7e71556beb656d773759f04a71f43413805c1334385e396e8b128225929977f41cf776450460707e0c247980ac42c69cb641af3cb36724d5705af745965181312a91aa000b42b82670a9aea43ac26a5cb3ebfbbdafd4225535255609c3a7d04332e6c816fb68e5ac05daf42c95c78f6db76213a083b3237b4665b9ede88c1bf53b4473005d4627bee21cf225bd35eb728932543956ca142b4f3614816d891895b14f0d28ba36d298d6713809180621d1b12ebabcf032aac6691b22cb9013d8a8dfd70ba1281a77f237f9318b43d043f193cf9e1004cda26f532ababca3528c69200624b613fba988bccc73288b7996c2de008f22755ade918784f7ae2f69ace6e08e0cc528e3bcc85403967da02cf1463c77976555460bba2824af0923f2dc4336ab44d54ca0658417f8fb5755f397fca11e07759c5ba86accac1e30523349168ef3740f59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d38752c435cce3cb9b176086019113ad638cf3426970de0013624313ff57ac82b1feb24195028b1b65bbcbd5c4ef3a60116125b3580743cca16ca9abe8fdc1ec1ca2e4d717a0eaca0fbcabf74034b74391d8d9668198a14e5491ec817701733be7ab11635e4a1e6910f3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b675a1660b7c22dd1947bb24f1ebc8b22b1ad1b81600b545f74ca076e468513c0a483466089dc1cd7090c4c5623b02b7824d2ba1894c4e200222bf867911c89d3264b5a081d7441a2f3729cfe4106a780237e179839323f97c04979887c4c223f23a81af875a33cf28cbf75722ab92308c320d32625ec326734a532333c8b1ab4767bcb682850750620c402878103056cfab5417354bd395084f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14fdf4f164c11041dbe981d8ff2008757b7e694f564a298b92cd182129ade5e72bcfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = 316f5978cb537a9ccef934d373cd244ec8b40bf72cba7e9aab5339dd2848b9007ba227f0e42a302e364d9ee9e6761ca09cdf5a1bcbee86baa24bc97e1cdc69c5e061cfd73c5d3446edae20513a9ec8314efae2dea09bcc268cb601e581d7dbb33dde376b56143921b5318086f4757ec70b9d33fb17d87807a7b54e2a077c3edeaa48900194049ac60e34776b975c07478bea0e76861e5bc6dbdb2a316d266c6d40889ea61e8d2d50754d6c112929cee6e1a9d20eeaed6148db31f4267d7da4f1747f468f4210dcffdd367f84ad35234b8b6252d950b7cf74379a3062baff3d20ef5fbfa48c3a9845d7f5371129b64f6adb9db6a69e3a89846fb24370629c589dc8501d98e18daac7054bef4b0d485fd35de5fbfd63f1c160ec2af53d8eb073be350c79dadc148f2b9f52829245b97ab3c86697bb1f9bff723eb633f366a015797180347c7fc1791bba66f1e05decff7d61f3f3ea00078d804ac4fe84458551649cc9426fed3eb8dc0db5acf85be11732a9afda217d21855c988ae6355c6e91f9a617175cdf3b5170bd34360e14f5fb7d00daed753b98b26f835344ddfd1d4b0aa04fb01d9f9ab108bd308b4d7c4d0978a83683e474726bb59508817e268dcd101125acbdc7f059be0b079747f3d22fd4d5c16b634939fffc1d7ea050c0452207671c0572d9228ad933f35d3896ee86eebafadf4ee549d608e3fe895af052df25fd75365bf8641f8e3ef581d2a4e4dccf06d56a045f1dd6e166942a998cfe234871b2b536eec90f95b5a55f5fb00547f34dd872e38f71b35d2eb339d78e17bdfd3799ee7f93a72ec83bfb2d4d2bfbcf080475d720676b26c5c4b9b30c98515133f8b3b7eddb64bea2d52671fd6ebff4773c24deeb8c20e5d8f09f1de74e12fe4e152221dca1d45207234e07d1711eef6f32f0f36f4c24cb0d724101d07e3d5c6a416b321af7442a6cbd1ce330915f57daa07fd7097ed0f4e5d87b57e288be359df4780c949a034449e9a9929edaefd094df3021dcc7d93b4cdf50e7fe524148a92bba0f0630d59f49c8c7ae39092013d14d5b942b4367a58694eecd3c614db59e498aae3cf84e373d324e9e893bf626797336f20b037c601693a3a697bd272476c7cb97c7fe6435925908e4894f48b02cdf6039200b1000a8c088cbf6b82767ca21bf46646d416a6686fd81ba82dffa963db5fdb88f23ed1b5850ec4193049426baf442980fdf1a60394d51e2c84f9a6c8cc940242eb625044ec03eac9e7242f6dca673447b81240dd019f23d379e52cbd2482e90ad254dd8e6e9814ac58f5ae9b16a126528bc912f6259b01d9f01ba1708909bd7e0ebeae96f27c6049035547b84cdf06d36add6f7c95cbaeb020c213111eb2fc0cc9defa65be9450179d2d07eb8c1e77bec3022511e22906a694bc28ab8e517b72e0808ac3ebab7d348093cea98199c2706415a60574cb6fb93aee68a2e63db550413dceba0fa85136f8a10db18f824844baaa6240ba4235f41822683669901673e8bc56d2b35a8435c64925a0281c1bd18c2d9c093430855f24f4a1b841588dacd5c061350622e536bbd7446de9df4be0944d3d29e9962614575adca136ce7c93e32d4f32e531d84757301c1a327d3641ee62bb79ee8f192577b11812be02a69e4f5d9f7c6d9ae5c536800d60bc5a6713c62ba25ff1ed00a7888f4e2186ea8d56b63ad057b112a9c325920192dff790f6114dea911e535de9e2dad805e4240135ca0199b96ea56584d76f4ad9d241b811baf547457161523840e7666601d39793339e4534b79ce8d0c66063220293faecc9925e38e6c9c29f47852d0f7193f00b07481dd2aacd0d0e7999eb6f7ae1e09578eea1370514132c2eb609a4f1a88a5800406d0fa5e8a125d1644af66715a8f5c078536908c1f6603a6d8b0d966f0d7ed73bf0ef507a385cd4c163d415d2c461ae0a2029f409dfd527348eed54c1a048adb3890693b427b6c6e037c1db7a2a44ff566da90a0633893b5e671bc63ac5e1c4f6888eb7199ce93e4a4c9d317f5d0b0ad678ef87695f4d545e995d384701673f1dc6c5451ec468ac0c9c18054c6835a54485bae1f252ba4d8e29b5e20b53f109d6e792637ad38c9e6093c4b34d20a9d23b82cfe978b49a5aacce3150649fb14ab9519f745a5d649a4b05e3f63a3103d1c655e2143b37cf17500815808e06e70f2f798a517f95ccc0cf60d +expected_result = pass +expected_shared_secret = 572994fb967815fe8bf36cf41560dc69aeba8e32b13e1d25128585dbb0e71068 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +private_key = 469963001d4d93da7cbaac0acdfc833c47601ae334dcc0022a9220138c16b9eca73ad1863431a34f593addca4f0ea393fc4595d22a7cadd0a8d89827086a955400abad84226541114cfcb3e3a240fb600dd6c0960a7976175c56b0b48c66721e13882e3aa5784e12869f0c8518037955f876997975d27a7c92d4cf005ab859590504c768b02576a94263c87c4bbfe1afb09b8c0a5c067776a0d96a5d12925b44ab3d3e57c6971b0a86617f65a16c7e9b42c283577219409e1ca4de08a92dc5b4e8e87051680c1b24068dda801fe871e0b28ab0611bbb97cd49bcbf159b7785830bc9d302c0a61ad138277afc2374aa64e983506bd11288f4a20376b50ae1c1233a1acf30af1da67301a5a420aa826db58322dc1c7ad8bfd25c3b21025b565c357b4a0802e615a35a384f1794a0612e030228a865a0390197e7c27f45a4258fe26082c850170cae86721bb5c68cb32153b9934de4cb11528c570af363925ab0fedac79748b3489b7180e81ff6db702d5a100336955ec02fd2b9c86c2cc001833b0ba1b7dbc9699c6556b448324d29b0f6a4028bf48a49b1cf60b4a9f91321aa64ca849848cee2be0a29219f783008417da307710f87cafa2603fd206e5698177e81470af4c608a6128908541183a5b4769e74166349e55b4d2a2a84600ef712c2d1f13f4fb3c91bca8cad209cb5ba0ff578bd6e29a0cf07a972d262a2ea3c4dd44a5d55446c174b345b96871076fcf785cca68545eb6be64bc9be17a7d5914d8a50b286d3a2a8e1a53faa53815acf0237b8bf204c34766e97883071e56539361bbdf29187c180414c83d9c09e30983995aa4850a6b2358aa6240642cb9b0fdb739fa5a93ec60c11061aa8b5e71316a517be2baea2f74baee32eeaa0a75d2030f5e8bbe1b517f56511fd8aa499621a9ef6c88b96a9f33b2b3cf04381b5c97b743063a6286751ad9ee14903c4674b308dd5e28bc700134c43c788b04460db78a0e795e24698553722b4c3a095784828960672cbcafc11af32c918ace0580d5bceaa574409854051a2419f148809147133866f9b651a38622f21e0614f10139ba53724831ff312157146169ea29293d2a3f1250ab9cc877d448ecb53139e6c5487dc2931d45b4a74c34bba11cbb965e1e664ecfca54db7bfe7e61db2382e50076a70a9aa028670a354013c894b729945830b1125aa53f4d352bff33fdbe7c64bf70a4c3acff3680976fb26368693d928122ed5707b453a1dd714fa9c5a8e6534d45b53a2ba464e217dc0461be31c5763715bb66b6f3a4c0e7a3a4cc107602cc3b67487a7d162422468b5cf33c8e5a63f801c2016b15c40398f914cbcdac9664b7601680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86408922fdc9650df7577e5a89215c8636d5c376f4596c329158964084200c91af4a7699018c6d139f521204bc521110aa222203774db88ac0ac94cb97720a71411eabee0b2863c35607a617e761298825acd91c73685198be96b84a98ac7295142f6c19bab0082c53a8a50a3a39eec2a34e859cfa2c88c9cbc77b1bdb5377981f61c1fc394d70820336baf21820d44c0956e09a5ef7786b8427a10ba0aed54573ca5245bfa751ef891e1072ab20a4f74795a3f296bc5e9587f272a9ffc71a878337f5149e7ac47a26532b2ba2cd848ad5e7a621ef3b0ac470ad0e64490f6463c0a6d091c1a1156771999697e576eb1155789555392da8d0f0cc364378274922b4d11a3013ac273db2e0606ccaff52048d30821093d5ceb0417a4347e5b178eb5b59d37c54cb911ac08cd5461b1a61567f4448288e78a3ed70c3af85c6bdb72d4bb6819bc1c5946bffee0974e91c56b47bdd7647990948834d463361c1919a977dc84506a0c13ec7a9da410cdf51a9fb67b867dfba51e029e6e99a35a0064a5f640a36b3e41c45d586804d9b5a8306674c037a587427af6160f7568518edb10e4d83e6fea21b23b20a1cc92d66c043b5328dbc9805d7c7d938066ac238c3461a2162624b75bafccf47f58065eef38207d22895e321a0adbb16d2001657a9f622849a0008ea88988359b508ccb764d265766d2b1e1f55fec412afd07a2c9a22729b8ce84ea770cf4612d369653ab92698c6358769d2e5317c2017a6ce707b079cb56a06e388b924e96254d26c853733b50520224bc51798578c4c53bc92552e8a42a07136992213a6763056a025106255f57e4670a6a4262445aa745a916a9b629ea64ac757186d136fe301c6226992129b493d0c2d635b5187cc2359cbbf235a90eb24f7feb5137e4157ee0822b0cc1761c18c25b18f757392863c24a13ce6dc84e3c28aafe018acc1b338a27746acb22f687af1e693df043625c63805ad42b9a368f13f19014b456c78236fff57c7de2b96e7a2223d00d9eb8973ab04c67f3b03e8cc1cecc7912033999101b37ec643605c0d70c1161a6cebc512380851f6a834de7631bbf47adea0bc17a6478f122c8be309804d2995541558d688b9e080c22bb3494f43c1b1a0c874bb4d5246688a2be22159a56151ac2e6385b1384d0c635ecc94b80bb8276f435a64883ecf51c43f066d481cdb5a21485380ca2874a38b39a691c12d983cdfee9530212439d154df71106e2854222454c20736f6daa41e9c949941205d84a7b5730b95cd3251c186dd97b1d4ec329521bbdb3394c819a984f87a7b3992d1d578b5e57ccc3ca151992395cc6695ecca7ab67806f2c2c0ef46a6bc02c2bfa17a8ec41caf87f48a146f2345b7a185baa1379880b00d0044f90e2a148186cbf474bab0330b8f029c72802f1b1698ab158e5c81343d34cb10255dbd1b9b6265d4c4a3b1905a650c29acf22ab6929a0d95357bc76983a201727b1a0f7c8464de2bc0da3a48a81b338a1855a759f764639d9e7306341a96b9aa52994bdad71ca3eba0cd695a701a0ca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d282b73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1ca0454a33bdee7aa80a2ac17fc709167843167208837594eb8a47ae1a38ce819c4ba7dc4521df532c0a6eaa5ccfc37e1f76e6ed20a1715139d9a41e2fb46cd5c0b3bea25f60a120222aa06e15504e4188116ade33507a26b927d10bed839577d2641b9550e1e921932185467b8c2856a430ed28275daa37b166e025073fa513a0c852091555b0e19a2c8e858c1584e229c6bd2bab500ec032abb4b8028b90e3b24feaa3fe2f826efb574a786c3bcba9829e49ba6318b2b24cca031c636c863f224619df40949b08ffee535a25c7187a92fb522376cb30d4fdc7ea9368594cc53921c857f7a1d9e9528a9cb817e423d25f791b4cb1e95e7b3e6dc406c83c9140385173073f7ac23d69c6aafaa6cf82862fe05a409521174328539b6a907f34d553aa77980c9f4959c329c563d8c03920b98563c5f13a0231eec58876210a5a78f1b43c1fb8b4490d18c16687065939535363ab88397e51760ac356c69f7b25458183a10a0310363f31c5c16f1898d06701824565a615ffc232f33513fae22b6bafa22177b142ff88190a207b4eb5edd4bab67185ab0c9b8acac2b37ac2108ab09f96461a3f079c3c018c6c058d2809f1346889e17cc488cb645c698ad3730084415647728c2116e013767b37bb513000feb359b84105bef19cc7dda7abcecafcbba381bb0727c8554bbac2d42c18bef471fce337e2fb99d69a9a54fb14a1bc6856dd56a020317c4a57e315cbbc371cd673a0b0919209f2361990068f0570b530b0678e01032ac6f95c2021651a1159b0b221545134c500d857c7ba0aab92cab5b5298c1b7b8ad588d0d53860f0563ad9c309a12a82b14486a10b79d7b6d38bbb03d9bb49db4c90610bcde5c383c418088f51eda6a99e386af8e1802d84b6d7f236104c2526d577adeaa8dd1c468d812cbdce44b04d64ad2938fc6495fc0a84e62e506ea548a8f5930c032b59e54aa54598f9653a118c5c83dd07f1b73061c02195436b6a66301bdc21953eba0e0e351e01605d9919956968601549abd9ccc9d284b3943c666cb8bf8c2112f52a5c733691fc2003c5b6eb8589d9594b8c92c4c4c6abc2e5b2bb67078f81849e5b6760cb1391b9c5a57f8705ea61f2cc475f1f3a45a2a0b12bb976b2874cbfb4f7266b6e1e20e6c2c490bab8daa779f0109be1a662c985016c483a71e636156186471a9ae452bb973ec28bc135133e9744cec8b330c0752451c6944b7a304a250595d86b394c6762d104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4ced722667caf175df48a3a346ec7cb1bcc37d67d3137ff7b7c70a07f202893a3320a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = d19c2f2cae13eb960f72953444d3c7b1400caf6ebc1f85f017b9e3ea75db21b9ab3b3fea55d9dab5931d5aa0f8ca4059cc5b34a84f735f8002dfc802bddf8d1ba392cd6f26d28ededdd92664d844a2cef31c7f2f5e212bd83d77b6e82c4792dc7270d41cca4a85a2cc649bec1e68b6c7dc4e4cdab1b3ebdbcdf5faf833f644df51d0475216e779589deb3bfba63601ee3474fee332ba1e2558f6fef6ec429cc3dd24b8ceb379d6451b7cfeb2e95d256522ac6521e79ca0a46070c5953d7a023f8e37342681536683535b7602ee52a7c0f510537fb807478d9c2ffa301fe7ccdfe2004a7e9d71edec7cbc630716d4c7013569b2d24e836c7018b1c8501ca3e9e2ac04022dd196d2d186e6167a227d528fab261b7a7f7abcc4346114cf13be6623724d92338675c3502434c1efd2c0d9fa11276a9d189f3e8c0778a9794c587488d0d20527e7c4045b1f49e0d59716c99e567de1a64ca26776d6fa783648c2863ad0e44274a96aed5a740b62684ad5095f33037b3b38932f37ac74d3bcde134a16a13a1b02c655cc91492ae9dfc3c4246d892e2a6dc8fee0edea910185e11d79e723be15b3334ace0d63db94e9d950163861ffccf4aac4993e0ae569d92163597e334ef1ea3884613f88e1722099ac84186e8d9e436160d6a7030f88f9634a2c20798c4a6af86d252f9e7f2c85dbf5f041feb022935cc987d9e065b726ce3bb4cf9ce8faed27181d430569729854a34e798274f558236c8f6f99e5dba5cb97b3ac10b74738ce2b91c62770a7aeadaa9e6c0e15c5e41a1151e774509f026013c7d6bb21ea0710a6b3beab18dd44ad6893c6dad807093632cd6d6bededed816fd8c7555c41976588198191c808996e1450561f330283752eebd51100b4e74e3c7d151e134645f6d1fdbe52a01d5d61fb0ae7ca1fcceb72c87534ecbebe172423f4293e9a6a98ea79182895f8b8e98cc111685b18cd99cb4211feb54a96a8a834aa583b24f371b4f8b5517add7d24945f54c1465b5121f7f6960fb210bf4561c8f3b662f2e0d511e27e62dc546c16ee91a8dc7003482c721b0a9dab43bac4a28b5ed285f32552ceb0611401d8b0ee444b0b2896b1766f8a26eae7d9d68aebca3e8004ff9e4fce24962abfd3d9e37fdccdb0f3e848b7759987efbd40d8657fa6736bf7fd831d975d527ef66ee7a6b8da173d5256923fdf22da29cbcfa321d6f52a17f9a1edc6ea7258af7a580e553888ef10f9803ffd32fec3d5089762ce75e2ba2bb14eeba9027f4a47f5caf1baf3e94b23ee6755cc4cf80bb2f4013dc4f71f0a493717288d8ed173d91742f4817be4c4e0c73e9d2a68b809d959f0fa491fe67dfbe345a4640e05fac0dfbeae1f885bce354b99b82897379f22e41a82b3f54244b489bb7341fb3524c6500a6ba916e6582f0e0b7ca715114bea90f0d4aa5e14f1f545e4347dd467ee5ad718d57dcdc0d2427e26e2890070493730dc1ae3711061e56c2fd7fdc7389d65c75378e902bfc8fd9599edced15bbe6d9895ef676f6e09fa935e3479af8c8e05e322199436a1ef8eb8ab51497bc7556db97de8fcdbf1517ebb87bdf6c694ffa93e25d1d30e113fe8e1a1f9cc6e395deaff5d043848fcd8990ef54134a30654c9b28b38b863ee6cb238d4ca8c9cc5a0af2ae9586b88fa99055a46c11185780a95ce967eb0f9f1bac11ca753a3762b248f8aa4ce55e47ff54d70e26f8fdc99ab055e3398394e89ee1c3df549838c64de1cfb93708453b0bc82312b7e3e07f386357fd92625929728a188d5bfe19d45b1878c1a61bbdd48cabd9010c3025fcb217af29a56a442b46be34760655d8748aac19959427c2df6fffa1af7229abed19307c99f0824303b75e34eeb011b10fa21dcc4022c8bdc75aaa41d3b4f4a79dedd5e0d8ad330e46ee3177fb2bf0481a7a61315e0395fbcb5a5d77e0e21748ed6f77bf845178a52aca547a5c3d6e24628819c27c023222bb47e6a1b0d53e06d020823706a4c89602d81d3161e9d14b33184324a684f0f6fafec91031300ebd8c8cf51b953374dddd064101f3c0922ba1e711afe1418c0bb7967ec7b5601396d88d134f5503073684ab44a02069d9684d70c62b0a235a141daaab741c1e5b8fe70e3c15fc71cf74d019d9fd0bfc38443bbdd75424f7308c75e1f2857716b3a6faa62fa940808c590bdf241c13b3a639bcd2971d34949cd95ecf21a54 +expected_result = pass +expected_shared_secret = 92c63dee4666bfb34fe3095f65cd458654df578f6eac0ec75f5235e5da6a926a + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +private_key = 3c14bdd913cda0f267abaa8b0a30a5eaa527638c01926623b0bc2ba55b0b596a92bad72e92845828e8050f4c2f40873918e4524cea8505208d345783f71202496721e361a582c5445fa31fb662a64941abf9fc203ab4a741c9214c1b80b4ca617c4976c819794f53cacdb3509978a6df5900016278388234cc1a09b804679f36718255b2db60a7eee5bc3bc78bceea8060354b54031c4c76b30a1a8b1ebb697ff8606ce408fba72dbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895be01ed5c23a0d22707d89467a5b9c662767a0d77d5c49adca983ce7401f34526dab1cb9fe744bde8c54c230705548b9ed00b9f4ea055466cde77019324c0a7c9ba404b641a6530ae64a964ea47e6e80aaa4652c9a8b66061103f385479e50a780249a909c92b7913329a478880162d8857d58fa39d3283f5a2a7f8ff6abffe2463db40728d06166627e9c92283fa57a2e46190ab869b6c21fbeac86911284153b259bd2a442070d1cc581fdd333e5990f84ac67f47491df01128f0959ada0891c236e0aca87755289c0e6c8fb136974c97dbb1b8871a4c70aa001fc950f0cbb3ace4ac44f800252f5bd76fc1dc09a3d2f8860385a4bf8d765b49c5379140e0a2801dac947c23803ab6b467f2bb1b019b9d53771418312f51b28db18be216794a0467d79ac8abaf2c90f4b1b3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935dd429bf8319bc0b8199cca9d3f78c483b8e0771622ea764fa610ee13c1a188c56d0b5c17094c1b7a45321bb69d99a666a7963268a1d0a0491b8b5cb700a7d86ab9039330edd8bb17cf1ac79355a82166458d2323e070ac109c98d201358f22bf9a3b513b8bba43905d1a790a7b1a11f682583ab4fe0a82f3e316b7c70afdd823c8fb7acfd330b22f378e8597ca5357454a71197cb4039e9a81d7995d14587b479657584407b281886d6a7fe9b6170a056d2003bf898027c275b7c1c3d1d0c157145ba52d264699b969d60aa3873a9606041c20b17c90055b8016ea703539638cff8aa0a219542bf51b68cf153a86149881c087d898ef9c3a089cc70a8656117131aa3f233c73cbf439022d224422920501c07243432aeb925c4023185d3f897a79a983d857c6d1422f9b22234005e00882f77c7704cc74adea4c8f3971e7964ba1a530c1f722ef696828c46946f0b329d909a47b83353330630359eb8e9b7e78abc50fca8c3aa9af967c89f464430c815d1959a21a226a966a6434301fa600a4d129886826803ec49a54a34acd62b50e33fd782937571816421341cd76a3570c17ac9c338e4ac4c51077650b98ae445d236904da694f755c1a5b288275b517b4c9b896c49bbc18933e52d34969b6ad8add604b526488c6397842a54b6657b93386b0ed7d36fd2f448efe43b0a144c33f729df530c8b6340cd61897b3c50b0d8ba81228604f7a4bcd120cd2a7bbba3b4818177c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d93589021251d14c920328c4063c2af3c8c41228355527adf41037e1ac6aa69a427a55354ca9d54025306c16f93154776b4a7af9c9ef2298dba9b669c40bd0601abd410357b8940511beb6c96543d121535437d8eb5fa6a6414860ac4e849f5fcb09104a68ba7987f52bc859dc9025450332b28f3959ca78f18cba09c3c4522d365c93cd4756b780a9ab87a040b8202c2cb7ac3c880796775feb4ee8e5228ef4c62bc93e5d068226701d244348f3665941f59415c6275e1656fe68487f3500739762d13ba5d3ec27c5f77b7703a1b2e645b05782e5a21952584a323282df23c8a9695c0b537ac9d6bb4e7907ea4bc2cdd684ad647ce10b326585a0f7e486a4bc15418454ce4baf62b81131c0008d54cf9a6abd94e212c0193c724a54f8c12b4ef6b6ddebcf678ac0fd84cbca17284a326b7edb071f9c2a3df66334e29d588b94d684474261b3f8fc6bfc7a9328b7b91bf2023f088337b331b0c143cb86549264bede51c9bed644796b53d3f230327b14c7d699332457e90a5d40a053309403b263a59d7cc6e56b3e87592735d95e3aa819c41182dd9c0972592fcb2caa046883e491bfb4c34c87b995f143ba5f7c51dcc45c5dba619822102d005eda5ac7d4b02b05b8c53f1c79df7a92a9d4cae4783db3d78351b11b00e292ab5425ab7110a6847a7fba29c24241999ac07fa77b461841c12519e9388635513837dca2a51434bb03bc43e89e9b73362cfc5f05007428c6c96271674a574f64d51cb5793454590fe9d42728c5c51858b2c5554b143acce2e1a9a4238cc9b88b12670e884b743168c967574f1ed1b700c50ce9f84d32ab1cd1e85a3a31a324770ec851a2de70805497a27148cb66249f8ba7796c02cfd462823dc9020f997114ea758511b5daa832fb6b4d05e10fd9f53d0837a5eddc05add9aaf668b87af55516b63a82bc64146b21290763f46b00a6ec3cfd71c702a28719fcce1f1a2b7d124a4ec8703d63865964036a27274c806ea1ab9067e5bb6d1766faf4b58ed05cca5c6688a86a5f9216ca7187423cb9d453825404448cb7290a5bae8848c41ba4cad130894cb385f68916d3a5ab6eb045522ba80c1154671617afa25e15734c5e5051f1e3173562899873ba90d670d644ae4192351b108f8511c89dc2c1633516b0a850a0345d46465bd058999ed227c8cb8f02625f4f0570a72a77fb1171aa577eb0239bcc2cbd00c82ed1baa91992ae4283be56094be2bb4c9f0623fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf30b0900716416a152be54946aebbd7ab8cc2cf535321a57cda44cd34060f86ca496830a16652a88d069802c59f902cf08d91afca82bb5b3aae6b4af650a3d7f5a0cebc8ce63a2a7c7e07c5a0cc9b18ab56698087dc65b2a014b8e00af240397d8c00c7454380df1497293327b81cec6e43154e97b93d9695d21c807f621576835e5b79f42d777230c8dffd72cf41a05fbe51765280bc6d3928c1166a6838e33a40b81826be34685203c7041599c14a84d3df2a044540957141545b465f03579167cadd8a93d83a03f7911406bf613562bb6a9863e80d886709978cdb75037b36a60f073ffba561fd87f6fac17d04b3233f797e091221114c78e794b9a9073bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372767060ec6951809848ef7cffae9aadea314d57780599cc3e55a8b0b04810e5b3a2cd9cae6d729e4d994c4d296f2b07dfc97596f8aa4636c70863ca52020b1c21c074838a4ac0360f88154c8e8ad820c3778275b966a3568b36b3f44a50a019a8d588849cb39dd813d5ca8905460bcebf94efad35a3a2ca588eb4fdf999e778b24c41259f198c20b219aa6c1715090000f4407a7217ff5645f8483a408facfe24b368d9042eca9bc803b9d0712b21ee36047016e5559b5d9bb6e046a63ba32a9537380ea73a22b662ee892a62af4b2710a2920a36f1740bb55b36700426287329e4f3b63acc77d6f6a94411a2612316da5b612882605a930a000c18dfb6331f9005427d63bd5c66bb0b4c496b6071cfcc8df3c4b350bb252d920b9ab3f73392b3a6682eb222c0fb065977b93c8d133fc07249f6a0a47d19fd8702f6c618d2c170dba4c65317c1d0bb188a09c9c4e97212ff004d9477fc36c1a25f3c725a7982146c4f3d20b0b07356fc8bd18289f860bb8834078d7d4813da9bcc2d3746f0b9387600088f277f9f747a9862be9a851cae219257b190c91c17c910dd8315a107967fc619c20093ddd6532b6a096838b1be3263f314c42a8f4b8b71586dfa279550ca54d87a1bd46b8d9c75861080294e9a084f3970d217610299aa8fc5814611a40bc01d8d60ab7878ec5c0460b916dcc183f826888d0a03a89dc3e27569b2a7a461ad847af7286af11a7c7a07ed8c3aa76b209d98c7aa72a5c3049be14f723c2062fca960c28925e6521534f855f3fec4054f3224851137ad18c4ef959e47c8134c86356f09b82606a69116b5d572a7c40a6a300b689721d37e80148821aa74902c0c30331664a65976c29e80034c00447245fef8a3a3dac44824b210a3b04f3b7af5a824632fcc5ebb45948ec3cb971607ee94ffca362ca60cd6e895c9aa0ce699570bcc4cab9832638c2269dd9b43f880d4f507768e4986d85814929afe4801008103900230956193e7262a0af2a6036f4cb85c581a5d1256cf78c1657598bf1c45f3048f3fcb0a37ab971d30f7f124e7662b171a5070bb14a750b26af9b020a929fd7b2b244d5945e58b5bb64b2f60b7296491d0ac31bc6a046c7aa3a1738b8563c234d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d14550c4dc82d723965476a518ea0915c1554bcc61c814c80ff120c37e7e8ed6d5c407b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = 3568dfe1f0c59088f8abb35ad3875213a2a65519db7396b940f13f3c3128a64ef475f74df976eed5054329271bcf76017d4c1b4d12d1c1ca8ab36d82f7af859e14782b3e871c84bad4326870ea4a9987859130c77b1c2ce061deafd94eb6946cf39910fdc0a64bd9ab44e87c1abeb8fbd846575b0c50bae3f3d1b11eda8e3d285e7486e93ba8a0344b3f62036eb6b52106da8db4f4f960a3e358585d6b58521aa54785b64a6af668252827ebe8a7ded2f29ff588679149798c8546eb0ef95c47690127ae999f0b4473cf62d555f2c7f3d14e4415c4cba34d907dbeaa246f1c73b9afe7f4d7fb5ffcbe89180c6766a6cbc4392a2a381665cf49b0ec0aa445bb41dd0663c42259382e9c7955370935c166e951989dec85eaf907f4256a0e34f18db5928701f1735b5b2490b9cfcc3435bff0e3f30f0decd7d406e64a45e81d2244ce6c75d77ad56acc575086633f9e8852ba3c31555769ad954b8c5d168a877b3f32d2421f354b0ca88a75216c0885d9d39f69bf56473ee3c032f04479a45c3a5819835ebd3883b729ca72806ffb8c80e8f4249cb5e8e4e5b9d9ec154ead07be9e0d7af859b1269a82beb09fb815da5ed6f3f7b5d1a5aecbb26c5eeccfa52f81e9dd4a0df5f981b510174eeeca9be4ef422f823126ea6ffc490858997c2860a53f3a58a315c9df5b8fd6f5ec89a21c158e7328a236ef733aa13329e8947beb7c5e921ec2b3a750d5410f4512e25a657024c2ca66224736b41af8cdab22616909f607ed5b29e02c34681c7db9f0b1c981b458f56127e96e12534b0b2cf3733af454e9fbaa5214a3be33ab7d054a7af96587d7df35d1c161cda7bee9e0dde3b4dbdcafa49c5444937719dc7b77174fa1b41d795b436f77eba0173812d2dc5a1eabc50ee12532db8941a79c16f2b70dc8a6a9465bd7d05fa0259ed29163cf7227ec0ab57fa41d7c61ea1b170ff8ca0df789b079bde45b2289e686c1436a05e6b21c1ed8bb64c99af660f255a7b232ac662186bdeb5582ec186e327d5e895467dd14d5b45b518c5c80854257e0185d028f699e9c52bcbdea89c8816866f1b4b311c60664b63a90bedacd1d5b62521d1743e54f4d0518f81c221aaef93777d1e769ee10c7085b01274e3f4c890c93085fba1d7d26bb24a26c22dce7e0a3a4309604ea8630b728a53a24c998b6be599fef3f2f02b85ac645fc3afb0db2622f3afad432015f2f5ab114beeb9aff0289cd712ec00813bff8aba8b6f3a3f72c1e574a09271058c97bafab3bc6c7f7046add6534ed76882362f8b56492fdadd1e445af0958e368ef01dcd62a89bb22cd030024c1a69c2ca27e186815fbfa71cac29f1a536518ebe6524512f15a1d2c8f6540d6f7ed415eded2468e49710f97c85a58f3c8027b76d69d27a4bd5d004353a6bfcf05f694350ffa21531cbec13536f2ce843aca02f94609561a4e94aa019d2a60fb501a44b05db67a3f3a4989c361a8e196fc68ad318c2ebdf3a7a101d3ad3273c692210f01788f7cd8a2eeb9a5a6ae82f25f7d8713593a25f377dda51548e8ed46a1ba233b44160f77d0fd6aeac8c45d9c2a4f5845284adcd7fa389eaeebb85e28bccdb548d4135be9955568fcc22059fa98f81c7fdeb695242d08815e9b33adc7cff5c0d6fdd2a492ce921c44cee72da15d195b3e5508651bcfda255d029c2d9ff11de9500c0544c21b86c4c57ba3bda90d6afc8074cf5c218565c5b64f40f6e114720b586ec1b77bce3784b500a7717f0a8d5fe4c59d8297428aa905c8e42ea2e5ba54744a9af35f63955058288afcbd5ac75dd8a2fbe417c5fbc2a48c27f79757de22593f032c9052f9975cf873717d4fa74be7245f59c1166d573677781ad6591ed35d235740532ed21a41c617383079567183ef5a42b32c28460b16e44e129a99bb640acb1f374d3974f6094afb00e3ed232c261bc05598e50e03619f66861d0bc961bacf4ffa6bd61318b8447bfe8a9e4d97fefd7f99628fe16a8f388cef1a7a32200f0f186cccb8230f40c08880fe6d9f1d6fb19ba46550b5b6e340e95d0945b0b7915edb9ecb89d93a367db3f5f7314f134c4e5a618140f0414e44ebb94897330f17a5e689c103583e260ba4e356524aa6f7f7e6e461b8ea45643528fc9019a69fa664cbe90e5369fc74e2ff2e78266ccedcc532d7e16c4f97267b59a520845aee5f1978257cd7581d9963a153a45fae +expected_result = pass +expected_shared_secret = 0e2179fc3d310aca496244699b05da9b7bbb7891ed41b675e5dd48355a586360 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +private_key = 2d149d32c41889573ccb5166c597c3fe207cb806bd13a8a7bdf86267a93da7110a31f22221a17a5381c367eb1b9cd00810189c1f12358b59adbff2060ed6ac6712c660b51b553402d406bcc1d2444a863b6ff261e17aafffd01baa2b05cd83050ab460ced09bc7c0c2963784b7f9798d837bbc0483001539f0ea65a0574b46785645019b25130095725fb71556add2832ea245e250973f504dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ee31e0fe931d16cc9da767c3a48bad09874f7730fa74c349d2163638aadfb59a462e904c5530a0b485541e391b6037041ec6a0560563f186be2ab97a42520a7daceabf1216e16870437cf012a6b6d082bbb23349628af4dd8ca9ea986498a80edfcc2418c3f5a627ba8baadf3739b3c578b2f193f57b72dc2827a2dc379aa31b6127c65352338c012cfcce0af1b33150d488cf47134e06b5ebaf0432c172090fa6671670bf7b66002e135e7c43d938343d5729e22e5597a06209e0793e65417de945b5e1aaeb2740fb1b350c902c1390a97586564fa94120cf7538b21aacc0ac0831b477e37c9e984b73ec91ed88705ef4cafd2f15a50227c0e4c0627d2a6d7875e9605afec339799690bb6f0a5b01141a6976fd51aa7a079827d37ca89726686ba95d6f275a59341fa229b4c163c260c4dbc4587c50ab8f0ac777849b5f700209f17c15251854c35aa23c20d486122ec8145565966f4a067251b96461950ac2171f1996e94517610338b88c091c356804cc691922449db0645a404ae4a641d1482b58e6230c7965c23605d66e96c8f0418ad786801d7530cfa2b5b757e06abc10518b274e3992e538922b717866c7eef827d2bb4c05ffa3322981cd8069dfe028d878a8b7a002472d302253a83ab84adf5530cc5f4671bf5219fe600ba97abd2555c52857abb76ccf4760adb30346c55aa5340b189e1968f72999e64c0b76297d232412b3c9384783457b83309ba7ef74abd50d16ea1c32a2362aaebd02da7790fb8827ff368261cec14f3a2095323502446703783ca9b6aa595d690031297c59b25414455c155924a47896716ac45330ce7069d131b75a57769fd4b4ca1990170a3570160cdbef1c930063d56e3546f09b1cd913c82057c0bb89111e6b1bba88eb8cbcd72078fcbf5059fe25c84bb5607d7b20bd0733fd96dbae2abd9531ddbe3cdd89a926361bb56ea0e5f9181b2c8c1532312f3f9005135c07dc211b824b1e63ac96e64845c35c41e0313511a5d429663796abf2443908d353766d40f47a910fd04a710ba5d6a5b301832a5b6016338d8858b220e8219512b643b8b60ca2a9347ec39638b787fdb44ce72408dcd2504de24af91130abc09b2e7c9bb26b3393ee06fd77019ed3466e019ac92a416c9683da22cafb1a9ad3475af17a15ee9f97446096647578f77fa02e79904fcc008fe509425446ca2a4c1dff32cdfa4ce120230bb5cc9cb49a2e2841bf69a1c49a762ec171698ca0445201c485a15fef2562eacabad3259119c9ba4185677e03aa0470ca848709c4ba0c8e5814416c5678033c819773db36e7a90c65fa82ffdf6921c38285122163bc0744de5c5363c9a973428a6daad20e5a62d37017b464da7637d9d26c6ffc2b5f17610072c7e1ce668cfd97c29eb597ef51c039015e4b35a7d049db6488e271851d20cb61655cea5a074338a722a10a7f77b5bfa0c8bc41b346bc5ba4bd17784b166dd83a6a5066e0724af7b603d4cb3a880f95040d53b9f11ced9fa55b1771900e8924fd7656ae198b392bf23a83418519e3c754203a9035c83903df9176004be81aa0cfe690297d67cc3432f815c4db7dc5797a2cb99140e28e880097a0f45415ba730b616572c2316895e7c0d11073c4ba5a6ddc74f59206deb3917e84a9d8ec6c63fc83a001da56b03bdf9c077be63645331596bb962845594907a22f8a85b084aa80eec51b4f27e1af011464cc73f6615397c22833ca5b81cb30df1982a18bf148a9d3fa5c6a46c323ca1b5a1fc4392a2204379bcaa3a63ff679f3ecc00930052ed80c965a82e55c08389d284d4060254a42f87c6aee7211933e2c6678caa453b8c006a94960b0de5192631f9ae68811d5b729eaeb1c0cc8aaccaf180fdc09792da38e194358124b7e87b7f55181689b3c5537011bdfc9e44bb41c301705ee232e0a6bdc2e4c6bc55958859a5afd2b82f502e88a746a20179fcd60fe0276affa12828129543471c7c620fbab41db49173ae4a144eca173b23899a99785a25148e6c92e6b5b3222ca7eb3bcddf6508c4b19a039143b9d87aafc77ae80627cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861d950256484802a7b479b67a803fba87d916d0918bde0973ba3f2c0228c0dedd302c6fbc9366c4eb708234592cae1f3c58499cd177621731738f0d8573b53018ce88676ecaace719063910aa3d08b13a2ca2e64afabd52a309b2e0a849f3537109518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98aac23f489b85a9b18245649e8ec3bb8397c4125864d8695752e942437b315b7286675279df55cde5d20aefab94b1015030c40de0735472e02aec59027c8caf0074b0fff4bfa12267a3a5bc6a380632436041cac792330a4ed585379114b641bac7ccaa534a3863b52390d2173e4474299c8e1a2571bfe215c71b1d23c14368926a2d0944a1f20bbc536c84b7c8218b3937946cb227134e35c36f81c73d6433d4492cbe9bb1631787376115f6f9c3e5b76e83812494719b60231dcc4182c3e8a3e21122106b9036c62755531b6c5572cda5647746b9fe64286d395cfb759caf4136466937b70146cb99010af4088aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cb907022bcc72617cfb7bcce57988ca4c3d60e94d12c34588f173473a5d0929b5bcb09cd8f91534e7bea694576638889fb29c2074058900587fd8889c89593cb5186fba07bc103f4196a7063ba5c4229170f8830e254862457adeca7219f73f201130719b39e0b84845709f2cac7adfb60b26658ea9137a940b1ad8ca7966dc1c0e540eff9999822b5e69f58133902ad3704345914e17a30a96d6a879e320ccdb91f9f7c68f683c00532449f5420e8444e4c01df8b203e38327e566130c164d91bb14bec93b6eb4419a22c744fa9d92e861ae7bb13862288030551aa43bc4f809817675290a2413e71c9d29578df619be496061f7307248ba88d9a322648f969a2fbe005d9f895264887898cc0a8b35cfd0ab7afc594c9771536677571b9188d3b5411ae450a5a75e6dfacd813ca905b13f0a52153d0793c908b2d641b00c3a483293399d0b1579e28f240393e13c86e0121f1dba46fbfc9a5d062c1ef670e01c4b6b7a809470ad15f725b80849a0ac6f5370c1c96a309ff964dd1a9db2016b189a61311cc82dd652328596d6a2aab35a8020094ff7438064a7801a050090a18e9e4c2b33c14cd1f97b518ac9f4eb9a1156c816e6ce01d6053481b57b1787bb925faf531fdcba1be23570dccac4312c148e7833162c6219835ce3da23b1d149e434928f810577c37d0340b6bbb45945d789f6cca8fd5226a3c066595399ee696fbe2025701669454a83e3162535d51b11216affa7bf5c62a62d696d4532954791ab088ba84208a7dfe76b33861ba6d6b51dd322005700b38c8e4973c934e12c374c3c86c099fb42b2dad468a8701417e2b5e902b674b759a0f8366a3c00be49b43c39a016288a1282c9673c1204a73fe2b45e90aa2732a46abf8496cab31c52066052684d078c1926d374da041bee98939b4a597b2166451801cf89cac513a3d0890c3163150a54734b7960bf5701f837af59e9a4c631ca49768829ecc6d23122be873234d825209400c883cb47db7b60b1b1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342a4198366a8bdaccdab8349f9b9aef229ce46d4818bf188338aab48420b9abc13eeb990ea41ccca136fe6a3c3827bb40c33c1c749620db32dbd773043302b8b2b52de82910ba96ee430283fd51f17c38bd1734b4aa353345777ffac17797683ad603cde78c51dc45403e97514015fee950215b7366d76b29980c79ef727622919b59931e9a78ff6977d9e49c8da013a2920827a21988a713e8a378c3db9c90b8a2703e2961b246a5d867dd98692cb60093d617fd9493edee2820bb081b2b1c3c9e6941817b408255a0cd09eb8aa43c7d298954b2a92250aac1864d1086fd7338ade31a36f756425303a51bc1ac7f920a69273aa11b7f077000f9ba015035dfb96159d28282bd9960290b9fc51a79be9888d737329801428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2c934c11e2eaa7c3c4e764863e436ff12fc9f517c79df6344ab98611f57fe7296f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = 8b5c5386694f22a31fe63768feec7eff7e73d01ad097adf11a44c36d84945968a6b59a167c808493407f5b31a0430e037538c9b12e5d52d653d6643dd3cd73a8aa48ef5ab20e2bb92cc79ca14a8bea99af098b29cd2507d06e0ee99140c7e88c7e79f7ffa90218bb356e648d034570cd834dc37d1d08d4ea82f88a502538a0243b280dfc2ad395a04823fb6183588f48d64ea0f81309fcdaa426d7e98eb2f60c15892218a5b804686bb842e975b561c977ad67f7c91d9ac8f6d103a18e2ceee42221ff5bcfda988521f43fc777a34eac5eb3a581ba69d03eebbb9ede81472c2a436b842bf899886e8058ecc84dead1e563ba6fe889a7e0b25ad5ff5b0077c7910322e0d0e8626bd636bb84aa0e7221958d66ea01f7423d7f61fb90d0c69922436fb6ff66e83390dad9e005bd882895cd5850a9ec8e7b64de89dc4fd244482806a8db6fde17013cbbb3a16703a3705b02ab690a88e1ad194ab6fd52d9d5218ae5454c05b8f03c40bc9a8f24a60f3b4b603bbfc251bd3cb7524d626378f0d260d67c027a52e16e0e5927d486a875a04e8a5c6abdec139e020c117b99f901c44a98ff9186e4ff14701b3efb455d223c108969675811f70e69d91d5b3286084161698b9b19562beb24737e9b998ddb9898d457defff2017d9e5e6c08145c3c766a5e1cc7a353b169570404dac2738716ff7ab0c2e56f05689b139a0f99119912e36ed1126702a7d5c52417740167fc481b402ec4acbcf97e45113126c6a9373e962669e570535ff0055f2cb51d1f978a60cd5403467edefb883fde3963bb77fbbcec128b62b429758cdde0f24262b5603edee30d8676e2fe5a234c83c6ad76fb84b3e8ed583a7eef115b9cb882f62e9f03306b400c51513f66e893b09fb01737476820770b62ead2d5bcffab7b85b71516144e20ec097bae7a732102580ce71b6bc05f1216615361224637c5e1005230aed6b17624c7b22943901aee4102846e0e9cda4b92fd41fc7f95e043dabc3fa1c4f860ed6a31236b1b33e60213782e8eb1ba3329a898d8cbd961d688735639a4705d5fe48f2682a5e58ff8a3524ed26e305d1830b9f231391527820f39a0abcdfd6e0ad41de8888e4e08bf777d8bed2a069aa66be30de2a210be0c30d1cfd25860b187e84c3cd71cf0a0dd59042dbfd52d299b4205c515997855432b79586520d60470589d1bfeb77256b3c65d95a14b8a64abc13c6d9318fada9f4d8045fcc04ec8da30a8d5bde9a14d1e8de93e9d9ffe64a77ca55d0d0473fd8ac11d3523a6f42d01df097d3093d9a7dfacfce4b49f03db78cbf0d587f1783f3a7b57a6ef7a45d7f47757591401d92899625b8944e60349bd0df5692e448607273ae7d56b864ccefdab75366c8435385f6f9feaf08bc3db55e4a2c18ab236e01f272ed11dd0ba70259f67bf369e6fd4972910a2c84c7b052deacf75d7b495238900b3c891bc46a95c82e3ee2a36f7a6e42658aba552994d1f6fb80c1f5b2e0b7ae01605e8ea55ff1b6ed14b4de413e501d8d9dc1d23e456e8c17228881ed90c3ce76d51f9f4dc74ea863e83ed32e47bf3df0b598fd7c5e10121a8cbce0b4bd89908384e2ab7cabfcb61ba4a2b06a524c318a739b13746e0110b50a56a583c0ddd133a8177b2a43f9000b3cf83afdce5617910539cb1c980651ecbfa2b2f1e1f4e4f97055775a5f439d861ba4694d8dee0f36220789b902fb2b4ea86280e0c7bcd638d43a6cc399c7c164fa5c75f1d547147589cb02b2bb6fef44c8927c0d26f0bfa8c6d5d341da0860f6cc4f9cd1ab4ff9225f71411e3a3b30280b3883e1e72dd29351196426f9a7aa2c0790c8d091d4aaa30b16e5262dab1de3d8cbaa951e003ae4ace9fb9c383030db4cdc6347863bdb2a4beb1ee0eaf1a276871b4a9f03f7ffb82f18edaf1b240f0e9e872247529c6c2a60a02a90526609b460944e52484e47c38b2b876854b8a95875c0e057902df9eb500bd113819d73b20055553bf893ad2af55a6c107aec3609571fd7fdb05fd1a65a206f6799e0560775865aa3eab49fafa60aaae6fae87ecc06c18d5499b71ad27789634baba61854282e2f0f7d06f8d4295c7419119e49a2753b7013ceed3f4f44b008d41c543cf47418d5ac2769253b636327d3970c0c1963f2f279c2415b03418a1a44968662d8663f7b8e4ce66036171a3ee37c476a239490892f2968d19309a460694a3 +expected_result = pass +expected_shared_secret = 573a8fd5e5935badcf974c50cc36e191f0ae2c1458fb00d4117e675424d4e37d + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +private_key = 85b01a4a587bae308d39792b47f71997fc55fdc2746f881ddf7bc215145c56d399c6447ada39230866384bb718ada160a7349747867cf695cccdb8a4f1fbb3e573ade85ccf38924f36482bacb9798d481521a0cae103cc9fc9675184490f281d3516cbee910287758a4c374c0a4313f1c29251b1655522936dc329f540a1fd887f0c775823436df736c367aa3013341e66854fb39a9eb90b23caec3e84690ad531141f39914a77a767a47b60f2868cf11311aac9da94c72e9624d21814cdc99c89a4b35e1c4c63cbb3edea06888162e180503cfc6616b24d270601d0d275c03109dd9486220b66d523a8111b4de5b99d236586a09a4f77a240cacb4a737c770bc4915f55b609075ee68499654baf90622647052a8369872a93114c80c60fca1345e20114552119669a0d3a7188d3326017ce92112f0b715c26b40851683478e5c719c11088f00aac577f5a8763d4a76e3cd00cd9061f021672847ba0d4785ea7b1b28fa364e64c4fb7f718d2352b1fc26858b6552419a4d8e1b22f8c7992e3b5373183d040948777c356d514fdfb2d0c5a636bc5416a799270e5c975c0a62f3a76fb134646b333b75582f7f2c51cf4bd37835c3fdb2ce1ea86306362f8216d27e40ca43a45edc9554f08c604624659aa10ebd29e59a60f7bd66eee447f4398addc73387579148bc4a26b6749c961926fd34296db3044cb0d2d1312ca6a6755ec48c46865a36a6330a9aa5d39167c6062ef1a7c82ca5c0ac1b163b85e43c278312c4304aa127d66576e7218c2d0c850108076109919ac6931264dc2e919ff441875e607a97772feb45f14881fbcb37b4d00b45f416cf56c9501c6598ff9425249740eacca49d92e31d679a4f16c3ccb4384db45e47621719c6c585ccc03355216d43625c08760254ae3cc4aeb1287cd5c3f0911641b05c7036c9bb360c72902325830bd25eacb5a88abdc926e0f205ee857aa66c8c47e434d8bb4a6cfabbd8b681c427846f0e18a2762152b170063b489a3e6b8ba06b00f14a3f2e6ac00725e5724cb629b7a312b3a1221c9460917c07637b71050bb644a38a8192270c857d43ea9304495206bf62b1c4c11b04a817aaa996b2a266ceb8a80aa46674f16207b61bfb484af461b6dad9a9e6c22c56f81bb355a6705310e921239497809012159e78a8a249796c155a9dc7cbfe7384dd092239c29773f6610e536a77b879eef054c5e539a381043c1b53d69566a96d1931b166c6f066cf0ec81e7492a200876d42007724ac916460a1266ab77a327ef1282479685bc43a2718c93a806c3de3a0cb918c7a734cb04759341c5b1496679987aa5db93b70f903a5f4024c3da6fe8bb2ebc27182e1179611c61f8f6214069ab83c7165a46caa74bbce0897fabea9b6b58cd34e7535b0297b4359960d23e4a498cf7610601d92af2fb6163c4b2761615121b62a7900b08d61065c83a69d51253d48399fc665962ad36275ed3774f114a079f13b8bce420b44638cfa6ce6018b58bea422a8287a6680eb21c75456592e8b24cb6c26ec3d3c1dc4a19ca16888e9b7fea1a863b7a0143307530b533269a8b692cb4522ac1aa27b01d38603fd009e1c02017bbb36da2049a2c5045a63081266d69d88eff7c2147ac956a33b4c198c1eab2ab93c592bb5137f291824c08258cd0b0bc4855a6b83b81858ee7b4beafa59cf7e4a03675113131251ff512c50aa885878d0c086d7461677bb81e46e4790c30a9a7ac4e0b3b600f04ad6381424a4b430b0a4db2387703f77c4a0c51072bbda954b473f86ad2aa1a5b926d18e0b0c25261502ab2d31ab5e837675b369880a2786389c9ff0ba07f1098e56c3c92557f3ee934573901d0168b3e35c4610385c324579686571a051d4852257ad329fdc85178438014fb365a11cd6a40b41ae8caa46a6eeaec1b264b8cdb2c040e928ec3829f3a7025c66525e937874e09c7fac652ab059a5017698d7c0123cb6dc889b4c3942a6e834d029673955a521318b930fa4553f46058922b57831e947015aa0052b4514deca02213e3171d7063bab2305a3a173ff68a1d46106f1aaa3967bef778af01c84450daa35b06801c5121425869d61213bd4b44667b7c21541103cb1f24b8a472e55e468b8a6cec630314673c8aa12fbc135b79498480721180c3dd1b72c6e762e6e2c322cb783f069a7e5594cd26a0914b3104b87318d0489a63ab263c88d561a4c8fb9a77c72ec2b917f685333c61989a4b3995d74589300688d2512943ae79335dbfb0c52cd14b16c085d510918696087d2ac47437c0294b8626a65f1e373d19a0107de053219a22bd0907ba19b4e7326f765989ea61174151356f04585cb89ba8d05a99808283b550c8a3816eba213362b5cec5773e152d14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43ea22074bf46f252a125d3740066509c48ccc347abdaf436153911dafd114555964c49ba9e2605213dc8a71a05e37b305f922a4e9a3b31e973e19b161bc4295d290535dbb8b6b359855d811614c14a408c34926be2700418139998e356acd5b85281b61b0c78733b0aee5a1ca99b56737c669d535b276c5546aa72673c5344fcc7923f69a0ada7096d75e81e32e0a8644ad73a4e7d19b3be97ea3d773be842597761818275cbb8aaca1206fa41686613986ddf37949842ba1741e812217593815c82ca7b583513938931b0bc829aa55d85a32b6822013244f2a3bce15791620e6cbc96b8555d0c77705c7cf996292cb5592e490d6243bfadac9dad7270a125e14faa8f8b321cc6c9e3b2407000340702a4c97a0189febc47e5baf51cc060af7cbf48642d46911e0889eace6bff53ca189a1036ba94912582b0f8b679a3b6ebdb31b7bba4f9c4c349052c4b9352d45e68463c865ab331884982c05f3a1fd78081d946a71d984887041a0e894f6995501233363027a3b7c321dc4a21d8463c9369abec4826f0906039a1a83cb59cac584d7c6426c91767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444dd52b236d4cd2c26cfe39c1cc8321cf7156867b37f85188abea7a040400dbf4830ed1835b2d47a6b8991451a7889020ead45451f46623002b31839c556a22382130b7689cc92cab281b164dd237357a195f4688f8f385f8f45a32432bc238a0c7f78324bd5b9e73aace5391d60f28ddef61e4e2c493c136b74229edda96c22f70f54435c6240747d963e576b2aeab0bff2009ba0f34b65c2a35b72477f36c914d048545c513ad61f964829a78bcccec39d2db38496a209afd760f1a51654d3125dd42c3ee13353f93e0114469c2abdf879050cd9466b4606241158a60b35ffe1a8956815419b9fe843913d22b93c7283805ba3098a52bc16bfd9b27c29155a22c99eda56530a69964466065ccaa447b13c4c8115adcc6285d947aaea1378a76e163556c18459b1ac905abc9b39e21e12486a5e56a228395093b150fd550feafab094602672860e5c74240ac705f25903e70667968435a4dc3e24dbc77e9806ee94436ce00b11bac776b46bd85a94634c1a3bf91e53781f03318aed41011a390f48e5b7e2866d11783c7b959882821fd4745a2fb3bf1e87756008ba1103a508a584a3290a4aa4783f10a9e62a73f11a0d18f9b8e3a608a58317f3d3909a5a622bbbb09b52350a7a681e2a63f02504aec572328155f67100b6331f38835fd56361fee46b903ccb020a2998d651bd2cc022f1b4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f43259025724ac0a05e9de54257859858685cd602bdedc01047fb903416a2e2d770aabcce2460903feb40274354b2e705111124887b331cba10673c0d2aca027a2c6ccb95c701568c20346ec747a29de09ff6311fc172910e41031b95330e240ebee2026048047e03c6de9a293f501604d3c7ce57a715db0aa91a6151230731e02f467477d04a5aad9b2b8176a1f056c3140bb1454cc7ffe380cf97139f4800fc4b740a22520a3b2a8730caf5e7580352b936ab9eafe3cbebaa87fdc771b0d704e455b8153c4b6cdc780ec415ac7326be810c63669a7f30a138a187108880b5ab97265a2158f542c37828c80b4bffb474ac27c6513bc54f0897ccd9948dd3c78f60c4cae733aca6caf41b9ca8052f25e58e78526ac8eb30afa960a04a322c582e5ebb286accc225a187a074877c21329856343c587e7ab6b09c3427091655f34127e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860ca17a63d0b154c9941d9c219c0a7c982114fc0c85483639a0f047a217a148346fc844c44f37270e775c5ca414ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc5b07c8359e6ec4989c34b31293f4df965b5d95802afa5836beabb001d5cd4daee6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = a4793adf41c5e21b686b9de3d72cec8129fd8a2e5a0fccb6ff7e2f06e82d8f3aadc526d701e51262e5d06883621cb5574e2e450a20fc47f20f7f6355dfce304028976c5fa57b63fc63e6ccfed59124d0a582c43419e433f415152162e7e4e08589b042524ebefe95166a55785ea189fc09b4bcac859274ce8c6d01ac52924874c8862dc1bb3ddbeb1fd480a1866567717956b26c55b29aacc0de9df4cc97065657092ccfd5c3854bbaa5282f217e1453deb8c62ee5a2babb288be4984cc32a86ec68a46eed9e8a97c369eb1a571105c2d63d52e7ca4921e6dfd4d3755d24965969c1789990608371e7c3a50d25aec8ccd9a43b681f4ced65d76640a668a4cdf7722b3e875a486ea72ee2e93c1d8b2cfe374e57dbdb28c95c9e9a5c64dbaf4b1c7132c3ebf3a951e013c94f653e8b1cd1f9a520fe7224a5b27e267d21662faf8c4b23043ed8b184bd02749654a25accb8580455c8e2af7274f9d2893863e49cd7cb7efe28a9edb4fec5d5acaca155aaf9deeca15d63cf50ddabc55dcf0c24748fed074447599572b51b1d6ab9b282ed9f53b5b77083b45d1f4b8eb0cbf8c29c0ae281ed97d9e9bd8a322cf48bfe70e7c091aba044b99d03336d015108831b5a7b6f5f2f4617097ea14895bc7bddcd5aa236eda01bdddbcd527d1d28de96df5aacb6103d214eb7fab3a3edb9e53847c8944716fdfde2365dd96a7e5e7f87f7566e52113cb584d17b849c35d6c99f0b5e2a2e48e618e57629c7531ee9fd098dcabb8920b97830e611563fd56b852c9693f0d3bbe5ba879ec4895d5b9e58cdca0bedaf1f9a635b2c73d8472f473f904c5bde372278d88d96fca6945995157bce76f8c290ea58164c0aeafe262c2627eb44d2915a9822742f3d1ff1a6c114ef3d5c04c827be4c8ee387223cbc0848e5bd8c59d869143ac4a58d0fac8763fcfdaf3b68f5edf1ddce50ef6d5d556babe89ed42fa2fc6e9d09307342d819550ded95155001a9882c69c38aba8478c1f7c9f1d85f1c69f062a835da33fa93c304905f9bcc0a8b5d01f8e67b0feccf3dddf490d7cfa46bb851c7e3cd1ff72b045102677b400cf9e3829263ff03943bd1767caeace23f387eb4ead7d27c73a703792279f9ebadb385162e2bae31759fbc735821d547da0f090ce88b12dee49fe9118dbb908b26ba68057ecfbacc84e705e15d4a734892e2546951cccfa05dff012e0b76a4b25aa648e78ac29b99db10773bc0dfa84aae26fcda78e906099111f3550b32aed526883a07977578606c78a15315969ce3dbc4cd2529421386d2e20001652af4aeaabc9085b26164f8a1b61a396be51fe6718f98e2ce4a67c5f36fe46cbb3c2e06f763a15d1525068b5b3dd7911f237e04fc00b461907c3b494f7400f6ab50db133d61f816127406ef28a61ff82903eaaae490646a2fd35da87812cb24abef28d381f319bae58ce8ae3696c30eb3db47e68c6e10c12a98039a3c2bdf4176a3a072fa5b020c30ff3e0ffcf51831a25c85523ab881cac1bb7f1ef2f18b1a7aaca6724cf60564e3aed54e5cc5b54259606a71d41a561f73605327d8429ff1da22f80c6f518e505f9b020cd1cb899b69e09054db0e7ca12c8ddb7e64ec2c02dc4b9dba1095487efe828f04f6eaa4009232a4f53db88b0f3335e3277a6c86b814829d920f409467503603639e7d02ed75dcb0647d0110722f94d7cbdcb34625bdd16683e00907c8b43e8297f937ab953fd0c22edc47419829210563dd5658ff0968b7c5261b09470a73c15f960dd12a92459f4fa737b63bc6ffc85c6bafb7bceaa947c564a3a30f0e540de9422918ce198f643666086772efa12f74917c269dd6acffdabcb6a71927a693120dcbbeae2a2023d1bfee1948b2d85bac9d3911b4f3e23900ac9b3624397521481a0a19502419f48ed2bd98ce979230787bb3bee28cca07b3a6cf8b1e37b11843d5fa41ffa77940ab9c90d61592319f728f3ef0f7ebb83c6f0cdfce9a55218b513d855e76599f1863451d64345258247a812e61d8aa5ed86358a95bff574a2a2c69c719104a04ed896921c4529154b0659de5e611ea81928f2fe57c02c98aad4c2932f9d435157ad26110eeac754b94d671e7eedda2163dea0e78eda73b2f776f69bf0da1c3a01a7f30979b7f8d4a2dc091af08904f123e04590014b9df8f6f724dd2832ca55c8b623dd435a2ecba4ad72119fcb42c2d6570 +expected_result = pass +expected_shared_secret = c8d5e0dd64b4f3c6450fd24ed2918887d3ea2806479d3fcd5a19894f4fe401ea + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +private_key = ce732e28b21f42f2bbd1b049e6b80264b218b581cbab8c9186e325f7617895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b652f86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458e419cd10c10c890c94fd3564aa25f1ec3a3282607d8b1864022cdccebb1b1e48961207e29264a9ca86c94b71d5382c9c6b8004c818f51a52006706285bb3281618a157c80c2c00905c33316516c17f04460124fd79a1c330417984220334c84d96a66fc8a5556814c58f7826ee86f17319da3f504f0124c3f06ca50792c1e1800feea8a8e8805a54bcb90c52eca144677327f5058cca151617f443dabba304b353f4a5caabf0c179a772582711c033b3f3c1225f191b887d8294fd18914850de6b194b91c250374963bdc7215b07cdaa8001372a21f0c3845979386c27949e0bbedc0b004258866a01ec5cb82fc751ba2f4510e514a3fa09b6aea7e5e45762076b81d781c2ba91dd6f40cf13c91e947a7d7abc2a2aa91a1404d87462b42aa71eb15209a9b0d4990c2265b051163cd2ba8319576758237482f500f7e94b3ff099616225737a766c10b6aeb213b5b073eff93c3ac91bbf2b93ff47c84d7ca2e794990e2db4a7e9ab19cb50cd522427e6a935ce3976490b21792cce5e4b971668c4793ca4954b477703730411df1f5ad2557caef78c914d0c223d836c407936ec58825f3b2a1925a5164b097a94a13d8ad3a27bf1ffb0c08c72b92215cb1b67c7d2c4a7bc7a6a8a054d2a34de69c78195bb149e4b4cebab78f41612db19540385f2f74757c662c2da3c7b03a34a9524e2ab90f5cc21fc0d2ad84bb996e6c73426770ffc1c9942cc22aa2934d97a66037a18760c51b0236ca1b1880a2286ee5241ffc220a4c6ec0e296090874b3ca751dd701086a15f419c67eb4514744047d7848980c036107586d36818e74ad98989c8c02afab4134ee0b545ed707876a613ffa10be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d6e29b184a38d8091b6a2c288ee2cae833a68a3cb6b30bac5ad7567c788d8c803a7b622fbd8a253b274b93593115b5b7a5282eaf93706c88c178bab897b7198c23b844219852a60410e8afa85c902edcb9a5e87a31ca84ac6b89a75830566062bc159cb129277af0645d5817c8822e384040f1621d66d41643897df21c1013cb1b426a703f120f21c780c67bb011fb3e8cb746c0b14c9f847dc1235f72e6bdfda1c55bd26e377395c4b17b764a41e0f7312782bf71820dd379befe58901a011fadac1efae549e5933aa9f9c64ce2273c486b56251674d56212c0ad7637854c7b8447a135fb960ffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cc32b395aa73a916514533857b4c3405fc32c2946cf4f4251b2091b6cbb00ce296459c45e558b5048b79cc4cb8aa01bd7e82320637a62e2038d5b3c0593b42d32a38be8312ab022ebb496a5fc4a991a1baeb660a23988fba329a79dc7144d20b5246466f25af4ad971014970ebe2b36316b86b3585f6b0753711a0bf3952c688b4cf6c8a24c0964cdc1f5c1c34b3c28359ba232840063ac30bdda83f0611042fd8b7c2bb43de68b712e67971e76e7adbc0879a41afa358c2258888769b0f785f2b4716e76753d41c4215b98bea2095f5c0ceadbb69c46ca152b3045b95a9ff198ef5302667d31f36e2330a3c1c44e983ba4388a7022f1613a47d19249f2534c23ac25bb76176aa102f103d1c6578ae141772e36ed5f30f2bb02aa34480b7d57e935b5097c5c5b61422ff6249b3531361c284d67b485fcc3f942501112408d01b96bc841df1c0a9136c01cf2652ef067efd740a68f80f2c1b70476b8b67eb14e97104722cb3c82c42d9912a2f2618d50c27312c13eba245839313ac08aa9ac7918252122a6a8ad632c691c8c0f84bb02aebc6f401c2455121ff33653e377805d3b2c8633d8b141d6b6370981bc63a7141eef2bf7e86692f28764716775bfa41043315e5cc1199427fc7f6a9889165b6b09d0bbb80a609c0d52063204bbaa619757e1748412cc1dcda4c2a102396927229ba83b1eba239f41dfa530b8a2779060877a5ea142910a6cb1ac97ca2466ab58625e823fba58429a613f2c92de06993ac7006c8e4834eb491efdb1988b9794aba1c0d42326e9a797c67181995999a1053b3a1ae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f263916041ba9ebf2b86e21b127c5951d7709fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4d50fba956ab9b881ef55a6459199c2987162774f573599ee0b6b001cba6bb5302df24ea0622d3fe2a7db12a063d528baea6dec8a97bf12a61249010eb7056ec5a9573c77b848a6c6fc13c070450919054c05be006a40368094775032efdb98e087991d76a703924528ec05ee50bc56d206895552cbf4999c6a7617ea35652c8d5cf22590bb9fcf62aa0e055805279400b2c9522cabe1853e06e6965b517cd04538d7f083e27b95c29b073ae13cac42beb549337491b88c877af8910bf8659fb2f309442460ee93a0344ca83c58c1840c95ea482c81380bae24c01c763b2bb05b369bbf074c8e96ac2b5b73920ae07318057a643640fd58c691209b08c9b5cbe972adf001e8c00fe853631341c8a634cc52c77754790a6540ce9585290aa243231332d7ec3161b096ced68d80208c362707ed892921634b4de6679e08a10f55c72043348bc512ad39c07dd41a88d3c8c06769b6c080b9a24080684aea9637527a099bd53af1505eaf0272a1f537593669e6ca1d5135ae9d77b737b77a475b61023777eef22477b663d5848ba7d8859042713bf7353dc46c2e3b9e75788b3813b4844c0a233019529809487531a820a079fc2a43da0874c332695a79aaf3c6d5997bfbd27783064c1c055b82b3be463b5b54eb8c2e42772cd56318c6658e0b90cc31596b3880033338e6e41e9d1187e3732b75f50ed961501a030d221370a61788fc8b164625939e7b19d076b45b51c555d063433709dbab05746641410cb34ae53e3652a0ade7ae5dca29f0e22048668abe03869914117b6cc18617946c73a20b49826748981367090e8b72b8181ab696b878c79bd16683b2ca698e1489daa23b54eb017f4000d481b268e2c7c02a75fb608217bcb1290746f7251d010a581df15ebdba8c5d379441d22e591c4be3c9cd9af05956674f558c2387518bebc02dc3c2971bd264143271ce28b1f419be088922e6644e939738b846cb651267a913936d80b2f4e8987b5c48c37672a222037fa1529a764be14a87939b6c72b7730ffc4db926836c71a56112724a88c9f55aab44638a4c9186717246666b28e1003ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed16b0a526c019e7399d1996f44755fbfd86a79d19fbe3957ee97a08d668adee16b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd2c0b398383378ab973c9647db074921531a9441fb53a94e229b7c7ba8f2ec9a1e830b9826bcf1d353d91abb56b89c33fd37ee6130757d08a1699929808c881f9907556af18a95938a1bcec20191ba5a9ae32b769e3c56d4cc6baf9c9152359609a9e8dd6aa9ccb12b35c9db5605bd8868474e65257f785b429c1869bbdf6e118024c906a951195dc4361aa95d4c53ca418a7b6926cbf539ec1f242dcb3b96e47bbe6cb0cd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091c701ab73271cd86765e760f0a58beb61b0e2d12bc7511d04b98e8fdb5412f618964367e2cb694af203ab805889e0936c55bf8553b2b006093c72015d8629b494a04e3b51cf18347e7a025064a488b42c0328cea0c57dc14763a74368e36159c72b232c8424fa01b5be63014fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc4529a00c1ab9f67e84de76500f59c7088b1b9dca9ca9f0309b5f12eb4d55f3d734e086a843a39b29de99162a062b1e6874281221ea3314d784572bab031a3732010a50c0ac8150691b621687b6020a5b347817a3899f141bd6454ee1b25e0b130bed368c5f905c1637c036c22f65ca761270a9e8bcc18dabdd78bab5c48a3ddb82a01c646c9dbcccf972b9f0ac4edabcea3088586e8ca08f7177ad3cefd578f9fe6ca08c99167c65e4c6193251288785720ad110f58f81f4b938dfd813b76887cab48bf0cfaae5a8a16f3b110e130be7313411d517e6febb2e0ac004d44380b8ab62e874538d005d4f744918a250e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de037f1d7e636b4ab366dd5725957b9e5d2498e4ee1929f2213f9d05c882d96a1065a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 609d810d89c03c441dfbb03f5bcdea6edf70d1a067da94f6ed3e9ba09e5ed29dbe118daa609aa4e7d5123cf423003aa0c9e4e9e1e181fd5d8511e4c2781bb2d1edfec62f31ecb486e349849bc9529aaaef620e1ac497b54d315ce29e1b0244ca97a1fe8053eea30542115b1f8a9337f4f0219e5a1d4012b44c3ccac837ef90e92fe9f33f5e968d6bb35b4c8cd608b3d15cbf2e262da93343368a4a3d91108976175688243a9596b62d1d6d7617c31335dcdfaafbc1d9f3928a8d19aee6442e6e04c0b72f119a596f203c0118d307164e8896f19c903f968f5bb3970f71c63dd91e712b9e53e90d796e6fc5cfa7ba75a3f0c3ef415272d9f71b328112cde8e5fbdb1e0ee8813387dbddc2d8a6a8949381f6d5d19cd4d111fcc78cc82134c204265c0260a3443142a6fbda728d2b6ba19eb1f8c87e468749048c9452c25b89f4c065861ecc87b91b5f26c72bd7300254b44c6968edd020539f3d7bd3c4af5bf80e85b6b12387c95d0f587f31357dba76f89c84db06647cf5e9b1950074ae86ec225f2783fc06b5543301d257e821c9b2f0aefc322fecd5e8294ffc4fff3a626f0a455d8f906971ef6077704a3b0c9275e7fa3e66cd3bc4aebe6ba87e545e42bfd9663d9050ad6528a27f6072b39f2616b1610b937f888884fb11a1bef83e44f0e7c3fe5f0377d0415cdaa58e9662dc92333b5d0361a048dc913dc4b603aa1f6ec4b71e677964c5b2359a3eaf6d457e168e1f7c4f5d6f2e96177bd0ab814a038f6ea5a06de663597e6738c026b581a7b4ebecde74f7b84a8bc01c18275b4a4347d9902b84a0280ac7b202317c0831d72129d98e112b6a01bb1396a3d724142ba67352642f840502e6bcdf7a3c3d84d1389628cd5072341e83e58d3f3b2ed7aa04822904ae8eb7aa119c375a57fd3d41f88c94ed420379b47bfd987e23721779368b76fd92e32c05b835f724e20deeeec9e984d4ce9bfd52d61b63dfd73d24e51d6005d63cc8ca34257d84dbd88ff6a97232cfa190f6c7a66b13155ce7a341da5958382af189e3b45a8e884698a7ba4f5345bba4a19460649ee5844734bff46e0114bda1265786bbc8b3c968e32a68373079d3ec5079d2faba3f31b903656d0bae43b855076cbe4e9c597f31dd77a981b8965ec13b453b345dcd665f571a76aa7a8769c2e0ecbb3b7911b3ff0ec8b563be40ed24aac61a794716f950eeac5054568e614335caa170e5045b06ac08da24807cb2cac132576529510041757188a8a2136ef544c75838f7a9852b45242526d1cc1dcba9d375ce332a14719506386cd09a972a11c6f40e31f5bb794feb9b36696087f271707fe6e6f580090775478428aa05a7986fb3bb2f23aca96b34a95d2c7947fe1bedddb527df4f816f6d726aeacfde3ecfb23b05b3f94911adca76e4776269746341daa40ff0f8c26fb8310907cc086a1a3d99b647edb2effa7c59d0f3eb615600a56d3b3c5458df518086f8146a7c8755bd1072038d859bca37b9ac9fd99215beeee2f59237ff2280663c406aca9c7ed87763a9dd618f734a452b9e9438ca40df7b22ea30f32bd1eec2ea006c55fc594b3b7643b46fde5e8776d6a31f1ada8ea45778cd3c39b1bfca7bf7ac1eddfb6430a2d86d5499b84cacb1669973fb82e0edbd39b0fa19909ea012b5d2f17f37b5cddf98a529b205339d58289731526aa11be9339eda449c3e60f229b7ef356c2bea00f0d8a89617acd6ce419dddb5f12c9744c85cd17c1cee5caf69a3e456c274f911706bc6f503418ae97fa8dabfa6a228c82378c1a56ad6e1e225cd73fac1230bc58a365252d6a86462410b2b72be47204d23af3ac8e2b014a28f77aaaed3bad6228ada26d8109c23101e3eb30dd93f219c00102e285d29dc10aad691b860784fd1caaba34f4255b27f746c8fb2b94a34f41dad71dd1c5e18e4b2c3c5fedd3bdad66653a649a3aceac9468de6c08099c70c7d6743e2ee329c50f8bffe17245a1d4dc9079635a3bf0d5035b6be5cf014a713fa578bd631e9a6198fc90159cb9d89aaf7f96afbc1130dc98143db98c58117c7c2e4db218f426cd959ebfe63f40af4d059beb8f715eb4a1e0f5a8981e63991cea7f87b07b29fefff046f38dbf22d53f3a2ca510f3d2d5636779228b5636b9458ce0e79e60a6422e6dea3b6f51bca95dee3a3de8fe877474897bb365c4d14c3b905befe7cea7cbff9dcf25b8c +expected_result = pass +expected_shared_secret = f0691ad2fe875e3f0993f25452c70f0c40891b998deb6a7f7aa3c0bacc59bfce + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +private_key = f76c7d8002b7ca65bfe6a59aa3645a8e51afe5fb80145241134cc072a60ad4b72d80c2bcbe1630eeda661cb62e01b0798203a1a287c4b8f725dd422beee6627c864149ebabd84280739193067a2348f2861dbb7f1a0914ba2bb3ac6c80d5ca1f483c8b86c1cf5a2c3bf8f6728555799381a1b1f3cd02e445cbe798ac0361e15335380051294667b9149f38d85a1839ae43d331bf14091c4accbb24c8e8105a9d1185ba880b7e13cd3563aa235b899e7509525280a37162c043b089d5a0bd48b225ebb2d0538f49c8ac3c3b0677d8093cf70b3404016b4686d653ce4715a85953171bb937f5a1916271ad53318e8155269dba4d0a520d057963e70cc01e680fe8408d03d3275c95a2c528190924749bc32dc31b21b58c6f5e4b59c157cab7653c0d146dec9a3f94e241993b09bd62446f35ad7772279e116464fb316db8449a3ab7525b3e89b12b54f14fb19057c39510b072894831a5747782d404487926ad756b1bf81cb416d94265dcacea475fcdaa727d0b5f01b376250b123f717fbb0b1976b7704fe5ae5ac10cd17b87fa8bbd3d824d3b91b567b5c20243677d741ae2cb1c1d049a842b7f9da9cece8931851bb35776caed97c27d395108e42661aa60cc181abb2774c67773fb29b445f3554d386c87d489d895a43ef268af0c81f6065e57e744f719120323b013d35801e26bac2700968566512106f5161ee8528372d45a42b41022239fb0b3cd23c4251927b355719a1f2a0689a4abc508660dbc282706b765ca4bc1887fd064cf8285b1155863e15b112bcbb1962255b362ce8fa4c51c97cfcea7004daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b86724c1adc3e67d756c1c8647fb4ba32b75a6da3a05a870fc1e12cd279666ca046e064a74625530e742efc72c1d5f959c9d256389c4c63609fa11a8fb5e70e1e2256c8164d80c69fb8f4008a647af7f3ad960265f55cb786e8726b65689a6a751fe045b7d45aecf50605d135a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b225728eb8836ad1f373f66a2134b8b429a8457b600c5a3274b0157f66f091ec88436d5667802a15749b4c9c499a36c58fc5a7ccc10a604ed00de74bbf433502c02ab0ed949f5da8b9efb83c4a2395e49413a7030f4f95901e8aa2716a3ebb09aaf61c9384586021301de0f8c085421460a10fdd176c68b4c115c91dac04121924213855ac22e8c98e3643c3d7c3b6c6c4ca964308510525c5aa00c32ad9ba258bc44a9f521a2873bedaf7c56bfc26a320c0fe95cfbe12c0038c1a65b62c18c37e61a2b9194c9ec1db8b9fd036c7c3a620b5c661d8ab0b46a6cd3391e53218e40cbdb082c2207630c2715541b10e3c395bf2a5a15ae8b506880dde937432ecb150f9b3c136881058a750024d9b247232b7289bd07462c051b7ba599c985c6eb08c7ac22135c99e85930113554c59ac06ae298d5935658f513644b01132b4c1ab84677e342a1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f782784e4b6fbad380c5131fcae11d4ec89df82490b4f1babd4673d7417b9cf04513718f2cd0cfc297071450340f1b110ae53ad21759bb5b8c8e495f55cba315805921485b73a248535ab3519a544f440b03b0b1a667665bf068f165570d9aa52fbc2cefd50738109a2f18011d1b0b37142f24a52843a81c44eccb8b083b8c98a51067197737bd47fb2b40a5a96e385364463cac81348ca44e9b8b2e457701fc0571dcc6645ff724e44b1370fcc235ac9f735b1c85e877dc30a9654006837c5dc318cc11f962837c0f26a59f171b6ee21b0ce02925c280710e140ea46486e68419b11b548d880406e929da097a99f8969840979eb861d483337d605c7e657c024c3315f76440f8437057710cc71817956c8135873ebb9d84b801cac006930443c09773a5f542cdb838e176b45497b97091a613c305e6bb240ee08009e699c6d30d44f4152ec0a1acc16e5310acba766278516470613ce1044e46a4192a145beb3727dcc22f53a98b4c7c414473160d85872f31c76edc5dc2e822a91976761a5d933b8d284082bb85162fab7a7d520ee3889f299956c7639dea77127bd04ba5500feb9077949a8245e4148cc2298c06203871ae8b0a2c3bfa4695c43050870392401315764ff65c9ef0db06b03b5b5582b57e1a7ec6ba4ad832a04e31268a853aaa2227f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f26d0769aec141c0686f750c1f17784cae142b942648655bc8a0acb8247462713a2183223dfb093a737306e94386d878eb8babe7ca066fcda152a0a81a792afc9ec32369101516122782100b24b02d5b8693a712f4711176b348e2aeba7314a3a17d0ce11315412e54a6508937a393897b01d361b1fe9b0b7cce01806a62d12470ad5650606883872a55030827b5bfa8a05fba19c9207f113c99fe5985eb70e88325e5cf35eea9605317579f15b161f55a81b694b0a79b8210b2c77524383aacd1936ad36b43f66fb6b5e668205396b40b3889da25e21fa985bbc6af4980d9fda368507a7659785363c6537f067eeb596f5337640e7b3b1877804f21c14d76d69d01b67a941e76cbbcc3765aefb0a74565470e7320605a0cc009c60e57c9e765d2f835dbbd91482d43b86858bf82161e1c3586290acaba2964f3a9b83352cf40aa26442634ef069e2932a470a59aff725b862b880e7a75fd705ee50624ca368e8c39c27ea0588c8983a453bca30897a5785cce2335ef8cd48217eee4485abd47a0769a0ac99089bea59c4481b18d27c15d92e915285dc62197f4804ea3b3e79bbcbf57671dedb8678f1264b420bfe191f21e489675b7f1479a390d0c8fe2a801f4cbad2f90138259904705f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fca06dcc3b3cd617a3f433174053885f785193c8a70432ac83c37b60cb1ca407f22c7b577f4acea879a8ae700985028aea3475426a3f071cc5162233e793aaf9936dc625a292b84d185ba31f964a4003c3a96701c6ca96305205b5071c3a6540d76c14e969a8061146940907ef20b857245c6f202b8978a23a6c84ceb3de596c10bdabb2732008c6a224de0ad219b9987099f1cea007d1466ab0719e396618014787ca6b1a2680e96a85c949486105bc4357a93a3109422e52a44bccb0c8c1aaca7931973560a82c65d253c02b2171688648a2c9f93f0a26ba58061c8cf64b54f2930a2a4c064cceaa6d34c76ba200c382a1fd1b70119304f278a87a77837856c68a119ca692b8c39782a16ac11cb6c4d9bc7acf335aeeae65f01a50d4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd440c449b8bdd15a3de54a3c1a17a444cb469e0c1cfa347b5173fe6f4749658984ca0530483a86b773471799b9bd53faf04d0a3c07515a3b915964aee1010333127b3aa72ad964f38ea89a4c561e36143eae3003a19cb4de14fe88bc5b4c236ebd1930474718ae654f43277255b1f508721ca318d2d5255db804166d94cf305bcfc6c91465b18f3aa4a64b624bbf395a10967861ccc3d13a17706511c8946ff31954962b9dc68aab370baca922b4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2b526eb4131e48546ee449d8eb7b709e296c028c6d085a3d614b8856a6d076cce23ca4ebc192ecf14954ba06415280275ca743587492e76a5ab5593e9d15b10f829dcf73a94e040d8a25aa29616ac8a88cbb148e1c727b608305841b8f3c63e967843c9a50c43c3366293868f1b1acba037d95b64dd088e07d42f2d218b18eb7eda5a2506cab773444f2383a5e40940e4f26033c336e3c7b5d7d2bbecdb39180c87127781111b318fc4ab8c50926c932a122aa79766a48abab6707710c66030668540cb5c8d87272dac2683ada81dd20aacc3c01df6056cbd23735dda391332c773934e361a1b6e247711a843644226adaab77089a831e37d571517dca952a58c0835705b03187b77e6ac91d426ab21b997905fb658c6b7510ff5e45e446204fe935a7612a364414014483cf1bc844a6935ce351d1e090313a776253386a01073a416b47a943712c0b7afd130fe833041716530c4af95928ebc541961558a707320a5fbbb3c113e8b3c88b0c3b359c13ee24172c8b649b67c645e07400cebc486383d8ea2afdde8c104e69dab368f092ab3b3b85fb70c3036fa5925301430d17603902b1373258b206b814bcef5a2588981339cb725a5f38a079935f6a27578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1a5383897314d60ae0ab1a8b50d6f5de454a2eb8b0502d57001e6e19223a82ef2b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 8a8fc2dfe41f13693c76063bf85b294dcc5af350562458d60a351a5928019ce73d03bbda5798bcbc45ecf04170b4410963babb74230972491fa66480de29f461a97fafe6506905d447f426d7b32e24e71da2abbb27dd73f2eaaa73eb40314cf15f6892f43993793c36bab7bcdc4e3da3276d3073fe3deb01cd15fd8d1470e7181fcaebb5f57239a6fd9bc5ab0ff7623d7c601a3b45eb01162ceb7aed1242766c7ab7c0662c59b6bbbb3cc4f4c061e2c8f6dd305deeb66860eebf38f45509b335707349696c8a694b270b68dbc23bb8d60a00f515f70ec312f06ee0dddd7a4b05608f9e0a1e80e8336104736b1a38a01e311bbd09ed5ed1d885a18917c4891d55e050bd4d85619013190efbc88d9e6b09d1a5a8a1d81e9259b5ba2d2cb549f8722561ff0e6367067149ca18963c0e55adb6bca560e60d1947e60eab78441f8ef7a1137eabc54d4dc9e96ccf97868a3242ea9a063ce5b5b252d286eb4fc80c8503af57455760f5a44e55342df303ded8be48c039d617a7b88ccaa5b4d5ca22474501ceccb97e5c7ece676cabcab5e46de64ea9b5390ee916eb2cc756dea0021d14076e8024fd3006b7e231903a90f53b46730577a48d35ec3a37ca3b974944b7fe89de8216f774fc628c0f4c61fc4b90162278d37a1e7287f9181635631538c918ee9863b3224b6a9431e57640b777f7531ede094a6a2e386faf6ecb5a6933c1645d95ff4cf5fbacd89cf586d328b8219fd7097fe5777e7f0ac995d477867211de7648c353afe888878a8e461069e10a7c67b3eb295ba0f64535a8b7b0b98f71603475446a041eca8820ff5c9b920ccd397a732432c6a052d2557fef2f9556f4029da850ad7b8cf24e9ec42b00169631f839819c2b135b9796bf8bb107475745197b7c6c449ca662370db8f5f6ce94917ad9c16f36b10660945e27981916b497d074551f9d60a2a43b04cd2ca94de6e1f31a7924fab79c513579d6ef24c3decb978883ef99b349cb647766d4ca40302443bc0be7b7249819fd5b025ad7decf8f531efb47f3eefdf900cdf8fc2798e244da56853a22264d725f5918d197711ebeb084156202d795effc7f769022eb6c62bbe51fff8d636a813cceec56f1495121fc6f3d295af840189b56b8a5b9a7abebc6acee6319d6c2ffbc68e9803573a8046290d1c9f969900a129caf952d8efbc0c7613d11b956181f1b3ac3882c561125af9eba69ea4aafb613258c413faf12302135816ec7626415418ff1053555b5dc26f8f4777a5a8e536f740f041a8fc9a9cffd8bb2932d11a3a5be865671faf54f54060901b00238a0e193a94c9ece9dabeb902e834c8b5f457ab1739059b7366b8b4ccb83b3365aa85df3961e7cf2ff37fbf44a2ea0919f7c4d9d7ff9fa817ce33eb4b15f6f1a6b630c37f6ada9e7bdbe98c49ba7d5a706aa948ec1521f64efedb6066d10bc2033e926e892dae1cb9902b8f1de72016bb02d7faac33d4e62d1200a2c72a24d5acefcd2ed4af194080f587b70a0e68e6a5dcd676d92371f0fa810fd0560d69a802d4078edc9a086d87380ba4adebb29f6a4b1765f7fd7228ab5acba0b8a0a0263c47b9d8e6e01f9f8e4d9442ed720c41879ad8d9eb76e8d41ee2b9ce6d7575395dbdf8e01d9083a59b19eb7bbc34593dba21dec635d197546427f4b0b771458710fe4407b9ed53c5061b584d0c371ccb1e18d6e32b87b496d1834825c311d06fa8eee65e396252e0a17130a9c7e3b69831860bbe0920e6adc2005c8916d1776ae8f9d41d8ab0ea4a0d4573494be6df4c7c60764e8d0218a59a7ed2e6b98e46d6e6cb2fc273ffb1759632af9d23d8255783db57470cd85b133c174e922fe73b696c537ccc69da7b8fede851f904b6720ed90929e463d1ff6d6a0038829a82a99defb0cfe0f2d2fcfbaa9fd7141443d12689c6a5dd400aa493f3bd6d14f0471c157d63e125495204ab788dea1b24d824e08c3b62a8be038c0129b136e1697aae78c5c83d94abe07971538eafe93f48cc73e53f0f887fdf4c80fcf786c45bad0d09f4b70d06d7fb811c51ee0569af07f4e92779572882eaa75f5605eda9573eab68944cd5fb664299118109eadbd912f28d981a149b2fc6bab1b03a0ba4cc87f4ede29d56be67859c27404a622f60f7f3632f9746be3b76dfafe4a2858d1eec3ec15fbf3dcac42a97bec2341368e33eb8eea5e7b6571d0aa3accecca45 +expected_result = pass +expected_shared_secret = bec215c6bb33e83574319c839db1ca6793931d35a7239bf4ad3c4a493fe5c5ea + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +private_key = ab150a2298917b1707af1ac0941acc5b6b259d1aae8f878bb0a37089b845991b203ee4c8f1a58cf9d2cc0059ade2db131bdc5fe3049e17f350a805c6f30479be91b12a36190a5332eca4737df5a32fd60cce222b592060add75a62f88d5bf6426fb18a944195f1ecb1babac1dcf20c39339ed45ac8c3ab582382480851107683102fa1914e753731964fdff686f0a354703858c15c99f30a19d9c281ae93004c718d1ca5452fe58183d806dd666792da7a76b0927dc77793396e4508200ef5097e45095a33af5683a4dd1a5f6878c1e6fa85771a990ea16f7a28034a897855769db8e4a9a425860fec7031d09e96b665f57662b2bb86e362c3f9a706e354c12423ac6cdc74973a0767d73e75f5739747433c3451f8e5b85e5311b6e009f79c00cc07ba26b74d512520496b1998a4445c19249729225044cffd51679b495511223417b2bac86cc242241f2b70966e9a7a03c3cc0ab526abf857dc1a140ad85825757d2b5a59b97b7f8c5015da02159d013c1f15491ff4cf64c564e50c389f6c85b7c060f98011a4518cd3b48c2df68c67f3497f439c11f8504e577cf49acfae704a2b093238520292602cc2138762d87536f6285c001d6975a242654ddecb5663ac44228bbe5bd58d9b90426c66802b466b21dc8d7a23893a953033874d0a93626c00b6a4fa3fe9eb0dfeba2f3e789aad8103ca153fbd7218b95547de700ca526aed4f159639c59a7699296486188c3ca111479ddaa747f99ac825c7593911d6261683ce92ee8aabb77f82ab14838db54149194b12791c4991181c66bcf05c67e19f05dcb658d8dfab09c180967311f4e2aa03d9b8218889f87c5a5680299a7459afdd69db27302d9761daa20be37900b971694d3b6aea8c6b5d53a686beaa478f2abc17c1c461807597148719925590c1e482aa05bb73077c017c1010ea576bfb5a63031875a23b0a019d608d64a30d0dcb39d750099d1c7583c34ab1cb1dd99a115547e3e4ccdf2a872e821b2330a5f6b30918226b7fcfc9fb4f37d8103437db12ee073a49d29a7359316f8d922f783797e49b8c2b6146f76c7f8a66838c86364a788d3c4ae67d02ca09391e8547edfe86ca1d131c5b96caf479d9562688d1238c6196526b17844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d04810311a28880247236a3761236b068a9a4edf55317e8841218441eb1137342977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e41531204bc0df8243f81367f4d979bf0125b84eb5d5df53318463102938a85214ad7355960300db40719a2acab9297381a6708391c78a8d4029487c324291a7e4a0945a806e0f24368c7a2af91b8bb155d04c557759228673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357be9227f9c4ce8b98003452c1d8d19c7a8332403a41308086346129d3f929b847bab1aa5d88935d816a708c6a5e41023bcd4252569cbc724a53df1b88909267a932186c751339863c8dd49cbe200797186924c26edb976de613cc2c46beb06b39f5c264716a76e67831e4198822d77386592c777a0846f9b278064656903bd1f26a8a87832d541541e8a06e5733700836c5f16a06f17ab68b6ba229c9e740765ddca88a01469a79bb44f2a4a55547abec4f74861b83687d69fb0402d6cfb0573e8181929070483e85a9147801ce7b8a707093b2c67a21f1c65222981ed55755025805823908d908a6516488a0b87800034937b582368cad01c99c47c84c2c09d494a6fba19e5275bb27c998c5ec863e01612f3a75951a0fb8790cb5b623b3c089cf40779b6936b632b54b981c7ec83930f7cafccbc365376a3fa3c1cdb162b1751ad8eb3b2fa70150b637d1963600b0badd755e3be7486f8cc306d9a05d688227f77514b02dc7d47c93986432c2b58c674a74218d6e9482f8a3b8a6c5798a833d97a65df98b3117203aa566ce46499dfaf56f69310bfe821c16bb794dbabb7068cff6fa3d2cbc376bf1c4e06ab2e4a73256a618d9236810642c1d1bb3c13ac300f20eacf79d1ef347a38084dc222bb8741849c2b038d9721ae56a5300be8b9b4ba70c530593a5816309ad50420d63a7bdd0375b9475c17c04d8c082f06a8d497768755ca932d2663637b2641c34a379ad8faa55c15246fc5a13a3963d4d36a1a1e06bb811c736e10301d96181207f65e992a66b7b3d1921c7f7247f34bf3951cadbaca9e346bde27887b61ab58fbbb3cd25466b3684b48223b24c34c6f1ce5aec8513717cbe5a0059352e4ac62eeb157a0ef76936c16db808572cf93adcf5bb44b1935d43abfca1b06d375f4d5a4d2a40392023a86e05796565abaa806d9ba0273e543ab03809c4fbc74fe4156bb2b60c76be49c7a1d5d45410627a85026a58152e2833b445a087a4f011befb1e03b7102ea4b17d6b5c4e3791f9c2babcf2471d86c720d412342529728cb560828c7286035e612698632cc054079ad2b53517b4c953969d8bafbdd0c09845191ab426c23a8b469b601c8751b02a4af32b670e6592f2e5b943924853e551bd80c5e717405eb2480da7a6ffab19660cbb5956546bc64def60b800c252d76c96d2fb3d22736143b144953a410653334c8967a367284e2197f5864c5e811721a49c29ca0e43e9aff5a7264381bdd5c4af51c51b66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7ed026efeb5b271324bc71bd73d09d923182fb7739405159d51ab7e51a0765c56d98d50fda35546bd762c21204f5661a72aa3a731a0520409c62154cf54243a32914a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6b917d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b1551d4ff31d11435a97a61c0f4430757c70a4d73402d94338765c8f708502774d36ac34cf85af4683ab5b36c61b04064705c68b578f7dfc4b9886140d28335e78c3b5ac7ed5bbc3dd6ab0a76a97858257c519cb57f0c949c2818c43962cc24695c5b3a6242908f20e14239930a9b8fee51bf5e62822f42095f37299316479c9371bcb567cd5cc138828ba5036799714dec18047c84aea562d67e375ce697536443ae087a5787a8de6314a30e81aea1312f3fa12bed1ce1fba8e637009bb7998d41a6654d70b2f9436f6737c9d118de76ccd885b4b0f3751990b93138a70acc047e4416fb2e21bf2359ab022696e67b6ac6b8045f3c826b81b76c4589a687e42d909ee5473512a71b6369d22877ab0f91a7cc2c01533635d896b6bd293f85962f05a2bf14315e42582188bb09f2c3cc86632f636adde80817c0681a3c8c313a65ad918cb12582ad1d76ab42643efa7ae8d94a4721b1f4bf77e8e47af68642112ab9629e0a2e3316d6185668ba373db4708add91ed47a5044eba47c346b7d230d4b324b30c6193184b493d111fd8362812b5fd1e19d4978672c505bdf9a2f888469faa040a4b3c5648929abaa66ec435d3173519b882ddd7474b1210368711c301961f4855a49f75656d356930c79ae11983a32a17d4757ce42a2d9e26f6a77475c12056a5378abf7c7cf097a7fb23badc4ae929a5d1eb46af442956a370d7f9a635926859e6099d2b121a807c107cc15ab18ae4634834c22144f689e92000829a4a9793ca767e43d707bcb2e0118e810b32f14007231721a5a1f1621991b556b70389bc8652b56d824e070a5f9552de88b14df346d43b460807662263769ddc268a78cbf4c155e46484c8e02087aa6493ce73b845289e9499d0dfc1b156621683521dad7176de52bc294770ca02ee08899b79673f562c5ec68157c758d4726cecb986c1355444d96402bdc20a620128ad3c9407a64537ca855f820c7166800839e32b5a0b9404ec4f375c68336c2c098ebaba5d1865a99a8b45993533b0651ef97477660c48ef40ea7261bcf9c43bfcc740a0605765c5cd84cc5640c92e533a2ec923a1512ba57d11924542f53329598598a0717aa91986901046db1c763f25098103b208933085b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3cabc04b7f7ca57072216c859e73183288c8fae0a71b98a2366a99f276c0b68688759e6b34d51a0f5fca2c52585894a5ee52253d6f963ebd1283431b6d681065426a19157a6384b27bbb0495cb8a4f42c5649f185601b4a19511841e775868c0ef0e010a8147a743285ea16a6f01323a9acb46c1418418c0b94793617db9fcc1039b0060c167052b3766e9452b65f4789d9123e5e299c0e440986013226b63db7c78109622eeb8880c351c6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273500dd7b94b28b5b650d90962962bb9a3ae96e70d35723217f3f178cbe565905124c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = cfa709be046d7a5089bc89acbe7cf9c0d995018315a1da69f28fa50534d3a66033bd7f3ba72dc7cf4a59c5af2004c5c84847f4ba0703bbeb0838b566072697cbc4f83519dcc80d4dc57af1d4287303f0e1eeecfb571dceb8960be0db46e84feb6418af8d5232751d46ea9e807464c5c046457c90a2c966fca923a849b247b0e597b04984ca27719fc8de2e7a88884c7bfd904211c691318fba488f0167c3ce3fb3f09a576e0e615d9c4025fabcd87f2fc381937bf5e5767c929b489957c4c902aed8ffa04a4151ef4f7b1fc24892b8417fa768c5c4caf89c1d7a4e2c0281aee2deaf5eb36f1a5151102246957f2d5b5a0f84490a7da013a4ba455337300376be4745a212e190a8319486dba5a491798ff284c7559d5ef4c22f11149688eaed6cd5b03e64982e928349a85a8b10e9c0e8d919877964faf74bccd45c9b8358dc06904642496d5b1723f44871beb9d22c20fe44f4f522e69cb69a8c2a4d02c813add14c7f3a9b813654343a091b59df148fa2331730e2b1bd620f8c4d2d7cf5cf2f179b4e7536e79673f75f26fb97f641dc11697ffa3470e7a51f2595d25534d0d8fc2951e566b825bde2a2fa95ce89160a245c779aecbe727c37124d7b4047f7a33143d89c36bc1a8d6f81ce89c11dcba1eefbf5d9cf516e96a4cb1fceb8c32b2783130d4744066a39a0e0c4f1a63fbc1da236a9b477b6a3602da150e02f0b904524ee76e427546e0b4c784f16eef19d2b36779db24b87878b8bfcd17244a30d6028b8aa0e2311d48efae841d37e4ffa0f7d3f2b68a81dc91ca5d4414a3c368be4e05b10bb932c2f7a5fd656ddc67e51e7b3b719f9ea25e3ac18ee56c53e00647c57a8f7b7a9ebe219ac62e0ead2c51e6f0b8e96803dbcdd1c45a7f8fca47b72fcd948c12d1e2a54e2c89f9d3f8fc9d5869e354693229a1a2f01bb36f4ccac457acc170f89fc02727c11aa053c2bdb810d8f4806caf8228b0bf6024fbf16b4c7ba3335a2e1b900db84b612f3f1ab4cb94ec7f9123468b282c02502901258b00e7bec13b8cb7548ac4eea609aa2bcfebb88e362ecd6bd971ff280ebe52dad8eccd2ffc148b7a39c572635fec41b1d4ed932701384c749874f6a53bd975901e17a1a8d371f105a0f7c61980e872e8c9b653b47031dfc70b255cacae5753e479f4ea2a6f7760af10a5c3c98c4bca1b9c3bc255a65d10a5a9d2094bd7ca335d43ae0cc5f9e2b401089fd05dd71fda89a860190924f47f79b22dcb5a9014824cac41cdd1b3ddce29aea4501bf061b95a0deec5f11cd2651091154b9ac5cd594f259727a277b24b5e5f560c63c21fded496ea84f4c808787ec84190ea23aeaa651d2cfb728dce2200b7239eeb48e2efde5d21077ce14afa47f3da8669cdda62ced1ea7fa0d200854a70c5b016b7258ed36216601d716937feb112c4b9f90527caedb744be654e3485bbb0854458722271f6bac03689c5792e0e2903f1985b27aaf8d0fcf32f10a18112978daac5b4b94e6ade015a23e0873a2dd18faa90606486d8d8884c2d4ec96ae81d895d39e40df7563c625b3b2a2d9bfba74f049e5a6fb237988782eeffd223805904f9e90b7cf65bce60f3a85d635c85156c4f7797cc9373b37e21f45f99624932c1073a2c7af131b6476e1acef410900bb9228ebb6fea2f2a912a2a8fceb80d2c5cfd6455ae7c6ea1b8c41a27eac6e83c565f9ec5096d505b0500ecd51873adc56186f9d16c8ca63d852d65b766d41dc433a63528b2809890f085cef8f6df26bf378b90d60fb01cf27c4bfd7401e2b923de0987fa04580169243c4509175f7798b901cac5a1818a43e4e70846c6d9de333b730b875cfd7b756237b87ce7f1b50414064ca6be999620d90a056f0f7587bb9403256b33751b0ce948e294fd4d7bc1c852a3386614e20e9e9257d318b065668a4893494038979593db9e5b9497ea660e073c0b1627c3bdee1b81824e6e814718974ec3b45a693fd1c10069a7087eea71482c47ccb01a2e017235c78edf0bf9258e534b1e47b1ab84cc120f83b8c8fe3b56964b28f9ffc9b654869e4ccd65329749db82334eca6e83d330480120a1c3d41d20181ae60001c6d5bf9037805fd5cb45d5daa5407fbfca5ec89a02cdd7ce5f0a86b7ad9b7f0966bba8975d291c06080d3d648466601d4af6e03435b45da8158bbee2271ce4d092f59515f40bb58d081abe51ab8fda4404b +expected_result = pass +expected_shared_secret = 18a505a0543800a93ab6e2fc1d866e22337fc8387d32541008ff82a73ce7dd31 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +private_key = f80c63dd6cbda93b6cee719fbad6bdbe1a03f18b3379306ace5625fb38c5edac9c8c94525c85961e14a76082bbd760ccf9b5ac777088b0cc80e0304fbcfc697cfb13dcf1cf777325eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd2f07c76e8b7a68b92abc870b56202f7634b9b37902d39bca04653fad9a0e4f0be548abb97c7a1fa18c34cebbae3987f4b3c52a5006629159ac6875276053908b389d931bc7e2871751169b6d81c8d8b5f52854a3e644c5c504675d688ba030e9e78a79e7788522516ffda2ec9946aa9791a634b6ab6d04456003acf348bdcd859567a74a7b73556820f8dfc12e467ae2fd11025e430114a5a60d3b42bb43845721637a69596eb953ab7b3e3b28b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e8552bf7135698e15b8d99b0777a0a5af1b7dafc172aa6a4d69202f10351603771876c580a7d24479db0d804b6513a09281f291f2706ab128905663aecb0bb31a41046771449d12c335051a2eb50ca81ace90940a8a6a355b21a9c7505491ea3b48b5323cc567ead909fbdb380fd504c851452bd34f0f65a39ac62d922a3c50a8566edab03358745d701332e4011022bfd4839ae7b6745c66aca80abab8213369e299253b40a7922df02ab70f9723baccb1ad563ad20c5eb8a01ae564be24f40ce91a0f06ec68c0604c74250909d317f8968947a12ea297a279821f1b5377b02653d66897aa526cf51553c268481f7174bd9495da4b0305650358a637a5fc31c99ba7ba304c6811b555e4b1c2f80eb4223c54032d16238861fb650bcba24b127026fba51f5985476103fe1375b94007a06bc2ab048bcb4a78e6d3c748b141be410992733630b8c917f89960273740a595071824a9d02908d52d334373e8a575d5d52e96e5ad0cc95bf2c761ae577b9ef6bead33103e5033e0765d748c409f8a44227b8f55838b38695c5e132f2cb9bfdd7cb8522906e9bc03dda468a04012277417869277e2169c63112e6a8942a1c13aee97300ff4caabf862058b6e7cc16f34c79ba200853701a98d630936a8a595098c8b19820ac91f47451e011069aa688bfbf5ac4ee018c53639a1b0573c8a420c4619166b011e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fb70d52b3ca5d01729935bf7e4bb984576f2acb7466c8248f975bad539b2260568dfa34cf2974d83699761c95405943a7a88374112f8ae79b4d244bf2d683f7cc7a533229bbd8b5e822c8b3449548634ff34bcaeff25a41aa84a1fa1f52f486f89630a7730e4f81ad23c14d6906816a849810951727042ed0782ef26c31281c0aade6c9334a88acb917b781c4f16327196422c24541065b5e80f4374da0853d478625a68f728a20c1c82ca4fcc4d62744fa658059141221a917d6121187d3b621179aa8f7b7cd0904e6e0787f9a5f65eaa78011b6b63290a55542c80a4bfad64677467dd1b12785e6bfbc31c1f3d46db55c0a035604ef658279db3232c675bc0bc97717ca3eb71d4f44caaf1b07bddc90ae982886594f98c41ae7481562cb63d0b2539eec589146735490a4a87b6ec5cc77bfc0810627aa3452cb061a1648ec7cbb4937826602185a7f5b9306d822633e2b7d35a39c135ca5c1c5c1bc80ba25eb91cd6a3d71341cb1314deb05a164d31123b0a6c5cc7ededc1301154e875493ff173d74880afb7438c44085bccb29095ba859a4cb2d77bda5d61fd9600d1b9c45592682bf161713c80d0aba348ee8bbf370bd4b1a50e6723b9b2499030a0eea58a6531579f8b110c7eba4ca3a57a5b6a5ad511f896a9f78a62908cc0fe0a0c06e652240f34d1e16ba51b41ae7077c3e982608216842c499a51ccc4365a864060f4d2b854232b56d803cb91c7fdd830a50cb2ae465c91416bcb09190be99c56f870c065c7bcf4b421718c17f3394a3684cb0bb83473927b3a1b4f8334851861044305137746ab39650949c8cd43839fa75b0a78c14d65b2d9139175f9756ce3865db6c77467b086c4826921047d13caac87a61e2d6b6a6a8cb67d18a0e910dec05aa5c3525ec86a2ed7c24c0e520b44a5c94940ae8d17f6b175642cb49640bc3254957c1e2501cd5017d3c297137a59cc06b69a861bdb73a0c739733dbbc5dd91628d85b56054ad4251def874aa0051ea234b544d7a0dfa60b1d5bb60b8bc95220c6cc96ab6ed53eea9c7cd1715e9c29291a361b04f205cb094ff888642827aa19c64893685ffc004b6ed9516f6638b9bbac94404f91c29a4d5ac6a9615179798cf6c486333a7641846cb49c6b78425aea240cd5f98ffaa826aa3b7b643a0c5f4c3ab4c21ea9081e9439445c98277b9a507bbcbb82d31aced3c378b017f7d62270749bc1901ee53c72953576125574dea727080a659bca4f007b6cf7c9cb2d0254ba9a293290c493654d25e7ac0cd88a6101b12622ba2627000de87d88e4990ccb9cf4a08918d044c2d52cf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348ae706f400a28f0b1c9f8a40d8be14fecc0b2f282ca8f5c499f2a3d16bb7501003d22965b7e33826d343f72a501e0b219bf868b3e47bd4fbcba0d6635421189c17c32479aa5fb0abc84549f878490bfcac6934a6393a0a14874a878d65aacfa3678704919240d31e9911fb703dd339684d5ae6090bd3478578f7a60d1d72da9d70eca9266b19c79115322e626ba64d52d26c9a655f1325aa63881e8800e16382a46865ac2cf015abe3a420ecef1290e5a2836500176d7b6d54868ae3a977cc26a40a2c20ec3b346c0a4b81549d274a7bc6b446d6a42512c55b9823d745402a630065297973b99b569952aa9a66b440430d980bf4944cd66513220f13964a30e86f738a0eb1aec491908d2c07a35591a384d0e560af91c1f7910b2d3f61e69234375b9b6cc017891eca65b83332df15773baa489862494435538db956d9c09660499d7e343c7d68fe082997b73b69705b9498ac9cd989efce26f4aa2b3d5e7b445e4132185a4e734175ee4b5b7cab33e42ca33096755473d774c758b3ab1b7687d62351c3c5251653953701c81e2cb2667c885e75c814f375eb946adef027f78036b28f4151f1c799fc1556de38bfb2ba996db3e3e70b79be2614b073cbd150c04313013ab88c477297ee615fba0a9e00a50ee3b0f66498ba09acf338b7342b8670c31428f4a52ccf9b4b6dc98667ba43792863661738e63653c34b9147b60ebb21ce89291891bb814096d662806d1d012481b922b9c2fefe9a66b919823970be95bb12c6619498228bec78db0739a5b1c93654a2aad73851355a0485a52c3896c3527964e88727c3805eec01a65cca1fec8466aa44bbac56e53895251892b6355c5e39953f680683ff72e0968867b536c11a33470f8ac74870d996557981711e5d0abc65c671f423ee4b67771055952b54df8934f0b6980779abe207c4f8ce1cf17bbbd90b24d1ff875109366a4270202036a0796146cc8ba70712f98b042b301c5143a6143e01b79b2af3a944100eba87da1725743c370d85894892469c00a95f3866726138c2099b9b6c47ce9b9630222c7656623260d8500b4d7752b6779af5b5b858016057f545175f61477476e3a02aca3d1485e0882b305c9f956908da84ebd8083ed26b8b2b8b50a347a4cda722bdc6ffc2b9043491da64b0fd0a39b7f1550186a0038e07598d6887e6c8c2800288b1c9a45a66233049d77d912b1fb50fc119b0b7455c8d90a3edcb046f2064d401c8f108b833caaae5573a10b9fd1775ab90226d8a32088ac614e9b20737c88dda963d0e77c7c592179b4030881987421a886ac7a422c98b6d51c53d8c1027c84881491994cc84e9b1185b3425758bbb1e305a1103ff6989c633a5697a97e5dcb94e7191d9a47330ecc60acf85083559d507a77f7033965a0859fd6306d27c0ed2b35e7b3444d957a52010ac49a8851952f6061ad551b7c74814606510a0bd19d9ee7998310c74ef507902cc71103134a411f90da122fe72fd14448dea00932977c0f27628f092da3ac07d901c2c3613d22d48ad6376ac1d008c7d19a31623ebc616e4fc3887d68c033bc3ec0e5840d415f6fd2c15355c223da1c45289315cc945aa39ae7498767eb3a6692b2a0ca6e7bc73a5d97644703aba392b5d386849f91bcc7f5691f295a267ac0c1fb84e5e31c94ab020e351ae410840e4198e417b8f397aa33f88114030b07d5c702c6ab64bb7df7276f593ab3d133232c919dbd06b6df756258b25c7132bf03c62077084ce937ce829b0172810b92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b143c4467b507971523509bf97d2bdd733ad9eb94f312e4226d036e8fe827a205333afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 9d9882a27b742d5b881f0d90337a252784a2b4cdf03ea7d09f4fd8826f3bf67daef9c48e0620cfe84925520467c308de3699719b08e551d463ee7d2bb5d1379fcafd75912c5b64008703fb7eed7303e195f476143b3a6723c14ce95af85df17462f123325a2ba206a680edcfe4c5d1ba1f7d6849b59d1a95561f12cece6f7b39dc6b1e9f9f42e56e9544ebd21f82b0254eb66de5210b9ef3bf00bd90a19f26462f4750c5d67ba46fe11e03cf2490963ed6e7f3646ed23898d1e87683e0252e253c3c3c2d767f66c0005ef9fc05eb66a8984725310e03de86edd931a74f7b0fc31b34a1019fa8c25eb5c9d20e4847d8fd3914547e2d9e6e58d2ec10d0d3ef5f6a00622568148bc0d61157d3e04108625c0a00330fb1911f6631a1336730caba6d3fe420e364c6048abdc83998b28c43e168b61c32e23f0df46bc980a915ca09e8425d9bbc201af25f2bdaee38b49123bf71560c32c0b033e1568aea57462c31fc37879314674382aca847be3d60514124700b07b0e86ae457cbde316629347b56307f2d627d6a28b5c4b1056d9f1f677d1658cb4c04f4f4e7afcf514c84d7ee8d0671ef7f502579435c100cbd96af496bd2637f8368f0013ce974ac519a32970ca0225053eb8b62ea4de0c37d443241e537903777d476f6f5055db5fec5c867e334d2c95be5aac9eda6e7309f9b96059174a73bb0d623d583d7fc47741410d6edcfa0068cbc60ada07c34539a6c00970f86e571fd2535704dc96a9067a902c0087020ebdb815dec49ff645543fb593e66a697297db587835920a519dfe468a0c397f52b7973a26e6705d88346c9937d022a9dd2f2f661aa609a6ca388ecf101a52125a63a1c031fba8f9833db93cb6e18e9aaf77055af81c9bb66fccd5c6cded6c0f191a6ca576c3960f2fe3b8bac77a8683e7fe27e7018852ddfced60d09ea52313517e2844ea2b034beae96560a3ea184145c6c30737020b0aa9f0a82c6a09abd789c9e29606fa1b92ed9b535bad8d8b19b760edad4fb755e56e6ee48fe7e955a176ef4954e619f93ccdf800f6931179df4879d397d9286933d61f377262a732caada2ce3bace41738cb2b939a73b0e16a6bb6563a7204fe8cd1583935fe6f6eaeac1aec99ba155005057de028a6f18a91ddbea4f3aa1eeb52842715b8196463fb082e523e3bcc21622f087dceb6dbcd9a13dab218c88826a79cfdfbd76147de5ed1337a851690e6e3b5ba8c994d172692d4ac72e432c0a0d50e2cbd59d11c193b169a6754d66e8d855b89b0157bbddf8faedb0192b2faa665981ef8c767312bcd8b2414f0774383949db885e68a79ad88191ded52bc0eb175b987ce5b0997703e31c3f69bdd7dec2aa3b813784bbec923550b8bc3ee8267190b539203aa07c1000d7f0e1f5fae0d1d0e5b93df78d2877b6c94a2acb676441e65c709ede336575ded7aa9189997468b5c79f12f43aa3eafea5c502b40196ba8ef8126bc24c2911a1afcc531da7c9692ac38f57efc844d44a038dafffac41cfeea24e24c16c475ed6f84972bd89d22d6b23d9e19fdd500f8263e7333eefc061ba764d74a7ba016b7afe7f5b7be45e01d3b6edcdb6ee47f7cef19935f53094cbe532d614cf203241707b361366400886be6d0667f6d601fc675518844549a64de3dd9fd44e553726953527f84e92c726e73c4fd6cac3db7b526b05648600507e599c13ca541767cbd172211547f73793ffcf09c6a7688a694c8431bec47b6169a6a08b124157aaa0bb6640d8d6bf8bbcf8683c652fb270af94ea472fcda30f004ecdf13875f6144701cf768a7fc950f6ea1dd4880fcb538fee5b80160ba89c8f015611ed40b6f08675d03c37dafc1ee0b682b3de7729ada805c4f3c2231f81b023ad5dba9396361835c8b93d094c85c7bf87ac063e4ea3de7567cb767440e0d9c9fb14bcbb3bc8ccf3217811b5c8fa1fdcea680bd555547dafe2544c3874a0555ad8540096d1f5013a663bf4dd1b549ab28c4f6fcb01b854167b8be45fb0460e3339c286b0103179f25bf260be3d911668259ffbf0c062e69f6c2035fada24aacb86222db54b38df9ca621c45e0afaae0c5d89fdae9ffd2f1b4bc0a23ad088e7b6a63c962aebdceb8b1897a277a4853a5285992c3b9b7ebc72a98e787f4ef5b443c58b81c3510db13a3e7c3f5a05112a9ca4ab5eb0b077aa664cf9c119c4f76cbdbc9cc7726d61 +expected_result = pass +expected_shared_secret = f155d993eadba79e6c2376daeb7f935d39286b10615ab42c5803d43f15960a66 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +private_key = d809438c90aea78b897a528534fb009d716de8d513d32168a1537489e52255d00f49c424bf5b5db0e15a3a9b9845eccf287776f9700ff5bb7ab9f40ffeab7f148a9633546846b672cda9ab8a37c8f9711b76474e7975ab7e16675a8626f8648b605066a4fb4a5c255a0a39387b03bb7f618c9ed1b37e488d4b7175b593860f6c97d637a2d8761d3b933291b2ccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cab1bb1cb746ab01293a2b2f2638beb06030d476bcd2c335dd5226b7450f8b5b2b130332dc9210640c10daa5faac16c1381c2a0c4aae3174be4faa53ca9cbf29769084715d6f8c163a0185030b0c7c9621336a9875946fbb73bda9774c07615711451f5594a44313878204c291ab7550aaf981409d4d7cbee727ba689400dab7382605f03873f38566421a354b59a3b48bc8f62a09519d932af5800a9a0c6efd5783bd93483a0aaac7853c890c3ba18835d1a2e8f14bd0768cc7d0b951909825c988648f797f5711fbc654380e661bbc41cf89b088e1410f19669aef65fd817564a4a4f40281b5e16a69be2b503495a4b6b680a08a54fe0b80ae668041aa120c7a363e38aaf2156cee293bfd4396dcc503646acb74b9460142e4476807c058d72c9610e3cbb50a29ed7244419c2c258659b3a8a23e7e69a3047298378424b7a12df3cce34f1364732b292b105eee6a487126815bc0013d66fb7099efd4931e4301d570bcf2facba0b433b9a03147242c298052650416651db690ce81c268381032b17c429a8e418b7e2bb63d30b570da588cbc36dc3798c65f81ef05530b9043310e182e88bb3e58356de408898738c9b3c457faca42b9b81ed7c4118869d5153338ef4260006c6be294b528c779bd6c8ffcb16e2aab439d3032b8ac45216282346200cf1c812033a4f9667af842481d807f92245bb322e04343971a656087cca8ce9bd3117013ae816ba745888a4ad51a167a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b4f2879a727028d4a1c61900d0770f15451a01964366d8a6ad1b5bc520392d43bca270ccf9a72df3d68b955c4bed0352b3f78151c4716512097bc92f2cf0a2560923d01358ab1b5f8b7bc687f5c110b04c6512372f119fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494a01c67e232b93080d5df1542dd59f21760a24747e98e26466280c04d1784d9b581b4cabcac1c3dde1ca8e00588e0732f76b99ec844032d99ef65c8a9ef4a661e78a47b0542b3129e850647862132c208cb9b3986eb5b510ea1854300ee966b0d3bc09922260ffc96b894a181a95a41f1bb3acb2572475b3fe8933fe3902c965678b95512289cfbac30a2b159b8f2b3535e40881d81c204cba9080b9a7b23190965eb660754368955c0c7929e9447b92ac78e7867c1b4770596047fa820c03a11caa3c2ba48120e29ad46c289920222c511c9e18343ab20067f926435c6d6b040955f9394601b805e38a751bc8a1853fc05857eae658a8a7cad729373e73253e7728fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ed82b23f4b6796209d51425e9168cb22224f39f069d4bbbb07a395d3633b71c81a238aa549b107530519119262fe4052cab4215647c0c2ca573efbce84881b45279dbb0845dac9ce5ca807666a76c2a18dc4a39a09234095d426ac769dc4d5584d9473705477c2373bcaec3eb1b911e8f9cdc581c2cd330f0a2ca0f937204323447d2328591761e3c093b8dc35249118015cafcf6bbb98626e43eb12f97b12a1c158cd473bba2b3d2aeba488859d64120a668a6be0f30a6d76211c2576be6a95654621eab6541b65c956bc51e0117306873ede094169a956e50c9f453834a6f5b4f4e7bf3d644284ab2057b653d40479cfb63679e2b50e6975dd839100e1888cc35dbc461a7bc248b5b756d10338cf68c4b8ea281493c9c7fb4d1504ac3478ce8cfa7100cd6411fc74bf054d6932a41d234eff8ba54f72b4ebc52ef605cee08358ad5bab7a0966d8b36b2573387c587196a72be1e47132d6b3bb92241e735b47aba99d28797b6382adb0263d6817dbbb71d46a17c43a63748a3f34873d19497c49515fa8b4ae5c588bdacc234f9a74ae67734d14b7f72bbedf8059fa51188fe16e54b22f88a59ed8a92d72188f1b687222500dbe642699493dc08c97b6a13e640b51f2173cc8a417be58077803627a7c9bb2a7b96e9596e3d96c74f03926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789e02664ee7552ce5b4c3e16af4299c775a4dc322ab9ee16d65a1298294adef821e94a5119e713175b69f03f941f7c56f565439f1e24f663987d65b00bf899495d5c2f178812ee73387a1627f98029344928e5c9100c50f87cb6f99b27e3ec7635c6b132e0b81229807e4d9903a2c5ab8985ddef435fc8462f67a6c01d2188d731412262392acb98fc49e4cbca7acf522a8d385dff01fd02c4be4b878bff659aac05a8fbbcc1565a53cc36af88b41a1a3a18b04c728b1b66a7698be968db6f0bb00f1665088cdd4e3464e34261e72748705b5b7ea5e4c02289365a56739a4ee34a5dbd5509ec297c12a26ed1116929a8eb4793248bb78a1c21d981733ec874eccd2c9b4bb530c4b6b10e136e764af55059da3da93b79076aea089818210bd076e2a8a49a5032405a857baf295e7868bd82c958c90474bc4403e62b85201061b7bb6ac533e96870ad0d7b9f8e6a835e6c6cb4c8437489448a273e576b91ae8062e411593b4c541098185198e49c0790db516adbc2852a220725a5d50d47333ac058325b61325840634140bfb7af0110b34fb408749998df156668634b775965f05aef99713d1f5bdfc5302337b1c041448f5b09af8c5560076ae90ea3d2dbc39bcbc8e9ad26981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc49199c2c35e35d6107ac61744df910c021591d6df53e4358487f26b4d4060958095fe464ca2703394d885625806106ea31173017f4f0594550bab828993d55628aca5955f61f4e4b316a8aa9971c65813949a16828b5792ad841772aa1b85314527ebc2e6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485b8064fc585ab8c2af6212441a763540f7af3d8a8620c6cf40ba81a914ca28a8265248673d731432ec9c70e083be49816098494e6994b385b509397198e2a50c76a8949c25ecc9849ed45d59c966444313d5f0419abc929b8ba51a2a49589978a0e29c680c07b9cab2be0035a06c18d561b9b0e862a2957d5d41a0a63c4be99c1d50f76ce57862b4f61cb42591f17ab1e85c1ca2dac3f746940c001d64d81dd0889629d60727d5a5fd8ab7549b439d66a30316883da6455dc023e6e702fb4742a82a101f60cd8f3a29d3d88c7e418c3d30803a541d6ce1aedfa540371c846c672753a858b39b5880d69b8d525c6d57522bb6530cd7a4edb7730cf720541454cab59595e8a5d6302249300a6fc2180eb31ba43398a2a18adca92af2a686c20454fa8a1864d73c0b91167b6b4730c2b67c55b425e92c663465b7f7a1d2163f7d7a8a08a962fa0149cf2ba8c4066cae7c0a22a989ddea22a5311ee5d895eea9a5416739f810ad5ac901471a72aa78956b5183b194b26c361219401aefdc49b6ab481be838f85290a0d96060d68e5fc71358a924b95225070c6283b401296698310bce2f1b7c8a531e84f625585429ad3394fc04bcd8a200834cbb9c9b9a8c83601fdcaca281a93f47c6e32c133414ce71f32e60fc52b4c07a1402c3932056fc3323ea2241a6484e6a074676996e5962867a61cdffe8811764953004cc9c3697e78ab5d156cb952b1c53ec674781792ac831d6e20b5b29c3b064520fd5968bb351a401646ae3267522c234a8404b02529da182b473051bea4b971b170d03aa378877fa47bb60f1c1e3519110121bd58b17ae373be2d21fc6d7ab2ee2085f4a194fa7717ec83f6c144e256807aa921c32b843aeda0a5cf85773b77efc579a677816cc998970911152d091f21733dd1c0fab31808f2a3a64fa783efc2e4a252b56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277961e67e555cd6c7c4a630fdd897cf61c9c5779594974088a2b415806b520503ebb416481e87a062582a479b3e05b9413aa2c7af59c5a9c5034722f43032f0d6428f8425f4cda38876ac45ba2137fbc56209823b05abbc00aa9e6a307bb164fe0413311f22be44244aee55268da3135ea5996f7cc3f51856610ca68310dfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9369ffbf2275f12c29cbb69f90a8c881721ce39b49dbba550ab93a2c4c94bfc669230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = d461713522c86d1f49f313c57c953ea6c90095c374b53608846b6c9592d574034ae4e08e082094bc82509f773b0b23980c27b18788cbbcad4cb03f292f7dc1b40dbb9f9aac870da48878f7ed31f551e9e0d1bbef739bd15f4f4d4b1ba219764ddc5031399f3b1cc3c40afe779ed6dbe177e47ff0696c76379db79749e608abdb4d8d7570bf26fc7a290061744e2b907b3e356dd503f6f52efc5a216ec851f4f88f65694556716e675a6480d7358de0d1fb3eab5fe13c803dfdfb8932938d1e2814d58bae2eff46bdc2d0032dc31b80fafdc9ecc6ace570da8458b3638bdf79c7f6fa398ba6d9777ace4404e2403f3410d23c79cdf84d32dbc30e255aa6a91062527de340208c0181d5592a8f8942cf07a80dbb1f14a3f800454dc80abcb555878bb1560cfe843f4fb5ce7d56770d4f7a4f36d20ffdbc6626eacb77bb74edd5e8d1d2b6021efb1ce39a41a4ed8f330eaf10c0186454919cf8184241b42b398d8d47208d3ede12d6568ac878398a3144ed985b5637ea55d498ac3de56339ccd50077c6ab899dd34b2020d8f8387938f8486ac586214b024b54b85aa1b1a60bf73bc07a24af056075cf89f5a985349a573a718e66593f470a48484c1f22aead53fcf5fdeb98fd4d3f3627b6be715b367c1549c7724afc6deedfdc825399b5fce1d72ea61b9dc65ddbf385d477bb253ce75f935a4f56f68c6990a3f20239746ea8e7834ec5372932893c3e4fe93f29d28a312354dfbe94167a4dbd80497f0fad7040e6ed69e93c9f04d254d3a3ba3ed743159142c82b99601cee295cc53d9bc48ee8828d1d9ea0f4c0956df9d3945e13ec9a311da1b5c7c6b190dc5d289e6a7b6e924457fac478647d71c9f916ea94365022b3a3e7e0f126bb47395f8311f9367d041a97395fc4825c89538a5fed9bb7d655bbbaf9d92cb8ef37b6ec71f20f0086b9d86d54766e409db6ca94bc3f8f025d5f613002e892238370bbbfefa16f25f7eb6be517c8e2870a2a708fa2aaf6b4f829bde2358aa374bb3557f796626739512e7d6498ed9dc6d4883f2bafc671bce7ba13ed3d0760efe85d465649b4cf641c70acaf845bfba0b0187ae02e68de2f5077140719163f2385b9e17175613f3c740ba8036ff871f1c48504a8c78b4396024325d2e4e062aa900f4a756b5339768d9f6884d3ffd96008454ec582ae8885e2af1fd9b732bcb6d6d4c4a790eb6bcac1b8b6af66650c345516d9b1dceca4841cd7792ca5271ddd4210eefd69e2e47230576e522120f4d768f5f0a3a9db569dd03cc7cf79420d0d414cd2e80569a578cb3ae3c73abec90daa76c5099c2168051a2dadac047b53c53775b99cdc06aeac711e6edf4ec694b4fcf82351a1f4272e460214cc44324cb94d2b63e1c8fbeacff3c7aa7c96aaea387979e802cec66846b697660aff05e09825022b91c94a842e1a6db46672ba9a27af6efd816aee4eedddfc2301bdcd5e359c13eb23e4a3100f3b9f5686c8b24ca570047ea2a8a3999d34615183f48c121ca1e4f8e0ed3bf554d7512fa532ee23dca8c532a6f23520723dfb97c5dec7d00f4e4ecd40a7c9943bf9f5c9f3a544cd9a837f41f346933eeb1d327effc39967ea4e3f35804e4ff10bd298bdf0e3782a64de00725a09aa20c24832f57ac680ab62b0d0bff68764486d0cda4fb56142430df0f123d02f83a70a2ab2abcc1582b8653137784435dfa80283bd8d29accbee3d57192be70ccb4c5e3fcf3fdf5c5dc127352176fcf7c1b614a87ceb0d9ff861d653b798381b87b96ca02fdff075d454d6e95c99edb7d66b89e423274c23abe0b21dcad3cdaa3a7371c1cd6a88cc9694107d5aa3a05431a2df1383f255801b2d7af9f6c3f6023f479fca87fba98e5730f4bc40f0da2c9019dcbef396d3a35ad092311b7368dfc9495e1eff80622eb8f6047213b53e72a712fd3bcd15971cdb61e1ce06f10d0929e7c6d61f8d8a280c27d86d4a9c129d8181befe173197e21d9cf702a04b5cd334f4d698d18d89e48aca65f7b2f459fd0aa9979113a9bc7e7e13ac721b00a1fc55ad7deb81b7aed345d3fd3cecb8434e7a279ed8b255352b142747d365b2fab7b44e0bb6c00bb258d7500ec7c2f9b2e152549f0f90d9aef6707146a662874dfa7c7004140e4b927e820e896847b34e555e98cf49976012b59d027978aab4c1bbc6f3eadb044eed3cb3496429ea295e3d4062ecfb19 +expected_result = pass +expected_shared_secret = 4cc8728603d51b14fca46ebaf01e6b6347ee9c71d192591ee857c206d131886d + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +private_key = ba45541ce7b3de134e6b17030710bcce09bcdba837f23566dbf1928c99cffcb674cab9c41b3151faa3078177b9126c7973e25687452da075965baa804276859b092d9d4095b5e3a27943776da65262511f62a3aa875b258c7929b502ad6cba00e3b38011c943310bb5cb24791a71bc5a2796d6197192d9594936089d88bfe976058ca16c152193838a3d7306b312f8160df15288f9063514a403acb76be298f5c92d65a90a0bcb28a4f438ea447a9c881808a18a2f5c3c1b876b3ae94ed28478fddc1e98a64fd797a0931cc4a18777e5d481d9e92c0cf2b5f5a58635b368cbc8c25dc733550774c0861795939b74e83a23757c212927805663de14a0fa00cf10f51850dbb4cdd7caabd5c09b2818cc0a09a58169e3827969518e8fc7bc8325b45656861a848347a358ef1155e5d43f7910a738a132c8892977075c9a19c1eb6399f2e7bf1dbab593a907bda509ef5b0de35a222fc951a0829a838591a0441294c35ca0b86be6fc02e1ea1b7d4004e5bcbcaa2a280ef37067d72790bb5d59587e050272ddf8b117286fe80c1bbf078e6d259a9b53bd6ff1b43a86b24adb27bbfa3546c179b8f295726ab768bc7fc8dc2a62715030d93581165f1e4a03d42374a31039d55741c9c49a1c807468cc826f0380b90c9c3f319cf1f73811d674b05c147bb2613ba56365ea04872b9244b236b0d480dd0b47b7797a23286269f97450e13791b205c8aa3310b72f3423b263d93ca320ae1ff04fe6e3bb703a6c4fc17dcfb6341aeb485576b53d1cab71d9049dcc68cf86008bdb6152994e70152f96c8ae4a0819102ba5077b26086b2dc6b04b324a31aeccb372cc18976bb9da42c8eba89640149acc544511546c5dd293c3173ef28ca92b85b86188bc6fc09e2725307a2c3802c6086f922cddc62b5989c5a6846496d2bcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a78824aae4322e1a69dbf64336efc3348e414ecab04010b9f7399310253679b48af3c23961bf345b35172c1d472f9a31274c730373a29154a581631a0916a21259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435124101e5d42ff0848bfe2169a49485c094226ec6994cb50ba9f6476fb2a39522a08145b987593f2fe67a2b2ccb036c4e6540145758c6745a389955ce9744cb8030bd85a838a5904198b318a4d265eea61c70e5a34156ba00a53f05c9be7f1ac214f6a75dc8154eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fed709c350a28a34873ce76f0fc7a4237aaea0804e2d3874d726aec41c3ac8e02706da459c01736b7a5e0936b3abccbebf146350ea2a246c225ba897473817f28c8d6bbb55fe98a48de682a91770edb1bdb190a0efd677a7fc29fc62690668924cb5887f4078179aade85c0dc8e3529862b2760b187b7778a56c6b026769e339aca5f8c948801fddc4acc3bcc7ff548dd9fc12cd7a394c24a7cbe18d3d22ae3b48beb295905b217af384393705107f33b02547822b0a2cb1b57b6fc637e071c0fdba2f87f010d0c81c42db454f5c7be69ac0069c33330bc40532248fd0b90a28908f7471fbcc543fa944038186979c1f5cd147b9f69218509c41c41873e0718d35b8c6c775f1f069bd22339d3c440f6caf9fe91e3d6b97d2a546e09ab4f6cbc2f5c1481eeca81c3a77209425ccb6c6427ab580b80350b468d9c0795441555b3bcf75343ed3966f69ca80bc850663776ad8e36fad9023baf84bfc59668e6567ffb6698fd0b0cf9cbe87462e35b9694303a90b2673a62b85c74664d5055cfee3ad39fa83206024299745cb7c683479399e948ac2254117f491ffb3311d69455bb925e7426d24b697ed44995ee73d9632459fd37facd4cc1859b0c6054cf1fc5c02e1ae82c2cf2ed21ea2322e315a196e825c27b2ca1cd0b93b4b9ce8e4aba0d248460814f5a734346a0577d55e0b680f01fab8c9a859385733db6342dbc16dc4ca42777a7dabeaa136f149666239cee53880ac4267a727920a9ca43c93a3e301a9859e01abcea7f8b2bfaa11cd3728c9c0ba4f7c7c89a466ffa3c5f2330a5ae87265a009b33c74d61562ca0132c55b8abe791b2e59ade002808ee2bb5ebabebc314e2d66b66ad566ef98623b721ab48117f3ab234a4bc2e6b80b05f97f10a508b9ab08c0650fe66185f146b0ef5993629b3f7fb646dc248e0690b77557971f02bafef88a9864c28e885562ea7b54dc217c5521146122aef78cb893a99c1c9621a6b51a43117016a7f2231f2380764dd81162a4433d6ca171062704294030d5a3bb9859a983c6b7f009f130444303932f141f506896fbec852a8a6934e72ad8c038319c58abea4c73319df541ce4086a90976356d001cf6479437b64dbb318f7db813d5034840e23910ec67519c93e9648ebd1b70edc3ac24c983ecc4003cf5b130eb251a6199814c715eb54fcc8ba9cd638a294bc2015c8cd7d28736226863a286dd4c0878345d3885cc4b2acc0ae08a277cc23e397dee84ad6ec2b4d73c520910b4eb4ba447071de01311754060195a37eb701045103b59a94d59131faa1b0a99741bf8b186f44c6f66f76695eca6932647e408966f7ac4b0b8af15f1c4fbe27a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be945113013d02197ba78b0f5f8008ac89b28ad829e5fc2516dbced3192242e074cde7c8e2b11ed1192b25db395f09bfdcec8b1a8671975b692c84714ba3049a636494996143212c54058deb770ba709ceb7659868998d6560c8f4386629331f7fe77dc5f5390443865d1215833c78ff2a6e24e3655ce799f62c3b5f24529c051c28347c3c792fdf8700ec3b6559f8bf6646352d2013bcd704bc2b26c0b8a231acafc7675d0e8a0459770f11d04aa0fa79d6062178ea4beed06057444c4b4a76712201937212de48941f868ff3184a9a700756a59e1297a71c3912cdd40e6f883295d0a62904a4be9350edb4483ee6bd20201d253997d983cacc0a4730a4255824ba9e4b7ca7908ce84a2562ba6db8e38b860671e2654f2c9b669ee9646d683e9f907733423d4b139bbda51e785a86a97103d8e14d645064b6e02a3ac6bd56abbad5cb09f1968fd70a84018692c2866af2b85ef8031b7693444cd1a9ca668bffdc9889053980a88bbbe59c883acad0f00dd7ba954c487b585910a10c95f571c245f0b415261fe348714c288220ea84d8bc524e438f43f29a9d42a8ba8138dfcc264182ae8cd7927d0cd0f5da7c2a321914e84f716836e53025e2ca75c8e34b04092752f1b77e9cb872e742aee71dfe2c1ece8c9fe82bcf56131ee0774076cba525934e21ca0387e43d53624caaacc88af2a59e234e24e262a1201582437656f97cfad4a087c622de1563d2a16758875b03ab514291c7d3ebac7e44304c32712af58b079031993ca79e35146723bcbffc96f16c6ab7975151961f1c3c3fff9a9ec5940da90a99bb2cce3f376cc4d9a417fa715892411b649dea698678936c35123e5ee8ad4cfb2a85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8db9a2e14f49581f106ab14779278a6aaa303ceb5ca7c246b5ac13162a9273a9ac00c745fe6f01598575e5348670bb82d8cd04a11a7753fa7729c89196be39ce7d543e24ab509684256e82825277da24b84d8f95517b55c2a301864b9a13ab809cb0ac7ff3047e58b9091c5b55dd0c23cb1964d8b58dfb80aeca479eef16f43ea66e185b6fc263e081458086585b8150b8239a531936e926ba339b79f18461851982ddb2a3069b235b8f15e8d74aed3571cb4a55067e385f3b53549fc4cf02079b8a41626a0aa52c5647ca634a37588402ca812f870abb94e09c2bf31bbb865dbc2a3f197bd7c679ec436f21684d7773de6cc551d370d75cc6217bc8db75431159aa5308570b173c7e90b6b09c16267b0169677610f57580640a536301d6b6b7c58525b6f853a5aa73a05c766f631c0f1c82f6ae54eac6659f2a37fc364b266cb0fbf8601dc5651daa87d79fa1852d950f29441982a71bdbb74d260c6b75630e3e80643676c4d59960a445b86d5508dba0c41f1516f44aa309a799ca626d4ca8b7fc5cd54c623acc96f15841c85cb1265f5ba3f6754b178a281e8106a23b04744ba248c703f0279cfa055dc3c70b8c68e48dcc84cea9d725b4ba5b628d9ac62899a460c157752366c00aac16e281ffe1233e217202fba0e2bb3cc5c170e1e373fda503a1d75af9e7a57ce113706d833ae662429e2774fdc686dec4a6268093743b718d3cafe703d2c27bf7b902dd1482ff611cedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d36945441bbd3f5c241a6d65b510dee6662e2a8f35757b0403dcd375e7a15991a7873c21100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 26b32c1f885f84ee7c603a079aa9b9bfd88cf4a140edbd1c9a76c458c5917e2901dd306f4489539b6512578750a3d1efd7f70c011fcaa9697754039de332d69f39ec075b7fa37380db35e1a549fd188b163aa3927d4f0c222965aaf3d004c89a6765e818edc975a4bd286a44d88d4d2376d89d2ea01ccb0a3aa4645e2058e9e8b059690ce511c0aa292615053f5f5089c8f0b91fd2bc3dd683e1482b0b49dec07c10911c4ae79caded9284fc9a9d3b9126ad0508da57fe10e4c3e0f85052b524ea4b8bc9474256a5e08015d1b23433fde585e29eae84561d2d513efa3dd09a01fe6078e920686e8123fcc0352780bcaefbd7a26e51f85397f99398f27d56a9853c2253d5d057b378009598f57745e9cd9bfad63e3a93cc00946993ebb2ab3856c3a17309a116cd5cf3a94fd18ed35286175036ae66ed022643fe2775b469dc3912d004362f03f1ed6d218880ed206d8024d66bb72246c1b27095bc31d9299acf030dcb8a58f7f71c4c2e1e34a3464458eb516e4c2fa2d819795b12d2c92a56dae7e9e47d16aba8eb6e6c9e044c89a7b18a111464cfa28a634842193f5d6c1a63bb39035630af6d3141b72312273e4aa3b338db926863c98970dd8bc8b936572484c0f3fa52d0cfa3b360e7c57169fffa35fb1bdca24ea32a55b229454d0b57b3088a9b9943c74b5204b86036d36e05da8a6a5a313034205a192aea5c60879a721f9338c10280b9b407d6fab7214e903a3039f59057d7381667127283eac4ae8de0e71a9b6c36037536ecfd0970dad44f51db9b3bdc961ae8ac451f8521cab090541278006549aad938ffd10f522ad149cc952c6e8c119b026672c6564453afe3de708cae3bc07276388e1ca4846c85310a66056146ac055f212be32f5730390375140427d54c781caec84cc85f7fbde7383354aea94d327bc830005f1eb6654b31586660409c237e00bb5a1a740cfe64db97b3211e776576e2e534223357513c8838978a8688ddbc16d9d3f2f8c3d21f32751c26b652ab107ff601a313c9488a336aff6474bd18edbaabf79ecfc6b8f6796d921d75fecbd736001b99cb7324571e7cef3ea13b8e5fa7b609e4df8a8a58b1ec2f1cfb9b5b413456f9b54f36edacd482efd94a7b2b48a64aeea7802a40823335ca5134a07e219a509e96c9f00b521b13ef4e2742bcffb02595daacbc1e1d43b5a8bd6ea35f0a70be84ec944e13ae16aa0a055c46afa180a0e3cf4326143b60a1bcca06045ebd3ca8425b3b13846796f855125c5bd93849480203a915f2221d097cfc1d6cb7d9948265af503b96f53e2c9b41e9a1e95900a882384f819afa1058b1d891f173daaf941fc341f984e77f483f04fffb6dd4cee50b93a289e6fbaf71d2bc36db6692199a47844544cfd3af2d6f9b5be58f9713e6af5c4fd20267fb68f6daf81173cc6d8bb24a46cb201e038610893f9e18170a0514114dfe0f41244283b485f7d1cacd88d3da4f8126b5f95dcccd17e8d90a6ba381bcbc933963efbcfb40ba83a16465e528bf59c2981997327a4f75d33d997e8e38d0429ec0fa9e5e450237b15238fb0c8ea272f684baa71af738d72e412c8ae3a933d709a6f647123d68d6cad188a914aa18ec760224791e1730d5feebd3ff69074498bec4b53fa3d9ce23dbf26f65bfbccce5ed8649f88d659885d0598d980dfe27494f924447340a7718f399c0c676d8a5740def7fe7ca5737e4e9c71f6a0e222c2978ad4ba5c5d5d5f6f5966c08cfab026b0a6091bdf3f5cc3bd77e5c2d91e200bce93bbaeab412d5dd40dfa7db74ea453ec06fa3c0299eefabf6fd9b3b57ee799e6406a266680f98e1d6a8d06ca968cd90a7e5fed2463f6f0a712df964192733915398391fa5590afba1adf5b5ebb8e7a90eef89bf67a19cfc4eb061214244b82672a2033ec48ddfd385211e5dc780014e4be422ea8af9db275f973bec8c8b40b3dd95fc58b200d79765845d297e3fcf15062b0915123aa279bfce802da4b166366f890a4acdd5b066391990d66a2f98b0cde158d144d61e4115caeeb84192bc98e27a832ce3165b0c25a58b8b78be5c3c32278b971abf5b6390e78f30d5638816499e926a6171b45814e17bf73af0acada513cf88b55be51a72148dc8abf01a3763f8f427509795339d80de25d57733b7e7248b6619078c731bfd8d91df790eb4c068676ef21ba472c2b1fe29edf6010c126d59 +expected_result = pass +expected_shared_secret = fe5dab115160a7200005216d7e6e7dd8527f9c2eec34f60c6710ee21f7f91730 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +private_key = 2d80a415a1b29961459e396204e5b5e65540a2a9ae9cd52d867a9e20952fc7565b66151653448353697b09723b17e3b1ef375a3e260a5869b579883fd1eb3a06da5c11e493f4cc9d18381856fb2c36223e7214ad78a178b2153dcde882451776478a4e06b392ce9b9d0310a5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc4568682ec2f5506f59742601c46db34efb9665b5815574518ff677be1c0991b644b5931b112220c6eee10c37c19316156bcbf354fb661635e42f6b26b07f9552d7b1a65d51c7eb6a132034bd755674dfc14345aa72acbb85d4724b2ba14925421e570543ae904f9bc4016bc0389fb9922cb12a393a24df219290dc506e501003c0ae8cbbc685a25a91147265207f93f190b12baebe7cc7edec476553762ea45e48694ddd172b6787b7d9719e89d77563c9c2ccb77caeb23d7aa9181b82b6cba09aef1851235c7986194c8322280b4192b94262fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391a314555674cf415292055bb39319dcaa7b07230204c068028b3ae7a7223df112032d60edd1b6b52ea1ed13b86231a1efb2969a691cef0d219835a44e907bb0cd2ce6da1442af1460f2ab882959e0862bccfcc6e3fc2bdb5eb673b218d6e9c5dc6461d8796945b614c81a68f9cf381d256bc1e63285141814077af5f54c2c6b487dd29cdb1d2ce08f09122d09632ab823cb00d86a57f8933743f347c203894d0043f5692a6e12283abfa1b98b39c6d638132ea4b94644e89a0adc35816be01a408f752b3215029d7661b554bd39abaa906af32f877cd4b28bcc217825ac897d06a4c233462fba602a81321db93279a19bf44131b86035db3c4ca911f1fa30146f9be0333650c3c24a5c85bf5e252413853defb040f8a16f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd5b18df1d947e171272ec5aa1137ccbe50ae73ecc106250c0392a41a73a4861acea19257be33cef406b7eac1796f605a709a4bc06bbe40867966e830e8aac19af626a4642a8447276f09cfba6486564079e1aa38d7e179d9634e3398b743a1812f02818e979b4434a4516c2c77672600d5b7d3bb6d7e3253189c3694120dbe2519c62c80558ac1d522855682962df611febc9f33fa27a0787501a42802863b5cdcc6aa81b964cc2c9b8081b63750a6358db5566a0d3229d2989e98199855a2448f54688ed2487b816f5cd651206350fbbb5cdd995a9db37b089caa57ab0deddc9392ea1c0f99031a42c350cab7b6f54c1e4acdd0e28d7975a188502fef055feb5889bf87929b6006562626335b05edfc544f10cbd927ab3c4c9e806700349b9a0099801d5948cff3bf0977a9691a25ac880d593a36d1e5436eab078bd9a6bf25bc3d6b5bdfa02aab06ab5842c440e40d430aad9311015a8767417b233fa8cfc64914533031ab39b845a3c50ce00ba0f1a586053768ea48293044f3a831b456320600404761c7e826a0b111ae37db49b31bb3e9389bd3e354f08879906996df2036ac49b9c773af5fec5375519ae7b8c61ce475ac544d13a5b421b8a686251b6d1c64f8a353406248b0430c8a3a308b600d0c9506d6509aac9a46093564eaa957b62b0b18078325ab1e847521dca74f5f212b013ab90693c3725729a4888c50533a27a83a436a627a3c1e0be10e35d1900791cc598413a818bc2f58687a502fc5f747ad365dd3348b3f96a9072c521923a513540ac402aabd74a5b364912ec36260235162492ebc96bce5c8a718e124c0669da4d0080117b07680ccfdc79ef10229cb8388460bbe664255513c71bc2243a2cc2a1122218581cc540514ad54365696245cd98ecd445653766847a03794959f15ccced05863e4656bf2571ce6445e9393c95ba11e5de102c358517f7672c0f26a34d8c7bbba5ce9abad9c8b4a6e9788b82bbd399838e4e138c7c1619ca8988a05caacf14a6be164c569444d49911525398d0a460d257e61e6b8e0d2614aa0b55ac0435f34493c298ad719a9900b94abc08acba78f42195637a464fc180013bb081bd7a4a8f66909557e85784780c589aeca24402125b661a068f81d046716e5b5072d754a6878004ac9423092a3e051521caabe98e955c093ad95d74157918960157dd5383702f3adfc65436daccb26429b4e18c04591cef2a49a51f34aa224a4f7e0bdbb1950b5b9bd633a1ceda3c94da93cfce38aa962a45a135a45105c6e2548db96698d581f42ebbb7c4aac8da6805024bbb2b0c45806015db249b4e10f92536495670bbeb0402d0c1be9b01e47a2a77d29cf03647fac3730878c7bddb724f7d8539e31274e20334949a92063634d6c1c0b5a1999460e25259fa91737d2b9a6457588d41041d8d1786ef80ec2951cd0c84bdc57108f02a7aa5297174c7be5a6157693c07a38242f85b79d16260ab37786e67d7d9a77c953b81a2a4b9e01697bf7a714fca3d9904795671d4b99b5ee83765a532624b4004fc6044c1840a4d07d45240251d32fbf922ec329542471037dac809f477fb6ba5b198683443c683cc8494bd1b7bbac7ddfd39f45a10c77433b868c981b7aafbbb2c8f2bc8a6e3134eed7bddd54b9fd1a38dda8a2ad60b4111b10571928c7b55721c527150668a1da383b8606f4e1575ce164dcc911af678a33973c807a159bdc12811b003d68b8edcb12de1614707b555a853290870b5e5b48d7774a9d69a116d13808961164cc0cc38325f49c463e41c043f120af24239c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4554a2ede21cad465be2e3001fc9c955a3b6dca4612d0763299aa8334b28830e996ffb13f7195598c55a704ec9539bcb9a44704c77cc1e9c2a7cd371d46c02a409215333acb076bcb2355acb6c5bec8cb2640c86882342ae3938059a99ae7a281d2b6ade8073d1a90459c04a5db7547b681b007ab996e1a7fd6a030c7b34332854e036b8e99d0369bdaa123a86ab931776e437271a2219af7a4c7b8b78aac0365c78d1de15fae8c4c397c7b6eaa4d02b06f8da7145fab7948b786a78639a4e80299e3c12e5b3847f508c5189d0c735f5841a7f5b34fc7e194f4f20f348475c1d4a3f4e8111c9cc6eb06214c43838b41ccbb6524da5715e5a2644bfaba69b0cbb54935db0379b52668e2b8b84ef5600ef76686bb0651f7c43c1c120e20af9de18aada655d48b375b4a23d21c51e1c3ce9e0131b61c345112b5ca302ca9e183443495da4b309ac898e02c4f70fc7359a57d25778457e70bca8a1c7b444208b00e24da7e0ff89c19190675ab24b605295ba862eb732e4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e08c172467c80ea05262831660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6225b1fee03cfdb599bb024416ca980c8181faf51b421b86f92147e12d04caf335a87fa1dbdb2b0e66c0795cb5f65130adf3bc8ee3bcdff9223cd74ca9c4a8544208b31cbc7a05b21392b0ee03b9abcca42cef8b5448482d8d8013ac221ae01436cab30e1c126f6f80af46baeb4a828f54735b5513c8f11228ec2af7d854d84e3688799ce24c8454e326fd0f52fae773ca5d408568551de89cb85265115092b960ab9792ab8612c012231921b6c697bac6bf53174ac50a6ea2ab3f48b532af51a6f6939d1ba14b694c149b5503f3320f438b731a59b4c22810d1196ed4a90eef2968d1ccd92327b37866abac1c24cf0c2b2228d0e41a3a1ec6a4227a36218b6437b5023e22d43f04b712c2c6665bd2deb160aa95199146618cc1ebefca7691248acb7c549cb66cdd59f5c4c0470205791c742fcaab677f966f746721f58846d1ab2fbc11b6f2978ddd282730402deb863ca1a7e224cccaa2b34f788987520c9da9c0c328cad6dfb46a920bf8ce22f4d265426cbafb31023b7e748252561cd678bb10218d4e5cda45488c4b2c1b2cc73c5c163da9467f02b5ceb4a5ecd136a2b518470719114d1c310a688e46bb80dc38dca1a092d36a3edd7c4c6d37074692e266a0f5fb0501e9791f3f90cdd93386c05c93896b950c7681f0abf8a044ab1227b68210c169b6057528315ca5fab7ab2c9dc7743d8943c997801a01eb2d9a195d2c6a8710fefac2e60702b68523667650e6616cc0b7b5bc50809d1d45e1673be8dc435b7355b0a26728205ae8713be0372cca8169521e574fbd18c37ea3cb6f02aa5c82a5834819254077e1670047997863a5ec7692bc26cacfd8c346290564fb27a50816f2d592277f56167027fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196e92ed698157064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb290261ff6a1d2fabc75feab002d16cdc44bdbdd0967c728ebef0e9814c60b5e57a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = 371298b6907604100b71c9f7170de670bcf388e150f71f83432c040261d09762bbb54b2bb3a9f050e683cbd1965f6421749149efab2ee69368087c9a52b3ae69d9da590f741303cca4fe69d66da0b7b5f1f523c55c6d0ea735abb53ff3055db3475559defc033277a06df8f8190839bf47cf0ba7b5aa80a2d1c81a69b04fc693ad12d694db986232cc539bc1f396dd1c306d9f183cecb93b7da0751dc691881c6f4ad9e02a692dbba4ee7cdbd21c8b62b0c35a41674f3b433304691978ab587eea993919cffddd25ec216e6b84c11d618682beb75d679cedbb58d480e803b2e1ee24228c9165ab864ef495407f99b475cdfbcd0deb672c8945c67ea53c6a53c7a2be2da425a38619d9220f7625abd46318123ddfe2b1fa9b59c0adff0c7aeedee850135a26cc09e9755f05f27f42fedcbe8e1478e9ce945efca92efda7eb28b175995a6f7d7ea75b3527e46d9c9d65d1d76bbcaec4aca8a8a10480b1f3161357082e7e42284d307255c5e479c9e530f6dd1c36279e29c47ec67d65d5ec8b5cdab5a3a53a1007bbee8e285c8440bf938725e34e0486369bf603d0c1fcc59fe6dd2b88ad5381a1e6c683049bcaee96152c00552505919951500f61160b5ab2550cb00fbb9a545e397bb31cb1843312cab077c54e408aebc25b0b14e945724deeeda339fa681fcf6a6129f709bf150b492d155aa06e2bb5120d58821794a4ff564282cc2f10574e246eb6531facc1d1bf4efa3b149fc773ec6997dabb4c726d81b357a152e722f3d9c1559f92fef95ddebb7367d650fb3010aa100413e7a38ae91e4af4d9620a63674e0f6eda1fffa7cf3364cfddb3fe2813ebce0aab63bf6d6fc68637ea5e2a142c6ae2a27142f7b52fb3814013ee607c06521ad3af0fd979bd4a75a174277fc818adccd7ab80055b54305911822d926d7bef7cb0f1367280d01170f4e874b53a1bfbd20bfa546d78e1440879875f957fd31bad69739e2b1f742a5fe58d37654079e59e0680247f1080a24adc1400388d146023899eef694df0c3e03c37b2f9c0be7807572df6980574cbeb7431eb9e9f42397ae5d14dab4bb8507ac9612772910ab44eb8c9239e680220dde1c420d45f87d94d5d9b80f76a9e15f083631a82a2093b75652e51d5d4129bd5e33220eca0e7650e6e195351a4cf062fafc1ef03af4571f281d46b992262e759c696e6ed5c8b2810699a920b0d1e9810d7635c8b0cdeb4cae1dc4c4284b41c542e66902decb4a60ebba7197462385cb8aa9130ba9d54b1a3ee32037f2c09f6ee7e8cb94e73100dabc5e2466dc41e5e29f075a64422ecfc954e2e589c79a1d4697ee8a2b18f9303ceb6e2a66dc734ef402756bae927c4bdc9150d1132693e5dae94e9610e0ec18d9aaf6e7c28551b3f6334af72a97b84e09a126b2b5d967cd5d53548280b60f0a88f90cb740291fc29799c8bd0ea74bbf1db1bc5ba93350093cc2ddae74721f90447160d49d01190306ed6ecf7efd2260d7a361daa91090f34e4fa5dc9933d2ec66468655845165596f84db142f31ad71caec5a98cebfc2b6e8549b6fa7c235ac832b7b71543b7f7c594d631c9402f86a4a4a8e17896846e1300a8a1c6e3ffabb5a25ab471194c0b393c1558e8d55a10723b6288996e8c37ee262f9a2a87d97b8ec521e23e784468e98b78059f2f19c26e96249998836127384f8383672e9836416d2539de6c1501b937d0c5a2ac7b5c78463d97b032829aeddafdcdec97e5da3f95b76e9c7eb3777c3a926612d442ce3f11beb8456c200fcd098c989e09d8b2b576fb06498e1a265d604776643e10aa24aefe62391d967efd62831be65cb38c0ebf9517cc7e8bfaf11e3b7404fb03414dd1acef354acce23d32fb0c26c275a0780c74ee20127d87f7e315b0cda02e55a44168a88e6a1785caaa2e0b8ab65754d1205ea69aaa252a4c4202bf50e8ba7bebaa50a08c9e41e1046092bb3d52cca244eb6ef9ac534c1893067811ec97a17b9cc63a9f0a1f99324415f782c0e70b16885c5605f137505e4d41870fabf9523cf32935eb480c29fb65f3a23e06db00c5a7c5286bc6e249dbc6cd6efbc275cdd6c7a8320d182b7a9113bf6eb837b924b3580be35d05d81a09fc4211f3a713da32663f7478b6e1d6f6c7c20ce32b6aa3d517f20fbfa56f9b7c99ac376b198adf68bc754ae8d08bdb81ea9672e8eb40943fec88f81526199b641f +expected_result = pass +expected_shared_secret = ba33ea19873105ed9690d40426b2cd24073c822eb86120a4fe8617b5201f9494 + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +private_key = ca481db6775f3d276a56ca0e60ca79be147e63b6898f4b814c69a06f55111c9824cbc1c109a01a7baa259da651a1a51d60bb358432550bc1aa1cf3656e0667d726c69a39ae564bb99162c824634b8b8a706d82175bd9657ec09a308b51a3b429822667a5135fe4350a8b3ca10e8b03b6da0bbd616ceec0a08476909c6182ef0314b284cc3f43c337307facf7b617348779d7493ae0a25d415124bc5d9134182169238cea1a46a3001a8165713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcc3032e4c2f1e92841d73859c76cfbe245193816d87c12bb3f12763174997760d6887a429a37f78c32cc1ac8facc587aa235821c254a2341b7c6bcf8b52c908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953554021af73c585b6ef248c07ed23116baa18c845571823d25cbae0af57d4f6ab2473b5919cbabdd7b4cccc1be89150cfc585953389172590edd61c3885446b500495247aed57a9fb1140ceb6b29f7f9a9f524106d8cada3432c12468f9bfb9a50b920cde85654c25249350f6760293ddaa28c771963497c4c5230c05862a4391330f54cadc3b0c92b9798f5bdf8b21016725ac8f565466464c2033872684608111248fccf94c61337eb6b1a9017e342c29eb2b148936119797fdb2757bef51a9a2601a00c6f0547b1831b1ca1118cd2e1cdd601a0b491c588cb5ed88ac36ae183848b9f87264cc5b020b2e965e5b89ff74c58cd2b338177bf1350afda9a74516a5845381e5fe132b4089506e8cde6346fcc760759592345927c5c6a97045b0ad3973e806778759b35988953c80b3e7574b7caa225c744372ee3042e07cce978a3f964395d40176aab7905a4bba98250f594c5a96bac41851e09f897df0376a89516040c1f8fccb93d44ab474c56913826c9e2171ef67510b53eb31153fc028b3625aa7a353bbe79cc76d393e209115dd00b5d6c98f80101705544604351cdb87715618343bc3fa227c1e9fa1ea3989390b02c59ec9174e5165239427592a2d973774ca62dbd9410164bcfd95834c11621f7da54dc55c44c594785fb0016448f2cc39a05e01d8581658a2410caa630347c3f0f6c86f344816bd13b3a04313a730f2de9bb50659b642353f6463d2e2a1a78b722287616cdc266b01098b3544632152db3b23938d67c63e51949496e13182326d5b7d70b81d90cc6c5d84d4e5907833a7a76d3850ac4993a696c4b210dcf352a32b4c83dc9114305308129bb4ff73a91d733303bca92fc0083d95d32ca54557a6ff3c42c2bab46ff913e1d39ba3f6092e30ab47f9985c7c439448c92b245259d388e291c04de427f378011ca983b21b2ba8bea9d6eb36001ac4fa5061ee1670066f9252524848973782774cfa795a2285a2669515d4fda7093bc54439753fb6b4e6b781eeff574155b2438e074b332417d751eab1ba1475436e8fc1b670c3928a3553d2bcfd1a59c46ea2542884f91f98a38d42ecc026ebcf91258acc99a50ae1edc88b90c98b74c3961b70759f39b3c20175fa80386376cde2b66dff213151b800921ab6932b45b720932a540c79cca0eaca0a9d5bc841c3acf3c08096c0446326114f05cb09745ebb986ddb76913faa6d5f411cfe987b5808d5b525759f50742969136a5089b060ddcc66c93aa7f94ea179ea896834bcb30147effd42753c9528643b5026b5bcf02aa1ac9be4ac5525f734fc1049f93963fa046b0ffa7647fcc19ccd2a89fe6582bfbcd70cab789e0ba67c6387462bd1dc35302b29ab65b53ee8cac6f7b5cf257b437819fd9ac402019563ed5104de97953453bb139835c67415515aedb810455855e63b5a442940d1ab85d8c80703141c9bb0a6ccaa6949a797bc0658f56065822c52eb14aabbea75c434a22409578f2b695864803c32649d9068857bc4ccf492ddbb216cd73bebfb517235218c6da930f26a1f7353dc2c2bca039b5eba4cd9fb3531523b1d5200c3c822c135b03126154699420e036ba827c849b285b28b81eaa64adf41b33895286ee8410beaa4a1c637617718f26b3a206593571160cff48437b5187bfd5830ebca6d2204584f822703075a40076b403aac5aa32da5a8e2ac0160fc8a5b5e871478c30d523c9f1967b4fe4aea55976fa803568c6863bd50c7b0756eac8ae8da498a8102cf7e4cef04582be990060177980606196d12ea824ca65d485783a32e42a4e20d41806e8ae1c51544c63c3156a42bd8abe55e36be37c6be6a51eacf02274eabb03f64c4ddba2a6806cce943cf338b09f50c5123c4083446802456ce85248daac7e5d9637a541c755b03300b43c4da96164c6c42c3910d36522e34895055c43847459451b8022d39a2c287ffb85c8459c31c2d183f98c684a959b2cd0a224cbb38713c4034a6668e14cac3c8f9d1b95ee6251f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ee51c62d244502a3a044f4c95fdb42a7fa0300d079ceaaab0f5720a1ba852fe7148d4a1642d1330942c81b27882c631c3ca3758f56b7718475404ba20cb8b436bcc1116690380507d02c63e62ac58f551072cca75a761f237b5abff58b2016242fb910f24baaeaa47dbf010600881ffd228aaef714c65b496795bce329819418c26321b5c73cb603d15ffa162901f386e9e815940bb5703477a996b313b50ba05a1d41ab65f233abbec534c106224c792a3dc14688332a8313408510386253c7eb076711ec35f6f929c301422192b3f611b36b97aff38a94b00764e9d89f38072ccd6b978e1a31e391cdb2cb3f9e344ba947a73db91891b944de4935d48a5663f85c94ba6ed8a3026c278d645b7b593702733865f12a3ceda3be2787a1efc2a2fc2211f405c3ad1c8c46257059e6cb43f36ccfe6231b730040849233d03b7e90076a7792f865467b6548e541bfaf5b7c3e6059cb426cd263494c641bdbc7616aa8348c6335d42719c0e79ae52931a119856c168897d48dcb44242c505c535698a35cbaa9f80a8145927af6653d31977e827625e3ba18ab7af3621df248434c2cc5e9324f34c60e1ff1253b4904b1952bb7e16dd979c03541a6be9bca09632120aaad6c457942b0077ff01b6808af3fb82d390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399e2255e030833485bc69c5c94cc48bbfe7bae3754bb49a2fc1a15db012be519ac8802a5cd005a6adc31abe237d9c2924134235db04b78c96876b084d41c62aca10008237a6f0c12600fd134ac59808418fde238aae358e34c1153842a31cb030bd97ab2cab83f74164358a1a077591c356162d53970ad65e21a994123c4000277d72ccbd0d712026217de9054fe9b38c61fa2c80871ba83a88bc98105e693a15f2213eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7a90a770717b14b40673591e986a1dbac4a87b111ad2854899808de206e6a768770e84023931bd4d996238430859a6f7628964e4465e5db7a9f5a0a77272ffa95a9ae759d47e1885ae6a4e3e78493a25153387f008a74ece68a67a8224e19209f20770bf4c8cb15cc39dc4147549c8cc599b760700db4591b284905562afe554658a07ff22c8645e29006d331bf09936085c4e7c345e2993a7332c9b40124d375c40e266a251002eb03b5dab50760972b7e9785dd585df7c6488ce9218c0171db28a99ff7a557c34936780fe9aa78bb395885085e0243887ffb27030393d925cdeb2a2cc3365ea95b5bcbe4b0bac9bb32e1a90b009de0f6be8ebb3e684514d2425f3f1688f54056f41c8e364b5e89859478349c793a70982818c28a245f690057095b320b2773206a3a856445290ea1636f5029bce3d8baeef0a73f912e110570817bc66d9b8dfab95da8b270898b6e30f28418ac5233a954f05009c2bbac3cfbabd0db906188abe7b72cce5001496360758cb477dc2ec02a590621c93b9067ed346378c419ab634d95267def3148a594be088bc349ec9669e4bba474c4aca165e664986c34a0dfc5c5c4781a61063f10f2c175693b5b5cb7c9b74442050f5d9421e6900cefe35bd942b49e469787471f43b35ef0c86340235525d50904263b2cc052757b01b75414027c9d02db50b4e47e5cb19f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5bb1a9788565de9455be321b50a39105a33e60a9533b506581d03459696192c08626009e723b228df1cac15c645db16faf697a7df68d71a56cf263639aa0185ed25bae84551c60205fe6b98d9328da3604d8d1c70d84c9ad68cbf266baeb8c6b3b9716ee50a8fb5a25bb6a32f0f971369601f9552a52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d7ffefda144195d79e581c91cdf0247f4346e811f890f54f25226b4ab835871a48f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = a5ead95b44ab725154827549ed041a9da95427c827a9d4ee7e8e37f7001a5ba417aee761a6cab26edb9c8d86e6c275a176f3ce635fba2e97e428df214c03ce4d6a59e60cd257fad420513f55ffe6fde38515d00b7f21d55cecd78b1731d33aa39bff3f007350aa5c380c137027c91e9e2f5fe009db047d0a78b95515c04407573dad32d4a788c27cf0740fe5647f5ac2ea1e23440fcb86705a71d38a746c8d80de67a84836a656a3e02fc1a81db65f52b4b55024b433a400cfb43d7474133db3796ec75403f2d38bf626a6bdab7f8ca89b2d2b2684345c972adbf851be5f594ea88d993577a7f409762b65eeae0a752673ecf43565ba57cd2fd76984fca7eaaf4847dacaec3ea6528fbe7a2cf236c48d76ed2861e66f9c9df3057349a465575052158deb91d63c48c0e58abf2c4d58cdf7902acd8d54869e1f8f46d322a9b1db170ff139a3bb09e75b44fc8fa284dcfb5a959331e110fafeb5973cbe4e8fe525c08cf1ad29a6c1f2c4b7004a9eb6b66c7b64d2f375b1fd8c72588abf25018493d47a5aefa0d93dcf36ecf336a5025c404d9afb0b8032bbd6e407390e917c7baa28f74119cf4a77a9b5ae1f41f108b42c9e16dd907534143b68ca49673c54eeeb496a9dc21f4be1070e4bd966d853353a8a075fc17d5939d9609a83dbdefbb4a5c710829e26a1b1c5ffb62edf0aaf4a789f78429f4050dda21d4ddd6a7e1a3494605f371a1bf6d3624c8cfe29ee961b41ccb6a01ddd0aa668e3535b686cd1f515d64e4892d61531502018ce3f4c1a8d5a08e272ee5ba785281c3c15ddfe5b58f05913cfe14a471ea01a961793e09db9b5114cfa5243d68f05be26aaf01149767ae46bd854d565124503d77daee7b4626fe130a9d9bcb8efdf495893e3b62cd84e484ba4ba5fbffa19df0c915b13e38fd0a41649251d392322cd6e22a2db1c9106de2c8196761272b9329cd6353cb8221e00ffd91a9f06455658334f66945e4b24f1cf30664c123257dffa874750416af0aa43b0f0ce2c7c40710f6471bf21376a0e6bab6af20fa02ae95a8359993eba2f349b62e8f8857423f46054eee46656c8e12aedc754b03d485ee98f0b7edad160aa052887850103de3b5cb4ab8189907baac915541e76e7734f53a69c420ea95fae22ed569bbb7d28311a52e1e43efd9dff98606979e82fb19d4d7b5b60d5a626c401d71fa18fef6eea32312d05aca694d54a6c2c55f907e25928e16bbe38ccf0b37a3ec0ae1593d69c60dd880a61fd803856580d9cc0c8e3f89c98d17a43f74e3695927bfb8d539fa4b79eb0576148da4dbb295277c8cd71b94ea21b9614367c466f03e795890cdc5d2a75ae57cda441589c88aff28fe60ac7d0acc0db4411846ca14097a736bb475baadfb334aa669e9e3dcd2fac3ccb8490a97f5a5cf8a627b296da204971224c299cee3d46591d57c7973f2f561bf5ad97039ae97ae03557e6caf2b7edd6977fca67dc70c60fa962382ed707075df43082cd593a01e89b14d08f1e9669a06934803eae0463deabf008251216684caf84913891ea636353d50e6f86f15408bedc97a88a8033524d7a3599db638efc49488456937af09f020c8f30e0d6c7f0fad55238fd38fe57c2e42944a4265707003b884028a8fad01ddf93aba1eb07f3ba0ae0c9b53fb56498c203d4013418065f589e2aa2a18bd02fc92d19bc1e38d72f449fa37fe3da189e953a9f9e28e1eedbe481bddb8f2bac2d6e6acee07e0e79818da2c8b961210a72a6365e5c679cdc2896a36a0f66c121a9657ce84bcc070a3f5cf06a843b59842b17eeb1e2c84f0d387b05782dd4c5613a6dd5024cd79d1429f2520fd626916304a0d9ca3a09a7638a45331fe6e6b6089bf07dac78f005c7227f2abb68d4048628143e90b31ce66901b0d0790bf0837cf773a3fbfe53d13a3b0d2420286ab7f7579f4f85f0e4cce62db423eedfbf6ea89f22c4271c566997303281d3a6b633685d5bcb5ba91ab476dd277a99574e39e45da3a7e42f490ef0d606403b940e87ac4aff2a6b09d8b18675d3a23c1cd05745e36bfeaa7e559d076a4839926fdfba3fa7287f6b278491f469393ac9973e154aa413af39f0b39274137081fadae69707d39134a54e0be1f51272b141d97d6c5e902f7a752982913e17da9b2e8648a298987cf1d03ecc3a9f4bee827731156fc1a38b6cbe7b3ed7cd06ee5bb9e7ee98f909a5 +expected_result = pass +expected_shared_secret = 2baf80269b225c66a8c35c6f835f15bd6949ae2814cd8c405a0aed313a637701 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +private_key = 90d7129b79c095b3063f53058a4baa74c262a99c822894254a050409215fe67773c26c7a6dcc739d8406a6055b388204604c7b065c0cdccc16fa880858a36d6200c6cec473bf81b245e09c6e5a55a8d8314334c23dc14fd6a9c011a2ca93753afa8609320b1d01fb9a2a4263ddeab8d5a00c40346b8f84afc7b945f521321103a5219b533f52bee42256edd1b9a526013a00ce07d44ebfd66c0bb67775d1acde4aadb7c98731931e54f5c458264894971df5d0ccd93817bb77a2e7d29ce47aba205c0971f34096280cc725a3c22a4ee24a9938cc2fcd9a670272a463c852efc04388ca8ce86a8e9f63273aa208610c2274709c55922ad371c197741af0526218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0ea2075bc25b797d82a8e0385ef1094d0a2b1731624308487991a7164d8a507f2390f354b4fa3a225d5a46463145ebb57b98724f1d3cabf11ad4fdc00bfa267d8f3107ceb7da37c060aa23e247c28ad0069d30681e37807117ab841f23548caa02212afbc1bc54297202fa549def55ddeb5ba4d10ace2650511366ebe9c1d61fa9d5574c86c0714aa523cdf946e1fd259148a7e2ab5c21884314e3b8082bc210b5209ccb6b95eaa2ef62203a0b707bf9c5db1a155169b07d41c0edb9709744caaa36622f189773ad7a59dc142317454d9c81d55d1c637876f104b6836a6842b87174290125505461eea77d63a8dad03c7941b69d7f66e434922e13a8182fcc35e51c9ce81978e35818504cb32e4a6dfc777227a5484409a38b2a1e2243110e84d024b1fe0e0bb36d4aac0622152599fefa177b294bece391d47553983e420de5462c72ab588b2934680a399ac40ef35a5e8819458e0a7bed1afbb29a446ecbcd4e45a50176ee201526e314cde085afda30226039ceb41a14d87256bf566db30ac77acb80b29b1f9d602e919707c96863304372a353771e1ce994241a12369fbf42bcb4315592724cd5085a589b1b4ca46dc49cd65a1247178151e455741c8b5d7c9cafcb75bf27a5b4ed05b22e932b1e3bfb0c93248400e5485486e0c39fd5ccec680c78e6137be96823deca37c6306d31c9142fc03ec540ac0120ebbe9bd5237583e1972d0c4676708ad35b559fb89bd872428a3e0504350451dd65f58bcb292c0ba437394dae55e6df13a8f41827939016a081935d1788c4807a53a011b89528fb60f386632e725b163e83e105324c3914f26f389dac199a926a25a02624d9a530bf0afafa4c5ffe6a5ef9422e422019ff337d1bc2fe16a07d9a046d183137d477dda378e17a95fc7e02ecddc0d551724a4f36ee7648c9aa771bd15ae29b7259abb63d0983917156ede6557be445735ec539b2199f9816c562842627cc83bcaa659075f5179abdd1a7056d27f7dd96a6813a940a9321cfb1946e95c16836ef028106bc26a3ee450d8e569eeb23b70722bcbf828821648b1668e6e47869afb16c0e4b827c4cec3c4c9948a6c7f874968dc80160a811cd06d58a885d033210341a6f7907f53a82c98468f6bdb7cc7a60107973db0e70f9a387673234d6665019676215ee4597c65a13a2636cee74266f373a4e48bb1db019bf44ebfb0a509e4bdd324314736292de1566f165449c3b618c53c0e7468a801b962ca60d6834276ba3073f725e800a39668bb515b73bb2b055fc55aa3099f4c2b12e027333df63567043b5e81a53f7993ffea69bf0927bad9a6e56cca6f96cad9fc434dd1aa6f2814171cc8b064000bb36931f955858510e5a951d8f3728b2b276962254d061ccec6727d758fa0944246a70d053021ccdb9710c046f5888bb1e0c75455a09394090d0144578053d46819fca8b923227cf36c5d874bb43b34463db3a502b6cfc0b38415f413dda5a1aeda6faeb55269fc2566940615f714ac0883f0cc74645594c17b6027c198a368a608d50258eb75dc00c793912e133290e7954604629de990808cf8c1b7f0795d6cc62892127229579d2600b8b17a16ca7fa2b389ecac698ad722779ba264c1027e39ad6a7c952ad9224b555344235282a6b6a0711fd854740a6a54a9728ae504764f943b7dc92703c03914cc0c6e9376aabb4cf52c00dcc211cdf81ede889529d06ca404a08b719e35176f86c2aec7e40d1210169cc6a09f711edcc2ab20e136f9412f7151bcf330987bcc5332408392075a25c27e3747c65b5206a91483eb501b48cb5e07d501579b5093255d5e565cf5ca6247064ddaeb7e909a190da61348365c1c508820208ba282b5d48199d7a947ce9946f633bae9d24eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc7419d9c67af522a744a506e73ccc5afc2cf27663e813bab0c82c6c64023fd4cbb5b74d6d5bada2a33ea3f407cf5239fdf56bcbb455f39b9d69813662281947659534f9443f84266937c1000d8cccc430d5f9821126b9b28226d8a8c1d7a247e2d0cfce23c52c3a2c92fbbc45a86394500f7d984c9103bb77030b41b6c885b1ca1c8b1107878069d2bcc23b52a38651c8090f3cfb023826cb84089809e9abdf107e0b261a8ccb3cb8e10434acc40312ae18b93b89323c3a7676d0827beae3b4e7407827579efe5750c47a322bf76851a762caf62cc64370742ac715f182c4e6a77f47c5f23644f42010fc029c49c538c9b821c7761c1d2c27d7096c9f66ac8801660beb39cfd23e531603c7145d61668a612b3406d16feeb67bc5578bb972147fbc5e3f14059f55c8941177cf24910d1c94f1380f2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecda81133a299fbca37b4a69ad509ba44403ae3e5b2cf4277c8d22b68fc61f5e105dbd8c31f99609ea2770058352b81836b473ebe95c9cea90aeb682ca81b3e70508bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d3270406e5b4589f5401261b790cb02219636ad9c65ea5c48ce79c2cf4758db9bbb55e003e0c64f9b025ddaf1a341f8c2f26593adb9af185915c0489c77f1038abb9802ec812885af603267b7457210f5a00c917039b1b8e1bcbdb8b8b3ca9418d27ca6e96644f7090322993797a54bcb13cf59428d24d499c6f631e8694c50389496c6454fc34aec2677ebe05a0d61cb7ac553e2017c93d7183f06cf461331073786712a2566230f191c8169a1bba3a968a44a3fde764a0b5724e74615f3cc0f819616bbb21055d85f0fc40c667048fec26fe98b901b67a2923c57e17ccd2ed20f8c3731f10b58b7e9234c4151f6f4174fe6216f5aabfcd3b634122896a156bcc0ce93f41a8a25cd825334b53269881a682d8447975b45e839b8fc54b53f8c70a5aa9c786113ffa708ddd5070b841b58d25820fb6e4d8121ccd016b9601dbbfa4116e1aa9f904dfb5ac2b4d607f43a3961161e02092b9233c75b7020d5ab4bd7e3abc3b679c6d003a6a072f0038983677f606ab976474d8616a5dad0c15ebc10986b9be9f19df7c740fd1198adcc019d43766a847f05fb5cd7c16a6215a0dc251c894ac585a5b530e2611c839e98786fc5d1c1b0817da7c20dfafbc67f62bbc872cfdc153d83f328814abdb5f7babdcbb125298127a83bdfc503d6a8a2359136225b2bbd9baa2a11050774924b8662bcfc608848840cdba8f5d72fa3876ea79784e4784860047915c8922c96bd8f625d56729b96d88c3dba9eb3aa308a7940e90147c9110770f712cfc81224f36fa61c1225ca7a653c5ab8d0b4327c014ec580b9b347d0403c235b25cd88c992582d44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f6fa1f9e8c34d46a391e80bdd48691a930b3b0dace1b6b4b90b948794c14ec7b767ea6b2161702f9f5cf7336badbd2cd5bbc114f7b84d73a24e0049c03f83fc60b618ee23bfc5a286751970bc37b47432f982101e8fcc3ce01089d5898a46baca7265f05e4027ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedce0373a39b545738371499e3b7c88d20179434082ca235bdfa7701624a09b20bc65a10dac15c6c14268fc73be9d7a2f6556044c49a2006403848a726e767d2713be1dd04828da143df7860a9253566c9932fa54c9561ef5a26d990c308cb8a65ec8ced7181371a517c16a28ee9989f9d5acd50c8ba7085e95c03de98c978999c37195356dfb2e1da0768647c2e4ca6ae1d6bda251103ed17482cb0ce78ba17c69848475835a0c2e9d08b27bb220185a7ca40713aaa70068f75140c37d259150e6b4581670a6f8423a5979645309b7b0ebb0e911a68e46c48b150552f3093d425761196378863c431605ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c13dd780ec5347c512cfabf4c2e6a44cb2b17993c7c746f93c1400a5db9f12511e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 187eba72434adcc60ef030ebf26c2b60cb370bbb217f1dfe1f662002df875aee461d371fac4ecd85cd34e406a2354d521ef4f24ea61231626a8f856596c2560a50a8bfa277e92228053b535f2fd7e88b8ba7fac2032f508face47ea7a8028d5adb5c200ac93dcaa8a26f521cec0e26ac0c32c0244044e71c1db0be8fcd9be389aa6a3b9bb51facea9f4a0d6d94359b2a04326d78f8fdb4e03cfa813e5a27ae1ec5a14779e3878b75a670990616d89a3e3e1460c6ee8c8cdf3c5971d3d372be837eee1252b5428e7ce752a0af05b34c1c40c9f8798f704466b53d83eb2be8233b041cf6c316c93b225d207ae6b3e9494900be4996cee6dae35d39f5a6bbf230bb5d99cc22c9901187e49221183935a5f4b696e449e925c87c9774a3ce2d0d189655beed14a4a33466f35b79b12449188b4f8c9e20d48ec98a1754231488ab6631e08617732857696df0924a362e6c88731e95aa9e8fc995744db8dc276fc8f6bb92a4b213700f795c8f888fe478bcf609e4e02db5330f3a29a2163c950e800c1e6c98cb86e3432c298529d7c678476a31f3936f35ae32a0e7ceadf56c38ed0af6aa6677c3d422dae5d259aff44de8e841736490dcbf8f2e5aabfa4b07ff71842c1187b9df78864e6ce527f6f5235279d69938e4b76fe68dd5e9f5bb87fc05cb87fc2bb8305718db18d2ad6034029853c6291877c6c8356a45e320698d342b327100e975ca9cd4b76b3486b800662e35f3acf57b375d253cb6e4e7e64779f00fc7ddb6b20693cc733e42110015f390223d168f59e000b75f9296d38649ee1eed28ee32e779d2a17b5a908e6d8855380896fa30932ae5996cb0761ab1a253e51fab1f564cda8d47b111510db92c3b8aa28cc406ad5a58283c3d36ce9d35bf85ff74c653f9926e3d9ab35692f202922481b7523c6c7d060d72d13dfed44e4374e6d95ce4a70d5e44169a80d8cb1de32d5cae2145cd90e96940fc5da4b3a0d14ecfeb654693f7ffdd202624c25d99aa254c45ff1b7ecdd6d0aeb786b8840fcd07c8aa9cd28dc15edb8be3cf5f8dded47ec3efed3df3e92ab87cb42d724235366339b4aa6f749af6e79ab606c8bc30f3903d9938fcad6c9f27586c3fb8d80428dd32683e0ea23b492bca855165c1e1ec9c812b4b7497956422da355539867392ce79c914f239408e763a7534331aa59428536e0cfdbbf81601d4af3aec59c4979f13c0c7c9856481d707a71d1a211b087f9c213ee9cb276ac05ee4a8938d8e9cf3267401221bb43ef369f7f3ae287bf99261b28f5b4377cf53be63a5da6e797dea2898f64d8ea52dc69b5de4c092639f168a4e24f202195afcd09cd9d7b9c1a5badd8024b2ae433781ea798bb422756fa17e5d1e4d3c08ef89e1194eadac34334ca6f6f1a69a79126353af5090cb605867bbbbc40d3f0b48e6c2a6aae40495d85c2fe9313fcc3d73b4ee0bef24cd3234c7562606144eefe5752ed1c9b8c81a25a8f0d20ce7bf4e282c934bce0c03cb095d1c54e13b85182886000c955db44b8d608eb22a5ff726645f28a1292aa32202a1be9d519c01b7232457cb32e633e8d14c3e90a51382610e569d72af874f3c557a944c2f1d3f172d0e9580431bb5cbe99b9fa564f6ebde1bcc3de195470bba8d50cb8d8a254522a32754a64d579ef292136cd80394e5a4aaf1690f2d42f9bad551e1443e120bb0c913719f5e7df94e95e227a9b5e0370a12629d37f12308c73e4eb5aee6c0b793df2f803e22d51d21a2b9078d3bf899d68f53326ce9a1d319ea9048d662bca4f455b1b7491dfcfaec3428916d635d8463dba2fc5e0833444ded908da99f2eccfab6d8c1666904ce96e57da3371b651e22a7cee4e123d362ff68db36283a19960b4ac3538cac26e7fe95f2209b66dcf934f087d5c73623a4eeabc118389cc12b993c2dc7d24e15af7e786bcba1ff7c505274027170055964ffbf60a1b929f773911eb36489e31d4c5107cb6cb4820a382b4d558d8f5deed70fd4b2468a2972fe14741b13b7b082152848d8b04c56cceca6c9a6f9917c6678d114db15d153911c622149a5319afafed2629b96734a58823a153c0e0761975751a291287a41e50238a065fee87a9b4751013afc304b4ffa822d3bb5c55cfef33a1223199cbf251c38e0ed11acd32b6f742d549d150aaff8688f28c66a803c41af1c52142b92c8a1ee40ac404a8f2cf45e548e5624 +expected_result = pass +expected_shared_secret = 07318e8edf0ca8f30f49fa906ec814e40ec52922f2c0ace243386ef2bf650000 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +private_key = 0246c2025246911b525e6c3421584bfdbc83d73ab936e76a26236a85215c78db7ddd010c2e038e3dda69b5aa2e9f4997d8589bdbf918be1c046cd518e6958ae6925146009d185b53456b5e16d59257f20cd0f6677535510d02602d5ba5b61c440fa07fabb1b5fbb38437e90522665776892ef205a41a1a2083902648844dc9d65e633266af871481f036a2888d3fb9901355397f37875a4494777c781ec40478d09a820204a4115701d25a74b4bd91676ea6391fa160617c80cd05b0a80e040cdf22b29978ca55282f2c40316a35433dcc8ff7cccf4280c0b11c548b5cc08fa45bd0760ce03a02f25689d0f057fae44cb1574c42e760cb331c2ce4be16823dbb2870592ba844f30dc407298590a088425e023b856e106437c6074547260a856e648cba07e51a23e70d7cc65656b4692ec24277f04905c4aeeaaacd36341c705b504cfaba73201c2745ab06b056f1768447981e0d676ec904698edb230f369190d8c1dadaa5ca59001ee8a68c302f04298dc5700c56b2b577d89cd9a585b239089847cd3e96ca80d928867b27f3657987724ff9031649c246cbcb4673f6cb8544150c9975a13938c89a68cd0b6de5237fc8d2b7a6bb94e0c0856f00b821636801e9ac84f35276065ee4108bc1d755c1c428566a1ca3762d050458dbc7093567a4465453ab8656272a3c03b4a3c55929271437724471d5d4926109c9792ba49d117813948106d27c33069eb3c40aa8370b79e23f35934ac28666fe72b43f722151f3c26c96cc3b6a40d9e1876e55970f252811070fefc00d70a009e4871f136a08515ab239c33e2de638c4260d0c89cfe30b8f8e5927f2c59fea3947ffd0bd636b10876c3c387c00e15469b42b80bfeb8681dc7715c2b248ca6fed92a9399b72d1023f9507229593bd9bd936a0f6abba09bc3367782370b60d9cbd0e8b3d5744101c8ca97eab822fa4cc399b5be3195cb1e3c9260030af60bbe3295c4de898c502543589142cf48dbc7505ec9a9d93cb6dd4c9678c1cc0a082c5631a255142603dcc01fc07c27d628d89f09b473816b5d5171c18a3f9737bd6d3420d4bccbd3a5624a2686e54062ce4696e061c83bc2586f1a618639e51e63bc6c64825eb50d4f88334b29145bacc49e28dd564b7a578217fac230ad00a44f3acbf8753aa572d66e1ab9198cecdf9bc722455bd267faf98424eba4031c3bbec8298a9388cabc6b3beec7a7fbb1c814811117a9d550407c9e6099cea65ece641f69454b6a0ca9bf86a3dd472f7c0a7703c6a5b25464c0b091b29258de673220857878434ea14cf50054fb2e63547e9be15107beb7a78cd5c00cbb1462a0347e72b51a15ccb5c333894aba511295b37c97c7f4c2eb6d97219559b40a67310f457108015ac1b8e3ae15acf85689c4058ec8a0bb18b75615011f2701bde8ba70986b39d3368e1f978675a49fbe8509f1239a1c88f1df4adf0ac8b68a87e2a403373fb808a7b1192371c7e68b80854b0e4335739090b953a2b67999f9878a32415b78c22289eeaaefe3298fd38abeb6abcf5a55bca388004e46375a729cc45926a7c3e3bc8b4e2a2b196aabe5651b642c1cb50f666a1bb6da4d1cce8c6344356a68de044214453d03b5ccb82225603ca7e339380d63a4d9160df03890df722683b10847b89df2c46757815d34942eee95d9a0904f50855c73104eac00e22893e3764268a84bc1940b2d5d3befaa5571b31869b238c8ec7aea5a70203e67a0d9851dee23d3801777b2243e2b6328bc4aeb10a468ea96db01b77f68cbd63e4bdc157408ad378f637580e5723b544bceef3962c3a49fd836e993386e4e2c91bcb92725216979c132a0879cbb49f4ff12a46b194851b76dc910c20440535f9529d68acd39ca13aaba696237c400c6b297368f0d6c304f012824783a0b02048d5cd1797c5d61b3f5792715e7b72be1cba7cfb12a638720f7962243933bdc150ee5b26d4368e8c9cb985b7a0e5ea36bb942840a8b3053c09fda45ff937396ba8433bc3175806b0e0a77e2e8cafaf55c69b44bc626c3fb6d9c37d1a83170189bc5c47ab44cc82cb97732b8ddec23596224cfc4894871787ea25493bc48e4a37b70e404e77436f9a91970778c74e21b19265628ba0bdaf0744a5ea4507f5b4a0e978cad763e26a112f38bbd1a34ef3fa06111b74ab835cc8479a8ebab78552ab3a3ac845a332bd1200c0635d3ad6768a4773aa803ebc08a0d7f772ff78ae9c90b5dd1b50e86724fc89110c128bda8209f0173e4d23210910bb05832b32017c182915308563c938695a0a8c49e6108c972587b04e6c916d5ac10ab425c15b370b0a4273d33530245048e62222d6211caab6a25332651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6fe701c23885e2141df14b4933c70040a295144a74a440487741116175addee87e656136a455bc9d1c5d611a22157aa3dd288b4ffa1d79668bf152bcb71108dc5916a223a703d376f3877406081c45a08470e4ae5679b34d2b4381335d8d5120282a656f121a861777d597a3b8910a67749855dba05f36831bd101ebbb427c92bd62f9c7f1a99a47c94e9dcba438835f3e053011f180f501c82611a64ec79e8b3563816a3fbffc5e033a114b8c94c9fb3391e0bbb8d4a33be98b219500f53b782fb2482fa9089b46b6f32555ba583370622771d02c6142647e6b87ddd382428552e58b80a66255394ab3815aa014c31878b74e7121b9f6d084edba988b43104910677aa62a1b27035de440b055146d15c466ea340b4658a41a885fe206c382923fd079f988b831a99d42241cc8637a647216eef18497298509832f8ce55235771e408a4bca646284771a0ae66ecdc2bb9d696d799c3cfad47a5a8b49575618bdac931d00c718049760f880831092fe3acd56d517377b00b156accc3ca6957ab22529673a59bfe87846c5431ef6b9c6c3201841da1451b881b2e26e44ac71e8858eeaa55aabd45281b56345222453440f7e427ebaf90bcd23c75e1cc96776ccdbf92766c778ad3b0a43a82463d09d79b90919eb76084438413573eafa0a60d26bd45ba0f75824c5808112406950d1ac5b226b9332709d1374b61957bb20ad7c33576bb68d265c7ddaaa12788c9e015a96009c0f99521e98e5c0cb38089d2101ef8700fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794257a277a983ce87c29c18f8535b07960bf20a3014974883529ba033a9604370a926778689937c774e74a3aea922f5fb717a7b73631c2e1f8c33f499674e584dc7f48e3efab83512c0f723ad981452003840215912e3d0abe816a58af87e1cea37daec759da34e24033c1842b2dc0a6909991b9e205178596c812a0cbaa48efb3586b5b6963fd445140bcfab6b4390832de8e27851b10619e699836a692bf44ceb23cd1f6938222b4b83f4a25a0c0c9ff397195bcf5dca633952aaf0321b121518f887c5ae945821f9b1150bc1d2401a7547ca3386bc33232cc58c6370508542994ca6cb098b01033c0c97ff468bc1c726a992181882ca810115fd2755ec18ce0f88cd37fb61580c039ab121ce95af498bbf4eea277eb780d3e0a0959a388d6a290fe58a64829184b763d3636b0551a90e5a9723b26f2c4869ff14ba806153d6ec32ad4c42d27161bf051be85303d9167245684bdb3198673c668e579a72136b6d252225b49f25746298532990352b90d82f6e324fb5877176555a078b82ac10bc8ea63a2b9067f13026584abfbc473909d50c58e9bc47bb99308298e6e90b3671adf643742e669a93e2a90b26723af4cf6bb64446619bdee7b5088369fbd737af0c4ae367313c699f384205c14c13c38599604390c7c911a5781bc2511208679510dc0d0dec26ec46718c748b59418bc353b7618195b77992858c06ff15a9077a37ace35101554e8a3932a9a9138a800bd3484b1b977d53f50a0443538aa5516780a094e6306e7842ee6a753c412d2a89c23eecb2b26a6ac90b3e890466a557394b520a07cb671ae9cd2c43621bf55a99a98392b9cfea6373d4b136dafa78c6e93ba7573b429b50be5949a254714c720721699290a510581b6af396879703aaf4a9781268446ba96a072009ffea0250c793237744e36bb0d3d752e1a6caa346a2f9d1695d49aa1aa2535c6449e8f4abf85079c0b99b91ac2e91613de6368c430a886eb15b192805e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c4d1a15b5c335af4091acc5bd189176b477938ebc700042cdbcb7385e10c3121b179660eb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d5acaf411ccb64500879102d9cdf6d9fcad673d874a4153383806fe174b2fc1e393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = 847fb7979787cf06edd5ca8187896c920f8b275668939297c3bcd2e23dceb07ad7c62fa6accfd6be9a70fc1af69c82cdb4c6dbfc9b598ab08ab9e5a4d0c5c741c8f9f3896dd05f1c61246e517d1e88bd90e6eceb7ef563fe92cf8c17f2413dc19d9eddb96d57f7003b595b51242080b2d6a5abd04bac0e1e8075f983c452e16b8dcc5c3360fabb9fa5fd3671b50d3f7230c65a46b0e04c43278b2495fc45866afa27e387a967e985195037b4db1ff57f11882ef5db34452e587529e7f3b93ed113b0b82cbb9cafef86f90530f21649e22aac11f062dab01a5fe8c8fbeea23d9a7f4ef172387a6b08bf281f708cdcb060f84a2054eb3a996c35e30d6f87b88f76158413b3c01e50ff7284888e6b2600f77a3c08df381799fbb62c187dd81e570b2b14a730b55738da957aa140499c0b2e3b96aba03d2306819347b0e0c3feb1b28183edaa603a60cdc3a4c009f2c0fbf001f783b54734785479e3a95b4003eb0c57afb24c1c212be1ef92d1e9855c10c4e0f7773b3b069ca0de87c103ad4eb68257e64ee16e657f711159e22d5f9894c2b22abb8c8979d297dce205c20963307a151d2a2e1014f97edf1eb0ae530f26cccf31bc3376ba1d5485e3cd47360dbab0b7e1a9497ad6cb8edf1b7a37bd9d15431b5ed36b1328964f2f8de3ee109ed9b1ad2b5411d1c71733862793054726c0f733fb7447e59760174e059aa4c3ca6683e6eea278ed52d36d13c4af8b7a9574cefbda22104e93942f147eeb77daf30ebbe3b90543f562a549c830a5e0cfe91c1841b6668570caf37e274f8fe49f29c0eda1bc3d074231b4c0cac1816bdd8e9e32b714fcbe40b853415f8df08a4e859a65bda61dcd173c2ed6eeb080d4c77e45ad553f1211f478163e9a548eb9b275c695a00971498b248eb3c56fa28ba886193a49d135bb85909357b8363dfa9a5e420a48fcddc95449fd1d2ffb712060033d4ddcdba89b2a9cb1dc4cea293fa6d46480f7b916b91b8563b17f9bd0161512766ab6d8f1e70acce3af223fa0217a843e7bca4a9bdbb86a440837d6766d9900f292124f93b71133ee6e6091e5e9b3f4aacd3ae9e5743f3d41e851001788b87680f07b80259ae213abce3d119b191e6877988a2dbf56027a39dfd3b00cb38dfa13b7663781673e745de54af5c3b3b0dfee94c8688606df28f6af8909e04a3fedb7afd7c19e27ae2b0e7b7edaeb59a292880bd08c74ec2a07fe47c9c6070ad98099d655f263960f9c0a06ac78570409c391a26ede69da5976af32c16c156a733a1c59045b85840f5cd01ad3e708b8925d5f46ea49c51845f832e389aff2db412e9272e6606a7c1a7e69237a25bc552759b3fd0eae62e59ff8ae8891cabdcc8678ef2a0326514bea8a50928261f7e27033de9afdce4eeeeb5352c9f37d6a00d96b272588a3390ad5645d4f9a497d4e24649e2d84f92bec532ee95595b9c3d64e96408c9292da2049264b595db45ddf8d252eebff55a24a1f8fcf9c8a4b8525ac2b129b396da03d3dbabfa7ad085c3f3ae03d74154bc63aa631e84721242773f384959869c36efb99e19e25f1343f3e4d5ccaa3b59b12aba72571db26315991ea6c1dc626bf9ccfd03ab89412435c1e1ec283aa6da8677655380e55d29670a0df9e5aac18bda35cb807c4bfaa6bd3e3324c1852e6847b4c15f2ff8473427ff475057c75ce75b49004568c61c7b891c8bb2d7ed9d7914a5990252bd34836bce00a63fe5b3b06d6a0173554fc5aa11650ad1cfc84ffc1bf2435a8cd0959f0a13a3a38f239ac9e847d858b18840bc9a3471303a7aa77cc375719de84f832cecd0885057306705cf928a7d78db8d03c8702e55c44f6debb0ab613ea31e8498e9afe9c3f51b7ffaa5ff34419323d4bef3eb4f120464a64287ce75f5fe18cf6cf596a197540ad31bf5c157758d9c513631f3d5db093995fc89c67f6623f48d9fe23de28f8bc2f590c3ed5b9899aa397fcda3214ddd30b413a047f9765c7b0606e21ad56bfbc5cf330355671e28df4eda19b7ca89cf6ea84da9ad0f8ed6d41c59d42331828916af76f13453265673a8a7f03cbee6e70894bb6b17cc01efc9ad0d45ea6a6a73d420d097ef5b87cf580d179b573f15790665816530a9a78a8200bdda59b73d38dc1de856e5ea100d51d46cedccb3b2fb60c043dd7c9b0973f9e6ed2169f0ece4dad007978997fecf33d9037abcd7d622ee0 +expected_result = pass +expected_shared_secret = 38b5d71f3a64feb2cd41d6b7a4ac5440707770dc4c472c3ed141165fb7e8818f + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +private_key = 34c91f6ec981b1830501d8969f8847b2c6bd5d5c43dfa044c43b551e610d5675bb7e7c9e393b411e69575301bf4ef4c7fd0b4b59e213905a254eb5540aca856c370dd28899541b725091c23907c04390ad32a56385075f42a7545672544fe177b74c7ed99507e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d5201165a47391d21a7ca732fe9b3455c44ee4e54fc3a6518d51402cd5a2d49429b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5cd040245543431c0d2c9091376611cfdc2eb9181b21c8417e3931aa2b1141c1051cb82aca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac7524f3855de2b00967b7bee0668112d51ccbc139fa73374df2685a3cc06838b150f92a64c17772053de2b05cc4d51832b8a2b8428436d99e1f2484b127ce0d861dc8a11ab0b0019e0b3439733b36a7a600f4638d820ba5624b445349a86465e1b25de787207dda0b629cb472d415a42a8ba191b76b5829d4d987a2b0c235521c187a0baddb603d755eb37396cdd57ff76276ccca997b00cd481587cb8728830021dcbb8478a267b744a5bfd08b4acb2c1e726121996e55b60d40f6975637831c392845d6823d4b9092151149992794f4ab29d4164a44239f07c365a87ed9786af7a57ac0bc0d491018007b6bf7705a21b082d1e040a4f4c25e329ef9a8518956044e7683af94728487a4f95305d4e15aad45c040f1cf9c442c519b2aa47a4dfc29063243c21f8b838171701b4b73516944efc4b61fb5bca63c3ed12a123f55b832e6c312e8bc48f145d62953f5901f7530068f2c9c9f51ca8fcb342852936d414fddc2c04f551c827071f99c7c24c991f9c97e10e051694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0bb1c2d3e859d3eb03c0a23b290518ef88ce1bb02fe71399ef71b380ec1aec4c7c6bf3830c1b15f7718d0e471d10234393d94fbd3305abd09cdf070a0abc09d7497d2f9b939794b923eb3f28b40904a53a05216a526132d9f3cc64606b40f26434142645d79481a8316e8cb0a9321a4c530a0ad139ed5953168a4ac864c726874e1366ab09a249f251ce5b1a7f5ca60ad66375bfdbcfa3d7ad23a13649c03327d409fda64581cb00a696557945c58e96c1c889be648c4885958adea79ab212a0bb15506bf5635e437ecee47b60032b4273b8c96806639c87031b6e23b71996b4576626124281ae4ca0a8fc081e1c91667967b25f76c4f72624cb29bd0a865fd67a4dbf14acc7a09871bc7adeaab37b298f12b60b6372b741681627e4c8346c0d34392716ec173b1b711b1c0a1d010dca486bd5167223658a5c55bcd0739dcfe30dfcf9bd8aa45b3ca0b5a90243547767a1843e4c87922031819ef9249800c6db8b0270f9cb8f2624adf4199741870b0630e1bb1b325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310c51eb565baba36be54f6a3151a104911c38ef78e61f1654ef35b2c836c2321a52fac710d6b03811444de5b8403569c8ce0444ef615dad54ae5649e68ab437c00a2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee7c23607c0683a2826fbb4bad4a58ff6e3bb3122bcaa202e6a997c647886db545fe6b94e81456379e7550db446a43616808ac610c3abf273b02b1b748296a760d78f0418355f61ce2898ab3bf9069576827b80557d41000bb0cdf5881d660a7c2569613ad6575e4c528a7c5b9ec91365b05853ab200aaba1ca98aff17a845a209fe4932f30bac0a8873cf5da17f323375627adc4786e906010f6b91333112d0bea256d3a126eb39965db773e7c3daec35060ab2d782b9a7692bc40525171416e7a12163d36837ee3c731ecc38e7236ad09712b4144030213bb53258033a8eafa677fd8a2cc013c5ab46a33531968a9a6c5e6a89613aceec3a4cddca52cf00b21d85657599d21c80692018a07b061db607d7df491cfe59d90d43a6eb52453b2822c7bae0a3336833469764516ec106e8d6912c9c35432984514ea5eb9a65c3c0aa24173bb736723022a6c31f06236639a0e0a25713c5a7855399637aacdc033c0117447730747507b69bc7a3f84621167ac83e4b45ab03b613ac4bd7217abb799027b1a33f55a9b550b3857ca53438dcd157b103c9e5987636a96b26372851e703a9bd36d85e966fda580cc79af69772c2a9a7042363a3e3c116dc7711ed06fbf956dd06266329002630508b7d1ca73cbc853e62b23a02bff7404ebe390fcf58bd57262cf1044aa22225fb36446d44e1b8171aa67c415f96db0e109afa31fd00631bfa23f3b6c9c02b20dc3dc1ba6f30e6f20c9ec7471cef6996350bb87d43690c059065cacf697c63b6bc98c881d3ca56f07c34a5b0b10cab263bb75399d162db389206939b15df58448837e0d443b8df132c65bac83d2166c780132875fad888a1c53aea51661c135cea6956c2a4b87a53baefe726fdf09687f6cade7bc9ef5bc25dbdca95a0acc47e0caef22159af5b499fb6e8643c70803ba40a5938a422433053bdec4b729744b565066962046c5d2bd14f14bf0b4030be99a8a198b80b99ec939791bfc8572942e98d47b00814c6a85c39ae7323cebbf353439f3961f0abb687b4c18dd06b706db4350fc4a2e868229272f499709eb1450c2995d9b809e77e676b628aab0212475e602831a367d3948cdfb0d43eb0865eac55c516069893d09f24a8176a3beca0c6065abca0a3a2b3053da2a3bca6a7088f39d9bc8b1e685b67612413aa3b2ba4673b301cd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a8f134fd1cb590819a65190af53355a6483b6a9909bef36c76836c77168c679757ef404a8528cd569911d036c751d4ba4cb1c34b695caf487866cb1de5554196682d32285490a75fb5d18d3b40539adc4d9ad71452016a6fc7156b34014117bc0dc45eb319a1f85b642f7ca7a12164bc7a1feb9114a7c5ba8d7456cc08a883ac86100272b710b225e49de711115b418946f503586076411c6ca3ec11a5244774a27baacc543556582781b273bccab4326b4140b5643c86d310331bfb859f80062ad27e38ea1724dc4b7c3498a8601c11f25c99001db2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8ac2ce68b6b8b2e51fad7939979593f8f19e19b2c18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01a8065c6756e6ecb64de11fed0acefdd45fc50c1f51b045d8e096a9e77f10dc8e8349b5da9723a1829e2ee3cc0379942fc47841b81df7a94ec7f40bfc2b737d9725486316c2ec3e2b516dbf7cb4936217cd4b23e4422122854791a2cb136a1236677a4e42504ae43bfc93259441bc0d676f8932a757c087f806b59e6380197b37719a2fba88b64ca54fc69ac8e2b79df7154403249441d103f931a25283bcded4c8b51a7995655d49611ddb2ac406b28ab2a80342f51bb8126afd65412b06d0596622e5722465b846a52b47fc6b5842f12acd602ef9c74065d5940d2462f7d99d39ea5f62b46f9fe297f1c01f5183c73c3ccb63c564dbc4c1c60877960202d9369b750129d91060d1708f057811e68c47c4b68781c102f2765e093c94f6c43b784679c4257287680825fc5116cc04b489add5a009a3e65b09644d5a9a9745d249314c4693f017a6d5b054d07fde34cbde568ea6fb9bb56c8c5023142cd19eb2b3b0c6b8bdeedac8b78909b1bb1894b382e6fca4fcd63390cabfb4d516fb18526bb45a0f9a6aed971050788cdd044248839d954594259b562317cb163273b12b453638b70be1085e51c5ac0b6cdd15c218103e92c53750f107ada702d8725548ccc663947c3dd959811842b62b13f9a24b1b4a18f5691dc4cc331c362747f1654e1b785ad1c07443aea2f6006bd670d7128a8373c68aa36ffc59797ab3994bea35ce894466f0c64c061b5d48b9a18c5544dc0820479722795d77c85f161b865dba01a70cc9c00c15167aa35bf0a147147a81d540346489dc58926c975333cc3d286b4c529a2e3e6aa6d2225016a7126dcb46669c72c453bd745632e772bd2da7c1ca87318276ad21ebbb6c419ee2eaa46a733e3934c0ae933950da8fd2eccedf2919d7e8a6812897780275adf78e6dc21757c7a0a489cd8cd95126a569af7c67bf317b146743b0d32a6762103a13698120cf7d07b72be91177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516c5115c724af7cf05049a012c8e601e8b5237e1aa5652cc5e4e1a6d0504331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8152641a683dd690d4ac3edf0261200cd9244ae7dab962eca2f3d22a554d0802eeac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 8c37340c59cfd8a543f9b76adfa38a34ceb4001269edb19d3acadfafb41bb5aa7c1b734e46de5046954fcc6188dc046bab996c1900dbdeafb72d1f8a3c4f51f6d118755cbccbc597f525cb827657dfb2ce3489b53e2a5ea10f73bbf1531770483ddd4083164e64620ab483ebed4a0b49e7b282dc0ddfd8fe3904d7c3d168112c7bdf0694a44be82782a024a105c11bd8a1401bbb5d0f97b23026d88449ab41d5ad616d647ba7b31228e3edc05c529a0cb081a5c1d8f12d4a6f0a6ee2ae3271982a5ee9ba9e06c0d931067b13fda615d30168c29add7a3dedd4ba1069bc58a56e66eb04f21cd3caa5b3e7655ba88d19f2a8060d2ab31b1cd73eb31a428bc421c8d27cb9c03bc9f866b6250488f73bb5ec1a9851c3607316c9ae0b47b39f2729af9fce32f8e1cef63bc167862365c8f18f36a559f6b91ee35d827135018c9a0dcd7431778996ebe3a4fd009c0f4d8e94c6d8089960d5c16f152d84139989836c86d1c4267322325a93025912dbfe11042d5cdd2e01ca8468f3dd86f29a7f33de0746a5c53eadf5d4c85a9de76e2b8ae4e4175bec7145803e5d6d57625fcc23186d1df1ff08c646dc416fed539b91443702331b8b46a1ff6e33573f474eecece71cfbea722f0be68fb6c99d815f626eb15eeacae5333dbe5479c29fb82b1e4b59350c5123a373b5f581085f3e388539f76864184596bc37424aff1ff26feda8833966286234e6f81a759a47f2b79aec8de967c4527f12ba414d887e19bfa224c99def53b9f66f44b695b5d24230e2440e0bba3114f6553c85df67c850632cdee289df39185af65b65be5e25f4bd27feb4d0c619b54a38aa8c5d665500d6243dac963407b7b667d492b497ca639ebe0471364473eb95886288b1663afc1dda99927674fcf7ffeba9dce8f76f0900f64957948373eed776996786d3d91d42dc1c7552d82ed2f0777d0d231736e4f05c24785ab0b40dc3fbedd959948a515be53cdaf1fa044033561721ac7a3f930ddadb812e6051e067d8e0883d2421ca6564802d02abdcf4ebaa9f94eb6f59f56306be7f265d4f676c58a72e78427258d4d011329708763d7b2f2aaa69de494d389eef0025d09015c4061e558ba2137b8051aa037694cedf59380fe62e0c5c8cbc0d80b2d72d7ee1d61ce81d5305ca9d35bdbdebd159136284eac79117dd4065e80f0a72ae43236caf71ce09c61cbd9023042e6eb8499b6463d409bb94b2886fc8d59b7765321485ef64f8fb4455fd0c1f14597e9b90a62f38123888fbdf6e1d4dfe730c769d1521db0e29bcba50d4fb447417c4c2b838f5984af13edba3d9b5b547177629749461fde7fb5b3fd72837445c8779588bb88ed67a44a253449d6e20f2dce29e484b19d1b1bd4aae5466c212b84a626ea97a9d6a9787da5c5eda1f41c34cabb8cabc4d05484391f6140129a260f96133f2118782e242409532e4d48931c3120903b2a6cd728a22accfdf2ffd81d1defc60ae9bb8f60caeefe7fe12dcefe951b5362b1d068f7af1c4e3c7d37046f7bfa8c10fa1f21f18101b57a77b7d76df2a6630697d2c6dd772453b2b7fd0833ba67369de9c6eca2bf94d8fe31997ca6cee22ca2874bbc87ebf3fb0edeaa88fe262c355b5aa21b6bc8a42ab18a48bc5c30efe96fa75769f4a2d2fcbb872b6ed8f616b1b05f53c4072812dee5f09d33a38fa51cbf08239dd806806421ed0118f411fe38f9d4256b2b110101aa7bacf01e0079af5a8b60d8aa1a179a6189120a00678e29255eeb4c77f2d8453d73accc226fa0dca7ba6b00aa8a27dc2647dd8f163cdf8c6de93251c1ff97396fcf80ee7cb0fb249192760baddaee22b2d8ba73a38cd71da3b78ea2b107d6e85c2f637faec470377e064a61670437d8ab58be9937bbfac5c060f365b2200e637bfcec0844de7621f2c438727048005fef0b4c08a99e86397c7de530cd4014b055b8b66013477e8d0f0b009aad118448e233ec2b8b6beb3bfcf9e60bdcd541c910e8d8bb72b56c0946c95ecb9167174bfa90cbf2b03a0d7b6250e4793694cb48a8d299780aac15e40ab66d4d18dcd634dcb0e09894ad42c5cee716cef46fcc1be68d52342be20c43c98af395636b0c5f33d261d16a921adad7a0b88dbe8650b5a6ebb6c18be5a4615087817fd96bf0d0c96d74f9e7f3e06a2b3d5e2843159e26b90ca7b5995f62ba2b6ca3819b61e34a70129d9b3a1b5de +expected_result = pass +expected_shared_secret = 368a5e417f4fc728f5080e8fe206ca7558909f6537f1012a58b2d9d45b7c6a8e + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +private_key = ab4545850434076342eae8409fe0590c34955e860267305fca05c347bb3e53bc714e3134a6e9b338674a9aabb02f021d1a09a190757f03d573c27687f7e35f2d77294d10cded732218395b344523f1b704b27689dcc286b5c98217f239c159ae5d655436f00517a50c6dc6b7f4f111e7f37a0f319bf6acc7b0e3345c9367b2a2b8d9d644936220c0a817fbb38ceb3469cd55c661e1c58d06807504443448c4e53204dc59c60a5153494478eb4056c9a85967a42ebbc287afda51fdd6b84b285523d41d80a56f7a68a168a4527d902311b18d5e381cfdd578bb7924fe687d3aea5607906815181171a727e4dbce1b678762a8b03c2a2bff1635ca85332ae90f14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83b90bec27172ac85154ef27b91623841e188d76b040f958c38c8a112c05b54103e55a159de0954f2477e798a573339508b7c2ac3872a623429777ba3179060135c083e2198d1e0aa01967c39c27372a1a36a92bac3bb13ee3c94b1f0391e2702c50253dd497f16f39bdcb9c68ccaab6312084884b113e70f38555422767f4e613b2e87affc01395fca37df0a1aef74263c1001392732d9d1047cc7c6fb910ae6136c33094526876a113514f2918909532a759617dbe2c97e72176490995dc82b663655df65324b1996a42150be41b2a1c90f03b2a6f04174da1b1cc7fbb024c3c972b9714300c683c28a90f48b01c28607922c3ed25601a609673481b365544b7c36a9550ef20c37005b0e395a268e90ce1a5271e1421b46303b80cbcc81e2894d7569e82c2f5d8c6996c766bc505976628cadd84a3f468c67c209117c8254bbaa1ba584dc2661728a69e959949ed6c9f1b42f01ec8e55614aeb7168cfbb5e16504eb9f585c7789c48e59c17b5975c444bd6e32a6654bce298a605043bd367400c14b1d8e1a592a034543c04a44c85711aa66c807fb07378fb525600c19d9a4a9a8c920ba7db0b1d912a45f2b6d518b469e9121d25cf40499196376d3d92827e1b96ae255aff288037793c7db07e1d15533c07162aacae3255c0cc368e2fba3fef09540952910eac0fb2f3ae376aa666fc97a3e122570ccf797c79ec575835e0be6e808b3cb1b72d8241c3679bf15020b6a63be65b95a2c9147eb98c6553c71c550e37603e6b73c877c94e7b603a22eca456c1409d5aa049673d0ea17c123b1835692253fcb589186baa498f39481c3d0640a4d34931033b30f26ebed6ca9c49ba6fb219d6dc8461937284235a6417cc9c0ca0ad385b04b01c81d5a7b97a34977250e3679ac55c3d76d83b1f7b99dba039dc179147223b5d6c11fc9109dc062a1e4b7c88c710c449320949bb4405b28ea2c04d48c58aabb46edaa58e442f3ab6c9810b6d702855f7ca91af71b0e574bac1040dbe864ddaa76827874839414cf3418d1702c6f368a10714cb25e208c8a5779f639837a07e348841a11714f41399da175c49678307d3634d6b9921880fd43ccb8d7842e5f34ce44a4923e7ce6b671c7a989aa748604d147ce7ac25a1533e80ab321b7aacb8d523a3a6298beb0cfda435d77714993173d080827fb07b7855769eba987696afdf58231f361d2164277bbcb26debb43d1395a23a8d890a2cd71362e2340eb68b84f0b23345d1c449353528c2998584941722a304677008da1a13f8c8fb0687cdf688c707a73d121ef5c609c2150c1ad346a2f85fe3f58aad4280f92c35125345610b901c305f6042aca2f6cc2a4a0d1ea46e378098125b1956f12f54154023549d64d799d6972e3b283108e779028c1f7339a9c3d8676ce316ec9b9f09d654d8b84ac1d26223b36aedb584084855374b0562a113d02cce4bc1ad3ee1b69cd76efd0504b48724d25c3416fc2d12eb58f174a9278a6620856763744a1f863bae4504c779571d83849a88c023f15ce838b524a9c450e2b8592b98b4c89ceb35990bd39b74b87cef750aed976f40bbafa6f03c531b0a9c47ac22fb2b24609324f262e3233274f088e05181b9ab973a4c727ef53d40f914bae5c99d919537e67ec61061c7b61b7d17b72eca748894a25a5a97d5876d4608bf5c2b55fd85243b1117fb907843e47c83d29e51a11d53419051461bce776c040c848cb8522fd2c14880b87fa970873b8f3c2199c59446aa08c7646c1f567ac35c18b82cb24ab1c51f2ce8a79ba51f432672ccf12c23a5750e9c9a6818b628a49a812377587323b1e63d8f21a9dfc76095827cfe352667c16e888b1a621736c28c8acea052f8c4618591b36650a63cf00b904120ce716fcfb40db52347b12486442267bea46c1b778a98268481155c53a72c5731ac2ee36fb72c61b60273d1419ab8e82611921c99dbcd4e209d2af64a08ac27bcd21fb7b9373f8a84241a1bad24c8dc11203b3554ac802dcd18104dc8833a4b60edb07f9135b452209b65229bef0ba922cc60e32954096794b7248f94b134143b0ab3a8c2288a6065e7adf5049e918b3447ac156bd462a204a6d8d680761b9e70d8796fa149dbd45509b6169bc34ea8b876d30c7a2e51943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397db06693c20cd7caa079576834a0991761c79fb660843778229b2af530276c345ef8c420ee395455ab47df46609b0bd34e2aa7f35af596750c71c4aa2754afdc48481a018f2499fae61584eca38f331c571bcbf73ac01b349953081908979499f2bcd6939b81a5199fb5838324928372aa2efb6c8da025873318c08117fcf47302fe99a31b923ba947871c6ad7168246341ae1c567f8706b88f240473a646173a58d559cb5d3865f2072d99b78cb7d63617fc05dd16391830cc22e2ccdec55c46f84262f59d1718c473626f55c8022849935b3a32f55180dd7b67cf496c999189d177cceeda613721718b0a2e74e0301e667ae8aa36d83298b2983054a3824d64097e380585c4288be24e5e711f09e72d31d29164fb34ec7068987241266587a367b067284f3595663f927255c66bc7c79e5575744500792e8236288a432b092597069182c28667c51b76c4a422dc8a023127b58979290043cc79011205cc7e61aed141bcb4c090a6405263e3c9d613a5d1b5b7e0a8c5915611fef213eb4a9891d49f303967ec3ac40ee145e8724e8ae90c6eab8edf970fddb459b66b654c8c1fe039ce07ebb50e441bbe386ac39473b9a6a26f0ba3799155bf047ed33a56eda493c26b6bfa912cd56623b18254d84c3e8e34a23b3948d4579d1dc301706c835d879787cc5964334e52875836e4b105fb9abb613bb3ac9a65ba8f39470e3aa20bdb1741f1f78d527555e10caac4e17f57e89a520514716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df76281d4515e4229547d235be6b6925063cc3832e08d192b6193d6c02a0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fcf819403ca08684a418c04e6e6397cad03b77b2bf3624b89d176f87c82508c9cb13d60b9b3194ff52a7b58413088b2964b2b92b94463f2cbd92444a888154410990c2d5c018916b5f7059c2087cdae1bf06942d05d997bbcb289bfb0725db84f6e23c96da5c64595e96969097b8b9a28c5adbe36093203f01039a0ada6e63a21d22794405940142e0c959bc624619b964dc6b60a1cd31dc99c4342d1ed67c534570a658361376378e82896f216e57c21159967212481845c112fe0a3b1b4b888ce4c22b3c73fb87084d645359a23d7929704738af9ee7abaeac15cd8c6d87295f849341bdf68b24a85621f397fcd31a209b3089151bd44c9d90092ebd2844fe173392a8836876ccd9d97cad570bfb55523cc7763502acc4d337e8634f97647f4a0996514264b0a3c6681022b739a66a98b92cd0577cf1906bf72cfdb23605169d0ef37ab96baa1aac1322149bf682025c3bb7adcc79c1a9c8fb52c3d4b529fda48997bb71d18a3d4fd201000c4648b634778b7a5ff190a27c1e631381b777ac0e858db4033509c66bf1bba3a5828fb7f578e8fa51c7c87bfca883ea96a968d78bf312983e6ba51bd05617c90a1677159ddb6d4ffb62b8642e56eca75cba3f9d810102037b2c57c7502a60831b15b49c87b7a14fceb228d2f0b82e1a5cb632b8d3070560977b24d591e7cc0c07017a09104d2ee24e6dc2c3af1231af922d62629c32481bfbe309d5a0cb4b61c2eccc7e9bf05fad1a7fcfc3635192c90d76668fc91a297cba04621dfefa729996bd118a308491b59c16cb7077456b0b48da4757f23b90253ca5a2c1aea9a524e08293d77022f66b5707aa4f30f6b099332cdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab9cc95efe512c84010ccd7118a92522cead44cff28d6e223f76702a47694c8f053fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = 492ddd4ed467d0e58e5e369c7fc26bdc88d83193f7e8cac9bef9348f3eaebf7b621de26c223fb6d9a0906bfe41bea0489292f6f9ecfb668712d2b13b7581529e77bbe52c7484ef70307bf56f5c1eebd6ff89a501e67fc0434ea4410ecc496a534a4e930965ba6827b45624eb6155678aee08fa5ad5a8c28f4d00becd89f0caa1463a029138eeb409e3ee86fce90a53500d04ece098620e7dbc6ed6ba67626c22948078113599f0a6ffeccde84f9570a3744566aa5541048fe51bba811d2f2fc0cf6681dc19c854b7e115b02962339cce2bfecb378c5a38cc4cdbe150fee1364746da4950927b1a48957f7c3dfcc836eff46505d61502bfb5d15e4b88f335e8cb9136294b6a9cec1ddf86d0974e6fec6d1768b27915604b1c73b65f019c8521ead40fc262f87319cbda47dddd387d6663dc06e6eb730bc06508d33cfe7f19d0cb8a25cadfcc96dd330ebe536c8c01838006aceadefddddb9da6cafbf1e2c3788edf391ef0a044d2c30a18458de6bd9fa993500333526b171148b48e5dec630313469c2f95138669f6b7c51e68bf67d4b95faf4b53f62ad0d1e38eab35af79fe7b3dcda2829046e20f2176e3003a3ec9ee87c351285eeb0980affe05e4d4404c8c122e1d9d3280e3af34d98d153cb0ddc25b88f16b3632d46dc187a0514b10262060a59867ce8fe781ca067958ddad2aadc69006eb980bab6a1fb515dab615edc771e5486ea24edc602c4526c785d0040026bf193d80e68e49b9c00cb00dccf3b3d9fcf59856fcd3c077b1b62abcc2f4b5a173b0716f833c34e1d5f33fe11010a02d56ec905b475212e01cb7cbfd47cd389222d7865ca484ff9bc6beacfe18dd9543e1cc7ec5e925e77ab33b5fee26c62943f8e95cb5551c21990ab63b33ca50ee4e2c4159ca4fbb5953ce7101a172d1a6b51a92cb7d80708625897f09c71ac2dd8491b0f40d3b287b3e2ad547557b21e47531d4029cdce70b580411ef0a5107491e8fe60d01b44d9849fef9c4e07a21110913ee320fe001102b986241fc6e914052e833271c6fd9921be7d794745af164e3a9851d3396f4544142b5c6f560d5f68c2b5c7dbe71eda07a4c4072c2f33636b36f457546ab81de8329661a008d94bccfceaafdf421c8c46a00fe0e9ebf20a335661cdf6d3ca61b8e3994f1f442f9598b93aca6fec36e524437a903a9fe356cd34b3d37809f93c702799066ee40df443492d934c8ccbf961f5b9a2522a139194f0e2f6b6e3b2ae2bf7df843b13a66a9e4786851d3996fe808ffe7196cf729d093a115fd8776c411c87a7aab196d1dd83abe6483d1e5edbefb09f40a24acd610a4937f41aacb9f50d4b2e122ed9ccdb0d62dc278dfc710620a291281f5738439a4b3af19d5264e3c3bc69be681349bb4aa03617a3299e433ed6e2c66f7dd2896910b65d365c9c157a49f703cd64a20c40f05f11dce7621e16ae9ce148f1463cd695bc0387a378bf659f6ccb8594e9a5d3f38b5e68739306198f5cfcaec603de5f2ef125b16bb2e8804e0df41c98dffc1e4c5949524c491eb882790474b98dc348e1d4b0414a30631500c85ee203852db7ae58892c7aea3415ddd854001b07a0c3fee2ea7414b4a7bad71ca71b4451b7257a04ce9e0be5f416e4bfb69abab2f717b1bbd795ff53346ad025933fc88cb3753685206fc1eaff473c2637dd3b9ee29998902f0456fdfdaf6d267499d1bc3e3cade385509bbd86c03af612f1e9d458cf134aab214d44774b591e3f8f32160bc8800fb83976235253cf0e3f21ac0cdb92fe209071077809ec7486edd35dba646a00205b91144441aab1dfb3b457b10ae14098c6154fb19e9f3ff083b2d199f272920e704718674c2ad1fa73507ac78e305c2a4f122bf13b9e9fb002ac128dab41cd10d123ee4f2b690e9083d66aa048e66dab4ef5c0bcb9583bead7e56542b172b21a03147de98de4e3c5292926cd96ff6a2740474d0d7d08dc8d2a42b34e9ea00f4e6188ec714158fa367ec7aba30af44b992cfa68018619a670f72bfc9363cc892e331fb05b4d54da38a3ee44556b3a848ae6f65c8f506171c3843f5943b0910116896a63c780a9678b4424a7527fbf2cb445f60d839b9b2f46878af32a7faed6ada4416377c8146468501cc2599bb20e674370d2ea13ab8754959d826706400091706ac63cc068871c98a8d3e9c29e18c150741fe5254d78b4c3558fcd8b8 +expected_result = pass +expected_shared_secret = 7d36e561b501a687939aa880285d32cd6d8b66e2e65b2a076d5aa516cb5b2e6c + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +private_key = d7e3338b3ca1d6118b7485bf85ab9e8f6c36e158b67d2c3530b0a544b8afaa0a8604710987429d0d1b1eaaba8f06422e992c475dc4cf909061efe673a3547575e8b00ba47d5a158c22e6b2c280b3152165a5a01a43d801e96791b6d99c92c0b0602c94c0b13f2672146a7044e4372c5fa8843fa7974692b0f292af9fc3b5793092c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe061509be046b3a048a73599ac20466f0707e9b46045352f94507659ba428cc6994ee3375b07d09ad3be1872c15692c7394626cfc01bf5435d7922bf9199533a22cc4ff021a97c571db311485b36e2a3344eb880c67819aea18b09919fbc57cbc11cb228f8c24f38a445c512245c3a5cbc65d20269ee849bc268899981b9f334704499b60a891139d9470a1a147f38470752c4eaec5b14d51817fcca22e7bc1c585cd2189131960a9e9284ac7940b2949707ec7a67f22db280775d8163394a3a9557bd48f50c26f177ffe83030a3455de1196a763f8af156df73ce3bd07ac70447573a79dd04a59e8b40e39c6fea736e14f1b1b67b5cf556c3adb29facfca4e6d8b759d37737863da2a7ac4a645a8f202ad61c17068385c21415f7e14146d896020b89cc73aad60135d5a3b94879184e086f1066a9f56041b6029d1f538fb5b18a7a741e04e2c158b69927a1a7708bcc411988c0c315d0d1bc3a31b0cd473fcd3abacb1bb3eb23224379b5350081efcb8c45584d3b845e2500420453718ad83194130983a355b1388bf246b9fe7400443c52629812fc1125c3800c3f824c0ff95bc24a2e8b306d5e3278fffc585843bbfcd06d2ec3482295717a5111aa7b6475040083106a01491cf981197eeb77d9b01c2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57cb0ecb3105d94715c7b1ba7800785edba95a7352583354b93cbef98c78bfa946a7431813ec36ac45488b170859c098b7c6813cab2ffb519814c3a9de3c254ed7a144fb6d15b183cb48a9021972233382fc8c388511add6a86837801f4bea0df0103b3a152648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f6717eaa18cb489b446d24f5ce239c79a6e34215e87bcb8461b5b509c895ec22f94c17c3bcc5904d968c469b200d3322b423761e3749556476d925a915971a62a5a330acbd106ad77da7897815cfa31cd44310d44915d762164b6170b2916b5427c694ff3340fb16b73500e92833ecc35bb25db6e652701d85ab215b366a173604c2797c2a9c420e069e7e4b3d1120dbd1c196d105211134478d23cc4428f8f56182ff3a51c7b84f01a08ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f7c06883c99c4ce934f9b04436d250ef262c42d4862b90c11f4924087469210a25cf4cb29d139d85d9c904004cb246348c60736d707b2b9b111c91acd3937d9e8934032746aa5025bcec8bf637936448a0dd67a27db2a74b60bba82bcc87d73d4a9033c427a85883613eda43829c7ca3c7a8f24364633610d8199a5ec8038d0b6686abbd47692ada94282c40799ed4bf8ecb65ee7c8b2047c41eb255318c139b89ce909831fe3024bac10b4110ca34f1bd752858a4c0c307537263723987f6c3e29918fe816ec4956c5b4b33d532367f14230b14357e94bbb7e8a947453e4eb606de4c695468c9b12458340cc59d0b23b01b2255173af1206383aabda0bb1fb76a65a814bb2a4a1a0108650617090c3a35ec675650745381e56658cbb71a81cc386bccef66cd599b1819629ee02015b4928a5d12838892333974877a2995bb2b73bf3b292da0ac34d26dbc501a2c20be0e054b8b0bc541ba92d135118a5a17c19a2b3501c60921b960e013f88ca623d4b37717ba5882bb3bda2bb146c42ca4b339a01fcff7c35ee467a4e7c282f175985bc07481bebf5395e0d3843759117459c2b7a45985a672657b787768c32cf37aca5a419743c70f48bb78d53f6d65b5d3d079907975b77698649292ab0c8c93938147b6afe695b9774881cb11ac88ac3a1321965e598b4e01b76114c6b47316657b01116412b0e4c5aeb29e0c1856382569fa800a91f6b7699928a12ab0bf92a395f643234c98b66501bb66b8ba4b88c516101594338ee57700b95ce6e334b7d4425651279153af42d2940a191c57e30e0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd4e0794d55bb26379871fa7692fc7fb61c8f0565916db30861a2a61b346986697690d16185753395060b229326681b16cd5b8069fb5498aac4ac9023adc380aaea764fd8625f765f5d73a1189a7524a6bdd1209a8a23bbc5d96c54b89b9f256d20f396b6f61e47e0989ac04cfb267b175a8b38395dc3e976feeba1967ace1c491733cb3b005580fbf666ff6093597cc59362cf60d074f6d33c3be33bd02bb0d3460abd45889cba06129ab11fe978d4749a675c32e2e9bb2d6816ce198bc5e67bd6069666c6b1ef780765664ef650c9847566e02c116f5318d1fb240a167a89b2381cb4cd7ad60eda125bfad338bfd668a008a9f9354999949ce5fc09aa21025a83cdb2c7cfdcbb3e03e0212d58b78e00ad85ca97e3f64a82e79d26053da439862eaabf9bba6a11f225ce27be4cb2ac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd8306370672f20f315474836509c93ea814c9c77a4366325d13c52b0d5a231d79ddf765e774c9c60f6a2f7b1377630be03149a31d7112e61b32296234678bebbe05bcc4857453858b06680399c699fd23a9f96b95f5978437b5d453704c32317beaa45222133d6cb8a5e984633081170c154d68674896911ce5014a9054c37901411ba72f77474b5591e0e1477705a3e1b535d4ed3b3c1d043de517b23035239a39694005c00ca332d9b5c98a16034550d4a92169966882bcb28f01171e276bb36f98dc3dca74058462f2caa4d5a9e60991f848b6c519c45332b18232b900d9787dc78a685360336b685d5301315923f8df99d34b8267932496ae4981a2cc94739cf075343de4231736b42d9866b0ce7030be42aca98309021b24a1a518dd0107c2b03a75552c169b605635323d9cfee4c607c656724b48f523a1ebee51393e1538dca234d864066f7417b1b67968a2c03f9b85255148a9409bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f63c1646e015d64066402a2a8f36b7c96e0a50ea13c220103194bb188c6947e533b1a173cdaf225eec27720a61bb3017205e98258fb470641633d955d14589bc566c9fce9590b6141f9c662baa60ceac1a7b0e518e370c27da21e2a098d62433f2fc336340851e2e536e0b2ae8c2b2b58057b5d30a8fab602c48ccfada926455549ee4c15f2369f58742d5fa85415990faab1b76eeaba47d05a0c35653b36192a6b108046bca55443fa075f072270e836293ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccab92446a09c8be6653f9398b4d5540e8544d56d5c88dd20ea99344b747304f56b2aa725f1a858eb7bbae293b891ca61c2d5942204455cb726c29a23231eacfac678dbd002ea8395203172b35a448ed3944bb07bd2e11b9fb52caca2213dd482159821ef5d9a98d09147e272d3a9b84023172d0d1ade55662b02a9574c13a5d5b79575c25c9d46bc5c766e4768836f787cc6a771a772518e7c5a2f4716e007900db8abc8a630916a268b080cf12ac427a02c474ad28caa73a5793bb0a7593913debfc4cd353ab92bb23d78a2822527e58f52f4d5a70b2f05eb0e6231dc43e5fb7c27bf6870181709f1b0ef4175753687a66261f32773dcc520c752ca7ad6344155bc63f000e1c18be1d154476a4a639d2ae5e36bbc157a7c7f8291b6506f12aa8003784927284fe1b1a4fb70aba9a39d0775dfa293f9a29a4fa3712fda54c41e45c6696aca509d09e42618164c34f78b5b385750ea93d39abbbac58640ce09e5a5245a37847c78765d731596bb10123f51793ea5d97c0321fb5810a22af50406e53806569c53750153ca7b49dddea12baf4ade371b4c7d05e29369a5d1c71ee1ba62db26c74b456cf30832018cfca235b32174c031c53b4c653ee205c632218ce05676f2878930334c2c284d7e3b73683cce303694e68bc7f95b0d186acf5101d95fb6ce55acda6743c7512638e42978af9037272a1a5e23e3632059ee1a3367ca9bacb27930700d19327a0c6ac9fb57d3e41bedcdcc47efc18653c2c5cd78200ac77b066b018d137facac920790bc9e593cc243761cab947818e8ad7ae6701601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e977918b12f00bf09aec2b492cf53686beb31c558d0493cc7b2b9a9dc7265fa9edb685d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = 698d515fcb3a6cae5c7489af712c4417864c849109264cde1dbffbe903630ba3fe59f0201fadbcd93708918530542cbf035b3f6e863476d736a80f413550e52998bc8f525d9d18d1cace1087b7a06e5c2257aa7fd93d6050f8da704e2694b73d17cbf356f974e415eb55e9f445e12f2fe78e69000879bb91a281f7a6062fa4994cb8c6096bb28da068b1e611340c5d0c2f12fbd20fad155361c019dcfbd101e478008a500d7492655c9baa4f04af597cc67e49705ae03b670ca112e2eb718cdf7399be05eee4e8fc14fb100b5ce1c024c8df11db2ca992b0560826e81cc5a18079d1a45e84648616d284fdad7a6fad5bfd59659d967208ec7e2a9fec243790401f85e0e7d147abfa0e585edf00e4a4341ffbd923038f2d43db27b0ce197f24302ce668743490068edf8dfe829786187f95a92a97bbb652135138945d279814ca80f2b7534f6c4009e1e806a4908712bded1b98d2caac89f1691a0f0a3e8072860705196b73292c9caa1994cd72ba5c721b01d9d94e0bed202084577bad20fb3d7f090a1dd156571964131ea5af05a12af20c39de5f8d4157e564e0653b3e0aa5c6fd8fa1bfe72e70b163eba1faad62164c4f05d7cb1caa1d1d9b973de2c10e439ca4c4cedc8dbed545de21722f0c0dcfb17f8d3e3abb197e7456c804ed7d6350eda067f2904ed9037f2d8cab1b53bffcaf42f20b05677a9cea30be46618c75e5c0b943be4c03e613f9676b5b49384ecfb9603bb0087129610df0530d83c742aa5dd4bdf93d18a816f02984c0e7a1014a03822f69b99c48fb63c578b17bcf190af9e1b6531fb739d1e5e67722c8956e0452f2d6bd4a2ef2c9007ec2c9d32ec193540c67911731b97e101e37f3dd3e6e5e5ac0e12ecdbd154d47fa0a55cbdef4cf77e2d95125910f95352717c33c8b62672f03f04cc60b0052b23f42ada97ca43a614bd1cc1aeed6978a841420236ce6b768937175ca9e95795ebffabba193397affa7328e14d8028252feb88f923d8e3ebe84e9e435d7c273425ddcda52740db716cb319de921a2330b7fec204a562386a72e36c8d01f3814a37e5cf0e1270ab565fbb4154193c1b35093448fa215de9ad83454db5a442c68077b0928bf3b10e1e5ea220fc655d31e47307bfd09cfefb9f6a469502390452af9dd459719f51fba3c3cfd40895b27495f8d4d8ba7351be43c908b8d6f71d060f3410abb5b8d34592ce663893cd6d6cfe31fa16dc93d156248cbf320ff7bc6f5167589e1688a7ca2474822fd408d29b5c637c82ae85098accc55e1439b96180d0b0e03c5766c880233741541ce1330f84ce1969ba735e22a20578265751e76fdac1cf15e7fd64e838131f69132079a12a104e330728a3951c18b4a1b45ecaf81368983fc31da091c708c910b608cff0798abba8812c07af6af07d274f046fb0a4fbf74a20467c6059a9a43474e7587c27e009b74ef4720fc9773748042dce5e17f3c1b0bd203e629f28611776530858e34493779604f1cabd13aed8b20ce2023425ccfe9bf1be4e38ec0c650b9ac6b804ccedcd0713a895f673bccba4c7cb06dc3e6c70a92da9986bfadf9ac0efa5685c45594edf0e40cdcd369f5ce2a845b4a43d27ec464ee8790a27e669f793c8bcad4fc9b8aef359ff16492bf65ed42edcfb3d81f38eeda496c50c118ac5450fd4bc7b5339c9664b32492ad9c5e94502f9c032f06640ebadcf5d345b5460d07e3f415d5982e073c36a5fa497d904d574cd571c0dbbac1fa0649166c04e70a9bf061ecf15b63befb0ceb7a62465c3bc27087fa3c61ea7f8f005f667727e9ac51b37f915439cc1ccb017dcd2e99e48506429060d3ee8f3db5db83301a1bcda31d05f68b95236ad1ddd47204564d3d9999aa3e46eacd30073d4bee95faa12a91a744e75720365f951e1292d891f94dd86c1ae951ec261b1164a796a316f026f5fd6b07d3d8984dbf82cad3b4ab0e3c3eea8fa7975765b35452d6d08e7e875e7af3870a4cf4e5b14cccb6292f859169ccbd43f915da362e7efecd46c61c65916ca1a39e2c0c9447e924dca74be8d0eb36b5f3be4028ebeb1e7f72c982054b6807f77d64c25689ff1b70098f1ce980f211c61d5b297ca7736325d0b8eed6ff2844dd954f7cb26b9be8c2ce00a73c876915a1fdd3094f0d85797a8df245a31624b484b270e4f39920943c6920714e86c5b6d3c32eb6dd6ead82d44584 +expected_result = pass +expected_shared_secret = 6be99cc08c8bf10372f7d5c27bc3ecd17ade8afb967aad41a1b33c0ff848a1be + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +private_key = d338b8576c1fd9168551a681f9c590095b6b8d8474f571226a4b68ee81a83738bb964356edb663d925960388c92896029a201ec7f046cde497e3384f613a444634aa3c41656c6031d5233720241603612bec1032afa7b3d41242ce374c8b118cf6219fb5e645002530781cb4660403f88287d115baaa07ce95496a7232862282a653367fbbca1e337155a3c8905e368c1974418e735f93b6965fec11ce7b43d81710d727a4c4b434003b9110d013568b7bbfb341212543031c862fac505944b86394554772047b2a864a6675ed984583269362759cbb464e7e248a48c3554b8054ed9342aedc8e221439f812697b691bd5c89b7fb11ec716bff96c97dd73c45b00980bc6b1f69117c2329386518058e97b26626d98196025724baf0c5729109399e035ace9a630cb6d7ca9cbc16ab560da5c01e37601bc0dca7a3af891b80418c0056145c7ac8c176605411a39bfe843cafb4fa61463b20a504e984308f2b82ca7081a97951d0961b2664e2d7b41df902571d02c1fe24ec0ea998609248cf51cf2f81d96a983dbd29bb37b9a7d559c72fc0baae894583a842fcac92d910c7d682dde70a4a7b26e3259b290a182392cbe36b68d2e321708e9c00d8c06dca5043c1a461e76438b7801e8faca17045b272b16999471f8fb42f53a43294124c3b2b7f7a13eee8b195a01871909a70e41a0cedb37f3f733ee259f40c1cd12c79daf90788d78ceaaab9e1d20b7ff8800a17ac28953a4e90b257d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a59822bc6382b9cdc6072f0a6cf65c9dff2309d1a433ac52e6cbab472e788f76558d57986bac5c79b921f06e509db18c70ee88af044b527e221e5a5105a19610f059fbf6009b985190ac81640607cc4fb69d4892b5d9ac12bac26765aad5c874fe3080beff77961cb9e747a8e4b4acaf3f3b81d51a4a755ae8ef2994e8a722dcb5b8014c1ccdc6a79046664c3b75c02b91e0b4c5c250b8eda5d67e9a0984a6052053d22266b2413b98d841e8aa686f4e0aeb8d5b2ed2c8bbddb0374d0ad8cd47a0e6945f0ac352307ac0db224eba29bc09397f05b1308828cd42b85c556bf0a938959fa7cde083d3d0163c21b016133145ae0c47ef73604999e76f9ad19432f82e762ba8174f89a23d09333f7e677f33bc15bf996ae6999ada8747bb0c454412c2b651d2a90382937427ea555b3856d0250ab1e3663b8d78f3d96cf9eb90b5a501129715df5db38086076c4b351305a9718903abf12609fb1bc8a59162e2152f8e0c62241ca5deb5260d71ae162b7ea827a342584576b00dc674a5be149c7744d7ff43a5b04a3ebd38c110630ff656f2ff042eb603403d14f18eb17cf675c995c2790e936cf8b60e758484bc04314e50105b28346829077aaaca72acb46d331e9127b17dcae5e639d2b33b9f3cca468f731bf0b332ba41d196ab77b3c436702078730369cf59144540ea08b5025a4c880c1530f40a852e35f96519c91eaa680d90d25a4256feb1878b48e39143ce43378eb3335d3e03f2a358782e0b54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf29e1472c26b4d7f80e4bb3192de06ec05a6a85479e1fb34c240cb0164b0170c151d330cfa3103f41183e458a4c15b414a043a1b7590ad2c79cd3d39e2e6655f17a1497f35c801064b95912349c8878c910ba7bbe3fb25488947315b4aa1c5c10870b0c81b8ca3f6472d89638c2d283efd290ee108a9abb71d353aa512a5601f67e02b5b9074881ff96650b9bca29db27bb8a2f84f09069c75ef6e42f5c989d3229b759908262818215958d1bbc1a40dcce324a5b5a18cde861c2ea085641a814be004e5435a837f0cf7326710fe73bfee27a0a739ef5c08204c3a98ab98a1ba865c51a82aea57f1c3a62c12b7cdebc6a87ba13df51a1ede668797199b5943cf5a6c595452e627b27c3554a92b4488a476d28348124f0ceb2a29a2ea926cc656496b4656b4c0323361483469bd183604d1ccdcbf8a25d05adc1344c1315263f46a5c37ba98a96179b5aaea3d14b7a7bb6c6cb4a1d068f6809938f5a55877137542642cd3a06b03400d02cc9fbe83a94b63441fa1c28f42de5c81583d19c846020fb17ae65b1512580bb4d066c536926f7d571b7fa152b25c460c63c4d18ad733422163c0e26ba99530074269c212f2697f2073bcac61e4e603b18b575bf696d7feb8724400848f05e91186052b05ac7828127802fbd1672b3fb45ff418374d61f1aca1c1b93af018cb60f006d04418088216844b29f9b64bd46710657ca30a054bb1bb0161a857edab220813170d1cb96f3d82365317cfee94eb1a8ba6bf82af10acbe3626c7284b622b314d72469ebc76d3ad8cceaa93e08793490ea0a73408a1cdbb066b67d1351af5a6c477d2b90b68a3982b70d32346cbdb15ef09736b28c23cbe03d18998270013509f13c7eb95d5a03895301cf2d0cbece1908b3c28e73e676304b0c98f7932bc246107ac07b27090c2779ea2b8c987b084d86bcc40496a1c44c751438af5951acf276b25414d4e37aafa3a1fa5b8fb0fa11be21bc76b7816aa3a1df142446aac524a6a41aa3411e00609f297e698026f852094e2a2e5e9146f812c283529e16256050204ad3b03f04e35af7d36799605903e8c3e2663f9e89791aa8cbf1b8047f2a159dd909d01a3eb3f081a930b26b6b3c32b7172b77bbaaf1ad51401c645b63828842ea7b7803f9699740cac72b56f434ab7e1c09b4ac5368dc559d603c5aa471cd673bac5abf0f858dbc672e16f819149094f2b144d008c06ba0c36ab2a61053629f994fc233a38576a7821229e79685c2147b7b15156493c1eaa2c087134f1222758b00b3cc10804561b24974742c2aa016e23cb19c868244c65371b6bbf31d5603b46e58bebf638fb7924ef4181d02f6a1da6321a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533d62b8d31889e6679251560d0fbb4f768501aebaffcb116a23422f48ccd89e0c645a11b0f80ad2c77a2f30b8cf415084e5c9f655824eca8be8835a81a6c9832e09c3c596417657657a9c85a13a54d3c0d2c427a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9c92ab3ca1a8c47c89d1a742cbf4352b762a60226cbbbcb28272856b2bb3f176ab32955c96a0274723a508730aa94730f998ce0e04ce1e67726412233e8b96c31481bd017c67f1aea09a3e96f897b70b969cf405ba7424a0e8aea4b45c6206752c075e2bd3b3abc53f99f2842a459a55118a10f87d8f0c2caf4180ec741738d6a04efa30f9b3b9af587c33297bebf8778b960596bc3095439ef3448c11871d228a0dc24718f6c59c8c73234a641c47917b27b46cda986a1857315911673ba0468641757ec5ae71c860de0b5ebf05cf6889a170743a27350b19e406a77427421a54f1c163862a43c6ec1260d45139b7419b0538ae31a0ac78584b3264cca519ec35acd94c1ae5b436eaf82fecfac8681224fa810fb0a95581528ae300081efabd7e599517c21f469208f4daa500b9225560b9381707440082675293dba332ca00c4cf746f46041b78d219eda4bbbd32cf07e37e20e15c25f8a96b5706fcc71f620abbf052a572d73b24c5445715c77187a1baa883a714329d619a10cc2c9c84b2c4c098f0e42c4c00a77c44845b45003b7c1bc587a3f6c10d34269430765da39550e2b78fd7b97cd9128a5d8653b7aa05164101a9285a9c1a77a8b255d1b8533a1315a82bcf7e6620c4224ce830b83844bb16560d6ef98819e0ab4523acc16961229a0b0847410b19647ca7836345b275609d5d12bcdfa5163b0c4caaf2a0f05993ed16b89dc14d33a60b56a0a298e453a4883c7b6c7bd2186718da1a29895b2c066bc6a2896947431fb224ab31b11f204f8047bd5e421d92b78357694d8959991e56b6a123373c00463bc259f78a3c2e7b3526331323e9af2bb55726795fd904160c302242b1bd7d65103da1395d82aa5f662e4edbc812479b0b79ae15f25a07363080d887fe8a0df37b51b5ab7c3e878d21086ca0e1cc47d877194cad6e384a81403adf05c430d22d47516acdbc946498a281611bb9f73ac3424f6cac3146faae1611103ca4008fa95a8ebca35ae114ffe14921a855f5049447643c391588444217a510ae31b82b5c159c928ba434890aee2c7268724bbc29cfd152b05d73198e7b62b43b9b03e081cd0a1ea7395246cc890735268f189f21c143e5f5cec76692e6d937faac7af3abc5480464f8b077c9352b14a22dc65514caf392d1ec6c81d96c33175f5832ab3bc19c54229f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df7233c98fa4af17fd014a60d11ca5e929e4fa2524f7db289ce0947ad90657990c153b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = 02367918fa87d1732fa29e978c06713a66cfa5e50a7ed5644a3da67a89651567ecffc9bb1f79e1bf0f30091bf08256384f45f32e420a8a45bda4305bb231ae0f5ad834ee9ebb6f77b5ec136671eacb9054b02314866433f3c8bcf74a6be5dff9c968b9c167cbed7b843de055b7a7ac6fd2772eb79d66a34d08c9e811fb5d860d1d41c3195d02a731f0c5a0887547f980e7f02d5f90295f3916cfda43ddb1d66d66e486b5c6e27701cb1b749a1f30a7eca93e812dd462cc998e368f3d951d04fb09dd4eb78b43766d5c68abb4ef48d8d67bfcd404ff8b717dae7f2bb9a15912dc6d6670213af09db6aeccce8fe6b9943422c919222461001e5a068cbc250b9b3a67be2db1bdc169057719ad03b9f687bac14f406400f39cf8e6bd05465e632ca5f1e176af32d089746b31d9a95485b6ec3e360d6fca07ee469ece642fba8c325b81c6b70c71d5e2c8e4b8a35749c463e87d99e6746022e88eee7f0c27258bfd2ecde268c37625eb6c44c40a89ded03bbce4c055d21f727efe0a6bd1bbe15ac2a011ebee84cb8f18c6932d7fd687018f23532e0942af1422b634478de271a852ec157f9b5547641bd52123cb12453c4f14498fa423d797768b58d311818d68aee9282f8bbe43e010ab36e7132400838ff27266cddd2ca36b7acc576c1874556ef291b05a0d61cec2e56d9f1881907c3885e2133a999c064677ad323608645b7a5f8aeecbcec9086fd644e02b03c0dad7c2407dcc935a640a4bef943ca2b0caf4aab51d958a6b0ddc1f557e43089ccd669650b5e3039c9c100fb604c0d1cff6651b193b98fa04735223128ce84e1f6ea5010d9deee37af5d4a1884e2483c2c7019521e2e38179ed008530e339b26fecfdbb271fd4b8f5211130a7846e753ca108c15a938ae3cdaa85b82e2318a85d26f2849c6312a0649b2751d175c68c9021a839a70e11d947f5d4576ec6e5a1ef9ac9467e323bf751b60e0adde97b9bcc54668f6f579608e81491d9ea45129d83186e14a533c825cd01d8480e4bff0ac9a5b4f8171a6aa5acfa09b8518500e42b30d27f9f79e1f131391ef5477099534c28e1a80e3f50d1019fa671179765cc8d3e40a4572b27447f37dfc5950321c20512fcba0de91baf9eec84c914572334e3fbbe13f96455477110ff515a01aa51cd94039966f6930a90b80795d9ebd4a5fb9ab59ec285112d8bcf9a4d4b2cd3892cfa7231875319f00d36a5b274da937cc2744b8651565d3018a5ceb5286f814ecc734a3e2d86832f531482d3cfcaa850e573f6311b05d58a86cb38feec0d357acdc1de40cd909322568d72bb78b72091f99197b341e6274fc7834c7830a7e981957f030e8df6cd94994564352273a3d054b1ea8b4c8139e677490fd95ebe56544d2c6ddf83bf99ee3cd2edebcc1b068ab2d4cff003a8ee54532fab9bad522d0180d0a4908969af1086b749b892d0872f86068e06b414f4e4a68fbec43ee1cb97fc288590f9451cfc0863c7ba58007a6e773fd54c2d5e5a7f324a272bcf8668a399a51660839442674385c6192f1c805c7b3331a0328349c7e786c30fbf436fa209bd79e7beae00bc01cf2db5c4b54372c70503e32b3b473b44b0e71e480672641dc03427cf4f31f047542f2cf9cbb9c7e011d6e73a112a16d1be72a31191d0fa7aa8246995a1128750bb1e0a27384590a71c1db3eae7720989f09e1c085aca876b75185e562f33dd26fd4a0e41495bd24e7e7c40f5a0d013b403da4b75f212db1c8fc9d93ccd9b9f6dc6f9cf48ce83784e21e622a62eacda50ef89c11fdbf7522d11532ec6e0fc7ef0c8fcf97c859be5fb79080aa9a980c787b65e37b2c29820978632289d026fedf0ac6cd0f7f3774cf36cfe60b6f86bc87a339c2c8b32e372165959177395208942d1c37289ce83e3dd3c5cb29a600f49479daa034bb728d076fffd4c5507edb4c5d4e1c67412042952611c3cea42478081ae3fc011ec89c964d22db22be0f369b15880a18a703aa9072b6b4c041d35393c953b3237e8c7f86e1f650640b1a03863281b28350a21e7969fd6f374c9560c36a62c708c8d1986d511cf89dd38bea10df48824b037b513d3ec44cc89b1939671ac0b3e0159a703f4a6ebb3ca7c5f48ea8d3080d337fbc9491b4accb5ea5f64897ddc966cfe585abdd47022afab5dbe39e7cd6e36443e98f108059c29b3f1fdf83e53a186b53f608869ba31 +expected_result = pass +expected_shared_secret = f6fec6f62257d9a7041f119fff60f734c928e945fe131bf70338f273c0614ae9 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +private_key = 9bfc3a71fa83a4070db5064ada8410a770845e818c49b91e09a251e1925edb226ee8ab153f94b2417560d88959113a6bbc854b0065748e6a7db90977ada0216f3c41cff70e5202b306cc22ff8a138c360d75b9cb1bba849c5bcc8c9b55e80647e513c9e3e15f66a144f013822da24266765e3f1125f435bda4c46ef57430eae331e1d54c91960eeb363ca25387d0d441abb930e4a7c329191c5ff7a87996a4b1aa74162611e67b303e284c7098a65069356b55304b11b8bba66c5829647493c09bf62166017977a988333092efe98d9c13a2bce53f8ea2c81a0099b7d5c2b11704971366a5565cc14610df796c604700680226cb165e9acaa6ab507a923b4d472a4b6c9424e7f5a622f87f4f8a1083b4755067a93c285cc0748d241c7051971128cc5af4db5c1f7c144f98b6bf9703f5338628ca22df4b84d10312edda9df71442464a24491a62687928c22455dcc23eca964e9248543520790d813924cb58a0c156aafbcf63906ec5fa891936c7e16b5fafd98026d64ea2012bd75b6c5f376eeb74ae9b29cff7041c650b91a2b852c021562ba33b66ebacf787be40810f22aa43f4174571c77710f775d1719968a5523780b613262f94bc36b611b63f460dc6e02cc588af99f164302276b0386e697469c55928c0e62438c25af90577de0883cf45819262905ed30d9a1a7918b82f9b4a28ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d510245f8834e890662e06774f389c0c623be3212aae5accedb101c43463b68889ea9a2c21aa0acb5329ff80a336f8914fbc602e2b9ae452647777651ccc4bef70ac06423b66ec5982c861ad9723dfbc834ca6a6433174c1d6c1ab9569265a96ab5d48495d72122763b3a7275b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dacb140666610ec7a15ff18bc741aa69425508d5cf682bafb6d3c9dfe02d80349597f56fbebb7ec8031fe71b6d6c065c4e6b5e5d17abf3b412ded81efcc8b6b1935fb37b467a5cc61f318aed20678800726509baa73bba244030500050d4b23e4ad71349cb0877566ad100ba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ed80df4095d59ab482fab7fca432ef5e76affc77f74f4cda522a0085a4917d04167a00b09863850d6caa0621c2d473de0763b7d3168b6147bdb009eb260901fa82013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c43010ad15ea2eb1e05267029e5ad8139728a907b98761b65dd6dab895363159b48875fb6aa80882256a04460b2977280688745c5914c089b37bfc949a8f9864afec2e4dc13f6092070eb561d09b530eba2ccd66b87b0986adea1933448066521e28ac2ed9c57ede492799b401cdba8377d593dafc1a0d233004e25877242c30070779d8bc5bb488dd3988004b5a8554861b560ebaa5bfff7c89ded193ea077f421c216996c1445b165b912901b217315636a168c0216ac026fbbd4239858837b02dab5a39d1be6b072468a264661c5e34f42380c66526377c990092434bcb551a744227445c5108fcfc3cb4526d0b711dbd4539cea05a08a78fba723f314aa643a9260baa22b96842fa4995601c71dfb42a5719c6f3b9208b19728a8c085d28068412bbf3461dc09206feb7b1250607c1e33ac229323082cba12b139bb30eb21a5861d902c0e35cf2db3c227050cb8c309dd256ff4871186330be93492be78e267640b49776dc98adfc0197c896a1fa27af841351b5c790a6519f58c98bff08029fc09e3b960b6898577c92612d264833737c3e4aa1765c5d5b49bb12bc0df280890ec6b7ef55ac5fda82989603a7f513c5a41c04b341e1197b7d4049e2c01cdef47f27208a48aa0a2ba5706abb474c467897e154daea8410181c6d4cbbc9e73746d46d6f372fe6836d82da12a31b0673c10b35c9673d25830ed32ae795bb7d1aaf2cbc0433939a79d06dd33cb485a4bcde071b5c083978d78bd8e359181152fc535770548df0eb33a780c0c9e7bf907540a1f953c972b43527b0bc586b8b2abc865b9127caa4ea98a5de1aa2bdda772ab0702f983ec8a4231bf48c2fbb37a4247783bb0221098a15781c3dec95c1990b21c88cd1f911624600252759d3539de5422f470189bd6c462361c8105549370a09e8ccc407908a4e433813f73e3ae465cf99af30105e6e4456b899777236466f05bd36a05494b347457439cc9ac66557580ef049071c7922f3770b4220063139a607c8019b52708976d184949cd88714f18130f0a6c91ca38680863eb9be2542a4b27a629dec949e552d8b3c86883211ec341b637555c70a8fa503412a771853d32cf1a5939fd7b6eb012b26e414b14710a4639096025a95fb8cb581358379330999cb6b93527ceb079b134021c19c9122640f90c11c234f808ccbe17b3e031b1a7a94654f82289e2755ae38b9fcd477afe576bad2218ce692b51205f61a59e644808c011c0ee0ac36a050a4c158edc9c770444d310097235890f2d630f85c0ded24443462906fb84d7cac3e7c1777d08a57a689302e99a3d9302faa4c0dec854d4872579365bdd1645706c744fa5a167b563accd8097e8c626ae63c8280663a382c11ba8f6c1b95ff1161c3b5679ec6c661c2b8081c1c39f6c732dc97bbdbbacb133006a7c94de933aa19156811a224829769637a54b9512d8a4e82071af50a66ab52301241bc5206bab6bc0b29776a4b630e59e72988c4c7fd83912499175a2a3d3a2270edf3a2977049bac7524cd69691f59442db348243881e04b8e9f1adb4a436555c52f2f729c345ab278011cde73521172e8fbb5509746ae871cf0e72416c2482a280c348862b313c9686d37ff0d73a1e216ffcd936d2941fb5bc77a9b0b771354fed30ca16121514541b5124386b835c22540ee2f9b5970c1508e41dee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfbd05acf507686d53257c372dc8279e89669284c76294aa3098462efda8c743b0b7305bde0693d98048412907b2d2b27892397b9f3cd31dbaf9446598dc886a4e1bf0f9c39e9faa3aca90ae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd1150cbdfa3609708e4de5365013c819fbade55636f2a311d7a2b2ef7b250632774ff22ef2e76029569346266e70bbc82ec09533f8caf60c4356d1023b4b4532f7c1e5da18f4582d40b8861166885f52c0db58357e7579c7516f9da7046d3092303219f327ab52a28cb6a246b5016fa6894599d9725fc3c2af262b53a4592f881f2a195d5ae75bcd36c30d6b7646424c219302c4e5794057782e7034eec6c488395710c8211ef954f9f7434265590862b2219045b1336af22889abbb4639ba0758e28f2378cd1b1a4225b4171c53691a9cc5986a6c3ff51ff53b4ffe3c4eb8585006c8667bc17b3a28c67439ac5f3c08a6e93a926aaf515c24f8a7c3e3b2ab2f5183def46f8ac996e400acc320b49254042ac43c7cb160ff32ca605438d7124b5a727099f48008d60ea2e63f5bf9b81e3183e1647251017e82827620070c96a32fe122632c4aae1590623ac191bac113e9c3676ee645fb762b0ff982e416ca2aa343f607a70405720e9c42ffd815be984042b37d5f76646db400da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca541169058521c28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceebf916a882b66752a7a6e96dce612ef5754c392207b5b1c69d362134aab5513ca757aab9cfc94db5302510101a73b7cfeaf7a0f1d259893c76d9111652a4ac02348c285b94f16c671fe953e1bb0ca222a3ad751096a1a05bb2789c0c14da099e75477ed038849dbb19de489fab582910bc70a3a80c6f76152d494fa067186958191a5101051b6d55449dc5a4434925ca9f610ba498a24b232ac6aa08cf477a99f5a223067aa4c91a7749b834c90d6e247653c6b6db65c5efa72f3cd9cce1510437268cf92753db242742e042def3019f85188db7573a43830abab80d4c176ad551c5c5216870276160aa61b92863c1725083a56df800735c5428b28adc49b75da02bf120996be7ccf9e20d43dba59b6900bb50456d6589cb2c0209e51258336034566ae1bccfc1fb314afab759b00e103c0a7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d63661ad0651d0f3286d3f055d1a307aa7371ae1a74f1a68d57a7438e4b5107bc0dcd8c4de5736adfe3170f8a1f01535a3772229da4386b4acc072c1611b53c899352b5ab5b39bb9cd4ec72e622c946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f091210fb4f6fac00a24167d9bd2761e601db0a3734e3c835d1e9c5865b1e379caba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = 2a70bae622394c84f44a5b2e1118aa28f3583729e7e606575297aed9041b31dbd14dd2e8ce797923821c525a9b9ad87a39e411c20f4b4a98066e149c3baeea96d67d3ab839a7479b4bba6fc0b3e6da970b38fc057552665d129d26c4c3c1b8c4e7785c09822cdabefdf7a4f8fdd955aa35ead1e414d452c080b64d793a9f658e307339a18fd1881848c4b0a92fe4ec4b1c397b32f2c8ad5bef07d9bdb1f1366185f2065b497a8357167e9e91de6cb9cbea36737a1e3fdef09367a6c95fe23144017ccc6eb5b9981ab6a936fec5a2496584a196872a5e1c4acc1a50a8ab3dd714006a7314ca2250c1b2411c7b8cd552d99731eb84b321e421909c1e7ab9d1a61b1af37b9472edef61c6848305a8b6bbc0958677e1c0bb79122d2994c72616b4df68376924c1484e9ee20c65be4446776ab72b0422ca4f3cf5bec0c9c550de418edce654051221383923030c022b476cc3d95bec28fefa128350843ef7cc6a442cd76ba6fda38bb25a909ede689290887b73ec02ce5d1bb4253526fd4f7930ad4ce36f09f0257e6286cc4bffad656c9826a2cad7797c17bbce5c552442db8fafb01935b973076dab3e271835740d59c8663b44f1cbb3772f2fcd5197c52418bc4be1b928f68008e5671a753d335b202779a4e5ab3f8276422ed23fdc249a5c0923f6dc1d4d72ad6cdf270bf19539ac9001d3acea44a90a7d556bbddaf2aefcebe3e73a09d7882e74933e23b15b7d00a71b8ba1f77f32ccdb4950ce9b914d75e7184ef6fee73d9201e69c2acf0104b05b18e6b7068761992d333e51af8d7685246000f63fc5221679aa58e8f375b1c420b136e4cfe5aea6dab98f81892ad11181482378faec81805438ed4ca497b7c02bccd5320bcdeb94413f3a88a457890b7ae6b4879c091eaf8709112dc39a14ef0123040cecdd8a50a2538fd6cb1890b23300521b0fcef1150b1e53d8ce256e0b89f51ee6940aa6f9c4d3ee6aa2ba413747662ac01b35ca6b976df28147e1c4ad7b7b958f0ba86e092d71a100ec0060e9a5744127520f4995d6d0caa87786e2d44cb0d77789646c4a76c1f470fc4d18eed0cf365278025ac73f971b441011bf76dec7521aed395255cac3f03583b0d37fc206eef2370f8a13986c98660443a10a8cc56d7b905a46ec6cdddece9aecedbddfabf86362c3a2a4eea97d990e8938167eec639f90f7135c98cdff4fcba60176ea48bb15db19b8d6ed38edd8a7789ca9502c80f6fa1bd08707fe9b51f8110593c8203e305949ac9672f342151832fc890b86961ba408f1d82c051f7ca3e585d8dee88a429d44de29d93ee55a4bd9fd674ba1ad67534f0de5f9aa9c828b8128ba2f0b74724689264119cc8ce9a0431810a09422ac44904f6ca01e12fb0a10a39bd657dbe2045433822bc60f64960b83ab813720c120eaf14c76a58d04c2402785aa1833d885ead1dbc594cd0d110faf736f70852f76df0d1c877062bdf012c818b01b70a3b73dd3fb9634c724a137570c25a006b6a9eddb3ff7b91635bd5b734785c47a1c24092eb5bc480510784d8841da2d86087c2edea18e51c75af631c71a7130c40a999caf5c6235aa52accba8d650a282dc75a89d83e5402556020acd43141a07ac36bf8b754ae3a2b7e64565d361944555cab87ff26ae58a2cb7f3b29555df9cf983d290d448982e9a044073468484108012eb0a5e3e68b17271ea99706c5dc8b3dc364cc3eea2313b88ca5b7389be2c8a174e7a405a64a6655a67b7b4ea81a5e767244a5a63d45222ec03b0c3cc451599de35dd3167d5e0080d7bbeb0fa6077e6f5c4143fc083bd8dc4b029274fb87ce5eb13a79daf68d55c5bc2966ed34d13fb45a729d1483a186dd8061733ed71c6f6d7ae76607ecdbbc80b16520b08aca914f3fc5585fc8b0645efcecae66ff36dbf2ea87f9ebdbb591e56fcaeae56bf25d11448f5736fcdfdce09568b6ff335aa886c6256e518f39edf134f03f4a73876a43628f2b1697c04e4249684b6e6ae3f706dd1f7ad0c62ffd7e9eb7a12824a3b1854dea79050d5e647956f6e3a3e2871fac0f78d219cb40cd11bea041566c1cdbe9bbca5c4ee57115637380c9b82bcf938abe19af0a1a93b272e3892ed9d38a12eca97089720d05c3ca17fddba22d1432aaf02d63a7f804c7d2ba373b643faafa7c249a7a6078d95e770ffe1515cfafe746b0d649d28cbd54680bdcf468960 +expected_result = pass +expected_shared_secret = 9c56f6d91af6741ac13f241f8c960433c0ed4adcc86130877ecc1dbc10573bc5 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +private_key = 5e484946337e3f4135d738b0862b69f7b247a5bb0812d56201300c53bb87b798b2b551ccea75a87f002d7de7878ed08e976a2cb62b4aa559bc36816e9690973f608b262612f89b5bc784365e33193fe9013c05818e0a7151297ea53c95089388be203071d0335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92914137c33773660aa15557c32b7a086a5a1cfd125dea60183ecba94da22f0f3a18dd2131bc792c4013b7bf84a7840c976c53117653c4f947839d8cb35538bb97899418688a9e062f9fc17d77450d85261aab01bd9ee77e917966bd26bd3d3990aabc8561cbaddc5a22f8c80d99453fa7350b2a022e4ca48dea6c9c07309543611abfc7cda76aa03e51acfdf0cc73921ef2d02f45990aee50ca77b93f14e4bef44576134391f7b67658e1cc7876713742267a556ea8f562bd858b24e04314b025ccb5be0650642a23460c3c65e0d6cb68232cff709204b7b7cab0741807100a712686b982f632095d7730dd9385a7a26c23741474e12cd8fc259ef346b5f287eb01b046104ef8415372b47da145ab0c5c1774626b5dea7d72db4c62fab14c03ca51384420690a799194e8aa05bb914db21956bedc948299baed7289c884ab9833c8669422adf51d4e1a0466056eeca478f11ab55ce2ce34430addc889044a5601357ea6a5b097b54252b046fa83c0211c236953954c36840e390d2707848c0b879aba2354ea200fca56cbb86c0c2269a81c790b966893f782aae9a4bd1b02fa85995a757ff2083fd26347c97711e07560af77cb59c7cd64f7cdbc880ad26a7bd7fcb9b210710e581c49453a3200ac08554a641068e6879ba6665ae9f281fc14c8fbfcb0cac0081c1a06db017d80048b324248f699825a489d0726893e109127a0ae802cca29ac56f6118d209a54cb842c9a8c539e43b9681cb868018c95d872c532a10a77bf52a796d33187fb8aa3fd780bd2c4b30fb7394dc64b0fe05b81128763a1325bd00eba411247b1c22a1146feba1b255c51f74999dd29a9453151bd9869e3d548347b93c1b798fe92a053b88c80d7afa5c561d31435d61251253b9a4c2b0f42830c81e990006dcebddb7002240ee8e276d4e31c2d249b84414f3997b9c4f5c0698cb2a24c48e3605f6d704e5db734ead12d62634dedc68ed6a1248273bad5ecac0651978b098ffcc148667671d4b59ea6095b0b363c31299e5b90282f914bebc66f6291338bb7600c8310b83963336952ec33854ed7c979b71f30188180b11bb66314c93242ecb890123c9f2aaa786acbc7dbf560cfc1625d06c3828998ed51b79d28c583bb38719706d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d7113edf611c521761be671fe37baada7a2b4a114dd458a19966a2a42914d61b47aef5abccf8240c88af752b51bcd0a3788c2aa38aad8dc00d835476c8386dd3a8628b261f1d6b2b9f771842c97da7bbc3d03696f60524be6476430044f6a8aa48c22901f750dc55c1ea7813ec3518b26b3fd0657ea6fcb6be94c026244a0401593664673faa680f866e174143b0cc086fdacc1f7126c3e941f090332d8487d5e66061d5311c9b5c8edc39bdfc34948400a9a3aff3a85adc48b21e11b57f853985689697a591c5170b2766a18d18937ce92857a99095fcb6a2524bea122ef1fc8f6aa724f754832fc17c932388b728359e55800e3110c89b8b7b711aff4785259b3e1b2b0b886a057d71b035617ddc7c0c8b1bcdecd50a7135c8a68a2fa2f7b62b10baf6325da837368280102d7a7439d328f91b2173d8625d769a6ea936990299a02329380a85a818524f601b36e6cfa8046ed2f7c1b5c13260152aa34ca30e1887f2849c61b41649913138b74c817b2da9174d3ad4ca15653f768896837323dab2c18781a8ba793d54c9126df6a6ec044b7e709870422a8a1c030f238767c91d75185def8002c105806cf728897b382aa596dff7ac969a5cedb9294dca50ca1c74ceb7605e978722b148817964cc1159883a6dc5094f02a5767d4bb5df6304d3148bf009068a1b2e4df78bf021182e985982f4b2629c049dc26667746c4503ae0491728202ba0b55a8248c700484597bab32dae41607538bcc5c9dde4a198cb81ebd9c143eb9b612930da8f56fe3d8c02863c04cea9ec675bab636ac40ecb18567a8e6fbc63a52327520bb770a5d64349817a13cd365c96741726aa9107e9a4c04796dbe92061697131e728104c9c6ada26ebfc51632898564d89b2919438ca1308c53387604c162a424afaa2af9ab0c42b50cc50b3318a15738057c2f1806017a7bac76ba523acc1c66111d45c253ab299463cfce584ece769707a6b35d6114a8b92939a16d27a7be7f72b660f0b851e4950c20b33c074d307c8fc9b51454e41a96a8ac76cc30a568b4bc442177e7748e4b0f7d31201569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2bf23a19a5740fc9b9bf18859efc79f9e9178bb542823a4fef94be8ca589abf740d7880380e78853708cb9220e5d0ace428c58a543acffd8333d2831857c3784090e3696a3b011683899ae31b40513e9589467a3cf2891439871a1b240fea31f2fb89956d9966ca204a598050beb2c36f9a6851820c87a5262a9cff23b1e7bdcc9d060484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ec103864b75ab25a013d7c183955884bd01c4f58cd410344396358bd6901a94228275c79a289b385c788884b2bd3371d0852b0ac4a24107a87f1da0e6fbbbbd0a25c9cb14b7f25b7432c8148a0c91f8c7616c7bee7119a8f9aa4da5291a820922ea68f2bd62c4300cab4d10a73db255b1aa33d523d774aba41fc5f26326220c8b3575520788c0476bb3462f73c61016c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a93001a8c4c539f576c735068661c02026bb22ce5932bcab118827107a784ce94c2c89444a7b03a2386772d89106b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f502042c388292394a4940c0470458726b76f39037e10821fb56b3e4f38c752f4278b8b1fc332a48da56cae9c56bd03343659b4abc262fee6855875ac2b8aabe02a352919ba6363c6e75a8358d3297386240aa80f0aa33b1a79cae3c9ce40f87520ac713bfc2dc9da6c5b2bab6443383279bc9f3433e4080c7bd5bf22306e4fba2a8ff0a1f7978bc6a7bb809664783c36ac81445d4964c8ec6e9616384c60636f6ac08aa1c23d182fe70034ff2390442190f8c2cd68c9892bb0a6fb29c5e3480697145b150675992137c5a16c507c96180a3129417d9e30815e30b90d05835b890cec789e3ec8ab7dec509919cfd670241250822c539fa2ca8d9d619e22f050744727bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb569147804112a0046e2149903fb5ae0e56a4ec2b44397973441394175bb675c3198800e1bc56185ca7076345ac1623ac0ac1f10f099fcf971feacb965482a2bfc585bf30647d90f7ba27cd76891ef5b3ef84b988f2a407f5552be77559d026e385627baea2debf3ae73e3cd1461b1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526cc2fdc6c7a39da80278182347a3330fa332e071d8f31321bf32f4507b16e328fa7892758f2948a1a951506222833c0bb68140495a7a5e942c6b17e674733ce754eab747e96d2a077e7024df77388b6bdb807744db74612a8c72011be7d8b0949c75cd1b6107c2422e30c1e577b3515556a10c1ba712aca7f6988b3873705257cee724acf431ca0f9961db020ebc784e4f27c6fbc062857015db28d64004cb41bb7ea3b5657e6b65200b3959c642b213dda13a1b25377c4a47c43dc2dccf3607aa02ca28a4067095f541b359e21b39004590ebba6d6db8fa461a1343b824d1373f872343e8bb605729b674c66f7e5c76b536539f06f919213cc14756ffacd5789a46e7c8ad789ba0f6237998487c1912e86b087c9388d3a6a9c18d505fbba2f7aa6168508b1c8702a2fc167f2202ac21ba862917f6d78971aa7296ce1306d2a1f2f06b8a3a214ed45765f6a05a7445cdea385ce7922e8006b549319cb38904f38a6f932304037c4fceb9647fb7ff9e9aff5dcc951aa3e4bf50c296b71259650b5047c94ea2696837e26aa1d18938851198928db1ea22758c6cac0906a995a022998a7a942626c2cec7a5fe83948d74509c61915819425120d9e6580c0a3776ad41a95b52b2e867b6d7242ccf281a241a88049058d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b246c206507b89f46c6e9cd5e78b6cc78fb3677ee609cc090cf3782c876fd5f941b0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 93b854ae8690e56ce1149ad776eb9b8b29ba124398429b24cdaad3596c9d2889d1166d4604443441b5a77a71cf4ad72651365263f38ec232de2bd664bdc01ba969a557c8eeb6888b4b1272035f34532290967a0ed6ddf04ef083e6e525279120bd02a8da8515ed4b420c9dfeabc5bd0d73da26b8afe062ab3a5279f1069ade2d6284c8df2cee06855eb4b94e03b5ae91a5ec345300f3750ffd02ae558e9ca00ec2bd11066ba7827d26063146f1d1b246cd3c1342b51e2e98e0a06faae93b462046b1e29c0b9b525a229395889bad0dfe46b6a6d3aef00786447a5dfa1b2f1a0fa8cfefade49bc28b76207790ea62a8c2f9dcd37a6884e5109288f6196fa83486bf89b5fc82875c3ca187440e4a53d6b0746be742410d5e4d9a91df391499482db0ce46048667f30d5902e4399a8815d52d4295321e53e68480ab1bc24c3a281544e0d68ffda5ffa7b0d770a6faac834815819558507fff7704d84d5f694385d5a480aee1a0396c31764356d7a034eada7e816d3b86f44f6d1bfa95a876939bdb77c100c9d06f2fa29a8a4c67b61ecefece063376bfdac2bfcfc9ac94778a87ede84dd299e685862a6ee3e435917a25dc763d6ce9b4fc19e415b3dda2f90d9d1e559d146f6a3d822e21f90d2bd6a4c196c7080703a54391f61ca2140ccea20cd143692845b20a78ad5a4b0403f373ad9085e5b3abb2776b684a4f9bd3dd78a1835cf257b106b6682f4d86ad0627ed0a3e69222c9809f2740ce3aa16c4fb39486d399520a529791c1fa90e069da5ec030f726093a527e51455060499f38ebcd797449cf3ad21186a1de8d63cd9fb3db22a8823292a262347fc6b5f9264a8b907237dad3da30079d64375e48208aca9f2a5953a4763a2006f4070b796ae75e7052557d682f04e7f6ba51454c19364697c279eef3c421c4d478e4f8c654ebf9d1bc2f4aacdc19b9f71f87e3ca7c2147813e64243e515a180286f23d4f3032b8b31aa35dbeb1922bafd81f72ddc3a78745eca243bb56df728d5ce2556b985217ed7862ddcc915b9fa6fcf42992923a14447b8c4f11781df1f88798e8b5b170b4c2fa86a758208ed7f46d13ec64a2e9bbe0edb79993e845b418aa402333179c476ab9f22cbaadc31d318fd6de048807676d8aa8dbb7615300b871e84757e1a69498d0a26872aaf537b1423fcca7aa9ee79da9f5111d1e239dc8944212b05216c62a18fc3bc7707313aa8a4c05877f09c8f167195d8edd787ee4447f57ff08f470b33c4bda786e4457d43f50df69ba500905f4b69d1f0e8b98ff1db00d8d0ee4a40958bd4b0df837fa44abb3e2fa236f1fa05bec38f1c6d9467eba4e2067decd56a11bf275e07fe74db3a79642ee2a0b2d658c34748b6bc54e2bf6814407f500e5517b1e162c2ecda4201eb544bcbc816f39246b0bd63f100332b4b78d3c3c262a5610da4ffd95f4da34d9f76d967888beee5857c1c7a44ce001a782c1e41587271b11e68c1e6bd84487275c7d89bda052b67c567d7545899460701242d70a998c2ec9db6be579bee739bd755b9f7b94988173958ea9943131a0292aa6db7fce96c361f9b4d82b84402f67693dcb166ae5e8eb7e1ccf88c755fdc071ff0acff6d74190b424c7c2ee899bbe904d1a367bb284e5df91b1c9ce68513d3d5d2940a261d8e0c3d86872a02f4b7f3e37af66508df837326feb6da4355d5158db2f96f52663f437b20b851f9db9d11f8ecfbf9e5bc429526edc29a7d9e0fc32106db843f75313cb5299021d193d4e0ebdad08be7f8d4ceca944a3b90f670a51ec5fbaa6c3b811514243945dae6223cba1650bad5443f19683c387674e23195ec1422367b7df591667d7aca7836efccaffd4c4d01ecdf8eb2e49ef55e256dafaf56d0c193373d33c4ab9af7aa564b92cd1dc7168b4aa58252aef2b35db657b97c84b0a7af5a158de9047368749e653571246899a9900c53bf8a8160143e052006471446f6c26cd6ccaf3bd92121654c19a8279ac459a36de93114bcf7bb3db544d3e1a17f60a998f6647ed0ecdc687161bc5481c7314d761a08d01e7a91fb4dfaaac857c0bda1a55dfa861d332822676cfe751bb60ea2e29febc238a96eb2f014c524bd8d5f4ddc21ced5a68f1d5f658821c85520d749d5fe7c1cdbb97c761bda8546a47507719a1e62fe1a25d24147bb2bd90bf23d3b68649c852b24dc99e7f2a1776ead4fb011 +expected_result = pass +expected_shared_secret = 021b7e80dfd1258695b61aac785b0134ed6e9864d3cdf5ebd4b3ffdd9a5bbf06 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +private_key = de4627135b3976b8ac07c0059bb28d09e98e3428228c1786c2e8a1d6029d93cb9eed217d09b03e9a7561af7441e4271c7b6c8c862c5a93e955a05a87b01a63d9e8a334b26e1fc0346051bf31d078860a9afe939f4a90c2a395b2b6c205475164e36a0c2930cd26e26420470b0d068e36971a978b17be984a418a3cc5c6b62ab00d6dca5657f71e08b215edfb88a5b6751eaa525dea4b0bd41430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638d808f78535b9fc6c6bc0c1402e16f0b784f9a22a30e5c6c1932c2063bc558a7b2636c76d5c0cb77e6c5518b3b31d920a23b2bfff3ab93fb03b3386f670b07655989c5185d5d393631e9acee701dad333379a63efbcc636bf2b4fa05b84a375559079c5909651e481da96b01a771befc7bc407db7d9f94b819a468d443a7aa8c9b4741266875268602336c1b1160a4ce5d41c57fb915335c87a72a7345316373d921a6d0ca09606154199c4f06c244a7c568bc5d82449149f92ad3350b51d3c474e77a3a1053160570c876132434aedd92c8961b95588910102c62ae1a75479175cdd666ab85478ebb6133920e9154441f1383b0f147137614dadc823f1848fa478b1f301d3f745c647c216c741dfd3b3195483f24f1a5313cb458273ffeb559689004cd534ec1369b0c68a873651f7413037118c6f98c538dab9c1ec649ff2301a03a650cc0c138e79d15f9079a639737e840a7dc720b173bb329a34cf65418495e4df2805a491a4c96b47d452725850ca8eb3944399f9d14157fa46b76f0891525461113766dc025ee1c2e735198c3db253a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb441cdfdc9fba20a9ce2943759c4d08c57a0e74bb0e1888e94723169437aec19aec1a2a46c81ae4645de32bb18f3527f4dcb8221a0f7be74f3f5a8cab0609be216465819fb858232b008a855c9e6b54439a67aaffd9701967bc46a274d1d6ac1d45cee7c54cf49669e89a44ffd7b73b2a12327a85bf5938e6975b949c03ef3a1d824ccde033cb175a3356c8a998e4c69d94630a896606fc1979dcb5c172a54eea2e99d5ae331bc64d708fae45c514a2544843ca59c3c122947bc3660da7357ac0e33f55485e79eb3117d14c42ec5c56653e0dd1a4e8205fe571823098ad8d9844a25b92238063a92040c500cc0bc2b25b493e4cf69de95c87b03b773a796d13f42014847727345888eb06d9251aede24d03e292cb452a3a38a0a461c8b4f9cd9f87b09bc0ca98e62e5027595c24792f818865777a346004fe3b5b587452648263aaf688154526d591acadb74520f3627d7395ec7b71dc3c6e8414985d591a05c88b6455870c48b12c576d7b328b88795295c051ca6293b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c83c28baa424b19370afe997d8b08e447a2eff376024f5ca54dc8ec0972b96f057acf5a6b0d32869fab3e1797ee2571b1620a076082c4ba6799c27b07fb073092a7a2f7aa110635cb94900e487a6664b318f54956039c57ce509ede489faabac96cb11f58c87708a8ed3408a526701bfb8507d67415fe64e7d41081ac12c21f3092af02810c604f02c4064e348b4f98f6be65d87650e56e7667cd5179c347a894b5a9da3a3a413c2d3a23e5dd0c7dc841e10e4a83b3bc0ead17b5983a57821489dca73d1656e97632beb9a3aac017855a74f5f393eb5e42c96a207b06687030b28b5e09afd66225ae892200969ce41420f960e44963f634bb9f69c7c4cc2849f258040257def4941d9b54476d2ced88799140807531b817dbb1b2da7a4477abd378155da169a84086150ab09ac8a980fc14db247b3a76723fd67701644bf72810394b0ac77e74bf94416d866489cfc286da29d62c1947be88a0cb78aae94610d48738019768df89b38198258dc7f70d62a3fa72479b9aaaa4a84259837bfd4872d8c708d478a0e674a66da6cff330a6e140577c6acfb83cf4eacc370ec57fa76c76c765c39f5a07b8b1a244265cd03ae02433d3fd438d5a885ea03808c6196e4a3a459ca6d6b456a6fb961fed58ec0d353ad36143c841cc8a0390fc55f35d50400156398020051a10c22c69207fa839e12750cf0a5ca404c6b5344b9671e6e15502ba17c37872a9bb390cd379281651047fac2b6d20010089c89021be2da6c17ea926bf636c042c59a1b79941c248dd3079f623095437766139de109c3346147d1f8a069b2316ed2606ca1454e364e9c43a80b0bae79f005e0ec3e006d1adab7bf69fa5b098166aa9520de263e25a36436d3a9783b96a763c9321727eb65a7207b51d526c6182c1d51372316cc0ddd946077a81f6487b34d68b59841ce41e779885027912c5d6271adeaccc07ddba319700694f927a374b794584de181b890f651043a1b391a7956477b436307dc8b0d0467bc05206074d17f560160774a8477509bf5a936811bb9acc179834a9d1106af0438148d076e4c3a7c70d7231dd475f06778eca68e40210859b092915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91c82028eb18d99556abec2cf3aab979d125c137b75586b4d419758ff68229870869be755950100f9c2bf6d706cb9bbc5289489df8acf49046ea3d27fe7f0cf0e148286970010151a11b879f9035351ab10a536b6a3144a806b8fac1389f58b0395fc7ab90436b440bc9e66ae3c73a5e8e5ad59662286fa9a03e62c5eb100c9b63dccc74793080ce967b7d162438a492ca2815f56950d02aab7f12254d75c499840c5d662c0c10185b4ba3f84a91b37745d1ebac3a2440dd899619706756ad70468e1515d4c0a765942dd5a84af8a894cab90a724a95481285a160102eaa39591ad4e2c871a160be835012705598ee166bf2622bae3acaab37d4fda18997212b831b9b043082ef2b7b86423bdc15d2be82687c35e12c85fce726f340634c1107df0f50f3253764fe4cf0d294d27f28674f94ad16b7d03f91fa62a42ba154e35496e9b2aa884ab27b5332514c377f78a2fb5e7ad85d643ee94763095b2f2616bf87439c22a26c46287125bc7bac3aab30b1aeacccd25532b326983a37a623f0a2df3d7cb732124f89c37ec1881f2c5993667339d825b68908cc7923d02c55e7f967d3d3b8d01ac87128b85c465b285d60869290a78b40d48d9c39e92c298b313eab8a8b1607b6da8c22967ada0294696988d5d251ea0565c84571914156feb5820e5ea145f411f5ff64b587a99b88cb08ff4270cc89573d901cdd5624c0a2c3a654b99a0bf602acfdd15c06d69077aea18e73ca0c2e650751a68b659a568c2742b626d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1e12041e056ba02bce42d9ca15f5a241db89e2510469762690d270d1e16cfcb92f715975f68b44e75bcb98e521a5c2be1e4a2e5ef07bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fbd00ee503966c8118a1993910c6ad99511da8216431b26aa7b09a5f304201acba84670714c410e21a2d4517a0a1f139304a6fe9c63371f65d43b095b16040af3ccc487840cc41a63bbb6e2dc49731013ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef33b176f31104a3185dfa62404dc4a771877fb94656d15c43142bbda1417a7c69996681a0c69b2d7395e694c4ade0a5886d28f207722855a30273c91e2c19a2b40b62a554f1ef9c282b51015504c4b84714a99a3ef33504429976c2c036a9782b0f2be79924d98700d6c066015b10c03db90844b7d4ffc14b49ccd5680b1c1d9c15ca935404737093c20a05461c45abcb81c6a19b3a0abc168356882b8ec3549836faaf354d3b60d1a5290a883ab1e19b9493c26113b3d03b8c3fec053bbd14b4be12c80ac412b6bc1328a4fa5f1a3f46bc4bc685c7da98533422aa2a8c9822237f62c969ce064ea0402cc656a88c39ddf221e3d6a52ecd38f160a3f71c281a02a24beebbb1c6c9025dcc51447a7f5679fb0e382854a29d8088b5fa11c59c439eef92f869c4fc8b66ac7656c385c0983b07aa98a71abd2b576212fbbd14b96b19559a6cfe5dc1f3549436a4263bd9b8a185740b4eb16e09184dfbb07ffb7266c275438e13208e4a2888b63fcca6cd8b5abbc14769bd61a74f34627b896f1e85c03202f4d58932c183d7cb4a5548cc540a32aa9c558e9889e10d706a809aca75218740bb6c39761bcb0bb0c76725eb80bd5a46d074864dda334359b4d4dbc7c8da2b413dc20a1201ae9e7acb49c905145307ccc92fba03c02045c9632564b68cdc1e9527b239c1f9a7f72358949b2ac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9920560200b8d070d1db2cbeedf3cb322ebbab3edb80cf474b4178633c210b2fc74b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = 40d176c0e576da5380547cd5e1cfdac9329cbe7dc473025481d612401a1f28901dc2856fbbf214385cd2a655d9ae8773f2dab66e1416881fb8d11db2d6a93ff00701db7bf4c28328debef84c4134698deb97339a66d5e046068bf25105c1fcacc439bca718e9a1bc570d075252121cd388834f074a27f2e4a01fb131b278599c9305357ff2f1efdbdbe37564b324b9646903ea90836f2e2ed93e91bf0b9d045ff2f119c0cfcd69366cceded4cb040a656d203b04e689736373a9a4a3062999c3999484aa11bd24f87f588423e98c0f34c0c522f4eb58fdca72a4e108678fb3116ecd60c5cd6c38936e02729241e4da1553005dd9c6b192338c9894b14aaa57c9196c28b2cef0e909cd02d6d7d5348dd409136cdf9fb9edc128f38c9491aa3b2bf75659f225c639d1e7ec179339a142188db6ee3d251965ff232ae26a1a9af7a19063c4c37fd60bb4c3f76890588a54d321e3d21f0c5c879418ce6cd3b1ddfbf83992b3b860c8756be4db101a395d9025e7aa7fbbad94ea3bc4dfdb5628ffabc684f90e9037b57f97c8730a4a8ff8353feb31ae5f3536f9a64c2cec9e25b666351f4462248c2f84b0cf89c2b2238fea1a658bd903445525f227a849f41f58f7deb9125aa3c1bcec584a17f45998e3a5c1df02d064ed19b8d3c455e2f244fd0e683fcf9a929681fe880aedd218cc3079bbab5f1731c58da5a00c78c512da63b4f2fc527c0aa7963df97f3d461a0129c7d76e20b7516d1b83eb388079d497cfe5834e30a6e336c8c45b214b360a089f4a63473ec691555276a5d1eb62e07b06ce36474bdb7ddf21a5caeac5ecddf648a7e6a862bac72d0cbc69f1e9361829b1657cf0379b05bb1630a1ea67a1a3f1079dc729c8eaefc5d77895e2746deb079e56982f9cabb21e225459c7d2ae76b112e14a0db49a55ca1c353eebe6947511f8509d1b99a86ad8f38f58107f8605b47e287397b97205d215ad9ee840a95a2c6da24b9f4305bd734759f5bc6bb006253fbba9d6695da96d77b1c6c5d2e6e7228ac9c83dbe16a095feb2895d2142251985e9d38c0ad583a80c99d453d2eab117e10cb3a91a621936569976c69e452075465f3fa7ba041c112944186a6e9f0862597ca2cfb443f6f55d2c8d4a622780c4ad9e9cdb909756cd702e51d8a4d96b08d62aa2579a9b8d20228db525667659f4ce676c590e6a86a4d8a457e9994377df22f9ac3d4336495b7fafa0e06d58673d70971ff3ff8c436cf17e839b26087b01544070cb8490c2a88c2d2e01fabe854d58aa3fc066e5a036acae3a7bf9d2c02104719314e97eab17d95dc4421e002bd15f4dc0f1860c7ba32f0188a9d333f1e9b5092e1c01f952ed02fa3a8fa18d3113d4f7fb1b58626cd2008da96b45f7cf00a22d4acdb1234661687bffa52491e25bccaca2d00d21b0148e13f3259f956fdbdccb7fb16d0780d9fcc0bbfb39e00dcffce4bfd9d916314b5d159880bc791d3836c7cc0fbd461375e35bcf259908a40da82d6f3d1a0f2e26fe78e4ec4882be39c2a2d97aa9e63d2ad6b98e56fa1e593a844f2d8907b0996d7aeecc4f87809c7730a3b6a21eb9f0a4f7f31d7af2d71462c8dd97079a686e7abeeb5912a9068d766af158d7c38d80706a439308af945feb81936571983d6947ce5891b32ef7f3a9d71e4cc2ac133d004d5ded7a0cc29303aa207a233d9ea745afbf718138ccf8a15d5fa39c6a2070a53c92221cd0cbf6b878dcaf7268a68fade731da0574998728ea63477ee99320ed00a8f239b8f4e85f7ff6c7266cf9a3ccd14cd6b9cb616e6195afef1d38f8f2d0d9779c4188e60485ff8f24d8a7a10accefb99b3d6ac7ffeee11ba0fd40190c672b84434eeea7e9a56047a3d0b983b0f834b8a7af34de7cd853d0282508bfcd0b52964d3020f27d3d137a1c3c31a281e5a4045c9da040188d5c59c96eb855f92afd4fe53fb546406c063df50e13643cc49d12c86d33d936c8818a3c84acc10b677850d3a6150089281c92cafe51024a03b4ae6071f2db11de2be9ad3068bd94ddf1d42782f318124967087f486c0514560e68abbe5dd2d7ad0a65fe9b4ca3dc00c97ba2d5874596337a466eb6593feab2029fdc0f3a665bc93807a80fb83a62e635e380810ca78677bcc399b360ea0e7ec0c89be6efb84e3a6e104db94f715bbe80da3cf4151bed37cf1c3586c2b478ef2c536e15f7ee74fc2e1016 +expected_result = pass +expected_shared_secret = 2c876ef4c2bd6464c5e4274d5360e210ff389325c1da4bda5495294d7cd126be + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +private_key = 84d7070ee80107976bfd1b0db6cc33f3c98178817d8460b63dc012311638aa43b253a705bc994931bab38a62c5d1dba793b8437bd600a8725d36aa898e353d6b955b80f8578f855bcee194ce2c6e4c6179ade8176e34578fb24b6d60c395b674a7a8a4c72550f83a09d24582f94125690428a4e76972b77a53e852ff3718a440b67d6521ca699e5a8c434dc47a38032129bb76bcb4c810028938fc94f1741a1fb26ec95252e259b8f9176bbad8763cb63da6f295b460cde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b24e09d4144ac900b43cec07f1dd2cc4f7c976eb0baa4d8637bcaa70946391109981e978ca023313b200092d26ccc823ebbaa85b8ba1680636d0be656f01769555b058af7825fa00d10a38b0a2b127a773cab406c1d4310a0882889759f20b44aecf68dd24416d9491cb523a1afb1a1ed87b28e5589f4059132603e228b185d426f49031af8fa21b11cb0f37c4557f94b2f158340921f95091128c5616f54105d47253f150ff335081d231f5b308a526b9506b03e0b5c6a88394f0c9c6e7c2b475c7508a3a8b1e0d571d1c364784cc8a7ca7ae6c2b24366a0d2865658d42a8495b24a16c9a9d8b1ea77332a1058dc292ec02c4723fa7204e93eefc24f10c4877425975cbb6142026a2aa649fc6c77e8c72dd3e5b0d9e9495a02c251b12b7ab51f6a9853bfd151a4873cab4102db62676496a8b38c8038e4c6d988880a6b2774875a5fe69693d9726af64a51d77a03e523bad8b2a6dbcea137a051d19e81059d07437e38db7891956c5b2c8abe282b5a02a5530c56a7b4b46daab256588b04344365313a3ad94a2d7aca4ba7072cb9259e2676a5c86215b24faa159bc18bce05451c69d2699a056ed3f6a7f2bc7676f11bb06cb72dc53d7ea6bafee89797b57445f3ae11262543a2882b863cdb455d5ea03eba56946dc61d798a76bdbc4ca7f2a102c518224a2091211ec4d251ccfb08aa2598065a79b8b61a56e925031a579ac5bdeef1a6e0b1381fe180db008f19e775e030052a624b91d1550fe5365260150ccaaf228acb8fe471d2c8b4b27bb57d62ae9ad9ce15a0b72ed98b8a619cfdd3a17ada37cc455d77640ea327088e9c33d4281b65dc9a27c68d27088b1f2a5fc586bb0993753e62a67bc3886048274ac267a95b42aaac3e60c2699321a79301acd350b92899a2c0ccc4703b243660a39c5901e3b6bb146c588dd3431c4a5bead8aa29e04f8fdc0d04783751707cc25ac359952abe7384f839b42d9c9982dc66a21c7fb5cb7316748423e25005d389bcd56fc498080f88cd75ec974ca9ce9f2ba995b50eca85cf09612fcbdc492ccc6d0662a59f8cc0ff3355f17424abb6c774a377b81c12b9982f60777926ba0b860123434cae8f926e902a5e633019e3c62087a1bdddf2186768baf91656d903c4f1ca88163b8dca041823bb6ee525583816cdfafccbcfe63dcae0b93c46a14fb72114194cd084c208921925e7c55ec807ee6c0a8ddb71c4ab3bd5836b7fa160009dabd1e5498d005718548324b0339ec71ac4a75c81f522dfd92b64e3676b337758490e068c3cc747bc004da30cecab9c542ffce8266d8106e77631e9166653d50b220829b272c2ed5568fd00c52de89e1cb76adb4963623c082f824afde530e842838d6c331d80ab47f33fc2730bae2407b8a40c10642bdab993d363612e5b6250825c92fb6a78535fb1ebc52bd83b6f5b58f52669ca138370f1b21fc80f09d7011a005a20125630d63a9e596dc782962c622bbdd44582fb8a2e4638f7a0029c740f87dacf6300a8ae8b4ca91abdb56534654395f9e2c7cc087633149ae3609089567c7c7b20e13c03a059a5c95b22be46671733b28b41b354f30b043ba5edcc15ebe74e7cbc3188b6ab37fc40dd3bbee7e02da545942138739479c4f610cdff564ba7a281b7249267c3740966c7ffbba92a8a1c3328b19f58c058eb27e27857e46585e0a4ac62f1a361e44f92413e37e7cca667ab53064dac9b3aabf3363451c95f6778ddc114f8c3673cc302e7183d49379bbdec05fd361399ba5ad58a5a8f823efb096e1dc522179100626bb67ab1647645794b38af228787b425b03f7c15082abd063125086c8586552070f6897252936cc00bf2810baed633638b1737b5ab13fcb47e181e6cb86c69301b77b85e2c64305f1584e370934a02aafdd27c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab9599544ff08a4a13643e181db6c752a8a5c948d010e8743ecc064ea034444f3a2b207bc3a0606600358907708bc87016261a61b1547bcc8421c009778ee31598d47a48d3a99e9a24ce230b9568cbf4bb61d9a0aa512b282e2506a51b0fe92507bb7cb044e93ca230b6d9f97cfcf31b9055c9775419684aab2609a1e11b2b354223c9761f7d6b5b02a16f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824c115c69510666308330901208d02f1a6057a0f5481af4956ea5281c956735d28e49173031b688a30289d385a7718c2c21c300d7ac3fc81bbfc6747c60f4cdb9c037c458c50dd1605ba167806a6fc32c759f2942dd81962ad657b51942b3fc8d925b9db72b1fd2b303c05043638a3217d1856d8b243018b0d8679db5c3364a85b78c913793e87855b382b3456d3d7c1c2b82bdb94c6e96732c6f455e4e631fd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be1b09430f2ce72482d6a8673a8d511a8a1c506a2cf4facaa9e489d6a3a5322410464d590d0f52b957b28937b543bd5a01f07261afc810d41bc815469e145862a3238bb194da838c642b817db611e18c08325502778922197e73aaa2c030869ca3ab06b22827feb4465ae60975a61255a405db1f112a2087218619bc9dc064035774306b14d4b6003949181301253034323f55bd0818097193d449a3ccd1315ee375c7efb833d03a87a881cb5dab7e0d045b6b80505cc18d8e9be1f1a7740d4981e31339503b1a2b22061d484d9368b8a5193d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e470999e90627014b34a7a8b168010ddb76f994783b5f41ebd60697198262cf42efc13128a45024386c78851c709389262d10d65c4784eb10c2cb13d9fe819cb4c6dc0c34da8c22b69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbe917b37292630518b093b98d39c6fe0138257467f93c76118ca748556003c05810e7cbe83c60f8791a72494889289716790242199262e44b356a98e38429733f07e4d2329da534fe8d4998872429793a6c4d14919d3adbda51c60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f11471d84064732b11d62d40633d67affe2bd75315c54321d3f515078b1cac4e1ba9fd529db1b92a47202c0e768b271826787bd6098a8854460d5da5d5744944887cbb1840125e2825393b64644b8c0b6cd9536be03d6c3e7e6ceb13b1901f1cec3456903f5b15e9994ed1207ff52915ff2460c098ef820a1e885c2ff231896a3c1dcd5ce49910b30927597d988808721cdb68f98914266919dcc46125278774d4c1861466a8197c4214493fad00f83808290dc6064a388633b0ffd2b1fdd84a6c3fc3576345d1a654f3b129fd6c2a6b95b46d235a9a7f44a6f9558af20a451a69c6f5c119712cc5ed91f91b946678520e7165ab4cc367d1ab985692f85e68a3b05c738319e0d7107f2f89710f32c7c047019f6cf29854bcda6b319288944e9907975083e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b964101aac6a016725c3903e5caa639614650c0e052673721b113f48d5cda5cce6b8a7449ba5308ab9f1c25c4c4335e2c4a3be318c99787fdd98f7b592d942617b4346fcc402df7a41043b0bd87c318757bb3878b60421ac5b2234863d2888984898d198d002035dc123091532371e444204ab05c8a9db00c4756135998369eb181882ab3c0c3d17189267f03d64af8b2c3addc90e32b3f44c43864615af5001b45c9677f59b8ce680edcec5088dc17865a790f593ab49bbe5327718a4b0a4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de04100878518c722d321740f4c4035a813a5b1c9cf081679e957b795a2771485874e5bf75f57b11f8ad9fe3b1d2d72a1bda04bb1517296193763776fae451b6615a8e9c788a5c8d65173bb9307b2cf9c863029553f56717b355843ab1dfe72cef8c46d6a8367ab70f83db71c4c410960a7b6221ae2ab64a17441f4b50adfa971f25c719dc8705926c6bad712cef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d03a2484828bce833f9262405b562bcade9ff04877838558409d2b60f1b689d137d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = 9dfa36f0d0157ec8952c2199d3b6fbf75e162d7abd5f697424597a9e6e272cae38c8353a8c98e4e318cb3ea35e45dc7dc65a964b13a318af75adede184d692b684270655c2fc3413d03d53dbe243e626e0f427b55c1b71aece27c08f5804e4d7608be6b6172d0d89dcfcde114381ea824091a43fcd55b2da0bc59a3aa7430a5f564884c71db9fbfd37892314e8ecf1f71057a94ac68580b82e9d8b5d957016ec3ee640eacfc497146fab1deef7e50100a4173b91db6b41c069e9e32e207a5664b4530a9fd17e8d2a0443b8b39d4615705b89ccdcf552e272db8216e9c5a04bd5da18fe4e5e574a6d8271be679638ede14e0926f0efb549edf47c23667310bde6c8f7b573022a1114dda342f8c043165e4d78d6b9b62a47629785acd03aa5a0b37d4f1ca00d9b3e1c7f32a30ba5f3fe80d339d80aaf508be370c9639753f45afcd7449d443f617c7285e6cf2ae9f5090423e47b3abfcd9feb78b58a6186a4bcacb67f5993e8d0aae8ff8d1745e44d769310d85ed5309a8a87a406200d55876f782adce8af5bccc071a520bf5728d21428776f3a03c6341323ffca12815be6434106a26e692a2f46e4cee37cbf4b28fc006d4386c3196330fd0a1dc02b8d6bb6eec71eec766f2e8862b5d91a20bfc6c2d133613eed0e39b228ffd73eae3330b71865e0afdd9596774cae2783c0e85375f5073675dc65f93b71478875f29f4644095ad735cf6c82a2fc10f5e4d2717d2de098d28ee335ec858eef9a39e64194cd07ecf7b818d5b6988b687cb7f1bc46b94e38a8035b9cbfc97c4bfffb0cfa03aa5beaf56a2a21edf2a73a7a8a49d7c72ff3c11ee42f92ac7bf769fc513de67c4095826535a2a520fdc2eab29f71fd7735e8bab1979c4068848d9bfcc2418d4b40e9122422c2edee659dd60b99721907cdba4e388140b886a7a814ede3590e7557d16310caa4209a0b6cec282c31b69371f5e088eaeb20f395dd1c2798b32bfd8739539f9a7cb74b8c926bfe01d563aa54506d4e8c0daa27a7ee7b5411c9295a814334b7aab656d96d05cb9150707ae678933b76afd957e6bb39655f24267ea364fa561d2f435c12882b191b295470501ad8c8db036fb92df81c6dd9ea9a61907eb587be79ccae152935d6865a86be4697ccdee31d890cd8d0f651f0aebbebd8e6840a2a609534cf295ab7838d705cd57acb0d7cfe30aa6fd4b48eee85974fc9123d5c085bb668c7bac8ff77899daf404c01ce991d14a2f23094e14c4540d5b0e60a541f4a0b50be31bf5039979c84277e2e34c7f07afcd9521510abef0fc8e3d5211e8edf03568f4439712e6653fddc949e0b4c5cef165dd5fb749128d5f1b0cdc0868dd49ab1d24d140bce4e1b73533141cc4a8419b0b0f4b27d1090dfeceb95cf13f8ff024c9d089128f313039f0ea12161656251b0710260b7893720059262c24797117f618a9a05a027cedffbde83a93bba0437204f3af49e831b2b1bacc3c17ce407d0f1935534dd341f45f502a6374b6225c89b3a096edfcd533d6e0dd8dceb2ba7a7132edf13b1a5c1f2f5b0b23ef49de8e9754485c59cf0aa3fb3ab5b473461d11baf3be9d0187ed7175b135c706535af6348f5dad15582fec850bc48724c7c4a0ca080ee98f502c23c2816caf7fc9a4950f0da7320b027831f856d8aa170e1de03f8994fbcff4bf1bc507acfe95196784b2421af9de36cfa6125e75392aa050a8235e2dd72c484e61c47bde72e20c23e3e70e9db972b54f7b5b16b2a610926bba71886b8ae046b371b096fe266840b644774991d279a2fe4d4a965f3e9e9934247077c787e54803979b0bc494b56b3b081523605d3d09be6a01037c2150e40e46f4865fa839ee58887176c3feea6dd4188e58224894ac2ac38d78adc2ff6d911b417d799f3638ae8ec6c3252045889b6c0d3004d2dffd71b1a1d49490aa92456b35fe08589e596052c845f63dc3622364c0fb1de74a2906cffa39c5b1029189aa6c3c0814edaebd4ae01355753e1fbf211ead32be62c906f2f1d8d894cbed74efb72e40b0971774837ebe05eb27bdc19a5825ea0b50b47df97058c4ad78670380db8101efdc3df6b372b1a6aedb47baa29abecf11e0be25ccc4a42505b7a70827eb74948ebb4b5be65ce07501288862d98ddc0c977c8e9ef0848f49ac26e0774707fd696035ad5fd14e5b68b420d7191212a7748e032fbeb5b98cec320 +expected_result = pass +expected_shared_secret = 909b047e7f0fac27df2787ae406fdd66893a98d98e38a9f5b67bb5c8431a77c4 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +private_key = 47318b2cc6a9d8bc6ebe7c12489017c03214325b61a2a8541fb783c448c3a31c1d82ba7906b09e3512af8d00d0706a3d391281f0315044c9c4f92b0ad72c60e18637577b942a442589cbb466ac344438750b86cc86b97d16339a9db0365e6696b183041543b031c9220e82bfb89c21a5b0a0d301109568b1c00b2b878c9284375949c88394f141abc188ef7607cb8151bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee518202c9119c80081beb38caff81f5ea51811f13be9491f431b127783227bf9b691031145d6a144213fb4f1c89c38c00c81abf075c4415586bdf28b946380c948b94d7a0c3a793100842230663f4eda9174dc7214884e0f552a50d16dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4bb22e174b061bc80e91428547576b6205490ca3934c9b15fcb69611a1639974478800b2cba3d5243a0e2762be2f87035295fff40b56be37ddc71915434c4af6472c1e5c519506e691703c49c715b50b360a5c2fcdb79f59c7ade27380f9905eb7aa6f5042c6a32bae657c699eb85a53395c0303e87e89800131f96969bf45b3f574a40ed813268603a24f1c3180607814914775350b88a1fa7e1034c9cb155879668950ad5950803abc0cc58bdfc408fc1f2bf7d3a2972aa66b58844c048150c0b8c89aca3bd3269474875bf10a94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946d70b8b87c56b81b77024503ba87485ba3655f669770410e89fc84925b87c008c3cc13c7b9447d82fc2932a1c641230725a422b6219d9bdb5ceef17e121132e6615075e0b26cf71e91a1593210a09507214716a3405b2503ca5f29d4479914cd10b3457aa62a6bb71bd08736e1519e69f709b8c8439b4441bbab5d0911bc6737ca742747ca592e5ed734a8aa1b77450a9d4188e05422bd9240e285865d530e718c6f1a816153cc27414446bba8129a1716171aa60ae086ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee6603f7993083724a596069f3270c071b6bab955844a081a896096f76059b9738d819ca3b6588d5f578058d28d2d0710b2bb2e307a5f9e18533713c41e172a99614a97c00ac0a83a25526c399cc9fa9b74cc4774830c8e754231b04274c90c526dea7fe3d203688114e7a90d3ac02ae69a139649b754581bb56825a215c3ba282a26c036e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781cd09ccb64993299745b34b6d7f897c0e05e1a6966e6757dbee29af2eacbbb7701dbc39294db584c7c3a7841112258951d88145cf73404a17adb8cc4d11788225557a83b652f95053e8507093b2a8b00ce77e7bbbe83233dc18880f2274472c05e646b90952fe92440d164092a058d69c96869d8a83377a2da92c2d668607dec3cbefc6242b49a9da97c19c2067722c8d309cb898593b08b5d8138bf2fd1c59081614f764acb392d7feb205a85270dfc1129929cf7b53d41031c92944972b8bc9a9c494ab384996647e177a87a101c45c747660aa4a38088a5f7919ca46dad338576463a1c1425a6c4409e2ba8217827ae83bed4e6c80ab528a6bbc1ad58c868b995d9f72c77e84173c9cac4311d8fbc5895d694498a68e0b16037a95f9b61c95ad0b052e01ddf68a1fe5c094d3b8726545f1f857be735475a8abdd7c7b749377f2fe1adb0ca283d6721a109790f4242ab1711b08cc2cf7361177969ee3106b8238e4d41795111908fe17dd68a461c490d165316e927781ad220fb371d5b1951c4d83d047b72f258865e4296a9727052f4214eb55727b23a52bc68f73cb417cb40ad595888c941ac9360c11c0d17790e3efbcc97373afddb9ae3f61030729d5b7b200e4555b6d25d3e6b16e211bd05dc2c724a33ffa8bb3aa4684a422c19892731630ee2125ac8d8cdfac2b69834bd888aa2eca804d7a935a8d371899023488c9799b55f2d83a7d970aee1750dcc59483cc49451991a799044a74326eb0689a1c72186226c8102b344209fb510c21a885306a69640f6add7858dacc86216a189984640d518312d553626da12c9180948492eb5d1090bb896b1cc315105b2a0002f83b3997f02a227740bd4421ade421696031c495892cd3bb68aa38ae1f02afb536e9499abccb904973661fb70ab80405c4c59421f913a78e89f67767e71fa51431061746a74746b1fd544065788a7f880b9c81c007e6091e6118f3acc518bb06579b45ad1374404284b0f1c370c53062cb79a08015b4086626d3083ee7b427b24613947588f7149777a3fb5919c73d5a23ef5445f24aba79b94bfba774f71c84f929978c44e07a84bb9139b32fb97d4b20e363a2098838c6a3c51ad244b540b90020c5a0ce2b135918db1e9093a0cc43ab210d28a7889da51d88c7b3d1452d7879f34a130bb263f51429086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e56881b94376638f507e95809862b0897744d3d8658e33c89a7791b93acb17ddc91ccc5b71b01b9bca81a7485c5e4428538a3ba7f124d24864149b26d0f246e9aca34c76103d676cd7a54abae1c895c37b1784476180601a67a5d04996d195363c61864caf95e7d3b2f4ed68ca2db09d9d34f86d5666aecaa468587fe5a3c56434ff4815c61094c831699c5f1be9301299e3016b4cc602bb62a4f1c2f1af247b4fb92d4a10430e29f0a71c02df70e48e0ab79c0a31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114e62417d9bb054110d3284b3285110b7069fcc58e2e13cb50daaa0fc082b7c87eaf13063c6a966b4cc24334a7e6fb8c3131461756a35f2b9842811f233a6a7127a33b7cc559b477b491c0155949f9952ac9631c32451b3872967955c1235b61af676429c94e9034405be47ac5873c9dc33ed94828c9429dd7cc29d076871222893f207b0f3a8086d77c3d7792ba25ba8db46a554b161a30cca878ad6397974acb3812767a95a01f73ca80f1d83006e9460d2348c047ad60f2841db1bae58952142aa3491cc7dde58debbaa27621c7caf299f4325ee978caab6ccd4bd7510f318b20e98d26a94ee99c935629394e6b80a5614891a75b45d81eda8a6cf8d8b43d62ad9399369023c4d677ce75f14f84b05d01b7b021e15e459bc5c82cc9c4158ba32c5d50708ad9f620297333a4d899cc7a90c28740039b351345bc7b971aaaf39d97326553740238e569d4870bb09c66af75b532778b9b0a631d362d13d61567212e6ab523fd4c3ebd5839e4aa1421db5e06e33bec836876d8a8624c22fa56c43d4060a9e52f1c905ea8714d8436569d050c7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dc5242c5a58f0c8caedcac7c5256d8f3b40bf57b055616c24569a51c5bd712279827bb00d274d767156173c7ecb8766202376e9a7227517bc4488c029b9b6b2642858344bd14c8837ac908690312ff5a6de7bcb88f2cffd40a9fc666800f9ac54fac76ff5a42ff83b9d49233c841607aa348e2a5dcbc572d2a482f78b2cdf3ca4bbd22148c925276b6072d777d53081311a286f37ab14ba2000ad4cb82769dc889de981c969f732eda2717cc405cc276fc965ca2bcc80054c557c1343847bc6054157a5276432917501f88bef0b44521c0d5fa168dd89c9e34aca4df0a348e53eb5c939650a240879c0911a8e1ce371d7ea45e6f90b8db0520b115f826085ec25a108309466c11920984534c99dfbc7467af31d5f941784586bcc0347412c48d0927a4b95a22d98b49a1a20cc72272f09bb63aa194e4450c3bc2351ca6d2043a68ec30c705cc856b00f5054a66d3140bfbb47425a67eddbc4204944a1e379e1516e45216e12d06b2d522398a125728822ced62dacb220c845a444594b3b6977eea89e256878e52c766a86a3fd04437b4165242553fc747b80952769c10547804b80c1a6d85a29620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d7452a3e2c6a1f87c4efe1234bb9971a1026292c22c94449b7c8a2cb117b8175c7416284742120c11378c03256e4d2b80d502bc5ddc1d4e3c022bea80140307a3a214ba51c807db26f2536829a62400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34bb128bc0556fdc40ea9eb0b73193396d51c1bd533c4910b358969ba135f862b64dbda9608dc7665fc61ccd645f8926d1835adc34386cea20ffe3283f900a4ffb693a223755a50c4771379307242e4548ed4dcba4574410d409a4838233499a337859c64c6941d477f70bcb5a653bf571602e5224e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39bb8615509158b63be5f5e51a0e690f2ad6fd0c56fa886bd85902abd52598bc81b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 3f57ac87afe43d83fe09b407027bd7dea796a49fa78c01a16b064651ec669319f587597eeb52ea0c3139f2e478bcd671a12c09a419757140d489247281c02b0f39255fed4c1fb81c79497551541b22f23729bee988944c8b4771add0c0af47f9769502fdef1769bd4a280747b2f70022adff6d4cd868679441edadf0e5a9409b09b7ec9bbff46c69cb4ac3ae080830a9d98815950079aa0f889678c2befbe96ded187534fed04b6896fb5360537a8f714f3860c9716cc69bb4d5e30a43a2603c4dfca86ed7326d75f8252c90694b0f4562df8a6506dfb1990eedc5af4418694638ff90c9a8f9289831c3bdc7e352778d9057b467f0bb8d085ffa261ebf964720742939d80de8ad8d9608d93c124b2211a68c66e5803f3a29f4b0d2402716fb7f12a0b2d8b85f7bfe42fb0544714099d1745c7ec78a260fa8a9bb381b75a8a7df330268eded6ce8018a24fc8164be2fd923ea0816635cc0db8d00156cc1d3fd728346580fb99b36aed774209e9e19634e55e645948eb640be29c69076b8ac9f112864887d4bdc55a11650fd9723bc80b9c5e4e853ee34ad3780799cd4d1ff9766a1a70ec6ce7a214a2dde93473cb0bcbd59073be1f3943f2bb9cd79b3f422713f465a15db53c0dcc0ec3ca78bd27d491bc231fe03316041538194c9f6f3196ac721b8f432c0059cbdc53aea19025644b002b2d64f64923c0a09366454e54953edddb8ef2adaa6d6e02c99aa1fff571465f1f4c1ec6ff3839d46a27b99989438373469141fdb9481b8ec1d02c2919fd38779765efdc65de7d6754ff1ff3573d9739f5d7db2e7d831632704c96d8aff25af26f34d6d902dfb07d54aaaf3ae0a5a15e95fd69bea419fd487218048cc065dc8fd3ee69cc6ccb9f2222860247f8ebf7d1801c340dd412bc6629041571f8899fb0aeddc76a26dd091e6769dc129aaaf57f1bb12e38a8b0378f27eba1a360d5a9e50a279f32bfe036f36ab0a33f1fc22a18129a3ac0e45e3377eeb59836fe23fa0c74615d4c5bf6ac894125019c8f801d5f9a44dc00d1c4e6f29a92d3daa5d1b47415cc0df26a19007f179392caf4bbd6700a8e9229a858931e0f1314a705973d865140c583ed0b63a2ec8bcec92d5506470f8fb43ce902934280e24b32a1b365d984d9ea92dd2da2c91a21be2db4351107f1340a199370d5c431ac2681ca5ad88f2634b73fd96fc56dd69ae5c59c6eea3c4597fde8ae96c162a82497bbd35cbd3d51ed3fd09fdffa5e13cfd3798390f149302becbf108beb59a7ad4f21dda52c2fc5488b3cae185aad32372704616db7040e707f0aa801cdaf221ce94b3097acbc5bf11733be5db7211bf88d6f337dde4825b41d8b8c3797ea7b31de659e1b6dc33f1576e8ec6c7cc27a4b2e572df14715169fd2683560924ae674501da9aea875c177743a98767539681bbc043bd99a3ab8b78189460c0e2b4b2d2aa88f7187192f9be33afa5170db91b4a0b80ec1128ed5c1b25fb1ce6c9e41cc662cef6751c1d3a506441252b7ff5fbc886e4e573cfbc4b76c76514a64443371f7dbf959edb577a9d9b241f9d6422887f6bdaacb340add18fcccff5a89c7ba3b62d931a02d4bfc40a38e8964628d576f06819e04d2fb199d5d80ad0f618677e47c700477d74f65edbe882b4be41e25476a6ec9ece34324cea745b6561ea2d3c104e34a8830298736c8b654be3e3716d1c9235d3c6acaff4ac1ea87f9da0d07d09b179156666bb2e01973f3ffe0ef25d2920dda4e55b28d94ee46ce88b89a56c1067f4785b8f1369af3836a01542384661d54ffbed84ffae0c4e4bd1b6f1bafa08c97e0074ee93c6955012c611b3ac6b6b4abbffde55212c194400f1dd28df59a279dbb95c1a9f05d1400e1e357422a2ed4513e9bc97696f0ad239877e1523fca75196fae41c46af4df83cd30558dd5c45c0776ccfb7bd1813e97c26dd5775e3e223c0e09ba27d4dfd6108a2b730657d8bd41e7fc1f119531d5104c580ba6a015c5847110e181fba3ceb6b19c50bfd12aab3cd2e73d36e13089f274379fbe07a9c8e93cf5156faea35e50fdf008c8be6c9f7f502191f7898ca41baff0f61e1a561473e48b59e4dfffbe817ffbe3899ad97b8c4bc91d4f0daf68e3630bf7ee35fd95fdd5ed6f20e0fed9e38168722a581928e1bb4aaf406080ead269382c9b8c4901756f1869a2053d245d729a8d19e8a90fbb2aa2ce4 +expected_result = pass +expected_shared_secret = dff8310ce364ba5686b9d42a17922b8d5e9259a176e38d39687a5269455939f7 + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +private_key = cd28aa8c74142a0508c2534d5adc64284806bb2c653bb9783adc640e9945c253af86f57c19b42c6697ac85d1bfa46b5231559c11f5a0da9b2bf43c40001d4e6c00b81237343e15a41da190cf8940b641a4b42b72d9cc8bac681369dc07d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a63c269a5821557299ff63b9f0161368f6084132c8b56984f4d1626d7436dae2596e1b24a86562374b066d2483a1b354fff9766845480ff396f6ad089b724b0f15a34c2288deb05a8418909803cbfe2f3c63c30056f358fab798f4e385eb0e35ed0c38ade7382787a2502d117ad0bc6cc0a4746aaad23345f10074b21970c18eacc898472766b2313472dd3348c82f69b7d961cd35a8c61984e7ca20ae6382f04a977a72b532a1395707cbb7cd595e0da0202498058e59f22e0c340c438851674e3ab1e0d872fda3baa7f87b67f449e6bb461bdf1cd771475d5b59facc30181599ddac8ce68dc2de5741b21422fdd512b39d9633adb202af3941e323c9326297cb58086c3282f722c4d50b94b32153ff30b91f07a811a9d9e07b7667846806b6f7071ae29323156b668f831a9f79ab7949cb363dcc8d151349db4b5ec1266e7f5af98105c95c0a4d47648aeeb01fbe1113948b407fcbe199bc2cdba40257745d765c6a0766012f19df41a770e96cc95d3cbc70549f7e61914a73dc71062f2a3a377ec26ded59e0cc85b11a74f43c3237c7561cb7046c0e660b5bb0ba0634ff2b211438a9b9b906f241b04b2439f29a3cf0ad9128d683f0c2c26ca050978cc179872b1664a751458c072106fdfa07d97105188278268b0481018782f361d08555fe5799a0654398285b378f7a9f143ce20673184c75e8b662085899812912fb8a60485921b2f7b3feab95cb7aa327d8b9dbcf7c7256a131270b731e33f8f555cf4f8b7a1e6aabb4c83d2938b7b21beb1c3b3cb3bc08bf52fc1f5715fa89ef8e205d85862f6a2cf420592aa24568fa0b8dcbb90d0b654c7c82c7411b6c3e219f46c352aa034c4fa0aa4fc47daac204b351497727b96714359a66466f6c4cc2b83bf6b87785367c7116489d6c5feb975e41c4bbb2a3d8fda920021c523227a438374d96032f62c41b17422584ab5880475cdda8b7f4844e5420c25d97235b0acf71012adab59298bc80052aaf1807e8015695d92184741bad318ba9ae27c306a2e42c80512534963b70b9d0b7f5ae70326c33e7d43249e8c9ce386947c167c8f33c88947244989c45b4858203249fa5a136734153cd94f1ad467b5043f7ed77f58d34490d1b5f9e323f3e2146011921b8a9f94e419bb85ad965443e7f4a73534457be43ee5f677a63a7738762b799600fa0b9cd328ae4cf507c1d9845eda77c30bb7c39c618afb402cd9b016f0092cb61e8be13a18925ca122a142409b8dc637a364093cd76925a194aeda21c61709255ba2de330693b888a6c2c6f0c39fa5b4c7fcfbcc198b3253c0abc5ab5edfb438ed3a82b72b5f54a39d21c37879480c4a648f182a94ea566c598ba4cf697140a20fdf4cabbc540b80e8664216a6e880553899964a7b239d00c68e720706512cd2a58b9c49bc0acb90283b506ca196f7855ed69ab21f059a11fa3fc4670dfdca6dc0a17c3e407ca5f7c0bf4481d006bc6f257323700a3027b296b58b4c4716200c8b382190c1cba73b87c1497b69e8755f9cc5228efbcde6f2c0120a524d87080590a92222725892b588bb8ec10760dc535dc2029e4bfc7dee8005a82446534462fa1443ca492999c01d87d71e0b6c9d0e7a9fac2264c8c80baa5052f9e876ca5b5d2c286d78467b8bf35e51c27b7f34b45d5534b45b520aa18a85e54d22babe9b618b098a49810ccc2adca1b8226f8ab826ecf9c5fa2b665ebb5449075bf6ca53dc5665ca639eaa96120585b9b772a77a17bc2634c268fc9df25b516878901a1332dc3a0a38cac0104c59522947b92abec9aa8d943aa710305a9aaaa751b564cba271355ba882bcaee053487b0c899af306678bbef3b603a8902cbd61aa78639eeac2a387158e27f629395422a3c922ddd45ba7c93c6b97148dc7b990c51c63101672d87d10c8782cd48dc34a925be78b245016a144c392447f576282e1c83745fb395bb2a4f5f2bc224a0628f75621817798f70437e6381fcbccc547cd52dc3121b31062ca9d2d7599b62b942c221868e9030e52b016bb30bba71109ec9cf44930d76757d16452623010828925c340a8c2a7772fb71a09e1cd8cb73fe5c1a8428219b9f14eab47ccb13703ab2aac1bab159fc57b1ed434b5a00d5221c05ee77faebb4a05ea04d9c6abccdc5764e876305025e57b9e25473dbebab8bc207148f720f224b1a4887da3604e23321f17167b01d546b5074cb27bb5b6a365b91232ee7cb7f47102902285fef001e4914499da9e31eb1376e110b3bb06fbb350a054bd79e84113021bd1a1637be1a7d3057679b41f20fabf3d764c158457e7a967cd4440d4eb2c2d09808296c1d666784698115a83ce0840467449080e038b81f1c7743c7f71861d0a150c5867bb71db4ccf5c5a92955cd33812d3590b7b999708b38d6867b979650a73a63cc9fb9bf87653c5396ab8730e38201d3d493443369a7b424fc895cbfd96271445849c38ba8c9a969cbb70626698f12223e450c58cf5a384fc784914072ed92338f11693bcc2c48c201390144bd52584260a15bb48401baeef381affc95ac96033816c3414d03ee70ca8c947c7b9ba2052393d3ee9856cd52708ac02294c4cc58461b379a8b3b5c85396b4e90b678c9817c34b2ed2fc9e8bf346ebea1e6987b81e32b6fde7947a1772230257c0b1c564427b0951a451c11c6f2a7c27b6391c2b0581d19bad322038989c3540084132bdcd6368682927524149a4620326c7b968f6090ebca4b7da889b48723ad977bb76369d3b07873b5bead9cb08766702b90d16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7d0084f324bc15a0347ff2264bea0c88711364ea0dae46763a02c3a90b1655eb7d74a59d3687738f1c8b26e0929920089237a196d64a3ea58facd259c4d72e17721efb36c6aaa1572ea88d1171134fa331c43125eac801d1eaa9ef426efb2cbd6718a4be981ebd2375b73c91b7248ef21c6bf6b29a4c385ee899007e44a50af44ff7a4a973d933889241aeb90358f84943917441c7840d0348526b25ec3a15558562f107cf33540823788075931711c5133f8516bef21c8425088435405275b970c457abb73f696612b253221112a34376c3133164a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb3690ba32476f701c7af32575cbac0beeec43bcd8b54fe2c026d6c4b4fa150111bc58a8119c083a1a755e0e0c57be5c0929f64946015f8ac80c07a249eb68afff3388f205353327b484cbbfdf6236222867bdab6bb2fb4fda4260fa1b47bd47b43490cb11a9c3aca191dcab94080bbe8e394cb988ad474c122964739f05b5964070ddaa7a4bf2227e96498f7205e17b77d926695c3508f1105e4774126f014b61194436042c3c155e4a5134dc95583c189aba2bb29268c44e2b6b6d52b70198a4e193c0b4587ab18a0166c51365b05949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a048717b60c22d5b2a6cdfc4158d5747925731aa85bc66ec37d3384ffc7910ec5b4d2cb5442e25ac411112dd4b983b68a90bc57ddb122d73372794214e4e64a07ae676da990239498257149c299a193fa1cdeb371cc354bcde26c3238bae59230f4ccbc4614708fdc39ca5d916d80873908204b70391788cac2a346a1ac72a92673532bc9286455d7eb405c830beaca707fb865aa1d41315628ccec14d431434fff6350e518f3ea8422b44cea3b6b39910ba6b5265e8d18452f7119384244228a983c3aeb0b139a96830ae90b9c2e569fa885406c1270f1654cf69a34c2375f2bb537f39a61935af753cb6ef139317105c9f4b3dea094093d667396552b2b9562cfc0e9ea43c54f99430931f10bbcc0c81270ae352cbdc29658188e67a3de915469ae4263667665385381a352b48176539f59d4e2b19737309efe6c40a1a4d3f52a7fe47089ed22fb3b3c24531865beb47f823221c690b60586928ec5cb9505ac6b9c764b62b63273165f70e76034614ec354b38786feb660704a5de79b1d3399da5c8b1e0416af49c22d7a6982a338471cc88b18258f2f3b55bf51bebdcc53a7829e4c875f18127c7b5473f0252bfe4735c59388b305f3f106803c27c6bc3c51d38070f1561eac805070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305cf14252096e4988d8ecc4ac6d29ff09c55d666865863d03a68db523728910a8273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = d8b74a1e62c0230105fabee0fe5352ab849ef211480ca818b64eecd888685317bc56a0c6bf0bc53df14f5af71bb0cfdf146ca07b11be69b9fe13743c2dfa2f5c2df130da68045ab3598e9c7cc0510f2f8d363c5624f62ba60344019436150dac29a7ffa21802a8a341847d99bc10cf989f71f2de3aafa7f20d49bd37d14b6d9aa90e09418de03ee3944aad45322fae41cd0acadfedb73597ff0d2cdfb86fa3ebfe8e13d8a5158cdedd760d144676e2b7a7f9fef5862b6466f8c421d4efcdd5f93c8ff86d4f42dde6fa0857973061f4ae50342af9d8f625481d7a0c191f3744d138cd7a11fd1b39059d6ef5c4d04864e97f96561e4e54797d2735db1e79419ef1c1aceebd7e0d8f126a54c9dbccffa70ecd2ad5a5c926af4371e2d3192393c549190747fc6f5aabbf12727c772227ee77576cb07ac9e5d058535222351a5d2a4a3fae8d7d30eba922fc75a89209511ce945a6cc55475afd954be547a0dd6063220ac58e188655402e5bfaeddc3b800cd6a4488da839892deb75504e84f550bed98047a84a57e597e8b6e1585e96c7b54e5c8427251a2c30b4b5790a976755cfd4e32968066fb4bd324f50ba744d8cbe9fb96c08c07663d37d08991bd36156701d60e7ad3f7281bc209b0ec79dec9b480a38500db888630b105de2143f8648618cbea5558f311e231944c5903ab4f61113fb95b80ea1d0f870ae521549fb4d201c70389079396e56e7bb2822241dfd9742738c62e30e2019d1ebcda1d720725c936b20837ee40774b702b8a851c8ce68f571e8e1420d05400c2016d4764b33efee8dee011726fb090449c8982d5b8f80a861f1befe0e553b3a9914cfab46ec458fc72bcf3ef2a6864e52308ae4754b7d7547b6d2bb16d8be6121b1af44284949624fda63d9573e56070e4b2a06ff84b4d009670e6270d307ee32a339d7255986c7885cc28a9af64c4231c3d85a8e1cd3c48d4cfee7424bed108b3ce5e962f5d29ba50a60c7da9e8583401d7a88d53f647aa4a0c48b2eb1b468ebcb1a2cc7903768e7d6e359114f3babe93c0070e26388ecf5d3d6bda5d8c0f3f57a58e26bf8b2667bad861b5d5d120c63271e4c0e6ffd0d6beb442126b1af8f5a97143d0051a48dd727ac65aeae019667d773b5f533fbc23e2dbe20f838b03a43e2ba0f60674e0b2798be3f375f2c6f6106d8566264f82924865ca6db0f5a5b3ccfc8836872eaf443020b1402ed8575db8458489c2e39d06fc3f071ea6578713c4ffd345669948b62fbe1ac4e747a68086a5c1c0d3bdf464d82715eeb6573178dce7c53ce94c340cd753f062425fa5431a670ec5af19434f0ca6f18638219a2edd4a6c1186261fffb0575e426a6587efc48d88ffe01e675d526ba18e49d794765bcc55dbade1ae3443ee61c9869ba7d5fcb21ae42162f37a047fa8ef2ccea32d1bc1f6d08c7a21bf443ba6550c04aa61b4277efcc78534bde2a0abc6633e304bfc39e6a19385708d0e08f245b77363bddd153087a6443fea3b2c586bbb7e2920e29e0b988d66d0f6b0325d058adac1a0f377dc4ed8d73a18580cbb133fdd00fafab4ba16d011d086eb5653e3aa9f3ebe53f88824b4c027587129ad990b0a78308bd101e191cf49174219bd0ede582af30e4242059e79d90058b01f693d56208771dd5cfad387bf3fd085053403a6a337d16456fe1344de38a830e9921bc1d66de1119a9926cb047d4adbb9d4a80158d17404538c5f7284f2469d6251352dcf693fae17b89613f37549a5612fbfe5366149794f5e334fd95ea233b87302960b67b0b3bfc41596c247135d4f95decd2bd82e92cc7f92f27186916ed9c6b26aaeaef313ef75aa2b5ffb10d509e276db55497dafafe9ab5ef4c57050f4270bc467ca004e1d5aeed5b8fe80168c4004b7c0826ca878ddb79d8ff337194b2602d90c89c63311268bf37e717f9faf7a0cf1fed7b42f922b32b010166e0998f1d07a207c41d2fede3df9f200ddc0e9bb59a95af738e0824893d8e2faeeabc45f8de103caee88df2a99d4b9f8e2ec6d45e8c74aced33438bc771b267c4eed7a1a1f5309ddc877591380ec9e6008a6b2e2d0fcf11ee580728d05a66f02c59589a59cf716bff1ab161cfdf9de7694ddff3343f0cdfbea1547d59ff0baf541edf2fcc3675133c9718531138203d22af6c0db87a395cb76188b5907e72a5fe03a7333bd64baba11812efbb23d60c +expected_result = pass +expected_shared_secret = faa9833781a7a41691f236feefa0c743bc141f458ecbba98eac4a51ee1ca001c + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +private_key = 8dc4a33d0a013d102a7ed6a5303693669033816bce0c8a83594695531999647a48f6708c65220be4d9a60f013201a36ee053796356b26e3617126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0e127f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab222318856ba8b6919c5a0a667866c0d2166b69ae04432c044f289bfd7255542cc7946b82c2db388c8b656f234a3b607c2f6611acc3a5a12c8111e42138abca9b8dba79921a177682c2ad1138b133636951f5aa77a52b7554943af52f7b53d0b84ecf44fd77018f7062e564c5e58753994724242d6b3a8f8a66df518f7e13a0a5c1c4b253dce12ae197342f5d72c296498bc9888ec347f528958aa689c8ddb81870184c9e2254f918b7465354826870300790044165216c8bc279ae93854381c28cb438bce444b2258afc3a84cd4f91de8373f877b30137c4ce4664e4d330bf763b344489604e97f4c9c24ffc226d07c5824ccabe38cae22487ea2ea0e89920f304bb911b401f45735089512dca2298ea1a57f643cd7524a3d6c9f055b25eaa62fbda318a7b8c8dc9c5cea953ad5170c0452a7bc04469987712d0522256a1ec52961561175c32abe93dc5ed37289b9d4cbd3966911fab85fe47b3c68692cf5a845286baef91493e15c6d23437bf7517ec5cf609c8628d82ff7cacb54d4a5ead25c85f59ab51151f9350247782459b598a2089a85f2c9bf66797e863a4ca0732268a4e40c57009d0c7d1ab1ff46b78e350dbfc19fcae823bcc040183a27182abde00a966a6075e68c011aa62eef913024ccc85b460098facc9c4c81d17c577bc009b8f9416d225d156c4e75b84691a90948d31883b1b2ab3635dc357ae867b2496983cf9595423c541e3c17947042b3d141ef825c99862302ba911c67619434b3f9cc489e8c8abae92af1ec3045c895edb41f745aa1f3d1a625e47eabb49432129a5608571431c4890c8fa5769563b8b1f9ba3c1b77b034f568038865c90304a4f79f65f74c17fab9e6b52236cb636ef5b686271f955a9e889b7a1ea1a010828aea1a838de1723f0149cf172f48890161c34039e99b36185f068b5707fa476d650bf149479b8c928f93089a4b941047b5b528135685797e0b9e65f595d9016a614393cfd630c6a217d0a03091853f606b238ee13c92c2b5d9e19b2c57638ce82a3d767639e115838b8eeaa5a47b7b686ea05cc088abd47a10ae593ae39a07f55cb4c1347acaf7cf59422182749e6aec39d62ccb876094ba3cc0b871c57a03a00ad67c5c1c6ef911c6dc36b13cab713be1a6610caa46db4ebb86b76572a0bd60adf163b325c89b506c33cc343c37a2bca7cacabd90494f044b550778677c2ebee76e03622705556b509c204087b5c5e5936c0153857691c3149521b800b76c43195897067529a4a87d68e974ed57178b7980eee227e4150af1234025757eaa3b645064202d632eaea3943b40cb10922bf569ab2c44867c411bc8240d110134d78143d3d44b450056be166b57921fe64a44f80968a1941d91a971e10c347aba369702b1ed542984f28b6254bf61d94b69f015b0e32b05e8897502238fd21d87978eaad45bf5997654b40a903319ca64095c9297b6393b33066d876c52c5dc2f79f0501ae14475e179fe3b5747b7b11af7b6c7187eae775e4beaaf1e904f96a741a6a4820027bfd6b15513911d921835598090b1f145d2885063c24cbc26b3ccf22787ecb3b67cce6df4c1c45270239545463b0ffac611dad17a6e81c4b80543e6e7cec66c25c8e23560d32fbc8c29740433462749f15658dac545347c8d4d5470e15610f7515756cc4eb73966718baf841995d1ecc081d68b4275cc8e33a87cb61df5dabd0f7cc980d5a043c431d8b6bf2b661d7841caba2ca6aebbba4f338459561c0cd68b07ab2d6764c27eba2ce3e33452f072a8dc37b5d192db301cd2937015a5c08442731c97a0d9333a62648b43453750dc1fd4752ef16845067271a6b236857c69f3cba42a2c5818564d2cbc33d0e43c926a4d57c38f618b51fc0c86c6e778d478916c4a186052b4dc9a89f7e4c0b089aa23a771bcc06f3b43a8804a18cc4b8ded358c7ba66b5f7385996968a27793fe845b40a4af8177ccfb45ca82f3513d29be6dea3046c9bb080220bbb1a0b30c10f1b45961c6216fc930a8760d4b79afe948166ce6222b16acc847ab4bd9540cb68872c9095aa7619b88414e313051b7abc0248eaf745c7bea31b01b29c5105fd698119ae0186e7c89aeec141027b19a5ac3e1c419dee19825f518d46879f43c8720e23f8916abad006b3bca9600932a67938015964b25b75d95788278d0af8be577ef5cb1fe61cfadec5500ad17de196a1f95187106649ea4227ac9a96091617d673f32454fe68442f0509faf86a06d4c421746310341257f48c51c961342372954e8373796a089721cc646b6c27b2d7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331aa082d1b66d708304ab884ec6c7e9ca98d7edb489fb2ad522a2b0881997662205a38a35ed77d8af15b70346fb825a25b0962f0a8befd5c602550925ac9454b6a4c02db9ae9a569dffc568d70a1bfc95c108b03f16c799310a4aefb74ded63c3ad4791ce3ad8cdab1df854adc814b2a1164e551a36cf87daf367f8767b122d4c2ce30632f22341b5458eab4cd2e9547f83b2d50ac57d8c30ecbf5387db6049a61768ef21123936664a46b4a2cadbe1b7a5ff752dec141f38aa5b0b85546b77f67d32d40f6a588e63ef136013f0ba4e2889714c309835bc0d8e858863a29622a843cc49dd2b85e66214c0b2695dec22d3c4a0f6544940ac77eb8a1c415aabe7797bb4e8079cf74943c5190a549a78038883ec62093a70ee6022df193a4fd7ba17714af692923b650b94f5b854d07139b240c29361ae9a2cf34fa4f1f6c2924850471d6338206a1b8c806697589b5d8a2ab860f4d1614426452038983dfe2ca14ac40170aad48809c99f68e5197a0f02a78b481062413cd8779c59ea9864bd9c68e8705f4179405d5a5ffb2273051bc1366a26312895345b81e780fd1683ec8e3261e1291723978a5e3350ffb6e1a7923b363162eb14247684d01cb3f48b7abeb2154a2751061327ea5c3839fa0a0db315b7ca60b0a7c5903309589e8812f5301dda14e98c92c028c1bb57c1b23f1b90ee5bcdb448229fa6ef147c56862babd6aabe7eb142e9a671de69786010720eca14ef6ba53d71e5ba885d50bb325707865b564e0018d89f27f8fd2678be207ef830b3a6457166b031a307cea082b8260937ed83f20646e50bc022f81cc6738b16f16954d983cc7a38d365462a564c8d4417c29ec50daf373f0c8134d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f8810cf0be61ab3d678757131ff93b5ba9a9efc54aac9fb279991370742af6be65145ca215ef35dbf512f13f88873f87b17f3c4d9e475f90a02d270ae72734029710522b93762d404691910a3e79686f6aef2118446d23955da68a477bafbf278822276b3882feb3112f2a47ec753510fa97bd5e4111ec67a66909fa3557d637c3686a214a81a6c9e983039d5cbd2b1853ebc7697a8c0ab34342fd3561d8b3ddb0575eb62c0f509079a5c5a3eea1b23417d70eaa585aa36ac24993c6cb463d63fb6129583e7908dcc4c6e55ba3cf30eee2842696777989b90ac577bdcac111ee344ad1478dcfa7bd15911d0e745a523a64dbc28f03c336dbc9a86c146c8f842478a172706cdef994d87c562d3b39911441e6570397f503da1f07c0c6045c3e863c7f3bcd41b787c8016058b81fc7b3375e9185696813a589c75995ede730d39715e66a370c127121235cb7785a42bab8a091872650062a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b85342b350477688a0fc2c5905216a7eff70bc742723d34a3daa13b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066083b2805846267cb3c989926d72fa18abd97cc0531a8747ca42d0b35c89478ffa2d3f769b1b2c0961ec877e704212115df3e171eeea463877b2f911878a15310b6042c1624f6232867578a842cbb477202395f51c3c129385993023325ee405975e062c705a63951b080bd4b98e3388c74cb6c4d9ab3d66a5e543481f300c2f8a1a17e7cadc83195ab4c840756db9fc11c39196bd34071e1ac098ab332354bb23d5a376ca35862070c933875ce21dd7383a41ab9abfe2ac96170c22c5133e07089940c03ff80ee80aa18b33bcf8061fd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ec711a0e259e3548f38022a5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0345118a7b9bcc773f0ec10c3e353eb4365d2bbff3b812df4635d5c8265b5d8c5a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = 668488b1742ab2b5efcb1ecb1abade0ccd75ab2f924a22d86911697d54145df559b4233de2c6174aaf9b4a28a4cdc61e2e0e45525c5faa7acbf6c1010ad2d278de2a93cd2274d0da5f0d6228f79386aa7768b9bb390aaeb3960f4ad68c8a40c56f547c94b1ba4f23646833721faca288c9cb7cf024d0ca2ad9b1c038abd3fb33d8315eff7b6a449d00f23c1614fc34b561cdf4bb49e18a4a7f0c551c61fd9ae12e8e26d06179de6b17253d162db35631fa96723f5e7d333dd283d66c68f974916c5c9e9860d5b0abe0fb8c445a00cddbecde8e97f621e2a8879dcbfda62352d658bfadb048d0e283fe5a571ba409a77bbd1fe24abb54ba232b33d24524d9f06128c08d179218738814f0c5b694244280eeb08d16059e85749a7217c289d528fbe06aefb681aa49e53dc1ecf487377e936851cae7be021046b64e11309d8b42a7681b851890143097758f5c5579ff4a1790eb3db4707731e5c2c46e87d5d4403fcce998936b8710fbaad0ba1525bc0bebeb8ff8dbf066e0a3bdd26e73aa9a19319d3b1e227ee33be3688108906441f306fd580608fc0e9904e99c8f518cea697bdba243ff762da3aeb7181b1b8c36dc8d0dd4df6043ebd9e8d6cb03a6a0355dcd88b134e3230c9d590cb2828ef4015a93cd6a6248730591f467b7c16d0cb3ed65000d568f4a4fb3b72a84b9d104dfa3b0d1c75c81adf89320545940394301a7176201a95a2d5502df6c79299921b2db70b2c0a6421f6fd4ea80346f8b6d8aecff68fd3dd9f4cf9a84bc9f50b7407036d003b6b470d57bc9910b4dfebca165f4c7bdd93c8f389c58b4522013e891c50bb8e34c57820e775ad7d2f5c824e6b7ff090d9662077df5d90a378b7fad220687198fb71c554b02b046690798d0665a53f6d7443716d11be803b317daf0c32c081ca0db1b71530b70ce3d1a6d4b59a435e2d423711abb3866c85efa62d170addaa29499d59a4ff5363d3d628bae1ccc279c8c373c49cbb73190558334bb9de513b31291efdfbe824accc8f09ec5cfcf43356d2dccb747a1983ca42e2bac83201491b2bd360d60d38ac8fc9ffbae86c2a5549acd88848104cbfd2647eb32073f8a30089535b6fc2e52f078192e3f5418e3ad3ccf8180568e7fb0f5187811f1f3b5e53bbf5c0e9890e0ca9c288ebb33f52f1cfd83747895f58ecb635a0cf7d671ed298b7d32ba470e6bd0e25f123486eaa8bb304ce20a2ac813c7d40e2e18000a5f59fff0eacd85107ba78f6186744114485f1af0ec6d986335c086335f045791aba91a99d76d3ec48d5eb4d8baeb9ab91e20862d00d170770d2486e39e3d9db208784e9aaf773993b4611934f3097a58bf6362f3f9555f93e5fa8526d3a0acc9840c2748a2729ba37254f16e8efdb82b3c216cec275e2243e7059a391854f5c4dcbacb109fd2c6ce10195c1ce02a8add8664ff46f326fe9eb38930b0d15b5c5e51f25b3d4e608c9a69c80520b4939d7e9faf21b44f01972e994b8c503507f2f6e848bee6df7e6492cf480828cfd724bfaeb26ef089ae29651f3194d21658cc4bc03dfcdfdd5af8c1a717b8dd3897f8d28db9768b853b5b3cf44a059042ca1d12544cacd0d91ad0d6a5afb82af18cdf21b697565390c8a1d043728e5309bf3be5eb71445f3f354fa5791e3e96e7b19fec2f824389f1882a1aabdfe62798cf48e7e2c58838383f99030bc0b1765a3779f764ed57eceecf2f32a985e48edf1dae22ac52b3b6e16ca870254f4a00ed3ec232bb7d77ca2be0f30a834567deb806e1d95b43021aaa5f0092ab91318518788083a1f96dcf22d387dc7dc35d9974c85d9f636b46c684cb668681caaf7de23dec177add2af7ef4c20084b847248aee6249a6e820815125dd40e141dd130a5260191628e44db1481b8a5949587c91f4aecc37b46c3b97fade84d2e6c6448520de16895406db62bec81aa6a92d99e5a611096128dcfcb2f996710b3ee1fdc34b51b6fdaa1a888c3a52c2d2d048555f358cf2f65d3c3537207b76e9bb11c336fc4a2dfea1ab36b4f429f2230515d485e5ee47a6a85d7eb238ae0877dc523882055a6deb0042eff47997b8aad4acb0e99c627187c6692b15825ad3b55da9e4af3d5c5a1d6900b16821c72873e027665ff2a5d9c2a550a89e389a9781163a3e3e559a90584c4de86403f58d8cf181be224fcc6098d28de413ea774a6b166e6c3d82ee9184aea +expected_result = pass +expected_shared_secret = 0f47139a8b007c4ba77c91ee885435dfcd38d38c0aa4f57fc147f08b4751aa44 + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +private_key = 38bbb649e7520a59ac57783e32a5022489365713cce30171ab46ab219b7e81369af44bab6f5badcf613e963938a0829ace625bd8594ed3c0981c5963f68874aa87685599041c4c296b4cc181e57667d499b2f961f44773ca958193e97988d816d702078c0147e41390f503921f139384d75efc91cd08544536b4c9c09bcc2914a807e090d98b5c07c1a4a0c16ff0eab557e5ccc1871ba1a36ff66b1acd113facd6bd16053f22cc85634a3d56e564e30862aa1409d48aaf92643b62009f8e206c2c8bb7f357b9432a8474349c3e1679f1d154cfd4a373665a86c481b9c3163308cf3a1a265a6313d0068ba2181ae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2a429aff3c9eeeb869ec9982d367c5809396987a2efe93dfda2cf45e774cc3541bfe655a7280af9b7601fa5183ab62682465fdb273ab435355b84563047bc4c6204aec310d4b91e8b849182c16a57605a6f5690d3804d8857379e11b324977f30b461954a17cb16c4dd93761224a47f4c680373c51de251cb69a2c737cbb1f76d7278033ae86480c7776cc7ca02393f333b6cc00c200ae58922756d3664a30d7b262302672c27a7496746f8f56797726340c734473522fa880819d76a004a480f48b74f7c6ee1998741d39fec12759670b4e8057aedc67950b929e200526ba5a27e0bbb67570bae100b77d525af70b7b6143a7419a35273c14b492e1e42c5b5918a62f3c829a50c1fd8715b030cec454c90c72e6509ab1936ae7490c6b62a6720a840aa714f7b6b0134335c75c44a421598b790631e2ca497e256be08910b69c01997bcd20591d1967ef5ec5c035b0c1f19a01bc0103de6cafda45db70950cf551da2442741eb7233b36396c124c6365a83b66d9cc896ff448f54194fa05267b8154895173075039143dcc58062cbbb1946a917abb184788052920d1428c856bafb3461a463627ec7430671ce75bc2adc95622eb2925a582a15e487787389bcf14dfd84801a37bc39136cc1a49cab7cb924772606d48d3941bccd3221eb418b12a6342ab6c357f273795339bbc720439aa9cd5a478122b8b01769edb013686c8e872a4e2c049a755a8f954614665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc642c091226667c40957c17b3c92bea102143dec663b6155464ac7a9559c533a647c5a106c38972a26beab45c2f04c974c9bb860bca64615b6f0782305c81862abc973d280088bac791876d3172d4e340f26452f60009a49989bec107b680b62cdc12751f9079ed07c28143a405a600a974230b20719b0953da3c2da574ce2c31786c77600646e25b3c305f6507d91084a836366c273d62c526e0630f9b483caf335d6bbb5bcf4adeb4143443a07055349cfb690948487f7795b67dc2e45430e7a5c9564cc84cac0ad0832480aa844417446b9b086a493b7aa163b76a50f35b7384bd054147a8621674843c3040ce06eaec68b6ce8a2c5b42390c76350e10dddb35c9f4c4a1cc148ba08601f92b2fb12c9088922c3463139239a62e878e4db61a3529a8fa7905a7a1aaf90216dab5026469b27d4122af5561bb91d111a721a78587eea259a4c7f6b743574398e30a11918896ebae2cedb5b35b095c3ad863068245497e16b94852d25f3121e5792d337c712206c2ef151ed58c8ced316160979d74b4c54b1be2448562cc6c23b96c7eeb3600a028e91d817ecb13c9269bd8ea15296012b13281bda6213f1753823037d24f14e733267b3c31cc2e2b235f1665bd6a81568c7bafc902a6184cea493508772866044a2f7c2aba3a07d560d535b97499bc0e07423221797cc11c46562c721a99c100530ce0b0f8d09013d27bff057a2456a622475297d49bb98595d6efb69d9353561a028e6b5a9da9a4207ba35f0a10b4cf66d7ff4aca409c8edb8160e8a60c5101fd480cdb05362430c98bd8ca34a318405024cb2a425a45384d501889e75c954767a1e274392c830694b59778a158f0b06cf2b444cd2c0134710b35cac598b1de47048d3b204d004a7d8d94810f9a751d782b7ccb158f70f262a53fa7b3d46676569f12b37370e17e1ce35cc0a230465a03903cbdb30ef18ce8b2033e9c5c1a686067ee639bf934b29b5cf2b921015549075cb0f609653e202afa388a409167020156648552c8dc941c1cc6424693025e263aef87f3e0b7147d0b8164077dd580f8c5b8f8ce10d77b217adfab3c65a2e6a04a662bcacc640b0eee6b08dc32c661751c0c8bddffc2e0bb78691a68e7eba25457a42aa0c3b15e17787619824e02edc7804161a3e7fb092e897506b8333aee03fd8b11c943853f1a9a44f5927309abde1321d60f73e41538cb9f83e3fa004011a94a200cc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29ba2274d759906a9043f2575f850f1152542585b9feba4368598c883c65120048b7c85e1a361adb0941e6479370f01604d4bbe85ba4683bae545b3772755765073899b00b0de9a6d810137ba8a91aab33ebc21c34274f3c995fe4ca8aaab926e7ba0d83175100fb261272137fdac3ec38ac299a25d2d9c514937e4386a06831ac39e21fc6e702a50476493754a37261c7187cab94922ae12f2b032228934782c056aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c6717905456d55016360d789a1f5ac166b1508d6100b0ce914216ca0476566ec33417ac234597a45c8a519b40842e5ee66b8b69269be2848053c50b38c258e38ad3104e9a1a50e9872dae129c38a367418c84f0cb5acedcae229291c3f6aeca507007042f609734dac77fa01c1735245d06f64aefec7736e077d5ac9d8767346250c7dca28105477b18c681fd779123e93788624007bc729ab13352f9915d062df3367d1acc58ed8478a9e6216a826977b770819796f24cad7db1538cc41c03a8192f2323c68a9f28fb0145cb543832639158cb098b7693c615b820ba01a3838cf805b9972ceec7689e9bac7831701d543e87a880fe91b59743888aac439d1222a5fc33f5068844fc3ae421cfe80c50db3031584a21b4330ce1a7c014b11eb3526ee4dc740ca7179a428dac27c128421167665f809959a5494c6e3a53f9d74f6e85ba7442cf68d999ce2a891da7cb6903ade2f576f858a5f731c259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a3896917ebd7c2e8c521bac1c612f0aaba462e48a30ba3d37a28507a16e20658f34ccd3905db5ab94d6333b1390e7a93906eb0c59932840cf55227f19a2c8728a7d385189057144b462a2338df6151e02bbc53d35412e4235d7045e47154e4b910a47ca8ee678595bb690a6b4459b23fbac0b51b055402a9a83f29691ae02a500c9c6352658fd1816a7a9e3f593ffda6939820530793382ba38aa851433585a39c68c7026461f9e0000b365ff2b67a93eb83437b5207061961233013a41cf7d1ce8f86c6b8159a65cb979161410d24b1b20a1ada82b72d127e941846e9d16d16f3b9a63b9e678057a20aacb88238ed9ca1c722307e2c2f3540afb2b78ed999981ff6a0a0e15f3c3ccadc9b242b886d12f29ad6113d63c8268c56913458ad31a04f6130845a1942fe68b9384c3fd2f62fe034c8e6ba23bb6799163553291ba2376775c4a67914f78bb75026df18aac6c8c9e6e77351dbcf8b97106d7ba0df874b1ee2bc508222794543ea60b3dc95093f288220f83b6a6b456f2a3bba809af288ac08b44ba9411bccb5ba61961817e20b7cdb6efdc4563a6b4b4888058f08ab01d702fb015f20c9202af713de66c1cf133bcde0277f84a5c1876b7adb21fc5a82555474b70443bc59355e3932d20c14887c25e9517c69d807c30a842cf50549da1620ea315e5a20549b59106a6e1fe56d6c4657d6f69891a7449a57239de5137e8c3efc2994bb0b2bd8cc49edbb3661820da27199414a33d804acbb1a80da68ce288c0974b0b1a8f038fd1819bd8090fb022fd648331699724b66059d148d6445acbcb9b910ab14cd0482972858b56541596b5b809aadf81657796c544c02b9a6eb9160bb0cc6445708d71051a89a88830c03c71903892860b950fe66495f992829dc783691876a06a1ff983965d67f2207a60643a6cbb59be857408d802b86f054d5137ee8e6a02d2603e29b4e970a9ca5f49e64e39f70fa5912488c98d28daedc20da06c811a38aafb0064e9ab2f3628587f7a099036a0ec71d70b04ad0e26919146b4006b15221ac78ea0599325b9de25c81506a786949deb23bae43c27c60b79f73635dd64b35002ce5d40f9808ae6a51cc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b772f50f7047714627bf76bc098e0b919145fcd8df6922ebac383e5c556738390e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = d49c2b7a2106705cc9c8c1a257b88f7b647f7aed1bb62b27aa4213178b6f39ff9e94185502826a0c36eb5033cc4cb6ac0f94ce65ba99b40743876a3478661c824ba2c86db3a7af824c0c0e771a94b181c80656fdb2b200587791262bc89bd2892837037132dd9b07fa19d14e4c5fc19302b26430bf8701e847fea6bb5c10e3c8305f90c9ae4eed53dcb4d557234b06bee720481124252a4ab77cc61347aa38136342c28d662fa1e9f52483e30337240dd14dcde53f9dde843a77aa38887d8e4dfcddac3a1ca2b713167f9b64fd76964c5bb1b6800f9d2e904f3b4a573357fc16f2ce32eaf54306e850091d34f3f9762420e56f37788d081a3ff997af2407d2d48d86401777bf63a4bd51cbe8f6072ac5a799c9b174130b2fb0efd787dfedcad6bcaa7a77854da9565c0e3ff941061db8e166e26fdf9f0ed78c40644af0e5cefb146e5257fa1d410462abd301703a89222325cf45c9198227331608feb7758b15bc3c1860b94f80e14013e3a313f83560b8c0929e7ac731c06aa4b29adbafd18123557bcfd363f595950636180ab6bd6076f64f3d8cdc2de61a69e6932b78f1fd400e1be742ceca9c85a088e459ed8bc3cc2da9a50b2ea8a968f6bcd9b1f292961f07d96773ddd2b48479f8896c5a6ce6d1e6c856c7705f5f66c513f004c5cbe844785e6c0518e47465aafa1268062ec079107b63802e02df1c7f00001c5e06e0406d9cfc3b264964d458bb3589605a6b15bcac15605c882d42b37dfbe7a3fcad0de74627727551788d1d4c1bf27d139f86883db8384ae53dea68ed93a83380174824c08db979a773ee6648db9ac2cbde415c8aba0f66fd7a2611e0a107a9d86c06479568c462eb9dcff7f0dc0155ce7620526ab937f04061c52324e9cedb8a39626f57c19ea40441177ffa949184c05eea0b013e2b5bcf36a1c8800287136960cf328e63eb51a77c64d9d1351753c76a92095f04ab8eb7a4a105b7776cda7b9c5dc5eb9ae8fa2bc069b745110b04486ab6f6af90b8654f134fbd3c4bc06f02e8620bf4a452cf3b39f96ba95246006acd9009c14d430d28ccc3634604624f7b4a04c14ed0ac41a8f12a9e8fb004988a76926de95ffb7e03de5e977f356d13d4fc7b4a0e73eb65e48124cb5b035a4e3ff30a84c1ec565a441eb5b6bb0f3cc7bd1d51703e3761d19c7e1b1149d8d67daf17805e9e7276edda6532d2afcfac2eaa9707750d7568e4c2b8bd5f31b4c1f5adef0abc447589dc8cf3c3c78cbef3df957bf9f87020106cc927990b93625a91858d7a1c1fb2c7127f11d8109154d42673744ddc3846c4450e698fcfde63f9260b7ebdfcf920b0f841fb17100dc9e6f7c654825be2e8fc7e4f8afb32a79e8e85c57109563809086a23e7e4b82e09a89afe2f963334482019aac0c5d52180c9bfa0db8bc5d3120ee0560581cad04369d2593c10ceb449eb9459770753c7e6829179e11912247d93e98db06197c7d44450035b0a2b46dfd8624949bb98b4ee93f7ff1152baac80d8a30971af84f4b8677c06c2486fe85d6f82c092976f5a15178c3f4d7caf1ad0b8c98bf58f400e8a673e49f9584378ee71fe72740424ea9275631d16e84009c3d3f64e131362bdaa49b9d025ba149e0bf770a76566533f28f060624399773a0bb34e380e99680b698a320e6965c724ee3dc2654d3cc520f752886ddac9951dc921808f9d83f466e77e3c4ed05dcaac7888947569c720f756586244340ec5d79710d80a8d3220c7b95cd3a2c649aef066e204197e4161fc7bfd76cd92ebe5e0fb75984711e38c51449fbab7e68d6e3f3c0fca0414d19ee4f83d5b9b61f53dd0d8cf65a8ef701435d9c0a1001451564a7f67eab8e2c66a84c849dc50e8d099ea1a55deb34ed42f8a9b385b51b714f45402bc9a0c77f6c2c321d31bb5e28b3d26bed1e76355f0b96ccc71db5d4eeed4ef059771f988aae855c363d6f9fa8c2e9118ae3bc33120e1e7fe672ae06dd7f109ae3fab3586122c6093c35b4dbfaab4c25c34364272d047d4a9b39a16958a764a00ca0426a9945dafb5fa44fc288f8d24dab2817bd6933235148d93904946ea753421939c6e6cfa42db032b37efa8fa124053b50f7ab54e292a7474c86ed599539a583bae64084eabf0daf4b8c1388e57f3fb831a633a118881548b6df15056f72109c1d5d78b25b81c7e3ef51325e2f49cfeea570af8a1f69f1ccb9288 +expected_result = pass +expected_shared_secret = 182d34d0e83216d26a9d13301fe75a3aeb15ab145433965996255120cc9a5f86 + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +private_key = af361347809757c2ae0c4a60393c90222c394cf136e95517552721ff136dcc234d64715a1ab43d15708187f89a6830791e0062cd43253ee486ac54179d320fa6a8bac4d0c07b7158a1eccfe52c4847403849982d73288877d04eaad37d392aa487597f80f19af7444e5a82cfbe51609ae515c1b320b6c75aefc121d5e2904a0185654a418e5c7a379b41838ace149b45c5a4040dd239ada846102a6bbc811ebed4710b2393ecc4bb8c6254dc815d2667831f962887a74eb883a5a8642e0b427450d01321246a8797b7be1211eaf64b0c706eedfa17cba2b010626112ab6b2b2b928df38ccbd9b639b9c6ad090e92da98b5c9914549beb6a9b5505579a56943d210722bf590d63c1ed56534a96552005226c34cc1ac32572d2ac0823bce348086096525188088df229536bac34a1c95083309a0971f31d975de0598e4e009d24661b2a79dfae85343b94fb1bc171493ad77d767e0814837348616205652eb4f98838ce536691de8c3af0a4970eb0c3600b4605841bcb0884e08bca3198b04b2afa6f575229c56462b9516026d32d2ce33a4b1add3b411371ea6516765f457613ccb50f94ab9395f6fbc94395a6c9c104ce3b79171a83a49b22add3a915086b804c3b42301bc1f14630ee3217f059aef485c019a4248b4a78a516d75919eb2b15bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bfe30a7578044867897c332687d925c8bab05d0c35693f557f541b571d6ab7e4a752b80267b0329d7558fe4bbc54c8612aa95c03f81641a129b1793160dba78c4e0269e9361087328a73c67c0044217a25c2e05b64a1b8ebec972606bc220b1a456d8ba86a76ac4a3c06429cfb6035ea50549db887a5f6170ea282bcc295a2ef000f571038fa97b6bd98fe0399ece3755d4b55e16261f7fab678c394c83676cb9f080bcc915c8b1c67dc998d7097074249585e31c5b30bd0250abc570531db43f546c2e05983a7b5219127809987343cf722fc38525b2ecaad2ca703679cbb7500420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04d3259ad003db768559e173df06a08793b10e5a1a46145b6f0fbb230ca504424b4e9617cb3f509993567b4cb94cb2cb39811bc1eab31b5f5691ff4108e5a6eaa9b15dc2aa45fc4ad26b9ca007a7c2a680acefa88f12790abec7e3da1c13a355c1c669117070a7e1976f6859921e273f53632b4144b58e0a74207100d2cade0c8a0410814d40a4234843a44978d0d4a173be52434760423235f5d7c8e1f56c8181487bba930cc9272acd524eb6c9d71d753fe62b0e9ba33a478b7e82b36d9690607550aca261085a08725281b02e531432b35398b7ed1355b8172776926bfe41880df90af6951a58981c708724deba6b6c2bb8af1c0009c71a0b82ac0d14cb0910a8ec3988251dc9e93f17e067608115c85bb6c47d33a2a9359a35beb47c3a04ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc04008873004bc535bd5c74dd49247419601513c4e8125731307bc858845896a67d33902afa4b58b50be969b947851bbd791d66887cc6e92e19a2b92ba6bcc2825c4239ab2894b2467547ff3a63bef65edcd579215aca66a13cc6705453c4964f1c29499179cca36a3b998bcd173458127b5f5c9db4d12448d3914f4092f7f37f4d826221ea8bef6889179919eac60dc2547c5e6550f45bcb3d4b41de1b12273675a0f1c611b6199f27cbd277a38a67b77aa3ae87751e96f4b268f75b36d070cc1743b469a2ed493d50004ea5269e91bb4111795741f713918438b9945458f2836d42247254b2fec86cced59b0c721f3c372923c0072f31576bac1c8b986b25e035fef91fafb1c7d0c19c94494f4ff57d86064b22b008214375d0e61361e2cda31472c5d1853f6ace7f8765659abdf95904df05b976039336c9753dbbb216e599347664a7b170eb563ad464a16ef963fca77564b794408acee8395135aab683a14b0dc18413f31b8a4929111550b07b50db2209403854bc4391e115095d2b2f632a76d4015b7cc34e9474a75c124396483c8f0c03800b1f539623574099077b7dcd364e34a122bb0b738d863db019cd19967e48a181acb23cff56346f32135a30aee015af3b463885497a844562107a6350672c2e47609ecb47db696d4fe16e54341c0a510ca0293c25f69d027a4b7ccb08c184a68dbb0e8822393ab7b05ef08c4610a0b84c8c4cd5b783e71327d925959782b6c106b08436861a8fb2c1ce2f239f19a73b84966698c52e3c380a7da81b54ab76e62929e6743c88b05457868fff3074f8f085dbb05816c8b4803a7398f1c0f2cb3765e84672b24fa32838f7199a8f738b89334dc6f391125569b12a670cd37caaf00ac919aa4b92bd4da706973681b696b33871441daca919216760b41f5000a7bf782ac33491382b1c423734016cc8ee4b80e6e25be4720ed05439b9dac5fd240193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f2902da9c4a641fc36a1289640a371ab965b25383b7f017834fb4c3c3477910288f8b305031a7b97b69f3eb48780d3558c7c741171815b169e4e9a62a261460ff2caa333150aa2698d243ec55abad0329cf8fca935094c6795489c902303fcca7f257c7d072eaed4a31c9146311b21b09b38326aae0d914c55ab756d7b0cd761510dd12572b912ec79b61fa230e4eb9dd052b29b775d891b7025bc89c0dcaa0a18855988c215c74f06b36976101c0f697cf8db4c0fe25f1c016cd11154f5a5cebdcc4add13b31a63336ae621f2257837b16ff0f6c07eba6fe5b058a42122aa88629014256017bbef582e123365ae37063fa97277b2063d3860d3920beca27638f02807fa3bac4ac08614ad1590bdc6c855f4d3b292982838923251a348cb48753ef773570ab00768341670c21dc7a356931e5b8ab51e8b2615f5689e607953f685aeb6b999815b2cc66c24f65d2ec64e4ee88d4cd830da4c61e15a033e37182731b5b0b506def921bdc19a85624630ba9102226f6c2467c9eb21483bcfc96a22d8493f9ef8b7276378ffc16c3a996f5cf6755d924716524dc85c39d22a8254e74244229c975b467ac94568312333eb578a197f4530ab74514fa174855904c7fd09b2003c3b94bb41c4559b45c00f7a73935ed15a39e47bcd46497141942c3b669642060533ce5ddb0cb4c1369dec82b8d7239637b615a086d4aa87630439d712a55556cdb911734a23779d7c5ddc628d0f326b5502a79da80fcfb3aa8e607fd5c25b8f2768515618538a990df66fe57c5c3b3a354655ae4fc098bcd7a382301d0b721a1e74795ac23ffb8c5493e14c0793cf03063794cb0d340a018461ad89e17ea89b7b88382b9a288bc4b13180db6ee6224fd929b628049c20c1c830504e09651147417b552b6ec810c744210532bb011a93baf28c20512558bc1c4c4a07565779b7fcb260839506e0e0224099c5751a93d6141f90816ea8da87cd1105715a67d0b969d8b748a46831ead199eb4c28b634a82d8b988d2a6d5c797943000d2546957eda9b1573bf534b552f225253d768706c8ad4c42e2688b40965c0dee151be4b7625d92e79fa40fa7c00093148125c65e841cdb86aa90a02099e2c6c4c0bbc95f14fd0734872f2a6d6b3c9b3d0285b7ccbb5b715e913245c14a5aa146f003788d4a76df1037195da2e939cc08f56c3c25405d7d1851249496d33421e5bc386645ff3a8367c3bcfd0542c8962ce146720012087693c60e3a47de4570887473bf9b68c22699afc314afd801a0cda51fe4340e4e34ef18c07a9c7a40190908ac323068c95d59bb04bfc11ac930f99d082d547c99a807c8d112d82f1b81125b41f57a243006b772673efd286b4d24684d2b046b53d7d26b6bbb862d64c42e0e909e813391d6a8289647e91660dc5891479c43769d9608c10763e5a35acb9ab7552a08d167abc9b02d3798115d4c0b6b0782c77bfaea4bc27835b4ae525bb052f6dc04d65074e00207213d612e746a44cb5bb55311c0d4a43d2eb3c2003cf3eb895fda1001bd55484992a384561152779df9534b933244654b2c37b3caa368319235a1da431d958a4dec38da311412606adc0d26022f8a822e4913b8b5e97b6c2525636b586c8b3c62ab4dc73539a028fec33a5704bf95183847361a8143d1c22495ea4a229b4214fc22334b857344c721ac2190b554f7a30479bdbc8854c0f0219b4002a0685119aec442242d15cdde0983f8c9ef2b3aee24ca7ed917b90407d5ad86906c0c865149060b36db1cb1a22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfaa9f015f625356a6bacbb5e565c70184940891589309a571b7166c2ee713b8fbb9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = 0efe44715790e522dd7c57674b14433a78f6ff40d93cb8418bb4eaceefcd5b2f9db4ac2556602b9c21fa8f12123e3784fa5e47cb2b1e59a1df68ab72bb04c1561b9b002081068df5f142a6157afd480835b0231e575b5ef4a06a9502cdd90d0df551482f563a47e435aefef9fa79dd8948cd34751bf8a6dd83db7e70bd00c2f89433a4ce9c3148d160d170c5c720567f7f7c4ec572aed3647744738722b1a7d5a657c031c65b4424c2677527e0eaf5e71ece38d307d5db72d03d2447b2be57b073652ca4a01a0733ec2bb127c6001365ad553b18ac2b0f5f70ee9ff6440cadfa07f1ad4f4e9561e113cdccad1c925855c78502e38b6e6be1af5b08a9ee18dce358fa089032772b0d864f7ec014e4c130cfde4c7b4c36246b14775d4f500e135b2c2126f3a4c971a9d0c26e1221d18c9841bfc5a2159b3918c7445ee24b4124e3eb8b73d96df478fa5e35e8a7c5e8d2823cc1e70e320dcb5b3c1d35f3ce40aaf700b9fad25b289241b2e259c69fa81ba095d2427d686186aa953d91ed8f3d2f5b3fe248ab7b51680192255e09b1d26fcaa9737889c8e21081549ab1bd98e1951674821135f95e84136621bbd6bf40501d71d02e6dcb278aecfd9dbdec9ed6f2e076e61888e63e9c2d4e89f22f2bd6a7c483ecdab4b1630105359bb5da97dbe0cb65c444a90299c4425f2d655a5d6762ddc671d87303ba65e06fab850f391295b041e583c59386d132091e8ed0407e89c97d4c061d87b5df0c2c3a127729c5c1538ccce52dcf845cd1015fdf457e39f3986c2d987384af25823fe56450e348a8035c68c05006c07b6d1f6ae6bde926a84255e769a6fe84a5f5de7a6d7be100bd68048ac892cbec2e16068d1216d0928e34f42420e90cc88c9b0bcd80124676f38da8f5a1cb0ca49fa252bf51584ff49c5b631772d38a2d266f1a383fe97c716dd3959bdd4f3341746dd90c09a07dfad70ce8a3247ff2d22fda1922a8fbc13a776f80fcc119b363de7434f0c44d92dd9de68d1be0fe59f9e288eea89be67be109dffbbf3963c11a36c2d1b25dd186f924a1ddb43338670b52765658837d6ded97d5299081741fe5311371945da0c8d50c3c30b79d111ec1eb1d42643c43a3bee2cb78fd6b682688252556b3e1ec7bdc3903d8f1bc8a4bc243e543043257d5ea5d8db320ae4b5511e51e53d1cffc863e20bffc306159f74cb3d674ab3008fbeded6bc8247911cf4407482aa4c9fce44c8646b79487335f906fb0280731d56cd25979326f941a9eaf669df8177a9c4eb9451aa52d96be299d7cf819d20ca35698affd625abcbc433816f0059a28586b034ed15e151c177df47a69719420df9359bf1534db883d910f31f38c2d048ef84a4bbb13d6dd5b943de1509ba15f2b2bccaf13bd1327dd3e972e8a32a29fbceed5c6ed947f470bc73f0b8937e5de4e32be391061f353f3294ff53c64b18a5f198b72fa9c0c86ab49011838537f8fdd8e651e2b56f9c14eb18d6492736454f322894412331ca0b236b7f84071fc4ca7183335c848036f8898f1a9c9b3df0498f25e41ba498bfcc398d2724c671fb5949558d67716b3b853bd6921e14e3dfe5dc495f0635b28c5ceaec62395f68fedd6946cfb3e723be0d45f7338e0977f1990003701a7c6dec5e470bf5861c7bdedd2c7cf2555cb7a19e606085e1d6a651976d4047ffd181f45c36f047a7378a7c2f7610a4a756bf8f4530a221e9fbee0c70ec490d30b4ae209acca94a8241bfea5c84e2dab5765ca9f9d0d72d99788e60b9e5030b92b930ca94d45225a572fbc7d2f8ae0b27c2b334bd528eeab4e6ea0bb32238939b7850907631577982dba433ca4a717540e54bf56282040e8cc8c59aefe7800a792e2b575d3e413c6e8513f42531187a943e4a64b429b2fe196972f6ea484b6cb84b7bd8908e660dde36931f6013aea9c5ed1b9300369e32c43201db1972075fdf49f6afb94ba8fc81097f2bf4212bef0a1bb559e139b434af763e201b13e938a3c7e30b8515cdbd9720340a53686b02b0b841cb6279415615789cb10bec3b92fc60335e5d05ef77abc905af3c02b31984cff768051ab2b6eb0d286516af882eb89aac29b856d46f2735b57869cf0cac9bce18a1f535fc5f219cb339ae357ad1bb8128abb0b8dbafde98c49316b43c7fd26ca723a4764e3767e6caef79f1bcee92a877d59e1618d099f29f1482be21f9c7a +expected_result = pass +expected_shared_secret = 62a14f68d726235fc16e0ac57ad4ae0eb3fc029abb18567a4ee574b44924693b + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +private_key = 31cb44a14c3ff840758055bf2afabad14a723c048d4d20c5908bb781844d574a96a0807c59d5192548a0089396a78b953aa52677b9a111cb012954b674571c5d0c7c5e6488d498290f7665f4f32dba7228ade2a724413798ec32619901215663b2c26360612558070bd06261bbab86b4f96056a498bf37b1b84238c5099ec8f1af4251c0862b861f334eee85af8d364a54f6bad0e44a23a0577933ca8482889a955086ea3a2c94b057c1c20d540cd6d2976126854ac123cd386a855caa385927318825494861079ac84606ac0f1810eb78a8398740be69cfa1777c61a5cc1d758ae28c072d6087c379a567648558ac8a1883734c64361db33cdd156fd371a2abe534b162c6e336143b944dc2309aac106525d6586793a2b3420358185fc787c2cee3875e3425be5627c1d49313413ee498b17e8c295908b718b3c4a6e03024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd0422ae2569fc37902ab90bd2c236f4da66d78301a61765a77e43ace81102c7355749c1463b55f10e26727086d73a1800924c6b0eab6ec905d5b01adc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67cb20b38bab1a8d81cbd22a5ea8c7587a13bf8eb8a37e5949084c26b4433741a31c502a4c412535fc6a1c5000057c65103027f78f81ddfc4a8843c59f8563bebda15da543be2146a3eb7b521700958bb2a5064923236193d981bd1e2920d00b1cfc504e32495dbb116c5bb7aa21b6cec5c9fc0b1ab73330544e7af5bb1ceb7c159e3509938d0332cf51add245606617dcec688f117bfedc27dc5b8b4884446861b592b720b53fb23cf08513f66c3b51833e51b9a63e297054a8c03f8baa257c64c2c8a265a8a92052c41146bdb3a32ce0b7196aa33564806dac33ac05a20178c2a0cb04000d484f0325c9d16956da0af88f68bb72b7bc6b122a486cc1eb01bd3027aa316c6d7c1ae7d8b9a747443c5d7237989a93ed939d905832e76afae4172d5f70589e54f7b5cbabb536e5f316b3d38911513b400ad83f7b2a3c72a6c09ea3b4f68129ed285fb99442fe61237d61756a2ad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea5920128356c369878855126c22f1ab66a3a4c202892c8863b609f7926175cf1e3967ea93b7ade7a8e6779672023dd5d81bd4d9345af36a38db17e96b8d85b7c0beb586aefc9fd9ebc585f071c1b9c34fa2283a60884a0cc5ea210887aa677d24192db582f05117fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e9410b4ca99a4a880b48053878a45340d0056031068a63113be4b51a630016875541e099935ea92b2668ae84c5a183cbbfed619691038973cc07b72adb803cbe26986c827ac75428cf183cd5fe7c9c719378438058f470b62fa977dd658f219983f97b517bb1aed01a478a18dbb89ac1b916419a3b25f388c276c190b866356ec84c33b29022286c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c7b2473719f4e2b5c4ab8a4fc172a132439e0e3af22a1beae17ba4cf39a155925c62a4c9ca76436496646906630b9349a335a4852c01b018f77da15a4a47efb74a64fa803b5d6927642b16e3ab78d13894104882ab803da0015b80021eb029fda191edb38370c2c4d0f1c9d76d776cf4750bbc0116263b65548cb51031748480225d85f364a0ee2f18e0c1a19203c9145bcac3f175acdf926d42b9cb6d987b9698167d775c04a877a460e47d24866bba3564727eb2a2ddb6868899262404884a138b20b1aa21a7003e35a79422c35ac37059e59164f805af26a4a8b3aa0a0931e08182f347151616c2c86b6a83699279ac00195449a1ee11490076a5fda3f044a75e844ae996b7c6022b2e09c0992fc08a16c29686c7c20fa5394d0a7378202958719633281435b055f3936ebbc1bfcbc5f4105b32ea37e4a222368919eb5f07e0c07b6e7d229e4b51b3bb9586bda9e90383f958b0c9777a2d8331c7e777021ab9da0a45a14b8b88ac78425f19bb6048209223786d19f5463724f009c71caa35dbc67f661ae04e5b3fc9b1d59119bc5506fecd01d6c574880fa8920c54a3204c61c717e47676692dace4b48236009a85cc212f7d9447aaa52acc65d25879df1312d41f14b53ea0fcb973ead32cdf833463ef73eed9a0ce2d09faff9ce3a06030b3021cf4360f3e4cf93528bdbe69d0655171ba7b6d93cc220a10d37e828e54629c6239ee13c0a73e58f0ab6632e764a840753393b206c180b3c333275db3f05516fde08803f7bcc10589f8f54793f732cbfe82658033694e6aa74823b92cb616433072d405e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb56292bb1d796bebb5c400f30098591447191a7ce6a3b2cc3fc7ab7b5c6ca02c6808be45671012867812c2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd6734736907dd3a9e60e4637e2ab768e9558339921d8c1a8218926815cacca840224052d574164a4661afd903d4516e43e3984b31554e5b666a9cbd332a9e6c63036d34189616cdb3d100331bba659649ef0abb86502fa994b941f9a354231110b8080db75c69ec6ffcba48642b0ef54479dd7995f7f9ba92f8b473cc7e31d04948648af330aa09996e868c75bc3949bc3bc8e5923df68b5dd78bafd3318ae4fa6224b8a7dc9814f7b35839b05cb709cb1cf2c1e80aa879c58b29677cda375a5e4229bc8431d48bb08af0bc27f982a6723e60b00df6e607665b7a4b4cb35e5162ba3698b7140ae7a25a3ea76db07626afc773854038b3d13654b7cf0a1a8e75959e5ea0797ef4a64538c19f0028dcb5cdb5803815467e57aca68fe00c3352602897aa88021203a4b970ebcca77846e5c01adb22859e41cdbfa8a7be9b932aa2c6d391379a035455d84282d5ab90d5b6de056f211cc6af61c1d5b643f8d299c249c055964c56906f88778a4600bd054850a9d92557ab2c33dca2eb2857b9617018ab08f25493b265b10ce74889d8cafec53f7b6805bfd637a6b6ade8a65d7f885c3af645cf08bae250753eac8e2b734a75976ac9eb8d2633a980285ec33b154c1551162c81f0254d2eb55a7db13f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d0609e5b36b8b7e097d40ccaccf496f3f00fb957162445025ed62592fb61d41a28b16a1f3a3cc83b1b173e9599e5c49a41b93169dbc4fd006a93bb233ef73df88116e091b17a06125f651f52d501dc86a856a96a43601c46f32b1fd6900a6513f7d298851b443242c62b34236c7495881cc3fa592ebd4397d5422f3c40ca62980188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3caeb0a980d13de0f3129e151c0813b259d53efa07681048888dbc082adc4dd324a028d48fe728701398ce20425bcc9b410687363ad771218285617a39f3c7bfbb2a6c006125d6fa6df88898f7b236f7581a8a077038a06394782ce7862185f4ce98ac06c25b611da7701a80329228391da903607793bc8a2189a123c177af9d987ae9d1c6d2d01bc5910f56514532d582ca092939119444b3b736abc0fb5140e14c723b1c6abc2034929a7edd48ce3d469b16b09cbba5008728baabd54d15f427d2eb5e890a5a13224038328fcb227baf6a7ea3b82aac5844d809ad86b6adca537c2c0b4e0d659606f835129905a6760cfd68b5697b9a8ec00159450205cbcfc0f8c9fb8898f135298ee99a154977fae7bae16ab9325231178a764c1b10b5c427598490cd9539b69b1848980d09768c435233f52376371b7971d861c8612ecd160655e83ba1e60a553b4905d35efa1bbf58318d78353da822241a354b439b2449a2825d43212be80483c167e6c5b50883412571cd2ac3c1b5aa1ec9c232e6b9b5a2091e189b3ab0b323ff13654bc60ed42857755902d063619ab98fd8790d05d85bef1ab23a09a9c241a3cdea620b6c338eb582dbdca9a6ac40fef7615091445a93b8fc2001e09816ffd54f7870b5ce6a4fbd46c3f42b8e63619b7675716bb65eab17299b57c45c834226dcc6c1f98593782c9733a078db34a137c5422cc1dd87a614c1604972559937102ae60337d997caa06b0f33c43b093af04595e5ab48a7a0966ff318a735024f004d6f1893b48b74b42135c43425c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a230cdc1249b09833be95c5f46bc5905b73a82206bd6658464659293691eb58551973121a42385ae81ac9ea2eb6419a915441f41946e504a6b9d5716e909bdc49337909282c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1655d6f749b0a013bec99e017f5e13bff76680a2f9386f2ac6938d7950d5fa1f9f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = 76a8aaf524ed637534be4d3ac319a56d11f27da6220746b43136c9222548c8015f12394c5222412b1806c7cad8b4940658d1519bc2f4c6880798992cb3334e607fcaa0344328bedee7091854ed2fe4332abed021d113833f6a63048a74ed630779914cf1a54a90f95e3d32b3a8fbb2f7242f7b55a688778c10fdfce2e74a3adce25266a9017aa799a79c5861fd63a03ea009985961bbb7d0458fc6a2cf56a64a8741ea85cd56501f6fb2762243c788fbe46fc963526d7060787f111159ea1145c107696491c3c838a8b0e3fc9b820a349962416c4756969ebb82279596b43a152bb8a96d880f6f187e5b8a6a2bd2b987f82401516c0b199ddcc49e7d609b2cb4fa8656b3189efd325b04c3b6c7b257d2e56087cab0fc74230dc7c440550879d221e066ad553dc84f3b77c25c1601f67aae9f2740e5040efb324fe3b86e6e9c558c9ab9ec0b22fd838a92da19ac3598324297c98a5461c9ef76a3f92f6c83b99cb842585ae68adbdc1cb99111ed0c19393f65c2b01f6a504755a671e40b0c336396aa8111acf71dbbca1e3ca4f901634a88ccfdc88eb790d15e66f1441fd4cbafa6f04841a809c3cbf26677f422a15c2d93d361530dd6a22391660e8c6619655fcdcff7c82192cde31070fde0ab9a027388ef188b13449d44b7ec9f684404f38d9b58fee9c1ac8703fb5a88f09b63b2e3ff4d5c6c7968c5de612453e42e490426bc8259b040c7c942bbf63a68c440ef7cee3687da84ffcbac763fc67946d4438c0ef229eb2433d848bdc469295be7b09d5b1daba8576f2502261361b4d9d206912d29d6f7d6b52f2872b71e5a0c6aebba71f89b603c81f1a5241a901b21ce2e88f44982aa3612ddbfb54ccc5536a5ad82f9ae5519bf4b2b90530e0887609577145df92481bd786e09352d6b3e5c856378324beee6fefbfd62ebd43de27666d17c9f2b668f20937b75276bde8d2763077662dda3d09cbeba14cf05e138cb8386011a7b506c08d12ccf4781172431b6dc70aa723fd80e3cb87ee0fad2b2211ae0b046753a7e7eae4dda7bb689104f5264bbe2fd1d99206e8004e8f658f3807d6939759eb85cadce7272723675d1c41cb7e5476a15f238f7a59cff42a7bd39d4374f9a74d63cdace08d74f12739ca73aa8ec8da29832611a891f7ba94877c493326024a8cf0bd83c8e29bfa48df9ce2c227387ed730046bd9c30fd3bac87d0cdd03c5f516ba20a07221d5a2290d7fbccb7fa9ce69d228fe52393c3ad9e0db134ca5cc085ba08ed902cd1e17319936791b8b0281fc1b219e8fef1a4b0e7e7328a7612a99f392ea5495a8a850e4059ff6d99984cfa95996e52a6e7809692f807963f591ce1543ca2ec33ed51dc457f7494fb7b641aa65447a9423cbeee9acde902ae6e8587f9690a67fad158905ad6eb4b86c435ac36914e0ba75d8039caf6ff4d5b9fb718145f95e173a0f074df2efa88804201f928be5b7772d5aa3ce8e48e4474a872a7a602f5e8743f8fdc1757240c1f180a24529b1cdc4d57a23afa8557119351df6f08e64ed1e84498c34a2dfdacd75de045a9ce6510e93fa4ed22735a16a7e2d1f4fe7bc0a22512dbe45ae055666214b6a61b495fcea2ac2380dd7849fbeb227583edbbe2939f63e141fca36b0e2a03c08927ed4c72631f8b35ec8ffb5ee7d3c5b3411af5d4f8b5a713709b53d8685d6930033af0eddfcfd20c3c85978432b8c1efb116945b0cd2998005b346b516602dfc17fb5b7d148512f8f074405292d3211d2d7eeadd046232b1056a8e8455e4c74dd990402b7164c511f8099dcf4acc56ff320762baa4ab6b0641384b153d94f119328f2bbd09731643700f9c2702eb83831154f1df082fc872230360d3819214a629af48be4ae80cae16465e4e0970c37bb432feda83bce8c1d89d772cf8b1fc2d5315cfb62b9f264c34fef2635cb1da048e22207bc84e5d81980efedc994c184efbd9fcc05120cdf8046cf15a3f27181872376f4c3e5868cb96518a0b0676f16ef277fa153b9e05688bd8db52496ef64a8af467ed46813108037482816d581f7624619e9d77c1c43dcb5a0579d2958d427d020e098a4e8714ada6c77428f0746d6cdd0e5a55aaba012cb8880b1e8af0fc7a8bd79e332c26c6742538ec997cc9775003198b0dfd2da89870c20e136f380d76d90aa2ec27f8cfd12a58c233b748fc4cc8cf1ccd58d5cd428a8395eccc +expected_result = pass +expected_shared_secret = 4ceda11055991ce1e5d910a240981e39a6a903b20ea6ae6a21d9d56d0935efa8 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f2c10c6e197927c89e57088c4960c46b767e27129fe78c7cae38717e6a2a7fc16dbc1582ac697e8915c90281a0a784c4b75345a13161bc6a586166d4385b507748d3b9516b10550f05782125c10f3761aea2c631afa83870c003950b891d96ae721317b192f21a50f2b2caf49f81177790c29c02216759b005692ccab4281927a46739ff7a9583e9a5eb9a62314e4967f5bb375fb627e5a45b918c801b4b1dac24d55c13aa7fc5cfc104647295650b5cadcac2c74aaac28b82233f64c1c01ab50f16213154d0312c5add25af449cfddf494045000a01c449d1084c876163c83c13321b1f6f87757dc186d4c30ce916240e538f196936ab9bb419093fd593409f3a308827ad9002e5a621fb1387ac06b442970cda9c720ac9049cff1c307806e9ff9209fd0cc52b9517c685c36c45801875dbce490163c91c707755cc8701af04deb9aa0ce460f24c72e5d811c4ecc297abcc4c9ba304c75812196409c19be10c494a8b138a6f05fb5558e7f2cbf6f1694e7d417f73781205b941eaa3ecdf91c71e998f9a8b6b72400a048a77ce4ad17eb265313303cc86150d477e42a39cb4b8c5a3723d03550f4b76d5fb7b524ec2658d374a8c955b0fb3fe878072ebc0201b2328b737f9f19bca8411f35980890d71e7bd9707c917545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cdc05fef147fdd625d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22e81cbe9bb0174a2b526b6ba0641456a3cc941569124557d3bc652dc8259ac66552db0ae06cbaedd091c268c2c6f4bc7e948329778cf48c3b37f9a3ed714c5c8e0099036514d9a052631b256fb7e7f7c91ea0311b8db8721d5001ae90991111c5873499bba20a9d08a135abeaa544706dabf7338497c578084e1bdce9155f87417b29313dd39505cc90c45c12c324b5d5af01eb2656d58607724725485465e33a6a64da220421c038f0a625254ad127ac941eb23362649d2049f8ae8c057321aeeaa31e0e98fe3da74d53938f4f900b6a33f1305a383cc12b35894ad498293957950010cf7912174373967c294bb89a90331c828048e3fa862fadc95283025e2f66dca10104be8b9f286c198b8c9f0f24c79a454e8dc0742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc09251fa2780ec0da59d8b12b17179320d23b822a3395466dac34384a364d06882592734f72ab0d2dd7131196afd4da54fc5801d85928cf61bb257274c98479ee0c2f65fb985f6c669d948fac153158530849311f0bc51ae72bb8c23ab5fed55e793a4e8489b423044a1b017273a4be35a305e19934b99b45dd2734ad4cb4c5b368c7a32650f306b7148c199a44bcc3a297429cca6015e906204c827cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648a52bb8302e32098c26e9a51a6571c9c290005265b6359f07598b10c7674f5356b0365ceacbb55b1a1822811c92c44f0e4bbda4a13364749c5384ca7670acce69bc48b6a0b0b2bae8ac5cc40aca6ce24957167cc0f24dd0caa3a0228c13934fbbb0c205f53d713aa441f5b0feb01fbd008209296cc096645da876b961b0ef736996d95766ba0d9f89a4a9ba5d8e31af9f5274bdf093e40169c9b94b0958ab9a585645da158a6176c8bb196692bf52a8158d7c9c2cc6937516450f50baa77022c748c19e68cb9bec6c115806a30552ec242d81b036d840c3d1a9bc15ba4434d4176418686546cc38f35ceef112689850b6bc3f7a3a544eba0ba809153d4c3a21e72a2a9c09845cc07efc1282123652826efd0267f5c9481d8c5b07370015d593b1828dee3aa6f55b31525b9ea8c9772740ba325b072e9211aa104baa516e7f528202c5b0f6f8a4965332eb711ecc9a9e4b85bf9d0cbca759093916c4992a338dc385c9280dcfb50805d95525d59603e8051bf70049698629267b2f29bb93f769b3c3b553f20cdff72bb77811b39c276623c98197cb528b9f90e470dbb378ae9750f1405c11551e6962709a266e6717760ed607db4741468a81aebc72abe9080b428b5844b646855f01f989378702a6894e24969fd605b261129bc0a567389acec88b0f15acb1189718115556cbd99a32a8b2861c097612cdb6f437e844b131e016f3299c31185123951b2901c5fb8296762292d6b37f5bdb67000d91974c77adda0e8601a03432c648848e38e45d8b9a45d8263e64d603e0f50d3f438acc29ccbe54bf6cdb0500b50344a96837828bc568cebaf055f070737f4771c8b4cb87230afbe824d6312ed22ca5e2d4c5dc354d44935ca64aabc5a64186e51697b9444a50569861404bd7a9b76898a3626edbfac8a806751d328bc393b83525514c56b7727110f802cc41bb9c43666b25e26987cc813fb7193954a0258c61b4e13f2da32ce3f1c030bc0081060a7e091929cbb729584a888a06610489f3312bd576666fa09013f4a191b498b9637df5ac5610103de4734c7e82c99062c34063b01fe2210d0bba1a15406836275aa119042b5072e77523a655f41316b3dc31f39840446886af337d2ea0c532999635786d9a6948164c361877891ad903a0c725289c4c02f81ed3452858d93489a07ea071847c38780c86c6de1c22f1db704a2249c6a96695ab22b9868d639ca4a8346ae0845aa8ba151e14941bf447b2701cb715456cb91b927c63f829c562628e01f88499a60aa69a0f3ef410ebb2698889711891b008c0b11a98c47e291b763039e5a214d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a654d0b13d23b8ac2869b4062ba3a27af9f4468a216789b92bdcc8ac7ff2b86b134606a693a1915c55421e8260a872f57a73047f496442d7b1cf44830a8cc01b27b54f495cb984e732c4a40f99a17c5f469f311b6bff9c582f888910da60e6211c788c2ff2ac489f1163826b672e6abfefd917184b3f66d72deaf652e6a596ebf5248a2809c3187c4a3834f220c28f55b589e161479882aac21407e56d4c541282b1b330a7681db50bf30463168733faa52cecb1a8c2d51724b7afe1976e42ab7fefb1c234da45aafb803e80c972559694548ee98ba2c818010ca940f41429a8222b8739c872b1afca093faab792c3e965e7b0bd8850be2498286ed9b8c9a6987577b98ec4a7835cae03b28ae9130ac40c5af971738e423f7f905a223a6c27752bfaf4c495874d0a984187631f50b8aa87ea806e78a1c18c78040548443587486171a11288d4d2a7d19b809ec8c5116575f3c47a1b419529112417a15cda9a0fab5b7968a0937b4c443dfa3d0cc893d4bab60bda28da5a7a7fe6394f6b1dbb207b5abb9b0157a029063ededa1d0f162bc536cda44b598396772e4a3173ab4a22cb91e4b165a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee7923c64baaefcb99bf37195ea6b657d442097289db24568d970ce526c11f507cd7bdc3facc879893c33d35b734fb9928f82867c5266dc1199ee679ac2c337c35c435f90c8ebd0aa29e22a169bc36d605d5a2cb1eb914534f5b3d89a769d806dd87b0d32c63d0225cac6aa1b8c3b7d9258ca68cb8086b673322716389876d85c71d2f5bd3d081d812ab37d026a34324135e5988fea7833973d3b25ad2b8777f3f8691b5671d05b266b61c272076ed0d23604ec7a670c634a7074e889c030026a1b29c4b025c59d43029be2c2a2665dc2f1423c063e1b78b79b550db2281c3bc88dced5345882b30ddc400a62bd35c52bfb063213947b89a91df0fc0f34f53555853a8724a9d15a00b285abfdb39e97b5aaafb429042aaec4d21303f1217a3c0ac7d249a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d650bebc225fcbc132936c9741b496d1c95d8318b6b9b9a71c071f7af5547f895fc4e313e3a262d31695b9471dd8f50f6e227c7774260d60ad56ac7608430f1c370cb917adc3b7717b484b52158740740366a42d9f010c333611e0d29523b04618895cd91a21629146bf1870ed2584ee8c0a728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba0b0687d39094e034399973e2d09116b225f2d41a86b61936743806e41a242b63aa19532f19c5fcf0204329537e996a08bf52acf80c39ce1938fb581543cc77146cd34a5223af8bffe735fb327c888208b5dd648d41ca209f976f6f226f853545a525f3dfb258c8074ef9a442c639a38459fd906a8982a69e29608da98b4c4a59eb6ec04382cc584e663f5751f6aa0486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb91c3c2aed0ff6944819c93f9a9fe77d14a16a385f644de118099fd4f7f57db9a0a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = aae6b8e3eb42edf187f787864affaa3e657383ed66e1d6c71386437f74b297ff2cb4884f17c32ab05efa09d27f3a3bf26076f79be7dde0f24f2f2c9229a8f10033f15ab8424bbd1c11e19202ed71af921842a338325c8997e1b9ba892ab8eb4c060dc28ee5ac28a047054d3ef96514d75aab341618ef99abaaedc22071c25728e1e19ba78298df96e51010f32ed5fce1bea80fa7b1bce6ab21a8cf80c478fd9f83222d29199ac57177aa549442a620687ed3e0f349c1930c7b5f3308b9b99ee8dce261d3e430b5e224ddd31d810c28247a2ceac2d858db34353cf7edda521bb7d50468feb2dbf07c4ae5f31d6b686905269321a7a7ed721a0d943779494be59440c0d1d8c288a6ea1ba07b44cdedfd9b98ff60648cca5b0000b11c1a1a7a005e5ad5cada8a1411c998c96d583757e8d2c50986165e1e9cd1b73c1432a79a25809de5843360eb9064775cec0a8578cced7ff6e5c7a9c653533e1f302b778c9933d6385857c0a5069c176d174a2b9ab7adb7deecfad589e67926806fbf567b834fe907193733d2e00a084331ec185bad1c85fd6b132f3a469ecd97c0d88ad87d0f864738100517f8aa407009d6fe14e597ce9fbe6963573105f1648e7cd42532b70fa0f499ceffc9fc7a3ce33136cad449bf81785a0f7002cf724710269dac94348be7a722eaf9b51b0b81e9f6d9ff3fc7e4b2a5bff66f35692c1badd5c9c7c3bf3444e188ea589ee69ce5c3e397bf29abeb71f7bd2df6aec7b3f60aceba3be1edd3c222f1aa2c6c415926383eac51a9e15b98478f12b7c69e4e372b0d443a90ea5f374797566acb58b84732ed7321f1c91f4383301da30fbdb44ab7b967d72f502ccfb46d81dc5746fcae3f6de14cc63601c87eca9dc7a9b9a406ae604d30e38536d7271c9d1b2512a8e1d0fc9cd9ac0ed24ba41cbb7cac9b099dd9d9a0b85b41363e19795e868b49f05557d0b49650f0c950a046c57917915f3a238bf49f5859f5e35087bc656987fc4600e6db90e3cc2e9cd4cf97df005c5f517635b92412d43477f3c633e51797d084d6286c5cac768d22a6229a8905b51157e536edbbc6b4477066463e44e21a31b8b9888168a460b1f80d57252bf8c145535a162270cfbfee98009a0f4d6e8ddb953c468ad14f7855fcc73d593f572e1796243d029559b26067de9db571b8d9090d49342aad33c23a5c83dc2205256fc1efbfac5b78fc39de344b1fb600001deaa75856cbb22d9555a381906c598e44a8e43d869972c243a444c559342d3ef6a9448576bf7e9429d407465c3513d2525510ffaea7923f066bb16d105573351ac0289975debc39bd43a49758b003919db44313910ceafc4e5196cb664b8e751b82110c14e5cd268ccdd393da65c25a6af61f1c509cdfed0df06bac8aba62c8fbbd69a45ce0f4c79203b543deb8d98b4a3e74d0f8c0b71056963faeb0e33ffecba17936196153fd11cb2bf121b6a80aaaa21e16cdbb4a70e1c1c6b2b3d4d1d9a5568733be1ee64ab7a95fdffd8d3ddf944692b1f3c092fe65e67ab40a58ecedd6e869b0be37bb69c93e8459f338af18a043fbe9b34217b2c0756b08ca505a5e513a2a07b12ef71821c1cfee1c4e61bdefb849f57aa9bb9743f06310780ea951bf2824575a7cab3d0edb7da713d68cf3eb3f9b3483a5a5321f07d3fd6918e258838f0f921080ae13601e123f854fabc15d7ee2cc33dcfb07b0f1236f6f7157306ac2b59a00136a2e1d8af72676eb959650ca42e46ffadbc1401928138bd65b45bc3e67ea59ede671bab9cd3eb856389303f2f34903c22309afed76ff0ecb9d2ca6b6251eb9bd2cd7a17dfe5b50f8acb1f3f99f3001282623bdebf20a91a4944538460b15d2c5896e8dad33cd1c9f5a0e2f567d564eabed3b6e577a2b03b8695e238d9a08ea06fc48e5a906947880cc343b6b2189886a7b88db45012815881631dcddf43ac5862283ecc8b798c4ee4c7aa56bb7dcb158bd1ec7a0c38f2df1524282939a58472f056d58dc38f7588386aa04940394fddd34ae12f3aadd564a55f8a5d7fd4bef9ad78c57f83e70cdcf284dabfa8122f10e95739586154a0e8916c80059d76df5f5b25a745af49d6cd52974fcaf65c938af7d8da7a14fca12530a1ec7b7bcc5083b4a7ac2508e8a368df0fb7b47c678414842d4e4b4b94dd4ba6c4cd7db0f5dbee9943f5b89fadd73a0ace826f58d2d6ba5b57795 +expected_result = pass +expected_shared_secret = 8d8257f05a4e76ad11783f7f6850c4f1c34017bf5ab47f89eae202132ada42ff + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c464442cbe0879fac60cb733496ffa7116011cada07377eac759172db45c9035532a5a48c18f3343e7fb3a0a7a1da9c75f647648a822bb8fcc59a2e0476fe958cdf968433b46ea296056a8460edc0b7d4430252b227cc38c8dfa639a72759de9325d3bbbdb1a5305e546580127b11332bb666236924ff1f13105176b81a777ebc946bd4b962e8050c0f80be026a513f7c9c74308f8336a9bc73bcabc8353aa10afb69aa502b3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be442bf2162dda987c602030770555c0bc62b1422367b95a91399642155cd0b17dbb848b642c765fda2400358040d4cd154a68db36265bb525fc90988fd0c04bf0b66ce052bb216d6183b444cc385bb8ae17388d5e8024aa41563653b5f72899cc16b37d642f6ff7385f557c941571a1c73bd9425fef3c343ed9b88bd02a9be5652736ae69949e43b5c9719c4b8e42c9071c10e3d454b3c90d315c93579cb106a3b16bab7163983f5c514b818516bba802b7fb1166679ee03c4c41ebcffc6322db61a7988927dd83b48c24bfe82a4fb1901f70e2c39c411fa65c43d56c02c79849e7745bee15b70e405939b055c2a76fe1021e094b4671a290f5d708ebf0b1155b94fee9b34cd9858d3a8dd4bc27f5fc0627f2a80d6681c11324ecb74639540b72a23083c3758cb29ad40c979b42679e1436fc56b3a7d1115137015e2a2af9a8bef038b6905c8847c16558ba2bc6ea92ad90b026228695d664720c15e6708b0934064760a745ea4a5587ba211312c7203005f838a2d5b7bb09b8dc7aa39d4956d494472f71a268991ca907aacf8048fc98c095798d0ea043c42c437f6762ed3678b6d701560016f405cad66117c786b56b3a88fb5968c26869f73a2227b129553b220f67cae75b5433b29259553ab4375a0aa6766b2aa0ad480b6969201ed21ccda0a39f8b8f565112565065d8d26dbc1a57425a29fe0a606ba826ffe45a69493b08b11712e88a2b4b0371db5c0ec0125e2659ed08275d18277b9c0ca51797d46cafe91951737868483a418427733ee2637b4aa9496c30fecab67b0b7278a76da2da201874711e6928b7a40e7859378c867b9ba81529656200584ea9a5881b657b68980ef8cb201338ac1b856c4ec5b0c48a80bcd6676c0ca624f05296e59155d5587c2c20bfa1bef1005bbe9840db205d9658935a67614595bb3fe48e52877fc5ba639d023f54d534c58cb90a0a98bd1c2e9e940fdc61193d4753d17463d7eb8c9c6575e0f6845b5c0a5bc69c5f90128d3078960671394b75c5c72eaffc1e8ef4afdb395ffd40a2f6bc75fb9b79e1d8756705b710b0bac1dbb4ac312fff30745590739c08bb25cc9ec62caf1226176c161ece62aedec392a3591ec2ac80e92571c1417be7d82b2f9a1990d50dab78c1dee631304ab5ac57274846a8fdc6547b224c72e0781b233ff8a6c876eca3a3e060a00b560f661042e85340c4a8257660c0592a429c7b81b5137d410b5492864e156dad292dabf59035fb0e02247e6c6847cfd86b6958c74209a8f389041e5389ebf5b9b633b7fcc08cfe14ba466a36777830d840b5fa9b7234403074861984e0593c72c3d5405bc375255e239258b47d782056f106a4f9a493b584909006061cd98ea65a8c131b6ad696b993a66ecf2c32ae1a12e24c83c7b696edfa64b69b71ea7a02a85097d25bbb21fb1475d250d64a9c87598ae12c0dbb7bcabefcb48266b483aa5310e2a734a8519449bcff963c4c10340ff42e2dc883d9c15d744a9bc2d1752383b6c9409e29b331e87c27a11189c41cb8ab182f82a920bd7c9ebf785b09b5be32813e8c128139356f4d60b2cf5c80bfa609b9026a18360dbdfa75d49755dbfa421e9407df6218333331e8917955a551a7f962b8e7be6cd43a8a35318406471161205b5a71e238b911ea2b536c861b0208b654a1fcdc0b77e5429379295354ccf6e93d41c2233852451c8b44b151286020b4093988fc23c533fb83c510720a278e75eb047a86ad2654225cd0445d7b9585873672522e3b18c9bc74ac2f536b5e6bbe6c1a250e50183c16bd79a970bba86693cc508094091e207600009d3893b6ad96433720bac145b6e0f7b1cab23a3379caf84ab285e12ebdb602f431a82e0b098ea1a1f18b18411989cb1b035d0726865712f5cc1e6b51674887b0e00c2eb067731dc8419e64b816955b407a1a813666d73b53d7955639a877a961b4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a391bc55b30dccf33dc1a93b9b784c7c3429ce8684e1910800739839bcb926374932a7241267835caa9131818ef9aa4ef5c1a3e2f03bfc83076d8a827c082f0d0c2ff89a8fc2e62a96396dd411259d26c7b9c84bd38c557fa45103f3b793097ef6b775f050033109ac7c606e2cb05497c9c596639a63171f5e70775de9c545b919b9e199f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a203825297864ef536cf578c277b6541083168d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b7a018e3e5cc8c581198e2b4b372002eb756bc7a65a4d67c86ab022f549bb97904e035173ae9c1073a9d23a315d054cf0e3ba27d401bb04569065256be9447a06caedd97871b52624f43916d475c7539bbbbfab35c0864c8c77b12242797323bb12935bf5a08c2ea4d446305a7345de980a03067513f6402e14b29e7287e30194dd76856ed80c55bd65849c1135d398994007b1f14a452e36bbe7283ca7b3ed1b67d0fc3667387c9b3c3cd8314515cd2c4e51b96a8d43a1c755c65740ba9830f65356290953b9dbb03600b18f4681f6f039379f26d40f2c8cab57378b66aa245197cea225eb9b712c95c4bba470b07bc6c458aad71bce067b0991036f5f54636248c516c88eae013232c0191257cd0a6322704c9a6d005fc80c6c6ba0636e701bc5847c091045bab969ab85f5644a5f8f43858c94b276201a7e77aa5c413c57b40726302559762ec40178199526ae63279fb510c8917ab40c1b1bb15dddb6d1c2b22520780f222c15ab2a16bfa28753a61a949aaea6abc3e3083a467110334a959fa582261561d3c8fa671ad34b8b7ff2b682020651935cab1b227d75261e3c98930961457a955275734d9f41c61069e1a5569d38a1a1ca1876e481d94851e62918fbd550e45fbb79a7130643bc1fea1c722675398498c6874ab1a7997008a166c9146882c37e4eb64c3e306d2b2b4c1409a81da2122a5360430774fa56c5a3520a7e870aafb55773124d93b17451c01c7e21be33a9de7a500fef26c7117c13599024ebab75ba9710c5465a089375b2a751f5c3eba8151bda4182ff3280826c3190b9b11b89bf9d151c4a939510007378895f916bbb8e107031459e27c9ee698a269425ebf5a484812271ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd82c10c997ace9e09f77cb9fc4f8c13b25a8a12c52c7729f22a3290140c7ad0480c00a175db293cea64d422baf4bd306c5d446d48b062f751f47891a8fa82b9786148c364e4dd85507c07a9b4448e57c2795554b3cf53d5d14ad3179669862123840a7aeb57240d69ecadbb48521c196dca4705671b1e566fe59b08cb963f417abd01a1915a33367508cfa9c89413b7709eb48e9bc2e809a56b027b6dd3a513a2428466c29b6ac802f9a83536ba1adfb96270c57a0743c12733525311e8fd04e12c52f15468e84c6af54d8bae8214c152c56082465b79a6cead444aa767571cb1351e4cc05a8a75057c5745abb125a5382cb8a3ea2170c104ca21cb5da000002b7231a8a0a23e50d173485c7d1cda9e8c1da913161e34fe0a986ed5c1183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d21f170569165ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93b506a8554738e522e11bb3b7976f9ab17ce8a190b0cc810258972a10283c21b9fa36384ae0be5556aa252a59c1aa7617b480729c0272576dfb0c6108db290a0cafb8588f6db8b933970ebca0933c9382acab4dc0c75c4e9a469ad60c86d7474440b870e7958b600b6a3b48cb13c938652198c183347358cccb4d45ab3a4fd7c7730470c2218726157f89facc31b6449fd6b4666081572ca291ba6e3657165b053c6a239876ca5eaa0bc659b0b1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc5d006ca6586818664ea6108bf0080966ba83c77aed8fb2066c94458e70a90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10357d61586f671648188f070899d2eb3408158adf5e8056ef37ab6d8817cd8275e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 722ee373d0ab7b12bfdc068bde1e6e3e25205e049621e8715b003682dbe090de85e0277a44abd1ef864542e911768d2ab3e948e72a24190d55becca0b3475960528494ad8f1990486d1cd627dd9015096b7141650267bb5448be49261cbc0cdb5139db934566e5ec5c4930e9412f2070fc1b4d960435797f21f4c72a44af123bab47134010217ac3a6b754873a1509d76f8412a69eb76e44b958f40cf00ebfd63a81fc72aa8408ecf238425009cd4abe2f71f18b99c4149c5575f758623c843cb965b827f71e0d086ee564ed710a6d7c747d11ca6448415846b8607b2feb8919c635d57d7e8ff5c3fc483fa28eb2b70874ca6e0ce4254c20b3b77893fae5149adfd7da1d04e5eb7ff0434dcefbe2abd245c9b01dbb710e86e69b649e68bd15fd7c9cea94630958b8a275c1d9062b311155406d7fbf1f9ad2060ab91bd9c0e73a3309d2485bc98b18b0516925671dd40102fced9412598b2519cc18580401b68f6ea472302fec5a0b532781a6ef538dfecee2b3834ea9ce02c57f82fa473b50dae41f38bda763d833c60a5e89bf630975c40fc91ffc02faedbd982f3c092c6e48e90b614163fbfd0b5621de436e3468eacd08d40228302f89d9228384bc4e7d0e5b4c4b2e9d6f8625280566a3ac8cb62203ef53efc2ae725aa46e9dc9330e6c0a021b89ece4af9baaa21cda48fa6e67c95e51a8786cbc4f9b7e1fe1bf6f7658d24a41ef2996de5de80c4df7d7aeb58bb1281a491956f4fdf360a713d10665cf36fe20c33262eb965eb6a806b793504f78e11a71d56c76d95cfce2d9e80801f02cbcee3156fc30965d62029867fb34ecc9990b523ad71ba540261261f02bc3f23cf9a7441a6f6ab3622de48bbc3027b04680896828bbdc0d630b78c294e25ebf872cb08fde4a313cdeac0b4155bcfff2b7f7ac98db3fb802e503b7280e24faf198193b3fe4f329c2128adf30a86dd4c0bf3a976af1d9e1119021380abae173ba04282f27819b484d243c6a5b3f90b638501a179672b0527ef810219617d062471e70871af275182414ae2925d41e2e95e4dcd49a5a1be726602e01003b845cce7e361dde2587d56120b33d57f5511bc523bce5d4ba0f99a9671d2b212d19d9ded87a861bbe7dbf765e947bfe6116d03dd459b00be91269f9f5ef1d4998f626456776cc973fe2650f87c4e37d96612eeddc25a68830c7b409d0e922e9b7c179670c60b7925ad59467d5a2e0da1f3a58a17f7b198b659bb93d16386a768438028b380eadc3b4cc6d36c0d7b216747a96d53af8fb0beafe9c1e3ce618d8288069ab4c893e7f8dc96a49de28e75d21c33c9a00afb5a2f96c1e414e621d46b51fc5e2eda325738966f07ea5a77402f575987480653fc0e8894ceca37d0c6f47ff1a69a70bd97716705e44befb7cd1d0c7e64563c3432bfed478d05c532e0469a9ae5ee03a56b656140f33c5c4ae2d79f2a681b7998c2237b9fde7ac0368106d3af4530bac3041b2405a8f21cb16af4264ba44f442260bca4a771633f169bc7c41051b1485a748e58a0ff618903e63fdd4bfa210ce52c7401976bfc02d0ea0c1d934c76993d07a0cd6c02e1cc93f59defed680bd7fc13d644bb474fbabcf2fa83e5eb77c98607298342b53b08a4818322b193591a95f2bb22da1c7bb5719d62ed4929c4d6a74cf7ee21e75ff9c2d10e6142f2698140d0297a7b1456ae60128ba3b497decda8733414ecca7ecf067916a50b648ddbe1092bb19ef4e0861e32eec2434e3645b9d280c2868cbfed38f5764c653af765b767c84f12e37d333dde99ba9ed448dc547757d9977543daaae2a3ff2fa246ab5ab80b6bc27a957a8587f3d176f9f2342794a0acd6c1d9a958b25e99cc870951d8428427c83a90b408e6353482445095311e5427f65b3f135a27b30707a7f1483e38819ee5a94ab3cf8dcc8b7eaee1d8dcba7a75d9625c7341b26c4561aba5a02f4860076bfe11d79803b2c52887d7aa6f556365422786adf9a9629fbb3bc6f3371cc04b21c03aa9779f6f56a8cb00e3160b4f88eeb293e7510df18ee120f65437feb23fc11831fb0da1ecd8632b9d863f8027e07ee4655305046396cc2f610bf5892a8eb55e1805a1af56518fc3bb2c0ada610e2fb1b79ccd5e3c29163c263156ea6a25a56dd34e4ccc7530bc7b53b18f2e100040b8252ac8d3e4afa057bd9a655fbb97d2fa890ae04c676a8c64b20 +expected_result = pass +expected_shared_secret = 08a60196adf66426b4e7b90be90160e196944d012cc34a524e1e73ca125ba407 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +private_key = 52d431d74363ba07b7ec47c2a5b98157f616b8c7b7d3e68ce3f2a31365bf4e21747203c5edd758000a8c09d38a83457fb7b015bdb187e842b46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556a62c8aac92f0ff59651c1abb789970a32c69d153b14a687fc2a56b9e0c382ba4f907a0bef79bddff781776abd042044a1c84c4c80ab9ce9a76bfa6374e9cee06081e3661a09cc3272331936cc85d6b2319cc7873227303191c36842b61013c0a41082b82034a2e1bfc8c47916859eda53033d5427741510e842265ae36d530a19e5d7365127bcab5b506321abe2b69de823b660b4699f8859de76899098159c211cffe51c7198cf1025bf9ee69236c913b16aad84aa4c381a577b6c7a3403627b323f11ebc1f304747f47407db9a8c9e4b866082597f28b6ec272ad2140a43a52188b061650bffae19761ba99ca724b71191b6dc5b16450cac50b247415370d5b207701aaec3a13cb477983f180388050175658ccb4714acb603b6b3aec340dc6c164fcb81331ec194c382fed024e0d962b056627a5b05a00b5511d78badaa489f8bb3f3c5b484f9c1450708b89828ef24b815eb43a6b8b127bfa49acacafc46434987bcaf5f91a926140bd56504fb4525ee1921b63733db2986dc133078caa44518871ba12894a553bd024fb731a0ac44ab80199394a2385bc440515877cb69b73b0c847e40adf238847608908c20bf7e1b86fa84781371d4cb52fcf2cc30306c8d98c679d4cb41eaa0ea8b395c08cac6df2348474a9504592ecd34a93b3262c9751e42193719b617355c59a25679d909a5e756c8db03e3b174e1a063edc733b9350b4f738618648baeaec5b76376d05329be6e706e632bd61292755f361096cc4565573562053b4402c42c85b5299b1cca0b9cfec4605d63665f24561d8c1dcfa896d1c6d8918a3e6f2a8d4224ff97503d1ebcc8d5395f0a64d1454623890bb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6b220a66d96d426b9a1f4c4c4d0349ce2bc790732247ec5d98e43bcd37cd94b652bfca7b988b063bb102ea0772df0aaec74c228261b4fa7a49f3b329f2c7c6d04c859c9816d5ba2aabb85e52dcae066b9af4d9951766041cc783dc672dde42558f50473bb43bc1f93bc6ea7d33f46ac4999cd33698eea603c7da265ad713e48691c8b048b21134c9998da19060cfb6ae31cb5a3b7387f2257fe94bb3ea4c963d01849fb021741395f1862085f031b6b05a7834551a6c8f0ef91397a29e12db6d776b05c7f12c8b260cf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a851be9a82c9a79a25cfa727c632727c765d4c496d466942147a8a7b65aec4ba84e4e2745671bcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ff9a0b663d79bba6b2b8908b32fc145e4f65c6a8a379a99c9e68a10c278130a1969e0cb708d0ca6ff1669d8756d1d530ade051aba3a07903b5d801456315057187758351588bed222785c9fe83a0fb4c59245cc2a72b309767348eedb7c2097b457bbac8aa96a67d785803744e149b3f131a8b1271ed42222f95622d63157b80a5e83d887c54c8f0303749d48a91e2c2f693abdbb23246667b8108b921349a8a945a27172807d72992cd744626662b1c4aec2567972b8452ceb75632bb81dd156eec21aeb92124b417f828a7339b90774520db6e890df621c559bc58b7c66398676806b502313ced89800d9a26e1579b565a66e3132199be13e6fe8001e36630143c96e53736e7672a7b2c0ee6aaf122ba1d49416c299795dfc47f7c5841134b429ecc73a974248642454760da77b8a9d13a297c4399d2479f3e6b0e56462e113300af202e745487ed781c98a8cf26c23abea748eb851ab09beb51097ee06b124225070f83d80d5af5f75695cc89fd42566946948abdaa068032a7c31c35a1b29423b8ad4b7537af1bb187c111d55576f9c382e391a56850231e36ac8f337086b81b0256a5d32880391732285a9092310bbe67701780cd77aa7e2d54ca2e03711988ac2fa27a9890b3720c783000bfd06224980199ad092dd515456f2cdb8c23ba190594e4c9a0de60e2ecb483011c0bcb3612c12be5e04521dc3892ad41cbbd769aa8b79cc9801866c87f7194d89fa56329100f63788904c7511533ecc5b8e7fe45659bbceaba74402605a84f195925a71e3153827a5b417e0b994ac6355071ad98b1328f919d6f8c30ec7ad3366683aa3472132c801e59176711e2b20c251281311a6041ae71f96b9ab225a35e6273b5878ba6e362bb1ac896a557078495d1ed08264984357498d119706b7f4bb42a8700eac4e80164e19c2263a425f4fd18f39c2b3e6d70904e7481a14030b40bebc26be4930a05b4236436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b1261355bf296be8726b04a066138c714b229028b2dc5e5233cec7abe672a0f67572ee2a0b84b6f231a37bdab5006a9ca184cbb82948c46b6882df10a6bc12a8e637d3d437023b99197c207acc2157c43396be138ea06adc0bab4aa2aca95d5989cb6b9f1987a58d52b0b460956452f6c00d08a188030bcaff3e9ce91ab88dea04547baaff1d64bfe3c2f5050a398cccef166a6fd82151738b227c04288e8bbde4c45aa285af2767d17b4a66529a06291757cb52ea67865afa5390a02d0e93226eb200a03fc0e83203e08390af0875f2331b8076259d9378dc77877652747774b85064b878b816cb30c6341c4529fd112b1857d2c2c104a57c52e6c7ed5274873e43303238d19f21447cb45ce568e3ca4863be289e5917e38b4ae2ca117ae7a45b29c345e8a463cda4264877964033025b5a77e8824b928bd2305421b810732a1a2a96225cef965e46369cdf15e0b6129b5aa061cb88688fc0e0da00d71612a56085be7d24f88b4c2e6b7125a58c253c8272b04a0df60485147b85bc566fd34ce78a95a235916729778e4b521ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629e712b8e3ceeba7b32ec4a4b9e115576a6f74495a7210c68af925c7ca5f0818390ec408757170c8090c4ec78fc312a1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7b52e32bc1799b649497b4542970a50ec5a412594d50234cac594efd1b415b777ca759ec6c51197177dd183307313a3ea9b7976879b85703bb81aba1ae3727e962c0ac0ba7f60cf0cd6c8e863a0c6f395b41935ffe6b56d7026a0655d2176be3cd9537c227cf79243e09a5d04783ed170af46ecc670b16a47803ffac59744ac514d84aa544350510706aa408b91e1bbf4387d13e05feea35263446bc7d32648c8131d1b53d8da5ae774634b85bc77742128bb984ce4341d1b05cff711ee33aff31b849c66791fd5259721bccfc8a1836cc95c39540652a305c410e61a980ea5b720c472683811c7c596b635072fe7589c1700d72bc2a84106a296636107454a7a47c66a1234a3a3abd91cc7b049738b6ab7d70f450c64daaacf2cf9148c1806e2308f9c883875ab36fa20593559cef890006eaac701db9d80a762c448ad14c4b8dcd22c2a4b26ff23912e30c1c4f0467762b39689bb9ecca9ae56bc20c1347c6b4657d780d0a6c0abe904c9fb8b7769c550a11dbf54be2f2b4fe895b74002ce859228eedb676fdc15fc52c5a0679399205cb0b964e8e3576dab64f21741009082b04a9a4881c91be1ce9a68291087619b8922524222b1385454f59d355231f75071cde1cc1f96b45425932406380fa54653f521c5a178eae6aadab4bddba968fa037a94688643961fbceb633cf95c253668187784b09a7270993f6f12c96ef91cec254ccda64bb71582f20227dac5bdfcd535de1324520731747cb81cb96f13633da59318119150a002a2417ab8963b51f4fcb4c3b34ca9964fd5d94e57b23acbbacfc1267641da2083e55f5ca34695c7a45a283b15365ab9dab4118cb230ea06eb4a2fbf952f1342710ed07a2cf16e3145490a2a3a9ff308e0555e0015029e65aae08024b2637da6b0bee9797536004f9c54a782fab6ee67a8847143529c8564c37845f2c281664366205f51e8b577b19daa25162f291e21cc498a5599a48c439457a2c98cafe7e600718b282c45c58f04306aeb59e5d6ad6f3a3140903c6b8636eb2800c554c4753a3c981914d4c6c6914b56fdc26132fb281e944f27b4abb3eb937cc49707e89eeda1694dec921b6a6d9c238681dc2f844096af3bb25d61bb81d557478904b87511b5c2acc402a9164807909376b800b8ac970648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7ef07b1f4886b895a3246241ddc084379eeb0f0ed84bdcd318fe72c9b546413be9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = 5aeac6657f61806a19b78e1501024ef9a194d5fecdf8a988f44c34a3c1f15d6801fc28fc2dd6776fa41ef415eadfbf8e5e870dc878234c74c09d62bb147c513b37a5767f3a976b4326510c958f532b22b9a7cc76f6c27638dbb47852692b64c8a87c2e74cf4d34b96e3feb0bdd497d1a371f8e4e94b72b6fec30769c07755cbe6ab243ea2b214880893e4b0d22cddf124d171f80b612520f314a225b9916f19bac96bdb88736c868e27590603be0873a1fb84a3f92ab8952206fef3221d795f5e905f61cdbc7edb33e06238cfcac6b1815b0637cfd16be6918474f2f63f47d908afbed7876f3d4bba22385098cdd729a568b2fabd51ae77cfada8849220513467f5dd720071ae404bce9324f3874e0b96d0ec919a4d0bdf51d71eb2cddc8a821f4c61d08cdb8fbd1a59775d1bee663fb8e702799192366a1b3c214f49207b49634731890e8d05712fc94cd63cfaa04f4e8580c5df6724d7e01d48675340b614115f94ef42336c84c08b13530cfb115093e16ca9474b2fe57a36345aa171217cb7cd811909f85abab99291ef90b31a697ddcbef02d6c1ca1c7bbf68bd1770c15b13b973a60b0a5db4ac5ea51abbf8dcd916abfa4426db43b0d45e763cd4f1430cdb7837b0a8856f8049324ae97f3bd1a7b6779c36e7c633a6bf99fe5ab377d0d4a30b0446978319e9407b265253200c98521750abf27324cf621a98ed9499e97b16418417c4570907e06404d117e89dbd3656d5cf8becd4effd19161f137fc45ff2adf02baf4ccd47cec32dc2092b0ee8c9dbb0cfe76f5e1e44bee72d644a3bc9112ba8c8faae23fe16a64d35e5edd741ccedc75975c8df8e370a3178541b3214999c15d5f2a4848585d31dec9d19e404e7810f2cc0172763b6c746fc7d75d6f1eb0d480d16ef597c1e9df50364591c09935a5274bdb7b5d0386f6cc6da6f50f2aa562ccb6368cfaf92c8ce1330b7f6e9a6d343bead20e5f9d9abeac428a63200c42127f163a30d1ebafff7ff582bd81e21355f95f9256687abe3fcd2fbb09fde72d079a955c9bfd09e31ab7827d2991834df205c3d696db33fd766e8ecba56a1c61d49295df83d4e2520313ef9330f07a3ceb51f3a2d06b36aca88bc2b6511d2730160f0a15528568507e367581936851db00ab92715b42f04df99884800adfe2692bf40c1aa82ff825d4a17675b7ef736cb705bb11524a0cef22b26029abd3fe0325940230a310a6bdb9ed6c6d2ca9910a2742cc7fc7538573d1f5737def3bb60608a44a1d57c1d5893ec14deed990a89215b721d0a6bef09ae51053cde3989e249bcc4490493ce55c1b623daa5deecce769fc3b1821b34d870bfd87869d55dd9c63db65d52c6ae6351a1f4b4c8b36e5e7d97fc6643b8011985d8ecb62c42d459d55186cc76785de1301e41c71f4c78add1cc9ff9bf578563fbb42c1c5b1385c32bd5c2fcb2605a9da5a403140370fb9b9d0673c3cfe22cff7dde0d203ab79ae5f01df3718940dc1a3744d14ef6434cf78aed1188fa8db485504a12a15ec609375188b7e95bd70294f91facb04a806ff935a2a51835c0e4f702ff92e01a0419088e01a321cfbee5c8352373b2ed195a3e89bd600d99d2d91c5377d938c014b98e11a8f3455f851c4dfce5b92eab76065fcee3aa10efb57b8fed365795b436ab8b38037c75551fd5b8924eac14d401d3158d0a24474ebba1c8bb84dd6a8c3618765a93e559142128fd549cc5af8f1e6b63798efbf9ebfdbc740ff683fba2f398abea3375b58f37987da855e5baa68d6596dea4901eba5bdc8eeb7e5aa28b8a8de187350ee35674b674023d493da86d1b6799cf662033f93499bf00ed13072bd7a67f4f7dbef7204ce31e6246e29abd790ae1d4d211e72f636ceca98a502aed3463c47f6d6f69e4347c9d6838f4cace94a318a0ec87c118086b79d2893614c3e5daffe2984d19dc25ef69e4c3b49e346c43147e040ec6aeab8a1121716e081887ce86ab39f543e69d662c83f967549abf6c222842d006c53b3854f808481852d34c25e2a73c6f988f6bbf75bba6f4fa099822deaa1cd933c005cc324685bf5e214298f09c2f6f74c80f628e4aef97622174065852e5b2134f4d3614cb78498c2aad54ea8ea563cef0cd786e30f94f86c404b5f8042797a67e5111f7050266129806f5bcf73b8aef3f29e26bea6ea9260d0efde9c35fccc9f761d8809a9de1d1eb +expected_result = pass +expected_shared_secret = 13f3b79bb1e5d20ed95c7165a610e122b5de6cb02444cc66e0f1f9ec44c27485 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +private_key = 28ba2f24db8e2a5b21092964f1871e97e10f2727c8b27916a5068edd27670d26b91a93332157ac686205e23616eb0271b081b51923c5996743cc114f3ad310cd6791aeb05f77960991513ec655533921a8d14cb2589399ebf18f7ba89bb7d6cd2d7336ece1b7b63b98f26a49d356578ce7275ee67677d1482e1bb3d85b88325bae0a00cfd1288c34078d73965442b7b140705f0fb76ee3d0921112c400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313e82d51836a2dc1b0f37a2e00545f802b417a9406e55420b4d71fbc2210d05a771cdc164ad50932ea40a876051828236153b4e1715edb1453045721e89a60acd0066227704b8ab991e8a06812226bc59943c0814c847a1865c19df4b7fa13ba3ef95543e724ef854ccb28bc1db49b75c1aca3649f848bc6f32c139aa79197543c628238adb755f4da6bd67130772b4790b28c9f1544a4e9860e875e68c1cdd9cc0cf17451434c7c53f3a9be39849720b1b80a836ba4c531d49bad16077e90203c9120c23239cea972454b08a5f10812443ca75b913df98dbe29c3312157e156311f67354d414aa041833f8454aca5b3898b3572e819fb2c4cada43c9c5191d6f7aed8f310cf77ccaf0c478686952e71a8a8173d0c223b04462b96c04ea7b218a13519b90cbe3be8c32b276f90d349acbb6362706dcd54aad0497a058ab0138a8e57d514d5d431043184bd1a07b77c3299ba6c7205938eca8403f31a1c605a942b73775a1ac11c40d81988e69c15079719aa769b5f618052d5290d84714ca57418366c15b74da4e98df96abdd19884ec1703f7978c4dd72b48528789d7148f16c23ef8bcd1f353cc4a76e7c238aeb1035424300f529acd46926874190556133021a6a9283ddfe02edadb7de23a4d141b0787539b68110b4882a51f95403865becea06e2d7a1c1f534fa3366bc1ab387eb867477b92f00c0d09615bfcc1138137cede4098ad57894ff74982d71ba2eca6a0f502cdc9c89bc6a44bd84fd8b62bb5d84332faa830e2a732259945028d2830a8aa866f92c24e46d164c4f4658791c11f0703d906a82546c75f81285c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce770f04f758e6124543e13d2365a915802f75e90997b10b15e650aee33a291c87030517b6c29cf10670d2dc5c8889aab7518b4dc86d86e25c52acc4db175a5957118f983c3a4443b33803a3161ab24004b7a789778c8414a8aa8c819468ebc28b68afe5333f7e666d44b5a961533280b0021bd3b24e2aa51ba58f2f45767a5722e918b1204656a2b44ce628a3a84125f918999a6311cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87b709353a77743949277147928273f112b5e618167a5715157b49ced69a2492203a08730ed07b7aa14bad136cfa969dfa68c28af40b9763872ed1b05d4161489bce1f473d4cc067a86258f6b664d2436d4856166cc60467887f9b97439f607d336114e46b2a2964c228a18eb532cc4c6813dfb841e60c3baa59978234a06fc95aaaeabec0123230ac33bdc48a4452403842bd6158c668f28f20bb5501984c5d3992594a9238e03798d178702b86973350dc21617aab9b4466903d4914d37a2ec3d936c162933505b7f45c3a26fcb3b32bc3da91aad5d7a8af045252202312d98a7877935cd6b8c9499ce722c6566bc21fd427f1902e6bd190c8889824b35b79268e4b2c4afda48b0c98856a097bff3c4523bc02739349aac7b8cd286798cb919bb550575b44ba40226cb323f83886e1e164efb1ab648a1a738747e799327f58630134beb48a187fa5694279bf644997448b57f909292807c441b8061f8a4c1d1bbf8c55836eab38fa483b66a652c556191e9c959c45a4175244b851b294e38134284f771b81cc72bee2bc188d58053c7589394b49b5b33cbe12993549c2ac05be0dda9b63d97e45e738eb2738c59224db502a0fe3aa37d113cd3393419c850b77b4b1393884dc9ef3d189ef3499372c8851f290f928a9c05a0a210926cc1b5728115771e55fa14c23ac4b1e9f507b02164f2234050f06896ba969347b3048d42892600e7dba3b8da0cff0d1707c0185f9b16fca3921c2b648e130bffae62f0fea48ae91588a15c064a9cfb0bc862dc9ca88b1b22e1b2cb01b18957737b65a63dbacc6828418150978215b85703586c1060740d56b50b40f806a7d2b83890d2996cdda967654506e096a9e59b69378152f4b8b2c1050a9e2bc9e20b513813db6f6b42701ba8ba3a03e80362c7904f240a49625435c00d040648262b44d881882de55cb3bc1968f5b3fe78bbec040a50972237800c378eb9ca8735f5502ac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c88509dc25276fac066199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8d514be837e0de28079e22b3f6c9991504c73bc2603161f8836a8814095ac527e0969c00dea613de63b05033b303c5937815b02ebc3466b5bf287265852665afa4d3dc7622650a0ca7438d896404e5b2a09220315bbbd5be37ae3a61953473e2be9b39cd71c072a97db3aa7546a9ebfc651500633a30919fe41a435cb5dd9b247192b233b676d2432132bd4cce04c30af99344e20aeb8e9b6545b4e9c9bb211e5add2071911dcbfdec072cfb76fd6366a74aa66c1831e1b6ac6def02d703bc9a9011480032e0b1a8e668cc3bbb46510b993958a455b25c025f19677f1c03828335b85868dc99c81d3b75d0042c3735cfc063b68630c00680dcbf561fe07ba4202b1045a2eaca9033ddbc2f3e620cff6158c904666927d61d4702c84aab51c60a748acb573704a5b422057ac3933233dcc6c6609cef96993ca951f89e10b68217d4a59839f261fac87375a38314f4b7ccaf5321a305ff7137e4207a9db03ac08370dd903a634b8951fd6c93bec205434ae6fc066eb18a4a1102297abb8cba62980340b2d643be20c067db031aa886282b03dff2870ffc455cf78a1657aa19e958df64b21cd9467a1306ad40195db3a9398c86c5e4111cc40816a860909ea742f8b14cb2309860b5d300253fe6149b236aa8ff44dc8d79b852888a9b2988644af45c030f5a69e93a44bdb454d79c36f2a1b13db7b395cd7b7da192dac99b4d5560fcbd96312483511bc8d9e738bbd4cb5e708cc0a02056a292180d06d0b0983a2748dbabaa88ad144aa1028edda8dea7704908440dd9a272feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abda504aefb2389322af5df12cfd399cd19b52cd8850510c37e6c087ac060e468c97fa97857e78712c17696ffbcda6f13248733cc03c4f08b92000590d79d74f1ad2336b9368572230ee472cc3d28a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c444929376021b7fa06f5acc940f2984b118164ab204ef2ba59de476e0ba22169888e64717e8635e7a30be99441814b5141a658bbe25641d3557f07b33d3027ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b162ae5fb9693607bc2fb279ba5b3bd19408ac8ca13e8c80f2139bf410e3065a0be22800c0305966832899753d342694ce56483a45f0d56848484cd1b9c949c192658e14e7c6abbaa51cb45441af9e46bac064376509d533718678a614c1b9e99796c0d4c8ac6ab134c4aa79a1c22692183c9f2af94836a52930680c974355104a05c0cd3a5c34d6a7b524b1dffe1459754066ab41a0b7315f302955ba23fd2b4588bb58048e981b0cb1df247874699021368277127912848cd65229c59617a7783542b289456337dd572c8e703ab1f22af68c962c9387e92d754027619b7f9accf233a10ac294ee15c3928934ee0b342f39f3ac5299ca681f5c569a2d87429bc7b4c492a9a09a48e17534e7a74023c0601e92bb13ab2f6918a44066e58433c2cd811ec5a144867c666b390841712d0659528fc76fc2ca17d3656b4b0673f682bd37980897b02d3608ecbb27b76ac848d55658f2606fb761154b0c516d0787909a59b35bb73e43988ca7459c22da04cb91c784f47e39152293679b41d13ea4908836735c3a28768509b2c6dc3d220c3db729437bea79727ae8156e2798ab7e9abef81437de27e752188dd22913e477230549f564a353fe17d513a72adf132eb0b0f3905cace01b05a073498c56221a4b9941a0223d4abadc87f83b6aa153920ae58cedb7aa5d4ebb6f4b34570079d6d1354afd1c30efb1aea9c25eeb07cb56417c134cd45441ed49182651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa1a2d9ea0d2280249d9d756975c6979a8770bf4b5f6addbd76d045a816bc1be385fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = f5ed4fc705e7731ad1463d9b3c1c634c6bf644df4f86f08d4aaf6a499f4643dae0acb11d08eb4f160489ade20211e0d1a32aaeada615cb99d309fa94a71f007172b3dd870c5682b88b81839063913eadf10ebd5f57206e6c2cd99a1d84607f54b2ba7f5d3db7ab8f63c97318819b078881b2926bd446bf7fa02728704250d34dc5471f72b5a9078faafc68d230f966134d683f3cb951130898c994851865aee64dff49a6844d28032ece637eb184c80c51385968f137acd1ad6bb68ebe96ff5d24886dd21f16294ec5bf3f9cb61a2d6fde85a2ee354890cce77fbbcc06df6e8341567e6548aefb2b111e66308ba49ae0a8152201e1543982449a22adc6867569fd2c562ab5ec6864b606910e373eadd2b5a19b01fdeb7f707c0a9626cc410b8f8a0062aa15ed499db23684dc1fdeb0d2ede15adaefa91487e54a92248761b09b689af2b2e3a9713533bfade1cbefad1a499e0e6246586f235dfec390e5001b4ee8d3916bd8384d3045fbdecee43378d3d4146f0583cca1302179ed3addce22955e8719e817c67a95b790b744864c8a6508fc24b262540112ca7b1a84f17ae26c61ea395e04346a0d32e21d35a5a2ba3e71ce4de4eee6391de568deda7364c5dd27ba6fd497e1555d469d6f87d3cf656cc6c16dedcb44a6aa4e7070ba0dc1045fbbdd8f45d3d2cfc8b3b73689c971260ea54a537754a08a7a2eb55bcbf7a02c7371e6e2a7d5ffa27088256a52b89d9c172b1601ecb98106f67e661adbde97e78f47129ee326aa8b25423c7cb4a57c60bbaebf204a3c520db9b9b5cd751b2f9c8a44d4151fdc5a0ee211c1c4a6cb5ba9331758276d87d57ea19829fbb67380794f6be412c4e3acd696dc305346f2ac01e1b6c42eb3f58dfde482162d8e5cd8fba4da08612b8f4ce2c870750f4205872bc46127d4dd564aab830844887c52c8bab93b54d31e2994582635172837bf1000bcbfc394879f9a00dca4134ae99677a81cb0801c9daba7c7a59e625086f6636e66624b4eed2d3bf32ae568f17cba3f3bd2b4b11796cfb71f7e562f9a02bb53bf7c1460f9cd9a72dae6c72bdde5edadcb231b876b233bf77920bb1b2835fb9449bedd6ee791c985136a2918329b92253b4307444f1aa7afe4a89d5f932330147b678d4092f26b9f094c1abccf00ce618a63afac2a02cb73fbac415aa961860031ce4eecf9e53f8a4daa8ca65af9955eef5c1a9168eb28c19ba1cf14aae597dcdf9476747a15cebec9e239f7c4b54a4b8e11885cf625818b827cd83bc054c2f54aacc33efbd2ae54d04514813954211879f9b20bc5438b7bbe951d30c7a0cbf52d5ce43dd6a485b97699121e64d4c7e7a378ecf72837150e8aecc67831130d05d052a06ecf065f3e24391d751e7623ceedc3f661e9798dbc252f2dca40057bea43807fe57afed578298771133d75e50562b947f1bd5f2c40445770688cd930ebdf9878b2f5924e0cf6cca6083b29bdd05ac25555244867db9bebd1c7b65af1e66d4a4d8b325203867214fded74a430415b1112efa11bf57b4a8d03dabd88d7a472a0677eed4956dfd6620267f2651d5209e07da56f538c64786267e701fbe1e57ac2f0985678fffc6a5e7b0272b27b457b25b93566e3ed346ceb3f8fdf005c3d33e0417b70d5d77250899a7e69a40afc8e332c3b315805c3fac44167d28ca64cb3f6df6c389818ad9a481492f271e14535d6085492ba4797c4cba39909fe1c501b56e5ad29a44c6c6ecbaf0b6383f4ad160ef563ca6a3fe6b22e880545ab934f416cd6659596b8283ee4c2a9406d012670f5a66ad44f5cc577c5c0ea98d70920926bca9c9b43eb908d0e25b96553836442d9fb789d977c677c6cd166f891ca95938f45732dbfa6d7296372f7a06ce5ad83bdf50ee6a9eacb3cf3d861ad34785ff5a0612dec617ebb27aa496ff379dc20f9bc5d6a59d38a5c922fafad0d9d3a7f6801a160c4123ef8716723f5fb9b8498fa1193a24d5107b0c5f13b2c527718aa413da53d9bac0b70c483835921bea069c5e1d9854e2db40c2427d21cc0f84a4dfa0c94db628c37012f23f637f2ef5e2fc0c11357891bd4574d42d9558b7515baa4667d32b497e3b9b5a20234c91f895ca8c2e71081fa6cb834aab7770fe35501c52395eb984a2a2d0ab8a608354812e425d93b6b92134eb877bfaf2b671be892a485ae94d67e9cad8a615dcb679efa56d902 +expected_result = pass +expected_shared_secret = fcf4227a487e719499f86e44ff74a5339870e4238c20731e0c85f00229f2a1b4 + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +private_key = 2f766ad78a0112b8cd4bf28dd0f589873553bf114f19c2719f61a32cbc85c71975b911237bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab4729d02abc5dc07309032c7112540522575d663c89714aa7a456410144d7c2bc1041c03d5a56e08cc7e5663c01f52e5077288bb8cbfba21b4a8a19c055691e05c22f94c62c3cc2b6a9c155e2a4eb2bb9d95b8c9d5a6394d05af87b038c210d9faa266cf07088b3cc7ab56ff3366fbd595b3c790b5497b34b94a72d8153fa13b40be96b51315ca4d22be3828c3556843545c47b0254266a802a44bee6e5a19a446472322c6aaa4cf47218ee3c99247564c552c93ed589ea8bb2c637bcf7277d5b5058dd80342815b2e8864b4c330920a82ec76b4a7bb893e0d18278f47f84743223a67f2983ac8c4a1845a61259670b02d6053ca181ba4c1bcca05b7af2a27c59c1e4e38da723b787aa2f36c71e3be05039183bffea6ab3bc779de2273326b327d42517b6c6ed8c7f96c6330d4c39e3d2a7b81a538693329abbbb5947b068c3cf7b45c173c1ba9964c86ed91d0bf64e209c1910c218434311a50a2128d52754148159891e00475654ab30b9693ad507b2e19acb7fe6b14f27c09c6b2570b861926683a285014631c2d7cb8c0c10a25d073d3c067ab819b9dc27971825ae21cc2e50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d90795719b237238c1f831007c690186949c600c6f587ac0d81c8334c57fe0c59db3e2815d63c26c620fdd75836261644d99327a334ea5a40571f0cda39ca716d2bb894a50bc4cc84d6621b60509dac77ecaa39b9779a3696749ce83933eb70c1e85bb2dc3421ae9a0ef40ac2d83a1fac16c6dccb0aa16aff9a94bb6d125665c3001b845e7f20e7c90a3db636950b0836ba008da33500fe47fd4a81df0e268c62974bad02a6d3b2267f917e2046df3c1883187683f030a28a129902083ce26730438b0dc0042998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913dc261b6274464b656bcb645f87b0cf4512af443959e67c47d679020c2905d45e21da586ee8291085a8a432ac6afaac594081ec298dc13175779b8635fc8eae58982258759999a57b704a5b040245d282a9b6c9cbca838399523f26695f60389ad42f6512783ae65a0c25b7258674398839af28866671329109a58e579c026549f0b7041dbb6623665fbc9a2ede41c0436635325912366ab1364b5a3162c4b8c2a14480aa6bf165588b8d26ea968291cabf66a4e26722f87977dab7807a2c65a26a9cbd339bac0b24e6b46e0a8082be95bb7a41b1b8b670ed3105eaf994a06a6414e9abe2a1b608c29c94b846012a0fcbd6959ed411d8d0c70a32559c68c74d94b2a9707b9d9755e3c69ac40782e97a1f904a32da824c7459b59b174a9fbb6b41947f47b3361d5558d831b2b444818ffa4c17f4bfcf8b9c7ce451f4ca99884c13f85c24d3cc4740d2567a54ab0583a175759fd7e197f3000a39717bfd9c768248518d50791cd84dba795e85388dca21507bc669ff0b906bf515f38c04dc838d0d1357377b1601887ae1b0a0c4490d38a871910c695c50008e5a5a0f4cbaf8497a56f6707f970b77962e13a5c09d8a6eea50840413ba51e22af3666098f23c12a9a6ff6785975ba75c6823e5980b78cb3e5d20b7efb9307468bf3b06cbdab62f0c4ca7157bb22e9595a4288e16416aac3748099229d397a1f716aef05676c2a035629c6878865940f17fa0d2ae5315c4340c7191b415046994b9188d4e22c50239901408b64c1132f854a13de43884b8cbb430b277341e74318669d2411d49ae3d660f84e35538c7668bb8c7edf39a3fb33bf7e45336fc68ab37477c037f7d4a460f3c211847468bc10e0ab67576605216f058153c4f5e041900265ba367afbb21bb13600c4aa74fc55222be11c88298b35789532f357157f48931c2a58cd6a75e82bf411a0311fbc2b84a67d7353cd13ab939a05d55157a19d226dea6191d30b28aa916624872bd067b2d7597d73419fc5cbe3a46c36d0047c231bb4c12609425c1f672b69f57aad8f091222c109fa66512046822b4c7c57ac9f2c9c701d7167697bed93c789a626af045a8d5a2c2d51383e41211bb38b76c9684b3f044ae2026d8b17f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749a52c8bfa2327db1a0258829bf7bbe4f59b1a6d8b8d3954db41bb4a20b0d660c21d6202759601630854ee75cc29454ab1a3469bffa989076301132aadec892978b3e15082bf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b507f31bc1495ce2d5943466996a0691d80405cc21b060568f55a18fec917106d7277793089e147d759988569820e0254ee7896e9797612c655e71371178a14b37b3a2c2b18bdb952a5295bdd4385c190b3d61136f128ba74c2c57612708f900c144093ae460c86c7a2f0b1903fd9a889dd7874f6543a2e112219869819c35c055813a394333ac6c9c860ad7505f8aa241046a984403b798e3211469cd1d8a57455702b2816f0b2b3ec60b273b102559099528d306ff23be250b50226b497b60b7540813f5b0c4a11732a6b9583a21b3dd2028e79a82ea0144ef34c32e4392a11241748351046b9454a50e9f90739d12a96a928e75806f24004b4a926f0e8769f90a921c4323d7fb7cc74c2e33248c30b774b795cea60c47ec52a01ae84247e53243542ebd8abc24a183e2d72247628269e108a5e93f11a45ca9561e8fabbf85aa61c6bacc2493aa93a38bb72421e8913fcc635ea0f2ae17ba41e43c5af3c83382f0667b6113591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc7c224dfe3bef7e0afdebb5f91b2532bb867ab3c08cfdb6a64ba1876285bf6463b9a241512919c9b72669ed252faa0aeefbb963076592f9884b5e60e42c2008efc08bcd1cc2bf31025c386cdf99b49283d6d7b0a24693618d2a2fac3b7acc60ec970b6d357b199fb6af3039eb6601bd57506cf8292d3181eff61cd380c525086962b58bfe53c3c0844431347a2f2112776818fa3ec2937b4b3b21c52be816637c38a68aa5373858e16c18134093311292814101cc2940b7f61953cf5971fb5ccae59ada4373dbf9c149869a0833bcb97d9bc68d6581cfb803264599a9cb1cab10a15178f6cb23ddce70d060b0ecc7a0feefa35b6db9800567417775e1df95ebd32a4e67616381b48595933f301408e2cc1951a095994428ea01883b4a8a8d780cf960d69a18425258eaf63ab2f2752aa411856b78dfd60c2da74c35f517718c3b117a98e968a72c3150105ca44fb02b14c439abb81adf5a94e2e5b7a8971848c4a9156e1445f41cbbe2c7c18785baaaac24bb87936ebcc8ef6ca4a951d1de8c2e6c5658034c1fde4b75dd1a176824298a669b0c4355aac3e201380c42cca5060192d06606e8430e135c50997579cd756da40336541a781e6702c0041c696270b65a92d531e964a1e953555628929f7fb59a7c2a5cfbb90b4f04b129cc011f7aba0942247908b22267df9333e8c762143c4b68909694de674ca14c7538604a7741fbd9004d861a04f63b74106729c6759718125cbdc40ffcc60c4aa30c7da001e30c889276d48b1329ac033d5365d76c85893da0e15590bcc064f0803cad5e80355fa56974ac577db713862545aa43747f9456b822e74e56e3a825e0f6259a3551565215dcaf4c9ce568c25d9c9c7471806210969146bb64c7af9a03ec276ab4ab10e8dc227ab491473f09718c4a046e84889d7c40f0bd0878675deea6c8e071b0e819f77147631939c035a8f9a4644b3dc35c3dc328c1c0cc6cc537af884d7c6000dba9e1e3062c2d43a30eba1873409422a5f664174d2f536e8420634558f4d427d3b8b48b96845b0f1847208c374f31d419988e9434a9f626da5258c00654b6789122de71788d6b259a29eabf83a42621b1bcc1924a79d3fb59ae6475ae6714296ba1528f30a66c2597ed308a3973a501cae96e1779813195805b12b0b008090acafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b1829428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3db0273551877522faef812d452b6444c4ecf3b9a9670810354b5bd57ba43aa5c4f271a03b2800f5290650a08ae83061f331489265b2f2a3ab1f4b3159103773b7806157e26ec1892e2c3d121a601777834b52939a658531646e713222943a0decb5b82baa4bac41f1cb2aeb3076a1a20a382698ce3919ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5a57b333a2f41fda2ea72ea11d8bd642d911f6afe90e60492ebeefdc17a93219211eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = d2ab81360e842785725a281e35958b2dc839bd1ddc19656a44364e7f2f094965f0d9516f525af183cda454a7eab8920adbdb00c96c5e4e8245e6de3630f0a2bf64bed8a1cfccd7455b29228a390ab8b9bda1b3a8bb5251f87d9fb461a197e06944979f4aa1008fa95f56b27d0caf87e7f77ad94fca71e26841383d391a168c300333b472263e90ae0110eac83e2b70ca139064d50264270ebb8c7daa18bfa3ce3e2f0d2b96777f04fced16c69602189da5250782a5f48f6a76c3bab6273addb195a10005d5d190f2204d20272c1fbb372224976b6e538c26acc90cb2905a528b7213ca54cb66cfe431dfb88000b42733488d89cb698beb53f262a1abe632a1d66b62e223bd7ec342ae362ea3b4cc322c152d90042c843d966997d18582cc2f828808b3015079bbf88e0ecfc1dc8a2a3f227573b31a78725cbc6a791669200ddde4e4c9c48752283bba0f1e243561e71f7ffa06fa837f3c70d78ba19d58c7c43816a89436acc77eea80390215ccc60312dea12f3d16280a33dbef2bc464341ff884dd332d00a2cecd1740d0a2847ac705766544eb7fe2e1b08bace10c083fa76e3543573af1a45230fa6c12b80e1b84f8340b16261a54e5dd612e825280cad56df2e9ee1a387c0b8bf846db737dd16ee5f929e5b5b2166e33c7a5b18732b7fa4985d1b772f69968202134d0c95d95be357a507625e97bf27a06d2301df39987f6641d32709fd228976f53624abcefee139128a173d7c2700cb912792f13ce697352b5bbf7dce8b1609bbe07ba32640ad08d8594a9cc82ad39e1fe414ffadbe5abee04e2a451e068ce4abf4dab9912377a31f222a420a56a50bac6098dc5aac5dcaed90fe65c894c95ee3e49955258af83493028ed855369dd119bb55cdb6c446f1026c9dd09186e35e813d57c671fd421cadb74c66d8dfb9f3c7b32de3af2dd5416487908dc13dcd39fee455e3a05235e3fc03a3a4076f5353fa4859908f8f0a63c6016b3f10a739175ad03cc4efba63a58381007fe1cfc6b7cc824e7befffd3a1566cd1c90325c73734c12cc308757304387db88d42fd0ae6b9933a9f3a8a4e95e74627995fbc77285cbaf944a2f5a5afd5cd722c7e5f462a0508de04dba5f728b87f28549fed395f892b250877099925bfe4b36129c74c8c6b81186549e1906c7fe9c2218dfb7c0932e31cad35e7ca2f7c0edb2fa97aa344d515c9d87d4a9cc6cf3ccd9aadcc8f9febb5cea1e263ab7e0228c974b6f726e6d4168ad170d167b893a1ea0b9f1090bc14bc6529a809b66c4726f6d50767831b3ef5f46f069530e12136406051833f729f0c7ad573e58897f7a24e1ff52e47ce2ce7f4467f6dcb98fff612d118665d99c54c92dc6a923631b5d919e44732a0b4662f2f09435098051d4e1dca6dd4e5032b58be812c736884ac2940425766465814c70ac36fa116aa4f1e9a5f8ea491688f39fe9a2acde2760018dc91f385cf181b3002172140fe7ff2bdf57ae92f0db586c9752145d2ed5af52604bbe4b62d12f17cae51a8db3cab56a1214b89fe1d55295e61ba2104c3208f11eec0c0b563e45dfa0bd029d92da71b923ed607c16392dc2c28f3e0dc58e2e54270ff0a11cfd106307839b992e6fd77dbe7b0527984c907fb670ba8f24eade12010f22941d6da98857549e6c17affd9d8c19b766060508811c65705a06208c8af5397f679931392975124653053ba92a66efe27be764acaefdae358b2228f9b56ae2e399aa3f808fb5d0de5edd3b9e7133c2468f732a59f7064d7ae615f1468051943eca7284a3bff8efb5812e6e1bd4ac2271a089b79fd5c613401eda4baea70a390feaffe0183985e108c1aa8e4f177faa9df5c941de63244a84282ff8dd7ad47611889ecb2d85f2ac009f4c11b7d56420827e008b502a3c138274050c37c27d3539d751159df30dc979d8aa4f52422d9960ea0013e4e53f474f05f360f9dfd9d689017bbb935536d72bd0bb4766649909ae713f5b47acacf3b688785c3abd48f334985a42bcdafdeea8809cbdc2c5223c7474645e015b956c60e0c61482d5c13550794ba19bdfaae821f75747e71672e596610ff807255e93086d68f90746fddc239d4a03da2f69f2dc484fdc5b0ab3e2da27f64ed0f137af649fa013ef667366a61b2378f5d8112dc289b31ef7c995cf137652156c9b2d42c2fe7ddb3a24f6b6395442876754cdf32bba6561 +expected_result = pass +expected_shared_secret = 3f8cf35d0ba76d75dec611e5fb059db5197862b7e5cc6b116a730734932441f3 + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e24073df336efa5a0d6fc17b6bb2c615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7e312f81066d516be72680e5a665830f74e371bc411ba86f00704dcd3c40c8c1295d6b52aca51ad41732032535af95bef907127eab1eeb54899a36961793ec47b91d9725643664082c4375f4843b0031b815c8dffcb7f25d4414191746d5aad14093bf2c005df655f69917baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd9f81d730157a59b971e4b4a0fba8ef49754a7c2be0325c8bc623fd2a94a6cc4226677260ffcb64d75167d63334e395df5ba4505495cbc8c3a3e40ab68796d6c646775339c29683a21f921a7c6a79d39a95c876f782a27a6365908381d793b537d1a681cab5599817e050cccf7803bf9a90ccc4084743c96069183b08702979c9dca2b9d9bc26e1de849976aa1465b29eb260ffc64478c39945a9b402520172cd7861c5a0cc089a028c8200208b3e4d7b3a91cc8c209c5e1d201278b01cab34126c701bfc2913df501f6d73d9424cf1176b8616c04c10940ef9832957585ec350e9761505162aecb28884f659ea23125c382cf24f383f9b09feee8aacb981df21a6bcec26e2a67493b919fea06170c18b79e5a01e6e89516707bcc7ca353727825514aa0d52504606013e53ba916bd133814c36b98fff15f847b7383854f692450aad28231f2bb4fd839d2b532066114da65be8cc5073f9992e03836ca3a623c301999a56fb00332d1ba8a26d599d0f5a97975814be81fc9dbc536d1c165a131ca3c55d04a05d7a53fff1299d3860cafd8bc6e3b97e72a595d294303a12994510f74887fd1d7bb18da70bfc5bdd58c1f6c1cb56f5994b7f2225ce0ab29e8cf3dc851f1aa5bf2ba255f7215cc71c5da95115d6a98a2317224bc6de1b2c79353bc5c3c046a7a0933a73419f7b117b88f3a53777143546cd29014e15e37c33770a8a9a11bc2f38777e400132a812a984908b3d2b87fc465b564045e79453c0666e3682a894c269551afe25286fcdb681cb50b260b4327b46c2d0699beca103965b0a218902eb4680c1b8c3ecb2011a396b0dca97d56aad231168fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6dff91091e8b36fd2a2c6b1094a8338ad540c8f53cab80d73e7dec3977452915b616d0f0bf9e842663cc477cdb5dc94579d6222d1b647ef4d358c5435d3d0799242b66818a683e8c5651b0b26ce4909f8656ff35cd7ffa1c5988074ffa32df093bcda32aee2003825593b545b44190787c4c8656d85cac293f615811ccb35eb0413f44b1722e0a182f09481712ac68e3c9d31085ea77946a54baa91c8ab8e814c5b94206070c0a6037bc02a292082018933a5ac32141180a6dc760c2c9aceb3b1a1505464150a732664aa51b02a721b63759379a638bbfd07ff9a7a84e071fda70200c61894a8891dacc375c120a35e0a4f296a02845477bc0484fb5bc539c3b8bea3ed2511d480b1dbe76c640622b67a1a8e000b954057322cc005f88284d6290a5d720e32b5f6cb6b992bc182d66a73b5019572867640343f267133b060545d4b2668b05e9d1ab7b1aa5c3287d9b08a79c9a5c9b6c93c5165c0e6b8c40d527ddfc01b3b88354c73f2544b5506c1e043100b4c399d2b6b8de81cc6271495b3c00893b744584ae83e300baa0531d191bf77015f28b2d95911cbb2a1c16265db900761c5333ae8074f387a97258cc0ecc391500083ef0922e00c692c9ab09abaa30c54984e918cfb332f96172ee1a0440d3b92175b386309475c92c25199d6fe75b1da41d0b86a68131a57fa839a1884f526948bfeccfac320509868235f05ca7b57952b3c5e65204f11c81c3077cb14c0b33633f9006b5d3c67f130c3d78038d7fb4934e4cbe8e3429a0c737ee48bc96849f360c83f2707bcc23432264728df21d4ac896e51a06a3b776ca7386d6072046abbb52c655df001b3007af2586b07cd7c81f38333784c2cf671cf7f3830a6144d4107fa40480852b3bb4f22bd2a33585e88e47c2b539dc099c298ee492cbd7d7a3bc5707c3c782d8a96a14701c352c1ff276a15762ab624c6d307a5b4dcb323faa9ddcd52289d60531d6a93be9c28cfc9ec3c489ddc6bd144a0458168e5b5686e92625325a8418565eb6fa0fb7619773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7bb2578e2a42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c4801107d0326eb24c7fd4612bd91275eca20f057c27e10b92e0b27c07a4d621751ef66307ce584708a5a58661838b56e2b2670ead04a9df7cf09bb8c83842dcfe4cfab4a83e75773e57b908feb46bf44013744bfb1d3cf98d34237b29207961d5d5cb43d6a49b17601743c86640ab9cd4a1786448c89e12adf884147e2cf091b66da57883cf36363611e04005be8376fe99c28fbc50092a034fb39abdcc97c6ae0565df82d4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7df119e86b92c407cccf98581bc62ba89228432a4922ee5c47be661dfb543ef26306f5301169a31b054cda1449cc2faaebd04c2b5823f58997defc48f6db37300b0c1c475a866b035639a5bdc4669cde9297d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6b31b8c529b84cb42dd8e2a48fb240c6b703c787590ecaa1f74044b5e295122c0a81c3a71322a2f4c9a33ea67d341a4426d60169acbdf19827759c144a271078582a33541bfa9367b757baef6890cff95d32d68f6c90338a20298b000e9144112dc22f4bb3117a6abf83b86b2b3b9cc244330b97392dfa3202ec7746d081f0a036360abad9d7028ab5bbde47403ca1a7c68a2c1679212ba707663ca412692049d45017f4993beaad79a990bfbb416d3072af8749f7f251dd51ba3c8b80cf34cc21ec923ee2a52ec3c981602c94d668bdc108154429508296805c156f05ae7908310fc176ba241cd35275b4c89e52786665e5798ca71a5eea5a721b51de6a78060a58f1a24da91666fdec925231c8c9f53d2fd270920092f29515dce0a8a2c6ca1e68bda6ea24b29424e22523a7d41773252e044356650aa5aa467b3cdb72be7700d268572d620279ca0668ab514243599de939a85990bc7cb640019bf8271efb7b1d32487b2e912e4f0267fbf197f1e3c4de63ad7455bbb2204db4c5995641892330c5b5140dcf0a8009d135a92352e97584c1f294e9548af9ec348e7408b448b85d234f6ed614834706a0c978ad9a08cc814953b8bbf2bcbd87071b597343629b3745d212111b7230ac9275c037d5e747afe60cbb9b439b06beaf537d6cc80bc1d1ca3db49f53c4a935a0226f37a85b058f32e307cbca9b7c62ba581b351ff5cafb198494d5abc4406e30932355754ab2a38232561319b0081b266b1fc714567305e0b27d3d6cb8457baf9242c598ac29520432fba3c3968c8e81078989380085178489eacb2c10c452079b1c33634df13d82b81da91ac85e43815f262c133075cffab454f50ad6c35410b295a5357e95fbb8a1d80964a40184a19618d2c0b7e13ab5828b60d461e10b41e3274363687cfc5849fe6badfa11821a31c2f724735ca1c4cb365b16ac43cbb24ec865a6dee75b7a6815500072065aaaf7b9af31214ad30ab984c57515a94a67b7391a37044cc22c9976851b19cd975a2c3be0539b213b9032928722029ac59231c90945a9bad4d39ebe623c08da1421d90fcd990bf8f8807b18c99a3799de3068a09912bcda3f5cab1089caa3eccc831f64bef79c538127b152f97946a264f4085c50299601043860d95832d15ed6f06051d12386559acfc5934cf4110827476b32af4498819e3ca252f28b48a96195f0a7c8e01a81d00c9063acc0954337d360b514906504ccce6a54bab7a3624130630a5f93c97af1c1a981b50eab54937251b9e1388842847ec6f4296870b51866c04458152fe3844cd879f335a7a1fc0b04094d2692cbb2f84f4a02b500d38fce69145dac4d0e4339d7978ef6e651c6110154046050b52bf29751c0778bd5e0409a1a2145bc87b1554b5ee209ed03ce01c251f4f39a67e09f2629a8024896c6c59f2e9a2e26523273e337b2b80760db1025f5b21931a82673be930ab5358381241acf46879650c208ce840b48041997500c8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c3a2b61f85f0b10ba790512d6422900db29d542ad96d8b6c0d954205a0d2c74810ec4469bf2b902811e5f5778a4190961853c777514319cab0cc90cc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1d3cd2febe168b1ddf776b954e96085a7d475e3c8cbde68f7c80ffc9fa46b0d4311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = 32f41efca0bab79755ed200aab047a395fce9fabebd21c174b6894f49d4b576fa778917cff6d1507904fada5b3234d17c15d8d2ca1e2af38061283c2c110513958f0a1f416b37866fa0d1d7b386197d02552f50e43934034af43f2db61b3c57401cda202fc6b13376b6b94270f6d28d9a45e367a7fb6a3fbb35411c66992fd3a3e80193b4ce81ed09c985cc5713cd39eabc1832e180a5363a486d3a3cb32b56a515c0ef81221e8252076d85212415d0d8bb62e4e981fc092dd3dffbb241d3443df4fc9e65aec0db1397e4b2300c94db9b25a514b1efd8b309cde4c84564f7efce1033c76cf2f83b1d7e27378701167e4199086c7d5590879850c2c114a6a8367ad045da19e04e0f5b5caa127ea3ce1555abf5b55bb88ec58a20ace7ef8e3e627a847056776588f1f5356580d155b960a839731cd6fabd9dcf944b07f08818720b1bb8b77697bd55d255cffd0ba71c241de4013a5c8d8eb90336a64a99794a9da0bcd8bfdf7549c5a6539ffdd821e18870d4497aae172f0c16b10908c4f49304317567d43e3c567ebe91407541c90f6030520343797f54b96839dbd9b54c5fe6db4a33146e42ea74863034cb78ffd3f35871cf66c791079a77a05c7119fe94c068768c431772ebcfeaa41d71a95f581243c42e1a3c7f5390efbaae0d16e35caecfa8f854313df32a2fabf90fa756a3eb2ece0e8e2cde0bf47f85fff1f3927ce15cf096298271dfdcf2822cde284ee563602da0fca82cd90b03ce8744a52a82f42e8ae6bf477dccfa4f0e3949165c7e8b0328a78d12cf8e9dc96a852fbb4005642c48d70d7360150d5ea284b77e30ae24b8142e1bf89ceaa3ef32eb877721f3d6504ce0c3663cfacd1b74ec92817b2b0d90aaea3ec36f7aea7f1fbfa39fb83fce7411918c3c07fa8d4579277bdf5f06648252cf5b9cdbf979fc139534a508667f075aeffe2b12f0f818ceca7c684151c5777beb7e5ebf9bf2bcb4b06483f6f91ea2841bfd5107a6c12d5d808b31ee9c324a62b8c274e224f7b87059b2d71659900af62596c40c36e1f44092345dcf36cce43cce1310130e1cd4663fd29bc3e6092ad68b351733f6e5157da3d3a2b62d0cabe290c2118311589b11fad11b7d74c15ac5d074d67464f2b1e9e901b7486f7f600d6e45a4a0a6fbb9423b0f7b68cd71b388a0227cd855ed6903373c8f269dc16ad7b02c8605351099036bfa842e6417e114ee3be6991e338f7b66e767348a41fdb174da68ff22135bf267db0d509fc9b8a98335709c7e0d9c6ccb69d9e701d7bf7263e08defc4debe3b09a6f10835fdecf0dff446ec5cc9e949450fe55fcb5d323957b5da26db9797663e9cc0f605797258b3e1d3f5a700eea83eabe1b2c2990d1b6a26ea97361f853c1a250d6e5bc8f5db9da7766722094d9f2699e975de35be0469d98c1274a3dfcdf97f5a3e861e6894736a7c6d85236689ede2c87243059a9494c536ea4cdb08645298ed55b982aad590a739420949b203723684267b16ec9939aac3c2159a32372700adbd4c6e14fc1b0823087c518ce3647b30e9ee9d4038667c5776512b1ad1529cf17f0a70d9da127ecb0f536f668b6ff2476f2f1e204a0dfaa4b83d2b35eb677c588710670df1da6753a3d6e1bc86c89b528ee6365ed85dc0db991b4e5594e74388a1bd1a05770ca93a0e78d96a2431c47371446f04701750369bff390a4dd366e63d4a1b536dde21810d1cd27368e431b4c94096175b41b2e3f3374377de490b31c1b8f36d0485461454a51e88eff8c5e323787b8e5b1a69016d31e4d341280397f9ba87651d9f341eaa1b37aef6130f34484cc1673c4f0ffec892e859de2b4aa0f03be218cce765e34257430e5a8e99a51beb25bbbf5c6ab7a8801aee3533322e06cc282c1ff735db37ede240f47377067424cf56a75a98ae77d47fa1b1e95b6146d730a7e7510182da193b4ae3aedd82a8943494cdc92bc7a069855000e2acbe6018d3d0669c16614d0ab413e43f1062a6be89965f497ffed2a0825d4d455b6fac1120b1b2999af343a672c7a702253436c7adea48087ae99be9cb9cc877ccdf0b21cbeb3b3a5b2897766daf7617cd52088ba160148f9ef21ade71db2faf1535f0bc276ca34b2e62392767e8f8a48f9104b6ce4bdb38fd9a273cd36d15b27f1a9c7f5fa9018917d62c6ea3c9e103a95619dbfff5ea1b38801ed1711777ca7abb7450c0b +expected_result = pass +expected_shared_secret = d48544c1ac452c0b821e080e02c9c83e95252fb033617ce270f58e2974679fc6 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +private_key = 2220bfa6a447db5013ed5811b45742b6e95c723a35851518e04b1b619c5607944c341a1aca4c0eb297bfe3990d514aba3de30867d646cd76a1ec1176f1e84ee60704b0e04366e27ed0f321bbf42322f5289f5167435b880851b48de717e40a1b56387d4705815701bc2b80c55f33b3c20244e0e27ffcf43c457a3674000a4404b4157cbefa05c54f50021684059939a3aa088dbba13be56047df450afe33c8742abb0cf48e0b1c24e8719eece41ec4a3254836b4e45b4eebbb43d398a813bccc0c42cc4e437050740c892b657765b252943896325e3f4c45887452847aa315ba8c811b39254a5c3ee64f65823fcf2a92e3198d2981289e021530aa4cbd210fabf51094392e25e755d778a02ca145fff47165711ab9397a0f9b3def26bd0e5143c23a815c8582976521d63bc74d8b42b95280cdc77de3528628862f44d475f49ac204c87d2647414a4a136a094b7fb923bfd3496b187592e81b8168bdffd9522f60bc37052fc579cb3f7a398dd677ba14a3fca1248057a59a58531b7a1f1773735a27612520b03121390cf624d46927cec7c7d00ab13dc2ba6445236bc68642ec9659d7bba40aa692c40794bc4bf5f13fbb617e711a54bd825329ac6a9af2a88a54a600c0cd6754b4a3accadb397cabf2af41463c00512d6d206d011baf6d833e4abb8dfbf736df8036278a8125389c3b99940881760ac150967464483242dd52358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0db0edda213302677fb73c493a349704333278b201b6baa8315731a348ded27283dbaa05e057c26c35d68a5252f1715337a1543895dfa4c395f9909b7b1283b450b71730292c32dcffca05221b14849aa5f94888e2a3fd33cab3b380f8093742247ac27012e8d7a6b8702983dfba43601677679568a8051925133fbf6550dc318e387c3e3176ec9c3cad6a739c6ba5b72fa587f000ca8f06eea003cd05970652b0f3f92b8bd4aa1570b02cab21d2bd0a9937a499943ce285b32706589c11cb662461444629f5c755b4a09805dd5659127bdcf5466270a5cb6328fdd0583e701aa98d34095506284b63a6f7b39d0b31fedc43e20e4bcb39b99d82515e041627fc5402290be758a062822c26b750463141d9de8793b385f556a3a3f74bd8ab61f69304ac4082e08f2cd05e5beade17d2c87b9535a084a6b0547389d08f548030b1dda0137d170039e082c5583bc83695aff0898f7e19e54204582989556b924df35a00c518ab95cbb466b5ba0d8aef007a8294294870902e74152832365fdb79508b69e45484139b4342df8c391864b80e807b9dc8ddcd4463fd1a986986b81a62d79aa9565308ac1471f09d09a23f24e4ee5522b00265770674c61348fdb3bfdd539994b20ff22b210162961b56dba538252610fa607372db1317497b85307b61d890a62b90e4dd37246763dc6093af5f4cd0dc20081ba4ce2d6bbdc969580607022c590a1687004b0730af71c60590d1a6b2a5e51c742d2cbbaa826600055f4811287a062da1696a22808507aac327a9194c5c6d49c823557100c158e60b845af953539a855d217c5a77599b1783f7488aa85f222df73b837e4b8d1006a8fd6b5b06083a3884f67e9cb7e962cd3b8a8cf22951f74aecbea2d599c533de42a0ccb5e94439144551f5d839215d9021fecbd03d8b856d66d37331997a77f46f067a83727bb0ca6b3746f7ca6a233ea575d908775c5a7ea497917b17b51ec8d58350aacc1cccad921ca06061e82067fc9215c5a3e75b861491771196836ba56c99b25cc5ac10008730518311fcb7a2ed14972b72533c7c890d83a5e34f75e0065021830386b1456da6a6cca5a474c3790850a71c0e84bc7125fe21a9fab396b37287a106baee569a7adf0845b49b096f689ba245707647e7fd70efa020a342c45335ca9e0809982ecbc38f55d4f9a9c36578198929eb8290e55848d04ab7c952513ead8484d44cf46f6959717b0c009938917ad916909dbc764746c3cc612b5b72b4f16049140b5c261e29b326716e401470e7b6598ac37c7c57dd3d47d548377a4939a0a7886eb7780c667b4339873be5ac23765a05deca7b264978b14952920ac0880a274d3a5ffc825b9a891df5560938b9fba313e05e782691bb9c0488a7838a4b4cc6cd3bcbe7ec12d1af108849a2cea79be2da250f029382498919d670022f38be928a341b9783e164567aa87a9055fca176ab4870a2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463d51504bd6b62a44b0c0251afac229ea8359da303066531ee34451fcf796544125f933cd52f9b2a5e72e1a42a45ac9a80730376076cd57a289d5d97e4e1c5826757943471fa4ac0b7dcb737bf95f92f2b94f844b2b26297b2a44dd9013767b8b2cc7c1c8c83583e78f12e60050ea0e45e3453ea86166b70c21b0310059c58e684ade01b18f93440b0292dcacb6c9e3488e235f219c91914302d1495134e9c2b2a3acb6f4357c740aebb4534448bc482a07ace3b2211bc6cbfaa95ba4171f955ff915a1d5b13cf07184bbb230ce99c8a13264d3b98c0ab0986d62ca8e22286ec90029623d0f033bd4c13a26f08120f76aba45a904d01266520206e6a76697254b7120296820d0a0a29f662fb623c34eb282852832c044565860200222524b42cd2c8676cce763e28555b8e86a2c710b47d40a788513d140a41a65bea5cb054b73ca98c3061a39c6276a96269cca4597897c37b25f672c0f3766be5065a05b19b4cccb1a6771421b5cfdb7094c89c48c20cafe814d98d41bb5733aca166e044810704b1f9d632ed279275c802640d2bf754a99367b4a5fc959c8f309aa028ce21057fdd943de716e3f66b76660011ae354ec9475b4452932859d2dac38a853cb1edb09e04a367e02a92e89794a0c4ad866c65f3b4657492d0b575215e7926bf455686393ae7c507b9c8b9062c89b2310725baddeeb8a3079a7301b5be5f463f826ccbc8719e017550734812f1b18da724b99641e5406244a28aad89920731b387b934d02667e86b2051d35ad6820909924551430177f934650b61eae840d952b9f1f8b7e22ac6d6b005013439a01698644b2caf2b205044846d84075b715835a18c5df409f686a78dc675aee4944ecc806339b5cc8d8bc64d24bebf75a74207e60a37787c59c5e6875f61238fb43745e58bf3d2168c844b7c24c4ea2822f3abca76163a40a219d2798a2e1a8c606520c5a622653348a63980e61f52654b385575697d56c86abc5536ad67264a7c3813c1a1eb21442b1c0ff129f93810685a359fb13167e59b2df26c6068b641738b6ab82357c95c0cac43a21f867e005c96e1a4dd240975264606cf8ce8ff7bf0984770a282c969253189cb70cd3440a92c56319c9387733af98cfc8892f0e6736c6b44a0b952934071737a24a3400257e3c1690ec9f76726a327521afea4259d87eb6978d4c77afafb1b9be81cc4ce1197592bc26908c469863aacb89b13b231fcc9669b8accb2a4a61f641ca173dbd2a1494519b77acb0dedc284f068e5ff73bfa9109c1fcbf34b15f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f4319997fe1bdceb9513c2ab34691292bb961ddd202398b99c8f1aeeed7302262359be5b1e53689103246a473549b8274a1753721c621a0f468a6a9080a007287731bb8d99360689fe616c707a9c0c04c919b05a5add406a7d1aaf9d675922439e4224300b18e5d2966a6104cbc5a43786584ec877198dc8317753c6f0109a11c3808a50693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d4f05e20c2cf9102593ce45770da720531cbc50552f1b097a5a96bf291895ad9c0fcbc6a462068eb2ca7f65217f0678d0e25c447161cbd9029ec24845c5c1b2b7832ae41172efb8fabe6543ae3bbde44a0b9f926b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6c8117091523209ca8dd342e3bbc0e8cca579c603daea4e11b06bcdd5be898b825452a28d15261bf9abe00a7eca0474ac4c92b0938aa2a00854f3a665ea56169b3c572187ec88945d6c9637b4a8f91249b8614e9647760eb68d2c08c21f390e36370cf30ca0bf0b5c48f7287c822026e30850754b51682a0ec016f4fa0773b642d4c5481502bc9f023ddffb199fd241f3c977a9522de7f61eef4b0ad3166515697ec9ec5ea87796dc6a24da4939e8b5af7fb191f861abd3850e4ecb1f8b819ddfe605ed6a113ae4075ba67414b4690f59b2a6121928eb21c4d5cbbb4551d2c00fde22b537522663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef99499c1b006a0ec2c299c41c3f728c3bb7848957fb2bbbcd05b65233b89a2b1b16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = 13061f9c915937c0e1ec0a9573d1e5cfec9b9db980f404000206aecf2f2092abecdcf46a82a342db12ea41d20a231e64182fbf8799220966d5d5906546ea40a2d9a5d431f67784ff2c041a70cf20b03ec219387419a5d5b85e0df0b816bbc36204f9f2a9578ab785135a65c0d07c5d5cdbcea40c8cd91d552418ea8d3c0ae467701dcc82ccb1b25c96eb14112a09fb693d0077228b36ebbd49e791a00c87e4cf76844b13caed08488239aaf586a13df492c9d0d9ffeacd66441568cdf84c7a86ab83c38441ac585c6a71fdd79ac0de031d18ab0ef1f133fab18521c5a439c9f338c4e7493290e98c7352c0708e6b576a05fb0def5b757ed0a51346c2472911029bdc595fc1afdcac39d3d6db818ef8a7713013b7db2eed84d1de37258c541397d7ed5c37b63563736f2d0924704e02c3d457deccb3d68964e6e91ae519199291c4fcf73a6a3bfd87321937cd8955ae5ac14ae12638781cdb20a12b199cdda764378839dd778a1efd6dcfefa2607d7479ed80918a067f6cb198d20883b876c57756accdbb13095b848411b5339b121530f9237dce7a210146608513accb3f377a753a90dab9c9559fbbcb214b3f13f01db9d578370d47a484f60424a33cd0edbe460b5f399dd64f6759a8db56013f2292aae64f7372c89e8fcd186c17cc18ad490b78115904bf8e13648ac764dde042ef51b082928a1db8ee45d344a70dc01055d38ceb21d81edbcdea93ec2046bcebdb07ce89a672afff73b97e76415d1c2b8502653cadf4e0604fb62f6a448e0fbc6355c1d97a8f16852c7b164b3b77c7d8ae594b40300ae124ea63e398b1982695810c949c316654f8861269e79ae7043e3c79c81337663d1f36c8d62925fdce17782ebd5250ed6479a2ed3a8619b46937d7a01864a7bfcaf5eab26806613208c1117dd4fdbb2832d941d292d20d5b96ddbb1317f06a64671857cf4b9fc78d5593108db79db32cd14da3454fe3cedbdc44545bf72ac79d5ab6e1c95eed4ac2ae27c379c9e9e763b263d30ba070b3bcee5d1479a1af464f344f59c1e9a187dd28a722ff5f31738a1b45f63bb82c119c4934eb30b47deb53d77c18d9592f98c90454ff03489889d65b551dd06154a5edf007d876b28cc8b2713afd7d952d53dc13d46677a3c846a4568fed5a1685112d20f8905e333bcb2d962ae0abf9f2868acdae7b7f6e3132ba9193ebab674437e0bf85e37811473bf07113d7120577c956d484f2d5e828db5cbb3949998f16b2a0cd91323f709fe8e7255dda601dcc3a4a41750e622f9712f4583f325a7c4e4977aad6406884210789c0a6c891165f67c55eabf3d2a1bebdee598ead19754fcaefae0f5f656caa3446455e04c95403867657bbaf6c0044383c6af8b1041d322799940debf0b110f6ca7828a53a7aa6bd0d7a31192be03120c61543c51459d2a86737f0d1fc4d195bfb14d80039dbc2317b5223283cb282696cd88d08e3d1db6c310337f225e9fd3c1dc76eae923f19bfba306755115029e26a9240fc722998d89cccc7bb176d72bdeec70756aae129a7b9e2d6f4a83ec497cc0a6fa1f27aed10f5b90eb58be3deb3662f60bb2dbb704379d45eb57f76cdf88189eb67bfd072ad751d48d3c5b7162379464da0249bb39b50b58c479888d7826fada02cedf7a0be759b5348d0ee76a7c95f697fa52a887aee6cb0f7e80934d938ae8b0a017891f1e3aaaa24360e08c80706a28208e5ddb1c53ea748adfb05aaff3febc468c9aca5aee9047c3a63151d4e1b8f97957092b2453f3e777c42fa218b31db17accf707482aa9f93b3bfdde8c7427437d21201f3de3bbf703a98d694f50e75a4be82e1b9ac2626c384065e40ff1a6d43f194efa0633dbf91b531241686be479efee669f96d10434c33129e7010eef00e4f97f05619b502f180c1619f8286f07a6c978676b4026e8cb62b42f564d34f5509abdf230f6bf3b84ba44acb9f496d2409680dcb4343b36663fc7b9384f0d021a92d4cb1ac48ac62f31132d0a12ba9d63378474ca52cc3c70f08bf46efcc24b0da6b476c427b19e2c51802c93d34f33d6d70979bc8b485a8c932fd015803e0540fab60ddadba357e2b156d22e84f261b26f6f77050c97389531a6d66a17d0e9e2e0fdfcc7c3e6209634911ac774727eae38a716a978a8005c8be1c1c6717369aeab55dabb98b0f6d701e5df14c489597ee687855db833219 +expected_result = pass +expected_shared_secret = 6b8f4cbb3c4fda3c067d7ba48bf24e24258ca7e26bfaf918b784d01ae74ec57c + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +private_key = 7934a9fabc835bf9a77bb807332251daa00876e5500d2c59f07485ed01bc934911a336acde5527dd166476ca1d1aa558cd88cd7bd17ce1791958e851991867c0525c9472a953c8b04a730e2e132c6c26811cb86f3234229f4caa2aeacd2e3c840e97b8f1805b94d7317b08354bcab64887a4e6a98ffd90a7544562ceabbcce6489c6e8534119c9589c405d7a96de3230094a459549b6f37078f2c01fc9080f049464b0a969eb742419147c8b39b8065a769d400a17bb25de51a699b69d54ba460d33ac6a6965916829b7a578d0b24bff786cef9963bf961adcc20f9a0cb1c159865a344a0e36879c67852df50aca08a46e72a4a70c027ce283de5bcb219808f2635bd7540915c5485ab70358cb017882b12acb4426b22b02605873f2bd0da59a658075136cbe15418cca0a11386aad43a52e3c5ac97f36bc7f648808c260643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc6007317a165e6a1657d0277c1e683beccc956d973c7624e959724ff9275c1aa2bb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab3709d20601c2a943d5bfbb3d384a7e83a7793905301b1704cf49992077b19f0204f3394717c9ab9a173113004fd325edb797a30155d0d2a1e4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9325f1705613705628458bd525fb333087cb4b967a61a994cbefc504d18c1b8a62898af32bc454a57e264722897d5dc71e32c2495ca857e1a234ae61c77083ba9b780342d7cfdff8b7ec1257b79cad017113a3238510c5683c3a8c396986ed392b0122c16e34a7249691ea7a931c44087fa1731746c1f3855bc72414fe3484d85b5e2586b6231b4bcf27831ea7b57070a815795f43e90b2112b235f5959ea253db76192bcb11d4e16399d40c5dc0a15d98c3b3b0289f07839f7738aba3281d45aa0a9ca1d349a64e79246c2c7770227f1e1cc74db8ab7ea7b0e60a9dc0e45443b30ca656cd6a8897ab105bda51b02179936f04374554a52992710f2a70972479462a2859736c2fe4359a474939ac3531b2905f90bc38860b5615abfb1a1327814c01048bb93c9725c7c3b0547921975766a97e29d529e4d8a090c36820db0fec33277cc679cd4a51f7ca05f204bff20acf63ec403ac7ccab951a8ec166c545abfce8734833274f724e77e68137967da75515e3c270ce79838839721bf3a14c952085071d6b3a555ce62d96e7736a583f44f726aeb921caa340d4bb788d63645deb2621629dff8a2c51d23bfee95caa7756f1884a0cd263039c37f7415e83d4908507c1b17a7308cb329d829c86953422b8b2f1786a4b86b980751255339258572a02ab22ad845632f859eac223e1245ac3533d359246316a3cc1ac58b4e6386592859547171ce05dd7a76bf8e93901eb7f40114175ac45e0b35109ac57be844c52d31a7ba60a24f30ef0e45581242c02e020ec86af106836b3dba8071bb8e8574fdf208100982e55f4b0dca72521440a2aea68c57b2039d14b21a56274972eccac7eed41c4b26cbe2c973507f1cdf4e618077406ccd3c8c5118545178351522485730b1a1ca7971b01766b914e83520bcc82131c5e5a632f88ea070ef636d02752ca06b94df20de6f757021c1fe4e4883f123d097993f1959ed8076c0491191b0a05774c5a2d6ab94eab91b1cbbab07b8027fb57730820f19609136131833bad67d888aa29bd69169d8957a5cb8c3a14b54d3f78154108904ef15d1f73ca9a635fe1231ea9e18cf3a473fe7492a3636d85b70ea43a7aa68c4f3f24c2a2e88f2bf5568d790e51122a27aa41246422ea78bebfeb6038db3ff65881bce84496e65d82f5c318c0217b5b5e299b570b038f740238a264b00da749cea6ae22bba8bc314552132894d79d23e73c492857d22a6f64aa160c774f8b24a8b14ca805619231347463a22f06ac2a96660edadc1bd767524600ba35789c0896897f2bb1f0c88c0b875952c9a352ac4d78b69c55687015544066463da8e0b1a3a8481d6bc89ff3b9590b94e03aacf4c0c12e404cd51aaf3d696c54158101015a550a455a28042c73627c7a414938636481647c30c90b6073b1582e31c275cb12755a287f967a7c6c377aacfabb57422510ca4505128b60c80e77b5c6ccfab6f463a63c069276c9321d8c961802a956f0b8f41307a73b5b4ea33828d1bab555c02616115f890ae7b1c5e6061a484825a448452bb26fb9b13d9bc002e6798d54238125477bc01babe0ec7753fc8c8c959916f16206a7ca31c7b121724e05bb5d71c648fea759a5d2b58a257e728230c2ea779ec4c55f2319cbf9cffeeb1f285a9fb0d4a391386ce69bbb6e37a548246d1061494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e53a2766642992881a2f1c8b7454586cb3822c125af4d70b15ccc546843100b1443e365cf31680656879f00e640692b94361286104c79af9c1cb2b98f01e3b9480c5b0af0988dc7bebb33bb3ad87cdbe09828a25f17fb323bd17a11ab961c236eeab89cd7c3030f4b437c09aec5f461afe64e1939c93081b44c8440f7b070fe982c16ccbc99fb0a8332739b641b326cc689c51c7ee33003a277c41c2a05676620eb9806ea6f53c2060f13a75ff67b7d1b4229443ecc4023c84293f3cc58c60a1bc00a3d1ad31aa88aa6d2923643585d39e16e5c8bc5e650a578d60584bc24c2fa2aad7b2cd9c99ffee6033353b60f506b95927dad7ab997868119b5976f561007b51aca6b36b08b03ae40a9dcdc19ffb776304bbe7d3aca167753634969cc57c48704a19a22416d2cb658e75ac2d428aaf9a13e6693e4d94df1f2a6559a4fdd16354c77129d32bdc3fa136e180d66842fd2a9540c63ae7412acb67b788936066af5b7fc44409a77a27017c9b883b705caa371b831c7195abc01530a97728708661d343cbca7ab7268b36294b2efd96f87a298092684b02569ab5911f4825826362414fa2f2b955f6a318bfeb18b12d058e4926ca973248d162164acb5b7a8a7641c9557a8a0fab208ac2744810397cc049ef46756e4d14a884745e73454e1d675c3743a5dc2546c424735813ab05353cf65b604ea3e44d8828c7a3ac9851848090b0639934d9b19ca7630844003a944238876966a62a87218714a4b3f89638a064846fc4163d03341840091d75b25dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae58012f2c3938c40cfe1281aa439486d5791e745892eb36905cb142a5c718f456b74ab213f4ac50cc000cfac943c60c3de626080b525c52051ea231f18dc126eb1c6fb76232d5722cee0c9e458c09a38c35ad64959bc64ff252358a5cb1b07384288b457ab15651935a99072f12336e14882a2d0b6f918933ca0574b49b214ba4018ca4b1373cc0f007b683a9a44f842610106de16cf202bcf0896c9506855bb4849beb06289b72041c75512e152183242a5162678d10d870aa888e218ae969c13b024729c7acd818971e598e495902ce92d29c73d355bc44eb544ac760c0cd58ad8157ff242963ae3cab5bc37b9c78ede033c210c59e20245fdcb51f7ca9588359e2264118ce4057dd7c6ade4bffbcbcba5f9433314cbea9309a0d86a15bb6f753abdc47149f6bb0eb339734aa1638fcc633244559a08af3c4b15e6bc8cdc63398165acb51925c7141cea32773fe5b0a64075d66c653e750cf42866255a9bf7d4b66c488f774193ce9b35ce52a164bbcc41f7b6779a9b35127ba7087a4b673096bba4048410778b18270674af334bb92475ce2787bf9a08b587a6d48845e44c6e04a254425ccb59b5972fb3a57cdb02f5100d45b43b76140c6047bc5ee59fb6e012660138d7c107285a2d461b20f1d49e1c206ffb28be65e26154a64df73358dbb49b77258fc45a15b9a80144099be67b76fd60b7e01518074b766211132e157efd507b5970c862d5cb870751da46ae460416eed595a74724152ba84229905880cb682cbe477995437125fcc23677c25fde14533c6aac694206aec917162b4efb61a1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d7872a694881916016c1af8abe353cd1ae2263cf417c013cf46212b3d5720af335d40b646a794ae602b5345300e30f4812e295f3cf07c2117cef1c591cb9a350ffcb718c64b0d76165e9a719ffb75f46b861f968eead3373c3cbcd6a983c9270fee433b2970b6f0947b8ce46fcad6518d5042d109ba53d324b9f657182bb110961e96a8b34c5a4b808840de8b71d0d87a510944a9973df9a900d9a6c272a61bee2200b4c80aa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516aa14ea531df0a7f93225de1c75ace0d2692bc750b1b538cfd0d860ae9c5a8c13faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = 67f0df1e6668d5a7bc8163a41d22f232639aca9455710213efffeabb29dd83664c4b50d538eda46647c9c16aaaa70b38270eea8b9c03b39344549b46997f519eb1b453047bd5c07bb496da5e22944d63dfb98c8923d9cefeb98f301f4a1ebb116e827ab354d3c5d64df0a46fc19cf47d7377e092f020f4d50399bec12f86a1207078d68e6ad4141d38f28ae3b78c0882d8661d87c8b1f681cc49dbf4ea9b46201de47048799ca96bb1759a242ccfaaf3088a4b462df9ef13c9e087ed63c2c89d12a130f3446bd42825fdb07e49de847968d72084dbcd79afb01f1db4f06829e822308dc51b47f85bfc90be5ef1056cf7889ea7d85952a881e6ac6f5453b83d731631c0ff615f2a45fc7f4e9493614afcf2dbe9f2f3d7f4dd706dd220bb3ac8c15ece45b3669fe962833f21477281abcd372dc2a1fba3e3867b382e9ccb47d39706a46ee2b04865d4f1339ad30a719ed0179c73a433b726093d9b77a0b63102bcc49fbb1b34a2be964f5b4c23f7b02d5f73aab5fee8fc25221cea8e4dfd4280a14c4f9ff4688a924ab533f9aa4b5bfbdb84d4a7e8d4ed59e0ca81e95b8c6f655c9e46a17f2e9159c261a39b32d3305fe64938c6610e93e1fc5c18790179e40c6559553a4cdb5b93f61cd9a4cfddffd81191c7a48800f4dd67228d13d2ef61b0652cefbb1ed9b6f0d1994cf08fccdaa4513652e1f6665efc38b621e2dfe238a6cf7c2dc88413e376be6eeab6b0b19545c6f41fdb7bd8abf3cab612344009f35592a5757678594f8626124a039bc16da995bed5129f4c10b1a2b490f62e1521fd47077903b87d10b69c1cccb654ecb9bab4930796bc45506cd0ca8304f313e9d43d84bd485544fe068f3f18e4f480f6ef0346f6e0f465c90bdaca8144d5261a1ff817bbc139f094f8c486167d7bf582f0929f9dfcd8577e0fbaa4b058ae158e7dd90f57269c30e73c18073ba8c21abd7785d522d9c0a6367d37d8d9808b84f05cfdbd79fc8eb1e28a42ce2a2a9d547995c541033517da3a7a8cc0efcd1cfecdf389469167d2ab323d337751828c87d6aa4631049b10d3159f662ecfaba93c3d890d058b1023cf415eb03e0886e86826fc6aea973cf32fe7efb5e39a5ce40101e0cd8e70ce92787aa9b4e0387f6765638f046b1d7fed2b4ed3c8fb0947965bd1dbba5aacd8d9d3a6fdc3e600372f404ea5013f75dab1cfc25436bc7cec331b0e462d84fd60129de1767ee0d4664682105b504e09c79dc4122d364baa14d464b8da59dfb3afa71f380c77feaa6e14045dea85a8e58a6e354498719f488c6a42ce369d25be4fe6d081b8a0ea3625ac59c41c388749de1994656990743277ffe6f19d938387970f3d9004e12799fb85a6bdbd206eec14b3ee6afc5b10622c8d99b642bb08ccf840197a77cb6d3af99d36feb114f2e619996a00ab57b9f44d56cad1c8cdb2584d9019114e635041cc65bdf6917795cf117eefa49d667f9788cfb83ec2f2eb1cf5921937c0e65ca4c2b254090834a8fe9f80960964ce84c0589e4de68c214f982091ab163574e8c1b005c655fc993f552b02c0576ba8be57c79ca9692dfce5a2cb72e3114ea9c7d4b21f94bb54cb4ed54e798a95cb7898fa62f0f594133254522b1e0c2b6a45a391f63483d66fabd227983ff3b178b74ceefd9cf41d1acca4c20dc1cedba9cdfbfab63d73a49e077f464137b5727b7aaf91521a66cfa4696f786f5463fd872e923fa180dd4827be09abead47e532583d465dca6937544d93e131b6f33924bbf402f853704b7fee75c9865f4ea022d1487c8c690c5a864f45ddb378001f31076b3c89be009f27e01a6582ed3bf8f8ff5d753ac7398691c6679dc4e663bb6fbe02b2ed06a91a8f95b940754818dc8c16f74333f67771e78134243599b76a6dc5e4c4028de18b6bae67f8ca8a4d799da73721310274b1566d79f5e3f9b04ad3724ca0ec8a6767f4e65dec7394a000f5320945a530317b87161405ce3817f647a99faa6d231035c4e2d252c3d49ac827d435c774f245c801daa956c6627208290fe57d7b97c913885fe0fba2d396139a1a56775b8cf7bc9bc02ea6acbb62561da17457d455d72c44edfae372dc3219100601181ed4e00c7ef58b16f0ada67033b83e73769b303061f68871eda434540beb6aa0dae4d44b4dcb1f677846111e7c939b67e72858f9b20798ac159669c85c279cdd11963f0986b86 +expected_result = pass +expected_shared_secret = aa9878a81dd8165350b880c4af6a2adb9e50a48b9e0709f069c02184d3785181 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +private_key = 46f47850e2b9aa4a6d209125be58806002c278a6295da7a4ffe85551529f17d83b358b243f2a622f353eb6138cc6380f8ad3340d7575e865a6cfd34bf473a3da8b9fc961cd921452d09b3209d041d6612576c573b08422715160b891a3370268468078f5464d7e5b84b3a3793f0c7cb2a0a13df37b9763cfbf054c768b1e65a00e8366b406251f812c5d428853d0e00f7bd58a8e348275461c1336c2ac6a39783a35d849aa9a847f37f50be0b95f617bc7adb28c0506c16ea3ce89aaa28a9252f0e228d0fca732289d05d9395133a82d8cb76db2023924273b39cb52b5a846f338b96c5b6f3acb41c7265a0c5b13094231f05943d58875ba7c2a6889f16107d325ad1b810a0b3c9e8928169d440194bbb90f771796856f9878158a432eff742fbfd5acaf59521e361f448c0bebd805a1b4435d0761d0448d83e1201a506a0b0a4980172d05e88d7d87b42054680cda74a386027aa4c3c5193fb1a893bec2722d55ab9b840d99cc81408153b383345192649eb99825bb4b1957326c4791a2722951c0ab67472f4841c20c23926c3c331f24c360e81977c2791ff3171c2c489b68c923b65d8ee6bd2d510e6ae97fb771bab401bc1a42935f38a0fd43ae2f8a24d8fc3f6e15c2c6bc800b73ccd8e91c592452484b44e6b2a624881064526182950349c78c7d58180b1676b5191eb6065c50596232b9566e4b8f0635a7d71927f8eb8572e62d57996ddf66cfed2147dc3451e95c034d6b9145bc0d30c915d66b1cce367406212f8bb40755091c9cb0306a490ef5336e21f82c1b7b6ccc8980da28a348815112f00c57362eb163a36e016d60f020bd12b6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f64e07ee6e6a300dd1cbbc840af561746d279beaa71dea5318aa3cb3c4c63c4a91e0fb60d6dd6abf1fb24d1b078de9413f1b0bfd8916577c4cc9e0b0c332625a5fb705e94babbe0659e022234586529a194012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f22a0acf114b90829b43112fdd617089c8b9d872b70d7027d74402b65058347b56074ba33fb91998e5a559d46622f5423808c8236317767a32e4772ae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abcff1be00c7bbc5b5b25a0c1d853424123c98fb330318432d324bbc7330342224baff909849d65e1d08a77e07d07cf16ce6f64fc71374eefb66bf9c742e518f2e30c480f82652b81c4ce7bf42593b990980d94062f96a7178258f31e2b90e86241c04b7b44057bf4700a040b6c0b08e4e8a6bf1cb1eef738f51ca9beb9c19b94b1cc623704a6c2455009f48b4cdd0f4a5d7f06320457670db92c7a4371743593600022da4600c56296d336a52e98888818ca10282d4767010a7abdf81bb6752048b5b163da385d7c5cb134108ecb03398500c1612a1bd563b21a0bc7b94c9719a75bf3b3e02143bf04a7e3d9b0070c4b449cb9594a1a8bbf871e595178bbcb611b466a8677905443abfa1601a9664c5f54f36dcc1ddf35381f586b4aa4566c02be610186df8493a30479f4c72aaf049a6666e806b13fd77c3b738721f81218b48984ef374babc0156f94ed581133c180c9cd067dce401739190ca80cc8d441b78a986834033abe3432f863cba79cbbacc2e5463bc3bd1b0f1307140d56a0e0768691747143721c76847dce7b86337a584a146da0c664d904441441bce3276c7d8906bd336ee07452626853098444339824dc5a82d0b515164882c99851c189de092cc955c9fc53c041471c4e4f7cc8d16aa74d83396d88264314912632e87f68f36ac0abbe568f1a5bea9e807c21a57e7103b4ffbccd02a5fe3774e54b40e6063af2cd48c73e82d1d2cc893c35434472e2a892a05d566b890369f996dbbd9c1d8d542d29021d2f4619d89826dc45f4212bd2e607e92f80b75bc9cd8a803ae3a749f539165cb2bacaa005a2787daca403c83baa258b7e8061ae4d11b5d255b12d6cfc4650af458a4b0a37c69cc8774bc4f51979a120292ec6c8d7193c5b52021b452807aa78c2c26cf4e4c2fe6236d2f3ccf5273bd3dfa2653498b5b681e18996098cb3f593947fed05a927223b27619eb484bac5561bc7ca8a112136501a461538b23d07b47b3ae35420d9d9171d1fc6308f0c7b2015fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff140f77a87e44960e6fc73cf170991bc57fde0c406e432253a2aee4b0beb4d26e0194601fa576cd89a5bca45e690833592b874d3b3cf303475f1140a0fab6129296c51b4a5b30650b8c26b5e67100837d011c2aa7881bfed806f308bf2f99118565cc85323410abc6e34520b818b49b6369dca3a1ac2776f75142b84c76a43223fe2b7f78544191ab4f0b9316c3b4495514118c63c1f9691ed6ec30670945da0a92052a7d2d11c4e0f8be14b867d4708f6fb4569b6081ba685c78e2c835e0bc29bb416db14cfdf3c98e8a4aa7161859e2cf74277a4c4731224c0649a01abcf92ea723784ffc290775282c256d433a64b705899398aca7e084ab6958c801b27fe8b39ff4bfbb1aac410421c50aa911706790d3c350b6126cf9242e33a359e21e4b72561f1368c3d2265b710bf0d6acee3a5286f51dbf16c471327612ebafcbcc5e22a5b5196a06336968976a9308c075816727997b7d52e34b648b8bdbf229aa4925b3e5167dd1caf619bf0d620540f29f6e77091c4b430e708d01ec9e2e0ca44e766c7643084af17722488f4786a720ec6dc4765e0f558a7a9c449f04333476262d65c4ba175a0e2bb29b524f8465a73436bdf6494578020a425149f3cc0c9b474d5eea98ab529aa1c97a84b54c064c8902153703618e5b99122d4402681a9c72258137b94091382888b4636ca983c79a944a4ba0169a730f7401d58196dc193742fc4d20eca71ad359987086aba19ffb05c0e09a0a8581844774b12beb3692e055df16b67706902d625590037997a3beb105931afa84b5fa389fe2b2bb2b5f521169f18b012d17a5ad203e2508958954b8fda5956bda2126503f34c571457056b333c9dd265bd9d4a9ea601620454bf020120d5a0e99f837cce92e20865dd7870a1ae12f1da8b369c814fcf63a9fd830c4827f6b151449879c4ba9691e68a02aeb89f362a9bd57909c3ac1e064780fa1c74ba21daa4b6684bb64eb108987b18be7683924e3202d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e51222c4df502c8415089255e8a095efaa822b892b2a0a17a146216282991833338553c8bb4947d892923010711084a19435b5c3f6a6af7f89457ac8a5ea4679fa2921692c8af459ad8cb22ec187dffc3425d88b6396cb7fb627f5fc718752658a5fc92539668c7327b90b26572fa8bfcf705f11422382079e2333af6b51e65310751343764bcaf5a981a260109986b5c29d2691f4a981d391175a21e16a13dd2501f5a256bb86169c63ba737296a5bacc65781b8ce07b4b8f28b173b42f802baf5f235bc06c9d752351980a72b52250269ad66a098fc9b68ad57c698a014b9d1c278f3559b361e3b8ba2d690c5380765de0b2d0e3c63792c7f9c8122b297bb8cb8381d6780505c253399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa5529fd8cb5215893bec6a64201629031b16a8957623b0619b33c6b90c78f4e21f8ffb94d1a6648d330d91096bc87093417b1ba6e14eef17ccf3923a84328b5b60adca0c4348d9198262b27fe56eff73566bb5123d7ca987a26fe9a00d41a2405fe31af48baa3a5249e4c6a638985669d576dc7c9ba575380e959ef93c2dc5dc15ca87cf3f98675eaa87eb5a51cc3450b946b810d05d94a815376868c5d9594fd02891637ff517a6597a1272b7c9933c544793ad167b1537b478ee3a20c8b874f5fc95aa46851fb1610453583b23c280838573770609344f14c4cc1da33720b3257a53a8e58c1c0ee500a3e4781a2cafea727ff3b86ccbeb9fb63b0f215ab297ecb1485589766ca828332942eb9c4037bd76aa1fd24160febb8dc499c486a6125c137b77597317f06323c901ecb7b17b75180c71c6b1646751f2522f1a7d13cb7dbe0ab46385aa94b84acb565f32470fe75b7f9c876287f2ad5b0b52e4b5aac9a43eb17b207943ace482b46123652f7460cc64427710603a8307ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc37591bc1a926d57c0ddb5b52024ac3861785b6134ad8c067c5e9a47ea96f57b40426697e12846bfde94af1b27ae4305edb932b79ab745abcc265b8c7a37063ddbcc972c26864269ee557785690ae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0e0013ff7eb7b8266ee94659f3372f5981ce1d87584cb1f0e80da2c0c95c16b4ea2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = c4285bb585926557c351391f42e7b83e54b65b3f0b324cb0e7ea76ca221109ece200cee8184c5b603ceb8bc5af9ffe39bc281953379516e808dc913990e3bd0561c868cfa85e4922bd862021c97a437cf2c33c64703c7c7e637e000601e061261bbd710f3032c129dd435a306de39a48ac1ad1d751429f7ddf3c166e646324a01441a855ca73d5be1f80749414bf383b0f9cc8359a8c254333f9a84b9527c2984d0c920f17fada4d49f003b64a9331e542fb2e846eeffd59127bccf394c463124ba68b43d7f7daa9a9157c72081fafffedef56afe344e1ddaa5f9af8ac7fc52730d49daaa0bb710972337eef7df81fdda22781afd9a1849f4a58b194febb65c6803d072f4b1bddc29f3bdc5a536dcc7096a37a14596c3f6435d8793a5c0c7ddd45a17a9aac7da2f1f742eb23e52736ed7f19a082741b46e635625c0e270c0ec06d60534bb7334b57b6ebcfdeb0ea6078a775d23d6937d601d44f3b3ee5140356616fd2eb904a76e5ff7cd98d70281e87d70c108f71a61a914c224f421d86db3db59bb51a0b766d79258134c0fec752c29075b4dcf5d5980c8dc9a618defacfb44cf5bc4ef1d691bf3ecd77cbdaf34be16322737932cc105ec490024e45c4d8f558b45f8d6965554d62ef1cb9ee69687f2a6184c54f22d23e2944ff140b83b967081ea995a7fd99b155e9d75961dcfbb4f04bfd42727e0cd66abf9b6f97f7b2adb0fed4032208b62eb3af3aeda3b3560f50bb29097c57ce059f786480cafb27eb51e1ee87f82b12e4ad4929b184e73673ed1ff8a58ea812099fb1c6af044021d0ec5921a25fc7f6c0dfb7ac01ba481cfa14ced4ae4a74af863b1d255543fb80ad53a67a04333670550fba396eda43812f7512c2a72e69d3599dbc247893429824f88b5c9acfa3d6c789ef487a530af12dc10f90cb95511020df2e402ee5fcd9d5acf7a2bbada0cb523a4b6c6a659a5ac38df531bc83ba54c5c1c3d9c4bc88df83261df4e048b14751847dbaa1ed6d3820cc6c4af84bb857a02db6c7db734a3d067076802620e76d7e60a0c7459061bce780b844ffdafafdf7877b1775f53cd9a44e2446fe96a9a9dfd3d1476b32dc07f1ba8a767c0398f7552f0ab5f23a77982e35290ad2e85caf6ccbe5396b3fa02c01a62572260c555fad2b21637193c266cdcefc22f7dd3469cec1647c9d5969f2863f4feb9ba753c8f91f35d94aa6a0f188ae11bcbaa872347adf646eeeaa9e67ebf44689e29f00fdfb7b71a60a5df52a3154c14f67f7893e6fdbf8035d919163b898d71c0610fddef4e7ec1d4e10357a2c6464e81c3e1eb2b7861c47f8f5770685c781167c96e03e82fe0871917a92d65d281803adae1eff3e8d43f0acfa0faf6853fa32c507990cf811e9a26886ce4c4662d38331a91623348129a8042d7bd92aa194e4543584f6d19fb302f408117e49b4ee623d3971bfb61b96ccdfb9ced039f300ed0eb75a2a8a5f22cf2cae4c9ce8a0d5b74a12fa08824744f3417e74fe1871917aae250f4544e7199820498a42a38f9656ece553229c75d8014c4d09257c5982a6bece62e102c99b24702cd5da41e8cab445ed69e96f811467d2bafe55fa6ab14031606ef8192de2cb71aead3a51cbba7b6ea2b69863a12884b94d2e1e7953aa5632b6ecc3d6aa5893c0f501c67f1e1b92e794a11167e4814071aa227cc66fb817568f84ddfd7bd94552545fd84030effe4c42b9bc0699574279f6c38146055123ad5e70ebed2116b625610dd0baa82487ccd85db7a69543cf0ebbcc87c0b96074d31697b16ee31d9237df7d0d7d9e7d0fa9f5a5ff615735da5fc38da1f5a1a854d98b3d4bdf0a0afb924ccf66039f9f8629efd571efe59cc467a322a3b71a1240398abc7164be61df0dd9a99adf7759ad1380d4782fd6987224130a50064119b16b551c3773fe11843f61b979ca171174ecd7e9885d64648f9288269ac2523fde655411c4e0fba8d123e70e2bd195a0f2c98946c6ee4f37be5dfc44cc002119d6d5aa21b9cd9a2f54acbb5fdcb3d050901f037ea9ac27a32f7f090df665362b59407aeaeb7a80c9e84e5e5939d9e105901862206becf2326db1005509177aa92e8dfee8302758edd739d829046192d0037ad9de1c6924a91e0048e8a4465c9342d7f07c5b7286887b19b775c5facc4b1cd6fedfd9c8bcc3d46a263f1156df776065481b3f9bb004a888c80d5b38 +expected_result = pass +expected_shared_secret = 5a23296c84df3d660e7c2a973c4e6bddad3fd814e158028ff92b234cffb1afa4 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +private_key = 8747252c693a0d6c06ab66071b13517e1c45abb370d26aba3fb31641a170b365c5f6235d1fd688d81c72716a3921420d228a7bd5a1c48ff445c47489b8116b7ca14d3ea78b20a7b5e579c5681187a2aa8fc900557501003fb9bead185ba9e7939f247bf1757ea66a4392095ea90239a3c67a8ca70186047d9a6b06b8887fae01ba8e556319a003934c88ddeb05f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad06e116f4542c4322072e3c6713015b1339512419b4daa8c87f5a8bff481964a8ab8a101943230f9527a10a604df6275e1ef18fe54a57d7544402134ab77802333897d4769ac23093f9b951d735b5623452c90270a0896ed3a81bf1191e451a4a67a4542556af78f1690982360ff1bfcff66386827df93bcd894ac8c996be6e0a29de70ccd459b9de46acc9e8043bb82d01c40e5785845ff4b0ddb8184afc5e52a72e899093669a9eb110a100a1159241bdd40612a9b1955b1752810764e7b68d89704a61442adf68108aa229e406cd10b6527a39a6b46068685b5e802cc25614492dbb6e06ba2160e930733956e7b29ab9981d4b477cd4eab880e56eb711b278f540ac204a996b32fd06b8bfcb7729660cf5125fe1626199f6285da628faf491dce2ca3bf285902350d52c0649339f31ea3ab764b90701bd647194fb27383681c13470b8d5ccb61dd74c5f666ffea7b0714c469c4803107235599c998349b5be7ab9e9dc6f01e928593939270411ee2490f16c54ba672ee03b710978760b962319bab3c2fc67cd9c2e9d4c153a8717826bc4c3d6c7444c051a61a06a2c87a1207a20754e9d7725b91077766871509ccc93f5a1fc1c20680263082801f6b81e8f319b92110f2da22f0d8c251ee4531b127c44b378da6a0d26f55de3285190ba1357012e42521cd1855252147d1abcb1582422f55091b5eaade93194cfa0be536343a282c4a948c355984cd20a7ca454ba034ac7355b02730107a71b3986fa01faa38d17e07494fb510e5526f690bfb27294fbb963a0606e140a182a9a247029abdff6bd8e876ec92207312432cc2700ec4c6a4a7037c5b612eeb2099d54872a5884e28981d794c7855590f1f1464017c8724bc92e0b644de92b5b80a573f641e4e65bd6f0396184086d6a5a50662f9cc6241fb7241d194b6d23ae6fa3c59fe60c81309ff7e39f93f72bcb0696edc771a80cc5ffc74138ac9d01b95defe7258bc555e3e28cab6a73372337efa0b4aa0c7d13b312a7313f8b63426c6677407903822aa1acf4acf4a130c4c68dd4dc47dd061ed0a4969e5ab630baa11fa0aa51133c6509c83e603425a385730aa0e07a2bac0754358c812f483f5ca6bef3105cce4cc33532116c6493f19880f693581e08999be24db44b84970c8fa4f6784d50614cdc9e626a31966acf81309ea6a730eb42011663cf10a90a9ec12f3fe133a7d02cfb95cecc6b52cc08571bd03e8315532b7c76c2040b60e9021a24734854b6a3d77cbfd087015410b7322ad5d9b04f651f895ab5bfc25f8cc9703bc67dc5eb5aede41682a17feb1b4339335efaa44a64e8b4eb0bbe17fb00875a06318c1e68c42e6ce0946a59c61700a7277976e2e8bfda906daa229d20732b60965dc5d794dc5306e68226aa18081486c28b28093b12280fa2965cbb012ab67a05664950a069d13332ba5c19c8d8c7583c1f74e4aa60006c3e2c9b8da1bb8e1935730c31d3eb066697b4fa93ac65e21651535ac1d3983c915b72eb260980c37033ae51c833e4e3c1cdebc03a7b17e85c224ca078dd91024805c444d766bba603f225073846bef949937c6bc2a6bb4519a5b00036a5d688b354e64775431ab18c37b0167495b31328454368ba49ee2a542447466269c6c122b78ac44d60c983650237b2957fce240d39817180a1898fe589c0044819037f1f679aff2c11fc4c0d2e510fe35272d1f823c2781198ac1859e2ce252709d4bb8c0dcb64c4f2baa33985312a1193095379d9cfdb508ce634a0e305ad9d554053950bd8b902ec462d0a1910303b4bede153b11c915dbb1feb52b312c42f754c0131c1218f4ca4402c4d74430b9415c586419210196eab4c6ba4587ffaaa71583c97c329731cecaed1414ab3aba4d830a834d6b8013495c89c4b413414b2197fb4a3ab3d470a0ac937d1b37a3aa5b4f6a69bff4c57a8306ab886243ee6b34e8922f9b416faaca70a850d9aa008b382383470c0bb971027cb329cc91a9d89bd46b64e26b30dd01069bb8c99ec91895769bb93661b429a0a2c6ba5ebea62cc6b6923b27d9b99b8fe2a01db93a6fe6362d530093d4167ef35626438a949ac2f77772b1ffa65f0c771a2c18cebb2b9a3366f42782353b07961d485b7b70020a36c5375152f558f3e028fbba53405f58918541afd0b89e4092b0ec372ce48c4222a6b33a192d380a1a133272a6b2a66816f33e410ee02362f6bbbe44976dfaa4bdb99bfe9897894c254e5a51728858ed386980c52064ea3a1a837b5ba02ba34fa6de770b001b9a9fcc90fda64359f37b85f203c0ff5cf1e7c4681e990a11183d158269267722441048911b41be8b63dc139859973eb4578c929b730b1cc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ed91e02930c790bbbd6f411bcba06769b779e125ae3788d5b3844a3a7b4ddf8bf3e53274c29ae25f4573a459fc2093caecc197e050075262c7fe590b9a90dbfec86a2546e800ba726d344c0c667445b35872059365626c4b9af412b701e00392171b1f8922129123f05f3696f47c405739e0460590a52ae7c875f0a088b0e4924ef3711b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfb42645f3809dcb623dd48936c0440daf036f12ba9f3573623360ff00ab58604106fd820bba7a9e9b09b7c022262330627302e0852b70c020432235b11d750bb5a700b123dce093e25c993035cc1c3237743bcaaa3620a33b16dadbc93555c13ab0781463a82df942b58930cdde7aa1f256cb7860d0704a7d82182cd494bd803684c4cb4bc278655f31eb439c9aacc78ce21967ea07e1a6b99e7f8253229754c7a97fc6411549641018cbddbe2cd0fbb12f35c0791031735d4ab51c62e2336025f0b327bc82d92dc91dfe544db159319215c40666b86917bd2a889de8647ad658c16b9a3e1d21532011fd40b5c548534f9151f39dba83cc3170db022d488662a0223c750a1d4e048cf9157bdcb0c75185e774ac10be2b0fecaa021613cac50461a380f419a9fdf075787fba921a6a9f3ba49d78892771994fff11a57fb27dfa895d4c2a58820798a7b0bcc096b2f591a4c53bff56b054f059e21330c308a2ab9e403e5b6b7ec7574640812464710b508043ffc3b5d2092ac45b39d0c743ef1873286a6779c15669b854549a156b77d42da9cb39b868c70a037d9737746b6f1b91733c41c610977a5f66b98a167d9a15e4f8750ebf00876783bf23b9e023793b6c54ad3a3c2d33ab3eb0a2a7ccb9cf3f187bd8b358564bd9948810f91b9dc426588c51432c83a4d704677f2918f6670e611a410014838e9be4c12415cd64ca1ab5dc5f81ee8610adc6c29f5da8224093d350aa4b7988303411b1a55a240ab4ad7900a4f3718a58901371623dfcb7515db485d1736068a1549714402649b1cc322ed093eec5022113384b8e40ebd9ab8654393c013c99380be30e16d565170d2f20d12859e795c2eb28c8900910e3b294302d420193b540f826b48663f726304cc936fddfa8fec5304d2100c45d3a0b9308fd032b535780dd6fb7649410867e610dafc425202316718ab0104552393084ce56e2a36a5eac1b0cd9899e3fc2816f94b59cb76c22742f736afd60b9615130caae76f905cbc1414c8274b11b713cd049803796a8ba121a95e946be67418a205759a3a285aa69ff254bc2b39ae75021227c6c48a377f9e2267b3725666e6480920949c413a1e805a52f159fd216938d0ac4743ba060b7fd8ac2071c7022c66680d80af15736c5a3500826c1448e601058ba38c278df84a6e65357adf6735f114bc17011eb9bc48698893acb932bf6aa9d9f845de9c4e4d4a1c93a1c9bce1023181746b7559ba6370fef77671769cbb53b2d6f123cb800f26ca8b6dabc7c24560d29561d8c0581391329e73209551ba29a579cf40c6bf792b0801b1d24204c20139cac32beac739e2269440c02990568ef2a9cdd3756923a100d97c42d45b71b0432176238c8c69af81755b194a2aedd65c1c4118a320c4ac672e78ba69fd80828b7094227bcbade5536f95b440fc9b953b4e0729bd185ca617560546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4b503f8ec36d39fc7b4b8ada1cbb933b9db9ee118bf081ed75dd5dba7590f6c8cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = 674ac342e1ab9008ecab115b7d3f1e4038762a8b454c6c50e1a38b996005113d6e860beb5e26e9b5a26f588ecc4b4413be6f713a1ddcbb503eb2df7fd53c02840199651d55647ceedd1fef4d011065bf9e015b12ad88498b17af47f46013de7f54a24114909119c0a50b9a03b947dc88ff948dc0bea2c9d68f1f63380697d8ecc0f77362055566f20fde0f9f45e2c026aff1603d3ce51394d5b35248a542f2134d222cc152a363c1f23f74e47b4d99c5ebe5119f0d1577f870d2130931c78a0fa81fb2b6d30c79bc0e00feed1a785ad2b6a00dee79a0563cdb0ee084bb016ed5160a0ea71384b4984a184d842aa6d11125ed10036d2773bcb97cf16013e31f1c86faf5e02ebebd6a7e8ed2aee8a48acfaf0f3712145f33884e78060515523c4a36919c97885810c6914c531a81e5050b3c00aaac6257c340efbd2bc6faceb77187ed1f3618fd868d790ac779f7774238ccda3d29831dcbbd07c99511a4b6c684fd295739a1095949ebfc335c871990ca1f080cb433e73e650f5e35e2f1dd3d6d82474a19472d0a356d7e896823fb396d3690d73136148117f80a335113c39f1896ff38a5f9ec7c177e4d0a65ea69d43d1ba4c39b07a27653925953a187ac65bee722136d9a8b2bc5c5eb9fcdfbbca6004f1a24d83bf5209adcf0d058557188d862908001e90037d1f5c56b695159ed833a4ef1b094194027a00e4b5ac9499c740c3091e39e710828345581e2184f6da0e037a3fbfc47fcb5bd19ff9869aa6989fdcbdb1af2f88e81a8e0ffd2c9ce75bf1dec0f3a04a2ec61cd302530f30b055aa6d3894d7e65012c4a80c65ab856a6205914da7aaeb14b045afdf9c100cb3e17442381f73a6bc78fec09e69730f6d9538b617ee64408b446aeef30b39a33249d8262affb1f8ab4e914423b0bf2740331eaad94330b0334110f6e55695795c55df52a44610e2c45cd7e55cc55209752dd929bcef57c2380759747a500c0d2fdf9ce9090ce30a8b73567bd05e730f624d16cee1172ee80ecb299f35946190cfbfc6ab2d5dadb90e61035f03b50e3e77750f87ff88caf8759b5c03492b1d12a2b36059d50bc8a410d1793ac223f497b0a389078a43e9ab37ceb8859617b62635d037f05992a026b438bf21739d6a28157fb401272cded6682786b6e7d13753158aeb2461cfbcb5f164d5585f167a438aa18a3a1197665fc3e0ded017c96a05ec20c6646ef7784ab63a3bb699a55df6a29e9e7c7ae8c98b143d547b9684ac2045d4c6e40d39d0cc53e96654f44e1f9bf0054b5f9b7e61ba26fbef4f6aad23079ea348b8bc73153fbe9a5107024c2aa2bb8cabc255347b02111674a5d652a0fd98ba53c5d779edf04e16d78965b63a5c9350d26bc9521d6b5d83e8ca4cb589e4a569ca2f8496e40fd706b804e5787d7727e6de44ece54717870538175ad1baf32bc91d586de5270c68bc7ea3860654dc25036abfd40d2c752d9ea5f230adc4484e85fa6b8eff4623e7c9c1e5f9a2f7bdab3f26a410938515e1e77e7a889471c4cce8acec08cab2c6011e15c3e8cb18ab975c140a68f6dee94d06cbc632b4e548cbc074b4b3ae9a6bce86b2445e474090005143c773f15f018a6485e9e78cd328565fe23b438d978f49762094cb4da91ad0660c6d6a3aba3ca4ba134c165c23b50c72735b714c9cea13f03d85c237d295367cd6b545f2276191548457eaf5b118e4cf90086dab9297259b9fc02e53eaefd1a9d442d1498595ec00e4e8d3f76965c0c4cabbd3e37b196c7991c7bd3676f8d4b146e08299f94189b57d095e819d3070da10366042e12c169538beb1b7e64dc542d7dca602d12949df421923dcd764d4d1ba9c5e077e6cc9be88e9211bbcffe2bfc8a91a5492c590c22617b8e9a7c5b34c2b2dd65eb8c713e5b2913a6794e479d86af019abac8f933b189843add7d24b2b1e904f0ebf789cd694fd38dab5c39d71afb783e6b8556f402696221aef748df46f17baedb58bba11413a42f93c417c76fcdef3be20cffc91bf991302c07259b4f6be4707a44dd7582aadaf6245648629a7c31c9d3f39c73b3f498d49229164dfcafa8086f1eb3d3f383343de6d0a6e82fc20c6d6a1bc4e489427829b83241e9f3a02382fcec52fbe610ae89089ccd4065e1112c8acd41802bb80019e9f4465877efc5e13a22bb08df929013cbef970cff94b4b1c479d162383a37e1cadb1fec00 +expected_result = pass +expected_shared_secret = d790ec546719fb05125841bda9dd361e162ca4241e2b489a0f948b612309b649 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +private_key = a32b081d2579d7737a984126b05465963ac3d0fc3d471b94e30b242699ae3ee7a305d187d9371af3568d7bbabdc30ca69be166aaa07c67799dce7345b2024ee41c5a6f35733cd12efa19256ddb74440829c6b52aaa25b258bac8d950ccdea410535bb3a44a46ebc44f5772cdad96596980c32a14916cf5c4a2fa8538491f7eea270543abc467344ff098edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca0165528241b4bc173bf17b4e7873a5081016a1c55e4bb1e7f71b849274d03e05e866656c126485979ce9660afdf3622e3051f76d02243e660a5a78c663880a7f9765df45410926a86acc7962878b4037cf2960b06f072367b476eb24b8c57924a9c699815bbeb0bb10b2a88b0c63f0171c759d59cea91c5c043a41a8155e462325893685f18c5458a0ac3e5bf2c696c8f07727c090e1d3502d075a706551c54a00a710027c52cbd83fb9dbd7567aca2b6eb809c00838e56b209e0c5aad2e6235e2c157d3659d906452f4a8c60b26f838a51f6789e42c00580e4595a5c0a12b796cb44240a4724c298abff1332bb0970a3ec475a434ec4dc2a4aa92c42e22035a4499c66827c882b542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0bc0a0c3b86788459b659a539833629c1b585a13134d766c9e8003282683aac1486a934edd3a7511319a7952b5eb7c5947b69ab5c904b2481a7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0e982a24d344ee8a22221a02c6538154217c453ac0ecd4bb1f820baab94d920765c4ac15972aa79ba974f3b5055efa7fe5bcb454f7ae70e1c017322a20c73ebf278054060687c6301e13b52952459c56bc8d8795044302fc9123921143ec2c73278939826682126b65c7d9bac044ae6cc7ca40f92c8ff28470e41d51895adb53ae30216b1aba552fcc14ab277a872029f3dc8d56794d842ba06770808f1c097787973b0a14280c5fbcc45c102c23821a07eea6c3abb4b52ae116f4b38e4a50cfb849177766495463197bca3197b53ab72b172c163003c9ab89721eff925f56b59373f5abd1430b0731419a12ba80641628d78d712bbb74579c0a18a4cb2aa6edd76fd7605fbf8214a00aa44e486810f3ac6e36345431c23f247f251112cb8a6c76444b1a5277b7c68afd2c49d4a81fc5069b9a004cdf0587a4a193d243bc5f16357e1b1f280706b4c16f9d8b3b6a5815a1597c49076589d5303a5c89ad320cf6042f2f819cdff04b850870e807b4f2b6bf99aa8f3fd16e95b3bedf247cdbdab048586116db7a4530c360bb240fb2964fd41a5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e8461cbe906e93b209742c0abec1c1bba9baa05a8fd05637d26548f48512f5477b93d0bd54f6674158b2f6ea0488191eb023a641b175cc689a2f326214793228138d6da03bfe4466dc962fd2a7c57102cf3f96cf3a6619d2f613ca063a35f4515c0473140b8ec3c53b1d9974021616bca2459bc31502daafc861990c1b97ea1ab5ae018ead781a67a075cc4924f9ea364bec33ed167637f0a643c3a810914a49366af69b3cc25938e77422832b7078c6be562513ee3648758515e3c04f27eb5cf0c73efce032cf027c7d6916072b6984452cdcdcc5b6293cb98111e13040548c5c4ecb4ea83c01580887eba79f0d700ce25274f4612cdb8427fe9377b7aaa517f12d2766834314263e27086fb8969a38157d9a02da83772691184df5117aabb901899e0e78a42c335b7eabaa462852423748916b9261e834320cb8e8576988321aba321348e68a424183e010bef6f0844b8c7164fc967feb02c76000b372a1547c88c7402347326cb43712be145e1854649b07aed70b798e845f7c4c5b0457ba58a370a9758940053476750c5168494bd733ef0c6c3a06117aa53db762440969a1939539f85c1145307526db7f43ea595833a7a49abe0d3446f2345fb429c4adc43b2bb17bac8c6259f2551b3c28ae1b57fa49889aa6a2503a9017f832666610fc24a4a8657475d3a329d31a793a6a4024330f0b6d7fc2250e6575d8a8947fc30d431cc24417a6ed4bc131b253af142f2ca88fd0c9a44f811103b064759cce44e02cbb062458502b71b9083d097f926a0da50b6914fc70e0858644253fdd9521e55c85d1ab71750942bae014469040333767dbe4ac80e4b3d6751f27fbb0eb0418406111c9e77c39977315526bbe1c8e06150a0384ca618001b08554c472464ae8b4b9eb679a790bf0e311ffc20b9a28a2edd52c4cb51bb739712419a116b1c0de65217ac429b091bbf94cc9e24886ffb623889028490976074888ca731ae4f9a9e0e4099f149372390bd2b78516044067201da469c7950bc9c681423b9a45b579160430add2b34d3dec2ce84270fbc019847c017d098bc4224bc9c99ecef95947e358f0f85def6837c5361fce2145faeca7ade0a612138c8cb26bfb534c2087c8dba4ce1f841e704652a093af188c55ab221123540a1007190453163a573d166617f452b9b2c7b9638b0201292dcfca46f4b9c95c1c8a47f44c19380a061b51942636c3bc8950f01186878004db1eb6a3b2ad5410c3484aea11a8d38881de278124c4c2b592b61bd87aef623de1b5b8b2d016a2d985976062758849362b2631a8a08404651305484a3b2dabda9982566822002ba1e83ba8b04c7be77d4086207e5b8310fc28812584129a4c03e938e950cfd43c3023a8774b42c9338ba497e853ba684c24aa03ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc659656715d0ffb8287b86cc0964d3e1b77e7d83afa733789709714eacd47b8bede99aaba2480002c0fb9136e397790bce939086ba75467340780cc31491e82172803a57129b3cfa3957bb70b114cfa99568428c540b187b98da9eaa20f3a7771d80146ac21b8908260c2cf79383031fb99ced3be7c86168549b8e2d2474e96bfe28158d91a16d5230b2f7b27d645c3b2096659a60c78a602457b0ef8553bff9508175b5e10e08326139aef678703d39693215d5d821811bb0868e483c646a4dbf0958978352b919c1354071c42bd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa3572bda92c2f9872bd19276cf66c31ac6cfed109bb36b77378c5d9a747637f1950cf36c5b22130eb018b607b74a270e0b733f12e426a2eb02fd3713f72c682d87cb6752a6a3037816b9a1278151c662529b54c52655b76c534e09cba4ccdb85289528b8f0201081cb05066515a3cfcca9031f386d6f4a411df397e526b754a0cfbdcc7968a03ffc7349f32036aa4b15123a6ce8d47f87516c717651d56cc7e2147cff3261ec76c045a32beb047760295e79f8c501c46b099bb7b508cbba9b099f612e595b41d32a946e0bcf26a0c5664b70971853b7965725d52bb371a03f456be855aa495a2e3d9925f6a7c3b98695b5e179e64c17410bacf2035e4fd3b938c98db2526804c79322230ba8455dbefa40caaba9757380944193063335b6721225f40702ebc418022fc2590d00f918765ac41cc6b40d39b45291af80f721069c7f73096b7b0a202749c70ce672f246209c637375e75a1ec03102940e8c17566b7c2ad43167f48a56c55c6b38d289d5675b9b224b7155905c814e175052a7e67685392448003d8e2815ba9810d8930051b615558cacd704202ad50f52890500e8be5cdc91ddfcb61948788a9cc2167a0021566a863b875361153b1a57e0c62f8cb11d3b3840f570b922e4a88151aec22baaf7559f724549b892575430383473b9183214104006dbfa356e2c31ba283f778776b43530a857c8126780e29c0316c64ddb1a947d747a8ed831135a8146936090fb59192b32b50327218125814b2863f2473b708338390ac2e507715136c8786fdcd1c10e2b0d63d2ceb6a4b0d8db6f8af354bdd1bfc6c71afb627686761d97b761fc0aca584539117ca416078c784972f67caadfe67f38eb1996e749e2f11a3c47c389d5c3f1f52d33f14a094cce5557154001ae2d17a2896ab4d0744e9dd4bbdedabf34d38c1c81812a3cbe4a065a0d6ca0cf3a9f5ff0268162a5b3d872b6782cab9149c52c2726079396b01866e00a20bc82208009f625323df535f1658a1ea29b933368992a89efa0ba586381d845099c35a299a467cce67af2d5b066d9891462114569a2261acf20cb64cf3819d0e0a4c20a153cfb5efc9c45501aa26adc5b26553b520a04c4388d665b098fe52b5aec48154a2ab5053279256ba4e6975f4764c77a5fac85275fec08d62534353b17764177037bae5f010266767164b307d4d375c85549edd3261c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f503341657b159925cedc8967872a45a3c1f0122979af87a878a2019b3f17c8ba67f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = 2555f9bc4a695e0925a3689286aecff9dd94a6d9d5f865cdb52f33218b314f382a4b99b7b49b941bee78f844e1e55f28397a25dc7524209030e4e6946f3529c89eefe3f6bbf9614cc6ce16c49a79120e9e22742e814738fb25832919de2fd8f5b3afca0df5a96e78ebec279941f1729223e9bbe0bb67e1e3d7a6f64e63029f3ff8e90d6581981f6546cb9e3aaf49ab04c25fde5db04ad5436bf6b06409e735a87c9b002c69a03bd65536c9e8c88b68db3f6d8cb706d97dfed7851885d081ee8e069734065f2b8f796bcd814c3fa751eb3d781bfd5cdceedc12519fc1881f655208b315cd69f1b0066ee51f90c61d86ac47112793834de1ccd2bde5f6bd561855b59de7e0ab44823fa6890641d3408b723ee6be06c800dc55a710b3e9e45c6b9d29e6a6920d588bfda65754d1cf71ab87892319a196e7bbb531830a5d9f7ef3c625b8f5c64eefcadcc5bcba8d6f143832ed55214e717fe58132e412b5baa0f663982d6a01372938d24394e6c3e6ffc2b3c7bd61b76934871707cf1dbc128da0b47a80bd48fe193226e6e6d72a6a48eed3c0414a9c3ca00f7862bd802f035a60d90e29962f9faf780e2e4c110a42e7b94c1fd6d9e95edeb6e5434f473a695f211016c25dfcce088844eac0acefde73482b8a979550e4a050ec096d5e309489333bf4e618a198bcd6988578638b9dae6d996842bb42b1f34cbc398dec9ee4584169aac8929efe472abb1dd6cd6d6e69f17e7a9fea7370db9574b2e008d65392d79197e6b8e7c073b75c6621828b9166888bd4073f2ae59e0db24654695633329d4115a00e0a5549afb82ca19b2d013d83330b510451d76aca0a9eb51e7a9ace34f732cb128167d0d677b0b93e6551233969a08fc1799d68908a05b10494a2e98d783aedff4e6c32be3a5c83a04b0f751308015494d2fe5ce2d555a6399254eb53bcbc07b444e647fd3a1b89b9648d9c8fb64feaf0df3cc5c3ac3b6c5a7aedb1890e5882b20f3ed54d79e072b957a3802b2637d0841f88e6cb82145495e80a76557d938acb35087d2845a3d21be902da3f4fb184428f723b0655bc530f9356cb1ee3486c25ed268a0ac20514b6af2a62b8b6d045d329791523c6c2a7825feb97adbac629b2e94fe92941faa3593b809febd42906d109a6904441f56ec7f7cdce7f8aeeac3efad95ebb1336f656d0ced4e2acd737c27b3190d2a872ce59511cfa22d001b19267d727b91a43e8523e8c9b277566e03b2876da5c1177127bd1968dfff5b42ad817b1555dc5b8f4dbfc43e6abc775982cccf8421fe2dfa4f04153f5e7a34556946274a786a57f80a41180e7de70c2717f81715593b2492047407e2cea8e16bc32d2ca6038dcd78133c0cc6a3a339876deae7e4e48ce6f3adf352dfd415028e4048ddfc8fcaf745d8bede397691a4561952d990709af7ad591b9ed819b9a62af7d53a19bbf6cbb9bf2ec59ba49ca9d62b618f39884a7f9d20018157ffed0b41d1ad5416b929721daecec07031d7d65be2ebf4c06e9ff66c25ba99014d87db604600a6ecf113849929c442191421f388ebd1fbd5b8a3ce2d5df4e06a9a1df07dbb6ea4564980aa9c642019736ff5e290790d1ed79acfbc9b57c0bd5301e0e7a65378cab5e7ed6b74d8ce680f32592fa19ce77b38d7b02a90aaa0420f28164ba5b88d5a331487d02b9329dce23120a7cb93933d1cd7760bf581f036e2898ed25f2f441b7b81ab09d921f7f8b86a3611cd4f30cd5e505f85325ff8c14561d5f13ebbcfb6d6559726488aad10b15d3473193f7fee98f121e4a957dec525de7713af418cf578218ae8f57c655626b737930de46d83ca55dcd8fb7ef1972b3168f153a16ded056cb6d24b9d3e2eb37ee9185d5b3e407fc38f35e72c71ea407959bafb783465810ed4042b678becb92dedba9b78435dc4b3d575093796fbcfb6905a68be1f8cbe8f112158c9ec77a44b33ecc9d34550cf642e3110ff7943dba9491ecb7539972b91b092fdb1de8e96fa3d6200bffb3964c969e655251f90c4fe3cc247de08b8188031458e0a02f4795531700f8e40c895f8be3baf309e8a80b67b5ff081ce03eba0ba8d30a283429f94dc650f0b78a7b782fae499d12bf848bc2414f981d68594f82cc28d1ab3b9b0e4ec42485fe190fda4d9c019dd66e8c8f303bf9ced811db77a5ca20e8d323d76800325f8fe1251260bb1590d7882fe3e397d1 +expected_result = pass +expected_shared_secret = 10086d1a59c41f84a089c239fcd8f8eea3b22c7796f9c1f9b1867b709cb77704 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +private_key = d1f46e67cc5aea63ca9ec413938661c2f8156cc79e10a64174774545b597e91a8cadb58deb15b27f343073b071873870bf858b5fa3ac3689698deb68c570406972210c2b9909571a12753448e00e6a0c165a101469828e8f60a16b55478c8899d9a38c1751bf220a60a999b0d2a429b375137db8bc9b85ad5fcc073355ae630100f8fc68ebb8534135590ce22d0a0672ab54936c8665aaf476b50293a32135283777c375767b04547501a53b72a14d3c4de4e001d16b2b2b598a22d784a3711c39db183ac82cf895b242954b41c713bf464464917d6b608d21b67b3519a6df161ad237359e262b95c6be3a8522b9248346785fd0db03cd083a21092f4d91af156b12f4c9c77c11cc0b68adbdb813beb21289743758f8136661704d0c5ca9302a064040334017d47815b7c35363f5c730298670536c69c122cc91cdfd18783efc4c39c8c29cb1023f1488a7469f1cfc1d7ebb3d1ceaadba3b07310000bd89c043290abed896e655cb1f43a1c7335aee30044d9652e6d3b8e394218f63072c7050a2984032c45735a3aaa4108aed8b9a19c13b9bac28ccb123d9987c45b91e89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1aa415df9961a4785337535869fb758cd04b798907e36197ea428c66aa516f602404e87341e154a0e09c881725cbf00761fd9645b658d97d21f33059e4a898deb0c826d9057ac302663897d71567117fc4416c860775b026e51a52663711868777d542f1224b277ec005f2bbcfc0c84146591cb36caba82692b010de229797cac57aeb64af446a896527bed9b3e55539c0f6a0e9eca5953890b95b0b282c3a4c46a44a8705a54a8806ccc0d3c736a20d34aab118813651d85f12906958933d69679d0457a4817dc83b525ccc63e94c1bcb1c869cb3a0bc46d47084481c2563754aa8f44682b870ed04996cb8886f43b91ac8767ae12856ce5b85f55c8802830ba1babf5797d0da723eec24616a195ac809371d93f89b19c874c840ee9c39e7370ca561b6e91552cea47f1d09c9cf633e7cabc9ef85f89d01a29d9cfca8143bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a82322793906462c03c20969f76c2c8c8ea2622a373c3e40164a77055ebae05787965b60a861c09658c32d4194dccd7ab1df87826590890b1785f0385b965b5ab3b870a0088696a783b5c7a69962b86f789bd43588705315258c117c4313198af42e2b7fe39894a86189ffc4e8c6bac5e7a0f03d86d18089a6999972f309a6debb365781f64197165d259bda98c7a920a9e790bddc587e7c08040d649b8b08fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5152b049850857308ba1310283a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd7712686200d451cafe599ab0d3a183d2b0df7b8fbf0995042ba0ce682eba8b71dc6c0744262c75b7638b51b9c4931d4f7c842328486a799d06027cd5cc75e4b1b6816c2ad66b86ed047ef978184bd344c00aa1200432c5d142246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375060282b7da42ecd36295fa55f8b5ce94b812bc421b47054469d39e3483a63583ac5a97cd63312e776902b73c34d5d81a35153589fb6d7590c0f9b4996f83cd4631a7fb6c09f60a0faf7c5d24f9983d9cb9b19566f1eb6800024fdf032c4032c778d74846f4c7b63a3effaa5ab619ad3c62680f5290adb5063f0137f0ca7b694978c622a9a34bae292719a7f9cb67033c0de773359aac3577ba38446a5610acb9d48509413b1cb024cd25a4a5a882ac31cacec34c25fa073bd38a8356934423a838415355680bc7155d433b4357ecc6221ba804602317c7703aecc7fdb30781a715849186f126619fe78f610420d2bb3adeb085753a710aa07ba2139c0897a172dc09e7235bbd0638d8c695dba8baa8b04f7a058edac52622b4a9638155d56448a3977786941ae23c6dbd05c4fe466412f29c74eba96921612edc0bd5d12e72e944e5105843034d9070416b649491c7b4245c14cc152107bc68b6078b76cc61a6b371e95202292584a1734f3c4214c2371b8168c6eb9c7e7efa76432316d140aa9055577d874a7ad70d16a3783f7904f3445e7d81260ba19153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d3c11f376b1f1cd8776b6280cfb52559b6b3bf4716e9b49997911bf8da16c4147a2cc9bb379ac5195a320783213f62156c127257a469a428834d384b1ed48a8a576b240c1c55b84d61e248df45a52199143fb141b39c29631216a32b8dfb876df873456c14178c4360b8215c71e219c08c915a9ac02304c958c1bf7e65b3742bac539059eec85fb6cb608975b401c83b490094a6d1714876727ea34cd27b7385d7575ff49931820fd5dc33f3881554c25dc41a65834115e1c899ef8a080fc6c53b81b3804508fe4c1fe6904960d96f8c1576614474c9191c99fa3a201a4143b09ae0f3432bd13a3442ce80ec3ca3c94bf2b45fc398165318bd8d2683148315d1969b70840af5b42d5779c844c48cfc0488ec65b414837a965c65902c21a2c48a590ccf9fb9c6f9e45913aa0577d2acbbb29b5357cbb6b16fe6ba9abae44645ca68573b5fe325670f2c4b5378c040171ec3a25229b1c3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3e80fedd62beeec1abd53a45a7c33ed4117f415b77a43a0d7ba4ae2031e3c57c945b9abc3b5b3b7915784eace07e7caacf256cd27b28c2924b01302c9432e5f3a2a75009d03e36fcf7089fce58ce57492443323ab494c07146db2ab8e3263955eb373031c22da591ec5cc3ce0155f69fc43c8484a9e332e2dd433a888190b05747e0971005b8026409ab874cd65f533a51a40a668900ec109de60749250890ce91290a43078e3ac85502b4f34518886578c26353a6577fc51510ddcbf4ffb6b501662dfd1001d6354b47b0528dbbc0d6a18b58c605a91957c27ba354232751810202a891aa83efae7957ac2883605375778369589597a8b4f23f325acd8683c4b1dc3103002e1c588039e08a7c3c92137510391b3f75b99810f5c932a80a7b5d8164d999c131828a59a939d90a8caed47c205681973a38074243a787866588399a199c8bd74c8b6546168e255ca13b23d0775eeb727e3cac8b4305893185517274c4a4abbed709f2b986bc02592d1dc38cde048e5f63f15086f11031348a7a68e044cbe1075f1eac3c330477fa5124c832c2c880e29da691007a82b79611ee04b64280e51d201aea5b00a633e59dc0c20d72742a925d4cb19661ca864bb79a029c7100911dcda5fa1b36392d3432c187ddc51190c563d4c180dc87976a142962023301acc29ab63853813185b6390fd84b7d395514bea0b35b22d9dc19277ab7d0d602725a9ca3af87df9f96db8bc6a3f27891f9283bd6a4c4966cd26d3c96c2b4d808a2cd435abe4173ead728a200a43f8e21907020d6c19293eb02785571a399a81b8205485c54ac19bb298c8941dc06ed7796a39ea2c84d755a0e90b53f86ebff130c6008f2dd69af0017bee0c6e13a0bb2bd73b02431bd211a5fffab76f96c080482055837a6295209cb2a62505b846005ca5a482709411b5b94bc3781a557b2efd85b575621cab87aaad6844034c4a1ddb43d70687d968bfce441e7054a9c9905c114b9791e65bb23aa0cf22ad7e005bcb38b24deb2e7741853ee7085a93250ef7624be270bedca3d322842b477a507c3ddfe3325d893cfc432f07c15a1422128b5703d92812b87915e86a8f8de97f163caf5f695ef9994ac4d7932fb9629de72a988194ba13c996c2252968708e6468687b1a91063de718331027a54aea679861b1b6b6930f8947af72a1b30895f225a7bbf7cd7e8a857b6216115c8e98689b89c7686d282c44407c44eb64d3795d51665bd538c33a7915b5f7773ff20b6d289d2425a2ea4a14e8e2a349a78c76f8760082a1f8315b4dc41109a05c6053484a1b381cd8412df92ebed7c489ea3db9915a23e07c37f7c805e448a5f08a89a860b96c4bc7a10d4c30522cc900291a8504e72f4ca5229135827626c138173f73f123fe013f3612a27df9965dd78c6f1a2c3577c7cf866e70190c8a249a6ac6c1eb45ab61f9a021470135292d6ba6c26455cf0876c9633b4afc24779c908b5619ce1df7464e096aefe51b5f43be40b556e2c5c41503857f8a6b4adb2a5d8a67cb668930889d68295736027b5b1a4b3cf44a05101f1bd4b365b8c54117c6027460e14ba516724361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa098560c001172c4734a620c248654c58f1c10135657083de776116a6acf8a55f3610d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = 05d9eb9cf3edf93f6793bf5ed101bd3980b34678bf212b1cc444f2f0ac437e62c732b29deefdb3e75279d2e90deb57912831648792e7a4cc586a44e48005c8f1a0146d7b7f21300950c11d4162b9a20d21ddf22a795885f8e511d62c8337321d9a9b4c3c90196dca3342241f6a8622df9b138daf7fdce9bc9e795474e1f0fce08df25b7e88e1530f0b0ed1d5dee54ff93088355b32eba417101febc633c17aaa5d5e121ebe634834e64cecb4ea34cefb21ec8ef095af4d0afbfedd1eee96c9bac511d2ba607eb82fa5086dcace03a92bd84ac9c135edcaf68c935063c2d23f70a1bbd3a7095b4bb9389b74aab81a9ef4f48ef33ee5a6c0b6c94a52e6d8c2abdba8edd93017f9074fa6a9eed1993e34670bc0a5571adb497a80b48559f2d535c9072661c6ef2aa1620d93e00b9a75032b6585441d872ab950424f251ee65bd56803a71f8a167b9111498e2e936f1cd460e6b6cefa57a409210af828454c35199d3e307661ca760f5fa366a9d9307c9106ae358f7a3d52c23892b2a9b30c284a62615aa47ae6112c7ad6b630af9cf039e128223037c73f4e26e82a0fe4471ca332426709210b2a6d30ec5257bd86d8c80b2ec71a4e1801a63815528d6bd4c145c9c860b7daf7e0545be68efceb423de334b4dec869124844cfd94769d112bd6ce527b178d6d26a454cc2feeb128a38b94e217305ed5f93979728fd7168c8d1102cba2cb9d864666d109b649cb41bd04546023bfb87ea825bd6120d800156bcdd2c163c24258241a64cc4953a53cbeb8c2ee92195897e16af995172f743ffbf05664e60f22fa48f86fc7f33876c883c1d19f097f7693f0f1e3031789e400d6a6a93770b0aa343ad104d24907f5a6f508922433222321c0a2d2ca88acc24bea23cb290228ab6ca8be81576cec9fc80572d3dff7b714ac0996333d052787b73e3bde6e78afa3327b4049b0ffb31686456dc7875efe63dd7f2c64d4ad8795bc993630ad0cfcbd976e4e2d7d7d22f09127f4c5fc60b52907076be9f88efa8337124ce0ed05923f557b3221d288b71c8c201735661d19856bc973ea273a3e7f1079c604c91352251c512dfef663503b6b43f3d6ede5126306acd88ea27e288f8826e14b5a77804d36712d0fe3ba38ddbc6d3afb0b40e0a9a493ff38bb105c33d73359625db2443e7d8f50823998b5428ad14f67a509127e7b89b7703baaf17e581d293c0140ab760431a1a4826a673b5c70bc6bf030ddbc47b6c05f9888d3bf72e866ea07f97739ddf24d855d7a1742d42ec23c3fdbf646f3f6d1bdce61e5fb6d117acec891e03a4f7949e04f1175635511a35e718a7eb65df43307318607b7da11f0cf493ea7052ce585457c1700855faa2a5ce5f0e7fe0babe6f8183989ffc81d28026904d6dafa5a8f21f438e707871efc796daab9ec2a5f5f5e00480798d9d0461ea51a11dc6cbd88c2a0c0dde6fa97641b7f7c6b6f7562ef6a0f01f32cc1ac9e6ca352394ea1b38500c2d5e4e62a929789d6f061c2c0ce579ec0d5a3639af83b26499057a1a94f47acad835443ca6544fe9986059b96bd646403a504bc5dd1d09087ea76f49ae005333ec1231406c79077c1d33dfcc5b2c9ca0d0cedeee31fbdb4a63d7a3229a720567dc99560c33ed3296d00ae19bd736af5194923700d8e23a64480ea385373931f4504411f94028fcf177b203cf2fb32cd1a2822f37e1dc139dc985c93c4c4690545e51dc01edb733ac4148bebfbdbf3764eea61cf3925952f9a43bc4a4b342be1fde9118d935f88c8a1bf843e759a04a0c6cfe1c4518bf12849ddfbaafc94e7692c7ecac9348edb99a5ebd3006e97eff99dbb6b51579294fb03cbb2d8a50fe233724c00dc00d29e001da7b0aacd73fed9380d73453d929c6781869dcd13bf616d34940fed90fd493cff48bc7d1a07a70632a8aa7c5f65b12e8149e845ed3b62f6fd5c23ca8de0b7f2b02e1f12bfbb039c90eb202f1d624ffd94389e9e6f4665d4b1e7d3652645e06060d140c3c92e2768b82c137e1ee0ffe88699774546d38a4060fe455a564cf4575ffd6900de3c839e33500f6cc9b91982fc21d5ee24edc6b17b4d3ccbd6974a05e646d9e61e9417f6e37a00b917f08fc49f235cd2eef6b2d3b48baf58ac63d12000e9a3e518791b16a7c1140846ef8c79595c5b81b8a06d12338d9416499bf5870f5e4d8126499ad46c5bbdb29bfd34865 +expected_result = pass +expected_shared_secret = 82ad68065774eabcd6e78c027286ca7c7120987c4984e56f52abeb1ccc7a273b + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +private_key = 09d0009aa9878c697e2eac9cec9675a9570660346547d7aa8d4548e3aa917e238cbbc10c389445d15714b237566cb44132d6983c9610e779570b74482d5ba2742a1bb51c68142c1680b800f1938795367b6d8a56c32a0d77922c78116643530aac01cfb2692f4bd6bbde615a3335b397487db8a1175a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988766114a80b1979118eca08217540f032966688c99feaba06d0a0a1e701deaacbcff9c2f2948a209ac8ee505c85fe0444b5c70d067100b63cbd6d98f9aab73cb06c97ff31d7aa0ce188707ddc5c07d495b27957b369055650abd5d9b9f75761770920dd0b574a5841c3bbc9f6f1ab0179c118c7a83b2934e950b3dc732c84264c66fcb0df78975fcab5feaba4e6af97131696a0cda1cc9e2c40a266fbe6667c1abb361f063103311a792b95cc525ff872bf3f394ffb48b30b334ca02bb32a901e3478f811505da066de6a5caba425df83c27565ca48b16bb2855a797a72dfd57615d5117b24374c2d306473a349521a8107790d268ac6b5813c593cb9e8621f8c68fd2e8082c491c95c5ac74c86dd37b0a4ea0cb66aa576af50fbdb0a31235bdc9e8107f1859acd2674fc72c6669a3465556f90269cc30b0a8f53563378ee016a7abcb5460d5371b01754bd7373c2314e2a42d98636112f3cbe0638e513b38d4850afd6a1d3d485308181febd88b75f532e4541965e0bc592885fd1c1b3108c33f74725850617b526ad4f2c8cecc19b0a0ade15057c90ab086c26cb014bff92988903bafefa3c4c96ccbcef178f988a40d339db324257de69a119125c52a4147360b1274808299446ee768680170457acef18814559996fa96b418275e031199e0d578e86c946381c369ab839b1a75e9d6845c98aeca24253b3b0f00ec7e92cc6f6a40a4d8b04900ca3e78cc7a5c51886e0901a908bf0a08947e3b524f1c606b055451ab6eda2bbcf832510b3075e2cb0ecd493b71102f4ec69565f96651a3a2c3b738c2d55805798253e055dc8508b98822e6803785130d22e494b50025b0ccbc69667013c4ce4a140c2e9ba928d41d7fb5237da8c5ac0310ef5007b2b0c6737bc17a747c5a2c1f3c1166bc2b0ad7aaab1d870e54694c1ca293665286c4eaa35d34bd6ea7aacea04871c257cf63641264aaa0db4f65337274356f71d02310a57e44d23ec6b4185bc5cb45a65d3b592af3138216332060264a6e53702d766d0f4a0f14f70b75b780688591cc414283a59ad2f84d665354d71c2aaa1c278ab6c8ba902283b286f82761906c9b2796595bf5ac01455ed2b43607207a30c949afb1ba5c50659143c98237279003ca820b4b5963b0882a088ce09c99f4a6368971a7d6885237bce28580e2ec483fa305fffc0aca173a89cc41727a55d4e29a8c410b3fe851b3d58b58c31920759ada529da162cce47618b2f715f3658d71f5455365c67b04748b371a5a96b75f342cc4c031c713c04d2b6cdec0cc92b7596bf4a2a0c91537a0c8174b3456489d2db70d3af2995c4830245120e9411e92ecb2293700973386983a0c6591cd5eaa34d5cc00fd672d20a604e78696d5542646c120e02c8dc5162630e71465accbb47cc0ede06feca295830091000bb220cb2a41777647d6084c853cb69ab9ab97204b14b31bf4b1ac577a76110f5cd17dede14d095662b5d12c931b1404d3b0ade5b216e69fd480a9335abd312065e187a03891a4e9a91fd01a57a8e8a1ffa075d8e68152ca058a876e2bd80e46c22af8360e3734145ee882cfa06c22167f03e103aba731e7526033ba815d9c3775d311f5d92a31d552d89bb291663ace4b5916436e1086b46879950de89d453a666f0b514ac31efe398acc52370e27c0f681a97b0966a3a14b7e45bfbe688b5a1b40d9f515b688218ef95a9ab211ca429cdcd6a4913b2ed87c9f65d64681b9bed10c09c94b9c0d95c75b69721b119b95583eacc884a56ac09bd3bd6f197a0efb6659e89ba3a019ee12b8ef056a44f174f0219f89616330d2bee1580669396009895cf9991a49e7bb89719f6d340bf33c427fabb2a5c96d81c42e18a96470360d96279bad640bdb41a40aca9142275cae4b95da8acf98bca3456c574acc43d3d72a2c6542d1a25c554a8439d9565af29d8617a129d5526cbb30aa578643b133a0254d6e22c33ee80564e7424f0842b113636010c566eb59f9923a021b2a19c08bfae521e44324eb5bc9873846141ca7da45be4f8619b334a7cf52093b2177f4a71ae211081a096071f958277555709b2f459685ff22849a86375e157258d24563b8028a728c5eb0bef79495c1c53979880930539227c188c2027681236439085b41763d6378a4ea0254a7416473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c2716053bb54dbf1bc22f32e6d88c2a1947bb599a878b84f29021ead84a763eba7b9f3422466836bb6ad029543041115d638552cc2017a84ad4cf687daaba75b0c0a73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c2325a3ac19f9a5b0327b80f220b9122583f5d908cc21c97083227b568c47e58a2a7843d2141411b08f9cf61deb4a9edf41617fe26bf9c519d0cc80cd292585dc4ce5a90339216a6f876206732af6dac9b2720025b31e17ec47dff321b06107993a414f1509839886bc526f8051c4380c3faf4b64d7e3c9f9a76e9d440a67499322b37c4af9b26b2814a2b8b699ac0adcb25835d038b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53df10c578562a91b55ca04ae8530c6aba9c16cbb0684385704c15d302c1ad4857d0d1657dd85c536cc76f228641899188b9222f2b208d34222276a3c91628772c6245433a0ffd16b0812299283ac8d5a36b868b9fab4189aa64a0b90b606e695fa542b8c7c3ff0f0a46d5b00da78236d518d34756a2f32075480a4c15b7c27cc8e4a93180e6b5859120a24db2daec61a479cb039d4b9e6041e816c96862c2b1d616748444b4febcf7a129e6e7817950c77a3fac386fa787eba4157b720fc26629842a145759cc8fb652811a8a3cacc29571463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b304c0426ec26fdb17ca8fa5496d794778c49b4f74a58240bdd39c2fd6628011837451cc4389a43f3bb20959928b77394651e4c2cdc44cb9499def6b366d15550b41ac89707e57b271aad6113ef7a9b1575c69e35e4d75bcb0333e89c091603b7ea5973a277672a1c504cc2c45022906106b97d4fc01e98a876be91d88f4c908b892b5cab99fa878dd1b3b1688976c148bd0450216656028d9c2fcc3bddab2ce6541810cb84f4af414eeb863b7c7452bb79a96e790cca35bdf05b4c3b059801b2bee373da6a0c3df79c986e71a6788712fc50aea51044c2b82b3d201ac7a1245c96767f0cece2b4af175329a4973696c5deea91075a6b8ee2c347d15c89448cb48d22126d82732c1293288ac60bb3bc3ca1e208ba71054399fa4a5d1db7389379600c128b0ec1803b88de90369903799cf5ca0c5ea0b012b691b0a50b9011aa412509d1abf24e252e9d2cbb315361977770ed77310c1705e46b06a5c1c35fb5e5c9a8066d2750b388855e982bceab6b5e8018181b66717142cbc3729b13e2b34205fb06724ec13c3c2977e346e50a79498f94756069693989b77432f8b5ac8d2b06f2e227c4728288e91bcd6cac439b068e2017ce1c808c74098ec2c099d81b9dc6ab7e780c0c1669806e3cf34a1c1d5d002aa1c9301670fc4e45b64c59481d1cf6446468806683f57b3bc25b032aa40d2c188c5a2a7d47b41b4753d5f7a3b22bb70643942d6c35317f05e6acbb4f6794b1b0c3bd47893a7f9cbbb61c608068054b385a9578303111972e8888c6427afe099a1a07fb3879b821b25fd1699ad001f51b27acc5b2926ab2caeaa9341e1a627493f44f561eea57745a0764a840963024ff6c070ad95b285a74527fc3da894c06f7bb5de61a012547f87c1517b9aa5575a1ac9a30d858c912ba096cff4a24085c750aab463f8b956fb837ee300470452c6431d128b27472b5cbab268924acedeab3e7b02b2b201a44e99654910cdc8d5206496637e88929a1ba4436272f6b5ce41533450663f7a1a9144b5400d727fe6342c6cac6e2c3312015b571585303967422ed8c5d4b75e4f203bf2f86cf0370aa9324c47246a27d9076559c906ecbbecbb20e020cd9b6328857832ad8400666b943f8418f57408251b91ce341a2f63601dc751c0b301729caad8425f717250d5a249b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24647a136f20b22c63afd2b88d14fe7677cf5c2b78223a587068377021f6edfe9b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 09b1f5d93b3554c6875326ff48f961225be029df22af93494a7edbd421193783fc0383f36c53e1d66ad64a1a6c58a52d1bbaa59f537e552ff276b1d328957b9f8a8d4e48c7b25c6e96e80ff1219f44d2d65e88b0fc84ddc1413fb4f56c018cf479e1c87916cfa69125c5ee99827bdb6b6a1f7ac80dc50830adc747a4fd99eb2603129b04c94ef1e431a9298c414e5aa87bc32831ce7c575f5f86a4f90650b99130147aaf75fbf1814871c983fb8676bbeea5ecd14562fc4b202e5de7cabbe52d40f436af9ac5b568c2d43e222f6bf19e6318d713d7a18eaaa3ed4c7ce5bb551a77dcacb90b68b3092f4de8f186dcdd80f224d0b9bdc2f7b85b0adb755eb56be6437a6fd4acae76a1ad77d97fc88e685d2890eede3fc7173e4a691d922d0823ac842af1cecda68acdcef39a0899e6cb94bde18fe70d7e511923e252570be75c238212022f747f7602579cef67a6f6d3f3b183b8dbfb9bbb39dcb3ee6ae24f32917fee81477b92bd0d6f69d6e7c97b9c5f83030e8331be2280a8a0a4f296b08bc62eb2581e1e1bfa9d5392d2e9290a396fa998da07cef57f42cf866f8d7ffe951e67b7701baecc00eec0de205d90b3115bb31c1da493d02662fb33dcb65dcd680cb548433fe9e0a67ec0b352a903390d5c2742d306276fd8f6fc3ae32bd2496a3f0693f178a528ee1c2df6701425caa647d0e0651809ba3cccf3e6db5418b15d1b4daaca4f111b675bd5acb277ce5cf2d84c5a2aae8222805fdc618df58be7133b685fa6094f7fa7c3edaeb0b7686a18590a086b3e7ed03b64e339de49cd79dae5f92e7fce2e7d71b1de3869a99bfbce25bef3a0b6482a9f9c6da8d228989bcb5f1dfdaf2ec6395a0d8b8979425f5395b1af29c992cb4ccf566ba7c0afbffaacfda474eb47e198e684db188096151ff776bee71275912e2b278933479a94cd77d70cf48d3a822362f3a12bdb95822b7728e7f48ad0af5fe375614c6e3cfcaa095df949fac1d1fb23220426a830b3674e2a48ee4c675f4bbaf1318d2e1f1b39b526b31af3e5f2d66a2c6c15d097e41ea68bcc5ea6a8da0edfe3fc37e0dce13f19217f5a901daf60a436aca6447780786300400eb0c82330aac637d7166e912246ef9ffed4dd1f55dc682ced90e4ba9d4ee1ac273f02115c4159ff14ea315ba0a5ba3c0d2b485dc931fa029bd567b96a4ca62ce17e6fff9a996b1c8052b76df2efd9b637ec1cbda1270e9d46c545d8ae274c831eeddb441f1f8b1c8b4af28996eba72e0b0d3507da9a923a6039be36ef41531d126d8498f83d5bc1df879cbda4a73da1ecd71914635ab28ba4a6ec32d6bbcc0c5d86ebddfff550837d253b7bbd40a824b8c2634adb9c4ae412189149d00a3e77c6a95d09ff7885af4dfd15d2c78cd616bf156e06d9ddf26442a2dae42e24a0fbb868c483dc5c4e896c1a3540ac8aa66935f8738e27e01c62f3af2362d0c27be70fb53dc09c1099d87d33e0c483f6e99d62bb5e7c9a1d12b54a1833569aa229f2224d5e95306abb2219497476da6872942195be95e9b2e95c92fd3c2d30035cffacb7f343d73b4cea396c2dbece97f10917838be58801ca6b3baa721e6db1c0cd71fadda0990572d8fc5c97d2facd4b365d8bc8c3c6104631e269c261d0e48167fa5b6bf884e41a00f855eb35fd1b5f17b21dbdb8cd9ae8d1c501b67379102c53fec015f19e6556629f3f385c8403cccd84c7cdf1133c65605051cbe67593a79701d09d714509bddc1f71e0a9863f456c865e824e041d5c7e4e411584c87d5c82ff9f6906d908a223e023e760fae53adf4267b6241c15d957d309aece790eb523326799d659603958886fb0795dab13fb0cb0212b84cedecfe4ae88a6e3cc9a4b9d503994609aca48f60a124120296065a7de2dc4985793c24cf6a849e708ff44236e0c83d831fa4ac8fce9b25947f8432fb1da499cbaae74a9003443350970e31c17b5efd6f317016a6a7a07894e13b8cf136f3d0f711acec26023be6ab981f12efcfe77438ebc093887c2536fc8a383164e7baa329c129ccd1935c9c0ca4a2a6267ab01e7afac3ab47c106d7b610563a5d822920ab3d3437fab93f3ac3ff1dff13d84f955df9a71776c54f0a86530f67ef1f9f4c954d90d5fd7ce1fabbdc218529089b29c43f116257799679916dd03081f3c931ccb214b1f56004d115afe31c39be017ed6fe7d1b95feb8f6e7323 +expected_result = pass +expected_shared_secret = 2d56c88020d399532bada6516f9a1acc28a565cf252bafd40043879bcd6de1cd + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +private_key = 96d9c668915384c2847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef7f405c2911777fb1e2f44721be8cc326a80e524486a16a083527e22d51e4ef624b02625fd6a857bea2c0590a3a4e39f0e041b7284bcc501201842345ed5ceb097a5a5f730ee53176f8acbf9e03c6dc4a069718dd64c47e1d17323d29acc630db2da9922804802cc768070245380cec6672f6a5a9d14e4012bb13caf8c320a320ed63b0591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718a421d3c45bd0426a87589362e52953822cf785802b2c6aa441adaef93dc6451ac68a9867c9b9703abedcaa540146ba6dd8acf7dc317a82a4c1396267032fccb53be9306e20e4713b82842e03b7fa984e5827c441e293352b2e2a51566eaca8d9c4206000655f761729020f7ff9b230d6c4b986bc94551175a8acc7e2a2c174c500666d3cf021a9b40f1a465447291f920865ad16240309b5c838a2ddc5beb8aa11bf987aa9d7c082e8c55c63ab01d0664e545e505b4aae50606136b6b01499a5ba10174852224ac6bd242d5d21758c4342f9a02a3d46a9a845112adccbb73488cfe3055cac398b0245c467b94eb342e1845969d70511bc7100f886308cbf21c13840bc17626ac93dfcc4eb22ba18f62b15b521539901166598f25555c32587637a341017885af1a6d1841aa1c747d918253e1c873c2ccf292bad45805d8946b00dd23cbda03878f66357d175d67a1b743c1e5428ce90661067011874b062e9ac8a0f726b55b76627c53338549c3f2605840a11d5606acd104bfadcb51253af718835826628235878d6160f15033844d76ae946ae6c240053c2ad6c3a3d72e721d9565a6c79b56840cc5a878c6a4033bb9c88dc43b130348082e41c269cc0d3b05ffe356b5695bb01c95f8aa9c30e50cf31f11419e13acffc7192b75948e06a68458db80a8f71573b6edc1513aa5b060cb77b12c62761bc188159a49c95180249b3e35c3100635012637cb9cf17ca9936787aac954bcfc655aec8b4215861a7709f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61e6018ab30146d60a6563b2f980acf66186fee70a458750cc62c433e651f447ccef8a773bb2731a866832ae535f0d82e605371f6b35fd6fc1188a52080c609bdd8748c321ca37190321b286c849d35224bb5107d83e2827ef0c63859133852630b237247aa8c100678e43618289239ef19c99aa6b9156704643285bec89f0b0c21f3a091e2063e5d3029f52c33af97529e701298d3961f492e6b731d4e2064d034533f4611fefb64f1899ef563ad71a52e20b199f0d80c557cc8cedba3cd1746d3a6ac2e697637f08a43d681ece3769c8980c76a26adcc585eb1194d28ab163aba5563a5c7985720248662bbc21470022ef4110b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53a020928f7a55981b520017bc06b36d10a21433797c15124e0892a81230bd6bb4774d46f73b874602588d3f8966469194041bdee87ac54059458b19724949e7998ae8018755d491bffda76a70a64eff902a4281734a7484037c739b7bf71b658b779cf6370420d2073fb820bea1b1df29c3b12c54e6967a9faeb87bd8c0d3ffc2c1b821b42584b97a935fa04b81252ca53333bd2aa2b7f6220742b366f2877e793cd948b7c3135457e46ae107c6e74104159a82914a7059f25a2737c1ddc299add2b43a2f6c25381058476b01a14468ddb6767d18c1049c676e335eee0a23b2b14ddc7421999310396497c642e5f30003d18bc76dbacdd06bc73f12415bc3250dac8bdbb4426c92430e00bdd0234c1e3680dc94d4c30c484d610463a48cd6864eda31ba63c7880371a854551abaabdc14c225fe59265726ad0746b30f85127d12158f8181439a68cc177dfa817678b08b5a5c1b9f75bfdf0c7ba019a92a512b2ca5e91f2a6e1e24238491d3afabfe279a9bdac45971b80f187730f518194ccbd327048c9fac4b75a38cd9432d1074f4152398ec4b2b0607c9a9bace0d87a36827bdcab03e55a9b9667afaca3395ec412872427cc230c4b04bd17c2017ad39834a94b98e7b75e47be158627aa6270ddcab77bc166d2b969eb4c34ba0000a13861c4db47db85839828c6eb2074425816f026096463595fc836b5e569623b3a02227b1c21a206e83a9c5b3ce1594eb9099174fb34e5b5c333e510ac2668a704548f02b47af007c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95930a65c2344510a450b9c59c24326c16cdb447231a026304bbcc9823c3a218989ef2352d445ca22b6b03186407d7973b4117c2914555acb33b4764515c4a37108306447f9eb200f8572c8467a089b824769b7df39967289a93b7f55e1a8447f862c1528c3dc4684daa9632417622c950b617e1a074b3b7ffbc23576a63857c1f386a0ff2a151652961137237ea346e691c4dabb45562653e26a806c6031368c17421747ffdd4725c02b40fc59737a75ba713311230cfea4c1be8a7c3aba9b589b6180dd701c4e704d69a0684a33adf1802eec804f44c2923aa8a577c34a4a678dd2446b7546af0021df00a431241509f6117cd32177da708a2d8472f8270e96a4bd21091f5d28b13fca8f7e2abfb57a9e4a522d95896b5811686e5b23d4577ace10eefdb9e1fd84cc51918d592857526c83f51c60d4210d92a425d7340a50423eea17b8be67325a33539ba09bb734eca0a4c365170448a126721484cf947933cc984cc7662da79d65601c3729881e9b4390a99b0ea62fea97eab9619d71b7bc282622ff0cdd0e72a3c8acb7449153df92e672c5c61b40e04854b0b523398a2634b727dae3657ed985b550849d51a04f3318892f7a4a2b73c8c301e2cb5aa60e5438d8962d8a36857f08c075948095c86de6bc34e35c8caa04772bab591e0137c4aca7c34598c65102e80ac0d677511b854a8829c08ea7766eb04c6047612aa83c17ac38a545a2863161ba3bf6a8005e9fb560597162ef1299d621b62c8a7b8c08e3a693faf0607081c6da8523805999e8b97056b5385834726bd7995bf6217c5e70863036b81c297eca1995ac48b6b7ab0ea85c3667370fabbca8d4c2d758a80bbf07839cb85d9428af1eac0d7c083567a85d13515ff399be3f5931d992c953a664eb8974a434270b47d3e635618eacd0989a15eb065348c34a19442db928d1e8b2b28a0858ed7ae8a5bc38087cc85515a344b4cbf529d7560590b3bb56de5331945c0c0b21d5bc8751d9120182c7348305edc765787ac9b784ac4bcea454e6a4c89132e6cd0a477f3bf43da356b66a8bd0980146b5d5137262b0062541960c0b19123a549ddf31d1c188171238259fb661e17363e12c57bd873c643222d014a2ae15cf6112c7fab407fc12b32c12ac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c699619d01b19919263102f5ef2a0c110752d3b34fd489b7a328638210307c6cdacfc6ada87190a98b0d008644b91aef65618507a7f59b89e7eb36998d26befc4b723741e0c35cf73e8041cf51af9832ba43b8e95e368974c1dd61ab65e24a87820cfae295d0ceb8bd6109b85174c80869716a6016ac8190df173ab61c4d3c4c37ae11593ac9a09c210b663bfefab5eebc30deb27cd25a8511bb2ae87851643b50d1b4ca5bbc66d49aa409aab9e7f3402ffda93abb53acd45bcc9978200e94cd4d617235b52d9297d4cd374b998698d82948dac3dd780c9336532c499c479756d50e9048432ce0156cbbd9c85f5ca06ab57b62981494622a74807cd881a58ea10a6e5c885fad611727441dfd52834d58b6408c7d06209bbb224a5d01eef9b491d13226684baa5a1a771971dd112ac668108963bb1864aa8ab7913917c980f3ac1c435457684ab758569247c98286b2cbc78263f1cb88478a931130b496b12f7428087162b6d525a8216061a3859a7a470cb9b88bb0c8b1e21ce4977a73fa5798cc814ccd1aa84370fa408a83e73be1e12511a59486c49c6afc1367b85231f47cb34c1a8f9a963cdeac7fa6076eb8a657e647466fc82663884d7c70eacc760db1b0be0b30779c98396aa3f2004976c8493ab90ae60996056668c8c2cb9065b6a2580a986d9853c071a02343b8903c0184991e2a71298269a17f64bbe1b6b51d0b299703a04a22e17c33b29634dd1766be40357f33a000a52597a3b5e4852473d886e06db52b7605df5fa4e0d5a0f291b5421e2c1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818db252cec8cb627455d9f792d7047cbe98b74eb26c6971be56b7219df092e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca1cde599b2dfc69d59036434cc0423337513fb9506452bd8f42bb82661ad0065ac95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = 2c4b08525d8eb581cf9dbe8f86cf3137f7ed83947ac6d197a6f6554344eca19217a703e8770b41a1b1eebc8c22153a14a84d9c729821d7e39371a3ad5e0f276c97ba04311b98c31f7a618d7731ca511078584ddd84ebcca03d033048fbd532952c9011f44ec8a4dcfe1d22d09745459747cd7795f8e908ba3f9cdef9bea90398c100b173082249d99c88d2a0866ad714d1c30704f0821bb1098b3b4a77363d7437de00ab99f5d2d2af2e2cf8f2fbdf957283df191cdbf955ccdbe360dddc9a1507e40a0c6ee21e4f78bb8a13bb3bd8a1e5abfb07dc9ab71297f8fa045017028c25987b33b7224dd2cf40d934aa8176316784203e59e77434e1b705c580038c4b417867d5aaf5578f581da5656f639a4055c9a599fbf85f52af8776da6e2b49ddb24ade772026b84cf3fb75a2dd45fd94abb3561dad486e995be3f5ba49d0ad65246612e121860ca05710fe4549a401d370c1a67c58f9a19ed302d7446184e3eb712609584ded6419f020d537717e0b8be66b0ff6ff7bf6db9dc2da68c05d2a7bee7f52f108f9d0caadccf05181ec347fb7d581c3deca1623a1d9bc7e5654bddd5c114ff9588043ae286cd2b3879c2d613603796d07b351c821492a5f9efb7ea90f2d02cf57db9db167ec4b016da3867e805e7222ce2de3f2a7b27c750a2a936f1b8f8dab3e574679469c6f15e891344e8b30c6e7350831acecf4157cda632f66085e2f9ba6f1b4004e72c29c97fb16c1f986ac051a490c83a65e36c2f8858f0aaf8952ef8a18a1a83985c0536b1304a3648d216ec3326c3770e1729ba0231ba622c0c1420cca16f2eb1593db56b688ea5133d75af1bca6ddae050b82233c634d607238eb61c5e6a45956b4250cd460447e3a326a9821f2be6bf099f1d34d4c42e8c6889bde923a52ea32703830e7e92d2381a46b5bc62ef1cd38f0707e2a115b3dd7b098544fe16fbae58155ba301c89758218de4ed80113477c3e27d11f6b66b5dbe77e7ffee9999fd08070a58d357de3362ba47d9d974216fd2686a0a6d7b32de1795b62e90f9cc09348033462bb342fc68d703d0a9308dd4961de35ad20d0c2fcbde1e15ddca139c134657625abc2668db40fd555ffa76cba4d34d574de6384864fa14e541f2f54d2cc54824446296063ba060a2a87a1809dcc4281f213b5bd1ecf56c90aae7aca811558343a01e28d980f5108c14bf411b4e278d4c861341e51faf804b67e4dd8bddef46e5f06b18b01930f53615f7a8bcaa5f5e1bad9c9bbe5c095c3de0cd4a351066e11e58a40fc7cbea308f540becf55c4db86618b7821db519d7d64078c6e875e4edbfc49156e1defc0a7910cb0d7804e2cc651add9e9478f3a91eade16b683545362947633b620c078cd8deb7483aa8e9497ad64565863f360b95cd0463fa24b04e6aebeacaaeaee335b0bf18d36da9782f4e22804b7e00b132c0dc9669fb8aaff619c824b84c4ba727975bd3d6c39f9240243a8a9f85113689f871ae9ffdf7b0f5d186844c80517e05a59a30ef7c781ac3a5a48155dcc514970f92bdc370d7b8a2a89a4926e68116a1951fee233f4aa28f60867b15bb12e470c82154d8225b7f637028a785dd08aafef14ce8e7085d8b83575f65768a8e5538018efbf627aa38bccb5ebd61c3ca8e8652598af4b45b2bd0d4a6124977bfdac2659eb23248caac6c86c9a364698e20c2d455e34dbddb2f073c9dabdbc21fda0a987341b926b3902f055048365d8685509b868bc510f57dfd0d775a041acc0e013a9e7c43113bf16f801de8cb6783c8da303bb63decb4312903a22e87174847d33c7d88b8f6733088e0b4cb4de9299d641e7cc9a18e7907b6c9c0361fca64598b8844a08f1a8d04d0293ca131cda0fc5b66301b1488a49f2df5382e2f4bee501cb92d5e40fb8416a1970c9be2af98560c22ba517fc21ba01ba3d9320228aa851f5287e86b322219e80d16877289f80d7a4e4afd163d2bb59634a04a1a8817922a06ff73a97044a02edce8b9d42df44795b903b86fb0ca5a77ab055c8da28a9f6fce33e570f4c4210f22ccaa68bb10a2b1b077372b9875864bd2d8f396184010f52397fa17b0b26423851b0dd63f3befbe3c66769252066d2c712040f6fb95e71295147a5a643be1850203e1d02465b83e18362c7138890c309f246c9c42d19f3dc300a88cbb9d92b461ee7c228d353858dedbd83c001f918a4c5b397 +expected_result = pass +expected_shared_secret = 44052d0cc62801e0d9717c65ddcb560246cd901f104b4252eeaef903f7c26af2 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +private_key = b1c127d24808fb2b9922332832131c4fd67fe8a1a070ac8d17100bf9f6291efa0bc8114d98f65c8f4abac3ab17b4241deccc37688b881bcb68503b54379838bbc100b5bab306327e7965b694644c470a5148666c7fa89872d39aff60bc533c83f280abfbc26f073331ef40b694ab25feea5b2f55196798b70681caa21537dfb5746c66129775852e5850f57c2db2e8a0e90530a57b387b1c429101d04096c3e0bb6e9af19f83b1b0b74c47bac678b0f2269798573fbca5d8e687965b13e495827adba63da8a17564a3e68037b3a4991993401c1c6b149895ffbc03760c13595035a713140eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685205b08d44a3ac8f8948f2b7bed9cace27ab6265722d8f2950e0c9ade053a4c4ca8e3f80a907a39e33db78e6065fe9dc050a5a730595ae5ea32e38c512edb79dcf345f1d9c238a1732c552ab8db2ccccd11822972896b323cc43aa03633617f82e89d63d4a1003cf9c5ce3379b1d53a63eac57adbc91510316acdc30fd74a1a2e6c23584ad1cb28444f9231661079b0913e20b3278d8a2e8b18556f336cb750694066b6c82c5d267a903b624cd440d8e187d9e438d178c8394706f016b835e1522ab6904f80cc24358b7dd3bb271039acc174164021e8a522fac473054d5b4cb3bc64bb107c6b637cd6360e312a85a3b1e3d2b64436a87e81016acb763a23ca9b7463023148b0c4888bfb18d9441841f723b9436b77b09c79fc714385a3ae97b5bde0a2a0c541dcd2b668c696281389ec270bc6d088fc42506cec85bcb4b611342af0a61b1b9d75e0df43be293cee6eb0413363716ebbc48ec6c361a48b9d871bd5742fef2ab286094a92b508cb794f2f69a8ee15c2d748d8fca8cd2284719815e75b3b0df76298e48280bf530e09a34d166cd5379777d472f0994ba8e5629ea7691fb973f45869635b61b277c375606b911aa1228271c85b047942a52187bb231412b50f5be423476720240e62b9d3cfc5b7af5ce9fb38e03349063741ade945e994a2d6492a92b1250880318b9b9ce845ba29bd3733228ae960663050888bb98a0fdc21d6fb34cfb5c1af6d9b98ed6ae454c09b89b6067401fb30a17dd331a845c713715b5bd4a087bbc14cbbc9d2ea83d0f9b0d56d939d01b7d590b3082d2405a20724e2c44b5123bc1407b11da3de5889ac52b7b7821c4af1303d3959eef3888b8847f3e0695b5b844e8e3c221718a25057e707a50e0159af4462bb1d103b9057ff7fbc1740bae1afa44138aa2b7e3270cf80a6ac745cf701040c97253133ea195648e929e6c6394940b6eceb18844f1c862da6597a46f64e0cb5d2803eaba4a08110a011a32452185a6425d9d44b43463893369514957592f519c22d2b06bdc762c519d5cb84e9a68456ac60aeae85ac6453de2bcc103e32dd509309fdc08e3b3698a193d83d62df74719703bb5f8cc5db7b88b80110d74d6949d00469b840ff7fabdd4c0cec1a097a6117c28046b06b82c8ee8204296428ab703840acf7f3333d742726b114d3292b3154b2c4095b6d465657ec0780c488a0c60443717109363c45777271955135e60b46104bc18bac09a18690b37c8078a226455320ca539f57a0706239e62716fca94ad8fc2c1e5834396072b134636aeac2d6a1b91b403b070d97c53c2c91784438708bb2761cbd4b99083096610c53ed9354f459c2e91f47bc8220f75b367ca8a8670f45cd118bbc72baf225274d2344343a51abfac2aab439fe5d2207bb1bfe2e54e58688aca733846b7c68d12a87b905243a0324698aacc579260e94fcabb28da1c8b6887ce10c99c2357bb92091ce1395c6ed345081c8b74d5a9bc961c9d79afe27a2894117ffdd9b3974526d33c2d5ff5757598853ad14520cca34b817d097a7cbdb7888b48b67f3a8d0ceb89aeb6374c97b130a658b10c1f78d38241120a3dd7a66cf76fce43a6fe9c6bc6324a64646ae09a2f948320db54177d2a35eee87918aa0874a2ce286528ecc29668d7b53591942c70206c63c6d8db92aab03053f81e166b5f40d17d09b3760c944cd24c5eecb7c780b39608c318ab3031f89559ddf76ced962c035b9d7b7cbed0985a2f0b43ad8849dc5a190c62a131e5bfac2c7c11eca951b2a19674315b811e09847c49339c3d8a9e39ba19ea979ab2c504335c03da056801f4c782d95dc2e163a043cf2db760edb7772c50cf5a62bda4742d2ea296b121094ab5cbf017755c74b6465137a1d32f4ceabdbf34a7471b45b166ad05ec69238b030c31485695a9cd615db68c83e457222d85960ffa8ba6c8cb5721acbca1a7b09b155a555f406a660c325c6166233c0500a0475931b27481a015ae521c7050ac2f605f032899ec655f0b662d7b65a3b21680d1b53ff554987a99258dda8cc711a18ad8917f838cf0a16d4f663bffb33ae9e3afe97b1bc5f9b1a53052f8907145440664bcb5570a368044151b0045515b94b7b8073615b2889a280e59940131ba50b016e0b8c6df2b34c29023e0773a06431397a68580c47610b50e025b0fbf374c40c1ba82a11b69fa9b6e522d4bac7fbe737a18085056bb7f7caa2c4c3bc5b6401f06b102a3b5673c7c8f1cb269438618f9717640c76a4f058ab864348f068691f95996072354532f3a3b6ad0e1448880cac03b6e2a84717158339c063147db0c586032b7d10a69e17c1b62c1ae5344483676bfe8928d637aacc4b613f24d7e2a46de3449f17b0062fb209cd9631160ce38a95361889b167cae272cb23f85bf34e14c789472974a176c567756c1c0ebd9905cea70cb88a55c68b476f877c605390ee1274c07cb95939c9babc97ec51df82a9b7d0908ddc3434208911142ca9b8620694bb3aa9accd1bc236a9a89547a26e44816ce3846f980c893b29e6e6c99580c2d0a905643f556f592ab03228cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77d40182bb2524a87e1cb511e9d591f06b91a71594dce26ca8b20450b899e22c679aa7abf5b178b1637f998502f7c7b4a03974a840c9dd041c43017d8f7927f94989f2a16a1f7cc9b09908da388a68b13f39fba43a391d75c76148444954063d9163b6ab1509b03863dfd62d94b59e849cb545dc7ba58502f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2c40797fc29955960dbe618cc5d21eb9ea720d77c3f8b3c680974fd8c474f9d588285609abd4166a45cbab974ae884c7061c6f129a1de7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb3f263bf774623a37bcdda056ce232b2b2b4f2e22f6eba975c933191812c9ae55d6b7c6c76c10983b02462e220bb90c946573e3e2bb87540034f870fc69b538780090c3b89c18645569b124c03680dfc10cd3050b33c16740c54916c5ed1604ec092793d097b94b4ca3474b6d90382d5cb21e8bc8488451af2492310b7239d9a46f8c868890c7b531834b2bbaaca7ac34651b941d32477193cde0a3347323b77ca97b997c429a2544a1590aa8252d6e0832e128262284908ab785543bce3e6aa43d4005b469eda56cb28b45c44329cf7f79cdebabc3a9c6558997e04f980c562c852a103fb40ae24e26a8bc8bf014690b9085f6e7bb947f2ce93550327a61900aa954cfcaaee412aee44cad3958555d18b59a0835c015cebc77242052f13a780bedacfcb9998df665a1ea24887b570f36198836c6c57a95de6349d031b2b33a3b6d52292ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c6890c094b625a5b747b2280fd300455739af8d97fdc39cf741128c03283f0ba09fbe19a24598e143b5a856a5b41334839a6188e769f78aa24673b3f69c51ae2c5ae98bab4b0254ce8c85204e6ae38b80a2f24c162427a66b09debdc8235e96d25e96132617dff682cd03896290832e3d7b5959331c7025868803a0c292ae4068f1ae8152221a4607bb9e4f94a5b98701e027a8ad0913b0bbd0ba551b00b0eebe302e5450681878992a616aef08a6c16175a5c22317ccc48200bc7452414080adf9216989669a560caa70320938c812ad12278588965525538921e5920580516156fd563fc732e37e5591e000b4ed9b93211579d21cde3a951395a21289576aa5c0b0c87bf36acc28c0ab51fc86da8cb00d23c40459088a1506d8a2168f94a365fa56ebd751a51c84342931a5d569793569f8fa21168ac2df9820ca3134704c533a399219ee79f4571b1152c95333c135e442d5c5984e55516f958ca38927773a2aa526b89b79522348c1244220dfa84c6778466d2a287a774141b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c592a50c7a070b3dc7e107eb1e8b96d62305c13327d729bf9d97c69f1fe6eed2b52e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 1ea5056618b2ebc32b56af994ccf662bebc5cbd0d03462802395fc56b48ac8dfb8ebec2e00a9bc3430c9e542c6953ccc18de1a47f6982de199bc5e0fd01570c3d5b1e66a294d97ba4c42e3ef500cdca834c35e19f437c64a8300f9a9081c02475cb2e5929b25d9c4108d3b23755d1395c1894be55d6471ed29559d2fec0271cd4d970741a77942721261b67ec50bed1e2e0869df8889932f0df5549604b1bdc152f0252baa17f81a05eb24c6544c538d4a346f990033f1786e90bf9219dd04e32f963a2333e1431456c77e55bf56c6cd0f115867697681db95259ac3331c9cbb5e60f514d802334917dacf5e736c739344a0fc3df794fcf773a4c2c3ef80c0971e63e05ac9dae9795af309858ed01d2da97797f09c5fe68b4859938e12622e685525bd4291dafb20e02a01a45f5b963e281990b091e7ee7949f3eb2245a31e6fd3c9de6163e752f676da020dedf22ab2e325d21470c13342fb72d21423bfa1457b0fa7c1b27ce04c5f49477d2d66cb5369eae5695643c84a233e2634c61bdbcc7ba0cd928210554f7aa0166def4207fc7555a0fff3c8a91dfcc9c5a2a3edffbc46d0a45af2ba4624458ab2d2a8785a7367f7d12b4f4db39357d25e64ad17cf1c97d0addf78b0d0c2c4d5b61077e1688650c9aa9d59f2f3de73395052a538cf713a4cf5d4f5d8b74c78403baae3352d0fbfc1990d7789ff039ab951416b649ffd35e4ff1d30a5ac5a119f442011742f12ca39153359d21a47c27b0f6e4497e7627cfe578031206bec2985b976be266a29982dd47cdfee81cec48e545b9a2290d5244f6d23ca942f06f2f5b410f52122a4c9980f43ea1d3a4e753874ab9e003a918832ed60767251a24ae76e05a07a2672541129709ed5f5856903cc261072fcab148e5afaca434d18aec3cda47866da2d59a0352f7a6dfebb0a4f1a5d4d62aed28490f02e3eaf1fb13020f2420b06bd4073a30ae47838c58e20e4e047d52316983b5bc6f478866740fab85ca2f731bffd4afe9ad305321e9a2d58ad70b62fe5b2ceff5c3387a94a67b33137db6e8ec4233f14db67a49ab2631978322325bab6fee732df98b148e258891ed365481b53404f8bbf8257e3f6c0433e36a57761671753f7d0e9106325e7756b3c21fc339bd5115c9787348408a96e96d776e1cebeb0bb547cdaf7f11f3203fcfa1d431874b31ddc6594aa62bdf58f1bd7bb1a2c79033bd1a2ce5e9f03e6b2985c73a5ec3d570f906f3534329bd8f593e72d7470515b2c813094b3942d6367b173dbc87b9bfea5c66d026334d413c20a50561811c064d540538e8dacda28104f34ad6f9f71fa848b8029e3642db710abf3d9747ce271a2c3221c5fdb13454e9d325d865037492a4fa5e84861cea263a3c087e030214cb076280e68eda408fea07f13eb8f40e6c01380bbb2578723b54222fa488ade248fbc237511d7369b814df3dacada41845434f6cd8bf8733c51d19a65e08359432140d2aa6cb227e9848f5ddae201c7301eebcf8c97eaf1f9d98ec70cfd4bc1eeeb30968cf906a8a8447eae658a5db0eef30372deb6faf96a2878232650179cad594c165621f2fc8c250dd1036b4e34a2361ec6a14ae69b7ae4ea909d53f21600768dce5e954cd770dc9430a5cf7799fde0023f8b526ed13eb0a4b55b90fd30e11b5d4087725496f9f435904ee3ce44de3ed718689cf252f062b782035879627b752624ff076a920270c9508eed81471a4bb58769d1fb0cfb5c71f276b2badf29fe78410927e5f754c10a3020ad82d5182b9fde9fc440d4dc437fec7ab11d54db36ef73073204254ea1e9eb2e0b94bb3f4684ce9360d37404f91a490c7afb8bc7fc80b2a1997f78f90d22778c252a9fc3778b9a47d5178403f33324f684b872cbfd36f900d0d45684194a080ae04e8fa8b7ff1dbea5a3c8bb3784540ea1d3bccb94e9820541b88bd4c7bd4fc8fc130381d7bfe45a721a3e93c0d4a996ad39d4788302a731c8ed43e635c5423c44e7ceab90d3fc177bf3e70d814434324cc8809aad09a73d1360b92270c643c14846f4d19efd1c3d70b6cbbe8caba8a898764fe107ff49e26cd1ef419d943dd68503ea0f74d82ccece18213dc346c239cf0511fa7a3a267cd55414ba4abd277643f30890f20b0f855ad28e0431f99195db57799f2b2f66b798b2f46b4394a7a4d2e2ce0941be0ffbb23954ba041e27d0597c20fb +expected_result = pass +expected_shared_secret = 2e95f47543ff640e6384d65cede004c4fc47e9e2f05649e694c18c7faf975987 + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +private_key = eeeb8866b17cda12a45fcc6f9d05afd103835147647a7301ee071366398473c8103ab3b064e340f4f9866190acede02473fb49635bc38debcff0f34c5175ae0ec025aaf19cccd46d658c2a6ba62b50d1452b09c21b430ee9a3ce05d36a8e1aab2bf0185f35664b4999cc8c0df049c01056af6aacb025708c184534f1172b28fcc94aac2fb7012e20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c7f710f51003777b060f8db5fe06c3520d35e97f6b5792b0ac3304349387b637686cac1a6e45149173041fd7c3cfff5a398ba832dba04dd7179d0768122a701f4e0bfa48149ff140e2978a723fb985b939458b081e1068ee5102e5f540365e6accbb8c28db84125b21e8d04622412c2f075cb57019eb828616caa245a8b099a01bd86268cf491823e440e984335af59924fac1d43263af725895c717e827532d35c7da9ac1420b46aef13c9f33a427bb5a1bc646f7b54a21760527d303bacb2a21aa39c5577bcd5f416f126741fba9c2cf9401ec20a14e9a7bb927cc8135bbb0c3180696093289f4b19539c58655b8698a5d1339c9490be7c04ad3311fd422045a5027b203407cb5755462c21ac51f523389e803f30e12fa9c0aa7b4a1fdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd3208fb6f28661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5bb222e7aaaf9e9149afd11ea5e86990913d2b543913942d148639d9815d4a8908362a84bfb6ad20b8acf9596df4187009e7b773070450010744712f9e7a9b8e9624e3e2b1d6140a9e4789775abcbd2657aa487740314ea1e446db5c09746accaee29783b23ebfb255ba5c9706f1254703c676ea09801762e9fa45d858732ae7218b37107b3708eaba05d2c035fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e55c05e6b5041552c17dd223af273cbbf65a44b4b6dabd51b341464a9993effd671481592c5a655d116b963975006b13503baae38332248f58656620098f42f97a813dfc7b4df880e5e783af5d833b89079474040ac05a6a7ec5e9ec1bdb282443c736514514f1cb7455958608a62503428464d89c66b209c417445416a54aa66234b1a5bf1c0c3f7064b6d0a7243e170b6acb01c033c5b1670a3ba6801024c03b24cc1786025fbc56bf04f3b241e4be701c9764938695bea4316adb6abacfb44f2041d2c29bb867379374b211e990f194b872a7b684a212dc179a4add943aabb1e6beb93f5cb100fe342d0781aa80989406571d1b79d08e31ae15b81740a22df02270f920ebfaa3c9d74392cd64e71f363df221134e9be32b6b855fb76e15b5c91cc6c3f750aeed71071a0803987ca7f35882ac31413a6001a6023c0a183961722b6ebba16f5577d95bea2c5ab446ac8e57acc96281a07599a8d335c2c12388bb0cb9f8633cd2251c8a7563b396072d0cf6e7b8e3af2192e5731341214c30708e128914c124973e759d4221f1735386b874905220c41fc731a22b9c665cef0cc5353b799399905f0acb549f13c6fa56fae2907d0353ff2054accec40310a2c4b62aac3f392b014ba88fc90eb868693eac83516336baa601f600518fc820bc8b0e76c664f3cc8e6a5cd6c34bf246a5d52f93643111f8f9557c3499664ec572dda5d73220a170095ac2764f09167e0b2277f08b23101bea40923a282132a07222ce0c2f1c5894318b591e5591ff20a5d8bb735cb3f7b161a1634267bd33721ba066713a4c25cae04a0973cca6834b717c7aa9bbaf1471aaa24d92c5242c388de17a42019506dc7cb6cd7315437595a9221c76c7862057afd76add8e852062b017cf77974062d00b9a6452ca040d839220372f7d44c36115a3fc5671eb652037421d08484a68b779e94b3f6aa5e74dc282525859a3945003c7fdef3b57cb5b43f14a290a1982ddbc9d8611aa6140ea8c36c4b5953ed45bb7dd96d50956924abbc70715b768975198627a9e64499aa778b9c4df403727486329678790bc8623414436d79beec3624bd20423d14c91e4414ea4784dc405e30f5734a4005b6791059ea8ba7cc224146a856f514753005af7abf5dbaadfd0492c95125493597520478304696fa30681134c5d3b71fe5c54ec7d06588798b31d6890eb842e0aba055017b8ebc4a355a23b704c6448bae0a62c2473c1dac43425852245faa8514b54c2ed51305047e5b44618f166cc329172668306984151c31cf04a9864267a1ebe30faa133fdfc040adc3cfa49a3c0f4ca85d7a52a72b71f217278fa787a2e3047922bd339176cbd5049d498708d65f2beb4ff3e544f973a4b9e19e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd39e1630db0b5fd819dc4002297a205898108050c9365014351f38c017564d6798a16382b6f34907a4850a0183b27243ec4123ce3b00cc682c1cb8a9d97845f5d24b5fc35c7e088cbed62910c4050ea6b76c88c87f9577941f6a5b3f2b614c94224c26a36a841c3b40469d2c0cfc366ddac23c8c2bfc401ad78c758a6cc1684d1ad400bad5d88417503ccf169481fa437e4a8cf78b907890cbbc1ab9f46178ee2dc6dbcc1604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11df700044a79a809112516a88c2c662965a2da9b996ff92d951337b4b9c11e7947b14212a6f3cf19d2c5d86cab5267a1c8065ec045517dc9be0783194bd846dffc50eb723eadf08ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a0128d52a34e27610d9a902d4151105409be06a11fd3f73c88b79c9ee630a98105556b777a5bc680a803f5a7b603f16643ab0a9ef7161861b3ecb5636a9529a24a59f17a389b61aff5e633b863065f37789a538f8353b80ad75b4ee876a6ca363b6679680115f4b9857bc88b845510027a0e9014621dda9a31e12222522557f8c86d29a499f0547e35a99d81b1a02147dfa3c45beb8a3026a23fd20297d20e33503cd49002a9fc7ff8200ae433b921bc93cf10209a05242788908f71bae849518ba305eef84597f654754a7808d81f2cb62bbb282911a0c5636cad75b53b454a5a923a5fc8e956c9cc527bc04b846b596c9b222a953db76485c6486907f898f6835a6f315ae20b57d3e56953170ea586658b9178c638c9c22c941097838af0123a601d0d4108b2ebb53b46233408ccbad9597633440ec1aff61743f0371ce62ca1977aaea8d98900f0016e5a9248661fbe5c1a4d261c5426a12715af037a5ffdb38b8dfbc11ee3b4edf289c3ab3995959078091e888ac0107467bfda6f3d35516ba7404a4733c8ca4adb010f7399ac5f14c2cf992fa812cf72f2c79750cf52e648dbb8c3b14698bb517166bc1f663594eb9a6c476c58bc103ea7f03f37205c5c355a2633b9ccaa829e3366fea63932550617aa96d267cdf4b98cfe3334aa0a5c7600ce6ab6aaafe7cfcce4bbbe2756b7cb10d6d6cc8c71b32a04cc652c01e2b62a73497dbd9a46eaccc382c5903fb405d950462ee6c87d2631ff97adb38939c4f284489bb9d1072821c108886842f5c1b402aa2e49d37aaae13b7c14b5a748c2dbc45bbe5bc2abbb929b613767a720ba572ca63c2080c4547c9024d2f451f25973f064941e814e3ec74b4c1770542b0782c67580b7a695c2ab29c95da2c18e4563a24101b11084586cf9a42ed62a2bd1570fc175f4d5bf50f8c4a196aea1953199143efb5183b3a905510623efa47c4a52522787723af5b5d05b86d15126ec6ba2201120b5a527324a9895f62959e24aa6f8c95d9001e7757fa5b3a80085bc48bb0d34388c0f6cb647b0a7cb992519922a730865a4032b51708fb6602b08d144336b7c7b65730d8677399436ff5711eee7b935d67054982472b96ccfe7279f1a673bd61757f7b951a5bc9c4b7e52c11a09f350737120e0923f8c1a2989f19a6faa06105391b39b266d9c768c658d56fb59f57020e0d17feaec496f729a810821fce59cebdc24e8b7cd3b869144225ca4b5a5c72432738ba5b939c64cf338021181765891469aa7af34a628950165a1328cc4c2b6874498a8205c675214137e47080624e250521ca34e394e829206df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332ac168abca2597ba39320653e8338303552b419c84ecc014ca3006b50a6f74b8ac57378f8a06006841f972b703a2b0daae868698b778bf6984dbc7bab537b29ec5462463295ca1581e2a60f5c169b494d0b7793af3313fee3742d84c1d20b6b47877320e25aac270e3739b34063b62fc171ec6a6ba7b62faa650496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa05f166082ad3ab0c739cbf0a6bbe2707741d9b5f53a0e16199280a2376c9e5a1781c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = a9a4803dadbdd25f9c157360a733e6473bf476fcd8e9c07c7ef8da14841e8844307bbb0517766268f74bcfb218dd420a98d35ddd0a8040f32301fbaa6fa68a1c01872da756d7359ff2ede53620cb5b180a6905c8836cf621851ccdc3a7490c3b130750e41f5f3f2045a6ade86678776744a7c0c858f0dad0f1b986dc3d64a6606a51bd6598e0eaaac34ad31f888bab22dd334e1394a62ed4e4dec4479af116a8c211a2b4a1399e27966f4ce8419551fc1d79148d0263aa287890ddf3cfcdb409b5a38857417fd8a5ea2e27a1b276200b4e42df603e29887b6cd99fd56074e031d7073bf529cad46c715bf8939da99d13d1cbc1bd740a58a08e381b3b95dc2c269e7d2ee040bc7a6d06589102a2a9a6366307aa429a20cab4b8cdfdf12b9255a23ce45903b0f79b66abf29f3dacbe7fabe5b70432f7474433733868cbc222fb9609c264bd5738627ccef8f529590cdf74ec496e781e9167c91b38d11f2cf12296fc404d49c69db03037f080108b6a68f629ae9a392e041ad4c1d1c5c98707c1a586a624e1586c7f9a57cc291d29a09c5efede7bad2e376fd865cddf0c10ee8f8da54edfa28ad29977f4333e9b1ed6f30086551a718a57dbdc39363f95bcb9dc6c5acdc7b92751edcce0688598b29b1ff7d0b0402cca62e764712e355edd9a02c690d3a7b3e125d8cb322c791ba39fc98b4ce39827ebc6a32414941dcd060d729f6044c88d7fd34917813cd01922fde7bb410046881178e1f2e62fcc9c8d851d91d6fb68c49366dd0abed8fac5db78c4146ffb33b46755a458c0a4b20c3b70ddc7135bb882db104c8ae7b4999771f0b7289c8c78f2c09918be11ce9a39a1e70a29716ec439001fab42e0cfe7b7ca2a65163a617865cddcabf3efd2061dc7fe0015d1ec66c7d7b700d9f296168f2aceef7014d2fc27af8a7228808ac6958aadbcefd617bff5b055be0aab337a984967b1f6070a106424d0f8c7ef56e80302886de677c155fb5327a6163f0ab4f4fee6046b4302331a6b1b7c311eddfd0b5585f8eeae32c33e639767cfcf772f70091b8c559b7821eba9e8020563017c4103e40e2277a441c8a5bff7ac7cd4389e9092d3d47205f563fcd1d7fe94e576bd8051c525ee446dcf66846648839fc9f0a32c426a3814bb399bb83e81b044d0369cfa3a5639f184751cefc6afbb4773625ddf90d5b16ae0c2b0e1c515ed23ea478c27e1c3419e0f14fcc6702fb730f82e298d16cd24c9c2fd0b91d28868e50c3002550a8609772247c5dce89c4bfaa547fa0019f254c9afd4f9d5869efff5ae805bcdef07168580c5c9a64232e2d3e6eaa81df52e8c42aad842df32bdfefb109b33f3324fedacf21d5026439839b8667ce7c2853d8d3d8b463c7861a46e802a0ad1d4b5080c491290e661b04a4870432fb6a695014018512f3edb80d5474fcfe8070b7bb851e0fc2312f44aa1c6d7e243872f1934ddf29bc7f4e180fcf160665fc776cc970d3754abcdfe9429b5ee03b02ade73c3d7ef9125a34b03fe38986167d6eb3363970a99065d5e996d33026e0da1ae583609ae1bdbd50b97b0e33f5708548fd869c120a5841711a81a131022b2a1783e89d2bf6a877719cb8cff6920a1c159ee550f126bdcbe39ccd65d238fd8070531152fee56c5d483e06655db20524ce167f21a0126facde0023d3711dd6b86495d9893d8d083f4cc9ba12906b770eb564a67aca0f62b11aa773de85afe12c13a77e5603249af0c16e97a02122d0ec0f8c3d052510a352a610cd5cc1bfccf18c9c0326c0e48bcce9e05383d9e18b1002cd8607c920835cc4ea5145849e8e2dce0e8f8240e9a10080f52687706ae62baa42d6220ab96ccd229ceb924873a0030a5f0e7bfdb09015d94a5ce039adaa6d2a447806feffd4dc79bdb9aef5c483c6a6450b83d385a4e09ff84a6d11a1fd9b1634dd5d849cb3019e888824bb9317471a96590ed4de34b4334561869291ef471411c47967e362532b92feb72d551893f4d592ca70dab56d0b742fb754d91b049a571fa85fba31f6f86b9b5fdf750398b72a9dd5af31eaddb80960b69cd1b5b4350c591386994354814e8cc38f0c172be358d54b37bb0bfda5048cfe7498f12af04ee886578c867b2268ae289e7fe91433f5c2038ccbcd94ceb184cf4306a2b187d2ede87c9b41095db2d7e883107757d73c1d486d4447b3377da7432a37cc686b7e423 +expected_result = pass +expected_shared_secret = 42f1442e384b4e747794c944f4df154cde33cdff32bf35c2c5234919762030ca + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +private_key = b27ca8d40a1cf8aac1a62553ff541ef56b4b4e352e38c0ae8c2cb2240c2d2525adc52b1953a1c239e3add71b5f7693196875babf8b31edc528f3b320e6569997639f1c9b5279c38d5ddb3b691b0228ac4480d45077db55bac24285c5820c49be25632c4aaaa23ed84e10a1256d9cca9b584d423a9fd37276cbfc5953c9284a4097bf71706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450b1289948323f64227960a0b24b442e78c551c5b35e89b34b018b80bd094f7594365195f44c05bacbb2e0a976a86559bd6b23d220b5c900375c6b188fb353c3b064ced669bee6751d5d22659eb89900a92b7ba84eab58b7e95cb8495191ca0491ef75a3abb9469a7939796c2f8c15ca22283235852b0a96daec403c5c057b5ac91d09cb16e01bb0d078170e0ce9596b913e953c5aa67bd8a2ff20c0261ca814f334244886daa0694368293fd858e14e23d13e66ac89a58867574804786c4c48d2fc003336c002a7776217acfe7084588455a0a85b8aa51c33e99b1cdb75541855577911db00475df42168e7a21efe57402303dfe37ab5bf10200395550a1639da2aa8e358748ec38946bbd3dfc27deb08f4f017abe33a2df3b9b96cac0e8c261e487cfff31a1484ca5e04036797cb4fc87ae6cc72f9ec0835ae2b160b425acfa8b75236d92870e4d43bfa7ea5c98827f95db6dd4200068650e3d8812de827c3f660cf8049933daa52793ac10f57ad8f2a7445927ca6022d5a485f9424662a175b2a6349b248aaf4853be709d42228c3ce3b13990794b9698869842b81649cbd9482c2435886441ed9a7927384371d02005a514717abec398bd183b321134a4de85a1fc9b72f7268ccafbae289c15dcec18bc26b81ec43c6b8a3919625165617d60c33f1e6b04cd5492414a15bbca5ce84284557c9cb481a951fa5df2e444e2c20969f38284e60ff15b0ee707115880bc6d3834230c7d22c7cd69229d1eea957f58b2d47b11ca97c926070cf1c1934ef83f5a26241c7c73959c8a0501c2c1c70671987243635fea56ce6ee292b1d6aa26c4cddfaa1751520fc3218e7e20c13c6a1df4835c7d6c0ba45923ceb2ab40fa7fe3732e47ab652309cdf28091d8d86308b73f90d86995220acdd9c544c95fcd24a77e7c90f2f15e52aab595e11b1ac0799a3ca95e0644771420aedc777a9048fa89ce94780c8f2b903548bd46a2c22e453b68736f5cca6c35ebb027c0c7035678f7f69a9ca02fbb4b23746759660251f6757be3aa1767d7280aa75b60a7a0cc892f70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc88514ced3597a594d0e28c7aa25859e57be9fb12691c047a8a7373fe1695ae742027a8f5630cb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc8625a2cb995b548d48294b2fbca97d375b91203392cc27fe835f62db97b14739f6c8b1880a53ddd388e2636f866416817a110258a098d9af4458a64c68654e97099746b9b9e23adab5653970c00719b54e4a2d2092cd7bd62ad9317357e35224184a4e24b4a58014f666b33e1530365070b73aa6da432d04f2588f34ac1cb3b3f7fb4ab200b459966fafc689cc40adad0c26108859a2943e6157c22f9861eee9ce412212bb11bc6c5414e781414711c8c61b29c0f90303dc5688da9d00b78ec8a80a4c5485b67bb83c850d2c0ca56e45a30f35250700469b957fbf90a6a097af95e4cd2060b38f8136b9f493e9c4b6b0395e04a0761834619e5b84ab33c3ceb083b1d268e468158232075f3a821ba286d84002c3757b99474b56820a414131e60636d03ba019fc37e8c63ebdda124a9370935926cbf1950ab83e56f088f36c24ea9a84e042447718220bdc53254708bf85971ed83027750301a685d2a91a652633e2e55cec7932126852d0216f3d943f5acc9ddeab99edab31e79a5bc5c5971f5b5ff6b50a57e2455f45346c3275cc1b1b0db991cf3bbb3d2a2f522a9ee5426556d84c5c0ac7d827a0e173480427ad9f637c1a71a2816858b2c152c33caae1fb5197d874d6f817996946e563c8de22aee6b5735e46ce6912b22f9187f8d75b4d47497d435f91759e1d1168341a48cb5c9fbf19137d397a2a1c75f0e71bc17a88e00837de428ba61b3a1e1c88ffe5a41570cca144a33ae851a3637b6eda83bb2281b6320527e3b22bc08b5aa644402cb674059135d9c928bc4598019722b8af0b647dd3f02d553bc457bc763883288dbc461e775909745317f67017d3ab5ac283d0462167dca55e7452438529dd715f8af6438edb470b816546d078db0ab2588bb56b2c0e06741cfa28c997a128370c1d72221147f0218784633b45207a3b43fbbbb0d0cac41fe70213475e61058cf21797564b0db1a2095cf367b9561ac2681ab8b6ce7d240b5d277169c31eb99a4b68b92b3ed1ce6333b404e8807b32a0b03080664cb9f0987d2ef56308707b46b14f5667b2ace438701cadd7b4026cc5886bb7c0160a9684d5220d422497a9162d84c2500c0bc4d8bf20a904dedabdc56a92f153770aa95244220bbcbbba66aa89823289a2335898f01789e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f020779f6b6cca633e33fac08c51330ee0bf70e8a6ae4a7df0f2be54b10c6e418426c69c212a33b6b897b31630c6928cc4865606ca1f7ce192411c8d4812645c0655e23553b13c6c7c073e0ac92f35465a1b8a505de879998bae71608af9e943b4caa34f248f6dc679d93033b51c53315aae72d843884c83a0a711d009414c215badc32a5f74cfb3179d6ef26818d7c79393b8bc8b8d212092f2250101560cef4abd4132cb31996b85432bf437037d73516927300528763472c0d5cab08294154001c3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd60fa1823e32935515f90234b7613ad5ea3734a6c0a9422a97dc7042a0434a684083e8bbb40d2c4ebc08496a7261eaa269175c2a8a0aef21474dd4837b6b1c7bc112d67a1c175b2634737b43e5475d5ec9a75827f02091dfdaa20fd43cf59922479a671363737ab1cc307225bb4118d1a714ddbc08b770283061762bc098415e1923ecb3e3c92216d30694fb869b514a314db3fe8da5fd4930ed0979011d8b1fc723ab617b6de420482e8b9fe2a3874b788f0416dcd20704c20285247784477385a1cb219313b700284097acbb90976b94a5fd8984bb6b7121bb020e589804281bedcd78c1cf0aa7ab136c7e7afc206983887beb2372784a2c388a18b1dfc5e077703c8eb7f8a966def46225c8b3fd0f85d6e3a328c8c1bcb0b55d0341cdc866e1b040e09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf04421056915cc0d79830eb972c01bd3756270975bd63e224d0f58307ec2986699d5f536ee6c21f5de6844da70b797c8ef5b9a473624c50647d171682f30a2f3fd7c670595243d59487cab8d0a7727d40350f9bb7d984ba82d8cf39e817c8984c17892295e09ff674a684272cc710bffb263bebf1be44665c85530d13f891026790c2c1590ab6159cc22b5ec76057371bba107ffbf402631297c2c59bd05634ba628a7bea14f3985d2b5260fbc64664bc9ee308694f8bb3c4ba1f4ee43dc4eb4beac095b74820a2787aeef612c0c48afd0b20ebec9417b12c7aa50f4fc86558d36fc764c5b69bb4bfab3526d533de0c2e2bc1cdd4b897c9f990e8987bbaf147a0c4428ab68ca077a2a2d3af76261a1f371fdd503f6d9517a8bb0d53499d65208baae23c77580becd252d006bf27bc11b87c19789384f063538448b98188b0dca07328265f4c4b68de438d8420874625bcd12912078056c7db367a1598bf200f39d2a90e12c8dbe7ae4b780c8f5662c78916af1a270db365ca9097a37525ae347961b13b9b72c68dfb7ad7517dfb318d5385b7343a63f5026bee90177ff212bd6b639bb15d7949680ea38336891653d2c5aec083a8873362ea5e6fb4b0b1e19e48c1b90235796ba570aa0a3b1ea6c483d3079c71cd153b246993b86b506e477625b3b939fd9616451b90da9348b87c0201e087a5592a208ac9ab7ca6712758ecf4cf1af163ca3a369e82b46d941b15a42d31f8775e6332387036cc1bb31c5505d52b1a0753098d40b4999a74e4743a73e539d9e7a9514aa5671042a68ba6ef785234622f7440241a55a71f018a09ebab25f7913691bf787b781ef818c8238cfe5cbff3f8895a19c24085337fe10ec7b326da82283f03240a02aaf2658e04f7626da155a9fa8117eb3cf3f36d1e48baa2f68d158a0123691872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a56840b3a72c164432e6ca838693ef25b30013e5cf56c1e6142828107a10cabdd169c06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = 325d59b9061200e6d70e4323079618de528e667137a0ad81daf0888da37e09a44e25e2f6365b5aacb05f592ffe22abca9633af8e9e8ee20232a4d6fdecd730588047e1acdcd3f745ffef9ac0a4a7e13e3e5f7954c7f794d0d6f278cd162ba2dbdb0a246a046881c4c196db83d33511759c536a44273d5d4c303cc2877805914bc4c24932721784e01290f53699e15630ef12a77daff98d5c2cc94be874076ff6ebf7b264aaaf706ccc733a71106338232140c671c4a11fc0f07bba9ecadd304b65ff0443ab6fc0b36f4273d27fc43c22be51ccbc0273f7f3aee1381f42c48258aab1b77406a972d530504d6e644bc8e79b4c0418ef2440155edae167dd14e3844bcf0d6dfe3c41533ccf705074a00e1af366797ce6c6cb1d6fb61b89fe62583eb8b946ffc50615522c720b28f14fe52bc6e2960fdcd9734056b1a9156a8d8c8b1338379aa61e00b83fdf85013750ae75749c2ade870400e1b744029d4d542ec00ae4b13e36bb4bf5cd4d7f772fee9b58a90f254117a03c99d9e058b1f4b3b768e1e98c27877c40f239b793f4c0900c79d151e0facc116027ca656cb7da34cd29665c7e49fcd7cf53fd654cf07d7e0d40b53695814f0f907438620cda0f081c478f3bf23045931975f65214eeb16bbd0434f9909608b8263bfe87e85bb2af88bb6ce2f6672e68693251c60de5bec2e801f46d1bd1a4ad1263159911dde676c2233f65f39e099cfb65653cfb31f4921bd4ca729ef5cd5aee4642af2d3cddeaa4356fbeda7fc41a87cd86ac107eb72d9ced1bef7f92acf4c7b6dfab6205e185bf2146bce3ccce9a1ed814f6258ac33ecc63f9402298750b85e1e9d2b8070baa24c06b9143445db7a81e9bf9ccbd6f4f84b07afd389947da350495a6b924c49bab542a1456cd3fe8725ad51e4f2769ff78eb5a7a729fe8cf79209ee526d472fee75750a3db23278ad532c245014dd45477bd216a10558f7428c923fe0b7281300214578e8649b16fbf597e40f6293bd8ea7db33dd9ed18c8b3acfbd03850fdfeec3581d3a36f31bfd024c2199186e2b8f550df3fcf0b3f97d3de9d0765ca0e1bc25b60a774486b5e16d6f38dbd0bb5a54178c48fff479feecdf42fcb3967b6b2c55c1a3102817c7cb8db08d86533b41432811b84f861629862b9901641101f0af0af26420af7c4987143a24f349bacea254dd755cdef1effe559413a9938d9453b067c3f2c0dc6e9b0cc5bf9a9aa8c6021f39d49879e0576075c7eedd1f04dc618d869e8fb7b9deadbedd1ce48de13c1dc2bf893ee360104a09d7915ce6f150d0ec95d1e68e40a84ba5ddc6e9257a603dfb3fa048f47afdb48bef0a4789945666764e9650827fb9e2328665c2305dafdb20ef9800aaecd55ffcaeeba651284a1213514ed615c2dc252e5271a52f3033417e0dc9619c3948f110b234c08c8fe0481040d6359f17f5fb2eceb23dcb7c01c697e7c4067538f04c167b9a2edaced56eb2151479a48fe90843470d2e38fe2d0ce331d27717c5b5c6e98dcc840072b4fbb9d4feba36ea1285d30ff6101d78063abcfb0bfb623cd67e023208a6eddc2a9496f2127a9bfd41bf5f40cb7ff729598bb8bf40361d7d84097478b8ec2813328ad9f20593f1f41e2af4812aaa53e2cb2e61ba4d1563e87d817b27b2d827dfca0f2b6e86bdbdaf536641ccc1f3cca2b026f3a17aecef844e658159f626a04b301e8e40329ab3291993c673da1baa8eab89813e47362e39177f7b8f98f65f049734b66f6b2bc4672dcb2b1e36512ecaaf83a8a97377ed8a085b5aace382f3c269f6f96b382a7c06ab2669d5024d308cdf1ddbfc7f8819977b98854ae29012f9bbf684b7ec5041ddfbfc44a6981cad002d1a6e7887e35c23ac62768fe472d286fbc5bb023bfe4aef65dc227e797200e3bc6c016c088d3f0e59a563e668af5a06640b92138d7996fcd19d9d184c3346601e64dfca4174259ca1698fb80ec9f6f082bc2b03e400b3d81d4f14e1f4744c86fde5454186d51e2ceee89d40e8520314f576699bbec6939208614ad821425552a1d9ee5e63bfa7f98f16d2046cf64b261eb09617d40ab211e5f8078faaa32a064bb0e7e4d1567f8ba8c1fe97a7caaed134d6fd0bc6635256e312e423d78b6abf69d01ffc778612d0d61553d9ea634f272c56ded2c119cfdd198acaa00896ff01fb14488cae64da87805f5a9abdef3ca09f35e5d +expected_result = pass +expected_shared_secret = a50a07f6b01ee4429848806031637c8ef8da23f253874124452e3771ef98b6e0 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +private_key = 2735bc066a2488726c89432e56452acb24a2a5407522988c0732ce072128c8d5147c42988f94a8516c77873858394a2bef65b87741c5b9691b6db84e3b1b2b2f851b1305832e4210e5d05710a5bb7195b8bee0cba9b5ba21ba57b962a280565aabe1c9015635cf1a7121a8581fa0a78ab26fc82838b6a405c6fa5d46469136cccc34930664240915ba5c86e67ed9e73f4b123233c92d73bc05408005dcd6cfd62635c3026c990753c55ca8dd385a29b1c79fdb97c0b4cc8f26b28ba573b5194d6bcc065f5b97df702009c43a65eccf452447af91200ef68f18cac25e5c71e62a39fd7a26c6b64b47e29d1e4084801599aba838a3808ed83454b506965507cc6d0b34bb139300d1014168a79d5707c74bbc7b980461249fc31734dc384c9dac4ea6eb4701402084719593b62aae53c8d55719945975cfd25bff31c886640fec37cab3942676c840a453c6751caf16a4743495bcde6528a942a47e7c2d6499b2a872a76e928ef4b0aabbb21604f33231235a7cb47c96d9c976a2aad533a06a24024ad0925007984d99aba3aa8168a8ac92f662348686f756bdc1a23f8537545d13ae9f657caa801788c9368864a05f40af22e33e10705741f06ef577cade6ccbf1d01065565a5b13284690bf611093e45684d6c69fc0f548af852248db6a6e86a2a907c95ce0053fd942a92b024dd18803474b03f73fc022912257454c008d137c5e8404379db2719581af17108a03f58dea58892912c5fab701d28ca845068761f6bab69bbb75584f7d289dd921ab30379248c91106a784738b17cf0044418bb9ce34bcd913bb26d04ca04896109a255a39beba1a2b58490862409e473ca623933ac14c90f64cc74af396c3186917061b5c8c28f3e8b694535fc2c73af9843031c19166d2c8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf2803e2c3ca5d585c4ea63009c7b850f08759c278f1027c59499526a8b2e494203197a9304022fa0c4e47a3a6fbd8bc59a7c1312a6d19d3063e8078b1a1bff964af48151e4cd3cd87f49bbbe01afa3a5bf46a7f9bc97de729285af35a6a9168683658ee37ba6d9499cbaa8cb44c93beb287ef7cc7b1eb6491154c14fc2027ab49316b70b8237a546090c9687cc70cbfb82208a7f61f63aac1a42961568407343a050b1048967c5334f3542860249ff9c2fac8639ef8c125d0b9fd537fca93c1006a77499658c0286267b910c10b12a6136152bcbc03e782c41b1fe94a000cd974a3a9ade3a3b8b4bb8ed8b403683ab4ea3b84b84c4825f61f99d72eacd894337523c6b6af765bcc99393213938d66b18b2b168d6c73c2eacc42ad22255cd3ac6d75200111c0a6076f02f906b1c96213e80310b8752b1b619e72366f9a0ba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3d519e4263b050259a9a0a8823e3cadcd0b81c1ca53820323a9539133c68b0a6cac1fc834b808d9375431f961fe3233c49fc9e88ea1ed0a068a271b502c0a0376a1309f86013b4947bb671c1b048c0905c8ce16d8035c7c05b9cb8755c7d7b6db2907dacc5a91b61b666837f209075e8ac5b86444b49ac878f9b2e18d42e0f791ab7cb7c973ca8e0437f15888916dc5d02f10dae54c86cab52f2b07f023a639288b2491145d56b7ad962840132667c78473e339f99fb9adc722f956165c5a8a8c5ca5622b504a624af6ca26443e776856292851c7f25b983878c9c567523be99bb7568b9a7488b96925a0fbb07e7599448aa98dc112f6cc283e7f57758c1b43eb9a926b2379df6c40e49159985cc4061618425b1d0ab1533bb3f5d03be664b8df86b95ae8918837a4b35023c9926cef826be5645784b33b333b7b0eff9c98a2793d08b2a11512f3e9120bd0b299c6c5b17103b3264964d58c4d9c51cd8f995edb72406cc16452a483786a81c6a45bab840dfa1c9cc978d6d9c3e22c4afbab8265816cbc322abd4e510985520d9fb0ac69702a784734f230847170b532c3dabdc06b762b22c738af9c9308a9b8b3fa6c376464f6c691265b43901561f44d9a1dce88e2d544bda01080fc0b58fac9fb854c9d2e96ae20a9e19b22fd69b6ff88a6bc324514987b039804b71c1c745d77362801847c780922b68a85c17fa750e2ce19f3e7765a785b4603931f9ba815fec35aec29b1ce3387af3327d49734cacb798c955b329bc90122ce43c3cd1fbb939518c68d1b044e0ce31863d2eec9607410f0a6b74d40a6f93e7a88442aa0111008d38661241afaf6a2101dca37e83aa4e8747ce884cc1c29725a19510c7688ffa569cebb45dd87fa7772bdd6b6f26e48c5ec93a1d66a2519c571c1b0979e28a82eb9faf136feb21152ed15502521176c9ce3e2ac3f3dc78fc620e151badeb9b400da2029f1b1c2fa70bc8ca232cbb69b0f98a39543b03f67c1544402f518cf5477d6c4baf11f8bf44bb1208ec96082bc260e52d2ebc17c003a7816a5d940cb0bd7329912c4239b2910d27cfd2a48c77501e0586a2b88c99c1da29d0167a88abc35adb5a79c76c89f4c814ba410d9b2da6994c5a78c701ca91f42348454261f6f7a23ec89428630c5a88c9e309d08e8b7e9b353aede6c952e36973a23e9aeb8edd83b256d913b9b64e392936d538a9ab250175544a70796202154350696c9056695d9c0ff730c27ea71f1562a04eac9c7d8b38d551c447362dbb1277e6408a09855d1292956c72b39e802a19573c620a74f996492fa15322bab6342a8f90a747c3a40af020a2afda4d37620100351f3a5086818260592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b701a2c5909034a748b9891cb5e430836036cf686d8be47e2cd5559e500ee617ab436306614c4f026c6e57021da6f3356ea54e924799ed6827a1f311c0a340280ac21b110ea33809ce3744ac4539e4e912f4a99066c26d3f047ac87ccdc55529e710517ff042a893848d5acb44191c6057a4659427a7c2345e9005135bb3856733320ca4c031c3b86aa83cda29f40467d5306dc0142132f1a844466abc1b28d94b4d1b98ad5ff80886b38d2a15505e8cc24d9b3273039c2babaf8380568a1136610ba3ce49add830785a1780eb67b6dd628f718ca7f1bcca357a1531999d96556515cb680e153c98281de817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a4007f1069e6378e7f0b4ae2b890dc84294627a10039d7a46b3c705493c6471b3cc9ca2535fb8cb19798b7d4d562ea33869383b28ff7b9462124070a1c17cd4b2bf4a622e054a1cc29bb177048a62ba8fe66fba75cca14048da8a41c2e3a13da8ab593c14d0b295b1b587aff8778823ad2ce3644de2b236bc144aa4c5c2dc697ae3c681ac10b5f53ca1d84334a7908c48bb7f5c93388186860c781bc483b1975219d24677487161b15407e52faf51919beb32b6c3bb1fe993eb15a4af84a64aba7d794252fae6785b1054c24aa6b249840b08b3fd47a275d1a0930b2ca6e8b0d4b498628418af01aec4c049eff55a576123c1e58dafc5b00c2373adb7cd62120b9a69541084100fe44776d3078d66b143b7536888c4128a2a637c66d270c0be49c99f1241a951c413409d16cc653715b88e869216ea42ff505ed71c550848a98315c84550ce83bcc750e4cdb8084f882a29a5a0cb6048b5cea41b9b8c2fb3c949fb928770e411ded9902774b529320f768445349a310c727f2012678f44967f37b0a7cc3d4af05fb285a82ca568e88c87168b14a84b90bc6297bce393aec894d7b464852bbc55f3c85f447980c904bf067f9cf55c756a6967b95bc4a08427a8c9d3aa6ea8913bf47a823f0050de189c7aab2dbb040129f40b5a885caf20281e39c178a79729072ad360876ed670c192912095a01e19af47f11c30a44af6165ecf290f885998b9cb4ffcb1b7d71c7a4c21c0acfc8f9a942b7bb266c49a528a28732f65b4038bb7dc2670ef20cde470bd142a836bea52dc4460c0e01d1ef06e7e7775e9a888cdb8c2e6a6078ba3126572886bb091a14735158b4aeff26a852b6b400698434c61031540fea976b523627e1c11f5e14c5d5c878c607afad79e425b62d5a56530bb6bf889581045cc4839857ea16bd9775aad3609d5287aae66c60f916df54c88e8f291d8019c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9147016c9cb2018305de8321f4d0c158fa2452347c78a376f399780e59a5a4e1c8bb793fa14cac662732805146d2ea5cd67196257362922a81e2177ae5289f2bca3d6b2b0168a263c642cf8e2a3ce8577151aba48b828fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1f475da2ec982c47d91b24bb5ec6c51910530eec26f38541b173b38927d23c5684f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = b12a9afb3a11faa33332ad6a1a156f0c2995d887cc15685d22430657b4c21dc248d54202bdb64d8a769ae9e170d6b3bed186910e4d7cd93da5b1d5a9c1dea5b7c904e4de43434d68ded70c20f56e277578a02e778bd7e3a9b54435144727722bbe5f48c68132c8ca71daee35006992e3fcb18f69dc7dc8bfdd1395603e81fb6e005ad8bb59904e92936f5591bfe301d2f74a51200e85735d453eb0fb0cdda582a8a03fc2e4d767bfaa7cf2a35864ad498cb466154d59e52dddea1d109e7457f223c554e6a07b3e36a8964b06191cc10a2aa3c865198b782dae79cc56b906121c7b0e196b1aa68b8812d82ff20f94de0681ef8bbe1807a7769a6f187a93f2ae2f8789cbe6503c29c18f52a3caa7749831fe27ac2f7ebf202e51b6e69daae1d1ddb94700efbac3758e3f35713d354d2fb8c2542f07e0547b5859794a34eacb931cae689791f44b0da435bae4088067b78b645aedc9a8a9250eff90de440924864bcb9df4c9b0e8c24773fc35a565cac3566bb4edc7fcfd6c1e127d321a0093c298d09f7e45cd14278a9654eb9a09292a073a825ef776853d191f1be5c742539a3ce6fe1593924918a85c19e420a8ecbbc1a41e06e6bb90b7fa65da2a1a2115786017674262ad9ef7af059fd5564415b24196f4bdcc74b192a027700de533fafb1eba5b106d78a15251058e6cfba6902cb07eaf5fad4116bd00d3c423bdf80da84c4307f959381d20ee956cebc112659e2e8afd1e5011e33821f54b5aad23889b01dfcdda799dd1ecec8ddc86e76f517584bde598af55ef21bd1d3cc8bb0bb7e130c02c9bbedf6d7fa415619778c3d9d6d415e02fb426f1b72a2dfec6d7f236829db3931201f9e843a45baead9b6dac19012c607593ec4cbf1c7f8b45a22cdc39b0e7b509741383c6a6d33ba789b3abae9c9e9a1f7a40578615a1334b5524f36230a09b25e89354f8260f5fdf22352162e87022526912debc4b6ed3d11287e0ea36fd44bc1076ae889b89ab1a40c471cd2e3fccef126486275fb51cb88b5b405f1f209c8a5bf1b87ee928b32191663f13a3bc29ade704bfb35945cecae149f3d33c5aa73ccaad926af794bae7224d40546d0d81cff42ad2b04804969e4a3e7d7314f830a818ec6253df06bebb888cb919c057cfba392c2239821bf2cfc6e8404c709cfc39a910ed224c9509ce391a059d3d4734ad580cf11e85177acf9d7560f2703c3ab59ab4399812b558699e62774cb52093983358041cf43123dbf493cee7095957c6fe7fefbc44efdd82b20bfb73a7432b764e23f617680047a79521451460488a2388dac0cf4244beac2c36dcbbf4132fa8aee7f546387ce8ad7263541f4cec45ab382392c9a22c8e288186b2b65e4fb809454aed6ab014a76d040f41b95b55ea76e2573faaa7436f676f2576a8c97af4d577cfa64c29e5c5fdbf951c2dfb0a4b54d416abe48fdf7722a7734cf67b3bd55e3393aff2ab0ccbeb678f83e6f93a19396435d1c19cda0037a0f1d2feeadc1a5082d16faa03ac90101cbc19c8586c8ab1abcc6bc55a1756870b52d5e120944e1c06a81c0941107a2fe75dbb7dd29db5be0c97acacd75e77a4bbf488333ad6b6f31b29397348f31c2ec4e6163d0eb836bbc654f5769966c80b10e7f432c5b5716bf963536afa379509d733a2b2b1816f2b9747fd8df5f645909f455719d18c882276eed15f3965fc98520a9deb12ebb33427457780335314427135fd77c57f22122ff980ea747bd9031403872dcbc9131e7bc13c6de77fc97449a08f73cc34fd795b575537258b9817d08d8185f9b62b8ff16cc84941e7cc7bde8d34149a81cc15c02942aa029552469003e0051e792c70c1ca784a3cd9f7be1baf79b1d7858301d3d32b6a51f363934e576843f4c86a913053d382026267390375e4f5059b0634ca08a8792c8943dd4ea558743dd579e5e4176c53a9ea43e864713ee282c2c5cfb009a426aaa9eb1e984144465895b8ee159e819fd1eff43c2d4c7417631a8d52c3c8735a2c9f2ac4bd03f406a2a2bfc6bf5d11e63d066a220a075bd3dffdb6fd1a712f2429be1ead3edf9199bcc55d63a69f9ab0738b3aae75e72c7a165a474d8a5f7e77f5d6c028b27d5843fb4dc4b4f740e446f597889db3411bbf83de759c473a11c6bbf2f3a2c506981defbd52fca4ece20039653e7dea7e8c7d690a179cc3dd72b1bbbf7efc32e41a108c +expected_result = pass +expected_shared_secret = c299f650b03170f5cdef5da81e52c2a094b11aaf58426e8c41e06a26c7d5ccc1 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +private_key = a680635121c694ac4672c809bb3b913e8ca2f659c756db1d7bb2369f41ab4ac9b3f5141216f3c997b00dcde37352d46463f371fec14b26aab239498d44975f787504815552e727329dd78428f5568b912c76b572ad9b3d335a9f5bc0283c76aef8d81369a0ceb4523bdc4bb0607c29d9998962f76b217774d74a3453a61ff1f40f89a51365212f39a07e913824bf36b6dbf6c8934014dd8716e998a982b124aed8b082c3a2998708bc1c4733773b73e0be315203e8e264a032797280ca0ab023a9d81fbf0565f491837cf031e219084b640ee8710589e05e1701870bdb7bf0b0bb539a0b3ab0028447110288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35308a23e9c9281c61c556ec148c9a663ad9518cea36aaec71b6995110fc01cb66b75e128478280fcd31a3416a12e28c15ba617574730437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0b80033ad52cfe1a155ea1a568f5b2ef77ab74878e0ce42a1f7c3c845713d17105ab2c91b83836e11b9858a66997b22e8a67682588ca78e6b6d736298ee34b100bce61e0ad921a9f020a7032351daed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc999b2b071f84c921c585b9b3233c5bedf82637bb1253a4b29b36b42b54751dc629a215656aa1890c0c56e0cb62a3c02252b771d72375a60374bf8d84552080e0d456579930b3f2a2a3b7913c031112fabacaef75bb2da5202d7671359282cb4707b52740d9ca06ab7034b48a292404d26b6cfd08c8b0da61550044069f4cf27488c028001f2c29292840b60b321de5cbdef1ca216838091c3172ed26d141c957dd93bb6a59d9e883640d87a2a85605a9730dd5333843805374b58747c7262d5a65ef442d6843deb731c943269b4a9bf00f39b4a3847840c1bf4b9907fd7b9a66c5da724cec467102f080d4d0bc519d0b2504a05f7207edce7398d009348f64267e01b0ec207780791942565aeb061bf03719d706f87953c4757a75a126ead15c6c9447c02938c3b75a58ab25ce65a5caa21898fa8050319880223899f5546e0d253df7950691b86f8e3115438c3b80cc2e7a6178a96a0f38a0cc47394be36c9b0721580d646a89b9327210d40728f4bc4adbd8b130eecccf528a5a09595f32c0f64e602f6898b8a4c82d79a8ed31c4172a7812c295c93841929b782b334490eeaa38c17cb4e77664306bc7b01726ec656e24311c51b0524c72f0745665d43073604c59ec88df6fc9ee2f2a0476079bcfb735e562f57e2b0e1987a0220c98f0b4cdebc70f93ca709c5c2fac7098a7b866662accdf09c85974d7c88ce9afb01f48276ee320d70c7c0e15950fc0775e13173b60555a470302d0a0047260e5cf85ea2f3c326968d3c308c15eb400b13bcaaa65ebf941ef59a069ba0bd3d00841b6124574303ba8c2bc9f90f107865882c18eba462f6b09eaee05796e43a8647c59c64b7a8db9c0941299280af728b872c303755b682a3ec10c5876f040543bba028e870c02a4312aee9cf2bd1302df80bd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a53948790234f62be0f0af0cb460f782a85d7488c0b9706de1c667f41bd67b9d43fc33647bcfd1e5bb6e2aa92e653764640a6d59a8271bb278160c9a153c98247b376069cdf349ef76c20a8867892258c21923621a4828a39fc6b72443a467a4590bcb0295af866f04791b005d0659143c54a4295cc883db27ca9c5190388b84f8e41aa85924e73025a7b7932d834074a39aeb92ba5079cb6ba77a94fa2f7d305e6421cdd093582868b1e7b90348e04875b837466a174923acf40972abe89a77fbcc32810a0e400a5d0c1e57e62ad581204db84b63d522cfb6423429647cd32544339101db3ce037c15ff6c26fc012d2dc05b76a35c5fca7ad284ad04b4696807c95e0c9abd0228487493244a86d713a4b4b13978c538ee77414b354b30548fea56395220fa60467249b13c59a50c20888ae5998afd287a8c1179dfa5610f5987f6021043b7cf6d749e3ac2fd6d58b3e9c78f5ea88d0c691bd2544aa591407484cd638864bfa49ae75bbe2143216c1aa76278cc3ba3f95b413ede648d883b825039d2aaa1539173dbc859f23d76da58b31d2677f9de1841e50c263257b04d84419c3892d590b286088e35b9ed4a57257ab09286934a0e63326876eacb60fce3b9642019560a5646f522fbdf34dbfc8599829105222193903c97101a8dd4806788a8ecc223eac5206a8706f38aaa4dfc87181ab07e37bc3106590fe18996e5b88fda7af242aa56e42cac7113392317604cc89e1f067896755ead0cbfa201775329d2c8804f485cf61cabfe35a33cfbba7d2426ad2f59a98625315633b0424ab2f2326fa8488fa92895ee08edbf32f6e318dd22a5719d3c4782bc1787873e93773b310ca9b036680ba69acd75036952a330abbedfc5477545ae7b09b6f3467a900083d4677c6b5c0dcdb9886f26b1c9b6e180b8f5020ae1a68b9ecc3a154a084a365a9035841700966cca311c09b13fdeb4da6517c9c3a9c3cd9c336607a53f1972856b161b2878c5689e8ea7124cb768fb48efd92489a1bb3660422bcf72ccbbcbf0d7383ef47586863870620c025d6b65cd5c861234194448a021417cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466b528b2fa2eafc943b861c78666a94e1091efe4ae69010f0a139cd9984be6f23a237cbc1345a53fb0489fec34ceba3874f631f4a34598a7bee966225e2b251ada212b9365bfa2613bc4b2e0962493c0c461361fe555ad61bc6dd54b844114781fd37291b7c3e7090cea1a20c86b3637011493332925f503b4ac6fb625ca41601995869443da8d82b81412012dcfe22eba66072a9cbf65f34294b4c85ffabcac3358fd6193c8dc1706c05e123b10445baa34c6616863807551bd33546ed39112f49c371ad31c82ea6db593a173884d005a0a5184417d5a16ec87225bac3728530ea21913b6b05283a4c078950ca84b73e417cd1878b1ac9388241c3e006d5c0b1148db78b319293707d92210622cce348e5c0572ecd7718bec7f6c644680bb2a6bba55d412776303b8b5cc2603356a7f685095da747a3480dae39537780188e264efb88bdb8c82cfaab5586b3629410bdf2274e8e2b76673c700c45fdef297778cb8dbc4bcec24c349170b39f96a5e3c6ee7d1c8da58357398a5f0202743339aa7eb74e0a5b8542909c29a8337e6083e3663df918c6a85246769b01403bb24c25c27dc8a4841166a86698eec30f049a80f786f6fa29cc8f7414517429f4aa76421cc8cab09874bae0f9999f0a846fa742d8d087bcd929d42e89f994ba2d421058b429e24c753436b908833c2b4365047da4825eba955e9c5de3a02c11c3c8e214416f2a8efe6b3ad033bc9acb992d77d8d340c69cb97cd59c7a5b127c6b46a51267b2471031166815c105914590c2aebaee9a9286d7c7d10b42c80077ddab4ba9baac51fd2512b481d1b1713ad4136b1a4a375959710a156fdeccce7a2c7dbf2ce57a9520b7c9509075bee4c5f4e3a2b45a748bfe210c88ba484556299511c10f762c162bd0114433dd1913f628540571c04f79490c30ade20434341b59e2bc66f489058d0aa2f14575942299783caf2e7b40d2a7bc10a150a6b0b1fa2a8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c95b25066a85d1896123db2297a75fdaa015a60942ec7266f8d00511a1603fcb2e6d533e3fc7c126d2753b9704ed2c5608a226cff698a8fa53f9746eeab1c51796be3c013c44f0ad8ec2037e75369877c4d63a1fba7ac534f4b6852068ab973e1d9b96be70cc21659971c90aa7793e51a517f3108a2ff24fd3541cbb89b75786a546b346ddc92ab5eb93227057f0fb76e1554c0cf19bf0d08e33fb1abcfb71c1a0779a91a42af586cb27a9304a75e9604211640be36739fde51f2d9107fec20fbce665a45a1aeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf50c153e941158f2202de5857b834e3e553f7945398bcc70ee00cce8ec15296b2364393085f2821d36ce6f04b0b336bba762c387c69280bb4fff179eef54b925d99176167f4f916e2bfcb945a1bab4e5398a03c17c79992848bdefac5fae4667d37c75bae231d424381c39722fba787765b3005699b7b08d2785805d476679e29372b619e3568eb263c2aad8c891ca561271cb5868b5971445e1cc2e2f1a11e44c0a798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b22b22f73a770cbdb80da84f97f27a14c5df5b3372d52503d3a20c3cb2bea8b404e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = f56e4e9f97a517a6d815580f3e72df4cbacee30faf8faeaf23852cf0798f27cb47d37785f82e0d8c4a6daeaaa6c0d04e3d9a9b9e2b40051ad3993d91fbad0626b36cd313479bbe79c7437a198851d12d349dc858078f89d1f15d6ccb3650c5d25b4e40eb72e0494f74adbcb6825f03b5d6cea726aea0107b340481a6daf20fb8b3e09e2000021a15d6b94549903fc5f4eb67252816d1aa31cf725eec0834073331e6c3202a64fe85763b3725c5b05c3340285072f4c67201d95959751afebd2e205d17a47a17e885682e9e592e37c92d0cad63fa0f12cf11639dd2c0bb6ae9d5f9900f23735647a31f99686fc203d653043ec715404564dcab8715eefa2ad8f28accaef47f5ca4198ebec2bd683bc9d8034e30a5e1047a77ce74096af3fbf984f50e8b945626357731a785e60b2445ad9ab260a20c44a6e81e9312532d4717f5e313042e365ed24f17bb9376de8a6338510af1ec6e06e6ecebd885e05a11c6c0fc11c25d7ed738eada6b6c8d2dcdc21058343f99da448931c8f2d637e2b7e39a8d571fb12ec0251c45996f86dfde41470f20ac3b6d580c78bc1a4dd65570bec1ab75422a17fe9cc16cd341065cf1a523979c6d05b97c605a4c000ea60ca9a642744b9415b4be3e77572a1eb0a002e47f843b0695133936e24825223a4ea6dd849cee7c8ea1aa1238bc4468b97336f18836c147d8cd62a4411987e7b9534dbd7184e5f638fdbc5469849b0ab8a09db0e2a4bdd0a3a019c47d5fa611dbcce91b76be7d91edead166861927ea965eeadbb7a3243b5b2e2ac53721d2e2d0010c8121291030f9cc7e53eb4ca673417af2f3c51ece935f8f78181695fd30261e33cda52d04d35135725e079e15198a9135e2f5666a47daf596e245e12e8cefbaa20fa93395159773fe71e59ed19f0a628ba116acef70a5bb2134a2e67ed415523a910ea571ddb9f2b8daa42282ac3f8e12ecfa62b62ba53cd56a38ba7474764f01af809ae1fd1b7715f1f76233b4edd9b84c90b3e97026ee72b065f8138c9ddd6718dcede648913886fe030954138ff322db57d06c16f1059b58c79ee2a7d6e98ab42a6bd3a98d8946405c6b694ba25b73139cf69fad46ad5a3fc28eb19e14515a5745b5a9a6512873d14c9b6626436ec28547ec3df16506ea7b0c9815b689f4ebc82ba6db7a0274d884f518917e2e03afd2bde2ca7fd0c2b0ddf5ed6de2249a239363e5337c4cbd31bebdd145add37dadb67fc0b22c96aedf2b6782082d4bcd5c48572541917c9ac3288b11e83c68b73420a88eb249cb3e82fdf3ec3669bfd1dd8d9a6a2467a58ffc050940305d0a91ea386f75a29336bc1490b6d90b76cc8986cbac84d474a2a6a512e2221597b60886390a37c7ae96bfc94e4168628eb29c7690432c24714b7b81d54f68b18daf9f5ad9f371b29d8792c7b2e11f23e87a053fb48c1b5945925cac1289cccce8f65eff481be54bd17ed2b470cd0e711be202dfcadcafd269fcbb94159170c2aa9377f6cc80081d7f23725eac0697f3e235d9c5d24485fd1170f3609469f0247c946f2e080a3f44d5a90e9220c531a73eab0d454366e303c6d46e44adc7fd700cb54e057280d1c799e8bf6e80b957d3d32ab48c1efa62247e161e540c1d977c70b591b77e4a2f1ddf6651b6f8158faf6967a7521dfdf3d2ff6e2970c389a1ed25d146320c3ddf12408c5bb012ece7012e6c86f518cbe13a857c10060d458fa5f05323bedbe06a295f7a115110f50566397af07d3950f820764633e5cfc0eed57f8deff0ff3ff91e06f1d049eb25dc3c0c73f6f811e3470e33bc3632d1365af3882ee090f7a259780290e07c6fd52de4c197b77b37a2b9c7b845d28420dc295f774e54e0ca647fca8080f17cd94a4590459f5e3bacf84d6bd5848707c45f120a0d7a612adfdfa33f1a969068580549cf83df5f64ce9c989cab89237f62deda5a1ee7fb4f8045a375a51ff9cfcb843759e444c35667bc649661fd613175b560bb5731584ed1421107b8795a2fe5e4ad86b4c3c50b06b540fb6602e6b443c210435172b9eca236992f4971ab3c5dcc965d89a03af1f5ea8c56dd7a361183db4ea502a6d11b960cc283d4b4e50ab1fd9cbe04b12cdec1543eac9a70d127152046d680bc82eda8df796e173c06802887cc3107cdc397c5de20869fcc0dd25bc9c5353734f0847e8994fb58e5f7b7d356922a7c647d72433f +expected_result = pass +expected_shared_secret = 5e1ac468279cfe354c4d0df6ead070071b19c9707338158ff7dc133684afe2ba + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +private_key = cf8293b02a9a6f579f51066bd6e51abd270104634cfd482823102f2b63b18a8bb4f45a5af4d8202523cc1779b44fd283860bd004307c399ca5d8eacade156af824a988f5ac6bb50eafa6177a95b9752c922bd6a7c4265a6a88b11d0403e47127b1e80787742669e763929483393cad6ef91f18143e9d2b7cd3e028c6f56b91768113259bcab926a082a2a6185a1bf18656448a628258e21a3c6cca23449b4f9483ae9d01bdd4bc674e06566300ad2a215809e547e2626f8d9437baa727f3f05c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303d98223e1a4ef6536170f53a0c61004beb75fa34b8aed5156e4a538269775808283cb0ba5282607d50661d2a626fac2737c98cf33050353bb83e1c1136f1c26fe48d81973eb974ab1ba4b97c95c0dee065523430cc06620debba3db92888497658bc5c64b98be65ab2a0738f0750022b95a66c583354a63865b5237fe7098d279c53f731f3fcae8689754194a7b888199b89761fd09ff75677b2c500d7359905e76357163834712659f26d0d8c9b47192404975cfb89969a77615d1a3fb404baaa54511ff1b3b08c1577eb274f5b3b0b825434e87f60d18fa73141f912701a99a7c11305000789229a144a0899685596aa646f13573eba0b54dd3205de2c60c3ca1614066474b89f2377994bd14ee0a77e1d4c0af77748c1e623cb8947a98636694c4efaf0ce2bf779c66a317989a335a0071505831471c8d845a5fa4b3e42d195074244f70578124c4c7894ab84584daec8c13a6598524c023ca99f4c0499a68aca3e6827798b10ef9a4639605e2fe8656606438274ac8ed8c87ae0a16ba3b8e5857a7f25831d8b85bc7105828575320c6baba75489455154b31e50074a313ba9ad10b747f39405544f44949dde165070c8271f1ba80e57bb5bd1320c8a1f8fb47354079532bba51282ae3197026e18c46ae6b2ab9940eaba9f1ee421592770c9a9604263a4917c825c084c3534381f22c057592dd97940adb1a439d5128cf795cdd25640fa9229220a1ce4a6624cc9956105465246334c77ffcb9907159461cb1416637d8df34ab4b401413c27b6d5a1d23331f88273222653adf9685a614bec9840355b1a23a0c4ce60b0b678affed200bcb383bec2580c89127b2870745c15570ba1cec89f5dccc47be517bb020c57959e433c11df10810d5b37aa8ab3392b3358793246f11ece238646724beb859c861463c42b5030d9a1fdba3e1d391f9ca5a99df58a7948c66fa2b50864b73a40b52dc7cff031b3a3b21009268cd5cb00a89b44c156333b802ad03b2f07f70f7c11057ce78705ab6ee43681aff0874030807412a7743399cae832f6f3b65df56ab1b30d6967379e10b4ef53b9efb5632a23b942f832a7fa22cde494b0c7393d51ac807a38af119d526a5a3b91068e107812269ec85410aa739c288c20446b68880343f2e12157094dd424a349d1523e76c0acb9c29c22b6346386b522b0466bc8a85b97430a1df80850510c4825ec4f2aab987c4a07f11693e7bbb4662a4890a3c54ebc0cbbd75ca468428e38276e81c43d81a8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137c41fee75640774c4b536bb1d7bbce797847cf84043d49019e92fe9e9808f25990f79b52a4445ca842057b02418964fa53478ed974e781901825a3b33e0333c64c765857c97120bddab43a6154336c0a1bca4ae0aaacb3eabb4ca06928f351b21c99d40f533f3059a87a8ac7ffc5f37bc2b3722118a9aa945c935955809f1095eedbb252fa1264d37666596c771a663eab836fe703150236b769c07e23a9bdf43886a265101c20c8715057d281a7b0699df7c7a1b4055e29945952027a06454e9295b89ca0a8c873f7eb86a39e83176e0cfca61b333e32ea658120e417d65fa9f23e3b634e8a3430220ed775155e0084b9713bf2920aadc2de53905a030ac5cfc4405960772f5354bc20ec760301eb77c1efacd29878306699954ac96bcdbbcbb1642811cb18e7b96d16540a8394574a85d0ad6c4f53025b790685dcca38cb95f95fcbbf5240ae18a3913365a4f96a8a77839e1a269f7b94b3dc58f6ad94bc4f15409f775685016340c03521218df1c68fd554d0902b05f935ea20c6ba835112e408d2a756581d8bbb8ecc463761c722794de90503d536a810bc927784aac5b15feda774ed1b0550b7a7e656817866881a2a4ef682462e75391298f75f2061c70141aa682d50787162a6dcd853971665c9609bbd90ab833367a44a0286d860c04057c8ed7797712affa2557e2db46b546390f3163f05316aa8a12a7d49c4fe03337cb9a7218739ddb184c1304530667b9b54441015b9f8501f902bc2f3000a4855e68d7350e83728765057959662504331d5026c8d52088593d0acc1f39e74a7fa59b959967073bb14de163d73308c276ac0e6bc26e1c165b873e46972b72fc214544317c31556a76c09588c45e4762a1b43c7ea2a9dd238ac6e39e9cebaa1945544fd8702d7066d329c89656499e6c8264ca1be481ac792c5a52188e8a954c06a96e13604e2ec0242c78bdc7763359a47c2c5c4f7762819504740c043b2a5bc8db00cc4aa9a8c6354df515ba7d7039f0268637430067b81284f866bdda366a8c25c3808af025561f24bbf8671305ba3aed330898f18b854c501549aa9a1c68dcf1071af689f3c4a46b19709cf02bbcb07f65b44e9f9385c94c4385d88f8b502ca9e19a246498646bcfa1308f8a6c45638a0df58668f55a3d30440453c36875b0aa1b5967e617a296d284c4e2828b64b83fb176156ba7fe864007414c3eb247c4063acdd61b4e5c42b9147044b6916fa9be1d25ba71a035d766bf4c1c336b836b512a23549bbc53e1a8fada8246b41cf93604bc9b792868734fa755b06a7821e688ce17c9a00c7f9fd724dd494b070b9d4fb0a2963ccf41777f86ba3b318a1ea543913d5a653f073b34c64980e02cbe17cdba5a286443677a152b0da21ee54991f34b758b87a3cb690858f29a003031e8a99964f3a904023404ca51d730957f34a0beb402169a6bf7163963d87d9c6159b8e342cd8738c945b832b698655071286338b67b372a067305e5299043c884b4ac6f624d06f1167003cd5659b68f36bccde8b37c817db27870dd196135b21849843835ec1efed74af31a3bfc6cc33a988322622e2841799635084aaba1eca13b61ba765466b05c742279067c5a1a1355737c84199932660b15e1c124f5718e86a8953a0ea5182299a8a4c4a82f91aa901f40a64c2c1457864f0beb17f5b6733fdb8fa9a04d9ed1480dbb2ebe1b8a37917ed30257ceb062d4b3caac11cc1283542b6a711a737c64981afa7cc0dff00c7019ae2169bad10a6f60f094020b7b422b006135b65110076da0ac1e9b8f354a46200b3d58113953197e7a942671e3ca61c17f4256737dc71b12291eae2626ec136b6898047427525290a62380b2b246ad86ab59b12499c77936f816cdf15c5873147e37a71a2993aa11042cc83ca7b7656ff35429795a9ba01075d670a464b33e368b70ce7b484e864efa8b890892b8648461a61b75bd7455979325755292576878d0f94728fc2433c1c04ad8b52e55c93f36c564630c7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b59807f51fce23361e2abdb21a0803f4af1dfc8b55a594e746b241ab0bba37b285666de8431bd3e28c7d6b64e7e1377364c75c1a1b6b8147d91074cd862ded548788d825bde070ede391b0a794fef56231f36b7c451d25db6419e761e700b080db345c613226d38895d55889b10754b9706c33144805325c3295359ca2ab758dd321154ce457b9734ebe32c02546a7556b599733c036060631d5b4ff6c57a1b6c5065b80a691cbf3c604dcf49d914853c87b6758a58d56e406c04230548954242aa799e0532acbbdb9d9a50dc2bab0c91b0268bd2f0427717bc5b9456895c1660cab6c312549a8f15df9c7957b1a9f3c00a7487a812d429bb8f232b559a5daf57c27a96a99327a39f5b1ec95b4161316f1a27ab2470a162231a93761ccc64689d430d4872acf18a4ef71c0b6ebb3d552b2bf4abb43d70576c9a67c3647d5919be77a0af046bc6580bf05b109a66256a21ba44c45c516212aeadb7594fc6ca17bc436102ef3d99722fb3bbb0bb39c9a1c14085ccff8b57140488270c165a8abe44333999a383c83bf1bdc6cf63258908abe715bb383c385fc26635283af0853b3e533cc6cc95591c08fcff360fc6b506b861444b3b328045270b001a481662bc847fd15924f5744e359c18514a909ca163fecc8a1521c1b2955ab7917e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e28709618588523d8fe8354d81146fd65af657da08926bd3a6ecbc2f81cb58d1aaacfe5b6e686f5aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 21e84fec2d39d07af40f870aea929d72eb835afc17ad37b589a40011f9f22507a8dbcae3db12c7c78f04b3224499df5a5e2fbf4457329d4f58d8031dadc47cd256e1818c77a2ff57b79bc7da942e255c29db6b6261a8f1e83469aa1ea312be5131e6e48b8af523061b4d160921c4270054f62daf17ed5d927e71c11093410bc29f0c8ae9c85b2883ba6a6c02e3cc029de0adfd661572aa5bba2b4387d071695a26ee60e74c17d935f9fdb94d90474168fb8c301dccb02d63bd00fe2e4fcced4be6d0cda9f73086a3ff95cf208b47cb28ea7d8d76a0797363d3f8a15805d414612d9a2e8e3ee010445b9dc062ffb6515482151d9b0bda80270174db7012f4dc55c3753933f3be1ab8f8e4456df8976d217b32d5158a96c641627a9f6dd1f5ee063aa12d1c50f76fa1038138bbc06211e9111b23ba6bbdc8307e7106d5a0fd9306cd7474c72a0fef226d20a5f0386ff7b7f2b92f6f5489e17a49b5c322cc4593ab4f105f9fda8adaa4c14eda1a4290a58852abd3e9c2bab221c43687d7d7636fd0c6131c52aae1491c71c63ca6879a234e59ec2955bf2ff4dd94785c5ef566e61b93bb23a13126adf488215f1ba44a7c7b4505ddfac3137fff5f0101db710ab15b7b5b89c76b83ddb22e33e4f3e412c4bd4e495ed2f456a43ca478b7f89c966d4b5c49040eab34ac3dbbbae5ffdc1a695985d31a7339dea863370f26d29c127c210615adfc18a759c515952070383bf6168bf0f5b3c013ce9dbaae270723ace4fdd89118c4f648551c01c07616336c4d6db0334b6f069e12d0a1c2c79134aad08c0fcc9f2eed1479627172e9cdeb0caeecf35a219fee07c9ce9dab2c1d70ca16944fc72a04ceda778db35ef540a57bfdff481c434f59086767762bd956f8c46cbf30c0cef79638ee82fa9da2cfb1f1f6f1dd148b498b59282a6dce929e4fb3b9b1b5fa9e441558133647a58dc95d37c5d497dfe55ed9a14df84601d74b8b15708b329b54d42ddd2e1354bb237b67d63483ce89fc9471dbdb031cda50532e0ba0de9ad761c9fa6996952f63b0b7d38f45e1f73e714ca2b19bf130defeaa3f83d0bafc815121c66b2c52e35d2e71c54533ec758ee7cde243c8b38d7d401bd8ee5b904192b9ee7856cdcccf8eff4aa2621ef12176cdbabb49c279f16a602c670350e3927d466e75939c15f597073e406d2fa871651f13048f575d44f679ad68f058d058eaa5725481c6d4f0c60946d9d79586ab9ac2a042adbc58cb71a9d6768367751ad564c65fa822a8d3a4c4799df3c7fbd5712670377a0396487fe854c4e0cf3e68df8dbcfe6771d0dcc7af77ad8a44904e192593930de973df753f94e6b92733484101a51dc0e1f6517c97a52b8e6605b494dab7b2822f413e5e64323e5e2da4a7be54083d972e5d884211d29ed9325a2676b48b5546e7843e26252d45b35e159ba58f8c6fe75b7087bcee9b5342ec1d060bae57fe60563d1d40b10ce5cd53c3dcde3b95e8181e0d204e8bba231b7bae36740c4ceed081dc5e2d98014b172f89bacae436700aae42d9898e0a7958cfa2adad1aa8a3f60389441ed635e246f101c91465183178c6478c27705b200a92d4532a0e333dca8c1a2dcc7f1177a74515bd3d901278753ae3cd852a486c79c8849ea3e59dada0d006284b320ebda341120aee768104d540993b073d5cf679b24b6c656c2b8df632690736bc8076b6012463ddf5e54746de4ff9c2c3d903e53d80626c396d722b7117b0c993fb03d4c3e9b0acc038d2803c9af5a75015a349e1bd878a5699f2062efe387b9c28acd3565b5012d147d46808d5f6a147ad09a39d4ac8cc75ddbe2f0579117101e39979707d4d3a7eaa832d8820a13c438931057e6c48e433dd0b89097561a66742c3b8145e450a6f377c5aa62455b79f444a1394a453612eb04161b450a80f58a7e8c3dbc66294b75a28b8e951b955cff641d107f83b385be1394dad6c4c7678094fcb83ece7d55f9c69decce45243d3acf86831fd694c3cda038ed84f0b14e724754dd43885e4dc1beaad8a45afd5963006cdf47d2948d4bed48244f65856c2504ce77a38e7b3b13a9b169b800c729cd957a5bc290116bedad6d844498a3a1314c2f63544200ed7de137a6126fd6f75b828d113e4fad9d7c102034e531ce9b881336a66c05d3b0c7cdbf3afad7632799a00391c693017e49d749e038d2b99858fb2f894f9 +expected_result = pass +expected_shared_secret = 7841501410e4158cf04f92b9d65d0cec732984ea66809130aeb594156829dd39 + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +private_key = a428a1343429ce9c3dadbb6213410e264426d1cb5c69c68e7f377bcbc454aaf867771258faa622b6367fc5cc46e960682a3984a13230b3d7c25a69ce4ab9af0234a109878e0cc42a9b858dc559ad3fe82c4060539c08828c51b337b7c0ea768ba646a2f04900a235a4042b88e8934d3b62821a13b67a912f162aa80953cb71c396d91b91521b6665062551e0a6ce453c233460789138cb16ac6e598f670c70d6325804cc494466710d984e3ea551f5ec60c5031e94421919f62c301181831b7fb4fc61da443fe12784cf84b5ecf240daecc87d711aad10808b96233d345ba80b0469797dc03583214355e8e9a356e367a593a6898355ad129a8546a0d03b2279021889c118db3583da691a9ad544086540bb2178b2125f00c94ae753038486b6cdf1cf7e5a2202290b4e5ac807eb04bea95678b52ff76c4757c68d2eb9283b8766f1a39e06c999015b1f1d5c3164338aeb432d54b338c361b9a7258981555fc2563e585a6ff60886c32343e0045746e50fe78a0a9bcbb6281abe3474ba50e1267b3276a1327a8f128e2b5ab077618c59902c35488553f745d2a0c942b81c0aab7afd0c869b9b9c66c1847257cb22b018b81b25c468a9bc35a180b090f4bb90c4ec035c0078b799046833cd90f7bc2678cab9b75b95a6b457dca8fcb84937c01479a0b7b6da9643da507a2b8b1ae25373825189729bda8b35fcea315b3b359705cd5b486582379093e64f431309f0389ff899beb4c3ca9689b412a210eb654f183362ab8398b1e3696df7432be662cbe62666471f2c056504a5c1c91017a6326acc7306524058fd0937ddeab972b00734f60d065a1ba8655dba3093d161b99e698fc778b2fe782fa8ec7c62d422e17b24fd107b87a8338ae7af6994c70d959cbfc3720b3174b9658f5d43713cd47325eb926320073f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c2ff2a1f4a87159472e7d7a4db9243a1c6a636ad50735b870f1297b6d6b5303e2552a54aa5991340aa40301ca2d6bd9a765b72fbde1c3c44a7649ea350e00cde59628e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd544295317b55ea9ab1117989ab7b7304304e5612119396727943678c31cf2b1779c946b82420a557a8d6426263d33c7f71591c7857e90a7fa05158e315ae19d1046249b3011b22291cae30501d1423674824b852c34c97258ab972af6c5195ffa20b6cf05ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a529a1872ca25cb4a99c38b225e379ace27485d8b91fef9ceb97c04322b59f533745d23720ae457fa11b3a0b831de777d07f88ed1771fa1d89db9acbc7bac471bd423acac482bfb29de13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65bc2e6e04875754a77025985a026adcd321574ab45cda47134b560219338fc93b0a398d7f85169b4b32c2ec3a06529f8e3a57fd353327b03f87d5cb60c67074146fb460476c92619d9c23ba7a371fd9425cfc6486992959109cfa1c1a75ab9eba4235af63c6f8648ae7855a4eab5c9d3923386996181980b16b02a53060e5a64a8cf3ced087bb64f93693ccc0e77aa355d741f1f562692477ae0082a4e73e21f05fc386a8b32b09a4b79c41612eab0c29ffe610dea9713da3680be504f528b5eaab6d5caaa20c7221aa39345ad0b6aeba27a563ab6e1b65fd70a81d4cb97f6ba16e35773aeb8c1917aafc9b8f5254380395a41b474b27463f42e7c7b008a52d4395131c13cdebb7effa846dfa429af7393f8a688203bb6a814467d1bcdf931ad12811f22c0a0aa3c1949b2eb266c59aaa542605319b233769544070171801417816f730391a4d5d09127af868d8ebbd58b767b1aa7015dabef5b32b773b9329898cec8c94d80630b8447cb1c17c3c400134217c0acaaaf73b4b03132d779523e0c9cc52d28693da3dbd5507151c348b11898ad548ea305ca0484c67f1c70435c84096117702297f0094113b1c6ae66b25090f9b22a15cea69c95a2b8801a6df8611dbbc4cb92ccc21424f2a2537ad50206cb4bb90935381e62c571874f283cdab005254220d538115a75298e440924e9a3823d69a5eaba0ac73633179040f95a14026455f9403a0eb8fea64c6c0da5d9a16254d897856a1486c8b2f773c18bab3cd4f80c83dac6dc9796100886d14b4085bb2265bd9c2f021034ef1083d58afd447ca55526d2691781d409649e88f43ca4e9b4aaf9bd9588ae52d126692b181817abb5291f660adf3a0044a0c527b233327c0f9db047c9415c806414bb0758dfab9a7d3c28484578b6084b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db333168c32033375a0321a287e133a9aca8eab024a85761ad4776b03a95130d0178f93684a2c0a519501ee5b85c4c3278e8b4e7b2b461cd4602a7918767b315cbcb885410ceb025f1342c2388637eb69ab0fc21568b1178ef3669a1b9e4fc30eadf5be70143ecdf543f1cc88e05a109920a5f3b4aabc0b8197783e8a16b1e06bc5e7089cc447186830a1d5bcc8bb31a6e91b691a65721791b0334495cd014c134617a3318a7906069e0574d83c8a44326db67ccf94a0a735942de923b5a6d55b087b4390e975e6b3aae4606abd3500fd54837ff875c54bcb7b5739ddc0adab741e57946ac0948ccef5ca791a46c669c552b97ec35633a141b92de18b0dba46ddc64431920938a927c255ab78fcbfc9653e1c0b8a0f42489674c0f79c30cf8a5073a06fbfaa888e914d53a3b6a86418f5ec6dd5a6b56973bdd9744d0ef326ab49291ba1b1a9f1a68da542fd944b3b88c6c364752fa6233d27a792e6a040f1824120ae9afa707d7206966a4ea361681627cb346572619c9a7d539db7469e60177e98674398ea296fc3005800c5da17a80ea06ad23a265ab7293401cdfe3460921596a7c228c883b0e1e48365fb02eb50950de3af481439dfb98447f3406c81161e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99c820e1f258825988d4827b5b1506a0129648101bd18823b2f2c2a142387f1a067a295175f5922eeb1de320711f0b729971bc7647889ee86cb5f44363a992369120dc837dd474baffd381253680f00675fb380bf96a89e282ae67c32b94ab48e35029145748eaa76037a98788c45dde75085d9c5523a7309804745f626f89362f7ba94738c5b9ba0b11bf560e855356e8cac1195cbb2921bfdad80db6b3bd9916a7c6cca281914f4fa5ad26d00e6f6acae0db49ae970755d16b2069b1a7ec0d7b879af301a9bf5519683bb3a59b066b62c8d150a316508b8c2c62a7f20fae59b3ccb0cc5e21055c7a638e11242c39855545b0a880484fb555f0fa4bb059ab05457bed820eee0767470628f81a321f113a8158a1ad1367f11802f71b90a8b4a1cc3c16552c11064ac01402b8b4b695d19ba74991673a963537b2ab14333633e04b0859472ecac568c87700a5076c8c265a3b0662c4250ae5cb53771cddcc2473f7bcc52ca97ba018beb6be5ba5420f7b2882f3acffbca13193c71eb60d167c1d9b256f4706a19204a017204ad28b6a0f607d61a97cb578cfc9633ba9d6ab84367cad900e5ce147ac935af727724af3ac8f0c86ec70034ea7c7f5330889b402f6b7be7bb6c7751411120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb311b338dc8a8e5b10c08b3ae26c945d680f4ad35dc07639c581301ca981be25075363b8d3a6b2165c99c0b61c298a502123c40e1cc223b21efabc1c34576e206456cc082cd4048fbb576e720bb967f5b58763342c98ae883cb24ca32e06398c56eb6a7b697df092926a8c76dc160f0c577ab476303647bad3b6951949acc2a69e793807a77c7ef163a25c842723d85665b121dc8622772caca988c5e8281d2e7055657100d31688b09104d0470d8953b82ea4c6afe50bb96b68f5524ac3a5a92cd26f26b142e37920ad36111226c763e3ce29c9c1235c8ea40995eb867ea8e844ed819c10f62172c52558667f4121bcac1815ee2806d863c22f10a20e74425f6c22b1900b520a5041b0a7f5842ad0fc0e19c893d7e42b1ecac89d9a989d8c45dedc5621565e2e788147c42ec4dc6a8ca22d4a1904787ac8b75232bb13aca7e30825e865bde0ce8ef1c7e2172d759873db265638fbacf7763b80fb4161417559a32c2d6cce4834be3316181ea4c5cd29687a498953998783057df991300f224324b207b723607961622f20377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8236fc15e2340175a2a64ca1cf31a4b38ed5f797aaa8acb0c3d2ed9c19c7099f27e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 8a7fc61cbd793349e4eca40c4b0363c8cd6bbda7d91b3bc947253052a8aedce5fd3fcd3267834afcf8bc65bf4fd5ae665e83718fb3853b692854fe073d4495a10c94443fa5b96d5ed4c576c3a7c35019e090b8f4dd290125c120b6725272d3e5715537abb68b1c9383b9848561af1e407fe05be8559386d5fea2609b87cbead19c2088b4a01988bfce6457e63acc7446de77e6b95d4de8c23482a54227f418eb0c7ce1549aab9872eaa1ed31d23275e3ced1086ee360f586c6e0f0ef6747338a11b3a547891198ac06731eeed8991690f69f826065f2bb33d0b90f8c95c54d3208c2ed01339e07616539729b427deabe41e942cd9482ac82989e04eb5892b434c12ec598be216e71bfd74a77250ea0760330a77f292c137e3a6188c26856aecbd86b9dd9900a194041f6665f3b2c5a567e67f403ec8d25718c94b442092521e872238916d56a22145081d3f7f279b31edb7817492fb542ab081b8e3803275882441aa79d0bc50438b1598661836a30ee401285ac14637711657102da457accb446d5e477a82c277fe6a89fe1392ef3ad1438cbf8495466217c9551adbaaeed2d5303660f6d3cb7366e11261b8f5cbaa5908622d3744c76e4f4d758317c38b93560446758b3370c3336457e8d0ed04fbd335884d48815cf6f5a61a1b4228864ca33b9772d5a11186464de82959adc9fedaba313161198782bd30cc85f3b452a1aabe85051aa9a476e57cd277ba5fb1ea30fa93fad105d25d25f0a852fae45591eeecc8eb4d60f49080735a0088540ee2b0a240b071e2543692d0577e79cb0eb20d78e9564969dbf5d0dbd57f733d945ca1e315f83eacc17bb2f9618730357cb009b61b040a9ae14c50cbd0a34f508640bb77947160cc18efe07e19fced266bd0b1512c2054d21bc9ec59a53cf80d9e83cc5a096c28d6473ecfedf997466d9e875a9968c06183ad74715de5f1106b66411df25333e4b74f9609a1d4d220c6feaeb2ef6349892b1abdb8564af4c7b3dc8b4b3901609721919b6612944d8e4ea7da00e46274dee2b926b05646f873c0c79d1a6fad3dc7e7c2a3bdbe3ae25a305d30fe8052c539076a5e8d4bf801a9fa9185886ed87059402a45cd540540e7f65f2b395e36a9778970807d8765a0eefd75def212d5c0f48e392c52bf4ba5b5add4765c900ca9e397f74f6581ef76a105f2237afbc356d3b4888efbd42038f3ec212ab7db92d8932f968e3ad44954b7ae0ca07b1c52f7a2658cba0f1cfd0ddc653a47d6f78866b03f2fc7dd45552aa9ecec792edd5ff572d7ac1618800262515b55d88bc777b6bfa7da44d1e72f659078ccbd434c8a8b1b79806b922f45fed511f8365c9c17aed6e54c8a2d820203b7f3ff248b406826c36009cb020fdd7d6487d5e305df9d3cf5fbfa51071476a080a30cfbf1bd245255fb852eb96f63093ecf42e2092a8c5f18f5d23a8ad5462a81330050654cd253948f5bf400d25dea8512f7ab19c7f4c9a1a15e8152c410014c0390618cb7573f62fa998f1e1262b0e52a31e16c397a3b1a2f33ebd56a82c0539bd0dec4850124b32976fd013b3f313052eaf8e7dcb33a88d59a4b3c9af50386812117a403902ddb66d2370261ed5200903c093bf31cc1fea44f0b9c9312e7ceb47bf2ea05dd2b0c30df2b6d1d0490a92d387584ab4e4a5957372579ac66bc8a75e55d28980fed47ff66ee53893c6065bb04dceb6955fed293502d174f7f702a18d1c34a1aeebf3259eefc6c87e7325199d14e249c3b5c5be857200209565f4b37db58f16a658388a8403df95bf9bbeb91ea5fa1eeb62e18fae11d30c002f90ca42c8b189d60b559aef8f2dfb0749a9c80ac32ba227acd8c9fda46f09c7ae9b56fbbd463ecce9df6daa3907e539ed001dc62ca0c472edceb824ed76b4a4c66b1dac16fb6cdc7fd6c9661f2f3b816a4ea63bfe8507e2e2a83eaec35cb739092a1717189d029b8d96d7631dd4899a1acad50f03bcd167ee77c513a8d99cfe696370001ece57d7fc9be5ac26131ed30aaae8a661f8b574b63cc443549d0d49525093fa7eb4c1cf6a818868a6773139e02ccc0175b8f50b4560eee4a57828cc3e41bba85d02ca8a6fd344b7cc0307961ce2f669f49bb7cc5faf609297d36066e88f265527b391f40a477ee6ef8abb8859050275c013018eef80cb875f4790478657fab67547619c21b131080082c3d31793ce4474c1 +expected_result = pass +expected_shared_secret = 6b3fe0dd082bf384c3e08497d380516e78ca778de627c112d02dc8c393334d11 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +private_key = fa198bb15b4278509dc232002c75a8bbf1853c474c8248b5062821e4d77fd5880979922016d17377f76a89ab9477a1024c9780fb728f6df3295666828143c52fe817b9688c70eba292d2716ab4970840abc4603f597b5fcdeb0144813602242625a067ea48b426738dad0ab986369aa5326dd199c72212c59ab20c8f63429683721a2c682c5aa853b86542698732ab86fe39c340db2d452286fdd599336b9923599b66c144c0c7848c20a6979133fb7b5efa3726a4f44389cb93d6a9c1b7e300cb852698c236ac00b2855861c88bad062a25423362c7774c1626834ee59880762508fb518f926a3f475d01aa8e5c8c4140537091d494af66b0e9426359032a2264af67e63541c2408b1853f87c68c28c8c13417f94d77f6ac3315f23405c233e14f7762c152609ac34842553de175a6fe1c08b44baa9d15cf09a6049b05b69f71df322171701ae91d050778a6754e374878169181a2e1336677889318cb54218ac055491b918bc2553023167151c98b30e1340403e0c59b3252f4d0c85ebac1877798c41aa43c5c7b738b7ce116428c049370ba6665be646b3125aeb947b1f3b2ec5357c7566c13eab148c453d6b2274a9295a06c822df9222cb2026f19603b5602d08d46d4c71384e776af2a441894826e4559f5975c586e47bc0236b4897622ae4396160334cc97aca101805814ae44786d1e445147a4728275c32554b9bd148ae9605e10c5a6b556704f1c17297a32eb311f1e92ee5f160e8522e06554b93b5c796e44086e75d236ca88ecc533c3b348091891e35639bd6cbdb3a408720b6e3a328c4268454169267a5c5348703c412c58846c192e0a162014600dbb351424fa8d0599775bd2d851db4b07438f655aad6402628563db3a435f75d440636cd64041de162d178c923490839f190f106be0020ab63e7b3eb718a4fb59e01057c416c330cc26e485a6d9c72b707da0b297c0a25247d26d40f044844c2db883a5bbfc2b06f1bfbccc6d10b65c9bdbfb806d7a04cd71774dd60bc423c1dfa897a0512365cd54a90ba6ac509298bf6455363583843925281aa405c291f11695cda995a9ac5f742351560b38f8720d66327b4dcc47626744241679247cbe42695b8d81c37c718cad53d1b318f9f900757267c43b982f26639901028f8f636c35091f1ca90a1e329d5cb069a918f45a078f33ab4dfd248390627926aaddff47ecef1718b2b048304cd40e72fb0872b6207856a61bd764034e82bb426747405e1ae5b93c63cb12c7bf09e47e27117d26acbc102b043616e60b714316dfc17306a77800ee87e03e4b74759794ee6943dc274aec1a08197a841e68f258202b1124803064f6e3295dd51ad18949a5a383a81363bb00118a8569a38d138bf8835362c723e999402d3cf728b0e11f647ce2b9390615b9e50487e23cee6f9cefc4a1ce5e83d28d642e3c16934b43931158ccef3832a457a5e833f317918858807ab084f687a394c257abcd8435cd717d1e6b79e78a37bb71a236729839b89a9905b5d935afdc2c1e6c71c597898c6a69765ba05e9784b7849c685ab5b6de3358c6299d8a4b075045d6ee15b639601aa95603a67378157b54889c3021453e373208cd06c0deb7747e411c2150b7d93118870818d5502490121a43898dca59417088eb0d9ce88497b12294687619053d9beab9a13c663b24058b620826fc7b03442bc998f568ca7f570dc638c0f781114fa6642e2cb4eaac2f638c85251c1f99422b13a1d58bc541de67069a228098bb61ad060a39cc5fa5b9495b79c92993f97284c9a657be1e528ae333061759c38a5a662aac58d214b7f837311c92e5d042142190446aa3d646495554cc7f37656ed89749f5028b1ea008163b5bb13244dc41a394a18e589a85a2bc4e71b596e15b6fcd64c59ec031678ac9e0a439b6a31233c0f1b6b5164320f74860817cb3a82f79828191300c8b9543a5b1e2c59b9c6867eaab23c542787262233578c1ff30a3a1a06991343962119ef718cb35080c6c785f91709f8b713ec7b1f47bb9d2f1c9d394cc6fe24ce45840322912f2288335ac78402c2cac4614b93a97104719a68963696a82477dc43a959a9aeb004ad3016ab18a33bcb3f61f731f91ab66d61867a94b2729c01c3d50737720249406333acb1dae84c9eeb89935770f4970a8e4b7b83c12a1e44c3eb360b42e77bd4435fb6f65cc14b894c387d0445af3f28cc2434138a07a667e5ac6bbba72dc3b7eaf788d8621dde4034a430c2de165b313733e2daacead1a014fb09d5b834411b8325728eb325b12310992012a7c4e05dba5017a59ba9777a9b3d5a681f79252e1c15ff8593bef7cd3c059153435bee16cd2b8433ef80bb21cbad40c6b945d7b6ddac39d0d0b558c7a42d9bcc701aadea5707f77498d5527e4f0b0bee834946302191d06f46116a77b884479a75a585a0c2105343584aeef31bd8a7aabbf669a2b2518f3805be390159b974ce43c83ef68b72024a42a942d8a03ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cb50fffc35c6a8b95172a0416130af7560ef1020ccf09c400101705ec1305ac95ca03143d22c93d72bd07e83afca94ec379142bea095c754533d802183a9b3cf2796ee2988184076d6c2235f39d250b080750762a0a31ffd26130700f6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc371c1de16bf2ba57359d060328a8cc01b948ed14197286ad0e8acef142dac64b4fe260cf066886c8ca9292ba2b3315a2d719c53b7acbb5125bbeb8d3df4caafb08ac54b8aa2816d3b44630623101f3b69e15c32c8e6912d61cdb2602734b206863c9b488431d72000e59c36e031471bd693e238314bc282dd8b4702d334e5985a8e89045f40652300a9dfeacf0c922e5b631f00c434085c5dac53bb4637c624c80dcd59a2205c8c5717554c114999e79b7ef020b7961f007541d009350bcc427aaccec0b0c9e3656214255689b24ae3cc874ff7c0574b09f0d8223e4c19cfb381a8c72f7324ad9e600669204b2590bd9ff6a589d26e0f2bbe575c39cb304ed5c8b692a17b65a7a27623144e7248eeebc4ac80239de04e8b3928e750a0bd44c30315647b5a6bf3e5955971c9f62b44ee01221ef93fa76843be32408563c111447541d98263212cab014e7897afbca8618a27b56bb9725aa1b711315e30aa445537bf02a201e5362e6b6b82f52506cf8c1e82f7912612b6e9126b7e725b30451d2001b76cb575ebc847db9b2a048277202b1434f9c936da846a6773dfe4193d019c7a7601fca114737559df7aac095849692831156a13a9060510e05bb9f48a01506a08f63ca5cb4b032962b6d484e8cb742b0709023b9926562bc83c72c047833e27760d6a8a8c559a096600254909db3668b0e2c8bbab67413827a2c808bf6c2662553b4d9166a152931f30031fb15822c12462b714276c743b2691e69321946cad96f9bd71982f47970fce751b013630f5aa90334c657d286f94d325333b64c6bc9955e859f8c51c1961400388bb9de91fbf4bafe8853b1ce98e9f1076af1406458b00ccf021da408575e126d850a3a1d51f31069194d65c4df88b94d8b43a4b6ee651654d6bc72b8c283c49093eb3b1dadc9bd329b11862542da3b770657318f13fe4b07b1d22482c0410652a3b52c2216f3028fa47c3e5934c3540b644a282729196ca366e1064bf5e57ae739229e3f092c3cc91e8e833c4e314b6cb91e6873f35cc4ad2b60281c862b9d0ca89aa0966713ca0e973a766cf303aa1082266923cba1ce7a91964440d43878fd359583c6de0f5c6c86424a1096d5bdbb843990f0b8285681bba7ae82008a56f992267133b7bd1a55f0fb37f84d6b2609cbc49c968925069aab3498ff7c986f522b0f2a1512a8cb5a6bebbe62f28901f2c5073896381255912fc482e9ef57132ea5f5f61b36a5a17366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8aad129ccd6c796b2883ff989650c04af16b339ec34912226f586286a553db3362c5e1056a369b22c1467cdd4a633b03585f82116510127aaa1459b2dfe049e6f191dd7cb4d0a8ac5df064e64b9021440357c4562302bb0ed0a6aa94ba1dd55a50829a574007608bc61508a0f17d41dc3bbcb8e91c4dee25d2ea4700d905348026046450ad0c2768ad72eb0b770d45a7416c041160170b8511da2958f44c9b06060183bb37967282062e0a93eb5bb4b2b15a4152c6f19b730b724f94aab64b60b7ef5080b251ae0290746c249b1a76c96825653a89914b1ce70982d3cd437837854c6d28f871999073b1c2024088f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc7526a1b77ae8a807e9de16a9ede5da5aec3ca5f23f5ea00e455d4a091467e6ac6dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = 3608928ece690b321f3a7a09d0f3f9795cc9f17bbf2b0f389000daa3d4448250e868c9b5f439e2ed83c5123052390c46db9e7df41ce8b36a94fe4bac780d0a7f1f706fb291dd73ef22db1a261645a5fd6908af766afc8dcb8f4d231ce30a4f75095b0755bcc19937f59faa625a4e9082039263fa6995bc698480e0d574fb91d9ad226b2238ae6c90db35b4bc7c3b0a86246fb9bedebb99fd61eb308ddb984dc816aecb312ad8109b48873b240e804e12f874784de2bacea6a0ce6c7badf8447fc92687968a7feeac5a52c9e4c5994eec2b9f5aa1a02e77c5bded0a722f6f03ad50fb9af7dbd3c947d51c88265eeec8eb8cda85cb4e435b42f6bc6449198c0a167c8854e53be601903455b2e70caf40efdcc0f01fa094f1f131c5a4a8a43adda77e6a2ab30d757d27c6945520e61d0d586a4f942469fe16a4040d9cb35738745c6bb7f0fea1177148efe651c305d357cf9fbb60b28e7aeb0f86d401df1c6f274fed52e5201c6ef1fa44a49d8a83247d9e427032cd36dea141a5a9034c9ff43fe78ed18ded60c3c5182ddd7b750a2136d1bfc9f023ac2e035f68bb294b9230ad79ffb08dd7e560c3895bc29d3dfebc5dde309611a1971866932ae205384fd0b928694f1ed3142016cfd22fee072803ccb2f9a0b4f72c52fc27f9670b0aa2a2998cfaf447f1fa17043195e2f00e85d4a9438e5a43ae167d423f4005236726bb696eec9f5ca106af893f41d9e417b487051c78271574e5671e6b4354c6ea984dad8ed2dd1ac638848a12f016a5e643877bf7db0669fa23002484ea4893b12e647fc17679fbc09e3eccf840b17734024ba032ec16bfefecb4e2cd8b015fdb324b96ad167cbbf4f2fbcfcbe920acbb7ff5a9824620c7449192bd44e768eb51fd59304b7be0e031e03294931e71a845c23086de8984dc9ea6c62068e0887037b51545bf0f361c0eceb66d8ce759255a35e44a74f7eb568f4c952c86cd5fc210376af979dc7dda5463d97fa4eab46a6d5df4dbeac5a00ac488cf62d0a354d953438e87425592c850006cb5d9ba10629c5e14dc8de4d0f32c0668899c061dd485c4c02ed9a150443133f0aaac359e6fb7df8357a21d4e6da958a1ed73ac4f424fabb29d49ded136d4a9d7f42ee86e34b167841199333523d0fbb53726ee4239fa0f6213e6ba9ae3edffa2e914a802a245cba75b01e0d450e041a5cb1504c426f0d36bcc0d590af2e9dc5f68ea7e2f13ecf0a266b97f6cc986bda423068cf3da5b44c16483ed6a37843eaad3e23f0c8aa8671c75e8fd17ff4836e16fdb70ba9722403844a51a81d10c7b399a9e9ef9022017c93cdbbe742f1380707469eb5c513acccdf27eb2bb84b0ba66593df3540e4b3321a70338b6829bbacc2d1cca888870080c0bdd9d9a0276f6cd25e60d833ac3ab5e656432410f765f7404e4fc98b16b68e2fdd39359b3fc4c0340b57e5e34fe820459b1caf7d0a19cb132aa14ff4fd77a75ec858c7f6aa9b3fe51e6f5b32c136e84fd4c2c2a1a0174f5e478a347abc1c53fcc50373d71bda547bcda2fefd2b3d1341a0cedafac274783d749d7c4a1f1fd5d0a0e8755ccd4790e766d5c807122788a9c041af93e2c6d503ad043c36dcbd4dad5ae503115e8afc84fdcce5961518e7c117ef1da56934d1b95320672c9ac0c9db215db08ba4337a173871d3fb2934cd9ae40152086ac86188d461f4a37a07abe99ad20956c82f7f67a9f036ca4212ffd3d1aa013d3f99fa2de6eb1372c983c44cfdf0e1138962410d821d2a32e57a37f6db98f357f0b1477dc8a1256eb6a1af5bf0c91835baa033a9612d74f59cfe33c340d35cac871e0c60c0ddd0cd8d2a6b7681fa86ac0efd32ad17ecbbe4bce8550984fb0b7a74ed6da5e3ba27f3f08c97baa276d4b3d9382e9086bc3031cf95ee7c6da42f2fcf025f067aaabe938956857404c57cf4cc39fe57107a79dd1fdb9c3cdccfd74f5c0e90459e4e68f33a986453202936042be7b7b69ec3cdec4ef4f258d91200d222680a8443467d7ffd58c25cf4990d93b157debd343e23c3e6ca3fe612c52cf6705f409dcf5ec499d6d6bb9fa406a8b9500767ae4b4779b99eeaa75de3ab4a99cd02df8fefd7090bd825a70e292e337f2933ddd2c6498e00ec5e928fc7eb788e68479651203160f29af2b9d27d32ad50a63ac30b1ef4a6fa5120f077874ff23d009f6fdc39403e630de4fe8a6e9 +expected_result = pass +expected_shared_secret = cb15c306ba8d5f4f8b723db93bfbcfd4fa02ef32ed8e39c2aeb706a463d9a40f + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +private_key = 55873ec8c5bac259501e025faed327b9b659b0810e7d43b8bf7a25a8c1a51062cfbc9bbeab182747196797913398db1c1ca41c1cc3a883400a29797ab4cbb553076c204167aad2208355279f504dd9a476985362898b4e423821cc2642c335c3c953c866451cece03098d5a2ae366ddae1a06e05547e1c0c0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a921fb14042aac83a1b4897bc6a15c87fc94144828966c49b6cb8f842a3157b60d6b3271c3661529d8a93c7daf7b4de1396308c0cbbfc9f984617cbb5b1825c88bdbc4c74c58ef3d54d089613a6a431e3a59acf4201fbb6828db0061f1bc514dcbfe72023cf8102e9834d5d6bba8a354fe04c6008b37f9b07857cda1238f5a562f288f3217ffd1a1bf8b2a0fcf3af0310c84bd6cd805c246c4a227c9bcf963093a9755cba968e7c06cc4f987b516171461b69e013076cb652c2a0b10f1b0fc9d6b583a929fa3905ba4b6b41f19d862c82b5f170277530a278773fa740eca749c00a61735aa1a27719cfb75eb0768956718239f43239e25a316339db665eb9784ab581137d020b992782956522b824b3ea4cb540a4b12ad7c512046711b0463f779e1279bcd2b7238580c72df6120850376db48978dc717cd1424d0b5e7331b76d0ac0b024c6283c8418e5b1a7a297aa483e5d2a65f2181ede32c69cc4b9a8c4c0b90bb17ec06336d2100766aed931876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb737647504ea1a29d13e0bc2d060bf7480345051e9379cfb0f901b9a426641802e5522ff8b199439026b123cf9b5827ffa147567912c46c88cef0b41d9526d227a72262c0e3b3157dc4898e07caebc8038142b5172a799b8a6db0f7703730c98e1957fef13d5d7b2a52945eff5c4337b6cc5004bacbb419ba73568aa357f61c70383447c6015a5896b9c0c0a2f2c7a76d940278d736d6b685f4fb3cc392caac1830b439468b6bc73585b4205751e55103099986308702a477588611a990580d88657024fa6d371550141405a8240109824788675d2546afad54628e93281abccae4eac11d200aa5c40a9e440d9f2a40deb31c2688a3266c9e16b60461087da271a1973374c99693c8111f9d458f92ac3208268078b177c818038305ab421b6d8297063061bb36f1318bb2108163a723a4bfc3c2a25f958f28b2b806a15e4310b8852103843c8ac26c7773084f1f82151c52083e69772a049123027916f039fd08713b98039f3b84cc83a8f88b2c19f48a958a443339a5a2158dfd7a08d11983601a1892a8c1152c602edb1592c3ae555b2ee54c5dc6020c0b95626fc06d85d78120ac135fd369de6b6aa902bb015a7bc3ba13a7391960c533d2f1a6278494e78b6a3c5b91a2b1aa2a0752e5c0a30e33cc86dcba2e3232c98b9aaf1bbdf9e825b15a6dc3a741d43a53eb10ad18e93541e224ec5a952d673984990af0d81577d1bc83b09856794d11707faac63a1e49a799224b51464916bc07f0a69f06f26696f5806e92ca4ada050cda48a9c90635a9c68acc753a711115c35488758a68256a32f4964c431d50c0a8c5053d1a41126a952270a309f69931c32194fd201bc3809db548a0005585081c6b11db7a19e14f9a4777c5c12b35289100d979e5b5b306c6692136a839ca4dda2a1e9d3bb3c418a732ec4997d124b7d6cb4bb090c0f35ac2d206f2b1b19dda1929ac935b2cb24e320ea87acbcccac6d4454b8a183e89e8738dc645f50239232ba5ea03baa3590cd29c05ff4c33d8107aade2104bc879ebaa431294b201e2b589647c29c66f7f3677ec30bb1bbba093b60abb147cdc07748b098ec1f83855464b1aebb41bf30f4ceb59c41c24701a39dc74b44fd8505980c1786275cf16272a29c285406c70eac1de5969d459ce1f211c8a47be727a57a772566984452e2b2ea96abaeb3a0990b9a7fbe5147f6a438e27a3624355b97c7140406d52870c421754886acaccab09b2351ad28716c476b61d7c9082f8cd81d31554f334af75030c4075d2965a9df37af81a4588ac0241183247c5047bb81dfb6bbd7252993d69cf5660abcf2aa5c9787f10c02793e9bb1ccbc3761b25759a38cf2c28ed1ca65700112e540eb4b0587e036b9502223fb95e2815a5e6f9c384369c24b1a962c4b05064909f424a15515fbf534b4f660b09e9146c40ac273822eb116ac60782dc519805c41f39a306d7e21d0fc2264b8bb6637b113144b0d459ba833965d3a39c51355416f672b25811f5f2ce8cec777ba322ce506823d6005d1147600808ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7efc25874d5190b893039493204f67e11560e49412b484781c571324f76218976a1633bc4ca3c0a6d8211c6c0171e0993baf46406f8b85fa0c7f0551b74ab81d642c634ea74b269837e2588228a8645764a2b9a7bc2a802682b22c24c2a55439d14d12e620363271a4468fcacfa8ba686f1bdbfc70ca9c0961f9a488b7962b8c718b9e7a33d8b5306e6a05616c2a1484aa044200038624f65b8a92ba4739c714ac71fb8f12af92c5cc06c2bb59367c5c471bbe6099d1b19c9bb1aa168c071dbc6e01c5c72fa33171c52b78c1deb32134dd8af5d147bdea32dd6c52450c112bc5a0d9e03b06d807173304972a9866ae4bf6b053d98680858671ce1f252293972c42c4bf6ec2ba9f11be4325c34f89e7d500dd749ae3c845f7d56815f11a2fb07b9e3f88cacb51e2ed258cf5bb981b089cba18f902c14e04503302ca929319645154cfa878cfc777f2093a00916a617b6086d973208883ace08270eb16be4ec404eb2951bb1ac825840bee09eba19a90b5316ab79c3ac062c07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f28a15e49863a2139dec116d99374236c8a7169053fa716756299ed16125d699c39357133fa49fe0db960a8cbc0adb979239b64a7b3a702878fc1610868790abf3968873ae5dc19020b28f1405cca1b0800ef236e020aed6157892161b54bb3d14a4c64fa1ab949648020ca86064b17fe8b3f7d915c72a68e2b46f16267b7598bc112537b7681ea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccc51f9a5357fd4b92ce4906183c0031727c7a966bf0c485a9312f7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c33fc2033c04294a91323f1602a6da351f0a6e478264e0e4a6adda77dd6a2535a748daa074af31af028509f2c27f15f00e60e72f7a7032dfb99d50c88814167a838758c2685243839d8ac19e76133b40dac70e49b33ff83299862c3496999dfa90470b7bb17bcd14019b093b5787abada26700a83377ae57173fe528d6dc35efe846d95933d68144ea3aca554ca0e873baa6bb926d70a09306621b3705942b4e0d60cbf200c10c3c4d5f7c8c75899aeaea40cec8928ae25baa2c7f139392221cc7042c05baf58371010492bc2125d27a9bb01a28a3855c98b894d4165689af39c0a26a6b920874728d475daa731940457b24199d11841d5bc369962c1cf3920b6af974b3150189919959c3b4e556c56fb22e5597b64506575f6799dd86cb0669651a1c017c8a74e5f63cc60b9047b21dee777df6010bd6a614f9a63c72074b7909137cb7155fea72bedb7428e0b197246af69121e97923f861af31f10249e11795a180c0c6c056d58d848a62370278308c4cc2b466a8d7231456c06e4b9f1faa65a8f0113f99238c52ae3c3a24600c4e943947c8c653c946bbf6b4cee89646aa23afc7b22f0d45464337a90a7c22cbdb4449b24d5bf3c070778773b92055206ca895105e264c9757918f6bb76bfc93de826c61c77b6a51b135915235271faad3cf608c0033b2581fc522965257eef576ebf7379a173b1b269e27648189696b30346d5202b560784777f88aca2c9f900344eef8aa0cb4a86ed6335be29b91248780674bbadb5b11f967a663c2f9129b73ec584c50aaae9771d258272198261f362d93830880e4b60e4b142b3822816501c89b5011681a5ec2ba2b03cf9eb1886c33c1c72cb6061b10638931e5f1461f413e5766a7becc59a052a0e221c6419752258955dce743131890bab88b8dcc5738eb6f409c1c0d888de1d0c5a7bb03e80171c2b41dfd411f74b5165804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca4e296f0d975f2f5731d822627c1964ec1bb1ac7452bf0c5c0735d6f75304efa4410e4cd20557b574cad1674395436203db728a58b8e0b95183c10653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b82460170e6cf1da1e7b92037f51b4e7674d9abf74f5c225c5c6ce16a971691284ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = 682f51001e8e82ff56040975149cf749e276aa9d891bb063ad5000f7d00b94c2e63ce6c5acb8d4406149a32d8b8c793ca5d89942dc66d641c6d92c543b593ccd4fb4c420eed148f58962715f57c2e530a70f03e3e2fb3e1939cbfa94f525a9871ccf482d6d0a9ce9817a1f8f9d3b6ab339b64e0121d6b788b2a2691ccb640be2b327229c68dd9f1f2d185a55416e7de882dcb5198b22391af6f3233a3d252303020d01e92d9148a1ca9128c5c2585fa5e62e8ddb1be592313fbe5c0bc33a9e15374aea856c7023935f6fa0772ff8df39a3d0c9bfe4362ef49d2a6bc176935116cab82ee4645f26421874420aa9452c987d50430be35131e368e759be4244ce6135b6f21df91a541fffcd5851ef54bea5381f76d16cd8fe0721b6eea13c03e45d123f5ce83c3734894c50456d85ab7aa305b1f86eeba6822511b59c34e990030e45d7b02f47dcb2cc51361a931a9c5a40a49dd506b5bba74bc4748ccca631b748b96e999e16152254ec3c0f5074f15c29a172916b2aa50da95176544c80dee47c4d3ab06fd814f22e79c91ffcab2535ef4a21bf353ac06a71e5ba365d2eed87b1c3b53d9dc5c760485e665630c2e8d16f86921babfde251f06b7a6ccbe8f2a4e9438e122a04e277564dfb258400bc842f83eaeed123c5e39f15e9b66d7ea24edf862ef846fa4df20751fc167771c7a16b71a57787352de96f0c45b3b39e7b91dfa4349c7dc5b4c65992598c2edbbaba461a6e07be6c6cf90ffef1dee70857babf44979c2c9bc62dbf5a2c5d212da4f6b421414e8be50a2c240b3eb7f3bfe84f355bcb21818e067396956f62c5907edbf859517a49ef693e21e426f73785bf502aaf2e43e35664438b65d0a71bb1c95f0173cb9d086c61b71eca4ea5e5bfbac4a9145157b6f445990d45758bb886dadd7136f4049b1131346c2e883c766d3951cde3ae60cfb736ef668f314e58e21c8341039f8e34fc815782657cbfac346bc6e1f2e7119d7cfbf0fc31987cc38eebad9d91e466590686bbf8068be39d64375077c1ef599dbc64c8de64e308d0599660804ae4ccb22dd216c1abcf3a2218af6e5d8f07fbf52f2a1e9ddcc467029cba6578996e1e794a83f143757c0412c993d8e8fe3f51c9df30e5bd579c7fa0a2ce6c58d47334851fb07c07be272366c9ad90d19b9126f49a70670a4358faf8d75e727d2cc4ee203923f234954c65c94206ee6d803a5a5f4f87f75e2b509d75a6dd8066b7a7d9d6f075fb7003103c86a4c5a93ff2e9585ad1a39d6ac9710c515485e9666877f0d4d2e11bd322c8e124fdca5a800944102a877f83fd42d23d10c0068f3a9c29fd8ac3cd6fa59a148b08bc211397f4d597d39ba2488c93faddaf25930bc5787339702e668312dc1a333fdf09d29f9bfe60ed68a7e86d62531eb08b61149c54287c547476e8b169c20f53e79e7ed680a78adb122f31004d228cc6dfdbb24ef3513abb24c81b2632a1950ff700f422a06fc0b975a2fc4a727f89cbd420dee046f08a7554b34df4d40ad940f14f3ba9affb9dfebc244b964427a95a11b69f9bcff4f4fa382ee648853afd194c3e0e5fdd8ff06d87d4b4905e57b4afc937901e5dce596a085d5e547adda8aa5a57b9e182939c2183b18a44e899707ef3442139bec8eaae2ad5f8ffcebfa0a66952419d8a14c9469fe5f26ad06a830aa1ddc8eabb55ddbeb5df35ef2aa37155ce6b390bacabe1f796e0619f813bb7c9f2a433bc121a7ec4b063e18b6ecd2ddc504028c068b5a3f0a227c645ea0dcda03ce2415ff68582178d0c1281bb5f0d9d01396876900c483b465f4ed9efb4f43790eb88d6cfa2bbdd1189c9d0df02c7f8062166ec2a47b365990474fd90d559b387774cd21ebe3f7e5709e98d41852ed027e6df5caffb12f0c34164507f787524f61107409c01133b4f06c6aad5f581632a5ef4d7c802e4124a196be7e983e5306ac1a230b5fb140c07adc56a38b873068025ef0cbc86d95af8c220f83402dd8c8144e6d6fbc8a01654da62c44680955ba175ef3e6ebdff1d458172eddaea322d0eac20f215a937eac3ff36292ec4658ab0f48516741910e6d7295f39849c76a88849d4648a1e6d9fdf60734e43f777cb98f2db5d5406bdd3fee73488581001f4f5e48a2d7f7cebe408ed3c9be66ce69d4b58cdda8a384dfbb4bf3ec60c9d2612d9a741ba2135d4140d8d0b3ae1a5c0be0ea82459 +expected_result = pass +expected_shared_secret = 8dc8bc55a907bcbad27aafbba2cbd957c30794e3770d0984a6323b641e5fe53d + +comment = Private key not reduced +private_key = 07638fb69868f3e3f0e596fbd96933fec3e1b47fd93c9b5d5027dbced43f1b536d9b2d4bb20ff795a5dba2ffa9e8eb828b28448886db3fc84facad4275d5628e39c5b257e374283c513f99c0ab49b66b8bbb56a41876f4f919a2ba59bb08d855198dc2befc4f88ff5f59ab587a79c327d792d54c974a79f62ff8a78948f89e9a87b688b084ed5960ffe8b6cbe505a4ece2f8ea5a64c5aad6d417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3684cdb7b21df9fd2d3418537e7466ba6385a8004eeee137d8f82aaa1e48dfc7a88f902d5ab7e88d7e95952a55ba21dd9b79a47141e6fbf6eb7dd307b08edae3a5bc5f6b68581c6865b27bbcddbbe42f5bfcbff488c9bff705faa98a2b9eea3530c76662335cc7ea4ad07787f5ebcccd2a4636b2e9e22ff3ab781f3ce0883c1a2ee15f5dc9e8a94194e48dd1dd9cffb3adcd3cee9253d904dd7adc0dd63213e575aa7f9e7b5a1f3362dec936d4043c06ff476c07578bc9cbaf2ab4e48f727ae4e686a96b2548820cbd3b330eec291ead62f489ea5e632acadd1df89680cc8a8b53b481e9fa68e7db4faec3a6a561c079f882b5ca8cc942a8d495afdbd6de89498fb935b775908fe7a03f3f4d54dce9d5eeaabd3593b39be9ee1388fe59fb441f7e5b5d4253786a0d69ad337dec29efc88504a5ba5997070f3a61363e17c6b9bb59bdc697452ddd59451983d738ca40dd34e3f5988854ca0513edb0a6e1498988197c6b31df58e0ef626564ec89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9791af6d18bd399af676745d909f84d57b6694df830664ca8b3c3c03fdfae67b89006868a695f7ccd666459ab7f056671000c6164d3a7f266a14d97cbd80d4d6d9fcaca87db844a4faabe82e8be8ca895d82ac5646fcb4a15ee685ffbdc9ce3372ab95366cd4fd93d84f81af3001ea05cfe5f7fa5acc7cdcb462c33cb5f4fa6b8bb369d43ba68609ebaf536f8ed08463b19653b5435ba946c9addfbf02b04b031cc960ddce2e55e8d428b32b257a4fc83e3d3a7980e9dd82e934f9d95c32b1ad192af3604384ddaed79bbbaa267de4c3f756ba02e33107433a4e83fa7187282b8d9203a4faf94e851833d121ac383843a5e55bc248e425e16c7db4cc9ab6ceb0e9ea47e2b8de0e582c86b6b0e9d7bb46db9804dab5d038f6b75c815bf7d9b968d419832bc9cfbef6d5ef6f5d59d43e00e9d485d3784510e4221736c084d7cac36d408aa649276e9788b8602cfa753dea6cb08f1d7c7a04726f03225b3895b9343de47a8185cfc1bb65cad6b424f339903c0ac4651385b45d98a8b1adf8cd6bab088787f7feeb1256e766b43cbccb964354f7d94cd65550688f6948ed1b5475b4f5f1b95f09d16ec08b56c1dcd69f7cda7c7ff9358cab911087732a649d27c9b98f9a48879387dabd0c25959a71654d6f6a946164513e47a76edd5987cf364cd9f6b537eca78b9303a5fa457608a586a653a347ebd4dfdce9175b3a30127f53616fa658a95277570c895fca8973f4bfef3a344d47de7e1c99f7a635ad3388a527b034bf7b8e70fb7d2c1f7c23ed3fd19af37499dbe9c787a9409c82d29fc4bc7d5a2f996cf4d5d85a4c1a1ab9b6aeb49cdeec2f8a97c3516c72b0da46263baa696bf267f7719d3f16423618ff33380934a6d1d545c4c5c5155b12496e81fc7a2319873978b6a2a6749108f56be2e96fe1792a5ddd077c8e2eae8bed367f499684ab347e87686ee450c9f9d2768a378d6d7bbf046d9ef17599e9ac5929918d8dcd7b4d19e9073fe4ec46e773c7f52444c323d3d8326f4a30f8680d2f748f57ae32c8f674fede8472db82bdfcb182c97b58e62664749139da011cc73828685a8c367a5b9cf8e7feb0d6ceeff13e72758bd004978c35ecd5144f228989cae6332ac486437cb5c57d430756f865253be217b3515c73df405b7f39fe7ad0b8cf61cffffbada0048b1fb4acdcdc38b535dcfec356a6eef6cfa7a588fdc86f98c854ac64c7bfaa96f5a32cc16e0934baa6a586b9b2d54f13ba274174aa1dfb3a81b96aa4d666f789b5a6bcdc0a6a0179adc9b0f578a493f6efadd2e7ce3951c9f249a5e8de7edd49a742d55ef1abba19af8c547855e0afc728f9dabb499c9beeb766f57f9cebff263f3f4d22302cbd3399facc630991fc8f28bdb4354762541527678bcf61f65c241146c426d23b9bfaa6b7df18c97f20c1b6125bf874b1d89475852c448215db0eb7737f91480e8cebd9a0871574f5ab62d9020175ec6927ca0b54c09818e42cf92a383172422c7dc1831d63b0c295de75159db8034e9e07f7b0b910c3c1e5fb66b3dc523f1fa6eb4910cb89a6c17562c83ab4c18d0cd7e0796592a372aa409b1c557347ccacdc4644a119064d06dd474929d1c6fb4d686e5491ce4bc89a30bb4b8c41bce5157dfc1360823b1ab618c14b10f98c25067398ea7018c278a4b3df31334d603b2044ef187cd9bc6ce42725bd962c264983e9e18155a8b9c47143d70460a26a56fe7658c1f150348c6087ef758ad167887860a007a5fc37358d43b5ebee820acea474f0ac07b76802866199c61231d5c747c93774d2c1e0c1c67e6c81b82752173e125baf39b4fd19a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a13322899af659cf1b3558c1b5001154b625809ed89aeebb89e6ea7d67f723d045ab05715c42355da6a5c8dd39c8abe3037751a01ed1c7374919f3121b5a52c53d1487316769f80721deeaaad3c90f76e7ae9e12ba92b32b5fd457e3c752c2650dfb885771cb77ac3c785a8c562e6a1c63c2a55ea47cf8b90eb8225c123c346452566235b2f31823a33521e087937a345d8d663eeaa05658917bbaa008c2e335f8850a90a326d0e66432f44ceb8289e4ecb2d12958e984072ecacb88e1348ff0b55654acba5b54971cbaeba88ec4b91a94c37192fa982becb9f3da421603b61a51bc8e36cbd053851c77b1b926b17a272aa9023246b02b3ed47f66a00bd5684823634e7ce58cf8f306e35b1e5322824d904801f0a2fa7c2bc9c252b0a56b7ba2ab0f636021745a70a9a43e2b0a8d615970b65309624b5184bcc30b911679aedd76025fe3908fd67897b0cf4be5a6f5413d7dd98564b23e42a93e4aa8821cd45054c643edc1158db6b3deb13fb5a51ebd1a8a78b87225a7338e101104c4a220d9bdedd48c85a1c2dae781a80c40e13b87eac73a764201c9b760ccfb1ae392699c7039d27c39362b27b8fc6f07a8a3d4410f1547c48a9997f62c61074452ef1515f8a649ebca9437205a4e8a61606b41daf6834d671f4d852c0c9c4096611648c6a3170678b1537cc1828d93580c9e5849a9653175acb753f2be7437be45f6c603e485f2ec301bb42b6c37c225d7495a584ae231890ab5c8c35c268cf4bbb0213c096019319561a8a6947637aa40d006b415bb2cfa2237e0890b6a3bc134abf8f6585e108d15940f91f4bf5b0c818055b21dea6e63b553988c47f4b94e7cf800a493b4734705edc56a4b6021c629500675876804cf0b951f038a5c7fe58e89774ef2992fd7c63099d352a7d21560b788b405709861817e59a96b3a3a83cba803b16934331071905bbec6532900155d8ac88cb32e4e21a3bd3a03fdec325a51cd2773964e6784fcf1853737aa64eb67564727272661abf84313a57a44b123c65509cfb7a6f6641cdcc3b57fe628c7b8192db44ffbf5796a8613b1fa126f6076883c783dc24e2a4464c40b3a41ca70ae87620866cf4fcb2bd204bf5c283812ba056ac0c345e379c4ba24d750901279bb2f3a16f612bfadb35703332c7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377bc200e4d315a30a6bcc3256f9734d06e9779caa5442a9a16069081377c76e75154368072dc446ed6c8b8e622a21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543546284eda2a26b47f05b735bcdb1202220076dc8b4e4b9f853533c8f6c7ff38817ba49712835785f17f14ca01d0c1c1e98810fe0b36e5b427157b9418449cedd641a4293c85c32700102acec22ebad98ed160a5f027bd4cda57f1f3720a12c134654dd5e73f829676495390d0e7929d6034e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7a0021535a6e25e437d49a780698be22ac9953949f571b85a685725f8207a2b0ae849b601ab91b159b3df4a154c2041e776070afc42969322380917c97510799f3149131477e16663d3174c7c1caea788535c6c005a64f2868631b31b66e205fd38c1d84542d0f1b578f58c9bf5a0faeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539228a39e87d531f3527c207edcc1db7faddcf9628391879b335c707839a0db051a88626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = b15696acabf3f5c71c09605df350f98ef9897474f241c7f7d16f7a69604358508458916d2c8552c704cb6e0da4305a11720a2b59a6d8190fc3e389e6551e7c59578fe2b05d7591bab326d894e23656c6b5fe4b7abd6505a8c26d1df8b44a0ed53affff9a585fce86da3b3ff22b1fdae2f6d255c26535f61694d50471f1d84d17673e481f4e824c82810ce8f2ecc9bb3f5f07bf1430e7bfd99fb98f3d2f941edf642d7b9e73bc1595a04cd949fa766468489f402f92325f6d9ec5d696e0fac2c6a37983a6451384ce9d9de448f15874e530943e8e0fe29960587a89b8052c9d0e6b0ea5dbb734d2a9c05cbb6d0c79f4a57db5afded6a7df0ecf47b7a31deaf37dfa1dc89722a47b40b4a50c7a2f32e8ab3da973aa683c0a698294ca3a045483175d87786b47f78ab0295b8267edfeeda442c351a38e95cf43b08342c67d0bc5dd5974f6c5c003ea31b5804a311c29eba17bdb547a629ec83974043bd03a37d0ec7ff39de1dfb8e632a86b26021e753e7dc731bc4ed7e7fece78b07dff5e8775b2223e19dfb3a06a1865ed4f08a84544492504f2962e005fde5de6e4ff48994d4ff811ce31e3909803c3534c1c6c6ddc9e1a43c845e7e7e2a1081186bede4b5bcf1b80b13d218a4ab446f479e38c1de4a594e0f20cdc23a9ea58778cb2fb104f1dc91ba5c17e74004c430aab1a3d1679daeb5082e517af6a4e28f564441b73235d084a5831cbb394cecd997fe08b1b4aa995bdd9726c04615859fffd1c9906fb2d0401ed6f591e13c6e79ec5e862079e6dfd3ca688fa5ac7f8d27907530549ac71fdeb5f869d2a9b235a0e54b3b866021d6b5c98d1c6c0c00489995e3c3496b69c76338ac422c9f94158ed5cf9cc6be93846034d4ba533a3422c29d675405ae853b8497dc912f4a83500c89db76bcdd7046d9832fa3d2bf3d02465ebb4168035118f087ddd47643d2db71f47419aed973ec4384866d45e1df216eda5bf6133f84a328c1129621ec1501fc46fe3eda460680b397a42a4368eb3dc88451b2b616eec5f1ec05e5bd2084b4945d20ea8630d81492c78cf06a78ec508a0c5713b486021643266a60d99744678e598b152cf1829897af720c18eb6893d8b1f81c8bbc55c8047391a9051a6d0d65471891ac2dfd8ac984aa7aff3974492b751fdc5dea1396886e8c94b9448e1ee633f6c2143552eb849c6d7e72b6a7c8121461544515e346d69973111c924acda06470b5df2320e06b8f1aff413f9e888436c31378025be66726a0ba559177b1137c431cce1a6fb00de36c6afce92f11bc75a885fbbd9b108e6ead43fee47da311230f922bab93a7677711e97ea4129802c5dff20d0d9db97f882c63379fc27d08a6fecc288cc06e257654b388e5018801ff19bac2c9487a5f47e073101dd37b10d43c935119b6f70eddf9ba5149ed64e8c129d978cbf2c1a306f83a6347bfc445e8fd645ab0e4b2a939328cb55a7951a3a938a06aed24ef32562149c8b7f2dadd75d2db3782b64f4cb1f56a0945277c9c5e1605a0c0eb65d7fe3421c90874bb9ccb945ea74c997eca73c94059b77c7c3f08dd6e5e494e3f23399f2fce056e9f130feb6cecbb3e8dece49e5673757515742094ac382563857b5d412d7191cdc5de0681c72c5daf833beedcd88e40123a617d2bd0d7595916a6894b9263b6eb91e2380154e0cfc52784258cf7320c4f02ead0b4471ea0dd0abeb5e63628f4836a23db269cee09e46f35b9de87ecb0422ad8ec6cb60b717eec21216f0b791c852a9f8a4c26167d7350e17fa3ec745b46311a671cb8d7f14885ff01bab0ef469d0850fe807e70d36a4b736b2c32c676258ae7d553dcab8ade6368aa23179778add214dd9154f510f50e5560c65fcec35e87882530edc65bee66b25a535da2146e14f8390bcf579c337bad974575d5f09a8768883f9393a144171feb3fc663eeef138b21bd557abbbad2c0224341fabfb6c6fdea6f3c265e5d8af169a964a7a86a1a0e222dd6371382079f838234aea8ff6e2b894e04a9a34cfacab81b0704b14d7d109949c68644c015bc2f26a9c294287ecf152d846f914c0745ceb7ec3d36ad9d723c15f89e2d8fe2c18e11180d0709d7002a50f87d1c73dbb616fd8de30339d83da5a8ed50321cc12f94dff84d9e544f17ec34a60eb414b2878cc1a05c264a066ddd37f0c504f0e6ccd0f311eb5212de32e9d655125e4f4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 94b49ea435f6945f45c45a7d580b6aeff8bbe0f5342bb8bd266df12ad5935f45cba7caa6e09e4007fba79e9946c9433a87afc4202bbdcfbdd8af78975e76e9d368f78763ddbb83e8a63db7b6af7d24258c7ccaaaf505ca92cb853a68e8d4269be91fbecf169a05f7eeb957557787c2f3c7f31538edba87476b157a06095a30e5fb388ac2294d755b43440aa3edf8b7d9dc435b415a7babcbd4ccd93cdb0dca20bd90647bed6514813368a794d38c917e63b69e7497cde8c519b160d5e44d74f44966f6e3a5ab9ffb8d8e3e68d77599a89aed13cd7d86498d88eceaf7fa7de25d73fd4b62802cea903bf15e7cc3eac350bb63adeaf9c7594844795a9a6274aa3edadcd10891f05795a77b30add76b6b1a35338b815679dca2faec9c3b602b2332492531507f6535b36dfb355225d37e7c85be15a5976a8a6ad5efc35d4c45acc954368ba6df88a47dbb8c782336f7ea507a7cfd26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b79f729638af6abd3e6db9b82e678a42969fbe770fef65723f77da6437c21cfd3601c884a9b9e09cdb1ddbbc1a675e7dcfc76b40ef6f7795e5ddabef0dbd01197785765e3e05ac38a89d1a0e8c8794685c1ff74060d97bd6de68818a74aba5d71a8df5c86f79fddf14ce5eefa9af1391567fa15fe6ecdcf9c0fe7cf09f97d8d693645a53e7eb3d85d9f6a53fd52bfb0abeef9b5a4f78da74ffacbb713357d735a744b7c65e58fb7e27fc67a5b4edabaae123ffb8bb6b4564ab4fc2dc28b4981614b69bb188db6056608ed89f658d3d9afe0c7f6d4267bd0549afae27996196a6d6f86fc28cff731f7942543ccef3856edf9ad1b2be652a33c3e038ddabfcd9a56e2ce174315e67b26dac767f5de695d8d104bbae2afb89b88f66d27b10909dcce1581a8b8888d9dc1c4ea5fc20ddad5073780cb4545087c890f6b9b9abddac9f3dc5f620713c8b5ac3301e8715ac39d13084926e841faf4ea7bbb7913fed680a78c0c363a2527f0b2d69467b6cac5d894f96f59517fa7cabe4bfefaa2fdcc75cd4f892cec6184c5f962b9b73d663b7d76c1ea499d538bb45a4caecfedc8eb93bba5fcea8c93615648fb112dfe331eb2dc1566351f80606d590ec33dbac8dd2a3bc05fa8af514564508efe005cf0f799650159c40dc952c9a54c27f8e6c3a6a95efbab24b3ef6d5df300f9baf88a46644b4df9af4979f8ddc314f5b9e75a753a36510b87c5fa95cbf36e1abef245876003b54d4f0d8ef7ab9d83c5a2417de4b5cc33b6167f4c55faf55d84b85efec19556d83bda6b9dc1aeb6da734efd8a7a8e517de89727d94ff950af2b503988964f0aa227d5f3487471d3bc905b6672bf2dbc7157f9b7b7e479bd7a19f777dec546c624723af7b5f7ce42274ac5652a7c2d7abbf127ef2bebe2f1ecc87678ea6018d6d60cf39e6a8f6424419187bd22e49b8f27486ebf5372ce69b306ef8123eb57659b113da95989dba5d642468db1f588326db9cd02af60b21b8c4216fb883854fb173ea86e3764e4edd6b89468c7ba6d4f36d2ad436b945b8b44d9840f3139293fc49cd7659b955453bba08bdeb5efa91f594232a47c65c66e1c5c827afe79925c55ee4adb3f64f3e20a862067fa688cfb64b6ceccb5944d17e07648ba74ae9fdf6bb3f57c5fa079536c675ff17a6dd22439c8d968f2f3e36e4dd0de7dc5db6aa212a63c9e26f22bd39201d9b64534c87aac3b53b357bbe5f2660caa74cdfae4f45e1b9868ed45cbf8533720f99a138f338b1d7647ecc8008ab2ffdf62513ad59ad6d73264817e08332f9c8031c9913f2339169851d7b746ad9a8f2f54633d57dc337630235da3255687def6ec2625aa9cda852d835ec95c4348c9be74473049abadd65ca055239d85dcb11f6f97e1667ae548664d6bb19b347288d57e3eef7369b5fea35e506765d7ce5f82cc4875fd8c67bf29accccf96e26c4b4ad8e3877945de0a52c355526e34d4d2ff62a35d5dd64fbf3dcca6f12fea5a45b77c4e90954d8f419f61e4cf5f90689a578db146fc6b1b86d99f6cad427c6ac438edb70b34cec467ae45e86e6e95574935a1387c5dc795533f57482a7211fed09f5337d773b2708c694359a51725f168775695acba0735be594c8390c760070c4912e37ce33b3bad965205d918331371de92c27a1a5ece876015a959e96aaf3b1a60e9e77e46d51d9d85aba374263bbc65ad78b2d5a53cb909682aa0bf37d49d172bb46a0271d30716cea8aa095992dbb1132e81265a29435ef2c51daa9f27fabf3a799813e67efca087ac12247b64cc0ba15a5486245dec1648cbc7aaf40805115d78f6687c47c553d050f1e6821b368f98da22f4aa7d738a81b298a81bc43e16c8ce1490147ca83d2dd98bb918300a26cb431c99a952471b84bf6118a4d5c0a898532cd277bb4443cd7b6924c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7d31921a66403c587c165bfdd341011d19ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fba176f9bb8dc7716cac344684334c5704d5a54c932535739948acc61bd67b581f75a2169a89a11076274b10563141722c9aa9a34bb28a69ad677292be84455b24559cbbc0f347e7b36a45555a8336b8adfa07e599633f5d1bb6adcaf86ac9e7885039a3c1d308996ab6c966f017f8297009c9b4b573b70da8921a0c256a9a03c0cd6a4f72c6edb5630b1219c4a3c30d1f1586cd936e3437684ac60efa62d0a345fbc4881b24372b5692c101195c66c3ad647ca04d37f91f813a7a6795b371a574565e14779772372cc4a79c40308eb1233ed643808e939f27571c72b2f719023e048c4d15c71b3e116482c413a816c6d3a3877f862559b4afaf04df9c62d02cb364aa2adc64078b8bcbefe043bd6f32ff62b9555fab5c1009cfc102b9b4b88b8a93b66e3a65a62b184bb5406dcae7b3ab6047754bd215251ebaf102356ba688095a8c9eb1a9d8771cf60e864b7b4a5588843922b6d4a7445476997a6e5620a528510439b02a4b0de9c147bb14433db144fc9ab4b4128f7291a637b7e609a7de058a3b58a17501c833be09143244cc7e2490eb01cd292454523ce413a6e8cbb67a464aef43912b4559651258b9b812989093540dc8d202c652c71cca1eac46eab3f9ec199eae025b153348a600b0e373b7cf2620f5560a3c64c15ec85b5e81c0bcc4840466c63cb124ca45994babc31f12486f3712d22b1f649a07b192a2451cfb079ba179c2b857c41c4f8842a916e06f9c6a07cc6a4d2821401a65060688713ced4bb72c08241aad91b50bc1b968bcf3bda76a8e1b20060975e8803dd7b762d9a49b988568cc575a6d34bca13a0ef701b823296ff114efec9031d79a20f6c640d4519a1906183099926d44e88703db7636e19394b2f65abe9a8712c868697b46871d830bbc09ae02487e8d59537c3841d5b080f503aea769b0335493b84b94c4a498b1a6e6acb578201bcbae6baf0e960aa975d3f14b5179051d933c4109361f03461f265274f72416df79d1187b6822a0c38177a02b4afdd635324eb6737c11a631784916452c700d09aac42ea2634abc68bd3f41a2ca679546414df2314d57c2b318bcb98d7b46fe1b5a7e3af1b2047d193883cfbc6e7d29049fc9c97b344736a0a48082b0a145aa8776125558df656718af59964d42f0704318db88d1e91b840690b96669c8851bdbeb6043f04c017b59b289bbf550a94d0aca4aff18ca84630a99b82711a661e8b202b976e65f53b5db52b255a88692852e06bba321b4de782b5d951ab02eb27098813c98b0f7cccb778b08704a068b4d48afb30274c0759fc5bb86fa59fe61688296846b2481e18a05fb9c02931570596ec436f570c187159b25c1f6341163b79670f62334c6b9a7139044a8bbd2b5183e0f82d3b6666735a94478784aa6168d0d3272876b5476b64f7932f3aa4151ca9b604bc7fd5d1395c3708908015b0d2c8cf04858eb23238458f70f964687bb2137a0c75c06a868c3490166cf2bc3afe9b3746e40c231b3638a3558974bfb0603cf4c28c21003dfe87b3eb959dfa715b78ecb71bf404cdb2b675160138a46501569918cb7deeb0489a72a4799a1a4ac625d5c6021f51c357895ccbf26fb5aa372343bb1c516ceea47683e5a4d094a3d5188270811751fb1e19d68ef637227e491cc6387760eb5a810b387f596aa20741c4627b1c13a303d160423bce1e422d929c06f067adb7d96112f1607d3c7e43e7aa09ea248526c6881901852123f1b734a8c1891261bae6e7a23dd5296858b6f7813196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2c9ede13be3dbb0edc3ab08226cae11771ff4c0b04a564b64a0d9ff10e373e986003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = e0f53f918f1b56e14a62744fef0e1f7a5a257ffd32d0657c3090cf56234d18b278df87a8c7d06693fc38ec3d913b77a7f21dcd876225f50b2775694f5446f6e9bf9f4f3fbba8c6f1bbe1ce5aea4f27a83338d7b8a89ae41842ef990b4d9fecf78bada42a9a61f192f08d7a34a9519a2e945213b34b4cd227ee9246e253a9d2edbbfcfe2f723ab3477e3d78e73b607ecc0b644a0bd15d6559ffad87d7bc49c92cb5e606bd8f7a634a105c15051486c58e1ebc0f21b68939c998eef4346a5d3b134279bd9fdfc5a2ef2507d0491718164ce3c8e03ea769475f3a419f01ea5b2469084d8ee605d6e4d2b346dd0e35904b40933a5ab3b3c6789c9c83bbb00cf2e328ebdf0f52ee1e5462f2399d68a798ca7b04951af96aeca32135a6572dd16360b9d9124e43f0b285197f31ca4454e22ba28963efd6cb22fd23b709c509c39ef20ff7a771ed8d53c2f130ec64a02ff0ea11fc456a42f703977e26e143d8e07d25147554081c0716ff78187484b4a4331ecea813f6851531a942552a342c4eebbe85697927d90734d83e2851a87defdabbaa247f1eb12ac2f6d6fc375bbe89abfe37c477eb47cf9d00084fb97d89ba8ee77fb9e16f459591d8e230840fceec0b653d06e01de59916061aaaa72ad3240c421494af68491d4bb2dd7934564b1c08964e22438ae9779bb72f22c120eddc24676e811afe4a38b9fddafc3787e9c43bd83bbff3cbc8872a94c3c84fc0aa2b6d561349bb5cad6ce202b0dfd6e9b65b54678332820b075e659909855c24be66aba5169650439014a5334520f74a6ecb117e247b37b5c44f92a3a2e030ff60dec5b0fef6389587d623c00a016ceccd0ff7081b1346da1af19b587d39f79fbb8c5584c6c8d1f776ce8de828fd6aaf0b7bbe7074acf01a3595b4bb8bf272fdbee1556c03db2ede1713b7f4a08ec16bb99d1e3cf17afe9426f3adae028d6f057be233a0ebf6dead93f1ebb4548f8c7da7cd0c5b9c131193545d164e51785c09e1fb8314cb874d5b8b408bb7aa47d74091d6ff60a237cc9b2e7a04a6982da853277bc59fe26f314dd63531e8675f28296d1b1903c360c09b38af11d065056a38f7d7f84d77503caf4197944e322f8b5e32b6fa856e05b850a77bf21d2d1875ffd970e325ebafca515e11732b117168ee814e7064eb005a1d90e1591c9fdf9fca1299f47c137c0a57c06cfb1172482b35aa6b7d30804f5b8ed71123b0c8bb49c1ac3e4548cb7e9e30f7fffb07a2278533908713a28833b9a5469e119082d705467ba1a0e626e607dffb03ce500f2be1398fc072f67c673d44b6f079d8005955e965dff4d8af1f36ac30eb20b91c9b5663fb1fc858e61c73dbb6bcffd2e8028b237129bc2ca003c3cda79e7d885787877bb5aaa25c91386331549c553d680bf2e9bd47ef502ecba1326b6bbdf6b75583e5d7b7f81ef037c8bc431df0bfb7509024ce05b21abfd25b4aa7a68eeeb0075a0aa85f6051e8a0f93832f1b049bc5a9dd44eee20032a76af3c475052bde457046d6c64004ef10e54b501a8407a0201dead9334209e0be7251c405594087178d8ba6ea13cfc36ff083159ed5ecfd0c72e99f3ece3660fe269efe32b55108ba712c43fc6d7bcabde4875b416c99035afa95efe1ccb2a1934efec2b15a70cf5fbb5b9465e88b339e4f95b2ddc3eca8b6e55a453345daa5ec70c05c69ca36def7d9024806f7849487338b4f86ed5fdfb3d5ce83ff868d88fa0b7f09370a1963b9cda1efbbdb7e14d5e1b46b3ff008a01970180570030f6b18f689b5e2de0d552fd596c81e0b2a7569d701576f86a5b84bd3c7633777a57d1f6ef39bcc8dcc777063b1035f95713e072a920a8a86f5327914eab7d1e13f35a1459423c1225acf6c658e68ca156abec8620f2c055c125d9140442d63d95406b389f3ccad86535ddf7e9b8b4f5fc61b406d97ba20c6b550117e166fc7e4b26555139154ace7157964e0be9b3a0df7dd6332b927ee3428809cfd35b7e72cf8cef5306e4533749c38296ee19d0bd9a36c2fe56fe3f0d6b7c31f28cce14ff407b8c944b5986e7439a9a2cb73e2f7b20c3b0a32d844b7bc529304d21fdaf56a00282909ea72d44116f61367a2d2f2ad888bac956b80ea070677edc04572f547b3e9debc96e2f983e0fafde0974d6241b28a75efda0441d60dcb90592f238b77c429e973480000952a3c4fdf6d2f2df2f6b99 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 734d8d45cfbe6e83c803eaf846d852dfce848ef4e504b5c91f774f6f6efb5107eed26fd203c486f73f40bab4c1dccfe2299753b96f7f9c0fe27cd6a83bf4d75a385782ab804b5fd972fbf5bc553eba8eaae7d7a7162ee3395f9f6116c10c1dbbc20b31c326ed4ccea5f16df20b5584abd6a546ab51aabed120ecc1323fd502697e9e6ebdbad346fc43824135692204b49b5b377b97db7b28c86956d77b2e5acbbeeabd95eeca479988bc69ccc9975ec4fa345f3c525434bc594218aef123957dcece8e410a6d6b9eebed9adb4135b56f4562f343aaec34396cbd556d7962679a76935bd16b4b4badce4650c55c3aec9bc2e85b548b5d3eb891b6596f0c54d09cdd982d98bf81ac77c8da98264a719cd8568e58f79df9c8e965fb94aa773b43a7084fc75f14e91585f551347f00447d72d934bec553c02de4f4276016edb4db77cdf8c546af05861804a5b7e9f838744511ac6c8be55e883acb7775b98c4b4c9c8789aef3e7f90dfc4127a6ae879d03ce3773bdd3938d41c53351d8e7dce5abe4cab5ca31e7e7f7aef9c8fabe4668fca5298ed166f09c25bc5797deea44f55deeb4c436f11f957d74876dec169c4d5e6c8716b3ddec6c3f7edc32fdc52e13650f1bec711f4dee37e11a76abf08fc8fe3e72d564e21e6a87e9d3b58f1e379cc8e2b7f4b95d56e04934ce75d7e5782fd4d7c46aa9439836453bdb7d9cef3bc1c944e995ff5c48b5c80fcc8a67f3e6c53ebd303bf0904456b3283e9caebdde494ce9f8a3f0b432dca69d0ba9c43d7d3e1626f72cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b773e822d5f9fa48835f9ad8f3236e5e96b9087d7ec9f36fb6895ef0048648adf5c933fec2759c8954dce7346e4b8c7a06f26b374cb4f8a6a7d67da521eba7233cda4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d0a0fe3c943dc83a9dab2db7095e7d8b6c3589b09fafeb3e534646538dfab023887fc286f00f46f8a46d476998e4fe7315f03c2359f9247bba2a15f97a6fdeaa9cc6158458e240f513274a2e3359d671f6f5fd44d348ba2b634642faf6c6cc6e6f65afd2d8e9abaa48bc565ca0ab67e6cfab112aad145deda003b44bd3879b4f6fe0ad3a58bd86a713dbe353d9f3309642c0e7b0bad3ffac4d12b36adc49a95ddba67ce8e306ef6bb20b546bcc55eac2b815fb38baea9ed6ae7aa87e4fecbc740cd8e6a3e04ff9e2d4ca0177cdc3dcdcb97d386d3f0005fb137578b03aef5bb5e8a5b887d7c9d50e00ee44696d8f6335ea81a59b87cb7547f4ed1ee59fa57d9ad0e8a31194247a6a9c65443a35ac36f1ebfa6a8559d0fdf511e6ee5fb37800ad4dcaa77847be8c04894e50486acfc3b8feabb8cf860d7acf734b7d0ab83e739244580653699c5eb7fc440b8dbed6cbe36039ebda6ceeaeda3c77a25b40f96763a47f51266ee0e5f848fd6a3a834edea49c4c24692cb43aa22067072fac2dff7898f298cbbee7f9ca68a1333f1942f95162aef32ce78943dd4d17854d7d9c69f6640ef2e67482df28029ea5695433763b6cf3b86756aae22a37f9f79f0c46ec2ac68a7e11c8f5505af220d651595bf94bf644ddc8d68053cde98863a3ff30f89371683bddca6bc63b8c61ff4932a0885223f34d60d4eea2f37461e7ebabc5e149a5184a69836c69670f8eebb94c5abc7e1ab09f0e3a7df805b9ed8de64847ee53b39e1c8ffd18609da08ff860277fcd6c383eb3733769f4e833ae5634ebc7c6bf31d74c4953dc1d5fb7dbe49c6f8ffdbaf245d43c9b357aebe2a63ba24d4757dfa960eb6ea667eecddaca48d7aa8850fb0fcee6279445c8e663db1d8ca70dcae64def0df1c9bda547272c396c29cc93f0c3f002642bade8ba0b8719824dc93b55965f8c1581f319ec6a95b3841836e8e09fe34dec887334d7de7ab934555af4f267052fff1c4d3a0471bc6e3166bc34f70efc54b5f9358d83833c295b1a589ec6bdbd610fa33d49a70232488b37e50f74cb99f3643d5c6acabf5c18166cbb5ba55b4b78401edbcb82d5ea569edf608d4c464c54a7f9faa7c9b75985088c8cff068890425cba5afaa617c7d416b77e6d6e8d309e22f3b9546a99091aea499dc613323c07719f3a917b2aebce5aaf9a7042b035f126c4fca9e059972fe92c9f4b3755648b5b2b7784d55a62e9b101a7a059cdc2f3f4b8888fc3a56cbb1447673a406c78e9a045df1be84da17ee2350b64c0d3bb63965328d16b3c446214c58731ce3c405d3d251ac560d0d9108e3bbb268c6931fc49d7b454594444dae401b2fa3011bf3c697e67ad9c1540ea945ace6c98d49321dbc36447858d783bca93ca67132800672513e577d14607cc046af9bcb4896f2bb39a0208405b3734505b239967ec72f8e8b0c2bf06228bacf834029dd123c83fa3f8f83892b504c1a11b809a9acc494c5e5c79c18401a41a6af6632c11266ae5821b3dc7c263e1b5e33a1a7bf172d6d142c79782e20ea38d6e791ad3b86517681ce389620562bdba89898679ea0c748d90a963e738a3e9968f3648e984c99f0e04c952309111396d112523959b9baccc43df715dc94ba3253332ed27cccf56f5812200e8c7e2a11ae02087e0fdc4389e98eb0ba5693cbb79680a6124074d3c998d911ae4e142296c0ca245719467402124574f8d271624315359c7842c761bd6057b92b4640a1703200cedcacbfe0e475f7316ccea74b74257e37c63035f04a880910bc042802332ee8b3c3612290c45793cfc5581b92236b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab999031d470aa948665aef9974df5a2fdd93bccb74762a0b7c2fab58430942f900de1c835c8b9cd42d521e54c434fc240add0b23ca1aaab0581ed9a593487b95a16353c0c7adabb285c85105a667af674344c3666da142049413973051268d94cea41c3cc9682b791ae17f0696df29f7f559375965f817a8d9a3297639017f5624f9df1b259412f89a8c88a361940ec9c3045c4a78364e1e06fa95500f5ec0704a365f4698b2f26a7ee348806b74e1579c2a466ccea209e515302493443f8ba9e32d04e03a7557380c7bfc83f191b84093c98aed14286f762d3b5513f996481d5445c7a7c931c1b9b52bd86e0b3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7e40b93b5108861576b3594966c40860f74cc58b9bacf51a5db6ab2d4ca43d964ffd831130b21457a08af7d8060f847e3695b8a7e8c9858a70d521908ce1c38c0713469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af944165dc9597392a6fc2068297d11c39d8648f550a7d157ec4b64c631a7ba7b94c6cd7083e21b149b484817a6f93e011a8e76931da4921e08aa604756c0bb63f897afdb8c6112a4ce21b2cc1935dc6b38b6c4473e2b0639266386ca988456ac843a1084c220b74f72b18199ab17aadf0960f50db4dfc7bb3454a9b29e74b09c410362cb8a5516e0546a3b09356b520a303e284569b2df6d263ead36ce75c82f6d141bf7c3e5b87b3eec630fa7a65a4c58676181916cc23e0c6a0339827571930bb65089376ba4bf60f4ca71d7090614f468732e60989298384a93849031a989488e144be739a78e1c49cac60af115c55a6501f010c100dfabbb462b1b3b6469c8b0d8b91061bea5da74a28d17cba84f04d2232076cc91c8bb21fbd558426f99b00e13525e37c23520698e0310c8a53c6b36192d82837ba0d3ee27b059b3e8fa1a315b64ca5159de3d9be0fa0352b511d1a803c79668479a1c3561a8ee6f7aca9ab4c861554a5b81b5e6115c952b3239595b9782fee01b869380ff09cbb5784811966b864d0414249b7dd0b53a762155170990911192e37c6c7263be626084118266bf7271356bb66d35aea64c5ea913db432c3caf989b0ec702139504fea41fcc782808bbf26d3b12a962d2b1a142c755fd1acbb802ac9b93713ee71af9d4430f240c7fcab059cb435a8373633417e79106a274882f5d40a4bd732c1e8202e41131497721792ac464b3b26a6456a9374a5520054e50cdb06a32b3973aa948a37e4798544020a7ace817749cdaaab1c7713b467a77593c034c20de0a9c71c712d6529820a5b3bb4e76202080a5e5c7ca86bb78c392a39aa37a91b4e75b3c5f2e56211358cd5aa2781ebc548e21e5351209b7a7d871a782da1306883a4b6b070a06b97639a3ca3273d1218a8000b7e85d6011000ad018527a25059c2ca252e5726629b0800b85ffe02745e9199a705d0cf4879719a53d33a95b2cccb52c1c9655419543aa146241b98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751ddff2546623aee72025fb6746fba736bae0e80e257e66edbf09d8d4dc11049cda4e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = 56211694d62ff252a094b42aea2280838c673cf1dfaaf01971185b9a4b9cf6a313d0fa2a54b11469be2f0534e3e77c13a9af9504477becb0a49d54abbf3ee8572873fbf5c9ce30b9a4c9c5f7d145993bfb146400254335f4cd8099cce4b426ae51937c95a6465846552ec9a321df8434836961a8358909ad50a976ad4ed1d699c516166ea8861d0240692f47d876a618a4ac4868d6abc7843fd371f8437dd3fb66d914006226f4a528cd96100570a18bcbcd3435ac73a7c9a05855a878be5bf6f6d3d279843cbacf6fa788c4ef800b18747e10205698d294c42e32e7e325821da1acf774dbd7ef1e10e1b143a0be35259937ba479f2b16d708d511fe3bdefb290312996a78a106d11c5d060b61d99c59b35d62d402d8b36f04ce5776c53bda2b5e274f3ed41b82ea51a48eaf990f31453fbc12772fe780f53168ca3f25931c8b4a7746fd7777112dde693624acdce62eb21a0d1d3fb1208f4f1a7b8e13a6980bd621997a73ebd1ab38e5249d58e4a3f5162163a2d992a28239b2e3961e50d741187e0383ca185f1850c77cd6ac5121d2c5a740ae2882695f46ce169a7ada95c5e48e9299b2e9f0333b9985d24ba875799fdcb7b7e784903ee3b4f1e2f2b01f8058bdde42b958bf2e0fb36c5d933c1ea6871af0a9d3f37b9f23cc6533a66a5e543ccfaec7d6fa4a8b8ab76ae0d283df21d3c2ed3526ea0907a331c4363916faf394db5c6ac6b1e53721a0e4ffe2b15803cec8ef4cb29d288551fe1b493f89ad2f15474559177a7f919998f4c3d11a5741f1ad4c1a3ee3b4f27be7217918d70a0f43c4f5a409e41d90b5435e50a24ea28776d6bfef07ce60cedfbda357d828283c50162880dca807cbe8e37c50e5925c282defd6ac28110b40b51e951d4943f53a085ad3d040a061b5212e35d7eeb25be82a6d787bc86d5aab30f797f932166f46f6b41798695a188c92ed86f5a5e934c002497d824194beffa9fb82cb6e53a275cf7171f32e5ec91755b1f083773f970ce7b7b79d9af71c970f816b990e046ef30186356567fc3e4f1fecd8e4f50e8bb77f2615e6fbbc40b30d3dc596825c26a7b91787eee1ae8c019f636bbb65fdf32df8da0883449c20f6c02d8562de5d6544c55ff8826a1ecb976e28695403ac0c89a2f009d0532fcc6ca5780b423740c9f9ea896a5659e633ee04fa914b3a2e2092ef48ef13f685046bc6b354c1b26314420354ea3c07eb63b64e4e102bcb43782864e0f0ef991ef21366acf36db469c4eb23ace9b8d9de933ca5459bbb4cf1f31a64b4246e4bbaf2bfee841c4684e005a27503f56bfd8ca08251bc870caafc7f79c3b206f7b7fe5e989417608c24262832e359ab429b9d73b7357dcdbc57aa03c3572e2d7bd67c58f6c8a1546be3d815395fd4ab50a626b6f3b57dbcf40858382f93ebc9d8db4cd34275affb174d8bceb504ac81fc5741e082322fd32d9f08e05936b00e035c0582d310c586e03615efd9998da8ba8820bd7c7ade8fb918118af7fbc4d40f4e5739891e294d392b1d4e97aacc170b8378debdd5cb75ef2a60a61685e3f83469a8ae3185f057478363da5a1956807131fecb86f68f0884c2a746ee5fe4153b8b9477c56b412a4a82ba01da89c7bc25b8b047e7c78edc83f36220d2d91055f967339bf024cf168397991d58215543fb26fd5da4097c00d1c0a0807759a550ae4139c5015269d11fe013ae15cf60fe5cb2261f4413458f9e03b1d53d874cc2ba54a21b2b91fe81d2338da088e23f190a02ffd62de52d0e618011ad8e0c83426bf590158c16894350ab9f9e1db42d3bf455ade601caf40e38f2d2fac40094b74f99210d3d671c7b801aff1023c6b76453bcbacef25d164ed3109c7640e4bc8574088189930226adb6ec7ef902bcf0ac9df59e55c0c04b568408aaee63c181b3a5725c3a4fcc9003fcedd69ee93f7f1505a488ed929fb5e7706502ab1f518a3caa77de38cf42e50e958c79d0bc93aa2de53a1c16d683d14ece2b5fbe22f583034b2e463e46bdc0d31c850d6c5497d5464a0ce78942e20f4b3deeeb2adfe210d0a2873575448a6b58cec75268f83775beea3bc1c73e80ed529c99056b0824c1cfd7636571a972178295de1d7415ed14e64f361764f44bd3f0396db4972f146ac0779441d73d7a5905e890dd22619a3fcce078ba66b2dc8b63a79ddc9ae148974844d84f04bb509fb79c73fceac5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 549ad1804af31ca6384397fabf16b2c4b9ab7407a093b354f898fc6775bacf2931de0a501c5a7ea7ea5c3bbad6739db9fdad59d69cc6de9b772dcd58470544b65be1abb77f490746384b83283740f18dfe18dd46759b61e85d30f187c2293d45b22b4f9f3ffca44980dddda42e67d4504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac100da6f69f770e8d82f6157adebe70a956456c86e6c856657835970578b35fa87d8f79c2ae54ad378f3c6a13a4207453ff324f18de3d43b4d0a32dfb707ff4e70fe42cbe4a32fa3f10a446d7944428b66e0e1ad4b204c5994cd3c294927d6d540f836572793c882537643fb64e1d9bb7273147a878ff1bdbd38d8b631d4516dd824d9da4e249b4ec9cdf6b67fbb72eb7a84d89de4b49eac5a3cfc6ea5d6b420779a29e1c5ae98ab30f0ea0b45538caae4ce61c4dffa27a4e56f757a3bdf01cd206c5bf5243e32c47b7111771daac633f3fe32af8fcbe6e6ec92b4e9d1c88e7285b84d9a12e14897b1fdc0693fe9cab42102ab999838a93a77142eefff068ac13dc4c6863f8c7036cd0dfd87be9fca5a675cff4dae4d3fb28eb770ead4234a456eb889ef92a93a0d3ada816e599d99cd8a96881afb5e54d766a9c81e8af4f15cf95283c333a0576b49c569c99450f97e4160c4cc4a8f8090bc2ca49d095ee4bd6b3d11a6cd38f19f7fb4bad3854dea9f96feea9e41c564a91f9c86dd7f498f89d06bd47461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a55e3798ec69145ff634dabd2298488299331dcd3b1b3e06f34fd297e525587888e448d0f45a6158dbd7e377dd5b63e153d93fcc8bdaa563264baa458649ce7fa5826e4b9b59e59e764ed442e43c5093a2a5bc5b835535fe7395ec556bd467a10975ce273d4bb99fd056a6ea4c5ce09dd33e9334cf7f6750cc6f209caf1f7be47ac875c401e95d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ffdac4c3fba7d563af51ff8b2957b8aa5d63a65bafaf86609b4bfe21f7c02acfeb224465e2ce78c74cb5db4c0c2aa46456761ec4a528bbfbb909fc121aeb78aa5e7a29c8ee408ae7fab4fe0be941cbbae4c3630f407a2c23c4d10a58a8e64546737e53e6e766e0f42c523f236f637b83f3905f4a7812ceb8019a808946c11a54f8ca6c16e06ad9a685edb094616b8d383a79e482c61186dc2499885471942671dd722743347de3c8007f218cf5cbb48490e05789c6a5e85ecbfbc73669f249c11befeca037dfd15994cbc450ec4d868abc2ffad5b5058429b7bd4ddefc4e273da13dba2bec9be9d3db9f90b45aa7d40a20ff8200ccb4a54e3c9bdc5b169830d55ebc7993eb3d5b4d914a02d3e83b84f3d622deb0e3ac0a3ae86741f6f6a6eef27ec55e28b975f2fa8cf9ddc37473cad7e788b4fcd3acf6c176c9c255c4355b6fc0b84cda348e9a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c39289eb84bdb45813f6f5128556d26d1017ffaffa2756e1cbd0a1aef218adc198a6dc043b1c518e3bcfb3c2488a5c02c79393b65f39990b72df74fa77b814ba93784562e0794c179549fad927d9b4a9e3ce28a339f73e3b9d3a99a151c873c555f5e3c3fd4a59823666e2bbb92e86ff09834ddea1b35fe3be3e103a020f5d4ddcebab6b44b3d96fc35c76f2adfbae25da595abf00563536ff6cec04a3b4f8fc04788977f25a6d80c78084d4c47a4697b1a6ed8d9d3d9c7eac45962d8d4cf7c7eb0f54760a4799e774efd805a9b6f5d8f47734619e57c9ddc93fe3458196e5940386951b6ed83248db78b669f596c2f75fb93fe8f5154fb24bfd682a34a08cc356785b20806952003354ac7ba31a355346ca63cf8d30b1ffffed6d4593496f066f4e5aa41d5fa61e5ed7b77ad79be4d79e645435f5d58a8148bc8fc808326fb38757637c7f875c6a324ffbf01c95d89ecddd6bb6a3c9dddf3e4f48127d510e6a94eb57c3eceb623244645a6f5b6f93932cae1c4bfa8b9c6a204cef9edeea76f6cd67e4b3bffdae8be65a3b15ac638538c5e05edd313b1c66ad8e259f037c9f4c09b8536134f09733f5c29665893d7ef8aca7a6cc5bacf7c86bac9f9754e688fd96ff68b706ccfade7e1d50b4a0fde55aea72a5c370048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f58987730d4becc9de18019e5142f94984fd0a6d84a8930bec6d96d413bbe97b14138e95e05cb05345c86b96aec66babab7cb8a2ad8f774086918795c39e95ea3e40384edfb1ad3aeb931419c1219286390b9cd2154348ba19ceb280c537353b701976236414f21939968190892001d10f8ea83ca16803d2ac4cc5a96cdee3a424c935b673732b312aa1d722f303bbd5175ed83087cf856c15364958b678e74b3618cabf82ca58befa00c6462b3c963edb4a4b509792f890b228c7ca68082a8f38c388839190942fe3ba6224c4c58fec51ecd52d044400f8eac86cfa6904aa99f47712ff29c3f73b02d2127f1c687a00e2c48bc032cad5b261b94fa44649c5b459fcd18d4014c34a3978f6ca6b9d667e5d93b87feab5c6f36472492b1dfc74cc9430d1818c0cc90dc947b01d33cb0c086849f81b570a407e5248a3527ab58074ee52313e678fd5876dce81860b4b06f22768e3e26a3ad450da516224e06bfee2235f8631f2f7697e3638d3911bea2bb486667336e4072c061180a886e45144fb266643ab524ab95baed92c1324045c7768465cc177a6543376be40e132e702318ba52eb10837f0bbbc64e10b5079a24564bb950915701a06bad9cf1f0662c63bcc1ba31985149c2cf79befb710528b3f3a1406869872be1c59bc011294ca50837852f6567f6cba9b5ed028bda8aa4ff26af2a4ae90eb03c65a7f03c61baa3008480b8a006c29d6a2b52e2278659ac2faa877422a3e0809736b576564d800f5287c5a73c27a9c1e1748b159dbcbe9f566cfb05fe76419c84321b8fb772597262d2b48f9c43bfd2a110bcc93aae57531c68bb222ccff36b2e8466fcceb237bdbc336e855755b25eb4784ade55cd54b644f6404b549a2103b31a0433363337ee7e520db9a8929f607368a090fc77aff437020109001b40de05035394a7032524cd8395916bc2fe12a7b9fa2a4ff93000cfb3077c23105ac40ed0162d8fa6e22a37f9670a4c686a93e556ad82509db3aa2074a47bd9605184a9a1f82bcdd033116e046ce58a9e639c8b506cb5c17129b3079fa96cb625115ea887c11a7aa7484c03ecb793a07adadcc25e2e876fc31766ef11379738a8bbacfd46c5d53f7091e6ab6108356d8ebcb45e6ba20d36d10b1aed4c2701f6b9924bcaba7934919c2a64d340c8e9a42a98001e75b09d902714bc47252b9b15c2a08f2345b78b97077bc989c662560e94f551c3aa7834830761dbee93d343a4089c8775ec85091dc1cccf91bdf30620cc3b92c6a25cf147385d1c60a5886cfb6bee5f30bde74c579689251199ea26a15a9388cca30ad565a83ce397e07a8665b0a9286d223402059a8238137306fdbbbc2f6e4c6707534559acfb4628f803250ed8c4ecf846d8aabca027b9471e4308d727987a49fdb68a11869adf57a6f786043243608810a6353c36cffd18e1ce8bf25512a04378e8dd7a01b5c2b563902288624c25c06ea881fea70390a039b82e162f61ba6c484bd09b703a4812535427a8843b41c405c7ca0abb8e17ef4c82589945e9bec2bbf348da0219160e50c54d965aaaa4a628079eea53898778331649a8851732618bf307491fefccc7074ca2a7a56f04309e39272b74a30e526a6db5c3ffac70ce46363fe596ad5c377c7f2464dba68d42851f6f70d4b8a0b0cd52d75c48a9cd31ed8f270b36b69244237f9da28e6b0512676145677b418309d1b491cd9cc1defd06cdf9c182ef4b33610b257d68ce0b12a3f024ae0f0113ad538ece90b4a3b85bdd99c495b0fad7780fa1804953041f643183bd7083c5969255406f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d80a0b153c8b8147676a212e6ed13687941132010a83457ca155888946c8bd8506e6301f1bb78cd9a0c4ecb73eafcb2fb7b02171885b6968ab52b89109bb2941e10683f30591c322261155d0dc7b0b1821eeb75abef6023ed67e16e0ba40c78109b45cd03bbe2c800fe4b19db4a960b3d11a45392c6b088cc6cc5d8de1275f035357d3a847313eda8c1c0a65c27a743a000063ac6a89754818ef7991469a39f39536a7b70964b33d25f01b7ad9cc4fea6546f82c3648751e2b41ac410e764255782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258125b786a67de17d61b2fc0e85a13924398aab931896b6174089569f08b7260687de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = 0bad1ae220239a1b88ed57737a4743fef2e3eb585e518ecb49bb8ad073973c6ba1a7b98d7d834c3e92c0d5851600556670c6e279f23ff0e8b257b9e0b8539130d0d01a06874347450c0e6c6c7e975ca591d8b5aaa01ecf5614295df5e767ba67b7033d4cd6c9a76c86ba83b4b47497b06e01896186521eae106485a71a2291c72956d9ece08c24e7f37c0b1feef1009a5aafcf53cc08cf19b74bbcef8e739606e6c3341d5af3206da79ccb7e1a107f5bb757d79be789531c57cc149ef6b8a4139f20c3338361aaa083f8e30331f603b6537a682bb395072503b583f4250692a406eead714f5e24be6b2f8508c4f98b349140bc6f5d9388f0153b4732beeb17a535fdc623774e6a70fde45b0485c3b186b287017f9b5e977a95671b681e949c258920a6cb4afd41af14f0baf5a199840a06253b221d78cbf3673741162ce5577854afad9380d09a984d9f3ad0c06fb5947195f78bbff51c9d2161279b4aba7bf711cd7b5f1ebb65e422421648ebde84e115f596e2158d995e48e2c21012089d6065aada81ad4d2faa0e655311fd72430651c61d4a40c77d74ce4509a22fc64856f060bb6cc1d6c546f81e8abb1748185b4feebd65001abb73e9802e389511cfa1c598f4713ed5f22aced8812f972a438612975b55cf59f2f9670c92e2985562f745ae2f9af9a40968daf4112a4a2bd18e1e13a0142393f743d19ca3511cf121aac9998e9978bec2a90977c6dc251a3191074c8fcfb547a1bfa1ed1341956d0c9e376d7a709c6526fc59f4546195670c8b36a39d8df3d8674cd9f3b78c1ec2683602d7aca3726967d20fe7154cd76c6c76b122cd98ea962b0aa5cf9c451c5fccbc77414bbaeda28f3ff3a5111f4b81aae471c12ee833b4173594f46da79410714f57c89bf32aace0493d8e1d7f982c9d07bb930cc65b542ee87b4b1eda9a8f5d173ef7966d0827f100d3f6017a96945dfd6f677a71d765fd10082e0fe82749a89950c8c46fd047e310066cd8b9bd0bc75e2f7a9afc416344fd8a584d85e1b531eaa5e6c36a521311d7faf1bd31db5497662d393ab4dabab9e74e52db1b490dd42a63cc9a439d1daa854d0f30c3c2ddb9d76495e5bd2cb51466b32010299d3e0d28724ecf1666bc07a22cbf73c816a2a3f5dcd84eccbfffc3bd16a168e90c008dc094c693c157cd9dfec2adeef804df20db85f6a5c2804ef1d85721514607d2fcbd988fd83a0166964259e9999ae991e00609e6f341f5001e5fd2c696e15d64432f8e27309080565b323beaf3bb9af047021d9900ef3a7c2ba113f48efd0efae554cec4464b9edd0f73bef2994582245381133173249beaeef4fe0e3c6abf3cc0d3f709fb93693b10de18f8094989044cb19080f64e42ae17997f724004a02f760c8627c5f408d8f46ba2e61e8ab1976205266b490e57e645abc6182351de1a7618c6fe8d80ba20e82a95efab6f2ca36fc3de204cf2d63515e497d0b06945fab49c72276d292de92d299af0e746286dbec3115213f6b33f73bb79fe55f49cdcc3b04af90fe4f38ee135fd1e3cce74a03f7f542129c766532732d154c879dd363c52da83c5a8d1ad0dca006f594f187650f8ed9b22dbba51f64c9bd52436aa6d49939e5e53c24934f474e320693d7a8236b8d46483ea9339378a2a2e0ca251e5fcb37a23b36ddc495c7974b7a648137642e3e3c38471244ee65e64843a70cd13501abb2727290a7de50086be6085a98d50144f5557b9725ffe2d968d264437d61354ce9b516c914358a398c314e3bc1b259fbd2aa47bd0dcfc7e384e7c95f01c9884c2db55e2e07d75d3aa1f8d1ca96de506d32503cbca39ba42a76839e3d716eabba954cf255333638751ed5d9ac8af41073abb018480262c53d1562abf58b2163e7045579428c71b6cfb9210c10777abaf40b6135a71c8fc6f9242a818599d03093fa5fb1cff0e0a43a732444cb2fe0be143b2146d9059b57a20136b4fefa558308562594f2bc49e3fc953367741a11af45c5d4fbab3c02def5c67cebc8f210ae208aaf0e2ecbddd50449b03c8c1912ceb6d1d2af72c86d22e0fc81b58818249be4c1d9f711e034e5f23dadb673931c0ab0acda5f569ad8354bb330b11744c09393a54979deb52ab6626177dd32c49f03d08f0a56187babf6eb750c8f1ec3ff0acdb820c112087d2fb17f466f7cd7cc7b96ee22d8e3039b634456618f2537d911c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 944ab696cf345bb67894d451ea2a5c9266ea5467c76945f379a5d879899c9cac9d05e89cb37f9b2bb477259f3fca357623c69643569d67aefb2f9b324a9d8090d4c5f68388a624e163c931df53dd7039d951bd7de51daf914cde5b2e5c3059785ffd5b824545acadb95f7f79d1c5726b59890c9fe31d5c62e8b3be33c8d16cadc322cf48a5293c71eca570c9536f958b84663b1dd5bb6f37fc3f3def014aa3ae05640ee9f200274d45d9bf451dce8eb7fd680ace1efbd4cd9bd02df7f795db60681bc9ecd387fcea796ff77270bf9877f895e693feb7fbe79a5956499ca3bc03f93fc8489d494a88668e6614b1f4a8f4f12a448c3ea4297ee90ce3a9f73c6ffa25622d7a504e0694bb7c75ef7ecc8f7e8ce9d57ac87ae17227f1e628ef157c333bed98f8a6823f765b61fd300f4733cf75f40c77956a7fd213b8a33183ea7c3e937104becc0995ef67f5536ead9b246009f855cb8faf210eb25686dc1553d74e7db3c588f79b45e37e16ac2089a4c70d38b877ed308964b69af211187154746c27f59c8105981c8c7d0ad58717978c01a66b5fee697188bfaac9b9289ffc940c53814d9f38459f5c4dfcf7dc9d6be8f3a13d8b0da45c35d541d2346baf4e73fb0c677efcf6a94c4159bf8d4d7b4b106fa4ab06bae0c4f209bd99a174bb4c58fc7d4feaaca49c4b5e7114a5cf408750e8588545134f83a67769cc6e0c4e3bb90dc040a3e84625a7ee34e34b8fed60be571ce8fdd1d7c5fa1d3e0c2c4416cb775baf8df48643084b391edfcaf49f78e9b3ed2254871b27dae1c6da4e39b1f5a8473f68dc7153caa1369d8e9ca38176da57ca8d2533f02816767ca8cac19e4c17fecec8ea4ea5da930e14d3e7a876c49dba310af60d946a2eeaa479888011db7942f7676b2fd338357bca38c4ca5d88a5ad884b8b4c14e9c09e93ef8aa658ed77cc175ef4cb38ef61856bd6c965b6b6cd61beb1034888f3a7d555443f0f5cc29d9ddf5798d6beeb4730ab9af4b9beb8a5d2ab48761e188cb9aa95ba06b28cf4b89d3ddb2145a4339a53406b6790b5e8f559d2ecbdf30a9cfa45447125b733101f645d935e0075ecb4996e395543b7e643137abf3df59e042abd70bee92716fd74dda107ba6fea19d8ff6759aa7fc11e864ee739325415ebda558d4b37fe6dbfc337747a7ef46f5ac872d5e5f3862ec09f2e495ef98b5adff961e5a4967370efc4865f06a72b4e464d37ce4ede803cdee7888b681d45e95c857a47b764c6799a87ef7327fbd403a3ee2909e0ee96f8aa43b3346e5bc1ff51718df4ae4ea24e3c4f15b99e72f536dd989c0335f25dc682e47ee640d99c165f506e687e18a883f90882057ce4385bc08bf8f616e8e1a40bfec93670945b7efa17593c4b7bffb76f9b8d5f533dc50b065dc77b409ca8cc0c7e90ab6e614d5f8af3deac131ce9e446fe85b4d693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fe00f6207e3b2086e3d2ed74c0867d7edd555fe5cd0b41bfa83baf19cd643f1d83ec00cf2bcf94fba6a8262d959c9fb34603ff1082c40a26dec46c55082ebf70933db0419d558cb6d6825e73525725d8cc0bc93c881c99a1614e757d6a05ad7ea15e887c178fd340d673d95efa1aa423c5b76a743dee714ee7ae96c36cb6a2ec473d93d96c22fb9af7ae6faa56506de56df9735dd3a82681637a1747eb49adaecc8aebdb7a1510d367a8bd23bc4e4cb67587cbf9d1928f948d7fb61bfcdd8fff2a137e3f6a6c3e13c782b23c495afff4bed7b347ced52f94683deea0e5fb584f7c8d8c740daed35358dbfedc3e68774cb1cf3e331e8cadb8d5045a37c93cbbd28fce00e089003458cb3fd9cc39640774c7767183a4ae4c974f3d5258a8d128ac8475dbb044c60311bb25167d3f9ea8ad366dc6f48fc7d173f83e3dddc1b637de633ff357a28ca32ecd834e4698da363ce248dceef5deeee9b31df6967c8ce5e94e765272e34aae5719838ce9579c8416f34a9963756fc83dae5427788bf98358da8b356a2944b7d99e7cc0884a2c58481d8f99f194f45e33c0c3dcea33e42287ab15c1a429e588fb3ba32b6897d781d72276d96c49576ff5cc537577b76ba6c6d993e01d3ddff5e9bae58eacb7f990a39711b6dafd68ceb50e4e7883a44e1ecf4b944f1041a9057ebcd8df95cd5eabae5e776ba758d8ef9c8702406afeb9d82d91c06e8a27df57be2d2cec9893e9c0a678ec02e94c21181993cfd22c19a7620d9cc494394b2218a81f9cbc743047160b0a551b6c802e44d09e52ea613c5f60940d77c3aad232f9df0561f159ffc0c88ac9c2f1109a9d89ac87b4a756352289d241b8bd694a1e140f255163f7888ad1314e6208082c0bbdd72220fca50d57c65c3b05d701b567550316c440c6f90ba50a46ad9662f99c61ad6601a4a26874e30ca1cb97998a13e68683a28996933ba186f469dc903b0c46a348a1c307ab9a9a4d427730920ae296d725bc045d2807ce2cb325cbd5f6cc216a0c0bcda1e321c5b17565ed0028d68554c892a9755643a69cb721fe6296acb64b93966a1743ed298b5e348817d62a93c453318db713e95cc53f8bef7d6a5dc2a7001473851324ca0db3052448da3136347008ad8d8b6b95a62e8a48073d2634a58525dd663da939948d49da9b12b1d758bb6f328d0f42a38837675e487403148729c4ffaa2ccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63feb255360c4796bbc99d95461b30502b42ce4e6aa92120b61a283927184931fb6c98727cf4163284732d62216b653c633659045549a40bb0c7c0a64adeb841596516bcf97e6ca33892ca8fe6ebb45e58313fda81d164193bd711ab5b65e7f2611b4b558f3c03294336043884e8b92390d11903035ed46289925447d3ab1a53802376cb2ae1960e4a7a13d0d05a58c89f5d0499be72acb9fb7dc5468afd332f483b1dac2370a14326b52467a205638fd603d835a628ab940a0463eb93814237415397b5a8b062b915c3f4278ed1db16ed13b03002c158700852837657b94a4b5ac43da32a7179a4c1a4303350652693844949029aab4222ac62de266240fb48bec4bded28213d945c3626aba1856c5e702589738fb5574380b74071dbb401696deb422b9de3699a0949e20522a3782e20a6aa2c364868ca41e7202ce8ec8bbc2165a09019a898bd4615741dcb73fdac5fc7c35503a937eefc08cf88570ed41163bb7f2e9315f0249d2bf5cb93b74627041bfb79c2b26754c6f38f8b802f28d7a775aa7cb082cb5755a195d66371fbccd1678478c462ca1896b201098d66b3991b2e73c299674bc645d2737111cfdfe89b416a7da8ca182164bd708119297283de6a1ce84cbfce07c683783402539f88b6b071213732b7594052bda614c95860b57bd5ad5ed10d8139348ad549bb573e3549320e521c0aa3919eb0978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ef030c94b2e93ea67a081af3413aa6ad1c41091364e558cd561674340430bc490a52728cc188cd1281c7aac45223a341eb60c8eab4959701aef2120c891b5ce115bf8aa17cee2a980c6895ec5061ab49dfea7431d755015117a5f0a0f200921c4547abba8bf13b5cb7987b0250c2885a0507094795f7274af995647b5b6e559275115cd55cbcdc9b988073b2ea214551752baf467432904ae95182514e39b3b418a49c410e4832d5377b95227b3091b5f782aa431a1962d6a907d3c2371161d71a9640b177a488a1fcbe57f108900e8e08292f4cf97460893004f5f88222d059b162207ad739650537bcb8b813490ca702555f134406e9c04cd54bb85a7689a1316cdf3c401d9c49b22816f47ce750aac7455a222490940f030f108086262479b8489fa00a12d09cfb5d4b6a4176fa0f62b1288c46af76340d81eddec842a548be29a3994c53a7e631baeaca3a0f8afc4412b6d51426d496d2a04bf29934f17e668421899c6690853876434e87f8f10ab52e61ff35b54227ac0fb7313d2f1c308405e5d767541c8c3bb4664c594a257ba30fbe34bd182790045bc1bb377f9d54ea8db52a945642075b0df8b2e6ac87e71177a4860157f83829bf7003558b7f35a1690920d494b4391396dd61a7f221991a1c6856f7b1ae5147422742aa0ea005fc1549cc034b9c11267e00fc32c2b3cd172975397a3647a41b1c69f9bb663835db97314468540973c339ab0cb36a19b2ea807fa788402d48dae0ac01285a8c5f3725fa674d0418bfff98f6c64c2fe21a4c6a7cae7b014277413781b7c3da207badc70aaac10e684c42940705b8ac37ee7c0a101bb3b9bc233845ef75908a83108a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ad35e259a200d16048302df38d8e7f9e1c3352502c43f086fe166325048fdce9cbe2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = 20be7822cd6adaadab8ca2416907a677ec5a50e6a8e4b3449c5e097306024a43f0e3f9f225861d4d9606860ae79c17849b4548057817d0b706c7c1551137086edff26dafa6ea695901a8f0c1e80ac82d499f6e7fadb20bc1ce9889c7758f63358a47897efb315a60df56651c4fbb5ef563fa783e32735f005a24be4643f4ada0844712b36711ce5696828fa70feb1cece8ac2521637f118eb9893ee2a58ac8f6b8d417aff015f06324e7f36dbd901312a62b33beec72ffdf22ef3cd416823379d2a3f7fb76bd010078fd0e3273b79ede7b6fa9151d5fb3ba6d7227b373b2e05d3e13f36e9dbc747448f8b59b51e5e39ccd0919c2168da6c31b909d1b3579713478be503f3139c4d451b7efe17c5481a9a0b9acd6a68c7c94a3085f3c5f41ba436e0f6da69ee3fc1575602235e932cb618f6b41d52d756d37847229ed09290cf11e54c8535cc3c141f3f0e0954ff66cb74602afb44f811b32f5b1c827a3c087d0bfd775a4d15e5f967220324260cdfba577f4fa3b560242595d242f5783fef0bf9cc217851638dc265e42f575b67576f65ba33797b678e4f767af10cdaacd7fa09342976572ac926ddc9158836d4724adc577220ed75d1242b9b5df6c13594f29c0f2366fde1981a00e253a17b2b74291453910fe097fa1139f8ab3a0905e4097443b2643de6e80bbd7613f43b36846a65fde36d934482ac6d706757601b1e5afff7e5d2019e1d1525b982fc75f97ee31896678fe45f5f9b7619bedc611d59929508e34b0178dcf93634d6cc82f6b4857d6f161399d34932d869fb850efa819cc1859f24694665decf61bfeb4a82d499823928485e4c30568433eb3f9f916fc1ad9be0d3f5257a742e85fac12ad0f2cccb770e072ee55da1ba419be9f5c6078713e535f60dd875c9834d21a2d853dccf798ae6da06334bbbc3feef8702d0f08afb0a783cbe6a64df220a1ed012d4af7448485985ff0a9e7db204be96e04e1de7eae947e9873eede07e85daf9e4c41a45338f1517e4f5f7e8fd8956609cd49b4672ebb965089ae3dba3572a45ead681a5f9ac64f7515a4719d2cbf0ea5ec6c1ca7b3e464b1deb0194ecaf02a48731caf698cf4d626fb5790f754888dd7c2b3444b3e8e6a1af286069e805d787a5f8e28bdaa567205262f6e0a8c7f80d7e9dd1cf1927576b23284eebe841116b20cad132f0b1f8609cc8a8873c85dea2000f632655f1c311953e44bea148ded0e02e5b2ba61609538c04576b0c199b3af0643ebc92c740c4e0a501b97a0034db8ec623684d0c08a1c03e41356efc6be36046a5944fccda633383c19bd19af053b051b283e8da490d31a79cf6c2a3924201b9c8975b215b368a1ecec59b0c957c2c4b112d0ce662768759fa16d7e1cda01d507514c8493bfab36565335b7f33e59baa99b9e28f722e8fab080b8ae5352883e5cc576aed084a94b6a7fd93d1325cf05a179e6ad015ac119b409d207c6974db16c2d6115316bc6e3e924c0cab592f35daf15c29e76bcaacf7a294df4bd4b47733277029c393ec3aa81dbc7cdfe3d5e86e41a67f62d3e59e8ad66cbdffbf159ff57caf059ed46859d4354405ee79918a0390fc5a779e3496c12064fc5161289d77d2330f101a2f457105654f421791dfe61afd83bc628a47cd5ae579c0fbee3bd6f158bd1997255083ba658df1663988be5239605593551886470d7dbe1f28f2bdd65cffd8511c3ba0d6a06ac6aaf3d785216f19568ba67c3986857aef636eaa696c5e50fa9109f6128e456d8af149aa469e02a95c17c7eb11211b186d7d52d7d306e50d076b5d5446edba2d531e6868b9d519760303bd5ee4ddb7674b7607625205f329552a6b1dccc79d7cc6afc6d3f71dd226b2b1ddefd6223eac169640eaaf5662ec6eb50533e9f3e6d8b550379161eb4e9f0ea0cab074b5a44a5ce0b5393748c7da5769d892bf88f04a58e50851f148b45a095b20c85e6fb475cb126022b55d12c020dc3ec336828a8300173c977b251c848262b66892d6f25010e56e323f1ff8bc59a613661005b6f73303e1c7f56b8e8c6e42e8d43b63ba1d01f5fc5a490c47f3016a5987f9f2c808902818a092bb5bb940786043ce7d4d9a73a225e041038bf68a8fb41ad2ca7f1031656e2b3073d03497997604fd3494b5ff1c0cd212d0a9704212627de2b7d8c4f0084924c28226235cb949f6851439077b8371fe4fdaed8 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ac65af9fc8b906dd9638374e58c551da08ac4ef86a90fd4489ba46294ea85e9d7ed0d7de1a89d297bbfdf7d6cdfc5c6af523e44ebed5deafc7600d736de9e564a79668e335fbdca1c9e3e592e73d60066b95aaffcbf55474f9c21cfd58f12e457586766fda4fae6fef64a4dd4a3fb07ad8ca7e2ad6662730ea7ce5aa2cff976f552323e76bfd4fa4a989632de492566adb8bbc3fcd4f9cab9ebfe5860f886d58afc740ad50a46d7a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661ce1ddd10d6bc31daec249a9b3a3ea4d1c57904dc6df923839d9a90aa2b93a87c44b508ff6b9f5d22e679438d64ffcb9621067b75477fb7e5ea1d3b9d9df4d51cf874ccfce2976562752cbfcfc59f57cfc60b8b4610a9bb36f9d19b9745034d7d57289726ab8a38d7a6c99dd74a5686619abfffa5757dc79e144940895e502beb8196f493f4b7f4b9d681646ad7b193586c6cd5d9eede2c968bd35eb8879ec368ece8d08f70dad3c22b05da3db4cf05668f8c73e5c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af5324eeb5e7534fac4de58e741e48b4154dfe4743789e35dc39c45c0a15cf42e7b3631b6a8c0971c8a34b830dbbff2ed04bbd6bfc5949c46e5b02947c73e7a0717c6b61ff679dbaf1afe4c55768a08f8de05868aa6ab4aaa848c79c0ef68849d7b9daabe367afce273e2c168aac0facd27855e2944b67b938170a9258f6739787d136e466759cf60ccb7da226b5a956925157f7fd48953d6f959c88c8784a8a5223ec4ba5a6d757b4321d48b70fb554e8ad50abdc13bda64553cd437dca92f36ced2f7e17bfe7c769a2bc1aa6c356a5a39c69f4963ba6273db933ff1d9af8ce65b5b9058f1b9ae64bbd380d4fa8eddb6c2b9be9f26b557c387e4db9aeb92c4d7d1afca1e35f98ed5cf69dbc511ac5f0bf357f7d525cedf7b36c6781c4b86c0d69e7b89c8ca643fb9990ecbbfcc5a8a5a6bfb0451d76ce934d96bca900dfdeb6e7bb093675e97b68894bb03068ed8a1f3643dee18374e15a76ad1c28eeed4b691bcce5df28fdcefddc71f8685c7e883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5058ad886d86d460cc4a3b7e3f4fd4bdebaa93b943c48e63480547d3ee8e8fdd9cbd63ef46c0b69a265aa3829ffd6a474c5aa530aa63d6a0c8572d4e3719af78194367405789e1f749ab5ad2af87b362067f3ebefec01a83acfcf6a49dcb5419b351bc95e08c7338fb933c8e476ea950891f75a186c9e9f99dab63634e6b7314188bfd686d74fcf03c7e542c6fb1c0c7712745940f7b923765e46757de5b1ba2f8e34cf585adbaf980317c9db1147382946c132f3c3a45973b879a523855bf0ef2151bce631fe6dedc6c3457ca03a5eff45b662f79a1a7a5cefe9a846dd5774c8cfa22f842e4e465a953e4e036bb56af787a2adf102ee14397fdae74af706a369ca54259c8d578bacd4987d0871842b98cae2ac3b572f98f145cbaaf54569779b61634f060c3db2a58fdaf335c9b6dfcd328f96958c69607d90c7a3926c7b62f36a5dbfb87ea15e8368e55e8e94390b6c0f808b91c166577037df61af1dbacb5cc0758ec0bf1d4c38ca54c4249ed7169be9f7e9f5a8ce864909efa8c5b6ff69b8994e9585adfc5cb77f59787739cfabab1ceb093e690c50632f7c336fb139700d43a0499fdb63fdc29aefa59ebad66bbbf0fe860e2f3dd8eba9cf21c6c1156cde1bf55a1a4507e3c880b749fe959470b684e03268b43a960f3d76ef1d4c4e7266f8089feb74959a12a6f1d9ecde02b8d5c14a500ccc7224c8ce3b7db99557c87b9bf09b449352ee8b3f99850abeab059fe0fb8434008f0905ec08917319d9350055bb889cafd6ec7b5e38ea9ee84ba90ca4d340e4f9cfcf9949e5c7ccd94e9c9f6ea086d84434c2748bba95569779947cc744dea189b218dafc548710b94a22579929319dcb3a6c932336003a9dff766493f5be7cb834cdd7da0b209b7a1fc42ba087d7d1dc02c383b60b63ce4e44bef9e6920156de9ab95aabb44f28bbb3f16e2339bda5077c898e3ba0f197f803ec467b8803abbb0a82a7897e7a39d1de2049788d27b70c95d3c719ac3df958a7b6eafffeda2c7aae703d6527bd4ae7ac89ccf0180b971854b229829c15ed8119f77ea8c7a80a4b7290b92a4bd7ed21e3b317e15d2ae5593ae3b3413d4552b767b5c264a2e31c28164e18c424a00b013389663ca580ba5b94a5e3c3a9234f15de0f4aab90a240b55b6cf6c4bf5d29ba93480014023f25c66813996f674cad2f72c34882bc441a851413560f54df40146fe9c634ce98a8a659b38d71cbdf934d29bb4c469c660190fccb1820cc365490a8a79228b79d95c3850c536f7ced9ebaa92c159e5f9a28c9562beb95d9fa000371a2670e5b066d16e5af730c59a03b8d2364eb048df031618d09e8c07781957b3d06c6ad4534149fa65f8c513733b8b095b6badec8d0ec0cff1618f5b754e71f50f3f7c9a209acbff1505a7a40621b0aa817a9f7c6a1caa1441af16606376c845c473b89bc8cbf95460192632098bfbec366b1914d9216b16a19c8cb45204379a782c203614b37fe411dca18c20cc033cd6510b649c09431afe167826576e19d425026b02f628c92e389d884a8e5975c3a3a252e0443239305e30bc6e73d33fd3b0cc63a8484721157a491535ec1918a99584808e75c26de2535227a7120bf97b64f320743338c642bdc9d02b45a29903f22ef3e789e29c4119acb125347749f373c3f4156a2ba0bdaa51fdab2185bab69801055c1743e7f7541198cd6935598cd00ab2a051667ab0fc67b9751aa6cb76b38b51754d66296d8abea1e6268d410c68412424c780bf8198a9bbb1227771114baad6a63977163fd432131f96168131cbcb536b8d223d521583e9b31e025abdec005a6ec66396d94b17436609e6205f1610a805cb39240bf3d19f81b20cfb94cef7c10bc7b3110b2231c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63165c07a81e15d8a5313552728bc5c2b7ecbc3e35975a9bc5c341a7d6967757bb7c67eb279f7b34c33f95dfa49185f908686a55cba343af19635d07b3a23d6442d15cfe58c04ab586930029d072704b546a4af3aa9cdfa148018954a857b3c8992d1c567e3b20ec300ac438b53ec808ad0753cb8026703c1892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71387c09ae312e00368ed4198fd23884f1bba5651ccb94488166943b2972ac73615a21e32ea83b9b23596aefec1785329238e210fa1528243ab9fcfb974a6316e26217d278596d188c43684d8c349d91cb43d301c961e4b51b51b202c58ddaa10425412f13228d16fc0c75e2b8eba686fe5172768378f16785247b9c6e1ccd9929a8d17a829566b640f0744bf565ea512402707e78aaa6809b75c5154dcf70bdea1cc05902bed4bacc3a6c3518d2a605cb96e3cbc5209239f4994df6b503d5f16e04562ed689a2130334ffe99b093a5cbe2282321551e943ba7c988561d332663ac4e8b367427133cd216240f659d1542e54e4ac32c42da7c39c0b5c105ddb872a9b617bf386d7259661c2823522198802be252747381053ceac84c5f827339c90812615eeda92dd38c2e1db2268a3929087480f393643d17cdec6cd059c2b810b464646a26427cee030b311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b42099de3c6d252467c0525131128b18508aac196a8b45c013519d52950a16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f5a16a98857d7f57945f05925b45a55209895b7ccd7a9831d93ccffe55a8ee0c63cc57a10a0c8f905542856594bb41359fa9f5c312ae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3c9222c020280f77b9b731514d2ba49b1b0b0e6533684fc5ef2665c25840426563ec3a2aa0a01812186021d40c4f3519da9799feac06afbf04cd390c0a52a0b687a5ef0877f053c319fa51ce7e53aad0313ba3b6a7ba5892a50cead19356d8068d1a93681833ed4b8c975e99d969aafe1a6a5c2326c4e290d65eaae1323125238303719c545202178ba17eeaa1504f13cd96838b7560c1a35b1257a1672c599b1b993a55ca982a1ae29b6664998469f171865562ee027c4644234f7e3b14621c811caab7498b204a55c8b302033219d6b2b9bf7939e9fe4523aa9cc9a41a1ce11c18fd6bb9bcaa8970534a7106199b76975ea8af98233f031a371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc95a5db7d619be642bd87294527b3f859372b279a1e6074824d9632b5d7f616e42a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = 3a0a5b632ed69517af9feeedba86c25ebe6a1a73c852db53637c6616ea2a1e77c02d3330758a95e34454346f64f88782b959407df9286028dbdad2ceeeafed8863a1d10b200b32eef145eed3ce167440f908efd4a905008cdc275a3afc61c4e124978f7bcec7bc7a045bd514154ccb0332de24fb83e37237d6e24e76a7a9ec7461397a536985a1cc2ff710f659a3bbe89fd4d3927473ecc8a11186b4457ab2a68083acfc75f7442a315d8b0b2b034f89a39b29fbc96956dbdb5651a3f349cc598b2f11bcb8762f9106f3c50db6b74fba67d67c47f12f4b82d3f6a424c38fc71ee1d82db9dc83536d54233b3ed286b996451fadd4fba2545a3d0f08e35c733a6ba865417607545c0840deb556f5c6381971d9ec96531514ae7d957b11b99a22c795172e7a948be60376dde244e9f00a5e9faa5e2870f39dbc39b863f5841020e30cc908b9d762dfbfdb84c5477dd2cd5fb920611531ef17325bd1e5b284a931c29db3ad9a544f7ebad407396af4ac31834960499c637e7a0dad0800742d14f2d62a0565746ddbbc099f2f357c674a68afa3f9cd157e254f80c24225268d6ce9338ed1b60372de9d90f5b787255aa9c9db05f424e2d8552ae24f603c54455aada7b7e41f2b46c1c6c0746191cb6a86575859aed9170787831345e890057966b5e39fe827000b4f571075475b2a157281896d1c897e52b900bca93d0806e6f41fed04340d8c12b5e5aca961135bec95a87c2221389f4e4f728438201b37bf817c69ef070f0d6f683d3a5ae5a2b1c4ad2af523e04a5df0414de537c5501eb94d954f1203ad96c1744011e027da4db58ce64808809464b48d483cf37406affe1b1ab8a883fa30bd44d8b12a4091f00e2ee789b1657209025b1dc11ab20a5aac601cd053a6eaeaddc522907464a8b7f447e98a23863ea694e7d675f59850dcc1a2303b9c60a44a9093c6e6ef3f8e57c1c43d237630eeef60d8c4de2c1ed17c05762e9ac388682f8bc22d296cde5e301ae53f0a3537f3a1559e1e9ee1ffc56f6de4df77ea50ddb98b03060b342ffcb49411d332eebc366a8cb577523b487845294071cf84a7eb9aa4ee5ab9712a2949b45729a813e35a3669726bc8c470c51b42afa1bb7e85cbb7cc784d50d0736cc605acf9b7ec8ca31e681816424abfb1fdc64a0d2b55045edbd7eaa51c790d8073bd29701e378d131b51abd1a23ec799e7fb94a451ba63c3dadd061e9e6edd3de92f279238cb125dd57237c560a81e5f3788fa70e1ba3497985bbfb8ebded19f93d658e8cd70a47edd4adabbe33bcf1c8a95785901b7e5fea98637cb4d71e59133d64c16fb2f1cab7342878035b6cf25d312997dac69120faaae39fa8ad10c5354cbf0120e894a6f97de6e091c3ee9366ec2e13c6800a197eaebac9a75a515b9f0a23f20bfc704675b473858dd7e812125029dd3c91f2d86ef19b5d536f9fe345e6e38995eeeb0aa8adabf0fc2647f71f4d742cedc71f52a85f42a6cc65da3ea7e05c0d40be45a61c0c81a4e994c185bbdcec33bf81100c113dbdb8956db9a75b629bd3bdb72412c0c321b8406264ea50cc65c4a938e29f3dbb2cf910ccb3a7a1374ceac6c412233889f3189e093c6d11b92c01ca94506aff55e09cceca978aa14cb7fe511effdd33f2a296b482f5a34683f9e1c64168908dfe7626e2f8fc9dbc535bb353e8833e9a1c8ed51a4fce122b2c7fdb129a960ea642c3bdf4d03efc2a2397bdf19aeb17ceb6220c7031e0a5159173de6d8b7cb106654b37d669527934623f64d2bbacd617b708e6d1770deb3443f27deaa55c3e0659a37be0ce8d4cd87771f8d6a59e19858f0b674a2b7abf263f2d4e821cc72581e5a07f72b5295cec2e45f1c97ab33d174ca160328b0c968f69d2f08a1d4e37e6a3f36ac18d0ca50175ec38cd38d546815a2911571556fb7ccfbfe9b1473ff91c833314b773e8ead462227132979924a20010fe3b702023777b79fb0f3d413f2e3a97e85dddd1289c76a1d31fa131d0b75d74665336270833516ace2a5774f10018ea505ab947a896bed114ba5483b69ebc9cf3a70a5501451d9138bdb63e2dda78b1e1fe4a78ac7f204a5c0d40d6f38c17162d0825e0b358ed116717ede8b9b8c79694930b5b6d22d661ea42a22c9ac8f99937a77a22d88a4d55fd69ba328e3e96fa3b9e43b95ec0f732df91e245ebc0ae0de65f1f1129cab5aa56137 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 67a93bb27acd00c9b95bad35538d9c39ad8480dbaa67a9584a56d346ffde5f48ec9b8f710ffe709cb5e39309e73467e9be3e44b42fea8608c0a59de7963387f7b3ec5febc6b6749e6bd9be3c58a9a77b53d786ff5854a3467a85941ca2c03873c0458b950f75e5ab85b83a5c2027894caff46dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451a2f761bcf74b5cc8569ccb93917a748e93c1913f0e4fe381e08ccccb7d903975ae25689c137d9c8f9d96b16a26e4439c265fa098e94368b36efe3871a7aecd54ca0c70974ac936e45dca01eef96a14c7d2075f999f6e841dcba6d0e71fcc4d6e14a95b1ddf517447bb947d996176bfdc5beb53e6c0ed34a1353ee34bbf7d9dccd3ddaa49e3e4659bb8d8a3f509addb06a3e796ce65c0628c817393bb197df1abedcfe3546d8bbc2519d583286f6f59da1bbca6fbb653ee1c3555203353509ab14b64cf9af9c33be70978d5b8d85e848dc4494279267ffcc485ff8b2c7d3cf08f00f39e52f45701525e79a5f62d705af00ce8dd413c12f37b605bc32eddef92b9ac99e4a34fa1ec8dba9decc9a3dfb37517446908c9eb1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d29f9e68febfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c9cfdb3ec750b18fbf2cec89a6f8c2881650e5c7ea0135c865bb3fb12a4c2c3c917d655a2997984c8557edfe943436a9fecc5c858d8e398decc27af51f458334f59bd40bb0d808ff7417ea5ae3c9439541aee59c6e46a5852834ce67e2b3665018154c5339467e6d6af189ccf20c68c583c96d9698161d9cd3ecad4f5ab0a8bb8a7b68359b13e9078a74069fec2709a615864422cada3a7dc8ea138ffc25f2b1a53ed1d7ed397aded6b782c665fc712e6679bb4761b6d0644f76d553cd703897c6943a86aee2caf9a7ac99517c23ce6457aa069b6fd2775efb36fdbc27b02fe6923d14b048af5cdc6b86d20a55d96ed8ff276f121a352e098e5d4cc3f09fb3a1c4a38244621b055d609ef189f6941b59f3300bebb0a442a656655455b38c6ffded5640cd4e36df6cbf4c5bd65163ecd8c95281efaf13fc57c977bbd1a8bdd263d96ea98c3ab33a516448a94dea4b24eae213bad2f640b2d5846c99a2588436106d4333197816ba9dd2ddc427c5b8d3a6b4352d7b8539ce519fccda67a755d6a6d7e8bb6ccdfaf1ca7283e797f25ae043df9b6436ff2abd482b94dbd70a3d6d64f05d04e3dd6490e3dc38c1236758f65e462be1ca58db476875c79f508e7bb90c53d798ee91714e642d88506c17f55ab9fea335d8463cff4a1661c16ee4c946ef651b7c5f07dc42659ffef7ef58cb79e445536b8948142cb4ec16cfe6cfeda659c2dce4523473f3f173fc380ef9a75f5f41ed3d6c073e05476253bfb0483c4b88cec1fd8c972cf651eb9684fafba3f96fc861acd8a01ef77c14be7cf779081fca1e8877a499d9efb3ed815cec21f4a151b8860768405474e9a1c8b6ca4466389a3f6dbb69e8494d7b25a4eabf34a8e9f8a26b946f03d6b8a33b0bf8b3eba9fd68d3e2b4074788e69d1a6af11c3b55f8c654ae778fbaeaed750bf4966a42c5fe89d96e760f7a5f30f358dfdc482014c25845706577763bb6dea00a378dbaeb0ddec15c6cd4bf847bacddccda7c61b0a956229bc9930f9dab8bd5923c5deecc595d766c014d946b2f9259c75e9985bc0529f18df44dad36abf21cfbab9fc3c34cb911d77c0e86d3e8639fd297dce0f6bdedde93c9cf61c53a9ec8d4767303480529ae2ddf3561d9f15476c61745327498e092443076e731a459cf603a7cff8e8050dec8293baec81ea694f98f5aedecdf79827e777b9e55ff0a388a7e7cb83ba37677dfb70a0bd3c7dcdfd3ad541104e832233bffd8917da7f6657c68c4e34f1983b6007b43ceb87a70ad33b3c674a19d999cc94a4f2889a8c7ee5228c1f93ce6db94e099c57a740d5f81a5cfc97a3a1bc6d92ae6deae139d9cbe74c969eae20c5db48390c46bb456e49e124559dcbf30cb6b5118078c8baac9e969f77aa55b521a351bf34f9bf7b18dbb4120ebb60d9e4d84b8d123f3380365f0620783824c676175cea40a812d896839993c4dffe1118855e5349e84c8604d1c85202275f93924ffe79141ea0abf85a4c970c45e0acfb20c426cf545caeb594907a23be6cdcd38486ef2cc1234054fa47c50c629657c91e71103c029539e632089461effb67a0f8cbe74b91793ab033bd89a2a0a68ef390ac90669aec42530c785ec3a0dab424c8184bb051780b4e80838539c81a5097d42cb854cbf324a26f3cc65024a6404cc2a335378fd10adc8e10cb99c323ddc55e70b32a06cbfab829e53aa059163c46339b7fa1090244a358dc647d4b1783b59383a0988ace605ad979f655038aa422981ababaa0c2f28899a352572f4f6515d62649cf88591ab7da91ca2c0e44aefd16ed3f174cbd0bedb7736363c609eba4655b2a31ba20f05e412282b28e15125eb212596e0c54181028cec9b106849ac366f62e8c1c5ec9502f01ecfc1749fa3bd7b251b2a09c731c468dc2988f69649fa9b46e9d244df903ac9004f09cb1dbcc9c69b33ab9e928fd2072cfed1186f9799ee3c2ccc2b68a3d662c7fb4438240d6e0b70ce98478e6c28294047400b9088eb4aae3a5a076979af8ab4234164b0846a9904ade949742d7402c8516ccbfb1d30581a288c9d1c69360a2b06b21541382ac9b4101b96d4952e89725258cf7fd33ac4f522d12b6f65b884f33a0a4d1b0e41d660d0861beca59164f8760d3274d6643ef7d13043d63a4cec67961c808cd64b9728872f74412b8867a2e25cc58174653b2a1a0ac0a24316f4c14281a0a739bab2de26ba73c4921c50b909d188e8b3c4db1274491c792028515930ad45e667c9e6870d204554556bfff44d09f95fe9dcb7370320bc6740f3053ec5b7396db400ac671b01f33dbae59838741b59e4c7f076a92ce92c5213adadc47c8f50bcd4756de7642799d5477967339e01455e6898d2194a7aa724338946b7db70608c0337e305ac876f3d87c6ad857162e491e469bf62c26285f9b817858b149358cb67248a298cb21771f1504f4997965ea38036d274ad72849164262fb58f46cc96ffd75f23b4a0c990a9d59160e4365b07909f7874a22ef1362035312f43b6272bc47eec6ce9c0b4418b60c5022502485bd92730ee75a9bb4a8c81a03ad4b292f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe274c268a11afd003beabb50d12b8550eb3008ddbca593c7bbdf6768fb561ac452d32c77d74352310e4322ee53b9ba879d511368b445df20aa17a7ac8f205a302f75f3c679557f2a37de221cde6c8f7248e73ec25de603afbc5baf1b076dc3b304550c198b6b49159c12490bd964b661e6ac0eeb2b09a78941675a2132527d0016d89ea6b3cec5d19f1818e4501134947a547957a195807774a8c40a9c50833790aba5628c2eec2148dd0430294b331235d4246770c293046a237f03487993043573a71f250090aeb01dcecae4b878633c59b5403abb02151d8048dad408473d63cdd018d3d295a46ab556c8aca53495683976b2186c6c818b852005d20964cdbcb6061a50910b9c429ba9f10a06f4e053c9e1c4cbeaac35949c8f23c3e890234ca990b2bc890d43c2a4051aa058a402b7caf4a3925f52c95c6b6c7d26b4e3d43b21d7b0fff3b37e5d33e391b5e617785f52128c581969e094d82d062a8631a76b093703626d8708c5f310abc1951ee8984bf858a7b582038a6a624f5921257764890b73cc9af94e5aa82d831f341486aac17cf29ac351483f7f26c80111f6715634ab69ca71a6893b13bbf50cf58c16b29d6b7c9b58fb3c0b9295a6320210f1db8193bb8a57889a28ce3b196f32cef048a4d60466e3857c07847e3883c1b7bab89224c94fabb3fdb921ee3c7fb716ae8c520d547b1ac49cbad256ef43015fbd722b8b31d6db24937338e6614402d9272ed014710fc5b0a7105e6659de2513101b22c81dba972fabbf23756b5d524d41a15b6d682a1894e8439b6946c64d10732ac603992353f03e61c1a136011b52c624b0943a3464ee92b8a7b970ab5ba9713205e4a22b6a12e063c35e8c65470b32f9e29255d9847de80cae1091fa536213078bba0181fa33bad7f3003d2065b8d997a7207b595994e816a1979ac5174137ead82bd88295f2cbc77e01c0fc9119ffcf25d8f2044a16aca9ca052bf917746109320dc076e1895399741ee690702b477a2d07242e03dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518ff0d1acd4fe1bd3bad938c23ec5a7f320766e01005e32769724abb4ebac578def84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = 5f87f10c9a250dd54145314983d0bdf99d7c5ad004b950ee81798763ce02525da39e2fc6c3b09dc64287954539c76011a7a087e9e387ed105a17f478b1dd601026ef979241e53fed94ad15c9996fbfd8863c2f2c2ac100529acb319a0be562e28ffad82ca952774ac27f6cc8532ff3dab15c6dcee9c1a670f0228fdeaf5563ce7c9c053ca328891cd49e494ed4ab9642707c67222753c82e7255c1778fe549bbb334d4e2015a6ad18d4c6552f7be3b545797a233fbd1a8b57771cc1433f298b758c43354f0a6a63e399d958dd8abe0bc4a6badecece4f7652f1a3789739b20d777b7e606751bad09a18d5fb17383b677feb6c99a3b7e55791af134b2942e67c6ed6b39acc417080cea35a9f70ab9745fc329986fb1f5e155695307748b258346a6b71fb46be707f975c91115688d944a2274044661bb803e4ab5b0cd428a080fb023e826acdfd70bf66482a1cf18d020079b65314c5070b9394efcfe0dfae0ead326d0124d1d8b80cfc3a75ff7def710f7a0b758981dc0a385854a2556cf9cfb1194efa38eaeaf80617398c3208eefc0ad72393f6a5ed527806d4b8221e96d73f80ed1a421aa308dc4bb9c0c928757e9915c08b0d21de69918953c9c7bd0c71b36deb4d5939d798fbfca60b30249d8c97ba3c4c38d57f31fdbcde15427abe36204e34ff1e1690f3ee87a7ba5094a2f45940dc2403cab349808fbdacabccf6f4afadd798bf1ed09d5b39458a0d6e279b08e5d046bbc2f08e3ff4dc97f4f78e02b069745c69606f9fed93913c3b7c4c744722edfb9ab431b05d8c2e3e3ba677326b0dc70f07c5a519a01eb18c8df7e4441dd86c1f704ca6aa5c073101ea2c64f36620c5d692fa60ce347ab1c466f565142cf19d09926aced32dc5f1127d2baf35a718eba32c9666e38b3496a1294f28d3ceae78293cb82c0b7755b26cbacdbaef00b32460f0e1fc898a724448657bc658d6a847241f20f14fec5a7b8a9d7c7b5491d2e05cccc0c9ba11e501e51ade82e4582db34ced28171e68da79c7e008d5a99757b9cc1e9c99fdf6f919dd120435e9023b6d431566291329037f802ba51ced6dee11e10c762723db6a1063e01ca2222d604b78b2dee4f653a2e6e2d572c2cb934c019a5c12e608bf39414db933fe7e7d2822f0e4dd9604cff7326ed0bbac843e186ab1826dd3a76ee6e82138ced21b9cfd11d4da585634328fbf16930eb70e66ba11d2b893c63430bcf3d0e629d27f7b78478da35a61e81bea0d4089dea702fff9db2b9b7600c1080c566411128f9416e61a0b09828cf01054693e4624b1a3ee03589f5729e6c8a73fd2104eda181ddffde4daea2187df8f1d9843123d906cc847326012a1b6a465b0da9aec135b5ecbbf3378e22c5d2b2f9266f8f0537506fe45397d97721f7952543a105b232a5bf705bda55d390d80e8809194f7d3bbaa39ce2ab2c27bfad073c5801317e11a44c809c23126f1ebc6f3765a331f44c0fc1fb31e315fa4471cbd2e21c0937ba67c71e801239035da9484060f78cbd38ca11efe0bbe9bfd5a7ab7117c4b49004bef93f9b37ec78013064c6d5aba18ac380cc27c02cf90f6745d01f4f9fad5f1ff3e26d01ba8ec7325e06ec6171422147f4f52def5f074462ba28dc0f4997ee46adcab9dc62a50ee400f1ed5c2ea22dd25eb92f8557ccd1b5bb0ebf01a9561e551398eb4a9296c96b1e715aa1e223d18797de63f6f38a049e1e424f295d0a966789aac7d1b487dc51fe612fc210b768cf09dab2e0bf095fe3b420d31c7889bdaf046152bd0c268bef13f14107a448c144f75b3d4aeb366da3dd67f98766be43735d5d93c48e59d51cbd0fd2f6356d791f0b82198615a2ca0a1468a3c497da5a694f73eb90beceda55b34aa410a564c3596cb5621cca2f16f5043f20635b602bea75fba43e3e950cff76598a3cca481773b09edf9fe224c3ed588256dd49eee5dc1abee4cf6fa83f33bea1e8116ef235e8e540fc99224c9a781f62f16c73f7399d13fd9c44a19bd747e73eea512e2bbc87c8f8ead1eccd3f7888f67d60cc5dd8c601fe39bc6ce85279e63fb738499a08912e5895f98d25af90c8f0396e6f9f0221854caf8156ce2f231b38adba6e9ae1c1afec44649e859227526aca8f4139fd45e105f5a1492613ccaddb59f9b918c799d3b38e1b3ccfe50e10ee01dfd7ded945a40d76ca4643df86289511138cdfc8fe0141 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0fcbac2fd83a9eeace0215c785ffd261fd991c2f5897e94ecf93368b79565b478731537eac74550cd599d5268e04af5cf327606686ab8864677907a3c3555018b478fcfef5498652d5259a32cfb464ace4c89bbc5758a9b53c64e95bc9cf3dc30647fd431cbc643cdd61ef5136c3919f3bb48b38db9d5ca0b21bb4e26edac49aabe00fc9fd66420b475d083e918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f66d4863ba6ddaf97ee39f38ba79eeed5d96e9b336dfdb24dbcc9feb8bfd77ac888554472d7732e7492c33e302a073680c684870b86a05592355baf272db51ddc7b17c9328d7a74da6367d9fcfb87f9f21c297b5398cfb56ce0e8a68323aabbee8d6c237fc1920be90e7a5b959ad2dca5c55654a43c84f16b29f522ccfa2ecd5bf875d62cf5683993eebb837a3ed8c7369ce5933730667b7463ab7026848bc9cae4617bfe89ee7acb5ed9b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895401ef45df8a3248a9f73efb441b564305ec48ac3d5c69d37e846ac9b78af9189e5e82286ddb397936769be7e37fa8ff7a013d90c8ffb9b395a4147db5a39cd7c2d8314637f680ad6bfd4e6d8bdee55df645c625dbef7dc4cad8c6a5c564ba2571c9bc9bfbfdc2d12578c8198d4aee414cba5749e7e2556a537b4e31f4fd85f904773558fe2344fb229ed1ae4de22123d60cca4196f778c77cad2ee58b6f33d71a85b79d2fe5f0a7c8745abcdb768c3c36d42d09a9a0355a5c45745d1acf53dfd5b949acf68eab75cac74f2364406a43a84f69655e66fe167643addd16aaee859f9da4cb361f8dc42dd7d2a79364f1d664528b6cec667bf34dd78bfd6a0b48466dd9db34ea71026efe37d8ba3a45ed7023aee75f351af5e4b9efe7fbfd9a07654b0ccae85014ed7206cecb05c8f77d3f762c97db08f355daafcc46d8e899ee3ad8b3d5ee8dbcf6a1c2e74cdeb87d15236d70943dab8ff48179f890a548d7c69a14fcc1166fd2ca4941c4addb57a452f39ed91a94781c64a9583c8d303cf1484cc6159b88aa3eaedd4f91e097982efbd529ce52a43b97dfafa0b379f2fd6dc226c6e068c792f377b9f655940d73702e4ebc525d86e809f76c53a4c15a35907cb2fc3aff19bc5f984d34677a33b648322cc9bfcc6b947b5346e02d4424a6f3e534308a5f95327c9b35f59ecd4a9521f4b93a5cd31b6f4c1204dca17b9f379d8e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b574dd683b7a460d9a1efcb5e50a35244c94320ff01b78f6311673832ccbc1794feb9e7268f5323726698f67bdb41bcc023fe8929649ca8fe49393845dcbac7fb58582964405d4adec8e4037a39e512c3fd07fa22ac7de21fba3822b493df9983866412f0439e1b6e3924d42ca8f73913e949b2780d8133e13e632fd4f81de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09f3d4210d5cce3ca3dffff61a809bc5dc44788bfdafff49f3f0e56e7c4f8ae1cbd339fc9d818844d47673437d8e50e6eb9cbdf7099876c26729f443e7cb3b9666441dcbdec8397953f586e3da4572bdefd00cda40c7e5e515ff849aba437ceaed529a50a2448ad87f495c6358d8d50b323b6636871e19faaaaf75cc2d869dce7ee870384a7cfc5110dcce15e5a8c2459f3966c853749d288d9916ee8cd897fe04a76f196a98c7ea5b84d5e72e9bb7b3b3f0648d16cfe5d45f6dea054834ef3af6d38e7b5acebb584d986e6f6fbb8a98af56ed2ca9828643e3bc6d4e256b6ff8830606a68779a659a6fb7837bc46fa9781a1a8ae398ab313c597a4b7070dbeb7dea82a6496f3e0dadefeb361ca8d691ea7d261982eae4b80ac5550b9e53308e971b05908dd84ba13544d30dd715bb9ffcae4fbd4b6a5ee46f5b77d1f064a25dcc4a8435d73f63ac0004eb1954d9b5fef195b8910be7848ec8454da99c0a0c83947ea1917e83bbe9f6fd9ae07f2e60aa8443ace7c77743c5461c37b58ef160d5b08afcd19025651038c7fa975a261578a82865b2dd34a7fb9785696ddeb9d1b1dc3e08ee8c456b85465ada04e9eb574ee39305ed56f4763aaaa4daa788f9e631b8f9f661df850b7386877d653107fcd5ba702b276804716279e61c4b3a599005270578414141c09d070d9302cbb10aac8b8483f11b1044cb83efb8315ff38feccb09d1775e1e29c59b1759d894ccafbc147b228debb52e83d2584552bd15b9b18f02ba12c6669ef94190126f6fe364d106a9d4762522f25a0298cb5e40cd6b89045f275456e8bc32e2c11835b31e6aa628e50e28a9a18226c73343479d0ac61e5a81c6a38c0506477e58001b6890155c3a71f21e1df151660c376cc61d90d93331801b31dba89b6853c2630d33578551399164db647665ad52f912831a956b8ab283f91c10209b0b055ba765cc75587df545b670ea13c6b917393666bd6a9e07a21ac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837b02600c03c9f8f1481414a241766df430a6dec7936db2374eba1dddcaa58c8a2984094c57349a78102a48e48c450ca7135a057eb2858a6176e67316ad21122c44643fd42cded7caa55a628a503366077058b286aea157e540c598822c3736aaba5298a41765fb949190977456e1b5c1810db1301342104b9526a82459a0f78b9a7e74808a49243a0902d8c6485f887ce62697a72474a1fab0d1342d5ab7a8d9ea38d3b129661c2ceac177d63a59d5b62be8a11379a51055b36ef78817b677ac30f05bd38c700cda17d52b02e8b19f09354ae074b4365ab379667744363b9d4ba17c061ef955631f1ca916a74cddf05160b82994c49688d71612676bb0d95f6fc58d92970fb71c3c2a250b4161b32b3405abd605d0a94ae017bb28801ea54588bbf0b9caa8cb5920bb02730454085871469cbccbbb26911d934680afda6ede5b29b0e4a0f9b15d13392647ec9ab1922943c88dca974af1c95d01866e906221c901319e2bb4db5807d3b22ebc077834c29aa555226903a4b53c7b5d29c226144095e03a4886a18a26b99f389a71c41849f10fafe816d213be109ab7ed104114678d16242547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fac2d2405bef464cc60c58efc595da6c1ada9200d8eb1631f119e99b38970db26be02333be37e661c2bcb483dd1156a7e016dbe39af9ba9a7a6fa8173033bf4283e5160b1b2d4914f453bcf3406304859205118c6056243209c87a76a7c3259258786e6c64b0405bb8ae22e33b1617bc9815bf57b182748cbc6c4e8cac9a9a22965e560fac66beee32f7b8248c241cb3213194221c704bc821185041ae5510689a8d7c4ce5a6c3720e9c845116d2b3b9de703937bf500c9249fd3b2b134998ca657562b19857f6acf575264eb1b0b27d50049542d3f87041ddb755cfb340fd122e4c46663a7b556921b41b50713d71cb20a7888955689fa4e43172f134b1a2b628119c22c391408b16092cd6c8fcd6cad8ef34e129c6d5fb8881725a3b8180a14ccb625a65ae7c59f8b7888afb126f2d8ae8457a273c453cfe69726d951b3a241df583af9995dcbd73223884560258459d0bca1e794c94214276547d3d740a8608c33662eda195f4e26b90d86955c2b4c8470592d1c075bba0fb49b6732b2954fe76d0dc3b3e840865fdac146f03ba0f336f0397c6fd450770a2bfa5837f46096d3c673c562c9ce79b5e978c2a40450ed36b43210386a769de3a9063b93455b694c5cb3837e865ae61b82aa96661e57c41e405d260bc7ac84cc0e1c7515c47c320c61723177f0f57f599958dec24a3f81ab7f1b759c61487a243ff13790de540bbd1b90af233d8658b2805152183bb220e1ce017795ba97753e9c06620a85d4e28591aa6c1f440240e9c22a9acbdb568a98eb745ef435805cc00c2722b0822c1a88b8b80cd05ad2a69c6a356889c2389ac128c49d627a1f3c844ec85b82a405a2e1834cb753b415e32629b7397713aac7c70ef01a7bb3db86ae13b4ed51cc77e2a90de08c77d6938b903e05913477d1c38c98a80dd034caa3746018bc32034b27602732bb0a9cca9dabdb795c6bbe181576e69413c419674b646386b62c0eb8251572a630b087851892bbf726fca0b7dd8a170f19100d6087c191ab56f066a3f61f973c47fc62c331287dec02518039b32e7c320376b0fd82788e2a8ef38b1dd977889c2712ad258d4feb5f7426a4ed147e742b0995a97c2ad876e1860aac6ccaa82287edc68267362ea53ba9d0d91549a448fbb43e3f90802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b7008db565f7ab9c362dc38dcd3e30e5da873c559e9a9222710e8d2e7f6417ce699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = 8859218dac402d756e7a282c88c77ff1c320193e436eeefeb6ed478ceea116b288467862926d741ad4b1074423ea57f8f1d6a7b751e34f88947d5c80476fcbb5385b8dbbd21ba11a69e646dbc24038abde3e8ac75ff1ae80097010ccbc99dcbc7d220ca8f1b5580e9585a0c193439b6de6d9d33379c24be96072ebad553105a3041c501483a34b2e27d81a3ea479b18df3d813db7c08d949cef6ef74daf1a96e2c2fc3a92f1d865e352f39e7a28c55c81acf68d41552c4ce3079ab0f797ee464eb213097cf08565bb689a4759d3dce560c460c2ea3d0bdcbff0998be2594f0cdcf25098d70776f6460e4f42a17575821565481e3570becbd44e9402b3db722bb2fd9bc6ff99270e5b6ac636346ac846e1e24f58d4f7d86691abee15e29f143ab5247100dbe772271acc19d263d737937ddd4408b6989364f9605c626a1ce9a5155dfa2719b0235a1d6fb3c9eb231f4144a114b26620574d29fb558d3b6b8e5bd07cf0a86905ab3846e56b7bf778279fec9768d6747014400b2b6641292ad225d18b23329f126c3e0e018c109760cfd5643f1b213144fec5d69e73ecd2f3d0209537473b92b35f69eebd7ad649fa435669da9ccfbac5f6d56cae98c92d2ff71cd08e4f7f2223290c9a2fa06ca83438e0ee184df2316b1b626c2104c68d778cf971a3504b38ff77d8d784e75d04e792ef0b54e5b933ee027d5e0015326be8618e35675949874ce976d39bd39080f8c9d03842e7dfe17e630df0379baf004735009b86b631d87f263ac14b0c018da9de19b24ba1b455cb71a4d4e88003ba9ff5b26d02e9592c55afc7761d98cff35df75665067af96f7dcd71587701a31295498c81886c38dc7e4ddc8077f5636ccca01040cdd9b80352cb638626c7a183a8e268f60830e24af051179b2c71fa9c41b61bd3a9e822ff619434e4a3b582c6e7dbfaa886622083a1af2e8c6e2c69762009d846563b82ec926a4852ba381e6abdd8e9fc0d29ec6b337bc71ae6cd3dcf9d10baf3d5dbc44c1ff54993b736e6fe3bf683e68a2634a77f8fd2297bd02366c5dbbcb80af4696b2ef13a6a841d6684b3fc127d9dc242c20d3d305db264555892e2ea0f9aea511c1308ecd6a4df93f1e8cb66e02f8c5a8ab94457bb656693c068f706b6205b729258b69561cca577ea435106487ba79e394a039a80d7f1f8f1bb16018aa28d0e1558ca9b9a52d7ba3465d93cc4fe1565b24b8a179ef08315e474bedf202657c52e552c6892aed26403a7b22c45e657ebe229f5fe6603462369ef07e82ec7f3c74db76de728fa92d9f73b7b141b4069eb3e8a4be72da94b84edd23c4a4682d2398f16722f17cb28ef635983a8f60276e5f2070c2da3525eed47449671663d5c5bc06e298d1b1ca5f409a336292be5c666ea295ed55f1bab1e9b59216875bb7abd34e2dd18d503f22ab66d402ce9393ae077028327d80973b4b11b1afd6975b55e41e331b127ef2f0b8626c5e0f2c83067309e15551fc5a76b2e353a702ac80391f84ce87d07ff77a4b7c528137de655d951d1b991da763a3a1116135c29707e74f29ac2b8d1682c1ea01cbaffcacab644654d9ee7485d41dabfa19aeaafc1f2b3c650c5b065c9f8a9c84d786c99d633607e3493da11790b853c37538fef57246dfd0605cde145e25d3b3d13441f2f3c6ea5005526e7c7a514547ab9bdfc40e46b017ce4f47aa417101b6acde4f8bc7891fe9b63b505d9d259ea0346253531638e35f5e992a7c662e96b296c91dabe688aa0061872ec39889451d1f8e237bf7cab21a1ff87503ef9d8e84b6cfb7e88661e38f4ba121135d2d9433e46d51a6b1c82ba8827cdc1c79b56692b03b3761092b983906beca37a675c22b2f11dae846880dc90b91efc690b1819743c4952fe9fa494a3cc6db7b056e04cc2b0859a869900d90a38f2556a09b7c0b5e8188e5415547f8ffccd7cf2b815e6117a2a1a5525a6a385d1444bbea0fdf4b889d3d71690e04df0a19e3e2128aee9634638da69bcb1f432e2fae59dcb23106250516aadfcb71a8a6dd3a7de9a298e581a7a0bcf2a7f12e1a31c3e0f806cf4836d1f6f93fb0805a433c7b311dadc784d4db480dd755386ba4c2e80e9c37d77350719429f5b6755681ab3932e8afcdb61198c95b46400e3eb893b2ffaaa5171fb4c94dbe7780777447239c956c7689ce17fca998e1e1ab4bde954f63c757f523487397 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a5c798161d819faf7d27a945a0f6619d83ddd196b6f4ae58a4c48acfc8fd1c34854026db0cc665c43c4c0e4567b46867cfdd6d2d0ff9d0b647072f7593db7392395b7ea953611d5c1cbd5472787430654aa03b6e895cfadd3ad467ea51b9486f3efe8275cda2079459df3b9aebbe5d203b466eb4f6911572252bdc8fc5ea31bae42bdc4142e393d3d5f7c94ea03f796e0cf7cc71dacb47456fdd386527bccf6e53d13eeb755924a22e3a55f74a8974b38e079d8349fb3da5887d1a14ec8acc6f07a7519856f353a4f267d7600e5f43095bb013dfa70ceda3fb2bb59993ff8aa68652846ba60ebab3aa574bdd8bca9ec8b877e7b87a45041657d0264f36fdc2b713f4eac43d5a2fd2cfdb9a7d35748907e086d6308d3382d09e39106cb28d947ae3bc389ffe8b729ce568436b3e08d7450d9a810deff65dc7951eee45ff812e05d8bd55820a97fb90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2054cd37b87c51436cc83b884f7634a6a5dc419684af3b78d420d64681d5f763e94144539df45ac7fa46e728e5f54df304b474a435bd2518bd83b058aed078dcf86746313bd8118e48ea346596e3560ca722b1f6dda147af8c5733705bc8343331bacc5b5c8de424ccf6114955056329a68a2a74d3d65197c21ead2a49dc41e07e4a814a798a434145b9e3a5c31aa6e4cdac8a8bcab6b5274490f5c45b2b3d7f59fc28f04dfe3acf068a5826e8466542559ea4d9ff11b463e9a4eba1af172ec8ea643fd3a5bb6663eb670d5fcc2f8b651c5e3e60a9e6479536aedc2cf56a9921669299b6b5399537f2efac368e1291dabc6945bde69aadb9f552b2df19a73de26e4ac7d9b5c7469a960ac64a7eef7981f96c54ae5df4c847d16ee69dcd30b9cabc6e58903c5adc88882cbce47f2888263ecb6ae97a9b2baf45f23ee2e2939f5c8bb8f0cd22cb578b9babf90ebd6260fb1923ca88b35c424fc65251f8fd1d7b5cb7e9f5a9a538b5ea97ababce08bd06ec7d1ad8490b74462f93648fc39a2004db6ea5eb4c92e9ce49395891594353b92b6b496d09376fb28711d97f2195ea5fdab80cd5fa6353cd62f06c80f99eda3ad7573c4fbf0f6cd5d6b63fd5bec5cff572fc8460385a642f6f90fb79a9b1cb18cbcb34bd87f7eb595f0598c687d9d731eefbedd7a0eb6616a88b8e33571bfa7597be4cbd6976b93f3fc2c088de3ab59dd0ff44e553a5b2ab143c46df24fe1e816aed7edfbf7ce3fa7f8b282237f249aaedbd3a6fe8771015ceb812cd5fe96e02c1bde7e9b961d2dd0c834d8d8a8aa3815529218d3418c49e176fc7ed8c3d35763c61d585a78664fbdd12a9ad2f35bfbd7e96ee6cf98dc296537c985577cac3f4ed568353ec2ca8eeab4bb1fef393d5b3cdd25305b148fd8bbe1f60b5871e9c9359a46a5ead03e98b61e8fc51ce9f62764301c96f68db87fa6273f9fa3c35b2cefd92faaf2f74edf73ab5a09e8517dbdd7d5cc770da5177f6c3e49348d138d19836391a54954ac4a0d0f9b154ec37965422019c2ca49cfcb8e317b3eee22faf297b865da163a0befa9dc25701f7e847a05754cb733620a824f19dd591c51c345420f2f6b8f3b846fd356e78b87f4555783dc39667349257c73fe78a61686f278a8696efbd7871c96f9aa472ed463ce69fbf12d6d232af77defcdd00487e93d7a983dfe45755d6818cd5c9a82114b3bdadddb9d9aa53ada6c5a5addf518912a86c2493e74ecfdc478e4cbae97b61b0f3e475f8c1e9e7c230946a1aa76c1766d7f0f59b56d6f7fdbd7579c54ca14f4deece842d5307627f25ffa8a9d0ad4f46a596e343154aaa3ff7bf496b8b973bd4f4c985fb7ea87d6e4cfc47490e23d712155a88c23f9c61e9f91fa854e15fdd90f3a99d3e612e791be8d7f252ff7b9e54a9b6cc6421a9e0399d4b6565e3b9e683a6891702ba4cfc576d24b58b0f64fea23f5d0a6c67ffff8caddeb6557dd7afd86217bb5429ed9a0b5906b74a2dfc68b34797231c64bfae38958f636fc94b868a6e342c66017b8bb1d1bf540a3f5e91efb76cd8eb4c9a9735a570f3bb3cdcf838045a94473a65444bd2a783813ed31382b5ebaf4427903ea5a7c731f49a25c68fd31a979a60766269eeb62e8d9bddf3abbc8c923a888d9d3b875cb723fc5fc707206a4b96ff9ac116a585f4394c4e83574bd16364b02bcc4c89dab6231e5ca7550517a335536b08665a136b47cf76ef816b037e91c3aec389b2411f3b397c70847a3f178509357db63a5d5caa882b2079644af11f01d18d9b79fc92744850a7e8b1c39e479c57b887e854cad028d17c84f5dd90dbb2042fdfc82db061afc7245c458b05f934d08849bef6bbd90349c4bac3ce44c1a51c622734265051787f7509a30d9ccf98250b42cc8e75c6d62a5a53944484578b262850e06b8717508c75d702783781290f64a412bc3f741312ecb795d15c17d198334816582209606210b73865fe79662943552b69b11bd141637b054a64497cea157e9156da70891da159c3e138f86c87e27376eab0204f8ec1edcf49ba47b1521870e46171d18268d277c1467b3be6c8c6895461166fc2c3f597fa6478348f640e44530f966c3008902c8625b46cc6120eb2d82506b01e45a9ed7a19f1c0df13c0346aab1f2cab8e01032b1f303147b5ea7e149b4bc19772408cb923e06614c9b1cb76e0b1d2eb1c4d1f6bd8294b280cb9ebae45cf0943c03b239677b7ea7c71265b04ca7c1580578768deb1cf10a2898143ef9d1c5d614b76a8322331a09c48422fd8b1c822384ae1886ff108e930692263965e949319ab94ee1b6763e460a0812780428aee4d446a61254722c9308c512711ab175312e39467aa21bcf454b8289803d85f33400d659dd8369dde71be20907651bae89d861def131ff805f56557cad430d22cb84a4aa65ae68c3f278b5816b86bdf57188240f60b54a8606b74cda0c47323639a578eda52575a32efe03b349b6938d763dbf4c44f13a0f92f75fc091658c60a32691a52c78569f322521799c91aa2cb550c9a683b061647cde186ea2ba57a8a1ca929420ef1895f2193cc6944a26e2688e611ec0124269f8c9e18c4032b731db827fe2930d3479528da2c2acd56a8182231b501b05c6383b070190782225d732f84273eb9655b2a4c5d04256a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd750bfbc28696808f52b13b09e43ff5cc098bb2a80b4c8f6a3c8a805cc6c69b7b02ec4f67651c65268431057fc7d1cadd8c4ba4965d67db44ab0c54926723a0842546fb0799e71483169ad17b60f9353777765157bc7e25d02ebcf9198c70a53bfc0fc7d51a42e260f7c5222a519937a48492ba079df30adaf127db4ccff100112e155501b3719a2a209983358771b05b38ceea677be4a4b086132c12f4594f427400f6ba5af4a07673464118cacd99a8ae5501ab22a235173412479cd759139d18900ce6ad44e0ca5ac230caeb82b6a98da48b318b620ef7093f06f20b5a0b4b95d986aada54891a00314094ca9478b790825a368f2f092d2978195ef2c52b64602929837d0b3efa65a61991ab61d8cd87f618cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a43272d8ff943261c5bda7a4f1092c9a6b7481f05bc3ff05ca5f1cd0b2bceb936233e0952f3380c4b7a1612c5628d5a6a05f837597c94ac061658c53f3da8ccae56adfa5a8156638be426cbee2025860c105da76b0e953c69957e649c5bf7151c77160a1d2ac9c541a80ab20c1b866c4fea987e30790b64b8aa5b12bf3429f47585ddc8780b9a6e1e7a3c030226ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf47186107219df88962b302010b755e002cce9d87781e4b717825fadc62a1a95589694581a18a188143d22f1bbf8769b3da59813fb963a78adb8d82b6155b02889371df684e3060134e738c682a03da9c62d2922c06425ffe8c2e18346e6f5296b7c4722e065d984cd17c8590b202865761162e6576a403e2806bcf618101fd5155702364f6920c45470bc9b1180b259c65bb552253406697e2371224a80045295a0e9b06899d06bf2b5824c9b2e6ca144647b01f45a811102afc4c7682e4b7ff8bb4464987757752942ac106389c847ab4dacc14c22b40cbed29d1e81c89704c21ea25747114f7b910ae8715b55671fdca0545007266f08851dc22446436e15827a1e834f270b38e5ec60222b1724c6054af281747739178c49ee04ce0fd39d5e7cc65644ae9a60303aa54a28a7c0ec4ac2ce7149fb8932ee26b67c2bce886a5fc9f321f5b06a03fa01d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165143b9c53320cdb1b7e8d71efd1f0a1ad5ad1e1ce84dd9fe7c92f19c926388e3cda1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 2043ec62ebe64855ce8a3c4dd252b9c6c7c7102b4a57b402a09f458f187cda36de17f2ba0f0702a7a49620d0a125036156a808953dabae6773b7085a9cc7df2487ce4d447828837c2647d01de3e84970a90c57ddec48def3e04281b88a6b45fdafc08172f024c563090691878a744ee6f372e798f06ee94b05933b58ae1147ccec96dfc76a6a9bff0fa662f5cc5a322292308300695fb8d4cb53912e7b4dca893970150ba93e6e3f1b6d8929c1a4da3748a6d3757c3e55e7a7f452af71ccccf0c5cfd4391f93d9ef0c415b164a3b205073d6633f07177ff9f533a40aafa084e05698b59207e2218d7003064b96d18f23ac12ca34fd6c652699340477b94f41ecb0480cfd1a71a550020a11485583a01bbd0ca04f29ce34fbba650f93c2098e7f0a925054949e9d31995ae05dceb5762f0fe32b2999e6e5a61d5ffc184cfa143e701d01b64744558e58926ea0ae3e8990a73008fa4ce137ecc722efcec77be0f9de7725544a9bbefb03af345a73b511cc0663f4d5980c97646dbc02abbf3553c9d4aa690026fbca616b7b290d3d67eec14dacc9566d7d0753098b76b0d7326018e8213a68eb5a129fcba227372468e04c2912b2e30391fe87abc25b9faea185117ee9fa4ba0efe0b4f01187919f45acc11b8c9c6f6323bab07beab92550a6cd62336a428052dbc55271687de791dd52ae20573302dbdd0e65750e931e19e56a612ebd3bf86cd95eb7dc5a25bb96ac2e0a374233ba0be71dcffbfd32fa861f05ea470bd8da19bef702925f31a9181b319c1c1c027139c643765b2fa9611adaebc723d06436f4923f2523780c0ac798d4a32f3e1a0269d23655238d38c24e597d20164b431f3645b792a809b508c0ab84363990efd5f7f0cfdef164de6801999fe9cea0293fad6d9e1a49b6fd03bc14d25e363754fb7f6352265b61817f65d7fd43d75eb5e50eba144d7c6f68b52724e3dd3a7ca118bdedc1f7e26bf722fb6f2fe962d1c2b03f8ac82f07a08b6c108d724e197ed65d0e5540bb0529b0cb1407fbf6e712bddd2744b54b1564b5aa789c65b9997f27257cc81affb85164bfd2b60aea2c4d31b71bb8a5f02cd0d1ae3909bd8f5d3fbf2177eba1492709e4f6c53af4619ac450a778bf416a66fe7b6327083434ede9bdc9a1ff624707cea766b53886f290b40999e342296439df4f1b8ce20832361dcdbd6429deaf3115186cc4677ed01da35e65001b53c711d8e8e83d12f41c8676fe0a3de5232ba0256f08ce3d80b500f5b88c9474ade0ee08d160946ce76e8320f8b2ee35e71b6af0f7361813d3b42cfe88cd79bb3864aa74747a579e7143a013acf903269d4a740b58f6390e804c51d87c0266afbc992e80b27a5ba512026091deab587f93ee9f73fb6dd7959b0422728183cbe14dbfe146a6dfe8553ad3ff708b411e2a2bdc6abd6500564e847b8fb447560d9d77bc402c8b131a2110ce92d936dade0f4cb59259b06cb021b681fb4db0cce6a7f8eb43aa9d569407bcd3e241b7b7047b2c91224610fb6acbc50306fb75f696bf8ca92cfc8e7f2bd5b9c5095f52a08acbb5939a206e392048e3946f10cf4f22a9c9365f9e475e09eb95e42b547fa06f6be566ea796fae62818c4627fcda9de3f1a49cd29b6ee2f538e5e92ef719a631a0ff80502698846f2a6454a5f8b34dcff2a19b924e49a71f57fa62819f1fcea60be197e7635802d5b2cfe3ba8d9a11eec184ece5d501da8525ae45ad2a2a23e4d7999bfacc24a8bdedf78b8619d0f13add32e8d078b3cea727d993004f5b51f978eb86c8b649f4890534e182eaf9040b26b788446e2736c07bdd707cc04f1756db88eef70b1122cbb96bc88c78b0c84c1fd11e7fdf546e5756119888e44d9e95609a0dd74fcd17708cc8bd4970d7a335c00d54430986be57cea04ac1d991a779b46249a061ea30300ac5dfcafa484f2f4e184c4389e3115bb4f7a36787f920d85bcbe3fbbf1450e61d6faa050b91a3374d2f5bc3c12f79e58a0c155ec89548812ebbc27dcb8f6ca73de92b216e5ecdcf6df67dd086c7f171d7d70af96e2db706e669ae153e62aec486f53e30115538832f8668ce478cfc75b5e5bfa43402f1c59db5c88012b56c7ea59f404f5dc5f438b06232160ad1619c23f81474a0bccc4ebb9c6b32a0297ac14be4af396ba9048231ef7de50bab59a300637517159fae0478351b333d6d7ed8676784 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b04c33b257b19945fa85b55625fea1a43bfab72c4810b839b2cbff51b5d2cd498aa258373eb3bd44ed3974eef9e4fcb61df589878d9ec4ea4333659f03ecdfab236cd4f8e5d3f9524f9da28a4adaf869735b46ffed98378564f9700cb815c43a6e75de54e6f67a93fdc0385696274e1e73a12b5960a94d9a4b4564df9d9b797771b48397835f6fd69abf516a73f9eb813004edd71d3a6e67c6734e86d1d7d9d3e9d142bebc1d0f8e293f4de4846bcc6837fc243c54dba144d4dfcd7ff3fd19b8f55ce1bc0982ffd366530abad387946e1495a4cd5d9cfbb62b28778905ab7d576610a74b3daac9768ad51b153af7c6bf0177a4074397bf5ed411cb33ddcb89519e990dfb85afee5e9f288d01ec5628034a4aebd1da19f83493baffd36d225beefe09628aafafd427b82f9bd4ea44319f5ae6bb07bd220f6f2ef550b919ad01cb3744b37103eb54e634d0e033670025e0776698e28b4fc367a77f1b4690dcf916e8ccf1fa55aa34950157f4f1e66ef7ca8283e9e7b60ec931274d9808a8114dd4176bb69783c094bbbbecd5b90fae4e7cdb9768498b2243f283f6a079a9e988ac6a85bb591fff99bc67d27b0ca9932a41c15ce93467374f133bb8539c2e5e64f01eb70b5afcfcdacdf694ecd835c4f5ee74be4cf6b55770ac04e47666a431d669fd5775a71749923cdb223abe36284fc98dc3aa2a41f45a4a299c647d6738595f87f7a47b88faec6c088c6207646d99cef5f56a2f0fcd3ea85202c7725dfc99d05bfd537ddf0f89366a3a83f8dc74e5af7fc58a62216ea63334d3ae8cbd0189e49b94ef5e0ba193fcf37ac57a4cd5528d1d545cb75e36bfdc3ce63951cd9a7b18e0b95ef4f4bddc9ebb67bda9b2ac5fe13e73e123b4a858a7e60637a32eb856d56cf905f7c655e4dc84f9fe783d56d249fd43e33c509f56dbfc7aa0683803dd4d228e39f829ae363cef48096fe48bd9756c36873cadc64ddceb8d94e6f8925c1b81ade69fee64f0b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd54eef3590d681dbc7657a777bc267637daf955cd93452eda06efbb90a83f95a9d986fb559ccef8277893373e701393b705a5c122ec3646ceb364367c83444d30fa438eb3a479adbae24f70cd495563a9d85c566d9e6c467dca66a3f36370693ad5f86a9a3f773af5d64e9bc73ff7979a65e0c98e98beea7ee2aa494fbd46e4e7da3f9ca0f89bf34f79e8f7eb41db97a3276548376ed277fde54e7a4dfa088b8acc5f02f598d1494bfcdd7c323fc5ef6c3b4676d6b3d93da2e69c96744095435fcadcfd24d3d1610fb5c4b988877ccdb9233c490a8b121ba7821b529de85e648e68b0565d50f735d1cb54cbb9ecfc1b9eff98fa654ef1e877c43c6e47a2b8f66196346859ce5344d208253ca429f76b884dbb3b7a30ac3de983c75ad73996adb62de7563ec9a4a715bcdf376dfb6433de79ec54e660f4aaa4b194d15026b618a4e5e66c90de3fc0b015aee63b5d8b3cb9eb2d6e45ab4938bc86fc54c7598c6554cf9ac35bf213c9dafd144c8b56f9a66d382778b28d666667caaad49633a8f9857313e8eb033374b5cbebacc7f453ccd8e77c5a9abc12eaebc1733eba09d9ec85a79ce5c1e66530271eed5984546c99bdaa3ed87cbb63cadab07a18ad591899470582aaf443652c723d954f7f5f9579f4a65f9736ba1b34fbf7f8216be4ee55da89297c8fae5b0706314b269a8d88ca283edd94b7e09f36edd7b6b2bdf32f94c9cf760bea6b6b60461f46d98afb35fd5fa23c40888fa9355fa9ff43a8af57a59e93d5d39f37f59ced2539b49d87f84e5583179f47b35fbc5af5a9aa958847cdcc0ce76ebc96f2013934d2e4a0ba28e4da38f312fc6fd9683048fb308b159205f7d50f9bfcec0cdf136a62333d71157490179782701fe59aa69b45865f138efacb794acd187309c447dec5ea81643f82945be8a864ea1ba348b48214e4c003a641d4d74e310dc5a449fff7d65a5f0f915d43c3fa8646e71e9a5e23a09afd860039cbca08f131948c65cca097633c28eeecf09ed936c4358bbabf9997948577b7504bc87dc53bdc96a68a4c5f9ef5fac66748becada4dbe654836895d795f464f3b34dd6f927aa53527a2d2ddd0c18a87f2dcdbb599f84dea64e96c5083306092965daaf95fae22ab9782be28474bab8785f6030f9b360a861c741619619a74a96fd30cb6334b6fe379c9404f95c5571b2143657c956e031f2a5a03733aa24a73224f89106f7514a8db8515bb9c7fb4179b9b410b7197dd849c3a869c687705c692842aa8bdff5169cf0937a0d669bbf54c92651449252245476b4ea5126041b5721002ff129272fcb76952791b635b8bbc6867f051935508aea7bbcd722c693990e3e8078b1629d21c09e1b417795445fbb857e8fb4f0a1aa6f761657584165d38ce815307e6d778cd63a283e081a5372b0ef040b889cf8041cc324145a571031f5c218ca816354c2c41817f196272976c2ff6115f5257cd13b373bd2a757dab65d1e1863ca4b7ce559c73ca919198ba574a9ee64047b85a6afaecc043327e0800cb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a6fc2ef7d2c4d175c2c8bc812d5b3d54695027a91baf657a60d4befe7562bdf620bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b602b02cd036a24c23816c96deb45c2a8cc7d623bc31e8811468a7c2b85c209b27364c4956b6c30c8094af8401a233c5e4d348980491ad24b04dc2706b502a9c8390ba3f611344c44bf50241cfcaadb7851685c73603b429eac840c6b9a7ada53416470f13311c2218017681204e33a588981f66a02b4e97f1cb8ab61e6a7fe45232b5545a3a35eecf43e67a4c29948206088b062b81875b632c1767789563bc947a59305afc91ac53387925b4b3c7ba24d84ab126d3b88e852433dd0ca40892d3429962be6cbeaa85a3abc46a27b525a562670c801f5f0566a7558197600439a2b98b16009f87147c55f99fb109515b125963f7240b12a4535cfa22ab53a3c5eb8c2500ca5ef9b2d26d93115480863843656c59a85b4a40cf8059d063cd2e7115d862015d059d3577cc1803e6450b811ecce3cc83e039520d6b23ef8576bd342094ff2a908f42f4ad88e483229f4ab41db2107e48aaf1b32a275425492b7bb423632e42a6c31e320528327713a86b4e83e929b217c69b34ec3afce8628c23a6747666735360b7e70bffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c4756421ac51ec963493c2d72791cfa2c69b58bd5463c544a3ca679b43ddd13ae979bcb158744d45639586959d6ac5784c074d0ca20f326696b607a206895d495f61525793a839a5631cd94bb7e39b609db1caaa3144387c46a22b2ed393060a679bcb13a7c781aa7be1a9d4d3a58a9831f15372825a08d4e41d0e3371e9f796ef0ca50e128afbb5b83ca78ad7ba50276ca2244b3452d02d803b0e8854181ed57f04aab2bfbb1a48cb949f570eeb550a9352c3887a2c37341d8881beff0acd11a8714665a05274613fb168faf6c151277ce03b9f711034e642425aea6e37f536c27ab4c859a64b96baecfa10abe982fab01e82a48538c12f2f615abb815f7fbc46d20378c77626fd4447fc088a7cf626180b2443226c0d560d028b54f884825290cb5ffabc1e152626e62816069a8f9965d89a09b9a19b9c8734a2f71808733a49f30bae54659c375de1a1181b478e08fb7ad85983d7809a4c7bbf67721beb9447191a63a10c2cc709a2d9489dba469ad9c035664aaad90bb8b7846152218635816ec4b1b39ad3b1e37201fd468a134445e183bcc3430cb2a9015a10b0369c079e60a42d387675dbb292985dbcd4b954c75b56a1152942ad9ecb12c8074c1998710826b4b1044a1c368d4808d081d7be1658193c1c0f46739ef1043f1ee38e90ea989db0c9d6d8568eaaccf1e986e4f3b39b596f4bc11e32fa03e10418dbf464f435680dccb76e0bce29005950ea7762e0a86fa4cd5e8819f3c95ff713b006155438d9211350c317589a5c599619530b664070f3715bd3947427476124f328b850603533a651a38c4119c2da956383c0090bf31a378474992636eb10b079b319c821b4ba9336f413929850550c9271f547344e682780eb9d2dc84b742b49eab256b6d8149a904ba0293a0a40731b98751a71371059b84d323970a385408807bda11497c42478bca048b1c50ed3681aa8044e8884458085b4834e313825b3951e8b743a765a166bc1a133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75f2d009cde4abd55a2c7417c9341792e60eaa8e26b53a3aae805746401c4c446f56047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = 405a96bfd02c25f66daea1440e632c84fd0e021f62a71ef46f1806de1ebbeed0ce4eaca6c0c5792677a2ae3ef3e66f36536f3fd37b4a2840fb36901020d47095e73b0023d1ab420ad313b36e5d4628c99cbde76099ae1282a3434a7ff38bd5de115cfec4a56362dd68c7ac5818348b1aa3a595b724388388f3622f7ca0133fb235e6c82a28c1f4f49f45e654d3c455298a18c21dae8eeb5c2887cc258899395bf55d3e2bd75a74eac7ce9a01d806f4f5d3556d2725a10cbe44545fc0915aebf08ca5ab934ab247670ba701ae17063afb56f753987118ddfffb4337b5dd48a8cafc6b692115b9d8af156217c5f1440934491203607da68f9a90c5843264e893d8a872dc2c95c3d9fa93c8c05fce5022b39fa763c996a30897689147ff2b2a0379dc6318193d5ea90093d83abc3f51df9a263a3a7895c83c30720ae773ccb4e2e805e2f87c559d274401602642d7b992bbf63e6035d347d8d6300b345205bb0d6cbaa2bc61326f7be2afd0bc2238621b75e69b3292fa42e79980642eb4e17f77c5a797e7eff2fbe73c1cae2e5b5bbc548207fd7af48e443f259b6727b2f0297b62389bfca4c44aa3020e583efa081a71dc29ed739d30d48aee2474685625bb241e0bdadeed100931e65d6dedc94a54e6df203e702520234230b738edea749fd0a8cf9b2e2e0e13ab3dbdce8cce21b290bf0bf42493b10c1545775b3d1bab14ffb6aa26d5b1a0db66511ee75e57422c4eddaedb9b5c74d49376cbc6b9a1d6a6d1bc4854cef00a43bd4bb52a8d3fa6444064a11393dc1398a2c5af503cb97041f6de40ab849b5cf71887be298218821fd6aed1775bd27fee8a532e94ecd80733ea2099d84afda3fd65bd084a6d7ffcd4433a993af0551d580922bb0a8d3d23f9032d29450a2a34cc8eb123b95d9fe4bcd8ba7d4bd9eeea98279f02851d268aaa3de64db561acfa717657e905ec1ff6a31d1857976397ef4ffee04440e523f7cd75cdffc64fdae8bab29ab5eb0fa8f6de7cd5bfa072c1b4a63486238713e9e06e9a73a554232d5d6ab3e09652ea4434778180bc2427e7a544c90bc510f90f227ba29f6279f033a90b9063da5a596eba9acf7e627aef79eea6fd39075ed8112c7261587d941ae6cba3a19bb05492e11339d333622cf2396a3d41b3053752208766ed434c7649a1e3d348bf5857a48c0a7cea8e155d30a046169d10988ed0ccf09556ec47cfa37589a4b677c6d1e27d9742ad401cc98184328a395a70342234fcc219b5c0424dc61aa73db27177fe4f7f56d1dfef7c62f726c5b508f64d68ccd8c732fc06ce1fdb864c3f5401eda20576835d82d5b24b7e2013d8c5ccf1aa5f401566be406f7639ac38bf2c7f2389cbb966f6d1f5a493d6b5507d04e8515ccc0cc5410977816bb0310ae5d7e08ea3ae1166b230e0d3482b7a7af0761cde220694e2662bfdd29ddecce7bb8d912d9352458112a26ecbab3ecc647ed695e82e2c312b16c58665bf394410f4c5f0c422c39b6567b6805668e04712b3fe49289f3e40995bdc7f0e74b1c23ca1688a05c06688f45f4a65e945f06136cbc139469784428426e1f616f4e6016bf652fe155bd40341270e343503419d726481128ff7a263d70f0026f6f11c443be9f6d3ecc808c61369e8113c0fa0fdf49c92b9361c2667c7a9afdf8ba46feb32e7b78bea54898ea55bfe5c95b8d73641f53d5416c0f7bc38dd4281f3e09af70c9a7739b257d55edc7c7ac17bcfaeac7f21cc93807215f96996c1186d1f23e25040456332ed86d9613b91b689e5b20024f279608974d65d8419228d3bdcd70285d6a21305d23b1fb7ca4ed7e95b63eb3c63cd7670e25b8a0680b03642ffaddb65d5edc8a2fda9f164c2f2e5e3d8aa903f9488573c824ef049048770409c8e6091dd07885ba404cab3d07a8f6019866984641e4019f5266d11c4ab7432645aadb519b46dc8727bc0d33fef2f5f58fd32f1183171d797edf314923c027fc98e91ed652a57137fdd7c75167d51d150fa91a897805c4a28c15b6704b3ae1fa199ea42dfc6cf99ce3e91501db463151987c60690ac7f71644ad36c91d2c5162b6cf40119980e2093065afde74d46d4dbe83facf91b3104731a689cb8d539ccf042aa32cf47c2b085a37d1458fe2e8ff9adc78c88b17512dcd71bb6d6955436663373e66550674f567284cddc9926e6e53b16ed4d93c60c36c0718c155e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a60e9e7c8f405cac3c8f45bec4f7de2069dbd7e543d465ba702cb1448cdf114cc4504d4a32bd91c638347cf5a4651d6a309fa0b4f6d0a3d86ab9f57e00fe88d1887865c695c3baf9ba08356eaeb4052e46e98e7f2bd56bc024d71b896d5b2cbaa0bef4cba45e295adf300ad2e4fbe8272d59cc987c6409e95abae2d7faef288d308b9ea3b3fe71d9d4ed166872bc8bd70d44af8556a356b631a6fbfe804cc09c63eeeca476add8e43eeba767298bf2ace9fb2496e0c573938babcd749ee3edfe9817a3ee5a687fa3f4e8fed829afe42c04ae9715c4a6a8dd73c6a54c16beea97a659da476e49c1dd1b8293ed4321783e0a66a36267673f9fc2c7463669be742987405c26f1f94b87ce88aebaeb7bfd787116c3da5b64a7e8956321463b351a9754ad389937b7aed431a60f8d309cbed2d8ae67f859ce47ecd1b3cb11a8a70d3b9b93ee5531af60d1874118ec505fd4518987e2af5ed4e68bed2cbf676589aa4e8833e04bd17afbf666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb335e4421ec75e96a13b5566e8258e36d34a76096f9c0e3236c3d36bda5e3d53eaad3ca33eaad916d8cedcd3466c75c1b66d3a3f7f4c60a796e0844cc0d79687fd86c61dca0dceec2e936ecaba44666daaf0a3ec6b9ff98bdc7fa82aa6a0c3fd361b3335cb83dda384188fde9e745bb9dad08908cf6a3eab2b4a7b78036704153359dc4fdb5742ab3c39a356d05374cf3107b95cb771ff1c9592d59c810a93e3593169bbf6de95d77dd79a3b3aa03c43fa9d177d7ef88625cf85aa0d99d2edf09a0bb0c425ce6af9f21613b2cd596aa77ba2bb98a386df898e5d4d691e7ed16f33e69c43b64e438c3f74b579c1a6cf7b0d95e59836aa499d7f768c97b7bfb19f4756561ff69128fb2d9c80afdefeca0890c9e47bf7646850fea94e1d83d869d5212431b0ed93430d4b45ad90ce7e357d2431c923b3ce08bc836b3edc8fab2fa3c508867eae87bf2768ad61d4894c1f3b6f96edb52b9b3eb77a8c99839faed8704c907e258f8e9dd1577d78037aa1ab87b03a46ad3a0a30c753b8bd89d923b7454f84c67ab6bbbdded5edc36ab6ab67c29ced3a54bd06f9c09d1fcac8483e0163d1db6650cb4ff8abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6601add40489d0534423786e84c95d57bfdde9636bfbfa76c2e3f9625747968f53d1fbf6cf4f95d6cca45c61bfda1fe899a8aefc75ec12ccfc3a2dae6d8aba4e06cdcbccbfb72c48ef564d3462ab49cf6576d8c358a865de1f795cc16f9f5be3837b6b1714f50b8e97f7b1e6fb64addbd1fc955b49a67094cfefbde8c8bf3abe4bdabb787d3e45eae1d8a96e3f06a4977ab1f8866e596dfca9d68996d831fea448dc0991561af4da96bf490dd5538f17e8098479a5763787939453a7a87a359643885bc5e6e49ea048b5ffeadc65c78e4a9c91726dbdd6f5352596034b3558f98637b43d61f769cbe44ef9c7642393e8882caa978996d1d4fea92838d10ace8711ebf85de7ff0bdf71eac7d5ed9d74323d234e79089f5b9a70df77813939b5a3b234fe3760be892d8bcf9bd72f387305ee56b0289d8acb477e0e744d14e3eabac316c13c242b8e8cf873533bc3714cae36d477a7ffdc8e72db9e18843f4a3fb6b0fe3b566bdd93c74ce56abf92755cf136f79784aecc9770a136fd9ef45efd79c99095d1225885efea752063af9e45ce6fed634c8e7f42de3adde3ecf16b7e023cd6c39869b98cb86ea5ab2e655e8abf7ed83a65d7a849cb68347ffe6423f39073bc7a5793584acc6104fd524048bb9e99e02597eb5e68a7b0ed43ca6d3ecfc8c843d61f6df7124e4be6785fb3a4d6c92eded5b8cde7889ae037bb338e64c69ab5d96296ddef899e54b7261aed5af54a9216890e94fb0287bba2698a4201f705a68888b3397311bb9a60c894dd7eacbc44f855db2132962d0f8a6da9fa26594a3e2589edd2460cc6fa57adc71753a7a94e7e34bab8fc1d9c6896f9a9abd860efccb33d8f38c1abc55deec8aa6c29ab6fda3235d98fdc2f75d92b65ec9a9794c8a7e6ebceee9a27a43832dea3e4b9bf64dc1c1fd5c3bd53c2504e7a9ea3222dee0dcec6262bbe4114b566cb55b5e77c06784a223b9cd2d59478b608d2e79b1dd02803a272b54f2ac66498ab1f621abcc61afe10141eaa935897f89208acf9b3593aa90fc9081b8993d48a84aed0252d7f28dd48571f1b318f2d22ad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9c211f8e959f0d75b1e11486f197368188c8eeba30a0865711e046f9483d3e953a55802299f02968a35374e6a2b9251af66790b73c200f74b5fae2c6c4ec024feb61db55c28d2a99a67436bf5879835bb42fac07b9399ddcc01a6d5739c2c4c4ab217a3e28a06e6ab367354195c5080f334e0674397556047fb02d195736db39abf7c61e02c11e9da5b1c4829039f159ac3baaf5e47a2e6c2a17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd492bb4dcbabef3c20f83412a6940b78053e26227fbf7608f2b6233ce17db500641b295e9d4a468486818a9375e074b1de9124cd44c05fb975889192666a38ebb79f0e80a21d1c0358f24eb4167dc1bb2cc4fc076bc634e37421e0a5054490b6f45695e59cbd4e7947204c62cf0b61c2422f39b2a1abe24229e456cf9b374c8a17c85664f5c02b575a640074354e385e36a5b0d373bff3105cdd110cf0ca235f3bb18a051b4894c26b6c6b8a4a9d185a6be6127a1f172fa4e75971552ea357c891210cdedc7a0f3278e930a0529b056820c7dd699a436b80017354d106698401b6092a049eda3a07674d65956943b96c9191340046148aa8c6837acdbca06fce4a341d526d437657388ba7b7632085a921e447024c5b5ab9198b7b7a6b8380b4daacaa6b17bb508365c34b8145aa3b2f5b11722345d80554919489e49433bb558a3c332eb12b1a36746e5a531eb2a6afaa1532183550defacebf4c6bfdb0a035faad062b1cb2276505da77dd99935b1a3bb762666de6506d3cabcaf8b5dc876fbfe55feaf4acc4a628e0347a66f424ca2095e2a3605075786f9b728b5905ac09113e217e663a91f3430dd6d4244bd2cd50b69968d95bf9b07c0f352912e28fa9f0600943a0ea1578955b314ec1bcf13bb4cff6c1793b11cb1b08bd55bd850136e539cdcba0c8f8b1a1aeb183dfda8b64718bb1d8707889c74d92737ca3619e42b7d971783219882b14c671c5005c352540cb5621c6409366adfae73b79957539f15bba26166f181a407b5e7bbc14c54119588b630b782621eabe39567032d76716b9684e217895d82e0ce9473cda40e0065c2d91a846d7cf9e86b934381a36f130336c7eb7913d0aa466737c8aa34453e4c0c21d098906e0229afb13b96b6e717a02089a19d479826c585e1f8695f9586b696c805f0533970ac5dae753903044ce0cb180276c4caaccb71169080474b3003e0296271fd891c1a788a264482de92b47549bd2867a8024bd65287f80b25dc18771f8f697d8a830559b544dbbcc8c656db07ab70174855192362dac79783357b199b090840dd5d474227bb8502528cc5659fa1b1575c7798052393866a48a006ab2572d7b8635e71448b1d48f0175baf92bbf98e12660f6730845164fc42aab8480871c3b2f844cabac957f62aba397abd4aa1319e7adef132aa7f55abed6143efc5483e2c32b1aabfaf3161bb24c19e50e95673fe6668617111a38525fa76cc314f891c9520b88d7b82f5c415b7310d20b5935849ce2d138aa162bee6a5822c52c5704b1f1b6838dc88ecf0b3acf5a5868f2576a58730fc7b986361dee901f5e050841ab06364c72029b259a754f74a95b32179bdb35888b0872c844443faac6f9f67aee9055e4f909b3d424d6167725e960185738df3a30930b4d74dbae5a07463126b9c6ba257ab8cc893758759b4d24f75cf2f745bc6337e366218716bb4c5b8d7f0291488c8e20990faec84cad2616653104d621b3662838c0d2a27e4a3b85b25f22ec350469582e75408ed36141033043e459fd7b0087077aac13058519ba1c210f68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661e007a8484540363321a08975f024353d72a1b08252173c874e515e543ca12959235537cc4f314f7c81015d462e2182130c24d3f572de234441ce52e48aa67cd8b2941508edc9c421ed797b52343c6c792e4e8a4001936ad81108e4080fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a1f06190bdfd692cf499be99bacc4beccf048c89926769f1b254cca9a9a44089a8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = 64ce20892558f065ab2cb0e35bc0ab93b0549b77f257c05d6a21ef7277194c7aeef035a169e76c0400afcccee0e3025ab1f64ae4f6b23e7fdd77bff46158f505e55d5e153c68ab964e2e9d45ad06c96735ac0eb148d757b0a06fe10d1ab334083ab123e72b863998931997160f7d5d92081dbfe1f7b25830b0e70eecd49b2f3b43543ac221c981733f4797167704312fe150aabe2e981dacd7e1906b239de9fb2fbad87306cf6aa70286a787b240cded1d15b499654f80b9bf492b09c34fa7d39b1c7335def5100c78aabca92c3cc6626ebd4d7969a164bb9badf607cc0bd6e6d7a72415902040189dff9bfe6fc9df1bdcafcac77cdfa26fe099a61a3f6febd887cfc6f3a80ae3af13955f4459dda9613927b4a7efabaa9eb76a8747b6da218022f6aea23deda7997953a0b0e6c810799a673cb0fab21d9949519e8727d601b3bb0da61eee486e94fd666ea29f690f5b30a76fde6e906d9ae3835dec164e08a184d6437479ee2f52304710617ee7e27944991c62240dbc0b9a4f534af0c8f6829a6d3a55b5cae6db8fb8207ebc183f509f66ecb63059f1e2db1c56adca32b9a90d8e0aca443610d7ecad93561689093191da6457c6610347a8154e40d7420546a4b9dc89cb804e03f4e3ba1665680e801c61c6bcd08976bbff1680038b6b47a6bb00563df5ae9b82b406a2351452472236fc4fa85e04999ca25145416a7e63fced57bceb621158beb7192ae5b227bbb7e0392bf30199cb345382f63ef22c0253eae4cc33594870cd778b8eb65cda23f170b40d50acf9f97b31b784b4014560146a3769ffff748b29e05f39f89351afaef01daaafe7f98197eb47664523af79aa03a9cc7ac2bac603df9a258fd34b8329d4711d40cc6fd39ea90b6c0a6bc18b822997bbf1b00e9e87497ec154bd7b13300ae14a1aec21014f407701bbb7bc6f9520f08d05a30b1a75f057ce1c7af26fff07b55c9ae255c4f9cd9a5d92bd234283d158a272f68dc8387cdf7c81218045f241bb83d8fbddd2302a8d7e344af462086dade8c8e6b4584cf5b3b693ce317f23ac1d0a24b237eb07b00fa8fd4a5bd4680e89f5e011182b4200971ca09dff2e49b72fdda8134c0ce80d3c50fa274c7ac74c3ca8e2033bcbc836604471d9f11b0da84472d69474f03f62deaf8537686382c39a5b7a03cb64a948f325733fac7ac62511a1546eeb9b40fc34c0704f8e79ef639871072167fb3a11741ac8b57cf1101b66c20ebfc4223492005389ee9f782841315171754e5d8cc0d82823f2a8af73b415734c2505540858a17600d045d9becef38c6b015667fd6f98096094e2b55c820627fa56abf03cbdb374e86d8b4a4c11d66dfc9d1f65b3a127f489c56f1fe6b493b077d70ebde29b47a406f33d589547dc11c678994c33d9d96d5ef706bebb836657a00a16c9b0d65fc176d5bdd0bbea6030039d53fdaaef3881d805ba72a23e8bbd24401133ee085049e6c0b7c74d2531f171e4b86190b4ce31307eb474d5976fd0ec2d0dbb6d522c5d2b2ba7012ccf2b33248809b1669cae4d16c7a64dd354141d386e7bf63465cf13086fd13639146688c3972f41b8f1e071bf949cf3a94e909c452f741fd98a280cc9df4bdeaff30e43efcefded41db01de9bf30d934e746d76acbaa91bff2f08b20e8a24639e1eee0338664d224bbdb8feb10398c3d8bd90ef9a664cfdcf8e005ba51862268aa6947c58dc45530b201c4ae650c765bf5655661292d05d96e635de51e8b8b7ceabbe7c20c5e6acd44238568cfc127625461ec7c22ab034d847432cbfafd973460a373d7d588b0dd8c2dd960aaadea186d999aef4a87bfd58dc03c00836a9b7b3bd52597b6cfebde4dd523066b8a3ebc7ebc38f6742990dd30aa0d963577a5c160efe3ff8f30158dc2d4c5a2a83c6a701f45e5579510891fff52f059b27a3281cd9a3022b8e9784f2d1b75487deb48db743c4eacafa4f6d59b7b5a211470f559272545fcbeeab53358ddf209b5f8a846493373985a5b1a265f65465deccdd1702d0d3348243f6dcd57680979c442ae494e90ccf0855b9445768e2a6dfcda0e70be6896715e6445d3bfa242c1221e0672e734eb717c8e0f7978d62ee59145a87ff5a36d2d1552e01e89a9e67ed30df6984607b4b46c457ad13eccdbbe88e0fc9c12722737abc9916ee07b088e5dc7cbf7758f87e6bfe83ede7b9cb3dc256fff5c9 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7ec737eb05ffb89d5da8b3c58508928dd74462e8968b1f65bb3b9780649210d8f02e2950ad1e863bd78af41f3ae9899cf0fe992608cf5cdeb4eb0ac1c13ccaab4ca89a869424cceaf777cfc7e9da081f73f5aa5df41d493fbbe7ce5b6477c773d8cc81d995509ff3a40cf8de734a9e8968b7fbe79a9a0dab85f7b442077a890688dccadbd5e64ae59ece5d39b554e6b82b86d2a149a687ce9fcfffeb8e4be792e7529f33d7505c77ed84a63a78f58e93fbf10ee9bc05c91a7bf16ebcc051c9d143b9748b365ec94eb6098c4eece8aa833ebc25bd3e733adec55aa5b0f3f31efb7c7f0ab21e2544073cf2b6c4d75049b63fcad5c68a936989baa2e55ad1846fd1e335569bd1d4acc869f7e03587d8becf5db545447f4e727224545ca8c16bca5458fbf4d746a12e27def29ecc8dd840e279e0cd9484b4f4dd0c7446959a521618b9bc57fc810ead0d1c8428c43c0fc3f30fa9b176a4f84375a0e1563fdaeab6cad367c9949c4723802d6931f1dfe2b14dd4675652b958518e3ec8d5bd6dfd9982080f319e668dffb5c8873fe70b1cdeaba56ee7b77ef5d7600bacdbbbea5b9aed5a9443bb81a68c22c7904a1755d4d8da47bce48fde3c3a8ec6c05ef2a798dfdd597429b3fd6046981146743ae85cc9cdccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398b9f36e0fbed9b951f6d43a67fad6f7fb803acc33e965fe725dc34003a2e3feebfc0badfc537eb2b6912245fffc6fb285b6cb0935adfa0385dead74f7a63adb76bcf4b8daa84aec32f87be3a786537acaa42e78b136c8c08e7ac1dbee25b44654266f4b3be4f33358b9b75a2e9e6d78e89d3cec68b88f7350ed52449598d847b2a02c3056a64e72c5a3b34685e90bfd0037736e1af1df39a3574ed777a36fcf9d8c243a4a512e6b6199cd63c7bdb18b95fbe4615e9799767e76fa4a88c93459bd3d30e09889eeee48890cc22146f472586e3d0f6b0ededba5b8f3f07acc1c693e9b03e618c9d359b7aaec5447365f835b3590185ed9337b6171eac38eef9bde08da5eae3a908de4b3f531fc25fca5fbe9859673d62d67e28c751324e245376baf368b086f7fb1b844fc033361994ffb3b39823afa2eee7598de66023f986604fd3697a6f523fdcfbfe40b97e480f5d523c3c5227537a5089fb684fcbfca55ba9c307b4feabe54d241e34152bfc2aab6ad568e7b115330c1be5891fa35bf344be7d93ad44bb27a7fe01a8f902437f42f6bd6f96fd4e738aec7a333a26dd1263dd4b21b5e6fa95a41a4456f74c9522657a9b4df8c5ae62f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4d0ae83b96869fba6c72987f4c3f8a0e56a08c96a00d78854d6762ea2394c3bed2172e43ce5de92749cfbd5d3173a7e1f1ea8c37db5b635bcfe9b6396e39d2d56bb135eb8976eeb0a28ef58d39a7ae84aabd46baf4ecfa70fe8fb71dfce33fb7a45a532dd54d3da8c580d6cea52d9098a3d478efd7622a7cdeecfe73cf4eaf5787d5bfb461889d23ab93a4ba327c47eeff58cff7f65738886abd046895834aa06a6cb57973f21ee353fcc1453bd15b3f4c4075e5e939daff4356fb393b5704d76077b21538e9b6a69d617fbd4baa364578557fd7f7a75e9089ae83e28e8dce9c5bf808ba36e539b40440f1ec994b46a4a128ce3e8d63f608cbba13fab24ed2cdb3c7266d3d157edc76f542ea4b641d5eed82a7d33cbae14d086d00ad711224c585f4ce74d4d1cdd3bd8a893a04aba0ffce625bb997ea24766b5a30599834376f7718d83ca5499b771f919705ace8553d475c68530464e2745a83bec2c8de52e3da60f1bf6bda43f4f85ea40d6dd4be6eddf886a8b6f488af3b36a3f5dba47ff50e34c333b4567c9ef960c8301fdae946d58a53ed847e164c790f54ef75c0f3ccca27ca8afc8eebc2b5e00e535634ede15bee35b5464c33c7c4c614350b66ffe8b641e92583d49546cc5bfb45fcce125acaddf67c786acefbd9e9cd7dcbb9afca1b8353372c3894fcaadcef693f09cbb0783c4efe635818cc06c5732b846b8024b94573d7369fe2dd0649abeb4f84aedf5809e0bbc855f86780cc85a48fa75aa6bb5b2515da15588c1ed63d107b7e4b6a9e400f5be483a52967c249e741353f816bc8ad6baf9e75da4a8045b8693056995a847dac15ff49b59a1b9aeb2188c46214fb86a8ff8138c5e8b63d6c29447bb60a56210ba594a3027f4d7667edd310b678523e87830a469e5a758024fcce5a7741a7368c790cbd86204f6ae2a71c2a6a0ce80d14f26e53c175318cca9fdc5fc0a110f6834e1a32986cbaa0f0283376b25276b304dd4c9debf7ccd4c98bb1e605abd84bf824a61f5218671b17918432b32359feda8cbf822c62e86061ebcaec22af3ddc83b45252166a55fa2b3942e346a688cff13272a092c22c5c156ae0b63214bc7919aa90847f9de579c6eacab9690c6281685f4184736092d7b365c2d0aa977b0999635cfb0c44a8193377205a49033fff2133853a4559ba895f0b5b36f2cced166f7dc4aa6d064e6223a114580b58128dcb30b5c8da30b97a497300061c9cb9c7eca6924b6c6b19469645a443851e59248a3759164c02a8a86a9d1e86c51907074c7003e1e0764ea650c9aa9f1ed14831363e56104d4126bf09207d5544c5696a69daf7a748ec7be4b2cdb3c628d5a302f1a82eeefaacf731c5ce3bb6a26a80e7414044087487648e62f9c5d9e29cebc8b5bf111995616b8677778a8cc6b55618a26c6ba74753a2d943fcfb838b6a14935a38cb96906fe2008d2ac8622b50ca4a79035a403946180fe69844020bcc093bdba58d1496ae7dc5741ff16b5b5185a86277ab65c92551b48180972ba55580cb8cd274bc58a83041c7c0349191cf7c9be0a24f23e81e9892c2e0fa979fb4aeb3648ac64534e6c3823ed28cb24569e0931506396140b72f059818bd483d70c8132bc38ad19b995cd9859bbb06342ccab0180e8471c77ebcce2cd9a09d32c7de1443f6c588ac2308612b3b3cc51c670c935a91b973063a31703047a630ec03375831a3357940d2285ec8363bee2b8626656669b36875875f32592e9fd5c1e48879e58746dae41a9e8043ad3975de6c0f59f6588376682c770bd2cc3e427ba50070a3d1572fc7a61f08773d60bc1dbcfb087d726372d23bf89647ce6792f1a12fb87298fff567e6ba833423c43bb157b507009d46c8bed6704e5b23e5c431206bc3d6ca5665db9051d882be08b714950054a6c0a341bf953c4936830a74db1e7236c5cc3b49ffb6230c02978b63020ff75e26f375621b26730aab7ed79dd7facf6bc7a038b779bfbc43866123ea910c4620363a8b885c7017741a22c35506fad12fa5e2360c55aa99528db32709b41c79e7a1730be27ade379ec986239cbc98c3e2bb818b3c33c29ce1b6cff56a58f97c0968e83156a5617a579e13fa208c840591ab630d942ff415479c8343230a9f150b39b1e8259a839eaa370b9a083f50a8992c2b90321549a15b482b752c65c11dbd5b302e630293d2463a47cc54a02c6b7784ebe8c6b487b185898887f1590ed21c1c757d248cb712b7449f712082b7591b34604af799f9b5ce2aab6ce9464528418b01b1abd3e4598ca45022809a708460eb72bcb708c5bb8c272ea187e0158778760b7ca864b0fa51347b4d7130a2ecf4140a8988b94498db660229f78852fc149dd9c5692c41123a6f1310743c892f761345d2f685e5f3a924e620d7122cfadb4f8fbcc95f5a65b31728624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a340100ad8384a2955462bd703237d331eb7742349876eab4c2c933133d3c833d185f129c5804aa1453b0947da3cf3bd44051f70de00b3cb28396c180b501e70157c22486f8a82282652bb21fc23c3bc123b6c3d6acdf079906b149ae2b52efdaaf3d9b0ecaa92ca9d8694bf07d4229835f3a0a21253877e1a39b4699039041abc8c0b3f6aec29bb22e847131670c0e7b5abeb2455a246d03b6066114552476a18c23b013a812d65a15d021c117f926607c076892499056c1bf058c52ca1703a0812678b4485b82814bb6960a86c3454b99b731cfe15ca5ec005f866b28235036e632b89cbd9aa4a6e70ac944ab82661134ec2ba3b871272864a85ef61f86f51337651eef063fc6f07a39d3ba7aaba5d7357506c550bed913788947a1863a25209cd01200272517adca5f1087c984e11f13404d046c5537711c56577adefaced330230a42cea4e13d0e899394f120ec34c2a6054e5d2ac90696115515345aa2125dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28cc20155074cd7cbd43ec2380dc6a71b3a88c9a4bf168ab2bf426a899706fa597812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = 65c9109d7c2eeeaa5ec2b4dae6fafac6f7e17093449f00a5319966bb022c49765023c6097d90f47d6e58b96c0c17d319a88c2819de8dd91cdef8817e354ca37a3e10853dbdd3231a2516df2dfd1f55e256ccf81e624c5c19c2df81e6311d02271fbd27de2f579014a06d2dfe32fc26cc5a45bd7575ccb8898e780aeb20d5c01145f1480c95a079fc6767523ff69f6858b2d56bfdbd3695d8a2101bf65cbbb28e347b2b528f2f01d630a035ad2802d087a676930c9ed741de8b0157423880998e655e20b6f4325b3f9e7fe36d1cca269f49412400f0ed498b9a7e699a968e41326f7c813cca95ee5b2bd5f5242de87609fb3d2e62ceb776486e7826e45b5ca6feee3114bdcf705c1979b96ff382c1f92be175e60b37e7885d18635b06183807d5f3ae5d3c9cb3df01aad1487bc93bbbc10d078fcddbe8a0ace94414d7af8a3cf0ee579b3782bfe8cf6b7f377f8170bf7fb8e7fdbd96a075b804140a65d034ee675fc3e156a12e261b50882875ad073e071295daa7743a9d581ab9096f679ed9f2cd7e36da05f435ddca26c0136676775a3f30ed0c800e51b7ae9dbbcd25d3fb9d6676a972a25fd7c4ca91859b175c98a933d84d1797427ea8c0aa1beef033a2a35a145d9dd59f7e29953c5bbfe6865bfebb558ffc747b52ff7b5f2e83d65dff3423328449d27fda0fce912a0b6ba78e2b66c9db821bd322b5081cddbeaac16f7ef2e41fd6b86e4490a2bc04fb697e09b3c543495fefcd999e6442a56ab49ee9fdde910a768d4f0bc51d797dd730f98de9edce163f685c0363e73ec6d235acbbd9e168b6152b0eb50b7276306c7efd42845b11cfa11de76163efc774e5c6ab2a44a6d117c7b80b2b14ecf1b1af7f8a09f3d23407cadf256061df3fa9d940ee92f3a80921f76f0f14d3e3e4b0a943bf6d6834d9d75d0c4ac931e59a98d4e53456bfe77a8f12637bab2e4db63fa8b47f9f26cf65c5421caf208e74dcdb98f1242320d900133a91769a5c9824a83a0e60cf78dbb8fec10dd1366c1a7bf75412da8072651e36ca8d0aaf464c3d4473cd396cd82207b20e2f5cd07b3cd1ae1a62d9ba86bc1cb81459975ee94ce5c1fae71d39fd2540d631cf6cdae1c60a3ce10b8732f9366a553333323a9a01c56a5a91267fdb6b3abd68f73377c2d10cafe7ab4af06b66c77dc30428105413a62ddd505b043b03e491520bd526e00ac068a64f115716f36f008d475b441a849617cf44c8e758726987ca48be6dc5f41f95933ac9f6a4b1a8e26092340108643003f0fc243ca8900e8cfc1b8a1910e2c75384d3653d3a47c619495837399e7668884138497c598b8fabbc5d406a00a8b89be59c44bcd8ad090be3c15efb1ae2f7417182fee2e68d0ccb865d81b23a4d5f2f54f4e91d89bb42a451f95d3f85dcada8d651147ea53b086175b52748f96ef432cb3b34e14a84139915cea2d3af6a33d2c9ef3e3004c516a2aa16be6dc5f1d07be3d5ceb3ff37c24d1d2c0edd91b9b29cb04b40311582d473d71e52bc707e9b0d497a3d6d6d96efae0f9b556358eb0b465a86f9cc10a37e5ef129ae64776ad2374649b388524825761a56d32e360124af0e2c63de5fc6719fcb13f9a664400b137c842d5b5c7776dc7adc6661567e8d62183a16f45840493d8a4b5eae39c3ecd40d60d2b0d015ae2b59dd6ac298ef11fa1c4477d2cfae2765182ed4a8625f3daab15f51712c3b9c2a33e8f09957807f419cc531e018dab3e7aba6348f1563eaf7c6bee397a813849a58f4eda0648727ef3d3594a171181a9153cf8eb02676cbe6f70b63eb998454edddb2ec074849720ede5a8f13d4c9f8e2f1ee6d95e87603e00731fce896f6bae80d5b01386427fc5602bf81d64b4ae3194a040af00b0038be7e8719b24b71aa884304cb1fcdd691ec6e5e4d07efcf683847e4b46946a7aa200d7c9fe5ecebc1f95182ad4c5ce44a5d0d92b8e511e5e9d2c0a74e2c5e9beff56e856a34905f20d0d97364b33596f7efacfeaf0c8f34fe76d9463fe972027a2157a0e6c2f4278f48227558ba3869acb0b06b724f08429e60cd52e2c7bd6db139f1b3200db659eda1b9d21329d8171e07049b7efbda98afbc49b53f51042b987b1afb8e99b8ee89500fd52e7d9db1dcb3ab5efbb5df6e084daa70e202fae574c0267a8b72b1ea174f0132ccf7abaf31cda71b4ebe9171a822bc2d3b44c739a24d51e85446a4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d62c6ce5e7594be682a81677441d6a4458fe3a79ce2576357745e3f1bdbf78ae61c8274a705b93d2eaa899d8c0126ac8adb7b3bbb589181e380eaea9de0541e426ddccabc13a165b5c64e78da95b919457c684b9ce08ef97637c740ffb3cf9f95de79bedd83c3ff871087b94134de864ef91b047794588d7abe4687368c84b44d8e26aa30bf58bbe4bbdee3fadb046d75997e4475ff2524b3c2cd4c15f98a2e6695463257bb8fa9a8423ea64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51b07eed4ccd3e20dbe2a226d72d7834d996ae9aeecc662fa42b48c5438fcd0ae8cfdd1b874fbb4ec17434ad584af5b4561cce597aab63390b60fe8cd52e57846e1a8c4f6c6758798b715d350755494648ffa7ffd04b6e6a40dbc2b0c596c2dbf873c38e6ff82ff159ba93563d2377edfc433949d3705f398b385f680169657623937a8c357864c39e8fc16da5c1ef4d7fc7fab358cdb114965e8a8e5409964ccdc54cd8d5b17039aa9283a59e746a46af800e58d6064683c39fb426ce8f73baff720a6522ad50c5196bdabc9b094895ba5f775acea7210958e11a3412bd5e67097fce3ce1ee0f4a86bff684c5eedd75fded89c23e1440ca66e6bb754361c549787ff2b9bf97f8f4bb808e8d3b29b16c369cc8ba9d91f6d12c0dd7999c7057bafa44d3d2383e407abfa55c63990c3ab657cb80d52df2661d97ed78dd210e95bf8fa9badd8b25fd39bffc42c66459b0c8889dda6714b63762494a5f7ed6f45ff3990772b1dce2dc76df5bf6feb1ae5c16d4a0303773d768c7dda7b74a8eef7d1f720c25dd30ec6b6266f4e3f94861483be13f71d9bd5780ab62e0294a8dbe93238530b49455718c872428bea1d84955f54a3bc6e9dadc6106ea3ef37d94a08563462437741f648ac46559d7a7deadf497aa9f22879d132ad8ba2f3a05e5b76b0d807225b30458df6105cbec9ae1cfae8e8a1da9bba691047c95676c9e2dc7ab76537691dbbee397738d6e3e20cdda7afd6699dedec26c97dd0db82a54af573ad2801aac2098331104fcca18699a2684e4b5aed83c7ad8aae706fe605a87cabefac499a56058d8b02bd5977445f4a90c3686d9405e33c3d70880b6449d41a76f84ef3759664f204ded3935998d79da7167afa11a59cf8b87634f83a738c0d32eb1b55453504ab64fb8982445ea49ebbcc39e465af92f50d7b53874c1190a766dac5e717d6f88097be56dd942534df5e5887c48b235dee99203fcf4ff867dcd55d7d6c3a5df5d2a24ebe7e7d6bd2fd3814667552888e3cbe3222ae0dc3a4157e8e1a7daf3088ba5aa1a3fd61cdc6bff9b3c5faa6db3e9d8e359d94fc6dc65c29eccc0534ee5d16be9a7c9dd119dc5949cc66b0d4f0a15e3132640a284a87384c7ed06782607584bf5cdd9fd99adcdf29cc9588c0f4b0f3b5ba80b962218b3bce4c0f64fbac9e8c23546fe33ea30d799d94ff8ffbf64569907755ed7bfd00c3f6f446dec0da27b37bb92e454aaaacb69dc85463fc718c85508ac8742d7e80eb8d5a789991129e5be4e4275f9fd76ce953d1d968d9dfe4aa6429edada5ef49fb4046ed2c939155ddb0d98fb68cf75c493d37e859c8d0e518ee49046e3594b4ee320f8d0ae2cb182553684d470e06f9b6c27a9cc6ce7a085544336f983f8d0b9375e0fcaed393953f1eaf32d4ebb317dde3f0596fd3c786223a1666ffbd60c8a2e4d4be0cda14505dc440bedf3e8ad9b29e4f32644266f7635bb97358d7b419fe5fb0c6a617c695025bf44fff5b1c54d271d52f33a825d65730ec7519d9d87ff66f6a244a1e28669d84bc8217ad9ce2f4dec86f3436df3d05a51f98b8c220cb7b2dc46b6aac461744a30a671ec8f8835dc32efe47f002f370e83e23135ce2f0f789b2eb03e1c55167c3fcdaf343ebecfa9eeee838948392d84a799de619c652ac49c64a3879658c419c8c8143d9aef9bb607eef6a75fbc3323f9501c61fa7e96f7ebea399adb6d947cf903a9bc7ee19c2c45f8b440f29344fb2fc2dabececd578608a4d2c6b649d8563236fab8d208be6967b14074cefbc7aa45ddf766ecca8f0673787b33c2ecfc760ebe9487de696d8ab06aa5410aceba544a6f8792c4ebd1c08cebbf197e4d17388aebd5fdaedbb3cbdb948cf1c59ff56db66dca0819602701895a6e3a2071623403b78438977211d33331312c8715e34929757ad52815c65806ea8b222ac2a5b4b718411732d6a0137c5c7ca8e285c02634130950e1143160f6a34cd64dee440b1b3b8d64458c78492095517892c5a169eb7ae87733aef3b16a5133788ace5fe57cb41ac0e5b13c403441d374aab997500533744714a84dd56ce547a10c782d6071bdcbdcbfba391dd44926022b9098e61d079b2198c4c4201295964aca9d703013341313a50a9b124427209bbb248aaf96ab9efc9028cb9a298838465984647aa1e2f4087c74ae23f2606194447e403ee45198e29c12aef2ccb0c4b07c98a02987068b4a4f14a778be34c362204ed4b31788e3b7d2e54d74e07a215c7eefbc3067f9c67e625bb43b9ce25179f58a113bd2cbbaf85c34ba8fe26a331e0b0610893e0947495cbb1e287047da04527cca1ac68a2ce1742d8c855576941b4d627f0d326a7e543497f09fe1fa536e997828c19977b0b82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e79501817d8894004c5586c78c1a54808c37d40fbe3171f6e950e287850ed19d975446fdcb1b0cac2d4a611d832acf1c20a28c164201638110e0997fb36b2d24c6b349c390d4a13e06aa95c40e878830827a440985870a4b6288f82dcbd9ae23175462fa054d2a9c6f6210a1a7cabb9a6ee8e37ff144043ec0123c2c0c4125ab48775529a86462c34c00b128a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a716a27b1576561f681e346ccb74a07b71938676c25eee2a83ead225afc408cbf085a4a342ddc2b058c6a138a94a819c737b6baf4a4493c38a52c1452a302535dee813f1dac31e09402cf720a3b16751451df057bf1b7519c8a62e1be69e339910e6024c59c13fbac116d6a6578ae40765f78a7147b5dcf93f4eea1436b559ae373888042c63c0a52cdb2777e8699afc229d575ccdf802c59c15bf3b6f028494594b53d2f3cce339229b3a03eaeb164f325686590f79dac06f482254838e5af209cdc31f9a5bb893961c5576c445a02034088e89140ec2b28cafcac58ad352d0ab34d0659332d9266db85bf57bccb67814bc74c107c41dc2f30e6330b17b4b710cd7ab0b1c01d9f82d3fa0216e51198d723f1e52314e850220052309a383e63b774370713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a85603fdd8b392a616f55c3783c28b5308a4b0a5c1c757b677c475c60516a65f656b4868cdec6bfa723c66e52931b738e18cc518cab93a7c942e7db127d239c11580c21c71031f20079e9506ec57119688e0df98e4045b77e87728496c2060c93f4819ad2a79ed10501498891828080f4841a8af6602e100981124f6a16c26f3380e4d3635fd3cb77cb6c8eac22ba212a804917b922218066241e848e3ba589569a5a6420019370ca04bc196e88cf2f428595f1912fe9670b9ac97c487ee2e7a77a621ab3b9b2e4c23c5d4c8657277951b55aae576524769ca5b83b37d84868367d7e9323d9ca4cb7071c352ac3da2b3ac58525a152a00ec268f85ab6559027ead8abaaa370751c64f51473b02126d7b3be27812bb008c45797c1b4b05b5cbb8c2dca419f85be36bc390ef5c4d3670c8ef7c00b59a44c65ad11d68c5af4b2b675cf40c002a1b7844fc9a6c32886c74a1892a2514cb930e4387904d1970168181f7b43c020a8071969b868a5b44729b8d04b3ea9716269cc005808bad63d0b063f21c23ad1377e80bb07d608786d849d79eaae94813435d602214075bde7bad770b28b380bd0d7139a7780588c01c8eb6622f1a874968c874b120ff81c988c5684f3c9ba677add2c23400283d6d325d8289473f557eb1c2977f04e95fba614ba7613720c704905f7a73a2834996a4232a8ac278a444fe5f7a9148b57124580b7b03df89ba646aa4233611da9b5327d61b6b1aa351d25988e0c25e6e2563168c005666ea90852183231ef5ba371935c4c0abe6b61c0a1da756ef390c120621af2ae243089f84551185616779c90ace0593b815dc5d8b2d5726a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa4a001c002374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33921c307c05f69f90cab5602a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f1326077fbe004761fc37fe7597638e5dae8b44bd44c8d6efa2893a0a84b104ace6ac48e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 13372ccab4d0d1364dd7d76cf4213269ff8332b39b15dcc8be813a16f36135139d49589788872472ca4629003ddc721a02d27eef1f842b2da4da148b9b83bdaa5f0f8ee1eed71391454394ec62f2fa18805cc78524db523debc3d9206871bed38b6d6e69dd74dacf6ba07889ad3d2d8cb1ee731b16120468ed3be436b8362e56ce66d1f1b9ce8b42323dc302ef37f732b9067d80b6e6b4be3acd2f4751234a5410d18c5972d32abf25c4922515005a89e03d310b8a76139fceeddaef9b37998412fa7ef24817861e6f210c1ffb2780f23de28f2de52205aeb9a64138dda4aa0edc91dd890c41e1e814939124efda4cd4a344cf1f3f046507822a726ac44acde42feedcc89e159571b2cd4450c370650fbae1b0a55aaeabb70e31300605b9ad5575ad05a2df9bf440f123dd1b4b2dad93da1dd0c7a2b7f03baa74b14c1b94e63fcc8cc3f173ff50f72570c5b3a65ab4520e3fe80b9479195f1c733a3e9059fb4186013ba9f64ba006ccdd270747f5e355b4a455a7197146bcb42604f7917503b86e818197fa78ce268e288fe3ab3a7d8678a01cc2dce86e77ce7bf49514867ac9cca6d722d374a9f0afbb51fea1c4f120c339160faa1f40103b3f84f69d8945d72d91ae9054c18f70d33676ef0f3c759973e25cd30c26fd3b823690b127f95a0b7d3999ec16ac645c181b264178bc7f11f64127800335890c31d7412a314ecd3d361d9ceb85d77494c20e465ef7c36a227bfb9104436fe95cb0050ea548ea22252394eee01c8ce8da5eaf4ccafc647b7ce956f1eb7b28c28cb05663aa5171412288679ba2d44d7de75a625667bfa865a3dd0f20cb92837dc383df5bb060fdb2f9457f1f8af77497d408da49d4510357f43ab7985ae03ff73bac3e9d2b2c2f3ff9190d5e928ec75a2fc0e2019c07ec2b4ca40da2fc16f7ccf3ff66cb06327ed9d2c73751e7ac34c062cfff2f6a98eae4e8e4f989dbaf648a7a23e5a9f336a5ef87dfc4b044384467eb7f63368daec721a1cc13ffca44b4a4bdc5c429b7e0466bd9d19ac0104879a629d124760427202c9cb325be4a7624593136254ffd5847e8f4cabdb2161178aedd4ff9a9e9622de100cab8523f75f885479965a7c4e8578c2bbc6d5db343d1e9e4b7b7b9006e8e63f8e636012dc66fbeadfdf1b94a4c4a58e61527e06fde7994a3a9edd9792af3352ed453307d8a5cdbd47cb2d7de1e78e13876ac46e7110418d3cdafaddca4e63b297dbdf79dec136fdd9cd66b2ffe04fdd541ba022493faf56b8c238e630e07274b0d2e7dba457ac1d2043f8181ecc8655c785105bd8635ef4b070774c21ed8fd1daa129b7bbb34c25b8aff031aa08635b69f021c5188e539b881eff8191b985c83d7d4465f99f9b6dbafe322c9b0359cc7d769ce3fe7e0df2c8de02e4676b5811908d2d29a270f8a7b33f70b270f5507c4398e7446dfea9331675ef9c32c73d5305492b8b3b5fa8b1e77d7ad3e2f566f0b17a7f2522ec38b28fb71b3fc9d2f0b6bb6adf50a0f779da14d43c387323b623160589970ee0fa10dc662d1aaf71632eed47064d523f04eb115d90f74a048529cf2e02143a788dc95e0d802cdc35a00952ce377954ab3b61b7fc2e03247576f2707569f50457df76e3b73cb20fa6d5b2fb716769154d4da9038d8f0dda0d93534dc42ef05de2c7815dcc97e0bf8e15acbb31c7fbc1063889e03a312d03c8d188c6423adbb20b6d49ed25cb0aff5452411914c61261f533ae1d8fe887b08db689f7e46e76176226fa75e41d9a4b700bae0ad7e7d1b7e2ea90c339ab143db4408bf00c79e506ef2adef8ff6d95a1800f725770be6d3438f46593e78920c4730859969c789d9068d830ec761a7c4d43b3e282c552993b232ec0f4251d5be3d9a743c4586439e7db125827a916a15fbf94eecc4af09eb109a7e27a45068458b02b475297de3f99521f3bc0a4c0eb5b5fb92fcc94bc520837168642017688a5aca19342dc342d624a02a30af36300fbe163f015e3e0c46d2af22cedcf9d98f350b40355ec0ef816652975b314800f3b0ecd2fead11d315700808f5aea0963088b008d048381336d7492999a5d29a36bd4d9d0e57c7bf870cdb9b75da48911a900c018cc5fb3f262c09cbd6032ee778c704500f2c6f88b20a6baa927eeb373cf490e3eda483dd0101dd2260d77e32d9e6088dc906b5a61fc4e2c22c8c37a82effb5b4c6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 212393fa68c40e1e53ec29801f4472dc3db8e75e6647cccc6a26dbdad4f99e5e5717d46bb4248674eee558d8af5a6373720a9c96a4c51c0efbc506cbe51b560ab742ec684ddf86cb092febde5efe2476842d15ee328fc415c49b7184c9332f42f70b63aa6d576296a8af5451f5d474019c47e29ffe2b25d3d30cb8eb2db3cec334a31e4fc248ed910a98e633716ef9ca2f7939c7033bab756371d6c2e916d61d08f3113c57dd5992c98f6adecbc9ae48e931473558ac94fe9ae9c9c4bea3dc40defbcbde234a2126f3f8e8dbdefc74f657a797098ebcefb6b57438c2253f8ade3bcbd5c0c52d4def79bb37859e36f9f0768ca7d075ea7ec9bb63336698acbfb6c9a384084df0cebf5dacd50087b691e4d345fed7bf0df51bd9946363fa05b795f93df1349fcb16d668605ca86efe34c03c4a7df581f8ca7daf83ff5aa75146457163c3abfa9c655f966a607a69ab1f34fd1ca2aa8fe3f38da10e84c4abdf6c0fafcba6773d63b39ef745df6d284830ec3275e5bb9b3e8b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bddffd617aaf8b14c10e0d37aba7db8cebbec0cb866bf5d57964b7cae6c9b3084a6976d2a25961dc53558c065d6d9bf5248aba263beb6363f2bc9fe65a8cbedf6dbbf6c7f459d47b64a964b3d3fca563ba5aeaba8ee9e2d82bfe733b4b4587a99af5d37eefedfc9aca5d869596e36548cd336ae774b8ba63772fa598cd5dcd43b092d938429886c708448b24a45b8dece9fb9db54c67bb63ebcfc8febc15c1284d9b02a3350e6e68f1296784b86f741db9160681f0133a663568445deb9c14e4d7f687aaf4ea36857ccd4bf6bf9ce1de03d869f3d630169365aa3c3b53cc89d9cf48cfcc6c166f197c9e5c6bf409bd3c42bd613703cc497fbe78dcc4b38d89d81e8ca1186baebce355d5b9d4e45515897ae233a2691d356a373dcbf6cd600fcdde8c468cfdd6dbc67e60a69909eee71d4a5ec1643b87059cad8dc259788eaf195f4fbccfc5ddf84bf8f2f95cf9780ae2948ef91657b927f8b3331f4d62de7e21a36486dfc3f289386503d6589a8d049bd6fba7bb9f087f96d5785678a7f3de6c892cbb2273677fddcb70f5729bfda0404bdbf16d8acfcece33ff924535c16e94f3be0c8854e439ea395dd89f399dc98aeeb7493b64965858be35977dc053b3c0b3788fc4f44cd3b49f4d93509db454c983da38b2b5c88521347788f832e9c64a6dede2521f34275c9f6c35e442a87b496743334ae61d9cd4e3d78be3097942aacceeed9b9cb673e10af71bf7edbeb5c4e1049b2b3ad0311acad457df8afc85172476b949aefcdde10a36e46139eb5ff7a74697c88ae4dc8287dfccf68b9ad5382125879e637b7cebc1aae95b042e9cf2488b2e4bfe5158dc8ce8d22d2d92480f36ff6d42dcebca24cb9ee9379386e8de55cf32dec93b99b694e99ab5e41cc8cfb8928d6cd8edc7a707044b49b8a131986a3f37bcdbcab5255b64b59d5a93b7e9d01a32384a87543b6ba2bffdb75c9babdf57bc8b9d8b78641b394c7bed64087454d0be7b307bc35a97cccb94f602a9d747e6df31eff0ee3e71ffd7a2b87d49dd3ede2377607c8e7f25dde1dd736d7918874aea4bcd0de8fe3b303eb7b30f4f6099cbfc91adb269e88390b5879706b164eeb27194ad69bf6204c5e2ea145c44cdf9002e898ec589c679ec7fc5857b387bb29e6b407a641fce4d01d8fdc7f4a179a3558d8abc8af937a4bf682d638e398e329e484b28cbeea4a9b6a30d97f3cce45345b032ab8051d44a8615c97815f1429bc1008af8e3659433faf95789a0051dffea8dc2d1043761eb7416338b68f688221ac0056efc9dfc788934e311f78145699361dcec46d55a0b6ce303789a3c0c4c57faefc14b8fef9f798a188d165982de273cd9a7dbe13f79dbdba64838ac127b78ef5be6c41d5fef28dd0b936558bad05b0cdd2c6afa00daf07a49675db34b0029ba77f76eef65646fde3bfea533e5536684bf402a48db1426b45e1b83e498758393907cd4999909812f8f382885fd4b95692599fa0d038d2c695cce2fbbff0d62b5fbdb9c47dc54f3e229067df4ddb513667be7e54f520839af94c6d72ad66319d04de4cf7dc9880233fb78ceddd0bf66ded346770b8df09768a5099bbfff38f72b853746054cc692001b531bc5a46a5cb02c910bf24519198c1a2f2023a4367e9d2ab4cf5887c756299efba70d9008fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9c9f228475e0a454639892d992503abfea8b82908a087761bec6ab7d60c1892f41bf1f99c6ed256b64c78c93a316b31272d6f236371ab2ab77123eb732ab303a5e89485f702f528a38e1920f12ea72bba8868c855e305425d84a5edd11918b4cbbe5c0001a5637bf8c022128b81de80509ea72a0f66ad870257e529a31cbaa39183f006a0fafac0fcd7781f1033257d766f78b4c4a9b10c5b8208a40368b393a39e7762467463b29a7baf4307285b898aa0bae485a63e739ba5a7a080215f4221217fb43177635aae61f218850a1d924052a9c0626a7f11646076176215152b5508db2c52da7477b7e2b0659b999148a214a12b9a3e770998b1a26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa94368429f763991911681c1ebce5ac515bd5663308361e2b068332763752047ee14ab31b914e2d28457395cf61c69ecf3834d305af9ca18decc6ed39ccf69a79c379044ced7440a248963c269b6b58a049a8077e0a0981639d581a8c38a16f4296af798cd2556889e9697ba8156714166f10a57c970c6131386d9154894d495deeca298e33de4b09a94dacc2cca1d816708fa1b1b5e0a7e8046143fda893f0b3eb2b60ca7a02878729768fc82d8b06a05f647916a9cb84b69ce532edb5a7ec4eccda5a5a4fe8c52ebec6584e6c0465529f57699706cb9a497c2e96757af06783a4aa6a00087079803a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401abc1b8d0c8eddf679a8ac0fde11917376a7063339f2c2507ac02ccc512c7a75b00de0701124ce3057a8c28687b2576c640bd0ea5422a534aa4bac9fde1735f35112c98528298218a1f051d54231f7ac5c4353be2205c3b6518df442775b9771ad19ba9252698bb6cda102cac759a5a0734cf07791a38c7ca940a86b584457559e7b933ac5750c4c43785ef61f5c121f8f4175570c7ccf864c4bb7c49c606ebdf7950e49433a841643f78273e117780a5e1e4cbf3e0016b45994c1821686d41133bb353dba0fb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb0e0baa50199d80050dae3266f228134a4c67ffc5241a757e0dc2485a64d4907934eea5fe503653311c4ef24bf09fc3f0388c88ed9cf965ca8a109297be60893559a0f3696e77b38d677a7e9f4c788d67046c28281c8a7f71ab250e77ad87b4f64237077d1a63b753a21b088c5149af5d40b928401e4c407e71b6896b840d8f717e627532f3cc604e64b84204730c8330ea35228580b4b886518e9670d6100826560f9623045291ebad1ae5fe6840c30cbe69ac54e62bad8010c98c513956534beb356cc6555c1c4225b7862c4651e55c4452448063b4c04e105b63daaa90f9a6b0769b161a32f49fb64010a91e0b4410d86b7bd4c91f421ceb091a88ed9ac5e01c81527886897a8e6697c7571ad95b818f942a5692459f9979ac7a8078883aa8a445a5af84b1b86c4c79a224a5c8f3a889eee0c768af29fd75a506ae75f9d578c26c8645bc8a8bf0441b6da2bb27b6baab43031047c6b826fc98766a1661be0626cd2c37864eb23f4240e5fb601dd645ffdd9898396273d3000d5486cdb67866751378350068a8439944ca11f9a5e7959ad43bc1f5cc8c741a220bee733aed2a41edc34fbcbc890a718f608794802bed150a0398b0a836a68cc0b58dd705353a41f28883cacb94c797b8cf8d23cad9bb9a18c53b372c50aaac124fcc07b310907988f38164f46d70305a381e4a1673145b0bfd8ab91a02c28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c45057dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c6a1c7e1589e98cc995a4a2b21288057fcca694c0c00e7ae05d861b90a520eb34002732a2812368931a18243ac62f34cd7027fd80436d0454aed978115034407e30dc19813c5100c3e13a26c3283d4a72e254ac3f7e637d9435281180dd6fb35f0433788d470b6216b310a63d5e11b373a073dc8098d3950819937e7f66ff954caae52b3bb86c80b5680851170140a1e59ba0b23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c49cbe8daa7dac02d7795e907b037e2ae56624fdc8d7c6320f9e1e69dd0f6286f8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = 65cd11c5fbfa837e85464c0dfcdac9724a25db17ea1f8631400187559d743cd8d29a811b0c159d777d234d3cf33a19b15bc8841e5434e28b752b865c3d1cd4f7ae70fe84d3f4dede9c515dbd7843cba1d29025a30070d3a1b841cd2cf1d76c4bdf6bc2d24d218959d180cfeba7a31c81e495baf9a1b313c2608b79452b2344e4c6f1960c530262085a5c9053456aed77daf70502a345c6bb3c147f8143f916f99754bb1ef31c4167bbf63c68b54ffe5fe459dc9679d080065e3b73a7b02f8bc1d1b996cb0069a36f9f04dc5aa3d00633c38b06404eea9a4af2f6144bb47c009a01df11accd962c20165a3ac6c27e5cf50691a58c45d68be6f5732df8e07e7bdbb2f58ecf171baf808dfbe151c00b576856e0ea7c292095c5000c9b77e21b7937953a38af0f53e7f4c65a70edd1396dab54df2967eeb7e02cc548597a6ffbd829dd72a2d18e7888cb0e3ec9049182301c1e6be6bb43f4130bb57b61138bc82720afafd061b3ad2c00896e7405e4063790a75d96e7b3c1fdc475388d488f4690e0c584a33efd2692f2f90c974b4a2498b847953e2f72c1aa2354d04c2fe61b561e29b7d37f164734bfbe96b0af480f4189b67c4889f1913497b55547a1b01a1b0adb944f75ca30145ddd8120bd7f09f7e36e479af5f50befce9bd15ade52d4b329854c62837cc0e64af3e908b9b47e61595f2f25ce78207d2331c183188d27b8e8f29661cd70216f491b886ff2afb018611176649c9488e6aee19fe6147a3c92e95fc1983ef5482d295e61ca2c8f4644447d0b918b443f3e6efa04e5651edc750a529cf33eea818242b45802773ab7e74840cfea962970ada0a2f906227f3733a72ead1295f78c0161cc91c448c9e150c565d022d194a7296911113ab1a550806edc6f1689be96da4cb11245f0c0fa93797a6d6dbe992e0e695209d010b3a728b0a647fa5990e78eff5aeb75870aecbd0e14cbad1b054c9fbaa5b86a00dc933789db11df313c39fa0e7b32e281173e5eb13be31e5c349709093c9125030e7e066ac38eb3d89e23833a08a66f7c0eb230d01ac83f792840db7de17adc7dcb828765f67e20ad5e4ead3d6f76302aa9a5b321d68971e07a1801f98544d6e1d5a68f8801872d099faac4c561e35d2b48036528a8a04c2033b4e2b018f1242bc6f8af436648730564629302cc5cbf1bd2214dc8b3e38a79aea4b67a52af232f23d0ee6f60b318736276986dbf567baef9c168c9331773cb1c32aa22dee8882d557f79da61171634a5a4e806939c3eb1d575712b3674f503e9199c6b1b630d20296fecfe4573ad43a266b8cabc22ebfb40717d781d4dee61591aafbe0a042c919a1804953d4b8c1a6cc5f8be7ed45bb1ee6f75671f102248d4dc63ad0e6098de0b4f3fc31bfb3164ab3701e51681993bf1a4bd78064b3fda30deb7d70c7ab35e64bd82f91da3b06688ca4a20d0b19849b72d2c342702a077e015ee10b277d5e1230b91c22d41085650549c9eec529f34caaae7de76bccc960bcb5b5c7e6156c6069e4b27a949ff8c9a1aaac2ee7625aa3f19568b14e883d3273311927ebc09dda978e1595b7f392ec8f896fc8c8f90ebe8dea1cbd54e8d061479656edd13dd69467a3adec9426f1e8adba7c80055a961d5f795d26268efbe41dd91f7ad4181bd6e6269bb348149654e2e12c94f5400f1f8b33de35db8a08dcd10b5e50e10def51cc062157effc7fdf2f1bc45cfbf600df322a7d711918468e3edea2ce05716dcd996e292de09a910962f64056fec1e8fd041dc26efd6e08b62fc943a84c6e8578eac778685515be6e24b07a204626acd3b43dcf2b95cfb41b366f1f283c1233c4c54d14024425a351cc057f07b861dbe48512e6e34b136484eb43fddb97778cdda81c4e294d740c6a2b124c1be3ec67c266be133506d35ec2a68e89d1eb4d16ca04066eab2978dc14171e8fb0d5591421b6852d4c2986057beaa96bd5e7b3ada56e3932b29bd1d4ddc4199a793faa47a7634029ebe81ce082efdca2761cc1c5a00d2a779e8b1548de89acf26787e7129ba62c445324249dfdedc6c6639d665eebc2c5cb475c89f8fda7ef4e88786d24ead0589567e82f0841bfe3e483b1af4fe488a5e8f42766f765e210ebee1b2380d082573aa423b3a5f41d46b61231fd9e1f7501a7b8cd2a56aa9d9e272df94d630630ee36fb35f1d968e2602e6cf16e4e38ea80529 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 69e774db244d0529fa2e064257f3a7babd8942bfd18adaf8c71db8bfab59176bad88b9a7792ff2cb03aabe6a4c2937be24645a28c3a7941f40503769eede86607fb44c4842114980ba64a59a647438c5476b8ddd0dc4a63277c4dc73a3dc9b59bffbdddf18e7612ab73bbe4378e93fa4a8fd1523ec5016b36a639e4f689e9b7bfd2cbf501e23deed07fbfe4861ae7cbe7f7e7b4d5dd1b78bac719c6afe4d96949fcfb1e9e8794b4988a7c03a23c8c5a751ed2c39d4ee8474b43cf8b7814a5932234e41fd543871bce02cbda349153eb5ae3ad57ac0670fbfc7ceb4435f84ebdd58573aec7c0cafdc6756556bf034dfce6709e65b16726625928faf6d14efc0c0a66988eab99643b4cf23ac697f4ce645e88dd8b3f204f2e8e8a9f838b708ae6fbf27445a7555d0cd52982cb00223dca46ddcc428aef24f81564997d5f37d0a1c411cf73d3e2d82e5cf6c3bb7beb9fba2d9ec631f8953b4dd30763e8b4c8fdb4fb5b177d43c11e8979c74d639136fa20b718c0846405bff0604c55cb8ff529f41d91ea6981dddbdeec7445ede93affe83446410a93150178a4a2b52133e74dc1f8b2eb97df4e8a617d5876ab9977daa8b7845537ebda2b7ed599c0cc16543832aeef51d6aa09d5b30f37d40083ae35c2b831b87f2c426d72c655c4e6eee1fecd284a3f84a1f6d49b5a03b3593894bca251bdd1996d1a039d0ca4d6d8f5b69beda735a45e2bd355dad587bca7330374d31573b44ebacfbd103bafc7f83c1c9f3ac3a41f16d7d4b7b7e1e78eaac9b4090538b6b7975b9c5c64d6e96577b7861cc88ed6c3365aabcc9b97a6b3e8a3aafba8b17376509a563b58dfbf4584e7bd0d56bbbed3d9164a8fd1c9d6636ae46c04bad614cd2c9efc2d0597fc285779d6f8f3e39da84d8710745c4455edf12aae40358991e7defdc787faf55d6c70d3e223dc2e03b3ffed39ca3b9bbaaa34abae794d4266e59b8defb44528b3bf34e8dd25767a5dfad9032767722d6ee544f3417458de9f8d9a52f57a38dd1e9c8ad43b775bc853d8475abdac86811d568e9e387486e8aff1bd901283a3913b6595cb2a85b6d432dedcbd9d146ab85ea5449850bc9d9be35709fdef365731f176ec1ada5b7f35d9848c42603fe6a47d46574a93cfcc0446e4e8718d2672ea06bddd582da7b655fed505daaac1bb10d6bbaeb3e80881fb891344b7b8652446e4cd706c2dc098b0a069fcedb89ecd67de93e9c92f3aa0a9b92a10af6640f587a5859408b5cab563ef28e4cea386becd756db669fdf87a003faee7654cab39ef20c2ecb234ac1c4b459ee48517bc838092e91de35b265e5f64119c05cc5d0a063d7c806ae8256e28b8e94f72df4f6bfb7c51d68925dc0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73de9ee9743f830af559ac53aa38e981129db5837d00d9843334ea3da2b77f4e588b0088e3d43e8d0dd49c4777f7b08678144618e34d6b9b6b72698888c55f9b7e3b272f9f620bb367a2f66c3da4c9d4d3d1d49650b5530bf0e7c3b99c06899df270570254daa0bfca823059823ce8982ad3b1677de127386265487665aca4c27ee0246f1a853965b6f9757148e37833d31e453dcabf0191c94230833a41d89c423f4aa5de0ec097210f4559273dd6c1bc28e09551c85c4678bd15a7b957b1b4e0eb8886cd7783545e4598ddef6fe70d2ddc81dd9f0e4cb7d16ca9fb6b8cb6086527106b5508996d34f50026470740586ead4f011db626ee74a8d7b6dbdfad73aeb5f6a8a9f9df7dcedcd3b203a5bdb2abfdce8798764a88cc84cf9ba31008470904c46c523748a4b39bd46cb5285d1f617c43c83adcadbad191fab61aa7dd07eb3ff5ef8fd087766e87344acc8429743f594f784095d1dd3a43eb7a835044cbaade65a8b52a9f43f6fcb3fd5ed4ce699a4713c4ff3be9b7205c256f643ce15dd477e32d645e70a4c6c854b45e3c65ac8cf4f1fc7deb0b6ae852b3d526a527e4eb8f66fbf56ab9a44d4b00c47eb4055cf36089c905bc8b53dd6098ca18c58b89cc5cce6a454b02c754f17d45e274b3a2a647b17533215c6fffefe7e988fbe79fc308866c4ae33edbbbce1d4a06a3eb75c5561dbd87a74dcd19717ef370e85c78da14cf5d8bb38d895dbfc4cf4d07ddbb21a29d7d2ac5d4e163c26a3c58f57212b9b824d071bdbc45143b4663ada61ea72608ea85b82b49075d3adebaa7d01bc9cd916728ce121c1fcba51e42732d76575607d3e574c654043d717afb96532da23924fc124b01026a8f8b859f4bcd1aca153133905904c3be8361200abc6e7ad42f236a0826c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f18042f2075e0a8c58a5c244e14119f5b6d5538385089400e23bc1c106b2cdb59f287c538f32917c202fb682b9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74096e0423db52e7c0099963c5147c2cdc7101b0d01cceb8ac64937186c23b0da108f58f5271e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af97c05041b0494ec11daa36facf034210383acf9089d371aeaea975c489211184d55db561c272cba9881acb88159c74bf9671147490fb7a4cbcde1689ee7cd777b3f83c54850e8082e884a7c3b3333d7cdc6318d5347b0160a4b67e46a24d756105c09ea0043b66a74f98599129b52eda51971b60b6c65867b3545139990aff9c088b7b114c03d10972bc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d6a1315c63136139ca954a86302ca788c27b4f82c57ea35bd7c31d5d543cad66bc4ec9b93df67d2b019e56e372fdd7808f4453ebfa3092676224670f79ec579307052832bb4f2150da4c06e8069855573378377c44a9508410cc62c60ad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f6152bb2845a3de24807102a274d2b33f84392648c6f64ac85d304a4c024d88c0a13f0874231cc6d2bc8d7c99c0530087f61856c000180e78939148212d2b065df99fa51a0e768995a8f3bd71ca82a1792afc7c05f8b07db30aa18dd25180b73d175382158a1c3d5135fdc40f2068c17ed11d32022caeb404c68418e7ba2f352a510cc203179366249385a2db3639809795cab6ac0c11450220d96356bc6b45ea943c5028771eb8c58097966b4821bd1504ba1a1836251047c8468089c58ac851999b7ba017267c3a6e20c5223fe5a41a52044bd5103f5b1d31fb9b0105ccba387cca72b6ff1bb27119005d6a29a6200de9dc2c19d85be067793ed476b0324c24f10a8d106b55c63bb346b9ddf44b9a5a5349b766132824cc955214315267d69f82093642b9c2360c2b57993b1ff2c52d8118d62375ac851f5eb181a24badfc165668e7a36817cf80f5873f87a6dbc3cd42c0b2bee57f0e06c93a9807b0bc32de588808ea0037db50b3bc14bf98affd4400dc9566ed8022a4c7c34fc4369987904b362b1d04cf3451914e5909ef750dbc56af138529a601a261932efd626510a528643693ee79284cc3987e3694cac828ba3964e637925b201e270744fd41190b3b1c088a79f31581b0641917dc161b000fb4a8281f6a6b7b1392949acd277b9901637c3454a058589299c48b3401a2e0f788744081cba76b5ec378bb83789f63962ae2af1175176ff353c1cb3632bc0e206194f4b7367779146df4acb6d89652b946a9b9c2b61c0553360616f90e97fcb190c43faa544891745ca9b97950384de8534626914ffcda63ad302c9f001a361ba7a94066c9d8b1f30111faba3728fb143bd788aaf04491951d541078aa1069741352fdf8c032964717ea1791472a2069cf43da46a40046c61c79cf4a7d1e093526d75b444a08b0ca984f2869026a4432244d662951df52ba655ac54c502e83e8587e21c4757166b78244da2b5364d3299981859cc61a67d02b32b19c8ab31b78146690690096d606befbad0ee628103712f0f81e5fb4bb22e65e9ad1410504ca75d29386f73b53b0be140a5b548a48b05313de873e18b030d6f691322a2409f4603c7bc24c103111fba7dd5acb3f019e7cc22bc3f6b1e6acca131364d0fa0694866e2322281cd229c16aa82116ce6fd0187d4034db33c2b3840db1f42c5df49825fa7c6bd62c31a625616270565a2fe3f4bb50c58597f70e6124c2f46a83c3fcb62ac65a5a66557b22ae31c7813243a1f0c4b905a31a40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a0825ea860af29b81586b25832356c1f976370496b6fe7493e482e0dd9483e51372b093d37f29b9d1a83c209bd98a363df8a3ae430ba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815da333d474be9bacbea4c301148be2ddf13c3c25d7e4f52447a549a27b6d12710da2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = 7a15ca405767bb90d0d9760073d0b132c61cab11bc4e0c7128cfe36a2c66f31aed86f7b1564eb5ada3a2dc244077f8b225dc3c11c14f01dadbd4a596f6331a1f35cabf199b357b635a9032a852a7b06c9ca27b77ab000780ddf16e2ab81ee06e41dff4282aa32848ee66deceb75e40f3cf72456f53ecb11f47ca808c05c9415fa6f07f24e6c87f2cdf2609e24df56c2875d62b12272cf673ec4e44db21893f1abee86fcd6a12d8bc34e80ebdba35ae88b8e48735058dcb1a0f7c423076fb16f33032e70acdda71af0fc5e7b0619f52e9f93d7471edc8e7b804964284943dad6cc162d1c8baa62d892450698e329c04b9bb6280a96a390121a6ddc339d6ee06e747f30f9610fff22fad8979a54d07678c245d00729ff1c5ce7ea1b553be1e4156d9a420a8b65b2888f9dd032d3dcbda9e0bd1c7a2454ac3a95ac3ae8384e062dd6875d3326a648e605e65f7302a9788ae8433d8c80ae86cbe77fb759ced8ffb6d62131e5a4568f15f2b0df40753d63fc20b99ff476a5fcc686b99a636c70a610980c3e403681369a41a952b49e0b7b0d3cf0fa14275a6427249de642f61a1062ecfb10bc59c2bbdca073ff786bbd35c98701a534cfbfa06f633ee19c3d9fa51080423da63915e34e8f6bd65a6d0dd54c627c01848681010aa5226890d707ef21b687b6bcd50a36c06f8d506b8bdfbdc47f2d21f4ff3b5f37b3bc99c7f7eb05f5853ec4ad4e9d7ed1ac8ea161806041698c2ababf591c41d5033c312df31c6ccfa0941aa307cc2614fab7a17555addbd6ddf5d3db269bf21f8a83e8160282033234cac43a6ac3b9e645343accdd7a0905c54ea2a9cca750e0d8edf10586134e9c63c61271067df91327e064c1f9dbab405149c116c8e5b31087513d2939e3756274bfe284222b17bb99a4ffa1d9c092d1ed2206f5c227ccd7feff9790da2b33a012d975097de5451b1bd2ebd1472437a58f52c5f581d44f97bede74476b810cb9b0ea47c190d147427ceee3d98b4355843d0e1239ad7a94c8cbf42e6c6cd0dc4d6b6177e32afb339abf2661860889c8d31b9fd984f75513d39f9b7e8da462b5ea7941440cdbde94ede2b6c50e53c9c83fab96736e82655c3dcac4fb5b1308dbccb81e869f9661dc68c7239fd2993e81c58ea5a203b31087862b0e9a5ae1abeb8dac43e66ecbf56c5734cd5e37cb5f9b8992ba3d36f89b3cac8960b092f5212c8cc54e1c842557860356e1ee6e3be44c5794bab7f291d2fd31de9e3177d218ae60e2a20291cf74c7244792b4bb33b471f0591da492c99f7deeb708e8cb29a187134f288938339f10d71c936805f39f1b0ff4d6562b4c7d8c4460ab6667570a4f806baed968f34455779efa411a7232983f8a9ebeac7a6b413b714f2b53386f8fe29d7a7d9a93f1264496c84df8c571508bdde65b31f82eb279ef312309694a8a98435e8ecdefe0256e55a85ce0b866f35d846db6aa786203bd1676436e9c398a1277dea0cabe668b9e92567bf5e9df2d99b0229dabd1dcf7908c858691b8b6241b4140d2488817a811004845648b7cfc9aab7ea513069a4a5c45830a286e8c0d922a5f0f181285b25d6263df9f5962b4f67f1fa1765afffd9e9f4204889bed16a4569c79a68147e8cf8e9162361f645c670d7b3cd0321ec6acaef224c7c11cb04ae086d34e11bcbbf01746f06b863615e3fd57a32274cb7781ef4eb7dc5ac4a7285d64c2bca6d5d5529c1781d3c43ccda706655c0252bfd7d49c1580e14bb558c91fbfd789cbc7e7f84baca72e0d42cb89034e8806e456436c6d893a7411dfc5820f9490b3a0390d696446bd6bffc3247acccd917e2a9246e3710b5c28c30bd0aa89724adea98886363443a81e702313f4df4cabbebccbc6b03aa6f15a2280ba828c6197443eccb034c6f6658662e56a102e38d0ed4d6e02efaec6e0fbf4daaaef3ac1dc7aedd17fdc1bbed4949891632e3938226f8ff8639915d5cce755ae463bc869d1fd519fb29b67743df797e20e034f800e598de4ad567f399f3e0714be08fbd55f038624fd9324361e793582dae656b2c9ad77a72b53231ebd8812c2f2d9ec5128f50da504e02ba2e4fb507d61c9ca805cbbd1a8ffd20367336735b8622209968d538f12c3102092062d8b9598953f3f4549f10656eec731cf4c26ba9f31c690bcb4fa2cd1583226c584fa5f1ce14626f1f8166cb84814b68528b9745955c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d575f41221565048f3b610f36d47f6ede9d875057d5cb4698a25e5dc0e8db3f87c63d575170f45d121a848d897c3d0d63dfe9b2d616a9665f384fc7fd6226a19309df15b364ae667c34caf7feddac0debcf450578c7de82da365d40786522c37b55fde26ed7b3c6bccf2804d871ff3736b394210b67ebfa72f7bf77990bf06e48cb7417f61a8688472ec529974635b35f5b4c530e68bee8dcf13387b66b5ef7d12ff3190d67a2fcf4b2ebb579f74bfd64e7fe995bc08e67388ff912b5b4dbb4c939dd686d2cfa4498dfa733e945ce95fbd67c67f6d862de69ddd4ef825db52a68c14435e90cefabbcf5babb734aa03538899678d439d738cc63eef6e1e4344ea73b9c41f36c712a4c6d7f42210dcb94ee44f3c588a2299d5704cb347b90b39d5cbf69cf1dc5c6719d9c488d94e89cd1bb3b3e50ef46f8dc3c62da37bb13b6e2046911d85d589d869fa4a550fe67957fd4819e9c0dd74b9887bb5d1f5c34d76b3527a42a46b689fc4c5767eaf13c44b7e3da052df8e98cda1f5d621567374de7a4207acd4dbe8417c7984645cf4f2b5a5434be901e9799cd760229301e14431b0b652c643c0fadccaa13cbc6fa6dc8d348b908b78343978fd5a0eef9dca61d4184f33f107837b3ec667fcfd7000570dd33856939bc8ba671b383eedb2a94596a8f2f37bbc05d48097d91fd2ab164f5c6a8f92f65239f08844ed406d6e3ccebf88d877eeb3f4c85bf696c691f85a94756e331aa33b15973ab59f3f429c7913731bd0f553933f21708d2ed7d78e3fdaf3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfd6e65773a965e65d34eeed94966694d88d6f205d6cebc3b3dd3d7405431fdbfe614089c633b52261da5fca73462c3ffd7afd0dd6e4c5e88454f28ed846be9b886625aaf372bb3361b9abd5baf78b1773058ef6108cbd20aa6e0bc19af13454df46b4fb5a68c3e7aba6f7e97ad63439d7f52cfa5d7e42d72e447f96883c93a1ff50165a1aee8be0ce6acc30f9e10e97536eb958b79eae3e3aa9996986805c6d1f6356d26c1e63c55048eb2920bec96ee83ca933d5ceebaf6294c4b248b426472481fb2a38e6ed4dd9042287eb9ae7ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb91cd457eecd673e37e21e85537bd2d97d8644539702be93bb6ff58064b28add53404bc78a397ab86895bbfe934e9bff6cc3ae48869be85ffe581a6ff748519bd3dbc96c716b1af4a02679ace5e51dbfa0fb1f7c81ea513c3ccc3b84a34025522486ce424bc04c96dedc5758aaa9dfed47fdb324614ff9e589d78acc88c43c2643d64da50afd90ebfa621493fc76ca982fbaeca4465f9c14ab4e6459f17f558946cebb1e3b5fd7d24a364970d7f93343ea6a5bdd4196b9e72e9596fff9f4ef8fb2d5c6c5cd41dc2f6ab71eb04c3a80fb5a7f16ed8df3347df00f663aa39409ac4e8c8bb0934b46b6a8816cd7dc8c1be1a7fcecce57bf5baa30e7afd7d7e59c9e386d5cf7863c133ba1c5e0f6ed6c4876ba7849611bacc36abd39f0ee73df6b8a22469e203ddf2aa53ff84390b893d2d9f9915c4b8257754b3433d97e7c6b0efda71c2e62050a67be39eb2ddad460a455a78d68c3eafec3c5c4fa4af72d45b55f58a01f2a8de6cf43ae89ec0fe643bcb35818ce54ffd29315cc7b4c3843ca54e91474f2f73f46d1fc543f24a884839b4788c10f0846b3fb87e98bc4ff634c05d6df250b8c2bfb46c50c8a5cca5ceed866badace5a8c88a3ef590674727f969056569b2b16e5e74e931c3b94a12a715925ce347e6a985a5762544af3b442487be4316c9ad20d396e9885c8bdba8c67621b7cee91ce3a248a3bf7cdbe9f9660167fc87164d41878891a2a5448ac965c2c7c293e66ab39ab1576ad253491ab04a11c8f4fb6fa516b77d9f57b98a71db94b3afb8705d58074de1084a6ebfedfafbdec281b97b8eca8575cc00b3df0e1533c3ed3dd9a55883ea9c5b278efda938f1536546cc474e5e37a05eb89ae4a822cc6a32b8c828ef782065695dd73d063cb97e953b04a1eaaaeb9dabedfdaf3695492b49b08cf6f79f59f32d74674f37972df66844da4803996358c59051685cf15410b7f657355692816699cea982cb364eba27cb3f055c38ccb7a5a78348cc39e6039a1126d369495687342f9b7c7c88a5f0d1c2b15e68366532f17d6ca8fd85d8e9249ede8c5ce6572d816657d5755236ac059125743772ea7ea7f42785b48f62974a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33921384aa9737af3a3e2d881224629a76c50712ba306b60fc88b85da88b716a41509a95876355fdd49a2eb7130600abd277810301062b0b9be3c97343e345e8fe25f6b58cb16c90a36830452547f4f658110f0745329406dc8a698a71449888e2554c5b039076f67397a94cd13e4b9f9558bb0464a39074fb6e556494032b5433d3df005ce4a1145f0448af07a089447cee578c2ab5d090a2b9ceaab2b472420a56caaa04387d7969fd51a1923c14959834b905617c61a68645aa51150f0079ea64bb16a8a8fbf701c9f5ca74a1803519792ab169976f886cecc709aa90c408720fed90b58d006f2f50d23c4bac1432176a47627f6090a788403042efd5a7d1a22c793aa8dd9a91e381acb0b5625e0fc203fe0b4c7e816eafb87cd774a5053036afab5b293c23598932ed3658f8453b958c1846c61c4190386343435b04c14ea3597f84a22f70124cb293781accb8ba008425149643e52cc124969929721486b42ac9b592eb1c15c4f8c6bbf901b8dd419c17c38d68bcb9d519e16021e62b211c6ea00e5622486e41f81f6ab58c49ba5729c91b2396f7bc9cf8462af8b06d1c28b0cca2faeda8b829943f64456bd214b7ae57061a325bb9c097b656217d65b36f575d39c11f971157abba074ecc1ba302d5318085e13aed84ac8d16652361b67a02c41aab82d10fc339c53b3e096aec1e1276a572ce1a5700c034014884392cc6eb4f9ad80a52b711053e2245537e76acee36f530610b8ccc4caf241a0f3c1f8195cad80c69b644c45f68ba7c448431705b3e9bb84568c895b56351a09bdd8ab2763054384c116e272f5d0a7f1f158e5f68ed0f47f625ca3732729e53a87d223c1ca807d277b726d0c7ee938667ff1c4af519ab7e1446a077b6045995d3001ff289014e43c7ab738f422aeea3269c878b3a7d979aab698c4b57462339703386cb4d0bb0598272349b04230c6b6708c894bb409755dd4e09fb8a84e6ee678c896992e845908b963fbc407589acdec414546a92b1da98c294b23a53ca79a27859ba787a7689202833b87893fde1b230b936916bb038316b025a5b1039a775b055d6b26797482672f02985e39c88911a4540327e3680c574150b74331ec63076d645743c677abc255d0b11d9489a35d65448a2c1bde4228b4d0ca03441d90b57d5c16b6bc6562b4d22e61e167861cb62efb1a43f008877a2895e95b4e0428086c7c34c146f5fc2c9babcdb0f74c76680a62a5c8a82348e7b396b7d95bca26169ffb90125b765d104ecba32d3291a38079567a599644cbb4d36549f26615fd31a6232688bd1694d6c72cbf04c91638ac4e7c1d8be2cdbab51fae70093af3272b885e56f62bfd925b02d099602110914a50d3431f10a803608806d9257bde17123e939df7e1951883ca93e1820e852f2b511218152011012b8adb46d9c400ef099ad3e412eea953f7eb7e627a762de88e7af6ae0b832190b91950aa40713521e0f54955f2039213c16a604b29cb6dba67b89947bcd81b22700569efb06548944decd13bd133877e44ae8480c46b6b547d72bb1ffa0f88fc3b13e2a48e5b490301d00df251e5691d36295a16dacef03c7974341ec3289ffd87434854062ed9475e758b6c297acc679730e291cbb52562cb9408b07bd70215aed0a1034c6fccbccec88b72e44944ab79592e659865f019280b8723c578096220ce5a0930dab0075bbf09b952c217b4ad8b707b8106f9f5180eb514176aaedcc3bbe0a9bf876895ffb1565d61b01f0a3f2d9391c56b6e6a9363d434b1338456313472ad730cd9374c8d81788fac62d68694df05bb88a6613ee14d13cb6e18f69b372c2944a7a76d3a16157686ab6250a98b42d50b15aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce132814b26c0fb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d5d286d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781ede06a48c1383938a9f242264aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc35d109f57ea2764642ea3473a4f192cedfbe153a37f131cdf447b60e92310eeadf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = 57cbb1d2d65c141407b9576f9bca609316fc572f2d2cc947cd51b7767d46825c16d3df8b3552d9f04dcc0c946ff2413271393542b55f0399350d04e78f8b89c4bb1009042eae994fc42ab5950197dce9b7d33232f28b787b781be3ed876f7403c1aea44f281388d2aeb7ae9ab2a66797e0bbcf9d9475fc0b1df08dfec18a199f4f1591e347a290a1bed55b3ccd4e02713874bf240dc39daf1d871410b9e0b13301097a8b5f34c38df8739f5c36f587400ee712aea03640050cb0451d3ceef2dc252bcafcbb29b5e8d6fdfc9e54ac34af80f03bc660424317d07def719b8c7d3bcc73eb55be669109603df65238354ad81f6077d24fa8e8cb863048b43d1d7888c7f4b75587f91432192a570fd7d78b0a6b081ee51c4561e00e67a0b9c59fd5851b9783d16237f038de6d9a48f04d7eb5a705a479d5c9b8c15bf50509e1c8ab2d75a3c1374ad0163eec68f3edc973ea23bc0eea94e0e4055b30fb39ab6ae80d4b745eefac8fe1d8521be3acf3b18563e1c3e58cf719ca2abc170554732b4513e4195a46fe211482a066d9d24929a15a0b3368c99aaf2fa08206e4969531171fbd669cea343bff8176235988e799f2636a8ad5679064ede2447d3dfcef86ecd8183d5e307ecc39caf2cae06ce08ec7e68ad4a865373f630dec35c1348192acbe7f03d6f3409fdd6e90c6e93c8cbc1e72c1eb929222aa8976aae747712c336a2faa21496500781f43810c94e0b9103b3989943e77c5e9c0b47d86c0b13a3bf3ed76a7f280c491d8633631edcc64d0f0ab05bb3bd420a001675d3d8dbba207db055c87bb703d54485a4eab992c9a9f33679def6ca8e3f6e43218e175520054de072a971ce6d053e0d71ce4f5c3d013a986b7b534d2d1d6b77df2326e82ddc8fdd4b529d586e64c1f08ab916e84e169e2e7cb3e86bb2db3a70913f629a509c601ed34202c51d1233fa7083184da3f9c198c182a114688d51fff6950dd0210ebce437f16db5c71fc99a7a7ffbbce8e9daee1f01704b5ddac15aae9bd9ba22c9acd7e456d3ba4506f14410673c3cba52f1cea52856ee3aed64ab2333a08fdf84702de5ce353146eb79a8e2f213dbfdada91fb94ac2fc7e744572d43d310c978e7b35430e10f8fb069bb7973e1dd4fa55073dc00aa0e871d9cab4e258ef4507fb3a6ebb4bd3d7b881ed82e9962aaa37895669b2dacba11386be59b90952a0dbf323b8f9b14d86b89c22066f6396e5df81ae195e2b99fb5ff3dd3b216650a011bf55df026ce1c6bda80f740838c50608e6c0a80a75be65b64b4a4a8b0879625dbcec514b5fdcc6739573b03e1cf99f7abf9cc73b04f9c7a632343699257e15c836b65e1d3a402758a6af62073df90166d091f9c22214f137fb401ba00d9c072f1feeb88321549cb40d5b97d4ab9d76e3dcbe924b87714a05d43dbfd22d0b6710023af4a4e7239b4aae8d0268ce441ffc1556553e6fb694267867d5d3edca2fb720e383e4172944918c06c1a7b7e3ac57c667652556b3f59f076ec6eb26bb7d99f6c934317906cbd84b78564db3bab0f4461bb3b9f4eca7ae19d4e4fe85cfac56827aead0f748e68ec0cf2f3b2fc764a01743ceef75e64855e03f4708f7c0f72d68dabfac742706cfdf057ccf36e3220956a5d2b85ee8b46ddba4eedfcf447186ed3c85b5086cb8093eabc3e874239f3c017441a35dde66c71c984d131ccdda6a037a0f44c75d4c993045acbb2e4a1d7ea8604fb6c898fd9c5842fe6feadd2c21aee9956143ce4536477a550169ab36b382a65928474c3d545c44ba6b6b9faf2706f15e6380cad7d1a1617aa59b834f6e88dbf6153c28449fdb7739b8eb5b150a4149b0521098b112dbf1ff35d5aa034820ea3d427c48cf4d57cfe2a90dcc81e01d81a392772c1ac307b3f9c0d08304414dd1789748e6eb258bde4727b7c9f2c5de553fcd4210300bf6cbc4306e0e43ea222f4df44639bd9d905acdf5b44192f4b5fc48e371dda612bd8a242b0d344387f7617eab7992de8db81440ccbb68c54b08d1c8004bcc9f4c970d5199384351edba8d86683aef89f60f053b6a5aee7fcc64b30d79414da116cfa251c4e7e94f3e621e2ae92b08888e07e3c2264ce732a1052422f3c3d9d313f148110e81eb8929403a36f3817ed62e86e7ebb83e364933d8c34cd3ae1788e446a17c4c80699a3498b8ead65e27b6ff2f7f794f92333bc06f0abe657 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 953b6e6f55fffab6b9e27b70807dd993fff8f5fac9278daaf323d0155bf18af5ea012a4cf53840cfe7e4cb63cb4c7aa0e8ea6e518d3ca47dbb38d7f05d9365448b38308868c83348acc365bf6fb4fa763ecd6ee2a48558e67f30d92b5869d77d99a5c0bef4981a6ddb3343d0921ee7e06bd82d15368af5f9923c6bc9d3594ab33c91c8e54a8f9a2ee55ad25f493f8daa80399f770899ec05417a698e6493aa647691fedc92855cf3702caafc8ab3a3194ce8437b8e2a7f69454ae03e70c38f972abb93cf25fdd85587f637fb0c7e590d8eb3a9f680d1944500fec3964eda17f55272cc3e1364a9aea7a67af4561d0ed143b7b7eb4ab0791a8d638e4f4b6536cfa69ca0493fec1a53d597d9fbab9c87578d83c9441e6fc267e7aa4ffdafc81d6c9f834a5a23f06c4b58d7378af90b85f8ed5237559d6d88e9f455aa01d68bc297a8dd86da0df9715439e998afe8b496ea49e45aac1fbe6718dd198cf5ca53483d88eba27893d23baecd393dd1643dc2a53275c84a1aaddb364ccc94a8ba3b5768f8dbbe08a7b090df746bec62c98c5e5198695c2fd48ba5c98753aaba88bfbbc6c8de59dafaa8343d334aaec7f532c63d60667079c4eb6a287b04c797458acd9104c94e96bf18137b0868737eddda8f2e64e0a8db9c2e35dc8cde81eeb931dff8740cfddcedb5542732e8fa80e407a1a6e5af0ab3e68a963587379aa3e6a2b18fa8a366d4bae8f7bd6aa1fea76a619ed0ddd4db17283eddbbf335b8796ecebb57887787b4f73d4e85867368be68ef6e5767bcfd580f07b003556ecffc3ae346f610ada80a2c9e4ca9e4144551c89a9d68373ed9c7afa83c75c6b8affb64e87d3b46abdc61daed70b5584be7564f932985ea4c739cd9d6732a7cf79a65f0f7b0682caa5e2d70b4ed699b1bb3ac0b38cb0ffda4db9473dd6b02954e37cda3d899d473588c77e43990eaec710398586eca722ed9bfcdb8066d7d732a36baf897e93c6d9a988b94c67a469fb7594ef6fd55fff0b45a0348f49847e5c60478685b9c2e0e3d41b47eb44fa05fb76232554df30990d7feb37eb9e7212dc66fac8f4166e5eced7834af588e06f3044d74b214ccd939564817e822eee09daa87c1fddcd9573254538ec3b8459ce56579cd9ca66a508e88c4db06e93a268b86fa4b7733a8cc89ac826e9af8f56d8aebef665a7ac423d05be730ab4ecef3bd6a7fba53565fc8cef73e90a8584a8b799d3f3f61faad4b9cf5d06cb883493147069eb1c9c8fb36fb699693d17de262e9ce5b383a0d27c1572c49547bc909ddd34918f7343a690859a15c3de19975c35aa991193d52f117b53d06c5f4683d19ca5ba6f5595b9bf69d96c1b45f4cc8fc6eec85dca33b55196d3f59c5d742df46642bb88e06eb8bd4c54f48af3f573d4cdc5143ecbddab5a2825dd721544e16e35ea8ad5f172dd3a6c3adaf79d189bcb074f546bd2d33b1e8b00d56cf33ed733dd8ed05eb358d148a91faca963b814a9c5fdfdb4de79b729d0cf7c3d9b48a4730338bdbac9cfa3638f68159979f7be0aa9ab90adab98bacd928fc4e367dab020dfe5a64c5f605596e3498ea63f47286df61dbfeb734c174e48237c656636645886b65c566bf95e9f7b79fa0301ed0ce756a60c5d8a18754d8f6bd8b884e0ac57f0c0b8f12347d40fa30f374e21157f6396d82556ebde51e36af083b303ac118d685622cb7c419fbc0063329af484d3392f8ac4d91b64c2d19a8d3ae936e0bdbd83c76b523e0afd878246c52a3be3e8d47e9a77f9bbf057365185e9986d3164c63495a651a65926ec96c7c54a03d0ddb74a83fd5abebb33c55711c4e268ac89c83df84858e6724ff051c617e23ebf1a66fe39c5ba5eef676549d643eb9ac3fa10cd9ab9a686217edcc652c981f74c3a17da2520a9f45336b955c46cbced8365861e5c79bd409fe36959804bcb458f843634eab5c2d4bc9d48bae38bbfb6ddde53a7ad77ebd4a39d57a5e645a346c2f8bee6573323cf6836433505dcee63629e9ac74da8f5d4307dc9b074ea29013e3febdd4a1c4a8f0eba7c42985472a57adc37d90139dd7ff3e3abe5db0736b8616603da46ecdc4fbe478b7295e9bfb1a95a33c9b7c2a52fa2ad89d647fa6bcaf16b83f2789ea59c89011739909ece3cd0a8e3248e087ea4024189fea9213f8fb3af02330f61ab15d3a31cbf57898f016b419430d790f4ba8a594e2ccb6483e46e5474518ccd033543065cbe6a5755e97790c4109a5cb18b124992d885493e03a262c3da395b46a069b9154c81294a7dd59bd092b69aca326220475fc792aeb639ccfa62cb9c549d28736a944af91119ad865c8e13700ce9482ab6b89fa7794f9d273bab516d142455a78675e21a8e74cb13876c82c738a55a4649304cb8f9cb2dce220c1bc06ddb0c5291595bd5867fd105236a91d3d61b25950c4d991625d3aa711a2449d118a51a88a1c4c17ca680c3ca950d141a220a0271a2b0593db333c1ccbe6a1380e465fe60404055bbfc511895861a32433a7037a00cac8197ac11528011e4eca80bbd921f2bb8162c0580fb94207c89471da649ee7cffa4293c4b6baddcb88efca19ab6c6e71f54814b8a2eff67ed476088dc30727aa0a47b81f9390bdfb93c3a8281ef3b92be88b130fa739023aca492549d42103663b97d7318c01e0660696984aa5c5bb1019024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785a41a25703627f0a51bfa82344723c0ba43184a77556b8cb107232f480488cb24f8bf324be8116fb49c8c329bbaf00c9ac7751a39a222217979a83301c0528b87992b87cbd5c576c806b4e8c383d5fb025ce83104fc5abc9d235ea374588505018c167a78902adf24f33ac22811c612cc09b4ab1240fa18359134cf4f657fb5c96bc544f83b8b02620b5564694284452d8d0467716bf41504dbd6574f5ba2879b674e9ec858700213df91f5f9b18686669c9365d2f2cb9def360eda91272b876cc75a022724c7caa7e003cbd0b8bcb5b8656fa7255f0c8be4bf2398e3106e47ba27a934896370d52e0cffd9263cc85b6266018fd6303371969e7b78d326c9fc2c9a5b1c32e68e218ad278a8d5ca5629210ba342148e45217d594958bc0eb6a13b5910af6f616e290472ce203a7f76f1aeb4651f00397fa537fb419ef2ca0f28834ec0ac07b11bb22b3a1a1b1cfb4679586f720bf6151662303f6fa774ca020fc03cdcac3b74c319c5b23ceed4c24ebc48f067735cd5a02f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f6082965579be60a0812d34361695ee6282998219366628ed9575203d6652fb127074cbaebd2c1b25c520468a4abab0b550503cdd33851ecae8bb27726396a15a63dc26078368aa5a7c1b075e781fd231ec27cac42eb9e507a82751b7c8cb7b3547b0a1a58c82cb99da9cb926e311b5a9a1d682bb8da2c40fb679ae4c15ea0360a39eb6fd10719ae253aac91132938579d3616dff29ea1d33640e3b71cf2652e85c786873e1457762d230e99b81db1a99dd0a8ce052849e1f8a5ee050eb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02907032337720dda9b9f8174fc20afb4439a21fb979af288f7b7101b104e2c7a9002b353dc1c80bfb00797455640b603b65c4cdc89254014079fb33217a15c31f6262c1430002aa148ca251aa15981947d27951f24030f9abc3e49370a94d803094881f3017a8be248e2c9515822439ae537776949641513c99c695625134348172b76b8ed929d1063b05ac774d83a3a6b0482eba52b2f07bd17021e0fc4b7651347f4b95e72f0a6d676158ca191a5c9975b1bb5b5218093eb9716e350e2d340ace90956c05b5d874dd60a7c9716894f551dc5986e378c830af8ce327a027741431d48714223c83f7b1dca94ca5e99814e1311c69481f38ba87fac128ea30c19b2baab1a2383113e5d282bbf0c4175a69fb4db66fe4421bbb26b990203929b3a58a85245bacede19159d1ab21537cd7861191d15185cd5b4f07a2559110cb42bc0cba54cff480750b56933666cc470b2504895a1213db43c5c176590c9d97ac7279d6dc55ccc7b1d4d82bb33f240b4c635a936beb5d71f787c396371c088d65f7b2a395071a4e6c381a1708ec05a6e55959845b456794055864c566d445ad9091834b77a30228caec6a0829bc243a9330b42010d62149d672373812dd014873bc79f627b25b1ecc782384e0dc8accffbae88c0415f6cc03e7640895c744f4707e130a9c9ac6cbcb70729db69ea7c6d8c8a9e94c1438c96289b41419af6ab083219f8a88753ca8b6ff168d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2cd65fd07a78e48c1a02e235ec76fdb509cf9903a4f5a850c51d9d3fda383cc67df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = fcb50c168f3358b2232b2f566c1da4da98f6a5b62e228456823fcf38ccb848e3e29d856e87621f63a33287c2e48fb861dad773a832f9d80d677e3d6c4f93e2d46bba6d8523135daabc358ec800144fa4b22e64843c1844dcbac3cab2128094434e628282f04eb18e1694096d0e19e3924045cb1a4a7805d879eb4a66f201809d1ef6a5523237b361739de7f5ca4e8a4e026128712eb591d422831ab93410d5a0aad8a86be6e8051ebd4119fa2c57a74a0f5fe71453bd80cd1e779df5d2fbc380a035ffb50baabdec86302e32c18dd2dfece9670f02edc07328033e4bc543e1306097cfc121ae9172d39681464c124093dd853cbed8138b891b9baef4633251610a95005fc6065cf747c964369269871bd4aaeb147fba8410b9c2d3366fefaa6a23c850b6d5270bf95a9d1a0bff4023d0c1593ec0e178429c120d16c88092c846d5607d1e831c7cfc084971720c9eefe55af3efb2cf53c8611f71cb4e25bab3c3970aa4e1d5f71ab263508d3922f4c188fc2dd1430e968ec49cf18a73e0080f29b1228a735ee1c9eb404eeb345996fe6e18d4bb466dd324f51817a612502d9c269a53a0a03de09707f772dfff58204ea9056ef052413bbc2e5bb771c9228f1e6d6d0e317cc254f2196821233165b38cf1ed26a407a8d5550db26e210a79d153084d2c22dfdae1d19ecb815075e8b82db4377b037155171eb02a88dd8ae4e876f13199655b66904ae4f60bbde98388a64261866404feef743f1246c7cbfebc6430af76dd70fb2b4212306846c3b8e9e2513f5f9601ae4bd8e3b892d98cda10fbcf55264ddf3ea834a8bf0a770c71cc8111061fc693fc3bb42b8d098ac54582b4dfc0ba6a3c58aecee800323ba806feb47068bf23747b35f557e74f7fbaf554ffd81b1af5420b2a4ffa23f56f1c361a02b16cf87e196d1e581be1158aa0973102519663df840f1a1ab7d9a553246d2249b0d418008ac2666481716f9a4dccd25a3cb38bc4a87cf9260cc9705229a7195c7165033414715abc58f1cd74046f06045559fe3083ca8a461240811d5aa75ab314ca9cc44d4aa86f792da4e020d3a9fdf18626162bd9ed2bca008b2d136f2df5a9b00deeeb7e292773cac02cd69d07a03aa2236f86938052f22c643119a072952b8ddf88d83c727b33c7ab3a4e536e96b48fbf3d2511689754c2aebb50f6c7a3c8b2d64c630712b33f1fdf17e4a5a523de991c2419d0607d8d2975e503122de717aeb5782342cecfebf801492315e2660a00d222a3d275b7f17ef07ef6161e7262bcd9476b1e963ef6199bdea3613a19851d375fdba192563ae0c17cb30f7d0b9672eca4fd300f49a176d1852d976b94785c1ae13a0a3dfed4e08377247ea088e01fdcec464bc125eaf7a57bfd25fee500252491a952aa8adbd53188bcbcea3e53e1c22e95b731e8053ad8c25f1512ee943fb1e5b744bfe620f03ff709b93715bad814a5b32ecc8da867fdeff6fcde7dc131633c530ce98e552bc5a7566bc46705e565e33560a37112c451c6305a601e4f21b4293d773df5fa417f2af26b002cb88d50748334e2157fb0be868022163f332469b0abb2fd47c8f0b36de48662f0af98fb33d2b6d6dcd6b49d75372e9a5dc37e894fc946d21046bfbe1c30447b39b07a05692ed580c8be056929dde993baae59869f35db1c6cb9477834d8b5885ea4d9389ca3ed96dd2e9a32c824c167d80c3efa57de8805430e6ddce94e086c27c67081ea4efb12edb1e596d3e6464a7ca37e34ae9635cf3892d1a523ccbe6dfe9697cedfe50a0892d084ba31076be21632de72a70136e537f57716218d6c45ba3db7caa0719454741913a40998125fa5ab84a6b86bb3b02ee1847e2a8a76e8497aa092c4165701f894be5cf024329c17fd166dda767e6a8bce10834e6c24087ab22daf5bb17ba0a58fdcf989e829f158b817bfdb3d281a0220b51716a53da3a84da6af40d64f45939f0072f007b451461fedaf3582e0c42ba16a7222dea115df07775d5662b51442595a26311abe6805c45db04fe9cd449e187a2e6438b4ed9518a4c9a8b21ed4431d4068e3fe2ec34573d0713ee9320e43ec320119cc967b38941dc794f9460cc300b91f7b831e72a4dc34f607caa68f68b535995b9bbcf51ef0656787128a0242748f6a976af65bb431b6dc45dc99196c2877d2f56bb392533badb4d1eec1dce07e4f5a07b59e319f88 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 88cdb4d44cc9eb48c126c5877ff8792abd8485fb81e489e39d3f99c70c43c3fc8c238a81d4f6ee62a33db2499c866b7108eee6b7fcb1b063da7e758a8d487d11575079265b3158302a23732cdd733017ebd7cb7199476c39b583a2446109e99fd5c95be22af92cf374919d6e84b8f605b8455825c82eca4b7f2e864456dce69ef14c78ac4473688bd6a9a836f1759dad791b7835a8593588f847a8eca97b6dfe88b6380ecfbe49f9a2dbab1638e55506c353639d153656b90c5aff36baeefeb87da5bce3bed8fb6c3b29e77daf8d3a0dcba48ac6882f7ce194e8838703db48cf7d02c37d988346a3af9584a55cb5d3c44c05a18619a4fe5efbabd3ea057ff1b3994c902fce272c9e6e948c3d04329504e4349796c399e1f8dcadeae47352ce5e9a1743eb65bdc757ef37fcc93cec867cd4808edbf820ce7efe0d4dd64ab432d664864b43f8a9b1e763529befc413abbcf30a4a478a30a11d4d812d37c4a8af01b534de7dde32ae6310fe3b2f83d924cb790166af3b83f2baf4409cbba501cebb32894e65445f04e4b4b4933de61f67645d37faa44e2775caa53eff4e16d0e61d69aba662c96e45e31e7347cbe748d63e412550c014f37d0dfc02aabb18d8533d19b1a879a079c3ed529aacc05f58483c80738b380c93e19d1fb23cdcbc7e0f7506f3705dee316edf4594a4bd33eed382f8ab47478f23763898398d754df64203a76b0c4455237f3e765ea65e6388595ceaefbce2ecf258b5b96c88f865fb53554f7a2d88d6124bdcca88fb1d3f9411c6c133934ba4a959da88a072bc6e2d63a00767fe36c8fc5643564bec47bc8953d4aaabd146ab5eb36e3308f6fb9ca01f2f3253d3f0f76c98f91dca53afc6057fff7b6d378809a59b19680aa69eee3dd3e37fb8a1f3c8a55bca129640c6bddd187bcaf475f04c73cee67affeeb4e4f02859c9988357df6665196675df5e64cc5689965cfebfc0e47a531cf3fb3daa9c649954342a3f62253fe08f6aafca7dc85a7a8e25e61445f12d7a4a3bd4b57a2ccca45d6999e4d7d9b6abcca7f09fa97455bd974ecfc7cf3c3fa413d6ce6f39dc55d536974a8ab7733755d4b9889cb42bce4ef4606bdaa559346f19dd87bf8b7f0dabf1b0c9b75b69d3195bd745aec47483488eb4c1ca2c83d8198cc6b5f3da3f9f668f863cbcf951268c0187da818ec1c26587d87ed088f6d68f1fde1057fc825c395ac6783f074efa8597feac3734399bfa247e4e1531ead7dfe49355e44b3ba5439ea1e65eda94485fc7e0124bb96859df1c8b68e87a4c479fe570cd6a33275b6c3dfaa0e5d8b3789aacb6f7f1fdc19026cec38a95f7547d937bf55be7a7525c97ac4f82714c32a23c4723b8f299ffce90fcb4761b9eee869e4d3484ba3bf22ecf8bc71fb1f426d7cf57781aadd09f29617549c0b2179705a34916ebe54aa3747867c3ef7ad693bba5c1e4fe14c3f47c5ed5a09f607b6dafcdecc1c6f3839db943f5ebc4d44daabf3ef69095b3f7d9bde9ebc21de788794b63e1098cc39d3a83daf027e8bcb78b855fd56fcf16b45e47994aac71fd8e5c521ac1a1b697a18569ac38e6f52640d09d59c4eb95e60aec32b77bd7cbcb6ab384de74b6a37d8400e980eef5acdbe5733be895b75ed7266c565bffa204e98f000e58161637f6fdbc5e539bb1fef591bddf16f57fd0a6fb7c9589f6e3d62e8e860ccb94883cda06d5965cc9bdf72e3215867f1a0c30832d46c98589706f684d95765beec2561ee86a3aad789fdaaf43c955a83a259982c78bf904aa471bc683bcf97e66ef7cd82c545b096e9b86fbf43d4d9d6cef3e6663cff8d953a86abe1dd7e2ff62831db042f781bd59b2dcff899b97a0cc345628c4c3bbb583d98d7140c46bf8a3eac3c34cfa88f3098f3960cea51c1b50bb8ef74baf383374b3ea238ce3b87248edceb0a9ead9f74745698d07cea5ee089e48d9cfe46a4fe73382656fc188e8615aeaafa60eb9d6c6a96def4ca0a7e8806e8df5686513684ce2b9d77f8ea83068423b9e6fb4a8a47effcb8867ff8fb4405ae59391566c8897ff8ac48e706bd634a370f0ebac6cfc66c4b536d3ccf245abfb3499acda2e367459c4bb4afbaccf916e9b99e86a6c64ace8c8e946ec1d6ec7a97595b5d3e434e9a34ed9f24e5e339f90ec5581f96c8cf1564b86096399f0415e5b757e7a6f9ba5120dd8a938e06c7ad8581fecb46b60afbbb444ea375e53837827f80de1e3753a4aa255a4917f1c8af87923f8397c9750cbc7e5864049315e718aa2732b6bf7be35694468f55b45449934715e460c6eaf734f96a1adf87609f8551dca87a94f0217e4e507c2b637f368ccec681f36d6cdd469be9d0bc7828c1bf13a2d28b8093b59a174d271ae9736b6397a4b8c9e4ed085a705a4987bc56dc172caf58e543bb9d151b259e735ca851dbb685d5158596d61a411e7c542a240c4900bceeb6e6aa7acc7db5dbf60c178813051574dcdfaa38d6b8eb595712c8b758f7827a981944f550597d120e926486e623ecd029e92825ebae4b6d049011fa7216dd81c005b376bf6b1171654b5a3ba932bc98111b8213343b9e18c9e7479611606961b476adab27e457225351e2981a4e65b6a7f0b02078505d7d3b7dd671c1bb79610dac7c92518a8b851ea5c3115f5cadad3cb24923baa686542e83482b725474381409a4016e54066c32420e99349d0c5a32ccb0b010983b96f8c657018ac0014a34020888317a13c8296a5fda3937ebc61f2d1022b2b00e7a6341bdc70d1a11b9eb10673c07e612363e6f0413095561dc15c313138efe56c67877c51f216476ab182a233f34801205a9087ba56a938900a0cced6e16462a5bf746ab679aacebed1b1b62b78a1e2aeaaa336f5286a84fa76e1fab798749d8eaa1e71c48ef6a08977235ec54179cebcc349863a9e40b61d68c1ddda72d60b061f0c42e6c179c0228d8722ae90d022d9747ccf9326e4e27bc87257c24892043aba248c1ccb8405a66712779444ee39bf91292b9f926d1c99c65a7941bc7c1378f682f390b855d88273e56fc1067088232f679c5544a03b64cb2a8d9b8319d254c3b19aa6184b1db0529bb9750df0cc6cf5a39b7139383876f633763cd07feb86393f6053a25b043e6b736b0309e7743103f0262133a4b701028db889fedb88b0f5a49d77938c33a5af559468a91e6184bb9ee9bd71d060c6f0b2a2413bba67493fb9a12e7b8c4f35497ec192b4086b4741402e46c97dd85f12d79a9b915160c788bc552a00c8ab88b50506363ff3eab9f84b5aca7460c882015ec08b3b4155621558effa01b4e1c3ffc310a2405dd4d4561e8bce8af738cf65279fd56571bb2a76faa6b1ba9b0b9c7c8e8c9349d504952c8883a4bea1c2c7f0528840119bbff2b2887310a7f1030bcbb0b8002402c2c782c183853658fb374de5ac9bacc24dad86b088daac4b62640fbc5eb9990e089b1f49e95bf3471edfa0521fe910c0da89a1193d2acc253c9aa8ed15bb4bcb16d3c14d262895d594693825ac0ca0567acc11c94a6c27438d6a5403a320b2c4c47400a9817a2296be402dc688957c7494600870e84cbaa433076b201cc64b3a3a51311f7c5a3ab206fa37c0a1c98048271648b5a5384c119dd73ea44370358182c713ab2e399655a171670a5295773d2c36b6e4b934599656c7808f13044084a82666742eb6b605dd2751de5872df234694a84397aaaf3b894e0a7507c3a354dc3409ccba4cb16b5387406bf7d005a17352c4d331b7801596f031a7a15044e1bcc00c4a920a1ff7cc1b904847977261ede038c5c51841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c45c2471ee52019b952bf716a1bb4059549a8c0bba67519ad4f10cfee06bb34496f38f9491c172f2be413da1b0a7de20dcbc1aff4103e546c8fcbb20bdca475c9161dcea2aa3ad534fdf042b2776b04477b14f2c705c85b3a7c5ac3803b3548b132c6af8e90ba88ba49981729a8621f30c2aa0dab04b49bb28abc92d9cc8311faa8dab45d545611a36b86549760cbeb4ad464199a35811a63cfa00a8a1bfc202ba75d73560eadd235c2490c8e514ca29b30ddb0996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553035201e48c406382a842256162b067f887729e298436485f10236f67f96d263c9d0835171dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99393c1c35cba50014163c84977edc8f02ebc9b5ec5045c6b1091ba794303e8bb52c7b8238a635c23d3c13d9e918d29025474098419aada6720c70da55905c197c1114c60054fcc651ab6aa9876430d4d530ec7a7a734189a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a376f022313718aba325ef4c3b720e2c3ab314ace74e983948ba2e43ee3a6ebde0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = b2407a93eab248e03dd8b32b67d192b562144cfc3f6c221a1d79bf545efc25a585332391ea28202105a03af661b765c19b832b48f15b7d94ca69f8f60db0754811c749005ea0af732bb6e2ba28d81c6142b02dc19733a0ac36b775bd617e801ec4f2b2a4efa3779a76ad443f6b3ff9a362a7c08493d33462aad8776c4471bbb79824842b4757a1d884b457fad025bcc3bf29dc5aa61d922f78b128a627d5dd6c84986f2bcd22182c9de1eb77b0b2f7aa81207aa26ea0406bae3a9ad686ededf3fdf43e13eb6086a9e308bd108e05150d66ee98d04e1b549998a148ee54821aa2908ac5b10baea34b2407158313aa3a9dccb1acf1bc5e57292becf2844869e6f83a7b4871078cbe2b8760f0e5ce95fe02e2b2bb71640cc7a8ec7a23fe0d674279e52e4b860136cd359c5d07c2917c1c9ab1a30bd27d0611cc19f5ee7fcbb0b460e98d1ee4f4f69abdac6fc1c10fb43cac153d6585195d0268433430b343e78f7482403cb341d250f741f34508e343d43f233a87127fd6f13272e12a2b73eb390fd0c9500f5d36a5f8caa8e9ea69e13506b2b10d0c3c0c58fbcdad28dc83d806e656925b365c598860f72bf087345731ae2165eb46c0a5d44ac43c9f1745f8c2feb805afccf9b1ad24cad13639b7938097d9314ccb948aa45a8479904dac754fa3f1a24327252724492acc9c3d1b4ef4d4ed1d379495dcd3df5e3e5b8fc4739282622fd2b73c0b459259f9151c33395269713a78b5bb8285b75f33c35edc6857103c2ff5f9148e18faaa8a09b2eeeb2fa73b8ffe180777c69c8f4401cc59478936b279ebfa6432f02c01e01328e36650fb2f54b75a2ea0434ee460ac451bc828dae2681ba390d304c0ff083cc107f9d941279d1cb34a1fd13c7ea98ba108856d4aa22d6552563b05b55742a03b815c8dc04ec503a86a79c20385b472cae9e04e1d288532629048cd844184984fb1538867c14d7006fb11baf5c9630e739210494f6f4b0aaa20ed6adf3111ce159c6ff6d70862824881d29ff6e990bdd18c4caae9189d7fc4c7a32bf0edeb435279fe0b38c1d7f2ab231970a1cdf0364767dc92e730b6d757242d0addcda7e4ac1da31ea5a722be4687ca79637246a6ab01ddc699627939799e4889d078f268b100ac98f3ab248f7ea7e1a2f1cf92f9b107efa0aabc8deb3be2e108d99b5f113eb0430065bbd6c681b3ac9b28808ca224ce44399efc9791e7432ec64848b92ea2406d6dbd8ec60387a0cca37c9789d293efd841ad0c19b0253dc8f27185983219344c0e895b42741995f75e7ed74036024875acd12d1877f658a4cc4d2199bbc7a70c9bd61607ad1aa708a94bbd6132b7063ca77ffcc9ac433426112e960eb210e914f03d8f57c1e014045d9bf9c25cdc399e401c40d23d47e40f5c478a864cafcc3a27d39c927d9b6ae4cbad079bc984343ae0071f1a9123ba2335a02b49d1a51137164d3f8f92b9493d8b64e312f7774543906d5c5f6c545e4ecfc67ced611b01fc2c85fc33dd9eb3c287d196eb9464660c95a3a67cf8bbb3e0d72542836c53c6ed82b4cc0de8efc7689243b5b690bed176634abd962fef5a42df66b87a2ed6eabbdb94dca2298392acb3a1bfdbb6e254f10debaff731ad7990ef1e6702295b4240b625dce707cb27b86a5cfe4407ccb8c27c8deb14a6def5a187ffe1ad23450542775f87e0438ed4dad3eba330bc7d54503a531c668674d52dcc73485f25f9ab79c1ce33ae6b464a719a7bbde4865ac2e5a10dc2fd18b09dd19da0cfc7c46c4b2b7a99de777062e9298d5bd31238a381f8c565a93c5a105cefe6c76354e8231ca91d4b75505367af0b1b7a7a424208bbdf8c468be7c97dd1512e927945c4b3a4f594214b8140d7b1a7566fa0d9514d1b828da6beef5fbdbb1f09a1b759b4ce2ee18a474edd188b889c5a9af2cfa1ceebdbdd83dd5738480954fb4d19afdfa3b31dcd2a85315d6707899889188ef3a392ea331534536f7158950f5cfb79e90a4688bbb3d13adf46ab60e7d996cbdeff1b424eebbf41d35e92eb710b4f92fee4ca8791479c9bdbf8468ece24868c1c875c1e2c76f3ca24d582e93be11e00a7e58377d9b395ce9ba710746fe9eb78ca29de5bf92fa5703fd36d98711a9863b7aa40c0e95d488b6ec72680abaaa17e13b8fbe7dc30888ce5acbee633370ab5546612f4602a4d9242c91714024a98c1c3663d4cdbaa +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4dba785c3f456e16a8eabfdfa7536f1b4555a9c4d3a09738658ae4846e788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c13cf84f848b89585f7699ffd65cb906d39b386ad4d2f5b2154abd1e77ad960eabac83f3788db33d7defad5dba40cd7e8525819593b7d7e69fdea46f150ee38a475e4784af38985501dca6d20bc8dc1c5c784db3380435907eb6e98bfa0e7350f86d8321736083dc54e0253c6e5c5666ddb7e68355d4e98daa753c1acce429b397da773b043459e5aabd093a5b031d502ccfcab36dd41997861286924bada1913d74327e9588dcfe6fb68711c964fd2d393c73b7c967c6042fda3ddeeb2efca3dd76e6d1efc835fa92946a40c4dcff4655301edbd9434f86b3c7a07ad3c6ea37bf623faae2d9a335e34b6d8e6d93cc7edf1fdab723b272c7df494834ccd93bd89ddbc3a9e9dea4be4c585f827a4352ef33026760dc83377329ccc0fe80a66fac50833c0f96ee796cd0ee74b584f693223bf8eefcb446fe9b06154abe1ee0c7bde7ee5f5b5fb3dc64f6d663573b879eba69efbc590e57f1c66ebe388aa2747c519e9af644acd903a801a5c04a7afeac686c89835cf59a791ad5642274a0f88f44491670c66c9bce24ba5cf6b86967aefe77f8dce89740df9045db844dd8d022297cf63dc8eca480906d3a90a840ae7da803e6a0bfb44b396e6816073c5d7ba26a74d4908ea3bad3a0c9dbd672c7466e38824539f98a8cdd82a4d540d3e2f429411c4d3f64f4e9d08fde1f83d26184cee538b27cfb91f26e86dcd3904ba6a34264e55b3cb3157937d66e8568f46f283c7c0e88696324a4fd77c3e6fa5b5ecda13126f74e5792fed69eaba973730a79889ed3bf63934d179143ecf3ed39585e4dc06a99aee0f446301f3b8a6b539dea9e061e7b08338dd6754398e749707efb4d99fca55ae3ecabfdc81ffcf779668809ad6db97a6e9be5ff0a862e664d292c4af559e95a23c19e2b9fcdb9b4a5b9ae517873ccc6449a3e96de6cf716d58d50e7cf11558f45ae6580c980654c8ca68e67122ecb2f8cc6f915f9c9754cf18ddb30943eea1a7b06fdbc8fececf776b0cf3cfeac9f7dc93e97a417edab0cd8f983bf4d2c613e087976eccaac13eb895fdceceb6df045df04ba61ab39cad4c6b2b335d3d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5d4d970c435509ef6cbb5d705c6538696f49d344bdb7d8f0a5c8869b47eb90ee3922a5af390bbb7c8d9c3a2f66541671c75cc2b7b7f48e0f34fdae6da74f65e5d7d257d770d2e9982d6aec6d19bf0ba48b53ab900fd8f80c754c14774939b83c6369fa12f35d1a8e94679942ed2f7b46cc8f354ad547f9f9175c35861d7239aaafca25edf3c835e87d921e5c9b134ca7e28ae8c7656bfd6a4fd253ece1743576e575dbba8905f4cc391d8e3cdcbf0155b5301ae00958aa99a4dbcb473ef65bd5baf55e91a5fc4695ed314bd990ebcf2148cf2823dcf49c8d080841fc8e384e73367c89fa11099f5b8984169468277e4e252457b23a3a1e33a36fef61247fcb2c14d3094da87f96a31913a428cccdd38e7b3847fda4637f46044f2218c28e5f5a57d9c0cd2864fd43aa5caad03a09a35ba786a86fdc9d9971d6258cf3c6695885684d1a5fb2b3818015ae887555fb1997b7a35a326481a56683982fd33a0ca13a844ac70feb16269877af7b2d49458515b3ef0a77f933c9d1fe40622ebc8bb666a1284798055596ade488439150db602a64f8ece3f10983ebee5bb8df6d6ec9eff7a53f994de9e2637bb0b4be98171a89dab7f0bc8efcb598a75b4ab304a9468088a62e0d59dac56e17bc95eeeb6c22db8d8ea3c6f37fa794ed358e193d530f9e2a4582cdc65849cd6652e443115d6868365012c9befc5efd1a844e8d2ea6146f7b4707873dca67ca6cd493a83eab2f7fee44731d24938709680e1879b2b4eb12f7efcfc39cfe9ee8635db6cf4b5796e831a49aca2b9cf9323f8ded15cf2d18f643735ebdb8ab01a6d9ecf95f5d093a147c3caa73946cd38b4f3ed73be7fff958c7445d88ad73a5d343ca768a4ad5bfa49b6b6e17a94d909837e97fa05d8e5d18ebb4e817bdfc3f7cbcd4640416dddfdb92632bfe3e36f283bc32935d4cbfea8f31fd85fb2ff70c834d6b6a5d2a56d98f36d29da3bf14b0961b350facf720ae691dfc4a847b143d9c9a2d2e7a35b6e33dd78b761125bd8c4b1d6994cb8e01186dfabe6270a51cd85b8b39678af4c337bcb4fbbbc0fc260d48aa801f86538eccbd3787a12a09b42e18afa2e8c77bdc11b13b5a8404cdd7b2ce364046ae059a4c950e1e4638ccabc8157b97a238a6fcba379bc6afda874335956d2325376fe1ce4405bee3e37ef818b9826743266c078c01c36fd62b1d17adf33467d9c1ca9f2ca28a2867bf7a8084daaed0a19d2d40a0979198135c229720205763401045879ed65b09825012e626a24118cee00216930d44a9bca32bc74a6683a8d1bae1701b189bcd8feba2da42cc3b572151e7243712789b2801043196bd8c15d972cf7674771dc55e74931fc0a55c434497a517c99ca3276d262ffd83cf66d87600d097b1ab5dd8dca86de94080da8c2aea980b3a1115b847786aa96b94ac818148e3e4c7fec633cbc6bd3104ccb216074a5b2a8c757a455ab38e1333435c3c30d94d8e922e8e77c0260b6128865bc37b82c7a6a276040edadcac335a10b569a2cc53a93b6729728b84b74b01d502b830330000aa1ccc9c4d7e7a74ed218d47ca60016411d7369248a261d6b6240d5b15d2fa5b3229373484c8d23bc8e78830062959d0504c92c0bac310967ec40af0c2902f82742efa78f57b70bcf54a73aa2aa93b0fb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad107711aa1729ccf857a14b0002f61575365f3ad9c18b947bbe9b3e31a7571a918728479710d64dabd569873461e12a9dc1103ba28028e001c8d5a79d24d30756cbb4a3ac9e48435ba09286ae89ac3c841e8909a4d94226a822c90b5a40f239cb0e8b98e86b5b06e20dd3764e42e8c8095052b1f66b76f164b3b867a98cb299e0995d44b5febc7a1f2c0cb2d0cd4f3ac5f9d5444797941666afd319a3c6713ed1e31338a41a6e2b548208cff5671a6fc7ab5df260c2d8a703a67eafa381c9d576c6c2b1177b6a66d951bd3c426fa79cc7b552ece197c92856b2c7064605079404a3b5d8b49afb9c87ea48e0811a61e81e2f101ca25a6a599947341040e381a52cec894dc9b6ad25b79dc903c35c450201071dba35ef8c11e17a1ae5ec7e13468c148a5946d928ed0321d717640e5a5767942ef2275e05e395321052e3e5059af77fb04271c2e511f450be168aba09d3b9eee1288ed1baef69ced005797982316e2c731f9581cd455300f35a6e1a5872552ac6eb68ccacaf636cc713516c275823e4a1a30a722f8c46a8932550db624dbb8b6e0bb51c3d54089fcc2042f38f5cb5988e56a1f42a65d5d788e2551f60487490b57904127433f685ad4bc53d6213cdf52d6b0991ae37882d37b5dc084e5a49bef660a4e8d03e24ac93e58bc05f8a759895074e156c09e73e6782c00a6cc80cd04829d270c7848d89bb2c321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a08314b29c81e31b63a008a51d283bc217adefe37d2d9b15c7257cf62a68751c2942c531bb55abfa321c581822c90c243d94b598fbb958e5950fd4c8b1f1cd06bacc30828fbf73a83f7387ca252e4f9805419c02d63189ee7b4661b5c1bd398ec82cc8da173ede64a38b3c1ed53a64db130564d2a54600bac8017d46507b3d56208975a70351a558d5774b249f7d634e6f21102310b6bf8c1544e217c68768400c3d721ba5c0f77b9d20795c8059145956ac7b7728222853a3c325d070a9eb256775c727118eb9cb7134748ccfd09f32c930881826d8e20af48b2e1ba10efc67ce0ee7730093a7305403eec951f59044a5f7317cb85caaaa2e2b5b90ab2b805a808c1be755f9a4c342a96e8ae83cc4394d73890f13bba0d35c45393730e4118d5345006ae62d38445666cbb7c25823c59a9d62e08bb8c7cd22b331be153af7c359091081fac67d96384100f44951422e83599763ab739fbb8ba2a064a41cbe1679a1c613815e9a51d5d6251ee73431cbad479cadeb64ac94f92a38d0798a4b6d3ef7233572b68d2a12d125a6d4e27939f341a4810f0c07bfaf993f8a74bf8e9710e7b29389ec3dfc498a4ff1839a1268db8b70e82670e689b5b3e333908b6e8b4a78fec249e798bf57b7ce985a42a5269435c81ba441230ea52319550476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd7944e5d79dabf7b7259df5ced02669c81b7dc4590e0b10764729d812f6bd85d74f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = c1a2cadd831afadab4b54857c7e1eab27eb6c7538d5d78622985384a68ff6d1bc4e8a792306ca33d26f5b26064703cad77063ffb3e55f9e1490397b7419c5906069f2551c993b0b7c913af47ed040735f45ea5a179a29bed28bd9bbd06ef9de5f8bba3cdd1470f533f69cbcf5cc473307862a5185ee4bdd08863032f6c38659980c11b05150311ce50e5dbec0e779142930d87b3ab966156f7f003c3ed6180a08be3bb52f9ea2e11008beae0502fd3c76d44b19cf1c1dceb7b076756485d446142ddd0ce1c6e5006ecd91214a6b735b2691ec0641625dd8d530f97ff0cc5134d59d17fcf612048af71e8f9544eff4e81281e100607f520bb7c7c6ccdbcf2bf68b1b406cffc7ecbc8d41e965d433314ab1e68df9620f5eb90a5eb73f00fb516185c8493d9b98cafbd6267c3f1ff25d5e03c41d0a862b37faa8fc3efd0fe2a979c7d2b4ef86e5f9e93ed1bf31f237db36bef649a4257e893e14ebdf6d1407488a2a80818a450316691641358438fef5e094b2469e0ebe4fb9bf4f503ac5b161ccab279d9535cea2e239475354019dff1a3c2274dc6d94eb9182de07e12d00ba1fee95ee31203d35536281279d9f7d0929fe5c7679ad8131c0036f5a7a9813c78186594d5ec9b2a0c1f8e5cb531c822cd2f4ba099991b910f95405c964bcd3779e23211148ed68cfba4851ed5fa80d601488c2a0611bb5a8ac49912a5fa6f250d360404ff5f3421504442fea844b90b9cf9f2269d210b33b72d31d2f163b3399477fa2c04a6d4ac0b57d9e7a964c3eb96155de04361c4fb6819a9c5c9073f47cbba4039779af6635ce90e8d5f5635e4391709bb13a57c5887bde69b34de173d14f52a70a9ea53e8ccf659a3c4af4b867a9127d0d84644259413fddb18875302bd9a99e195760724b3e06f6f17ffa1fb13b90cac5aab72abc5b1999bcc8004f6f9a29fe8dabcfeb6083c1e5c87d7eca5b9595d5d725889858c173a13ee943ca2666475aa7b90e043ede6792e56ffae6081e6fdcd10100440dbe8a3b3f7ebf6f531074e870d7c57b92621c02d8892e8b1c29880b822e6ca8904ac37efbe11995dc3865a5e443805f4429a972f1cd6cb8bacdd119f6fb2fe891939e4ffc4014f3bb5a083f6fa26b8b6c17b064f5f19fad8e4260ef2ee8d0f1c2b20a01aa53b245521a84b2ea891af2fb004ea5625c5b59ab515aa162fb0c512bd61fa485016906fafa77bd86c6cc46fe96448a8208ac5146ad32b14e3cb0b41209e9702276ddac1e5a261b9d1ee756d55d9eeacbba104c93f80f36f1adf279fc6cd73744421298ae6b7a5fe33e025fe3c83c72d21fa86fc6c2f1366582bddad8544f886ab61a8233877a342a033c8c16fc49aa721f5a9de13b139cbe37a1ae746df5dbd6963a844bb729f051ca000d101aee39d85177a3c708577c4743fcb250915006a7324024cbffd4342d7f4364851845723f16b5d87ff778f814fb1913996dfd1dd32364b2f9a4f025bdd5dde20251324f2edc9fd385d3f84ae4f071f866157d218ff48814ddf81100c59a018239365b22e267195363aa3548299a0aff4dc9febd6e5e9f59b24fb7767710591ffddfdc56f48dd07678152bd22440d6ae864bfd46da4299c1bdd22c5d87814982e9cc451c0bcafdc686c0424a84b012d75f27f7687195e8c934f7a6233fbd06a519c045d13eefbab26b414098bb384b5858d122f9235da4f21cd980b4ec1399f15643132ad31531134720ef8c0268a325b23d8d0c2a3c875e7bd817037013aab674e29efb2af86c3185b8eedb4fa1c89e5fd89fadcfd43a37f3e2517e978c522d4bec552fe22adf37c3df8aff7fc611e00494bb36bdd24fd4c508f30c097d6de9cc3f786b3f17db1ac06715ccab38b8825628b677aec1ad3ed8533eea31db6ca47fd6fab9f0f0a3c668b402b9099618f388a326746a4dcdde06d3f51f1106e805b6b0177c8883ece5530a52275c44c1ef25860053b6dfea49287c9ac4c94db1298cc1c782bdd5781bc62bc49490bbe130a60dc47779e8fa16b66b61a56577186e6395418c73a0d44ad453c1c96949818db8d2145d4f5e9621037f06093c3f932d3c5060835813c5682a3ca81c3513f3533673881de9973442818ea1a2407b67ab76b3472d54a99fc35c9dfc1bd50fe38ac3970d73aec2582220a658c71be9424d0f37ca2ac17674298651160b0f839ef7dc42db08692183b5fa10b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ed55584416844e1cb3c75acfb387e014deaaf1fb3ca8a5b718a8ce03ae5ae26bacc7534f8b084a666bd60888de533ae61686b07faa83884c6a0efb490a8a3fcabb50aeefef58ac43ef4355247bea661c593766ffa6067e7aa66978e4b36fae431ee4ee4f4f82d50d3d5bccd6cdf7af225b6560c44f44af78677abba8c6b7984eb3ce8cdd0769ab407c9b3acd32f0f4fd1866ade03ee5e2f3336384c61ce9319cd9fac145db264cbc4059b9447f631d8f41ca376aa6f76111537019dded1356d19e6f8f200dcdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc95771637356da7aa4e51cc548f0c78aa5b3f3582ce92d00b4d972e9807ad4b1a0ac82a1dfb7fcbc8cbf8a8e3abafd3ecf165dd3a25ce9d50133e967c7668aa8b81977b410d67fbdfca802a76716b95e4df8be66d3e4977c33d3ba5df2446f62658274646422d4eda8ff86b58567cbef9bfcdcd6f1644c413fede6f39309aaa259a3d998beecc535f17d773ab1c5350e3c82d7dd175269700a56b0e5fe1de0fc13d4bc7c64f38f50e634427d2614aede34ba9b0c4fef1af9300098667f8d03588577e64b031139dd228ddb113623fc4b74e946eef86a1a6bb52764c6c13aee765e37a6864d0888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2f8e8ae3b748005d1fb6bb03be5d019c33bd38bd60ccfc45e9af268de8928cdaf66076619889ff7be769fe59e5f23ef5ff4ddb38e5bb6886b7bca9da659935db493ded9a808157e425eb04c153e673333424b7aa939559e4ca973f7644b8e3b8dacedb8c87cac6365c1fdd8e329403c69490976cd400d6f3148e14a6b3e6b3c4f054451e5bbcb7d33ff286afef63dfb8184d0546eff8e4b33fda87ea71d42d1f9736ed58e9047c8744735a728b636dba7abc33b2eedb1573af8b24cf5a8668cf09f91990a499bc8935f955e1dfd301a65be870b7f02fd609929f431f3436aa5aa6564c468aced2f1e540365e38d9eba6f0e82b6daba0e8ae77f03f1c7bd4977d47da0e5e672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca6118a3d4456d495d8a46b35ff01886cb52e38d92df5d7fb8f6239d628e9e323edfa51f8c7a33487232f4934143e176a9d2848e751d8594fd94910ef4e15389c5736fba58aff0567a7b5c4f441a74efd673dd7ccd6802878c76bb9ea576965ee45acc9dba54aad1b6e873a1d8c74176f068bee6e64c8897e8320427dc9cff676e06dd20f3450804c7a1c8d725eae7f9ebe8f715b7894ccbb543f1d00e755d168d19a96356fcd7efd6fd9a8c3a8f0be6500433f925e37ad4fa474b8e44ff83bebfb46ce6fd509a5aee8cbe23b74cd58d79d92f93bfc9cd941f89a0baf7d8a930bfcfd00adcf019e3cce107a18e9c4408d5e6fcee9e45459ed87f31851b88b6b73156ec820a5cd9717fc2fe6ec83d23413ae5e0662894dafbf38aafe38fa8e8514fb53a637aefa83379cdf6fa7bc3155e6b25d343f1edaa787fcd2eaf7f8b39a8becb44923792a7d586632bfab963ae537768e45961f5f96cb433f0e75738a974e68ba4d3d5b3591ac5679b6e857d8e8b2a486bb2a9d19c8bd3bec5dd2e4da17e84712abcd1895ac6f74cde571b77a07ec4691ca51569fbf637da32c58eb9a494c1a6bee0d8658113521654ea8397b5be554c0003421737f8f4dcb505beee7f594d791ec21b7a477f35f6d827d17e5c87c6b376d95c8c6ac6f8110762556e88f306d3359a85b52faacba4802417ba44b98fc0ed5121dcfc595e5cf2f397950d78506e52926afd53dd7d15a69a3f2f3febb9dca1b3a11294729a1f3912b54321344ca50dcfbd996d523b72a505a8f0945e00a650260e5c3f9c7132d48baf5ef9a1fdc4e23ae509c439c11ea2e1cbada30453f72eddee9c7f4b0866ab9fcf5b3e667ce38f8d97ef9a0fbd5e3afb7bfd30367a6306d4c48387b694c7bb2169614a746fa783619f9c7264e3ffeda59ec47d63d20eed705e83f0e9be5a493e5dbe99359be9f27d6d80844ff2968e96af4d72dbc348a88d0ec9bbd01c3018b8e4739eb34fdfe2913ee304da40c46632b45f810f1afd73046417885cee1cf31a495b7db834a1336981ffb34dfe40c84ac878c558cd937b7e0a9982f99b3c8abddd54eb7906f2764ac38eb8491c75171340b7774793b7912bb4186a7e3837e33414af6aa211061f3831c4f4b16b753228e998a721385d7b14211d8a7096c54ac3101dda7668013cc1555163f822b1cc144e240c284dc87b5075a813872511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e39298872552f8bc4b0df1632255588ee99b4bd373a21c665574bcd3fbb35690237a6cc691f80523390485447be94b76fc219e7d75c6649ccbeb00271fdc1d666351f396c08eac20ecfa784d45bd4d64847ea126d9f0a23a3b1727396f299951f95a68efe55c5d4c792e136148aa35d0663d64f2c040586e44b6cdf60c54e0c08f365001513694e27569a3d6c6ed2538937a7afaa0bc2ceb6b18914ac77c65922ac49e47c74447b889a39344db09dcf1bd73ec5c48263c214a1e946b2cb806668a32b83c0c97ad547989836a53f1025348ac068a69357c7f46c69f963c5634908b9963bdea79689b9679223824faaa920439356c10786a646472372be8729c4f2ba1e2897728cbab136757ac5a75242608d6d10e20aa6446a4800eeb621ea822c1a61eb7c5b84e764d83452f60e5bbe79b275c4a4445715d21ecae5a569073475a74ba62383137974bc071c27cceb5bdcb1991d393784ea8b28f259b118089b4b77f9b68ab0ca953ff8257a3938482313f4c5963c4b101eb0321d608c2f3127cf451764e15636eeba98021c963f359d2c44a9e92357f2853821ba0c8105c488b242d9c02ae637b2002ce644132069a8babe23d4e9a056fa0b8be8095113b86e6b5c748706924f6aec490a46dd398444499b95289f13a84868188fcebb861a004254068f6d9b4b83aa81c9b5433c70868ab5364a80d870b841a216506663aae569b025c5cc43b2e5a6821fc300eb6574d0088bbfb7483959892703666da17797dba514a489376b19707a144b6f80423073efc608347ba2e639b0c8f2a52ac959592b0b0c1a5b4fba61483f225344051dcfc4ec124a9d10cc2c557339325c699f091319853ef7a445b4064d8e66895f8c0bc887786f5240b72c319fc0b55933b5864063d14c5f732472c71340ea26bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa110e2cfa9ea61287716f199af376b106fb097760b3f11237fced41eb95b798f2787b3039f9c213ca5699aabfb03af86adf5d52d6aaa1ea952bc04725a22b2a28f4006cac30e265c793018145573cd1c715a69d704217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbecbf25804a210daac80612972acf605e91303a2d59b1ac84ee217872bab85cddba9c6d1381e312b4c574097d95b8afb595bd91c46fc0df0a761f596569f99b7bc6505e922a1f90c045493cdfb9a3c650224bdcc26ca199849128945ca5f97e230d601283aba102a26818932004bb114879139ebd637ea035c20c3ae176b70999c3ffcb7951742c73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab4d07bd6921cbd95c18ac60e7ed35aaa352e143aa1fc49630cfc8a09845cffe260ad953b71074e42f08e265b7473db4d178c269f317ac035cc1124540a4a47886b6e5b04418a760777e73aacf8930f08c2ff10815559c1e04672bf4b851233011d7b3a84155d76279f9778a72ac9803d36506824a34524c835222224545deae1aaaf193b778751889957d5082a9e9a34e6e44840cb7ddd712ce9313c5033590e9ab54c25852aa8b2f09252bed793bf6b972b593ca9317ba278937a607c6b9b8f79069fbe452fddf01622465006373e2f661e366a90ad1483fdf76e04c388d61646f0162195d36966d75dcc89a3d96b2f98c79d9e0babd9816aa2084611ebb558735c076576e102b3857c1eb2876d53c5777f146876e55020641072010e7a1b773d357d81b52b4071b9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e768295192ac02bbc0acb70de25a27b724ae7d3121b1a4a869034e70f279c3914d882422e1785709599df782bae64316aca97d42846a52d03eaf423e813cbb3fc26c0e1134ddfaaa3275226f6416d9788ba2026c78e2bb1850c681825774213628a23494db886aa29892ec194791a84c73b36fd5cbb2b4bdd3d664ab10246cbc9bbdc97d8ea5528ca41924e240e544a747071caca25b05051587173c9fc851edf10fd0171c69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c692176b38737a053dce0551b63e3eca81884bbf95e1d8975671a2f7f1dfae2511c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 570b448d4f9e17ac98bf61e3947f0006e0530ed08513ffcc4a272c08f665e408e75ddac360496d3fb2d18820817c42db871efb3a0219503ca91feb86d681d331df81b488f55e1d8f2a0b8c81e7ee6f49817db829131227e2b3fc7f776e4857ffa2ff4c6b349563c4a478bbf4078a01c2e4ff8d6b55f8dbfd787cdb94b1dcc9139399cf0d91657678d74599426057f8f05dde9b5a4e2366362c6fc0ba11140e8962f2ccda15133b8acea41ad23e155579c43062ead9fcbf512e4af35882a359a9a3a2520e192ece2f253c79ff16b51dc8b0d835f10db442700b1914bed638aae549be39a8a7f6e165bc8992b253848e36924943abab0d416569126b478965fb1601f0b5bccf17a58b8b934494fa39d4f98dac08c0d500a67ea8bedc71fcdc55bbd05724c89df1a6e4f8ee235c17ec1e3c13d742aa58bace2cad2f905740ad852d1b2ec0b891ea9cbaf446668a1aba50b162368c4289278a7bb681deb4ecb093d31db7d1f9388deea21d9771bcf7d0a22716fe1b3088c5c8c812416d428c14c79865746f67182c4ea08dbb89f739814e80b373a518a8f1552bce620aac42ee35d70d8571969315ded3a2208aab7f719fa46d01b73d92ca1fcd7d34105651a7084a5c62892aa322cebdad8c69a200ae9287772a83b9d33e7e059549de6a45b08319bfde2bdc5f80594e18d8a3351ff0f1adc88859f796eedbf58cb2e5603494ae61cd23028a21e00ff0a58b3fb4715dbd56bde04e90232d421678dc3c4e0eec2b2abd451f3826987c302731e3181764c2dc413e2eda47a51965e7810d7569a66ea1f41d494ae02834081cbc46b854517125dff564ce5e4bf9c849190c3fd986ce05a09c8f1c746e557be72a7626dbe01a964a136a2f529454284ff615065c853b591960e71c293e376ee1aa16081251007b95f5d02d92715d4cf6cc07174f94d8b6b02ddbe02a0b0ef15e32a6d008f1335115632f1dbd70502bf0c0bdb9639a79b37db9177cd0336a46ad841c951b11a2ce05bbd7a85a6e7932b629cffd002e93033701c5449eadf68e722470de90615b33ef965d3b04f163b2783d38a96cbf2d4abec8e628f8b4c1fa11ba849941fd7b663e38675e88d5f9d130527d62509c6e488d463c5a0e522156d08e93ddd50ded499295e5c5803aee6e33b0f51754a5c2154fa6d806d6645a003ab09bf716472fa935ae260a23c19563c8f749705f68b987b8d8e323bb3fef9b7028740730df332740d6632d6149703d4cb74940d05b7588805e2c501d1f7e2d16ef5d0f41adf1ee368b3b678b282f592a4b8f02881861279a0f347ebe24b3a8c656545aeb38c16cf0f37ab103bdcb4d81b621cca4b461c8020cecd65ba79de82600230338b8bde69d5d4d3c79c6094535f5afb70736f2267227be333236ad70b4dc4ca92f99e0fcbdc7d53b79b94e8ad9a80f06feb965c0164e2a254503a66eb52bc8115e95a2f9975edfbcf0f8ca8942c5b4b74a90d4b64e9cf6de899d6397be16962175b0e0bf790de9baf06b9257cbfd8bd47dfc75ac68d6096b121b7519ca7b615a7ecbbad61c5894632c719c01e3d325c71fe097fefebfe9a734ee844ffe847ef7c85a3478978e4274b402f612515021d30e5a940dec1af24f52cdd7c22ed40a439f47aaefc6f77bdf124ea4a8e5a6d1a708195ecabddfedd7447eb82774cf231958b11fb6d152a560c78238c94b383c069805a93d6abe39533a26a7f2c44b0fc46e552a1f104f4c4a7e0273e5354500d797285659bbb9faa3cec81cc9ed64ab954ae6ca8c18bfb1655ae14c682059f637ed6b6355940f224a3b01a60cd28f03378d3268b9fb3dd335911569308fdb9267e3e5e1399218e2d691620948833741fb3480114f8a2cdd738d3d313644dd11e9930835f5e84a42aa2aed8ba4b852c56724a0986c319458ebd36d97b80ef8cf15571374bfc0524773f40e69d38cb56744099863c2c2da9d85092a343f60b27c725891b8492e0a85e5755c1241f27a93aeb48699543abb24585512628e70921de558bb1bc88c5616153d949acc31a7d3280f2dad7fd800504431d7e24b6491499f0e67c947cfbc362dc2fd4a16367e53319738b39f169c6f04e464c014800307eed443f83ed044b308ecd34433d29d012bc09632472563103c09c1920a5d5b5837baf5da6737a95ad26d7cf5c16d7525d6e7b3c1fd41e383827034df3550af31add3e8795c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ffd8874d8b37c946409d69cb045f9b7d1a43debf4792d4773cd7f3643567671b8e10cfb903e3d2679a530118ac454bd542af389c46b3903e7b4323d97237ed8146a66593b8fe659db67dc942feabb5ff954a3d85a95f77062c3d4ebe68e476d15eb5d6b5b8a805a435ef78e2a6b68afa93727777e7c114fe24e7a10a94f182e7c40c4cc547b98fe007a1d998d4ac5bc3c31b65124f5a558c73e6be935c7a664ffff4955b6d67ca54d48bd4e27ff717af7b220efb2fbf7c17df6a541cb0c1ba5a1a96f9b80ff32b84cdfed9cb6f666b41d9ffd1bd74f42b5d2ef7fe8c5443f34c5dc3afdda165558bfd74e3ccae85cecbf107d725eea3a30a7db045a2c4a79bb1a4b0f11e87bbd8b29a8c60b17d68a82f64d9c3d5b5e391521bb945d53ce1d6543654e932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542ce6f6637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356147cd4bb849e197d54d105fd2f26d824eaddb27b36bf8abc7876ca332cfc3a9ae61d995f3ad0ceff9d538ca2d3a6729cfd06d89f7e7ff57093ea3a34113749f23fcf1c15eab2c83667acdf10a549f2678c7187691de949995af5769d4647fd992bf5eee24f3d2c07569cf26c11f3942cb5d5391a794d42c77da0a324b05908aeb9c70b88b38a95f372be903ed6d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab96787d466ad56de9c442076fc046aa8cb4fd93bef3abe8d406ff6dbddde725daab0e50931c575a0c9137fa61442b22deb05686d398a6fdc0bbbbb25a073e99c380fb9268ca9152da1198b5c556dea03c878b78f7e6d586ab43cffa57f58d1255711654968fc80e1364887fe8e980ce1eb85645b399788ecf25b2af33fe564604a86397a4484ded2213e88df667961bac9ef19b9953f475c1afc9978c81cf5314a3bfab3747954abe4c8e7ded9fdc6625938ca4a92bee5a7aaebf86f5d7ee899d772c3353e35c2de8696041bcc8c8e997f8c78014e7c91d3fe9b8b34b63af5e6cfaf2854cf912f69c3c5b50b6fd9dc1c63f8835b3a83e37d855c69f9335fc66efb985933f4a66b084aa599d9e658998a15ae8b087120f59a014f6cf9b3f7dd48467f9ce2cfbaacea7bca7417d60d4f950cf9543cbceedfacf96d978a2c36aad92b665d6c9513b59278bcecc89ef04e555e2708ef976a74d3055a4803520357f960e596c7c4c2d0158a006d88504d681c76e0f21f4574eb9ff63f3e1058dd0f3d6f1e398ad1e6cf8067d24d17fdef57e9e3a6be9aeaa07b66d77be495a635c67066a2945376c9836ebf4c413a05a9b1348c323f9884bc7d820a6bad7a63be6f518878a97fc5f5332433573973df74a00fddfd50198a2b23d6005335e6b5e1925d5fb244999cc333bcfa4e7845b767bd50cf66607a9fd14d28548a4454f87ad6ea4fec8288e478cb938d7d9ec5cc81ea1a9269543dc8ebc6d253be1698990d8ec587e7f63e7445baf53317cf3eb8863d151a4e5659928ae7d4c1c7b2bd3ae9889d7a05ccbd2f0c78233ae0653452e3dabb7598ca83d3716689eef12af524f371180984c07fa6e239e3026d6b745ea285aea66876d4506d88bbaef17305bcf24c759bc348e763f5aa7cb4c6c4e077979a2c0fb137966016868a67be780bb9dbc8dd89b97c6bae2963a2ea3bc217fea194eda115b83139401aa4e6db7c87233d6d3b8ebfb5decb5d964f04534f7f79c6de1789cd6767e1f6930c88b69b168cc6574e84c9c283ff57d33ddbe0874393fefc57e6c989d8320b2ce135f88c97e8f4ebd8f478cb4962ea409dfab7b62ce092be5073ce8bc46838dba3c1f6bad0eba64545aba2d0ac9f44d3a2de976f62b8aba4396107fd31add4d20d46c78d94350ecdceb844af1bac32d2cf7cd3e93c6d279cfd4cdd20255b901e533dd387207c8a8a4c8fd51472ff2e350f274a375a81aca592ad55d091bbd7facc360f5f8f7a6a6e41265d4505e4a36d605a2595a22c3ab5e83970ad33dd443da518c44a86921815fa40ed6a2055eee4aca7928c521df980d74bfb753eba37f485fc29b2975cede5bb80d417d8c5f869cefb8d24a56c72cad48a2d78a963753d1d5f088c8c327cef82b3b246a75397d4743525efd314b9e5284385e9a58ffc4aacb3c476327b705515c6f1980b53b3654720296742b3a793258138d86728f4846ff1030f6f604d092847f011cd59165b9dcb400a8723ab79bd137566d709a5a7f62cc7a7948331920f75530c915b1bb086e422145dd74ea1b557f68b511ff8a1ec0a39845c0aa94c2bc05922e3cc52c7f59eabcac2d36b5535eb0d7737768d6322023a2ed2fb0128c2724442c794d794f302b89fe8b1a3e8326253362fc44bce193fe7725d1864acb29bcaf2c0bab9423dc593733bd99c077534cdda88f4bc2fd846b810ba71d2139fe1f50ace7821fcc5c9ad7c20baa4a430b8085441cdabf16251f8b686359c755981ec4c8fc834cf7f019e599051afa87584f2c41ce13aa9babab5aa20204974a10bc36d4aa1c7706a3838b8dfccb1fe16038d78aa78eb3594998a20c72337405e2f36683a01b87199764b533077688a9a755c2c38632cfa4c2047663e860a2998937703ba0f1780ff367918eb208b917cbd340b69577806e282401767c258b38b0c6b21a057f42b59a6dcb2eab48063116fd2b1ab64c0a864326e8683cb63e053fc03a5f6d6b58f0820f500ab1d78504dd80991e68fa6f91658fbc64c594d32a507be17b465684df8e65bd5745fa8d6512d382785ecb9b207746686aab683b0cfac43d07a0113317cc895a513776611b981f05bbf7e1bbf867923992441176135b394c6dedc8d64ea47971994cfb46bb7692f47e1b372994f3ef19a282799ca530ac7b82fca207537865ee0f4c73b0a0a84e1b2d2b058175780a287ba9a435a0fdc24fdf48ef579b55ce1b55531019060193fc5cbf013a8bf521c1f459afb125c78d2377722824736ce01901a16a54652d064e9058f918b5552936dbc77136b009b2108862f962244597386a2b078c6b46308436144b75b9926133a46ce1c44ca7b5f52a678463191d51953a516a1c937101fd236c962a8dcbb671bb1be92035910eb0b40d8672317aaabcb04bd8b716f104c3eb49c1e5bcba7e17d15861671950056e5278b845afd6cbcce9b2119d86fa1fa067f1c69bfcc7e693020cce979869588337aadd7d6ac7ac3ac67a3034a035a12750dc30c99c8692b9cd74ee2918a23248a3a6875e25bbce8c6902cfc81ae878fa4ba1df57523d3013fa79a9ab08894004042cfc00b0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b04034791ce31490459733ff1c7752864389ce3bcb826608f966342147d6a3626c4ab842480b571a9487bd8785c37a7ed10c8cada99aad1a19b144accc2be8a17be87111093189efc951d08799b5dc46e46e571b370b74e881326da687ea02e1088c400067ee3d885c0db3fbcb336416c74398132090971e2aa1fa9f6ca7ad186bd4c139be57665595337687742b1aec0da12922783c6aba7fed24d18d142392b26b3650731c07a15a987455986252b8234123e3a4a54c08b599f1948d1383183992e2cd17d3312cd9b3cb4149ac98ebc054f17cc516c67d8b26517316143c6640eab5134f41d6987c25454ca62070c985b2e0eeb24e05870667627ce5282f95635be4034d90232e997c18409b1d4991b7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54b9328cc492842238ccb6b652da6c037ac6afdae2be4b894dd66a70b5840f20fc18bbaac111486b9558137269732f2924ee050242329c0d1583bf890847b30d5921198814420b60475ce0047d973269424c54bc9e3b4c94633c1418db9a03a62f6cc224c59074809b9e023a5aca5757d3a789062bc3067698a5f216fb2c7355609a99aacb81b99087a087ed64cbc462301754931048999a2b9b0e06c9f251bc41b39092201ca3a727b5e498e4db782dd53846c7635ac12f6e89c30480bac297188338a58f338d6b7075003278cce876bbe18cdb00326e44745a4009209b04fa53ca742438336ac4f9cc337b1636898170a1d97c58661415dba67935162636a87f01bb87b66865d415360220edf89d0514663dd73a951070f68653b9c2b637259a395c500565b6b5a05b3f6555fb249946c9904ab40256d63b1d6c2344f80dbaa5b1be7b10299a7ddad03781983f8eccace5c85f3c3bb3a9d61c040141757a2e881c33a9784e48293374ca497cb59e12c07a4b6b420d3094400b24cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff2f54bedb19919171eca777186dd743b11ec9489aea09534c157faa75adf1c77c6590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 1c0150bd0c1a224e1de7d1c477f59517a9b46c570cacd48f189be2ee6ca1df6e5db2b93284f1100b3ddd47edbc5d29a8ce6e27e45d6bb7a58b4b0680b3fd9356b59d667bd9818a640735b7590fe7a99f1513d1c4637c6b5bc8e8128ca3101fbb5c71c6c50bdb475aa67f9c7e269580f41cbc0ab7dad00b9e36799827f13fd6e9f094f1e1c0ebf256cd5a56e60132796a05a4f7c2d2e6eadd842eb313933620e37108ea7c796e2ba2478d0d78ccdc66a09d14b7724f906bf4d57c919503faa5897eb33b0942366c3bdb45c3f9cef5e24454d66772778636f5261039abed24164fc831b7f0f4188b0bd392b2da8626c27d5c64c9167f86e9c20dd25b0b7315438607d7b66c27c3008bff089ae46a0b0aefaa71de7d0be42aff014179b998f6ddcba8e22294a33a535a6fb7719683af3fba951fa49351b641bdee63dd5b20d49e62f0f004a57220cd2701a6e489273dd5d1a37b35c5c6a2b86017655f0dbe5018319ce462a37aa9b6a068ccd5835261d33c195d6d98346b3dd49c14e70911a1ed705bb9d82c47f3bd2aaa5918b080ce8217dee1059c2bf0b81be3d1ad8969e1a15365f1803d56da5c60e6d227591547e1b7dfd60bb9cb3b32edbf8e7cebccbdd1c0964c88cf0ab5708b1670836fca72d4c457dde2a7d664bec8861b773805929b4e382256a615fcf693ba29e85f0fbd683b6d0a0a4af98e781ee946d430ddce6cfd62f23ff3d24af0e7c1e763b6f99233c8c80917a0e2b7afdedbd1cce32a1a8c959d47aaf7d1f92ea8559e0ecd2629cbf84844183484e46f386d4aaca70e276b1b4cb8703a6bb049c04120d129ce0b2de3914b3f50815b75ea850a54e14f8d9c8a8276a6ab50a2516f4b9487d2b91ef0234a269f78a8087568dc8f6b4320c7702370c6fb134ebc62f90328970d17b600688333a448e8cee00c998c23916f0f6063745639d330d496707caa9417d47a6731f4108b29ce419831a8d16783805841519b25a4c61d9696d4619dad0cc1ad3ec4e09b672ac2d68232ac9c768d5c0aa75de10031ae9e6a62d29e376afe2bf765213da0b4555e1b8969ba3eb37855cbd5251ad39f75601ff3dfe2bdb94f30f7ae51441bf8f39a32a3c1f173e3058068d8e83c0d1b3cc7835186d65f8383decfe3f11d9a4ed646e5b727ce18daedf4265f0dab11946a926a181b249cefd8aac2cd72f0c249108fdb3cca073b66ea1fd51cdd18e1175165ee41c3b51c8660495997442e74c782c95c464475ed6d7a3925fd15a6a0a623a93df1d57f4ce760de84c24e5ee00dba9f7df5a043fd6b2510c84b9653c278a5f8572583d4dc979a82a13517f1eebc4a00b3d7d4ff0f6b351bece612613dc4113c63786a995f27c13d0a9f997300bf5627e69428f2cda6771372b4f5a4108b282a5eac59422d9e25dee919d16524b9517d0a0ddc6732ccbf5c37b8dc372e0c295408e1592fa532f7fecb9c2ba2287e9825570c58322f5d8cfbcb708b504aac591e965948330c5fed5f5f9ca20f8c2ba1d813d4458b0d69e63e47ffc0ed13ce35b0ea48f2be3c1eae7721af145e451d1d7411f72fd237362500ba3f0d9b6c00762c58d37a5304f463e645418f83b0beec4a4fcbf03a6ea2306cd527268584173120e24f326e475abd09c78742c45b92eda33c239af4d635f2104510176cda3cf531b0bdc7e30b946b1349b123e03243fc1d19072ccfd3cb64fe0c25460be6bd4b2417cfa6292186e4eb8b9ecf7b534609539b29ad9c7b64e78f682822a03a16f5cdcba6b66a113fb8d4f092dd9136cafd896d2f2a87eaa0b351319ccb496edb346f885e3023ce6e1383d2009097b00a191b08ce3f317df080dff716554b4d5a91777cd3f41ce42c83b5c70a100f13c12e66bbce5a9164635020a4b0135d1ba08b45868f1cbaea1a5fc67acf36225bb09ae64e5a14b6fc827618cea4a805a2e7c30d9e20fff347370290b182a26440634c8941d67ddd7811f193684b330d961d0a336023bce514dfc912d6b7606d667f9bb17d055984f00ec2cfd675bf6fcb32f0be073d274e9d56aa3076d0c92bd8078220a2402dcd1dc51e10536e2e7fdcbff960ab06650634a1185d336bb9498213a144efeea84e9d8674b517753176075d48536dff17defcdc6e6a73386f30e77b5e8de17c0ccdb10bfe0868c50839575d5f7a33ac45d4a638ccd2260eaed4362ad7f63cd8967f3a91ed17393273 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d32cbc1116ac892e9f9bffc33beb59bb94b372f97815278f0fbbfc690c94b90fdadd1575bd8cdbc7f48aa133bfa068cf1bfe612c43f5b9dd8963bbc66d938f46843fef4f4357e535c2259ed958a75cb6f03296e90be53a9b46373f8b41cb38c1cbefbcb91898669a872f1a8d9defe227f4fed65556930fcc6b494cc6a6bdb08731cdf4e7f48b86554ccaf953b8fc7daec737d8561dcdbaa7cd2a0ba8549f888643ffb1e3a419c49b34ec90fe3eb71635facce7a79d05cc04074d69ab3cca8d910236ea229ea08633edc70aa583e86912e5beb3cea22e94ef39db531d6cf6cc333835bfd480d6b1cdfe9a664e49045791d33b414696375dc3c7b0644626e8822c63f5d52ba765ff361d853d2454e6cb9a5bc064de1238ccb53438c91ae96a45571f743895fd60f613efd623abebb4afea15e90dd9452ca8e352a78e09579f06ef4db2033aac0be1d9335986e8542d9480bf66d3faa3fd2d0878c3753e6524a80a3f4ad7fe69d7fb6d9d0f64423a632996abf297707d94e2a6b86160b69981ee8add1c372faa406f64dc00fdda75c354491e759c3b5026e6c1920fb7160883ee1dfde68d7b59339350bde559c4a79033dee94cf15bd75a001f7d0f27db4feb7aef6bd07aca616e6881610cd1cb037c833fcf2dca56a00ea2e1ecfaf7ecb6121e81f2ebcb1eff7c6ea84251d8a2b6b6582e09e6e2b8c7f8fb6be8844478fc570c8d54a067b3422db47fc6ac691f5cca95e4db4540b7796ca0dd5523f7d14db34b8ec94d5eb66c9f5cae2f838192eff34f43c7236fa18deba17ab495b8fd529d89b8e1f4d7bd6ae85ebaf445efdc6c9566526b8708be3bb0cc8d9589773dc9d952a5cd78e43bdc68cfa55ded7a1f618f456eb4f97ac1b49ab948592986f33fa6fb19165320de672bb69be42da2985b38b90f79572488c5f86bf3d55fb9fb90449b66fc874b9439f000466786fb7e393765c7057051999712df34b5df7741a3f0e0046ec19f5b41d6b89d7fe33cdf734e296dcff9dbf6344219a6a22d2cb50c75bc03bd7fd0eae1fe1ada0b9aad771ded5d7c8feeed65dde87d5d47821e756a926638395883879a91b94c6164b4d89547626a9e7cafcef944dc956174b6cd5e54944571a6f655406d4d331f7290bd8af6e8c0eb1df65bcdc5464595b31a913197ed79298867aab427edd9481cdbf0cd8ace149913a9d79cc6fde9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e64ce62edaee101c5a49b35475ae68634a7b0cefccfbef6d8cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687d9fcda9ac9c03a9333a866a9639803c76b5b199f94a269f389abb511d789e5edb892e5c565dd8cc2df74f88eed7bdbe3903576dde6934c4b6b75f96c477aa184d43f06792f3944efe1fd6e44d42d827caffd2989b936b91694825c4bd8c1dc0778be1971cc1efb93ec1b3674afb4fd07568ffe89c707b5786ce40d51b433b7942d88a6ef9bc9d091472844dd4005aa804ad50ce03b2bb65ef620bf0ac6649d4ee4f024eb2eaca73b80d489b73a8d94d834a88d2a96864611be0ef6ad30a6670a866b02e13c3fd58d56c19fb2425e3f1d49853abed68f498cb049c99d33c33eeb491997698adb6b05f9e63a85a0a7b8ed7ddd5d61963fc5acd1f6d9af826dd708f306338506574d4538e5aac2463ab95f4e37e3e3f584fd475a23e46bf79b97f844d3fca999c1ceac629f47261e499e32ed51d7d59e4bae4c2c4649e398add6bfca2dd70386b4f9c284f84c930610a3b22936090f3c03fe7a25e03f4f2d3f6b3a7c9a7a5ceeb395cef08ca8009a810986f33164055bf6bfb6e489b38ac8149dbc6ca863455c22b589e8a4bb5ba87aa0bed3fdc7eeb7f364387363e728a6de48aa47af676e73ab655396711e64778bf7fe45474c4ff9495939704d34e2476eca43aa94c7eceb2d3c009be35a81e576299787acf391cacadfa19f77a3d8081ae459b09ab16f4e1157abc387ade8f4ffcae09a610af90a924e9d485e3788980ee6da40bd86e6cc3d481c65a854ae8855fd04c93421c799402e639dfa3c73fabf27c64c0f9ce7d4723a06c73a9ae0fad267e58705851323fd12df86d16e63cac8b2dd05a60cc593000322c9c566b472b375e8484843aac71e74bf0315af59a8a4f6104a43159e198716e239247204753f629c5202c7812c9ae2351d88b4256e7a82b42b15e54412e0130d5e25388240fc05b253e7b0c94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e67766301b386b088f71922ca370916319d8f099f263caac7d7c0f81959c4b13a0da0b5c269760036a552016f8b591f6b37177cfac940f706c975a59da7c04fc7210ae32508c28204ea204073c73b474d74b54cec08bd14361b144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613c917393761efe2c2e4dc73d4998a1cfd6a2ff278b6f68b1f108151b857ee913b3568171bdf1502953b81fb085650bd027c4b66a8276319201ac328604100ca4f684f2fc65f220cac1db9c434a218814a14cb630b5b18410e11c37c92b31600e37c8bf12c895b1f315f0da01cab250881966d3c8256f5513cfd68e383bb8ae248e27f3b479f7a82da2aa564b121586bade1ab522776b49a02a16e3a798acb005d70d3ff24a8ca3458a826788aa09889293e4d862572907111071f0d58d679a0c620155ffca45bf03a1778941d41776ea11cf3ee899912c703d50c8e88ac447b2bb0a0cc3bfd83ef3261ca592915bfcad6cd26409472e4be62ebfd65f003c59d39b7f9f710f6a76a1e8291c834323f145aa3b8a9e2e4c2e98621074c49fd0716d3d61a2787a0598e8096ae05fcd7aa4250a7ac4a5314c842b8dc8b563c6b8f626763d865c141474c72c1439ba7012661985a061ced9679ac94983957dc99c4bd4061ea43c893bb707c0f633787c1b11d8622dc08c47954ea907ac1513aa3c4420dc48366e4045c79cbfc3b52415324e8c6669e52c2c16b1722ddc7d521558180781898a2e681a55693398ba712712b9c515d72255453a3c4212bb7b3692b3998d1bc6781ca28fea483c276a92c219a62797a88702b2587005208512aab304799a99acaacedb1699993150b41aa3291423bccb6dfa31a7b42be4997581b9aa54716cd5d62cb1b9bea0e8165eab6a6300242bb5a711f36e9a43b12e24492ab95218e084e1d2976a222024263e4c87cb93cc4fe556812096686ac72152f1a8a12b93c6530d08c99b9be3634dab9c93d27f2a4099304b4c61a4bf0fd9cb28803d0824c5058a515dc69c81228687376865852fe9daa07e45a889e650e0c58fc2cb71846b5296e76d71105e87ab2714b2b82e06342218822642acea28700486709c43b2fc421eeda5070ccc8ad1367cf2834e88eb8ff8d2059f455c2da34843418cd3449497b753c92826c3174e5e304437c04c7f518fa2eab149762c916b1c6a676a8d5b3bff02b8ea9a366f1706be888fbc40285d6cbb924249ce963646595573b5a5d0079fb9b0275ff031797899ae0bccb3ecc32eb48ba3769bd5e56667cc02723c773ba00924a961102225f2b88ecef333302077c2c761f48991755a83e09b7c3406bc8784031754bbab6b49c361c93f5ab9778b39b9cb66501b63d8859af0a00bbed32947b92f49961c5fc38bafc9b0a763802c9709fad39f040c6736a4c45a110a08822e26d93bc6ccb566a687ddb786f5d31378505f5d575746c3cbfff55899c933f0052e1155b776b9201f0272bcf67c3fd26868bcc42b2b9361562bec56ce1991ac7347b6bd500065e990b257bf20e1537988a560dc21aa652e3bc8650d80870a1a4190014fd1c43229043bc1068a5fa074fb5087581a932ddb5923730ba05216895ba1e67947c71aad452861371a542325607a7752b8485c48fa9ce930793130996bc63d1b162517c34449f5263077a41f576150d8b062718e493242f57041f2da6f271c0c5ba3a00a8c8faa0aa9fd61073dd70adb7991df8a143e797a9cf6b0cf257ceb347dff45cbf6db25d5928074b3a6ed918fd35895bc7b93682897c0d322d46755962928f3390664499a14dcc025b1c0780858db32826679a923e20ff56755a26604a2c8606fd7087218232cdc3b488423fa9328f9eca8eaca9fb4311777592157b46e4476c885581f6ca524ad1cbf663a0591a7679e515de5b65cea3a0971c9139019735d421a25f7126a9bb66f67c177f3873bc5a8a7c06026913a631b1b370aaa17019a7cdcbc22a24f9e38a69637928788bed0560a235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb7a9232085a0222b9c863931ec3bdbdd51be3f16d6cab3009c138e0c8cb692563b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = fcf8147328a10f617dbd830a270d85e99322d550c48b8b7a79be3e8de132b1fd8a515f39b21a5ca46e319741a4425ac4f9dfc85ae47964fb68516cc9dd34a110a304d5a318a4f76166165766d108ec79440341f9424612975360eeda65bd7d2472331d430c9da35a17fc3b416fbe537469c6bd4de4a64478459e3df90971373421f6b53751cd482cb2b570b64c7db457b31d2505952345ddceb27f186bab6e06ddd164a4e3be2b0612cd4e8a7ab6efe050f1bde501185cdc6c7bafb33ea8630138e96cac4eebd50a32214cae082cbb9ef7ce1da7e5021c9691a6149a76d4584d154161e391e7a25108fc850a6bc26edda0cc107c4d810407a3fb9d1e364ee07172eef29d83bfe895d7c18b1f4486bfb5170bcf3f46ac0e478834e6cad1ae51447038cc8fe396cdc10c111593816bc3f08e103b93fb406ee9f24c4be1f24878f5da0c358ea14c321d4c7e6bfee0190f2afb4250c1803db72bff2f0fbb085fdcfe1df32e559e5be30fb1a9cadc7c4f34b40562cde97fe6a67681ae2c6c2a88d91e6c4feb7d30311d0ee0875babdb871322d9aa7d5e0c3bc50cae1c9809f3018961ac9b983a14857fe0d6ddf71506f592f9f6b465956d3ee2f4fb3cfa043b24b87e31514967c0c8d8d7c8256003d172e7393ee5a74b8113c53643b88a203cf30fb7be3f617696f3720711cf03f242269155162ba1a71644a2376b71eb50d98251c4e7a6ef953ac5d4e1d1ef41d146e31b82da436b41269b2521d56545d168ac1ee559a8fd3226a598fb1b383ba6bc61a14b2397e29352baa7c60b29daf8b3749e05d7d75703069411081350339727f283558d71ebf53b421e585e93c252f65338812b08ee74b7189576e44fb7f0d11d71eed724d41bbf373ca1d663955b7b7ef19198b5734909a582af72054848c366a9a519bafb8a532d28c6dc9ae2fa2aa98eaaab0d61eed5d888b4472a4c39f5128cda5f0ad11154a302ae70080e56c58d8dd94f7c2199694c91b1fdc087a9b78be41d4496a7895af00397bf5f1174a76eace20e6d243e7354b5ff570799297e9785522123c29884e97c1dcc303be462c7b6d6b1fe059d67dd90d0d3c410a54e155b24dfe25aaac5c1dff0f68c8401c02c76efc9bb9773876a845092443250cce94691d1244687ae5cea0f9fe1595c0d83fecbbf5febd6f7d18bf5b9b2b6ad4e606d67ae2c0a6ba994ecc35f1dc012fa21bb94d3f604f045124550e5b6b7710416087b19cfc7992e30376278ef39857414e8320499c958f7b8d20724cfa30d1e89fdbfbfb2fe132fbda5ebdc3712b96bdca5e9db036015ce27c44e960c2a78039f2fa9cff6e1663505e424d467352a734db0a2e0b61448e6c3428afac5094e7fb3d15c5c18763d18e68bb853b33084cd85c562fe2a989a0ca81c86e05b06972aca21491d64328621d3542a1b929624c6b703ab9294b9bb972396133c1f1f496332c7605099d092133ac127e0d0651f7f3568aacd520e56ff0a729c8d86ed7f78a18ae093edd0fc49fec84d34703cc8e6c1b12873988312918016946c9a35a3c8ec14203e617f4da8c798d01582134bebe3e8b629bf14baf518f9b5c170d5d3ba53910a10ae00dca87f5b0fe03a7b577b633a93e19323dcf68861b207a5acc69820caf616dca99de0b0c7d9a9dbd33dfee0faf482f11fb466650ab246157174b815a88547add371bd64f4ea6b5d1cef3a187a3ac09003e148e49f707ba4e365111860ea1901513cba013163a6a5e820bdff516c78bf8efd69c5407d5cb8db21b92788c21442eaa01bc459399dc89446b802591c30ca8799140c7c50907c1a2dbaafffab98bbab1d2ad387ab786f7630cefa20de4c7b576655410236c56b1078ebf8f658a3c0d64b7f08fd113631ef012ab95b2d7a280b8a58a1fa57358bc4db04a372c8484f13dc6a5dc1e510777214bb6eaebaa3bc6dc5babf00ad9b4c3fde76e7170b48fe93cda3b5ed09d16e43befefd436a6a790d2ee696422377fe27ffe0e2d978870929c809bd3c3185bba158eb9a2178a8ec139a1531dcc2b171d067cdf197919232e4216aa160a086b395f0016abbc74fd1a9a37dffbdf83f7e460bb86fe9a6f21a31ba32a9d137add40874811709db42932156c5a1270a056e654701fa1ef5cd9b000f710d3983639ee7097ab9893e955797968b1141a0ab7c22412fb4bf4aa2f425c8f1e38364b952eab9df825f62 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 818b55fa5ac30b8e891f3a36449f4b2b046feb6765a61cc81d9d59d1f82f6b0d67a20f825c88a531de5f0dd95f0b4742d29abe7044c62d45a05bdac4623d305e3c3417d67f60c9fedeb6b2a3a8e19bde60ee3cb0fc6fe44435a5bb64e2c16efdc72febf6f7fd0f87a3834ab5348e96fdc950a3dbeb7354c4e50369bd4364cef9d66b3fedfcd580f1c9e4c0c335f547748cbe9264b787a02d6a9d7ed573b8676cddbdfd777a2a0ca5ec99ea1317c5289784df1e4e84c53b983778bf8933815f56c9a9bd06beeaf8f5ac271ac3f1e635eb9a8263c855bb33df58ea3b7f8f87d86f58aa57646b97560e593944c4cb3567a2c48fa795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b5082fa144737ea39be4bf5ec41cc55c5344ded158ab4a1bdf0a36e2962b89cc2aa8b39e98f3ed4b0f0cb587ff71c74e4f31b7ea45eccda8c597c394e5d36f571cfda7c0ae7116edc7731c70c3edec492c85de16c5122dfc5a96973d7f4f3b58b504eb65f67ee6aa7779b77bf554736d9e6e76dfc6ba007a590b4eed4b86a7a635effff6d86ab3319db48c4dcb91fe78df45a948035ef42e4ac9861b62860837cd8e3fae0dd851d8d21f8aec4d8aee5f13bc3e8462f47fcd74a8e97d27feff98b1f8bbc37974b025295a80e3525d38ffba8467f8079d78fa6069ef3bdbb3349b3e506e474ea228c3927a554d7747bd46f1a0343cb155bc796d75c40e5c379fc0fc65b195bef153ae4154ad3d5147b0cdc4f3a3c5ded656e813f9ae1fd63ab7a53031dac2d0f87caddecb8156ec8c08bf367c4ccae7626343469e4e7acd7d554629349803519534d3870bf02e8cd05efdd0e63db9e21cc7dbe463e8df4adebce1280f6843b87cf60cecb9467439abd6375d6b1acab7306f3adef866f883762b5b4509cbb2be24fc5c65d047fedd29fa431f9b7d987f53928a8d2d4c33add899ad736b40cb4fc656be02e9dbf8d393d73fa1ac5d9c4335e1f1dae6b11e39cb16f7f75d3bba75440414af98ad4bc5239568cd60ef94c9bb8ff1d57efeaa74dbdbb8b72f3fa46694d1aa79421ba6811536ea8d94878d9da04695e0b247968b7463ff49a0588d44c5f9e47f0739f7ae7b198f8bdcf56967becaa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e84fcacb74e1d45704fa4cfc92ce42453ba5c08558eee321ad6a6a38d476aadbf6987da1264ba5148b40a3a9be3d5e3a48fcfa4cf44caae38ea9cb8da86f7b45dcff87ab065ad79876893d8a3f50ef59f369c41f9ea40daa5a5985ce9ce06cf9bfcf947a3f133b4e57bb8cc3d7fa1fd25715a6fa9c99df6c018b7202885235de9466540c9eb5482a87e675e57be87f2bc74e33d8f7c20b97d9e79f343ff3fdb1b75ab2ccb6fa597392db92ffebb46cfb5ed1330c24e7ccfb39fc74deb8a749d3613b3803a6abcbfd99025e305cb32ba6a5b568f65c3ef7d8d49aef3f9e81aafddb203603569e9d5f641932f33a2cf4c0055e72dcedf9564a02afd7578a48a4e2e5248f3ac7baefef8e56e367bd3c567ab978c750d85454c68a5806ac38b7b3396fe9fe79ad01c5867d3f9de9b54bd63954761ab7f4a57b1fb3fb65f285743def07bad6818fac83c9f8e3e14644dd699a04edfbfac9e372b576a0470a9f9c5d2293bff5f55826c534c28d0bdf348b713766507674ae8f0dd0c7c580d37c6da35edbc62600df33cea7dba19bf044699184ce455cfc2319ce4ea8c451cbceb5863f4c0f9489f94a9c14992abaaa393273e4c48b740b764216ab16df3b9eac38d04aa3bad2e85f35da82ced93d2359a1dfc7f2f6dcbf05b4568c868258d8f4e07364139d514bf47ec7585593389c6cd459173cc759e8c7a9379890faf77553b3eb3facd86db9008ad395eb2a573fad42ce1ba09513129ff38ad6975294662f4f9840f622a236f5704e29def4e5e4780990fdd109cdaf3a3bd7aec51149ecf77baaa9c4f7884b9aa89ce7b81d387d663d4d75b9e5e5dd6deb878bab34151b852a5757421c8f090c44fbe85a81e076f4116c025977d9aab838624b340975f7bde6bc1067870aad26ffa53759df1d00bb7759579c6657183b6a67d4ee2bc6a8870d56dc329b483484af78a81b5f87edd3dde4fbf4386b6c88259da88de68a638e8d6566b6bc5848b2755c2e64d1fd9b79f5a2c7072419b955ee69a6f453b862528bc78905bcbb44ed989b5e71b9126a6a920e67a074b2960d6a3ab50128fd9ce39137b03a66968616f134bc485770e87f01304a17c70d9adbd4159d67b888862b0b6052d9e8496084ba93d197766d10f6477679ca90fefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c398341a4810c6698351f7cc4fa59c2b0a86418145743d2b850cd47f32502e00d96b0a67cb3ababf62785b11a04de252813efa36bb83001ea322490a7dc5c54f32274b01fa71d40717ff917b81fc899e28adc5c4a0c41742c7d043195cbf8393a84206ca1e87032c553b68776f9153b4e2e0a445d2937fdca7539b8a2dc497a1f338802c073e891a3f834505a82a39f54544a49921e348934a028b7c54f11b26ed1a9cc2db7c58ecae2586168b120a2cf4487a6b34b8015e64816af26b864b7b30b19022d5038f89431056153dd03169a31a18c5f6649f6b638d4c249b712bb9563e4adab4f3e83c5bd05e2617b4530161b5264ee996abd5905e025820c7e1b1bc05188adc559fd0a0177473d816a166025bb4402d7e98b7f148ad42f72920d24e024a4d7a8a9dade92ae250bea3c519ab515fa2581b1f88c4caf62d59050e4ab1512c14b581d7c012645f89a0722ad2a1c2f2639b2b11051059549417d8f3ca8ae80fc241adede55999222b05b7b7101885cdc149be41cf9d2b9137e3bd0054ca89818e84811bc21944dd19bb2c1a54251992f2a51ba93a452c290272850225e9b2489324972cb6982c338f55192b4b87c2c91cc985ac9151c638aa741a476f25b3853afb4b106830d882a1e8a26b1b1305cd045e112a7e7a723ba9b801c48358e3004ba12b347d28a571f8a6c05b7c81fb3ef2e324b1819df549abfb871e25053d3e4676c9088d277688d9f85db7fba99fc62306c0414654509a086d0247aeb60a9924a2ba77f76d669c1880c302e67b1e1e638e4f74628ba73e0c565bf7766ea68206fc779f9c55b1b48c350dd095a5566fe1a611ee9507e729142b384306527c7928a7c09a74e7c03925e87d71c45896444522a63bb6b78615003d5cf37ca7e55e82888c17f171aeb440952328ebfb9eca10396b2044ce7275ee2709e917cee9425ea4c8a95b163876a2159907003355323d56b62e243cfdc714102a345af05f4e1052f9673ef57abd43e802744316642c26809a9f07805ead090a676204cfba52f4f04715e5788a08754d23b7c5db0d7d72ad20dab9ad776d52d1954a99407eabc44174237b127c4670aee6689100ab4e9e003a4157b69151431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb783115803170c1f8b2c84d0dbb801473084aa130d5c9c99eac4e00c2355a04556a26247a73b4a7121fd2cca08168d2399a1a45b685a921b9c0aa339390068348a3a8cb55653987c691e9c86cd67c385cd580892a01d160c9e86a65bcf63a50777b353b948e70061d03154e5ea518bc687a4a6b6c83372c0d16932accfcb13525457979218041af9ba2e012f82d79fc245356aa98b11f186fd2c538cb5159cf9562b5a5344cc1c44b3703a50850358c6ab4a5fcf830bcd2b1a0c932059f2c5a43b932e32a2fe9ab9f2f3b1ace7a3c1290cce509a5aba7d50a172fe51c65bb142b54ca6113baaacd44f3eb76aaff63a474a74614a0793cbbd7a1c822292bd75b2cd9d7b579fa995b9561a2ccccc1de89e861832522412753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dab154f96a4062751e79c4aed5a1c6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dfe021c47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc18a0b6591760576c819716560159908903a32111daa1339d8a8c66081894a52465f542b011bb607177d6af34d88ea80d7247ccbc269ad67a15df94f42a22bc1a525abc7480257694e9918597a8aabd1b537b163d6dca6dfb77fdba61949e3c15015b567fb88b509b43d4665abb834263a47c5a6007e2807b267aa50e8af44452b01a62b3034ba54ba910b018c629266e26514263820fcb3390dc117f9878c0ac4b3ff899d83d922184c42990088bcb03ba65993ca46c18bf1583f5599ad549801e934b8990fbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f6481642d52117145ea2956bd5e446b895609be84a9344ff0f5cd1ec62af9ea9e3c076eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = c105196ffe91f8ab509666645cf70a83220648cdc8d4565d622dcaa2cfd6f10168a7c22d7cd28d5f65024947fe9f98d01f7dde433c8610c768c73bc584c35061c283085d68581e3270eb0171bd0b736649b079c2db7fd076bca7cfb6a186b88cdb9d9899abcf9a0bda849769a045686cc751e48cfa006baf9799c50c143fe643e66ecd041552d3d8518290b5a968604c1a9ce404b6d768be6496184de90241412ac4d284880d5360349fe12a33bc6ac9e697924a13eded8ff49c0d295d22f89d07a2ddfa2f0c7f83e8f59ed5573a747120be3ff44fa616eca090776245d10d6c8126b035247abce9b79c737f0119498acaa2b796f57e37bdcfb2885d8cd9681367d386c5ee8b0e6e8d9010b6fcdab4736282034d4bf3a0df5636fd541055444f69a84c593df54ef98daa5f6dc3a372139f5735d5cad090b5e79e2fff17509d3892dc339788d8fd3d408392f00031b117eca35d5be3173e053f52f25c649add017b2962f0551960cbd959453fe679de209e54593938390765cf0982abde7c6cfd2a32623aa534209d7a90f4170b64e78a8580ee1ca84e5b64115c7b9fcb294ab14561ec36f27d6a5cd87772e072637483ed4be1825de437e8cc321f2dea21a15d5adb668596ecc4832e3d5a5414583a2562aee3fc6ada088988d31b5b9e7534f6d4a9ae91125bce9a69db45209f7f76d0a21a659e35b839dacd367e9998eedfae7c2221b32a315872e1e4b00cedb20872e19edac6ea11f6202034fde554934a1a36378baf39b1c598e2666fcff60880a6993ea8214b0af7bfb08339eb643edc706dfd95d5366ee6fa8b02983e4c1afb0f434902ac07e50024c45b21c9d585a92ac046f928ea53588a54dde77de6859e571bc6869fcda8a2a5253c6332fa276ae247a72b7bf76cb459f6d7af5847be8ed0f26c3bfcdc48699db4b20d016bbd6ed416af20a82cc2277c97d65e27cfc6b0601eb5c29235902ac129eaa82f12d9cc2a6bd917e125cbe7957bffff7edde73bcb674dd6df6613bdb11c8139948c7fb10ca79e7c812d1e5a4ac7348c33e825096573ef00b63604ebbd007d3ad5b6b4477ccc992ab7fa53d6d62c2390ed9f836396e0816e2ab26fd308ea2adbd3b08456331d595fda53c7439210ea3b0f6ed5bb5ffdc258c1c30f4ed8e261b4edb9d2f0a94f9263b6caa34e48fea279484d0e88e392f1b7055d3eff14eed541f02c742be56bb9e7f3ffe8439ff997de9037a8d239b042bae74a3331b1ac2a8b7d463485f80fa051c6f4078c7d4835213e4210d6c41e401aa82fe2fb90378d4b975af6011cfc4c3210b24e7666f469fcec5bbeddd42ee79ec8ee731ec96acc9f45f72ac19559a3d30f0a2fcc786ae3c717f813ed5264a39d0bbd8d2fa0f438693a5a2805d3a86129bde0da616a66764fb9acf86587026fbd236ae438ef6da440524be4adab42527924721b6dd00a19c5c8c2fc42f2a5536d6e2b962a671c06b2559b9e2101497df277384b0785c87b5a8ccb08b8b8b732bcf7a9a88220a54684726f1680f51e710860eb2de2b9a6ed30b3299047a3be82b62a9267dfe9c535278bece20dec0783147ac65bd695796aceb61b9aea1f40d2592bcdb50b3ad97f3712566d6285be09411e36f1a4d7f10ed14b52e31da1d09f1cd3d1a2f9f3016440ec725b11f15c5b619a53267b50c04bfa8e3c5dca1cb9e326791d02f3a4f44aed832a2796dc5fad97a85b718f6a2fdde7ba7db3a9d2e4c5f6f6aa1c01ca3269e022eae8867e28bfc54947e05e9614bd0b41a54cff3f40aede9a3a497688ee5a08345f705e05ef0429c3fb272b0f3fc2b4e65dd3f4bcbf278730240e665ea696c119b38f8839a9e03d7aa70ad7dc382bbcd96f8325a8e52bec023888a0a99c0b11d4cd3305f09f1b4dd0efb552696c0240c5f7ee90571d01f460eac11e03ae3654d8745222911db99a222a2fde74ad001a699038451a832bd8dfc2bddd62891a685b519254b611bfc5e6100e70a02ae0382a45a8ab5a99e3046584655f45cae8fa2a0dcd66cdcd022e764fe318adec9d482057bb0fe373090bfb712c979662a2f23245e2d94ce730a0578e2f01c34cdebd096d0b83d583e52a934ce2c90d52f8371a2ce7e96eaca80e6fa7e7b41a28bbe2b109cdb70493698b493be344c961f82b74266096dc06df7e5c04fcf213bc9ef98d006325430318236ecb1b691963da4f0fcedc34c6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 92cd87e633d25864c3c5e9d49e865c6226cdd2b39f8a1578eb69a864ccb2fa155db337d2def5b50e973495997e18c6c2175656890fa4bbb86c5028d16fdbd656bd9e6a4b39a8cafd70f3fbbb255bdd296c999af1f67e6d49968dd02a9c4f4cb9dd7fc875cf32022ff5f8e8840f7589c3df85c1f7fc8588c0a33a502a385d0537e86cc6809185408e9c7fe636f7265f8a439332f93a5ba2943e6dd7b30d79a25939a4c19dfbf57c755a6adebbdc8390f8aee407a541c46cb163dfe174f215556d20ab942ddbcd1627826648acc30ae467ebdb45075470196b46697d9ec6974f477eda553f80c7d1e853398c69a6e4a7da746534928631e6c8e1e533a4d1e89cdd6969c0edc862dfcec4ee6d0035bb50573ed61b5dbd45c8c6cff3ce04f76c5a6db01d4949eabd27d3319c0efb7aaa4e5f636733bf8e903ae098a7f977d98c01af67225b84af1c8c404a52472b8d1a793e371be7a9935ee69d331256620f4dfe390474dd7ae7d17a50291b6bba4dbc43f89fde3fe09b7fc8ecf9acb1e67ef6b4f33a7ff5e6acbff298dc35673135d5e83ba37df968330ce992dbed4e9465f67a195a41893194bc51c67393252ae1ed4cd829d99a3d23ceaa387209fdd974e73178459bda539bcbe89f5efbd5ef2ebe3c1e59018a32632fdc21d4972acaea146df31d3a646bb7dfa5b641ebfaeb130470a5ec7c416f7036bd3d15696be23e3b458cc9ac8460cf38ea6976a9d2ccaeb90be6740db4289a55eca386d3d8a7d17cf1102aacf46e57812dd42c3a6398efcb2eb5f2424ea1d55eb38fbce4d7b64bd7c7fdb184d8b0a8906cfce08bc9f6df64f9936eb6b5c6a636b395acb651ce6b6018ea9c93ce525eee624b5570f81dd466dcd9a909cf36f34687265b61db6bf298f5157d5fb37346385cbf4df33b98686e0189bddeb7f68f598db1b6cc7c3f792d5546e34fa807e760ecf7d8049f823004453048c6f743b87c1670c7eede311ed08a24590294bc9ac899bd58819763dfefacfb85ac66521ae95c77a7af06e772c8cb75cd7d44afbab7a764e85d66319ea005c9af8cc4b55e6df169e4f93e79b36506d186becc2f59d0541588819b5edcaa3b80253178639f63b3d9180ec7e8bd4e95435bde3ee4bbd3abf0bf335569eb100ed3bc94b56b338083c8f3298ef734ff762c6bed0855d73cb3b46baf8ce2dbf82a4347f31e8a6e16fd7e95f4147545489ad1378a853d489c03fbdc65273080bdca5f7aab6d3f8438d33ceeded733ab8a68c7ab89edb06fd5ec92c557fd59488c6f45796b7dc39e72822ebc7643aa5d56c483186cb65d86d7e865479ecd5eb97581fda554af613c486c0b9566a7fd5f9d2b82b57345aefce368dce26ac53b9e794be57ec16a498b744ce849ae4d53478fc44ea0adb4fbc3ed717fb69657378764685151a5d50d74d79e6f4da1596f898e9fdf95653c9fe7f9885d1528f1aa5f9420ac95de9f8fc429674025882c9758236e946163d4f1f5caaa456183cebb12fda02b6c758eec4ab654e879b4f451bdf4559697c4494d8abcff7045342234cd818ec0077c9232e6683856dea36f74329988af3a82b898c4f0bd33005fd1f40fa898e84bcedcc45e369cd1bb7f3527f80d6655574c5a13f43e3f834633ad41d31a7e01ab4e0f06458017d63edc8e9d9b31c8ca7fef5f5656fa4ee9d36259adbffa6ae29237e8e01f3e7ac5fcaff3845b9de223ff3eeb946ee00a4a79fdf61a7cfa0c26f79b64d6bf7bbf4b7c3cdf2fa4beb9c6837c83aefc90c8bdbc21ea3d5854b37da36059dc409428e065d873469cc40ecdf1474abbc8e8dfc21adad1237dc147e6c6a735899bbc68e7e012c4d505ca6c386ca9218db857a7bf8908476008c6c5fb7e30456e26a6a0c247a6a0a5704acece835e54d32def57a5c59dd44d71058423d6449327ae1fc3541ee73e31043ed194b89509bd7d1e3b77075ba6a4d64dc442fff94a2607a0e36dd9920a438c537ea21477b39863f399d3729875f4e5bf9b05baa0dc492eabe5fe7f9cbcec5de2d6ad7284d8e69a301649822f5f68182ea264696d8bfd76423babe37ac6c7676e757f4805ad4cf35ca841ffd6d99568bc393bf817a8c6a5ced2b9a76b036dc17996c6cab32223ae814338b7169ac28f4f129a71ec5da554f8b684c9f9d9859ce9dde9a7823bf24c9fed4588355033f5b22ace43a30478209a8965d587c91428b92fe034a1714535cc458c5146aa8b8c7b2c047ac76fb3d306174cc370873e25ec207dea86d8430a7ed130701c671697185c385dfe0410d91799ee546b4d6347ddc146947a9a5692c64445ac60a9259a7596ee8421eef78bac115dc95067e002aa89b814dfb1498ae7829517c8ab587afef52d4f4068eb21686e4416d93c51efc2ae6eb1cb1304228728769f08a4bb64893231c4be107a6de473afe6a1a3969b610a87fe2bbde35c31d1530b05aaae1afb69c07b6c6d4753b16588413aa588726f80cabafed3323f412abd2579096a44c30991eba87bb4d667bbab5e848a0bb178441aec4d00477310ec4e33677925985e1aa7b9965a103cf14fdb004a60406994e0a2fa5a5df0465cbb11a54298cfb109488564aea65b5eaef171716719916a4615d3ad708c8a825874b7cb671a5b61f5c3c9b9325ff964046cebc4991343b0eb199b9099f04c97e28aaaf0bacdeb4a007f956530c712ecd49017d73c8e498fab650608106174c7141a7373e27b3d11c2b06455b4f1c1471f8a0bc73c4299c47eadb75fa75210cd813798d84aea44a1303c95ec02cf4602a496a86ba364babeb7603195c7cad66d75b46d763094fb0b2760b048af1262954b5bf5833cbebc2ada183bc207290f094b6e9c2ba622914604aeba35237d17606d1b76330172f74a06821b07d8348979070b31ea32166568c261c91df097e41cc1ae4bcbd3e1525f179f8acb232bd056a5e18eca475f40e0cefea85d664bb87918339f407831c27da3ea42da34be7be4beed4c8a5ca805cb209d51a826d32c2125e204f5c87944372c3c1952d5f8b1873c1c6899b85748448116b3aa85156df381371763aab6c8b801b19ccaa1f87c4097c3c351c62ef1c697763915eec69389671081562e76701d805b2a62692b6f3a17fc163339f49edd205e65ac81fee42eb689726a960711e1b2ab7c15e385717946c27c86116b635873324bf2fa21a5c194492571ab5a7afa1427aed8245164a23f2518a4f4016bb9af0c14a16ab67675767d5a165948261f4df2bf1ad7cbd259cd31944cb7880920dcb227d62b17cba049388b340173221559f0b70baa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab32142888d6c070357b6e8500c43182240863b002bad191bc0e189c0a0f481afe268dd9abf93938d572cac462c710b67507a913936739e83407412db51ee778570692006a3399e12beed2c2bef5a43bf356a27d1222f267b2d6ca313315905b7550c7c150827c8eef97803159d86127029388fb3b733a6f1b83b638dc08778ae53bdb4751ede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e98952f410e774b520413a847046149e1a36339c8807cae45144180a2bb7445626f1b2bed9c0d9fdb5620450b69fbb972f6beccc9cd12591b22957f94f47ad7022acec4233cf86e25631b8e975eef2348776207b56acfcfc5b1e43c3e64591fa4129077c4028c7b5c54734945a7bc986a4f4719867f219978115aeaa06929812506a40426f43a899892de243da4e9940db29ccd421fde03c80c79ba1c1a1b163170abf21cc32130c19ba2c9f30d95b78d560344971ca8fc9cb899b082fa21aef5110b32dcb13a369364d44f3aea0c4e7c49f22cc0a3c07b0c134e9ca3bdff78283592050f8c99f0e467ed39cc32a9cff97cbebc90aff850a1b1a20837e02d516033ec9cb4337a1168e013587bc4db0a7a4cb52c3496c0371c1699520d05c68d81885920812af1841eeb8570783aa6cc0088d67ba2f7acb19370b1a9e2066528bf38830e9c72c3021b6e49640805979bbf662404236bfb74717659268d4129943120aeec2132c5a205b7b3a6b8bc6c944fbb035315c24666f1ae53451b52b9b850f15e0c71a086391741cba130d07b96faa70971a2d974bd6219a2339098356ba3b573a33b2837d3d186a26559b0d2325ab88ba9e0cccba484a14b2f73c54204c3111e846249a9cbbbeb8e7d1b448f353ff7a35d1600a6c8e87c06f653930bc1c3796fc0e8001a3cce3a37745382467f614af24c832757390cd0566f0c443c7c5539c72927ea1394005ce4b8bc223905639b1c7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a0163017a26dba83777c4c0f46f31375ba02680ffaba588a9fe91f97ccb99c445fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 929c5e294db4575a4c6c5ce5dad5b9280b0f44731782f874dff9c4df0c016422c8659d96f48bb8deb6cc2c083a6878004e4afb27400fc86b71e78ae91d14deea3bf125bd81f2e5490474119e3412d5da97b3cb6ee74e6a0665fc018145ddee19ccf3634855ca2992da96881d8cb457bfcd8050f6ac71849448d5a384e2ccde4e154cf6ffde159b34c6f9a04bf7f674787b3d561dd7a44493c5fc9b6968fef5e7cd4e39fcb6e325a491316469e1d8ceff045a6b1e750011b7b37498f46fe15bdb375681111a38a58155fd6a1ad37be5c58a5d33fee1d4f896a152097170abbdd766690792f3b8a5664e8ba9f271002fb4d59f005ae5a03853cd813ee3183f6ff32bb482d3615ea5af3314cacef1352f20e4416ae01b6f03627182736eec2e1a9cd092fc52b2d31df7bd8313e83b2c8a4e8e425841000083d83c8f07fc0a5f2a332deb838a31f1a1422e9083b690350410493e6964b69a01b1d8540eed1b590d7a63f29d32d3207b69e019aeb61bda5da0b6ed2fcd9791dbf2a8d6225e875870b60ef08047789b2586bd67a6974672c8e659c1f14b784d0458a599497ea78a9349096da0da59a66d9bdb798b4ba3f85c6536ffb1b1ff750ab24cc2d6c0d476f908671528fd1818d42fd172a110b668266c66b3ef2a9323ce5d26ab6b0981b1dd0f3a3f07a88c7ea2eca259d9fe4033af8134aebc6a0dc0e634c1728586d41eaf842bcc7ac403e57dccc5019535cb8e50e56e43902286cc58f10b83763c663c116f97e04ad0a67f873e05271a1554f4d10f7422bb4bdc5b1a0d49ad74bf1749683834ca7f4379dadfdac9a0a111fc908812988ecde205951a4a427f47b32fcf49fe9b6cdd14ea7428a463ecd4a22ba68cd05c8beb4480d4b7aa9a7eaf1f6aad0148b81a426269c8e8d1593a73bb6e802046987109dcc5af778f84744ebd3c7fce555f6b5d685cbc64d77c6518c19b5981cab55f81cdf2fe247303369794b15aa0b10e0d6b2c67e52c43725389776b8d666445da486e133b4131377cdf60cb4a7813b4f45f53bb576b9a35d56ab8587243b2c128796908e60beeff98cc0e10845a8d5311876a828d6862ade7087861b223e2bcf6796e2d19dfc5a6441b99eb7f267052e91282488637de81b3c033c1f5ecde939048f45c178d191c3dbd8e9e7ad0d597816a8bfd63f80971fb7f8cf77556d599db8fb02426dcbd3d982977bf7a4e22598c83880a45b2aa72fd8047d2c765d03efec2a09103688c8208ad9df23ebaf584e30c9f0695d76adeccd0ecf6058bf1bfb812e44e7f5d50851fecaaa0cd9a9321079d07668563fd85d6eb0556671723280944b003739e204f51f0c07ffaaf7af28dc9fa28076b15f5092a38762504710ddc78139bda1128541d2ceb29ce4a58a7176c624180dfbf257fc7cc685e35060dd1ddccd85a16caae2528a3bce60297fe68472544d1df6e6eb1453dbf0fbcb3449db5da8791761d8daae8fa4b0b82c695c11c8d57141b8453da367af090aa242afbe8fa1696db5ae73286eb5c72a5164237bb48a081a709437f4900c944d8655acffcb7554b151a7bfd5f430ab57c83b4954593b52ab8cb8affc466316de89aaaf6bc54729f5e6d6de1745325af0bf392e77988121a7a695489775bf8db0a4268612262ed68d8dba026c41a00d359288895b24b71d663ed815aaebb3ff62329a6973d3f7f79dc7ada4349c9308bfd91c9192545e05daca09454821bcbb2769adc6dc09526e9499f97d944126a9dc6a1a20f01599dcd2387bb130607bb3e84558ee7d781e4b591ae83af6ede35e91ab07e05dd3c1973d522399aa42a9034deb5de2b156e0b7aed374cf47a526d9e8751544f15564834f165d10dc24e0f56323ab373df8f021934dbe9838b8b55078823461f74e9ec52a3e38c31e578c84a5f21add911b18dabfcb060656d2da5e124511786616a67655f98d6f09394140928c0aca59b798af0528c046bcf21928f910c688adbff35d80c59d97c7cb352ea823e922f00eabb309d711b3b143afafd64fb600a5de7a0958b3e590ffb6c20aea00cbbe2e52cea27fa5d34a63012dfea9b38d1ae6585b2cfe3a63c9161793a12513293a3c7985e33c4081d6a4e740f501b3dfd54a86ff0498f0ea8ffa3be90e86f21d93f31706a794126d9b2b46231bb26e1102e8b6fa31f529cb23e6d131f0dea516e231e2d669562843b87e3563e5eff17 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 817471e55466b5babf93afad879c9c951ba60d33dadd73d985bf528f9aa07ff755d7d79a2f9ab53d8986fe9d895d64d1dd97ad3f7a922526f79b5858f2087e659eb7bd4fb8a52a5953ff3622d5603a0a3152a9dcfd6ab9cd863345d8be5e295c06b79333bdac8938fe61e55350edaac95aca140398b74e75235b94417b8799a4b6d6933a8c8e5bfbdccf886664e7b8c5cb0b999bdcb2bebf88d569666d5fee2aa5dd1a8e58c0d36ced3a74d913fab8afb9f276be035f96a783f66f5e682658de520b844eb697112fd373a9470509d40dbfd0a7f85a94ebef55d4608167d925a476099c3ebdc3fc532a6d8f16be4de6416d0c30d55d808cd3c0823ea9265e985caff5538fbe6087703f28f157ae3cd144aca49f4fd15492e0df53ee5c9e78853590a3d521e843a0e37a26994197c3e61feea6096ec3458fd286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb380308d6369eb29bf64c2dc660ea9938200738e3cdc318b77ff86749c43c72f9667d80d462d549bdfeb3dcb0d9641b29308a56edf739e4b4c4d213c6fe69be61f94ff4c1a45472b5464f97c6d647ec69dadd5214f6db9cee938a934e5dae0b03be706b74cb8c674ea955a4d8ae1f7cdb56263041fca1871a579aafec45d9bbf14cd1f0a9c5d983d86b33acf923a2721c8b2fa7b058cbfe64f43bd90f60b6cbe9f26a4f55d53e7cdbebfe3aa424976132c3b4b4bdd908f7f2557a3658df85c868def45b76a207cb31b7e402caeef39dd48378b80dc3312f78a74065b2dc873b22d37990e465e425b9938ffa260d9a93a7a005e9eb956dab7c2336be3d3884ae51e839f34c964265f4ffc08f52cb89858d69dcf093de59c54021b83da94884a173be6bc454ad5a71935fbeb52a4f7544a7fccd3ce919ee9adcd5693d6e5bfcfeda4fb39a8455fa44eb8467eac3fca43c1456409e395e1e7ab12ec8f24ea4ec7364ba4abdd8896bc7bf81c85ea66c767aca6dab52058336ee4e7fd8a4e1d44de277df9bbc67f78fa0657530ecbeec3148e897d989bd49ffaf0fd0afbaa5b0ae748b8d847af4b326f970c626ee16cfe2a1c66003a4317348374e66b29fe87f37edeaf6fec75cfeebffbfedd96f6765c46f0c153d0555b41a2f7d50da52339edd8517b1a5f4e47b5fad081efd8eaf3829f39a40d7dd565937c59ae1b2af5b27d8f07246c4e1c4d230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26fbf51ab562c0e44bd238874e93a4d3c9d0a5bfb08a0b68c2c8fc0cb56325548da43e627977f914efd21d84fc3619823c4391e75ee2b5b77e8e7d7f9c1a37d3464cd5f9654307f1a0cc6c973e458cd9cedea7b6fcaa76d1f6dc44f74b986a772cf593af8ef215ffe17a5e9c39fa533b7f4fe8177ea5abe123e831e1dc561543a7e55969768fe57c6d499c4c615e1fd99d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf8df5f4906ecd7363cbe3841aafab88524b0ca3381f6cffdc84c6a112979c3c39e45157c0749c04c1fff83f53734bfee1f1842e0f7ff78c6ae1e337b542e5ae8563b16d99ebe7ff5776e85a0e9ff9a28bbf5efb444b7c8235e48f70ed014bbb8839b4b8c2ea2738f68a0a4ed3a733170fa7606b5bf25739e5dca5da4acebc11f95d6b47faf4cffbe8594c5fdac085cbba4194ba16e3f475b424e7ba1afdec5a38fd62fd878b02644d3c9df67defc4b64c87008d7ccca4a36ba838d4799a96eb3f32ac8dc9a403a3db5c529c8ffb8d38dc5fc5edfa5a31ac425f835317589369631036b487f29ffcfbc9ae2b4834135365f27cc58def08204a2ce8cd3f9467ba6688a9555476a935e6006b6922d91c80ca777d9a0cd9f74ca04366e9a967e047ddf6ed5eb196f8f7e694b0ebab8c33e99e7acab053b4785bed85c9eac4f76b34f74a853d48de5a49c2893340cde457d34ebeb5681d87ab1a8a5b938a2762ecfb9afe2d6594af14d719f3449327d4a75ef94886ac351a4854efcfa02cdd06f7dfbf7ddb545c78d88c7c770be3547ba600bbd7ce5c87770377c0878f04df75ee4f84a1619ba346df9b78f78f45b65660f9ba5cc8c0f1b900c845ff26e9b7fd9a9ee148003e9b09ed4c7bba8a8873b8841ccf0d1baf57f78ca54a4ebd1ad380baffeed9af26bb90f94c8b62859c31e146647948785b225ce860769fc51df7c4310984254f927b1c200834876b23a635869c90df39bbe36094bf6b4835750a6f3788bbb7a3140a7f85b1c5cc8bdb386a0f15297ca9c6462b21df7c11845788c130313c642ba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fc913ef440addb37107e3032476aadb55cc0cd93e317a8ce2439f2464278884915c54b97e882dc44817488994c0109adad13c5102847bec7730a57227158c4ad1b51afb66d5c01bb6d2cbd1a7083fa6b049912f736824ad40a1acb22f2cfc9c3d145545bb6494d0159c40c12bc84e8d22bb8e1a76c237020949698175b21410cd4c7bb567c52b08fa6253a50e4f1573abb18f74abb9837cce85545f8992c9cfab66f800525841948b18b7ef3a2b0961c4c7e8902acaccfc865b45a5209fd5a4db705f94122fc69196e3b56139173b32ec9063c4151b2819bf9c7b5d7626b01cc420c86d1070428d4a774177035269a46ada8ec0e02230fc6b066c57dbb875a8f294e66166f3d7b95edc3ab66b15d7b55dac16182c13b371d82c42b85313c65da7eba0920914acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c284f1589af30d00dd6893e70d571700b9a07baa6083b2c50ec4eb95e2236402f7b50c87a9305a8b5eb25664d74d4337af268b48bd1855574405ea6237bc057e191cc6743742dd5a66373b110d380bf7c03039296f56ca700ae07d1a826965d55d86c19902762e75f10cef33664f099f8440634b2299a474bb8af328a3e011bca75db90b90c52c1699c1bdcec31565e411fd1c6ad2d08eba8c50b66a57cf10a98e2335327b011a4c3e11f58415b6c38f1821a69671fc2481920c896b389cc5783c5fd3b7d974ce03375142815e86e13ed4e052b1e009a25a2097c02f3eb337c3c85551ba14e1c22036916cb993612c809bec807da4e25cd8094c36720d376982650a986396504893bb0d82389886942ed1aab5bacf3957aa8d191dc56c4049a0714d89bc3af9680ee602e154b5e1c35f1c0440eeb0ccab22103945623fc201939aa71f99ba8c409bff83276f84879e590d9a448e1f052188285de9668260282e8ecc630c15ab164271ace0c954f13944fa9f4eb3a848f11ce7f0a439ba07a469720d4506ecf6cfa241136b469c12e48f137601f39a5adacc54b094127d2c27fe38aa461c76003b9ecdcccaaa2b16d1e9a164122a0b1a1fb751bfefab4a1640a792d2381a74aae77084a4e3cc33275eaa595733fc4a99d43be88803244b449ac71da53b2cf30043c929811c9a558a165da241afaa8c45b07c27876c8ff77b721b21022c958323b41ffb606c656519875b8bc6e897854c08ec10611b954c693568070528824b509f83a3e6c505b6e3203afa863bca408403c0ae86a374c1613917bc06b94dda73a8e0c98cf54a60cea727cf1334b324343b2c47df4a843e467989e4160e1611c1558928717d794290cc3911eb70200f51152d04871ca46d2753836791ba98aaabf697adc925a827cb7f3ad01069f5748778b5946c78ef9688e16a5326577ad5a5773db939d2631b04545c530c9b99141f4d213158d213163bca141c7949f24958b9aa67089488a732189ca923301143a1728a6707a6e8aa5bfc4d05b6cd1971290114542386231cf04c2c80cb28e50026c66763a570d173612f142ef1ebc6cc9a82f7fc10b7104b7ed6b30c95c5a63a5e1e52450c1c26ca11613b2b3ceed10968e85c0a9539c28242f1b9a083c0109036c6aa9349f201648ef14d67094af9715422885c7d69627702943bf0955d90496dbb0c0f2b3137b89c62903af74b2783b11748bb6df46403b69701e1d9a1e8a63f01cb969fe9ce00d7b539159e75372dff7a85ba660aa8471ade291fc782403f16bc2bf1c4d1a138a0160cf44246fcea7666276318940624a32b4af5b15f8b4da5a05557bc819db8884825b8c2770d6636a16a296daec0752e961cc4d11d61826d883a61f74203006a83380a0f9e5280fc1b831567136d178a906363bb801411e069b461027a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a5401916b35e996e1336cf13249d0cc33ecf610f9811c27aab55c52944298c3a13158c38501813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516fb21cf5cc9a8a47a07cb2a154f73676d39a98a7d12a4abbd37378595c6332f46ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = 32321e07f03c470e7f512459b81f4f73ee87272c832c9d6c1aa1bb4f1ee06e7bb26edffbdd4a2895892183cd155487b1a3b8da76c38def6dff27c8d28f5c6c59e4c8ccebe41b55766b1f7cbc269e029c11036263536a0132d116d3d8868ece468e6eea88a30abcf98e5bf9b0a933264b79265de1f986cff311956bcc2b7c4288239c14a7ab629dfd754318159c49380ad43faa6fc26501612ab3d5403291d312de1e183909754bb0bd4fb3c1905e2fdcc6ab9f05b984cd093605e7fa082836a7cef37fd745dba9c2d1b381a139d31e5ef4fa2d19d0a37b732cf5b2d40104f37e35f57fda0763df9ac35b81ccdd6b5ae33c85e70be21935adc0e84e46bbcb1f1c06ec60e2ef862f442cf401d57453d3052153c917bedbffe7c00d82e8f502b22e2eac53b97742f9f03f0157e3b00a997bfe577fc58db3b84114ae7f29e2148661cd3136043a7a194953f45a7735685643d1d4e54373a2c9146db06ecb8db86e210ec22218bb8e70634f558720d6299de1f5b74b0935c97d9b5bcad726964766a42a18b6918bd9dbb290e65f28298b3d37c46e58239263bfc8558f4949d882d91ec4e553235bf18cb8c056db5565b7aa4e7e2c3b8267188fb5f3ae0c5e7b68494a17a17f51c7e4e7153954fd77067021ba82eeac97e54d5398ed4a0462118b9ff429e1fb3ea12f915b4105c2c089e6db8111e5acb42942ca67687748e24f1b4460dfa8457e0346fc54d5bfddae4e2dceb761d1bf33787d37c25ffd5d5c21338f388f5676560636d30e71da73fd7595843cb1d6e3b117e471efad1da518b4bb02feddcaff136cda7b640e259c8d9cf915f53e3d63643884d85daf87a5956ba7e3cf5b56588aa16dea2a1aa839deb8e1f10b404721f29f3163cdcd68f599ce325906d3d1f5bfbdd0e7b251faa8a3eb64396570bdb58d6f7d7a2129c0f3e45b3d876b3fde7a70dfe5b0b80f75c03f4f710e37f820937f8c2ca9ecc0f0b0b4256d754e24a5d1c544fde6a22a0b2eb69eab48808d940c09fedb315dfaa7a2f476df90b952bc8e799a2952168fc704b1e3603e5f84702d81a0bdf87695f971cb7629df72dae408f95635c1910314d9f973f52ab00c190e03e9a11cb93456186c41fc56ffc6e8005476a4c9377a08f406b0b116250ff4b29006ecea251e7b52d49a51dab8709267bdcd6241f487fc4ea2a75388d4ac15543ba1dcf99675dd03b5dd8ae49e28ae1b200b277e2075e169baae3217c62a2c8579f9588caf53eba32c62351dae4d963a750f8f3882dd97eaa7115d802c197a24232efb77eb499d25ccda398cf7111c59e137cb0125b2799ea89f60b6eb55acd3cd2dc95ff5eabf114fcde7b734aaaba78f4a8b6db55cb97dfbdba70fa9df336563406f0866177b71c411d96303a6176ed0387a9744de6c1e34f67682a9ee2bf0c619b79b02db5129f31afd2a09a74c4fee27874171517e4a33afdd8810e72cac1915c7a701236059b9d78588ffc27ad078c9aedcb6872518c5aa0538e9751219bddd322ad0e5586d16765de15c19a2d3c56304085b390932c8e75d1f24aeffb7ecee790c87047010fce2ed157366634324ac2579617f478715929afb1696ba2e965fc7a19fe956cf5a7faf163bfb662533a6f1dbb2d3a81259155349b8c7b861c6771210dfe361c2543e7380e4b16250099651175152c86d6e3d697dfb92d6d4654ee0e5dce5f835d3d9881fcd85313f431d3cf6e13a615371bddeb17abcec3e44952405a8150ade995597dfd190c8ace3d580fc01d928e584ad40f41da93e7e583c70f69f9adddec54a9fd7d03177632f7cc818bbbdcd048f7937393d159ae0d55ed3226c94a7fcdaf71c2cef76772fa3f0874081f4b9ac27e3a9da00968814f9c38407a77b03778731a69468ccb83fa20c0458a4fc4951282e6d5da2b9134064547ff41546e7db0bc81fe24e1af6e4bc4720636f6c956bf96bea23b2627ad7f09f3285b9d93111c381ba9ee649c503ba794105d8471e9340218c55bf16c63b845cb6501050ac0eceb2ffe24f725e6a04d5a3acb0e0d98d6256a769762215441875e03fb7e09d46cde7bcb05c2d7faffae7fb6749e480c17f68638c3aedf8573c284a0ef9701402dc956ee859f5aa2fb704d234c6294c14b7bb98f8d5b1b202a898b245fe9e9339ee1418146f2ddd5436f707ff461304910ac55364729dc52218bdfca3dd084b1435a341a464 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 60e93beb5544294bbd622e41956430d0fd41e0f969e954a48298c7b503f2baeeb70b7c796a753cc5bb93723bf0380abd6b8aac4f1be02ddab380b88ab9ecd40fcaa8b775882a673864fb757a34532746f7df0690ca1dd0b65ee2dcb5d235cae4fea59a764736a018a091c8f2a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb7926463f5d6755d79b972ae993c9e44e3ac14db3bcc85c4f98a2e185bf4faed19a4737dc78547847b7ef385d3ad7bfe37f764cc873be8cb1286a0e7c8353adfb9bad5a17f0893cc04ef2b5cab8f66706955c5e168a99ea8f0a95dfcb25a434f2ae4a00e48772de4d32a51bc73a8cdbcb105cf9be554b2735ed7f03e4c26dd82c735fe0ce68833a47a619a611b08394a6da64d9cf2c25aa1121a80346d5c9bf3522183db15f6f69dcf5febcb8e3336870b4cec9d3a89de4a9042758f517b55f95e33b403c50169da0f53542249e18f93874c3e9be1dd63ae9fe44eca615615e424235d785c92ad0dc412f8ac0ff5b88f056142f8a0934734b09ba14d1dd89bcae36279a5fe56f082ab4b0709a6dc3f79f8e9544f49d9ff78b264399c2feef9c803b341e8e6eae96bc63e952d65d59f0df43b1ce8e1f7aee5498ff70eeebf9dedfe193bb61b870008ae57483daeb8ca7ccb460193c68b5d9e8dc738ff227fda89b21ecad053a9fa4d4aef8767c0d3f3419838c8c8afc0b3d68e737ba7732ec68a8570948a322a143e5a03888c08a1bb7c42e9db91128e9ed955f3848bc3288ea881a468d26aa7fa4acb926ab8696bf4a094b8cdbd42329fcea89cefad8e8a6b0ca19f4f3b7afcb51c2fed48ea44037963ec1a325ecdbf7555977f468feb49b8346338db983e513bffdeb35a300495f437cba88c36d01536f7a56bc9dabd110db7786ed3120fcabb7e82e2c440919435a14bc1ae1b35449932496f885c9c301c7f58faf778cd0a4722ff6ee32c5dcc7a7283ece0e3dbd4723f55d0044bf1e9f3505e80f32483f7079b2c0558b95c622ecdebe885b2580931fc96e7b6a4dddfd54cb327712ebdff90a6a8ddb6ba17b3efb1e7f31d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fead8897caeedf959f380f9a84f7d7ef676b89fcb5e94b8997d95543ef6cbd28a7d02befef76b1c91ac327874c050dec2e6f80fdd6dcead3587ccdaa6ec76f064b3264bf419b03e30aa7791053bfa7ed89f6cb8bb12db5c6ef517d5bff34ec3c4237af98dab3f4d44ae26e773ed53f391a689d7b38f11e55fddd80869656e15baf9a2a6419b38c2ec39112c4f16fbc5d9487efcc4369ec9daaccf3a7531fde24f97c30c4c6774fe80e9b928a0941c24cd3ce588f7d94eaac9eb74b7959bfd8b5b15ff94ecbd94c5f3dfd4f5e9e07dcd3efbcb2937eedcadad018737bb9ea37aed30c1a6e55cdbd4336a4bbb7c5dc89d57ef5c575cd4dfcf9c8407cac999a54976bea465e9075dae67c8f85b2d554ec8e702f3d62689741315eaa546bc63b4f723bb95f0dcc525944c967d7a5793c34c7638ee5a6d8c878df2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93379fe5dcf2959d1fdfa16fff77b7ab78dbfba797d3f13dab307caeb663c866635f621bbeb9fb4fdc7add8882aff0933c03c183d4c8fcb14a5e1f344cdffbdadc0c9b0cda8f40a7a7c97d6ad8eecb20a9ad4119b8aee8ba27383d9666d8d0cf9f1a6dc8b8ccbd098e7f2edcb88cedbbff0efa04935b5d766577dba7c20a73e4a8b81d6c8ebae3f6817f8b9d654b005d7437c73761d6fa4351fb39eb8f1f9547b433c57c36ef268eae4bbcb38b49d6348fcc9facbcdb2f44e724ef530a5e5b6d4716098d71c6d8619a8e15ec97d9cd99eb773c343a4f105b4926c14979fc6ff7e76e6d3bceb101fa96cdc7ad22ca61498d0baeed47a8358a1563cb41d607118e98c084215cce631bdd2b96a74da2e98e93f710eed36b043fbdccff69e23417b8fa1dffc57abb971dc0a34d04378308b90ad46d64548c5480bb57384b7488cf99b0e6be645958f64c712b7545463fe412eab21c55020c6d9e2e4a5dbeae51f8a9cb9e9c552b73b834e445f97ac16eda5e7a357c2a6608d388652848c066b5f345c7ee8ae410db478ab5e7fff84fba1965abb0687296f73d9f993d7d730988a709532712120555db81fdb599de13109277a48d20b0b16db7c6fa73622acc63ab1036c9c07a48c73dcc4111e10c919d09b3a48b96be05e56d809efb66ea3bc97fc360b85533c4ad1a9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6582274b7559be1362ddcb91e5c857b0e836349d4023d461b1b24cc873c56e6404149026cdeea16affb5fd715766617b9a5058776b74b72075e25002131baa50ca093bfc909b6102e8e5ba2c748bdc5ebca2be715b2800abe643ed542a8f4c055a0c7122854af8460016ca079bb701db46b2b17d0013dba7d24685fb46966ce53b3842cc66c8baca0934efad619459888945759b3842e26a914c835bec4410fabd4c98350717ffc143b2ccac4e72b64d195fe1147fac6171ba8b213eb5724039d889620c70a55ff0145caa543bbba3f732ccae4b0846200ae7ac6c84396224474568c058fd4785347f077da03acf744005ac1cc02f93f2130386aa2b62275722e11589c625044335779d8bae917a632652536337db7c78272241b4710210cc7954b6622bfe1653f4788450900d3dc9bcad010f9429615d24c9a4bc80a2c078f5b6e3c6847af5b0791c27fc99950e77676aea63413a3b259051cf6a83f0f9c5952462ab315af64b978bc4154be10702d5b266ac524ca2b5570199ca7ec91064c0247b08e01a8ae7f194db11b88d584237b507e44b411d5c5112dd22c7acc8d6f3513cc8caa63342284e6bbb16b2f63b9acc9cab050a19fecb758ec455414992aec45bd453639564a0c2bd164c1604d035380b0c2350f530770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe542054094a450a8c9f7a686b7565a3036ba7126288ad157bdf172c5e772ce052689d2495d00159a920b68a86fc905364c20027f90171845347366053d8c718a444a1e60133fb954adb3a47a7242b8100a8f9784181a4e7e479ced14190a282feb98008c09ae2b124a8743a4230910dd612cc75bc0068a4d866ca871a48b071cced3336d5c01ca3b819fdb2c22acb71b2fc2cf61c95b6cc164cab078472658e5d19eeceb823a373b4097b4e83b0d86e9a50488c1a35418c497250bc90aadab70ad35a16facac83093570399e8f615933f48e7fe8c04e517736732d6792c59e400a228a7cf4896af6c6c4d2f3acf279c861c83100b2868cfb42bc75052b26b6920591c78aab2de99c2ac0971dc90c19b6072f388ffe054166d95a785b8eeb141a9eb0482ee6b57c896d8805a33756005978a98f3817ae53b09ab4bad0011218382269f062b9895697514f9ad872a49392166c72c380a86c711d1f00c9641a6a03083a3755a482ab70cc213cf6f1bf7699164998a96a8258e819652ecb01f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341a62631f0410bdc0fda9ba4710a21c8934d6132ac21bb4a9292b16f787dfc58ace7d69efaa67c3a5405b98a9a07b276bedb636c18a668a1c36acb7170ac82253a85d1524ed79bbef4f046649b9f6a31b924196c6f72b12f108b6d95af9b373e34489155da84b8a810cf005caffb8b28504739590fd6b2a5247a5139b39236a2a496a93717854b162584bc57044f510656906ddae771bc029a0473a481eb2bb95397fb903a36a2042a4327c8c54bea769c419cc5efb83e84692513936f8f8775a1b114c13a4318d522194b8f1f7b05a8408348b3ca877b0a59f34dda1169a8c12d716ab9f558ace0b72750c1b4b9f11be405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbd407d36457c291b4027a6ebed8003658619fc4cd617898e8ca2e77a505cbc70f20aace50f301bc16c398d30473619326e261e2713375a68d83cc719a381284216d1cd011445010a2d24379b8024c30ad70841eba93cb65621260f41125c8cc03fa2894e84bdcb06b4120371a610ade828beee4b3495b4e97e25ed28bbd50223ef0c6b5a6c53470d22abd74c26af08cd44ca194815bed9c58a1775cd0431b41553454cc892088bbaa51b26d37c25a1000a7f8c54abcb1f5c0c3c61c7f6d36bc45320a886280fe2ccc24c704a376294ac15d70f1a300a8ab1dac505f3b2281439b3f93c4d4f62f5883bc00d9589f5a89e3413f425248a8f7c011f616d65b857d2353c0d28bc574c1f2522c2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae591aa9c81277503a34441fbd6cb59c6d1ecd5e00298fa56be9df562576250c52e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = 8fadae443a93690d09a1783148006e46cbc537e90bc4201d319101de05c33bd3a917a7442f35b4f1c56acb4dd73dbd6be0d8a5cd47f0017a60eba182642e661b03bd988febc9ef27a96ebc1dda94853649786fa3707507154d4c3d6f07a0c0d059d0eb18a55467deb1f0a1ef776053b9856e7e4d6a432ee2b9717422445175c17aa576d0c3b26e715bfc654ea33835ed61fcc7e25f39e2009eab6dee957ca0f953141d1ccc9f6e887b512dee3f289139947d19fb3c035fcbe639a9ae1dda60ca47f45b033ac4dca01480654769e903771983322b756be853467cdb7ff2d8014fccee50e588af4e7cb79776242d036776b18df0ada02884d034e5af3829bf58eda38c280927c29e030dce8a4d8505205c059f9c054453d918685254ba0063c883b49c9623477e4b3ec0de7669b20b8357d8d1f6dc48479bbc1c35a661bdffe1f0bf6cf7e1abb5c78714db3bdb5d86ffd20c33806be106301eb53144a6ca2523a13997dc60e2cbc751acc36dc58b2a4cef33c5230e2d0a05b23d0705cfe0c4e638e7856887d866772abdc9ffe8950cc5a41365dc88085a9a9e51e340c8e4fa8388123e7442f17f9a647c40c90f7438026cc0fc18fa97bae1bb63fe49d745e1c219ae9ddde737a543afc8e38559ba8d65846041030b38e8a3b427b60fba15d87e15f477b355d5326d87066607ebeaa701c9a8d97884d68495211042e12d8cf7695b5c9baf136b064471c20602566257abdb5c77891bfd2e8f473f88eb8b5db0a70b9c4d338971cda283d50fa8dc0683068bdeccee3e0563b2c270e4d4e5bebe41c1fe84d6f8cc7673de8c70c2b18a4890be8255dfffa5866a5a039b38f2aa01984cd87f245a18fa16658b2efde81014e08a1452003ee5ce7530f61c0289c837315e593f64d75665c0c0a73d292a9efa16ceaec82854a58c9daa439b1ebc9681324a7e20ca86926236976a1ba362d33f7487a4f3d468f6b3f80e2ab541102f1368ad1da3a16fb3cc636df1cffad9ec70719cc395a7159542d64b7725a982ac5240b054ace33f4394dfd35480aa9ff5c8120407764ce390f0e8f8cb77ec0176f4ef6c9e64f2906d4841ce8d46192421778a3181f723722d6dbbf232e1ac9f2fbfb38a8169811782e267ee85f9b6cbe78ee9f75c224866fb318f271884cf1496724dde18bce61fb941c8d3fb21b160779671b0f14cad845aabe334c8ec30852cdd05d172d12a8d86d8e33c6067af227bbb3512de73145a1dc0d0e81a330131aec815f842233fc332605eb5576ca1b77a93bf02b0e94546bf7e887e996b1fc1522a8741f30d4d5456bb3d3de2efcd1648c41da7d73bfdea433fa60b2fb95084b1ef23c750416d5fdf3452b68eded81b4ecc636e9f4a973b0777e8fe15a62ca6399a41e9e92508297ac0c4d9be7e904481da8c1981f44322bcc987cc68703c27948badd76a5313ce40816612bc0f6c51399d810b62faaead5eebc32d9c9598a91efb8484a2ba009361de1318cb0f02796e827975cf0fe7137de63c2746c05e1d01fe2403b6fddb9615a9be91245a416532ce48f059a3053fcb6b9b6700a5f3ad6d6b88101eab3ab2c5d38250ed818cab52d152d4786502a48ca27269979f375948f0b1ab51fb6d9eb743364c683d3cf6af6423de3b3dc22fd45e2e561e122aa7ad2af8f65f5ce7d6b2877135e05a8eb233fdf6d2dde8430a59bb7665013ceca35121ce7015ecdc747b3a89fb60ebf7c05c587dea7c476e9295721ec45733605d6c94ea1ce7fa8e90dab6f8ab5457c90ee8afcdf25d901ebb34223c5db40e7768fcfdb3e85d3abda964b474bb432f0afef11c2ba80b381c6d6c009afad4b1601058617f0b24e76f6e3c36424f8c7f96fb9aaa80213e05caf90dba0e7c5a2361c1a54ab20adb6b5dcd8631c6b7540cb64fafa0ceeef7e4d8dd799aeea9225fdcfdd920360957c193fe1191e5f5901f04c7829bc50f35d8c5e2072c85d96b9a94605d7a1cd392a424054921fe9b0004dca6ae83214e3e4db55f839221b78cddc1eb8d5f5a2702cf6923f886850838a2f5e2fcf2a0afffc11cb42abcfb62baa4e42a47cf2290f824044affa377e0c2a58e325127fc2d0be21ad503b2efa5acd18856be477b62814efc047797fe15c6324d3b7afbff35062a8207f9de600ee3393bebf451a9dcd9eb51455ee5eb43bd1ad34ca52a7e63c9b43d3bc144906ca33992c33b18a07f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3a756d6ede57aba65d618fec41eb4edbec38835cf2e9ac88f14ee9b57fbda0a6ed1f5c3268ec649209fe5d066dcba69ceadfd312eec15fb8efa60e4c6c956f88055fc2d35e6b295d05e6e67e4375c0ff3257ba72c0f97f452b60a02fb57f8cf7f71a4f259938b5bae8097399a0e3fc371ff03bb6769015495b4bb7317c9e99c966215c58d3455efcd360048f6c2c8bebb437a66a968dcba35dae7d98fcf9e3321da10acfb91764719daf5866c9855018fe89ff9e78b38b40a53c4e6f6fe63390a39db54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f595068d9b1095405949cc56ded9a21d864965fd5f83a970083bffeb6550893b5d6ed6418bdcf1e44b6b05a9f9093e386c9d44fe4d4cfbabd4be7efb49aa2c67eaea9e97d2e4b7d58775962570d528b8ebc8d32f8d65bdcaa391837d484af7239a4a8c0b8f140e3f4aaa6bac0ca86e63f523d9620bf9c2c4efaed2365e91ae699a4cbf454c4d2e2c4273e9345624ff737c8b3697b9831d39142c3e25b346d12dc82995dd6def649087ab763cf5bbaf639c8c7a852bc76d456ee69747fe66ee267844a7f5eae05c5821fdc2b98db05cc935a3bbade2c6a4881cac21938a304c4cd3cecc1bfabd932b777cc459bae4be75389862464367c6318a15f1de6fc5f17da139a95523eedd2f4e34c075f2d05f83466fa209cffa9553e014934f51ec49f5fcd87d1435db935bb62f3c3ec87bb7f7427a458232474ad9dcf22c5ff149977c7f366f49bdb14bbf60bd0a8c056f3f9c2fd91bed49735d64d0bb4a259d75816aa24a7e8f1a7768c3469aad7e82d30dee6383d38d7c4ca258d2693a354c19c66dcaec05fbe80bdd4c20bd95b42947d16b66139384c82fd6bd0ba9ad9bbb5dd7593d08616d2e4fda0e3e792a5b4a4de22d1c571f23e5d235562c167d7546c8ef7536a929982f6a55cf8fd9b0d5735f69ac6d5fa824f5d8d258ea5cfde075c54d8743bcd76767b69b5e350989e629c97bce982a75806136f45fa692df0ffc16af9499d8fef7f993eb3472f95d527eaddda205e4a9366a4fa978038b9e4685fdbc8d84fc1fcbc6aed08d79f544078343e9ad689d9dbd77c18cfe8f036d7210f4a0f5dc749f9bdbf47e309027968968678c0e35af75e38c5544abd57ed8a64641aff4d42d52bb14bab4e5edaca8eccd838b4b5e3a36a351b82ad785daf81e8ed6872583b8babbd62a5787bab8edade9c80d9130ec6be5ef5d9a9faa1ede3daacea7f1daf7fd7896884e436003789b8c781c599c99df465c85e3cfe85154d7a6562e6e5b3b800deaa6b9dc7c0d998b9defb99da6afc27a5ef7ce52eb26e84e9ecd038cba69835ab46ddac2e87368f37888ba90f219ce9eaf410afdb3e1894db5f640a18bde715e95a45da61ed6fb2c8af1633ec530f557d4c5605346a6500b7c1494d12fc87dd55f6823c447b71a726d65753716b30d3ef565dac474ca3acee664228f85a5c4a726f681e996e9e3af89d08895bfaf6bd6a3bff3a5c5c1ea894cb6440d075004f879b42ae4ebc8fb74bbd132ddb3348742dc7f44e85dae2b7bb57f8a9537a5d2827880f8b5decb1394db2553c086f7c113a300078db1bac7b60d78d7ef443af5c1099633ebb4b9313c9f82cb96755ff11ccbb7dd9b4711f85e99e7b0770ec0801d373c1d4fa849a9ca4e6c3304c09c2bff220ae69bcbd43a58415b1ecbef06b85fe7f8b59fbcfd07675718486535d3a6ae62e0d478d74cc05bb5e60f398df746eb351ff6ed49a5449467a9a39cd5297c52ccdcb96343258540446e7fab8e7ef2a94aec5a49f0579f085acfa164c3247959aefdfdcefa8acb96570516db08499c3307e0c6055fe185fa07fd547f4c702f95eb37df3da24c8ea79a942dfa6912dbd0c8d892b244c766dd795545423233a6c0ddef380bd6b8f953ffa532b7b6c2d667913cc966f6b88f64cebb06b3bce64eda8be69f0837b8a0494995844d6545d503cd61d65c563fdb6b82e4ee76495ef15b56f3f53d5537cdb2e6c349844f032feca904d5a19c65927ddd88babd8ca4c25c973f8abd765ba6b4121358c1738e7d7e8f6cdadd6186594b265fd64ed6eca59d9cf5ec1723cff707d63fd6f40a47e8b0aa3d952d84aa7e85701bb213d489c59debffcff463d9608cafd53c614fd2510dbcdcade2f57004cc995db29139a713ec106607f815db318f03d2caf4a294caaccf34914106d463fe118bd0b65021f086f1f9a8f34a42e197525859767d89b0eb29cf54a93e76f13bf43344bab7578ce167796976e5c7a2626b76ca2222cb358904386a5485c67fd58f7027543185c71ba82cdeb93b619455cef931560452d7650b25617c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5960a08a6d8992a23aa5840c97adf727e698c990684d0c19ac71bb816ae30e71351c3300b2edc22601b6bb7545a87869b9712997aa5c3ce6080afa8333e6159c1de61333f4742e5c49e887a8a4ccae2df6c7e218a509124d151a711da99a11d7b5841752c498521c3c4699113dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b592327d0242ac68ba6d01369257c56427928aa5b0534200ff8a4a7263f9f955598a0980ee67337442df706360faa20dd6941195036831186dde104c5e6cd79a84afd6917c1122070ac6cfb120c7f22276afb4d51f52d0ef2bd4322164f938f66269703ca1db984bcbe337c710142d024ac0d7502579b1b804bcaa5fb551274ca547301fe6597cdb0754ba6af7d74bca789c6a7460ab599cb14825fffe28683267001e32ec6f7802826c3d5091f8c520ca52c51e1e2b649222bffe45d9d373f8224b9e3e973a852a0d6acafd22561aa1376e9842ab292a61c21308e209d3ea353d77a8d835a46e9315ee19bbafec09ed462269de56b36f6791f771922b49a51b3870ad0a0a2f3aa0122ab02648ece97c96ed24b9e99b6ac2c964cf356e4a39c21d0274eec6fcc8893e7cb425c68c8e99a89d22647a5522ffcbc46184ac181d556616503aefbad90966d2806b6bf26903b18b1bf5a89167a10d47cb4a6f101fb09473710559f39b3046bc7a55331e8da418bb34089793c2a7606112011e89318267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd85f815c9c15b36077e9971b4ecf7546c4486ab074e511b729ecc835c175b8304038550aec0c6c22eb76f866444859293d21b4743e0202a3b6db7d2342585a5c098ca66822f86f01a6a9c080b414144220c44054801c36199432870f8b39b08831c8623972b1ae3442d0fe409b47a5c22e67738008a71ecbb8016ce110794b1d313460650ceebaccaa637f9625429538dd1e00ae8930211063f3265ce4b7c6ece835faba9236cb228ed003cb22cc8b3c5811bd9c276944d929c5c67b26b8648be93a89396c2949e26866ed4121c3849bc6c15adf8942fd4ce8f12b5dd83cea1322ed4c0bd2bf9b591fb01a7dc49387c04e7c1416abbaadc2c183072ca13c31f8e964c2a9b56912571fbc07878584f7926a9cf13c0f4c114c59b1b44a94014c2963c596471f7771cd383c235aec594b61eeb17266a5ebbc4828805169d1a2e468448e73a1e3c919ce3f738d2e1242c0895b59c27e12cbeb10c591a54108a7b730d2b902185b9a8da9d2ae01807466c456c4eefab336c13c6e137b6cce922b1113e1cc862c8883eb69acb0667a68fc58fc5d6584af926b25159f4700c110c43bcdac03714714ad4c07afc4d54200cf0184e5e8a6e5df1ae6d13c9f9401ce38c6144d3b87dea304625cb8aaa6ea0695fbbb775c6d0b7f79a6fdc4c53c9ab072d027da097a0d69ac77a9cab23941aa160bf36d95b10167364a0c866e44be2930199a00972936275cb9f3340812d70968a95428b3000b21c68a237961b99a2c7f62c9988675f01b1604910b0d8942b21c49e676532603ddebc39876c8479603f9360a9538679c4a83dc1c33947b5c01a5c659d30187db308bd999d68e30c79e40b631bcb8725b72a414e3be0300e4c7a30f56abeb9588fe0292dfc23c4c994ca20726cebcce5942a3b376bda76a965179f56e66a2bf94ca35090af041607c18545472db1e71af96570538796418737b048859e676480727e71e3534510998402ad13d54284b76d6eb04715934fa6f05cadd2a6cd6683d981cb5f6a884d04ccb008657f990545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdb304558423f4a47961e230c9091f0519c15de10275da4757d40edf70ce729a5986724e8701101c208e4e3bcd4341098d8b07708a2c81eb6044b82ca3868a4752cf42f2596c7ba678723931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a61c6c4009e28f6a20aad0c0b14b7cc0a01aeca507c366913ba5cadefe6656881b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = 39325b915a27e67b4e189cd75ab85f09f90259a816b188c86bb83ea12072787ce1d920bf265a004055f378b980baca30a3e3d5583cfee57837793a58dec88478f9be1884c5b820bdf63511dec3ea3f502463230f410f3da014d1f1b2074573c4a981ce5d1407ef42efe250464e60992e361b1d8aa52a7ac920a43092ea68645bd7a859c15c5da7411fa82aac79b94eb0c7b0d20cb7d3457522165f2cc4c7e3702723b74b683851a7b22a2197b49993065bde97775240dae26f2c128bb9795312fe9c7b912521168cf6eb620aee6f4ccfaca57ca71726a20126cd8df821194242fb044ffb32c2ebfcee78401386ada4f9339d504d26c536d388c981537569056fb4d54742228e5363439656ba7f5f5b7a949ae60a73891d98b0c18b5b9d265504f7ffcd4b4443c7b40a927ed0a8db13ba7dc6a1f6f65d95f2930652f9b8e03bb81deb4205e2633d4d38073397574fcaf47132a9dc686246433867968fc3c0564f590e7becf5e77ac4feca88b73bb55fc1c7b88fe0f3cfaac080ea06ff8a58d52b7ab22c344ebd3de5690ac58a12b17afe32ee420241486b70a4941004a4122906d7644e3f1da0f5b2c0cf94a8ae411ca0a49431d3d4a9e0af53ba7d899d6084cbe3087bff51886232cbc64b184707fc968f1e0f412057f5c35c18a4edf3d8c374256c154019203bc8d0191393b216c08143ec31d236c6c8cc599edfe6c3280dab9e46e5bd87f5d39a1dd3c153050fd8f43605cfa0a13d62eda8e70abff019be852f7e179d78832997a39c5f9d64d15387ed5df9d2744703860deac9d71edd8b0557c77cd40566e3a4d750c1e81cef0d6605c61159e02583a103140dd5d1ed28e8b5195499b283c4fefeb59658b176245b6308c21c64703cf5125283b5062557ee3edce4b42fc47e1e5d502682160b02d4010b4d731c15300eb78caa8c59bc7479339450647280b6414a812478f8309637135a5e95147f113f57701c8882f389164c748bfb561d0e088efdd7402748aa56c8faae61cf0c73c2a0ba7a2c9cc91e190fab3c45c1e414cd5f3a67626cc1e217422ea31f374e26cf5f38e003777bcd85d699ec6072b74c796bba303e72a996830e08503cdc6c572d6e756ebdf9c75a6dc09446d104a186e2c1de5d123a4931d13f90a9d7947979ea2087c5bfa83af27057cf2d28c932ee2ef4cac3cb330cfcfd9467ec056f4a9cf1bd376ee99ff213709139bb3694505452247cba750e70cf0783f51485e9596778907800928baff28fe3d7a078f0acdaa2cb531568ff4ea55aede535d6655eada18dba94da7ac9f3dda16a4e26780bb69ef34322b763d96cfb4366e68effd984ddd2bcf88211fa25525e94dfc7340476a4a95d356984d58f7e909072068fbb955495b8a749a9da1d770c4864156c24c54a10bb95839bd990405a477314459abeee6880bb30e8ab6f7eac5e0c074d053af6746277eb9aeebdde930e39a91673e62d85b21f64816127435de3bb02571788fdd575b7398961d2bb30a7625695fe3ed468a78aaf58e9eb841739b1e4d557d9895753acc6fc18c1ddb13ed1497a2f9da1a7bffa8ede51036cd094d720604db03a58c85af1ab9c078e92d8eedc226f4e423554147fa6602e48d0e4698cd0fa6bc45113bd7fe8848345a4e6d0bfb0124af9efc748bed49a34455c6b4b18d02dd2e719e486c20d7f183629c4814d01eebb337deb5debcdf058ea815ab556fd478f2d44f099c9a66b043b00795639f92782ca1de0c4da31b2a3ddfb1b20dec2333ff9d2722f88d7aba5de0c6414fd3e6f9612d26bbb9e70ee8dda869d11e253ba7def491c60824217bcf6ae74b9db4fe986b9aca5e66d8e4252500728dc55d34e551ec3f3aed46813c7785674b56da68ead15d9b0d353fe167e5665f4d7b331f9a535718c3f15f31d647564669bfa8735d88ba234bbcf79e048f1edfc0dca2fb5a6860293d4497ac5409fab8c026ce8ac1f77e6235a20fc910d9ef5a99a2e115807ad70af2d50eda409475813531b5464966bfef31e145dfd341693e7bf2ad51d6d1c492b67bba82b120bae325003434d01b23ceaead993823d4032b6bfe8e6134480063b48483cbd8a80abb90d7f073128f9742a4a4762c8247325c7dbfd96d8f952f8db139212c15ae1525a8611289cb8875a4f06b626def6eca35956547a7e4b097781d6c041c7e232a83da13121f6ba642e038553c986fbe6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0baa531a985251b6b10153c8fce6938a38de93f9ace7a56dc7f44fa8cbff89cd9290888da8134a0fc43ccbb75b50b6a724d6812183acf886d36ecf52fc89341938d314c761185d87592eb2f3ac4f1d2db06365709ccd7ad426ec94d4e930568996f8cca58c4a0536cd5668488715593e66621f96c87b2e78a36438dd4c390dad532e3db88dc7e2cd3c50d30baa91c98cf0bacf32d6dc81468307ca35b47abfe69e74e53467cf8bed376758f1a59270fff5f0078ff288ae25df32427d9e4726f4285c4fbd35a333088dd643cf6dbdab6b27c8b679792ecb8ba5cf8cd9bd9678fda7ebb692eca6777a2fc4ed7cf0402533cbb9a3f2edc1036df09f0ef9a626b763c3db5e49c4c479ee3a13c2c37deb6666aba2dd99987990bd1bb00ab580649dce8088cae30a5b20567295aca7f029ecbdb4795e78bf150c7954f9a4998dc219cf3e5a0e4621ee8f18c536da0b7808bdc9e12bee342cfe7e5ba799653fc669c1032aa014cb79769361b11d91b6fdd0ccfed0933c6d067e4481f491b2355e72638832ddc4f4daa18c6b4ae6f8f5e688cb812490fa13b43e3d6e5bc857fcce8a629f3f6b685e5fbb5beace871aa8f2ff07caef04d41858f144143cecc5b0c579c84fc949ef359f0b24b210cda9f44dda3217a8058469c78b7998744025ef75cd1c70a96a75fd96d19dad31ffcd81dbdb796a66e86daaedf9cd989415f7d35aedf2db50b5136b6737829f0cb1da4be31bbf38208ad1200fbcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae826f7012af634fec159c3870f7c69126b3c3105de356888f9077fc217e68dbd75e0a4dfb8adbecc556de88d89ee6efa39a6adcda9c3c61f6d874b50c163ba7b19e656f5ff9813cb318c87abbbe2a3f8996a4cb447dd793055ca178aebf455cb956443e57ce60f4788cdc6b009cd86403bc91043fd3f3f74fa8f5e9964484d7a52c92cf75e153a4978d1c0e6c8085bf5b53c8eba77a9422f91df78bd39895dfee8ffd3d9f948aebeab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5edadc6b78d90a338eab57a222fbb5a58f837c097bd50e4165aafa71e8ee3bd38d61dda90369fb769bdce60a704445da750bd3f194821396d3a9d8cb89ba6a32d37a15549548aace4646d47d66ca4de6cf7643c2a5939478a398749fd57825d172f965d4dc6cc6d7adfc46d568a53c98df68900b7b212ffe50cc5e4613d4927333beb7bf73446064d76c3b0ef84c5d32048d4775cddf02534772ccb83caa847575e461be56a7238da2a9847d445f55687a84baa06dd69d4a637efdcec0a08ebb97b541fd77a9688386983eac7779e3ed7cd2ef13e83b27b465563950abee8bba74837375638e52814448f37db6dd865c898e80aa17ea2ac4f740e93f05c3fa9c85a06a5fdbe2ecc5335738f9d46c90c5af1625779f3a329dd6937076e8afc3d0b5d7d99d3fd126c8398fbb8f33afa35888bcaa187950365f022585c3ed8243f53122b6c5ee9a95b94e51b0eedb222de35c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702f3f7b3e53555e24abb77dca6f5d5df1edaecf85e3f7e36374988dd8977a0d93af43a37e05a3463f2cb5fa2db7fe1e785848da9678e229e87db6aefcda2ee5bcdee712c690ac98c44aef61bf959ce716ca4acc65704a5e93a7731d1a380dc9534aa6e1ed89c03f8ff10b1640fcac8003235d3f4ad9da5b89c2fbdb7844e4269ea8a944a77bacb8bb6f60ff4bdf445df1503cde97686c7feb6e3c7fe4e22d30c063e6fa89a474e49db88962859fef910a4490b4d458a48ef0dbe639234c9676d9343a46c2f547aca939e4e471281ce009e34bf847e80c8f33a5af901557b3d4f9eb7084e4507449296ccbaec642470c8a51e6b7b759397f28c6e1163b0d6691322bad05fad9a5fe7d3d29f62e8eb22c6bf009c8dd3e5cf3a43e44e9cacf2dfaee496472e8ed922e4646c6ff3c532a62a718c303e993daf4ed7c2afadb7c7cbaa8ad82b46f7784a71ff4dd3678eef20cfe1b757496ab547375415e5894f1a89d47bdf06727570c8cb363343d0f4b73cced8b3d639c79b8d8baab3791cb7fa51a546d39348e1a6e126f789c3afa599dc3df94380e63d85127c201be38a2685786391d97d3b6fec35d89553e3dc1289051a39501a814cc5efe04bda7d7ae7531ae70706277f71055ac32fa25abd26ac6ea6975d5a91618476d62e311a9fa3db53582462467b19a7a7f025a3b20a3b5e183eff249c855bdb3719d5934c3be5b64576b71ce525bb2874641a09c036bcab46684e6280b5806b74c4192d0a55a54a6329ee7715c88ac3f1112bf49b7cd642553b152a45366fc925a4f34c2f97646c51511c0c9899161914654c052a06c6311022023954c28bbcc22b4641bc327aa37f494383639aa3f8a4153127f28ba56837a198b604ddac05f82cb4c11834aa19637804c6643125c9465ac03516334679f36175b35c0c4da90797e7a0cc36173eb07b8c541ab501151d9331666267adfa60315305be5345c46f628746025e7959dbefa1fc0593ac94ace87fb515a03b00bc84b66507ed2c6ae4d931fd28186c396582a56a63cc35af5ea02e980ae2dd21badb02699d69e857334b1e96a5086bddd7152bbfb2c49a411085a94321a43e1491f0f0067b06688a5ab8d0aa17a9448004f25c1c5322b8d7b6563977fad0c70e7bb961ce84cc685aed34b25f0d30ec53a7a5ed943f6ea3dfc917b01985c609c995f765baa071b3749c89346805550ba19d958c535627e606b2f0c2706632fa466504c267dc7805e60a0680ecc158d6b4f75ebaa030292ed12cceab06d5c878cddca919050cc386386f5c8b3679b254959a06ebba5520646e65250ce8b7cca03227d1b43f49c9e9297269eeb64409712fb868cc47b406d9425868b6a304aa46e472acb0197a071ab9d1622861916cf31afc12466a4022a3a635ec89433635bb0afe2c5f73670ba532714803b1ed473608c5e00c1ad9fc90c91281d5e081692d85dbff0acaf5579e2b1b6c5c1b61c3579cd13a7c8011cf5c19709366bc9676cbb8b2271c784672200e6a0254bfcc9b6387d42993e275ab2da100301b11f7e4881cc5774d2f849e3d3ce63639ccf303a7f7914287079c6066525a4870b974d3da72a9290b96c6846eabbcbac2b730849a9b014100adb9c66d0b5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebbb136907a02eb5a351c94607fda4eb44458c9cb8b50da190e307fcd63885463523086036c5655e8e2621d4516a39084fa5b4f9744a921f497eee3a46eda05a4f1481ac5b4b819a66753b5b75a95640b0cfa07aa8a2033a8f51cc526cd1be8cee5677a78f18af9608da3a565bbe1a79c58691a45ade1aac936f15eb238bb4879af7da68ce2a106031a322c198527b94984a16d9b4a55bcb59e9eb4b2068182cc9b17a8cb2b8a776206b59258a2c9a19243c9925fb5d135604712baf09e2cdcbc6ed11fdd530d83a901f06c166130b912a53c075178195662d9212e4219c63271485ffcc9aaa6222c9aa2c4e64f5d686bd4874aadb456ed086ebdf151eea4be6bf57e2cca56edb04c0e68aa4deb1580d005d9da4fc1943c85f75208d0ba3b517f89a82a2fd8bb96ac07836391b2dc3b6b0533f0d91e170986cd245fa2a90d6a345679377b767086a1173dea82969fe3bfaa643af8f98b97a8432afa1a8c748ee7055630812bd2d80be782a726743627e707f7ba069931c9929b37a9b0b04bc23405e5b890700dbc419bbc635c12c390e0a8618ea01f2abc84eccca4b9f576664237355a40b7e931195b606c6759848c33a002b74b4706266aa93fdc2054d95e7ec30f1ef53f4730af8a31a757a55a9fc69765f67ce7ac0413dbbb12980028baa2ab2a378a55a283a6c5b73837f8462259c2aeaeb36c7be5447ea22a85a561e2477742c61dafebc969ea66ff992455db36b6029d863a8b896057251b8adc659f294707cc643a91f3aebd594b2d1c3c1168b474e011e7a280e316890d467b77732e48c7bb0216381ac8bbbf6a7d61b90c9266a33ec7744099b2e4d464f1a11e1d38883de5c89371585a2247c4b80110566817808e52dba03061848fd6338cf03992c1ab83f68a13e75c6565868dd419815a19983aa8d5c4123109a34fdcad5fbc3c37c87d1d4a6b1366906a97099df940b2564f00e37760786ef28c7896c09d04c0cd24820596e538ee3876b548667cb26dfb6073eaa5631b92c4bd05320c923b53552384d4afaa047a2241416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc4576536d1bace29aa7c31f7681222ddd15a3cf6ea6bbd3528d2ec8610d68d13471600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = 3bdda88aaf866064ceda7b317ae51b6746073e9fbeb38608155b75cfdb558f0e5f5c162c48cce778dbdfbdbca7b2e51681a59bb262238de3d4bbb812f7b0a58aac58dfe2adc4fb07a9f22809aeca5fb7c0d9c6f6a0d776990c71325a176e86e5326c599508e1cc4fe1e6cd62d991fd591111dbb553fef6f44cd11c122405b92c4eb814c91d9ab28cc49cc43570fd2cf1948b558209e74da1d221b3a4fef04b22dd4c0b200d7df252e1083e4418758e92017bf4e59be135b84a6ce14402d0731850115ddfe15af373ed3edc382393c38cbe579d28ef9dc7d9dc7a9514a4f84b7add3fe6a65d80e8ee9e084fae2eba4a3f26223fa94a1ab237d158da8b10c2109801be34d4b4de815996928c9bdfecffa52a432d054dd3efc775f264c682f27e309f6b45832f1797d393c77811564f5df892f82617b333ba5f1101817a8ca9937a64ad9044a28072f748ed94046b7d5d3e415e5958cca81c86f104faf5b85392f48579a082b8398029f82f17314cbb4a5c2b6316b5ddd9b2fa1520ef0619b3ba69b16d2143d5b46e829d3ab62d72c370345433446e98965c04011c3dd4b4d1079d868aa7c6f7a3b977b8201c5df17cf9783374199c2d629055dd03a3829e1e79ff41183a97c8ad42d283086015359015da9e0173ffa99d33f73bc1b62990124b3b6fc1f0d2eb45733079d25fcfeac076c648c7500ae14b4d15f4511825eed307a0da06e8ef7a294985b02ea50eb7c763782a712887ffc6bfac2ef3f1ee6e16ea92d70cda1f63a298cc9cd882db26b4870fca0c47d167f78d470cee95e03c76a589ad3d620fce2bae40857b24708cc5d7e3a62d2630870793d38643ab2011c2299e6b5dcf9ec0cb1270e8b276219a2b3cf7ce28a877fdd8cf6e758de1e49b13afa9096ab6a43b5fab52b12aba0aaae8e2afff23cbe63c2c1488f5213c7eeb46d9df443343c810e6d2645cbafc71ad920f13563a03345fed0335f838cf109a66feafd887c3410605f65f074511cb3e80eb456d344dcd4f79531802f64db35b3608fc5cbff5614eab43afb77326d7e0caa693b5969102562bb138fcabb89ca44c47c3ab42ebbec653aedd2f45d9e12a841dba293e5c4483509774d5daab33dc4f132a5c4dbdaa19af73c16137c16010996248d889280e5e1afb1a5c962f73fb797b8abcfaf505cf8e21699d2b80d310fbd3b053c1a25ab5ca288f49a6c4b672d6f3b83973681f51cd94bf8052fa6e5ccaaede64c2253bdec403c35e1f772b0c9ae00d99b35489904716cbcbb9a7dcb19b30bc3d236e8997ed3a49b6621046e1fe0681b89d3dd3208c519a4d2ec95d4493c465c3f4788e7cfe21ec561aa5a026b6846593b8eef6dcab4c04e5f34333a56c0dd65cc6c151900552f0332caf8961c89532838a61db0d5a2d129644ce64853baa0b390f3818f43df5333ed6c5c035844b8e1ad8c13f68727ed0e64e39df6520fa5852380fe063641847089ccf1ac32dec22b905b00793eb542e391eb3daa3919443be7379ccd59ba76892b27d8d47cd5ccfc6bbeb184c937e58662f0658b135a84ff45e98c14ee6f4f5f078778c93587dbdf00690db36428b49f83e0c16420a0b7444cb407e2e52c3718cf06803d3ace50e4f1cafd22c2b5d50bb4d13895bf8bb33e45d0017e142640ebafa5240e3768463dab2fcb76b34303c9f76a683e755f1ca001f5cfbd41a2ea3763213c298227ab6f6d64858ef688e1040bb6e4d621fed4b9a6aa7510feaeb79c970007aa29b1eae1f459a1b381ccd01a8ed09e5fcd8a3a63555a2dcbcacae0eab716803da8e2e018aa5a56120cdc85258588481a6db2fa8ac9d88dfd21f8ceb85c9ca22bff56147b8cf31dccb8720ee81f7ebab1306237992652a8674a15b969e61f1a9582f989b5bfbb98c46de614d429efa46cb1752fff04e91ecdbcbc5aee7b53938ff6d10bd8bc0b54fcdf09cee0ead24daae0288bced7fbc60a5cb8a249f0057d1a25143f408cd2782b6ba96e39c9529effb0eadc7b3f9cc3ff46c576e001b38fabe06ac3032b970caf1fd581f28d965b70a82ea3bb02108b003a856e7bddcbe3283c33fef8241c7b0bc2fc5738ea5e9d251b731ab2553e752ab656ef624572b77b03725241d6374b67719ef076d13f332a80fe5b0391ec95d2390ae70983e7fd3304d5b408d5c9f8c00f41b6ab9fc6889683342aea39ce80b33e5223073c3ee9b875f8888 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e1dfe21f16d48fbc565fdaa3063dfd439ab3a81b31fa257aa604f83547c14666e0af5ec2c1c8603aa36d1575754a86c9195becc6a9b8c9f77ce6484c5198a193ea4369293798943f7928e42f849c8d7479eb0588e6e6b4abc4ce81b4d66434e4ec4e37c2da905ce4ad2b85de7d966d34a3b1bfa8ca5d8d70457bef6d5b71e68fc9e2efbf9dc37ab61ad9e797a43f66b27b04c13c034fa6f594264c9d7da884c86fb159d775f785da197ff16e8bc992c9b2e1de851304dadf9bd811ea89d2a69b66d34e59bc93f5c7bde35e40a976a3195541ef2fa7edfb7f9d647616c3e399b6c9251fff047ff5af7c34e7eff1213ab5f8bfdb9093f5845f66da1b456f5649b895bb042e42fc5c700cfac4c2a44cf1f96d57b8ba1fffc9332a612e8bb9043559b5567090873d3f9450f37670b473a9709efce1e7e892e43c9ff6efa594601a27a98ed8e7de9ffc625b98e0fa8f2d5a311a87a6c23b4dfdf44d761e373e64a4a18a833d654a947bdda969432a0f30870e3a919971cc4c8a469e6901b45c26cf8eb615e600644660796935e65a480d496bd3f2053ded5c97d8fdeccbfe949d1339947c6baabcc67eca0e659e3fdfa5dea3da1a4adc3beb323bc4cabb6065e9d32ccca3dd3c8689c9a3591dbcb30b99b3f55cf2ac8258c5b85c696a372c7aab6bddd62aba078d4466fa4c23bfca0e09b7d47c4644898aacf6899c79b5332ee0f11dcd40253e40c5920db980a58cd1b55c506a6662bf1f53ff27e4139fd2736e39417d4f63f7d3414e4322b69b60c5dbbb4459c1d6a0f35d65da13f455598edf678505f54b527e3209565fc59efad5f8a05b9f6340fc38547e9147dd49017475a0aaefd2d47b3547ed715c455debb3a40a8a0e93f47b6b8ffc05b2e857b5d9cfd1e57ce09ece55b82db25293d1c59f37f7b6f9244f31fcaf5c75e6d0bd46d796a68991bc68cafb5b0b7c748ac7d39d8c4fd1b3b4de76c1941f3e511d9ba70956b9556f245ccd443db888d43a857e4e8dfe7e5713b5ae5a9fc3a331719cf27ef4bdce23ef320f8d695f9f07bfe8ad3f317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d89db0fa67cbcf36c0373cd56c268e0c243132db5de7365310f573225eb80bc98a2bb76f9e8c6170bec90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834bcdf2bddde91c3fe4e7aab462f49d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c868f3928877955cf8d15fa2c116bdc325b688df6d1ccb3386cac9bd5ce0c3ac381e056f916dc89e25a910c78e677964d153b74554c8f38939f98e54409fdb701e989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c65ddcb1bbcffd37d7bf1fc31acc9b5c94b806c7edafbbeeabad87f0ce419ddf978fceb973336d27b69af2fa85f6c33b7387dc0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a45f8de99cbd7a875bb6bf99c8a6dff4e6104a59aa9e958e48f8d3c75eb5a9a7e81d7738374692033c4c78f54d527d204f83a9b95f0016466fe9e89efbacaa23ab8fa6faf7d66aec3ef7e468b9c3277e1673839551f62aadc49bc135ede1e792dd9678ead991b0e7cd1239df3c9b21c5762346fbbc128fce71dd217f6ab0eb9ad6344ac71aa30048b7bfbdfdae1e9755a1d9e45b5a9fd15f594b4ce4c5c73fd1d5c9c8b63ccc7331c7d662015b5e46d57b4d7ee4b6eda55eb7fb039cfc9a8ca4c1dfa50966a158ba7d5efe449ab67dee747a7588b4a6be07e15a817658cd579f7e858e6c07ab3cd968c425a3431f65e25496fffe96e2a2e4445fbfac1e78a6453d5aa7f4762ddc51bcdc19b0b4839c94bc2fb5dae888e0b7975078d6c30ef7f204f80427a34bef364401ffd05866bac17595906438c363c4d53422d994371bec8d2084d26fed1830a57be5c754196b75db44e859dd281db3829d8a0fc5e9ae7c3c85475dd0aef32d993af7195d1f29cf92b59c3f0e5dd50d75bad5ffdbf23ccaee4466556a4cbbb8d60a3f016d63f90e4c84e1fc62e5bdeb0176fe81ef530b5baa8f531618f41117ce78696d0bde858f9a9bd6088e65bb34fd37f73717b5cc5e4f3f19caa54ca4850ac896e163c7009e5054fd41857521a7c33d6425e068141b06c2ea57a010851a3b30ad021f6c0aa896e81f13f02d341faaba798a73a96d0b66b00bad5119a8d44797a1218b18224657573c9c556f5bc096f057f72fb749fe41fb9d290e76801b3712faadc58a1d3a8aaabbb996277d6902707a21ee099b5906854d2d45de78c1f134293d3dcced2296c5dd6b1469ac91c2508008951c7fc23eccb9a97f23501b21a625107a9c56ec39b724189ca111a935c3b58f262a29ff577f8459c74d9147dcb8eeb8689ee35aa131369cb805362289ae5973eff1420a8abacb650a1683104d2d82acbb28e54205404d68292f99c9c222bba8045769b73b890c33512c04af0cd86273234e31e94349a322aa13254484c3b99a2ac01f6ca00a77ba7b78711c73249eac054d34a1b0718814f407fd9d62a5d48212fb3afe5518e3a671bcf2cadcf4c8acb972603f960f194a4214cc8c9941fb31a6093a34c102ac18c26ba171a048d39860eec35e890149b9bbf510a4ff2270c72a507cd4a0500ba593841974c419a7ee37859a76f02463cb8303489e61ff21492afd03124368ae02c794642b7fe758f76219128ac75f19c41ab01adfa1a51b027c16e5b15279587e4f4a929f34ad51b06a060058521af6e4a24d54920a7e60c4174baec0b5fc4b498b23711c92bbba383556ea6169f558f5ad29443012c5b82524cec7ec43a448fe57d88c4ba220b56ebc2bf90a2471bc735e88c2e73a8771d669a1d76566ee80b78410d7cc02407091f4b6ac97cf2afbe67a02e445eb51389b8233080d42e74e20650a514f995395f8b23ece04e2a5930294b37c79aac8782ae62dc0d7fb60fff5c8d54e29fdda87562250a70038355a70d6bc0c3720726f0586acdc727d993988032cffcd5a9b909857be58c3b6a7c10041976a472d2bb7d3a0932a6c0cec9b68126b98b40d4041f5439f395cf6ea5213d39c69ac91b85696b009084e662aae8053df014720b5759c5f81b91f296bc4103c7dbbbb6248f87e8543e8a660bd6bbb9f81ad5721d7f36cfc776acbc8635e1910e4191730aa68e5e177d2d2234a645768d26cc069254daf0c94a09414a36a3d19ca05a5475378254ddb0890cab0e686438461a1d499aba23eb3dc2b61aa6a46c4afa2a262c6f09979f01fa1a98f62b8098be6416c6ca5b3f8ee79e28c07cbe2855bb64c88f67947a495e87f03361080cfa3c2aeb2791671729248b488278c72e85ba2dac1dd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb97e0274975323a7b20d27937f0c785152209060b05088243636039808c555ce29fd18a449a9a188afba922650f17102fb0a28381ec046164358e344fa250c05df6be895a5a0566b409f893e9d99cea7b3d71eac7a4d0081d951eb755cd39215c60c1a21de05217692bef3b8b4104608d198ab11c4c30941789919830cba4e7431dc127ac770957257c19eb80595ab9bb9d4a0ac266b7a37b94bc517139c904595c327f5c1430ac7d7e33bee0ba9c7bd7b266e290c3645821542f0e0a920fdb72707544a6d10c8a4c5a46148c2458b6c5ab06d42c2d7db03ceb0c00ca37303c67bae0038e0a373d539b918737116ed029a4d78a71d74f770ca53c9b4ecd19bfb172299c55a0cac83fcdc8c74400c5be76907679b48e0ac041987f96754588b83722b49159f92b41b82e6625a6108a957c34b2d0e30d536218acdc56a093ba9940c075362c1028c6ba42a775864bbbbabca70a5b7da5cf05821a9a81ad022784202362e587bce2a5b090530be4c51ef77a887af373637326f436c891304b72867dced161c2f0342f23aa15d69fa887652081a9c42b0669a689c5fa77649bab20eac8a16a51759ccd0f86c06c610a88162291e6cc1d911a88fa26e7ea4a23a224582807f20a8f1e2202a92495b6393036a25d4cd97fc72a741e006b7e919358f6ba3c5ab136823ceb955382bb6fe3f61b6228467f3c6f5de79531f11fe4f268b7f50f662c85a49b36a7213ae958a14e9bc45d0105ad13c591aaa7f1663301aaac45427da3c6a8873ba78e7c7473d41bd79534df8145d1749f94cc9c82377cb388129d0692f839942830c5814a8fca410e4cc754f7315fddc20fc1d588ac4c3cfe9c40277b3f6173809dc063f6813852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdeea5db7a82254d19c0a0c552ccc92db9c3eef74cd73a9937b7b7298171313f120e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = b9fe4bd50912df5228e9eae3f7d3cb113b2b3b80ea792ab437b9018fdefc174659f06d6d3ba49321e01685676d1306c2314f28aec295a9f136ec94b05dc6f333c886e02da664f0aad7877e84070f9e1ee2885c490630b69ca33a37e91b60f3a494242abd1cf1ff456315187279a08711c3f2c4a8b6718a031c2d1bce161bbec45ad8074996572d4bb2ca26197db8770243a0c6bc24e5c91504cee5618df95637f7cf913e062c12ce872c0ed43a38d4cd5f6389156ff1aef15e65287970f5963feb0e902f28f3e3ceee9cfde1140892dc69dd07b460dd8f3a9b41b34ffaada9a7ba82530cd5adc749d751d017c5e2a1a6802d955186ed07581cfff31825b5b5811542ff31ef774884d429249e4c0b66a9a35191922f302716d9cdb94bbf24692f23321a56e0797290fab5322b9156c7dc2e6e0fd9f20e320af281d7eb54f90e87b92ca5d9d7406bce4beb674db62b100a51340e93d5b47b533f66c68c2333dccb0e450ccfe02370ed5c4a377cefa3c2a69a0e48dd077e1b61d0a7af38349d0959d27510edb313ffa05a84d575f372e56f3e701dcbfc86214f5f66e7abd7a2c036e22e2521b6a0667ab623f160ded4d96f387b1a764758ab122b171c8b274e6294a6bab4cad72533e4356f3b578c05b0c5a7ee6e587d03b4c6e96f0b6e8c9c641144defa321600ba98ceee7ca29c1467d81a761438ae918f4161ae418969f2f30f8603f051b59ff636d6448be7fe4220caf2eec15dc671dc4e1d64eeac4b824f11536ae6fff0d66b49415da59dda35cbf2288dc6d5650b3685d02b81d12af0bb9ac5b1b34992c127b5062cd5a714a133583b3d9af35d4e6055b214f387485c59f8610d9ff7e9a548442229fa18f5b2e78dc2322c20023d886f32cb63a5cebd0f33c9877b3f7f19b8de870375ee386d2947a0c28b4f1e37e3cb39b5a9c9f3faae7c711bbd7432bc0ecb7b64dcc2203e8378be2b50a85333c6d2f14d89436ab3b7125e1e9392d6ee5f22a5789a49c7cea3731b513fa29e0879db8211c705d1f43a9f26559a95b30835bd26bd251fb9dc8259aab2f342f269773ba66317136f600e26bc39910f6a91858cd0afe36e5d7b54ff75a281d261deae9acd30e2882b0abd5513065aa58b5ca117d956967249154df5b8d5e2b2d458ae611014f633468981241731afe24d342dfbbf06419cf1e3129f5606336835c9501d67cf335bf5330a348b66d2470f68bd547d3a8aa7e7a4d560bbe20bf0be13babfd64c6277a772fc71eb085a26d4cdf9a0338c0640094b3c0b838d554a092b996d0eab4d6b27874a6b5b43f546f77eb93675e9abbf1daa2f4bbf76ea490148a261cf726ceeb3d9c586c92171124bfe6c5d33a6a0b7f95b09513d833fb9f47a0bf1dc822b38fb36c2e81967cd8d99266d8e62019ba0849c1d70340521025e6235012fb671b87a442ca3050c6b96283f1869854b5127ba4d8cffd336a866b9d4a6725404ca8acba96accadfc3d7b464398b67eea20b3721c769eb3a9127968dd0250e0e39f533482c306bea024c3ef0a840cdd50bc3dd57cb4c7770bb8a9e27f53b84d843a72224de499b641a2fc18b45acfd84c940ab189c3dbceccfc48f228038b095aadeecee2f805b1fb248a12c9d7ceeae2052a08c90565833dab3682511a057c420e7541f595e098b7c2724cd3bfb8979cf8d730a9c60e8a58a29ab64c414476d4c4496d393e6950e839bd9e8009f02b6c69538a0d35e619f321ca87f205aa2e5e417f7a6e55db244250e7ce3e5e4a9720156531b1d61526a712e8416fbc20a4ee2e7bbc97425dfbb4eb94bb9a0ff3f25f515dd017c4bb44550fa43aea7fd035e096d4e0056966b07fb4e2f4f40c612b5d25ab8c5bbc6d22f47d53a4964252de54bb4c973adb8cf4f0a6f2ce8d136109098ae90126d34460abd6ba895952e795b3bd5ddd4753179b21d6a54626c47d8abd4bf780177963961de0f915d0452c1a06febe965cac1d5ed0ad59ad52599a213d563defb30a4298b2d7f89e28208d141458739c719c18c9fab830f42c47ece180d458f4def3c878d7c9f16349a1a1ee157d4fc4bb005eaf1452c475c1e206ef7ffd87bc31a0b3b0486aa4e2b7129b9f69ff9f0252050a5a6cc1b1677f4544b640b911da9fc7c5b70077ba8cfadc0ed4558bf536608af410285d3da540899fe63139ad733f9d5d63d2c7730ca74f0051747d9ad4a8007a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 259336182d6ae98ec4de39eb4f269f2f5e8980ff9d3c78d3e1a4c58e63d51e879f1af333393c75b366cfe2e84cf9cc930d29f8298897480571d715d7527debc119b10724e2efe8873ae3f5bd0d420d13a752d33087bb6f8856f8def98f50efed021e321a2d3f944e9875d9ecd33c7976b7a4606edf70f6d02957ac49b862cd35640ce84e6b989201a74eb774f2f88b31c94acfa91e605b3f634199be1639a50c7d9e89683c5dbdc975e6f7b87ff3ea48a2352c8bcc254abd6d812a6a5ab7747ca92d73d1e3eff07d8866a9801bdd67a6eadd848c40996ec350db559a0ab1d91c9be1ce49d7cf41a13849d9fbfda4b9b9b30b348217491449a43ea4544467824ff954c4869c8ecdb2ba2744c8d38ba584cb78ea6f6188bcd1adf67ba46883fe6964bad03e2c601064e5f937cf13b9cd00456d3545bc5e48b6dd06eb14eccbac23bb1d17ebb14361b4c9acb7b48805b7890c3676b66df3849eb38836dcb1ef56807f5b048fc7174440d82ba8a7eff6d325cdd2cf6abe6edabb195b74efd3f9db7db44abba87581a3c57f079b44a9455e40ae6ec88adcc14368569b35527f72220ba7760a8a0508bf0043d31e4f763fe89b611366b8b93d2e5f3d5c97fbb99bbb09a5e5a6aeef128f404b7b4cceb9e462c6a5acce6c64f55ab38a763a03ba49fdf68819b6df8ba88704ab4c7bcd8f9ae50ca434ab0632add5f2a4acde45997375d699024e6792f845fcccea18789b2297d401d6872374b15c95eaba4c3cf5a8930d34c74fd444a2c87f90d9353cd77362ef6c99d8d27c5d504bc5b3f2ccf7f39788231e3e13e7ee19e3915a9a4f0646aef6e5e3e155b41237b2ab08bdf393f2bf5cd0707cdf22854d080bb8ecf58cc9b75d1abde8551fa74b3c7d62ad4dd8dbd7bb47e56c56f21b7e83beb9321c58a924048ab96d32f558e5da1bb33ad431249ec1a6778d917db1a464faae33eaac97bb5e2aecf42792caafe314cd7aba3a8c15db5d1bf4e7c3888a2e19f1a7bae926044ab865935a2738b4378484b44471eaf50f4e925e976beeca9f94de91b0c85b487badfcec4be7c7683d5d8413ed96ae888bafb97cebe3f66ef7397004cc5684ef53683034fc31616ffe6bdabad29dc5203e926aa94b2f2a4506d697066f3e3057e76b56e69ab8a715b84848bb4fb993dbe744cad769edd9eef8c1b4df8a6bf829b9f177d73cb103eac0f45557a69ad89dc87a6b8314f6e8454d81c32ec07c4ba5c1c450b818ddb278770a1ce10dc386fb94e1d4b983503964f7b6afa10ac5154ccea9f6f22b4a70e5175f126bda841ed4754eef8ef84fdf3aab6e5d8b313a93c29675acfefcdf5dbd4b5b7e13d7f28d9ac9df569cc1bbc995eaacbd2f90b0293a2bba70ae8757c5a7ce84386094fdfb330e573c56bcc368a7de4d4371453c398f3ba485fedb663e5fb99c5f9eca9ba94caebc9d60a6318c06f268a86c0d4e9cad1bc4ff5e4a745bb2c827d1b89ba371dcef10c5dd95086d997783841d8dfed849a1f74696464aa1d67f804dbbc6acefd907696e7ff7d02d750d68a3d36c600448c91b5f3a16e5c84c4d819bcbfbfacbfcb03b6590dd65705ed75205fcfc9bba4a3a8d09d5835b1540f5dc673d07e640f560d51eb563ffb048ee95e5c5baae8a93147c41d9ff82128b8c466ed0865ca55516709ffb8f34efdeda56796324b6f4bf49da8fc7d49a84ff076be2187dd4b5eefb5592f9549a27faf74969d87d4cfa5f2e7ca3b733925d5de8aa664288b95926ccd90f8bb7a7c2466fcf2bee4fbab852521978dd05bfb52885d8c86cdb6a8df1755f8beefa7bd7b00b2a7bfa49693646653d1c50ff8f6cc9c39989ef5d316975cbcf6108e5b9570979dea584330dc346e4c361edb0f6ab71397999f4bbff7af368d42e8094dec69863f2500e6fa11c408adcf11858bc53d6fac6d395898b9a02fbdf80f5f8413eb39ad5409dacf8ee549d468efdcf18dfc6bb5b08c5f6a625e73f543b10baab509f54ee7b7690c758d2086155acefdff88c11ae4eefbf917fe47af7e6325adee54cdc4df1a56afec68855fca34155eba706e8e9595f00abddde08e841d78bb295ec3bec505c17da8d9f41e55bfa2f76eb073f3e62365a90e7b5d1eed705ae84b1d5782977e22d9864eedc852e69f862dc868ecfef70b83d3a58fd0fb39b1e4b0c22871afffa785df48224d887a73cb9b9a68aa2a768b3ab087bd9cbf6253378885113bc6168d631121a5fad30cc822133161b0c39c0a2b30c5c33383555b415c6fb0588d16b3b890894026bb507d080f93e13327707a54725a3a859661e49184025f66f2eabc07c5072a21275440c9d520c9d0570cd4bf8752dfb37ca066ae450a3e5e6694b9581f6195b4b580fbf55b9f933c6f9867af36786fc8c24ca71b47127aa08798f99b113c1c661483a6ad196028b7752d9d4732622934a5b05c8b5095789999796039928b453e480f008a4bba7a49aa65462d71672450b56c441d2440fd4e151c9d0518d10534f24c1a355a5fe3aa1c4365493c7ad66f254300c373ac264b3339f3af02e2736b8023a270a20babe69cc15d494803bb515ec54719619bacac9ac2a58a4e67fe303ad9565b33c8472335710e0544c4a96bebdd98454058413db3bfc2958803a5963c725a4ca074ec9383dda1e892ac9e2210a60d19d5e4b3471f9519adb6bcb79c16742c07e933767ea4b20134ba8329c0c026da0e8a5e12770c8ba4ea7361bae91af0f953b47032da6640f202a8468a096bbe92cb8b02cd524b38a7a4c69d5b9818c8b88da78a7f2236746217a75a1f6e2805533a17996b7f972939a23c75c9023b715a714ac346f8102c2f8a04733495a4b456f179372202477e60b60ba210365274a393d999390628c7f63d2aa2b05cef68776db9150c39b6eca9ab32da9c6753208d74a2e7911af644a028d2c5a68494ea3da6b08a5b67d11090c587f580800e04c942445bfec357e33388a0bc328808624e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b350cb557bab3f87a05b22edb886812935402915e5ea51f41b70dea48aa2aab4f9f247d3f637efba51120a258cab867be231e67675ff29c83bf982e7b15b766a84cd9369ac28c29af664f5c7a7553ec9a0c3285caf26ce0b9c84d504ead34617f303f6d0ca807a7c0da1388f7407bc03c3111c8c87ee158e68b53ce8c668e8343b2303bcab6a4d98857c7070bb103c47c60cf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c38f028203357eb2a37967a60a95a1dd22b15f3d723f812890ffa105f1b9b2a238914f39975c1c0f49244e4db7728e15329f2ba8eca4cbe7b76029c9a6f721c72e27149807ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b37007fcf8486c6c5d0ffb3abed3cd8be0b87d1b2c80ab2d3e40949f94236e727b92e83a9ff0b40100b200b6519be545e893b60d09b881c2681d335f9f501b0910572645060bb8a141e910e6aa582f652ebaa79bf2f77b373459ce87c474213ef0257295abc192c05bf31ca3eb061648455fbf82710f8777636c229ef49c6986cba9816d11d636186b62d2b06212932e9e727954530182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968243289e1cc8460130c034b45660b3668863d719aa9c8e11df72084ae53c3b4d85a7860c42b2482c9a050b1065dda241b43ec996e368c6c7bcbab69a433040e56bcbd4f167a9d71c5d336234ba4a5e47a956459b4c0477b4780769530cb6c9b4a2cb6aa27423f76a58f89753196d8cd99107ec04741be761696c642cf6443bb72c5dbd336967c336672aeef98af9b203ee6f4096531034f890b1dd0862a0737777278167a2aead708533206b3624b906c57e4abc42bf61364e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f501104b9240cbc2c87b0531f6e008b38f1287be901af59a45ea19de5b2c4ce78ba4eb1abf4284ce0ea22f18c2a26f428bba481e54a1745702a8af06cab649bb5c7aed2342413157a811a35b162b6f444cf2ddb22a24bce8e2925d83313d0b760017b65b8867419c7a1f57cc785b26bbed63ec79b83feb60674e2497b87be24aa1f899ca59d6391c1f2ad9aa90806fb1c97dcbfe5b9934ba169386759532b1117115e77884623c84cfee522bc0735e1f34eaf4b452530418f652e6f15cc3cd88a52e98078424d486cccd38272a0819887d85811e6bf8dc3689a3112b1b86d77d2bd91a53d123a11b6eb4ce3a8471c35126c017053c8a8f46054bc9c92752631ab8a9100b04f79e14c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d21972998cc3abc79487ca0a4db5b17514e9961916d30ab9b500430ba748c5c7922650a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = de22f336102bed90db56dcf3c81080592ffed51e0d542b585cc15890ef83d4b2137d9a2c2c9d3b7a5008f13c9d9eaca44a97774491e0ec09f5fcc60f20ba8e727de47eb93bcc9c62c412c3f816015d39d052ce030da88e95975285220762837bd725eb1a5dc89986d74de1315a7f52d8bc763eea041d441c2629714560ab6505e7538a444291b61350e5898ba0d08cd82b2f7a15cb0c7961efd3e195a050619e6af964b2b27f55632474d257c7f00bc360a11187eef5fe21eef35b00964bf760693f179d9c086a21899b2f9c840dce611b4cc27ea2b1822efe7ee9ab30c822cbe90e37f7fec7b4dfb50ed0c6dc187fa3a9343e6c0fa0b6e6c6ac80d92e995999cdd5eaff5aac21dcfb45d195ac9d4e1c53696346a762d8a013550a882ef8f56b0894c3ee66a3ae4d0ba94f1c6eb276880172272ee958f44378ba23c461a7d79f5984364e1663ec4d403efabfc9dbb617c7c350ba5de146316b45b5f4bf06dbd3f6cb4ce48dae4025920cbf638cced37d9e7df698d1736ddcef51ea6dd0fbd9431aece193199a3911faa4f4585b88ae0a68f3d59f68766cff57dcc8cfc2b5da676af40555125c8b99ce911b41d1d44ac4b09aa5ef235f1c72e10c134ad457fb735db7202496807000fe76ca7221c72255d82fd538290d092fc518eaf0dc63d4079aab51fcd2306501decabad9d54b2b6313fe4d1e8585d55eb52523ca1451fa5151bc378637bb129e59cf8fa7192048672824a90d7e53b324df2d1cced582e003df5de8a51c1c7e14c63a83c2fd17a65c92d3be640751decba18aed1a47483c602b5f9a136c2a47c39837a84d3cd4e30e2d38b7599f62b2218a0ecff2159904d27d8cea620d873d00a96714699936ed0d1b3307c8b987d199de13622d51fc3342ab58c025ffb19cf90b42981cc86174bf6bebc8777f6c66da5b2ac85c778c6e47bb7bd60be9e17a7d7a3377143c36c876a15d115ed1f26353ee1bdfaa870dcffabb7a9ef8fe01067f93a681314e1ec0c8683e237433053d89879042f28bc41e7963d7b24076c40125aa65ff080a41d52b4059b6f01bd6b5583be37ddca124ecb8d7d68446acd30c2cfa9e696ff1ab4c0b16c86d4dc391e5c081d8b982e14c8ef163688591fdafe9554e45d286378a8ab2240ee550241efd0cb058edd0b4c861ffa751d0b69335f57a4bcd180a5119a3b76286179e04ac93ccfc1aa36d0b83320f9dce518802f5e7f4bf29a79ba3671bdb130ec01132b9fa24a2e8ab5058a7f790813ed175fe183c7c5393594488fffa734fbb154041bb569ccc2b81a5926f522ed4fafa4eb35643fa2c2abcb1e6559da7938714cdeced33b0ca4197f00b6b0cf9bce07e4138a1563e78959ad985776ef5af16bd0119f20635f6e6706a116d82a4bf1ea8dab7d3c47fa5699db9b4b006d4a2411f64645937df678e4acddb1caa089b1b0dd497da2fd4e2cb7eee47be2bd595b1dfb1f3fa0032200db31d7b49d7cb5b738e61e3e8824543548802342ffaadd4d21af36f65640bb1b42f2cac9063d05b334470f996fb13d0195ca47c675004eeffbe95aac706b27ad74d1e741e4a12ded0b4b1ffba5c09d3d9a3dab9a21e55fed670cd408c30516812e1729db8b5262e2fecfd91df70392733ea049d18aea68a02086d76f62b5427d07c40100ac75f766f4e2eaa32fcc7ff27d7fc9a526835ea0bb1a5483c1429e1e4ce370287173fcb0ceb8209c2496581d4e2ed15034723ee57ebc6a1f211a6fcb35e56f9348c2b83ddec9a008364da2b9ec95024a8f9be28f551509728d65b1ca1e77d36e9e1ff47f5a98eb569bd7deccc3263cddf76e2ca2b2019334fc06db81e82a3174aa8930eec28339ca30e5cb6529ffea5d0a1737083d9df4253baab48bbb8523afaff1f7c3ab8b071248cd888e65e92c89799a7e27464024c2f7d94755234001dd8749e913e91fab6ae3a3de7244126edb48ab1a85a21d3c19e55d54d468911c46438900844a6a50a9f28992b43b8283a02276c8dd4a6266f476ac7537afc03b6264f9bf39b8f9a922c85a890cedb11aa22344a7e17a7da87d156c26bc309c24fc3174899f9e283172048bffc8b1f1e1aecc2ca1976cbf83d482fa3cd4c511b73e3c45a66eed5db3fc1c9ad2ddbfc63324dd2a4a6350e02614d2cfa96429f6d7b703f4452d372fa53bb8304527b3edbef7c13cc91d44793a4e87ec7a034f657c6548526 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 719950ed1960ff7cfd7d59bbecb83aaceeccb569b76cd9b053389c552cb6bf847cf40cf019ad3e670dfddb284c15d656151644f78caeeafa8b12cb7c626f56c13fce621f735a84f85d66a90f3a745ed8733c195f6b1b9b272897521ad2fafcb958a9669a9db7352dbcce373acf6aec86a555c3c48f78166c0fcbd23c496086aff6116d884c4d8c9febef4c0f3506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa33cd1ab64a6ab7491d513d3b4e8a134086111eff0462395b9d89d976ef05aea9e1b88bc80c4c8bac44af5fe886ea788a1bf59dda7811615e059853d2ddd73ed8cadad9ab0507e75d57c3224e953509588e788713d5a6715ddaa48e972f4fa55f16579d9bc6988f562cd0ef96e87aa7869f9c08f66d7e340023cd221736c3cb372b867f3042382092545a55d32ec7f7bdc85d449c786145acf42b85d4618b0d70ddad12f4a8176f0f1db67f5a7e3091bd849559a51b958963fce2ecf5df9fd9aebda932073a2ad3ee5b12c5f94c647513fdd645b34c14ac1b32d8565377d624f6d7f3af5cbd969a37d5ea43db676ea6eefcbbc6ce4ddaacd716d147b398b7d469a919d83baacca80f0f4e41448f805bda32146fe14e766db2450f599963dcf899f1d48d839754858910e1fc23fa9e58a9a314946f690a9c5550e33e60fe8a7b66b0e6f7321d8e0f8de639cca948e7d8616047f85ba41cef9f11d07f831bcd987dec3149854b71683faf68179799b13cd31a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c04835958eca7a45cbaecbcf354d7d8e37873308e3926599df6ce56a94945fc7911ebf6bef27d7457da7bd6b60f87ecc3f396e857e95ce26444b74ef91b468fa1670d018494257f667aa76e42976fac48e78da72ef1cf07fc740109f699b46345e4c9972a35daeb3eadbe87980438de50fe2b005c8dcfcea6eecb56d99e67709d16c49385e8ab20a19b74325a9aa5d83bd8ee53758ddb317e9815352617bfc582e979be4f680be34188a75b9cb303215a76a246d8f69acbd173d06abfb99c7f7829aa546aad213ddd6a88aa4a6c6e4674674fa75500baf94712ce78b84eb0285f80beaf7813647a5dcac3a258991db4bf436c23f37c6981e5144af755fece99f03fc1a2d9d7f09d5feaabff7383885cebae4cdcc21ede9066653b9acecafe366567c9238785b0f0b4d153fa9e02ca2d9a3b37d84646b157684d7ac7217f7af4533749a9ff99bad8f3877dbe5cff9c75b38d4d02178ce30773ee37ae4f1497ab386cb375fdf04d85c841fce25b357d41d82279f5f6b85c7a47f906408eba66336164cd0506bbfc92d30f4f33a5be7330926bb3f849d1ddbd9f5cb814ba8a7235d6d0a037e6fbf6216aa3c4d5cd5d5cbcf0358501936ad2beb3563c341e33e5de6d68404acab0149bafa84491ab67a2de8f9733fdb0d05f9da7c4d441c8cda05d9d0afc0224932e7f5f1567faa433c92131ff899e43a93cc7c8f4aac6ed5acbe0e62e4da4b897b7bdce7fa0b3af35406eb6d3ee08adeee4777e5f3369859d3d21584b6593b5784344d53c4dda17f5a918d4c46edff6eb767017e660478c5338eb5e39dbfc77ac4670fb531be300628a7a50fdde22768edd699c6bc5dbdf6606414ee433f9606ed6dcba4f0731ec7be04efb25daeccd9d725dccc33eb762b9f442eddfae1555cf726a91534d509fff7e37da4932636a38d6d8a6ce5a40a3206ac91bc8a3cc7245f7b6bd438fb3dd0eee2dff7bb022fd088ed9abf5580092dd8d43bb86206f93726992523acb1dc82fc36de64dc395c778d8ea756148fc9918b531cb8b0fc8b7a5a9634d3a7349475a8a117b0c243eca0b7cc8e5a92f609b5b558435e15509fd78ba747be495b9e78bbe78b03c117d4c67ade3d5b07b58eb675a72a646763a9358b61ef3eb1156866cfd7ab6e7498d3e5ca92799fda467dbe1d3a5f7e7e0f6b92a815546f9cf220bfc337e86142d8ae205594bb2c93e50b4503d8db5ab3a19de4ba63e9e8353f60b579f296dbd2efa77eae0d6bcba9d13f3e7b5ee8d2e8f5f09d87c7e584c1de15eada436044caafd0033f51f649d275a7bbe4455cf8d35a97945f597d04ae740dc576f12f5b8cac3ea76c49f5d6a183f3853138becb6949a158a5ec045512b74016fb841c8881035448319442d0786cba94aa139895eba98bff419a6b42644b68c5ce534b0f705225f4a7b28cbaf879b30fb633fdc2aa70c54639f180e76b927ca4622f086601a62afff5335ffbbbcb52075ab7681a55625e01cb31248e17708b7d728905b64976409d49583272fb6208e06ed7539fc4f87b1f0b821de4155b79531546824bb4a13e09cadf66b7889c6baa9679df6187690c9fea246226a7a405b997c322b4ab041d7fc0b24ab54400813a29c87204ea29414a7c80ac65d374998494b914467f44241251402adfa34616b021caf86b2adc690267a41c40b763c11506b658132c59c0e887888a2d5a8658bbe403758c84cf86611026a5bf802ae4e5031771c42d047ef42021a7c59c2c0a6e3f10b9adf716bba29d824b271d787379021ec44b4b39c3493bd980bfcbba73e5772e259ccdac1f062a887cf25887c30817da33ac19c2527239e7f6b434f0affd278130b1a480348aef2998924c684e3ca8f49694dfe149152b332128061c659cf2c5861ca003d1e8bf33dc06b197abfe2862362a9a15fb35f6009481d2a79eb18826581abcba4bbba6846238c5edf5b30d6830437714addb5f6751a7f6d79558148c0db07a7b2a784dc78c8176a2a36b4dbb7855602742ec2624d6c6c589c515b5224ebf92cd70b954c5190e4212a0542857a16cbffe060f56140e4f3b2e03b86ab0c8cdee1a3e2e95cb43c852c40b6cce660fe61bc7631a849ea28e6c93203bd55c4c4928d6ca777023264d2b2f96f99f3bc9b23d51ceadc713572542eb00b77ce79b2f0ac533198a60f03939ea1502e09807b5a7c19ba98396167b116c88e889b022195b016c58125de60708890793bc582717253b6608b0933b0b0d160c42bc3efb602e899555265189dc376b15c04cf5348753344f0e8349b4ea29a6b85110f81c247029ffe93ec5891194963bd9aca2ef5a3e912c255e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d4331ad5a30da5a57636e75f4900285b927289e7ba510216e73189b6d76db21c600e8c26488449041529700539c42195624bbdf1c19eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a645862416fbc92df042baba25ff1381f3c09b79e2c89410625462018ed38a8480afac4a313da239ba44090a7aa296c304dae24030db60bd376ecb7779f2f2414d144e624a9b0d2bc181268229ac1f92929d61c15250730d58b75e663a2a175b4b98a906c3871f1f9a46f0e842c7b48238722124e7c2882b7831576a03b1ca105333e4b004bf286e45d3a9188757faac58e8d995e7101129fc560c9021ba159d748619204b7963f957e7410592028f97d297e2a8042bb8b342f1cf1af6a843a1598b1a0e851cbe6452842762109eac773cf58fbcd5845545485eb47be86bb51522273bb7782223b855c221de3c3ce3290c3fb4c9dee73e23c06994fcb437a93ab885230ce5521f8224521a6ce6c5ac8f682353ec78f22cb133c1c48aca73a461aa128b96590b2b508832f9a04a1099b7775101fc349b6a686b9cc3c7954567f1c605ce1543a6e967857a19678b5e6a3b996fea65336794d36c3045a0ac514962c79a6b03342b2ef826b4e4a2aa4b8e2d66ac920557915058c551b82bc0134dc489d55742b59c143b88ac8903cf6ca8aec2c784c1dc15e3b46ea8d7bcd43ba3161564b6510459f7956949128d6373c1ea8b41b92396d124b3b978325b1d21c290b76a1504a01adb164b3a6cb9bf5422a6b571f209a4f18c31c3a647d8e3cfd335067c75308026c40c5ba20dca0317cc6954341758274330f35df38abb5f1b59806a831979bc985576ae6a8df2608d6305ae2f7406f347cff1415de856b859d8306271c716495ec273a2c96355e195326883c4f024943f54c35f0003e70c9dd5c412f6c260f18a6adf1435150abdf28084cdb13685881aab0c710fec5272417731a65eb9360684e170f6c7a13310686471b0e91b2002b789a5a465128043ce6b7c29bb5dba20200dfc69d242823e477e34e146c828022d78c37b8c8fea50294586cda2f728d9b10d0cb58e1b091b68dcca95e6ad22416e1c9a7b0a75047c72309a284426fa98b3c905f1491a44d1338e0cad6bf2ac3c845005c268eda736b1c997a64438323501b6ac5628455694573afd782ccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545ebe9631b6d4237dd6884ae3647dd8622fc13d1cc689f3c8ed94ec6bcd4bbdb6980f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 4f1b2fe882e53704f5883b1b8613c9d4a17f72b1500612c398b4715a1d43ad79c00f69c66e8c7afdac439207f66d163d40bfbfd7d96ee8ba5fa98b009d1dc306453eb1cecdca7eeed84a08fd29ae9d9b9d47f76f5428abc46b9ed9845b2685cec51559f0496bb1b0161b024633f05bf6ffd3455ca80f750aabd5c0d2bc3ed18d95b605c404d61074021f7c11ae279027ff48dbb89403f5eea50924a99a5f5a2ecba792b55842416a2dc21512ec75d7b8ae8f4c865b8ded35ff017658a57edceb87ddd9ca4b7df56aec4bd8ea02ca467e52c506273974f130b1e55f7250dd21c7c42f237753f5ec7f533c41b27206b3771189c85fe9d0184072a8d0b81e6f98fb8b4b4de9de9427c1fe368ad0e85c8acbd3c31ec17c3a071ca06a3bfb5df86b20d2eb3bc3f5adbd452d11e604f76395301f8e7b7ad5e884ac90ca7ecdd65363790b9b0e72616ae60d1b7153a891eb95de5ba6a4ba6789a03e20f1ce0be511d7c7c394202324ae0fc429d7a3dc27ac35cef64c01ee6fdde76c0ba59b03fafb57ed3ff38c26bfc095ea62cfaaa9e8dcb22bd26e779c0231e3332fbc0e5b24f06e63c74525bc14a6c4bfd72f6d8ee252fca1d8264e7a2f60079a3aa68a6ee11ab35a9c80e0203c01d62913edc91d3228107c95f2fb147612d974e6811c5fa307cb6617f0ddc5ac910577beff3fde9a7d082db41fe52f105cf338173717a73661da1e850c607c1e9aa9734d6ca90ef855879dbe535f9b144678eb7a78fd1a7d7e49f174782bc17925258a84d8fac64f74e58005d5a1931e9ebe55f2e9e4790b7d7a0b5d5bd687477c279e15dfba7eb38a928fec671a1f3cf5316458162f92c2df26bca3d98dd5d806e22d5fbf61d84e7b6e9a06e6edf5b01868f09bb13f921cbd8c70d1a6257f96e3b147802a5e995c20873f4d8c99ec7ba76d1885130a5df0deafe0461dbaa7d398286f18bc5abfd2fe03daae5ad101f16af01dc22a64b6b1210b55fd3269309d4bbea97d136db04ff04bf3095c053122ae29959bc3f157dcffad37fa6a6146cfec799f225bb576927bb6a291b9e52dfeeb6180f61d61567a764a3427c105f53c615d18b5b5a3f29943aa9226f890247560c6b14d830de714e041237e2b515ee275caab6383e8deb5bd417073ea524a49e485282f58aaac69999b63ba5436d5632311be74981f58bdc1b0f87b2474b1876a10e5d1add2a3b11c1202c439964ae85589c881d7c81899d1dc2efd50fad84e729a5ab4e6342a6749f44f277e52f83fda0411142c0eca549c5dcd85da7838a64eecb0e06f4a199637beae0ea839eb151d35a36d8902c357f02f61c1ee52387de35605509564ffe882df8193cfc15ec582564a4c824c069be5faae6d5ca3e4a91b242bebc52c6c6d98d8154472599a0e7c8cd9aeadb17b8dfe0b3a8562487d1f47cf87d4c4c4001199c7d192307c9a44dca16f7a4c8ff29b639f1be6839b48a51c3148304c15e68cbbb6225d9c3139544307a59120ce7e3c4451486b445baf6a31003a81bff820bea80cf66593919864452e9739d3e33fb354def95268c0f377bf49bb319457db78b1c73465b4cd8915b7453f39fe15c95c981a831d6b45032d05b2a14ef8787dde3ad7aa8eb0b37195465451c672d4c0a0d87905fec449600082b85638884488570932d28e7bac4086b787137dcde64676aadb80dd440e0953b67b7f5a369984a8cb473af2ae567b1c1aad0a2dce06fea6345155c084880a96e093f8e394c6d16c9eeafae80d1ff2d8f94f6ee77de3ed56e9146292113949f31f4f60a6483bd5c4b51d507d1c01d7ab7eafcccc0ae64409587e2fb2866cdfe94c3dcb047faa437c7fa7036351f59849fb4fb98cab19feab17ea32d3e8a7b1b0ec93be3d73040bc090931c6b40bc5e8b64e6768944306186f1d309ec0a950ded03a887373e201c0498ea5ee4d03adc2f0c00fcaf4fb487b1a4965667d263ec958a02edaa992e7bc5421044c44374db93eb1e7e0db56d79bfd97eb676c3c17fd652b4daa788ed71b3d96cf774b3fb4d5bf5ca2da108695abbbab29657e6cbe7c100198d076d8030282e63758cdbe521b60b8651c7ea370b5dedab33c659b60d9634e19dd20b5f387d9764284e28e35efbb7c419efe1bbad9a7bba3a36c8fea83c050da25334e5f3fa8140dcff62d89abf966cf9420f5d1b309566a797904c2923ad126793d65a1eedae40ef +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4ebdf6f053c3ec27e2c8ff94dc99ee26196895aeb620f97429574edee9568f1e3feb564d8aae883d6ad32a9f9ca57ac0029f5c8e6e679194fdcd39e627e6ec7c2c3f842b547f074f47fd82a06bb42833f3a39ec3cc07904089e25cd5a854168d83ba8ab7be60b6ee881d25403b297c73048e32a8f8805e529a8ba2deda6b4d7665a383e71b03b1c0baab658fc50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2bcdcc80c9d248b97ddd5ed01bedca43f4fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48fab5e4319b8f9a0491fa3efda443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995fffaff817907de5c66899824889a760ca4a38a57b3afa880a45f4e138b37487b2ee7332d2689f99a5a3759df0fbca43ee6d45a5aba65f6c67783cb74d2e7ba987ad381938b4a651b79d8fa5fe8e6d073a6aafe60438ba3c9547e4557e1f7f41934e4c912648d269d7bd9bd69c8454666e696926ec4849f7f5e6e0c815638e34f323465839d36a8149bad494b71f1336a4fda954369d4265b6cab935f06694c58fb500cb77bc3fc4d805a295a692648a31612bf06d06c2e86c61675577053a747bd3a748f452b59dd28edcbeca9ae0eb843ea8b7ee21e9b822e8d860764d8c5a77f01ff2f90d4c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe69d27fc4f4e6c580cc3b41c14e984ea552bdd6396e5f867887430a2534a44ba545adb286cd61d7d6618c76945a5c3b29bbbb09b7f4b1ac53e5954f677d8c8c1bfd7da57c62fc8b80e73d737741f924ef7164b4ebcd8822a4c340b5b74cb5c2d407b9d63365c56ce4c5e6ab43a8bc699d8c34074a9bf4816f1ddddb464656c379fde8f9b6a6ec22e5345684f43ca647063efd52f6e6664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1b08f8bb36f63a8a898bf3b7b0fdd7988f8fdbe4cd405d46b1cdc37600570fc37ad9c2f37e313fbab2adae52db6f11ea653987305aacc8876ac4e0e4b7f6e9227b8b35caf616c9575506870fbdf585549a2fa0fb185d7a61139c028aefee3bddee56d328b16ccefbf5914aad88108e62d563bc0243303df9fb98cc57a45369517640cfdbf63a555aa1df69878c4ba567f8d376176d6941d34957e1373b86fd483394c3616d89d14aee19e705a2f7bd848bb23ed88de04ea4bfcb36eaa81d4da713e37be79f5ff51cafc33fd5d074d5947838625e49f5f6bcda5e683d014a12fdcdc827deb5208dd39b6659606a8feb8fc63ed61a939cb455e869a3fd83268561e16381c0f615227d105feef31bf39a04d97ba4d78adc66f23f85ba675ee871f37700bcb1af9fe2bc652ccfe9bc0fca0d7f7577c9c96dbc9b8b07b917f258c1576eda186f1dc1f87ebaa7714a54052fa660f034f237e98ea14c2467b46cf9877f5edc29a6f992b66da7db93c8fce3343f734d86bc548246a57473d1285463d0942f298f45d933ddab7a09766a9f9ce78ef539f9ce9a0e97364cbcd366b6bd8b5ceb082fded199cfaa5288617b5d019eb3a40b3d0af538119d733f2544d18c9d94f387a3f5ce7bb0de624fe453f68a916436c8e6a80cd05472df7f39bee5dbe6fe44aa6d9c20e7e89cea3fc4de324bd60242ac803133c9bd5df67c436df8d4e7e7b54a3489e5dfcf2c83a982b55e60108535ea7b5890e8b0d4bdccbc6e3a17e6eaed8b61a2fd73c07f9c747bfc79741616750b83732364d8aedaeabf8ed9e72dbe81cbd9e8d4ed10e3ccd05ebdf487c8a29c4c822c59cf457e24c973f5749f865ea82afaae5382bb68b7d8a6cf9fe24484eaa35ff97635e60d4bcbc8a403d0ae76fe5c6a96dd3336f4123ae5e25e5d41de8b88ef9fe1b2bd762734e63ac80cfaff7c43980d8bcadfe4caa430d45b36e73b6b953e3c97c7f655244d534b2963facdf64a33466dd79440f4361c8c77f1a0adb903ec183a369993494480cbf7d13308bd58e78d88a53d450450f6c7c7fde0e8a7124b957f106aee02598ee29dbdc68c53af48ebc5436aefdbf672f7f2089aa4cf461f2d7bb990c3e530872cade57a839a15b4ace0b2895fdda50d3caa18ef6dfa123f5946a689e96b651c6a9b4b4ed0e93f38e5f990b65f0f22cf68ba428266b1dbf30553a10aa6c5118f85ab9daec1c521639b686bfc4b198c511939a039982cc774aa074d391bc5137419a22892005114f3132f22497ebc5316e190013325b2c0c1f23ac61ebf6875640c7f56c78df4937c883bc9da38d1f709a6df68026d8af0ba51f1f2c5ff0806cac1a396a7272a4065660906658a25c570c7067d1972417142b0b6bc244b8e52b1b7a4b915832486f8a7486230cc63a981b195431448671e71c38527effb2768ce1574baa6a23226563794e714c1c7f75c05fc4b2630a47ae24b2a1d3141516941d61a58b609808612064881347b4765e892438eaaf1c538e0baca4e6e1bb38821633a385b7c1cd285b6edef2739a675110387e6ec747016a6a1007c87949368d31cb7a63a50e210ce168c825b86695223fc1b8789bdc89545a3394f9c1bd943094546f640b0b129c4e78a9ca0b8107bb18923ce669da26268d57c7eee01f15d0454cb1cb7af05f2e787833bcc4d4996312c82714043907b30a8d250ece8aade970cbe463494e759f463131c12b636503c747f64249d2687b3301387620307503d9562e5a033d86eb23546b83b0f70937fc6b70db7c1d519fe1ca0b93137a41d89843a635fb5c389d420558746be267440e8aa996124ff97b163eb828fe492e96a367ee7c22e2f4031c44688935b0e6439776e34c2c525a31664386a5b6040116d487846f538e0da71fb17a750d4b0b8f4c37ba859810a8aa15b573eb029c8f7052124bcefbc48dc60743e7a455a0c4cfb7c57847c50afb1b5725d735d013441f7b1b43d93840cc4373dbaaa71035ae110955d9cb60ba5b5de5999b082335ebc1d3d5b6a6681e2e4714423b50d30aac28a4006869a85941247f0a8f8da236421b761315b6adacc513f5ae525373cc57482dfb15286546d106925adbc71f4cc1bd33641cf63035b7c02669ced392b0b8c70e776a768f859c04e3b1c1f05d9a909025f075bc0021b091b0bd29ae7e7c787a0a570cb99f9337986d714595023b53147913b72f7df50b6421319825304af61ee75765f44581eb0378ecc979f81950437ba7603b751dbcaf1261a17346cdf645a65cea895320211089a07101bf617b731e38a8114335e3267169d060a9c09e7e829d0168a21bc580087554a17688cd742ef7e4a2510779b666a2b613bf81d8060e06385398babcf2ce1ae7abd2e66ac06142a2f73598ca2a1ff769923a0aabcc22268710c0a2143b96269bbace0f69a25142bb9f1a0c05266003f7a69ab405dcbb3360290ba355c8c6f5b1035697865cbecf8a20209019ea08b6416c86a098af524a2dcb9b7d16253960670ea96897b406c5680b14de691fa5305405f35048865e549c3847b3bf01856a15a25dac28c5afcb6be3e8adaf3689a0e5bb056b000a1308ac643ccd94c28711acc4653b52cc87c7d6bde2dbac47678ddf7101484379de232cae6975b4ec02d6a043ae14a53632ab428666fcd98b9f702432018e783ba3c7d32079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4baf2a4083a91e3d58e89270ef4560669d555fb0444737c6dae111cd1e18f55f1780ca0bb8e7c1ac3e7168d0c9e4a515ca4f11c49c967bd78149af3abc3e692c4659b30851eb86ab41d575021fb146d60069d242569d111e510b731724e6eb456c5428754db8903f31b365c7aa9976c13210438b50ea3e778e5a60e25f85c42bb10b24b72bc820300c91547582fee167eff958894e4898c198a4f652f871c9b03234f98e7a237778c679b757db3225394a356991b2810cc6ca5c7ab888dc9e59529f3498ec40efc47051c03c75225187da36d3daa9f3f0977da80a14a13a990ab20dd415c2036003ffab31b7aa534ec7cddc40a9877ad6cc61d07b7b1d8b71db1d1a2b71923337532e464853357400aca0f6a883ed84b56e77b755594b7bef178115b18c68175dc2c390d462ab641ba14d80b1d36cf290c6afa532d8d7091da94703cfb7334d667f0e3150b60ae8bfcb56dd40e3a58bd4d09a5a3e8a167841118a51490a126d6b85ee90a7f3d5432f59635b1d5587821818afb74ce42569751512c9840f364b6370cb318c1677a304be1a2938234b56bd2632f768a93750158e844df96c720007228c2829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd847db13de94d97a88d5a3deae31c246f5f04d0c7d7f337859e024764337a08f25a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 8bfde9f50edc17447a32142caa59ccd778ad4fac7180926a6851c4236c118ca5a1af677ff00112e34a515791a02058ac7a784408a93e2e475a13d42ece94315e4495ee134aacc0e657de7864bc4f0aebbd4707e4b18000a10c94ce75ea91cfa9fdd629c29ff02a3b35c08b69f1600c094df1f87f8cb6714611c61559ca83ff20048fd2fb43bbffbb9c996302cd08fc36c56bc7da84b85a98b4a6fa7f4a4d1ebe4bb89a2f2944fe681743015f1b6c78f93221d08ad12d1220774d737df2ae3791bcbca602b724c27f57c90802b6ce86b374c582247f0ddca21f9c23f97192058869a433cf31ac318231e6c664645d66e18b0dd0fb548a3b85186699f43f9f4a2a15c9517e3ae66585922f844f09cbed5be15786f15061e4b5781934df2b317ebc9425872269ff5dd42bda30f3aa232f788eb78138d09b83e0609a5a0d3a1b22a37409ed21489545638194a81972f4667a4e1ebb517dcbfb607043b9a8658bd41a960301ad29c3c94797d2f0598f42394f57b40aab2bdd3aa0b156967a03d597359c187dd715e5d8290895f3f47273027b1f81fb3dcf992331ace69ead7d83502e569015d11533d704a5813cc88f74d39ee7d2ae492593c7d69d29899ed23ae6b5a7d2dc4c28dd8c6971a52cd6692b03409f1328738bfb1c1a8304229f46b02c1bb70aa23f0f9a6087bcc0c948ba291e63f56b306cd48e8a45352ec1f4e1125be5dca924231d8e8b6a7ba1d14d44d7b43eff0e6ce8c86061a27b84ee8a018d4accd3f2ac03f36f5b466e5f914f7eeda28f65d13a7ac5ea6718b4687875ebda9d67c9eb4634834f6bf4a145d9dedc96a3b118b026bd44b473e8839f86405982f33c70b21fae5e2824af14d610da2ce00cdb72f15f2ba3bbdbec777fa17c83a7293da0be926ef828e7e15c71efb579e72ed088a7408bd4034cb02511a44f6352cb44c7800279ae408c05ba7c9de63a5d16668e956771d580d5c4cc637ebdaa4d92c75fd3fda04c09882949ac85dc0356f210a538bc666c75a89c067cbc5ee5f7542712805be7147103acb203c8f99a5fcfb8ef874b6dd815e8b74e508a1fee87020d1a68b28358153d7b344918b5691ccc46d614b7606c2aefeeb623c4f367b7450a9fc6cb3ceb45139996d39e7afafc80c39ede56777f0e6c9bfae67a89db0aa2abb0a7d4cc24b6ca6e5da624c9f3a01cfb5e7039d5064245fad0c2273f7a33694b5be46adfae5afb1c05b93d7477e22cb2128b3312cf5c878953f8d4c4750e183849da2dab24c222a8173e6c1dec334532bd65bc0557fe85894abaef701cb660173dc1a02c64538b48bcb5f9d9ca5acbc53202faaf96f1d8281bc55788f72e64b99482fcb17c6315a9e48b661adeeecfe7339bcb709d70248e7daccaf9faef94bf769d26c4ecb231426c131fdf3ad9b744580508ed04b26508727def4e0e2003c0737bcfe26eafda4d8f261ab1dced0c88d08966b5a573e5efef88e1d332e1994c57783f189b16f99926035764db0f7d704300cf6ef23881abaa531a9902b03a3689207a80dc3f496e38e4a1560e6b0e71a93ff595e5c595e7e2cdf8e41e0a26dd24f850d6633f5ae45e0a694406e28b8fba10b7db3b710980de3f35f2aafaca276f59d7c3953d3dcdd82090fd988485a3373a7747884fc7e0dcb4c81018982fd3680a492aa40e1380f212c09e41ffe1a8952e6af7a9025bd2c3f385207f65c13b73ff15b062f0707c0c66baea4647019a0a16e24c21854e8d207dc99f3e58468f954a797cc672cbe2f3c898d0bc894fbb642ba3929232a00013570aa97b219e582058a3f4df92feab5c2ce14b2887a3bdfa4c63c93d7b476dadfc7e61aa156c523a87d7b1b38c99ea84ed417ccde7d1a5bde2524c118c9e3a491538e5b979529bd5e3d370e9208823aa0dd4f814e133553921945386b2a8d6c8847a94ecb8313bd51978c7ca65f7d52a0d8a1deba338b3aa9bf31755f68e19f11b7c19ea4f8c02fdc6974187c35d5f442aaa91a88f2b0b8a19febe41ce52898e616e5a016995419b7e1aae8e48794e5e245d0ef013e737ba64bd487f06ffd25536588cdde82bf10c26c1154e96b4f8bd83696f5d41e00bc6cd8d6073a1d98884c0e411d11e33e8a3f76a061562c1040a79127741b614b0a68d391c8d843df2e44136eec02186fe637cda6fe2c3abf3d821e9409ec5f4c17f76c8d4da5131ece03c095af052ace7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 1f83902bbb77a98bd32287d79dddca71dd9d57385ce6ceb3c08b80ed95b2bbf7dc101cc1912b71b29b87dd18f54b593d616a31ff4957c8cdc32508f124f6a7b125b0ff799fff47afa6a9a7055382bdad8cbfba71ea1b530bda5a4548922d9dc6de99f7494370efa6c9689dd86bf585ae6534dc05344ece941ef793ebffe4312a371ecccea78dc1a166ba98fef806474826a9f2caae9cee4b8a669abd146491abf3ea57c7f4f4ae73750f69a343d9f75ec935ed9a5656f78a6e50addb8ba28ecf2513f5661fb0dd5588f447f781f35cfc13f8c0dac843aeb3f418b6e8c567f51d568f2c6be8eac9bab558dfbd8389cad8bbaa50e1ec5dce044efe58307444d2403ae67a9369e2df81d387e3eb6566637dd8414d9c4fb971c0fa7771ba53b7ce3ebffcbb85aab3316a3a99a9ced8bc4596a3fb3d15ffbb13a5cbfb762ad7a08ca4aaf33862b73f5badebde56d395e809ffbc7347e847956b57e695c978dc2431f07f86c1eda880f7871cbd51612d9901cdc403da599b988a8ffda716a9535c8ed02b3bcdadf6d053f5a8bc66419fd9d7f1ea718b7bad6bb76fd307e1e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edc5d0d884428cefc7cb6a6c86c8d7a605973aef3f70433d8a7a4aa768975aa6b0c49f4cc98f7cfc83ea475ef1090a68593dd68029e97f489316bff74b7e33423bf96893d271fc94b1c775c6bfee3b07bce543b3300db7250cabd1dd4a2529347848830c975261a547183f4533ebc0ed6f7f2064ba693a9bfaae6fce87a8d737d75aad6c00eaab71a5cc25034120445334a39d63baa2ac3f54d77a921209750f6869e6a7ed05eaee1cbf9cec9cb7b4a6f370e5c139ba472a85e14b28bbb8f7d69c5a8201b730db67ec1fedb10e1c42b4a97fb7f7ae5477dd12859d68199443157ddea85760445895f7e75ef8bb919c721304f8301c4f666eaf00beb03dfead066e3c52dc5ca71a74545abe78df395773d3bc9678272873dabf8f4a4aacfdb46940f59b0b8fa7574fa0cd794d64dd3d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c8bd5d08f93d4ef3fdfda93506c831455b649ffd17fd866c87683ac3d7c6fd9cf253ef509d777f35bd618776864ebae9fa5318e739692c5aa86648d49778b6708e447b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464dde801e0fab64bbba4fa3fc0003458ff7301138fbf444961c54c52764d8c4f79c3c553424aa4aa13a53d5abeb786cdffb686fda185d5438af5c494d98c8d381d8f1c493bc0e7797cd1995db78eecaee8859b9f29c497cc35eaf12d9cfebc6a19c599c9d364e587c7d32245145b6dceeb54cc7ec5b541b71dae959c90da747eaab53f8cd24365c91f53b7b0b9d373d361e4eade4d8fc86ed4d8caf43763b3f9dd65d61afef962337a45fe051d36889253a423939abfbdada6fce1e1a9931c960d9f4948723ca17a731adfb48356e569306f3481ff5cfa7b036b931a234d564cc35e59a7acae4870759e576dce410b3d4e0885534f577692c5a237344a5f674ec7c45bdb3f42e7db004d5ab620ca2b1bcda57cdcd5ba4f52abd54e0f840e4ce837f0d53539b4a3eac9c6dd6f83876c745fba8d505681c9f3e315a99ed34b04e558be2373cd4ad7dc7af6eaa8e36bd197ad8dbee695544fd93a23a29577e36e14e5c8b4257ca7ec5a467d53fdaed37386c933799bc3bb9f1a50cc98db79f1f7b96da7a5ab56d4499bff3ebccf7aaa87ede5b4df226c6b5c382e5ea3545f5db9b0a7b31de5c789f7713ba9b5fb5fa6498512863da850d3b1b867a6bc87f295bbb168e4ad3bca5ec3f40f72894f157d92387cb072692bc7fe61ee3ca1f75ba423653c21582004d8c3f0fd8f55746e7338cc94c45ee69f8702559f0c783cd16676a44fba9a652962c50c13d98327fa196ebc902ae3ef657fc7e77f30629a5ee99e7e965cb0ff990dae8cff8d3a7f46ec3123dad8cb43a9ad48bc46c51b9a56722c34f578ec7179dcf5b746b020fc63527ee4f1aa199fcc38f566a0275cef828534746ab958abaf2c8814b1596170ecf13436ade47d47d1c5497c74aabaad0162e8c8b4ec71a3f8a0a37fd96d63dc956e2454eca20a8a30b0ef00729d639993d4cacb58c46754147313db4bcf2f3231e1aa3e81c7336e49c4d760454729e9a47c4550062afd77d971228863c24f1881d589c111b38a7e3f08788298e5cb26ccfe7a71b171fc504b86d4526a2c0a3e0251710a21fdd68047612cf215a46f1cb3d5376cdba14829ff67f7d4704f199ac398777c8ac0ed24c4f00715c976b0ef18a83dd177367078b43003c10e588dfb9c7c99c5164bc14755114d5138715721eb3022cf2d016f97011f37502c44a397aea0a7818546c831f2073a4697aa878d00c4b7ab8312233cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078293e11e43981f00a25988f076e20a7d69e25fbdf7030e8404ebe35f530a8cc5793cf3eb1aed34b3ea742f4fe853fc8b7aa77a2b17669a116c49a0a114770b14801a62868839ab199e3c02c810cb6e0489820f25c524969a57172811089c5c81659f6859a1e5197ca36a33da0e2ec00cd035b23973448d12b251793da4bc9039b11c4312cf3db1abdea0657467885191334fdc8f590973b201addd09cdbb545fe66a0aacf679f0b89d7914268084888d358b767a8475e85da48590f0809e0ccb2c7d286f12fb8c6fba2f1b16cafc97a0b9863b107826c197a7a6bb0bcec280c526ce18058e2d47bf92e7bc0d4031d4c8c8c8f57bd880c8b12c556d750eef27ac96fc47f37c2c26468a8d27b2bdab5483f241aad905c3a76fd82308d2938bf7a070e6dc56e100b99dba0e46f2729a52a365d732965875b020b82ab23de8f8807442ca89b31fcc76162961564060a119002b116a510b0c2e1f301c55992bc48519ec5a1abd49a4e9da97bba98bb4774c0e6b939ac720cc22b2df733bcb128c7d4165cce67710719c1c978cc49257ff741ea1c3b5a6479c4935447987bd61d99c1d80c833f671f6a44be835a8d8d733adf4af4dccba087c4b8681a8b49a863bc21887a0b1d50b05ae1513dbda0960bb156be96a1321b553f21aa0e14295d00b81096e1c557ad6c949bec43817a836f09b0ad0803ca072b488a1627ad2c017013492a955fc829df7d800c99b1ce02b1d35a68d3269cb322b4d66ca9ccd279fc738c4c3910a8a4a479bcba7b1a6ca8745505b80236b63244d54942305c3c0f89bb4e771a5b09dbb072d20417f469b47cb8b64380b1a99b6a83cd111a881af60ea3ae5a314dff60841592f46a39beb80234ea507b1c9233b898a33208d8c936294738cba7287c5ba7f2ab0b7b63a0d475ca3d6486858cc0de5580e95c56c635825bdac834c71337916055d1c9490e7977982945941b8ff196ba5c23f92553f9a1b962a56ac9498b69ce0c9393621f7a662c6074c9e93b44d099a0003390748547e10052506ac88dbc1d3523a16b0825b4656552383ecf067b2a423bd0aae22ec0971e52963241403438c3c254724e1565ee569b0d357b416bf3d770a729a277caba335519724b2098a107f3f4c1aa1f49796208e739304852c949debc717dc8430f23987d60f0a0a3fd5f97aae412907227fd2da078f1a1bf46c0b66e596839632b121c5eec37694809861541b223619850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcc805a0f4655c61a8564c3577273d198184a2b4443a11aa05931dd1827c0720214eb2798af1a83678808913c9c6dc57eea4c1f2f469bca44aa8a8082cd4082464a9e6ac0a86da0d1e0021dbd3196b726ad9b43dff34cda455c7a51ca343f1af8ce2c580c581e4ecb1517cb36959114a481a0e73718f07a8eacb71a7c2beb2654fea5a7e01a6c02f183686b89ca0c775d0605e17225a655a544838a60f252412fa5baf353d2d264c4e4c2cd31bb4f3075410c220632b3d605c7431479f5694870cb1b1724c0363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d6252c8733cb40627485df64a4e872cbc574134c319cf1464a6b69a6318038896111fb69d306a6c47a393069b0f27911255e0306bc4ca2e93ae71336daa3a8bc0517eff101989f9c19bda6751724e1bf816d4cc7397cb5a57a14c471aa511e42f18e4937001977d063a4ee855f326811ec26c8662b5825a95780a3d031948d53337a45679f5c328573c109e5944b68c0b4d2b466fc48f921328d6fc74705491077987e6cc936e2bb69b534ea97acf85e60f2522a55c115cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89adf122b76b83c343de27054985634387fb7138f6f6f105cd4cd3f5b02698a964b036b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = 9fd78c1122ebd395da508c0a171cd52d0bfa8af3e954152bd5f835dd9158052e9e65522850ba3bcfddfd2c204a48edcd3d4f5f3c6d7052933baf66b707006b0909a57638a99023926d0a4d8fb5f5a81cea061fa3914fce87d3f12c31633d1432e7c0f95480ef51aecdd02344acabdd33f7b258240aabd85c5a52537f1ad6adde693d08c2dd6633a194b83614f1962664e8b31b11ac70a4a710304866f7809d9ec1b60a64a20c0ec9c383186506bdb44cd5ae5ccaf2dc0643b6e23e5c2104bbfd4b83d22ccd88274f5678e416219bcb667fb749b9a936aa32fc64d50bb86c624678d283a7f93f57050c7b0cbeb695bc3c7a15c843ed99bcd0f9f74c99e3ac7239283571aa442f981b0c9a9a34869de8e707f1640003717ff0c4894e70d7bf3df2e017380e3c39e01d19c042121ffbd9519b4f4a8eb6114f2927c715bcba66129af881214dbeb83436908640dd4f56137a8ebc14239a3fd227869cfb998696a57a10ba9169c346670a6d503d751b6afe396edf421a11fb6316a0aa1285b6933bfc18077a125e2d1b12e841584c0aab9ae055123918fe18d74cb375c819b02d0fdf1507c2f3fa19e872a7c7d7e7eb4a919c3f5d55e08721339580342e3c1bd6de5cee43774c0760f58c1fd307ec6d6e84eb9f98dab5c3d39910c57fee65411e366b4a665f58c258c34f1d6bcbcc5a9729f19cda362576f8d1f61003c1bec90093e1703ac84900df5c304aee2e847efde6be48a85a491f7134fa6cb485264ce1d6dac67ed21a94ec4f50e1f13d9906d959448218d0ced49bc32623f0d078115101803fc528bf3860e5f82552000140efddd8a644e4a7b102ba4b9951b2334372b665820d6f4515c1e7e89b3de28241a69eae8c5bf9d86a4c3c31384820debc75b6e3bfacb54f4489e5b542303cfe7f068d30792edaec52ec931987a51ff6c61dc551aa29a387bd6fa0a6cce23d65eef6302b9e99e20be127ca7241c80ab3da3c73b328052e73a04a66eb9623077130394a08db2ae8e0566f44ea5e5294a5b03197c5e4202e93cc20406777b35d20114f814d0506f02af5aa36103b9f6f7507b4d261fa76680d8d43cd88ef7bd3c397a3a2af42422ae0565dcfdb223891511f2f1f0fe7d5f4181b72598edfbdd4e7b032ad715db6ebee82a678d89a44d9888a4d6a71cd8fcf6ab5fcfef50f392d1c3c5b2fb3a9a57118c9f3897287cc973030921dfb70421f4bd93f540b045da90e8e75b319a66c3dc08a8b8f75ef2ae4a0d5ec62313b3aa9ccb7400ba7a3c9d38e25f43f48838d9bdee604b0501862d6ed0a05ba9b16bc4d24e759fdc8b72f47d7cd807dcf917bdf979135d153ed612a1388a91f4d3817cd051877466523e67c79dab62237c501c9b14e7493290b2a19da5bbf399ea734948418c9202fe61deb9b229467ab88910613d2ed46ab72b74cb40d56afab6b8559fddeab6083d9d339dd766815915e9d0bfe6dd729ada70d0082db06b44ce7d9b8e2e95ff40dbfcdb7f96e48ed5e61386a3b9f98c27de7486f88912d34256ad3d69827213c734a8c3bc062dc666a6a425e3d2ec9e29614c08f37603bbcfa8a2e69e696f111edd85d36684ae58eaa006b212e31f8bf850bd2113b97264428cecc74f65502988c8c2909643d3a9c5d0af5a24924a0950a0e0e9fc48708bc87967a5c53deb73089e31bc90880a929245e2408c9ff102a09fee0f8ab1f6814b3758540f1516a789856a8c0551f9fd909640ac45c6f262dc9ce47508f2a711a9ee24252e8010c0637a29d52d6310822aeb7908ba4094ad81ed06e37e0362ec9a8cbb17902f21e3e9c1bc7398cddbfd7a88fa36aaf869279ac05e6903bde6269c642c22e5185c444998d4575342088dbad818e6ebcf51b1eff795784f0264ff4426b47033b76c1f3f86e6120b2bc2a0fdf14fff4757b6b25587d1dc95783f83b18bdf3481ff15870df6aa8ffee072e2df4aae4f3ff7eeb84476e0e83959d6675b81712160d640f57b2424c6ba169f858015be5688e295be442a6a555ea578bbc345a51c049c01c1e0fbab96fb946f7464af0ab2de717ad066d6a4d8ee3ab9a60d0647edfd741c6802fdad1f3a8c277f269f6901dd9a7145e2720d4c9456e81f463ce52f53d23bf0e7de5d90e54a16038d8d8009465da7dfee322b2f87e8de9053116010b1873d43c5db1638b857eb2338d8b4d2803a2830fd370e640b4b5046b0c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8b78635ac351c94bb6b2dfb861e4914dcba415f66ccc465b370578e136330a2c5cb0daf858eecb733a75e5cc4fcdf7a1269dd17f2cdff484401dbf3318a98000637b3d065608678103a4dd8ba75ccbe58207ce30ee6fbbc023f317b6556aacfae807eb448ef002d795cb6fd0788f652d39edfe535f75034b0e6f42785f7a6e06f4168aacfb07f2a9e8753195b82eb9855467322abbdab28de546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830d06f0ea7ddad67e7bfa2c8e59f3dc8b3de79b27b5944ec85567788043dafd2af27b6c6314ee7c46e87d109a4aec5ce7969d8db604659848315a9d7a667378f80bcb8457fd5a748044bebac10ba5bc06ec08afb13c1fc34703f63e26c25ffdaf6b0d3a68bdbee98a7c5a489c9ec9ac1f14fc6f2bc7585cb01bb4b55496a93df9d3ec974399ef77ca7cc25f3f65a879420fadbd855e716bdfef1bc8d6c12b3488e4d8ecfe8b89b79b1f9cd9eadaf35f2ce65fa5d4ff98713969df9977513fed37249b4e25f5ea2975f6ba76cd3295895a67ecac279bc65642cbb5d1c9fe31ec5fb5c7cb73b17757441beee4f9f95e4d4177e542bd744aa587738bfac0ef4cefa1fe9b0a5c5e28b53c244dc7fa16ead354c85bdf6993087b61bcf002795d5ada7a3e6747ac9ee0367c824988ca705b818d7a921dba333724d5ad235b18e463a8ac88180c88f17e579fa5ab6e9d4a2f53b03f7c7ec39c47373f369f984f8cc66dbd29f4206a63777d6ca376d1be8be6eede7e93cb9a0437b361537432abd712794f5058790d98e82be48632a3e33a83aa01ed7c8e79c6f12c33fa9437ed984a149f903da89bd53e84db6c8dace3789af5cbba19f010b889ca98af99e5b0b3d4399b06e366e833a55a85e11784708b98efbbf23a27aea2ae6e76a73c2027759fd97a7db870f9fc79afc89436dd92db556e0a738c134bf59f86c98d78a43a4974503d6da8cc6c9098a5a9dbd91c9bad94a7df03b543d669a9aa4944e1cd8ddfdced7d485fa414b0765a88f175ab6c94b12b2e77dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f08427763f84105ed3edc5c1873bce1fd7a897e740c4aa82bb5ab1659e6082b795fbd660bf3fda9a7f840d9f7b7bb4061343d56757258ba4c926f4f21eae1cb265b00b9aafcbe665679c86eabbda12b74f1c591720ed0ea2bb293d7ead5b556369378a8d5b7297c97327d5dd4493dbb173ad01458686a93287b6da0a6923c9e3989b69612b9e5a04ad962379bbc466a03f5517abadc0b13dc6cb4f0637bfee99fe916e9c7f2caf28cbfaeabccf92f7cd7ad85c6f43ca90e4f629759536046394936c3ac5ab979d5cec2aecc19b5c17edb47b0f47f34e6e6028bf9a137f5bf14b62fbac4f2cc6eece89ca0467d4868c11c27f99373687b657d132c55795d80f5b87f0e4ce504673825b98e8a0aa35f2c8d8404ec060ab43aa3de7ceec9d04746169bb4ac4d3ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a965dee494466a49617b64e069ffc57ae4e08ac8e3db58526c7647d56cecb657ccd1143343aaa8422cf3bd0c822f763b6b8fb7d014e649ae43bcc431a73bf04e78da3c0eedb675f255143c457db18bbf7ba5e6cf301d64c37ac2a456f4354fb0d37e4d2d6c3208f3d3f97474811fa7f0aa89dd1ed35ddc3685657d457a6cbe9c7a9e8aa5e62fab7dbcb1c656f51bea39853e339619b1eea7fa46da3a063c90949fc284b4c5ba94dc235588ca74da54963252e45e3305e328cee701fe35756b35680d42174e7f2beb77f9267e72e444f3a78ec659e31ffb364c1ebbf8ab6472996be218f9011c3f32183fa1a39eb2ccdac20478ec168e4e2ba66b0e742d973bcec937a9383c62d7f5cd15f8bcbab546179a6365819777412c5671def8cfbeabf7af037de12cf690ffc1825ff2664bc9a70591156eecbb5b361fed506354d5f9de908d6a9f3dfb3c1d888ca74bcd2453e3feae69b23345f2d8d4db569a122938839949400af46a7a5df77ced6c853208ad4d2de7793c6a6bf543dbd32cf85b9f3072cf331c23432d4f7792ee771105d78823dc3daaaf542d60ac0c9ae2e9cc348e45d8a5787904c1348e794753d89046e7788e8990c5780a4440b33dfd24d25e62d57365c8c611f96ba675aae5a14164b5171d74146d792d6203ba384ca81ec71ed87b8ba40023ed8bc6ac54406263ca3d97c5bdc20d9e2cca82b0aa54586863d95d3ed0075cc897f6726caa441896e86e03711a3d109f5bc311e81a5194363f8bf735ac9a2caceb7ec4826f8af2b303c3914e9b7c3c5337432ca626970761900b44cc92630ac8469a6bd9d2b46d88c225223dfc405d6f1447f9878610d021cf3762c235c414025239ab3827ab5a4699c82e37b1a27b460f0264f4089a98e41c924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad0873935718bce46b2f19864e06486a4f5c8d689adec32a2e7c6b57071be67017fe25b8f52ca525f99be536a4c1468b5f9f418025450048692f961ab8feb5075b543e04a0564c26c58a72ec6433b623a2d5a086c85347e45ea7b99d03ab50664149414c3f81d219a5b5e732c0a52c060e90e64e14873c02167a21a67da6a0b945781341cb7c65aa2dc481b0998de5c8d893a548f055f8fe420f173b949862a5549b0ac1908f202ae0bec6b19c0b3e5178f4e40485ca33a93947522c1aa6c188ac2fc4cff214b995b1bd69229d01a8d3d2045af723a1de559abf78c09928d71aca3c0016038340ae715058c95cd33ca85709b2134f78b86a84ae764ae94b994acf1354e42126638b57ad207bad29f1e60471acb5b650332b4656ccc808c15ebb8df203ff0821bea62aa67967bfdd09535e7088ca98e3795aa1167be9126348a946507c08243a969b2f9238fd29f0370356288cb1708024ba7a9cd58a12d306d4f4579893c8a04a10c1872b6a602c155f70a8ba6987fd28dc842b9f60b4052890a4482a351533b4752061e30957f8a16b6f8502a1b4d8f91b56b71470ee2cef40648533bb1d9179b3e335e051115b817aa30b3707b64121179318593b0460bcf6e57a65e045d00353605d60a0705468c6b8e4db422c31476c8a0b54ec166ba59b75f9834633c0052757dc437005f653ed4c19ceb7c774eaa75ba0068f2a997a79a98bee42abf9a3b7597394d4907e430737f860454407b8fbb2da0a054c2a4c737c8724c02684a070da34388fe9927be4259859849ea9cb6ef5990eae176efa10154556ce5650cf264bd11780055b5931bd6c5f51816d135996757b386b76a03893efea95ef964b402079cad080b67098b2c092f1e9768782a8e3daccd82741cdc5c8575796d08e3180b34b4ce227e7593ae9264417e7b53daea2987a01fdd42150a4262441475370c1357a575288571996527c95a9fd62c3bf54a8c8ec0a335c3a31b934002443d07f27240860e8ea76c821a71e67132c9a5a1d4d3b5f29cc9a9924081fa3c33f4a11285458954042337701c392998da8ee556a544f0b49c9c2b83b58dd8d165e6751318363400d61652d7170ca44b3033bbb20b45072708e6453b1708b5b8206419e050d7c8843e0bcc227b9d6b426a9f693945d69ee98558bbe133fc6427a8f73981786f42dc03fb23621952ca8ae03810648b8cbab5c1d2816fd1c231e10f7eeaac9a798c2c3a4cbac428c6971851320191d3195fe4419ab69fe913280d0763a906c33c4a9d311c74d9459ee85a6599061f09376a14803e1ddc67d8328bef1c7f673b62bbc234b20a29802ca9c19c89b9b6628a6bac7ae29897b1136a0b8c28b0441bd00a9144c85c9897a48902d176b9b03a454f36885db61b5915811d60c170f74abf894bcde1a088195fda3043be6080b8b98dd48168c12a68d0b74242472ddff790608170c271a4bb19907288854cf1c4cd744d1eba1201fb643b805c7c7c1f6cc9437038bcaf6616f9a6a214785f5fe71071e4564d0070a401b457023685a65d63fc525bda14b26c1f5381885b24786a939669261b769068c3f97eee28aed3fc68d3b08d6a6b77ee2449030c0190c016394b0d9c8085bd550d12f5110e647b9a1549e8f67f5fd0580fb39358114aa668bfa3a202c0369ddbf5518d80aed20c403aa3cc7148119cba54ce1667c2654d9b5a833d5a552808ae72629a2da12498319a30113b314c870e8752e442af5ed67bf1481f071921191b2b21964fae23b33df528a22090e4bc6ec2911810e02e65758397b48d1906013cc0cc0c2c73944b45bef04c2781acf467336a107ff7cb12e6305ed85342d2355b047862be56057cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a69684c3182ca7a48afe60eb85790dcb50b8005b568921dbc724130b0ce83f127845475d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = ba3071a54dfaa0906f8ee42795eda8e49faad17e7ddc5667c5e4a10375bd75fcd52c555e82694b6562b862bf9eafa16c02fda81ccb4ee96e2ecf9f13528eb95e2dabb90876dc9018d48f137bb93182d83ce6290673264c46c6357dbd792d361ebc0aee118bc7596b58af225090d063950325f098f616016e259cb6056ccffd05c4ed8272866c555456d51d6e30052b8e920ba02975733cffcb02c1697668e518942d12485340b0696775c8f1ff7302f4025faedea28e39924f9006e5faad919a292e01a8b4255575d3b9f523283e474505ee0c34e8abf992808cbb23e64d44f5d62593200eb4afc6a6a5de98112b6dcd3cea483b741f82105bd56d6c21f6e4b4112b3767fefa5b67e42ec38963eab8108f5b31116be611708cc3e320d308aa8859c1eed3320012b800f38226f9617cfcd3e3f444c4b633fa4454722cbae119d03cd4b6d2fb8cfb0ba51c74f9e0859a6747c2241b9794b5991affe54209393858e85dbf0504d8215de1be359c63cbab55134c610d81ec0446b62e86e7f3a205ea621104f4681960e39f0b22492d62cc765ad9c72f1dc820752b2f4a23cb0518c7c299115d2c8ce14d799366715ab518283b31232d3806a81fb994b839673ecd987c7d95208e2d87a8c78b32adf938a2b99888a26f45ad655e4eefb8b3342d3862f00eaf129d0d660d5af10c2b30dfe64f87a4ee4450ca155ef2129095beac466a35269cfca6fb17ae3edc9959f3af90d1487e58cc1d62633ce0b2ad3e482a9005aeac77542cd14f3581300a2ad1aee5b3a99e4570dde81df5fe60675a8acd7c950ec15dd94c96f96cdff33e155427fa7d87bf47c2ceee2e4619f4163322c1140b1c0d3786bb065886dce73a16c4787692a0c974dda5ccee7741af8febd8a4a150d3e7e99663ad59b9482e064ea3c64382b1c7aa2fe8e9d3d763a33f2a89494c1552cdecf44461efe20b61167ca83c0e5fc890e58ee5c549b37db205e4368dac61bcf8c687eb32329865230cac0eadb9c41d998a34e3490015e275828a386d1e9fdf14273b94b0346aa6fb91e0ab3d64ceed7f2abf2bc5fc5d016a0a8a87d10e723aaa90d9b0b37d99483560be5fac144a4376d83925d312a065a9669e27ea4715d58c15564cfc50b8209120fe2db562f0b43119b378ddc5bd4fbad0fae538e279a998320131bc5d033177183977a637f9b0a590fedeaa6d70ca065969115f0f5523e22523164562339ed91e6b5e8cd3f480121f1d0a85c57e894d30176a8ee2eaa1069c5c7f6c2cf116780b59be89120dc9ce50afb6b85fa4737bb0bb2195b5a5db44b8eb0793281df1a64b89751fd0b8a06021ef95f01de2c8b5abbfd0f2202f63501cf019582ff1a60bd0b99cc78e355a9d5b5adc3e32a05c0503afc2f015bc6280117385c837a6dbf184949d179369d431a26d869b65d6ef0401246f8609393739e9435e9bfb6f48586d8b2a0debc0822332d97537e7b332eba4a61db9a093d844652c8cb8a32cb44f723aa07aa10551320e84ebe81f3e7d251bf40b7fefedfdfc0c7e5327206b51e34b6ec5c958c44b88c3ad6fa552d882baf129db0c34d5f57431f525275d72a1ee47725e0f3bfaec864d6812f270e58671e0f5bf3795db9c9d8d77d04d6025eaf2468ae90307a701ec72623feac4d0a7f91470a2da29058a3bfb18e60dbb5d8249172a495b31708058117a5b24c9130a0451f573d273faed048d4191b2dd2a8341d57933ba404200fd5aacb7ea7c3310ec54fe7764178d507ca302c773f53855296d094029e9f06e47ebe01d74604b8aa70c574f77ccac4e80f862144933b303627ff8effa189938c28263b64f57cf0e0810feb90b3eb94177735fc5a531d71257fe4fbec3a1f218316b35d1f5b7f8129e0c361ccd7180472aa07c91ac6b4b00c4e8fe91da9c4321b1824f7f7a87b059f02ef8b05a40b8e3c21d7834cc7f58180a4bbe8a03da4bc99bd37b2ce542ab0fe850e67f9afc9f00f41a0d38c75d345ffd28515f9a442b33b05f0eac1d0cf710540af1be81e7481dca72647d810dd7c9b851f8264ea21080d8eb5315ef5ef75f7d85e0b2fdf895883d9a285324ef7dcadce365ddbc0eb0e10bd25bbf34109cafc32d88384834e60249ffdbaaf72ecf6d02bd539d6734465eb5a176123155d743933dab89963f7ae1ea01ee9db1b7f038cb0cf7f9059e20a0acecfc357e4ebf3f016ede1019cf95 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = bddb6a1bc7d4f8b530860b71985f402098c84ae4809c0ec8ec7583a66a3f4ccf90c02e73abc4e8692f5606d54991f5b548dff54c74391727d45997a57ba534a97b3606eead9f7c6446bcd8bb0bea99179bb8f67731a63ce1d7e7f30b57fd17bc016d5e8e24e27fbdc26f3f4aabd45138484a52ae5dd2464440178ca7e966d4d58383f6bf9cbfa9727f907488ea8d978965f9a51fbf729ba8c308474d56089f2cc869b523c41d4d9507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373e5e85426b7b3a5e256154a7b78cb205d49df0371b94dab21b83944fb383cc84adaef4ff43bf731276c1d26b6120534439bd29c4ac7c0739454cf860e3facd86ff9c64af3a83dec313d32bc0a410329d35d38a3ca9dfd41a56a8c7cf496ebe0442afbcd13a8209dcda2564cc9f4d20a47595b3d994888b383e996115aa282eac3e35944482edc2d07774fa3e2d796c6b74a7634b6c0db2f91458a35d41ffbee04848356ecffbe52e2dfca9195afd1f9aa8223e804d35e749f99c539b913c54a0c58683259b3137aa464b9c6e04bdeb85e999b6c5354e6e71c78cbbffeb456ec4c88199764a5761d18c084aceb0a263ea50eb86cba549d8efe4a35e830f7b6ee16b2bfabca3dfde8c3833bb98e385c37fdee25eac36afc966eb3c12668562e9b0c6b485e669fcbc49b24d5dc6d3f37aa7be16095d85415e15e14f2d956beaff9360b58bf915654b9b887ad9733f425a5c6a9db401ff3d8099bc0e95c6a67d2cf5667209ace08fb4698edfdc45caca8074185f54ec474eb35bacd2f0b7710dfe5fece71c98baa7ab6c0450ba6e47a838575a528f7be221c3c920df834269a9425a2edb76cb7dd77ed86d40b7e6d39c9c87a58ad8867954c85f367b9d5aa158e0bade9ddb5da6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aaaad418c79a948199365a6a1055f38114f80ad7d4b3389ee157af377bc83e9b9c86d0a3d2ab3f8737fbe653ebb4e5982334efd11dd3bcb13b4d838a9a624566c7af5fa44a0934ab6cc333e6e5faf3fcf6a6fb97615cc3c782dfd1b3e5486bc69c555a3e837e6613ffa417df2e8d972523d8a91ae5f758e53c1168cb133593c1641e164c8a06cc008059c55449414cfb28667b9922fac42b8bffcce5fe3a5d03249c676db758adf896e84d5bef8ac510782002e4454c8a0390c332ceb7a5b4ef3eb2aead057d096058358ba779d07d207ef4990da77abfd97062ed994fe6a242da941d8865b387236cb8528babbf2e9e96c15898b07e140d3ba500cb7b1ac85e02ed03a058d839cf652d4577316d23c756aea7e5136f9eb20699ff04f5e48953fedee5baf27489e9f98778d3eb0b5764e6338bf5970c2f35d1f8e5bb6bdb1bab630138859b729923343c3d259f2a96ffe39ee9868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5c7eea79cf81a1e3fb373fd5d995b039f6664ffab8e3a73dd6ab93513e92f0f43f2593618e3a809684bb6b3e674e778038f8fefea3a50fcaeb1088f7eecd36cb84329c988d975d71e97c1311643bb1ca2b43cc57c84cd5eb9e09ae36de39decbdca3bb6f977959578954ac17e3d3841d572673e66401f816edab5c23bd2877e6d1eafb9ea03c5c248d6e56679f43b33fb553aca2e482f0b61dc9dacbca4b91cae9a22c5709ba487779795395e9da6ac5e2b576c545b35e61db1a57bc651f69ddc4634589be9a31a481b2e6a365941bb07da679a9ef8a6324d2dc68438e8ba97cca7df6ca3fa79f367ee0cdc651ca753c6ffb8e9cf47eabd64cd266d268ba3c18a30168452031b9458b3c4a084a7a964ffe7fb88fde8f8f6df75cc1879fea43d84a38db1933298f6c98c18e88b5aa96e9d65e7a638d374626575ffe73afd4623bc97d4db61b7e24c899876c3aeb0d9cd277f795e0a65d45cd180436e8f5cf876e66cb817e262ead947b9f6c80c6b68ee3697c7a200b55f576459478731ac9b62b767f443ed4105a8313466ead9b7ea9d4696f8fcb791c44593a680ad34b8096ba82434828c59f638a9a871be4b611bc4fd43a0066f4895ab6760257d181954f3f934e3f6742dc54cec3cbbb9dff9f9adfd195e7374cb6fa9adcf6bdad48798dd30173cbf7ad3870effccee35cb7b620a5b7b3999b94787d401b9e7c6100d6d7952085257f692ad9173888f28bdae384635b2057a8183ca07853de05f72437d6872575ff4c0efb06259e397cda6a87a178498c9aac54b046a8219d98c48f113319984995f68b1affb863ff97dd8d14cace2921bc192e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e731e0a68940ee5b8307460b402651457ad1a7883d0165c8cab4d88f565008155ac009776500f3779530958c3003c7603c900e50148088b9420b78eac241dc0aa11454195a03998388ac747fc465dc140e9193a9294abb90b8022b493e069ae430ab3fc9307fc89358d3a88fb054e9836cefbe45c44569b285b01ec892d5ce8288ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc06a08f521b6063066788841964696a31547c851b578fd02434526c7e641fb9721cd390984bb121518a88633658c7c7c6b0830cb6800b2368cbe703cec33a4bdf319b49909b590a8bbc6542a108bf5927c49dbaa2c5c5009e002e242ba210a64f18b8542be1cb92a8293c56586b568b489ca697d6c4f819c399590472e8b9de9573a1d2934b86bf2d2b6f92ec8489430e0a681fee0a22bc3a705396ce6a74c1d5d3a91aa253da718757c875a1442fef4241f95b516d27220973c25e29b1d335846db494db4cac3a0b76388304b4252ac2362ff032a8b5c3322f6a0e5658799f1193ec69bf15c77e5ff2a3a2925690496af4320ec688450058b5727a0e66f98270267b3f49270e310714f353dd4b74410a9a0e778a1e030461113cfb05a142001cf39721215026cf84b1c0e706dcfc4d9ea80514061463a16e069750c026ad26ecca10f5830b2b756d515ef1c64d6d2c5e73818998aa9230d19d35842400c4568f62397eb0a42cf86c857c3ab009c8c831257d246b456996bc1bcc378a44bd88a0fc3469b0da0d22410218941431a12f37831653342f12206c56c4b3bf980a5017114b3112a6100b06a2a62104c48ce8639d1830e785cb3dab23f398691b48458d2acce79511ad276643476bd6c33d8d1c40fab1b81a96a7dfe36115e49a07f8c72240b9b3f24a2739b963609b0c2705f928c6ba7c2fcc0c164be46fdee5baa5730cd7a55e1221cd73305bff9b8ae5c126b8621bd6116c17286974002c88785c745bc32f0b86dba92e072a395e91acf7257ac5ec5ee88a7095acc39ad023a904b72c0ac845a318d18c7c72a0c4387cb470c8ba438498c5514398c70967b46109e18505543a98d51a3753bf3c657aef7264a91c2253f801641c609628a7f13a246d5aa13f3a4d1da22221ccba20091c6284452f376b32cc2d27d3869137a3fcfb06b7c93f70f3a20d84741b8a186d78af94c204bc0b6da175175bd819479485db23bf6eb2cbbb62a088f2bda7cb470c26b281e29e0f29a111688cc2e7cd61985eb39287546967ad991eccb99a6dd4b111861755964a77e3a7d2c5b9dc966e6f51bd53d72f9775a624f344fdf4bb3a9822d26b6db6b11efb527a2138c45f27c5e8a834ebc780e1e8210a9a7a4b7c3fc63b1757a22b8cab57bc07aa27a228cd30411ef407bc276ace8c05498cb641366b4ea0caf8101198b35a51d502a1c1894eeb700a832d70e627ac0b7a57543769991f007176cefb10c6e74a987c1d9b9750db5230317298a800b508d41c942b48c36035915c0504646726ab767a5059d39996a3e310ccbc610d878f9b7503b08822bc1541a359c807526d27a7abc1d78e3c0c3f67f0609c699e44ca8ce2c7a78e70042be21f4c569e9d0494a6e8c2f0592ba5060b365b57d1b03916e27fce04c42205803af0b213e27b21245e480b6330bc8533888e72e9bb2148059ac42ba2ba2550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de4898181422a34b9a239508878a0682eb2466a44a59542b268d31989f049f433a7a0225d556770f4391dfdf4432133a0d888436afc531f4584abc40022c36314757e79538cd1c67da58a049cd10baab7a7fa38293ca84403291372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc7e1c2e62a2616838d5d13674b832694975cf1396deb11a1cb5a1bcfda55ba86583884aa9593399a047f00e703cd458ad157333c349c46021b7ae1970bc2927f094c77970a7c9bacfb0a6e02108036f809c9ac23877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e4359601c371b50b50b5306de33cfd476d3b5f811700dc4918beb345840244e3a248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = c15dea8dc9b3e3c3f0f882baa4492c72701aec1c38c15825bd31c70ea9190b9f8dac474cffecc40a279208bd639ef51489b1de937e444a4efbcbdc4fa7672f5485f1f3155e913ef6e79de719e74c08cb86ae841cec022278cba60e42bdbb2c36db4f558d8d0755987773d960901daaf8ab6de00dab4a3d3f0b89871a1ebb51713c2c4e094ca0ecdfa1c4ce541b2eaa57b13c2c73bfd3062ebc9e313c9183d90f621f978b0e984d025ca549ef3a493e663daa6608ffaf322b5e073e0b0a432926755b8b2953ffb7072d1a9d007d84666f732cae69d58c3c5fc133e513f2ebc54f04ccf95e8dcc87f0448bde13e581c6ea196fe22b1fe2a3f036153f7d4adbfe39061d5a4f6cd33bda8a2d68f491cd4a287366c7f25a586940a23b08f893d24cd62335130e210c02b1f4185b7c0788e23117715e9ada8a65bf90251321c8bd7d335723977606aade969c34f346ecbb3680b4d27af6b6c718dcd434a61ddefa5d27b24e786633928e13e226f1d63c98c408110f6cadd667b5f4a7893fa9c0e037c0d54a138d106801ed57c059519a774193e09ceaf35f21f6e562bd93ac9c4b2f85391be1ef215d8a95350abb2aa05fa90407677cdc4b53bbf70086ccc8aefe333c82ddfb52f2ffc3b5b2484e1c7b51597f3e915beafa963dfa604643dac74ed40afc4d57161a050e70e9ec5bd460e919d8b385ba68e0ee842391aaa355edfa8b930bae45bc818dabe3935c40cd6ddfaa068897a5454319702e8e94b1e86176939e9dd6a6034600a9347d00a5b561060f2fb1fd89b7cd459ab76d8583171d95e74122dd9a1e8d9942dff9febe0b30af1c799d27db896abb738c06074781b192bcfc468bbc267021522bd2637cddfc937251dc0c61c8f61e6f7acc1c2d25bd2688a54d81a1bbcaa224cf818119ab78e1e8870bbdb21396e4f3c300d63037867a8c9fa61577e0ec11edc7126f0355d8c104a5aebe42defa7c9fed646a4708c4de81ceae2bd23ebdb4362293c442675f754716475256be312734579837973b7d6a7beebc5db3f08322e76d4d8e3824842a930c1db7595505b824c24209c994881dec2d81db4fdbb6267cee4c42722c15817a0770f8c84b2825dfa882a41eeb123e4719facaa0a4c1dbc0fcffea49eff0d478426e3ba5e6f6ab077d0aeb03d66c275fcd86e4c0fb4c3561834ad83cdb9663a77e10609cbe92d2e3289fb3fe0ebaf208bef6ff9021a95f86edfa20e8af937ecd483c60c5aa0bd948d93fe13dc6dc6f1f4740c0ea16918ba739bfd5294c8081d3c4e5fd2aea8674744738c9f5f221474f4500d3638ab4ddd06710ecb1cc4a8aa7fc52427352d68cbf723dcf8f5a3a9948c9e3cc37bfde685fe73407813753ac60b6e129ce3f432332cd2d1eb3caeb6e050698f90e82d76987e3588cd76245de5f0e7ae7856e760c39b3a6035c2a25f568f496ffca9ca83701db810f494968d550e3fc686b6388c808657c75ae01f41927b4149962c1b9b383b26705b8b54201aa2091e7c33d6aca433a36be9810eee0fa2bb8b5d0624c0d7bbd0403f4a0fa5444afce8d7df30a18aafedaa3397fcf02f2867b3d3895719b03e237c0105e5a5b4b6e31b10610383a5660dc630fa5633ea95e2e3eb0e92820087f5493c434d152ee5a781bd50a4f6bb2eb2c3c3b146cef5528031af3dfac925193ea62d5ba10a2ee26b600703b72592269c67c6a244cd7605a419b16f6e65035fab65db94ba1589801f831d27fe91371c6f8df759d0dc96012137a3348498c9f9e167de687ebad6b0213761965247379bb12e703c4dcd8c429aa35bf2abdc7dcf13c33c4da813dfa6732e8fe2edce3136be82e4e58ca2d620a599e925327cae64a38174a581b5a8c5c1e526c24f0ef70282271120b8edf6fd0ba1b31190c8a81128ac4c634072417f347c966ddb3b9393386fe80b15245b236a66c8310c82acc3ec9ff85b33282540a40522256188af8ce3a4f961555354421eb0cae489dfac24a4073d5853901819ee24f2b2bcde412d48656e6b517ce5a247385b598c293aa1baa8e6073b9344025392ccf33f14c7379732a3e421a5994b619bf2ce5c3988541d9588ad4d4fd00d1024308be3573e6be351c43350eb29f5a1cebb834dbe1e7d92dbc95743f3298c2c1f5474a10d73b5c7b097eedf174909b4102a194662e38474359ff4bd36f9f6d3797a1e0c6624139c47c30ad263769c9 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c6389f081ca0932ab66f658047def78b38bc42b5c4e1a7c7a52bd9d9ae59773b67abeec2aa8666000c6e6b0e4b5c0369e0fe47688ac6fd48c73d783e3025c92d88fa479acbde8a7548384b763a868c56e78345a773a9852016b9fe765db0bbaba585ee8056b7564c53fef8d40d4cd1261e5d323c62a4fda2b518330b6cc4abca84f62c792d07c1e2adbbbd7c5b9a698cb683981f98f8ee6991270d311b0f81dbf9c6c9e69daa26a447de36e9bd310f236d7a5a49b2bc616fd346c356fab09544998c8d5ef641e7b48c35ba7a69ff541407d4fc0fb501c69c58a9b798c8c76933f72ed9bf443fd8bac3df2db45e1cdc56f6fce1792a33ec1a62b3fc99254e527e63328a56d03db49b7ecd7f7307d6cb1ff0de94bea4967213e6e2b6ad3b2c16a9bd4c66e0ac893273e69a87aeae67843944628e6374b65e8bf419e9840b8e6c74e72be3a35ee5a29777c0354633812d3072ea50e7daa4f906d01d6df5617fe137c9e649c97417dcfd3e1677017ff6d57fe073dbeaa213525199bbbfa78f1899a53dbfb8d018e9869867a42bff48d6e5f0efc8da15a4e6965bef0c4207a499a2156ebfc6e1488e82d85a71c9f8776d38d51d1a6e4b1d4e556e5993ed595ca9b0cb3adab0159575863f3145b340149894a5d2b2ea4392c777292e5f880dc93f5846a1b8e26eb6b72248bd1047bbe62aa58747f68428509e53575f945735e75b42ebfba30fec24c990a857f41d2c3534cedd50847c85d98143fbb2ec5e38acdbd55a8b8bcec8afd7b5697316e65af9821918f1a153d1ef0a90c3e8f9ee9d354317f5a99c67745ca4167ddd10d7c29c2f8998d7402e0cf00d0476c4d74c34754afaaeaa1213c9a0198065378de3edf3eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c60486dca679b301bbd8ef1a948a5a83debb396524edb368c736a56977f78af0916364f278a4e3973385fe3f8af8ba80f96d29e6fc65cad3b33c4e1597f818cbc489ba97078d999c373dccf46741cd7d97c5e1ea5aa1e6f7757f4467e84ab9c5bafd9ba48502fe2706788cf5ac1829c7ff0a66f26d3daaf3f7bb8ee67bde95fb68f9341be87162a5fde3a7cc7ada05fdb6f27adfbdb0c6c4f75692e67ab1c9beb46b4de53fc901dd892a3f6e2b0decb2ce5fbc6bdc31a1e37e70fb0a597fd3aa6eef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2ebf9b637a5e22559a59971be56d050efa40f7c33071d377a6bdeacf79d85f3c86223a4c90c31c249531474860153efa1f49ac0ff57551daf33f7367c5540084b75d6736ecbbde0290839ee2456ee16bbcb57c602ff6aa104916254a68acf4caea8f96e4bcef887ded7485511f55a46c75592c88d6f86d05356c397fbee61caa04bf55a05c8409e644055759a7f6dc1c93ed221fb97780b92c2c8aafb6b94c259a9cf6f91e18a801b8f456b93c221b6f512aae7213f8f11574a5c35c3650a7b586e9c61f47ed73e932a0ee9f4d3e359af6a7f9e91cac6e012b7eb27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13e4e257adb443fd428de78f916d9a11b8cbb485d8381f539e1ab0359d3c30f6b73bc8f29ee5df902be42a597e7fe48b6333ac8f1ef0558eb10edae5f519e40997e66e8ecfb84e7dac43eca24eccc61a446b285c05d9a68aac887baf3e17ba7deec8521aaa3088dbd3cd7d56560ac66987f609c531541e8b45d855f7dc44618b743d2fc779145d58867d050ed2904579cdbfcdadbf8be8fde9c025e1644b3a9c288a1fc8465838eee259f12406dad499776503e6380e76a0e3c327458027facf937a38eb88ad7ca5ddb7eb5c4aee7d4863f8237eed8625581b4bf425288873fdddb35d37542360cb5685beee5872a935069cc09d043960dea5af7fd84f74b66da89264beee8d177dffeb686a2445129d65d8c59249ff3e0e5e5ef36df177cbf73ad6fa9ffaf3e0e48c9224596c44ce974650dcd8eae7dbba062bcef017898bfbd625c75eb2ec34450fdfbb3e95f509d28309b026b3fd431e430fbec1eb2b7d88bdc283fda04633499c3a9478a7b756edb1904794f6adb9505fc0540dc838c67f4c26803d5fa0439efda9c8cac575dc3367a7713fdf43e3c039d3e09b5d6731076c8edeb1d99caafda48254a73ebfb66849548733578aa80987b45a404d892f45f83fe6260b4521181484a7ab65aed79a53f2e495ad444066d1108d14c4fa74847fda990a783fdb923734860238a94b8634217de964ea35a3d4c651a15c719301a2cad86352257c2ca1a87f329092e18c5c782ace76ba239c6001143f87a0406da9437d7b19144386b9687023a34a46814eae040c71673aca3993acc03879c9af60ca0e4eab9205b7ab65c33ff1295100d349f84694abe062672135865494ecf58db2912a3af380c228b78d329634f359008871769696bb357d552c3e9fc17d8b636e1b905303bb2a5b6a6f07f478d4229daac38ecf47c205371705b72092f7a438d01267783e24370080362c659796d7443354d92dfb9bca5ba5355e5c3608bb3d9b312fc7ac435b81cc1a6ba84a74283763a520381e9e3c998dfba80d8383d416495b42b7b6ca3e91789c8191b894350f52b6b7a3e38a45f50f39497794e0971650c446551d7d304c87515bb415773c10bf08cc20506c0f515428e8b9037c42a837469de6a3a37c695b602407a46b7796593623a9c840accb5a6b1175a30f62c8b9461c444eb73bf1e22418347af3d92742175bbfb41474156745eb0dcbc4077eeaad6c13c314d3188d3c9bf2f73784c0cd1a215c4623a8bbb19997d82be2b1719346190f054a1ad92819d9b812028633469c3661238fc66cab7c05bc5468a132c9b3a50ea5a4a8ea04800c97c3b391115725011e597312b7a0440ac2da794859776ca73b550d666a8f058477a1a0c9621ff6184f415114d35514909719234c166734b5535b863afbcbc5a2264a86b0642a41763b6d6da15447bc930f925415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da37862790a282b8db833ae37bc5a6940a8b95926f1f468853b288c9a4c7c128bcb56c7a218c3fc725ad1b89c829799b0a8a1f3718fb489b83b900f1cc9b1ee16369f18b207d022a35224330582bc4848e4634f3490c12c756246dc9f3cc27550057a1863ccb91a4b891820bc882c0e6024e1bb037677092c633f2cf68b96b666e1034339ca3e43f6ae7fdb22f9fc7649e559e5d22a07075bde79a82e62b5a5258a0e685a2cd1bc8566cdb4a19d5c581236f0cb4e7aad6f561ca9f6850d30a6fa0c1eca230a06e11cd6f26194f56f40bbcdc99bb4c1f32c851bbb7af48f19d813f89b01d9477861e128631b9b4d72c4c7ccbe59462a4519a8a34a44dd84586c4a542aeb6e1338b6836297a59283af07ccecec01ce074d8469c93f509f09f7230c092c63f2245ac2137a4349078a473d81cb3f87cbdf843645500b932bc326a85fa91095e4513e9dac02d92a69f5acc4200bb1dc0270b013b1f2372bc75aa609e291f0385bbe9376953cccb3f99971dc9747cb913760506fb051ed186454255fcd642aff73c32743158d467b0ad012aaa439c9335b4ee23a426cad3ddbc4ab882076c2bbe83321fb684825b032059838e3d43da29852309b1a7c15c08a5669a3ba2200b34b7f325a5f47b479aa49984060ace979e9db6bb68466973a3e0030c0bcfc4e6c6c13f734b1731ca956f89341d37b1cd5c40bec802a98c674869c04571993e461446b2e2a68ba71915bbefc2d40dc8756b9ad9bab639ff6985e03b5a861785981a7b1449594d584bc1cc4ef7a4333e5453944c61d0145a5b6c999900df26299ccea5cc1d36fbb80c1a5e9c619a4347669377d541519ca47f06884b1984408d43b4133bdcc488bddc599c4057b14a027d051420a5c17cc1671f18a2128b58e9b7a5e233a6ed2da288130b51e47038c9aa2751556ba24b284515af73a81a6881d665426d1d27a8a763fb3b2caa19bc310a9c10024b7d722606c3b6f19c8935b744e28333df8b9480a0083eb588380e6a12d777862e5c7d3e1874e8b1405a5787e92accdc798a873539c133502569e6de7a29c7025289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960750209ee517629ca2280bcb7df35793bf233fa074185a04894ac515b8985ddb5acab68ab379a639c49216a8ba4f9b125947150a907385e9729a7d621a5a9bf8c4a1234e6ce4411923c18ca0e925cb372c59220a502390e4c740571f71eea1083887a5797f5631f614f4e91184811892c6086b0f5bb6fc322afa31653509c8e11a8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2e1f6c5a99a49d6b1b4aa18089439bb4c56ca465785bb36594ef2ebd3af20d5641646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = a9bd39228fd0d5f72c71828ec1a4eb1d77b2171f65bb4e14c300c72db4510fd4d1aca62ef2260a8a014b3c7212101eb18b0fc78ec307f37e18bc0fbdf09328bc407960f5c850459a20fe17a9ac953874e4b19f75ec9c97287a4658f3bfa60917e20b17df6e662649f665d0b2da3b362acd21bfa020987f9918be06917c1ebae5fb91f445bf7dd1a5d25bbd488c9dd814fdc28972b069240f7c78073d551c6c07dc6dd643af417c00c4a23109083e9d82f68dfb49bf84a92f9d9fc948928ba7720b3ae0a9cb0a327460872a0cbe1086249712c0f3198a37bb1a438683a298980cdee25fd99ca87980551c8fa1d18d57c1658402d0ad8eabb57148f1f8c64f37fcfe613f191a0ff957aed38d7b873675847d4b885b2dcc3fe28d41c48caa7069eb650ab9a2ffa33cbf6f43072d6609dc4d2cb192a43b53fd67c0e549b65f5a0360aa6246ca44db675d77b7fd9ec15bcd1dceb6da84d7ee855ddb7dca7891c44055e4788009416b198f5a82f290533565c18f4889b77cbe66054edfc31efd33a639b539d0814be5b5756c5c06ab84be4df37cda9eae6aac88397134b3e97c0eb64639c29377aa216fb535ada2d86d7d441724b2298e6c76a41fc56250cab16477100ca437276d021c21215452db5215d749c568e9fe92f69a27e79797c95e421be93ae2497971ea1b318e71e706e66f293187502b2c788fdaa9dedddb8f24a7e767df6b4e8734a7cd988d33e52d149bdee4eb7578912624e2aa2d7206178ebc414fef841aaddc77e78a499341995a26e1166b288ee5adfd5b31813692cf0cdd365919fb11b3e566e6cf1003f1f7eafb9326ad6264383fbf698a66ac2ff656fed3c568f1e63b114a4549a30b633435a2f1b6b74b7ebbec9a9add304f6cc55c2976165990ad993c9bb7a86e90e9a3219b64e7ae8c73eed25ce1aef76afa9b7a5f58caccc904bbae8a51af94edff0353799ad64cbd70ac8a371090b7879ea360fe156c46d859dad7d89b1a444d647b6f93d17009562764a32c47924762c99b4f4c53990f7589f3a5d19a5010c3aac375c7b2faf5d1b9eebd6b0234a785db84baf242a99e409205a20c5a76822be5a364f89531195adc7fa4a10aa1beed267181c706371dfd4331e6638bbe762d7ca7a2e0123eca1a32041bbe27ac63cd8a87acaa09f96d6c399e1b06435a0cd80c0c1dda988891413a6a77f50c20e10d301541a989c2a7003aee10864b01019ec21a5b7b03a454b46e2297eed7d8436980a7bd16af924de74e9d12a49f895f8ac759a343103cbbb63f904bb9ac01ac6686c1f80b1f5ce3e1f7d991ada16b2f9a884ea44ee87f6de7b78ed45d77cbc93cdf98b668727b518b8865e9edd9e28f385c44ddd63ff1fbd123b3d6e16da6250172bcfb2d1bd5aff50c8f465fbe3797ae387f2cb003214773f9f162ba2a50aa285d101ead34f85c586bb0df460872bcb969db24821b64f94e6cd0d9d498b821e5d5ae5fb9efd604e3f15d0bc879e634ae325481fd9a401d895812add6b0614c87a28956feda8937944c61fe76c9f0733dc2b5878e7ebf95728c4eac151b80ed0b338167d528e435885d73cbbda79a3f9c0e3d074dbbca283b8a91445b9add3b7b0197e29cd4b52a69c6841df1fb2e6c4a10639d693cdd9db1aef487747825224757b08b9ff3e66d76c2bc1075c40241f5ef6cca4a2fbd5bf161ea978e8cf9943b8970af717deec6a16a835ed3c0e6106c82213d0a3c724c40ebbc4c7041f4e658ecfb5d9a97029b8f1fce55760be4a2eacff5d037e28102848095b942b0c1607bc8b9fd788e0194b3014803a974c5c69d315f2f8f889711eedd47c301b50f3c6d4f41794a01e0b9be3630b0dbb3999882439426c567a15585cdb869bfc4e8922599857789eb86d4df864722c85e0a1e16e544668aedf839576690e002b79dc6f8362827f55a7c9066f69978c1c0e927b740ce3a8b93551d816dea0d7604f00629aa8a3bad8449842b61aa8707401e24a34573a0540bf6ac645cbe5857b141fb559b89405964dc99779b3ba347f605fbb940e4c72f4557761ed73d3565043a38b1d136511708420cefc09a625ecae3b9631e858d22d3d355d055b9cca76df3085b15c8a0d80fea0519a67480a2d8182efbf49d957331954e372602b42a3ae09ea33f9bce9f40ef3e9b3ad6b6ec50880f78ae8a04de4175cac0d509dac33040889ba1ebc108f206 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f85e96a68df4bf8e7edc544dbd65ff6c4fba122cfb8ea95e560e7857bedc5905a8bb2590e63b449364802c6b4390ce9eefc875017acf652a8f0d6ab0f7f5aca2fe833ed3551d37419e9d6d2b65e23fce4d601d9abcd9382ea9d628bb30d98fcca8665957346c3a08553c97dd32f77e66348ca9dc321a6db7d51bd9de74e7851e439d1fe89affb8c583762043a4508c3160544ed2264735d6d0a6ab43c95e553223d583298a1155dae3b7c99ff559a1d33115ecfd2489934518bd52fba1cbaad19e9e8464b59cc909415a9f53957364dcca9f96ad8035f8be5bd36db7be9f1f29ea6e4b7fcd493b7b4ec90bc76fe98faa0f3b39b6f454785c5dd2eed6c80960bbe5846e9dbcde837cd277a039ecf2427b86a6658f97b6d101665f3f79e25445647f3bb2d41f5c80d89aaf6d96a02cf49033f19349d9a9af925fbaee7407b3c90c8a53d958c1c83465e557ac7fde545d9ee8c960b3c547ffad8d4f0af2585fe13ed9661b57ae1c3dba5768645c73fde76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0873f73c345c4c7379cf3f873fa5953f53b9a026a4dc22dc96e279085566c7d19deba276a0928693e639b5564a59c08aeb0df5915f5478dd86e939ae1529bb9a3bdb83487c696e79f20dd34f01ddfa60f328184be42b8959dacd683f3bc20f7e9034f3ab14a4745ee62f7afb474dbc4a70ff0c053fca85ffcfb253d0fa5fbeace3125458df8753f5d65ecaa38bcca26f5b543d51d6ff6c8768335854e7487d6442dcb765ab9ec4eea1859b4b6bdd6d918bd8508a9722d5e6a0f897cf95e0b75fe0913d794b46fcf7a78466dc0a18b8e6334a57fce77ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa11d4063696f112dbd1b4434199897998f6e142af4a353349449efa233cf848451cbe6d9d0145090ee37534c42d70fffd2cb82363c847865aa243ca994be499267fcbf5535845cc708cbd9a1e8a7835cf00e8d36768755afab53aba85813eb859ee83efea7563ee4bc158599f0dbd4033393c829aedbeaf89ed852e1fbefeda9484787d51f967e058d41ba3c313a24e4d463cf3ec36801aaa1aa64ddebcef2ab63decaca30102ae089087311a7fb339bd45a163719adf0c313de6307d8feea9af844c7e2cfdb4a5348c1a432f44ebb9f598b8c1cff6f55c4d3cfc22b187430748f8294fdabb9f283dbc4be2d636b6754b20a71280df0cfe4d13b1e55e4746dbf3ca1f34991fe7c39ed99bdf586dd39db8e6d4f8f2df8e57cfde39415aea96bcf6fab63402f57b68f312d3c7acaf6a5f8e55ad69967226dca01246545059e596dfe28199cd0f5505adcb91a0da284fdb059f33d1a8b35211da3c815717fb3a9482c946efdc74b5f6353d5c9eddf590d5d50996393a12f86841580ab599bfbc8838a53301cceed5fd492b04dba272f4505969d88f6b193ea42b034895428de181f4ec2c64b962a92aa9c3fe2e7ff954de531c4aaf857f4380fbc8f9c37d64b54f20ac003b844c534e7e1436d2e75ac09d3e3c83b8575e791a7c95d051fcc626fea682699766e485dfcf6ad7baa8e065e9a279add83d1c5c74c5b95c1b79e5e69c9a6d4b467a0ae80aca9817d78e7e183e4da19501354f31a58c8557e48cbf38081a8889d0dcdf87f34d14e69ece6bf0abca31517c986c44ce87ea32feca99d06d62448d323c3ed92c9c10074982503df1f7c9c07a9d7a585de3f9be8ad14d19419f093e7934219a5b11b402838e0307748194e6d5385497534eefc6bb8bb85ec5069b7099671d0768f3bf7421924fe89ed8e5874fb42bd4eb673f4393bd950dd740cd4585a27ccb4ff5efa7fcc26b9512c29d0f8c6e040ea7922efef142c7e1a99b886f3fbb817f1e6c75f6a999329afabbc3c797965c09c2d81671346355b4bf8c78c72c6cd99ede16db3423a1b69a008d615f4f3bc1bc6522b5fc77abe492740d6fa8227235e3c8ff6fd99d64ca494ea1eff1cd6fb02f95524fe47bc4fe938dcefafa4323173a8e06f64959a5a615fa3b218622007af0408c3228ad53dcb71164c9a80cb844f69d50c1e3f497aa3a66ce1c317c9e6b6a6e90f8c23fb4589046a70ebe027fd7aba9b45ec78ca14d9babcccfe62ea6130d8414e98b85de8a908aa6ac1e96fd9ea9bf4595a7cd565d91416b583be0c3355ef18b9b4bc1ea59135d3701eed6bb0b66bb320572189525bf4804a8d75a5f973393cf53ebed81a1f2ca339016e35617e77b58a38e15d417043e6174888ea4408cc8583d196042317f3c9571e6347424c032dd459ecb873d7f9312fe891a0a81261136690363b816a3b538923e56741cccbc86d477c629a1713e99a4be8aae2b3516e863ef232755fa0025e40a664b714bb5c8b2a42568d824246d069ba2469ca370c1417a6a632978dd39503e433ac8566708c21ab04924d257e8002804e92147db57a8d39168c709563e7604674ae830c176914ca2ed38b9e793515231b7e15b5dbac4027daafb276099c0036f81621f7dbac5d24c5067023dc6b219881cdb9f290bb9454adb45a45eb1b975b1094aab8b2a9afe05a8240476753ba802c15495c5034f9348ec8c732724c9703e9a08220854a29598cf42b6777a19eb462c4907f0a7b5a3e991a5d7c4d8a70a78ed5cd35dacf9e98c19c596ccc1c4710ec9b029700acc002a1c661c13ba1c25a1d853a851054546c33b1f4032e1f089e9c4c8af9a99c3c72ae4077272c3a37839b817b55a31ba99b66580766fa2180c35a50462c0b98adc38c6ac1d72a7396b28e36cb6a601cdf7c9857f5413d380a1d031bb5801890182518ec414dd78a8ef86edfc0a1f10572205b5593623c41d873da21aa60e3870348032497b367bb50dc6176d415ba54f8809b4155462ac6d34593fbf57fc7d5bf64c10af1ba368d52afc8e2ca3ff8467528c625b26709122c6b1b34648247849338a24005aa9100a790b054640ed59383eccb6415f7a15f2aca63cac12609113d843aea83814691072ab8292b7c5db1d973aa6c7b2bd1a4aeb4bb1d58ca7da26b2e0296211042488c0dabc511308791d7a8ae725c922ef374acc53d76ba5a12fb2a5bb94c309824ee119c87a62f5786996800af28d11e59a83de0504413351651d0209e98b76513747d087333702cff8463db4c353557632c8c46c3667623e012e5d7937f6b004bb549960c5760d15d08d1a4e85c288a2044d1362aba2962d2b078b7854f997abf6072c390342536a8ae8f62385a5770d4752db9f979fa09037bcbae54d4583e17c4be538100349a379502dc69c283638ecda028ba0cb1d21426334c4789715cb39c79cf408c2d1720afc8986de03627b28efb773ee612630b2ca1a0a81239b6020e1380ac69be3cf3742014c52f9b22a118aae7092efe8c93705c0a7a1a8849c0216f776695840bb0a168d5b991e4ca78af08255646000fd16373831f8ed490724019aa15c57307bf06011392859167d0ca6fe88feedb49878c7bb0609aeb604429710db83b1fa592c7a5e911ce795e093a9602875700306d38234e2a70bfad422df30380986533bcec5d8c119bdf3b99e1596a05a123e2d3acca83031ff778c2181f75d268d6aa98520c969306cc80863789724c0ec5552eca57c3d84fa141c69e07b39d9518bcb52049ea04145c34ad355cdf65cf6c1014f511b9c6bb9281fa243000781a99301c06b77ed606c0fa1eb5987e76aa5bb346cc85c85aca114cd0a51c06448c1eab496299515d7a1598940c33c8bc58db4486867158a09080b97674cc9a9f7a176fd5034c139b19a50d4355011e2b65d47ab642c84812c74dc16a83fedc38873145ff3143564c4aacf969f34ba743a14595bb0b5000c30b47662a7b4eabc0980aeca368573550c3148811386ee589a88a53cbc6be1ab2755e58441b6c87e83baba58b63bfd097f0d4922ea7c0aff97143666d912199fc4307a3bc086ab13d6a6481f411bf780b10f5e04a41f27f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9630c2c0dc6bf3987789bb59195f416f8661e6f5395839c68a0d85d13d0ccff807956a28124e47b5b3c9f3aeb9537c3403671c03d28a09610c89c8c6c69d9733b320382a84a6cc2b9407743cc66611e84999d11356115060e6c2c5f9610fa820d18b355b64890b0a88fe784a39ac0c9e539732d79a36832492439944b643436b84d4bc870b5c21a5e224e321a5e7a6931e628342ed4616fb4b1997cb12fe6be06b20e7794437512be498aca2c532c3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bdb8aa8568431ffc4681caacecd4475c838cf7348402a06413e7a9590ba405ea5e79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = ea8abbfdb194d0c3034901ff96488866e79fb029a7765138a85feedccc7429ed2881a8193fb0b83b49adac508b6d4da1c816fcb4ca95c9c65f4cb761c7d0fe050f60c295a554930abd90ec1fcc151332849b488c9c506a3a704a1cbd74c56726dbf1d1da97d058382b158803a25aaf6229930cacda8e990d6b6b917c222667ee8d1580680f87dee5816de3d2af2b874bb5ecaff31673ee28a02b58c59761651fb776d8f8ed8534e9607de88ec36fd3ec9c041f4e2ea1918ae57a7cf676f381a27e9047e940fe6875647dbb6453740809aa067818d8b8f1e1df6bbd2cf8f2b1e3cbc7499466cc41ace193eda019729e4cb451643790f30f5fd05887ebe9e4250bb47005133b3392fe282bf569a6c69c96815a34fa9af0db7ba1cc8786f7f8ae095463601783907932ad5fc2e626b72217189b93fc390556f06232b9a5ec5760f4069b15ebc878c3050360103faa7355e81ea267094e9064fc550e0337462bc20bc511c044065dfd8f1b014945bcd9be4953b4d4b99ffc633947b0b19b3feacab69cfbb261d6ef365f9802e7be7528d718aa353b05a49b1ce782f8370852ec7589980d0e2dce9d90d76010ffa317bf50b49ff31ab4f4828de281d75c3644e63f383a91ccd3a2cbed9df8fffc533c8f380c80e6352da9a36527938f227395f38d1db181481c65e3fba3ff787e463b241323b05132da8c648b4c8e257b8770f5235120d1a47ba2e68fb5a7e3b96770c57cf8b4f7f86f568cc0b7715d584ddc7bbfdc2b7ed559b2ea88e44ef2c2af0c4e5c0686f37769474b4c714bbab23f12ad0f232777d528c2ee89be7cce992cabfa8aac02336f327c2275b63ef927b010bf29ee1ea7b54476c8a064cb928c3096fe722f93408426231ce9f59f8984caddb27e25bf2179307e666503de33dd6296e312c2e92a3f05af31e81e5ffd1719298401dd2b3f104dcdfbfc31f06cafd0841bd319e50434a7457363947e6ac60955fc8cf2f02bd518b3af0ad77bb6f0da7bcda27ff22d8203d5b3bac070375332cb42d6ef895e4c48b47737b607ed9c1f86de6f2c251683708c193297c353b9a2348daf4d35f4c56a9b87c70f6d32ab17b15f62efab893eca7d269c5505f229b360c604230fedecdd732c0fde78f5d7dc6b8f61655e7eacf9351cfe79ec3a6880f84fd5d09037562c7c30bde8b7db5e672f4210111dd773e27a346412c9a32ca6bbd992b5b7dbe0eefeec512d8a1ec547a8a429c0033f59999eadb257e671be8852095b487e3ce21dcc41aef7efe8c520c52d6aad34451feaa77da8a18546be3d5bd3a24a15c5a0efe090d11798ee1c378b181bfa78b9c79f9509ee94420b5383c51e1f21ef30f95c109dcc534febab2eddb8438da19360f1a5a9ad80e3bb4bdadb8f68d23db60ad9a948b17682ac706e30f64eaca334331f6e9f665ebca0bee9b3fe153437a6356cda49db7b30fdb23b55e0b52ca1b54a115a179309f4763e70c7edfe6fa8cb28d3ff9259397005d4ff4d23915e5698df64c19ad60f24163a4d0c03f682bbae2864e5a446a5ad9bd4cadb8c7e02e8ed83e646ddfba1aceb34eba2bdb6ce854e1aa40b7e75d5a365e774e1639e3230b9f6a4b25493798ee0116365687c13b8be2041c37d81007c66085625143a0b4776483dcd25f4cbfcd42894963241760c1d66371c21413273d8a3ddeaab5e9ab5e00cede4547a3442065b057a7011576a52e4f1c5411d432e94a516532e881a28f3519211e58c25acf0200c8a55f272fb190bdb8af0bcfc4a6867870d4d06494e6105ec386b970dd0cd942853fd98505c4c36676a1d3a986aaef6401c7d31aad6e425ad2047ea3964cb065e714e35891ab5ef5103744d43ed6c4f2f0f563ca3295f7d9bd58a3a2765dfa4a04a055b6ed1a610682139ad91def5a5e5545e526b690d49356b5b9c565501e1576e3873780ca61ecd2b6ecd89f9fd3384b18b0d5f90742f4cefb0516013151c77490fbb2621ef28bba3bd0ff6252d363c224bc27a5384c700005fa94d93ab17b5733dfe45b60fa9bea0168c617e15e37f99b538a9d4b03403913c385a963f2eeb46058709b285aa383b73b004cb89e5e735afeab81bd40d80b7ffd84df84a1bd414762f8312b44f1ffb2004194b9c34f3708059eeaa9c09cf67a98d7a3a35e87b9e18af7afa188c9eecb0a1d5e048b514cb446d6a4bc30e96ff244f07dca9f290699a650c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f8fb5baadf4c878e558dde3594fdcebb335b6f65bd5dda6de7de9e0afe516515ef981ac6473bf63cec43883a7914a7d70a3d66fd1f9ae148b04f96dc2e0eeaf8b5e056eaa5dfd89bfc564226e56dc49eade1dcfa1df58edd4572c6ae47bcffe283b97f1c2e3bc276a471b63a7efecdc86c7a69a34ed17a425b37aef969c1cd079529caf9a3efc3412c5616ef352303e34d0dc77885fbb9b3677c9d885ddfeb0e257bb7f335fd53928b737d19da3b3218f19e6c898e96b4609de136ad9a1425a0986c597e2b4043cea4e6d7a4d0f3de729c73f2bbbe85b579c4ce3a34344a7403b95e4f5936486c3c7df805cd8ef6f5ab22d4d0ba5f3ea3345abfe666023bce6a1b63a97fc33e3aaf0ccac2c40a4d5a58e07d0c7ab1add1ea67ca6f5cefa7137d259c860d13fc396bcbcc4e77f82439852463b74d855cf6d4f91c8f2e5ad89acfe02d6d59dc077d5ef6d54355c547dfe48077b8defbc313d7ef1b5fddadfef6b17cf1e50d64e36fff9f2f4cc8e3526b1a99a2f4a81e0cfed46d9043246d461c7c1b0df6b56a9c7f7fadea57584dfd44c3fdbb6045fc335ddd173ec03467fee46b71edccd33413eaed7bc26af543028c39191d9da52a6ac04fe7a32e9c0607ba9edab5b4daad5ec7948393c4a77dc340688541aa713b596843e5ccba6e6b54f9f610539bfd49e59fab36d59f8ee9cc8b139eac0144f57e34ffaeb595100ac113ac416f05e8877df1b65db6d063512dc374781e7d025964c96ce3536cff09a96740037fe1846efec4446fcd3f93fa6b6fd8b53a0dea6444a61823b08cb74b762d618c08324f0667f24fbeb3a34c2d5f86b4de59fce3b046079f07e558ba28a8893a8c94f9711d2f7fac79d0114c8bb6aa536abd59dbbca00858fa1843b62a2bd6c68c6b304dbac70dfc6cbce633055a178a396ef35f5afea76543953d4bd7e2b8be217c5d5b1a82facd80f51e9d222759590f6280bb8c976f6c1d0baea6658a29546e0a4e8aaf85a121f8647cb4789484bee0189b9bced852c397a3ef5b9b15b71ffe7440dc3554db740289ba062ee97a6e4aedcca796a9d21f4bc3a4c68b3aedf56d88cdd8af4e3ad3edac3538882d671b1fa765e7d5f94f9d099ec3e0e8d62ad45a0b98fbc64de6e0cdd7d1c550998963d8feffa51c7361d86156ea3a8ae7d18d6f7a9fae8f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50f8e7099fa090de5cf39e374addc61305c4de45a1ba255000a7f6a0873c700497060d9dc93f7be47edf61f9bc61af6d14ecdc3e67cdae4b5ac0d5a06398d4d6c6b4ceb351f1ce9f0974324c0af9fac7d4b4677aa4ffbf65686c232ddb74cb9ab507f2555fcbe8d6909754304573a9314b3c846fcfc34c6302b3cbd5dc482e76576fc5900b367017cd3a860a887459f8cae5541333eca8b5d08e3edcd2f3e7d1bb6bc96f4ecb93d02e76d92d8aa780adc6766532178a8cfb63fc710ee24f5e56e91486c3c7658e3af2cf0a77873c944a5a4bd70ba1696e46e18b328e3d813c9850c40d3698c5afa218fb3425c7863dd59669ffbfd7b2ad5568fadf78fa24c52335ebfc966a69ca882f7d7426563d2e0992963d5fe3efa96f968a92e9423dc4a1f676ff6829985008eea13ac23e37fa8b64be3ff3bfe61563fc98c555ecc6625b7a84c79c665dc399977ceeb5f5b12a52f9098192cdd4cc6b83a8d89a63756ca956dfd21758a18dee5f8ef80055cd3fcfa218168d38e78861dafd0ec6c56a98df519ece656bc4dee3a80628d1255865067982744439e83b893c3d55f67466a8c7f2ee0339c56e60d4d4dcd93afed67de199e5b214c9c48e4eee3b36d32377b637dae0c5579b7bb381c25bb7bc9fe59b1beac969fa9ea8e7ccd8b8573eadc7c44ca1f6a8e85f97834dfdd2266fb0a7b050ce6858fd34b50b37b723b42e747948eea600bfc8172e81be23a1c82ace8d5aebf63fe43e495c39bb9e64fe77695ee289087258e6a0729f656d7f69ad688bbc5cb66f094737dbb85ffe46c0dbe46d8de0ccca769aab3d0e3b52fd6eb638bdfbf0c7bdab85dbb7a9a3684dfa504ee5f45f675b2b458eeba2db14ddb45abb314c5583785925bc83408fcaf0d6687f97f2075f886aba525cf89901edb6fe4493cb6ecab86ff61a53fcd45ef1ec58348f1aa59d4476ec8b5da936ad0edb0ae5a6b9a66bab5538cab0ac6e0430bebd798c474ba1ec345ea6d3ba9fa0377d46606e70c86dd1be281a9f46fbc0d890c607dc009f46b459958989852b5582566cd30d02317cd4e0b84e6b1917e692e45c9beae45bc8e8bf6a65587f206a67d93a4872c571200bbde620e2639659302068088bb2d8bddf33c98ef34541b4c2a22897815b809b060f86200aaea90376234860a66e9e8843bb52ca7033010e47c41d573fd9ba40c4faad88026eca797e80396a2ed5586f8109a44bcac355117a7a3f72950030cc506482aa0ce39369bb350fb07b1388981c89400ab5a632c172d159c6f0e126bec96e17c0c18c615be5110818e0cfc2900f76d706aec990021aad6eca787b453991a896f4622537051e3e4a11a0954995525b8f2b11583a3a3e594400ac97b82a4b5da822891910c721ab0bbb9942f2ba777a0c5d8c532393934b391fe5669850bab01740905b684aaa96be0cf50df463406b91a28149174b555c742c3f78569bf294681ca09a336531edb94bf30459893cb2de348330fc56a7304ae2f7cc33d13b7966751414420dd089a48a6036c1cd7c5608727b52612864b63694005590859aadd91b068b053453d1c6f9287c58aa042073087f7959fa932284231b39aa991c0523be599ce85b1f0fb52d465156c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eab32960332860e2a25b7a25e86d0a7aab0226e877f0488877d941fc0a0541461b8a4744de6456df6c5ae6c621a969a02f9c943f68a48809328a0ba3892d7af2fe169ee41554f0ac1a3836e151760c8472f60b77e274948ecb6748c404a74005bde6c5849401fe2d667748b9f3c19a41d659474b0b4a6829d848a898b93080c66aae85b3660d392f34a6ee9c6b10df567dce1892f4932b6babe31e0a50f8217985c6537188b817b3311c25e8c63ca265b568ba9cfdd451e6fd517e18317fb99c8204abfdc937134e845cfe00018e097022997653a8d5be32cfb07b34836c242b74ef9d30ba0d7ad8c2b2944c766c025804eab23a05b6fe6b85d331904c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2e70e1a63815c760da8195bfd431a9fd88443e26dde85c5b08091cb19349cfc73ba195923a38ab6a044d1c9cbe498195c1b5a27a2b07b627c141cac61d391ff1b88c9893327447d32234705d42f10374b77c86d83d71e3711893188310c45c51a5473003d8566d87fde99c67b962f6b4750d7851d3b6201a2faae68fcb1011404b252bcdb341e68702c8dd6a237813e049c42aac05977637cd3c81103e1973f6b45b8b0b56f69afffc9cb5e97bae9b6c5809abaf47b5b0b20471bd77ec7455e1dc25fbfaa7018e58133a44678083c06e06334452890a35240526225a33736a042b1595da8452c2eba086acc1a6cba45beccbdfa23acb2f01cbeb75ff179cb39242ceac33eb2889c4784cb970938ad336da5dc013aaa2973043372cb99657297e7ca05702992b578a65c00c867b43eaca93e975695f7625aa8240c0e5827e1636d72ec4a0480408f911ef631b48a1c4462665b230550924b23481bade7b43a1d76cbe6791e33874182f955313cbe69bab35aa59cd1b133fc326ba571713a1c4dbe2a662b514021bc7bae44343f39138444173dd7944c6291c50973ff0b9c0aacad9409881ac232306354d5362537b507e2ab84b4a0a3b5b9819e62c3b6dc1fcbba0224b48da7114dd4fa3103069caba17c09b7bbef8b94b6e15f58321b708c9c23a40288708ccec56f3fa2bcc7397101fb9e54fcb7e7e816f149356570a006f69779fa6e30b1310e6bc6d983599eb81c202c5e887659f5e7836fb7a72eb80474116c6659c24dfc4c38dc2e8d6a0787a3b6c170a23ba53865a53849f4c3f25b2363e582bdf079793bcb832878b0f7268f658b72b3417135684393a4b1f40322ba7fb147416ff0b58d3b62a7343a6c51b4c8f6894f0b05e33476ba24c61c276652048b009ccc1a768e48cac707a42f4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2ed2429d547b4da5176a7b621a38681ccb3e72d98f1f9926b1b30325d6cbd3862c7d044dc16b8a25dc59c2a53e295040d7627f744bcdafeb522cf8ca6eaca400106b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984984f4c4ef2371654067ce0f22bbe4648dc9d87eee23842f31affcdc36328e8db1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = f513d8cc0665dd76133ac4e7ea22b5056763fc59a9afaaf2b4f583c9ff4347a2b3dc968d66775ce0f71b8895e79f4925f984d20349967c0259734e87e2b2dd59f86a89c2dd4a7a16cd8c67c2ea4c0e863c0b6043a73651f0a7a927399ae7bd4a31cfd904c2293cda2f28cc16a3a3d0311e044b55c8a6a89e147833cc06b5ce9f9f8f745e8ed3e3499079d480c81546ea970ff389eb49e29bdc46f852732ed9cbba2cd47105d6b52c812d91492fa750556e73ed832c194b9bddab98e76e8d939b95984397da789125212bab18dea5ae3c22cdf029f9c0250cb12015f380b33ba45482bb10ebf412d10633d74f7e7a7f63d162ca1c51c14d8799ae2234b2396f38732ad355b7a173a7cbc229cb9d252f7fd6c5d09ab41d20395e5887cf586c63a21d76a4e3e00413bf0af8ac22378f6d87067a3090dcfd60d242719f8d7bce6a281af3c29685c453354eb4721c2ea92b5937742f0c68d2d2ca30fb459153e7a371a7515130c20ca816ecadcbc4ff4969c033c81e52d9249588e854f063a79d6aa181e31ff1cd8eaec38119cf051e84351a3b8570b43dc6d921ebbdcba47f30a7a237e3a74de67b5d59a7f06c8b6fb13e810a9895c9e4bebccd649793ace6f226f3fb9f04c39aeecc9a7f0c5a8d82d862954d7aafd945702464640ba5c16c4df0f1b9122f9dc6942bf9ab261d7b65139557e8dcad44ef29b5a96557c07a311dda243b4c9fed3344ca0b647617eef8d7fdd3942982958d599da0fa786b40b5830fb5e05e32a0d6bfa3141905d4a1b99b8dce6d0bf53212b72454817239dc1d4b8431d4a2acb087fafdb68a326ae4c28f372db791a9c654a079a1d915a25e2dfa117af68d9e0a8f624a298a390e688cc4e8356dd52fe42569f796daab5610c7b2ac4bc7e1e3801c91a49d420e661b9432d930a10dd1eaa04d283e05b3ec41f821cc56f9bfb1eae60338ba0eab94f02d4dd043eef6d6c651b4efc3fb3fd48ef2c420087719e68a790e1d5a7e60fc292a0be640993327a68e5d3423c6df76c51bdc3a787eb23b11a49067f66d2cda3bc4d0fe7c7235b75f00872647581b75afb0b2555e85b8455a0298580e4f0f5b20c57503f2bc541549ba7c72b9d24f28e4ae3f9e0930bda648a243f5c4f473f87d3777333c7571c4981c081992fce9755daed0a97fc4261ed48af7bd55dbc7172a296488acc6ba32db0c3e277c7785e9e78d79509add74de0d15131ea9d1a31817db156e275cbf3334b48c39c8a27387549a92ef80aed8a830cde142ef9109d0c7db8da348697915d91e0bf0a819657c1521ede55af68dd1bc7aca0e7c0feb04d34b89b93df3e591e508ac7f0e3cb4ac98e28d207f2a105a4779ad594af98ca35f1d4b9f2f6babca73ab0f33f4a3011e81d6d74d183cd9eb33bdd7683eeae9efd5f15d0a847db8464ce2d0510da5d8664c9e688a58016e9203f7a3e02eef0c19204fb083f20cfbfb574a3d7b5af99b4f698f0c6248a1c2b1d8989b792abdbb4cc14d04432d56b63f99711e234c3c8fbf26a61769e8f0a251635f0e8faf0eb99a0c2965f1b4ba9804d4090cc5adf1a8c5f9bbd1e7ff0065296dc99a9e6dbf5a4e0dce4b5538b0f1c48f02d0d66a77c3a0c1bcc87b1353a83214218d0be833f3caf5abb13000682b1148623c1cea256c1dc7becfe14b698cea823e58378e1ca704878da44c7a4364a8652cad214df0f6e7be10423f308ec0422000f911bc7c5038eca2d155876da42da83ab23b732251049c007d4f7e1ef7bb35aeb43dc3c730b8d70a9e2e04e5ab0cb1c31d5dccd158b1977208404f8405a6f7a0f48c29768897519f21a8bef1d0da7bf4512d34730bf4cd1fa80afb5034d662a6ac860ae39819d82c6bc7886358a15ff8183f6f3f76f601a1286ae7367e82cb7d4a5a7d814248bac54ad36e6624532536c0f9932fd88a5c79b5615bf42ceeda21129ebdd38297149e59df243500f6453b4886acb80ce1c9ef44ae7a54c8a6e8d4da7b9c34c2ecfe206b6a0537e63749ddeadb645fa1f937c9f7d19acc9119462cd7be43fdfb5efb350c9f59cbc12995d1428edeb0ea90582d985ed0381dc586dc5216fbb5bee11cf8547499f0783c318417a8f7ee101b3f01d99d489876ca4e094f8cab6f6158daacfc9f21e830e798d1e7fd91329f59344ed126df11862b8a355d1b7b567e5676d09e9a9e3dcba5f42e7989a761c26e2b391a8470 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5b47b61def35736f3c431a498e378c6c7ea5cdccb58f2f53112e7f6f3beb724db97349b965d9c9543fa66d7a987aff4c479851a0ea485254755db347bff9a06e0d502ae3a911cd6771aacc0b5eadd08af91496ac11ef899b6562dcda7b6b9b7eb516335e3ffc43498859d87a44cb8ad589a06f6d9fc5798ca06744051533d5d6e54608c790a8abd776cbd2984b58eecf4e0638c789e5dd99f49d4cd775b45cc159b44be3ff49b5ea1e398763e35dbf5c6ccc2dd929c9b91047a1ab98a141fddf7705d8641dc33179a8c80449591c4157cf44eb8c8b3009328139c18f8c59e1a6ea2c9ec840d552c2e4b38a7f65b17cf8de6abb73efe8f07e3a1d179cea38561663c9c02eb68166aaa45748316877a9a5bed605f40e4de5193aa5aaeeb34dc6576b57692b543fff42eb14879a257f8de3d6a298cd6ac6dbf8ec3482db7d8abbbf8fa825f72624af6e26a879f65c653f81257dc52efdeeddffd681db43a977d69dc9bb34f9c541bfeb8d83f2a3675fee059f5f655cfc58dba41f55e899c48a8cf55893d3d77d554357d2ecdaf4d31a9d69796df408328a1fada084ab122c6ac53c3c34ace0537dc9aeac739246e4ebaef9ce4c9fd8d78bd43d45d8557ad4dda698b34a7c073b9378367076ff8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dfed4497c997c9e7404433d690354b7bff3bd94aa02cf599554391096cdd53f5c1db19ac33189b2b9aa3c48bc4e09bcdc60f9bd3b45a370c59045abcc0bf57dd03d185ead53056c17eddb5ddc6494524875bce89e6c7a7cd483289fd3abc155bc31ffeb427b7d5093f4616c124b7c29b0d43181c7bded83de769f511e3617a75652d4568d7c7b3ab2b7464d5e4ce6ccf54fa8d73f6e834e5349676f0dc69e96ab44b746e51a28cd2e065a0017ee5420cfa6a69a24989331ef980f718e42e7f74ea863669b5f039b59d48c9dbcc75ce4b434f585ecef72ecf3a29873d0d3a57276128f7dbb4aa5de68e834946741b8e34890491d37b6051959739fa8eb81c694724e704683124136c1c48f761ee3f00c59ab5bcbcef98b97393eb91ba87ffddf2176e9f012859faa6b01b1649786b626358e823a8f26cf794095681d2cf5801be8bf33cc71123898bdfaee479d5a91e8916ba86523f8a051697f814e667789c874394e97adefcda8998e4f0695fe7952496afaee7c6d6e8514ce47148979f5c8bfef8c7ca1836430c3cfb66b17cbca63fdea2157961cef6d0627e57aad986b61fef4f69c3bee6ae182ad76c3cabf076903bd5981445ff4fefc04a138ae0fbd18b2e93ced58981caa3bb13f317499e6ec4bc5cfab8b389467fff95dbe7305cdecd099364d7596b191ed08ed734d7775c5606af0f2af978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad11ad25f46af2345e2b136f30c09f9fbce4d763e60bad961bdcc4d5e1b4edd34e60aadadc6b3c6cc9660e547ed6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aacedbf05f75ed1bd92f43faa848d8f897ba21906af25e68a88c6ea358ae0edee9771a9f03e465ef9ccd20e145f652eabd12be8ab198549b67b4f1ce1fd8bd01e43731f2383f62ab90adb3e13197db7279021efe2115f36fbd874682fa99606b522c69648543f9e6555827ff35ceca37a9d5101afb9903f824caf88aa3cb7dc1734bd49c0769cc5a44483e13e7dc62961472be95483683f774243e689005e4c02ec73e04b5731c49d0853494adccd6608a575388d245a312a1a38f1f9a17d36d73eb3b6ff5ee75f46fdfc697ce6dfcda7cde45a739e7879c17e277de285d733c9b539b9e5586cf37cbb66cd5beafb4f5ac6ff2f077f4ea5783b579331928b57a9fc407c56541117c8665aaa2efead0eefdd6a39e1faf73c9e653d6bbadee747f0dbfca1f5ba6a1db99e0f87955fb85a264ed5157afb9fd3c35c8ab4590f3ce3d381132b488d2ffbebfeb740b5f6513b31b63cca1ca8389faaf6e22c3ff1e5db42e3c71cfbc4465745dddf8b391ebb29f5f558735145ec799614926f5a55d57c640f673e50be76e8f56f73aba60f6da4cf46437305e14416c6ceb386b55e8c7d154b86e58a05bf337f1ab4376db313fdc905bc776461a7a463b8e40c03739a6b5fd196655871adb3c82ad10fb2b2b538e61e1b664fbaf761f09b4d5e358b518088b3206e1295bfd0461a2ff8553b40cb92e36f0f928af9fc7ef54c358d88280697ac3d5548029c3faf882ae2da732e0c47934b9c98232c40b84a344421e708226ca6524c062302765bf4d593e2d75d3a783f1dd7328767315dda868e685eabc18fdaec2ca8b037fdc3607629cc3ecc8e848c771b94c6a20a28e3003778ba68b923b711060bb6152554707d7e4c135ae8663d87643ec4921c6a5c20ac69e67b0b795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e7b03189abf9b4a91eb782fed97bc3a6314d0ccb528b313d165b2910859de867d7d6290bbc85185b0201561af34b9656a00b2ec32323b26a04888786f81007362814bcc82862a7280a5cee73a330e6c2e01fc9afe2741b12166949532c884ce8bf2281aa4b860756463bb49bd1524b8ccc6ecb6051ada819865b8bbe1bb01141b77fa3ff5713f95baac10866303939c07483b6bfc500d61b7ad494382c643e87508e410c30fe96b37960ad4e707421944b13b31d6686745c52ef6ca4fff3074f19c1695038367b1218e8b08d8e6180870b0fe5b5511e3b4641b6fa44156c561aa2aa9a1e163aacf73c24d84bb764004b3b329ddcb0f15716e17c51c6c432ba1407c0d063b0cf2c073763a790cd0312abe6d26b0d75390492a88772763fcf67e1bf28e1a01c0a5714bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5e80acca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f052450875a8997c335ae85d5b790377301f5a094a5b43b515206067e36fe51ab9af296583d47450a34a302844b0526a4ef891d01c287602453126557a876c583c2a06561a88f9651e39929d0b43fccba48595925c01adc0677200c39c64e44505aa58a9b5c88311c094dc3aa5314f167247b501798c4a0d5d9a04b77c6552369542e96172573e727890fa3b2e3551286113221fe92f81c481c125bfa7a6199ef8c0eeaa0a5b8973c9a33807a464fd4a50eb294741c5a8fd998171872c0fd44ec86112e19a707dec768f7245dd2a6f60a554490947e5152dc3eb9d9e7151ff7188127b5313757431d3a41c673e203c7e8e9963d0ab1276b5c1114c38ec8cc0ba0a94918cbccdcc7dc5366704415cd2ab9a7fe55ed49498b8b7105fb312f4a153e394a019749a23dcc180236468a47d96d47be66a0cdfd16a2dd15aef826041192b8028b1ea782fbf0a2cd5fab19011b219099f8e87c74cc69841f4a927e181e98ac6b3db7846ec38c0ba8aa9f50ba7a423a474060ef165299b12786bc8c05a384ef129b0f6c06c1047e582c02a54aa8713422bb6b9a6a4195fe6843d7c639916943b5793107cb8e63365dab357cc02a9f1b33e8da29f25f9839d862285864ba790bf965292470965e0a9c1d1f65b72139908d791a4d89e489a983279a703a0c34222786e123b45c793c925b1a146c006f15fb4a1c85e181f8b1c6983e1a1d7210c12091d83439ac8a15d965a386be47145bb946162cb8869b359654121092d81947ccb5717e805478a7c0ea924692b361ccb730f3180c8f79041f8d366757528b0828b7ff9531c76690c37cd8072ccb1c36a195a84197a8797446273d686aea96fefc153f1710d98229abf35b6e6127f2e5a5c9e88a33a85a1006a1383988e3c72692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f0362c1f84954408ba3c9284442b59c1a4904128c0bbb50b2e34c98b819a1d6793de75697cd814ee162ae3dacc0d50bade8b835c3f27126731d2721ab61802f544967df987b5b0b02efbc95847a5f06113737e55ca4db20c4400580b5c241016b50db710d7555d8f67cca13b2d86103d3870d5713b217d03b3984334a6ca272d43911ec23db3b5c15139efcd510a95c96d68a70d2988adbd048122678ac8a051282bb4fb47d6d5819a3a9866571cf53b78ed80a76ffecc971b221bfb917bc69018dc0177468357292495d98a022634ea7b0b1f517734ee40d0e927919221ce9eabfa05596a801a342b87267ac9047129995630271c1c2f02a4d1af2217b65c05609b8745306b6a90f86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a174841a59db1202eb2e3744bb36b9c5a229a33cf9eeafca4b3d02d155d870b6bf62d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = da9300af63d3c10ab2a839f3a2e3375613529a345f92182ec42f0212a041d741c6b0963202359ab3e443104a935086117a43bec2bea7ebb7e5f6151c39d2cef855c2f725ca7d4f4d1ffda1752f834636baf6ad31f4245077683ee725316bceae73a44012afa9e923e851a93a74f32d94c47617bb7cfd1f659d81b1c0e8ad2f3c5fa54eef5aaa1b763c573a2d1298055ee6623f31694078cd0a4ce9cd047e2a591377437741296c28773d4d711d7ee8fd4e5b376199d42d86482dcf9fc84af2354b858ff6ef1cc3692ca1e0ddacc17ce13c739544002cf8748dc3ce62418941533da39cde819215927fdf87c4e5f9da167d03dd8a1bf91c89b007cd0434b045ab4f09dbeabee5cb93aa90d59da49c1347d5e9464c6a07c1546f734852f486f9b06cecabc380bc09ff888ee90c4093eefd9354658a26270c0c4f5ec4a489fe6fcdc55f872e9f6443cba943636eebfc49c801a2434a16ae0edbab19c3da71fab90f2a48452532a914ef0034837cd1bc08d9ae64ca3110822aab9daa043658f666f38a913042db83b1a842e463cf9dd42277be70b240b2c4563bddda5d629913815c6c7fde5bac736151cc3a39c773a55190de33d233ada200850c3cda654a37adeb5b643c8daa3e39ba68edfee6ef904b1dde292fa197899bd5455bedff84bd504b48ba00beef905a1cf8bd512c79b847d5dc4489f1a3c0e1394a7edbf4468e8d1747d1fa9a877b4a06580e3126349312d28865c81d59a375311e081497f9fcb6f9ba2530a71ab2903c52cc7707c6269d3ef67918ffbef0aadbe002d60999a41c8634d5ac8e84b4bbe5292fbe735b58ee3bf8ebda070b58a5a699984eb1a5e15c35b49a3ac58d23cf8e472ee49a2b26ad0ad3fce13c18efd85e9fcd455fea61d135c2083b792b503f43f729b27b02d30864e60a8702b749e91c3493872a15d173844cf30cc9eeef4e2dfcaa7e8c30cbf5a72c871201a3394715ab2b0940ace5eb1eea0ec4f4f4e3db9537e4f47c48d48f0247ae78844c575443abd1d00cb5367586f512bbd25fd252a893edb265867f9ad24d70009f9a9449ac0198de1c496ad303d2905daa97b57cfe044cd2fe94a1e8f8460ccfda24b119d6190d80cbf5955148b1d24204029fe471b23df9f0d67b8ce5b67e7a3ab2b843cc07ddee4503d3df4f3ed5ee841f50101043ff92b446d7e3f651c607e22fc306c52d8e49e924ec0c3bc3023a54f6298da4a4cc311ce3ae5b771630a203eaf010e8dde0c302da59ea4b23f60d03aa8d64f16f188e21598c4e50381eed5ef49baa947cc025c7fb508efa602c09dbc7e991ed31f48cd9121ec4699d2f3f0fc259254221f9d40360a15513b292408e04a0d33b77eb517c2438439a9890326a6ba84f126d58a007f7ca0063bb1373a441f8ee3356cf281e2eb75b941818ff5371973aaddd6a4545b11744352a8a02fbec9f9c2f73854430ecbbc6b86936b63cc3e9cb3f5d8e608888005212e5664c14180d6cc1c86041f7c0b3d6434b1a11055c75e3a0c528ddfcd9b7dc81c07180ddb888acb09b338c1d4c905b5b2586581c0f21793b8c788d57c67a9345b3a66b80fe6d3231cd5e4bdf7a50a54dcbf3088fd41a081e8d9d77d580aa8a068fda445cc272e37eb6192fe4b0cee1edcc4e450aad693845c2645f26576320a82a4a2ff4b67eda5a25a401c50a8ed9a932fd2c114b3329a98fbf2ad9a9cce4f2042668eb406aa07c95b0c30c07c67f7442d67921b177c1da33d6d6118e80a1cbcd9352facd70b730a755c15e8ffbcb24caa8bdc2012a0224dacbc024aee430160cbfa260f631aba1271756d528319e699198617669856bbef5943931bc23b5a60e34b05e95139ded9d7b69f7d195cc762bfffe968b5fabb4782d4032707957da5e324d7e300fb1be97ed226c4bb2e518efe1eb8f828fc7b0851be18c8be61ca1f095ae567cef8ad9f5d280a33979d33cecc7a09fb2e9d628d91d498574b46379c9f441de209ddb44402479c2d5dda5fd4cee0b41ef34ff3e1f937f7a1ebc683192b9265a7a92c805f3bae38b5dca4bce307df1423a394f54072ce533f918cadf3a8161634b05746dde1b85918debf842c71c84f43c5643bcc25843940761d7ab0061118c88febfa6bb6f859e74b7c338c58b0ab741f5206fc9bab9692d30f39996571e2007ad0967d676a8b128d9f6bb90f80662f3046a46dded36ba9584c853 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2d1fef1a4ffa908456f1677d31dc8a4a2a734a2571d19c421c47aecd5d7c3c53a9321e3290b693b0deb7ffeca87cd9db0419c48bc4359d74e46d9932beec787674d8f6afe6c7aff28fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c378f8225ce77d3a3ade4cfc20b9d7c93dbc339d6df71bd21b47c38d6d6efa5eacf8ce512bce5fc0d761c9057a7ebeac6c66e98f9a8ed2f67a0f159a5ee6612119f54d57745736cc3cdb634f5658fb684d805888fea8582135bd499d343a545e4e0a6f0c23db8549e25bbd6358f8bcc0a4b44a7a4904ede8ca6dca45779bb564a30dfeb340b4c317cb77db5dbf89ace0b4676f3c295b90e93c264da9e17c3bde66df351c81c58b545306449585718f9e99a74dfe3b0ca1e737c07a4b7e21fce54604590e4e5f4c8f77877890546dcc2e49be4b08c94a744996fe8959d4492f0b7a3f53a98f9a8d914863b9583d8677e2fe583fd2677e8a3b8ba544e902178824f4c41cbfecbf7a4b666acb413c31cfa744b9a5405efc5b54afc6459ef70494e34753c1b14d7e23b95850a8c026843643f4fb329bcbb85ffdf5cbb969bd4f3a3eda4ec959e1b5c9cc3fa180588b9baa690f7459b138fd9fafd0bd2ade910a3efd948c3cddaf04d866edd6ec866b48d7baf2e6fb5025c6892c76e16e37eb998b888e0481abda592c8b36f74647040cf3c51b5ba9959290ed3594b8d73ad790798aa304579822255e62eee55719fbc9b5bd4ca4d68d6db2941ce8093ec5167487b7538c9ab47dc278f15c8c7f324563d3973fa73bbaf07c771b25d70d98d479df693535425fccae108f72ce8ff4f3795a7034ed4814f5e4a749233d9907eec11d6ed7e9f34fac3536365ed0fa2ef34d55769b763cf34d8b991faa6b8cf60126e953cabf0733cd3a08eaf5158a1376f1fb159db3dc6c404ff0adb8acaa8cccb7dbfee583b9909c903ff43613de78c568aa7fafe7e345cf4daa9aaf17cca1b5a4a5a73ceabd581e73bcc019bce2b68c8c273dfe588ba096ec5a73a6edd9bbdd66935bfd4e5eb8ea55e6fc9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddc4f5cc4e89ed773d8adb91e37d8f12b78a0105bffef3d874ceb6d5d5469f6464705741ec53e0a8185a155337306d91c779e09f19527e95a6803cfa4a1f7078cfe126e7531a5941298bae19a3d9ccfddd985e3bde1ac8239fca1a76957e2da306a3ff83994a010fee8a5e9e16138f0477667f338a6755de1248a68224fa79d9ab6b58b88754362b3faf350fd062a554ca8a40da0481bb8fea9c0f3da71987b744c6b9ab5e8093df8c8fd0252dd7f0eb72ae3694ef9f814df4b1db269f4404cd0c77a845dfb751f5a0bd1cb93e6ea628098d0eebc9428f7f77139831575b98e47b7dc3676d887b57ddad96bcaa1f38d049776339cb3fef6489dcdf620563dcb08c53fb0839b4a9d9864ab06b2c3fe15957dda96ccdb9dc529d4df02c6a1e5846f99fa1683838b986daba0d664a2ad39b7aec75f9c4b05340ede9881f48869dc881db0e91e24bb5aec448ea15fe57e69edf254575fca87a1b50e6d3952073d689bd4328b7dca1a871ffbcb0a98f3dfd4747dc859b357fcfaafdfec8ffc5b3b9a08e4534aa7eca46f7cd93547ed32c42e0ed64577a5291ebd57df43d5984eda1befada3da14319a0d85e6a26b5cdf32ca566a6cfb1099b2eaea37b487caa6de9a0afe2d14c83064742ae46985c398749f392046bbf13638b19c7e6e6fb94c8d5331b14bfdccfbe3569962774eabf6e8880d8947ffd596a6e85de186069cb930965fe256987b5fd71f79a9687d85fc71f92c19548c337fcc8e34bbb9e8eeeb5e81b5fb68344ba865640a00d426d28869e397f077a675dce69a27f64635adb244eb758a37d55fec1fe154894ae560a8be0628d94f9cd60330cb03f978cf775e33aa4c9483bdcc169802b9ef8b108b7ddc5718ed6377a7ae1922b72d6f3bab633b3c92da42bef825a53d93f48bb74ad432c56b56565aaf00f8c2228be246e8a6fb8b9d22e700f9bf5b79578badced3d8aeef6de6356ad7dceda8a5b358f2074e113ab967f75c3b2dc7f4c1c81f18b35f8e573d80394670fe1b89baa485faf1b45b2f71b5642eca6a05d78a0be53c7f9b62ecf9440b36ecc40bee26ac378d8b540992eed54b23676827aeb4bd44857c2c21d55d72d0db795b0b6c8bc9077aeb59b71588abfe926f7ca57d305141012a41eb063f5281018563eab7252c34aa832a4bc27dacffb008e6d255cd547a0ebab65f410035550297c50b1a637cdef9172b6d4ab96ac598ad7622c34c3b98890c77cb9a5a08e3411a235da946c92a81d7bc57998175531b203e21e3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2991def527fe6c838d3e1221bb7a48cf7a247895dc77328a07b8c342c731d24ca8a83b9cdd7a47025467aa81bbb0878ae5c8e6fc0ade2f88c68a328fa132a4b5a0298ac19f46098a451870993015360093bd7b0ebe3929a028333312361e07a7dac8c90b50019e73893f78d097028fc5714362c41dd42c4dd71cfbea58e5aa96d82b03f5ef65d572957ede919e094a70aeab998a55ae4b2988890c88ffa1095273b132550068337586284976a30b0c538474a25ec076960d1bee0620a2a875fc53054d28042674b1f51b7877629a1fa815e2ef578afe936dfe5c7cfe6472ae7c264809a3a1285f6a156448246e4e832c75439cef074f62bb4ab5a4bebf24a129c046b0cb215552d126c32ea74088a2a7da6bcbc380354a00642ddf9810ca8c0df8296c55c057df32a4aa14f45192846e31c38919185e2c77cfa199b2003b80a5d6a867cc6764fa4b907646cb923e39bff6a14f335392363890cf66a10026e7de62d09daa31a50a5458515dee1ac7e092dc19ca6ff506dddf67aeb26ba4d720a92310fb942581f69024ba975598c97c41a6112c812aa6a21258060badb32dde0a5eaaa4fec6983776b1348c06a7877bb1b44223cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a277625298f403114a018b8b78af433a15a69de14158657ba05855bce24402243746de13728b4c4359409a282b994f3053777a72e6c30686eb0e4746b88ab57fc9f2558a1a0820c59c2cfc801b97b0206833d4c389e415330ab87ff870c90f86218c3b2c058b97b1e595f87703f6d34118965cc88423e3bb4e182210c225902fe3229e4559ae8a231b34395989c732f54be1b90b3f846adcfb5a36089f1b057c70931921fb36207966666413c8998c509a6268a6bcc1271ead333060d9753820a0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040ab2773976ea3e6876590c152c897d59543fb576e6ba22f9b312995f9969c91cb9098aa2046ac4bc69a38ab5c7a206eed57514de7821e64aa6626299c99b2a7299dfe933ba386a19ee01cd7a24db661356a19a68f68018a6847f56c0247346e294158c36c3da5e51af8604c3ff26014648f310977ccf8bfb36316be8321c71a4e1745237f964b5df9b67f8699454a810fac4fc83493aa2a7e4af61728759a12a769fb751d0d2125413cc0d4e0b5aabbb63b8c8ac5d385a95094e0650d16009da134c36a7c8a59ba90260b9af69542add7a72922c8dbd2b9e1dcbf39e6b19a4815d1544d31547f9c336baa44c835805c1a03610c0ca2b33bc44557583da206ccdb50f1c7309de949996ac72fd9803ec5bb7a151fd8f0b4e78008e35c102a33a9412b40e4b7a247864277bac3c1409006a75596d0cebc52621e91a7af791672e29861533e765257beb06fabe44c20f0a44a288c42d22851433c2be639404aba3e6b356c4671906a375894954849431f71717dbc1a26b19258db8096138cf83894182c88c6d9a56d718f489040667184ad175ca0b02ecdb1b5fd0a2b785197bc696a68471c9b486d7596657318bfd1f46aa29414c436c0f69252ce96bc09837cb4325903bb15d81b3f5c62cbb8dbaced7421b4361a8c196601b002f79877158c97bbc80072ecbc8b69557a4c60c8e90d23427dc7ba806ba6234189bd874c30ec696710c53540f74bf61b2a777606721952f930358b55c183db4f1ea17a761a0cfa14c55ed47cfba737bc75725c3471aa8b563050bd424512df66b0684948d068b94765adacdc5a24e18035c5164c54ca64171143a023a7a07ad8b5ce3aa095c7307eadd6499d89cceffb00f635334a3c91785009fa6a93c1211854882e99b7a32306bcf053551bf99f99c8a458106a55ec98a0c06c7c58583ed757956a89533c6c7b2867b8d3a5fef526e13abe818919fb03a7f9f0cfa9025fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f7243d71bcbb46b9a423431b3b30947eda5fd81b526cce79a36730d8ee1be42c01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 5c55a11405874e124d98ffff57d1de80e558b530fca5f3b32e5a1dd9ee519ec1076b7a094d98a00689d20c2f9d02f2366331ecf9a38724c9535f5f28756c1ad9fa29b326deaaa3124b20e5c5431346405b624b45ac9b9d307b07d85239fc0babde057cfe3b149ddb91db18809727ace779d5c282677fce653180c032d650e5de3cf70f190723d3effe7ac29def3fdd3c6f24b92bc574eea5fd3bec978d94bb4415e0cc952cd66f09bbd66d625845f9a854b2008709dd1bf5a1df212c35e3b646dd3f4e79559ed2612dfcff7c7ec48e8be3acc1117e1cfc928249231d6c3e1e032e5422eedb5c4473147fffac7a9f536e6242a0fb768c61abfdccbe15e84f1127752ed12d2fdec88546cc3225db71edb9fd49ffda8470b08ba0673deef35f2c6f85ffcccc8333a4a4853979dfebac91f41af523f285b21bb23fa098b1687ff38bb40d92fb29520220b9a9e146cc8ba13cdb4820180caad1855973a0b589158b16b62e01148b4769f66424e66799e5e7bf50915e04fad2b709963a3e514c3273aaaa4616735b07672f44ad93a46d2d68efcbd63663f6dca1656385fa9c80e1d7937eea2a6a957ea5f60816578e90f356deb8aff0977c9a949e27af55231de9d61b6071b73b9f75d33c2e7c3840263b51919a6716c91d3b1f5ded6a6aef9d5ee539ce176020392148bcc920866eb5628a2afb4be07e61d21dcbed1d13d4cdccd25042b3ffe919f06ccc7334b78d86f157d5241af54897e89b7bb3b9fe1e27f6bf48df6e4cf9548f55214722bd6cc8bb13b158e1cfdba4441f469b9d1f0d22c3c57608be47315e2c907004a075a135e84d72e66d2c5a951ce5fe0092d717955b169f204242fb05d7c2c6a5c273f3471cfc2b1179a71a9034071668927d8ddde3e1f7a3741844b277880e9fa9c4338ebb147d2ed8de148736f4385d981190e2dfe70af1f4412478facb105a0280a2106b3a0bab252edc4e09382cefbdf79178f29c4beada55a936da110cca63e9ca18a4a5024b0225b4f4e30b47b494839b4b9905960d18f2b9fea9df5bd807f1f53b5488e487c7ca8339194d2c6733a07cdc8c226160c63ad4bf54c0ba2e9b7db082130dfa0ccc95563b9d25ebf54a2afb0b9fcbb3137e881ecec27ab78dcea4eb25b333c5ddc6b6ead196e948add01be8950cdfdc12caa7d741a9138dbefa1d09a5ca0ebb309fb7ade75eb07526b59061c12419fb309cc55f0f0fc5325dfeb42cd91585dcc189d07b3a1f460f907feb69f073d50086e650230f55498dc4f3a34867d7f91a64ec760289c209598f9a27ea49b841d7cb5be8a4f3373b3150911d3c09e53f54fead8b7d734c66f6175ff87d582f4394cb1984de474f365eb8ac8c9fdf3cc0c406de7b780c7bed74652d36077bae4e899b26603bc24718671422938e50fc5c6d7e5ab55f010ddd9d9e637a8de4d88de35a40deffb060636736a956bec000977729365385b758be15a3e86b7f5b175e00ec39399e5e2e227dc4129adc4f4a04dd0e80b74057d0ee4bf3c716ca87954fb0d16d55cd6d8080a9510c185d0a62f2a9b09a7978513ca0336c66c34ce7c8e3cab8f8c91f85e90796f7f71bafd636dacc005b38b9f8b3b81e21051660fd5fad3781f1d4df1753a658a4c22a9c89c1471bbef06052413034b25a5ff7f42a09e808ea68449a17e7ef8d0e8f99ec528931528f35db90d7b46c2cce8fa40928beac45d09685044a9d84ac56659fe0fb9cd889ffd1596585af2dcbabde87a97745acfeedd94022edfa18fed63e0e3f757ee1f8db7cf25ebe5f238ba9682de4faa5912f1c9c292e12ab59c45f01aaacf8b3ec3a461b13e723b160c69ff98c5352f00eba151d43930339eb52d0487d801a34e5cff52a824a5965061aafb77a58dbaaddcb18f6b403471f5c9819acdd4716b86bf167131ed5aee53311cb77d3fc4f1ace517ff7f2c430f0b912541fe35c3a8bfa15dba69e8ddda522b46b5cc0a74981ab2dc2a63755d6e1a17780d0cb003eb938e5a1b49b2116eb32abef130f86b0ef2166abb38e88106762dbe781a55baab6e2d6d4a406abd997d54529cc2ddecd0d4c283c8e2558b2c79cbcd9c03f08c9e3a0803083bf6cc50b5ad358214723a67da6ea2ec99f5869e01040459df692d1011c3ea53a215fa2d15d11611187bd16d07a9e9a6de9b5f8d30ecf08d503943e374fbe19530ff3b44c42e43b755bfc809a58b4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 47a7741316be8796eaed5e8a9b48e46b43aa54a98f48ef42866b8d79f731d98c754b67fa2b9e70a7eb4b0d73b38d6665d1e43af0c6eab95cb54879707805bd7889e3ee369d231c600b76949bf86366579ab637f4cbaebeabcbd2fc945bf007cf58bff5afa67393cc58805ae5017ae2dfc9dd5b5fbe4109d8b2ffc4fe93712f555b0ae896e85931030d89643af3e4c38581d4c40a46aa8ddb3c26ebde29fa5f7b1fb6cb3fcd2ab6b50327ad0de8e39ad83dce676ab2ecdc2774c86a2c72a50afe4dcab588a66d665ec040f9eae045698bcda1dfb95048c545d08654c1b560384561ab07bd8d7ee82f99c79b2f67ca6eae66434321e8501d474ad84aa71286a948c5ad197f32d07f576f167d63a9ff62d3423ce75578dfd52ef8401a4d4b0e27d6bb7d4fe4eee6a528f9321fb8b817d8c094bde829ac38e362a404beb78df6ea6782372d35cbed99302c5660a3ece31b93b675d59633699ec44c29cfbd231be9435fef1238890018e618cbf9e315beebad90a06ac7feda5680dea12d1a41eba931c279acdb875d9ddb7cd9a6adbfc3f239e843012a8cb917767764d8317bd56fbc42758772c1e53ec034447acf791b837a6a34aa788edd35593a55e57572fa99711bbe5a83454bca7990e834ba285a09bae1666cb2b2f397059d4354687d0524888cf6461e03d313abd4265de38f4ff4546e9b3de7e5b627f30e08c4585478f9996798e9b47d8eff82ba45857551ea4c79b5ad577938666413e74e84585e684783d33f3c8de420f66d48473fc6bb627b399e90697e760783a4ed9d663ecc524568def8507f0437314488af7376bf2a6bacf783b74fe97d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85b0ce8dc81a8611bc4adaaaaa440471b64dd53adb874db67102b6a64ffca8bf8487e19bff768fb71fd78d8508eac24b89284ea83e67585b7beae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774f8d5e001b44c8194661af80d0d59bfeb35ebe9c943f6f6b98e488f89842765debdc4959993345c38bc801b95d56bbb47a3bf3f60ef33d6ade2b8f7d4578948cfc54336f7c9596f75689f02e3c970fcc980af56758aef08017fa4bff34dd13dec58ea6ee8d30921691d71f6839635c6b37d497ca4a87d4bef47cac6085f3848ef63685fa4bae8af13bb36ef445fe6536297d4e4ecfcade6f839f9842fabfc264ab4ff648c59d15708f55ae4a396d5f4bc75e2d603c03cded4f52facc579a0cbd1f64a734e8350f03acebaf734eefb486f6b93c36ac128d3e574d70aba97d2319d78fb43768f98ef6dd3b090ae1ffcbdbeb3b5fe023e00665d8111fd6a74db93de87bd94a634907730f3d800803b233b95d1cc7cce4acd8ab143734347f3459a5bf0f30f958ed50b4b835b9e736d6a7b45ec8082a4d080967b44bd553835bf52943a49dd51f48c27823c5aa1bf0b7b733ddcdd4b2a7819beba4b3fcb1fa9e789c2c57cb0eb50533f14a03dafd04f2187492c51ec14128744bf4a83599a30b96e94473c2bdaff2fb4ba34108689ab8d65baf4ff3559a76f759768c81a8cc5aa2a679303d33b2437b05068bed096475e9f80bf34981bec47878ee5329def7165db8d7be89f8f411a5cf76795d545b69febaea2065b7a6ddda50e6a0871393dd54af62e9b858e3453d9a86bcca625268378563f4ba29ef6c29e4754ccfee7ca3be778fffde46472f4d19ac50494a63449fa7faf6b50287f820b6ede5bab6be04b7e3ffb8b05ccabc2fcc4709a19ca96671b59f611350e4b5f27513d50f0aeac776b0bc26372049b8fe864e328798ec49c5e51f8cb149843216ea5a06f9ea5c8922845b084ddc49e7a929f76232bcfaef1cce07d9c7e8bbcce4f99f3b7bdb1a1f648784c69493c9ea3deb8166c07267d9bd56af241834d288e52b5a96ce58dc9d3ec9af1af711b58e8539b93037623dcb95625eed3c03c457f560b41ca23b2a7a8d66b1b686ba4566577a2a71448648ae3b988cefe82a1efd3cf3a18f4a59636fa33579776b5a5b2c9ade1a5c5e88cd6cf9833c132699917e9befbfa0ee333012b8c1acb7321cca98f086aa4db73988cc49762ca54147f566abb0ed18ecf73deb4ee8a17c45b8006e46317648bef9f47b93b6013a405993b3dc543a4939519f942b982aa75743861387558fd01f3066af48080751346618e25c2501979f70cbd722528c713e9bf1b891043de54424f7022e45cc287b7a8138c842f1bcbad18795a382439c5c470a91309fcb8149039d0435b9b80a0773778111134c104cc5e7bbc455fc0f4d157f2afb40972c41fe85622825b5ac48c0e357cc2d953140015bef5cae1cd2bf7519398b610c9b191fa34767ee67880fd9ab6d5782350b176d3a7c318714f8208f71c80a1b189bf10827b763acf096b49cc5c0b2a21c268a6c69500ce889785825438890a6e7e399ede411d83a53bbf81fc0b0b472692db25b69396337b2724f1425aee7296fb29a399a16a13ce748995806cc5c64ac87783af77bc05329ba849a086304ebab9edfc5435b55503c2a6f9b996d75359e963077f4a88ee2e259a6b97635a3bc8670b9fbb94af2fa3046b51bee299bae327f1519ca170a1aa443ca323c1d336952a3d2342d481b10b4752e34c2f03866ee8c8508a77a4721c387054cd241bd54b8be0bba7be18616d3b649a452123e347f8f52c0c5ba2d9fe7560ad88f2bb77622212dff7474b2c250b0341d9ce6ae52dcbac5d3b99807af81744498031477b6178d4552d3e813483c3c6c4a73dd111e7874b7659b29db53946538cf3b51bd53d63dca591d16043469310c512cabc763b208a19099fba9f82b445c05bddea259a0156940e3099d97928c8079bb7846b566b4770c904b75b430151b3198bcce1830b9b8cd5381a1b255a880e49865297a801291f491201684c658d288ec63b8e6d423c4c9091f9552926253876629266969acd09a8c896ddac6bee964832bc0952b98a95ee54422da547ad9174503093835c74693047d782829f06327d11b6a646ae2e8703c3a6bfe9516e71915e7294a2d5a4ec8406792b55692c5591af95d3e7376f6ccc58caa2ff787a126193175162e6a084159e957d85383a0502bbbe091da6a62a7ec4441453306f74c40c483abe092a36a5876a60e1893c8c4fb3dbc946d781873d49cbad7ba431ee820f6e0246b5548f045ad65b0670c341d3edc40f331b59740ab0d167e02fa36cb23b10467084a63b9f1facabc9c86e6511f8cc6928de03913001927ec47e6b001264c9629343e10f945e4f9065e3985e8b4b3536b1aaac91a02a7b701c961a939388f57b310c4652d7649d604a0a7006686c5c0f467486e5248dc24be13f411fd524a6efb276bd75875d5cf7a18482dea41b4579f168486c3d87545b415ec495f37185b6762b754194f3f415f82628ed9884b658465ffec83f5213ec15264c454cb4cb46106c21bd8031d11fbceb50b7d897aa771748cc2e5a23fe99fa91347fa90c642b5410c2c4382b0a498f479aa94011959328eeb48e8222c5ca82930f5a4d40a7460a827c756c28e99a88440b0ca206241f4472c06ca74d48a5f565b8a85803e214f9a6cc92ab2b80bd16c0c5725a9c7bfc6067109600d8142a8bf681ee32b3d2bcba3ea21aefe0655fbe06c0c0c6b303c6b2efaa6e8e6b29fbb86cfd13c6e143d7b104ec625a6ab2c782bb88d4929ccf7528aee89947ecc33e5187bde373c21f2ad26252163a48bdfeb74841987e797048b506c8fa6c60f431294ab03ae304e1e64a1489a05976355f44b6bdbac7b81d2b003729f9ceab9190165677c81644a5820d8a158da62ce19657e947170472e67d87fc5c526b2db8fca728ef881198ff809b80bbb3c1652fb9a51c42aa89ce96844721a9da7274d52050b106c7505497629962b747e117c2970948fa1e6bbef069cf4da83314083f57455d9b031639202351bbc4631b080f936a1e017810632bcc19b41ac0fc7939d5bc6562b074eed4267b9f6a6d110ae51f2b6d9b39f46061031573c5a10c2f23b6879338889e05efdd4424820cd98298b59dbb720a101e8e62887303d5efb4ea99288199b54a3caa85476876d969b2ffa0b72754e85d3979c17155d784e3ed0a2874cbb9890b4bcf6334c8855f7ac45159a18e4f29ff5d8a5e5f34142c01e3fc53a2d07cc7f6c582718c434c062383bb60d4c54dd07a06d2642c8ca4920d5b7fa723f6f2540eaab1385eaa17b4339b8b3cd08f60e5727045fa947bec4c6e766b850f86b80d2b559507137234cd9856b7310aef4f50034ebbd5336c026530b5ff525c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c4092d5afa2f038f879184f7344800ea49a63543be9600bdc2b184207445882900e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = a5f7dc2067f18ae678977fa4f0138e96fefc96c1c9079b1b5ae3debab2464eb38b217d051cb15d87851322abf0e9256620d58f3d62084faf29daec595cc4eb768299e4c83f283fab2c58dc0a4b77c3672e14103e9721975bfd6138a0aca1ba792fd7f93699cd0c2196fb185ffbc8e5ace4e6192c1e431b78c88c21186f1c74747c4ef88ed223b9ceaa7785b94096e769ff0ebd5133e099a2cced0f21ebf34deb02ff3463a53f43590713cfcce43c8260eb6efaa0ec1eb3c1f1403f6d2be47d0695be1c8897e32787e7df4ca49f1544798ad874ffa44f2f98000106e9386bfbd874a700e5d95001b2bd45f7aa3bb343c80c79b7bb508a93fc6c077af870cde24fdabb1bd4fb34b68c8cefdc4198ab60f5abcd7d80ebb2fdbbe3f99448ed48840e7ba62c87d783f8f20c356b017c31e92be43dcd833fb885d51a94623aa24c732c7c81267a67341bd33ae8ab8940eebf9d5e704709400619e72989d4a67b8b48656143d47c5db50f415c0b726f7b8f5280b7a099f7b2fad0a48e82f0d00926f39f63671a212598a2b1d6cdaa9c693eb64d568739b2c8f2d875a519d7772c1af1438e130e2d232fb8b1ed25aafedb8adaa0ca5cf8a97b1cb6a16b93816b5db9698f8d984168c5926a8a7da376890d1b99e0d7d1692045c57cc1da67109c9e9a31983254c1c816f8129fde3fbe54fd4a2f589d5b7c1d9e53ff5e0204889b1598a4954eaf8e161ce562899b05994a614b66679544170b458f3bbfcefb6cc34c6b153f334329929fe96bc5b1534b786aaddc0d7528341f4ca557b7082c1677b04460e4461eee5b7433e4c426f7af796abe8a15a2ad4570f9a9b81c59f372c99033bfff6c74de930473d49dc126ba2bd5b271b8763d0bd5201b101bf10100f3e70d9bbe865c7d1cde804ba9b9811444b4219ceea6c395866ddbd4f715a471bfe79eeb5446964692bbf41a617937926b0637ef5fb0c1f21676ee2a3ba4e685c6246bfe206dbffad10f1461006eed4e7f3b7d7eb66e63e21ab02a2748b4f6819810fdc086e3df15cb2a77ba2c52699ac58731ac9464022fe124d55491999b3b6953b8e8ca6f0a822c3a16a90dae90d66cc6efd9bade18edbda4a22c49ede2616abdf7daae20e95778c22c1c9733d898d017af3e48b271c4b0b89b72a7faa262c898dfb81b417208489e14957ab999507df5e8de9400903bd2d20e401695295c9923c8965db1df1f6891a2c9468a24e078065ccef077a81c93fd1f5455c8c1b17d9e9b76404cdced260650d3f89d21e861da69cf60504f6434f19136a45c238ed0a69c85d01618bf2987d1f0e7d86ff0d950a249dae581275ad7ff76b3f2fe170bf5cbd3b77a729ca3c12a66ad6e6ce1e58f1f7d83025211898797ee20ba367b31f82ad1257362fb04dff88b128304a9a5e4efdff3187836cc7fbc9962c32fa9115e7250b42a48bd54e99576243e981e77a5461e81bed22fbbdffac5a5d4e054492b663071a6a6b2bdffe2e8af8c2c91a93cd67e39e5709d583b1345fbe04a7be14b444557e78201b9ae095f14e67f43829548a5d587d5fe032261c437d2bef3fdc533564bef450dde56948b94d603f86f49831f66556ac89b76ecb19287a74e74064c8534e021d9f62ccf84a9ed3a309d3931faf673aa04dcd2c06bcef92d07ddf3e840d10fddbce6454b25f684fa80317aec6390da75ea9bd5b33d729908f6efdb150d4d7f74e7a1f63750987183c8a2b47bf5f1256c14d3a49682dce5ce1b6875f3e87a5597d82cea0ec4accf0c152a04c6f337f934b8febb4d00e266dab16d2b352f27e40b055ef5e672d7466ff11c024bfcfe659a2a621ec9afe1a1e1de1473c3a7c6ccdd79db9ab384cadfb0e63efb855e79c1deee4630664462a24e12f3d954da6ac191747b16e18fd1caee0333fb013a680e5971b8678fad6a44e4232669b4787a47254f9a97004de7942a5d640bdcb69b04c6bf28d420b3ba1fdab6f9dd824c47255e6f2217f06080fad4bc1d210e125ac3330f2b748498960a9d12a770619f716a5a9b2041c3141c6e93fccfc7095d5569748666db7795e0c235ca25e68093d2ed8b1ce8c88d5898aa69711467b43f8990289156825d533633cfe67ac8bfab5b5e1604f1ecbbf303fa48f638adda11a5998e26023f639efd3ec34775ca4468b71e703ac664189821eac927d64d9333b58ad6dfaaebc8f8126d447dc2e5e6a74c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 35e4451348cfbaad6f1846f96178b6b04ea1c0196f275f5832cd81ea779e6b8c4b3f25dafe2963aa756968358bfcd47d774e5ed4294f02a843f89b87d78d3bae5d4a9165b9beebdc956d58965b64bbf953e729e60b53552d2ddd251cc9c21e837e0a7c4c043ba0777e53b39f658b41b5f8900d57f1268a8ab868b15b1fc3b804e416dcbe117ab3a027b8fc2cbf3566569a23dd6ebe32ddccc5eed69a392bae8e4a7bd6c9708a48badebaa7a0aeac1f7f9eee0399803a374d3733af6def1a846cd205e76dd3eb4d53750bcccf938beca43c3a6cd5601eeac251f9aab9bf489f2fceff436f124fccd1cbe7dfc75db71f5a1a433325a559a0df3b49bbc3d1c9e95b984303735f9f2646f0dd50097ab23a8aa5569ab744a934c2a9eba046cb012467d39c3936eba9cfec4269eea0eea559990e33b52fef9d5a603e19fc19a8e8c057b7c94ea7de0daf2c0ab3637878a9ea90bf377874fa38bf39dfeb6e31345340858aea53d4bdda3deb99fb628d975a921def908afe9ad37c9b99b8b09e5070339fdf86e25d9556b27e6cb74a9f1819fafd8878815f6fd82cb002ca49e879c50e33af2e747104674eb103d959e3c22f3aaebfe3dfd77fb6ab855928d4d8523d48864dc8cbdb832bef5249f46b7178af9769a4b359664ba48da4a746c215c58bcf752e43835b6cfa9ffda3fdae59d39d38ce6dcd60f5bf5095f1d3d59c4f0836532647776deb4fd6f337fc37562973a1f9bd963fb4bebf5c21597a12ee7097be55cd43c76874c44f25c1aa1bbcea897367536ed05ef4feb6cdf246dcd6ad82ac03b5ea4f32dfb44e201f4fdf65a4bd03b16ee7f9894d65d87e35f1f730a7b9efc2eb43272cdb2bfb8e616cd7df64d41917a95b0544e95e3e8d6d60d15cdfb90fc0f278d05144e960654f3594c9973cd8664b7bd31bff0328f7307b95fd5f5a273fc2466d41b1286d6f175bc0c4e942e8b8be69bb365ae1ab4cc19a0fdbec5e6ced1acc1f5bfb91b860331677290c643bb9a00b4b65644592c5ca5bb1abf5d2b7d80cd3fb09aedc137946a3fab6c8f3ea1e97a4735a5c0a239b073c6e066d53cd64981174978717e8d45f35019b3ee615ddcaac31a37e67fe35ce57586c365ce3bcc7587dad66c7ed5674efba0196f81d94843e0edcb3a93c060f5c0c79ea0d4eb229a55b7c5d67250f6c4f1b48313788a31fb0ca5e783ec9447e64314e878734ab594029f3aead586225c7a6ddda5f97bb7673fdec47c15c06c7c30d90c89d404c3d44136c79f56e81cc2ef3a7d3cf969b72f6cabe063a35774a60873f67b1ba34b93a5d3ebf5fece84a034f9a9d24fed897320bfcc11449ebcc097a079bd4bd9356113b3cb993c19384886efe82e37ba659d5b8bfef44465eee318cbd092b8f8e53c63bfa3897afcdbdc66e28ff5c83fa85c36da34fd6cfe697f173fe361bbef5e6c5c6ca0fcdec68708c14c175f9e0d01dfad647a317f78f52f76baf0d6a3ab5e780d37a00baf0c6a5322827e9c5ac88641a9d15549088b5a4deaf3f443335abfc5c2f7c5be3ae42740cbfd71fa83bff71af0aacb43833b66f95b51a885d798825c3a2c04b399d5f8530daf4117b6e762c7b6527b0509b5963b685610e5db4d489b5a93508ef8653a6d4cd0c35e71de128adfa72ba3fb9d379843f41bf849d2d1ebf6dd5e33c0c76e96e909b375a930caa5eeed5e8d96dd8698864678adf585c4fad72ae56990c25adac59ad0fb3db18dfa0ba16a445ae6ead3c9f679c333cc97d841ed6a91a54d7ed74c463bca12657bd9e544d8a6e181c5b463ff9ca94bafeedf375d5a96eefb9313dcfc93645c738fb083cf9d4b466fea3c28d3be6ecc6cc5e584d35e45c5ed7f33d7f3c7c2f75abe4e748a79f88797d9d03b8ae9b839ea935f6ee3ff9e775af239c7c448eae6c7b407c42916cec4cf3a1cb75fb44b5acb746a5b2b576feae5fd1cb81396cc1a17752c2b5748e988649bc8caa98c2c3fd9cb02be153a59ced58a76748d72a1b6a5a68b1826ad62b2f3cf849e3d77b5ba236d76c939dcbaab624d7e2b529f1b56d98c48778ef46917c63a23a563a3addc7d3ba5ef7b87857c8912a137f530f6cb56f8dbdcdac5316fb1b28e821f65e507ffbabe9882a69487407b0a715a68d2edc1b2d339eb559d483e8dd255f4ff758db79be3c3830f0332f31f89ec458368a31cd2466203c2b510cd773d66c92cf2c95d7700d82b54faafc8931300f48563aa4cc976ad602d31c4b4b6c96c6f527a637231f1b94cc38767a608f44922a3f391b9e6c5f78a87bbf6cc19849ae619a2d84533441727e79e241efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ab71ce07276a78546859e21ba695953c8521a07bc8b4264bf1d3403eb8cbced71753b6619a4309599c4ecd32826e6609d7d09f976c02dd4143db7ccf9ff09365910757268f49141445b689a6dc0706c92fdd8382c63010f7a026abf217ce572256360a9a4ab2b7acb235f6929b8661dfd5bc4041813e657c95ca1a36535e97d6a56c7022dca5cbf8d121f24ab6df3002fd4b619b03ce2c4b57ab65732721901448b9c0136b1c72145b2b101fe1bb555ab2c0482caf3a1cedc926a007858e7a4ed9dc120eaa7e945275c4a847146c88a468ae23ec173ca76494732792d9a952178d83790b725ca63fe13ff7c5cf5096b3828b463aaa0ee913c390359c9e4346cdc063b8517dc5830a24e578f2053f33e5999fac5603ab62ea785080bc39e0aa206c98c560597d219746737015a5668ba4f0b06f45a7385c753a854c4d818f78466b5b9421fb84b0bad8b5b0cc3104ba8b9531b9033c52fe7c718ae81a3b06ced360a879d9cb3f73b8d6c09781462e6d7c13377006d95406329777e2651ef2803c69e984d4e719764ccc1307a64a1633e7516b2c5380c443a9bea049c91cbaa7bc385b989d1453676ecac1c2123f05e83ac0295c6e36ae6f0364ce5b35348037b7379bd2248af8fba3acc293479b24cd0a2b0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2940761e48e665461bf30c2e9702ac726ad1aa7cda90c5655b9904ac1699921ac4a3a1981b566c6015016ac84e7964f64c0b5eaf69fd5460b9a17686952951ef9a04a55926bd482e669bc6b731aad4465f9901337a0544f27ace61841a5c2b0efdb2e4b897bcbf1c032142b73f70cc0f7b509d6847f61ba4e209269acced24a0721ca6d9e634167622928b65447a5aab30765efb7c977a56020b56abfb82449614df3fbc118369e8aab020cf989015696140b6a5c960db2fcb5be3c41091a6729c62547db67307ace42760689c32c2388310d1269915470286433c5624fefe684a12957d90c8b61fb334bc56cfeccb229f01f0312a11449310e432e75037ba429adb4507fb74a293823364f81b756673adbdc063d030fbec029569c8db185a0ee8011000cc7b2118a046483fd975d9a0122fb0596aa8a6d9b99ce7303b1c8a4342696001167a742fb9374d4a20a8377e8a6495e21ca6eb106b2c680a48ca6c138673ed09897f4c731412ec536759a773a1e3aab3b335301eb2501a5cb48c33a1e026e4bb25e2f867271e48cd48a029039519b296cea8b04953bcf41b515429237e696503e9283ca4165355585be315f20266438523d41543194aa6aa476bb2c229f2f12648a179e46c1696581607b4585c5341359aab5c5f0b2ca96177010c892f8299042a880b9c281483ebf0a96ecd9cac2f13bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b09178f2883e8c6397c74352aa32a49468adf650441a73a2a0e7489fd7a42a9421c8366ec7b5a0ba8b0fe721190f825bf5ca839fcb22f425738e92b68608078316af96526965331d16a41052f2154faa17fa843a5e2278cd122aee688924e57029a8902a03186bc562f99b2e72b9cf8e578bf28c2f5a86b47b4555d50a1512ebc131280964165f139b7a8860120ca684cec34cec402552eb3b9063b7d8266735cb1be8a0b253c67710d80d5d1b128e38085d40cdc7e2cbf4b8c9e1861d2f41a79e1b49aca0668e4b9312003986045415b194f0f583811b181fc15f8cb5788bf14762095bab613f51f4351bf00f669102bd349b70c40549b75ecbe16394a3062c5316bcc4a1ff57cdc976950618c7d103248f4c4cc2087bca854fdf6840ae98238c26656615143f0538c960888f32bcabe935732b6a5c24372b438449812e4f125b07b836b1e076f7e629fd3578132c70776635c5fc0d4b435ce2e301703c20ec130a25657eb394013924bb88090b1599373c5b7624d59d2f2c3b2d71a308a25092d5b0eb6ba81c5b0c650104b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60aad7166f31b2650d125c8ef23b5825fe11afe25d0cda306fa6c7a824b4c2d31d4f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = a368cc5426a57b2426b82207a847039cd8d56199b28a9b5184b5868528d3774eceb24ef6d69a936fa15534ac8eeb16c279c3190c59dcdb808b62edcdf9301b36ef634e14a8433800b1be9d04c6cd781c9000aaa74f8b063561146b8c11b75af02fe5f4eeb852d5f53842ddf4f18ac33e317b5d3a7d4524f5037246df16d15c0c211f37a8bd1e6b35b6eb5153e740d85cdb248b78852253f2c156d405648668c700f7bd3ab1c7670fe8fcbc6eee04745abdd4320fa883d6535b7366336410823ead993a2a994e48553935a17ca6889be18bc2905194e365cec1cd1d75f309aa05f3ec3445c53ffac6361f8873cc1ab1d5ad2c44b72be01a86b828d5f9acd26eac49160fe941f263a82286574508debb2ff9cf8cc10e85dd4ce479c96a79f3915e085726334e4dc636a705175ee770fc9b463e34a2ccb04ac598608370c38936e36b6635e98fbc5fe9972a212d8ffdb93bf5c26092ca7ce699c4beef08b2c0d9fcad9985dbe35a95839420ff1fac408c914dfac719b6e329fe872d5b657907d056fe5eee7fc9f302e3d6bd23bf965dd7c5fc5943134e55459ff271166c3a15685c49961b0a7b7d5ae61b5fe6bba79a59de07c6e04c9541cfdf84c01685226c3c1b3f8de17747b9d44498593f2aca4d38597b766133d20b95ea15ed087bfef1612793c75f32169a3f366aa34a671ec2701a5b3eafeb687d60f3a4a022253444bf9e8fe98283c54e3e080925b26df9665c6e35618d29379745890f7fcb4ff6e66c45f1c1412888564b036ff10ba9650b4bc98f23a60eb1e17cc57841ccd44bb8db168fd2b0e52a384df522556d5d3cdb3d3f23d6c876fd8e627aa3644bca0ce0a49f982b69109f42163ae61293356bc5154c1dc5092bb50843583f72f8e9c8c5cca5d2343f5c3fe4f58debf45579a302c070b141033510a9605786e376704dbc6c6a748c844c41f2338cfc3d84aa1f7ed352dc47eb0a512357220714ffaa503647840a1105dd68c964efd899678319bb3375c8eb9047ff3d2eb98b1ad8ef50e55fe41fed5f2ef1b534e7dda5ff5e988f86e83a70ea5a8a99f822e2fe53500a87ac4705ed512f560498b17459e0e0e6114fb3e370ad38f0fde6a6e247a8ea81c6797b428f022113a0bbe97296165e151e40524268bd6729f969c2e988ee92cdd98ff945f9159e61603c10a39b107c1684069faf0516ccdebc4628510afd381b99f686610741a3931253ac2fdbd1f043e0b46919f420cdb188ed3c3bb11515532f2d029d8920545f8cfdf93a9a186b90afb9ee501d7af8eee89e7814efda71c02bceda251342f52bb115d3d4d4b6aa4a9a1957eb2c9229574644144a247107763294555c3a259f8ef07c73381b547b47d871f5d73ea0e2311fb29136a8f20d13a1d4968d0ee96d91d3b25d45a10f18acfcd5b30c45c779c1208e7a04b5d6cd6001a5fc900273e9553858ad746dd3256feadce32a5468f6de7126ff6df864c530107c6654d10b07c8338eab64d5c0e9747139820ff591e964e332ea357574509da4d7709ce2f163e999aad5c99687ee61881d6d8a7634aa5eb5d0130986517517ff45e764fc8ca00fb5b5f76fa2f89c011a5c5fb8e27f5e97bae00472338b1ee7e053f2529b3ae4d360ec408748cb81849958cea3926e934ca60c6c322bc7758c3f3de8dc6324a5157064ed137ed373c4bd2caa10c19c4d5db5741001ea2f20a7373524c0e31b126579db7a5e441444506a776768532433f7f6ae4ea1f708148a372b4ec0fb52e453c675c028201e4d3cd5cf0f815a9372d82528eeaa106ae2ccd0d9471215be33e5a45cbf58993b81e6360310b6476640940b1cdc8e79c65aaa5aeb906c3dac8e0a14f54a656aa138ce3bc2e3567ad6ce64f07e1dafa43bd022eef3e4972340e298835fb81618c3dadf88eb994373ee3e84107f8eb448dc31a4d33249cf3f02b2f42d810d89fd67355ca260cc1bc1c8c0d8103b94b9c67b705aab41facdca2819b8f591ef79dedb0905a44c2435ee41e488e538149ef3fa9cc44881620cdfecaf1583f186c5c229df8e62de3d414b30dd700a6fff2d4a013ce8b0ca52d7c0da2f24d21f65038a7cd11a90513c4812b1154891f898f8ab3a4d666d00fe98d8cf351b12580e36055f5f31d2a048b41fd0445cabf9f6f367361fc4a1706b7aea67dad68688af01cd1fedc893ffbfc6efd3b3acf38545538e0a4c0a155c30 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 03a941a829c02536ef4427fad08d6bea6bf16b58bab845328c36cb925a5169d6b1ff24eba55de0ff3cea457ee3c443c6d98ca879e673cccb84d65e90686e9edf59c23798b9b6bbcdc0d49df5f4b21563ae55ef87dcccbe4c53c62918a6a213c460eb8c92377cb58aeb6d6467d50f97fc9dc6907b6be6bd3db314c3ad6bff46999743ec7ff1bd55af3bf753695395d6e57d7de15e183dda398d1378d6b80e7bb4fb4f36b7653cde7cacdebffeecbaf2eab65b853c7118f0819bd5afb8638803f8fea6c3563ad27d7edafdacdbbb23a571489121cfbaa0d7ae00df96b2dc8b40e4d16feae60635e2a64462ff8d6d5959c49d0cdd9b2955e658db7b0dd21eebfd44c6a43d08b5f469656cb9396c9c640cbd77cc24ac0f293bab4cbadd998ecdba315354d8b754f0cb53f826cb5dc92f4c48159626053096063841153f723761f843e5629c945778a2508f6a28b9da5854ba7f8dc48e44929eeca17e28304babcd0a04ea8a6fa04539ff09ab5b7197a685a67d07ec9769b69e64fae457fb8e1b7db23ac4a79723fb031f44954e43e936c6e5d840494b674fdc9aee84a091175f8f4ef1151be376fdf8d0ab6b709a443f14c56ab67e3a97f1a4b698eac96160befc0f5f77e4b4e2508446ed4999687ac5ad6f6ccf5468f3e944b9dd99fdd3e9337c85e60f4a0798556cfabfd47a40146691d33cdf179b5bb3d3d88f2cb29e2b961b73d611de528fab952dc75d23339c26a38f695fec13cf360f369abdfef8cd64551daf9456fdfaec7c359c09e92f5642f1bab42814aea9ff844bfe56715fee0f1e3063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a7ed70fb665756f98156c65a704d7e1014bd664da92e9ad9ef6c944db876250b951d1633235ec5bb6b79f899f8adf6bef819a241068b08337136b8bdc33476fdebd292b68ede75490ebe93e267bbf2f8459fabb17e1dbef80e8ae89599530d453065ad45457e3e86a12c554db46e7a9a6e3767598031c86bd68e5585444dfb4ecbe078d350cda1cc2636d12df3097d776d2645db74db40aaf92acc909abae1d1dd5a1b1469ea2673020bb7ebc738129dc272efcf73d37f620efd8389843b0540117c7ab924c141de40a08deab1cd596103a1aef3c93a2a79be19c7870abe8333fa7eef65a2bef80e3d490f05dd415ad06d8a403d5d948da4b1055be8be35a8f935f079c5acb31d4bd42ccb526e783aed7380fb3a62b3a5090f95bcca410215ab5d3da89c7f73631853640f7bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bc7e8dd7facf602fd303faf5a0bfbc32b5f69ab45e6bd8ab9f9456a68b869a5ce3a0b6c98edebf276572efc9a3169eacb33b99469e9fd20495db284bd4ba7c677fd754e58397cda1920fd404b545ab2f79cbf6fd08eb4c82f6d569598147f9910e07dbbf89fd3764f0bb999e4a9cc28ecde93b1f4d0cc78807a54d13933b25b350a16c842e4b31337bc7745ed4fe564c21ff7ed6ab800717baac4a9c954c6ec5238bcd03dac6fc497a6a9b9e4973d7d44ea53b90db26912ac7796d3f7d24d3705db5bd0266b17b145fd8ca77624c8eccbcec219d73b2a6399cc7704d25452a3addd71df020f5eb0af8d0f9e9325069ebc01b72759f7da637823cc69d3ab59f7b0e94b5b653ef1ad01cbb5d28284576cbd670bade6f94c06f8bfb0d79d4d16e5fd193ecd79ddba69d816e16d22b15d2d165340c38bf824a35d7dff7db3680a4ce964c57f7aed4d385ddc41383ee860ff34bc9cd50af4e94dd439ee97c9b0852aff733c2974fd6f4f41b1a46a87ad9b48a59adde3cac06e8adf9b0bf835c20e9b05b8b58a62e8587bbed519ddcbfd3e5c28e4a8203c4421587915e5d83ba576c25ce9fbd539b26accf57ed299b3cee76d1c08eea1bd9e3c0f88f478ab072cac1541c892f3e4d733350c0566386ad4bd8d759b6c8eba047d06add31e46ff66fbc8e9625c374cdc4c3b6d0f37c5576e678eeed7fe186d9c774bc29ffc7d7889dbda78b0b14eacacce997e93e178f393fc655db0ff8bf8d8d9b395ddb659dae366c87b7b07f17fb7fe9e69474ce50dd578a5fb4e926abb8ed39d04cbc9447ec0c967394a95aada9594a8cb4d6de945ada7bb18a5e52ccc5ea5672a99ba278867903f11dce73ce433c475e3b7e0b3c65921b3c842b142e139fe1d15efe13b7bc3625177282f4a92ff5363027901e2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703ca521be85af4651c52ab82006c95fde5779c10ca73866911a4c48088742b8b2243f629fbea924b7d8968bfa6200361a9c344a45466de00b7bf0e5b78dabb1bac3278144a94b27193b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49944d161a9290b4ff328e4fcb2427292a01367c713806b37cf92649009c09416a915b84c23efdc41d7e7859dc81276042357663c0bb68282cb71d891177148a17c315b7cdaa9aff35b4a4369e83453097b88d61395da62431f19a7c8427a2cb15eefd30b810bb74342a306b1bf26a0490af566f5a17885baa8f4a60e1c9432cd02a15915cbc8d574cfb23399ca1d93b95bb1e7a68a798a9b9a6d4dc92bf1bb84ba1109db395dc4b59f1931087e4524a090ccd037be1be6237a6483ae1a21b859bedc7a5a57a46fc02b13f5a446f4997b310b14c734160c7a19a36507876cb4c0cb2bef3bbc5d26281f15ca5d7654de307b20f9b3ebe90dfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358db0784a9c7dc25cb6f6236ad96784759277f660c49130a8ed9377f85394ca90e1d59467ef98eb555956755aa51127a26f498f3a6a2d2f972357b0b40c1254f143042199bb380ad86a04c1a8a1c4fc68166606152c5950ca8b0b3b86d99167727f623927963770a1423a5cbc9629f248409183cb5a0d99e22c915991c7ec3e5288400add0c355a3f94e7a4962a513b05af268e31c7d1c4b3fe0f0b8be500812bcb66ffa0fcfe66928dc86d769ca1f4095ea3124c5e1c7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c1703a0b7b86a691935824299062c5bf927fd5573e413552a7731453171c945748e9943429da1c00588742c8c2acbace1ec1a290e3830006610d21b945647180075194db0170426087112764bc23718bac96281ced834396cc8d4d003d3246641577bd11a59a765001215760d8122eef819f2d1416f998c7a8a080718a11774072f3a563a0581b92e5aa24ec05ec9004d578438313913b176e783c01e4d313648123b9db69d9e7c648d2cbfd42587ef1a2dae065fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9cf818b938843f78ac68ef8349f37468e81c06044ad9a051585c34d33d76cb8ecab0c0886cfea5c725b3013c048db0b7efe3792c6777a0b8413481aa0ce5b58228479f90c941517631319415dd52eadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f5903163a9f45d681f0c637a5f53f7ec0cd30c270e3b78ee4d575a3040b71c30106c6831dab1f2c8515fa8a6c5477c311e7023d779365466228aa3d1fc2b819b51e0771c989720946aa19e6b28a463577214c58bd35237c33573a75a11cc1b5dd8595420cb87f9063bb7247d88789f40198a0395c001877cc35a5a5171e3360781bc3588930827339c24233747d9b5d96f6a31712cfd71cb962b7a1974c3ed85c05a525a21aac83af06c68136cc9bb8b7d74216da468d78f80153bb0cd2b2316dc975ed6c09b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df8117d8312093bb3363d02c72f727f3371c2c8491dd611ab24765fa2665f612517d1d66882056903a67fd4173575166255609a54a3245d74b46c075c04b702ac4bc88e71b757907091c228b0182e10305b7c1cab0df3447a93219df5390a0302f99a0ae8bc51108c7c3397590f4b241165414952840303606e6c1b98755264b01280a8caeeec25c0818840d494bc436279a939d96c6f9160a01233afbd576f46359b2c75097bf15c37047f31a186b7bacbf23aabe9b7ab649938b08687a4b1734a834d3fa62a8a7a180cca4fd0a74c32a76db42009daca9ad0c3a6f8a06699630f56a6c793927d155b229269b1e3c94e0d23be1ee3121e4b638216c5b722ba3aa3129dd49bf1f93e78d16d1e820485527564405df9fc6574b7809a8bc289a02ea0e455a3a7813c195921194756558a6d481ff86a0de4dc39a347ca01562454f589f953837a256cb2ba49f200a7d1b22ef801109e2a45e28c57e201354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44737933cfd8c0e61085f2ae264d85c4ae05f8bd40bf29976c6d52e4f1c7ff709cccd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 2bb76b2b172b91454827ee5680a5d60d98d45f08c3d4b549edb5deb2a20970567ca6ec9b2c634d436eb162a1d19d64f397dcbc8aac9867cd71586f70a336add2d101201a6872f943a49f13e6994c61bf51830e361605495e42c54968e7eb2d5e99df9f3e997c72644e10086ae5f1b424c6db7aaafa7f84d741ab9a23959e111f749696cffcaa7091c00ef5f8b66fdfad2b47a029249816c59155c3695ddfac0837fbb794cbaaf4961e00973173baa56522f65f6cbe7c7a17172f6af28a5169002a1fba98e763b74df20e7d0d0fb73c01ef35bd12ff9bd9bf6c3074cc571fdedc187cbd9a9b7b02b57e81f4dc62e0cda4fe8e942121eac58a64f561f8a4532bebe68879f551e5dfe9f60e7beb44531432d0593f41545740a860fbcc36ebaa22a490575c8d8356c1678853172d8ca769cf6791431a1ce3f1c46673a7a4d3fb534ad97d11e79a0023bc90c74dc392bf240a675acc777ce4452749d6faf47618a3394529868e2093de715b67d0bd441df6a47315e6323a091967c647cddd53ee4f96b17bcb20de94145176838934926746e267db99703cc5c259becd0c31eb8bfc6e303564712ea222f51045b1ef629eaedd8a9795fac4b33e554f6f0a223992eb7b77d095fb5df37a5ae525201f67583fc94537fd22238ca6383fdef8ee29766a5435b6cbe75676dbedafda4b2515b569e5f3dd3480665f66b834d6ba52d3102665dd9eee38a6c50c81ee0d779f6b5868e5430686cd0ab6d0a292293aa780e196a1a31bbb3a8091ec414f4714533f117eb0a58d021b136a01b5eb83d7e9c8837d4a395d2ad10c0c06788b358bc8adf8c3d7363e7b59f757e6251fe08d87a7331be195836a16a742725f68fdd7f841d92cf03961b58957b3f533627d8cecea3cf66650a6d903e6fe35e26f5de9ccfc163ed973756c2e54e2fcb06b53a45d2a6db06aff3babffc02ef9cd1a509219262889dd8e0e8dd69f27e92a8131b02822fc6798e0317ef68e2a081c9a7cddf207d23e27b1c629868801ccfd3931370a87334d404b5ce1cafba023555fabcd66867f211ad534c00dba25014af836022d153920b6dffeb1259ad53f94b9ca9e21e31c21903b5b957d74aaa84ac4a55d172759331b5a2bfcf25a0bb4a43cd45fd7e734c8c0a965356f70b106c33a4a53229ac8df8322f4e7066aa00be77e9c0a88fe3917b2e09c092e30140fcfd6f215fbbb57e1951ded774d91774fff041c247d56f7444777d3031b7c2a849026bf132dc40d7fb4a2895872a296a3b5018e28ececa5645719866cca58a7a960d6aca25fa3baa95d411c3123b5be1bf279ad8503d7b508d1768baff17a412a43db832b589a9045b3dd859104eb9a83e03f70acae016347fc85638fb35c66409be9a02350d2078fba28f7db1c233d3ed0fceb923e6f587e72f22239a0ab1c7a17774cf18660cbce046551227a4937ca1ab825c26a9ee4075c4178c6beec79b779c2466ac7702bea20be1b167ee52e24ba642c3b16855d02e40345cca41fb38f4e06cb11da2aa4564f12c5c6acca2a41a83e0d37f9c12ea52eb82f5ee91bae268a1ee60b5dbc239ec33905e0d52170e90f2fc0121aeaa59c971a4f91fdbe92d248074ab271aa790e63f97d8b9289df1a7b5aaf8c9b942ef43d2ee3e5a6cb938a0353c326f439dabc4902a095fe2caa4b105ebd8b0c208f0342f17dfe818136f0f627dfabad97f23ab33df3a37cbbb664a0458665c795cbd0da8854c3e66532e1af1d20bb4a21bb0d25e8bea9db9572df1ace3b6bbfec6c9c20d688dda913a0bb1eb7435915964696f760127039f83de95f4569105785109bacf9936c6eefa6979fe67e026e353d0221e36d1676dffafafd3d9cb51af0ed05ff3d1cde08388199cf2defb58698c6f2555b6f587dd4efb83b10a0737b82ce8027cc8b83dc5405e5a75a65266d7e8b2e6b35a49af0eb41e0b435617d2b4ac75a0ca56ef26f6bf771ab0d971fe5caa9be849af1d0326272bfd238a41bfcdc14eaf67832fbb293b19a4b1752ca1e27bd9e79e0607d5217f980a865fd436b0ce35c3225e3a04e578d04c9dfd82d5f203b4d113ee19b0d097c41747908fbc4dd16304b56139e5705f2574e00af4ac6bed23be79919f068f6f1c68e9f1ac4d2ec6fa6d89036b46f9511088239a3c125d7a96a7c8f06339e73e9d358169a56c2099936f4fdc7c963afca70586c1151c547bbd299 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c94f401604c8c4c78d8417c805cf723b14733044aa2755897f65987a6ef1846ea07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bd3d6f851c9e93bcf66e3c9e9c939be52fb07f6efd295d3a6efa9d3ea8861e39b1ad58eb8bde805a9cdd48179aa22d3c2ed7bb59d5c8ef75e281c77f83ac7b49eb997965b161ebd25b47ce6e3cd9ede4ef5ebbec8b7b4d20783d60d9ddbfe6ac387b629cfed351868186f6a0bf68905f9cecf353d3fb577c263ef919533c7044697da4f5bfb76bd9d367f44bfd3613351d95395f5cfbae63b2a56d8c69364f41e85d543ad8f35b940fbc3b48f63360c5daa98f59c7cb4634e5a3440dc5957a3644f6ae381389b64fe01113f9fd6e519113c17e64782239941cfbb11a647b814372e323f05844592cc3c17319b4200feb0bda3f5acac3f18bad085c8f27b7758b85e9316653baacf53dc94ccad37f99eddb9fe67e2a13662c77921e4a9a86d8d8978f811e53a60c1d89a1038483f6e5e6fbe09a3b7637fdfa45cfc3a81b96d84336cf594d2427fbe1bbb9c7b3685ea45e45c8ed731b9b75ccadbfdb768119b20a0c346156cbcd5bb108bdda0e3c6e949b9db0b4ae220f6c9169d8c5f38413c648eecfd623f35b383bdcd5f4a8d716fbebbbcc9f8d9bdbb5c8414fbce2f8ebb0d795c6786af95a7e7b16f9f7978a03558f997d9a873e9570273beb7e986ab9f56036dd022569d4c98a85bb98aa198deff63dc6bccd1f6d32ebab8caee5cf4717b17d99e25c67a8a57fc371153a4fd9d45fd3304a74b98393606004fd80454a005342c23e8a284bc5b9b7ea39e748a94739536b517dbce61addddb64c81001acbc2793f9f29b42214442fba962f43ed48d3d0db2e86d21a4de61c4b5948c7eedeb9fa5865cb0ff90b8eb9f727e137d6a678d9f746beaeb9db686ba84d65f6beabe332ff036bd123e620ad68e84d32ca5736d3ea3a02feacfe067dfe5a5b398575bbabe48ef6e55cefb4b67b34852dce758c58562dffd07aefe8d347ef2bd73f064f1f89f6be6bf3440f9e5b7468e93b8abec6be231b6bef7e4032ed4ed23c6da47d32edddd3757d6eff7453dda3ed810f9383fe7e82a85ad7a8b25ea97d1d2aa21238b25527d08b14d0291e68329bd2869889f8fe42ccfeae8ddba5ef37e3de649aa9ac56229494dc3eeb90b96ae4bf829af5f8c644e10a3bcd356af43f3654296bdb79b9b7d53f72321959b373f313aac107c8b7aeb83172778b7b199e7373d7fdf5ac6aeb40cfe750b82f7f47bddb910d880e4d5877b63ff6d6e6bf4a51cb1ec863a79b0e099308c4fcbb7997431dd8268a3b762b9a5e28eda14a4a92a5b55e7950268a9a845df889a98835cb9562a5a62785da5348b3398b39794dd9a18ea058bbabcc7740b00db8cdbb4e094fc7f14b47ff4cb424c6f52ccccee30398023a9b50b4bb4a3ceff1bdd7a0a54eb05fefc31e3f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c44f0bca7c865baf2461b3d966ffe989fb37b78c5555a62a3439f3ba7646086e11346d79bb8352a286e552d94bb58b07cb832e3bf88031d34ed493446abe723e57e57e3589427301a6e40f47658258a761edcbdc046c08bb897f349b2941fe4c105792efeb45bce8e1e05c137afe93504da51fbace0acc5c7bacbcf34c35db3da9077eb63f5d526dd8b9473f70acee9ff3992547fe49e5b7caeb6a0114d46ed846b41bbbd9c6b7ee8f3ab4e77fb9353a929764c239832d9f660463fd72c964aca8e96d94df275159b9cb7eb19b75882df6ea3374fb84e81d558812c7dffdd094b9f4d692697cd4c0bee2067d257cdbcbbdbbc82064770df7c0d0cc624e839c42f54c0d76c558999fc2779ac69fdfe07a347e9316a3bad42b78a058d71cc9b67e46ab224ae38e757f27f777ba94edc84de70c2cacd25fa391c08a6d45d96c704cb3e275d5303fd592884b096a7ebdbd4ed98e2f5469306eb6166073dcca7a5bc26357a77d2b51688aace3353cbe883d47acdce85d27ff7ed7d4a60e57186f3e3562ecdf8bbe382a7b7108dbc782cb75f28c494853175599290657552ca4b406b54a9f6d7240e56e14667cf3fa68c3938ab9b309a36ae9c5f499a9ef77aceaca77fd8243ae88617469a4df12f23ce0eb8ea6d63a50abd686c5a63f44a0e9b691f0a718f02246fc688a248e3c2f387a55c463f0d976af9a2399cd4845c22516e0b3c882625aa609b64195c90925afdeb2901075565db2562b11d2c07c8d0d94122462c25a794da3639879a409256018f7418af91608b63ab222069e31c2ac0233e8f73ba8be2b0ac0463c9bc79cb048ae517295e8a01d2e16437088d20168f135c4d63b41021060a557003bcc935c6c97b3859176807b5637659f1b5bc4b488d4e5657e9f7b37c320b5df12bf31330ad27a7f205907d6614949bc97f3c1e94f21dd235606602a5c13254f43ac1bca2a6269bc5e6a96c31e30c972067a6030665ca7b05a700c53c560860a11371505457196cb33152b10f9b99518d4ca6433724a93219db1bc834499a019c02665c650c7c0d22724bdc0bb852c9523d1a9e5b06570a6610bd1175a74b869cca729e8c17ed5101d43c814fb18838f840884a4159bac515f7b5a637b703385e5f7115cd187e2964be55828a33656ef0384896525d4511aa2fc40046729f54acc768353b8001201bf508b5904e3603abe5b426dfb77f213c54b443b7d5ca6998291b56c379ad5216056198bf5617e58977a0490c308bb5a6873ab980a1364b1d25f0b01c3acf3221528c942fdc83a9a9a60d819c015fe06d2c684194c56a98c286b2122ea3fb9b18d003cf91453fd09940f7722999af0645b67179bb11b35a4cc56c2fc1c581f168f1918983ea00693471f6e33144c642dc5a4c28b01ef514449213a4e4749f0b2c40e6e06052d6870dac120cfc54aba5143d8ba4fdfb946af9c90f99ca2eb158f001003517b9aa7a1306973deb713671a16ba714245ba96723e3453718a3bca2ae2c1b4d0265102ed901b3a1b6b6ec639a8900eaf67b5e500876137122a5284cf52de9881352770a9d20af5aa59c71189694590c549831021aa911948e550765f8897671621e5d3771f1263f87220c0f0b28804726c112a7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d4d0021633c9744440f0f9a309d1467cca4d67a917198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62006d29fdcb62526714cad2ca04fbc28983b54b6b037436917da15608759abbc316e8359a26c55e7df179a74c39269c02caea7e61ca571dc771e7679e611b9eda31bef53b11e3524ea3f600fdab967fc8a23b0b73407738955b20b76c75b971c4c1105b9c5a3557d57af4db036454a22093a570f0bb10038bb3a46a0c92866c707c28a91b9e6172314408dcd3b051f363775842274988340165887a027bfb629847b9271a5f66c15c286537c76c31f62b45e2995f0aa30dfcaa6bf2883d1deca9b7b2029515c564d3b970143c29956ceff588e99b8025a2343efa5233361bb2332afea2499656203cb712ac8cae4ce1489df2bd9223c3c65737c101c0dc5c2bfd83444a29c64d8812cd69a68f004d2596033e903d744abcb688ae65b0371d711b187b62e6c755f2f947d828446fb45f30c42da615b3c5f682f2157e940691ba674571573647c09225748416529653845a6944859dc3c62e7c0a9da78a4ea492f57386ec31b0c8730206e5adbbb0253113a173e20313610fbf696803718a0d393e7ce4165e004a450825d8935f7738aa7c6a1226640f3cf40ffa6644dae2280043c501635550bc76e8348d133a55cd73001fa3197c1a071bf30a1ff907813aa8b8986449918c08164817720f30e44828010aa6a11a378261e8b141d52779f73927d7f505dd99c7a43a2db1197ba33a2950c280549564733706009185a493b59bba67bd511e4dc55a4f458d9b1003b90a30aa87874fd83707f1cfaf11a4b9088bd41c8d69bcb77853b396c15e24948722943f0e28c4e896c56f7c9d3974144d43a4765392bdb0c2ef5bc72b27b11ff57d03a8214de0520dfcb3093b5ac72003c615c04f64693f68c0d17cbc34f8cb1ea068d681c917315836005dcb423c0695ad19a06801847e947b045e7b78c9728cd321579ea31e5d7633b121884ef65095354dfe63891945983d54cea2583ae4b64f54065cb5631272e1149c151ed0715e93a30c38c85c59415acf73ce76d9453697a3625a607a205204b307dc3c92cb140f1a75c671e916fcda070567b42a2aa12a2499e26293da440b664bb8337b6d5497471b002435c8b40872ab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923ae96ec4edc7ee08108fe6c0411a96f48731066ae4be12edeb7fc667039c9c1de8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = dccb4033246369cc996695589256e3fa1fe2702fbd5e0509fd02024cee12ee5507a2896d4d0aa03158ef904cae32b231b420c576d0db77d2e9a655b3ed9e26961036849742263244171a48c32015678f8830f08b904943256769255b0bfa71d5c9a727c617fcf7c3d029f2c090db9e53471c6934c94f0149b6e81c128b118235cacbc0d1ea91b79e9223eaa95248befab41078c39a3efdc033fa80fdbefbd4b72ffbfecd8a271f992afe5008ded37b98053449016d4c8c28ac834e63abe341e2602ad3873e5b543e8a4b53f6d824307d5baac7313a3f42e2dfe476dc2abf2b7230b4a71e04949bd08d77b420668ac0e78647be06552eb03ea83c56db72e4b0b41a2e1ed176ec7429d510516c6056a8c2dc35e017d8a9a71e2c0be30abf65994feb4a4ec45b4fee8377616aba107b8350cdf2ba10a1d01db9b9bb789753785ceae2bff11d0adf44b17e64beee6a233695d34ccad2fb1c4e36b5ce20185aef568216998d16c3cddd2e9e251800e4f1bfc9033e2baf0d2a594006e59341054a07be0968cea55839536e240b7a56c9e1ca5a6fbfd0bb23962a7e721bde72c25cec3ee610e0fa2c7ea175a355f7646363aebe34f6ce18d0267aec0cf27d91bfbd6b34a98d6167751fb98f0047b5d0a43943b90f19c0d459e78b46b568c5752361d3394ac4bc7c9ead6af89611786a99f26b64534f0f4157c4fb737a1787214d8044cfa0442815c5203adbe8d1888ad78eb9a1a29e98164a41226d356e48cd43cdadd19b3053d2c507ca4257a4c914552fe4f2ecaadf7313925a1da260498b3d430d6c960d3e8c1dd31dc0f583a6f2a013018ab04dc52fa00a80ada1022b818f313d9388b73edef561027c6981c7bdf98edf623571d3a37cb4f09a829316eff704335962160e333ee52fbb0dc67c8cf6ddf7e84f576e68e2ff6049d8d3341856abad05ad6223112a7e8056d679c5eeced4eb96821d040d283bfcca64fe5398b0d3b718731112862b681fec18af5368dab3f3dcf0cdc0a2311b25627db2aea98633c36c9e822c4b38602cbde7ab727b404f382fdd9a4052c7b57f4627d62a3920daa4f6edc5ff59cfec7ebee4eaaf0d3e89642a7de253084041ac44262ebf5e11ea9ed394d0ea16f326dba11b5759e69cc9e9acb0f963bc3703fedefaee9f7440cd6200cbab88f447e1c6475ec5dfb2debe34dd3c77bad7802cea500ec48952bb6e18b4e4f83a0fc3a5c59f7a06167996e9bd353586066f594b8a4d90fb027298b843e10b008ff66edb74aca345e475f1cf49b1106b9592f1f7263b713acf9e3a9a1c024ff44126166dd59977bd565902dae1ae0a788c1157343e045b0af00ab61fcbfc814e667039ddea20714a2fb49ad94b5dfd84da628d3f1119c440b6de841f0adadf874863ea4accb2fc0deb9de1dd18e3bfe372b92f0d72a9f61778c0daa54c0f6580ee0db7de48c09427190f3735051f06c83ec6a0425aaed68ac49a8e3725fed6bb1777f6beab59417f398ca66975cefce96b5775bbec006246dc8ecea177eabf074accd9b6661da939e55873cec5797bfdf579d38e80a7a2b5a3ee826ad69429a0d432d0b35fb0a51f84d418bb8b769a32deabd8b70c40d8c99b95a3ee7f5ff0bc243f76c6bbfed2fb72a4e5642bca96b0959601f3e7e4c029c0b04213fbb3582668b6e4561933aa1beb3ec12ad139af94b5f688b9c2da98ff4eaae3de57b0e2ca894114b969b8d2ca26e7af503db776635098b90039919d9b136124786aa1d123f1b9cc93afb6e4fb8ceef7e1fc18f6dc804f7a4b28432a689f98e67a123e177cb4a6b0178c3dc0c62ab19f93f624c2bf14ba6dc1702aa547e4bfc713ab95a40c9d8722044511ac4020c70a6f435f5566d08614ba112fc4ff8c2e5e1d13046a5a03a15ee834bc92cd63f0078fadf9aab21cc3f41eea633bd7f866b4701bd2da73674c8d3de6138035edeb47f5086f764c92679e62f0eca34c873e6317081705e69fe45331fcc807f4faef5f75f0dc054054e5e1aaf05f848f0d43ad9f456bd3ebfa809108aa1114f34b47e7fa34483982689cea633c541a243dd48b109922fc1277aacfa681d99c4879cfa4aa783272136c555be0be3149566a2ea5e11f994133220efbd7795f4975a7cebded59afbe539250099b2d78a11bfbaa136229abc4abab7cfc6b25a89b8b9bac53f1b5c4ffeee2b22641122e9c89f57b03d03e25 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0c9c633ff39d1c7cf9f8356aa02981ddfe89d6535e2bddd750d3db111a88b32df4e58f3e7d54361403d212f7c78f1679dab68b71aa9925386590ddc8e2984abecd9647453b3fd99dd97df38c04dd921fa7dcb57e0664d148ea4ad6f97020474afb65c5c67ab4febe515c6592942bee38e4d97155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b57dca3fea3314b4bb404cb66e3bbf8f2953f278fcdb65cfb489d6b3a6f443775796564d75cbb4b9cbf4a8a98d7733f69f9fd4ba89782f974ae69e808e97cb2478f52c8539c2454041d9f32f33b43ed8359dd6856c98ba50cd9e92f9a4ad497f901e59e159b5af795ab0acf0aa753931f47764b6cbab6968c7a779802b469acbee7f677a0a485ff5cab2f038e12ee8c3525f703cbe4127b33fb01adce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78558bed31686c6b4c3749958efd6d89201fc9e0b7c19613823eeab1d8f672089339e47ce6dbfdc3b7d537286d5c26b7f3519af651d8762ac373817bbddbfceebdafcf910afb66896c55a4c946a791e66dfff19aa21dbe32322bbfd127c10d87563028bc4acff2e65deacdd8e9928f8e4d2eea54566e5724b40a55fc0f4632b7b85f0445c881938134e5e6113560b0065bec4d9fcfbf5f797cdba0bbe90fbcd2150d7916ca93c2abb11bd88553aa34c3d5e8bfec423728c86f5f9c301aef712f5f2f68391114dffa4d5615eebaac17de0f9d337e134e3ca3d81514a937f9798ea7b57b3a3a0c8f9a2697b0778c802116c067a5c368576395c43d3398ff97c77051ace6436f84e19bac181afa6cb85d66bea1163e6b0864edc33ec124ce84e82c69202d749a4b92f3eed40d09519df7678bcf82fff9cf5124acbe04388ccab61b07ec87ab3b830a3ef78dda69bd67711ef42413ee89a895af8ec8acb9e69d6495d00ecd8cadc27bee32c16aab0ebc4b13abb37d67ced11ad246e87be1233ff09a6802f6371858972e2eb48e5edd8cf3a8a1e664f73df8cf95ea144d37143cf0e8eaad7df3f581b39b5da3f21c07f224a73daa2b61f3d7c8f25a973b8e5b362fd6800bbcbb6dac8c2a86a7758b38339752cf3ea65f3d84ec982a36d256c69af739349e2d6ce9c9a70dcbda951adb648e5994a687881e578cdff9439e4df8489ec6ad9258eba796e8a6ff5483a71887e55783aa5fd1e5b8889897de67e3feabbe3251a6f4f5bf8f22f8d903e591331ca793cdcef824bc62168be6eb8f7caf99bd5e9b0c47d509e38378fe717625f1f8fc882d1b8d0db3c2109a43d1754f765f9f7b17eb759fb753688feffe2fdb2e7ccba484ab89e92b79337828e1986430bddde0b50a5621fce5dc7bb545cabc77c336893addf4436e732b905e7d769865cdee0a9906438e9eafef521862a42f7baba3f02eadcd1906f31bb68fdb8e55ae48e32dffa30a4a5c3ecdb17e0dd26fac3bdd56cd9d06cc8f2c6b4ad4e2070cebebddcd885d6caf6cd43a4e513f0a4ac07f5818c7686f0745ece93c24ff951fef63f51a3fb373d076dca4eb8da156dc6b4258f46f638024b8782c9757e076ceaf18cc27284c321ba9176645474dad32d97e6575db39c9b23fb8d405f8cec82abf70ea4f4d24c87e9bf5407d8f9a563c78655877795c4f15d24a788dd4bc7ec129db6076d2ab4d36479f478b3b552c46b5720acc514fbe92ba87619f4c05b6d032d5ff63c4dac60d86a62548dfe9b313ff904bbe7da59842da87735546de2189e7d7a3c3f1a9b9f2466c8fea980be798d249ade8389e626a4693ac38a854f9494f382e0c5b92ccf5b29abc331f543ec39eb34d9858f9c8a237e3b043713cdddf1a77bff6df69698b9c927d6bf13f689989ef161b481b63ee77f95de95b45522b9a4f14f3eca7afbf4e8848137b925a6ad13bc7921945230dd76184ff5e5ade4d85aad8b36b664da1b25a4a38d3f305e543a7ae3c37b48296fb84a3464dde4de6771b79e43f51cecbc2ffccc6d4cd6d4a76d622d363076e543b1dea3f9ca586c935505e3f3ba5c6de933db1dd690f5ed2ca9e8720437f437354a41d7849775c95c4417bba787f27f4070ad664498cff67c545b7323c54fb3c0be2962d79f2eee449bbb62273da6945c402d7d08dc7a35f48dc2df7c5edf8c9c64432afa34cf05478830fd3b7572f8bd73104745eac83154707cf81c85377ba36b111c9504a180f01c880d08b55c3008a9594e75b3f026a103724064393351dfa7eb5ab9a1c774a59c47b31437011816abba42b75780c1ea8769a7bbd1ba60e686c726f2aa6c9101614c213a8147cabf658d5505aacb288f065bd31c5b7494b377ef1ab72925fe513c49ccc130cc542aa34abd31b5d99cb8f6e2b9a1c5417a4ac9c91011627e6353cb6529ac19697d05d076bb197790431f9ce62a31fb8154797583692ec9abf67b678e0c204a822e228b09bbb7b4cb3a5df788b0930841aba9e4f7c1212150c87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa500245acb15b7dbccf9a013326c2b0336b66c101aa499159a7c875eb6cebe292d266821bc193ced74b04e61845aa5b1ddc953699cbb7743cd76d930bff38efd943c34b01a8d973a81247d966825d1a9b3b2fbc5769c9d5ba883fc357946d54f3cc3090ee48eb2fa80b4d86dee07c57c215f07dc23aaf8c4aaf2c9e03ca2daa433fd9c584bf582793919449925f27786b6dc2de9c5cc08220feb501fb7e2900c243b1c357c8fc814cf87b233b70ce6f0938b56698c160ca893afa877bba49c0a8f606e30761d9dd14be7a40f8db95496865c2441a47aeba1ca7458256aa5a910948d4c920d32712c55cd8546809704c1760c8f8ed991d8ca570cab3441782b6e4035d82c24105397cfaa8ad86a385327873a228bb0c02801a50340b70e5483709ef03de0483bf08b940c4aab7a61c24e9947875c8e2b930dc208ace4752da4d0253ebb2bfb333a1ec9bdec73283d435c4d061df6b0692df903c6481179e07adaab8d69277958458f6ff5c6e4c92804ea47bc8a03bdd707c1a78d912467a83575fe74aa25c043feea0be5899210d7c8bc8b669fec5840f5b1782a5a9d947e78301eeff9b12635c9b15176499a3593362fe5a946fc98c7083bb185c2087b58b6d7caa3599427259a72c6f89fedf61f7e111c04f008053cbefca2ca13a06d09d9494cf29f82c5b93bfacac8d705e35874d0297aa15c7fb181878b32459cb09d6d489671e7700e4731e783c73c86b5b8731ae765a639b20f8c69844559b0763b5cfab7396c1aa09ce238227c29ba34a48891a39cfb37f1226cdb35517d354d422000c3709b7cf53bb9807e2ae7321b38bb29c327e5eb3d02036b1a4c61a2a66a3e91af4288875719496003988b488d84535cb66a4a1f1ac69952817fc13ffadaaff145780aa02ac41cbebfcc9d798cc4d9a090a4212f0fda861b8760ceba5f334c1a54d52567c2b51628455c85517f67baae5c694293c29a684984ac3e711501d5219fa8279bceda4d8aebcf17babe31fbbffe6c297dd27cd894be83b416ee182306d65d2a962f64811ad1faa4ce72a6cbb1c5d22a1c4a2c1eca36b38618afd0a928c4db55b991428ad72a40679ec7521a170929cf10a41cf63bf0dbb5f1316a23d2acce5c7c34c67f6b2450f36556bd987b525a009c77ac7e23355de3aacad177ab7538eb7b25d613a3e9c11c79e59fd9ea263c0178d47885c7384b492909fbc63ac0b2a4ae455dd3446b395c0bd001765f31c79649c53453252e02b98af51f23f8b2f5f2c8d3eba71ce67a95170237b7a408235429826637f8cbecb11a4dc351fd0134a0cc7869983a02a50ff3958e445a9dd35023900b7a3c41ccb66a54628741adba17da89cef8d83e8f66893bccb50918b6cfa1480b051dd0153fdf5a0561c2c782dca0a02861b87a8aeb304927716884905e1e0a004f3a119b3293fb0850cbba7581f1363598c1384ab228d8720b4c6124e2ad1a9774d7a16880542d30dab2f0796fe5536402bc10326c7577971c496083e0c24541e07c813a01989013ab9580abcc038284588294b743086357d50b01e93d841c6a7b929d32291e47d2419b464c3c692847f7706865a29335a4ff50c536991fcb790d0de50f68914d1ca5b438bc0a43393510fbcf15a895d5d546850c0fb1d970517819e841cc42dc279e8b398a563c174c57876605e1212be53ab714486588f96b8599262d67bbce891b90308959524355338355598b233aa89e4679749207f3ba1086ccccf836c7e3528989d0848b947487781a2b025955b2c748c700b479216c3caddcf63564392d6515767b771a21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e4e23909b028699d6677eabe6bac4bc4e8437acbc52b0b17f1df5760c0455c2b5e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = c688351c04b40d541e7da6b46d4d64ca90ae56db02257e9e64834e004827bee1b5b54c18e45c2ea9f379775f2280097b9b992547d209e01191328318d06aa7f34050ec2064da3f29e2c5e326c5aaf08f10bb8831cb81ad6640e5873cdee26f61311429a0c6432a1d2aae2c1bb40e2ecb57820c0634f242220c931ff3cbc13836cfad3517e39300f4c0f98eb3a533d4f35c5c98e14cb2c8d3ab3ea556fc9a03b09abfe1dd52199f33bf176324aa13f0c9fe138af8c84f889b547bc74539482f7f80245537573bdfba12c0fbd0ccc739fcf40e8f84f7f6b796af05b746ea4f33eb7977be3eab48722c195b1d4ef2b56112fb30d9f7ad31d31c8e7640c4ddeeada3ce4c7b6698d3e9b880a682d3d14317c04013ddc620d919dad419013e4813ca81ca9c2f3006d859f19689549ef64f2967e80295dc834bcb0c23bad006210ea8c38843de7983bb9c1e6735f853cbc559f121dd5ba19d4f7d98ac125d8efa03b858466827c6db2a2f0bd27740623341a691af087e416dac30a2e6d782c4c43e4a6993fd4222a8e2958c40d285ee743a9b32a82d1918b2eb216d6175ea69643d2843a32148b931b1d93a793165b282e29c2020ac05e2b0fa9d8ca9f76f5790cca5083ee17001f7f43fbc5f8429dc86f4849b1ca16ba588092fadd39b93d92e4d42aed9397acdbdb99e12f701231cb14800eaf02c948b93362e4d88c01f57e4ccff0d641fb2a209e706727d236cb089bf1de19e64ff0eae24a89a8661caf94e74310b1665e108a0317824b8de8a1a6978007bbc61971ec7c742a588b704f357ea8c22007b8b60feab7d9d78d6a5a89265d263f4468da1def7f165188ea05b9fbcd80431e21659e52870ca7865ade7d1f7d0a70373875c07ac1a23c0ac995f7d1ba610d0ed559083fcc437e1896ac73918b0c1dc290fe648eb84d9a8315e01709a80a559a7a54b4884472f0f785aafea6a69cfef57d460910a22bd1bcfe05e4e19ce109203e4711605fd982f32ac8152525b43cf9ad8a9500e7c90116cfd8e59fcdfd9aec7978ba333ffce54e2c4c6b145aa3fa905212df5e3e0e03339ae6c5b1130672fc0d3a98d4e2ee2d7550ffa0d360f77de309798d64dd805b3f4887d3b3810b44529c0b5fa39d7de88a772e6f9228755cd3bc05e5eb3acbb2f7c445e763fa463c54bc9681dc51585f2fb6203381c466f89f38108ba3c779e0794217f5154ab3534ed0627367cf8e7a8a6f76d3521b632b661429845f7b173b5f3e3232cc391eb8de1b0cca409a717222d2045124f9dbec51c7ac8177ff637dab056a0c649c5bef3f9460d2a4047c62fc1546eb291d2c968246533df79185cb9e26136651c5166d37e531a35aaa41f6c7edb7bf5f1092695c270693723fde78b2f36d79a109b225589c97db8db07343a6aa2fe2a43f2034ae315cbff869880a53aecddd9e31eb62dddb73a615a1dcf163e51423eab895311b303170aaa3658fd8eb6be92c3a377f197b00ec83e50ca8a0081a5280908547f9d373d7e1d54361bb7cb8a2d08ea054024b25b47365550fd9c9df1ae1bd2349990b776e350b3f371fb466813faa6b6b4e8d005d790cc69c77d7cfcad983aff636edb9fe06ffa0079059fab7d0e30b90c88779fbe65b203460b7455a08867c8840ff5cff27fdb33f8b81591503cdb3b0d1c61bf76be02b3259892f20393a1cedba43d7ff6b6a83c648ac6751c3f8e759223cbc1959400f09eef430d179ab0ab40840300afb19ef43d685a525b9ff44c49a5cc3ffad91b6a64049298e6b2322891162c21448f416484c45573d306153d7cde42251e79b15f03ec742cc62eff79b0af9ad84fa1621a083b97e51805c310483380661972e141eaf12032dcfff1991a38df720bfd3a2fc185f6edf150e873fc33cec05f8e6fcee6b7f2c62af3672844ed45b8237495d6b7be6feffdfa65e61cea2c70b9b4bc1716bac1d4ff28f80e9a3dfa7cdd559b3bd0322db1f5954b3fa0a25e7b5f4dbfed9ca6c7a917b596f323300863fcdef1102224942ead7e79646e67294cb3922609cd19d1f2e067df2f5a0a4317c7c50888af3417f55b5183b7331c85ab82293c5ec4a43d412dd6ad0bef34041e0bdb4ee9d6cec778441a7a088e368c7ddbb21456f7e4b2c16ac001b8ebe83981d9881b5f2fefe910ef66866dda7eeef28c474b66b72f3662d8063e770f073d03f4a88bceb10eb195f3c59128 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2ecb7cabaeea306e5a13cb82e5a8be86eec2bdfd6c71b969678f532639b57b9e537e57de8514390949cfadd8db0e5c3ee3eca86afff25066dd8896b5f6fbdfc6fcda6e0e760daed8b8af6cd89d39bcb3cf9fad4330ed581626cfedabc12f758b407c8e9dfa373f45c377fa6d41b7f05a83f2b737cdabd8e14df437e864c4abbb3dd084964fa7eb37ef4406a7a7545af60e9e7c0ef95ccf33b1833bb6d433fbfce37b970d4ed7779258faaedd9abaec5d51d806d6eb85be0f9599ff28b40587488fa376729685a8336c0eefe3f55447e2c489521eb98e73bd784bfd08a6dabdffff6f894ae5456577b8e156c66f6f1bbebdacd4d1ac43b77936f23d60d43d5a3893a82588ee489f8fc59fadc16b31b2669882fca1068e603c5ddf297b7fe85f5d20f8f958099b2e1e8ed4ae4a8b9e57325f5c470b7852a9b0ef04b4a4bdb65b4c5d7d486366175540b9ee752993ba979d8a446f94088c7c4ad2fd6cd520adda141957e63cbd71bad12dc6da02b3872f3a623218a6b106f9fe8580e97f5d9fb647f128c2519a8a0ddd64977e616b56fb849d4ce72ec95ff44697ca71cea3deaf1bf8a6448a1c6b38c158d0427683b71c954e49b6a3b978417b78debea1ba7f9b8926db4c7ba4a04efe2373f4619e3d82d655d7fddb5b17a6368f7d8a0781e12a68c536ab419d9f46b7e73fa9cc9a9d371dcbc0b8a433446e33ad1f3a73664a15ee409b4476ac1dec18ff6ebe968ed8c6a9d59eb92f234499435e2d06e6c849be5f74f2c8bc9de9fe48a8cd713d93642dc852b33652298de0f03bed7b77972c797add3a38651b4c11ea968ce53f10d38df426d1010bdfe557bcf5b3328f2fe50a8cdd76a8e2acffad2c1c7661844e6b34b25e7a30ec64b6e7e4f82f48344bfc6f33ab3c428c76705cb9b1e963782ec9ef6d874027d13384d8299fb4af17474914ec606b3f67ade46cfeb0c9df84508d594f265a8fb639e209c9b7fc418a33daaf44dbba34c1c66b7d5719e8ed6caf906f76873dd58cc7cb50eec762aa96a60e5b832e6e204c58221ffcaa84af9c1fb9c9bc683747a2724c88e75d539779742edca6a6a6c5f5d68faaf73d4cc7aabaced5f4aeb46cc96c9169e2e807aa6c94ef6be6381216fed2dd7bc9164eccec7e677fd56313cc32f63c628ecf3343adc9073888d575705d8d660f5bf659da5f7be64aa4f466f6dc451dc72aa69d2dbed459b890a4dbf2a86e3d44f7dac96aca21169f932a6135df7a6c05582e93dc0cae37df16dc6249b36093ecc6b993e3d455c2f6e695ceeb520c64078bb552a65a3bab407d46c0ee173bbc5fa95c7cbd871f3810cdcf1655c8e79ebb04a3e03ed8da5fd9fb4a5ea0d78768514f84ae5f580f26f47b3c44af0a397f28ce3d1cde4d34cc49bf6b3998b061ffa9a013889685446c6f81b344ec08e8300b0e3390a881a3a4937c5efbf4745b069acbf63e5b9955aa4999ba827bccbbf776839f91a90672720591056ffd6ade834886bde77cd78b6d61305833fefa710ebbc0dd17f9494af85acbcf2708cf93ecc76b85691f2dbfa4379c862e420c33ef694f9bb5c76e69378f6ef3475fca5760a5be82acfb4fa955e1ed931423b0a625e94c36f25bc538e2ebf9e928c68699fbe82bea04f94e9ba65ac12a68d013885b1fed91dbf1cd7b76f0138667b5ce8cb742e5a54bb34bc17b28c8af6cf7bacc6c308cc128bde5222d755de6e145a7dd3dcdfc664c3fb8c5763ac841f845b7799c9cf706e4196eeb6728499e843ce2ae8093faecaa879bc7fec4aa6af79f8dafedf5353d6ef1a6dd433ffb748c0790161b648886a880cdd3381aedc289ac2bd876262c90081470454be2f5a7dd939c6bb583f63cadf625bd3e403395a3a9a3c8b897c2dc5a6b73dea4cc87b6f456b66e6a008c8dffd6b97064e117335189fa4ce92883b88b3a0917994974cf4837b7b32ce6d36bcd877e81421f39086940c4ad3dcdc6e2ca24e1d06d38dbe35eb013658037b98e3f9d4a647d2fbb7983136480b7f2dc89ee238ec25114d155fa5b0c19fd437576a5fd55f27d8c58e3611e3d71eaf9d53c4bae4af87694a4d77a1faf5f0ce39d7e64749ba2eadad6770dfb8c4bc1545c405bbe6e911efa4915c4b57dc230587f0bbbbbdc3487387635e457c66e3ccbce8c750495f7959651e7c99be7540833828e457c66edec8e201b07d8068bdf671086d6af0beb628685790487707b66be4c7341c654a8119774e8b262b2f34944898e42752149039356c1348eda779b526da7ac838551855a4a8af5780c5567295dd16011e3177e267948ba7643174391a34c5597b7af774256329f211518e1a67b2f35898e610f49500c2b4647297723004ab77f9b538524a9b96b1e5fca8f224c2e24701bb726735b408323784e9afaafde570b2f4c2bba88bb54808ee73aae69ba352612268e9b4460f004af4998a6c484474c0d04111f2d1091d31443ee2447be719e8f4c3a49e918eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523ae006853b5e09706259605e72e78ad6fa602bfbc7bfbb0d2d78b5155b3d2017c9086803be862ef501196ebc2af13b2b0569473e9620fab2c85fc23874ac14b59c0f082029b553184b01c76d856858475914f025df1914c16a209dc90a306914c3371a6cf68473a431b2886a8cd40a5302834a73359e001658b90725e02e63c27403fc0e1953b11ee6a6415815d2b2bda0b13e54511c96b801da22b5ae94b68dea940ea4787f3a1506e290696c3535b8ce73351a6e48bed272af5e456904aa03094210494c90b280c2942682dcacbec8c644e9a36d326816a42b23b96b751afb7b951a87d8e94db48932aa14bf73e92b06b85f7afb4387e949645c5838622ef7bb2fee0175914b3c931b25f80a010568a179a21727f52ce578aab6da1a88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e18fa294b7b8055e6acfac6242d671855f29979609b821566acbb381dfab0cff8bd47204fec023ef281226b63a7d0397091a9844e23b28f57a0dd205a520a48a3e517276977388b575522c5b78627c4253bd38840a7889fa75a7bacd10b8f27a3e13bc20aba3ddaeb88ae62b2930338cdda41e0770b4d2092da100aeda2b5f5600718d69b032a45bd677b8732965b82908b877f5f77446e4aa132d46044067b21090404d21d01231264651b38832137da53caba0865957f5af7ac4d640fef96702f853bb4a70767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5c81471539c42144b4cab5d8d53285f8c415cd8cfe2d30295d00dcb47b4ffd90282f6b582a57bd3f13eb41b088ba624575b355f8c7fc0f34f1e924fe7d653692c4f44e1c64f9cb145fbae9e789c029421793a4c43856469298b4ec648b21babc0167c04d90a3a8c554df46b80b407dfca54d5f68e2dca4e98a92ff38b427115c26aa33161503a83143714234fed912829bcb924d69049a1c958e6a3088cab51f956c87862e776320e78457cf31c20957158bb377460bfbf93a44c079e1f1bcb7b4268a0cb1cb8151512dc632252700cf06c988b2a3b254ac6422c73432ccb143819105897575c8672b7b0464e61a6a8891bccfbeb51f96120107cce8e950802b2c04650a1f264aba721541897538278bbac29b73f811940a47249035b04c0023084bf57806d51da03605c0ab0e6a6b65cab53cb26425666dd1b597418864211c6bec492d4577bc127369af391f8ec72c53302df5013c2c7c62d364b35508219749f131b7e2792cb206a9abe2c21a565bf05c1a7f8995c89549aa3120ffd83cc7a8b8a95bac3e7eaba48b57f55829f05bb265cbbb8b0b7983f7618f2511b3fe3ce9a0b735f2c1acd189f9115a1f1933ce19a8535958cba82464ed9829bc9a0c1405266f697d54128cb31cbd5b95c72740fe16219997210512a7343130e7dd00556948abc6c0dbd215e9db44a2d80c5606b930c6c8b949081bb453461a21026943929d3bdd3c942f8951aaff04276d2186cc052b6f67e84d5aa6be0c67ad74aace945ddd7c4b75248a0854593e8b27e971895b58c08e8107214afea3aa1b41a17ca121fb8308eea899e8cf04f7e884cd40746f2106a86164489ccc20f526154e613c565a282d5742f4953e963c42e878ab4d6668cb9c15f8629f537cdaa078db33191ee281a46ebc2a3036639e5cb1b201384b222af46873e1c946438125f060afd4734e21794a8da3d7b266c4125b60c9c480091874ae9c242f550898a30281380fa352c0d4466295a24653181e0e292ae099abec3275f8a89f22c983c8a0875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433513906f5bef81445bd210d63fc4c9b9ef0b61c17b0cd5b229a45908fcbaddcecded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 2929caddd4f0363b2578c242f3e6b4978d19f155c3de70cda974496e367811fbc606beac5c6462d68141dc06dd9a3e7fd30a4019c010f43b1830e197aa31df52362d0b969ea4d2abca78b3d2f9dd6ab72b5963b2bd469d4118337fe5792f49e424ff43c31dda4449ecf3988be6ec3e353ad357191264a54145eb5643730da691a4334d3895299bd3f18960ec2ae9a28f05f231e8935ebc4a9ed71752030f40b849ed7d5b81c64171ec4422793fd0a23e85283d59e8b0dd5931436bc37ad82594ef3f73d2c0e64e7c2f7e0cdd14a8ca835f8d2d0cd30b726a0d66f529c0236069f0b8e87cb2e022cb255157a77bdb49fadd8836010f301208d3a70d8b64a7df70d4a15b1ea9e3f15f91de9b934d3e4b17088037d282bfe89a2eb54fa17b1857d977286e238f1928ff0c2d200fd6122b2c85b80e75543d9814ffd2a90f4d7bd51bef826f8063ba56e1ac902ad4499d9025fec564f2f87c4fec9db6617b64dad6f35a8b552f7da029d5699fcf6c477201e36fb39b9f9cc40a5e44366ea7d894f579eff17a061f3d2861b38b21a25177fe658627b7a11e136e490810c9aaa3ce43a7700e7a30a014bbb13362657b479fc26b447b554db4de68dfb9e4912327a6f1c475497a5638ac334c5fd8b8a2c5a6d27e7f9c7e9e6dd53d5935811a20a24a46c6cd16912e6917946f5b59c47afae99d02c93778e755b6292c5bef16ed8fdbcd0ec0f8f27e2a4958ad98b4f4f78a21f6f4f96cf51d97fe0566ac95f01cba045685838f7db03d30ad856c4ecf5f1480e2fb60e55af50b8ca917e66e3b84cffa0dc50f620512d9139701be43810caaaf0c762ddb843fccbfb9205787ffcae3cde855013c5ecd5f64b68006ce2fa6dfdc416ab81328a478f2298e144cfc12f763daf2715652b22c1c20d7d1365f6d29cdae850364e32395960efb4d0064e96ccce5c4b089a3aa56ebc5d18595071b594024d392a536790f3dd1cdc0caa5f8367a5639c7586b09d3b1da545bda09422c9243d6f21b3a023ad806a0ef688d2df93d9f7aa05752356a90375b1a101b52ec1db9c196ab7532c44a1690f15fbfd2606a646592d44c647df10524167244a0b1623abb9f26fb068bcf72b42d09be0496c326d37ffedacc15265f7204d5892984c235e54cc4f3c0af4b412cdd51961fb30f4172965a54c2142e93d06e6486a61d748d138c71329990960c4d5b07d05d1f795b91b938f2f5f2e1b13f601be67bcc226ec1e595b4fa8ccc8dfc0f380454f1df747fe796fb6c26bdbec6ccb15d2fc5034f539bf2f843fc43a36405542ea6cd388a2b3d18c67308d6bc9bb379fa29dec50142db422ca575dff40fe21625dbc35bb3696f24099a920c6ad21dbe033bd851298edce552d73e0b77c81d7ee67b792150caa688a16d5a933545340025c60e95911002190327e62ba892eed528a5a4a4178a13fca93f203a54b53c5958a5dcb067e108b7b8ba1bfcffbb2412d0b86c6012a7792eee413443a372c09d4ecf3bc0c751911c33de3f003ca1645c4de0341192c6c5bc402f49fae10a7eaf3126260eb76c1c92f4629204c7bd70e7f26c8d6b3119fde18fb09d327b79bcc7b687dc352574b224977f1ec61c0dd0a6bf6cd527f24948a92ba5a61fd458450f045ddb8c86f3e925f5afe9302a5086bc0f09f759f8b59baa5f6cbffa93b5eb570fa0c5aa400e4164904940e94884824b28f2bbc7b4e79bf9b6e9002ebc9e017da0c49248065f37718ed74f9fb32ffba07266d599a989602b55d8a700a2108708de10f227a82d874be5f8b1489496970b6dd2a45df290227728e833be6f51bea9e22d186bcee723bd71d562b100da63164fbd38476a3aa305610ca3f3f96bac26a41cf884fc6b201602c7efa5097cf59a06707d7dd86ae4210016df94a2c9a59601a1b6d87db3b8d3da59d56032165c7499b6581548e8d69fb898acdbb28adfacf9604d47ad382d8b4b655cbf76c26f856ff28693b3c725f047bbb2fe72df9c38f58d8cee3435eb7beadf4450af322e3d837cce09d80f2c9e932d795d00a43c8359cac4f9d3e2b80d63144bed2559c9b733220c9ced94fea87409c42c7f5a6f2c8fe35e0389c195fe5c13a18aab1dbb97284a45d0bf87d7d004c264f8f687e93526a0b64632d6730a76d1869aa02ececcda1eeb1d05688782fb86c909b7ec128c081088992a7d6bb73f06644b9c8d6d12a6f88917ad29 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f3ac3178bc3e6c9dd2ec3dd46ef3f88f9cc63c1abd0b14a118e5fe2c9a998d4c67e30e4415084f520945f55b985adac8c513d79789aecc59eeb7ba54103fbe8823a4a837786cee40d36dcff5d46186588f50ef419e0c4ba1c6e9567b9d8206b53bcef8974d52102f59f5d685497e498b23696b4fe813d7a544e77fb42ddb34c89af2c63856fb43bb0a74a6073959eee99c4d98386984847962b353b4d81aaf4cf65349d8e97db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b58f0369799d45fce734e5cf1c692537a48ac6d3b9dc741a08a66d874bf46daad570b6f204e33068aed900ca87dcf5e91c4ce1c84b46d3c5baad46fee2f7269fea9dba968f0ff7249b3c6e4c7c19e9ae3047afb45ccf4f53d4a81cd9d37bcf8a09f4f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773717d46c46fd94ea547d3d50ab35e953464f4e64d765bd8103a88e448446f6c8f376ce5e3ca9a98798639b83638ada857becee3c77d5471975c51b8088af6348babefd234d27d6c055d3aab766db28dcc13d343a7963dac868b5f6ac83af04b8d8bfdb64dabe9df3fa5c2bfc2acaccc4588c1caf6f556faaa6cebdbc36467f346a1ab5c5841ad7bd33ceb54d93659bb0451c4c87ca485227fdc0bc3674c4f75078cd2b9a3afe6ebfe464e07d19fe594dc4968c547adc723c1970cff7d5c5d33e3a4533f10f8655c6ba44bbf2c2a4c85b8fb4b6dcc09775e24e43c985459cb2bbe519ebeec6f348d017a785484802e9de032fca2313b4fbc465dfcdcd4f3a5675e33cf0db79145867d6fdb8f44d526c8a744929728ceccd146b6e67dd3f660aa4e3ee5d200b5960f3a03b67ebb2e59160048e499ce538adf7e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc78aed62571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c86565d3f2f970071b40f6ba3544c64c418871858f8be6057a9ea7f6326d4901a7870733580c6ab8d4bae8b49cb4d567577aa8b0ca2490edc68b168583b8b38415e3ff5558996cd9e1a957d95153dc3607e813fec57abef327d4ec441c980c286b71b3e748ea54df2a5580de701d3e73944b7b411e7ef9dbd8a8dd3d4563eb8de4c753f697ec4b4303448c261bd783d8eed599425dabe68078f8bf795c8cf65a95f366bcade10cc75d3f6d64bfee7cf1497f36c48e68b46ec084e7b2a876cb556c705c7ddc387d75ffb0aeec9071eff7af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94b9f389beafbb64d8cb2cdfcd3c945e39f3acdb7e16a45c03ec3298b3c44eacee76dd49b2ebbcf3ff9a2d3b7fc68644541de0e15fa0d357809009cd7876d4a39898b385b70ad7b3bf1eeea83b93d54f6f502da3d0836fc6fb5330ae453628501315dc17edec585f884e49a82a5adbdbc8bc2c7598d558f78703ab4d6d7a17bebab74d52f41ad6d49e5cd048f5f13cd69d956f2a5662e068d4183932b62e6ca76f74214acf5d0ea7f4c77ec06ffdb786d68fa4e51f7ac3394ef59b53bc48e99c51bf60fafcdb7bd3cd4fa9b5a6cf588dfd98fce5aaefbe5fe75e355537953d9b85813e3b56336f9e6a72405ef123d5ee942438fcf65f92cb91a0f99b3dc5b0d90a94d7f9b0d9d4ca434d8750169541afbcf2daf0f13bbff3ba60f6faa2df8ce76f74cdc219d555c658f34f73980c4d6c0346185eb9e7e59e8716f037433d2a79c72fa6307a77b3d0d4fcd9deaed464b90963c352bf648ab5bc1149d9ee7ce5bc0e89613e94165d51fa534d0f7f3f4e28cea0b7ad34b3767f2df9599be6cd97e81d9b8332f87b38795eedfe622f7955bc646e470b54bd3bc915c3bd2ff4deba8b31a21b79130a3ea50cbabe79b7370b5130695ed8b6e2921f5f7a2ffb8a19666fc571076361af26b1979a939d58eb55b781badae98a9ee9db5ab19deff617a59852ad4b5db78e1a63fa4db8ded29c8bd11a5ff46d9e9c6b4b2427e55045af7eebdd925d6a7bb5920b5d95c43f7b628fa74bae4bb4957597077e93c880293e37d9c4f4f4ce635715ec4bd8854acd90edff3bf775d941bcd0235cd398c56d0e46d8f1e348dbaadd4e35ff79bd5c9bda80dd0ea7c0c7f0646cb34765e4ca43b2254ba566d9f9d9d68fcf76c08745bcb7cb2c3478823c977ba1f3565d880d8e731337d798fd273bee2a03416cb6d11774e0b7c177e23a619509e04c334e486f97a963035c2952fa286c8108a3fa6857c080076143185603ef480c7ea135c76497ac2a4ea1c65c535385bb233c54b0326d415d2b01cb0fa60b969bcfd5578920a06659291b59e5100441b0e535b46294680627646c052d13404e486713fc460727f50677e48e64275e4e2b33da225686d920941277caea4d8f4a7c7b96b151b36836a76671c9010cc7546ed301866a694104169540a8620415037654a55ab132d56590663c21c267b94a2f1a162bd61808512c2e7c671247142c3cc54622697edb50514895276efcc21bb02d45c79a4549a501e79859361457047aba280f91c13556d06095a13ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a482afe97b508304b6140ca9da2c33f26522d51363662a0c437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fd927c2e3207cc77cc127790ff2634cc2220ad001e39ec393c5c5b5598193d628417b7bf5f903e9274c2a1a38f72db99e4c2aecd8b5b5b445d3d259057b2b3ac1b3a0657c2dffb6c75c93b20ec3358180f9c124fdac8a64d2b73ce6819bc1005602151f7e4c804bc89a81797ca8313650910c7b2a36ad2a690e3af7a99cb2bb09cb1eaca0891bc69d989cb7220faa3626342cd33438877799835c2782413a9f1ca29861752f294b7e3c2a3980618d0540a5cf00c01943db920bb4693436d3b7436593e7b9a83cd21cbdc692956cb3f7a17c41f46af94bb15059b8661349248235adf68b69d9944f2f30f93173ffda657c9d722d0521c12b2790e230afb49496a930c46a62a4d8c26601a4e783b73c2a465722401769365719681c5086d8a7bbcfff451e58b2cf32b363c501e978971d8c5ac6f41b458693c711765c7fc1ad7319f3481a68bc456eedc04fca898b0b3ab59a14b7fa1c148b6b792352e7ccb1456a86a5a0377ff98c08ac0bc4c997b0370baa76950bd0874f9478e6b8150770c4ef2885e88d119126492c09b8e93110616406e6bc7ab46ccb0b47587c0da1c54828f98941dae515d279308302b672ba10ffa0749395269f5c5a03581799eb3b60fd53355b3690efc291c3b77aec797fd09b1cccc8d5bdb8b4dbc18857c28ecf86ba3a654b8a351d0174df4ea4d7f4159656010f051462a3c4988e28e74c39cddb557566b7c757874d9061fa5f85693ca2124822891a4a0afb000a3887522326dbdf4a54e851cc775405938bdbbd39370c01ba010b8b3785e3880a54470546b617ad86bc984a70de844a510e6a14e241f18c765fd04c2006c6781ec90c9e16881b7bc4557945d68a4543a5f16968b39f38e8f5aa7699171d8567e35da662087aecea63aec3094bb4c88f08432b86780237218afc22ec78c96322a81b8060719fb6742c290ecd8664fd378a95341f3c326d992b3b7417c5f543249d57475b3b526b93307664217b8837c1c48ee6322df891cbf6943fdd445f2da71f8ac449c718e8412cbe0bc2efbe601ad08af68b48f7d2677dbe05914d9b1629b6cfb69a9f43a05b6fa560143a45f21405b25983115b537315964b3525117158013a434785fa13b30331148f028a2e3e299c9969fbba917cc27b851823630bbb930ab2336b59d1e0060e74230d6a0399087ace16894d1e4236f3b9b708645a3b27378a86c960bb038080f93e66bd1bcc3e57739591c386c45846cecbfc90ab3fd506ec50c0d0ec9a2422cbacacac17f62472b4ac6ccc645d48b0283a6c62136a60d62354a983d4ceb74eddbaae57711bd958614f054336a38630535f0dcbdaf918e5dfac711093974d2987dc1109ce7bf7429cfddda9e1826172114254ce0bc526ab358e359c35cba02e720c4611dc17122b8bb02702a962db3470e32620d62291ad8c9db86615e9ab48df3aefda4003f815a1157640e765afb2527b2c532011ca07e321673c721c3f32a2613394f68b687a042724c0207cc3b87675ab51a60b4f12d312a0fb5443cd0518b1f9788fef9a36752291647c234d49daf4a6a4bf420e990307f676271a47cfdc68182500a93c914ea348dbd544b3163780a2c2373282e319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e4f8b3e9ae47d3b5b95c080d4f18440c24b0691c19f06f5547554697bdfe97b011c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = e5f3a007c0d3a9ba2786ba555a8c3f419bdf9df35908e4690b22a7ce095253c994778662f9b1cc0c358f8118e13cd4eba3108b886bb5a97b33b6887c80d2cd131a774fe781433ddc0b9dd679689546546b1c013bd7d8904a8bfe85933bb1488c37d4ef74b9541084f835cbe9a4fd7387ea213369e2d862ed7a5f2b294d2cc77d644a63c9d05847178dd0ce695519a92a0451d6239fcbaa76a24ce6b32624c9e3814f7da3d29087a44fef74c9b88eec2ce7f46690c9243221a235dc929a1ce9e446544427fdee71f1ef91827e181924c3d8f70273605351682cf4dd81088d4fb259c86dc3b4548ec57412a2ebd8fa5db3be5795402ab5588823ec62ec2df6d4bf0282ecc973dd8ffce0c8ec62f53b69cdbfc98fea226824eb43bdbcdadea7581ea102896cc57e5cd279a01796e023eeabf45d7b7813b2eb92b5054cbc2833942bc4d3066fa41d5dd6e9ff78dee4ae7f12ad6840148d2123544ec23c2dc3518f0b8b2ae13031a11dfd91b9f145093faf6affda150674412e4765e8bf21edd066e3205ad01b2f1686e8b7269fb41d793835f331bf2b71e6a53c35bfdc267a68461fd4a006947e0883824762e32bf1c1f93b4f98f5e154e32aec66307509ea72f2f9249b6c27cd7962032ecb7502c53791cf79a680b70ec248fe491ad71e75ae89913c88d5807d00eedd55d4ee077041ffe686e82a6f8d0c726e8b0da57b8e23382e8262912c7f2ded964bf4872f71011d39b887ffdf17f86cc6e7cf90cef123bda28e234e6dc0980bea57b733aeff0fc8c5d740a44cc421ac0d0e55478664908d74005ca6ece53dc69449de276ad52bafba85b03ad44c07c5210a1d8fd0f95f7a0cc9c88fbc9f838ed57926256aba7432e75de13fdd99ea43d034d12ca369640b5097a878b483c1ae1195de6fdbbbccb6a15c7cc8207e6405493aeb238c0d39fb544135a3796e52d91470eef480bf4f8f2a0b03a4625cf87960260b4b7c491cf446ac4f757892e47dd85b2eae90bb9b03eda843dd2f9993baf08b7f9142af62bc432ca8a3f3b2e85b08715d25ab36c4500250e8b1e041e3798abac3914646e276ee9828280dd9542d8e5aa28b80b3966b139da0ebdf6260410401f02863a22986ce2cf1be953ba68eca4be543b840ca0bcfb492907628d66afe24a2376f6c886ff9f8ab09abadfa112c5a4b92365c57d615a17e41249d757a787ceef452b5ee386c773685a2b723749cf9dfee7c97f1f0e524427039522fd0481594d777f03f7d11da3c001f822bbdd33c95a096f8ab09eca4b588ff9a68435cabb2b2cc1f39ac5e146474505bd893f94e2b603e8caa82cdfeb15873cb12ff87c387c476e96960cc182f569ffcc418900e6eb9db6d90df3df01cecbcd1f6d2c6605cf343cdb814b78a513161cb074c5b164b8c0248123a68c7ad12769dbd290a9fff6b2035715934aa78582ace98f10190dddffe8cab28f97ac7cbeb02c9c854a7900a3d3b5a94c12f00d4074d4016b02abfd517e4621aa16360d05a38a4fb6f22f0fbfde41fd0c7ac0d7583900c51cdb62be446792f051b5f1c768cb91f829876315566c607b3d944043d723bb985669f157b5c7d5baff47e9973ffe89a1364d0bd8e2db2e6814afdd612e5965ada830cbfe22ac43da7c9e49aa54f9da4f88e8c0df1fb6dd2ea3a92db1069f344f6530c472c400006bf2bb137cd601c686a9684207a828de1c5f401667e1a83832501c4def21805da23c5d63355be52f7a55d1951218aed1aa23303298d81db3453c9c8502942137f57067697f67179b8b33d9bd7a98ebcf63bcf6f925abf063c2efb4d29fad0914a24aeb9ab16e0b8aa03bde1ad7299105b12e9f222186a3f52f8344c8fbecb8a410328f99ed5ddf3afbe2bf2f5aa8c4d3b3a593e7c3769863a6943981824c8d9da5d46f1ff2836c765f641e3bec4079b1bc3a4bd3792658a987faf9dec7b3728e33d2f28ac93d1060f6376c8571d8334db81489dbd09dfeb57f9917294bb7b482f430d090da5046e4e7d0e1610dd4e0181687e6fe2c8d8369ae2f3a88b02f4b435a70de1ab2b2f8c1f17990d623e2ea489a63aa21037230ae37919f1561c0212be8d5ed87e1a1c58ac5503ccf40b8229ce8be8e542985e3bbc9875249fcab3588bf7fd6b84825f744888224706e1d14737ab7e162cfc40eb65b8701a09b38e9a8dbdc8602675980f7ebec5538ce3bf92e8c299 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3707d9958d38272fac6687b4b15bbdbc1a9ad7467e8ff4cf45fd614de74b969eb9c65edd2e7d84bb57ac27963aafbce48df8dddb6f32f5adc634d677a81cf26fe6706329ec05a54afd0f6080877538f63df93cc6fdecbbc0a9a0a52e5488eaea2f8beea8f8b917f32f397b94c90e70bce4f3c2feba4c736449f84bafd6711c0d70daf7fde1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2dce518fa4bad4cf3439ed6952c9317d198b0d2efd79a89560dc3361f573309fdce5de6ed448ac2feff1c8ea36027dfc27f640dcc394a7ecb5079978d05fb80eee5c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb525dfd90a54ba793c84552da7c3cf9e78a9b8c83c310d88df751f7c02a59ab69ceb29a5fd001f96d0a4dedc338df4eec1c8e34fd0dac4d5596f98afafa99bee8be46bc0a96df51f639ae5b52239d86229b5bc79ac020b61a57cd4092ce0cf9940f798a9c50ba1f5fb30bfa947f20b62a71fe5c5a88d23c7dc0e299c53f49a1ee5e1ac68e2568e33dafe95e1fb5d783e4559ea79e63a88e88ec4234e55abb5ca92fd89c0d6d9cecca32e549b0ccae67da3d7a3a64681b8e5a69c5d7e78775126f483e7701447d34f0864d8d53201fab9763c7921eca6f21f47e7ea364298c1c3ab893549572bec45c1a8c3b88659cfe5f6811bf3f2095aa7ce424d7e78198ed9f93d63b52547b9c731f9933622a33c7a8b927b6de91593488faadd1243e0189e9159c7a027c39570fed9394ae67a6475cebb492247368483e9d26e490ed5f396d7babfb638bdfaf9f50c9ce383e4fc858455f63fcd7dcfcb85edf22f74feeb45a124ab1b997c917a550c3469a1ce85ec0f38ffcb4dcbf751e12ca17b7eb808be446eb7e80ef3d2e6998ef9eefa857c84ffc377f5f4ffd51f38a5434522a9e6a715977025b3b4b6d60f778de7e4f6a2f95927335cb30fbf418db8510cc0db1fc4eaec4bbfb4f998ffe504b8c5d336d4f1d66e8d55b50c393f973acd38af36db595e3ffd8239d4ffb5f9f43d967181b9b94f55f1c104a8ab7f6dec057abe4e9bc8c6cf350c91acb78b094fe4504d9f78a9f652f3deed7ba2375b3245d877c8e8b874fd42717ec95663349548ea2c74fb1538fb9945c759aedfe469cd091b44592e8105da96a479be0ac6b3ba155d35abf8169e6e93e9bad3d431945b852f5e9df11f9175bf4a32cc9fb8b6fde96733d153a799cb8fba3c86ba2decf3d4a97bd3b699467991a5712a6d7c27274d3224cd1848c17f1550be47b71b1e9873045e215bb817cb92c12a7bdc6347df8b64dd686873e8d0b477faade8af57df995546cc38cd6f931fa54745c55a7e84ea85cedca7b980386fb91b8ae677a035a4547b584887acf567c8cd6bcf85f7ff460dccdb73f5ae0993c9894e8c234895380c55614facd15a6c016ae3ecee6cdea4be395f8a9d244231adab053c568f3ec64d06a3d7bca0e62d7b7669811a45e2f8ac6887137b0b86f7d35decce6d4ae786753fb6568cc5f2b297e2222fd8c1849d1f75cc4fb951d2bad81ada952998b0b0e938b77359233a76c135897faed59cc5639e978c12c6bbfb735fef4bcb1e7de80e0feed367c02e79916d697f20197d07e9980bfe3d3a0ac5d3fde0a8bc850476630f5b8b37cb8a89ce4a048aeafd576b70ddaac283981457430cd6fa900c7e81f47f2574802ec9e707e54db0e77c223467ed07c29b7c5197a38b9cc7c77da9d18fbaf71feedb32843a931debe69fafa76ed82a646858e4497f777c0f58991305dc0a5f669689bbdc03370114ff32dc48fc36d38a73e42e17a6d7d7e1f6fd58c249fa50779eab3fec811975d957c38a5e3f39f42f7a68e75ddea6a50b730898e02dc93f4f056bcc4f71067fb6ce36865d7fea75d771751fa12cba79298851764da3d8493f3ea68858654c638d7794cccc420fa9e253f8cd8ff9721efaf19bb7ab6c97f58e3ffe6aff144d3a37b7477d18bd35e4613b73b4ee15a3c639593c8530212ada53efe4b7d48dd93ab27def3976ffcd9d8aa70c878fcf44fcd8343488d7a0b86ff8dd3cc8ecdee4837eaf1526583603baafffe10d5ddae5145cebfb63fe1e8f968d81e9a652c42fb793883144b96518cd88f4237f9a067ad83bb3a5acecadbbbd2e225b33d590a3bc60ff331f856884594944a1055f1ac6bbd5f7bbe0c7b5363c984d408b493b92bca2a9395b7dd9a46c17b632976324206179bf05406e629f86875573d05b0599b561dc5ee8f54a73690b5c3b414fcb7aade872a9489a5530025b442c94052d5e892cb47b7c7585547a72a9e3a3cda629aef1876c96c479063c49e94b952cf819af8b3bc39995d4563337bbcd419c17c4f5696a6002cbc6b760e344a7fc49c2d0c0ed52b54f16041e5c4ecf2426442b9d59ec05872190a80b4f341312f91b7737cc77696acc5e0323e02100563519ad3002fb95b0591aa126a70ecb708143c7a502c53a77a82ae915b25be77c68006f4ccb0252463dd668537c24bf4b0039cac4a4e6b3c19ad37301b595c504909d8a4b8af71c0fc2c905e26b5317703b3195712070b0d5677bd5101c4baf9186582a8b70d163ab01c6151177b7c83b6cca2bbf62f6abef41c6ad6764cd8392819a85cad945ebd210b9c08f1333a393b144a4782e683ca2c73c5875f20debe3ab59c8393f7caf4328a57618197450097d250e9a77266d15cbd7b3867dc49c0e83c7717513bda8235e8b89fde06cef1413ee0a0e42c814b4da9d0b0c5961f73e90c57c1dc614de43c396118979cba7144316607bb82e5451e9475c0cc4127c58a69fc47e6f02a3fbaa03949a9760573b2bd3c6606325c56a23cf4aadd8024bf9d1020332cba28c7fee610d45674e17281e047822138b04df69ce9e11aa644c47fffc688ba4b6c91b01e2747d2765b7d9579485a37e7090aeae19ae2773cb4cc17b998c9d25955a33a0a9c47117fba45f02611f1fb59d415a93aee26a2e4726e50c457c692766d55477546785f76a2ab7c5ab983a90771834da4016a755a2040ee3f6a24145cd2f827729bc74b17bc92032548b663f50b307ac511c47e24e4ac4957e552c4662915074373d83b34f468bd66091b984692dd32669332b0527b0a0bb3df41556aee9693eaacf97047516b6aa455311cf97135b697e7e9a2e147756e8fb0b657b41a6352fe6a17f4b031efe17926b7757fa74831257ce2442066c624bdb106d3330b99d730e7eac1d1528348156352e266475204c6e13b5dc06b2596097c1da6bb2d31e139c34f732a70bc09afd6a8e9700bb20fc78e3fb15eba8b2eca7bda0508b1d8c0c9393557e62836117219fc2201c79346949c53d8414c7e673106234e98cc1508c81317450670ca7de957bfeaab0e6780fbd755eeb08a441f983e3c81468a7bfcbb152bf6a581a901564f2cc6ac13423c32dad054e02e6509725bf13605f646922bcf84fcb4b456c7ca25457415c7275ba54ae8c4717157a299fa18b49fa6be7460f8427516649440d4c0dd42814b8c4692d71b7b6c0049473472e002a53392d183b4ab70b6582557f8ed067eebc00b670b517433466ec6b2f967ec1720b8c68c41d2923fae5c4285c63b03a8416926b93496dd57b6e241b14f2576e7b9a28076b2dcb8c2f475152a5fa7ec98c952a263cfc221282d57bf329a0dad122046a75399507574289a18226afa90ce4d7235ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fc817899375f890470238004cc7520be51feb8291cb8bc336813dd14a7bb24b2b8b8b425a969c4e410ac4876787f67ecb61409885518e0533884c613f70a22997b0b8cb1e2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db8614024778225b92d5826e1bcca780400e79b42e0fa3baacc5825bfc0f45cbc485d69c024ca504a975ada9a5a822cc0c11cb3fbabc64d07db6133a7e91223c3658725686ceab91eb74060bd039cf1488376660225b42db441ddbd437d5193bfe777b35513ac8d85e6da433faec55fe969fd3865eb9045589b09769a41c963596ce70238cf7b407b096ea546fd5f141ddd54ec001b76cf634871240d9f82f77f5153e84a6a5c41a3cd908e962c5b8898ebd4287fb2c97a0710b448c4ec93cc5ef1719c91b92ae77b35cf2628396160f0bc3263003e2e89243f073726a657b2386173115b778cfc842c67a4b71d5276a934aa94d92b452286a35913b0262af2a4007642a0b04f76ce58a31bc776d6f1b8966180e2ef026763a87519a10b8049d799a8a3d038d5be31eccd5676550482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc1b4fdc4929c2c7e4501ba7a9feb0be571e27c43fa96f9a7f934636ed9a86110bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 463d031123a2c978da1db90cce3787e657d434302d270680b17d83fc6a1d20f1ccd4187b401d849074362291c6428345717be577b5c466eb9de098fba1a8ec2983c82782d40c59d5aa38fe1c32c7d65f46733337dff0b10733925b6adb40f63e015b7d7648889dd504a5199814deecfb8f27c1d7adae37835a7e18717d1f0d990250e128e6de30796f0f5a70ffa5860ecc7dbce1456928af33cca30c8c6e66ff88d0f9fe07fdef98ac16875f05bcbfba2357744e405fc991cf4f79dd6a1e7ac820acbafcd3b6b08a0dbe6e6b25d462f4fed17fa26d682d456fe45bfb9bde018b207ade36fcdccfa00964a50d2933f5086fa51f8fd1d22880cc0e17b3050f69168c123e9622993213904a599fba68bebc1921bde537e30d179636fcc951a28b8e6ddac3876fd6b6b2be3cc6f63719899e2b0c0c241e9ac94853ad7a8378e12070f63a4a1d0f122043bdfeb1e98216cb31f26f6525cbb9fe2b2ff536c8bf5f6768f273cf507f5806605d086fd383f3eca5e20b0daa69d1c048ac30ac3d5327f166ef453d2f2ad3533d6ab83482a32a34fd2795131702e94358cdec743d702c64f40c1606a43c4a95c80d8a60636dd2be5ef48f2e58c8ea1d173ab2e64107703d827604fd276feaa32455d97301698abd9773438c8e1a22da3199a6699df6788b97e09a2ff174e78f6cb939c82a667fa28d647fab7c3177e21f1a25bb45f33a94f370ed15098ec34beab6e551b848773a2c01e5f47d32c997ddf41b7158fa768664f63294f1815dcafe8adc38c2835862c95b66bcc0397a79b950e48ad39df432458660e21120804d88ac56511a02e458d4ad0c9e280b58fbc595a651a27ba978535f740d5e3bea8249fa6325808472ed85fb5919784a826a402db695c24c8656a5b3e57f7f71cfe96fe42226edd6351e94df63022c466370c005846604e5d1d2e65d55cb3aa22bfe9c52fcb7cb8ec03190ac558be4f5c0c93dc3fea8348d211587cfa21d6592523c62f345327f881b911531ef970912608b86a56a7cdb6c7f2341f77c9e7dd83e83f554b68147fcb69ba149f37aa9ee5a13f9f4faa8205f16c74ed1ab56d94f7e7b8cbd287d5c0ab805e35ff9770b1dc6f8fb4a3b99ff24895af6d6aa664f5c52112481400046b3d76c0de2e7a59e46ead9cb6f36a4511a98e9bb85198503e4c9a6c154362bcbe153153d206988bc1d93610889d8c9a66f762bcc2e12755716ae22efd15933e11666da92ba74efcc1ecb234f265b895770c2d81c891a8baeaa573b433ca1472b1a99a186255d71576c2a11dcf82aad1bdbdbe76b685555de1e0c16f4f8f920085a08989462fdb055c66204d94f4c09cc10a9c98b367af509cff5c9bc175ca47213fb121b833114c9ff45ff85f3e9322c8a30feeb24ea684b744fc941e5eca51604632e31cda5ec04366d0df787aa8f8be1451bf783ab0bf582d0c04b05beb11e970a93c798fe8db58bfa28bc5659dffd605dd05155132f95b21ba865002b101a4143bc372a1c008ffb04bd06f38cdf9bf07eb3c1b0c45cc4f09b0db38b44f342b9adca8f2282c8c71a4ff8dbd47e6ace1444fa17e35fe3dabcaa9c2c3b9768b167fd0f0268bf14007e3cc06cb37dc422f9c0f3f5fbbfc55674bfb61413cd59a382f2a8195f4795031f0852ac2236851570c0254dfc90a8244fa25bd9ed40efaa27997dd9860e61a222268efd31aa09767a73d03f056b92207625c0962f9f8b2c58c1b6a9333f031f0e52a16971b6b016083b752d75af96b12b1eb4a31dc2e58fc60811616422ae613195beec540dfb85fa62c4c0a81203b2335fe4ef0054e18dc516d9ba15961d1b62474bb1c7322aa34ac9c24f79d62ab4b2590557db827e1066ec14c57a3a8ce650e1288f3d58461b29eab4748e6319b128d3059f3bef0978d74e7e4f5f666007731b16579ed28eb50e0b0c189f5e0e2347750378ca5fe08b04843c9d74de307b67e7862936e351afb4b8913f64f4226479ab763b8b1991945f4a87b7d7fe302000a365531655c8ef5719b4a97934e3ab8d9f55b459ee1c1914b31c4dd26e7c553bd62829cd2f1f678025514100a328f24947ab0b66020d10800678cf9f5944a7bf5496f3deeebb663377f140cb64f3057be389524934efaf66d81bd415f053d51221fda178857f1cba2b1c21cedfd18f30aac3cf48a721716747579c31e6d6c45a2e69c8427b05121cb3b190 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc865f1d549b979bd54a9b8949f5e9e3fc3a6546d7d794491351d39723d37d31c9824eace39f7e27a97440354ee25c7e4fafba4ba8d41e86bffd8d8acc2a69aea9c809313d6b46baf5245a505d48e293a77ab4e74d2cd95b0b4a45754a4a94bcb01d4543bf7c7dfffae2009408725c58bc76bde03abef3c4ee093ed3c7bf6336d9707b3b862fd93e857902e5fa2a496e9b1fcf0dde7a9245eff7adff38a7de473076965959b2aa3c79de3eb98ca984783ec8abd929e05e84cc6b92a7fce2c07c8139a62ca1ef16245cfc93bfda168d79e1c93c9ed8ff438a02ddca4ca948f48bed6d40ab6a6bdafb06fd52f237e45fd765b34362724f13096e1845785e257cae79ec39fb8c80bccec5fd687a547b7e8e3aa1d8ce5a918984b6b359ddf4711cbbbb967e6ea54a8d46eec5dc983fa2bd19e1bdd7df9dc3c0a9e775fc18f7fcad6f9c510e64f0cda8cbd86502a5880ee1536eede6ab36bcfd859ce879b3f5d7add9073d668b7385c8599edbe849a4942d87a914a8ef9e196309156c9ab245f4c637080c963f9648fb2ba6f33df566f88bce79df03dfb827448f95f8670c9bcc34a9849795ebdb0e631ea06accc26373809986db6ffa724d12d2579d5e6e44343de3b98fc800b6c9e0fc98e9859a51ffdb5ad9510fc91a3b95bcbf73b3a09311dde3e52c6e734fdfdbc5dde8a54a30668311bddffae2b55fe05c95ac43875e9ff3c2acb3d4a6b53d363d5d75a6a7d61055a3a788bcdfa15eedf97c3515ca920ebac9e7a998bb598b8436bdb63550f4e6d2aea505766fa901b609c1f9d93bf7537fdfc26ec6a3b2c5f6b733d0529330e9a89601bd89de3da0bc5f530b3d62be741b0a8e8a78b4fbaff74b736fca23b3f2b4d542caa64fe38a6ed06beb5498733a38a80ddb5afcf673adafb08fdd909e68d40baf080be79cf7a60aaee3719635a15dbf21d1cc88cafee950c94cfee7d6008dda5b4a65605d2d7136d1255f07479a1db4fc26c48664297562a0bae0e89d6e9d853fc7c490f4d78b5b3b226b37101b3eb5d05a26f1ca1f33ea854ff3f59d86a40df69a0256eecedfcc0c6b77f2bec624ee4e1084d8d1cbabd0c7702f43d2ffdedb985382c66ff1b7885a80e5edf59bd8988b5bcfaecb04639bbf5b119f6f9409d8245455070da3014dfb6e31e6776694b44e3a7e433407099a51a4d870b336f547677665c7067ee81ce266ff0f5d8268731bd13afa2ecb4556f76a5dc50772a6fa38541af968ae5c59e2d04c3b71dfc722da6aa7dada277e5915ee552e48e7119c7b7f7ac984f9e9b7cc0b534fdf277cc10e7c48986f66643a9b33d8cf179932488d743f95e6595ec03599feb8ef9d565fb86ac35afeedb601dd58a8742c02a3e4f6cbf5d06ed66143ebe933060c98a4bb553185661857debb395625fc86e4bd47377b54459b45e51ce45596b9178d57d01bbbaa9a63bf444889fd8e0f1f4de08df89e1bd4a58f84348463b9fca3176aaae6c2ce19cf679bacc6eb685b9f443c2a9f3d4bcadadf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c170f9e18d8493b5f4fc2b4e739af5e735c665e79ac423aca37c5f22da7d30e79410736fa30e76c2d8ef5985f7d92437800967c4daf407e8f6ec6ddc1bfba5c96c8f1474fda7f7464020d314b1b448dc7fae1a57efc9490354f5da38c4fb14ed7a07cf6e81773edfbc3eb265460d345385d81bac591b3cc847a954ae1494f2529dc84464141fc95c94dc1b19aa0d81dd7400e381cffb9c24f49fb77e9670460e15e5d945d7f5245b3dcb68e100dc5e2cff7e96d830838db4a54403b5a9df3d392ec46d8eeacbc09fedc84158c98afdea77d625f08658a17590c6575f429f3027b637f2a881c3592271b3e3dfab7aecea3596ca1c085e67847a4c586394ec7735ca932675e9c7ec49fc1ce964a47b00548d25f2df8003e4eded54d603f3cf5465c2fca52993352f70bc129aef8ee8dfa4a75f8ae83e5d8f4bde46eab6865c18256de1f4a6e49ab5ac82bd7c548d0c65762aa0594b3c7cfbe449dfe238a63f35463c94b2dbbb18f9b33e6548dd7398f0cf833f1243e73eef3918b355314e4afa37cf88aba630d3bd1f46b158b4a92cec5eb3c85205e3f8a86d424a65002d87d6806cbedb0c2c364c98989815ee9081d132427943a0adb0da7197cc7430757f3868c49c045d39c8c085665d13bed825fd7cac7fc6933adf438a4cb6849b91a1c737d394c5e08649d88e9274009c4375a4fad4b164851540e43ac603ab6f488628fd7272bc1981ba03121c3a22e587ef30a793ba097d160025ec1b629a348fb8b854b54139d5b6af09a7515ac4ba457c8289108c7c316c069a8e454a8d1084504c2a4e03c0a321681d168933e0062bfe1635de39ec8c9aa2a5a48983c1bc34798fc64114c18ae77f13408f753da60cb892c52f811c8382b3c455c4c0f08248bf7278b9b4b927580a3e50930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c22529ec61343537944ac07cc5a1ae713ca8fcba73daa688c9ca369e8b8d99fb812489482a727d40c7aaa6290f5032ab8fb5b09ae4985d7558b8c55b9f0accb3781b9b2405f11c05e99cb3723922d0da4963e68487631722c0cc643b3920b8c2ac34b54e77c1fc748c96c186b3a5439fa2b3b2e1a75b16357e2210da4b3fb620407c4cb78f18178f2b6c4706b619f18dc0863c72794434978d20933fc79193894041183660f0437a2e309eee87bf538a2b8c7672833820805bc2cbda61e8f04b7839b1493372759aaed528980e02726eba914491b7317099215135175c41986858fa31cfb689a865375e8547932899867b987167115031f5b4dd263f0341395e1176bff3a69fc9b9c020ac8515af5e665a15f48a3cba1c4a96390ad7795f7695e654279802c46275bab1e32fb7111619c55c8787cc01140f0fc03fcaf4b6df9877e0f24971f06749bb343e1a5faafb66a75b4888a1c63f593bbf3906c324083f737a39247ca110279a677736e77eefd3b08f645100e249461657da00b365a58beeb48de3f96b6797850119145975388ab4c9025215dd4b0a0ec066c8a7a593fc0a1ca921c3c54659d40fdfaaa4f63a6b0d55a761e9a57843617ad6963087396a0187bdf593d98009ba825d056bab8e3b6ad5eb31b3f195a2c9b7cf9281c176b58346cdc24c580f23131213a08c4cc1c776c146893e8cd44983bc01494793028225f2161f916b888c923c8c30c43c41c1a2d12f18a4918216771cb992ff1abdbb33aa5f363e6cc044a0d68e6b36785951566e4a666af6cf9d3222fa17566966c734a364ce14933da00305930b47dc1e977b88e328296461c302c35f3e432e5d01243685c176e1b6876b03e341ce0a1c52ef32966d67004cb4abad9cc8a534b728db8c32811f7e71556beb656d773759f04a71f43413805c1334385e396e8b128225929977f41cf776450460707e0c247980ac42c69cb641af3cb36724d5705af745965181312a91aa000b42b82670a9aea43ac26a5cb3ebfbbdafd4225535255609c3a7d04332e6c816fb68e5ac05daf42c95c78f6db76213a083b3237b4665b9ede88c1bf53b4473005d4627bee21cf225bd35eb728932543956ca142b4f3614816d891895b14f0d28ba36d298d6713809180621d1b12ebabcf032aac6691b22cb9013d8a8dfd70ba1281a77f237f9318b43d043f193cf9e1004cda26f532ababca3528c69200624b613fba988bccc73288b7996c2de008f22755ade918784f7ae2f69ace6e08e0cc528e3bcc85403967da02cf1463c77976555460bba2824af0923f2dc4336ab44d54ca0658417f8fb5755f397fca11e07759c5ba86accac1e30523349168ef3740f59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d38752c435cce3cb9b176086019113ad638cf3426970de0013624313ff57ac82b1feb24195028b1b65bbcbd5c4ef3a60116125b3580743cca16ca9abe8fdc1ec1ca2e4d717a0eaca0fbcabf74034b74391d8d9668198a14e5491ec817701733be7ab11635e4a1e6910f3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b675a1660b7c22dd1947bb24f1ebc8b22b1ad1b81600b545f74ca076e468513c0a483466089dc1cd7090c4c5623b02b7824d2ba1894c4e200222bf867911c89d3264b5a081d7441a2f3729cfe4106a780237e179839323f97c04979887c4c223f23a81af875a33cf28cbf75722ab92308c320d32625ec326734a532333c8b1ab4767bcb682850750620c402878103056cfab5417354bd395084f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14fdf4f164c11041dbe981d8ff2008757b7e694f564a298b92cd182129ade5e72bcfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = 316f5978cb537a9ccef934d373cd244ec8b40bf72cba7e9aab5339dd2848b9007ba227f0e42a302e364d9ee9e6761ca09cdf5a1bcbee86baa24bc97e1cdc69c5e061cfd73c5d3446edae20513a9ec8314efae2dea09bcc268cb601e581d7dbb33dde376b56143921b5318086f4757ec70b9d33fb17d87807a7b54e2a077c3edeaa48900194049ac60e34776b975c07478bea0e76861e5bc6dbdb2a316d266c6d40889ea61e8d2d50754d6c112929cee6e1a9d20eeaed6148db31f4267d7da4f1747f468f4210dcffdd367f84ad35234b8b6252d950b7cf74379a3062baff3d20ef5fbfa48c3a9845d7f5371129b64f6adb9db6a69e3a89846fb24370629c589dc8501d98e18daac7054bef4b0d485fd35de5fbfd63f1c160ec2af53d8eb073be350c79dadc148f2b9f52829245b97ab3c86697bb1f9bff723eb633f366a015797180347c7fc1791bba66f1e05decff7d61f3f3ea00078d804ac4fe84458551649cc9426fed3eb8dc0db5acf85be11732a9afda217d21855c988ae6355c6e91f9a617175cdf3b5170bd34360e14f5fb7d00daed753b98b26f835344ddfd1d4b0aa04fb01d9f9ab108bd308b4d7c4d0978a83683e474726bb59508817e268dcd101125acbdc7f059be0b079747f3d22fd4d5c16b634939fffc1d7ea050c0452207671c0572d9228ad933f35d3896ee86eebafadf4ee549d608e3fe895af052df25fd75365bf8641f8e3ef581d2a4e4dccf06d56a045f1dd6e166942a998cfe234871b2b536eec90f95b5a55f5fb00547f34dd872e38f71b35d2eb339d78e17bdfd3799ee7f93a72ec83bfb2d4d2bfbcf080475d720676b26c5c4b9b30c98515133f8b3b7eddb64bea2d52671fd6ebff4773c24deeb8c20e5d8f09f1de74e12fe4e152221dca1d45207234e07d1711eef6f32f0f36f4c24cb0d724101d07e3d5c6a416b321af7442a6cbd1ce330915f57daa07fd7097ed0f4e5d87b57e288be359df4780c949a034449e9a9929edaefd094df3021dcc7d93b4cdf50e7fe524148a92bba0f0630d59f49c8c7ae39092013d14d5b942b4367a58694eecd3c614db59e498aae3cf84e373d324e9e893bf626797336f20b037c601693a3a697bd272476c7cb97c7fe6435925908e4894f48b02cdf6039200b1000a8c088cbf6b82767ca21bf46646d416a6686fd81ba82dffa963db5fdb88f23ed1b5850ec4193049426baf442980fdf1a60394d51e2c84f9a6c8cc940242eb625044ec03eac9e7242f6dca673447b81240dd019f23d379e52cbd2482e90ad254dd8e6e9814ac58f5ae9b16a126528bc912f6259b01d9f01ba1708909bd7e0ebeae96f27c6049035547b84cdf06d36add6f7c95cbaeb020c213111eb2fc0cc9defa65be9450179d2d07eb8c1e77bec3022511e22906a694bc28ab8e517b72e0808ac3ebab7d348093cea98199c2706415a60574cb6fb93aee68a2e63db550413dceba0fa85136f8a10db18f824844baaa6240ba4235f41822683669901673e8bc56d2b35a8435c64925a0281c1bd18c2d9c093430855f24f4a1b841588dacd5c061350622e536bbd7446de9df4be0944d3d29e9962614575adca136ce7c93e32d4f32e531d84757301c1a327d3641ee62bb79ee8f192577b11812be02a69e4f5d9f7c6d9ae5c536800d60bc5a6713c62ba25ff1ed00a7888f4e2186ea8d56b63ad057b112a9c325920192dff790f6114dea911e535de9e2dad805e4240135ca0199b96ea56584d76f4ad9d241b811baf547457161523840e7666601d39793339e4534b79ce8d0c66063220293faecc9925e38e6c9c29f47852d0f7193f00b07481dd2aacd0d0e7999eb6f7ae1e09578eea1370514132c2eb609a4f1a88a5800406d0fa5e8a125d1644af66715a8f5c078536908c1f6603a6d8b0d966f0d7ed73bf0ef507a385cd4c163d415d2c461ae0a2029f409dfd527348eed54c1a048adb3890693b427b6c6e037c1db7a2a44ff566da90a0633893b5e671bc63ac5e1c4f6888eb7199ce93e4a4c9d317f5d0b0ad678ef87695f4d545e995d384701673f1dc6c5451ec468ac0c9c18054c6835a54485bae1f252ba4d8e29b5e20b53f109d6e792637ad38c9e6093c4b34d20a9d23b82cfe978b49a5aacce3150649fb14ab9519f745a5d649a4b05e3f63a3103d1c655e2143b37cf17500815808e06e70f2f798a517f95ccc0cf60d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 469963001d4d93da7cbabcdacdfc833c47601ae334ddddd22baff0139ce6b9eca73bde86353ea34f593addca4f0ea393fc4595d22a7caedda8d8a8f7086a95550dabad94f2665ee14cfcb3e4af40fc7dddd7cd960a7976175c56b0b48c678fee1398fe3aa5784f1f869f0c8518037955f876997975d27a7c92d4cf005ab85969d504c768b02576aa4f63c87c4bc0eeafb09b8c0a6cd67776a0d96a5d139f5b44ab3d3e57c6972bda876e7f66ae6c7e9b42c283577219409e1ca4de08a92dc5b4e8e8705178dc1b34d68dda801fe871e1bf8ab17eebbb97cd49bcbf159b778593dbc9e3d2c0b6ead148f77a0cf474aa64e983506ceee288f4a20376b50beec1234aead03daf1da67301a5a420aa826db58322ecec7ad8bfd25c3b220f5b565c357b5ad802f6e5a35a384f1794a17efe041ff8a865a03a0e97e8cf7f45b4f590ef6082c850170cae878febb5c68cb42e53b9934de4dbe1528c570af363925ab0fedac79748b3489b7180f8eff6db702d6ae00336955fddffd2b9c86c2cc001833b0caeb7dbc9699c6556b448324d29b0f6b4d28bf48a4abecf60b4a9f923f1aa64ca849848cfefbe0a39f19f7830094e7da307710f87cafa36d3fe2d6e56a8e77f8e470af4c608b6e28908541183a5b4769e74166349e55b4d3afa857ddef81fc2d2fe3f4fb3c91bca8cae2d9cb5cadff578bd6e29a0cf07a973df62a2ea3c4dd44a5d55446c174b345b96881d76fcf785cca68545eb6be64bc9be17a7d69e4d8b5db286d3a2a9eea53faa53815acf0237b8c02d4c34766e97883071e5653946ebbeff9188ce80414c83dacd9e30983995aa4850a6b2358aa6240642cbabdfdb739fa5a93ec61ce1061aa8b5f7e316b5e7be2baea2f74baef3feebada75e2d30f5e8bbe1c5e7f575e1fd8aa49a7fea9ef6c88b96a9f34bfb3dfd4381b5c97b743063b6f8685ead9fee4903c4674c3d8dd6ef8bc81de34c43c789bd4460db78a0e795e246985547f2b4c3a095784828a6d672cbcafd1eaf32d9e8aded580d5bceaa574409854052af419f148809147133866f9b75ea397fff22ed61502de39ba5372493eff42fe57156e69faf9294dfa3f135dab9cc877d448ecb63e39e6c5487ecf931d45b4a74c34bcae1cbb965e1e664ecfca54db7bfe7f6edb248fe50076a70a9aa028670a364d13c894b729945831be125aa53f4d352bff33fdbe7c64b07db4c3acff378d9760bf7368693d938e22ed5707b453a1de7e4fa9c5a8e6534d45b53a2ba464f2e7dc056ebe31c57647e5bb66b6f3a5cde7a3a4cc107602cc3b67487a7d26f422468b5cf33c8e5a63f802cf017be5c40398f914cbcdac9664b86d1680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86409afffdc9650df7577e5a89215c8636d5c376f4596c339e58974d8430dc91af4a76aade8c7de39f63ef04bd5f1110aa2232d3774db88ac0ac94cb97720b7e411eabee1bf863c35607b6e7e771f98825acd91c73685198be96b84a98ac72a5e42f7ce9bac0d82c53a8a50a3a39efcfa34e859d0afc88c9cbc78bebdb537798106ed1fc394d718f0336baf229fdd45cd956e09a5ef7786b94f7a10cadaed54573cb5f45bfa751ef891e117fab20a4f74795a3f296bc5e9587f37fa9ffc71a87833805e49e7ac47a26532b2cafcd848ad5e7a621ef3b0ac57dad0e64490f6463c0a6d092cea1156771999697e576eb1155789555392da8d0f0cc364378275affb4e1ea3013ac273ebfe0606ccaf05f148e3d821093d5cfbd417a4347e6be78eb5b59d37c54cc9e1ac08cd556eb1a61567f4448288e78a3ee7dc3af85c6bdb72d4bb6819ccec5946bfffed974f9ec56b47bdd7647990948834d463362ce919a977dc84506a1ce3ec7a9da51dcdf51a9fb67b867dfba51f0f9e6e99a35b0d64a5f640a36b3e41c45d5878d4d9b5a8306674c037a5884f7af626df7568518eebe0e4d83e6ffaf1b24bf0a1cc92d67cd43b63f8dbc9805d7c7d948d66ac238c356ea21636f4b75bafccf47f58065eef48f07e2f895f4fea0adbb16e3dd1657a9f622849a10d8ea88988359b508ccb764d265767dfb1e1f55fed5efafd07a2cabff729b8ce84ea770cf4612d369653ab92698c6358769d2e5317c2017a6ce707b079cb56a06e388b924e96254d26c853733b50520224bc51798578c4c53bc92552e8a42a07136992213a6763056a025106255f57e4670a6a4262445aa745a916a9b629ea64ac757186d136fe301c6226992129b493d0c2d635b5187cc2359cbbf235a90eb24f7feb5137e4157ee0822b0cc1761c18c25b18f757392863c24a13ce6dc84e3c28aafe018acc1b338a27746acb22f687af1e693df043625c63805ad42b9a368f13f19014b456c78236fff57c7de2b96e7a2223d00d9eb8973ab04c67f3b03e8cc1cecc7912033999101b37ec643605c0d70c1161a6cebc512380851f6a834de7631bbf47adea0bc17a6478f122c8be309804d2995541558d688b9e080c22bb3494f43c1b1a0c874bb4d5246688a2be22159a56151ac2e6385b1384d0c635ecc94b80bb8276f435a64883ecf51c43f066d481cdb5a21485380ca2874a38b39a691c12d983cdfee9530212439d154df71106e2854222454c20736f6daa41e9c949941205d84a7b5730b95cd3251c186dd97b1d4ec329521bbdb3394c819a984f87a7b3992d1d578b5e57ccc3ca151992395cc6695ecca7ab67806f2c2c0ef46a6bc02c2bfa17a8ec41caf87f48a146f2345b7a185baa1379880b00d0044f90e2a148186cbf474bab0330b8f029c72802f1b1698ab158e5c81343d34cb10255dbd1b9b6265d4c4a3b1905a650c29acf22ab6929a0d95357bc76983a201727b1a0f7c8464de2bc0da3a48a81b338a1855a759f764639d9e7306341a96b9aa52994bdad71ca3eba0cd695a701a0ca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d282b73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1ca0454a33bdee7aa80a2ac17fc709167843167208837594eb8a47ae1a38ce819c4ba7dc4521df532c0a6eaa5ccfc37e1f76e6ed20a1715139d9a41e2fb46cd5c0b3bea25f60a120222aa06e15504e4188116ade33507a26b927d10bed839577d2641b9550e1e921932185467b8c2856a430ed28275daa37b166e025073fa513a0c852091555b0e19a2c8e858c1584e229c6bd2bab500ec032abb4b8028b90e3b24feaa3fe2f826efb574a786c3bcba9829e49ba6318b2b24cca031c636c863f224619df40949b08ffee535a25c7187a92fb522376cb30d4fdc7ea9368594cc53921c857f7a1d9e9528a9cb817e423d25f791b4cb1e95e7b3e6dc406c83c9140385173073f7ac23d69c6aafaa6cf82862fe05a409521174328539b6a907f34d553aa77980c9f4959c329c563d8c03920b98563c5f13a0231eec58876210a5a78f1b43c1fb8b4490d18c16687065939535363ab88397e51760ac356c69f7b25458183a10a0310363f31c5c16f1898d06701824565a615ffc232f33513fae22b6bafa22177b142ff88190a207b4eb5edd4bab67185ab0c9b8acac2b37ac2108ab09f96461a3f079c3c018c6c058d2809f1346889e17cc488cb645c698ad3730084415647728c2116e013767b37bb513000feb359b84105bef19cc7dda7abcecafcbba381bb0727c8554bbac2d42c18bef471fce337e2fb99d69a9a54fb14a1bc6856dd56a020317c4a57e315cbbc371cd673a0b0919209f2361990068f0570b530b0678e01032ac6f95c2021651a1159b0b221545134c500d857c7ba0aab92cab5b5298c1b7b8ad588d0d53860f0563ad9c309a12a82b14486a10b79d7b6d38bbb03d9bb49db4c90610bcde5c383c418088f51eda6a99e386af8e1802d84b6d7f236104c2526d577adeaa8dd1c468d812cbdce44b04d64ad2938fc6495fc0a84e62e506ea548a8f5930c032b59e54aa54598f9653a118c5c83dd07f1b73061c02195436b6a66301bdc21953eba0e0e351e01605d9919956968601549abd9ccc9d284b3943c666cb8bf8c2112f52a5c733691fc2003c5b6eb8589d9594b8c92c4c4c6abc2e5b2bb67078f81849e5b6760cb1391b9c5a57f8705ea61f2cc475f1f3a45a2a0b12bb976b2874cbfb4f7266b6e1e20e6c2c490bab8daa779f0109be1a662c985016c483a71e636156186471a9ae452bb973ec28bc135133e9744cec8b330c0752451c6944b7a304a250595d86b394c6762d104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4ced722667caf175df48a3a346ec7cb1bcc37d67d3137ff7b7c70a07f202893a3320a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = d19c2f2cae13eb960f72953444d3c7b1400caf6ebc1f85f017b9e3ea75db21b9ab3b3fea55d9dab5931d5aa0f8ca4059cc5b34a84f735f8002dfc802bddf8d1ba392cd6f26d28ededdd92664d844a2cef31c7f2f5e212bd83d77b6e82c4792dc7270d41cca4a85a2cc649bec1e68b6c7dc4e4cdab1b3ebdbcdf5faf833f644df51d0475216e779589deb3bfba63601ee3474fee332ba1e2558f6fef6ec429cc3dd24b8ceb379d6451b7cfeb2e95d256522ac6521e79ca0a46070c5953d7a023f8e37342681536683535b7602ee52a7c0f510537fb807478d9c2ffa301fe7ccdfe2004a7e9d71edec7cbc630716d4c7013569b2d24e836c7018b1c8501ca3e9e2ac04022dd196d2d186e6167a227d528fab261b7a7f7abcc4346114cf13be6623724d92338675c3502434c1efd2c0d9fa11276a9d189f3e8c0778a9794c587488d0d20527e7c4045b1f49e0d59716c99e567de1a64ca26776d6fa783648c2863ad0e44274a96aed5a740b62684ad5095f33037b3b38932f37ac74d3bcde134a16a13a1b02c655cc91492ae9dfc3c4246d892e2a6dc8fee0edea910185e11d79e723be15b3334ace0d63db94e9d950163861ffccf4aac4993e0ae569d92163597e334ef1ea3884613f88e1722099ac84186e8d9e436160d6a7030f88f9634a2c20798c4a6af86d252f9e7f2c85dbf5f041feb022935cc987d9e065b726ce3bb4cf9ce8faed27181d430569729854a34e798274f558236c8f6f99e5dba5cb97b3ac10b74738ce2b91c62770a7aeadaa9e6c0e15c5e41a1151e774509f026013c7d6bb21ea0710a6b3beab18dd44ad6893c6dad807093632cd6d6bededed816fd8c7555c41976588198191c808996e1450561f330283752eebd51100b4e74e3c7d151e134645f6d1fdbe52a01d5d61fb0ae7ca1fcceb72c87534ecbebe172423f4293e9a6a98ea79182895f8b8e98cc111685b18cd99cb4211feb54a96a8a834aa583b24f371b4f8b5517add7d24945f54c1465b5121f7f6960fb210bf4561c8f3b662f2e0d511e27e62dc546c16ee91a8dc7003482c721b0a9dab43bac4a28b5ed285f32552ceb0611401d8b0ee444b0b2896b1766f8a26eae7d9d68aebca3e8004ff9e4fce24962abfd3d9e37fdccdb0f3e848b7759987efbd40d8657fa6736bf7fd831d975d527ef66ee7a6b8da173d5256923fdf22da29cbcfa321d6f52a17f9a1edc6ea7258af7a580e553888ef10f9803ffd32fec3d5089762ce75e2ba2bb14eeba9027f4a47f5caf1baf3e94b23ee6755cc4cf80bb2f4013dc4f71f0a493717288d8ed173d91742f4817be4c4e0c73e9d2a68b809d959f0fa491fe67dfbe345a4640e05fac0dfbeae1f885bce354b99b82897379f22e41a82b3f54244b489bb7341fb3524c6500a6ba916e6582f0e0b7ca715114bea90f0d4aa5e14f1f545e4347dd467ee5ad718d57dcdc0d2427e26e2890070493730dc1ae3711061e56c2fd7fdc7389d65c75378e902bfc8fd9599edced15bbe6d9895ef676f6e09fa935e3479af8c8e05e322199436a1ef8eb8ab51497bc7556db97de8fcdbf1517ebb87bdf6c694ffa93e25d1d30e113fe8e1a1f9cc6e395deaff5d043848fcd8990ef54134a30654c9b28b38b863ee6cb238d4ca8c9cc5a0af2ae9586b88fa99055a46c11185780a95ce967eb0f9f1bac11ca753a3762b248f8aa4ce55e47ff54d70e26f8fdc99ab055e3398394e89ee1c3df549838c64de1cfb93708453b0bc82312b7e3e07f386357fd92625929728a188d5bfe19d45b1878c1a61bbdd48cabd9010c3025fcb217af29a56a442b46be34760655d8748aac19959427c2df6fffa1af7229abed19307c99f0824303b75e34eeb011b10fa21dcc4022c8bdc75aaa41d3b4f4a79dedd5e0d8ad330e46ee3177fb2bf0481a7a61315e0395fbcb5a5d77e0e21748ed6f77bf845178a52aca547a5c3d6e24628819c27c023222bb47e6a1b0d53e06d020823706a4c89602d81d3161e9d14b33184324a684f0f6fafec91031300ebd8c8cf51b953374dddd064101f3c0922ba1e711afe1418c0bb7967ec7b5601396d88d134f5503073684ab44a02069d9684d70c62b0a235a141daaab741c1e5b8fe70e3c15fc71cf74d019d9fd0bfc38443bbdd75424f7308c75e1f2857716b3a6faa62fa940808c590bdf241c13b3a639bcd2971d34949cd95ecf21a54 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3c14bdd913cda1ff67abaa8b0b3da5eab5f7639cd19276f3b0ccfba56bdb596a92bae7fe92845828f8d50f5cff40873918e4524cea85062d8d345783f82fd24977f1e46ea582c5445fb3efb76fa64a4eabf90cf13ab4a741d9f14c1b80b4ca617c4976c819794f53cacdb3509978a6df69d0026f78398f34cc2ad9b804679f36718255b2dc6da7eee5bc3bc78bceea8060354b5413ec4c76b30a1a8b1ebb697ff8606cf4d8fbb7fdbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895cfdeed6cf3a0e2f707d89467a5b9c662767a0d77d5c49adca983ce85def355f6dab1cb9fe744bde8c54c33d705548b9ee0db9f4fad55466cde88de9325cda7c9ba404b641a663dae64a964ea47e6f8daaa475fc9a8b66072ed3f385479f5da780249a909c92b89e3329a478890e62d8857d58fa39d3283f5a2a7f8ff6abffe2463dc4d729dd61676f7e9daff83fa57a2e56e90ab869b7dfefbeac86921f84154bf59cdfa44217dd1cc581fdd333e5a9df84ac67f47491e01ee28f0959aead891c236e0aca87765f89c0e6c8fb136974c97dbb1b8871a4c70bbdd1fca5df0cbb3ace4ac4509dd252f5bd760ceec09a3d2f8860385a4bf8d765b49c537924de0a38d1dac947c248d3ab6b467f2bb1b019b9d537714193e2f52bf8db18be216794a0467d79ac8abbffc90f5beb3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935de4f9bf93e9bc0b8199cca9d3f78c483b8e087e622ea764fb7edee14cea188c56d0b5c17094c1b7a45321bb69d99a666a7963269aed0a0491b8b5cb700a7d86ab903943dedd8bb17dfeac79355a82166459df323e17dac109c98e3de3590ffcf9a3b513b8bba449d5d1a790a8bea11f78f583ab4fe0b8ff3f3e6b7d7dafde8f3c8fb7acfd43db22f378e8597ca5357454b7e197cb4039e9a81d7995d14587b479657584407b38e886d6a7fe9b6171ad56d30d3bf8a8d27c275b7c1c3d1d1ce57145ba53df64699b969e6daa3873a9616d41c21be7ca0d55b90e6ea703539638cff8bada219542c05eb68dfe53a96e49882cd87d898ef9c3a089cc70a865611723eaa4ff33c73cbf44adf2d224422a2d501c17f4353faeb925c4033e85d3f897a79a983d857c6d24f2facff2350d5e0098ff77c7704cc74adea4c8f3a7ee7964ba1a63dc208ffef696828c46946f0b329e9d9a47b8335343d630359eb8e9b7e78abc50fca8c3aa9af967c89f464430d8e5d1959a22bff6a966a64353d1fb7dda4e1f98878f6803ec49a54a34ace6fb50e33fd88f93767e81652e341cd76a367dc17ac9c338e4ac4d6ed7775db98ae445d236904da694f755c1a6bf88275b517b4c9b896c49bcce8933f5fd34969b6ad8add604b526488c6397842a54b6657b93387bded7d36fd2f448efe43b0a144c3307fadf63dc8b6340ce6e897b3c50b0d8ba822f8604f7a4bdeef0cd2a7bbba3b4828e77c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d9358a1fe252de4c9213f8c4063c2af3c8c52ff83565f7ad04e138eeac6aa69a427a55354ca9d65df5307ce6fa3e54776b4a7af9c9f02f98dba9b669d4dbd17deabe5ed357b894061ebeb6c96544eef1535437d8eb5fa6a641496dac4e849f5fdbd9104a68ba7987f52bc859dc902555d333bf8f3959ca79fe8cba09c3c56ffd365c93cd4756b88da9ab87a040c8f02c2cb7ac3c880796775feb4ee8f5f28ef4c62bc93e5d0682278ded244348f3665941f59415d6f75e1656fe68487f45d0739762d13ba5d3fcf7c5f77b7703a1b2e645b05782e6bfe952584a333f82df23c8a9695c0b537ac9d6bb4e89d7ea4bc2cdd684ad647ce10b326585a0f7e486a4cce5418454ce4baf62c8e132ddd08d54cf9a6abd95ffe2c0193c724a54f9defb4ef6b6ddebcf678ac0fd84cbca27f84b3f6b7eebd71facfa3df66335ef9d588b94d68447436eb3f8fc6bfc7a9328b7b91c0fd33f088337b331b1ce43cb86549264bedf5ec9bed644796b53d4ff30328be4c7d699332457e90a5d41ad5330a4d3b263a59d7cc6e56b3e8769f735d95e3ab8e9c51e82ddacd97269ffcb2caa046883e59ebfb4c34c87b995f143ba5f7c51dcc45c5dba61993fe02e0d5eda5ac7d5cdfb05b8c53f1c79df7a92a9d4cae4783db3d78351b11b00e292ab5425ab7110a6847a7fba29c24241999ac07fa77b461841c12519e9388635513837dca2a51434bb03bc43e89e9b73362cfc5f05007428c6c96271674a574f64d51cb5793454590fe9d42728c5c51858b2c5554b143acce2e1a9a4238cc9b88b12670e884b743168c967574f1ed1b700c50ce9f84d32ab1cd1e85a3a31a324770ec851a2de70805497a27148cb66249f8ba7796c02cfd462823dc9020f997114ea758511b5daa832fb6b4d05e10fd9f53d0837a5eddc05add9aaf668b87af55516b63a82bc64146b21290763f46b00a6ec3cfd71c702a28719fcce1f1a2b7d124a4ec8703d63865964036a27274c806ea1ab9067e5bb6d1766faf4b58ed05cca5c6688a86a5f9216ca7187423cb9d453825404448cb7290a5bae8848c41ba4cad130894cb385f68916d3a5ab6eb045522ba80c1154671617afa25e15734c5e5051f1e3173562899873ba90d670d644ae4192351b108f8511c89dc2c1633516b0a850a0345d46465bd058999ed227c8cb8f02625f4f0570a72a77fb1171aa577eb0239bcc2cbd00c82ed1baa91992ae4283be56094be2bb4c9f0623fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf30b0900716416a152be54946aebbd7ab8cc2cf535321a57cda44cd34060f86ca496830a16652a88d069802c59f902cf08d91afca82bb5b3aae6b4af650a3d7f5a0cebc8ce63a2a7c7e07c5a0cc9b18ab56698087dc65b2a014b8e00af240397d8c00c7454380df1497293327b81cec6e43154e97b93d9695d21c807f621576835e5b79f42d777230c8dffd72cf41a05fbe51765280bc6d3928c1166a6838e33a40b81826be34685203c7041599c14a84d3df2a044540957141545b465f03579167cadd8a93d83a03f7911406bf613562bb6a9863e80d886709978cdb75037b36a60f073ffba561fd87f6fac17d04b3233f797e091221114c78e794b9a9073bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372767060ec6951809848ef7cffae9aadea314d57780599cc3e55a8b0b04810e5b3a2cd9cae6d729e4d994c4d296f2b07dfc97596f8aa4636c70863ca52020b1c21c074838a4ac0360f88154c8e8ad820c3778275b966a3568b36b3f44a50a019a8d588849cb39dd813d5ca8905460bcebf94efad35a3a2ca588eb4fdf999e778b24c41259f198c20b219aa6c1715090000f4407a7217ff5645f8483a408facfe24b368d9042eca9bc803b9d0712b21ee36047016e5559b5d9bb6e046a63ba32a9537380ea73a22b662ee892a62af4b2710a2920a36f1740bb55b36700426287329e4f3b63acc77d6f6a94411a2612316da5b612882605a930a000c18dfb6331f9005427d63bd5c66bb0b4c496b6071cfcc8df3c4b350bb252d920b9ab3f73392b3a6682eb222c0fb065977b93c8d133fc07249f6a0a47d19fd8702f6c618d2c170dba4c65317c1d0bb188a09c9c4e97212ff004d9477fc36c1a25f3c725a7982146c4f3d20b0b07356fc8bd18289f860bb8834078d7d4813da9bcc2d3746f0b9387600088f277f9f747a9862be9a851cae219257b190c91c17c910dd8315a107967fc619c20093ddd6532b6a096838b1be3263f314c42a8f4b8b71586dfa279550ca54d87a1bd46b8d9c75861080294e9a084f3970d217610299aa8fc5814611a40bc01d8d60ab7878ec5c0460b916dcc183f826888d0a03a89dc3e27569b2a7a461ad847af7286af11a7c7a07ed8c3aa76b209d98c7aa72a5c3049be14f723c2062fca960c28925e6521534f855f3fec4054f3224851137ad18c4ef959e47c8134c86356f09b82606a69116b5d572a7c40a6a300b689721d37e80148821aa74902c0c30331664a65976c29e80034c00447245fef8a3a3dac44824b210a3b04f3b7af5a824632fcc5ebb45948ec3cb971607ee94ffca362ca60cd6e895c9aa0ce699570bcc4cab9832638c2269dd9b43f880d4f507768e4986d85814929afe4801008103900230956193e7262a0af2a6036f4cb85c581a5d1256cf78c1657598bf1c45f3048f3fcb0a37ab971d30f7f124e7662b171a5070bb14a750b26af9b020a929fd7b2b244d5945e58b5bb64b2f60b7296491d0ac31bc6a046c7aa3a1738b8563c234d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d14550c4dc82d723965476a518ea0915c1554bcc61c814c80ff120c37e7e8ed6d5c407b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = 3568dfe1f0c59088f8abb35ad3875213a2a65519db7396b940f13f3c3128a64ef475f74df976eed5054329271bcf76017d4c1b4d12d1c1ca8ab36d82f7af859e14782b3e871c84bad4326870ea4a9987859130c77b1c2ce061deafd94eb6946cf39910fdc0a64bd9ab44e87c1abeb8fbd846575b0c50bae3f3d1b11eda8e3d285e7486e93ba8a0344b3f62036eb6b52106da8db4f4f960a3e358585d6b58521aa54785b64a6af668252827ebe8a7ded2f29ff588679149798c8546eb0ef95c47690127ae999f0b4473cf62d555f2c7f3d14e4415c4cba34d907dbeaa246f1c73b9afe7f4d7fb5ffcbe89180c6766a6cbc4392a2a381665cf49b0ec0aa445bb41dd0663c42259382e9c7955370935c166e951989dec85eaf907f4256a0e34f18db5928701f1735b5b2490b9cfcc3435bff0e3f30f0decd7d406e64a45e81d2244ce6c75d77ad56acc575086633f9e8852ba3c31555769ad954b8c5d168a877b3f32d2421f354b0ca88a75216c0885d9d39f69bf56473ee3c032f04479a45c3a5819835ebd3883b729ca72806ffb8c80e8f4249cb5e8e4e5b9d9ec154ead07be9e0d7af859b1269a82beb09fb815da5ed6f3f7b5d1a5aecbb26c5eeccfa52f81e9dd4a0df5f981b510174eeeca9be4ef422f823126ea6ffc490858997c2860a53f3a58a315c9df5b8fd6f5ec89a21c158e7328a236ef733aa13329e8947beb7c5e921ec2b3a750d5410f4512e25a657024c2ca66224736b41af8cdab22616909f607ed5b29e02c34681c7db9f0b1c981b458f56127e96e12534b0b2cf3733af454e9fbaa5214a3be33ab7d054a7af96587d7df35d1c161cda7bee9e0dde3b4dbdcafa49c5444937719dc7b77174fa1b41d795b436f77eba0173812d2dc5a1eabc50ee12532db8941a79c16f2b70dc8a6a9465bd7d05fa0259ed29163cf7227ec0ab57fa41d7c61ea1b170ff8ca0df789b079bde45b2289e686c1436a05e6b21c1ed8bb64c99af660f255a7b232ac662186bdeb5582ec186e327d5e895467dd14d5b45b518c5c80854257e0185d028f699e9c52bcbdea89c8816866f1b4b311c60664b63a90bedacd1d5b62521d1743e54f4d0518f81c221aaef93777d1e769ee10c7085b01274e3f4c890c93085fba1d7d26bb24a26c22dce7e0a3a4309604ea8630b728a53a24c998b6be599fef3f2f02b85ac645fc3afb0db2622f3afad432015f2f5ab114beeb9aff0289cd712ec00813bff8aba8b6f3a3f72c1e574a09271058c97bafab3bc6c7f7046add6534ed76882362f8b56492fdadd1e445af0958e368ef01dcd62a89bb22cd030024c1a69c2ca27e186815fbfa71cac29f1a536518ebe6524512f15a1d2c8f6540d6f7ed415eded2468e49710f97c85a58f3c8027b76d69d27a4bd5d004353a6bfcf05f694350ffa21531cbec13536f2ce843aca02f94609561a4e94aa019d2a60fb501a44b05db67a3f3a4989c361a8e196fc68ad318c2ebdf3a7a101d3ad3273c692210f01788f7cd8a2eeb9a5a6ae82f25f7d8713593a25f377dda51548e8ed46a1ba233b44160f77d0fd6aeac8c45d9c2a4f5845284adcd7fa389eaeebb85e28bccdb548d4135be9955568fcc22059fa98f81c7fdeb695242d08815e9b33adc7cff5c0d6fdd2a492ce921c44cee72da15d195b3e5508651bcfda255d029c2d9ff11de9500c0544c21b86c4c57ba3bda90d6afc8074cf5c218565c5b64f40f6e114720b586ec1b77bce3784b500a7717f0a8d5fe4c59d8297428aa905c8e42ea2e5ba54744a9af35f63955058288afcbd5ac75dd8a2fbe417c5fbc2a48c27f79757de22593f032c9052f9975cf873717d4fa74be7245f59c1166d573677781ad6591ed35d235740532ed21a41c617383079567183ef5a42b32c28460b16e44e129a99bb640acb1f374d3974f6094afb00e3ed232c261bc05598e50e03619f66861d0bc961bacf4ffa6bd61318b8447bfe8a9e4d97fefd7f99628fe16a8f388cef1a7a32200f0f186cccb8230f40c08880fe6d9f1d6fb19ba46550b5b6e340e95d0945b0b7915edb9ecb89d93a367db3f5f7314f134c4e5a618140f0414e44ebb94897330f17a5e689c103583e260ba4e356524aa6f7f7e6e461b8ea45643528fc9019a69fa664cbe90e5369fc74e2ff2e78266ccedcc532d7e16c4f97267b59a520845aee5f1978257cd7581d9963a153a45fae +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2d149d32d4e889573ccc5e66c597c3ff2d7cb806bd13a8a7bdf86267a93da82eda320ff322ae7a548ec367fbeb9dedd810189c201f358b59adc00fd70ed6ac681fc660c5eb5544d2d406bcc2df444a863b70ff61e17aaf00eeebaa3bd5cd93d50ab460cfdd9bc8cdc2963784b7f9798d837bbc0483001539f0ea65a0574b467856460e9b2523d0967f5fb71556aedf832faf45e35d97405d4dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ef3ee0fe931d16cc9da767c3a48bad09874f783dfa74c349e2e63638aadfb59a462f9d4c563da0b485541e391b6037041ec6a066d563f186be2ab97a435f0a7daceac0ef26e16870437cf012a6b6d18fbbb23349628af4dd8ca9ea986498a80edfcc2418c3f5b6f7ba8baadf3739b3c578b2f193f57c7fdc38f7a2dc379ab3eb6127c65352338c11fcfcdedaf1b43e50d488cf57e34e06b5ebbfd432c27f090fa667177dbf7b66003ee35e7c43d938343d67f9e22e5597a16f09e0793e664e7de945b5e1aaeb284dfb1b350ca0fc1390a97586564faa4e20cf7538c2eaacc0ac0831b477e37c9e984b73ed9eed897d5ef4cafd3fe5a512f7c0e5cd628dfa6d7875e9605afec33979979dbb7fda5b11e41a6976fd51aa7a079827d37ca8a7f6686ba95d7ff75a59341fb2f9b4c163c260c4dbc4587c50ab8f0ac777849b5f81df09f17c1535e854c35aa24dfdd497ef2ed8e45565966f5ad67251b96461950ad2e71f1996e955e7610338b89cd91c356804cc691922449db0645a404ae4a74ed158fb58f6f30c7965c246d5d66e96c8f14e8ad786801d7530c0afc5b757e06abc10518b274e3992e538922c7e7866c7ef08f7d2bb4c05ffa3322a8ecd8069dff0f8d878a8b7b1df472e3d2253a83ab84adf563dcc5f4671b05f29ff6d0ba97abd2555c52857abb76ccf486dadc3d346c55aa544db18aee96907f999e64c0b86f97d33f412b3c9384783457b83309ba7ef74abd51de6ea1d3fa246faaecedfda789dfb98f7ff378f61cfce4f4bfd95323502446703783ca9b6aa595d690041f97c5abf5414455c155924a47896716ac4543dce7069d131b75a57769fd4b4ca1a9d170a357026dcdbffec930063d56e3546f09b1ce9e3c82057c0bb89111e6b1bba88eb8cbcd72078fcb05d6a0ef5c84bb5607d7b20cdd733fd96dbbefabd963eddbe3cdd89a92646ebb56fade609e81b2c8c15333e2f309d15135c07edfe1b824b1e63ac96e64845c35c41e13e3511a5d429663796abf2443908d353766e4df47b9e0fd04a710ba5d6a5b30193fa5b70e6338d8858c3fde8219512b643b8c6dca2a9347ec39638b787fdb44ce734d8dcd35d4de24af9123dabc09b2e7c9bb26b3393fed6fd88de9ed3466e019ac92b4e6c9683da22cafb1a9ad3475af18ae5ee9f97446096647578f770ad3e7a9d4fdddd8ff5d9425446ca2a4c1df03fddfa4ce130f30bb5cc9cb49a2e294ebf6aaec49a762ec27e698dad4463dec486ae5ffff562eacabae3f59119c9ba4185678ed3aa057dca848709c4ba0c8e5814416c5688d33c819773db36e7b9dc65fb8fffdf6921c48f8523fe63ccd744de5c5363c9a9744f8a6daad20e5a62d47d17b464da7637d9d26c6ffc2b5f186e0072c7e1ce668cfd97c29eb597e05ed04ade5e4b35a7d049db6488e271851d20cb61655cea6ad74338a722b1da7f77b5bfa0c8bc41b346bc5ba4cde7785be66dd83a6a5066e0724af7c6d3d4cb3a880f95040d53ba01eced9fa55b187e900e8924fd7656bee98b49fbf23a834195e9e3c754203b9d35c83903d09e86004be81badcfe79d297d67cc353ff815c4db7dc5798afcb9924de28e880098adf464e5ba83db61667fc2316895e8cdd11073c4ba5a6ddc74f5a2d6deb49e7e84a9d8ec6c63fc83a001da56b03bdfacd77be6364543e596bb962845594908af2f8a85b084aa80eec51b5ff7e1b0de2464cc73f76e5398cf2833ca5b81cb30efe982a18bf148a9d3fa5c6a46c323daeb5a1fc4393bff04379bcaa3a63ff679f3edcd0940d52ee8dc965b8fe56cd838adf84d416d254b4ff87c6aee83ee934efc6678caa453b8c006a94961bdde529f631f9ae699eed5c7f9eafbec0cc8aaccbfe80fecd9792da38e194358124b7e87b7f5528e689b3c5548de1bdfc9e44bb41c301705ee232e0a6bdc2e4c6bc55958859a5afd2b82f502e88a746a20179fcd60fe0276affa12828129543471c7c620fbab41db49173ae4a144eca173b23899a99785a25148e6c92e6b5b3222ca7eb3bcddf6508c4b19a039143b9d87aafc77ae80627cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861d950256484802a7b479b67a803fba87d916d0918bde0973ba3f2c0228c0dedd302c6fbc9366c4eb708234592cae1f3c58499cd177621731738f0d8573b53018ce88676ecaace719063910aa3d08b13a2ca2e64afabd52a309b2e0a849f3537109518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98aac23f489b85a9b18245649e8ec3bb8397c4125864d8695752e942437b315b7286675279df55cde5d20aefab94b1015030c40de0735472e02aec59027c8caf0074b0fff4bfa12267a3a5bc6a380632436041cac792330a4ed585379114b641bac7ccaa534a3863b52390d2173e4474299c8e1a2571bfe215c71b1d23c14368926a2d0944a1f20bbc536c84b7c8218b3937946cb227134e35c36f81c73d6433d4492cbe9bb1631787376115f6f9c3e5b76e83812494719b60231dcc4182c3e8a3e21122106b9036c62755531b6c5572cda5647746b9fe64286d395cfb759caf4136466937b70146cb99010af4088aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cb907022bcc72617cfb7bcce57988ca4c3d60e94d12c34588f173473a5d0929b5bcb09cd8f91534e7bea694576638889fb29c2074058900587fd8889c89593cb5186fba07bc103f4196a7063ba5c4229170f8830e254862457adeca7219f73f201130719b39e0b84845709f2cac7adfb60b26658ea9137a940b1ad8ca7966dc1c0e540eff9999822b5e69f58133902ad3704345914e17a30a96d6a879e320ccdb91f9f7c68f683c00532449f5420e8444e4c01df8b203e38327e566130c164d91bb14bec93b6eb4419a22c744fa9d92e861ae7bb13862288030551aa43bc4f809817675290a2413e71c9d29578df619be496061f7307248ba88d9a322648f969a2fbe005d9f895264887898cc0a8b35cfd0ab7afc594c9771536677571b9188d3b5411ae450a5a75e6dfacd813ca905b13f0a52153d0793c908b2d641b00c3a483293399d0b1579e28f240393e13c86e0121f1dba46fbfc9a5d062c1ef670e01c4b6b7a809470ad15f725b80849a0ac6f5370c1c96a309ff964dd1a9db2016b189a61311cc82dd652328596d6a2aab35a8020094ff7438064a7801a050090a18e9e4c2b33c14cd1f97b518ac9f4eb9a1156c816e6ce01d6053481b57b1787bb925faf531fdcba1be23570dccac4312c148e7833162c6219835ce3da23b1d149e434928f810577c37d0340b6bbb45945d789f6cca8fd5226a3c066595399ee696fbe2025701669454a83e3162535d51b11216affa7bf5c62a62d696d4532954791ab088ba84208a7dfe76b33861ba6d6b51dd322005700b38c8e4973c934e12c374c3c86c099fb42b2dad468a8701417e2b5e902b674b759a0f8366a3c00be49b43c39a016288a1282c9673c1204a73fe2b45e90aa2732a46abf8496cab31c52066052684d078c1926d374da041bee98939b4a597b2166451801cf89cac513a3d0890c3163150a54734b7960bf5701f837af59e9a4c631ca49768829ecc6d23122be873234d825209400c883cb47db7b60b1b1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342a4198366a8bdaccdab8349f9b9aef229ce46d4818bf188338aab48420b9abc13eeb990ea41ccca136fe6a3c3827bb40c33c1c749620db32dbd773043302b8b2b52de82910ba96ee430283fd51f17c38bd1734b4aa353345777ffac17797683ad603cde78c51dc45403e97514015fee950215b7366d76b29980c79ef727622919b59931e9a78ff6977d9e49c8da013a2920827a21988a713e8a378c3db9c90b8a2703e2961b246a5d867dd98692cb60093d617fd9493edee2820bb081b2b1c3c9e6941817b408255a0cd09eb8aa43c7d298954b2a92250aac1864d1086fd7338ade31a36f756425303a51bc1ac7f920a69273aa11b7f077000f9ba015035dfb96159d28282bd9960290b9fc51a79be9888d737329801428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2c934c11e2eaa7c3c4e764863e436ff12fc9f517c79df6344ab98611f57fe7296f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = 8b5c5386694f22a31fe63768feec7eff7e73d01ad097adf11a44c36d84945968a6b59a167c808493407f5b31a0430e037538c9b12e5d52d653d6643dd3cd73a8aa48ef5ab20e2bb92cc79ca14a8bea99af098b29cd2507d06e0ee99140c7e88c7e79f7ffa90218bb356e648d034570cd834dc37d1d08d4ea82f88a502538a0243b280dfc2ad395a04823fb6183588f48d64ea0f81309fcdaa426d7e98eb2f60c15892218a5b804686bb842e975b561c977ad67f7c91d9ac8f6d103a18e2ceee42221ff5bcfda988521f43fc777a34eac5eb3a581ba69d03eebbb9ede81472c2a436b842bf899886e8058ecc84dead1e563ba6fe889a7e0b25ad5ff5b0077c7910322e0d0e8626bd636bb84aa0e7221958d66ea01f7423d7f61fb90d0c69922436fb6ff66e83390dad9e005bd882895cd5850a9ec8e7b64de89dc4fd244482806a8db6fde17013cbbb3a16703a3705b02ab690a88e1ad194ab6fd52d9d5218ae5454c05b8f03c40bc9a8f24a60f3b4b603bbfc251bd3cb7524d626378f0d260d67c027a52e16e0e5927d486a875a04e8a5c6abdec139e020c117b99f901c44a98ff9186e4ff14701b3efb455d223c108969675811f70e69d91d5b3286084161698b9b19562beb24737e9b998ddb9898d457defff2017d9e5e6c08145c3c766a5e1cc7a353b169570404dac2738716ff7ab0c2e56f05689b139a0f99119912e36ed1126702a7d5c52417740167fc481b402ec4acbcf97e45113126c6a9373e962669e570535ff0055f2cb51d1f978a60cd5403467edefb883fde3963bb77fbbcec128b62b429758cdde0f24262b5603edee30d8676e2fe5a234c83c6ad76fb84b3e8ed583a7eef115b9cb882f62e9f03306b400c51513f66e893b09fb01737476820770b62ead2d5bcffab7b85b71516144e20ec097bae7a732102580ce71b6bc05f1216615361224637c5e1005230aed6b17624c7b22943901aee4102846e0e9cda4b92fd41fc7f95e043dabc3fa1c4f860ed6a31236b1b33e60213782e8eb1ba3329a898d8cbd961d688735639a4705d5fe48f2682a5e58ff8a3524ed26e305d1830b9f231391527820f39a0abcdfd6e0ad41de8888e4e08bf777d8bed2a069aa66be30de2a210be0c30d1cfd25860b187e84c3cd71cf0a0dd59042dbfd52d299b4205c515997855432b79586520d60470589d1bfeb77256b3c65d95a14b8a64abc13c6d9318fada9f4d8045fcc04ec8da30a8d5bde9a14d1e8de93e9d9ffe64a77ca55d0d0473fd8ac11d3523a6f42d01df097d3093d9a7dfacfce4b49f03db78cbf0d587f1783f3a7b57a6ef7a45d7f47757591401d92899625b8944e60349bd0df5692e448607273ae7d56b864ccefdab75366c8435385f6f9feaf08bc3db55e4a2c18ab236e01f272ed11dd0ba70259f67bf369e6fd4972910a2c84c7b052deacf75d7b495238900b3c891bc46a95c82e3ee2a36f7a6e42658aba552994d1f6fb80c1f5b2e0b7ae01605e8ea55ff1b6ed14b4de413e501d8d9dc1d23e456e8c17228881ed90c3ce76d51f9f4dc74ea863e83ed32e47bf3df0b598fd7c5e10121a8cbce0b4bd89908384e2ab7cabfcb61ba4a2b06a524c318a739b13746e0110b50a56a583c0ddd133a8177b2a43f9000b3cf83afdce5617910539cb1c980651ecbfa2b2f1e1f4e4f97055775a5f439d861ba4694d8dee0f36220789b902fb2b4ea86280e0c7bcd638d43a6cc399c7c164fa5c75f1d547147589cb02b2bb6fef44c8927c0d26f0bfa8c6d5d341da0860f6cc4f9cd1ab4ff9225f71411e3a3b30280b3883e1e72dd29351196426f9a7aa2c0790c8d091d4aaa30b16e5262dab1de3d8cbaa951e003ae4ace9fb9c383030db4cdc6347863bdb2a4beb1ee0eaf1a276871b4a9f03f7ffb82f18edaf1b240f0e9e872247529c6c2a60a02a90526609b460944e52484e47c38b2b876854b8a95875c0e057902df9eb500bd113819d73b20055553bf893ad2af55a6c107aec3609571fd7fdb05fd1a65a206f6799e0560775865aa3eab49fafa60aaae6fae87ecc06c18d5499b71ad27789634baba61854282e2f0f7d06f8d4295c7419119e49a2753b7013ceed3f4f44b008d41c543cf47418d5ac2769253b636327d3970c0c1963f2f279c2415b03418a1a44968662d8663f7b8e4ce66036171a3ee37c476a239490892f2968d19309a460694a3 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 86cdea4a587baf3d8d3989fb4707ea97fc55fecf746f98eddf7bc215145c56d399c6447ada49f30866384bc7e8aeae60a7349747867cf695cccdb8a4f1fbb3e573ade85ccf399f4f3658fbacb9798d58e522adcae103cc9fc9675184490f38ed3516cbefaed287758a4c374c0a53e3f2cf9252be65562f936dd3f9f64da1fd887f0c775823436df736c367aa301344ee66854fb39a9eb91bf3caec3e8479dad64ee41f39914a77a767a47b61ff868d0ee411aac9da94c72ea6f4d228e4cdc99c89a4b35e1c4c63cbb3edfad6898e62e28d503cfc6617bf4d2716d1d1df75c14ed9dd9486220b66d523a8111b4de5b99d236586a09a4f78af40cacb4a737c770bc4915f55b609075ee68499654baf917ff64715fa8369872aa3e14d8dc60fdae346ffd11465f119669a0d3a7188d3326017ce932eff0c7e5c26c4d851683478e5c71adee0890ddbac577f5a8763d4a76e3deddcd916ef021672847ba0d4785ea8beb28fa364e64c4fb707e9d245fb20cf6858b6552419a4d9eeb22f8c7992e3b5383e83d14d948777c356e5e4fd0bfe0c5a636bc5416a799270e5c976cda62f3a76fb134646b333b75582f8ffc51cf4bd37835c3febfce1ea86306362f92e6d27f4dca43a45edc9554f08c6056f4659bae0ecdf9e59b6df7bd66eee447f4398addc73387589e48bc4a26b6749ca6e926fd34296db3044dbdd2d23e2ca6a6755ec48c46865a36a6330a9aa5d49e67d6d62ef1a7c82ca5c0bceb163b85e44cf78312c4304bae27d66576f8fe8c3ddc8511d80771d9919ac6931264dc2f9e9ff54e875f6d7a97772feb45f1498efbcb37b4e0db4604e6cf56c9501c6598ff9425249740eacca49e9fe31d679a5fe6c3ccb4384db45e486f1719c6c585ccc03355216d43626cd8760254ae3cc4aec1f87cd5c3f0a1e641b05c7036c9bb46dc72a0f32593dbd25eacb5a88abdd9f6e102d5ee857aa66c8c47e434d8bb4a6cfabbd8b78ec427846f1ee8a287fe52b27d063b489a3e6b8ba06b00f14a3f2e6ac017f5e5724cb629b7a312b3a132ec94619e7c07637b81d50bb644a38b8e9237dc857d43eaa3d44962d6bf63bec4d1eb04b8e7aaa996b2a266ceb8a80aa46674f26f07c6ebfb484af461b6dad9a9e6d2fc5708ebb355a67064ede931f394988d9022e59e78a8a249796c155a9dc7cbfe7384dd1aff39c29773f76e0e536a77b879eef054c5e539a391d43c1b53d69566a97de931b166c6f066cf0ec81e759fa200876d53dd7724ac91656da1266ab77b3f7f01f82479685bc43a2718c93a806c3de4adcb918c7a734cb04759341c5b1496679987aa5db93b7109d3a605df4c3da6fe8cbfebc37e82f1e79611c61f806f24069ab83d7e65a46caa74bbce0897fabea9b6b58cd34e7535c0f97b4359961df3e4a498cf87ed601e9faf2fb6163c4b27626e5121b62a8addb08e6e065c83a69e5e253d48399fc665a6fad36275ed3774f115ad79f13b8bcf4f0b44638cfa6ce6018b58bea422b8f87a678deb21c75456592e9bf4cb7cf6ec3d3c1dc5ae9ca16888e9b7fea1a863b8ad1443d7530b533269a8b692cb4522ac1aa27b01d386040edd9e2ddf017bbb36ebfd49a2c5045a63081266d69d88eff8cf147ac956a33b4c198c1ebbfab93c592bc5e37f39e824c18f58dddb0bc4855a6b83b81858ee7b4beafa59cf7e4a03685e1324ef51f05e3c50aa885878d0c086d756e677bc8ee46e4790d3da9a7ac4e0b3b600f04ad648e424a4b430b0a4db2387703f77c4a0c51072bbda954b473f86ad2baea5c9f6d19edb0c35f61502ab2d31ab5e837675b369881af786389c9ff0ba0801d98e56c3c92557f3ee9345749d1d0168b3e35c4610385c324579686571a15ed496ff57ae3f9fdc85178438014fb365b1ecd6b4db41ae8caa46a6eeafceb264b8cdb3cd40f9f8ec48f9f3b8df5c675f5e937874e09c7fac652ab059a5017698d8cd123cb6dc889b4c3a4fa6e834d029673955a521318b930fa4553f46059affb5793ee958de5ab0d52b55e4dedbdf213f3e71e7d63bbbf305a4ae73ff68a1d56e06f1aaa3967bef778af01c84450daa35b06801d6ef1425869d72fe3bd4b44667b7c2164e103dbef24b8a472e55e468b8a6cec630314673c8aa12fcce35b7949858d72128dc3dd1b72c6e762e6e2c322cb783f069a7e5594cd26a0914b3104b87318d0489a63ab263c88d561a4c8fb9a77c72ec2b917f685333c61989a4b3995d74589300688d2512943ae79335dbfb0c52cd14b16c085d510918696087d2ac47437c0294b8626a65f1e373d19a0107de053219a22bd0907ba19b4e7326f765989ea61174151356f04585cb89ba8d05a99808283b550c8a3816eba213362b5cec5773e152d14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43ea22074bf46f252a125d3740066509c48ccc347abdaf436153911dafd114555964c49ba9e2605213dc8a71a05e37b305f922a4e9a3b31e973e19b161bc4295d290535dbb8b6b359855d811614c14a408c34926be2700418139998e356acd5b85281b61b0c78733b0aee5a1ca99b56737c669d535b276c5546aa72673c5344fcc7923f69a0ada7096d75e81e32e0a8644ad73a4e7d19b3be97ea3d773be842597761818275cbb8aaca1206fa41686613986ddf37949842ba1741e812217593815c82ca7b583513938931b0bc829aa55d85a32b6822013244f2a3bce15791620e6cbc96b8555d0c77705c7cf996292cb5592e490d6243bfadac9dad7270a125e14faa8f8b321cc6c9e3b2407000340702a4c97a0189febc47e5baf51cc060af7cbf48642d46911e0889eace6bff53ca189a1036ba94912582b0f8b679a3b6ebdb31b7bba4f9c4c349052c4b9352d45e68463c865ab331884982c05f3a1fd78081d946a71d984887041a0e894f6995501233363027a3b7c321dc4a21d8463c9369abec4826f0906039a1a83cb59cac584d7c6426c91767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444dd52b236d4cd2c26cfe39c1cc8321cf7156867b37f85188abea7a040400dbf4830ed1835b2d47a6b8991451a7889020ead45451f46623002b31839c556a22382130b7689cc92cab281b164dd237357a195f4688f8f385f8f45a32432bc238a0c7f78324bd5b9e73aace5391d60f28ddef61e4e2c493c136b74229edda96c22f70f54435c6240747d963e576b2aeab0bff2009ba0f34b65c2a35b72477f36c914d048545c513ad61f964829a78bcccec39d2db38496a209afd760f1a51654d3125dd42c3ee13353f93e0114469c2abdf879050cd9466b4606241158a60b35ffe1a8956815419b9fe843913d22b93c7283805ba3098a52bc16bfd9b27c29155a22c99eda56530a69964466065ccaa447b13c4c8115adcc6285d947aaea1378a76e163556c18459b1ac905abc9b39e21e12486a5e56a228395093b150fd550feafab094602672860e5c74240ac705f25903e70667968435a4dc3e24dbc77e9806ee94436ce00b11bac776b46bd85a94634c1a3bf91e53781f03318aed41011a390f48e5b7e2866d11783c7b959882821fd4745a2fb3bf1e87756008ba1103a508a584a3290a4aa4783f10a9e62a73f11a0d18f9b8e3a608a58317f3d3909a5a622bbbb09b52350a7a681e2a63f02504aec572328155f67100b6331f38835fd56361fee46b903ccb020a2998d651bd2cc022f1b4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f43259025724ac0a05e9de54257859858685cd602bdedc01047fb903416a2e2d770aabcce2460903feb40274354b2e705111124887b331cba10673c0d2aca027a2c6ccb95c701568c20346ec747a29de09ff6311fc172910e41031b95330e240ebee2026048047e03c6de9a293f501604d3c7ce57a715db0aa91a6151230731e02f467477d04a5aad9b2b8176a1f056c3140bb1454cc7ffe380cf97139f4800fc4b740a22520a3b2a8730caf5e7580352b936ab9eafe3cbebaa87fdc771b0d704e455b8153c4b6cdc780ec415ac7326be810c63669a7f30a138a187108880b5ab97265a2158f542c37828c80b4bffb474ac27c6513bc54f0897ccd9948dd3c78f60c4cae733aca6caf41b9ca8052f25e58e78526ac8eb30afa960a04a322c582e5ebb286accc225a187a074877c21329856343c587e7ab6b09c3427091655f34127e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860ca17a63d0b154c9941d9c219c0a7c982114fc0c85483639a0f047a217a148346fc844c44f37270e775c5ca414ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc5b07c8359e6ec4989c34b31293f4df965b5d95802afa5836beabb001d5cd4daee6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = a4793adf41c5e21b686b9de3d72cec8129fd8a2e5a0fccb6ff7e2f06e82d8f3aadc526d701e51262e5d06883621cb5574e2e450a20fc47f20f7f6355dfce304028976c5fa57b63fc63e6ccfed59124d0a582c43419e433f415152162e7e4e08589b042524ebefe95166a55785ea189fc09b4bcac859274ce8c6d01ac52924874c8862dc1bb3ddbeb1fd480a1866567717956b26c55b29aacc0de9df4cc97065657092ccfd5c3854bbaa5282f217e1453deb8c62ee5a2babb288be4984cc32a86ec68a46eed9e8a97c369eb1a571105c2d63d52e7ca4921e6dfd4d3755d24965969c1789990608371e7c3a50d25aec8ccd9a43b681f4ced65d76640a668a4cdf7722b3e875a486ea72ee2e93c1d8b2cfe374e57dbdb28c95c9e9a5c64dbaf4b1c7132c3ebf3a951e013c94f653e8b1cd1f9a520fe7224a5b27e267d21662faf8c4b23043ed8b184bd02749654a25accb8580455c8e2af7274f9d2893863e49cd7cb7efe28a9edb4fec5d5acaca155aaf9deeca15d63cf50ddabc55dcf0c24748fed074447599572b51b1d6ab9b282ed9f53b5b77083b45d1f4b8eb0cbf8c29c0ae281ed97d9e9bd8a322cf48bfe70e7c091aba044b99d03336d015108831b5a7b6f5f2f4617097ea14895bc7bddcd5aa236eda01bdddbcd527d1d28de96df5aacb6103d214eb7fab3a3edb9e53847c8944716fdfde2365dd96a7e5e7f87f7566e52113cb584d17b849c35d6c99f0b5e2a2e48e618e57629c7531ee9fd098dcabb8920b97830e611563fd56b852c9693f0d3bbe5ba879ec4895d5b9e58cdca0bedaf1f9a635b2c73d8472f473f904c5bde372278d88d96fca6945995157bce76f8c290ea58164c0aeafe262c2627eb44d2915a9822742f3d1ff1a6c114ef3d5c04c827be4c8ee387223cbc0848e5bd8c59d869143ac4a58d0fac8763fcfdaf3b68f5edf1ddce50ef6d5d556babe89ed42fa2fc6e9d09307342d819550ded95155001a9882c69c38aba8478c1f7c9f1d85f1c69f062a835da33fa93c304905f9bcc0a8b5d01f8e67b0feccf3dddf490d7cfa46bb851c7e3cd1ff72b045102677b400cf9e3829263ff03943bd1767caeace23f387eb4ead7d27c73a703792279f9ebadb385162e2bae31759fbc735821d547da0f090ce88b12dee49fe9118dbb908b26ba68057ecfbacc84e705e15d4a734892e2546951cccfa05dff012e0b76a4b25aa648e78ac29b99db10773bc0dfa84aae26fcda78e906099111f3550b32aed526883a07977578606c78a15315969ce3dbc4cd2529421386d2e20001652af4aeaabc9085b26164f8a1b61a396be51fe6718f98e2ce4a67c5f36fe46cbb3c2e06f763a15d1525068b5b3dd7911f237e04fc00b461907c3b494f7400f6ab50db133d61f816127406ef28a61ff82903eaaae490646a2fd35da87812cb24abef28d381f319bae58ce8ae3696c30eb3db47e68c6e10c12a98039a3c2bdf4176a3a072fa5b020c30ff3e0ffcf51831a25c85523ab881cac1bb7f1ef2f18b1a7aaca6724cf60564e3aed54e5cc5b54259606a71d41a561f73605327d8429ff1da22f80c6f518e505f9b020cd1cb899b69e09054db0e7ca12c8ddb7e64ec2c02dc4b9dba1095487efe828f04f6eaa4009232a4f53db88b0f3335e3277a6c86b814829d920f409467503603639e7d02ed75dcb0647d0110722f94d7cbdcb34625bdd16683e00907c8b43e8297f937ab953fd0c22edc47419829210563dd5658ff0968b7c5261b09470a73c15f960dd12a92459f4fa737b63bc6ffc85c6bafb7bceaa947c564a3a30f0e540de9422918ce198f643666086772efa12f74917c269dd6acffdabcb6a71927a693120dcbbeae2a2023d1bfee1948b2d85bac9d3911b4f3e23900ac9b3624397521481a0a19502419f48ed2bd98ce979230787bb3bee28cca07b3a6cf8b1e37b11843d5fa41ffa77940ab9c90d61592319f728f3ef0f7ebb83c6f0cdfce9a55218b513d855e76599f1863451d64345258247a812e61d8aa5ed86358a95bff574a2a2c69c719104a04ed896921c4529154b0659de5e611ea81928f2fe57c02c98aad4c2932f9d435157ad26110eeac754b94d671e7eedda2163dea0e78eda73b2f776f69bf0da1c3a01a7f30979b7f8d4a2dc091af08904f123e04590014b9df8f6f724dd2832ca55c8b623dd435a2ecba4ad72119fcb42c2d6570 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ce83fe29cfef43ffbbd2bd49e6c8d265cfe8b68ecbab8c9186f3f5f86e7895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b75ff86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458f4e9cd11ce0c99dc94fd3564baf5f1ec3a32836d7d9be86412fcdccebb1b1e489622d7e29264a9ca86c94c7ed548fc9c6c8d04d8e8f51b5f0077d6285bb32826e8a157c80c3ddd905c333175e6c18fd44611f4fd7aaec3314e7995ff0334c84d96a66fc8a55578e4c58f7826ee86f183e9da305d5f11f4c3f06ca5089fc1e28d0feea8a8e98d5a54bcb90d5feca1446783f7f5058cca25e617f443dabba304b353f4a5caabf1ce79a87f5838eec033b3f3d2ff5f29eb887e8f950de891495dde7be94b92cf50374963bdc7216bd7cdab8d0147fa21f0c3845979387cf794aedbbeecdb004258867bdeec5cb82fc85eba2f4510f5e4a40ad9b6aea7e5e45762076b81d88ec2bb9edd604ddf13c91e947a7d7abc2a2aa91a24d4d8756fb42aa71eb25f09aabdd4a9dc2266bd51163cd2ba831957675823748306ddf7e94b3ff0996172f5737a766c10b6aec2e3b5b073eff93c3ad9ebbf2b93ff47c84d7dafe794990e2db4a7e9ab19cc5dcd62f427e6a935ce397659db2189fcce5e4b971668c4793ca4954b4787d37315eedf1f5ad2557caef78c915ddc223d836c407936ec58825f3b2a29f5a5164b097a94a13d8ad3a27bf1f0bdd08d7fb932e5cb1b67c7d2c4a7bc7a6a9ad54d2a34de69c78195bb149e4b4cebab7904e612ebe9540385f2f74757c76fc2da3c7b03a34aa5f4e2ac9df5ddfefc1dfad84bb996e6c7342677000cfc9942cc22baf934d97a66037a1886dc51c0f36ca2be881bff86ef5f41f0cf30a4c6ec1ef96090874b3ca751de7d1087ae5f419c67eb4514754d47d7848981cd36107586d36818e74ad98989c8d0fafac4e34ee0b545ee7d7876a613f0ae1be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d7ef9b184a38d819eb6a3cf88fefcae833a68a3cb6b30bac5ad7567c788d8d8d3a7c7fffbd9af53b274b93593115b5b7a538feaf93706c88c178bab897c7e98c23b8452e9852b6d410e8afa85c902edcb9a5e87a31ca84ac6b89a75830576d62bc159cb139f77bfd645d68e7c99ffe394d40f27fed66e4e643897df22ce013dbeb426a70402fdf21c780c67bb011fb3e8cb746c1be4c9f847dc1235f72e6bdfeaec55cdf6e377395c5be7b764a41e0f731288fbf729fddd379befe58901b1eefadbceefae549e5933aa9f9c64dfff73c486b5635e674d56213cdad7637854c7b8448ae35fba6dffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cd3fb395aa73a916514533857b4c3405fc32c2946cf404f61c2d91b6cbb00def96459c45e558b5048b79cc4cb8ab0ebd7f8f320637a62f2d38d5b3c0593b42d32a38be93e2ac1ffebb496a5fc4a992aebaeb76da23988fbb3f9a79dc7145efdb5246466f25af4ad971014970ecefb36316b86b3585f7bd75381ea0bf3952c688b4cf6c8a25cd964cecef5c1c34b4cf8359caf3295dd63ad3dbdda83f072ed42fd8b7c2bb43de68b712e67971e76e7adbc0879a41afa358c2258888769b0f785f2b57e6e76753d41c4215b98beb2d95f6cdceadbb69c46ca152c3d45b95a9ff198ef64df667e3ef37ef330a4cec44e983ba4388a81fff1613a47d29f49f2534c23ac25bb76176bae0301d3d1c6578ae24e772e36ed503e02ccdfaa34480b7d57e935b5097c5c5b624f2ff6249b363e362cf84d67b485fcc3f9435d11134d8d01b96bc94edf2cda9137cd1cf2652ef067efd84da6808e02c1b70476b8b67fbe4ea8ed4722cb3c82c42daaefa2f36e8d51cf7313ce3ecaf4583a3e3ac08aa9ac791836fe22a6a8ad73fc691c8c0f84bb02aebc6f50ec2466ef1ff33653e377805d3b2c8633d8b24ed6b6370981bc63b7e41efffbf7e86692f28764716775bfa410443e5e5dce19a4f7fc7f6a9899e65b7bd9d0bbb80a609c0d62d63204bbaa619757e1748412cc1dcda4c2b2df3979f7229ba83b1eba23904eefa63db8a2779060877a5fae42a1da6cb1ac97daf466ab58625f8f3fba58429b6e3f2d9fde06993ad8dd6c8e4834eb491efdb1988b9794aba1c0d42326e9a797c67181995999a1053b3a1ae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f263916041ba9ebf2b86e21b127c5951d7709fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4d50fba956ab9b881ef55a6459199c2987162774f573599ee0b6b001cba6bb5302df24ea0622d3fe2a7db12a063d528baea6dec8a97bf12a61249010eb7056ec5a9573c77b848a6c6fc13c070450919054c05be006a40368094775032efdb98e087991d76a703924528ec05ee50bc56d206895552cbf4999c6a7617ea35652c8d5cf22590bb9fcf62aa0e055805279400b2c9522cabe1853e06e6965b517cd04538d7f083e27b95c29b073ae13cac42beb549337491b88c877af8910bf8659fb2f309442460ee93a0344ca83c58c1840c95ea482c81380bae24c01c763b2bb05b369bbf074c8e96ac2b5b73920ae07318057a643640fd58c691209b08c9b5cbe972adf001e8c00fe853631341c8a634cc52c77754790a6540ce9585290aa243231332d7ec3161b096ced68d80208c362707ed892921634b4de6679e08a10f55c72043348bc512ad39c07dd41a88d3c8c06769b6c080b9a24080684aea9637527a099bd53af1505eaf0272a1f537593669e6ca1d5135ae9d77b737b77a475b61023777eef22477b663d5848ba7d8859042713bf7353dc46c2e3b9e75788b3813b4844c0a233019529809487531a820a079fc2a43da0874c332695a79aaf3c6d5997bfbd27783064c1c055b82b3be463b5b54eb8c2e42772cd56318c6658e0b90cc31596b3880033338e6e41e9d1187e3732b75f50ed961501a030d221370a61788fc8b164625939e7b19d076b45b51c555d063433709dbab05746641410cb34ae53e3652a0ade7ae5dca29f0e22048668abe03869914117b6cc18617946c73a20b49826748981367090e8b72b8181ab696b878c79bd16683b2ca698e1489daa23b54eb017f4000d481b268e2c7c02a75fb608217bcb1290746f7251d010a581df15ebdba8c5d379441d22e591c4be3c9cd9af05956674f558c2387518bebc02dc3c2971bd264143271ce28b1f419be088922e6644e939738b846cb651267a913936d80b2f4e8987b5c48c37672a222037fa1529a764be14a87939b6c72b7730ffc4db926836c71a56112724a88c9f55aab44638a4c9186717246666b28e1003ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed16b0a526c019e7399d1996f44755fbfd86a79d19fbe3957ee97a08d668adee16b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd2c0b398383378ab973c9647db074921531a9441fb53a94e229b7c7ba8f2ec9a1e830b9826bcf1d353d91abb56b89c33fd37ee6130757d08a1699929808c881f9907556af18a95938a1bcec20191ba5a9ae32b769e3c56d4cc6baf9c9152359609a9e8dd6aa9ccb12b35c9db5605bd8868474e65257f785b429c1869bbdf6e118024c906a951195dc4361aa95d4c53ca418a7b6926cbf539ec1f242dcb3b96e47bbe6cb0cd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091c701ab73271cd86765e760f0a58beb61b0e2d12bc7511d04b98e8fdb5412f618964367e2cb694af203ab805889e0936c55bf8553b2b006093c72015d8629b494a04e3b51cf18347e7a025064a488b42c0328cea0c57dc14763a74368e36159c72b232c8424fa01b5be63014fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc4529a00c1ab9f67e84de76500f59c7088b1b9dca9ca9f0309b5f12eb4d55f3d734e086a843a39b29de99162a062b1e6874281221ea3314d784572bab031a3732010a50c0ac8150691b621687b6020a5b347817a3899f141bd6454ee1b25e0b130bed368c5f905c1637c036c22f65ca761270a9e8bcc18dabdd78bab5c48a3ddb82a01c646c9dbcccf972b9f0ac4edabcea3088586e8ca08f7177ad3cefd578f9fe6ca08c99167c65e4c6193251288785720ad110f58f81f4b938dfd813b76887cab48bf0cfaae5a8a16f3b110e130be7313411d517e6febb2e0ac004d44380b8ab62e874538d005d4f744918a250e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de037f1d7e636b4ab366dd5725957b9e5d2498e4ee1929f2213f9d05c882d96a1065a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 609d810d89c03c441dfbb03f5bcdea6edf70d1a067da94f6ed3e9ba09e5ed29dbe118daa609aa4e7d5123cf423003aa0c9e4e9e1e181fd5d8511e4c2781bb2d1edfec62f31ecb486e349849bc9529aaaef620e1ac497b54d315ce29e1b0244ca97a1fe8053eea30542115b1f8a9337f4f0219e5a1d4012b44c3ccac837ef90e92fe9f33f5e968d6bb35b4c8cd608b3d15cbf2e262da93343368a4a3d91108976175688243a9596b62d1d6d7617c31335dcdfaafbc1d9f3928a8d19aee6442e6e04c0b72f119a596f203c0118d307164e8896f19c903f968f5bb3970f71c63dd91e712b9e53e90d796e6fc5cfa7ba75a3f0c3ef415272d9f71b328112cde8e5fbdb1e0ee8813387dbddc2d8a6a8949381f6d5d19cd4d111fcc78cc82134c204265c0260a3443142a6fbda728d2b6ba19eb1f8c87e468749048c9452c25b89f4c065861ecc87b91b5f26c72bd7300254b44c6968edd020539f3d7bd3c4af5bf80e85b6b12387c95d0f587f31357dba76f89c84db06647cf5e9b1950074ae86ec225f2783fc06b5543301d257e821c9b2f0aefc322fecd5e8294ffc4fff3a626f0a455d8f906971ef6077704a3b0c9275e7fa3e66cd3bc4aebe6ba87e545e42bfd9663d9050ad6528a27f6072b39f2616b1610b937f888884fb11a1bef83e44f0e7c3fe5f0377d0415cdaa58e9662dc92333b5d0361a048dc913dc4b603aa1f6ec4b71e677964c5b2359a3eaf6d457e168e1f7c4f5d6f2e96177bd0ab814a038f6ea5a06de663597e6738c026b581a7b4ebecde74f7b84a8bc01c18275b4a4347d9902b84a0280ac7b202317c0831d72129d98e112b6a01bb1396a3d724142ba67352642f840502e6bcdf7a3c3d84d1389628cd5072341e83e58d3f3b2ed7aa04822904ae8eb7aa119c375a57fd3d41f88c94ed420379b47bfd987e23721779368b76fd92e32c05b835f724e20deeeec9e984d4ce9bfd52d61b63dfd73d24e51d6005d63cc8ca34257d84dbd88ff6a97232cfa190f6c7a66b13155ce7a341da5958382af189e3b45a8e884698a7ba4f5345bba4a19460649ee5844734bff46e0114bda1265786bbc8b3c968e32a68373079d3ec5079d2faba3f31b903656d0bae43b855076cbe4e9c597f31dd77a981b8965ec13b453b345dcd665f571a76aa7a8769c2e0ecbb3b7911b3ff0ec8b563be40ed24aac61a794716f950eeac5054568e614335caa170e5045b06ac08da24807cb2cac132576529510041757188a8a2136ef544c75838f7a9852b45242526d1cc1dcba9d375ce332a14719506386cd09a972a11c6f40e31f5bb794feb9b36696087f271707fe6e6f580090775478428aa05a7986fb3bb2f23aca96b34a95d2c7947fe1bedddb527df4f816f6d726aeacfde3ecfb23b05b3f94911adca76e4776269746341daa40ff0f8c26fb8310907cc086a1a3d99b647edb2effa7c59d0f3eb615600a56d3b3c5458df518086f8146a7c8755bd1072038d859bca37b9ac9fd99215beeee2f59237ff2280663c406aca9c7ed87763a9dd618f734a452b9e9438ca40df7b22ea30f32bd1eec2ea006c55fc594b3b7643b46fde5e8776d6a31f1ada8ea45778cd3c39b1bfca7bf7ac1eddfb6430a2d86d5499b84cacb1669973fb82e0edbd39b0fa19909ea012b5d2f17f37b5cddf98a529b205339d58289731526aa11be9339eda449c3e60f229b7ef356c2bea00f0d8a89617acd6ce419dddb5f12c9744c85cd17c1cee5caf69a3e456c274f911706bc6f503418ae97fa8dabfa6a228c82378c1a56ad6e1e225cd73fac1230bc58a365252d6a86462410b2b72be47204d23af3ac8e2b014a28f77aaaed3bad6228ada26d8109c23101e3eb30dd93f219c00102e285d29dc10aad691b860784fd1caaba34f4255b27f746c8fb2b94a34f41dad71dd1c5e18e4b2c3c5fedd3bdad66653a649a3aceac9468de6c08099c70c7d6743e2ee329c50f8bffe17245a1d4dc9079635a3bf0d5035b6be5cf014a713fa578bd631e9a6198fc90159cb9d89aaf7f96afbc1130dc98143db98c58117c7c2e4db218f426cd959ebfe63f40af4d059beb8f715eb4a1e0f5a8981e63991cea7f87b07b29fefff046f38dbf22d53f3a2ca510f3d2d5636779228b5636b9458ce0e79e60a6422e6dea3b6f51bca95dee3a3de8fe877474897bb365c4d14c3b905befe7cea7cbff9dcf25b8c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f76c7d810fb7ca65bfe6a59aa3645a8f5eafe5fb80155f41134cc072b6dad4c7fd81cfbcbe1630eeda661cc6fe02bd798203a1a287c4b807f6de5ffbeee6627c864149ebabd94f80749e93068af349ff861dbb7f1a19e4ba2bb3ac6c80d5daef483c8b87cecf5a2c3bf8f672855579948ea1b1f3cd02e445cbe798ac0361e15335390d51294667b9149f38d85a1839ae43d331bf24d91c4accbb24c8e91d5a9e1e85ba98db7e13cd3563aa235b899e85d9535f80a47e62c043b089d5a0bd48b225ebb2d0538f49c8ac3c4bd677e8d93c07dc3414d16b4686d653ce4715a85963e71bb937f6ae91637ead543e8e8165f69dba4d0b6fdd057963e70cc01e78dfe94d8d03e3f75c95a2c538e90924749bd3fdc32bf1b58c6f5e4b59c157cab7653c0d146dec9a3f95ef41994bd9be6f446f35ad788ff79f1e6464fb316db8449a3ab7525b3e8acefb55fe4fb29d57c3a5e0b17f89493ea5747782d404487926ad757bebf81cb416d94265dcacea475fcdaa727d0b5f01b376251be2407e7fbb1be976b7704fe5ae5bdedcd17b87fa8bbd3e8f4d3c9eb567b5c20243677d84eae2dbec1d049a842b7f9da9cece8931851bb35776caed97c27d395108f4f661aa60cc28eabb2774c67773fb29b445f3554d386c87d489d895a43fff68af0c81f6065e57e744f729e20323b013d35802ef6bac37d0968566523ed6f526eee95f8372d45a42c4e022239fb0b3cd23d4f51927b3567e9a1f3ad689a4abc508660dccf82706b765ca4bc1887fd064cf8285b1155863e16be12bcbb1972f55b46fce8fa4c51c97cfceb7d04daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b877f4c1adc3e67d756c1c8647fb4ba32b75a6da3a05a97dfc2fefcd279666dad46e064a74625530e84fefd7fc1d5f959cadf56389c4c646d9fa11a8fb5f7de1f2f56c8164d80c69fb804d18a647af7f3ad970f65f55cb786e8726b65689a6a7520ed45b7d45aec05d706de35a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b2267f8eb8836ad1f373f67af134b8b429a8457c7ddc5b3f74b0157f67fd91ec88436d5667803ae5749b4c9c499a36c58fc5a7ccc10a604feddde74bbf4345d2c02ab0ed949f5da8b9efb83c4a2395e4a4e3a713df4f95901e8aa2716a3ebb09aaf61c93845860224dede0f8c0865fe461bedfdd176c68b4c115d9edac14e21934f13855ac22e8c98e3643c3d7c3b6c6c4ca9643096ed525c5aa00d3fad9caf58bc44aa06fea2873bedaf7c56b0cf7a42dc0fe95cfbf1fc0039cea65c6fc18c37e62afb9194c9ec1db8ba0dd36c7c3a620b5c661d8ab0b46a6cd3391e64fe8e40cbdb18fc2207630c37e5542cede3c395bf2a5a15ae8b50698ddde937432ecb150f9b3c136881058a7510f4d9b247232c7f89cdd7463cd51b7ba599c985c6fbd8c7bdff135c99e85a3d113554c59bcd6ae298d593565905e3645cde132b4c1ab84677e44fa1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f88f784e4b6fbad380c523efcbfeed4ec89df82490b5febabd4673d84e7b9dfd45147e8f2dddcfc2a7d7155d340f2be10ae53ad21759bb5b8c8e495f55cba3168d5921485b74af48535ab3519a544f54db04bdb1a667665cfd68f165570d9aa52fccfcefe5d7391d9a2f28d11d2bdb3724ff24b5f843b8ec44eccb8b083b8c98a51077e97737bd470bfc40a5a96e385364463cad8e348ca44e9b9bfe4587d1fc0571dcc6645f07f5e45be370fcc235ac9f736bec85e877dd3da9665dd6837c5dc318cc11f962838cdf26a59f171b6ee22bdce039f5c38d710e24dea46486e694e9b11b548d98d406f9f9da097a99f896994d979eb861d483337e6d5c7e657c024c3315f76440f8437057710cd7e817956c8135873ebb9d84c8d1cbddd6930443c09773a5f542cdb838e176b45497b9719ea613d3d5e6cbf40fed8009e699c6e3dd4404e62fcda1adce6e541dacba7662795e64716e3ce1044e46b4e92a145beb47f7dddfff53a98b4c7c414483e60d8587303ec76edc5dc2f8f2a91976761a5d933b8d294d82bb95e62fab7a7e6fdee3889f299956c7639dea87e27cdd4ba66ddfec9d77949a8245f4e48ddff98c06203871ae8b0a2c3bfa4695c43050870392401315764ff65c9ef0db06b03b5b5582b57e1a7ec6ba4ad832a04e31268a853aaa2227f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f26d0769aec141c0686f750c1f17784cae142b942648655bc8a0acb8247462713a2183223dfb093a737306e94386d878eb8babe7ca066fcda152a0a81a792afc9ec32369101516122782100b24b02d5b8693a712f4711176b348e2aeba7314a3a17d0ce11315412e54a6508937a393897b01d361b1fe9b0b7cce01806a62d12470ad5650606883872a55030827b5bfa8a05fba19c9207f113c99fe5985eb70e88325e5cf35eea9605317579f15b161f55a81b694b0a79b8210b2c77524383aacd1936ad36b43f66fb6b5e668205396b40b3889da25e21fa985bbc6af4980d9fda368507a7659785363c6537f067eeb596f5337640e7b3b1877804f21c14d76d69d01b67a941e76cbbcc3765aefb0a74565470e7320605a0cc009c60e57c9e765d2f835dbbd91482d43b86858bf82161e1c3586290acaba2964f3a9b83352cf40aa26442634ef069e2932a470a59aff725b862b880e7a75fd705ee50624ca368e8c39c27ea0588c8983a453bca30897a5785cce2335ef8cd48217eee4485abd47a0769a0ac99089bea59c4481b18d27c15d92e915285dc62197f4804ea3b3e79bbcbf57671dedb8678f1264b420bfe191f21e489675b7f1479a390d0c8fe2a801f4cbad2f90138259904705f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fca06dcc3b3cd617a3f433174053885f785193c8a70432ac83c37b60cb1ca407f22c7b577f4acea879a8ae700985028aea3475426a3f071cc5162233e793aaf9936dc625a292b84d185ba31f964a4003c3a96701c6ca96305205b5071c3a6540d76c14e969a8061146940907ef20b857245c6f202b8978a23a6c84ceb3de596c10bdabb2732008c6a224de0ad219b9987099f1cea007d1466ab0719e396618014787ca6b1a2680e96a85c949486105bc4357a93a3109422e52a44bccb0c8c1aaca7931973560a82c65d253c02b2171688648a2c9f93f0a26ba58061c8cf64b54f2930a2a4c064cceaa6d34c76ba200c382a1fd1b70119304f278a87a77837856c68a119ca692b8c39782a16ac11cb6c4d9bc7acf335aeeae65f01a50d4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd440c449b8bdd15a3de54a3c1a17a444cb469e0c1cfa347b5173fe6f4749658984ca0530483a86b773471799b9bd53faf04d0a3c07515a3b915964aee1010333127b3aa72ad964f38ea89a4c561e36143eae3003a19cb4de14fe88bc5b4c236ebd1930474718ae654f43277255b1f508721ca318d2d5255db804166d94cf305bcfc6c91465b18f3aa4a64b624bbf395a10967861ccc3d13a17706511c8946ff31954962b9dc68aab370baca922b4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2b526eb4131e48546ee449d8eb7b709e296c028c6d085a3d614b8856a6d076cce23ca4ebc192ecf14954ba06415280275ca743587492e76a5ab5593e9d15b10f829dcf73a94e040d8a25aa29616ac8a88cbb148e1c727b608305841b8f3c63e967843c9a50c43c3366293868f1b1acba037d95b64dd088e07d42f2d218b18eb7eda5a2506cab773444f2383a5e40940e4f26033c336e3c7b5d7d2bbecdb39180c87127781111b318fc4ab8c50926c932a122aa79766a48abab6707710c66030668540cb5c8d87272dac2683ada81dd20aacc3c01df6056cbd23735dda391332c773934e361a1b6e247711a843644226adaab77089a831e37d571517dca952a58c0835705b03187b77e6ac91d426ab21b997905fb658c6b7510ff5e45e446204fe935a7612a364414014483cf1bc844a6935ce351d1e090313a776253386a01073a416b47a943712c0b7afd130fe833041716530c4af95928ebc541961558a707320a5fbbb3c113e8b3c88b0c3b359c13ee24172c8b649b67c645e07400cebc486383d8ea2afdde8c104e69dab368f092ab3b3b85fb70c3036fa5925301430d17603902b1373258b206b814bcef5a2588981339cb725a5f38a079935f6a27578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1a5383897314d60ae0ab1a8b50d6f5de454a2eb8b0502d57001e6e19223a82ef2b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 8a8fc2dfe41f13693c76063bf85b294dcc5af350562458d60a351a5928019ce73d03bbda5798bcbc45ecf04170b4410963babb74230972491fa66480de29f461a97fafe6506905d447f426d7b32e24e71da2abbb27dd73f2eaaa73eb40314cf15f6892f43993793c36bab7bcdc4e3da3276d3073fe3deb01cd15fd8d1470e7181fcaebb5f57239a6fd9bc5ab0ff7623d7c601a3b45eb01162ceb7aed1242766c7ab7c0662c59b6bbbb3cc4f4c061e2c8f6dd305deeb66860eebf38f45509b335707349696c8a694b270b68dbc23bb8d60a00f515f70ec312f06ee0dddd7a4b05608f9e0a1e80e8336104736b1a38a01e311bbd09ed5ed1d885a18917c4891d55e050bd4d85619013190efbc88d9e6b09d1a5a8a1d81e9259b5ba2d2cb549f8722561ff0e6367067149ca18963c0e55adb6bca560e60d1947e60eab78441f8ef7a1137eabc54d4dc9e96ccf97868a3242ea9a063ce5b5b252d286eb4fc80c8503af57455760f5a44e55342df303ded8be48c039d617a7b88ccaa5b4d5ca22474501ceccb97e5c7ece676cabcab5e46de64ea9b5390ee916eb2cc756dea0021d14076e8024fd3006b7e231903a90f53b46730577a48d35ec3a37ca3b974944b7fe89de8216f774fc628c0f4c61fc4b90162278d37a1e7287f9181635631538c918ee9863b3224b6a9431e57640b777f7531ede094a6a2e386faf6ecb5a6933c1645d95ff4cf5fbacd89cf586d328b8219fd7097fe5777e7f0ac995d477867211de7648c353afe888878a8e461069e10a7c67b3eb295ba0f64535a8b7b0b98f71603475446a041eca8820ff5c9b920ccd397a732432c6a052d2557fef2f9556f4029da850ad7b8cf24e9ec42b00169631f839819c2b135b9796bf8bb107475745197b7c6c449ca662370db8f5f6ce94917ad9c16f36b10660945e27981916b497d074551f9d60a2a43b04cd2ca94de6e1f31a7924fab79c513579d6ef24c3decb978883ef99b349cb647766d4ca40302443bc0be7b7249819fd5b025ad7decf8f531efb47f3eefdf900cdf8fc2798e244da56853a22264d725f5918d197711ebeb084156202d795effc7f769022eb6c62bbe51fff8d636a813cceec56f1495121fc6f3d295af840189b56b8a5b9a7abebc6acee6319d6c2ffbc68e9803573a8046290d1c9f969900a129caf952d8efbc0c7613d11b956181f1b3ac3882c561125af9eba69ea4aafb613258c413faf12302135816ec7626415418ff1053555b5dc26f8f4777a5a8e536f740f041a8fc9a9cffd8bb2932d11a3a5be865671faf54f54060901b00238a0e193a94c9ece9dabeb902e834c8b5f457ab1739059b7366b8b4ccb83b3365aa85df3961e7cf2ff37fbf44a2ea0919f7c4d9d7ff9fa817ce33eb4b15f6f1a6b630c37f6ada9e7bdbe98c49ba7d5a706aa948ec1521f64efedb6066d10bc2033e926e892dae1cb9902b8f1de72016bb02d7faac33d4e62d1200a2c72a24d5acefcd2ed4af194080f587b70a0e68e6a5dcd676d92371f0fa810fd0560d69a802d4078edc9a086d87380ba4adebb29f6a4b1765f7fd7228ab5acba0b8a0a0263c47b9d8e6e01f9f8e4d9442ed720c41879ad8d9eb76e8d41ee2b9ce6d7575395dbdf8e01d9083a59b19eb7bbc34593dba21dec635d197546427f4b0b771458710fe4407b9ed53c5061b584d0c371ccb1e18d6e32b87b496d1834825c311d06fa8eee65e396252e0a17130a9c7e3b69831860bbe0920e6adc2005c8916d1776ae8f9d41d8ab0ea4a0d4573494be6df4c7c60764e8d0218a59a7ed2e6b98e46d6e6cb2fc273ffb1759632af9d23d8255783db57470cd85b133c174e922fe73b696c537ccc69da7b8fede851f904b6720ed90929e463d1ff6d6a0038829a82a99defb0cfe0f2d2fcfbaa9fd7141443d12689c6a5dd400aa493f3bd6d14f0471c157d63e125495204ab788dea1b24d824e08c3b62a8be038c0129b136e1697aae78c5c83d94abe07971538eafe93f48cc73e53f0f887fdf4c80fcf786c45bad0d09f4b70d06d7fb811c51ee0569af07f4e92779572882eaa75f5605eda9573eab68944cd5fb664299118109eadbd912f28d981a149b2fc6bab1b03a0ba4cc87f4ede29d56be67859c27404a622f60f7f3632f9746be3b76dfafe4a2858d1eec3ec15fbf3dcac42a97bec2341368e33eb8eea5e7b6571d0aa3accecca45 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ab25da2298917b27d7af1ac0941acc5b7bf59d1aae8f878bb0a37089b845992bf03ee4c8f1a58cfadfcc0059ade2ebe31bdc5fe3049e17f350a805c6f30479bf9eb12a46e90a5332eca4737df5a32fe6dccf3ffb5a2d60add75a62f88d5bf64270be8a954e95f1ecb1babac1dd0fdd39339ed45ac8c3ab58248f48096ee07693e030ae914e753731964fdff686f0a354703858c15c99f31ae9dacf81aea3d04d7e8d1ca5452fe58183e8d6dd666792da7a77bd927dc77793396e4518f00e05da7e55d95a33af5683a4dd1a5f6878c1e6fa85771a990fae6f7a38d34a897855769db8e4a9a425860fec7032dd9e96b665f57662b2bb86e46fc3f9b7d6e354c12423ac6cdc74974ad767d73e75f5739747433c3451f8e5b85e63e1b7fdd9f7acd0cc07ba26b74d5135f0497be998a4445c29f49739f25044cffe5e679b4955122f3418bfbac86cc24234ef2c7d966e9a7a03c3cc0ac5f6abf857dc2ae40ad85825757d2b5a59b97b7f8d6de5db1fe59e0e3c1f15491ff4cf64c564e50c389f6c85b8cd60fa9de1a55e8cd3b48c2df68c67f3497f439c11f8504e577cf49acfaf7d4a2b0932396fd2937dfcc2138762d8753606f95d1ded6975a242654ddecb5663ac44228bbe5bd58d9c9d426c66802b466b21dc8d7a23893a953033874d0a93626d0db6a4fa3fe9fbddfecaff3e789aae9ed3ca153fbe8fe8b95547df8ddca526aed5fe59639c59a7699296486188c3ca111479ddaa747f99ac825c7594aeed636e683cf9fee8aabb7708fbb14838db64e49194b1289ec49a1e81c66bcf05c67e1afd5dcb658d8dfab09c28d9684eef4e2aa03d9b8218889f87c5a5690f99a7459afdd69db283d2d986edab2dbe38addb971694d3b6aea8c6b5d53a686beaa479ffabc18cec4628d75a7e4871a9f5591cee482aa05bb73078dde7c21edea576bfb5a63031875a24bda019e6d8d64a30d0dcb39d85d09adec7583c34ab1cb1dd99a115547e3e4ccdf2a872e92eb2330a5f6c3d918226b7fcfc9fb4f37d8103437ecefee073a49d29a735a3e6f8e9f2f783797e49b8c2c6e46f76c7f8a66838c86364a788d3c4ae68edfca09391e8547edfe86ca2de31c5b96caf479d966f688e1f38c6196527be7844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d059ed312af8880247236a3761236b068a9a4edf55317e8841218441fcee3744f977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e4163e204ccddf8243f81367f4d979bf11f5b84eb5d5df53318463102938a862e4ad73559614dddb417e9a2acab9297381a77d8391c78a8e4d29487c32439ea7e5ad945b8d6e1ff4368c7a2b09eb8bb155d04c55776aff8673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357bfaff7f9c4ce8ba8d0355fc1d9de9c7a8332403a41318d86357ef9d309fab847bab1aa5d88935d816a708c6a5e420f3bce4f52569cbc724a53df1b88919f67aa4fe86c85e339863c8dd49cbf3dd797186925cf6edb976de613cc2c46beb06b39f6cf64716a76e67831e4198822d7738669fc778ad846f9b2780646579d3bd2ff6a8a87832d64e541e8a06e5733700836c6fe6a07fe7ab68b6ba229c9e84d765ddca88b0e469a79bb45ffa4a55547abec4f7496eb83687d690bd502d6cfb0573e828e92917d483e85a91488d1ce7b8a717d93b2c67a22fec6532f981ed557560f58068f3908e9d8a75e6489adb8791dd34937b582368cae0ec99c47c84c3cd9d494a6fcae9e5275bb27c998c5ec863f0e612f3a75952adfb889dcb5c6f3b4cd89d04d779b6936b73fb54ba8ec7ec83930f7cafccbc365376a3fa3c1cebe62b185ead8eb3b2fb7d150b637d1963601bdbadd755e3be7486f8cc306d9a05d688227f77515cdfdc7d47c93986433cfb58c674a752e8d6e9482f8a3b8a6c5798a833d97a65df98b31182d3aa566ce46499dfaf56f6a4edbff9fec16bb794dbabb7068cff6fa3d2cbc376cfec4e06ab2e4a73256b6e8d923681074fc1d1bb3c13ac3010fdfacf79d1ef347a48d84dd3ffbb884e84acfb038d9721ae56a540dbe8b9b4ba70c530593a58173d9ae5d420d63a7bedd375b9475c17c04d8c082f06a8d497768755ca932d2663637b2641c34a379ad8faa55c15246fc5a13a3963d4d36a1a1e06bb811c736e10301d96181207f65e992a66b7b3d1921c7f7247f34bf3951cadbaca9e346bde27887b61ab58fbbb3cd25466b3684b48223b24c34c6f1ce5aec8513717cbe5a0059352e4ac62eeb157a0ef76936c16db808572cf93adcf5bb44b1935d43abfca1b06d375f4d5a4d2a40392023a86e05796565abaa806d9ba0273e543ab03809c4fbc74fe4156bb2b60c76be49c7a1d5d45410627a85026a58152e2833b445a087a4f011befb1e03b7102ea4b17d6b5c4e3791f9c2babcf2471d86c720d412342529728cb560828c7286035e612698632cc054079ad2b53517b4c953969d8bafbdd0c09845191ab426c23a8b469b601c8751b02a4af32b670e6592f2e5b943924853e551bd80c5e717405eb2480da7a6ffab19660cbb5956546bc64def60b800c252d76c96d2fb3d22736143b144953a410653334c8967a367284e2197f5864c5e811721a49c29ca0e43e9aff5a7264381bdd5c4af51c51b66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7ed026efeb5b271324bc71bd73d09d923182fb7739405159d51ab7e51a0765c56d98d50fda35546bd762c21204f5661a72aa3a731a0520409c62154cf54243a32914a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6b917d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b1551d4ff31d11435a97a61c0f4430757c70a4d73402d94338765c8f708502774d36ac34cf85af4683ab5b36c61b04064705c68b578f7dfc4b9886140d28335e78c3b5ac7ed5bbc3dd6ab0a76a97858257c519cb57f0c949c2818c43962cc24695c5b3a6242908f20e14239930a9b8fee51bf5e62822f42095f37299316479c9371bcb567cd5cc138828ba5036799714dec18047c84aea562d67e375ce697536443ae087a5787a8de6314a30e81aea1312f3fa12bed1ce1fba8e637009bb7998d41a6654d70b2f9436f6737c9d118de76ccd885b4b0f3751990b93138a70acc047e4416fb2e21bf2359ab022696e67b6ac6b8045f3c826b81b76c4589a687e42d909ee5473512a71b6369d22877ab0f91a7cc2c01533635d896b6bd293f85962f05a2bf14315e42582188bb09f2c3cc86632f636adde80817c0681a3c8c313a65ad918cb12582ad1d76ab42643efa7ae8d94a4721b1f4bf77e8e47af68642112ab9629e0a2e3316d6185668ba373db4708add91ed47a5044eba47c346b7d230d4b324b30c6193184b493d111fd8362812b5fd1e19d4978672c505bdf9a2f888469faa040a4b3c5648929abaa66ec435d3173519b882ddd7474b1210368711c301961f4855a49f75656d356930c79ae11983a32a17d4757ce42a2d9e26f6a77475c12056a5378abf7c7cf097a7fb23badc4ae929a5d1eb46af442956a370d7f9a635926859e6099d2b121a807c107cc15ab18ae4634834c22144f689e92000829a4a9793ca767e43d707bcb2e0118e810b32f14007231721a5a1f1621991b556b70389bc8652b56d824e070a5f9552de88b14df346d43b460807662263769ddc268a78cbf4c155e46484c8e02087aa6493ce73b845289e9499d0dfc1b156621683521dad7176de52bc294770ca02ee08899b79673f562c5ec68157c758d4726cecb986c1355444d96402bdc20a620128ad3c9407a64537ca855f820c7166800839e32b5a0b9404ec4f375c68336c2c098ebaba5d1865a99a8b45993533b0651ef97477660c48ef40ea7261bcf9c43bfcc740a0605765c5cd84cc5640c92e533a2ec923a1512ba57d11924542f53329598598a0717aa91986901046db1c763f25098103b208933085b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3cabc04b7f7ca57072216c859e73183288c8fae0a71b98a2366a99f276c0b68688759e6b34d51a0f5fca2c52585894a5ee52253d6f963ebd1283431b6d681065426a19157a6384b27bbb0495cb8a4f42c5649f185601b4a19511841e775868c0ef0e010a8147a743285ea16a6f01323a9acb46c1418418c0b94793617db9fcc1039b0060c167052b3766e9452b65f4789d9123e5e299c0e440986013226b63db7c78109622eeb8880c351c6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273500dd7b94b28b5b650d90962962bb9a3ae96e70d35723217f3f178cbe565905124c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = cfa709be046d7a5089bc89acbe7cf9c0d995018315a1da69f28fa50534d3a66033bd7f3ba72dc7cf4a59c5af2004c5c84847f4ba0703bbeb0838b566072697cbc4f83519dcc80d4dc57af1d4287303f0e1eeecfb571dceb8960be0db46e84feb6418af8d5232751d46ea9e807464c5c046457c90a2c966fca923a849b247b0e597b04984ca27719fc8de2e7a88884c7bfd904211c691318fba488f0167c3ce3fb3f09a576e0e615d9c4025fabcd87f2fc381937bf5e5767c929b489957c4c902aed8ffa04a4151ef4f7b1fc24892b8417fa768c5c4caf89c1d7a4e2c0281aee2deaf5eb36f1a5151102246957f2d5b5a0f84490a7da013a4ba455337300376be4745a212e190a8319486dba5a491798ff284c7559d5ef4c22f11149688eaed6cd5b03e64982e928349a85a8b10e9c0e8d919877964faf74bccd45c9b8358dc06904642496d5b1723f44871beb9d22c20fe44f4f522e69cb69a8c2a4d02c813add14c7f3a9b813654343a091b59df148fa2331730e2b1bd620f8c4d2d7cf5cf2f179b4e7536e79673f75f26fb97f641dc11697ffa3470e7a51f2595d25534d0d8fc2951e566b825bde2a2fa95ce89160a245c779aecbe727c37124d7b4047f7a33143d89c36bc1a8d6f81ce89c11dcba1eefbf5d9cf516e96a4cb1fceb8c32b2783130d4744066a39a0e0c4f1a63fbc1da236a9b477b6a3602da150e02f0b904524ee76e427546e0b4c784f16eef19d2b36779db24b87878b8bfcd17244a30d6028b8aa0e2311d48efae841d37e4ffa0f7d3f2b68a81dc91ca5d4414a3c368be4e05b10bb932c2f7a5fd656ddc67e51e7b3b719f9ea25e3ac18ee56c53e00647c57a8f7b7a9ebe219ac62e0ead2c51e6f0b8e96803dbcdd1c45a7f8fca47b72fcd948c12d1e2a54e2c89f9d3f8fc9d5869e354693229a1a2f01bb36f4ccac457acc170f89fc02727c11aa053c2bdb810d8f4806caf8228b0bf6024fbf16b4c7ba3335a2e1b900db84b612f3f1ab4cb94ec7f9123468b282c02502901258b00e7bec13b8cb7548ac4eea609aa2bcfebb88e362ecd6bd971ff280ebe52dad8eccd2ffc148b7a39c572635fec41b1d4ed932701384c749874f6a53bd975901e17a1a8d371f105a0f7c61980e872e8c9b653b47031dfc70b255cacae5753e479f4ea2a6f7760af10a5c3c98c4bca1b9c3bc255a65d10a5a9d2094bd7ca335d43ae0cc5f9e2b401089fd05dd71fda89a860190924f47f79b22dcb5a9014824cac41cdd1b3ddce29aea4501bf061b95a0deec5f11cd2651091154b9ac5cd594f259727a277b24b5e5f560c63c21fded496ea84f4c808787ec84190ea23aeaa651d2cfb728dce2200b7239eeb48e2efde5d21077ce14afa47f3da8669cdda62ced1ea7fa0d200854a70c5b016b7258ed36216601d716937feb112c4b9f90527caedb744be654e3485bbb0854458722271f6bac03689c5792e0e2903f1985b27aaf8d0fcf32f10a18112978daac5b4b94e6ade015a23e0873a2dd18faa90606486d8d8884c2d4ec96ae81d895d39e40df7563c625b3b2a2d9bfba74f049e5a6fb237988782eeffd223805904f9e90b7cf65bce60f3a85d635c85156c4f7797cc9373b37e21f45f99624932c1073a2c7af131b6476e1acef410900bb9228ebb6fea2f2a912a2a8fceb80d2c5cfd6455ae7c6ea1b8c41a27eac6e83c565f9ec5096d505b0500ecd51873adc56186f9d16c8ca63d852d65b766d41dc433a63528b2809890f085cef8f6df26bf378b90d60fb01cf27c4bfd7401e2b923de0987fa04580169243c4509175f7798b901cac5a1818a43e4e70846c6d9de333b730b875cfd7b756237b87ce7f1b50414064ca6be999620d90a056f0f7587bb9403256b33751b0ce948e294fd4d7bc1c852a3386614e20e9e9257d318b065668a4893494038979593db9e5b9497ea660e073c0b1627c3bdee1b81824e6e814718974ec3b45a693fd1c10069a7087eea71482c47ccb01a2e017235c78edf0bf9258e534b1e47b1ab84cc120f83b8c8fe3b56964b28f9ffc9b654869e4ccd65329749db82334eca6e83d330480120a1c3d41d20181ae60001c6d5bf9037805fd5cb45d5daa5407fbfca5ec89a02cdd7ce5f0a86b7ad9b7f0966bba8975d291c06080d3d648466601d4af6e03435b45da8158bbee2271ce4d092f59515f40bb58d081abe51ab8fda4404b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f80c63dd6cbda93b6cef7e9fbad6bdbe2ad3f18b337a3d6ace66f5fb38c5edac9c8c94525c85961e14a7618fbbd86dccf9b5ac787d88b0cc80e13d4fbcfc697c0be4ddfecf7783f5eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd3fd7c76e8b7a68b92abc870b67fd2f7634b9b37902d39bca04653fad9a0e5fdbe548abb97c7a1fa18c34cebbae3987f4b3c52a60d6629159ac6875276053908b389da3ebc7e2871761e69b6e8ec8d8b5f52854a3e644c5d5d4675d688ba13de9e78a79e77885235e6ffeafec9946aa989ea634b6ab7dd44570d3acf348bdcd859567a74a7b735579fdf8d0ce3e467ae30eee025e430114a5a60d3b42bb438468fe637a69596eb953ab7b3e4bf8b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e865fbf7135698e15b8d9abd778ada5af1b7db0ce72aa6a4d6a3dff1045e60387e876c580a8df4479ebdd804b6514ad9282ff91f37d6ab128905663aecb0bb31b5ed4687e449e1fc33515ea2ec5dca81ace90a4da8a6a355c2ea9c85d5491ea3b48b5323cc567eae9d9fbdb380fe5d4c95e452bd34f0f65a39ad6fd922a3c50a8566edab03358745e8de332f4d1112fbfd4839ae7b6745c66aca80abab92e336aef99253b40a8affdf02ab70fa7f3baccb1ad563ad20c5eb9bdeae564be2404dde92adf06ec68c16d4c7435d909e3e7f8968948befea297a27a9fef1b5377b02653d66897ab5f6cf51553c26848207e74bd9495da5bd30575d358a637a5fc31c99ba7bb3d4c691eb555e4b1c208dfb52f3c5413fd16238861fb650bcba24c1f7026fba51f5985487ed3fe1375ba5dd7a06bc2ab048bcb4a78e6d3c749be41bf5ed992733630b8c917f89960273740a5950728f4aaedf908e5fd334373e8a575d5e5fe96e5ad0cc95bf2c761ae577b9ef6bead43e03f5d33e0765d748c409f8a44227b8f55838b38695c5e23ff2cb9bfdd7cb85239d6e9ccd3dda468a15de22784e7879f77e2169c642efe6a8942a2ce3aee97300ff4caabf862058b6e7dce6f34c79ba30d85380ea98d73d936a8a595098c8b19820ad9ef4755ee021d69aa688bfbf5ac4ffde8c53639a2bd573c8a420c56e9167bd11e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fc7dd52b3ca5e0e729935bf7e4bb984576f2acb7466d8f48f975bad539b236d568dfa34cf2974d83699761c95405943a7a883752eff8ae79b4d244bf2d683f7cc7a544ff9bbd8b5e92fc8b3449548634ff34bcaf0ff5a41aa84a10af052f486f89630a783de508ead24ce4d6906816a849810a5e72714fed088fef26c31282cdaade6c9334a88acc9e7b88ec4f173f71974f2c24541065b5e80f4374ead853d478625a68f729af0c1d8fca4fcc4d62744fa65805924e221b9e7d72fe187d3b621179aa8f7b7cd19d4e7ed787f9a5f65eaa7811eb6b73f90a55542c80a4bfad64677467dd2cef785e6bfbd3ec1f3d46db56cda0366d4ef658279db3232c675bc0bc97717ca3ec7ed4f44caaf2bd7bddc90aea8f886594f98d4eae758e562cb63d1bf539eec58914673559da4a87b6ec5cc77c0cd810627aa355fcb062ae648ec7cbb49378276d2185a7f5ba3d6d92f633e2b7d35a39c135ca5c1c5c1bd8dba25eb91cd6a3d7144ecb23e4deb05a164e3e124bda6c5cc7edeece301154e875493ff173d7498dafb7438c54d85bcdbf9095ba859a4cb2d77bda5e6efda7ddd1b9c45592682bf26e713d8dd0aba348ee8bbf47dbd4b1a50e77f3b9b2499031adeea58a6531579f9cee0c7eba4ca3a57a5b6a5ae6eef896a9f78b6f908dcdfe1adc06e75f240f34d1e16ba51c4eae7077c3ea8f6092e6842c499a51ccc4365a86416df4d2b85433fb56e8d3cb91c7fdd93da50dbfae465c91416bcb19e90be99c56f97dc065c7bcf4b421718c17f3394a3684cb0bb834749f7b4aeb4f833485196e0453d5137746ab39650949c8cd43839fa75b0a79ce4d66bfd9149e75f9756ce3865db6c77468bd86c58f6931d47d13caac87a61e2d6b6a6a8cb68de8a0faeddec05aa5c45f5ec86a2ed8cf4c0f5f0b44a5c94a4dae9de7f6b175642cb49640bc3254957c2ef501ce5d17d4cf97137a59dcd6b69a861bdb73a0c739733dbbc5de9e628d85b56054ad4251def874aa0051ea234b544d7a0dfa60b1d5bb60b8bc95220c6cc96ab6ed53eea9c7cd1715e9c29291a361b04f205cb094ff888642827aa19c64893685ffc004b6ed9516f6638b9bbac94404f91c29a4d5ac6a9615179798cf6c486333a7641846cb49c6b78425aea240cd5f98ffaa826aa3b7b643a0c5f4c3ab4c21ea9081e9439445c98277b9a507bbcbb82d31aced3c378b017f7d62270749bc1901ee53c72953576125574dea727080a659bca4f007b6cf7c9cb2d0254ba9a293290c493654d25e7ac0cd88a6101b12622ba2627000de87d88e4990ccb9cf4a08918d044c2d52cf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348ae706f400a28f0b1c9f8a40d8be14fecc0b2f282ca8f5c499f2a3d16bb7501003d22965b7e33826d343f72a501e0b219bf868b3e47bd4fbcba0d6635421189c17c32479aa5fb0abc84549f878490bfcac6934a6393a0a14874a878d65aacfa3678704919240d31e9911fb703dd339684d5ae6090bd3478578f7a60d1d72da9d70eca9266b19c79115322e626ba64d52d26c9a655f1325aa63881e8800e16382a46865ac2cf015abe3a420ecef1290e5a2836500176d7b6d54868ae3a977cc26a40a2c20ec3b346c0a4b81549d274a7bc6b446d6a42512c55b9823d745402a630065297973b99b569952aa9a66b440430d980bf4944cd66513220f13964a30e86f738a0eb1aec491908d2c07a35591a384d0e560af91c1f7910b2d3f61e69234375b9b6cc017891eca65b83332df15773baa489862494435538db956d9c09660499d7e343c7d68fe082997b73b69705b9498ac9cd989efce26f4aa2b3d5e7b445e4132185a4e734175ee4b5b7cab33e42ca33096755473d774c758b3ab1b7687d62351c3c5251653953701c81e2cb2667c885e75c814f375eb946adef027f78036b28f4151f1c799fc1556de38bfb2ba996db3e3e70b79be2614b073cbd150c04313013ab88c477297ee615fba0a9e00a50ee3b0f66498ba09acf338b7342b8670c31428f4a52ccf9b4b6dc98667ba43792863661738e63653c34b9147b60ebb21ce89291891bb814096d662806d1d012481b922b9c2fefe9a66b919823970be95bb12c6619498228bec78db0739a5b1c93654a2aad73851355a0485a52c3896c3527964e88727c3805eec01a65cca1fec8466aa44bbac56e53895251892b6355c5e39953f680683ff72e0968867b536c11a33470f8ac74870d996557981711e5d0abc65c671f423ee4b67771055952b54df8934f0b6980779abe207c4f8ce1cf17bbbd90b24d1ff875109366a4270202036a0796146cc8ba70712f98b042b301c5143a6143e01b79b2af3a944100eba87da1725743c370d85894892469c00a95f3866726138c2099b9b6c47ce9b9630222c7656623260d8500b4d7752b6779af5b5b858016057f545175f61477476e3a02aca3d1485e0882b305c9f956908da84ebd8083ed26b8b2b8b50a347a4cda722bdc6ffc2b9043491da64b0fd0a39b7f1550186a0038e07598d6887e6c8c2800288b1c9a45a66233049d77d912b1fb50fc119b0b7455c8d90a3edcb046f2064d401c8f108b833caaae5573a10b9fd1775ab90226d8a32088ac614e9b20737c88dda963d0e77c7c592179b4030881987421a886ac7a422c98b6d51c53d8c1027c84881491994cc84e9b1185b3425758bbb1e305a1103ff6989c633a5697a97e5dcb94e7191d9a47330ecc60acf85083559d507a77f7033965a0859fd6306d27c0ed2b35e7b3444d957a52010ac49a8851952f6061ad551b7c74814606510a0bd19d9ee7998310c74ef507902cc71103134a411f90da122fe72fd14448dea00932977c0f27628f092da3ac07d901c2c3613d22d48ad6376ac1d008c7d19a31623ebc616e4fc3887d68c033bc3ec0e5840d415f6fd2c15355c223da1c45289315cc945aa39ae7498767eb3a6692b2a0ca6e7bc73a5d97644703aba392b5d386849f91bcc7f5691f295a267ac0c1fb84e5e31c94ab020e351ae410840e4198e417b8f397aa33f88114030b07d5c702c6ab64bb7df7276f593ab3d133232c919dbd06b6df756258b25c7132bf03c62077084ce937ce829b0172810b92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b143c4467b507971523509bf97d2bdd733ad9eb94f312e4226d036e8fe827a205333afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 9d9882a27b742d5b881f0d90337a252784a2b4cdf03ea7d09f4fd8826f3bf67daef9c48e0620cfe84925520467c308de3699719b08e551d463ee7d2bb5d1379fcafd75912c5b64008703fb7eed7303e195f476143b3a6723c14ce95af85df17462f123325a2ba206a680edcfe4c5d1ba1f7d6849b59d1a95561f12cece6f7b39dc6b1e9f9f42e56e9544ebd21f82b0254eb66de5210b9ef3bf00bd90a19f26462f4750c5d67ba46fe11e03cf2490963ed6e7f3646ed23898d1e87683e0252e253c3c3c2d767f66c0005ef9fc05eb66a8984725310e03de86edd931a74f7b0fc31b34a1019fa8c25eb5c9d20e4847d8fd3914547e2d9e6e58d2ec10d0d3ef5f6a00622568148bc0d61157d3e04108625c0a00330fb1911f6631a1336730caba6d3fe420e364c6048abdc83998b28c43e168b61c32e23f0df46bc980a915ca09e8425d9bbc201af25f2bdaee38b49123bf71560c32c0b033e1568aea57462c31fc37879314674382aca847be3d60514124700b07b0e86ae457cbde316629347b56307f2d627d6a28b5c4b1056d9f1f677d1658cb4c04f4f4e7afcf514c84d7ee8d0671ef7f502579435c100cbd96af496bd2637f8368f0013ce974ac519a32970ca0225053eb8b62ea4de0c37d443241e537903777d476f6f5055db5fec5c867e334d2c95be5aac9eda6e7309f9b96059174a73bb0d623d583d7fc47741410d6edcfa0068cbc60ada07c34539a6c00970f86e571fd2535704dc96a9067a902c0087020ebdb815dec49ff645543fb593e66a697297db587835920a519dfe468a0c397f52b7973a26e6705d88346c9937d022a9dd2f2f661aa609a6ca388ecf101a52125a63a1c031fba8f9833db93cb6e18e9aaf77055af81c9bb66fccd5c6cded6c0f191a6ca576c3960f2fe3b8bac77a8683e7fe27e7018852ddfced60d09ea52313517e2844ea2b034beae96560a3ea184145c6c30737020b0aa9f0a82c6a09abd789c9e29606fa1b92ed9b535bad8d8b19b760edad4fb755e56e6ee48fe7e955a176ef4954e619f93ccdf800f6931179df4879d397d9286933d61f377262a732caada2ce3bace41738cb2b939a73b0e16a6bb6563a7204fe8cd1583935fe6f6eaeac1aec99ba155005057de028a6f18a91ddbea4f3aa1eeb52842715b8196463fb082e523e3bcc21622f087dceb6dbcd9a13dab218c88826a79cfdfbd76147de5ed1337a851690e6e3b5ba8c994d172692d4ac72e432c0a0d50e2cbd59d11c193b169a6754d66e8d855b89b0157bbddf8faedb0192b2faa665981ef8c767312bcd8b2414f0774383949db885e68a79ad88191ded52bc0eb175b987ce5b0997703e31c3f69bdd7dec2aa3b813784bbec923550b8bc3ee8267190b539203aa07c1000d7f0e1f5fae0d1d0e5b93df78d2877b6c94a2acb676441e65c709ede336575ded7aa9189997468b5c79f12f43aa3eafea5c502b40196ba8ef8126bc24c2911a1afcc531da7c9692ac38f57efc844d44a038dafffac41cfeea24e24c16c475ed6f84972bd89d22d6b23d9e19fdd500f8263e7333eefc061ba764d74a7ba016b7afe7f5b7be45e01d3b6edcdb6ee47f7cef19935f53094cbe532d614cf203241707b361366400886be6d0667f6d601fc675518844549a64de3dd9fd44e553726953527f84e92c726e73c4fd6cac3db7b526b05648600507e599c13ca541767cbd172211547f73793ffcf09c6a7688a694c8431bec47b6169a6a08b124157aaa0bb6640d8d6bf8bbcf8683c652fb270af94ea472fcda30f004ecdf13875f6144701cf768a7fc950f6ea1dd4880fcb538fee5b80160ba89c8f015611ed40b6f08675d03c37dafc1ee0b682b3de7729ada805c4f3c2231f81b023ad5dba9396361835c8b93d094c85c7bf87ac063e4ea3de7567cb767440e0d9c9fb14bcbb3bc8ccf3217811b5c8fa1fdcea680bd555547dafe2544c3874a0555ad8540096d1f5013a663bf4dd1b549ab28c4f6fcb01b854167b8be45fb0460e3339c286b0103179f25bf260be3d911668259ffbf0c062e69f6c2035fada24aacb86222db54b38df9ca621c45e0afaae0c5d89fdae9ffd2f1b4bc0a23ad088e7b6a63c962aebdceb8b1897a277a4853a5285992c3b9b7ebc72a98e787f4ef5b443c58b81c3510db13a3e7c3f5a05112a9ca4ab5eb0b077aa664cf9c119c4f76cbdbc9cc7726d61 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d809438d9daea78b897b5f85340bd19e7e6de8e5e3d42e68a1537489f5f256eddf49d4f4bf5b5db1ee5a3a9b9845eccf287776fa8ddff5bb7ab904e0feab7f148a9633546846b672cda9ab8a37c8fa8eeb76474e7975ab7e16675a96f6f8648b615d66a4fb4a5c255a0a39387b03bb806e8c9fdeb37e488d4c7e75b593860f6c97d637a2d886ed3b933292bfccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cbbebb1cb746bcde294afb2f2638beb16d30d476bcd2c335de5f26b7450f8b5b2b23d332dd9f1074dc10daa5fabce6c148ec2a0c4aae3174be4faa53ca9cbf297690857e5d6f8c164bde8513db0c7c9621336a9875946fbb73bda9774c086e5711451f5594a453e38792d4c291ab7550aaf9824d9d4d7cbef7f7ba689400dab73836d5f03873f38566421a354b59a3b48bc8f63ad9519d932af68d0aaadc6efd5783bd93484adaaac7853c99dc3ba18835d2afe8f14bd0768cc7d0b951909825c988648f797f68eefbc654380e661bbd4ecf8abd88e24e0f19669aef65fd817564a4a4f4038eb5e16a69cefb503495a4b6b680a08a550edb80ae668041aa120c7a363e38ab02e56cfef93bfd4396dcc503646acb74b946024fe4476807c058d72c9610e3cbb51af9ed724441acfc258659b3a9af3e7e69a3057f98378424b8ae2df3cce35fe36483fb293ced5eee6a4881f6815ccd013d66fb7099efd4931e54ded570bcf2facba0b433b9a13e4734fc29815f6514e6651db690cf8ec268381033be7c429a8e418b7e2bb63d30b570da588cbc36dc3798c6508eff05530b9043311ee82e88bb3e58356df4d8898738c9b3c457faca42b9b81ed7c4118869d5153338e04f70006c6be294b528c779bd6c8ffdbe6e2aab439e3d32b8ac45226f82356f00dfec812033a4f9667af94f481e8d7fa2f45bc4ffe04343971a656087cca8ce9bd3127d13af8e6ba745888a4ad52ae67a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b5ff879b7f7028d4a1c629d0d087df1555ea01964366d8a6ad1b5bc62d392d43bca37dccf9b7fdf3d68b955c4bed0352b3f78151c471662fd97bd9ff2dfda25619f3d01358ab1b5f8b7bc687f5c111bd4c661f37301e9fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494b0ec67e33fb9318dd5efe542dd59f2186da24747e99ef646638dc05de784d9b581b4cabcbcec3deeeca8f0d588e0732f76b99ec844032d99ef65c8a9ef4a661e78a48bd542c4ef9e95d64797fe32d2d8cb9b3986eb5b510fae8554ddee966b0d3ccd9932f60ffc96b895ae81a95a41f1bb3adbf572475b3fe8933fe49d2c965678b95512289cfbad3da2b159b8f2b3535f4d881e8ec204cba918db9a8bf3190965eb76d754368955c0c7929e9447c9fac78e7867c1b4770596047fa820c03a11caa3c2ba48121ef9ad47cf89a3df22d6eec9e18343bcfd06709f7435c6d6b14d955f939470eb805e38a751bc8a1853fc05857eae658a8a7cad729373e83f53e87f8fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ee8fb23f4b67972d9d524f5e9168cb232f4f3afd69d4bbbb07a395d3633b71d8ea238aa54aced75315e9129f62ff4d52cac4f15647c0c2ca573efbce8498eb45279dbb0845dac9ce5cb8d7666a76c3ae8dc4a39a09234095e4f6ac769dc4d5584d9473705477c2373bcaec3eb1c9e1e8f9cdc68ec2cd43df0a2ca0f947f04323447d33f8591761e4cd93b8dc3525aee8015cafcf6bbb996f6e43fbe2f98be2a2ce58cd473bba2b3d2aeba488859d652fda668a6be003db6d86f11c2576be6a956556f1eab6541b65c956bc51e11e7306873ede094169a956e50c9f453834a6f5b4f4e7bf3d644284bbf057b653d40479cfb6367aefb50e6975dd839101ee888cc35dbc56ea7ccf48b5b756d10338cf68c4b8faf81493c9c7fb4d1504ac3478ce8cfa7100cd6411fc74bf054d6a3fa41d234eff8ba5507fb4ebd5fef605cee08358ad5bab7a0966d8b36b2573387c587196b7fbe1e47132d6b3bcaff41e735b47aba99d28797b6382aecdf63d78e7dbbb71d47ae7c43a63748a3f34873d19497c4a5e5fa8b4ae5c588bdadcf34f9a74ae67734d14b7f72bbedf8059fa51188fe16e54b22f88a59ed8a92d72188f1b687222500dbe642699493dc08c97b6a13e640b51f2173cc8a417be58077803627a7c9bb2a7b96e9596e3d96c74f03926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789e02664ee7552ce5b4c3e16af4299c775a4dc322ab9ee16d65a1298294adef821e94a5119e713175b69f03f941f7c56f565439f1e24f663987d65b00bf899495d5c2f178812ee73387a1627f98029344928e5c9100c50f87cb6f99b27e3ec7635c6b132e0b81229807e4d9903a2c5ab8985ddef435fc8462f67a6c01d2188d731412262392acb98fc49e4cbca7acf522a8d385dff01fd02c4be4b878bff659aac05a8fbbcc1565a53cc36af88b41a1a3a18b04c728b1b66a7698be968db6f0bb00f1665088cdd4e3464e34261e72748705b5b7ea5e4c02289365a56739a4ee34a5dbd5509ec297c12a26ed1116929a8eb4793248bb78a1c21d981733ec874eccd2c9b4bb530c4b6b10e136e764af55059da3da93b79076aea089818210bd076e2a8a49a5032405a857baf295e7868bd82c958c90474bc4403e62b85201061b7bb6ac533e96870ad0d7b9f8e6a835e6c6cb4c8437489448a273e576b91ae8062e411593b4c541098185198e49c0790db516adbc2852a220725a5d50d47333ac058325b61325840634140bfb7af0110b34fb408749998df156668634b775965f05aef99713d1f5bdfc5302337b1c041448f5b09af8c5560076ae90ea3d2dbc39bcbc8e9ad26981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc49199c2c35e35d6107ac61744df910c021591d6df53e4358487f26b4d4060958095fe464ca2703394d885625806106ea31173017f4f0594550bab828993d55628aca5955f61f4e4b316a8aa9971c65813949a16828b5792ad841772aa1b85314527ebc2e6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485b8064fc585ab8c2af6212441a763540f7af3d8a8620c6cf40ba81a914ca28a8265248673d731432ec9c70e083be49816098494e6994b385b509397198e2a50c76a8949c25ecc9849ed45d59c966444313d5f0419abc929b8ba51a2a49589978a0e29c680c07b9cab2be0035a06c18d561b9b0e862a2957d5d41a0a63c4be99c1d50f76ce57862b4f61cb42591f17ab1e85c1ca2dac3f746940c001d64d81dd0889629d60727d5a5fd8ab7549b439d66a30316883da6455dc023e6e702fb4742a82a101f60cd8f3a29d3d88c7e418c3d30803a541d6ce1aedfa540371c846c672753a858b39b5880d69b8d525c6d57522bb6530cd7a4edb7730cf720541454cab59595e8a5d6302249300a6fc2180eb31ba43398a2a18adca92af2a686c20454fa8a1864d73c0b91167b6b4730c2b67c55b425e92c663465b7f7a1d2163f7d7a8a08a962fa0149cf2ba8c4066cae7c0a22a989ddea22a5311ee5d895eea9a5416739f810ad5ac901471a72aa78956b5183b194b26c361219401aefdc49b6ab481be838f85290a0d96060d68e5fc71358a924b95225070c6283b401296698310bce2f1b7c8a531e84f625585429ad3394fc04bcd8a200834cbb9c9b9a8c83601fdcaca281a93f47c6e32c133414ce71f32e60fc52b4c07a1402c3932056fc3323ea2241a6484e6a074676996e5962867a61cdffe8811764953004cc9c3697e78ab5d156cb952b1c53ec674781792ac831d6e20b5b29c3b064520fd5968bb351a401646ae3267522c234a8404b02529da182b473051bea4b971b170d03aa378877fa47bb60f1c1e3519110121bd58b17ae373be2d21fc6d7ab2ee2085f4a194fa7717ec83f6c144e256807aa921c32b843aeda0a5cf85773b77efc579a677816cc998970911152d091f21733dd1c0fab31808f2a3a64fa783efc2e4a252b56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277961e67e555cd6c7c4a630fdd897cf61c9c5779594974088a2b415806b520503ebb416481e87a062582a479b3e05b9413aa2c7af59c5a9c5034722f43032f0d6428f8425f4cda38876ac45ba2137fbc56209823b05abbc00aa9e6a307bb164fe0413311f22be44244aee55268da3135ea5996f7cc3f51856610ca68310dfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9369ffbf2275f12c29cbb69f90a8c881721ce39b49dbba550ab93a2c4c94bfc669230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = d461713522c86d1f49f313c57c953ea6c90095c374b53608846b6c9592d574034ae4e08e082094bc82509f773b0b23980c27b18788cbbcad4cb03f292f7dc1b40dbb9f9aac870da48878f7ed31f551e9e0d1bbef739bd15f4f4d4b1ba219764ddc5031399f3b1cc3c40afe779ed6dbe177e47ff0696c76379db79749e608abdb4d8d7570bf26fc7a290061744e2b907b3e356dd503f6f52efc5a216ec851f4f88f65694556716e675a6480d7358de0d1fb3eab5fe13c803dfdfb8932938d1e2814d58bae2eff46bdc2d0032dc31b80fafdc9ecc6ace570da8458b3638bdf79c7f6fa398ba6d9777ace4404e2403f3410d23c79cdf84d32dbc30e255aa6a91062527de340208c0181d5592a8f8942cf07a80dbb1f14a3f800454dc80abcb555878bb1560cfe843f4fb5ce7d56770d4f7a4f36d20ffdbc6626eacb77bb74edd5e8d1d2b6021efb1ce39a41a4ed8f330eaf10c0186454919cf8184241b42b398d8d47208d3ede12d6568ac878398a3144ed985b5637ea55d498ac3de56339ccd50077c6ab899dd34b2020d8f8387938f8486ac586214b024b54b85aa1b1a60bf73bc07a24af056075cf89f5a985349a573a718e66593f470a48484c1f22aead53fcf5fdeb98fd4d3f3627b6be715b367c1549c7724afc6deedfdc825399b5fce1d72ea61b9dc65ddbf385d477bb253ce75f935a4f56f68c6990a3f20239746ea8e7834ec5372932893c3e4fe93f29d28a312354dfbe94167a4dbd80497f0fad7040e6ed69e93c9f04d254d3a3ba3ed743159142c82b99601cee295cc53d9bc48ee8828d1d9ea0f4c0956df9d3945e13ec9a311da1b5c7c6b190dc5d289e6a7b6e924457fac478647d71c9f916ea94365022b3a3e7e0f126bb47395f8311f9367d041a97395fc4825c89538a5fed9bb7d655bbbaf9d92cb8ef37b6ec71f20f0086b9d86d54766e409db6ca94bc3f8f025d5f613002e892238370bbbfefa16f25f7eb6be517c8e2870a2a708fa2aaf6b4f829bde2358aa374bb3557f796626739512e7d6498ed9dc6d4883f2bafc671bce7ba13ed3d0760efe85d465649b4cf641c70acaf845bfba0b0187ae02e68de2f5077140719163f2385b9e17175613f3c740ba8036ff871f1c48504a8c78b4396024325d2e4e062aa900f4a756b5339768d9f6884d3ffd96008454ec582ae8885e2af1fd9b732bcb6d6d4c4a790eb6bcac1b8b6af66650c345516d9b1dceca4841cd7792ca5271ddd4210eefd69e2e47230576e522120f4d768f5f0a3a9db569dd03cc7cf79420d0d414cd2e80569a578cb3ae3c73abec90daa76c5099c2168051a2dadac047b53c53775b99cdc06aeac711e6edf4ec694b4fcf82351a1f4272e460214cc44324cb94d2b63e1c8fbeacff3c7aa7c96aaea387979e802cec66846b697660aff05e09825022b91c94a842e1a6db46672ba9a27af6efd816aee4eedddfc2301bdcd5e359c13eb23e4a3100f3b9f5686c8b24ca570047ea2a8a3999d34615183f48c121ca1e4f8e0ed3bf554d7512fa532ee23dca8c532a6f23520723dfb97c5dec7d00f4e4ecd40a7c9943bf9f5c9f3a544cd9a837f41f346933eeb1d327effc39967ea4e3f35804e4ff10bd298bdf0e3782a64de00725a09aa20c24832f57ac680ab62b0d0bff68764486d0cda4fb56142430df0f123d02f83a70a2ab2abcc1582b8653137784435dfa80283bd8d29accbee3d57192be70ccb4c5e3fcf3fdf5c5dc127352176fcf7c1b614a87ceb0d9ff861d653b798381b87b96ca02fdff075d454d6e95c99edb7d66b89e423274c23abe0b21dcad3cdaa3a7371c1cd6a88cc9694107d5aa3a05431a2df1383f255801b2d7af9f6c3f6023f479fca87fba98e5730f4bc40f0da2c9019dcbef396d3a35ad092311b7368dfc9495e1eff80622eb8f6047213b53e72a712fd3bcd15971cdb61e1ce06f10d0929e7c6d61f8d8a280c27d86d4a9c129d8181befe173197e21d9cf702a04b5cd334f4d698d18d89e48aca65f7b2f459fd0aa9979113a9bc7e7e13ac721b00a1fc55ad7deb81b7aed345d3fd3cecb8434e7a279ed8b255352b142747d365b2fab7b44e0bb6c00bb258d7500ec7c2f9b2e152549f0f90d9aef6707146a662874dfa7c7004140e4b927e820e896847b34e555e98cf49976012b59d027978aab4c1bbc6f3eadb044eed3cb3496429ea295e3d4062ecfb19 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ba45541ce7b3de134e6b27d3081dbcce09bcdba837f23566dcfe928c99cffcb674cab9c41c3e51fab3d78177b9126c7974ef568755fda075965baa804276859b19fd9e4d95b5e3a27943776da652636eef62a3aa876bf58c89f9b60fad6ccad0e3b38011c943310bb5cb24791b7ebc5a2796d6197192d9594946d89d88bfe986d58dae6c162e93838a3d7306b31208e70efe528809d73514a403acb76cef98f5d9fd65b9da0bdbf8a4f438ea447a9c98e809ae8a2f5c3c1b876b3ae94ed28478fdecee98a64fd797a0931cc4a18777e5d481d9f9fc0dffb5f5a58635b368cbc8c25dc733550774c096e795939b74e83a23757c2139f7805663de14a0fb0dcf1005e950dbb4cdd7caabd5c09b38e8cc1ad9a68e69e48f796a5e8e8fc7bc8325b45656861a848347a358f01e55e5d43f7a1da739ae32c899f977075c9a19c1eb6399f2e7bf1dbab593b9d7bdb5d9ef6bdde36af22fc951a18f9a838591a054e294c35ca0b86be60cd3e1faeb7e5dd4e5bcbcaa3af80ef37067e7f790bb5d59587e060f72ddf8b117286fe81cebbf078e6d259a9b53bd70feb43a86b24aebf7bbfa3547ce79b9ff95726ab768bc7fc8ecfa637e5030d93581165f1e5ad3d42374a41d39d55741c9c49a1d8d7468cc826f0380b90c9c403e9cf1f73811d674b06ce47cbf613ba56365fad4872b9245bf36b0d480dd0b47b7797a23286269f97451ee3792cfd5c8aa3310c7ff3423b263d93ca42dae20fd4fe6e3bb703a6c50ce7dcfb6341aeb485576b53d1cab71e9d49dcc68cf96d08bdb6152994e7025ff96c8ae4a18e9102ba5078bf6087bfdc7bd4b324a31aeccb372dce8976bb9db4fc8eba89640149acc544511546c5edf93c3173ef28ca92b85b86188bc70cd9e2725307a2c3802d6d870affcddd6fb5989c5a6846497dfbcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a798f4aae53f2e1a69dbf64336efc3348f4e4ecbbd4010b9f7399310253679b48af3c23961bf345b45e72c1d472f9b3e274c730374af9154a58173ea0917af1259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435135ed1e5e4fff0848bff2e69a49485c0a4f26ec6994cc5dba9f64770bfa3962fa08145b987593f2fe67a2b2ccb036c4e665de45758c6745a389955ce9744cb813dbd85a838a69d4198c3e8a5df65eeb6ec70e5a34156ba00a53f05c9be7f1ac214f6a75dd8e54eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fee7d9c45da28a34873ce76f0fc7a4237aaea18d4e2d3874d726aec41c3ac9fdf706da459d0e736b7a5e0936b3abccbebf146350fafa247cf25ba8974748e7f28c8d6bbb55fe98a48de682a91770eebebdb29da0efd677a70cfafd6f690668924cb588804d78179aade86cddc8e352996fb2761be87b7778a56c6b026769e339aca5f8c9499defddc4acc3bcc7ff548dd90ce3cd7a394c24a7ccee8d3e2fae3b48beb295905c2e7af384393715e07f33b02547822b1afcb1b57b6fc637e17ec0fdcaff880de1d0d8ec42db454f5c7be69ac0069c33330bc4064ff490ddb90a28908f7471fbcc543fa944048e8697acef5dde47b9f692195d9c41d4e874ed718d35b8c6c775f2fd69be2f339d3c440f6caf9ff9ee3d6b97d2a546e09ab4f6cbc2f6ce481eeca81c3a7720a4f5ccb6c6427ab580c8d350b468dacd79554e555b3bcf75343ed3966f69ca80bc95d663776ad8e36faeadf3baf84bfc59668e6567ffb66990ddb0cf9cbe8756fe35b9694303a90b2673a62b85c74664d5055cfee3ad39fa83217df4299745cb7c683479399e948ac2254117f491ffb3311d69455bc9f5e84f6d24b697ed44995ee73d973f459fd37facd4cc1859b0c6054cf1fc5c03eeae83cfcf2fefeea34ffe316ae96f8f5c28bfca1dddb93b4b9ce8e4aba1df484618e4f5a734347ad577d55e0b78df01fab8c9a859385733db6342dcce6dc4ca42777a7dabeaa137fe49676f39cee53880ac4267b7f7920a9ca43c93a3f3d1a9859e01abcea7f8b2bfbae1cd47f8cacdba4f7c7c89a466ffa3c5f243da5ae87266bdd9b33c74d61562cb0e32c55b8abe89eb2e59ade10f808fefbb5ebabebd3e4e2d66b66ad566ef98623c8feab48117f3ab234a4bc2e6b80b05f97f10a508b9ab08c0650fe66185f146b0ef5993629b3f7fb646dc248e0690b77557971f02bafef88a9864c28e885562ea7b54dc217c5521146122aef78cb893a99c1c9621a6b51a43117016a7f2231f2380764dd81162a4433d6ca171062704294030d5a3bb9859a983c6b7f009f130444303932f141f506896fbec852a8a6934e72ad8c038319c58abea4c73319df541ce4086a90976356d001cf6479437b64dbb318f7db813d5034840e23910ec67519c93e9648ebd1b70edc3ac24c983ecc4003cf5b130eb251a6199814c715eb54fcc8ba9cd638a294bc2015c8cd7d28736226863a286dd4c0878345d3885cc4b2acc0ae08a277cc23e397dee84ad6ec2b4d73c520910b4eb4ba447071de01311754060195a37eb701045103b59a94d59131faa1b0a99741bf8b186f44c6f66f76695eca6932647e408966f7ac4b0b8af15f1c4fbe27a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be945113013d02197ba78b0f5f8008ac89b28ad829e5fc2516dbced3192242e074cde7c8e2b11ed1192b25db395f09bfdcec8b1a8671975b692c84714ba3049a636494996143212c54058deb770ba709ceb7659868998d6560c8f4386629331f7fe77dc5f5390443865d1215833c78ff2a6e24e3655ce799f62c3b5f24529c051c28347c3c792fdf8700ec3b6559f8bf6646352d2013bcd704bc2b26c0b8a231acafc7675d0e8a0459770f11d04aa0fa79d6062178ea4beed06057444c4b4a76712201937212de48941f868ff3184a9a700756a59e1297a71c3912cdd40e6f883295d0a62904a4be9350edb4483ee6bd20201d253997d983cacc0a4730a4255824ba9e4b7ca7908ce84a2562ba6db8e38b860671e2654f2c9b669ee9646d683e9f907733423d4b139bbda51e785a86a97103d8e14d645064b6e02a3ac6bd56abbad5cb09f1968fd70a84018692c2866af2b85ef8031b7693444cd1a9ca668bffdc9889053980a88bbbe59c883acad0f00dd7ba954c487b585910a10c95f571c245f0b415261fe348714c288220ea84d8bc524e438f43f29a9d42a8ba8138dfcc264182ae8cd7927d0cd0f5da7c2a321914e84f716836e53025e2ca75c8e34b04092752f1b77e9cb872e742aee71dfe2c1ece8c9fe82bcf56131ee0774076cba525934e21ca0387e43d53624caaacc88af2a59e234e24e262a1201582437656f97cfad4a087c622de1563d2a16758875b03ab514291c7d3ebac7e44304c32712af58b079031993ca79e35146723bcbffc96f16c6ab7975151961f1c3c3fff9a9ec5940da90a99bb2cce3f376cc4d9a417fa715892411b649dea698678936c35123e5ee8ad4cfb2a85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8db9a2e14f49581f106ab14779278a6aaa303ceb5ca7c246b5ac13162a9273a9ac00c745fe6f01598575e5348670bb82d8cd04a11a7753fa7729c89196be39ce7d543e24ab509684256e82825277da24b84d8f95517b55c2a301864b9a13ab809cb0ac7ff3047e58b9091c5b55dd0c23cb1964d8b58dfb80aeca479eef16f43ea66e185b6fc263e081458086585b8150b8239a531936e926ba339b79f18461851982ddb2a3069b235b8f15e8d74aed3571cb4a55067e385f3b53549fc4cf02079b8a41626a0aa52c5647ca634a37588402ca812f870abb94e09c2bf31bbb865dbc2a3f197bd7c679ec436f21684d7773de6cc551d370d75cc6217bc8db75431159aa5308570b173c7e90b6b09c16267b0169677610f57580640a536301d6b6b7c58525b6f853a5aa73a05c766f631c0f1c82f6ae54eac6659f2a37fc364b266cb0fbf8601dc5651daa87d79fa1852d950f29441982a71bdbb74d260c6b75630e3e80643676c4d59960a445b86d5508dba0c41f1516f44aa309a799ca626d4ca8b7fc5cd54c623acc96f15841c85cb1265f5ba3f6754b178a281e8106a23b04744ba248c703f0279cfa055dc3c70b8c68e48dcc84cea9d725b4ba5b628d9ac62899a460c157752366c00aac16e281ffe1233e217202fba0e2bb3cc5c170e1e373fda503a1d75af9e7a57ce113706d833ae662429e2774fdc686dec4a6268093743b718d3cafe703d2c27bf7b902dd1482ff611cedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d36945441bbd3f5c241a6d65b510dee6662e2a8f35757b0403dcd375e7a15991a7873c21100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 26b32c1f885f84ee7c603a079aa9b9bfd88cf4a140edbd1c9a76c458c5917e2901dd306f4489539b6512578750a3d1efd7f70c011fcaa9697754039de332d69f39ec075b7fa37380db35e1a549fd188b163aa3927d4f0c222965aaf3d004c89a6765e818edc975a4bd286a44d88d4d2376d89d2ea01ccb0a3aa4645e2058e9e8b059690ce511c0aa292615053f5f5089c8f0b91fd2bc3dd683e1482b0b49dec07c10911c4ae79caded9284fc9a9d3b9126ad0508da57fe10e4c3e0f85052b524ea4b8bc9474256a5e08015d1b23433fde585e29eae84561d2d513efa3dd09a01fe6078e920686e8123fcc0352780bcaefbd7a26e51f85397f99398f27d56a9853c2253d5d057b378009598f57745e9cd9bfad63e3a93cc00946993ebb2ab3856c3a17309a116cd5cf3a94fd18ed35286175036ae66ed022643fe2775b469dc3912d004362f03f1ed6d218880ed206d8024d66bb72246c1b27095bc31d9299acf030dcb8a58f7f71c4c2e1e34a3464458eb516e4c2fa2d819795b12d2c92a56dae7e9e47d16aba8eb6e6c9e044c89a7b18a111464cfa28a634842193f5d6c1a63bb39035630af6d3141b72312273e4aa3b338db926863c98970dd8bc8b936572484c0f3fa52d0cfa3b360e7c57169fffa35fb1bdca24ea32a55b229454d0b57b3088a9b9943c74b5204b86036d36e05da8a6a5a313034205a192aea5c60879a721f9338c10280b9b407d6fab7214e903a3039f59057d7381667127283eac4ae8de0e71a9b6c36037536ecfd0970dad44f51db9b3bdc961ae8ac451f8521cab090541278006549aad938ffd10f522ad149cc952c6e8c119b026672c6564453afe3de708cae3bc07276388e1ca4846c85310a66056146ac055f212be32f5730390375140427d54c781caec84cc85f7fbde7383354aea94d327bc830005f1eb6654b31586660409c237e00bb5a1a740cfe64db97b3211e776576e2e534223357513c8838978a8688ddbc16d9d3f2f8c3d21f32751c26b652ab107ff601a313c9488a336aff6474bd18edbaabf79ecfc6b8f6796d921d75fecbd736001b99cb7324571e7cef3ea13b8e5fa7b609e4df8a8a58b1ec2f1cfb9b5b413456f9b54f36edacd482efd94a7b2b48a64aeea7802a40823335ca5134a07e219a509e96c9f00b521b13ef4e2742bcffb02595daacbc1e1d43b5a8bd6ea35f0a70be84ec944e13ae16aa0a055c46afa180a0e3cf4326143b60a1bcca06045ebd3ca8425b3b13846796f855125c5bd93849480203a915f2221d097cfc1d6cb7d9948265af503b96f53e2c9b41e9a1e95900a882384f819afa1058b1d891f173daaf941fc341f984e77f483f04fffb6dd4cee50b93a289e6fbaf71d2bc36db6692199a47844544cfd3af2d6f9b5be58f9713e6af5c4fd20267fb68f6daf81173cc6d8bb24a46cb201e038610893f9e18170a0514114dfe0f41244283b485f7d1cacd88d3da4f8126b5f95dcccd17e8d90a6ba381bcbc933963efbcfb40ba83a16465e528bf59c2981997327a4f75d33d997e8e38d0429ec0fa9e5e450237b15238fb0c8ea272f684baa71af738d72e412c8ae3a933d709a6f647123d68d6cad188a914aa18ec760224791e1730d5feebd3ff69074498bec4b53fa3d9ce23dbf26f65bfbccce5ed8649f88d659885d0598d980dfe27494f924447340a7718f399c0c676d8a5740def7fe7ca5737e4e9c71f6a0e222c2978ad4ba5c5d5d5f6f5966c08cfab026b0a6091bdf3f5cc3bd77e5c2d91e200bce93bbaeab412d5dd40dfa7db74ea453ec06fa3c0299eefabf6fd9b3b57ee799e6406a266680f98e1d6a8d06ca968cd90a7e5fed2463f6f0a712df964192733915398391fa5590afba1adf5b5ebb8e7a90eef89bf67a19cfc4eb061214244b82672a2033ec48ddfd385211e5dc780014e4be422ea8af9db275f973bec8c8b40b3dd95fc58b200d79765845d297e3fcf15062b0915123aa279bfce802da4b166366f890a4acdd5b066391990d66a2f98b0cde158d144d61e4115caeeb84192bc98e27a832ce3165b0c25a58b8b78be5c3c32278b971abf5b6390e78f30d5638816499e926a6171b45814e17bf73af0acada513cf88b55be51a72148dc8abf01a3763f8f427509795339d80de25d57733b7e7248b6619078c731bfd8d91df790eb4c068676ef21ba472c2b1fe29edf6010c126d59 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2e8da416aeb29a6e459e396204e5b5e65540a2a9ae9ce5fd867a9e20a5ffc7565b6625e653448353697b0a7f3b17e3b1ef375a3e36da5869b579883fd1eb3a06da5c11e493f4cc9d1848e8560bfd372f3e7214ad79ae78b2153dcde882451776478a4e06b392ce9b9d041da5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc456878fec2f5506f5974270ec46db34efb9665b68e55755e8ff677be1c0991b644b5932be1232dc6effedc38ce9316156bcbf354fb76e635f4ff6b26b07f9552d8bea65e5ec7eb7ae32034bd755674e0ce4345aa72acbb85d57f4b2cae49265fee570543af9d4f9bd4d16ccd389fb9922dcefa394af4e02e9290dc506f6de004cdae8cbbc686af5a911472662d7f94fe90b12baebe7cc7edec476553762ea45e48694ddd27fb6787b7da7e9e89d77563c9c2ccb77cafbf3d7ab9e81c8fb6ccad9aef1851235c7986194c843ff80c4e92ba4f62fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391b3e4555674cf425f92055bb3a3e9dcaa7b0734df04c068028b3ae7b8ff3e02ef032e6dedd1b6b52faeed13b86232aeefb2969a79ecef1efe9835a44e907bb0ddfce6eae442bfe460f2ab882959e096fbccfcc6e40cfbdb5eb673c2e8d6e9c5dc656ed8796945c6e4c81a68f9cf381d256bc1e73f8524e814077af5f54c2c6b487dd29cdb2dfce09fd9123dd9632ab823dcddd86a57f8933743f347c203894d0043f579fa6e22f83ab0aec98b39c6d638132ea4b94644e8aadadc368e6bf0ea408f752b42e5029d7661b554bd39abaa906af32f877cd5bf8bddfe7825ac898dd6a4c233462fba602b8e321db9327aae9bf54e31b96d35db3c4cbaeef1fb3d146f9be0333650c4cf4a5c85bf6ef52413853de0bd50f9ae6f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd6be8df1d947e28ef72ec5aa1137ccbf5dae73ecc10635dc049fa41a73a4861acea29f57be33cef406b7ebce79706d5a709a4bc06bbe40867966e830e8aac19a06f7a474fa8457f76f09cfba6486574d79e1aa38d8ee79d9634e3398b744ae81300f818e979b4434a4517cfc7777f600d5b7d3bb6d7f3f53189c36952fddbe35e9c62c80558ac1d62f85578f962d06e2febc9f330af8a0787501b4f802863b5cdcc6ab8eb964dcfc9c8d81b63750a6358db5566a0e4ff9d2989e98199856af448f54688fdf487c8e6f5cd651206350fbbb5cdd995a9db37b089caa57bbddeddc9392faec0fa9d31b4fc350cab7b6f54c1e4acdd1ef8d7975a1896dffef055feb5889bf87929c7dd65636f6336bd5edfc54501dcbd927ab3c4c9e8077d0349b9a0099801d5948cff3bf0977a9692af5ac98dd593a36d1e5436ebbd78bd9a6bf25bc3d6b5be0bdfaab06ab594fc440f4dd430aad942ed15a8767418bf33fa8cfc659e4543d31ab39b845a3c50dfddba1fea586053768ea482a3d44f3a831b45632070d40486ec7e826a0b21eae37db49b31bb3e9389bd3e354f08879906996e02d36ac49b9c773af5fec53765e9ae7b8c61ce475ac544d13a5b421b8a68635eb6d1c64f8a353416f48b053dc8a3a308c7ddd0ca5d6d75d9aac9a46093564eaa957b63bdb18078325bbee8485f1dca74f603efb013ab90693c37267f9a4888c50533a27a83a436a627a4cee0cfede36de90089ecc5994e3a818bc2f58687b6dffc5f747ad365dd3348b3f96a9072c521923a51364dac50faabd74a5b364912ec3626023516259febc96bce5c8a719fef4c0669da5edd80117b0778dccfdc79ef21ff9cb8388460bbe674f55513c71bd2f43a2dcfa123ff1868ecc5415e4ad543656a6f45cd98ecd445653766848ad3794959f15ccced05863e4656bf267ece6445e9393c95cbeee5efed2c358517f7672c1ff6a34d8c7bbba5ce9abad9c8b4a6e9788b82bbd399838e5ee38c8ce619ca8988a05caadfe4a6cee64c569444d49911525398d0a460d257e61e6b8e1df614badb55bcd435f34493c298ad719a9900b94accd8acba78f42195637a464fc28d013cbd81bd7a4a8f66909557e85784780c589aedaf4413ef5b76ea06808ee0477e6e5c5d72d754a6888d04ac942319fa3e15e521caabe98e955c093ad95d741589e8960157dd5383702f3adfc65436daccb26429b4e18c04591cef2a49a51f34aa224a4f7e0bdbb1950b5b9bd633a1ceda3c94da93cfce38aa962a45a135a45105c6e2548db96698d581f42ebbb7c4aac8da6805024bbb2b0c45806015db249b4e10f92536495670bbeb0402d0c1be9b01e47a2a77d29cf03647fac3730878c7bddb724f7d8539e31274e20334949a92063634d6c1c0b5a1999460e25259fa91737d2b9a6457588d41041d8d1786ef80ec2951cd0c84bdc57108f02a7aa5297174c7be5a6157693c07a38242f85b79d16260ab37786e67d7d9a77c953b81a2a4b9e01697bf7a714fca3d9904795671d4b99b5ee83765a532624b4004fc6044c1840a4d07d45240251d32fbf922ec329542471037dac809f477fb6ba5b198683443c683cc8494bd1b7bbac7ddfd39f45a10c77433b868c981b7aafbbb2c8f2bc8a6e3134eed7bddd54b9fd1a38dda8a2ad60b4111b10571928c7b55721c527150668a1da383b8606f4e1575ce164dcc911af678a33973c807a159bdc12811b003d68b8edcb12de1614707b555a853290870b5e5b48d7774a9d69a116d13808961164cc0cc38325f49c463e41c043f120af24239c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4554a2ede21cad465be2e3001fc9c955a3b6dca4612d0763299aa8334b28830e996ffb13f7195598c55a704ec9539bcb9a44704c77cc1e9c2a7cd371d46c02a409215333acb076bcb2355acb6c5bec8cb2640c86882342ae3938059a99ae7a281d2b6ade8073d1a90459c04a5db7547b681b007ab996e1a7fd6a030c7b34332854e036b8e99d0369bdaa123a86ab931776e437271a2219af7a4c7b8b78aac0365c78d1de15fae8c4c397c7b6eaa4d02b06f8da7145fab7948b786a78639a4e80299e3c12e5b3847f508c5189d0c735f5841a7f5b34fc7e194f4f20f348475c1d4a3f4e8111c9cc6eb06214c43838b41ccbb6524da5715e5a2644bfaba69b0cbb54935db0379b52668e2b8b84ef5600ef76686bb0651f7c43c1c120e20af9de18aada655d48b375b4a23d21c51e1c3ce9e0131b61c345112b5ca302ca9e183443495da4b309ac898e02c4f70fc7359a57d25778457e70bca8a1c7b444208b00e24da7e0ff89c19190675ab24b605295ba862eb732e4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e08c172467c80ea05262831660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6225b1fee03cfdb599bb024416ca980c8181faf51b421b86f92147e12d04caf335a87fa1dbdb2b0e66c0795cb5f65130adf3bc8ee3bcdff9223cd74ca9c4a8544208b31cbc7a05b21392b0ee03b9abcca42cef8b5448482d8d8013ac221ae01436cab30e1c126f6f80af46baeb4a828f54735b5513c8f11228ec2af7d854d84e3688799ce24c8454e326fd0f52fae773ca5d408568551de89cb85265115092b960ab9792ab8612c012231921b6c697bac6bf53174ac50a6ea2ab3f48b532af51a6f6939d1ba14b694c149b5503f3320f438b731a59b4c22810d1196ed4a90eef2968d1ccd92327b37866abac1c24cf0c2b2228d0e41a3a1ec6a4227a36218b6437b5023e22d43f04b712c2c6665bd2deb160aa95199146618cc1ebefca7691248acb7c549cb66cdd59f5c4c0470205791c742fcaab677f966f746721f58846d1ab2fbc11b6f2978ddd282730402deb863ca1a7e224cccaa2b34f788987520c9da9c0c328cad6dfb46a920bf8ce22f4d265426cbafb31023b7e748252561cd678bb10218d4e5cda45488c4b2c1b2cc73c5c163da9467f02b5ceb4a5ecd136a2b518470719114d1c310a688e46bb80dc38dca1a092d36a3edd7c4c6d37074692e266a0f5fb0501e9791f3f90cdd93386c05c93896b950c7681f0abf8a044ab1227b68210c169b6057528315ca5fab7ab2c9dc7743d8943c997801a01eb2d9a195d2c6a8710fefac2e60702b68523667650e6616cc0b7b5bc50809d1d45e1673be8dc435b7355b0a26728205ae8713be0372cca8169521e574fbd18c37ea3cb6f02aa5c82a5834819254077e1670047997863a5ec7692bc26cacfd8c346290564fb27a50816f2d592277f56167027fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196e92ed698157064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb290261ff6a1d2fabc75feab002d16cdc44bdbdd0967c728ebef0e9814c60b5e57a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = 371298b6907604100b71c9f7170de670bcf388e150f71f83432c040261d09762bbb54b2bb3a9f050e683cbd1965f6421749149efab2ee69368087c9a52b3ae69d9da590f741303cca4fe69d66da0b7b5f1f523c55c6d0ea735abb53ff3055db3475559defc033277a06df8f8190839bf47cf0ba7b5aa80a2d1c81a69b04fc693ad12d694db986232cc539bc1f396dd1c306d9f183cecb93b7da0751dc691881c6f4ad9e02a692dbba4ee7cdbd21c8b62b0c35a41674f3b433304691978ab587eea993919cffddd25ec216e6b84c11d618682beb75d679cedbb58d480e803b2e1ee24228c9165ab864ef495407f99b475cdfbcd0deb672c8945c67ea53c6a53c7a2be2da425a38619d9220f7625abd46318123ddfe2b1fa9b59c0adff0c7aeedee850135a26cc09e9755f05f27f42fedcbe8e1478e9ce945efca92efda7eb28b175995a6f7d7ea75b3527e46d9c9d65d1d76bbcaec4aca8a8a10480b1f3161357082e7e42284d307255c5e479c9e530f6dd1c36279e29c47ec67d65d5ec8b5cdab5a3a53a1007bbee8e285c8440bf938725e34e0486369bf603d0c1fcc59fe6dd2b88ad5381a1e6c683049bcaee96152c00552505919951500f61160b5ab2550cb00fbb9a545e397bb31cb1843312cab077c54e408aebc25b0b14e945724deeeda339fa681fcf6a6129f709bf150b492d155aa06e2bb5120d58821794a4ff564282cc2f10574e246eb6531facc1d1bf4efa3b149fc773ec6997dabb4c726d81b357a152e722f3d9c1559f92fef95ddebb7367d650fb3010aa100413e7a38ae91e4af4d9620a63674e0f6eda1fffa7cf3364cfddb3fe2813ebce0aab63bf6d6fc68637ea5e2a142c6ae2a27142f7b52fb3814013ee607c06521ad3af0fd979bd4a75a174277fc818adccd7ab80055b54305911822d926d7bef7cb0f1367280d01170f4e874b53a1bfbd20bfa546d78e1440879875f957fd31bad69739e2b1f742a5fe58d37654079e59e0680247f1080a24adc1400388d146023899eef694df0c3e03c37b2f9c0be7807572df6980574cbeb7431eb9e9f42397ae5d14dab4bb8507ac9612772910ab44eb8c9239e680220dde1c420d45f87d94d5d9b80f76a9e15f083631a82a2093b75652e51d5d4129bd5e33220eca0e7650e6e195351a4cf062fafc1ef03af4571f281d46b992262e759c696e6ed5c8b2810699a920b0d1e9810d7635c8b0cdeb4cae1dc4c4284b41c542e66902decb4a60ebba7197462385cb8aa9130ba9d54b1a3ee32037f2c09f6ee7e8cb94e73100dabc5e2466dc41e5e29f075a64422ecfc954e2e589c79a1d4697ee8a2b18f9303ceb6e2a66dc734ef402756bae927c4bdc9150d1132693e5dae94e9610e0ec18d9aaf6e7c28551b3f6334af72a97b84e09a126b2b5d967cd5d53548280b60f0a88f90cb740291fc29799c8bd0ea74bbf1db1bc5ba93350093cc2ddae74721f90447160d49d01190306ed6ecf7efd2260d7a361daa91090f34e4fa5dc9933d2ec66468655845165596f84db142f31ad71caec5a98cebfc2b6e8549b6fa7c235ac832b7b71543b7f7c594d631c9402f86a4a4a8e17896846e1300a8a1c6e3ffabb5a25ab471194c0b393c1558e8d55a10723b6288996e8c37ee262f9a2a87d97b8ec521e23e784468e98b78059f2f19c26e96249998836127384f8383672e9836416d2539de6c1501b937d0c5a2ac7b5c78463d97b032829aeddafdcdec97e5da3f95b76e9c7eb3777c3a926612d442ce3f11beb8456c200fcd098c989e09d8b2b576fb06498e1a265d604776643e10aa24aefe62391d967efd62831be65cb38c0ebf9517cc7e8bfaf11e3b7404fb03414dd1acef354acce23d32fb0c26c275a0780c74ee20127d87f7e315b0cda02e55a44168a88e6a1785caaa2e0b8ab65754d1205ea69aaa252a4c4202bf50e8ba7bebaa50a08c9e41e1046092bb3d52cca244eb6ef9ac534c1893067811ec97a17b9cc63a9f0a1f99324415f782c0e70b16885c5605f137505e4d41870fabf9523cf32935eb480c29fb65f3a23e06db00c5a7c5286bc6e249dbc6cd6efbc275cdd6c7a8320d182b7a9113bf6eb837b924b3580be35d05d81a09fc4211f3a713da32663f7478b6e1d6f6c7c20ce32b6aa3d517f20fbfa56f9b7c99ac376b198adf68bc754ae8d08bdb81ea9672e8eb40943fec88f81526199b641f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ca58edb6775f3d276a56dade60ca79be147e63b6898f4b814c69a06f65e11ca8f4cccec10abdea7bbaf59da651a1b5ed60bb35853f550cceaa1cf3656e0667d726c69a39ae564bb9926fc824634b8b8a706e9fe75bd9657fcd9a308b51a3c4f9822667a5135fe445da8b3ca10e9bd3b6eadbbe6e6cefcda08476909d6e82ef13e4b284cc3f43c3383d7facf7b617348779d7493beda25e4e5124bc5d9144e82179f38cfaea46b3d01b8e65713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcd3d32e5cff1f9f841d73859c76cfbe2451948e6d88defbb40ef86317499786dd6887a429a37f78d3fcc1ac8facc587aa235822cf54a244eb7c6bcf8c5fc908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953564d21af73c585b6ef248c07fdf3116baa18c8455728f3d25cbae0af57d4f6ab2473b5919cbabdd7b4ccdcebe8925dcfc58595338917269dede6ec3885446b60d495247aed57a9fb124dceb7bf9f7f9a9f534e06d8cada353fc12468f9bfb9a50c9f0cde85655cf524945df687df93ddaa28c87e963497c4d5f30c05862a449e330f54cadc3b0c92b9798f5bdf9cfe0177f5ac8f565466464c20338726846092ee248fccf94d6e337eb6b1bade7e44fc29fbfb148936119797fdb2757be05eb9a36d1a00c6f0547b1832beca21e8cd3eecdd70ea0b59ec588cb5ed88ac36bee83848b9f87264cc6cdf0b2e965e5b89ff74c58cd2b338177bf145dafda9a74516a584548ee60ee32b4089506e8cde6346fcc86d75969f3469f7c5c6a97046bdad3973e806778759b35988953c80b3e7574b7cbbff5c744372ef3d42e07cce978a3f964395e5de76aab7905a4bbaa8f50f594c5a96bac4195ee09f897df0376a8a5e6041cef8fccb93d44ab474c569148f6caffe71ef67510b53eb41e53fd0f8b3625aa7a353bbe79cc76d393e219e15eeddb5d6c98f91ed1705544604351cdb877166e8343bc3fa227c1e90aefa3989391cdfc59ec9174f5e6523942769fa2d973774cb6fdbda4e0164bcfd95834c126f1f7da54dc55c44c5947850bd116448f2cc39a06fded868e658a34e0caa630347c3f0f6c86f344816cde3b3a04313a83df2de9bb50659b642353f6463d2e3aea78c7f22886e6cecf66b11d98b354463225fdb4bf3938d67c63f5e949496e1328f326d5b7d70b81d90cc6c5d84d4e69d7833a7a76d3850ac4993a696c4c3eddcf45fa32b4c83dd9e14305308129bb4ff73a91d733303bca920cd183d95d32ca54557a6ff3d4fc2bab46009f3e1d39ba406d92e30ab47f9985c7c439448c92b255f59d388e292cd4df4f7f389de1ca983b22bfba8bea9d6eb36001ac4fa516eee177d06609f62524848973782774cfa795a2286af66a5e5d4fda7093bc54439753fb6b4e6b88eeeff574156bf439ed74b43f417d85eeab1ba1475436e80cec670c3928a3553d2bcfd1a59c46faf542884f91f98a38e4fecd0f6ebc09e358acc99b5dae1edc88b90c98b74c3961c7d759f39b3d3de75fb8d386376cde2b66e00fe4151b800a2eab6a3fb45c8fd932a540c79cca0eaca0a9d5bc841c3acf4cd8097cd4473f6115fd5cb09745ebb986ddb76913faa6d504e2cfe987b68d8d5c5f575905d842969136b5d89b16dddcc66c93aa7f94fae79ea896834bcb30147effe4f753c9528643b5026b5bd00faa1ac9be4ac5525f734fc1049f93963fa046b0ffa7647fdce9cddfa89fe6582bfbcd70cab78aedba67c638756fbd1dc35303bf9ab65b53ee8cac6f7b5cf257b4388e9fd9ac402019563ee5e04de97953453bb139835c67415515aedc9ed455855e63b5a442a4dd1ab85d8d8d70324ec9bb0a6ccaa6949a797bc0658f56065822d5feb14aabbea75c435af2409578f2b6958658d3c32649d9068857bc4ccf59fddccfe6cd73bebfc5e7246fe8c6da930f26a1f7353dc3cfbca039b5eba4cd9fb3531523b1d63ddc3d9ffc136bd3136e5469a4f0e036ba827c849b285b28c8eeaa64adf41b338a5f86ee94e0beaa4a1c6376187e8f26b3a20659357126dcff48437c5e87bfd5830ebca6d32d458408f3713d75a50d76b403aac5aa32da5a8e2bdde60fc8a5b5e871478c30d523c9f1967b4fe4aea55976fb8d3568c6863be5dc7b0756eac8ae8da498a8102cf7e4cef04582be990060177980606196d12ea824ca65d485783a32e42a4e20d41806e8ae1c51544c63c3156a42bd8abe55e36be37c6be6a51eacf02274eabb03f64c4ddba2a6806cce943cf338b09f50c5123c4083446802456ce85248daac7e5d9637a541c755b03300b43c4da96164c6c42c3910d36522e34895055c43847459451b8022d39a2c287ffb85c8459c31c2d183f98c684a959b2cd0a224cbb38713c4034a6668e14cac3c8f9d1b95ee6251f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ee51c62d244502a3a044f4c95fdb42a7fa0300d079ceaaab0f5720a1ba852fe7148d4a1642d1330942c81b27882c631c3ca3758f56b7718475404ba20cb8b436bcc1116690380507d02c63e62ac58f551072cca75a761f237b5abff58b2016242fb910f24baaeaa47dbf010600881ffd228aaef714c65b496795bce329819418c26321b5c73cb603d15ffa162901f386e9e815940bb5703477a996b313b50ba05a1d41ab65f233abbec534c106224c792a3dc14688332a8313408510386253c7eb076711ec35f6f929c301422192b3f611b36b97aff38a94b00764e9d89f38072ccd6b978e1a31e391cdb2cb3f9e344ba947a73db91891b944de4935d48a5663f85c94ba6ed8a3026c278d645b7b593702733865f12a3ceda3be2787a1efc2a2fc2211f405c3ad1c8c46257059e6cb43f36ccfe6231b730040849233d03b7e90076a7792f865467b6548e541bfaf5b7c3e6059cb426cd263494c641bdbc7616aa8348c6335d42719c0e79ae52931a119856c168897d48dcb44242c505c535698a35cbaa9f80a8145927af6653d31977e827625e3ba18ab7af3621df248434c2cc5e9324f34c60e1ff1253b4904b1952bb7e16dd979c03541a6be9bca09632120aaad6c457942b0077ff01b6808af3fb82d390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399e2255e030833485bc69c5c94cc48bbfe7bae3754bb49a2fc1a15db012be519ac8802a5cd005a6adc31abe237d9c2924134235db04b78c96876b084d41c62aca10008237a6f0c12600fd134ac59808418fde238aae358e34c1153842a31cb030bd97ab2cab83f74164358a1a077591c356162d53970ad65e21a994123c4000277d72ccbd0d712026217de9054fe9b38c61fa2c80871ba83a88bc98105e693a15f2213eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7a90a770717b14b40673591e986a1dbac4a87b111ad2854899808de206e6a768770e84023931bd4d996238430859a6f7628964e4465e5db7a9f5a0a77272ffa95a9ae759d47e1885ae6a4e3e78493a25153387f008a74ece68a67a8224e19209f20770bf4c8cb15cc39dc4147549c8cc599b760700db4591b284905562afe554658a07ff22c8645e29006d331bf09936085c4e7c345e2993a7332c9b40124d375c40e266a251002eb03b5dab50760972b7e9785dd585df7c6488ce9218c0171db28a99ff7a557c34936780fe9aa78bb395885085e0243887ffb27030393d925cdeb2a2cc3365ea95b5bcbe4b0bac9bb32e1a90b009de0f6be8ebb3e684514d2425f3f1688f54056f41c8e364b5e89859478349c793a70982818c28a245f690057095b320b2773206a3a856445290ea1636f5029bce3d8baeef0a73f912e110570817bc66d9b8dfab95da8b270898b6e30f28418ac5233a954f05009c2bbac3cfbabd0db906188abe7b72cce5001496360758cb477dc2ec02a590621c93b9067ed346378c419ab634d95267def3148a594be088bc349ec9669e4bba474c4aca165e664986c34a0dfc5c5c4781a61063f10f2c175693b5b5cb7c9b74442050f5d9421e6900cefe35bd942b49e469787471f43b35ef0c86340235525d50904263b2cc052757b01b75414027c9d02db50b4e47e5cb19f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5bb1a9788565de9455be321b50a39105a33e60a9533b506581d03459696192c08626009e723b228df1cac15c645db16faf697a7df68d71a56cf263639aa0185ed25bae84551c60205fe6b98d9328da3604d8d1c70d84c9ad68cbf266baeb8c6b3b9716ee50a8fb5a25bb6a32f0f971369601f9552a52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d7ffefda144195d79e581c91cdf0247f4346e811f890f54f25226b4ab835871a48f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = a5ead95b44ab725154827549ed041a9da95427c827a9d4ee7e8e37f7001a5ba417aee761a6cab26edb9c8d86e6c275a176f3ce635fba2e97e428df214c03ce4d6a59e60cd257fad420513f55ffe6fde38515d00b7f21d55cecd78b1731d33aa39bff3f007350aa5c380c137027c91e9e2f5fe009db047d0a78b95515c04407573dad32d4a788c27cf0740fe5647f5ac2ea1e23440fcb86705a71d38a746c8d80de67a84836a656a3e02fc1a81db65f52b4b55024b433a400cfb43d7474133db3796ec75403f2d38bf626a6bdab7f8ca89b2d2b2684345c972adbf851be5f594ea88d993577a7f409762b65eeae0a752673ecf43565ba57cd2fd76984fca7eaaf4847dacaec3ea6528fbe7a2cf236c48d76ed2861e66f9c9df3057349a465575052158deb91d63c48c0e58abf2c4d58cdf7902acd8d54869e1f8f46d322a9b1db170ff139a3bb09e75b44fc8fa284dcfb5a959331e110fafeb5973cbe4e8fe525c08cf1ad29a6c1f2c4b7004a9eb6b66c7b64d2f375b1fd8c72588abf25018493d47a5aefa0d93dcf36ecf336a5025c404d9afb0b8032bbd6e407390e917c7baa28f74119cf4a77a9b5ae1f41f108b42c9e16dd907534143b68ca49673c54eeeb496a9dc21f4be1070e4bd966d853353a8a075fc17d5939d9609a83dbdefbb4a5c710829e26a1b1c5ffb62edf0aaf4a789f78429f4050dda21d4ddd6a7e1a3494605f371a1bf6d3624c8cfe29ee961b41ccb6a01ddd0aa668e3535b686cd1f515d64e4892d61531502018ce3f4c1a8d5a08e272ee5ba785281c3c15ddfe5b58f05913cfe14a471ea01a961793e09db9b5114cfa5243d68f05be26aaf01149767ae46bd854d565124503d77daee7b4626fe130a9d9bcb8efdf495893e3b62cd84e484ba4ba5fbffa19df0c915b13e38fd0a41649251d392322cd6e22a2db1c9106de2c8196761272b9329cd6353cb8221e00ffd91a9f06455658334f66945e4b24f1cf30664c123257dffa874750416af0aa43b0f0ce2c7c40710f6471bf21376a0e6bab6af20fa02ae95a8359993eba2f349b62e8f8857423f46054eee46656c8e12aedc754b03d485ee98f0b7edad160aa052887850103de3b5cb4ab8189907baac915541e76e7734f53a69c420ea95fae22ed569bbb7d28311a52e1e43efd9dff98606979e82fb19d4d7b5b60d5a626c401d71fa18fef6eea32312d05aca694d54a6c2c55f907e25928e16bbe38ccf0b37a3ec0ae1593d69c60dd880a61fd803856580d9cc0c8e3f89c98d17a43f74e3695927bfb8d539fa4b79eb0576148da4dbb295277c8cd71b94ea21b9614367c466f03e795890cdc5d2a75ae57cda441589c88aff28fe60ac7d0acc0db4411846ca14097a736bb475baadfb334aa669e9e3dcd2fac3ccb8490a97f5a5cf8a627b296da204971224c299cee3d46591d57c7973f2f561bf5ad97039ae97ae03557e6caf2b7edd6977fca67dc70c60fa962382ed707075df43082cd593a01e89b14d08f1e9669a06934803eae0463deabf008251216684caf84913891ea636353d50e6f86f15408bedc97a88a8033524d7a3599db638efc49488456937af09f020c8f30e0d6c7f0fad55238fd38fe57c2e42944a4265707003b884028a8fad01ddf93aba1eb07f3ba0ae0c9b53fb56498c203d4013418065f589e2aa2a18bd02fc92d19bc1e38d72f449fa37fe3da189e953a9f9e28e1eedbe481bddb8f2bac2d6e6acee07e0e79818da2c8b961210a72a6365e5c679cdc2896a36a0f66c121a9657ce84bcc070a3f5cf06a843b59842b17eeb1e2c84f0d387b05782dd4c5613a6dd5024cd79d1429f2520fd626916304a0d9ca3a09a7638a45331fe6e6b6089bf07dac78f005c7227f2abb68d4048628143e90b31ce66901b0d0790bf0837cf773a3fbfe53d13a3b0d2420286ab7f7579f4f85f0e4cce62db423eedfbf6ea89f22c4271c566997303281d3a6b633685d5bcb5ba91ab476dd277a99574e39e45da3a7e42f490ef0d606403b940e87ac4aff2a6b09d8b18675d3a23c1cd05745e36bfeaa7e559d076a4839926fdfba3fa7287f6b278491f469393ac9973e154aa413af39f0b39274137081fadae69707d39134a54e0be1f51272b141d97d6c5e902f7a752982913e17da9b2e8648a298987cf1d03ecc3a9f4bee827731156fc1a38b6cbe7b3ed7cd06ee5bb9e7ee98f909a5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 90e7e29b79c095c3d63f63d58a4baa75cf62a99c8228a4f54a15d40a2e5fe67773c26c7a6dcc739d94d6a6055b399fd4604c7b066cdcdcdce6fa98d858a36d630dc6cec473c08eb246ed9c6e5a55a8d8314334c23ece4fd6a9c012afca93753afa96d9321bed01fb9a2b4f63ddeab8d6bddc40346b8f84afc7b945f62e321103a5219b53405fbee52f56eedeb9a536d13b0dce07d44ebfd66c0bb67776deacde4aadb7c98731a3ee54f5c458264894a7edf6ddccd948e7bb77a2e8df9ce47aba206cd971f3409638dcc725a3c22a4ee24a9938dcffcd9a67037fa463c852f0cd4388ca8ce86a8e9f73f73bbfd8611cf2757d9c56affad47ec19784eaf15f6218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0eb2d75bc25b797e8fa8e0385f01d94d1afb17326f4308487991a7164d8a508ff390f354b4fa3a225d5a46473e45ebb57b997f4f1d3cac01ead4fecd0c0af67d803e17ceb7da38cd60baf3e248cf8ae0d69d30681e388d7117ab842ff3548caa0231fafbc1bc542a7f02fa549def55ddeb5ba4e1dace275d511366ebeaced61fa9d5574c86c17e4ab5f3cdf946e20df59148a7e2ab5c21884314e3b8082ccf10c6fd9ccb6b95ebafef73fd3a0c7d7bf9c5db2ae5516abd7d42cdedba7d9744caaa376f2f189773ad7a59ece42317454d9d8ed56dec637876f104b6836a6842b97e743ade25505461eea77d63a8dad03c7941b69d7f66e4359f2e13a8182fcc35f5ec9cf8e978e35818504cb32e4a6dfc777227a54854d9a39bfa1e2243110e84d025befe1edbb36d4aac17ff152599ff0ae77b294bece49ed47553983f4f0de5462c72ab589bf93478da399ac40ef35a5e98e9459eda7bfdeafbb29a446ecbcd4e45a50176ee30e526f3e4cde085afdb3d226039cec4ea14d97f56bf566dc3dac77acb80b29b1f9e6d2e919707c96863304372a353772eece9a4f41a12369fb04fccb53e55937f4ce5d85a589b1b4ca46dc49cd66bef47188e51e455741c8b5d7c9cafcb75bf27a5b4fdd5b22e932b1e3bfb0c932495dde5485486e0c39fd5ccec78dc78f6e37be96823deca37c73d6d31c91420cd4ec64dac12fdebbe9bd5237583e1972d0c4676708ad35b559fb89bd8734f8a4ed50445d451dd65f58bcb293cdba437394dae55e6efe3a904e827949d16a18e936de788c58d7a54ad11b89528fc6df386632e725b163e83e1063f4c49e4f26f389dbce99a926a25b0f624d9a530cfdafafa4c5ffe6a5efa4f2e53fd19ff337d1ccffe17ad7daad46d193e37d477dda378e17a95fc8fdfecdecdd5527f4a4f36ee7648c9aa771bd15ae29c7f59abb63d0983917156ede6557be445735ec539c2e99fa8e6c562842627cc83bcaa659075f5179abdd1a7057df7f7dd96a6813a940a9321c0bea46e95c16836ef038e06ccf6a3ee450d8e569efbf3b718ffbcb08f9821648b1668e6e47869a0be7c0e4b827c4cec3c4c9948a6c7f874968dc80160a811ddd6d58a885d043f1044ea6f89d7f53b8fc98468f6bdb7cc7b6d107973db0f7df9a387673234d6675d19686f15ee4597c65a13a2636cee74266f373a4e48bb1ebd19bf44ec0bda509e4bdd324314746f92eee566f165449c3b618c53c0e7468a90eb962ca60d6834276ba307307f6e90da39668bb515b73bb3bd55fc55aa3099f4c3be2e027333df63567043b5f8ea53f7993ffea69bf19f7bad9a6e56cca6f96cad9fc434edeaa6f38e4171cc8b074d00bb36931f9558595e0e5a951d8f3728b3bf76a7ff54d16eccec6727d758fa0944246b7dd064df1ccdb9711cd46f5888bb2edc75455a093a4d90e0e44588d53d478e9fca8b9242f7cf36c5d874bb43b34463db3a502b6cfc0b3841504e4dda5a1aeda6faeb552690cf666a4d61507e5ac0883f0cc74645594c17b6028ce98a368a608e5d258eb75dd0dc794aefe143f90e79546056f9dea9d808cf8c1b8fd795d6cc629afe27229579d36d0b9be7a16ca7fa2b389ecac698ae7f2779ba265ded27e39ad6a7c952ae9f24b555344235282a6b6a18eefd854740a6a54aa7f8ae504764f943b7dd9f704cd3914dcdc6e9376aabb4cf53cd0dddfe1cd08efde88952add6ca404a08c7e9e35176f87cfaec7f4dd132de69cc6a09f711edcc2ab20e136f9412f7151bcf330987bcc5332408392075a25c27e3747c65b5206a91483eb501b48cb5e07d501579b5093255d5e565cf5ca6247064ddaeb7e909a190da61348365c1c508820208ba282b5d48199d7a947ce9946f633bae9d24eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc7419d9c67af522a744a506e73ccc5afc2cf27663e813bab0c82c6c64023fd4cbb5b74d6d5bada2a33ea3f407cf5239fdf56bcbb455f39b9d69813662281947659534f9443f84266937c1000d8cccc430d5f9821126b9b28226d8a8c1d7a247e2d0cfce23c52c3a2c92fbbc45a86394500f7d984c9103bb77030b41b6c885b1ca1c8b1107878069d2bcc23b52a38651c8090f3cfb023826cb84089809e9abdf107e0b261a8ccb3cb8e10434acc40312ae18b93b89323c3a7676d0827beae3b4e7407827579efe5750c47a322bf76851a762caf62cc64370742ac715f182c4e6a77f47c5f23644f42010fc029c49c538c9b821c7761c1d2c27d7096c9f66ac8801660beb39cfd23e531603c7145d61668a612b3406d16feeb67bc5578bb972147fbc5e3f14059f55c8941177cf24910d1c94f1380f2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecda81133a299fbca37b4a69ad509ba44403ae3e5b2cf4277c8d22b68fc61f5e105dbd8c31f99609ea2770058352b81836b473ebe95c9cea90aeb682ca81b3e70508bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d3270406e5b4589f5401261b790cb02219636ad9c65ea5c48ce79c2cf4758db9bbb55e003e0c64f9b025ddaf1a341f8c2f26593adb9af185915c0489c77f1038abb9802ec812885af603267b7457210f5a00c917039b1b8e1bcbdb8b8b3ca9418d27ca6e96644f7090322993797a54bcb13cf59428d24d499c6f631e8694c50389496c6454fc34aec2677ebe05a0d61cb7ac553e2017c93d7183f06cf461331073786712a2566230f191c8169a1bba3a968a44a3fde764a0b5724e74615f3cc0f819616bbb21055d85f0fc40c667048fec26fe98b901b67a2923c57e17ccd2ed20f8c3731f10b58b7e9234c4151f6f4174fe6216f5aabfcd3b634122896a156bcc0ce93f41a8a25cd825334b53269881a682d8447975b45e839b8fc54b53f8c70a5aa9c786113ffa708ddd5070b841b58d25820fb6e4d8121ccd016b9601dbbfa4116e1aa9f904dfb5ac2b4d607f43a3961161e02092b9233c75b7020d5ab4bd7e3abc3b679c6d003a6a072f0038983677f606ab976474d8616a5dad0c15ebc10986b9be9f19df7c740fd1198adcc019d43766a847f05fb5cd7c16a6215a0dc251c894ac585a5b530e2611c839e98786fc5d1c1b0817da7c20dfafbc67f62bbc872cfdc153d83f328814abdb5f7babdcbb125298127a83bdfc503d6a8a2359136225b2bbd9baa2a11050774924b8662bcfc608848840cdba8f5d72fa3876ea79784e4784860047915c8922c96bd8f625d56729b96d88c3dba9eb3aa308a7940e90147c9110770f712cfc81224f36fa61c1225ca7a653c5ab8d0b4327c014ec580b9b347d0403c235b25cd88c992582d44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f6fa1f9e8c34d46a391e80bdd48691a930b3b0dace1b6b4b90b948794c14ec7b767ea6b2161702f9f5cf7336badbd2cd5bbc114f7b84d73a24e0049c03f83fc60b618ee23bfc5a286751970bc37b47432f982101e8fcc3ce01089d5898a46baca7265f05e4027ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedce0373a39b545738371499e3b7c88d20179434082ca235bdfa7701624a09b20bc65a10dac15c6c14268fc73be9d7a2f6556044c49a2006403848a726e767d2713be1dd04828da143df7860a9253566c9932fa54c9561ef5a26d990c308cb8a65ec8ced7181371a517c16a28ee9989f9d5acd50c8ba7085e95c03de98c978999c37195356dfb2e1da0768647c2e4ca6ae1d6bda251103ed17482cb0ce78ba17c69848475835a0c2e9d08b27bb220185a7ca40713aaa70068f75140c37d259150e6b4581670a6f8423a5979645309b7b0ebb0e911a68e46c48b150552f3093d425761196378863c431605ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c13dd780ec5347c512cfabf4c2e6a44cb2b17993c7c746f93c1400a5db9f12511e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 187eba72434adcc60ef030ebf26c2b60cb370bbb217f1dfe1f662002df875aee461d371fac4ecd85cd34e406a2354d521ef4f24ea61231626a8f856596c2560a50a8bfa277e92228053b535f2fd7e88b8ba7fac2032f508face47ea7a8028d5adb5c200ac93dcaa8a26f521cec0e26ac0c32c0244044e71c1db0be8fcd9be389aa6a3b9bb51facea9f4a0d6d94359b2a04326d78f8fdb4e03cfa813e5a27ae1ec5a14779e3878b75a670990616d89a3e3e1460c6ee8c8cdf3c5971d3d372be837eee1252b5428e7ce752a0af05b34c1c40c9f8798f704466b53d83eb2be8233b041cf6c316c93b225d207ae6b3e9494900be4996cee6dae35d39f5a6bbf230bb5d99cc22c9901187e49221183935a5f4b696e449e925c87c9774a3ce2d0d189655beed14a4a33466f35b79b12449188b4f8c9e20d48ec98a1754231488ab6631e08617732857696df0924a362e6c88731e95aa9e8fc995744db8dc276fc8f6bb92a4b213700f795c8f888fe478bcf609e4e02db5330f3a29a2163c950e800c1e6c98cb86e3432c298529d7c678476a31f3936f35ae32a0e7ceadf56c38ed0af6aa6677c3d422dae5d259aff44de8e841736490dcbf8f2e5aabfa4b07ff71842c1187b9df78864e6ce527f6f5235279d69938e4b76fe68dd5e9f5bb87fc05cb87fc2bb8305718db18d2ad6034029853c6291877c6c8356a45e320698d342b327100e975ca9cd4b76b3486b800662e35f3acf57b375d253cb6e4e7e64779f00fc7ddb6b20693cc733e42110015f390223d168f59e000b75f9296d38649ee1eed28ee32e779d2a17b5a908e6d8855380896fa30932ae5996cb0761ab1a253e51fab1f564cda8d47b111510db92c3b8aa28cc406ad5a58283c3d36ce9d35bf85ff74c653f9926e3d9ab35692f202922481b7523c6c7d060d72d13dfed44e4374e6d95ce4a70d5e44169a80d8cb1de32d5cae2145cd90e96940fc5da4b3a0d14ecfeb654693f7ffdd202624c25d99aa254c45ff1b7ecdd6d0aeb786b8840fcd07c8aa9cd28dc15edb8be3cf5f8dded47ec3efed3df3e92ab87cb42d724235366339b4aa6f749af6e79ab606c8bc30f3903d9938fcad6c9f27586c3fb8d80428dd32683e0ea23b492bca855165c1e1ec9c812b4b7497956422da355539867392ce79c914f239408e763a7534331aa59428536e0cfdbbf81601d4af3aec59c4979f13c0c7c9856481d707a71d1a211b087f9c213ee9cb276ac05ee4a8938d8e9cf3267401221bb43ef369f7f3ae287bf99261b28f5b4377cf53be63a5da6e797dea2898f64d8ea52dc69b5de4c092639f168a4e24f202195afcd09cd9d7b9c1a5badd8024b2ae433781ea798bb422756fa17e5d1e4d3c08ef89e1194eadac34334ca6f6f1a69a79126353af5090cb605867bbbbc40d3f0b48e6c2a6aae40495d85c2fe9313fcc3d73b4ee0bef24cd3234c7562606144eefe5752ed1c9b8c81a25a8f0d20ce7bf4e282c934bce0c03cb095d1c54e13b85182886000c955db44b8d608eb22a5ff726645f28a1292aa32202a1be9d519c01b7232457cb32e633e8d14c3e90a51382610e569d72af874f3c557a944c2f1d3f172d0e9580431bb5cbe99b9fa564f6ebde1bcc3de195470bba8d50cb8d8a254522a32754a64d579ef292136cd80394e5a4aaf1690f2d42f9bad551e1443e120bb0c913719f5e7df94e95e227a9b5e0370a12629d37f12308c73e4eb5aee6c0b793df2f803e22d51d21a2b9078d3bf899d68f53326ce9a1d319ea9048d662bca4f455b1b7491dfcfaec3428916d635d8463dba2fc5e0833444ded908da99f2eccfab6d8c1666904ce96e57da3371b651e22a7cee4e123d362ff68db36283a19960b4ac3538cac26e7fe95f2209b66dcf934f087d5c73623a4eeabc118389cc12b993c2dc7d24e15af7e786bcba1ff7c505274027170055964ffbf60a1b929f773911eb36489e31d4c5107cb6cb4820a382b4d558d8f5deed70fd4b2468a2972fe14741b13b7b082152848d8b04c56cceca6c9a6f9917c6678d114db15d153911c622149a5319afafed2629b96734a58823a153c0e0761975751a291287a41e50238a065fee87a9b4751013afc304b4ffa822d3bb5c55cfef33a1223199cbf251c38e0ed11acd32b6f742d549d150aaff8688f28c66a803c41af1c52142b92c8a1ee40ac404a8f2cf45e548e5624 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0246c2035f46911b525e6c3421584bfdbc83d73ab936e76a26236a862e5c78db7dde1edc2e038e3dda69b5bafe9f4997d8589bdb09e9be2cd46ce5e8e6958ae79f51470d9d185b53456b5e16d592580fddd0f6677535510e0f602d5ba5b61c4410ad7facbeb5fbb38437f9d52266577699fef205a41a2af084adf648844dc9d65e643f66af97e482fd36a2888d3fb9901355397f37875a4494777c781ed4d479dd9a831fd4a51e5702df5a74b4bd91676ea649efa26d617d8dcd06bda80e14dce02fb29978ca5538ff2d4d316a35433dcc8ff7cccf438dc0b11c548b5cc08fa45bd086dce04ad2f25689d1fd57fae44cb1574c42e760cb43ec2ce4be178f3dbb2870592ba84403dec417f9869da0894f5e023b856f1d6437d6d74557f60a856e648cba07f5ea23f7dd7cc65656b4692fcf4278fd4905c4aeeaaacd3644ec705b504cfaba743dec2745ab07bd56f1768447a8ee0d676ec904698eebf30f369190d8c1dadaa5ca69d01ee8a68d4dff04298dc68ddc57bfb577d89cd9a585b249d89847cd3e96ca80e9f8868bf7f36579887f4ff913e64acf46cbcb4673f6cb8554e50c9975a13938c89a68cd0b6de5237fc9dfb7a6bb94e1cd85700db821636801e9ac84f35276065ee51d8bc1d755c1d4f8567aeca386fd050458dbd7d93567a4465453ab8656272a3c03b4a3c569f9271437724471d5d4926109c9792ba49e1e7813948107df7c33069eb3d4daa847db7aef3f35934ac28666ff7fb4408ff151f3c26c96cc3b6a40daee876e55970f35f81117dff0dddd71bdd9e497ef137ad8515ab239c33e2de638c436dd0c89cfe30b8f8e69f7f2c59fea394700debd637be0876c3c388cd0e15469b42b80bfeb8681dc7716cfb248ca6fee9fa9399b72d20f3f9517f29593bd9bd936a0f6abba09bc336778247db60d9cbd0e8b3d5754e01c8ca97eab822fa4cc399b5be3195cb1e3c9270d30b06dbbe3295c4de898c60f543599e42cf48dbc85d5ec9a9d93cb6dd4c9678c1cc0a18fc5632af5524f603ddcd1fc07c27e6f8d8afd9b4748e6b5e5e71c18a3f9737bd6d3420d4bccbd3a5625af686e64d62ce4696e16ec83ccf587fea618639e51e63bc6c64825eb50d4f88335bf9145bacc4aef8dd564b7a588f17fbcf30bedda44f3acbf8753aa67fd67eeab9198cecdf9bc722455bd267faf98424eba4031c3bbed8f98a9388cabc6b3beec7a7fcbec8158e1117a9d5514d7c9f6d99cea65ece641f69454b7adca9bf86a3dd472f8cda7703c6a5b25464c1bd91b39f58de673220857878434ea14cf50054fb2e63547e9be161d7beb7a78cd6cd0ccbe462a0347e72b51a15ccb5c333894aba511295b37c97c7f5cfeb6d97219559b40a67310f457119de5ac1b8e3bee5acf85689d4d58ec9adbb18b75626de1f38debde8ba70986b39d3368e1f978675a49fbe850a01f39a1c88f1df4adf0ac8b68a87e2b4d3373fb808a8be19247ec7e68b80854b0e433573919db954afb67999f9878a32415b78d3ff89eeaaeff3f98fd38abeb6abcf5a55bca388004e46375b7f9cc45926a7c3e3bc8b4e3afb196aabe575eb643cecb50f666a1bb6da5decce8c6344356a68eed44214453d03b5ccc9ff25603ca7e339380d63a4e9e60df03890d07f3684be0847b89df2c467588e5d34942eee95d9a19d4f50855c84ed4ebddde22893e3774f68a84bc1a4db2d5d3befaa5571c3e869b238c8ec7aea5b7d203e67a0d9851dfef3d390e777c2f43e2b6328bc4aeb10a468ea96db01b77f68cbd63e4bdc157408ad378f637580e67f3b544bceef3962c3a49fd836e993386e5efc91bcb92736fe697ace32a0879cbb49f500efb47be94851b76ddaedc2054d535f9529d68acd39ca13aaba696237c400c6b297368f0d6c3050de3824783a1cdf048d5cd1797c5d61b3f589f715e7b72be1cba7c0be3a638720f7962243933bece50ee6bf6d4368e8c9cb985b7a0e5ea36bba4f840a8b3054cd9fda45ff937396ba8433bd3e75806b0e0a77e2e8cafaf55c69b44bc626c3fb6d9c37d1a83180e89bc5c47ab44cc82cb97732b8ddfcf35972f4cfc4894871787ea25493bc48e4a37b70f4d4e77436f9b9e970778c74f2eb19265628cadbdaf0744a5ea4507f5b4a0e978cad763e27ae12f38bbd1a34ef3fa06111b74ab835cc8479a8ebab78552ab3a3ac845a332bd1200c0635d3ad6768a4773aa803ebc08a0d7f772ff78ae9c90b5dd1b50e86724fc89110c128bda8209f0173e4d23210910bb05832b32017c182915308563c938695a0a8c49e6108c972587b04e6c916d5ac10ab425c15b370b0a4273d33530245048e62222d6211caab6a25332651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6fe701c23885e2141df14b4933c70040a295144a74a440487741116175addee87e656136a455bc9d1c5d611a22157aa3dd288b4ffa1d79668bf152bcb71108dc5916a223a703d376f3877406081c45a08470e4ae5679b34d2b4381335d8d5120282a656f121a861777d597a3b8910a67749855dba05f36831bd101ebbb427c92bd62f9c7f1a99a47c94e9dcba438835f3e053011f180f501c82611a64ec79e8b3563816a3fbffc5e033a114b8c94c9fb3391e0bbb8d4a33be98b219500f53b782fb2482fa9089b46b6f32555ba583370622771d02c6142647e6b87ddd382428552e58b80a66255394ab3815aa014c31878b74e7121b9f6d084edba988b43104910677aa62a1b27035de440b055146d15c466ea340b4658a41a885fe206c382923fd079f988b831a99d42241cc8637a647216eef18497298509832f8ce55235771e408a4bca646284771a0ae66ecdc2bb9d696d799c3cfad47a5a8b49575618bdac931d00c718049760f880831092fe3acd56d517377b00b156accc3ca6957ab22529673a59bfe87846c5431ef6b9c6c3201841da1451b881b2e26e44ac71e8858eeaa55aabd45281b56345222453440f7e427ebaf90bcd23c75e1cc96776ccdbf92766c778ad3b0a43a82463d09d79b90919eb76084438413573eafa0a60d26bd45ba0f75824c5808112406950d1ac5b226b9332709d1374b61957bb20ad7c33576bb68d265c7ddaaa12788c9e015a96009c0f99521e98e5c0cb38089d2101ef8700fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794257a277a983ce87c29c18f8535b07960bf20a3014974883529ba033a9604370a926778689937c774e74a3aea922f5fb717a7b73631c2e1f8c33f499674e584dc7f48e3efab83512c0f723ad981452003840215912e3d0abe816a58af87e1cea37daec759da34e24033c1842b2dc0a6909991b9e205178596c812a0cbaa48efb3586b5b6963fd445140bcfab6b4390832de8e27851b10619e699836a692bf44ceb23cd1f6938222b4b83f4a25a0c0c9ff397195bcf5dca633952aaf0321b121518f887c5ae945821f9b1150bc1d2401a7547ca3386bc33232cc58c6370508542994ca6cb098b01033c0c97ff468bc1c726a992181882ca810115fd2755ec18ce0f88cd37fb61580c039ab121ce95af498bbf4eea277eb780d3e0a0959a388d6a290fe58a64829184b763d3636b0551a90e5a9723b26f2c4869ff14ba806153d6ec32ad4c42d27161bf051be85303d9167245684bdb3198673c668e579a72136b6d252225b49f25746298532990352b90d82f6e324fb5877176555a078b82ac10bc8ea63a2b9067f13026584abfbc473909d50c58e9bc47bb99308298e6e90b3671adf643742e669a93e2a90b26723af4cf6bb64446619bdee7b5088369fbd737af0c4ae367313c699f384205c14c13c38599604390c7c911a5781bc2511208679510dc0d0dec26ec46718c748b59418bc353b7618195b77992858c06ff15a9077a37ace35101554e8a3932a9a9138a800bd3484b1b977d53f50a0443538aa5516780a094e6306e7842ee6a753c412d2a89c23eecb2b26a6ac90b3e890466a557394b520a07cb671ae9cd2c43621bf55a99a98392b9cfea6373d4b136dafa78c6e93ba7573b429b50be5949a254714c720721699290a510581b6af396879703aaf4a9781268446ba96a072009ffea0250c793237744e36bb0d3d752e1a6caa346a2f9d1695d49aa1aa2535c6449e8f4abf85079c0b99b91ac2e91613de6368c430a886eb15b192805e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c4d1a15b5c335af4091acc5bd189176b477938ebc700042cdbcb7385e10c3121b179660eb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d5acaf411ccb64500879102d9cdf6d9fcad673d874a4153383806fe174b2fc1e393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = 847fb7979787cf06edd5ca8187896c920f8b275668939297c3bcd2e23dceb07ad7c62fa6accfd6be9a70fc1af69c82cdb4c6dbfc9b598ab08ab9e5a4d0c5c741c8f9f3896dd05f1c61246e517d1e88bd90e6eceb7ef563fe92cf8c17f2413dc19d9eddb96d57f7003b595b51242080b2d6a5abd04bac0e1e8075f983c452e16b8dcc5c3360fabb9fa5fd3671b50d3f7230c65a46b0e04c43278b2495fc45866afa27e387a967e985195037b4db1ff57f11882ef5db34452e587529e7f3b93ed113b0b82cbb9cafef86f90530f21649e22aac11f062dab01a5fe8c8fbeea23d9a7f4ef172387a6b08bf281f708cdcb060f84a2054eb3a996c35e30d6f87b88f76158413b3c01e50ff7284888e6b2600f77a3c08df381799fbb62c187dd81e570b2b14a730b55738da957aa140499c0b2e3b96aba03d2306819347b0e0c3feb1b28183edaa603a60cdc3a4c009f2c0fbf001f783b54734785479e3a95b4003eb0c57afb24c1c212be1ef92d1e9855c10c4e0f7773b3b069ca0de87c103ad4eb68257e64ee16e657f711159e22d5f9894c2b22abb8c8979d297dce205c20963307a151d2a2e1014f97edf1eb0ae530f26cccf31bc3376ba1d5485e3cd47360dbab0b7e1a9497ad6cb8edf1b7a37bd9d15431b5ed36b1328964f2f8de3ee109ed9b1ad2b5411d1c71733862793054726c0f733fb7447e59760174e059aa4c3ca6683e6eea278ed52d36d13c4af8b7a9574cefbda22104e93942f147eeb77daf30ebbe3b90543f562a549c830a5e0cfe91c1841b6668570caf37e274f8fe49f29c0eda1bc3d074231b4c0cac1816bdd8e9e32b714fcbe40b853415f8df08a4e859a65bda61dcd173c2ed6eeb080d4c77e45ad553f1211f478163e9a548eb9b275c695a00971498b248eb3c56fa28ba886193a49d135bb85909357b8363dfa9a5e420a48fcddc95449fd1d2ffb712060033d4ddcdba89b2a9cb1dc4cea293fa6d46480f7b916b91b8563b17f9bd0161512766ab6d8f1e70acce3af223fa0217a843e7bca4a9bdbb86a440837d6766d9900f292124f93b71133ee6e6091e5e9b3f4aacd3ae9e5743f3d41e851001788b87680f07b80259ae213abce3d119b191e6877988a2dbf56027a39dfd3b00cb38dfa13b7663781673e745de54af5c3b3b0dfee94c8688606df28f6af8909e04a3fedb7afd7c19e27ae2b0e7b7edaeb59a292880bd08c74ec2a07fe47c9c6070ad98099d655f263960f9c0a06ac78570409c391a26ede69da5976af32c16c156a733a1c59045b85840f5cd01ad3e708b8925d5f46ea49c51845f832e389aff2db412e9272e6606a7c1a7e69237a25bc552759b3fd0eae62e59ff8ae8891cabdcc8678ef2a0326514bea8a50928261f7e27033de9afdce4eeeeb5352c9f37d6a00d96b272588a3390ad5645d4f9a497d4e24649e2d84f92bec532ee95595b9c3d64e96408c9292da2049264b595db45ddf8d252eebff55a24a1f8fcf9c8a4b8525ac2b129b396da03d3dbabfa7ad085c3f3ae03d74154bc63aa631e84721242773f384959869c36efb99e19e25f1343f3e4d5ccaa3b59b12aba72571db26315991ea6c1dc626bf9ccfd03ab89412435c1e1ec283aa6da8677655380e55d29670a0df9e5aac18bda35cb807c4bfaa6bd3e3324c1852e6847b4c15f2ff8473427ff475057c75ce75b49004568c61c7b891c8bb2d7ed9d7914a5990252bd34836bce00a63fe5b3b06d6a0173554fc5aa11650ad1cfc84ffc1bf2435a8cd0959f0a13a3a38f239ac9e847d858b18840bc9a3471303a7aa77cc375719de84f832cecd0885057306705cf928a7d78db8d03c8702e55c44f6debb0ab613ea31e8498e9afe9c3f51b7ffaa5ff34419323d4bef3eb4f120464a64287ce75f5fe18cf6cf596a197540ad31bf5c157758d9c513631f3d5db093995fc89c67f6623f48d9fe23de28f8bc2f590c3ed5b9899aa397fcda3214ddd30b413a047f9765c7b0606e21ad56bfbc5cf330355671e28df4eda19b7ca89cf6ea84da9ad0f8ed6d41c59d42331828916af76f13453265673a8a7f03cbee6e70894bb6b17cc01efc9ad0d45ea6a6a73d420d097ef5b87cf580d179b573f15790665816530a9a78a8200bdda59b73d38dc1de856e5ea100d51d46cedccb3b2fb60c043dd7c9b0973f9e6ed2169f0ece4dad007978997fecf33d9037abcd7d622ee0 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 34d9ef6ec981b193d501d8969f8847b2c6bd5d5c43e0ad44c43b551f7edd5675bb7e7c9e393b411e6957540ebf4ef4c7fd0b4b5affe3906af54eb5540aca856c47ddd28899541b72519ec23907c0449dad32a56385075f42a754577f5450ee77b74c7ed9a5d7e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d63de165a47392efea7ca732fe9b3455c44ee4e54fc3a6518e5e402cd5a2d4a4f9b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5ddd40245543432cdd2d9d913776e1cfecfeb928eb21c8417e3931aa3be142ded51cc8faca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac85f4f3855de3cdd967b7bee0668112e5ecccce39fa73374eff685a3cc06838b15009fb65ce7772053de3bd5cc4e5e832b8a2b94f8436d99e1f2484b127ce0d96edc9beeab1cdd19e0b3439733b36a7a600f4638e9fdba66f4b445349a86465e2bf5de797f07deadb629cb472e4e5a42a8ba29eb76b68f9d4d987a3bdc2366fec188adbaddb603d755eb37396cdd57ff86f76ccca997c0dcd481587cb97f8841df1dcbb8479af67b744a5c0dd8b4adbfc1f7f6121996e55c6dd40f6975637831c49f845d6823d4b909225e149a9f794f4ab29e4e64a54f39f07c365a87ed9786af7a57ac0ccdd4a2de8007b6bf87d5a22bd82d2ed40a4f4c25f3f9ef9a8518966d44e7683af94728487a4f963d5d5ee5aad45c041fecf9c54fc51abfaa47a4dfc39d63243c21f8b83827e701b4b73516944efc4b61fb5bca63c3ed13ae23f55b832e6c312e8bc49fe45d62953f6adef764dd68f2c9ca05eca8fcb34295f936e4e4fdecfc04f65ec837d71f99c7c24c991f9c97e11ed51694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0cbec2d3e859d3fbd3c1af3b2915e8ef88ce1ccdffe71399f07eb380fceaec4c7c6bf3830c2be5f87e8d0e57ed10234393d94fbd43d5acdd9cdf17da0accd9d7497d2f9b939794b923eb3f28c4d904a53a062e6a536e32d9f3cc656d6b41ff643424f645d79481a8316e8cb0aa4fea4c63da0bde39ed5953168a4ac864c726874e1366ab0aaf49f35ece5b1a7f5cb6dad66375bfdbcfa3d7ad24ae364acd3327e4d9fda64581dbd0a696557945c58e96c1c889be648c4885958adea79ab31fa0bb15506bf5635e437ecee47b6013fb4273b8c978d6639c87031b6e23c7e996b4576636e2438eae4dada8fc18ee1d9e667967b25f76c4f736f4cb29bd0a865fd67a4dbf14acc8ad9871bc7adeaab37b298f12c6db647fb74178e627e4c8347cdd3449f716fce73b1b711b2cda1e1eddca486bd5167223658a5c55bcd0739dcff3ddfcf9bd8aa45b3dadb5aa0f43547767a1843e4c8792213e819e09f5990dc6db9bd270f9cb8f36f4ad04ea984e870b0630e1cbeb325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310d5eeb565baba36be54f6a3152ae04a1ec38ef78e62fe654ef35b2c836c242ea52fac710d7bd3811444de5b8403569c8ded444e06e6dad54ae5649e68ab437d0da2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee8cf3608cd683a38f6fbb4bad4a58ff6e3bb322fbcab3dfe6a997c647886db545fe6b94e81456379e7550db446a446e6808ac610c3abf273b02b1b748296a760d78f041835606ece2898ab3b09d79576827c8d557e5ed00cbdcdf598ed660a7c2569613ad6575e4c528a7c5b9ed9e366bd5853bbf00aaba1ca98aff17a845b2d9fe4a3ff30bac0a8873cf5eae7f323375627adc4786e917de0f6c9e3342efd0bfaf56d4ae26eb39965db773e7c3daec35060bbfd782b9a779fbc415f51724e6e7b2fe63d36837ee3c731ecc38f7f36ad09712c4e44041fe3bb63f58033a8eafa677fd8a2cd0e3c5ab46a3363e968a9a6c5e6a89613aceec3a4cddca52d0ddc21d85657599d21d8d6930e8a08bd61dc6d7d7df491cfe59d90d43a6ec5f454bf822c7bae0a33368334697655e6ed1d6e8d79e2c9c35432984514ea5eb9a65c3c0aa24173bb7377f3022a6c32fd6236639a0e1af5713c5a7855399637aacecd33c11e744783d7485d7b69bc7a3f84621167ac83e4b45bbd3b613ac4be8fe7abb799028bea33f55a9b65db3857ca53438dcd157b103c9e5987636a96b26372851e703a9bd36d85e966fda580cc79af69772c2a9a7042363a3e3c116dc7711ed06fbf956dd06266329002630508b7d1ca73cbc853e62b23a02bff7404ebe390fcf58bd57262cf1044aa22225fb36446d44e1b8171aa67c415f96db0e109afa31fd00631bfa23f3b6c9c02b20dc3dc1ba6f30e6f20c9ec7471cef6996350bb87d43690c059065cacf697c63b6bc98c881d3ca56f07c34a5b0b10cab263bb75399d162db389206939b15df58448837e0d443b8df132c65bac83d2166c780132875fad888a1c53aea51661c135cea6956c2a4b87a53baefe726fdf09687f6cade7bc9ef5bc25dbdca95a0acc47e0caef22159af5b499fb6e8643c70803ba40a5938a422433053bdec4b729744b565066962046c5d2bd14f14bf0b4030be99a8a198b80b99ec939791bfc8572942e98d47b00814c6a85c39ae7323cebbf353439f3961f0abb687b4c18dd06b706db4350fc4a2e868229272f499709eb1450c2995d9b809e77e676b628aab0212475e602831a367d3948cdfb0d43eb0865eac55c516069893d09f24a8176a3beca0c6065abca0a3a2b3053da2a3bca6a7088f39d9bc8b1e685b67612413aa3b2ba4673b301cd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a8f134fd1cb590819a65190af53355a6483b6a9909bef36c76836c77168c679757ef404a8528cd569911d036c751d4ba4cb1c34b695caf487866cb1de5554196682d32285490a75fb5d18d3b40539adc4d9ad71452016a6fc7156b34014117bc0dc45eb319a1f85b642f7ca7a12164bc7a1feb9114a7c5ba8d7456cc08a883ac86100272b710b225e49de711115b418946f503586076411c6ca3ec11a5244774a27baacc543556582781b273bccab4326b4140b5643c86d310331bfb859f80062ad27e38ea1724dc4b7c3498a8601c11f25c99001db2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8ac2ce68b6b8b2e51fad7939979593f8f19e19b2c18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01a8065c6756e6ecb64de11fed0acefdd45fc50c1f51b045d8e096a9e77f10dc8e8349b5da9723a1829e2ee3cc0379942fc47841b81df7a94ec7f40bfc2b737d9725486316c2ec3e2b516dbf7cb4936217cd4b23e4422122854791a2cb136a1236677a4e42504ae43bfc93259441bc0d676f8932a757c087f806b59e6380197b37719a2fba88b64ca54fc69ac8e2b79df7154403249441d103f931a25283bcded4c8b51a7995655d49611ddb2ac406b28ab2a80342f51bb8126afd65412b06d0596622e5722465b846a52b47fc6b5842f12acd602ef9c74065d5940d2462f7d99d39ea5f62b46f9fe297f1c01f5183c73c3ccb63c564dbc4c1c60877960202d9369b750129d91060d1708f057811e68c47c4b68781c102f2765e093c94f6c43b784679c4257287680825fc5116cc04b489add5a009a3e65b09644d5a9a9745d249314c4693f017a6d5b054d07fde34cbde568ea6fb9bb56c8c5023142cd19eb2b3b0c6b8bdeedac8b78909b1bb1894b382e6fca4fcd63390cabfb4d516fb18526bb45a0f9a6aed971050788cdd044248839d954594259b562317cb163273b12b453638b70be1085e51c5ac0b6cdd15c218103e92c53750f107ada702d8725548ccc663947c3dd959811842b62b13f9a24b1b4a18f5691dc4cc331c362747f1654e1b785ad1c07443aea2f6006bd670d7128a8373c68aa36ffc59797ab3994bea35ce894466f0c64c061b5d48b9a18c5544dc0820479722795d77c85f161b865dba01a70cc9c00c15167aa35bf0a147147a81d540346489dc58926c975333cc3d286b4c529a2e3e6aa6d2225016a7126dcb46669c72c453bd745632e772bd2da7c1ca87318276ad21ebbb6c419ee2eaa46a733e3934c0ae933950da8fd2eccedf2919d7e8a6812897780275adf78e6dc21757c7a0a489cd8cd95126a569af7c67bf317b146743b0d32a6762103a13698120cf7d07b72be91177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516c5115c724af7cf05049a012c8e601e8b5237e1aa5652cc5e4e1a6d0504331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8152641a683dd690d4ac3edf0261200cd9244ae7dab962eca2f3d22a554d0802eeac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 8c37340c59cfd8a543f9b76adfa38a34ceb4001269edb19d3acadfafb41bb5aa7c1b734e46de5046954fcc6188dc046bab996c1900dbdeafb72d1f8a3c4f51f6d118755cbccbc597f525cb827657dfb2ce3489b53e2a5ea10f73bbf1531770483ddd4083164e64620ab483ebed4a0b49e7b282dc0ddfd8fe3904d7c3d168112c7bdf0694a44be82782a024a105c11bd8a1401bbb5d0f97b23026d88449ab41d5ad616d647ba7b31228e3edc05c529a0cb081a5c1d8f12d4a6f0a6ee2ae3271982a5ee9ba9e06c0d931067b13fda615d30168c29add7a3dedd4ba1069bc58a56e66eb04f21cd3caa5b3e7655ba88d19f2a8060d2ab31b1cd73eb31a428bc421c8d27cb9c03bc9f866b6250488f73bb5ec1a9851c3607316c9ae0b47b39f2729af9fce32f8e1cef63bc167862365c8f18f36a559f6b91ee35d827135018c9a0dcd7431778996ebe3a4fd009c0f4d8e94c6d8089960d5c16f152d84139989836c86d1c4267322325a93025912dbfe11042d5cdd2e01ca8468f3dd86f29a7f33de0746a5c53eadf5d4c85a9de76e2b8ae4e4175bec7145803e5d6d57625fcc23186d1df1ff08c646dc416fed539b91443702331b8b46a1ff6e33573f474eecece71cfbea722f0be68fb6c99d815f626eb15eeacae5333dbe5479c29fb82b1e4b59350c5123a373b5f581085f3e388539f76864184596bc37424aff1ff26feda8833966286234e6f81a759a47f2b79aec8de967c4527f12ba414d887e19bfa224c99def53b9f66f44b695b5d24230e2440e0bba3114f6553c85df67c850632cdee289df39185af65b65be5e25f4bd27feb4d0c619b54a38aa8c5d665500d6243dac963407b7b667d492b497ca639ebe0471364473eb95886288b1663afc1dda99927674fcf7ffeba9dce8f76f0900f64957948373eed776996786d3d91d42dc1c7552d82ed2f0777d0d231736e4f05c24785ab0b40dc3fbedd959948a515be53cdaf1fa044033561721ac7a3f930ddadb812e6051e067d8e0883d2421ca6564802d02abdcf4ebaa9f94eb6f59f56306be7f265d4f676c58a72e78427258d4d011329708763d7b2f2aaa69de494d389eef0025d09015c4061e558ba2137b8051aa037694cedf59380fe62e0c5c8cbc0d80b2d72d7ee1d61ce81d5305ca9d35bdbdebd159136284eac79117dd4065e80f0a72ae43236caf71ce09c61cbd9023042e6eb8499b6463d409bb94b2886fc8d59b7765321485ef64f8fb4455fd0c1f14597e9b90a62f38123888fbdf6e1d4dfe730c769d1521db0e29bcba50d4fb447417c4c2b838f5984af13edba3d9b5b547177629749461fde7fb5b3fd72837445c8779588bb88ed67a44a253449d6e20f2dce29e484b19d1b1bd4aae5466c212b84a626ea97a9d6a9787da5c5eda1f41c34cabb8cabc4d05484391f6140129a260f96133f2118782e242409532e4d48931c3120903b2a6cd728a22accfdf2ffd81d1defc60ae9bb8f60caeefe7fe12dcefe951b5362b1d068f7af1c4e3c7d37046f7bfa8c10fa1f21f18101b57a77b7d76df2a6630697d2c6dd772453b2b7fd0833ba67369de9c6eca2bf94d8fe31997ca6cee22ca2874bbc87ebf3fb0edeaa88fe262c355b5aa21b6bc8a42ab18a48bc5c30efe96fa75769f4a2d2fcbb872b6ed8f616b1b05f53c4072812dee5f09d33a38fa51cbf08239dd806806421ed0118f411fe38f9d4256b2b110101aa7bacf01e0079af5a8b60d8aa1a179a6189120a00678e29255eeb4c77f2d8453d73accc226fa0dca7ba6b00aa8a27dc2647dd8f163cdf8c6de93251c1ff97396fcf80ee7cb0fb249192760baddaee22b2d8ba73a38cd71da3b78ea2b107d6e85c2f637faec470377e064a61670437d8ab58be9937bbfac5c060f365b2200e637bfcec0844de7621f2c438727048005fef0b4c08a99e86397c7de530cd4014b055b8b66013477e8d0f0b009aad118448e233ec2b8b6beb3bfcf9e60bdcd541c910e8d8bb72b56c0946c95ecb9167174bfa90cbf2b03a0d7b6250e4793694cb48a8d299780aac15e40ab66d4d18dcd634dcb0e09894ad42c5cee716cef46fcc1be68d52342be20c43c98af395636b0c5f33d261d16a921adad7a0b88dbe8650b5a6ebb6c18be5a4615087817fd96bf0d0c96d74f9e7f3e06a2b3d5e2843159e26b90ca7b5995f62ba2b6ca3819b61e34a70129d9b3a1b5de +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ab4545850434076342eae840a0ed590c34955e96d2683d5fca05c347bb3e53bc714f3e34a6e9b338674a9aabb0301fed1a09a190757f03d573c27687f7e35f2d87f94e1dcded83f218395b3455f3f1c7d4b27689ddcf86b5c98218ff39c159ae5d6554370dd617b5dc6dc6b7f50ee2e7f37a103e9bf6acc7b0e3345c9367b3afb8d9d644947ff0c0b8e7fbb38ceb3469cd55c662eec58d06807504443448c4e64fd4dc59c60b5e53494478ec4d56c9a85967b4febccf87afda51fdd6b84b285523e4ed80a56f7a68a168a4527eadf312be8d5e48ecfdd578bb89f4fe687d3aea56089d681528e171b7f7e4dbce1b678762a8b03c3afbff1635ca85332af9df14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83c9dbec37e72ac95e54fff7b926f3842ee88d77bd40f958c38c8a113cd5b551d3e56ae59de0954f2477e798a573339508b8cfac397fa6244f9777ba3189d60136cd83f2e98d2edaa01967c3acf7373aea36b9fbac3cbe3ee3c94b2fd391e37d2c60f53dd497f16f39bdcb9c68ccaab642fd84884b113f7df38555422767f4f6e3b2e87affd0e395fca37df1aeaef84f63d2dd1392732daeed47cc7c6fcaedae6136c33094526876a1145e4f39e890963fa75a6e7dcefc97f8fe7659d995dd8fb663655df65324b1996a52e50bf4eb2a1d9df04bfa6f14e74da2becc7fbb024c3c972b971440dc684cf8a90f48b02cf8608affc3fdf5601b6d9673481b365544b7c36a965def20c37006bde396af68f9dce1b5f71e25feb473d3b80cbcc82ef894d7569e83cff5d8c6996c766bd5d59776f8cadd84a3f468c68dfd9117c8254bbaa1ba584dc2661728a69e959949ed6c9f1c4ff01ec8e566e4aec7e68cfbb5e175d4eb9f585c7789c48e59c17b5975c444bd6f3fa6654bce298a605043bd367400c14b1d9eea593ad34544cd4a44c85711aa66d8d7fb07378fc5f5601ce9d9a4a9a8dafdba7ebdb1eaefa46ffb6d518b469f9e21d25cf40499196376d3e9f827e1b96ae255aff288037793c7ebd7e1d15533c17e62aacae3255c0cc368e2fba3fef09540a5f910ebcdfb2f3ae376aa666fc97a4fef2570ccf797c79ec575836edbe6f8d8b3dbeb72e8f41c3679bf26df0b6a63be65b95a2d9e47eb98c6553c71c65de386d3e6b73c877c94e7c6d3a22eca457ce409d5aa049673d0fae7c124be83579f253fcb589186baa498f3958ec3d0640a4d34931033b31ff6ebed6ca9c49ba70cfe9d6dc8461937284235a6417cc9c0ca0ad385b05cdec81d5a7b97a34987f50e3679ac55c3d76d83b1f7b99dcad39dc1791482f3b5d7ce1fdaed9dc16fa1e4b7c88d7e0c449320949bb4405b28fafc04d48c58aabb46edaa58e54ff3ab6c9810b6d702855f7ca91b07eb0e574bac114ddbe864ddaa7682787483a4e4cf44e8d180fc6f368a10714cb26ffd8c8a5779f639838ad7e348841a127e4f41399da175c49678307d3634d6b992198dfd43ccb8d7842e5f34ce44a4923e7ce6b77ec7a989aa748604d147ce7bcf5a1533e80ab321b7aacb8e5f3a3b6f98bfbdcfda435d787e49a3e73d18d8280bd7b7855769eba987696afdf68f31f46ed2174f77bbcb26debb43d1395a23a8d891afcd71362e244deb68b84f1bf3346dec449353529cf99858494182fa304677008eaea13f8c8fb0687cdf688c707a73e2feef5d6d9c225dc1ad346a2f85fe3f58aae4f80f92c35125345610b901d3d5f614faca2f6cc2a5add1ea46e388d98126be957fe2f54154023549d64d799d6a7fe3b283108e779029cef7339a9c3d8676cf3e6ec9b9f09d654d8b84ac2df6223b36aedb584084855375bd563bee3d02cce4ccead3feeb69cd76efd15d4b497f4d25c34160cfe12eb58f174a9278a6620856763744a1f863bae55d4c779571d83849a88c024fe5ce838b524a9c451efb8592b98b4c89ceb35990bd39b74b87cef85daed976f40bbafa7fd3c532bda9c47ac220bfc256d9325ff62e3233275fd88e15e81b9ab973a4c727ef53d4009e5bae5c99e9e9537e67ec71d61c7c6eb7d17b72eca748894a25a5a97d5876d4608bf5c2b55fd95f43c2ee7fc9d7843e47c84df9e52beed544e905156ebce776c040c848cb85230dfc1498db87fa970873b8f3c2199c59446aa08c7646c1f567ac35c18b82cb24ab1c51f2ce8a79ba51f432672ccf12c23a5750e9c9a6818b628a49a812377587323b1e63d8f21a9dfc76095827cfe352667c16e888b1a621736c28c8acea052f8c4618591b36650a63cf00b904120ce716fcfb40db52347b12486442267bea46c1b778a98268481155c53a72c5731ac2ee36fb72c61b60273d1419ab8e82611921c99dbcd4e209d2af64a08ac27bcd21fb7b9373f8a84241a1bad24c8dc11203b3554ac802dcd18104dc8833a4b60edb07f9135b452209b65229bef0ba922cc60e32954096794b7248f94b134143b0ab3a8c2288a6065e7adf5049e918b3447ac156bd462a204a6d8d680761b9e70d8796fa149dbd45509b6169bc34ea8b876d30c7a2e51943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397db06693c20cd7caa079576834a0991761c79fb660843778229b2af530276c345ef8c420ee395455ab47df46609b0bd34e2aa7f35af596750c71c4aa2754afdc48481a018f2499fae61584eca38f331c571bcbf73ac01b349953081908979499f2bcd6939b81a5199fb5838324928372aa2efb6c8da025873318c08117fcf47302fe99a31b923ba947871c6ad7168246341ae1c567f8706b88f240473a646173a58d559cb5d3865f2072d99b78cb7d63617fc05dd16391830cc22e2ccdec55c46f84262f59d1718c473626f55c8022849935b3a32f55180dd7b67cf496c999189d177cceeda613721718b0a2e74e0301e667ae8aa36d83298b2983054a3824d64097e380585c4288be24e5e711f09e72d31d29164fb34ec7068987241266587a367b067284f3595663f927255c66bc7c79e5575744500792e8236288a432b092597069182c28667c51b76c4a422dc8a023127b58979290043cc79011205cc7e61aed141bcb4c090a6405263e3c9d613a5d1b5b7e0a8c5915611fef213eb4a9891d49f303967ec3ac40ee145e8724e8ae90c6eab8edf970fddb459b66b654c8c1fe039ce07ebb50e441bbe386ac39473b9a6a26f0ba3799155bf047ed33a56eda493c26b6bfa912cd56623b18254d84c3e8e34a23b3948d4579d1dc301706c835d879787cc5964334e52875836e4b105fb9abb613bb3ac9a65ba8f39470e3aa20bdb1741f1f78d527555e10caac4e17f57e89a520514716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df76281d4515e4229547d235be6b6925063cc3832e08d192b6193d6c02a0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fcf819403ca08684a418c04e6e6397cad03b77b2bf3624b89d176f87c82508c9cb13d60b9b3194ff52a7b58413088b2964b2b92b94463f2cbd92444a888154410990c2d5c018916b5f7059c2087cdae1bf06942d05d997bbcb289bfb0725db84f6e23c96da5c64595e96969097b8b9a28c5adbe36093203f01039a0ada6e63a21d22794405940142e0c959bc624619b964dc6b60a1cd31dc99c4342d1ed67c534570a658361376378e82896f216e57c21159967212481845c112fe0a3b1b4b888ce4c22b3c73fb87084d645359a23d7929704738af9ee7abaeac15cd8c6d87295f849341bdf68b24a85621f397fcd31a209b3089151bd44c9d90092ebd2844fe173392a8836876ccd9d97cad570bfb55523cc7763502acc4d337e8634f97647f4a0996514264b0a3c6681022b739a66a98b92cd0577cf1906bf72cfdb23605169d0ef37ab96baa1aac1322149bf682025c3bb7adcc79c1a9c8fb52c3d4b529fda48997bb71d18a3d4fd201000c4648b634778b7a5ff190a27c1e631381b777ac0e858db4033509c66bf1bba3a5828fb7f578e8fa51c7c87bfca883ea96a968d78bf312983e6ba51bd05617c90a1677159ddb6d4ffb62b8642e56eca75cba3f9d810102037b2c57c7502a60831b15b49c87b7a14fceb228d2f0b82e1a5cb632b8d3070560977b24d591e7cc0c07017a09104d2ee24e6dc2c3af1231af922d62629c32481bfbe309d5a0cb4b61c2eccc7e9bf05fad1a7fcfc3635192c90d76668fc91a297cba04621dfefa729996bd118a308491b59c16cb7077456b0b48da4757f23b90253ca5a2c1aea9a524e08293d77022f66b5707aa4f30f6b099332cdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab9cc95efe512c84010ccd7118a92522cead44cff28d6e223f76702a47694c8f053fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = 492ddd4ed467d0e58e5e369c7fc26bdc88d83193f7e8cac9bef9348f3eaebf7b621de26c223fb6d9a0906bfe41bea0489292f6f9ecfb668712d2b13b7581529e77bbe52c7484ef70307bf56f5c1eebd6ff89a501e67fc0434ea4410ecc496a534a4e930965ba6827b45624eb6155678aee08fa5ad5a8c28f4d00becd89f0caa1463a029138eeb409e3ee86fce90a53500d04ece098620e7dbc6ed6ba67626c22948078113599f0a6ffeccde84f9570a3744566aa5541048fe51bba811d2f2fc0cf6681dc19c854b7e115b02962339cce2bfecb378c5a38cc4cdbe150fee1364746da4950927b1a48957f7c3dfcc836eff46505d61502bfb5d15e4b88f335e8cb9136294b6a9cec1ddf86d0974e6fec6d1768b27915604b1c73b65f019c8521ead40fc262f87319cbda47dddd387d6663dc06e6eb730bc06508d33cfe7f19d0cb8a25cadfcc96dd330ebe536c8c01838006aceadefddddb9da6cafbf1e2c3788edf391ef0a044d2c30a18458de6bd9fa993500333526b171148b48e5dec630313469c2f95138669f6b7c51e68bf67d4b95faf4b53f62ad0d1e38eab35af79fe7b3dcda2829046e20f2176e3003a3ec9ee87c351285eeb0980affe05e4d4404c8c122e1d9d3280e3af34d98d153cb0ddc25b88f16b3632d46dc187a0514b10262060a59867ce8fe781ca067958ddad2aadc69006eb980bab6a1fb515dab615edc771e5486ea24edc602c4526c785d0040026bf193d80e68e49b9c00cb00dccf3b3d9fcf59856fcd3c077b1b62abcc2f4b5a173b0716f833c34e1d5f33fe11010a02d56ec905b475212e01cb7cbfd47cd389222d7865ca484ff9bc6beacfe18dd9543e1cc7ec5e925e77ab33b5fee26c62943f8e95cb5551c21990ab63b33ca50ee4e2c4159ca4fbb5953ce7101a172d1a6b51a92cb7d80708625897f09c71ac2dd8491b0f40d3b287b3e2ad547557b21e47531d4029cdce70b580411ef0a5107491e8fe60d01b44d9849fef9c4e07a21110913ee320fe001102b986241fc6e914052e833271c6fd9921be7d794745af164e3a9851d3396f4544142b5c6f560d5f68c2b5c7dbe71eda07a4c4072c2f33636b36f457546ab81de8329661a008d94bccfceaafdf421c8c46a00fe0e9ebf20a335661cdf6d3ca61b8e3994f1f442f9598b93aca6fec36e524437a903a9fe356cd34b3d37809f93c702799066ee40df443492d934c8ccbf961f5b9a2522a139194f0e2f6b6e3b2ae2bf7df843b13a66a9e4786851d3996fe808ffe7196cf729d093a115fd8776c411c87a7aab196d1dd83abe6483d1e5edbefb09f40a24acd610a4937f41aacb9f50d4b2e122ed9ccdb0d62dc278dfc710620a291281f5738439a4b3af19d5264e3c3bc69be681349bb4aa03617a3299e433ed6e2c66f7dd2896910b65d365c9c157a49f703cd64a20c40f05f11dce7621e16ae9ce148f1463cd695bc0387a378bf659f6ccb8594e9a5d3f38b5e68739306198f5cfcaec603de5f2ef125b16bb2e8804e0df41c98dffc1e4c5949524c491eb882790474b98dc348e1d4b0414a30631500c85ee203852db7ae58892c7aea3415ddd854001b07a0c3fee2ea7414b4a7bad71ca71b4451b7257a04ce9e0be5f416e4bfb69abab2f717b1bbd795ff53346ad025933fc88cb3753685206fc1eaff473c2637dd3b9ee29998902f0456fdfdaf6d267499d1bc3e3cade385509bbd86c03af612f1e9d458cf134aab214d44774b591e3f8f32160bc8800fb83976235253cf0e3f21ac0cdb92fe209071077809ec7486edd35dba646a00205b91144441aab1dfb3b457b10ae14098c6154fb19e9f3ff083b2d199f272920e704718674c2ad1fa73507ac78e305c2a4f122bf13b9e9fb002ac128dab41cd10d123ee4f2b690e9083d66aa048e66dab4ef5c0bcb9583bead7e56542b172b21a03147de98de4e3c5292926cd96ff6a2740474d0d7d08dc8d2a42b34e9ea00f4e6188ec714158fa367ec7aba30af44b992cfa68018619a670f72bfc9363cc892e331fb05b4d54da38a3ee44556b3a848ae6f65c8f506171c3843f5943b0910116896a63c780a9678b4424a7527fbf2cb445f60d839b9b2f46878af32a7faed6ada4416377c8146468501cc2599bb20e674370d2ea13ab8754959d826706400091706ac63cc068871c98a8d3e9c29e18c150741fe5254d78b4c3558fcd8b8 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d7e3338b3ca1d71e8b7485bf85ab9e8f6c36e158b67d2c3531bda544b8afaa0a86058ed9884f9d0d2beeaaba8f075ffe992c475dc4cf919d61efe673a3547575e8b00ba47d5a158c22e6b2c38db3162e65a6bdea43e8d1e96791b6d99c93cdb0602c94c1be3f278fe46b7d44e447fc5fa8843fa797479fb0f39faf9fc3b57a3d92c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe16e509ced46b4ad48a73599ad2d466f17d7e9b4604545ff955d7659ba428cc6994ee3375b07d09ad3be197fc1579fc73956f6d0ddebf5435d7a2fbf9199533b2fcc500df2a97c571dc3e1485b36e2a3344eb880c688e9afae8b0a9e9fbc57cbc11cb228f8c24f38a445d5e2245c3a5cbc65d30f69ee849bc268899a8eb9f334704499b60a99e139d9470a2ae47f3847085fc4eaec5b14e5e817fcca22e7bc1c585cd2189131a6da9f9f84ac7940b2949707ec7a680ffeb38d775e8e63394a3a9557bd4805dd27fe77ffe83030a3455efee96a763f8bfe56df73ce3cdd7ac70447573a79dd04a59e8b40e39c6fea736e15feb1b67b5cf556c3aebf9facfca4e6d8b759d37737863da2a7ac4a645a903dfad62ce7068385c224e5f8ee4146d896020b89cc73aad70e35d5a3b94889e84e086f1066a9f66d41b70f9d1f538fb6be8a7a84ee05efc158b69928aea7708bcc411988c0d3e5d1debc3b3eb0cd473fcd3abacb1bb3eb33f24379b5360d81efcb8c45584d3b845e260d420453718ad8319423d983a355b1388bf246b9fe84d0443c5262a8e2fd2ef5c49ddc408f4c0ff95bc25afe8c3d6d5f3f78fffc585843bbfddd6d2ec3482295717b6ee1aa7b647514d0841d6a0159ecfa9ee97eeb77dacdec2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57dbdecc4ed5d957e5c8beba790d785edba95a7352583354b93cbef98c78bfa946a753e813ec36ac45488b27d85acd98b7c6813cbbfffc5e9814c3a9de4cf54ed7a144fb6d16be83cb48a9021972233382fc8c38861eadd6a868389def4bfaddf11d3b3a25f648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f77e7ebae8cb489b447df4f5def39c79a6e352e5e87bcb8461b5b509c895fdfff95ce7c3bcc5904d968c469b200d3322c4f3761e3749556476e9f5a915971a62a5a330acbd106ad77da78988e5cfb3ecd454edd459e5d772e64b627db2916b5427c694ff33410be6b746dde92833ecc35bb25db6e6537d1d85ab215b366a173604c2797c2a9c421ed69e7e4b3d22fddbd2ce96e1d5211134479df3cc54f8f8f66e82ff3a51c7b84f02ad8ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f8cd6883c99c4ce934fabd4437df50ef36fc42d4862c9dc11f59f4087469211af5cf4cb29d139d85d9c9050d4cb246348d6d736e7d7b2babe11d9eacd3937d9e8934032746ab6df5bcec8bf637936448a0dd67a27ebfa74c6dbba82bcc87d73d4b9d33c427a85883613eda43829c7ca3c7a8f243646346e0d8199a5ed8d38d0b6686abbd4779fadaa4f82d4d799ed4bf8ecb65ee7c8b2047c41fbf55319ce39b89ce909831ff4df4bbdedb421dca35febd752858a5cdc3075372647f3987f6c3e2a9e8ff8e6ec4956c5b4b33d63f367f24f30b14357e94bbb7e8a947453e4ec6d6de4c695468c9b12458340cc59d1bf3b02bf255173af22d6383aabda0cbefb76a65a814bb2a5aea0108650627d90c3a35ec675650745381e56658cbb71b8ecc386bccef66cd59abe81a6f9ee13de5b59f8a5e1f83899f333974877a2995bb2b73bf4bf92eadac35df6dbd6dea2d2dbe0e054b8b0bc541ba92d145e18a6ae7c1aafb360ec60a2eb961fde3f88ca623d4b37717ba598fbb3beafbb146c42ca4b33abdefcff7c35ee467a4e7c283fe75985bc0758ebebf5395e0d3843769e17459c2b7a45985a672657b787768c32cf37aca5a419743c70f48bb78d53f6d65b5d4dd79907975b77698659f92ab0c8c93938147b6afe695b9774881cc1eac88ac3a142e965e598b4f0eb76114c6b483e6658bd11174e2b0e4c5afbf9e0c1856382569fb9dda91f6b769a9f8a12ab0c09fa395f643234c98b675d1bb66b8ba4b88c526e01594338ee57700b95ce6e334b7d4425651279153af42d2940a191c57e30e0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd4e0794d55bb26379871fa7692fc7fb61c8f0565916db30861a2a61b346986697690d16185753395060b229326681b16cd5b8069fb5498aac4ac9023adc380aaea764fd8625f765f5d73a1189a7524a6bdd1209a8a23bbc5d96c54b89b9f256d20f396b6f61e47e0989ac04cfb267b175a8b38395dc3e976feeba1967ace1c491733cb3b005580fbf666ff6093597cc59362cf60d074f6d33c3be33bd02bb0d3460abd45889cba06129ab11fe978d4749a675c32e2e9bb2d6816ce198bc5e67bd6069666c6b1ef780765664ef650c9847566e02c116f5318d1fb240a167a89b2381cb4cd7ad60eda125bfad338bfd668a008a9f9354999949ce5fc09aa21025a83cdb2c7cfdcbb3e03e0212d58b78e00ad85ca97e3f64a82e79d26053da439862eaabf9bba6a11f225ce27be4cb2ac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd8306370672f20f315474836509c93ea814c9c77a4366325d13c52b0d5a231d79ddf765e774c9c60f6a2f7b1377630be03149a31d7112e61b32296234678bebbe05bcc4857453858b06680399c699fd23a9f96b95f5978437b5d453704c32317beaa45222133d6cb8a5e984633081170c154d68674896911ce5014a9054c37901411ba72f77474b5591e0e1477705a3e1b535d4ed3b3c1d043de517b23035239a39694005c00ca332d9b5c98a16034550d4a92169966882bcb28f01171e276bb36f98dc3dca74058462f2caa4d5a9e60991f848b6c519c45332b18232b900d9787dc78a685360336b685d5301315923f8df99d34b8267932496ae4981a2cc94739cf075343de4231736b42d9866b0ce7030be42aca98309021b24a1a518dd0107c2b03a75552c169b605635323d9cfee4c607c656724b48f523a1ebee51393e1538dca234d864066f7417b1b67968a2c03f9b85255148a9409bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f63c1646e015d64066402a2a8f36b7c96e0a50ea13c220103194bb188c6947e533b1a173cdaf225eec27720a61bb3017205e98258fb470641633d955d14589bc566c9fce9590b6141f9c662baa60ceac1a7b0e518e370c27da21e2a098d62433f2fc336340851e2e536e0b2ae8c2b2b58057b5d30a8fab602c48ccfada926455549ee4c15f2369f58742d5fa85415990faab1b76eeaba47d05a0c35653b36192a6b108046bca55443fa075f072270e836293ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccab92446a09c8be6653f9398b4d5540e8544d56d5c88dd20ea99344b747304f56b2aa725f1a858eb7bbae293b891ca61c2d5942204455cb726c29a23231eacfac678dbd002ea8395203172b35a448ed3944bb07bd2e11b9fb52caca2213dd482159821ef5d9a98d09147e272d3a9b84023172d0d1ade55662b02a9574c13a5d5b79575c25c9d46bc5c766e4768836f787cc6a771a772518e7c5a2f4716e007900db8abc8a630916a268b080cf12ac427a02c474ad28caa73a5793bb0a7593913debfc4cd353ab92bb23d78a2822527e58f52f4d5a70b2f05eb0e6231dc43e5fb7c27bf6870181709f1b0ef4175753687a66261f32773dcc520c752ca7ad6344155bc63f000e1c18be1d154476a4a639d2ae5e36bbc157a7c7f8291b6506f12aa8003784927284fe1b1a4fb70aba9a39d0775dfa293f9a29a4fa3712fda54c41e45c6696aca509d09e42618164c34f78b5b385750ea93d39abbbac58640ce09e5a5245a37847c78765d731596bb10123f51793ea5d97c0321fb5810a22af50406e53806569c53750153ca7b49dddea12baf4ade371b4c7d05e29369a5d1c71ee1ba62db26c74b456cf30832018cfca235b32174c031c53b4c653ee205c632218ce05676f2878930334c2c284d7e3b73683cce303694e68bc7f95b0d186acf5101d95fb6ce55acda6743c7512638e42978af9037272a1a5e23e3632059ee1a3367ca9bacb27930700d19327a0c6ac9fb57d3e41bedcdcc47efc18653c2c5cd78200ac77b066b018d137facac920790bc9e593cc243761cab947818e8ad7ae6701601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e977918b12f00bf09aec2b492cf53686beb31c558d0493cc7b2b9a9dc7265fa9edb685d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = 698d515fcb3a6cae5c7489af712c4417864c849109264cde1dbffbe903630ba3fe59f0201fadbcd93708918530542cbf035b3f6e863476d736a80f413550e52998bc8f525d9d18d1cace1087b7a06e5c2257aa7fd93d6050f8da704e2694b73d17cbf356f974e415eb55e9f445e12f2fe78e69000879bb91a281f7a6062fa4994cb8c6096bb28da068b1e611340c5d0c2f12fbd20fad155361c019dcfbd101e478008a500d7492655c9baa4f04af597cc67e49705ae03b670ca112e2eb718cdf7399be05eee4e8fc14fb100b5ce1c024c8df11db2ca992b0560826e81cc5a18079d1a45e84648616d284fdad7a6fad5bfd59659d967208ec7e2a9fec243790401f85e0e7d147abfa0e585edf00e4a4341ffbd923038f2d43db27b0ce197f24302ce668743490068edf8dfe829786187f95a92a97bbb652135138945d279814ca80f2b7534f6c4009e1e806a4908712bded1b98d2caac89f1691a0f0a3e8072860705196b73292c9caa1994cd72ba5c721b01d9d94e0bed202084577bad20fb3d7f090a1dd156571964131ea5af05a12af20c39de5f8d4157e564e0653b3e0aa5c6fd8fa1bfe72e70b163eba1faad62164c4f05d7cb1caa1d1d9b973de2c10e439ca4c4cedc8dbed545de21722f0c0dcfb17f8d3e3abb197e7456c804ed7d6350eda067f2904ed9037f2d8cab1b53bffcaf42f20b05677a9cea30be46618c75e5c0b943be4c03e613f9676b5b49384ecfb9603bb0087129610df0530d83c742aa5dd4bdf93d18a816f02984c0e7a1014a03822f69b99c48fb63c578b17bcf190af9e1b6531fb739d1e5e67722c8956e0452f2d6bd4a2ef2c9007ec2c9d32ec193540c67911731b97e101e37f3dd3e6e5e5ac0e12ecdbd154d47fa0a55cbdef4cf77e2d95125910f95352717c33c8b62672f03f04cc60b0052b23f42ada97ca43a614bd1cc1aeed6978a841420236ce6b768937175ca9e95795ebffabba193397affa7328e14d8028252feb88f923d8e3ebe84e9e435d7c273425ddcda52740db716cb319de921a2330b7fec204a562386a72e36c8d01f3814a37e5cf0e1270ab565fbb4154193c1b35093448fa215de9ad83454db5a442c68077b0928bf3b10e1e5ea220fc655d31e47307bfd09cfefb9f6a469502390452af9dd459719f51fba3c3cfd40895b27495f8d4d8ba7351be43c908b8d6f71d060f3410abb5b8d34592ce663893cd6d6cfe31fa16dc93d156248cbf320ff7bc6f5167589e1688a7ca2474822fd408d29b5c637c82ae85098accc55e1439b96180d0b0e03c5766c880233741541ce1330f84ce1969ba735e22a20578265751e76fdac1cf15e7fd64e838131f69132079a12a104e330728a3951c18b4a1b45ecaf81368983fc31da091c708c910b608cff0798abba8812c07af6af07d274f046fb0a4fbf74a20467c6059a9a43474e7587c27e009b74ef4720fc9773748042dce5e17f3c1b0bd203e629f28611776530858e34493779604f1cabd13aed8b20ce2023425ccfe9bf1be4e38ec0c650b9ac6b804ccedcd0713a895f673bccba4c7cb06dc3e6c70a92da9986bfadf9ac0efa5685c45594edf0e40cdcd369f5ce2a845b4a43d27ec464ee8790a27e669f793c8bcad4fc9b8aef359ff16492bf65ed42edcfb3d81f38eeda496c50c118ac5450fd4bc7b5339c9664b32492ad9c5e94502f9c032f06640ebadcf5d345b5460d07e3f415d5982e073c36a5fa497d904d574cd571c0dbbac1fa0649166c04e70a9bf061ecf15b63befb0ceb7a62465c3bc27087fa3c61ea7f8f005f667727e9ac51b37f915439cc1ccb017dcd2e99e48506429060d3ee8f3db5db83301a1bcda31d05f68b95236ad1ddd47204564d3d9999aa3e46eacd30073d4bee95faa12a91a744e75720365f951e1292d891f94dd86c1ae951ec261b1164a796a316f026f5fd6b07d3d8984dbf82cad3b4ab0e3c3eea8fa7975765b35452d6d08e7e875e7af3870a4cf4e5b14cccb6292f859169ccbd43f915da362e7efecd46c61c65916ca1a39e2c0c9447e924dca74be8d0eb36b5f3be4028ebeb1e7f72c982054b6807f77d64c25689ff1b70098f1ce980f211c61d5b297ca7736325d0b8eed6ff2844dd954f7cb26b9be8c2ce00a73c876915a1fdd3094f0d85797a8df245a31624b484b270e4f39920943c6920714e86c5b6d3c32eb6dd6ead82d44584 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d338b8577cefd9168551a681f9c590095b6b8d8474f68ef26a4b68ef8ea83738bb964356edb663d925960388c928a6d29b3deec8fd46cde497e3384f613a444634aa3d4e656d6d31d523372034e6047efbed1d32afa7b3d51f42ce374c8c1e8cf72e9fb5e645002530781cb46614d3f98f87d115baaa07ce95496a733f86238fa653367fbbdaee347e55a3c8905e368c1974418e735f93b6965ffce1ce7b43d827e0d727a4c4b434003b9111ede3568b7bbfb341212543031c862fac505944b8639455488fd47b2a864a6675ed984583269362759cbb464e7e248a48c3554c8d54ed9342aedc8e221439f91f697b79ebd5c89b80ceeec716bff96c97dd73c45c0d980bc6b1f7aee7c33f93875e8058e97b276f6d981960267f4baf0c572a1d939aed35ace9a630cb6d7ca9cbc16ab560da5c01e37601ccddca7a3af99eb80418c0066e45c7ac8c1776d5411a39bfe843cafb4fa61463b20a504e984309ffb82cb7d81a97951d0961b2664e2d7b41e0adf572edfc20ef4ec0ea998619f48c05edf208ee96a983dcdf9bb37b9a7d559c720cdcaae894583a842fcac92eaedc7d78fddf7da4a8bf6e3259b291ae82392cbe36b68d2f4fe708e9c00d9cd6dcb5d43c1a461e76438b88d1e8faca17045b273be6999471f8fb42f53a432a5ef4c4bfb7f8ae3eee9be95b0e871909a70f4ea0cedb37f3f733ee259f41cecd12c79db09d788d78ceaaab9e1e2db7ff98d0a17ac28953a4e91bf57d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a5a9ffbc648fb9cdc6073fda6cf65c9e0ff309d1a433ad5fe6cbab472e788f76558d57986bac5c79cafef06f5d9db18c70ee88af044b528fff1e5b5e05a19610f059fc07dd9b995e90ad8e6416d7cc4fb69d499fb5d9ac12bbcf6765aad5c874fe318dbeff77961cb9e747a8e4b4acaf3f3b81e5ea4a755ae8fff994e8a722dcb5b8014c1ccdc6a79046664c3b75d0fb91e0b4c5c35db8eda5d67e9a0984a6052053d22266b2413b98d94ee8aa686f5edaeb8d5b2ed2c8bbdebd375ddad8cd47a0e6945f0ac352307ac0ecff4ecaf9bc09397f06be3098f8cd42b85c556bf0a938959fa7cde083d3e0e63c22bd16143e45bedc47ef73604999e76f9ad1953ff82e762bb8e74f8aaf3d09333f7e677f33bc15bf996ae6999ada8747cbdc4555efc2b75ed2b9d382937427ea555b3856d035dab1e3663b8d78f3d96cf9ec9db5b6de12a7e5df5db38096d76c4b351305a97199d3ac01f60a0bebc8a69e62f2e52f9edc6234eca5deb5260e7eae26fb7eb8f7a342584577bd0dc674a5cee49c7744d7ff43a5b04a3ebd38c110630ff656f30fd42ec6d3404de4f18fbe7cf675c996cf790e936cf8b60e758484ccd4314f5d106bf83478f9077aaaca72acb46d331ea1f7b17dcae5e639d2b33b9f3cca468f731bf0b332bb4ed196ab77b3c43681fd7883d369cf5914464dea08b5025a4c881ce53104da852e35f975e9c91eaa680e9dd25b4f56ffbe878b48e39143ce43378eb3335d4ed3f2a358783edb54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf2aee472c26b4d708df4bc3e92eed6ec05a6a85479e1fb34c240cb0165bd171ce51d43dcfa41d3f41183e458a4c15c4e4a043a1b769dad2c79cd3d39e2e6655f18ae497f35c811d64b969e2349c8878d9e0ba7bbe40bf5488947315b4aa1c6ce0871bdc81b8ca3f6472d89638c3df83f0df90ef1d8a9abb71d353aa512a5601f67e02b5b9074881ff96650b9bca29ebf7bb9aff85fd9069c75ef6f4ff5c989d3229b75a9d82638e8215958d1bccea40dcce324a5b5a18cde96ec2ea085641b8e4bf0d4e5435a838fdcf7326710fe73bffef7a0a739ef6cd8204c3a98ab98a1ba865c51a82aea57f1c3a62c12b7cdebc6a87cae3e05ea1ede6687a7e99b5943cf5a6c59555fe628bf7c3554a92b4488a476d28348125fdceb3af9a2eb9f6cc656496b4656b5cd32346e483469bd183604d1ccdcbf8a25d05adc1344c1325f63f46a5c37ba98aa6e79b5aaea4de4b7a7bb6c6cb4a1d068f6809938f5a55887e37542642cd4ad6b044d0d02cc9fbe83a94b634410aed2804fee5d8e584de9c857df0fb17ae66be51268dbb4d066c5379f6f7d571b7fa152b25c460c63c4d18ad733422163c0e26ba99530074269c212f2697f2073bcac61e4e603b18b575bf696d7feb8724400848f05e91186052b05ac7828127802fbd1672b3fb45ff418374d61f1aca1c1b93af018cb60f006d04418088216844b29f9b64bd46710657ca30a054bb1bb0161a857edab220813170d1cb96f3d82365317cfee94eb1a8ba6bf82af10acbe3626c7284b622b314d72469ebc76d3ad8cceaa93e08793490ea0a73408a1cdbb066b67d1351af5a6c477d2b90b68a3982b70d32346cbdb15ef09736b28c23cbe03d18998270013509f13c7eb95d5a03895301cf2d0cbece1908b3c28e73e676304b0c98f7932bc246107ac07b27090c2779ea2b8c987b084d86bcc40496a1c44c751438af5951acf276b25414d4e37aafa3a1fa5b8fb0fa11be21bc76b7816aa3a1df142446aac524a6a41aa3411e00609f297e698026f852094e2a2e5e9146f812c283529e16256050204ad3b03f04e35af7d36799605903e8c3e2663f9e89791aa8cbf1b8047f2a159dd909d01a3eb3f081a930b26b6b3c32b7172b77bbaaf1ad51401c645b63828842ea7b7803f9699740cac72b56f434ab7e1c09b4ac5368dc559d603c5aa471cd673bac5abf0f858dbc672e16f819149094f2b144d008c06ba0c36ab2a61053629f994fc233a38576a7821229e79685c2147b7b15156493c1eaa2c087134f1222758b00b3cc10804561b24974742c2aa016e23cb19c868244c65371b6bbf31d5603b46e58bebf638fb7924ef4181d02f6a1da6321a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533d62b8d31889e6679251560d0fbb4f768501aebaffcb116a23422f48ccd89e0c645a11b0f80ad2c77a2f30b8cf415084e5c9f655824eca8be8835a81a6c9832e09c3c596417657657a9c85a13a54d3c0d2c427a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9c92ab3ca1a8c47c89d1a742cbf4352b762a60226cbbbcb28272856b2bb3f176ab32955c96a0274723a508730aa94730f998ce0e04ce1e67726412233e8b96c31481bd017c67f1aea09a3e96f897b70b969cf405ba7424a0e8aea4b45c6206752c075e2bd3b3abc53f99f2842a459a55118a10f87d8f0c2caf4180ec741738d6a04efa30f9b3b9af587c33297bebf8778b960596bc3095439ef3448c11871d228a0dc24718f6c59c8c73234a641c47917b27b46cda986a1857315911673ba0468641757ec5ae71c860de0b5ebf05cf6889a170743a27350b19e406a77427421a54f1c163862a43c6ec1260d45139b7419b0538ae31a0ac78584b3264cca519ec35acd94c1ae5b436eaf82fecfac8681224fa810fb0a95581528ae300081efabd7e599517c21f469208f4daa500b9225560b9381707440082675293dba332ca00c4cf746f46041b78d219eda4bbbd32cf07e37e20e15c25f8a96b5706fcc71f620abbf052a572d73b24c5445715c77187a1baa883a714329d619a10cc2c9c84b2c4c098f0e42c4c00a77c44845b45003b7c1bc587a3f6c10d34269430765da39550e2b78fd7b97cd9128a5d8653b7aa05164101a9285a9c1a77a8b255d1b8533a1315a82bcf7e6620c4224ce830b83844bb16560d6ef98819e0ab4523acc16961229a0b0847410b19647ca7836345b275609d5d12bcdfa5163b0c4caaf2a0f05993ed16b89dc14d33a60b56a0a298e453a4883c7b6c7bd2186718da1a29895b2c066bc6a2896947431fb224ab31b11f204f8047bd5e421d92b78357694d8959991e56b6a123373c00463bc259f78a3c2e7b3526331323e9af2bb55726795fd904160c302242b1bd7d65103da1395d82aa5f662e4edbc812479b0b79ae15f25a07363080d887fe8a0df37b51b5ab7c3e878d21086ca0e1cc47d877194cad6e384a81403adf05c430d22d47516acdbc946498a281611bb9f73ac3424f6cac3146faae1611103ca4008fa95a8ebca35ae114ffe14921a855f5049447643c391588444217a510ae31b82b5c159c928ba434890aee2c7268724bbc29cfd152b05d73198e7b62b43b9b03e081cd0a1ea7395246cc890735268f189f21c143e5f5cec76692e6d937faac7af3abc5480464f8b077c9352b14a22dc65514caf392d1ec6c81d96c33175f5832ab3bc19c54229f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df7233c98fa4af17fd014a60d11ca5e929e4fa2524f7db289ce0947ad90657990c153b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = 02367918fa87d1732fa29e978c06713a66cfa5e50a7ed5644a3da67a89651567ecffc9bb1f79e1bf0f30091bf08256384f45f32e420a8a45bda4305bb231ae0f5ad834ee9ebb6f77b5ec136671eacb9054b02314866433f3c8bcf74a6be5dff9c968b9c167cbed7b843de055b7a7ac6fd2772eb79d66a34d08c9e811fb5d860d1d41c3195d02a731f0c5a0887547f980e7f02d5f90295f3916cfda43ddb1d66d66e486b5c6e27701cb1b749a1f30a7eca93e812dd462cc998e368f3d951d04fb09dd4eb78b43766d5c68abb4ef48d8d67bfcd404ff8b717dae7f2bb9a15912dc6d6670213af09db6aeccce8fe6b9943422c919222461001e5a068cbc250b9b3a67be2db1bdc169057719ad03b9f687bac14f406400f39cf8e6bd05465e632ca5f1e176af32d089746b31d9a95485b6ec3e360d6fca07ee469ece642fba8c325b81c6b70c71d5e2c8e4b8a35749c463e87d99e6746022e88eee7f0c27258bfd2ecde268c37625eb6c44c40a89ded03bbce4c055d21f727efe0a6bd1bbe15ac2a011ebee84cb8f18c6932d7fd687018f23532e0942af1422b634478de271a852ec157f9b5547641bd52123cb12453c4f14498fa423d797768b58d311818d68aee9282f8bbe43e010ab36e7132400838ff27266cddd2ca36b7acc576c1874556ef291b05a0d61cec2e56d9f1881907c3885e2133a999c064677ad323608645b7a5f8aeecbcec9086fd644e02b03c0dad7c2407dcc935a640a4bef943ca2b0caf4aab51d958a6b0ddc1f557e43089ccd669650b5e3039c9c100fb604c0d1cff6651b193b98fa04735223128ce84e1f6ea5010d9deee37af5d4a1884e2483c2c7019521e2e38179ed008530e339b26fecfdbb271fd4b8f5211130a7846e753ca108c15a938ae3cdaa85b82e2318a85d26f2849c6312a0649b2751d175c68c9021a839a70e11d947f5d4576ec6e5a1ef9ac9467e323bf751b60e0adde97b9bcc54668f6f579608e81491d9ea45129d83186e14a533c825cd01d8480e4bff0ac9a5b4f8171a6aa5acfa09b8518500e42b30d27f9f79e1f131391ef5477099534c28e1a80e3f50d1019fa671179765cc8d3e40a4572b27447f37dfc5950321c20512fcba0de91baf9eec84c914572334e3fbbe13f96455477110ff515a01aa51cd94039966f6930a90b80795d9ebd4a5fb9ab59ec285112d8bcf9a4d4b2cd3892cfa7231875319f00d36a5b274da937cc2744b8651565d3018a5ceb5286f814ecc734a3e2d86832f531482d3cfcaa850e573f6311b05d58a86cb38feec0d357acdc1de40cd909322568d72bb78b72091f99197b341e6274fc7834c7830a7e981957f030e8df6cd94994564352273a3d054b1ea8b4c8139e677490fd95ebe56544d2c6ddf83bf99ee3cd2edebcc1b068ab2d4cff003a8ee54532fab9bad522d0180d0a4908969af1086b749b892d0872f86068e06b414f4e4a68fbec43ee1cb97fc288590f9451cfc0863c7ba58007a6e773fd54c2d5e5a7f324a272bcf8668a399a51660839442674385c6192f1c805c7b3331a0328349c7e786c30fbf436fa209bd79e7beae00bc01cf2db5c4b54372c70503e32b3b473b44b0e71e480672641dc03427cf4f31f047542f2cf9cbb9c7e011d6e73a112a16d1be72a31191d0fa7aa8246995a1128750bb1e0a27384590a71c1db3eae7720989f09e1c085aca876b75185e562f33dd26fd4a0e41495bd24e7e7c40f5a0d013b403da4b75f212db1c8fc9d93ccd9b9f6dc6f9cf48ce83784e21e622a62eacda50ef89c11fdbf7522d11532ec6e0fc7ef0c8fcf97c859be5fb79080aa9a980c787b65e37b2c29820978632289d026fedf0ac6cd0f7f3774cf36cfe60b6f86bc87a339c2c8b32e372165959177395208942d1c37289ce83e3dd3c5cb29a600f49479daa034bb728d076fffd4c5507edb4c5d4e1c67412042952611c3cea42478081ae3fc011ec89c964d22db22be0f369b15880a18a703aa9072b6b4c041d35393c953b3237e8c7f86e1f650640b1a03863281b28350a21e7969fd6f374c9560c36a62c708c8d1986d511cf89dd38bea10df48824b037b513d3ec44cc89b1939671ac0b3e0159a703f4a6ebb3ca7c5f48ea8d3080d337fbc9491b4accb5ea5f64897ddc966cfe585abdd47022afab5dbe39e7cd6e36443e98f108059c29b3f1fdf83e53a186b53f608869ba31 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 9bfc3a71fa83a417ddb5064ada94e0a87d845f8e8c49c9ee0aaf51e29f5edc2f6ee8bbe53f94b2417560d88959113a6bbc854b0065748e6a7db90977aebdf16f3c41cf07df530fb306dcf2ff9ae38c46dd75b9cb1bba849c5bcc8c9b55e80647e513c9e4ee5f67ae44f013822eaf4266765e402ef5f435bda4c46ef57430eae331e1d54c91a6deeb363ca25387d0d441abb930e4a7c32929ec5ff7a87996a4b1aa741636e1e67b303e284c7098a65069356b55304c1eb8bba66c5829647493c09b06f2670e7977a988343d92efe98d9c13a2bce53f8fafc81b0d99b7d5c2b127d4971366a5565cc156e0df796c6057d0691ff6cb165e9acaa6ac5d7a923b4d472a4b6ca4f4e7f5a622f87f4f9ae083b4755067a93c285cc0748d241c7051a7e128cc5af4db5c1f8ce44f98b6bfa7d3f5338628daf2df4b84d113e2edda9df71442465af4491a626889f8c22455ddcf3eca964e924854362d790e8e3924cb58a1ce56aafbcf649d6ec5fa891936c7e16b5fafd98026d64ea31efbd75b6c5f376eeb74ae9b29cff714ec650b91a2b852c12e562ba33b66ebacf787be419edf22aa43f4174571c77710f775d27e9968a552388db61336ff94bc36b71eb63f56ddc7fdfcc588af9afe64312f76b0386e697469c569f8c0f6f439cf5af90577de0883cf4581936f905ee3dd9a1a7918c8ff9b5af8ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d520f45f8834e890662e06774f389c0c623be331faae5accedc2dec43463b68889eaaafc21badacb63f9ff80a336f99e4fbd6d2e2b9ae452647777651ccc4bef70ac06423b66ec5982c96eada7f3dfbc834ca6a6433174c1d7ceab9569265a96ab5d48495e7f122763b3b7f75b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dadbe40666610ec7a160fe8bc84eaa6a4f5508d5cf682bafb6d3c9e0fdfd80349597f56fbebb7ec813efe71b6d6c065c4e6b5e5d17abf3c4e2dee8eefcc8b6b1935fb37b467a5cc6203e8aee2d67890d726509baa73bba254d30510d50d5bf3e4ae7e349dbd877566ad20dba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ee8ddf4095d59ab482fab7fca53fef5e76affc77f74f4cda62fa0085a4918dd4168bddb09863850d6caa17fec2d473de0763b7e3e68b6147bdc0d9eb36d901fb8f013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c4311dad15fafeb2ed52680f9e5ae8e39728a907b98761b65dd6dab895363159b48875fb6aa80882257ad4461bf97738d688745c5914c089b37bfc949a8f9864affcfe4ece3f61afd70eb561d09b530ecafccd66b87b0986adfae9334480676fee28bcfed9c57ede59f799c4d1cdba8377d593da0ceb0d233005ef587734fc3017d779d8bc5bb488dd3988004b5a8554861b66debaa5bfff7c89dfde93ea077f422cf16996c1446be65caef902cfe7315636a168c0216ac026fbbd4239858837b02dab5a3adebe6b17f469af64661c5e3404f480c66526377c9a0d92434bcb551a744227445d6ed8fcfc3cb55f6d0c8eedbd4539cfad5a08a78fbb7f3f314aa643b9f60bbaf2b96842fa4995601c71dfc4fa5719c6f3c9f08b19728a9cd85d38d6851fbbf356edc1afd6feb7b12516d7c1e33ac22932318fcba13be39bc3deb21a5861e9d2c0e35cf2db3c237d50cb8c309edf56ff4871186330be93492be78e267640b49776dc98adfd0e97c896a1fa27af841351b5c790a75e9f58c98bff18d2a0cd9e3ba6db6898577d9f612d264833737c3e4aa1765c5d5b49bb12ccddf38d890ec6b7ef55ac5fda8298a6d3a705e4c5b4ec04b341e1197b7e4d49e3ddecdef47f282d8a48bada2ba5706abb474c467898ee54daea841028ec6d4cbbc9e73746d46d6f47ffe6836d82eae2a32bd674dedb35c9673d25830ee3fae795bb7d1aaf2cccd433939a7add6dd33cb485a4bcde17eb5c083978d78bd8e359191e52fc535770548df0eb33a88dc0c9e7bf907540a1f953ca7fb43527b0bc586b8b2abc865b9127caa4ea98a5de1aa2bdda772bbd702f983ec8b4f31bf48c2fbb37a4247783cbd221098a1588ec3dec95c1a9db21c88cd109e26256d0252759d3539de5422f470189bd6c462361c8105549370a09e8ccc407908a4e433813f73e3ae465cf99af30105e6e4456b899777236466f05bd36a05494b347457439cc9ac66557580ef049071c7922f3770b4220063139a607c8019b52708976d184949cd88714f18130f0a6c91ca38680863eb9be2542a4b27a629dec949e552d8b3c86883211ec341b637555c70a8fa503412a771853d32cf1a5939fd7b6eb012b26e414b14710a4639096025a95fb8cb581358379330999cb6b93527ceb079b134021c19c9122640f90c11c234f808ccbe17b3e031b1a7a94654f82289e2755ae38b9fcd477afe576bad2218ce692b51205f61a59e644808c011c0ee0ac36a050a4c158edc9c770444d310097235890f2d630f85c0ded24443462906fb84d7cac3e7c1777d08a57a689302e99a3d9302faa4c0dec854d4872579365bdd1645706c744fa5a167b563accd8097e8c626ae63c8280663a382c11ba8f6c1b95ff1161c3b5679ec6c661c2b8081c1c39f6c732dc97bbdbbacb133006a7c94de933aa19156811a224829769637a54b9512d8a4e82071af50a66ab52301241bc5206bab6bc0b29776a4b630e59e72988c4c7fd83912499175a2a3d3a2270edf3a2977049bac7524cd69691f59442db348243881e04b8e9f1adb4a436555c52f2f729c345ab278011cde73521172e8fbb5509746ae871cf0e72416c2482a280c348862b313c9686d37ff0d73a1e216ffcd936d2941fb5bc77a9b0b771354fed30ca16121514541b5124386b835c22540ee2f9b5970c1508e41dee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfbd05acf507686d53257c372dc8279e89669284c76294aa3098462efda8c743b0b7305bde0693d98048412907b2d2b27892397b9f3cd31dbaf9446598dc886a4e1bf0f9c39e9faa3aca90ae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd1150cbdfa3609708e4de5365013c819fbade55636f2a311d7a2b2ef7b250632774ff22ef2e76029569346266e70bbc82ec09533f8caf60c4356d1023b4b4532f7c1e5da18f4582d40b8861166885f52c0db58357e7579c7516f9da7046d3092303219f327ab52a28cb6a246b5016fa6894599d9725fc3c2af262b53a4592f881f2a195d5ae75bcd36c30d6b7646424c219302c4e5794057782e7034eec6c488395710c8211ef954f9f7434265590862b2219045b1336af22889abbb4639ba0758e28f2378cd1b1a4225b4171c53691a9cc5986a6c3ff51ff53b4ffe3c4eb8585006c8667bc17b3a28c67439ac5f3c08a6e93a926aaf515c24f8a7c3e3b2ab2f5183def46f8ac996e400acc320b49254042ac43c7cb160ff32ca605438d7124b5a727099f48008d60ea2e63f5bf9b81e3183e1647251017e82827620070c96a32fe122632c4aae1590623ac191bac113e9c3676ee645fb762b0ff982e416ca2aa343f607a70405720e9c42ffd815be984042b37d5f76646db400da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca541169058521c28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceebf916a882b66752a7a6e96dce612ef5754c392207b5b1c69d362134aab5513ca757aab9cfc94db5302510101a73b7cfeaf7a0f1d259893c76d9111652a4ac02348c285b94f16c671fe953e1bb0ca222a3ad751096a1a05bb2789c0c14da099e75477ed038849dbb19de489fab582910bc70a3a80c6f76152d494fa067186958191a5101051b6d55449dc5a4434925ca9f610ba498a24b232ac6aa08cf477a99f5a223067aa4c91a7749b834c90d6e247653c6b6db65c5efa72f3cd9cce1510437268cf92753db242742e042def3019f85188db7573a43830abab80d4c176ad551c5c5216870276160aa61b92863c1725083a56df800735c5428b28adc49b75da02bf120996be7ccf9e20d43dba59b6900bb50456d6589cb2c0209e51258336034566ae1bccfc1fb314afab759b00e103c0a7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d63661ad0651d0f3286d3f055d1a307aa7371ae1a74f1a68d57a7438e4b5107bc0dcd8c4de5736adfe3170f8a1f01535a3772229da4386b4acc072c1611b53c899352b5ab5b39bb9cd4ec72e622c946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f091210fb4f6fac00a24167d9bd2761e601db0a3734e3c835d1e9c5865b1e379caba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = 2a70bae622394c84f44a5b2e1118aa28f3583729e7e606575297aed9041b31dbd14dd2e8ce797923821c525a9b9ad87a39e411c20f4b4a98066e149c3baeea96d67d3ab839a7479b4bba6fc0b3e6da970b38fc057552665d129d26c4c3c1b8c4e7785c09822cdabefdf7a4f8fdd955aa35ead1e414d452c080b64d793a9f658e307339a18fd1881848c4b0a92fe4ec4b1c397b32f2c8ad5bef07d9bdb1f1366185f2065b497a8357167e9e91de6cb9cbea36737a1e3fdef09367a6c95fe23144017ccc6eb5b9981ab6a936fec5a2496584a196872a5e1c4acc1a50a8ab3dd714006a7314ca2250c1b2411c7b8cd552d99731eb84b321e421909c1e7ab9d1a61b1af37b9472edef61c6848305a8b6bbc0958677e1c0bb79122d2994c72616b4df68376924c1484e9ee20c65be4446776ab72b0422ca4f3cf5bec0c9c550de418edce654051221383923030c022b476cc3d95bec28fefa128350843ef7cc6a442cd76ba6fda38bb25a909ede689290887b73ec02ce5d1bb4253526fd4f7930ad4ce36f09f0257e6286cc4bffad656c9826a2cad7797c17bbce5c552442db8fafb01935b973076dab3e271835740d59c8663b44f1cbb3772f2fcd5197c52418bc4be1b928f68008e5671a753d335b202779a4e5ab3f8276422ed23fdc249a5c0923f6dc1d4d72ad6cdf270bf19539ac9001d3acea44a90a7d556bbddaf2aefcebe3e73a09d7882e74933e23b15b7d00a71b8ba1f77f32ccdb4950ce9b914d75e7184ef6fee73d9201e69c2acf0104b05b18e6b7068761992d333e51af8d7685246000f63fc5221679aa58e8f375b1c420b136e4cfe5aea6dab98f81892ad11181482378faec81805438ed4ca497b7c02bccd5320bcdeb94413f3a88a457890b7ae6b4879c091eaf8709112dc39a14ef0123040cecdd8a50a2538fd6cb1890b23300521b0fcef1150b1e53d8ce256e0b89f51ee6940aa6f9c4d3ee6aa2ba413747662ac01b35ca6b976df28147e1c4ad7b7b958f0ba86e092d71a100ec0060e9a5744127520f4995d6d0caa87786e2d44cb0d77789646c4a76c1f470fc4d18eed0cf365278025ac73f971b441011bf76dec7521aed395255cac3f03583b0d37fc206eef2370f8a13986c98660443a10a8cc56d7b905a46ec6cdddece9aecedbddfabf86362c3a2a4eea97d990e8938167eec639f90f7135c98cdff4fcba60176ea48bb15db19b8d6ed38edd8a7789ca9502c80f6fa1bd08707fe9b51f8110593c8203e305949ac9672f342151832fc890b86961ba408f1d82c051f7ca3e585d8dee88a429d44de29d93ee55a4bd9fd674ba1ad67534f0de5f9aa9c828b8128ba2f0b74724689264119cc8ce9a0431810a09422ac44904f6ca01e12fb0a10a39bd657dbe2045433822bc60f64960b83ab813720c120eaf14c76a58d04c2402785aa1833d885ead1dbc594cd0d110faf736f70852f76df0d1c877062bdf012c818b01b70a3b73dd3fb9634c724a137570c25a006b6a9eddb3ff7b91635bd5b734785c47a1c24092eb5bc480510784d8841da2d86087c2edea18e51c75af631c71a7130c40a999caf5c6235aa52accba8d650a282dc75a89d83e5402556020acd43141a07ac36bf8b754ae3a2b7e64565d361944555cab87ff26ae58a2cb7f3b29555df9cf983d290d448982e9a044073468484108012eb0a5e3e68b17271ea99706c5dc8b3dc364cc3eea2313b88ca5b7389be2c8a174e7a405a64a6655a67b7b4ea81a5e767244a5a63d45222ec03b0c3cc451599de35dd3167d5e0080d7bbeb0fa6077e6f5c4143fc083bd8dc4b029274fb87ce5eb13a79daf68d55c5bc2966ed34d13fb45a729d1483a186dd8061733ed71c6f6d7ae76607ecdbbc80b16520b08aca914f3fc5585fc8b0645efcecae66ff36dbf2ea87f9ebdbb591e56fcaeae56bf25d11448f5736fcdfdce09568b6ff335aa886c6256e518f39edf134f03f4a73876a43628f2b1697c04e4249684b6e6ae3f706dd1f7ad0c62ffd7e9eb7a12824a3b1854dea79050d5e647956f6e3a3e2871fac0f78d219cb40cd11bea041566c1cdbe9bbca5c4ee57115637380c9b82bcf938abe19af0a1a93b272e3892ed9d38a12eca97089720d05c3ca17fddba22d1432aaf02d63a7f804c7d2ba373b643faafa7c249a7a6078d95e770ffe1515cfafe746b0d649d28cbd54680bdcf468960 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5e484946337e404e35d738b0862b69f8bf47a5cbd812d562024ddc53bb87b798b2b65eccea75a8801dfd7de7878fdd8e977afcb62b4aa559bc378e6e979d97406d8b2636e2f89b5bc784365e43e93ff9d13c05818e0a7151297ea53c95089388bf2d3072dd335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92924e37c33773660aa15557c32b8ad86a6aecfe1f5deb7de83ecba94ebfff0f4ae8de2e31bc89fc4013b7bf84a7840c976c63e17653c4f947839d8cb35538bb97899418688a9e16ffa0ce7d7755dd8536eaac0ebd9ee77e917966bd26bd3d3990aabc8561cbaddc6af2f8d8dd99453fa745db2b1ffe4ca48dea6c9c083d95447eeabfc7cda76aa03f5eacfefdcc74afeef3edff45a9daef5dca77b93f14e4bef44576134391f7b67659eecc787671385ff67a556ea8f562bd858b25ed4315cdf5ccb5be075d642a23460c3c65e0d6cb6833fc007e9204b7b7cbbd741817e00b8ef686b982f74fd95d7730dd9385a8af6c2384e475fefcd80cf69ef346b6ff87ec0eb0471d4ef94e5372b47da145ab0c6ce7756f6b5dea7d72db4c62fab14c03ca5138442079da7a9e94e8bad5bc9e4db21956bedc948299baee7f89c884ab9833c866a4f2ad05ee4e2ad466056eeca478f11ab55defce3453daddc889044a5601357ea6a5b097b54253bd46fa83c0212cf36953954c36840e49dd2707848c0b879acaf354faf00fca56cbb86c0d2f69a81c790b966893f782aae9a4bd2bd2fa85995a757ff2083fd26347c987e1e07560af77cb59c7cd64f7cdbc98dad26a7bd7fcb9b31d710e68ec49453a330dac08554a651d68e6879ba6665aeaff81fc14c8fbfcb0cbddd81c2ad6dc0e7d80048b334f48f699825a489d0726893f1d9128adae802cca29ac56f71e8d209a54cb94fc9a8c539e43b9681cb8690e8c95d872c63fa10a77bf52a796d43e87fb8aa3fd88dbd2c4b30fb7394dc64b10ed5b821f8764ae325ceddebb5ee248bec22b1e46fecaeb255c51f74999dd29a9463e51bd9869e3d548347b93c1b798ff9fa053b88c80d7afa5c561d31435d71f51253b9a4c3bdf4293dc81e990006dcebddb700234dee9ef76d4f3ec2d249b854e4f3997b9c4f5c0698cb2a24c48e46d5f6e7d4e5db734ebeefd62634dedc68ed7bef48273bad5ecac075e978b098ffdce48667671d4b59ea6095b0b363c31299e5cadf8309e4bebc66f639e338bb7600c93e0b83963336952ec33854ed7c979c7ef30188181ceebb673e4ca3f42ecb890123c9f2aaa786acbc7dbf560d0ce625d06c3828998ee5eb79d28c583bb3871a7d6d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d81e3ee07eec521761be77efe37baada8afb4b1e4dd458a19966a2a439e4d61b47aef5abcc08f50c88af752b51bddda3789cfaa38aad8edddd835476c8386dd3a8628b36ef1d7bfb9f87e842c97da7bbc3d03696f615f4be6476440d44f6a8aa49dff901f750dc55c1ea88e3ec45e8b26b3fd0657ea6fcb6be94c026244a050e593664673faa680f866e184e43b0dcd86fdacc208ef6c3e941f19d332d8487d5e66061d5311c9b5c8edc39bdfc349494d0a9a3aff3a85adc48b21f1eb57f853985689697a591c527db2766a18d18937cf9f857a99095fcb6a35f4beb2ffef1fc8f6ab7f4f7548330ce7c932388b728359e55800f4ee0c89b8b7c8eeaff4785259b3e1b3bdb887ad57e7eb0366e7ddc8cdc8b1bcdece5da7135c8a69affa2f7b62c1dbaf73f5da83736839de02d7a7439e3f8f92bf173d8625d769a6ea9369a0f99a033f9380a85a81852507deb36e6cfa8046ed2f7c1b6ce326025faa34ca30e1887f2849c61c4e64a9e3138b74c818bfda9174d3ad4ca15653f7688968383f3dbbfc1888ea8ba793d54d9e26df6a6ec044b7f7d98715ffa8a2cd30f238767d9ed75185df09dd2c105806c07f9897b382aa596dff7ac969a5cedc9f94dca50ca1c74ceb7605e978723be48817964cd1e59883a6dc5094f02a5767d4bb5df73d4d3148bf019d68a2bfe4df78bf13ee82e985982f4b262acd49ecf6667746c4503ae059e72830fba0b55a8248c700484597bab32daf4e607538bcc5c9dde5ae98cc8eebdace43eb9b612a3dda8f56fe3d8c02863c04cea9ec675bab636ac40ecb18567a8e6fbc63a52327520bb770a5d64349817a13cd365c96741726aa9107e9a4c04796dbe92061697131e728104c9c6ada26ebfc51632898564d89b2919438ca1308c53387604c162a424afaa2af9ab0c42b50cc50b3318a15738057c2f1806017a7bac76ba523acc1c66111d45c253ab299463cfce584ece769707a6b35d6114a8b92939a16d27a7be7f72b660f0b851e4950c20b33c074d307c8fc9b51454e41a96a8ac76cc30a568b4bc442177e7748e4b0f7d31201569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2bf23a19a5740fc9b9bf18859efc79f9e9178bb542823a4fef94be8ca589abf740d7880380e78853708cb9220e5d0ace428c58a543acffd8333d2831857c3784090e3696a3b011683899ae31b40513e9589467a3cf2891439871a1b240fea31f2fb89956d9966ca204a598050beb2c36f9a6851820c87a5262a9cff23b1e7bdcc9d060484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ec103864b75ab25a013d7c183955884bd01c4f58cd410344396358bd6901a94228275c79a289b385c788884b2bd3371d0852b0ac4a24107a87f1da0e6fbbbbd0a25c9cb14b7f25b7432c8148a0c91f8c7616c7bee7119a8f9aa4da5291a820922ea68f2bd62c4300cab4d10a73db255b1aa33d523d774aba41fc5f26326220c8b3575520788c0476bb3462f73c61016c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a93001a8c4c539f576c735068661c02026bb22ce5932bcab118827107a784ce94c2c89444a7b03a2386772d89106b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f502042c388292394a4940c0470458726b76f39037e10821fb56b3e4f38c752f4278b8b1fc332a48da56cae9c56bd03343659b4abc262fee6855875ac2b8aabe02a352919ba6363c6e75a8358d3297386240aa80f0aa33b1a79cae3c9ce40f87520ac713bfc2dc9da6c5b2bab6443383279bc9f3433e4080c7bd5bf22306e4fba2a8ff0a1f7978bc6a7bb809664783c36ac81445d4964c8ec6e9616384c60636f6ac08aa1c23d182fe70034ff2390442190f8c2cd68c9892bb0a6fb29c5e3480697145b150675992137c5a16c507c96180a3129417d9e30815e30b90d05835b890cec789e3ec8ab7dec509919cfd670241250822c539fa2ca8d9d619e22f050744727bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb569147804112a0046e2149903fb5ae0e56a4ec2b44397973441394175bb675c3198800e1bc56185ca7076345ac1623ac0ac1f10f099fcf971feacb965482a2bfc585bf30647d90f7ba27cd76891ef5b3ef84b988f2a407f5552be77559d026e385627baea2debf3ae73e3cd1461b1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526cc2fdc6c7a39da80278182347a3330fa332e071d8f31321bf32f4507b16e328fa7892758f2948a1a951506222833c0bb68140495a7a5e942c6b17e674733ce754eab747e96d2a077e7024df77388b6bdb807744db74612a8c72011be7d8b0949c75cd1b6107c2422e30c1e577b3515556a10c1ba712aca7f6988b3873705257cee724acf431ca0f9961db020ebc784e4f27c6fbc062857015db28d64004cb41bb7ea3b5657e6b65200b3959c642b213dda13a1b25377c4a47c43dc2dccf3607aa02ca28a4067095f541b359e21b39004590ebba6d6db8fa461a1343b824d1373f872343e8bb605729b674c66f7e5c76b536539f06f919213cc14756ffacd5789a46e7c8ad789ba0f6237998487c1912e86b087c9388d3a6a9c18d505fbba2f7aa6168508b1c8702a2fc167f2202ac21ba862917f6d78971aa7296ce1306d2a1f2f06b8a3a214ed45765f6a05a7445cdea385ce7922e8006b549319cb38904f38a6f932304037c4fceb9647fb7ff9e9aff5dcc951aa3e4bf50c296b71259650b5047c94ea2696837e26aa1d18938851198928db1ea22758c6cac0906a995a022998a7a942626c2cec7a5fe83948d74509c61915819425120d9e6580c0a3776ad41a95b52b2e867b6d7242ccf281a241a88049058d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b246c206507b89f46c6e9cd5e78b6cc78fb3677ee609cc090cf3782c876fd5f941b0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 93b854ae8690e56ce1149ad776eb9b8b29ba124398429b24cdaad3596c9d2889d1166d4604443441b5a77a71cf4ad72651365263f38ec232de2bd664bdc01ba969a557c8eeb6888b4b1272035f34532290967a0ed6ddf04ef083e6e525279120bd02a8da8515ed4b420c9dfeabc5bd0d73da26b8afe062ab3a5279f1069ade2d6284c8df2cee06855eb4b94e03b5ae91a5ec345300f3750ffd02ae558e9ca00ec2bd11066ba7827d26063146f1d1b246cd3c1342b51e2e98e0a06faae93b462046b1e29c0b9b525a229395889bad0dfe46b6a6d3aef00786447a5dfa1b2f1a0fa8cfefade49bc28b76207790ea62a8c2f9dcd37a6884e5109288f6196fa83486bf89b5fc82875c3ca187440e4a53d6b0746be742410d5e4d9a91df391499482db0ce46048667f30d5902e4399a8815d52d4295321e53e68480ab1bc24c3a281544e0d68ffda5ffa7b0d770a6faac834815819558507fff7704d84d5f694385d5a480aee1a0396c31764356d7a034eada7e816d3b86f44f6d1bfa95a876939bdb77c100c9d06f2fa29a8a4c67b61ecefece063376bfdac2bfcfc9ac94778a87ede84dd299e685862a6ee3e435917a25dc763d6ce9b4fc19e415b3dda2f90d9d1e559d146f6a3d822e21f90d2bd6a4c196c7080703a54391f61ca2140ccea20cd143692845b20a78ad5a4b0403f373ad9085e5b3abb2776b684a4f9bd3dd78a1835cf257b106b6682f4d86ad0627ed0a3e69222c9809f2740ce3aa16c4fb39486d399520a529791c1fa90e069da5ec030f726093a527e51455060499f38ebcd797449cf3ad21186a1de8d63cd9fb3db22a8823292a262347fc6b5f9264a8b907237dad3da30079d64375e48208aca9f2a5953a4763a2006f4070b796ae75e7052557d682f04e7f6ba51454c19364697c279eef3c421c4d478e4f8c654ebf9d1bc2f4aacdc19b9f71f87e3ca7c2147813e64243e515a180286f23d4f3032b8b31aa35dbeb1922bafd81f72ddc3a78745eca243bb56df728d5ce2556b985217ed7862ddcc915b9fa6fcf42992923a14447b8c4f11781df1f88798e8b5b170b4c2fa86a758208ed7f46d13ec64a2e9bbe0edb79993e845b418aa402333179c476ab9f22cbaadc31d318fd6de048807676d8aa8dbb7615300b871e84757e1a69498d0a26872aaf537b1423fcca7aa9ee79da9f5111d1e239dc8944212b05216c62a18fc3bc7707313aa8a4c05877f09c8f167195d8edd787ee4447f57ff08f470b33c4bda786e4457d43f50df69ba500905f4b69d1f0e8b98ff1db00d8d0ee4a40958bd4b0df837fa44abb3e2fa236f1fa05bec38f1c6d9467eba4e2067decd56a11bf275e07fe74db3a79642ee2a0b2d658c34748b6bc54e2bf6814407f500e5517b1e162c2ecda4201eb544bcbc816f39246b0bd63f100332b4b78d3c3c262a5610da4ffd95f4da34d9f76d967888beee5857c1c7a44ce001a782c1e41587271b11e68c1e6bd84487275c7d89bda052b67c567d7545899460701242d70a998c2ec9db6be579bee739bd755b9f7b94988173958ea9943131a0292aa6db7fce96c361f9b4d82b84402f67693dcb166ae5e8eb7e1ccf88c755fdc071ff0acff6d74190b424c7c2ee899bbe904d1a367bb284e5df91b1c9ce68513d3d5d2940a261d8e0c3d86872a02f4b7f3e37af66508df837326feb6da4355d5158db2f96f52663f437b20b851f9db9d11f8ecfbf9e5bc429526edc29a7d9e0fc32106db843f75313cb5299021d193d4e0ebdad08be7f8d4ceca944a3b90f670a51ec5fbaa6c3b811514243945dae6223cba1650bad5443f19683c387674e23195ec1422367b7df591667d7aca7836efccaffd4c4d01ecdf8eb2e49ef55e256dafaf56d0c193373d33c4ab9af7aa564b92cd1dc7168b4aa58252aef2b35db657b97c84b0a7af5a158de9047368749e653571246899a9900c53bf8a8160143e052006471446f6c26cd6ccaf3bd92121654c19a8279ac459a36de93114bcf7bb3db544d3e1a17f60a998f6647ed0ecdc687161bc5481c7314d761a08d01e7a91fb4dfaaac857c0bda1a55dfa861d332822676cfe751bb60ea2e29febc238a96eb2f014c524bd8d5f4ddc21ced5a68f1d5f658821c85520d749d5fe7c1cdbb97c761bda8546a47507719a1e62fe1a25d24147bb2bd90bf23d3b68649c852b24dc99e7f2a1776ead4fb011 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = de56f7135b3976b8ac08ddd59cbf8d09e98e3438f28c1786c2e8a1d70f9d93cb9eee2e7d0abd3e9a7561af7441e437ec7b6c8c862c5a93e955a05a87b01a63d9e8a335bf6e20cd34615ebf32dd78860a9afe939f4b9dc2a395b2b7dfd5485e64e37adc2a3dcd27ef642057db0d068e36a7ea979be7be984a418a3cc5c6b62bcddd6dca565707ef09cfe5edfb88a5b6751eaa525dea4b0be4e430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638e8d8f78535b9fc6c6bc1ce403ee6f0b784f9b2fa30e5c6c1a3fc2063bc558a7b2636c76d6cdcb77e6c5518b3b31e9f0a24bfbfff3ab930bd4b3386f671bd7655989c5185d5d393631e9acef8dedad333379a63efbcc636cffb4fa05b84a375559079c5909651e58eda97bd1a87ebefc7bc407db7d9f94b819a468d443a7aa8c9b485ef66885f6870f336c2be160a4ce5e4ec57fc9e5335c87a72a73463e6373e9f1a7ddca0a6d6154199c4f06c244a7c568bc5d8244914909fbd345db51d3c474e77a3b1d53160570c886e32434aede9fc8961b955899e0102c62ae1a75489e75cdd666ab85478ebb6134afde9154441f1383b1fe471386e4dadc823f1848fa478b204ded3f745c648cf16c84edfd3b3195483f25fea5313cb458273ffeb55969add4cd534ec1369b0c68a87375ef7423d37118c6f98c538dab9c1ec649ff33d1a03a650dcdc138e79d1509d89a639737e840a7dc720b173bb329a34cf65418495e4eff805a59ea4c96b47d55f72595dca8eb3944399f9d24e57fa46b77fd891525461113766eddf5ee2cfe745e98c3ebf53a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb54ecdfdc9fbb2da9ce2943759c4d08c57a0e74bb0e1888e957f3169437afce9aec2afa46d8eae4645de32bb18f45f7f4dcb8222adf7be74f3f5a8cab16d9bf2e64668e9fb868f32c0d8a855c9e6b54439a67aaffd9701967bc47af74d1d6ac1d45cee7c54cf49669e89a44ffd7b73b3ae2327a85bf5938e6975b94acd3ef4aed824ccde033cb175a3356c8a998e4c69d94630a8966060cea79dcb5c27fa54efafe99d5ae331bc64e7d8fae45c515af544843ca59c3c122947bc376dda7357ac0e33f55485e79eb3118de4c42ec5c56653e0edea4e92d5fe67e823098ad8d9844a25b92248d63aa2d40c60dcc0ccfb25b493e4cf69de95c87b03b773a796d1304f114847727345888fbd6d935eaeeef4d04ef92cb55fa3a38a0a56ec8b4f9cd9f87b09ccdca98f6fe5027595c2479308e8865777a357dd4fe3b5b587452658f63aaf6881555f6d69eacadb74520f3627d7395ec7b71dc3c6e8414985d69ea05c88b6455870c48b12c576d7c3f8b88795296cd51cb6f93b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c84cf8bab4f4b19370afe997d9bd8e448afeff376024f5ca54dc8ec0a7fb97fd57acf5a6b0e3f869fab3e1797ee267eb172da07618fc4ba6799c27b080bd73092a7a2f7aa110635cb959d0e487a6664b318f54956039c57cf5d9ede489faabac96dbe1f58c87708a8ed44d8a5277d1bfb8507d67415fe64e7e5ed81bdefc2103da2b0df910d6d4f02c4064e348b4f98f6be65d8775de56e7667ce5e79c347a894b5a9da3a3a413c2d4af3e5eddc7dc94ee10e4a83b3bc0ebde7b5983a5792e489dca73d1656e9773fbeb9a3aad0e7855a74f5f393eb5f4fc97bfd7b06687031bf8b6ed9afd76f25ae892200969cf4e420fa6de44963f634bb9f69c7c4dcf849f258040257def4941d9b54477dfced887991418d7531b817dcbeb2da7a4477abd388e55da169a84086150bbd9ac8a9810ce4db247b3a777f3fd67701644bf739ed395bdac77e74bf954e6d866489c0cf96eaf9d63ce947be88a0cb78aae94610d48738019768df89b38198258dc7f70e6fa3fb7f479b9aaaa4a84259837bfd4872d8c708d478a0e674a66da6cff43da6e24d577c6acfb83cf4eacc370ec57fa76c76c765c39f5a07b9bea254f65cd03ae02433d3fd438d5a885ea03808d6e96e4a3a459ca6d6b456a6fb961fed58ec0d353ad46e43c94ecc9ad390fc55f35e5d4001563991fd052bedc22c69207fa839f1f750dfda5cb4d4c6b5344b977ee6e15502cae7c3797fa9bb390cd37928175e047fac2b7efd010089c89021be2da6c17ea926bf636c042c59a1b79941c248dd3079f623095437766139de109c3346147d1f8a069b2316ed2606ca1454e364e9c43a80b0bae79f005e0ec3e006d1adab7bf69fa5b098166aa9520de263e25a36436d3a9783b96a763c9321727eb65a7207b51d526c6182c1d51372316cc0ddd946077a81f6487b34d68b59841ce41e779885027912c5d6271adeaccc07ddba319700694f927a374b794584de181b890f651043a1b391a7956477b436307dc8b0d0467bc05206074d17f560160774a8477509bf5a936811bb9acc179834a9d1106af0438148d076e4c3a7c70d7231dd475f06778eca68e40210859b092915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91c82028eb18d99556abec2cf3aab979d125c137b75586b4d419758ff68229870869be755950100f9c2bf6d706cb9bbc5289489df8acf49046ea3d27fe7f0cf0e148286970010151a11b879f9035351ab10a536b6a3144a806b8fac1389f58b0395fc7ab90436b440bc9e66ae3c73a5e8e5ad59662286fa9a03e62c5eb100c9b63dccc74793080ce967b7d162438a492ca2815f56950d02aab7f12254d75c499840c5d662c0c10185b4ba3f84a91b37745d1ebac3a2440dd899619706756ad70468e1515d4c0a765942dd5a84af8a894cab90a724a95481285a160102eaa39591ad4e2c871a160be835012705598ee166bf2622bae3acaab37d4fda18997212b831b9b043082ef2b7b86423bdc15d2be82687c35e12c85fce726f340634c1107df0f50f3253764fe4cf0d294d27f28674f94ad16b7d03f91fa62a42ba154e35496e9b2aa884ab27b5332514c377f78a2fb5e7ad85d643ee94763095b2f2616bf87439c22a26c46287125bc7bac3aab30b1aeacccd25532b326983a37a623f0a2df3d7cb732124f89c37ec1881f2c5993667339d825b68908cc7923d02c55e7f967d3d3b8d01ac87128b85c465b285d60869290a78b40d48d9c39e92c298b313eab8a8b1607b6da8c22967ada0294696988d5d251ea0565c84571914156feb5820e5ea145f411f5ff64b587a99b88cb08ff4270cc89573d901cdd5624c0a2c3a654b99a0bf602acfdd15c06d69077aea18e73ca0c2e650751a68b659a568c2742b626d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1e12041e056ba02bce42d9ca15f5a241db89e2510469762690d270d1e16cfcb92f715975f68b44e75bcb98e521a5c2be1e4a2e5ef07bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fbd00ee503966c8118a1993910c6ad99511da8216431b26aa7b09a5f304201acba84670714c410e21a2d4517a0a1f139304a6fe9c63371f65d43b095b16040af3ccc487840cc41a63bbb6e2dc49731013ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef33b176f31104a3185dfa62404dc4a771877fb94656d15c43142bbda1417a7c69996681a0c69b2d7395e694c4ade0a5886d28f207722855a30273c91e2c19a2b40b62a554f1ef9c282b51015504c4b84714a99a3ef33504429976c2c036a9782b0f2be79924d98700d6c066015b10c03db90844b7d4ffc14b49ccd5680b1c1d9c15ca935404737093c20a05461c45abcb81c6a19b3a0abc168356882b8ec3549836faaf354d3b60d1a5290a883ab1e19b9493c26113b3d03b8c3fec053bbd14b4be12c80ac412b6bc1328a4fa5f1a3f46bc4bc685c7da98533422aa2a8c9822237f62c969ce064ea0402cc656a88c39ddf221e3d6a52ecd38f160a3f71c281a02a24beebbb1c6c9025dcc51447a7f5679fb0e382854a29d8088b5fa11c59c439eef92f869c4fc8b66ac7656c385c0983b07aa98a71abd2b576212fbbd14b96b19559a6cfe5dc1f3549436a4263bd9b8a185740b4eb16e09184dfbb07ffb7266c275438e13208e4a2888b63fcca6cd8b5abbc14769bd61a74f34627b896f1e85c03202f4d58932c183d7cb4a5548cc540a32aa9c558e9889e10d706a809aca75218740bb6c39761bcb0bb0c76725eb80bd5a46d074864dda334359b4d4dbc7c8da2b413dc20a1201ae9e7acb49c905145307ccc92fba03c02045c9632564b68cdc1e9527b239c1f9a7f72358949b2ac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9920560200b8d070d1db2cbeedf3cb322ebbab3edb80cf474b4178633c210b2fc74b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = 40d176c0e576da5380547cd5e1cfdac9329cbe7dc473025481d612401a1f28901dc2856fbbf214385cd2a655d9ae8773f2dab66e1416881fb8d11db2d6a93ff00701db7bf4c28328debef84c4134698deb97339a66d5e046068bf25105c1fcacc439bca718e9a1bc570d075252121cd388834f074a27f2e4a01fb131b278599c9305357ff2f1efdbdbe37564b324b9646903ea90836f2e2ed93e91bf0b9d045ff2f119c0cfcd69366cceded4cb040a656d203b04e689736373a9a4a3062999c3999484aa11bd24f87f588423e98c0f34c0c522f4eb58fdca72a4e108678fb3116ecd60c5cd6c38936e02729241e4da1553005dd9c6b192338c9894b14aaa57c9196c28b2cef0e909cd02d6d7d5348dd409136cdf9fb9edc128f38c9491aa3b2bf75659f225c639d1e7ec179339a142188db6ee3d251965ff232ae26a1a9af7a19063c4c37fd60bb4c3f76890588a54d321e3d21f0c5c879418ce6cd3b1ddfbf83992b3b860c8756be4db101a395d9025e7aa7fbbad94ea3bc4dfdb5628ffabc684f90e9037b57f97c8730a4a8ff8353feb31ae5f3536f9a64c2cec9e25b666351f4462248c2f84b0cf89c2b2238fea1a658bd903445525f227a849f41f58f7deb9125aa3c1bcec584a17f45998e3a5c1df02d064ed19b8d3c455e2f244fd0e683fcf9a929681fe880aedd218cc3079bbab5f1731c58da5a00c78c512da63b4f2fc527c0aa7963df97f3d461a0129c7d76e20b7516d1b83eb388079d497cfe5834e30a6e336c8c45b214b360a089f4a63473ec691555276a5d1eb62e07b06ce36474bdb7ddf21a5caeac5ecddf648a7e6a862bac72d0cbc69f1e9361829b1657cf0379b05bb1630a1ea67a1a3f1079dc729c8eaefc5d77895e2746deb079e56982f9cabb21e225459c7d2ae76b112e14a0db49a55ca1c353eebe6947511f8509d1b99a86ad8f38f58107f8605b47e287397b97205d215ad9ee840a95a2c6da24b9f4305bd734759f5bc6bb006253fbba9d6695da96d77b1c6c5d2e6e7228ac9c83dbe16a095feb2895d2142251985e9d38c0ad583a80c99d453d2eab117e10cb3a91a621936569976c69e452075465f3fa7ba041c112944186a6e9f0862597ca2cfb443f6f55d2c8d4a622780c4ad9e9cdb909756cd702e51d8a4d96b08d62aa2579a9b8d20228db525667659f4ce676c590e6a86a4d8a457e9994377df22f9ac3d4336495b7fafa0e06d58673d70971ff3ff8c436cf17e839b26087b01544070cb8490c2a88c2d2e01fabe854d58aa3fc066e5a036acae3a7bf9d2c02104719314e97eab17d95dc4421e002bd15f4dc0f1860c7ba32f0188a9d333f1e9b5092e1c01f952ed02fa3a8fa18d3113d4f7fb1b58626cd2008da96b45f7cf00a22d4acdb1234661687bffa52491e25bccaca2d00d21b0148e13f3259f956fdbdccb7fb16d0780d9fcc0bbfb39e00dcffce4bfd9d916314b5d159880bc791d3836c7cc0fbd461375e35bcf259908a40da82d6f3d1a0f2e26fe78e4ec4882be39c2a2d97aa9e63d2ad6b98e56fa1e593a844f2d8907b0996d7aeecc4f87809c7730a3b6a21eb9f0a4f7f31d7af2d71462c8dd97079a686e7abeeb5912a9068d766af158d7c38d80706a439308af945feb81936571983d6947ce5891b32ef7f3a9d71e4cc2ac133d004d5ded7a0cc29303aa207a233d9ea745afbf718138ccf8a15d5fa39c6a2070a53c92221cd0cbf6b878dcaf7268a68fade731da0574998728ea63477ee99320ed00a8f239b8f4e85f7ff6c7266cf9a3ccd14cd6b9cb616e6195afef1d38f8f2d0d9779c4188e60485ff8f24d8a7a10accefb99b3d6ac7ffeee11ba0fd40190c672b84434eeea7e9a56047a3d0b983b0f834b8a7af34de7cd853d0282508bfcd0b52964d3020f27d3d137a1c3c31a281e5a4045c9da040188d5c59c96eb855f92afd4fe53fb546406c063df50e13643cc49d12c86d33d936c8818a3c84acc10b677850d3a6150089281c92cafe51024a03b4ae6071f2db11de2be9ad3068bd94ddf1d42782f318124967087f486c0514560e68abbe5dd2d7ad0a65fe9b4ca3dc00c97ba2d5874596337a466eb6593feab2029fdc0f3a665bc93807a80fb83a62e635e380810ca78677bcc399b360ea0e7ec0c89be6efb84e3a6e104db94f715bbe80da3cf4151bed37cf1c3586c2b478ef2c536e15f7ee74fc2e1016 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 84e7d70ef8d107976bfd2bddb6cc33f3c981798e7d856db63edde2311638aa43b253b7d5bc994931bab38b6fc5d1dba793b8437be6d0a97f5d36aa898e353d6b955b80f8578f855bcfee94ce2c6e4d6e79adf8e76e345790bf4b6e6dc395b674a7a8a4c72550f84ad9d24582fa5ef56914f8a4e76972b77a53e852ff47e8a54db67d75f1ca699e5a8c434dc47a3813f129bb76bcb4c8110f8938fc94f184ea20bf6eca5f52e259b8f9176bbad8763cb63da7ff95b56dcde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b25ed9d4144ac900b43cfcd7f1edfcc4f7c976fbdbaa4d8637bcaa70946391109981e978ca023313c3dd093df6ccd8f3ebbaa85b8cae680636d0be656f01769556bd58af78260bddd10a38b0a3be27a773cac4d6c1d53e0a098f889759f20b44aecf68dd254e6d959ecb523a1b0bea1ed87b28e5589f40591336d3e229be85e4f6f4913eaf80af2b11cb0f37c4557f94b2f158341afef9519e128c5616f64e05d57f53f25dff345d81d33ef5c3d8a526b9507bd3e0b5c6a88394f0c9c6e7c2b475c85d8a3a8b1e0d571d1c364784cc8a7ca7ae7cfb24366a0d2865658e4fa8495b24a16c9a9d8b1ea77332b1d58dc39fec02c4723fa7204e93ef0cf4f10c4877425975cbb61430f6a2aa649fc6c77e8d7fdd3e5b0d9e9495b0fc252cefb7ac5ef6a9853c0de51a4873cac5ed2dc6f676496a8b38c8038e4c6d988880a7bf774875a5fe69693d9726af64a51d77a03f5f3bad8b2a6dbcea137a052de9e81059d07437e38db7891956c5b2c8abe38fb5b0fa5530c56a7b4b46daab256588b043443663e3a3ad94a2d7aca4bb7d72cc9f59e2676a5c86216bf4faa159bc18bce0555ec6adf699a056ed3f6a7f2bc76770eecb06cb72dc53d7ea6bafee89797b57445f3ae1136f544af882b863cdb455d5fad3eba56946dd6ed798a76bdbc4ca8ffa102d5e8225af0923eeec5df51cc0bd9aa2598065a79b8c6ea56f9f5031a579ac5bdeffea6e1be3820ee80dc0d8f19e775e14dd52b6f4b92de550fe536537de50ccaaf228acb8fe471d2c8b4b27bb57e6fae9ad9ce16adb72ed98b8b6e9cfdd3a17ada37cc455d7774dea337d88e9c33d438eb65dc9a27c68d27088b1f2a5fc586bb0993753f6fa67bc3886058f74bcf67a95b42aaac3e61cf69942ea7940eacd45db92899a2c0ccc4704bf4376da39c69d1e3b6bb146c588dd3431c4a5bead8aa2aed4f8fecdd047837527d7cc25ac359a5fabe7384f839b42d9c9982dc66a21c7fb5cb7316748424ef5005d389bcd56fc4a8d80f88cd75ec974ca9ce9f2ba995c5deca85cf0a7effcbdc492ccc6d076fa59f8cc0ff3355f184f4abb6c774a377b82ce2b9a8ff60777926cadb871ef3434cae909f6e902a5e644de9e3d6f088aebdde0fe96768baf91656d903c4f1ca88163b8dca14e823bb6ee525583816cdfafccbcfe63dcbedb93c46a14fc7f114194cd084c209afe925e7c55ed8d7ee7cda8ddb71c4ab3bd5836b80ae60009dabd1e5498e0d5718548325bd339ed7eac4a75c8105f3dfe9fb64e3676b33775859de068c3cc747bc004da30cecab9c64fffcf8f66e9ed6e77631e9166653e5db2218f9b37fc2ed5568fe0dc52de89e1cb76adb4963624cd8308f4afde530e94f838d6c331e8dab47f33fc283dbae34d7b8b4dc1074fbdab993d363612e5b62518f5c92fb6a78535fb1ebc52bd83b6f5b58f52669ca138371feb21fd8df09e7d11b0d5a211f5630d63a9e596dc88f962d7ffbbdd44582fb8a2e4638f8bdd29c84df87dacf640da8ae8b4ca91abdb56534654395faefc7cc087633149ae46d9089567c7c8bf0e14cd3a059a5c96bf2be46671733b28c4eb35403dc043ba5eddce5ebe74e7cbc3188b6ab37fc40dd3bbee8fdfda545942138739479c4f71dcdff564ba8af81b7249267c3740966c7ffbba92a9aec3328b19f58c058fbf7e27857e46585e0a4ac63fea361e44f934e3e37e7cca667ab53064dac9b3aabf336355ec95f6778dedee4f8c3673cd3d2e7183d49379bbdfcd5fd46e399ba5ad58a5a908f3efb096e1dd5f218aed0626bb67bbe647645794b38af228787b425b03f8ce5082abd074ef5086c858665f070f689735f936ddddbf2810baed633638b1737b5ab13fcb47e181e6cb86c69301b77b85e2c64305f1584e370934a02aafdd27c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab9599544ff08a4a13643e181db6c752a8a5c948d010e8743ecc064ea034444f3a2b207bc3a0606600358907708bc87016261a61b1547bcc8421c009778ee31598d47a48d3a99e9a24ce230b9568cbf4bb61d9a0aa512b282e2506a51b0fe92507bb7cb044e93ca230b6d9f97cfcf31b9055c9775419684aab2609a1e11b2b354223c9761f7d6b5b02a16f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824c115c69510666308330901208d02f1a6057a0f5481af4956ea5281c956735d28e49173031b688a30289d385a7718c2c21c300d7ac3fc81bbfc6747c60f4cdb9c037c458c50dd1605ba167806a6fc32c759f2942dd81962ad657b51942b3fc8d925b9db72b1fd2b303c05043638a3217d1856d8b243018b0d8679db5c3364a85b78c913793e87855b382b3456d3d7c1c2b82bdb94c6e96732c6f455e4e631fd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be1b09430f2ce72482d6a8673a8d511a8a1c506a2cf4facaa9e489d6a3a5322410464d590d0f52b957b28937b543bd5a01f07261afc810d41bc815469e145862a3238bb194da838c642b817db611e18c08325502778922197e73aaa2c030869ca3ab06b22827feb4465ae60975a61255a405db1f112a2087218619bc9dc064035774306b14d4b6003949181301253034323f55bd0818097193d449a3ccd1315ee375c7efb833d03a87a881cb5dab7e0d045b6b80505cc18d8e9be1f1a7740d4981e31339503b1a2b22061d484d9368b8a5193d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e470999e90627014b34a7a8b168010ddb76f994783b5f41ebd60697198262cf42efc13128a45024386c78851c709389262d10d65c4784eb10c2cb13d9fe819cb4c6dc0c34da8c22b69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbe917b37292630518b093b98d39c6fe0138257467f93c76118ca748556003c05810e7cbe83c60f8791a72494889289716790242199262e44b356a98e38429733f07e4d2329da534fe8d4998872429793a6c4d14919d3adbda51c60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f11471d84064732b11d62d40633d67affe2bd75315c54321d3f515078b1cac4e1ba9fd529db1b92a47202c0e768b271826787bd6098a8854460d5da5d5744944887cbb1840125e2825393b64644b8c0b6cd9536be03d6c3e7e6ceb13b1901f1cec3456903f5b15e9994ed1207ff52915ff2460c098ef820a1e885c2ff231896a3c1dcd5ce49910b30927597d988808721cdb68f98914266919dcc46125278774d4c1861466a8197c4214493fad00f83808290dc6064a388633b0ffd2b1fdd84a6c3fc3576345d1a654f3b129fd6c2a6b95b46d235a9a7f44a6f9558af20a451a69c6f5c119712cc5ed91f91b946678520e7165ab4cc367d1ab985692f85e68a3b05c738319e0d7107f2f89710f32c7c047019f6cf29854bcda6b319288944e9907975083e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b964101aac6a016725c3903e5caa639614650c0e052673721b113f48d5cda5cce6b8a7449ba5308ab9f1c25c4c4335e2c4a3be318c99787fdd98f7b592d942617b4346fcc402df7a41043b0bd87c318757bb3878b60421ac5b2234863d2888984898d198d002035dc123091532371e444204ab05c8a9db00c4756135998369eb181882ab3c0c3d17189267f03d64af8b2c3addc90e32b3f44c43864615af5001b45c9677f59b8ce680edcec5088dc17865a790f593ab49bbe5327718a4b0a4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de04100878518c722d321740f4c4035a813a5b1c9cf081679e957b795a2771485874e5bf75f57b11f8ad9fe3b1d2d72a1bda04bb1517296193763776fae451b6615a8e9c788a5c8d65173bb9307b2cf9c863029553f56717b355843ab1dfe72cef8c46d6a8367ab70f83db71c4c410960a7b6221ae2ab64a17441f4b50adfa971f25c719dc8705926c6bad712cef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d03a2484828bce833f9262405b562bcade9ff04877838558409d2b60f1b689d137d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = 9dfa36f0d0157ec8952c2199d3b6fbf75e162d7abd5f697424597a9e6e272cae38c8353a8c98e4e318cb3ea35e45dc7dc65a964b13a318af75adede184d692b684270655c2fc3413d03d53dbe243e626e0f427b55c1b71aece27c08f5804e4d7608be6b6172d0d89dcfcde114381ea824091a43fcd55b2da0bc59a3aa7430a5f564884c71db9fbfd37892314e8ecf1f71057a94ac68580b82e9d8b5d957016ec3ee640eacfc497146fab1deef7e50100a4173b91db6b41c069e9e32e207a5664b4530a9fd17e8d2a0443b8b39d4615705b89ccdcf552e272db8216e9c5a04bd5da18fe4e5e574a6d8271be679638ede14e0926f0efb549edf47c23667310bde6c8f7b573022a1114dda342f8c043165e4d78d6b9b62a47629785acd03aa5a0b37d4f1ca00d9b3e1c7f32a30ba5f3fe80d339d80aaf508be370c9639753f45afcd7449d443f617c7285e6cf2ae9f5090423e47b3abfcd9feb78b58a6186a4bcacb67f5993e8d0aae8ff8d1745e44d769310d85ed5309a8a87a406200d55876f782adce8af5bccc071a520bf5728d21428776f3a03c6341323ffca12815be6434106a26e692a2f46e4cee37cbf4b28fc006d4386c3196330fd0a1dc02b8d6bb6eec71eec766f2e8862b5d91a20bfc6c2d133613eed0e39b228ffd73eae3330b71865e0afdd9596774cae2783c0e85375f5073675dc65f93b71478875f29f4644095ad735cf6c82a2fc10f5e4d2717d2de098d28ee335ec858eef9a39e64194cd07ecf7b818d5b6988b687cb7f1bc46b94e38a8035b9cbfc97c4bfffb0cfa03aa5beaf56a2a21edf2a73a7a8a49d7c72ff3c11ee42f92ac7bf769fc513de67c4095826535a2a520fdc2eab29f71fd7735e8bab1979c4068848d9bfcc2418d4b40e9122422c2edee659dd60b99721907cdba4e388140b886a7a814ede3590e7557d16310caa4209a0b6cec282c31b69371f5e088eaeb20f395dd1c2798b32bfd8739539f9a7cb74b8c926bfe01d563aa54506d4e8c0daa27a7ee7b5411c9295a814334b7aab656d96d05cb9150707ae678933b76afd957e6bb39655f24267ea364fa561d2f435c12882b191b295470501ad8c8db036fb92df81c6dd9ea9a61907eb587be79ccae152935d6865a86be4697ccdee31d890cd8d0f651f0aebbebd8e6840a2a609534cf295ab7838d705cd57acb0d7cfe30aa6fd4b48eee85974fc9123d5c085bb668c7bac8ff77899daf404c01ce991d14a2f23094e14c4540d5b0e60a541f4a0b50be31bf5039979c84277e2e34c7f07afcd9521510abef0fc8e3d5211e8edf03568f4439712e6653fddc949e0b4c5cef165dd5fb749128d5f1b0cdc0868dd49ab1d24d140bce4e1b73533141cc4a8419b0b0f4b27d1090dfeceb95cf13f8ff024c9d089128f313039f0ea12161656251b0710260b7893720059262c24797117f618a9a05a027cedffbde83a93bba0437204f3af49e831b2b1bacc3c17ce407d0f1935534dd341f45f502a6374b6225c89b3a096edfcd533d6e0dd8dceb2ba7a7132edf13b1a5c1f2f5b0b23ef49de8e9754485c59cf0aa3fb3ab5b473461d11baf3be9d0187ed7175b135c706535af6348f5dad15582fec850bc48724c7c4a0ca080ee98f502c23c2816caf7fc9a4950f0da7320b027831f856d8aa170e1de03f8994fbcff4bf1bc507acfe95196784b2421af9de36cfa6125e75392aa050a8235e2dd72c484e61c47bde72e20c23e3e70e9db972b54f7b5b16b2a610926bba71886b8ae046b371b096fe266840b644774991d279a2fe4d4a965f3e9e9934247077c787e54803979b0bc494b56b3b081523605d3d09be6a01037c2150e40e46f4865fa839ee58887176c3feea6dd4188e58224894ac2ac38d78adc2ff6d911b417d799f3638ae8ec6c3252045889b6c0d3004d2dffd71b1a1d49490aa92456b35fe08589e596052c845f63dc3622364c0fb1de74a2906cffa39c5b1029189aa6c3c0814edaebd4ae01355753e1fbf211ead32be62c906f2f1d8d894cbed74efb72e40b0971774837ebe05eb27bdc19a5825ea0b50b47df97058c4ad78670380db8101efdc3df6b372b1a6aedb47baa29abecf11e0be25ccc4a42505b7a70827eb74948ebb4b5be65ce07501288862d98ddc0c977c8e9ef0848f49ac26e0774707fd696035ad5fd14e5b68b420d7191212a7748e032fbeb5b98cec320 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 483e8b2cc6a9d8bc6ebe8ce249ade7c14fe4325b61a2a8541fb783c448c3a32ced82ba7907bd9e361faf8e0dd0706a3d3a1f81f13e5044c9c4f93bdad72c60e18637577b942a54f589cbb466ac344438750b86cc86b97d16339a9ebd365e6696b193d41543b031d9f20f8fbfb8acf1a6bda0d41ee09568b1c01bfb878c9284375949c88395fe41acce88ef86d7cc8e51bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee528f02daee9c90d81beb38caf08f05eb5e812fe3be959ef432be27793f27bf9b69113e145d6a1452e3fb5fec89c38c00d8eabf075c4415586beff8b946380c948b94d8adc3a79310094f230663f4eda9174dc7214884e0f65fa51de6dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4cbf2e174b061bc80e924f8547576b72d5490ca3934c9b15fcb69612ae6399744799ddb2cba3d5243a0e286fbe2f87035295f004eb56be37ddd7e915434c4af6472c1e5c51a5d6e6927d3c49c715c5db360a5c2fcdb79f59c7ade27380fa9d5eb7aa6f514fc6b3fbae657c699eb85a53395c13d3e87e8980023ef96969bf45b3f574a40ee8e32696d3a25fec31816d78159e4775350b89aefa8fed34c9cb155879668a5dad5a5d803abc0cc58bdfd4d8fc2ffbf7d4af972aa66b58844c058e50c0b8c89aca3be3f69474875c01da94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946e7db8b87c56b81b770255d3ba87485ba3655f6697715ede89fc84925b87c008c3cc13c7b9447d820cfa33aec64133d725b4f2b72e9d9bdb5ceffe7e131e32e76e5076edb26c07ef92ae59331da09517f14716a3406bf503ca5f29d4479914cd10b3457ab6fa6bc7ebd08736e25e9e6907dab8c8439b4441bbab5d0a1ebc6737ca742747ca69fe5ed734a8baeb7755da9e4e88e064f2be9f40e285865d63de718c6f1b8e6153dcf7414446bbb8e29a27e6171aa60bed86ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee76d3f79a3d83724a596069f337dc071b6bab955844a18ea8a6d96f86d59b9738d819ca3b6588d5f578059df8d2d17e0b2cbfe307a5f9e18533713c41e27fa9a6e4a98dddac0a83a265f6c399cc9fa9b74cc4774830c8e764f31b14f74c90c526dea7fe4efd3699ee4e7b9dd3bddfae6aae39649b75468ebb578f5a215c3ba38fa27cd36e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781ddd9ccb64993299745b34b6d7f897c1ed5e1a6966e6757dbfef9af2eacbbb87d1dbc39294db584c7c3a795ee12258951d98e45cf73405ae7adb8cc4d11788225557a83b652fa5d53e95d7094bfa8c0dce77e7bbbe93f33ece88810ff8457fc05e646b90a5ffe92440d174d92a058d69c96869d8a83377a2db9fc2d668607dec3cbefc6242b49a9da97c1adfd6782fc8d309cb898593b08b5d8138bf30dec5918e614f764acb49fd7ffbf05a95f70d0ce22a9f9cf7b53d4113ec92944972b8bc9a9c494ab384996647e177a87b2dec45c747660aa4a48d88a5f7919ca46dad338576463a1c24f5a6c4409e2ba82188f7ae83bed4e6c80ac5f8a6bbc1ad58c868b995d907fd77e84173c9cac54eed8fbc5895d694498a68e1be6037a95f9c6ec95bddb053fdeddf68a1fe6cd94d3b8726545f1f857be735475a8abdd7c7b749377f30eeadb0daf83d77f1a10979104f42ab27e1b08cc2cf7361177969ef4ed6b8238e4e4e79521e9090ee7dd68a461c59dd1663e6e927781beff0fb47ed5b1951c4d83d047b72f258865f4f96aa7f705204f24eb55728bf3a52bc68f73cb417cb40ad595888c941ac9360c12cdd1789de3efbcc97373afddb9ae306e1317f9d5b8bf00e4555b7df5d3e7be6e31ebd05ecfc724a33ffa8bb3aa4684b5ffc1999f73173dee31f5ac8d8cdfbcfb69834bd888aa2ecb8d4d7a935a8d3718aadf3488c9799b55f2d83a7da7daee185ddcc59483cc49451a9ea7a9d44a753f6eb0689a1d7f1872f6c820fb3452d9fb61dc21a885306a69640f6add7858dacc86217ae89984640d518312d553626eae2c928d94859feb6eed90bb896b1cc315105b2a11dff83b399800fa22784dbd55feadf5fe69613ec495892cd3bb68aa38ae20dfbfb536e9499abccc9d4973661fb70ab80405c4c59421f913a78e89f67767e71fa51431061746a74746b1fd544065788a7f880b9c81c007e6091e6118f3acc518bb06579b45ad1374404284b0f1c370c53062cb79a08015b4086626d3083ee7b427b24613947588f7149777a3fb5919c73d5a23ef5445f24aba79b94bfba774f71c84f929978c44e07a84bb9139b32fb97d4b20e363a2098838c6a3c51ad244b540b90020c5a0ce2b135918db1e9093a0cc43ab210d28a7889da51d88c7b3d1452d7879f34a130bb263f51429086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e56881b94376638f507e95809862b0897744d3d8658e33c89a7791b93acb17ddc91ccc5b71b01b9bca81a7485c5e4428538a3ba7f124d24864149b26d0f246e9aca34c76103d676cd7a54abae1c895c37b1784476180601a67a5d04996d195363c61864caf95e7d3b2f4ed68ca2db09d9d34f86d5666aecaa468587fe5a3c56434ff4815c61094c831699c5f1be9301299e3016b4cc602bb62a4f1c2f1af247b4fb92d4a10430e29f0a71c02df70e48e0ab79c0a31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114e62417d9bb054110d3284b3285110b7069fcc58e2e13cb50daaa0fc082b7c87eaf13063c6a966b4cc24334a7e6fb8c3131461756a35f2b9842811f233a6a7127a33b7cc559b477b491c0155949f9952ac9631c32451b3872967955c1235b61af676429c94e9034405be47ac5873c9dc33ed94828c9429dd7cc29d076871222893f207b0f3a8086d77c3d7792ba25ba8db46a554b161a30cca878ad6397974acb3812767a95a01f73ca80f1d83006e9460d2348c047ad60f2841db1bae58952142aa3491cc7dde58debbaa27621c7caf299f4325ee978caab6ccd4bd7510f318b20e98d26a94ee99c935629394e6b80a5614891a75b45d81eda8a6cf8d8b43d62ad9399369023c4d677ce75f14f84b05d01b7b021e15e459bc5c82cc9c4158ba32c5d50708ad9f620297333a4d899cc7a90c28740039b351345bc7b971aaaf39d97326553740238e569d4870bb09c66af75b532778b9b0a631d362d13d61567212e6ab523fd4c3ebd5839e4aa1421db5e06e33bec836876d8a8624c22fa56c43d4060a9e52f1c905ea8714d8436569d050c7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dc5242c5a58f0c8caedcac7c5256d8f3b40bf57b055616c24569a51c5bd712279827bb00d274d767156173c7ecb8766202376e9a7227517bc4488c029b9b6b2642858344bd14c8837ac908690312ff5a6de7bcb88f2cffd40a9fc666800f9ac54fac76ff5a42ff83b9d49233c841607aa348e2a5dcbc572d2a482f78b2cdf3ca4bbd22148c925276b6072d777d53081311a286f37ab14ba2000ad4cb82769dc889de981c969f732eda2717cc405cc276fc965ca2bcc80054c557c1343847bc6054157a5276432917501f88bef0b44521c0d5fa168dd89c9e34aca4df0a348e53eb5c939650a240879c0911a8e1ce371d7ea45e6f90b8db0520b115f826085ec25a108309466c11920984534c99dfbc7467af31d5f941784586bcc0347412c48d0927a4b95a22d98b49a1a20cc72272f09bb63aa194e4450c3bc2351ca6d2043a68ec30c705cc856b00f5054a66d3140bfbb47425a67eddbc4204944a1e379e1516e45216e12d06b2d522398a125728822ced62dacb220c845a444594b3b6977eea89e256878e52c766a86a3fd04437b4165242553fc747b80952769c10547804b80c1a6d85a29620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d7452a3e2c6a1f87c4efe1234bb9971a1026292c22c94449b7c8a2cb117b8175c7416284742120c11378c03256e4d2b80d502bc5ddc1d4e3c022bea80140307a3a214ba51c807db26f2536829a62400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34bb128bc0556fdc40ea9eb0b73193396d51c1bd533c4910b358969ba135f862b64dbda9608dc7665fc61ccd645f8926d1835adc34386cea20ffe3283f900a4ffb693a223755a50c4771379307242e4548ed4dcba4574410d409a4838233499a337859c64c6941d477f70bcb5a653bf571602e5224e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39bb8615509158b63be5f5e51a0e690f2ad6fd0c56fa886bd85902abd52598bc81b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 3f57ac87afe43d83fe09b407027bd7dea796a49fa78c01a16b064651ec669319f587597eeb52ea0c3139f2e478bcd671a12c09a419757140d489247281c02b0f39255fed4c1fb81c79497551541b22f23729bee988944c8b4771add0c0af47f9769502fdef1769bd4a280747b2f70022adff6d4cd868679441edadf0e5a9409b09b7ec9bbff46c69cb4ac3ae080830a9d98815950079aa0f889678c2befbe96ded187534fed04b6896fb5360537a8f714f3860c9716cc69bb4d5e30a43a2603c4dfca86ed7326d75f8252c90694b0f4562df8a6506dfb1990eedc5af4418694638ff90c9a8f9289831c3bdc7e352778d9057b467f0bb8d085ffa261ebf964720742939d80de8ad8d9608d93c124b2211a68c66e5803f3a29f4b0d2402716fb7f12a0b2d8b85f7bfe42fb0544714099d1745c7ec78a260fa8a9bb381b75a8a7df330268eded6ce8018a24fc8164be2fd923ea0816635cc0db8d00156cc1d3fd728346580fb99b36aed774209e9e19634e55e645948eb640be29c69076b8ac9f112864887d4bdc55a11650fd9723bc80b9c5e4e853ee34ad3780799cd4d1ff9766a1a70ec6ce7a214a2dde93473cb0bcbd59073be1f3943f2bb9cd79b3f422713f465a15db53c0dcc0ec3ca78bd27d491bc231fe03316041538194c9f6f3196ac721b8f432c0059cbdc53aea19025644b002b2d64f64923c0a09366454e54953edddb8ef2adaa6d6e02c99aa1fff571465f1f4c1ec6ff3839d46a27b99989438373469141fdb9481b8ec1d02c2919fd38779765efdc65de7d6754ff1ff3573d9739f5d7db2e7d831632704c96d8aff25af26f34d6d902dfb07d54aaaf3ae0a5a15e95fd69bea419fd487218048cc065dc8fd3ee69cc6ccb9f2222860247f8ebf7d1801c340dd412bc6629041571f8899fb0aeddc76a26dd091e6769dc129aaaf57f1bb12e38a8b0378f27eba1a360d5a9e50a279f32bfe036f36ab0a33f1fc22a18129a3ac0e45e3377eeb59836fe23fa0c74615d4c5bf6ac894125019c8f801d5f9a44dc00d1c4e6f29a92d3daa5d1b47415cc0df26a19007f179392caf4bbd6700a8e9229a858931e0f1314a705973d865140c583ed0b63a2ec8bcec92d5506470f8fb43ce902934280e24b32a1b365d984d9ea92dd2da2c91a21be2db4351107f1340a199370d5c431ac2681ca5ad88f2634b73fd96fc56dd69ae5c59c6eea3c4597fde8ae96c162a82497bbd35cbd3d51ed3fd09fdffa5e13cfd3798390f149302becbf108beb59a7ad4f21dda52c2fc5488b3cae185aad32372704616db7040e707f0aa801cdaf221ce94b3097acbc5bf11733be5db7211bf88d6f337dde4825b41d8b8c3797ea7b31de659e1b6dc33f1576e8ec6c7cc27a4b2e572df14715169fd2683560924ae674501da9aea875c177743a98767539681bbc043bd99a3ab8b78189460c0e2b4b2d2aa88f7187192f9be33afa5170db91b4a0b80ec1128ed5c1b25fb1ce6c9e41cc662cef6751c1d3a506441252b7ff5fbc886e4e573cfbc4b76c76514a64443371f7dbf959edb577a9d9b241f9d6422887f6bdaacb340add18fcccff5a89c7ba3b62d931a02d4bfc40a38e8964628d576f06819e04d2fb199d5d80ad0f618677e47c700477d74f65edbe882b4be41e25476a6ec9ece34324cea745b6561ea2d3c104e34a8830298736c8b654be3e3716d1c9235d3c6acaff4ac1ea87f9da0d07d09b179156666bb2e01973f3ffe0ef25d2920dda4e55b28d94ee46ce88b89a56c1067f4785b8f1369af3836a01542384661d54ffbed84ffae0c4e4bd1b6f1bafa08c97e0074ee93c6955012c611b3ac6b6b4abbffde55212c194400f1dd28df59a279dbb95c1a9f05d1400e1e357422a2ed4513e9bc97696f0ad239877e1523fca75196fae41c46af4df83cd30558dd5c45c0776ccfb7bd1813e97c26dd5775e3e223c0e09ba27d4dfd6108a2b730657d8bd41e7fc1f119531d5104c580ba6a015c5847110e181fba3ceb6b19c50bfd12aab3cd2e73d36e13089f274379fbe07a9c8e93cf5156faea35e50fdf008c8be6c9f7f502191f7898ca41baff0f61e1a561473e48b59e4dfffbe817ffbe3899ad97b8c4bc91d4f0daf68e3630bf7ee35fd95fdd5ed6f20e0fed9e38168722a581928e1bb4aaf406080ead269382c9b8c4901756f1869a2053d245d729a8d19e8a90fbb2aa2ce4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = cd28aa8c84e42a15d8c2534d5adc642858d6bb2c653bb9783adc640e9945c253af86f57c19c4fc6697ac86debfa46b5231559c11f5a0daabfbf43c40001d4e6d0db81237343e15a41eae90cf8940b74ea4b42b72d9cc8bac78e369ecd7d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a64cf69a69fe557299ff63b9f026e36906d84132c8b56984f4d26f6d7436dae2596e2bf4a8666f375bd66d2483a1b354fff9766845480ff396f6bdd89b724b0f15a34c2288deb05a84199d9803cbfe2f3c63d4dd56f358fab798f4e385eb0e35ed0c38ade7382788af503eee7ad0bc6cc0a4746aaad23345f10074b21a7dc18eacc898472767bf31357fdd3348c82f69b7da6ecd35a8c61984e7dbfdae648ff04a977a72b532a1395707cbb7cd595e0ead202498058e59f23edc340c438851674e3bbee0d97ffda3baa7f87b67f449e6bb461befecd771475d5b59facd3d181599ddac8ce68ecfde584eb225fffde6efb39d9633aebf02af3941f3f3c9336f97cb58086d3f8308ffc4e5db94c4fe53f03dc92fd7a811a9d9e07b7667846806b6f717eae2a3f3156b668f93ea9f79ab7949cb363dcc8d25e349db4b5ed1f66e7f5af991d5c96cda4d47648aefbd1fcfee13948b407fcbe199bc2cdba40257745d765c6a0766013fe9df41a770e96cc95d3cbc70549f7f6e914a73dc81d62f2a3a377fcf6ded59e0cc85b11a74f43d3f37c7561cc7d46c0e660b5cbdba0634ff3cfe1438a9b9c9d6f242bd4b2439f29a3cf0ae9e28d683f0c3cf6ca15d978dce7997fb1664a751458c0731d6fe0ad7d981d5188278269bd481018782f46ed08555fe5799a0654398285b378f7a9f143ce20673184c75e8b76f085899813aeffb8b6d486afeb2f7b3feab95cb7aa327d8b9dbcf7c7257ae3137db731e33f8f555cf4f8b7a1e6aabb4c83d2938b7c2ebeb1c3b3cb3bc08bf52fc1f5715fa89ef9ffd5d85862f7afcf420592aa245690adb8dcbb90d0b654c7d8fc751eb6c4ffe9f46c352bad34c40adba4fc47dabcf04b45e4987f7b977e4359a66466f6c4cc2b83bf6b87785367c81e6489d6c5feb975e41c4bbb2a3d8fda92012ec5242f7a438374da6d32f62c41b184f2584ab5880475cdda8b7f4844e65fdc25d97236bdacf82de2adab59298bc8015faaf28d7e8015695eafe8484ebad318ba9bef7c307afe42d8d512534963c7db9d0b7f5af7d326c33e7d53f49e8c9ce386947c167c8f33c88957f44989c45b4858213f49fa6ae36744e53cd94f1ad467b5043f7ed77f58d34491deb5f9f3f3f4ffe4611e921b8a9f94f4e9bb85ad965443e7f4a73534457be43ee5f677a63a773886fb79a6d0fa0b9cd328ae4c05d8c1d9845eda77c30bb7c39c618afb402cd9b0170dda2cc6ee8cee3a199f5ca22fa1434d9b8dc637a374d93cd76926ae94aeeaf1c627d9255ba2de43d693b888a7cfc6f0c39fa5b4c7fcfbcc198b3254cdabc5ab5edfb438ed3a82b72b5f54a39d21c3787958dc4a648f182a94ea566c598ba4cf697141bfdfdf4cabbc64db80e8664216a6e98d553899964a8bf39e0dc68f8fd7076efcd2a58b9c49bc0acb90283b506dae96f7855ed69ab21f059a11fa3fc477ddfdca6dc1ae7c3f4d7ca5f7c0bf4481d006bc6f2573248dda3027b296b58b4c57e6200c8b392e90c1cba73b87c1497b69e8755f9cd5f28efbcde7ffc0120a524d97d8069da9232f72599fb588bb8ec10760dc535dc30f9e4bfc7def9dd5a82446534462fa1443ca59f99added87e7ee0b6c9d0e7a9fad2f64c8d8dbab5d52f9e876ca5b5d2c286d78467b8bf35e52cf7b7f34b45d5534b45b520bae8a85e54d22babe9c6e8b098a49810ccc2adca1b92f6f8ac8f6ecf9c5fa2b665ebb5449075bf6ca53dc5665ca639eaaa6e20585b9b87fa77a17bc2634c268fc9df25b516878901a1332dc4ada38cac0104c59522947b92abec9aa8d943aa7113d5a9aaaa751b564ccaf71355ba882bcaee053487b0c899a03d7678bbef3c6d3a9adfcbe6eaa78639eebcfa387158e2706fa3964f2a3d9f2ddd45ba7c93c6ba7e48dc7b990d5ec642de672d87d10c8782cd48dc34a925be78b256de6a144c392447f586f82e1c83745fb395cbfa4f6ffbc225ad628f756228e779807d537e6381fcbccc547cd52dc3121b31062ca9d2d7599b62b942c221868e9030e52b016bb30bba71109ec9cf44930d76757d16452623010828925c340a8c2a7772fb71a09e1cd8cb73fe5c1a8428219b9f14eab47ccb13703ab2aac1bab159fc57b1ed434b5a00d5221c05ee77faebb4a05ea04d9c6abccdc5764e876305025e57b9e25473dbebab8bc207148f720f224b1a4887da3604e23321f17167b01d546b5074cb27bb5b6a365b91232ee7cb7f47102902285fef001e4914499da9e31eb1376e110b3bb06fbb350a054bd79e84113021bd1a1637be1a7d3057679b41f20fabf3d764c158457e7a967cd4440d4eb2c2d09808296c1d666784698115a83ce0840467449080e038b81f1c7743c7f71861d0a150c5867bb71db4ccf5c5a92955cd33812d3590b7b999708b38d6867b979650a73a63cc9fb9bf87653c5396ab8730e38201d3d493443369a7b424fc895cbfd96271445849c38ba8c9a969cbb70626698f12223e450c58cf5a384fc784914072ed92338f11693bcc2c48c201390144bd52584260a15bb48401baeef381affc95ac96033816c3414d03ee70ca8c947c7b9ba2052393d3ee9856cd52708ac02294c4cc58461b379a8b3b5c85396b4e90b678c9817c34b2ed2fc9e8bf346ebea1e6987b81e32b6fde7947a1772230257c0b1c564427b0951a451c11c6f2a7c27b6391c2b0581d19bad322038989c3540084132bdcd6368682927524149a4620326c7b968f6090ebca4b7da889b48723ad977bb76369d3b07873b5bead9cb08766702b90d16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7d0084f324bc15a0347ff2264bea0c88711364ea0dae46763a02c3a90b1655eb7d74a59d3687738f1c8b26e0929920089237a196d64a3ea58facd259c4d72e17721efb36c6aaa1572ea88d1171134fa331c43125eac801d1eaa9ef426efb2cbd6718a4be981ebd2375b73c91b7248ef21c6bf6b29a4c385ee899007e44a50af44ff7a4a973d933889241aeb90358f84943917441c7840d0348526b25ec3a15558562f107cf33540823788075931711c5133f8516bef21c8425088435405275b970c457abb73f696612b253221112a34376c3133164a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb3690ba32476f701c7af32575cbac0beeec43bcd8b54fe2c026d6c4b4fa150111bc58a8119c083a1a755e0e0c57be5c0929f64946015f8ac80c07a249eb68afff3388f205353327b484cbbfdf6236222867bdab6bb2fb4fda4260fa1b47bd47b43490cb11a9c3aca191dcab94080bbe8e394cb988ad474c122964739f05b5964070ddaa7a4bf2227e96498f7205e17b77d926695c3508f1105e4774126f014b61194436042c3c155e4a5134dc95583c189aba2bb29268c44e2b6b6d52b70198a4e193c0b4587ab18a0166c51365b05949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a048717b60c22d5b2a6cdfc4158d5747925731aa85bc66ec37d3384ffc7910ec5b4d2cb5442e25ac411112dd4b983b68a90bc57ddb122d73372794214e4e64a07ae676da990239498257149c299a193fa1cdeb371cc354bcde26c3238bae59230f4ccbc4614708fdc39ca5d916d80873908204b70391788cac2a346a1ac72a92673532bc9286455d7eb405c830beaca707fb865aa1d41315628ccec14d431434fff6350e518f3ea8422b44cea3b6b39910ba6b5265e8d18452f7119384244228a983c3aeb0b139a96830ae90b9c2e569fa885406c1270f1654cf69a34c2375f2bb537f39a61935af753cb6ef139317105c9f4b3dea094093d667396552b2b9562cfc0e9ea43c54f99430931f10bbcc0c81270ae352cbdc29658188e67a3de915469ae4263667665385381a352b48176539f59d4e2b19737309efe6c40a1a4d3f52a7fe47089ed22fb3b3c24531865beb47f823221c690b60586928ec5cb9505ac6b9c764b62b63273165f70e76034614ec354b38786feb660704a5de79b1d3399da5c8b1e0416af49c22d7a6982a338471cc88b18258f2f3b55bf51bebdcc53a7829e4c875f18127c7b5473f0252bfe4735c59388b305f3f106803c27c6bc3c51d38070f1561eac805070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305cf14252096e4988d8ecc4ac6d29ff09c55d666865863d03a68db523728910a8273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = d8b74a1e62c0230105fabee0fe5352ab849ef211480ca818b64eecd888685317bc56a0c6bf0bc53df14f5af71bb0cfdf146ca07b11be69b9fe13743c2dfa2f5c2df130da68045ab3598e9c7cc0510f2f8d363c5624f62ba60344019436150dac29a7ffa21802a8a341847d99bc10cf989f71f2de3aafa7f20d49bd37d14b6d9aa90e09418de03ee3944aad45322fae41cd0acadfedb73597ff0d2cdfb86fa3ebfe8e13d8a5158cdedd760d144676e2b7a7f9fef5862b6466f8c421d4efcdd5f93c8ff86d4f42dde6fa0857973061f4ae50342af9d8f625481d7a0c191f3744d138cd7a11fd1b39059d6ef5c4d04864e97f96561e4e54797d2735db1e79419ef1c1aceebd7e0d8f126a54c9dbccffa70ecd2ad5a5c926af4371e2d3192393c549190747fc6f5aabbf12727c772227ee77576cb07ac9e5d058535222351a5d2a4a3fae8d7d30eba922fc75a89209511ce945a6cc55475afd954be547a0dd6063220ac58e188655402e5bfaeddc3b800cd6a4488da839892deb75504e84f550bed98047a84a57e597e8b6e1585e96c7b54e5c8427251a2c30b4b5790a976755cfd4e32968066fb4bd324f50ba744d8cbe9fb96c08c07663d37d08991bd36156701d60e7ad3f7281bc209b0ec79dec9b480a38500db888630b105de2143f8648618cbea5558f311e231944c5903ab4f61113fb95b80ea1d0f870ae521549fb4d201c70389079396e56e7bb2822241dfd9742738c62e30e2019d1ebcda1d720725c936b20837ee40774b702b8a851c8ce68f571e8e1420d05400c2016d4764b33efee8dee011726fb090449c8982d5b8f80a861f1befe0e553b3a9914cfab46ec458fc72bcf3ef2a6864e52308ae4754b7d7547b6d2bb16d8be6121b1af44284949624fda63d9573e56070e4b2a06ff84b4d009670e6270d307ee32a339d7255986c7885cc28a9af64c4231c3d85a8e1cd3c48d4cfee7424bed108b3ce5e962f5d29ba50a60c7da9e8583401d7a88d53f647aa4a0c48b2eb1b468ebcb1a2cc7903768e7d6e359114f3babe93c0070e26388ecf5d3d6bda5d8c0f3f57a58e26bf8b2667bad861b5d5d120c63271e4c0e6ffd0d6beb442126b1af8f5a97143d0051a48dd727ac65aeae019667d773b5f533fbc23e2dbe20f838b03a43e2ba0f60674e0b2798be3f375f2c6f6106d8566264f82924865ca6db0f5a5b3ccfc8836872eaf443020b1402ed8575db8458489c2e39d06fc3f071ea6578713c4ffd345669948b62fbe1ac4e747a68086a5c1c0d3bdf464d82715eeb6573178dce7c53ce94c340cd753f062425fa5431a670ec5af19434f0ca6f18638219a2edd4a6c1186261fffb0575e426a6587efc48d88ffe01e675d526ba18e49d794765bcc55dbade1ae3443ee61c9869ba7d5fcb21ae42162f37a047fa8ef2ccea32d1bc1f6d08c7a21bf443ba6550c04aa61b4277efcc78534bde2a0abc6633e304bfc39e6a19385708d0e08f245b77363bddd153087a6443fea3b2c586bbb7e2920e29e0b988d66d0f6b0325d058adac1a0f377dc4ed8d73a18580cbb133fdd00fafab4ba16d011d086eb5653e3aa9f3ebe53f88824b4c027587129ad990b0a78308bd101e191cf49174219bd0ede582af30e4242059e79d90058b01f693d56208771dd5cfad387bf3fd085053403a6a337d16456fe1344de38a830e9921bc1d66de1119a9926cb047d4adbb9d4a80158d17404538c5f7284f2469d6251352dcf693fae17b89613f37549a5612fbfe5366149794f5e334fd95ea233b87302960b67b0b3bfc41596c247135d4f95decd2bd82e92cc7f92f27186916ed9c6b26aaeaef313ef75aa2b5ffb10d509e276db55497dafafe9ab5ef4c57050f4270bc467ca004e1d5aeed5b8fe80168c4004b7c0826ca878ddb79d8ff337194b2602d90c89c63311268bf37e717f9faf7a0cf1fed7b42f922b32b010166e0998f1d07a207c41d2fede3df9f200ddc0e9bb59a95af738e0824893d8e2faeeabc45f8de103caee88df2a99d4b9f8e2ec6d45e8c74aced33438bc771b267c4eed7a1a1f5309ddc877591380ec9e6008a6b2e2d0fcf11ee580728d05a66f02c59589a59cf716bff1ab161cfdf9de7694ddff3343f0cdfbea1547d59ff0baf541edf2fcc3675133c9718531138203d22af6c0db87a395cb76188b5907e72a5fe03a7333bd64baba11812efbb23d60c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8dc4a33d1ad13e2dfa7ed6a5303693679d33816bce0c8a83594695531999647a48f77d8c663fdbe4d9a6100e3201a36ee053796356b26e46e7126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0f1f7f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab2233e8856ba8b6919c5a0a667867cdd2166b69bed4433cd44f289bfd7255542cc7946c8fc2db388c8b656f234a3b607c2f77eeacc3a5a12d8e11f5fe38abca9b8dba79a2ea17778fc2beee38b133636a5ef5aa77a52b7554943af52f7b53d0b84ecf44fd88de8f716fe564c5e587539957f4242d6b3a8f8a66d05e9f8ee3a0a6cec4b253dcf1fae197342f5e7fc296498bc9888ec347f528958aa689c8ddb81880e84cafff5509e8b746535482687040d790054e65216c8bc279ae93854382cf8cb438bce444b2258afc3a84cd409eee8373f877b30137c4ce4664e4d43dbf763b344489604e97f4cacf4ffd2f6d07c5824ccabe38cae22487ea2fade8aafdf304bb911c4d1f4573508a5e2ddbff98faea57f643cd85f4a3d6c9f056bf5eab6ffbdb3e8a7b8c8dc9c5cea953ad527dc055fa7bc04469987712d15f2257aeec52961571e75c32abe93dc5ed47f89b9d4cbd3966911fab85fe47b3c68692cf5a845286bae09e594ee5c6d23437bf7517ec5cf609c8628e8fff7cacb54d4a5ebdf5c85f59ab61e51f945d24788f459b598a2089a86ffc9bf66797e863a4dad732268a4e40c5700addc7d1ab1ff46b78e45ddc0ce9fcaf8f3bdcd40184af7182abde00a966b6d75e69cd11ab6fef09e3024ccc85b56d098facc9c4c81d17c577cddd9b8f9416e2f5d156c4e75b84691b9d948e3e884beb2ab3635dc357ae867b2496983cf9595423c541e4ce7957d42b4de41f08f5c9996f302ba911c67619434b3f9cc489e8c8abaf9faf1ec3045c895edc4ef745aa1f4dea625e47eabb494331f9a560857153ec4890c8fa5769563b8b1f9ba3c1b77b034f568038865c913d4a4f79f65f74c17fab9e6c5f236cb636ef5b68637ef955a9e889b7a1faea0118f8aea1a838eee72400e49cf27ff4899d161c34039e99b36185f068b5707fa476d75dbf149479b8c928fa3d89a4b941047b5b538e35685797e0b9e65f595da0e6a614393cfd630c7bfe7d1ad3091853f607bf38fee3c93cfb5daee9b2c57638cf8fa3d76763afee5838b8eeaa5a47b7b686fad5cc088abd48ae0ae593ae3aad7f55cb4c1347acaf7cf5a5ff182749e6aec39d62ccb886d94ba3cc0b97ec57a03a00ad67c5c1c6efa1ec6dc36b13cab713ceea6610caa46db4ebb86b7667fa0be6dadf163b325c89b506c33cc343c38afbca7cacabe9d494f044b550778678cfebee76e047ff705556b50acf04087b5c5e5936d0e53857691c3149521c8d0b76c431958970685f9a4a87d68e974ed67e78b7980effff7e425daf1234025757eaa3b645074f02d73feaea3943c4dcb11affbf569ab2c44867d5eebc834dd120e34d88e43d3d44b460d56be166b58afefe64a44f80968a1a4ed91a971e10c347aba36980fb1ed64f985ff8b6254bf61d94b6a0de6b0f3fb05e889761ff390efed87978eaad45bf5997654c4da9043e9ca74d95d9f97b6393b33066d876c52c5ecff7afd501bee4476ee79fe3b5747b7b11af7b6c7187eae775e4beaaf1f9d4f96a741a6a4820027bfd7be5514aeed9218355a8d90b2fe45d2885064cf4cbc26b3cd0ff887ecb3b67cce6df4c1c55f70239545464bdffad6e1dbde7a6f8ec4b80543e6e7cec67cf5c9ef3560e3ffbc9cf9740433462749f15658dac545347c8d4d5470e166e0f85e5756cc4eb73966718baf841995d1ecc081d68b4275cc8e33a87cc6edf5dabd0f7cc980d5a043c431d8b6bf2b76ed794ecaba2ca6aebbba4f33845966ec0cd68b07bbfd6764c27ecafce3e33453fd72a8dc37b6de92dc4decd2937015a5c0854f731c97a0d9333a62648b43453750ecefd485fef16845077f71a7bf36857c69f3cba42a2c5818564d2cbc33d0e43c926a4d57c38f618b51fc0c86c6e778d478916c5ae8615fb4dc9a89f7e4c0b089aa23a771bdcd6f3b43a8805ae8cc4b8ded358c7ba66b5f7385996968a27793fe845b40a4af8177ccfb45ca82f3513d29be6dea3046c9bb091ff0bcbea0b31ce0f1b45961c6216fc930a8760d4b79afe948166ce6222b16acc847ab4bd9540cb68872c9095aa7619b88414e313051b7abc0248eaf745c7bea31b01b29c5105fd698119ae0186e7c89aeec141027b19a5ac3e1c419dee19825f518d46879f43c8720e23f8916abad006b3bca9600932a67938015964b25b75d95788278d0af8be577ef5cb1fe61cfadec5500ad17de196a1f95187106649ea4227ac9a96091617d673f32454fe68442f0509faf86a06d4c421746310341257f48c51c961342372954e8373796a089721cc646b6c27b2d7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331aa082d1b66d708304ab884ec6c7e9ca98d7edb489fb2ad522a2b0881997662205a38a35ed77d8af15b70346fb825a25b0962f0a8befd5c602550925ac9454b6a4c02db9ae9a569dffc568d70a1bfc95c108b03f16c799310a4aefb74ded63c3ad4791ce3ad8cdab1df854adc814b2a1164e551a36cf87daf367f8767b122d4c2ce30632f22341b5458eab4cd2e9547f83b2d50ac57d8c30ecbf5387db6049a61768ef21123936664a46b4a2cadbe1b7a5ff752dec141f38aa5b0b85546b77f67d32d40f6a588e63ef136013f0ba4e2889714c309835bc0d8e858863a29622a843cc49dd2b85e66214c0b2695dec22d3c4a0f6544940ac77eb8a1c415aabe7797bb4e8079cf74943c5190a549a78038883ec62093a70ee6022df193a4fd7ba17714af692923b650b94f5b854d07139b240c29361ae9a2cf34fa4f1f6c2924850471d6338206a1b8c806697589b5d8a2ab860f4d1614426452038983dfe2ca14ac40170aad48809c99f68e5197a0f02a78b481062413cd8779c59ea9864bd9c68e8705f4179405d5a5ffb2273051bc1366a26312895345b81e780fd1683ec8e3261e1291723978a5e3350ffb6e1a7923b363162eb14247684d01cb3f48b7abeb2154a2751061327ea5c3839fa0a0db315b7ca60b0a7c5903309589e8812f5301dda14e98c92c028c1bb57c1b23f1b90ee5bcdb448229fa6ef147c56862babd6aabe7eb142e9a671de69786010720eca14ef6ba53d71e5ba885d50bb325707865b564e0018d89f27f8fd2678be207ef830b3a6457166b031a307cea082b8260937ed83f20646e50bc022f81cc6738b16f16954d983cc7a38d365462a564c8d4417c29ec50daf373f0c8134d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f8810cf0be61ab3d678757131ff93b5ba9a9efc54aac9fb279991370742af6be65145ca215ef35dbf512f13f88873f87b17f3c4d9e475f90a02d270ae72734029710522b93762d404691910a3e79686f6aef2118446d23955da68a477bafbf278822276b3882feb3112f2a47ec753510fa97bd5e4111ec67a66909fa3557d637c3686a214a81a6c9e983039d5cbd2b1853ebc7697a8c0ab34342fd3561d8b3ddb0575eb62c0f509079a5c5a3eea1b23417d70eaa585aa36ac24993c6cb463d63fb6129583e7908dcc4c6e55ba3cf30eee2842696777989b90ac577bdcac111ee344ad1478dcfa7bd15911d0e745a523a64dbc28f03c336dbc9a86c146c8f842478a172706cdef994d87c562d3b39911441e6570397f503da1f07c0c6045c3e863c7f3bcd41b787c8016058b81fc7b3375e9185696813a589c75995ede730d39715e66a370c127121235cb7785a42bab8a091872650062a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b85342b350477688a0fc2c5905216a7eff70bc742723d34a3daa13b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066083b2805846267cb3c989926d72fa18abd97cc0531a8747ca42d0b35c89478ffa2d3f769b1b2c0961ec877e704212115df3e171eeea463877b2f911878a15310b6042c1624f6232867578a842cbb477202395f51c3c129385993023325ee405975e062c705a63951b080bd4b98e3388c74cb6c4d9ab3d66a5e543481f300c2f8a1a17e7cadc83195ab4c840756db9fc11c39196bd34071e1ac098ab332354bb23d5a376ca35862070c933875ce21dd7383a41ab9abfe2ac96170c22c5133e07089940c03ff80ee80aa18b33bcf8061fd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ec711a0e259e3548f38022a5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0345118a7b9bcc773f0ec10c3e353eb4365d2bbff3b812df4635d5c8265b5d8c5a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = 668488b1742ab2b5efcb1ecb1abade0ccd75ab2f924a22d86911697d54145df559b4233de2c6174aaf9b4a28a4cdc61e2e0e45525c5faa7acbf6c1010ad2d278de2a93cd2274d0da5f0d6228f79386aa7768b9bb390aaeb3960f4ad68c8a40c56f547c94b1ba4f23646833721faca288c9cb7cf024d0ca2ad9b1c038abd3fb33d8315eff7b6a449d00f23c1614fc34b561cdf4bb49e18a4a7f0c551c61fd9ae12e8e26d06179de6b17253d162db35631fa96723f5e7d333dd283d66c68f974916c5c9e9860d5b0abe0fb8c445a00cddbecde8e97f621e2a8879dcbfda62352d658bfadb048d0e283fe5a571ba409a77bbd1fe24abb54ba232b33d24524d9f06128c08d179218738814f0c5b694244280eeb08d16059e85749a7217c289d528fbe06aefb681aa49e53dc1ecf487377e936851cae7be021046b64e11309d8b42a7681b851890143097758f5c5579ff4a1790eb3db4707731e5c2c46e87d5d4403fcce998936b8710fbaad0ba1525bc0bebeb8ff8dbf066e0a3bdd26e73aa9a19319d3b1e227ee33be3688108906441f306fd580608fc0e9904e99c8f518cea697bdba243ff762da3aeb7181b1b8c36dc8d0dd4df6043ebd9e8d6cb03a6a0355dcd88b134e3230c9d590cb2828ef4015a93cd6a6248730591f467b7c16d0cb3ed65000d568f4a4fb3b72a84b9d104dfa3b0d1c75c81adf89320545940394301a7176201a95a2d5502df6c79299921b2db70b2c0a6421f6fd4ea80346f8b6d8aecff68fd3dd9f4cf9a84bc9f50b7407036d003b6b470d57bc9910b4dfebca165f4c7bdd93c8f389c58b4522013e891c50bb8e34c57820e775ad7d2f5c824e6b7ff090d9662077df5d90a378b7fad220687198fb71c554b02b046690798d0665a53f6d7443716d11be803b317daf0c32c081ca0db1b71530b70ce3d1a6d4b59a435e2d423711abb3866c85efa62d170addaa29499d59a4ff5363d3d628bae1ccc279c8c373c49cbb73190558334bb9de513b31291efdfbe824accc8f09ec5cfcf43356d2dccb747a1983ca42e2bac83201491b2bd360d60d38ac8fc9ffbae86c2a5549acd88848104cbfd2647eb32073f8a30089535b6fc2e52f078192e3f5418e3ad3ccf8180568e7fb0f5187811f1f3b5e53bbf5c0e9890e0ca9c288ebb33f52f1cfd83747895f58ecb635a0cf7d671ed298b7d32ba470e6bd0e25f123486eaa8bb304ce20a2ac813c7d40e2e18000a5f59fff0eacd85107ba78f6186744114485f1af0ec6d986335c086335f045791aba91a99d76d3ec48d5eb4d8baeb9ab91e20862d00d170770d2486e39e3d9db208784e9aaf773993b4611934f3097a58bf6362f3f9555f93e5fa8526d3a0acc9840c2748a2729ba37254f16e8efdb82b3c216cec275e2243e7059a391854f5c4dcbacb109fd2c6ce10195c1ce02a8add8664ff46f326fe9eb38930b0d15b5c5e51f25b3d4e608c9a69c80520b4939d7e9faf21b44f01972e994b8c503507f2f6e848bee6df7e6492cf480828cfd724bfaeb26ef089ae29651f3194d21658cc4bc03dfcdfdd5af8c1a717b8dd3897f8d28db9768b853b5b3cf44a059042ca1d12544cacd0d91ad0d6a5afb82af18cdf21b697565390c8a1d043728e5309bf3be5eb71445f3f354fa5791e3e96e7b19fec2f824389f1882a1aabdfe62798cf48e7e2c58838383f99030bc0b1765a3779f764ed57eceecf2f32a985e48edf1dae22ac52b3b6e16ca870254f4a00ed3ec232bb7d77ca2be0f30a834567deb806e1d95b43021aaa5f0092ab91318518788083a1f96dcf22d387dc7dc35d9974c85d9f636b46c684cb668681caaf7de23dec177add2af7ef4c20084b847248aee6249a6e820815125dd40e141dd130a5260191628e44db1481b8a5949587c91f4aecc37b46c3b97fade84d2e6c6448520de16895406db62bec81aa6a92d99e5a611096128dcfcb2f996710b3ee1fdc34b51b6fdaa1a888c3a52c2d2d048555f358cf2f65d3c3537207b76e9bb11c336fc4a2dfea1ab36b4f429f2230515d485e5ee47a6a85d7eb238ae0877dc523882055a6deb0042eff47997b8aad4acb0e99c627187c6692b15825ad3b55da9e4af3d5c5a1d6900b16821c72873e027665ff2a5d9c2a550a89e389a9781163a3e3e559a90584c4de86403f58d8cf181be224fcc6098d28de413ea774a6b166e6c3d82ee9184aea +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 38bbb649e7520a59ac57783e32b5d22489365713cce40e71ab46ab219b7e81369af44bab6f5badd06e3e963938a18f9acf6f5bd8594ed4cd981c5963f68874aa876855a9d41c5cf96b4cc181e57667d499b2f961f44773ca958193e97988e8e6d81fd78d0e47e41390f503921f139384d75efd9ecd08544536b4c9c09bcc2914a808ed90d98b5c08cea4a1ce6ff0eab557e5ccc197eba1a36ff67beace1e3facd6bd16053f22cc85634a3d56e564e30862aa24d9d48aaf92643b630d9f8f2d6c2c8bb7f357b9432a8474349c3e1679f2de54cfd4a373665a86c481b9d3e63308cf3a2af65a73e3d0068ba228eae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2b4f9aff3c9eeeb869ec9982d367c5809396987a2efe93dfeafcf45e774cc3541bfe655a738daf9b7601fb5e83ac6f682465fdb273ab435355b84563047bc4d7fd4aed3e0d4c9ee8b849183ce6a586d5a6f5690d48d4d8857379f1eb324977f30b461955ae7cb16c4dd93761224a47f4c680373c51eef51cb69a2c737cbb1f76d7288d33ae86480c7776cc7ca02393f333b6cc01cf00ae58922756d3664a30d8bf6240f672c27a7496746f8f567987f6340c7344745f2fa98d819d76a004a480f48b74f7c6ee1998741d39fed1f75977db4e8057aedc67950c9f9e30d526ba5a27e0bbb6767dbaf2ddb77e5f5b07db7b6143a7419a35273c14b59fe1f4fc5b69e8a62f3c829b5dc1fd8715b13dcec454c90d7fe6509ab1936ae759dc6b62a6720a840ab7e4f7b7bd134335c75c44a421598b89d631e2ca498ef56be08910b69c01997bcd20591d1967ef5ec5c036bdc1f19a01cdde03de6cafda45db70950cf65eda254f741eb7233b36397def4c6365a83b66d9cc896ff448f54194fa15f67b8154895173075039143dcc5816fcbbb1946a917abb18478815f920d24f8c856bafb3461a463627ec743077ece75ccfadc95622fbf925a68fa15e487787389bdfe4dfd84801a37bc39136cc1a49cab7cb92487f606d48d3a4ebcce4ff1ec4e8b12a6342ab6c358ff73795339bbd7f0439aa9cd5a47822fb8b01769eecde3686c8e872a4e2c049a755a8f9556e4665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc74fc0922f6667d4d958ce7b3d9fbea21fe43dec663c6e55464ac7a9559c533a647c6ae06c38972a26beab45c2f04c974c9bb860bca64615b6f088f305d8e862abc974df80088bac791876d327fd4e44df2655ff610d9a49989bed1d7b680b62cedef75109d89fdd7c28143a405a600a974231cfd71abd953da3c2da574ce2d3e786c77600646e25b3c305f6507eaed84a836367cf73d62c526e0630f9b483caf335d6bbb5bcf4adec4e43444ad7055349cfb690948487f7795b67ecfe4553de7a5c9564cc84cbcdad093f480aa844417446babd86a493b7aa163b76b5df35b7384cdd54147a8621674843d3d40ded6eaec68b6ce8a2c5c4f390c76351feddddb35c9f4c4a1dce48ba0860209fb2fc1fc90899f2c3463139239a62e878e4db61a45f9a8fa7905a8aeab0adf16dab5026469b27e4e22af5561bc9ed111a721a78587efaf59a4c7f6b743574398e31bee918896ebbefcedb5b35b095c3ad863068245498ee6b9495fd2503e31e5792d337c7132d6c2ffe51ed58c8cee3e6160979d74b4c55bebe2448562cc6c23b96c7eeb3600b0f8e91e8e7edbe3c9269bd8fae52971efb1338ebdb7fe3f1753823037d25fe4e743f67b3d3ecc3efb236fe665bd6a81568c7bafc902b6e84cea493508772876d44a2f7c2aba3a07d66dd535b97499bc0e084f3221797cd1ec4666fc721a99c100530ce1bdf8d19d13d27bff057a2456a622485f97d49bb98595d6efb69d9353562bdf8e6b5a9da9a4207ba35f1bedb4cf66d7ff4aca409c8edc8e60e8a60c62defd58dcdb05362430c98bd8ca34b3e84060f4cb2b4f5a45384d60e889e75c954767a1e274392c830694b59779ae58f1bd6cf2b444ddfc01357e0b35cac599bede57d48d4cfd4d004a7d8d94810f9a751d782b7ccb15807e0262a53fa7b3d4667656a0efc3747de18eece35dcda230465a049d3cbdb30ef18ce8c2d33e9c5c1a696d67ee639bf934b29b5cf2cafe015549075dbdf609653e30fafa388a409167020156648552c8dc941c1cc6424693025e263aef87f3e0b7147d0b8164077dd580f8c5b8f8ce10d77b217adfab3c65a2e6a04a662bcacc640b0eee6b08dc32c661751c0c8bddffc2e0bb78691a68e7eba25457a42aa0c3b15e17787619824e02edc7804161a3e7fb092e897506b8333aee03fd8b11c943853f1a9a44f5927309abde1321d60f73e41538cb9f83e3fa004011a94a200cc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29ba2274d759906a9043f2575f850f1152542585b9feba4368598c883c65120048b7c85e1a361adb0941e6479370f01604d4bbe85ba4683bae545b3772755765073899b00b0de9a6d810137ba8a91aab33ebc21c34274f3c995fe4ca8aaab926e7ba0d83175100fb261272137fdac3ec38ac299a25d2d9c514937e4386a06831ac39e21fc6e702a50476493754a37261c7187cab94922ae12f2b032228934782c056aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c6717905456d55016360d789a1f5ac166b1508d6100b0ce914216ca0476566ec33417ac234597a45c8a519b40842e5ee66b8b69269be2848053c50b38c258e38ad3104e9a1a50e9872dae129c38a367418c84f0cb5acedcae229291c3f6aeca507007042f609734dac77fa01c1735245d06f64aefec7736e077d5ac9d8767346250c7dca28105477b18c681fd779123e93788624007bc729ab13352f9915d062df3367d1acc58ed8478a9e6216a826977b770819796f24cad7db1538cc41c03a8192f2323c68a9f28fb0145cb543832639158cb098b7693c615b820ba01a3838cf805b9972ceec7689e9bac7831701d543e87a880fe91b59743888aac439d1222a5fc33f5068844fc3ae421cfe80c50db3031584a21b4330ce1a7c014b11eb3526ee4dc740ca7179a428dac27c128421167665f809959a5494c6e3a53f9d74f6e85ba7442cf68d999ce2a891da7cb6903ade2f576f858a5f731c259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a3896917ebd7c2e8c521bac1c612f0aaba462e48a30ba3d37a28507a16e20658f34ccd3905db5ab94d6333b1390e7a93906eb0c59932840cf55227f19a2c8728a7d385189057144b462a2338df6151e02bbc53d35412e4235d7045e47154e4b910a47ca8ee678595bb690a6b4459b23fbac0b51b055402a9a83f29691ae02a500c9c6352658fd1816a7a9e3f593ffda6939820530793382ba38aa851433585a39c68c7026461f9e0000b365ff2b67a93eb83437b5207061961233013a41cf7d1ce8f86c6b8159a65cb979161410d24b1b20a1ada82b72d127e941846e9d16d16f3b9a63b9e678057a20aacb88238ed9ca1c722307e2c2f3540afb2b78ed999981ff6a0a0e15f3c3ccadc9b242b886d12f29ad6113d63c8268c56913458ad31a04f6130845a1942fe68b9384c3fd2f62fe034c8e6ba23bb6799163553291ba2376775c4a67914f78bb75026df18aac6c8c9e6e77351dbcf8b97106d7ba0df874b1ee2bc508222794543ea60b3dc95093f288220f83b6a6b456f2a3bba809af288ac08b44ba9411bccb5ba61961817e20b7cdb6efdc4563a6b4b4888058f08ab01d702fb015f20c9202af713de66c1cf133bcde0277f84a5c1876b7adb21fc5a82555474b70443bc59355e3932d20c14887c25e9517c69d807c30a842cf50549da1620ea315e5a20549b59106a6e1fe56d6c4657d6f69891a7449a57239de5137e8c3efc2994bb0b2bd8cc49edbb3661820da27199414a33d804acbb1a80da68ce288c0974b0b1a8f038fd1819bd8090fb022fd648331699724b66059d148d6445acbcb9b910ab14cd0482972858b56541596b5b809aadf81657796c544c02b9a6eb9160bb0cc6445708d71051a89a88830c03c71903892860b950fe66495f992829dc783691876a06a1ff983965d67f2207a60643a6cbb59be857408d802b86f054d5137ee8e6a02d2603e29b4e970a9ca5f49e64e39f70fa5912488c98d28daedc20da06c811a38aafb0064e9ab2f3628587f7a099036a0ec71d70b04ad0e26919146b4006b15221ac78ea0599325b9de25c81506a786949deb23bae43c27c60b79f73635dd64b35002ce5d40f9808ae6a51cc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b772f50f7047714627bf76bc098e0b919145fcd8df6922ebac383e5c556738390e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = d49c2b7a2106705cc9c8c1a257b88f7b647f7aed1bb62b27aa4213178b6f39ff9e94185502826a0c36eb5033cc4cb6ac0f94ce65ba99b40743876a3478661c824ba2c86db3a7af824c0c0e771a94b181c80656fdb2b200587791262bc89bd2892837037132dd9b07fa19d14e4c5fc19302b26430bf8701e847fea6bb5c10e3c8305f90c9ae4eed53dcb4d557234b06bee720481124252a4ab77cc61347aa38136342c28d662fa1e9f52483e30337240dd14dcde53f9dde843a77aa38887d8e4dfcddac3a1ca2b713167f9b64fd76964c5bb1b6800f9d2e904f3b4a573357fc16f2ce32eaf54306e850091d34f3f9762420e56f37788d081a3ff997af2407d2d48d86401777bf63a4bd51cbe8f6072ac5a799c9b174130b2fb0efd787dfedcad6bcaa7a77854da9565c0e3ff941061db8e166e26fdf9f0ed78c40644af0e5cefb146e5257fa1d410462abd301703a89222325cf45c9198227331608feb7758b15bc3c1860b94f80e14013e3a313f83560b8c0929e7ac731c06aa4b29adbafd18123557bcfd363f595950636180ab6bd6076f64f3d8cdc2de61a69e6932b78f1fd400e1be742ceca9c85a088e459ed8bc3cc2da9a50b2ea8a968f6bcd9b1f292961f07d96773ddd2b48479f8896c5a6ce6d1e6c856c7705f5f66c513f004c5cbe844785e6c0518e47465aafa1268062ec079107b63802e02df1c7f00001c5e06e0406d9cfc3b264964d458bb3589605a6b15bcac15605c882d42b37dfbe7a3fcad0de74627727551788d1d4c1bf27d139f86883db8384ae53dea68ed93a83380174824c08db979a773ee6648db9ac2cbde415c8aba0f66fd7a2611e0a107a9d86c06479568c462eb9dcff7f0dc0155ce7620526ab937f04061c52324e9cedb8a39626f57c19ea40441177ffa949184c05eea0b013e2b5bcf36a1c8800287136960cf328e63eb51a77c64d9d1351753c76a92095f04ab8eb7a4a105b7776cda7b9c5dc5eb9ae8fa2bc069b745110b04486ab6f6af90b8654f134fbd3c4bc06f02e8620bf4a452cf3b39f96ba95246006acd9009c14d430d28ccc3634604624f7b4a04c14ed0ac41a8f12a9e8fb004988a76926de95ffb7e03de5e977f356d13d4fc7b4a0e73eb65e48124cb5b035a4e3ff30a84c1ec565a441eb5b6bb0f3cc7bd1d51703e3761d19c7e1b1149d8d67daf17805e9e7276edda6532d2afcfac2eaa9707750d7568e4c2b8bd5f31b4c1f5adef0abc447589dc8cf3c3c78cbef3df957bf9f87020106cc927990b93625a91858d7a1c1fb2c7127f11d8109154d42673744ddc3846c4450e698fcfde63f9260b7ebdfcf920b0f841fb17100dc9e6f7c654825be2e8fc7e4f8afb32a79e8e85c57109563809086a23e7e4b82e09a89afe2f963334482019aac0c5d52180c9bfa0db8bc5d3120ee0560581cad04369d2593c10ceb449eb9459770753c7e6829179e11912247d93e98db06197c7d44450035b0a2b46dfd8624949bb98b4ee93f7ff1152baac80d8a30971af84f4b8677c06c2486fe85d6f82c092976f5a15178c3f4d7caf1ad0b8c98bf58f400e8a673e49f9584378ee71fe72740424ea9275631d16e84009c3d3f64e131362bdaa49b9d025ba149e0bf770a76566533f28f060624399773a0bb34e380e99680b698a320e6965c724ee3dc2654d3cc520f752886ddac9951dc921808f9d83f466e77e3c4ed05dcaac7888947569c720f756586244340ec5d79710d80a8d3220c7b95cd3a2c649aef066e204197e4161fc7bfd76cd92ebe5e0fb75984711e38c51449fbab7e68d6e3f3c0fca0414d19ee4f83d5b9b61f53dd0d8cf65a8ef701435d9c0a1001451564a7f67eab8e2c66a84c849dc50e8d099ea1a55deb34ed42f8a9b385b51b714f45402bc9a0c77f6c2c321d31bb5e28b3d26bed1e76355f0b96ccc71db5d4eeed4ef059771f988aae855c363d6f9fa8c2e9118ae3bc33120e1e7fe672ae06dd7f109ae3fab3586122c6093c35b4dbfaab4c25c34364272d047d4a9b39a16958a764a00ca0426a9945dafb5fa44fc288f8d24dab2817bd6933235148d93904946ea753421939c6e6cfa42db032b37efa8fa124053b50f7ab54e292a7474c86ed599539a583bae64084eabf0daf4b8c1388e57f3fb831a633a118881548b6df15056f72109c1d5d78b25b81c7e3ef51325e2f49cfeea570af8a1f69f1ccb9288 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = af46e3488d9758cfae0c4a60393c90222c394dfe36e965e75537f1ff136dcc234d657e5a1ab43d167d8187f89a693d791f0d62cd53f53ee486ac64e79e4fdfa6a8bac5ddc07c7e58a1eccfe52c48484d3849a8fd73288878dd4eaad37d392aa487597f81fe9af7444e5b8fcfbf5e609af5e5c1c3f0b6c75af0def1d6ef904b0e85654a418e5c7a379b41838ace149b45c5b4d40edf39ada846102a6bbd9eeebed4710b2393ecc4bb8d6f54dd8e5d2667831fa6f887a74eb883a5a874fe0c4f7451ede321246a8797b7bf2fe1eaf64b0d7d6eed0ae8ccafb0116f6112ab6b2b2b928df38ccbd9b639b9c6ad19de92da98b5c9914549beb6a9b5505579a56943d31d722bf590d64ceed56534a96552016ff6c34cc1ad3f572d2ac0823bce358d860975f5198d88e02f9536bac34a1c950843d9a0a7ef31d975de0598e5fdd9d24661b2a79dfae85343b94fb1cce71493ad77d767e18e48373486172d5652eb4f98838ce536691de8c3af0a4970fbdc370db4605841bdbd884e08bca3198b05bfafa6f575229c56462b95170f6d33dfce33a4b1add3b41147eea75e6765f457613ccb50f94ab9395f6fbc94395a6c9d1d4ce3b79171a83a4acffadd3a915086b804c3b4240ebc1f14630ef3f17f059aef485c019a4248b4a78b5e6d769e9eb3be5bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bff3da7588d44867897c43f687e9f5c8bbbd5d0c35693f557f64eb571d6ab7e4a752c9df67b13f9d7558fe4bbc54c96e2aa95c0408e641b1f9b17a3e60dba78c5fdf69e93610883f8a73c67c0044218af5c2e05b64a1b8ebec972606bc221bea456d8ba86a76ac4a3c06429cfb6035ea50549db887a606e70ea38fbcc295a2f0dd1f68ed38fa97b6bd98fe0399ece3755d4b55e1636ef7fab678c394c83676cbafd80bcd9e5c9bec67dc998d7097074249585f3ec5c3dbd035dabc67d531db43f547cfe05983a7c6fe91288d9987343d08fffc395f5b2ecaad2ca703679cbb86dd420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04e3f59ae0d3db768559e173df07ad8794be0e6aea46145b6f0fbb230ca504424b4ea6e7cb305da993567b4cb94cb2cb3991ebc1eab31b5f5691f04e18e5a6eaaabe5dc2aa45fc4ad26b9ca007a7c2a78dacefa88f12790abec7e3eaec13a355c1c66911717da7e1976f6859922ef73f53632b4144b59eda74217e00d2cade0c8a04118e4d40a4234843a44978d0d5ae73bf5f43486d423235f5d7c8e1f56c8181487bba930cd9f72ace5f4eb6c9d71d753ff6fb0e9ba33a478b7e82b36d979d60765daca36e086ad872538eb02e531432b35398b7ed1355b827f776926bfe41880e09daf6a5ea58a8ec7097f4deba6b6c2bb8af2ddd09d7ea0b82ac0d14cb0910a8ec3988251dc9e94fe7e0686d8115c85bb6c47d34afa9359a35beb47c4ad4ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc14d08883d04bc535bd5c74dd59f47419601513c4e91f57323d7bc858845896a67d33902afa4b58c5dbe969b94795ebbd89ed66887cc6f9fe1aafb92ba6bcc38f5c4239ab2894b2467547ff3a63bef65edcd579215aca67ae3cc77d5453c4964f2cf94a9e79cca36a3b998bcd1734591f7b5f5c9db5eef448d391504d92f7f37f4e8f6221ea8bef688917a9e9ead6ddc2547c5e6550f45bcb3d4b41de2be2273675a1fec611c6e99f27cbd277a38a67b77aa3ae8785ee96f4b268f75b37dd70cc1743b469a2ed493d510d4ea5269e91bb411179574107e4918438b9945459ff836e5ff47254b2fec86cced59b0d8fef3c47f924ddd7303e576bbcec8b986b26ed35fe09f0b0bec7d1ce9c94494f4ff57d86064b23cdd8214375d0f6e362efcda31472c6de853f6ace7f8765659abdf969d4df05b976039336c9753dbbb216e599347664a8be70eb563ad464a16ef963fca77564b794408acee8395135aab684ae4b0ece841303ec8a59f9111550b07b50dc3fd9403854bc4391e125d95d3bff632a76d50e5b7cc34e9474a75d1f4396483c8f1cd3801bef53a6f3584d99077b7dcd364e35bef2bb0b738d863db019cd19967e49ae81adbf3cff5634704fe35b3daee015af3b463885497a844562107a6350672c2e47609ecb47db696d4fe16e54341c0a510ca0293c25f69d027a4b7ccb08c184a68dbb0e8822393ab7b05ef08c4610a0b84c8c4cd5b783e71327d925959782b6c106b08436861a8fb2c1ce2f239f19a73b84966698c52e3c380a7da81b54ab76e62929e6743c88b05457868fff3074f8f085dbb05816c8b4803a7398f1c0f2cb3765e84672b24fa32838f7199a8f738b89334dc6f391125569b12a670cd37caaf00ac919aa4b92bd4da706973681b696b33871441daca919216760b41f5000a7bf782ac33491382b1c423734016cc8ee4b80e6e25be4720ed05439b9dac5fd240193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f2902da9c4a641fc36a1289640a371ab965b25383b7f017834fb4c3c3477910288f8b305031a7b97b69f3eb48780d3558c7c741171815b169e4e9a62a261460ff2caa333150aa2698d243ec55abad0329cf8fca935094c6795489c902303fcca7f257c7d072eaed4a31c9146311b21b09b38326aae0d914c55ab756d7b0cd761510dd12572b912ec79b61fa230e4eb9dd052b29b775d891b7025bc89c0dcaa0a18855988c215c74f06b36976101c0f697cf8db4c0fe25f1c016cd11154f5a5cebdcc4add13b31a63336ae621f2257837b16ff0f6c07eba6fe5b058a42122aa88629014256017bbef582e123365ae37063fa97277b2063d3860d3920beca27638f02807fa3bac4ac08614ad1590bdc6c855f4d3b292982838923251a348cb48753ef773570ab00768341670c21dc7a356931e5b8ab51e8b2615f5689e607953f685aeb6b999815b2cc66c24f65d2ec64e4ee88d4cd830da4c61e15a033e37182731b5b0b506def921bdc19a85624630ba9102226f6c2467c9eb21483bcfc96a22d8493f9ef8b7276378ffc16c3a996f5cf6755d924716524dc85c39d22a8254e74244229c975b467ac94568312333eb578a197f4530ab74514fa174855904c7fd09b2003c3b94bb41c4559b45c00f7a73935ed15a39e47bcd46497141942c3b669642060533ce5ddb0cb4c1369dec82b8d7239637b615a086d4aa87630439d712a55556cdb911734a23779d7c5ddc628d0f326b5502a79da80fcfb3aa8e607fd5c25b8f2768515618538a990df66fe57c5c3b3a354655ae4fc098bcd7a382301d0b721a1e74795ac23ffb8c5493e14c0793cf03063794cb0d340a018461ad89e17ea89b7b88382b9a288bc4b13180db6ee6224fd929b628049c20c1c830504e09651147417b552b6ec810c744210532bb011a93baf28c20512558bc1c4c4a07565779b7fcb260839506e0e0224099c5751a93d6141f90816ea8da87cd1105715a67d0b969d8b748a46831ead199eb4c28b634a82d8b988d2a6d5c797943000d2546957eda9b1573bf534b552f225253d768706c8ad4c42e2688b40965c0dee151be4b7625d92e79fa40fa7c00093148125c65e841cdb86aa90a02099e2c6c4c0bbc95f14fd0734872f2a6d6b3c9b3d0285b7ccbb5b715e913245c14a5aa146f003788d4a76df1037195da2e939cc08f56c3c25405d7d1851249496d33421e5bc386645ff3a8367c3bcfd0542c8962ce146720012087693c60e3a47de4570887473bf9b68c22699afc314afd801a0cda51fe4340e4e34ef18c07a9c7a40190908ac323068c95d59bb04bfc11ac930f99d082d547c99a807c8d112d82f1b81125b41f57a243006b772673efd286b4d24684d2b046b53d7d26b6bbb862d64c42e0e909e813391d6a8289647e91660dc5891479c43769d9608c10763e5a35acb9ab7552a08d167abc9b02d3798115d4c0b6b0782c77bfaea4bc27835b4ae525bb052f6dc04d65074e00207213d612e746a44cb5bb55311c0d4a43d2eb3c2003cf3eb895fda1001bd55484992a384561152779df9534b933244654b2c37b3caa368319235a1da431d958a4dec38da311412606adc0d26022f8a822e4913b8b5e97b6c2525636b586c8b3c62ab4dc73539a028fec33a5704bf95183847361a8143d1c22495ea4a229b4214fc22334b857344c721ac2190b554f7a30479bdbc8854c0f0219b4002a0685119aec442242d15cdde0983f8c9ef2b3aee24ca7ed917b90407d5ad86906c0c865149060b36db1cb1a22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfaa9f015f625356a6bacbb5e565c70184940891589309a571b7166c2ee713b8fbb9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = 0efe44715790e522dd7c57674b14433a78f6ff40d93cb8418bb4eaceefcd5b2f9db4ac2556602b9c21fa8f12123e3784fa5e47cb2b1e59a1df68ab72bb04c1561b9b002081068df5f142a6157afd480835b0231e575b5ef4a06a9502cdd90d0df551482f563a47e435aefef9fa79dd8948cd34751bf8a6dd83db7e70bd00c2f89433a4ce9c3148d160d170c5c720567f7f7c4ec572aed3647744738722b1a7d5a657c031c65b4424c2677527e0eaf5e71ece38d307d5db72d03d2447b2be57b073652ca4a01a0733ec2bb127c6001365ad553b18ac2b0f5f70ee9ff6440cadfa07f1ad4f4e9561e113cdccad1c925855c78502e38b6e6be1af5b08a9ee18dce358fa089032772b0d864f7ec014e4c130cfde4c7b4c36246b14775d4f500e135b2c2126f3a4c971a9d0c26e1221d18c9841bfc5a2159b3918c7445ee24b4124e3eb8b73d96df478fa5e35e8a7c5e8d2823cc1e70e320dcb5b3c1d35f3ce40aaf700b9fad25b289241b2e259c69fa81ba095d2427d686186aa953d91ed8f3d2f5b3fe248ab7b51680192255e09b1d26fcaa9737889c8e21081549ab1bd98e1951674821135f95e84136621bbd6bf40501d71d02e6dcb278aecfd9dbdec9ed6f2e076e61888e63e9c2d4e89f22f2bd6a7c483ecdab4b1630105359bb5da97dbe0cb65c444a90299c4425f2d655a5d6762ddc671d87303ba65e06fab850f391295b041e583c59386d132091e8ed0407e89c97d4c061d87b5df0c2c3a127729c5c1538ccce52dcf845cd1015fdf457e39f3986c2d987384af25823fe56450e348a8035c68c05006c07b6d1f6ae6bde926a84255e769a6fe84a5f5de7a6d7be100bd68048ac892cbec2e16068d1216d0928e34f42420e90cc88c9b0bcd80124676f38da8f5a1cb0ca49fa252bf51584ff49c5b631772d38a2d266f1a383fe97c716dd3959bdd4f3341746dd90c09a07dfad70ce8a3247ff2d22fda1922a8fbc13a776f80fcc119b363de7434f0c44d92dd9de68d1be0fe59f9e288eea89be67be109dffbbf3963c11a36c2d1b25dd186f924a1ddb43338670b52765658837d6ded97d5299081741fe5311371945da0c8d50c3c30b79d111ec1eb1d42643c43a3bee2cb78fd6b682688252556b3e1ec7bdc3903d8f1bc8a4bc243e543043257d5ea5d8db320ae4b5511e51e53d1cffc863e20bffc306159f74cb3d674ab3008fbeded6bc8247911cf4407482aa4c9fce44c8646b79487335f906fb0280731d56cd25979326f941a9eaf669df8177a9c4eb9451aa52d96be299d7cf819d20ca35698affd625abcbc433816f0059a28586b034ed15e151c177df47a69719420df9359bf1534db883d910f31f38c2d048ef84a4bbb13d6dd5b943de1509ba15f2b2bccaf13bd1327dd3e972e8a32a29fbceed5c6ed947f470bc73f0b8937e5de4e32be391061f353f3294ff53c64b18a5f198b72fa9c0c86ab49011838537f8fdd8e651e2b56f9c14eb18d6492736454f322894412331ca0b236b7f84071fc4ca7183335c848036f8898f1a9c9b3df0498f25e41ba498bfcc398d2724c671fb5949558d67716b3b853bd6921e14e3dfe5dc495f0635b28c5ceaec62395f68fedd6946cfb3e723be0d45f7338e0977f1990003701a7c6dec5e470bf5861c7bdedd2c7cf2555cb7a19e606085e1d6a651976d4047ffd181f45c36f047a7378a7c2f7610a4a756bf8f4530a221e9fbee0c70ec490d30b4ae209acca94a8241bfea5c84e2dab5765ca9f9d0d72d99788e60b9e5030b92b930ca94d45225a572fbc7d2f8ae0b27c2b334bd528eeab4e6ea0bb32238939b7850907631577982dba433ca4a717540e54bf56282040e8cc8c59aefe7800a792e2b575d3e413c6e8513f42531187a943e4a64b429b2fe196972f6ea484b6cb84b7bd8908e660dde36931f6013aea9c5ed1b9300369e32c43201db1972075fdf49f6afb94ba8fc81097f2bf4212bef0a1bb559e139b434af763e201b13e938a3c7e30b8515cdbd9720340a53686b02b0b841cb6279415615789cb10bec3b92fc60335e5d05ef77abc905af3c02b31984cff768051ab2b6eb0d286516af882eb89aac29b856d46f2735b57869cf0cac9bce18a1f535fc5f219cb339ae357ad1bb8128abb0b8dbafde98c49316b43c7fd26ca723a4764e3767e6caef79f1bcee92a877d59e1618d099f29f1482be21f9c7a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 31cb44a14c3ff94d758055bf2afabad14a723c048d4e2dc5908bb781844d574a96a18d7c59e5e92548a0089396a78b953ab5f677b9a111dbd12954b67467ec5d0c7c5e6488d4a8f90f7665f403febb8ff8aeefa7254e3798ec3261a9d1215663b3cf63617ef55817dbd16f61bbab86b4f96056a498bf37b1b94f38c5099ec9feaf435ec0862b861f334eee85af8d364a54f6bad0e44a24ad577933ca858f889a955086ea3a2c94b058cec20d64dcd7df976126854bdef3cd386a855caa3869f73198f5494861079ac84606ac0f28e0eb78a8398740be69cfa1777c61a5cc1d758ae29cd72e6d87c379a567648558ac8a1883734c64361db33cdd156fd47ea2abe534b26fc6e346e43b944dc33d9aad1d6525d6586793a2b45fd358185fc787c2cee3875e44f5be66f7c1d493144e3ee498b17e9cf95908b718b3c4a7ed3024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd15ffae2569fc389d2ac9dbd2c236f4da66d794dea61765a77e43acf9ee02c735574ace463b55f11ef6727086d74ae800924c6b0eab6ed9d5d5c0eadc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67dcfdb38bab1a8e8ecbe2fa5ea8c7588ae3bf8eb8a37e5949084c26b4433741a31c60fa4c51f535fc6a1c61dd057c651040f7f7808eedfc4a8843c59f8563bebeae5da543be2146a3eb7b5228dd958cbfa5064923246e93da8ebd2ef920e0db1cfd5d4e32495dccee6c5bb7aa21b6cec5c9fc1beab7343d544e7af5cbeceb8ce59e45d9939dd332c05ebdd2456076e7dcec688f117bfeecf7dc5b8b4884446861b592c8fdb530bf4cf08513f66c3b51833e51b9a64ef97054a8c03f8baa257c64c2c8a265a8a9215fc41146bdb3a32ce0b7196aa335658d6dac33ac06af0179cfa0dbd4000d484f13f5c9d16956eadaf88f68bb72b7bc7cef2a486cc1fcdebd40f7aa316c6d8ceae7d8b9a747443c5e7f37989a93ed939d905832e76afaf4e72d507d689e54f7b5cbabb536e603e6b3d38911513b400ad83f8bfa3c72a6c09ea3b4f78e29fdf85fb99442ff6e237e6e757afad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea59211f8356c369878855127cf2f1ab66a3a4c20299fc8863b609f7926175cf1e3967ea93b7ade7a8e67796730f3dd5e8ebd4d9345af36a38ebe7e96b8d85b7c0beb586aefc9fd9ebc586fd71c1b9c350bff83b6d884a0cc5eb3ed887aa677d34e92db582f16ee7fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e951db4ca99a4a98db48053878a45340e0d56041d68a74ee3be4b51a74dd16875541e099935ea92b2668ae84c5a183cbbfee6e96a1d38973cc07c7fadb803cbe26986c827ac764f8cf183cd5fe7c9c719378448d58f57db62fa977dd658f219983f97b517cbeaee0ea479ae8dbb89ac1c9e6419a3b25f388c277ce90b866356ec84c34bf9032f86c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c8bf4747e9f4e2b5c4ab8a4fc27fa132439e0e3af23aebeae17ba4cf39a1569f5c62a4c9ca764364966479d6630b9349a335a495fc01c0e8f77eae5a4a47efb74a64fb8d3b5d692774fb16e3ab78d13894104882ac8d3db1de5b91df1ec0f9fda29eedb38370c2c4d0f1c9d76d776cf4750bcdde16263b65548cb5113e74858d225d85f365adee3fe8e0c2ae9203c9145bcac3f175acd09f7d42b9cb6d987b9698167d775c04a877a56de48df4866bba35657f7eb3afddb68688a9f62404884a138b20b1aa21b8dd3e35a79422c35ac47d59e69e6508d5af26a4a8b3aa0a0a3ee0828ff357e51617cfc86b6a836a9f79bddd195449a1ffee490076a5fda3f044a75e844ae996b7c612fb2e0acd9920cd9a17cf9686c7c20fa5395dda7389fd29597e9643f81436bd55f3936ebccebfcbc5f4105b32ea37e4b3ff3699e9eb6fd7e0c07b6e8eff9e4c5eb3bb9586bda9e90383f959bdc9777a2d843ec7e777021ab9da0a45a14b8b88ac78426fe9bb604820a2f3787de9f546372500d9c71caa35dbc67f76eae04e5b3fcabed5a1e9bc65d6fededed6c574880fa8920c54a3204c61d7e7e47676692dace4b58f36009a85ddfe2f7d9447aaa52acc65d25879df1312d41f14b53ea0fcb973ead32cdf833463ef73eed9a0ce2d09faff9ce3a06030b3021cf4360f3e4cf93528bdbe69d0655171ba7b6d93cc220a10d37e828e54629c6239ee13c0a73e58f0ab6632e764a840753393b206c180b3c333275db3f05516fde08803f7bcc10589f8f54793f732cbfe82658033694e6aa74823b92cb616433072d405e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb56292bb1d796bebb5c400f30098591447191a7ce6a3b2cc3fc7ab7b5c6ca02c6808be45671012867812c2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd6734736907dd3a9e60e4637e2ab768e9558339921d8c1a8218926815cacca840224052d574164a4661afd903d4516e43e3984b31554e5b666a9cbd332a9e6c63036d34189616cdb3d100331bba659649ef0abb86502fa994b941f9a354231110b8080db75c69ec6ffcba48642b0ef54479dd7995f7f9ba92f8b473cc7e31d04948648af330aa09996e868c75bc3949bc3bc8e5923df68b5dd78bafd3318ae4fa6224b8a7dc9814f7b35839b05cb709cb1cf2c1e80aa879c58b29677cda375a5e4229bc8431d48bb08af0bc27f982a6723e60b00df6e607665b7a4b4cb35e5162ba3698b7140ae7a25a3ea76db07626afc773854038b3d13654b7cf0a1a8e75959e5ea0797ef4a64538c19f0028dcb5cdb5803815467e57aca68fe00c3352602897aa88021203a4b970ebcca77846e5c01adb22859e41cdbfa8a7be9b932aa2c6d391379a035455d84282d5ab90d5b6de056f211cc6af61c1d5b643f8d299c249c055964c56906f88778a4600bd054850a9d92557ab2c33dca2eb2857b9617018ab08f25493b265b10ce74889d8cafec53f7b6805bfd637a6b6ade8a65d7f885c3af645cf08bae250753eac8e2b734a75976ac9eb8d2633a980285ec33b154c1551162c81f0254d2eb55a7db13f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d0609e5b36b8b7e097d40ccaccf496f3f00fb957162445025ed62592fb61d41a28b16a1f3a3cc83b1b173e9599e5c49a41b93169dbc4fd006a93bb233ef73df88116e091b17a06125f651f52d501dc86a856a96a43601c46f32b1fd6900a6513f7d298851b443242c62b34236c7495881cc3fa592ebd4397d5422f3c40ca62980188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3caeb0a980d13de0f3129e151c0813b259d53efa07681048888dbc082adc4dd324a028d48fe728701398ce20425bcc9b410687363ad771218285617a39f3c7bfbb2a6c006125d6fa6df88898f7b236f7581a8a077038a06394782ce7862185f4ce98ac06c25b611da7701a80329228391da903607793bc8a2189a123c177af9d987ae9d1c6d2d01bc5910f56514532d582ca092939119444b3b736abc0fb5140e14c723b1c6abc2034929a7edd48ce3d469b16b09cbba5008728baabd54d15f427d2eb5e890a5a13224038328fcb227baf6a7ea3b82aac5844d809ad86b6adca537c2c0b4e0d659606f835129905a6760cfd68b5697b9a8ec00159450205cbcfc0f8c9fb8898f135298ee99a154977fae7bae16ab9325231178a764c1b10b5c427598490cd9539b69b1848980d09768c435233f52376371b7971d861c8612ecd160655e83ba1e60a553b4905d35efa1bbf58318d78353da822241a354b439b2449a2825d43212be80483c167e6c5b50883412571cd2ac3c1b5aa1ec9c232e6b9b5a2091e189b3ab0b323ff13654bc60ed42857755902d063619ab98fd8790d05d85bef1ab23a09a9c241a3cdea620b6c338eb582dbdca9a6ac40fef7615091445a93b8fc2001e09816ffd54f7870b5ce6a4fbd46c3f42b8e63619b7675716bb65eab17299b57c45c834226dcc6c1f98593782c9733a078db34a137c5422cc1dd87a614c1604972559937102ae60337d997caa06b0f33c43b093af04595e5ab48a7a0966ff318a735024f004d6f1893b48b74b42135c43425c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a230cdc1249b09833be95c5f46bc5905b73a82206bd6658464659293691eb58551973121a42385ae81ac9ea2eb6419a915441f41946e504a6b9d5716e909bdc49337909282c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1655d6f749b0a013bec99e017f5e13bff76680a2f9386f2ac6938d7950d5fa1f9f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = 76a8aaf524ed637534be4d3ac319a56d11f27da6220746b43136c9222548c8015f12394c5222412b1806c7cad8b4940658d1519bc2f4c6880798992cb3334e607fcaa0344328bedee7091854ed2fe4332abed021d113833f6a63048a74ed630779914cf1a54a90f95e3d32b3a8fbb2f7242f7b55a688778c10fdfce2e74a3adce25266a9017aa799a79c5861fd63a03ea009985961bbb7d0458fc6a2cf56a64a8741ea85cd56501f6fb2762243c788fbe46fc963526d7060787f111159ea1145c107696491c3c838a8b0e3fc9b820a349962416c4756969ebb82279596b43a152bb8a96d880f6f187e5b8a6a2bd2b987f82401516c0b199ddcc49e7d609b2cb4fa8656b3189efd325b04c3b6c7b257d2e56087cab0fc74230dc7c440550879d221e066ad553dc84f3b77c25c1601f67aae9f2740e5040efb324fe3b86e6e9c558c9ab9ec0b22fd838a92da19ac3598324297c98a5461c9ef76a3f92f6c83b99cb842585ae68adbdc1cb99111ed0c19393f65c2b01f6a504755a671e40b0c336396aa8111acf71dbbca1e3ca4f901634a88ccfdc88eb790d15e66f1441fd4cbafa6f04841a809c3cbf26677f422a15c2d93d361530dd6a22391660e8c6619655fcdcff7c82192cde31070fde0ab9a027388ef188b13449d44b7ec9f684404f38d9b58fee9c1ac8703fb5a88f09b63b2e3ff4d5c6c7968c5de612453e42e490426bc8259b040c7c942bbf63a68c440ef7cee3687da84ffcbac763fc67946d4438c0ef229eb2433d848bdc469295be7b09d5b1daba8576f2502261361b4d9d206912d29d6f7d6b52f2872b71e5a0c6aebba71f89b603c81f1a5241a901b21ce2e88f44982aa3612ddbfb54ccc5536a5ad82f9ae5519bf4b2b90530e0887609577145df92481bd786e09352d6b3e5c856378324beee6fefbfd62ebd43de27666d17c9f2b668f20937b75276bde8d2763077662dda3d09cbeba14cf05e138cb8386011a7b506c08d12ccf4781172431b6dc70aa723fd80e3cb87ee0fad2b2211ae0b046753a7e7eae4dda7bb689104f5264bbe2fd1d99206e8004e8f658f3807d6939759eb85cadce7272723675d1c41cb7e5476a15f238f7a59cff42a7bd39d4374f9a74d63cdace08d74f12739ca73aa8ec8da29832611a891f7ba94877c493326024a8cf0bd83c8e29bfa48df9ce2c227387ed730046bd9c30fd3bac87d0cdd03c5f516ba20a07221d5a2290d7fbccb7fa9ce69d228fe52393c3ad9e0db134ca5cc085ba08ed902cd1e17319936791b8b0281fc1b219e8fef1a4b0e7e7328a7612a99f392ea5495a8a850e4059ff6d99984cfa95996e52a6e7809692f807963f591ce1543ca2ec33ed51dc457f7494fb7b641aa65447a9423cbeee9acde902ae6e8587f9690a67fad158905ad6eb4b86c435ac36914e0ba75d8039caf6ff4d5b9fb718145f95e173a0f074df2efa88804201f928be5b7772d5aa3ce8e48e4474a872a7a602f5e8743f8fdc1757240c1f180a24529b1cdc4d57a23afa8557119351df6f08e64ed1e84498c34a2dfdacd75de045a9ce6510e93fa4ed22735a16a7e2d1f4fe7bc0a22512dbe45ae055666214b6a61b495fcea2ac2380dd7849fbeb227583edbbe2939f63e141fca36b0e2a03c08927ed4c72631f8b35ec8ffb5ee7d3c5b3411af5d4f8b5a713709b53d8685d6930033af0eddfcfd20c3c85978432b8c1efb116945b0cd2998005b346b516602dfc17fb5b7d148512f8f074405292d3211d2d7eeadd046232b1056a8e8455e4c74dd990402b7164c511f8099dcf4acc56ff320762baa4ab6b0641384b153d94f119328f2bbd09731643700f9c2702eb83831154f1df082fc872230360d3819214a629af48be4ae80cae16465e4e0970c37bb432feda83bce8c1d89d772cf8b1fc2d5315cfb62b9f264c34fef2635cb1da048e22207bc84e5d81980efedc994c184efbd9fcc05120cdf8046cf15a3f27181872376f4c3e5868cb96518a0b0676f16ef277fa153b9e05688bd8db52496ef64a8af467ed46813108037482816d581f7624619e9d77c1c43dcb5a0579d2958d427d020e098a4e8714ada6c77428f0746d6cdd0e5a55aaba012cb8880b1e8af0fc7a8bd79e332c26c6742538ec997cc9775003198b0dfd2da89870c20e136f380d76d90aa2ec27f8cfd12a58c233b748fc4cc8cf1ccd58d5cd428a8395eccc +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f3ce0c7ee97927c89e67d88c4a6dc46b767e38ef9fe78c7cae38717e6a2a70ce7dcce582ac697e99e5c9038ea0a784c4b75345a23e61bc6a586166d4385b507748d3ba5e6b10550f05782126ce0f386eaea2c631afa83871cd03a5db891d96ae82e317b29ff21b5df2b2caf4908e27789dc2addf216759b005692ccab42829f7a46739ff7a9583e9a5eb9b6f314e4967f5bb375fb627e5a45b918c801b4b1dbcf4d56ce3aa7fc5cfd1d4647295650b5cadcbcfc74aaac28c8f233f64c1d0eab51fe6213154d041fc5aedf5af449cfddf494056dd0a01c449e1d84c886e63c83c1342eb1f6f87757ece86d4c30cf9e6240e538f196936ab9bb429d93fd593409f3a3098f7ada1dfe5b7fefb1387ac06b442a7dcda9d7f0ad9d49d0fec3088d6e9f09f1a0ddcc52b9517c685c36c45801875dbce490163c91c707755cc8701bfd4deb9aa0ce56df24d7fe5e9eec4edcf97abcc4c9ba304c75812196409c19be10c494a9be38a7fd5fb5558e7f2cbf6f1694e7e4e7f73781205b941eaa3ecd09ed71e998f9a8b6b734d0a048a77ce4ad17fbf65313303cc86150d477e42a39cb4b8c5a47f3d03550f4b76d5fb7b524fcf658d374a8c955b0fb3fe888d72eccd202bf328b737f9f19bca95eef35a8d890e7ee7bd9707d9e7545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cecd5fffe47fde6f5d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22f8ecbe9cbd175afb526b6ba074e456a3cc941569124557d3bc652dd8f59ac66552ebdae06cbaedd19ec269cfc6f4bc7e948329778cf48c3b37f9a3ed714c5c9fdd99036514daad5273eb256fb7e7f7c91ea13e1b8db8721e5d01af9d9922eec5873499bcaf0aadd8a135abeaa544706dabf7338497c578085eebdcf9e55f884e7b2a3e3dd39505cd9dc46defc324b5d5b0defb2656d596d77257f5485465e33a6a64ebff0422cd38f0a625254ad127ac941fbf3362649d2049f8ae8c0584feaeeaa31e0e98fe3da74d53938f409d1b6a33f1305a383dce2b35894ad4982939579511edcf8aef174373968cf94bb89a9043ec828048e3fa862fadc95294df5e2f66dcb2de04be8b9f286c198b8c9f1ff4c79a454e8ecd742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc0935efa288dec0da59d9cefb17179321df3b822a3395466dac34384a364d0698f592734f72bbdd2de7e31196afd4da54fc68d1d869f8d06ebb267f74c98479ee1cff65fb985f6c669d948fac15315863d84a4eef0bd5eae72bb8c23ab5fed55e793a4e8489b423044a1c0e7273a4be35b3d5e19934b99b45dd2734ad4cb4c5b368c7b3f65003d7b7148c199a44bcc3a2984f9ccb7de5e916f04d8f7cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648b5fbb94dfe32098c26e9a51a6571cacf90015f65b6359f07598b10c7674f5356b0365ceacbb55b2ae8239eec92c44f0e4bbda5ae3364749c5384ca777dacce69bc48b6a0b1bfbae8ac5cc40aca6def4957167cc1ff4dd0caa3a12f8c13934fbcbdc205f53d713aa441f5b0ffcdefbe0d8209296cc096645da876ba6eb0ef736996d95766cadd9f89a4a9ba5d8f3eafa05f74befd93e50e69c9b94b0958ab9a585645eae58b6e76c8cbe9679fbf52b8e58d7c9c2cc693751645105dbaa88df2c748c19e68cb9bec6c1168d6a30552ec34fd82bd36d94dc3d1a9bc15ba4434e4e76418686546cc38f35cef0ee3689850b6bc3f7a3a544ecadba819e53d4c3a21f7fa2aacd9845cc07e0ce3831f36538f6efe0f67f5c9481d8c5b0747d015d593b28f8dee3aa6f55b31525b9ea8c977284dba326bd72fafe1ab1d4bab5e6e805f8202c5b0f6f8a4965332ec8eeecc9a9e4b85bf9d0cbca769d93916c4992a338dc385c938ddcfc5d805d95525d59603f8d51b07d149698629267b2f29bb93f769b3c3b5540fdddf07fcb788e1b3acf76623c98197cb528b9f90e470dbb378ae9750f24d5c1165ee6a6f709a266e6717760ee6d7db4741468a81aebc72abf9d80c4f8b5844b646855f01f9893797d2a6894e24969fd605b2621f9bc0a567389acec89bdf15acb118a7e8115556cbd99a32a8b2861c097612cdb6f437e844b131e016f3299c31185123951b2901c5fb8296762292d6b37f5bdb67000d91974c77adda0e8601a03432c648848e38e45d8b9a45d8263e64d603e0f50d3f438acc29ccbe54bf6cdb0500b50344a96837828bc568cebaf055f070737f4771c8b4cb87230afbe824d6312ed22ca5e2d4c5dc354d44935ca64aabc5a64186e51697b9444a50569861404bd7a9b76898a3626edbfac8a806751d328bc393b83525514c56b7727110f802cc41bb9c43666b25e26987cc813fb7193954a0258c61b4e13f2da32ce3f1c030bc0081060a7e091929cbb729584a888a06610489f3312bd576666fa09013f4a191b498b9637df5ac5610103de4734c7e82c99062c34063b01fe2210d0bba1a15406836275aa119042b5072e77523a655f41316b3dc31f39840446886af337d2ea0c532999635786d9a6948164c361877891ad903a0c725289c4c02f81ed3452858d93489a07ea071847c38780c86c6de1c22f1db704a2249c6a96695ab22b9868d639ca4a8346ae0845aa8ba151e14941bf447b2701cb715456cb91b927c63f829c562628e01f88499a60aa69a0f3ef410ebb2698889711891b008c0b11a98c47e291b763039e5a214d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a654d0b13d23b8ac2869b4062ba3a27af9f4468a216789b92bdcc8ac7ff2b86b134606a693a1915c55421e8260a872f57a73047f496442d7b1cf44830a8cc01b27b54f495cb984e732c4a40f99a17c5f469f311b6bff9c582f888910da60e6211c788c2ff2ac489f1163826b672e6abfefd917184b3f66d72deaf652e6a596ebf5248a2809c3187c4a3834f220c28f55b589e161479882aac21407e56d4c541282b1b330a7681db50bf30463168733faa52cecb1a8c2d51724b7afe1976e42ab7fefb1c234da45aafb803e80c972559694548ee98ba2c818010ca940f41429a8222b8739c872b1afca093faab792c3e965e7b0bd8850be2498286ed9b8c9a6987577b98ec4a7835cae03b28ae9130ac40c5af971738e423f7f905a223a6c27752bfaf4c495874d0a984187631f50b8aa87ea806e78a1c18c78040548443587486171a11288d4d2a7d19b809ec8c5116575f3c47a1b419529112417a15cda9a0fab5b7968a0937b4c443dfa3d0cc893d4bab60bda28da5a7a7fe6394f6b1dbb207b5abb9b0157a029063ededa1d0f162bc536cda44b598396772e4a3173ab4a22cb91e4b165a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee7923c64baaefcb99bf37195ea6b657d442097289db24568d970ce526c11f507cd7bdc3facc879893c33d35b734fb9928f82867c5266dc1199ee679ac2c337c35c435f90c8ebd0aa29e22a169bc36d605d5a2cb1eb914534f5b3d89a769d806dd87b0d32c63d0225cac6aa1b8c3b7d9258ca68cb8086b673322716389876d85c71d2f5bd3d081d812ab37d026a34324135e5988fea7833973d3b25ad2b8777f3f8691b5671d05b266b61c272076ed0d23604ec7a670c634a7074e889c030026a1b29c4b025c59d43029be2c2a2665dc2f1423c063e1b78b79b550db2281c3bc88dced5345882b30ddc400a62bd35c52bfb063213947b89a91df0fc0f34f53555853a8724a9d15a00b285abfdb39e97b5aaafb429042aaec4d21303f1217a3c0ac7d249a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d650bebc225fcbc132936c9741b496d1c95d8318b6b9b9a71c071f7af5547f895fc4e313e3a262d31695b9471dd8f50f6e227c7774260d60ad56ac7608430f1c370cb917adc3b7717b484b52158740740366a42d9f010c333611e0d29523b04618895cd91a21629146bf1870ed2584ee8c0a728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba0b0687d39094e034399973e2d09116b225f2d41a86b61936743806e41a242b63aa19532f19c5fcf0204329537e996a08bf52acf80c39ce1938fb581543cc77146cd34a5223af8bffe735fb327c888208b5dd648d41ca209f976f6f226f853545a525f3dfb258c8074ef9a442c639a38459fd906a8982a69e29608da98b4c4a59eb6ec04382cc584e663f5751f6aa0486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb91c3c2aed0ff6944819c93f9a9fe77d14a16a385f644de118099fd4f7f57db9a0a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = aae6b8e3eb42edf187f787864affaa3e657383ed66e1d6c71386437f74b297ff2cb4884f17c32ab05efa09d27f3a3bf26076f79be7dde0f24f2f2c9229a8f10033f15ab8424bbd1c11e19202ed71af921842a338325c8997e1b9ba892ab8eb4c060dc28ee5ac28a047054d3ef96514d75aab341618ef99abaaedc22071c25728e1e19ba78298df96e51010f32ed5fce1bea80fa7b1bce6ab21a8cf80c478fd9f83222d29199ac57177aa549442a620687ed3e0f349c1930c7b5f3308b9b99ee8dce261d3e430b5e224ddd31d810c28247a2ceac2d858db34353cf7edda521bb7d50468feb2dbf07c4ae5f31d6b686905269321a7a7ed721a0d943779494be59440c0d1d8c288a6ea1ba07b44cdedfd9b98ff60648cca5b0000b11c1a1a7a005e5ad5cada8a1411c998c96d583757e8d2c50986165e1e9cd1b73c1432a79a25809de5843360eb9064775cec0a8578cced7ff6e5c7a9c653533e1f302b778c9933d6385857c0a5069c176d174a2b9ab7adb7deecfad589e67926806fbf567b834fe907193733d2e00a084331ec185bad1c85fd6b132f3a469ecd97c0d88ad87d0f864738100517f8aa407009d6fe14e597ce9fbe6963573105f1648e7cd42532b70fa0f499ceffc9fc7a3ce33136cad449bf81785a0f7002cf724710269dac94348be7a722eaf9b51b0b81e9f6d9ff3fc7e4b2a5bff66f35692c1badd5c9c7c3bf3444e188ea589ee69ce5c3e397bf29abeb71f7bd2df6aec7b3f60aceba3be1edd3c222f1aa2c6c415926383eac51a9e15b98478f12b7c69e4e372b0d443a90ea5f374797566acb58b84732ed7321f1c91f4383301da30fbdb44ab7b967d72f502ccfb46d81dc5746fcae3f6de14cc63601c87eca9dc7a9b9a406ae604d30e38536d7271c9d1b2512a8e1d0fc9cd9ac0ed24ba41cbb7cac9b099dd9d9a0b85b41363e19795e868b49f05557d0b49650f0c950a046c57917915f3a238bf49f5859f5e35087bc656987fc4600e6db90e3cc2e9cd4cf97df005c5f517635b92412d43477f3c633e51797d084d6286c5cac768d22a6229a8905b51157e536edbbc6b4477066463e44e21a31b8b9888168a460b1f80d57252bf8c145535a162270cfbfee98009a0f4d6e8ddb953c468ad14f7855fcc73d593f572e1796243d029559b26067de9db571b8d9090d49342aad33c23a5c83dc2205256fc1efbfac5b78fc39de344b1fb600001deaa75856cbb22d9555a381906c598e44a8e43d869972c243a444c559342d3ef6a9448576bf7e9429d407465c3513d2525510ffaea7923f066bb16d105573351ac0289975debc39bd43a49758b003919db44313910ceafc4e5196cb664b8e751b82110c14e5cd268ccdd393da65c25a6af61f1c509cdfed0df06bac8aba62c8fbbd69a45ce0f4c79203b543deb8d98b4a3e74d0f8c0b71056963faeb0e33ffecba17936196153fd11cb2bf121b6a80aaaa21e16cdbb4a70e1c1c6b2b3d4d1d9a5568733be1ee64ab7a95fdffd8d3ddf944692b1f3c092fe65e67ab40a58ecedd6e869b0be37bb69c93e8459f338af18a043fbe9b34217b2c0756b08ca505a5e513a2a07b12ef71821c1cfee1c4e61bdefb849f57aa9bb9743f06310780ea951bf2824575a7cab3d0edb7da713d68cf3eb3f9b3483a5a5321f07d3fd6918e258838f0f921080ae13601e123f854fabc15d7ee2cc33dcfb07b0f1236f6f7157306ac2b59a00136a2e1d8af72676eb959650ca42e46ffadbc1401928138bd65b45bc3e67ea59ede671bab9cd3eb856389303f2f34903c22309afed76ff0ecb9d2ca6b6251eb9bd2cd7a17dfe5b50f8acb1f3f99f3001282623bdebf20a91a4944538460b15d2c5896e8dad33cd1c9f5a0e2f567d564eabed3b6e577a2b03b8695e238d9a08ea06fc48e5a906947880cc343b6b2189886a7b88db45012815881631dcddf43ac5862283ecc8b798c4ee4c7aa56bb7dcb158bd1ec7a0c38f2df1524282939a58472f056d58dc38f7588386aa04940394fddd34ae12f3aadd564a55f8a5d7fd4bef9ad78c57f83e70cdcf284dabfa8122f10e95739586154a0e8916c80059d76df5f5b25a745af49d6cd52974fcaf65c938af7d8da7a14fca12530a1ec7b7bcc5083b4a7ac2508e8a368df0fb7b47c678414842d4e4b4b94dd4ba6c4cd7db0f5dbee9943f5b89fadd73a0ace826f58d2d6ba5b57795 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c46454fcbe0879fad6dcb733496ffa71171eecaead7377eac75927fdb45c903563fa5a48c18f3343e7fb3a0a8aeda9c75f647648a92fbb8fcc59a3ed476fe958cdf968433b46ea296056a8460eecdb7d4430253bf27cc38c8dfa639b7f759de9325d3bbbdb1a5305e546591ef7b11332bb6662379f4ff2fe3105176b81a777ebc946bd4b962f8d50c008dce026a513f7c9c753d8f8336a9bc73bcabc8353bae0afb69aa60fb3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be54fbf226fdda987c612d30770555c0bc62b25ff367b95a91399642155cd1be7dbb848b642c765feaf400358040d4cd154a68db46f65bc5f5fd9d9890ddc04cfdb66ded52bc2e6d6183b444cc385bb8ae17388d5f9df4ab4e563653b5f72899cc16b37d74ff6ff7385f557c941571a1c73bda4f5fef3c343ed9b88cedfa9be5652736ae69949e43b5c9719c4b8f4fc9072ce0e3d454b3d9dd315c93579cb106a3b16bab7163983f5d5e4b8195e6bbb8d2b70be266679ee03c4c41ebcffc73f2dc6ea79899f7dd83b48c24bfe82a4fb2adef71efc39d5eefa65c43d57cd2c79849e7745bee15b70f4d593abd55c2a76fe21fee094b4672af90f5e7d8ecfdb1155b94fee9b34cd9858d3a8dd4ccf7f50cd728ffa80d6681c123f4ecb7463964db73af3083c3758dbf9ad40c979c4f679e1436fc56b3a8eee15147d15e3afaf9a8bef038b6905c8848ce6558cafbc6ea92ae9db0272f8695d664721ce5e77d8b0944d6486da745ea4a5587ba2123e2c82d3005f838a2d5b7bb09b8dc7aa39d4956d49447307ea268a9eca907aad08d48fc98c095798d0fad43c42c437f6762ed3678b6e7d1571de6f405cad77ee7c786b56b3a88fb5968c26869f74af228cef9554bf20f67cae75b5434bf9259553ab4375a0aa6766b2aa0ad58db6979f01fefecceada39f8b8f576ee2575d65d9df6dbc1a57426af9fe0a606bb8f6ffe45a69493b09cee712e88a2b5bd371db5c0fdde25e2659ed18f75d28f77bacdca51797d46cafe91951737868483a418427733fef637b4aa9496c30fecab67b0b7278a76da2eaf01874711e79f8b7b4de7859378c867b9bb8e529656200584ea9a5881b657b68a8def8dbf01338ac1b856c4ec5b0c48a80bcd6676c0ca625fd5296e59155d5587c3cf0c0aebef20d5bbe9840dc2d5d9658935a67614595bb3fe48e52877fc5ba639e0f3f54d534c58cb90a0a98bd2cfe9ea4dfdd7ee93d4753d17463d7eb8c9c6575e0f6845b6cda5bc69c60ade28e3d78960671394b75c5d7feaf0cef8ef4afdb395ffe4da2f6bc75fb9b79e1d8756705b711bdbac1dbb4ad4eff003e74569d739c08bb25cc9ec62caf1236e76c26eecf6faedec392a369eec2ac80e92571c24e7be7e8fb2faae990e5ddab78c1dee631304ab5ac67f74846a8fdc6547c2f4c73ed781b233ff8a6c876eca3a4ed60a00b560f76e042e85340c4a8257660c069fa429c7b81c5e37e5edb559f864e156dad39fdabf590350bdf02247e6c6847cfd86b6958c74209a8f399d41e5389ebf5b9b633b7fdcd8cfe14ba466a36777830d94db5fa9b72354d307496e985ed593d7fc3d64d5bc385f55e239258b47d792d56f106a4f9a493b584909016d61cd98ea65a8c131b6ad696b993a66ecf2c32ae2ae2e24c83c7b696edfa64b69b71ea8ad2a95d97d25bbb210be576df50d64a9c87598ae13cddbb7bcabefcb48266b483aa5311efa734a8519449bcff963c4d1d340f04ff2dc883dace5d744a9bc3de752383b6ca4d9e29b331e88cf7a21e89c41cb8ab28ff82b9f0bd7c9ebf785b09b5be338e3e8d1f8139356f4e6db2cf5c80bfb6d9ba0f6a1846ddbdfa75d49755dbfa421ea4d7e07fe8333331e99e7955a551a7f962b8e7be6cd43a8a3531840647127ef05b5a71e238b911fafb536c861c1fd8b654a1fcecdb77e5429389f95354ccf6e93d42dff3395f451c8b44b26ef8612db4093988fc23c533fb83c61d720a278e75fbd47a86ad2664f25ddd445d7b95858736736ffe3b18c9bc74ac2f536b5e6bbe6c2af50f6de83c16bd79a970bba86693cc5080a4d91f2d76010d9d3893b6ad9643382dbac145b6e0f7b1cab23a3379caf84ab285e12ebdb602f431a82e0b098ea1a1f18b18411989cb1b035d0726865712f5cc1e6b51674887b0e00c2eb067731dc8419e64b816955b407a1a813666d73b53d7955639a877a961b4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a391bc55b30dccf33dc1a93b9b784c7c3429ce8684e1910800739839bcb926374932a7241267835caa9131818ef9aa4ef5c1a3e2f03bfc83076d8a827c082f0d0c2ff89a8fc2e62a96396dd411259d26c7b9c84bd38c557fa45103f3b793097ef6b775f050033109ac7c606e2cb05497c9c596639a63171f5e70775de9c545b919b9e199f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a203825297864ef536cf578c277b6541083168d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b7a018e3e5cc8c581198e2b4b372002eb756bc7a65a4d67c86ab022f549bb97904e035173ae9c1073a9d23a315d054cf0e3ba27d401bb04569065256be9447a06caedd97871b52624f43916d475c7539bbbbfab35c0864c8c77b12242797323bb12935bf5a08c2ea4d446305a7345de980a03067513f6402e14b29e7287e30194dd76856ed80c55bd65849c1135d398994007b1f14a452e36bbe7283ca7b3ed1b67d0fc3667387c9b3c3cd8314515cd2c4e51b96a8d43a1c755c65740ba9830f65356290953b9dbb03600b18f4681f6f039379f26d40f2c8cab57378b66aa245197cea225eb9b712c95c4bba470b07bc6c458aad71bce067b0991036f5f54636248c516c88eae013232c0191257cd0a6322704c9a6d005fc80c6c6ba0636e701bc5847c091045bab969ab85f5644a5f8f43858c94b276201a7e77aa5c413c57b40726302559762ec40178199526ae63279fb510c8917ab40c1b1bb15dddb6d1c2b22520780f222c15ab2a16bfa28753a61a949aaea6abc3e3083a467110334a959fa582261561d3c8fa671ad34b8b7ff2b682020651935cab1b227d75261e3c98930961457a955275734d9f41c61069e1a5569d38a1a1ca1876e481d94851e62918fbd550e45fbb79a7130643bc1fea1c722675398498c6874ab1a7997008a166c9146882c37e4eb64c3e306d2b2b4c1409a81da2122a5360430774fa56c5a3520a7e870aafb55773124d93b17451c01c7e21be33a9de7a500fef26c7117c13599024ebab75ba9710c5465a089375b2a751f5c3eba8151bda4182ff3280826c3190b9b11b89bf9d151c4a939510007378895f916bbb8e107031459e27c9ee698a269425ebf5a484812271ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd82c10c997ace9e09f77cb9fc4f8c13b25a8a12c52c7729f22a3290140c7ad0480c00a175db293cea64d422baf4bd306c5d446d48b062f751f47891a8fa82b9786148c364e4dd85507c07a9b4448e57c2795554b3cf53d5d14ad3179669862123840a7aeb57240d69ecadbb48521c196dca4705671b1e566fe59b08cb963f417abd01a1915a33367508cfa9c89413b7709eb48e9bc2e809a56b027b6dd3a513a2428466c29b6ac802f9a83536ba1adfb96270c57a0743c12733525311e8fd04e12c52f15468e84c6af54d8bae8214c152c56082465b79a6cead444aa767571cb1351e4cc05a8a75057c5745abb125a5382cb8a3ea2170c104ca21cb5da000002b7231a8a0a23e50d173485c7d1cda9e8c1da913161e34fe0a986ed5c1183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d21f170569165ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93b506a8554738e522e11bb3b7976f9ab17ce8a190b0cc810258972a10283c21b9fa36384ae0be5556aa252a59c1aa7617b480729c0272576dfb0c6108db290a0cafb8588f6db8b933970ebca0933c9382acab4dc0c75c4e9a469ad60c86d7474440b870e7958b600b6a3b48cb13c938652198c183347358cccb4d45ab3a4fd7c7730470c2218726157f89facc31b6449fd6b4666081572ca291ba6e3657165b053c6a239876ca5eaa0bc659b0b1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc5d006ca6586818664ea6108bf0080966ba83c77aed8fb2066c94458e70a90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10357d61586f671648188f070899d2eb3408158adf5e8056ef37ab6d8817cd8275e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 722ee373d0ab7b12bfdc068bde1e6e3e25205e049621e8715b003682dbe090de85e0277a44abd1ef864542e911768d2ab3e948e72a24190d55becca0b3475960528494ad8f1990486d1cd627dd9015096b7141650267bb5448be49261cbc0cdb5139db934566e5ec5c4930e9412f2070fc1b4d960435797f21f4c72a44af123bab47134010217ac3a6b754873a1509d76f8412a69eb76e44b958f40cf00ebfd63a81fc72aa8408ecf238425009cd4abe2f71f18b99c4149c5575f758623c843cb965b827f71e0d086ee564ed710a6d7c747d11ca6448415846b8607b2feb8919c635d57d7e8ff5c3fc483fa28eb2b70874ca6e0ce4254c20b3b77893fae5149adfd7da1d04e5eb7ff0434dcefbe2abd245c9b01dbb710e86e69b649e68bd15fd7c9cea94630958b8a275c1d9062b311155406d7fbf1f9ad2060ab91bd9c0e73a3309d2485bc98b18b0516925671dd40102fced9412598b2519cc18580401b68f6ea472302fec5a0b532781a6ef538dfecee2b3834ea9ce02c57f82fa473b50dae41f38bda763d833c60a5e89bf630975c40fc91ffc02faedbd982f3c092c6e48e90b614163fbfd0b5621de436e3468eacd08d40228302f89d9228384bc4e7d0e5b4c4b2e9d6f8625280566a3ac8cb62203ef53efc2ae725aa46e9dc9330e6c0a021b89ece4af9baaa21cda48fa6e67c95e51a8786cbc4f9b7e1fe1bf6f7658d24a41ef2996de5de80c4df7d7aeb58bb1281a491956f4fdf360a713d10665cf36fe20c33262eb965eb6a806b793504f78e11a71d56c76d95cfce2d9e80801f02cbcee3156fc30965d62029867fb34ecc9990b523ad71ba540261261f02bc3f23cf9a7441a6f6ab3622de48bbc3027b04680896828bbdc0d630b78c294e25ebf872cb08fde4a313cdeac0b4155bcfff2b7f7ac98db3fb802e503b7280e24faf198193b3fe4f329c2128adf30a86dd4c0bf3a976af1d9e1119021380abae173ba04282f27819b484d243c6a5b3f90b638501a179672b0527ef810219617d062471e70871af275182414ae2925d41e2e95e4dcd49a5a1be726602e01003b845cce7e361dde2587d56120b33d57f5511bc523bce5d4ba0f99a9671d2b212d19d9ded87a861bbe7dbf765e947bfe6116d03dd459b00be91269f9f5ef1d4998f626456776cc973fe2650f87c4e37d96612eeddc25a68830c7b409d0e922e9b7c179670c60b7925ad59467d5a2e0da1f3a58a17f7b198b659bb93d16386a768438028b380eadc3b4cc6d36c0d7b216747a96d53af8fb0beafe9c1e3ce618d8288069ab4c893e7f8dc96a49de28e75d21c33c9a00afb5a2f96c1e414e621d46b51fc5e2eda325738966f07ea5a77402f575987480653fc0e8894ceca37d0c6f47ff1a69a70bd97716705e44befb7cd1d0c7e64563c3432bfed478d05c532e0469a9ae5ee03a56b656140f33c5c4ae2d79f2a681b7998c2237b9fde7ac0368106d3af4530bac3041b2405a8f21cb16af4264ba44f442260bca4a771633f169bc7c41051b1485a748e58a0ff618903e63fdd4bfa210ce52c7401976bfc02d0ea0c1d934c76993d07a0cd6c02e1cc93f59defed680bd7fc13d644bb474fbabcf2fa83e5eb77c98607298342b53b08a4818322b193591a95f2bb22da1c7bb5719d62ed4929c4d6a74cf7ee21e75ff9c2d10e6142f2698140d0297a7b1456ae60128ba3b497decda8733414ecca7ecf067916a50b648ddbe1092bb19ef4e0861e32eec2434e3645b9d280c2868cbfed38f5764c653af765b767c84f12e37d333dde99ba9ed448dc547757d9977543daaae2a3ff2fa246ab5ab80b6bc27a957a8587f3d176f9f2342794a0acd6c1d9a958b25e99cc870951d8428427c83a90b408e6353482445095311e5427f65b3f135a27b30707a7f1483e38819ee5a94ab3cf8dcc8b7eaee1d8dcba7a75d9625c7341b26c4561aba5a02f4860076bfe11d79803b2c52887d7aa6f556365422786adf9a9629fbb3bc6f3371cc04b21c03aa9779f6f56a8cb00e3160b4f88eeb293e7510df18ee120f65437feb23fc11831fb0da1ecd8632b9d863f8027e07ee4655305046396cc2f610bf5892a8eb55e1805a1af56518fc3bb2c0ada610e2fb1b79ccd5e3c29163c263156ea6a25a56dd34e4ccc7530bc7b53b18f2e100040b8252ac8d3e4afa057bd9a655fbb97d2fa890ae04c676a8c64b20 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 52d431d74363ba07b7ec47c2a5b9815706e7b8c7b7d3e68ce4ffa31365bf4f2e747203c5edd758000a8c09d38a83457fb8cde5bebe87e94fb46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556b6fc8aad9ff0ff59652ceabb789970b3fc69d153b14a687fc2a56baedc382ba4f908adbef79bddff781776abd052d44a1c84c4d8dab9ce9a76bfa6374e9cee16d81e376ea09cc327243e936cc85d7bf319cc787322730329ec3694fb61013c0a51d82b92d34a3eebfc8c47916859eda63d33d64f77425e0e95ff65ae36d531ae9e5d7365127bcab5b50642eabe2b69de823b660b4699f8859de768990a8e59d3eecfff5ec7198cf1025bf9ee69236d9e3b16aad84aa4c381a577b6c7a3403627c3f3f11ebc1f304747f47407db9a8c9e4b86618f598ff8b6fcf72ae2e40a43a52189bd6175dbffbee9761ba99cb7f4b7129eb6dc5b1655dcac51bf47415370d6bf0780eaaec4ae3cb477984fe80398d50175658ccb4714acb603b6b3aec44ddc7ce64fcc8e331fce94c48ffee0f4e0da6fb0576f7a6bd5a00b5511d78badaa489f8bb3f3c5b484face4517d8b8a8f8ef24b815eb43a6b9be27bfa49acacafc46434987bcaf509eb936e40bd56504fb4525fee921b63733ebf986ece33078caa455e8871cae2894a553cedf4fb83ea0ac44ab90e99395af385bc440515877cb69b74bdc847f4dadf2388486d8909dfdbf8eeb86fa8478147ed4cc5ffcf2cc30306c8d98c679d4cb41ebadea8b395c08cac6eff348474a9504592ecd34a93c3f62c9751e52e93719b617355c59a25679e9d9a5e756c8ebd3e3b174e1a063edc733b945db4f738618648baeaec5b76376d063f9be6f7d6e73fbd6139f755f361096cc4565573572d53b55dfc42c85b5299b1cdadb9cfec4605d63666ff4561d8c1dcfa896d1c6d8918a3e7ffa8d52f4ff985d3d1ebcc8d5395f0a64d145462399dbb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6c3fda66d96d426b9a1f4c4c4d0349ce2bc79083f247ec5d98e43bcd37cd94b652bfca7b989bd63cced2ea0772df0aaec75cf2836eb4fa7a49f3c3f9f2c7c6d04c859ca8e6d5cafaabb85e52dcae066b9af4d9951776d41cc783dc77fddf4f55905d473bb43bc1f93bc6ea7d33f46ac4999cd33698eeb6d3c7eaf65ae7e3e48691c9bd48b31e34c9998da29d60cfb6ae31cb5a3b7387f2257fe94bb3ea4c963e0e84a0cdf1741395f196f086fd31b7bd5a7834551a6c8f0e09e498af9e12db6d777bd5c80efd8b36dcf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a95ebe9b8fc9a7aaf5cfb7f7c73f727c765d4c496d466942147a8a7b65aec4ba84e5ef74577ebcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ffaadb663d79bba7bfb8908b330ce45e4f65c6a8a379a99c9e69ae0c288e30a1969e0cb708d0ca6ff1669d8756d1d63dade15eaba4ad7903b5d801456325d57187758351588bfeff2785c9fe84adfb4c59245dcfa72c3d9767348eedb7c2097b457bbac8aa96a67d785803744e149b3f23ea8b137eed53ff2f966f2d73e57b80a5e83d887c54c8f0303749d48a91e3cff693abdbb33f46667b8108b921349a8a945a2727f807e7f992cd744626662b1c4aec2567972b8452ceb75632bb81ede56efdfeaecafe24c4e7f828a7339c9d7756fddb6e890e07fec559bc58b7c66398676806b502313ced8a8d0daaf6e1579b565a66e324fe99cee3e6ff8d01e36630143c96e53736e7672a8bfc0ee6aaf122ba1d4a4e6c299795dfc47f7c5841134b429ecc73a97424874f45486dda77b8a9d13a297c4399d2479f3e6b0e56462e113300b0fd3e745487ed781c98a8cf27cf3abea748eb851ab09beb61d97ee06b1252f5070f83d80d5af5f75695cc89fd42566946948abdaa06813fa7d3ec35a2bf9423b8ad4b7537bfebb188ce11d55576f9c382e49ea5695d231e36ac8f337086b81b0256a5e3f88049e732285a90933e0bbe6770188dcd77aa7e2d54ca3ed3711988ac20af8a999db382dc7841ddbfd16f24a9de99bdd92de5e5457ffcdb9cf3ba29d594e4c9a0df6de2ecb48311ec0bcb3612c12be5e04521dc3892ad41cbbd769aa8b79cc9801866c87f7194d89fa56329100f63788904c7511533ecc5b8e7fe45659bbceaba74402605a84f195925a71e3153827a5b417e0b994ac6355071ad98b1328f919d6f8c30ec7ad3366683aa3472132c801e59176711e2b20c251281311a6041ae71f96b9ab225a35e6273b5878ba6e362bb1ac896a557078495d1ed08264984357498d119706b7f4bb42a8700eac4e80164e19c2263a425f4fd18f39c2b3e6d70904e7481a14030b40bebc26be4930a05b4236436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b1261355bf296be8726b04a066138c714b229028b2dc5e5233cec7abe672a0f67572ee2a0b84b6f231a37bdab5006a9ca184cbb82948c46b6882df10a6bc12a8e637d3d437023b99197c207acc2157c43396be138ea06adc0bab4aa2aca95d5989cb6b9f1987a58d52b0b460956452f6c00d08a188030bcaff3e9ce91ab88dea04547baaff1d64bfe3c2f5050a398cccef166a6fd82151738b227c04288e8bbde4c45aa285af2767d17b4a66529a06291757cb52ea67865afa5390a02d0e93226eb200a03fc0e83203e08390af0875f2331b8076259d9378dc77877652747774b85064b878b816cb30c6341c4529fd112b1857d2c2c104a57c52e6c7ed5274873e43303238d19f21447cb45ce568e3ca4863be289e5917e38b4ae2ca117ae7a45b29c345e8a463cda4264877964033025b5a77e8824b928bd2305421b810732a1a2a96225cef965e46369cdf15e0b6129b5aa061cb88688fc0e0da00d71612a56085be7d24f88b4c2e6b7125a58c253c8272b04a0df60485147b85bc566fd34ce78a95a235916729778e4b521ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629e712b8e3ceeba7b32ec4a4b9e115576a6f74495a7210c68af925c7ca5f0818390ec408757170c8090c4ec78fc312a1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7b52e32bc1799b649497b4542970a50ec5a412594d50234cac594efd1b415b777ca759ec6c51197177dd183307313a3ea9b7976879b85703bb81aba1ae3727e962c0ac0ba7f60cf0cd6c8e863a0c6f395b41935ffe6b56d7026a0655d2176be3cd9537c227cf79243e09a5d04783ed170af46ecc670b16a47803ffac59744ac514d84aa544350510706aa408b91e1bbf4387d13e05feea35263446bc7d32648c8131d1b53d8da5ae774634b85bc77742128bb984ce4341d1b05cff711ee33aff31b849c66791fd5259721bccfc8a1836cc95c39540652a305c410e61a980ea5b720c472683811c7c596b635072fe7589c1700d72bc2a84106a296636107454a7a47c66a1234a3a3abd91cc7b049738b6ab7d70f450c64daaacf2cf9148c1806e2308f9c883875ab36fa20593559cef890006eaac701db9d80a762c448ad14c4b8dcd22c2a4b26ff23912e30c1c4f0467762b39689bb9ecca9ae56bc20c1347c6b4657d780d0a6c0abe904c9fb8b7769c550a11dbf54be2f2b4fe895b74002ce859228eedb676fdc15fc52c5a0679399205cb0b964e8e3576dab64f21741009082b04a9a4881c91be1ce9a68291087619b8922524222b1385454f59d355231f75071cde1cc1f96b45425932406380fa54653f521c5a178eae6aadab4bddba968fa037a94688643961fbceb633cf95c253668187784b09a7270993f6f12c96ef91cec254ccda64bb71582f20227dac5bdfcd535de1324520731747cb81cb96f13633da59318119150a002a2417ab8963b51f4fcb4c3b34ca9964fd5d94e57b23acbbacfc1267641da2083e55f5ca34695c7a45a283b15365ab9dab4118cb230ea06eb4a2fbf952f1342710ed07a2cf16e3145490a2a3a9ff308e0555e0015029e65aae08024b2637da6b0bee9797536004f9c54a782fab6ee67a8847143529c8564c37845f2c281664366205f51e8b577b19daa25162f291e21cc498a5599a48c439457a2c98cafe7e600718b282c45c58f04306aeb59e5d6ad6f3a3140903c6b8636eb2800c554c4753a3c981914d4c6c6914b56fdc26132fb281e944f27b4abb3eb937cc49707e89eeda1694dec921b6a6d9c238681dc2f844096af3bb25d61bb81d557478904b87511b5c2acc402a9164807909376b800b8ac970648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7ef07b1f4886b895a3246241ddc084379eeb0f0ed84bdcd318fe72c9b546413be9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = 5aeac6657f61806a19b78e1501024ef9a194d5fecdf8a988f44c34a3c1f15d6801fc28fc2dd6776fa41ef415eadfbf8e5e870dc878234c74c09d62bb147c513b37a5767f3a976b4326510c958f532b22b9a7cc76f6c27638dbb47852692b64c8a87c2e74cf4d34b96e3feb0bdd497d1a371f8e4e94b72b6fec30769c07755cbe6ab243ea2b214880893e4b0d22cddf124d171f80b612520f314a225b9916f19bac96bdb88736c868e27590603be0873a1fb84a3f92ab8952206fef3221d795f5e905f61cdbc7edb33e06238cfcac6b1815b0637cfd16be6918474f2f63f47d908afbed7876f3d4bba22385098cdd729a568b2fabd51ae77cfada8849220513467f5dd720071ae404bce9324f3874e0b96d0ec919a4d0bdf51d71eb2cddc8a821f4c61d08cdb8fbd1a59775d1bee663fb8e702799192366a1b3c214f49207b49634731890e8d05712fc94cd63cfaa04f4e8580c5df6724d7e01d48675340b614115f94ef42336c84c08b13530cfb115093e16ca9474b2fe57a36345aa171217cb7cd811909f85abab99291ef90b31a697ddcbef02d6c1ca1c7bbf68bd1770c15b13b973a60b0a5db4ac5ea51abbf8dcd916abfa4426db43b0d45e763cd4f1430cdb7837b0a8856f8049324ae97f3bd1a7b6779c36e7c633a6bf99fe5ab377d0d4a30b0446978319e9407b265253200c98521750abf27324cf621a98ed9499e97b16418417c4570907e06404d117e89dbd3656d5cf8becd4effd19161f137fc45ff2adf02baf4ccd47cec32dc2092b0ee8c9dbb0cfe76f5e1e44bee72d644a3bc9112ba8c8faae23fe16a64d35e5edd741ccedc75975c8df8e370a3178541b3214999c15d5f2a4848585d31dec9d19e404e7810f2cc0172763b6c746fc7d75d6f1eb0d480d16ef597c1e9df50364591c09935a5274bdb7b5d0386f6cc6da6f50f2aa562ccb6368cfaf92c8ce1330b7f6e9a6d343bead20e5f9d9abeac428a63200c42127f163a30d1ebafff7ff582bd81e21355f95f9256687abe3fcd2fbb09fde72d079a955c9bfd09e31ab7827d2991834df205c3d696db33fd766e8ecba56a1c61d49295df83d4e2520313ef9330f07a3ceb51f3a2d06b36aca88bc2b6511d2730160f0a15528568507e367581936851db00ab92715b42f04df99884800adfe2692bf40c1aa82ff825d4a17675b7ef736cb705bb11524a0cef22b26029abd3fe0325940230a310a6bdb9ed6c6d2ca9910a2742cc7fc7538573d1f5737def3bb60608a44a1d57c1d5893ec14deed990a89215b721d0a6bef09ae51053cde3989e249bcc4490493ce55c1b623daa5deecce769fc3b1821b34d870bfd87869d55dd9c63db65d52c6ae6351a1f4b4c8b36e5e7d97fc6643b8011985d8ecb62c42d459d55186cc76785de1301e41c71f4c78add1cc9ff9bf578563fbb42c1c5b1385c32bd5c2fcb2605a9da5a403140370fb9b9d0673c3cfe22cff7dde0d203ab79ae5f01df3718940dc1a3744d14ef6434cf78aed1188fa8db485504a12a15ec609375188b7e95bd70294f91facb04a806ff935a2a51835c0e4f702ff92e01a0419088e01a321cfbee5c8352373b2ed195a3e89bd600d99d2d91c5377d938c014b98e11a8f3455f851c4dfce5b92eab76065fcee3aa10efb57b8fed365795b436ab8b38037c75551fd5b8924eac14d401d3158d0a24474ebba1c8bb84dd6a8c3618765a93e559142128fd549cc5af8f1e6b63798efbf9ebfdbc740ff683fba2f398abea3375b58f37987da855e5baa68d6596dea4901eba5bdc8eeb7e5aa28b8a8de187350ee35674b674023d493da86d1b6799cf662033f93499bf00ed13072bd7a67f4f7dbef7204ce31e6246e29abd790ae1d4d211e72f636ceca98a502aed3463c47f6d6f69e4347c9d6838f4cace94a318a0ec87c118086b79d2893614c3e5daffe2984d19dc25ef69e4c3b49e346c43147e040ec6aeab8a1121716e081887ce86ab39f543e69d662c83f967549abf6c222842d006c53b3854f808481852d34c25e2a73c6f988f6bbf75bba6f4fa099822deaa1cd933c005cc324685bf5e214298f09c2f6f74c80f628e4aef97622174065852e5b2134f4d3614cb78498c2aad54ea8ea563cef0cd786e30f94f86c404b5f8042797a67e5111f7050266129806f5bcf73b8aef3f29e26bea6ea9260d0efde9c35fccc9f761d8809a9de1d1eb +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 28caff24db8e2a6bf1092964f197ee98fedf2727c8b289e6a5068edd27670d26b91a93332157ac697fd5e246e6ec0f71b18eb51923c5996743cd1e4f3ae3e0cd6791afbd5f77a6d9925e3ec655533a2ea8d14cb2589399ecfe8f7ba89bb7d6cd2d7336edeeb7b63b98f26a49d356578cf7f75ee67678de482e1bb3d85b88325bae0b0dcfd1288c34078d73965442b7b1417d5f0fb76ee4dd92121fc400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313f8fd51836a2eceb0f38afe00545f802b417aa4d6e564f0b4e7efbd3fe0d05a771cece64ae5d932ea40a886d51838f36153b4e27e5edb14530467f1e89a60adedd66227704b8ab991e8a0692ff26bc59944cd814c847a1865c19df4b7fa13ba3ef95543f7f4ef854ccb28bc1db49b76ceaca3649f848bc6f33ce39aa79197543c638f38adb755f4da6bd77e30772b4791bf8c9f1544a4e9860e875e69cecdd9dcdcf17451434c7c53f3a9be3984982db1b80a836ba4c531d49bad26d77fadf03daef0c33f39cea972455bd8a60ed912443ca75b913df98dbe29c3322e57e156311f67354e4e4aa14e833f8454aca5b3898b3572f8e9fb2c4cada43c9d5e91d6f7aed803e1cf77ccaf0c478686952f7ea8a8173d0d2f3b0456fb97cd4ea8cfe8a145e9b90cbe3be8c32b276f90d349acbb63637d6dcd54aad0497a058ab0138a8e57e5e4d5d431053e84bd2ad7b77c3299ba6c7205938eca840303eb1d6d5a942b73776aeac11c40d81988e6ace507a7e9aa769b606e8052e5f90d84714ca57418366c15b74da4e98df96abdd19884ec27d3f7978c4de7fb495f8789e7e48f16c23ef8bcd1f353cc4a76e8cf38afced3542430105f9acd46926884e90566e3312ea6a9283de0fdfedadb7de23a4d142bd787539b692edb498fa51f95403865becfad6e2d8aec1f534fa3366bc1ab387eb867477b92f01cdd0a6e5bfddee38137cedf4d98ad57894ff74982e7eba2eca6a005d3cdc9c89bc6a44bd84fd8c6fbb5d84332faa831efa7322599460f8d293da8aa866f93cf4e47de64c4f465889ec11f17d3d906a82546c7609ef85c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce87df04f758e71f4544ee3d2365a9169dff75f9d998cedb15e650aee33a291c870315e7b7cf9cf10670d2dc5c8889aab85e8b4dc86d87ef5c52acc4db175a5967e18f983c3a4443b348d3a326eab35dd4b7a789778c8414a8aa8d8e9468ebc28b68afe5333f7e666d44b5a961533281cdd21bd3b24e2aa51ba58f2f45767a67f2e918b1204656a2b44ce628a3a95ef5f918999a73e1cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87c7d9353a77743949287e47938f73f21fb5e628e67a67e5157b49ced69a25aff03a08730fdd7b7bae4bad136cfa969dfa68c28a04dc9763872fdeb05e4e61489bce1f473d4dcd67a96f58f6b664d2436d4866e66cd6d467887f9b9743a06d7d347ee4e47bfa2964c229ae8eb63fcc4c78e3dfb841e60c3baa59978234a06fc95aaaeabec11f3230ac33bdc48a455f40394fbd6158c669ff8f20bb5501984c5d3992594a9239ed3799de78702b86973350dd2e617aab9b4466903d59e4d38afec3d936c26f933505b7f45c3a26fcb3b32bc3db9eaad5d7a8af0452533df312d98a7877935cd6b8c9499ce82fc6566bc21fe4f7f2adfe6cde90c8889824b35b79268e4b2c4afda48b0c98856a097bff3c4523ccd2739349aac7b8cd286798cb919bb550575b44bb5df26cc3f3f83886e2ee64f0beab649aea738747e799327f58630134beb49ae87fa5694279bf644997448b57f919f92807c441c8d61f8a4c1d1bbf8c55836eab38fa483b66a652c566e91e9c959c45a4185f44b95eb294e38134284f771b81cd7fbee2cce88d68d53c7589394b49b5b33cbf1f993549c2ac05be0dda9b63d97e45e738eb2738c6aff4dc6dfa0fe3aa38eee3cd3393419c850b77b4b1393884dc9ef4de89ef3499372c8852ff90f928a9c06ada2119f6cc1b57291e5771e55fa15cf3ac5beea05d7b02164f2244d50f06896ba969347b3048e4f8937dde7dba3b8eadcff1de707d0e85fabe6fca49f1c2b648e23dbffaf6ff0fea48af9e588a15c064a9cfb0bc862dc9ca88b1b22e1b2cb01b18957737b65a63dbacc6828418150978215b85703586c1060740d56b50b40f806a7d2b83890d2996cdda967654506e096a9e59b69378152f4b8b2c1050a9e2bc9e20b513813db6f6b42701ba8ba3a03e80362c7904f240a49625435c00d040648262b44d881882de55cb3bc1968f5b3fe78bbec040a50972237800c378eb9ca8735f5502ac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c88509dc25276fac066199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8d514be837e0de28079e22b3f6c9991504c73bc2603161f8836a8814095ac527e0969c00dea613de63b05033b303c5937815b02ebc3466b5bf287265852665afa4d3dc7622650a0ca7438d896404e5b2a09220315bbbd5be37ae3a61953473e2be9b39cd71c072a97db3aa7546a9ebfc651500633a30919fe41a435cb5dd9b247192b233b676d2432132bd4cce04c30af99344e20aeb8e9b6545b4e9c9bb211e5add2071911dcbfdec072cfb76fd6366a74aa66c1831e1b6ac6def02d703bc9a9011480032e0b1a8e668cc3bbb46510b993958a455b25c025f19677f1c03828335b85868dc99c81d3b75d0042c3735cfc063b68630c00680dcbf561fe07ba4202b1045a2eaca9033ddbc2f3e620cff6158c904666927d61d4702c84aab51c60a748acb573704a5b422057ac3933233dcc6c6609cef96993ca951f89e10b68217d4a59839f261fac87375a38314f4b7ccaf5321a305ff7137e4207a9db03ac08370dd903a634b8951fd6c93bec205434ae6fc066eb18a4a1102297abb8cba62980340b2d643be20c067db031aa886282b03dff2870ffc455cf78a1657aa19e958df64b21cd9467a1306ad40195db3a9398c86c5e4111cc40816a860909ea742f8b14cb2309860b5d300253fe6149b236aa8ff44dc8d79b852888a9b2988644af45c030f5a69e93a44bdb454d79c36f2a1b13db7b395cd7b7da192dac99b4d5560fcbd96312483511bc8d9e738bbd4cb5e708cc0a02056a292180d06d0b0983a2748dbabaa88ad144aa1028edda8dea7704908440dd9a272feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abda504aefb2389322af5df12cfd399cd19b52cd8850510c37e6c087ac060e468c97fa97857e78712c17696ffbcda6f13248733cc03c4f08b92000590d79d74f1ad2336b9368572230ee472cc3d28a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c444929376021b7fa06f5acc940f2984b118164ab204ef2ba59de476e0ba22169888e64717e8635e7a30be99441814b5141a658bbe25641d3557f07b33d3027ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b162ae5fb9693607bc2fb279ba5b3bd19408ac8ca13e8c80f2139bf410e3065a0be22800c0305966832899753d342694ce56483a45f0d56848484cd1b9c949c192658e14e7c6abbaa51cb45441af9e46bac064376509d533718678a614c1b9e99796c0d4c8ac6ab134c4aa79a1c22692183c9f2af94836a52930680c974355104a05c0cd3a5c34d6a7b524b1dffe1459754066ab41a0b7315f302955ba23fd2b4588bb58048e981b0cb1df247874699021368277127912848cd65229c59617a7783542b289456337dd572c8e703ab1f22af68c962c9387e92d754027619b7f9accf233a10ac294ee15c3928934ee0b342f39f3ac5299ca681f5c569a2d87429bc7b4c492a9a09a48e17534e7a74023c0601e92bb13ab2f6918a44066e58433c2cd811ec5a144867c666b390841712d0659528fc76fc2ca17d3656b4b0673f682bd37980897b02d3608ecbb27b76ac848d55658f2606fb761154b0c516d0787909a59b35bb73e43988ca7459c22da04cb91c784f47e39152293679b41d13ea4908836735c3a28768509b2c6dc3d220c3db729437bea79727ae8156e2798ab7e9abef81437de27e752188dd22913e477230549f564a353fe17d513a72adf132eb0b0f3905cace01b05a073498c56221a4b9941a0223d4abadc87f83b6aa153920ae58cedb7aa5d4ebb6f4b34570079d6d1354afd1c30efb1aea9c25eeb07cb56417c134cd45441ed49182651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa1a2d9ea0d2280249d9d756975c6979a8770bf4b5f6addbd76d045a816bc1be385fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = f5ed4fc705e7731ad1463d9b3c1c634c6bf644df4f86f08d4aaf6a499f4643dae0acb11d08eb4f160489ade20211e0d1a32aaeada615cb99d309fa94a71f007172b3dd870c5682b88b81839063913eadf10ebd5f57206e6c2cd99a1d84607f54b2ba7f5d3db7ab8f63c97318819b078881b2926bd446bf7fa02728704250d34dc5471f72b5a9078faafc68d230f966134d683f3cb951130898c994851865aee64dff49a6844d28032ece637eb184c80c51385968f137acd1ad6bb68ebe96ff5d24886dd21f16294ec5bf3f9cb61a2d6fde85a2ee354890cce77fbbcc06df6e8341567e6548aefb2b111e66308ba49ae0a8152201e1543982449a22adc6867569fd2c562ab5ec6864b606910e373eadd2b5a19b01fdeb7f707c0a9626cc410b8f8a0062aa15ed499db23684dc1fdeb0d2ede15adaefa91487e54a92248761b09b689af2b2e3a9713533bfade1cbefad1a499e0e6246586f235dfec390e5001b4ee8d3916bd8384d3045fbdecee43378d3d4146f0583cca1302179ed3addce22955e8719e817c67a95b790b744864c8a6508fc24b262540112ca7b1a84f17ae26c61ea395e04346a0d32e21d35a5a2ba3e71ce4de4eee6391de568deda7364c5dd27ba6fd497e1555d469d6f87d3cf656cc6c16dedcb44a6aa4e7070ba0dc1045fbbdd8f45d3d2cfc8b3b73689c971260ea54a537754a08a7a2eb55bcbf7a02c7371e6e2a7d5ffa27088256a52b89d9c172b1601ecb98106f67e661adbde97e78f47129ee326aa8b25423c7cb4a57c60bbaebf204a3c520db9b9b5cd751b2f9c8a44d4151fdc5a0ee211c1c4a6cb5ba9331758276d87d57ea19829fbb67380794f6be412c4e3acd696dc305346f2ac01e1b6c42eb3f58dfde482162d8e5cd8fba4da08612b8f4ce2c870750f4205872bc46127d4dd564aab830844887c52c8bab93b54d31e2994582635172837bf1000bcbfc394879f9a00dca4134ae99677a81cb0801c9daba7c7a59e625086f6636e66624b4eed2d3bf32ae568f17cba3f3bd2b4b11796cfb71f7e562f9a02bb53bf7c1460f9cd9a72dae6c72bdde5edadcb231b876b233bf77920bb1b2835fb9449bedd6ee791c985136a2918329b92253b4307444f1aa7afe4a89d5f932330147b678d4092f26b9f094c1abccf00ce618a63afac2a02cb73fbac415aa961860031ce4eecf9e53f8a4daa8ca65af9955eef5c1a9168eb28c19ba1cf14aae597dcdf9476747a15cebec9e239f7c4b54a4b8e11885cf625818b827cd83bc054c2f54aacc33efbd2ae54d04514813954211879f9b20bc5438b7bbe951d30c7a0cbf52d5ce43dd6a485b97699121e64d4c7e7a378ecf72837150e8aecc67831130d05d052a06ecf065f3e24391d751e7623ceedc3f661e9798dbc252f2dca40057bea43807fe57afed578298771133d75e50562b947f1bd5f2c40445770688cd930ebdf9878b2f5924e0cf6cca6083b29bdd05ac25555244867db9bebd1c7b65af1e66d4a4d8b325203867214fded74a430415b1112efa11bf57b4a8d03dabd88d7a472a0677eed4956dfd6620267f2651d5209e07da56f538c64786267e701fbe1e57ac2f0985678fffc6a5e7b0272b27b457b25b93566e3ed346ceb3f8fdf005c3d33e0417b70d5d77250899a7e69a40afc8e332c3b315805c3fac44167d28ca64cb3f6df6c389818ad9a481492f271e14535d6085492ba4797c4cba39909fe1c501b56e5ad29a44c6c6ecbaf0b6383f4ad160ef563ca6a3fe6b22e880545ab934f416cd6659596b8283ee4c2a9406d012670f5a66ad44f5cc577c5c0ea98d70920926bca9c9b43eb908d0e25b96553836442d9fb789d977c677c6cd166f891ca95938f45732dbfa6d7296372f7a06ce5ad83bdf50ee6a9eacb3cf3d861ad34785ff5a0612dec617ebb27aa496ff379dc20f9bc5d6a59d38a5c922fafad0d9d3a7f6801a160c4123ef8716723f5fb9b8498fa1193a24d5107b0c5f13b2c527718aa413da53d9bac0b70c483835921bea069c5e1d9854e2db40c2427d21cc0f84a4dfa0c94db628c37012f23f637f2ef5e2fc0c11357891bd4574d42d9558b7515baa4667d32b497e3b9b5a20234c91f895ca8c2e71081fa6cb834aab7770fe35501c52395eb984a2a2d0ab8a608354812e425d93b6b92134eb877bfaf2b671be892a485ae94d67e9cad8a615dcb679efa56d902 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2f766ad79ad112b8cd4cff8dd0f589873553c01e4f1acf71a06ea32cbc85c71975ba2ef37bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab57f9d02abc5ecd730913fc721f54062f575d663c8a7e4aa7a456420e44d8cfbc114ec03d5a56e08cc7e5663c0105ff5087f88bb8cbfcbfeb4a9ae9c055691e05c22f94c62c3cc2b6a9c156efa4eb2bb9d95b8c9d5a6395dd5af88bd38d3edd9fbaf66dfd7088b3cc7ab56ff3366fbd595b3c89db5497b34b94a72e8e53fa13b40be96b523e5ca5effbe48f8c3556843545c47c0f54266a802a44bee6e5a19a4464734ffc6aaa4cf58fe8ee3c99247564c65fc93ed589ea8bb2c637bcf7277d5c5d58de8d342815b2e8864b4c43d920b8fec76b4a7bb893e1de8278f47f84743223a67f2983ac8c5ae845b6e25977db02e6d53dae81ba5cebcdad5b7bffa27c59c1e4e38da723b787baff36d7ee3ced5039183bffea6ab3bc779efff73326b327e4f517b6c6ed8c7f96c6330d4c39e4dfa7b81a538693329abbbb5947b068c3cf7b45c174ceba9964c86ee9ed0bf64e20ace911dfe84353e1a51af128e5f75414815999ee00475654ab30b9693ad507b2e19acb7fe6b14f27c09c7bf570b861926683a295d1473ec2d7cb8c0d1da25d073d3c067ab819b9dc27971825ae21dcfe50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d9079571abf37238c1f94ed07c79d186949c600c6f587ac0d81c8334c57fe0c59db4ef815d63c26d7fdfdd7583636e644d99327a334ea5b4d572fdcda39ca717dfbb894a50bc4cc84d76f1b615d9dac77ecaa39b9779a3696749ce83933ec7dc1e85bb2dc3421ae9a0f04dac2d83a1fbce6c6dccb0aa16aff9a94bb7eef5665c3001b845e80fdf7d9da3db636951bd836cbdd8da33500fe47fd4b8edf1ef68c62974bbedfa6d4bf26709e8e2046df4ce883187683f13da29bef9912d83ce26730438b0dd0d42998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913ecf61c6f74464b656bcb645f87b0cf55e2af443959e67c47d679021cf905d45e21da586ef8f91085a8a53fac6afaac5a4d81ec298dc23e75779b8635fc8eae58982258759999a57c7d4a5b14d246df82a9b6c9cbca838399523f2669606d389ae4ff661f783ae65a0c25b7258674398839af2886677e329109a58e579c026549f0c7d41dbb6623665fbcaafedf4ec04366353269e2366ab1364b5a326fc4b9cfa1458daa6cfe65588b8d26ea96839ecabf66a4e277f2f87977dab7807a2c65a26a9cbd339bac1bf4e6b46e0b8d82be95bb7b4eb1b8b670ee4ed5eaf994a06a6414e9abe3aeb609cf9c94b846013adfcbd6959ee4e1d9ddc70b3f559c68c74d94b2aa7d7b9d9755e3c69ac40782e98aef904a32db8f4c7459b59b174a9fbb6b41947f47b3361d5558d93eb2b444818ffa4c17f4bfcf8b9c7ce451f4ca99885ce3f86cf4d3cc4741df567a54ab0583a175759fd8ee97f41dda3a7e7bfd9c768248518e5d791cd84dba795e85388dcb2e507bc669ff0b906b05e6f39cd4dc838d0d1357378be601887ae2bda0c459dd38a871910c695d6dd08e5a5a0f4cbaf8497a56f6707fa7db77a6fe13a5c09d8a6eeb5d840413ba52fffaf3666099ff3c12a9a6ff6785975ba75c78f3e5a8db78cb3e5e2db7efb9307468bf3b06cbdac6ff0c4ca7157bb22e9595a4288e174e6aac37480aaff9d397a1f716aef05676c3ad35629c6878865941fe7fa1dfae5315c4340c7191c4e5046994b9188d4f2fc50239901408b64d1e32f854a13de43884b8cbb53db27744ee753e866adf411d49ae3d76df84e35538c7668bb8c7edf39a3fb33bf7e45336fc68ab37477c037f7d4a460f4cf11847468cdede0ab675776d5217fd58153c4f5e14e900265ba367afbc2ebb147ddc4aa74fc66ff2bf1ec88298b35789532f357157f48932cfa58cd6a75f8fbf412ad311fbc2b84a67d7353cd13ab93aad5d55157a1aeff6deb6e91e3db28ab9e6624872bd067b2d7597d744e9fc5cbe3a46c36e0d47c33ebb4d1f609425c1f77fb69f57aad9fd91223ce09fa66512046822b4c7c57ac9f2c9c701e7e67697bed93c789b6f6af045a8d6afc2d51383e52fe1bb38b76c9684b3f044ae2026d8b17f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749a52c8bfa2327db1a0258829bf7bbe4f59b1a6d8b8d3954db41bb4a20b0d660c21d6202759601630854ee75cc29454ab1a3469bffa989076301132aadec892978b3e15082bf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b507f31bc1495ce2d5943466996a0691d80405cc21b060568f55a18fec917106d7277793089e147d759988569820e0254ee7896e9797612c655e71371178a14b37b3a2c2b18bdb952a5295bdd4385c190b3d61136f128ba74c2c57612708f900c144093ae460c86c7a2f0b1903fd9a889dd7874f6543a2e112219869819c35c055813a394333ac6c9c860ad7505f8aa241046a984403b798e3211469cd1d8a57455702b2816f0b2b3ec60b273b102559099528d306ff23be250b50226b497b60b7540813f5b0c4a11732a6b9583a21b3dd2028e79a82ea0144ef34c32e4392a11241748351046b9454a50e9f90739d12a96a928e75806f24004b4a926f0e8769f90a921c4323d7fb7cc74c2e33248c30b774b795cea60c47ec52a01ae84247e53243542ebd8abc24a183e2d72247628269e108a5e93f11a45ca9561e8fabbf85aa61c6bacc2493aa93a38bb72421e8913fcc635ea0f2ae17ba41e43c5af3c83382f0667b6113591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc7c224dfe3bef7e0afdebb5f91b2532bb867ab3c08cfdb6a64ba1876285bf6463b9a241512919c9b72669ed252faa0aeefbb963076592f9884b5e60e42c2008efc08bcd1cc2bf31025c386cdf99b49283d6d7b0a24693618d2a2fac3b7acc60ec970b6d357b199fb6af3039eb6601bd57506cf8292d3181eff61cd380c525086962b58bfe53c3c0844431347a2f2112776818fa3ec2937b4b3b21c52be816637c38a68aa5373858e16c18134093311292814101cc2940b7f61953cf5971fb5ccae59ada4373dbf9c149869a0833bcb97d9bc68d6581cfb803264599a9cb1cab10a15178f6cb23ddce70d060b0ecc7a0feefa35b6db9800567417775e1df95ebd32a4e67616381b48595933f301408e2cc1951a095994428ea01883b4a8a8d780cf960d69a18425258eaf63ab2f2752aa411856b78dfd60c2da74c35f517718c3b117a98e968a72c3150105ca44fb02b14c439abb81adf5a94e2e5b7a8971848c4a9156e1445f41cbbe2c7c18785baaaac24bb87936ebcc8ef6ca4a951d1de8c2e6c5658034c1fde4b75dd1a176824298a669b0c4355aac3e201380c42cca5060192d06606e8430e135c50997579cd756da40336541a781e6702c0041c696270b65a92d531e964a1e953555628929f7fb59a7c2a5cfbb90b4f04b129cc011f7aba0942247908b22267df9333e8c762143c4b68909694de674ca14c7538604a7741fbd9004d861a04f63b74106729c6759718125cbdc40ffcc60c4aa30c7da001e30c889276d48b1329ac033d5365d76c85893da0e15590bcc064f0803cad5e80355fa56974ac577db713862545aa43747f9456b822e74e56e3a825e0f6259a3551565215dcaf4c9ce568c25d9c9c7471806210969146bb64c7af9a03ec276ab4ab10e8dc227ab491473f09718c4a046e84889d7c40f0bd0878675deea6c8e071b0e819f77147631939c035a8f9a4644b3dc35c3dc328c1c0cc6cc537af884d7c6000dba9e1e3062c2d43a30eba1873409422a5f664174d2f536e8420634558f4d427d3b8b48b96845b0f1847208c374f31d419988e9434a9f626da5258c00654b6789122de71788d6b259a29eabf83a42621b1bcc1924a79d3fb59ae6475ae6714296ba1528f30a66c2597ed308a3973a501cae96e1779813195805b12b0b008090acafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b1829428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3db0273551877522faef812d452b6444c4ecf3b9a9670810354b5bd57ba43aa5c4f271a03b2800f5290650a08ae83061f331489265b2f2a3ab1f4b3159103773b7806157e26ec1892e2c3d121a601777834b52939a658531646e713222943a0decb5b82baa4bac41f1cb2aeb3076a1a20a382698ce3919ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5a57b333a2f41fda2ea72ea11d8bd642d911f6afe90e60492ebeefdc17a93219211eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = d2ab81360e842785725a281e35958b2dc839bd1ddc19656a44364e7f2f094965f0d9516f525af183cda454a7eab8920adbdb00c96c5e4e8245e6de3630f0a2bf64bed8a1cfccd7455b29228a390ab8b9bda1b3a8bb5251f87d9fb461a197e06944979f4aa1008fa95f56b27d0caf87e7f77ad94fca71e26841383d391a168c300333b472263e90ae0110eac83e2b70ca139064d50264270ebb8c7daa18bfa3ce3e2f0d2b96777f04fced16c69602189da5250782a5f48f6a76c3bab6273addb195a10005d5d190f2204d20272c1fbb372224976b6e538c26acc90cb2905a528b7213ca54cb66cfe431dfb88000b42733488d89cb698beb53f262a1abe632a1d66b62e223bd7ec342ae362ea3b4cc322c152d90042c843d966997d18582cc2f828808b3015079bbf88e0ecfc1dc8a2a3f227573b31a78725cbc6a791669200ddde4e4c9c48752283bba0f1e243561e71f7ffa06fa837f3c70d78ba19d58c7c43816a89436acc77eea80390215ccc60312dea12f3d16280a33dbef2bc464341ff884dd332d00a2cecd1740d0a2847ac705766544eb7fe2e1b08bace10c083fa76e3543573af1a45230fa6c12b80e1b84f8340b16261a54e5dd612e825280cad56df2e9ee1a387c0b8bf846db737dd16ee5f929e5b5b2166e33c7a5b18732b7fa4985d1b772f69968202134d0c95d95be357a507625e97bf27a06d2301df39987f6641d32709fd228976f53624abcefee139128a173d7c2700cb912792f13ce697352b5bbf7dce8b1609bbe07ba32640ad08d8594a9cc82ad39e1fe414ffadbe5abee04e2a451e068ce4abf4dab9912377a31f222a420a56a50bac6098dc5aac5dcaed90fe65c894c95ee3e49955258af83493028ed855369dd119bb55cdb6c446f1026c9dd09186e35e813d57c671fd421cadb74c66d8dfb9f3c7b32de3af2dd5416487908dc13dcd39fee455e3a05235e3fc03a3a4076f5353fa4859908f8f0a63c6016b3f10a739175ad03cc4efba63a58381007fe1cfc6b7cc824e7befffd3a1566cd1c90325c73734c12cc308757304387db88d42fd0ae6b9933a9f3a8a4e95e74627995fbc77285cbaf944a2f5a5afd5cd722c7e5f462a0508de04dba5f728b87f28549fed395f892b250877099925bfe4b36129c74c8c6b81186549e1906c7fe9c2218dfb7c0932e31cad35e7ca2f7c0edb2fa97aa344d515c9d87d4a9cc6cf3ccd9aadcc8f9febb5cea1e263ab7e0228c974b6f726e6d4168ad170d167b893a1ea0b9f1090bc14bc6529a809b66c4726f6d50767831b3ef5f46f069530e12136406051833f729f0c7ad573e58897f7a24e1ff52e47ce2ce7f4467f6dcb98fff612d118665d99c54c92dc6a923631b5d919e44732a0b4662f2f09435098051d4e1dca6dd4e5032b58be812c736884ac2940425766465814c70ac36fa116aa4f1e9a5f8ea491688f39fe9a2acde2760018dc91f385cf181b3002172140fe7ff2bdf57ae92f0db586c9752145d2ed5af52604bbe4b62d12f17cae51a8db3cab56a1214b89fe1d55295e61ba2104c3208f11eec0c0b563e45dfa0bd029d92da71b923ed607c16392dc2c28f3e0dc58e2e54270ff0a11cfd106307839b992e6fd77dbe7b0527984c907fb670ba8f24eade12010f22941d6da98857549e6c17affd9d8c19b766060508811c65705a06208c8af5397f679931392975124653053ba92a66efe27be764acaefdae358b2228f9b56ae2e399aa3f808fb5d0de5edd3b9e7133c2468f732a59f7064d7ae615f1468051943eca7284a3bff8efb5812e6e1bd4ac2271a089b79fd5c613401eda4baea70a390feaffe0183985e108c1aa8e4f177faa9df5c941de63244a84282ff8dd7ad47611889ecb2d85f2ac009f4c11b7d56420827e008b502a3c138274050c37c27d3539d751159df30dc979d8aa4f52422d9960ea0013e4e53f474f05f360f9dfd9d689017bbb935536d72bd0bb4766649909ae713f5b47acacf3b688785c3abd48f334985a42bcdafdeea8809cbdc2c5223c7474645e015b956c60e0c61482d5c13550794ba19bdfaae821f75747e71672e596610ff807255e93086d68f90746fddc239d4a03da2f69f2dc484fdc5b0ab3e2da27f64ed0f137af649fa013ef667366a61b2378f5d8112dc289b31ef7c995cf137652156c9b2d42c2fe7ddb3a24f6b6395442876754cdf32bba6561 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e34d73df336efa5a0d60ce8b6cbfc615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7f3e2f91d66d516be7278de5a665830f74e371bc411ba86f017d4dcd3c40c9ce295d6b52aca51ae4e73213f535af95bf09d7127eab1eeb54899a36961793ec47b91da7f5643664082c4375f4843b013eb815c8dffcb7f25d441429e746d5aad14093bf3ddd5df655f6a9e7baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd908ee740e57a59b971e4b4a0fba8ef49754a8cfbe0325c8bd6f3fd2a94a6cd4f26687f60ffcb64d85e67d63334e395df5ba4505495cbc8c3a3f4dab68796d6c646775339c29683a2109f2a7c6a79d39a95c876f783af7a636590848ed793b537d1a681cab559a8e7e050cccf88d3bf9b9dccd4d84743c96079e83b097d2979c9dca2b9d9ccf6e1de849976aa1466bf9eb36dffc64478c39945a9b40263de72cd7861c6adcc089a028d8f00208b3e4d7b3a91cc8c209c5e2efd1279bd1cab34126d7d1c0cf913d05d2f6d73d9424cf1176b8617cd4c10940ef9832957585ec45de986e50526faecb28884f659ea34ef5c48fcf24f383fabd9feee8aacba8edf21a6bcfcf6e2a67493c9e9fea16e70c18b79e6ad1e6e895177d7bcc7ca3547f78265e4aa0e5f5056d6013e53ba916bd1348e4c36b9800ff5f847b7383854f692450abdf8232ffbb4fd839d2b532077ee4da65be8cd5d73f9992e03836ca3a623d4de999a56fb00332d1ba8a26d599d0f5a97975814bf8efc9dbc537dec166ae31ca3c55d05ad5d7a53fff1299d396dcafd8bc6e3b97e72a595d294304bef9956edf74887fd1d7bb18da70bfc5bdd59cef6c1cb56f5994b80ff35dedab29e8cf3dc851f1aa5bf2caf5608fe5cd7ec5daa5e15d6a98a33e7224bc6de2bfc79353bc5c4cd46a8ad933a73419f7b117b88f3a53777143546ddf9015ee5e37c33770a8a9a11bc2f38777e51de32b9efa9859d8b4dfb87fc465b574d45e79453c0666e378fa895cf6965eafe35f86fcdb681cc5db260b4327b46c2d0699bedae03965b0a218902eb4680c1b8c3edbf011a396b0dca97d56aad34ee68fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6d00afd91e8b36fd3afc6c1d94a8338ad64dc8f53cab80d73e7dec397755f915c6e6d1fdbf9e94f663cc477cdb5dc94579d73ffd1b647ef4d358c5435d3d0799242b66818a683e8c5652bdb26ce4909f8656ff35cd7f0aed5998d74ffa32df093bcdb3faef3dd3825593b545b4429d787c4c8656d85cac293f6168e1ccb35eb14e3f45be722e1ae82f0948181fac68e3c9d41d85ea77946a54baa91c8ab8f8e4c5b9420617dc0b6d37bd0fa29218f018933a5ad3f14128da6dc760c2c9aceb4bea150546425da732664aa52bd2a82eb63759379a638bc0dd7ff9a7a84e17efdb8df00d6e894a8891dacc375d2fda36eda4f296a02845477ccd484fb5bc539c3b8bea3ed36eed481bedbe76c6417ffb68aea8e10db954057322dcd05f98f84e6f90a5e7f0e32b5f6cb6b992cce82d66a73c6de9572867640343f277e33b16d545d4b2669bd5eadeab7b1aa5c3287d9b08a79c9a5c9b6c93c5165c0e6b8c40e5f7dd0cd2b3b88354c73f2544b5507cee054ed0b4c399d2b6b8df8ecc637e495b4cd0893b744584ae83f3d0bbad531d29ebf88de5f29bfd96aeecbb3aec16265dba0d761c5333af8d74f387a97258cc0ecc39161dd83ffd922f0dc692c9ab09abaa30c54984f9e8cfb332fa6e72ee2ad440d3b92175b3873d9475d9fc25199d6fe75b1db4ed0b86a6823ea57fa839a1884f526948bfeccfad4fd509868236fd5ca7b57952b3c5e76fd4f11c81c3077cb15cdb33633f9006b5d3c67f130c3d78038d7fb4934e4cbe8e44f9a0c737ee48bc96849f360c83f37d7bcc23432264728e0fee4ac896e52ad6a3b776ca7386d617f046abbb52c655e01deb3007af2586b07cd7c81f38333784c2cf77ecf7f3830b6e44d51d7fa40480852b3bb50ffcd2a33585e88e48cfb539ecd99c298ee59fcbd7d7a3bc67d7c3c782d8a96a158dec353ceff276a1586fab624c6d307a5b4dcb323faa9ddce5f289e6d531d6a93be9c28cfc9ec3c489ddc6bd144a0458168e5b5686e92625325a8418565eb6fa0fb7619773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7bb2578e2a42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c4801107d0326eb24c7fd4612bd91275eca20f057c27e10b92e0b27c07a4d621751ef66307ce584708a5a58661838b56e2b2670ead04a9df7cf09bb8c83842dcfe4cfab4a83e75773e57b908feb46bf44013744bfb1d3cf98d34237b29207961d5d5cb43d6a49b17601743c86640ab9cd4a1786448c89e12adf884147e2cf091b66da57883cf36363611e04005be8376fe99c28fbc50092a034fb39abdcc97c6ae0565df82d4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7df119e86b92c407cccf98581bc62ba89228432a4922ee5c47be661dfb543ef26306f5301169a31b054cda1449cc2faaebd04c2b5823f58997defc48f6db37300b0c1c475a866b035639a5bdc4669cde9297d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6b31b8c529b84cb42dd8e2a48fb240c6b703c787590ecaa1f74044b5e295122c0a81c3a71322a2f4c9a33ea67d341a4426d60169acbdf19827759c144a271078582a33541bfa9367b757baef6890cff95d32d68f6c90338a20298b000e9144112dc22f4bb3117a6abf83b86b2b3b9cc244330b97392dfa3202ec7746d081f0a036360abad9d7028ab5bbde47403ca1a7c68a2c1679212ba707663ca412692049d45017f4993beaad79a990bfbb416d3072af8749f7f251dd51ba3c8b80cf34cc21ec923ee2a52ec3c981602c94d668bdc108154429508296805c156f05ae7908310fc176ba241cd35275b4c89e52786665e5798ca71a5eea5a721b51de6a78060a58f1a24da91666fdec925231c8c9f53d2fd270920092f29515dce0a8a2c6ca1e68bda6ea24b29424e22523a7d41773252e044356650aa5aa467b3cdb72be7700d268572d620279ca0668ab514243599de939a85990bc7cb640019bf8271efb7b1d32487b2e912e4f0267fbf197f1e3c4de63ad7455bbb2204db4c5995641892330c5b5140dcf0a8009d135a92352e97584c1f294e9548af9ec348e7408b448b85d234f6ed614834706a0c978ad9a08cc814953b8bbf2bcbd87071b597343629b3745d212111b7230ac9275c037d5e747afe60cbb9b439b06beaf537d6cc80bc1d1ca3db49f53c4a935a0226f37a85b058f32e307cbca9b7c62ba581b351ff5cafb198494d5abc4406e30932355754ab2a38232561319b0081b266b1fc714567305e0b27d3d6cb8457baf9242c598ac29520432fba3c3968c8e81078989380085178489eacb2c10c452079b1c33634df13d82b81da91ac85e43815f262c133075cffab454f50ad6c35410b295a5357e95fbb8a1d80964a40184a19618d2c0b7e13ab5828b60d461e10b41e3274363687cfc5849fe6badfa11821a31c2f724735ca1c4cb365b16ac43cbb24ec865a6dee75b7a6815500072065aaaf7b9af31214ad30ab984c57515a94a67b7391a37044cc22c9976851b19cd975a2c3be0539b213b9032928722029ac59231c90945a9bad4d39ebe623c08da1421d90fcd990bf8f8807b18c99a3799de3068a09912bcda3f5cab1089caa3eccc831f64bef79c538127b152f97946a264f4085c50299601043860d95832d15ed6f06051d12386559acfc5934cf4110827476b32af4498819e3ca252f28b48a96195f0a7c8e01a81d00c9063acc0954337d360b514906504ccce6a54bab7a3624130630a5f93c97af1c1a981b50eab54937251b9e1388842847ec6f4296870b51866c04458152fe3844cd879f335a7a1fc0b04094d2692cbb2f84f4a02b500d38fce69145dac4d0e4339d7978ef6e651c6110154046050b52bf29751c0778bd5e0409a1a2145bc87b1554b5ee209ed03ce01c251f4f39a67e09f2629a8024896c6c59f2e9a2e26523273e337b2b80760db1025f5b21931a82673be930ab5358381241acf46879650c208ce840b48041997500c8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c3a2b61f85f0b10ba790512d6422900db29d542ad96d8b6c0d954205a0d2c74810ec4469bf2b902811e5f5778a4190961853c777514319cab0cc90cc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1d3cd2febe168b1ddf776b954e96085a7d475e3c8cbde68f7c80ffc9fa46b0d4311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = 32f41efca0bab79755ed200aab047a395fce9fabebd21c174b6894f49d4b576fa778917cff6d1507904fada5b3234d17c15d8d2ca1e2af38061283c2c110513958f0a1f416b37866fa0d1d7b386197d02552f50e43934034af43f2db61b3c57401cda202fc6b13376b6b94270f6d28d9a45e367a7fb6a3fbb35411c66992fd3a3e80193b4ce81ed09c985cc5713cd39eabc1832e180a5363a486d3a3cb32b56a515c0ef81221e8252076d85212415d0d8bb62e4e981fc092dd3dffbb241d3443df4fc9e65aec0db1397e4b2300c94db9b25a514b1efd8b309cde4c84564f7efce1033c76cf2f83b1d7e27378701167e4199086c7d5590879850c2c114a6a8367ad045da19e04e0f5b5caa127ea3ce1555abf5b55bb88ec58a20ace7ef8e3e627a847056776588f1f5356580d155b960a839731cd6fabd9dcf944b07f08818720b1bb8b77697bd55d255cffd0ba71c241de4013a5c8d8eb90336a64a99794a9da0bcd8bfdf7549c5a6539ffdd821e18870d4497aae172f0c16b10908c4f49304317567d43e3c567ebe91407541c90f6030520343797f54b96839dbd9b54c5fe6db4a33146e42ea74863034cb78ffd3f35871cf66c791079a77a05c7119fe94c068768c431772ebcfeaa41d71a95f581243c42e1a3c7f5390efbaae0d16e35caecfa8f854313df32a2fabf90fa756a3eb2ece0e8e2cde0bf47f85fff1f3927ce15cf096298271dfdcf2822cde284ee563602da0fca82cd90b03ce8744a52a82f42e8ae6bf477dccfa4f0e3949165c7e8b0328a78d12cf8e9dc96a852fbb4005642c48d70d7360150d5ea284b77e30ae24b8142e1bf89ceaa3ef32eb877721f3d6504ce0c3663cfacd1b74ec92817b2b0d90aaea3ec36f7aea7f1fbfa39fb83fce7411918c3c07fa8d4579277bdf5f06648252cf5b9cdbf979fc139534a508667f075aeffe2b12f0f818ceca7c684151c5777beb7e5ebf9bf2bcb4b06483f6f91ea2841bfd5107a6c12d5d808b31ee9c324a62b8c274e224f7b87059b2d71659900af62596c40c36e1f44092345dcf36cce43cce1310130e1cd4663fd29bc3e6092ad68b351733f6e5157da3d3a2b62d0cabe290c2118311589b11fad11b7d74c15ac5d074d67464f2b1e9e901b7486f7f600d6e45a4a0a6fbb9423b0f7b68cd71b388a0227cd855ed6903373c8f269dc16ad7b02c8605351099036bfa842e6417e114ee3be6991e338f7b66e767348a41fdb174da68ff22135bf267db0d509fc9b8a98335709c7e0d9c6ccb69d9e701d7bf7263e08defc4debe3b09a6f10835fdecf0dff446ec5cc9e949450fe55fcb5d323957b5da26db9797663e9cc0f605797258b3e1d3f5a700eea83eabe1b2c2990d1b6a26ea97361f853c1a250d6e5bc8f5db9da7766722094d9f2699e975de35be0469d98c1274a3dfcdf97f5a3e861e6894736a7c6d85236689ede2c87243059a9494c536ea4cdb08645298ed55b982aad590a739420949b203723684267b16ec9939aac3c2159a32372700adbd4c6e14fc1b0823087c518ce3647b30e9ee9d4038667c5776512b1ad1529cf17f0a70d9da127ecb0f536f668b6ff2476f2f1e204a0dfaa4b83d2b35eb677c588710670df1da6753a3d6e1bc86c89b528ee6365ed85dc0db991b4e5594e74388a1bd1a05770ca93a0e78d96a2431c47371446f04701750369bff390a4dd366e63d4a1b536dde21810d1cd27368e431b4c94096175b41b2e3f3374377de490b31c1b8f36d0485461454a51e88eff8c5e323787b8e5b1a69016d31e4d341280397f9ba87651d9f341eaa1b37aef6130f34484cc1673c4f0ffec892e859de2b4aa0f03be218cce765e34257430e5a8e99a51beb25bbbf5c6ab7a8801aee3533322e06cc282c1ff735db37ede240f47377067424cf56a75a98ae77d47fa1b1e95b6146d730a7e7510182da193b4ae3aedd82a8943494cdc92bc7a069855000e2acbe6018d3d0669c16614d0ab413e43f1062a6be89965f497ffed2a0825d4d455b6fac1120b1b2999af343a672c7a702253436c7adea48087ae99be9cb9cc877ccdf0b21cbeb3b3a5b2897766daf7617cd52088ba160148f9ef21ade71db2faf1535f0bc276ca34b2e62392767e8f8a48f9104b6ce4bdb38fd9a273cd36d15b27f1a9c7f5fa9018917d62c6ea3c9e103a95619dbfff5ea1b38801ed1711777ca7abb7450c0b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 232dbfa6a447dc6de3ed68e1b45742b6e95c723a358525e8e05beb619c5607944c342aeaca5cdeb297bfe3a9dd514aba3df3d867d646cd76a1ed1e76f1e84ee617d4b1ed4367ef7ed003f2bb04f42205f9a05e67435b88095eb48df7e7e41aeb56387d470581580ebc2c8dc55f33b3c30f44e1ef7ffcf43c457a36751dda4404b4157cbefa05c5506dd21694d59939a3aa088dbcae3be66d47df55dafe33c8742abb0cf48e0b2cf4e97e9eecf4eec4b3f54836b4e45b4eebbb43d398a813bccc0d4fcc4e43705084dc892b657765b2529438973f5e3f4c45887452847aa315ba8c811b39254a5c3ee64f668f3fcf2a92e3198d2a9ef89f1fe530aa4cbe3edfab05e19449fe25e755d778a02dae45fff471668eeab9397a0f9b3def26bd0f5e43c23a815c85829775f1d63bc74d8b42ba5f80cdc77de45f862896ff44d475f49ac204c87d2647414a5ae36a094b7fc9f3bfd3496b187592f8eb8168bdffd952306dbc3715ffc579cb3f7a398dd677ba14a3fdbef48057a59a58531b8aef1773735a2761262db0322e390c06f5d479f7cec7c7d00ab13ecfba6455f36bc68642ec9659d7bba40aa692d4d794bc4bf6fe3fbc6e7e711a54be8f5329ac6a9bffa88a54a601cdcd6754b4a3accadb397cacffaf41463c016efd6e2d6d011baf6d833e4abb8dfbf736e08d36278a8125389c3b9994098e760bce50967464493f42de5f358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0ebdedebfe3302677fb73c493a349704333279bf01b6baa8315731a348ded37f83dbaa05e057c26c35d68b5f52f27e5338ae543895dfa4c395fa9d9b8cef83b55db7183d292d3fdcffca0532eb14849aa5f94888e2a3fd33cab3b48df8093742247ac281efe8d7a6b880f983dfba4370e677679568b8d51935e33fbf6550dd3e8e387c3e3176ec9c3cad6a739c6ba5b72fa58801ddca9fd6eeb0d3cd05970653bdf409fb8bd4aa1571bd2cbcfed2cdda9937a499943ce285b32706589c11cb66256e4456f9f5c755b4a09805dd5659127bdcf5466270a5cb73f8fdd0583e80eaa98d340965d6284b63a6f7b39d0c3efedc43e20e4bcb39b99d835e5e14e627fc540239dbe759ad6292fc26b85d46324ed9de8793b385f556a3a3f74bd8ac6ef6a3d4ac418fe09ffcd05e5beaeee7d2c87b9536ad84a7bd547389d08f548031beddb0e37d28dd39e18fc5583bc83695aff0898f8ee9e552d4582989556c9f4df35a00d5e8ab95cbb466b5ba0d8aef007a82a4f948719d2e84e52832365fdb79508b69e45484139b4342df8c391864b80f8d7b9dc8ddcd44640dea986986b81b6fd79aa95663d8ac157ef0add9a24ff4e4ee5522c1df6587d674d6e348fdb3bfdd539995bf0ff22b21026f961b56dba5382537edfa607372ebe317497b85307b61d99da62c9de4dd37246763dc6093af5f4cd0edfd081ba4ce2d6bbdc9695816d7022c590a1687005bd730a07ed6069dd1a7bfa5f5ec743dfcbbab8f6610d55f59ee288ad62da1696a238d8507aac327a9194c5c6d49c823567e00c158e60b845af953539a855d217c5a77599b1783f7488aa860ff3df73b837e4b8d20d6a8fd6b5b16d83a3884f67e9cb7ea6fcd3b8a8d02f951f74aecbfafd599c533df4fa0ccb5e9443914465ef5d839215e9d21fecbd03d8b856d66d3743e997a77f47fd67a847f7bb0ca6b3746f7ca6a233ea575e9d8775c5a7ea497918be7b51ec8d5845daadcecccae9f1ca16d61f9fd67fd9f15c5a3e75b861491771196836ba56c99b25cc5bded00883d5194eefcb8afed14972b72533c7c890d83a5e34f75e0075d2193d386b1456da6a6cca5a474c3790850a71c0e84bc81f5fe21a9fab396b37287a106baee569a7aefd845b49b096f689ba245707647e7fe7defb1fda342c45335ca9e18d9982ecbc38f55d4f9a9c365781999f9eb839de55848d04ab7c9535e3ead8484d44cf46f6959717b0c009938917ad9179d9dbc764746c3cc71fb5b72b4f16049140b5c262ef9b3277e6e50e470e7b6598ac37c7c57dd3d47d548377a4939a0a7886eb7780c667b4339873be5ac23765a05deca7b264978b14952a2dac098da274d3a5ffd8f5b9a891df5560938b9fbb3e3e05e782691bb9c0488a7838a4b4cc6cd3bcbe7ec12d1af108849a2cea79be2da250f029382498919d670022f38be928a341b9783e164567aa87a9055fca176ab4870a2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463d51504bd6b62a44b0c0251afac229ea8359da303066531ee34451fcf796544125f933cd52f9b2a5e72e1a42a45ac9a80730376076cd57a289d5d97e4e1c5826757943471fa4ac0b7dcb737bf95f92f2b94f844b2b26297b2a44dd9013767b8b2cc7c1c8c83583e78f12e60050ea0e45e3453ea86166b70c21b0310059c58e684ade01b18f93440b0292dcacb6c9e3488e235f219c91914302d1495134e9c2b2a3acb6f4357c740aebb4534448bc482a07ace3b2211bc6cbfaa95ba4171f955ff915a1d5b13cf07184bbb230ce99c8a13264d3b98c0ab0986d62ca8e22286ec90029623d0f033bd4c13a26f08120f76aba45a904d01266520206e6a76697254b7120296820d0a0a29f662fb623c34eb282852832c044565860200222524b42cd2c8676cce763e28555b8e86a2c710b47d40a788513d140a41a65bea5cb054b73ca98c3061a39c6276a96269cca4597897c37b25f672c0f3766be5065a05b19b4cccb1a6771421b5cfdb7094c89c48c20cafe814d98d41bb5733aca166e044810704b1f9d632ed279275c802640d2bf754a99367b4a5fc959c8f309aa028ce21057fdd943de716e3f66b76660011ae354ec9475b4452932859d2dac38a853cb1edb09e04a367e02a92e89794a0c4ad866c65f3b4657492d0b575215e7926bf455686393ae7c507b9c8b9062c89b2310725baddeeb8a3079a7301b5be5f463f826ccbc8719e017550734812f1b18da724b99641e5406244a28aad89920731b387b934d02667e86b2051d35ad6820909924551430177f934650b61eae840d952b9f1f8b7e22ac6d6b005013439a01698644b2caf2b205044846d84075b715835a18c5df409f686a78dc675aee4944ecc806339b5cc8d8bc64d24bebf75a74207e60a37787c59c5e6875f61238fb43745e58bf3d2168c844b7c24c4ea2822f3abca76163a40a219d2798a2e1a8c606520c5a622653348a63980e61f52654b385575697d56c86abc5536ad67264a7c3813c1a1eb21442b1c0ff129f93810685a359fb13167e59b2df26c6068b641738b6ab82357c95c0cac43a21f867e005c96e1a4dd240975264606cf8ce8ff7bf0984770a282c969253189cb70cd3440a92c56319c9387733af98cfc8892f0e6736c6b44a0b952934071737a24a3400257e3c1690ec9f76726a327521afea4259d87eb6978d4c77afafb1b9be81cc4ce1197592bc26908c469863aacb89b13b231fcc9669b8accb2a4a61f641ca173dbd2a1494519b77acb0dedc284f068e5ff73bfa9109c1fcbf34b15f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f4319997fe1bdceb9513c2ab34691292bb961ddd202398b99c8f1aeeed7302262359be5b1e53689103246a473549b8274a1753721c621a0f468a6a9080a007287731bb8d99360689fe616c707a9c0c04c919b05a5add406a7d1aaf9d675922439e4224300b18e5d2966a6104cbc5a43786584ec877198dc8317753c6f0109a11c3808a50693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d4f05e20c2cf9102593ce45770da720531cbc50552f1b097a5a96bf291895ad9c0fcbc6a462068eb2ca7f65217f0678d0e25c447161cbd9029ec24845c5c1b2b7832ae41172efb8fabe6543ae3bbde44a0b9f926b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6c8117091523209ca8dd342e3bbc0e8cca579c603daea4e11b06bcdd5be898b825452a28d15261bf9abe00a7eca0474ac4c92b0938aa2a00854f3a665ea56169b3c572187ec88945d6c9637b4a8f91249b8614e9647760eb68d2c08c21f390e36370cf30ca0bf0b5c48f7287c822026e30850754b51682a0ec016f4fa0773b642d4c5481502bc9f023ddffb199fd241f3c977a9522de7f61eef4b0ad3166515697ec9ec5ea87796dc6a24da4939e8b5af7fb191f861abd3850e4ecb1f8b819ddfe605ed6a113ae4075ba67414b4690f59b2a6121928eb21c4d5cbbb4551d2c00fde22b537522663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef99499c1b006a0ec2c299c41c3f728c3bb7848957fb2bbbcd05b65233b89a2b1b16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = 13061f9c915937c0e1ec0a9573d1e5cfec9b9db980f404000206aecf2f2092abecdcf46a82a342db12ea41d20a231e64182fbf8799220966d5d5906546ea40a2d9a5d431f67784ff2c041a70cf20b03ec219387419a5d5b85e0df0b816bbc36204f9f2a9578ab785135a65c0d07c5d5cdbcea40c8cd91d552418ea8d3c0ae467701dcc82ccb1b25c96eb14112a09fb693d0077228b36ebbd49e791a00c87e4cf76844b13caed08488239aaf586a13df492c9d0d9ffeacd66441568cdf84c7a86ab83c38441ac585c6a71fdd79ac0de031d18ab0ef1f133fab18521c5a439c9f338c4e7493290e98c7352c0708e6b576a05fb0def5b757ed0a51346c2472911029bdc595fc1afdcac39d3d6db818ef8a7713013b7db2eed84d1de37258c541397d7ed5c37b63563736f2d0924704e02c3d457deccb3d68964e6e91ae519199291c4fcf73a6a3bfd87321937cd8955ae5ac14ae12638781cdb20a12b199cdda764378839dd778a1efd6dcfefa2607d7479ed80918a067f6cb198d20883b876c57756accdbb13095b848411b5339b121530f9237dce7a210146608513accb3f377a753a90dab9c9559fbbcb214b3f13f01db9d578370d47a484f60424a33cd0edbe460b5f399dd64f6759a8db56013f2292aae64f7372c89e8fcd186c17cc18ad490b78115904bf8e13648ac764dde042ef51b082928a1db8ee45d344a70dc01055d38ceb21d81edbcdea93ec2046bcebdb07ce89a672afff73b97e76415d1c2b8502653cadf4e0604fb62f6a448e0fbc6355c1d97a8f16852c7b164b3b77c7d8ae594b40300ae124ea63e398b1982695810c949c316654f8861269e79ae7043e3c79c81337663d1f36c8d62925fdce17782ebd5250ed6479a2ed3a8619b46937d7a01864a7bfcaf5eab26806613208c1117dd4fdbb2832d941d292d20d5b96ddbb1317f06a64671857cf4b9fc78d5593108db79db32cd14da3454fe3cedbdc44545bf72ac79d5ab6e1c95eed4ac2ae27c379c9e9e763b263d30ba070b3bcee5d1479a1af464f344f59c1e9a187dd28a722ff5f31738a1b45f63bb82c119c4934eb30b47deb53d77c18d9592f98c90454ff03489889d65b551dd06154a5edf007d876b28cc8b2713afd7d952d53dc13d46677a3c846a4568fed5a1685112d20f8905e333bcb2d962ae0abf9f2868acdae7b7f6e3132ba9193ebab674437e0bf85e37811473bf07113d7120577c956d484f2d5e828db5cbb3949998f16b2a0cd91323f709fe8e7255dda601dcc3a4a41750e622f9712f4583f325a7c4e4977aad6406884210789c0a6c891165f67c55eabf3d2a1bebdee598ead19754fcaefae0f5f656caa3446455e04c95403867657bbaf6c0044383c6af8b1041d322799940debf0b110f6ca7828a53a7aa6bd0d7a31192be03120c61543c51459d2a86737f0d1fc4d195bfb14d80039dbc2317b5223283cb282696cd88d08e3d1db6c310337f225e9fd3c1dc76eae923f19bfba306755115029e26a9240fc722998d89cccc7bb176d72bdeec70756aae129a7b9e2d6f4a83ec497cc0a6fa1f27aed10f5b90eb58be3deb3662f60bb2dbb704379d45eb57f76cdf88189eb67bfd072ad751d48d3c5b7162379464da0249bb39b50b58c479888d7826fada02cedf7a0be759b5348d0ee76a7c95f697fa52a887aee6cb0f7e80934d938ae8b0a017891f1e3aaaa24360e08c80706a28208e5ddb1c53ea748adfb05aaff3febc468c9aca5aee9047c3a63151d4e1b8f97957092b2453f3e777c42fa218b31db17accf707482aa9f93b3bfdde8c7427437d21201f3de3bbf703a98d694f50e75a4be82e1b9ac2626c384065e40ff1a6d43f194efa0633dbf91b531241686be479efee669f96d10434c33129e7010eef00e4f97f05619b502f180c1619f8286f07a6c978676b4026e8cb62b42f564d34f5509abdf230f6bf3b84ba44acb9f496d2409680dcb4343b36663fc7b9384f0d021a92d4cb1ac48ac62f31132d0a12ba9d63378474ca52cc3c70f08bf46efcc24b0da6b476c427b19e2c51802c93d34f33d6d70979bc8b485a8c932fd015803e0540fab60ddadba357e2b156d22e84f261b26f6f77050c97389531a6d66a17d0e9e2e0fdfcc7c3e6209634911ac774727eae38a716a978a8005c8be1c1c6717369aeab55dabb98b0f6d701e5df14c489597ee687855db833219 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7934a9fabc835bf9a77bc8d7342f51dbbdd876e5500d2c59f07485ee0ebc9359e1a336acde65f7dd166476daed1aa558cd88cd7cde7ce189e958e851991867c15f5c957fa953c8b04a83de2e23fc6c26811cb86f3244f29f4caa2aeacd2e3c840e97b8f28d5b94d7317b08354bcab64887a4e6a98ffe9da7544562ceabbcce6489c6e8534119c9589c405d7a96df3f30094a459549b6f47d78f3ddefc918df049464b0a969eb84f419147c8b39b8065a769e5dda17cbf5df5ea699b69d54ba460d33ac6a69659178f9b7a578d1bf4bff786cef9963bfa6eadddfdf9a0cb1c159865a344a0e36879c67852d05dbca08a46f7fa4a71cd27def83de5bcb21a8d8f2635bd764d915c5485ac7d358dbd1798fb12acb4427cffb036d5874ffbd0da59a668d75136cbe164e8cca1ae1386aad43b5fe3c5ac97f36bc7f648809cf60643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc70d7318ae65e7ae657e0f77c1e683beccc956d973c86f4e95a7f4ff9275c1bafbb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab47d9d217dec2a943d5bfbb3d384a7e83a77949d5302be704cf49992077b1a0df14f3394717c9abaae73124dd4fe3f5edb797a30155d0d3aee4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9326fe705613705628458be5f5fb333087cb4b967a61a994cbefd5d4d19ceb8b6f898a03fcc454a57e264722897d5dd7ee33cf495ca857e2af34af6ec77083ba9b88d342d7cfdff8b7ed1f57b79cad028ee3a3238510c5683c3a8c396986ed49fb022fc16e34a7249691ea7a931c54d880ae731746c1f3855bc734e4fe3484d85b5e2586b6231b4bcf27831ea7b5717da815795f43f9db221fb235f5959faf53db86e92bdbe1d5ee6399e4dc5ecda15d98c3b4cdf89f07839f7738abb3f81d45aa0a9ca1d349a64e89f46c2c77712f7f1e1cc74db8ab7ea7b0e60a9dc0e45443c3dca656cd6a8897ac1d5bdb5eb02179936f04374554a52a9f710f2a70972479463af859736c2fe4359a474939ac3532bf90609dbc3896db5615abfb2ae3288e4c01048bb93c9725c7c3b0547921975766a97e29e5f9e4d8a090c36820ebdfec43f77cc679cd4a51f7dad5f204bff20acf63ec403ac7ccaba5ea8fce66c545abfce8734843f7507f4e77e68137967da765e5e4cf70ce79838839721bf3a14ca5f08517ed6b3a555cf6fd96e7736a583f4407f7aec9f1caa340d4bb788d63645dfbf6226f9dff9afc52df3bfee95caa7756f1884a0ddf63039c37f84e5e83d4908507c1b17a7308cb329e8f9c86953422b8b2f1786a4b86b98085e25533925867fa02bbf2ad845632f859ebdff3e1245ac3533d369f46316a3cc1ac58b4e638669f859557e71ded5dd7a76bf8e93901eb7f411e4175ac45e0b35109ac57be844c52e3ea7bb6da2403dff0e4558134fc03fdf0ec86af106836b3dba8071bb8e8574fe02d8100a8fe55f4b0dcb7f52154da2aea68c58bf03ade4b21a56274a7feccac7eee4ec4b26cbe2c973508fecdf4f6e80784d6ccd3c8c61e85451783526ff48583db1a1ca7972bd1766b914e83520bcc82131c5e5a73ff88fad70ef636d02752ca06b94e0fdee6f757022cefe4e488401f3d097993f1959ed8076c05aee91b1ad5774c5a2d6ab94eab91b1cbbab07b8027fb577318f0f1a6d9146e31833bad67d888aa29bd69169d8957a5cb8c3a14b54d3f88e54108904ffe5d1f73ca9a635fe133eeaaee8cf3a473fe7492a3636d85c7dea43a7aa68c4f3f24c2a2e88f2bf5568d89de522ffa27aa412474f2ea78bebfeb6038db3ff65881bce84496e65d82f5c319ddf17b5b5e299b570b038f750f38a264b00da749cea6ae22bba8bd3e455223f894d79d23e73c492857d22a6f64bae60c774f8b24a8b14ca8066e9231347464bfff06bcfa9676dedaecebd76752470dba35789c0896897f2bb1f0c88c0b875952c9a352ac4d78b69c55687015544066463da9edb1a3a8481d6bc89ff3b9590b94e03aacf5cdc12f4d4cd51aaf3d696c541581020e5a550a455a38d42c73627c7a41493863658e647d3dc90c6d73b168fe32cf75cc1f755a287f967a7c6c377aacfabb585ff510ca45061f8b60c80e77b5c6ccfab6f463a63c069276c9321d8c961802a956f0b8f41307a73b5b4ea33828d1bab555c02616115f890ae7b1c5e6061a484825a448452bb26fb9b13d9bc002e6798d54238125477bc01babe0ec7753fc8c8c959916f16206a7ca31c7b121724e05bb5d71c648fea759a5d2b58a257e728230c2ea779ec4c55f2319cbf9cffeeb1f285a9fb0d4a391386ce69bbb6e37a548246d1061494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e53a2766642992881a2f1c8b7454586cb3822c125af4d70b15ccc546843100b1443e365cf31680656879f00e640692b94361286104c79af9c1cb2b98f01e3b9480c5b0af0988dc7bebb33bb3ad87cdbe09828a25f17fb323bd17a11ab961c236eeab89cd7c3030f4b437c09aec5f461afe64e1939c93081b44c8440f7b070fe982c16ccbc99fb0a8332739b641b326cc689c51c7ee33003a277c41c2a05676620eb9806ea6f53c2060f13a75ff67b7d1b4229443ecc4023c84293f3cc58c60a1bc00a3d1ad31aa88aa6d2923643585d39e16e5c8bc5e650a578d60584bc24c2fa2aad7b2cd9c99ffee6033353b60f506b95927dad7ab997868119b5976f561007b51aca6b36b08b03ae40a9dcdc19ffb776304bbe7d3aca167753634969cc57c48704a19a22416d2cb658e75ac2d428aaf9a13e6693e4d94df1f2a6559a4fdd16354c77129d32bdc3fa136e180d66842fd2a9540c63ae7412acb67b788936066af5b7fc44409a77a27017c9b883b705caa371b831c7195abc01530a97728708661d343cbca7ab7268b36294b2efd96f87a298092684b02569ab5911f4825826362414fa2f2b955f6a318bfeb18b12d058e4926ca973248d162164acb5b7a8a7641c9557a8a0fab208ac2744810397cc049ef46756e4d14a884745e73454e1d675c3743a5dc2546c424735813ab05353cf65b604ea3e44d8828c7a3ac9851848090b0639934d9b19ca7630844003a944238876966a62a87218714a4b3f89638a064846fc4163d03341840091d75b25dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae58012f2c3938c40cfe1281aa439486d5791e745892eb36905cb142a5c718f456b74ab213f4ac50cc000cfac943c60c3de626080b525c52051ea231f18dc126eb1c6fb76232d5722cee0c9e458c09a38c35ad64959bc64ff252358a5cb1b07384288b457ab15651935a99072f12336e14882a2d0b6f918933ca0574b49b214ba4018ca4b1373cc0f007b683a9a44f842610106de16cf202bcf0896c9506855bb4849beb06289b72041c75512e152183242a5162678d10d870aa888e218ae969c13b024729c7acd818971e598e495902ce92d29c73d355bc44eb544ac760c0cd58ad8157ff242963ae3cab5bc37b9c78ede033c210c59e20245fdcb51f7ca9588359e2264118ce4057dd7c6ade4bffbcbcba5f9433314cbea9309a0d86a15bb6f753abdc47149f6bb0eb339734aa1638fcc633244559a08af3c4b15e6bc8cdc63398165acb51925c7141cea32773fe5b0a64075d66c653e750cf42866255a9bf7d4b66c488f774193ce9b35ce52a164bbcc41f7b6779a9b35127ba7087a4b673096bba4048410778b18270674af334bb92475ce2787bf9a08b587a6d48845e44c6e04a254425ccb59b5972fb3a57cdb02f5100d45b43b76140c6047bc5ee59fb6e012660138d7c107285a2d461b20f1d49e1c206ffb28be65e26154a64df73358dbb49b77258fc45a15b9a80144099be67b76fd60b7e01518074b766211132e157efd507b5970c862d5cb870751da46ae460416eed595a74724152ba84229905880cb682cbe477995437125fcc23677c25fde14533c6aac694206aec917162b4efb61a1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d7872a694881916016c1af8abe353cd1ae2263cf417c013cf46212b3d5720af335d40b646a794ae602b5345300e30f4812e295f3cf07c2117cef1c591cb9a350ffcb718c64b0d76165e9a719ffb75f46b861f968eead3373c3cbcd6a983c9270fee433b2970b6f0947b8ce46fcad6518d5042d109ba53d324b9f657182bb110961e96a8b34c5a4b808840de8b71d0d87a510944a9973df9a900d9a6c272a61bee2200b4c80aa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516aa14ea531df0a7f93225de1c75ace0d2692bc750b1b538cfd0d860ae9c5a8c13faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = 67f0df1e6668d5a7bc8163a41d22f232639aca9455710213efffeabb29dd83664c4b50d538eda46647c9c16aaaa70b38270eea8b9c03b39344549b46997f519eb1b453047bd5c07bb496da5e22944d63dfb98c8923d9cefeb98f301f4a1ebb116e827ab354d3c5d64df0a46fc19cf47d7377e092f020f4d50399bec12f86a1207078d68e6ad4141d38f28ae3b78c0882d8661d87c8b1f681cc49dbf4ea9b46201de47048799ca96bb1759a242ccfaaf3088a4b462df9ef13c9e087ed63c2c89d12a130f3446bd42825fdb07e49de847968d72084dbcd79afb01f1db4f06829e822308dc51b47f85bfc90be5ef1056cf7889ea7d85952a881e6ac6f5453b83d731631c0ff615f2a45fc7f4e9493614afcf2dbe9f2f3d7f4dd706dd220bb3ac8c15ece45b3669fe962833f21477281abcd372dc2a1fba3e3867b382e9ccb47d39706a46ee2b04865d4f1339ad30a719ed0179c73a433b726093d9b77a0b63102bcc49fbb1b34a2be964f5b4c23f7b02d5f73aab5fee8fc25221cea8e4dfd4280a14c4f9ff4688a924ab533f9aa4b5bfbdb84d4a7e8d4ed59e0ca81e95b8c6f655c9e46a17f2e9159c261a39b32d3305fe64938c6610e93e1fc5c18790179e40c6559553a4cdb5b93f61cd9a4cfddffd81191c7a48800f4dd67228d13d2ef61b0652cefbb1ed9b6f0d1994cf08fccdaa4513652e1f6665efc38b621e2dfe238a6cf7c2dc88413e376be6eeab6b0b19545c6f41fdb7bd8abf3cab612344009f35592a5757678594f8626124a039bc16da995bed5129f4c10b1a2b490f62e1521fd47077903b87d10b69c1cccb654ecb9bab4930796bc45506cd0ca8304f313e9d43d84bd485544fe068f3f18e4f480f6ef0346f6e0f465c90bdaca8144d5261a1ff817bbc139f094f8c486167d7bf582f0929f9dfcd8577e0fbaa4b058ae158e7dd90f57269c30e73c18073ba8c21abd7785d522d9c0a6367d37d8d9808b84f05cfdbd79fc8eb1e28a42ce2a2a9d547995c541033517da3a7a8cc0efcd1cfecdf389469167d2ab323d337751828c87d6aa4631049b10d3159f662ecfaba93c3d890d058b1023cf415eb03e0886e86826fc6aea973cf32fe7efb5e39a5ce40101e0cd8e70ce92787aa9b4e0387f6765638f046b1d7fed2b4ed3c8fb0947965bd1dbba5aacd8d9d3a6fdc3e600372f404ea5013f75dab1cfc25436bc7cec331b0e462d84fd60129de1767ee0d4664682105b504e09c79dc4122d364baa14d464b8da59dfb3afa71f380c77feaa6e14045dea85a8e58a6e354498719f488c6a42ce369d25be4fe6d081b8a0ea3625ac59c41c388749de1994656990743277ffe6f19d938387970f3d9004e12799fb85a6bdbd206eec14b3ee6afc5b10622c8d99b642bb08ccf840197a77cb6d3af99d36feb114f2e619996a00ab57b9f44d56cad1c8cdb2584d9019114e635041cc65bdf6917795cf117eefa49d667f9788cfb83ec2f2eb1cf5921937c0e65ca4c2b254090834a8fe9f80960964ce84c0589e4de68c214f982091ab163574e8c1b005c655fc993f552b02c0576ba8be57c79ca9692dfce5a2cb72e3114ea9c7d4b21f94bb54cb4ed54e798a95cb7898fa62f0f594133254522b1e0c2b6a45a391f63483d66fabd227983ff3b178b74ceefd9cf41d1acca4c20dc1cedba9cdfbfab63d73a49e077f464137b5727b7aaf91521a66cfa4696f786f5463fd872e923fa180dd4827be09abead47e532583d465dca6937544d93e131b6f33924bbf402f853704b7fee75c9865f4ea022d1487c8c690c5a864f45ddb378001f31076b3c89be009f27e01a6582ed3bf8f8ff5d753ac7398691c6679dc4e663bb6fbe02b2ed06a91a8f95b940754818dc8c16f74333f67771e78134243599b76a6dc5e4c4028de18b6bae67f8ca8a4d799da73721310274b1566d79f5e3f9b04ad3724ca0ec8a6767f4e65dec7394a000f5320945a530317b87161405ce3817f647a99faa6d231035c4e2d252c3d49ac827d435c774f245c801daa956c6627208290fe57d7b97c913885fe0fba2d396139a1a56775b8cf7bc9bc02ea6acbb62561da17457d455d72c44edfae372dc3219100601181ed4e00c7ef58b16f0ada67033b83e73769b303061f68871eda434540beb6aa0dae4d44b4dcb1f677846111e7c939b67e72858f9b20798ac159669c85c279cdd11963f0986b86 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 46f47851efb9aa4a6d21aef5be5880610fc278b6f95da7a4ffe855525f9f17d83b359bf43f2a622f353eb6138cc648df8ad3340d7575e865a6cfd34bf473a3da8b9fca6ecd921452d09b320add41d77ef576c573b094f2725e60b99ea3380f68478d78f5464d7e5b84b3a3793f0c7cb3ada13df37b9763cfbf054c769bee66bdde8366b40635ef812c5d428853d1fddf7bd58a8e34827556ec1336c2ac6a39783a35d849aa9a847f3705dce0b95f617bc7aebf8c0506c16ea3ce89aaa28b9f52f1fff8d0fca732289d05d9395133a82d8cb76ecfd23934f73b39cb52b5a846f338b96c5b6f3acb41d7f65a0c5b13094232fd5943d58875ba7c2a6889f27ed7d325ad1c9eda0b3c9e8938e69d54d194bbb90f87e796856f9888e58a53feff84ffbfd5acaf59521e46ef449cdbebe8d5a1b4435d0761d0448d84fef01b5d6a0b0a498027fd05e88d7d87b42054680cda74a396d27aa4c3c5193fb1a893bfcf722d55ab9b94dd99cc81418e53b38334529f649eb99825bb4b1957326c4791a38ff952cdab6757ff494ec20c23926c3c331f24c360f8e978cf791f03e81c2c489b68c923b65d8ee6bd2e6ede6ae97fb87ebab50ebc1b4f935f38a0fd43ae2f9af4d8fc3f6e15c2c6bc800b73ccd8f9ec592452484b44e7bfa62498e0655f6182a5d349c78c7d68e80b1676b529eeb6065c50596232b9566e4b8f0635a7d729f7f8eb8572f6fd57996ddf66cfee2e47dc3451e96cd34d6b9145ccdd30d9e5d67becce3674073eff8bc4d75519ec9dbd306a59def5336e2108fd1b7b6ccc8980da28a3498e51130ddd5746feb163a36f0e6d610df1be1fb6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f65ed7ee6e6a300edecbbc840af66e747df79beaa71dea5318aa3cb3c4c63c4b9ee0fc6dd6dd6abf10bf5d2bd78dea4e3f2bdbfd99e6577c4cc9e1bdc3336f5a5fb705e94babced659f1ff23458652aae94012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f23adad01e4b918f9b442effde6e7089c8b9d97fb70e8df7d754d2b75d58347b56074ba33fc9e998e5a559d46622f5423808c82373e7767a32e487fae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abd0febe00c7bbc5b5b25a1ced8544f4123c98fb43d31853fd324bbc743d342224ba009e9849d65e1d08a77e07d07dfe6ce6f64fc71374eefb66bf9c742f5e8f2f3dc48008f752c8ec4ce7bf42593b990980da4d62f96a7178258f32efb90e96f41c04b7b54d57bf57d0a14db6c1bd8e4e8a6bf1dbeeef738f51ca9bebace9b95becc623704a7cf4560d9f48b4cdd0f4a5d8fd6320457670db92c7a437174359371dd22da4600c66f96d336a52e988898e8ca20f82d4767010a7abe08ebb686fd48b6be63da385d7c5cb145ed8edbd33996ddc171fa1bd563b22adbc7b94c9719a75bf3b3e02143bf04a7e3dabd070c4b449cb9595aea8bbf871e5a5e78bbcb611b466a8677905443ac0ae601a9664c5f54f36dcc1ddf35381f586b4aa4567ddfbe72de86df8493b3d479f4c72abfd49a6666e807be3fd77c3b73872209ef18b48984ef374baccd156f94ed69ee33c28dc9ddd67dcf4d1749e90cb8dcc8d54eb78a986844d33abe3432f863cba79cbbadcfe5463bc3cdeb0f23d7140d56a0e07686917471447f1c76847dce7b86337a585ae46da0c664e9d444154ebcf3f76c7d8906bd336ee07452626853098444339824dc5a82d0b515164882c99851c189de19fcc955c9fc54cd4157ec4e4f7cc8d16aa74d83396d882653e491273fe87f68f36bcdabbe568f1a5bea9f8d7c21a57e81d3b4ffbccd02a5fe3774e54c4de6063af2cd48c73f8fd1d2cc893c3543457fe2a99fa05d566b99d369f996dbbd9c1d8d542d3adf1d2f4619d89826dc45f431fbd2f6d7e9208dc75bc9cd8b8d3ae3a749f539165dbfbacbad05a2787daca403c83baa258b7e816eae5eeeb5d255b12d6cfc475daf458a4b0a37c69cc8774bc4f51979a130f92ec6c8d7193c5b63df1b55f807aa78c2c26cf4e5cffe6236d2f3ccf5273bd3d0af753498b5b78ee18996098cb3f593947ffdd5a938ff3b286e9eb484bac5561bc7ca8a22fe3660ea461538b24dd7b47b3ae365fdd9d9171d1fc6308f0c7b2015fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff140f77a87e44960e6fc73cf170991bc57fde0c406e432253a2aee4b0beb4d26e0194601fa576cd89a5bca45e690833592b874d3b3cf303475f1140a0fab6129296c51b4a5b30650b8c26b5e67100837d011c2aa7881bfed806f308bf2f99118565cc85323410abc6e34520b818b49b6369dca3a1ac2776f75142b84c76a43223fe2b7f78544191ab4f0b9316c3b4495514118c63c1f9691ed6ec30670945da0a92052a7d2d11c4e0f8be14b867d4708f6fb4569b6081ba685c78e2c835e0bc29bb416db14cfdf3c98e8a4aa7161859e2cf74277a4c4731224c0649a01abcf92ea723784ffc290775282c256d433a64b705899398aca7e084ab6958c801b27fe8b39ff4bfbb1aac410421c50aa911706790d3c350b6126cf9242e33a359e21e4b72561f1368c3d2265b710bf0d6acee3a5286f51dbf16c471327612ebafcbcc5e22a5b5196a06336968976a9308c075816727997b7d52e34b648b8bdbf229aa4925b3e5167dd1caf619bf0d620540f29f6e77091c4b430e708d01ec9e2e0ca44e766c7643084af17722488f4786a720ec6dc4765e0f558a7a9c449f04333476262d65c4ba175a0e2bb29b524f8465a73436bdf6494578020a425149f3cc0c9b474d5eea98ab529aa1c97a84b54c064c8902153703618e5b99122d4402681a9c72258137b94091382888b4636ca983c79a944a4ba0169a730f7401d58196dc193742fc4d20eca71ad359987086aba19ffb05c0e09a0a8581844774b12beb3692e055df16b67706902d625590037997a3beb105931afa84b5fa389fe2b2bb2b5f521169f18b012d17a5ad203e2508958954b8fda5956bda2126503f34c571457056b333c9dd265bd9d4a9ea601620454bf020120d5a0e99f837cce92e20865dd7870a1ae12f1da8b369c814fcf63a9fd830c4827f6b151449879c4ba9691e68a02aeb89f362a9bd57909c3ac1e064780fa1c74ba21daa4b6684bb64eb108987b18be7683924e3202d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e51222c4df502c8415089255e8a095efaa822b892b2a0a17a146216282991833338553c8bb4947d892923010711084a19435b5c3f6a6af7f89457ac8a5ea4679fa2921692c8af459ad8cb22ec187dffc3425d88b6396cb7fb627f5fc718752658a5fc92539668c7327b90b26572fa8bfcf705f11422382079e2333af6b51e65310751343764bcaf5a981a260109986b5c29d2691f4a981d391175a21e16a13dd2501f5a256bb86169c63ba737296a5bacc65781b8ce07b4b8f28b173b42f802baf5f235bc06c9d752351980a72b52250269ad66a098fc9b68ad57c698a014b9d1c278f3559b361e3b8ba2d690c5380765de0b2d0e3c63792c7f9c8122b297bb8cb8381d6780505c253399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa5529fd8cb5215893bec6a64201629031b16a8957623b0619b33c6b90c78f4e21f8ffb94d1a6648d330d91096bc87093417b1ba6e14eef17ccf3923a84328b5b60adca0c4348d9198262b27fe56eff73566bb5123d7ca987a26fe9a00d41a2405fe31af48baa3a5249e4c6a638985669d576dc7c9ba575380e959ef93c2dc5dc15ca87cf3f98675eaa87eb5a51cc3450b946b810d05d94a815376868c5d9594fd02891637ff517a6597a1272b7c9933c544793ad167b1537b478ee3a20c8b874f5fc95aa46851fb1610453583b23c280838573770609344f14c4cc1da33720b3257a53a8e58c1c0ee500a3e4781a2cafea727ff3b86ccbeb9fb63b0f215ab297ecb1485589766ca828332942eb9c4037bd76aa1fd24160febb8dc499c486a6125c137b77597317f06323c901ecb7b17b75180c71c6b1646751f2522f1a7d13cb7dbe0ab46385aa94b84acb565f32470fe75b7f9c876287f2ad5b0b52e4b5aac9a43eb17b207943ace482b46123652f7460cc64427710603a8307ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc37591bc1a926d57c0ddb5b52024ac3861785b6134ad8c067c5e9a47ea96f57b40426697e12846bfde94af1b27ae4305edb932b79ab745abcc265b8c7a37063ddbcc972c26864269ee557785690ae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0e0013ff7eb7b8266ee94659f3372f5981ce1d87584cb1f0e80da2c0c95c16b4ea2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = c4285bb585926557c351391f42e7b83e54b65b3f0b324cb0e7ea76ca221109ece200cee8184c5b603ceb8bc5af9ffe39bc281953379516e808dc913990e3bd0561c868cfa85e4922bd862021c97a437cf2c33c64703c7c7e637e000601e061261bbd710f3032c129dd435a306de39a48ac1ad1d751429f7ddf3c166e646324a01441a855ca73d5be1f80749414bf383b0f9cc8359a8c254333f9a84b9527c2984d0c920f17fada4d49f003b64a9331e542fb2e846eeffd59127bccf394c463124ba68b43d7f7daa9a9157c72081fafffedef56afe344e1ddaa5f9af8ac7fc52730d49daaa0bb710972337eef7df81fdda22781afd9a1849f4a58b194febb65c6803d072f4b1bddc29f3bdc5a536dcc7096a37a14596c3f6435d8793a5c0c7ddd45a17a9aac7da2f1f742eb23e52736ed7f19a082741b46e635625c0e270c0ec06d60534bb7334b57b6ebcfdeb0ea6078a775d23d6937d601d44f3b3ee5140356616fd2eb904a76e5ff7cd98d70281e87d70c108f71a61a914c224f421d86db3db59bb51a0b766d79258134c0fec752c29075b4dcf5d5980c8dc9a618defacfb44cf5bc4ef1d691bf3ecd77cbdaf34be16322737932cc105ec490024e45c4d8f558b45f8d6965554d62ef1cb9ee69687f2a6184c54f22d23e2944ff140b83b967081ea995a7fd99b155e9d75961dcfbb4f04bfd42727e0cd66abf9b6f97f7b2adb0fed4032208b62eb3af3aeda3b3560f50bb29097c57ce059f786480cafb27eb51e1ee87f82b12e4ad4929b184e73673ed1ff8a58ea812099fb1c6af044021d0ec5921a25fc7f6c0dfb7ac01ba481cfa14ced4ae4a74af863b1d255543fb80ad53a67a04333670550fba396eda43812f7512c2a72e69d3599dbc247893429824f88b5c9acfa3d6c789ef487a530af12dc10f90cb95511020df2e402ee5fcd9d5acf7a2bbada0cb523a4b6c6a659a5ac38df531bc83ba54c5c1c3d9c4bc88df83261df4e048b14751847dbaa1ed6d3820cc6c4af84bb857a02db6c7db734a3d067076802620e76d7e60a0c7459061bce780b844ffdafafdf7877b1775f53cd9a44e2446fe96a9a9dfd3d1476b32dc07f1ba8a767c0398f7552f0ab5f23a77982e35290ad2e85caf6ccbe5396b3fa02c01a62572260c555fad2b21637193c266cdcefc22f7dd3469cec1647c9d5969f2863f4feb9ba753c8f91f35d94aa6a0f188ae11bcbaa872347adf646eeeaa9e67ebf44689e29f00fdfb7b71a60a5df52a3154c14f67f7893e6fdbf8035d919163b898d71c0610fddef4e7ec1d4e10357a2c6464e81c3e1eb2b7861c47f8f5770685c781167c96e03e82fe0871917a92d65d281803adae1eff3e8d43f0acfa0faf6853fa32c507990cf811e9a26886ce4c4662d38331a91623348129a8042d7bd92aa194e4543584f6d19fb302f408117e49b4ee623d3971bfb61b96ccdfb9ced039f300ed0eb75a2a8a5f22cf2cae4c9ce8a0d5b74a12fa08824744f3417e74fe1871917aae250f4544e7199820498a42a38f9656ece553229c75d8014c4d09257c5982a6bece62e102c99b24702cd5da41e8cab445ed69e96f811467d2bafe55fa6ab14031606ef8192de2cb71aead3a51cbba7b6ea2b69863a12884b94d2e1e7953aa5632b6ecc3d6aa5893c0f501c67f1e1b92e794a11167e4814071aa227cc66fb817568f84ddfd7bd94552545fd84030effe4c42b9bc0699574279f6c38146055123ad5e70ebed2116b625610dd0baa82487ccd85db7a69543cf0ebbcc87c0b96074d31697b16ee31d9237df7d0d7d9e7d0fa9f5a5ff615735da5fc38da1f5a1a854d98b3d4bdf0a0afb924ccf66039f9f8629efd571efe59cc467a322a3b71a1240398abc7164be61df0dd9a99adf7759ad1380d4782fd6987224130a50064119b16b551c3773fe11843f61b979ca171174ecd7e9885d64648f9288269ac2523fde655411c4e0fba8d123e70e2bd195a0f2c98946c6ee4f37be5dfc44cc002119d6d5aa21b9cd9a2f54acbb5fdcb3d050901f037ea9ac27a32f7f090df665362b59407aeaeb7a80c9e84e5e5939d9e105901862206becf2326db1005509177aa92e8dfee8302758edd739d829046192d0037ad9de1c6924a91e0048e8a4465c9342d7f07c5b7286887b19b775c5facc4b1cd6fedfd9c8bcc3d46a263f1156df776065481b3f9bb004a888c80d5b38 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8757f52c693a0d7cd6ab76d71b13517e1c45abb370d26aba3fc3e642ae70b365c5f6235d1fd688d81c72716a39225fdd228a7bd6aec48ff445c47489b91e6b7dae4d3ea78b20a7b5e579c5691e87a2aa8fca0d55761ed03fb9bead185ba9e7939f247bf1757ea66a4392095eaa0f39a3c67a8cb7d186047d9a7bd6b8887faf0eba8e55631abdd3934c88ddfbd5f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad07fee6f464fc443fd72e3c67140e5b1339512419b4daa8c87f5a8bff58e964a8ab8b2de94333df9527a10b6d4df6275e1ffe8fe54a57d7544402134ab788d2333897d4769ac33d93f9b951d735b5623452ca0f70a0896ed3b8ebf129ee451a4a67a4542556af79fe690a8f3610febfcff663878f7df93bcd894ac8c996be6e1af9df7dccd459b9de46acc9f8d43bc8fd01d4de5785845ff4b0ddc8e84afc5e52b7fe8a9d93669a9eb21da101bee5934ebdd416e2aabe955b1752810764e7b68d8a7d4a6154fadf78e08bbff9e406cd10b6527a39a6b56d68685b5e802cc25614492dbb6e06caf160e930733956e8bf9ab9a8ed4b477cd4eab880e56eb81eb278f540ad2d4a996b32fd06b8bfcb772976dcf61f5fe26f619906f95db6f8faf491ddefca3cff85902350d53cd649339f31ea3ab764b9080ebd657e94fb2738378ec1357db8d5ccb61dd74c5f666ffea7b0714c469c58d3117f35599c998349b5be7ab9e9dc6f01f9f85939392714e1ee2490f16c54ba77fee03b710978760ba6f319bab3c2fc67cdacfe9d5ce53a97e7826bc4c3d6c7445cd51b6ea06a2c87a22d7a20754e9d87f5ba1d77766871509ccc93f5a1fc2cf0690f630838d1f6c8ee903e9b932edf2ebfff0d9cf51ee4531c1f7c44b378da7add26f55de3285190cae3581efe436fecd1855252147d1abcb15834f2f65d91b5eaadea3e94d0adbe536343a38fc4a948c355984cd20a7ca454ba034ac7356bd2741ed7a71b39860ad2faa38d18ed7494fb510e65f6f79dbfb37f94fbb963a16d6e141ae82aaaf47029abdff6bd8e876eca3fd7312432cc37d0ec4c6a4b7d37c5c6e2efcfd99d54872a5884e28981d794c7855590f2fe464017c8724bc92e0b644df9fb5c8da573f641e4e65bd7fd396194d86d6a5a5076ff9cd6f41fc7f41d194b6d23ae6fa3c59ff6dc823d9ff7e39f9307fccb0696edc771a80cc5ffc74138ac9d01b95deff7f58bc555e4ef8cab6a73372337f0adb4aa0c7d13c3e2a83e3f8b63426c66774089d3822aa1acf4acf5ae30c4c68dd4dc47dd16eed0a4969e5ab630baa120adaa51133c6509c83f6d3425a385730aa0e08afbac0754358c812f483f5ca6bef41d5cce4cc3364fe16c6493f19880f693581e08999cef4db44b84970c8fa4f6784e5d614cdc9e626a31966acf823d9ea6a730ec5fd11663cf10b9da9fdeff40ee33a8edfcfb95cecc6b52cc08571cdd3e8315532b7c76c214db60f9d21a24734854b6a3d77cc0dd870164e0b84ffad5d9b04f75ef895ab5c0cf5f8cc9703bc67dc5eb5aedf4e683ae7feb1b4339335efaa44a64e8b4eb0bbe170bd1876ad6319cee68d4fe6ded946a59c6180da7277976e2e8bfdb9d6dab2f9d2083fb60965dc5d794dc63d6e79ff6aa28d81486c28b38d93c2ff810af965ccbd12ab67a05664951ad69d13332ba6ce9c8d8c7584cef74e4aa610d6c3e2c9b8eaebb8e1935730c31d3fbd66697b4fa93ac66ffe651535ac1d3983d9e5b72fbf60a8dc37033ae51c833e4e3c1cdebc03a8be7e86cf24dad78deaed24805c444d766bbb6d3f235d73846bef949937c6bc2a6bb4519a5b00036a5d688b354e6477553eab18c37b0167495c3e328454368ba49ee2a542447466269c6c22fb78ac44d60c983660f37b2957fce34dd3a8e7181ae898fe589c0044819037f1f679aff3ce1fc5cdd2f6edfe45f72d108f4c288e198bce85aefce2537d9d4bb8c0dcb64c5ffbaa33985313ae193095379d9cfdc5d8ce634a0e305ad9d554053a5dbd8c9d2ec56fd0a29e0303b4beeee53b11c915dcbefec5fb312d4ff755cd132def18f4ca4402c4d7453db9415c5874e9210196eab4c6ba4587ffaaa71583c97c329731cecaed24e4ab3aba4d93da834d6b8013495c89c4b4144e4b2197fb4a3ab3d470a0ac937d1b37a3aa5b4f6a69bff4c57a8306ab886243ee6b34e8922f9b416faaca70a850d9aa008b382383470c0bb971027cb329cc91a9d89bd46b64e26b30dd01069bb8c99ec91895769bb93661b429a0a2c6ba5ebea62cc6b6923b27d9b99b8fe2a01db93a6fe6362d530093d4167ef35626438a949ac2f77772b1ffa65f0c771a2c18cebb2b9a3366f42782353b07961d485b7b70020a36c5375152f558f3e028fbba53405f58918541afd0b89e4092b0ec372ce48c4222a6b33a192d380a1a133272a6b2a66816f33e410ee02362f6bbbe44976dfaa4bdb99bfe9897894c254e5a51728858ed386980c52064ea3a1a837b5ba02ba34fa6de770b001b9a9fcc90fda64359f37b85f203c0ff5cf1e7c4681e990a11183d158269267722441048911b41be8b63dc139859973eb4578c929b730b1cc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ed91e02930c790bbbd6f411bcba06769b779e125ae3788d5b3844a3a7b4ddf8bf3e53274c29ae25f4573a459fc2093caecc197e050075262c7fe590b9a90dbfec86a2546e800ba726d344c0c667445b35872059365626c4b9af412b701e00392171b1f8922129123f05f3696f47c405739e0460590a52ae7c875f0a088b0e4924ef3711b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfb42645f3809dcb623dd48936c0440daf036f12ba9f3573623360ff00ab58604106fd820bba7a9e9b09b7c022262330627302e0852b70c020432235b11d750bb5a700b123dce093e25c993035cc1c3237743bcaaa3620a33b16dadbc93555c13ab0781463a82df942b58930cdde7aa1f256cb7860d0704a7d82182cd494bd803684c4cb4bc278655f31eb439c9aacc78ce21967ea07e1a6b99e7f8253229754c7a97fc6411549641018cbddbe2cd0fbb12f35c0791031735d4ab51c62e2336025f0b327bc82d92dc91dfe544db159319215c40666b86917bd2a889de8647ad658c16b9a3e1d21532011fd40b5c548534f9151f39dba83cc3170db022d488662a0223c750a1d4e048cf9157bdcb0c75185e774ac10be2b0fecaa021613cac50461a380f419a9fdf075787fba921a6a9f3ba49d78892771994fff11a57fb27dfa895d4c2a58820798a7b0bcc096b2f591a4c53bff56b054f059e21330c308a2ab9e403e5b6b7ec7574640812464710b508043ffc3b5d2092ac45b39d0c743ef1873286a6779c15669b854549a156b77d42da9cb39b868c70a037d9737746b6f1b91733c41c610977a5f66b98a167d9a15e4f8750ebf00876783bf23b9e023793b6c54ad3a3c2d33ab3eb0a2a7ccb9cf3f187bd8b358564bd9948810f91b9dc426588c51432c83a4d704677f2918f6670e611a410014838e9be4c12415cd64ca1ab5dc5f81ee8610adc6c29f5da8224093d350aa4b7988303411b1a55a240ab4ad7900a4f3718a58901371623dfcb7515db485d1736068a1549714402649b1cc322ed093eec5022113384b8e40ebd9ab8654393c013c99380be30e16d565170d2f20d12859e795c2eb28c8900910e3b294302d420193b540f826b48663f726304cc936fddfa8fec5304d2100c45d3a0b9308fd032b535780dd6fb7649410867e610dafc425202316718ab0104552393084ce56e2a36a5eac1b0cd9899e3fc2816f94b59cb76c22742f736afd60b9615130caae76f905cbc1414c8274b11b713cd049803796a8ba121a95e946be67418a205759a3a285aa69ff254bc2b39ae75021227c6c48a377f9e2267b3725666e6480920949c413a1e805a52f159fd216938d0ac4743ba060b7fd8ac2071c7022c66680d80af15736c5a3500826c1448e601058ba38c278df84a6e65357adf6735f114bc17011eb9bc48698893acb932bf6aa9d9f845de9c4e4d4a1c93a1c9bce1023181746b7559ba6370fef77671769cbb53b2d6f123cb800f26ca8b6dabc7c24560d29561d8c0581391329e73209551ba29a579cf40c6bf792b0801b1d24204c20139cac32beac739e2269440c02990568ef2a9cdd3756923a100d97c42d45b71b0432176238c8c69af81755b194a2aedd65c1c4118a320c4ac672e78ba69fd80828b7094227bcbade5536f95b440fc9b953b4e0729bd185ca617560546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4b503f8ec36d39fc7b4b8ada1cbb933b9db9ee118bf081ed75dd5dba7590f6c8cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = 674ac342e1ab9008ecab115b7d3f1e4038762a8b454c6c50e1a38b996005113d6e860beb5e26e9b5a26f588ecc4b4413be6f713a1ddcbb503eb2df7fd53c02840199651d55647ceedd1fef4d011065bf9e015b12ad88498b17af47f46013de7f54a24114909119c0a50b9a03b947dc88ff948dc0bea2c9d68f1f63380697d8ecc0f77362055566f20fde0f9f45e2c026aff1603d3ce51394d5b35248a542f2134d222cc152a363c1f23f74e47b4d99c5ebe5119f0d1577f870d2130931c78a0fa81fb2b6d30c79bc0e00feed1a785ad2b6a00dee79a0563cdb0ee084bb016ed5160a0ea71384b4984a184d842aa6d11125ed10036d2773bcb97cf16013e31f1c86faf5e02ebebd6a7e8ed2aee8a48acfaf0f3712145f33884e78060515523c4a36919c97885810c6914c531a81e5050b3c00aaac6257c340efbd2bc6faceb77187ed1f3618fd868d790ac779f7774238ccda3d29831dcbbd07c99511a4b6c684fd295739a1095949ebfc335c871990ca1f080cb433e73e650f5e35e2f1dd3d6d82474a19472d0a356d7e896823fb396d3690d73136148117f80a335113c39f1896ff38a5f9ec7c177e4d0a65ea69d43d1ba4c39b07a27653925953a187ac65bee722136d9a8b2bc5c5eb9fcdfbbca6004f1a24d83bf5209adcf0d058557188d862908001e90037d1f5c56b695159ed833a4ef1b094194027a00e4b5ac9499c740c3091e39e710828345581e2184f6da0e037a3fbfc47fcb5bd19ff9869aa6989fdcbdb1af2f88e81a8e0ffd2c9ce75bf1dec0f3a04a2ec61cd302530f30b055aa6d3894d7e65012c4a80c65ab856a6205914da7aaeb14b045afdf9c100cb3e17442381f73a6bc78fec09e69730f6d9538b617ee64408b446aeef30b39a33249d8262affb1f8ab4e914423b0bf2740331eaad94330b0334110f6e55695795c55df52a44610e2c45cd7e55cc55209752dd929bcef57c2380759747a500c0d2fdf9ce9090ce30a8b73567bd05e730f624d16cee1172ee80ecb299f35946190cfbfc6ab2d5dadb90e61035f03b50e3e77750f87ff88caf8759b5c03492b1d12a2b36059d50bc8a410d1793ac223f497b0a389078a43e9ab37ceb8859617b62635d037f05992a026b438bf21739d6a28157fb401272cded6682786b6e7d13753158aeb2461cfbcb5f164d5585f167a438aa18a3a1197665fc3e0ded017c96a05ec20c6646ef7784ab63a3bb699a55df6a29e9e7c7ae8c98b143d547b9684ac2045d4c6e40d39d0cc53e96654f44e1f9bf0054b5f9b7e61ba26fbef4f6aad23079ea348b8bc73153fbe9a5107024c2aa2bb8cabc255347b02111674a5d652a0fd98ba53c5d779edf04e16d78965b63a5c9350d26bc9521d6b5d83e8ca4cb589e4a569ca2f8496e40fd706b804e5787d7727e6de44ece54717870538175ad1baf32bc91d586de5270c68bc7ea3860654dc25036abfd40d2c752d9ea5f230adc4484e85fa6b8eff4623e7c9c1e5f9a2f7bdab3f26a410938515e1e77e7a889471c4cce8acec08cab2c6011e15c3e8cb18ab975c140a68f6dee94d06cbc632b4e548cbc074b4b3ae9a6bce86b2445e474090005143c773f15f018a6485e9e78cd328565fe23b438d978f49762094cb4da91ad0660c6d6a3aba3ca4ba134c165c23b50c72735b714c9cea13f03d85c237d295367cd6b545f2276191548457eaf5b118e4cf90086dab9297259b9fc02e53eaefd1a9d442d1498595ec00e4e8d3f76965c0c4cabbd3e37b196c7991c7bd3676f8d4b146e08299f94189b57d095e819d3070da10366042e12c169538beb1b7e64dc542d7dca602d12949df421923dcd764d4d1ba9c5e077e6cc9be88e9211bbcffe2bfc8a91a5492c590c22617b8e9a7c5b34c2b2dd65eb8c713e5b2913a6794e479d86af019abac8f933b189843add7d24b2b1e904f0ebf789cd694fd38dab5c39d71afb783e6b8556f402696221aef748df46f17baedb58bba11413a42f93c417c76fcdef3be20cffc91bf991302c07259b4f6be4707a44dd7582aadaf6245648629a7c31c9d3f39c73b3f498d49229164dfcafa8086f1eb3d3f383343de6d0a6e82fc20c6d6a1bc4e489427829b83241e9f3a02382fcec52fbe610ae89089ccd4065e1112c8acd41802bb80019e9f4465877efc5e13a22bb08df929013cbef970cff94b4b1c479d162383a37e1cadb1fec00 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a33bd81d2579d7737a995ef6b05465963ac3d0fc3d471b94e31bf42699ae3ee7a306de87d947eaf3568d7bbabdc30ca69cee66abad7c67799dce7345b30f4ee41c5a6f35733deefefa29f56ddb744418f9c6c5faaa25b258bac8da5dccdeb4e0535bb3a44a46ebc44f587fcdad96596a8dc32a14916cf5c4a2fa853859ef7efaf70543abc4673450fd98edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca016552834eb4cce73bf17b4e7873a519ed16a1c55e4cbee807eb849274d04ed5e866656c126485979ce976dafdf46f2e315ef77edf243e660a5a78c663880a7f9765df454119f6a86acc7962878b4037cf2a6db07fd72367b476fbf4b8c57924a9c699815bbeb0bb10b2a88b0c63f027ec759d59ceb9ec5c043a41b8e55e56f325893685f18c5459adac3e5bf2c696c8f07727c19de1d45d2d075a70665ec55bdda721df7c52cbd83fb9dbd7567adafb6ec8d9c00838e57cfd9e0c5aad2f6f35e3ce57d3659d906452f4a8c61bf6f838a51f6789e43ddd580e4595a6cda12b796cb54f40a57f4c298abff1332bb0970a3ec475a434ec4ecfa4ab9fc43fff035a4499c66827c98fb542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0ccda0c3b86788459b659a539833629c1b585a23e34d766c9f9dd3282683abce486a934edd3a75123e9a7a5fb5eb7c5947b69ab5d9d4b258ea7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0ea8fa24d344ee9af2222ad2c65381552e7c453ac0ecd4bb209fdbaab94d920765c4bce5972aa79ba974f3c5d55efa7fe5bcb454f7ae71eec0184ffa20c73ebf27805416d687c6301e13b52a5f459c56bc8d87950453d2fdaef3931e43ec2c73278939826682126b65c7d9bac044ae6cc7ca4009fd90ff8470f4ed51895adb53ae312e6b1aba552fdce4ab277a883df9f3dc8d56794d842ba0687d808f2cd97787973b1ae4280c5fbcc45c103cf3822ad7eea6c3abb4b52bfee6f4b38e4b5dcfb859e77766495473e97bca3197b53ab73be72c163003c9ab8a8feeff925f56b59373f5abd153db083e419b1fba8074e628d78d712bbb74579c0a18a4cb2aa6edd76fd86d5fc09fe4a00aa44e486810f3ac6e3634553ec23f247f262ee2cb8a6c76444b1b5f77b7c68afd2c49d4b8efc5069b9b0d4cdf0587a5ae93d243bc5f16357e2bef2817d6b5ce6f9d8b3b6a68e5a1597c49076589d5303a5c89ae4fdcf614ff308e9ce0fd4b850870e807b4f2b6bf99aa8f40de6e95b3bedf247cdbdab048586116db7a463dc360cbf410bf964fe4ea5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e856ecbf9d6e94cfd9743cdabfcec1bba9baa05a8fd05637d26548f495e2f5477b94ddbd54f6674158b2f6fad48829eeb023a642be75cc689a303f6214793228138d6ead3bfe4466dca6ffd2a7c5720fcf3f96cf3a76e9d206e4ca063a35f4515c0473140b8ec3c53b1d99740226e6bdaf459bd3e502daafc96e990c1b97ea1ab5af0e8ead88ea68ad75cc59f4f9ea364bec33ed167638fda643c3a8119e4a49366af69b3cc25938e784f2832b7078c6be5635e3ee36487595e5e4cd4f27eb5cf0c73efded32d00f7c7d79e6072b698455fcdcdcc5b6293cba9ee1e23d40548c5c4ecb4ea84cd1580887eba79f0e8ddce35f74f57efcdb94f7fe9377b7aaa5180efe2766834324f63e37d86fb8969a48e57daad2da837727aee84d05e27aabb901899e0e78a42c335b7eabaa462852423748916b9261e834320cb8e85769894feabb4fe348e68a434e83e11dbef7fd844b8c7164fc967ffbd2c87dd0b47fa1547c88c85df3483f6cb447e2be145e1854649b07aed70b798e845f7c4c5b0457ba58a370a975894005347685dc5168494bd733ef0c6c3a16e17aa53db86f440969a1939539f86ce1463d7526db7f43ea595833a7a49abe0d3446f2345fb429c4adc43b2cbe7bac8c625aff551b4cf8ae1b57fa49889aa6a2503a9017f8326676e0fc24a4a8657475d3a329e3ea793a6a4024330f0b6d80dff50e6575d8a8947fd3dd431cc24417a6ed4bc132bf53af24ff2ca88fd0c9a4509ee104bd64759cce45fdfcbb16f4596dfb71c9d83d097f927adda50b6914fc70e0858644253fdd9521e55c85d1ab71750942bae014469040333767dbe4ac80e4b3d6751f27fbb0eb0418406111c9e77c39977315526bbe1c8e06150a0384ca618001b08554c472464ae8b4b9eb679a790bf0e311ffc20b9a28a2edd52c4cb51bb739712419a116b1c0de65217ac429b091bbf94cc9e24886ffb623889028490976074888ca731ae4f9a9e0e4099f149372390bd2b78516044067201da469c7950bc9c681423b9a45b579160430add2b34d3dec2ce84270fbc019847c017d098bc4224bc9c99ecef95947e358f0f85def6837c5361fce2145faeca7ade0a612138c8cb26bfb534c2087c8dba4ce1f841e704652a093af188c55ab221123540a1007190453163a573d166617f452b9b2c7b9638b0201292dcfca46f4b9c95c1c8a47f44c19380a061b51942636c3bc8950f01186878004db1eb6a3b2ad5410c3484aea11a8d38881de278124c4c2b592b61bd87aef623de1b5b8b2d016a2d985976062758849362b2631a8a08404651305484a3b2dabda9982566822002ba1e83ba8b04c7be77d4086207e5b8310fc28812584129a4c03e938e950cfd43c3023a8774b42c9338ba497e853ba684c24aa03ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc659656715d0ffb8287b86cc0964d3e1b77e7d83afa733789709714eacd47b8bede99aaba2480002c0fb9136e397790bce939086ba75467340780cc31491e82172803a57129b3cfa3957bb70b114cfa99568428c540b187b98da9eaa20f3a7771d80146ac21b8908260c2cf79383031fb99ced3be7c86168549b8e2d2474e96bfe28158d91a16d5230b2f7b27d645c3b2096659a60c78a602457b0ef8553bff9508175b5e10e08326139aef678703d39693215d5d821811bb0868e483c646a4dbf0958978352b919c1354071c42bd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa3572bda92c2f9872bd19276cf66c31ac6cfed109bb36b77378c5d9a747637f1950cf36c5b22130eb018b607b74a270e0b733f12e426a2eb02fd3713f72c682d87cb6752a6a3037816b9a1278151c662529b54c52655b76c534e09cba4ccdb85289528b8f0201081cb05066515a3cfcca9031f386d6f4a411df397e526b754a0cfbdcc7968a03ffc7349f32036aa4b15123a6ce8d47f87516c717651d56cc7e2147cff3261ec76c045a32beb047760295e79f8c501c46b099bb7b508cbba9b099f612e595b41d32a946e0bcf26a0c5664b70971853b7965725d52bb371a03f456be855aa495a2e3d9925f6a7c3b98695b5e179e64c17410bacf2035e4fd3b938c98db2526804c79322230ba8455dbefa40caaba9757380944193063335b6721225f40702ebc418022fc2590d00f918765ac41cc6b40d39b45291af80f721069c7f73096b7b0a202749c70ce672f246209c637375e75a1ec03102940e8c17566b7c2ad43167f48a56c55c6b38d289d5675b9b224b7155905c814e175052a7e67685392448003d8e2815ba9810d8930051b615558cacd704202ad50f52890500e8be5cdc91ddfcb61948788a9cc2167a0021566a863b875361153b1a57e0c62f8cb11d3b3840f570b922e4a88151aec22baaf7559f724549b892575430383473b9183214104006dbfa356e2c31ba283f778776b43530a857c8126780e29c0316c64ddb1a947d747a8ed831135a8146936090fb59192b32b50327218125814b2863f2473b708338390ac2e507715136c8786fdcd1c10e2b0d63d2ceb6a4b0d8db6f8af354bdd1bfc6c71afb627686761d97b761fc0aca584539117ca416078c784972f67caadfe67f38eb1996e749e2f11a3c47c389d5c3f1f52d33f14a094cce5557154001ae2d17a2896ab4d0744e9dd4bbdedabf34d38c1c81812a3cbe4a065a0d6ca0cf3a9f5ff0268162a5b3d872b6782cab9149c52c2726079396b01866e00a20bc82208009f625323df535f1658a1ea29b933368992a89efa0ba586381d845099c35a299a467cce67af2d5b066d9891462114569a2261acf20cb64cf3819d0e0a4c20a153cfb5efc9c45501aa26adc5b26553b520a04c4388d665b098fe52b5aec48154a2ab5053279256ba4e6975f4764c77a5fac85275fec08d62534353b17764177037bae5f010266767164b307d4d375c85549edd3261c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f503341657b159925cedc8967872a45a3c1f0122979af87a878a2019b3f17c8ba67f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = 2555f9bc4a695e0925a3689286aecff9dd94a6d9d5f865cdb52f33218b314f382a4b99b7b49b941bee78f844e1e55f28397a25dc7524209030e4e6946f3529c89eefe3f6bbf9614cc6ce16c49a79120e9e22742e814738fb25832919de2fd8f5b3afca0df5a96e78ebec279941f1729223e9bbe0bb67e1e3d7a6f64e63029f3ff8e90d6581981f6546cb9e3aaf49ab04c25fde5db04ad5436bf6b06409e735a87c9b002c69a03bd65536c9e8c88b68db3f6d8cb706d97dfed7851885d081ee8e069734065f2b8f796bcd814c3fa751eb3d781bfd5cdceedc12519fc1881f655208b315cd69f1b0066ee51f90c61d86ac47112793834de1ccd2bde5f6bd561855b59de7e0ab44823fa6890641d3408b723ee6be06c800dc55a710b3e9e45c6b9d29e6a6920d588bfda65754d1cf71ab87892319a196e7bbb531830a5d9f7ef3c625b8f5c64eefcadcc5bcba8d6f143832ed55214e717fe58132e412b5baa0f663982d6a01372938d24394e6c3e6ffc2b3c7bd61b76934871707cf1dbc128da0b47a80bd48fe193226e6e6d72a6a48eed3c0414a9c3ca00f7862bd802f035a60d90e29962f9faf780e2e4c110a42e7b94c1fd6d9e95edeb6e5434f473a695f211016c25dfcce088844eac0acefde73482b8a979550e4a050ec096d5e309489333bf4e618a198bcd6988578638b9dae6d996842bb42b1f34cbc398dec9ee4584169aac8929efe472abb1dd6cd6d6e69f17e7a9fea7370db9574b2e008d65392d79197e6b8e7c073b75c6621828b9166888bd4073f2ae59e0db24654695633329d4115a00e0a5549afb82ca19b2d013d83330b510451d76aca0a9eb51e7a9ace34f732cb128167d0d677b0b93e6551233969a08fc1799d68908a05b10494a2e98d783aedff4e6c32be3a5c83a04b0f751308015494d2fe5ce2d555a6399254eb53bcbc07b444e647fd3a1b89b9648d9c8fb64feaf0df3cc5c3ac3b6c5a7aedb1890e5882b20f3ed54d79e072b957a3802b2637d0841f88e6cb82145495e80a76557d938acb35087d2845a3d21be902da3f4fb184428f723b0655bc530f9356cb1ee3486c25ed268a0ac20514b6af2a62b8b6d045d329791523c6c2a7825feb97adbac629b2e94fe92941faa3593b809febd42906d109a6904441f56ec7f7cdce7f8aeeac3efad95ebb1336f656d0ced4e2acd737c27b3190d2a872ce59511cfa22d001b19267d727b91a43e8523e8c9b277566e03b2876da5c1177127bd1968dfff5b42ad817b1555dc5b8f4dbfc43e6abc775982cccf8421fe2dfa4f04153f5e7a34556946274a786a57f80a41180e7de70c2717f81715593b2492047407e2cea8e16bc32d2ca6038dcd78133c0cc6a3a339876deae7e4e48ce6f3adf352dfd415028e4048ddfc8fcaf745d8bede397691a4561952d990709af7ad591b9ed819b9a62af7d53a19bbf6cbb9bf2ec59ba49ca9d62b618f39884a7f9d20018157ffed0b41d1ad5416b929721daecec07031d7d65be2ebf4c06e9ff66c25ba99014d87db604600a6ecf113849929c442191421f388ebd1fbd5b8a3ce2d5df4e06a9a1df07dbb6ea4564980aa9c642019736ff5e290790d1ed79acfbc9b57c0bd5301e0e7a65378cab5e7ed6b74d8ce680f32592fa19ce77b38d7b02a90aaa0420f28164ba5b88d5a331487d02b9329dce23120a7cb93933d1cd7760bf581f036e2898ed25f2f441b7b81ab09d921f7f8b86a3611cd4f30cd5e505f85325ff8c14561d5f13ebbcfb6d6559726488aad10b15d3473193f7fee98f121e4a957dec525de7713af418cf578218ae8f57c655626b737930de46d83ca55dcd8fb7ef1972b3168f153a16ded056cb6d24b9d3e2eb37ee9185d5b3e407fc38f35e72c71ea407959bafb783465810ed4042b678becb92dedba9b78435dc4b3d575093796fbcfb6905a68be1f8cbe8f112158c9ec77a44b33ecc9d34550cf642e3110ff7943dba9491ecb7539972b91b092fdb1de8e96fa3d6200bffb3964c969e655251f90c4fe3cc247de08b8188031458e0a02f4795531700f8e40c895f8be3baf309e8a80b67b5ff081ce03eba0ba8d30a283429f94dc650f0b78a7b782fae499d12bf848bc2414f981d68594f82cc28d1ab3b9b0e4ec42485fe190fda4d9c019dd66e8c8f303bf9ced811db77a5ca20e8d323d76800325f8fe1251260bb1590d7882fe3e397d1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d1f46e67cc5aea63ca9ed4e3938661c208e66cc79e10a64174774545b597e91a8cadb58deb15b27f343074bd71873870bf858b5fa3ac3689698deb68c67d406a8ff10c2b990967ea12753449fdde6a1ce65b2de46a8f8e906da16b55478c8899d9a38c185ebf220a60a999b0d2b4f9b385e37db8bc9b85ad5fdcd73355ae641ed0f8fc68ebb8534135590dfffd0a0672ab54936c8665aaf476b60f93a42e35283777c375767b0454760ea53c7fa14d3c4de5fdd1d17bfb2b598a22d784a48eec39ebe83ad8fcf895b242954b41d7e3bf4644659e7d6c6d8d21b67b3519a6df26ead237359e36fb95c6be3a95f2b9248346785fd0ebd3cd083a2119ff4e9eaf157be2f4c9c77d1ecc0b68adbdc8e3bfcfe28974375808e4676e704d0c5caa4dfa074d40345de7d488e5b7c35363f5c730298670536c6adef2cd9ecdfd18783efc4c39c8c29dced23f1488a7469f1c0cee7ebb3d1ceaadba4bd7321dd0bd89c04339dabed896e655cb1f43a1c7335aef4dd44d9652e6d3b8e3a4f18f73d72d7d50a2984032c45735a3aaa51d8aed8b9a1ace3b9bbcf8cdcef3d9987c45c9ee89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1ab4e5df9a6ea4785337535869fb758cd04b7999d7e36197ea428c66ab5e6f70f404e87341e154a0e09c8827f5cc00d761fd9645b658d98efef33059e4a898deb0c826e9d57ad4df663897d71567117fc4416c860776bd26f5ea52663711868777d64ff1224b277fcd05f2bbcfc0c84146591cb36cabb8f692c1edde229797cac57aeb64af446a8975f7bed9b3e55539c0f7ade9eca595399db96bdb282c3a4c46a44a97d5a54a8806cdcdd3c736a20d34aac1e881375ed860efa06958933d6967add457a58e7dc83b525ccc63e94c1bdbec869cb3a0bc46d47084482cf563754aa8f44682b97ded04996cb8886f43b91ac8767af1f856ce5b85f55c8802830ba1babf5797d0db7f3efcf4617ae95ad8d9371d93f8abe9c874c840ee9c39e7370ca66eb6f9e552cea47f2dd9c9cf633e7cabc9ef85f8aedea29d9cfcb8e43bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a834ff7949d6463cd3c20969f77cfc8c8faf622a373c3f4d164a77055ebae05787965c6da862cd9658c32d4194dccd7ab1df8782669d891be785f0385b965b5ab3b870b0d88696a783b5c7a69a6fb86f789bd43588705315258c117c4313198af43efb7fe39894a96e89ffc4e8c6bac5e8adf03d86d18089a699997303d9a6debb36588ef64197166df59bda98c7bafda9e89dbddc587e8cd8040d649b9bd8fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5153bd49850857308ba1320f83a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd87e2697fd0d55ecafe599ab0d3a184dfb0df7b8fbf0995042ba0ce78feba8b71dc7cd74436fc75b7638c5eb9c4a3ed4f7c842328486a799d070f7cd5cc75e5beb6817cfad66b86ed047ef988e84bd344c00aa1200432c6de42246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375070f82b7da42ecd36295fa55f8b5ce94c8e2bd5feb47054469d39e3483a63583ac5a97cd644efe7779d2b73c34d5e8ea35153589fb6d769dc0f9b4996f83cd473ea7fb7cd9f61adfaf7c5d24f9983d9cb9b19566f1eb68010f4fdf13fc413fc778d74846f4c7b63a3effaa5ab619ad3d6f68105f90adc5d6400e37f0ca7b694978c72fa9a34bae2937e9a7f9cb67033c0de773359aac3577ba38446a571dacb9d4850a4e3b1dcdf4cd25a4a5a882ad3ecacec34c250ad83bd38a8356934423a8394e535578dbc7155d433b4357ecc6221ba8057df317c7703aecc7fdc3d781b7e5859e86f126619fe78f6114f0d2bb3adfbd85753a710bad7ba2139c0897a172ecd9e7235bbd0638d8c695dba8baa9bd4f7a058edad5f622b4a9648e55d56448a3977786a4eae23c6dbd05c4fe466413ff9c74eba96a2e612eecdbd6eefe72e944e61d5843034d917d416b649491c7b4246ce4cc25f107bc68b6078b76cc61a6b371ea6fd2292584a1734f3d5fe4c247eb8168c6eb9c7e7efa764333e6d24daa9055577d874a7ae7dd16a3783f89d4f3445e7e9ef60ba19153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d3c11f376b1f1cd8776b6280cfb52559b6b3bf4716e9b49997911bf8da16c4147a2cc9bb379ac5195a320783213f62156c127257a469a428834d384b1ed48a8a576b240c1c55b84d61e248df45a52199143fb141b39c29631216a32b8dfb876df873456c14178c4360b8215c71e219c08c915a9ac02304c958c1bf7e65b3742bac539059eec85fb6cb608975b401c83b490094a6d1714876727ea34cd27b7385d7575ff49931820fd5dc33f3881554c25dc41a65834115e1c899ef8a080fc6c53b81b3804508fe4c1fe6904960d96f8c1576614474c9191c99fa3a201a4143b09ae0f3432bd13a3442ce80ec3ca3c94bf2b45fc398165318bd8d2683148315d1969b70840af5b42d5779c844c48cfc0488ec65b414837a965c65902c21a2c48a590ccf9fb9c6f9e45913aa0577d2acbbb29b5357cbb6b16fe6ba9abae44645ca68573b5fe325670f2c4b5378c040171ec3a25229b1c3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3e80fedd62beeec1abd53a45a7c33ed4117f415b77a43a0d7ba4ae2031e3c57c945b9abc3b5b3b7915784eace07e7caacf256cd27b28c2924b01302c9432e5f3a2a75009d03e36fcf7089fce58ce57492443323ab494c07146db2ab8e3263955eb373031c22da591ec5cc3ce0155f69fc43c8484a9e332e2dd433a888190b05747e0971005b8026409ab874cd65f533a51a40a668900ec109de60749250890ce91290a43078e3ac85502b4f34518886578c26353a6577fc51510ddcbf4ffb6b501662dfd1001d6354b47b0528dbbc0d6a18b58c605a91957c27ba354232751810202a891aa83efae7957ac2883605375778369589597a8b4f23f325acd8683c4b1dc3103002e1c588039e08a7c3c92137510391b3f75b99810f5c932a80a7b5d8164d999c131828a59a939d90a8caed47c205681973a38074243a787866588399a199c8bd74c8b6546168e255ca13b23d0775eeb727e3cac8b4305893185517274c4a4abbed709f2b986bc02592d1dc38cde048e5f63f15086f11031348a7a68e044cbe1075f1eac3c330477fa5124c832c2c880e29da691007a82b79611ee04b64280e51d201aea5b00a633e59dc0c20d72742a925d4cb19661ca864bb79a029c7100911dcda5fa1b36392d3432c187ddc51190c563d4c180dc87976a142962023301acc29ab63853813185b6390fd84b7d395514bea0b35b22d9dc19277ab7d0d602725a9ca3af87df9f96db8bc6a3f27891f9283bd6a4c4966cd26d3c96c2b4d808a2cd435abe4173ead728a200a43f8e21907020d6c19293eb02785571a399a81b8205485c54ac19bb298c8941dc06ed7796a39ea2c84d755a0e90b53f86ebff130c6008f2dd69af0017bee0c6e13a0bb2bd73b02431bd211a5fffab76f96c080482055837a6295209cb2a62505b846005ca5a482709411b5b94bc3781a557b2efd85b575621cab87aaad6844034c4a1ddb43d70687d968bfce441e7054a9c9905c114b9791e65bb23aa0cf22ad7e005bcb38b24deb2e7741853ee7085a93250ef7624be270bedca3d322842b477a507c3ddfe3325d893cfc432f07c15a1422128b5703d92812b87915e86a8f8de97f163caf5f695ef9994ac4d7932fb9629de72a988194ba13c996c2252968708e6468687b1a91063de718331027a54aea679861b1b6b6930f8947af72a1b30895f225a7bbf7cd7e8a857b6216115c8e98689b89c7686d282c44407c44eb64d3795d51665bd538c33a7915b5f7773ff20b6d289d2425a2ea4a14e8e2a349a78c76f8760082a1f8315b4dc41109a05c6053484a1b381cd8412df92ebed7c489ea3db9915a23e07c37f7c805e448a5f08a89a860b96c4bc7a10d4c30522cc900291a8504e72f4ca5229135827626c138173f73f123fe013f3612a27df9965dd78c6f1a2c3577c7cf866e70190c8a249a6ac6c1eb45ab61f9a021470135292d6ba6c26455cf0876c9633b4afc24779c908b5619ce1df7464e096aefe51b5f43be40b556e2c5c41503857f8a6b4adb2a5d8a67cb668930889d68295736027b5b1a4b3cf44a05101f1bd4b365b8c54117c6027460e14ba516724361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa098560c001172c4734a620c248654c58f1c10135657083de776116a6acf8a55f3610d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = 05d9eb9cf3edf93f6793bf5ed101bd3980b34678bf212b1cc444f2f0ac437e62c732b29deefdb3e75279d2e90deb57912831648792e7a4cc586a44e48005c8f1a0146d7b7f21300950c11d4162b9a20d21ddf22a795885f8e511d62c8337321d9a9b4c3c90196dca3342241f6a8622df9b138daf7fdce9bc9e795474e1f0fce08df25b7e88e1530f0b0ed1d5dee54ff93088355b32eba417101febc633c17aaa5d5e121ebe634834e64cecb4ea34cefb21ec8ef095af4d0afbfedd1eee96c9bac511d2ba607eb82fa5086dcace03a92bd84ac9c135edcaf68c935063c2d23f70a1bbd3a7095b4bb9389b74aab81a9ef4f48ef33ee5a6c0b6c94a52e6d8c2abdba8edd93017f9074fa6a9eed1993e34670bc0a5571adb497a80b48559f2d535c9072661c6ef2aa1620d93e00b9a75032b6585441d872ab950424f251ee65bd56803a71f8a167b9111498e2e936f1cd460e6b6cefa57a409210af828454c35199d3e307661ca760f5fa366a9d9307c9106ae358f7a3d52c23892b2a9b30c284a62615aa47ae6112c7ad6b630af9cf039e128223037c73f4e26e82a0fe4471ca332426709210b2a6d30ec5257bd86d8c80b2ec71a4e1801a63815528d6bd4c145c9c860b7daf7e0545be68efceb423de334b4dec869124844cfd94769d112bd6ce527b178d6d26a454cc2feeb128a38b94e217305ed5f93979728fd7168c8d1102cba2cb9d864666d109b649cb41bd04546023bfb87ea825bd6120d800156bcdd2c163c24258241a64cc4953a53cbeb8c2ee92195897e16af995172f743ffbf05664e60f22fa48f86fc7f33876c883c1d19f097f7693f0f1e3031789e400d6a6a93770b0aa343ad104d24907f5a6f508922433222321c0a2d2ca88acc24bea23cb290228ab6ca8be81576cec9fc80572d3dff7b714ac0996333d052787b73e3bde6e78afa3327b4049b0ffb31686456dc7875efe63dd7f2c64d4ad8795bc993630ad0cfcbd976e4e2d7d7d22f09127f4c5fc60b52907076be9f88efa8337124ce0ed05923f557b3221d288b71c8c201735661d19856bc973ea273a3e7f1079c604c91352251c512dfef663503b6b43f3d6ede5126306acd88ea27e288f8826e14b5a77804d36712d0fe3ba38ddbc6d3afb0b40e0a9a493ff38bb105c33d73359625db2443e7d8f50823998b5428ad14f67a509127e7b89b7703baaf17e581d293c0140ab760431a1a4826a673b5c70bc6bf030ddbc47b6c05f9888d3bf72e866ea07f97739ddf24d855d7a1742d42ec23c3fdbf646f3f6d1bdce61e5fb6d117acec891e03a4f7949e04f1175635511a35e718a7eb65df43307318607b7da11f0cf493ea7052ce585457c1700855faa2a5ce5f0e7fe0babe6f8183989ffc81d28026904d6dafa5a8f21f438e707871efc796daab9ec2a5f5f5e00480798d9d0461ea51a11dc6cbd88c2a0c0dde6fa97641b7f7c6b6f7562ef6a0f01f32cc1ac9e6ca352394ea1b38500c2d5e4e62a929789d6f061c2c0ce579ec0d5a3639af83b26499057a1a94f47acad835443ca6544fe9986059b96bd646403a504bc5dd1d09087ea76f49ae005333ec1231406c79077c1d33dfcc5b2c9ca0d0cedeee31fbdb4a63d7a3229a720567dc99560c33ed3296d00ae19bd736af5194923700d8e23a64480ea385373931f4504411f94028fcf177b203cf2fb32cd1a2822f37e1dc139dc985c93c4c4690545e51dc01edb733ac4148bebfbdbf3764eea61cf3925952f9a43bc4a4b342be1fde9118d935f88c8a1bf843e759a04a0c6cfe1c4518bf12849ddfbaafc94e7692c7ecac9348edb99a5ebd3006e97eff99dbb6b51579294fb03cbb2d8a50fe233724c00dc00d29e001da7b0aacd73fed9380d73453d929c6781869dcd13bf616d34940fed90fd493cff48bc7d1a07a70632a8aa7c5f65b12e8149e845ed3b62f6fd5c23ca8de0b7f2b02e1f12bfbb039c90eb202f1d624ffd94389e9e6f4665d4b1e7d3652645e06060d140c3c92e2768b82c137e1ee0ffe88699774546d38a4060fe455a564cf4575ffd6900de3c839e33500f6cc9b91982fc21d5ee24edc6b17b4d3ccbd6974a05e646d9e61e9417f6e37a00b917f08fc49f235cd2eef6b2d3b48baf58ac63d12000e9a3e518791b16a7c1140846ef8c79595c5b81b8a06d12338d9416499bf5870f5e4d8126499ad46c5bbdb29bfd34865 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0aedd09aa9878c697e2eac9cec9675a967d660346547d7aa8d4548e3aa917e238cbcdedc389445d167e4b237566cb44132d6983ca6e0e779570b74482d5ba2743aebb51c68143ce680c8d0f1938795367b6d8a56c33add78affc791e664363daad0ecfb279ff4bd6bbdf6e5a3335b397487db9bee75a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988776e14b8db198aee8edad821764df032966688c99feaba06d1ada1f8dedeaacbcffacff2948a209ac8ee505c860ed444b5c70d077e00b63cbd6d98f9aab73cb06c97f03ee7badce1897d7ddc5c07d495b27957b379d55650abd5d9b9f7586e771afddd0b574a594ec3bbc9f6f1ab017ace18c7a83b2934e950b3dc83fc84264c66fdbddf78975fcab5feaba4e6af97131696a0ceaeccaefc40a266fbe6667c1abb362fd631043e1a89fb95cd5f5ff97fbf3f394ffb48b30b334cb0fbb32b9d1e3478f8125d5da066de6a5cabb4f5df84cf7565ca48b16bb2855a797b7fdfd57615e6ee7b24374c2e3d6473a34962ea8107790d268ac6b68e3c593cb9e96f1f8c68fd2f8d82c59ec95c5ac74c86dd38bda4fadcb66aa576a05e0bebda31235bdc9f8e07f1859addf674fd7fc6669a3465556fa0f69cd3db0a8f53563378ee016a7abcb5460d5371c0e754bd7373c33e4e2b4fd98636112f3cbe0638e513b38d495dafd7aed3d48530828efebd88b75f532e464e966edbc592885fd2ceb3108c33f7472595d617c5f6ad5ffc8cedce9b1adade25d57c90ab087cf6cb014bff92988903bafefa3c4c96ccbcffe78f988a40d339db334f57de69a12aef5c52a414746db1274808299446ee768690e70457acef198e4559996fa96b418275e041e99e0d578e86c94648ec369ab839b1a75e9d6845c98aeca34f53b4bdf00ec7e92cc6f6b4da4d9bd4900ca3e78cc7a5d5e886e19d1a908bf0a08947e3b524f1c606b055451ab6eda2bbcf93f510c3d75e2dbdecd493b722dff4ec69565f96651a3a2c3b738c2d55805798254ed55dc95d8b998f2e78d378523dd22e494b61df5b0ccbc69667013c4ce4a24dc2e9ba928e4ed7fc5f37da8c5ac13e0f06dd7b3bdc6737bc17a747c5a3cef3d1e66bc3bdad7aaab1d97de54694c1daf93675f86c4eaa35d34bd6ea7aacfad4872cf57cf63641264aaa0db4f65337274356f72edf310a57e45df3ec6c4e85bc5cb45a65d3b69faf313821643f060264a6e53702d766d0f5adf1407dc75b780688591cd4e4283a59ad2f84d665354d72cfaaa2cf78ab6c8bbadf284bf86f82761906c9b2796595bf5ac01455ed2b436082d7a30c949b0beba5d5d659143c98247f79003ca820b4b5963b0883ad88ded9c99f4a6368971a7d6885237bce28580e2ec483fb3d5ff0cdbca173a89cc41727a55d5ef9a8d5edb3fe851b3d58b58d3e920759adb5f9da26fcce486e8b207e6f3658d71f5455365c67b04748b47ea5a96b75f44fcc5cd31c713c04d2b6cdfcdcc92b7596bf4a2a0d9e538adc8174b3456489d2dc7dd3bff995c4830256ef0ea5eee92ecb22947d0973386984adc669ecd5eaa34d5dcd0fd77fd20b6d4e78696d564f647def0e02c8dc526f630f7e465accbb47cc0eeed6fedaf95840d91000bb220dbfa41777647e6d84c853cb69ab9aba7f04b14b31bf4b1ac577a772edf5dde7deeee4d095662b6eefc932be404d3b0ade5b216e69fd58da9335abd322d65e187a0399ea4e9b9efd01a57a8e8a100ae75d8e68152dad58a876e2be8de47dffaf846de3744e45ee882d0ad6c22167f04fed3aba731e85f6033ba815d9c3775e3e1f5e9fa31d552d89bb291663ace4b5916436e1086b46879950de89d453a666f0b514ad3eefe398acd5f370e27c0f78ea97b0966a4ae4b7e45bfbe688b5a1b40d905e6b698f18ef95a9bcfe1cb4f9cdcd6a4914bfed87c9f65d64681b9bed11cd9c94b9c0d95c75b69721c1e9b95583eacc884a56ac09bd3bd6f197a0efb6659e89ba4bde9ef1fb8ef056a45fe74f12e9f8a6e6331dfbee168d669396009895cf9a9ea49e7bb8a7e9f6d44dbf33c427fabb2a5c96d81d4fe18a9647046dd96279bad74dbdc4ea40aca9142275cae4b95da8acf98bca3456c574acc43d3e7fa2c6542d2af5c554a8439d9565bff9d8617a129d5526cbb30aa578643b133a0254d6e22c33ee80564e7424f0842b113636010c566eb59f9923a021b2a19c08bfae521e44324eb5bc9873846141ca7da45be4f8619b334a7cf52093b2177f4a71ae211081a096071f958277555709b2f459685ff22849a86375e157258d24563b8028a728c5eb0bef79495c1c53979880930539227c188c2027681236439085b41763d6378a4ea0254a7416473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c2716053bb54dbf1bc22f32e6d88c2a1947bb599a878b84f29021ead84a763eba7b9f3422466836bb6ad029543041115d638552cc2017a84ad4cf687daaba75b0c0a73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c2325a3ac19f9a5b0327b80f220b9122583f5d908cc21c97083227b568c47e58a2a7843d2141411b08f9cf61deb4a9edf41617fe26bf9c519d0cc80cd292585dc4ce5a90339216a6f876206732af6dac9b2720025b31e17ec47dff321b06107993a414f1509839886bc526f8051c4380c3faf4b64d7e3c9f9a76e9d440a67499322b37c4af9b26b2814a2b8b699ac0adcb25835d038b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53df10c578562a91b55ca04ae8530c6aba9c16cbb0684385704c15d302c1ad4857d0d1657dd85c536cc76f228641899188b9222f2b208d34222276a3c91628772c6245433a0ffd16b0812299283ac8d5a36b868b9fab4189aa64a0b90b606e695fa542b8c7c3ff0f0a46d5b00da78236d518d34756a2f32075480a4c15b7c27cc8e4a93180e6b5859120a24db2daec61a479cb039d4b9e6041e816c96862c2b1d616748444b4febcf7a129e6e7817950c77a3fac386fa787eba4157b720fc26629842a145759cc8fb652811a8a3cacc29571463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b304c0426ec26fdb17ca8fa5496d794778c49b4f74a58240bdd39c2fd6628011837451cc4389a43f3bb20959928b77394651e4c2cdc44cb9499def6b366d15550b41ac89707e57b271aad6113ef7a9b1575c69e35e4d75bcb0333e89c091603b7ea5973a277672a1c504cc2c45022906106b97d4fc01e98a876be91d88f4c908b892b5cab99fa878dd1b3b1688976c148bd0450216656028d9c2fcc3bddab2ce6541810cb84f4af414eeb863b7c7452bb79a96e790cca35bdf05b4c3b059801b2bee373da6a0c3df79c986e71a6788712fc50aea51044c2b82b3d201ac7a1245c96767f0cece2b4af175329a4973696c5deea91075a6b8ee2c347d15c89448cb48d22126d82732c1293288ac60bb3bc3ca1e208ba71054399fa4a5d1db7389379600c128b0ec1803b88de90369903799cf5ca0c5ea0b012b691b0a50b9011aa412509d1abf24e252e9d2cbb315361977770ed77310c1705e46b06a5c1c35fb5e5c9a8066d2750b388855e982bceab6b5e8018181b66717142cbc3729b13e2b34205fb06724ec13c3c2977e346e50a79498f94756069693989b77432f8b5ac8d2b06f2e227c4728288e91bcd6cac439b068e2017ce1c808c74098ec2c099d81b9dc6ab7e780c0c1669806e3cf34a1c1d5d002aa1c9301670fc4e45b64c59481d1cf6446468806683f57b3bc25b032aa40d2c188c5a2a7d47b41b4753d5f7a3b22bb70643942d6c35317f05e6acbb4f6794b1b0c3bd47893a7f9cbbb61c608068054b385a9578303111972e8888c6427afe099a1a07fb3879b821b25fd1699ad001f51b27acc5b2926ab2caeaa9341e1a627493f44f561eea57745a0764a840963024ff6c070ad95b285a74527fc3da894c06f7bb5de61a012547f87c1517b9aa5575a1ac9a30d858c912ba096cff4a24085c750aab463f8b956fb837ee300470452c6431d128b27472b5cbab268924acedeab3e7b02b2b201a44e99654910cdc8d5206496637e88929a1ba4436272f6b5ce41533450663f7a1a9144b5400d727fe6342c6cac6e2c3312015b571585303967422ed8c5d4b75e4f203bf2f86cf0370aa9324c47246a27d9076559c906ecbbecbb20e020cd9b6328857832ad8400666b943f8418f57408251b91ce341a2f63601dc751c0b301729caad8425f717250d5a249b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24647a136f20b22c63afd2b88d14fe7677cf5c2b78223a587068377021f6edfe9b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 09b1f5d93b3554c6875326ff48f961225be029df22af93494a7edbd421193783fc0383f36c53e1d66ad64a1a6c58a52d1bbaa59f537e552ff276b1d328957b9f8a8d4e48c7b25c6e96e80ff1219f44d2d65e88b0fc84ddc1413fb4f56c018cf479e1c87916cfa69125c5ee99827bdb6b6a1f7ac80dc50830adc747a4fd99eb2603129b04c94ef1e431a9298c414e5aa87bc32831ce7c575f5f86a4f90650b99130147aaf75fbf1814871c983fb8676bbeea5ecd14562fc4b202e5de7cabbe52d40f436af9ac5b568c2d43e222f6bf19e6318d713d7a18eaaa3ed4c7ce5bb551a77dcacb90b68b3092f4de8f186dcdd80f224d0b9bdc2f7b85b0adb755eb56be6437a6fd4acae76a1ad77d97fc88e685d2890eede3fc7173e4a691d922d0823ac842af1cecda68acdcef39a0899e6cb94bde18fe70d7e511923e252570be75c238212022f747f7602579cef67a6f6d3f3b183b8dbfb9bbb39dcb3ee6ae24f32917fee81477b92bd0d6f69d6e7c97b9c5f83030e8331be2280a8a0a4f296b08bc62eb2581e1e1bfa9d5392d2e9290a396fa998da07cef57f42cf866f8d7ffe951e67b7701baecc00eec0de205d90b3115bb31c1da493d02662fb33dcb65dcd680cb548433fe9e0a67ec0b352a903390d5c2742d306276fd8f6fc3ae32bd2496a3f0693f178a528ee1c2df6701425caa647d0e0651809ba3cccf3e6db5418b15d1b4daaca4f111b675bd5acb277ce5cf2d84c5a2aae8222805fdc618df58be7133b685fa6094f7fa7c3edaeb0b7686a18590a086b3e7ed03b64e339de49cd79dae5f92e7fce2e7d71b1de3869a99bfbce25bef3a0b6482a9f9c6da8d228989bcb5f1dfdaf2ec6395a0d8b8979425f5395b1af29c992cb4ccf566ba7c0afbffaacfda474eb47e198e684db188096151ff776bee71275912e2b278933479a94cd77d70cf48d3a822362f3a12bdb95822b7728e7f48ad0af5fe375614c6e3cfcaa095df949fac1d1fb23220426a830b3674e2a48ee4c675f4bbaf1318d2e1f1b39b526b31af3e5f2d66a2c6c15d097e41ea68bcc5ea6a8da0edfe3fc37e0dce13f19217f5a901daf60a436aca6447780786300400eb0c82330aac637d7166e912246ef9ffed4dd1f55dc682ced90e4ba9d4ee1ac273f02115c4159ff14ea315ba0a5ba3c0d2b485dc931fa029bd567b96a4ca62ce17e6fff9a996b1c8052b76df2efd9b637ec1cbda1270e9d46c545d8ae274c831eeddb441f1f8b1c8b4af28996eba72e0b0d3507da9a923a6039be36ef41531d126d8498f83d5bc1df879cbda4a73da1ecd71914635ab28ba4a6ec32d6bbcc0c5d86ebddfff550837d253b7bbd40a824b8c2634adb9c4ae412189149d00a3e77c6a95d09ff7885af4dfd15d2c78cd616bf156e06d9ddf26442a2dae42e24a0fbb868c483dc5c4e896c1a3540ac8aa66935f8738e27e01c62f3af2362d0c27be70fb53dc09c1099d87d33e0c483f6e99d62bb5e7c9a1d12b54a1833569aa229f2224d5e95306abb2219497476da6872942195be95e9b2e95c92fd3c2d30035cffacb7f343d73b4cea396c2dbece97f10917838be58801ca6b3baa721e6db1c0cd71fadda0990572d8fc5c97d2facd4b365d8bc8c3c6104631e269c261d0e48167fa5b6bf884e41a00f855eb35fd1b5f17b21dbdb8cd9ae8d1c501b67379102c53fec015f19e6556629f3f385c8403cccd84c7cdf1133c65605051cbe67593a79701d09d714509bddc1f71e0a9863f456c865e824e041d5c7e4e411584c87d5c82ff9f6906d908a223e023e760fae53adf4267b6241c15d957d309aece790eb523326799d659603958886fb0795dab13fb0cb0212b84cedecfe4ae88a6e3cc9a4b9d503994609aca48f60a124120296065a7de2dc4985793c24cf6a849e708ff44236e0c83d831fa4ac8fce9b25947f8432fb1da499cbaae74a9003443350970e31c17b5efd6f317016a6a7a07894e13b8cf136f3d0f711acec26023be6ab981f12efcfe77438ebc093887c2536fc8a383164e7baa329c129ccd1935c9c0ca4a2a6267ab01e7afac3ab47c106d7b610563a5d822920ab3d3437fab93f3ac3ff1dff13d84f955df9a71776c54f0a86530f67ef1f9f4c954d90d5fd7ce1fabbdc218529089b29c43f116257799679916dd03081f3c931ccb214b1f56004d115afe31c39be017ed6fe7d1b95feb8f6e7323 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 96d9c6699e5385cf847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef704d6c3aee7770bef2f44721be8cc326a80e524486a16a0845f7e22e5ee4e06f5b036f5fd6a857bfafc069da3a4e39f0e14eb7284bcc61ef0194f345ed5ceb097a5a5f730ee63e76f8acbfaed3c6dc4a06a7e8dd64c47e2de7324df9acc73ddb2da99238d4802cc76818df4548dcec677ff6a5a9d14f4d12cbe3caf8c320b4fded64bd591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718b4f1d3c45bd14f6a87589362f5f9549ffcf785802b2c6aa54eadaef93dc655eac68a9867c9b9703abedcaa540146ba6dd8acf7dc317b8fa4c139626713ffccb53bea3d6e20e4713c8f842e03b7fa984e5827c442ef93353bfe2b5e566eaca8d9d4f0610d655f86e72a1fdf7ff9b230d6c4b986bc9465e175a8acc8efa2c174c500666d3d0df2a9c4df1a46544739ef920865ad26f40309b5c838a2ddc5beb8bae1bf987aa9d7c082e8c55c63ab02dd664e545e505b4aaf5d606136b6b01499a5cae0174852224ac6bd34fd5e2e758c4342fabdfa3d46a9a855e12adccbb73488cff3d55cac398c0f45c467b94eb342e1845969e7d511bc7100f886308cbf22ce3840cce7626ac93dfcc4ec2fba1806fc15c5f153a9d1166598f25555c32587637a341017885bfea6d194eaa1c747d928f53e1c873c2ccf292bad468d5d8946b00edf3cbead3878f66358de75d68aeb744cee5428ce9076e0681ee875bd62e9ac8a107f6b55b76627c53338549c3f36d5841ae1d66d6ace1d4bfadcb51253af7188358276f8235878d626df15033844d76ae946ae6c34d054cfad6c3a3d72f7f1d9565a6c79b5694dcc5a878c6b4d33bb9c88dc43b130348082f4ec269cc0d4bd5ffe356b5695bb01c95f8aa9c30f5dcf320ee51aee3acffc7192b75949ed6a68458db80a8f71573b6eece513aa5b060cb77c1fc6286ebc198e59a49c95190f49b3e35c320d63511f637cb9cf17ca9936787aac954bcfc655aec8b4215861a87d9f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61f7de8ac4de46e6da6564bff980acf66186fef7da45885dcc62c433e75ef447ccef8a773bb2731a866832ae535f0e8fe605371f6b35fd60ce288b5f080d6d9bdd8748d4feca47e90322bf86c849d362f4bb61d7d84ef827ffdc63869e3395f630b237247aa8c100678e446e8299f39ef19c99aa6b91577d4653f85bec89f0b1cf1f4ad91e2063e5e4df9f52c33af97529f8de298d3961f59fe6b83ed4f2d64d034533f56e1fefb64f1899ef563ad71b5fe21be99f0e8dc557cc8cedba3cd1746d3a6ac2e697638fd8a43d681ece3769c8980c77af6adcc585fcee94d28ab163aba5563a5c7985720248662bbc2158dd22e04e20b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53b1fd928f7a55a8eb5210e7bc06b36d11af1433797c26ef4e099fa8133dbd6bb4774d46f73b874602588d3f8966479e9414ebdee87ac54059459be9724949e7998ae8018755d59ebffda76a70a64ef09d3a438e734a7484037c739b7bf71b658b779cf647d420e2d73fc9fdbea2bedf29c3b12c54e6967a9faeb87bd9cdd3f0cfd1c9feb42584b97a935fa04b8135fca53333bd2bafb807ff0742b366f2877e793cd948b7c3135457e46ae107c6e751d4159b8f914b7d59f25a2738ceddc299add2b43a2f6c2549ed58476b01a14468ddb6768de8c1049c676e335efeda23b3be4ddc7421999310396497c74fe604dd03d18bc76dbacdd06bc740ef515bc3250dac8bdbb4426d9f431fddbde0f34c1e3680dc94d4d3dc484e6e0463a48cd6864edb3eba63c788047ea854551abaabdc15cf25fe592667f6ad0746b30f85128eef15808e91439a68dce77dfb8e7679bd8b5a5c1b9f75bfefdc7bb0e9a92b5e2b2ca5e92ffa6e2ef423859ed3afabfe279a9bdac45971b80f18773105e8194ccbd337d48c9fac4b75a38cd9432d1074f425f398ec4b2b16d7c9a9bace0d87a378f7bdcbbd3e55a9b9667afaca3395ed4e28734f7cc33dc4b04bd18dfd17ad39834a94b98e7b75e47be1596f7ab6f70ddcab77cce66d2b969eb4c34bb1dd0a13861c4db47db85839828c6ec2d744268e6f036d96463595fc836b5e569623b3a02227b1c21a206e83a9c5b3ce1594eb9099174fb34e5b5c333e510ac2668a704548f02b47af007c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95930a65c2344510a450b9c59c24326c16cdb447231a026304bbcc9823c3a218989ef2352d445ca22b6b03186407d7973b4117c2914555acb33b4764515c4a37108306447f9eb200f8572c8467a089b824769b7df39967289a93b7f55e1a8447f862c1528c3dc4684daa9632417622c950b617e1a074b3b7ffbc23576a63857c1f386a0ff2a151652961137237ea346e691c4dabb45562653e26a806c6031368c17421747ffdd4725c02b40fc59737a75ba713311230cfea4c1be8a7c3aba9b589b6180dd701c4e704d69a0684a33adf1802eec804f44c2923aa8a577c34a4a678dd2446b7546af0021df00a431241509f6117cd32177da708a2d8472f8270e96a4bd21091f5d28b13fca8f7e2abfb57a9e4a522d95896b5811686e5b23d4577ace10eefdb9e1fd84cc51918d592857526c83f51c60d4210d92a425d7340a50423eea17b8be67325a33539ba09bb734eca0a4c365170448a126721484cf947933cc984cc7662da79d65601c3729881e9b4390a99b0ea62fea97eab9619d71b7bc282622ff0cdd0e72a3c8acb7449153df92e672c5c61b40e04854b0b523398a2634b727dae3657ed985b550849d51a04f3318892f7a4a2b73c8c301e2cb5aa60e5438d8962d8a36857f08c075948095c86de6bc34e35c8caa04772bab591e0137c4aca7c34598c65102e80ac0d677511b854a8829c08ea7766eb04c6047612aa83c17ac38a545a2863161ba3bf6a8005e9fb560597162ef1299d621b62c8a7b8c08e3a693faf0607081c6da8523805999e8b97056b5385834726bd7995bf6217c5e70863036b81c297eca1995ac48b6b7ab0ea85c3667370fabbca8d4c2d758a80bbf07839cb85d9428af1eac0d7c083567a85d13515ff399be3f5931d992c953a664eb8974a434270b47d3e635618eacd0989a15eb065348c34a19442db928d1e8b2b28a0858ed7ae8a5bc38087cc85515a344b4cbf529d7560590b3bb56de5331945c0c0b21d5bc8751d9120182c7348305edc765787ac9b784ac4bcea454e6a4c89132e6cd0a477f3bf43da356b66a8bd0980146b5d5137262b0062541960c0b19123a549ddf31d1c188171238259fb661e17363e12c57bd873c643222d014a2ae15cf6112c7fab407fc12b32c12ac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c699619d01b19919263102f5ef2a0c110752d3b34fd489b7a328638210307c6cdacfc6ada87190a98b0d008644b91aef65618507a7f59b89e7eb36998d26befc4b723741e0c35cf73e8041cf51af9832ba43b8e95e368974c1dd61ab65e24a87820cfae295d0ceb8bd6109b85174c80869716a6016ac8190df173ab61c4d3c4c37ae11593ac9a09c210b663bfefab5eebc30deb27cd25a8511bb2ae87851643b50d1b4ca5bbc66d49aa409aab9e7f3402ffda93abb53acd45bcc9978200e94cd4d617235b52d9297d4cd374b998698d82948dac3dd780c9336532c499c479756d50e9048432ce0156cbbd9c85f5ca06ab57b62981494622a74807cd881a58ea10a6e5c885fad611727441dfd52834d58b6408c7d06209bbb224a5d01eef9b491d13226684baa5a1a771971dd112ac668108963bb1864aa8ab7913917c980f3ac1c435457684ab758569247c98286b2cbc78263f1cb88478a931130b496b12f7428087162b6d525a8216061a3859a7a470cb9b88bb0c8b1e21ce4977a73fa5798cc814ccd1aa84370fa408a83e73be1e12511a59486c49c6afc1367b85231f47cb34c1a8f9a963cdeac7fa6076eb8a657e647466fc82663884d7c70eacc760db1b0be0b30779c98396aa3f2004976c8493ab90ae60996056668c8c2cb9065b6a2580a986d9853c071a02343b8903c0184991e2a71298269a17f64bbe1b6b51d0b299703a04a22e17c33b29634dd1766be40357f33a000a52597a3b5e4852473d886e06db52b7605df5fa4e0d5a0f291b5421e2c1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818db252cec8cb627455d9f792d7047cbe98b74eb26c6971be56b7219df092e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca1cde599b2dfc69d59036434cc0423337513fb9506452bd8f42bb82661ad0065ac95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = 2c4b08525d8eb581cf9dbe8f86cf3137f7ed83947ac6d197a6f6554344eca19217a703e8770b41a1b1eebc8c22153a14a84d9c729821d7e39371a3ad5e0f276c97ba04311b98c31f7a618d7731ca511078584ddd84ebcca03d033048fbd532952c9011f44ec8a4dcfe1d22d09745459747cd7795f8e908ba3f9cdef9bea90398c100b173082249d99c88d2a0866ad714d1c30704f0821bb1098b3b4a77363d7437de00ab99f5d2d2af2e2cf8f2fbdf957283df191cdbf955ccdbe360dddc9a1507e40a0c6ee21e4f78bb8a13bb3bd8a1e5abfb07dc9ab71297f8fa045017028c25987b33b7224dd2cf40d934aa8176316784203e59e77434e1b705c580038c4b417867d5aaf5578f581da5656f639a4055c9a599fbf85f52af8776da6e2b49ddb24ade772026b84cf3fb75a2dd45fd94abb3561dad486e995be3f5ba49d0ad65246612e121860ca05710fe4549a401d370c1a67c58f9a19ed302d7446184e3eb712609584ded6419f020d537717e0b8be66b0ff6ff7bf6db9dc2da68c05d2a7bee7f52f108f9d0caadccf05181ec347fb7d581c3deca1623a1d9bc7e5654bddd5c114ff9588043ae286cd2b3879c2d613603796d07b351c821492a5f9efb7ea90f2d02cf57db9db167ec4b016da3867e805e7222ce2de3f2a7b27c750a2a936f1b8f8dab3e574679469c6f15e891344e8b30c6e7350831acecf4157cda632f66085e2f9ba6f1b4004e72c29c97fb16c1f986ac051a490c83a65e36c2f8858f0aaf8952ef8a18a1a83985c0536b1304a3648d216ec3326c3770e1729ba0231ba622c0c1420cca16f2eb1593db56b688ea5133d75af1bca6ddae050b82233c634d607238eb61c5e6a45956b4250cd460447e3a326a9821f2be6bf099f1d34d4c42e8c6889bde923a52ea32703830e7e92d2381a46b5bc62ef1cd38f0707e2a115b3dd7b098544fe16fbae58155ba301c89758218de4ed80113477c3e27d11f6b66b5dbe77e7ffee9999fd08070a58d357de3362ba47d9d974216fd2686a0a6d7b32de1795b62e90f9cc09348033462bb342fc68d703d0a9308dd4961de35ad20d0c2fcbde1e15ddca139c134657625abc2668db40fd555ffa76cba4d34d574de6384864fa14e541f2f54d2cc54824446296063ba060a2a87a1809dcc4281f213b5bd1ecf56c90aae7aca811558343a01e28d980f5108c14bf411b4e278d4c861341e51faf804b67e4dd8bddef46e5f06b18b01930f53615f7a8bcaa5f5e1bad9c9bbe5c095c3de0cd4a351066e11e58a40fc7cbea308f540becf55c4db86618b7821db519d7d64078c6e875e4edbfc49156e1defc0a7910cb0d7804e2cc651add9e9478f3a91eade16b683545362947633b620c078cd8deb7483aa8e9497ad64565863f360b95cd0463fa24b04e6aebeacaaeaee335b0bf18d36da9782f4e22804b7e00b132c0dc9669fb8aaff619c824b84c4ba727975bd3d6c39f9240243a8a9f85113689f871ae9ffdf7b0f5d186844c80517e05a59a30ef7c781ac3a5a48155dcc514970f92bdc370d7b8a2a89a4926e68116a1951fee233f4aa28f60867b15bb12e470c82154d8225b7f637028a785dd08aafef14ce8e7085d8b83575f65768a8e5538018efbf627aa38bccb5ebd61c3ca8e8652598af4b45b2bd0d4a6124977bfdac2659eb23248caac6c86c9a364698e20c2d455e34dbddb2f073c9dabdbc21fda0a987341b926b3902f055048365d8685509b868bc510f57dfd0d775a041acc0e013a9e7c43113bf16f801de8cb6783c8da303bb63decb4312903a22e87174847d33c7d88b8f6733088e0b4cb4de9299d641e7cc9a18e7907b6c9c0361fca64598b8844a08f1a8d04d0293ca131cda0fc5b66301b1488a49f2df5382e2f4bee501cb92d5e40fb8416a1970c9be2af98560c22ba517fc21ba01ba3d9320228aa851f5287e86b322219e80d16877289f80d7a4e4afd163d2bb59634a04a1a8817922a06ff73a97044a02edce8b9d42df44795b903b86fb0ca5a77ab055c8da28a9f6fce33e570f4c4210f22ccaa68bb10a2b1b077372b9875864bd2d8f396184010f52397fa17b0b26423851b0dd63f3befbe3c66769252066d2c712040f6fb95e71295147a5a643be1850203e1d02465b83e18362c7138890c309f246c9c42d19f3dc300a88cbb9d92b461ee7c228d353858dedbd83c001f918a4c5b397 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b2def7d258d8fb2b992243f83223ec4fd67fe9aea070ac8d182ddbf906fa1e0adcc91e4d98f65c8f4abac3bbe7b434edeccc37688b881bcb68503b54379838bcded0b5bab3073f7e7965b694644c470a5148666c7fa89872d39a006ebc533c83f38dabfccf6f073331f04db694bbf5feea5b2f65e96798b7078ecaa21537dfb5746c76e29775852e5850f58cfdb2e8a0e90530a57b387b1c42920ed04096c3e0bb6e9bfe9f84beb0b74c47bac678b10ff79798573fbca5d8e687966be3e495827adba63da8a17564a3e78d37b3a4991993401c1c6b149895ffccd3761ce35a5d35a723e40eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685206bd8d44a3ac8f8948f2b7bed9cace27ab62668ffd8f2950e0c9ade053a4c4ca8e408da907a39e33db78e6065fe9ecd50a5a730595ae5eb3fe38d5e2edb79dcf345f1dacf38a1732c65fab8ebfcccdeee822a7f896c3f3cc43aa0363361708ff89d63d4b2dd3cf9c5ce3379b1d53a63eac57adbc915113e6acdc30fd74a1a2e6c23584ad1dbf844409f4177ed79b19e3e20b3278d8a2e9be8556f336cb85d694066b6d8fc5d267a903c6f4cd54dd8e187d9e438d178c83957d6f016b835e25f2ab79d4f80cc24358b7dd3bb271039acc1741651fee8b6fffac473054d5b4cb3bc64cced7c6b637cd6360e41fa85a4bee3d2b64436a87e92de6acb763a23ca9b7463023148b0c4888c0be8d954e84207f3b9436b77b09c79fd7e4385a3ae97b5bde1afa0c64edcd2b668c696281389ec37dbc6d088fc435d6cec85bcb4b61144faf0b6eb1b9d75e0df43be293cee6fbd413363716ebbc48ec6c361a48b9d871bd5742ffffab296d94a92b508cb794f2f69a8fee5c2d748d8fca8cd228471a8e5e75b3b0df86f98e58f80bf530e09a34d166cd5379777d57ff0994ba8e66f9ea7691fb973f45869635c6eb277c375606b911bae22837ec86bd47942a52187bb2325efb50f5be423476730f40e62b9d3cfc5b7af5ce9fb38e0334906384eade945e995afd659fa92c1f508813e8b9b9ce845ba29bd3733228ae960663050888bb98a0fedfed6fb34cfb6ceaf6d9b98ed6ae455cd9b89b60685defb31ae7dd43ea845c713715b5bd5ad87bcce4cbbc9d2ea83d0fabdd56d939d01b7d590b3083df405b2d724e2c44b61f3bc24d7b11da3de5889ac52b7b792ec4af23d3d3959eef3888b8847f3e0695b5b844e8e3c2227e8a25057e707a50e0159af456fbb2eed3b9057ff7fbc1740bae1afa44138aa2b7f3f70c08db6ac745d08de040c97253133ea195648f9f9e6c6394940b6ecfbe8845fec862da6597a46f65edcb5d38d3eaba4a092eda011a32462e85a74f5d9d44b4346389336951495759305e9c23dfb06bdc762d5e9d5cb84e9a68456ad6daeae85ac6453de2bcc103f3fdd509309fecd8e3b3698a193d83e6fdf757e9703bb5f8cc5db7b88b812edd74d6949e0d469b94dff7fabdd5cdcec2ad97a71e7c28046b06c8fc8ef8f04296428ac7d3840acf7f3333d84f726c1e4d339fb3155bfc4095b6d465657fcd780c488a0d6d443727e09363c45787f71965e35f6db46104bc18bac09a18690b37c8079af26455320ca539f58ad706239e637e6fca94ad90cfc1e583439617fb134636aebcfd6a1b91b403b070d97c54cfc91784438708bb286ecbd4b99083096610c53ed9354f45acfe91f47bc93fdf75b367ca8a8670f45cd118bbc72baf235f74d2344343b5eabfbcfaab439fe6eff07cbebfe2e54e58688aca733846b7c68e1fa87c9d5244ad324698aacc579260e94fcacbf8da1c8b6887ce10c99c2357bb9219ece1395c6ed345081c8b74d5a9bca6ec9d79afe28af8951e7ffdd9b39755f6d34cfd5ff5757598853bde4520cca34c8e7d097a7cbdb7888b48b67f3a8d0ceb89aeb6374c97b130a658b11cef78d382422fda3dd7a66cf76fce43a6fe9c6bc73f4a64646ae0aaff9493f0db64e77d2a35eee87918bad875afce2875f8edcf9668d7b5369e942d8df06c63c6d8db92abbd305308ef166b5f41de7d09b3760c944cd24c5eecb7c780b39608d3e8ac3d31f89559ddf76ceda6fc035b9d7b7cbed0985a2f0b43ad8849dc6ae90d6fa131e5bfac2c7c11eca952bfa19674315c9eee09847c49339c3d8a9e39ba19ea979ab2c504335c03da056801f4c782d95dc2e163a043cf2db760edb7772c50cf5a62bda4742d2ea296b121094ab5cbf017755c74b6465137a1d32f4ceabdbf34a7471b45b166ad05ec69238b030c31485695a9cd615db68c83e457222d85960ffa8ba6c8cb5721acbca1a7b09b155a555f406a660c325c6166233c0500a0475931b27481a015ae521c7050ac2f605f032899ec655f0b662d7b65a3b21680d1b53ff554987a99258dda8cc711a18ad8917f838cf0a16d4f663bffb33ae9e3afe97b1bc5f9b1a53052f8907145440664bcb5570a368044151b0045515b94b7b8073615b2889a280e59940131ba50b016e0b8c6df2b34c29023e0773a06431397a68580c47610b50e025b0fbf374c40c1ba82a11b69fa9b6e522d4bac7fbe737a18085056bb7f7caa2c4c3bc5b6401f06b102a3b5673c7c8f1cb269438618f9717640c76a4f058ab864348f068691f95996072354532f3a3b6ad0e1448880cac03b6e2a84717158339c063147db0c586032b7d10a69e17c1b62c1ae5344483676bfe8928d637aacc4b613f24d7e2a46de3449f17b0062fb209cd9631160ce38a95361889b167cae272cb23f85bf34e14c789472974a176c567756c1c0ebd9905cea70cb88a55c68b476f877c605390ee1274c07cb95939c9babc97ec51df82a9b7d0908ddc3434208911142ca9b8620694bb3aa9accd1bc236a9a89547a26e44816ce3846f980c893b29e6e6c99580c2d0a905643f556f592ab03228cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77d40182bb2524a87e1cb511e9d591f06b91a71594dce26ca8b20450b899e22c679aa7abf5b178b1637f998502f7c7b4a03974a840c9dd041c43017d8f7927f94989f2a16a1f7cc9b09908da388a68b13f39fba43a391d75c76148444954063d9163b6ab1509b03863dfd62d94b59e849cb545dc7ba58502f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2c40797fc29955960dbe618cc5d21eb9ea720d77c3f8b3c680974fd8c474f9d588285609abd4166a45cbab974ae884c7061c6f129a1de7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb3f263bf774623a37bcdda056ce232b2b2b4f2e22f6eba975c933191812c9ae55d6b7c6c76c10983b02462e220bb90c946573e3e2bb87540034f870fc69b538780090c3b89c18645569b124c03680dfc10cd3050b33c16740c54916c5ed1604ec092793d097b94b4ca3474b6d90382d5cb21e8bc8488451af2492310b7239d9a46f8c868890c7b531834b2bbaaca7ac34651b941d32477193cde0a3347323b77ca97b997c429a2544a1590aa8252d6e0832e128262284908ab785543bce3e6aa43d4005b469eda56cb28b45c44329cf7f79cdebabc3a9c6558997e04f980c562c852a103fb40ae24e26a8bc8bf014690b9085f6e7bb947f2ce93550327a61900aa954cfcaaee412aee44cad3958555d18b59a0835c015cebc77242052f13a780bedacfcb9998df665a1ea24887b570f36198836c6c57a95de6349d031b2b33a3b6d52292ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c6890c094b625a5b747b2280fd300455739af8d97fdc39cf741128c03283f0ba09fbe19a24598e143b5a856a5b41334839a6188e769f78aa24673b3f69c51ae2c5ae98bab4b0254ce8c85204e6ae38b80a2f24c162427a66b09debdc8235e96d25e96132617dff682cd03896290832e3d7b5959331c7025868803a0c292ae4068f1ae8152221a4607bb9e4f94a5b98701e027a8ad0913b0bbd0ba551b00b0eebe302e5450681878992a616aef08a6c16175a5c22317ccc48200bc7452414080adf9216989669a560caa70320938c812ad12278588965525538921e5920580516156fd563fc732e37e5591e000b4ed9b93211579d21cde3a951395a21289576aa5c0b0c87bf36acc28c0ab51fc86da8cb00d23c40459088a1506d8a2168f94a365fa56ebd751a51c84342931a5d569793569f8fa21168ac2df9820ca3134704c533a399219ee79f4571b1152c95333c135e442d5c5984e55516f958ca38927773a2aa526b89b79522348c1244220dfa84c6778466d2a287a774141b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c592a50c7a070b3dc7e107eb1e8b96d62305c13327d729bf9d97c69f1fe6eed2b52e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 1ea5056618b2ebc32b56af994ccf662bebc5cbd0d03462802395fc56b48ac8dfb8ebec2e00a9bc3430c9e542c6953ccc18de1a47f6982de199bc5e0fd01570c3d5b1e66a294d97ba4c42e3ef500cdca834c35e19f437c64a8300f9a9081c02475cb2e5929b25d9c4108d3b23755d1395c1894be55d6471ed29559d2fec0271cd4d970741a77942721261b67ec50bed1e2e0869df8889932f0df5549604b1bdc152f0252baa17f81a05eb24c6544c538d4a346f990033f1786e90bf9219dd04e32f963a2333e1431456c77e55bf56c6cd0f115867697681db95259ac3331c9cbb5e60f514d802334917dacf5e736c739344a0fc3df794fcf773a4c2c3ef80c0971e63e05ac9dae9795af309858ed01d2da97797f09c5fe68b4859938e12622e685525bd4291dafb20e02a01a45f5b963e281990b091e7ee7949f3eb2245a31e6fd3c9de6163e752f676da020dedf22ab2e325d21470c13342fb72d21423bfa1457b0fa7c1b27ce04c5f49477d2d66cb5369eae5695643c84a233e2634c61bdbcc7ba0cd928210554f7aa0166def4207fc7555a0fff3c8a91dfcc9c5a2a3edffbc46d0a45af2ba4624458ab2d2a8785a7367f7d12b4f4db39357d25e64ad17cf1c97d0addf78b0d0c2c4d5b61077e1688650c9aa9d59f2f3de73395052a538cf713a4cf5d4f5d8b74c78403baae3352d0fbfc1990d7789ff039ab951416b649ffd35e4ff1d30a5ac5a119f442011742f12ca39153359d21a47c27b0f6e4497e7627cfe578031206bec2985b976be266a29982dd47cdfee81cec48e545b9a2290d5244f6d23ca942f06f2f5b410f52122a4c9980f43ea1d3a4e753874ab9e003a918832ed60767251a24ae76e05a07a2672541129709ed5f5856903cc261072fcab148e5afaca434d18aec3cda47866da2d59a0352f7a6dfebb0a4f1a5d4d62aed28490f02e3eaf1fb13020f2420b06bd4073a30ae47838c58e20e4e047d52316983b5bc6f478866740fab85ca2f731bffd4afe9ad305321e9a2d58ad70b62fe5b2ceff5c3387a94a67b33137db6e8ec4233f14db67a49ab2631978322325bab6fee732df98b148e258891ed365481b53404f8bbf8257e3f6c0433e36a57761671753f7d0e9106325e7756b3c21fc339bd5115c9787348408a96e96d776e1cebeb0bb547cdaf7f11f3203fcfa1d431874b31ddc6594aa62bdf58f1bd7bb1a2c79033bd1a2ce5e9f03e6b2985c73a5ec3d570f906f3534329bd8f593e72d7470515b2c813094b3942d6367b173dbc87b9bfea5c66d026334d413c20a50561811c064d540538e8dacda28104f34ad6f9f71fa848b8029e3642db710abf3d9747ce271a2c3221c5fdb13454e9d325d865037492a4fa5e84861cea263a3c087e030214cb076280e68eda408fea07f13eb8f40e6c01380bbb2578723b54222fa488ade248fbc237511d7369b814df3dacada41845434f6cd8bf8733c51d19a65e08359432140d2aa6cb227e9848f5ddae201c7301eebcf8c97eaf1f9d98ec70cfd4bc1eeeb30968cf906a8a8447eae658a5db0eef30372deb6faf96a2878232650179cad594c165621f2fc8c250dd1036b4e34a2361ec6a14ae69b7ae4ea909d53f21600768dce5e954cd770dc9430a5cf7799fde0023f8b526ed13eb0a4b55b90fd30e11b5d4087725496f9f435904ee3ce44de3ed718689cf252f062b782035879627b752624ff076a920270c9508eed81471a4bb58769d1fb0cfb5c71f276b2badf29fe78410927e5f754c10a3020ad82d5182b9fde9fc440d4dc437fec7ab11d54db36ef73073204254ea1e9eb2e0b94bb3f4684ce9360d37404f91a490c7afb8bc7fc80b2a1997f78f90d22778c252a9fc3778b9a47d5178403f33324f684b872cbfd36f900d0d45684194a080ae04e8fa8b7ff1dbea5a3c8bb3784540ea1d3bccb94e9820541b88bd4c7bd4fc8fc130381d7bfe45a721a3e93c0d4a996ad39d4788302a731c8ed43e635c5423c44e7ceab90d3fc177bf3e70d814434324cc8809aad09a73d1360b92270c643c14846f4d19efd1c3d70b6cbbe8caba8a898764fe107ff49e26cd1ef419d943dd68503ea0f74d82ccece18213dc346c239cf0511fa7a3a267cd55414ba4abd277643f30890f20b0f855ad28e0431f99195db57799f2b2f66b798b2f46b4394a7a4d2e2ce0941be0ffbb23954ba041e27d0597c20fb +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = eeeb8867be7cdb1fa45fcc6f9d05afd103835147647a83d1ee17e366398473d8e03ab3b064e340f4f986629daceefdf473fb49635bc38debcff0f34c5175ae0fddf5abfe9cccd46d659cfa6bb6fb51de452b09c21b53dee9a3ce05d36a8e1aab2c0de95f35664b4999cc9cddf049c01056af6aacb0267d8c184534f127fb28fcc94abcffb81efe20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c808edf520d3778bd60f8db5fe06c3520d35e97f6b5793bdac43d4349387b637686cbcea6e55e49183d41fd7c3cfff5a398ba832dcad4de7e79d0768122b7d1f5edbfa58e49ff24de2978a723fb985b939459bd81e1068ee62dfe5f64d365e6accbb8c28db84126cfee8d0462251fc2f075cb580e9eb828616cbaf45a9bd99b0ebd86268cf59e823e54de984335af59924fbced43263af725895d7e7e827532d35c7da9bce420b46aef13c9f33a427bb5a1bc646f7b54a2186d527e3d3badbfa21aa39c5577bcd504e7f126741fba9c2cf9401fdfda14e9a7bc9f7cc8135bbb0c3180696093289f4b19539c58655b8698a6de339c9490be8cd4ad43e1fe5ff045b5d27c2d3407cb575556fc21ac51f523389f8d3f31feffaacdaa7b5aefdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd42d8fb7ff8661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5ccff2e7aaaf9f9e49b0eeeea5e869919e3d2b543913a4fd148639da8e5d4a99d8362a84bfb6ad20b8acf9596df4187009e7b77317d4511ed7458eff9e7a9b8ea6f4e4efb1d624da9e4789775abcbd2657aa4877413e4ea1e446db6cd9746accafef9784bf3ec0bf55ba5c97070ef64703c676fad9801762e9fa45d858732af7f18b47e07b47d8eacad5d3cd35fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e56cd5e6c5d41553ce7de2f3af273cbbf65a44b4b6dabe5eb341464a9993effd671481592c5a655d116b963975007be3503baae3843f248f586577fd098f42f97b8e3dfc7b4df98de5e783af5d833b99d79484d40ac05a6a7ec5e9fcebdb38f443c7365155e4f1cb7455958608b6f503428464d89c66c2d9c417445416a54aa76f34b1a5bf2cdc3f7064b6d0a7244ee70b6acb01c033c5b1670a3ba68020f4c04bf4cc1786025fbc56cfd4f3b34ee4bf7d1c9764938695bea53e6adb6abacfb44f214ed2c29bb867379375bf11ea9df194b872a7b684b3efdc179a4add943aacbee6beb93f5dbe00fe342d088eaa80989406571d1b79d08f3eae15b81741af2e01ff710afdebfaa3c9d74392cd64e71f363e03fe134e9be32b6b855fb76e15b5c91cc6c3f85daeee7e072ad803987ca7f35882ad3e413b6d01b7df3c1ae839627f2b6ebba16f5577d95bea2c5ab446ac8e57acc9638ea07599a8d335c2d1f388cbdcb9f8633ce2f51c8a7563b396073ddcf6e7b8e3b0fea2e5731352fe4c317d8e128914d1f4973e759d53fef1735386b8749063fdc41fc731b2fb9c665cef0cc5353b79939a9d5f0acb54afe3c6fa56fae39d7d0353ff2054accec40311afc4c6faac3f392b014ba88fc90eb868693eac83516336baa60207dd518fc820bc8b0e76c664f3cc8e6a5cd6c34bf246a5d52f936442eef8f9557c3499664ec572dda5d743fda180d95ac2764f19e67e1cff77f08b2320ebea419f3a39fe32a17f22dedc2f1c5894318b591e559200fdb5d8bb735cb3f7b26ea1644f67bd33721cad66713a4c25cae05ad973cca6834c7e7c7aa9bbbfe471abaf4d92c5242c388de17a42019506dc7cb6cd7315437595baff1c76c7862057afd76add8e852063bd17cf7797416fd00b9a6452ca040d839220372f7d44c371e5a3fc5671eb6520384f1d08484a68b779e94b3f6aa5e74ecf82525859a3945003c7fdef3b57cb5b43f14a291ae982ddbc9d97eeaa624dea8c36c4b5953ed45bb7dd96d50956924abbc717e5b7689751996f7a9e64499aa778b9c4df403727486329678790bc8623414436d79beec46f4be2d423d14c91e54e4ea4784dd4d5e30f5734b5dd5b689e059ea8ba7dcf24146a85605e5764dd5af7abf5dbaadfd0492ca6ef5493597520478304696fb3d681134c5d3c7efe5c54ec8dd6588798b31d6890eb842e0aba0560e7b8ebc4a355a23b704c6448bae0a62c2473c1dac43425852245faa8514b54c2ed51305047e5b44618f166cc329172668306984151c31cf04a9864267a1ebe30faa133fdfc040adc3cfa49a3c0f4ca85d7a52a72b71f217278fa787a2e3047922bd339176cbd5049d498708d65f2beb4ff3e544f973a4b9e19e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd39e1630db0b5fd819dc4002297a205898108050c9365014351f38c017564d6798a16382b6f34907a4850a0183b27243ec4123ce3b00cc682c1cb8a9d97845f5d24b5fc35c7e088cbed62910c4050ea6b76c88c87f9577941f6a5b3f2b614c94224c26a36a841c3b40469d2c0cfc366ddac23c8c2bfc401ad78c758a6cc1684d1ad400bad5d88417503ccf169481fa437e4a8cf78b907890cbbc1ab9f46178ee2dc6dbcc1604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11df700044a79a809112516a88c2c662965a2da9b996ff92d951337b4b9c11e7947b14212a6f3cf19d2c5d86cab5267a1c8065ec045517dc9be0783194bd846dffc50eb723eadf08ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a0128d52a34e27610d9a902d4151105409be06a11fd3f73c88b79c9ee630a98105556b777a5bc680a803f5a7b603f16643ab0a9ef7161861b3ecb5636a9529a24a59f17a389b61aff5e633b863065f37789a538f8353b80ad75b4ee876a6ca363b6679680115f4b9857bc88b845510027a0e9014621dda9a31e12222522557f8c86d29a499f0547e35a99d81b1a02147dfa3c45beb8a3026a23fd20297d20e33503cd49002a9fc7ff8200ae433b921bc93cf10209a05242788908f71bae849518ba305eef84597f654754a7808d81f2cb62bbb282911a0c5636cad75b53b454a5a923a5fc8e956c9cc527bc04b846b596c9b222a953db76485c6486907f898f6835a6f315ae20b57d3e56953170ea586658b9178c638c9c22c941097838af0123a601d0d4108b2ebb53b46233408ccbad9597633440ec1aff61743f0371ce62ca1977aaea8d98900f0016e5a9248661fbe5c1a4d261c5426a12715af037a5ffdb38b8dfbc11ee3b4edf289c3ab3995959078091e888ac0107467bfda6f3d35516ba7404a4733c8ca4adb010f7399ac5f14c2cf992fa812cf72f2c79750cf52e648dbb8c3b14698bb517166bc1f663594eb9a6c476c58bc103ea7f03f37205c5c355a2633b9ccaa829e3366fea63932550617aa96d267cdf4b98cfe3334aa0a5c7600ce6ab6aaafe7cfcce4bbbe2756b7cb10d6d6cc8c71b32a04cc652c01e2b62a73497dbd9a46eaccc382c5903fb405d950462ee6c87d2631ff97adb38939c4f284489bb9d1072821c108886842f5c1b402aa2e49d37aaae13b7c14b5a748c2dbc45bbe5bc2abbb929b613767a720ba572ca63c2080c4547c9024d2f451f25973f064941e814e3ec74b4c1770542b0782c67580b7a695c2ab29c95da2c18e4563a24101b11084586cf9a42ed62a2bd1570fc175f4d5bf50f8c4a196aea1953199143efb5183b3a905510623efa47c4a52522787723af5b5d05b86d15126ec6ba2201120b5a527324a9895f62959e24aa6f8c95d9001e7757fa5b3a80085bc48bb0d34388c0f6cb647b0a7cb992519922a730865a4032b51708fb6602b08d144336b7c7b65730d8677399436ff5711eee7b935d67054982472b96ccfe7279f1a673bd61757f7b951a5bc9c4b7e52c11a09f350737120e0923f8c1a2989f19a6faa06105391b39b266d9c768c658d56fb59f57020e0d17feaec496f729a810821fce59cebdc24e8b7cd3b869144225ca4b5a5c72432738ba5b939c64cf338021181765891469aa7af34a628950165a1328cc4c2b6874498a8205c675214137e47080624e250521ca34e394e829206df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332ac168abca2597ba39320653e8338303552b419c84ecc014ca3006b50a6f74b8ac57378f8a06006841f972b703a2b0daae868698b778bf6984dbc7bab537b29ec5462463295ca1581e2a60f5c169b494d0b7793af3313fee3742d84c1d20b6b47877320e25aac270e3739b34063b62fc171ec6a6ba7b62faa650496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa05f166082ad3ab0c739cbf0a6bbe2707741d9b5f53a0e16199280a2376c9e5a1781c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = a9a4803dadbdd25f9c157360a733e6473bf476fcd8e9c07c7ef8da14841e8844307bbb0517766268f74bcfb218dd420a98d35ddd0a8040f32301fbaa6fa68a1c01872da756d7359ff2ede53620cb5b180a6905c8836cf621851ccdc3a7490c3b130750e41f5f3f2045a6ade86678776744a7c0c858f0dad0f1b986dc3d64a6606a51bd6598e0eaaac34ad31f888bab22dd334e1394a62ed4e4dec4479af116a8c211a2b4a1399e27966f4ce8419551fc1d79148d0263aa287890ddf3cfcdb409b5a38857417fd8a5ea2e27a1b276200b4e42df603e29887b6cd99fd56074e031d7073bf529cad46c715bf8939da99d13d1cbc1bd740a58a08e381b3b95dc2c269e7d2ee040bc7a6d06589102a2a9a6366307aa429a20cab4b8cdfdf12b9255a23ce45903b0f79b66abf29f3dacbe7fabe5b70432f7474433733868cbc222fb9609c264bd5738627ccef8f529590cdf74ec496e781e9167c91b38d11f2cf12296fc404d49c69db03037f080108b6a68f629ae9a392e041ad4c1d1c5c98707c1a586a624e1586c7f9a57cc291d29a09c5efede7bad2e376fd865cddf0c10ee8f8da54edfa28ad29977f4333e9b1ed6f30086551a718a57dbdc39363f95bcb9dc6c5acdc7b92751edcce0688598b29b1ff7d0b0402cca62e764712e355edd9a02c690d3a7b3e125d8cb322c791ba39fc98b4ce39827ebc6a32414941dcd060d729f6044c88d7fd34917813cd01922fde7bb410046881178e1f2e62fcc9c8d851d91d6fb68c49366dd0abed8fac5db78c4146ffb33b46755a458c0a4b20c3b70ddc7135bb882db104c8ae7b4999771f0b7289c8c78f2c09918be11ce9a39a1e70a29716ec439001fab42e0cfe7b7ca2a65163a617865cddcabf3efd2061dc7fe0015d1ec66c7d7b700d9f296168f2aceef7014d2fc27af8a7228808ac6958aadbcefd617bff5b055be0aab337a984967b1f6070a106424d0f8c7ef56e80302886de677c155fb5327a6163f0ab4f4fee6046b4302331a6b1b7c311eddfd0b5585f8eeae32c33e639767cfcf772f70091b8c559b7821eba9e8020563017c4103e40e2277a441c8a5bff7ac7cd4389e9092d3d47205f563fcd1d7fe94e576bd8051c525ee446dcf66846648839fc9f0a32c426a3814bb399bb83e81b044d0369cfa3a5639f184751cefc6afbb4773625ddf90d5b16ae0c2b0e1c515ed23ea478c27e1c3419e0f14fcc6702fb730f82e298d16cd24c9c2fd0b91d28868e50c3002550a8609772247c5dce89c4bfaa547fa0019f254c9afd4f9d5869efff5ae805bcdef07168580c5c9a64232e2d3e6eaa81df52e8c42aad842df32bdfefb109b33f3324fedacf21d5026439839b8667ce7c2853d8d3d8b463c7861a46e802a0ad1d4b5080c491290e661b04a4870432fb6a695014018512f3edb80d5474fcfe8070b7bb851e0fc2312f44aa1c6d7e243872f1934ddf29bc7f4e180fcf160665fc776cc970d3754abcdfe9429b5ee03b02ade73c3d7ef9125a34b03fe38986167d6eb3363970a99065d5e996d33026e0da1ae583609ae1bdbd50b97b0e33f5708548fd869c120a5841711a81a131022b2a1783e89d2bf6a877719cb8cff6920a1c159ee550f126bdcbe39ccd65d238fd8070531152fee56c5d483e06655db20524ce167f21a0126facde0023d3711dd6b86495d9893d8d083f4cc9ba12906b770eb564a67aca0f62b11aa773de85afe12c13a77e5603249af0c16e97a02122d0ec0f8c3d052510a352a610cd5cc1bfccf18c9c0326c0e48bcce9e05383d9e18b1002cd8607c920835cc4ea5145849e8e2dce0e8f8240e9a10080f52687706ae62baa42d6220ab96ccd229ceb924873a0030a5f0e7bfdb09015d94a5ce039adaa6d2a447806feffd4dc79bdb9aef5c483c6a6450b83d385a4e09ff84a6d11a1fd9b1634dd5d849cb3019e888824bb9317471a96590ed4de34b4334561869291ef471411c47967e362532b92feb72d551893f4d592ca70dab56d0b742fb754d91b049a571fa85fba31f6f86b9b5fdf750398b72a9dd5af31eaddb80960b69cd1b5b4350c591386994354814e8cc38f0c172be358d54b37bb0bfda5048cfe7498f12af04ee886578c867b2268ae289e7fe91433f5c2038ccbcd94ceb184cf4306a2b187d2ede87c9b41095db2d7e883107757d73c1d486d4447b3377da7432a37cc686b7e423 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b27ca8d41aecf8aac1a62553ff64eef56b4b4e45fe39cdae8c2cb2241cfd2525adc53be954aec239e3add71b5f76a3e96875babf8b31edd5f8f3c3f0e6569997639f1c9b5279c38d5ddb3b692bd228ac4480d45077db55bbcf4285c5820c49be2573fc4aaaa23ed84e11bef56d9cca9b584d423a9fd47f76cbfc5953d9f84b4d97c07e706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450c1f899493f3f75ff7961adb24b442e78c551c5b35e89b34b018b80cdd94f7594365195f45cd5baccbfe0a976a86559bd7bf3d220b5c900375c7be88fb353c3b064ced669bee6751d6eff659eb89900a92b7ba84eab58b7e95cb84a5e91dad491ef75a3abb9469a7939796c2f9ce5ca32f83235852b0a96daed4d3c6cd57b5ac91d09cb16f0ebb0d078171edce9596b913e953c5aa67bd9afff21cd261ca814f334244886daa0694378f93fd858e15ef3d13e66ac89a58867574804786c4c48d30ddd3337cd02a7776217acfe7084588455a0a85b8ab5ec33e99b1cdb75541855578aeedb00475e05fe68e8af1efe574033d3dfe37ab5c0ed300395551ae639eafaa8e358748ec38946bbd3d0cf8dfbd8f500e7abe33a2df3b9b96cac0e9cf61e487cf003fa1484ca5e14d36797cb4fc87ae6cd7ff9fcd835befb160c4f5acfa8b75236d9297de4d43bfa7ea5c998f7f95db6dd53dd06875de3d98e2df8f7c3f76dcf8049933daa52793ac10f57ad9ffa74469f7cb7df2d5a485fa4f4663ae75b2a6349b248aaf4853bf7d9d432f8c3ce3b13a9d794b9698869842b81649cbd9482c2435886441ed9a7927384372edf005b5e4717abec398bd183b321134a4de85a1fc9b72f7268ccafbae28ace5dcfce8bc26b81ec43c6b8a391a6f51666e7d60c33f1e7bd4cd5492415ae5bbca5ce94f84557c9cb58ea951fa5df2e444e3dfd969f38284f6dff16bdee717e1598dbc6d3834230c7d22c7cd6a2f9d1eea957f58b2d48be1ca97c92617dcf2ce934ef83f5a36f41c7c73959c8a060ec2c1d7d671987243635fea56ce6fef92b1d6aa26c4cddfbae7526fdfc42e8e7f2dc13c7aedf4835c7d7cdba469f3cfbfab40fa7fe383fe47ab652309cdf38d91d8d86308b73f90d869963fdacdd9c544c95fcd24a77e7c90f3fe5e52aab596feeb1bcd799a3ca95e06447724f0aedc777b9d48fa89ce9488dc8f2b903548bd47afc22e453b68736f5cca6c35ebb028cdc7035678f7f69a9dbdffbb5bf3746759670f51f6757be3bae767e7f80aa75b60a7a0cc99ff70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc895e4ced3597a594d0e28c7aa25859e57bea0cef692cd47a8a73740ee695ae742027a8f573dcb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc96f5a2cb995b548d48294b2fbca97d375b922d3392dcf7fe835f62db97b14739f6c8b1880a53ddd388e2636f8674e6818ae10258a098d9af4458a64c68654ea7d99746b9baef3adab5653a7dc00719b54e5afd219fcd7be6fada3e7357e35224184a4e24b4a69de4f666b33e1530375d70b73aa6da53fd05ff588f34ac1cb3b3f7fb4ab30db459966fafc689cd4dadad1cf6108859a2943e6157c22f9861eee9ce423fe2bc1ebc6c64e4e88e41481ec8c62bf9c009d403dc5688da9d00b78ec8b8da4c5485b67bb83c95dd2c0ca56e45a30f45f5080d469b957fc09da6a097af95e4cd216db3908e36b9f493e9c4b6b0395e05ad761834619e5b84ab33c3cfbd83b2df68e478e5834fd75f3a821caf86d95dd2c3757b99474b579fda424e31e60636d03ba019fc37e8c63ebdeae24a93709369f6ccfe950ab83e57fd88f37cf4ea9a84e14f447728f20bdc532557d8bf85971ed8302785d301a685d2b9ea652633e2e55cec7932126852d12e6f3d943f5acc9ddeab99edab31e79a5bc5c5971f5b5ff6c5da58ef455f45346d3f75cc2beb0db991cf3bbb3d3aff522a9ee64f6556d84c5c0ac7d827a0e173480427ad9f637c1b7ea2816858b3ce52c33caae1fb5197d874d608e8996946e563c8df2faee6b5735e46ce6a1fb2309e87f8d75b4d47497d435f91759e1e1e68341a48cb5c9fbf29e37d397a2a1c75f0f7ebc17a88e00837df4f8ba61b3a1e1c88ffe5a4167dcca144a33ae851a3637b6eda83bb2281b6320527e3b22bc08b5aa644402cb674059135d9c928bc4598019722b8af0b647dd3f02d553bc457bc763883288dbc461e775909745317f67017d3ab5ac283d0462167dca55e7452438529dd715f8af6438edb470b816546d078db0ab2588bb56b2c0e06741cfa28c997a128370c1d72221147f0218784633b45207a3b43fbbbb0d0cac41fe70213475e61058cf21797564b0db1a2095cf367b9561ac2681ab8b6ce7d240b5d277169c31eb99a4b68b92b3ed1ce6333b404e8807b32a0b03080664cb9f0987d2ef56308707b46b14f5667b2ace438701cadd7b4026cc5886bb7c0160a9684d5220d422497a9162d84c2500c0bc4d8bf20a904dedabdc56a92f153770aa95244220bbcbbba66aa89823289a2335898f01789e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f020779f6b6cca633e33fac08c51330ee0bf70e8a6ae4a7df0f2be54b10c6e418426c69c212a33b6b897b31630c6928cc4865606ca1f7ce192411c8d4812645c0655e23553b13c6c7c073e0ac92f35465a1b8a505de879998bae71608af9e943b4caa34f248f6dc679d93033b51c53315aae72d843884c83a0a711d009414c215badc32a5f74cfb3179d6ef26818d7c79393b8bc8b8d212092f2250101560cef4abd4132cb31996b85432bf437037d73516927300528763472c0d5cab08294154001c3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd60fa1823e32935515f90234b7613ad5ea3734a6c0a9422a97dc7042a0434a684083e8bbb40d2c4ebc08496a7261eaa269175c2a8a0aef21474dd4837b6b1c7bc112d67a1c175b2634737b43e5475d5ec9a75827f02091dfdaa20fd43cf59922479a671363737ab1cc307225bb4118d1a714ddbc08b770283061762bc098415e1923ecb3e3c92216d30694fb869b514a314db3fe8da5fd4930ed0979011d8b1fc723ab617b6de420482e8b9fe2a3874b788f0416dcd20704c20285247784477385a1cb219313b700284097acbb90976b94a5fd8984bb6b7121bb020e589804281bedcd78c1cf0aa7ab136c7e7afc206983887beb2372784a2c388a18b1dfc5e077703c8eb7f8a966def46225c8b3fd0f85d6e3a328c8c1bcb0b55d0341cdc866e1b040e09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf04421056915cc0d79830eb972c01bd3756270975bd63e224d0f58307ec2986699d5f536ee6c21f5de6844da70b797c8ef5b9a473624c50647d171682f30a2f3fd7c670595243d59487cab8d0a7727d40350f9bb7d984ba82d8cf39e817c8984c17892295e09ff674a684272cc710bffb263bebf1be44665c85530d13f891026790c2c1590ab6159cc22b5ec76057371bba107ffbf402631297c2c59bd05634ba628a7bea14f3985d2b5260fbc64664bc9ee308694f8bb3c4ba1f4ee43dc4eb4beac095b74820a2787aeef612c0c48afd0b20ebec9417b12c7aa50f4fc86558d36fc764c5b69bb4bfab3526d533de0c2e2bc1cdd4b897c9f990e8987bbaf147a0c4428ab68ca077a2a2d3af76261a1f371fdd503f6d9517a8bb0d53499d65208baae23c77580becd252d006bf27bc11b87c19789384f063538448b98188b0dca07328265f4c4b68de438d8420874625bcd12912078056c7db367a1598bf200f39d2a90e12c8dbe7ae4b780c8f5662c78916af1a270db365ca9097a37525ae347961b13b9b72c68dfb7ad7517dfb318d5385b7343a63f5026bee90177ff212bd6b639bb15d7949680ea38336891653d2c5aec083a8873362ea5e6fb4b0b1e19e48c1b90235796ba570aa0a3b1ea6c483d3079c71cd153b246993b86b506e477625b3b939fd9616451b90da9348b87c0201e087a5592a208ac9ab7ca6712758ecf4cf1af163ca3a369e82b46d941b15a42d31f8775e6332387036cc1bb31c5505d52b1a0753098d40b4999a74e4743a73e539d9e7a9514aa5671042a68ba6ef785234622f7440241a55a71f018a09ebab25f7913691bf787b781ef818c8238cfe5cbff3f8895a19c24085337fe10ec7b326da82283f03240a02aaf2658e04f7626da155a9fa8117eb3cf3f36d1e48baa2f68d158a0123691872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a56840b3a72c164432e6ca838693ef25b30013e5cf56c1e6142828107a10cabdd169c06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = 325d59b9061200e6d70e4323079618de528e667137a0ad81daf0888da37e09a44e25e2f6365b5aacb05f592ffe22abca9633af8e9e8ee20232a4d6fdecd730588047e1acdcd3f745ffef9ac0a4a7e13e3e5f7954c7f794d0d6f278cd162ba2dbdb0a246a046881c4c196db83d33511759c536a44273d5d4c303cc2877805914bc4c24932721784e01290f53699e15630ef12a77daff98d5c2cc94be874076ff6ebf7b264aaaf706ccc733a71106338232140c671c4a11fc0f07bba9ecadd304b65ff0443ab6fc0b36f4273d27fc43c22be51ccbc0273f7f3aee1381f42c48258aab1b77406a972d530504d6e644bc8e79b4c0418ef2440155edae167dd14e3844bcf0d6dfe3c41533ccf705074a00e1af366797ce6c6cb1d6fb61b89fe62583eb8b946ffc50615522c720b28f14fe52bc6e2960fdcd9734056b1a9156a8d8c8b1338379aa61e00b83fdf85013750ae75749c2ade870400e1b744029d4d542ec00ae4b13e36bb4bf5cd4d7f772fee9b58a90f254117a03c99d9e058b1f4b3b768e1e98c27877c40f239b793f4c0900c79d151e0facc116027ca656cb7da34cd29665c7e49fcd7cf53fd654cf07d7e0d40b53695814f0f907438620cda0f081c478f3bf23045931975f65214eeb16bbd0434f9909608b8263bfe87e85bb2af88bb6ce2f6672e68693251c60de5bec2e801f46d1bd1a4ad1263159911dde676c2233f65f39e099cfb65653cfb31f4921bd4ca729ef5cd5aee4642af2d3cddeaa4356fbeda7fc41a87cd86ac107eb72d9ced1bef7f92acf4c7b6dfab6205e185bf2146bce3ccce9a1ed814f6258ac33ecc63f9402298750b85e1e9d2b8070baa24c06b9143445db7a81e9bf9ccbd6f4f84b07afd389947da350495a6b924c49bab542a1456cd3fe8725ad51e4f2769ff78eb5a7a729fe8cf79209ee526d472fee75750a3db23278ad532c245014dd45477bd216a10558f7428c923fe0b7281300214578e8649b16fbf597e40f6293bd8ea7db33dd9ed18c8b3acfbd03850fdfeec3581d3a36f31bfd024c2199186e2b8f550df3fcf0b3f97d3de9d0765ca0e1bc25b60a774486b5e16d6f38dbd0bb5a54178c48fff479feecdf42fcb3967b6b2c55c1a3102817c7cb8db08d86533b41432811b84f861629862b9901641101f0af0af26420af7c4987143a24f349bacea254dd755cdef1effe559413a9938d9453b067c3f2c0dc6e9b0cc5bf9a9aa8c6021f39d49879e0576075c7eedd1f04dc618d869e8fb7b9deadbedd1ce48de13c1dc2bf893ee360104a09d7915ce6f150d0ec95d1e68e40a84ba5ddc6e9257a603dfb3fa048f47afdb48bef0a4789945666764e9650827fb9e2328665c2305dafdb20ef9800aaecd55ffcaeeba651284a1213514ed615c2dc252e5271a52f3033417e0dc9619c3948f110b234c08c8fe0481040d6359f17f5fb2eceb23dcb7c01c697e7c4067538f04c167b9a2edaced56eb2151479a48fe90843470d2e38fe2d0ce331d27717c5b5c6e98dcc840072b4fbb9d4feba36ea1285d30ff6101d78063abcfb0bfb623cd67e023208a6eddc2a9496f2127a9bfd41bf5f40cb7ff729598bb8bf40361d7d84097478b8ec2813328ad9f20593f1f41e2af4812aaa53e2cb2e61ba4d1563e87d817b27b2d827dfca0f2b6e86bdbdaf536641ccc1f3cca2b026f3a17aecef844e658159f626a04b301e8e40329ab3291993c673da1baa8eab89813e47362e39177f7b8f98f65f049734b66f6b2bc4672dcb2b1e36512ecaaf83a8a97377ed8a085b5aace382f3c269f6f96b382a7c06ab2669d5024d308cdf1ddbfc7f8819977b98854ae29012f9bbf684b7ec5041ddfbfc44a6981cad002d1a6e7887e35c23ac62768fe472d286fbc5bb023bfe4aef65dc227e797200e3bc6c016c088d3f0e59a563e668af5a06640b92138d7996fcd19d9d184c3346601e64dfca4174259ca1698fb80ec9f6f082bc2b03e400b3d81d4f14e1f4744c86fde5454186d51e2ceee89d40e8520314f576699bbec6939208614ad821425552a1d9ee5e63bfa7f98f16d2046cf64b261eb09617d40ab211e5f8078faaa32a064bb0e7e4d1567f8ba8c1fe97a7caaed134d6fd0bc6635256e312e423d78b6abf69d01ffc778612d0d61553d9ea634f272c56ded2c119cfdd198acaa00896ff01fb14488cae64da87805f5a9abdef3ca09f35e5d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2735bc067af4897f6c8953fe5655facb24a2a64d7522988c083fce083ef8c8e5e47d4f988f94a8516c77873858395afbef65b8784ec5b979eb6db84e3b2bfb2f95eb1305832f5fe0e6dd5710a5bb7195b8bfedcba9b5ba21ba57ba6fa280565aaceec9015635cf1a7121a85820ada78bbf6fc82838b6b4d5c6fa5d46469136cccc34a3d66434d915ba5c86e67ed9e73f4c1f3233d9fd73ccd5419dd5dcd6cfd62635c40f6c990753c55ca8dd385a2abec79fdb97c0b4cc8f26b28ba573b5194d6bdcd65f5b97e08df009c43a65eccf452447b0aef00ef68f18cac25e5c71e62a39fd8af6c6b64b48ef9d1f4d84801599aba838a48d8ed83454b506965507cc6d0b34bb139301eed14168a79d67d7c74bbc7ba8d461249fc31734dc384c9dac4ea6eb47025df0857e9593c6faae53c8d567e9945975d0df5b003fc88674dfec37cab3a4f676c840a453c6751caf16a4743495bcde75f8aa4fa47e8cfd6499b2a97fa76f9f8ef5bdaabccfe604f33231235a7cb47c96d9c977afaad533a06a34d24bdd925007984d99aba3aa8168a8ac92f662348686f756bdc2af3f8537545d13ae9f657cab9de788c9368864a0604daf22e33e117d5742fd6ef577cade6ccbf2ede065565a5b23f8479dbf621d93e45684d6c69fc0f548af95f248db6a6e86a2a907c95dfdd53fd942a93bd24ede8803474b03f73fc12f912257454d0d8d137c5e8404379ebf71968eaf181d8a03f58dea58892a1fc5fac7d1d28ca845068761f6bab69bbb75584f7d289dda2eab30379248d9e106a784739be7d00d44418bb9ce34bcd913bb27dd4ca0489610aaf55a39beba2afb5859d8634d9e473ca623933ac14c90f64cc74af396c318691716eb5c9cf8f3e8b694535fc2c73af9843032ce9167dfc8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf38d3e2c3ca5d585c4ea63009c7b851fd875acf78f20f7c59499526a8b2e4a4f03197a9315df2fa0c4e47a3a6fbd8bc59a7c1312a6d19e3d63f8d78b2aebff964af4825ee4cd3cd87f49bbcfdeafa3a5bf46a7f9bc97de739f85af35a6b9e68683658ee37ba6d9499cbaa8cb44c93bfbf87ef7cc7b1eb6491154c140cf127ab49316b70b8237a556d90c9687cc70cbfb93fd8a706f063aac1a429615694d7344ad50c1d48967c5334f354297df49ff9c2fac8639ef8c126ddb9fd537fca93c1006a77499658c0286267c9e0c11be2a6136152bcbc03e782c42befe95ad00cd974a3a9ade3a3b8b4bb8ed8c4d3683ab4ea3b84b84c482506f099e7feacd8943385f3c6b6af765bcc99393213938d67be8b2b168d6c73c2eacc42ae3ff55cd3ac6d85f0021ec0a6076f0209d7b1c96213f8d310b8752b1b619f7f366faadba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3e5e9e4263b050259a9a0a8823e3caddddb81c1ca5392d323a9539133c68b0a6cac1fc834c8d8d9375431fa6efe3233c49fc9e88faeed1ad68a37eb503cda0377ae309f86013b4947bb671c2bd48c19d5c8dee6d8035c7c05b9cb8755c7d7b6db39d7dacc5a91c6eb666837f219d75e8ac5b86444b49ac878fabfe18e4fe0f89eab7cb7c973ca8e0437f15888916dc5d030edeae54c86cab52f3bd7f023a639288b24a1e45d56b7ada6f84023f667c78473e339f99fb9add8fff966e65c5a8a8c5ca5622c5d4a624af6daf6443e776866f92851c7f25b983878c9c5685f3be99bb7568b9a7488b979f5a0fcbd7e7599448aa98dd2eff6dcf83e7f57759ceb43eb9a927bf379df6c40e59e59985cc416e618425b1d0bbe533bb3f5d03be664b8df86b95ae99e8837a4b360f3c9926cef826be5645784b33b333b7b0eff9c98a2793d09bfa126eff3faef0bd1bf99c6c5b181d3b3264964d58c4d9d5ecd8f995edc7f406dce6452a483786a81c6a45bab840e0aec9cc978d6d9c3e22c4afbac8f65816cbc42fabd4f5e09865f0d90bdbc6a7d2a784734f33d84727db532c3dabecd6b86fb22c738af9c9308a9b8b3fa6c376464f6c79e265b4390166ef44d9a1dce88e2d544bdb1ed810cdb58fac9fb854c9d2e96ae20a9e1acfffd69b6ff88a6bc324514987b03a8d4b72cec745d773639de847c780922b68a86ce7fa85de2dee9f3e7765a785b4603931f9ba815fec35aec29b1ce3387af3327d49734cacb798c955b329bc90122ce43c3cd1fbb939518c68d1b044e0ce31863d2eec9607410f0a6b74d40a6f93e7a88442aa0111008d38661241afaf6a2101dca37e83aa4e8747ce884cc1c29725a19510c7688ffa569cebb45dd87fa7772bdd6b6f26e48c5ec93a1d66a2519c571c1b0979e28a82eb9faf136feb21152ed15502521176c9ce3e2ac3f3dc78fc620e151badeb9b400da2029f1b1c2fa70bc8ca232cbb69b0f98a39543b03f67c1544402f518cf5477d6c4baf11f8bf44bb1208ec96082bc260e52d2ebc17c003a7816a5d940cb0bd7329912c4239b2910d27cfd2a48c77501e0586a2b88c99c1da29d0167a88abc35adb5a79c76c89f4c814ba410d9b2da6994c5a78c701ca91f42348454261f6f7a23ec89428630c5a88c9e309d08e8b7e9b353aede6c952e36973a23e9aeb8edd83b256d913b9b64e392936d538a9ab250175544a70796202154350696c9056695d9c0ff730c27ea71f1562a04eac9c7d8b38d551c447362dbb1277e6408a09855d1292956c72b39e802a19573c620a74f996492fa15322bab6342a8f90a747c3a40af020a2afda4d37620100351f3a5086818260592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b701a2c5909034a748b9891cb5e430836036cf686d8be47e2cd5559e500ee617ab436306614c4f026c6e57021da6f3356ea54e924799ed6827a1f311c0a340280ac21b110ea33809ce3744ac4539e4e912f4a99066c26d3f047ac87ccdc55529e710517ff042a893848d5acb44191c6057a4659427a7c2345e9005135bb3856733320ca4c031c3b86aa83cda29f40467d5306dc0142132f1a844466abc1b28d94b4d1b98ad5ff80886b38d2a15505e8cc24d9b3273039c2babaf8380568a1136610ba3ce49add830785a1780eb67b6dd628f718ca7f1bcca357a1531999d96556515cb680e153c98281de817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a4007f1069e6378e7f0b4ae2b890dc84294627a10039d7a46b3c705493c6471b3cc9ca2535fb8cb19798b7d4d562ea33869383b28ff7b9462124070a1c17cd4b2bf4a622e054a1cc29bb177048a62ba8fe66fba75cca14048da8a41c2e3a13da8ab593c14d0b295b1b587aff8778823ad2ce3644de2b236bc144aa4c5c2dc697ae3c681ac10b5f53ca1d84334a7908c48bb7f5c93388186860c781bc483b1975219d24677487161b15407e52faf51919beb32b6c3bb1fe993eb15a4af84a64aba7d794252fae6785b1054c24aa6b249840b08b3fd47a275d1a0930b2ca6e8b0d4b498628418af01aec4c049eff55a576123c1e58dafc5b00c2373adb7cd62120b9a69541084100fe44776d3078d66b143b7536888c4128a2a637c66d270c0be49c99f1241a951c413409d16cc653715b88e869216ea42ff505ed71c550848a98315c84550ce83bcc750e4cdb8084f882a29a5a0cb6048b5cea41b9b8c2fb3c949fb928770e411ded9902774b529320f768445349a310c727f2012678f44967f37b0a7cc3d4af05fb285a82ca568e88c87168b14a84b90bc6297bce393aec894d7b464852bbc55f3c85f447980c904bf067f9cf55c756a6967b95bc4a08427a8c9d3aa6ea8913bf47a823f0050de189c7aab2dbb040129f40b5a885caf20281e39c178a79729072ad360876ed670c192912095a01e19af47f11c30a44af6165ecf290f885998b9cb4ffcb1b7d71c7a4c21c0acfc8f9a942b7bb266c49a528a28732f65b4038bb7dc2670ef20cde470bd142a836bea52dc4460c0e01d1ef06e7e7775e9a888cdb8c2e6a6078ba3126572886bb091a14735158b4aeff26a852b6b400698434c61031540fea976b523627e1c11f5e14c5d5c878c607afad79e425b62d5a56530bb6bf889581045cc4839857ea16bd9775aad3609d5287aae66c60f916df54c88e8f291d8019c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9147016c9cb2018305de8321f4d0c158fa2452347c78a376f399780e59a5a4e1c8bb793fa14cac662732805146d2ea5cd67196257362922a81e2177ae5289f2bca3d6b2b0168a263c642cf8e2a3ce8577151aba48b828fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1f475da2ec982c47d91b24bb5ec6c51910530eec26f38541b173b38927d23c5684f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = b12a9afb3a11faa33332ad6a1a156f0c2995d887cc15685d22430657b4c21dc248d54202bdb64d8a769ae9e170d6b3bed186910e4d7cd93da5b1d5a9c1dea5b7c904e4de43434d68ded70c20f56e277578a02e778bd7e3a9b54435144727722bbe5f48c68132c8ca71daee35006992e3fcb18f69dc7dc8bfdd1395603e81fb6e005ad8bb59904e92936f5591bfe301d2f74a51200e85735d453eb0fb0cdda582a8a03fc2e4d767bfaa7cf2a35864ad498cb466154d59e52dddea1d109e7457f223c554e6a07b3e36a8964b06191cc10a2aa3c865198b782dae79cc56b906121c7b0e196b1aa68b8812d82ff20f94de0681ef8bbe1807a7769a6f187a93f2ae2f8789cbe6503c29c18f52a3caa7749831fe27ac2f7ebf202e51b6e69daae1d1ddb94700efbac3758e3f35713d354d2fb8c2542f07e0547b5859794a34eacb931cae689791f44b0da435bae4088067b78b645aedc9a8a9250eff90de440924864bcb9df4c9b0e8c24773fc35a565cac3566bb4edc7fcfd6c1e127d321a0093c298d09f7e45cd14278a9654eb9a09292a073a825ef776853d191f1be5c742539a3ce6fe1593924918a85c19e420a8ecbbc1a41e06e6bb90b7fa65da2a1a2115786017674262ad9ef7af059fd5564415b24196f4bdcc74b192a027700de533fafb1eba5b106d78a15251058e6cfba6902cb07eaf5fad4116bd00d3c423bdf80da84c4307f959381d20ee956cebc112659e2e8afd1e5011e33821f54b5aad23889b01dfcdda799dd1ecec8ddc86e76f517584bde598af55ef21bd1d3cc8bb0bb7e130c02c9bbedf6d7fa415619778c3d9d6d415e02fb426f1b72a2dfec6d7f236829db3931201f9e843a45baead9b6dac19012c607593ec4cbf1c7f8b45a22cdc39b0e7b509741383c6a6d33ba789b3abae9c9e9a1f7a40578615a1334b5524f36230a09b25e89354f8260f5fdf22352162e87022526912debc4b6ed3d11287e0ea36fd44bc1076ae889b89ab1a40c471cd2e3fccef126486275fb51cb88b5b405f1f209c8a5bf1b87ee928b32191663f13a3bc29ade704bfb35945cecae149f3d33c5aa73ccaad926af794bae7224d40546d0d81cff42ad2b04804969e4a3e7d7314f830a818ec6253df06bebb888cb919c057cfba392c2239821bf2cfc6e8404c709cfc39a910ed224c9509ce391a059d3d4734ad580cf11e85177acf9d7560f2703c3ab59ab4399812b558699e62774cb52093983358041cf43123dbf493cee7095957c6fe7fefbc44efdd82b20bfb73a7432b764e23f617680047a79521451460488a2388dac0cf4244beac2c36dcbbf4132fa8aee7f546387ce8ad7263541f4cec45ab382392c9a22c8e288186b2b65e4fb809454aed6ab014a76d040f41b95b55ea76e2573faaa7436f676f2576a8c97af4d577cfa64c29e5c5fdbf951c2dfb0a4b54d416abe48fdf7722a7734cf67b3bd55e3393aff2ab0ccbeb678f83e6f93a19396435d1c19cda0037a0f1d2feeadc1a5082d16faa03ac90101cbc19c8586c8ab1abcc6bc55a1756870b52d5e120944e1c06a81c0941107a2fe75dbb7dd29db5be0c97acacd75e77a4bbf488333ad6b6f31b29397348f31c2ec4e6163d0eb836bbc654f5769966c80b10e7f432c5b5716bf963536afa379509d733a2b2b1816f2b9747fd8df5f645909f455719d18c882276eed15f3965fc98520a9deb12ebb33427457780335314427135fd77c57f22122ff980ea747bd9031403872dcbc9131e7bc13c6de77fc97449a08f73cc34fd795b575537258b9817d08d8185f9b62b8ff16cc84941e7cc7bde8d34149a81cc15c02942aa029552469003e0051e792c70c1ca784a3cd9f7be1baf79b1d7858301d3d32b6a51f363934e576843f4c86a913053d382026267390375e4f5059b0634ca08a8792c8943dd4ea558743dd579e5e4176c53a9ea43e864713ee282c2c5cfb009a426aaa9eb1e984144465895b8ee159e819fd1eff43c2d4c7417631a8d52c3c8735a2c9f2ac4bd03f406a2a2bfc6bf5d11e63d066a220a075bd3dffdb6fd1a712f2429be1ead3edf9199bcc55d63a69f9ab0738b3aae75e72c7a165a474d8a5f7e77f5d6c028b27d5843fb4dc4b4f740e446f597889db3411bbf83de759c473a11c6bbf2f3a2c506981defbd52fca4ece20039653e7dea7e8c7d690a179cc3dd72b1bbbf7efc32e41a108c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a78d63522ec694ac4672d8d9bb3b913e8ca2f659c756ebed7cbf36a04eab4ac9b3f524e216f3c998cdddcde37352d46463f371ffce4b26aab239498d44975f7885d4815552e727329dd78428f5568caefc76b572ad9b3d335a9f5cddf83c76aef8e8e36aadceb55f3bdc4bb0608cf9d9998962f76b217774d74a3453b6eff104e089b5e3663eff3aad7e9148f4bf36b6dbf6c8945de4dd97e6e998a983cef4aed8b082c3a29997d8bc1c4733773b74edbe326fd3e9ef64a13f79738dca0bcdf3a9e8efbf0565f59e837dfd31e229d84b74dee98ed58aed5e180e870bdb7bf1bdbb53aadb3bcdd28457e10288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35309af3e9d9f81d6ec556fce48c9a663ad9518cea36aaec71b69951100cd2cb66b75f1f847838dfce3ea3417ae2e29ce5bb6e757483d437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0c9dd33ae5fcfe2ae55faea568f5b2ef77ab74878e0cf4fa1f7c3c8467e3d28ed5ab2c91b83836e11b9858a66998cffe8a67682588ca78e6b6d746f98ee34b100bce62edad921a9f020a703245edaed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc99abfb071f84c921c585b9b3233c5bee08f637ccef53a5bf9b36b42b54751dd6f9a215656aa1890c0c56e0cc6fa3d1ff52b87ed72375a60374bf8d8455218de0d456579a3db3f3afa3b89e3c14ee12fabacaef75bb2da5202d7671369f82cb4707c5f740d9ca06ac7d34b48a2934d4d26b6cfd08c8b0db6e550044069f4cf27488c039dd1f3cf929294db60c3f1de5cbdef1ca216838091d3e72fdf6d141c957dd93bb6a59d9e883640d87a2a85605a9730dd53338448d5374b58747c7262d5a65ef442d6843deb83ec953f69b4a9bf00f39b4a3847841cebf4b9907fd7b9a66c5da724cec477e02f18dd4d0bc51addb2505ad5f82d7edce7398e0d9348f64268fdeb0fdfd7780791942565afbd61bf03719e7d6f87953c4757a75b1f6ead15c6c9447c02938c3b75a58bbf5ce65a5cab2e898fb8d50319880223899f5546e1df53df7950691b86f8f3e15438c3b80cc2e7b6e78a96a0f39adcc47394be36c9b18fe580d646a89b93283edd417f8f4bc4adbd9be30eecccf528a5a09595f33cdf64f6d2f6898b8a4c82d79a8ed31c4172a7812c295c9394e929b782b334490eeaa38c17cb4e77664306bc7c0e726ec656e253e1c52bd524d7ff0745665d53d73604c59ec88df6fc9ee3ffa0486d79bcfb735e66ff58efb0e1987a032dc98f0b4cdebc70f93ca709c5c2fad7d98a7b86676faccefd9c85974d7c88ce9a0bd2f58f76ef4fdd70c7c0e15950fc0775e23e73b60555a57d302d1ad04736de5cf85ea2f3c326968d3d3d8c15eb400b13bcaaa65ebfa4eef5aad69cadbd3e0d841c7ef45753d3ba9cfbc909e0107865883ce8eba462f7bd9eafed5796e43a8647c59c64b7a8db9c0a5ef9938daf728b872d3d3755b682a3fce0c5876f040543bcbdf8e97dc02a53e2aee9cf2cde302d08dcd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a5394889d23406fce1fdaf0cb460f88fa85d7488c0b9706eeec66704ecd67b9d43fc33647bcfd1e5bb6e2aa92e65376474da6d59a8271bb27826dc9a153c98247b386d69cdf349ef76c20a88678a2f58c229f3621a4828a39fc6c7f443a467a469dbcc0f95af866f0489eb006dd659143c54b4f95cc883db27ca9d5e90388b84f8f4eaa869f4e84df5a7b7932d834074a39aec9fba5079cb6ba77a94fa2f7e3d5e652ecdd093582868b1e7c9d349ed4875b837467ae74923acf40972abe89a77fbcc339eda0f5dda5d1cee57f6fad69ef04db84b63e5f2cfb6423429647ce3f544339101db3ce037c15ff6c270dde2d2ecd5b76a35c5fca7ad284ad04b46978d7c96edc9acedf28487493244a86e7e3a4b5be3978c538ee77414b354b30548fea563963fdfa6046724abe3c59a50c20888ae5998b0df87a9dee79dfa5610f598807df1043b7cf6d749e3bcffd6d58b3e9c78f5ea88d0c691bd2544aa69e407484cd638864bfa49ae75bbe2143217ceaa76278cc3ba3f95c4e3ede648d883b825039d2abae539173dbc859f23d76da58b31d2677f9de1841e50c263257b04d84419c3892d590b286088e35b9ed4a57257ab09286934a0e63326876eacb60fce3b9642019560a5646f522fbdf34dbfc8599829105222193903c97101a8dd4806788a8ecc223eac5206a8706f38aaa4dfc87181ab07e37bc3106590fe18996e5b88fda7af242aa56e42cac7113392317604cc89e1f067896755ead0cbfa201775329d2c8804f485cf61cabfe35a33cfbba7d2426ad2f59a98625315633b0424ab2f2326fa8488fa92895ee08edbf32f6e318dd22a5719d3c4782bc1787873e93773b310ca9b036680ba69acd75036952a330abbedfc5477545ae7b09b6f3467a900083d4677c6b5c0dcdb9886f26b1c9b6e180b8f5020ae1a68b9ecc3a154a084a365a9035841700966cca311c09b13fdeb4da6517c9c3a9c3cd9c336607a53f1972856b161b2878c5689e8ea7124cb768fb48efd92489a1bb3660422bcf72ccbbcbf0d7383ef47586863870620c025d6b65cd5c861234194448a021417cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466b528b2fa2eafc943b861c78666a94e1091efe4ae69010f0a139cd9984be6f23a237cbc1345a53fb0489fec34ceba3874f631f4a34598a7bee966225e2b251ada212b9365bfa2613bc4b2e0962493c0c461361fe555ad61bc6dd54b844114781fd37291b7c3e7090cea1a20c86b3637011493332925f503b4ac6fb625ca41601995869443da8d82b81412012dcfe22eba66072a9cbf65f34294b4c85ffabcac3358fd6193c8dc1706c05e123b10445baa34c6616863807551bd33546ed39112f49c371ad31c82ea6db593a173884d005a0a5184417d5a16ec87225bac3728530ea21913b6b05283a4c078950ca84b73e417cd1878b1ac9388241c3e006d5c0b1148db78b319293707d92210622cce348e5c0572ecd7718bec7f6c644680bb2a6bba55d412776303b8b5cc2603356a7f685095da747a3480dae39537780188e264efb88bdb8c82cfaab5586b3629410bdf2274e8e2b76673c700c45fdef297778cb8dbc4bcec24c349170b39f96a5e3c6ee7d1c8da58357398a5f0202743339aa7eb74e0a5b8542909c29a8337e6083e3663df918c6a85246769b01403bb24c25c27dc8a4841166a86698eec30f049a80f786f6fa29cc8f7414517429f4aa76421cc8cab09874bae0f9999f0a846fa742d8d087bcd929d42e89f994ba2d421058b429e24c753436b908833c2b4365047da4825eba955e9c5de3a02c11c3c8e214416f2a8efe6b3ad033bc9acb992d77d8d340c69cb97cd59c7a5b127c6b46a51267b2471031166815c105914590c2aebaee9a9286d7c7d10b42c80077ddab4ba9baac51fd2512b481d1b1713ad4136b1a4a375959710a156fdeccce7a2c7dbf2ce57a9520b7c9509075bee4c5f4e3a2b45a748bfe210c88ba484556299511c10f762c162bd0114433dd1913f628540571c04f79490c30ade20434341b59e2bc66f489058d0aa2f14575942299783caf2e7b40d2a7bc10a150a6b0b1fa2a8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c95b25066a85d1896123db2297a75fdaa015a60942ec7266f8d00511a1603fcb2e6d533e3fc7c126d2753b9704ed2c5608a226cff698a8fa53f9746eeab1c51796be3c013c44f0ad8ec2037e75369877c4d63a1fba7ac534f4b6852068ab973e1d9b96be70cc21659971c90aa7793e51a517f3108a2ff24fd3541cbb89b75786a546b346ddc92ab5eb93227057f0fb76e1554c0cf19bf0d08e33fb1abcfb71c1a0779a91a42af586cb27a9304a75e9604211640be36739fde51f2d9107fec20fbce665a45a1aeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf50c153e941158f2202de5857b834e3e553f7945398bcc70ee00cce8ec15296b2364393085f2821d36ce6f04b0b336bba762c387c69280bb4fff179eef54b925d99176167f4f916e2bfcb945a1bab4e5398a03c17c79992848bdefac5fae4667d37c75bae231d424381c39722fba787765b3005699b7b08d2785805d476679e29372b619e3568eb263c2aad8c891ca561271cb5868b5971445e1cc2e2f1a11e44c0a798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b22b22f73a770cbdb80da84f97f27a14c5df5b3372d52503d3a20c3cb2bea8b404e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = f56e4e9f97a517a6d815580f3e72df4cbacee30faf8faeaf23852cf0798f27cb47d37785f82e0d8c4a6daeaaa6c0d04e3d9a9b9e2b40051ad3993d91fbad0626b36cd313479bbe79c7437a198851d12d349dc858078f89d1f15d6ccb3650c5d25b4e40eb72e0494f74adbcb6825f03b5d6cea726aea0107b340481a6daf20fb8b3e09e2000021a15d6b94549903fc5f4eb67252816d1aa31cf725eec0834073331e6c3202a64fe85763b3725c5b05c3340285072f4c67201d95959751afebd2e205d17a47a17e885682e9e592e37c92d0cad63fa0f12cf11639dd2c0bb6ae9d5f9900f23735647a31f99686fc203d653043ec715404564dcab8715eefa2ad8f28accaef47f5ca4198ebec2bd683bc9d8034e30a5e1047a77ce74096af3fbf984f50e8b945626357731a785e60b2445ad9ab260a20c44a6e81e9312532d4717f5e313042e365ed24f17bb9376de8a6338510af1ec6e06e6ecebd885e05a11c6c0fc11c25d7ed738eada6b6c8d2dcdc21058343f99da448931c8f2d637e2b7e39a8d571fb12ec0251c45996f86dfde41470f20ac3b6d580c78bc1a4dd65570bec1ab75422a17fe9cc16cd341065cf1a523979c6d05b97c605a4c000ea60ca9a642744b9415b4be3e77572a1eb0a002e47f843b0695133936e24825223a4ea6dd849cee7c8ea1aa1238bc4468b97336f18836c147d8cd62a4411987e7b9534dbd7184e5f638fdbc5469849b0ab8a09db0e2a4bdd0a3a019c47d5fa611dbcce91b76be7d91edead166861927ea965eeadbb7a3243b5b2e2ac53721d2e2d0010c8121291030f9cc7e53eb4ca673417af2f3c51ece935f8f78181695fd30261e33cda52d04d35135725e079e15198a9135e2f5666a47daf596e245e12e8cefbaa20fa93395159773fe71e59ed19f0a628ba116acef70a5bb2134a2e67ed415523a910ea571ddb9f2b8daa42282ac3f8e12ecfa62b62ba53cd56a38ba7474764f01af809ae1fd1b7715f1f76233b4edd9b84c90b3e97026ee72b065f8138c9ddd6718dcede648913886fe030954138ff322db57d06c16f1059b58c79ee2a7d6e98ab42a6bd3a98d8946405c6b694ba25b73139cf69fad46ad5a3fc28eb19e14515a5745b5a9a6512873d14c9b6626436ec28547ec3df16506ea7b0c9815b689f4ebc82ba6db7a0274d884f518917e2e03afd2bde2ca7fd0c2b0ddf5ed6de2249a239363e5337c4cbd31bebdd145add37dadb67fc0b22c96aedf2b6782082d4bcd5c48572541917c9ac3288b11e83c68b73420a88eb249cb3e82fdf3ec3669bfd1dd8d9a6a2467a58ffc050940305d0a91ea386f75a29336bc1490b6d90b76cc8986cbac84d474a2a6a512e2221597b60886390a37c7ae96bfc94e4168628eb29c7690432c24714b7b81d54f68b18daf9f5ad9f371b29d8792c7b2e11f23e87a053fb48c1b5945925cac1289cccce8f65eff481be54bd17ed2b470cd0e711be202dfcadcafd269fcbb94159170c2aa9377f6cc80081d7f23725eac0697f3e235d9c5d24485fd1170f3609469f0247c946f2e080a3f44d5a90e9220c531a73eab0d454366e303c6d46e44adc7fd700cb54e057280d1c799e8bf6e80b957d3d32ab48c1efa62247e161e540c1d977c70b591b77e4a2f1ddf6651b6f8158faf6967a7521dfdf3d2ff6e2970c389a1ed25d146320c3ddf12408c5bb012ece7012e6c86f518cbe13a857c10060d458fa5f05323bedbe06a295f7a115110f50566397af07d3950f820764633e5cfc0eed57f8deff0ff3ff91e06f1d049eb25dc3c0c73f6f811e3470e33bc3632d1365af3882ee090f7a259780290e07c6fd52de4c197b77b37a2b9c7b845d28420dc295f774e54e0ca647fca8080f17cd94a4590459f5e3bacf84d6bd5848707c45f120a0d7a612adfdfa33f1a969068580549cf83df5f64ce9c989cab89237f62deda5a1ee7fb4f8045a375a51ff9cfcb843759e444c35667bc649661fd613175b560bb5731584ed1421107b8795a2fe5e4ad86b4c3c50b06b540fb6602e6b443c210435172b9eca236992f4971ab3c5dcc965d89a03af1f5ea8c56dd7a361183db4ea502a6d11b960cc283d4b4e50ab1fd9cbe04b12cdec1543eac9a70d127152046d680bc82eda8df796e173c06802887cc3107cdc397c5de20869fcc0dd25bc9c5353734f0847e8994fb58e5f7b7d356922a7c647d72433f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d08f93b02a9a6f579f51066bd6f5eabd37d104634cfd58f8242dff2b63b18a8bb4f45a5af4e8f02523cc1779b450df83860bd0053d7c399ca5d8eacade156af824a988f5ac6bc5deafb6e77a95b9752c922bd6a7c4265a6a88b11d14d3e58ef7b1f8d78784f669e763929483393cad6e09f018143e9d2b7cd4fdf8c6f56b91768113259bcac9f6a18fa2a6185a1cfe8656448a638f58e21a3c6cdaf3449b4f9483ae9e0ebdd4bc674e0656640dad2b2e5809e547e36f6f8d9437bab7f7f4fd5c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303da8f23e1a4ef6536170f53a0d7ed04beb75fa34b8aee5e56e4a538269775818f83dbdba538f607e5d661d2a626fbcf737c98cf43d50353bb83e2ce137fec26fe48d81973eb974ab1ba4b97c95c0dfed65523430cc06620debba3dc9f888497658bc5c64b98be65ab2a0738f086dd22b95a66c583354a63865c5f37ff7d98d279c53f731f3fcae8689754194a7b898e99b897620dd9ff75677b2d5d0d7359905e763571638358ef65aff6d0d8c9b4729f404975cfb89969a77615d1a3fb404baaa545120feb3b09ce577fbf74f5b3b0c8f5434e87f61de8fa83e41fa1f701a99a7c123d500078922aae44a0899685596aa646f13573eba0b54de4fd5de2c60c3dae614066474b89f2377994cde4ee0a77e1d5cdaf77748c1f6f3cb8947a98636694c4efbfdce2bf779c66a317989a336bdd7150583157ec8d845a5fa4b3e43de95084f44f70578124c4c7894ab84584daec8c13a6598525cd23ca99f4c0499a68aca3e78f7799be0ef9a463a6d5e2fe8656606438274ac8ed8c87beda16ba3b8e5857a7f25831d8b85bd8ed5828575320c6baba75489455154c3ee50074a313ba9ae1db747f39405544f44949dde165070d8f71f1ba80e57bb5cde320c9aef8fb47354079532bba5138fae31a7d26e18c46ae6b2ab9940eaba9f1ef4f1592770c9a9604263a4917c825c084c353438202fc05769fdd97940aebea439e5e28cf795cedf5640fa922a3fda1ce4a6624cc9967ed5475f46334c77ffcb9907159461dbe416637d8df34ab4c4d1414cf7b6d5a1d23331f98f73222653adf9685b6e4bec9840356bea24adc4cf6db0b678afffefd0bcb383bfcf580c99e27b2870746ce5570ba1cec89f5dccc47bf5e7bc1fdc57959e434ce1e01d810d5b37aa8ab3392b33587932470eefce2386477f4beb859c861463c42b5030d9a1fdba3e1d49ef9ca5a99df58a7948c670afb50864b73b4db52dc7cff13eb3a4cfe009268cd5dbd0a89b44c156333c9dfad04bff0707e07d2ed57ce78705ab6ee43681b0fd87413d80751fa7743399cae832f6f3b65df56ab1c3dd6967379f1db4ef53b9efb5632a23b942f832a70af3cde494b0c7393e5eac807a38b01e9d526a5a3caed68f1d7812269ec864e0aa739c289cf0446b68880343f3fef157094dd424a34ade523e76c0acb9c29d2fb6346386b62fb0466bc8a85b97431aedf80850510c4825ec4f2aab987c5ad7f11693e7bbb4662a4890a3c54eccdcbbd75ca468428e48f76f8ec43e8ea8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137d4efee75640774c4b536bb1d7bbce797847cf84043d49019f9ffe9e9808f25990f79b52a4445ca94f058cdf418964fa53478ed974e7829d1825a3b34ed333c64c765857c982fdbddab43a6154337cda1bca4ae0aaacb3eabb4ca06928f45eb21c99d40f533f3059a87a8ac7ffc5f37ccfb383fe18a9aa945c9359568d9f1095eedcbf530bef64d37666596c771a663eab836ff7d3150236b76acd7e23a9bdf43886a265102dfdc8725d57d38ea7b0699df7c7a1c4d55e29945963df7a06454e9295b89dada8c873f7eb86a39e83177edcfcb6eb333f3fea668e20f4e7d65fa9f23e3b634e8a3441ff0ed775156fdd84ba7e3bf39f0aaecfde549d5a13dac5cfc4405a6d772f5354cdfdec86d301eb77c1efacd29878306699954ac96bcdbbcbb1642811cb18e7b96d16540a8394574a85d0ad6c4f64df5b89d685dcca38cb95f95fcbbf534dae18a3913365a4f96a8a77839e2af69f7b94b3dc58f6ad94bc5fe5409f775696de6341cd3532fe8df1c68fd554d0a0fb05f935ea20c6ba845e12f4d8d2a756581d8bbb8ecc46386ec722794de90503d536a810bc927784aac5b15feda774ed1b0550b7a7e656817866881a2a4ef682462e75391298f75f2061c70141aa682d50787162a6dcd853971665c9609bbd90ab833367a44a0286d860c04057c8ed7797712affa2557e2db46b546390f3163f05316aa8a12a7d49c4fe03337cb9a7218739ddb184c1304530667b9b54441015b9f8501f902bc2f3000a4855e68d7350e83728765057959662504331d5026c8d52088593d0acc1f39e74a7fa59b959967073bb14de163d73308c276ac0e6bc26e1c165b873e46972b72fc214544317c31556a76c09588c45e4762a1b43c7ea2a9dd238ac6e39e9cebaa1945544fd8702d7066d329c89656499e6c8264ca1be481ac792c5a52188e8a954c06a96e13604e2ec0242c78bdc7763359a47c2c5c4f7762819504740c043b2a5bc8db00cc4aa9a8c6354df515ba7d7039f0268637430067b81284f866bdda366a8c25c3808af025561f24bbf8671305ba3aed330898f18b854c501549aa9a1c68dcf1071af689f3c4a46b19709cf02bbcb07f65b44e9f9385c94c4385d88f8b502ca9e19a246498646bcfa1308f8a6c45638a0df58668f55a3d30440453c36875b0aa1b5967e617a296d284c4e2828b64b83fb176156ba7fe864007414c3eb247c4063acdd61b4e5c42b9147044b6916fa9be1d25ba71a035d766bf4c1c336b836b512a23549bbc53e1a8fada8246b41cf93604bc9b792868734fa755b06a7821e688ce17c9a00c7f9fd724dd494b070b9d4fb0a2963ccf41777f86ba3b318a1ea543913d5a653f073b34c64980e02cbe17cdba5a286443677a152b0da21ee54991f34b758b87a3cb690858f29a003031e8a99964f3a904023404ca51d730957f34a0beb402169a6bf7163963d87d9c6159b8e342cd8738c945b832b698655071286338b67b372a067305e5299043c884b4ac6f624d06f1167003cd5659b68f36bccde8b37c817db27870dd196135b21849843835ec1efed74af31a3bfc6cc33a988322622e2841799635084aaba1eca13b61ba765466b05c742279067c5a1a1355737c84199932660b15e1c124f5718e86a8953a0ea5182299a8a4c4a82f91aa901f40a64c2c1457864f0beb17f5b6733fdb8fa9a04d9ed1480dbb2ebe1b8a37917ed30257ceb062d4b3caac11cc1283542b6a711a737c64981afa7cc0dff00c7019ae2169bad10a6f60f094020b7b422b006135b65110076da0ac1e9b8f354a46200b3d58113953197e7a942671e3ca61c17f4256737dc71b12291eae2626ec136b6898047427525290a62380b2b246ad86ab59b12499c77936f816cdf15c5873147e37a71a2993aa11042cc83ca7b7656ff35429795a9ba01075d670a464b33e368b70ce7b484e864efa8b890892b8648461a61b75bd7455979325755292576878d0f94728fc2433c1c04ad8b52e55c93f36c564630c7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b59807f51fce23361e2abdb21a0803f4af1dfc8b55a594e746b241ab0bba37b285666de8431bd3e28c7d6b64e7e1377364c75c1a1b6b8147d91074cd862ded548788d825bde070ede391b0a794fef56231f36b7c451d25db6419e761e700b080db345c613226d38895d55889b10754b9706c33144805325c3295359ca2ab758dd321154ce457b9734ebe32c02546a7556b599733c036060631d5b4ff6c57a1b6c5065b80a691cbf3c604dcf49d914853c87b6758a58d56e406c04230548954242aa799e0532acbbdb9d9a50dc2bab0c91b0268bd2f0427717bc5b9456895c1660cab6c312549a8f15df9c7957b1a9f3c00a7487a812d429bb8f232b559a5daf57c27a96a99327a39f5b1ec95b4161316f1a27ab2470a162231a93761ccc64689d430d4872acf18a4ef71c0b6ebb3d552b2bf4abb43d70576c9a67c3647d5919be77a0af046bc6580bf05b109a66256a21ba44c45c516212aeadb7594fc6ca17bc436102ef3d99722fb3bbb0bb39c9a1c14085ccff8b57140488270c165a8abe44333999a383c83bf1bdc6cf63258908abe715bb383c385fc26635283af0853b3e533cc6cc95591c08fcff360fc6b506b861444b3b328045270b001a481662bc847fd15924f5744e359c18514a909ca163fecc8a1521c1b2955ab7917e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e28709618588523d8fe8354d81146fd65af657da08926bd3a6ecbc2f81cb58d1aaacfe5b6e686f5aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 21e84fec2d39d07af40f870aea929d72eb835afc17ad37b589a40011f9f22507a8dbcae3db12c7c78f04b3224499df5a5e2fbf4457329d4f58d8031dadc47cd256e1818c77a2ff57b79bc7da942e255c29db6b6261a8f1e83469aa1ea312be5131e6e48b8af523061b4d160921c4270054f62daf17ed5d927e71c11093410bc29f0c8ae9c85b2883ba6a6c02e3cc029de0adfd661572aa5bba2b4387d071695a26ee60e74c17d935f9fdb94d90474168fb8c301dccb02d63bd00fe2e4fcced4be6d0cda9f73086a3ff95cf208b47cb28ea7d8d76a0797363d3f8a15805d414612d9a2e8e3ee010445b9dc062ffb6515482151d9b0bda80270174db7012f4dc55c3753933f3be1ab8f8e4456df8976d217b32d5158a96c641627a9f6dd1f5ee063aa12d1c50f76fa1038138bbc06211e9111b23ba6bbdc8307e7106d5a0fd9306cd7474c72a0fef226d20a5f0386ff7b7f2b92f6f5489e17a49b5c322cc4593ab4f105f9fda8adaa4c14eda1a4290a58852abd3e9c2bab221c43687d7d7636fd0c6131c52aae1491c71c63ca6879a234e59ec2955bf2ff4dd94785c5ef566e61b93bb23a13126adf488215f1ba44a7c7b4505ddfac3137fff5f0101db710ab15b7b5b89c76b83ddb22e33e4f3e412c4bd4e495ed2f456a43ca478b7f89c966d4b5c49040eab34ac3dbbbae5ffdc1a695985d31a7339dea863370f26d29c127c210615adfc18a759c515952070383bf6168bf0f5b3c013ce9dbaae270723ace4fdd89118c4f648551c01c07616336c4d6db0334b6f069e12d0a1c2c79134aad08c0fcc9f2eed1479627172e9cdeb0caeecf35a219fee07c9ce9dab2c1d70ca16944fc72a04ceda778db35ef540a57bfdff481c434f59086767762bd956f8c46cbf30c0cef79638ee82fa9da2cfb1f1f6f1dd148b498b59282a6dce929e4fb3b9b1b5fa9e441558133647a58dc95d37c5d497dfe55ed9a14df84601d74b8b15708b329b54d42ddd2e1354bb237b67d63483ce89fc9471dbdb031cda50532e0ba0de9ad761c9fa6996952f63b0b7d38f45e1f73e714ca2b19bf130defeaa3f83d0bafc815121c66b2c52e35d2e71c54533ec758ee7cde243c8b38d7d401bd8ee5b904192b9ee7856cdcccf8eff4aa2621ef12176cdbabb49c279f16a602c670350e3927d466e75939c15f597073e406d2fa871651f13048f575d44f679ad68f058d058eaa5725481c6d4f0c60946d9d79586ab9ac2a042adbc58cb71a9d6768367751ad564c65fa822a8d3a4c4799df3c7fbd5712670377a0396487fe854c4e0cf3e68df8dbcfe6771d0dcc7af77ad8a44904e192593930de973df753f94e6b92733484101a51dc0e1f6517c97a52b8e6605b494dab7b2822f413e5e64323e5e2da4a7be54083d972e5d884211d29ed9325a2676b48b5546e7843e26252d45b35e159ba58f8c6fe75b7087bcee9b5342ec1d060bae57fe60563d1d40b10ce5cd53c3dcde3b95e8181e0d204e8bba231b7bae36740c4ceed081dc5e2d98014b172f89bacae436700aae42d9898e0a7958cfa2adad1aa8a3f60389441ed635e246f101c91465183178c6478c27705b200a92d4532a0e333dca8c1a2dcc7f1177a74515bd3d901278753ae3cd852a486c79c8849ea3e59dada0d006284b320ebda341120aee768104d540993b073d5cf679b24b6c656c2b8df632690736bc8076b6012463ddf5e54746de4ff9c2c3d903e53d80626c396d722b7117b0c993fb03d4c3e9b0acc038d2803c9af5a75015a349e1bd878a5699f2062efe387b9c28acd3565b5012d147d46808d5f6a147ad09a39d4ac8cc75ddbe2f0579117101e39979707d4d3a7eaa832d8820a13c438931057e6c48e433dd0b89097561a66742c3b8145e450a6f377c5aa62455b79f444a1394a453612eb04161b450a80f58a7e8c3dbc66294b75a28b8e951b955cff641d107f83b385be1394dad6c4c7678094fcb83ece7d55f9c69decce45243d3acf86831fd694c3cda038ed84f0b14e724754dd43885e4dc1beaad8a45afd5963006cdf47d2948d4bed48244f65856c2504ce77a38e7b3b13a9b169b800c729cd957a5bc290116bedad6d844498a3a1314c2f63544200ed7de137a6126fd6f75b828d113e4fad9d7c102034e531ce9b881336a66c05d3b0c7cdbf3afad7632799a00391c693017e49d749e038d2b99858fb2f894f9 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a428a13444f9ce9c3dadbb62145ede2654f6d1cb5c69c68e7f377bcbc454aaf867781f58fab6f2b6367fc5cc46ea6d682a3984a23f30b3d7c25a69ce4ab9af0234a109878e0cd4fa9b858dc559ad3ff8fc416d539c08828d5eb337b7c0ea768ba646a2f059d0a235a4042b88e8934d3c6f821a13b67baeff162aa80953cb71c396d91b91521b666516f552eda6ce453c233460799e38cb16ac6e598f670c70d73f5804cc494466710d984e3ea551f5ec60c513ee955fe91906fd311e81831b7fb4fc61da443fe12784cf84b5edff40daecc87e8eeaae1d808ba6f33d345ba81bd469797dc03583214355e8e9a356e367a593a6898355ae1f9a8546a0d04bf27a1fe88adee8db3583da79ea9ad544086540bc2e78b31f5f00c94ae763d38486b6cefecf7e6af20239db4e5ac807fbd4bea95678c5fff76c4757c68d2ec9f83b8766f1a39e06c999016bef1d5c3164338aeb53fd54b338c46eb9a7258981555fc2563e585a6ff60886c32343e0045746f5dfe79ada9bcbb6281abe3474ba51fef67c3f76a23f7a901f8e2b5ab0786e8c5aadfc35488553f745d3adc942c8ec0aab7afd0c869b9b9c67ce847257cb23cde8b82bf5c468a9bc35a181bd90f4bb90c4fcd35d0d78b7a9d46833cd90f7bc2678cab9b75b95a6b457dca8fcb84938dde47aadb7b6da9643da507a2b8b1bef53748f518a7f9bda8b35fcea315b3b359705cd5b486582379093e64f4323d9f0389ff899beb4c3ca9689b413bfe0eb654f183362ab8398b1e3696df7432be662cbf6f66657ef2c056504a5c1ca2de7a73f6acc83d6534d58fd0937ddeab973cdd73406de066aeba8655dbb3d93d26eb99e698fc778b2fe88ffa8ec7c62e4f2e18bf4fe1d7b87a8338ae7af6994c70d959cbfc3720c3e74b9658f5d43713cd47325eb92643dd73f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c30ffa1f4a8715957fe7d7a4db9243a1c6a636ae5d735b870f1297b6d6b5304ef552a54aa5a9e340ab4d301dafd6bd9a765c7ffbeeec3c44a7649ea350f0dcde5a6f8e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd5442963e7b55ea9ab21e7989ab7b7304304e66e2119396727943678c31cf3be779c946b834f0a557a8d74f6263d33c807e591c7857e90a7fa15e58e315ae1aeed46249b3012bf2291cae316ded1423674824b852c34c97258aba7faf6d5e95ffb2db6dfd5ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a52aae872daf5cb4a99c39bf25e379ace27485d8b91fef9ceb98cd4322b59f533745d23720ae457fb1eb3a0b831de777d07f88ed187efa1d89db9acbc7bac471be4f3acac482b0bfade13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65ccfe6e04875754a77025985b0f6adce3f1574ab45cda47134b560219338fc93b0a398d7f95e69b4b32c2ec3a075f9f8e3a57fd353328bd3f87d5cb60c67074146fb56d476d9f619dacf3ba7a371fd9425cfc6486a9f95a1d9cfa2cea75ab9ebb4f35af63c6f8648ae7855a4eab5c9d49f3386996181980b17bd2a63d60e5a64a8cf3ced087bb64f93693ccc0e77aa355d741f1f562692477af0d82a4e73e22fd5fc386a8b33bd9a4b79c427efeab1cf9fff6e0dea9713da3680bf5d4f528b5eaab6d5caaa20d8ff1aa39345bddb6aecaf7a563ab6e1b65fe7da81d4cb97f6ba16e35773aeb8c1917aafc9b8f5254380395a41b474b27463f42e7c7b008a52d4395132ce3cdebb7effa846dfa429af7393f8a688203bb6b8e4468debcdfa3ead138e1f23cda0aa3c194abfeb266c59aaa542605319b23376954407027e8024e7816f730391a4d5d19e27af868d8ebbd58b767b1aa7015dabef5c3fb773b9329898cec8c94d80630b8447cb2ce7c3d5dd1352e7c0acaaaf73b4b0323fd77a5f3e0c9cc53df8693da3dbd65d7151c348c1e898ad548eb3d5ca0484c68fec70435c840a6e1781ff9800d94114bec6ae66b2519df9c2fa15cea69c96afb890ea6df96e1dbbc4cb92ccc224f4f2a2537ae6df06cb4bb90935381f6fc571874f283cdac0d52553fdd549ee5a85f98e54d924e9a3823d69a5eaba0ac73633189d40f95a14026455fa4d3a0eb8fea64c6c0da5d9a16254d897856a1486c8b2f773c18bab3cd4f80c83dac6dc9796100886d14b4085bb2265bd9c2f021034ef1083d58afd447ca55526d2691781d409649e88f43ca4e9b4aaf9bd9588ae52d126692b181817abb5291f660adf3a0044a0c527b233327c0f9db047c9415c806414bb0758dfab9a7d3c28484578b6084b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db333168c32033375a0321a287e133a9aca8eab024a85761ad4776b03a95130d0178f93684a2c0a519501ee5b85c4c3278e8b4e7b2b461cd4602a7918767b315cbcb885410ceb025f1342c2388637eb69ab0fc21568b1178ef3669a1b9e4fc30eadf5be70143ecdf543f1cc88e05a109920a5f3b4aabc0b8197783e8a16b1e06bc5e7089cc447186830a1d5bcc8bb31a6e91b691a65721791b0334495cd014c134617a3318a7906069e0574d83c8a44326db67ccf94a0a735942de923b5a6d55b087b4390e975e6b3aae4606abd3500fd54837ff875c54bcb7b5739ddc0adab741e57946ac0948ccef5ca791a46c669c552b97ec35633a141b92de18b0dba46ddc64431920938a927c255ab78fcbfc9653e1c0b8a0f42489674c0f79c30cf8a5073a06fbfaa888e914d53a3b6a86418f5ec6dd5a6b56973bdd9744d0ef326ab49291ba1b1a9f1a68da542fd944b3b88c6c364752fa6233d27a792e6a040f1824120ae9afa707d7206966a4ea361681627cb346572619c9a7d539db7469e60177e98674398ea296fc3005800c5da17a80ea06ad23a265ab7293401cdfe3460921596a7c228c883b0e1e48365fb02eb50950de3af481439dfb98447f3406c81161e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99c820e1f258825988d4827b5b1506a0129648101bd18823b2f2c2a142387f1a067a295175f5922eeb1de320711f0b729971bc7647889ee86cb5f44363a992369120dc837dd474baffd381253680f00675fb380bf96a89e282ae67c32b94ab48e35029145748eaa76037a98788c45dde75085d9c5523a7309804745f626f89362f7ba94738c5b9ba0b11bf560e855356e8cac1195cbb2921bfdad80db6b3bd9916a7c6cca281914f4fa5ad26d00e6f6acae0db49ae970755d16b2069b1a7ec0d7b879af301a9bf5519683bb3a59b066b62c8d150a316508b8c2c62a7f20fae59b3ccb0cc5e21055c7a638e11242c39855545b0a880484fb555f0fa4bb059ab05457bed820eee0767470628f81a321f113a8158a1ad1367f11802f71b90a8b4a1cc3c16552c11064ac01402b8b4b695d19ba74991673a963537b2ab14333633e04b0859472ecac568c87700a5076c8c265a3b0662c4250ae5cb53771cddcc2473f7bcc52ca97ba018beb6be5ba5420f7b2882f3acffbca13193c71eb60d167c1d9b256f4706a19204a017204ad28b6a0f607d61a97cb578cfc9633ba9d6ab84367cad900e5ce147ac935af727724af3ac8f0c86ec70034ea7c7f5330889b402f6b7be7bb6c7751411120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb311b338dc8a8e5b10c08b3ae26c945d680f4ad35dc07639c581301ca981be25075363b8d3a6b2165c99c0b61c298a502123c40e1cc223b21efabc1c34576e206456cc082cd4048fbb576e720bb967f5b58763342c98ae883cb24ca32e06398c56eb6a7b697df092926a8c76dc160f0c577ab476303647bad3b6951949acc2a69e793807a77c7ef163a25c842723d85665b121dc8622772caca988c5e8281d2e7055657100d31688b09104d0470d8953b82ea4c6afe50bb96b68f5524ac3a5a92cd26f26b142e37920ad36111226c763e3ce29c9c1235c8ea40995eb867ea8e844ed819c10f62172c52558667f4121bcac1815ee2806d863c22f10a20e74425f6c22b1900b520a5041b0a7f5842ad0fc0e19c893d7e42b1ecac89d9a989d8c45dedc5621565e2e788147c42ec4dc6a8ca22d4a1904787ac8b75232bb13aca7e30825e865bde0ce8ef1c7e2172d759873db265638fbacf7763b80fb4161417559a32c2d6cce4834be3316181ea4c5cd29687a498953998783057df991300f224324b207b723607961622f20377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8236fc15e2340175a2a64ca1cf31a4b38ed5f797aaa8acb0c3d2ed9c19c7099f27e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 8a7fc61cbd793349e4eca40c4b0363c8cd6bbda7d91b3bc947253052a8aedce5fd3fcd3267834afcf8bc65bf4fd5ae665e83718fb3853b692854fe073d4495a10c94443fa5b96d5ed4c576c3a7c35019e090b8f4dd290125c120b6725272d3e5715537abb68b1c9383b9848561af1e407fe05be8559386d5fea2609b87cbead19c2088b4a01988bfce6457e63acc7446de77e6b95d4de8c23482a54227f418eb0c7ce1549aab9872eaa1ed31d23275e3ced1086ee360f586c6e0f0ef6747338a11b3a547891198ac06731eeed8991690f69f826065f2bb33d0b90f8c95c54d3208c2ed01339e07616539729b427deabe41e942cd9482ac82989e04eb5892b434c12ec598be216e71bfd74a77250ea0760330a77f292c137e3a6188c26856aecbd86b9dd9900a194041f6665f3b2c5a567e67f403ec8d25718c94b442092521e872238916d56a22145081d3f7f279b31edb7817492fb542ab081b8e3803275882441aa79d0bc50438b1598661836a30ee401285ac14637711657102da457accb446d5e477a82c277fe6a89fe1392ef3ad1438cbf8495466217c9551adbaaeed2d5303660f6d3cb7366e11261b8f5cbaa5908622d3744c76e4f4d758317c38b93560446758b3370c3336457e8d0ed04fbd335884d48815cf6f5a61a1b4228864ca33b9772d5a11186464de82959adc9fedaba313161198782bd30cc85f3b452a1aabe85051aa9a476e57cd277ba5fb1ea30fa93fad105d25d25f0a852fae45591eeecc8eb4d60f49080735a0088540ee2b0a240b071e2543692d0577e79cb0eb20d78e9564969dbf5d0dbd57f733d945ca1e315f83eacc17bb2f9618730357cb009b61b040a9ae14c50cbd0a34f508640bb77947160cc18efe07e19fced266bd0b1512c2054d21bc9ec59a53cf80d9e83cc5a096c28d6473ecfedf997466d9e875a9968c06183ad74715de5f1106b66411df25333e4b74f9609a1d4d220c6feaeb2ef6349892b1abdb8564af4c7b3dc8b4b3901609721919b6612944d8e4ea7da00e46274dee2b926b05646f873c0c79d1a6fad3dc7e7c2a3bdbe3ae25a305d30fe8052c539076a5e8d4bf801a9fa9185886ed87059402a45cd540540e7f65f2b395e36a9778970807d8765a0eefd75def212d5c0f48e392c52bf4ba5b5add4765c900ca9e397f74f6581ef76a105f2237afbc356d3b4888efbd42038f3ec212ab7db92d8932f968e3ad44954b7ae0ca07b1c52f7a2658cba0f1cfd0ddc653a47d6f78866b03f2fc7dd45552aa9ecec792edd5ff572d7ac1618800262515b55d88bc777b6bfa7da44d1e72f659078ccbd434c8a8b1b79806b922f45fed511f8365c9c17aed6e54c8a2d820203b7f3ff248b406826c36009cb020fdd7d6487d5e305df9d3cf5fbfa51071476a080a30cfbf1bd245255fb852eb96f63093ecf42e2092a8c5f18f5d23a8ad5462a81330050654cd253948f5bf400d25dea8512f7ab19c7f4c9a1a15e8152c410014c0390618cb7573f62fa998f1e1262b0e52a31e16c397a3b1a2f33ebd56a82c0539bd0dec4850124b32976fd013b3f313052eaf8e7dcb33a88d59a4b3c9af50386812117a403902ddb66d2370261ed5200903c093bf31cc1fea44f0b9c9312e7ceb47bf2ea05dd2b0c30df2b6d1d0490a92d387584ab4e4a5957372579ac66bc8a75e55d28980fed47ff66ee53893c6065bb04dceb6955fed293502d174f7f702a18d1c34a1aeebf3259eefc6c87e7325199d14e249c3b5c5be857200209565f4b37db58f16a658388a8403df95bf9bbeb91ea5fa1eeb62e18fae11d30c002f90ca42c8b189d60b559aef8f2dfb0749a9c80ac32ba227acd8c9fda46f09c7ae9b56fbbd463ecce9df6daa3907e539ed001dc62ca0c472edceb824ed76b4a4c66b1dac16fb6cdc7fd6c9661f2f3b816a4ea63bfe8507e2e2a83eaec35cb739092a1717189d029b8d96d7631dd4899a1acad50f03bcd167ee77c513a8d99cfe696370001ece57d7fc9be5ac26131ed30aaae8a661f8b574b63cc443549d0d49525093fa7eb4c1cf6a818868a6773139e02ccc0175b8f50b4560eee4a57828cc3e41bba85d02ca8a6fd344b7cc0307961ce2f669f49bb7cc5faf609297d36066e88f265527b391f40a477ee6ef8abb8859050275c013018eef80cb875f4790478657fab67547619c21b131080082c3d31793ce4474c1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = fa198bb15b42795d9dc34fd02c75a8bcfe853c474c8248b50638f1e4d77fd598d97aaff017de7377f76a89ab9478bed24c9780fc7f8f6d03fa5666828143c52ff8e7b9688c70eba293df716ab497094dabc56d3f597b5fcdfbd1458e360234f626ad67ea48b426738dad0ab986369aa63f6dd199c7231fc59bcfdc8f63429683721a2c682c5aa853b86542698732ab86fe39c340ebfd462f86fdd599336b9923599b67ce44c0c7848d2da6989e33fb7b5efa47f6a4f44389cb93d6a9c1b7f3d0cb95f699cf36ad0db2855861c88bad063af5423362c7774c1626834ee5988086f508fb51909f6a3f475d01aa8e5c8c4140537091d494af66b0ea4f635913fa2264af67e63542cf408b1853f87c68c28c8c144e7f94d77f6ac3315f23405c233e14f7762c25f609ac34842553de175a70eec08b44baaade5cf09a604abd5b6907eef43fe7180eae92dd50778a6754e374888e69182afe1336677889318cb54218bcd5559eb918ccf5540f316725ec98c3de144d403e0c59b335ff4d0c85ebbce877798c41aa43c5c7b738b7ce1174f8c049370ba6665be646b41f5aeb947b1f4bfec5357c7566c13ebbe48c453d6c2f74a9295a06d8f2e0aff2cc3df6f1a6d3b67dfd08d46d4d7e384e776af2a4418958f6e4559f5975c586e47bc0236b4897622ae439626d334cc97acb2de8068e4ae44786d1e445147a4728275c32554b9cde48aea6d5e10c5a6b556705fec17297a32ec3e1f1f9fee6fe60e96ffe06554b93b5c796e44086e75d236ca88ecc533c3b34819e891e35639bd6cbdb3a40882db6e3b3f8c4268454169267a5c53497d3c51fc58846c193eda1630e4600dbb3524f4fa9dd599775bd2d95edb5bd7438f655aad6402628563db3a435f75d440636cd74d41eee62d178c92359d83afe90f106be012dab63e7b3ec7e8a4fb59e01057c416c330dcf6e485a6d9d7fb707eadb298cda25247d26e4df044844c2db883a5bbfc3bd6f1bfbccc7eedb65c9bdbfc8d6d8ad4cd71774de6dbc424cedfa897a061f365cd54a90ba6ac519f98bf645536358384392538eaa406cf9201e695cda995a9ac5f84f35166db38f97f0d673f7b4dcc4762674434e679247cbe42695b8e8ec37d7e8cad53d1c3e8fa0add757267c43b982f26639912df8f8f636c45d91f1ca90a1f3f9d5dbd69b9e8f46ad78f33ab4e0df483916f7926aaddff47ecffe718b3bd48304cd40f7ffb097fb6207856b6ebd774d34e82bb426747406eeae5b93c63dcefc7cfd9e48ef7118df6accded2b043616f6db7153e6dfc17306a77800ee87e03e4b74759794ee6943ecf74afcea08197a841e68f269fd2b21f4803064f6f3f95de5ead18949a5a383a81363bb11ee8a8569a39de38bf8835362c723e999402d3cf729bde11f647ce2b93916e5b9f5d487e23cee6f9cefc5aece5e83d28d642e4ce6934b43931158ccef3832a457a5e833f3189e88598d7ab084f687a394c257abcd8435ce7e7d1e6b79e78a37bc7ea2377f9839b89aa9d5b5d935afecfc1e6d7ec597898c6a69765cad5e9784b7849c685ab5b6de3358d6f99d8a4b075045d6fee5b63a6d1aa95603a67378157b54889c3021453e383f08ddd6c0deb7747f4e1c225db7da3e1897d818d65d24a1ef1a43898dca59417088eb0d9ce88497b122946886e9053d9beabaae3c663b24058b6218f6fc8bd3442bc998f568ca7f570dc638c0f88e114fa6643efcb4eaac2f638c8535ec1f9a4f2b14aed58bc541de6706abff8098bb61bdd60a39cc5fa5b9495b79c92993f97284c9a657be1f5f8ae333061759c38a5a662aac58e2e4b7f837311d9fe5d14f14229d446aa3d646495554cc7f37656ed8974a06df8b1fad08163b5bb23f44dd4ea395ae8e589a85a2bc4e71b596e15b6fcd64c59fcd31678ac9e0a439b6a31234cdf1b6b51654fdf7496d817cb3a82f7982829e300c8b9543a5b1e2c59b9c6867eaab23c64f78736f233578c1f03db3a2ad6991343973ee9f07e8cb45d80c6c785f927d9f8c7e3ec8bef47bb9d2f1c9d394cc6fe24ce4594d323aeff2288335ac78403cfcac56e4b93a971057e9a68963696b8f477dc43a959a9afcdd4ae4de6ab18a33bcb3f61f731f91ab66e6e867a94b272acd1c3e5d7388fd24a4d6333acb1dae84c9eeb89935770f4970a8e4b7b83c12a1e44c3eb360b42e77bd4435fb6f65cc14b894c387d0445af3f28cc2434138a07a667e5ac6bbba72dc3b7eaf788d8621dde4034a430c2de165b313733e2daacead1a014fb09d5b834411b8325728eb325b12310992012a7c4e05dba5017a59ba9777a9b3d5a681f79252e1c15ff8593bef7cd3c059153435bee16cd2b8433ef80bb21cbad40c6b945d7b6ddac39d0d0b558c7a42d9bcc701aadea5707f77498d5527e4f0b0bee834946302191d06f46116a77b884479a75a585a0c2105343584aeef31bd8a7aabbf669a2b2518f3805be390159b974ce43c83ef68b72024a42a942d8a03ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cb50fffc35c6a8b95172a0416130af7560ef1020ccf09c400101705ec1305ac95ca03143d22c93d72bd07e83afca94ec379142bea095c754533d802183a9b3cf2796ee2988184076d6c2235f39d250b080750762a0a31ffd26130700f6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc371c1de16bf2ba57359d060328a8cc01b948ed14197286ad0e8acef142dac64b4fe260cf066886c8ca9292ba2b3315a2d719c53b7acbb5125bbeb8d3df4caafb08ac54b8aa2816d3b44630623101f3b69e15c32c8e6912d61cdb2602734b206863c9b488431d72000e59c36e031471bd693e238314bc282dd8b4702d334e5985a8e89045f40652300a9dfeacf0c922e5b631f00c434085c5dac53bb4637c624c80dcd59a2205c8c5717554c114999e79b7ef020b7961f007541d009350bcc427aaccec0b0c9e3656214255689b24ae3cc874ff7c0574b09f0d8223e4c19cfb381a8c72f7324ad9e600669204b2590bd9ff6a589d26e0f2bbe575c39cb304ed5c8b692a17b65a7a27623144e7248eeebc4ac80239de04e8b3928e750a0bd44c30315647b5a6bf3e5955971c9f62b44ee01221ef93fa76843be32408563c111447541d98263212cab014e7897afbca8618a27b56bb9725aa1b711315e30aa445537bf02a201e5362e6b6b82f52506cf8c1e82f7912612b6e9126b7e725b30451d2001b76cb575ebc847db9b2a048277202b1434f9c936da846a6773dfe4193d019c7a7601fca114737559df7aac095849692831156a13a9060510e05bb9f48a01506a08f63ca5cb4b032962b6d484e8cb742b0709023b9926562bc83c72c047833e27760d6a8a8c559a096600254909db3668b0e2c8bbab67413827a2c808bf6c2662553b4d9166a152931f30031fb15822c12462b714276c743b2691e69321946cad96f9bd71982f47970fce751b013630f5aa90334c657d286f94d325333b64c6bc9955e859f8c51c1961400388bb9de91fbf4bafe8853b1ce98e9f1076af1406458b00ccf021da408575e126d850a3a1d51f31069194d65c4df88b94d8b43a4b6ee651654d6bc72b8c283c49093eb3b1dadc9bd329b11862542da3b770657318f13fe4b07b1d22482c0410652a3b52c2216f3028fa47c3e5934c3540b644a282729196ca366e1064bf5e57ae739229e3f092c3cc91e8e833c4e314b6cb91e6873f35cc4ad2b60281c862b9d0ca89aa0966713ca0e973a766cf303aa1082266923cba1ce7a91964440d43878fd359583c6de0f5c6c86424a1096d5bdbb843990f0b8285681bba7ae82008a56f992267133b7bd1a55f0fb37f84d6b2609cbc49c968925069aab3498ff7c986f522b0f2a1512a8cb5a6bebbe62f28901f2c5073896381255912fc482e9ef57132ea5f5f61b36a5a17366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8aad129ccd6c796b2883ff989650c04af16b339ec34912226f586286a553db3362c5e1056a369b22c1467cdd4a633b03585f82116510127aaa1459b2dfe049e6f191dd7cb4d0a8ac5df064e64b9021440357c4562302bb0ed0a6aa94ba1dd55a50829a574007608bc61508a0f17d41dc3bbcb8e91c4dee25d2ea4700d905348026046450ad0c2768ad72eb0b770d45a7416c041160170b8511da2958f44c9b06060183bb37967282062e0a93eb5bb4b2b15a4152c6f19b730b724f94aab64b60b7ef5080b251ae0290746c249b1a76c96825653a89914b1ce70982d3cd437837854c6d28f871999073b1c2024088f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc7526a1b77ae8a807e9de16a9ede5da5aec3ca5f23f5ea00e455d4a091467e6ac6dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = 3608928ece690b321f3a7a09d0f3f9795cc9f17bbf2b0f389000daa3d4448250e868c9b5f439e2ed83c5123052390c46db9e7df41ce8b36a94fe4bac780d0a7f1f706fb291dd73ef22db1a261645a5fd6908af766afc8dcb8f4d231ce30a4f75095b0755bcc19937f59faa625a4e9082039263fa6995bc698480e0d574fb91d9ad226b2238ae6c90db35b4bc7c3b0a86246fb9bedebb99fd61eb308ddb984dc816aecb312ad8109b48873b240e804e12f874784de2bacea6a0ce6c7badf8447fc92687968a7feeac5a52c9e4c5994eec2b9f5aa1a02e77c5bded0a722f6f03ad50fb9af7dbd3c947d51c88265eeec8eb8cda85cb4e435b42f6bc6449198c0a167c8854e53be601903455b2e70caf40efdcc0f01fa094f1f131c5a4a8a43adda77e6a2ab30d757d27c6945520e61d0d586a4f942469fe16a4040d9cb35738745c6bb7f0fea1177148efe651c305d357cf9fbb60b28e7aeb0f86d401df1c6f274fed52e5201c6ef1fa44a49d8a83247d9e427032cd36dea141a5a9034c9ff43fe78ed18ded60c3c5182ddd7b750a2136d1bfc9f023ac2e035f68bb294b9230ad79ffb08dd7e560c3895bc29d3dfebc5dde309611a1971866932ae205384fd0b928694f1ed3142016cfd22fee072803ccb2f9a0b4f72c52fc27f9670b0aa2a2998cfaf447f1fa17043195e2f00e85d4a9438e5a43ae167d423f4005236726bb696eec9f5ca106af893f41d9e417b487051c78271574e5671e6b4354c6ea984dad8ed2dd1ac638848a12f016a5e643877bf7db0669fa23002484ea4893b12e647fc17679fbc09e3eccf840b17734024ba032ec16bfefecb4e2cd8b015fdb324b96ad167cbbf4f2fbcfcbe920acbb7ff5a9824620c7449192bd44e768eb51fd59304b7be0e031e03294931e71a845c23086de8984dc9ea6c62068e0887037b51545bf0f361c0eceb66d8ce759255a35e44a74f7eb568f4c952c86cd5fc210376af979dc7dda5463d97fa4eab46a6d5df4dbeac5a00ac488cf62d0a354d953438e87425592c850006cb5d9ba10629c5e14dc8de4d0f32c0668899c061dd485c4c02ed9a150443133f0aaac359e6fb7df8357a21d4e6da958a1ed73ac4f424fabb29d49ded136d4a9d7f42ee86e34b167841199333523d0fbb53726ee4239fa0f6213e6ba9ae3edffa2e914a802a245cba75b01e0d450e041a5cb1504c426f0d36bcc0d590af2e9dc5f68ea7e2f13ecf0a266b97f6cc986bda423068cf3da5b44c16483ed6a37843eaad3e23f0c8aa8671c75e8fd17ff4836e16fdb70ba9722403844a51a81d10c7b399a9e9ef9022017c93cdbbe742f1380707469eb5c513acccdf27eb2bb84b0ba66593df3540e4b3321a70338b6829bbacc2d1cca888870080c0bdd9d9a0276f6cd25e60d833ac3ab5e656432410f765f7404e4fc98b16b68e2fdd39359b3fc4c0340b57e5e34fe820459b1caf7d0a19cb132aa14ff4fd77a75ec858c7f6aa9b3fe51e6f5b32c136e84fd4c2c2a1a0174f5e478a347abc1c53fcc50373d71bda547bcda2fefd2b3d1341a0cedafac274783d749d7c4a1f1fd5d0a0e8755ccd4790e766d5c807122788a9c041af93e2c6d503ad043c36dcbd4dad5ae503115e8afc84fdcce5961518e7c117ef1da56934d1b95320672c9ac0c9db215db08ba4337a173871d3fb2934cd9ae40152086ac86188d461f4a37a07abe99ad20956c82f7f67a9f036ca4212ffd3d1aa013d3f99fa2de6eb1372c983c44cfdf0e1138962410d821d2a32e57a37f6db98f357f0b1477dc8a1256eb6a1af5bf0c91835baa033a9612d74f59cfe33c340d35cac871e0c60c0ddd0cd8d2a6b7681fa86ac0efd32ad17ecbbe4bce8550984fb0b7a74ed6da5e3ba27f3f08c97baa276d4b3d9382e9086bc3031cf95ee7c6da42f2fcf025f067aaabe938956857404c57cf4cc39fe57107a79dd1fdb9c3cdccfd74f5c0e90459e4e68f33a986453202936042be7b7b69ec3cdec4ef4f258d91200d222680a8443467d7ffd58c25cf4990d93b157debd343e23c3e6ca3fe612c52cf6705f409dcf5ec499d6d6bb9fa406a8b9500767ae4b4779b99eeaa75de3ab4a99cd02df8fefd7090bd825a70e292e337f2933ddd2c6498e00ec5e928fc7eb788e68479651203160f29af2b9d27d32ad50a63ac30b1ef4a6fa5120f077874ff23d009f6fdc39403e630de4fe8a6e9 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 55873ec8c5bac259501f0f5faee3f7b9b659b19ede7d43b8bf8af5a9cea5116fcfbc9bbeab28f7471967989e3398ebec1cb4ec1cc3a8845dda29797ab4cbb553076c214e67abeff08365f7a05d4dd9a476985362898b4e4248f1cc2642c335c3c953c86655eceded3098d5a2ae366ddbeea06e05547e2cdc0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a9220be4042aac83a1b4897bc6a15c87fca4e44828966c49b6cb8f842a3157b60d6b3271c36625f9d8a93c7daf7b4de1396309cdcbbfc9f9856e7cbb5b1825c88bdbc4c74c58ef3d54d08a6e3a6a431e3a59ad05fd1fbb6828ecdd61f1bc514dcbfe83df3d09ed2e9834d5d6bba8a354fe04c6008b37f9b07857ceae238f5a563ff88f42e7ffd2aebf9bfa0fcf3af041dc84bd6cd806cf46c5af27c9bcf973d93a9755cba968e7c06cc4f987b526e71461b69e023d76cb652c3adb10f2bdfc9d6b583b9f9fa49d5ba4b6b42fe9d862c82b6fe70277530a278773fa740eca749c00a61735aa1a287e9cfb75eb07689577e8239f4323aef5a316339db665eb9784ab69ee37e1fdb9927829575f2b824b3ea4cb540a4b12ad7c512046712bd463f779e1279bcd2c7f3868dc72d06e3095d376db48978dc717dde424d0b5e743eb76d0ac0b024c6283c8418e5b1a8af97aa483e5d2a65f228eedf3fc69cc4b9a8c4c0b90bb17fcd6337efe00766aeda3e876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb7376485d4ea2af9d14edbc2d16dbf758d34515ee9379cfb009d2b9b4f66428d2e66ffff9be9944adf6b123cf9b68f700af475689e2c46c88cffdb41da5f6d227a7236fc0e3c3e57dc4898e07caebd8d3824fb5172a799b8a6db0f770383dc98e1957fffe3d5d8bfa52945eff5c4337b6cc5004bacbc4e9ba73568aa357f61c70383447c70e5a5896b9c1cda2f2c7a76da4d278d736d6b685f4fb3cc49fcaac1830b439468b6bc73585b4205751e66ed30999863097d2a47758871ea99068dd88657024fa6d3715501424d5a834d10a8f4788675d2546afad54628ea3f81abccae4eac11e3ddaa5d4da9e54dd9f2a40dec3ec2688a3266c9e16c6d461087da37ea1973374c99693c92eef9d458f92ac3208268079be77c828d38305ab421b6d82a7d6316ebb37fe318ccfe08163a723a4bfc4cfa25f958f29bfb807ae5e441db8863ed3843c8ac26c7773084f209fe51d6fd83e69772a0491240f7917fd39fd08713ba8d39f3b84cc83a8f89bfc19f48a958a443339a5a2158dfd8ad8d11983602ae892a8c1152c602eebe592c3ae556bfee54c5dc71fdc0b956270cd6d85d78120bce35fd369de6b6aaa0fbb015a7bc3cae3a749e960c533d3fea6278494e78b6a3c5b91a3beaa2a0752e6cda30e33cc86dcba2f3f32c98b9aaf1bbdf9f8f5b15a6dc3a741d43a53ec1dad18e93542fff4ec5a952d673984a9daf0e8e578debc84bd9856794d127d7faac63a1e49a79a2f4b51464916ccd7f0a69f07ff6696f5806f9fca4aead50cda48a9d9d635a9c68acc753b8ee115c35488758a68256a32f4964c53ed51cda8c5053d1b5ee26aa5f270b3d9f69931c42e94fe3debc48d9db548a0005585081c6b11db7a1aee4f9a4777c6defb35289100d979e5b5b306c6692136a839ca4dda3aee9d3bb3c418a732ec4998eef4b7d6cb4cbd90c0f35ac3efd6f3beb19deae929ac935b2cb24f4fdea87acbcccac6d4454b8a183e89e8738dc645f60f39232ba5ea03baa369dcd2acd5ff4c33d91d7aaeffe04bc879ebaa431294b202efb589647c29c66f7f3677ed3dbb1bbba093c6dabb147cdc07748b098ec1f83855464b1aebb41b03e04ceb59c42cf4701a39dc74b44fd8505a8dc1796f75cf26f72a29c2864d6c70eac1de5969d459ce203eec8a47be727a57a87f566984452e3bfea96abaeb4ad990b9a7fbf5e47f6a438e27a3624355b97c71414d6d5297dc421754886acaccbbd9b245ead297e6c476b61d7c9082f8cd81e3e554f334af85d30d4d75d2965a9df37af81a4588bcd241183247d5d47bc8edfb6bbd735f993d69cf576dabcf2aa5c9787f11ddf793e9bb1ccbc3762bf5759a38cf3cf8ed1ca6581de12e64deb5bd587e036b961ff23fb95e2815a5e6f9c384369c25bea962c4b05064909f424a15515fbf534b4f660b09e9146c40ac273822eb116ac60782dc519805c41f39a306d7e21d0fc2264b8bb6637b113144b0d459ba833965d3a39c51355416f672b25811f5f2ce8cec777ba322ce506823d6005d1147600808ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7efc25874d5190b893039493204f67e11560e49412b484781c571324f76218976a1633bc4ca3c0a6d8211c6c0171e0993baf46406f8b85fa0c7f0551b74ab81d642c634ea74b269837e2588228a8645764a2b9a7bc2a802682b22c24c2a55439d14d12e620363271a4468fcacfa8ba686f1bdbfc70ca9c0961f9a488b7962b8c718b9e7a33d8b5306e6a05616c2a1484aa044200038624f65b8a92ba4739c714ac71fb8f12af92c5cc06c2bb59367c5c471bbe6099d1b19c9bb1aa168c071dbc6e01c5c72fa33171c52b78c1deb32134dd8af5d147bdea32dd6c52450c112bc5a0d9e03b06d807173304972a9866ae4bf6b053d98680858671ce1f252293972c42c4bf6ec2ba9f11be4325c34f89e7d500dd749ae3c845f7d56815f11a2fb07b9e3f88cacb51e2ed258cf5bb981b089cba18f902c14e04503302ca929319645154cfa878cfc777f2093a00916a617b6086d973208883ace08270eb16be4ec404eb2951bb1ac825840bee09eba19a90b5316ab79c3ac062c07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f28a15e49863a2139dec116d99374236c8a7169053fa716756299ed16125d699c39357133fa49fe0db960a8cbc0adb979239b64a7b3a702878fc1610868790abf3968873ae5dc19020b28f1405cca1b0800ef236e020aed6157892161b54bb3d14a4c64fa1ab949648020ca86064b17fe8b3f7d915c72a68e2b46f16267b7598bc112537b7681ea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccc51f9a5357fd4b92ce4906183c0031727c7a966bf0c485a9312f7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c33fc2033c04294a91323f1602a6da351f0a6e478264e0e4a6adda77dd6a2535a748daa074af31af028509f2c27f15f00e60e72f7a7032dfb99d50c88814167a838758c2685243839d8ac19e76133b40dac70e49b33ff83299862c3496999dfa90470b7bb17bcd14019b093b5787abada26700a83377ae57173fe528d6dc35efe846d95933d68144ea3aca554ca0e873baa6bb926d70a09306621b3705942b4e0d60cbf200c10c3c4d5f7c8c75899aeaea40cec8928ae25baa2c7f139392221cc7042c05baf58371010492bc2125d27a9bb01a28a3855c98b894d4165689af39c0a26a6b920874728d475daa731940457b24199d11841d5bc369962c1cf3920b6af974b3150189919959c3b4e556c56fb22e5597b64506575f6799dd86cb0669651a1c017c8a74e5f63cc60b9047b21dee777df6010bd6a614f9a63c72074b7909137cb7155fea72bedb7428e0b197246af69121e97923f861af31f10249e11795a180c0c6c056d58d848a62370278308c4cc2b466a8d7231456c06e4b9f1faa65a8f0113f99238c52ae3c3a24600c4e943947c8c653c946bbf6b4cee89646aa23afc7b22f0d45464337a90a7c22cbdb4449b24d5bf3c070778773b92055206ca895105e264c9757918f6bb76bfc93de826c61c77b6a51b135915235271faad3cf608c0033b2581fc522965257eef576ebf7379a173b1b269e27648189696b30346d5202b560784777f88aca2c9f900344eef8aa0cb4a86ed6335be29b91248780674bbadb5b11f967a663c2f9129b73ec584c50aaae9771d258272198261f362d93830880e4b60e4b142b3822816501c89b5011681a5ec2ba2b03cf9eb1886c33c1c72cb6061b10638931e5f1461f413e5766a7becc59a052a0e221c6419752258955dce743131890bab88b8dcc5738eb6f409c1c0d888de1d0c5a7bb03e80171c2b41dfd411f74b5165804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca4e296f0d975f2f5731d822627c1964ec1bb1ac7452bf0c5c0735d6f75304efa4410e4cd20557b574cad1674395436203db728a58b8e0b95183c10653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b82460170e6cf1da1e7b92037f51b4e7674d9abf74f5c225c5c6ce16a971691284ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = 682f51001e8e82ff56040975149cf749e276aa9d891bb063ad5000f7d00b94c2e63ce6c5acb8d4406149a32d8b8c793ca5d89942dc66d641c6d92c543b593ccd4fb4c420eed148f58962715f57c2e530a70f03e3e2fb3e1939cbfa94f525a9871ccf482d6d0a9ce9817a1f8f9d3b6ab339b64e0121d6b788b2a2691ccb640be2b327229c68dd9f1f2d185a55416e7de882dcb5198b22391af6f3233a3d252303020d01e92d9148a1ca9128c5c2585fa5e62e8ddb1be592313fbe5c0bc33a9e15374aea856c7023935f6fa0772ff8df39a3d0c9bfe4362ef49d2a6bc176935116cab82ee4645f26421874420aa9452c987d50430be35131e368e759be4244ce6135b6f21df91a541fffcd5851ef54bea5381f76d16cd8fe0721b6eea13c03e45d123f5ce83c3734894c50456d85ab7aa305b1f86eeba6822511b59c34e990030e45d7b02f47dcb2cc51361a931a9c5a40a49dd506b5bba74bc4748ccca631b748b96e999e16152254ec3c0f5074f15c29a172916b2aa50da95176544c80dee47c4d3ab06fd814f22e79c91ffcab2535ef4a21bf353ac06a71e5ba365d2eed87b1c3b53d9dc5c760485e665630c2e8d16f86921babfde251f06b7a6ccbe8f2a4e9438e122a04e277564dfb258400bc842f83eaeed123c5e39f15e9b66d7ea24edf862ef846fa4df20751fc167771c7a16b71a57787352de96f0c45b3b39e7b91dfa4349c7dc5b4c65992598c2edbbaba461a6e07be6c6cf90ffef1dee70857babf44979c2c9bc62dbf5a2c5d212da4f6b421414e8be50a2c240b3eb7f3bfe84f355bcb21818e067396956f62c5907edbf859517a49ef693e21e426f73785bf502aaf2e43e35664438b65d0a71bb1c95f0173cb9d086c61b71eca4ea5e5bfbac4a9145157b6f445990d45758bb886dadd7136f4049b1131346c2e883c766d3951cde3ae60cfb736ef668f314e58e21c8341039f8e34fc815782657cbfac346bc6e1f2e7119d7cfbf0fc31987cc38eebad9d91e466590686bbf8068be39d64375077c1ef599dbc64c8de64e308d0599660804ae4ccb22dd216c1abcf3a2218af6e5d8f07fbf52f2a1e9ddcc467029cba6578996e1e794a83f143757c0412c993d8e8fe3f51c9df30e5bd579c7fa0a2ce6c58d47334851fb07c07be272366c9ad90d19b9126f49a70670a4358faf8d75e727d2cc4ee203923f234954c65c94206ee6d803a5a5f4f87f75e2b509d75a6dd8066b7a7d9d6f075fb7003103c86a4c5a93ff2e9585ad1a39d6ac9710c515485e9666877f0d4d2e11bd322c8e124fdca5a800944102a877f83fd42d23d10c0068f3a9c29fd8ac3cd6fa59a148b08bc211397f4d597d39ba2488c93faddaf25930bc5787339702e668312dc1a333fdf09d29f9bfe60ed68a7e86d62531eb08b61149c54287c547476e8b169c20f53e79e7ed680a78adb122f31004d228cc6dfdbb24ef3513abb24c81b2632a1950ff700f422a06fc0b975a2fc4a727f89cbd420dee046f08a7554b34df4d40ad940f14f3ba9affb9dfebc244b964427a95a11b69f9bcff4f4fa382ee648853afd194c3e0e5fdd8ff06d87d4b4905e57b4afc937901e5dce596a085d5e547adda8aa5a57b9e182939c2183b18a44e899707ef3442139bec8eaae2ad5f8ffcebfa0a66952419d8a14c9469fe5f26ad06a830aa1ddc8eabb55ddbeb5df35ef2aa37155ce6b390bacabe1f796e0619f813bb7c9f2a433bc121a7ec4b063e18b6ecd2ddc504028c068b5a3f0a227c645ea0dcda03ce2415ff68582178d0c1281bb5f0d9d01396876900c483b465f4ed9efb4f43790eb88d6cfa2bbdd1189c9d0df02c7f8062166ec2a47b365990474fd90d559b387774cd21ebe3f7e5709e98d41852ed027e6df5caffb12f0c34164507f787524f61107409c01133b4f06c6aad5f581632a5ef4d7c802e4124a196be7e983e5306ac1a230b5fb140c07adc56a38b873068025ef0cbc86d95af8c220f83402dd8c8144e6d6fbc8a01654da62c44680955ba175ef3e6ebdff1d458172eddaea322d0eac20f215a937eac3ff36292ec4658ab0f48516741910e6d7295f39849c76a88849d4648a1e6d9fdf60734e43f777cb98f2db5d5406bdd3fee73488581001f4f5e48a2d7f7cebe408ed3c9be66ce69d4b58cdda8a384dfbb4bf3ec60c9d2612d9a741ba2135d4140d8d0b3ae1a5c0be0ea82459 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = e8c1ec9725db20ce81dc38ce561f41294cc7500a1e4435d453165de9150e88c2cb014ab9188aa155662250a99e4a0a38cb4b8b05cfa5772e32c908ad66aa5bb810eda6084921c8c4dcbbe8816eafc609ee5cab04305a2980947d5824b0937dbe554a4e7a8d892171cdc93afe94980a1148b45c7105596637f31e83c46ba2a2691d959487b386fcd13e16e80c92c59c943351018262f9769ff8d0970106a7bef7132f1c114357202289a700516908420d206b752628919202780cdc4c81e80afb93751662aa05712159717560f4ccbd5771c44b2680063e044a1fdda3c1287c000fe3b3992724b4217da4bc29d075478cdbce3b02c1e787507b8320211b51a7a647ed462d562776f9402dc1553f2803442f87682263cd3d103df0a7b0a0453eef4aaf1ae6bb051655540a1359f60a7babb3b9087d8cfaadfbe6468bd7355b5a373d066b1b324efa1298bf0747208802fcda5f0b838af5b971839503c7fb90757587690ca8b8db49b76954f4c184e00c7f38229c8db95bfa8659058885382581b21c219f1b73858c1ceee89b93d1885da6377ccba5167a5d0ae3295f55b2b3b87187dc19b6159c3e3209d6c941486c62ab59071f0588f94b4b54c4794a349a86d38584129c73f5ac24b98f9b305ccf9161213cb30bf94a7f7ca395857fe75a67e6d501fbc8c8775bce75c80952f5572cd17d276022f5720e140676eac2cdaad4bcf6826a02f2949a954e5c4242c5f56c8690975d3b0da95342da6acd1af2ac42088e46a3b0c0248ce2176e897c3c7a84737dd0315628ce76a17059a67dc78765b21815524a647a72630a2107ce26c0fae0c4a562bc0940283f192e94e961f389b300d7a77ee8193eca6d15a38dbdbc4df9f1b121c93e496a35b6d494780a997a30086ccb04f82760721460f3c2bff6d13cec9ba550e9c77d7c4b4ca2b3f8393ba1bacfca65cb2730c11fa1b5f3eabe46fc86bc0c7a1bc481412a106caaca881a1216934075f7ce4bd38e15e48c8363392b8262b04a3a9df21a6daaaba6882300c43b2cdc654ff7569a15cf932bc234c35b7a640fcc4b0d33854356723806e06c79696767b3112c24659aa77b1303a9f5f512ef859fb4557e7bd99436db48e1c55ea2b7aeb3c54a87789551f08d8c47786f4096aef8374249c4bce8c035633b2b4badfa500171acc1aff83efd80c8721918dc9c9238846a33882f4fd1492a7151fda95306b2c212a2167ec3628400012f4b628a119898055feba6c37e55746d9171ff6aafb810145eca9538d46fe59ac356e334c8a545678a62afc33e1592c578b063b9b8a76aeabb5708238ecb77987bae12f2c590d351fd92c9ef743e7a414a5908b84f9a7ec62a06e94b859a387d49308304a303c35820c45b69a3c624bcfa87f40c5a0a8cac4a80af3a0617e952c5606473f127353257b46754677a28bc207068b8965818d301f48007b2c9678ff2c4170594453424e5d2bffc954c0de338719a89f1ca55ff328b1b3b3d5b742f8b9484fd296b1797afbe18c76ef6394b4aa2f61ac5d0196b4dd35033f1570fe07836d4b18ae59b420230c6f98291a16d07409741953049a354cc398578f26ff1d996e6551576d54c5503981b0779b53321527c9a94359a064809ffc66905300b9e829efb636a65eb4ed33ca697f61fc0579e99454c3b429a7e793612f705a4e048bc2558f3ba75fc37634f99c6d1ac8ebc71782a18929e48319a36532be581df871b3c78c4b439a6b3a2851183a3fc89cca6561edee187c44a1695e09f1f508806349e956263c64334000b3a96b4741763218ba4bddde30755e6a3603b914510a2970808f6ab5dce0bce7bf390d6a7c15ffc6f2c70a3cb66bc07c06f0977493d581b7ccac9e5d0c614c75aa2116b591084121972d5fa0725a62b6e460c5bf3609fe07003279f4b87280a8c6bc55001165b3f8b98b350554303cc39ba3a3f1621445aca775b27c7d504a8fdc70ea3b92c897b8476ecbe90736bbbab2bde30ce7f3805574a08bf81b498796d68d5c013505bc2b5262852ad340a +ciphertext = 9355147f2a94c2b07b1175eb81038bd097d31616106f8f47e156bde4c23a2ae940e809339bb8e3c43e9a127b196c752cefeb501ddec39487e5f585a616a248d1faa3865af0071da3d1e4f4c5dcde7570efa480d03a5513ba6207f2c3cc40bc0621c3ca3913a230a12fd23211dfa54ca20386234114d6c7ba55a634820a827927b2d7261be075ac79a75c07c60c3a7faa6d93141dbdac305c5f96a7f72e7e119a5d271198ff78021762b32587190dec2c7d1408ce303566e7d3d287e37bf7aca291e4e35612c27f0167cda2314a3e643967ef8ee8ce1d4f053343f90423568673b448d687532a2f6e7ebfb456a80e37ff5cb8f6f2650892666649d5b852172790e1ec1648876e507f693d5319ad804f59d15f83d3954956efbe8073f8d87a02ec843ffb7ce26573b6d467c151752cc714104b9fdbbcd3d772a7d79a57fedb48621c72451ed8f46d93af431b2346ff56312714979cb3f87add5ea5329aba8582ca5aa90505d8ed076eacb550c6eebb1adc9cd76d976e49f968ddcd872cebc207729d1ab4975ec095642ad1f09c514edee36eda3ee71f49cd506433313e04d1dd645823181da128a692d79979192cfd53ced99d9ae2c11ea21eacb2b19476f339e24aacddf903ac1f7f14960d27130de6ab9ccaa962e83a2aa8add814460dd441f2281ce4e01ce9e326ce23b811e2e9c247c7acf7d696cda346706930a31f22a7e13fa9ccfa7c010721687feb3dffdab6291c826600c223d6ed949710f9eb61a02ee2bd1fd999acec2e608785fa8ed6453cf56365e7e9fa52e9ce74268a0d559019616c1665fee0ea498b6df35e0f11779382c78657cedeee93ee7113c7f0fc9d3bc62f91d652ac6acd877ac9aad0f9870e3b7e8c0580dc88411bccddcdad36917d57985b3171ec093e1499e632c50b1a9e3f02931f8ce84864e181a18549cdb89d21f0be3d1034216c3eaa4a64caa04589c373adb3acd4d26577edf89a7b18f929140d9cbc1d936e2a71b4bb5e3fa4e1daa9a46a8d0efa4b1560f520498a6146cfbb2f8bab799cbb505aa3cde5e6cd92396b4085f5c164ef57feb68bc5a63be7d163e98974344ce526973faa4b7eeaa98f8c72e705d70925a8694de5739d98e5e9997b607b040d878c68068df1f26166c8b5617ae465b2574e0c9110069cb7b52b26fd0e5aa27e6e30da4a67ef02495c004a5d2a5a220abdc40c885a0ced90b65ae7bc07b23f3be550d7bcd8d0aa197e8f5a9a34d1db9f6af2642236a1a028a36755c65af17276ae9003820c2c289b76b451bb2c5addf2875511dfe0f06be82815ef79756b34de8a4ea3032dfccda9d12d0bc368406512687882d340035ef2491a67d0983d52b7b353b80181e0dae4dacfd5b582f7ec4ff84973e4996e30e6e62cc9a9363f7169300483ca321c65a36162341ba176a3bd46cde60d3321313319e523d02e343fb52e93a6a67b9fafae49dbbcb6c694ce0f1ddb168ddc844cc31323aca6ddb3225f089ed0e970c61cbc9efab6eda3414c8edc38167d2ea03ef528663d9111a7ef305a8a9b4ffff4486e2509b42f215a297086e7cbe842d1e304e3fe5150fd3894663c9dcc8d0cc1325e24755d3eb35e940249895367e3fc4b69a0fe583139c69ceb073967080beebb7def63d4357af1f9cc58b27afb63ec0c6dbde2b670edc7f5eb5911e04b89122813869664735fb29b95c7478c9c0a904634a31e8f23a7450692737ea0b90de19c3bd3888b1da20ceca9884c182ebcb33e025a3469757d94b92db96cb921e1f52eba6027f1ba470d5fa873ad1e36c6352858580b2a737deb6366fad9443076dc6b0dce59c2661147286c1ee601f872e6e16f7908dd7ed43dd8288178dd28779926cc114a7ea96068ec0d1e5d5abbf183bde7b45d21cb98ef5f07e0349f5fe8eed42e5ec0d61ca25edc685f4280633c0855c9f9155ba9846a98e1eaecd8bba771a445a033af236557db202a0bdd6f0a919fc46c7d34c64f24fd1b9bbcd8bf20c5b5b3c54b18002bacba74ea87d83baccde6802b18bead3d31f50ec57363e1755edc28b1f3d5d8e90654054e716be9432ea233c011b3a90801d18ec697a3599746f634c07f5ff987d5672361e95e648bc02d9576f892733037c5f3d73a7c3724ef9039cf0561d19f422a40137221a76559509ae1346d8bf8c415c293a4c73e4a0b97c29e79db5041e5c46e77d3b668914e761857d9 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 6284f35fcf6813d724bf0de92ecd6240bc277917121c1b4b737ee6b83248ac6f762caa149638304e4ae44ab84356627cad729b69566228c20cb6b88b921b027a37fa52f658805303314ff7105a204cafb62fe28c50450704ed307ca072aef585413e50979d043786d39c09d65173a28c8d50693ab4c547808d45993d3788880c8a6d6a94cded24382d72631355386de290cf51c0e320891ac9644898bdc506beda788640e74927b6cf42511e8943c2e16a926fd9603468c591138117f480cad9a9e1204eef816aaaa734b93356847c4111f3c2e4887c65b7cfa9fb344ec83b481a0cb3256ab7e38b1a433a03143145e0b09c1904dc7b734a6139c3f6a5a399020bc087f42376fa984fccfb3b86229226008e7a16cad6c0107f6cb4ce23cd29111ffb950c842582a2c35670d700228a64bfc772207331de5bbf2b +ciphertext = 141347bbd9949f7c01486c37273f44676e9fb02a6f83cdcc2ab468debe9b0dfd95a25316956196bedb5f5bfaad77c516e81baa110725b8e6742dd08a01a2a0dadce9264848206a38d969f9491ee708693f34502f4f5209a9d7cecae18dc873ae5b2d010568dcc4b98ea899dffd6ac3ba27502fc95507f5c0cc76bfd7604d1e5da5651f73e5b811974382fa959a7a907a33642a86db554a029dc332d5ca2dfb93d5edb34bafe8d4a15f677613479d403e4551c0df68293e9219bb507663502cbac70d10af8bbf639983beabcae4395c78718dab0c072fbf45e2b5ee35051351bbd6201ecade31c5ce8c04b8aeafc392b402d37d18ca2f49c01e150ae5d30844841ac7564b7e5cc8deb72246bf435f750c9d90ec1e682a9ee7c56f3ea87168e16be8c21f716b9012c7f8daa185efa9c38d3b2390e42e4ff87f8d62808c33d603b2164d4e9bc2b4eb92c3d9c87ed0dcda19fe26d89da923cf4da20bf6fcec75ccd1ea6ccbd9a87f11ce4aa0a50999fb8f0a1b928030e3e74b0faceaff90d3e2458b651af15d4ef6b656c513a11959f2ad234779f3a35853f6a81b7439729c961cafd5b8b0e4032d04ef1420c7b4ccb1cca6416c6ff4c337e659b5be59ba0e4914761174a69bdc677ec1749d5555281bd92e1fbf1029702318fa4a1c09e93a92abfd45ba7d6f671a74dc1502e6316b0cb1bf3234995cf9bdf9f414c658aa033d2251ef61c7ca636417c0c8807d7bca3c07931b6b9f72a9ad3dfbaa2ce4abe21ad9a81cf92454685fc41dd331f73a6a674925c2f8a41310f7b664f531166b3538901a9d012b5c22b74f5d182104f49f13133e15da814d6d21db76791cb0d553cf841e9743fe618d0998a954a27c20cc8389eed91fabc14311c42d38edbd0027649af536be1c4f162396f4f28bf19670f2363b373fab24e30c8a45954163ec7e22b234fc41ec7ae425a87eba26eb0b56923e7f101d393ea2351565fcca614b8396b585658bf3c91b096350ad84c5a9235ff620196dd219e2faf1b9d73e4b2a84c2c4c9c27291f5d2fd4a26be2d64e5ab3367614bf17c85a404af4cff7abe07c2ca48923cb6ed5878d3acb6b23791d9b97a7e6e1dc658e6c6c9a1613acf820af205425db644f5eca1dce0209c7909581e3ebfe2cb1ee1c5359608a76456021c22ae7423cc56c4d3e9444dc19e5fba58506da45d31fdf606ba66ffc7b72559ffa258d2ec3f010cb79cfb6dc887999f52f748a91761bbf7788de7c54b3da04accf7976d6da7629174d827a95fb10bc5f37a0b899f374687d78ddd7b0511c5c0ecf8240c95d452da200ff57edda9b175c9554d723c5dee1a347b929f751b523b95e87ce39d6d0359aaac2b8d1d94f942836d9fcd53a0b0d5acbd54a11a647cbf23ff3909772965f765b941095210a9944f79a97b8098874b4c9549e13dbf72eab90d592be042a510b914eb99fbdbfdffdea71514bee8d0f62352380d644250158cb087266e9bbed0fe8004a700c05aa6815cfab2e39a57fb4b7ed6feaddedc0c995224e1267178fade76bfe70c804995db3d65b6ee9de745b2af55b1ae2cd31be60a989175b5a161d5662f0061cf9df519c9533cce8d3ebd4e8d3d7989224fb2b8c3df8abbc4b90e1073af6e63012893a35858f69c94659dab9864ba809a36c4ffcdba2e5d8ca12be55d19c2464bd754c1c4ee90e29b897a1f4ee3a9037eb4651a8778178abe3979ddc3d0747ef5f470b39387584fbfbcb03af25f62c1e177ae1e96aa01d609ca974f94e855e8e336390439ef9105819e0aed719844e337f0e84b21cf8356c96e5cfa3f4a6542874f5211946b5767c1378e0cc5f028835e3d4c39169f3f73a8b39ae3dcf3b2a36a7908724bd3573a926182800dcdd6525fcf634daca07bb724ace9fdb074795191a712a506d54ce1e7e2735565aba2f5b81dd4b4c093f23dc0acae53994e231fa3236fc8b7ea217804ecb5558fb45e762ba5d846feca31e12d4870644bcc602ab93b0701125370aa7aa4c07828092016e2d2da22d243c9715e839db3c805719e6131f4d19cb8992c00894d6add12c5b774fec558098d2113b15ead990cc2dafd51f66e0945468b22acd3c0917d1a72a5f21af03b38111fe01393cc0ca00bea4b588e04c4dcda78528389d985a72483d80cb02d92382eb884c7606619a0f4674e1f4f97143c75502ef3d93d26aa1cf410dda42c4974fbf288 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 676f16797a7f04cd8a973534d752225b9c59634002f92805375fdaf968c9d15d88c3505b4ca11a87b2bc2052c6b1a3130b4098c778bef0a7e3e3292ed83239428d9997345f705ea7f6c5725887af6666b0c59b60892d8973680777103f50677f3671be9508f23a640dd90617bc417dd12becda71bec3c01808a69d270881077d0440116c7a627db4348952c358c21e611c3356c7be768933ff834e7792c886c4720840a28ce339c89a14b6b90d86dc2fd7f7aaed5725e9183ff56b07e1220bdc03418eb90a703050fbd3678afa8ae0ba7e783465ce5bc409922f49a5c7dae674bde4208708818ac592aae724f7bb1fe7ca7883908ba8927156e00944e09932132ce9e4a9d2b2b8ffd073ca174bc6e0ac20211b82318f4728c67ab4b5c90a4c86c4ab669bca92b080edfb4ac8da60fd99620974797bd97d306acb93ba89e43210317b26854c9c72b97a19b78f3c90807e485b3d943780a39508593c1b356113fa427183c427349ac4b66359448f1c67add951c0bb90cae78a3688343be3495519b258d67900563b07cc333fdca8be90da6bbe176d4924546387881ed034faa73f2a0acbd0d358ef0c0bb9e9a45a6bc07b03b0a81a3de78940aa22082f16c97972c79fa68cfa214992f25a14d652b61aaaf93781f67a0912f5bf5fab1adf825e0d4cbb9b91b0eff95384a78445593ece3567506466ae8b01feb5585867059f3cbe87818b5e9076d2611435a834a5a7673be46a9ae36dd2148d952c647459ba52e02d26db2dc41c9539479bcd38ce3d09c907189f08e5ccb0a233f050490f084c46000eca6005de43899d743ab6d5b85421163ac0c5ad587008c307fc5882dd63a83d8260b826ae62fc41a9c6bce2f82613d24351b006559a63b7228689f6b8459b35e091b8799b0f8357113d56398150ca6ca3352b6164508936a339c69b9ac660f2510be89cb7584f663c9475c93b54b3533016566d661b28bc28a2bbc40d954e2ee0bb8c722d9c0b72e2f725dcf537bb8650f8d30756423c95825940398805304e2d51a6ed6a1b496ac7ed2339d495abe93c4b7cb0041583aa2d54227e6a02926b639bfa60c18981e3e96d33579e01bcbdc625aef546cede459f94c1a65900c6667611465a47c979b49aec5270f16fea049758da6a2121abaa801ecd208c2d3836ff9bc589686de14882615532686b0e7740abd67b40cdc5358663b04718993265403ff6b3de4a4aaea0bc21a9b7d7796f4d3a2e9208542dca718ab4b54a43996bd59de5ab6f1110182bac8f2202ab14d78a03513afeea9d63787b2da220ef594cfb150ee072be5dd02896ebab306ba49b7205c5161e001c052c708fabc579fcd3a1b581b3e4937d4bcbcb49250ba039646b191361339956fc90d6b99a1e11976e768535ac20f84157445221d407c00d7c289f842703f0005ad500d0aa0b443639acb49ba61413a348ad9dda12c0b7324f84b631d5c4f624b0a5467fe79a11e542790767beab1778e9c665c6667dac86ac0d1587b6d35349e10c6be9abdc855f8762b11c0400 +ciphertext = f82e1bf5f19daab6d8e8982b3cc8487d8e09ced830c71f1167d52d207bfc0dd0d7de8a655947fa83d231c1d50049a838567488308ccac8c6ffbe39b93b4b84311b0beb14e8367ddbef0a89e14025142323a00f5b1fb80ead28c94947dbd396e8fb19705735b033170b5240fc7eec961860aa61cf1da1fd0551906130e063af567c8ecc9cc2bd0ed5bac20009cec1e7d14cff77cc599ef98df26c29815bb17898c8fd267fa5739ff2fb1dec57333a6916ffe6eba42b0a1f95d1a65c9a0667b011d982b01a7424bd5ca8dafb64a655e1552f0f31ebe1cd7d1ab90ba1855c273a30ec5c1de492e03b8cd662b99c0eb4f4d05b7cdeda1694dd406581380479c40686dcea7af8fdfb366def613882b5b3b8ba318f89455dba381882eaa2bf02923125d21edd70534d3dbf5cdc43e85ce34a8945cace97467102dbc73863f6cf97482c0394c5795f0b327b56399d2b0889b03ae8a9dd5015a1fc801b16b14cfc713dfd87e2fcdfd5b411cc84379de46d215faecb728d2df9692aff4349eac1c5ee942ddb30ca7246a58dc7cf8cb229573bb90eab6540c27e84e8f451899f5f263463b1d80e1d62cd010a59a9b8337f84b7e020d5195a7b0fdd81bebf912b6ed9e4ed53cbf03e80a30bc8492489da2a2c041d7f45b059e1e67ce7819862b4ab7a134cf691fd2c82d00d0328bd5a4ffbf95987058bab8d6b44dc7d2db651ad8916e218fbdf7b53b8d365f5da81da9497764aee838e1bb9ee40aba5aca635924ff018468a7aedeadf15c3a15d0b04a18935b70a20f6a493d511f89c4a96778bac0578f4444003e08de3d80b000b8578c778afd6e2392c0a79057dfec1e283397b08779a6d5da5f8c98562923c1121be61426a49ffb4ea38602739329b06ab202720c625527ca2a36a07ab29fb0eb1dcf91e5d8e6c449fa300c1e9a50df47917c45db8aee45472091cf0535a361e3493e11c46b1908ee4d3ebf16219e8eee742f7d7ccad9cddf1e1805593c4b37f8fd1b5367fbcaf11006a6042571632fdc111729578096784bef6f0a4ca98c0b348c1e1e7a092123e777611b896337b721f01a4873d12c62b1798410c45b2d0ae490983494efc35c33f9fb72ea98b8dfc2644544062570f0799d4d8d1749353c0977c2ac42ad08e2e9623ff367086e547b750ce109baa3beedd3da82bd40ee643ca6565e5c0c164767828e6090e02e9833c39f66bc65b994b306fab36c62f08c991efdd5be802503efffc11c48265e37ee801fcdc79bd4fa4716f35239b903a948294ba0fd331a1fa1b5ca5ad569f664df6f1468e695b32eed3661a2c5ca1671c635392ae1daae721f5f106a53666edbd8e512684fc6a85ef31f3ac4377bbf2a4362378a4654793e34e39c76ce88837a7ff7bf1e47b606cf1ab8c797e2e13f137c99c66a91bd8f4a7b9f23e2cf88fbcc0d6efa9b7e45998e5f58ff077237130a8ce2c7813cb32fb772388dfda4ae0f9e31481f9c86e78c1a7f2ae60d2d93adce09ccbd7e5cc099c1bb72a52d065556c738174feb8975faee6d81cc80b4872d9434e88b9c2b22ef9f07798011b33bfb1d5465805eb8ce7fce2f6345f587cbb6dcfc8d4a5953d55dcfcf889d87e3857da064fa106dbdac70733e063cb7f5a5bd625a42e81f814a6001dbfbedfd8ae690b674353147e2e3bbc06c34d3c316c209ce1883fb979fad58e40aa54530f07221768e01c82847c5dbf21bf433d21630621dcb8e0f142d897b583d02decf37ac5652739b078048ae8888bc3e5a46ca9172050ee85edbece0a27efdc3fd2792aa9897a1da1a6ea0cd03bd23ad95f255e249f8c2d3485356919d67761ef0d447486b693c36c0a4ac9c066282f6544a6e18339d7f74a94d1b64f5a1346070e3e41f5a8d3f8cc0abca4e3a8cf70684becbc8a6cf73a622d09659c5966c03ca2b22345629b1c702f84953a65e5078f4a1ac25a23d00df97f3d892412ec3ddc477b6d7ec9ed19adde72ade9d5d158ea57d6aaf0ba5f9db27fef1f5183f4924930e7ce66cc4c90093a4352c0b40704fa1b66fa919c9102c08c2822f72bb55cbe2440f86fab7d23535c528e24707a9bfc4c46c99a5323ebfbefbd59abd44e748cc21a30f1541bf21dc6324c9dcdb8cff0646482b7084015f5962f3845d3a1b7352bb1a26a5df9f1f67f4b4e8bcbe941f05a8e6a7d27f432b8caeeb4e5aad987d3b1bdae36cf0533ef05919389a4 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 7d7a957c34cf72e1c2e700907d0b7f0f970015c9ad66653850822413c23b21e813d5953fd5482c423cc81299005bf13666a63f68769afafcb513d96705a4256d351f1df11a0738a9937ba0f2d88537a10149173dbbebbb8fb83c2ff9a82fd51fc47620b5786f35a2a468755d7db228bbe94be54c49147c119f30200fb37a02005e29a386d1007f9f13b16c781a7452917e1b9a5de40a6e354abc8409ba731ae4731a2d1c95054640d3ca0647a88706098d34a37369e674963b04f42c7b8aeaa52964112548645a1aa67e6cbe4ad9c0375a18cfe94e66a6b3547735ec13ca52453bf22a9da059938af1cbbb6c37614566f8283e2d32355fb6ad6f23ac +ciphertext = dac08c19ef2d940fcb7b94cb1b2c5d69f6e509eec48a7d1361ab9e5b9a9ca8261fc3f41cd3495ee5c299f58cefb3957977695c608a19704237ef9b54e164a890c8aa916344783e21200657574b2d1d6c86d0c212686e78b1473fb3c7630c3a0f38f62645e01a7d79aba8f39492f8ca60831a6e53f5753b2018c38db2d0e2da7704de91e8adb423c4f49bdfab0a907346a08f28f15cad2a57840519bf80a9238327a257ccdfeea10c9e9149902a778740ca6a92f3947580343fb28c52f8b2999b808a953acdf6e6954e3db1b5cdb266ebce901da003da2bf9aa5321f94fafe43d8d255b30421fe53d01ce0b8e603f3c6fd90f77d08a485e88e32ac8f4e7e5b51382b3eeb889c7940136d9dbb8f00cda0a0fb8f8be16132574462281d2ea5abd87e976298c27afb380c58579f9c1ffc417c0c804ca95ad61738e0d68c9d353423ce53194aa28c94632ff3b3caf90f890974de2f70a698094c1347fcc77a72807e94cf66ddb2e1069eaa8705aa1363f6774b8e04efe271cae96590e994bf41bf4866c73feb9b777e07db4925249638b2980a851c1519da7095f60f69a75ba64546f7457aaffcb9847966b428c34c68312c04a8483e067253ef117bd73369bcc5d2c29902a88b9768a65618f089d371a2c4677db072695dd2205a30a53c9e8e3e7596446fac23b51188f2ed31cc99f310392a969517442000ea2f864debc269e78bee7489e9d40b08c45c0aa0a303d3b7aacc334ce9c3b778d8fbfdb2a013083f1c1803469c1ee052582c6c08a03b1609ad10d40aae30beccab2677918799d4470d86b543f83610e4b6996535b968c303774e141732c25d2fff49272dcb2a0bb963bdc1cac6104d9d5c850aa4f17493cd543181048ee9e23329c5711730e7ef4452cc3c8542f539066076cf88c2afab08b30408be9de358ba39de9760a617c45e6e2c9465933d9a3b7f4b3325b26dde2ddfff88f61fc060f65485bb69645bf7bae3087d2e29fab1ad0aba307411e206d9bc2cef9efa0b261cbd31ac314f311f41f4e55a91955076f9714900210aae9106ac269b530686380fcaa0a8e479f43169500725111e4374a664d41ae87fd989a90cf1a3d6845164fcdd8d5332024068c449ebe3f9f27f1f09d1667bec32a4d5e41192ab3a9748877e66f847066e473f6c5087aa5dbb7bc20a93db65e15029c653f2fa1b32a7b39e25fc84c6e0ac35a9af3970e11b44deff976fdf7771e9eca17249f2e3acad792d13a3310178c2a5cd7b0d245ede5c9ca40c97f822db9beae8af3ea61a056cd69394dc92494bc43db25ce0757ad45dc34f73198ed2bfe70538b7384d92c4ad3ec1acc1bcec9ed789577efdd8be115151b4429ac871685c63271080674c29e1ebcf20a2210602231fe53c65c554d80145bfa7f8d2b7e368bcf31d18163570c5a488a032f7ae5803f4e59cb9242ba4628700094351a72a1a56d8e76d7634b27f74d2eaf44d86536f520740b367e97a30091c7727ef2ece0ad3c19ed83aeb97cef991c2d8bded6ca796de3f246856f53e19f69c0dc2471b3215772625b9823240032c5c7fec3485c35e788e45b61ca6dcdfcf2f181445c45938a1f81efdcd025870b92b8495846e5417a27c9d9f9e522484f4d8dea865b984a392c0bf7c25bfe4588a6ef9b27f3feead214725edc3a6254d6fef6bfffc482a3510b4896743882317b7f2130eb2fd248b3c37793581a09c38cda4b37e9d52329b539d8bb602e595154463a7fb620ce3ea33355215eef0a976d70cd40a334d5b856f4d85a46374d6422dffab2cf3856fd79a8f31a2af973a55b20a29b5a1cbe4bd8ae0e155a67b731a625b8d696306ba1684412d9d354f4321a6d0a43e8b55e767fcd88d5221b546d54987625353718c2514cb17454bff0ef6f9e6fad0602dad5621ec11eb4f9910c0d7442515f8522d680f13dffbb81db14c40eb660f200c3d65ee8e1d4caf7c9bd66db52567e8fe027df56991b3b1646ebea7442c54d6ec3e8bbb8ccbf74051db416f475cd764949bc44d623540ccd793a3612e16a35a890057cb8110ad451a73b65e03509c614459a440566c22a6ae57411e9aa8a610ee538c8f1e8bb430816d4db377c94fa44f4b1f40f7ba435a84e098786571e2283da28938253c77c8096b0749ec42a38a26c6bd0894e8b5d09104d1dd0e7c71d8260321157bc39bbcd7a69aad25589fa3d3787126fe3db +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 74aaeabefee69cd822c5fb55b1de46a6eec2cca606bc993619d24bc18fe7135740beac30b35499888ab607744aca23a7bd19cc04012aca71175b3e7c285447169d293ce1c0622534be47081274e3375710a8e8b5a701068d67f94eea0b8a75e04386fc07d4305a81c395ad529b9855 +ciphertext = 5307cebde8a27cdc32844654b2344007d69bace076badee760dd68be70e256b330c55a3276b8170ff0a5ff9a2a3b8203582cc3441ee6fb0519a71e2c00271c9941670dd01d76ed788b8ba900c651aa3f03b43d4e1d880fb26bad15f0cf6ed828647f32c7cfbab7bb9a41a6a465e1b3c60ab0ae258572305a52224067d318930208dbb799222b04c37d7bf625bb11471a983bffc82c445dcecc08aeb717ced442fe86a1267bee5f3556c89ba1977a11db9f3d54735a2f839f2d6fb72d4e3d0a361cc4d224924286c68ea4d9e7aaad1f89ceb3b567f4114caeee5eee49286ec4519229c17264999e09d09ba9bb1268e75156119c8db279b529847c11d00978363c63d1a6b18556b34d9583b00180cf2cdfcf5087f43f6ed383ef7f7d2fd53509170d256c5755da4287d9601d5d147c287e57cacdb62e67502237bc31f834fe90a51e1961c8f0336703ce930a28cc7052e2630591622d90551f5ebdfe3cf3ca6be49187f014d470d247783c11fe2675bb80f58cc11de001556a49b55b99ea1d78a5a5b47fbbebdcdb9f5fd9cf6babe234f939d59d3e3a399477557aa0b38934a05ae2428083acaf56aaf76ea4cdc559b579ea4ad49f661a7d372985220472567f08b1bc2d9a79d15821ffa608e90167be20c09992e521579db120747f67cc5cfbff6a86e3266acbaaac24293874548b85d1f4acdde55d48f6d1d722ab7426b58f1414f72e7764fa2887bf51319e914f33658acff1ef76db928af4e6380ddc06cf3d415513f24025a8611532f5992335800da949863ec9e89be88d6732cb5b064fc4bde50c49084e09b891132bcf263e9422ab9356a710188518794c19f715f187ec5bc607d497efaf41db0d4cb3345797b0e46d6ed6dce2e77d08dcc0c3d28c6eedd4577cc6fb2aa1f391a9b6bc65ce3ee41c8a25ab3cbed9e9711434ef5322ad3524f2463f1d57622feb241a04d6794ca93e53af305050431655cfe3f28fc387748a50f0c4640282a5c9929a8d6953cb3c3d52551fefe4ce4825689da04751c9254dce3486e5598e5da9f93151de4ee04e3628331cb21bff53579a4de8a29364bea16e6033e1286b53fcfb1c5b37651a1b287a07c489dd75589873b526daa7fd4235c5d00dc10735aac4078fc70667786d679fff4d9c9400cc722b9d81e1b7bb7c24a613c70fa7bee9ac9aed08e9808185e9d4f3a1415702eb6430b3bfff9d7ce485b8539336d395e1237317953802f151d3949cf72126a7380f8634985a31d0579d9733694247187e984f9fa9486b7798ebb4f1b7b6aaa2b6e903afd086c06054657f58ea07074d3c12502a5b02a020e45af27b9b689441d8f20d3a940ebbeac9730eddc84d64bf53b9997639da0c4776ec101478b1f54eda549c5898c476b85a12d1280d29d6d28a10f11e304c5787a18bc02198767dd758b6b845e65b289c46c292308ec38ec1318f4070e56505454a8c18ca917da0ee3542d151c2fb68531f0727928a232b8187f9eb0dbfe0b90902e0f4e0a3319001314761d0bd2916f35ef4e1a26b2e94d7a2956b45432168e665fb730191ec9ca4cde2ad96a63439c5786f59628bedb6dc50c7e55bfffa29c156c12a21a7fdde80d62973ce95248322ab8208580f1e56a56d97aff37424dfd39c852f4d2bdd9773fd281193668e94769eda0d4749b3727d096ad3f6fd5595bca082e6437f76fce1869cc8eff8c5920bdd9e03d9b28d8ada7bcc099116143f884fa4cf0bc73513090aadc80799f26c9a8f6d3e430a02fa288061cd011a4dbcf9f601750f03a87f82ce77c48ee86710ac6fcea87e6045aa0d37cf0c1a03144c7c174a7c76fc5756a1d226a17a397194d1696685c13e11af7fb895086e781ce6a3c20e3c92fd688c57f136bd55418c02966d5c2fdac5a0c196143cb553b1ffec3df1bc6f52fcd0a46d5ddb551367caac00177b659a42416fc84ab5070db19e76adff80adfbb555868e6aafe90f97df4a2929c00bd09c5a9194644ac11622fe5477e4ce684eebdb3a37bf710ac037c9a506d86af0ad5e413ee1449e8c92d004286fb733ee1a0f4d811796c07b4edee59aba242795e0b5fa322d2172a278f89764cfed94bfdd03da7bfa2e293a5585b6fd73ca67e89ffac3bed46bbb2ecbf76dffdd9018c66b88425d229f9a470b64dabc07253bbd49a950f89029aad8fe95fa9e171d9a4f5cb346171a9b0b99e6f9d823f7b8 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 63f126 +ciphertext = 4e60fb4fa481199a478ab1b9e08f52c0f345c4620a3983cbfb8cdf7d4e626e37ddef3c2cf3a0f3703f6672e7f506c65414969fd5222e6dc9433f52d37ba8267e96fb80f97e5fef11136d0492412382dadd4d0924e46c43a9635c5dbba0648746d20749e3f72a6b79e0cb40b88623f4ec87b1086bb37622ef26ac48fb9df15e08132e9a0022f76e6f4892ddaae720f6e501844e9c1a645febfbac1d71351dd1945135638ed6ee9c02859d00d864510093dc21bab05f1384ffdda65d154a21302d90c0914613cd8ed25d8c072b0c6531a929d4717b91a56f828bbd7fec9e9a5f9ab818a6ca3551995c8a77ebef1c1e0ca39ff8689447bf231fcc107ad46009826d0765f89733e0886210c5aa3b99418a2859f7c58033d3bd30f5f0d14801c16a64f07d31aa859fdb10b131a85bb0f8d88f8e26861c08634147faa9c965c0e35abf5467c21bb4d1546a2793bac3053f88c3a0101d96f5c65c3360f13cc654bccc633998a1ad356e3e211df5d25f24cd8b4660e7d1aa4ad16d0db23e24684c68f1d8d692d1ce18dc267b76e7f61c80d66b869ed1ad2eba3048d3cdab37a48986c9cb549763e2cd98d915531cabeea290843cc3912c4291f1283246344e0c8b8140f71b9a600aa14b80fe66a92ed6ef3bc5ce2f713892f21d560b82b06501abdbc113e4f6ff8f40667d8380e6a06fa61db914f88d8c09bbab7a7953bdca67d7abca82995edccfebc1ce685caeb35dd5078cc3b508f331f48492257397b2e03f11534c456c64510862dfa260510bcc3476a7bb0a0a02d71bb6eefda0206c94884c7eaaa164845741a9fbf582daf0732f021149555775f12364b309a8014f7a9286ffce6c283ee13b54c3978e1185519229550bf3bb40f26de8fca247e064408632eeb73e9d4afc89e6554bda17af721e506be5282870509a527e45f7c5a9fd410efe98e58ae8187d68e3439d5437dbe7b84e8e5c548eb1aa69a1ced6e264874c0c402781dc97e20b993b394642eddfc1fe76158b551f6430a497b7cd665ab6ceba1fa0dba0d96d0e46b7af8e2bb016b84128a105bacf1c16a09a95918e464cacfa65793076d34def2a72779e01c3a900c8bea7aced2db2e3001f87f5d695d16db7440c5a4e14d9027c2085121785c4e3b8beaa2dde31895c17becdefebcc3b771765bea6123fd723972ef95bbc2dc8520638a2de45900555ca96ca9a2ed3963cefb6ebb3778502b590eee56890c9a61f7e2aec71699ff4263923434451f36d5113423f9ff3974462d644aed1c2f21fc5b38b82070e96ea9a07cee312a5ddab1a0b26553fde08550db0aab820a7568d9964082ddaeacf68cc28230a47a5ec752a0bbb0ce4de8e4c8d21207dae2aed90b3565354a9cd704da28b99224de87c8b09a027398e5adc7b0be0697ee8dd0e739321592a2a2cb1327c88e5d3fd7a874377685e6c2711f15c48fbd4409882723f92336b73d485d7f4572c5e2b3aaeade154f5a61d1685e6ea5be963ffb4b15cf2e93c6ec4bfb0d56af483f430b6f7bfcd0eb9202a4c8cc669d34c8eec5f6400e857ef7805627dedae75daa59e064f11c3a235c91c17578a3b6460f9bb2081a32bcd8659d5fcad32b65867375a1998723e1969c8cd7b9c999c59f1efce75460da6d83e4fe9785cfec15ad1b3c1c04db11f42b3f32b7a80d3ab16ea910490fc09b308f13d0ed7e71523979694ee2fa4e3aa97bf39094d99617c683bf472fd7264bd282813d519e4a6f59d7fac6d8f5b240e4a17ddaffeb172c12bc8a01c2234cd4e704923d1afbbcff05b827f7e3126458461b1fb8bf506e5eb6a51326f263d3f1315d07e2c32c854c06eea88b08b6c3e1c97b1f90d7c26ca436caeb2b7269fd8450bc95b07c82b14efaa0d0fcc852b8b16a78804ffbe21597f0e1f16cc3f4e966251eece0b5df96b53d1ca326e06da24c6d62edf87c1bc7c1a1924fd2ba91e496cc78defbdee0fff5b73ad228219a221f5489e302fe2b778009b5387efedd662bb4b269ba4a7dc610e9aa49f6f3d78acd1e43202bf279f0a7e8186dc2de58c93cf83687d86c3f94ec0eb52461bffe4d7e91371fff635a549c8879f34d2b6a9e832eb72565e57e57bf6358fd796b5bf130e465cdf5acebb63d6b69a9937636e8eabadc92d89c4917cc48f5cd5f772f9c338b37c0235a4fa5faeab52769af7171eaaa36b7f711c34a59e56f6bfd68cdd75de74a16482 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = d3081240b56f1827c53a2ba0892f8d503369265248534e6ac680f8919ebd1814e13a170cb30d54ebb358ccabbdca28987260a93cc18d4667d7c27442c658a81a1538d95ae8818c37004a28e14f36987c93c957f86986958098d6934d77f1cd8b2c5f666415b9c4b69b9a4234852b0ac5bfbda4669ec71677d049156c0e4143b93078ab02b71027224d2ae7992df17cf257ac1f69896069703fdab73e4116b7289c5d5b6c522148faeb71c2466a0bb21465e94fef086667aa79a6ac7ebf4c8f6b015949bc603411ad298284579a0dc1014e68981999d502b86b6aff5973bd10bc5e5840ceeab382c8cb5efc1a388376081c9a9e5454 +ciphertext = 32540e397ed7414da742b511109f6c7a97e5c610e70cb6a0adae1ef69d37b15fc6b3a0c65888ae86a6a465a46e7461f4cb179f163c874e6f97bde8f7f7b4fcbd5451357bf4dabf95d4ad8911b920bae29e521d4841a0755852fbfbdfa5578cf9465865084b7544aa41233e33e3f7ba12986e8b6216e39ba26f9154341515785bfc0d0c0b44353934e1cce82e1d897244677023cd615d69b6f2d58055c22a19e804db3f7f9098fb7dfb3ccf82d417a8c2277d1ba58dc6dc40537c763440f5a5439282dedca66228e43ec551a6bfcb94772db001fb24e742a4a3527bc0fb64b53bcd381f43f8e9ef289aea26f37298d20b6e5744cffc9a7e1ea5dc96db9fd4c3a3338e693da790cf7023bc8c4c162beeb07a97201ac1efc29c999bb3d5cd137522ce1b5e4211b814c1598cd58af3c9d8a9834833203ab5caf353805811a6336222959188ae3d65300eed4aa92c491284d942545e9ef63963082c65c5a48c5294d8c74f3d3744028808ad394bde754e3a7a8f3d0b66f114c4559dbba147303771495ebc12f38561974b775bf019bcab10a04954f09f6350d188d9f9e09eb4dfc502695fd592f3d42fb3ab72bc687bb1954ead484c98aeee850f5e5870f3acfd0b434e9ea0d39a9bb6e1c53b16e149b1f6d5ffce7c8efa1ee8e48f75d2be2cbc6e59672b5b0e2ea6ce9723a1b05194242aa2011f480f1532049142236260cd1dcdbb6c8b65a5896a11a2a78573ffcffdf3396fa02b12e1334358d6c92c8f67ecd826e9f36da3721254eb2649442d9621d0f8e60472310f0440d9b991fb7f3c70a9d2078dcabb9ffa6e6dcbb714ceec3e3d06b378b8ace2d0a56fdddef604a361267facb5e3a54f693576ec13ca0c47ad2230434532f535209ce83c72607123545560bb11575388223b2a5b1ae099b10f1289ddf531f260e3001eb372fcba48e70d338b3699a75da4664d186fe0b200830348828e379dd6a386b1661c1d767ec4d2bf770046a83963d866b0c655fb72e31d76ad2308ba404b6bef3e1f2439db8c47a59e442850a6ce1f71c37e7ff9b7e752b372d21c9e280f96d8d225eba1bd4171a82aa185829897d2a2ab2d191ede0ee80c327f9e358b4625f035fd349d703de20673a995e93d7a6ad7fc91943bb740dca50e068577692381ea3638b4071eb38d09d613dcf39f99ee8e627e604c96620a25ff3c63c039e58d7d1efb2f9cf8bdcfa00ee5cbc3557f92828bfdfd0c6ca69a6e6a8b3cfe02cddbcfc785d8ea838261fff761101a3491cb7f75be519b7a78add9ab72d38f8f50aa29e4ab402f05398348aa28eb2ff3eb185d6d5a072fdf8ef6740f98228eb9ce58094eec3c4b54bd4e514607ddd0e6cab618afde9dfbea63b2963e2519664c8a6983812f9316a5938a68ec78b9e0d51a288206b4b735bda1f855d23132a613cfd12d8c98374db0d618c164e685b08340c48b65bccb37175dde5f2013622b7ea2165161802b46111412a3500df8bcfb63d4975530f64ae29ff633a223e9f5122e942b12c85834899a3ccb0bc7f800319a6becd756e5a306343569b4353e0d2c7176eda3127534662f5f7f68c8ea8748d2f7fe3e0373058adeeb2195884b236b2891a560b4a0b491b3a2c1a620f6c913b6b13f0db70fb690319aef4c1973493516efad55fad06193986f6e04663693cc295833df383eabc56dbc9623068ef3804bb6074a1893bdedb3b0c4bf847727f379005ba45b4ef1501ccba908504ce94090a651121663ef302fbd5818f2ed92d2078ca0f5c068f06ac4e56d013b1da3bf1fed6998001948acb1c2f4ac09754ab6f7015e004dc1c3d6d71b10e02ab3083c6fbf760b7207559cab4d29e6e08d2ffccc12e9f1a43a4e12a8288c4d28c4ea1b5c77c2ce336ca28716d76ed8b7c083524678a08aeeb7b90609261fc27ac39f6bdf00e2144fd26c30c2f9d4b168ddf036dc78e7f5001b4ebee25d47a2ca6e7a55beac0a2c628a6a24671e3de596d2a4c50c583743dc42a08218b2e449d2b9dc78ccd8deeb8b3ba63aac354a1cc2ee76a622d3dad7701074ac68c7629e11b646ca43d22674e70717839513151fd094ae5c909a6e28518321ba8d306899138ae009caa29729cbac3cf376123e5a679cb328a1734f8b1c60c33b04fabaff0b11c3dfd804ff2d60e9fac69eb0dd93e06731fa37b9a3576dd9bd94bddfeff6eb314827899fc10e7903611d14ef8f +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = b0e7ad0092 +ciphertext = bc1c8ef7bac5ee55c38b2650dc2a3392ee2ec8afda64278a8a75253a60dfd67340eb325060890ddd8e853bc7be06c5491ce99e4afd5c0ad71300bc1e3c8666d944af31e8da5f4e3f4f0f1887b2b2fdfe03c21b5ceaa8bdcec653b0c1188489405067dc45627efb16fcfd0e3d0871d5ada439839258351bf8707894e1387f3884bf64e13117eb6abd8df8800b10ba1dfb431d2d84066dd5c425ff95bf0a296eecda9eb0a28b9c1d9214b8ff21d3255e3903ed26ffddf58b67650a7ddf1685d2c4b5da96327a5f7d841fbc3b58a3e5613db9fb1fa83f12dcd65703f5742027db832315d49ecae826ea1c54230c5c504b4c605104a61be8c223633bd6c4f0a4f5ab26ca340c7a8a99f53014bdab810af98f74460b9e445f88d66e58415ca3a190e540360b752716ed1a5406a8f9b35ff60ef526bed822b9c5b3c8303b74159cb78019635eeb28c083e4d3befacfeb4be6a46be058f56c5bc8127428ef6a8981ca55c86b098939d15062d079d02bbc2f69eb4288cf78ce896f71933b6cb95a3d34f0f5f6d2e7db63d7fb9ae036b528a5076b88bdbfa8c0596c9f7644772f76a98acafe61d73e194570d6b4997ee40167282d1e75135ab1841c5012620b4e17e5909c98971f7a79b30d6b715159aff043783df9bbb92e23899179530ce707ea2f68827ad4267f0a33fe2328cbe75dcf94a708310b645eefcab19c13f24102a56373cf0dece2d794b233c13d687d8f1a4516ae67f200335c61dc1fb307838531785c7659d91748e262fba86b7e24ba5ac7d5d570570cc4a1a16713e6d60668c30a578fbbd15d7168d98fb09f469f4d955f121201a734a48f869295a36dd584ea45849ec7bccd497fe8f2cadb26ae7f278b69a9445e1c7120b15cc6a63ed726f24c993ebc04626fb3ee5c0d3e893f833afc8a2cb7b30661a8af46962dc0caa69339a1c0ca801a27db2925b99bff8dd083ef3bdf5020f88a4659e16f11036feb4043873cb00d9cc04e4b16c5645e6d144a0a7fcd1087183b98b3b91ae12132208c58ca2d2b7c2a9742d5a66920b7176a69a7bb5a7359a6fd1d0c3b56c79962785ee108279ab85075ed28473765803aee58d458eeb2e32e83ea3417798e7dc615bf98992186c85a9b5c98fe1740a269b72caf02e93f2e8fda955a78a0cddcb8598c334fbca765538404484ab5890df456b2d781a0322b408141ca4a247dabf8e186b2c4e656aa1cead87f1111bbcf44fa30fc6cd97a9d762f9435941ffccaa0d445962fdbb5c4b545df3ffec741fa59445ce1e528bdc8eae1b069e3eecce5f44ecea894c5066c277261cb0de279a31438716e87db61d100467299770a1fc4c908b049111a0148ca6f8a4f35a9c7665e527e51af01f3841bc811d2778ea997ac0f6ca0de8e12bbb392a1c199ea38d4beaa99a5b5c28d868623251cae58a8d247552b7e2d1720ed0e438b64db5a994b0786e944cf305583cf216f9a80a3a7dcaa429b21946eb053573fab1dd06759df7ffccd08eb05a2960c1810d1fdd35157af24e0760977dbb66c136835e1f47d3f8909458c37452a45d4af00b5e7487897007322f2b9a136a8788a6fbcff5c7c0b151f8c0c6ea943ee366151d5705d39d9c313a10e1dacaac5d448b27ff03236ebcdfa1d9f6fbfd8b013d1ab988ed4c321d7df28e9be67c1dd007fb9352835fceaed2c032c0d3c03f86c16d5d5fdfd01967bef17aa4af81d1475adfcb9a7dc3e614b1a34defb2d2579d9b03f482a44ca60667d46c4759d4da675a9290e333e8504864d4462a4e42222850c581fe7b0fd86cd4b4ebc3135dfb1bfd8ef11a937ca7354966bf6942dd2b6295f240a3dac9ce15eee061c7279131841542643296e79570f209fee620b0374cdaa0061d44ba38f9d86086cd99de4b9db77f8335017987ad2a0352565afd5fd5c13c741f6af440b3631f335d1c9c5b900a53e4b3ea51400edafa1d11fed2a32f5707bd8cbbd13094206367b4057b042493ad593d9b0c039f4f4d6ad8fecc309729723f783969d73359379573f60e382e9b6051df23ce7129c7a99ffe3c3a159c6f7d32e789072f35a6348a7b94c89abc10989160b1f16b0ea6c53de3da170a4823a8c9b8cfc849eb38294944cf834f0426ceb6f0fd01ba8472c74978c05d8c11dcba538b39859cd3ab85a5e79f79c046c7eb5482ce85191ab4a1f3cabe4fd02860e8f7869fa534ab26aa14b49c8 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 7103d1a93d9180a3a311b48012904a69893b8660578991d7969e284d6fd639092a96bce12a7cec79f774582814cfb3cc43ee6921d8d312246c5c1de67446f96d7a225316c7c9fed1833a9413d1751e3f047129ec3cbea236b0e69709a155058ca9864c6ee46626bae0b78b6705b6286d0f83af82c0a60bd53b1535cf3d9151f0296d7d98cc112b1c7d3412d399004063c98dea70134b7461787bc12225b8c125578a9850faca8dd69ebb7007aed58308569b0c7a62df964e29ab4b9d544961c1869d79c7f2e09b0480c27221093a031bb4414399189d30f526b96b3308e4 +ciphertext = 2245c22e8d9c7fae6f32e774aae2419a9673c7baa4ce1b3725cc9984cae64f156f19499dd4183bd58a05c5efc031af2630864c9c44626b6f97dbaadc6dbe776c91d9d1431759e1c45d0142d9ae614421834b4acd636f1b8424df246e98b17e9c6b929b9d0b6469e87c66294947aafad71b6e2b89c202dccd721f8e2edef6ce104fcb3bed61ec833eeccbb6f4014f578f49ffc17f105718c6fddb479feb8d33c0e85886e91680cb7d71205589e172b9af88c44f31c2fb38bb2b979a291cc7e2daa7054f160c9ab6f1b0f7027de0b612479bbade9ae3a39057eeee67be9f2b50811292688a3b5620ebb53a82f6ef571dc8d37a3a4a7650221300de3af131b779628efc0444ecdc444b2524f76913ded7435c6a1e500a3382729c01aedc462fe11cb68aa3ccc045f6da85c8c190cc07a92428ad89e593028b578f9dd759660c7c9dce831d53b298d417b097e08425f2f6072ba2380a4914c83d24baa2c30c9fb4c881141d70e1dc7d3d86d52cc053a0552705a61da272c719e5acbca98ab3d919746b590ae23fca0539d0f44b6f7252ae74a333763ce5a31e902e926c766d6fe671fa39d084b2421978f03da6da5f68638de547700cdaff5ab45676b0086d39c5ade71b2c912713def6db65cb6c0aaf77a7ef2da876a358b2383383c6cf73f24a10966c6f163f67a5c618a1402464c9d21f1306e1ff00cdb3f7117234fa75ca148a6cab5c25cc65a6d049edcb0ef1f064ed8591d4484ffe5e966b4114dd493a6664e8e4d21c37d507397ee7974c3df6c549e1342fbf2a040c4b0dd7b92f75bf40aebe5d11649f3f129553a190a044ebb6e6f40b318c28216744b4d585f853ab6dba9373395e5c60d089d0dd65a1d049dabad79122ee72e3b98159d1014e533238bb80bcb0b13676538a7cc423fe63524f8daccbb1710d5485564be90193d8d80afe27c3349eeefb8da9f5ebd5cbb7809da4f8873bf5c912422703bf3373f726e7f4fab0e9a2e3f569038e0d4bf3c24e066ffc8e6c50b9d8c9f6c8824e9966056b7f8087347956dbe84cad9bad09f2a1f060ebe546cb0f33da7507cde055338843b01aba2eac280fa09578227c661b43bafbbd7e5098817e2662c5da21ffc26a87687d10af26aa0e2305838326b8367eaf8188915379d941a937ed4a4c160af5c307dcfc64bc1313b710c11351fc1ef65889e79889d75924aab0d751a28d690b232f26403b94c04d6a59c4a0583f0de08e2a770a3a33f04723cdf358f3addab0f6bba549f6a25060cb9e11c89c9459c737aefe3802b25c2ea628fc065e1037502c4ad77a13a12fe49bbd3413036a41f5b862913052961131d5bccb67ddf3f984edb2776550176e73da79b648ac64b06fde1e819d3a2b16f42149c5a25426a28f88a0a311d837f09e70db81df8880199d1c972a1ab5d722628da9a0047787bb8fc867465052862cc03f40042048a56cf970c524b248528ff9646e9c8608c8b8c0d3fa475b29dc00952928c16f0fb0521ae6396e7fa57596beb65f20ecde47b5b37490fad7451c71d3cf5570c695e3ea8aaf62009474586b0e308d698a7d2184cbb6187c9e2f5a2ef1f8f4e0220db682a176edbe0f2f22bad820974649e9ba27da72a1496b8792867f8007bd37465c30a8082d6a157bbd58a80395342a6cebe8615db46db7e42249d392850aaaf444d3a869c85255531075338d2c05c9103e6f2ac61efa3a991d9d9dfb119207a7816eb28a599a621c7a9d118aa9e0951f950a7f27f9733ee237755719f6861e0eeee48e659a2f9bf4e3ee64becb60d4fb53677f023d54e1f549cfb349c529ea6a2596cf2b453bb6784dd5a40b89083b3f7cb02696fdefb38925c98be3bcd39a2156077e7dcef0b79345f46ae7f22521e8bb3cde13ef2d10837663c873fe61afb2a54658b945caa3cd60dc7fc268db067981212844994dbc0c06a6f5edbd5b4d96973144e0091093782ede816343c844b5ef51420a98521c59d8db122eaabf4fb2fd0da57826983c3b7c8793ddbc6774374dff18338fe4373cce395cb79f140dd1eb2ba0844332b7a04819e5473dba355d68a31e9910517122a9786201a9ff19962c3877eeef46019b166b957cae109adfa2727b40e2a51be095acfad11e754d8275cce5cc166870daeae32e41e34c19d3a505a0badb503d4d604c1c2cd7d2f5d09f5830b715b9ada08614748436b84d3a4a4e9e610e +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 7375b60a855ed33b0dd98209c66cf5b23a0458c4703c0d9ab437304580c301afdfca74fde4c8dd75057d36cbd6963c0b274c44482a081b5b62ab01a4b7a017f23666ebc83a613a7dcc9354021560e37e5a1690f376664bb5543a115a8d36620b202ce9505dbd84b63894c730037e30d208e38c670947c728b81aa5dccf952b4e55179e2f115741b3c20966c4187869a2e5a2487819fa7984ec9909a3b38eac519dc32ab92d2c7a6f5ab2daba08e81cc623c44b44e07a170776e0397ab32391b41c776988074d797535f8138704ace3a7447e9a6da43790e71a0532503ab8e68f22e560228ba534053418c5184d1a9dce616863e0a99c4982479b91836ccf6d7543a3a46d0240b537cc04b72b1aae506b32c7a432ab2cb9733b16c88d40979ab04bc23fd2ae2f57367679003bb077788817c6a034a2f18eec5b09a609762b027482609b49f31446f6ac438c86a05ac12b4c38b1e642c36793ea79a42757762147abd87c731e5288a417921ec0b2a1c478b51c9eb04206f7125d64f444b298b6189348163b0172523c71156d8f2cb9d0786a9500117cf197fa843d0dcb7ed5d10c2de431091cc3a5e76b2387736f4b287404598f391f06b9438129099381635a6b925541b288723f529b6761292f076446a216990905769c60a5547a1566921457c6bc8c426e367c880308471ecb5ad9ec88ba6b07d3613d5766bef75188c9b49b4bec498c029ff2257af42b9ca1236a3b11295fa41b96ab6df3e0af8551c53fdb62f1ec22130bc1d16a1f93053e42b61a9bba4d506c298d4b71d412c648c46df0a9583b87422d16a9fa935798e425c4f894b5a253c3604a2f2407d2636348e3628fc2c2a0f8b2a5801dc153a05f4c3dcae727e03206d4770c6fc94c79205e7d289afae6c81034654cc11361ebb4f0f6c02cba486b56bc1c7310afbb092c55bab98044f8162bad5252cca4a56f4a130f4218352c667022550d7927cd65771169c06e6c1c19040d9173880f407f03872c5c7a07fbf463d10627a85372702529d31908166b80eca5b262b67bc6e99081f9a4bf82416be12796ba +ciphertext = c212481804b3d57097046f05f9fccbdad73d83fe4d1022aa9bf51436418240ebbd41b51e5e2ccc057396452303642d51a22fc8d41d126e80fa2d4dee233eb92ce5a16b30f4eba2cce1fa99a3188deb2809accfdebcdc3867cde483a58477fef8572fbb0349c44ff25f9a9308a14307e1b3ecd9dd111294925ffb36e5a331441b2dbdcb97662ce0d1847cb9a6d1817483329161e485a898cb6619f10ffb8b5095eaae318b969a1bb65d993b95e4b2f775ac755681423bcf68642319a794fbd98e4317ae6c00faf62f129342dc000549c4f3306d732702e978777a95028c712604c42978b4fed2819b07b1e4a3b3b7412705c52fc01a834ce4ac486a24ebc936200097275e819812b6873658264bd52f579784f5fbb71c51f2d11917cc229ca2e6ecab51a61fc636d2f67ba1713ec6abe8f29d3f2d7126887c722998361523b389007fad0e95490563ea6a1b5ee95ce53433c296d24ff40e55abd641a4e46c0b3f53d2d93d223a569e8fdef54bcd67589f5dc6dbf32916ae2cf5bb1eec6a50d4cd1fd4b8895abed52f49f851597f1b70acbb5289fc376fd84dade33c0c2f0db7f7086a8ef6eda4e2bcbf85f347df22487c48788c934691285dee0f065c32d53f23d586245fde64ceb1ce306fee4a179d6a1eecf9b0635710a7d15c5382132900c9ba8d7b113c029bec5cd229a7da6e0cabbe9ad81dc761b1e2d6c7620b6a90b574f8edaa823524787f7c55e0176035c2926233665ef9719d54946917c194acbd0c66ee4ac279a0acc95ba2ca0721815f9a359742d326ee2384af1f8148c89d241ae70dd91d92927bf97aeeac29ab453cd57c51f082b27abe502f26740798c7bb955795328a230d4f648686dd808735ecb8f8e1e0f3a11321d854a773378e1101541c01566a3c26aa230be935dd587cc9fc995e2f42d8fda0bd8b6064c9e40293790b6e6a2fbbe1679092e679928430c197b3e40993bdadb7c1b8f1f4816836f5327c87041e67f9f285463fa7b305a9f7e4d24a10669836cbdbf655f6dc3223c3462a3a10f1fc46e93a5136a4681d49b2de71bc2b6b5eda1b6d502e282d0be744a8170edb157f814a2d073444848c9d6372d779e4872a030c6bf18a26571414d606a05d2193a607861f65a72c84bb6d820f628b942d86819cc34f6ad1ff19c19cfb199b9feb1106a654e6dc086e03f36e9ac0e783c63adf3ede5b1baed0c0a4f1fcfc0479b15fee717b50476c03720b9300ed6bd8fc8616ecea0c92a06a2483099b667b6551c3fd3ff364f287ebfc5e8c2443718db4e49b3156257f2ce203179fa5e2e1c5c58387dd1b4f108546fee4f651dcb08cdda6ba0c2e270d60d8589ab8275f680be857ba5014a1bf05b4446bf089093b01aec3ddc3e5ed2f63768dfb17dfa5188c5ce225ef1c8ecb5104317e56bd1396e80c7c498e9012b1b669b73626cc740a126cc420ee329c153a27ebbe767681427dee6db63632020ff6fcd247605b3b3cc527392bd046aab00e2423b87074543c373706cb12133bcd49a0f02e901b531a80c8ed2cec252bca066fe9052b753cff3b859f623f96d78d3e79a13f7971171cd97707430e19f3b0ba0496c4212e01deb848205c84dd736336863f23b72ee3d0ed59a84963e0f7884f9920dc3256d5f8b0ad9b7632f6db76b6561f9ba504a511c7ec86d2e1fe2f6174a3c9b17c3b7af123a4f802960f71ec7066ffb7589d95384fac59d44f3e9ac52fe6f6341f2ac1db5451c639f4f2b078e77a08b30a948558b21746f553ed3a7f84aeb03ef18c3f28fce57164a8b3271471d88fee0e16bc0aad67c962c1b15eae9cb096680735b9878d283c56cb7a52ef1ec90c53fd89ea976de5d7d64dfb51600f723bcddc61cf5ad545dda909b86fcb5de4427bd611a408e4985c4aff392063075b79a4077f893a71a3179090c2d538549364d92f4d1a91e91b0f483b2f97ac1a7c6e8692dc96bc167073ba885f5188ff1c76fcc50db4892da890e7b7f3286c3a64ae3b211cc018ce49149d9a080aeacdf038c171078d1e8eb90d05364fd8ef9c76d0cfee22d0d491355c208ee36a9213db9f035e27d0a97bb68f2bb2e2053276b18a9f178e4db0d04cb55b646fa96e3c09056e0d0cfac771c4b60a5187a7b4477b4d363e33a9594d0aef97c903245252f58be5f7f1d0e64bd2b988c41057d19b8f9b3d9ff8eb4af77b8bd62f01e46bfff5f25bc9a3 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 28566288a1213b17b879b5018e1020e4a5b690d6077a46b6c34588570606907b5d5dd6b623ca93323c911b1853c0b884f0456d7be2894ac0030098c0beb5a292f99b7b342f42a44da7b05933c910124b33d2c263ab28135d164d67f03afa6588042991e18ab42a0579be2b09281ba21453474ccb605c2968c4254696708eb1503e2238b34078471cd90aa109568ef2c5a7f47f55aaac813c7e9f302b4d4a6034662697028eef3ba1e2d79f9408c3f1602885c21c376ca243643a91539b7e72008ef38d4c5b749973c92529bae34428ade99e8654bb68542af827b0cfe65adcf9c69eab8aa6cc5b436b3ae93b5aed68029c3601ba6697e035babbf71cf96172d6892d3a3950458532f323742235157887a7d536ad25928f625b872f1c6b1c152eeb303758d86521940fdf3145ed2b9c2ee5453c61b2f1d608534032ef3c982b02bbfbfbc182b3b221838050777161559a383c31904374bfacb4e0c0be55e15c700335b6d801c57aa2e2bb8bac4ac105f945eb018b81f953da789762bc438f00216b6066c75411b63560a2d08e8e3677539b4eec172c945889a5232de86ca9a1dc0b2dbcabe391805d485f574860c322717ea43793200fed8684cc0255538c990fc377678b9f22a142e7cb48fa309d76da2589273406dc490fc36163d115ca714dea7777fb76be08c644e8c645b4f74baa987510a888793b6eed8854975081d5ab6e20180ac331487e149f2d4bbea3d68eca045e375c1764c98790dab830d97f3447b928e57f7d4cc5a331c095f44d2f92b48510a3d84bc4d4eb8d7da60d51b15106ec6260c42228ec9211532c8f838fb823a50d0bb57084b52d5ca5a64b7cea314501373286ac4f054519c6c0423bd471fef483f518800e44a70262a163b0bf53d9a5d22b5c9c874974643d7efaaf24858d9d608fe3f902b2747609d29452446c6be521dc75440ada174f62424eb8597ff38bf23a6d4ac7798137aafbbcb7f7a0c162d93efe0419c6dcbb18a99edf54527b2c37c1a10ddd5c4766075c19e7c60c36befce90ce5ec1752fcaaa547be9eda92e897a2b139aeee7454e9d208e97b32a40a65754c540b89777d714228047182811378370843e792d9a441bfc2aef2d219d2255bf26630bc15606af7895ddabb76db0e3e1484d9010b0030caae9728fae74eb9281eb7075162330415f73b4f8512e917c62c28b241367a5c027b1de9b1f54aa140c93c448c587b4a2993b972ae73b4be1ba6b920a73fda3b08f24de173bf43aa744e0c685269956cb4a230c561bab14988ac9dea3668f71c0c6334bc14e9133e190151647e96f4cf3007c11816aa132285f710688bb41874f21baf9739a3c64d0c96aecd0b6985bab40a4717fbe620a9784aa7f62b61e868dd2871127c76709045abac28f32470b4f31b57f87982a75e798a9b1af65333d0484467c3b66645a49cb53f7c91263b9af377197e1ca3e36087d8e695a2b46039940aa82c5d55d08e9de51a370b2a349a5c917500624b11ad1b0c1025511c020d5a449b43f7ce60da9cdd5589a4792496f46976288d313b075083945b0775db0572dec21bfd7a8d3c180e8b30aaaf782e373c740dd22d43a7b1ce32a20761b63c19419526282d8c967b74847ee328b005716927700250a295b9713e20c57ef2088da765fda4997d1a016e308a511897495ab167b119afc8be7ad099c42c27fc17569111b94a2b484ec61d416846e4cb35a1aa77e234cd65c576ba3b8b4371bb55200a26f3561eb36ee1a23cbe3851ffea0f4cda76ac236b659cbb9dc16e13e85aec9859b2fc641ad4bd4d4126b49a9f8d6b14cfbcb8042b88f4352ad0552c9ba26897066708791e5e7968fad433564523379c5bb6a3529799c8fdb4772713955f09d0ab2c729b17b11a466c8de13edae1170d6c427be16777e5b02cec68254958b0d05a3b80898927569b0167ac3855c3cb333ad80f5e785322696af9e70d2a7852a31260f852490643408f3b11d983b6bbca4198bbc88f420e4778828ea8c85bd7a1e7f1b95e4803644aafe4e51a800158ff060cb0fb1a5ac265adcb82c71402b5328508dc3ef951c11e0aad925c1b30c24913103e27a88d03553dec46bb53d278eba8a8da898d91408e16d0801731168259411ccc9b3b0527160a80e392398ea652017bbfdc00a64eb7499444832bc239c95457dbcb83a0f6321e302da9b93aa85b70585ac68ff31f214b1a2e17a72dc139838bc55d75c43a0442e3b703b77c9d4945ae058973e2467abcb035e2c6ce78ab762082bdc5dcaee2549835d274620ab547e8bcffa72876938c07b27a3ee403586c6168db1f6882165a50c619ba80b9687b25b559c13c6bd12775972553e98287fe7b3d20f34edba375979b9ad4155de157760c24027d7a26a9d164de1b6620a48934eb01475938788b331a50b2a04878484bb7546c66bcd2647c1a99cb81902032aa59f8a824904fdb2608e689127325879fa1517e8b6706b462dd635b59d1b88692bc76b07facb2b8b538065c08adec4a7268581c05b36ab8fb122a6614d042202572015337caaab599e4397b75c5af9e1079de101c7cc01b4b5c878eb01aa4d1025cdb7d62f27ead9a29429ba104403b2beaa5fa7b4ae514bef2e16903614e8daaae0c725f8c4c90c870534163b9042a403fe3a861b6268c24b2725c34595bb1d7143a12c470498b26cb2397d0f3bf5daa4ce606c767245312e94745da4f363a1e12d6a1749b48092c50b0604654963955b276753a65d894ca5bda0534741699e6466de1082b483196548c4214ab246341371181fcb948fd8076aa2297d8f85312b442ec3a014930b3bc3083549192bb1320057cbaae073a78d00b5be34129ec1866670db3c1ae2ce1c3aeb1123807af2f433d35dc008bd50b4d6c372ce5357a6aa2c52400b5a846c7ea18c29c081e846d97aa443dd398b6763005803627b1440211372d012c58b040e26c5bf516b1210c9b6543c6684367f2d412ff756b872947e553bf02f2004f105c3f961024631be3006f5dfc8a5e007902d195278cc86a21cbdfb4863b09094257a940c65abd248705b237c8199b6efb52bbfcafd2c01876a9bb515a55339639f7217046ba8700e06d1df524f26379a5505984e18bcea3b728e59060b851ff424c868c1f79f354f852a08d12be9200a666237ad8bcaa38c13970ab3cbea3c1f4530de9c83367b45ceec526832b828c70b446ab74563684c8019e248a845cdca99f921d81369d850b2532829f7c6b5eb0032409629219f778b089c20b3b554e8a6a13995250d7758657a87968a778ca512d49692bb095673572bcc7ad4ddb441bb625b558c086d92a3f36bb24739294004dfac8afe0b199099a5dda8cc340a8418f856836558018963763980fcc7710f851c9b293177da767c99c558664b4ea94778e5529de3399c76c429d4c3976f97310547a6ae4b2c04a9086b3911bf42e4cf244c048aa789b71a4abb0e084cc26f4b2e5d0c3ecf573913306b0659dc59672ef111eb67517a832ba3118554b4935032c9815b9a90235bcbec578c3b3b618ca549c961c6d20201971053afb88d45bad9f6c972cea54071594cf3b15173a3c369612b2a932e5d0a8f2f07575660eafd31494d492e47a73b7a2bc6a2b77dd84ace2ca3c899c8af321163e79662a756db420000fb92bf33405829467a25500d6c77a11609c815548517425c90979fc3c849d842657f207a9520a2e44c85644bc3b266add6370ef818f5e8b6b4373409659322c30af7ed9c66ef7ac76549610a39d5632822b8804454a550e511ac99ca70c285a23e5085b963f9039c2add13681dbb6d4fc473021ca993c596df0b2fa931c8c4c0b2c80a3e71165981bab59b35fc9ab2ec209661c70a796844cbb02a493a63a05d7c2f505875c53203aa3272500b574023407e1cdd40577b5a8c2dc746b20634708b27135e579fcb984ee638971737b9b700e97798176190879126318abbb96142ec1f4268c2464f1ca621e7488fe9571fb8785ac341ed216a52c447fc641adfb736e4d9a2f084682afa38e6b3c6297f989fc5a7919058058b666fa14ad04b00e870c195c82ccfe6626c0d7261aab60165584794aa927e9ae548607dcb44ff5d51b5ec09af395adc98b944fc9128a698a037426c8d7b8bc17c7bb611d7f4acbce586ea1195cf9bb253cc414a45c9dd181cefb37446364007181a79098b9a9600d2a2b141ad9183093ba1aab7315c46f8833668e19b6dca410ebc8b9aada91d435be8cb09698b7a31b617dca35bd8c21592bf396c0743d1b101571c01341250721ca4a6a1903a2f01cf13c625382ada336c19a067c98f53c06234bee3e601f79606124d8cd250a65ea60001039a966e80fec370379d319976920b39012f799686395d7fac12b80862ab04a6cc5c49c664fa140741eeeb6010dc46366bff023894a96e3dd0454b89de274dba12f0e5905d517cc68f553ccfc +ciphertext = 313901fe358e7a8a665ae5c829c1099d01fc3583d00fdb329aae4609e2b2aeca203523f8acfc7ff61f9bf6a57371d32b5ab50a7ec4ac524985bd0834bcbcd9b6b3fc801764eff4226b3c5178bed823b367ed550bc2528a8bdbe092d79af9c453b238317e528043d7c9b3f9f89a4f47e4b87ab454f9fd88f3d83abd184fb2a29bfb61a840aa9256c66a3e5bf72fe3d0e02a589312f1dc4f1a2188b7d7318ac777889f0f56ca298e0056d00d14261870c76fd654973c6fe6f59770b94547fe2ff180cb0d5009ff261fd8ac497363b539f08562d2fd18d38e879dd3a1de0496d4228bb8bad728c5a5689dbf1b41a69e313d65ad6745a580c9d7142e535e1ab5c40782360de454479c64bca00c4c4fc49ddaee4a729da4bb86f3a5b05a5d0ba2648309a26790ba6a8aa2b35757424f7b725a81104bcc86fca74a14b6053f859c1db31eb7234e21f87c247a8881b6cba2ed69b2a239b28fd885227b42dde69c36591eacec276d35e31d638d6741d090a142e6e250582d2b1183e732c899e4d3528fba3a300e3ba8 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 1ee594b2253dc2dcbb6c549cd7d43d606006f344a84ce52f1bb5654227706bccc074e7cddd37093d33c0616472d219975622309fc1a910fba1d7e3c57217663272165500ccae91848ec76748290b0d845cea0321ecd83602bc6db958941bf4bf36a7b335cbb2a4e6901f598c5c729899b741bf9aaebac1cbfac56474a5c9bbb00d3565a2b0f01610963a20c0772f924495d4671cd719ff7499f1b5cb6e3b7dcd2a5c7a40ab6fa2b986662381416220199dce41563a9a73838c08f0b71e9ed6cb2040457f33237295a2b04c6e35596394f519a8f3a6c7e63302a1b991975c5a78091a1b5ab51842d98200be3cc960866479f08ebe4a71a98203258142b8a217d0a00af90c647e4190d4f46c42c6c55e88cb920bbcbcb169a4da05832940dd305d481a277915a744f1b285085ad049ad8d8486ac70b7dd915ed23a8f074a5828e749c08ac126316e528b2ebb293e27e4ce2cb5c9ca45495331c3c0c56861a4c7fc06175eb4b91f1aa17c4cb26be28107a2054d47364656c90b977e3b1c8a74b943bed8178230b832f48d037b3d3812afea9043141c99fd4b11d8f1c8a7a6924222a803eab9381b66dbe3a96aa87771ab2891466d06f3cec3317cc23ba63b546d7dc243c5104222466860c6524081a426d541a365a06003008a24aa5dea69392c0f15d7295cc328c2895b26842809da51629ca43b8b76f4f6b947dcb12d0a33c2b2171c426afbe6cfc6f27cba00a5534c828dd679e6f91b46774575f3afe22b81bdd6cf27f76132a73dafb144160c2f47390fac185040b70417053283d5c7983b8a62d2031292954c12490b73bc41e671b8a55fb60a7b24478431375d113910d0a44e606aab81ba76d36b53425a9494f0908b0c8cc94c2303856b9bf5c94fc35b6f95a8c6ebcf04d00e58ea0e515ca938dbaae84736f39b1797db95f8921a02d3911084c34c5432224163fb748efc580cfcf72717e37bf12385a32b6a98fc1cb6c045248a2363205c5b661bb7909ec39961d5c795606c4e6af0af869065d7f43e0b32b26032a9ea0b9ac73a2985ea6bdfa1809d85572db10918a7b52e5a600da41758cb2fc9f374cb053d647b0d76b7768ea00c742005dc42585c9b6bb3691772f8a626302b5b9773995cb0ee87bfe3fbcf3e112d120b162052b3f0c9c9b986c80a85a2b2f5cda588c24cf7c1d0d4326c43ad583a8b6f9ac8ca40ab92fb6c04f3c0b59bac57374c0b5438f5549d43a9118e72609e2703ef6856bb310be9d5426dc8caa1326e3d9a3d2df797df0b9c25044d1894ba3cd87eb0a56ba0e8b8db325a56439953729ac01b7f2b95487975b70b55a26c54a2ead90702d453972144592377b6fa69e9e99e5a2380a018cc15848fff4b0c4f3ccc42062ee365a085e24e8359b37b41a687789720a3358ed3ca84cc9d45304ed974335305b604735ebea3b9e4450aae540d3de956a700b8d1a52c4df383f2b3a3eb8c935e2aad57db9059161cffb0820f9451b7241381403773a1705eb54fcef246255b5a7f923e06e5a4d6156effd62b3cc81e8200633ac41c1c8aa949a41cf07c18bad01af67c1293748cb38a7ddf184adc69746a46a094c965b40c2ab8141a08f930979a3a81d7422203025d36a42780b75efb88c33c1e115417155a8283737ce7657aefb6681ad984edf9598e747179b10c84a9b8693b4456ba082d40118293446fc19f0bd18880e76011dc2e8fc84623f103703878f1d42c5856546e0aaf37aa2672ec85fa8bcb9e9509517b9391509d6c6a8f48e0377a7494df71a9d140b0622772eccc888925813c5a507cd28580439f95004e4d654acc8c4761c60c847a5e3632c5e2e2b4789c3573663347c4159647740ce4a0bf38abea12cc18c2ca4028118a5a479abc52068a036994a134f20093212d2e21ca6340976ce53056f08d1759aefbc38f79a89f4b5568633956b16018552164af484de5476eacb653b0cba42588cef17acad505920c76cd0af1c17e391f1c29ce909c0e6c523499d0954df22bf92b58ac36212a9995a48384db2926a4194b359b62bab7158b70c1f3640f79719ee8e2bde4a9cc118cae9fc287b384b29ec6320305bc20a5a6076c5c768157307281e1425902112df2e50e2571270c70a66251611899261e497d1700c99c909154a414a0b6b1107056fe986a44b37f173b1ffe8a1888f207ac5bc962e727cac7cf241c9dd6ac758c898457c061ead3053c132e78c2005be7ceb716a4192577c3fa916845b139d3912ee47467256d8494a9fefcb4a5a23323c4533e9c0f83115c608096b76b29f70167778803339c423db89040e66bcec0aed9765b3b950d1f6c1098ec81eb7050b8101ab95bae34f3c9d6f02daf112b4a60caa25160870161d62a0d39a9bd7a13605268877405288f882836938d5af348b700c14f36a533ec2ae08952ae036770e24839b51cad4a02130c7a7e4b9912c5695f2811ad18154ab58951b32c657136999956b05884efe7a942390ea394a9c466843ab6cd93e4972d742258423ca06a7a3351b974b24e8f9123e425b3eca6bc28d430dc61c6847501391b879fcaa1f182731731c52227a4e9899f1e98a905d17c20aa21e4f91f9fb2093f194607d7641a5990c892add06091e864324419c6a3992f6841a483e44e33525d94106e24db7df7a7526b06b7e8201ec8136a920598fe3134a682cec9396ee873c3c3448d52e3c2b29052f90232da14c20bbc7c93f1992fd08b644712493a0ab3252a18b682475c63f9216f1d001ae06b72ecf23fac8134645a4974678ffa043919b16dd65a2674c52ff28ccc4d69b065396d3a3cc013dc56211294c6f6cffca6cf9cc57d570556610c4a02a99bccc2b37ea99120c97e05547d159c160ff11dabeab57681c5270691167ac530514e10b846330bce5ba88639d558b098c4d4213036030ff8a48645803481305adc9367bb81c0abe28899a1c7c72803cd5b9efb591ff88aae01962ea3eca9e3743367103445b6b91587caca4c2d60654285476e90d3a1682c084651c56ff37c05fa9eed0787dbc4c79ce2509ba4a8b09b2d8978cd75a24dd15018d4aa085839633bd23b4c77b202e99c2b20068719a27d898c34f70bcf4c536966cc8d48349dabbbffe83784db2772bb8c1b105c9dd11f1e3547441830b9720439e04311997d686c771d33bd27b6a8863124a6758529f98297d88e165573983b33af141ceeeab1f72c636bd3a6791149b8da3bae3b4791438dd46673a1d25f42a88511557b3a5b752545853eb77c6137b44444baaaca1b671c0c1364b21735507f4882bf18cdd698b9dad2799e53c066dc0866a1b1bd774ced00016999889e419f70a63fb59b27e22cab1a232ab2a682537a9c22327bd71a0242bc3f39261a7cf45701daa44b969e1b0cc1316725e274ca224cb8d135675df767344b832bc959d8d2652decc891da8243805edb1b4ef2d0134228251b01793243276eb80fde708c101683f6105024800d14b78385395dc3b0c14b9c048f437db7b6ce07e3c9ac90bdde2bc8c2420bab840d73a5cd3e59bb0b6b6a1da638a2501328b3104f774fd1031e614a1cd6f2605f8956af5ac6a602a239e6ce43f8a8b1a51b0ea02a92067e5e54107549cd822349ad213d69c51f5fe8bffe664f78e4979bab9f053927793aba87259dfd1c480f981e5b53c676cc169a223c54477fa6869bcf8013249507c5e3ade4406b42cb66df42a1dce65921d50f7490846e026bba4c44a27c68f605b18313302218a6257b5bfa1645ee40ca3d408b40521f59cc9a93eab45fa0aa02345ab030c625fbab68a56ceda56d4a21889cf212eedaba5f968d161c5d6cf45662006141a777425c025feb8ac403b494d97513b44f1a84ba52e754ead356a74c04e5b6b7c85c6794518d2967070480a92ee9914bac702ca5547bf989730489b205cdbafa833b4a5826e3805d9535b2748846505b09e91adf17a900d663c4c967cdf80259e7bbdcecafb8201a47fc26d0454d9ae46bc4bac74f1537f7447267b5cbf76b2eda33bc50e70aec88a15ab9a5686b802403a1e031cca7aabd694378ea203ab8bb2a54d4c16b34a030632f83451dbe2838c216ac41531862fc75ef8cc1e3079154651832979179b31b6dc320f65a5726d9a1bc8a0ab3795a93090820cb679d9068d5652b97e7a76b704aee6145b3a09b113c5fbda1aa5d981d214b57d1d090ea6295d47262a63a5a35c398a8b780d3889ceb90ba868b77a8611afa65974b403ba89a8ddfa632a96a8fca2a81c6886df689541b341230d1c3e3fb9c6f30b5a8b97d40e02cf05450671935ed902dd8044f1e03a4222b646339706ef928d5109c8c6dc983f64fe85a928a88b40e89f70b5701041f528f3b143267ee693417f87d5ca8b3bae8128875880492c5fc7d681e9f4f7731cd511b860dae222ca1da14ab158909f042e07c6c5e97efe3d1400ad36df29c2476901db09b00b25d4540d6b8 +ciphertext = 606a16b19d435ca9ebde1f895ff83171666e3703e47107bd499daa80d5d57f278d7bceeeafd2078109729bd5aa4d264b036e14eee48c57ac861d5c23f21894afac6d42358f23e141e71d3503944de52abe90bfb678e0df3b4808d8 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 76200e9d1c1a7a114ae40c6291342c87f21fe6a1b499c75d155275dd87752e144110c58b7db8b9f8f19af45cc2e71729157cca0f3b513e423b6c72319361b9300c2487993f333a0cef4854ad0b3ba0e7246dd1424c6c374ae1190d95ac01513ef0329a2a8ab64d453fb651a8808c5cad2a8d6acb6a0785516daa2044202c224b603817cf13d7c6679289481b9733089a45ac5c7a749936ac1932bbc8824a2293a27eca4214a6bbb0187ac37cf108f219493e5107c91441ffd37b2a99a5061886e3c1c0699523db8a1938c338bf68a7148b698af9c72bb7a73db02040530dc4c4717af8a58f336ad4b5735932180ff2aaaaa207be17bdd8373acefc65a924aec860aba61604459297bc673806e3848f4b712d3793874793ea5c91ba5b95584a32218a14eb350e12e6c3bc07cbc31732e68999e9987d1d538559c276ef96afa5234fb14386d93075e175100d19489a472e7a0a76c8a672929ab696b81afcaa270f6b6ecbe886c6819e532868960156cd796be9bba540978cbfc73678b7b50484c3e8b0971e360569f15e52a77598d28b271a3645b82afa274824ec60d65ba8ff510bd84c763c710d51b10d18d500c7c3c66c52bc6df416a4d9b4478230d4bb6c1a4c77e4db16b2c706a6a62cde20b6d6c0522d62460aa05504463eae06437671708563b67292c12679c049cc27969c30bbd9b4d59b1fcff6b34d227f21c7b9d5286bcf231d4f9ba922372fa8f61970520031cc1c6dc20bf5c033035524042a71009ba8f0017c84c75467f157f565011f1783f0a46e770041846a5e89ec160e8c2751d63fac2aa9790817199cbe3fdaadc9500d8c998c7895b76053bd73a9430b9520023b736070b6c41705dea129f6005018d885d15a2b6530518177392262bc4c122bc126ad2a2955ba6b7666339a5a347f63997324a5cc9272532e20b71c9249df1231f0968b85345695d5730be170ee8033eef8047a1c9c0eb727c61ac78607931880aaff233e769357f9911588649cb0e4869558b8ec0b5d41962df8b65bead74633364d0f9126e26602c03b40911b2345e21dffe12d55039ea85c558b5a9cc67401c8859c806c0fb1c3a7386b7395f525b9032d9b71bd5e37239f02c649540e291786b8b1578bb01706a68dbb882bd8215643768d9035c03e6c4c3b789dad5269ca92466424368f3a0bd3804631221d5ba5502e386470f3ab3be97e2c0bce94a5217931315d624b6ca12a70d8b14e0886a05153ac951a333b51e030b9d3db3758db33b191b75898af181ccb18c7125287b4ea577208d12d5c7b6b7cf8a5f881afa5a176dde11226a7b8ff2a2dfb7b4916fc1cd97a96a0f89dccd44b10231a4c5c0167235bb213667b6443ed9660ca403812fa8ce170742582c398fc3dbf0a86b3c338af26222a30570052b6d6641185130ffada16dda0982ef888c21746a988c76afb65308c1fd49b5f5bab66511617f25c937c666cb3570a6abca827d0c5fd9b062c664a84d40ae336964ea76a3763784e789c5b539e822ba8ba24ad0d8a823a4794fd417c0ff58cf13ac22236387948a71bc0afd7353a53299bb2cb000b849988e25403e4aa39d2a9731a7c5238b7a17b4cea40537b82c3206aa5cfa5395e41b7610cc00381c08c0169514a0d4071a8efb084ad949f095c6665d78ff32307c286033b644b32da1a972b795a058955232155c33837403ea32b334e405c80abb374315af709a10d654649e121b069369f0a400c38be8175160f22c8a30a5096142939b9ce5e1074a9ba076eda72b582a9ce780a0934b6ae313503d42969e090331305ee11b799119b46466053ea176785a1d2a3ab9b95c164d39426e065d172b562f89f72b30eae18c4dd6674c6653faa46759d65a1fb7b26108b441c2402d91209d353743bb1a673d941a2bc25d36c21a690bde804c4aa8852ff710bf8e7810f6245aaf22a09a08713913f0e378cbff635fe949fc95a60b6e13728a60315a018bd82866b047ce7d5623c49987b1369d03616de153d0d6a893c2bb0b711667d6a111cbb711de084123abcf4aac3b8ab5cb7d07ed7d71f9ca8129b5a728ca3a4b6f362575a6ca599002670caa051b560d66e345802b4172cd4db752a646e3152825cc55f5cb786d4385fd31b3b90526716e23ec8902d457754de73a32b635c6f6b47ac1126f297b79497726a5a712a3a5d5ebbcd41a059bce05b7f03831b9b5f3b4a4bcae1ad8907681d97631901030de88190e2720d259a9157951ac04ff75c319be927be234c456865d8908ebe04ba3aa77f5a353b11a31840c4cf0ec41cc57899d9a326b6c96dbb03752ff17db26c4d6ba0673952343ad7988cec145bc8bf2b1bc3a19204614ccb829575b374aabeea35f19411965c9c1fd235f09c0603c0343c36ae940a38f1fc677d5aba3c614836db1603ea7cf87a6f5d320c3cf531cfab9fd99a1a089a7a273a2ce49169c7d991d1da88e3d46346cc1c5f3b91be331ad76834d719a71e2a02aba40211389245a838189562c6cbb6bd2248ad766c8817423a092f231c659ef25967ab8b31a87263ac43098ab785f222f2944107231f3a3b3cd795375945237f766c9895b002455be6ba23f52321ca20985a9ca5aca515da61a0effc769028525c9092bc387fc4696fb26bae6da31b9a86cebdd91b8be41344f1a8bb1246f3f1a13ea906c8d121ed3c1014b9a94892b60fc721e2c31fb6c1275278b86cfa6b324b50402ba2cbeb3ea9a1184740417723474c46b2a944628801b800f864ff8bc1623699ed19960c0287b6421130a9a0f991c343f5bf99517d88071c0c97be62b18383c04fd9739422808cab9209d03754b82467f6ea08cb03b540481622c33c74e4563eb30305bc65ca5cc1e5957ee007a5cbd05d34233fd4ab5dfc060fb1f79f7f936c3124440464c47f524942ecba0d3b50da15906e52834cf406c4b700d8fca11e06112785407db2173ff192dbd68f65510ab74a9f4ee239c1a1cdcf63542dec031078cbc79580a047737d966989f30c824aa9c227484a703d27044a42d2badb8150a018bc277a8e40c60945e7636ea5cc99ec6cbee885c066988d464efc7b46846648a2bb839ff9ca04189474e62635fa687851302c237b3980add1f67b834ba30dd70823b27df140b2201372c9ec6dd9d2bfdb7cba06f93083a80c14a87f93cb30bc462ee56ba8a13b0ff097925441ce4c80a3f16871a7ca0f916306c90374e1d45c30d57dbe1b63e0512e0015abbf1847e1c68cd0c401a8871501150d9b135204e55cba0692b335308e34364bd6abb2365826e77b8a827112058e12aa2795bc527da623f6932a359ab28e65b31e1864b3a46c95d2933ef4a68ea6a2cb6a74b386018c43c4e55a84d3d6c36b53271182a13da13d372ca0cd994d3e66c9f3062a891231408237f25b4d4e42adb0924df83a22282a2c119c3619c91ec14905d225140d55b15eecc748f28ae274c300073de0a8c10f2a60c4d792216b91a407a863eb930cd954afc58537e68a99561a42eccd33f711a314a10bc03a4e20adf1e656bf92cb819b5086e42096a7130640a4e5f664f5f352aba4c4d8e26420d9b3405599f0a19647191b96307836c559a9679bb731b920ec7fb8c415595459bb171906e202158c6293098a3b916bd80b0dbaec5f29529f1923c16a090f78059d2a884ab4766d57547125381022f1cd83a8b5deba95ca1b997f60b4f8f2c1255867d748bcfdd5ba635c8f286863765273a5ac25f2b58a6e517a774960e17425bd887f49c532941363587529f3d714cf76c7a8e9b99f00a9f2014d2f1c865cb78c692c8d9ae9b7a2d85e8bd0bf456b57ba26ca97238a444002a1552f61c6951713234a653915e33a8d95c01c934312094a32f9783bcb00cf959e8c226e8bb3c4bdc735f2b34f9b5a0feef0c0b3e6939a532555b2cb6d07be7eaa15c795b9e683b0da0818a3515c9fc163c23411b521b2b3cc3852e20647f43471b568d31b2840f7571420ce28c07d0c70532b3a8eb12095bb680a95d99fcc8437dd32cfc45a60ff9a757ec810c65c68e3485087295b36d875ea4a87fcac50343b903d73b391023f921075897341cd5c6e787885b504ac8b6290032966c31171e2f883b6c56312cb19d30b5d918478033040f8d023e9f950c76439dc2c075a45502820b7787905991bc8b2c839ef8580895ca9f3a54380f1596b82576eac2551326612b07139181fd8fc27f1c44a79619f108a48fec9319988b0af172a2473480f196686351979399431e382e86a59a8a9a261e7385adc359e828003fa5122a22ad2ec9ec923748b991202c56c451410e9380547eb15221b340a2834472b4f4aba614d49485a95f781d9d3e2930b810f4cffb99278735bb377c7dc389725431c66be54385dcc6df39c3a09cd3bc0a596bdca0038b3ee577a4db0704f1ef52cf582c0556ea7067e0fff7e3ce04ba9af9c9f1d6fe561eab828f8ebd1227ded55 +ciphertext = 76bf5280ddf2e0ed64032da43f8de41a3ab664ba66922bbbdd4c18 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = c9d71792ea79155b13bdf78fe8d9b648115d901700a135a814f7329986af317a30b5f95707719c61cc46e5b69dbcc35e0a7a96add87a73f686c9ac1788db1ff27b4c558a7007870c76c067d0108625fa81ba12171a497bc1d2cce97999bdc89ae8496d0fc497ec3a4b58cb8210d17e4c26bafd86869801243175049b616579db41f3f64fc378604be6cdfe937ba0e3a23828887b06876a451e6734bf472859ae611af2f687a7b55dcc06472e1748cf97438986b0e3dc0f97f788737b7067cb2392d24afdf87d622875905b2d64d2bf99eb270af48125f028c35414432a79382483aee02cc2175ab28a877af2546b63bec860a6ac0105d796770726883648b2544c393ffa3fc1849703330b66559faf458990b2af9aaa961423b533040400a5ab6ecb50b3880ce77bb42d057acf8765f29019e0b49c57e792c8ea93922a634b1867d34cc781903218a726a22c5834624d6a45c0879c62ce17aa176b44e514a7d7b40e8083154519a1e74334e6a23a1b8500417599365b696db80a58977cfdcb0de226370c5851dd4962fe9b8a206b48f80ca89c74209bc017ba4427fd669db266a699e985ec57353b1b71573796200372bd154b36058257f955e8f009bb75c96d8199e6bc31cb82192f7b98db806e1bf5a6cc881f86c59f183216d69c43a14727ee85a4b6ea364d5b8d2d1b7aef872a32ccbe71698e021b83c06c1bab775cd3014d43587f0f61b35ea8ac479baf28423ccea91d0d5b8fa60634666440c9e3755cfc953f022e83473035d8af84f156ef8a8ae8787a48bb689e95b15ba78eeb571c2a81b74385a4ccbc24ddfa4d4a0320bafa44cc98994d48640dba6b0dcba7c62cca117c20079bbe8c1368f580b307f07d1ed39adda198d763199cc30fa1a47e6be6c004b7788a0cc1df1647f39b71827332d9c12becab7626e54ec2c0219d4c7df3937910e621631c9164c87536084cb5c46b58224eb2055150f98e07fab448dbab8440944084c047f09baa432edda77e6a0b43312923065481ccf167411924c409a0844c4b258bb7471a18b43a77a927a39e577f5ea86ad1f399da0a4336c165b32475aac3b1f3f381a3d611940b5a955336865409295396f3179c9188963ca019ddc58556cb5d274640b9f13528f2627748278b63aae89ba35473ce86c27c11f98bdd229dae9c7f7fb97036b5993ab3572f42beb85a0f11f1c3bbc5bd3ad96a44e525f46140ddc09c4112791a9559fe1c4247eb7d0617a798abb0c78c46399c04594b7e68978f12ab1a79f757c9887784d43d0d999850f54dafe79738c4346df2ac30b9036374273abb24bc848509a77a17d6a9ffa87211601157c6b9f3f185e145b47bb9877f18b2d71875bab94dad39bd651331bfca0f37b452c9477e8070760119125fc24b9e325e81da8d0d497bd5aa2f963129a4342bd3ba0500a485a0012578533b5256687a033b1124326db41ed545b25b395e640a8be63cbfd6f90ff3f470d1f6425ea9a85e9456b265270c7c703ee45f147533e9f0ae66f22942b980de4997403627a721cb19a65e3f649167248c788b037af2c3b9808bccd419969815a4a1b97a611e70f7cf7dd8952a087e862384f9953d9fa40b92fcb7a8c075d8b368704b79f7e13f21e9bdee75a839a9550fda5dd154902ea837d5b12ab86a1087d4442591203b937f4c001f8460cc6af636989570e7a11b03459eb8485844f54901869768c402a8da87daca48865985be966901f952973187faf7199d4ba41925553c0a7e154bad670176f7c33bccc3a0b99002572c019bbca0f33b38146830a8e64094794a1c106b39847464c37315b6ae764b43842c1cd1200d7a07381c856d71612b0a28c02b1626540195ac442f849b6ebad54cc0e2ca2f31289a1354b0e7680e13a6a536429ff401ec570aae0589bf7a4501542f3a2123934c99d7d37d1d722cbdab2b6942cb38941efe4b2881629bc69c3bd5018474ba415a404dfdc82aeb8b567b017f54212876017256812c58474161c96af76c5f003d9ed28c3cf88aaef7e52853086012325cf43b12a0ab1ff934a204a651a7d51ef45705dd24863e1c9984aac623e0bd9595c090d6ccf2db128e4c52cef078e4d23b94ca268b9c7a92705a99dc009f421c4b20a05292ae065c49b3d94fa7247bb6aca966e40b6a5c8a0c575982e78b01ec89c54933e1d4ab9d34242494ca69d6a58bbc657de19b914a95c9d579574534d755a3615674b4a4439a9c50e044864566680df70dc5b831bcab63d829c0fb171f0da029be1608d1335f3579a61c85be1f847a848b1902d6645b47211ee22d35b6592e0959264b2482d661cde564841a51dbf599a4b87687c05f38b4affdc777824c1d9ed7a979e087c1510272a64ef1765bd7d07ef670b95cdab42d61435fc12b5149ac425abe3a087e2b4b23c2c08f015cadd97cbdc12b23d232aa1387bc6500132076c39bb95fa90975b387594086ca21eb517437ca78861008372f839c78d4d226d3abac08aa316c7cbdbac1154c9c12973a72d70252c6f44b3783546a82b2ee34144d9baf4558b6f32a0d3397506df631bd5746f3b798e645353e27528405982050a622e603bf677057c06302d913329c0767513870f991976575feb78278b8c95f10aea140107ce0af24154f171c4bb36a9decd322b4322a1299471d409adcab56f66b6f8528ba353089181c595c6b4b82060812cc4a1fa3149ec183126206b15b1bbb84257341018e9444f5425b2d7baf317b4b546b098419a39bfb8827474fee612954d61cc11107322725a9a03fb2c5cec514605407c6a445b0c2150a59359550e39e83d2c946680fcaf305c07215de6aa56d419f1869c28c652ffb2ac3bca0791766018167513f0b2ed6f159a885248c40aa8b5a74ec305c27045e58d871e407a16a48c198437e8b68a90ea42a0e990c7682004a2b778c349de42c6ed543c8479506b770c1da1c09d5a3a1eeb71d62d1b3cc446fb13a92611310faf2a729dba76d3b2c315b6350b9b140b54615c392b8512cabd27241341e366a29c4416350c0b874865053a193a8f7c634e373c0f3b4c04920b30614aed4c489a92531f574926a58fbec43b8d4a1c35cc89e150c96b7c1e7822a8dd80ab592535ef60c2790575ae2cf87d32b1a9871ce5336d162965bd7af83816cb1e18aa77c7b2d37138d4708185c5fc841694ae75cb50a5ee07206b7886df1828d310c0e8a836ca8e48502ac0feafb816d7b9bd1792615b43e2359b948626033d5633b64645c0cb08e60a63d855289c1b6b51b74409055cab969322902f8308016bc2844d80f0316ce9528adf6da6851674a629c92278811bdb497a0308c598c8834868345647c33ab5070414ea0399c5928159b89004cc7b1e6bb1265341559481eae703dd634085f864781c50c44015a4c7996800a02ce5967b73146b599cf2e589f1cd8843884981ea60fccd4cfb4f57b9acb8683ea268640710aac9e284748c77bbf037a56bd299d7a43a581d13e6cdc7cd2661d74f0bbda51186371b09a2049b28ac89e39c9f76cbf112538a7384f36805edf118bcf9647f177c98621b17389c4d7823cb3736f2977bfc0d2c42e33725bf015dbd0bce4d2418e1a4763e6449df9b287c0aa9aba00f61a49433a295ea3358b017138eb37fcc622c134c016237d7f76cc450a21e0462d1ae97265e78f3a005c425a344b6797982b229659b0dd26487048c65a57b584688b3a50a1c6035143b52122973a30339c01a64a791cc5f789c36a8b45547888d80b84cd2c11b50457abe879ceb49aaec7bdc7629e391b1bdf3447ffe54801278da48075daeabaa7749a080479e520aad0e42ba5e65eba029185d92dc4f78125d1087d90a92fb59e97a3986746a08efa1ce75359d05a5be633270041389777658270be76587f4e366474f7c32e416239d64d1fac12bde047a4cb3954a8c2d67c907514b406253a15688adbf997062597793ba82343c637984320d82427f41812ea426f013d26084411dcad5cdb1b9e4b864ad822b3531a06f1338aa21acc4784217a647d065925c86a2d417149bb35c914a202c0cab596396f63b5842b286856b8f9e655c13035f1d10b82bcb3ef030e51c76b12804e1cd44df1706bee8850c141312e1abe34365a9ba8c26d024931c921fc712210b453bd56a0dbc5a186b5548cb51a09a39bf2d4459efb12074a3c68b4a575b74652d8a42d3611a60c0fd5c4ab496b2f62cc38d2cc518927bfe723855e0c88db864f25838dcd5c1bcd9ab0d765257f193e274a90d3440592c98739ec4595ccaacb969b66157e1a9b5c8ac020d896c693dc589a5b1900132236a8966f1a643d82fa401c394483d0345ffdda594a643c688b920b18444c066eaf8a2eb5a7f3187b58e8bf721637b759a5393929090597c421268ed783e3c186d61f866252f34450d6bb83006b2c9f8df1358c20f9ff0b576b6fab3f5eeb729f9061b42c85ed +ciphertext = b197b8bcd27fa8ba7d73bc18c11d7ff37fc3b04259f26ec1bb980851a750b94fddcdcd323fe7e319a5dcbf8da6d320636abbc6d8a48d861d0525d5e9d0b583f92df521b5f5e717d43f99f10f56 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = cb7703a834556826aad52b1d05164e558839a261c6f72a8a7de66aeab085a7e3921ab8250e01c60f14120b52cca2914396fc62d6489b4189a7512c172d29b139e2273275379a650aa539b69ee4038e93aba1e71f2fb9493fa23c380c57d27220a652921fe376895735cd1459494b8c5d21883718b88da849c8d020fa47774411a85347c754131757f810a30276eea5b3eaa0706f67c0ad8b8b5d9c1b76f737e5f601e2c6346921b5b79330b0c264269c7337b96cf0352a41929e5e3b139b0960cbf675ad64a1963149e3a344cbd81dde73758007b1b132ca150b5a32f110db66a5dc66a7f4771c8bf69476642e62c4ce9c27c699ac35b9ab3f57d5c3af4c631fc7aca709020814af92660c6e4cc96915963509b9656a195a8229d0a45d59f5826f397c5025a8676a008951ad43ac7c4918a40088639a971035e3930c817af73ab455fc912811a4e60887168b5b8885c7709424c4eb8474569746645f9224cb47f6a5c1023eb820017485acb9c191e0069758e05b8e279e50402d6ff52c96236f28e9b2911b8941f171cefaafc2a20b69269e231965aaba4719747d063a34acc4611546b6afa09bbda45e698b81a72935764843364364f2123b85e8c41cca2d2c51796607481cd418f300841445b1d736a321dbc2590914333286fd0685a0868621885546d44c263c1bd1d61a81434e8da49d877c56ad22b53fb4cf259b151c748069dba7388b6e8c21c5f3c045b2162da1ebb646464e76530200100138637434b99f36e7b931e85de0519195a1663fa1529a64a8b792cc753142450a48eb657d97da2ca55029e0599543ab45ed48c621559647225895ca22238acb83c732a46b26047015b9288afd436a07337be6047d1a18755d81370a01bc1ea40f4b477d2ea4777cd791af9b8d97a49c615514cb63382b40af90998b9fb89b7ecc70c87a3c232b52d40a60a868c14fc231c224583848167b76cd29b80d01f36aa63caaaf4b141191cf23b42a17f3216ec336c6942e70d7490fd766a9c77e16a341c5d2486bd2af6641066cd5c8c35176d94443171484aed71ef986565c200d3ab17f4e482323809181319d1ef1376f8b1209c8283fa22dcbdca626f88af12392cd375eb723366278157c616c148068e55b49f7c014cb59c16bb601ac3a8cba129098f025f1b785585a00036013edb4a540f6189c6ab950f98b1f001bd20537d65b2a00e70054a83479f37b5cc3afb552aa2ffa322ad03796a62975b22a8be32a60999892c5a9e998588db7bb72f21e0742678260cfe71c8cf3467803e0b2f6a596d20a2a8b11c526fb7b3b994556664876b56a0a498b62b3265c994bc64ac5e3700071bb1acbcb368ca518291735393235ae6b85a9437e9898aa0d74a76b0753bc2a3908826cd62b143636456145586b43870ca31f57b884c6eaac9cc99975277affbc2b09237e4ec91aec73991ccc54480c101b1b09e09c7254735e1826129326b35cb2cf34636548394be67cb51530a8faf75fd34bca2eac9dd1fa44a54595d917a4a050cf33048e3d26698e4c0716eacd7499098b25a15c592d24fc7dfa896d8e4b18c1290f117160fc7029bea1169436b378c2195f194ee9689a044a8397dc6f5df400b07512577253cc339699e206b1678a4b97321abc7f3da1c115d83f8c3359e2f88522974f834a7575e60301a7b654669e6cb814b526827b236475029e13c449e6b540a9c4180dd603a9b2b26022602760211e85891086c204e88ae4da7dce69a8ba2a2fbe7241a560305e63abdb90b3881653ce7a181d22079a733144c529d1137ef410136267bd248cc27093ab09205b8620aaf7ab400eb210b023c4359922123568c122279496c167f241d1d7ab9ad2a975cc808a22c1002650bdf891e5277bb9f54add427fed052c86fbcdcb36c1bc9cacdb98832b1758db334ab16c21e534b46f294056403d9955a1a391584be412eb6c0e6b43b3a95108cc42c936a11f0e3b484683c802149190798a9b8303781ab928dc5653b288d5d441d541458ef51b765b24644cc167995c35b21c3708569e859d2d16979a245719d22806e0be7c58218130baa25b2f5513c049072c9242a36bf9a8f289acd1156d81167eb0294eb3b447585abcb78712dad79a86d23ecae66f14807a0faacf7290c6b5d6ab6b3a5b8c9c5c9eab50e36c393789a626d435da205f4a571f59131396022eef894316d8643423b17d3624b21c5b21a34080016f773c879e9808e9f99945acc8bad97ac6289765da262bc83d48092908251d3d453ffc85bc006c19d88806a552a340707585c8b6df505df8642669da1f35226c09561f0b1c79aac90aa875a2f7e6134567cd21a6475ecb6ba9ec64ddb3200869cd79c4cd7c704db01b0b62a86d17317facc2c105f8213108640445052d32560a25319b515c45f81f502a87c3ea6252634d67d4497ccb63a9e5a89059745d86198b8768413814bff16660230377c50e9610816e38832cb8868d999d7d873d28e1b6b8555b85eb132de1c0bd587089330846d0555d52896641532e7c78f7b53f04d4057ca25664ecc664e7c5d2e802a3fbc9cc54ca2c625aded9ab3ec5b31c9527f4eb39e6856eddf94e9b0655eea224393287b67a3fad940ee215afc945b97fb9813f975c41976ea405b4c0b696e87b43afc80b1d7b11b409930f6924de38ba94f07358aa8949d46a97d22fad567ca7c49e4a9020ee59b5259c589d7455edd943e378321c97a86bfc8fdcc19164ca792aa80d281a5ff1d4b6a14a261a16c4b6379c45c28bb1b147d4485f581704cdf33ddfd5ce88c0c8ca593aa37155e6cc8b20e921f6ba0af0a591d3e88162f2203b2707005308b4630b906219700609c5cb1d6788a6ff4a12f48c95d7e9387854b22895af367b9590773cdc4cb93e810a4efab15579900d846c149abba5123d1a4858cc2a8c54e126ab80c892466821c022feaacc0cfa57f6883fb348c5900777e17681e1f67863e755bc55bb5bf71218b092867580ee143ff8b1b4d55916b471472d73044957616d781b343c41e61a958e6ba28aa88fe6db0ba131ae3502414f6a511723580c8a515a553b975490663a995962a1865333a3882ef6da7f6fc6bf67369af568bf6f0722b6d19566996c1ce43197a435e3b3927f1aaba955ace993b0c9e119f5d2c0e80c5c64a33bdf3a5aaf2c51fcd5758aa66061eb021e35b3ec384d3726b6a1d247318201db7412773a21a85668861384e5d63caef902b24280b4c58a53a961971845e08c1c1dec28c0d07baf5b386789569bb8283034291fd08ee1e85c1ed2ac52dc64a1c8067b1873d5c5099ff951283423f0056dede47936f9549722b84a8a8be0c4407a58345abc8cf854287f58269169127ea12878d00cf0815bc8a103dcd97cf89605cdc91217dc779df6cd8c44bd52469ae2634eed9bcb200b1734d9bc9feb25b76c066d180412798c2907a6cad8a7e28b4a687ac5801c5093f82b3200ba0d882920739d7e105e8979156ec4c97d64876805cdea505985e78d768670a63abdfe1c9f6bd1cb36c90247952b66d63bbe711f933781fb5363b0c72e5075af61cc9fa5ec089446a380b503ff41b7000931062522404b4e414c679dc75265829a687c1bb0391203b3c501f67d96da80dea50cd938b039e1722eac5f64640d3448a533b07132e29ccb723774322b3c700795a45ff35a000c166b6ae663cec00146152c197a3e806647d41017adcb0b3d07b106e191b17ab5629734d6264f67eb2dbe564155e30bd5a55fe8152bbb96210c312678acbe5f98be7036c8a4379d27b7c1f29912494041b0bbc71e361f09fa29af73005f620af78b46f7f7268a3129cfbc7cbd614259b937890bcbe3aa82bef5b663cc36130c01e12c6a4a0022d760acf37833ecb7260c5c35b4487328b51cfd9169ecc95b12a44d40a6a609988f67047d5b74917b085468f2bd99da21478a1b5624cb6138cdd270ab3d216c8645959ca05cbd5a93c9027546693a11bb1aa7e8472aa33ddda97bbcba8dceec90cf971c58cba20f56785843c5749cbe9047baac7351313bcc14163d62dbb092a84ebc6cb30996c24d56cb06997fd9a2a36f22c668a75fbb419bab176e4317431f351c8a66b48a3263eb91c8d7d569771cb6d0d91829a0cfede381bee01be6a44caa03ae195619b9b28836512655a527ea120f1d47ce4af80fa4f4b98850983a9cc5fe3231f4c51e8bd8c488254c188000dcb98e5e19464786954b5a0afb7659d561c408432f70e85a29ab13e66a81fea3387eb259b5a66c50d11564203ec8981f814c662a21c4a6ab63d3a017dcca23843b2f34167438106fcabc8ae12748c1e02e94417f9c95209e6b03ea6300b9eb924eaae6d03126d1b330fde6fdc174dee2749fd6cb98325e00f18fd060a34d4b45fb559351ca18594f27f6ca99597b2bed12b9b57202dc7616a14eb242d580135f1166d7bd00d152f6bcb38ce0b0d8 +ciphertext = d378b7eca8bbb011d248d51395d424c2098ad773b8a42d0a7495b01535745f55fc76a77a0ae935f79e2235d52c6fe0d55bf8f4de47a7d101a2a234711060b7fea3ce693085cfd02602b5815f496f06910448a0a44894b31b881a9b1514215f12e5a0d86aed50021538bd6cee533ed0f6bacf0e7ce4416fb6f0b4a82c09a6f73567a7af8e6779723aa5b8b513217e58a6a5a47228bafe0fb64c7c011ea1d94b956f07a630fd2f3a7eb8223d16c384fe729b1408de10cb2ca54ff0bf853ca9fafc33818367e3b80d2645e2cba0ab132040ef6f7b3985530c251896cfa73a9e0588746022dfac4c2e85ed1b8db8e841ff4cb2f8da725c2ee473f94507e3c711ae008dbdc3f6d51dbcf9227385c8281b4e34f7908880aef27ac17dec68191cdeac97bac9379de7d7bfef663e130ac30e1e61e7919b68d68f4ff183e82308b5bd42a280673f6f6804466c2fd9f309b5ea59416d5be4fe7cf7fb62d2eb14caf670b589ecf555e503c958e6f6809d342856a8bb0033327aa876bbefdfd88cd6d1b08479776b65f769c052f93ec365ad3cd16bc4010f3eacd6f87f +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = f7d38f58e5b97d8237b587cef9c385469bbbb12848f1e6315748c15183082c21c07dd2af6ad00e305cabf3b4bd27d45ba2ca858ba893cee5752b72ab144594a7b4b7d2b9a0acf5225807577ac5431008579c43521000aadc0489bf1c64009d83ea44acd0c12714e8b932b05712710e7472c43aa40c698851dfa84b03733398f4955d798551926b8711c8ffb55068a23fa642cdb8f40657243820c77f09c743e5907f703bbf32331fe8ac62f2d58582695b3aa7aaf17a8c005c8febf58dd8464656c343d1207d1cdc467c950d7e2c928d35a38c7380673a737df8c62b53a8966a5e9603bc12555c12343e3f24ba8f9b2261b2796844b87afb52ac85c0c8b73d8a2abf94f17952619a5542aa224a68e6e57932226a814c8dfe04b2756bb7c3281852862a024973512b4745458100e095edeacf5e40a4c69716c734b812ba44d49014ec5a0ea7012b38102d3aabcecd62a3d0aa2584b2a6c88482841479c30b978367168b9c895e41979745b3bfac52a87776a386bbd1a396668a6dd2c623fd4441616151a8dc3213b1473ccaa3cf8106ec8a74f32334a41413c4b95a6c4a365d62ae316b0378968e98e124267b377cab6b046404bdc94da666c1e44bc7b9927a7ba7b698c256ce55bc9fc575886acbaa6c92f95b7469ebc70c20693705367a3418fa024a04e46528d07029875feeb8216948c714ca0c54923f3989b30de3a924ba47e08a4df4a2c15f8a4d4d9c16b4438c2fe33e1f36b7c87987c2d03b4c8426351b3b6e19c18258b173493a03e98faf02384d864c89f48e88c2101bf541be886997a2017ea2b35768c7955b9b655941d7796cc1eb06b5d3bf11032514ba260e0aba28f7181e2cbe6095303038262462922729afaa01be627c29bcb27fc6bc9a53095cffd0a4989989cc1b9b0827053cbc29fe12834e8c7ea5d960705bca156b236b8853fcd8295dfa6dd127897be798ea15c3636709ab980dc43aa5aa6a941378925084950f5144bcb732fe171384d047b8cccd9bca1644794e58330f72672b7e73823550a89c1c5fbe691fc1f3c9f45078491a0524a6b88a521c3717648ae6a8a5291c63e0c90c439224904fcb6b957ee28be127257d4702727c2ba6017b135b7bdf357cf566874d0cb58f473cad74c1f2673fca3b5d236c27b562936451998a9426df73add60880dbac9cc26898c3196b750639f4c38a28a2c491e82faf9c4df0cb77fe52b41d66bd48511f7653866360aca481843ff3a765224ccf258f4d55b0d91b0c440a7065a98be700059e57841cca47bf4486e985c5003bcfab3822e15770f78380f56b012c459998452dbce938556c622e8422b801cd99ea450a7aa0c9f62294117181788f645c9b5cb814ef9bb2559c85f86512d2112039a40807b24474917ed013be4d146cadf400c64450c1e0650b5897f436540ae72331b48f126c5cdceace1abca150283c716aa822e63077d1aec4a231cd14abc951a23afa87324c0887776b42ec0f2d9a63825c96cd243240d4a746a07047993b9d5328940b12abb92a053b94ccc04dc86c3439483eba226463f90c6631504fbba5e26577f3f6552c0228bbe276bc4c39f1537d3b420b75451b6cb90a55873b01812a42b75d86a31f57dc62f177ab6df07f0fe9cee4c0a72b1cb660732d4fa64d6e777636d4735e0787b1716de768494561c009d4aa0c2a6fae989e995c00b079106e9738478aad4ff7afe1569542216a068819c12a5e8b6b32e997a324c07777b23d21e556c3834492a93c9e3b1d332156fafa328e56530525ae69eba076cc0e01b20dc0ec4a819bba46303e714769debb0eca74a818b7926818b511787d7e9a7a7bf23f57a47f86e9b074d13e5cc17c757066f3cc7a0bc5c999f86a8136be4e2732cb90bdb960a3d3b15007091f917c295ba160a646123d403211c775a37944bad6906db02912915c99c84c60128e515887abfa1a4a2599f6eb995a95a4a2c91dd65b8b6546081d977169414bcdb61def640600066694a7526cea05c366a7757c1ba9d1a655a8b14bc70bc042b203969430da2d4aa5af383242d9d56d88a55a66fb87d589cc642520f51c0ad8085b8827794f6564de477211d02388839615d62f673912c7c2824c6561eb848fc47a1c3b253c65263c669cbecf75cd25b2839be6963f29416f634a92433b6a4951d8b68d94e09ff7528036459f045b698846616c290ec2e174b1f337e7525c270a96ebe25ad2db58a4d2600f0133643050b5802b7987350c8c06a81b854ca8547f7148e21a22ffd51e7b546ab6e49a30e8514955a53e315968b619c3231891a428959237b9e57eedcc3b85ac480c103dfe15a8bce93d026513f87bc87435202b8c7ede6308c048c6740b3b0fc283d19a8b1df15e75a125d1dc919d610002b01550d734fe5594dd5216488c9c5b87b344eb5024ea4e6800361a2393e9eb4852a7455e33c08cd6031d389f3063a52439b3b4359071dc0be7bbcb2b8c9655fc2953e70dc5364a0d966230bb301016b2413cb74a203f4e034722f47795dbc65bb8b5e6ea9caad7a0836a3326d59b1f0c1572ac5df2625b59ba7b907ba7c1cb06e9dca88bc27ac0808361045377d4c1c30c16405558840338a3486ada4bc5eb84bcae92589e955bc025832a46772712930bd4b0f42961feb70edf6758b8619ff7d32e88889d925498738449c3a10e18280ac83b51ba06cb1772bcedd13a00c895fe3b4c3c91a97caa9ef559a2b2da341b5b7126206c08718763c4a891d219d19a7ef51081edbba0f15736d216746e430ca70c7400ca14d0ecb6a93334d570773a793fdec21d08e2c12e4b90b895be55a45a4595a9f56262b967984db1c973920a0de51bf08a709f2a5e338ca1fe974812d93ed4228297d11f3e606931f318d6954c14420ab1c774186588ff36c29237913329952e9b8551a059a843bfda548177e0cc6429b446653328d32f807708f35ac603e36f2680ca45422605b741e20bcee8d0c66ed76030e33f50fa5c2f62b4a1265e1cd869ff40a48a219ad01c965112964e0000e628a450044c90a2ab9bd776535567a13a2f41799cd677ae400921883bac2661a697fc04cf0121349168f75803c8dc6aa2251a043569d74b680d5bb123607be09632fea029604b90c63491c8060d0c06434d5811ae0889dad49c52c7b532dc7bb80b831813942930c49080a6cae0437fd509f327166f22cfb855bf4f1523729a4c64f3a820bc1d79125745e067ff0980fa83a0183132c4266e2db0b69d1bb4376baa010b2738b93c739011e5b62c71813b06291656872d80d337124151aa765835bab0238b4489e626a9c0919d224a716b1033666ec7040c7cbc5cb5901571840af72214ee95b3359bc9d7443fccec095c7c30f4b4c7b0a75f0900cc9d8a9eaa84462186cac58aa18ab5a8a9acb561161094600b563a15e70908f7d4c2f5cc5936617cb528a8ee1805d42c9d1db017d8401418073a7bd00ad32a34155ca93a3455eb26ac00b84c33464acb342f04b36a68b0852f04bcb0d3958bbc24e3b35327c5116530396bf8cecd495e8fc5bf48590dbf1c2e0225936c8a5b761271ed29153fb671197bad3c32ae8d2c4077392dde4aa8d6f56b5766ce28c76888e1712545375205acf1618479358a7f6c12f07c750e53c64323847bbb00c3bba29cccc88e2514007ba31d2a3f8ff13f7da10441970c2d4729605a744fb99b1a57a130006500a14a1b91b6f958bf25d5b37e90763a572472a7243656ae7019b44efb5752a97b01923edf8016317088f7dc23af411dba650d060324b2e7a8e2e986661398d8b0913aa538adb201be882cc1c57c63a433657433b7872507e6a47af20236186fd02c7a3066ad19d5c244d1acb429a04b6680d88b3420015ce4c63833bb1b5ba69dd92542e02830ed446ef1935a964bc3c25a2204671936e1a548bc8687c701b07b618e921ab050b0a8a4c67c525dbab0c3a2d5cc541bca5905b42e36beed9674a09944b5524db5643e3ec2a975e1ca98b573500860ad7a84b6329addd2a5c8a243adb776d16400c78867db67ba8d32135855022a75a6926b3ce09c58228a72d6ab3796f698ed59bd53cc5215dc1b60e3bd2a015523e19ae767ce5b10ab0875b43a70ba0dc507515b464b744170431dbb591b63420ce316ab5c22941aab67c6d4c56a411f071504f839c2818a27b7e6c53bea0c731aafe8608936f271eff6851ac69baa1329ee79b13df22e970a0c60667415334fe748b358c9863542a612255cacf1274f67c1f2753a63a75a71643f87911c70b27a7d71adeb4bb73586388f4a1c6db39049a3ad059b3c720c8c39327e3803aff3f84e30c1acfc7c24c4a3c0e5949413550cb4ce0195b988ff1d06811ea11817c4d6505f4e039a81690fa0294ab586d5e325388c3c8c1818e130f8fb8a7e6901313f1deea3d752a428e28ef80a37a3827bacb1d89f7743bc213ff1f45ad14a855296c2 +ciphertext = e0e300e4646594c98739bbd1ddca7ffeb0502b1f0ce4084a0540b6d149046733b8d861d2bbe1e30bfdbc423b87a2068b85cf298d72670595c5579bc0c4fba84211b5de334a2a6a989b3f29689f26b8312813cbe82674a45dc3 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 57535e55aa2033f03edf98c0ee1ca84ae471a2f84e322719302c0c387325e7bc129fb2a81ed514c83613788830867ac63a650d1af1694f94972d85172cf64fe323cd74f3cf55533d138a5031298050e169fe2a7e20f5b0eda78aec3602228973b06a1c17a10902f01c4a979690363b2298cda9c3ba58c31b6c1a7252b9543c995d8f4bc6ec4cbaadfaa75a25a4ba4769ceb12e02c68a557a0b98f6b03c6a67ff35389a733582699379bca24a7c5b53cc0da2e81b3e06132c5ccc928a3c2f3a020ad5094fd08341472c0b2858a30a000d03493be22d6fcc3acb147e13012e80322cfa3c77874ab6277a59224c581718c0846b00a7c15770c7cfa0f8275811794b329fc2d554a4a29bf701831298181cab0a1a15aa91746355c17675d48ca11065a3410582797c620abe3d00be68b612c785810b9ccaa204792853ac4f98372b1b44c6f577dabaaa35453131d7b86e827466f531a5918decc115d7d263c7b91e847351df7ba4cc66c9a01c3d752c89005985895c4a171a28a28482643b82ee249eb3472a04bc511afbceecbab034bc2cd33654298772ec089e3049532230b2a6db8924a8ca4c68aecb526ac954297c28521e8ca797c11f2e767ab4643a31b28f28312da8b8bb126323b5366a7d006963f653f0c002e4d4b2c4f557dc246ab4eac61d044c99038e7e688b40ba37df09c3492626f29c753b194682a5a83c1b00898876e6dbcd8b3011e3f922d238816437cb0f38201c914a3ed2c54b95613bd08b9596c3a1aa0023875cfa3a779d307cfaa317b40779df1b1e1d6953f064c575d202175033ef95b295c94a8a824f4e34656f3ca5ebb8228de50b9738ac169887cf3369922b3355f22a08239d77743fe55aac2df293a950269b14293450bb5f0584fa36ba68c72ba00891c6d982b09716debb78469075bd064626e614368661be774912632596f319b83398df36977324a108b9a50e3135389c41fbf7cdd8275dafa42ad7075a4f61912391c37f6c8d5c015529755f4fb27fa4d94050c15bb936185bac19b2fba3487978d880af03629801ea6df65128970b5f8a4ac6b94b669c598da447acd2eccb2c832dfe0cbba4981f8d5ca969f315985365fd07640fb32c1e226f0d1a0c7ee22fc5bc2dcf2048e3b21dd416c6fcdba6ba31c32949adfcc6adfcbb0fc3026b83c73b80412645cca38451c938753cfcc1b584574bd72666aa30be144a5f73e04ef9f146d3201232c2c85443afab463c2d0544f5c26fd472256cdb559fe826c2346d8bbabd61710c16370dc3537d62108ac8c4b9265c7528090cda92122e9330781a0345d20405a6356c2327b9a704af6b056ab3be440c2e3b83b0a304510b33ba6905217883cd74bac0219b443820ce86e0cb6b1006392896072cb5be78c348dba32f479808278cc2930d21c63827c007eb3aafcfec8351aa5d5c6c7d62963fb7dc0217e10500c8c2311616333397be495b4179cadc548ade588d853146da723da1450c13ebb5c1e52c60e75675957993b6726c842a2971cce64055093a356ac3629b84420f866938a9afd7c77ebff77195ac9ca561a030396bf7e63a1564b98a56b79338343c29bf7ef213eb769a373a860dd21e6a7597319592316a2c1ce08c50a8c24c616ef5512ec5416ca9db371f6370d9bb447fac0f67f6403b90caca1b26942c19f842881f0669256b96cbd9965fa93448d5228326b4164b2bd64c0ecd391506a264ee7aa27975c7abc8417d4a3ad24914a7883aeff682e2080bfc24c3a86227997bae44a53885ea92e59076a8d71240237435e4b08f75a43173585a62478d40445e02adaeea6f182771a69764eb8cceca3412ae2a3019b797d1e56542c5ab8ef3461e18529cb20740509387647e8db3266e4bbee4b41645fa277edc98ff1839598a214c2289063bb70ef7075b02a134c9a2874823f463247be28dd3c9ba2da77c96d03e42c01b6184ab729416e37ba8a8a3ac8290a194f77f1f942b14a6380d139d79bb433d59a681956321a0349cc844cca345acd9abe98917c160962e14ac06b67c451416f69b43ec529a64ab240f4612affb374c26c96d488f1301b6785618ec8aa87be04cb5529b57ea4ec0e3502af840df176bd29b6631245522c725af534c53b289dc74c91753793fa9be0aea586e63094e7aa9bc5867a1328bd3c157905ca1f2f8850688ccb6272a7f348c3798c47a357e9e2a9f9fd466e14859751944a449c39a09c814c5a0c0749669947e4b94a6d7a319d3975fe8969fb805a88362410ba0c74d380faf64b7dd8761685320a9f0500aa6cdc27a9621b878396cbcdca92e14c23bbca206257363c3f5a3d0daa673fa98e4b0a84f7b748ce08281d8cdbb5402c52b525993c1392b223f72af51fabe9ee80403b50fdcfc6c31c147fefa32a1408c7dd11522f66339bc6ce1f09ad61a0cd6047b98856fa84192b0455ee3e9593ba3ad2e418bd19398c3b501a12cbf97b45417652961a61a5c8900118484cfc0b883c732b98628a5670652b6932883c21e17202cf800374a9f7b4a7ef6430e13ab0275e81b1514590b350395e34b6ed6a81c7930b3eb67eb1a49fc6b7c0db7ab4fc219b817884cf95055a140336c38d8d37a4798a537551957b4007b01b8784386faf3abfaf7857614581b891d9c81c9ee104ceec5a3b335416c7a3e79d82d71d623ad9c6d7c72267874a6feb0924b69af4f243544e2c485c5afeae05546402a93e9cc15995f162c234e41672f0773dd260b675c24ef7b01dd848ef6178133f71e147a5a8c59b62257365c9c37807101c44c1ca929a25a239fec779eff304ea7e4afaf81b238e2566d9b21087c8dc6c20cc7784c5180740f604b8372807b1577a3ac06a4d415ae748eaaebab54a673d1e4be2a959d0360b1758b1b5012b4fbf74cb911aadaac1b78ea72f6a0a99fa221b7451c308c3f6708ad875538e1476787d3bd1341767f528a2f58b641f8b07e650ebcf2a8ea3695c267065c694cead733c49ccc534c3561972ff4c3ad74dc869d9c1aaf6b29d78b66c47bb76a3160f8b03117645b39105b65db803a8b9b48a385517a3844e3bdd027930ae7bb2545a82e75b2c71a276ed35a346006b8b46e1c726bfbcc6ef566cac79b556f77584e7b58dbf1a97ab59ec2cb0b4cd970503705b7f2a7c9c5bd8ef6a52cf5091cab6466565e40780e1e948e0785c30ed35c4c1c7347b0c7b9e6536b07b0449132496acafff543d4837aae15cfb540378a77a1f8dac5d3446a5a3014fb4645a1868d4ab9bf0c7b5f54f55f926374295693a8a4caf6c94e8776ce2b000dbb4cb0c7e1ac090a759ba845523982820460fde410520cc0fc383afd27a60993bd17e05575517379225639e49165f09294dc1df889141e846ddd125465662525946ccfbb35521bc646812343e020358c4163c80317f1a241dca078e87cc8418fef1aca7c242ae755274ee668f8037205a756cb35351eeaccc075c4acc08b50d8427ba52ac8b714e0c726fc929b758a81abfb2741589f036574bf223ec651343023b0b32a4d558ca0b7f6cf629030ce305d42f266ddf66ec5276b6594a4093099e2a58aad0a2357008f8717302f35c107d18a3da01a8be721985478f7d470227422c3c9387f251711c5837ef5ac7b4c29c4ba5b8da14b4ef1a30d718bebd6673dd4921be710a8cb698d44545e578c29f82f60b99c48422fec73c268595ffdabc392d150965766f1d07ab9ba60a6e3235aeb28042b46183bbfa5715bcea27d5426734d95239776cf072207f9379c71c80df6f98264b82c4bc0abf620ce3616c38802904a34535fb3529a6888b1a089ad790dd96b3ca0d5775e6a1491e3bbc85a9a9ffa2d6dab8230b63535a383c3691cea633e94dbc216b4be1a7690ca5b0cb6924e5c6035a4565acc657d38d28eab149fa6475490e51e266a62594ca5424398103816aa5894f677816f27928f70c79c6bc5c6b87d469785a57c5fdc22649dd7c8063b692b3180f50781b69925a3f59a9cea7c4065b026bca66d0a1937460d23401e7e0a0435f10cf68860163a6aa8cba18bf178d7d1783760cd48b9b4ebc0c65943739b10907551be5daaa0b09861474aa4d8900e66142f5a7a258c12adc687434d220f9123315742bc0fd58588dc0e6b34c7b65b3afa5c705e97687c968e6fa32cb31b29c6742f19bc747f7b6aaad55bdc5765f2f06b70f944cdd4a65406751099561375bc24b74b5c43389bd846b2316c6442267b71a789c5017cb714fa541162cb4159889ab430b4901a6b980a4a166a3eef8c672b1843cd1c0e6baabdb16368bb1394e55a1666fb6918359767a44339b453a1d734a2125234c2a01fd4977acaf43c71225b5631f9ced744c2c668c3886e26cdb59c3ab31a21fe3c240def9562e6c5b5897c8eb0bd046d94ba4dbe9025c80c0224c175a04c01c645344e5843fb890171a89dad5e95ff78148496f44957fb917fff1c1d6e615bd586 +ciphertext = 2cbbdbe50d328a7466e6728d56b395743c6258df9989dead67f25bc35c2475a1a7c7edafdd199a7503ae7dfc1c72400fd11013836d3f25667d4ae9a41d1ed8cc726efe0ae36e462ad289c9422bdb34e7fbbe0ae86f329beb22f8e38e96f9cb9990b837376d3cd67d382380911c2ac36ef57a662b6524aa61ad66588d12e9a3e7fe75ec70c6aab32492ee +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 84b58cc63aaefd7670ec47325d456b17d1b6dfe61e34345a906626286850a40a23e5e4b76679b3f072c1c5a7855a1c06acfb875ac78a4dc725fe13a34b4a30e29b4107a266226146481a5bb442a8abd85f5273bcd0c74a4905c7ec4935dc5aa57a376389164a3b68480f76b188560950dbb97201c706eca17cfa6e16a00cfefb2e9ae692954b3ed61c39fd2781a9b9b27d673494144e5c12385cc691007899cb779906a9b5f3c79936c90f5af5a78d04857779524a510e79f2b607f34b2fb9a62b057577f2b218779e9fd6bce3fb4c52ec5324d552ad01ad76a4c105214e00d869f9cc708b8645b2bccf3f643c0b355a9c7781f1086fc152a89cc8cc3a5594c1a5afef4120e196b175cc8d60678d884ba18cb786700a46b8506187ab02e3164f16f161c1082b10351b5f1754e5fc1de726b8bd783cb7705090f006c6d58cdacb96a1c50edd6422cae184cee01e92e312a1485c29c0896da5ad1eb37d33dba3e0da226f9672aa267dacb683a07c9c3be4436de971edfccacc4014f1f7b7dafb8a4d7a1858ea192e8185da8354baf0c45d698965316ce7274a114795a8d617802b7601f70b60f82a91161fa8429223463674737119f212bcc5a2ea997b7c536ab441bee8607bed994feb35b0af4bb66644390866c9358047c536b317b278f766193009a041c578dee231d4395c3bab51b460737b9782501424d792314f4240076206dadbbb2fc66367f9b7952b51f47840c6914e0a314eab28388bc03e80a786241614971b4a6bea137c5824a7967cba884f05d7509939c117548b9039587f80a594b9ad90b693a1fa99c4f14db8433008e2c8abcc6999459a54231621c5a3f577adda0a2c21e420dabc84a982b3116ca133a36d021579dc1b5075d060bad30f8da900cc3b80b2a441c23cb81a066d5d42b899496ba97c53d080802c39b309c60dbf816781e9b5ab84662c616395f20c0b6740795c7c8961286516bd60925b65585133371cb7b3182cb2991bb10e15d2085adc527771b1b3dc46dfe19e3bf7844c14529c7b7952f5010014cb44b1ba43d3a1f015163e069ee84515e26c2bcebb8cf9b35da80476d555a0d8971cc0e88a4cf91737822f4cd752cff77a4588a869e9a67e022dccf79476c2b46c54004ab1204ea310c9d11e70697d71812e25024736d018d8e8133133072ce1b28ce2985b604dc74acf0ecb574fb9b4d6958e6c314c84303b55518f0235949927b82c88c15a85cb99e7a58c4a73a1390b349b9a03539980f68795812c10055080f41072224a21a23426a1af85930239ec4fbf36225ef8505e84a02ba328da7a789c563c91b65fdc9c7ac5b1783f7bc3898a21af521faedb28f326bf65d4bcd097238ca68ca0746947742f8ef4aa4f4281184c08b88282e6d0adee4cc5f87c32d8e12a6f6c6532817eb7d4a07e61b75af6047dc94b6e3cb42265cad8313f95575138124831825f6894879097444d022f7e61c75593cd15b0a6d0604749718e76b506edf9491d157a029b7021e866926b99c523bfa355a4335c1887e827dd748b052c4137983ea522c0675aaa406b04b89194b2e061aa899ba0c3435da0183606b289e61134d037c553362eac65c119c1a1bc74b56a9a484c40a0b528716b5c3a298bcce55075c4c1af7b877b9b5002e0ce78f76231e159cd62cb233a2153e270b286683eacc87c9c8ddccb4ec8e53eb309946f420359a56c985a8665239750ec3b6f8597cc3a7757e420ef391381f724eb19c761120e1a99386a5b87a8c48219325b353b1572fc3f09780f97c6c7a61025f7558b5017105b3509a1b445c7b29f8d5753de243f0e2a195bb81dac5455122407a715404bd69b63c1bea2fc85a0f4b91a12009f416853dc95aa87caa5cb83fc2523557cce21a1c567768c61f08d88e63c53da57b11a28170439aa645a6caacb9bb2c6254b1e54ea3d1862ce42c15ff7019380276ae1763cb7c097c4dba48d6c73f98104da1b3974c18b9a04c13f77bea4d7717d959256389a581b1051e409ecacb30d9aa8000c64b7a23903f4172f469f315256e8eb1df80b443738736b816546c90769ea37bcbc5a85b5a4624a7878b5012f95141cb58509db36287b934680997b4a98f51835b14103dfc338d77957183739a6433517a01505f5204ab118e78ab16ee8c9df469706807f71e9a3ba735950490c0107623f57876647c314bc20bc7a3c4d60892a5c65d446c50669340f95c3b29b90e5dc3799bb2c745cb22fa8c8b2760bf3e142ee69c56d474305b5124a2a9adb228a224a103bc059789774033000660b45ce28073df3895fa60771c3a4e57b50d9c92a0da951f3792ca55129e8d634f3778ee7925143708e7b202f73d63b38c522d9c97b74902bd6fc79e7e92a231c7d0c354bed4abbf1e769877a61b5d991a3f06988a30b0e444335b58ee96614861717d4730a42e00ebf85cd94d02629d0872aca794749070d870a0a696b7fc85bce62839499b84dac834a6b1b07752310c4948244474cf435031a2a93745ee726c777e21d7b86a535518a4e75673423a118264e59604e0061be82b28344009a4dc1215f75c36828b7d77421f4b2799c15ba940c3dbcf88a67791c72418ef39c5cd6b4b4dc924ba5b69e808a8bb7c75fed414dd66588e0a02ba783b235e650ffb941b7774fe94c0e2d39b7d8d2cbff428ba66c4b7ad486afe4a6e3997159802a0f818c42eaa6aee117c914452570a482815fa9f69e54b27c3de897295ab98a10b549f1257e786c510202bd68a2b54024e2419a59525e273277d145c1e4dc69da8aaf99958b535846c78375a4722e24ea2ad72bab4f504e1dd58b8de19f4b7874a69125fa2925367976002ab6362878fe679d83642008030930570f56927cd6386188e43c48e5ab0fd7192abbb36f6a2580c3c2c14c2075db019921b49bbb985f0967f98273bdb72c0a26a5883610b01380e4db5650a1bcb1e3acc2855f295b3752e69a3b8b092506ccaec0606d947b0c21573cb63765e134b1a8a4081068ffccad2193bef0954d5e95a52dd35f5520a15d27af4c4623d6e5a45ba34d62b19165956d63a99b84f3aea4fb9ba953c135a0b482c9ce32c1657da8c3ef55082d90979c801eb6d07c5e5340a7bb79ea474335999ecc9b5a4ff1413d35bdb928a4954527d7a2cda3b07dafe1933f7a1c0b33803e292a35660cd59782796709de063f3ad16556da0295a38fd814086948cdcd5a269f89462d373537e085238799c7ba09dc973451f80470603fa887a3311395c0112edc4b13c84509134639e1dc1556a81e05a76f42c70138293664db9a8b448a222401c074091689142fa397ef03bfc9810b1acb85f6738e3632a3255c263851bbbb5c3afcc04317d2b312811078e4c8a1d014a8c1228969056ba17c99b67fa043bd01f60943d764959c033c5c0d0c7c748ad12fc402003d301cff12b0a33b02c477604b78ab0d68574ac6859e6b0170f998d2f8b542a456bce46ce05b8e9bc85475b0b31fd69a911c9af41230be0b1838407401667023300831cac0d8d7a09e164774460436b97e0ce96558888e1faa0011f42d38342d98839a43711df536070ab9478c2631a926048932c01dcc401537b222e521d4ac7a7323566b5465d11bb7f589aea356502133c3c646706ac048f9aa308ed021d389556fc475f60507e83804e5a1ba331acecc34cce8557703d3b5dcb7486b7086dd19b4098820134c5ef5933f596c45a6615de38c775686322e0b96807706f06a144e73cca1152180a244a9eab4d8c9cbad8614e3953a5cf185d5b7c66399c87b1b3edfd21c410533ba735e39c5ab7beb51241891c4f3a4bcd8380cd69aed024d9d70b79ef91906eb67391908950703a6e2814a6821c9979149169d978b805277994ed84847f5c68ac02a01f75882e733de969ab0bc07bed51f59340b0034b1f4983d38e093b4493ca8840824d55995966b70aa8c710285a79834c223c056e80e0f35b67030419ec29b1992144c11cac843b5a6c31133e661a38c92f1b4bac8fa5235a3cf58056db4e7b52532218f9225afc6a770d5bc9c95c9bdc2adac11c402accbc29a49c20a3a3415889158818fd371c9d804d80586c93615b14c85d42ab687e55b0eaa68884a5a8c7a07c77281790b5955fcc33ad725ebe263682579a0f59f3781c8d0e9b7fac05226699d2a600f94525f7e622463d3617461a978437f6a69c4b0c30ab1f48c4d2c31447740a8069e20ccbaa7a3aac89a9eb12ba61dd41974aa0df6f92502d96d368a36dfac4595fc93d0a392943a1eb4e42536ab4bfc4ca6b9aa8ac40878100a9382989456f8902733235c296d3347883caa20339e134d18b5b9a3ea52aec7971503adfca3c407bc8abb99298c64b2ce5de570182de0a7c3b84f725057e416cc75b9f3f0999825457860aa67f68155920e3959469b87a6af65766c839d85ec62d0bbc39d319e412fa073b1a4b9e9efa0591802 +ciphertext = 5206389764a491c61bc855ce6a0c1104a9c099cf1d87fc36f62387e298136637163ad155fd810db0f680477388c1ab17ffab5adb8335cd52f64881a00af9f815a78036c898e53c0c2fde4c8829bfff160f26e2cdbbb91516b7623dc123d6c0036843234e2b84f66d25e073909cc2d95585b48dfb5167ea380ac611880965f033a0b04baf1051360053a502d75383e223c0043c3f43670a2043b7d954f8fdf35b8448b83381aa806a7dc5d6d5a72f94dac892379107fc26390c36eaee2838923e72e0f8b44008dc3014e34994d67d72ce1255813a4afa47beb2dc0e657cb4a8e0abcbc0e06b65bc6dbe66b0c4fbe963aff5890dc9551da05298588bb2f450df64ab099a5cf01dbb79ebae0fa972bb20b33f7184d169d4996bcd843852ac5186f780 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 95f63a86241eaeb0325ae0b109953ea8a18df2f201e300242be76481329f6a5093d490892b7351763a89f05c9b292876c31453b49064cad5447692927eea0457662255695788f61583c4720fa1a6f89450f1509947302861055570e2ac0bd31bc0f75c0e472ac8c17dd0b4169df461b2958b48b3b3364521dfeb04a1a3a68cfa089ddb632b3895a5707556bc3c25923592fb0d1893c14bcb7c6ec693145a2ee385af2cda9c3c33108d8b9a349a65d0ea63e578466fa360640bb67f901078e306a0622700b0adf3733d707620932b306b517d0d42548e8534eb82becd8cb11de01842c99283451027a4687cc20890116c366aab340837b80c936e63339a390b3ae680c440c798ebcf7eaa182398725ddca00b8a409e958d1609809a13b85e8014d10736afca36a1d910a5745afe4baa11d82b7120b074f77497c169ae033a88b18fac9c3dfd78bfbfd12760043b9a0839dc1a2ecfe26917da7d89ccc1e5c0abf56c497ea608efb8ba9e89a1880c5581d608f0ec119bf518aa08391e503d6d0b6fd64baa80e8c2759363d1568e44ec2253b98cef74a7880189ccf6391b19960cf08335f033eff1bb75e532b210132268772530b64ca87d1a7a0f3d207a3035c2c8451c07294d857c3528fccec4e1443703812a8b8159b141e69b8b2136470cf09815b21bbc82625b044d40c45aecf159e8408544a70cba26a877b09154534cb33422688660ed690359b917c61b9ee1c4264f55387b07c3ddc0334e813b95020f002a835c4bb623bb299097634e15aada37bf7b64593c8557704a198ccbcc8913a17447c1014a3b6d767eabe5523a71596c5b0eecf911a008369c00c2a5d73cea759ad1877fed56a1a07283f479484abb041be9984c9272b504184d6382eb891377b813bdf1330269131bd870b16b16255465713732dd2a6185646ed4ea20d14b336da02850c8b6c047aed0c43c402c489d246accb853bc963341848ad0749b829894041b280bfa4a794903c72515b1e03de4b00b7369376ae49980ccc7fec4a0a248935b7c2c942c8eaed167b6c8779bb4080c03452b1288adf15f34987b7d56b3c7135c10446f63360e3646b37b4046f96c5eba1a63db0a8a394a8fd01388831b4354898df54b5aadd19f79c786adc9c04707c3a284bd9a0a4ff21351c790823936cbf04b9a872636dbe972a639373ebc5d66d78f0789744147715d44b2e5634392e510f5c27d233554b944c31a76163782ac220bca786a183c48c1b693ca81f3ba686b8170152f1d8c421f743f7a427165142e345579a72c23a3d28bfb8b434a171e0eb211a5f8c82e54b69c78acb8505e82b082e5c82f36f65051e323ecf25bf73b9cd42ba7a0e715443234bcb9075cab3f4468b8996998685c9dfbea4e1b3948bbb6baadb63af83187dcdca108220acc019ab79c540f20a00a5b7703468b80c46e86a3127ec1c6f806901ec750e3b774390a22d799700623a0b9242457c570c9c60bdcc521bf7b3dd9241a6a288607179c702645bc5c181f61a150899e34c56d1e351b6a6c72f5cc68a2ecaa00b40fc2c27499101013582050333234ac9951813bf61b0f5ed385fa7461e6613e42585e63746d78d37d77263da582518ddb6860d5a2bf27aef8772cd6819678b40a2f6810c56954bb02c31ad95aad66c54e294e0a792be41b9b2f0593e8fb010b0a086c43b232213b3b68c27179316779356fa710df4a948efc9ec7d6b69a138ca4ecb5366b98663ab2d394c20b613326fa49e0c3851bbb2539863e4c7630f4db8759d83c313a43555709fdcc44a8b9399e99b01465b8c56b3b06b1a318908b685c10725a351c678fece21d94b798d2948cffd2a141acc864cac90d61477dc205fb9191f659a6729096e612a16c5b8de2c35e98b4965050c66f9c5caabb9b8c6786433636ba475c6324263a588817f57cbb084e566869fd1aa991a50387669872f44d6fb564492475a34ac7731432b11293317911463455abecc3af9545f1a2165fd57129035aeb38cd64a92a7860cc21c6439949688450845460a3c70cc215539e0450c333d4adf6a0756fb41575da5b6a722cd7d3125064bbe4403c71593d94d2a2697613e287397a770ad6173b7906186bc60c65203fede696a0fac4c278b48ad55ac7c3c24191a3ad82084f6b521c7805613c0d82c157979547f05a3e4bfba7c73bba70a71ae6b85ab5e409426532e71b6ce9da1dbd56975eb12840f544132a2160da3a511a94830022cc37cc2743ce2cb241be85b8860708d4e196f607c07cf001239907a3061975e5aa5793c3b98660d516b1db109aa24367adc3a7f1d6bfb9e82f09151a16773f4609602b9c365096b1bb9101eb6a3dfbdc215efb51c66b35e2c74182f76848300887a7315fc896ee507e40e41a1ca11bea80a1028437fd9048f9f4bb692b796145b64e6570067921fcac16150c8aeab59dbb7339c6655b6ea184375c9d8e7230b05987485c75e9d93980e72689fc7cbbd21f30dbba2bc35daa733dd6469d59c5838ef611c33a84ebb19ca27a2542c83e472934b1a0ca97bc8548570a28543b0b13ab40fb2122fb3706636375c1327d78581f212a8b9a4710a000cbda583361c02dd9692dacc3be92ac18d20b21f04f02f2b743d960373463f4b2a0151a474f298009e7c91cc39c879c08ec9714077ccd5944611cec78cb992abcb8869161c2afeb7e5d43a113e9391cf72ad7a9542f494bf990cb33527e0790143efcbdb472b9c5a764ba4a3ee1c76558d943afab41fd71b11a6c49f72a5b45e68153532cccb90a1ef5be64716f576411c15926498b169263b432cabe8df1b1fa948f9430a17ed2cd7e9320fb5c9900a2b3d0c785d7a26a78630434e0c18b9b862f006eaeb60398f82bb2da0f116c6a8476ac91f440d788621a39b259d13bf2163f7ac54b93789f5e5b6ad162271e9a81816bce83032f89c557b8fa82baa17436394dda934fd1094791867be7a0b14e9597f6a4abe2164b2821aea60461d3024b66e5797adb3d9c72a5437405d1156f5cf33a8da7acb6f164dcbc7aaf144e1b031b0eea8895e529c6a86a2e49aec8b065fa657f4a84c120a580f20b946097416d14c35a17385bf43b91ec378329cff6c12b8479b909fa024967b0566073fc39c067010336a6ca854cb8ebb1ccd9d00d249b15e60b7879d1828564b44965146c13b73f0b5b8f7b73c48bcfbacb721ca1700efa4f1aa19f23cb8ef305b3efba9c7c4879e4d20b4d0cbd1febb607e7bd6d03ac02a4440cf248bb242c06eb6b71415f7cd32d6800633f0637e41ba9f1992484b7714a50435092229a102ebb487c3852484ac45727d128113956db536c073b9a521b5aad660ccd730026f1864c071e6fb98d41e78e52ca7cfa195caae62565f4512425503ad0796c0b5aeba33b16a5b3d338c972c315354bcb7c45aed00768b6418da0bb3986f0602db80b666b973afcca78459f9441be5439330fc355a63a75f12a9c5e59710735246541c52dcb1d2dfbc1953a90834a48cc0a80b168501c777d2d731024d87a4ea668bab2cfa9845230a41b8c69b696c7b450c56c9eeab320090c125a92ec5c639be90c5e8250ca191c5995bf290bcbbd484e9e03bf53cb14759b3b6ce16ce0524b0be8a629c2883a08aa0b4189fbf98315f28709d1ae6373734dd4559d84cb18837aec739b47503ec66a1e7dd32cbc6a0400da0debac7ac248040f74497c5269a1845f4df97bed9bb0c1d4c1f65483048ac8dd05399b02cfe6f3a0396a362f25648e638405b83b3dd176da1c93f5283ac6a9c4c9f3c7475bb294dc0209778f1ab070e5c78c095bcac6d53643c63b20f168cd96b8574665989ba37b9c86dbb28a22ec199ae5cb120cb41953c53bb65e66aa93b799b1cc618600e57aaf0688faf454dbd70db24c195929a4d67b6318d774e04a6834dc362191621a900c8a4977470917b4abbf307590f773a3563119d44905b66533f09a48dbb35022c47eb12689cdb95550a68ee6c40e3b37aa8432b2dc8190e745469fa47c3cec1fe0381d58688a79b1c504b22d9b9a97243a31433452b3da42e34077c1227019b99b1157176607bfcf008c9f3c5be5b996ed186f38bc55cd06c338116be0a31f9521053085c0ac7a2e22d89147261c59c13cd6dc7817cc93ca53c1aa48ac124bc05cb0bbb25265c105155e837a9a5638adf9cbba21844c505c1913403766aa10eb3a37ccb82d6743ab13bef0580b993c5b87e9c2d3a1cfae8410e57ccde11aa78f47af332b81c05527705413b76b631e070035b4524416bc2b5905496cb2b1e523ea2334c3458f48a522b329b8a321834d2625d38516610a3eff42418c4d3dcfbef30641f541e07719de52abff1c85fad7c77bfe3761f21b7aced8dd3a446f752ffeec57869e598b54f8725ca73ea65ff04f729af08b9dca7d5652c0547ac52a6117876dcbf5b32373ce3ee2dec1b03181f96b5021e606e0d0f5147d +ciphertext = 748c6c53886fb3f48c8dd843922025255f50d444a241ae1a214cc38c94c777345cf003cdb147a707903c1e2c11721c919cac3ce4e437cbed2d6bc1028319687d4c704273e90e2f6f92d4b5a4576057c02022884df4490dac400344e25ddc4fc3b5b204bc80cd8b3ca37664707137e76696526aec4269c1fe402d9ef9df937f8d8aa3a650c7c6876e0b34828e55fa70919bd204b03ba51d75f41134396d2bbf0014bb84a374e5b851400f2bb9fdba3999718b3b2e19b9508ac0f524e99e195f5b557e23cdc1e65ee5be5fbb5973d05693230be2bec219b5a52832b4053e40f627be4b776b1ef67e2566290d5bf3f7211ea7cff5fec891da8ba2f0c729e6ae44cba02a3e467d2beb491c1068d701a4522bd32fbb4a72ebc1aa3a416c6ef77ca2906cea8f245fe9936a2e7a2f9f41c873a2d1dc66a087d0841b803be0d7334714703ef598e812b6012b03e5d5e2206c41f0c8ed403f174a01b8431fbcc48048df299439a156e2ea29ccfc53578b15b47f8cc03017200e01af562afa5fa466d4ce892c164b6e829827a184dce5b479082f4a9746728e853ac9dbd893e08caaa4621773050fdaf825c48f0d6f75f24236fa5c63c507007b6171ad87fd3af6320dbe6776461948b725d5167800a1110d83aa2f731ebcc45a0fd5c6ecd7a70fa74626d58595ce47b4ecc767475ccbb5e0d544c95407a61c4c7d98abb81656bdedf0257735a16d99ef2278294ccab13828a8b4dc8e88c1f47551c2bd2949fd7eb35141f7e98eeebc2eae8b3d1bfbd288956addc02959f6d8fb75eb6a9bd48470463742661037b91b55da9a4cf21d5f3af709f6d8b67853ab3349e134e1834f120677b00644235b5a803ef5ac3035fa8b62c5b853e6a40bc17f953005611403fb8aae93c8759ed3eb67cccdcb8fc9c47f2a28e8c47ad2efb0ed6d0e0e9b56f265c7e03699478eb9842bde0c04289c911932cd83a4ff2150a350a93a8442e9099ea19e5d84dabae25cef57c1b006bd9276d8132304d1abfb8f62f829a85ab7045744fd1c1690b4e2053e3f44817e36beb44024e16fa9b14a163ae3fdd837a9ceb1fd976379b95e9298b7bbd42be80067acd8d95d9ed7995befb2e5ba27a47c9f540c572d33bc8beddabde5c54650b3d6d074eaa86d0787933fae3e89a408969ad4575e657b71821e5a2ad49301eaa009146b8af0e1dfc2a2db4cb9a5cbe54d2169ea502d25ba5af18c822982d1ac5f59903ed2682b7f813aac573f12c5a87779d94ceef3cd6e5879a543973723e31bb3aad9fd0245ad8aaaa740dff3d3fe88e5f7affe0e5b73e3f8894c5691897132c697c380 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 7944b442b59985ab8d6bba09accc983f1cce58c8a8c3860300f14e80248c80f90f1bb2a5f151bf4b30b674565b58771f9d42090810565f640f0ce1a92c18cf64abca61d9a352c9a37907cc19311302660fb1989f8d995d627019c275967a7a74f0f15dfa5305527336036701d943c27275412792c7f813cd892ac245d2452b8b9cae70b1a181acb03505d17a7ce39a8e87816f4a329115a6826e620d3b0b41f4877cb039ae7034cbc2241ed2e9bcff9c9e1a79127cd7cb5d0022bf49cb8a7400227463b60b257edc8779a1bcb02902678846cc2c36eefb838868ccf3b944056692635b06a245044dea358d163515d10bf7a22ffdf58de5f72487705b69503021d07d40936318db3b05829453e675516bc32e42aea82b899df714fa25ca2c82718ec708da872d2da99782356b6574c21d018853b56ec1e81772d312b77c9af719761d01cf28823d9d4c32d07289be81239645155b48c94518712b5a8d6ec6682a40c2a59386e26a5ad81a7c39f0a0be187477a78bfb7403759539218c0434939846d1afa2ca01c4c67ad86116f3b48004ac10bc380965412dc2863035624926017a64640133ac6f4d45142b580e0b6318ea4885b292649496c798e0c053171314b329b354571b891cee57475fe449c54513efd69511c18b67da785aeb7a348b92f3b8206aa63b9a8059e06c496095befa7044caf44d282913fe157c59245b78eab17ed0aed64a895a257f7650a3a6616fc64a0032056482bcc076595092f66c01934eed67a7a3c76dd2b55547a5a06d563c4fac1466d14f81dcb064b20db7e25a59ac9c12ac07093417c566034e1939834200c5788dbbc11a06b71648d41a2ba6118d1773d7880934f39f32658657e520808834de53ce542789bd3726e818003ee46a97370945e90ff3544cd731590148c557216d26731eff8534dbe8856938bbc3c754ed571dfaf0cff9a23861885eda5955f2189fb876b9b0e93316f943a1c230094078637290f826a682a5068bf011258c34aa785fc323cfead03162404f4319aa1100918b7a87845bcc2c21831cd394d6322b1bb53b2cb145e6d10a3266737386bc0b5423ff1868a3c4a950126bc280b2f22272fb926b42e630a23a53515b58ee3aa8a385149bd89d5e07881767c6939884ea1c76e2f103a8970f878116cdc886a9a10b393a7e25f8c93dc15d80c61776fac437e99ed83a08fd4b569a9600a8f19161472e2fc508971765d18566186b26731bc93926a0fe50cdc9c07d719b28ef4c741a955f7a73c1e0acc04561191e5041231c6ea8504538831fffc32214e233c9c254f57142f03b9d9feb328881407a069bffd7ad58bac32846b9e74147ddc9008176ac2695be2755107e4922288a144ba955d66aab29ab6c5ba91a879b3649267dcf4a0b1d457768c94e5ba5c01e87a5c420187dfbb907449f4950ade67ac1002d6b143672427315de9a25bf60a35db88d84500293404ff6832bf34a655a003d8301b0b92bb8a622983bdac5d00b6a9e9438a384a9b645882bd55a204b17fe859e93fc7d7be87d352612c9a4b9976bc2f6a541b9577b9dd04b2982660fe03182ca84567b269cfb2a0e99b4c55881bca233b6959cf0a01da1565692f49ed88b2f5195559c9921d650bed7b129692552045807ec999febf0a287b03ab08c8edab8aaf55a946e280ea1b08887d43bd0ab993a9870cca12c434bc72fa793c44a520465297c99aec2a0180eb735daf603b36549806c8f1cc52827ba537354c7730c0570022cc36a783aaa47045c04e84cc2c0f6b159aa41cc94ca16c808cbd4798e8998fae2cb331a5df855caa591324305bf3fc841125a38ef253be2395e0220b821f06f1550733b256377ba6292f98f5c76a730248f949563d4cc9c5137bf1bd38643a9bfa1b13414128d5e4089aa863748091c043bae08d44a39c74ca7eaab8f656372027b4527b293594bf45913629a7f97e68a1eb7aff2e359ecaa2489868478a6645a0b9ca43432ca144f6e2b2676c96559315608e6937bd8a9b8053498028b033900da835886a60ef4f1475720508853915d1870807409cf21228aa1cb2cf4b3cce00ddd07c078ccb47eebc6bee309e46430a6d4359764ab97c7c3b129406de765c56633b378a262fc01b340c8bf18a97d7667c438a9a0a64c5ea22f15627169038e2b375b79a7834a17bf51c644db079054d33d40902a5283b8ee6189dea31c40681e6ab6cf4fe37d340719f6205c38a911e7c303c70bc1f248c77d535e9e06b63d7aacb1c80f4423889c9ac8dc317d8750621315b0c62a5fdce113672427d7691d383b21461240ab11bf07d08ab522071e8570dad396f871acac329b989547ffa3155500520499c4d0128bb9fa87821762ec5a778978b793ec51e1fc867dd85a972b7e83e89c38486c77400da5eaa4e9872421eb02eba40bd7c76f55abcfdf683fa71892738418abd31270aa5b4306c4bf637daaa3bba87187693022e8fcb501405b27018bfe359ab6c121609c0c020b22011143b3824338b56184a314497a535922ab1a95c886836989871712d12c1768c96fb7a5cde778c827315b6ab120e41d90a8bc482bb5338b9eddb0c57a36500bba18fa55b62380c6f42957864a9847ecc9a563959cc2119132c931b69c13a68fefe8951f46125070c42f497e00b29d64726b6ffc9e563a802872614c3129bbf329a9a5c89d42abc83b8d7354abf98693934a703a547cfa464186688702ec8e99db90b4e13a1eb855a8059496208488e7563ab187fbea61e6cac714a0b0e2d093ab88ac2f7805c8e0647d745253d284baab00f4ca684af30c5671022e592f7473aafc9c1fb03845745c43be346637fc8dfb847ebea9cf75ba3b3d345c7e31a17a8a81b160b88b35cf4f5acffbd2740c791792a28b9c624105428125603711c22837807e6799bc1289cbb204a2baf49b5d3c6ab23382c6cc2a08b844c7eb79c303af93150b0274a35f069175fca68f7ba59c09294c2cc003818fd5f484e9597e71cb23a61051987642db13b755e319354827a969a80f35c90b884f6134c9870038fc904a7bd12c031b30b93833a2113a82247071f262bed34e23272cf837b38cd438ff9c8bc722120aa1104571945095a0f1655c14e28d3294c479ac1751f27213d67a82fa52ead59997d62ad7c35b8f2084385969b1031ff8f7238146102e06c6c1734103033ad162cbe56c8ca142c4d4b663eb9b995009d092ec55f4241e553b1442aa3a1bc51444651f33730d88668ff0aa00a8c6c68c566efd424fbc45519d9b09385687ef17ad1205879bc6027b74a2091c0e7a472a67800cbc9ccc5cecc29df72f7a038534c239765045cb264048638b00c423d7fc140f52890a136e5875a617bb5221407d82399e8567a29c00b3b67c9f5fea19d30ac79e3b2edd983abd335d34a030a43a72f51004d7f54b98ebac2c3b59cd207193e602b9f12871f533cb83760dd38089db55099b5da77b180a056a4ff108b843524ad1ba3503b6693b61995c96b5db552e28634c4b74aa878d07b33f66985f5d714c9c9aa8a1d09b1a23bfbf44054ee2351b79a171569e94a176be07b6be02154de830d7b89f09999fb4f1b083398fcef29b46119115302463fb002131b4275b4276348c48d6a06552a439ca29d23760eb11c81410022b975c405a4e29852f8be93352a631751657f574a2438c4840a980c17c9e56891389445f709986ebf71bdcd35bad3677083382b0957d3b9bba2ce88371a517675a1fe2d766ecb536510360aa462ee824bcb92a09d2ea99500c9636b5ba5416c14be78ff526a561270be94c7e114c13af060ac506170fc8b3e8756b6fbbb19e2566285bbf6822894a997d7dc264aa9058bbf2c7ddf1b1ec13bcd817403148945a403af25c5a051574bfc3531179c8f52837c13c9698b102cce1b9d5c6b2dfe8ccd6674181e01b3d818dc3926688845c7719536ff25a2705572f5c205a8cc0d8ac1e433bc6b52c28da1b97202b58e5faaf29e68d2f2ac05411a78ab59dac460d8cb687ec756b0626687747a711985859f602fbe3793d196163352fa6c9787e174aed4807b1f8a9497b84f7296483766e5fa2034ec08c8674953bf18064d842cce3183e47af885a5ee3fa4aff8a9453616fa498a302003477a4ccbd5c3614938e3e3a4f4a157c4a986f17b56fb45b628a31164f8c25f85b45904a44ff164e8705581cd23f9817c3d8495dcdd7b155c714268b872981c843d21bd3d69e02032195a5af7fd240bda61063246c63762d37b2c5ae8a33a78060adf35fa1342a7434c12113aae7b498a831a7e635137b68662caa8fe59c5f12788b11805899d9c2b14a1842d0479c632660284819302d57247c2d8e618c366e03e75af6381448a5f0881287e302b3fa6cc48e478724e89917de08d1c4503aba3c62d87fcbb8bf2b3c51d269302dd1fea96ba10d11e6c284a3d11781d83178f96cda7fa1ef64a13e +ciphertext = 4692b49d06b5eaa032443cd110620608c9eeff22f2636ba18b47fcdfb63f5351daf41a4bde6de4530d672d99c6b3d5ed8d0a94ec8585766e29961468ce25709f86545719a9f8880be4513cb2e9e4923065863dd34109bc22a86d5921a2ca6d463c43a9a9c762fa4fe6851e2f27c2760116146805f1a6fecca56572b4a1da332a2ca84e7f9964be8019e9e15e2445063f172ae6b2db829d71bbd6e1e2d13945ac00321c2e4e29bc761fe5709bfe8e1172e43fc832d19d2760e88e760dfe4de7b9cb63e9a5bd851c9d1ae1f6b94e26c1ab06c0969b9500eccec5afe3facd17a4c1757cd9f9129cb14e5f3d56f286fe3657c606aae76a6a66b8e6bd03a50e4edb2c5968a9214a98c692ed876dcea1a42631fd85f6098ea1a46def56762a0785f3f10c70800d60a0ae0850d69a58622b0f79b594f55351b5daba3368f002b5781dbbbe3c126a24162dbc0ac190e90dade870e7417e4617c1488e5e17cd4073451dc392c7c6a0da5f75c8be8251ca7fcbac6a73dfebc4360a8b24ff90e6e315100f6a8b4a9ca5aee3cff80ea33206490515960154f1fcd320093dcfb8d54ad220b5dc96bae5bed62798c0d53203c39ddd2745e0a8cf55517d763a3e3b9be69662a14701017a9c3a3c91bb381fe4acb6a4a42d269fa881a75729b9f63715b4ef6998bdb510172a078daa8c72ec5fdb4369c198eb861e889966f8c3e39b3b2f3acd4b18278e488714a1660d643bd79c04c665057eeab8613bfd86c74f8b8bf5e96f6dfa9473125b2a6dab7310a1f9feab40cc12189feefd9aa15f2e9ca2db452fc696216f2ee7c14c1244e035bdca13ef95d83f44ba7ea0e653a846d1ced985596ee86432bac922c514a0aa439f3b2ff202c782057473d28bcef1362be346d8280e45c578e7dc9d4f4f7abced574d2cd60462acd55e8693f9d9efdc7ade4c7c2200af71259b0ac9c56cfcf1ea9710ca183060034b57cddf12a42e881265b6ce1352234f7a15e4ce9c668982214a195e2bd92026bc4af1afd4f476c232eeb7fed6b9163bb173d6bb88b6af130650aa472ccdcacdd1d0f63bcc220bd708fe235de84f198300599e553640da0b07438d4d1cd572041cf41dcf761b1a3627c25340517f2561df30623fb59399c6b2e448871fb09417a385974d86d579a456541e8cf7a643487e29cd4a6c22a7aa7030d2b99d1e648a5f333cee31cf4cfb3f29aa9c70afb22ab7e8a9e9630a06b93678b83f4b04a18d03444267d2940b203a534f8221fdb6532ffe2ab2e35fc26d7a778167625fa71022aced53cf6c40f463dfd70ade7d584edb82b2b62edd1a6e6b88649389e97d5bc7372347b1fb78911662192ad1eb53361a67039d6924d01897bbe4d1532a60039145047657fcb7c21e0d2fc24e5d3a6f8b3f6898cda558f3f1ef190de742cf5d10af47f32936c7d1f52af890f66239280c9fc4eb6c088f77ba104606f4e0 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 77f208c2d91f6a297e4ff1b4fc9c207d024bee757ad4b09e70243c9158b714c2871e6678e4615d427206193679273c15cc207a8caa99ef6740ab4c1a75d40d39d102229c2d188b67c272b50b3b9f84b44b5dab79c3a3963d970438e13bff20c19392935f466ffc797e00f611231a16abb91440acb18766403e0ba914a30bdac5a6c73a0d97cab093313c51492de6286f8c6a4b176bb64ce8729bd15156a734271b18c85bc80d8cc04279944a6b49f32831bb7340d7d67a55067807677f9c100a756950b2e5272fecbee14a5169e79c6fd96a76c66ad1608614c2b88b9383068c4022f93a2c230e458a5061f8c60217244bc43be3f8cc71527ef8b3cf1675152a2ccf07117ba6ba9a17c76f12532e6e25a8cafcb0b7c54051c60ff4fc81c9f3852959aa93ea1fb777cef94b20155a9a60d15377e2345fea4214f92667c38d5589bb5be64628457e0ed07714182675766e66a45e78b822ae86a2edf26cbb71aaaea092c85947ffa18c82123b3312c451a03a09205bc4635a0c053a70089accb5bd96aaadd6eb5c7786990867255b20564d8a84da50bb903bc68dbaaebff87794f844d31149439337994c53e54317139741f944052d973ceb0841bb7480b848cdfc243740f638e1b276207126ec42351ee9a46b1ba34763cee2a37af975ae256b69f112ccf6020515c9a09fa2b6bcf943f7597d4478b68a933ff0aa6a0fc601a2fb0082558d53b7ba46c342216768935c6b32e344efcb9626236266b88853f3b849632eeb5a2e1b85bb6a3a7f80773d70018b6f0735a1e1681d53ba488746575b33d8e5815d79c5d66b57d083a78b59c186b2b0f4f76c4976bcb1e8877c37ac9646308f6ab4e6574b41356bd8d90ce17b3946e0ac88d18e8ad3610a102fe1c070f3cc0db6ba40e2fb68daeb48952ba467b5938f38c5e44a3c302c15c136c5bf275e33601a1ef194f7a883be847744db11fc9baa51ba7b78911f3d24b25835aa17ca31f3ca6b594a22bfb3c528628e9287561504c284b3736b9168b9c64386669093ac815cb474e562c452f41e789860005aad1a2b6c0e8c0bfbf0ca7a037b21e6bf0bac00e3930fd8776166a9a60da67806668b3a94aa50b85eaf80cecc3525930aa3c6343467cb460585216c390c3414b693939ad062c0ae1686eb901d4bb7ada13244e519468b567b986b0e4de2bde85b6140d91b0eb0c0a3d5c9f5817c340a16695322b2d317b5900f41d45165ba6878d198f55414991aba43924e59088bb4f2454718bcb2fc82d1774fe8d87b1fd27a22f94fd665aab7c469f5f30250456b5f66942cd55ece10119b9433e5ab4537741dd299a46046063ef54f1d201c88eb9e00526c28c15b9e4b44bfa47f52c5c70b8182d2a779da912d55d28536a54cf28170a964c4ad796bf880c51756a0e9262f8b6a8d6e324df3853880035904385d888c358d5645bf6779ca7a6b1de5782f3b91fe3462036a0470a85f68eb6b5cea95434a94592a2c18f4081737835926bc1c17bcd9dc8ceaf639b4a77a7e43168ba6c9d4018f13457d671a1cbfdb6bc2ca07438c04b8a023f56787b6291fc6bb201022028922bfec023171ecaa9ad263e86c0acf567cfcc4499ff4b47e99a65e00185a05641726be984c74b1ca5c6f20c50bc5225d55a62949cc32b29eb1c3738d456993238cb6027b16a15374312301f11ceb30420227be8d7454a9c1389a5810853b6c87a7b0e9bcb53e6bc278049659a979857443ad5726c51563f1c9a647a330e81109be3577069b68feb6cbd40a02ec5c2515657732a1c0068c75709c451b8a8f9986801e3a220234be2b0c8e34b75883bb6cb41bc33e2a40aeba29212279580074e67603f341c53e55421720cd63330351a65a533594294930be9a23e0e23ce919154ca75b32a523316964b89814b5c45496145bd9756ed4a68f430a09f8da157d82c25446a4eb4c453ae5bb44fc2ad5185987a8af5f91cc5c696631cc4cdf9c18d88c2234d0731677692dd10cfe4bb0bf9b0bd3f2740c1c295e20595e303d80b26369f0778e639747a930f52c4a47ab48acea8c3dbcadc346231395608d988fc4571f9b614f93d40ddacb62cd6968d8ac895ac817e746bbc1ba5c78d124169ccfe29c0bf336cb2b56b6b51a473a548d40b9924b1953b71cb19d8a374623aed5e3a97d588623d8267b33275f4251f581a6aa3bb4fb125dcad62e8fea2f393c204dc56da2e97ef63433136001ea6134c2d9c5c8d8915f5206b5a9c9b636c2dc55becdccc95fd162172c1b4dfb02f260b378fa1df69a98c3686c37bc5c913b2d5ee82305e00df786824231348aa05d331ca10470989377cab6f40165059c4ce7bec133abd777688851647eb9c12d053ae58c1731e93b09f73bee70853b3412a52434ffbc948e9204986b4cc98ac0d4482315990e0989cba62917a3ab07a4058597a43f8a365ae1994171294416da5f31970e9ca00bafea83359b6da56325216a6001c99731c57e50b50bf523ae35b665a51a777ef6b50fb3a9e52930d8148f84fc46ce8780f4a2a9f18886600c4c6e94b3d5eca128735e9211be0166b05207a24d79c30c1b9c91e89d1b9a1df246c76b6267f640a8070caea86129e8101327f49da7ba97632811eea6775eca3480089b306850d0232d26503ea7c96a1105990737cb1640893457587e26b6a37723f9037d80a58891330cf7d07d168aa1e24a761649081055681756012ac47c00ad6d77c3b37f010be113358466cff1224b7eb489d2576ac680882995479bda3a73572f0364199c940f93bbc6c011acb91553e2035269086a56d3c6e5a0c71823611373c85830c69eb3badf03c606b63fe8b24727cb90d6d4a22d77cbbf254ebed2c99e65bdfb302bd3040f152133b9243ff207b0f2a579cd786607ccac113543183b995b241b9a77a08a585efaa70caf0361b9cb50a2c6941d3a36482b1862a925575902884008821296556cc5d54b5b1f042d67d59cd1d0ad75a1c86ea9206f0a91c209884d07118b989637b98577b690cbd9c0b2e31235a3120906c6b4793683829f5c83cec5c634f0a62702bab2f9ba61da4a226497c3991cba4c178c21c4c420db6452143e10a369ace385c5aca0c990685dc836ed9046990b1fbda806274969cea8c84d440ee90377510340c723641b7c2b1c7b1aef623950481c2041b8a836aa51b32264c882abcb29ac336837ec4f4c70159084b1612019cac9b4b196bdb7ac2790073f1f75c438d4aa49fc070794a8a47a2b9fb6a9ad869cce04bbdc1573d302126c40a3130201db6007ba818e9d9b165da0a652fa832112530d70c75d5185e54235e34656ee3470efa78af9f01fd7403259a30071821668946fd0172eba16cb010408d587cc187c8a89cacd730a3d29d1611c9165e80953fe810b65bb4d99bc5517933bb6982d4c200b4d1558e2f6b5a39c3044815db383cac5c1096be1470e08cb2c79a68a16513d6a5cc3780ae530345a42573503b2e776acf8317567513e5a400a739a0e2bb785a44ba2d212c3413a07b21ba6d40089a7888d458b8c8f2b3c90c9ad789b380d03579dc03604ac24cad760e543c4707987de2c6a9a73a90130082984ba3d55471215c554378c5ec248da22705b235e53591073ea89c6074ad9d11c79ab468fd386af4c9a109456269947468a6efeb4882294c5392a49a5dba0bc38ce65ab9942688fed9563e1b7a5e92385c895b584e842b87aa06f1b1c8152444e9a04c2353205ba2177d7b0b3c9671b747f2992b1675b0df602023cc370e7526853374a6aac45e1e7048b97345cf265f1196da9103a3959cd1e93a2329631f4c5b178a8757fd9418ab51678b25b7b08b6a6e83aacbcb8271385ae626e778371cafa30c395073bf3109063a9c631a241198e8b000cb1d9ad499c0b1e9bcc4714015b6a77d373555f091cebb1132550495c54a2e62636879355ce13a0cf64263e6840bf3137bc754f1014cb3f3215796560a036c545569c3961c8c93636429a898c638f00953813bb8ca5e019f01c1db3448f9e050f2c537d3e723448204ea61c78622bb4c09a7c0ba2c3f40a174946c094f371ad05b546680a8fe5095fc7687d86b787e1adc472cfe26a70803861c842676191687d92159cf5456100976050406743043591914710acf1668bdc052a27f66ebf01b7a49506ab00ab126707a3aa60ccd21b4152941c5b936168afab1b2208a825e2d197516a4a024658c6023b32505e6d4b10d55b0b820007b4b19b3ffb2632dc40f927b87e47522b9b119ce014aabb14966a2651ba3b8e6b4aa816c6d3210f82444c57c2563af1b46b4caf95d63c0b07740c794383f252522233ea9eeee6b5d2101c5a3cd2ea2afcb63cf39feea775f6ddf4745f9be162d7bc3d8f950aa39642a290a895a91d9516ad2dcfb497951b6ded91a885ea66b28c8b42f21dcebeae089207ec643b5dafa02a2f21657873a39d4c291fee35c09153ef8a081e5a5deb19265e00d4c1a12ed39f08e2cd612d +ciphertext = 54a755cce8f3169866a0a37a104fb6b09f1e998df52a89c4112b5dde6c286326efd9b0f1b2f8dcd6987a0455cf9e9ef7a298563430a74aa78d3f3aaaf1feb4d09f4fe8752ab923e3737197944cf5b413c4d0356d3737a42f29b46c5e339b93d5653c45cb9bc9d71b0ace269a4b0cff52edea6a580d26f5713613a04116ba40b5594be1934957d47ba13e28e5080c4dc0c470ddda31733ba2fcee305938db4f5321df2304a4d8ebc8d2b2fdafcc174e2d6f6b723034765e7663c78be0d91e99d3bb2ff47b878747ebb17eddf93a93bb01696701ee91bbdd8f8440818c13cf1c5bb6ab6b4dbcda8da1363883dd207c79f575899cc0d9825a42a06da37176747d9cbac6fc251946ba50c63aed389b13e00b0a2c351a7fd92e4b6a57d26295dcfe31d304c278ac4ef24931132b0e6a199f8029a7ca26ec65ec6686f7910d915733e6ec705f67ea4394deaa93732d816166fa2dc8ff4f67c874a27711dcac232f26d3fa55b50ea5c3e03b2bccfbc0530df2d00a28f7f905cf3387a9155c0f688d020c53d242eaee5058fc8ff957b698f9690f987378b06eb3946b2d5e12f22ead85612c15578bea505be2538ea2e0e3242e66498016119500b95ab787dd33c06c2ec76eaec5026e139eefac28e86621b862cc12fe2a9b832af182680a2b28616633190cf6b5c3ecad99e3337fdd7dc55609b53b68e665970f1414c5aedc449d51b97382fc50d2538a878ea1b3efc8495de74b60bdedb1649ffde6690805011695aeedd14b8ad223af91f4d41eb9b676177abdb793cce54ec58e972e2ae32f2f8abf9d3ed3cf6508413ec4cbfb1add8dff2c968e90e5c228d74d8cd829ae9805bb5f64fca73c293eb56564181780dc6cbc39c4ea23802f4f6207f78182a79e03c69597092f1f02a2ad16ad9913e072010c378651876e6c7167b591498099c645d87a86b542bd50838060172e662269084373faec70e71f7040ea32aa4eeb7d29e6c127299d7309f13ddc0048ee15a4380ebd7b37526a21a82917f4370ed9307de6625c7a61753b5b56fa1f765f08925740d5279d1e64aa531ee7f7882d26d1d55d74e4d24504ed8614de5e6a3d79f545225aebc3d13c39f84073dc609a043d586f0c834a03b54c8caa18cb4b6a509efe03c0da8ca20e751dbee31777ecf97bc4a2f170fc715c40b365766a01e79281797f191ad30473198bad5050176b19024d4e86615836f37c2dab823d666832c0a87b75fdf95ffc6ea3c3f3cd1f421fb8d15551e2b2cc559e0891a5a88525965b6317de0d4dc09bdc557f20a4288bf125dd86199a005dc05aa80fb1e1ffd14e2a3736d8c2fa5428fe56f96defbb53f8c364bd924281cd3b07c0731831e56a17dcc1f7973a909ed5a7b5eda73d1be6abfb87bf4dbb59b0a9233ca34f332ef5749dfa011b8b4c774e0b43c16ae8409ccc86cefc182cc0d0091a365eedd6bb98d004355b5a8ba8dcaf5b0039f8dd5dcddaa7876de541bcdf745ca32dc6432beafd25cbbfb040da3836c9c14dc8068b8bebb37b81e01692ea10d5d25809ea7dfaae27a3e06235c61cee0cdfba8f9804b242e2169423e0dac637e32709f8b3cf5ca664ae1b16bc65b546ccf0fde4f6db4eacd3e5cb97fd64604a544fccc553691cf7f6e4267e11d344d93800c9336099543438dc617a0335720f829b734f66022876234abf17abc3e0ed75a855cd0f6f2310b9462638900145b2e1bc2f356735eeb65d4eec91dc45ed5056a63e5e70d74a3bafa1a5d74bc77aafcb73aebf50a9be2f4fbb2bbcbf75fdc98d5c25799f9fa4d27576f0f3fdc9a23a16ac462c7f923645829adc767175087f6effe21f41df3c4f4b20a1b67c0046cc044d623e2fede39bfa56207d1c9a41163eb30d25270c57373ebf6b0d531d512799edb55c5e9c0d790007b02c1d9664f533a36d2b95137cf15c35ab4effec451e224f11b8149a2ae1c24f338735d46566e46d28e1a2f2b769396218ed47351fe5cc47e023debbc2fda132fc207599461c4b2b307a09d9afe9a082cdc9f468aba9142c82cae6bd8f5ecd89c78266ea546f406b38669df08097cb1904afd3d0c75d530c8920d7071bcf9c0a176e3136e7981d94d7e3fdd79e54a494c5243cef54762748f4e16a6a4221ec355bb5a616c658e47099e2e580e6c2d2d17897ae46e7ff39ed14949274757d31a85d3b245f6451ab1d1f9875be34532155dd0956 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 6c4a52c382039831974fd801cbfba67ef298f737ad34d4a639dcaaed31c4e9e8c951f120a414339c750d5d9c8fb0802e14d72e45881495775616ab75c6f275f3f7c6eee0500a18970c3b603f6b4eddcb73d7404713a8cdb882c225ca829d8bc71ed00be2ac20101004c2f07f8a3a03a6bb2d6fc295d7cc8e09ab5f5883bbb58653b8b53699089b853637d7fb2c51884c554c1302241ef72a8affc67bcbfb0b204109fa851d5899579325a38393c45bcb7efa3124f2aaa4e44c4b5718272df6383178cd5d4b9b64268b08390f8dc6555be36e84905002b32e440174e821bef4416f99694c9e05827494a0f2cc40bf724f45863c804c3f5f758a2e166c39543e94230bcac001df42a64d314c38868f8c72a4fd126662b8717c98202966134d8a32e84b3c60726dc984a660f475ae2167e091703c30a484cba0633c8a21ec111453ad238b975ae320583b3c72058dfd349fa954b825f96d37e625a59c22d1c0be4e914fa6ec0154da7838b618279236362080b8a11b66f87916a81f91fa2c57726600049de5c5a90f005970348165e44005f0b877ab05566937e7db6dfc3559e966abb133a45a19288532b510b10f980c48da8a10573157875a1a4b345bbf9cb3aaa4c12b705ffe17a6d3c2031b469f43f5baaec03d1645c49ce482675a4739db2aa706b369248662dac54620b413490914254b9eea3af569a2c514b014e43070c721da0c482ca870eb37a8e5237e5f1708947b31750a5e6334864ae61c078059570c37131c1fa60c582933cbcab31e495894d10129fc556e805c0e78a089dc27ca19b7737bb0b931d2cce81b134509a441993fb08267c96667944cce094bb808583315444e81795b26ab0764d57e4605cb450b96a228c2ba97b24084835065902312699367b82339ceaf788437dc3d31c723548a4b886133cd2c98f512ae0658c496c119b718c281b8939a61453c2770110c159dd1288f95b71b93087e1a6c81c36cf466961b3712ca8597ff182ed460b7fa7a3face4be46d820b587a091297afa7805c91121533cb376b500d3f019de9822b8d5164b51cbeb229686e263bce393389746b583cdc1326c3a733f7c12b67aeb78246b994f37818f32345bd19b7065c430b2004d9bbce9729a1f236dd36657d755c4c27733a5d665125740080bb9fe697d8eb923cfb38f0ac41f4b91b265373662858835bc57e3f678d79720261435ca2257149b5a3f059d5db46cad01b8a99383f462749e841fe8b1a7c2fab2bde2b33b15b57c6929e8d50a5e1487e5b3171fc52b79245f26017057f06395e61bea294e4c6122585b579ccb9695b90433dc55ea82af072728cc6459e9b3c9c6b18513f19b8582472c66a02ff859cda044ec6009b550398a070f1985a97565aee5672eafdc4d357866c99467db035212cc201952206de8a11ca029c8c88dbe494ba2b4302d224a4126a21f7209d213904044356bd825560088bf542f1dd7067787c11e6808740ab8d955b14debb27c923e84c2955276697aa910c84426b3981be0032b81141bcb6bc62ea6800f4125790833ad5236ea27a95346a4e9954ce9aa8b9a41a55541b06d9370fc617c378bcd60d0c36aac964f9a3eab93ca22c5cd98fb170b66a50ab55bd73b72a3b9554d006d0ce021c005cf70a5a0e049798eb8352553737be9093ccab9145aabcc89b82212a7da0194b7c89a457360d5701d1f5541ab23bf8db5c645668d7b8738ef15b1fffc66fe829d29f28181b23b7b8b8f61eb7b93f09ff0e4af95c0036b351c60e0c2bbe121dda201872b1109d5686db90d733c6a36d85af1db4b62bb3d5827bf01ac5e567675f0e74c29d12bb9cb92b9039745710780c02354f26f5632555f178bfe965592cc39f8f934b3706ff72946baa932bc89404810a75da361d761adad55cee73c7b6a128db201a6dd3023df5bbe75d3abf3dc330e766b58ccb15185a20204a78af1b2e8b90ddb9368a2a157e3221da2b5384a65a14b186212f1b664e64f791c0fb403731518713c913d5c437230c42484ca8a23a86f63f9a3dbc9853290a692f44708a55942f9be397a9ba4c26c80a967d8744f8b5ba67e4121ad242a1c36a6201260113724ac8356a0981a93bc33e81648997692e961a68b349289421d892313641ab241907f372ac41bf649e64a28f963c21971a1ef90bfd760a8c9f89bae804e27c2b3bb3599006d600180452c5cbdc9dc1a46d1923f3cb6646212ea3ca370f918d60864f9e0a6b3c8c1d02473a4aa8fa9968fcdb60179e0714722a65149812216216ec8a5d3e8cd78a6816d3c824c35ada7c33db00403b0cc69c47a4f96029e24162a1c1820f343b0d5c25f2069a7ef6c2d2d66a5ce256b62dcb5e4b330621b874d04420e678ef7952fc596c4f8a60ff197ba62d95b98287676ea2893c37d9fd55f82535e0a9070530b74355b8f697530d8291bacb5585bd87264d3611fb362aa7acd806b7cb6138c76eb6e4cd77c7a9c74c4457a6d52be3db6a8d4821c5b6359ca250207393da50023b3224a9583915c6252288b2d4fa8657954cb3d75869a2014603a001f3a843e46326854696fe63520b24dfb4653bcb8629a6c5262c19df427c4776544e5cc3f1a82657b989fc85c76f06472caf404d85cab815aa5c0bc2713f21b5a021ee9f5b418b8885b92613a55b57048b13d6b8bdb8b18021090edbc857890447d899236a8951b5c1ff7f86f1600243fb2ab43a939a57c467b092ee183a9813704da10a6d1db52d11437f9b65f4527c5fac89767f5bcf8589fab1ac4c3597b9c48a4a0e06fb583a59c37930192c5269c9638721ca5658460b155571218ffc7aa2e877ec096c77acb0666060e6b9ca5fbb58e7ce6b5d0a11192c66cdc9b5300b60cc6acacbcd78a2df83f66487e6e930a9cb852f956b7ba9346fd470af194c56e8967ef6286f0261ab2028ea9e94d8516b1729b4598929d5935a601c1a16b2bab07348cd2bb1c097947fe62ccf167ba668900bd80bc456b2d1e857c1b57c578b2b6869582cf18a1b9ba46428b6b00ac109f7a8f832b963d8834dd4c2d3102bb3b934aef008bb7b8c7748ace598c0fd411b924ca8ce96793f715cd38713af361a270517829a42538466519c598480850dc2a0cd03cacc6475c313a8113b60403970f0830ae8838a097d852414368213bc3b69959b94011ad70c743caa6b831af4de1abbd3129675692d204a4fc226c26875c1ea0125e0b0e0b8cc899ea0f3ec6760a8c6b9072666c028d217b88f4d39b5a0bb462374bce7a7a2a710337281710db3932c6a8386a5787567f4c804177475ddf8a5dffd907dbc8882e649f02e0459e128df4783d402485dc32b6c33616ca34726dd0b2972c1c06e07c99db08882a2b88c2ba4fdb80f57bc51a2502fe5187367ccf73a750a3e29ab8b564edf57b31b06b95722a70e105cdb234be65800992936035265611105eb759e1cbc9c0da4e7fcc85c5a28e9c8785b2d490a6b70aaac96b22870e5b79666f867759a90153e09c6733cab0a4415150aea8bcce9db69efc07b7e8ba90d4b42b3f763ebc3ba1866bca13489c41a06239313c9af05f1c3883ece456ad59b9176765ef2b9117269523b26da6ac34ea685d3ef3144911b37e6038080557bcf80be2d17985c15ff7d5225342ade35bbddf93707c4144e6635a65d0c6f7e66f5413860318bf1ae45bf2285b6c5a5612c4b9709487aa439536c8c7975499bf375cd20b630d037818389c46c52a1233a3ba6c6811b383a7879eb303af5b70810f5534bc036536198fa688c48b5a1f1b3155382a73ff7a238ae5027e48387d41b467641d5b2aac2c4c13b6f965b5498d5a501e1e9b62a236034081c97b60618fd841c78a142ecb7e1f2c542520010b097f8e74570420968fc28e03511a27c86ae346abd909566769bbd7f02265e7b1aa8684850462afb1754e297ae41a7e25b5ab006d145e2645a200983a466472515772a60a80eaa3b4e7b0ccec7db9c3a13a523287008738c8822e08697dd9b25919c40daa02a621091c760741e9b92c128587cbce259637bc19ce09204fc8a71856f896ff7c2963fc9d435b2b7e530fe62774597ba0899062b87a3da1f0054993c9b4e653f7305aa2e1ae464ac9fe7c1a8f46c9f5089d09355209e3b8267a3307bb03923b750119c39b9c77cff3c594b42febb1090d396f9e1ccb9bc166b7864683f13e5575136d993edafc090ae007a29233361b5221281c29fb9cbbc77464a9908bd8c5414931de6a4cafa976306a7b29315b9ed1717e6a47b9834275332d3222352dd292c74730c94b530dc51e284bb87d3a2924a174782c17c04035873c0568e1a97c28a0b60944eb76f0f899fd5b166ddccbc8b4f99930a254ccc027eede201995a4893761b6571f44e0b4e1d446bd255641177e18a7aa834ef122d282d23481ce1915b3de1cba1e527720db5504dd7457f8346a1ca7786c7e146e58d831eb8227b5d9ce0c5b3e21d6a3e14a27c30a92f3a49b720c5aedf1b73d139d54e504854f73af +ciphertext = 20bfd050419416af4cfafd7ae9eb190ebd6a94f086d5adb134fef29cb5dfefe4390aafcaa828bc9eb23e2c9e97ed39700f5c940875b80ef56db980ce727882dec2a68b1ddbc627952b67d34946dc07666e85b3d79d690b2bbfe683aac0d7a768e69ee655c9cb190c45c5c0442a7429c0dbd6ab00ee9d199b64329c91738bc2ff3dda0e49cbeec590ec1f0ea3b331419b7b548abd75fd33415082148665a27a7e7d9dd0fdf490101598812414e9f86fae0976194d608c314c950ec8e9ccb51f8aa9b01c5c2be61324883c7618a018c5981bc7207a5e40a6ad56dea7be993d5bd4af097902e1ef2f67179278a2b330c28f4a9b35c9cea25fff57faba7f9d7ef4177e1d92e0ee48c1fcfb4d076b9b532a3abb69d2cc460f9fbd8b36a0ced8f82a22a1bb07ce1ca59b1b4741839939e0f98c1ee36371c843d56a0f1ee335ae2e197e746606343cd5bc45a4c26a90daa4abfa69e45fa7857e459000389b9400026685441f2612e61f78d22e2d1b24cb21e1ae5086e112de9741376e6c7d479a4698de51f6ff0d74b3b1ef54ec5c041841bfb01c24bbf5661a8b092bab3ee0cb9839078c6c4c79f6b20d2aa1892dee46c67c7521a2dacccf4ccbe0d6026ac3d763f812921fbea99ef8bcde87354f023297ad0a3063f1f82da09a2c691143ade66f4559d3a187f0a24aae97cb7fc8a1bd7aa3cb5c311f08404054bcd9596ea62666538f00e81866a1733b75df64352ded18a8b456b3749930655dec7379bf56456d2854c9f98896745ca25add969437370371db80bc77120f504c85582716d2e704395a4bc77c66475d11b6b4e61bee3259d29a3c9721e7ad14b45ed4087ea13acb8ac11f52626f3c89b041078cefe0b88b0f5cbf1930ced6f961f392071a7820aa299be5ca836e07e7307b0cd6be571c04f98cf13191414a7a8844398573e83d1f47dea272fc793fd07e9c3fa8b6a4f9bd21d50851965ed1f844a810cb5b8bce4811c66d222ab9814f64d020ab7e3c0031ee75e872aa306c60b1978415a05327a294707e2d400de191466db5ff0050ede92b343116d97a4d5d891fe83fa08c5e9bdc640213fdf114d46681a18ec4ab4711cf0aa7536ed412e196c02c5af34a12ba738a98dfd50457ca104370a7ce785c6bfea772065d1db87b08751947e49a9de341beed0ae91693fb44f74a0e812badf441d6dffdeb00931052911874ee9f503878c52160677ea8b4eb3b80bbc50798aa78108986973c2009665c6ecc7a4f5f430e4d6045d7ba96e17a815a6fc5d4928079c77166a4347a4d85ca64fa5a2bf8299df2a6582fbd9c7ce9b6311c8373f907d42c8ddcd321ce28af4263169e254c1bd2200ba6a6368134e903f469a5d00894b759cd3200aedd5088d8cb2067fd89bbfde10d02d76182efcc3d4ca76ce40df4219b84e2f86cb38e49c22196107b9ac1fce7889b553343322e449ffe22c9f39cf38df735cbaa17fbd55f50ad9cc40853bde97d95dcad8fe8f511f7d746af66e1a8753dbd734c88443d3413c0f683658620578f2ae368a33275ee112781decc6e6e537023ecacc3701d7e6fb03292fbc405bcdcf67a39dd2510ee0a315a4618add9b121bebdb62b84d65b9947260bcfaa8e025d6b887b75ec8461f26fb1ac8f1c63ccd32bc6f90396647dd820752f687a0cbb5f26b7294f6d8701904aa419f5e273b69ca31f3a9e49ffdfd87a9d64ac6d118f661da49b05193a3fb9c77f89b098f0bd9ada33d294e540689e60baf5f8d376fbd1d41ecd7454b935ede6019df0206052cbce4267a22e30c95d0dfb10747bc945c898c458be7da6626687368d3dbac2767386028816db5954d3c2dc0f50e4e86311e42055b1ffe925251c855f1b7692b29ed03e1cf6b82c23e0c276924cd7daeabf5cf5f21e97c2b9764e1aa7bdd9dd1455f339d9e5f4a74109bed6b555cec7204d21379090afc3281c6d5605ceda264b88da7e6245918c8d728cea9c51d270e60815eb5e49b3da07cc4b580d08c4a35d41512223b12b20b6abf761182be3ac786bcb56f420defa9130b315b6e85ec0a4ca01d917cd56eae7c0b85dacd6fac7cc03ca654e15d3462a25591a7923bc0d424ed8f655b4aa38810797adb836b5e2e6c281a8c10d0da51251019998e3b695911b16fabdbef37a64c56199ca5d41136b34bb02ed23dd44d81cce4277771382f55bd718b642a300f2cf7ec518e114a9a8 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 2996a8b08015d2c3685c0a82f372cb502193cf40286fb57a3f7aadfaa5c12f978e688049e9011a5c0c298270425c5755e74b3613689376042fd7c14e1063311a3461e0f3c99ec72918e0436d09b1828a6566f37f4b7a5f314917c46013f6520a1a8783b224985c691039f67c4d7b0347ac611c7351da7551d734c445791c58851ee2584f7c089fd7d647889407701b9279c7a78f640a52d194b08a7d00d05761d9264f96a5d04b5aa9313681191e49b9587b451349f69993d783fdbb3b351ba9d7e167a6343b16149df7f29b04a8b226a7405faa4f28e7307cd7602840129cc49b31c754767350fe5a35aa3789aeac1e8252104cd32ade3bc04dd33def66184409702a12c20a81baf8299c518794ee42c26f0102e92b3da7fb8542e599bfa3b44715b33b38a90473c087429b8d082e2cc5134c098cb7f0186c6948748bb848b67306523eda08775290b882033118125681a615e52c8da6e0ca0b18592f9947b10a2058c77bb0286bf420be00fa1761442e84a13f37449118f773144b6617f50b4144571e0b68777143afb3c202d96e64936d20382ab6715953956c9d854213627cbdc904ea1cbbade84c18e9350ee5c02915c76f7869858845ae37b133d48d1429a240fc25f00cb1f76aa8ca0108196a9b55cabaa2c0b6547178d112a35caabdb59c5bac0b8242994c8cf454346961cd7400c2f49043615f7e7b8b51332addf618ae83cc723c5560dc5aee1294b1682aef512513812bb112495f3a8c81217ea6079b7365cb6493016a959327b14efa204c9997bbfc428748f7104ba2c20dea599cb09889654d1b143a60f668c5d1ce9f7855f351abae06334e50830551531f1b24405334c29333d6c8840bb77892ac68d40a660b2a94760b5a8390c9267c1ab10a1037503d87d1bad6a68e401c57d826a2a9780df28987d2a67efe4c99bd75afaa5477a023c809e5b9e5d81a0af922d4ea151a415bd1b2bedc4ca286860c4f9bac49f054e9ab2d49b96191815905d0aaa516a8ec262b602b4a62465eb3854407cab4eb4590f47b7696f39d5b3990a8790a7c273d1f9321c0a34bfdc4936fa4b8d42088b9b5adb86ac8a2a1bcc3fa23e7d556767a863fe81870db6dfcd53f88ba14a6277df790860ad5b5afeb7ce381aa6f29105dba774f95b7a1c6bc5120a71b803379d2b9a8c956bd5cb00189ce8c8c348902c719fa4cfbea8055d62492e02551993e7b778ef94667ad468cc43ca1c6a63f714c83fe7abd9994b035065c29f59e6c9251698499ee928d6d212eaac4af1f906fa62b7b488538ef2452c15c2fd53b83fd53aa8c1a34e833628b57c04c985a8ff3acb83062d3c0b19f480b88dabe02fc6532641d36b9ac6e228625761d9427b4e2d35af262ae855484921a418ab98a6b46229eac588b3a4ccbf8a3d344a242b469b4754f133752c186196aa35d71ea9244cccb43f872dac5b5d072a5277225f05006f9825c46e2b06e699a8529132d2a6c163184e12185028badd81c06d6101f21767ef6467ad03c81d8b32e72871c5df855ff55c8fe312e8c82591c35c6cc20157f979ddc240ccdb6162bc2b1b583063311c483628b7b44a35cd87777e576764b3ba663a61c4cca745431fc70bedd9b160a909f2615ae3c53007d499a1898092e34af2f525e3ae22cad98996846ca86cbb376e8b8dcfba0a2262081c8093ed4bc2e220a77eb703971aaf3fa34a7ba0527028248cb3a5fac6f8957899fe67d23452be7aabca31b66cad58f4771989cf7bed6675b838c5c45d13f76723ab62b325a085c16d39986a81fd3276f59f55caeb25db5506184e71236f3220bf5645db372bba27729b5a00c27b39a309a9ba25c5eaa7570b282ca310369e354f665af0f4797e2949a49374ef4eb22f899c11587a0dcb079a19635065302b28983fb3011acd7992812ba49cc7bdd80067297adf2d15a8c4abebb40bb2b264cc4fb19b6a18a1d106611805f64921261548d176662f19964ed92068dab5c33d334c3906cd63356efc61948f7864a7bb9adb12551217096e74a06d710df18bb86e2718a035248f654bd238a577287da1889d4634c4f0772f8345e3937bb758b81def5380fb2340445a3a0d95fd676648767c8a7b88c3f428745718c454295b4b317fc779f4770063f1c1f88350950fa91b7154bfa7838eca8adc78053464cc7d3fb8ffa835d121107dd9a0a0caa2a5a3b6268d92b7fdb189bd29cc57c28c6da2ccd982f42517c1f0b2c58b610c1b64d42316f5d5a7b129765bf436e1a127088529c4f22596ffac839b4869b96c776f2028cc7250051a8ddc172165b752e191bfa4ba5d0274426c43b30b2cdcd6002c0aa0b74eb41c8306651832aa3812b50d0513a352eabf2c5193a0f07c717a5193bb24c7df33b5abecc7c6fdb9e1a4979124a7ca0d761949646bc46b024d217d3f12cddf1b1eb103c72c6ba4f214446b052e5ab12027934676b036845c813241f8c6243aaac9f92c508b1508a0182b18af618b443716f93328f294360c0038b717460eb97759b7751606bd54315a5a667cd7c1d91acb3fa068b9afb3211981efab3b40bd028517415229178aa388b1749a8f8e124c6a14db3d52d73b5523f0c722fa454e714179e767a8e9c5e56686f932472e5dab4e175b2eeea2bffd57d90ac6588dc3bc3e783ab70678ac97353db342ff115726bc34912ca2264b5a6216c3ec924d9e2116d16cda5c37878716c9c9957d9378794e00e38e3b8ab75081cf135d95032be45cd46376d76f22a0544b4c3c53871da790c021cbeb2523aa907f58ca1d44790fd03a971d5661c95546b647c1b5c36ade62d4b199a805389b5a724e935b156740e5b61435302c8b1883d49f1bf74bcaf0bf8bf26c01fd4fb7416448359a2954622514f529828a635e2a71739e11b1dca72ca0463220a05dc50258cc4c5e782958e18c7d4bb54eeb791acba4045570e35768ff885aaf061890ae85009aab03ad653966499dda4c3cbe0b1d35aa6cb4aa6fb68aa16aa8806b06d67ac7ad2c6876b981994ac1ec6275ae1904684915860122666b2a7d860c6c39aacc7ec3f9fa62d7de582241037c84798d9515167db4b27293ac7d203da085d3f088df1ac6bfadb71a7729168751f3ab6b08966640bd2ac2de91992551422f9015e938341f6455b743fc0074ce9a9ab37856d02cb67e52b6dc613bee1f8aea829465d843daec66b4ad74a47c73b746436400b88f0fb7cfce92e869b26621ca5e8c9a262764be79a2870da8b02d872a6a4643c70b7294280b0472ab7b11fe4ea312d98744f1313a1b42e2ab765325063530689a4d42ac0710816c9740f9987d9dc9799fc6300b21fe2d779505285128173dfc20c79326e10d77c5809c7958077bbf6bb9d51c0bdc3c54ea631e3d16132f1580cd62a828096aa38530df7b1425097ac5b115dcc816c616f8bccb766aa448e3136d78b55a3e9883b22945d3183ca84c8d6286d9a52895a988a41c420ea7622a1b897b193ca0dbc97a3cb4d5bd2a58a13c20f1527359acc8ca150defb6f54415e0142813ec68e3ceb8cb6d52de134bacf47a2865598dfa03b395b80d1841866874a2aa7a3a623789de8c0e9857a77c470c84b1f0901a1d1f0236863b8f989429c48c8e57434dec33969d68747a365f0249e5fab6360535b3cd95e00ec682e93adf992871dc1bfa2477ad1d3790bba1fdad488007710773a4bfe619f63b017ed4c718dd3c2768b5704100e6cc65628e26753e3614048c5918c238b7113e774bfbd4179039ca313b6a79770cc1d4632ce12cfc0f86a3e5071b63000b1106073093590a76a7bd031d24ba4e7319c264a7baf30190d8b8dc3a49dd6cc0a04a78efbc65de7d84c223a1fe47b7c7b622075db71510bcf4ab29b1d8328ccbc00e327795e3c9124d2aaa5b16966988a7a347d42dc8479c5b7973b04ddc7b2f2563c4b5228979a7b08bc1c7a4932880083605a9e921921373c3a3923313b151ce374cd9e6a92e8e44a09042fa8e67fea15c57ab1784dfa7f284057c5902614640c27f92fac15b36e156999c63efbc5ac7a662729d65ca1a05e638605eb831c3f150295e804cc23556cba023e5b2c37d61a8d7a08c5c831b870ca92986b26f42dddc6c5b4751fefe40e38673b89eaa7296a61c250589c2ac2672a4d7a97bc55d115b4ba5b5780981b5c78d075955be49a2938549eb39e0591549e3b8c409c128b7152d7a33abfe6a9c0e37a76fa2ffe6b168d49ae83a005782caa531448d1b251672cbf49d3a2b8142301432cceb633c07194c599b79a20208b16cabfc14f731b1b2e4a87d03768289bc895e200824187a063c071e969cc2871896c9e5a3d7291b907a72faeccb0a5cc5932ffd624309ba1a8a75b5dfffad6a80048d2d94641f59c357cf714e1663f3f4d42e3f94b4b3e954c9ef58a26556b73986954234b72b610864f4488e38bfa35bb0068f332254b941fb5692078d2d9316a9620085b730cb3cd2661f351f2ac8d69bbecf54cf850ddd2d69ad908f9 +ciphertext = 18fe4b773a8d269bc0cc1cc9c0cfb265c18c12edacaa7a222c1e1a471bfd18163b75fbc21eeb5a4aeb383ae68a0de53e21bcfdc7343e9dbe4d36a02fc5799f9b7fcbeaf7cb3033372fd121883701c2eaada4fd4328a39221f175b3a1a3f9bea2354e3481d55e2a2ee714a7f4e023032392f4fa4967215f84de164fc3625b92e487206e6a382b240a3b2f294a10282dcf22c93a8726421ffada6814e2684968f26be5b030eb25b3ddc040bbbea92f3a118c7e98afa1f57a986ab986d16a4eb2a4d993abc7b72504aa46941386996a7cc383bf91286336aeaf318d2de6fda890b535f1bd6f13b147986bebc3131ee1253c90f302e24b5d6be934a84cda7d2a752d7a2dfbcdfc56d8f65f630eb3e57f3c74918c289e6ed6914651123d6617c42b3cc5e36b91ab7aee58d31a6811b91710895f5b36d175a485e9a3b66389c9942aaddd0c03f240f9897ef649bacea860df3f47b2208e4d6ec2c8cb471c74f84092a339ee1b4960c078eb4ca6ab0101023fc33cda1a293c1f2012851b1db4ca69d1b42d72eed5570473c99c60b2eff55289af93145040e5294eb18fb3ee137c1ff144e19fa89d1dd7ee725cc3fb01f1844eeddce6f21c25196b207e47e2d8246b9027654a5775530bfec74c602ecbf95c1733787e27b63a7bceab251a9062df91e5fece8ac253d8b6a2b5488ae24c1324aefb596e507eb9fb8183d78e737a3c06db5185b4c43e1e8becc52d1137f42c9b1cd335c711de4ec27dad590a46f21866b73dae36cb7a53d2321d737439a8d90f9ed19c2179c3533a4066f381ff27d5f471ca7b28d60e719d204a6ed6854b486630b1dd5c7f181b3c55187c096db6161637c85bf0cfb9aa0fd27494d54ec59f5fae65da3baeea1edbe8d5c978c6554a6e01487f68162eff9e6634f0cde2dcc323a5ed8b7f232733a37190353fc9cbf5667bb63c5f4579e03bd288eeea8f877f23be0eeca75b9ff039805865790ccefbf6c4e8327b9c9c4673d7d0f652fba564c4ebe3d32514e17cc350e824d3675cc65419964167ca73d1a87b16ace71a4dac7853499b9762b0cf0dc1300023c68e5837b4fae568d19e8cbdfe5f3729f4b24fdbf87a80cff2339598c8a1c103cf3b61530fe84ee3750ac9144011fce539a3e7e2b55747f72bf6922db38734fb189d1dae75ccea015fa6935f227ca68fb79cbcb8d50ba4ca1782324e7e3524109d7b4f6b0cdb4cdfe3b72e1e449ecc71c36d100798b7fdd387f15a257e408eee23762ad475435fcfb8bd31ccfbd645141c706bb5f667b7504ae1f4dee13afc855966e677bff96ef32de6ae2e0b543073c137dd0c30f5f40668dbffb1345524b0dec1398d53f353c023ad65fd10c4bddcd7571e0f9e8c1cfe9937803aa6a4defcbaf18be8d03b08e75603a69577671a754478569804b7b74a8a2d810a0637d2145ef6147f8e10df8425c034740e759bf15f12939282be15267af32595b8a4d44fb9bae6daff06f0b4a788411a9b2c12b9a01170dedf5366575847d6735194a04cebd2490b2edfcfb58ef89ee2bd72a05d7c59411ef86beccc8ab83f75d6e072a51598145fd5f4f6228a21531b59eb6be1a700eafa7abef01e741548ee7c8d23545957c2dd9b92d8890c928523f1039df32d6d2e1e498e775c7584561742e8d3cb3564d850fa2ea5337cc45c76b74f474e6f83720d65352bfc0a920d7d939b6a84018d3c64627ee08da25f7a03fca32715ee000f5e280709d547ab50eab14c9431acaf0e2af36fac2a6be7c8b02a33d9ca7e55ad08e688befaa09f3b79b32502f1f9bc9d682105c3a337a0f15dca08c92eb84fc3c18c871396b34a262831b8265a4876618636a90efbfd14d05287411fb7d895d882f3a2e826e58a7f102d92cba58aa44048220a6747482193c6c1d74fd72952a7ed2de82ad0379035028032c2652fde93806e7200d5f7dd40c23fb51dcd330bc5e06a208ec18948cdd9a67c1b529fbeaf25d2c6597d037f4625398e9a5f64f0a552b33938676730f788100e4daa8de8b8d8ab59031a7662901a62c51dc7599d0a20a872e32e83434e15002973d20b9f1563d17b3c631b2c5e1a11953727bb442c522c0d276e4cb5e15e3dbb1d0532346df4ef873b03079549708bdaabbe11167697007804a4f4294778983aa1b4559f96d6d94ede386a981de3c39d70bdb742d620a7c30f5ac05e1379134794c744bf94698c8d +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 2b2a1c3f66b751d8c355c18141e51199241be8711254956490abc69771a64377900c7215deb5affd9662386ca17b7670174aaa30b023854b176d654dc215515f9992e71948c27574d6e221b2a5971b7a7195e15b01e1c5e537994154890c1c1da07c02ceeb7131cc9fe8f485b64783201b080389ca2f24478ec4b6407744004d0396f1680c450807f6217e70850b160e5799383261afa16737b2b25a30162503b4280d03a883ac520b182a582195982c7d8ae75fd40c8fd09c23db4451368754b169be57d9aebfc8243b102bfe7a764ad609eea78ad432bc89298dcaa52938c5c0eeb496188a9524da95254bc61c8213b85c0ac65b1b5046cfc2f5a82bb038b44282c1d2c5309393a287c22c043e17c23b6ec37271c063a5f8b5690537139a83e1556c7591092f53ba13281585b05d2d0c5a36bc8582a10174f11a86160fb249685ad426a129984224926f5440e54202c5e814b1622d82fb5474c68939593f51071ecec43d89445449245e17134b2916392d2057865703d4f25cacf950302724f6286b0f33afb6524d771168524cc5887c7684b263f8f8830c49519da28318a4bd2dc27175c95a5af4339b00349236b715142f51d7c28f009b16d110315bc1915b517608a7667a41f11863b52aaa08e1999d444f0963ce625073ae75c84fe199002b0f39d457bc587fcffc8af3b97125d703fc5977b71aab850a05f3d77fd5a4aba1aba0a7793f72a915b5647c1d07af24411e0c033e0895178d90ac0d314020bc0c6fd83dfbf024e71c2962ac47d1a742ded109563bae2a157766080230d1843ad18134b846aa7c8a0878c535b7678195542418baa3e260775151ebd953a0239b29831b15f210e829b629f1c889d955dd53b9212615732c2acfb28e9319a075217793922fa09c36a5e6874d9b538dcc9954b063ceab21c5a903ab79c4ce4c3032e53181f88dc2428b7fd157f690b2e61461304ca531e1c6520719d8e53f0122018f9281fd19ca5df634368969b5c1a3ffe3a76788057ff41e412c96a796a220721b9d869b65a3706e338b03f97b84c6094204613e1c7d2b4b7cdeda07329701f329515f8bc2cc047594808186a87b91ca49ba9067c080cbf9a70f73f475f25a2a6105922e7837966c9a0e493e73447fa45620fcb9185635bfc96a8ed98b8910c72a99722cf4f78e0318a133ca044ce696518aaa9406b85dc8b88e0650440a8eac6b2848902a0696907f8b955ff4bfdf79bcd90299126703d7aa0a64d70ad66986ed6637a551013d74b6f07c9329203a07675145c807f2bc723b45a8de45c50c141a16ca7e26eac1efcb6e7ed566b6024effd7ab70b9957c594fde687eec11852ebb1644bbc7bcd12561721ca545024e2ac56fb28c9085836a354308c27d0cc49709a0595bfc1662b4c7c7e75c3556add3508b9ce2915db87612294b46ca6975f61371b8200e7380cee4af2e0433b2a44e41c68a71999584e29c42cbb0a93cc8343c7bb3d8720505b7fc863e50347944d4a05ef6725d818427751e51e7701a862555b0a860c10f6b8b41c26422d1c609c76bcdc3b5039d4b98eca465baa3504ac284c9320dfbd18f5be1b678ac09fd0aa10cda3b89ea6dc1a140aaba7850da9f92c800effb0f0ed5b33e91b37e5c278b3c112f9c8bfe4557c2848f36d660447552b1e27ee97596abeac03988b31ed0bfcda59cb7881bd8e80091069fb53c4917b3b7278925b9e1956fb46f0d891c4c392db02011ce4a235bb5bb730505d3bc029443832b657c218519ddb885073a6b49ebcdf5f8a30864b99f8a052706bab8689d67954b905b015909c53224b78cbb5daac14a8d51814952420ca436c16c976c46371b133ef99046d37c7c6347b0dbc32f0f5c15fb4b875cb61d250bbe2a3059c9420ff2803ec6529cd3aacf571501edf06b8c74ac91db916fe52e7e812255089cdef4a841f2c768912d2a7a2b34ab0dbb3144fc46adfb02cd6d984f0640058152a661da1f7dd05f2f511140f5c9d0c669c9d4685347457c643896a4480e534f0ce0aa53088a060a491d8bad9dc1af31595000d279150c2f8e2c9c46c97066016876f5477b517e9768caa8c30f10eb6143d92fa019ade9952aa32824e482540de6823ff931c7bb93c96997f6e359c03b3575b812cb1a3a9c2c2506fc0c3d69506b032f0f412793056f7f8c01206c86b5ea882b64434015c42079240b190b78e747cbb5934f808b431a1babc122282730ed512f370280b750173d71c6c12b00859702afd756e3c171b2682a9fa74bc71a4c165922fb0068f2a06b48973b3de54df0566cfa2432ec274422812bb0f39db8ea8148c614095a8fb4f6a09a424174951ce5b2a3ce43569866bb0c539ee0367fff004235783e9d6940b303074766816b63137fd04c53dbadd460bf44c5b2e5d23f0dc40247f980030109970311fd0792401c60c5fa19fe1c298ab1b77b304f8f1a05d9f60d7ed11071a32e403595a570ae36e9b67cea62d7b1260cca820a3c7ccfba54a7c0027a4cb1169094cec84c5e1b0ac2f85ea84192a8a9c393005bb12492182c7185a41c14812f6cf874328cc184159733d5ba87a269feec977a8002f1b95966a7101b598bdb0655ac50a0fae77d7a10a99a77184ee3075fc1bba5b5998537873bb143b1d1852f31b6bc42500ba877fcc190973b762c8b1f10d81e7a7c3354ec8e19b367767107f8864ed95b7a98b40ba3a3922c6285e9a08cf00b48c273515a3828aba7b10d395120a0bfe728b8e4767d53167e20a26430965c60ec12c5f902b16532c7f639112790e1bc8962093c2ad4aaed40b05cbb89e043814eabc7599ab1b13660b4b90f535c355e6858eea773b2d28edf863e96a065e8106940a5a442672b63f792db2146be990f05f84d9462bd30322424357f58462bf55a252b0c46b81a891fd320937b29ff96c5a5c21eb19c20ea75bdf1a349086c7c6be5b994147466485557878da7a32bc43cc19d83831d3a3f17564553099bda329262552b083ca76a8648d60075c4121c7df33548fc2f1e8934dc189fb59ab4f9845d997464411834fdf67c4fc2606fc2cefc763b6b7815ae352bc435451e636dcb4a9099422abac25687a67a58ac4db9a49add35aa6ba0a35f5885b789833ae42c5a328686a14a65c09a26626290a86ccd289edf0870a35cb189d71a8b8b17d3863efd97c47eea0377a12ac78870e317195c84845d6297f40a1ec3178bd66b41e0e650476cbaee56a1d5b15123c4678ce09b93a099bab18d11b74c9a851d21e09995f98c8bda31a4b01716aca9ae4011c1a988b613c7b7d573c7e15bf2f91c081948cb51bcb99c29f2ab78c3091009f56b36d5a8e90652c634c1d5dc7edd6262a3601d51f6ac014b0c27e4528d35b7f0f73e80ca7179c782979266c2771ab61c5c19732034acc83c4890b8a81bd9b21fab784779f51b6689980c4458e71824adfabfc3471bab747fa24b7aa73c29ed585ccfec8010390e55a0482850594e912098e58056b6cd390c41f588143837adc2fa29ebc06c06555d40430104430d319b8b0f86691df2b8ef0b055d174fcda2b06fc115178954f07b4f64fa8f7af846511b6824607e9efb86c9f8c9542c56e407886c18298c5943a20bcf6c424ca51c57fc0295c95421ae6017cd249eee3a0fd3e010f9066c2cb98a05e88bdec448db8a5635cb9258f50182467910f0210c330fea62160bf6bf7c4273c81c4857837a705568eef1593a0122d29c63cb5487917b9d9afb515e83bafcb08baac7ac4993cd2dea5aa12b1a055b5498b33a36e62729870098e5c075f995d2c71de25302426b24d964bf578180e4d1ab90b40e706a6f95908ed496b7eda3b0e5025b9e49b371d29be0525a12a9066c657f79109012609f07c4388b94cd8641a52bd16a78c8ce2b80c075f572b15b82a0cc9af29b0408baad4dc57765b275b35961e65034a0bc24d4021d86387f6de7aa54da9af6693944a555ace2715de80e9bf2841bc72bdc6c5121c4637ee7ab743a0a15fb6013e72a2f74b91a5375533650c6219b828229904a048e538548a4561476cb5d0074e37bc8b19c26be0bb2473ab80ecc7150e926dc7643d2ea71aad3ba450c02c266743c802077c316ddc73b4b5c6773fc684bdb94a4ac53d56732262b4f9f8768d62bb9930a132b969181f1a55c7a62e43acc8997be42d70ea95049927897260a46a1b40056d95b184a15c8d17674477b8f5971f97b20c8877792a6b54bc89ed0d39c56bc85b7b04810752d0ff9938a253244b207797b8a38295f788646f7ac1e2a59513fb17d360ac7984422c2250c903675a1a036cce2479533a99515cfea8271a9b5a1aef9f3328cd60441bcb67325aad7cf3ae5982a015a6c316f37b9c0e1e051eec696f5da1fe97fa797f7776bd1515a4a2ee2d2cf3422a762ae430350bd1aa8abd7f5062a87af6a54da295920e852bdf3a5e7ca2c079038db94473104aff30d1a868228d95c167019524f2e63e94840f9a9143d203321 +ciphertext = 893bda08bdfa18838019a6a1e50f35872599b37ff7e53990113211240411f5d3cb5bb855e3c6eba53d45a73128b47db0915f237dfd22ba45d0f4c892107138f6ee055aec79ed6a167139e4d4d3c8fbfdad7c862926f0993415bc65b77a519766e825fbaea74c53d8cf05dc9eec2e91b428f61ecbf5f2e816724aa8f2cafc0646dc4299219c9e7af6eb3944d091e592d81a70fcf95bdce81a91dc9f197b95d04807ac1fe14bcd45317f1d0955e8797de4f8b42fb9dd8f7de69861ae45cc1f026d2c96749c22cf7988b51073f723301bb05dc6b8a7bb4b6aab6f39a08b5f3901b20903585c6cf284def8685f2b45e63355735d44b19823c461ec7812fc9603d8f2ae0e70c220a4fef621b7de4c99240a6706f860592e7b16220e648452018b78ebec6b3031484a6f02c937486a3a0a5d3d4d334184a62e665ee91b109d2c57140c024b587d1a2b514985f7387eb8542775bab8ae1c4c17d0dc74bfb7d58bed451540417334d86c6bdee82cc8c001b5061cd79629949376b531a6e37a1153d6aaf49ffa4f6ff8aaa1cc793cbe5f20dd83dcb1164b0dd66c571584de2dda1f0dce7b8e76e5648c0f86cdfd3c48dcaa427af5b795d26e1927a4129559feb23e14f75c0e57d1372f27e99758111f5ca274c25559484ff796964f5a5f03b3f4de26552383d3706624feff2e3c2efdba044a891bb7434958e2c5631c6d05f8205b6f3d8a6a9df5c68e4e0f94a8739080399288944b9ba9ce0407fdad235bad35802300e1c29c7298232c4d54956d7380ea5d53d6e3f59c30730e9e4843a71ef723096b3b8088c8fa6d2f18fcc506490a44ed8ba71c0c8df3ddc6eef6181cabff10f98da37969a0a353d80c76e00335859db6ec110e42520b13cbfd5198d8eac80022927f14911230e8e6b573535ab31d1a821d78ef651be290c9f744701b6f3a03c094c16d347c11d2ce944295b0977fd930b1b6d41570a4f56678d4282f11878de375bdfd8b3a78aaf4d297a5b84e04fed230b06c1f4cd387be6307edbcafad406d15c8f5fc05e5b35372a38ea68d041bade5707f3f2ab9c7decd2665a957e6a5af0d1b5d48830abbefe9c3047886151b27523473e77adad42094d9c9c8c6036df7ae291e86bd3e855153b24a2892463ec3f8ad7a5a7bb540db40c692a23914ee3d81b2d78f44e23cbbc0eeeaa7ae0d8f37043d817ad9823a353e755e9ae86e0f64d8a30aafb366d1a37bd2afff2d3e1db43ec682e1880645d5a5831621f2fd9f2073a5e70ef07f55fb3e5e187862bfd57a97cf16daa090bb01b79ae94cc14885ac94f3e7c67d6d007a97b126038f042f3dec3d9aa1cfe18b1d0e35c7f03ada0da9242edc86a2877082ae32067f35640dd503c86db6d7a48073efd03183be28b4e68c8eedb1ad48ab96f9ab37c8b6235d071cf6db457e9d6e086955453e3670af7dd6e2281219b15424f5a3a73b7bb0ae3c56994bf09b13dfe85c44bda0d3a758ea637e317c375e75e77641eca426a7a0726854b6c1c57c4d20ae5d0ffb23f5b171bc27e3807841a70b653daf77147c664dc98ef555bb9c9164fe98762688bdfe86ff2475ba1032a4adc1d80d27f7d0e8b1d00ff6d66f1c49488353570a735dddd15086f66d8d9f038b40622dc1b9af8a3c5982e4bd8e3cc39b3d1cc145f29ee24cebc3919270ab28df78cc00f302c42149cbe6f343f70b6c3d9809bd6d5263b45e08eff43b346fad943ae7c7b013d9c5d358512d491c90599ecbf931c526d019214e1dfb002a77d4d6907d50559148fce1571fb5db354a6510743a2c3e0af7bcb05b3afa24a5f8c3d3ac67f4fc802ab901b3aa2f11b39bde43cf0d8b38d3c9b2b11f9eec5b832a4cc1ee2bc9a91acd32f12a665ac905ce8fdde989ee4888bd1a9e9d10c11fbc1b66094e8f20f22a9333efcfacdbff00a238cb89fd596a764bf225b245bb8273d2ee3eb3e188f37206630107e62ccdc24c6818112587245ae3d49f9ed9a02210979c39dc783f857fea3987c0be2272d9d85a02190f66ec1164ca5651551645822c7be9f124c1b2af7927c902e96bcf7e5302c52dd6fa102c9d09b29d3cce00dcf6e38e07f9946664e6b6cebf97a2c054eb7ea01ecc32496a096b963b3f0d37bd936c3ec0fd7a92300cb6e3e76c087aa7617c983621ed753db191866dfbdc3b03d9a6569c42a5600dc2202ba384328472313633e65beeb792501c986c82 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 77b19780a5aa6e84ce35d25f3a5c2f90a3cbc008c13436aeec2bc0e0d33abf9bc2330a1c2170461afc91181b49a112c4a1fbce18663aa71c06a57b606ac3268fa1a039d4aecdf80d344aae2d102902291803581e8031cbc82954f6149fb0e11e2a19688ec319c84518213a7502f914d62ac2468b11593410fc0683e3872660243e81cc6e65210682f495ad1aa788c7580a31bdcf867c64c70b6ba01c12889723cbc9f0c64f25ca52f275c130cb553a5771be0c0e1a391414b231c2e9b8110c9010a7a0f7c1b98df5ba7f5cc629d79b0ed8ccd8a580c1149caaa30abebbbf16653d41019e52c01c58d5b0300463fc9a5f62109bb9805c74473c19790e7a77ae0acb4ffdd86c90175ec70b39844c39944132cbb4441170c81541b1813374ac784c7d50681c8491f8953614bc7ab26679d50769ac43a34f46489f073ab481ce329c8594409f8186bd35762cdacb34e2427aed72774fc550c3c9ab7e3069b653b1363b99cdb75aae70b55e48694f5326f68baaafdb48a9f17e62916e0625ae3653b3b819b9ab1a6af2f831582ccb8b2a7b1eb71bf4c30c195507a0693d2cdc1e6ad96773026fc17a461644ceb950075532a1b4e77dcc554b0149863ddc0709fba2d66a77fca20169971a86d5880e49b3a3b45b8678908f69b719ca5949e8ca2b42bb02e77cb0b68e4a7764c790c480fb6544058c5e5c4f390ac348f50d3a94295654b0c0c21d9328426d93663979390a0a53d0ec9ecae26009c2403588a755c7c1861b85db61c10c63a4afb01cea45297560b06dda3e1b79869c6790aa2754287a53638397ef43cbe2f71fa83872df88979f4a72e84cb16315784839bf959a268062b45de54935bcbf4500209ab5990df02bec3672ab7027ddc74bac6259ae802e8065bdc8853efb9268cf066f896507e2b13734ac5017477b657aabd3f72048450d1013bd2e90b625d9059be208f4097959c4b4b6566199398e3cb8347a268f5695a12f3343d0d5307123747ec3290c785119f21f1eb96807f073f4c299da21cf48316c6b9a39c8bb9698c534c0f4829284a105ab2b72f2a1b4dc45fefa918e0bc157cba00e25a12e534167547454431ab59b5c6ef87e3844bf82e7b0a6c04b5a427b93e7ccabc54af0c60c9435b05969ca5e4020cbdb7c08d2251b49baf574b1d004a18a3c30b5508408a47c787cc366fa8fabe29deca559481c310d181f9743bf0cb77b4eb21137a44a3e650712b14fefd43ea6909555d03e37333e13703c9177037d9917aab43665bc7367234da70b2ca27645c1d41ec1597ba32cbee0f197a4e9b97fd24fed6c1394a968f0ec0f0fe45a31399b45910b587216bab4cbec763352c62d848c1fe476434a7a951ce642b7692f40e91d9839004a1b8139f988be958d0e93bf5059480c9c22b792a6a131a9a06c5f36392d78da11d207650c18b90046853039b902eb07118b4ff0d28f5b90519541ad2ea06d19950713a16287e30bb20b66328b84f867831345cad588c0f8971e3823c3c861574cd3bb9b28b6124b6fe35032ed1287a1f775454ca2878ca62749208f61271ad358b0e579c0293518cab5f165cb144774b8a3ae9c459a6355a81c44a4169cad371009ab160ec76549f6860c14fac13047177276a4ca1248c15c4238e69c5c8a94d8bcbdf3e830e3105bc37a823e0316611aa7ee7966fedb838c6963c99ac590f91b461c8f877414b3ebb5b67234965833f9b85133220b899313d35ac3d414a6dfb40b7047530f26b6cb596bedb0449d332f8aeba50132389c15911f8337329ba9f3374f6afaa18d330db2638b65d39aa591ab633acbffa9551cb3293ce4233e4bafbdc52f9aea795c431fc8f54450ba6a3db18fab82a95a07b95571c1afe25aa777768c24a57e742e094239d1fa21d9cc2bfa41b8f37c8c5a66bcb2a0b166bcabaf05062a1a55d7b3667a9091af3b3a7c7651961c36f7e4ab9602a3be31c4a2701e06710699d49d42955e904023f7b2842833a58279ced4f6cb2713762f95532b41819085060e7995ba863bfda3b6f67a95d1f6a7951ca98699cc6d49cbf6ea4095881830845d9c736587599a1c498cc3a66399c768f393213cbaafcb2b80ab900186a253f9710d89b31226747902c142962bc3722553fee5b9eba05f095c829bd59569e17fc2e108c017869ad0649a768ee5bb20fe7370a9736a15ba7f5d72babcfc691b580909a15a53a97f64e52d93033cfdac95232bcfde82a6d2fc1a91a609f36a01eb500dfe59ac6f0c145f7417b9639d6e192a79e4a761345ef9f0c1f0e704a4b17b4b9c1caaac26c90a0c6330165d780339804620cc9091d12d22e56e6657acd825bab887188f71be3a743f8f020651426240eb463a4630aabc994a98adfc686a09fc9fa7c1adc8a5214af287763687c2873dbcf213adec3d9ed00904bacd4536bf2ff089efb1c602e373e3308573f8015250b67bb9b2440805aa037987f0cfe6dc123cfa22ec0964ccf23333eb20eeb9a874ab106dcc51ca0c7586611f44264655d84ec9865591d5475eba5a61a226b420919a698e5ce37442919716a66d4ab6246b48c2b1d60689f71f9d549a11b0a6b8988562f87af8f150089962fa433a530983f0976c114a8e3eb81e49daa075985a5e58151a808ae083ad16687bd7321325d28924303c0684b68812af49458df6516afe28366dd1898e2b6b25f1b676b35ab096bede486f169674d6cc90a12caae9930a8056810cabceeab20df02bb66625b08a8141e36680ca109d6d61a353d5619f7543bef1bc69055811bb9cef4907777559d67700db00898ad19e11c8a7e45484a5e02928630a642652de473d45c84f322c92b06977e732c8bfb0427b7675b7c030fa795b9686bd42573600b77bbf847b5fd326cefc350cb795ff09b9f37959542ba56b99a48dc807e8503d9975b66a14736da15235a3a7a3a99fb87047c3c2557b462152789b95816858b7bf1908993124b58c4b19d961a4176728436a12c05371f9755c9f819a745c9ae5c910a2826972f72f55b5abaf4529ad8653eda87a41dbb7d3ac9d03a0a3fa602dfd814caa908196e43693480b32f92d494b26c5d79d908943fd8a9bdac3a53ddc2ac10326e47c5c43868d1fa2bb651216f560ad824a51a2500c1f09777edc241d43544299c33f7815f42c385f9c55ae12906ada1976241225e1480ec6974e17092f463ab1bc80bd807007a5c59b84ce11b097e9e1c79db6c0e54984c257b1934c0de3ea5ace69caedd74b93b30e0c899a9c352bc0392a5830c8b05240ab70b2ebe2a2569b7433db5c64500edceb786a168411494202f1a21b1cbeb9163d47b573a8d77017f7607707007ac1c874b7447c201bf3729b7fe6a815185e47698fe7592456eb023eaab1d312b504a69a7279862f41cf886589d60322d4d3ac13263568235ea7e858d7332a2c5573190696a24a939bbc8ac701c6f583cf10dc7c8a869cfed0ad2c524c60a837fc7239e3b89e8001c909b1c362d044811b49783890ca943b8e9431ebb479d73b0764170115268a693491ce498d1d533f48a4626e926376533e590329c1b67e7a6686e0e1acf4b74d5693c84db255da7463849244c7d280ff3a206be6afd75b3787eca770d162b0b005f4c228dc82cb4a80b7ddeb3032b49ce6e0c24c8a6f95352b39728e6c559ecd7077d0a870f71337c1b75ba69b24600a65f1671f2b95a4a763220ddb8b52d46015a7355ae23d5ba7069a919ede641e404867da7427327408a6ac53fc629aa54a04e5c26c6fda28aaaabc03b544a726428377ad6a7086c08a829bd100ce02036c30840f248c7990608b235a8e5330b7c67daef6be4740747a89a4363a41c6576491425e878abf0eaa2e33172a92446d98dc6d6dcb884ed2cbcea7524393b2df7baa739a95d96676e34a3cba78cecb4b6d20198bae04815b8310005c179bc62424e490be6b4512823224a000da4c6c9d8281aa86895222ba287239f0395c8e18ab161c992c6955c3f5a62188a982a1a8ea6c7a841688523127cdbc9c5713ce7b814d44c44c2f8a762c326f1820c442a585a3da5c528a5e5363ad00a536ecf8b9fdbaabf5e903064c04720ba5b2563d5855682922cb2f96bb392236cb151b27b05baa279fcc2a94f7c4a0f941a274485e227924bcf233ab268924568809b5a5808836dee87ea4cab778036518298848d3c929156e67e75cdbb0b8ccb0a900d63d6d319a94b122cee12af512097a33790e32688d2a953f921d10846417415a472a7f7197cc9cb01aebb95e93694006519d06d0050a34712f848e1c499ff9f980657840d7f8ba7166261b1609789a300b4109286951b0591980eaf31c9e14b181a995428d3d5f20ff7e571ba94723b2fa743f5f068fe62de887597dbd9e456413b414196b301ca68220cefc53c3e6a6c68a975348bc3f4beb225366e7519d72edf8d0d00bdede9f96ceded974d68dd4eb87b94a37867f8f1a28d062560593d36cc5883bff028785171ee20ba45d +ciphertext = fad362d74450d5170b7b6fc7f58d10d68c61ded6e582ae090d90d0594b4dd6368661775f6bfb16baf658934ccccdaf7460334d682de9fe11316a54de4240d42f35bc242c54d23d9a6bdc207875c3dc43d4e81b4d1966fb7a7760b13ba31a79fc25e8fa702b0537ff976158067edf30b3a9f4f4ed8291ca07838c1fa99157868123733d38ec3615c7b4100dcb8f04babd09438089932c9fc71a5d216c29d6a39d5fc82ced20a59b17cb49d6c1cf595fdeb6e81f69e4416473921f8776155cf552fab5a8afa54098a04dc46144157e4662ce563b7bb576697e733304c03c079b8608b2482c1a60271713c5662442459587fa353f68af52f4083a552137d40e801b16001bd2f808a93d3b0c2963969be8d23ddfa6c208da63c434c7b360ea13ad9c9d2b538f3d0dd32fbd3686251aedd81b9acc0d2188d7108995663a665c424cfb1feec54bc6b95afa0e23fbc28d881840ef900c41bac1b81701789c788dd919cbfec1c1c0c5773493229b489f69a6d67ec066c4498c7c830e9d6eaf92fe8e92826a0b44d5f4eed29f1d17262a9ac43d2b86891a08925527530e019366b6d96e8c833932d4101d7ebb2d8bafcfffbfdfc4a0246f3e01ce95163a088f83078c5874e744035fb91c13eb850800fe581306d92a6238e25c70765155046791f2857c9623c9bf20e4005f236938900813b07fca387bbcb2f5cc1bee8eee8387652d5bd4d39fb7ef258bf23bee369c13c09a2520d7a20b96e4ee1e2f68638067ec51d69124bf37f8f63ccf27265bb9581c318caa979238fa054c53cc90de912c1a74cea549123e2f373c609790d511b5b482fb5b98085a72f59c380a5524cd90b382a5ac8f3ed0498de8ea3a76af52b37728a92dcf6f884054c61d9749aa05c4a3a15c999fb003bb60d5315e850887b9ce79d3effee5b5a39789da73686c534987921eede479356fd040eb826e5c0d5ae3885493cb5c1c60d326f53c0e7de8026583e8d7af6e5b0c72b307a49eb1a6da11a2149d62ea0fac8602696fde6a4f786683a7f54332d6c584ebc4ec174fcb67010615709718d4c69531bb6219b4dcaac60d201dca88c9e68bace2e219e09a2cfc43032ca039eb696215f35e134912c53705d8cfa8bfb9286a449f6b42e67b19e12e307645b6831c1192342a58ce69c8897ce76e0acb23aa8654b0febcece31af988aa0bee397d3f417e608e11b76719b9a38c2e27f9494c4eb54e995fe934d8cc128e3e82e68326a1e2d8fcb003c4ee2c4f98c41db3f2ed5d9b0c1740b3d30a2bd1ca0cad85d12136efab0a58a20d432b077237a09b71b1937c849b05ac0eb8ef0797d13821b7d8922b2117ce273599ad727c38ce4d2b128c460641193b55479982de6b0b88263c3844db9888bbec8477c90a03609380faa79f28d09b5f04e0b9567b3ec74f6e4ee74effab593f7f87d22cb19b91d8068c7952915a5ef126adfcaab98c61500b4718f0414c7bfd5e5acf49539127bb51a0322668dce268bb309e0fdcde3cd837a474e5e4301629ccf97b8373493b84257cc80374f67b9726f22cfff700cb849be5b968bcd187aa9b9b480ac8ecf53526e6a3f2c8dcca96fd1cc05e50bb6e5e9c232131fb0f8e441c01e66f3a0c7343cbc0846bb86dde952704bea34867b0d45301fb94a95aa7d0e4222c647f1cf8f9d00852b4838ea551a5b0c6b6685482ace807f65f991400efe3d2ddae7c02cd9b770e4217d1c5050f719956b534aeb3367055f0875d4bf158514ed1555e17ec4e4b80d897f563af1ec53f76ac32e2a9dbbceec2633b62e7b4a163ebb809e408dbff6ad56b50792a07006745ec9bc685aff80399a46ceef4c7981691f30155acd1445c16e219a929bff4546734002c5a1128bce2a25b69385613c8f6f6af4661b03751c6702bd084ac55b9d041c19859dc26c15c4f8a0f6c37ac1f490b4f5f7fc819325ff46daf99747eacb1e234ff98d0653552e799ee553c7469774ff63f735d0f798a84ee89217d96494e64ddf5f6b666152afc8c797cd85314f411b915e730cee4f6c4f93bd1039c681970ef44b267300484b0ef5534bab138aca0e3e63a56be463d3fb0061ee7fd587f04ebca39c4b4c5c476e67a88b7a507b15a5b0587200b592c05b070bf7b4c4c94e3041040d74244f1cf6b381947d7a52ddb294e4bab8b7d2e1f1979b0d083507d722b17ebe695a767c1a2ba35e4036cc300632e +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = e843213f78014b191137c95344544658e9171e822e81c4c72bd31e504ab06384a516636b5287178dd069f8540b77ca6a59837b58ccbd8323421a0ba992a65ac23197d07c056085b8e5010a92d7333323463027a49b2c8283653102fc6ce70bc0ddf82795b08fd614723441794fd7a3a5521a0e170a48ba9d873c0d0115095669aa1602a25c51cdbdf434092280df34c141585e451a640b7392a378375cec969ee40c04e8bca6782e86e22c5a2c12a68b5c3b49ac17ab64002c24921601aa049400fdb9c8a7bece942ab6608055347f023aa1ffb733128b1e476a664180bfc5156d33026a6d326e8465adf6ea8ccf1c4ffcd80b4b0b75549b0e4acc0362b1480a3c158f0468ee6185427198a700980948abb5d9614071216b127d956341e8419eb25670a47a19f9bcad6e67142b01c5db96cc0a5a48183073bbd86035832eeaba558e8b7442fb0d98bb253c22cb5d06c20091c86cb91fa43b44cb254ea25b1e004a1b6e872bb0265036e01ef47a1183e3aadb07bb2c06ae6377860015534a0aa7bfe24754333ca7687381db986a17080bb7ac0b97a61cb51490f16e422608d958333594bb6bf85bcb3ab9cd7c6c7ad5bf087315d3e28093654edea23307e65657dcca64407536fa6704681801c15602b5814dc9ac60223c81275243e44d3f837762fb1e719446ec1979b4c546775c5a29945d03a6166e4c2ee693569b0b6b02839409c148c47b61e20b9b517b2d62e644e80272314375f33628732186a4e73e52d34dde9983d96804bee20b9dc11d6f51b610c3a782fa843419a1716c9a9b08be780051517678c2ea3777a597150969302a0943dbaae66c0fe62598b8b20381654fffa674f2d140a5f323b0e87f107326a3908b46238035366bb511a71573281b683f57e05126a9ab6166af75401b1580a05fdb052afa8eb61a64104735906b619c66095a42b3ea74cee1398ce8674f93229a7daa95a8dbba8c6270f40ac2433a57e9aba702c791cd56720ca3a306547fbc159b5eea5e6ed08086f47ae1bb177c2646d4f64c8aa7cecd475abf4a786a06c1388aa1bbf2cd7b049403391c13c3c29f2c6a05dcc4668137b7718d08310ad72b4f0ffc0752144b80506696d143d049bb33d408ed789584976b10d593f90152375364a1171c93a88347eb74ef5c36f9e19fafc8672f636ca6e191ab542c00330a25eb916c4a900e999f768cbcf5807858352361b5ad3ea376eeb7ba5573695e904679d22be3a1382800845f2ccddc40659dbc0eaddc74df360b303c9082c42ad2da5f6803b1210abbd737846098b0dc435f3e28734d546fffab6602f24a2e50cb507bccbb8967627982e36585f035b9ede31a5fc2c2a3c57454a88d2f3b388481358af188ad6a4ea04269b3b00cfabc811a4c9739a50457ea3ab25150f9821b9f130c15821bfa364f4d823ec9cb810c92083d21bff9211ab99c3d503003609a995543b41f6a9b189aa7960176ef625191b839af0c55fb1c60fc66431a932c13c4bd513a96ca663c778b5f18a502db6c53b997805db345e7a4af46dc8d4043a34e5ba734220f11a158fd946c92c386e0f8291ab2bd4dcb5cd3ac4e841338bf668c0a6535fe7c794511920f2602a8b8980358ae63234706a7bfaabc0dcab07a0d958142c88ce13b7d1df50fc8750262b7b20c5b749586848bf135f0a87bda4a611dc4ab8e68a5f7533b2d973eae0ab64ab89cabc9240a8a3d6bb14a5589849d254e9cbba4c1e0183191a07df12c27906b19bc2a88d71a302c7c1ea16e7823a34893175f21a0719062143819d844ad55d16615562e1890871b07a7ad556f963b9fed12cdac3c2e25a3cc6c356506478c916151ec5aa71b0132c5554638b8076f379304219e16e7314740532849897e8b127dab2aab090face89b6d172606e79aad9316952c3558c92bc46404a17778e3a3b85016cdcd433aaac44e4167b761b03d4c422d54797645ca5e99830ecb60bb01e0c5353a6e6d43966431cd99eac14ce7b719e4a9ca301d5644289be51d2262824350895670a948543eacf3a3ae1a882be171d7b7b52ce9122346c9bc269febb3cea6a525b0c0521b528fd62bb69e3a6ce8f3bd134cae8b347c95576ba46618ca63535fe7217a97790c42bf9d0817f5680b45a139776aa7f169cef9f85e6253c512f94036bc6cd8700c0be70c648ba7763b71d13587ec8b94f63a40df57bfbed69eaad76da9b08318656bf9db152fc85bae23635f729e04148bdce30fdeab6c6804b0f7d6c3ad19479b4544a9477b0483ccdeda10747843d179b1f6ca6d27117a51a9a6ed0a3ecc497cae41830d054f91d85c75c28e6dfc5d7827663bb98b68f42c236536a77338449bc3c690ab1c642bf7847bcf344f2c8775ab9733d237aafbe68019d603a54565b7e24114d3370f2375d0443036603840e8b8d5a2cfef088e48a044576ba6379155dc3cc177f4970b28689088747c8619360b81e4bc26b0a38d764105443755d250c80ad6504326cf062b3219c17013525c382441598b22b0f531b91bb076c5ce6c9081f01023fa108ed4f0cb7a36b84e4a1c5e261241f08e3e7b392c02013fe5c1e3b16757573638d514fca74ea4b249345559b22978f704ab1e77b205727b5ff0cf91c096b92c67c8f3b8127a16d2b24c63a3670f2480fad09f77142574a55644aaa525c73b3e6448fbf813c9337a9c037fbed380b4016026dc4e1a1312e3d98ea26752d072237113411654432f6b971871098f41959eb1acfa53819df8079bdb22bcb3cceed1281502bfdb58899d1728276996448717fe10cb3b14ae385b05ddd8303c342787119fc3f89db5743a38b5a4d8ca0967d21047b1a3a3984dd46a597a010aa906292625022f07c7974117809c836c5c03aa6901f611096090ca8c679e70ea16005b0382867cef620c90088ede2b21294c4d79665b061702b9e51136fba924f37afca48c077abf8f7c1352b43f82618519db3abf6a726722bc9fac254426b50e12c0169999d2e7c3b63736fee60a3669753d561ceeba7d4be328fe92610ba5403a849dc860afacb456eeeca2b506b61c300ff0f95f7af90d518c702230aab1883f4e7b0d9e2bad8c0c8d3af40d363060f181cfd12315f4439303aca704da9b43796270d2aa5fd554072a2121ac9e1ae0308f626de24a7ccd3c830fa13bc0324acc5551482b137465b036e0b1ec53bb013746780058e91605ed559e56738ab8c59cbda420c21b8ecf4332c29c530ee534d0e67fb162cf74618c071746f1e83c99098f0065c4b89b27b1e570fd6a85c5e31977352459f25ebd247f196451ef4156c440a8a9799fc8149c58b199dc32bbfbe1b93d22bccad72f4afb0631545b7bc252fb1c09125c1aa060149c3a5d6f270ee2e79559117d0d514dab326e00db4cf5fc56b3104ec90a70f6a78b46718086d6852e36a075241e5ab66d1b7c0da94ccde173a6cae66756d424e6776213ec0bcd8598a6e8973e64a37cfc2233f01bc235c8894ac2f815843f995b368c6cabb5962187cc71892d72d463eab6492e481617fc1309bb82bc989a55993636720908fbbd70e51e9b6a652ee32d56e8539c980faa901e968a161de59f76084336638566d8bd9d7c675e510375a1b4f6b04f48b3255c94807d4a95aa85774c6565751a26a4d225ef4a2b17a996578a4ff7e3b7a4e07870928f2fd65552029076824a8e00278f23a106b07523540d1f78c0f9d119d3756115571bebe3aff1bc1823ebb7a7f92ff700baf2c5a0479bbf36a48b9ac9b59dfb6b404671551692c04a6a49899e25e9924598570e030d3cb1ce54f29197805ca76c14e99b838c76308ef86f26b18ab0c1b32176437c035376c8563feb1b677aa324f75dbcd000d5369ffb2694085cbe16751f6df51cad2129848b4f8f631e5b24154423ba210627b1a567f2f5c7dacc3e06a9b4727587809063696238df2c177a80283134b2ec32389c4bc71e6786ac46a1b106b1907b95cdc3a93ba395942ba158c45899003deebbb42eca6b9f9534c066c33de5860502b5b853b79cd3cd61896ea854250e76550f5b33adec3b75f32d19a924c4766147a7925220349ca575656169aae63d6c1551ddc91c470a85bde6cdc190b02c576b1edc88fc7c8afcd3992361707fbb618e7974e3d12d23d055621c53bf788963bb3393c737ec349cc2bb136562190b619eee824ef102ae9f892cff893a15342150d299088a4afb078dd638c334519d67a202560b08d5baa2e17ba1a10137e6112de27142b874c1b45b3e92a3346e7cbf33ca5623d5b4b80406db3a52bcfa8add4538bb22ba88e9b5517457b4b126dbb8c3a7371a490948b3d058af0982bde2d25fb7a513cf0b7d6f7637eec34cfe0742b5a757f6aee351b8fe4134502133e2a0c610952782d60de433e21f937f065a0c297f4e6e2d52cf9ee135683079ce6b2931771963de19ae21252c701921d88a0d35327c39c4e75667eeb1627653c38e1c01da7598db717af222cfdbe72505f03229 +ciphertext = b32fa2ab93b2f37a0db4823baa6252f8f41057d8a6c9a4d9bb26e7f5b162ec8cde91cd55e08eb349f1f08142f5e2fcb45d31da3635ce70b1c480890e9beea9db50faecd41712ec48ef9e5e096cba68195c0cc5458abeff47821a5abd7ef60f32fc1434e31b97c44e726907a3164c52d6e2ccc54f1c6e817fa79697625564f968842195ede97edcb8b3d7e08ae55f442a78762f879801b5d059c365d9a2fd8babcab00685db2d419aab04c814e87d690f8114badc6123f9238344fbb9a93888e0cbe15eb3046d41557d479bc5c8f94014b037d4c21f6baacca59a15513160fc1b622e859502cb938d435f7ab5b7b07050a94f3e1df13d86465ea4bf54428ecf3d51e7c889596f2dbe184bfad8b96dfa72b3c24664a917865df6e3ecb5493bc694cccb28fe090e2a65a7e4e89e175ce46b113800417f77423a8ba51d0706322a3e5ada475a02e7aa763579e40f961db2cf40d7b6a11a8e0558044fe098881ca67500f4afcf700ab5fe57483e33b24d7bd42331a3305e988a913e2fe057b6188dfa63c7d289276f71671973bf98271456e320d83da86c3611b76b7d3048e17dfa9faa98a6b7477158c8db1966ee6514de63bd30babafb34eb38660df5aa5cfd58e5e5c43c7a11162d2e44f8a9edf623dadb6a114551d61c387a1a5d43e7f787416c65576448427b61ca1d9bb7f6a08c3ebc76093ed9314ab6cf45b51c9f52292165f7fd62953be1fd4b54cc307001e75d18fbd69083285442d0621a99d050554bd9bea9785ce0ca2465c4aa12ae4b18173caace33fd8498dec8acd7746833d65c1a9e90dd7ed68ce45bc7f162d7dadc0f5a0f3d3ce45383e17ea975f2e5260ac1c9dec2e87c12d450a8cfe94591077573c187fa54870876f2c43bb59ce8e9470c7314625c5aee8b8ad1776da2753ccdc7e5351a1a91025982c78d18ee6885cfbc749504c21bc63aaf7aba1cbe9c5f6e41784f510bbbb51213182fc64add62f2e4529dec35b4e61b8f46584f6002336d1c22ff285baf35fce787cea62ba2c9682ab82dc5f3e0d62f0c4111ed1dbabb0ff7b3120238680c9e25b3340286a502d720c0a5b188ad5ef4cabfbda8f3419b47976ad3e10311b05b41dbf4b0c1c458760c10292a9e1100f9b92886dd88a6ed2922df3210a9b76cabb139f4886654e407b6346f23984cbb13243de020b3e2c54c819c67ee28f5413dcdd03bcf79956fcbd6fc7c3743d3c270c7d49221230f7fe3053b0c968b82c0e78703e80eb982fed30c42be289f72c67bcc88f139136b3abe73fb96bdbacad8b37165a198d8e84bdb1ef4dfef650cb8b9442d1dc232b7557276b2ee14285ec8c4c39e9f56d488bc949d1d9a0eae9ce8b7ee302ea61f78210361c0861c7e36647e2d874817de49efe206a6f1e80faf31ccd485bef21de361b82bd8b800322ade03208da2b39ff2cba67e17a6962f7c4522362c182cf06a787e0d5b2f705e4658e3d2b23c8468503ef0f7e5cdc1f952e58f1a86c8104a1d0cc2bd07dad6155d4f7b4cc6abf2a1fb2b09bc92e89d448c62438128da1f9a9857b1ee9b1808a0c7848c83bcd7721b621c7b86c694388b2b135d60964cf587da10dd21fac91effa652d6205dbf478fc0f6522ce551a5f53b090c4e5dad0eaf3ea14889b8ef265b5c5d1a95eb311b2df32f0aa6b9983be93135cc2ea89fa3057c22ef49843e75f334960eaf277e9b4bfd378433f9980f950cb3000d0cbec0f35c3e3f3c97b136875863e0f1b3879f56741097eee60b9d28060978fc68335dfc0bfd0492d7b11feae8726a44eda69907b4ea760fc3bf038dccfa494e4305e958999bd35da30ac00dcb7a55dc374b3029e3ebd8711cb44018df49bba4932ae58ee10f663e9f409794e7dd55b03e3ac55ff790d42a0367749e69f5e9434a27ec834fa29ba64b4dd5046f022109a1e921b86bf50475b4187600932c113d191a054d338b1933bba54a9910cfce9289106c2038e6eda717e58a7de920f1e18a31311b2262699a5c77d5fa12f695c197cd9b8f4669236b096b532ac96a05806cd8ed56b294041264192b10f89e4a968a313fb0cfb558a5be5b3258cfa954a00228af262b8c2baf64099c72276c9c0ee5cf6b3d057f96c57793fe1789db12164122b41b71a150b32f1e4c76a1f45b533d41e6af89f87f00d59c700db664b1bbc33964f47fe719546c17843caf06eb49d99eb57b37be7db86d +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 8f08a7d8ac0dc1cc7849d29a847586f7d749aae9b2e944cf101181c4e8370890bf7a1082ec544e3fc85a6cd8569e1b13f205170052206546ce047935581a3039c400a036826c2690f2d645555c54c78c0fba40928dacb94067bf390523b911cf21f72128f6a34579034b9287c65564451089ede995eba380dd50a0fee720955483d999509e1aac6128cacaa46ca55a172de1ce9c650637026dd7dc1c20e4365fe90269c24688c8c5a90940c0637c5a0309b47c8c6fbc5f99ba799791c9e9149fa7dbbfc62b00d6b944875293e4cc19bd1ac4be5c6f2300a1ab6404d92b0a5a896d1338a6e809497b532fb08583603922c74c708a4989fe32184bc07768a45bd99083d6e0225f0b5dcd328cf8c03a94a9b9bad6c5deba46df709c0f222009fa3e6523b962147182a81e9d92c252984d486b3c5f588be6c9c696066c3f3c9d9dccb678b4338ed0bcdabb82a25c03531aaec5c6bb0da41c44623e43442bcf388ef2bb7834e24d3e050274d0c3b5a6206b66554db312c7e33615f6488b3020f85939ede7be26d3c4ac96881feb32bc302ff942590af3cef7557a8ee002070594b3a156d75bca9bb22c80e5998e7a727a948569fcaf1cac1ae5b6b234399c9031190f69443f1660c3362942141c6bb668e3364708e7cf9b70997a16a4528515835c83a592c4ba2238b1830324fb379d962baeda200ca83915bc6c5b16391d7642d434418df89d3511842c1bcecb32a84c5965acd26f6b608e8ba82c34e50ac29a9b464a37d3618cebd698f4cc96b0608f3b4380daeb58261223406933ceb72ded45a0eabb6dd6f7abd7121ea9926c98737acabaca51a1b2b7f0ba1a568f1f1ba324f430f35364cf6c9d6989043bfa88a2eabe9a038ee6e6c43f888c5624c0a68212567b42d1a58a1d6cbdb4243628761361e4b079cc698d4073a8307ebac20dc6babfdcc391622427a071283fd28ef9a8080dcc228bfaa42935c2c209402c5bce6d43607a60777e500807a59073c831909865beaa20281294f6b98a80bc80cb21bea2b872e8c6141a7ba0faf5aea411c3978398d96bb06435696a266f5934711466b153262b7a7c60fdda2c2cbb1a6353ae258340cd52529fec83b9a824c0c97eb6376415e20f395c1719b19de5801e77671222710947db7c925964c4c5382fe422c17c5a8c12b1926b9d2db1ad87f567b6697c50b7436f33a470bb78b599cca3fb9582045b5558245fa36ef0061a55c0bb6b7858255a7af4ca4b7f099857fc807ac300d2c745ce2c1d3c7a90e9eab70508c009d4539b47c32e4cc15848bdbf9c5f63995aaab5cd60682c1489915b03ad181091d9ac30daf7c9e5642beb234bf02005a3bc6a4b3102fb01208454ccae9b696d8c880a8635eacaa4030a45eeac9aa40b055722b0a4816a949491b3f68a02e6a4bcd51d5731a7d4113fdab8b7d3993621a3b13e6ac01ba7c6b7bb16963b5cd32132db65c388b78b8e884e1c8b6852e7152e9b0d45120c37f87c73925427192cbb464970e63f6d990cc240c70818402ef362895b766496b7eaa736e88218eddacdb5095836212dd6898e00d61c4925a6f8db80c9518987f613e5637038b06bcb65cbe4614fc954aefbda263c951542d259633a5a1d611a8313c577ac45c1049cfe2b165d31437fc8cfb721858c8742500b76961ace0158bda4eb1432fb3e67c00a9125b640d14825dcac50c7181fd8809ca6171a8b0e11f093c514947d7642cbe8ba357401119c4632a3ceea3a15a31c82aa1371ca8c0460d5c4afd1bfa651b124f4600f20afed4a1fe85cb4fee836ad332dc42a0ebf738e1e283bb41bb8ad5a1ac18c50c8a7b2f3025c052b6691691e3ca482ce638c1963b3a03489cccc928d189f10543ac6596919887e00f3188d391e1ff46249323667d2118527212c265efecb6712282d4a71074b0cb15eb4241e7870ff08c0d4168262647d46f08cbc319fc53000ddc419f9aa249a295ed421b0a4d2c142da10c67474d632a76d11a27b8a7cc3f12c53471c852bca9d0b727c5803e72117f2a1944594748f92b94d05421f7268ac9677f5b807314520da69591560b6ccc8b6e7a8c0432b0f5d3106dfbc4419d39caea62bfd7caef34805a6e8ad6af7a52359a9a98433a1556b4494abc2152be8fcc913602989d920f318c744b7889ae051d1aa2c599aa6391213dc411686900086a853d5679b9e7a2c2c875652419b3d497b7d4c55b5e17998b6a9dd33775bac9b855577ea808031f434969c996dd2a9a4824156ea678c439ad7399b5794021778c2f5405d47acac5b16472e52be56cc4ec5dc64e2fb5f901877e1d885487693e1357d48503d35eb6ca31a8fc6b191fa6754cee0ca41a6bcaae63030f07e18930309320bb4f329aca0b23b23556d34974480b5f9913a4bbc2e8062192a54066bf4a627e7c05604a9fb155e4ff04453c8a5f9aa1030a45f37f948523666d1261247fc6dc7c71240cc5720d9aea5631875904596ec4b70e9425da14c17f473baa27e4a5b5dee18aac25b25632277d5b14590b6c731fc1a41eaaff5a9734948014bb8b54dd57c452885f6cc3f7f3ca72df536f679601d3718acca5fc166107dd6afce5473fdcab0bf770c0a811b3d66409ff12db4a959de7518be6393db50b775c120a2a76147671cfabc1b912884d9b99fed4b62e5b9af532b778b538ea6c77ebaf263eccc8cd6e2c40156699c3775c4894572a2354cf26a6c6c2025a42440a55ed3b18616a39417d06ba5c1b809b31f1e9198abfc20cb6ab3d0003043cbc62f3153260b058c2b6fff188e3d79c60ab64759e95122589c7b12af40d9373b537028fabd81b66680d801a2a4b9df943f1e95bdc68a8efca2998c5ab5983b363d246a9ba07a67320702bb0d62330be197c5d0450d22c5505e830c61fc09d8193866c51bcd395f37ea6eab86380af531b02b58474713c760ac802032391192a3296f2f52496a565b6939a12a2282667b8a54108293457fba1c93ce2799b9d6c9ffa5b7c94167d69461d4aacbadecbcf44977a53945b3531ad953b187f8c5256249f0048fa183c047a5ac70e6ab70224a7b47900bb68bad0aa78d3bbce861c028005412d2c22a6702641a69db90b4da9a7f5d8caa3ce3b92ed4929ac271a39b4dc6f18df038ae5100cf91ba9986482f87d499bf1b6c1782c300c9cedd28b224caaf42823d67d21b9756c50208c9264860e13953dfe5bb85db3e5a23990ef5b1a04ba51bb84c280a1442dc81fd7944a2f55b73c905dbb57952647f2c15ac4a351fd6c02d8aea0550d4cc8fc17c27bc790af37df8a4ab15518ee64b1956b50702799e6999986665494cda75fd758a115681221cbd76d8c70e34c483b58dd77a68a3765985d1c7d294274858cc30881f59781bccf57203d2c33026c90c61b31847c6c7877494bb2de2cb9a8b19c17e583feb2b8735b99e418a0f988838695c8b9662273418b03db764a1a484e20a5e695200bffb84d529c25ba92745135ea506660a545dc8c70a684472a6f17c6a511b74c6c27dd45e5ca60756150e46964de0e50f5e45b3bbf551e16571f1d038657389f428b6e685a9a1253160c40deba62f54a40268d56f7339824c941085c70549339e362b5a083bbb4fb3bae4ca31d30841ae667e72102efbc766ce5b6f89fb2c2b6a6662972ba3b0ae69a95268c3417d49559aea2ae92b263e0897faf47b7da24221b08138683cb8ac618fb977cd373056bb40edf01d5e592badb53d1f87a5b54b4586297c174c740a648c8c0c29cce38c4961313717c44f8728c1b9b144f97f5c724788cbb305b80aa0c471133cb7494283267ab8a3b811f90c0752f003a6226df4121f7312829c63a814a7190b3c0dd60bab0215834db21695b21f87e551766c70c91957639cbceb1065e3290d665a3bc0ba54689331515069ad99982ae41a7ab8c6b790776248cf03165f96d4af866604a9e492836acdc3bba4e58895d766bed9192851d50ae0312336b1593ac03c0062cbae51385b8b1a8088a99f0836cd979ba878973ff8153715223d43709ef04ad5c3bd76aa8309959ca0c65a1474064130c7f619487255395af7c8670038dc69b8990c05bc8c8cd3d6692b20ace8c9c90e425d3fd33fd82000e4c5179fb5915c10a23241782c0bc96e494f9d0c4e81a78cf20b663871b13a3761c789c6273340bf4bb0b7a3bf4fe810fee9552c7561363b35f70559e6c86d656b039b41a87bf125548945e10783559cc043d49a024a81294313a996586f8300bdab5ca3552164c5cbfdc58c244a12572477b90332d3f318d11168191746bef5a249ea22d178441f206c020173c20990398c1afde49acf4546af94abc4aab185c1e1c10f541f346a3ed88bb9a91cc0fbc49fbf52c116f280b6a916264d173bdd4c998078dee6adad905e3a7c751c35e9f9edd5cbe92bb9ba5e76a5bc2acc97524d9ee1966f71bca094f7de4a5d6562baa8f72e0d63ab82a06f16b3f4cd +ciphertext = 5757595d98a504d5a16c00dda097f6413cbb2c77a7997c921717c67fbe7b35e20e87aa8a503922bfa0fb74c236ef791b49fd2b90cac8a395cdc95c05187fc94394f19b1638ffb329bdcf8b0965f68e747895624704617f22bd195ef2669d3cd8c84378f058f53fac3424a5fc85471f88112ae7f44b6d3b991a11aaa1cf5d1d8f8ed6114ff9add2b94d12e6e7689cd4bf1f8d884ed221b26076a63afe88227a84b3b0e475df441ae7131734330d4c33a7bc5592c8f8c41ff3e4f846b285238c1436dc41477bca4239b60e3ea3408b0db89117322679a04a3f6733da9cf02d533df0869393af9bf38e4c62d92c355a761fdbf9b7d0b54fa0743ef8096b92a51781f3eb3ba2d69da8f2957141567d2e296a008c4efeaf53fd78cd0fccdadb1cf2e4c049042004e3220d640298b5a498d4ce1cf725e99d788ac34563ebf0c7fa3dc11ef81a2f1e7f5e5212f19c521988a021c128a88db8cd0861ceab8a2104c4ab4337c7b0e31b2344c758748b53aee3f1693e798d2c4e0d6fd31623af1eece095f10e5906f69bea7aecbfc12c1ce2d332cb23f7c05c461ac9259da5d39fcf54646f52d03e5ee9034e8b553a64e0607152cc96027ac69fbcc04b0518949ac3d9a90c28e302e27ab86532d55b9910af43629b85d11b543f93b25343a2727afa4d3059a9cd97315f633ec8fe5616d2d05ae80e3f8a7c9c987ee6cce05eef829cdd524ca2610e0c5a64b3bd34acbc66c74fb6db10a3f0451fd81306c59812c4a5144920abc31a2a200f4d91ccc637d772fa2623f97db4444b902c76a1f1df02acc85e36a886bdb07bebe28b711e794b089f849d3ceeb842234b6606c076682190eecf82d07503d67f07f7569d8f670e49cc9fc157e1413a30ae6b91534e784ad7b19cf7921d6dd53e323d048924505066d59ed2f51f834f2c69c1db55e6062bb02cbac923704b3ea6c77dadbb546084d0425e53ee27698d25ce8d3e8b2eaecf66c0e80bba753853dd40134e53a2e1a7620227064dcb162b7c1a6999510420ac3ca910db6a765f74ed76023ca30d2512515348a9ed3988c2682265ab61605d9a464fd87e3199c7ffd3241dc022c7cbe416a04635872b39fbf7d99d686c93d5e05b0189dd9e6c79168f89924ff648df18dc30b7a96ae322ebf198f80c92ea31393c291c056c6572ec0f1f6af93479ed2dbda18bea52964c0d8ca817b361d08f58cfaf13a08a237909f8325895ff0bb90fd89b7617146153b609e2bae01d177f7139e8b37fe4d6bb88139626cab328e676b56e9152411812619b22d41bd0d2a0e2ba3777407ed1d388d678b889d2610b904b84517100ab7e03dab83be86de93dc5de9bbe1aae0882dba2aa25cfd7b1dcea505479663c9a8e667d1d9ef292d56d1920d0f46c6ff335a32449659fb1c0d9f461daa124cec86f789fdbf2ce685e39112f1c6f80c327977bdf6e96cb88635dd65dc50b09347158a1048424ad1afb684158b101a7795f305d6d788bb6cbf7fbda1685fb75cf50a4caafd53513d64457161fe8ad5f259cd0f37866cf140302b2e73bd244cfe9dc481c0a49799ffd591986fe08878ed6a1c19609fdf4b0a6fe393ceec740adfe21f6e8f965e51db6f5e10dc3d134b06877e4899bdf1da6ea5499e1b21cb68472f792a4c218fe6935e054bd7049ccb00ca380957d4b1f23b18e25f67b3fc2e4d7ce8530a7bf13c807e8a34a726b7872e48e12dc518d1ef637a79a778b9a04a775be0ee6509906f18ca17f1a3c83160729b1c299f487e85bf8487014c5dad4ab46d53173c87a5e2ee80a6aabd1c20aefab8623f892853b97589897aa8841193159c3476f6ebf66018baae0164529018f613b0e6f29360533ec29642f32ed7a9ef7ce0cddf3a87e052e8596a6e2a3a1407abb131007330e3cbbba99148d6c77ffa5d4e793ec9c894d61ba43e0821005560089be672e8283bbccbaef3efa438e008c4635ac21caa1bc44674e22a336a30852726b211b2794924135404ce4e3aa2977b0991802832a81fd5cd7f6b860cbb59d059c6c850ac26f407f00b2aa6edd0ef7f12c931f43a4f6f4c219053003a4aaf621f7acd1f9d5f6ef05f94c798f1e9554b3a86a86a58ac8a685e935d483dc8d73acf6891b0346cd805a394aea1db90c57ad0896dc64041e94423949bd6686162fafeaf1cc712b53f1c9506adfa95533620e97cce9407a8d0de44e2eae4f1b96 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = c32571dce4438a2374d929b8c7c0487e530dc060214801bf7ac433ed461467d9c1642bcffb268471a96530719a27092283f437c5aa67b5094a8ffa3e1c818ba4723026d08c02e14ce09386e3621d7ad2a404b501871b058bca9e2e57be5ef30595806cc6a7bd9b29c7fa05afcbe4a67261a19a2c9fac6287dd704094787486757472a673e138afc0777ce1917711f804ffd372b4870bafdc101f9090f8e86c52380138603fc2b913e0d21fcdda910f602530ea587f13159e3095df728d4a08b8a1a80a00573d89b413ad738a9f58aa9adcb9cf006014b116a2746f48d5a9f32616c1202c970276c4d74511c324625656ebc4873635b91aac846579229e42b9029112570695160860e940a716f0c0eaf71008a37b17b5a540a8461152cdb79721c9e096fb13344edcb120909151eac3a65a57c74c3a759a3460855f95b05efcd8a8bf938b7ba978085777a2d48cb2b1a1e7f98acb929b3f52bba2b31df7a651e72a60f0469b8883bc2797bc95fc060a2b52aef0bbca816af326b30bfb010fdac82303c3d72156f77c408ad87e72d96a0a7c40d97137708c862e6614f927c3eed3b1db0a21d3e561bd7c789f91a00e8ccc09909cbf00a24f162d10241513fc6716c95bc2a3582a0b878ac24d23142b8d962d2a0c853ee4b606860f393a9f68d6b9e8a0949eb04535a41dd2078a7e197d58e78903936e30ab158e4813a4f3be2303a503ac4dea7a084f374e7631aeb086036c0070ae97790179a044c37f63577615d44fc555afd4532c6f4559778360fa74298ff0c322ba3bd547ca6b422e621ca183374fef994a2c809d7bd08e28faab8d161f45f75d086a0684c41405707323e4043c49842509184031054372c80c23c2a7b4143ea234c22208f88ac7a3a5be09c42543c9c7bf18025642b091c59c8ad365f3ea4673aace2665c10bf133b951aa2911c1e38729606a7730442bd8647d6e1bcaefd392ae27c594dc45f84995a19980839468e5c218b0513526a68154643c303c1e34e0902f32488cb53b5b2c4e2f25cea9f60e648a708607b3c59aa3bd536df51870ba4c27998a6cf9eba05b7a262ca929435c1cc2638039b38a07a5a6e12bbe8234c038c3602134cfb9d62eefc9143cdb44aeb8655baba22c25cb0eaa6d18c02de0b34a74a696424ac920f2b8171b3bdde92e66867447d01b31ec6d78e8a42aec61ec21b9c95c9c6c6b036ac40946ac96368b74c0cc9fc7d9348f3a5c8f09363c743964f9c854a927c46952c1bc98a6bb8ec05c390e6acdaf238273dc96980168b537c6861a287d3a520452a48723004cc19fad98b6d5d86c529130d1971adaa08db05c9ef732a999d6a60dd1c5047473942143ddb85766b383a4b239262779237b54889075913719f5d72cc787c2b994b411836e6f8386a1a9ab03895870c0ab12086016b9970178189b17c97d5b2b6bb256628caef88272ebe959ab41404b422fb5da29a59022e8784b85805b3342092419605702081a6a73b2954874fb48024061e6351676093b8ad721d923b4b9f167ba6c67583420dae72e624b2ba416b686fb34d5235c2c6896e8b991c21ab8584a4b7dc4254499087312965e66322153734a636e70e864cfec184a76a51067b2bff92c41493b88574f20a61018813f21301220a7498293050eb6a7d5286d0c2393fc5327e55a4087d0511e9b3353073c7806b4ad1612fd9909a8d3881ed3a2aa336964909f5e88cb40a4311d3bbba2d5bcf2831e16008d47d88998b541b648c242186bc1b31cfac435f179c39586733a6aab67035ca70905a5eaababe73fc478a04f58be92f1202d74cb371b44a4f7ba13f39520d9947d258fdf373aaba52ccdd4038696016d4c96811612f34a6411e3a9237b168fa48483c010983108bc2411634b3416f15b7e3b366021953f5a8a44270a4dd78de78786f3a42627441e35f8bafd2658fa9274e7b787dd642c323bc298e07f0526b73c4c17dfe994672586d545a1b7061bf7b44352a846c75726b0e30b7ac02c962ba90df3ae3b851dfd563698e1bccfc274235897870a9e08a853f8686f7b65099f4753cb21beba89168a2081bb66af33e1c223e37e54a260400561bfa3526d10952c7475a6f8cf0811cfa3637d8d382ab859cc43795b2177cbb6da0bc0899409acc1c3ec6926a5a100cc514c2ac2a197cc1ba8ab4e0723d3cc0b29d29515307d60ab0c1a120dbafccc1b5b54c91023a3bc16de79a34aba5777564d7ada01652568b2971c34b58d36048aae34c70a8bc099a4198a586dddda0d83b893c9bc5c3997c0ebf3b1e789747383189436960c2781decc27d15b7467e015490a81b0e1461f7330fd75690cf7b7d836997c78c82f5c92fe265ea24187e3ba190e85608ad86fa8ea465ca3c196096f175946140c076331c4bfa8793bbb9ed83404468aaa48c71bbeb7ad5e372849f36c3414580d29a593566e9082ca7776b2b2cc8b38f06100d93ebc7b2b78b6b65d075f5e38ac05959cfe4808225a4a232ac22f16b9c5953cd6cc8782902ea0b114987591c02707b8d04c001aa7b4e5bf54d49288cb101efc5adc12ac7be6419ba94cea86685d9a499308abbab6188adc9626d5a58940a948a66f0e977e19097d2f97b34f622048f7740d159eda16aa9ec37ac68ba08e2bc4f8061f1172532184a0d8b7455805818dd18260f81924e316310a153927624559ae6c7398b9d8ce57b185abac97da280fd4d288c02bb09e2b9c5fb80ea7ea6ea1a5459359c80af1aa71fa72d03698750101e5520dcd9757ba29ca70281bf06b963e78940b2a557df0a658526ff7ab0017c5b8bc4880375920d257a4dda524ac053a26498be4407dc490c4f5e6916d8473d9332c943b43841b649253710fb0bc3c70b64aba76ce912486665a1a910626634d7bb42a82134c8fd5a5411b824bd9a0eeac595740705f37b7f52590a61b1434c4b2a37aa11e1358d94902b16b907d975c6479babac19461029c3ee055cae844bc415315b72ab032a13179be9ca35ac925b653b914b4c6a980075a7f6ac9d685c264f3aab5462f23835effc51704a29be2754c4e9c292a20764603c8aca9cfc09ccd11469707578772549a7bca90aa01a0c6a261b5796793578ec1222856880a9d568051fc05ba97b5abf821c55198f95c3938268deb86c34dc816bc700e834a5f35d10242f3635bbb4ab8d425713b1ae8f29b99a182b02c26961a4f4cf238548c72adf25cc21743f0dc52abe62886ea4644c1c18d09a3cfd8cf0eab0dfb47772a04a9e577baf96141f4397b91f834daf339fb25bdd6554255d59a3e6105cdac38b25923f316ad3795ca1dab81601a1296cc05032486ba1b21f04c96fc4b271ae55411f04d4de8c9d7ebbd890676238620fc261e162a8bd11c409f164edc715a43e55cd78a6780b9b696493a2785c0b11c12293422170a03e4681eb4ac5d4ca196790795ec5647f9186c9c041463f79f0e22b412c68fbbc29acec1ca8bf96fa0f02fed085dda074165575a68b69c93e6a38b937fb2a45e42c9348a64934cea9a479065ee20216a212723668db09c4856625eb4e21192391f6faa41c93619709483a9196a3d275491509e05444b32ac17b38ccf573849e2e9479c57726ed262b3177feb26b706a703cc405a6c013ba961835b43774bb444001daae5a5449f1058b042b778bb55f43a39f45689db099b73fbc76eacb838c3b53456c65bf0bdec42b09abaa9b467a5896217b0906ab5d69e948681d6149bfc6c27ffe6cfa476a57d061d646ba48191818ae7a85670907d0006f7872a345c8e20c0725dbaa5e7954c44f6a95f2992b9f65b6daa9ee639408d087f30c439d9638ee8a8cf696990ae471227ac4b316187d2b0a464700e965ac0358a0ea991afa68ab73dfcbfdbeb046d69429c8c109eea402892b36e432b1257cd7f477836408c252575cbf17d9ad75d34170c12a6114553140767c7e0a008572978250c36a8a28f699a474bc54fba9c9ed9971e1d3a86a0b79778699d2de72027ea4fc5d905fb1348e8fa586f897443dc07e3781e389a7e77eb25ac42adb27560b31558ec184b70470743f861ed6936fb588607756e93a6a49462ac4ef541f38aa36404a3a6f70aff5742f437000f725da5ec626edbc65744215e564adde2480ac3cb78e67d8023c819bb6d92204ccac87b548b1712594e50f614e1236b6b45ceff2060005b37c9a738ba892136e3584f49b5cb5a1aeb99a961bc17dc860c1a2b930e09866b244383b0c9b7e41be6074026270795a02172354b311bcd6d3384cbca41e829c1d0e2b18fc66b7db34e64ec25b4f13d3fc20d8dc2a9053a7c3c11ab46247937b7c30390f6ab8b4659fa60dabe3df63a52779e974d2ee8c70ec3f721fb0a228e372e3f64551c6282008dafa09259b0c23b3fb7233e2b3f0d9002abc41c1687b93e7a11e094196be1890d380a5708875a68d5ee470bf3d46f0c983ed0d8430408bb7c79a8db6343d4bd6ac5d25ad5 +ciphertext = 4d42ad3c1fc522cc6427ed0bc79b66b07ce8dea0c0f5dbcc342669687592cfe4402b9798f8f572a0913ab661425aa71b6ad187b56a1454c30ec43625b68133bb1735db24f1af33e66e377e166ed0513f16ddafa6a8273add094d10df82d55519880d2aeac679117f521f4d79dcd46971201334c1107d6fbc8edf550d12d9cf4c071d7da39d898be1938e65d980ebf62d84624b6ab76fd196bb48353f5d1ff31c664e5fc3fb4c2ac1e0e22d410aeb5800b8915b7f1ef60f30f324723436548c437b80c674e86b8acc112bafb28243a425e6fd617d18616284740b26c7041ff20863bc010a234b33e39a69f0123abf9b297b7aecc55ce0ef8ec076c2868f0270d8d4e89ffc86629030ca027f273f54a91a660311d478eea37755e072be1d8f1d0ee4e5a0e267e3e7196bd7ea3f571dfb95a750c175c23ed12e3106bbbe957267e38b69dab21de69be078922a5856238ab39636fa17cd2a9a1d2a81b35ffb33953538b3a5f3b86b71950a6f0801e393259be9ba6ce5eff71af9e6944564f4fe86dedb684e8401e47326f78d78dd891c6b526d8ec3caa8ac08553de4c8c20ec15f697ec846afe5480201ae76696c80a3d65b564ee2fbb7683544d044a3ccd21495e555496bfde843e69e45e6c2aec40dddd3465a7822e50fd0c0cd3004782fcc4b8d9bcbe34186eca92390b51920c594be4e82f0c8f2a4fbb316ad24fa130969a0f745df2aa65c2b71f58038c2d541fbfcdb8873b00defc200678685060b4b98328490b4ebbbea2a25e20983312ddff07206727688309e38c310d00810c121327489961487ed8e32bfce2c197bd6ede1f5ea229d2d7b9063bf62c17c816bb8e2b7363624e1b9346ed6d3b76981dd882afe84fdb95583756ddb8da23e966c4e5196cea53a53a0d61bbd9c7506af215f12e67ebf892392a239fa89326469b89327eae87c8c86d26e0a6c7973c355ace70a3e02f9ff5f2cb1b30a28b392c151b3ab24002c86614ba36bbad0fef65c37180dd6dca6a75f4d8fd1b35baa85592f203475736a1f6170d8975a2cd5dcdac9677a0ee8f01920559f495b9075e290936e6faebc19b6020b07c06a3ab4e5d52e9340432ede4d6d4011a45cf931729d9922e6871e0b9f295fd85ac742628964f865b50511503d8c451953882bc386ee4d5e823e62dfaf775e80b3fd0e04b74e58c227c6122079c8d13b6de67b89bb22d54b5ee14898e3bd471654f0f797fd2b841068e09985521a8b9f76ec069ddc81eb92d9857e362edbc0d2d379ad943c872b2023a0ae9115753e22eb03080865a13b638d5d3eaf9ed4777f94b32b746474bd1cee44ea25e0ba3fc548fb36310b0df4f0b939a9e550c497db93b377742033939594370b1c56e7ecb0365d67e55b011d4c7cbbd932809787ccb2de884b62f5eba5a6e96726374610e5e3738ac55f687fb70b9738d61e5bac8acbaad1459e9eb6b9640606349cb0e056762e4feb11d515ebeeb24f01e0d850d1056c1f72ff3815b5fa63df624362c84c0f3cb0341843d09f35897fddca3a61766a2087aa14d49aee3bf748eccc87b21a91e261e63890c4884facd178662e2c9672ec3e391e4e959fdecc2a6fba662f5fc3e7a1fa7728ad808bbe9b7a36e32a74934f1a7c9918177bfbc157736ed273910c90fe44edfcbb80f6799e82e7b46660ca628c25e2f85d45539151a31975742089c1d15cd064ec6b7d5406ce638e13e79c70c7398c28b8a46b00d7518845a35d27a810cc5a56bb1ef54fd67ad78afcab4fe374b8eb570933b6873003b973b5eeb0a47f627c98749c07e58726b0504eba6640c9de220c464d932f54cd000b85620dbe531ad88d1dc8a41111eb1f8f367d7879df14f8428d73b927527f49b65cf445f802bd0e8ae6444c7d4e6c69401bc312412e9e8aab84a30db53f3c1e98cd2c423743c8b591b683c1b79ea23608054d7177f237c7a5db92835f5e10f549892f4d9a981ef0f7a8cb60ff17dd9b63c08d54cfbcd197551a1eac9ce060e35ef7dc73f60038a5a8b1309b198b56677a375e2fa21c075be012acbaf8d4ff8d40a7a2eb44b4a8b10b56b626a5519f9530588d7afe08ebbef28f8e0c9d45b6155d6b699ef03b8e2e72a32d2eed47ef8979717ee0b19755ef80169281a2eca98da19c5bf21afbc80b4a83114ceeceb303b036ee8cf4a7126f030a00b6c5f0bc1abd81e308274fbf05f2b4652e5acb +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 1cd9373175369ad6b50fdb33d26244bd8631ecf841c3ba5c5c0a1c813bb1b0b96806f10900fb4701c849cde63ac9902c611601b56c07bc250c7a2b51cc326a216660f28865a6d470021739b144818b6233363372afa3a45b02456f620f13ab925b1a9fedb2c728649afa85c079120c136c4fad792469e424dc8baec3997b39829e45bc8868854f1819c17b2524c91cbcabf686f316cc9f0559d67cae6ce2b623a19c13a07248a10c03d5a1636a3f42981d7b8667c33173b009437184ca3e22a8a1e74447f95f13e979049a8eb04b98d490511cec79d5b8225cf348e9a325a03325c8f21812eacc64f52739029c5c7704e438bd6f70029a447b448aa8557431cbca074e4b1e4011cbd025c48de629ab299d537b86e2d224917176bb5586f6332eacec73f678764f804f3bfa852294b1218251698386884a324734aa33503c61485b578b6b778846741142b096018324546d704df81a698305a4ff782bd6ba81a31408f85cc6d720affbbc9d3db732e7e4a9ed79c5272b470e3a0c64824cd56347711b4bb08985e1e4196653a6b31c04cdc5cf56414cb2095baebc77bc180aa457982c549f55565593048114669619454708861f52fb7129f68969349849f503437c682a86a7c7fc43c072a8bcb80a58b546bc700ff7db44fd50c6a77235a58b5f0c86a2e35038afc4c79cf225d63a55ddc8391f145de7c80b00648ad9619ec1691492f6b5b4604e121a257cb75f7ed9bc28c0552ef6ba20a3957a664115546bff5b7eecec0b4bfa828d2ac553455b405689d184b4e45898b9838b257213dc6b9b6970cb976a33d1915f387156f2b8ae21256a21228cb9d888361273f7b213c5bcc935407c3c409c78662182358e49159216013100b76c40d9be8af0680342759f45856dfa77a3da370c7b36e72681aa913577bac0a41665997548b34c6d7553659c29077a84834e941b07bb7de73148813b8dc9370e80210aae00bf63e60cc0dc935b02a70ec23661f0001dfb085747429e279f7ca941804656652c3522a76c71f0cdac8162f807356c26ca883c011bca075b4ab9c753284f35a4d9c8c2bd64121c7a51d214c0fd79538f72ab697b17b54122c4254b6fa2200743ba5f9bc90f318407b3072ce0a5524422d171448d2673a4acb10a211ab17c1d983a67eaec91c32544746951ea546826963589c6a6f54729e12164aefc81c2da5df326576ccc95f76482506668f5612b1da7aa4e43ab1b4715b7680db26388ddfc2869323b2760b6ccf0520c063e40110cedf7ce60e441ded7bc6202332ef743625167cfe92e41f1b13999c165e532db0359f7dc929b9b9fd9b06551797e5a07262c586610045d4fd93ea3e202b1853a9341caa266180d185b5793277aab7fbdcc871140ab5e48c0580b89552048ea011059d024abebad07f6c929b82094bc5e7580165b98647c60a73e7358bba145d961873867663cb223b8461db8592ad88b7457a013db334749d303a8a5b23a7c74b99a7b4302056a96cad2272201fabbd0a656c4e0bf0ac66ec8356bb110a534ebab6d46bba24053211783cdeaaa70888e76a94a0aa5014d60bf3697982c1564f06c2a2fd25163c83410470d26d71d3df01910231afedb14aaf0cd6da581f945899c6246e7f57262875be241a83c2664c9142ced991859325c8ca45a597301fc0543799ba1b41a4bec160205908d96032324b2b87b03544555715908328de86d06cc381c284479523c4c346b4fda62f723c1f047aab7d2bbb040985a7a9d1d629367c3a952c0cd230631d1d499924b580ba250cb54c805d64dcc6a57f765a938402cc839481429c4dff0165d960497998964622b74ecb587a85a9bf95873a3cb63c10f32a0664db05c819ba8c6f907aaf0c6c529c097e914a43b3a3789a993aca719f1beb5d036bfab1155d53467f7a6fc535bc73a5d91320eef8c39755388bb48b228224ad4b324d074177e869d93595288f213c5b4b306e84c8e59489eaa3dbf597ea638003664287722a906db55d40893624a0a1e496547382e636cc420592598bcb49325caa44757e8b9a52644c3f0d83771d206f03aa73e281b26f93eb86bc5f6a608b25416a41a47efb074acb19ea756c80f297a33507fb66288ffb272a2922d66172812cc4b025718f5d90eb1fc63dc339bbaf2a107754698169ec0a9bc207b1faddab832850fb924c8d028288c64c8eacba6a561b374bc776795405b4660ebbbaa746bb3c9a5a92f42663ea1813247a7448285504c143f056069219505f110282a8672d7a025d40a3d515c01d3a4798b657131759a9991027bc8ee76c16f770ce779536c2c814b52bb05206c4ae74613197cc2e12d986c121525460a7c67c44666d060bc3f960f82527fe5e003dd078e85996f0a0a3452ccacc7db480f7bc3dfd8b86df5a0f31b6095a37bade57b8ba59dec694110bb371f039c5aa8bf49f04f538b28fdd231f9999a3c3ac600bb585633c75b40222ae26c3ab83658d9153b7c65e900895945b5225c2147d70ffc570920db2394d179594b854fa462d99b5992271f2e858bc068a6ee7077c3c29e3b2b9ae0824bb7245ac550010e5699bdf5885f4479d228c4e7aca69ddb67f6619560587ab91c4978016f6d922176676fd181b547331a762c5019c79d56d9002734c5d283512f9cc99314774d070fb97895eccb9dce142b89bc2a711ccf045c09018990cd00c5d18937dc95afd2dac4e4139331e792958a461f1c99ebfb85b1c40ded170131cba621da9a36954acd718ea30bc473c1b1578b5a8de405bca9125a27c32b760b62f8b596434019a9b787348b2e6822df977d6e275eab5aa4fb98098ba3bda0a621a64c73df562041690c00d23d25e717859a226cb59d331b503c323749314df6935b19f5b503e43432c37ceec240760221570548d34428aa17be5182bea31a2174ecab0d6525d54349b2c72889412e82c042f012b832552694585bde29ced9321e1c249faac3772c98b8c5d008226b4918b84d0ba607f612a4e9d5c872d462697341fa413967ab1c2d97c199404e34259ccebc10c5650303bc11e6466cffb44156f89049f08ccb2767f14aa0eea02448120398f18ee6575626638957d4c913258184cc68c7551a6422ad96d279df92ba5bdc54fd539b858a11a3b165b4ba554aca66d8052f56b816dbd874c1881be26c1911748843d4bc00339e20936abdb8b3b66432f735a46ad70ec7da44ccc99566286e4ddc447ee03f00a45ccaa64d84d59e9b527aa236187d565c9489292c130221228a3e830a01046e42783a495b128ee9bc1d468b96528404b41df4c79e414032c1259b6b9c73898190d124a1e665a8a7f52150ac20d9d9ad57d3ab9131392a794037112e8b67c083e053a354a56894a10c4122611ccdf5886a6604288d4aab4ff1c23f2502ab911d755ab2c77571fbf38617401824a3b7bb3c7a44e075993015319ca47788b18f45165411a01a241328a37d5e0490910a48ef4928de8a6f395494af940457324978793bdff728aec4a791e9b4fd74506309b6c6b7b87d8ab0d7a1bd23637cdfc1808c4017e2c84337639f65d82139533942697b168549f0870d2be561eaf3accc140269f6167b3552e1a4346be820c862b1360087a97798a1d741a48314b98a4964f97a4c881e625ab67b9b845ac8c509a6b6a3465abc439ac86b355f3c75c6d65f24d9bbe5d92668553c2a6734d0da4ea005cd9e24943b0a34c13319cc884e11461d3a19b24d6ccbb5fcce684883fc031f253519954c19cc0a0213b6877f8c33f4eacca5802e4e055a3936187b1385d0d1b090e7386eab214c90c80465a0bbd563a70134a48a1e771aabc17c4e81651c38e140bd8016988b5d66bb5a706836d5d41f8f8a85c282cb86893a6f0a5ccf333c77e063df2a271239853c01532e2cbea5db2a557335ac548f0c8937efc29e62ba6541a9146cf4cab552ce3c2c16126118c9aacdf844b17927c357b517c04c424075bf24839a513cb72163729fa13765759c9565be33b50d4c48940c4c987a157f05319c46393f93f7c952eca54f5a636b05449a87a29583b556156110436d4cc4cd610062c577408cc605cf900ae04678234310436349de039256277b738c738ee41eed32369b9b5b9e686395f1cd5af74a1a08bdc4f10b7b50c7d4c180355660e6c5930e584d322a796bb954dc700f7df0b756723c24479da99669b946b663c71b4dc97126a0ce7e300ad4d4bf2b27122f47c62fe13cdd0461d0e3cca868c9eb9a2c4028a99b984a6a272d04602598a4b87ca932fc8c725bc235b2e179b5252332d5afb3f6c06d4ca18b1915fe4cc0e2b21fd3310f0094bef2d76e5af4c5ab234cf6322c91e553ddb6da4d1641c2bae46e1fb45e84118f872dd5345523269fcd1eb8a9e6294ed4f9183c154d4f51575894aaa393014cb240ba925a230df8c3aa6e7e32eed5fa7ba8676702aec7444f11126dbce2cc5c3301484e4148a6e5e157bbfd3a4bb924 +ciphertext = f0bbc890cb09f04aebdc4c85a2934db52e2c399c519604a01196163b853f84b287d05950bdbecf1efb99b06d9e8cbf5b97dace73427fc740d61a591f3157ae6ba0a93917a37a4d3b6b8cedf717bc77fde7fd449911c680d3a9711de9d358fcaf4d94d20f32feb63bb498ac9f9cd68249eddcdd4714c458f30855a94c9af6b7554ba699498a1776e0036f0bf35622a03f5e334e1e53b92b0dff515319770dad60bc56161253ade98de8ca550ddec8f8e8299e1142154563c109a6ad788c2adcef65ce64b2444fd33c81fed7f8434b924123d47860a6d8cbe5f6ec7acd1cce428a65b9dc233e9ba1102c207c188ebec87b56edb757b3a92201e2f75b2e7e26fae0eba79a0c61f81a7842b54e6d21d8d1d5de0ca15cce0b589bb4da1338d4b2975446a630ea64b09ce73c77b38906356ebf2152bc27550d1187e6f8e9483371180c562052a50349a0583fe53f91c512b38ebb0d684940d9d858b38c875d6e382f2a7eb5e7cc85f29cb3b0d7646e42a963392db7b3413ea7c70968ee914073720e19a641d359c025aec9bf4cd895c1a5ca26dae81bfbf3a61b9f26669d32ad7009ab83862f8aabced22254e30a5235ac1e5d358bf8ffcd65a65849642d270e0239c1a3261db00d25ef52493c076ba0504de4b33dafbee00494ae471b237b1785c5292de83a153e687bbc745d9ad6efb681c62c956e81036525640a3e77119bc25c1f65679fe0635c2a11689d6d787010c3fecdfc4fd400933a7084fae3811dac509159983ea26b6804cffafd5f2eacdb07179ea16c10a59db7dfe48a9f1c892f91bff8aa5757b2dcbac4e8cdf0dab8fb7d1b2e4734a1b958e0bbe8ce2e00a405182860b0b85fcc0278f8c261df79847005cfbbac2a879938a681d7a020f0411a5bcb25a25eb088ba1448b41055518370b5320780331ae3dc9201f1f58645232eccfb9d5c2f4eef73ba913c9656e4f017ca76eb0952fcf6e91719daca6a6c535e82293b3d59f7405c2dae43819b4af824e2a0fad20a467be11618593795c238923b9fa72ae4349ebfa4c0312b625e2cd71be3dfcce3b30b81328256c11ae4b7d6e59e10ac28989daa58d88d744bc9021d461149a920c271eb7a99e48dce03c6c774228ed1fa1a79be1bccabc2416a75db437529434dfab3925850bc24efe944edee4d63cad4997c2735f96dfbb4846ad0e8ca627cb71ca73426dcaac4a5d01b300323911956034e86850da6ee885725c0c78cdb35dc76288818d89d402f1cc59b8ab2012ad561662b3e06146ed303635595a2ad26b57b678e7b45db36749f34746d2aca3b8c35a34ea69476b89fddbd0d908e430a16c4df189d091cbef133ee5d332e9f23c7f29f242020ce1ebb917e512c4574d2abd79fb9abf1f5815cec361a2b7849393e545915793f522b8effd699248c292fde8a0d70017fe2428735a067ab87189c643ecf816def6b554a5415eaf0dc3bf81285c10130bc4d2feb8258e8021e716a6b69d7bac3ba5122fde8105e4f77c9f79f0129d462731e3e393dc1e59a8c49d8cb0d8296ad922360d6889d781964b5d117e9a0e7424b6c4a46570b63c21b5b5dd21521c76b83724b502fbecd0d0d965f46950996fb2674d97759178a2be21e6a9b111e96136f22fc7d39b9f8ff7e591a79ccfcdef3fd626c00208b6e00c7e62196f9b1c690598d2405c2ec2c9c6ac76ac0e7fd105885695639bd256bdb4e98acd89cd58196e982edcc5cd596c55c970a8538e11a3fe9b39e31a77f37951e65484926dc8057f80563a8862605c57c373bd2f610c7bd5937d5fdd2b862d6eebc88d961be5905786d5b08326f3be7b3261500f034b02abad05a5a59f89de8133a5af4441c02c0d49edd65444feda7749438e278eab050d9136eda1a7a79a74197af5e1ee6e1c01e2f83518dfda5324652d1e3ef61ba26fbe3f81ce80cc63e0ab1d1d378451c93e56466a8a02dbf49fdcf5fc44115acfa417e305bbcfe0e2b1658b482efdc02891cc2973dfaaa6d6f899cef1904f6903f5b09101a3e33084038e4154db9980a3f09c4ea6498b77aa31edd9d6f676722924389045b700e6e79ae92cbae3e4f2bf69a623a7be820227502a8e6a571c1340479fda3c24637de9b176317dfaae4395890b756f5e704cd99f2b3199cf889d7867e3bf2b9f7258381e66d8034ca5585baebe262f647b95ec2534b621ef37ad9278ee153dba45ceb4103 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 25a91c785414933966f5598001a985cbe1b3f1c07c118a0549e4133e643268254ec5c8473ee9538c899847caacc50405f1d27092358fe8327296325b170a89159981c1b20649f001fff75c59a1c041647ef9787cbe903e94fa3a720047f69c838e141010153dcad7a7b2c47c13346b287ba8529309d4ba7d93595e57cc4ac5e42b658096fa38187092297d6137911c2ac7f99b8d0587394473de1b7869dc491b824ede343d950ca7dde87892a79df5928d4a0770816a6c98d1459a412f37fa6b845c7f5395190a64880364b6afda01da4386500103567a7503ccbb5f033913b12e56eba1a3819b75a8aa665ab944d005f8a982e894638fb494dd5b638775309ee08b25d48a814456a2269be56b0bb321a51e9815c55c45e384bef05694df70393bacbf8b4b76bd183393271c3181b278092b18081c3ba8b2de4314fe7821c9b9bf45794f51e0263cc13c61f98106b26b8a182924650cc7d81ce032c3caa11730406b2e6558ec0b985982aac9e0696842906997b8716234ced2593c171bf09a8abceacc2f9b1d43f49d9bbc5bb0b104eb6279cbe94b0967969ae5161e32725f08b52bf9b8647974d7f10d827b2361c8c59f623f94c1b5406b43778ac9b0fb5298f46a86f71a09f4aff89306ef0949b37cadcfa6595fa00941ea8880a8c2001d7c06ba3e7178923076631a9c5e5ee209d7b2ced26b4e49671316fc25b11303f1046d38374aee878fa9825aa106c645d9b99005a4a93c7b25119296cc0f0e956173927cb1e2822b4882f087c4df6aba7d656fb00cca42a63e36a0143b344f6432665694101b0c2bd85c0fe419c1eb7473c126ac3733cd1d4799396879d80a93f7975463ecb1c041a8513aa377db7b19902091f70776c2857b05cede6a3ac599b81e42006e6a6a6ec09a410878e7604897f79368653a945251ec7b4b005d18343b354a9564acb27db2c9963b104f76a94735c08b7c147c9c420560a18a44863e7c9085e61060d299200b42c9bc4c088540807ba3a0b13764e5a0c0e666afd9962693448e1db231e9ab2f9c880862a1c6bd3b4db299a15bbaaf0ea87bd8037feaa44ba70918b2030ee4064cd69a5e10d7a633d538ff49316533349cac623c2291b9a8a66959364a218a019201e43a59d68694587231b2345d5748a002140d87301cb31878f980178602616de906bfc1aef0e991be6c0f7089623e686ca956b3630936712899bbab9a9fc36105f67f105ab6a8e4c34540628b4cc2fb6a4221175ed07b7a63b5b901a925b08c274a40b2f435a532433016c9496b20571477110ae9bab973021af5b64ea366c852cbfcf433455907609c1e347a32137ba33b8bbbc667a3f91ca5d41432e6d3ac899a5f912538eee8675fb36fef04561069ca7877cf948194db684484999a5411a8562161dd0b277ac114f7636705f29a1867cdb0371eedb312b022047b75461100915fd58bf4273d4ab98db4e258d46641b6319181ecac50ac8a1f3718894c3ec41c21224b6a8584373a8b301771216947bb45840e74a3587cd40044490837fbc9986377f111775af276210555e1b8272bf4c6f52a3390487ad5133e5fb962c414708dd94ce7aaa308288cade9be3e81862485c4edb7b0d1e69e33ab76a1457d96d568c7c651d7e7a7174c716ab636ecb7ce0dc10c4c72a244057f85a57343cc2c64239b438c3015ebab0a1a95e0088017d29bd22c3af74770cdbc84ee9c867a801a02d989423538738bc4db764cf69cb67474040fc1899a39287a28ba99dc78ac19081ae20497809034b070e5d4c597d90efb1c2d92f632e6227449e1457461a61c004c11505016530d9033b4f16b53d8d92e30717b0ab22125d200b5aaca1f32ce9f96237eb898ae641662045828f969765296e8a14d5b597f60ca5510164205cb631825451f109b5692835dc4a85c284c85eb5ecafac91f53a36971395390281671cd02eb45504b511c3b8d5d2bbb644721f910b7b56050a01c3a5e0bc00ef6a1ae784dfdc8c06034631da29f8d93c99fb4093746a829c42ada97011d58bb3c643911fb50c77032095380b2c5ac2729867d799d17c2134ef2a701a4413746851b82bb5939a4872cbd9a37a987eb6374166d4aa7238912892d1154f8b567a804160da857110c0b526c238d9368f257c7bac7cc8fe19c5cb3b84ab96c2eec0c343923c66973b5d2a4fd7b3356822b4a6c552178551d8c90d14b1941949018c978ea886d67bc6e8a6c0cf03417e4006768d5952ec1864d329774f8c4614377dd0433bb723c7d13adc55611a6b911fd523149563832175f1adb8c88b0a7495472d414b349886a265518c77c8a1ea12fc990c821866e40e18258fc0f33ac507e07c3cd569396850d00bb10bcc95404b68fa7f8cb5e8c8e6d57b2de306c65d596cd386cc0f45a14220bfc3719383b8f92b1c9624b509aaa96f1b967370815a60263a5335a4af1500c515d8a74c5a431b4afabb903115988020dba328bccb209b5eb84baf67efeba99366411394080c3861689d061784c33c4e40e9aa7c5cc05414f278c97da8fa32983eb47c9ddd7bb12b6243e47ce633bb6db47599465ceccd0570d9a640ae25475f08ce15a8572e2b9293c271bd8683018b18aa2756cb9a1d48c50c284127c8544f565199be560e5e90dc1082f1fd27cbd5b42ecb113db326486069e2b66c729e26fdd163be9a84c150291b6b2bc0b2949eca6506b700d88cb71c67c6ec126c286b0930a6763d5aaba9388a0bbc35ff44252b622cb39a4a6ac4896ba6b4b3aa6181fd19ed31bcd25ec4370202c6ac338a4e420723a1176c88147564438f0a47e15cfee363c73c33a930577da9629494413553703b690689c060549752566846a41125bce636c5c78c2d14568245631fc28733cc97fd4f18caea75e17d20db52a55d9bb373f095ec0321da05283d98c6fb967827301777c8b3008107c46a7b661c4580587017cc8464d61b2e275306178827da14944258bf29b27556014d4364846c927e47c5ca6a85f7f620a3ff84218aa6e87b329c19b4381d7b6b21423c16a8719b559f68608f8709979207731a165efa747f9410d2c0c670786570c4782180418f1e873888190f1562e29ea257468ae829408ba5c4513d91f25ebb11fb44d2f570b94c5531891469bb38aae4b3db839c85005ade4172805b28f80c5af5f45570e6573f382c5b4a517d8c99b2fb41641ec1546395146f1514da94e775aa6e2725d50853dff437170482b3f1a51f0fac7541678890a46c5fc275fcc6cb441287147a98ab778d24a84fab9b461bca39f7798c4687c86589965425d0704693c0bc80f23c19750aed5814e29e8a729c106e049074b69a9e78404f4c7514cb877979c67f5b150d7620b2b2a1beae7200c03c6bd625cc7c39db4bc79947073b6035620218f9fd517d44c26dd1709f3f38f4094af4cd239c208a2101903e7659965110ac81b3be7cba0fc3b8011bcb0eba7288285517f2989d3b77259b072d03525fa0641a61743aae64f83e5ba97556918b29537515521806dbb8122f6c7a00ed8937c3c5d14dc261a724735b07b9709a74c7c0a4ea30d851c6a43e15cd2ea569f344ab5402f6ad17462e0ad5b44bdac269772c18708f8b5fc58b2ff0305787c57ee1a7b09e816962b36c91573a1dbc2794068f15647d2b49396e8c1d065a16fe42dd096a1b4387bb3095fc3c4539a3205369225e0bbc5d009a0cf08c004a21ed5e62e09a3259191583cc225dba16b9fcab9acb99fdb797249aa075c41046fe9b87e7b146f215b32bcc60e5503a1ba429120548bca089fa69839496014900e47cb7e0ac1006133bb13a6045368697ab445c0337a43f39cff4378c45b6813b3ab15256b09fc8c8b7241937a8917b9c7a05c1ef265766db230f4954280066b329a446a7111b3700529f3a25376b6beb96eb1616f994359dd2814ebd1acb032b51fb5491923b2ee4ca48cd0746e990a39a6c6b8244bb23c51b6ea984e95418e97c33c0647abd485e55accc256609c942d34d80317619f84a53bd42bcdc32864e3d67b69d2438adc601bf6a93867a3121708d9d21dd7423e0515a58db35f1c839df8999605cbc35ee19399b7c15f89c6e3785ee0659eda411029ba81f2886ee21205ef438223d7ae14d461f1c8abdc3bbbd50c20766215c09a69f6e10872dcb4ed78253bf6388148ad0071683c923ef2989bc84c9543bb712e12b16ab0bfbbfb32ff5217c03ccef3e678eb179dd8a7237773219922c41efb04e7921a2caa88cf23c36952192de18e3cb4b3352573ee13c3d9b13014a5b9afab2f905b7f0ae6379872a0ea90534e8740837888464111ab99cdb763b1c9b707ca9d47dcb79baab3affce169eaf03a0a4a676ef7453ea16196610db17f26156d2dbc36f8ee6a08c0b1a067a796e6fea791289e1c9d2c54fdaab61c50115c805719d1a31d4f0b7fbfc1ea7aaf7b35495e5eff57b9286a2b814770c621e8d8b09408eccdcb18ac735c00 +ciphertext = dd9a0d0ecd6f481ca98bb23e28a63590456261e704469c74280fd23568578fe50a85cf38885ca68bff63e6960be3cb1aef2075393267e8b59a3d96576dd31c331b4de44de7436aa18294b85547a5cff3db1fe0d4c4cbfa11b83a544b249816eb4417e3aa986344fd05dc0652c5135f21ee348a197d1b97fd9c520a2fee2e10cec88be64f55d8e2f8f3cf2fc79121b214de95e9d104ad9028d8f5a16d2307a38ceb4585b9f9b2a50d826e7a93682a6ea9213aa9e183e16a3354ed23d56bd869331e7207bb6852202e2ee57125d7d80b8117d036a1a3b7a260951e71652b826b95ab0559295de086941722433a278b3002d572bdd5bd8f735d0621c1f4f1316787d5d5d7b45ebfa59cb2b10ea69984a498cc7da8f0792ce707502d84eb6d1536865972f8cc1212996070022c12b3607da3026e360d8049743c91d694054a01d6b68f03fb49939866e82f7a52f6ab66c228ff91b79a47b7678ed19f90cea88ed4d3a7a2ee232ec170020cd9704b67f8fdbda91c900d3ecf0ca86952e638e7fb08fdb52d4ca1f0301b9710d41f641bd31f12ca40e297e8b04bc415c61eb082c4604f6f61f99d822dcc8e9ba1e2093441fe5e500d3b71ba3ab837ffa57f86b573026f7d0778fdfa659b70153ff6e587f8d369a81150d03a6853e300d479b495236baaf894241740d66453727751077d43e8d9fee7420f73a69b1f26d993edbc8c5900e760a7da00eeef9f62d99a0a6b5e488a610d17955c8fc8409c2cd9b134a65c89f49e923e0744e156fefe2496d988630c878981227e1aa211810b9e642eafe72e7f6bd6ca1e6b72160c0f72ab7d90dab18c993a3a36d0a73e62d30aa92a901b182c1d525f31391092d70bcfa7fe979e7d6291f79bf70856634e5d24375b8c5016e73c9ee31d21a6a2641ec7654d0d1589b7e462552db15cca17d6c6289423644186ad0c95050acddb54cfaf059e18c62fcf4a1468f78542660ead3ebc16709c19534e8df7ab32827e2157fdf1c1947dab45662d16c3fa59ba9363306a93e0071e60c8f4ec8f1aa4a77533db4c3675cd339ae43768111a9d83740c85d494e8d8ee8b1b578002e94db8bc1286e6b56023c7b102d503c8e03432e6dfd03cf3722ed6dd4e7e7bce6b421ee75885f3f04ed62b1c0ee7c600306c0f6a5d55af011b56160429109a815eb1b7f65d47d4a01bdb07012743051d1c1210942d76508272b252bb982a87fa426f0d560cd828adadb4cc453e581996ba110ddf1f572e35a88629891bfce2fa70943eb61e285f4864fe5b605e9693f911b76ee385a5f81bfb028bb1c4c8955fa5222f63c694e78e3ad267a3919a148c751206427d8511e5623355eff9c210db9e593571795a6334c431f938548297d1e2c877f600e107c1b5fea2890e7070e4d2a8e506ee331ecd2ff2a9159eca5897141c80b5832cd3dffc5c4b7794f1b7d1cb353c64a30f8152d98379661a9bb1a85195d757bbf3d10bbb27baf96e0d61211426440b3f66109e689c94232782f889db8f149cef3223cd2a624b7dbc064f959e05a51ac28cc0185d65fa31433584bb7632cb3949a5b027c1304be06debccc979549527737768d8736d4332e0e3c3c5a58117c96cca01443d7b3496810895106f4dcbc51af16493274131632424708c7f59311679a4f164375f8fca5d755307a026b44a3a6df791a18ea8de900398c02d9482cb9bd156819fdd3717e36ecf2515a2ad66ed0eccb88ebcb6868bae5a4aaae9522dcdb5c85f542144f1cdb2ce9d2eed432815613ff6ed0d7ec37d1f56a89ddcb7cf780cc85fc1c351c2518cda6c0c10f817421bd063bd11b65ea815db6fca3f2bb5afeb46b85819684c89e1e5ea118b1ec0f0ef7ec0b83de3da9e1aca02f7d0fa318f3c19fe0fa3263389e96e6385f9f6da65b9cdaed263690aa3a5211e73f4dd5260129f2cb25b0052c522293247178395f48b16d168d7afc12c329c4b7267ec8fdc3db39a5d275b037e7062ea0ae5163d1f06b04fe93cc45b5ff58f3568b630d4e9ddc60272de3c86db5ee00d44d72cd9070e4b388c9551396948463859e4d156541bc554c9892998a1c547770a2b491452d758719448012e48fc4b5b30976a038f405c8e1e98c630e6859281e39f41a66a43a5174feca46f8161589241f1a373c019bff4d4d4bd9735ea2dbe81c65d7c6af881c19875bdb9eae1054086867a2bbaed9b4e60455b +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = ccf4b3ac53b10ba06994f56027964dc16c5f2c6219b48c51055a29c9e47047ea90d7e821b5fb49e120b06929557661690a65aebe413fde3a9fb4734d0a686de6fb8fe997630b708dc9f62f96d5c368f05ce5b7852a353c0a09008fa51c52c8904dd2c537d4979da11aa73b96d8b520176566e0168b68b025a899213eb7bf48724874c948a25582b01aca2189b794abc28d10151f838d30d9416764c32c588cd8b73cab791507d779c2296f4aba01d9989afbac478709aa7c687af35a7ecaa44d54c38bae54ca024051ce4907526958c1a836fde6954e10ce100958479492e3715587f059fd81b4cf5c3b91f9a473807d5493168de97dbcf8c513cc8f60d5384bf04ae7c63895e91046182b8f122bd226a1145a08114617516cb2fcb0a96ec03270f38281fb66d2d9187ccb4eed45047e35b21851afe87b85e7d43aa813ae730501ec744cc0172fa643662e8067edea0a97521a2d57ad117c3b284530e7562565129a4f8215a6eab40d179420b53548819b59a524e7f6456a5006a7670502b22d49e694ca4ba49187c7fa6c861f3bc0f0060cfad4be10038c9ab82c8075236c82820e3a885fd083aef675fba56b80612164a7a8e4f89eb75ab52d59b2a6360ec00a74351b61612113c942ab79504084c0c80a3b5a18c37c86b41c8c10007cf8056e24ad7b710c92a9a2764c162fd42e49fcc16d0a26c68c0940238a734256e6015d53c855b9cc8c3a978734c623ba1a9be7972ea88776e8d81f2129343fb4b8baeb1779f64da810304ecba1f88686d9b60116d693a87cb6985747b1255acfc70cfa3c02ec33652555368f898fd68c0c81933fb9770cadb513287b17202b6e5e603a9099a2228927cf769aff63143b0274427032a9a8bfbd7b0c853c22e65200253c20fe6b5e82bc9af28a8689a12568ec02ffd856fdc86e51f50a76457c748476b6f28138f7cec8b27258f33f259850ff57a8ef785bd884c156ea5f7758950d00569a6236499046a1f17adecca100e932b5c46606261310b2946f73688509330da1b6c6b7c57c01006f7258873c876155c1f467c6d49a10dc737fb24161c83723d52b3ede6c14659a6f03932c8f52452088cf52fb5e758b0cb9c3b1cd9b223db41f97807192c04c80068037507859410bfec97a1d685efed199cd1ab54c4124c8e9bc839284117ccd4ae508d566a19506ccb727b407fba098bc451d551896e30b7fe1563b1590b783bd8f8ac866e54c3bc233ac4a33c30c7e6f8c7ab1b93bb15c8ce155c4f5ac24c2563583811a916c8fb7547384ec8bf666900aa14fc7663f3f2bbc3b36870ac0366053129102ae9358c2dfd3157c590a362178e8670198a326ad687ab61b88b4390f2633b16ddb0d9fb550e3db02f3e9acc93cc9e7945d3d23515d684235bb2a8ada2e1156b0e4082121a2c88cf0b19fc96b82dc90478186810374b7f6049b2b6a3e2184373cb43a726d10b42a0e010e025b9ef970b5868412c54a8bbfd3af4059aa0295055e8686630b234298c78d40c67f8297c66284d70876a98a04ed9979259a48cd82c822073994f3a1eb89c29f1b628dda57fec320d72155d325b911789203a039d6a30556d54031f26f30935da7d37f1c10b31b36226f1c69d257106e81400ac93877e2b1cec52454b65e23a888188351f0b277f42c76a3e22ad9a0348d678b86230e7ad17c83673ac3470a4150ccdae34557190a84a4723fc4126782c0b07b65cb84c56bf1bb7d9b2959d7596333229f065d9da18f35799800d97912841da8678e52631b7cb48a69d797548bc7823678f76617632c4b41038963a60be30728e710100a12556cdb8a35e049693437aa70712727ae3e9700aa8c846c56a91ba8880d063a5634472dba093cb637647b0f7dd080c32a0de06867114997ca5a113cdb0217c283bd675b5ed727ad744a6c46a93df8503b38c28eb3a46550ae1330276f6424ab81946d28a8ad185454c180b59c7b2b60b38ed88447638f943c140fc35d1ee37e05c503ce19c7d5aa64d559568628367e17147cc2cb5d80c90d548c13bb5f905b6b25e2ca24e1690a6740ffa923efc0714c4462ad789022b6b73e60ba063a90ae76b9116b3c80ab45b0d1928c25ae11133c0b1432ac1b029b98a5713284f637ae504a534c971fe1922b171c7231080e0cb358b9c25f5d67ab6aa58871dba25e9204a9930d84f3ab55cb324ba5599a2c2cf673522828cc432b926651ab3ee5c708f941470c5dbd2c9e9529185eb8b20674b92f8756463acca0b22752f976eb9445decb25705bb46d977c962b253cb7489fc239c76028c6f673a1c332fce7015d78474009093b032e5c1b082a01ce833638fcb935f92baf92c3435d4a0f097b484368b8e6e0a87fb4b25567901ea03a509866b3c74b66676fab79b6b5ac77cea1c5d170944e536e916a214424331ec88b8ea06158c38270db09e096a97e5a50c64879550189d4447800712123086cdf57b34cc32a4fb024f9153760021b1028bf19298383bb93328c73dd598cae050abf1c9f16956f0ac44ce1d0c5ed302c8f5648522370f1658b6b84b2b6e37c656b3f89036885f2825dd383ebc2005a519f75bc439294195e760284d3c1945b185860291a4a4a8d3840d5c77ab60432c7318dcfc2a0c0916b95025237375b310a96d63b41c9c82e8d1101a097748c633219805985d216a0d385a477afc6ec1c61ea4f1694c487a60ed97674a9c2ba999300da8b9dec5bc56f666a33c523e5c98f9e0a296274ae3201b6cad045bde1b12cb5471104970b797d83cba30aec3fc5f33e56a2a60d844c9576315cb9757afa70082420af958b3f7c5107b090dfc3cb7be08792eb2cbc27c40844ba80a25345c9c2292b5bf23831602b1321454eb93a66bde4767b27493d403250c958c49abf1c61856a374d878325664421996b2ecf5abb0a2206e32a0fa5c694ba635f52c3983583899b1ba83eeb411fc00300d6512c77393eea5bd40c6bbc15cbaf98308b1537c0d43bd809586f57724d7b1b4e2bb03c557224c33f1de5ba48274e2e5a6c4e68767f30afaec7a611b8ae642c27958cb17a6a7285358218008b8f48577da1b2181a57c0d4804b5ab9fe892e7b911a4d9c1578e72617eba5d813ca699bbcaaa70668e3ab932a4061a58597f0aae2ac1875984f8e4b71a0f1cdd7ec7497645a409081046809d0b3b886e31a85200a4527b6c3e07d60b997596a750cb7c380e708271a28c09bbba6c655b8e091e796cc333b2fd15004ee98246f79561c583b160b60bb812cf4538e6bb0cb47c16699a07d643c3f45418b4b1a2ea789130b973b1e158b4d6c0cdbcb8259fbab45e38d80a87d3a1c522641562b79cc2743309811590730676256b925782eff065147826b37696446fa56a0c4c021a91828b3a3f09a4c0d92896542866d3395f0b09b22b818aa63281794c6a5b9924d717020e14c74aa4c87aa3617b756160b68567bbae7520401355a1b8542796678ccb1b49b618d0b8b92b951b317f2043b888eb7e3563d9c4cf305a105f1531ff1522205133c3855ef504b86431ecb608fc0a515c1e244a0da9520accdbc031453e3778978a559028bd2b14bf7d4a28e838d53f0afadf719b938c4b3772b89323293f83a77d79018d65ccf094146216bc6e029061ca7ae315a187489d57c6f395711aafb4922967857a8998e790769d94a95fc09f5a1876a3698e714a7a8a46c5209331618c9c5710382020e6633bf65c40d8a34adfbf3b2cbb8211ca608ad061a8544437cea2b8139abede988b828571ea6bff8342abeb1c5db57557598027230a399832b951cbf42659de0584dbd0c37eca74ba2f068710801c553b36345c1a81b3273c7a97ac3414c944ca2c615ff4562880265b45c96886070cea63972c44cc17b7070501452a09f6d4ccf4cb5b7e6ba521fb510be81b6ea357289bc1665a154c5b0813c7a88d6d9a8948492d4e0521a676a54b881d1e3427fe5a76c32c35fd397e9dc7ca50b8d91c55b1fe01fd5e4cf124145cceaa9b5b8a0431aa100b67f4d3969a664461a423826fb6b3975c8e9d4be74d1046ee8bbfc92a45de62a11b36f81c59433e06807b768c163cebab74fa4c73abec6106a1898cef5a27012a499a07951f663a87a1aa42b25d7b3031a3a405d96034cfba9838380ad600ae15ab1be4c974cb3594977b9483361a79244b920ba24cc52f44644bec12ba7b69535d723e67176dc601b71fc59211321347a73402b64852660e8a391067b1c22d1adc68392211a2003a0157cf0451c23a83277026a95b77c787a42e67a288859748a8fd89662b62c37edca4670d57be2537279d39ccd84adc25354f1f25d01f3a8a5f7e669583b83fe406183152eae7b26a99743ae6c9417780ef98fa48069e2c10153bd376bcba7032ca92ae78b425d12a2743435cfbe84ede3fa76fe964ea8a598bef7c445bb1342674d2ef66a84e9190eb1ac4e31e50426f63cbb50e7 +ciphertext = 428a49585735feb800c0ebc3b32afeef364ab6a8aea57e86de3adee53a7535761389bac910374c222306fb17950cc0e1ffdd0ae74f4e331664d0e28c2d4d8bb40e7339d718f832e755a39905dd14fe15e216468c97d35cd497636f9053623c4668cfa5e34345544c1dfeac570c035b2780df8fe9bc3f42d053d50bb29276f760dbf208e068943d1dc4e1b9037cbc812e22592968129567e84f836d330fe78b1951fcf760fd8167a507e19ce8e89409c70accf167161d7d6479f5a0d1a2bec85169ff62853886dfca8919648e618078dfa4bc0d648eab9e4336171282c5915a3bca6351ea65bb81ad59ac16cfaba0a3d85e19bb69095be7b6a5b72d577e5c89f3291d7e248a903bb639f1836735b7bbeaf5d2bf8c78f0beae6760fd5d5d4eacfdab02dac6792ae761d64687171bf8e181f2786e2bc49185b7cb0b2d5001a8807040de64417a2021af4b5e9c89b222807a60bf4ab41de36da11e33892e47c2322585a040417483a460bf05b95ee811c0a81ffbbb77fd412690af077756ab14afd0d821eefbc3d47774498cfb06ad722a2da4a893c3075e250810fc64abf262cfcb3a1f65d628c6a4e7004b0eabf1086ecf4b6ac233f6c624b617373f063af32775810fa12c66648c6cbbd974ec4b0d045ed9b2c5e652c19076316c233fed7ba8afbfaaa11e6f5a2bb27894caa02128494d9113288ed646012d3618d6e26fd62726713b0a1f603cbfbd0b81f5097bca9e639a0aab7f6796d12344c45280fc10d63834cd98951542b48ee569a975eadb3c1ec6c4c6568248b6a93b3c481eee0892d13bf4a3133e6ca46d0694360649093f42bb595ccd3fc52339c502a3e69d2bc01b2388f3874d25ba35468669e43db1b870f602fc674971bcf1e44839a6228677dab007a3ed8a7ccfd3cce2cd8ab567b8aacf6c44063c000f246eaf2110184fca3d9eb7840ac36c02f469fe3e4d1292da7911fba3c99103c2b0901eb2dabf50c98e6076f35c0efbfb94be99fc3f7348d8e18e9765164825bc61e97b5427a41d35a92f588ac9dc56d3b7675df2fb7a13a3969e013231499b10eec1ebea1057c229a7804cfbb8f9b595ca6ba5d9ce38666b6529796c427ab420fcb6366078817b0b71e35fe79767ef9b5ed3aa8113da7c8adba022f0dadfb8743e7479b39e9adfd6506bba3934a191c39a35f06a136bf14deff7386774401eb7a542223ae145970a6d0b57a47c51124bf4a4f45cd36563ea502691e25946677d731e034de6567f36261f6cf87e68a76ba3fe4374788dab95db4915db75be32dac3e7742c1882f03044dcd09ebe02eddfdfb368ca521fc7115473c6ad84674330ef3991958001decf5b4901c26a911987022d621c560d1f5437a2bb32f0e3f553b063f16973c00513df9c1b30961876963142bd51165790a57a39f09c6db072401585d3189fc10c7b554c7606d13960f6fa7c8ae121349b7be9384148418ffc39c400b1d0e03e6c3fb22d4cc2b696bbed8dffb50bcf5de3eb4cc8bea21b1a462678955289b2ee9d2b911bb3b4ff00739e3f10ddbca76b4076858ad1a676ad01a72fd910684d071fe8d539b570a13d6aa0aba941ab44d59e3776968237c95a38af2cb8b99f03ef05923ec1c844b14cae33cb136c6487803713ae4a3f468684f3e16be4cb618e81ed6f41670bfdcfa8825ff9fb824f2fe5692d8af9c75e321a8bb6396f82e0726ffb84a0675ce216b2e67e8a1e9081cdf149cbdf69e5e999475af62ea8dde07e66947b539366a12115167b694c48845f12bbbec10a788d6558136c19e50a8b04e576d7660bdbd60281b0f6e56bd25d1ae2b9bbbfdd03890cca5b321b5c9d29910048342b9d6a86dd89e204b54ee67024f58540fc46baa1ad194da6e6e9029e5a785e7346ea473bf3c4ce79d1a31e8ef38c80740b3b9669cc778a49e0d7eca19e167180c7e096f4e692e25c1243561e4c68253605c89c073b8b108850441b43141ab95fafba7f2d98d950a50f9a5afc037885027624705986f364e5151177e91f444a915e2b4a14ba8093a912f0b462ef35312408af02d124b320a0e197434046d1f673b1cca0ab58bc4bf7a2b29180020632b802249d10147fd1eceb156733b6ecbc7512760f271627b5453831baea29bc7b7b066b3d0a0b85ca0f45e95f5f9706cc070c79368b804a7236cd90468ddd73d476be3057dacb608961c0bc19fb0d9a02e9d065cc924ddad2e72e642f184d5df441010ece20c32ec4 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 20358f976c5d1ff771fe547469d24106a932c5e7a85945ca5cb6a436127e83b87111d558fea4ce2ef883ec1c467488cb5a6599e51650d2c16d1d6999304661895a3ee52510a794438460391f937024d1c140d289699800c9e49a9769a4d933ca5d6842ad9957ab94bdcfe6b1a4cb80ad493e46510537f06bc8458a5dea576fb68e8e470189035ebc8abed7d39e33219cace145af9a1878ca472bb03c3017937b64127f7751e270a9c84418219023c8ab5905a7597f897d3c3aba91e1b660154bd8928aeeb37517bc5b5f4bb97fcb9af3d636e5fba56c305ff019b759b34f13957425056bc4765f5f968d22971ba695b1da660c3c2543b74aaa3e8357f161b3c0bcb17f77b3598b61ab8b9d5de58ca94595c7e1b175f42521eabaf1612a338ac49a678b6e3bc40e99a37c847a66025620a5a930ec9675402841f9744a7a0da507b0ed0c03bbac9fa818436e601a2cf26f389536e9b8cf40434d8cb9b644b108ace318be37bfb27b3d0881abadd7a7a73a52a3f8994da8c9f239406d35b26201837667bd67b21bddc8cae7f50d6b0a5c139c97bbf16cfd5b50fdd3650d1065fb8016030b271eb292bb95b8f8e0061942c0d8d83441f4c5c614abda9776ee8acc6674016f199dad13129990b7abd2c50c44971c4135efd96569b0c3c21c712ce65423313bd7383f67a91f73e4625ec1805bda1f1cd720afe06ee378cff6d70c94017eefd11567f3a1d89b2d7797954f742a6231011a4b2bd0a157abd438b3d25d6fc0cc5138b2c49bc477480b9bec3d3c4b5ec321910e18b20f3645b6e2a00c6484ca4299062a66fd408a9068432d23c09da18b157a87149705f6bb0e842a4bb82460ffb74681e49514854aece91ed35a6e09290c3155b6057c28e57b8c94850321e73602f7b94f345ba9a4769be079d74b26264aca05771ad9aa868bd38112639ff93684f57caf90808a3ad474335c29282b75e9ca89d8136151e3b379e53a3c5c89eca4c734bcca4b5237a40c3fbcf7439d6a13e79b3f62125cb5e0265b468a1bcab4e92b937c51b03fb78d46d3593bfa99b02130ffd4636300008894c6131469b211bcb9ea852747c5ccf93fb37c98fbb3751ddb49b2f3218cf17b0d399f9f081aca36882ba793b881b7fc6a2b2b334b42b44dc837ce0ffc15f28104a5d26c080cbd10856adc2a603ab9c9ffe703f7f4946037c428190d7b3b357d79a04ef70aebc90f011799f0d57ba8665e19c229f8314518360836dba3efd7442c7aa7fb1423f681a42eb1b7949a9e70b687cf146821bcaec54508a5e272ffe00f57d0338ae7048c6704fcab245f7c3ad1c5893d51b5f2c239eb13545e06c2021b652c614d50bb7b74d3ab2f4c999cca2fde9a15e68a41c1125f447a41330310069a43bc15511839aca550c4ee694262084cdcf2b5fc8850dd7c3211a751bfe327a462b3b5985dead081c3750e04cc3020e45567dcc4257341a872b7e92b5fd174c77c758b64388ddc7bce1667b54fd238dddba3c959cedf795796da9c6df464bc806178058566448675583a27ea5b4b22b1d30b098df40eda0909ae8708c941ad3edb334e29c8180c6c51c76d9da44701a6a336ecb9b5ea97d2b9c677167747c4a1a3a436d88525da4aabe2c30740086c2ada5747d98ccac63e63a199c4793b6e9c28fe763dca688b7352c25503576fa56eca566b07629ed2a3c0a8479f6155a72de18f92132bfeebc6b2b4b751377e910a6b3d91ccd7f9aa3e1a98095c568fe01d3f3bae1fd31865a2107cfb554ba64e2f18421d9a3b14931e0fc8a40f6336d4a89fa9d584cc94839b1a9b4f35a03514548de8cdc7db090f254c9a28969288c862635b46d2a23b857def0b422c6842b93771066c9f91e6b17919078d1501f407ab91d8b3a16bc0c8aa6d947542c0c6a76647773ed449eb57610b7492cae3502fa5450d94cfbbc8af3e103c82328b8477584eaa0ccaf900cc566f65b45563f19c69c68ff56b8b42625cf957b7b56232022c12ad89ba561a7de9f920b5d18f8678684af99daff0a4a38298ec003e65fc289a98614e64981b31919de59e6c55299d241fc44b71c0c578cb37a66088c85ed76e4ba183890761d8536aa2e5beb270ae3082359b6c3371171e4eab39a6ccbaf18697c3683171a37a064830d5968e07d1b3061038bf9ac305d65ff374b17b2888c2d459e18995bae91beb635eec74c2c66cb8526746caab48e8d33270e84eb1d6cff22c54825bca3534822651c417771a7c07805c993f4ef3a3f8fb9fcdb4a2347132cb138610449a3e7c7a63e427f3112d0f3cbbb41815f360190f6657c55ab92652c1594c4df9e742b2b088e92c613ca13a8a84562c20808872c57de24922c82797c5a7e6f251c7e6ce02d67118a044ed36cac7bcce4f24b5fe3b871461a261884a97e4c5afe7c7dee44e6b7a6b010a4c3ca80f4f49b8770c4394cc57df9367b7d91d73e829ef5485d7a981c1114bc4f3999aeb6d983869b7c16acd803c589b489a62a4ec2826c0477fe81cb917b5bf32d6cacc25028d966405817c71360ca1d728351b931f7a714df3a7d08b441bf61beb06766da09d7c5a06f4acaea91722aa9b0d4e3b3c92d48ac39482a2e32b9424909ca27d479254dcec14a81b5eb44a16d6826ced35b13a2701f29184b3eb86dec576fe8cb77b473b392b834c16b9265bb699180286354537fc436557306793160cb03bd1616d1b192267daa48ccca69a1aa2122885c9927ba010a39837c49aa12180b32983a5a95d16463d009a7ec80dfdb82cd9966dc7926c8ff85201a8becf4a684732226c915070596aa9bcc400a31d4279a34bda85c570b32055c92151825ccc35f0db0e142b3d3d009f1ef5503cf44999826d4cbb2699d193bc08a5f1b3a80a88a725554c6f255dc16abb88978b80004aa3a25c2329b081aa950d3a90255b6fe2732a14744d61186a9149391314a6195644529ba40f47882ae64bb41c5de7b893608c8c2b847238420e85106ac32ab88ab2ba9800cc52b601cd7b5f9c48a775ab351cf11b9ebc3471d7caf7c66ad207cd3c41678a9c0f87e356faa9bf925709e43358177940c25096537847d370c292783abfca8df9f72c2925b978928564e378c22b58f91b874d64491e9a5c27c5cee2916fc82230de9cb32f4bb74d954f7bf5513dc78dacac38dda64ffb419a697598e323688bd68db379cf79e33c44e0c0d8f542226596e8370445c34754e7a1a8c1a30ae41a5614870fe88496e92da73c620275267e86bef499903965b2f2f2b7842ac138a579e1b8a240a5c706328871a33669496bd01154d9792fabca6dcb9a86a05528ffd20c130490ac83a3614b900ba993f8d589909368d41452e7393a5063629eaab317cb63c76c66dcd06fb9ca2d883b387bd34f6a333ebad9bd27351784643e23d0494acb991ccc6530b3ca8a6aa691f26022c85f5ab7a8d8d1c6903747e5798815a99995e53a7459786648b479fa80adc77e234a1c2e7b5cfa7b2fe5c61698d6461fccc1987741f9ebc74d025ddc15b582f625020b5022d51fbd09531fa54fdcd06effd8128e3c4040190cc72597f4a966f1e0074bb48e2da148d0c089d343a82f811e22960973da8d10a3b12d1977c98ca1bfe902c2b3772b1984dc7c91185b678645530d42500e2295dafb373fb1baa98948d4845915e8c3391a468df3c63da30dab4b4f3c9a7cc852180a5365c3c48eaa8c11cde90bf8451037a6397407a4bfa409548840e9a802cbb99f0da01b5df683c64ca9235396ba94a83be60ec5d53a4c7c1a72c530ab1b9a6c12317a11364555345fd93ce2a57434a9254157c6c5bb68f155c4e8e563a9fb417426ba4a55aa95203c5256062eab93cf91000f572fece7101231c51b778023b538e154cde98a3084d194af86c94d8320f4a37397567286a951dae81cb80a9e28a99144d83e0455cf7f9a0f5c159a997ccfcb10a929c70b1087a418c6055eb378c64c6581e394213413942317a32ba74f89b2fcb15ecaf6527474c33c625c66216048342c040626cfe6bbc7522921d846a1e81d15210b4b92c6ad9a2efc262b3f0279712c192c46853629bf7fdcb9c47b9c0ba0a6e1dc735943750704aae6a3cab9783f2a42583ff379aa9449c2440018094023575cce142e7f6b6edbfc09fee1a5394231fd5772ee1c7ca881116a32b21384c526d971c66acf7e1b7eb228ad7dbba34f099f93856ac682bee6834e833322629c493b5b5429897903447c5289b9d27983ef826be9080e54b7afdd190166259f8cf117cac79b59e63fb779b26519aeaceac27944cbbd80745415779bf0116b0a792286911ea1b3a7033647c18369cb9fb447ac5e4ce47e90d7c17511acde60c94da4c15d5d9dbcaa30d3dae03773af14151bd1a73b9364f2b0e09ca249a83719e2acfd7e39e94db4c270404f6a46440379cc74168084e8c4f9fd5d88d4bf1771a7a2941e7d291089980acda69eb101e4 +ciphertext = 03bd84bb4e2f3ddb6b690ccb3b38097c344fc92c63fd4c29880ec26c24683585369bb7ad86936d3d4bc1f616a46f997ab2232909c5a4ded0f500710e539362f4883c6b03a470fc0c3ce0668ab1f150e1bd9d0ddfa36ae7b0b16577ded8cce867f6d4dc7e1302f29dbec985ec20edcc29110ed2090cb981e08ece9f08cda3cc94ef38525c8dd8deb693aef96b29d4b3eff7031f56362220fbeffbe1565941ce198c051e0ddc64a2c2061de3b9843c65c2f99fdc0bc2f0d1deddae059307652764300671ba843244aa9e19394e332346f4ffd26389d0f23eceaafa7446e7e0bbcd2b258a74baac71e5b97e2378ee7f26624ca4ed853219b4d52c244ecf63b4f6613e278bbe30b066c944f44331055ce3d6ef47587212fa13f42b219b4305cfb612e5eb37804172822d757be6bceb2444a8d0cdd3f1543b4f2afd7ad676a1e8689e4bd4f644e451d2a4dd9e307cb65f490da1c0f7facbb0319fc518cc5ce31197fc7e4d84b7c092d3cb27eaab49f5eeacc433d398fcc6dbbcee1ae3bca8ad653d06a8bf03c4e7bfe66673705aaae25f6d4f13d1ff55e3d58073e38b948ed3cfa09e4eab37a193d27bd9b1fdb7f3eb48908a3d5f82b11ddad9e8d96135c2775a0890a370d76802779ffaa8b7146cad75331e5d32327eaba661b56d3073385380e0fe7b519e41c980bff4476be4337d04f71678425ddd2b0f83bcfc345b0a9a2f8e4674cb7165936cf884ff5de3423a50a1754c333f9e866bdc604cd8413d9516748011265625e75ac0766d4c9189a5c61688252db91b356c5739f0d18b4033880f64fd28cde6f970998020997f3ada53340db73cca46e104f92da309fede08c26c577ceec2c84e399615cb90d95309a7691bde19af476d86468a6804d5ecdbf0ddc9e27f541a87d01f6bed8f31a3e76cef4e535bd498e0aa0b1f9ae5dda05de72e146d0343b22ed8d5f5d25d205cd84fb019f766f2ed5b816e6c18f2cd7a1cfa83cef75aeeb711f021a7a22c1bde8dccdecbd4a658a8e0ed623a2d0fd0f36c84ab79de296fd341364265a5017410bb6ed6936a75da95382ea7d366165ef16b3bb94f8bcc75aa467ddd41c93d97eb6c16ff5b5360e0e5a854271d13971b9538e09bd849470debf2bc7ef8c5aa33bd65e1f1b21e4b3ce4305bd7aa7d7f3a348f12934f10d6a356a0e789ba06c000f5b11947cbcf2bf844a2eaf9356b9d8c6150670cade1cf50a71b2dfd9fd175014b6809d1de73f42a51ea5927c256cffa4dbc595fd3cd8bc2686b87f4a0d3f12a46ea0880b2392a7dcd24135c0bd5f482c1c904da605e50fe9b64f287c10621017ec1249e677fa0ce3551b9aaf61ac8d4f3ed0f7df8600f696a097c4d3f6da41e439c9a09c62bd57870234ea792400df793cac85d4f9de1182cfa7c2058cee4de5f46138a7022511dcba406e317e365f3f4454c7e584a4acde818a63bd50b9b41c7572fc1c77b113eeb0d383f876d836da3d0cec6246d44663e74766166443bf1dff983fc9398d3e4f61cac0ca6b7fe2d8024f84617514b2a555ab73fd498902120b17d26c2c776b4693187c1b459576243664401317774ca32ad321831486bf756afc4579e637171703dd7e8f2edb4b95fe706bc9099dbf8c3613e98c97212005933c59211410e50fa9aedb696fc3cb7cdcf92697a61aceeb635c7613e8f20c3b3f450b21c912179be54d1d611eb53503a6f0555e2bc94634d3554940297582ed4976b2673414c1664cc9dd72344a23dff878ccd9d2cbe7268f854b3ea237624421a3d9732b0573e7ebd6a55455831c994b588ee78657ae90dcb0470d5de233a2b41a7df6b821dbc202ee9d59e7612b1a17e8828c9e08f9f501ad0db70873878a2b7658b686cd2d30c99e6ec3c8dcdc888a5ccb1bd55d0705e1178a595c365f23c118a142d633ac061996670a41ee32e0c276f4adbce4aa5b825911450361810366a424b83e2254702db31f1c1c615db375042681a1b88746ade4a0e6f96eebc1093134f63fae3735dd35c3a3c04ccd752981070f3c8c261ac246f78a8bea95c1fe123b8e24fd316cf1bad8eda0af4a964969b9b863c257fd80139b368f6f3e9d24d35bfc8251f8d22bb8b0da459b77b2444577817985104615401fa8af674e7d6a3c4743f0848bbc3e6de77083bc20f71ae6e1750fe6a9bd8b39c3d40473fa959712ca1c2686834afcaacbc3e5377ce4a59c7fa839b61b5e906769f39b3974fd2deb4b667c2ebf428385307ce5629eb1e +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = b0320c43f0b9dc03acc31430e6fc407a65c4633165e613b9b37c87f2b235581764a00a24c9f2070734c6fb9908efd62ec675abc520671ee19d1b99cb75a87384d5c74c23cec297800bc8c8a5ab28955462b4296612f182b44b6e58052e7b88623b81cc9f0481b809a61bb109ca1b4f763239c9228c08f5a2ee26bc0e2c1d4d55c23973bb8ac4685ca86d1a5382d8c75df1aa52caa824fb828a41a5105facc76a18b059e7313477ccab4548c2db4cbbf87f9ea891037b94f02b77efb286e4f69e5d3c13b354a1c4a65b25fcbd89303bd7b16644b0187738c6ae279666dc358e3195b9783a8a065068716c91facebcf9a5e2ac47c545471c061618451be8194d3ed831dbb13227e3c0bf247c6f0c71a902781bac031ad49cdda480d46801833caae8d1830f91b88752296fd55d75c0c185b2470f2c6c1eb2acd0c64beb98b49d93c7fa198f4a56cfc99c5f8193c89c81ce33648d0193ad9bc14d68642c62910f01ea8dcd60a058456c3879486701a8ae6952c6570d16e3c115417acddc628d7b6fb32300ea4b009dfb0fcbf6491fe58238b763e4d52848150316f9ba642b30efc476311434adb0673ab9cff19abe5392cc1fc25798c5053e30b60a736840217fe656040726bf854125e68543255a117d27a28dd6513316b58cfa26bbb5c00b05c655fc958e519b90552366b49c33f642b43a3499d29ee936afa2f90d92b36f10d30ea6686615d02dc32ab5e65ac0ca65080599b68292b5d9db45c4d54ac61a6bc33ca5039c3ca5dbc6237729f2a63776b71c8f3911cce109c7b672163a3f9ea2279fe00db09c175fbb920fd3b69bc51201c216cb0473d89455aeaa7a62aa57598ab8445292551c4325e1a9d77c2c6240791a4601d9e4be32a6720d4250e8000ed37631cba4c01886b5638ca522e5c686261b733bb22266c7bdba390ad686253925f3e097b959cc1344ad29f73e6e59b279b28bf95100e26433c0d92254d526bfba2e2ffa187a13190e8a51dac70bb67caa0b73449df59e1ba4c2a88655d7996faf658790eb87f312824055806dec2b0f1b2a57ea3dcd84ba2bb706a51842a011a8db6b5e58a9a384e65e9458b07dd210b8377dd76854ab0464ce1975c5d3b9d93ba2c7d2c43e444b0fcaa05e991e68828e9810b8bae41318a27bb5812bb7cc0a2d1c6a34f7636ec719cacb697b0167c3785c4e5c64a9201b69315639bc2cd4f68ed62c3bb6039aeab4b8b30c3445f862bd709f1783b8e2037aa800aaca8b064be138bd42aa70d66779d3681b3cbb17c529b9d556c97a5e35420e9037a56fc8135ea1b6c6b8735680bf822b7415e151eaa76efd086deb87c0a7d7672d46c1d857c6e787187eb2b21a050b4bf17167813ed412158db56075c1c78633bbba6914d2a03ad18bc8dadb122b590a5b3b81fb078cb2935c88a7791490cd1266970b0b70d91c8b66a93da54acb2c4b5567054f78c84bb2c11a5d75671fb49478974783e85b5818caa0e22423a83d3b28998c3b68c595aa7cf78034fb2b35f324195a60e084029b4058fa301b85a892be556ac924cdb2d3c82ff42bd78b0a50fc8cbd827e67612d37100c3e5c7a7f331559f8cc47054973e9c8e096c730a908e3694f4ce56a3cb9ce0bd6141cdb0463105bd4e2ac399726b7d14da1d44770807c3a41c5ba1092d18c733a94031f4923da507fa127a19aa3849f9a3cd677603d4c963a57779a29610c444eb3d964b3862da21c0a26a493818c0d1ec747efea3281c701dde81534c2120f35325cbcc381128c6dc1454b8a41d7d2902fba23692c5a07d4bcc95641b9e7825bc6b328054496aba6376537423019f8a7ac8718c27e105a77861e5e610e35d1cbc4e45f0aa18845d6285390a9943cb0cde52be5292a1234391f57566e89554ef77e0a8502e7b38691ca8f2d37703f027d3a5a9aa4a7c03959200e69cc23409f8334b8d8e6c9e9b0935dec68e3c0b0e41145c4604d0294c67a819297c23e7aca8a27e756220b2057011ed31582b321cccd111464f02e1e9364dc37c9c54c032a97b07040c648813bb5f5757422c622449621d6b0d703648381678ad5bb6ed522835626bdb4a58d773defc37cbee39c6d99b577737d873cc42c68bae70368d2c65d9cb78ca56bb90f32c2bf696a3e0abaa6bcc55283330e592f7d741ad83493b1b9c511d054a49b0fc189576daa59ec3512cb1c8dee83302943b90fea7d0bccbcd0ba64c6cc38af556e8d6553b14625f87c801c2465c383ca8b8b8b73143f6b7c6d3312b3db9851b3b21b0c4876c371b0d011b31ec6014dc76c07a470e59812939890de11ca5da14f6f313bbc2543fc89a3ca317b645c1df8682685663dba3b5ae2614def7381677366a7932e4274b0d249c136e7619be05fe8e0b1881b9d56dba30e986f7211376b5a13a1f588bf6b789bf7b7980b5f25d7ce1492cad5b63dd72838f33569493c0d61117bf226b7f08ca8d0679c0d2a4201f8a1dce66e59fba484182ca0d4c90e435963580bdc7075e34c9703d68518e25346db60fff89eb1409aa7308fdd7bba49521b7ed7016445cf17a54d7c2916d060167a9321922c3e6afa0c2ff275e1961d04b0acc41c1fb427ae6b2cb52d45a726f15f571374b88b173355ac65e1685c5703dff15bd6db6647277626a479b0f437cdeb62dd403a1891038e9a8f31eb62940b3035133a72c98e1f7971b06ca5766332f062b1190442173b05be048533042b4d2ac344f8ab86685113153793a3994968293d597925a61e5ed691e790ad2f45cd915159fb4519d1d302b9ba0c91e386e8620cf9592e7af090243294464226b4a6344ed81d80b52add1c52744b5c8654ceaefa8647680f4944a00d2216e0c791d5590197d6ce8123628fc4c1f0131d7d346d2ad5bbf921cf33f37b0f47b8063aa62742636dd2c291376dfee8b5b4c67c0657ab4efa92cbc806c26725ef24aa0ba3cb06e0a971450b209634a3b00fc7275b5fc5cd7e91cb688299c43a57f08aa0f95992a0e9374be9aa5c69198ab42d48e2a16aa43e9eb61a62117a3c337d648b54eb3c8e4931683aa35aca264bf90323bcf46af5dc1c061b3718443a300289fb4b60de1ab7e838ce1f547d9069214ab30b333b22a3a9a6265a9080a69173d7b161669d06654119e95701095bebc20671c2532da2455fb209975824a2b1cf4c143f950a62cab04dd289c6f1d68b61179a073082f4a42fd6d309be78317dd62729f26d0bb8ca02b45a469b3fab42ca914a08dc80c3c6d693b01a29fb67b2fd9c2dbf66bb8b45c9052b46c9f6ca1742076841bcbe8b213c37616c09accea94451001500b4b25d1c5b880a66a6da670961a7b593cc64414354c0a47433bca02a4bf8025ee150c4032a119f498bca024a8cf0065544b08f701993160e6ee918317c1a998007ba7088d3a2455a35b7b850b69490846c789e0d703304716fb4dc535f5a63eae95cfd0c2c3de1891bd4ba12613076ec02da301e1c655c9ca49cc8f551a8d05a71c0b8bbf83dabea2059353ad3a6001b006b7e056e08802298f23863a82aba230453146dee474113e59c2ae85c554b04d3ec51f6988764aacb33eab9c037461d8204c8595d870bc10ba52511068e5b071d5cf169d4bc9391d960ac98b8e15a3ff577cd1392a26d32b6401ba5791743dff58d3485bac652b3fa75268fa7ca7556624cd230917c70b73812fb4c7607050fc0018d6bdab618f727a21945d0dbaa37b425fd0a8dfee421e2d04597c6b28885201d8147f35261dbc0542b9707efd2abc84777bc3475d4f82e61cc1579c30dddc174d2795b206377e94531e32b3be471750d478d18907ed6d36b3fa906266b843a500e51d57b7228938f25c337645c40362c86290d69943136c94c305c5e79d06039bbc41f8ac35b2a28c68b55ec580ca181cfb17a247fa86e1478a8f1063b83407a937180b7326f060c6c6b4553143947ecaaa3c074b2e99755a8aa0f37232059861a2c22aea7e17200738c03fac6e38b28cdfba608d71beb5b7e2e78904eb8474572b822d8c649e33a681480707aaa2aea76b0282a6eb83b47e419e114b593a42c3200a5d0e233ff0324111123b27814bac35b276c01feda240f458783aa7a149669e1acabd8757792106d7a5a08e67b27e3d4a726e33276d79a9bb4c9d6c96e664c52727474f3aa4e81d274e996b809b3263ac01f510743255b474ec1133a345bf731313f524477a1b97e028887ca5a800c5573d555f9b97241548b1c703d4c3070d5a9175638ade0b0661b8641002b1b2b0b05e19382f4d192853526ae5a1bd0983cd7a94be87529eee937263c1c32fba8f8f3ab06813dc9699a9d678710fa1323dd2ea7e49ffb2bbb075cf43a722b246791d643a471139065f2868c5c0fa4084ad7cbbbce325f4f802c3dc7ae8beeaf925f748ac6215ab5f0cd738690cdbbcc19fa2cc61d85b3883547ca863f3d7c4081ac6cd13109b30f5aa1ac8acef5c413 +ciphertext = d7f73801468d995334863614336612f8adcf6a08bdb8ab95f1d3d332835c4711a447f2c09b09a923bf2e142a6dcac8cbb5869b1ecab13f1eb17ca7d04c869781e068c65ea5e2a718f37c5fb49e884b046f3008d01893b359fadc31d07821ac8a4a2f87e30581151d1edba235924d1ddc64c0b1e5c6a0ae529e87420afc5225ba03655216c89c5f55b9ebe98504621bc8bad4a9bd43009d8a69dfb3b32bb95fe3349bcfe8eef93b58db050d639273e558744977aad76e4d0b8b48f2e36215f2b0feb277dd5a584636e1f94fffa4f0a69b1a1ae8a3144d3c3182b17855caf518eda35fa0b4c3dbb5194564b01144ac2e0cf8bd90482d37bad609d18f74b181e0d0ccf79ebb2a496a67a4cefd54041fcbf577c37ffa52912d9cff0a84aaee9753ab85b05b7b273d3c82b65d89a2e19b702646a0f8e69c66c5cf231e59e468c4a2e5c2738ca3b2786c789e82098bb6fb6370eaf1af33abaabb7391f21005c71f5d83d0e0060a4804dd5e2aaa09f0b5c653768387079dfc1d5a759407f4929271f30c817c5c0c20eec66c4a9bdf14349ffbaf80fc11fdc44512b430fbe36732dca97dc877b7da9e596cfdaf9fe22a2896e76b39fc78f975ff3b018cd1362adf26c540168fe247c9b7f3a7eab290b7b1b3dbc59ea00fd22a6887d59a0d0f2d67dcd4be89c9da9a53fbbabe78c96a0506d9b3bde1d8c1924e52f6beced0acad54fcf63d4b4810f2d1e93730e72dc85ac12570b7e3ccfa04487396355c83170dff226396d47107efd837112787cbd75b980fedea4857627fed8e3128d3619bfeb468674b4ba355882d5a2a72a4714db94bcbc4394ed39ca10b6bb197f54d5923ef666e95a5352617e4d2110e06097f5b97accd8d9ec88d945ca8921b91e8d52c00fa061ce35667f5a6360eae0f3afa4c1f551c2fc9d117881ea37be4416c7e9c6abe4974c6b1c802f0ada6fd25e63283cdb578704d22185f7b682a232da65c7037a482bc85129c82235e51cbe1397ed632d155cb9d8db4afb58a3ccbc26ba47238fbd04f843be7505a71d940ec01483e33fd679bd85bd3cacd5160107e97ed001b6f0b2e0d6b6b5e2c5b123bc1c25d636dfd4bb696cbe100b315da7167b97454b468212e5d1efb9a787b6e4639ab067f361fcbdd409bac27ecebed1763733ef428d3e8bb7ecd3f1b9e3c0f39c6fefcd5364a0a652beb5de40c65bf79d4948e5f33ab7789df33b09ffe87ab66283fe33d5257993d8d6cb654e8f7b745f3c7966f6faf45239eaa7b33eb566cd782d8f8a4a0c2d0ef514c23bed35b738d267e53f63b0df9abf82489fe44c1274ca7fcddc287a999c308a3fcf14f80351e7becf6b02abb0c98c1b452bca692ac26fce6ccda3f9d1e3c5462eb095e6cc6f6b7302c67c134172ba0be685d35d178f188e31614880c443c3d267c920f34374ef70b1310c174a19ec6b00d59c64f6ee3507cbed39eb77f89b2357b72d59055c3071413be1f27ceba2927efd15f63ebd8e63fe526307fff3460e20c2e8c8841b5d3340ad3533bd893c73bb29ae71712d052f2941571dcd9d153abb937f2d60e1e2c9467d8fd699eb0ebd57579f87dba8d671fe3ee3e184538f7efbfd488de3e3b8c1ed68ec56e02a640f707f6ed980515c4c89d4592f96ddfbbc8fca14d0e39e0482569bc4758c186e8ac195d42e46d5a07a8de539972f59bbb48420f7628447628584cddc5ffd97109eee216dc70fad45f145f940745b26fdea1af63676a008a2faf26ef9e6e0b57e8660c780c88248e2f19be8a5d68333f34b57e44243e93e7da628af6ef26eefcac33c88c7166b4483124a19aa9b7b466208b3fe65bceec4c9ba3eb51f718917c732ab5bfed7b9705a07bc24732efbbc6087fca7719abead8ff9a4bb9bc1a00dacc1efde9e54753a1df9724fa3b91292dd83d6748e95ca1a731834a68895f7d72a6b9f4100be75472c6e02b5c6ba31d50839c20ff2991d7cf9c77930e87343347eff49fbb514bf012557a13bafaa47f11ea4bc3f792e2ad52ff366630fef96c506b6f8423ce7b012ed9896ac76de3d732dfe80d051ec1236c5cd4d2c42092e0e2bf404b04eebd0d9fa785b4652f94ac519f4728d96b3a71f12c5168e518c21588f4b96d94c61c191b570765c6f4b7aa34dc1688834ee338434c92516ec9123d4886acfd8fc62f0d9e23e4caa7481b37f9408882b7ffee09de8a454d6290c4fcec1e66abe0e4bd853394698de620530e29d182beddca821194529f7c7a +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 26d62eb4f645e5b5154afb83f9056be71477b93c8bb470bed591a228ba8307632c0e40a3abe608f1a30cfcf020baa86b007b76e8102a69159ae2e2ac6a02902d429c5a13a2eec67f47282ab7dba9a2d763bfbc1962f058831bcdc0eca4414aaf582012be1b7445136f257b1abcc6c66e9c4b2d663536e7bfea9a56ede4516f43cebff45743a47149f6a641969363b38ad3fa6df039094f5cbd17c87638750e1243160c16ba20ac806f39c7f94185a3f38e6da45d7174a719c22b09d12525dc791db6a057046545e2b2d542a52aa332a4c90ea533ab09730bf1bab2516075bc071a91d03b361029e50921983a79611ca3fde7863560036fa9ce224ca5c6e4c8f70745ad15b3db5b4f84caa66e3806637817178a750c830ab02811d119af0812b62110004b1c3471e3ceb5a9934e65159ed5bc3d3a1b47133b82584008a34c6bac60ab7ace7a387205c65d0d43c968403f6f378550d7ce174384497a0ea3b211ddba7e870872db19ceb1e41a8b91c850449484a4a67478a6b6b18e22232cf4e948d35a2a4168550f61484aa2abfc7bce27c8af4f17cbe994c463f25eef652a2d993e63bba3bbd09578c1798123ba1043a4d0f47476143eb69397dc722e165b1ad70458e68b632d372b71e9a56a4042b33b6a0edbb195b7135de984b5674726873d2f946664e8233a38c336510add577783d53a84037d06a75405f514714acb59a904b58a8b943939002354b242afa8f46f79161b35c1861a87ad844a3aa320c263692a37dc9f52267e985177be37580c1463be036d4e5595fd184c926a08dbc793390ccde4a585f960412cb12f6702616adc0c4f47b3b6950e0ff18a9349678c0b771ef36bbb6c49f7884202084e12017c198c5ff0f81dc5d92dde0a79034c3568788aa023980b9c288cf83fbdc3255d0924ac36473d8928338253c8903b8c7976023a65dd200ec35c77e71c6e1222554afb5dc9065195915a9605baffe16368638f75b901bf9ca8e38587fbe76f976c3184686a55f0603cba2935815433c3399cc9ac301b85d76091a8f2aed006a1e866871f2a17f28c47fe128356b2a2314528d259269e9c51c4110624b84345967e8a723056c368b862b0541ab0158716bc7688bd1b0281d237e3bab12fe7c5a07893932563c20a802b796ec29433fdac8cd259854c8c76bf99c897666a6a5260ab8221e7da9c5c92bab7a7381918cfdc706986c491d364834381cbb5574037b5179e7464b20498dc4ba24de954327cc4af657499460d2667a5c83458c1d401659391bff85be80a5b82e5a944715f8952072a00a4aed1bcc3533e31881d98e50b84802823b3ac004dc5fdc9a85e719e12c2b662506cd9f18d9e657012b0bee80c9f28b602855bba1ec72077dcc6ecd8a939c83abf419ad1fb8581d87109608b19b00889f8ce9b35ad321b0cf6076f64881f1ff92fdcf2cd4a2c2a3ba8cfbdcb4918059d54e3ab1a9881937b9c762758f9363b94228f70b7302ee9180e023ffb0849e73cb5d5c9c612f6bb0401b6aabc50f4f1562e6b3ee3155fdb00961bf73ec940a1d0f284f23c0ddef583f0a046f4808173c0af897b479c96a49fa52039489afca45c4bdcba2c2965e4e02235671ae5187e6c213748319a3fe36af8b12ab7d6b18b72178f4b295d435459fb827469ce09912bf817bba2d7919c9324a7f8b96c7703499429466c6519232927d2a39b3c2332d88a9ea42324e701691c3a468a85eb5b02744c97ebe5ccbae96599d312a7833b704cb2d33c4f19a061130180004185a9316711a5769c1523d9a1558bdc9e8bd82d4996b3d9794d4846bce1370772f3286f30b1ff1c89b4cab3574392ee861c59b3bb7dca7ea09886a0709723b0cee888cdab9b786131a2c705239cd6b1507b7904583ea3a6673e347b52a2af7ee166b63c5830323ebd754f8a92961d5c2702f3b5d58593b54a2bdc0c4b2c647333862e57e38c55f39a007d70ff715bb319c30717382d490f286781d3502f2e9a0fb185a37480cfaa7381b013666750c2a61cbb1de23cd0433516010a1237143de909f6675ce3b9cac2ea02632985eba470ce931456f815d097ba32713e23fc6b920701f5ec391a7b4c19185cfbfac216f5a573840a2fc524d7381ba9e754397117503a56eb5917aea48cf36247395292b2a0a29a65983afa31a8f42744d31211b2be75739e240a0775002f2176974e31b42255086ea8b00329248395a9891a77cdbc41863340530067133759197a1438718253061fd7d853c6a565588b6e7579aa4d3b59ad2ab0f4d21d2e975f29514a02937ba2ea848e32436fb14f6d167578778318883b4962986345a31f2123193b2e75ac1573329d7f4c8a22f7cbe56b584ee4207882044a726c3842a461d56044c13bfc6712f8a75fff7cb6ad460ed5fc976bf20fd3321770db95e97cc11db2581b56b038e1b29a176932a98e18e0174c0898f6096d89a5cd9285cf65a5a9f1186267225f9b2660737008c62859f120573c5a3c1d24455c0224e7aa13b8f84e1013bede303c64171708ca402330c3d398a4fe6142bca59dfb690f03a420516a5c63e96f890c3414e6105be9379a75176bd0444040c3561bb3a04a5e9de7529145caad1238d2392f8f67909414451cc5b8f6d8a0ab939b4ad6695671872e75098c9a10bf9666387941b22a36821522abe8cc7fe793d173bc3a336c47212f210024718855850a11eb70a9ba30938713665c58959a92710e173ac57a2d51c753752135bf59c55afc68d054a351ebcb70986a37605c5d107bd7d71ce037388948c528ea3a00adabb2670c027816c6d9772de3c0f5f6aa73bb4f9ff922d4b91f91eb4298055a48c5c6ddd96ea8420069f2b1a5ab8286d83d40e27e7db5783082524909504083c28ae86c38b40bc5fcc45d1549a11923195c33c863c4a90424b3911a2fa51bae9849000c1616f7a7c3f493e233ac206bc19cac9e6ab8c5d29b56b839016451126f9b6ef1d94b62d31f8d1914b822af3021528f475ac0e0362db111f7359ea6b39d79718ea94c16c018ca70aba61ab76402a37ab124090a55ca91574310961d6cda19efa5bd29aa2064163026d42e0df03f095535bcc456d5613c3a463e21ab60ac619fb4b6b466f714437c6101630ff0f4bdf9c5c127095a539659f959a70d093ef7901e68210ffcf1a88399808f856f02d348bdd4670675b477a1545b332104357edfcb12941182e934cd4006206f343e6273c69310a315e28b0962c856346e2e8489d763686f6213be81327ea4c4b78054e3f76ad88577a042b492a1a57bc64c10eb57bc6b49439256fff770e1f65124f26ae4e478a46b025566c5e15c98fcc47a7298405e51342770553f94631d5983404628a4500f34bb1f16c11ff9503d575b5fd85c285fa70be8d5aa9758412d1b958c464c9ad8b4e6db1a2c6c8c34178355418c9d3c2cdee0781190b96f277e4906a049389978c47609b763842307e9034f4b378a3ec608f77600c1e20723a49511fb1d433363baa23bcc816ce27859f7a14ecb4c423401cedfba069c392a2838bf072c298d344f2b096652bc311f24a42df87bda705bf5da32546246f372b1f122cc6984aa79059f407273c7255f4c052cc1c05e5e8164ee9a153b7531f84c36cceace13628e957272ffe2a544e0697b73b0abea9ff2f22aaa9657dcf545c7414ebd7bcde5a4725609860fa4a93e5899bc0824211231a78b71872232c6b1642ce904633570e53ba02e7741051ac2bfc4939be8af27819fbc9544ecfa4afd51920ea475e3932ee7399b74fbb6e2f30acb0b0826484d28802630e8667056b6020a2e3c710b88f8ce983564955a8a4c9c26f162c4de839bac28651a25a5c1e06027617333525d4d723798340e1aa0569622c3eac01ed7c6279dc76f5229cb20d8a9cc1b9e4328bfac18067fb06a538870c134727b656ab55c12bd9422b6901988c5a4107b5d308a4f57168840790baf093c930a56ed9b5fdbf34cca571f061a979e5420880c1f03b40c30527d8460ba44f2376643aa7408b13a98cfbdab3be4345e2db32bdfc91fb4979bf136c8c2e1498854514edb0b1612c9eb0a9952e5c448e981549650e10046750c73b1b383a4111722c241d8b692e1d48dcfa54b2eb925acaa247377238bf4cf1bea12e9a4387046adb2b7af40e689341a879621223898b3e4c16e053a48665426a3320ecba41425a70a83e56ed7bac1cc622ace37bbe1e634f1e3361c1c6492db258664660b8a34c49922c92c102dfb029c729aa4241d95b4bd308214e62acac5506bc75324bc89036d698c50339e97b835ca028da17455f10b9748408fcd195de06299a701939d9566ef4e1e54b9d6abc63b00131a408a5aa5b645fa83aac2963b068fa72087fbc91c6e6f55b0152ad58fd4cec2a07f9d3728511cd232949f8ccf7d5231bce91f969ef07cc420b6164d801e28d6c5705a895afc84a00ebe074cb5b7b3895ae6 +ciphertext = 58db5f938e86b48bf8391f06293db364e5228dcf1986f0987ca7e26a701f2f396b3901ee9f21b5adb7c905adb647de76f1b7f5976dd87499a481329b76129645c2059c008c4c1cb82e7d2c6dd39ddfdb9823ebeca89391bf5fe6f5c1c9a21d38e5fa66d56a6a2c86062a9627352e16a581abfba89555cd32e2cead15ad0d1795d505c0572b0ab960f8779f3974438a5171b5ffa382d8754f8923be25117a9aa859e933124fe06b14b3e5f5ee9fb3ad7827ff41a1f8b4e31e1fe10a50563474b83e3305dd09770613d4fcf4b5586cbd1ff5193d1295c9fb4857c98c6e65dad7b7ed944d3a03a8d949c1dbacc44023ca0c8924116b3c343fa2c173c4b49bd930ac4f633ba364d4732488953b60f676bb347e891730699c058a51fdd3952eaaf30ae9ec53af73f95bdf861fc2dbdda2094e99b0f8b67f022d77908690b0e458138f3f3b2011200cf0d4cb98fe954fa81dcce69ffbf1192bef6a076b2c260f185229eb4844d87fbdde99d734fe3960f285329cfc7005a1604fcfc8722c2d0123cecc85d523bfa8b20a1d09a298f7390507d2e8d1c9bf89b75cdba7d3f1c3c4204752be6a806c943e9015dc4de14efef0fd0f3e558429ba966b9f52ebd47c976ef5d4dfa02d2febcbdb75d54af01229f2caa64bccbdffe594ac47bd08d20034a53c5405df25bb5055c08f2d3e2c7fbe420334bfa39969f98f276944eb25da9c2d27d3df6002415e403cbc564073d58bc7dda72cd8f6c6f34ce45e4585dd7c635355e707569cedf2341a329a7a040faa8245f6050adcff1cf9346c9c1ab53d9e9b9d691d60775db3b7e93eb360c02da8d54131693c841e595e70d797e4088fcae67cfada68692deed296454148c0ba789e13287fddd2c8d40245355e5354f077d3ca9f5a30f2de3f691888ea0d07e39a35bf0f62d870d330b90916d984c63c4e20abc1fa79b85c93ee366813fcc2c42984a2626bf9482ca21c578132a0458154a8d96141dea1bfc1d63b7693b41c1a8daaf96803da228538ab12582c39144b1fee1b19f9095f95a73df9a63ee7d75b6ed873bf54b384bb8bebe2817d6508480bd542b5d780095cd60f86d13d7a7f86b2f4339b18bd14b308b0622fa89741f735f59e087785cbe67370095ad67c59bba84f6c19d104a731503f54ce01bd9a24f8bd70b1dca316dade26f59557c299f2bb4905d81bc7099ef61b4182f05b08fb114168cc052c9f8046d4b0f283d9a21f1f7d0201c737c1b147ac8dbedb9437c4c5685a336f336087f91731c6119525f08648a2e60b30b65fcb88b13e274842ca69355fb7eefd7259787ac4bce9f3515df59fc5d28dd418e35b5e6fcd04c5e353424cdf04fd6b83aba86275913f9788541667606c414eebed9fa9f1db5d4af71bf56157efbaeb7789b1789adc5e278ef29f1227290b475569914c843c5c4d6f25b4fcaefd2308374ba52e19c6baad056c999dd74727b73854947419255966382096820cb1f39c778cd35a0c180717eed48da21f553890b80f9a542a19a49015a6b9728132030c79fd3d94f79c935c0705731cabf9407d6d3c5d1b428646ebdd90a69dc21ddc01146eedca04a890853eb85347e48c0c5e5eb5aea2a38efa29d6d15ac8260ef594a1f11f6fa1f0b301e94f516495c10c49d44296223a1e98e502cc015bf576118e2993123a06831ffdb486521787b9b1fb62f9bfd906ae91985778696a0b9428dd3066ab42fca66432b3b343f7c64a6e7e47b763fcad1020df2a18dc2db2748fe249f65d8a1660a73c7c4db5912be1052e9593a1b8e1046e9fca7bda1d052d389ce98d3a5ef0f31cf5e96b8cdd4447b9024647ab6b027eb1df7399d3c83514df1f646f118e3c776e8a78dd855fb4baeb5e0cf599f48293b83df38575e0afbf009481abda2b117eed43727f5da0880550d9a1272dd0867d10fa8f6bb4247cb154e8de15f8eb9f3b962eca0eb23e0f91625b624e117187c3b79ca6a9193b5619e39e7c90f9499b30b6289ce1f638a210e5e59e890a367fdb9c352a0c22139e2fc7e0dc9c93bf57f225b8ac7c8b4f93c0ce3c02be6f108b16d8f0be4f712b5d3a96aa524a4ea9b75ea6d07ea951c759fc07733392e4ffd9ed34fb31e07ca7229e4d34f96211ce9fda9590694aced8f9e95c8aee3bb9e7497691f7abcc50b99b26b478c7a874205fa1c61be14c6a2eeeee593ad758e63ddcd16f1658f883da553255735a5e +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 97c7cc71056459671522e822110162526b0bfa914dd5b1b93c82b003c2153bf2187941b8611671f9332622cbb39c25b1c599341397570bd2803aeabd345a9ab0926b244876130004ea82931043133d975077a29bf1178030276263275a7c93782a42b990317bbd6122f5ab0ca214680b5939a0f565fc1275b9427ecaf39ff0e640e75c7202590a616891dd8034aa0233d9993ca6c543e4cbb78264629747cee1a394f25615d4e14c50e6acc91717c4797246f7a377fc867edab8709c53d48cb2c1ea16c221c44717ca4795a792580812d76213139718522d6e888e71f30eb5531ea7081e66c33b388cba82a6938e6a34f5cb23f9849b40b448a7c3415cf9b931d15cad00335ffb5cd9bc64ea7a49fd8bcb13a142bcc85ac950c797da61eaf566ff847ef18cb417c9965e561f5b5bcd9f14bec361c6d1722c4f30c2614366a5b44b787612d19100c32470cd55467890b57b601f133376649c00b2e75f74532d18e49cebc3cca09543b14b83d5a5c5e7d2c04253213bb23d6bb808baeb93ab78c851954fa54acbc92b030b30b0ea220424a8c6fd66490ae173770c009437056ba59690d47ff6a8af88957dee37461db78e1c18542145188eca16a8842a2a95802502aea490ac89b8a52684582eb60c0d8aa1166365dac1927e395358525a8bf688a854b99526152ddb8518c9bd49b7148eb235b25c09ce31817f92b59403a5e51b87557667cee17f7323800b397835fa92143094e20047b0ac459c83ad7c842b6f3634eb4a68db55735025106ee587f7eb6ab6d260887b8b7f742179ec318b84a35f7094057253b9dbca62053b10a267d7e76b274bb8d72a3639762d4210659dd6a4c5d3ac1e1914d3a405fe190b64b640c7585725e9a9c456b6003a49e7606939906ae8409123cb00c45b81458aad44659d0a5a77c5f002b963aa8a328f4154a138472ae1e3c9a45c57afcac18e964565f12b7699ce387a66fe0ab76f75656cacaed7db06203723fe8762a05c67375bcbdb4bb54b465cdbea57c9db6b1c81c61620750aea93705366eaf0c83fb6bd12bc582f3551708b5dfedb54c040145331b1342b2d003b18124b7bf956b9a1539f0b876af3669c95b2804485249748a855cca670268ec6e0983edb3d82e9276090a5796020a0757982200a2a90a29a9376e202467b7b70959b7d07d203d3a3a4ad9068699955bd8b95222c7934964e6c2a2e17a4869295552e359f3e65cc997c27b1d881d8e1969b6c59bf6b717ce74741f753cd9aa50d97c939a0b060226640e365ff348b6eb42d4178180039b49f63bd89e4915567b342b1b942480661e8252726b7ec96364537854efbc38d229a44b533438a049830c93e281c5e8bc67596218b69a9e1d9bf97c3a5de322c0426911a8b9ae85c709e22c0be6605d12524eba93b53a47c6c9c3a99c5c1087691a52ba06bab2d760a445d6c410005b9ea6737f3e07b66d1cb64723e66a02e33720e6b6bcd8e089c981387a6e481c9d65bf28006ebc7be8165cdc7c66f69a9b23160b07c0a8571e876ea433ce63cc08a9aa4e7c77409b5884b9057554726a52690a81661687c4083b84dfc6a5877382a1c4a4756585ae3e53405cc411593137b2cb7e98796707c03e550b640c427f9607906ec558745a8bf37c6f0d1596c7178c7bc67ed954a16a9901fc55a72a50994e7bfa9607e1d67674f820d07e2af9e478dc351b28fa300e53a850b34cb5fdc1a00585c93750682ac63081597c612678a4a1662c0753d213c1cdbb7fea9659897a1524b7fdcbb3eef62c5f3d7a3a2464f03aa697aa2b6370c3b5c870c5ca03690e8bbc638bfa4fa9c2a9a996ff427f1f210616015cfeb16397473ced8be558a883a206cfb3395e367a061189baab78e34009cdce02beea56a785bb5e6854de3f817070b2ef794afdd1a83c56b1a9802b2c66678bd263365832c362116a54957406b7a0080954ce1931bd54b7789b093f567dcb980736b5fbba9584df5b5da2785c17c0b7ae433d8018b11e20dccfbcd09f107b3e637a228214f523836281440814a5fe525e3cccdc30c12dedc6ee6c281218966a6568778081d8403c7b78bc2dd826f66140457f55082618b0fc7734a47526bd496b5fc7efb988ca79c00405bbc23934ea7ba3ffe669a08e6b538e6cb9049a0323904d573ab4e55c0b2ca3bd7648dcf05a887843f54e5b3d25b50ad699aa51058a76127d7194148121965e9669d67c91af3802a623e21980c40047d450088ca448860bc3b00cc502afa09cd90cf440407beb8456b883d07741a2822ab625a2a29f0c83f3044f32a2a2583182104413eea9abafbccb39951c0464f80370462a8525c5087a3f06e836759ed296df45c709edcbfb517628c4404b6200cc9c08cb0624ce5e401e2142f077117be8ba988327d90199c28c07c5849446f55c7f238064515ce8200853bbab868239e04a8bb668c77e0b0197997ce98e851c90481077263fea45a247562d6f72a38409c6bc274f60cae5bc6a80516a4996539a33969cf508ca7041b4706a72016cfc83694b223989a38b1d2490477b620b978c8e2718b57755d9ac5bd267b1e36032f815a9b12b878b6dc9baa317fa0175ffecb75a0923c24cccb5342c6c8d407caca52e9937c1217100e1945e7f4ac4ff270ab79a22c1681edd076a4083977a598484b61328c9b02b29e8547671bbb21a949bc5f9c6c3a0b0c7d2b7da9e094e3a9030ee15ffc23cb24b80565d8205c97a85d940273802fed916132da22b5fb7c6eb76aa96b2fb1d1a0422338d5e20fed89b98bfb6a2d6184af8c9236b76f0147263f357e94ba43ba034e8e5b35f3bb7805b1cc21e5bcd6f0a3f5a875a80a1cfb22327f042e2f78270c89837ab87b315835194c3703276504d64f6c08069e4bba52f0b48f3ac4788c322ca8c20809aebe5304521a2de05729c6cc6524e01f0143058546547e98c7a8aa7caea39947047e0be42f7935bb990c455fb0c58ce3981c94c3346519d0f60e2cdb4af0ea7f5e5b1a1f932d28143315413b47fa2a6c668721e9cdcd705a8ac36f8fe13cddb33fa65a50dc16cabc876265578493a8147bf042a9dab42772187f8c3a8e873264267ebb594cec401dfb595389eb994f13a6b059b4f9d16f9ad18537d29ef848599f271f71d702aa917c30d99bc65438161b619260bf4320c8fc862a968c3fb5257005c502fd703063450467b400fad54b3835519442b1c3c49f48bb13d44c911e1a2b3e4616b5675d947c2c63e555f190929a28366c762e8c784656a008fac6b7675018e12ba87ed0a52729a7c9c6a37a24853ec6bb686a76f501a0709bca77fc7ad8d41f2deb3ebe83b742f8ab93b0a2275b6c5381b13e22084a24597925a2bb85a8ff4a49b759a207668374b879502254b1c02b694118596558a300703d60225dc15ce203cd7a0720e695cb16cc017e9cca38483da98070ba335325213c1ac50fb5b495abdb033f821b49c30e46f910c6f4c8c1c9c6f76a525fab8ef13667a19ac0fb3a024c123cd3c9114677b255880d6e385bf530ca7096902519bb4722375ed461209b4d101b35ae87997c4a07ef413418c5cbba9bb577fa6431a8441f3b2f6f54b9cc1a4fea186d6a659a4df4c4ce112cc153896024c1e1ec3bbf29a6dc42b2f8c744b0941ff63b770a4243bc7c35bf4ba4c666c3b33b668ba1b8df35cf68d050d7c2854d3502be3b8dfc1abd444b400d3700e500a3964078da906872465e8777c732d8198542bd06177c1fe5116303a6dd6291c9c7170309bbaec84628719a5f492bbf3333428826fe8073e90a6efd78cea704afe2e69475b738ca83445bfa30163c639b5b804a2182e66a84e2bc6af3b69aeb593862d9bc2ce0202b0236b3bb8165e523c559191cbc17f2c8434831a9abb10168077656274a6a83b1f8c9ab20dc6a54886bf74525b1e77847ecad42d42139e28f22fb072e84a3a0e0c22343cf563bc4cd3876d3133b02086c02c4ace86a246399277a05306847981d17cbc446a76d452ba983290ad23d01f9bb54a44fff363a76cc0ef892321e049341d49b75698e5b59c6d37753c26a5aa6f4856dc7cec0296cbd42b1d563b178843b8da2765a7a7c4550a969b3c637c62646831ffb376c9514481d023b25c686563b65d818cebdd5263011c361e714eb5ab10c45a807101aba75771835892af6baa9e643703c938a4890c740a5d2385091d64812a47053f4cf60d04c0811c49d7b043fbacf066134218303704bca43383904a1ba29a15f88a657e5e46f6da342b9373eaaa6cddca39e61ac820b22a66711a32d089b36a666dc816239a6556361b1d08626e549602e14b854da35018835e0fe9f2fec6cd9dc1f6cad427bd9293ad820a8a39ac05578953ea2765b22923c91ce70e29db612c711694d7c9f0ab5f96a7beaad043be3dc6ea8f79bee76b74dcc18080711a4b39cf52e72c617eacd918c35618d87fb5fb9c949d85a58 +ciphertext = 8c07ab68c06b0b48e6746a133cb086617c57b1c94909c1f58a986321d66b5d7b30cacdf5d84f211014fe6477fe30601066789cc8b42ed113b241e5b64a1378b02bb84ee8fc17456ce3d8f211b68ca85a86b678b36fa8cdf9d78de90f94c5872034ba4dadb5efa7417894570c769c1bfd682e5d8ff988cbdbb09fcb676bdaf569cd5d0f426348b6fba124205a2be8535aaa1e50fb267ddb6affed01e5ed6a14548d1a76e1a3800b43ab1658efacd46883da77104dac26c40a32be3c51ed2f7852ec1eae9edf21caa55678f922920e0216b041fb6f919697098c989ff6a5688aea295a06dc694e04fa9bd10f3996a675330951fac45ca3810ab13c7ff915e690dfe5efa55bb94fd5518accfaba0c7451f18c132d5b8887571f9d21967474273e66f52eb5b62e469f631a627aff6e2b67e6725613a6bd900d7d9cf31612c87fa6f9b8b8ab329e8702098933d9f4e2acce10f0adca6c8f379c2b2a1270135d928e0c5fd89f6774667da5980f793104cd8b44a32f05e066aa4ffb99e8f15b4c77cbef1ca45107755040d180da7bdd773831b50222113ae55cf3d5fe2d12c3e91f73acf2138b5b1bec2a6e36e3fef3458f8909d1873afe6d52a3fb7868cc0da90d6e0a11e0ad46061ad5cfd3637210aac2a6af1e996f701402b4a8adb7b03f5a440a7f1822281c9d02f595f309e3018497df54ac9f4030d9354211d78de4647130fa959368a0b27639db9e92c6ac71e988c00be430a16a68737a0e291fffe176145a84400fc475668487f529f706944f6fb05f54954a668a73cb7c73a19168dc275f84e85055d0f76f1e17a66f5919cdb187ddd7d7509d7ee835e147468cc510c1102d3dca98f90f39fa487b110277ecdbbe58e89fd4e94801cd4c210ad99505549a6a84fc920dd62bd9586547aa9c1c9080db27a7ec135552eeed6991879da9becef283657d48d719540835e98931aa3001bbcefb2e71db09617b5fa06b2eb79ba17e8a11eb93020a6887d6d5f855cffeea9f39158c99391fccc8abcdc69e70c0ae58099fc4efef7c3b3e5132cbe1dac2fb592066cff0d1150ff52c666766293373e4d82fb7c9c45176e884d6ba765e6b05eb851ca924fcec504297af4154c6a9fee1b48046af72bae402806025ec8b80f98572c79a3c767931802059958de86047b11d6bc6ccaf8148facd499fb2d0e1985fa8453beec810c0724559c6347b6fc09c3b66c6c3c7523476ea45b65d69c649fba3b2a34ba6558165e465ddb91bf7d706889581c6a8866c43f26f24de07aa3fdd4b6d03eddb1fef1f463061fb7c3a5d5f75e57837057d5bb7970f14edad8c32169cf214108684060891abf3c8fd8ef16341b1b8c30435b8f8fbca643179738f43857da0bebbcba73fbea9398faba96a43a66b8789eeac33c8bce61b814379d33f5b7bf20f089d08881932f61082f40d59368f14a09254d65ef06dba0fca26521b131147b513c1941961efa5301c11ac23da4a03375b5541d1877264b8f3c317f2b1eb1d1bb152040b08b1570865992837000f38e4901b9fddb46969557175fce09a8939f672f851f1a145d0912d69d35b97c3a049a68d2302cb908a307270e2e36b32ef60cb2f94d24cf82fdb4e6ef810b427bb202c24877e2342717bfa1ac6cc2cd05e332f93a73a914c1e98bf4fa9310dfec60d993dc57358267a46db5c1e36a063732b1d57f15f5a3fe1f5ed360be1571b9fdda7c6ae34067ab6aa6d4608578a88c53d706298d6b9c7ad99e536bcbba996d3f166e62c2836910b34b28cce129541f6a00a961d21c9b8b46e527051780a232f7da908b40d5f18b45bb4e183dcc70055d00327a22f3b382b18f49c4af09b8e903d8c162b18d0855efe39b482936a4f3ada7892ce32bdb29197faa19f9f6be4c2bdc2ae28c90b5709f8d9548fe418df3bd14d4720d7548f3df6261343ed317f906267d787db1efc3394085657f9e8fc125bebe4b0f4655e68d84fc79104e71403c461e12425286fdc5ccca86bba156d2055e12bc0db344e14f690055e1befee50debbfb7ca2a85d755021998f56e87797890b427c7f36653e7e865ed33ace194359d2f3a81943858aaac57dcc77f8ea3302b66998d829c212f5460704544f4d431defc62f32c921fc83c224711b763c497c7e53a9b7d88667fbcd4dcecdc5362672a8a8dbfdbe0fa6705a68f456c1ae3a8312a6d900d1597ee6664bd43d4c1ab62e07103f0f9eac6b62336af81312e81a +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = e2e301feec6f0e3bb07c8a9b6af3638d62867a834a0c388e9aa56a64e467b433560e347fc5bc6381c1351b64cf8bec6f5e185b96e3c234ac81e5705eef2b1265f90129745630494d93d3bdcd04401169155b58c5f7b421662c18f76c12a4e07cbd85a749b1c59530112a911d8f94aca0cc5415a80b4ca12848154d054c1145896637a60e7ad11155ab4644e57f53124288b0ce96190527681e617c679c59353bc861e4976c22111def84ccd90341fccb7a0270bc6eb92501278a3897769bd4c64cd231189c60ff32742cb563899c15b70b394f9a38cbb4a3376bcb636a22a0339669873ccddca144f5c54636cdb6a1a3afa8036675b0dd903c752bc45301966ca291f005a247958ea73488a61c0b4240216045c6a0f3bbf7a8a2dac91eba40c070295d8289b24e6a12f8225f19a18ba0f040cadc9529540931f9441da28f586783fe865f3b98676bc10b5bc404c8c4213c3264a7496d82d9345d0b5b957b511e9b670bf1bbddac1765f309a7fa35d350be54e5017fd12318fa00e3d577b53544424267750c2787a7730e5759b8349f4198a167e27d9b59b603a746c2a35ebf7c9093ca459df43808726fd4ab8eb73338df9160a0b985ca9cb15538a0f6659a6572ad5f077f656c720a34cd74b8350c447d267827a0a65c82673d057b1928ca70aa0207b6f0a413c4c086363dcd06433c675132a20d9e057e2c19c34fd64a5612059b399c56b43903aaa3b3e92c37e26d30c82e96398f8da31378d43562c88672067b001983dde8ae46d55d7e8a84d3a308c6fa8cca048bc9ecb985e66d07b54d27cc81de7ccd460c36e3c53b071a2c3812a78d8643b3352bb679b03f701787404fdcf41e154907826438d19404e525b646f1620fd1078dd64afb97114557170e5950a16c77766994e68894a472153b182883e86933b651566262f352190a461f1004153de08012d68950d760596706b6aba99f33a60d178d0dd53023b234c629908918562117c99ed764e10b0ae957c0e46c24e39c93edb24433cc9b153725bad726af24b17150c2bca98fdca279c99c62a66840a8a21316f7609b7c5df2eb0b9f3b0d71688e390a495fbcb236010365f76427f58f547b105666560fdc992ca0b78042bb2176567d7bb5ecd97b43519226279de8d857feb700a2da3d9f0b057cfa0fbbca82cfdc792f004db8413c80127c8bd23df90ba9c97946011787f85c725d52071a7356640466e648376ea999c704c8d7049250cb60ee3a3f0f1a4b570ab5f87a2beb846602538711a18916847a301883302b453f884c4b4cb914c3a17334666643c6a9fb14bbf34d2638a66499cbaf091fa4ba7480c8426a785eebd558a71448d4203f1d34b0aa67a86d7a3a7f6375b2933befc904bbf883eae082836466a477862ae88a8572739af428d9c3c1eb4b0f398a6dd6dcc1cdf6210053316a482e28f00ecb3668cde3ab3bb1abe40a0806045673354d8b8c75bf8c8f2701bddc4898d32906b97b91e549b1382cb3fa63bcc98c0bf4985afa718a600216a643bd8bfbce2a3553d7a43c9080462bc9c4220a960d7697fcbc1d0201a094f31ede7202bb5824f1ca7f86cc435743b94c4ab4708b4085a553dc2cb92e5c109405bee771280773b92c1b17dd919a7591a56d05b7e5932c58f40a97b2b2a2605858899ca2f4afa2a10150780715563c5a864909392fd06cacb2d077d43249c0712ec5fb60e1295991f83e6407a043ca8bb7ca41b4b87fc041034c737c26ac00f982c1e83767e9978b00aaca0314c472d14524fc4fd75a34aa225009e86e4cf0a5aa1621068977c4c9a90db2940fa35f69f847a2958ee8d67d20d5b74be7472ebbb7166753c18b111d5ca741a691b6960f7c9b3ca9025aa60625b0b103ebd8a294c35867c8ae99162bc14989a081c3b3823048e2667a3180e17758c1abc94c869b7060c153f749d214261aa20ee7fbb32b6b1da7099fed24979ec90f6427614b725b8a979c8bf2433bc8319141bd20548ae8070f8c7b89c42494cc8b8179c79b6e278c1ae4b3c8a5b3c8f425021c7ff4b734e8716346ba2ff2f16e9f1567c553c0592228b45387330ab09bfb7a0a89be546575057917d48154a795a758332742e981ec769df5e79aa158b52436b1fd2a69920b67f08b268092ba8777295f2080ed239a46d88d13421b8d9c608c72220d68a1b54471fc98571282b33f51783f876b1fd021e0b689f3a57c4a4993554014a9cb888d316d3fc16760ac5414e0764ccaabf223aeb91473fa7c60e8f6a37db46564b2a01334a7e47ac60ed708eb7abda2ba4b879843832350e9c84dda2881d3920b9eb3b5dfa546fab9b9996278fd051a490337eb29a1865c04be761759f35a05a424044082cc447db0d2031eebb3c5569e360a2e961550430607b2560f9283b013a44372d824ace386dfe5cf09832525b41896467cc9d5a45d916efe352452f60aebd515c7b86f938bb894181a9f54c54c323cffc26836fa798cdcc682469f157ab242bbb0a734b47e216dfbc88385689bc88273feba011fb2cea027ccc37425796568f51b5ca43b1d9303b3094171d49a637156b304847069d57752349770f0b39cb142329ccd42b41788a58b013bb64289b0cc7042adf06ff8631d6eb9435cf215c33b11a7476b1c627275725a2e0624ace8c89cfc59ac0a2f124759c4a409b17481f1f50493304d8072858ff1618538c23cc6a54c0a02119755f4ba37a1cc66f0a0847cac44e769b4d2664a03d54c91642203da86d815ce6abb02fdc0a448faa2edb7092c15a361f4a74a372c47808b8f30971cd264a86b73ca509a53f7a8c595b1927c6a74f800c3583825e96ef8dc51f2a88899731515aa37c45aa65b85af84c6b474b14dc88564148190c12079bfd2993327595aa54ecf269ba326392516148b673c9a618832da031b743ba162b9cada133053461d8b834c6229534c4ca5c9c56875a1ca50c5a8257147866a87540bdc0969a110cef2b547a7e36444b38953e19e1809a1dad64ae8f76ade4475e6f8a70d10cb564a8d23f866ba5a7790255f506a1c1cb6a6c78c8ccc940388b93806644bab1ca0156954a5a48245721a984a977f481807c1cbea0a0e16a447330091ac39241e12a5e73230e72602182abe9a0a3779fa038ce31154d91f3c13aa8cea8cab8114d9e0036d5991988a56f9277bcaec1807729436868622277957bc774e47873fac3e66180270dc45d2b666ae7a7b3222b0395cac3e2745727ac0c7a30d670675f5b2a67bda3eba5a2982923fd69a5e7b5a86b6a347787bb8ae3a1a05a1cb315ab576449f57090248c943c5b3203648c1e64a9dfd2b5e3d515447430295cc1ccf7a7461842230d41f903a1adc076c3e55433d44a4c5406023dc14ce63a99d2b1fb5c6acbbd432e1386456cb8651db4d1a2034e9353b46d4b436e439f8982d4f15a5f01a8c61258d5ae058a9ba8e80017755180ecabb4fd047ba05b264216b9fb9222953fb755f456960d0958aa5a73e75204ff739c9c1487f4a284d93539dcccd698365a9d5b0d4e7ba97d7bc312cb4ffe138e8267ee4851c26149e44805e98309972d411df751ba4987a1394b730534eea502c4c742c2bd65ac9304b92b7106a611e3b6c94eea65ccc23cd363655a02448032418272b56413584c3c56f00eb906b8a781ab1130e3a93b4bb55fea23fd5c72e6c4c206de42fc4b01f2552b540388180f30a77f60c2d111baef8a9e7d09387dc1e65945ed1271ca60386d128989d5a1c2c72cc6fd5070087508ec4ae38942b3b25131391816ca7490d7393d2e5a0d6b9049c145fd317854b6b9a079bbc7fb30ae9f2c0288725ffa3674e92b44c2315ff737c2aa0cc9a959b4a92439e4ca11f725476c95d3f89767834068aa83b2420151ccc6158094ec826c6879425706847225c8abc566bc6539b23305eb411806c0ca378a21503e0ab8eeab3c1836e04a5a62988c6325ba7d2dc81fba7986958a8f1789badd7af8e30c2ab84195beb6852ab63d18b1e8d64c5dafc7d08314a88104aa5d77bd7ab87c1194d647928d5a27c711534753a1269a6655a272471da966392cbd3d64c05791c567b1732c6a35b6409e3f0c58b8a4de0b7ca47a1b2488b68f05c718a191c05b39cf84539adf7408734354c63483f02af88890822e019688833bff223c038186d853a5cbc85688cceaf4c5b17c2b9d7ea415e6569a0409a67d8224bdb376db4ac1dccbf9a13aac3988e0a1a85e68a9cb9b613a14a92905392f54791de6a806c95c2511c5240a4a60352b1bc228d6334cca5d14f15ba4b13494521123982d2b9b281512d50c934fc075e11107b9937938960e767086de211b75fceb6e82ed94ea117a681898da22d5afcb20c892cc1938eda5aab2075b4d37cc0e2e1aac504d19e1420efc34117678ec5ede286c72218b1432c2b9f61e1829575aa3f26903e24c57e74925f4704df7e8ad1a08ba5cc444072e7d040 +ciphertext = 5a2ad37a7199c987b8524845fe4faac9ffa82fe820780436e5f35984d5781bc5d0f6cdbced8676f0a1d2f6d6e33175cfcb548d1a62d87235240bea1cc20a47ce404171bf17d7db1a15a41d8f4c3fa8d10635c2facbd35f1604f0b52359d277c9fbe56f0135b70151fb048da745191efd5343221d22139af6b66dfa31193e0238b4455a779510d4a700823b593d335825c74608bcbb99dbb6a78889d8ebc99df0b96b0442ae6bd9771d2364394deb80c4b03ba07ee54713075e189dd081935006a447d1af2dfa538516f9b1ea264148de2eb052faa0206369e685b42f8e83f1209d32cf20e093449a0e14313498736cd1fdecffc8b85017fd701665eb5b3958a665a059b605e05913cf388932bd1eafcb9eb1bfe6335513f3b4d9fa855f60e7b8431da9d9e40be8f8512e026ca1267b24e175f4f7984c001be6477480470231a9586d721dee13260d96c420ca64d52c888caa665a36c2eede05aaf39dc2603b4891ab8e9ff83eaa3c8ca4fb94cdab477fd6ee081c6be546f3b9411612c4c6763ddd402dd08dbe52d4fd95e62fe1a47c70dd9eb697187307b17c545da5e4eb307812a1a475f0b1510e35d3a3fd3a26b022518fb1f45c93c001aa32b3a4acaf233f06d9979b3cafd892fa74a9193c1f646248ac8924cb6813fce3ae21d345d938fcb6165444fe0432ad2f154d8553463e157f3896616b1b10554688a022d47ba95806a39ab81aa34a793cd04499b20d067e35326bd6dd6835aa54860b19ff900c44647cc27819678bae6003701761ca34862b5bbe6e8b08db137b1d66c5e2206e44b2487dfe5a7ddfbf3e754c6ad358e5f0eaf55ef7b185c7807e70993625493f851eeeb466111ce2f6bd53ed9eab70dd42680bdb1beee5f7868c48a309ffe8b94c437e5963f1250618a5726b2bd878109fd908adfcc074f077f854fced737e817f77a3605eed973b8dbc92b177664beab55c29e11f87c38cfa0de0e5608888fad5284bc7ebe482e7cda79af3a9a740dd81d59b28585f0020ec764c2511855436066047e0835f3063ccf6205807b83a80ce9c7a3421a9ad4138d6fe26ed9e0d99bc2ed810bff00b7cc2b9fc815346e8e95e63e606a9bca71b1efddae43304a5058bbbb738ebbf56383f1ddacfdaa5f058133c179872d4e28bb35b29f1f4114a10bdbed66b56aa9705d9f319f16610e9544dea68d36b8075cd431b3b1913905a4a83b8936e7fae2fce103ad799b6d38a70d5ee517d9aaf094214c120f3e1c9cba25a4c1f9339ba6dc936637d50e3a66abbfcd1aae278c0efb0386c950533a93f7f57828245f0eec908c0b311d043ada6565c87f8360dfed55e72b4c64565eb058197f15ac284f5232f6cae23cf326ca7ddc496322ae386270faa8ac3d42b049af3b737096cd89d25ab3a0c513a041eb53263e940ac66c136349eddab636534b561df509baa4739b4113daf078c7d16528daba01b2efd457bb17e4f5d5ad43696f2ef208d09e48054a5428e2c680990d5a8fd004be27c236c6b86cc2ea106a3a52831c6d3bd0374a0be61393892c67072b39021decab8403900c0a3f8869e0423c9f65cca73f1acf46d30c460d4b551d0ab5b4ff81d487087661f853941fcdd9ad3612a159678336fd93baa84b89b700cd6ad0fcbbe37e7a47ca3a48b68e5c79c2e9e6daf7c2c7b45fff9cb6f712d7f5eb21dd755af06d86e6819d71fc18411784200249e0923f08e5d369e59df4e9aba53636ede1c35cae816733d8f5f22431447f44212b0feab34db941860a98d496dd9934d44c9d40663499b41371777e703a82077d542d8b98a3ed4a30a025689f16e057dc67a3a8d92d3855de72a46c4ff6b02c9bd57af2ca45d440c29f3fb69658324bbb9bb0627016556fd9163f7e76f2529c6c3c80cb7fa409ff92cb2c2588a4fe82246d107f7d87116cadd495a5bd38cd8e2155faeeec38a106802217013ebe318127d429392a0b5e25efb9f504fd6b01644191e1b55f5544dec096f0e467f6746be5ade00909784a1baf698fba6e73562a593c595ba476821aafc4c5e0d36ddd72a597b4da58fd27e7bbc5d781a1b64f0dec40fc30098ec0ee807b8dc2f7e3356c1637a45d010361485baa9b965b9dcd0a4a80e0c13de717d027cbafef9c6e2605a5402e6eb0f1517fc6ecb1789d6a13de89f7159eb2d04083a9759cc77057fe4a2102a05128b5dfce8f0126c4c982f3bc476a4 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 93666b8163253e9391126c3287e16d2d3a6c0b2103ae552d7a5690bfe8c35f3194e2070129c849c6b83f457ab5923c41a0ac6d6db39a1af1657c562c39e38ccd605fa8578ad6f68f8c4b855ca885f8cb834f05bafef267f145272521a51c633959eb99b9b29ed98942734b632c7336f26ac2e00c452800a086770baf806978fc514791bd83b3bdc6ecbc8ec6786d1c3455f0612f17693093ba61567ab5e7c691ac1f091641d1277a8b68297346275deb7f8bac0c900153f2d53b87a365ea17a550d610dcf456daeac02558a8a8a435c8ab5a1e931d11488cb20bafe3029a1cecc7e62a692ea697f89a568603ca5875b66c971bb0fccf32c655cb5b3a2ac6b91049b82f7447ba3828815181744c0bb0a20188405414400b43fb8f3e1a6536a0a1183b8384969f86470450fb38b352c038c9bc87892576f40842d417e9980f20c22fcb537841106033a1b0ad48952a348b7a50b8c8fb2128ca777f531d1d75ab32b35fdcb02bb9677fe9d87cb2180f40200584297026bb1c603a5fe3d71c7877c3e09b3203c195e73b51ee5195b0da4384594d3ff91bec7a00b2f06f380c164efcaf7bdc8cb4750370922138d22b1329c1090949532c1aebb94d8fccad4c55a25638ca65eb7afbd022a7b62894191667081643f63ad98370e36a22e9815f7815446b18af3e331f6ff4bb449b1976981b5313af2b372db1fc9f830a993d272c1946a89e3142489b143a397db7d210c48687e0e3522e3b75586655d714c1581c742cf9812bc8bacfb9cbc68c7e4fd2a53c45a175a01f0e30847309a99294c008365d94862ba4f5071abbb0d544640ec88140a20bc540b138c1c68ba14606c5b800b185d7f92bd5e5c6b121cd4627c0f6d38e1e7048336167b4b516badc120b8909e07b3fe590c92ea17d2424c9b4538673176a741546c09629f8eb76bc32c88157c82b770453d6cc2253a4d2751364f65418252c35e76e7dda6d57d088268906ff7c4512f5b985fb004a458dca38bd5a2bcc239aa8a896af8db40aacc9787e6c6b5a499b52f82ba13981851580b84b8600a480a39b673912a52f59810d77b9cef83dec4599972aa9aaa36bf49c3361aa1beaf3025be205e0963cc64636c53c2b0cb491a844ce605404a4a82388d66db6c1a8099c2abb335764b27b66456cdc50483c9053e4e824c6b2cf43e05a80f687a3e1a149d85e8fb92f65f74e25f1b378776038887fe5904239868d7452452d6aa50fc36bd198392c569bdf20b037183a477a8a81aa21b8c560185888c3140fcd7153cccc4b7009b12fc60386e3a7ce51758971844cec3c33426f0d2c4007309d73356910f0444152b94dd4b9ea67b96f2bba8a8b3271251232e2b49264addf96ca926a4805db0d19616109677d6ac816f3440fba99a3b21241be3b1304ba95c880886989895f844c7ba9b8234acd5e4b6ff584901d0b9668c85604d5096d7a1ba6e26cd373330daac9b075be93620185a0aeb43a1b746c31a1c14c9575955d485f5a581892a15fc114804aa7b0f566cb410557a7b336179760bb36b5d1733b41d10d89da730896661b82a7708c55208717fa561899cb2549734b5dc6cc7bb4797df46390043125eac78695cae4ea35dacb30c2a39596e4525f3625c77aaf51a485f410077d06ccf2690e97f790ad0124ad004f66121e365bb4aa5cc2b5d2cb72580932677781d561c9fc0373883b8e061c241b618b68c164e7b3ee8b161379361784b7240595fbfa7e92e9a99ed84ed30104f046cfbe725b8836a6840918d680807019496f41779e446aaaf67e5ad637b95abe24c94064b15b57f2245fec043df53f1a4c8277784720a51a7cf2ce9fcb42df38cd72aac805d7a80dbc0d8c67c980163d86c76500211dd9616180d7472bf62ddb0081ad2bc1cd6bc476267c4124318dc7367dc175e983b1819b49126177e222a22711463fd1ad7776734899183fa139b8dbbdc0c183232b4a9ab803ab6966f8a408551a1a5b37c3b5747de64c480ae3877244280e1864bb2a33e965a86dc590edd47bc20b6e6beb7f1a77804744750ec261500b6541b1a5edb072531bc557cb86fe6c7e3cdc8084215be112b34c641980f604d059beb0091b82dbc5c1f235dca28b9c404d47748c7784667167c86776768f055868b2546b74959a2353de4bc56fdc75f7e26b1057367170c462780050d2a6a602b619f28d1ba15af30bcb37ca7231bc8c6c75a84a0a83ea698ad8c9446850700f79b021c6487e5b6565c5b8d57374f3676b2ca165d087405c5257b309a76988431682c8c337814ee1776bac5d2af9b6d0b144ef51c91588acd5c221a5d9bf892509345140cd594e5853825f97465610c38ba976e19b5f26d91f111973d9f4c165ecba5fb7650a0bc2f35321fcb304a8a7685060b0e866885ee0bc57812360c10f43fc6d0d412c579461ead492dde64b6c55a92e8b19f9d9c7d985a6e784c0c5d73b655206664635164129450a6f46832cdc5390828293b1ccb99d226bd7c7538b54797478afc6fa0710465a6b777f86922ae6b18153499cde34ad02c3aa29f813c32220f0437826f9363224ce4b9129a2324b7ec2c59a8994a8c9274c869adb86838f48b832bac667d13735917f3e1934301968f6935e2a8a3686e786c55cb5c6575603d714f3a628a7424f0c977aec8a90c50b848db59564250625608457a7b4f88941a73aa37bebb99bf8baaf09984d4c1e93f51d895c2608b286a88b651bf13074f65f2eb3404d2248871630a4f33f3272020d9267b0a790be5a3f389132fb472ba48c99ef23abd650b3ff9402e698a071460608835677644ba8f75471dc9fb0394ef3082e8954b44c26544d029bc2489c5de04b026b40c8b37301803617d6224801b2ee56940131b2ec420c0bb9be31906774817c2d3a0299a86d05b62624c950d7e4cedf4714bc892bb7b573b608b70042a726a11636859ac19bc08243af26d314d2c39d08e3a9aa8b739e33c362b49c84773db9d040e3275816061aa28230427775ed543003cac647dc8721f88c2752a46ed8af121a66de657b7c3a7d6c1b4074d13fdbe3b433b49a7dab42e359bdbd9c161b5707f8e683d1a8451b0366adb9ad27a77ccc4506b558c25b615174e99790c82e6e616dbf063d3a0c396c76a1b5204e4f84c2f0255529094ea5b987eae0b20c9982c186537ac5522ac6c3cc7c1e571493ac184adfd35203da2128bccfc5e2caf4693784a4cae40a795b1436dc9119a9a8401db689eeb37e08591ce86870d11a8add5c02cecb93519040c487bd2c9327dd4a421fd2212a7bca9907455404ab2ad0b8b336a0d9891ed588575c62042ef52838f65d905996aafc33d84054b5545e24234d25568aba13317824923aec10728b0f8126c64d83ab25d6517e118da7f7b122cacebb4852ff4749e47cb9b6cb2aa5577922128864b64bcf6495d99ba3e9956c50579744ca1c21c3822be58090929fc70ac587552f7d469fc2c6aece5922fad3830549b7ffc679d55930e5d7cfaaa7b59967654e40c2eec070ae4190b31c8558a30da53baf872b852dca911b69027d7c0c35f96bbdc092cb1775eee57d8ee9a7d6f54d3ca2251ab57d22d5ae3184874e49a909b64f41b65670469dbd987b44076c66b2afa498b03dc65b4febcaddc34cb5281203c47ae237715aa1a0ab466b8998b0540b0c7ea13e7ba80f9843ad5d3c2be28939aa622d02ea4ba30132d3d74f90b70241ba93da962b7a2b974c8512af111ad7593e5a303535cb7e309589054ab1e25c4569977d4757c5262c800e732e0542219bec73df134232e64439684479526c3f4b1b5f6635c3741881c99f34b19f1149c54144893e378440630e447914b533836fb91b7aac5ee335209d980fc5c3ad3bc69ec674811bc989fb847e81b066909290de41836b00b92b6bbfd1c9098174319ef14958684ab2abb3da5aacc4b1a1a9251bbd43a2f8d592c7ea47c5795d8ecc5d0791340f476ed4c621dd882e3ee5ab5e962fe1c92c7e61a3d30038b9e4af6541876c2326947a39ac81c35f4c0ef42564e7349100dac19da35b99424db14b26a0a30ef8385c16181a25e6144925c439d1396a586f92978f41278e62b1b013b9abe3b7c3ff94569a95297332b41cbaa6cf221eec32639e438691986be5257c60c0266cbac659f100cf3169649b68c5470a5e147678aba4c4f06a6e8996bbac70556963103b1600e133b519a754d7b7373b7448554b1acb892424bff5f096bce0290d317de83cc109f0b080251094976830d208c8d1680dd442b5035fe94030eb98951e210ea5b685079c5967539b61f37c9ae090b0f829db764a84e991b3d58e29156f522115dd425904ef8331e26223c27d2aec1ac07e2e4b949cab57ca7ff23b9c1ba7e3bc4adb21a561aba5cccaf39a56d15b7418dd396b180c655b42f530a258376398dd74c974e6cabc0a993d1ae16deb913b6abf90681701b83649c6e3e2e6ac +ciphertext = dbacde8a75a7244917883eca42f001a92e3fb6e580d4647134b8abb475a73a23f378e2adce37060a1a204048a64b84631e241dfc8402d7285b1b9141c76ea0ae03c486863a941330731bf4e4e25ddcef66f3c90dd4350fec0b6f629b40739197ebea4c2f7b355f18fc58fe92ad5df8a5360779ffe5a34ca6530037a3916b0498fcca05f07aca2caba0ae1c9dec6b58207310b6400e5194538b4476214df6c022a50aeef027a1b8522d4e9b53d77a1ebeff6f16a68c832f0e08f6b6c9efa92203764ea21baf55edbbc8e3b2bfbc10e3f77de637c0ab3c5fe931bb101b3e7267309f4e9b571bb74e1ad10adbacbd80d74ad371b1e200040cb3a957eba31b926aae09a1a0bd21959217160118411ec494cf5804ec42e3e09954f02009d292fbc8430210cf81c7c052c95f997401c408a01b8a43ca8ee9e8dbb8a2cf2c5f48212d7705c486810219d74e674c6b7d579c4f1338df7e23dd05a885dbb7f2af335d186b5c5392da06d60f1a419eb80195e00588c71c48e22cdfff7b007053ff91c1fe9f35adddd456c6717414896d876b543ff47e32bd544db3935237e29407eb4d317a570641c0d198ed487145c4ff5ddcb6ee002b6c7b8267d910829f78e34ec599b119daf39ea7c83ae5038e77d839b346bd6a16c466e5628e2dad4aa0b84f9f1ee5c740311b3e3db53dae0f11b24eb3c824e8105944c1010ba6b7a72574b96812b3cd8a1cfa31ca45e458949478d04d9be417a6c0e6c042592b60cfc6ff8189476cd442b4b2d8c53198a81277bcdbe95767284f50113edf58dbde95cf7bc762afc6471b633a49d1e068943e03bcbd28cbdefabc961b7f6bba235967956973580cba81792a9cdc340a0de17a8b2d49a44d130e796e8a47529470bbdd9a7ccb84d48d2b26aa2344598ed707976ada182501d845f207d5b82c66f38d1112f84810f4e3eb156d9fb168173c1db664906a58a887450487bd51669500f05770f4dc760634d8d4803c8a312a5e61d63725db72ea6dddc2c2c916d94d85e4d34f411e19545b1100fc865acb5fa123871b78561ec3eab26b513607631fd240cb282ad98a82c5344ce4b8f60dc07a2e1c4fced865ad841b5df1f835f0e00177d77d0bad3d01d1f1e6c0d0268cba94b6d5862c1b817349d031489776accf07ce7aaa206465633e06b4c27fe0aa846ea5b5f4a701a6ce7eff3465b55f8bffc8859a494814cebf16e3826130d6511945c6d957a26abbcbd731dca9ea3265845c9ec7925f5a24d27c6882523929a2efd07649e154163cbc8e7d34898f8bea14793db37a36eb90d9567b848a391e7deb3bbd0551398649fcadf74f4035e79f4bca67cd63d7f0c2f95997be476e64b5e83dc089f8716a8368020be30baef3ce54fb269b40af99bf81f57f9d5a3d6790210cb76554212a33a3e266b5bb4334c0677cd3c791a1d7513384e980239629a47f61cb42d3202fff6804112fbf1dfdfb48a296d7eafb1574b0ac3ecf00dec4d43075c3b2abb6f523651715e3a53de51fae8e84f4fb546ee7d1942a801a6ef281f5b3397abffef12c1efcbcc098ec58bc607efdbfbfad0ab1c8c6be756a6127d088c3dceea416c5d1041d8ac7d1ec83c4dc343c77d1f29b576d038d78e080c0febc9b2e0b45d9b5211dd72a2196bccd670b795448c300a9c4628345c438c7a1a95a198758899b6111116a35bc6ac523295a19766579adaff2d835c7ca434946c957046e3b247d2c4583c899aa9077cba82b6c7e7c613c762800e3101f6e9dfa763a088158d058fb6df899dc7a764fbc61e9dc0da91fc8849f0899c14dfd6f1470613229ecc9c142eb801320d86d71d0d23ab5dc051784e0f46e0518674e151e2e38a3e91695125bd584206dc1bd79a9bfbfe08326554867848c1d9ee44b32f32c70e006dc0d05ed76c9f49df4628e76376f435bb8338423828237b157aec1e307702484486ee8acb7adde53fce93199b8a03d594d3e8c9c7624f84ef9b9eae7b014f0617eae4aa922901496b16a9208fa11647a7315f1db2600dfcbc24509164d6a97a22110299c5ad24ce30a2061d38f49042e508e0988c37e5a0a6f269e9712362e7f38df48903331012c5f7869190e001f0fdb596807314b5108f2fa1e11f4cf35799cd4028b3d77634a3daab139bfcd906fd96c2ea4b8701d24ac55fd6285cc87a035d46b4273df74d7f0f8cadb3d6a21c9bf043ffeb60527833c2b6c7c3480be9e3390224405cbea20b135bfefc391aa4d31683bd3fc84 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 125330177a4865b5a79f637fe9a101a4dbbeb2903939cb2d66e4cf19f87d705b23cab7b3efc172503aad3db743877acfe50a7485b7ce9fe2677264c2b5a39d63d08d3e021e80e87d2633a12b05264fb17bdb004040986d1d301ecb5a378a878bfbf5cc72159201b24b2c046097230560d48ecf7568cc3c861185412d8878c477229fe88e8d700e4c393a6ee87c26cc606f6a691a700758d4aa69ec630f7a1c57030a141b5fbaf432ca499388d9b4cae07ed6846450b5502f2c59de4817da90cbfe855c6d707db09272631cb1bd1b008c66b938c3b042210baef66453b3a4a1d818d89ac7df6bc6a1604de63ac56a2b6429757ecc6218b58760db42ae1778819e181690f8c6092483c145507585b053d2b6b8b29cdabacb0839bc1c278d62732f0b406b7ba046b161175c521681e446cc1888f027003ca62445114e3af9827001181d3147af57a921394d8ac9140e7029d7551fca696505d674b7730251e9ab45080a3feb5bc274b5d986b366db58dd9c3a60a24b654b6fc498445553089072cc21a85d356b7136dbc9a0c30215e92667fa01246b1be5a8c7dbab59c7c681e00c8f50381895fabd5ea65b24245effe13377d55301b561bd8a56b2fa6beec49f72177d389c5fefd83ca1d40d778252d0d7c4d8114c838a0e9a4917b0536d9ce455ef6a51674386cb231ac7b1096ddac9395b7699ba66667019ba8c6f40e120b3f020f8810ef8000ad4550cfbca8dcfe528fab755efc90e55856b8ca50ce07623162ca3e2eb5441416f9da79786cb659b22bbeec0c6a9734bd4ac1e64e24c59e33a502b4a99eb3631b38eac141b58a568eeba87fbca83824198ad71b1dcf57eb187a04b70a9e4a4bdfc94c64cfb807ff1ad3ff4bf7088348446a330d19c0737301bf2c62aec45fc18b9832a7d6e337cfcc0721433ae79a72399c3160d1193edb319d34b627f47c7cb7b5d339a9dfc724e48d5a1cf4657ae42c188d5a968a24e1908be5f57c9b6f2074639539508497e4caa7ff61de2305fd1d4275f5a1911e35ef1f13e5a06af5e0638d6d24164662d9cfb0c151c554c485694d152a29953cfb96dfd2a8e9e4bc406d831cf8749c2d14617889496098ad72a17a9390c7f38c7fcbb1b81340885aca728f21b89612e2e86aa19563360e7945f9c6591c7a07a1996b23414b818bf10a472653436e4c155dc5079d0170a456767ead5bcb35b73978278734718b153bf4a730c9b955407b86f14681e46a330471336db12b92010c8d19213240c8dc66523e617259855bcc1c15488a2cad8e665a8612d83524b0b03629f873fad531a8069955ac1aea0597faaf2413f8ac1f650a3552b0b56452ac860a726035c5fa990c9da9b344413ff39c35d119fe9aa8d72a803c91b59c1d20571415a17179ea5c413bac0ceeaac37c48aad058519fe12c6706600cc296026340eef250238c7ad675168f4c99b233a939111a86666c691a6bd9dd913389841ca293bb9c7a578c0b4d795c5f5276026241b1c835c104b39c5d20e3831a92ee81ed1f751e12c693deb2b7f354d136ba354e503d7e59737730d10f25eeb798963593dd12cab29468f246a424a370da7e758e3c933a82ca657875fc1b40a7fe2316dd888ccf39e20030d83bc33be36506675283b996c355463494372258122f679c0ecfbae4f264fcc255ae309b247292322e98e2c5474e6ca4ad0685577568604064aecf64479756e36e49ac3b2ce3ca383428081c55530d4580c2a3b8a06752842f67a402c3db98b494d6807166b7963735aefb86785318bdf8216ea793413e14241b04dbc71bd224bc7d54b1668b6c7b0995c899b236c3a49e1785f75583250bac8d430421bc29dd5d21abd911afcc8a2260c7ace4558a687350d58c42f877c5a32006772a68025cf2a3c8bba25a016a9a885a46c49131fa9d45a426c5185dba51779bdb6786c04c7bcc0c5775c6575ff713719430dfdc7cc159a29d6b24f7d41471aa45d45fb2d899c5ec894460ed5269c06791ba8b9b6c81fe2301936078dfea95da95c744d45bd2582378585cfae335eff1426b6b635887414d51032130b6892010ae97840364596496c7143c6b2fd7c3adcc34c1055b8fbd4b527293004f49e1e9b0facf641b913783f9a4e585abf0572833861932be6944887cd57aa7fb6111d4e2324404916cea713234bc82190bbed3c0e17d65f4feccc15b071f30c73cbf868a6c55d1e77b9e871cd4245829d1430b7b301ade77ad85c81bed21d191b78482b131c25a82f329962850763186bc5a8460793155145c50f783b9a19af70d239129368d6e869042348b973bc9d369bb6281596b35b3ff005f7c79486c45700405bdf0853a7cab1162c85a7c43c61ba723881cca02acb7812c53c2214bee75abb403da94b036fda7866866db8e01093e03e75d994bfac188ad03cb2514c09514d04a2acf0d7501d4a38fc375eb1d6591c475910715c4be94250ba231eb2bc86058e3f399ce7db03e0647f61b5672225b2f8ba5be38772c9ba75312615ad0a2615a808e7836f124c71dcb796cc27abe522083be0b5ac46006ce07329db7f0b65219ea172b339973eacad3062bb83d07fdf2b9ecdd5c41c6ba528085781787a345c61a58cbcb20142765b11d5c539d9d184bc016b3245346dfb3535c59b51b6a2ed1a410367a416c35b37b52422cb88b27815f8b29f9d4b86ef961816c59258a304f3238818c81e310536caf155afb826ae079e926926ea259d32e5230f884ec55461b1eb91c2258b57992775033a7b3b7cd5c15cd55a7fc37a4dde18262df81b6fb57fe188488dc8c6912753d539774823bca606567b959963804da5942dab129db21404a26b67f37657f0d370d5b76b06518135d5bb4ce94ef519746d4ccf8fb9c6208683dd671d20fc770256376e1547876472a4e88f42c27371864a5aabb17910b1ef556bfc773a2cf435745bb2ea725f4f41206e33879c576f206b9faa700560019d7b94a9d6665f0594b49d8163bda93ea041c8c15001a6a3c95ce67ec2600b4c399a1a628d22321c45e9001d238b22d740f0fc5735093d66529882030941e14b156a68d3b83635e8a88e363923ca2cbfa87b76a83328c97c04d77a48c5935bfc1c70971604c90d012656ebe761f488611f00a97b3573ead81068191d401a576bf849f0b332fc90caf2ec81431aa5769cccdb4c2a9414b948ea3803e8c59a2205ca3a725e995b66d74975a879dc434cc3db8066f01fc2ba33922a2cddc4b86b90b4cfd4b95c885ce8b852d9098bd7d171e97579e2a789b60cc549fcb49e233892566ad1b5cbea493e07c45e38e31f34851975c3682597c7f666691550530e982e6083499b5638a8b85847b75a1157365e36cb53438d9902ca91e69b3407907ab774a5b0061a34481623989f1cb7f439306357b5db972b4657cd9149137983379c214eeef9c2ad2b3db713c6e498b369d93e28414cba404a519542b23ccaf6c843882c914c038e9f85ba0018913a227f76f758a639bba042c0bcf448c212b5269c7c228893957756f5a97ade8b5a0ebc061811bc26cc7e546506c75b9cad404958a98b1d64befbc53711c49cf9a3a0edd5339c7539d864c5a7f610e2248773eac7de480f19c86b1fe31e08d2874caa485f6a3c6b2c86a4620aba828072e31a923b4305982a6cd9868fa2b35a6772d296972fb00d20e5abcd855bbd50b37f239710881fc5b08388f12b277a41999c2a7a44ce2aeb53ef06b9ac76a6a17266dcc60f4f11454001a01c0394c9b8379fb4173fa657b59c00e450497e79b1573222038c43f3120824c36f6616c29d6328f2914492b03dde932d44591505961dca3bb7711a8be2631ccdf93b66c8c8f0069389606cdc468fd821a582ac94c2d2b2c70977e917a4d95624290a7a161156d24b887e2c1cb4461fe7a93245724bed171b96537147d41fbcfb9e7a44942110a510ac7d5d95475b886800bc2cdfa8551219883a73b30007138174ba3c774a713066b7db8eecbb8967b91091b41ff53ac5407cbfd7e779102c6b361aa9f270609860bf9d01cb2f3742e4fc3749564f4de98361f20ebc925120a570aa802feb5405c43b7ae172c909f5ac969c62da954c6214795fb9042bc1685cb637ef09c09ce30ce3d6581bf24c7f490fc433a29cc8854c3a27bf588c565b1cf52665e3d8b4f6750b1081a334cbbd20a54a93a32f500400dd4a6aa7834f1b8c600a71c39a88a454b380fae8697fbc50fdecccd090a6cc847e0f56723030cebcc08bfff8674ca284a938581ac85f77eb37cbeaa62c15098251b1f1447fdf582d8b5a9be4fa10a5206c4e9933b12670c79b0dabd9654b530daaf17fd9be093a48f1921b05063b6b402f670066c4dbd6d37c4b33a0f1feb7ace0ef0087ba959caa9756d6522efabb75ade4ed3a2f54c7b713b86c9c1cb551a0edb8352e0a76f802515e77843ed6fc68d2c7a0ab2d940b6dcfbda574965e2f47 +ciphertext = 8bc0a262daebce1a711b6d366d17e847794bfacbdbfdd7ba05318df5c14f9d26965d92f67417e5442bb1e24b7ff185ec0b1a1cd93416d54267c646b93367b18531c241ce6824038b5f65e8575db6c1d4df3f62fcfe283df8e13dd55add3c4b192463f088f411f793d7be55f7557f49264ce651aab1b4eb8ca9c6fdc5adfcf9162b2c4bc1eb79c522cfee5b64bf8af8a013453330150bfc21b547ee507caa9d5b05ed0776e825210507a5278e1a7665cb8fd2672b47edb808164df8e1408ce4aab4545bba1e844264e5bdc035010db2c62c6a49ede8dffea2331731fcda92151c414c90fd32bc5cfdab241186c2a1e83bb1242df3b27b427c189061cda241d995ec735127b20132fa68f4e04bf01737e3ad2b3749250c6bc9d451bfb672a6de0cf4564541899230fe17ca0ce5eb6941eac58a85b51b4e34bb28b306e8c6f15edaf9716872dc3694469d9647e70428008ae986c4392017dfc0a4e678345062183743e33f59bfa17fafd58ee0039f2fd770de0a1aa3cfa8b3337dc5c74d62726a2cbbe177c0961f9591545f26ee3bb6dfd9ae72348654445eba818fd9a7fd6ecaecaf103a105a2d7dceeb301937b1c480e3e24a7f0c2c8804c007f7305111e0e07912214eb65cb39c51f77d7f5973d31f18ab7a5f3055400d11a748876e501d3fe9eedfbc58c7512250e00badadad1988301ca926461691edf3b4fa59de305816988d624ff6597cdaad29871266e7f8f720f2b35f34ffc0929c5f1bb253f19c903ef4da8c833a05de64c86103f92264fb0c018f4e4758981ae834331f2a49193b35f8035ddfa2ec798cbc4e2a1b7368459354413cd1518a24542ab34705495dfba051e671ead1eb7fbb658c6492e0a423e743add4429c1c27a8f1d52bcb1fb7a00dbbc7c9cec242ede703d3b53b62c92e1c49f8182722eefa3780a3a93e04760971e5f430277df0440cdd65e5ea3f3aeb2f0dd47f37b0cd546aacd5a9b6c25e666a021d89496e90875de4a456b563da7e0d782b7cb4c4fe3e65f404cd3e489776a18e697e8a09930fb576380ec70ce24f95fcac0fb6c852d94b3a5952024aa8fc01f7fe58cdcb0c496d7ae75a8e110a89b0757f011d4ee99edd5f5218a87641b395f0b685c79c9c3c8cbc64963fc5d092e120bbdecbb40f500828117fdfa3f0a5bef41a2694ef2953ea833d14ec1ade086770b21952be4db16191ff71895fc5416f0c0b8bdb5a7a0e2e4a0d124dec357dd612292a491140c00622675e88bc0188f0eae4953f299641583b0967f7ee77d7fd693162deb065432b5e2369ebc3c51891c498dcfa2c7824013f5f55c5294d24b58394f8db55587b550ecb33ad1854ed98056e98dcd5f5655b9f3c34968e104a0dbe3e2823eb963b27c8f6b986a67e54f9da63846fc89be755a5d9a273c098c90af828dfa25b600f532a0baf3b8fee6e6269851575829f4dc869538dbfee25743fe1e4a8c130deda24ce1f166110fa75620f579cedadee93a2315d7daa28cd69d799b04166cefe91c4ceecbbd2a61d73e4d63028d353fe13f6bdeea9441ecc83f7b8cc3ae36056200b98224325c9987290c68501cf22f55012db801b1d2d8262ef65c81f11c2774c5055cc21df5f46f5c75f4f3110634d95d2aaef9735aaa60ed192ef2440f4aa5c0093581be16c8dfb7c4e8cd7d0f225744c3e6e02f5b70a91ae996b07c1ac37795bd82c45c74293a0ed5751b3a14df343683e6e924001c2b494949300c699db46f74fd10da49f1495be88903da8f4bb94f6460460ec50526e542c1379efd60a22dbd5f06e2f833a3d71a2b7efb15d1d15433e8b2cb86dedf90d6dc4c3e5b61c36e7f2e44a53f20c0cebfd3760d233dbc9848986728d3e579d1ddfcd059168e7cc8d7a32bf4f24b97f50c99506d1db062ee93aec55a5eefc0beb2c80b36700e9679d589b1cf70e125c1f7701c66dbeb5f31c1e12338790fb0f27ac995f6ad7a79a07cb9e83489b7694d727930b0e2e4f47f59d6fd83b3cbb6ff528ccd67d7450a025be3988fb75bdd91f7c32ce17266703c03c7bf0246eb15ddc3635361e72b81f2cca65081fc3fe199e8538f39f4648c971ab3929a9c93d6df8563f0c9e7bf69f9d998bc1ccd1efd33c90b2b9d18cb8c34f0e4b1a76a62ad91341a9ed6d20227664bb58067bc3945b55daa7a82d46b8c4d611197c810b191ce27b2dd81931535887dcfeb2794f924a0cbdea3313a069b1bfe2e3e8ac +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 5c127fd25524fcb4b9895665ea9ba98ec9ac372945798bac9a00af874cb0c3236ea024c2fe4314ce288b335016e6c8c7961b4326627e5d5ac2f57448809c9d3e798bdc7c2761529a92b88960d772330247bf0172e732217f7b69e2092b1eebb8cd09502d35c8dcb60d5e000082cc270089976020c93c8569f048aa05886111a42443f84622820df58c1605f45fa9578088a114c517525c2664644b8b7a4307907682a3dcb44fc928c5511b715671d7772544293f4d78c96e3b64700649e4752918eacef3da6c82320bcef85613eb3a217727b435a0e446458b5523c49a294f9c9819db6c0f6642993169059685cf9637ffe2a762459d8907a16ca102c3e42f2ed231f906cd33db014b89b2c1031f16a0133312317e1c0dff5040309148bbf6ad54b73a86dc087353c2895b38d7a07963a2775ec9361de7a01e1c7db943cf50ca9df24213275ca332476b0c9058463002caa72c3f5273bb584cfdd5004dca92c5fc715be2480e05b71f7283aa0260162bc413d34ae0c55eb84bb5fc802c47db210ecb7c5825956d00590e3b18c53772d260064256094d37461ce61e5dda5f6b04b8893817f79b5a230ab87f3b60cde676ae4aca2a805d1f78aea6f92c18f3c7144a164e47a5709acce7441033d77c6c93448a3459466709ef262d5a143fe035422a0a36da501b29714b03f983e9a80c37eba3b3c6cde1f5b07b0b4cc4808d99c381dab3955ebabbada115b8f8300d5741d2a3aeaf458557c170db046f4dd46409d2b48e81570d86845777471bf493c657b30a7a7969ba75344b8103e36b54178383dab1f6e88b7f0135dc65be5138732328878f203e8f3a5c045809655c67e42661d4a72237027263cb615a76b96014cafaf740a45a0f93b745d6f37c63143fa49c0e28ab0079699fac166b21215f474283dddbb839c75248340dc85279b5b33e07e7407f1c777315677782837ca63ed51a072fbc7217d5a914a54462852d26267c50b4809124b9e4566a7478871e93a6151ac68eeb5367fa3441a30301861375ec603a68c1c361cd59cb5a41c50e7f32c1cd34776308967f06364f338cda588b72dc3d5b3c1189da76c830ad2a7388ef53ca94034ff1e8350fb30f746b0915b689d6028144f699da415a5cb60d5750548d8060a74cc0e636bd1918b536b2b46a61029fd46e2b56c56ce6b64069203509872e2972d70447ae35cd0a6434a9f699506a4c0c7cb9ac844cfd3530a7433d8f134c8b72bd2325ac46f26b32984e8b1629109b55d391129e444403867e3d66bc06e9aadf965140893287327e1af82b8f051cb5e86ee7499aa3584d295499320c5f662b2fed125daa09b581d00ec793a49968c31fa9284ca09261ca5a6365bc3d682400e62f0a351fa9ca21d18041bc63a1700ccbaea97c9bf341c0f127e04642e1f24804ccc6cb9931ef18794fb951eac646910ba020716e785c0daa3468d63b58aeab0818404416859ca9c2a1f5c42df0f70bea40a96337b7adcbcd1d8acfe26258cf358cb30287d5f17146e72e805648c54974dfd08038ab88c2a6911f201c7800a7206ba966161a7f8b13055b5e974ca13d92ad6ebca8234bb001fb0913b4a22c0862224a59beca0b20b15c7e889e69785a6c0128f86382dec767aeec44a18856d67b7d4c033a0e63286dfb3a0d270e7f27883b81903341b54c9c4b26326903f30774f0c36441afdbd3c4cb950285d0c8a91aa773bab1f05a7228369b8bc57dc00544284a37da07bfd547643753b52a55c9595065757c50a9ca62f53570a3ac5700edb513b44fb7a61098f3a95a732943560e77994a88e526c7f659c67a6791058171eb8d6c6491e755570da34ef258090ec76697cc4bbc9a93f9e879d8460e13572bb2c1934a72939ff286d2120e5d0c1840c164c447bb9ef94205693423ca889abc45b203b51d68c4596ac9b7c897080b57942453d228cd97eb7b9ee317fec084bff84b7197bbbea77dfec33654626e8c459928d76c3842bc69c9a9be91c3e9487d972037da98c1b3784d29f19c5d2a3c1c1b709e68a71380ad8dfb120f4ab9e91b58fc501dfb2105f5985fc92a9e3b16105be03daeba10418453d52a9061162322e385859b28772b7ffceac26e4504fad131d4c0a4250001632a7bf859a74629c827f366321cc00adb19fb898f44994950e5a4b003afff8c94c5529f6a9708efb8326a319ba79b1632fa3813861b38e4844db6bd7d2992c93bc0b2526cb3271b6a452806938130a93f3f05687f1c5882555d19c6090be88dcfd296729912a31b6bf57ba2ab104b73c057c6da440fa6998f202285d17fb89879d7433d5ff54577cc10ae6a99398c2f677b41fc346b3c7aabb441a407524848e5b2f49114a314a85fabc4aa45bfe3255db9506a762998ef88aec3409bf9cac77491b6785233ea19977ca35466313d509976a2ca42188578dd2ba097b744cf31b1bd175183729afb6bcde8a875024351bfc7995e3a557d3a5c15f439215264b57a4998e4baaa424294aa01ba8c3052541698b96fc8214909064b06c0068c5a8698bacdf70a0637e30be993181b4b6a9c12b84fcc844ebb91ed641c83a551f9f304b216016a50c29cc154460a13b3b8a232e845834812cf913597e1672e47556d95661a670f0462c962f8a3fd8b4ee7a4ab60684ac368b44ba9795e636cb1523546d0513d894e24052d75a2925b83ce4324423ce8621f252177043fcdd0608a821aefca5d0df31f77768057b15887e2beb83713dec39ae5705457f733a7461484113e8815b51aa4bffdc28f501ba1e089cac706c214001d0489c07b086a7e51abc186199dea8a755675daac686ad5b28b19cc61b42052020850e0676338a210599eb29876d29a350fb8b128db4123783e539b189c23a9cbd62c54d039a6f682413158b54428534a3af039c52275c188031491337d249679c6a1c9a1a470fd21a11f393cf6c958049cb854c813d1e6b7aba405a947358eea5b8e4992b63430e020a3d31ba1ced3ad998c609d414d94b550c5b4216fd2c559d163463b5e470049e6395296ca3727ea6c9c84a5548a5270075d7a2b7385056ff2ac4cbc3b233d8c2287ec0c544c7589d9cae7929ff0c3af6394b9318c4dad3329e4a56f75536bbedb689e698d5cc984c20647fb9a5ec13b0587c2a239248bd162bb05112cb0965f72278413a955b95655c454c2223b7e72d22a63f1cdd9651c9c61b32e991d44012208672d4482aaf57a247212703deac7a1413d910265cd80ce8848436aebce13f9c3164a8175a1505e80386098c642d96d20726a4ad1654fac2e28cb67c74c0b5faa868350ca005b186d717b9670a6468a502d4223a70a667f2c3f07385599e48f33c24542fabc65f49f73cb589bc17be7e4a1ba6bce2ff90e12d6caafe64325024cc57a88145c952943068185c976c92f7ac008aad94106c8441cb8329d708c32e607e9145b33451206e0bf73572a39973023051d2d985259b233ecfcbd65113bb3b4167aacb4c615cd69ca3eefc39fab59a3eec131749a2bc2d317ff738206ea44cabb1ebf395c3bc26bb8611003a1348a580bc3fb3ec5993d6e9491eed6892e2b2515521e29fbc16bb03f9ae286fad0952969162cf309ab439ade89cffbab76e9ea495f61c4e8c5555d93133b549c193b7a3fd645941367aa0b5cde7b6d17a3c04ed374665a3e16f98c0e7846c6544c57fc442e29c1c0d8c5eb8153fa2c1bc6ecc133966a2e7b9a8cea6b73d6cb5bb3910fe21b97f3aa14f9483c958a4d252cd03c32f2d6513f8870b89004d5c20d52bb860589a57f1b17173a96f510372eb8581be5388132c7fa7a2406a52c7bc87e9a0795e83730854c2373d04961550865ecccc924a0456b3b1786903e8402849b298512c711f114939abf588966b58bb72e92832c05943c83425a040878e4c0076b1177281def810c9e756842a1c585524f706ac491f0a9cbfc9020a835db7bc2f783a3211160d9f56efbd12d9fa8c7c705786c7c2d10f33b0c0540846b7fc2cc9c9ad113eadaa9851029e4d97232825be7589d5f6425319b4a5caccfc1a767f6217b27e95938cb4749a16d59b6272b70070f590878c709dc125a4f188d31e2733145071c80c7efc5435e8c716b1517fc4c2b96a46ace3685d8f1acce577a53382fe417a122f4ad73aa4073bc7000f781fdf4218b3bc8354950bbf96d16798551dab4aef8c7370a75bcc74670b0191d30a422e68c60e821c50065d254756b38096d5341f0282c6460748f5c18b30a4d51680c1e781ee134665fb16c03c8c282909cb26925fd363bcb426820a27529b88be8c5c3c1e92e8e815e3ffc4064b9366ef56b5c4c237e5e45b8bea05b37c7f4fdd5b85018709f7a57e8c78b70aaa7b6eb4a218d4274cfbfec85fe1c16699a5bc885635bbe9399c6c4ec32f0070b9fe6083bd3e7b04bc9d9704a0a3f00f4c2d3a74f679a0f6f18c3a039ec2a6fc1f0f8e066232d5e84 +ciphertext = d8b822528ba50b5d9884f675006d9d605a31e05e830469365c6df664dd90c6d42aef21043318cd0ce1492b2083b1571de9546cce20e747e906cec4a403676854665a1fb1295a5a9c1e4951dcef7dafc7213a359bf88e103c0b3339ebe9ef509ab8d36de3cf3a1c1f4f0042c4149bc965f4bff03544c6f936d030b3ed63b0648675590052b9d55776e51084ce680f81ca12014bf992e122226b06e9b6ec06219948c2feed4bb532f9b5ea689e97700000268596336491e3c7f0a59d95bcb7a76b7796db43f53b0b4b50ad4005434a2e3eecc1f644901659d0883473594d6da8e6fc9cd9af718cc1b6adbcd072beb477d080b61b546858d0fa6fab5b3e138c8e4692d16b391e795838acd5e18e00859704c5072edcf66451e7bfda78065b94f5bb90ebd27fefd3dd2ff53a981eaf777e7da7b1df75e81fc2edcf6077a7620f920396f0c0a2346f151f07b28e2b30977db58106e2479c2457a02f0d7ae37918dd90b412be1a2feef4d39a043dd04d477ee60e69f18291b132b1a0eee114c2072eda51d184275e6e359ff29e0d6d48f5b8e2b79e69a4449826d18ff1091585c7b4abafa0013a31a6e077b0f062cdda66f47cd3b66fa88dbae2bfcf0d2460cc6787ea8fa339dbf256bf93f022d7d6e3e63c8aea64e35b48cb93be0a8c1601dc86072c031a06e5bb9be8417baa52b4283f5e515543cd5b806465b88f2d8635ab5db11a031f7f4880022805045d11ec00ec3af202602acd43699bb1010cd0e2817db7bede25d250af67432d88a10b1f51acae18602f6702b995a63d84e4d9bf6dc1bcc28a8211356e96151fff614e1fff8321f122c69fd015fd668d776f8eea09e9f516097cff32d5bd88c9d97b259d6c4ff748fa6f94183ff41736f8a2b23747f2eeaac261a2178f28fff903174ca4bcd821e9980a2d0d43af2936820e72370cac17aa789047d1ac951b9759ea93bee0de37ce2744aa4d2dfc69e67455cb2ffbd48b423d6a22bd689c5a77ad3ac6eb537d12beb040d87651db8f46f2a0bd7e611f6482e588fa84d2741d13e6643498def7b898b91c7c3f3ef376478dfccb2be2faa0cb9edef3d5f73ce9e764217d0c6c79ae335c79e1a4d0fe9b38efa9a7a8aaec460b26d7b4177976d3b81c0d9736b03c06440e7ea5b2afa8cbdcecc440d36827aff4895396fa556de1477e3dc6705b7dbf11129b07ff0e88a190d5e3d1f7f76897fbf82596ca1d29610a7bdfbd471b303d0bc343523e45b2f48af7505069a6df7f0ebed2fdfa6e5012138bc62a054f9237e125a0cca1a57c85bfc249571045025d338a56e390a97099bae0ca578a8a49495a5c7462b107bf9e1e26d5fcaeaef38fbefef1aa3a684df1ccf9ed96baaac1a254c333ebb4c861eeab9e5e2d8ccfa9d68551d55eda19f82d011c575c1c90d17e1ee8e3a4157f1fb0f6323cb0f1785e73048203a0ceefa836134a22640fdc3cec04db6f32fa0e1cb5441657a64b20f2f945d9a5b0be6870a8d640116296af8ee9f21bef5a1f4aee6ce8ea27a85c4260f12f9aec9e9812ecea5562b236b945e5b2109ac6cf79a797201e80ce453b637b53b6c7b6930805d849a429166afef227594d473ee15f587d014dd6de5b11ff2dfe67b0dd5fa4a80547cc7b952b69a4f1c1dd849c3eaefdda12521de75f908b8e2c3ac6af7490195659662e65de9bdac30f189ef99cd2ee19196c76a3f18da59f8339da8c33617789f2e4bfc40fb729268014652ce095797c74a1e64e06661f67571e5d543f9a5af14aead9857b94cf9052e244551a425afcaddb1e234bab0d5442745571d6df324545a1a4b0fd34a68932c11458a24eb61dced09007d373810230eada550742b224005f800f6d0c02c4816b2feb3c82abe6f5c5063d3fd763babdbb4139d280b72020f84cda09c58aa592d83f4b2be76a82adb05d1840dc1e5bfc144713983ccf0dec86faa7148eb59befc3db95ea99982a42b5211d61a6934cf9e83faa81517710e59eb43d8b6ef25635d7b1f86a1b962c15500d4e5d85e96567707669a715805b196b203a91f2fdbcd351d759a3f24bbf79b8e24415eed18d97974681bc39650d95c2e94803461243ebbd020335cb31214d7ac985c36cb6c7724391ead74b4ae7aff3ec3d80038bed655c521cba23b3cd3b3c5db265cc6006b7284aba3ed0fb7c8549d85eef2d711d6a1eeb3609b6ffad0ffdfe3f49ad83fcdd572107a5e142e4c0b3553c3fb12bdc33dd9a37cd +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 45c6bb1e5b9cf7378228939f195cbcbd0b44ed9ba90b1a2112e338c9a4950cf60b5ea3bef5973998586f64dc49b945a5497b8b12f33cfb5212b2f9baf5aac4f8b8bc22e4a5e67c3b409c0280c3654a8466414068abe5240510038aa1955f18c89fb0ad68915387005c5f107cc743716e706d19d869eed589c8f671bf59a8c395bc4534ced6b6b35119021f7c79a177364014bb9dfb71f8949abac5193d04bddc6a3d8cb99934276a79f36a7c3a7f664238fb5625ff7942787a22c6823085a40437c73b330a890d151eb8eb54827b4cae505d6019c6f9a2ab99b69eca793b408050807c72e757609ba83cb9a6b4102981509a90fdcc34b7107dca580cce3925017c97b4c2619054a3862449fe7231f1c8b7fa2a24247c0812194b1ee5756bc83a2bb301f2f06cd1b2272f933fdea3cca7f49b775104b53bac0f0cbc4212831806c7fa5547ef005680d96c0e53307aa25d7c0b5706bc4282483d0d9462db529e55d68d9e75b62d970b39d9cf380aca4d0a46075c3da7d4ca551650cef2330b97b37f39c56ab7275ae41ff529a604c905e907b7ee70bfde46b20d753b2f84ba0b8a6276a285ff4cba6fb5c82bd1358d1c56f5441cc7716f1c9aca977733014301cd2510b8ccc23cdccaf7271cf2d41bc74a39394b344253340c300b45c9243808acb5a198e8d26fd927979c6c0e558948eb8c7db2444f09f132992586152073fb216618f2920a76c9cccc203f954d00e883fbab57e483c9453237bd19a293dc9b58736f3d03269bfa4a486245ae82051919bdc45c3bdcb9a7fd401f6d6a0ce747589e495b24c891711c0aca287c2caba24db68b36f61c78a968b53c48a8040ff698bf95ab1850bba8bb40b819c07b2793ae901bbcab30656f3987f277822aab7ba46c987b529dab4789c28b1860db35dcb24493e67edcdabc7cd41d3b777991929fdc997eeb2a8942cbb65f93aeca3c8786a2b1afb5a2fdd081c9324e8d4735bf8b7d60b0a516972048114cb5688e16e94967e3952fa1b6a1561a962aa8679ca828a84743770b70f335f91ca109f269e0891dfa22a4d702c03248812ebbb745c93dad93cb7b26c1faa8b31efbb172708f71b24ab9612abd7b4e595a0aa9cb1fee34cc7119328107352350880fe053fa671967c65d8fc21871835a79b2a6e84bcf357a4f5248808f2c4abfe67e5f2862780444b82357fc21228a090439346d6eb424a60566aed48b59c1c80c604a45d01334787ff33cb5ad32c9b674595e1571c3832d8f231f8f956365713c15678949c1befb557b788829b2b64e9600a706059ad8f50cc72c05bec365aff7441d1c63fe0c68f817af6d99b6d6c8a524b4412ee6adef217319ac13ac08700b6490a2c092adcac33a23157432a0e99b9c558c5ca4d9661bc0ba7cd99d525167543695d330216ccbb4151bc321300bb7374ab0900397783a674a4743b9c4c51b58d7a5b5771bc93d14aec6bc5c82258834e85f5c7153e8d9a7a460abaf20c32491a2f66b7cdc17cf2017c7757986312b5d6f831baf6c6088f2445959847b4b6b58ba65ad206f434591324b7e2114276521690cf63875ea505c9c2a8b5ccb0c6bbbab294a50abcb82db29c89c3b0f70709fb6164a058c42830eddd51e5a626b0c8478134938565142886c673e557df9839f7d61756a21143b8674c6f1b7ca539acd3476f016c95c4361f060226fc19f53e20de6203b89d76d46c6300d216a5862aa04e2cb331bc871825641a48940c5af6a97959bc25bc76122cf43279d368675810e2532694d95912541756c680b2bf74b2f0645b358048ef3b1e9c569d8641fc0b0cfcca02d36f3b4b997b4bff03855eb66e6e2228cd6aa89101600033cbddc236a81660c04640f88338a218dd931c3ae6245bf008cf09b501e43bafb42ce76e10e18b0882e0141faf76d36298f55b611f3d92c5b873a5712cac8dc4a12224af0e2c3b354aafc30aa1ceb9f3f22b4a852a64258619153a3806a8b2b0694c4603dadd2771d94642f488435d8cc19b5936d4bb414b27bf5b697140c97b7766217d1c5f1b18982ebc6e521c7d4e41578b12421d9922539b95311c2d133b8c2e590fc131b7978a301706f16771c5b54407bfbb856a9563b38233a04133bf86aaaf35de1293596832904515c272352a61825de77c3c868692496add23c063f759dd012620626458e80bea41833b6a517aad6b8b8b06d3c99cc95330396b9b18e499e28872c130b4dc1db64c0f67370f511a477cac47a4a54eb3836299e13f9185ed01e4f22666b27c6b9450bf9884a5c8bc92a71ab75123dfdd842561859de6b811554787c78609808200cdb8954f808af546d4971726b88b18ab80eb9a548abc63e9776a269d81a38a050c8bc9a6d7a5aabda849d2a582bb5af3684b3cc19c1deb26b0349c47f8460d7c21756e37980f90ce424889178770ff648b6702ff903a736422b3cc523be485164c8a5b53581695bc199fca3989931d4005741039499a02a78e977c7d3b8c572097e52137d0b7cdb90513bd990280493412679de2b06ab05b4acc8abe62b63820119ea61a0eec0842de8a11a3c226d3a41b848390b7217a7c190463765e42b6d8e00ad40a03d28e05094101029b3299e76c7f92580ed232ac462706f9c238b4b94ad76b773771b3d0a46b557c217988b27d88f02b2788c06acd6e45e11bb4a00eb59ca5c8e94571f24f63885d063d2a8be9a0abe03b695811192381541045c4333e31b10a92c61e495824aa9fe11122e26885b49af7c1806432c700650604423299809595a46394d5371321422571b8919069ac4b4038544458a5a0589bb087563183ecc7899474f1fa6c3e28aae1bf0496ce5923f70c806ca3b83f443b2d549e5e1b7c0411e3076a401fb7f7dc83aa920a446a61fe2046cc5da77de254f3eec496c8360dd678cc88911a17577e9312b6fe902cab10ec6241e34a062ca8a5e7b569a78a877fcc5b8e14c0a3f8446f08a25a8089da85c95bad6b29664259cc75cc40677752a03b113579ee23c10b9005481c934b1bebcd00017cc2ef497c6f4730f0d553c3391bc87e8c5eba340c1179cc456533dd4524652970d0611cf6b59afd87b98e435b085533ad2cfc00b8b483bc03d7c31d41b21207b20a5c65a7a568d1b561e842cb0028a28b356708f3a4276f24c536ab7d46690bed958f6dc268621ad9d2ab608f959e5096cac845094dc59bc83c94f1b3488bca98c2a7da38279cef934693c9b944b5cbf55ccf04a81be3708503b00fb9415fb7631f553c8b8cc1b9081012f0089dadcb67cd301c1505edd5b816ea03cbd4bccab34c3b7648ab855a1fb75737f300cb38b66e168b21af126e321628d813edd833e4d8cb9e5333123714fce0c0fc2d69fa5594bb1788c360783dee5c1a1fa29206b249cbc4bed25ce8bc11ed845b1bbc7637734ac6bd2938a4b3ddd96891ee180babc7ca9ec42e2232f2f3150639899a08048bab920dc421ff1b1799cf3a5e9843bf740c4289143f2985e4fc700dcd9ba6ee734a608bf8e441c7e7b8c7ae70b1ef0ae5106399aa0942b57401aa05b42d4611ee03912128efb31099f9b8961e5421fdaaed255bdc42800588663e3257a7708ac7bd329a7e167915947bba9ce01b1501fc49add73b398393cbe0c8787b3bc3c16cec2b08e0e9abed0261071d5bc9627a4b89bb05b25bfbb534fc3657501152352d28b8833b74283a7dc141b8e6395c272977577a5dd8a5deef7cf25fc9bc0b86cca0bcfac517dffda974499caa73c6b1197bf802a1170811a5004a849c213f7fbb1ca885294c16635e3467621b8f8373336069aad974c19f656f2ab227c9b9583771a7250a252ea18a9937f637b39f0f14de0c9c270e07f909783ca37b540365d2338c894257eb9a3226fd5a158927c11468872034aed076d77db5317fb5a69428b37d1bd38d25cd3e48f68131ab212681a7c23d2402ad0239558e26808310e9f90484a9aa80143bc932b556a29893211473fb05d0c56042dfac374078ffbf870001269ac7ba976e6171b77202a86aea2fb7f6874562a49be4d8ab4e2a77407025a53902582f965ca8bb0486b1031d72494f52f4ea24ad48611764860ff2a98666877dfe7b703e4b9bbc85e367b5cdb82cb7a661046e34f08a3aa18254abb1906be87ad4b42c17e469a45d26022e94f7b2b0f6d520afc5146930c851c85c554d6578ea05ff2267ee6c3c0e343cd9e131114a3a31ee4a636913d61fabf10d10012c246915c3a9f180d4d530e31746a5572b7bd7620338645bfebae1baa54fc5328baeb1bfcb255791c325f8a7ca4336d9ba8538c1c1a4878a0cb3aa3d0b09864a828c0f665f099727c18f0930188206efa2b0dcab2e55f40423cb574e459c518d0882b4c822da4ab351cd5a2a579a69fa541023cd760ea0c4650c92ba0fa4700b1d94e05c292d0379d7d0561f44665b60252a3fe45c495fdf1f0f88f7b3c93d00fcc553dfc +ciphertext = d99afaa2515ac2b1c31020172781059c9a49e2649e11f4572d568ffe89660925efc21f66c8f5146800c3990e6b64a6ecfc98f1906b7363efb5cbb2db46e3513afb5eda6056e1d82b97ff3a55d3df822965161314b0fe19b28265c8afb1e66623bab08d703df6fc3fda573f7e4c35f94cd5b1763ee7ef7bad5d7e08954a06f89324445417dac5a9460eb7cb45d1414a81d501d2a35b2ce4796b77a7d8f33984f220ea5b01c4d741ec51015bcaa6f298d5cddc134603bf5f86d37d3560fffb5016987d3dbd644dbf5b5dc339ad2bfdb44a0e36b70093fc4e68028b90d74e7f50492d185f9b0ba38f32acd3c14faecdecd33dceba67d9a620348127cef1385035e8663c9c6db3b0b3e29923f8d28a43e0f0b37daf4d412de5f3694e19fcccf28d59fd5f927ad6bf40dc94d387dbdd3735095e0986687deb7746f49f9ae0e46d2847c2995655513ccfe3782072fab5137bf1e8a5b43909289728a3a16ae4d0d70652bc10cdc50e1fd1b91d22d841f7f1b49d42da3b7f9f9ee560bd5a764a1afeef256d83f5af672585c2fda14f6008ebd7bfe6527579bad613b73a18ea2ef4bfffce6a3d4dc3c2a630d40798a306df441054ed964af5d3d7ae3b42fce77fa3320535f9da327ac8287c4ae8d701ff38c18674309f60a8107b697ac441cc284a92ddf2bdead7c12c3f14155d88a24680531cc0fc3b24adcac4dd25df83ec273f248188ca17b408639f1ceccbfe1c0e403b5a8620c65d4fad49986f183a981d3cf92e721a28217a536385bdc9c68d6d4f4931249e458fe2e16af94d0ff3daa02f4258079f001ba1525ede38cd171851ca0dc5ac72acf9cfd47c43e82fc95d8d69506b9afee4c9fbf91981859e7e42f74ca43d1284a033245ab28692f11986e8893d8c3acb104b31c6d73edddacf8f8436667d2538803465e4bd45ab789908925e063e19ba01990d2840ceedd074e6c56341cdb9a9ad079b2a87f83b66c2cbde98b6050db4eeb8bddabad8687473c64530dbdafee6d0e392c3eee80249087423515f3af26b2b1fa17e622b404542690975da73f6731278e01221f64dc528cc5c3166a9f1a0ac57ca84a96b626236553dfa6cf21bb6f48bdafe181b7e92cc76644e50eb6ada9d04b58500014bdf1820be8509c6e411a2580adaefccef622002081493f1c84cd4cbc2230d4b45836c79b54b40168195ddb4caed45b68e8edaf4cffc48d3e96d23483bd4bed7b885b35528e856fd48f57ecfcfaa0127fdd72fbde3ed1b7d59ae614ab76ca90d3947f8854003e3b88bf409adbc15d6bec5a24dbb6aaf84b2ea70da0b0293c05fe818171bf8997082d326e82722765640085289057adfb75254204f5424cad29d1a4d33e63562995a8b0811ae857490be384d981468e78b3e313107214a86955b598364c02e72e67c3f26f0b4a25fa8010637ac0e63f2ac18c6db1909765a60340452b78105dbfbd90aa3fb0d50a36d752a79bcbce82e1a156f027905b7c3781011fc8c8652e20f6d1174f8379e5ea7107a950d6e8c23d93b9d029e2e00afb37e42f9a38a1935be77229487d071c13255b08d671d536b3de9f6c4862c88fd7e920fad613bda8f206c12c7ef1dfaa92d938fd2eb10d353ae26645b2d5b79b9840e03eb57f78173bf2b8d2d8bae243c9f5a5d639b7d0f8600fda808c431a746bd59e383ff901a58ca0a99ac5c85a81f80e505015f19a9a3fa77d294bead9d4249cda5f7eacd0905488640b97d80f28f7137c66cd9de7b0b380895477b6cb979df0375c966cdb0392c5eeb4c1729a5c0a14199160e0f068b5342c7bc8f424dff8991170f674d4239c683de2f5c6cc34e7155c36b4014124a51921aa228cf2115595216490c66b6dc1802effe3d06baf33c935e439b6b612ee2300cb8ea1bd53c23473f92e75ce83923cc4b752981aa03ad1fdab472754104d8078b3a25f618a00949a238a8617df9667f6ebbbcfd2707508a1b2de1e7dd5a3835c144e1d0558d7fbe2bff4920d3eff4a1bce770b41bf41ed1dcc2876e1c68f14c8691c1beb47901a863bde1a0e430f8c261ead751774ef70e76daad9b106725a09772c6fa59706f904b8c227b8551a6544f7376510056dce4f0c6020e995000f684aa735c1859d7bfefbffba8a3b7041de1c37df06d81dcfcdb9717cd5cb6627a4751b9a1f3279f0593747a958548feb27a3609690a952a39872d822b56c572f4d0d9014118f3939e3df6533e4694d2292663bf80c69272c8be61f4b9c2d70de7f9 +expected_result = fail +expected_shared_secret = + +comment = Zero secret and error +private_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef29e29f750f394807ec879386317ee41abbe06c10bb51bfcabe2f194f9687c46d211536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 30a0fa10e8c0f94f9e11093a8416c0c21c8d76f192b2c5bb48149a874efa1dd6ae457ab33900dfa4e04b117396c5b8cfacda8d01bec1eb08e83c11280b885b8d883344df96cc32edd098b05d3ee2a30081fcea4cb7f6bfa4658a0f3cd3299be05ed2ffaa90d6791469d383bb2f07d61e25d5739de0652980a072fb5803c361d81413004161390926457e7384a6d7c37a7b0b6ee33fe95b6078b3bf085a1b080ca03ed6d7729750117d41880c8ef0e402bc15bd81b3cf4272cb84db3f48682968f683ef7bd5c07fa0f85b6787e83b9c6d9e665befc7d0843a0b911893c9699d99c36c8a95f1f61edfce6803eef39fb2d555503809289877a78ddd41b7f271b8d8ca6f01bb6a2262cc6b459488677c67fc2035c47fd20e33bdd9a81d279fb7f1ff9b5b8d3e000c02c68d590e637fbfc899c9fdc7a10fe7348e2bcf4f1f731ced7f5741175ea484c85f8304c37f1949980a0ec0101935f7ca9bbdbbb4fdbeed3a56238344419655dcd2dc0bf0a2abdd81fabfe56440f44c615992d1c1b9478334c199c40d4b62494be60d0d18a2cb1515060d884fd39e4856cc2c8b4030b46a00c33804d3d2d9b6408ab6a258d4ba55c52f9eb7c864f2511899d28b91fe9c1e328d867f404f7dc523c89ea66dbf934f2d231b63d5b4329a8f09a336554da77bd22c506823a69341af85a0561015c84cd1a52391ecbad57667a2a0a99cc7bd0e6a18dcaacab1b6c7f9173fc1b7bf247bd8e2564f74fa9d0e6a8a7cfcc5597e27d06962ef3f78d182e21a7eaf77c8f783f916b170ca79e3f1032f2ebfee0b9676806fb5ad881a6db806bfff8bb077bd1e0e988de526469e3ed6970254781bf0d3f1729958bf73f59da6b7ece2e7e3b7c3b558bb63825111422d7320086a34e459c9681bad81cc89db23a376bd620588eb381839a5f819dd826b13c060b48488cc857298b614dfe1e61b8684efc110fdaf72fe0c79d0d1d4de979a75a5f58a783fc074a1b0f3e5251cac2b0a798a31bf9b8e5c2f84ddcf2ba8a7d81878aae9c53ad2bdefa5cab9c2f1637ffb2299af62f382e4dc843c0e6c989c6a983d86675531e3b297ebc8254250f052addf07df3ea7a104bea20052cb7037e68b52bdf205cc8b77bb90c6fe671182fab394eb62bf39733db9fc1a18f307a788038d3a58a18e6661a74b4a2e55c24d42cb2824856138c1898630e059087837409612cfc8a7635a1e6c985506711c737ea7aeee42851c9edfce69500b34d15357b14867fcafd459e2de311b826d8c3819eff5ec2f16c6f6c59bfdbb4d9c63997c1e0b461170326cca23cda09f0c0f978ff75800ee67916d521b87ac96e09d8230a9df27626420d17842aac5e20aad404c07e1c1bb32f4fae720bda3ebb8652c5ac9259e9bde7b0430176ed477977116cdf18948d2e117be3a5bc996ea9738c4709b2ff9f625d34128801d696f6b5d0730ed935907b170d9b1d0099a4a221e7c488aa1b341a212a12bfb44f89f13fd33af275816b2c8a56b8a2ba19893efab7809efbe92453d339046e6cf08fd6104d8a487b385975eee673955e059bb997ebdad498bf4c2825355e5d4732e78d4d9288c247a5c4d2e53d5d1d6dcdfb19a82a610614abfaf61e982f9d17bc10221c3ea5033679407b7cfe22fcbbf9e1a7e8900b29b9cca73a8d3461586f78733dde42d12e9bf39d14735dd4c1382b3613c9bcb057feabaf0e90de42c9c16fe87c704c0b03cf324b4316653a9c1257affe86d5bba7f17d4973ac798e5a4ecbd6227b2da17f4eaa462faaaf6cf17adaa4b3564c0a012422480cf3bdac498dc9750a486ff54662135f72e23addecba2b49d85a254259dfbf2579a1be48a93a3a31045046936bdd268c2aa54cee82c4148ad281bccb8bf3677e3ede6dde20ffd2b61836fcd80e106c92d72a35b57d4ea17366f92743ac36b77339077882491a1288c8744a435cdcf21dce1eb4196e076b269d2652152500aa9bc2b1238e910400820801040002184000000010000400801840042080000100008018000020821041000002184104208000400420001800040002084004200008010420821001000002100004000200410400021040042082180100008010410400000801002080000000008008410000020040002080084104008000010020801001040000000104008210410020820040040000180100200008410400021800042000184 +expected_result = pass +expected_shared_secret = c5aa00b1b6e55e6aeecc23499baced296d8576f3674ba6a9da68bb14101194ce + +comment = Zero error +private_key = 76da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af6268b734e27627797582803cfe6006230901d074c72fd0755e011d676a8e69d41459c31fa5aa5de74814d0eccb67d6151dfab3d83927623242d78367f20249ee924c2b582d9d775a1cec0155a64f058aa6741867c7e491f6b53f1f8267832b7a6a8494dd249680a5b147579503425a55914580810673d507a2b0cf003cad1ca3809f6a06706ba72034ab8e79340d6232eef9815e761f6343a3bae63004c57bfe876b8d4a6a8b1550db541b359aa0f192a3fc2937078875ef55aaedc2115201c721db56b170239582cdb5c72ac4c7c94508210ab0bfbd1ac7cdf891fb370522ebb8a087709b3803069843dcd8bb4ce28663019cb470413e78097d933b44621b1f3a0930839807a13325900d0536a8f280225afaafd1d76c0e7aad8fa3af38884440d5b3a9f56922720d6854979b835c4ff69af290aa94d662fef6be4c46760b200333992f4df215425296f8d50876a94753024dd176991ea8a4b4256fa25a7ad7429303172bc7c06382316a61c0b2746252d2d7b1f501b2f9d6457e09955e29542a2b8a9b681139477ce641c0e766a4573c65fdd08b74038ac64021fa53ab9e2801743c9cf730b0609985059bc12ac92c61d86ee425b5811c6e4b144f0ba3599d7bcc83ccc4462c0aa17c7dc9d55598aca3a48b6ab4479eb4f4584796c64d2c74c360a34c901f08d00d4e4cc7e70c7b816bb0fbd323ce96416102580ae89095d4cb5ae93cd9b105d1065402a4a2681255d0821a21953ff851c23648a849ba27b267c0e70558d54146031482653116570a0fb6e7a63fd5b0ea9212a920c43467740642cfcb53130cb77a2a3bc678572235920191973075fcc1e769480895bc7cfa3c4c8068c3907c8da657e656bd8572a54f80847683639991952ad7b978e49d0022c17adb021030c54ed691e7b0b738c0b7078442651b979c46b0786b45ae446f73b56ce1b64042f5b27bc470efaa8ace21afff35487aeaa8d635bc607908e3f00236c74017dc0b515863ae690984f56c5156a70fe97f72e913ba74a7d04cae8b14364e2baea90695b5e36344107835ccc4335552f228c32e861f21357bb345663a1b9d70ac37ad9b4a937c304fd887048b8364744536a443540b7b5e572522a8c969b8a45068622982ad161c5ca1b69f9084657bcbc36025a82cd416beb15f037c045371617a81bc9bda545628804e4cb0b9ab7a6bc959ed6616465323f9b861521cb493da674c579b6799584af793459a2d1513345e67c06c1b268930c6d4dc0cc56c93e7f01bbafc589e178491f6206f9c89816622b8d5c19795c7c3404b54404629933fb6bcc03f99ad2155c332eb4181da3d07c35c048920f35a7bac1b465545018b899a5248b53f354cbbe01a004602dfac254efb3bb42130f55520921a712b20cd250bbb0d7949db4a05f5a64797417158241ca40c49dc83186cc236be4774e51856da828a5143588d32cf17c7a8d44aaa7be6aa96c794773b656a622609ac22b7b302dc88ce0d317c8a18877db8168621485edb278a0561d7abbbe33560b2eac30cb6b05f850418e1293d8566b5c370cadc2b80c10c9a84a47bc217bd645df4d627d9b28bc898701d87a07560918ba0a657589660972a7d636df533c58c02cdf960a6083c5a1452ab54673dffd2769dd8b95fc761b152181e2484be9c5e7412a994b81478a863e32489ad294cd7f60e2648a42f8890c740220cf4564725b290355cb86834b08182b54ccad880a4fe3617d0e04dd651334c00ab396c42829a45e149b3bf584f25e1aa674293e132a2a75b5e5ee4c6977a2b1df64220683326fa3a7b3888e42a51f712c944f9cd5aa6cd992c7f60b0858a638862b178080c5ccbe45ab9e07b35d37c34397cd2c6280226402784c04bb6c1d8492d5c021969108c13c7b2d1e605711a71256a3216557687f69a8ce38e8e3c74c12798e7547653418ac2b41133b3172a734d3c632930e2638750cab4d0883261598df19f1ebcb5c1baac516a4167f3c14e271d6348bc92ec1da704996bf9c53177855028335b834bd0340123a67632598afe146298177668c967fc4461ae3237a38a1be079a460a7a5d7d6cab0345ba945708d604b2a037198aa7209a9356270010cfb96f663b35601c92dfcb202d027e753a662e060ddd90360bbb38f4301111c509d624abc4752ae1898cc5732a518061c4ba4aba3ab5b9a66d9e8a679ca31136aa709e14cd35a129e693436990836c0648aeb5815e34a91e0ca3ad6838e859b2169b6e482492ed42bf2026b0508b733e437f1c6cdee0654c73b98b740474e2b9a19d08878855564893059904623711c42b62e34733e583424a9d25fec3b20b6345b28801d3db830cd503aabaa5120a040ab31513af89fbd0b8e11034abe120be9f99756bb26a9952615527ba4a1c0cc562cf565635fba5d2894b846b19907aca15e1979136c79b737821ed74839584de5b7493121c7cea71e6b744e42fa278690a6c9f434c0d51e28f5ad045c6d88969bc1e7b68b1b13a1d1a01e0a913e187eb861023a8268061692c7db71cc1272b63094e4c28163ac636fdb5a9422757744032b329e0891232a60cf1d5b71b2090bed7807a2d09ca1192541290ce65605e4197951e87c85ab3a41aa7e76d4b9e4d691c3d54aa27595a86a218b396fdd99642515bd4dc38dd7861b17e30eaac2c3e139381e2ba17056b7a7a07f7c9626f716c454e66c0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef224f69e9f571543a7fdc1819f44df00286533560a2d7c8e23d8d8c811bbe9f90d11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 8702ea652463d333c0695063d67f213d9e150f2e3aebe2d2bc992677e4492bb95fb116e17e8c5caf5067ce0c9c2d8c81369ec85fb7dcfb0ba32dc924a67eee3f92e13251bf1ffef5b1e3f98f25f7a8446a0305296e097e51bd157e97d476258ab146f7160413416a86f4b2a860971c1169d3b01a82201929cf2dd258c693e2becc839ceeb97c9b570e26a54cc1915ef8f17c47fa0b1d0b6bc9f25379514fd234425d02ef22cbc151fc2cbdf4549bef807afa1ec7e5caece5a8f4b62f2b388c210357c998e61fb205dc975c8fb5814345671bb8a614f911bd4de6eefb458a74d95093ca17549940c65101d62bfddfd4aae3c9a7adee294ad409ef778b1c25811cca3ece5928dfd6f3bd8a4da41a81b7973d5df2b1c25d0610ccd9b61e477785908d70b23a6ca9ec11a9c63ef6f52b624d66243925d2f5c2f90538540304bd3a11c76344c2aa90a12d8aedd1c6517732a15948fd3bb6a2e736b33bf68e816f19905b1a96156e2431da5525147d35d6b903708add85dd102658ab1972aa19cee456b7ba1c7847cd6b4f132068833a70cebc4b23a63771f4afe8f2aeb077572c76132033b2575c1dcfd12521d1249a5e38a8ad06979601f18e156518157a7c8e6526b957f657f8489e2224cfb73b2d1736837507fecddddac860a587122a98a08c137108e5fe9f9b2feef6b52e712e3493f66c98ea9cfa08aec95b27220f5b219689216b8e0aba6ee8a7e758730108652776d100680e800d6613aee85f831c3d92fea5123136d204f8983a7aaaca63d812234da3ff596ccd4970467f24217565b6069b6bebf58ed984a2f0476cde2319aaa792e46eb6b84f4c3c20ca27183f1e3e2be347b5d1250a666a81c5936b8d0f569db64aec4c2bb1099e6c5aa6b726a1617026c2c8eb5e72925d030759677863cae4f09018377636b69f2aad335200934ad4bd622fee2780b11bf1373000491724b37fe82d8d26a869bfb4d003dc0f85961dec623dbac4c55e7a9c439eb91ea01960d3103b7c0aa052e81acdaf1286620229f5a2973e8b0a72eb423cf068fac5c26190bc90afc16938eedbb5ddb3c9b5bdc8a595ac12f9c80dcb9abefda4268b8d74c7462104f105cf3437bd2cbd337dc5d71b552936e9df0e47eaed472f1162e2bb1b94ca19d449f7d1fcaf0e737a07075352aa6a45318981f9e67a6b23c2d03b3655147fb0d2b07462d64277b6cd11f4ffe969929a20774a885831ca24abddf752cc6133f8211edb3b5229218c9a61fb3683be29c7a2beab256efed36c6537614c77089ce44a6402a07c54cbcc105c4c1d7f35d2390ea2248fea06f472ed018548b1377738e62c081345659121a3948afd758c3fc764291c17f1274f6025c802f42ef00c6d692311c27035d7ed2ffd32d82671aa31429ba471b605993770e093a9ae706d523accf9684fb12a7b6e6da228e9e781a8c28f6cb6da9a6876f0e5dfe2fea4b6da856dc981ad8323dadb1768aee416471b87819d3685564ffb3bfb3ef1dc93289416b540f3a2f46f29bbdf9fe05155ed8d12adf5f85f372999b113d780e3034715f6e143c256cb2c50e86b044cb5449d09576e776520f8206ec7f9deeba0db6a4a131f0fc99e8bc794ed12e45bfdc9ad5e40a7f6825ce57f3f396f20afd968574b6ad34f3c150dd65ee11b7e0e396067e7d3931b493089ac078a812fdb2e6a56b04058a53d0c8fa9d0e6497cd89b0f35abaa09b3c8cfe7c89caa9325bac5440e971bc0ddaccc7390456b7ae38e51862522193e90d0d6452d19c2501edeb37567a0c6a9f9aa9b6dab2058bd08b3ed4f90e823ec4fc4c003e137004e0bda32bb843defc50ac4d0e6c21e1c8456963db80c3798319336723f4cad669696cc3ba07c98f986a9b7559bada4540b10fc50ea11d4eabb00baa323f4a8f4b93bed5561aa3dd36a0c8c9f56a684b65f08c7e725f60bab7f786b26921f9a638f7046fcd25ca266a4cdf774f29fd683d97750b7a9f551e99b04b3e6345f831cff027bae6919beab52eedcd93a2295f54cf4b14b010500d18493f99439a6f528212681d240adf2cc4556daf03ed57e19689f09f29a06b618fbe8428bbce371514c8b15cd9c34da0009fb854a8299b7d02f1c8b0350628c901427274f6e5c7f34c2097a56e0251eb14e5ea5d5ac0b12c778476d1eb4a85513387ecad05510f64bf10d1325a91f670ff6fed9c4a8421ac98c0d06 +expected_result = pass +expected_shared_secret = 4aff47d4682e6b414067b3020720ed442d0e2fb4a2b15c38df29723b8bab7b85 + +comment = Zero secret +private_key = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af6268b734e27627797582803cfe6006230901d074c72fd0755e011d676a8e69d41459c31fa5aa5de74814d0eccb67d6151dfab3d83927623242d78367f20249ee924c2b582d9d775a1cec0155a64f058aa6741867c7e491f6b53f1f8267832b7a6a8494dd249680a5b147579503425a55914580810673d507a2b0cf003cad1ca3809f6a06706ba72034ab8e79340d6232eef9815e761f6343a3bae63004c57bfe876b8d4a6a8b1550db541b359aa0f192a3fc2937078875ef55aaedc2115201c721db56b170239582cdb5c72ac4c7c94508210ab0bfbd1ac7cdf891fb370522ebb8a087709b3803069843dcd8bb4ce28663019cb470413e78097d933b44621b1f3a0930839807a13325900d0536a8f280225afaafd1d76c0e7aad8fa3af38884440d5b3a9f56922720d6854979b835c4ff69af290aa94d662fef6be4c46760b200333992f4df215425296f8d50876a94753024dd176991ea8a4b4256fa25a7ad7429303172bc7c06382316a61c0b2746252d2d7b1f501b2f9d6457e09955e29540a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2390505f8fe5464cda5ff3108cabeaf9343650b2c810ac7885a566a0e966dcc7911536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = f0e103c8bf553c2dd0a1043aa1c6eda544ac9ebefb081b1724be5cc4bf4167e8f59c53e11c2d2005310f3ac9e470759f8297971fbe8c08e7edcf5501164ded5e40e0cc9883ce1a8a574579cc7f675780e1f130ebfd2a83fc6fb276da2e6baaaa80b9b27cd19268ed6db19ed2e5f8467e831e5b19d6afd169ca9789c58b887214fe589a0fa5ecbcd88866dd2f574c39813b4bca5de8ee9577af32ca11bc6e17ca841d7c565a630c145855dc974b9584ca24c9979f46516440c2f5d35f148283cbd41db73bfddffb5a36420cb3c0d15e81f1d6e0c5e99b4693a7c83a51ecf91d7833cfea740e2e53f294c767bae0982a46532c35737fb5a23fcdd46d530b7b0cad6127a66ad052ee518006c6024bc2b2944d9b7536d47287dedf8a1bf6dfcd8373444a379fd1756d1189ea101e7c26f579b32525973eec803b074764b13d96d60f68a279e34c04f3e43bec799fb0fcd25da9eb14c4ae21d10a1dd7cea23b2ed5724f3ffa5d37766a34bb9d3aa8330a923a41925a7aaf071593ba163913aeba546c75d889750492ac376acf12e841cfc53f28a82a1ce65d29289a57218731c0b7ff814ce4ea7cdc087bab5cd2d57f0f1a45d9ad7096323edb3ef3558649f8aa2fe49a146244991f1d0cbf2c2e74e50038d6c47d80479e04f6cac03e667dad2c8865d6c8cef96cab4d3361e3def6e0b45a2dc81a4993e05177f2fcf013d992a943cb0b11b6a75861bfc8ad534065aa832915b254fddffa898c69c24514ee452ee1f7d8e052bcf3f6f598fa69db0ce6b3397994cd1f139e665d87ddc69ff6a4b7368ec4e5d026fbb16c44a62a33c2644a93128cb76397516dc88f664261bd09409b2d0187cb73e3744854ced4d6cb1099c56fb325dc93232ba353e421c3e318669f821df71c6d8bc68cacd45958442575b9960b0d903406c2d6c8577bb1a3ca8e24f47c7bcd2fd6a4ab83a3caa554c6695b286b115df21699a78269b25ad7013978daa30290d541f3060b01e9c3fa0d703322700227d84101c9d50dbddd00c92f57154ec9cff10a3dbfe6c2d4b5a0e0099dbc9b4883dbe2d1ad748fa6b5136d8759b9ed314d330a8822ecd74df76cb605087875150b205ecc1b73023bc185b8bb44c8c3c32d76948bde1249730aaa1f52e11754b2037d2cbad433c9beba44b6c8cf19b15e688360dd2cb7d9832926ae72b5533cda8ef08a0f92c5c1c5c287caa02b79eeb8073492e46cc4183fa2d4623a36e0a968ccc6ac29ee9ee3582182c261c7c0960f163b290f2ef893da422ad03fcf3926942570c186e7a90bba86ff792472911cb04bf72a8067190d4d87331d52d4505618c60de95142db27f784c012e209addd58bbcda062c590296be66722e175ac6536c58bd10a68b6d75513c78853d4d1f796bf477cf380c7f533f741460c9c5c2d1ad851db4b761b9c5eab3fd9d291e7921039150f8d2b81f86f1f997214660ef4cc63eca4b6c76bb5742fa9920d6e2db3480ae82380fcfb8caf51abe21094736f58cd7e6706b5d10c4b33f021bce59d288bb41faace2411a0ac5c766fc7d87c5d6a4f0cf2fe16cce09dc7ddf8d968366ac293ddbe9c0c709a4c0b28eaf2e23b4212c1191112fb9a316aea3334ff9f4645245420006c406724cd7f254a46097daf669c2b137560a25432030a6c7d6f4732594f21a277b610b870222b4ff561a6401f10b35cc5045020cad9479bb449322d37df22c9522c8b7c5c0c4897b1175f0dd40038a477c46e10f10f4289a81477a07b8ea223007e25f5b871d246e585083240c56c3d80d4425ff7821f17acc96121ca9ca50b95ea46ef8116734d015ce88021c620b57fe83b5022ebd980856d5102e4e80d7b176bb79209809cc32a7d246df9df5b0375bac96547962c413f516f4f0c24c8921d148f0a168ed5e0434b72538b9e5cdbc00b7e7984c243872fe44baba62b917a3f0601b81cb1e6cd89de2f38d0fafc2eade0b00a573d59d290586f1040082080104000218c000000010000400801840042080000100008c18700020821041000002184104208c003004600018020400020840042100080304208210011000021f8004000200410400021041fc207618010000801041040004080f0010800f8000008c083300000200ce001080084104008000030020801f80f40000000104008210410020820040044000180100200008410400061880042004184 +expected_result = pass +expected_shared_secret = 71a637ef1645d00719e56ef39217bb4d8b2cbc71db826affc2529589830148cb + +comment = Random ciphertext +private_key = 3e52918647ce7b53adc5493a377943e758a00697bd0b831ccce27f0148c3dcf18878705db008cd1e637929d3ce7499592d0190662131843c155ca52ecd145c69d21e42b6a07b0830af558a32cb23b37c20b6d25d91464828f84425289459696ef84401ed0561f6a38b9f58554fc072ba9b78e9769620aa43a6d6200ac1769daa6432f89aff793388f1179b3a36e2c397d98a9ae1778ae5c41d5a88cb299bab1bd5aacad4a9f0a68aaa8c7cc227c4c99a7a08c9cc0ccab4a0cb66ee8432fda46ee16aa6ee051b11021c04e870cc80c6a7dbb2c33260e98c007d80bfcfe93ef8344c14d49c6ff872fd8b828b7ba1eca73628b6260ecc4af1e440ec073c340c0140c4bc07f05376a25fd40171ed621d1e2137a3b8c995e1921b14331bc269f835b3f5a81d4c25cc1a47c0d2225f3cfa8cf082855176634e22bbd04a9c05924c01d6bc223200c2b8ce85fa4fc3381966c14840680d0137adae5340e5221358b235d162a3b65a3a27529af9815ca6502c2779b09606a8926602893b6fe2dc34254911a5e46b0aa8069ef122934cbdc3f4b03150854c362f0f6c4ec3451c53c57a93d39b1d18c5a80bb7b7840ad951adc7962911836b65e4717d824d7c66a6d6c27575f83e50b91a25864ecf7133293bbfa3e5cf635c1babe7b70e0048c23a6a93e4a75e162e86649b0b1b0fff680d34d4cbe191b200c766cf0b936ef59ba9328dbe445a2838c2d3c68e4d32b74e5754f5b785412cabf1e1c121cabbe23925289a155d858e026916e80019415c69f36c0ad5fc914fc4bf26079113da984c664f7f379fcae92cfe7903d66695607c016eec95fe28aae5f72d483a464399bbb39a2a8ec3cf6a4a449c179759b126c352bb503709017777f7cabac4ac6d15eba9411c5cafe202f85379556b70c368878079a5dae88ce10228418902dc4b43759b650af7165dd69a2b440ff789741b7cc6ecdc2740b497a88502daa7a661316bc0fba5e90bb90bc9cebd0bc4d7a3653696040cbc1bdf3c46a5c9046cd512fa5694085b2a874cb613a97d1f654441564a5f8382b6751fb457793f429ac09a30c3a6bc89007c65d6a189a77ca0a820f6b773f51093ff94bcbd4cadbf79a487d76b62f81316484b5c005bdc84133eac7cd12a418500545a95505f912dd0082921670a134326cf2b69fb68aedd45602fb77cce8b177326239b60bb94f741a232b52cb219e7822016e70ad3bc102b86b95e0c51c8424346a85e66fc6f200573c73ac4ab287de53027e0a544dc127705492d42974b0080c551f37d1efb0cdc076b0d0b9a55dc33ceb4b798988e7544c44fb98bb23aa25bfa6783e55ad7304b9e222c997576d5f27872e00ba9097ba1a99750f00ab791b638c32028e655f9167bbeccb72eda40b0b648c5981ab2479cf3c6cdbd7034f2f0cc78a86e05c2c1b2baae9d102dc8c57ed11a8efa884028647c380c8eca1a45ceac7365db470b8a8375b7274bd727bafcced80a8ffad1745ef76cf9b898e9690b2fd477a7100673937f09325312598ccfdb5073e8768203a61790c0e0476dc7ac6131271776538839d62fa3b8b081278277bb23ab6a3e1eca841a6830bd48b77e324618ba6eae2544ac245cd1c5ab3ddc0edb1168cfe33afc33378d6978b11ab8696ba29dbc2ba3ebbb71c38bf058318674ae5fc227f42957f6940b0a047ec580b9abe756446bb4d788197e56965bf31628024508891c19a52f08f466c2a57da86267fbfa0c9149a623923d7bd254d9d91baf4bbb37a87cc1139fd13a1ac9c2c3fc2506d7b7bf56f9b1b49542e929cfd41b0f3be796595c8baefa8674492723f91c616329d8427b7882065b7b648b2c5e875245a9e8b99b238b86c40e93081eef2a8a27d2900af24657a09e0b2ab907910ccc8416f989ca9960973d1c61f556285812859b2aa4e0fc3afc3c3ebc4c93635374f6db20324a9fa680c2bd2697fe8687a960c5d0883018d621b01361c1171936a07519a585170200859348664a59af2b4dd28083053255c58b0337d801dba1108b5c7972c71a790acfc545c303784a13568fbd8725db688b8ed2c8ec222ac8705a2d4876be587564203c18b905cb2183f0fcc8e7e7a4fb2cbeb76a66651c59d096102a2585a6e929c241b969975ac17822cf2406a8ecb64a921db933ce9aba6bf2e28a88877e14c0a3a762906dd4975a403d1a82b73d3864ae20733d687f0a308248039ca1485c2e97710e2241e3b011ffc207626945db965f7b9700697b10161743ad7c5bd9755780f422eef8106e05317542c08fa0b98e90c8eaf912b8f58ed60acbb173bed2b61e309161d0b9b6d1f32d66c1157675866c405ff1d5a684f1a82c1ab5a9ab1728c8007c546bc9c6cf3549044f72977586af01b392da3b59e6d3c841fbcdf6c1626018b3fd58597859ba88028c8256c5e3e330cfe529b242537cf2bbcac0c5cce659184160523b570aa7bdad24b0165678bdba71f1567675cc22b206c802c7a27336a966f7c483a9161d642d2c53874896052599360d90c91afa81b59cae6e3cc017aa6a1bca4cd7a6174598cbe6025eaf32303c69b5ae446ea1736e39b2230081cfe1007a221986184307731c6050d2ba4df6b4f1a19928b0b5dfc84a6511b7b340152ec92a053729cc4b1a7619a5bf664059c02936e6a781b3196c96008d98c69b077b271632ee111680b8ba39c778b50aac70431c7c6112f61697765cb1b61355f1921d34b010fb442a6a86532a0c8bbb725a4c3a86cfb4cdc7054e8e64ae5b603a078c17092a776d59cf051084560329dc93b6562b736657c050347a3604c06aab8562163031177079db161188cae456035eb2377ddc333a5965f161015fcc113c639dc85c8b5c57b4e64934ddc17c7969429f66af0cc2a001eb028c243e317822e5c90bd5e17c69b41111d6893f8cb2d7b4243b40017b0c592062800b95a677403ca5e3c65332ad716619758801d41a3b23769ade1b1076e133be56b1f5759db7128271da869a2c6783b5170304b9218a17d644685d38294f509f21ca79ede4192f1b3951a594a8039e08873ad59018fa217d1d429b072952bb3127c879a1dcdc11d7627ccc3b7a3cb35063f067584aaee2558dea1a00fe852bd3c90799bcb0b16906c7600a8fbac9a7e1946b18c41654481299b9f8a47920931627ccb89ba0b3adc117de5344cac347d0181fb5d580a0e738604261916a247f63bdbe2993f87481ea69a9b4154deddc8c28db5407756f4d054d1964963a34834953670e18b6c98613fa2a13211314014a719df0a9c07a0274e51a50f61efaa5c8920800fec28577fa3d1b3a6bfb4046d52163b8f0584952cb8b4b07041b144bd0cdb5c2a96f0a7369543fe5f49e2a007c270b360b653c39041d714b202bb6b49ca18d83001712d5c23e435d642273d5395c76c5a1f4f63c2793b5df23bf220313a431941ce91c7ed717600124f365553661c0f7b67b85627eb5c55d94605ed61c51dac3bbdb5c92f9975546e5add95428e5a5ad20a3c8f9d48302a55e8f2c0de2d68209e75d89f1b0c1b202f26766900873a51568d69900b7063a04e555579b6fc1bb42922c6bb72c5089e2b16736cd3d440e55288e36069db73b81f67c69876960b41aad55cc6bdb3bcd6be39e47f93e0b8215d1843a56a683c37aa7b820b1aa34920f632b179205b6a60fd7b0782e0c38b9e7c940eb82e3d0671e810a2c2788a6ca8b34e5206044ce522829d9260030a5a53a5161c00cb8181c6bd50b6398e839bd655e1bc56818a707eeb72a4fc133ea95598e747a46452ce5828a65b751fe8a0ece6a5f8b6a4538cc2954bb51a5c0b33580be7b5ac449508434748a0ba7c3b7e4ccbd48c59dfc18b6a3c7e4133a1c377d1f82337941b2050ab164c26cfbdc7f547cc517d98625809021bb3d70a6229c8cb0c1246ab53744b7a8ba881977a2a67610397a628cc4b5c01c68ea112059aaec460c785726197992e3c5b69eca7abc19376e40c55e6a3bd1d91f96a379c16b746c102038113ac0458beaeb48998006b0c1ba53d8573cb56a4fba3dd3bc1efab48ae6c527d4523a1e233dcae1c14952332cb96884734180ac6d9fbc1d31bac6cf727e7a4c8f1d885f0cea139fa031ffc8af40d7302973a3cc52bfd4f4651140776dbb50b1f646ea601527f50a38036fb08677d3e84339359092fb8ca668c820626456533a6eb7460117a099209f0d1c2739c446063a04c2ac7f2f3858632924ac8610ef126648319fdfeba0841a36b5dab3d4864d3cbb8072d2b8f948149c8c5517f7ae0feb6b27b226f0383d7b048133080bc0414c55d024b16ac7ccf5398cea01d2048bfb75ab947339f198b5d88acb6be68e169082c5ae2c39845bf15231d98cef36f30a113f0e781e14ab3ff69d699e411bf40f8430cecfd01e3bae23c74a004cacf8a46e6705f27e1674047e7e7a1649482e1d9b0de92455cd14d0049bdcb7cea4b867ace5c8922b +ciphertext = 542acf1e3c7dd990f1879ef5b5aebd32055618c4e5b958995f0b22a78f9e2bdd8dd0cda23893c56f48a20d4df878e1cdbd39f50310f2ac0cd502e761329da00d49e7b8721f53af649ef7edfe74f259ffefd492f13b1ac396eb65916e02b3348560ca426e9b93beccad58bcf0c5804f0a10532635fcb74e45c1f8eaa83d56e78d8a7ee5aadcb7e06eddef900b484632bf1bdb0e1a4ef8b6fe34789934d9baa887ec5a39dbc6416f66008751aa193a9c313ef8a57a515bfe046953fa6a1329a770e9e1bfdc33f3a68dbd5cec1c2a55a0e41093583230ac35386645e6dcd166f25706efc779fec0cc4299e8e7501b93a857378713475782cb0b31ab645940f4c875548345ca0138372719c3cf9022034f17c28bb90f6090d4b8be957ec63c297a0ba95dc02f8761c18e7a948c1c20158230e2f9ff809cfd01b9d020b7164f8a3c54a143594d7d35b8e1ad6cb25d96c11c1b7f47f62a8d90c0e2b3d1460b86a463579e7b44ff74b6a29f30521588a26887797c60d86235e0bf4c2bc7166bbeb275996e1f50cfc36641710a52fe08fb5dda30f6129d3a304e336ff0d8698515b2cc450cffb45cceea7ef51a989d036c71367a4d26cd6025479d2f7ae58e700928e176c59b3040b054a09312d9fe529ce784a71513b44c1cd4073209a93a4df73b7097da88cea0b31c3e77e70abcb4b2ba5edd8db8f47ce844750158ddc5609dde43eac393eb5909d9415ee4698d923d8ebc28612f8b0676565010360b9406091ddc881fb6a992b70645b6898d13a8e3e449be589cf17bf9312e5cc58b03d3c181f7f176b67bea210337d6c52913f8cfe145da9426434c1fad0da7911bdb35e68b86b5bc6717dccee9222c4842c28fb13115278f1249b213498791082bab15d32f59481b29b9512945602eeba8af490af99fbb841bd1aead2b4f6f57f19dc970e83bd3928ea2d33ca3c3e50cd5d68e6ef516371cbaecb6b73f57fd5ae5b38a74f20759dcf217066081fee51f0fe8a93aabeab4717f05395e304e86bedbe11d462c1cb9d4e32e75b35fb707e7b509e43b450d6025b2d3e84e00f3d92b717578e820a33788013b2bda42f2701a9c6044ac2082e0387e141bc97a60bac45e0c1f4787bb5b892cb190e4b6776f5139082850494bc5ac56a6f759a0505ed4757009c35a4d36bad276185f1fc75399043168b22cc668a4b1202e03407b9fbb6a0799ba6a396ea78e137f7c68996f18f1636037179c4b920ef68526fc9008aecbfc0a2b02432e2b15832b35a61f438e06ce977c4d447612c13eebd0549edf316f64f5e7f3ccb0b46d19b79d103c1ab8f1551b6b3d22ab75a85660af2a9eab9c734875fef1d526da819829b66d65c8459a1aa404ec83842aa97a595e0271630644ade4df047f06778fe1bd1466bd413279940f15b9b848fae294bf4964286629682abed221e1ede635f315273854d57f68872bd9cb503545ef7b949b36df853eb7a4f47805406555d361aeeec6b77a0b6030b5a124f34cc121a927740aeaa6a381083f4e645b0d460220a8a5961be7ef69f60d3ed3c49c3348db4924373a706d7f16a4a4c16b0e3f4cdce663d224c20cce901801c4b29f9f9ada5ea9e5facb5e9cc0621b297f94d3cc828b33c530656cdf66ba0ed27a4988eb019065c508991bfdd8af7678449353506c0202b288d4f6d5693ef3f8447e7724c9b31f7e50f54c2f0933c5d4d6b4691010f285bf58b5a6b254f2dd12936f0aa6789351c7e61f046fcff0770df8cbbf0cfe6565700bf1dfd4d7ad1dee9368e2756c6e0f7de2d0ecb0d986b2b7631ababf3c6ae3e6f4c891cdff84f7f9aab7f3ea7ddececa4608e2574904fee752f4eebe442940a688efe390dd97e576349569f83d02d4627dfc23d65a8e4b9cb6bb66070e0fdf1ced446bf9cff064f1b113bbda51c62f278226254d15f44005fa271fb9fe3613f640253206279ebff909986aec32af0bc00663e10fda8b419f766eca892763bd3c4cc349369ee97dfedf76845fdc3ef7a884531edf2cd0ac840423688feb8a0519343266c2168b3c93c17e754dc4afb47dba4ef6f31ebdabe58b10168b0857f9899f48f61b08e809809014ebad6c1336e671b9abd3c8317942589ff517c3460cf81d4f103e111c15d09b878263ab2d4b4810898d3a654123fa96b1c694ba7b212712709c9173aa34ad098f9f3dd1c075af8d47c72952bfac2a196c +expected_result = pass +expected_shared_secret = 66e9331f3ed7e258aea053740f4b38f7bb53eb1221eafc8c59f5216491aeff93 + +comment = Random ciphertext +private_key = 9de97c03283f8a274066889bc1e245ec824d4d50043b1b5de2fc8979c133e2088c261146f3c45d989cb5813b6e3cd29e6c052d3fe63fd765cf1d875e5a5878358466902817963702d890ad28c04602d634ac2450168ab9fc4cb81538af680a706f7a5857eb90f4bb9c35061cde7c65041a9449d51d10973d50a15569a30c6f430fb078c8f15923eb2456f8145759418e06fbbf563bb54d9c0c8e12652a477ea13c6ad71a6cf7037b5589b9b30157dec15b0cfc1b3df712ad5a3f868bc4a3aca15353c900a76b1045505174a0842a380667c88ea920828b95cc850a3342111a3769b0bcb0ed429278e801ebc0566cfcaba8b26831843bb76130cba7b81d583569651b90364f427b728d1805825a5343a011c823780075775237a329222704e791d5eca376802595655210074bde295516a50ba1a968ee010c65d4002d4771cbf3be3fd48d829452b390a36d1b4bd2a177bc065cc882b398f795ba2c57f2b97f16f748900b2ca6f1541f487bb35707fc708139f462d89914ff48c82c49957e235be75b3ee6a77b0dc7ac09908abf896e06a70aa700c84b67ac53a168b8ca9b539c3430e390fa04282059cb7bd0627037233d68012cf70698a521686b07dc2bbe3c90b33841733c8975eb6592870b73af3b787c06bb83545d7f63284512b341b55a46122e3189a39e52bcfd1308cb486beaebc85ef724de0725e3c29633355a6a545fc1b32fa4bb2909bb74684243f3b60aed037b1c896e02459afe21649f8597dd661fc8f099c2b10fa451bb6f2bca6e20ae379414565c213908a91f8633b8ea47f95a27328ace766acfc7cb496ec284183043336736bd725f7a86c079da0e4f259ecad3b8eb35163153558f614dba9a4cb82848237342e02389309926ef693d91bc8e3b7147f8606b267128866c840d481405f2688d64bca7b272beb7c294bb94edd5a8072637d1259300b15f84399e2694c7b47435c782098f47ae78a245660082de8050bbb3b14598194e2a6e2fb52e0c414ab9ab27f76ccef0e52fa4339f2539bf9eba7f3ce467094c147bca854a792876a6c3d3a3261a93a2631a8c38d9caa0977666075743636e804076b463bce751cdb0454442e48021e32d1df23707f27a534ac249e766e41534b616b18e34596a6a9685d73b53dc9d1258913b96799877ac53fa3c8fa261b76b12135a7126ebcf2a66b79220b508f3c5aaaca73a9902f554b200835b4f60bb22a8051478a5084512194770c09a332cc1c3a9ea00d97a7a3fc120e3705e53107259bb808d95a8dfa2c2783cb04345119e46b00c4a81c8282b12bbb20c70ad10341deb4224c583c1eb008ddb349cf16c88ddf2061b081fc1f42330fcc39cd610225b56fff737f0542861aabc9be32343830d59c207cdd09fd2c31730a51eaab3342094602f9b2b293048062956436910294473c368c27884c63d355061887acf619922115a12117e90ea276d5ab0ad2c80b3b7a5dcd371e3aa700ec92e2df51328d84b20575f88e28c3fc4c57090a62527813e498ad364ba5331170e3563dff93bbb80542ef97dfb514627c5182df48e11d2b27d97c7d99813e3e1628fcb7284768ee852303a94234057657fc1a91482a901c7cd72b9a2751c0c4d9a9b35197e869a10fc1a926a62220eecafe54a2e0a4bc1fd3259ca04733e12949ba66fbc99afc2d4521e604fa272668c420b38b8486f2cbdfb6cbcc26982f48b000fb75d482003a65c3382d853d115a97486b5adc84009969ef64c2404137763450fcab592dcbabe86e66c59d89d18f6171c4244d50315b79b3bd72700f939761a8c46e3dca4271cc9c6960ecf1ab8ad88405ec2223d89cc897945ba79898b3247631b18a836c4998a90ef93204819430c5486051109663c6c753c27c890890b9ca89c1a83f6f92a07db45ff44aab3c299f7d229f5b2a5dc4c973f710f3ce153b2066e60bc6ac2f3423a3161c1398004e221f52020856286b3d98566e58a9ca93b14218e79e3977cf65e213685373952ef73a29c3a7b8e1453f3e869d4a5acb69c0e6a49177fd40e913cc0685c4f10724cbd23a483b4063d520bef0041c14a5d88eb03eed36fe47059e27bc7e2e26dcb4177533994d3937abce2bbb61a8b5796c757603f6ae1a6701101b8fc915c1b6a15ca40a5570fa2c933afc2299eb83c94181216d6480c1c7de3812c911a857328728ac562cf09ccfe16b54e1a8a32b2b74ea814222452a1e9ba1ce39508969004d672b24b33e0b4affe6b15cb1a8b9ccb0729450185645bb6e47db63866ece406b54071c942643646c55713abffebac41b972db61be66a845a19bb605fbc3e169910dfbb640b70c0ab1804e19ac8b311bdf8c6e376745b356a10cec397eb4928baabb74bb17db46c8e36996954b41b942bfc81331b7584f19d5a6493105fc346836415b59a02ebd1c442814ad9ca1cf145063bf94c988492091224c86815933e476afc41f144175999970df779053431322fb9101e42ee6a4cf4a71916fd80276052ea4e5263a2c56a6ba96a8440621d36166ccb95b49351844bda154706c2cb52e79bf0cc64b9b7124dcccc53444b84c32547e03bccc490b571759222a523a3a34404372460480459b4c9438b80d9a9af98646a91a9f614016cff6cbee8a8810ec218a5034b2490432303743b7b2e94320eec8c814d875476ba586111d4b459a64fb2f6c72bba8f7267b273a166abee6d84b95b2a36aec401fab63d90bc787b8bc8c0376de363552e4c87951ba8b701d775341f9b63ae5704991506d45f030c6c0889e4c239400761f184f14f7a945579dc7e1a53ef8037e43582c7b8ad7f873edb525771b5610982cabe024013580bc602e91f25c82527b1023b9246638eac82f33d7223424054b9a205e8bb057e15ee7b4b718316cccf45f89a4c64a1c656e00aa8522b74b63115671aaaf105518456b115258fff0c8c760678b0a79eb38a984ecadb0f10c9235445e343ffb5152fec8400a70aff3a462564196a1a179eba5c58e9164913ca208cb8805d87fcbb7bab7c45265f8aba1a6618e67aa8ac00ab68031c8b1376af3b112f44406732f5e4955f19866d591a089f61ad5abbbccc036493aa45bb90569ab5ccad60c812946304b68b511a96e2b559c23835ce8299d4b94d8294be2455f25368f5dbc267e720ebfa8b4e11a9e2f7a053679ace67b46549a10c8ccc2fbd66c552a1bf77caa4dbc95de69c902e9c8b938c4fc3a2bef4b0c14747fd98b7d1909a39f5310911c54c54627a237506d370decd4a0daf29a1247439d427c28e717e0c5be5a6709ced629214c03291b0502f8afd4ac55e13b2cbe5b70cb8ccaff69157736a1c0922a99cc0fb20383215aa9ebc2bf516b1bb95017d4a08d32671efc4cc4a1305cb9056050e6bd74986decab8a6c1357700641a0d397f65c14b6178fa6fb13409a9bde1b7ec9bc5afb5c53e47c975122a9efa16d83e422e692693f784871a369dee33d31ea5a74c097d3b1932a7834fd2c0e8a781cec624915831893eacc9c023009c8976bb13d07328aa34bae58330258cbb5b28992851b2974b179d8966e2a584d559975c4d55799cc5b2f39682f92025c6609062558b26456cb565fdcf2c09f2b30566b3788667b29d870fdcca598487cfb141cc8d93430c58ee0e768e8a534305028ae2a314aaa27aa368fdfe5bd9d427828ccb5849b4a0ab6ac446a3328189f87c3166c74bc19fc4642c76fabb354f5c0bf172097b051b16705c497b01fd7fc8692aa83955173ac874afb811ecd817821894b71f82cf0ac3ada4136692126a2f696d230ced3299b5dc539176155d2956d92f68032e660e3d4458de04866f484ee6b0d090a9cbf20bc7fc3537debb2a3c35f67724fcd38a4170a4ff2786080d14c1632370f983caa77719d9c5b2c88649302a2db2332bf426c0bcb617e21304c70617643cdcceab4ffd42875b003d3c1a3b2403afad52c58808b3830bffcc7779b586356804019cc407cf9ae150c09d1ea0c0826c0e7a5c568d64f478b1584f673e1db5ea5f4bca6772a6d94bcaa7773e30199a410826e51b595e81ab5279d9b4578be6469dd0baf84b800323415e4e6605e522018c28cf1b80747664fc5a098053a4f47cbadd2424fd6905ed766adfe519c58b52dbaf686300c5d3e038c32d9a23abc9b9610c8a04c2e46868abc1c4a1a009765d5ae8467291b1a713fb4724002a12c779fe0a7a78f6a294ba09139124873a07f4cd1a40791c5e6708bb540a1e0629ef2b07014745745299944e74f91e66a8e117037197f56c0ab3c8a5864ba2f748c2800dda0b763a537166dd25a6834933c25d650ab6168667060d86b5782f9e16af2cc00799e4cf3faa67c6a9f2c819144d80e48d9fea4a5ed442366f10fe41df877cac7bf3dd35e71ef935e09cd2ee6d890a159cfdeb1878b62e04a97f05d03bad55a85a8927878585d61357b744c4f64f21440f301a8d449a30d5a18 +ciphertext = de374fc747d2eea9c6b5760d2c4c8949a641279c50f1bb01673742a582ef761ad6f527948a32e77a10f731adad289e30a81106c0fd4bef81217c4cbfde4bfd43889c016b13d4fc3c20472261b635a40a77b9507e19598a1846544580cf9e25845378cc5148395cb564a4ddd5270233fd3a8f11c788715fced0ac06ee790c68b89f3ee8efddef02f2c880ebd2f94039a94d25a4642103cc94ca522ddb443ee589f7967d2cd52dd5546723356b74f8ddc270291b5619f15a2fe2502e099927c935fb44cbfa2960d035cd809abd70dcc136de631c812a65d0f7fb9652f9c72c0ae61d45b894d04d56a668f828d4fe223e62761eff354811e3c24ce8d88cf466a8e0a1743c8fd8f4f4b9ce2130a41db05e0fc62b68bba453a1fe846bf90e45babd053aaf6d0548b2a97534c1eae8611bc3b15e1cf6edf719adc5e9cad4ed50fa9a9ceefe7b1ae9b7e562eeba6c1d82e9d80128d2dab6d18d037edb13e185d74b9180761d881fc21030546fd2a189ab857c55a2fe3afc768ea009894a5319075465c679685fa926e24e5ed8e35db073c43ad636f8d039c6441d48b6f7bc31ada9b2955b4f5d64ca819c2e9d5026e235f9efb3e32a98fe0d8dbff1150661148d72dbcb8693b381df3ff6677cecbfe0e6d1c18d415b1822fcd1887ebe0f24f04c07d5e35d36e18b840da79cafa3e48c7043ce3f20610d0602a009b7fc4ecd1b43b72cfee6ffabddf251c6db036ea72a15663867ba9c465ba864e7e52e4905c69665ce12dd54da53a07f2c779c1fe306a453d3ff3cd428623d16b2d4349dad5b325135a42f5ddfd6112aafee724e9bdba9dbfc2cfec3ab08c45593e65f9d33742b980852cc063484afb3f5209ef8ad7a441b51d35fafccf3d15e9ae77f0a3019c742412063985b1725774106d6b47ab1b176cf7f029f7435c1dbd7c1beb53c3fa7d028f3ece13d86584b03a680b81538513cfe206c6fb42bb2f73dc0491f85455aea06478ef49ecdcf7177960f31ca5bfa9ad56a0d6d7005fca9c477868b90969c2aa02d1ed92eee16ed7ec38dbd0264028a66859f6a6a7826cb879ce653c3397a1ddb4c7cc985c11f6b9c8bc842e4fe424b3d32e638a218b17d7c6eea35bf8ef40d6a81f4023d9437b1724ac25591eebaf8a54811a70d4424c9e44b88a30c27f8338399666c381165ca715e965f87bc764f98d897beec42d2df9f72bd118de555a9dc18593687ee79127f0748601bba7638289b9bd5e74e5e217dba7181a78f6a6bf2536a867e3976b5e12bb3917631655fbc268b2693cd2e8c556a1f94e4799331eec89e46cf17f1fef00f49a67af9114cc3a55347dbb522d9d5e0498437561511e2ab533ddf58adbcaf94c48e5135652d2ef9071666e415d57449c2ddd4bc228579b3ba07453ebf80e4a74ee867b8e1c5f15e88880b830d62218abfa4571d0caad89cf0a609663c1eeb433d71692d7aaf370b83c4a9b99782382cc0ee86b03fd1962f79d1058e9cbcb99a3fab011e40ad4315d1d221ed8b1aff92d0c01291c56d00ff1266d50abeb188c47cd405dfe4a8d01e72b5f4f4ce31afc7685225457e9927ccd8e152869ee0eee5fdb10ff7d5265246ff6feb543210a880812dc3bcb80b7d26457b0250d4fbb341539b8f1fb97c38a0ffaa3ac3cc9fe2fe4d7c62ba2a09593734ee849dda1a0fdf61431c52f1d611fea3f6089057b2b0f6c8fc792ef8caafe567d12107dcfee6ad6b0b67c9117d6a5ded0b7bb7dda5b0e6ca13b7e7176e04782496833689e72112c2870939e5972fc1df47d7e3eff50228a2bd753037308f6db0101bc08f18f531de2313abdcdad635fa1f773cf1948cfd9ce01218ddc876451c350c391efcc8b4d42b3897207d49c6d101977166ba7f75f3ce2879bb31e0f5dd7990d7878bd13d8d791151dc3934ed3d93924a02c6cea0a045d270eef832206917c920439551dc94224208ad6570fb09ab27c5cd862f954437f223c8ad3aa3924e7159e267f7793d84fe3f5b5d5309d6d5cf74a82d40424ed2dc318c6868470798f75d9d60d48cc7716f1bf7c3d3fccd637b4284fefa787e3d894278576132dd6eebfd103090471fc89e5a8a0b368a7238484ed9da1aee5b16d33ca19b8285a2c6ee50581345f4067f6419e56cf97c0d00088333adab0601f2b11e2f8e09acb37f17c85bbeaa0582ba586cec37e961f9424f699f55355ec300a363706bf59b +expected_result = pass +expected_shared_secret = 8f9adf2155235711d47199027291eb4cb2b2cfebb1970d0d436a2378b85486f2 + +comment = Random ciphertext +private_key = de1c56a2eb8efb35095bd79d98c9b8ef070c61767621d896ac438a6bd6109e296f6bf14547c270a64611f39010967834d32786f4a560c14057c20cc8e3a333c6e22cb3e61df50b489ae0b97e7118d91b1d7d224f1c3b1b99812bef537ebfdc4ca21bc1eeb280c9c0b63875b26406af5d84401ccc21c010937b062375838e3b80853414c185d464f737a617159fc88b906669bbfc44b25fb774ed01885ea338ced984bde2820583cb1269a2c853a700d7554d643710c48c1a29cd310c98d99b810471753186b9b1b6a1658412392ba49f10bafd06c9eea116e5999771282d0c012379068e6311b7ca0491ac2382132c95504731ee6c1efeb14d51624668a66718b857eb080f0c58cff74a7dfa0359b00331e3dba37cca5159418df1e704437773f958a1b94c0f56e79dffb6a2b5a8c89277b2a635ca1f958e0f7cb568214b23b99ed2122810448bf769141867961c0a7463003fdf02728171452aca5fb8178b2b2a42c4f694f5157fe61016f66861a1aa9377186a056a1775ba785497a29549b1fdd0b096b6836f59838090104c28a1b6b91c2d8332de626e2cc72ae6b27edc07ba685258cdb9b6864c42fc866c946b6021a649f3470b59a285158b10a0a57bbea162478815857921a9441c8ce9656ee838004d58bdb0a603f46ff7343710127a302bc648455c6fa375db7a78b766aff71b168dc3a865bbc16c203d99c3039a8a5f4d4a253586658104507a8b6d976032f55189ee775363653f9b3b20f5324271b0c86f9bbea8275f42dc0e06f43c12c416ab861f599053e28c4cb9e57ad6c5b006d829249a658da860d223602ebbbb52b795b731542593088b7350c5b41c7bd748094c839f73565207c50299bebe89b2b9b230d82948bebc9d9ac38ef05260257a29a80c0deecc53557c6e120319a1cab967c71e1d427de8f968b7d2ceea79bbd8257e11dc142af207d6170284a2bd69c9a50f3a70e8a4b3082c12bb312653eb50c1bc4e89f1a5adb511d2ac49f7065ca495372fbba870890f3704d0b7665d1186b9ae522233744b3780a13f181cae20ab5ad9bc233ac8024954f53884b2317ab74c54d3f3554e505d72232d7c309d5b2b0cc6919aa73625fe2441f0034d28f42576d279c3cac9da519fded5584091c46ea4236ec22b71683925fa47a0db3acdd957cc0643b368037f263249f9853f764ff24806482304b8040042fb3658b454e2db18c8b0a7c0f13f63daa012a1cc66184ad123aa23d18302194006248aad63b87a4409d044ac57d386c5a9691dc9000a8502dfc55437e458913260d208c0e7201ce051290d36147f528b46225ba8d156d7018e5d1684b916b2ec746584b28c4d66a76ba0016187b4e5fc5c949aa77c8c8cea1b3a6ee6bc13bc6624503965d72489986fd6b18637c984ed00c0262055a77a462d2251b61b39653928af261f6b42c1529ca42ad34abfb7448de60ed0e907cf200a72042988d8508b2565ea819b3a2c6a6772b3abbcc158f5a60a4a64584789923a1d6b2407c6f14bf90a44c4d533f1e9c4a2a24664b324a0300cf1aa8eed29727a46b28691234c9b11ac1b0fa73021a52ba456c83c2ff9138c133e69d6394d61ce260489e2a307a02b2dac8a3901f6114ca0aaa07653249a8def526dcd3981fd46961f134bcfa94af6990387942982a7852ad291d5d9bc3d1a0f81709dceea88f61aa33c1cbeb5a6780aa73253d28e3f1810355ac647846da4eaa74ca649b836bae345c2632194ea4541f777664c34bfc93956eb081bd461cc680a2f41818dc100ab35b760535617c2b97628791ff619cf647bbf5d00187407650e86a364879b603781306c5bac327228a20bd7eb3e73b68d27773e16cca13c7832c4d5c59330778340c7c418b4c5d3293a1922823a58728915887bb34ea8cd66662a12a5a74f88be9b9454b822683c5cbb789a993616819c80017b763fcfba47f4cac44cf35d71d90181c4462130cec1996dd739c5510a7e0dd248368131838b0e78c0850e1309fd336d9ee50be7814c842b4f881b87a9c9a25b21cccd851c239a8ec3d3c9775167f7d83a21772d9cc65d16717927f5710ada33f8691c5848b8595ccd4cdcaa3dc887008253f31923d85b1800b73fbe869c842aad69866596913c9bbc1ffef24a9c5046c664762b7712cb2a0125894383a8bb5d96b180f68a5f847f474b3a660352b6176f672b58286b3760e0cee8104614fbcf348c956646633d1392ca640d102717c0d6a4e7827b0004664e099034f1a8e1f77eee22c1769a36709a0323e5a988732341745f501255ba442b13d11fb9b0b1379164be4520f783c8b30648ae00792768623f8016a120079b2625579bc8eddcb7d0a8864134b081414b71341d93e67ba437b5f7712b0ca19079c7cddcd8772e304e63fc13cc25a9cdb309b02a8900b381c98394e602756ac0c42e0a7c949c9c46e91734d5beba48c6ac020c363b90ce390de6d8341c3579c147b87db160a1889d8b0b310038587c3188ca489848951eb01895305621f551a9e5526d5b72680fe0be70e4260a57abd6f1399c010398657af92509a8337e2967537fe9c7341a868b40bb9fd4201ea7ccc48b548bd004bc50ae1bf80eab85b5141a5f64aa6490664ca3008f97c51bc6a301a240012403967c43cdfb6115dbe28a083c053348150a1b48226292f4e1ac3afb926791788db862951a21f5fb4736e15e7c20a4acc3a34dc8624ccb73eebc951f8327eb8baaf8c02e38b20d2fda424ac00daee7b6fd338fecf036b7b237401061dabb1059e6b0269417363375125b52d180b4dc91922bb74c06909e300c100fa071bf79afff6437aab097ee455b198b8d5f9788a2873292d445908284ab74489d828d5c60658ba472e05a00715c1b8d061a93f99e46fa7b4bb2369250bba4f7abdd6ab59b6679493a1181898c355b95a5b46d6219cd0cd50a498ba877bc4540a56be4b24e7e2472d742696b9428794495d4a39da3e12f1fd836ee2c7117148cb0ba205bdc5869b08e455a6701b1203bbc20eaa9bd1271243ac06515a118f032411490ad1232539dc897e5208f5626a05c7a0463820cc6b335bfb1653f05a1f8aa70ca7a45dde814c7219761298e7348ceba7728d87a7d7b6c4ae4f2a9d3313e35f798727c71a1512c88fc89028939d6965889820d36348dd3a90a4e7c967506584356686657b003821e3dbb95e1310293a967bbe77713045481b79aeb771f2c53871ba8b539aa4551d06415876ee78a1d79365661447a562c61ae7a1d2996bb8683b62501827ffa9ea7d1a1ccd3ab6f2301cca5762438322bd730e5d4be017b71a0161eaeeaaf5e782ff33bcacc7a0b2fcaa57a86bb40c7a6874ba460f345bc7748d716c9a5fa44c9f809b7688e163c07afa5cd01e3cb7f8b6d629bc37a16631152bb54a70f83211eff82468242b281769a226245061bacf558573a619bfd389a80d4c486825af4ca708da0aee7cc93fb9047e8917901b24a5ef9524093af0a41ae359088faa00834742f03f02bb6f8613f693c79da2bf65c65f6345922a33b96e7171416b7f1632bf63647b2c3cffc646cefc4bc644c6e6c822612061f97c1b1e83c2f572586c2c6793d98b94bc113375c03cec16b41952441797f538b849f41c9622351b578c823866c96f1548c54cc27c47621c72672b50cceeabae6352e5af3768966889903cea5194a1935c0f0a998350b687a839c1915c8aa697caec7a75825a228252a75c054f3f246f755143e7c7d535b6579d8610c9a92a33b20a5a92cf05c3fb1d072ba283421076d0c384bd5fa4721ba35371a0bab9846fdb6b0a3221bb21b0bcf158a5ec086404632c5c336b187ca1f1621ed39b31208901a944ddd799db32c337496cfcc7471ee0aae4ed813bf715994b3bc700a9f1bb23fb0d04b6856740df22aa0aa8596b1c79612662c48b13c80c97c0696b47161908505fa361a985cc003ca24d24713f9283849c29adb87124c230eea216ad75ccb10e77794645054a602d50b19615c6fd640bd5052ce5bd301e44a488b75137d44aa325aaaa9843afca83e6540453282ab7ce64bab45a842e96af28484abd6bb168369d533a5a309b3d9809523796e0d7585df5b65d152598d686781fa37f20629b8267381b434c03b0c4660ab4f400f30fc2568431a3e7413ae3b303ecca0d0368ec9e17acf82b4b3022b94c563c6d53ff25860d539471b2328047c7f433033a7802bdfa14ae6f845d84c5df78cc0859c98dd62c7822321d046242e183e1d39552f7a005e657dcd4b17dcca7852530b772b6f20f8010f2c1c62e672d7e38a48313e18d03235c6a66a413a0849bb804014b119aa149191502055a1d5e53297c2176eb40750fd5bf2f16867b9dcbb5ab65313a9dad7e40ed1d3130077628ec51aa59551c9206057c3681978553b4f5822c69f9d888d7ae4cd80c10e320bb6c694880425a513d1eb1d5e90a608e55e6a3674e31d50 +ciphertext = 4ea41466fb90c96542c58668800024d8ef0c1321ab1b6a2716fd06883354ba9331d75f3e02953e60725c42b601981e822833dfcf6bf2566e42a617cef05404eee8f6d0040501b54d519449017f985c9fc79994b9fa0c98ae9b953531dceac563bc4089476fa6fc8a6372427092b975e016fa32a3e0fe3935c394155c7eba7db71a06e26d9a0e9677f2e800bb00a9de6e1a5184a2fbb528493de19453ffb92624844243f6976eb47f5581b827ec07b5f667b54eb0029d7f6375e64e1afe9d21f81bce8ff1198c8380d68773bcf0fbb5bece87dc76f4beb583eddb9f55326b409bae7a1b81259a1d6cb8dc980ddd0a84f543f02a65f1475b4be47a103a7fb80aaf1a112251435a445e4413fef3a2f9beaecb947828011c4c5343874c475e107aeda38e77576b8c43778469a8c9ec1a2f1cf3a64d20a1049875158728930077e5197928e2745ecc62b7f874af8e2872a70bb6c8fccbecf020f28f448f25900be52410f66f7d9e16e1b36f9f57324b9a4517c4f5d58b4db4b57e75859f94a94ae53a09403d9aee91d41e349a7c8fa096094bc5cde588b6fdcce903922c49bae5c197f9b918b3578c706868a0d945b74ec58baa3181a0d7868ab7c68e8496ddc77d0de0e1886ea51e37411d2078578f14ec95180d6bfb7099f565b60125cd8db15d0abf8e3282ec78bd37aaac9c3ceb4ee36f41ad73be416fa61eaddaedb2a1cb82ee165e619f433b4539bc60f95549bd3689b40022af7eaae687738b72d2072cc095b61594ec905a0a5cf76b8ce803e9f598e2b0373610040e172640afc60a431c04aa376601a3c4aef9f460213bc7c82ca3c1017b657b0539ab635348df5f4f20888e29e6e7be70c89a60ace9b9834374adcb7780e12896deabab24c02b4afb19af2b4e309f3ada06f9a4a5200ba0134d26c752cda1cc15337ddfb7eeeac7c2ad2984a792ad24c1e653b13c52e937e2672d33a01ad257799150fc815d2352fea62cf1630cfd01f70e2b90f295dacd3ef9f1efd7a0055c7346004c7dd25b3d3a8bd5b9297bf73d3babc9efbacba6de8cac65856690bfcd270411e6eabb8c921e3ae797d05cfdc73929e42aabc28fdb193865462f8dbf7b455f5f9467a542afa534ba03cb9fe3c4c0dc7400a38d2cc03db897a978315f0b8261575a9e5912a42436b77fe42d7d05bdfb78fca4790a6fbbbc6058967c48300fe45a573944bd1d2d25b0d4025fe95201d774ab92cdd243e1b934d67bce29c750537aef96ee63b624ae4b87425254cd7f42380d7dab440042992db8b966c2971cb7517b6fc833f296f6939036c72ddd86c1c0d7ab6c54213a0e103b179bad5fa2f0d3d15313e96ca2623bf9c91ae30cda87bc181a7d6ce272aa1774cde9b544a7f1b4f519356616229fc62e6b7397751a2ee4e45a880584cde5fff47ecc52e8ab8e030c408c484bdaac223b76fdb5285626ef0874297d0ea4ae3f9c034e0387f7ff53a8771eca821cb3ef544712d1b8e144a1d6737f0b119fc692fa72b4e423cf17b5ce5f7aeed53a3ab97504d61eb48a85aa723d4e15aff062d272d9fb6ab7d54eeecdc23abb4a018d76d9b029c29230428638d32e47e44fb544a68d9fa20e8b3d41fa1425443cbe30fa48189b5c6b1828d6e77acb8943189d9f5e9cf72e22f17836cf7c77127a0329414d230c23edeb8f7bcd33612f64c755dbb6bcec3ac1adec2c56aaddf27b88f40c42a964291caf2428b0ca9a451fd496e6389aa244953c38600cde263878a23b947ff1a4920e2ff29c422ac455e7ee36f47e8aa9275384c60c34a62d859752fc6b630bac5c69a252a78da4f318754a179b77fb782ca109c215fbf4d7b040cd5fe78e6e129be318a449678557830cfc2d001cf79c4083117d41de49b4664baa77e472043d342f5ebc456e493104c66973cceda3ef07f1f1ef4b8ec69bdd565ee373dc758cb88f0f3aa9d83471ef95cfefcddfcffdbb9f907ab7d59b006e9b2e07b02cf6689b838c6272ec0cc0b33b79f2fa7b8b97c100ff5a41581b1a448dc897023d497b165e72e3967021bcb9c490b6a258fb5eea351b590c4c053726dafd8213d1d98878b07bc460469e313b5289d0d1dd07086ea6b1772143124f681fc448d2c3d2ccaeeac9d4646f1b64932cab2e90e5980b86364a4d7195c298c0db16afc2b9b434de3195302a355756fe59123cdc5d6084ff0c4a514abbb5055a9d9ebff9 +expected_result = pass +expected_shared_secret = f3ba1d5a1d96a4a59e87131ce0ac876b5e190641efdb4a709e72a5b772d68459 + +comment = Random ciphertext +private_key = 3b52132cb892b4c7c1cfd8339866592833cf0b898806f7a1f1a34146fb8801935e76b17332275196f107a3a7ab6d113033354696142589b3327ba118b27472450931851b5ef4ecba241b1158476a4e63762f88593b089f40703d44247ec9962cd67920ab4493a5ec07fd935c4586c0f3831941abab0ac815b45539b3c23034795fc7826d9c8a2f32919d8972044ebb1e9b6ac8fd69b509d8375e4a8aa2dcb160710a2dc1cfe7f8009a93a4fe540ea2407441505b174aa27d30285dc15fd06834b09799c4889d7942b3d80ca162db8b65462ea9e47a1c3566ed625fd62c8aa8906e275c72cb25ab83cac634f03a48780b4f6103a6c3a7847bbfbd584081318b5b5acd72593cf1d16b7651a4c869115f0cac01e6019e982ac22649019a038fb44f41245b7a05ca37fc5341b818c27a4d08d6435e934484515461c62d4e2bb866ca427d350158e92f87911ee2c7b25d2433a66c0c0ba182434b891c510449382e9ea959d36513999447ef004f66f59ff2f10c0247ac8256372f74bff58b0f311447c1e7b1a54a457f67959c49abcd849ff20caa6b8482b6f53996c27a62ea113dc9ae3f236bc00a288d3c0799943e5537189c15b5c4da9a7bc5ba23c67efbbc531b06b3a2f45843999df4170b80c7601e649cb8b05bcf7453f8423820cc6ea728cf64d04ef243305978c06ae0cfb2c91b6b6386c7c5a8915460888c7e4b52a11b422a4ce4abee449e5fa64d6d709b86c785cdb52b2c7517a169c36d181c8c419439a488d0e283a5f7b4caba541acbbc1886a5f2ca18d7c7b961b71053c63d1c7210a5ea6e335655a272b54b614cc55530946bbf14114dc866b436051a8d526adc31c63c4a5e8e0498b114b117807bd9c757d498b61b75a56968137d1690fd095cf3c9945ff0457905ad33524f83652cf5d5b81ae578cebb8cf6953ecb705462b12374718eabd1ac141bcffc22caffba309705592109b59c224ac17979e913ceb30aca1875486f45921b33207d10a5a1b204df562f838ca92544ba5eca846711c2e29502cc2140e083c881120194275c85987c0d32aeb5b40c45db7ca122a86b2b6e9938b95175bda2288ebf1b4c333a7e1e429ebdb6cdda350d10179a8ada376269c809b736328c5846db5927ba7a6b4703b19326429ca606b389b1092e161c1ef7423f1aca4d8286690c9cce69e528cbb8b44001424291465f4399ff1390c455430be406eff516b5fa2faf3474d458688d8408aa154429428e812a72d7b334e4142833db92189b544bc281e1430c76b6344e7357126b511109b6bbd08b1b04ad6153b13e2364b4e28389ba641605ce110a54f8632de9577c9b06c97a9117ad0824cfb2a65b868e09e05e18d59517cc36128a434d8ab0cf1a31ba90768b553f8e627c34164f2ee64ae0d83732cbbbd288ce604b115853167c578b0b96a913936c0457a2cd2b9c1011cac36ac1b67792611364b14a981aa173df852b71b27ad8d4a2e321cd9de49f12390e4b3668dfda8775a55cef52455c29c25367c4396c7b8aa97910b846a53c09b770303bd5b4495bbaf81a80352670456a76bda51aaf07936e723eaf1b4ffdc98196f09e91f42a9806458113823370cf66f704cf0c395645185a613c86bb1923ec081dd34515db14da048aeae02dd8aa1a2ce259d0d61cfe3bbcee104a921868b9d69c1095b00a4cb2fc26b8bdb80aba7c6c83ba0a92d542432b2b0274590d67049dd612f281062a0a169c88b659b6847c8424a664c902f475bd158f84f5249715a3e7d16986479a68dac060033b44c587fa188846d9cc9c52bd04e670bcf17fc8c5caf92a0898f203af594e00478782925d55f97664a329ca1c2d412002668a5df5233d8a5506636c5a8e798a0a2282fe962f8ab94bf476a6271ba1b3fb8754625bdfd35247b290e38c4369a45084d6ab4969009d007a7a1a22f1f35d153c2b89111513c87d3fbc312f8614a75b28613c14a7c63231b877b1d3592f553ed8346b75c031b82084b7c7ceecb6891d263df05844f8f4482f25218c387229205845217bcf560fa5c50eb3745e1d704d99dcc18ec0c85fc4a6b8e49fbcd07d2400500c715b6b7a11a899ce11ac0b35eb66da783bdaa94fbd288e51460ad8a07088a22b40747ef0e86523c256255c524eec4681448c5588a3b085874bc800f9e75bf46859d243661fc59ae18c97ef9a942a541d80835cc0cb02c1e926fc6b1acbc824476510859122e7b00807476fb4994e19c9774bda1a519056546c90ca5a010c94c22e1c10057cbb8cb45e60612e48ccc1af6a88a3d1353d60a02f684825934ad086bc264210ca124e1b01adc606c923b27958ba19a655ca683967d423817bc5183e73aaf8186d10e99cac3175cf7a143295974ca3842fa57558a979f7a31ccfd22f6e88906925ab62b92d2053231d5074c0ea21c2141b01205854080456a6c545841f6d01620e101fd2655d5b06074194585505b75f78a46790348f648b800ace74f971f27036a8e500c0a2085440b1f89ab8f1b41f10161726c594fe3a38b57b4165a289d9f257c397031b952fece78df2c4c1f4d6455a787755823a5bbb918fa44d0d4a5a94002378495a164c625213791cb860e26495da25b68a52826bda6d1e91b1f9a8cdfec13076d633465c6cfa9c559b0422c1a89ad7e91f85db3c604cb4563a29054446b61745e3ab0feb7ab0c3f72e2af12d9a34bd2fdb7966a453112a3b3cd47fad527bc50bc1f7e8900e46bbf8c820cd091bd2e81f3ab63a7cca8c3cdaa345883a653146f3b82248bb243f760385064abe2c6fe099a03a780fb4f9c3bab958d7d6263cf78217887885918ddb916e4311a9005cc2bf77ca111b677d22332887409cec23ff7495b1f8c72898999d04b9820537fe71bb5242660b2401950243065861d7739d4ce4cab9228ce951b99ba52b17a443fe05cbf68c2ebdc35f113507e91c056e9709138a49b3f3c2a640149e62bf0e8596c5e15f19b2c51b87197fb3305e471898f5337db022961c17c7285f0f6c8ef542cc09291d663c90f682b6874a01a0a4098dbcab821b18b0ba128ca37133db1f08029672a86cc114c4938a8a16b7c6e06a8a5f638d0a296d7ff003cf7233d556bf59164b6585cda181bd1a1b7de2b56a46b74c592a2cb74abb5050989a659a8e69aa9860ca07948225ec00baa502f0a133fc9216ba0151486936b05768b57842762146fc42c15f84b4b3c172c78cb75c6bb71b4caa7a085e59ba935a2a6426f74240a92f17575dc28b09361a80b615248206270bc510365c2eaaf09af1ac4105a66a502a9621b277af61ab8bd43e6f7964accbc068770605d50b5d336388d504ee576e57986088e03439c95788b276442717df2298fb42517cd34c6df2ce0f085c80d3ae01d5717ff55e33b5a99e0a59417115be10b96ca84458826ea9d5415e6c23cabb7048369e161141758a547bc3bd759508df03711d59c1b4c573599710bab12e89c2c801398060131f335003cdc43ed8f59353fb7392e497ae053dd7b03fcf794d5ef3ad3b5432c1eb5eeaa53f18d1b080a6447506cf47291b08f2a309c1736714ce08f8cc210582b6f150ddc1c3bdbbccef58b7790b1252541a2a21b57a546855520ef372b9974069843c9fbfa9aab991af85613ff9e5113c1271f72b2229929f866cc2d9b247badabc808bc645fb6b1fa491d522922740cb9f281066d51426f4141d8ac257329a85916d70074e6213b2793aa1d50b3249a855cc70c761c93f0d5a5ab4a9cdbb34037c2a39426bb0d4766583258588162898c52195579c7c75532c3c069ec2401fc7acfc1c62eed59fd5ca725342c618a1be45bbca5d23769e6997c60c6e49a16bda09479519b449d6aca4a65966a515bc5229d83a11afe2128b715b8ea9530296c93d475db4649dd4e4af9b4cb15bf8913e040c82eb3f3ae63898585434e4a0ff30020daa86872c2d8541459c0c5128010eb34c6c20248cc81cc7f23a94d6b879744a10d877a67e142a0857b5d6ccbb4b467a7253a86cb33073bc458352a904152da5e7cc867437de631c44068a23e88865f1b02ad829fa731bf5c61150c425e0264c7a3cc88500c51e7017ce593c6cd60bbb04b1394a3638e5be41628560c803dac258eedbaf7ccbcd91b9387c815cd1c579b4667e488a1df2521e9c459b826a03ac172b37ea0a2ea208ce819d55e6079f051ce1fab6d0335b1dd44a8e4a144b2292af55722c8cb0af15b815887bfdcaaa2740bb6e3538dc1607f35cc44cd4a53bfb79a057a189b4313d9648c3224571d56908e81f853b9b131030dc79174ef1c375057e4c9c0aa74c6696c0930ac3cbe2b8aa5ba3ca4f74547d80bdf4fb2ac451d53f7c393e29713ca6984c7f0e81ec8294c5176426fcd1e232414cc33dfe133d7f22ef4a8c8bc90ae98f80f3c6fa5af0ba11d43500768f1185f4d6be77f0f8e564e18f5c43fe41d6235ec7768e33ee28be943c5e0b +ciphertext = be1c42f1169ab5cef58b12b7c674613030a5f8012d2d49cd11dff0037d19bd9d7f308a4b9672171fb0735e7eb36b3275cbe3dde4c5b7a03f01d97ea48ce9e8fd97d5af0abde80a82cd8d2b1d3c6b60d7f606e65c207a530a7a4d034286c02ac7b51a7e53eaab6a79a69596fa6455e1db2e011a64ba3a83ef73d6198028181af4352846e2813f8eb2a911eea61d2d98cd2a68a5b6f87e0d70f0abe7a553985715157d641de7ce14261d2a0380d72688280a3f7d09eaec352dc4b5f0c12ecbba73bccf18636e85328c99510e762f91633be24641b95c485ab0b26544fbc185a3d3b49f74432b95e0858d230bf86b649fa7ed34587bd77a297e64f8f78f346287a567a2564a895f6ab3adbad948b83d3f8fea56c7a7c78035cb791d9aa987983aad848380e0dc2421150d122d59b080eddba90ef249db71d6ff2b198bc8fbffd31b1571c9e6659ab4d784ff6e0e3fc491a65c7bb461d51d78c1b6d27f141e7d62c988db570caa5e4cbbc5e5b4fb95b0a95e1496d8ccd838ed352ad6b6cb69da18bb75b0d2c7f6e8c46bcee21e08a5105ff634c584da39c0479e1292f7cc699d321c030987825b0e68fc4a8985935b1337ef9a1643008b194fb69a80f1f97528cf00774bb95160b5e70e4792081d81d4d9548e74ebd67725e4f97f0660a59e86cd9a13f0e1e39939c12f596e191ff40a824ce3680c80e68e1445a8dd5684fe4853568e84ce7052d0cb8ed38fef633a05f4aea017eb35d8864891b01778a8f70af45ea9b288baeda6407fba5a6a726634fa2fd15c41a25fb82b21f15f6afe64abe4d62040c35204cc740036aedf1d13c53c4288fdd1be324bd464e7f2731c7828509171ca4b3759d9b9f54de869a575b812675867af98237944f3aa451b072806b581935af8611206db9018a17e334598cc7f12f8a769e034614e094afe0485244a474d2a61c0edf84a1eb3d360413f070e970c4c45f75096fc2e7b1ace59ada18b2cef19c05e96279dd89709d97471d1b6a1e88b8fc1d881e43a4d86cce5f5addd0d00cc9b522fcaab0aeef4b727e1aa132bfcb6428a3d58a34ce60d511718d564a89b0431abbe8e9fd6cf2b993bbb6ba5f0ed6cc399bb8312c8c2c60274bd70550ee18fd4b7bb0a8597cadd2075d1b7babc66c20d1b54ca44b5d687bd8d16917d08e63fa1bc0fb6478d090bccca83e87602e668dd3f056a8116218f2b08365f86ba481379905bb6018b54c5e6f9e160495f54ebae84a86bcd5468ece17aae829f83c3d5b532bdde929b7e152396f84f0a6e32111b262fc8dd968f7459094c25a89b37ae1ed4d91ab62ead3ac3b339acf0b9111d450e0bf380efcd6717679270c90bdd07f0b9efeab6fc74b19a86cbf4777220a9c6f85e23de592195962aaa2412c3be4ab3daab3808bf917a4dfdcb9cad03ce757efdccbacdcaa6f4c54f849378f12574773dad111d80f503fe477506982b3b26bceea9921b5bdfdbd22328172ba15256fbac74efd8ba037030994a70aedacf49a5326d30c10003a4e93ef334dc83d607631442421a45336deb2b344a6fae1e9011fbb150a4dea94376e4b47924a109bc20e62e8571afc012b6a3b2acc80e30480341a7bfd88209775ae77bd199a44801573be788525000aa77735865adedf0090f9da80a8e76114e8219f289e5d95bc56718548c31794784225a15a4a3e8820c1aa73b8be2117590082b89e904a5dd8c37e07fabdb1e1aa1f83bd1301705a82be70ba0cce458eb9a240153bd8775104fa3085da878c5b329e829c1fc5e344a61437610eb75a48e7b6072c207f2cd909d9c8bfb9c6dc565c9242e8d9cd1fcc9f31bceb77aca0fe1adb723870761f80a47d77b1126882c278145da3e1212a3caa4dfe7724b1d3001ea1c9db9d40b367661052ded65a60b1b5cae2b5b9088684f30d707b49f4212e5810d2d1e00a5eaa67c6acdfdd35e3959b68219bcedf4453b228f02da0df6d9ecc2f60a2e23b6dbf3f83798cfb16c611980dbca7ca713a042b27e435d35b56112efdde5a0bb49db415b0474b8f577937944d555d1fcf9bc628252c69e0371943dfa8ee6ad2e2155efbd0eb7c05aaac93445271eac4a52cb48aab9407f2f727b24e4edf3a98996ea0e245159f1133d9193bb50ca177015e198ddc577a219441fb4fc0552fa50fd962c0805979475ca5a352d467c5a63d74ae7cb028623096121184ada1598ac5a56 +expected_result = pass +expected_shared_secret = 0875b7ef9a48d579171055f3551abd33943150d6590d4abb1766b7e1f40a58fd + +comment = Random ciphertext +private_key = 01e03dbc643752a835e685b3e203588ca48a985270016578a2698bfb8518ef543755690c553332567c7c859ac8680bcbab88af0e40afc44b1f98a6ab3c725750e1c239561562244caecc7ba577c842a2c1056004d2948b9f56c22cfbc117e4b3712646e2766a594824a41059da58387a452a96a7afbfd552639237d7566ef60416dbd870eed69bf392c1aa19aef3693f0e3a930fccc32e7bcd31c5c05bb81a1f6b018bfa2776d16b71b9346a145d21776625f9318a8008a8193d102c532441a10068140645bee4c427ea383c50ec1410087f3356847fc3349e2b702ea0ca89e12d0d6325d8b197c5882149656899f417fe41913cec59ff5142230aaa32bb8270025de5f1aec0722ed859261077a4229155f259487ff9a719cab47cd482345455bdfb10560b91614185ab683867aa54a6ccc36e9626eb286832427905c5242e1c959c0a32977170631b9e0150b3c019c0b3a272fbf60026c7bb5f58ae8fe0155c76a369a7313b259062b22340d004a503b46636290e22cf80c74074f30f604a4148e52568371aab12c6439b6e84cc9b9bd54dcaa3a5f647c34e2219f6c81c41a31b8558b2e5c204b4351a6c143c05aba10a27a08e9742f459214e286c996a91dcaa92f38658cf137e143aae3384534440977e77aebab30a48044d08742f5bd05ae7504981d29543034157936f46f29bd12284921500de283a3a1ba984c96c87230a76246a2591659cc05f644b31cf6580a1283b800146da5c866ccab5d758609efc7e5de8bf14204e0a2c8d78ca4e2b4319e9731e4f6c400372428744751b6b379b130b707731cd786124f194b1ab285687821ab4127debaa55555225184708e4b65c5974d246207586bd8a495a7ceca054acc044f8ce94e60b5e509725ea68acb6bae7e448dfe93c453787760b827957bbabda6c701c4077b0446b357d632c6265954840c4b7959ac417353ea7c947028947c7f09f262807d655b737e3a06f58435324050e1466f57a393e6695fe7c141db289ffd3acf6936e0f5c79c2851809e66a04db7f9f019ee5830ff383a5a5f244b02a791cfa08a3533490b27aa8a47f8f5c089ef045e1e0c590a72fbc076015d769b1046f07c174ef9897158c521de2179d2422c6a825d3e62620b54ef876ad7b327950b895d0aac281c8243b0960069b6935f988dcd46c2cb3240970a9c702c2c40286893b732f9ca88513c3b797c63cd32282191a90db0ef4d5480432c8dddc43f4d62e431a240d1704f73592ba9a539732b03b513f82157b39393988d3b28e94c4ec902216f01e1eeb6f4e5173d5524c10479ef66693265662797987cc6bca8b00b04e9b6605f37d0ee0612a92b919b0310409abdf4c2c21f87d7f8118abb7a8576b1fe7b9404d652e36d13330326cdda0bf9bf08ef409713b0912c64131d1e58d4c7224c5f6bc4c731cb39b00f25712b8dccf22d7b28c1a4402c555c1a41ddbe24e83310bdb3b815e43a1c7729034bbcea6fcc51735ab86d8ae7d81767235a7e9d2936f1809516b9c542c4fc8842452923dc699561ca07443581541b99aea52482d44a24e866f888c37cb16902ecb4a222282af7c29c563be4265a79b2b082b481151065919e7bd0623462b1369f680c6ce279d462360c4767fbc2caa0626c90c10b23fd2cd972418fd6744ce7c5129aa9e8043b4437073d72c242546755470a3c307246e40b15515336b19b7775a9b4b6b9090846dcff063cae01bc7983254b6b5e085894368092f3447c7169912ecc5168c4c8eb5cddfbb13e9d6147b475211104f30135407513a8f593948e417f5e937d9b9bc85d6ad4eec757cc82c1365c05572a88ff64abe98bafe3a6bb3b16bbb054ad5486bb0a67a7afb7251dbb5e5b33a6af106266cb449956cf65952faf812b9a4a8e4f778af287df9c5c6ac5084ea621f166a582ab60b6cb70316b28d5af4c015fa646f60c4dc3a64e5f94793072fe5c03315e65feb6c0e6683959a5596784330dceb4833538a16c51f478696849c4b81ec7d5147baa440c609200e45852d8fa4538e5c04e89359b5c2cfc6299c256b92bb5a86196343f0801f99e769ec938c977b31b8e1b3ac779081255045d0bce180a8cf861f7df4047de036317579fdfc482c768ebc47723e766872827774f2aef8a7294288b71b492b9acb07790c7aca1b7adc834e2e6129a8b56d84f720eb9c9e126a933c891fa4868c2ed165fd98afb8f3205cf08540e639cfba7cecb45301ba2f4bc1a10e080165ec727fa601a59b72f3f223b7b703ebea46c1903ffa20513a95a02dc6266c6a9ce314b3b3193a40d1a9a46275451401ed330e2aa3183969c0aa37c20ebba70d74b13adc7991ca4e3eb52be737439567a2546873517a61e7f448793ac4b2706112f53fee110cb647b970d0967f0855dcd72758444bdc494de50c35cf958c3e901acb627d6360402110633160b755ccba33eb6a197807fee048f720c3195a2c18d84edf0659adb174e5a340b022bb60d0a301a12e44c6bb9081714eca3ba209a119b0bf52117a99603677d10601a7cc16262c0a4b15bc396c36b4c14ba0b916800966b93e57742e04745f1d5967eb54b58767c809f21afafa94403c2ba552143970440f444c1e952e49d68ae74a394f490eb5c95e9424b2016365d5b09ec7c49767f8785d5b6c90ca09b845b5c8d2afdb797af0d00c6916aae2f2b0c7d2b3cfa67864585d64326505a3780435ba06b6c0f7d501c0c8b18117301b4c0cd419269d750d44666167332781da00feb53c24c9a4880b2589a59539572995537ac91ab6c438163a8173a9663cf570a933d1b5c074c5b1ea3ff014972593a0099b08b2bb3454ac7678accc3576250bc8554fd7b3b65402499622a9840f5a795a6bf312098940448732ac79c9c070780994a0f663787128797a6231d9d9c93c1c68245a8eb1a5c703b07f869010a86a48dc87487226a8f9e0648c5579acb9622fab2b6cf4a890335af512923680b8b6da2889614b2341012ad6c7084c74dadb550f05adc1f1a4aa00a1dad20f8240768a42657ea2bfeb4abf53c23e79554c193321895b15dca2267f08879ca870a5153cc12788e7c2c497756cab62055275c0de29a02867520790b6472755d222379ce8a7ab355908eb0d6760b09289187a915d18b7c1ab7208a924b2533b83834121c5279952d7c170048cd4b72591951f6f08cfc9d4637cba7ba7f931379375b44a6564fa4a1ebca4df5766a319b982aa627ad77e6a286cf789cb01e7aac9599964b6a54a1552b9c09a7fe35e21d3beeb61c872b0274ca307bc1a84c3c23e7a8b9af4892a070868de9c53a40a6ff0fba0b5b9b1e2caa1ab3a61305b8c32c221fdb8114de4171b193106554da8947cfd11b2e2779fb9c23b79987ec5f8ba6faacbf668a209d77ee5cc6a2207b4444c750a693077b72df4258b7a494efe064ca26b10f3ca3238d90ed27bc3f80290b7a71681ac70fd39318fbc27e328703d7b77b2000fb7390f39164b970bcec77010f33076ce05cfcd128ff4c676c0694e0db5ca41694abd9b6d5f715b44f02d9ef53900630a7cd7c757b0245928ced3cab4b051736b326deb669e6c668c670c1cab12b075802676f35a12c48ba2a68df38a0daee87e16a2a37bf34ea720347322a64d2a77a7f227bf637753564c7f905a3909b43a969817661b6705cd6083b45e483553008f4b36474bbb172154420f2bc9678212cb56948a49589a977f11677cde1ca9f819c97ee83ae318adcf4398b436cb8ee773ad9cc078056a24dc705f1b63eb928fd56290a3a9c6d430764de0b14d3b5329629b29c060f8097fde7430dd13a994475cbfb55b12947518a0a716ccbf33f803544c0b77f8c38527be8d80b677432a21b68792161d311ab51f43a529a6429b673723343e64e79fb3eb4d3da882c1b7c4fb947ded25b874509849eab6155ccfc3812e76c1269f424b57fca928110ea0d7abdc4c8ccd065ce7807d49f4b7faf30aa937ccf1e703c3c12f63a3b3f871cc35148d24172459086ab7bb565ee599020a00421aa7f9a27d1c267ca7fb868a9882a4cba277776f38600f357c9015c8b832c09578934a744700caaabff9c6ac6f92465e404deae49d53bb7dc9c09f1bd00535522a4a3270ac9b00c4a0098ad2865745124d61276d89b5932c7f51ca041fb0686cd8251faa6faff737120256c4eb81d9f6400e47698916a8d534059dc8902676401e9638c7c7480ec2cbd4293a084b90bb1176836441e003992910241df40127d3707c50457b4c0d136721534059f46127b3aa304295ae42fabf59c3c7eb5122222aa08fac5434647d9813234db4bed17a119705a86e997b3686d23915af3e3dbaad3d8e25216c1352850229a228e584f891241033c2c225266abf5d10106eb801e8aed7f70fb29efc7ca0f8e83446b4743557f9d43542b3a62598b97386dadedb70ad269694ced2046f66569a2c53b620d2402ade1ccbbd +ciphertext = 59efebc7d7b940016f2401fb3f873cba05f7eff8d95c6050908d2e2820a9dbaa02db475f4fafc8a76417a789299cf1e79a8e63b1906dff632da4ba07e04a9dfcc0fe0ea6bd6c45ab0cc6dcfff5d9b3c392e3f448f7b34be47b56b80c39635e8b0ea072a0d5b5d45bae005ddd20b68b6589b2dfeb9087267a25d3b77cd8e351d9cdcf9583b2f4e1a8f3abe347bf1561c64afc9598e29e4f0a945ebe605056f821e25c3fdf9f44b4cc7c3fa23583f331db2fac4130992c97ca4c19b7c9408047c69e9e6e577fa1b110941de1696b9218b76610016a2fd949726bfa9aa970bc107d26c1e2e788804ce6f204a56feb8007c641287f00a5d2891373512c4cceda5768a405de8466fa8ea66c855a236a95df1c31a4e99308e1db049057a22dea64f01e51129d8c2d722ae91923ca4ecda2148fc9ff717c47f77a6fa011eb3875bf2a6bbee576fa81d638e6681faefc169c04e287209eca0bc2324e03feb243fd744324c257d510ae6985f62c50edaf5b34618aa562ae04e79a151d0ae26fb90d0ca280e9c105aedd1ac538188950719fb5206eb241308bbdeaf877b39066557c461aff0fb1d94b5050e18fcf9c34c8f065f9db2e1e33bd2ed5ced24b744575f7c423a1c1a01581085053cb8fb91f0bb33b8d928dd0f5d8e9f3d2bad4c2d317c3015f0e396ed1a6c34ee570577484412490733c52852deb0f32e8acbd22300854cf02d77c63468b45de0ba1a7062586b2a53f991c5dbdf7541efd7bcc8869685a49bdf84061568c2c2b3a47d28a66bdf5acd92a72694595aad03c87b17e8ccb2413c5bb047b907ff60653b175c8f9cec9352bbd5aae3d30535549b68f2a682b5cceb4039a4e1235219afceea0dfc5767a9098f81b5c11f8291eab9b7edd7dd095c97de7c1df956c675bb9f7095b5cabdcee54ea95554fbfc1642905de35af5bfc1dc3df81e7167d4dcfed0bdbee6af3ae676d99bd50983729bc1698f28e89cda3f67dc56103fe96f056e4aef8be628a3ab2cf7917b816b3e3f6965dbd96edbd1f4d1f047de3cca5df7c1753c14abb0592a68fe5a7ca54834c947671712fdd56fc85370e46bbef9a8f827513f47b6b296689ce515571375a217c7499a510ce6780d74f8a197597b35ac0e10dd815531f2b80df12623a60761566adc7b2966fe8a149a89fcdbd392241b0a9bf1a737941550b5eef8d758a0b96a34226573555b05631e13b8abfd4c6a8f20bb0640f0d1c82e0a534400277a71eae9e815c1162fd42ad6a3e174f399a729c25b2466f3555d39fb3a4a33869146614a1532ffb595880ab1a692f88dc24b80f57bab4c09ed3c277f63966a21599367f37a1f5b04fe4c38f27fe0fc3e6ba2da173d9123e459f8a6886ec6d65f3127ec35e91ef89f4a6e0643ba625431bd27842220d8ce23325ad9432c58de26d7214e9f06bddcd8dbf0f6d578820115c3e631b15d30d153d9a8742459039de2acdd98b15f424c765e3fe2f219ac89734ec3f8a52231aeff0c0dbf1d3e4cb78ee1510b38b5973d3b1e687e625fcebc2d7bf678f8ba3b4da39014dc84d1e7acc883cf0f0534d2cb5a1da64293b84ecb70b4fa6580a3589764caf6e7ae8a97d82d7391066ffdf47ee71688022c4b06cc0abe5031499ab22f5e15a2ca67329dd872ff7609e3ca2fcc95f9a61a8aa919ef48bb6520b8c0f0356e94aae616c86786ddf7113483a1014ab5c7ae8cdae8483230941a37859a29551fc345f4a747f88b892f52f175394312efe1a5d7147ee62c82af8fdaf10312ab182be1fe37cf3294c1483487aa1687f9251fa5497c1741d689b0bf2f326e63db23952a9bae084cafe368da6a83fbef0fc5c8701300d7c199e62e16842380bdb37284e7296492693dd33c6c5f6ef218ced8e7ca4cd82d46a2bd9fcd63901695784b8afa04f604cce41f2424d59a09336a67222b6d24d3ac2286617c726d5b62920f984b2b6a1c1beccaf6c141fd2a64d63f3fa18a745f76c505107ab0d74df63041eda039929bbd31528eebd5037a15188186fa0c0ff7f9cb2b2857879a8043f22e7cc2167354104f17b2e54fe22d762eb035b30e71acff8331c1f99d1eb8004caea2d8954aa90e9deeb66089eb1975687a6124e1725d458ac71db6f39e5ff3a5ffebb29476722f3d719471a8e4e57b50c36e934f2393c22d53bc5e8173e0adc56f8089263f6a69e369683514c2d501b622085443bc103 +expected_result = pass +expected_shared_secret = d7be239ac10fc094ef55cc8c2f9ba566e2ef81618abb075c2b2604d8392e5e8d + +comment = Random ciphertext +private_key = 5298b224795b7b3c2d47e01287602e9045390014a3635824e59a0e250b89b5699d00341aaf5a3e20106801e77e9e6281146a988da5900d5ca69ea2338b387602e9c32acb9a77429bad1c482c99bbbff625288189e6634571bb96af335841f6b5b4f95e90ec20627a18491333b91c5dd238b2ee1b096f9096a450138cd646faea7dab830193a63350475e7651be18097445729bde4083a0f261c0eb942423cf533a31f1943e85239c5c80361b6b442a4a7ec1c46d564c76b546be76106bf029749de44c10a54308d7b1a0dc720bb31032a8736c9c07edc205a9e56d473088531758d24565747983eb55baa606557ed904daa1a03701aa147642a0d73a2f771939d4ae56884f9d465cbcbbbe6be3bb7776c5746496d5219eb6d82784c25f14d10f7e7468406a6188acbdb6f8069aecacfe149b4b72646d898ed73936cfbb9d0dbc2a76daac30e93d22c99e66617a4171099e34196aac27c0d82f9d2b2724771117eb0cb1a6943c54a08d3b8713163f22fa7490c9a801f5cfdb7c2ea32c10e10aaa836464d7d471f0f4719faa1fa4c5623335936733450773cab66033248a8e4444c00aa3bf0fbb7bdcbb87a4027092d43d6dea808e394e77102aeb91086cc213550104ddf1aebad5bbd55b0a2c451cc103794bb42bbbb1bf4dcbbe5b97823ceac708f0b30eabc73a40cab9b49ad4d597b558774233cb34e88f9f3c5a9cb45065509ae8fb2cc93a6351686e2f60c5f7535898d170bcb7698c150da927b789b869b818520af85337a24289e718a2a28a213b136e31c562111ea58979dd97be2d988691148ac0569c238a1e6d3720204c5b15d999b1b7b39ae0025353b66618bf2ea6962b04aaa8d145ab1608d9c77407d239d7673c3a53abd4e03bb12bb204b29aaa2c4dc37a44d5d86d19414534794c4ffcb079872df61656a160bcacb84153708167cbb338c1144b9358cf21301db8bba9fb6387b2a96d8121590bc20cbc026a09a57578766694b611948b648a7d012b6372689810167e3790747e9a0fcecb1c17579aacb0b90374a0cd6990d4c9131b6186bbc6637c58740f2131bac8c57889413ce7a0d976ae17481945831685a6c30d56a7503882eb6c8b8008c5a64118edebc735c1721ff639c3335ec9f8b1c2919165250234505b1e0382bf0479aa97cf5c7197400587f406af6de713c9d392a1817630ebb6034279a5291de731a4d389aa656a5eefdbb1152409a1944695856be9511a639781556107f19b5b1d7858ca1ac741e10d175c62dbf4911d1aca227a7f09772ebf4b8ba045088e4324816509502424a40ac57703495ad18c3ff56f2c92b557c3a4f3472c51479b9c590f09a387af730fea842f59b72b3413108593b25968ca2d54cd7cc80d981a2084e931fb28b604b82925fb259fba616cf828024bb0444ab0c92050c2e596b7c81c9154bb76802d09440520084c90314e6fa694d7e28373f260bc021ddc1a2a5560643b1b7699e733011522d2415ea782c0c3b5c7608528975999e3860a07e184d0e7cddfac845c899fa2852c75942bbb348c1130b77d0786cab596ba5445cdc16e9ea399032994aa5b6ec6f030e4b39be268be7874a06744982121996548895b2533149c2858c51c801718f68499221620bb500d3980120837a60d5016113ca131345fb0744dda8280136b84fcc49c0004b609f023eb085055f56098f58d13e256dfb77261a14285b88e9740bc3ed588bbe45a105c2736fa6bb98426e4962f9ca1720847777b556c8db07abc679532f391aa2a5674144036627310a4a9c10537ba42b98107c84e5c15b1c18fff2bcebde90d195a2bc906467c04446b9b1fc4f28cc2d3c949ccc9c2598447382be21283f15002ab7b5283c218ce9b297778b6b814aa2ab336a817b25d4a470bca76be92393ec840bdd03d9db07254ac2e324b12b767c2ca7632f5a25700babb02d59d6511c8528a6a771921d833ca03225bc7846880e2a3f1b933d297c8d2e07cab64a73320a8edd8006f2c16d346ba848cbc78f5ad3f536c571cb0cc4760927856a214b05a611548e1a63da0351531133578aa187b1ee67a1b8541a43ea3ccef8bcf82455ff56b8e4009d0b8914cc411abf6e016bb334923e542d50b8bd6b63fad81699bf44205d12ce0d9059ef3586468755ee63ebddb0ab4d76217cc978aa6bc25bb9116eb00d38196f83b57c925b4143525d6cbb147547835dca4725687375964db76b93c16c3633c9063b602b3d9a2de0b2852f1be75d97a3439ac56040d3dbc9d8a18813a8984a516ba29a67ecb7c120cb86b27d37bb3240b59990afec034decbc535c0999fe7cba01465a426a772710302a807e8ea3e62552962eca94b0703e3c2bbd923c5e02a1509b271f8a00594e636aaaa60668778af877993224f38506f25e14975e672ac1106340404b519c055eb41ebd982cae8961b9858e4c8a20fc349032c01fb7a15f1d114dfc8039a512c251c8e29c65c092a2dee0449dbf1694125405de47f8f7a98aaf5072bf07bbda63b503b6b01393e0e39aeb09210d092741df1cff2450aa4facfd3615e5f903697806b1cd6bd9b9574d96187bfbb7a47f059768acf78838fbf1065ed3557a94628da3a9738e59ef47789d67aa1ee949b52c345a54669fac09af43b86e0fccb33f00b61381d991870b872ab3ff90c32230ae3253776564b0025cbbfbc39646b7ddd190fdaf707d0066ee8e52b6f451249d19ea8f11ab1a8a2a76bc81bd6376d47ce55f498ef5b48ec567fb1ec41c12caa32a823ced30dfc489a5f906505e8a7cd63528443cca134ac6d8436256c805a12714863926373a2cf029124b7148d8c35055cbd06169d87a35071342962f05e87d5cc9a4178cde895ec7bc7ecfc280509ccca0731608207aae76c7997047dc35b0ee0c4a39bc6a8322ecd4190dc3814e15824faec27d21a57d79b56b934c97fa28f1b147936b5cf373411f7c5730973ae467c2295e66a417aa87f0ca72fa494c47b9aa5f15aec1aaa6195ce191cb25c445f82a0cd1123c9668a12f8b0a57db994caab932841410f8a3e9243c87ddbb304e322d48637c523526cd870533b3f4b947de61c12241765e4a34a29311ce3861f85fa3ecc2678a263088161822fcc4a6d056d7aec8b8f062e6961503eb6685f8433635793dec651a50782f2719aeb08988d3bc35ec8ceb4042570cc3a18a23e8ab220d9a7c8c0021540d393ac552cfac36e610a057f6133b9d29cf5022c983ac9ceb6a8893c3717346524b377c14217fc154e14693bfad0529a10887d7520d4114e67c54673a6aabaab72e5cc4f8166b03e2190e0f35e55970059a3803a182568838f0c10ceb5540adf1b503fd41b32324eca320a6a60acb60458c603631bb77e7b047fc9c23a55034ae67bb78e0765922c3c8c246cda77bcafd833729853bedc3a46f2cc94cb26f484ce6a852947e43014e2c4a4255c49abb384a124ccf04f070a5213e1a9453ab5a7938caa047dd6fa5f126398bb9a9c58c13dc498bce47b1ae382ae877450bd839e51d2a49f685a6f093a923a274c8c87bc02074b50385f791d396917dbb4112f7b2c33508814608c2117c0ea93caec749d71d2c69d867427564342c37a65ec11ea7b88a7a6ce6e3ba2ce1c78f57932a7973bff2888302c318dfb0ce6d54c4e0a3ffc934bfcb74c9bd5c221511c17f87cae5b7eb684541d309e6b6222fc7b4cbff5935e3a39e5b4c6ec03c6e87b9c143056a62196b1bb2e865940b2908906f852bd981f9e44a1bec846f1ab6715603cbbcc80974c5b4dd672b4b56e03b968692b248fd0a9111ac298e65735576717553a95c7344bac22ae8505b9aa846d79708d5c932647c8ae89add8392ff339c195c42f24e3cc23d3170b3c1a17791ef8c4a56aa669aec9750fecbb414bb5355b6945da00e8e2ac0ab28c5d2c992e4a7c740522eec28d1c874e494bbca2a80ebbc85797f4921789bb238760bffc03c75874953822b77ba494aa626c19773d6c2d483c2881ac8168538b51c9a35e4b24ab8a3183dc9f2b5a30cea41e7ce09124a0986114bf29fb758b98c989b50d16847d240a0991a35e1b01405a939b3e710a67797803747643f5803d99a97b90b29cd7c06139cd12a754712512275588d727c31c3c6516d22a9b2ccb326500ecd5291149163ddc09e1e6731ba89debc0357da341deab3bad435a57f21d6bf922752595c8bb7c24675ac9e12f91670b11aa4806697748ea1cc705268ce498ae4471b30211f8d46c7c1ac046557113465d13117cafe2c5cc86cdb902cc69044050aa70a34536558670bafb71478448a8e25c5db830246474e970959388aac21c4251e221821aede9dd0c4c1e46b665e54f307334e1da55cfa033f7c3ac0487119011d29cba81feb5d82e71aabbeb057b4e8c595cfa5cfb63141dec879ee0b696c04c460554ab9003e1db3c098492bf78b0deccd7811e0fb321faf0851f0061818e5b571a +ciphertext = aebbf3376082b5c3f1f82df785281328bd869bbb7194e0fcd0db3a3969e26131f8b10ee217cacf0fa6fd36c3655990fffd96af4905a9e2914aab741ceedddb079d61b6b148425cd93a20ddd15dbec759aadd354379bf65326b255351102ee69c3a99eb2da32f3a338faba2702e2f90b10646596b0ea932d4c595f176f44029a14359cf50f274f876d278574adcbee63b89de977f5ec9ba9f76132ee96b4c532a42500f798c1e518bf31af7cf76357d448fe2c943ef46168b2633f15efb23dcab65a4b3c2d0695cdc490126d5821f7de2234c9329d9afe38321bfcde966a0bc12d0c5a8e808d2375d8b32434f579a3476fb0f0f35a4461b615de2fdeae8b72034d2f24e5e78d52df851b65b4e9825dbe408367ba2847d82c9c74c62218d8f64f82d6a14102e99255309f74020d4688936318f11ebe217313cdb28cb1ff31eaaa71add125ecf643b86f9985efca8ea63438af460472cb794142912b87b2b33d4c7cce01731562f110fbe3f9a65b65b8279f4adc01730f1042e4eb34bc476c534e870d1f9516781f5c0b406d570b00a86c718e6f0ff1ac28087b09934a709b166d867b3ce5c4161702a13534ebe81a0ed13a7f62c29d4997f42b2d8bc0160af93fa7f2e7128bf38470577715a2e4ee6dcf431ce0de7ef517e1edb722fe75a784bacf33c18314e079addeaa1e8811ba3ea57ccca8c4d9e4e73e03b786c9a95ba65554fe0caa3d92d32f881ada6e184c44ca1a17216c1318e9fe3d08883646d89a912bc97b34b80088c308dbc89628e5926505a7415c57b247275a0ef62ed558b14eea6666668f533c4ac98e401b99f24e81407b7412eeaa61a5596f95900c80e7e6ad8d4a1ad7061073eb8c6100ee8cd1d410863fc1bc3f92fcf3f40428a9ebd32d9014f33e67ccd66a476529734aac311dd83db025c1e89e9a15724ef2ae3989643cbcd1fd51144c21811deddb92a7c01c7b4b023b1a5c63191652e670faa96aa5e6170a7aeb8a0f6727c135628ecd5c1f50b2420288422b2a7c9850a0d358e30803e98db3870428bab2b9fd9fdf1aeda73e8989f2c0c850a78511e480b0ee403d63969a47afdcb9da21b824d984fcc4a03642447adde98228be4dfbef1a08dc7ad1ee145099f3344d1fafe438087cf0782c424dc90d66bb0b70650981b525241b072082192f3d2bf75587f3303b14a41a69813e67d2f9447022eae6c8143231093e51f197c8992e7e9e39ce129b236b119de21f2c08967e048f16c2244b8ed033f21b2d64906cb3932b3aabe7c419460f44c003a6a6e78cf013d543cba56958ccb0a6da8515a3274bb237758278caf3136efcf29b62597e0d4bf6cd278b4bf2b2d27bd184f80a35ac66c8cb1d488229a90d5eeec65ffde3cf2acf373fddebabc43b05dd16bd9589fad47f92e6ef8d201f66d2e6eaa969b7c5e861c08cc935fa1a9df956581e527fbc2940bcc65efb38c1ccbd56ff744108bab3891ecf7173037fe0fcc7c3ad7eab8ffb3eb16abe51d378c02e9153ada8df8fa13fce73cbd710e55daf869054d6b40499900d5a3df099bbe5e9928e9e287b8f3cffac86f56a5619f535dfcdd333c2d948a54578f92fe2d60d10425167c1bc2d7416770bda4d449ae74b441ef204501e2ea0fcce8d7bde18d4426db0d0e3f3b05de49ba57472162e8d062aa3fcc781706f205218fd34419659ab3b03bd16e86569b5b12bfa32c44d3dfe7a493030d53b9239064f3b1492ec1eeb961f8f9f36915e2c5e3d2148a04d0c55da4e83712adcfe8747b44c35ec17c9da5e938eded9abed64745d6d991a27b512ac514fe7e809031189e3bff9d1bde83769d528b24f38ac52c1d29aa34dc07dc8dfa6701ee20f0f0346b4896ee4587dba6e7f5e95e57d4b3a75ac388fe92b5a94e5dd823dd21e196b5294b480de0ddf60309f6ad48f0ae2f1c349cda2dc9ad94a7c7638ad1a7336317f71b68bba82adfc3269e42d3418c77931f74d85295caa1aa6f9d525dbcf71632730ca3dcbb212a3f7101c240daaa891c85d89bd22450f9b246e1ce927a306160f21ede002ed442a4653ce8552f120e10b2b04e2a441a4c56216def1163655969a7ff09ead197936d46b743130f8cedc78e86e326d96fc658ce6d8241fd24b3e8a199b07f87acec1779695a2079f55b54a175fc3c79f8da180e64bfe8425f2982ace1a1957465057ec54b5a1bf0605e1ed59885d6acbc +expected_result = pass +expected_shared_secret = 09571d6c8ef610abfcf8bd96cfa87ddb363b9e4b1c25376eab6e4bdc58bff9fa + +comment = Random ciphertext +private_key = a4954ae56166253918a3f54097db687ea38e0ba3b0afdc0437b41f59d0c53969ce9b7cce09e4958f80abc5237adfc80aeaac3e0cf452c552c0851246fec2c2cdecb158a4b12e352cf2723d3ab6904804278aa735dd9a6b45474ab5539d5030ca132a63d46cab8b66778967875f0643db8822c033c351c1ca07785c24f789a8e03b25eab63e848b9f9b54993abcdab2c04740ae2a5900ac2572f6e1b2fefcb0ec174ab6a703fe2c5f082a988e598c66665d4b5000f422796110be38742f965a576c7a2ebbe82b239c31a7c7294f218ef7e386f0b16f08821c245c3458e2313a0c79a4133b4c3a0e8cca0afed1824231446cf97e3be79d86c083d2a39e61546278067ff497a0e471a3c4c2c4bec082e098b0606748f4f98b47e5102a0ac4ffda800fa9151f97c3ed11c9f6b0b4bcc8caf457638032bac35b273e0444785568f8389277281fe514840748469d7433d6fc8c37d00971e22eb8998854b023b70c84b5d2a0a5b266ee994625846bf295bb215b2e446600131b489bb45af6e0a04d6a2bb82354f1fc757af7b97aca689101476e52a632bbb08e07b7fb5664192b85daf6827e4a6d0304142b726a98b014e2468ade70747537b8ad1b4440f401af191cb80274674a6a1f937f68a25ba6534d68e52ec7b91399809bee85680a65c6956a5408b9b6b099c18af5cefc8737fef3542e2029a2157fae2c16d9c6256337584d646a80a37eedd374d573753ea3036bbc5549e940cbfb2911e661b22a50844416d5c92d35d07f3d0929dc800018d69757a5b15065a41fda53bb8a8db930b5038c71ee751303d23ad3b08bfa373b40a5b05d4b88001caf03411b4fe594cb7a93e14327b9da743cb9a11f999513dc485353a85e50a726a64ba351a0678b169bf475988019fd75707d4407f1dc40f93a615d1a2481da17cf1976ba6b9457d1c76a82972b7ab1f672963e1792cd5383f39163b182cb2e225b8e145bc10b01029697b65a80edb51612d5cf12f74cb88881b60cce5116a4898376c005c9dcc0bd206ca02087885aea34d92c7286853ccdc732fa2c399ba3c0544b86a6e0287d621154a901d43106b4ecaaa573b583dca7728c7d859b8369823a54c13a1220cd500c14a1f66d4d28032b9b96375b934d1739a5a8616a869c325140ddeb1ef0e68f27f0161ef0716f635a188786d74a5605061f41d32b8d8b1c885391bdfbca6d12cd406388617a35d69a38ebe7c95933a6dcb329a29c63cca06d29d1725d8b82c6c5908f3a67a09a7fb5f4cccaf51a822999f47504a00122a917883f4aa48858709b197c4832ca889c206d170735f733b21c6e40c3bc53d74393b10231ec4a8c624bc1c92cb1163fb2fac71b079866386155b16cb4f5934901365041c5a01a99cb96517e727914f8a9ae968dd2d758b517b07fd77a15d74314464d07651bc152c0753211589612dc94b6bbb9713943c95fa16da63471d733a0ab882be036b60ebcb24c146705140275093212c19a8644a47089b8e710b4329988d3571706a7b6528407596985e8fc7812146cc2f9c1fc7612dfd50ef060cdc3f295fd483928a301926404d1ea332e346b9a59668d2a22b29087f20a0867152307c4903858cbba5a7970387734c93ac14bb5dd664e67f0685a45221d031d8886bd2ad0b9ce079262801ccbba0123ac1a7bd9c125aab436a87b692350e2353a18b060cd828beb0b164702664a883b83791e34a8350e7c3984c4c44f8a48f8031a608708510275b7531c7b91cbd46c89b037b3bd12c39eb6a412b9a8987625e6d143e29085f7d49395924db2701b78e05a7f22747ae505e1ac76ebeb0bc3e813db3652d530ad8449b2f0c38b866088b4c20dab53a8a7a9caf6426bcfdc8d9dd92fa8d0ce2ec7197226a2bd3635dff75dfdd74b3ee8c91250a7fe387371746f38a707e23956251aa69aa676fb20ad001406b426164511bd7b8003f4920cc8ca44684987ce51504f059fb0789a5d72300f6c274de4b97f11a3ce41c3182bccf7353cf5b5b21d84159caab6d2b56f2fb844e7745964a40a9d2a1c6f65a27d331dffc635dcb2956110605ef230537c6236b5a31ca4959efb8720b42288f76074f52454d88617041f0f5837495c0c2d187dcf09b03f733ece299506ec4ecb8820a7ac4c06b1bc0b5c83c6664e22538172b94bd5362c14052bea439a0e05af854a22262b75b8a5b4f861c4b3cc0dca25978ea7cc3a7479f65a176cd579aae9b96356bf46f2c40b8c08906c3635a8028d7556fcf17006c63ea71b6f1672a586848d96e04cdc071dc3a49987567784282ebd86b6ae14b1c8a0bdac9840ae78bd18633aca9678d940939eb710806c96a13268c07cbe14f3819986a6f1400156bcad1e8514e0d12fa5f25d794605fc57ae3b9a6930595d9b569e67f18a0f66491d7856fbbb5e395b46f2093503018df1bc4953665488ec17d31a9afb8c7f8d8c980a83a7da7762a1397e79c9397345c5adf07886d141054465f1aacb55c54fe5cb2b20222d8f445d4bf48fa3882f11d8047e1371851aa60b740ca0f78081b0c05ce17d733a948ec040c0fb46bfe00396db438689afc4767d90ec1117f98bc9b2018e98af69620b4b59a7e67a91d4615d796591e6252013980d33db600a1014c9742f536aa00bd7bc037836272cc9c448801171c5aa624581ba79bc047182bc8742f4183887944f85cf7132c6e7089f62879ef22306ded1c18c987c07e96177397e4e277bcf1281bf3bc8c2a8a8e3e16fa79344affa8fbb5aa25275bd88690b47914e878123ab597eddb834fb13c18798cf6ae05bd914cd2e613548c14e5509966d958d5f556b6a2a1aef3a93a28002c86516765508ab298dc3ec72ae527ea127c1d9f43bf3818aeb325192db5a10b67814f108fc820ca388c286b1602d4934e025846ed5257c0b0b380c7fce0c8955ec06b7259fcd1aa6b6814b8dc5c816f434325207df5a33487632f707cac40a8e8a7a39ffdb7f8a70aff5950b121c212b296ce3a38dc306544eb7034634a49aa4b886c78035e56775d568592bb5a0833a8696537b8c5113e63584b3659d428caa22a32b79a63025744e3498e79a990f8a5389aca3f218205e1883e31336db03a757ccb261acab899a013e0a036af4be9b0bb134168dd4841ea0565f4208a97f86ac6a3a7745859d12e64a42c9bac5ea8f16ab24e02823a30120e0572bf28819d6123f6cc88cca101b63ea34f54923afb3985dcb4b2403c5bc028fc4fa361f016aa1f6b55be9c3578640cf1c94536869e5aca1379c7ff2e56ccb1c169afb3926326efb9aac18f9594cf0ae27d61428f0612d82bd1a2c66659a63da73b5630380f0282c580b7ce23c43e9aa8617da6b0804502470c6e22683fa60c9c62cc33e888e1ed433b8f55be56092d4fb100de64ae12a39d5c625d671aa239616728201df981265756c9fcbc332063ee99b3eaa92c6078a55361741a634a2be38815eab21a16a09b43c70ed18bd8b447f9906b918857c798493b8583c22e53e93c878ace15e30b4c658a798476660d9a96ebc91c9ae68ce1b2311c5b84e1f9722a8c9a3df61ac13d48afd3712b31a7a9da5c18c40960b4b3157d2b9b7a7414b04a50758b45d0cc2157556c2509547f6a513986714ac9db093588feab13a0c06d8c92139d065d9a60951844bd7340f7c1453735c28d7458790b67eeb520c9e70038f50185c1a89262a013407012595a2d8c102faf19e366c40649c7bfd432b669a1571326ccb363720c23e075497ebe24cd9d6c785e651432ba1a25a01db1c47b4514b03f89532900e0c13c584966b6e59901f3a0fe2c19e0777c4ee7409b5689c62fb9ff18822b9877f7cd26b9a71299a32a51cd564a959afbec91cd0d4cab6c2025f08515bca4d2a70989e0b1e999a929fbb5c5df3020ea34e33a721920ca01fc80c1d9090e819c2c556c1fc5c593e3a773a2b131545196f6b2c19681aa63844bc0a45951257de86b7f02aac8407192d040b8deacafec77ce36474901b8c97f2cc427320ab9657efc00c197001cfa72b0f5892a4f253ea155c04d5b566f878323c62db43c8a0f88bbf1a255847be50aa3925ea577b227f450b96f7b764cf32aa86020fb661521c526c3075b1027991fea2be796374f7c86088431c4191b965984b21b9a16ab4ba2286975e1842cee45269a3554f2a4e62ecab3b4075f5954b9f895f6bb4556a330bee8700799b150063aac8772a3f85b660bc4756d1afb238b8c9699a9d100f96a2c406e20b66d55ba222cff3390242a66685f62d4da3260f22a6ca95ac66db79ad123e9406b71ca9c4c6881810177f9a62070f3a9a8cab6b82f6b5f7836e849852cfc5e2aff4c83bf204bc475b4b87f623e87dd0f84950705ab4b860acc212158af1eb90fefad9915d4c89930c2f9da7b61a160a30c54e1f4a74337399b0c5755dca1a9cfbc7ec67e2f9a2746003558aa47307399416cbadee27fd0db35bc7a549 +ciphertext = 9c0a52bf981835dfc163939bea10728635e3e519077d1ff0d74913bcfd729d349624c04426e62da4810aafa074a53faf63c6ade5dc72d993e0ab07760f68555125295192c1b58f17ebee6d54a0f5811e1f07a8b764ad64cfa33d23c5e1ed4cc9162c871986230288f1b382352a4abb491a9dcf4b4e65e0d8946c49ef1967f3d5850f33a6030fb19e697a049231f32d0d7bf9e9ddb8bca3ed7854dfe79122052ea026e69834bc94d20f8446351dcc6ac7d752928416a90773faef9a1b64bbaac3ab43e144f8084883992f7105ad79517d7e700d35d06950a9b8877803a797d97b8bab85885fa9329de6bc3705dba53b24add6122f4d01a574438ac243abcb6c2eebeebecd7337f585b080217607e42f26174ecb3df54e87c43c13658f04d6684dbb40f40c7bf98b2759aa5fd31d720574424352640e195e3532549c7bfb5acd26234a16c57e9ac4441cbb59ab52fe3e6c2ce9afc46343568a1ad18c4758b37da1b5edd68508409aec1524bdc3c8380cf3559438dee92a68746e2c5241972dd6572a357f9b5d2d5e855fd522f5cced52f25eb4fa039e8fed919a9e8692266f7c1b2385e24d7385819df1774e5d32fd7595b153300f04f0d2fc9fb3730a52ad49d38961d856ad8378a2eb16fe7c8002ae6fc11e076d50aa55ab432952968a3738aa6371485da0093ebb359f9b4b2027dc1a4728fc866e2f66f1ab8a437a223b2629e1df8cff41fcc23a6af4e71aa61a3198ff798193a960df229cc1e61727e075084384b535c956879535139113bcb6f8d2ff83ce4948b6d2ae41436f6acf2660b55c47c8d5dcdcd457da821e378ff72ee42657f2f416132e5321b2839c218c2ea21db244ff5d2ce38f0c7f8cb628377930338d1cce8a788f4f2d9a4c9ae4485cb156f0701de2132f1ef3b05fff1c972a105ed5073ffd1f51520a6de361716bce86389915b7460d23c4399dd0e6d30dd9f775e312d6aa5db008525ce9ef3065682e5b3d809e21578a8821de7d559e28eef0dbc085824031a762e241b75879672000a0b115d6d1d600c1a6c537e94e3a7d8ac8a6a570d48a86505e51210b98b00ba06d79986ab9e4254574bac1fb32916169c4c7349197c8fc731a8dfcef31046c2608508080ed5c9ab64c832468d517879860f62d65f52b19c3e877c08b5857c64ddc0af4b378e0ac65a745fa9e7d79e646132b64753bf70c7cf3c0d5b0deea99e27ba3c2393fab254bbae7729ad8c9047a063721dd062e3993c1567a0a7890612b5dc7f08b5f54dc5cf934aa410e94000d6508ba22c099115a53e6c64c95e15becfc5560ba96c1068ee52f194b7fd2a605f6ede452e8d99c660ec633d33ee5d851bd1a495848554b1c2a107c7072609ef1d88c10fa0542586c2423e40b8547bff339b8fc92db0902551f26dcd1ba8a8708f5717006b72723a8dc0b3b1733bdfa6ea2db0e8699682675a5ee8214fb259d33f6c56c7c648dbf503d3cb744ca7a58fc8e85257a1e3e4bf1e4b39bb2d97a3f80af7000a3b6512e436af6b5de59fb5c57a0911544a8def9e1d92944fc1b9b057695ff60c62c4d853282d33c189bb4454a0558665e4dff3389fc5841131af71e82338877c87491c1d89369726b7fd1d0c389105b419825b8b29033a72034d01f521b2ad8432eec596013b403a023f0925f211783899aa8deb471034ed8c8a1a94e706bc1b6a04ecd9396e63a3f7e9fe3fda8e0dbab0c571febc7ba0e890015480af94a89677ac8de00447424cbbcc0222450999fc7c6f21bfdcd740163b8adb16360fb53f65c87616f93d1a342ac828cc6996e2303a6585e8e44b87bdd5375a4dbc44cce72ec05371aa0f00e8901590df6ba8cc86b54f887f1cef2ea7f96eb11d04ef5bf831d88e62b78158cf4f7f1d42fd3973753c7b59a8555ee5b2a756b0afa60cdb44e34bea6731a6826bf120627660f1783f8f646d0456df101373ca12b8f393b66dbd33f73c3db0ac80fea3fcc84cc3719ea80994e1593d8987d558656ba76a30999870d1fc2b2d6c78be7a25322e68fa424a1e5ff23142b6401b44c13c844207ea16962f80e23b2b4733ab32bd95be7f7fb487528ad3b342c619a5a71d0244332e95b53fc33b466f18fcbbfeeb370b3dccc6056d2d2efe8c4fcb671c38a8c051c985ad0c11df594f422110d57234c60bc30a47a8c8dc3da893a36869dd8bd72b029a01a4157c82847f45fe09705 +expected_result = pass +expected_shared_secret = d9526adbec8118a81c14215fceb333fa396f954c8f98984160adce1e86c933d7 + +comment = Random ciphertext +private_key = 31eb78bc2343746c647b74369863467bd0acf469b7559a9329da5b2a9271e4156e485374aa0c7e5c819646151612ab91b9769f6eaa04e2435d3d612f47f6b064ab00c9a4520c1a19da85543476c81a7ca03f5b3ac58660261a08033b0749302209490d7837bed9234723d778d52363643ca76985876de04389e67769b84af8c77a8a50a75714c52f07639ed335a315a37311046d18b8073090e1250ba18b536166b2c08505dd5b6e116a1946d2a2d943bdec95b0270aaadb709f3a094d21624d64e74923d943d6757cdf0a7a4ba261d9586a46c6123cf729d6715b22b306dc0cb740aba39b40ccbacbb6d7434afb423c7e5021392b3cd658a2bb93b37ca2957106bd632c06d311c583ab5660598ec160cb57a1856c6691b9f406b1c9131e737255dc9f8493b0c9727372a1521ae81a447a4aea7046bc794db6990982e951807315ece369745a0df4a797b78b8414b6c8fe140935b46a76430d87b04d231b99d691cd8b8445a1569a69755691939322e7648f3b3b90b543d0b5618eb812cba58177ba60acc3745da287d7a32068565645d81ba8bbb713c76c47594a30d88989006ac12c0205b36049832423f9a5b5f493dec9c4d11cab6218a215f24854ba8c8c01503e300e9ea621e342a8c7f4a1ac930217d347ea047d6ea85d9caccf17686eeee7c23db247b3b76b4fc5066d1a81aa68222dc12528cb7e718721df7b05e1e0223733c31d0aaa565b8cf63510b531304cf42783830bee6aa1c74ac8130398493b930dc930acaa21fe914e666b68b87139367469f2c01f79b59418b31c74a8b3b6272b7364b4843143772295ed1270d1b9ca306378df613304b57be713bd3ab462e0b17d3f0559a56c4220f01b25824ebf351397dc27bf77a584d080d10ab07986bd2f7953e38982d9c809f6da51fd609ff303c30e126893ec1a3b4c8d0819c8701a53d384314e4825c6d660f1b4b4cad92f5a88135202951aa0c8ba5b71115aa5de6b2287e8010f3b069b49087c82892c829f52d75cfea7095db0236656054723ae189920de49396f5296fdd671da3459ced940c32c818d11b558c2a121d55dba4424bc96c67a44a4728529f1a5b31d8aaa5a632a9f98199c0450c24c742aa7123071899cca2b9a4115b644c4216b0f07acc21a72201beb1d7be2bdcf929a728a5b9d7019b8b13d4e77b5c716bace71b4ceac25ee09be79e10b36c868ff325ced610e8915253e3279b44500af43640a09b588a3a0cb13484916ccdc8293c8f60062f51f39d9b1f0b74dab0711434518be90b73bf520a2948f07f37660e529e0c99c9bf45e38a8c81d57c7aef15697d3454c6033db17319e787f9e1c6741b90fea683cf447c9a01047adf75f8a51cf6745633c705e56943162b37d236566f321692ff15b301b8d9cb7a736559abc65a539ec60b30661e623a354752873833f2691206eb48d5fe99302fa8010552916937c3bdb1606eb23a58028e135af9f127da70277ffb98674a70cfef501fa236d9e8781a11c5ff873308d68bcad919bf63a1a820cb274ca075af6849bac05c19a81a5e0974ddb342535439bb00d3812749811af66b438cc904c8e38748ffb269f388dbf30a068c1b806563618136656080c6de478b110433bc416d4c49c15549e79e37eca6c9156f66687fca6fb091499669214e569173b0b59e44cda6c72de6875f18b649ac05c1ca9c010e6bf1201abf24456af46bb9ed6540f1cb36b8a65b85c337a5639db47867d7aaaf6e97bfdcc77a0261acb501406b17b8570bc2304595b3a1f4240c60be9767e142538996cfb360e63e81b70e8829cb4295ea467b863a2a4f808314473353b77fe9049c0e2249a080ebe8328f5e5548d639c8bd629c235ace3f2628ab245334538b8332dee971fa1f0330dc86379bbb20b764774e78077384f8f43804121a459c45823b076b5a90324c258affb246b25a1d078ba0c1768d179062c99326937bcd32b9012d179ca95098119a19b621fdcbc71b4a0646197722a7512436848fd54316a71705b60b0b7ba3f00b7663fa040a79b0af311047ed22768c085a6588c71d59d130a20f1926d82890a8d037babc81fd9771a61cbc1de31819f1726ade5c589522e41359bef0c68a69c5667a487c1a27c7080112a9c6fdbca7e05f406654b91cbccb979e5aee7873dd5e82dd607308ac2985e54864eea0daccacf179135b9c1402b631e93cb966e75b3001345723c127988630dc8307e42bd3f717c52c9964bac76b8a709513c8e2c451cf441923914b0862b73494018be0a7e73c3ba0df741180cc135365a76a69568b70ddeba7de2362431b6795ef38c0acc978015bdf08b0c7f116a2984a30d87602e3c205fd597bcf20055f8aba473981aa755189909e2b17c262b38bbbb6d7ea0473dc357a43844aa40bc4f888cec4402fb52a5ef2b6a23f81762369b44343113d397ea3468b000c4e21a3e5a28a58aaa13f663a6f12959afc363487b80e78bb7e46b060ab46b4bb458a6b8bca94842fcbaa6bd7ac51efa4a633458c3a59d33f1700a7bc5b1614a2598a0252401b1457970819ff7d38b451b88ad54c4ef6698b7088e83909423e3442b660ad9280c3218c667a622ac831ffaf274b331cb726454bd63981d19be80568356d4cc1a74a5ed24617116bc186b750582885b82901aa521aae080e2659d2fecbde15a708c9909d01b55944ca996294d7a09781ecc67f2f46c775150bd07008733906e8b7bdd2c37ea5546b00c62c0a05ba7cc4a9e66634941a2e6d57732a60aed6862526c78f1f33c72e8aeb276a87c935f6e998b7f9014d4a700feb075cc2a4f99930a3923a7a7d8a529a32eb6ecc8f6a3ca9b89079a70ca65fb1c2df14926b8600b4c533170872681447fc79205d13e91c2cecf2baa48279dd4b4609cc691f07c822654544843afc6d62da790c9bcb94a079b1b747673a63904937575343700033b22b3473107d34ee0227bc22b7e9189702ebc19c5218548a5ca70537da9b17d95e34d002312f323a48ed2ba9fe53a5b43236095548de1618dd56f311bbe1faa18c627260b6b1c9a8862678212b9709d2645aee05872d5d8476e70c03d853f687b908fd16a49165c9b899758178918253928354953438e3506734c862f3aec208162126f5b92fb83947d8348c653b33f75c30fe42e572557611147fc8237406a78b1a787d9bcc3edec99822b7d126ca74f041ae089748c2879159c3d3ebc18133cb5b44b706ba4ab3dfcac0dbb13192b05a6b13b2c8724d1e2c1918bacb002365a2c43ea577c6ef8cf8ae97621eab740668bdd0989fde4bca7a74f1be62a7c78c80fd1b6e3ca2ee4a62e7eb50f4aa067e6c10ff10057c138a9d545b78dc224320534e4024b5a8922014ba40852af32a99595a6c109c3936c521ee68747aa2139e03cc822fcc337c1966e1c3871b5a625797c0dd4a898605f64e2744056404a80b175a7101af85fb4012ecba40c134c53c38b58c7b5a1b32ba0f7d6bad375becdf6805f9c0e0b672dc5c01b1ca8b2b87b6d29822f3beb1c14553c2c16355021b7ee8a5b762cb7f0556f804a2ad57ab08c7cbcef40725dca39cd9517f9f54612fbb6aa411cee2692283603dc0469e0f5cea7c657daa31fa9c28f1cb07b75f469c05174e444cdbd056915434c582781fc514231bb2bbd3a946925ae36382988294d8261c98aaab71b32c64f7b4b9df5c80082971fa7cd0b149d2f8a1af322b02ce6a47f8bb4383084ed8672dd487a32428e5002193e4c1ba3ec98bcd5417743caafb4797f763c4acb411f847b45b1cab607ac050b6c800869fb3026b1174f39bba98a41260eea35a3a0655ef66ee7b0c5b2b8a93f0a03de8644492ab36d5c0198f14bd58cae0eba58190a89bcf7a786f85109124875eb97e26027088534c7d386ff325fffa146ad07ae9fa1bb66c796f8a07f6978b638b483461a32217aa41c960e72537b17779964e65633d08d1947420744229ae06b740a4c8425085737b967b0451f304283746a9a2265c17b1413d91ad1423fa79a990f7c2669a62b2409cfe4b3989bc9a733266602c624e1e353d5e529968574d49998ec825b3a6430de3358e5bacbc729ade255a1f92a5c56cc4cea5c2e78ba1343012ca4e778deebc9be197e7b06b81d24946132128fc14d1153041e413638e95a609009091c6074658ba332100e403ce31380b911c4cff98c8d84c49a1302730a9494d77043ec2904db9b4e10ce60253083c5b7affc2325ba91d1d56486894d51801f2f792c3535a7ac515a06b81860d37a4214b7f2219cd22844020652d2c5ab7391706dda9b106b1265b496fa3870ffb41309cc73f6db15ead3743c58ea866e565cfbcc05338110612d4c3300f667610d657350cef190c4c27116e02966264ef88a9043dc10e4dd996358f565f225427f6bbcb3658c4615a37080817d97fb451d12454502026570e72bb5febbaf60623be8151e301c5e57d26832 +ciphertext = 98a00b988bed0cbc9a9358c8e62c0c1ccdab06dead794726b4f744632dc36a76f878b6f932261ba2bc1481b0d3cf5fed40e083c44c3f73ee1851cbb660d2b41ded9a2baf8f2ac4fad4f6fd91428a8be6d2e5dde3e4346408b753d3a786ff6dc78650337d8a5f97e496df7435c2e890c4b8024ffe17a8fe799cb29b2c24af81b7ef8ed5f6a83927fdb99c2d45fa57a5843133206d9df90ee0e01b0b81e6c6a581873c260a38df508968f6220b0f367992216a9ae4aaba009284c44641434d76b9a193f4b16b50914ee593b8e25c19a98195bb9c5a2c528755ae4e3b6180bdee40ec26db6a3bfa406dd080f79eed68e447cf36d64fcecad23cd26e6880cd8c41670d2361417726da084d2effa5ab470227439a3c9c5065ec1d6e5d0bcd03ee5fc51c9318cbbdd57654f93109577339840eeccd2366487f495e9f8229b559d74f0bff8761cc55fe85d6f622f36e1dd42e3b775f26555d5b22e550706c4d1c7751a41b56715daeda1342ec3e47dc83d5ae563ec0988ba626dc2dc95d676322e6b35a89b8d51734e48a686a73aaac53db01d6d01951cf2e0ed9594c23f93dfe840ba17735f6c161440aceeec4c011e07a35edc5c9172d620403f797468fa62499b0e4a065956cc1261d08affcc754f2a93d638d821d76b307a154cef647c99663955c02349280f7f9a55d06945566bda40a541df9d9241201e07251f54c3e7f6250f9fac64eade774e6005e8200a9351add42b4ff0d0ef98039790949e6ce8983a7728ef8ab7f8c955d79c81745ba249300665571ce18ff81f21b7485e3032b7e752eabd6b6813426f19895c23736b49674ec152bf214fd5d759bdaec98b7fd46239f071fd91bb48fec7ba700ae25d8780664630b6f5cd8c3ae0fcd6164ee11254b487ed5f90a1bb1b23df5d5d02dfc032f0073b144d18f0eca02fe04bafd235cd42c7d7d0bbb8dddbd5c986035846ce9314b51c670e3ed8978d9ff8307ba73141ec99de955ac0f76e54f5f29f372e8f2737ddf420d96207ed9d022936e11685e16e9a081e3f3c38128446fe2a33934a16e02f7605b98eecbfb110aa0e9e8f1ec000936513809aba982ab3f143e641a6aaf5169c929e8370585f1dfb2b6432327a52a4f61e5b807dca10e6ee7c9e7244baa32388754e7b69c4684731723fd3f913a14b57091b0889bcabc79781cbbc387484e18742f6bb67116f54b42c7b78e7ab8fc2dc52bfd3aa6d6b534cd06ada4ad8b79c24374f5db79340cd654f46753070866cb0ead62eee4fdfe551f7b612e97ca3941eee1dae9493b4970e405c7ca082568fd9c1d8cd1da761d5b3353dddfd114969369ea1544ee8be4d1ce48edb61447be73b286cab5872499e1138d6ecf62d53cb2fa6689c2ec1b8e893aec65dfdbb951ddf15eea93958e74a2e48bec0cbea9b6c5a1b75039bd09ada8c2a324f434f1aaf3b741171b1b972657e6e50126af9af8702e961c543459bedc4d4ca3b257bcb55ec055099f5f47982f2283ea3313949da27c516d7ff52e42aece66dc57dfc544d5785559b7cfa49ecabf8f8b43d1099768f96d4e6507dae943faefb7f85205ef7d12ff508b2d43072169c6f8ba4913dc7874724185d4efe8ef3a6b65b6acda0416d569bc4f96de3583d3a2f1969bd7fe30351d9ccb3ff39bd3f7c55a2125012f0493e9e84f323f4f918c8a490ca45ff1339215814c26e0caf9b431d339199aa2c47ff5417b461feebf15df0dcc94863bce27bb0e2a82e6e693b0ce21235e4261a926b29866184ddc3162ffac3a4e3d7090c4c857937b3287ccfce4f9a12fa88da5495e67834026d1d573f047eba7e16e75aa9641f26ec24e288603e7164c52daa913359782ae0fc5785795aa17a75d568f8b9772f3aa8d54fb210dce8429dacedcd53f4e6b7da5d6d06f846eb7cfbc2645a16417a38e1cb0e5df68b03987e32fe7e2e78b1a41f9dcb138e68c41956d97755f4e12f6933ab43e0460b4feda7b350ab20094237f839392507911bda1cc26829e176625e7c8731e665eaa5e7ccfb4cfe97efc548a1d587d864057cd682134fc03f302f4da29e38c98e6c8dc385731766c1dd34ebb8a25356ba76c717e69ea7fd766e0ead57cedbf6c1946a37a005b5e92fdfd913adb5c63387ae68e361a00c2963dfe80016b7ea70ed6c4e85d234b5bf00ba6bb68b73acffb1bc84206d62260ce4841590100078bccbae7b2c52698 +expected_result = pass +expected_shared_secret = cad9040e83b00790eab32604fa0ef20dbc6c2184f10135253ca02839bfeb59f3 + +comment = Random ciphertext +private_key = 4bb151854bbdb0227d75b1c58074c6b0790103c2ccf0398de2abac68cacfefd00b5cd905ae70180b31ba12a9bb8b6a03db94390110a1ac263a04d8511a4930973b16fc16a50e85697a63180f41b95a016c665235f987cdd0659bf9795f739b6a25632a50e94f7bdc925040ac8595bdd3d58f0b713cf9317656a5ac6c635df162c13c8a70f997c49115487a2642d571288d9b2ee0e68ad5788e41bb0bca464f66e59196b22317f77f3b47706a86c5be90bfb18195dab87836d48e89e63b24d534efb174e4204ce0c33226a02454c9419ea6b48113607d1289cdc6beeaf77a64f130c8c42ebbc30d02b726a19489187926413c1e434556a49a7d7d603677e2046c81aaf54853bc60872d0793f9e220dde38f5a680991ca705f8588234752c969cfa8434238e6a2934651cfc1530ba99f4ddc515059408eb68f95c81e80e7ca9c0a699897262a95bcfd723212e74cf8fb225a1627856a708158b9763a7186b6475b985a05e965ceb1cd8918924479be0bb1297831cc1a5c42c6593267299db891bc656cb1f69c2092c0925c7464e22458ff1b86e636a2e9778a6be68448d2cc43a89dff0b5d321004bae37f30b63a92b4a1ac29900fea0f4357bc837a5e9540c32344065cf04e16cba0f8647a2daa58b3631bb72a1335588bda436a3826090bd8b047f1968ab68b4e3268e67c2320cb43d63543e448279571a2b531cd73baa97cdc1c7c639c6a66aecf5acf0461504e45605220b8ca797861ac5f5d77b90a4200acfb1a2b6656eeab002dd29c7550935562c22fe2539538cea2a80abffc8576793aac765916c4356a17798861a108b147a2cb0c4b1210dbbc4a357c05aad1ab1a80a6603474b2e02dfeea4accd02d28a8682f6354784179c50c255dd48d12a297ba476ddec6c976b8a34fb42d7618c515b338bf5561f0c64eecfa1d10c4ac881a128988ae4aa090b8d33178d4bca1017ff583787dc88471796567d90c04b47c3c083abac7925c5598f1a9acc3277584c4cd53e47c5862cfec22b0458992574936854862cb28a1ece3ae17875335a90aeb4243f3594f46587b6fcb0f468bb7370b5745626ef2449986e17097f8509d7c07a7ec715033a9a121837e02c64d5404518b28cfb251fe1b307664956f0b69beea6716826586ebb8c8b853de4325d93a0e332a77bb557f69b885b3a21b9eb51997174bfa3716820ac344345d64e2358f66cfbe3a41659bcfe7f67c89f90e9c55111544549ef0cecf2128eb2a691733c7dba55caf398687088d4518b4a8d3a7d872670b5986dec4121381b8f9f5a9e7866ad1e3741c707b5586cb9ad5148b67b147754c82a840e6701d2b6928560677230c16b78370c4c98f3037bac357b69c2cb051d2cff8f5941767768de84cd67730f9090bed28ac2d30c5613c231af7b4d0b615dcc9a3bb139b9de1aefba5bce646be2386cd4aa1ae60971384688daf6434dcecc68a349c5c3a08f4b473de70233af3c915c14464ea494af202cb950600b249d3d24baf260187c649d0b54352811616907aa69ac94269647f1b29edb95381c22edbe786744547c60cba1232a018893e241026b981c890580019296814f57c3216a014e04e95f0b087d1797edcbf126b2bb98b8f5c004eb691bd33b72ca0a9a22409beaceccd07c28a61d1778c89c26f66716ed4afe2e382c67788a70349b4a192ba078c4fc202ea13812af3b4d53cbc74507e2aca4572ab198a6177b73748b8b7cd8f650a0cac04b69b63015908d7644f6e34cc13d2cbb81a7d4e68cfae5a6feaf18e6ea31f8c180ee5179c32fab28c7290566c131fa614726c74bf7c63a25721183166e0c8ace095064ec4600e962f07e70bf8065e5646a6fad903516355ceb92188262e2b5303528c8b721b447db145b4185a28586440b77f635946265c08ff248dc873ba6ec060467130ba57c4531c4fba8706ad625392dc45f391b499d3794500bc34d7b5141b7f68ba48c32b3589ac54bee0b811764e925643446a6e35d828c852bcf443c88bbbbbfe951f694937ffbb2a88809af3547960a62ec24a64a9aa6d2051c819615d724c23fc4727630288ddc49662f1981db8b7837ac1f3094b10e2841f46c4102b967f7b5f6a6096e0f8690988bb7793313815188fe8cff8024e6582acdf90143499a0653aa702565d5956a1cd94b2cf071a7f821e5e74a9532b3c98ea2c9590ba1db47956f7c9df8b29da588ba5bb916be5957879bb18b9bd118078e1c46372c5805bfb36c401029041597793b4c874517b568a0e48b6844b3c60f9b66a45ccda4b3d8373099c7c2e24e17471c8549d22b232e83b80032453d8c1307333e165c92e9c13dce5b6479624be123fc8e507b7f3cde476ad30e934b39896a582abd77296a76a82d15bc5da79571a9a377c441212d5601b9707eaf220da4252695051c802aff95753223690f2910d9ef93de73a2e941ca1f7114d2384320c9c36c9ecc59f503b91c38a819cb2b089a6284352e2e25d09168c3aab6509c4a58b0894f77cb3c144a702f395c9007135a46413059ae667ca7b5b31a364a567e69cbf1300b8596ed1f173f94782f6b0b13ca047c9f0a254676c10898bb93744e518b9c26c589f016024d2300211c7911139547163e52530f3f0219e9508aeb215b373a17451cb91c21241e8820134b2652013b240202a425a61273c16381ed2f7b55339180288b59700564d6a278faa3ab8560fc665af6e9761d8837919c689c3174c989315ff456de8627e149652d47b95e102415641a148c41a56a914fd2852318cb4b30ba7d086198cd4bcc1f12c526602c3da71b8075d0570650b856b558a30b8d643bc07498e9cc9d642bcaea683aa11729af461f8577b6f61bedeb90ffcaa5dfe789e9c21a3cb51964fe18a0e7bb2053289a108be9da479abe5c5b3b7607e6899f46a93dcb9982f7a4fc5288e5c125d8805a15c8472746c5e7885c7d609c94492cf11e45a0bab9d4a38ce87044958675e8554a21fa02997214c5929b046b89cc9d9bc30988ea69488c8f6a219727e4c39c2b6e26543373d9396cd82769b321a2f8b162d1b3737db96984ea35d72063e10ec23498728a0a503c8da61dd0a37bdc3ab6565239ab387fedc73de35406cd4ab47b2117be6c6f10b4e09e42c11e03310a2ac415a249558519642a22e2812483a90ec96ab0b33c5b946576fd45a629494e53128f03a480e396be683b5d97519f7363710e871f384252aba288b4b0ce4f6caf8f07d1e0b6ecf0b99a68c2887f49635e65752a1b3581c68a2011854a3c3238b72a420629dbb88fb58c2f368209d143abc485457a5724c611c317b6f1c1c81d63750f26b9e0cb131a89c2b2aebbc70e027cb736a74b6ac9e19b8a1712509d613d6d26a7b88c1a176abca473ea1b1ae032459ed76b8d849cbccd2ccfd2331275a008ed7043702826b821b3d49393f402c17f3b800d7375ff543576a2b5bd1b862ac2dab99aa259c198601a425a83566f12c6862bf50b05a7745a73b2bb66a86041d77322a9c2b775c65dd0841e7cb70516a6be83133c17449df98404e1576f9e90362704c876c0d83262d47b2a35e0092336c0e40c0b4c8b39d0c83cf603994c5ac09661c2b32e02eff89c2ad9ac3d42839a9578444f1aa3b511552359abbbac7f9730d2b6c74e04741fe23164860a7fbd9085b089cfa75adebe7c92c1317f93502be218abc079737d2b42c96887c161ddff3653475c7bdf4083faaaaa32c870617a796d55423719eb955a92ff55596772f42e79758c79fa414402836cc83f51a100c46ed1c4e95461ce98c598071914782aa290997ef654a9be27b7f817b6df311b64b6ea03ba561123df6a88005f58deb928ae80c0e5aa82b71f15ebc144826720f022295c2ec3d2a40643bdabd64d588281a829aaa055cf00199ac744b140ac4029a19f505c4c56df4eaac5fe79353189f67158c3f19294682216a77cab3f52823ec86e5c47d78544687c561458a608602b8e2489007b16aefe8730fccc857859ad515b9b3001546d59f1341487b11ced55a6d3f3890e1d3928d73c119da2d2b3b1ae7d6436e0b2f75b5bb3323818590bbfe51aede710181595b0463a10f628d7d55b182598a28b650d5c9ce419c3c81127b82528e96e39aa5f20dc6a981b0f7569690cd639acc5c949cdd9863726aab887469c83b5c67e96fa77012307550cfb12761d4b29be8c5bf26ba45da7ff6a4ca4cf8b9d313b9e303ad276950b5f6425f856d9aeb6b95a8281e3445831a74062c631680638bab5960b9bc94806df1d1a918a3747a8066c9174992c0af0ea1bc87599e3bb555c73831d99297c55a53ce727ffa6c65bf6047809013d5ede0d5c33873d48c11b11b65b5929c437577b30c8513973455a7a28a855d340e2941522e393ed9eccc764405a208624f0dd00abde6b3ff941e6595aa31975033db7b90529245319e6a1ff86b93ba4d8f19340c8ffac92a2d96f315e3 +ciphertext = 2e42fa5e35bd7727f039f5b4e3935e65b0e9133e1088aa52945f5c723b8cf0faa5991a5a29dc788042beb590a8aa6f8199e2fe6537cbfc668abfb79f7c7ee5a0983d3a5a5719567663defc772c9dfa6558a4aefec285dc2ffe4410c7de2956fe8a8fffae852710d540a819e2a886cb39bec77d5eae6f0863dc3760d038b205c21068f4e5d4214bbccd66b14ecabdf7236933c642f122fd4bb88e5a25338c5f4f78aaad683d21d453840d26bff234f8701f261f5d2e328c048946755b002f2ae5df6d86a07e823d0f43b808841fd0c04229f314541c5178e6f1e96d3a6c2a2f48ae5c2d15b45f31baa2ed0c42e81145ef7fbb9b345a29fff02e2914ec20a1ebaf6799cad5ccad08efe7c976cd37e3a4e3bd98b5b17d61d655feb7f364fac60083ea60c40e16377bc4b1bea1b1b190b07944017ad2f79821f0dd881cd81ec73da0d29c0c412923a9f52153a7cf71ad290ff670edac81dc837119784748383807696f2bd20d853d6da34a95979229d8fafa6cf3f3af15eaae61f8fcc83554a291f914fb2b7470c9417d7909432cca8b32b7f5195cdddce046cf9aa150fcc441c303fbe4d8c9b134543ff85ddb1bf6ad32e486e6415d083b102513960906b250c17f1ef1838c77ba085139b20e7b2139a06c1cb8c395f6bce7246ad76fee25fcb7c1974a4017af4f53e369f2e9f7545614fe0525e7f3d9518e330f83e9dbeaf4cd5653e5d466307a85f85deff93f3718445b684eb5d0044f4c6469d722c5a186e31c09aafcfbb0c6139ab10973d613251ccb33def17a6f3e3b125b5c1da885461b0d723efd1d9c4af7a70096ac7cee96d12e941821f8dc4ffdf25e36829111f678c46a342614b1071ffc366d2a2dd78761fc91e0386756a8adf38baa30997becb8a910db18b014e164a0af795898ee7049f8e943cc474b17b752311c97426a90fef44f9cec08c840d824d6e5479ea6c57e4c5dc602f71eb2c845e44b4df36e139d048b8f54211ac12f430501adf2664e71a48bfe9d2ba0883228e0d1b171699176af81d9171b49bb61ef87ec31a64a1a0b5f10e01f2df6fa036ae153c609a4ec34e443571cc345843f6429f0da9676db7d1c885da4383304fcd21f01989cc6b3ebc40911853888dfcc6eb246df23a660ace311cabcc5805f010dfb3a5fe5d7c6aa1a3456f20fc391d35ff25b9b9870b0b9e22a4a533c2e6cb685fa3c9e24f08591ed554cf67f7df403066ab56a10f0b8ac5c9a1396a4212717f16b222b44cadf3d43337d0251c8e457611927e2756f42a3991cc1e388ce29e4eef7d20da8db77b014f3428476ae5ab1e5af36c5e13cad8740cc2fc96776fa8fc2a861e04ad129d9c2c521100755bdd8797f98f2323f16a7930d945306c66c902339757539048cc50256d85335a7861b350b740ad730c71d9aeb17832be247b3896489169c3e866c081c7b108e8c6298eb76522bf2250ae328fa9bb7f6bc29142e323ae9d30a794347de4ba00666e721630949c63e9d5ae5cac6c195a8480e5e3c992d801b5f264fa1c148dcb094587e9ce37564bf15097b2fc649d840727a4a11233fe8067f820ad697400269e98aef3d286da3c06e6a454a93d0b18c709235e2ce361f93384c0fdc91a68b7406f503a1871ec38966b0ba4470c0513a573e958a843b0574c7656083e5152972c02bd1e6f8ea1c6037019399b68fd47bb0a8a0abf0bd1332f258aa5ba8670c34990d4ee6151c0b536d111dff02a435eab7e30864619835817fd5c2b43c89d3a376cb7c58bbe5c979e694ea97a16aac06df07078799c8f288e5884f32bbe5c3afac72e1d57d5638908e97b41e7000ff1f89cdc2797e021f8a929746ce8e8fa73d53bfd3b5896685e8db897f5c3a23b14105730025407972196dd7f7d9cfce6a0b7c502c2b1f5535f25bfd7b8082325bfec6d440ca1b91b128281eec35d80612765ad49e43ee136179988ba9412040290b828c7cdfc7a82b70862797f80646fffe1ff2938ef2475e5837fb208d99f1e635ad1af8d9edecbf5a8505782acc71cfb84b54b2cd03c6bfd8bca2f0ef77bb59a814e8aa784a1af0475b8caa31b57635c9537416268145009500f4469ed2b1051bc2a91f205f7b598b9cbe64b4306ffbae88971e6163b451fce9f132bbb1d626d446e018dde7f60cb6540ab66c51c416a22cdd0543a1428b5225a7d41749bae89eb09678e14aec7c8bc6dd2d0a +expected_result = pass +expected_shared_secret = 269df7273fae3797f0d5b5853f563e955f4139acc34f938bb51019d5229c551f + +comment = Random ciphertext +private_key = efa2a5bec28a3b309bba5110e6d76ad5591c796a8bf73530b4c13ebcb79751d8538c3a66f7a39ee6f59c47c5278c6aa82bcc7d9cb6130d666ba0e60405565bc151bd10e051568b860cb75fe6e26452191c71861d61f68684cb0e6c2500d71b7831806eea8c74c3806248e11a1c147c5f20aa9703c289e342d8bbce45ab0d74b00eb61aa9be7174cfe82c1f727194ba3d2d1742e52cb9714b95b053603b81ce74c7271d811f8151822b49af0ddc9c1751a8ef11a28fb371e8dc6e3a087ac2fc6268800d61213c9f0a0a453182a2d2aa2bdb644055806305764ad90f4d90b3d0c885ad86bfa840061a4a134b3901799c4789053e28f2547d8751c887a810f54d612b34b9f4ace9490d2495c6825ac2c930694543cbfcc03f29712ba61a10f1077144d89c7fc36670e0190f08084970211ca85622c3639aa81bb11993eab98718f35b431c9e6ef2b595a223c147aa2f798569b901244a0599d4ab14522761521fd1c7b9774095f010b466e0a7c990ac89971a5105bae3d9057c57636a7c0fdb9a032c30a443f271f440916b34603c4c3d22441e9796a32f1a03a9113dad47727bdb044bd975af3b11d063c3b7e69a306c4e58e11ffacbb6322975b2a4b62fc1b63c851f41a91018c85d41e4a16c12c4adf6b5582b7282d382b519beb63ab0f4b76a67d8091ecb8e5790a121678274e332d63161067bc4b432cc2905a6e84c18b31b5b25621c5f345343bb9f8d52b38e32595d90a818d2c96c0b577eea03e00a11039a4450803cae3633d05432008928ab3297a5045e9470017cab62549cc095838eeb8429f37b0ad5e261635a9ad5544fdf644d5b38201a66380e21608395774c538eae7ab0f545562c58576451532687310a34743a49329597635719516979a9fe4141f379882c69a4e2eb5f102c4e0b226589c00ecdd5bfdf2b5e56439d6d1a41200cc828742eafa092e66b75833aa2a6cbbfe7e4b0457c218a4022bfdccdb62802b291244fa6734cba7deb3c0d0a7cbda3cc90624a8b86e693d8443ded8100b81c138e58aba8429d1f7730a97b6ed0e5587cf842b54618d2dc451e5a94ba6bb397c8435e9307d2b2ce87a107e1272d2203b6b7632355033f49385239648c450c0f6ee4afb3019104d5cd84cab9fda3703474b2a850a8dd12628e5770f19894f8f065ef5a7886b597665404f98ca4cad1c00fc56cfe11071ab340554c7a2a56c38a515ba023c6d29125c8825874b61beccbb6c1600070d453bbc60f0790918aa31739413d98ab304308bb70769affc8b97989ba1066a93b82b0045523dc669b03599f3ec1363e835d96621bde02821948c7fba8139716cebb18c6c4b26c594a05a82bbce900018d07c3eb162b15f12517f0a5ba646a6adbc0e032969f62390c70b0de602d7e7c3ba125036a663c25779ab0641a9a1197d6037913892a667ab97a2a16a34ab3e90acc4319c2814154a764c25e8b095b3a38c32c2f244580451458c9a0179f2315b8051367c76684089694ca3fd42640738c8a9df89763b855dfe265f528ac757506ce2a592bf70d5b16c6a5a9375e11051bb93719fbb58433881c29ad37352e15a3a3114176547181a48c59e004006e31971d7760d3117872069b60199ade7659a03cb6cecc38c3b81cb7f9b11d77c22b42623887aeec175692a64b3581ce1be35cfc359ddb7689b7b9ca4ba700971c7410c21d062c4386574e93dc951e1abfbe0c5d5dc433230c73354acb683392dae279d739b047d6b9303895b8f6345904a18be0950b57467043acb1f45be1537d551c972d68bce024b685a9a81076007f685f1f146856b71f7d9c884a30167c5638763426944613cad4cef2a6865824a40a39af20c247cad2843f43bbdab8aaafd33a1b7c953e9571c3c779141c3f95631604418d4a4cb80c45c4c0f2a4f311367ad3623d54010c65337348420a5205c591c5c1aa46b2c2b963f803ecc02cfc0602067ba2f782158ec7bf1da10d8752a3af0a291a57953179c6d9328a55e48c2747610eb382d55b6d9d0bb1d7f94a462b6dfa45a97aca5c23a74cbc484eacc49ccd172a099298cb767c8af9599d628aa8547846f6005fa55c0bd5035f8673f6989864452c06f6c0aba46e1062835390bded200cb7acc131e895c0728f1b28944b224a8854b68938bc332a16a31130a821a803851bd791a8fa1098346380345c2156ccb2665532a6962be6bc5343bcce3615bf94924be0768858e49663aa37a7a55b7cd29ef91b86d7a05f18190a97f17607c71fc3434007bb2d0c1046d7d1a956f882c5f30678da492a52670f9b251db38b6c2ca2fc3785b693558e3ba60c685b89e01584f5520f744007ab81b51b1ac7da644c9012a0614c78cb458e351444c4687560ae4625a7e10a8fb83585c5a351e77c97133330bdf83253a995cce068904351e7ec3bd77b44d76c447011588624a3bf996e50640d1f9352c98953f646b4ffb048f699b3f8ec861f435fd1b88379b34d9e804b9a99c7525a71b92317c32c079c16b5d93b209709072226b41b4a2555158b3ea41c1d43761770546e03b2b983aa80947a769b40bbe534aa6cadbc7543c5884cef28964750128211b48a1260aa3a7271977293a0a5afc458b4ac057b835c68509dd3a07787b79b997b71b7118f6b03767070a89ab61538b8bff57604553064f2b2bf61127b60252450284a67747f1a0932afd9b5f69a564a64cee1478b596152b6e8b423c81539e3312b10901f599c2f88a45cc5a6614540de3174cfd283c157346268bafe752bffb44b391c72df545cf6930abed413b8f2cb5f79126d90240ea81e379159f86b583018686083598ccb7b65e471f0d4b9988457be35b71a779f3e4025efbaca96f028e22c1226f98b44396c1ee3cf399398b6bb759e5761ef1502be3a8e93898d214203f60bbb00d442aa426607b840ad00c64564bd84781db49893d4555b132688314587de67626427ae5651075c8c46368779f8028a9a3c04062946c2ea3e8dd72186c0c663bb1c3f0b3e732bc4ef906961d64375b946991a4e1b2a565e27326cb742745a4201f11c3a6213c0e7642ad7c6d60256912c2df9291765436235c8aa61809c5e8a64b0e2831cfc0d971714083031f9a996e4325e494892793275efa961b6e2710f746dbb190a85fb073de48dfa749f8e5762aab59d42f93232e1b3d8b8cd08cc5f3d7bc5e059538bfcbf01362f61b8113e356151384bc324b1faa8b7901183b309639e6b69bc384652324faca96b8a3662732698536bb92331b08a331cb6f1b444f28cfef5b09f3288b9b58989475f04e7acc500c88bb78fe9b95ec610bfe84452299b354eecc96a603ea682cec5aa33f2e38768a4bfa7ac9ca88abc2af98b14a2bc5b9373a869329d583b8010c3489706f4383936680fe32a4f311a2173469ea866047030b9f64ccc4d898a84494d6aac4c4bec01e4364edc71178d36b9b95c6f6387a45177254523012fb29ddc754a4b26c6605a72f0e81db34929f6aacd46931b6bebba2918a256fa3677e9067ca1bf7c589473e6a943cab08d9c1d32ea787f75a67891962dd8beb15aa037777d71d84c027b706743021246368653741a099645c6b422e1bb4de76c2b667a9bb6b3345b3edd36ca76c76cfc4474e6172f7f33bef9c854fdf4ab2fe27696072d8df0453cc04670d37f27d13d3a5687aec678ca050e7bcc5c7ee37bf1bc44a974438f4b9e3f471a42f99e7811948866c03eb957d23c3ddc16ba4a582637f830d2229085058ec078a8f9402d7fbbc405cc57e90039b05cce3b89854ffcb9e192b58851735f15b84f704dfbd0aa781753ee8612be825574ac4ae368328e573276c23efb18505690b46eda77ee16420dd572b7aa4b3d446dafaa58544cc7020b4ee28a56301a6444fa40852ac4a49a33e246c5d60233da19b480e84096fbc4312791a6dc83342052dc359a8059bbd0429090132e4edbb159f49f18113df1570d8a162df34b8ad707bd43137d3f64297e53463478193386c7fea6ba22548c38c1a71c2222f74381e02145f9823a79b55b0d175d5e1725d25357ccc1350f343321822d1f19ab4079a58edca7036748a6f708e42119657ab1f200a444268270160ec10628b0993be06ca3b3770213458eb90acabb7390dd211ba28981b9198d6ce8223b1364ac0825201b37ef10646ba10915ec750d92bded6b02118a2073930e99809469fc41f6d1617ee629cb900609169820077406f5809f8220e93445bf00af61b91c333199362419a406b4beda3524d1b2c7044fd2b7000d2b0eaa60cb9fb09e31b150e9e21e1174180fb50009003b77fa8dd21c885a714a8da509208889c621a1a910e6808674b613160d57e95a07706e000b5b9f76f3480122e0b09fab3fa52cb4befb4ae595209abca951b2f0fe849bf86214471ce280cf5172551c00c6df948595b0c240e25a7dc10938304c07f2af0a990aacf12167d7fb646ba36d +ciphertext = af041736d23d1daceb0069cf227fb0ec2a27e13707f194ceff556f3b593a9070b830e0fd9a3e3a1745863be6981c204ff5ec896d87ab64a75f25d78c9566a62e98d659af4291ef9218a8cbbced4835dd937f9e9340d6222ebe20d2d50b28cf557c619e0d889715a4f7f9d00da90b1a5797173a3753a0fc7e81caff030a8cc2bc81cfa868869454c3d748dc2b94de61af2d115d2e662c4f5d593cd66f4e74f8b3d6b38dd5670d3eec06285239d54bd80f9b029b20deb0bbb982a55e218a656c55ce64192cb5a492848e8c447532bf252e4645ded1b42b90badafe30d1d2f65a5e147bd53488e0acb4b2cbf7323c87deff83e8c897deb5abe5645ae490a6d90d64343e8c89cd5fc2eb7d70f3a78a0233edd6aeaf3ca519a7ccc2a1958731a37d74bc582e53165499b77f9807a40d55f871a91b48ef302a90288e5587699647f3bb93961060bd8b3cadd218a3f25da63ca175bda7e23f90f2ab40a803f7b71055abeda7c2b30b5732ad861a764bd7cbd942e4af691fc3a000d028cde477f976c58ab35ab137f5489502d1cfe2678f5467965bd15f8c5fe0a18fa4dad2be45e7b08b29f73919225d5de877f89d6d353171ca84a3ee34ef5aadee4557134748c5a9e78b3979be2a8f24ba625c800b87bf49690baafc40656625f700699e61c68c0578f4177339c9cb66a0996298b5c110e26114017d57685c24b0c39832adcfe267be5445ede68e2235a49f8f99fcdb793e33e806db3292139476b9240b131cddb10496e24583a1ba633deed5dad9d3a42801b5c747db0a8ac59f65bf663397d22432711524f65328c9c76dd63560d23e2894c0f2f5867c9d1d0e44bfd727fb984187c362fa9a386a998b08bc349075dbb0f1ff603d34d4368c71f936ab2ec8ba0dbc814d33e4ad57e00316e2b255f2c7189dd9c4fa90fe9ed7c5f11ff2f81c81627d6a178ee323678a5ff3edea16adfa74d431a3056815a573c1158d06a1e305bb8262d050c26b774406cac0a591bffc4572a27c6b5be9b16e6efa2ec43a942aac05d42835e8a29491ada39011fd648e2d75247da22e220f019d39de2dc0b2980f925172826d44eb1d49f3e002f3fb9b5a69245b96f097744dc84746141b4ec97ad77e4ea0ca7d68f039809e956ddd689ef077a981fcf4c824dcb66d68551cfac6ed3befe40160ccb1d87141479c5357c090d7d476a1608c89644dd5e4a96745ed64f1a927fb2f922d5878b68987877c5d5a30c6df18b263bc4f6ec54c20071c17cd5669ae25974158e4f734ca99bda40bc2e4d8a76c55a5d7135b9679f1ee82aea90d7b2177ed13c958021ae54ebdd5f38d48cef6d575dd2d81727734d940fed2c9d89f4aa8134a99524a9e526821ebcdec8331e80cf62a2dcef71dc888f5b79b1cc61a382130de2a9c53c2e7655059c80e0e24836c36fba9be265498a24650200e09fc81d079deff57039ab7eed350c59cdd4984bc2f7572287e610666fecaff9a39c245c35439291847816ac2488d8c01586f88a6f99640b303c7bbe7d4290cf454d5e546c94e86ad860388f1553491fecacd3c73839437a1c3d1f51e195ca391cf8eef2b89ba960082f280201dd03a2689ad3a7522b1b79c61887ab37da51e978e943333cc18cb56b8888868c332350068ba5913473a666fd10e4478e7778f784b76d352ee7b07e4c93fb4f430a900ffa3361fd0ec5f27afc38db91534655f735743ac857b6bfe2c107fe458e6483191890ff4e344f2866a52a0ecc6461718bae135528ddc77dceec6f956505378b6470edc2377991d4c00553449efbf32111ba18a7c53ce71dc72f8228ecda82221fcf21964d58907ed680b1d7adb4213f2fd8e37fa18845c8c02a065c85d360777d722f91943a6164977ca03d70c867fd95519b4f1f88351bff895d90aef8e9d9ac4a87335adad1527a9e526890942f881f8776e474867a1a3d8a30a6bfeefd182a1db762182f60612bb2c462dafc1b5bc2f797e56db04294e19c7dc2671ed1510647bd47ecadd5754e9bd6ef9bc19153115d31ebcfb8e11a9c07b19797109ff95e37f912a07da55da65586db800fcfafbd6a9c18e427af47f1ab42aa33385fa91255f6a5ed3c9ca7ddc9fec0fbd2e4e14406897bc0d405b3006f66638ff34e31bacf13bab665404d231b4a7e345a55294d7c7efdc844e7ac557b94ecbb2f75bf73fb327e1b8e65294c15e6b6c6a257f033c +expected_result = pass +expected_shared_secret = 69ab30770f491dacea2e37f3c737b2f49cfaa211f5726436ef4bb49959625f24 + +comment = Bit flipped ciphertext +private_key = 36655931558db90025f501528590845152711ee684bab5ab7cf7067509c07980b825536a4c00bdbc146f8f465a46218c2409b66555c194759e862b5743a68c884b75df693648764b846183dbf7636a721666947942a36e2da64b70c0b7c2189590e23a35a4c885281913564d16c007386663a3765adeab82f562bc170a6f3ae4786fe75bcd6a6279e9584de1a74f09ba78d98903baa9ce380720e92beb109734d95795984dbb29b7c6b1a698e22a13c576d228864c78afd4a643a0f2222b2c112e079d8ccab2cfb4bd41dc57e595a2256bad6da6cfd519cb009182e202c7e5da6765e21caa7848eed74c8cbbbb36dabee4f745d45079d63123bbb7b1fdf1c2156c940d97bda4b8204aa9c309d03ef5f75c23c6ba5083445230a10f9483d4ca9e991c71527b8076433d022271d1d356a9f415660b2d3f4924095c695835b90b90222af6b6413c9c71d651b7863cd2779e5a443af0f981d62b82b2e328997ab40618af444bc4cc30b751561dfac10d9c019b345143a28c176696925bd34a7746256819cd8612b6a747a1c0c2855ee66e4ce66d202881b2721d9ca0ce7db7a110f2191924c30772552b61b2088c6bd350890fe7b13208a5dc89c57096ab76873f7ee252c7b7654fe6c5e2dc823f907e11c53e18b5152d39a93492888b2cac3358942ca169a62946a937934c4c1306918d911c33daea8b3b7baaa84596fae6356a300b33c582c8b73a9ea2cfd5e77221b1972de0584ee5468e83ca0f1bb4ab8593e2c9744e9c2209145d38b07f38c2a14333ad5cf42adb43c31a651652a3425d0ba531d2befa20a4b1970213637df5503e9ab8955b763d5c5bc6c23096519861be30206879383fb8a126177580f86e8fb81a88ab1503bb2e1b344df8ec87732282fe1a855db864d521b712102319d86d592a1026311982570ea93572ff729ef88c420f5bce1cc56e3d4a5977753b3bc3a75ed383e6ca35d4953f6fa974261cb9a0da09012471e9b86c92d3bd2ec28221ca3c81f90c6870437ac6b7ad92a00f859243b40230a569753322948c519ed85102618cb1e63ba2fb979e976a6fdaa725cc4183b024ada0746f42ce6656202fd613bb266511f3bef2e4c2722bb3411ba967732ada2abda268075f4772a097b3d2384598fb8cab989edfdc1a4b1867e307906678550336b71236526ef5ae21c4120ec40355ba7dded2a4fd846ccdb3adfbfc473b99a338e905410325c6f8cd98b5883d976bbe508e5c86a64d6c1e085b35e1a2a8575c76bd6261ac2245ea49bc70c81ac43a0d398291b553810ca4833b689d18659997aa5fa079aed02a9bf1a38e4f8b7edfd8247457c3beecc445a29621726b16f429b9e5ae73a34086454b8e0456114a35525ab69e568219613f1b05cb2b1cc9961c11d41623ff9b53755b8da45ccf8db9b7c99c7b35cb39123a8d2713bebaa66de3dbc6c4c17e95fc31a285ae273121c60a6e08472c805276b91a9b41b2b46c219913823a5805b61810036966bdd7834f2e4429fae70288b7143ef9776e43a1fb75159a635b8368030f7c9a5d86097c6a35fb7371fce28662a750d70b066cf0420179a399f506b78a1fd6c84480cba33383b7715b854998cc64ac4ae2f1b06d69bd6fe945b9d9af0f993ae9301e760b14dd4cadffc66018636422c1969749a1beda093058b6deb89951828c12157747bcb1a8d899823c28f1d3a307b4aef579bcb231b0b138ba91381149440ed93054e98542de62ac28b64576198491e48b132a0b64c2c83e47022ca30289274fc5e7778e532f1c03630aa34ad548849cda075b949d93bc29c15188d16c98c2f3b6aefb2e22e94e830b173927489896c744b1751700bf97712d8b7baddc45458e04c3b2c58480c899af3864f126be07bc34f0f42fe06ab8ae7ab7332097370435f262c240a01989b3471532090939105540827aa9715917b7cbb46966ea4d6d998fcd9a5e2c1079c6997113917a1b26cf835c341559843b70176d96599e957e1d6c15fef361a819a6a6647563292ae115c0480469516aa79f6caa1e5931661014a6f4c01fac5042cc793f7220c4c2b6c02ac502c2a87b6767d1a045ee5127cb669be7d71903709397053dfcc13067475a9559879942c5dd377df7b8a824a22706037f6b18403e9bb280e04424564514cb37fb1186736212524b5a2dd37b2b7a56d6c28b244030bf01395626c3e8915d4be9572642623f42291417745425b91f117196ac05d706a47bacb25e344f8c2304dcaa0b202005c9d2abd750cce868c11ef4bcb6697ec762b37ad925c3ba18cc87862161113bb1354aa260239ca9d2252e2cd3c95d29ae55ec466357206e7b6e81fb88d4846361d0afa451796b4606e045b47569073044a61c29450ecc94dcb9ba642374a38caec3eb7358fc0af0ebaf6763bc8debc481dbb1b11979571207898050f2524fb6008f00eab91ddac5b9983a248abc89cb6080d92f48c6508112592296af6b67bbaa20a66522a184d97c544b89d9b080a996940bb77d2ed8490ff637a987483e8a75ccd4ae1f91897c405503e4ce0ca7232a798940856a87233cef05b6f305a91230c1e48828b8b42b5bf21931f47ac40a3b4c8257c435af199b8b0feb37eef44f45ac0686913bb27c685d193f8d61b21fe426cdc57c7ad2398a611f7981954e07b7949a4e15626d7b7c9bed04b70bfb2dd1184135e45e517723aa9481f54a62125853f0838abb2551c88c6fbd824e0ec2031f4b9956882385aa9debab0559cc26b1b9b2ef8bc5fc700d25b80799232c31046af6ea663973277f8b18f030116e183bca688e85e3097c8870924abec2a1a4ed4901d3c8bb6b5374a3578d47a902e3652cb1b10810f9566e971bd510cd4190755f278aed1416b8d56745616df1c4bf615a37b88275438b07371442788756877bb7463946f6577dbd2808489876fd995fae90199e5c610d449f21971d94c0558b83a317cccf538756e3b9603b212f1445997dd8747e575f37947cea43ace876ab7fe220d44199c379bb40d11e9fe910040207a6605973c3932e243d9c01bdd5c64b0640423ea34f9a4510a4c78809c47ea0a2b5a1291d64460b33c50f0e583a0a8bac8f7a34d517537cd8550b243723f5a43d7265ebe5a991125447eac611a81a8a03b7dee1bdf10441d002889214a731cb7a4d833af75c372568bcbd6a8b6de9a746a553436ac058b0394129758d3780e11a1228fbbc4aa47fc40832a578a45d49b5efbc7142f668a185908adb29a7fab9000a0c5da7219d48942311089d03949358a87f1b859de4b60a8233f7fb11624c8bc387a44466bc0e745060d0155cd5724884bc189bcad17bb55ed5ab788b48098549e92a8092d63c62904e3e0202c7a26ecd5b680edb99ff04cc1413128efbac5414aeb37b988453ca48d599d39baeb9880eb0b2aee13860478128058b81c93aa487a2c7aa59743c5bcea9220b7acaa2defc26b0eca092a858c3033eae912c6c4111f7bb37d74c04a7c48d2753baa0bc0f2a122a2431284f110e8bb7ba54f06af2c4752179851cc338732c9df0b40e9f6805e24142786406f1058f80d6b31bd58ae1e1040106b1dc0c8e24b618c9e4b4e0465f045659996c331f8c5c1639af5ed053d39a6bb6731b38c41b1158b22b3934eb4166094b4cd4a198114b2ff8a594e1b239b224c1e5ca5e9889498cd80f0188bddecb942c89671189c7d124be29e241be34040ff4755ac4c2c37867edcc27886ccdb0f20b14367dc4f1533b4a1fd2b5ad7ca3c679e5c8ab19074619ba2d69c19d13a57473c45d23b19cca39794605640255f533a6f3870552097d7b3a96893b851b92c4317bbe7ee7685403ac83c632d49099b515ccbe7688ad5748b8729d8c807f0bc65da951b7408633fec04ba728996408c52e47c1bea541a6a9660ac1a8684a189a764740d086e46a85946bbb9df6981dca6430f1ab178223b284a5fa2ca7b2acca589669d9eb510eb263a661b40be9cec91a23a685193f8889b6ca0b0e1051a0d57fc3629948005a742c88a2809e40196ebf23c4df538e46752983e1664dc8abede3841b4451788bcff78c21f5ab4633a119b81b0219fc966a946e87b7606e1c8e40b21a9fc815f9244ed35ba9d66b489ab50b6e663e32f8c70a01226184a45b159b036545cd4c9d93e681f69589fbb80728a8c70d374cb47cc39b918a33f23f69422c9e876375277d49884cccd704a5691330085a4cfbc76099a0616b3071a90aec482eb8859322f5b1a51609a7248d337c63ddf356a666a4d75b1517b0860ff12c5c637f0a4b8d0acc52520496ace29c59e019fde4cb8cb1b071441a4aa05787c54339233a777b0b3adc4ed0df2b87594d0b5c98f3a5927cb6de8a46932d6e4292e5b2b534b8023e7fb4dd96870b0be4aad2bbfa091948d813b818d29b150c91e0a010a68dfef0627add21d6172ed739d3c57117969dabc1e3e9b90ceb39f0a5ec2c12f1fb +ciphertext = 07aebf0432cd201de5b88cf0b6211c4450f8c7a15e3691521b460c722360d1d8624ffc9ab0862d2dee800771d5e958a7fa6e40e866dbb7f5ccfaec281b84fbd25832303e8367b9beb8ff6f5db5099f54c59a125f2d0206db1506c686c80390ad8bdab13d5928dd17c9628872077844ad58218fa4bf036d3713d94adfa43259260d090bbaa564f9349241404a0233e659dbb96903e71390d0cecfc8eccc05da6444bf6716b94d143d97f34b195b6d5b1f2b277e6275d5fc38a46c583a4b8838557559987ebe3873782c7b3148dc6c6911ea1c908819128ec75b0edae6c516753a88f42d39bd024e1e16d5c08a17dcdab82107176f1ab6423093835783d3216d1fa949a3c3ce80b9ee6e234758ef58cc195a19bde995618ee68a23da2f786151cfba9d17590bb76341d42292e82752942a3b76923356477807c63faa37e0b36663a54267002d9effc5786a4660fb518d6bf543dcf44a6096ce978190e4adde3e5520aa13e17e134b92340a5b7b0bd4c58fcf7d1bd299228cf2c649c5367d925009e512c026c6fa41e1495385d0b9b8d95b3bf083fecd4df9bafba0125a58993f958253a3f425360df9687585c20a7a6c6f249167e3bd6144858961c3e503011bd6f2b69b1faf0c9e6ee739034226acfb4b662b83fa2527ae6ce406fc1e6560f4eb523effd0f114fa992064c2696df0af8049c60599303ffff3f03d032c344c3343f1161c0381861bb2e7b2bc8e9125e5f3bf3bd0b94a4a1a02b34b524ffab070b9baaf70721fccd475d753538a51ecd4235dc47c804cb26af550177e2fa3aed42f2ec439aa282dbd7998b174005d4e7b9bd9081b337e82b9837fd68c91bab43e8153a17b835e530d2a016b74706123e6b821f63edd232df6ffab160a0e7dd1dff17859aedbaf1eb14100cb1d1c5089b1190829d3c0db5034fb801e40ca361cb005c51a7894be3ea6c019617283883eda9cee0f7c4a667a70bf68e0a7b9919483df690c82616606d516b5f56701ad6eaac503e65f6ed908ddcc4a1d811472a085c750742d37a18792221cb04346d6f1ec53cad34030754efaff46933b19c71895c8a95eccfecd90d5f1bf6d1412a168d47b7cdb64d854449a7d3b371f0c1173833e4865da02de5cac0b7985354472b4a4bdf7f081d739ba4fefac0998eb6a98e340d5a1b5fdcd81605fbb9e0b095a00b02e0d8a5ab05aa8e0778eb1b0ba01b8657f89bfad78c4927706348eac33b741dbb28b911bf88ae3c39abc6deb13a286fa31da4a03033e400f3f78a3fef077ca62cd57e831356e37ec2b3a3c8b72eff183632f752d980f4d19002c1045fb75cc3e3983fd9a758b233331144d2e6cb900abea8a36fb2b89b88a91f5ed2252298a534263fb0a9c8ffca5287a858738c5e2912211b16e3bbb35917af54472a3e22f158f58beaa678c470a5c798ca58592b4c04fc238758797c1948d563ff7f1679556c7e6c6c045e9e5288c179c5341253af4348040e825dd0baed0e8ce9f54d196ea663b2f5eb37efbf7c0593983ba429d3ad89af44b76116b65ffaaa0f5ccea2809abdfa8dd4d6f000e7eb65373848f989f0b1f212a51232a8db8cc5ec3b754a4a5c4cd2666d87c554b62d99e94543805b2a59772c557b2f76af1bbebd7786f8089ce4fb1cc9e59e3e22850b9e4515a3dbdf036b086b419a300c8e64c1b94094f7abcf24d3f00fe0bd581a293a416dbd1bd74f650f7c4b973f5b3072192f9d2210fe53b44dd0bf40df08cda701a7a59009460290bd9c3a8bfcda07efb84fad8e634d2f61bbbde54bb7bec61e925045523bb0508ae7e2e2b594447911d6c6c3ca1e10df56a06025b34038c994dcf14fec2b110443369feb663c9cf30b348b3c4b1c4892d232f46d8c132cd591e2adee3249cae0f63c993562eeef76b602ad93530876f473ca2ce2a8370354f544bdaec83b5ee227d34d5bfa0b060c684c8ac3cd267ce5f480c9ecd6d423994354d870cd01f5ed82729e6dcd9a370b6435c9002e33de13933c49825b9374ddbb3d2f6b4482658c94d860de4d64e5e02660180951862fef54cb98fed9c306529abfb4dc98fc87e44edaa7051f093cae4f32a94bbc9e1612c130d46e2a145381f57dac203a3d77a4c745ee45a383c456d19fd76a601d47978f6d26e242c9267e1ca5d0301fa48ada3780df64a2d432af0a334ef1e749a92c9aae25d0e09fbd8092469a8dbd4923c +expected_result = pass +expected_shared_secret = dcd2e849a7804f21560c176b40f88c41c777e87fcfed2d133b641c6c694460ee + +comment = Bit flipped ciphertext +private_key = f0718fc8b516d63b17b577cc9a6c43fe877aa960a2f05b58fdd07ecd11060a314bcdeb0cc4b002ff0a41beb29c1fa99c8117a62848752ab17fbd5b0ea43b352d3b72b425a4599abab3a4c8b4bc11bef95da1f86612c760957ca693da6b79c8cac94a9c8f485195194152b50cff3b3cbd8667e33cb87012c307d38b2be84f72822d8b8725fe3b7f0cbb0eb3ac362657b14b01b08ba8b4d4174c092504118a56e98892c6784335179aff37c033987d6c25c5e65ababe24a805dc2e8018b59c61b242b833ae13bd93b99dce3b1344ea04a81808f76b3ae2d460c2597f772b20c89ba179cbcb87827ce5d567b90277b3dab989a82beca918505675cbf07f0d3688d6faaf4f23ac14ab30e1d6c020d3ce1bc74ecea05c0ac995bd942d5111cce1b89a2880a174cb418a0614f8d0904ad8c141721dc9775873b307ce8989a7b86b92c29ac3050e01e08cc4628cfaa98238b77a8d2a857b1027b4b9cc4283841e25296e998807f210dbb29230f7699ec6c9968b14473a7aff1c8fdc84c21ec51569c88693b9a5b494ba26d947af6b1898572da4b268f299986bf96039c40f5be273679a896fc98031b4063f107b08280c25035806aa60849cc1fba566c688a5beb9b1c5bb95304792c33259fbb01f54d1be766125c4279fc3e44f01e52544a0948a3384b5259a422525e6402793d64d57324c56f9937ec33b1b6a7bf142204268029840747006beeeb8756f235e996b4af9f36ac97313c5a7cc1101aeeab597f7fb07020386bfa20631b20d5d279259810e65f49438cbc82a4a5bf5c95d2701337995ad9c350b98360de85ca831960066b47e10c9bfe6c328e696c6d1d01a3d7abb1b62ae6d32271103b88898ac65189743b6b5883357cae91c5d022d2511872f158f07e143e0a2cfccc170f8e80a7fc555632acb2f35491fb76bd6274ad6ca785618a3df17755415c04380242bb1689cba53169bae4cd72a285cb56df821c6d86b01e8188dc64945e24fd57c9a3b198ad581a0f8d6aac531cd3387440b42c54072a244dcaa3ce88974b6c82c5b7c9220a1d681c80bd68ea2b5a92b245cb0293d7d1a8bcd40768bc8cfb3fab62268ba058c9bff9a2b0f3a770cf70ff2c14137254f8c9a806d2198df73c18c167363366f079637ba480429f14d1f1a27cdf19676f16e098cba044413bdf0068a8991fe4ac4906619eea12e4ec4baaed4346d1bbd200864572c57874a33944b26dc2128c0d521ca250ef9c271b34509a23338d6330f06854d26b60dc0843732f10efbb250ca3b1e98c8324170bcb22650ea91ac4bcbb883b62a2faa6991f7bc8d1858e6414dcc551db0200059d4a29f652e2d9704e938357de508c8f30967d9823cebcee2f84b7667c1337cbc12dabe9f5184965878ca1b1296f050d2372f2c9240c29682ce50c435e8122ca36d90e241f6135d546aa937781d4196465b37c4087561d4d91cfc149003840b35192f2362915c32312134b12113828b84c63c7782a099087f128fbdf471c0fba42e8a8ac745c087e6745d64c864058a8d68ac84732406c6543166486cea799e565d2a1ac0a4b1794fca5173c6ad1a35b682bbb9ee3c91ea5c3397576dd2e87b9ac3ce77218ef5608113b861e158644b403c7d8ca421b75fc17ca7ac9157d2766390c4ae278575af9873bd13b1766584b10c297b1963a20260d611bac5d799ca7557a39733cb10cc544620935bab75a5acfcac0778f55e661660530470314a67f33a22c2f65281f289867930fad7a8c21728364c6cb955a6f5644ebedc485267612f7cbded36471dd6b7017813624741f6d2c1b823b871340af1c16fae4bc51ca7cf94898bbc158a78f913ea72cdb1959dfb3193ba5520a2a29d291582a2f43e2d26a73eb5482ebc0d430537e756b873c349a024bbd05a2c1158ce58715ec68708711c4f6091bf8d1b49d8a49c534844b7c5754a6c2a7fb3aaaed64aa72200db473eed41a8fe833409d462df36cc2a616887150cd427a147b99e57f44cf60037e554927e5cbb31ea164edb9f8380c67c4713819c24ce344bf4515de7ac4093f5144fa449e2198349a332537045b436330e1bc30822c187433c391097c03882fc38683a571632f38dd0478a4c97b3e81201a4d08a8aebc132733e05536115621e945731b30ab4d202b32d37ba3b5c5d2430778f8ac2d8273822466c662b8e14d624d5102db9292bc1140cb51ab8ceb89bd5e69ce17c434b6b3dcf2cb86a91b543e115fc622b26997093e28fffb8701f0444ecfbcaab39623ee38dbe4802f48191091c915032bcfd7783c1e64f6f700ad1e39e8ee6cb9c067204b68ea9518ec216b3f7171edf39c08250bd2523a10d4745df4182bca988d0694116fc3381ea4744eb70415771d4708757c2666602ca7b526e52ba8592034208fcccce863079883a4a92175a6c5e2b03165697cebc00cb64688df78aa26e9b979230ce312b633f8339dc125c3bf416cec6c83b0333536277977cc4c96342b89c5a63136710137dcd51138ca1a695fc91694c3e9932451f723d15941a14d848de283c176bbc408a10e70a7867393b4264b4eb0c5edbc16f3ad66fc02c09168966d3faaf4fa56301a3a38ae71808b013038350b8a5c2c0150c6cdca5387610c0f2823d04946f4a27dc9a7ed19012273cbc3178a04a553de2840b8d3392b716a475d9544adc7cbb95360dd0c9d975cc8dc59459ea07116328e095bbce2695ecd4180633954bba2e6c371baed697c1f53ba4907157a542b2daa87e8a4061b656140b4768672dd5b466ee5a000737948f162a4f460dd27934dbb36d952867ec7c6d18374fd024110bb6ac5326073202aa80483a0c07753005982e80628533c94658a9024058e76328afa098e1727f068b5b6ea659b27764fe52caa1d3567c9141b1b95eeb23221bd3372eea196a2936533c62524997a3b85fbf6718d1197a1882168362cbf0490722898d8e6b788f7cbd0ff14e78287e08d461f34b3098fb129486631ffa394e7a93eb61239dcc44b479494ae327bea48c69b37495e665b833066fd43c92578a7cfc28f75cab2cfb33b872ab031b616dc1aa1a680bc25118e8d7ac60426d942667dfc67ac80a18bf387b2ecb7941539219d5782582b86324523855ac553bc1b327a9c464a613d2987e648a10d41f38008ef8642f91537321c5034aa23c29f8c3e5f8c983f9bef7f507eb10a2960371c1b5904b27b68827899b3305f81931a204c2d34695f6e2c521a4bba07b62b7a25a2b3515cd9338ed2167f6f327893988b8e1ad2eeb00cdd345ef824780474b8219a385e105c1532160fc2afa8a84225340f651bbd79953462a9430f335caa2631e513130d611aceb1f45356201536108e3b362622112b57a37289cc1b470a26c62c7c5ae4ee66a94c09e88632b41193fe9ac421cdc9cd1930b7a1778fd77362b3c5946da57b610087028a478d40e1a01440189b87ffb15a7e36443b35dbd2031d436753499a3d8887d2ad415777750b18c23b7d01a9cc424d2511c6787385e2014aa92ba765a8cdb771190d585f193854aa67e92b32396265d5c4c4cdcc25672bb47511604eed65366a53a2a99472f8ba1cad9481e67b30a431dd81071a5a00dd2dc48d89c89dabaad8cd80ca0aa1121b873ce775a8bf3a6636b7f153b64849723fe2a64e143ce8c24b1d37bc8724ab8b3b70493fc78175a550d0bcf43d6c59707874702aa95f5675ed59dce4a7877474960d769bf313635374bba0a5e38f0b94cd738b28535b8749ff0e7932c7b9c31616b879066b8e7006d673f4ffb048fd56ab5632d41e650de465abc1ab476151414514544d0150c6aa8ad299883da01331a0a04164d43b240a9a581f0ac502f333a19a43a357bb8269346103c82601073deec82fcf57125cb569dd8bd41d4795638722d0230dcd30e497cb3e239a33d693e3f0c327ff4551dd21b665a0a132c1b1222224501cda7c1c97ec85d754363e5e117ac021edafb9aeb506a56d8a0c6684035140770b13e68081c325a951c825f71773394cba60272caf490c44df6b980684b94f45ecd4a22b601a1bf874821723187bc9a05831d7813c75275b96e9a3a490949a01bc4fae99993898399e220caa15605703b94ab7f53c0cb613b69065c34f2841f15447560a080b9182bac9b760db6c60b2135581c8736b388db1266b634a6a6e92bce53af3c0c68d79b0fa5e515c16a95254824dcab92e448618b3452ebaa2bf6e19e520b3819786f697bbe0f9a066bd92ee2a8363066649fb50eb799a1cd844fcd57585e369d4ad6a20ca21b1e230e14bc80757b1ae33b2ec9c03e9588146c37b36021710be13537005fad86905e37991e01af178d206c2b0f24882bc2247b40de909bde9652416f57e71c7edf5c9092b1b100f8af3d762a6d2c5d896e09eb7f6760f7ef1599e691d3ce5fffb97ae25f3807690fba44222483bd2abd7edde3d6241c9f8485680f96a71c9cf252 +ciphertext = 78b373aa70d75c6842a8a242abc8b5b94901fa94d0fb35a9f04dee477d7e5cec36683c6dca571ef27a785f9bedd25ece8da0b51b4f164770dd5aeb466c67cb63581b073cebbab3490385830c9d303d11a9c5bbb6b38b8c7261213a333252a943a336874486e5cab8c8426d70d64094876ebe1bc8f775d2dcc57715ce0d836a132bd0a9727884b3d6f1eb2fe1e3eee4bdf44552f6c6e5acbc9b2635d9dabf8c6eb73adfbe11c924b3b8dc46b2f4becb434404c64930f67993e3b05eac65edfa7d9572cc9cbb38e770ed8eb38450426787390f87ead4443ac47fab26740d2b9c51a963f32510fac0da9ae7e59e001c0798ec62ef27850eb5984a25259c913766a3b92e2c68da62dd51d8d46cda56a0b7c3204f6abda9228a78940d5084193d79cce509848b5e0244437c894629d9d8044c3165b9f7111bea11289419cbcea7432da9b26e9746059a2c7b1e2b61a97de33cfc4b41c827fe644ab19a053da7c3fb5f221d8839ad7d0e569e41454feac48395f3b0339bf3615c9e71df842dc53943861cd8767d79d13507c114e99e2489cad1c7ab2658c9698880b9046a78120545edda7b9c3081345a0e86f05fae2646e6f0ed2babac1187408f497142585676c1ccce5d5a8a94df6dad674922c174c16232dc7aa29ffc3ec123fb18b42571a940de5ebeb1ec5ecad9a161bfbc2438108c8096c99b482d7fa62870f2de6e96cea2ea5341a95e42e20964d3dead1e7d55727c7335db19b0579738f8e76231806d3da23b211e2c992a33051d9757e903d3c2b4a6c1e8655845a2b9bec1b79e6ffe0f7bf796430eca8f011884d1b38ae55216ef38e1cc798d3800270a9dc0045ec7dc15d0ce2b282415b3c67fe1f388bfc26cad73437bcc98b3f47f3f47a2137fb6d643e107f4c248ef3fc411e7ce6ddae75b4dbc56a261bb35e66edb28cd112a0359626167d244e74741edf3218261a79354429a4af9044ff3aadda35b29242f1e6dcba45513d8529ff9c8ebea1ba6a0f5cdaa9506a8babead91240e39aff014d7e9063af0ced892433d395508a06345bbf6927710d045f7edbd77412e78fa32b5b31993e8907acac23f2f2bb279bc184e1b524398bec0ad5f9fe627d9a6fe3830adb57602c1ae2b4cb69a76eedb33bc62514c0ecd236f400f740b49d84bd7cfd5b9eafe1144316b6101f6959e6d6e7d05f353e2412a2ad4db7a93d7e247be4901b1bb8eba4ae2a5fd62340bbf4ec9ee8c1ab18aa004eca8231cb52eea12f05396400e5ff063a5df364609c88482b9df6fcb01a4ef2078391a3357ea737830c0c73f78e42003917cf6cc67e2c254a9ebdac2a5fbd15c8abb968e3b35f13355a9f954eede761fee79630790f99461fc24ddcb6dc5deabfa0315c1b8de7245165a12b5bbbd06e39a48cfda716492a8b824aaa6b3bb0729eefecaeb71c04e335737d55b04266da6ec619803c75af98f006faa0dbc5d1096cc986cc5953d6651257ee56356a2449e420f63627ae8a47b78be1901c3871fa613a2a0b23b40016584f059ab3f60e51fdab75b3243c87c685ab4a72863bc3e559247b639f32604958c88d1e99913ab1872230e722d365ff70334fe7d2d502984bfa5b541d091db9ca6ec625ca772f260d9e32f523937cfaf531c4555ecdec5b19ab0e36b6698a62a81bf1fd797f9824b59c54ca71056fd2d3807fe764d99a85270e2d54c5787f2bd9589064a5b94852d1ea8d3d0a7a47a65f6d5ba880d85347cdacbf751655da7c1fd99ab6a14c76a05fe24d1221ace1c83e91195f9a0576e173af3b5ef5d9521ebf79ff36ae435a41fbc4b04ade89a27e8a7ed892507e10d64e349a956d8fe906b4fe288630af3c9faebfeca5e67f80a40aa18397a251cca95b5c8d4059da79fe01baa4955018498eeaf8719c2f38c9eb5144869447e41153af65aa00a6095dd2ac680b285f3bacd1acd7aef62279018a17683e4b12751dd35c0e94c4267d938e8751d2beaefaf0f3c1506342d2e08ded0def088da15e7d0fba8efad67deaee91060a4b89d22f0e7a97f4c33095d0a6d6e313580fbf7de2317bd48a7d61a01760b310b45a779e5181e2b7b8feaddc991ba1a529c601c2d5b4ab3386fb77eea67766cc99f7df5b1208ec6f398ae67dd829cfe44fce3d0d6adf0e6e42753c17484c10598f81f2706668b2824ff9962c80ac5244241a4747f1b9e1afadacfb5029a6049f807898e +expected_result = pass +expected_shared_secret = 4b5d60dfc192abda5168127ecf64dbba647d745526ebd0cb94c8945f6730e468 + +comment = Bit flipped ciphertext +private_key = 91f26da6b843aae1a3fa65cbd1628d1fd13fd4f107e7713bcce48c57198573b7b896f3c35c3c1379c78945abaedf25cf7a17826239ce9114cef35c71acb8cb0b7459e5801d7d723140138af94b3689e76526847511fa9e562061eb6a0347c026b40578ab98b9426962201151d08386ab033fa45cc9d9bc71b0305912d83b7914bb40e84d921919360349ab8a78b9f54eb156b1e2896c60f87309e3afb5715f631aac6db08988584bb75131f03ac42b5892de5953986792a82a726f904d11cca1c54ca1d9a3a80ff198e9f3b1389269a7e4cb11f7ba1d92baaec6a03fa8bbd06c3eb125bc8d4aaf5f96abe6ab5b0f6a2607d3a6b6d29bc489338fd52ef92a974deab761d45f96e26586dc29d9091772140ed29337ba50b6c07a11a1610a2405929b95978122764e18cd66e7cc751948789851f4814783d4cabe99156f01618518b28bcb36aa0a7e32b96324c45cba29576be6057d78a664901c21c2a362a98011a141e9279434aa10fd10a47836c1cc608c80d459aeec7ab219287843485fe707d8871e396b8d435705f939bed0c43265bb3656787f584152bcba56f091cc392c0784796a602996e550b7da20350cd81be123795f671b5393cd93c0086a532a4c053d983ac2aef29b29d49f675c23fdbcc5d4337438485fccc1156562945031443232419ed0117bdb6abeb43747872408079d8d26489cf77360d3bcb3358453c109c4d7196b1b76d99733fc075ba1cb43c55500d93c5422a621a99951fd923bd8845f18263e47a59370f0bc6c8614eb9301a9e2ccb65546aadcaad23c4a369a357ceb42cfe78ead407f879349d92bbc2a109c71b380e5d66a6670638a1956408c57cf292097d96010c123666090bcdc954bc7366e839941f154c1c37ee1bb3c3ce301fe77aef76a474f9654f42bca28a96b86c36602f95fead5ae5f50097675b3562416a50598c3a8184710309214b56b891d3bc1298acb05b2a1bbd8cc163751ad31ba6e0590290dc5752f432b422254a4887047f2c4fa9aa20d349a843087fbf29e894750996a607b399889a4220ac3426e519550522d6c308915364a0097cc6e254350b22b8671128efa6b4e4688800a723822062c17821571b0316543ee380899870b15b90417773ad23686036a31fb223b7f0b8440b9308f711445d1b544c5c7f8d19200a20359690b8146c36f91a00508ccb4fb2397e470b50c554dd765cef02183033e525b22b8376073485dbea2aa44d82dafd88ffed903b1e05d015a1450f5845a1731d104c04f491d2da98445203faba38ff84120d9ea34f6155ed3741a9f018f13663916abb6da42a923c497cbb2af8d304b8da696ebb05f248c2d6699055ad1bdd6599f7dbbc60f85884a477898b3147ef085ce5ba612ab6a83426d97c3cd00aa107fccce2901827fd068c133b7e24c80a2d6998c84cac593568431c2614995346448a20300463002a366cb98341686e1c06be38976511562d29642ec5a9d0c158369495757b2c94ba700528c05f52a2b3cc4619477171875372b1bf370a0a15a251abc6ee71c07702416bc116cfac7486e092b496abcd90a120623b6f1b5cf2a41255dfa753571adaeb318b35158cf944272a4552acc5cb45a900a8b37a52b213130c389a9591768a0aa52120db81246b1c65ddc063cda32ad3c6950e3091f0094865684a7d7206dfc079e6b4ebe588e65e51c44c911b04a65e628751dd9b86599b89aa606be9995c56578cb8b2be05ac2aea56ef2b4cb29f87ea40c4ff87821538819e3e821998c781975645220c478142d88ea462ad005f4c278d9e95e01db45da996c26ba8fbf9c72537284e1385408a8874cc8092f32931d799eb4877dbc4b1d5412a4be627ffc6c080f96836477b6d8311fa08347e1320c249b87daab89f431051c72be3a605005c79dd563777c39931a41872b05cdfc402ecd1647f413ceb55c2671e33acf48212f351e96a29b8fab5aa10b7214293a39b202f6f63af8aa87fc831f1b8206f6d1a7dda9c92a096bd1dc1f10f2b887f2945d17bfafe57d9ef4a1e70044d6fb39a4b9cc90ea16edf7b7b6401302dbb71bf788383c95d6507fc6576de93810556721f0628243e06852727ec3f0a429b750bfe22ae61151f143a66ec31c64e6ba9ee3497d1170fa485c0b2326226b2e54f796bb7a3788e4298e18a8957c2eafa3a23342a320403390d83d9f6b86a83a6a3f355add7b9367b37f10e260d6627bde22a85d0c102b675163e1611bf4befc213ee04ba05228575651799ed35f0f277fdda39c99b183f328a57891c49de1490cf77a2d866ea6795cea400912353e8f846fddb888d7e058b24a2708158e3dd481e1054940f942515c5ba2b6b4f9d8c0631419b5024f13d14413325ecb8b09f6b1c85c5492f2a4a6baeb7e22cb718974a08ff642586b7c01a1a3a5e922f235b839a360ff707e7eb07c119a3e4725ba51cb7bb0e2baeafca9a357a5b37c5deecc760c51504c09acca38269048b147da477b5b449d1376522298ac53981803c7dc924391c4ce3085cb2b1b7f2d523d4c567313f5b5d567ac5f9b53f10235c6145abbd6882d0135ccb78125795fa4172ece557250b8bbf739282cbc1978902b0c2c940a7a6e4dca3fc1a7a5da92cff524cb61115d472b56c366a3b977bd80ea49ec1c593331b522c028ecbaa0995326f5572e65bcb0cc225c49493643c65caf664bf1c5bf92ac7d74b828c5103ff39529289b5772263e67e913905a38b0ea7a6c2021b3e09b0306469d021c318621da458ebca6954032579e01b2318117e5cb426cfa1f0c0487af36b9c8005fe62712a9c7b927fa95a70cc124fa587170154a7582f80152dcc4538e037e848723f45c08d5c08b5010bc9504747693111fa528f2a567d13b3e994ccda2f733c7605e430b32ae2520139485b1a9643db2562b02b1037c61b981679bb318db756a08c61fd9b9c505d8929a511400082f4b1a058a0b3727c73aeb4491ebf5cd9c2bb13559252686b4d9a47fc8610eca06ccebf1331801582f928da200ce51b1695b61ac50b52309e659d7186ae39043f8244ce8a56bf99346752c2f3402169a075e26e13faf231388605d7df9abd053c445e2560485b9b1d1bf12db934016a42972ce9e7164e2c7cae625643cc0ad1d99979521c401e48f771a45dde3661ab53c94a62efd2b2981d65a1634cb1000ae5d09bba100cdfa6929c606ba4ca0aa43d4cb0ecc9913ac89799245fb3c9c18ca12905823d1f8086d96baa32b873921212d1726b8d2cd02692ac14269b334992339089709aed705a76db6582b74c024d21581a78ac1b9b286f5156af8026f628d7bd3c706fc22cb017093c016955c5f8881923cc4c4dc6bcf8adb1341f54cd0e517e0781708b19a8ea81ff08c871a648bfcdc867562a5b6d451f7f81309c29264e703edb50cf370baa8359586aa234a6c623b9078e9d01cef2cc23b3a8788359ae67230c6d1a1b78741ef3a6116d77444e433f7a7443985b263b578f41c88e21170a2095e406b3489a29204c0ca0235ca85f894967206a61b34b9ba1f7510571821bd11f042b926021195a68f6797b690cc163bb400e539eaf4b7e1f23d7ec2015d7927d51331e2d18d61b877829b58dc8368d904b51fb9010674511647694e6714b1b9a06a9556dbb53a5e65977570896e6a3da2514b319624d89b7752c871b11b44a831210cb770cb175ba5613ab48158dc8c356e2961bc744242440f1695a770536843b7bb70997620f94e5e1788bd83baa2770b78743078a88bb828508d174e52e2471f02383782135595c6cc78642e15cd9c7a2823791612e922832036796b1b6fc13c9a127bccd783138c4d2cfa39aa8c15bd8bc8292b60b86c6c94b550a2754f89389ab5d93cead9cdcc2145a114428cf78a4a4c61d887578da93f4b3c2775b3baad979939271f24f0ce97bc4ed6698742d186ea08475632794e8939f03a5c23709e481459c907aecfb3c6ae285686685530055a7306a8556170abb60a7d308347c20abfb476572c15a63619851407b16a7ee434918ba62bebd80bd403b20c79b4189b8a4ed517d3e4a2a0320340d6876250b7176667464b41e112b2b03474b0b397edaa330d058127903152a05b411a5663a9bb3ea291bd311ff61475e9a77998fa920968646a79cb692b3cd957c0b69243f4f648672560544996099662eb2101801a6dbafac911facd5801c3967bc49e6a5bb4406ddf58c27e3b601481259a518dbdf09731358fab0861ca224b06e6135d0b605b4512922520265b7257e49e3bc429f3d38726165cfb43bfe61b7bd37307f6b211d2044fb88a4111e1a4feea2cd686b00328b4d95413eb8bcdad642cc7414614fd4cb3b8a2b041e1a1d5887f0fd617a19366142b7e4ce1bf584d3f522646362ee435f8d910fe6d7bb12cd364518302d3a629fa392fdd31e91c40e7a05707edc935426bfc2db0d6d353a71cbaf96d365b1b43cc +ciphertext = 43e35e349582d3dd0e695e1325f8e65d894f80a51da6b63e58dc0ef28951feae29cba67e0f2991227475118ef3f4f2aae9e6fa545fdc4d0eb705a06ef9e6b5c98dcc04007eed620ad3db9b991c824d2877b70e1841208c264d8a2fc60015d566760b2ec2aa82357f95550e353f10b65cea2cb307307e4851e9a1529b546047d1127a3e0a30ac12be0a14ff38ab9eedc313d1ae76208d21838e8e2bb3fc3a952eb5b967dc8e6db1fdb0ed005703e3ae7ddda47d2918e5cabea63a3ba2a9357f8b2467e2f82f9c667462148c3da7edb89528b68f385f03dc48e4c174e7ccd733ab7ebae1bf756d85d994c636f5643bf62b1f97a7c69021349f4c4f8a9bda736e594453ff713f1025ad5ee78fdf939ee19bef04b69fb428f556c521e152161e5589ab1f9a4078a8bf9c004926f8ab160cb90cb737d85b2be4a9d8768469f3c1f295cd475352e0642e6ef13c330c8be36458a362b2e066a3b58adaac31b38e88ee9bcff26ff2241ce88c527df4feafe3ee1ed55a9cfa26a134134e2d9e3c7304c257570e1f73a97a7d265ec460b4c74d839aa817ceb2029ad8cb845c87fa5ccc440e0aa6cd79760fa8b3aea32ef11ed75eabda0c198b36acdb8333ab0f72668a35e8e85e4df3cdcb4437b5a1d557423818ffd5f203110fd0ca2687e3b956dd21781fa732887f5aaa87cbcb367939f33dd31b1f97d007221602041f84ae38bde79f936a26f3b383217bc41a3dc0a6d58d8a4a9087700336d595e636c0595770c362632938099213cedc61a70e74e27050e9398e5801b2ab63684c677cbc9f4e27d5b9d4d78b65e1cadaed5b7121fe8df689348cc48cb5b64b1d3f26a0d57dcfd85dd94ae9f107134479c51d64722a65280e9e4ad7995006218290b03a155e3ee0fed64889f148b5539e3d71d2f84be42c1edd0de7c5ca71c82b7a8dbdceff9fa00f0a55eaa6a6d4675269c0e166bf0213c5ab1f1268efd7e18a6a82cb571c961e80241889223623a93fe7a869bdb67ab0cdbd18d66863a594febadb95b90b222f57c6d2a395987867efc541990038bfceeaf1f4e5df110148cec06b5a278850d1ef67f4423094103b9a4d23a60804cf6c7033664fa59a101a8fe256500a833b9ee1e5504214e10cc8d723e22802d9f06e0d5f33e386e8a2e51f5688a47fc42eb528e8f44ba59cb20b536e09614aa8650cb2440fc0292bf7973972c379f939b4ac764691bb2eef47bae4f2c661c8d56aa9ca58212f7f05f933027cd20b4845b9f8184b16a5734467308764f5966fed71df65c3def3befa69ecfa2f1bb42a7ce9f341ee15d75bf37fa229cd8f3b26999d2b5756016a60144cce7d7acd01ddd3f28dafc79fe3212b93d1c20f8726dc1084e0bbb7819092b9ebe15220ec356de82a571734c349829002d66226bb29b6e3f5db3b3b6010f46b38797721cb9a1067234b00f6e7f8334e5204ef01ed26548b42b64ffe5a0ba8e46faac0de5e4e04c8c43ffbffb83259bc6dc0eb52c70854c48593e6b579df6a47139aedcd6d70aaa413184f1c877b83d950251b2cfe442a283924dfc0c0604b74fac1c65f2f96b95570f233d05f1c19ee7472799a092de29696de6c472c08b266b8b6cd0efe95039a1ea1ae1426038d3ca06cd510036a30024a53b2892dc1f91be06a607ecf06dee31dbc106edc4214e709cef75b92aa217ae2d713842fca6faaf84472dfb2d4378291e588687a1b6a50b21c9826c5ed38764882811e722a321a1bcbd2f22488db91171a5333573863e851105a1fb86830612fc880d7c1d43e13de231b9a19fda630f46eadd72c91cf6eb3befce7ce5f482cc9e415947a54db2ca15ed6bc28b5a8950a9fb06fad9adebfa8983685d71dc88629dd59eecfb46c56bb536957250a7462b17c2ab4e1f28a81f21573933d8e80170d9e6feaae2a71cbeb7a0bfb167e3db10d5a8ca48033a2eefedec1d3f7cff6caaa321577a51ea5129e5ac0bb05fcbb6ce0f91162430a4202f9c40be7d2cbdbbecb3d7669d2fe18d965b3031669fb98759b2bf9b530eba95fa6ec718893b7067144257fcbe08031496488f38766d668f2da9bcfe5f8b2e24249b2dd84419a9fe0cf39858a4cdcea2e13fa7041bc588fd2c924c5d9aaa70525867317814f0e781dd08fd1174e1c5ff895747ab258f380cd399e02e44d7b438a03e6c10762bc1b73ef66bba83a307c455f03afb3ed10af7ab013bf56 +expected_result = pass +expected_shared_secret = 3c67bdb5684f8bd7593c1d3a5dff56d4cfdd7a855a931b0ca9e6f46c6ea1ffc3 + +comment = Bit flipped ciphertext +private_key = 04bc22fb06c21c0379cb9756aaeca974ca9c6e194608091a94004fadc27392bc1f54b9035963a7bb5215a91a21a9f801e4d0a6e6c0a4fa2c382c38093313a67b1542526c17ea029d555a57eb42005ff910db2bb1d3596d4a10844f81b26c3837934365f2635ac6228d7dc8415704210f617c05b959835223c6d38a93e3047b6ba73ab976c7ba28e18a1700b09a1e6964bb86066e739c2c35141edc106dcb62f0f9c417f8198e576f547c622f27b880267fe77c7219501d75a4adefc17b6a4b7df3b9684c3429b1f0436caabff1f24c3b744bc8e98927bbbefb9c98ad97b22549381d2184635ba563933f576321d7b329aff86f924c4b20fb660ea13369909df4ab7ca7f4af2dd1588fe512df6008682492f8bb2d6a738b454534ea17005b25105ccb15b12814cef3baecb853849b8a9f4ab8e4238379342a30d5cf8c16738e291068e99600e9be2b73086d789bb8e5ab41e765b7a1c55c50a1be722919d747a9006fbda16b16fab7c16027d2a7b79d877989dc4948f50745076a43c70d0ef3b05ac328b3db4cb8827d158aba8d871d69a4cf602780a4eb614b7b18b1c2c5eea0b616e9beed452ff28abfb9641988f9a80d7b082e7ab54edc83598b9995a802adb7c991cc812a2b5916272eb779154fd15025907105196be7c37cc833814ac53418ec4fe7648cc455bd3915843d544d9b827d989a54ebb3a9fe976bfec87154b66a8b334c1ae7cda7a6876c7ab5deb27d901967f5a6710ec21a0bbb95147797b458870fb8ba3072ad951c8043913cf468b32e7767c3259a4aec6d0a4c191f9a8efe62cf2c5b1125d227cb8a542e22c401146513893dac346a44402ea32593f87b7507f1bf5e82891f352308d55f801aa39d766cb93b85b4d629d224438653302f0cb3227431bfaa6129b3940cd010aad913e295cd487c332c390b9d53c671147c462765ed004a097a3ed5796cdb5b1e904a25052372df57285184ca3f47476cf149dd9c160b35c05d2c9f1e8a4306cc0c1614bc2574c0bd9c634cc82242abcf43c1739d900ef1083a8bc4033ad853f86519c83a80c65c914f14c980423b439441e0d95f691932836292dc097190c220d88635890c099626997d9105a60c64a2b98275d9899e285d510c6bcfb281c69c437cc90c624a30c3b6682dd164fd26755b5c915603242efa93fdea934fc1a41ce14c8c1c6f903cc2fcaa21c08592bd21ce9553a78d54438b70a4e27983c1966637b418f6e04fd3f51cf2707f1f5ca85d3c6ff7155d1c5347e4b665f2971d30f9b2e81b2505a62df200095851cc057014c67902ceac44df688c94d720eec966a765af05231cd930b6826bad838aae9bc24d65e06009c401b31b0bdb2918d641ce240ca6b339a7288099505b7a88bacca1f57a733ab483929232b93c773599a293a321a858af9681e1d22e9e32c9f40101846243ab66a32f34bfae3c96344ac5802c8439c10b2299495e51a4b5240443c1080cd00ddd1b1d48c2967980cb2d5a67fed2be406739bfb8436021783e372b6fd18e971749ddf78caf700f360c46f12a3d00437263e87fa29bb694ea716a4a1fdf831d6f0b61397632096a76b08a6f8dd126e12c6aaa62a61b8a273e14b863a59f78621136768079406a9b04c8654c3832802d8b704df7086112c79a033c3f4a3496ec549de8173586893b8c85b3efc5058395352f03bc6c5a1891f2452e93b0458140a1f796c6ebb389c654a3e838a0651c0b1504a33449f734c3d0b39ede299376349064c2b28088be1d3c780892b1fe77bbb5d70aafe467b5b770a0774b57743bb9d386116822bd2433e0222476438aced74f4ed0b96b8c1a907c3726ab91f6d12c9b4108a164711f0002a5509ba316ad06488fc818bdb3432df9408dca35ba7bf3b02157122586bb57e84ecbab2107c7850e8c54114105824481b3d28bde47bf10f788ffe2936e2517afd66f181592b5e88ed657cee630681b99be1ca4a8b5a9604d171f9f072679ba26d04882cf7857a4081f2b6191a8b4711642cc19c395d0926a27816abdd84b5d9937478411dd78c0287588cbaa364457a0721953c5ca3f1cac2eb0db1c2da45ca9377928473fb2828162b5809677c12b3b4776348267f37f64168448d3a6cc1736d44a21d34b638a69a765c19d38c51c28b8cc0e830cd53c89813a8c7132901cc93b8ef5b49a58c6e4e36c1449adf8a4cf215626fea7bb66171ed20457d7345e6086a225dc9aeff000bae4792847680616aebfc748f6715708d19d16f33833fb93d2c8bd936723f8dca7949c8965e768ac59c3cf140891e57b33247abc13ba5ac0620d695ace5795fa04041c6484dd0708b50113f9e28575f8b4f2618f44f94beba06a26e87040143f504b7353d314c2e05f815298264171a899a625a2cab54b47a41a764f28764fd09b118c7ccb3aacd0870654f872f7744c4f57a971e35c823aafbda4aa135890741333acd9a9c65250e714c7a5c17497d65cb2352d0ec942e73b6219242b981b00c8976d495c2a3fc779423093818aa4e26397a6128d6da57af216b7a9707d4218bc7d28aa722840e36b85d0594d7f085408e359e5d2c5dcdbcb419c509205a9d67cad75f2ccec232a1a951efa7acc00605a9a3012faf75760c560bc539bc066bed1a256df4cb2a6c8c362b231d7108bb89c5bd8bb1f8f32131c36bca6786346d8114147c947b423f36999bc1bcea9b8cfce054299605175d7cf358ac0080c6dc2f7109537839326063b16635ce87c225c742d61466523882c8ca3c41aad8af34b96045c56acc29912940d584267a8497cf90a140cba864a63691c7324129fef594213b2b400e18628c50df79b524b1c231c958e26ec2379282459766d94316e090c061f259a8a368122620310578b0decc11a857f0f0039cd60afb9561e05eb2242a77b02b16386558fdf2b221c8a60b4812741b824c788b7392939826ab2132222c25347bb47cf5e666600d5ca118a0205b2cba7d45ce2966fd46c5e355779e367c027832ed281b6c6303616e105dc51cde8d9c29b8c26aed5be6ddc7a5f6b579489af4edca596485437d24e77959697509184894d40710a96d3be4752770ba24a31fcbce869b764dc97d9277e308b1f13300d5a284f63786033e2b6018c696f713a3f2841f8952b69a66f59b972269c7d88313c94e9cf0d4bcfb8551ea4e75e8fc745494b06e6360e6412878111c149508b2b805472549fc423ce996198d7043f25357a285477e5666efd96188f18b31e5559e6467a4877333c56aabf446488da4603aa32a8e24d07698dec458dc5848a899b8c855ca147009576ec11eff3a6d7c1bad751aa6cf1605a936677f198567c7364a271031a659269441427368b79ae89365adae62e5789b7b3493037fc95c57633446524dcf61ab7e970a2b5bf8b783f8de03c9397bcdff9c224b81fa37a324b95afb399444c39b2ef0552ebe01ca58b648b8556b1ecabff302fd88789a5ea8222f0c947510cbf06a0473589b15479173aa05e6834f88c8cb3343f8e9818fb719dfff688b797094119bfbbd3aea312a17fc70a0f9caeb735256d4479c2ea417f67b87cc8b15c692d9a98cfdab46fa3c2495f47022a407c81a7876fec3c39b51f9d56a0f9a5bb3d974c6dbb50ac834b0a27727669327f81a1ef40068b925184a60cbfb15d993c5f223aa923594512893da9a9c551ba0c2eb23419f53402b65408c64e04aac90bd2a5b258ce72e8413f1b18af455aad9c684028123b3788c1e8963fd666aca1c31dcc9a813860a41616af6cb37f6a06f85363c3930d8f13283eb2b679ac39c23788a8272a1dc658237b6c0f55bac7c05bc9848545d865638a732d059afd2432d8d09b7bd835c697869ea613f5220c941aa9eab49305f54ada517f98669dc4c35ad5049ed3249b15035a57ac2c7f768599ccc96995bc63a11447d9b4995567c1c24bc0870de84b7786e0130afc4893f9b53824ac3c132fcd9a6d4a0b6628a521e52a37a5681800d1540854059b5455eb435b13eca4d97099700c19a237cdecf8441201af802b64fd1343c51439a3c46f9f171734c7804b35ae9b77b0d90c34f9464ef1fc9ea9e5cbd645573c9b3c89290d7d7901988a70fd07845f6b71d8a7c5c04451b1c064c8a0207c4baee1948a003c6d2d5ab859d6872ba354910260210a2b7375ce81031471ca3a399346a3c542c1ea3201d19086b9056af1b45a2a490b643a58c011ad47676e828209f0b1257253d7d70282c40111ab062ee49d16a87ac19474bb6c6c943b156fe7ad43b8751a772688b51054a023291606662c2d7c2392c0f3bbd7ec2b4455a51dc72ed1504a2634039023ad74b016139ec998bab3797876caf718c5129a3eeecbc124b6ba499e10a638a72c3197721e2416d11fc9c667d26f6ed8cd3d765c5ce0779d99cc3162f9c64e6b02bee5d2ab2ef7c57e89453d5768c5123b28517b07c071736a33544c79fd704d41 +ciphertext = 9510fcb318ad9ae0d0f93bb6e7d350637f24ae8ff767ecf79d37332ef86018923791e667721cb875c353ffe6a71efa20bccef1c60c589ae430aa7b0001568fe38bbe76b42cb64e2503be23a6b6090dbfbbd4f97525e5581052cc8d9c4e8fb0672f077a9d00c650f69c7527a2b9289811608ee417f8a4d479886d35833b63787372ff0a060585982bd67e70774e0f5da26f5580b868a9549e2a7bbf8655ba5f965ba101aa9bffea2f6bb9d1b8878b4d783758de36f7de0bade133171bb9401371039736b8b2dc4cc4d6c5f2d93dadda98ef9dc90d46f49b683c4c5b1cbf007566ad38c4443bdfc393bce086ccceeada913fb24644585646250e9aa197dc43d53e5b7a849c6c230f497d91d2c4e053b4b078625690af560a5ec4178e77df7f4099b09089d0a38b0f737510fecc21ade8bdae84c13622021d63050fa7706472c831abf4eb5d8a612b6f2ff23569999b51ff278aa339fee6c7ed1faa55a8c77671db18e329ef15841e75cfdad7af6b0c581737f4c750a882aa28333440a7a9da6d4acb49d2988498c825fcac2af684d917b4dc9a91cb3b77d4f83936fb0733543e1cab7e58ac04f5b36854a16806918352c29d7f297025f84efca39e5f48c3fecdfb3a38f8a0256dc99d8a3aa2b146b0ceaf85bbef2a6f911d1afa2b96c9d5300539ff6f8dc651fbf8634d8f398770bcf4d3bbbb98526fbc84a57a548665512329fb6ff390e6f000558c1e0414ace2c6232b2b3fd126f5f86dd9191070ecb03b64842e682d13ece74ae4f06e2eb67267d159d2ca4771a2630f9114206b1ce2931eb9f669d870d4dd5b1e8dbf4faf208e8b449f8a3a780701ea75069c3b21af45c3a0145bd82d879f19b283e271e38a957a9490f26fae82478d537184c2519cbacdb037e1ab89bb57d1dae0f100984533235b8be0038f261d7592ff5a26941a99981b6a68ef73741eb31a71cff7214b5d1b6b653787a0e89cbf10901f0008285d8b1926d13c10adfb6d1d7344486d1300650309d6081bc54f642275f2d83ff08db34e392be8a6af312bb8ed364d479eeba3d90f30143a579f1cb376f31c9821026a9bf26db4a042324add4c980efbfbb42cc6bcf514c20b44cb0e8342d2fb699d4d3f3c615c89bdc9abebcb5f01a78ad980c4ec84214f63ca9b164508228bf046354408d9712d9e27d1c96dae0e6e0cca85127d9413bfc60ea989cf6b55944f1a2d29f9fcb9f298a6c4299397e0bbb25637d86c762b29cdfca48105ae5ed792e202c31d60bf8524783f5b56548dbdfd2bf5980e5edde3418976fc981a442be4df991ca785dd14f89c1d6b243b573ae963727a942fe9a3b2f9062da2306f8bcc8932cfb3bc37934ea1aafc620ace4c6aa87e051ac0305d7b15dd6b720ce3f9106a52cc957d21d49bab04de1b6c76e99b8e3f6231304d9e6034ff5e396166cbf7900df353c67a96bf460496b43548a8b67d1fb1f5215c512131f28c9347e7e0da707ca8a6e779f24150815505837e6e5d6f8b9f2918d71e80b7418617e89ab5238a999d470ee777a1cccd1a8636636eae6eddea80cce60569ad8a50366a32a12e3b589e9c48a83ceea42b168607a1ad753a8629bcf2aa1d7bce592923f4ed8d1c96ea8878de7f090de4e16eb189c7441a721096fdb0b4370e4081b843c19c0ed75e56bc724ba7f292d6196555c20bd8ddc0bae1f764649c59b652d25131c6ff5f50c79510dec5e25baf7fbdc7b039ad0e6601ff194978499476b8ec32f4fc2c098d91ed969f0aa5c586209042f45a31d62eeba46a500e9d3345384671d01687e5f47b1b18013e8c20abc3cf9fdcc84dd548990a1c8ba6cb034942d02119a011f71487682658048a565b938c5441973a102b0847152186e88a8a0df3d1aa87ad1d2ec855f6f9ee2e1884dfe1d7c1fa3ecca1c90e6cdaf6e3d2d5914e922677cae18e219a70759b26c86d917f7e503e49e462657973c4a352f328a22657e7097ff59bf8d51e6e47108ee402f9d506d74df083f71071a851d8a9b39bc6cf2bd506dd9292dec697d5b1ff05be5d1a0663e33b2bd217e6166b7a908ada370736eae9c6ce0f82e2475daae1a337ddc10abbb503b4d67ac8b33464ba77d8c59461a7e6978b7e5664571f4c7eb557a9cdd3e8c10f2a0a156c035cf08542348a24b175144858ff80e0ab82e6b490f9a3ff73dbdd00d4b3c6500165d5ced0c0fc95e3bfe03bb9bcb3 +expected_result = pass +expected_shared_secret = 5276f242dc9ef4fdf0d507332047fb7ee1078bd07f7bf2f089a5c7b406cf8802 + +comment = Bit flipped ciphertext +private_key = f6760fd8c08db45220b481cdbca3464f05264225a58e735d11abce723cb5366007717647aea983a44696a3b7ac61118f9d5bc50ffa6f6777b05d40359f71bacf7624c47a2e7c619d3d5053735936195c684e2c8be4d2caa19c0e26425416da4bcf38ae45e555ab9511cbd2c6cd70c70d70a7bcd20cd5b40d9975c99c1965649c6d961838fc38862dc83860a15753a23c2f7a2590e0c6cc31a3bffb5d04a594d30989e3a127290a477a7ac8f0909b04bc3932f6cec6f17b6ffc3142f3657433a44d90c83ec2769794cd6d99103c83b332684631b9550bc3c6a0571683d122658b1ea6f20e774963edcc49dc4706e1268c0713b816311c6798cc9a3585f0e75ad89585a9c466902525ee66b4dc7675935308da01164116b7327b7132d90bbc093f1621440c1c262943cb7860617e134866d7181b0743bde414090261c876186ed4b47cbaa1778b0d6e59ce13b51ff3c62269c039e8d8874a5397f4970cbf401d04308ad40c943d7b062cebbd6f1617cba48c9be94d51dbc7245c7a9a2791a7d37208ea8ce702559c16c10e8619bed00fc0768e748199f627135efa8c01a607e4eb475bf1695f6aa196d3c37f3913fb0caa7a1079fbf914c72b31f5b6718cc4c90260457ec64f1c9c7cffa6cb6c2cccf7d0a0a33b1e6b6c9ba18b3333d845d72b456e23221e3472e864a9e101061f319d09920c0743b2adc64bf1355e02f43cfaa65ee40b154b6b34dd445fa15375bb663c13c06615b11ebfb078858ccf68c87fcd5cca96e625e79a09e3e02bf74179a9f574a3d17bf2541697163607c61ca2450decd2358c1c6b2541b23d470d09400b2882b6cec2616051ce420abac5017160ab72f0240c9ba69e694883c9d7459fb5b23df4cb6974a9606526743105055c37119baedec82dbbdb536e0c3c205302393ac8b36239068a88e9bb23d2c81fe8948300fa260442c2df237d6ef4b0c0b139d5f07f8d9890a3a8a30f740f4fd9bfb1077f0b099d5c325e14e9342c340aaa0917d559383eda5f36f548fb681385bb45408c8ba5591965a20ddff864f5246f8e0077c1a0adc0517d7197594264cc5ae82005f053db1b4167d4a0b5f0863009ba8226c3a975c80c1616d5518483fca9546b297498bf69790ca192992d052f5167a522c69e3d4cb25d05a72484057191a9212cc002e672aac25cfd39a07881c65b9a814efc7f975a75f10434261b6aeb693e448ac42e5383b0bc5ee0eac401188495c9b7d82421baa6541ec14550ea9b74904a95e6874af02eac832c43e1004583cad64079dcc2412ba92f01b9b0be5a0b8f1c39bf2a6bc33b1228c20ba8c111b0f950d8669658731a8386ba533bc3efd2bb81e57386531f82b0876286b4cc64c60f3c907384232e893530a5bc829433ee8575895882da2c76a0163cd3838c50439d80354c28ca4666836f347c921301b143b5b502a467fad0345f037c8ce02fa9e27197e15ade7424bca499bfc90230b2215bdcc6bf7292525474e4d958e5c10772006d3a3a84164970c68417ffb27b3964139d57cb3d4b61e96a80acca7239eb9d0fab6d0908546c745e155753c13275efdab788240c4eb55350a592281bb9b0b8bac3779e04f8a28823a7025b8f750934b00b0f1d42a418306bc8c481e0f418a8c161150a55c411be6405539e350e0429a3a21541b28c11a5b19170b7650f41318bb3b5db532a7626706a1691aef322191b2bcdc0c705dcacd1c96e64211d8b43b52fd1b10e9c48cf28930c8a20b8349bace7b57bb5c8e1f79fc1b2c75516687b0ab1ad71927c0b1dcda5b04bc355fbb73b737c845942134c49be87d04fb34c6668597f64a13c9f5567fa20ce8431bab3717f4d099d29e34e9285902035439e711084505049e6a0496a22cdf38df35a5f56422b82b081b09388cb3a15b98c025bebc9f25c2074e50e78ab918cd53ffcd9c8d648916e72b8e4056a6d883c97229d78e3c3c7b1774e66919261250de419277c1f02f58cffa620343ba1c43790c6a044ca00511df1a5915c6587091181caa594893ff8f7865c5066aaec615c567814e283259619f305a76b558174ec5e9c25a2c4e7b8357c6c7c6cb4d1186c89eb651ee32db3658e55ca9e0509a0607abbe3b4894b69219a1416a23b44f66341dc02950963433c46c8c2fa67153b2213f42efe057f5860a2f3162b94b1215086cc83b01e37028f41707585b842f0a93d90c44f58675a65ba4e6e4b1d22ac7972b1bdae666d03a321bd465d59c546cb765f3a122169e20e02946deed1457dcb12dfe2539a505c253274dc3a4cd1d1a4c1fa589f590ba3d82d92186c85275a618ca412c60c5d6b224d5c35be755f4c480f9ad799a85463f277b382783973f68d2e659114a38f5c928edddb6ced02a1a3971d0348a15755ce48d7309ec64706e9cf62da3dbe923496c57383d1ba7fa427db66658cd7b945c2a5bf02662ea8cab3f5794445095bfb0c350146b7668055f093726bb393e427b6b84d28e0c6725848d60399b2619286f1384651928b246f963cc3b3bb7eef1461cb87533aeab816d751ee5ccfcc23b60ac27ab67cce776170aed38694a474bc23bc3f8c6b3952569b0470791700de51b9ef6c24fa49b50aea93938bc422b74cf4145d0680682f708865f2a67307b5028b056eb5992fa6a36476a05f3912acdb89e24121027a2eec545ccf91bf4f0ba7d903cf29f211da322498b00af429cfeba071bb89c74cf22ff3d418fcb1a34ab7bf63389827089c20b32040ea1189e9bc0f2a28a8066a12678428f413c9ec6786863e58f7178b6b535df65709fa68488348c698b4d44a30292ab74cd52e5de402b909185d396dcbb4291ca99f034978a45386e1707a542803d87092b7657d1f04c593d53da92920d28636db533cd9f3ac676a79d7cc77b51432ddb82ce6f1aaf2180a4ea706eb6378f5a19e82c799eeb940913c7fddc895520321208086af5795035a12d58496abc0517e47732e47394d27bd3bcb89568501f62b27e9542111c98032c81409080fa68172cf80a439e68fea97743cf854bb0986a2c6ac2c357712e424c0f64f2328cd5029cda119420d2098f8100b6009c022403920171e14a54ba7366172bbbb59da3a4d3927a113be11956d32c69a9b0b26f1ba79c8f74195666e423c33a8b74cd328a2e1557e06287826b240d1883b3ac63d9384034cd0b03be12b1469802c0342aff27487f1af6e6231cb75bb645a817a8a4307e103e5dc0b3fd774a1492ac924863af3cacba3a7c17b1492167812d41a8b8501d3093a148071955075c17a995e344fa12410ac8b74b5247effa942f4d87c3f3b703162199b191c16d99d305bc5f8e232d70a41a9aab7da168395d10340213fa1c238bb7511c3f2a1e876bb95c3675c39126236026887154c05bdcb246e9aa18ad4124412f378a086a3f0613a15d405677032809782d3d5cd58e56282726fe6774e00c63b658172ad1874552bbf9fe1bf0e1b08ea7413ef191064056ae729167d191ced8915e0ea720f207227512258f7b930f74447e30d5f63c0a69672149748db825739f6a1a8c8439435639979a6b3db374cd11e95f6cb07321ae12640b3776c35206b6b794820230955a01026b784f34414bd2a676650423c52300700987fb6b14bc4b06537468037ab309b1da3d409d86941003a6007fabb3aa37ae435aa845110b1b594e5e787c2fb9b035b08131642c26949b20c8f526342acb7924467452169cb452439b60298840964d89b420b9559a8c40ce591b92f62a07ae2854d378bb651223f8a3bce3c855e6c8e26e1b942671622ea5314491f41aa83c253372f2421160b2aedb0a25986100f6a42bb2b0fcb2567fe630177a94ea5245443f5c742aa426b727f88a2a7d05cb492c06111c08c0965a422a07366f1a9bbcb87dec3c4a0ca1239101730584201e81d899544c18a51324705274897384aa9466c06d40039d33798bb1ac9785bc436b3cb0c1b1615f99f76b1179e767d9228259e6503a79a432ff123d1ca815b39474eb734cffa64da718deb90b69df9619dd0c6871087ba1396e5852103424fc4311d1b2020eb5442cbb3b0bc664ce70306bed0666bc08166687aa4525a69c60d1d117e84505622439a9b0bb30dc01a2411307a5b7f7c4b4bb945344bd311fe224db88771e555934c2cc85942ab73b0892b6284f46b78d44770e24a3c3882650e444f509006a5c92725f5b616a7431fa1989d0ab77a0a05ca78b7fe90ae193a165ebc24f18a71ff745e9afc59c414b299a9cba0841c839818e2a6c749a90f61ccb3e1bb6eeb0a881b22064c707d9e90011f6490ad090eb7d95c31bc8d9c0ad057b4be7255a362422958fa35bd07284063f7f98418b8a2efa96151605e274e98534d1e0f4d4be2783028bb1301e2e7de4752bbcb093999bfe29e57a90c41ba4d6a959e1a0120980f6619f7bed4e826e71ced90764e09dabcf43639665f67f4a1e2272e6d3767 +ciphertext = 9edca5346ae35b6060eea5c602dbe129013761e979f20ba0073ff9b34e7d7e9e357a83fe22710423b2a42110c5b52e6a62871022a9892714ae4002600926746e1055eec32b9a05729eece855474d733328603f46439eb6ac2f21aa54fa43261e596dc74f06b3d5cc6f78459447718d7fd4188f7cd80e79d27d6f1aa4d200e4cd84bb2c079e373c580cc465a9b491a8f6ed64ea0d4352ae0f55a50b02aab53bc1efea72439bcb3e91e3e93538fcb4b76b2fc8bef0c65bd249e3381ae5d821e9b62a9c64585e7e4425925afe733bed669ee441b1a4fa3a9986d6545bf761360666583550ab8f9757bbcee5cbe532099b0320de5a80df11d12401998a912037d0d088fdc7ef7199d64f3788507229f4f3fc257dbe42ab0557b333543b3a3ca9acdb6451401dfba4ae093a688de50cd3e94e1bb157db4ce7ef5c041072274a413d34bb2733c08fb01937aebe55536913474edfb51f415d19cb5759dd2c98f1f836012f9bd69c6836cef697b9ddfff9ec84c56e2fb8791f7481c722c35d490ee5a752ea36e09feb2cfcab500756eb37d1674baebcc3a34c1c19a65dfef68872e823b0493bb39e268ae95529af66a66b1b0f679f53aece15919c172ca12007f20044a605f5de7ce1f106e0e75b957df2214201a2b4ff7371c1514abf430e394ee351480d9ec5a60b8d8b3d45d352fdac3eb7c1792273db093088e070cdccbe7866e248b810092a99acbea2eca7851d91ad48180d97377b13f932d85840a0b2513c318a96e9714f71b7e279240f3a5e4f933333819a30bddc63da54d0d34635ca1b9f1896b560d024931209e5cca8cb4681efc4e53f2ac86eea9bf42d2a9d9e467da5f2a4db2c34148c0f894332fecf0bea1d3ec8a2cdcb3cd83b6ad570335de9bccb45fbc94394a253bedcb36bf484fd1a55997472e6514096500cab28a69403c78d7483946801799b2fd1a4ac04a1cdbae392437f226ea11e9f683f24ee5af9ac64b2442ddf815ba21cc47ddfa53568f16acb46eeec86d8e7c4eb8eba2404a17c5c9f3ac2496b093fd14d78590e4bb88b33211bef570fb344407dec2b2ec30a9289531c701ec1d53f74e9c7978509c1561a78e19c82c15ecfd8f0326e79f02537e513a7a61ccf4ddc50c76edc0fa6e50ac24b801fe70eb6a6fea519a9c2e864a483d9e630831d6e07a2b5c79cc1ed3d74b07d17e54f42fe51136a4f7be9c8e046673b45a3e6156c464d56853f8228658169ef507b8529baf45aa52c0f9ce2b7301180b56fd104fb04c5920bfa9bf618cb7d7b1c3206943931c672fd6f0f56a7bfa1860ad136f88a06ec083422897e462aa65c60edaa0797d43a8b55c6b0526894bc2df398c275ef705c377b2376f0e13cbb6ac880cdced358c9269dbe1b63a642eca54e7d32f38115d4443f2c17032546966213afb025a2daf6574b0698f0602ff37bc44eef3860e66fcf6ddf76b0afe7acec65befa874d1a8cf20679a6ecad8d515b0ab638c1639013912b790d53b63465b9db6cf03d44b8444944b39d3aa334fbce7280f53bd21237b8472fb85de460ea5927a70239ecdee795cf7342db6c73ca633e3f1bf5b2b915c878ddb58bb87fc3d741ffd4f24ae69ae881cf3f0f784f1bcb4d4d12a1643d846f6b455b1c5d484976e170ba9effd8804bc79921753b69b23463c3312bfaa42df2a472a7fae778b4f42fdbe03400d549a53397f783890961c590fefe07c3ee6d4b20b0f5242a7de2c49f962c76909d8307af486218c35563e39d8db39b6580b143d0e086fc12f174c6a5930c0decd80a548a7fff976c3a7db1d44e948edc85367f915c7a4d08ed4d6a02d7ef5984e61007cc4638648c0d827679db32471a175cd869f0a6c884742b7dfdc36f4025119b2103736dfe601c06cd344342f27e62bf0a75d657efb89b37fd9642bceac10046437c0250ac9b77608b130411227ac178fbf383f8cca7507d0be31635047a9cda1c7ddb91633ef5aa91e0f6dbea173f6b12633c2c68545f5884b77159286b17ef600fcb6c9a27648b838f71f477d756cb536cc7094aa000c03c79bafd56353a56e295c82877fe9d1ac6f586abad99832bd9b8bacf5c27e54268832f69f8b4e350047081525e10ffdd97614e6b516fbff80b9977c6ea1b3cda7f0052a19e67117939c4e95c7941de1c98f35c22115a817bd758bb6d8bec7474043e6305f3da30e2c866202b9d61503400 +expected_result = pass +expected_shared_secret = 8e449ad95d75fd23e57cf6be0cda04c238c0287f1c01314108bf94d919f41a48 + +comment = Bit flipped ciphertext +private_key = 72481f0dfaad8f317f0322479db420ee60234608a69fb0b7965446089c5c7ff61c49a34c55204a8c9a32c6e2527bbb37c4e0b4fdf4558c72a626c875f8fa73a1b6a3906b5da08007bc35b8fd463396c56e23d771f1539cfba237094b6713693ef6b83a95e6b1f405470388b3339198b84669009967eb0b29aa91bcd0a13f4e2a1e6c4723888c808af00b3ca0261de22e2f224fd3cb17e0c926c3a25d589b8e58d689217616e26150f099a9b2cb80d291774cc1ac6bf50cbf867db443a1d34b84e8b907bfd77cc19235cc7390b2d7beba42c83e1b2f284417f71562b2318e6d8268003103a09bacae7047c8529ea51a3fe75c4955f022dc22a868d1c3254406ca26acf65063b64a6ec8c9808f2639a2f185b5a188f70720aae7b505ba1297143830c55980c70ccfa8b04fc30ca656a2d0cc655d187d02016679760972aa1a2a56649ee2c302546a05184890552cd9c964481a832ba85b47b18be95070fd977309d58b1ac0330c11c5d055985874283f862a59798faacbbfdc4b478cc0a7788b4208668a4ec8b5618b8a653416d3b69daf3116e9a666c252aac48ba9b4722d2cf5c29855c65a531392075586a4c2d3bb22d9067d4ca4abe8600faef27eb4536e1a02c50308549831af417414ca2492ee91b7a20cb94eb94a0cf59b089722b9f33fbfb80ec5bb5f3231646a76024c7b8fd44c52df658d97e333337b2a4dd26a09986d66e7a5c6e22bb6d69b2f10256a133c39846d201b0704d3a1fd63677572ac0ad4129515beafe794084c361b058c74832e39f34eb76c15eda2ac01435b8c9c2ac2f1165408212a035a09d280393232a78c82b6f33deab0579a2543f54485a4bc5fcf0434b2696cd35aa18a4b1efa114492a00cc1a76331d534c2c1717dc86a70506f62936ba4741c0be32af3f271b4171ebf20b13760c937f76595b53235d22001c59318d7652c2b01abf47341a71d263a1d96a242b7861dcfd21543527d810878ebd79d5404663131b11d396adfc6a8861255ec86bc46fa912aa55c7db8a4d9b67a20308668c81fa5579399d0bf79b72ed1e46136660216872c67d937e98c4466b12851820d266a4d9b4510d5e91cfd4a5b1ef327b7f35b00e37957f80a7ec7c45fa7a855608b84a49eb953928e971f99690f1713af4aa95c4792257ae72ad1912930db33942476d6b544ebe644cb3b691aa9b58c106966b490fa85229ac607c1c83e2eeb7cc88b7359065adb1726286a12487183c724ba80074ab409c785d19d367b5e9cc134c0e3cfd22cc6c13a9a5fe35ad29b1de3151fce18792e1393fd5c7539297d002281aa1b84c64146f78c5ffdd99a569c488a5b851ce1a44dcc3c201618c90117faf6a4b4c8a4a224604538584e864e5a041ed232a9cc887c25456fd92c5320f390cf999d70f97c68fa1969c9921ae1337b5c5924da2ebb6b0e6be56fba55a78f5076b362370f248513710dc3710f76c89589270e4c330d5ada52d0a883a155bba33babfdb89c5f153c8c55c774281081d52e204aab10298cd4a25e47a0bf3b738c8be3cb6ac2186b6300160acc6ec8ab8c508efe3604bb837b4591c05c063ea693a754617e76008ca87237654473de6223ea608a1c7461e3d57203435d17c735ac983006ec89f49477ac822e8d8ac9f4978a68832d736c84fd390df997caaad444272c636debc0a1d60986346619454a3732cea4bb30efb63c9f1a94cc1a62510556a627cb4531406521cf5ef603cff23a31ca0444a347b5e74743584784531dc5bac7114ca6da2c4467443cfa8b5db7bb7996832fe1d87c06999d30cbaefdd9045cf1ae33e4ce9eb477ce860ad396b47afc288bd48f91864859959fec1105c6a1092d99cefd802c2d85a1a496afd9ea41867b7fa5e366f4a5a6056240477c5c05fc6b4a87736371226c3281ee79978b3ba92e3298debc8d4e569b51b159ed33c54557859db9b536189c5f04c5611909e42582423a4a897c01b07a6543e63990db749fb95fde33038c1a47b6207aa3fc39623a93827a48585a2adfa4a3bd2a8c7c0399716b268a82a231a66f30374a61306257aaa138689c9dbb1160928a6d146d9b3c89aa2bcae027a30325383329aa57617cf8568903f4b88ba215d1a49d9e76ca2a8b2b6f0798013570ca6b4036b5582610aa104693daa464e932bcb9ac804090cf315003747480a3a13b28b4987381cc8d134a5d91b405030183a8ab2bf5a71ed2952084cdbd0769eb719bb526ca5495ada523905dc46d7b5b8dbfab0191a182839b1a0b953d7dd44e05845300111e35282d81072f3aec2292e18bd5e693a1e14108d9c75c12bf61a953e3a8ae40d5949bd087ffa6869a97b298ca8653600c3eb21d4c8ac8f374802b6ba927e700770b6222c47f95e07c8b5c96c584a3d6d05a44aa0fe0e0156ceba891dc211dd26bb78001bafa499c8482410475496accbcdc578db18a2fe7a3521b6958f7b705a41ac7a15efeba98ad093dd01297c2822e4d65a0fb51c404216d540c7ffe3430b7234af3e3a67dc27d70820502d354bdbb74b3014e52b0053731c951410f78297c1eb944f4170562caa3b4a703cef0a4f5b1b515623a026066d70031dcb883b79a362cfc7d94f7a111c70aa86991fd6886d9f407c033004383829d984c242c1b21ecbe1037a5d0ea55b2244d53f59eb20a2cdb9c3854513daf9a65c7314531317d0af510fa7bab82ea01efb5a7c07721300c057c568bd61a3bb4d55af5f4c10cbab767828277c2547100c571790ff404b03d925eb27c054c1b6294638d54bc222859ad01a02d1bd685e782495710cfd220c4340818e313cbf4763133a20eb78c1fb4688617e38de8e6b863cb86f201770e92ceaed7016998337c9b716ea067c493c77f444015e99667c86f60869e8ccc5e18563873a27ac0c165faf36b545a68f6c2709863bdf5d326dbe6855ec018c9f35663a208a9c32218215796e6cd63b07d7a9a45e4140fdbc7aa587ca2292b6413180fd0020ce610b1ac597011f5231a5b300c92999ec1a6a79350733a0de79c9c554c18f81a83d90905f75b5dea6423f0e3bf046c7077a33e7c592b7346c301d68a57c08fed40a552f75f0cb5759ab355792110ae3201a87a06b1ca100bc05ddb66680b25ba2635b57035406a0641ef2a113fa4bb8cf41daf99c975836c13cbcd79b41d26cc42963aaae24073d8c04f860a6f16c37682160119a320c5f8a0e52c9398943b18376ff72072a7da2a7efa32ea660607c7be665c609784c27f4b3220789822f6866021a4414b4d40db2bdcc39652c70312ec9368061ace009e24ab452dfaaae138226ca6243ff56259861a0c255cc84697cea76c6b5649763040a8604d3c118ff45b46ed9721b900889d9c18b16c5823804ca2e5263e63874377c0802411c03a3e40bbb6ccb60cd2ba80b734c589b758a35cb95de262bb8ba54da336f4863ad6712c2af127497791a4e8b1798c65b1905177e23f598588e6f109a44072e521b4721b31b99c14d9f75ff5b883db6b6f6a3b16660086926a4a52456763d364d0f59e202133c6a0a58cf793af788f72343952314de6f3834eb5326a131d245ccaa4b6a766b28b572c51eb67b156f63180c8817d2b9bf5812999678b5537caf1882f56a39fb2a22a1779ce0217c68a9a4f7b9c47c13195f2d3191ff113109812950314140bc11a046c6f333a4de3c8d325929e3352bd78c6c2960188320deaf0b3b3ec1f338c28e0c119f5619daf8c6fc11511194b702ad2c1a0a32334443c1a1a1503994ee143ac45b8656d15a7a5ea993fc581cf53305808aecf5295f4ac9b33e62e171b365530a707919f01119904ac9980d26671b418deb30a2ae7820e872e6dd9ab3644940a82b09808b08b5c6da306b46f7a931b8457eac600cf55af10b29db4a47d41e324fc2c5547435bd4708522a3286f298076fc19d8aac7cdfa52de651efef41ac522a7a5ac51363c6c6416902d0c9eccd4c459e5cb02acbcd9925548f2a010bb29757420e6a7aebc072c12c1bf519750d5f8457cc96021eab2c5c57d6aeb69983911ea60667184200ee2533a596e3e752f7499012cbaa7e68647bd26714c35acff4a0d5587bca364c6104c87d829175ae28ba2d756297baff2639f5d60a756319dcaf86b54875b097a498af278d1a594c6e6170b9ab2d1323fecdabc97c8b6a182c8b7986826b70ae5979a9f5020b171bab3724d87b451e8cb78a056b97e94ab4bd6629a23975838978e8b8fbbf9834d399e0df30b94705d13992fb49911f2909109836b72194f8f70216ab187de6c73385440479cb8c0f430118a554dc8353946a09bec948f6140d1797ad4b07aefd1c2dda373e925ceb31822af19cf2d1a71669b2db886edea2cc18aaaf083a152ed8c53f638413464cd5b597a4c26bbaf095a8f247aeab8b091ed615faaaf2a7d6ee7b3adeb205bc764cc05febdd7476d0239075876271f3da24193c5224290c391b7 +ciphertext = 9a44f39604e01f5f37096a15dbc053e7d538400aafcab9ce039a1694da9b4b428bd15497d81087c77a7635cc6bb4391e326b5b9509a58fac0cb0b2af9fdde87b5b7e1bb5eb910b511ddf7d94bb6acc2727009befd294f252d877552951144a481c49c8c09e9eaa14ec70e63ba4715b876c152f3bb06be7e6cc894aac1d600b967d19dc8722412812ef6206d1e4e602b4042e356592798b7a3e3ba22f2a077eb2378bbeaa3bdeef2a3f42ba7c481ec8d1d59d7c26066295b1ad384d3e004ece47db6e0e59518ccbf1a5674b9d1086a001b57c9f3e111c7c7f1390a981d481b3ca97e38f3c02911cefcc50d021788160aa5da93503b0846e30cc4073766d60e280baec786d5a7b1b9b00a31c680c9b5d04859287d7b36fafca5eb660c524a16076a2b8ec45d62e3e22fbaefa319c75468b8929dfa44e44ed0700b430645abc8b73d589acbc41dcad7a9deda1bb3d88c639eab54a65cd957b7871e2300e80b4d1ced2e8bd357b418405164baf90e4b2b345b2db04f4a7c0cd9bdf27b7ab317214318ebdf07621dfc0ff738c2ed09134f58aeb48928a2cb78296ab517a2365d81588845922b6a252c6dbbd58467bb9d12582179c93ddb25ec5ba3eb4c30a825bdb6f1109432418b51407b268ba1b2efca0b69f27c1fae4da9d831aaf0a81929d5f609c960191bc9bfa8ddcda39f21b436df6d2e8c6ddbbc2bffde162f60a8a8669fe8c8bbf5a7bec2f9f1ef9f8bc83a1489b21f2419b50f7820ce4937fbb139239d7eb39d208087c269faec1feb123f2ec6e00c365b5de5c4078f9570fd1445189e9461b04fec27432f1b26f404fbe2635a9f53771bc867bb76e0e0640c6fe97300799e2ac5161041f7e1e411640a29f555c311f2fc3cbf0bc00bdc6faa64e0ace7c349367beac0a0bf88a4c72b906a47236b702221cdf8049f0aa9a911db7a52f5be7402aa967e53e255e5d9a3005bd16164bd78eb88a2fa94db7701b00ad9ae702065da6cdde902ce9c3b1923c98189c8719d5e95ce40b70cb88e97b849383c4ebc5557d61b9c4a098e88e725ad53cfb3b9952b608d0a4b48a00a87d3952ab0672baad4cc9714204615d2e5a0825c7ce3b7686fa27d648eed02a58753dcc70a613a07ce943f4a9cf13d35070f2c2a238caee90a438c28271b438198dfcdbf5d843122732d058520e794802fbd9dbcce4524462a46491968c50b04d86ed475d67c86836d17752a0c3ee195e313a0f6a906e4cd8b6c636fce4cf16b2df05b3bf4d62110ee54ffe7562d584ed5c598a31c6bc0a6b558e4275c9695b0a16a5c62139ba55b3abaaef13e0b2492250809a602a33537458aefbb314e423e5e113ff453279e6397b7910b5cdd5d14d3b8cab920cd13db2a6defe6d369572323409e6c17742a0dd4f6fb6101bbbc92a8be053326895ac310c5d6623af9aed44260e8f508ee2cab331db50ae7f760bb1602a9803255fa41fcdceb5f36a889f97ce6286155e415d0db304a8ca7ccb0b1a78e207414f62d556f20c45bbed9a27353b36f52ca1df907178341bfc00a23420c100967e079a071c5ff27bb1616b325aaff9fdbfa786440d27e49cfda801c9b8646ad20201fa76bd7a36ddcf153e13600a275b70ff33c3b712941fb23f61da4933907b667e03141da4aa76e3846f4159c9e4aea5e07e3b6be2f29a97ffe778de39f2f85e8daa8dee56ddce6e6eb8180b7855db5cff723455574d00ba6b7651b8eeec41a5d048b9c53f8d53ffb0af39974ec490dc2edb20c89fe94856d38ea1731851362d217554eab57d7776093bf3aac8bf0de9dca27586fcf95711eb959b48828052f1015670468bd4e408f9fee7f3e8ec8ae6dfb3eb2fa6221a449f6ae5e4c66526f6726273400103f6f69259f320e6731fc0cebdd232390ca20b8aa1213cf4f7df8c1ea8f66f77d319882eeee2d22e053d9ac441113aa0d206e8ee45fd04a5b4f5c180947fe1ed0cd726b0f88f722b6a9a9b0010ea2bdb5d2172d94998a633eb12c2c447b1b3626337cf7c0700e7711281ff5c2097d9c9806de85adcac00d170cca3ffccf62384747c8292f350eca87eca585a4a09f48b4c6a97496568295760ffba13b590c8555cb3204abf2067f69263c282de90c27bc6333b623f55f65edda64e476bad6d83f2590a4b6e9b5e48cba3b6d5b0b06815a221cbb401746084a016d8cce7b48201988499d1bbb9fbed738fa45db3 +expected_result = pass +expected_shared_secret = 3cb30675fc4179778d427678c28a595a679be3c29500b9294c85912c07380de8 + +comment = Bit flipped ciphertext +private_key = d0a11d276028e1d61a1deb6aa47376179453b6a45965886ed6b757a3f282a8d19a02fa1541607f1730148a01b5bae76cecbb972ba2bacc36aec11b786a43363306cfe3b38c047a1923009c7ab20628e180ca025b4294cf8bb87ba6997b48ab746f2a8c57092610e3367ac71ab1288c429ba97683cb0414c7b05c50f3b0209d99caca1538557777c73196934640368b0fc8736141fb9b6a66a13875ae6ce25061640c30826329794a1e495bdc967bc815aadcc349d6d77e5954ac49cc396da234b48242996b0a13c1a495a88e14879eb95448ffe7475a171468858e2484cfae56031edc29c5c5bba03c2e78c16f98331d65fc68c292887be1b67ab8c5d9f06fa181b71258c636560b707b43bea9ac87c4cad740b0df62532a6999227194fb443465042a1bd436ce0b839b0c7e045a4691fb60748513fc6c08b8b530ac94cab9e5553991b5007654b85099c0236775056285285db7608b4b1a4fdd6787bc80633fc32b7cec781a63510be7af0ba74e5f84748a1c1275682c61e09336f3aa16419e44b8c33cf4bb64e4a1e8222386dcc4ae612033619e44fc0acd39922ab27c6b7064e0758a2ac0212eb894ad1a4105a56a0bf70ceb529a0f4a31d4f617e86763b637a6e81c84b4504b87e2ac00b92875546dbdfb70ce1b34cf70a213f28abe71bdcffb8057ca02d3b4bf78da01a4485177925ad516cbad76092ed75161642077b383685878fb27ad0677a40d19ac7e22c3f19964f33ccc1e2c3656816555d9ca6a6537a8712506e6066cf2537d15276ca00c7d226c3b074c41187f0dd7673a0919d433843502328f937c171c088033376366b57696b585668e8f2287a6e71e7344aeefe58120592d440992e6ec2842d4c1091ca11175bf146c2eced41e1225b6438b526b723f30682f55387de713a1f9f42aaae9af50f55bcffc3535bc4663d51cde90315da5a4b42244317cb8785b8d096c333b39b1ac7013e12ca2a178a955b06c770231fbe9a7f89c2e9615b411991d6f379f89206ab57bb368bc6b03e4a05dac091a02aea59693c8da62e81a828c1abffed24a8f9cbb8cd39372042fc621347e232f43f20ae3a222312b7ce2b4c63669044375984a591a8d682a9f503dac85947dc887c8daa63c5716856303c3f249f5d35a535b52c8033d24a8c7445a59d3f45693f6bdb6da632bf60cdf282e0f99c0005513efd4026e2ba1b126926a388194a386ff3619665a68ba669c921846e48b558a9b76b6628522552f47701f58a44eb44c7f4606a5c1480511037ab1d60a7ae58219f4baea769badc77621e52e295793d38c20b373b8f2da125b42952c7526136928070243627946ca69c3e08448dadca5bcc6cdf32868f056b6d7667d837a234860467083bc4d699ad55a674497b8ef19c7600005915b2cd67566c7c1ba66c903ee6bca0a898bc7c358cb1b7a97a7040e680b989ca0dfd6ad00a6b83cfa079da9c9abf86355604540f69d90536d15ca57921435cc18047dd44ac6d15f80346ae5d4bbd76bb3135a589ca97812569c6c312209b1cfcd2802f9267a3511200aa584fc6b80daebbca5f908ff6c78684282a3939b23821fa5421178687532f471cc702c011748c1e9565d146a1117a4628889101c1e9ce1993c6325c9881aaae7b90ed15df2478e30c9b7e1c00dde21bbf228888687895b59503bc6401dc673b384adf6f8ced91a83ca82aaecd7163a688f9d4b410a7a9dd79ba8d1405348aa7307b22250525c9da50f01021b72d1c846d334a2b819b19090e7f12385391c6a49aa9ef9a128d73191322493e437fce4514c219d98f9b23cc32dcf6b3cde5ca460863fef1614ff98b06096660c88bca340733ee51ba7c9469a8a0180c718008b8172cb1f17a17a63087bfac22716440fafc51416a39c06833bd0914608d306bd6c2e3129c79a73bf2b0a4bf5339333da9f23cbaa88c14cdb65a78c6848f5a41240d6291807630b50386ecb69ba040c0d3722a1a46739e72ad3457e60d80b9f00bc331c0599d2831de05d8665165f15c5e72bb5d089a2ada8670dc19ccb55607cb1b992676801743370d8ad0efbba045a9f77829c6df94002a54574535b91a57734d4821ca603e3304afaa47fe4066fdadc80b3271a582821adb00c3bf58c8f87a8ea7168d6a0589385b1ce216e1f1b21cb08665a606cdd6a17b81b578a0556563a3ac971c2c58812aecc4056e27bf4f2ce0c485789fc62a6f30a6d944ce5926ea3d3688bf79d0f64462343612a3b308665843e14240c2b4b8c2b2d1ee9a337c6a986b668d5b88932ea1a01a1a4a7c10e97937340aa2c7e484c7159bf83f65ace40314ddc9341cc0a509a31b785b2e6105d835ba6baaa1c4ef931a9027a1c066432a54f28a119fe3bb40895089bc323b231639485902dbc13150994af0a3f64981133e44908d992b0427212e36099e0aed0851a41f4a643569259d6129c0a53c680785ed9399d36480e7260cdc28445391ec37a431cf35588b509ca05890c7c390123a5d827812c2ab24273b3f3071b47d9a8377b64a09b09f6562811bc100d785a979659cc84a253a24138eba2a3027fafec4813c1abada11eeab0b158dc93284a0bad258d0f192a60a89b06068b5cd80dd14c03a56014c3dc31e0c5904b757de13ca6bce9aad947513b924340288a9fc42fce85bafc95299dc896c1108231441b15d190d9a4968db92dd4e475ded9107738c0b545a87c75220efabd1e74b0e632b03d308fdddb919de3bbd32c7a5b049e30661668baccc1b615b449322c551164902292b123a8e74df7a12965c526ae7704fbc008860878ec3431b3f48587852d2d79b9fb8bcf20a9b659fbb6bf5c96f8145b00661b6692a717fc25038c9ff0823f9e73979a220f9f62a2bc5452a1e16a902a360efa4bb9d68b05dc272a248562336c89fb95d4065b08c237e322b3bdc679d5c8069ce4c314bb28c0e31e47f16db029c778ab6d6f1294fa40533ac37a3f00627458c2970381b49a0c67973f8d631ae0a68b8cb16c8f820cfb4b0e1c6b484d2b3bdf56bd914b9d4c0979bc030c61cb7ccde8317793956c9bc52bbb57f9321742a48db0c464d3eb7459e15f74412966e9363f13bf8ca1bdb5219e1854a604c35adf64b440a8cd6ab6091ef9401b8abaf697af4b656c70aa63ee5c196a79c43757acc454a960297983920054b9128376031ba11d71210a80c59a4cfab8142358e3d3ac4ae2699c2bb751788c284b7a60ec2c5a5388aada9855866a4e53193e219217b4bc2fda57f86855a0e60e4d37314687c97f5c34e82919d065746ad370889a5db78b0e3365afb68509db096c6f8c27e3184e2d8b0438964d00986aae17457ef869c4e3ad10465340a966fe15ccf8d096ba1b91ae0384731363c9b776bd92a6b7578adb18a046943df3925a1318a987599f7ce7aa44375c7eea7cc86693d5a960dd770e45730ff1f07b374ca151c50b6e583aeda0b7f8f49f300a91f88595eaa25ce394be92fc4dbd1071e6b347eec815f549cde14c7819fbcbf67cb21c48acfaf959501277ea71bd026279be484795b74d2a182574bc30fafcab5c38af9c9c115931471a29b7186183ea496865e5303c6a804179650ad9bc753a84f0671107d67122848b0e28386268cc234739bf0c2bf3f89dd37aba0dfa95c2359c9e784320a3b794b65581a6a40dd7a53d395a45f187b53a3d69d5cea29baa58a5b42a5925778106b1a67a97f486f0170af9f20ffefa5e21b02dcd0364a273b50397b9148a4ef7274317230662b185ab4a9383601603859d5b4b80e5f90ca10332822a07609b942e118db6b502c52b84b03cba0cfa140b192ad9db14e31207008799f399082f5ac83397b20e609242b71924b16829729117c05b7b8b1d52468fca690a55647edd65080dfc9be03ccf9c20517488751c1c9e3418b6dc73a24a053b1bf77e689216952701a1b99df7cc8fb407770ba526df72b21265bc8af3227f95a380d22ef04cc1001b15ef5321d23b41d250aca9803a1ca22de2d43cc2d4c9186724e213b0316842efca383830805668365ce353aa26cce6281df9e07e4b33c7f1f864089b5f08d5b36f109823f41b408a2d7f90202b3cad7dc199c2eb2c6bcb265e68a34d931122f96f82fa8f3f8121221b62eaf738f9d9582bf28ec3b6bc891c3658f373d68ab99ae74da62cb5ae23bea69c718b43b1d7f29eba8bc4f599319e0449d16561eafa29f87695c8a66a7c074bb6a02820988488bb1c8fa63ce1d47d44b24b67762093706552e41be3b1095da23b1211776138589b6c8ac54825e0093501f708882206af082651e6bc42f8064b9baaad3c56ea7aa207b04b827c6669ac95ac015c359c5caba0345bda3ac371996620e0f9f65d053cf8d5f0924e824b66597f43e5ba17fcf79f5595e268a420ddaabb0a47302d53b368825d44c30dd7d66ac6eb6f840e8dc361042af2b5380b7a10ca11a8a4b34f457109e02abc16 +ciphertext = 1f216e7e4535ab964329e3bc20ec6b27863c59b991c885c0599a35a59ffb7f2b1a80d11ebdb58487529a7b61612faa9d613a411195a21ac4732dd8406f8f01540899e077d516ff7b8d3abeb534b4a72f2c25d094f6986756baf0da59c06e9524277f955d951031b285de8f5b5f702ce63cb8ec08336405534d2158dc30294b7003b3ff581988be9a8656a20c6c34c6c93d4ad7124d4f1c35a166f10a977e61f4a89198a12cbf029190a98bb734d9e85a37f35fd9e67a79f946a6afce26061ef5ff0fe31a8c34e5310693f5871b0912af73c1910cac40fae77703ccf5bdda70daf6ca6c5f087433efe8a5279940d933963020b23ac72ccf64f27477b421d032fcc599eb337c8bc0cdbc050fdce5665f80f379bc7598268acc3bd7e5eda5855cefb90c73697e894bfea9a317031b8e0dd2874d175f50e4d910bfbd2ee49c72104043b45895a5c6dcfbac4fd3a6804268479c32680baf7afd97af4eb1c09333c24dc6ae87971b3bd9061a5618cdb39e6856779a96f14e186f197bf4f2cea3db7a3f59eaa8631f4729b0df6f3b9faecbbe352e995a6fe1d8561732effd863789bcf818263a9c73a562192937acee05331f6a029d499b2ce3377a921fe35729b3856d0da7143f0b9a90acbbd39d5c12c6fb97ea3eefd0d39196465dce075165335ceb6ea466ea865a6f352d5c1a226267ab9f3c2317ad9228a8531c304e7b13282b55b8e5886ea9670f9dd14119912b01bdfba405a44e935ab0fd5e9ca703178ca138dad6d88aaa1152a885770baa5cdb46e0279272f04fa931b91de92edacda3443c89e6dac86dfc1b2697561c5259cd150429d6b024775a2f0e8234dce94153b9d2d79b9899d0be4f58cb56ff40cd89b09521f1db430399c34d883327c723179ae54ffef1833e5090eb78304e22d2ab49995c943e956ce7b0a29b56bd8b909cb0646ff3d3680bc8fc3a09ba4ceb91558dc2bfbd1c193369c7f8ef17ac935646727184ff878adba20a99f5e8f41db5687e24bbf867619503788f8bdb899a83617138ff4ada688bf064dc5ded3ace1ff3f11a8d57c05ba04b190e6f1fb33569533e24763f808addc4bc0c1b1562898411592f3035084d9938df9e63a044ad48a559a439eb08675a7565004d9a71bf78e807389bc004084e0c4873a4f93a0a41bc5d50f4cad07554a67605c2f7a6903e8ec4cb462ba343ba32ebdd45a7b5841dca06b794c51d7b31844c0b3592fdb81fa1552e0844141eb970f68da6fd675d910d06af2086f0b23a294469b452317410d9075af4a8cad3aeef8e5619ad8d6561bdffb9e423dd2dc79e0b5ac9a6fc66f5874c41d4856c8f3222589e03867f84d1bb85a96953ebd2e22c52a505a137b25249f4f3cde443906151516c07360e14b91de29062fa29e4f1b5055b7be5910bffb1eb0864d15e2091e47a76f7c5c79c34c950ed89e5912811be256e10838d36ac1e5f371ade4afe5f2814576f5e6d446b413dc5438507e0c7ab7aedfde945e62fcc4098a717e8bde7780fc083cf567e9015d328ee03b49fcd6cbc4bf6319f33026732da8ab705bc07e51cb6189eb20cf898e2a2caeabbb2b6fe05984d3b0ba9569900414593ff63b4aa569a2b6c29b6f0954cabb65cfb3a71fcf06e7004d39219401f16d1d4d2e5f165093ab6877ede3cfc3ea10b1cd3b9d4ae6f6a68c6edaa1c0b87a94a3d9c3a974de170715641ea51f63e51560fb9372d04197827235b8a5b14f738f1322061d54015927739dc421928d911217cce56270fbbac0e5b19ec09272c665c4b59d9741f67764c8ecc7e6f083ff9ea5dec4647863713227bc6a6d9ffc02e2d35fb75873adc2036e1694b3d2d4d49fb340152a80016392b674249e5a22d7640fde9dbdd157305b584dc99b64400aae4563728b6f8ba7791148365c6ef7e861457b8333ebd27fd6f12ddfb46862231fa41e15915ea69bda33b0684aac6083a3dc8e8b724ba172f991e93763c9765285d06587c78a12a4ee1c78428cfdbe3507d8342902d2b73bf7e7c0c502992fd493dda2c21eba992da000c5ffaf4b5a44a664780993f86922daa2176215bc1b6ee5b11b5a23624b4d4c7228724f7319c8e82592814d1da912b572f2030f89a4e64ebe0c53779fbf363aab05b40aad08ea67670710f2c2a2b632d8a544534b1b112200a6f3c7b3f863e025c07fb7b63786a8f78db817a98d2074c44aa86b82751c8 +expected_result = pass +expected_shared_secret = c9a881f25bfc87bb841dd15c0f9842d186c95d9b8ca6d15ee8d8519a668cc142 + +comment = Bit flipped ciphertext +private_key = 1ee34e5918beeb135792d2aa28e53074b57bdbe061464c052a6649e8ebb1c24c6e2b19683cec14f8e61fac36afe51b71d80c61e434a35176a5ca68c271e99dc7c71d822abf675081c925263de7bc3242813025cc4a454047f2c6833bbdb2382f06db72b5b938795c65d6106d69bb2e3ad73573137b347a37daac26045746cdf3afb6b6485339b082b10f17e15920b43f193a7bf25323cdc39952b8ce43425ca6fb4d9f2bcdeeba68894627c811744bc34e0f46ccf20916b25143f00377c871a3ada80e60a27222e957df356c38e48739d3a337cbc838ba81c588154a5b5806e8cd73dc351be675127177435894490095558b2a025b653d78bfa162cc5caa09dab06a2a82302480c0aae04adf747544b58ccf8230024b52a4e206321022c2e913a8590a3888386e36649ab3a89b970c3e34ca1cf51d76c482e802087244a856ca2246dc6512a70e4d522d1ce25231f4cac65960024547e8f60dac9099bbf875a2b20d5336abae077545a6b4d2706471f8a136d562cd87551699541d717bb12371a0d480348a867a7cc342321c669ccfa5e2571e0cafca061c5aba66f5fac7e42687ed1185665a3bc4d32b21c851c7aaa6099a46286429c771437dc02bd416b1a39b7e05417567b937eb0569f544cecceb811565428e920c3b1a4c853854e76c4a2d77049a8a9e54259386a75db93555361b717656615fb8cf2dd276880a47e8ea45476bc4dff127d936b369779ce1c61f9d8bcf9cc50e87811840f794cda735929b09ccf0bf6dab9c320c0670b1741e8b04ac3328f150c58ca2601f0b1b17da11474c2b7c29cee479a2e86a8ecc6a78356186587a9d5fb74e51e3350b5b66e61663d2c58fba385968ebc00351013626afde5ac19fd23b34a1603ceab1190881a6bab319c98eee9b4fe4e440ab93c7348caad7338d7eac923ea33cc0808e0a37632f013852162567e2ad6bd9749de11a133973bd5229db401f79d7ac6e552b76a3bf025240710926793abbbdf31b30eac06b533f3ba0389ce28ba4d954ba369bdc0c70ffe6cb9e6cb5aa27354e303f7a875ce6a24a11059e3a4c16b330a37692975ffb2781e7a031666c96b3108ba49abd351621632e2b963790e1ac83e02caff6a63d3aad72c248361082125cb234e2b5eda8575e53510cbc662af358f98b600e3b1934e2784d066ef3d3bb6f2071768a9ef6f45a09539bf79cbfdc970ef42112c8d96d0115a1bcd7c71e8285552c6eebd28612fa61e365615d37b3d88385cdeb01cb34a434d2b2d920ad10212c146a29140c5fd94a542d96bc55b567c6a6ade8e88a64f8c592e7759b52549d220a8043784b15bc18161d69b498e756a37e6c6557a15b6843ce4f3017b65428e844047fd4be08b25f36e69281d35611a31da6cc484a0055026214c3db6ba1b7ce5fd06f71e2af6d898883a7cd464044aef083da783e9c0a2ee612a29953c7e19b50d3180535784af01a48a228843cdc628d011c16ab2808981342436b619ccd8c82164c2154daf59e885c1461902853da859439c20a8cc65d3622dd967bf99619aef315955890710234b164abdc536d8c598e86b751f851a26ab006b3f78ec1e0a949fbb89ad4a6acb14978270fcab33e62c38190880f462c31ca2b7f2a46703e0cc0a19524d78937c2fa86eb6871e0737e8979a01216014f4aa58b197723faae72e7522c348ca10b1bef44ba6c1c25a5243a7683368f72222ec7765a1730c33bb3a5c0131d0921e49bc2d762954a16ca0abb093bf73ce2f03113435419cc705d6883c7c90aad4a9ded3642bf7b240946a4f80a013921ca42d589e59b683bf907fc723aae8b45707b60bdf92549eb8f06a75e268c31117934d3286bf5f0b1b0949fb6687efa5469c54b48f4831d7c4b93e7e2b17bdccf3ef862ef872ca5e9a6ceba6c2a8621ec16178d9407179338ab0707ea775fd4b3881b1a3a08f6235306664b98a7f7b55a86d175a1a1064d63b4e5a2ae2de71be4db6830f116a76632c30b9aac5ca1c5a4afb4f0acfb007c76e06e5de490eab81df78235d647463f9620d1607a8a033d7611c9fc32026ba66e398cb5d58405fe6209c7bb86d11c44807b3a5241c3c3e3661519542c3a78dc269af389737572394d0824d7e9ba206b50ebd6288060cb10228da1126672f6a672f59420212da5d821db3a101be57f21ca2502bb2e7165ab7c287d6e71a015555f71607bf8da4fba6881ed1443463973570b9ece77373986b52677ccc3c27d8e11803401d0e5cb4112a938eb093100353d3082ab0e958a53c876c2128cd9d5658d8948cc490d5fdb81980348bb29037432aea4f60ed3eb8f0c9a15bbf20994eba85db7770dc9cb5ca499fa3b140764647c8329dadaa43785a2d138096511c93bd920a9152ece38b2b194b020dbc1fab83015e86269daa002c8a4a094906da097a69192a8fc5bf839b2f9f03d544181d8aa0a9336808056bbc793034cba61fb7a1e3a3a6c35da10696cab8c1c72a12b1c94877803571729fa4bb7d806b91b06eb3b1d6c5a58c950570b3409a6163f4d176d4d5966a0fc91f630caa8d30a59a95159a2126c3b39f89b016cb014ae7c2d52468f19aa4ca8ec745cc16d747522b31cc54c0c85a252c4cca02c16a4615a9b6532493768833620fa15837c0e8aa52defeb3e7c43c00cd7a3f608c96f335303241e462075faeccae923127dd821bc02a257d5cffb5322f3a9b4617c0e82938cac6a39d3f6931b3721d0a088d1d683e27042a5328a5aec2d7a9309cd8b2faf11340b198935f1b73e7322ca3b883a6569ba0cc8f1273031f02207d3b722b11492b5ca0532cb03a982493646c828899c65196ab1349d37b078b9a9f96abcc24c7e574aafb37b7e69fa4ba15159e6538ba2562a15f2940d49c3244903feb5ab0127bafc665eba888b1ea95b5b2836836ccbad8772a4122e28ba0ff88511fa66c63ee62f9f455e26e71c8a19414618cf8bf847c1310f4ed55884254115d55a3ac763c1890e5351759557831f591ba1ac20018ba219e59c9e80962b4b01534138feb48df10bb6adb984cd8acdc1d0b4aaf0c0e4732413a7b83da1063cb94160a7522829571753365ae18b79249136246e19713cbc47680b5576cca6324a77aa67d082f2e354030a48d583378fea3048617442a8928b032ae6485fe2e99370975c8067cf90c7510a69cef93c55c16b7345cb46a9837002b45fb18097c8c2791255112a940346dba0db476beb80630d8272e25470869b719e006ce7e97ce613a173f03ab9749f64b8328b0b112f56a13cf839d96b93b3c2bc9c956f7a6b91fe3bbc18d088eb5076a6a04a03604888e6c1c52b71b1bc64acc8ae51595b6e131a9468030f51434f4863bb36788c7c5c0859a879ca3c27a5b09bfbbfebc800e25109e3062a2142ab312520be667e2167ba34041769f200eef0644c86b0cb72bba99193e9cbca774c91949c2880324613fc3e6ff49abb25c052271afc3a293a048991470a723c6a18bb76f730181e153c31f75d05969815daa65cd9288ec8010adbb9f4d36db52b50074cb6a084c95fc00104c7c13d49060258c82d782560c14cf6f09863415f0ce78f44513f1340487ea59910133dedc45b2b022dd6db42e16b5463005d089cb51ae692da8a4129c90e003544d4401d6b6506721266ba381c5cb06e184a14eeda5d0c4b9c5bd58707e6816ad880293a019e777e131815599a6cfba6a4d3e377a749780b59ba864c128b47128d7204d71b74009457a8eaa7b48b106a0bbeb2779b3ee4983cc890ac26959e48cb44f08e8ae2118c40c6bd38cf35c69c04496d005b085eb710c1032b99d25fb2731ef2c53669006abc878a9e59ae512991f98779ea8c76d7309d2cf183912b46b32659acd2cf19a680c129b37ba74e39349fca9579de923757d41551dbc0b81896e05010dcc954e182287424b0c2f029a742c77464cd124468485cb994c5bad5c567c6fc357f6877412601f8523e25a762c957916b0909c45cb24f0449dc539293f99a6bec7358c8cfe38b1c8e8a68aa44a4a4602d281085d8a7aa77687955241b149971b399735f6338bd09547ec432e4e882e82b3b6efbae3f228ba62aa4edb009ffa77c32f1ab9372a871462c1aca95eb3aba6769be56a595b0c3a5f85c4ae1d46ad9a8ba887cc8c1a19460a07bd51c1b32d9163b9b34edc1bec5c759d640ae9e6a6ccdd274ec66ae916967c0998b45d694131c43da3917ba751e0d6c2ff1d3cfe773295f3c3a5a1ccb9f403552201441303219183366f605ef0bbee2f354dff6626c7a0ec7cb182210a4a1f3061d90025f6ab77cda808ae7160900590450125cfcad2ea8626cc98b0b51eac18340b98d2191c913018194c41c19f89e6442dde632970abaf78816b01e603692c81fcdbca208576ded7d4b2b76840eeccb50f5511fd74e015dade5bdd2048407bb7f55a1ad1c2d427a500589c54c269e7ac90345cbd419bbb73599dc +ciphertext = 3f67845e3740e57de61a6866cefbd095b124b6c270e081294541379ed138b4b40088df58d5e26ea0bc02b0269d928cd93fa330c0e873e8957594ec0af4ffecf7cc8c1c44725411299c4d0da047128c41d6537aa86004970f5d93698c2b3320cd35b99587572a8017474b7dcc0ec44d24796c8332f85fe0b823ee5662b4b32141de7e1dce1c017a2b6570032edcc3c41ff201c5837ef2424aba0cc65255fb271cca4940b0449798bab0c01928c19d09585d0daed7570859d24724e9d928bd26ba5213d66f313667c727533987e6e1b9ba1c20ae8aecf5769909dee2f7ff3c4a37302d01be8314d0f8624a492ce33a61fc016ba705484fd5b1d5990294fe193533c84f0fe3b06e38a6cb027bd6cea736044dd5445b0fd1e728186313ea992b34fc13264d5095a6da26c28325d4c60e64ff274b2d29ba3040b98ef12996ad801b32cb6ec8462c353b44511b6cfa39a438bc187650eff9450c2fca361e709cfd8bdf783ac7e92d6da7c0b17f5a2f995428cf42f83e27d673c9466aebc87c1302791b50bd1475f93e406ac6228d16326b09781cb7802f99779be9041aa29a3ad758f037616d09b0735c4f26d7539e2da14d95259dffb3fe3725152ca7445cdf46f0eaf6d07abbf126872e23419c222cbecce589a68a15facd707d9e1ac2d591808bff3b8312a6abb57b87c8f1498e8acccbfb6d6bbfda3fc52c73465907a01098bb37cb62ef6f4811f2a965b584ced8c096cdcb37aa56ac672b4d6a6eb3a324ce4735e681767299b46c41deab4c9e5a2c4747b84ca6f02ddc7618fbd3d9b343d312adbff1625618d22356968d769a8463012cee8acd2d4e48893c2843bfe005eb85d20f684d6262482ccebce80508effe1be57535f40382a77b1ea02e80da7f93985b726d937e7185e519416769c8a9a4d552738eaf59dc2b0d941fce7a0d51366369e3402f1aa49a6f5dcda90d738a84de357cd308d52518e8287f34f6e17c3724fd74526227a71790c11639d646d214e6a6476b89c5a33a8751f91b9a770c1cc3dfbe026104d7f5db9acf0fb3b6d9fd3bf4d4fef51f5481bb0309fd57a2cefae1c473bd64438f2a902d2643ff5c7610499da71400a223a5489d21901ac9fcbdf40a91b660437fff51245e5da37ab27da2b2d1478eb85e245e56748971e6137a058169bc41617a55e8090e531550721667559e0b9964f88827f394b777e28929c343dfe6598effb0646a04b6599d172060adc8b8e566f2fd8287eb2cf5b8633d973605444b2e50bb71985f41f5c67bd5a43a141acc75d170858f3720d9e857f9118b318c576ef48ab82858afa37b523fdad502d4b221a0240ec47c085d0e74cffa32407746708951ec62a47c2e7c22073d7676d1a95b2e7ffed7d57c82ffddb26353a324260e4e2dc447f9289bf5c695efda8b594aa62bde7336867a6dec1952f789fa8d20f2ec64f1df5d8a17ad925461b97ab6c82ba1a0a83799e980e695afb610f6e73c1e799ec24a4a89d919a7f4b9346356c729cad21472e432a9157afb6a4b0967ad36a5450ba01f8fd2d083b5cb0f4209c43457c32c6cc71f344b5f743ff68eed499514a8d40b3a21cd38f956dfc1e086a91ded1f6e917b69cf23d58af13573785a4c09fae2f11be5ac3c06abe9c17760112d945cbc89eaac096713327fb11e9ae1c423d7a8b53fbef37af0f8b4e5601ccd130c7029f1fbfb7140231241832807affb4cb6e742250961a25fdf85c37c0c45354d8b52e222859003d333bfffa0140c517f6ed747ad41138ca654c45732a4d49e3633d00b288e14827f519fbbf1d8a087ee0b88540526820e64d19bdb830235eb47045c41ddb56bc3938955d31dea43817cdb405ba6158dbe387494be25d0f0f631fdee8a04b1b0e47d84dd22b990497e00c484a34d1f918439d960e86d90690557521f6746555a5e2c29cb232159dd171c648a9069bb2ab66d8e1d4eb9997e46ecfbe03cc7b57e3637c844512e0d7b1ef446b45a9cb8fff6ba24588ed3914f35cfc81561f73f36f01d222b42f72a065c47f95b3e367e8205cdbad1b7118a1e1b992686d0c78f6d0516a34f82e8d51ee69edf5e09ed772e853cff1c9536a90663ba5c59cfa15920ab7dbb35cec532d7048b760eb0fc3e090c2d7c4fbae4c78b8aaffb2d5344236b6260eb1480ae727319357d3840913fa01e17290b950a569855b4e3ae3bc51a8adaceaff6b7 +expected_result = pass +expected_shared_secret = ba7f687b375c05ab36fd658ce18c66f5fad5a3dc1e537025730127388097ab85 + +comment = Bit flipped ciphertext +private_key = 6c07a02666721ce5a55c2c0af527026f4483d0ac869ff32d98c72d019748a5fb295b851c7373ca782238db77c5baa24906062ed0b49e8956bc0d7962fae835499075c38972bc7c0641798dfd5381a534aa03196f57b842c519ca22d72fb9759a31e92a49fc2a63cb0eb464c027bb63e7d805ad0b7506b99836b48c347947c95a4a4125a5a89b01219311a855a0e981a704a60ea9635f96478552f1b3fcd168d212c6fe939d13d290716464ec875028e431ce789c522708014b8afc3133c9927ef8b69798b498d7804162690d7aaa786d20c3a510757639c9a5674efdb962dbc7cd9878669ad42fc29ba757c6c6ca6cbf83e18f855423ca835ebb8820d4761182e536c98a62b03bca9702918e496157a696f1856700499c8f97c6a9118deac17adc57b851409738312f0f358be6c4c40bfc2651f05dcf560e479529ce4600b882a17e49ad408688bb79068939cd2df98f4f82b46d0b129673c63fb7af80c25f26b729f4e41e1c39cae2fcc28fa90066fa9ca1a7346dd6202d13843400686b86b6c5c977e61667c1d8738cf8bac60a7fd2ab4e7ff26d31aa3f9bc73c495714f557970d2ba2a0f88992452740558646bac319402824e18954c370869cc0c4548e88c222f96002730546c5f92042864f9fc627c4e4a9a58936144c0876d39744f70071d973b0c7b6e810cd9de41bb38110bee0318e44406083cb48091367b4ae454ab28fca9ee359a1318a4145d94e21dbbd39f14817ec7f1d608dcc073dda70733536864ac50648761bf8f14f95b47b5b752a8f0253ab80b80a149c97cc1ab7fc690884000c42142f536cb622bc463537d8a530e2f6bcfea588028160ac549176816c3ecc40406c11579bb9e210c2ce41341e25b95c203fde091646b122b244aa92f76dc7b0464dc019622bc7d9500843138285e1bf2f539a291c6d6f41ad8bb29db5105cbb666317598f459124a4d73acc5b1f02362cc8421665808d82152d87eb91cc26a39a84c06e2cad91122287e38de45b2d92e4c21db8893c241c18403b8553b4fa043b54e8634b760fd2348ad1e5b3d9eaa9df04a11fbc1992e2c37e93cacdc2921773c851199821d351aeb99fd011b553a70f80b74e0954152c5050e9b15c05ca7e743c02656505c2d7743a3ba3bd2487b30672b152046e39357e4577ada37a03a4878f0b453e733d022353bdf3654d4603947aa12ba687b4aa3f96352fa2d5691dd73266c63b89551e49cb2175039f7c968c6a7b0587d2117d73913b4c03d6956a4a614cc1b2505ddca4d1b79ac9023b11246012980c46a5abd9a4b4a88bb7d6c4c2eb11676c5c877b417f9259c7c94cc47dd8463e75c6573211d8a957522444b793491499ab18c3a833dcaddfb5bbaa2ac96d305e2e7c4d466600b70745c9922e839441d3ea253fe0c7f510076969778de9a667d89f06256502fb53f8783cd09c264dd29f2ba754009d957ae6bd1ff4361af3c3e1e5c8deb322c7096144765614cc71ed4666a0f3342731c1d5fc49986a5748465b10d0c502ca067bb76a262475f2c3a5b3bcc3ed196b3f3abbf0885e43a071fdd7113d9c7c5eb03cdba0b6f6427981d764b847aff123cef607a9e7649c2c7036bef56ee3b55fd2417fc4c5ae6c231f751691a6c09a93ac4ac2aa645eea8a212255d134666b3280d3f60efaeac0196497f242982f2c10c34b8b146b4641139091100a48445eb5c1058eb29d3bb3910ac843238a17c4bc658faa2d6d53085a70b3eae859828c56694106a6e654ae50780c41366ff84f1ea0074e3a6f573ac038261f5d6866bbc2c851b6a41fbb23c1e409545b2839a74219563174fb5f0ab142cf519f5922009e241986a43810967b760c3c4b732593357a402c0eb6eb4d855184c79b95fcf5252cd5408adb8ffb4aba8344a3888874cd06394fd42daf11683093945956901fb30c6949af02d865c4e02c29858421c630dc531b7270679aa17d9a83aad18018c6c2688e2c9b8482c26cb77025bcb47c24bb385699c8c4ab1e0838c2d464e9183d1bf4920ce6389b0b65c07b178cec517e9c2956e9a3a3fc6442336a3ac63b7381272c407ebfb34e35aa96f7084aeab4b99e7a3af124010f4c1a3420136b649515457d5907a05b714907d1872527367e0689159bc5016287ee3a7e22bb4f46a6a0f2e282acd44c3bd18b61365011037a5890c0bbd660c5b43bcab28ac07b0c5f641872f12faef64c3ef77f726706763c79b427485765c03a6cb7e860210929a004595ce04bb358813efabc0ea7b9043f44379d4862cd19a8aa427c08847b0044b26c00c541669e5c035568872f962353a2d47a2b858f4518148df022312756f9e311a06c0bd0e3cc4067a040236e3eea3e85f5c287f7051b167388d7ac17a4bcbbaace3ff5b462874b6b333546206ffaa50bdb2867c034219bf5cd6ef5016dc73075b3af935055a4866e44108ed0594ed6e17c4653282542b43812102fac1f7f8385d51962137878760a47e7b0119fdc2f65b218bbe414573483c2e92ca9245e19739dbd7581090b81e7d55b77e6cc12b764526b597b0a77444097ce7ba050a67d5ee780223b9086a99c83c45049418a4ce091abcacb4d644de30ccb48172e326209a17562b9d7296e9455d691b6a2951fccc197c693818b173538a88a04289ac01b323667bb20fabde6f897625a663ac72ce644a7e2fa333e91103fc13a0020c4a45275099923dc0747da8738d69c4dc171921baa88d6a2887ca46878e89c58305fac5b1b624aaf4e9967e4d4a89bf0a706f2c2a766b9fd49c4e6516ceee8c662b51b9f962705102e94773cccca2877a080e3e423ee977f6da861f63951181414742220fbab6de8a546ab240323f02385e56aceda691c664ec1779b2205a9b873448e275382d02f2bd1b7ab2813916553e0f7729f1750538694b20a59880b62588779554534ad7c1b20b9a58bab9e1d140e6c1b7d29909ec191a7dc059860935611bb9da3a11c6c07867be1a212d6c82f8832f901185b614e295c4922025500f16181104f5c3045442059499aad8d207daf4a5483fb493d5409978cad5c0b574f5c931db2b097aa23ba0c460a101ca2e65f4aeb64484255c0d90e75f317fe8769f68544b8fca1d1f86747f6848cfab89d4738cd781a7d60bc8bbb902a9a84dba83197a0ab5e9548e3ea5ec78ab832dc75d82837c4f4888be0a530e475d794483da361f801779cb874b543b29570051131abe29372eb491cbbdc5f9fdb6bd6c27c57b681ff74326d8809d2a4bd39a705cf666a2d2b6f78a1836496077d363eced74b47c69eb048ac3e9575c0c56c3d534e4b06700d39812316615fc95fa89ba68e6282495a3469ec97e6bba66de7b2a6ec4ec90bcf9af89d394bc20253c996222fa3b78f1e0abdb50899492496a3a14bd67b42ce5bb845f26a82ab6cac2b0b0c324b1e862a39d12301d881f563c0f7809bc695cbad99b482d1315c5c1443090fe9a7089b5aa52aa076ce82872d831d8a43ca6e21bd961a6c57f695ee7748d3758f988738e7f0253b08c29d12a62502788ed38151e50da0452558f94251364fce827bcdd75ca2b061bc624e78a822b053282ea94a226350b7ec94dbd644b4684252da191904789c8705921b7758853d99567f95c3858333a7df1b8d4d76301a0172ad1096072214777ace36db88eaf6055c912725961923f0c1295c57d29a33ba095b022312aec9043ad68837656dacea530df52deea9b1fb48b1ca0424fe78b8747895f523595e7b1a0a8cce7c71928b925c0d2330d9abc1b3facdc5f95ea3a23b9c47bf024a69476280833026b9834065c11d88a72b5b064a9eda2e9ad99e6b545a130b582b7643691473a597942218c90e8888d2d06313098be49166a43712644128897750b267575adcb9fc03b221041293d0020bc2c870f22df063a7c7d5704a75b29a745f0a325d0879a5eff6bcd14259fb80b5363a36d7f6738a8526c6f8c423d312885998eaf55b5a2713c41a60f657470d23a55b81330e31aca2180ef4c0b1e9d7836a3c1409da8f2c42710b92c2a9d39f727a6f3fa09f498126e8d60a07c744ea291cfabc561198c27c8387a196af3e661156291279e4b913a7aaa4125adf55804751c69acab0847ba4243a39cf9b4d61112bfa0a1ac4e3174a4201022871b50ac597249891c3afc62424483b76f8f6547d3a285e6b102aa7a3b3f71188bcc009c192a848956d1c8f05e3c4ddf5bd1ee105319077cb323997502fa6486116b5b2d88762d9a570ff512ef4463703d56e14574afdbb8f86bb23b7dc586f34bc410ab3e05b73382037a9c287c218472aa81767c7af6b7841ffc98cf3d85b30b845080ed6a324928e19fa746b5e3bf1ec3401ab66574cd85b930b310fa48a038336c14c23687bee57cdf61209933ae9cb89eae6a3f2715a8e08fc66a7af2e0a18eea3ca3bd41b952304c77b495b6a6aa6ed8f4b3ab341c46abd79b73108ed336f90 +ciphertext = 3a7d308d5125feea5f250827a8ff478cee661378a243a55a98ebf72d2da5d8eaec7663b71737093395b8ef5db812c4bebd19858238086d66c1f7434a9d6d952458d03c0e0a576c78c6ff774aa878cd1d96aef177c5fa16f886642e782b1cae846d1abdba3982057ed179f9dd28f734f60a87b99f55eb030e750599daad3f5730528b0e4e5dda17ca16e31a62cbbe2181491c529603db682d5afece5b0dea3dfa133c0fd404fcf8bdc7bfe9fbd6bd530d53e536c89bb20b73de522bd803841226497ed4300961c8314374905aae63cf0a4cdc7db138592f295a2453019b1b134301a703a826405fa440af5aafda58dcfc8761096da6cbd756934df6478a18830f24f84130dce43fea62036ab8d60f4c61006cc10c22c32e5dde19fd589c3736e1f946873d4403b40e9e14f9820ea46bba6b12bfb6efd938d70d6fbd60ab52732be02c31e0be6e09d79b3c5571134160a89aa9a7c8de98bcc7224d3c5005e4d9a46c63bfef7333abaae6294dcc818e5ec60d4f455af45bfb0b10d6c825ecf410064dc7cc494cf819864c98a8a1173f5c300af49dfaad2d91e049b3e9cad29563419c0a3776c0cb2665d4df40fdad840c7e5dd1895a8218585f0ed9fb6f6706fefeb048bb9b9e950494e95a375bb115427e4e861dfb8471b3c482ad958d32ca38e5e5cf587d0cae2dbc3ea82de9fc89ddda20d2ccb47923bc86599f0b1ed73ee91bd9dd1b6d6e0401d94fd93f50187efbca2dc5adca126ef42b60765beb02b0e7cba4558e0038d38a7cfd6f991f16c42fd2ca78b23e8a8966d5d1a5cff12bafd2d44115cf59cfe0ca3769d768bcb73ab5058cd3c0adf2dc074863aeec15b2f07d801ae09d45e5a37c51a5f7a9ad1bb112863228e4890ed5187fe7f069978c9ad8d4e02ed6859c6d512f890bef01d252401f46bb9f2cf28a8e26d033d93a923f29b8b12a2502604c922b16acc2e1d62511a8e0518f94bb774abcf5b456a48030f7d14f36ba0c68a2c2bf638b0e482d8d2ce7ab900dbfbfc55a898198b2776416ac0e95e3bd11f014d1144f30a5c3bca62390cbb228c4d6e31039adfec4e4b05da6da76c3d2fbfb40e323b5f50bb020de37e757775ba6044c7bb27a1aea35f28fbb28d9fc145197bf92e5cd74b8f4e73ed7415f1a8abff890fc3f98f59c2868256613eb12f1b4abd89c3553997a84cdac981e752babe35d0f18f9bf025ae11086cd8d572683141af683dfc94cad1b6ea2171aaf67ef6d3b2dd539db8031ee0f64ed36821af801f7891f5839dc0f0fa38ac13576cb8a3bfd862d7dcb8ebd494b86b14c69952f14e6144693ae05736fbe5ea044e22f708cbd15bcf0528138a7415f1a8dc151ef80ef04d553a34632264d83c6d011e82430f2befcecc3d0f24720a09f641086673dfd1b1ad7cd22149ae75ccba294ac77a41bb8fc7af9c0399b00ab83a1870d910e31666aba8e3eb9762d963d0ad0c67af55a126a9e262619101dc793a6129831356478eadf0f6bea601a5467e140f5868e1aa56b1c5ce1170bed36e26368318c9d0ea95cacc11a5d371409ee1f8e70c74a75a564a7412ee80249f46e89a0ed9828771aa808fc016f3007687703f73fb65e5764005a27cbfa3021493d6e6f7c71ed01fe5df59b4e991664859d877c13595fa3670101c988e6795f9684fec129c9c8c12547300ec255a4df6464950daa4c262712fd2783656b6fe497a0888ba10decf9da8ff76f74f889b21c822645f81853db3a31ab913752a019f383b916bb4e24776a8ae4c3617acd75fda6ac31abd71d54fc94719e0f04366a9a7554323880657563ed952fb39a62a105a2134603eae72c94fd1a7e8e331d4f280511d915d89342a7c6e5c54b4f00dae7f849e27021be83e095f62d8e93465c04de4461a68d966e4e74193261b96cf878d8c9bc7015dfca81014643ac17935ad391f19618f1e1bbf52b79f1dcec11a567c16b62fd3bafa95ddac806124201301f27d38c8ef28402aa0442a3d895b406e7e28410944bf33de5fd4a1dd44c0e1546f83870a84cd83d3cb87bf8e01896dd14111beb1fc444c7c401f3cf11b72731dec40ffed25aeba92f076fc4cbe2aa079f6ea6c848234733f1b3fbd27402b87a0e12f5add565a44c42a4c5719fa778ce801a51ae98d7fe2b0574cc6861c57f5ea057b6156c72b33d6247079bf6547a0648e9457ea3571c7635f3aa2d549bf561eb7e40 +expected_result = pass +expected_shared_secret = b287b6f16756d05ec4ee5097837af7793b2c02cf3e9e522f0ece77cb8851faff + +comment = Bit flipped ciphertext +private_key = 8253538f03247ad30629b6c6926711b1eb22e4eb32b3c9c70be69bbeca36c6324ab8996a8eb8bf17b09319a26efa229b34c80a70b3847bd56deb51148891156792b6964a62f129b4f053c5c6163138a9662c6ace91d57e38c892d18bb5a5453f16b4a30838569c077911a15c580bc6438aa0063504b9334bd7baa4b0198d4ccb9a335ab678c31f8278a035b71855e49a3105ae4d4176495c6259e37b2e341cbefca3ca95311ae89d27e544540965db642c0a69a3691006890172fb9c0aadf0492068165d4c19739473180284c464211e5ba68ef71a59d32c5e8a5b253582abdb4243971c541811eae7af89458fef2279e9480789439ab195379605106c2747ad7136fc8a27091b90f6e4236bebae6779c2c2f39aa21c0601561eb4ba06cc793ad654051122a383f39ece970f3db57fc902c9e57153c92895f2945bc3d998bd988b2591050a64cb27228616b93aefd96a2b1413aea21974fa0d785c5eec97b2df8c650bd39374c40951e502aa749955f43f1f259d4836cf65b4015df07c0481b60ddba3171a188a20c882ac16c54c50642b04c703878913a15e92c0169b0a70c97312da11a667217fe2b1e3262a62bc0e0a92b7af042066f9640d1101f04701ad40173db67f3c3b6c1a884fd109b3e1ccc13a6889a860b0b636907b7a531f9b452d95a05c2b68593c2def215352cc2a1b82367a117ff6a18fafc24d6998cdaa28c6259a5acfc91b0d84b385bb67b7318950f8531b7734d8a8b4de5a3c2cf4cea1c35757457bd920ad030ccf8d2283b31b3777796cfc47c0755300b9b338cacc706eaa6ac408193bb231832881cda9751678c7d952c959806c6e6a4475bb1fe185001ae342d0778a18a29dac5665da11a5ec8a800f1b9c67b169c4d20fa5a02598896977d773717a14ef23c899e60c36819a0d4055c7b0266f7557e0a4944254cbf050654780134df03608f598a3c99ee5242ea7596997bc1ce08224a91c0c7d16b996eac4d48c16d8137cd980c9d1ca9733c956b4631259356d0bc62a3db0903b0989afc6634035bcfdc2c828690cccf24a53474fd3f55a6623969f833aad1643c61c63dcb2c9cda332b36b0fd5e520d01c1ee06177971a4dc9403beed5064671332d4089631c2ef1eb58bc60bb798a338ea1649bab4c8ea0c26dd40a1d66a9ea117ac7c3a0c6793e9f015a823095f3fb826af85979d81527c4285d806e9840538479a5fe004ceae0a91e8383146973ce8610a3a68b53cbcf108b5163d270bf267b42423d7df612cfeb17be62c2b2f8089092bd89f60518b22a9c8a88829b26705a1c156c045007b98b4b058c74181115c18e85a9b40bb0548380058632aa7956c66078271cb17a0516687292bd7980a036ab0c4383d1a38c8b6a052311428e99c83adb91aabc30976cacba5399c8d829382c07addbbe6cb8bfecec8bc033a127dbaa39369eb267472c8b7e9b14c2df974abdf861a0044c4680bc2abab2c8f33bfa25a688fc25fc20cc809030879594e2466640c86d59698cc480b879793f051019ebc26533b569a64943cda0a2fdf0763990b593d271b20a86328c43ddb7135dd5a137e5bc8a389fba291ba3585031100b32f88a4e5968829bbb78f3afd2f5266213c8f0739e8fdc898c9b8523c727113b6556f12e3e050a1d228b596b317513a59d628aa89307235c168b08c67c498af45cc2aa0c351000ae155a17fc13ce7e052583796a8ca781f2d73a6fc49654822dd3b7396633c7f576a241340e730c9cac2b5a49f7a2a015a724758b074581cb54439437c005685174e4cbbf997adf94050229563e0ab1b23a9088d678c15c5a4ef9157a9716d34772e5fc9fc52150a77c38d1dbce28abc806411a0c360bdbb10198d88710771e3486509bc4b956932ba61bcfb165c68f7a4da0b4507e9640194a41c7d15a88c190337c3e63ac6c16a72965121f643c6c28e1a943f809dc3420bdd97b0cc2836ce811212b5bf203cb63d8695908029e34abd6c1ba1f889cc2b7c48fa21594763c529464af93047b4562bb74bf5f595b6cc5a48e8acc589588761972e56abe273b1dcebace5d194400819d455c58aa702fa4932d26fa816a575985ba6b52fc9f344c5dd4031de358cdcb45b9d9a77418b5b3435b40cd45ba145606378268a3c4097490c9fe8b13fa4a7bbb852f34893bea781e566c2a04914a7e637f2c0b1e6272bb0729c7d6e69811883f728416a99441adeaccfeb69f0fe0c202dcc81000ce94c16e5eaa772b220713455639f30c7081782487162a69c7af1218377249fa5c4671f78d8708bdc4e45b2599784783845727c8ed95c4835aa27ccb3ab4156a70615edf4c5c8d251b0295c316f35ac75710873a336c881b57bb2a2f6959e216aeb261718ef862881b873684b149a72e6065394a90649a67173fb20a59290b3c82a5f72517307774aea61fe056351687c9d6dc1f89ab123b17a44374261e8c9a8f24a639c53aadb733356aa70f025a61f85bd7f33555ea7c7fac360af7820076bcea91cb2103a08152219b40104ddc2b2bec9e46805329b1b2d83a56e565a7acc59204735705580ef050cfd68b50230929a9eca21ce166dbc3c902c3caad35a81f5c9817d2a68ae5cf2765682646376271175e60483238253406cdfe73905171cf845688da0a15f2675258db354d862d537a1671a40540e693a48ba13d371abceb526ef11318f788d1b96b3d157ddf65c0eac10092c007a109aea9da4a8fc2715af8a5c429b0498b8bb25a6ca687b1fd7782b297198e072108accc04fca0c7f8962a528234eac8a5d44a4e5749291ca8f5d2016195878d082c06b6c8b1585624637821924d5a409db36a594b77c30dc06a9f16696185a3d88479834cb8cb2b1dcaf0ad798bae19e1c03d38c12ee297221732cd9ba210228693523dda9ca934098e321aa6c1c6a887ac032081ac447357b047660df58ada778c40e891ed856de68b0f215228b1b8279fa8074c6c2bb84b07291643b0c938fb77a579bab07354a6fe0238421cb7388944bf3375d00c6cacc46a15d5815615cdf2b131126252d8143ba779b05c24589fa59cb43ca43b3280f0527bc34660b40956f8b44f80b547ad9946ae76939056286997c352994638dac034930f46832a53518cfa0b7150442c17abb746e0659b09599e00afbd874716c85267e56327a455e3478ddda95e06ea4c7a81622484632a43c28cb46c836b3a4c8c0783d9cba0ca0f23f275101793d10551d050b81ef719da9505fb4245baf67c69056423a4cac9364b87d39a4e198627f42779201cd1ccad9e8574a5f55595140e36dc6693b08537812aa758ce42fa179536b7e77b475c21cad797572a109f1f17271200c6fd11c8cd34aab7e32e1bac127603b40af8b125456bc595518fd19c5e661c64ea15aff61a32ec5644421e2368103b20923c32b1e0f98f1ad473e2ea46313b37cd950b3e472b36909fe275551f337730f6a8240c4bbc82a8f4e34a0b75640e848e6823a5a7f5b67c104abcc63738791ce8774b4a499d59b21cb92110f402bd8282beb28b5383548f47564363ac5f280b5b2a795cb3953dbd906cbd6b8c3de522dad4a3151c120b7a89a51ca0ad0a95c9b4b7c2e6576b6ab33936cecf4955492539251b44fca4c92413c142e1309175c528cb2d55b452903c7498e23c33ab3e9b41865c737388c9856f94129abc709a9c7e28b763c0482fdd13919d3512fea354d63a333ec6bc6e1a70328593cdd35a98c99250f7b3b3c8ca8170060a2022f7b3161be3bdf3725ce5d80ce98401512657cfb5728b2ab4840b30c0833fd1e45f86aa115434ab72512b92843613031bfbe87fe7280c6c207ef49680e5917bcb1b4badb099ec056ec21147420c72cd4ba0a29bbb2b3598df862d67a4a2a5852fe786b9bc203502da8ae7371164c6ce340c56e6b3034adc9a41359d03e027ddf743e342af4f84450371b275e42f536aa602e1c50de7ab22863998440ab6032837a103302764df477c1b505063c95074a28718a6a9fcc71baeb03117f7a0ece241deb27b5e6596ae62993d4a7f4936a46b2a74b3291ee1d6aa606a06ea021d35e58cb272658558417797bb91502622dc23e1da843f2337f375436b821f7165519b30a011a33c68c8b43c464d74557732b4a513d0beaddb04edeb8054426369a5cf288c08ac6c589fb4c5449a6de062358964935d22bb79d8412bea783d11bb9fc4af81c490e3b7b37340ae998912f8f07d64828248438b35a6aef5e636e4355b46dca8e4a0485ba9973b7aa9c304c6be659b9a975a4e94852d45794d9666f258b92e071891958483542f683cb0d686780a6b5969ac50bada8c80ee0c1b675e072f085c6566941da1fccffefe707ee2e7c3fd5c15eedb3d84a518f000d1e1c5d0645beda0b4acbd26419949fa7d07e502db21d5e3949799ceb680f70a4862347269642db215780f05c4a6b61089a2a52b35a21bb69d998e7998 +ciphertext = 3ee4b8bdcf8e8538ad0ece35d684a49f66a1a280c8e1b62edfd4fea0d2bd2307e6c9412f76cab318d4d46bccb8f9f3077bc1a44dd7a5e6d59aa7bd675037a0b53efc28c6600951fa578c46103b7472b8aa529bdf5e2d90902d635c5b441faae2a4df4cea8fe4db4f9475fb02104f53f5ae430e9f1fafdaf524cda0b495a16ba5978481bc2c08567c61c108a107397486bc40aea8fea9636825ba40c0cb00e71758874f2cde1d1629ee2f175d7307f3186ed4ba57e89c4082c420dc190ee8a6e0d420513d6667a2652fef2991df82c96a4f20a9a6aec308bc5e12dde0f80192d9e7be7230b575a3b312005ffed493dfb0165283b15bf65e4fb74a48a2307b01f6922c1c5d3e9969c1ab9f6089b0a59ec04e9a2f0749672973736a2c12031bd8a30de5ee4f43dfe5d8e8f812486484a68553fb63590468f4dfdad3bfe4af5d9e1803d48c3d6f42ad94883821b053c5b44a601e11117d066622ad7c6759b4911e35250b6e043a54fb27d51311068e2f5c3454d19d42ea3ed604c80305605233a6801845b183a23451db7eaa2df1c33f98614ff57d5680749af86c7edbb9a3143adf5ee00c305a6c03985ffa18716bd8b13ea9d727cb6fd73e0ac8abcd11522e25eac04d4c80997338661b6bec84a1f389cce3b9393f56000a676c66ff5b38cc01290d62e5f871aeb9d9f7e58081f7432724ee49b4b23db55a79e5fc7617bc74315b440ca71819f48653348b869b876b889aeda969e8f36c10f4489deb7d03d8134aed2b8ca658dfb4ee6b374fd68034f374b0486a2f88b073eeb9c518642b3bc2dc206e2a7518b343e2adb75da568f54ad9db423aa6f3369b5e1500e55b9f92a1333882a5b76c05c7456d65aa386ef387ef34a3a428fa0ae7788cc16bd3ff37bd448631768af81b212c52d15f5f34b8e02cd7376680b1f9dfc9426bd887a1b418300a3c15be983b15c8322f64bf54f9e548c7eb21618a5f3b79321d88bd9e1ac3bf801b6e85faf8b331d3d8cb762615df9e7f342999dc476e67827625e343bf4a844cf3a4597f62d3c7f043ed05571b8e766c223fe600d4e8048edb83eeee60656de0d9a47168e2c360443f21ec78bfbac42e8048d4da56a2ad7c87e9f7ffe5742a47553587a85881d6f6b40b4f9be33dfc17e01227a1958d3503e1857f2e36290ec74ac21398049aa84164e6530cf40e0d2911a8e26b27167c47ff2384d5d546e5d8a648ae42b57b0a147ba9865389a545ad86e77aeebf95028c6fe45161eeca17d7ae91e98b2230fe2ea39cb94357bba7470f927cc9187e45212205a6d6935b763c98381682961288104ac2df556612f9f907541e8f2e3d0049f0d6029c2eaeeaad5d29c544faf70970f72f275bea47def2dac339bc37dc900db647f4cc54802ec97d4670c42941487c432ee36ecfdc03273b9d27bbc46ec580fcdc6ee85a0bbd0a3f618766c15ec125f72d0af165c67ef1111a1a8c53de966eb618d9719140563f4bc35126a9345228e2d4f1abe457b6b9631b2687298ea430d7dac1de40d5a16cbcb640542e679547dc063de6ecce59d0c8e14137bd6b70d4ff7bd9f0e1bf188fc0a9e7b5c74f26c985176ac2379f86eced990ccc2a29de9328a4f331dada90875ce8d6546b017f114d488ac20304c090ea00c910a47623fd07e27e16cffedfb624f2e906e07958f88f1d4d5300261d94e3376ca90cec5d9bec9524cc2a6f5de90a15953fe63b9a0c5533a8a4b667a8fb9255c9f0a5212ccac59f6dfd75badb26c26258a62d244aa8e26f51e1439180d93c10ffbaea9aefcb8923070a3cb89c8058f504269d18629bdffcd8e67b063c1afb35e9cdc5aaa98a349bf9b7fc5447036d39763ce4764f1dc5a1011ec5f21a02d3de0ba8870b089d2b571fec26650bc962cf26fb6d8879d65d07a71230fd80f76cd4fd894a752520ced25e286a8f4a51c3a830a5bf0858534f4a09986b4531757e475969c2a84876d3ee73d1b3a9adb6e7b7d00414c0f8694687bc52cd5dbbcbaaede43331227d5a4b5c6060b879e1da7ae06b53c426fed7f5e904adcacebb8ab7d1d423457948614b5db23f7e8f69b60a35a9e2b16d85f4645a6a844534743b912af2b05510ac15f62fa8369bb982bec7c571253d1afe548ed1a607d4e440847898aad1e7797b0586862ec97fa7dcccac0646531e3ea4392206ad8ba36856a13279c6f7aa4a48069ddfb85689ec25 +expected_result = pass +expected_shared_secret = 0234754b861e8d110d940af2fbf5794e2b12754687a03ae6bf950d6ec2ba7615 + +comment = message all 0xff +private_key = 46c69dc68a931e46bef5ec396bd852667818cee9699e36595278b5c4356e60b2b37991c35fec342d574a5cf6b1e7086f26e33de11b5444e557c7bac7fa501380f89d1bbc481891c111ab6526b834dcb11a24f9415436b14db9cf30356a600768517c167ce2156936ad2356530669722c6864a89821cf3b5bbe98a248dba699768de0c8977027c4f00abfd7a99ee683912f5b4fc9182bdbb76ed349816b16026a741fedf2a67329913bf2bacd94aa4720b77dd169f46936e5bac4d6439b4eea432e6988916b000be2c67697322713931f42146314c4f34a5a68bc7293013ba908aab8469a44629fb8ac7c04d610b8b2726ca229a1990f17f28c75b025957bc4ce70c8e962a75df9c6661c44b2ea1de5236fe612ab085212318711d41c0497b79ddb5b0b3ea6984e4167875a7421a9365e2046ea734f1a6486b07c1752b22f31b191faa563e8154dc77072f3a345a6cbcd75a92b0376a146dc2653f435ac46763a84ca8eeac0f54bb9fef3a50d24bfccd633819a1f4983bfa82580ff8c17e0655c687b618bfc8d14f3c7fe4c3d3aa644186798c64ccd3629ad95862b44db7bfab1616720c942f30e40788d884b5e88581ad940b2d22a25000141dba301a490188bc21497db9038d3b894898bcdf272a9d8485fc20a3ad57ed2ba6cd8ab93df7a986e792f767b4fa81616ad028173f743d438073960bfc9c82fb846980c06537b49bc57b53f10bbbee7088922cb2ed925b940ea870521911a4b83c16a17e1d12da4a691e0f3bf22345524e291913b6d5d4b885a3bb2ee386f96887979794019c188a281b54d68c538e3079e437c1d990154a8ceb1798d0239a750a428f3250b342231821ab81be7be3a36b10a910732572888616b3409323513a77136ce05c7256315398f7c13e689b4c3e97fe7047ea6f60ac336692dc6a29a09b914322441940f58041449f56d44820f8afb19cec4175a378413ea8a7ae94542d90d52250e2a853b8ea69fe4abba5fca533f027174cb4582c1af0e209138b817ec4a53e7d911c2063461d52ffba306f2f755cfa63e5621a49cd0bd47798768ab22a2d16dbda65d709c32151607d90bbba5612e1da481f02a7ce9c51f3c059f33ea811a187717907bd74144b6b0527aa62cc259953cd700a19160e0c73ea7f987ef1b2827e04d9fd89091f57800ab6f1b8ac1cfe315ef6b51fc6441d95341b60963ab23994e984b33950aea500ee1400b5dd1a9621b13a32b7231841dd8848e52943d0a7ab31dfa8912b2833b4017ddfa38c38141e44cae46228177b974fd0191dbf29d4c391c8667c107b9830930a3ffdb028e046f639619f8620d333a1d5b4b3037da696087534dd6104cc72f27e7cc56867dc8599ca1c285c68aa7f538a947b5b442508b10d378d02995102a9349a0a36ccbb1fcf8b25dcb965099824be6711f4177c8c0b36fb8b928c1612eb1a043a37b50b53d4ea698d088786908a67f0a89cad22cfd2818960b65fc32bcba187a0e950a5fc9cb30288fd5462cbb8b0bc070bf8ff8cbed519c941477e29c2e580261c988cfe4a40fb58703f0224dc699c8d3b065ca360d93c717b405a93d65adadb107d0f78acd5593f91609c5dc2745e221a1f1bf8dd53185fabc89f632aab7cde010bb531324af146b0ed37df7e622035254fd7bacfef551edc76f20375b3733a0c77b053ac40a24d8b2165781bddb927a02c430044a6e573741774955ca5966bc6b30b07119e5396bc99316230f4f9a3292eb82f116461665adf51acb32cc7955206bfa2456cb9a622e171673d8590ba725b4c3a44862958e3669200b4f26920591a65b22051dd39a236ae6c4e2579cad950aa3fb1faed630453c355225118a686ae9c9b19890295ccc9dc480b2bb52aaf04890498b7527364659d31af0f1076684393882819a085c2e2902716a3fa3c297c142a821b91ce7db23bada26dd0c50aa2b6c68fb0b8855baec00b4b4db95627a81463038b1630d6618acd6e4c9023511ac56a29d55b999b70ee08bbf4cba9545c31c1ba0a031a57e19a2b85592757e52630f873750701ee8350389ac763bfa23329b66bbc9399ea0a60f33502e402843202cbd4c9d8c046c1b4399f5a157255caaeb6a0ae2689938c06ed61118baf75baa254488e9943ea2a7c5796132f12f7867c13061426e3a60f0e7b6cf14a778084a6b63addf12b8927c8e9cca091f89647007b892f06f854cacfda4c1401427a6a90e944a697644c20b3b91885058a06a656e8b9ad40126086266f25333fee604387b8cf6188daa5baa452780af94c47720c67b38477c7464646426f8b92bd965799d6c162f595121648b4c0513cc215738b363a159a47da1a28629186cbb98d473204c44b2bef786f681106ca4a9ff71977fe9bcef32778db11e71315b2c1a28f23ba8577ca4023982ac7c49af1263fad8b83d65375a872c63e83b93887307cb6e8ef90d7cda06c56052d31bac50f746eaa16720406c88c0b58e427bf0b83d0f0b931320b5d5e88279ebc669721a4c83095644a485855a1d64227a3b5fae42897a03757d74415df1bd2f08867189bd3acbb8ed008c5784933398adbf3105dc02c3caba27ce012f15857d0a8b0a82a87cb524afe1c86ea9eb4b7300cb15057145785cd2f5538a435a88b2020e381bc593a6ff200801fa36a7946baf0c81e15b2872f367282190aebc2430889f1e66410aac0dcdb15302c60fdf0389c1cb8a411aaadb8315d9a005fc1376a75138d939aaaa909574b3c49d0a70f3cb3398ac163ba2ca1bf51b669028db14860f3094fde5c8ea30336cc86e1882c09f374263a4856568aa7931848ac4ac577372ded2cff2fc66baf59fb7e10732d07504546c98a7c5a494155036782418be787485c058a7962189b9b8cfc948989d0b99a853ab9c418dd8b8971d9983145019d99aa62d780434d891f8a1c21b83a6e90729f40492226cc148432fb380bde9d12c6728775a26149fd065edf3bfad43032ddbc6cef70943f802750a01eb06b5c45751cacaad78669a8f04b4be052cde483a1b6064d5e420f9321489380f3ccc6c411523f7d15876665ab2b35529fb1f31eac7fa700bade8741135a8018336f7b9100f72b72891c67be4b57e28152fd2b0817470b001013986c227760deb8350270ab16979b41acb6310796b1bcca3673bc8cb30330618148f68944aa173ce12704311b02797a2da635574465b97144cf00c583382687bc01db48231cc56a23ff659f096011620c870a5bb276ca47c5096049bb004b47993ea615ae780a6468fc2436929470a656183b8773372b46923fa50ebbb30ea81097a59cc6ff3392c296cb8893f95c26e9f43adc8c941e1b43dd8497a47bc5e103c51c9e4a5ad3915190158938052e31045a0ab5ac1b2726ed683a7b56d8eb66e1a4564db711df78540c5e3cef30264bf846efecc60ea0a548dc698e7d8136d098427529e0984544a60082c71abfff80fc3f960a0ab5bec85576355271ea2127a79cc9b609f38c0286eb1811cba90d8168bf3904962227580e70f91a760323ab97133150abc3d77e285ebb1c305e121e5777073bb84eba6260eb56f8ccbb90e121143ea6839d2a29fe061a25092aec7bc78228a84f058ac93c69687cbd6e6c638a824b7f43b9a9cc62ad88057d3676197b1d6457feb8c52b7d68de71cb861a9a2d08392bd2140480152908cb8a60b88c5843ecd15514b5622b3166427e92b2cc2a47de669344c0578238f633c6d24b75580262f1064a17e73b7ef1c3320b16e35a576aed30b1fc0201739a9abbc1288d527f5f8197c0bc9c25716df829dbfb6ba8bc5a70284b90166552c11645be078c33b32aed846ff143f2a47c651b4cce269b29303b44e51cd1f031e8ccba55519979466481e37a4c89bcb09a69208795a63d1bfd2a99f300878758a0f80eb24cb838a9c2949a266b400c6a8e2b3cb92d4bf8ff10ae92901f2b793c5673e9ab569ec7c7f797901ceb41aea14417e868d134406e5947c37cb03c196c7c82bb604929a35b11a68b83858dc13674aaa94fc818aa08f694b1ae6e7607c78836401134246c6afa00e560a1291672777432097ba7b1b9752a288267d23c65af285ae7ca05f094b190656d683794d67506ff61662a4ad5bb8a1aa083fc0169509236cc93ccee4e30f7324cf5271a2a2900141f8047c506f89d51dd9f807d2f09be3a621742381bd8541788446e7d94afb6190f3d448ca74cc5afb4f0b0bc545a5c95c147b40308a5438a4bb8932cd989141b3cd78cc67c66c741b2c65e34c41caf747a22168c9b28160905f35d25316a6179e71a0e6cb0ec6518423602f0c18c466ec56074573ae92183e6ed07b52e2bcb8404fc7bd393d1ca935c6ce561323a6e701c5a03cdfac300920451a13cd675a0264dd700dd96db6dc67c17fbd40d10ab5ce8f2109711aec689849f9bdeeef3d88f92e6d31c6745adcd2a1ef162fef80fdbe3666449a003d7e +ciphertext = db144f5684efa1f29162c04de06b4507130c6272032bad9ba22c405eb5db675ae3a9d54f5e45221b73a2454644d0744eaddd916c9257f7a82b5b650e9f179532c99333d75f3373925f2c2afc609024ca698371196874cb3fbb22c7cb97656fbf66622797719a18407e6dc27ff942e93cc54578f09ffdd3dc73fe0e748ba6f03ed2a45ffa10cc28902698ebb07edb4cc728e06516217414ceed2bf0f68171888946b81a604d055e182d660b501176b19186753bcb44c67b18b5a458ed034f05150166eb737895fb4efd3e5bc0eb9c3526ca908ebb244e45ec1d2d1dd961956608603a74298faf984f5219ca8f9779c4dd6261908bd4cae9b3bbbe0a342ca702fbaed2497ba9e8399fab864c92373cfd0dde3bc2602de712ee4d1d69fcc064d39a2671ecd3b54d0eb6957f01a923e5f8e639a6c4f716f534abd0ea9f957b5e09af8a3c6a1365c0d796f2adc0d60fbbdd418e1a6242f6eb5c26c4003e57be8dc5559c109ac6229ce8c4d26e35d60366c50a863ea3ca6daa428dd5ae902ffd31dd0fbfb3137e7d0c48fa0c74b3285b83a347c370592df918536c1c44599d8b870530c97b5394cbbed19285f240c081f414a267ef2ff0c11d457c101d6a77741fdcc55688fa61b91c0837592d94a4bc9a52a9a14eb6f58306e94f8d0162cf17e623289812e0827d8db27c32de0377fe73b01581a2f71cff9ea5be8173a7604082e9a55e6e5bf34b6af0d8b53968eb229c920975fa4e5e464d6d0c2393df57bbc121591616db995d53c023bdeb31fc215e02e2022e8278578b8a44ebf2f1fe1b689f7c8e77cb557e4ffd13d3c725fa0a6aeff1fc436062ec2bbbe97d128862d488bab4b88fa5913ab54b84ceb3be4856a168bcad5cdb5b8afc643f13e911cd2c9298df9061c605ea7d692048c89942b2aba2932864e55f5697bad466de75dfda121cffa1f94bb5df71c0d62a2a6f8a736b4c0c323041f295b9c5582217aec3481e03adb500c617dc835f10b97544c99604361706a42ca4e4da89a79283d2da1827e7fee9701d7e254ad234784d16410cecc47fa0a6fef737c4b48b98b7243c0500ad11f41f0b33d15022de69cc242afa5be7d360674e8435da2ae29b54fcfe577398357faacf45af5f46d73ee4148e0185fda13b7759cdfe97c4d6958708489b9bc63c2af0d6e3e5eca9649f6101c03b027833f1eac6a7d32298e41661d8b3ab3c0cf033726c3f76a37eba888cd08fdf3021b036aedfb584bc3a7ac59b21b2ceb989d15644bed38db96b6ca76bbd3e7bf6e4b55a7b5e56d90783bccc554e03cdd94f7918e1373ac4a242a14716d477f21177ee03f63408878b53023afcbfd88e281386c3369885be08e08f8e1e502cbe926af52fcbd277f8f3423717c33768e7e07783d891ee91a6306b03b244b78208a2fc5cbd891fe9ef3d400abc11c7bdab6c6e88414ae9365cf8fa392fb6bab8f4f620487029c85c1f3ccc7a0a7024faf8713b4c0a3f880fdccc2d431fca9003ac15a1c5854718ca0a6c50775a892635dc54879557ea01551aac2827f5f4e534c61cdab731151857a6852533c50f87298d885696f9dc3105e0a46038930bf04330af136a08abe4aab641a3d8b31be61536376e3d12463bb49ab73ada9307a4e117a4a079845abec56f39a0eb1bee37876cac8da745a71460b9866dfd820283bc7c95c8a3b6fba8927a9db29ac0b68a7a80e09df76c00352bfc7fe108924252bb4ae4431f876bcf9c28ecf8fcefe962bea41943d42218ceda181acce5aa937d5e43e83934ec02ef5311f095554f6b3e90fbe20a819369de4a35f19637f983d6def6b37379919256986a45533130ef3b5566cb597cd9fc2f3a6466dc9f5d3a0ef55cc1217bb6a6d0c003fa22eb1a6dfdf080e663f5a92fad4387712097e3dc597bd6063e8de5d221fe684ea6fc783242aa3dddc49a53021229e9c49439a39d9f70b453b16cee3670c638c6d42ed60c45309d44f05020ffbe94e7f2a2806c915567785c653077c4af5e179b0172d11b88a38edc6efcc08f123fc6a2a6d6c573174d659f533ebac31bb399680f2aca4683feb5d35a5613fa918ea6d733d9bb72e1e2b25cfa7a5c981ba4e0d86f078a0f1ce9e967dbb02d3095ed92f24b503e78e1600de03c38352411952835d636c7a68b5884b1bdbe1fb0e462c014ae2a6295146bf00d07cab1d48d1a792e88930b499fc9a5d3196e +expected_result = pass +expected_shared_secret = 994254ce67b6f9ada90216964d3fbc25d9cb601fc7141ca1b4d543e01cc43599 + +comment = ciphertext secret and error zero +private_key = 46c69dc68a931e46bef5ec396bd852667818cee9699e36595278b5c4356e60b2b37991c35fec342d574a5cf6b1e7086f26e33de11b5444e557c7bac7fa501380f89d1bbc481891c111ab6526b834dcb11a24f9415436b14db9cf30356a600768517c167ce2156936ad2356530669722c6864a89821cf3b5bbe98a248dba699768de0c8977027c4f00abfd7a99ee683912f5b4fc9182bdbb76ed349816b16026a741fedf2a67329913bf2bacd94aa4720b77dd169f46936e5bac4d6439b4eea432e6988916b000be2c67697322713931f42146314c4f34a5a68bc7293013ba908aab8469a44629fb8ac7c04d610b8b2726ca229a1990f17f28c75b025957bc4ce70c8e962a75df9c6661c44b2ea1de5236fe612ab085212318711d41c0497b79ddb5b0b3ea6984e4167875a7421a9365e2046ea734f1a6486b07c1752b22f31b191faa563e8154dc77072f3a345a6cbcd75a92b0376a146dc2653f435ac46763a84ca8eeac0f54bb9fef3a50d24bfccd633819a1f4983bfa82580ff8c17e0655c687b618bfc8d14f3c7fe4c3d3aa644186798c64ccd3629ad95862b44db7bfab1616720c942f30e40788d884b5e88581ad940b2d22a25000141dba301a490188bc21497db9038d3b894898bcdf272a9d8485fc20a3ad57ed2ba6cd8ab93df7a986e792f767b4fa81616ad028173f743d438073960bfc9c82fb846980c06537b49bc57b53f10bbbee7088922cb2ed925b940ea870521911a4b83c16a17e1d12da4a691e0f3bf22345524e291913b6d5d4b885a3bb2ee386f96887979794019c188a281b54d68c538e3079e437c1d990154a8ceb1798d0239a750a428f3250b342231821ab81be7be3a36b10a910732572888616b3409323513a77136ce05c7256315398f7c13e689b4c3e97fe7047ea6f60ac336692dc6a29a09b914322441940f58041449f56d44820f8afb19cec4175a378413ea8a7ae94542d90d52250e2a853b8ea69fe4abba5fca533f027174cb4582c1af0e209138b817ec4a53e7d911c2063461d52ffba306f2f755cfa63e5621a49cd0bd47798768ab22a2d16dbda65d709c32151607d90bbba5612e1da481f02a7ce9c51f3c059f33ea811a187717907bd74144b6b0527aa62cc259953cd700a19160e0c73ea7f987ef1b2827e04d9fd89091f57800ab6f1b8ac1cfe315ef6b51fc6441d95341b60963ab23994e984b33950aea500ee1400b5dd1a9621b13a32b7231841dd8848e52943d0a7ab31dfa8912b2833b4017ddfa38c38141e44cae46228177b974fd0191dbf29d4c391c8667c107b9830930a3ffdb028e046f639619f8620d333a1d5b4b3037da696087534dd6104cc72f27e7cc56867dc8599ca1c285c68aa7f538a947b5b442508b10d378d02995102a9349a0a36ccbb1fcf8b25dcb965099824be6711f4177c8c0b36fb8b928c1612eb1a043a37b50b53d4ea698d088786908a67f0a89cad22cfd2818960b65fc32bcba187a0e950a5fc9cb30288fd5462cbb8b0bc070bf8ff8cbed519c941477e29c2e580261c988cfe4a40fb58703f0224dc699c8d3b065ca360d93c717b405a93d65adadb107d0f78acd5593f91609c5dc2745e221a1f1bf8dd53185fabc89f632aab7cde010bb531324af146b0ed37df7e622035254fd7bacfef551edc76f20375b3733a0c77b053ac40a24d8b2165781bddb927a02c430044a6e573741774955ca5966bc6b30b07119e5396bc99316230f4f9a3292eb82f116461665adf51acb32cc7955206bfa2456cb9a622e171673d8590ba725b4c3a44862958e3669200b4f26920591a65b22051dd39a236ae6c4e2579cad950aa3fb1faed630453c355225118a686ae9c9b19890295ccc9dc480b2bb52aaf04890498b7527364659d31af0f1076684393882819a085c2e2902716a3fa3c297c142a821b91ce7db23bada26dd0c50aa2b6c68fb0b8855baec00b4b4db95627a81463038b1630d6618acd6e4c9023511ac56a29d55b999b70ee08bbf4cba9545c31c1ba0a031a57e19a2b85592757e52630f873750701ee8350389ac763bfa23329b66bbc9399ea0a60f33502e402843202cbd4c9d8c046c1b4399f5a157255caaeb6a0ae2689938c06ed61118baf75baa254488e9943ea2a7c5796132f12f7867c13061426e3a60f0e7b6cf14a778084a6b63addf12b8927c8e9cca091f89647007b892f06f854cacfda4c1401427a6a90e944a697644c20b3b91885058a06a656e8b9ad40126086266f25333fee604387b8cf6188daa5baa452780af94c47720c67b38477c7464646426f8b92bd965799d6c162f595121648b4c0513cc215738b363a159a47da1a28629186cbb98d473204c44b2bef786f681106ca4a9ff71977fe9bcef32778db11e71315b2c1a28f23ba8577ca4023982ac7c49af1263fad8b83d65375a872c63e83b93887307cb6e8ef90d7cda06c56052d31bac50f746eaa16720406c88c0b58e427bf0b83d0f0b931320b5d5e88279ebc669721a4c83095644a485855a1d64227a3b5fae42897a03757d74415df1bd2f08867189bd3acbb8ed008c5784933398adbf3105dc02c3caba27ce012f15857d0a8b0a82a87cb524afe1c86ea9eb4b7300cb15057145785cd2f5538a435a88b2020e381bc593a6ff200801fa36a7946baf0c81e15b2872f367282190aebc2430889f1e66410aac0dcdb15302c60fdf0389c1cb8a411aaadb8315d9a005fc1376a75138d939aaaa909574b3c49d0a70f3cb3398ac163ba2ca1bf51b669028db14860f3094fde5c8ea30336cc86e1882c09f374263a4856568aa7931848ac4ac577372ded2cff2fc66baf59fb7e10732d07504546c98a7c5a494155036782418be787485c058a7962189b9b8cfc948989d0b99a853ab9c418dd8b8971d9983145019d99aa62d780434d891f8a1c21b83a6e90729f40492226cc148432fb380bde9d12c6728775a26149fd065edf3bfad43032ddbc6cef70943f802750a01eb06b5c45751cacaad78669a8f04b4be052cde483a1b6064d5e420f9321489380f3ccc6c411523f7d15876665ab2b35529fb1f31eac7fa700bade8741135a8018336f7b9100f72b72891c67be4b57e28152fd2b0817470b001013986c227760deb8350270ab16979b41acb6310796b1bcca3673bc8cb30330618148f68944aa173ce12704311b02797a2da635574465b97144cf00c583382687bc01db48231cc56a23ff659f096011620c870a5bb276ca47c5096049bb004b47993ea615ae780a6468fc2436929470a656183b8773372b46923fa50ebbb30ea81097a59cc6ff3392c296cb8893f95c26e9f43adc8c941e1b43dd8497a47bc5e103c51c9e4a5ad3915190158938052e31045a0ab5ac1b2726ed683a7b56d8eb66e1a4564db711df78540c5e3cef30264bf846efecc60ea0a548dc698e7d8136d098427529e0984544a60082c71abfff80fc3f960a0ab5bec85576355271ea2127a79cc9b609f38c0286eb1811cba90d8168bf3904962227580e70f91a760323ab97133150abc3d77e285ebb1c305e121e5777073bb84eba6260eb56f8ccbb90e121143ea6839d2a29fe061a25092aec7bc78228a84f058ac93c69687cbd6e6c638a824b7f43b9a9cc62ad88057d3676197b1d6457feb8c52b7d68de71cb861a9a2d08392bd2140480152908cb8a60b88c5843ecd15514b5622b3166427e92b2cc2a47de669344c0578238f633c6d24b75580262f1064a17e73b7ef1c3320b16e35a576aed30b1fc0201739a9abbc1288d527f5f8197c0bc9c25716df829dbfb6ba8bc5a70284b90166552c11645be078c33b32aed846ff143f2a47c651b4cce269b29303b44e51cd1f031e8ccba55519979466481e37a4c89bcb09a69208795a63d1bfd2a99f300878758a0f80eb24cb838a9c2949a266b400c6a8e2b3cb92d4bf8ff10ae92901f2b793c5673e9ab569ec7c7f797901ceb41aea14417e868d134406e5947c37cb03c196c7c82bb604929a35b11a68b83858dc13674aaa94fc818aa08f694b1ae6e7607c78836401134246c6afa00e560a1291672777432097ba7b1b9752a288267d23c65af285ae7ca05f094b190656d683794d67506ff61662a4ad5bb8a1aa083fc0169509236cc93ccee4e30f7324cf5271a2a2900141f8047c506f89d51dd9f807d2f09be3a621742381bd8541788446e7d94afb6190f3d448ca74cc5afb4f0b0bc545a5c95c147b40308a5438a4bb8932cd989141b3cd78cc67c66c741b2c65e34c41caf747a22168c9b28160905f35d25316a6179e71a0e6cb0ec6518423602f0c18c466ec56074573ae92183e6ed07b52e2bcb8404fc7bd393d1ca935c6ce561323a6e701c5a03cdfac300920451a13cd675a0264dd700dd96db6dc67c17fbd40d10ab5ce8f2109711aec689849f9bdeeef3d88f92e6d31c6745adcd2a1ef162fef80fdbe3666449a003d7e +ciphertext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010020001001002002084004200000400400820040002002080104008018400000801040002080180000208010010420000801040082184104200208010020020801002002000004200018010400020041002000100004000210000420020000002002000004000210000020000801040082100104208018010020020041040002000104000218000000021801000080000000200208010400001040042080104 +expected_result = pass +expected_shared_secret = a935f71eae79fc9629cf51d8f873054e4329afc1486047270f23739a80fd8c63 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca62e0b7d8cc8d1d861dd052bd9bb622cd8b769551c2307c82aedc92accc3d2c67c3ecf8341290af6c93a295fc027895809a081aaaf3cd0131174c8605c7fc29ece47036866f7fc326f7c947f70852356410e22700b5480897f288dba24c494685ecfbb624bc189dca10d9307595969145b21ef4ca1c435b3d39555434e133f8ec8c00dc49f02788041a6deae40ad5c9a3198804fde6230dc25b7f86a86bc00b43da73b5b40e3943096fa4540a019817881b4421961e293250056300e273f3d87153765ec237a79a16ba89a960fe42aa887c65fae65719766c44b2b8a0e54e97aab5febb1c194939e11928258cbcad6281cd37ad6033b1c9982df721200e36cb70326403422519f3afc3451af15969c2b26957c452fb136db18357516617892214c758cd9b556a827434c9510a5f6094bd32c8633966eb113f9e4902b6306c87732b96542979159ab49a170fe71a23093c1aca70202287d8288fc2f56072ec7aefa293015b6a58a2899ed79d4a09701ba42d26c599d8a2164204563fb90ff7372e1ef7040c4b37bda74af8a45652510df4d67b7c618279d2844b10815913914c392a4119911d2b40da79b882534a6daa1b3b8679eeca4ef2b57bd48507b994a950b98865103cbda9b6fd38ac82b64859863864ea023fa6990f0898a8d3ba8a947fe859934ab06ad545133f57a3c692c19058a07fdab3f0daba0bb7846ef3222ad4bf62d995a7bc4801e5114b5c131130c58f76bb858abd1303003461442d64762cd5ce3421b52f492ed5660a4d632af3d24b9b5a1af291323429896fda2e21494e5630502aacc91bacc2902880c99890f259c1b9fa01e7a716a0a3a0707581acc347622369a4e610a1336047f3429ec16e7cc97607a11ff59473b5191e04586c1b32cf82da6816e47c72d7344e84a0d6cc42099781e5837eb6ba878e489172c41b4e2c3d0370874c0bb939c485a05851cf351652f82f1ba0a50fb235a6f10f98655cf2cbbf1c21acf999ad24f77ebed4297425b59072ccd1b6aa6467874eb014b3c911a0a9430cc86cca1aba84cbc709824a5f3abdf7f927d8f9a8c5d6cb955661fc7bafdec7cffd720fedf95353b01743613faff9b4c94c80472894c2322f641240b0d60549e4a405e9a20c0b794151a63a598e26eb021e1717723bbba58302096b563ea4217a8863350a7a729b0c1f8486a8faa7379a41515103f59b773be06a6b3b01ebdc67cff93147279f861114f97c3b9e7abebda5a51ed4518c6a20e679cf2a48b8bb354095b3ba14d07f3a61c18964cfad11b6b814b50c07bd2c6aa38c6c4b20d47778aa5c82fc575bf02b8967ac79fb9c1354bb1df83af95a839015c32f8b4387795038720c53f1780c6a5a42d828ea42264e55594732419e450afe13ba956581465a686a1659bdb21bb2083424d19fb0682687ab005f1111c4a43205db0633d301665c635dc016ba2762360474e728362ba46b52b54475140fbdbbc491ec5141e7947ba42053c4b63dd1032d8b8d3fa2c593322e5509c01a1584759892a910581fe6bc16b935a5931627b67e77247df0d3c77b94190920aea31c093a1a9146f75e51f07d45a607c7f4c38a5a23a3198cbaea7baabac8e70721b80596c015285f20ce45c9bc86d67a1942c139c9acac70bcfb7a1f0b993c7d145b4a03be0a86ba201647d7831c6d960420fb517ae68f3dcab3c5651f49d221037283aa4711bc3973ecdcb7c030c24b084ccb850f91d35e78e381970a948e376d4bd7b670086542a61be4c670aab7257fc58dad24a3afa727dff967cab9088587385ca15209c18e06b68ab8c66db7d680fe40677f8a0d6edb9d34b4b1901ba729338a7bb90f98ccc61676934d8b87d7ba15170017e9247a6445236512aaf23a6ccc629e2a2a7d748b0a67b2c64cb61aa549b7befbaef6ba45e0b6c3a72270de5497f6ea95059238d0d28aebf1cb4f209c24c8b83f19368c495ee05638f45b7002c12a23013f24721501d6aaa6c337af9185d8b733464229a8aab8eeb50f8fc5b4d9880897d3128387aae8ba6e2c116a63b5434be0503b77903f98a7efa5b919c4a86f39671a477c4569acaa07b316d8402a1580df17736056acb05379cbc1228aebb671f7ceb2a977e4f04ba363538c4c28f5a585d712453556b4cc74894740b73c5882bab36f96c27dca7caa815331ad4425cbc732ee3a56db445dec2cb7b3c5444e95bf796b3e69999867307af7c716aabca5854a2118eb78e92c9e1da4209ae0c7d61a0920e58f50f62aa4321d541a8ce7d74f456abf09b293f7da5d1549ab0d34044a624cd51c5ff3774101fc4e77cc76a0f3a1224c3ca2d42f92ac6a23862dc2539dadcb396dfc41e73996497879d8c396c3657c379acfac04a652fc4c32aac57e0368ef606bab471e52495369d7c616d3a3d01b668c7a0f0c305efea09a2d01b602c4a2ee47027b0c5f18994c3e369c7b985832a48372fa6af929605b0c1806539a0dbb2b1eaa674ab8720b9381688b18e5136330e303f0b4a9d6b5138a07cc372431c8958260c91c655551b35538860acac1f047905cbec0623bf9c33968583355822dd563af7b71a39113b3024074f865ba8073b412672eececcf8af0669413655c318bc5684e7a655e370840c59666ed8a6884c05060072fd2c0bde6f39c22c1348200855a66aac2155cc13233538aae893abbc3cb4bd2c87ca6f78c49691829a6cf40d7000000000000000000000000000000000000000000000000000000ceb5bdac24ea7f4ad6d89754c2feebb5ef0ac07688d8dd5ce8d9a2c87b213f0011536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 3c14f18e865f367b72dddbccd6c535fc2945bab3799b9edf5dd5da57f28a74aec23c5113f792f0a92e096f9c7af548e96c6a4157de843eaa0a0089e25b8f85ff44187a662845fb8cab374c143f4f96c6482ce7cb7cbf8f27e06dc50e0783568652043c45767295f860e63093d53213c808692d0bdfd10392bab65bac43979fbc5aaf04c824df2383154bdc30362c28d0fdc353f4f18bec2620a906426f744d717f04cf108aa91c82028ae847bdd5e66eea3ec0e719cd1a3f0d36965a8e2a1a03bf4233edfc4b5cfc7fdd8ec969037b3f02404e3bc3933ee3c2e910d86476d9b7667772ac75ea46e181e95b9a3157c3420ccffb064de3ffb32c1c855040eac8cbc15c9ae7ca1aef4c442eb54c3e574c9155474e93a14a5295f66e9ff6292dea202b9bb4738d7280128057586e0a9635459119df84bbfb083f0545d4d8387ce9a502f2c3addf0a7968fad11284277478dea0b29c96b364ea62ae83825011f1ccc6cd7a58026a4250e76696b836bc06f83e74e528d216f474dee938e78534fe21423cea6f843a70096f83e144208700d156261c091782fe8787b32848ab55390e1968370203e59a9a53b1c48a6a449a55ae997d5f222712f4f674991e8a4cbb62b67479b56933c290f701483d2dff855797323f19c06e692940fa32c9c2964f700b4147e23dba5313ac247ee26ca05d147e469b6e870651878328c79fe28158e29a6c41ec48356de5c2374c2d7ca435330264fba31bd9c1c85be3afcd456b3345a669577c996062026108891b8cdd099d91e3c662fcd1a2f28abf1567b519ffeb46e9580ad17a5b13c9c52c544fad1648495b77394232ebaf7e26c57fedc43bffd6021fa165e526627a80761207ea3ef172e8a26bd65bf51ae6ab9071c61c17b19d02e66ed12fdb851adccfb9ce73ea98839f96ce0eb6e1bdcceb752d7c5ac5d6c4bf6c56258048a21208fa289dd517511a5849899ac33d50e1e94fddbcca5987324230ecaf242497be400d80541101793f8fa5bd896bccec92e425bc63500305d69a226a165d070545fc2277a9faf16c5b004aa8c7e8c3147890cd2ab0847afffd4026ca76cc6b5d6c9aefec6fb1b21794e37c56aaece2cee1881ce64c9941f904c6e0143f0332c5b0b9ef7fa394070b73a62b2f811ad53524fbf9a038f185daa3546715acfd63c95594a7f18924c3da980d8996885b04cf7944477b2b9b1d939e81d14f84b129f76046a6d78482ff8debf21315f412c234cb776f529829e07ddd89806e343112d82ae23b90657ebadbb1fb7999c868b52f907b7f8aa131dd334a5332b4b2d8fa664e18edbd89b4596e34eb631cec9e81dfb44fded66b9f236add78150415c3feea074e34b43284765274defae58471f27a889c641069b436ecaeace548b03e95cbea4a424611b79c0a26502808b8e35a1b285163db948692afb29d94367eb43ae5df88467e4cbfa92f0f4b5388a975026c5cf0ad2b8d10c53f3eb5d6d94e5082302e8780e5a7dbe4eeb7061c02f4a46d6611f6599fdf2121bafb38789cc789f2e1730ba6be17caf12d5deed32f731126b3a75f33b86498e1c739db09c3fa2a97fd77a16ce0d6947e5c69120e1490b75cecf695390255938c9f884cb0248082b36ba19580130dbd292b34bed650c4eeadcdf15685ed27b6c23edf7d218bf7d98dfb3018fd7e14e68242554250886dcb6a0496220f8b4c4aed6c87dbdcf62b47bd8c07f6347773937e0bd0680e7e0d62720947ce2a2bdead1919ea3859bb01e341b814dd13615711afb12320cd914dbc97f6767c5d0d69f0e38b46e4bf3b132466bcd89ba1ae98144874c28bf476702975d3afc17fe4bb1dec671b85111e5f1e359c15d6b0421935e26a5d4eac269b64d122f9419a9fa0fd5d239fb20fa31192ba2acfac52c92cf5f339aa80c3e5a2a4ece0b077d5114df54349cc8f2b6daff625d347f5fa60a37913a1402bbf9790eed6ae5b67b87e076479ed1abb258d6a7e91ba07786d819ee869f5ac216341535995799e492911a9b077be49ab3538d3a52fe14e19b6a0d6af2a7df2cb1e5904a3941b079489f574e066f6c565828d2a312573fb6e90ea67a7747c8b55b1f117482c77022b38ccee1a397d82f272166b66af0ab67b631b2dc891e2ce4404e6446563489077873674ef477e9da7d37926489ef60b5a028e8b6ddc871bf5c224be846b9299f02b82c8dbead01d +expected_result = pass +expected_shared_secret = deafeb0bf0d0634e5acaa34966e58df8b9bb63b376e3409db49b4b117643fdc9 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc8cb39ba3237b6f13c80ef947630578d2d213f1914f94c61429bcaea77c646f1b99d35ac8009907ccf604c1211ddaeccc2f1001b49776df94560e5ac35e0a7ee3f39377e252d83558d6e57651b0b3c0365e6a133dbe3002270a0bfdc524e5d298b42c1408e17d155c82d69c256f78a69937843491153ec2117ac40370934d28783a69d0a02526afaa8600d289c27e9481cb737cdc4b9ddf53caf313b3c4b862b08045dc38428b126622d77ff3864fa93919427b049786042d234429e9858ce7b1d57a2fe92979851b9d4ca23fa7a80aa4738c9b777020b857b8fa2e442522423608d51b78c574569b9746e441bed403ac21391fe327818dc81355bcb2f5758320965e10946cda9a7c1d329f7c1720857c8751e57b87186e8dc21199e3b7ffc1c4c5607cc3c258a30163131c5db5d96e2e8c2f209419d5a03dfc618a53b1799cf102348b89ba289fab2b206f61688fd974023619fa5187b8cb28be778b666294bf029d7fa9abe3ea739f131930a13629bb6fa7221a788591f595911d3c8a6625a032f393adec83a1bc0379bc0fc42015610c1e8fec7878cbaf623959a22008ebc81ccd02b0847a7318b414f1ac47ab2b0dd88049c1047e4331767f3847bef0750ac4623696bed9c2162d2b84e0b4b606180a6d2b6dbb5190bc3c6a51780de86071ce2a0f05758e199983ffe8349c036d6667870296c76930b34260af449b2a6795b4fbeb3309f017e9f820c145716a91569057a22b44bc38b368fbe221e1f92d0d5430913580f534b8373aa760d47a0ebb6bcda55b5cb62797b819cd185ea798a1b9e21391381173d2a416eb98db74895085ce31c868f52a2f7654b3779a0a324126c1b3aeb73c073deb19e7925126aac8d87bb09ca69b68dc4fb17bafe16a4315677d57d0c36e9479fb03a30609b7456aa8e8b76c97100728c46ac8f39588f7062c1b27fbd12f4c9bcf95f24f1a698da0e78ff1f4481691068ca7070d341dd519c63815a2fe3286155c741e20a3bd8c89ee6bb069bb89b7aa1b1c4b4ac85699ca2c786d8305cf1c4527979442fb4f3823c7dc887abaf866fd1b20a9933707c23036e653ed99476c242c791744cba152f45040f6bc3414a13dd8670327d50e446a22b07a42bc056a95c94d911356e276cc95d585aeb25f061b87da78550805af57414cec34083be60f6e7b0ddd1a9c60f5725681bb70db9390014df9dbc5e022b4c24563efbc2b32604aa41225d9993f924cceea9c0196a8065237cb47035142b0693d090e6ef48ce85aa33b57c9bbd4c1dcf4b8314162e0f9b44e01732d6cb7876559096620e974cdfc263adfa1c8d94ab6080cbd42fc1a585009662640eed3353117017e754db4cc0901f3c18e6452667312386b8bc27c32cdd9c11c14403d390f80f121c02500a1d03942c0aaf56a83f3f062ebc708003d7deac3a47f33ce9463381b19818cb97c8d61c320da588105651f5496b2d38615a5929e50234a54393814311b52b678ea8b50e3ac47c30ab2f99998a481602b4aa701384ed347878b85b8bc108eb90bda44423e620613e223ea6a03708493b7013be2b926daf33fe3d81fbd9795a885accd8b4ce3ba33ea57bf04530afae5643bbb4b22981ff5b097e68c5615b70b4213b3feb020e968734ed33b6ed87cbf5468c5f055a1dacdbb9b19d2a057a6fc371d389ff6084fecfcab2f0bb66d0931ce29afd098ccc4020af50275fd5600f3b31c063174cf5a63363752cf5612f121bcf549993132c71dc5c4835c396f2436a70092244c82b5497209b779786b3a399237e0a7237e550e0d784f1258c540ea91bb99c915f052fc8164b6c1b88058242f7b13a98cbbe1646274105f330ad0377ac65e6acf89987979d44bcff381620335ef93b9f7698527f2c55a39a4858812e9cc8c99aba640c7915bb1475ae172bbd2251fb2695b842d27f688e1e23f607905bd347c83db7376706f68ccb72c94519e426840b412944c7181f72f98a56c0c5ba302ec728b31a43d6418984c47dc0276bc3cb6c2817e658ba9acfaaa1017659d10beeee7a399e6049dc62f5795558c082f273949d9f82cab2c3977359f510394720cb9815c240ed64ad4f4c4b27057da3abc1486942d01c5852658a267ac18e886c410031bd9aff0950165b53e53cb28b21172b1866d2dd16f9cb59c9bfc8aac8606bfbc2a0861a9c7f62d3d41074e56a73615085b9053fd2ca533470c06970c4c6a097d0b4661c2b001e9bad5238392b811a1276ed0a65493080e94b7813d9baa3c05c9f7820f77e4af8891170a6ab302e23287932b82364fbf5abdb4f2716e5b74705b0756eb6e3b1ab9f96707ffa05d3afb29dff48a004b86bcc784ea003727a49c072cb3cc6cbc4473c40965b5f76670d8cc1a9fd3c4982662b8fc2d9e982debac25d891217dd24f798346b2ec770c427f49ba4452a1c8d49b9089e751931bccb07557db36bbc13225590cc94586058c3c1ba406633e650f703a44aef3c305f652a4f4c785b02eeb40cab763731a7c20d062125a24b2bc58ae6c4a0aa4e4c5a330cfff7a46bac4ca58a33127a8bea7d5598b29c49366cd11cb4d60d71c0d08cad7145216a8878d6c346a32a948b52300c8448d55a532877daffa805320bba26a9f6197a08f71b4f9210cdd9c3416263f5b921191084b87236649a02e9f0a20f09004bee065485088430924326353ad90077ff0a10fd3c077111e909e000000000000000000000000000000000000000000000000000000685787f0aef0813a97602f4a313fcf54eb7464005d6b50ede43e1b99eece8efd2e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = bf6a1a4a5905e3b6bf5d5fff91790e56f6152e31289585d4209cc364cfda745e4da6ab9baf213a75f7f6ae50b4570298035dd17a7108ccb8a5f511a0377562eb37eedc3426e5ceeb793eeceeb5f3ca4935c68d352c6b1ae2bff892c04de562dc2197cec88133bd7384679a1c7cdf80a43aec446e60c8690c50207e54d1d6771bd41ca54654b835cec7bab1efdd6c0417d06cd74ee851c4b0cbff894dd245ea33bfe28adffbd0ec8cf6b34148c6a8126b988f83f5517125b998859abfbf4e9eec1afba438faf25238657d0b9a370df6445dd9527e85502ceffb25e13fe6cd8108475f56252a148ca7d11dff8e83c760a239da62f994dfe5a4d409feba83005402252491e87b5d585168dbe6c4f9b257bbdf7797526a208dd05687e2d8176655848e9f171d6fa63791b02e6508a58f70f461c5de34ca3713c1c0b0b280db1d493ee5103e768ae38482a38692425f05d91b496b47743f28a12d34cf26a7ce164bea186549cd4eb1e0e9558902aa1b63fe90b3b5a1ae952676d37395e64c873f042022c7c9fffe06e875a7828af940e0c4bd0ecff75d8154be5bb5d3dca963f35b0d5d45020c4e793c4f895983a71a1f48d8a6a03cd58f570f56eb3affe3514f89e46dc9a91cc466da782e976aaee83773a481788cf872ce552fc56399fbc8f802303a5e8a0215fa3822d21393d268a15e617edbb9de328ad2d92633fbac21f5efee93588b8f8789aee93019e61602374bf84e004174aec2a98939d3fa29462db61e3cc1acf68606802fe312336e72ecf9faa23177235d7fb3b00b5c8639ef16af505f42943c3c3b8bf0b1118ee78dc8143fc74d178b4db2e4eed82cb21930e67d5fe265e2c095aba86991fd378f5bee637e0a6e283440d57b11cd6e44dbc55e06a574fe959d946b54619091a4a0ea394e5d00c707bb11595773241b23731cc741bbe253369555934daacb06492991e8e5238344e75c7b3b6d85cff5683a75995216228922bbc0e5932bdde90486569d60decd6dda4cb4e8961a1beb45e8e0dda5fe91c2ac9e709f4585f4ccb56d89979767cabfe7ad88094bc975388840c55c8379ead9374b5b368ac51fa7ea08fed2519209ba78dba663a6c2d352bb9aea6bd24131178c52d4a0e161496c758fb8a451001292b56f69180c18aa5afd1a6c0bc1c141aa68fbb9b74a75f893036f3ee4b65eac6a9a67694d8473db851fe78d0ed544e2927c9cdaa0e8187389cc0a15612b1ac53c59ca1deac4cfd6a3944b7df446a0121dc81fa7ada3660e27f6c2f65311f9e2e9a1f97545a8b3c6e226ce547a3d9d283cf37338c07e2f426e7017a6a513fd104b88cb8b9a92cef6a1aee3f12f258a5d059318830a6d842563134e896d577adcd229548396e5b1d3a1bf80b49c064cbc20f22eac0a2f3da972c580a92b293d99b820888ac9b3c50f0c16ca80147e5e73694da824b0e1e1cfc771773727744822e933d2631b1376bdd88f37d124bb6776b83c5918ec63c48c8b339b62d1e487cefccbc8e9f3276d1c29f448c5c37b33a2442f096286e64b90dee751a6de0f50197805a6db4bf77a845df7770dd34a44ad0344caf560c77e7edc655604a4d42e591842022d64c1ae605c749479ba401a31867b4a11b978ad690b4c2a7cb6d0ea262e15ddae9025b522312e08bbad67038b4c2e272bacd18ecc2317410901ed69b6b9f03a6d5575efe5a9c08463ccee314a522fb24163630f888c9eef18539e5a088e80f4604612515dff0e0bce97e9788d70d148431e8eb9cd49f52a42e21e36c392dab9aa3f3c80e6e8f812d18be435a1b073f9c346856446dc5144f5e6776704342cc877b6bbbdb01cae23a579f5238241988a9ddf5cc7f2bf64265b465fe34d911c10265cf7d2208e526d51467de5fc1dff6228d771b643f4e31ac9edd95929eb89c98a3849a34a8672660f8464c42d6566d5ced7639c2f2165d505c7eefe844649a605a3622e60569676a41cd7db48ac0fc624c1cdfbd8e1f07ec14519023b068dd1e58e720d53e61560b1d00f7a1b0f59c20139874c4d0c35004b5477cf5b3880a95864eed75de14c8be43a52cd46d6e4e510058e58d80096a243e191471abdf0f2ed4d7d61ec97ca4b7d2658294a15cbd40414ff3e185a809522ace539bcb806881019930bdab728fa2f2d773f7997db7aae3927500a4a9b9508d199fc622bf62f445fb0c0df9e50e34a833c0a +expected_result = pass +expected_shared_secret = 5a9c3568ee557530a57078310ff6452b09049f55f30df0704f9607674971e033 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca584a4780ea352e9dc85393457e71ca62e85abb2322aa45c4fb3d29b15d55a027b8a74186000b9a05550b2a343a3ac21b0f7a2b2aaf736a1ca49df5b61fa749266b0696ad7b6c48b0dc82803b10a4b64d6caebb33a13c60effd699ad44c1985c9e3f8ab21a0cbd728ab52e07c4bc5ab3f6c698ea307f435bb7b5545c44758fee3b9077b5a318c2b584012cc9b57560236be789bc4b026d1f26a857365b2d1a6e809a9f71e140ec56c4db3829b74539a90345841483daf6840141100c66cbe057261fc346ab8c36b03cc2b2ac838835cd373836bca05d9f57ce2231980ea1bd9908111e79b602572ab37495e9f6025269713f4318dc472d06b473268bcc7c5cb956b5a1ebf419aa18b9d6f184849240470607fdf6325ed561c270b095079734fb61e04c531be893c2621c5ba48bc897868126b995e75777c8ceb100c67556484b71404be802ded5299cc41a83b0c7a99c8d36d55f7fdb4697c446904c2420d667f5e58e0837778ea960bb6605890b8437f24f7d35acbccc41acfcbf2e35270ab36880d67fba099be5882ff1e53ff300bbde74cafa260a124624df72a7f73449b253525e75b658656556422e26352900a0b1ab258dacb5cc3ca0ae9da2826f15b8aec76676920168492ad2b9b56714b3881103634c1cf299403864cfbbda1546d1031e022ed172960171bf94894dd48331f5973bb509d068a32a60f56377b911f5226fc77ab27ba0295ecc70275a0b311284eab09825c14ec7826779039f3319877fe39d8f938068b9916fc60a7359737a918286b2c943801713b78a8d14a558994fccb48ca20065a013318f099917bc930d0ccfc54b6aa0a7791af5c0443c96c17a5a59666f73c395139268024a49bc7285aa7634ce461814592e74081c04a99c84a2205420a5a9777a24b11717011d897c2ceb02cdb79b94d26862df47cd793645b6288f4e7a1f5d18a1bf732dae8850f289307ab82ed5ca025c1553b5d40c6a776946016016ab5913845958904b53fbce279979dc36a0c6b2c483864b33178998e090d0e01d263c84daabca5258027f57bbb99c00d817749b14bfe4902ccb65258d50559d6678206ba44f3c0160dac0434a1e2d25bc16b407b0209b1b08122c68b75a6a4f22e50387f13a3f590ddbca358fc60e8802a25b31bc4ff327c1da127b20132f0036df997b0c7a1d43f8758b4330452ba985c9241b1879c0995247569bd1a1c927b52bf318695e73102e892f9588a527c68196b625ae412b4fb35ebc3c147a4c3860348a414875b60233f8061c38000401452957fc7223303930e653051535e647943b1a50d324108189955e589d837b1ad3fb331ca7b0993c0d5275b2f9254fbdc87ecdc8b28378553719b1de9297bb65abe703294d11aa41f7a5832a7247c100002b2c3afca68bc729f0f2432ecca03b83b6c748cbdc457e1906ae03f25ac5e37ab0880cade4c8aa6904862484e985a88f54c0ac75712ca9706d9c6e130376a14549a1a7a9d2bb155e797c98a22076e00343a55f1d488941a6527e808a65f3b79a73b46c3523f71455c0bb33d26690bf657900d549988cb96069cec0822b1127cd9456c975cccc86486ea3686f46e0ac92b35ff2cb881106c1803823df12163d004ebaa45919dc7a2c304868885badfc4baa43bc386500b1f8acbb0734183b674b338cba409684f993d8a6068d466d4ac82dd5e42f336badb7c78aa41ab2d0eabc90d9a6ce033f1dd9755939a8854498c7415af65b52934246ba521fac2780b0e1586e351dd6266e93ba9e3955c753841373dc89504c7361081034f02e18311fb2297fdbf79d004ba49cc916836209965c6ddc2c4a55b667eb1c08d405b01bc6204250159fd55485d29c48da37dba05a6cec2f856943f383a6a5ea09c947c4c7ca849881aa6f407a1e86be6954b221acaede360ecae49ca9222284695f93480ec710365c68847e7b839aa81d84c6bca8c7a71127a750e078cde65bdc649b17a0a928c8cac51a9e5a40608f21b3254b3e38f81aedf4c69bd49aeecc32089634450c42999357d432a82a0b96a789c3001c7b9a5b55501a7f360616ba7a648648866228bea7520fdb11c70d549fb958c673825f98923469fac9af62c702bab67f29815b331a136b34b29bc54302bf7f35721e722a01cb7a327b078f590864841926214a3f068fddfb8cb196c7a8d8c78358488723bf508a27729085ec4c9bb7337834212b2ab082ee1339a8c64e267517db35ca687826d4b62d40b60aff89c720ac62fa2c3091eb87c3eb1f33272585a6c91d8c669b1a69c9211c098105a0c58960137b3563cb16da942cc90e47c95bb0f9895af845024692bdd99e87269c15f82468454791c7682c8962bb8b85430bb6ff067df8bccd78a476779b075876350b3668fce84af7e5b6a90911f973144740046aa7bab4a1bf2e6961540990d159ac6884c85b28309336ba18ec9e2455cda24a1c25246375dabb21f0c252b4319452719c84756d730a33a90502b4749d36a2ed80b755a931148c8074065487504b5a7c2db6f648adf92d8c8258d2689f921123ae5495feb095b5c4981a860df6478340bac21b700601d324c9d0a1951353fabaa885f00b3622b59d31cfa2eb524b3a5f33e520c6074382ac30cd9636f9c3693f17595a4942f2bbb5b168649fc35a3ad63d11179e64c0a7cb258692087f665620dd0125e5a8901eb8468cd2007020d53b720000000000000000000000000000000000000000000000000000000a8dd5506bfad75f5a719996c4d3372ebc7315ff25049b350b6d52dede10546d5ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 516f535f15a891e51513c4f47d87634dadaee540c8d5c4970f199679cd8faf38eab3c2369df56d5b31722036fada3011eaaafdf4f83acb5141e2054095ba0f31ad2b89532ce8a55908c9349fa23ee04b551853012e712538f02c7c6cb9bf3ca670b8a3319aabaa5f857586bf1cfba6226144b9b40bb90a706635c1a4d252b8f3bdbb3eaceee7c0dda061b9da7a3166c1464f970dadfd92cdf2f6589dd8c07db7d8e7071978c7cfc432e668eda06826facab576af7213713abb2c3538291f9d09e59f956b6f2946d67815956d3b9a492bc2bb1a2942e869245ffed653be70f0e39ff06ac55d7f8282b331404bfaa3ba7213c17f7939238f7f00931e39fb5e97bae2d4f392f59ccdcec0881d75da5933c31f20d66b60c9383d36aa12b1a975fae04bf808f6ba0099a838382b844df1bcf1366e96c462e2219ae96c3d25d10792c775a2d488b27026e17dad61745fdfd44772116092743bc74ac5bd519dfa22a39f90f4bf38160daa52caaf71778f1c2030c8715674c2aa7191c988b6a5ecb02bb68126816db952393e8c52e91249f14e920003a6f803b09543342360857b2de0b227feb86187bff55245d6ea004d54527ecc6196155d0a32fb1f97908c2e61ee1528ba98d039096eaf8d4bff977f05a9a0b53436b55d2b9322cf1b0f6891b0573d44eff7515f5005f0a12b7066180436c24bde5ddb183652b1f41245f812981fe0e97ccbcde1c2f3ef7423d1bb5e744c05ff49dce1af51392851a716834b4f059fe179f1cd31860ed8ecdcf440f62333c86a6cb7c21409fe20afafb972cc3ef584cb76b85208c56c676f21eb27bb490263fafaa2e23e8f3379023df3250678d0287badd7cf425c04632c1b688ec438dc6b3963a26e69e093fba5ed940e672bc8ae109bc78dff824a04b90dcd5a5a453fecf60c33596b4a89bf683e1ee5a3cadcb0a6c1371cf21ff75335f16d94b67c0b774c38c592a498a9d7ace89c5cccd998a339c84d3ad90e2fc96c0d1d4caa6cba13c5a11a9e04936f3610e16b36c2c37bbfb73517ac10ed3bafd6b9424c2dae97600458553a243e124c85ce66b414129f3f08cd48b33af0a633befa2515a5b7eff8b6ba70710538926d05ba1fe341426278efb17b2b3769069cae9c051168b5e5deb437550e1eb7c0bf88c2514fd51d8d511b7ec90c233b846a103c0fc516e8dd0805c5a2b0880b9a5e293e0511926802b252b7781332fd73be09f02a7ef234cd1cb1effe32cdd7e3a37c8668884cb8e6cc10033f42786c3ceae1754dd4b7b9e69fbc8273e27f977b0e1c3b320d2dde5f9edbc751b742ab24cfd776a67f3a5d52409911d1fc1dfdc1d35771f5ad35d19c36401b2688118efaf1c71f333528ec6140dd2196946d69c6f1b6f53428904dafa316bd4a28ab7fbc9380928abece9ad7ff6c6a9c26fc581550900b7e6e4db71118da5d5db5c504d0d45b310abf0057523d573f868aa04a99be48cc694e194737a1502c2a379ad39ee8d6448867aa2c970c84f00c446236ab4908d791d304f69089968ec5412a807501f5a11ddb06bfa598ac07ec27776415da98efc38326973d6908c1b8cacb95cf2a04811ca39bf1ffce699e4c6d8bd35e51e4e02b89a3545391354a8f4d46beaf9864794524bd6c975b15ae0dceb2c4623096d75bd1ac8991880b3cddeced70fd3b27af44b2d36147c2e0d34048e4f30de879618e7208529d30122fcb179f754d2745169afea6e91d5538d67c54648faf2b61ee1e75154db58d17160dc5a5a36fab0a8dc86e421c4d99f963e6822802adc7b261357bf34fb4ef076d1d617e3ace0b8936139b52bf6ad4ad26205dc206756ca54c972bf932d4d0646df0eaae7a7bd2962b26df4aa54f4e9cc353896163c8b48355c7df687941949ed03b3434102708f881cd9a114163fba2263e29f992eacc807c2a96dae2cfa5701122f8426feaaf2d739802b29f1d70cd6a46d1a8e15bbda052c2ea8d1f41d4a5d856c44ebf9c7fa22005eebb61c0f0012e4e36b2ac1926db6938790e1319b9bd66de5ba35674bbf22317731a8133eb3c45cde4f328275592472ede408060462ce06623926426e5c2fdcbf725d5bac2b34e0c887e668e0be3c1cc7ffb97dd030295f8739c9813bb429c4ad0d381bf8958d76780beca5b9f559deb25905c618fabdd3bba6a80085b2e5b048a93ee2673447a70a58a09f06a30298ee8d4170fcd +expected_result = pass +expected_shared_secret = 2b5d1e7837bc6877b4bad1c4b7e04276d96f318dd248017846f71328d85e2eda + +comment = Rho leads to frequent rejection on matrix expansion +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5dc9ba816e19d8a177de33a855960b7c464cfd51a7279a48c80091ec357b9fd118e12f00736036fa8268079754a4d565773f2a5d5c913109a4606a276d07372eb96474c7722d85a17a50a956b3ca8132415b2c404a0288aadb44fbb00217c0005ee36137768c3d4169d300ab2876c1b2a92c0cf119fef5018bf7acfd2031929b9671898c64388898fb74a483a100ce2ae67275e53b00d94c2888f831a286631450308aea2580fc5cdbae53b7108a9d3cba88a437a5c0917dfa3bd7fb2266f2b2f57f52724b67e58cc2781a95191f60a34d74199102b5fe941874a4433034ae6c9aff9e2bf16f01781d72424508835e3a587903eefeb0b0d218e11183cc7293c81c09cb5fc4eaba4cdf22284206b23b87566da704665527c6c587aa3070b01e79094747a87ebb2b9e5296a2405528c224ef45ee6fcaf0c537fa2e2479d579d71a3400793188d895323f274077416f94c4e68811ad9c73598d7ccd53bcd18f8b1cca8bb5591298132258f4210d36722217c2fc5925330d03d1c037cc7d520f52b7774187555c00026e85418aa30f84bc81607376ac9c2e64a98a4c024c7165610027967228cf5f85dc88ccf5df023a8cc0e76723c97b99934766caaa3bfae25afacd39eaae56cf36023c6e368cbf38f27a268ca24845c48a85f2198a6c1744c73c62c830c34b8248b52b62f847c3ef87b6458235fd25cbe2abe57aa62709452ca6412c0932c3a10bce9181628631db6a7b525d1c7e5231e33f65470a31371023444926a19f80a67495a9fd1043efb44adf3789c576577f5ae6d136b3268606fdabe081509fe1c4c05077a6805b22eea9f965666e82866a47444721a3e7647250ccbc69df06b3e3c3895c30f6d275ab624913173952d630aa72240bc4b979ee55ce8505f42f1b7ae797f53f4b23616a00df2153fe89c94391a35074946764275e064abaa01487830839616df9485423029b470401cf010fea769d6f237cb00bc2e8c13f6c49f740c9544aa6519e93dd824ca395076c184b2b2078e4a51622401be47f089d2668260b1b8817052d0c407a76009a0b61abb0a0b3c481d86d4c4fe19b910d1b34fd4408098ae5a599e7eaa04321c44da53297f788d9c2a0707f8788780343a80cfe6119bccba711424cd8c453649870280568347ab5bed10b57222c213e55c703ba7f154939898c89e43643635ce47534f770c44dc839f295b1361a9a6bfd494baa2b8a3264bddd204f1f063887192a0f1849e2b0b3fb6293c2cabf6fab1aada5ab9c35a6ecab7b4c605d6178b26203ea82a76a9fbb7d95c8cf0230dc2cc57128493d0b47324d333ace21d3b3750ce6584cf193a0aaa25f8f865d93495598109d5b07450bc9c590905e9a19934e28bb5bbb149f2b68965056b989338240d1fc52e87446d3ad6617927cdbd268249b785695311458909c62a724db618fc28114a904053ca89d127150d930d583ac664ec1ba08949a027bc86c403d0865b9d3781b0d4a034067fc558033760672639697d649f8bc4cd2a90ccf2435fcbd98b3dec0367f02889991aff7709bb0503a2c732c3869b4f969a75f797f32a323d546a5c47ae6e3292872ba85414c7cfb28078d67afbc42894a92172ec2270974a259680f659a03147661ce4ce94d608b62a660c0099ee1460b71b4c091110ad6ac5e5c5978ec04a203686f1385573663956e8c77a5c29ef06235b671ecff82e49d68f8e0054409c68858954d25162f0177fb08b29f5d9afcd4cc512d8b0f42877a60197837717887849ee127d5f76871276b9a285307e96890fd3569c9ba5c58664cc20744c9609bfb859f72c85363a34a721bcfbf2b9c48c1ff8d813ca596430d62370f91b342516e650173c711196a50396e43b46d6661087c4adfb8639c0cb17183dae91b95e1832ac14554909390e087e3bc09e9ea5ad53670eb93c4fc653a6798428be514d6d00509ea1310ba84fe56b2eea2006817b31bf661dcaa3b26592898bba2ea0379aeaab254b9b62c4421a06254798b892272095a989513a2199c8d90afd753b574ca7f17c2c96334f32a703dfe4735bc2965db62a5c995e349bb1d6c63736874180b044dfec8c83527731781dc193b68c997b4f8637a7c86a8c38172e42cf4ea46dd43abed5b0b386508a00bb0203d6a8a0ab5edf228a85aa8f9152b48bf1bb92240c92059b531b4206abaf3478c41d0c1c054422a7fcc405f7bbf453cd9e133208e2475738a03e1ac2f18088cfcb51c8ba447514aa59fb54066c979de9c38c43cde0162f30023c3a1026a2a2a18cc6c0cfc390b7336548a06239d287b6709ba92869a8673448e142f74848bb38b1ded527b0a69370910fcffc53cb875b008d7505428ec11b3f93c7ba27664ea1099f6dbb3cc1ea7d84e1807f3b5cb1b2bac0053c8097094ea73aa033221c853f88672e3ea335a5499502037dbfa227aa458d5ea59d80fa4a2eb72fdf514f4fe22763d227c9a69a5769b63168c4b4fa9403e3a1ef54b39e6568479796c591afbbe1a911f92df63aaa698a2f5309a92617242999176239bc01b8ad26b02b6d7446d8067a52d40c424b99bd353de13a6defc9a92855763fbbce9f648715aab80342beaca6928a036c08361643f669365105fc6853db1a44ac0b574a842e58a74905c9c437fa375fb22d7b113ec4e91319926168516618139d8edb60574774bd808f88457609127617c85394c65f2e3d78ca47000000000000000000000000000000000000000000000000000000007aa0d0036620b783edcee3438127f41dcc173ca5c8a67d52254a308b80bdc28bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = e831dc3e5f67734ce3520b52763f64d8f40199c8dd2e723441f9d9fe9b33a1ad8ec79fce3745bc53ddf45990ee1f86fe0191cd5515093eebf6357409891e4822b543373ff83f3c0f73b67bf1e15cbe8b95b0e3dbbb20f10fcad2bd05778ae106e8ab813a131469bbc6da7c2ac3b991c6e070fdc7781cce3cca56fb572ca822b8a52592d24141f089a4dbb842a4318a223b947aa7684be12273592e0d4b6fb65071f9292293a85eadee0cd22b6b893a683d504906923abf3b25e0e7024e7b499b281c965fdea72de1f02fcebf0bdbbf6e3ca02bd05089f79f641ad199300cecc03d88d41360cc895e77ffec06f835c5cba89e8e3d17906bad950b85542bcc551588c32f0376631f554cef3de448afccf8efeefbab031f1c95e569c8b90bda0038082185370403ec340ca345c7cfb1e82a2c5c47bbcfde132e798f53da8c33adabc610272e7ff2037a009e3d3df4f521e8c9b5f3ed7cf28bed5d25145926edc4ce783b11896be3ed184e3d9b92b29dae5510fbec4386e89bcfc033704d05ba91bc6bb09320bf017ad7c567f8eedc273f992fb6d6dbdc9fcebff8007088afd5c9eeb3b14b152185a01b8fb537530b7369b30ed437a280f71597d09b07c1477d8680ede31997c8b125267777437316c44c3b1a1251f608ebf5b37416b5a2914edda779653010685c0d391f888073bac0d4f9b197fa009bc0bcffbcdf0fe2335d6062edbe8f25f87abe8f75b80e9f9cb6709057271ed6690c9b6bc6044c218d65c88b8aba768350567374b66e0489803a9932f77008faee9a83402269803ca5c90592491c686bb25b627dc997a3a8c6db9e5233e02ddb4e5fafc182bf996f741f6f34933d7ced8eb86da62e2739f8a0b956ea7bd854b1c6328671adcb0e233ab192e6f77594a2a3a11dc534a21b5e49bfa45122e24d878c4614180b230836e95a9b3dc8ceb7c826e83a66bed645bdbdc0c4257cac60406306bdfa30a8b8f5a4480db8c75b68b31604cb3eae19b3893d3600932523d0c55a4ed3bf8f86404764187dd4214de1d9bdbdadc7c9fecf06a823d3b3ae16561b3b1890fe1b9689d92e478120e9c38262d312b3ae2eb3d773d946ec99f018a6963b261fa65de5887801882c64f5598003aa4dba947022112cb33febaf8b224fcd3ed10cd2f6b4396c966b5a9709e69c7b7eef4a926171762ad9707af6ee93d4c17b04af42fad670cb7099393d8182045a22e1a7bb8e02da5d4e1fe2bf8c8bdabf7f7e2a3e1fb5db003cf8078635dcbb3cd2b49cb3b8d84e6ed64944c2d75cd6f557deb1b51029df2320ddbdee99f41153cfd7ba46d44c63c90772c3d60531f60e7e761913dcabedd57bfeab2fd0d8bf7df560d8fe30763e7d45c22459991ef1583e6e937edaab7e9f1e8a68552336993460c3dfde7f3a3c5b8b44d6afd57f04d62feb97290b488286426c48c4c87fcaddef7c06a534b671698718fa326549ef5e8e724cb11c21f7b362b967caaafd8205a3eec0a52bcb0d6ed6a1d0c4f433cada99e021047536782581584ef2677b3f3bf75983630e70d57f90b13c369bd4103fd643953190a536b05ea60b47da77bd0f6fabd0ded8f608a08d807234b54830aca2fe82a181626a9b9a219246b039036d1cb04748a2f84094770a12de1411e4510f11b5d090e79d8185cd8718649d88000e6f9571bdf78623a85c42afda73e637bde0b5a5e73aa2ebe2cd0897ebc09ad6974d825a5540627b1cb0e7df03a73b91270ea6402927bc4698cc061cbbec9245024e0515bc27a52714e2189ff3a17caf5b3530b781f70786f074d5c01b5a108cf7d13c2363cc54c73ce71b4b33eb354dc377dab5807a7d05808833c270d5735fb1e75727f66d3ca1ba467545590f3c2fc1218d94bb264ae313930ff8485d616cfd5a64080837ca618344559b46ca89c8b29f83e9a2bb62db57cab70be4042e01f68ef54d3a915d0eb51f21ff89b729ba4d63c6b2fb1b14e5e397f13f0c277dd81705581de763d3a3b8e2115156b4766d40e8bdc0d68bf76e14233d8be21a68d881ca6f5a11a1ceb0393f73a9276eb78bbd740e4a94128e6f5eb00aa10974cf41c6a4cd22ead82816a402a50b306b5312ba196ea4df4c5386668079ccc95a75893b834415254b2feb5b25f0c7529d6954a3657fcef64a8eff497b95ffbbf20bf7023cc62f2119e2f06b3e5fd22b39feef1acec8bac4962bf52b90ed35 +expected_result = pass +expected_shared_secret = cce58b5d736b86aad09ef4782fe87a0a4555c7f0a4b190de6246cfb21308b103 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00dfa8bb9d8c58e33260020a33fc04021baba0f6375ddee4a6023846a2dc73eb69758edc915ab2446b1c59fed89bbb86a9be2242c117cb719274873c8b0a2857e4076b3a792965011675c23deb8bc0cf7b2e3ee38493461f8a2068bcd899f1822dfbe8444a612f9fbacbf87a0d45f98a541c5141b230be12763a3563f5d47e369b65c10254e5f63934a05c8ab3409d7b4207dc423d537abd4404a9ec6afb1cbb529619bee740a4c71efc952b3b871043c24c0c919f74f508bc23a9c1ea8b76ac449e28379af42bb6140d376c9a4ec76b34042c7d711efb559c8c87170662788b4cc907e4882d4332d90c43175cc56eb943d589a30a5ac1ae312aeb8432a1d7b2f7448fe0f48ad069989e908d28616530246f8e817aecf6ae638acd7030a596d5be06964eeada35f6175bc0d20c26636943f1609eba3b8852531f083a576231c9b222a9f96ab1fb79aa0149155881fae91adf26c4f1e463f6f603511311351c6c1d1832f482306d66a4a2e585b7e223bd539fc45c5b29558e3110cc268356edf4bdfc2177e50618c73948527b9073c885ce0873dc47350eb3a421f59b4cf27438ca36d3f271b4467f61a2bfde259cd4a67674c4a1827a7e23e24e023b08aabac3c8855d4c737f0e73600f368a8614529aa4217f198e1eb69696f2bbb829835ffaa069f31b1c9c5100ca1ea6781b47c3bd788ac8a3831a56b08093fa64f70a1d3402b17b184e96dbae2b84aa75c2116dc1ba6183c6ce5a3cf1e1c65807245fa3211e9a49703498451916a8a04325bcbf34140539b89acb550565525f99aac5cff44d25c163d30aa6d9f36edd44a3b2c6ba5b54ad0b0b28a5e0991fb41b909067c1300fa6d174dea315f33434b6f79016b5be65d87333e606b2243ff524a01a754adc354ae2b444271a1ca5d4c0f06761300715ddf58cf16a41a83892ab379348b778d1a62cb4b806f03c3f219b8419c746b1b127f5cb8a853955626ba6a5130b19022845cbbb250759bea234592cb294fb7c97777855236659f48b59a21c99ec9130baad818536ff238b33234c718a45de873a69d693db31157a86c9a123b5ee11b715b90a409308efe93db1e3512b012435f26e260527681bb939216ff5409002dc4dd8ac83f41c745509a82036ac3ae524cff190e07998b2e93bac316932fc0a56f98f27a7189ed4449b875f97a2950366754d85a299a422e7b7405b629542007ba5c93e372ab3d6b2ca26db5a9107cddb34408d0b075e209239c2c52e041c2889a625b86282ab8232e10cb14c04ecea6037759f8a6057d4c2037527bae813982128205e535a855710e077cf4b3c94db0683d462365f40043a328cc0991b84e8066e44bc2cd020722157111a76970a521f85a24708565c38babc003b1f84739ff5c7896bb3b9515cea8074f2eb18592b2c9af9b67d4b3f831093bc49993cab27f4b8a47c4364c2855d9cb2cc7e5c7f9d6b70076057e3b989fd314e1c16161a4b1e83713c1fec8cf29a60271808c03814e7252c52c1440d933c363b9878b198ad3641c92c53e5d4bb240b03fb81086662041c03189e43c7afea6cc036a12af28b051792fca44dbec68839d3ce6de4340e88bb4289105e162e8021c169c81aa462866cf20eca2206f7745685abba5636897a8c8ba1292ec1106d623b0e2769244f702a3c295dae415602a2b313da54184aa3c32992bf3c7a846b30fb046c816ca123854481ca1a6d1076ba261f0f969003a37a83e822b668006aac6d5ea3be1f91c5f2300c53372668d3059ba8b8f6f020d2c5ae135811c395138f4a3c17f86f20f2bf704705f7b7acb1c617367bced496cb3ee5bb23e34eac352d60459704ab39b7b2b98bd2c7d5f809382331c3f29bef5aa25b18adcd821dc4d0854638be88fa55b1d00babf77ac42b6e256a1fc3030870a8c612dc2dcc686ffba99093b13889da8631a60b150946cf85188e15826f22866168600c3629494063f1a16ff5b90d6db24cb08c6b6d0257730970942ace54f0a0316b0518c1810c860b276b510424163e6826dffb02fa1572b96a857af935ac8423fb9179452cbea55c3fa490148793c42a0450dfc286ae68b782847eabc30e3652bd7d998324b6b87f7b308a947b1bc74683c02f73f2b130219529950bbfbb6b103645685c8461216e8d51bb2c1266b449657e63625af83743b584e325866ad14b0d5361975c01462739139c8ced3c356a21080d5649753a5ac4849c7ea42820d712490a174243cb744b75cad06f4231ad132321c6f91469024a29d7ab8dcac97a91aa8a08adf39638c1053082c3cc4e38adc7950e280c17ff4781600a95692a76f0c53456eb697d30a354f738cee78b5ab7ca72f99b8c224e44d3337851143c46907dd7cc6be50f6f3ac6f8d8537ff4bd12618b79881148a9791bfa77fd062d65c3a5e9f806770664a050570ca2858175867731c2e2e49ec3a88015b96498806ad52580dca82a37d34b39fb5401e45aa7f8ceaff25e6cf94b0db972d1c21f601041ab309cb7e757b2d65578b252585bb6c9456f35a89024306cba79886cb05af6cb230f56025d6c31c325bd64ac6cef327e66f6b4bb80aeee82043468914a7b0b5481ae7b954789836e59dab088b54467a85fc042a26d0581a1d6059bab0f5d0050a61ca1ef1c705f4bb9fee243b8452ab7ba022bd6a3838baacd8725e7b37bb09580e371813ab53ce7746c7ae67fe6cd89411d000000000000000000000000000000000000000000000000000000438256d8a53ce5b5b7f8a459eaa59843deae0326fcf80a66f567d501988ab521e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 04825db8d0ffc522482a8464e01d1da34eb0984cee438850ca8e3b8fa37ccf842aa33ac29ccd52eca6f187be197907e7f84ef4bfccb1af2ca91e7fa3cc6cda0dd3df2efed4c3980d9fb011ed301a2117176d5a94c1d9983fde14e4f2e45f28932df2ef001341e57053462edbf03f4f6133918787ba1d62619eb818655091c7660dd4162a1caa675b125ba8461b137a55296b968d1851c96c455809c1d9151403e2530b18ac186ca769cce801f4cdfd181ce90515dc1cd8c1c66596248099de2ffb8ee5486d7674ef326338dd55b2fec7798e34f57351cfe5258a52a6723c147e9908d05132636795ca6f0bd682a10b100688e4d9f9d619e2e8de507caa684208bf8bf9e3b63d473b51ada0ec4424021181128f55595c2fcde65667e5221bd895eb9560944f7262ec89d9070c19b45393a69502a602d753b97e8fee4f1ba1762c21e87d04d3a86c3368b15043d36906472bbaf160130a31ee3ae005e1711d68e07b176349a50647da3746f42862d1dd394b75f4a4baa3061544477cbdd03a37e34a2c57992cbb022df33f4525ca3589b295967976d8f46c931c047b9912de175f2afffa428ef4e68f2594aa88ba839e9c278b23af1b0d1d7094ceeece58ad15d92524baf693c0aebec574c10d67596dc5d835880cc3c79263e5ea520e6d3dbb32ca894f6b37c07b7077e4f807b1f931fe37324d237be301f92798c1279b73e1f57de6825588f5a1eba171b85cde0e4b137c84967af4f12f26f340f0269868184c4b2e01648f68db166ebb134b67e135d3f510f16c450024968106fc8fdc6d49043a1206f89a8ebb7a59a69d354440ce2f6ee4617df5acd396e3739639094efbfd93ea89c436a776c910dae04317c3c9c9af5b265d8e8fc3934a5527125bbe8b72ea8f9c7ed3e760107b313e4855c799e8013a4f29dd69d7922cb76a5cbc6b2d3a6468d74ef015da8c9c3f3c47da81ed7f1491fbdd67c800aacab404e88df2c7fa383ad3d07a1139881db4e99cad396769148d143be6ec5832fe8574310b9b89644865bb206b1f75704dc883c3913ce8f4a3bb0c24dee01548727957d85e42139c16b5e9dec16df089bc07f7466ca38a421709e4cd86ad111d7ed7a317764d13ef73fa4e65722d955d97e8f37341bc511f9596f2c46c356e5366162ac33dd643011777fee6beb5e8b03ded3948e165db06fa89a1e576d1e52f7785b6fb1133ee82a283766cc81948879815e8fa05cf29c727b8820b39a4ad80ef57e919b71d83657331c8daf6cfb1cf7f883ad31fed93df35abb12ad6781b19c0f4223303d39957798d516d09dc00d8dc52fb60464e55b8db1ba5e23236873c1c4001bcea552f5f633ab42ff3124aa5d62592a9405dc1277e24a9fe610de9f3b2321774ef6b6dbd91f1030561ccd890a99df2a039264c74a3cc5bf97ce8572a4ac1a34745e55f9d31bdebddc04882fb27283d63cea4fbe6e5f5c660a8ab5a535c44c56c39664206e63b11ab9f7127579e9e7bf02ca8e249c2d21639f6e09c5e4b73ea45351d0841f87aca886cf4b171981289096858f59a0796d04d2b0e1dd8721ff246cf53f46b6d6fa2240907440319e0fadded6877a1cd9be7347a2b757a11e0563b6df98bb12c79c6fa60803bed991bae7524f7610e77026d5e75843ec50e684bbabd0b37b1c1e2b1b58c88022bc874e401828d20a013dd67f1e26a27b440b3a85292a65c39ef0ef17d26178fabbcc21a64e4b90daeec7a763402105f42a819fb9096da9a52fc3e918259fecf4aec6f54f167ffb795264ba7ca86e7f9ad67df0f79ba29a83534354a66b7c9c32dd386809e3245b3d7b4d353c3ccce2df45d30a37a9bb5d197d1ef74a31b0e9c9022298ef0fad317ea3990af27d9b2c80c1a123d773aacf759dca2042046014b7e228c963977cbf7ab81cfb7870e9d26049428b2eb88d1e4e1def593f087adc169e46a36869ee73ce1f5b3ce962636a75b1d14d1423fcae3332d2cd6ef6bff1b8cb7221c04b7a27e5dd7adda864826444c94f4247601004091548f8e3fe14db0e3cca9528e76e2db9d5686fdd51442f799e41d7f63f93a17628b65233e9882b82916e02a0f84e5b0592ab1b8719a0aac9428e2eab67c95738c82e4b0a2c1135bbbb9d243acf146b2ee88aa84ac00af15cada505528c1eeb3c7bb23dea16992c489febb1e242a67dbfb454c95b42740baf31df72eba9351e1c1 +expected_result = pass +expected_shared_secret = 536cdb35f0c8ba05ae954b77f6b04849704359e9e7cdc7ff879f4b70dde3fbd2 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697c6b844a5959672b08796868e7107108ca4c30a58be4ff7b37b0402697aca2dc4839dc51a8811c34c8183442711a8d055b640cd73d2caff9357bdd9ad36835ae9d55d1a291e040652d020a905027a616b3b5c63c0be2c1068e9cb0a9b4abbf346590237f96422308ba86b055872e156470b53e35b2a604bcbd2b97849446684149a86d9980c5182f1a020c32b14de18c03cd0633e303bf9f8a24ff0c95d5a65c031c18550b7d7d5b8ec672c3953bb3be0c3f13925200394aabb26090a3b9a12bde30418b997abf310c1724a88b9782418d09552a63e2855b7af2196d422761f5c8a877426976c90552bc203f5657f5370258b936c3706f074c11b3b2586391f4c4bcdd959615a819aacfb48d2c799a9abb182c7a9fda6a80ee50c4a827c9f50835b1859033629a9601b5b8b357913b6de142a501974a0c191a071a95cb8c45fa857736a93400141cc325d1b4518d3ea58a94c14f9b261759281b00213f91652b1e52bbc0c488bc0990a136e8e3b5e20f41d9f218646d43745245ca4c277709903c06b2d1ac8bfd7d00164a4122e50441742702ae38c2d422f6d956a214375485443b11c3a1d705a03728ba53b9cfdea8c83550ef17b9779220885b993df38bd50d12933d3a4918c92813490aa5792659206569b7514a413db3506c28095ca4840f964312ea8862bdc932bea84fc19749c026d0e3c620de5942006b47083514f141f2fa81713bb95523ba5df235a78f52aca7a8b86256c64933baa18342c1a3de1d3a0697809f6762290b0474e205253bbc80064a8d60ab8844324e20c1b249624bdd5434efcb46f52a1d3881cbf0055c390a91b286bf0dc67a95a4acf40cd858427f805b057d85a5d121a7888626341a7e475a512476d8f15993f58918a22b92c23908bc528dca6c3239794b802335174b2e2246d579b5de3a17d7f1aadfe69906601730f4b6d6717ad98d6371628b062750459fc9cc1640b8a584a92d10d4adc136c8c7bfe76748a91af2d644ba95690a34114ea574495f967f4b951cb487f4369858f79c111e8671a250dc0c053d857b3d02566e2254df7c1be3d1651bdf29d96829a5f41c691f4c1e4d8a5dc5b4fc9dc772e4411c442bbcb767508b7585116232b8b4210bb01f7bb24f54820b29a494a07a4456b785b90b29fb89e265985133828e8819f3c8437449748c7cc7b5c40ad0fe193ed6b1f0b0ba71339adccc7020b9334107c32ef765da84564f8ca0efc213e91219a11c495a44b905acabf18720f8396c4dfaa78a5258e980c6011712188bcbf10d9cec3028bfc85a2be9b7fc879cb86175900a66df3128843c53ce2417be898073b362b98942bd52183fc0b54e5b84570d59cdb6282ceeb3ee9226c5a5806c4646056b4aed3a09dcf4821deaa9e2b7623b0193d2ffc25abcacdbd6a39615102818b9ffb6a6ca89911aaba7f1ab6cc1601bb056061fd4417161b9a1678be6f5558d2870af1d18219a031e685c66cb74ebe7a2f177b59038656ffc56801c839445c61035bc54ef2b2aa451ce494acb9574c8fb4a6e6399f07ecc2ad5054bb23cbad267a9ef4c350a2403c06bbce5bb71f2865d905624fc0c84868a3a7f52cbaf45f9ef27a9a0a3e83da93721464a910b9f0399fa1b856bee051ab84ad33113d7001af17926b70e758f8001a790968178c1b9e679e877591fd177384519da0c94157001bdb6b112a74241a447b4fb31126ac94e993711c4658f20b81a7526a55e9945f53878dd64a09a481023b385de41b763ca371a3cb5c927549b112fd73cbf2012a5b334f446962111907c4b04a0c06ad9c69b85a722be0a33860997ed58312bc0b1958c4a016650eed626661785ca1e8766efc09732a7c3f8044d18564e2dc8ad9c62563a01433d8145b13968835111073cb134a9b0dc80f195ab12732514cba1a66929065e3159c4a6e7d40b182f420ba56aa6d4446eb7bbf49db265cd22c189139b50b2ad4ba1fe8a130e4d9427cfabef8a946a51a5defe3642842365608b0af110116dc3bb1db7b2ab137c6c3a9c04253d60c72e696610dfb62ee841d7d427842b032a254c3647b0812f20175575ec1f1c0ea14824aa687c4c52f6d224c289862e015634a815dadfb1ec495c4cc968ad6e983c829490f1905b55a1d4a08b50d3114ef6cb4c780cab2ea702b8762c89492a29c452ee35e00c366a7e932a916977c7aaec8908219466864f8b0c5f8a3c46c745aa96550a710203055e90916b190872c186efa16172399240e0801b3166810360db1c7788a33be47062aa3310b57c1220b9001491512be0366bcc67ed80640fbfc7fa5199d261a3b9204cc085baf653635c77c80c39a080dd61b3b095c9ea24c8cd270a722bc16ec5011e2b6494b0560f8b126b943b0b56fd0f82be5fb615d724c74002f8aa85aa91cabe3d79e39753252b847843aaefcf56e08a919b7bb7bb5e404770a46e6bcaf4d278924f85a49a496aecb6ef2ab692590877f2710cb642f312231310926eaf8a96b4ac13224439decce0bc614e8050d698b015d318f284109e2103d1e877a4f43bda014291377172c6c8e1bd7c80aebb3ec3578cde5ac745335b6408d7cb5150e26bf95641441dc06d9454ce9e75bd6eb19b4a49c0b70adec9695c6a5366e69146aea0a6f27c53f19c4c718cd21d1601a8a1bd2c26f9b5aa984abc34c4bc9b0e212e1b84b2e41547883378681045145b341cd0933ae00000000000000000000000000000000000000000000000000000069d5efec0bac9641295efca3f5b6600f3067c8f4d8492e698ff0dff4983a8dcbc975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 8d6c45548a028fe38093d0ed1c1f89f921d823750a65a0f4b55eec20b6144a6632427f53b6a56e7419f89286e0b958d63d1b5ddc633edc0b08414794b6e80265b426bda64347c7e6e8071a7076823bcbc9c96ed247d85386dea5de7eb551fcc92d86f05c121d16fe669afa879faba422c460c1998d150fd0f2a27b9928b66c022f879f153f604d6372c173afa6e3bcb8b9792db362f0b3ca28c7cc4e128019cdeefaff98cf247f3db5a35b59027124d440fe7c3f523e36e48c343bd10acbb4faf3859e7012469779ecd010c6a94ec63021be2c22290ab1e4bc92dae6dccc71263172172a0c527dd379453e053050b79aba7100854473abeac7c0f7d29fb9f72059e5b64f83cf8a7be5c2524e0d87e7b9b1851851291534bddb128d69cb025416433d006c7ae4e1e9ba95ea63dc614a8677ab1472cd8ca7d9fde895a658e0fd4755dc340e46847265454d16e561ef12af68e4be6db09c58d91221cdaa5a2188fa05258b0089c1d66ac890d8c7b9149ee9e27bf16cf78a323c831c5f3cc063a2aa48f8306bdd296efd061305b1da2a696bd80fe90d2a873bc9384231a6edcfc6a83bbea524eab04af929d6d489ecf5480e67722f5e67ebf463d36a6b26131e9284e40083b90e0fba3db9e347b7470405cb4486ac1ecd87c4ae8893d65dd191466863d4d98226c6790cb8a176b53978e726b5494397d7a7e522ef31cd40e600f4156384a2e605be4be6be73b57aa1120b05700cf7bcfab4aaaa439cb152da52f4129b78c50f5d7994591b37fd444a907981d029298d590f4d7ac3bbde8d852e65d85a0402ef680f348146edcfca9886509e8017354daa6634a4880ddb3db205aa23b7f1934a35464105fe852911c7729fdd5ae11b8ffbd3e329c7781bf9a19e8a25d2f15787178cfa6addb4f6d739d611dac67d64f01647ccea0a02f2f03ab1dbf0e45c95dacca0395b3b2241a2a4ff3d82d8fb02218dce04d2e00ec60208a9835daed88c91b75a94d80a5c10054491d48574766c40d8b2aa96836f9965117310574168eb234ea516df470ec12ae167c4b618162b6b7d751b9e8f7ec84262c8a3d442577456023d2abaf2f8f666c7e7c2b230474597e344fad49eee580f429a65e40abad25eb45b3cd9df1cd42aca2693be05af75241638df4a8b400e2df9342c35f450b359c1b0cfb5190453863d412061361ac6fb7828044e55302bcc6134cfcfe6247034a65e7fb89da7ea05beb35a386950957aafd29c4d60770d6d150a3c97e50ab9e6430bec496b9255aa054383d1858956f86d600ca56f05db5546af09b81a3a9b473d9b8b5d83de010a6c4dd27bdc1e699e998cd2b2412c732d21908441e7e9d43b571da361108518223b1a3e8f7c9f36599e4f933c9208a0716487c89050b473a1d027b31044ebaa81f8e62f4766c3887fe15282e84dfe303ed273f96fc70b6f4402a5d97a59058d016f3f6e9dff119edec4654aeda2cc011cf005ba3d6cb562c23d8ab2aa1cc1bd362ecb80f3e0b2261ef518b77664f58e90747f273fb19386d3602164e1c126b754269a6b5da31f965c36023fb2eb454e6fe0ea83c83c2033b49cf54056119660369a499da230a4a6d528729809dce197ea36b27ae6324197ba3dedd5044069ecc9f5ea8a02ec29089dd9e991fb828b87f3c573a0bd7b9490f5437d18f98526b4fb66ccbf2f58bb8b27441fd5a8b54e23861115bddb1ef115075541d6187aa3083e156a61c4ba69613251e2c0800df9ebdde17ae7643c3d6032680ed73b44711570a8b269649b33360a92206b4c4ec4529287376d3b0596d9dc94a5a25a75596fb3efb449fdae50f3446592d9a0fea2e9c68de91e21a09f85a3889635927414d88a5f413578d2c2e79858ab9a2a75f9606eb8d3a4fb582429bc5527f5e56da5f0e24cb3afab72925b3a9cd2443304dcc1cd96d0c496ccfe6941f870c230bd3831e7d6c25ac1132cae6fd7d874192514e7f812630e0919aa735b5a7f8fb04fade34f1a478b3b2617f0fbb6aaa1392adca2102518b4518e40919ae5f7770be298c467de4663cccf5349ed38056ae429fe00d332447e12237394b8549fd8655b31db77bf72388e58369248e9682fd2b306178bb7bf4aa3bec18da1ec50f5004f6fc8a92f56b4b87ce71e6709a15bf5f1442ec7a0b55c70507d3ff42ce190eecb930a2191fe764ad8c3e1ed2118effa9d8806bb091b8557 +expected_result = pass +expected_shared_secret = 7fa8518febf294de03c48fd26404aa1736aee3eaf19d5a55311fc4d367d56447 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe331704aa56092a4204a2293e77935390cb1d2b2924e0bb27d4aa471474fed2b6982b71a1c14b2cd3ae12b12d5d12919235caeb8aa3827c844bda40f5f57e5f59c75c86b645224b3a861eb9d9773b01cbba45122bfb1e4a60ada0fc10f133c546563661064adbf4a89117657366789cfc282f9bbdd0547029c92aced02963f8cf462326db19bdc980149ee0823ecb1d9e22a5effc6cb588b17da70789d813b749be180457e82a5c958b069551748e12bae79cbc0dfb5ecccc85f565c22eea1836b52435b023959b4f4fc12956a09f38d58836891c4c2b0b4502b012b868fb9bc0455c12e83c182f1637c05469708279b1f4af2c275e174ca5ed0a12b39849f49535b8ca73089acd5067b6b57297327c4cdddc7d5c752a5d2cb04c659d04f803c72507f5832e7bd528e903863b932d80c51e8b2833684a084c7100728ca33a4304c85b8cf7b61412e76373566c34a75ca88004cab21a3274bca1ebcbf34222e351a3df4b557f09904173065b460d54210511f4515180b3bc0a87f9125a0a91252c11464dd98b98b790d85379e8434858571ed2261eda1ac35943b4361abf24b92af0723874601a9dc98a6c872801c54e55981024887f9dca26f6531952055f0ea90ffa859e6c39aafdb8621ba078dcb4884de4bbbb0b96ef167d5332c00cf79f93d30807a44e60e68dcab05e3167315f5b71bd2844017b417af2ce61e2a2d2713b7945cf20a39a0cbc92a07348cfbca566d04fa6983c3e37b2bac33627abaa656c873da54a46399ae61117086b7798259a11315dcf411eb7b4a32f375596485dcac61494978e3ce6626b8194211bb134aa82d3b28997d25637f4a9bcf828f7a17d04bc15eeaa809d582297da9f5afccdad46b71983a5f40763d709c2d7038abbca9dffc530ef293a78a43aa2979f53d3a4ff184d2aac5cfe7ac114d378c7a4a46212a3c56c7443d5b4ed309d7d356e169270196159ab428b6dfc5441004fbc019de1f5aa0aeab64c850d1e9acc000a9628d849bdfc7d8a4b29664b65a66aa4ece6a72ad5136a7ab61f8c85eaf798ad7752b1c5908f931699c35fe2c19a7eac2c73f512e4a368e221381281c6f3688965d55969309ccda49bc38a558b605e38bb593c2bae94cca262b37408fcab7cbc29dd0466b7e7ab4a6013bcc7a3d9b87045f7609285aaaea16ccd1cafefa5a22b33043d47ccc0b0c9a0487691f93f92ec0c9ac47756e3cc91b3331866afcab93966c2a1d1490238c79c61d757e5c383a691b2a241c6c19bbd5c99655c4c632d95b9368688ed9294a4865c602c70b40ab6b1cc6c6b039206bc560c302394e46c428a82979b2288b30bcb813e6c35c35565b67bfc1dc4804ec8462d54709a4ce181d46abfd6554afce4204eaacee5092828321e1d3132d7d0b4f2444136117ba1dc843b440e2b644ce6b5cd1cea7ba6fbb1adbb0a4d9417cccb68add346446172ac0232727a6fba3cb59c38057b2b8be26b56d974483d31019fb33d94449226608adbf1b1571c34f5f920565b4a791b78836aa50687ba6ba49b4e280bf037b6901770db351af99bafa9dc0cab14b406561c101478b4b20d4f765d70f072f1d6676c43a8ee432426f2238d37c11a280adb094458fa6ebd2269da310438503e15b22da42a7a24566881d3cfd41bcefb34cff01328a16a01459259e5406451d831f9430ef7e94d4022714c007de3fc0fd637c16cd14489f178f54aaa72529816f3158c601027dba98093712b54aca5d33954077e3b856e4588432c510342e5c99e90995fe7604524a3d066196dd63e98a3b325d2a8669013c9b10cfed68b24b0973f0c286e59605bc3c0d34094ea667b780288e323b334463dd31c7c64b10f6479430406d04b4756fa685aa30a61bac24ed5451a63ca3299606491644e76c765b8ec2dac478192a685210a4af4397f7646309d17b1c1543346ccb884c28418858a5fc9866dc46f5bec91f2a73c02a1585e620b7f9045ced60827f58123274649048477c70f4b57ab8e8189ee8560ce4b84b2d57eac13270f00cac1e0a11a394ab4fbb0fc8890af29111cb87905c09c3d3170806a80063258a6625a24b230c502460f5c44a6c27457e43412a7671cd24911b23f38013ea1d7771f6b4ce483803778be0e5c447b457900133f4fb882d2b9224f2997a532360e573fa626543e856f6b8760107110cfa28815e71b0b1430f02bb857005193875caf86693c1a0748d3a4d3469be2eca0db34b10f692ec1b12d84453fc067cdbdea8bf59a2b00b083a34a5e3061327263be41ab8012e8283f1b86238a077cd02c79845fb71744a0b2306c29a541d6bf2467a483a03324d87cfd00135f8a9bc3aa97ccd68d0fe98bd7bc260976344cd9af0e6c911f3589a09695064769f5b92ee1165ee7f10031d5811274075ed14069d391b09b3b0fb80280767fd04b47e755a1eb3cc3bc9084db2b79e5b506a4022662909c135083b5a12a59c6328f6ca9856b0befb52e84624af1d81b52068ffb80c58b837134f49990632354799ee166461a916b170a5ea397c319b0a492f566257a3672101038a88be2e4ac5781bb829423ca2429b8238150743dcd43025da8121298b8557c410993828c316265bac2f6c2b0e3340ca5dc4c01045c14731d7525158ca89e35e21121256d08b8ad6c850aaff8ae7b97cb1e8683befab96678b6c0c564b2d41d92d24460d75461c91b42b62112ae783c1d0000000000000000000000000000000000000000000000000000005a5da723bc2449073c0a117f8b3f083e4aec897237ff8f85dd3504f47a4cf42cd48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 182bc48cfb7ef59210e250816725e59be1f4175faec6003c718d88e5d802c96d95e024e9cae147f6cebb2fdf3a98b796a1cddbc680095fe1c4a3ee780b61dff0d5a208532a836a90c919b32e23ba0539fa28ad99c3200469258e444c55237ad4f25651ed888a9ba538c90a94f601d0db2a8e0ca91b655c7abf7a4c5e2578a6de7eeb68dc681dbfd4fb042c6c36dba421a81dfba5c2d8ed9649193905692db183a946dfb819ecfbbd94494c36331b1d65e6468c76b28e35af3b5fc6503b1a7407fef9c493d8f3b86ea00900c5928e857744ecae5d8b486f755b6ef655a1fed4261daf062b62352f88e8f41b4d3a656a5b8ce0b3c7d44ccf4f9e901c9a77b84240e6ac45d941cb2d9305e9e78ae39213e825381e2cab3abde4447b2742677fd271d0e53fb1b6eacb6eebc24cb44444a58488fb8e114f4a771e16e96c350518ac2eef03e1c116034e7a5f82dab805994b791af74c9af4e0e80cb1d543779ed0edd752294652869d83f43a26c9198b375b621d8ddb9897f9b2440505372aac898adcae00762e5d46f189903e1e3d21d5036a3eb74c1a833e377050dba79bc2fe909b1f4df99ee85265ba379b83ea67ee9b7386dab1ea2dbf2918c066fea055b7024f60e9e431619d2282cd207a06fe2d926f96f6d6d92906c71c5a9cd64451abb4e9d4eb4d02cd394740a0b6c3d43befd2c4edfa6539b1f7e165fcdfecb8e0a5e52744b050b5252df3fc3a39badff486164c1b238e315362bbc9de3e34d9e10f44931fcfb45c47d368d922c56695ae3bff0d809b620f28ae16916432f7627c2849ba943556fbac4bab79c8b939c12b78eba9ee62c256d378ee912b124f6f7c56be139b9a5b85f6b98aeec516d1086cbfe06dd54c4bb2910a28206554d312f907c7462f6791f07841d9bc88a96870719dd548197f3b92d22b8789656e41cdf629beab410d8a7a5c65453949256892392d9ea67730007cee5482f6beffbf49dfcbec6f76539474f34d9b803b759780dcea2ff8a307998ecaae255cb0bc464c4fc4a236d3989a82b6e86de2d1b9df441fef56524cba6cf996ccdbe18e7dc433a938fd0017a912c44177341a42cca0e2104094658b1a2822cb0d2bcddcf37770efd18e41c6d3c9eeefd57f7d350104b569cf270681f2656f8c561c901a17c5453ae0a8ee6bc7751d8ce737166d2978ee8f38c9ee07bc785dd59ca6956f850dac891e1ccb25989dd3d347a0194a1d44d8c8fe9418be7e0ee631a80798c2003bb4bd5bc76269fff164ccf95eeea8c0c2867bd5ed4838251768f910f9b58f21478509bec110926cb886ac03f6809de328311c7f66636b46fb04e2b54ba2b09cdd06c0b6ccf1f0d744f699f281e8aa1fbe90ea035924777adbfe3fd28d21935ac911be0c8de9e2393632d07f140ccccb46c4d625821b08f55335a95c2dffef96e1feb13091d257313eaae7d911e5e120f2192c29450e32a101738fb6a73104d9ec0a2f995b7b134f3f748efb82e012d63448bc417f54e3f354ebf584b26e4dbb85c75b28fd9ae25885170ad64113e8d5b47d54767ca184d579edd0b0bb30bfcd5d1e44838df5431235079163075ecbf30ba6d5ccb737e732aa16624abcb42f1c63f91862471c3d8a14697ab74a28b4d1c7a7426732e7d323c2518d82968d7237c76493fd3dd169614a756f7f931f29bdc89055688c142cd71dff82a33f4494e36a64fdfb377613c92d58644c5828997849e19ca5de4dfbfa1ad860644c60d794f0cacd1d8b059d9a126d56b41ac2f03d8c0cbdfe04573481b5d7cff7ce84d757b3544ac5162c600808a331fa671629a6d140c49f4685727f087202a8ca5186d2315d47270cd61ed96ef6eae844194dbd3eae320aee0338beb0d163fb668b22451b3d5a8fb2b4c961a9615a6b1bae6d257bc5baf216022f6d2bce09adf8001c9f8e9c9eaab2d9c5af0e81dab1ca14199646e854bc7b33419490b91c01914705f5b4d094f1b71c8557958f01430040eaf2e06f427135e439f780ce8184e64b339537ec933c8a896716738a0986491771d4d4e6e98d4d33e2633ef2b9dc3c0fd83dbdc48a2c8aa53c70aab81bfb13c0cf11f1d5adc9aee2b1301b6e3a7e644deefc7f1ca260bd26abe04797f7b87f32b792a68db6d7136ab6c4a29207ffbab0aceadf8dafb1c7cd28a484049e91bb900d01a10db39398f6943969f82c82788ee1568ab6adb1c6e2 +expected_result = pass +expected_shared_secret = cd7069783053ed075b29b8bb8f86ba6e723df5d0a8e813c585874f5b39ca2d0a + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960116a338d74bbaeac359ab3728e268abf75a8d30b118141bbc56670dc0c5b2d05c9c2f03952338170754e20287c99177c66b810f009002c244f213891c5b980aaa23d15f413d4a80160d24e692c450b68c8c43ac60256ad748ab6aa85aeac5c623d199928f88b04ac7bad2c1249c18fe1b867a02a353a112ef71368eee3210f7082f8b216c975070e9a1a27dc265698bfe4849611716d0fa1b1f9047e8b0905d184b1fdd863377353fae732a5d0388c3c6606a773360734c9ba915d49aa7d358263d7abce563afaf382976b2ca2e1328d4aacdfd78851eb143a1b81c21713442421bb1abf77ba25d4355dd10602ce06754dd9a77aca0e25b1260e994d0fe1b83088a5d385251ad5c6a54c45d93a7d1b25cfddc1612b8b30e753814b505524a5b0b26747645c9b636543ac7a871b6a7cd3865f1d8636cb5210ae9157b567b2ebd17fe3f59b73379d086348c9806848ac3ccc1547e8964f6a1c4b532787dc8620050b7e628274683b79e133969ae154da157bbbab159941484cda4108c84aeef56a453578e606159c2c0c8d25857a72912297b678d44e0b328bf0d05a1b096d302c6edf39934ea185d1577207264f0ad6c098f6ae59759ad045726a03c0735080c6b1a7f39ba84c27b41ae555f3e93133620c81674a8d9b29501b8bc19ba9fbd375875843524194858a88a57ba69f719c11b534b5055ac821216d2a54be9771fae1bba5448e39a1c6ab667ea0fa6df038a1843675aa5ab1ea132f797490c3da86b0d58474db11417645e4cc68d0294839513b36db91bf3ab32b2aba77655c407240226bc0baecba66c40dc24469ee617f06f739d7d2249a5802f69285053c74c98cbfc134706e535a34fa03f0a697d3db3e3d2240958ca40ea9545369bed2d44e75592154967b71956d35031b8b425972544b63b8bec1743608c2ae16444eace5395689a02d0999b189065342166984a1799bbc00b7b1cfc33bc210433fe86464093d69b83e095b74d46b8786e71732c6088b4753933b77d40c32570879525b20b2b006febb8d0195a6eac5aa310a38b2fb1506d0bac2857e65ea29a210bdd3ca526d59a259f7cc6ac20c078aaefc8537a69516a8081a0e6313288cca716869ec4a47b7b1afa40a59f9f1b79a2307582a2537330dcaa4167cd848bd51725ef478fe98c6ab616f71a43f24f323f536c6fcf67fbd517ed2d61efa9acc8b9966d25848cb416df944a7f8f900c395884062ce1553518abb314b446a85a0a58f78b8d9a8cb7f027ec87470e9fa05cecc07328a6fd03b8960582e47e97272960802013be71974e83573a0fcce793160949826f376492e3c4bbc376f60ab1362273a918bca4fa64c13c290af3c59e7b0279f410a14d5b1d53c1123dc1e6515619da1405844b5047831e4e0c2c0eb890ed5660d7b98f01019cc98c513ba29ff89101479bec1f37e81f84b23d907728665dbe96f4c2469105c3f3261cc4972b030c58746258eb14494b39381c8c022b4010f6758a0ae85c10776ca67c8225ea9006d8798cc90ceecea408d896ba957291166a189619447ba3940379308fc303900a409b333c9c5cc54a8829a4b36241ca9bf319c2442093c1c22dc111b64e783511c7b38e7481977a56f5baf2ee28e15fc5f46a0a83a26b3edcabbd8602938b2c320f0a384228f1d1c86c0a41c2d238af906c79c5ba65e66a2e76626ff50bf3acbc24b5891e0f4370d764b6c503997b98c9c4656ef1c6ccc89a6794b5913d829e87194088b183bc64eb55c85342a3d12a08c0518a69b4c711348291df114c8da5adac6661197373aebb3ed6b8f9940a127527f43b0857d9c4888082802acb374824791d9c3684c2fa05cc965b9481f1cb1956b4cf3c84fd92083f371835c087371ab840d90b93bb3a0dee11307c66a22c6c18d86a3ffe89434d5322cb17666454482f06d608a8a0f1509562435b10bc3432331891c6c759b4a8517247bd8ae4f950f09638dc5206e39db7528e63d15cbb7484c2f68183dfb234cb393b193e134a470adda3a497d6049b4d712edb380b278b79a065f0bac8ceb654c0607a387a689713a5553755b6121012b614910543bad77c21ad8770cf78ac789c6124369a5766a65e89a8921520febb92fb85e561140a4eaabdaf4809052434ea4a9f5298c3eb4c8a7a98c4c5811b4519402c55102f6973cd13e503ba847874c76754ed8cb92b1ab398661367a3b21f2d0ba969347821cae1f475567700c8a0b911d45b3ee10cccd2544990a6a29d0140685a1de7696abfba58f1577cd84713dd947b9d14d83901c19436dee843021e75951e6474146b355422a80d6a67e4c4ad1fca2d8e607e28032a7d0ba4ef916989a47059922be992381691e0580b5b5192a210acf95285a9f156d14fb3ba7b8090a6946b2345123477e96c373814b26f12b40f0b302cac522f3c07763b82b53d36abf2c74dd29b8edf0c9bb5c749af9ad86542ae6c555930a7a95d31e9bd13ff6971ef6a62cedb4779dd008ff5b165d4b4c4e10ce512932ef890bbd5331f445ac68d045babc39f1f528d73210d0f526fd575af6e80945c92f95448972dab108089931e99958f28ac08567cad714a4c737e8a37629d64deb5c8dd8b313d10a662906bb8e958a60a7427cf2b0c226452463c1cb716bcd9b93d0ca0f3e2a12c5389e38983d11e7534d77525fc6aa32e4a91d552e3cc5049ee74ff2bb98ba8b60c134000000000000000000000000000000000000000000000000000000ee98b001ce87113fbd028ed9f6c1bb51a7fe0f6273a1159702261ce2cfdfb5b3a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = f47ebf9c54267c3ca90048612dfd843904470288652f4177601e6db651ac45682f0885eca62d9c71a2526068d57bb05d65188f5265c5d8c6ea66eae04070de6be319e67e08ebd76c77261c7d6a684711166b62198a4b7f2cb77f5646af2f0bc24212b2c6155b1181b75d449930b97c7fa700f151e7f679b75692d4da04a47864b307ec54b1288550f4759b25a34df63dd1c8db38b9374c6a9964abd7e143df3083832e0ee46521a715c2f5c7770904715feed7c927eb1e424f5a27984be052d36bde159795e0f5c909c7f7f5fc5f71e4fcd09c1a24e377af273fb9f469c7374e769d49a71ee13faeed93253fd3346e0b695741870b8bfe1046572f9a64bf52dc535a2ef548f932c8cf574e456705bab088768336e5422c6827d18fa0aca54de0b788876c48010249db3e874b448032390f384fb67af94653bd1fcb64655cf467545c2939ad167e37951a39200ac7270c6d7101930c05d417e7407e8003cf428f8e0f4a516fddae3ad998843f73d96d97fa84d37829c0072b75f2ea0c61472a23cf99928511ac3ee0031c61af06b9849541c3e87fd7b11bb1fe7afd49e0a07f01e721dc975ba4440262b96c90f5f4a12fc2e2d0ca6b7969c24a81cbc8d87e3086339959c7af99b690240740709bbc09e41f318c977c5a9431a977decc1cc2808b529d40d8a823f8d2428da165dc21026b73dd9e60f48d1900807ffde3b903b667ed20f71e71790d2de970a13913c69d2dc72041152f44be8c78735ab1c7cc473bd598d7e0a671105e5e26da1492bf0031d7051698d46f36c3b389048bb9147518efb3bd57e85ff5fdb2b606c1504d15eab114fb7c144b35c60d5874b3a6adbe1193f38113fbb78416ad9ea7e896ae57b41881b91e54552e3e7d17891759802e0f49307880eb3dea4657059bb144929d484b6a573ef854b466225a3b7e33f09b4a7bcc04c7ed3bd8efc704812cdf33e450b1a497f99d6c5b7267f0ba5cb250d0e62cfe4d18ee03a11132c222877f3d3dc4a12d89b9bb805bf66629a2c14fde7c7baae60e7634a61e9207dd9ae6ed80da7869ab911e0c8e3ab90e3135de34f548a12ba5a20faec23212ec4014ab1b624f516cf95b1fe42aa33e136a524d8e1955ea964a738bc3d7fb66d92e3926653587f69d421657c1765707ab8e67ec50ba954907d03dd1a5ec5c5a78f044c9393b028417e2919664003a96c7ddf2aa997b5ef1e1f3d9f333380ccad84df867c22eaa6fc2fa3defe362cbd6d068166935c67d6b498c853fec2ec699203f0c1b5ac93d4e1369d8b9776fd86d8de47d8cb813538d613742c6de64e854b9230e427f0a2982d69563bbf7237c9a88b06e67a73baedafd7f7043c9ac7bf3b2d3ff2f9961d62fc0d6a0196ad15b0cbc2f34b1cfcb1b77164a8f8fae684bca6507a1cec731820c920bab97327908736fd552ccfe0f1d075cf15b58970cc41e9f86f28702f4bff59b88f2e478ce69a2f8746673e25cc38971713d018f7b4dde544b05d02921a6ea43ec5992bc3e9b2585cceebfa3adf5503f0d8c2b63de7230221f0e53d61dea4f9e153e3e2db14498a5be638b3177c14d4bd9ae54ddf24aeca14bf1a5a146ee880e181cc8eae9e61e514905fb80f5fa812ffde64918727f2c00541f7ad40d8f2bd2e58b28e1bc21f075eb185af9186a4875f99738a095066f5d2c3b13dceb5935c48b1946d7c45536a122ac99638262eec4cb395cacd6458f6a2970fe400df59d890a3b7dc63cdac7a8f74e4546354c830d45e18f1acc03da15f01dde2bf31669e8d4479921196c826338c18afbb553bf5ef3ad5492dc7e0d4530590a5a09a17629d50dcc941b6a31df1aca559ff490a197e912cd01a4e6385e25513237ae611328b07ffacf6760be6465a00cde8cb8ed630b27cf36cecafe59e9a32c68d28dcb853d346ce4ae872b97abdf85ad6aaf05694eec608cd38799f9106d0f48fea705c0abbf8421418d4a511230c73340461f3a0de4f69b141d00569f61403303542da36953c26def5b2b322e70a101d5fb53aa9b9ff1a940056212e30eac32d3b7cc161ff70e74c0c4a73bf2cc722cfb9c30fd1c90276a8383dd2fc625e1c8d728e16306019ab61066f25ebb9bcbda68322fcbece63328501581e71fc71b7e31e0b57d2c4280100838c439e48d6358c370a9ca5301953d9b4d00e806ee3a4d0fbdbbc0da4ad72833aed64390e03a818bc307 +expected_result = pass +expected_shared_secret = 19a85075ee44b34ff0b11d12655036af401478f0e66d354ec9d17a6c197a69c3 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3969fec41d1311ed2545f5281a09df223bc4918e55551ec060dbfeb41c777c79acb7375215002d9afa37b5a126625f7445c3fb51233650037e070648c924586bf7013c203e907332901ff722c35c1991acb2da41cacad4b709ee242a9e71eeb0ca1d05595fcea8d175553ce689ba595b8f98707a68a4d20f8a1fca8c34c3482e88c8b043a9d42e4a9e55a6cdd867e106b271031355bdc71c85c80713c0ef7c3ba3bbb9ad4e32615a2b104e52dc5e7481e258351385f9c8932a074529e327e6c0949756b57ef47094e184517819d459bbe35ac6154a70d004490b03803e58c9bbcdcbcd8451c2b0373656373be77a59beb2d47410d8a8631745653a02956dd0a0fe99ca87d78c273230667f25bddf3a65a216921a12844b8c98c197026e14638a97fa5144b44189621f00c75857fca20342a09ac44a4aa6c336d9ae58a15972f22555139e2b3e00ac0bf67b15d64ca8ae77a79b44e5b47a72ea06930aa9695b96987aa0dfbe63d83a352c9370247f6b21f225e096480b17333009bb7858246413061f4c42b57b1625ba25249b9697b09985dcb92d155c4a7db3b2e77464ef901af38b930e0b5fb67cd7a4cad52ab9297b383dbfb7e7cb32bf674b24f92c6f13ba50afb2164173282031b584828f8fc835a094bb4631193258f8bb1aea8949a7cb4abd1279ae3373ac36108eb290b1bbb205bf81f907873de0466179787394a48c72bc100192d8a0a46f76aa35a2c4ba8430ff976caa5d2888b7bc054bc07ec8a0374a5276dc01c34918b37795369b66493ac0e3c1362a4f3217d240ad438b7472172474a377b715eb0702e3b1652c3e35873904ee3b139896245c0a05133e873b5183d5ce54b758075478874cbcb00aec3a5f82c03f6ca9783ba3f7a6a1c05a41b0fd30f24f8c47309950282b7aa9ca84dfa20c8a9c5b9b3665ea59b2bf035159a20eab110a862c4112cb697c923311387b99a15066c569c300772eb44eed03e25903e88a84cc5f3b6b982086563a36f21b3f9c434f3200b0b9b5852a2aa75eb54426049c264b73891a28d9412b9c3bc5b87cdfa6b07242a4c1aba32b229b374071d4aa33580b52dc09093d9c40d95801246561cc70136c389ae1667bb0ff600fb82321c509121694c4298c67b36a21264201ea1c97aaa757e5c975195067416964a3a250151337bd489a4e943c03bce82a7b447b134f25940b345166c5b498b6431c159c829434067562f7a331b051854b32b7000c42a122974beccb36016459c61a97517c80c763964c64f6f72cfe69bb2c87c63bf610dce640702e99affc20d1ce934cf1c70683090367673c7422e57389394e7c2aecc13b23733076c6a50631c69106792492a6dfcbc7963998d219f5be767b180568b76658573410ed41796a9affdbcb5a9991ae48572f1d2a78da29a6eb85cbc50329e24c56b41a4b9b313a85abdab851886fb45f643b6774c7792b89dabca1d54b1c728b38dbba6887b028d51715e131cac8ca22eded549b54c39733309efdc2b5a5b3e45968afd13392c29a519328c57e259e7aab48d730175d61479b044fa019cf86681ffb7a43770c7b3e22efe3aa45c61246c368e920b8183b7446475c32f739ae4774c4430c5265a3aae3104629c31218c7b424c3ca25a4e9bc8cb5067a38ea4cd6f704c5cf895bb676489e8995d15954422495e82caf1484fa64264173c5bbe8138b6132cf45b8f6c1b2a99d42fadf494f90730ca9286fc9aab08f3b006622a9837149f30275bcca354136d876a728634c6ccf48be4034bb937bce815b291d9236da83700b494082900d435151ca37258d39c816704f8bc1373aa2f6f1a916e21c983fc590473072ea0039630b016b963fb8bc95f21959538854e9c5fad4212d80ab30eca4661d1aa6184a8d7a872ca6682a85773c6ea9006a64ba1b44205facee36c93b962cd01d700ac7a088c7c43fcf8bd07d413a0022fb43883f9351ac675508cd89c50f06eeda01830c42a864515fc88c9693026e785ba2a163dbc819541a61d98a64e95e62937795290440769c1049592499ea0726c18b943040fc9d533ed38655d05264cb0531d23bec531c6726c9dcc132e34704752ba240b4c4ee506bc15150932c9038e164aa22925152c52cd59ad3c68bf6ac9789c01b7a87b8a5314354f36038a3b2bde93cb73b596f830bf84f024458641504cc450d510791c43b9db3ce60127f081c8d7f61840eb75522590ef57391c3a4189771ac293770aeac4ea031707d6c38a2334d44817db05cfa54aaa5540c3334291145970903160f85cb814905b493bb995ab3ac79bb62e3cbda3d4a0cd388517547cb3b5a6c2ba9ca5646473dba10104a2bac7b4a8f79cede97d48a94d0080ad5782819d8c4b19f8860b711285ab3082784420863487863e182a09d30c8dd8198a8876829f1c336e583d27e4a06b091c4627022da33f06a201cdf43120e1a6b396bf26324d32c73cdf531488650b3b899c1ada8bccaac08c3c6617649233501839628e53c1ac7ae51ec19b1468039ae88140feacc9027c5f9370985a0932422c0b24b849be7a9bc497cbd3d317f48c50009a676161901494a52045afe3b6c516b18d31aabcfb27b2024505f758c91f441b8139889bc6ae3440208f34508df8a25bb4b3fed3929da0572a5a804b086ceb74020894b534bccbdf485fa769aac8e9577e477caed5b029c86b4682a7e74cba8c930ff80d00000000000000000000000000000000000000000000000000000049805cf685e4bb4bff7412194d13b4e36665e21e561c596fb7b7c099dd9d978e53f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 6d12517b654513bfc072c7567a03257db9f6b093bb84737dd5cb2861952e1936bc84892a5b7c5f70c5349b4af1ab9e8b65a2107232f26100b4ed9fa413bf04bd9cf7598763fa3c40b7a2b2593a4bd51167a64d6228dc5bd20d0cd431cdccba3dd5b97a56b12b422f666fb817c1a5fdf9d1fdf8d69640826aa94ad87bccaf8bbe4f1772efa2604d14006b45836addb7f2935697c445b4fa69452e74290115a623e8758803000e0f4261ec8d3a68f4e82df31c8da1a59d74aa956a4227ef6b59b430345e4aabd96fb0c336b9be15ec550cd964bc15f2de060b2144648d71e7ceec4881bffab6540591f3837f935b4ab48c3241c95edbe3b7be6de17f62b6a141048b6663d6316ed3c1e8320f3ec5b818eb890985225a33eecae76a813f08b9deed452d34546b8f806f8ea57e6315ed7e305c420d037c2fd2359022a92dd3b0645e00551207f578158f2d853f41f09680fb226b08344af892ae470b1f281b58b2129b302f2da1b8292bc851b0f274365ac410ee178594fca317d55df1a63491b92d8d1c5be3b2814c40ce082702b9f6a6e6eb9807325aac5ad656523e69732feed01e4a085372b72c604a201730f785059709a6be4589f8e523d254abf8004bdb615d6b45dae3e7609b94be0878532e1dc124e92b24b677276c66d62fa6f097a3a3ba029c56cd7b3af092abc02ae18ace1109e47beaf478a84f34ac8bec69e67f71e9e8713b2e04460de25503c8355f26bbd9a84e8f136c15e93d17c8da50e0ef1f529283a574f81de5ec885b3e114f4b26a5ce46c6d94540981c8e8c38fa5d6a2dc1a78d4655a255a915903e88bee5f30bbe9e730d9d47084500cfc4a5cf5979696508cbb3a20ad11870b0871ba7c579846e67c5d504edb07bb742f58684c7af5b247c5b1459fcf04fbd3f1b2f7caf32a73325244d1febc8bb93488e73679e1171208597d50bff5f2a0b1b0e38004f93facc8daef9865d35a779ed93f4e9e65413733b01e2c4aa7f649ad4774a92422b47b1610fc003fb25b62ccae811e8bdd91fbc65c1b2505a8226ee96e275ac3de93bf8539ab14ebb5f3eaa536a96ef7042a4158af84c80e7b5f161172ad08438fe518d32411c9e9fb2213515617f418477ea1b69d767ebfbbd99fc7ff164da7a43f0f1804f7e928531283445ea517a9e1e715bda558807d2df4a636dc5a0cc59353a33b4179a0c431802b11f676d46fb3a7700b08558c409ae96af58ada7af081d42d6d0db42371baf3d12078f61b88bd09cb9e37f51e512d8ed1f44eed6113600f705f7514f5d14a91b1089d7b441ff4166f728ebd4072bc77530bb85ae0c6b0233d47f9d474466d7b5d852c20f6c5ff936efb6842fd94a4618ed11086ad6ca4dbf9bd6eabff8c230421c486a3c68b440f2e9a28c580cd438ab8da399f8ec2e7e0a38aa95ba39acc9ca8bc928479779c0165cbcbe292690015ae10db2edb418fbb148925eab905a3093bef13fefdb1774bdcfa7b907caa321a5b9fd149240a0ceff340ad906fe103f6bb111eaa53761cdd971dd61d463ae503e96df8c457e71065a86ea58fc345d73646f5c9261701a7264f119c29faa19322af0097a3f889cd40f0eb7884c2b2716342634a640f6c6388a68822cf38d93f159f67048baa8cfbcf5ab5f8b45d8786206a7ba497fc935d2be5644fe5d90e551fae7ae2bc0f237dd03352f511f61bf873b33d4974e1936260536ca88e0dfed5bb80700b3300f781439530b4569084297e38deb96976b66922a11fe56e5a14a5bb01654f485e1f87bd204433dd15871e7b9f4ebce48775e117f29cdab877d65d601c2657b407c26b33778491ebe4944056efc8bf547fa7bf534b56c363d4a165210feea4888078320636e50b08c46168953db0caec119f38188666dff40c056b1f70b4cd956ee8db8309c406563ac9d4353b36f51ebd760670250c556d9f0f2556aa153c0b8416b26fd723429ab0357e32725b2ef106b3bda98afba709692ba91a2ae2708d9d67a79cf615f8304cb4301e8120ea00f1372e429d873b0c7161beadf87fc12f06269784aecc7f6545345753a5a55799269c9276125633252501f0d313ca9f8e06e4e2777e6ef21e78efc716992ecd979fd3ba00b4c3115b194f3b84f515fbb0b4f31b279f3e776273715c05aa9adbed7e12b6f2522a397cc6acc96b25dc115835ee824a22a21319fdc4514f87b4c5d48bc7e83c2 +expected_result = pass +expected_shared_secret = feaca519e19182ed57d07e8661103ba82976d8a079ae871951bc678c73a81379 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d74933a0cba383545cf629d357aa8927a7bd4f6575059485fd455be7198fc01a509920f6c0b8c5a565b4b86c084a60bd9b9b6037727df67b83ae06c5e47aba5d263ce83808f40a378aa43b4ec5458b33a0eac8c816abf5bf76a1220a99205258cc4a9236b4dc252cbbe8884e8ebc1fe921ed408582182b273a199d121153ec38b7f183174754f66332ca98b87a31672720815ff7bcd0cdac810db905ea76e6496742d26b2989b201fbc2936f5a6cd60c35e757f8c33b75277560ab948bab2962df9c38c91b44f08090e5585d852c4b729c52de88fd8c54722162f2d7696946c7b710079500136a28b9abf9a5c0294a5b265865cb04f9796b648f85858f8982f15c2bf31626b236b2c3a6493910be2cc8610829d96693cce3686b8a63b91439118fa661729462ce58e5e28b764aa39911569d1ca5c1b33885400a16f169858930c7f135ab6a95d08ccc70d057f9e73a4c8ca2da7185df37c8a6f727893bb6db74329cccc4692589128867cbaf28694fa747e86cf98619e99b221db88a81afa73b348586f87a12c4aa441f688b2c0cd16a89e315b3553a16179db0e01d01e19bc1574c75a13987b2600ba2ca68cba5c1d0ea69ac5fcae7862ab218b1a94b22030b40f0b3b16bee7c6d6e58700e150d7217bd7721afa7702023786f365a43a60226068c5ef3323c8f85488e77c106a243e96ba538264749539f5874d55929b72a695ebc3366589b04880721180258eaa095a950ea13319c0302245d86219b79a1dc61caa658fff790f99d2c3f25c11eb34aef2e66234e2116274ce54e5ae335260fe3ca3e0673128d064a39c82a3a9ce3be0a2c501aaa53175478b847f9cb17ceba19e120144534dc1a9b38afc864913a8dad5a7ba6bc9ada898c60b63deac87092275685820131001911b98af683248b50f1e2650bd299c9628678ae542e3e7a526620d1f78aaff445ba75b47d0ea0af4a3a3e7447851377f40c248053a88f5706dc119712a5001b8f035436c7d9eb1269b845156e60c5a714026cb330eda7f4ff1980fca10f5b87666d5600f468b11d81140b27498a10715147167fba6c8c58680824b21e97bc982b61aa43f2dc4866641b9bf6200e7a8afc3c1b3c70226e2a320c603797330c952050c90508a4b36580fb5c83e7c9be912891e7849db960f83b134543a3ea1c40d7f0029118a855a926f8b6a2777172ad5452fd0a38753a94bf3f6023fd631c3e9a49be1194df4c7fee149698a2cd7b54c5fb33b306ca72b6b7b4280cc5db4c452bb8abe365a3d16c5c02122be27bff2f1623294bb6217c201714e9868b991229df1569d7dbc9ad957379bd58a41c990fde349d50a3a2102637b18be9f4b10cfec0fd3fa2cf4868bac98a268891d9bb208f489c1163a16c4d68a13156ff31a0129839a6ba4436ff735ad69161d551cd0933a25728360a7668f166516a69ace60b8283878cb22394fe8beaf153632999d60554725c041f5b089dc205d4a3759a7044caa82c78bf50d63fb3d72172622f71c31fa66460882a603d02b798470b24409b019a6f4b85f571c5122b872997aa4c389fea1195ac349014660e619888a50142ebb173f95011a716f1b031a7b860d1986a3c43a65bf5654dc8376d2dbc8d25ab90d139a18167fb73b758331ca69274a2d340e59bb6091975407b4039bfa9e2a4480ddfbbc8b26c0d1457f39a38f1b8626186c469b48007fe0cd2472a3b4369d425518988741507912bdb12901fc19c49932cb1b1558862291a63ad878cb6afc2dd57a1593e80e720a0766a031cea2528daa3fa866543fb5a2ed8a1c111593db955c36143ea38a43d73024de9446ca2c69923ba88d2c5b4444cdd94a3c380156dbb0346a02271237cc488c89d050035db74022c7c924921abfd86f71646221ea2c61b123224a1b34fc5f02c6849678313fd86a7da11f3ee681ae5560ad42cb3a86bfaae100478b0677d23dacdc9005b17af54515863159f6072937ac882212cdb3e82f3f811737b81928b605a6142a9195211fb73142c96e2cd309b22a8191166e33d39dc5a26148179521a4ce69d4c55988966ee2b278bc2564c62007e75da8b1ae169595a9dc58dbf47da2e0c192a915a59765abc62e375588d8ea3b72850bd0c584614305218c729628a663399dcbca2d30fcbb6e99921f5c22d1e06f6dd99442a27c1342afdd2705041acf8df78bc4e835d8e400cb6419c52148f676354421c5e7268c84501fe82b851bd87bae738ef5c67032c746356010ac03caec13b212060890a38ebd28285c990021a76cf3a417d538167b782b65a56cefcc2ec6015ddfa7ad8f2876a9b3bc0d9649827abc33d7ab21d5b20e4a84577311ac7b381741c8238955e630795c7a3072d23dccf4ac689a781fd783fea7592d0a629449b44142b56f440ed00b19bbb976234439da01238640890353b8e14b7a0d964819101110da435c9b68e73b033c78b1efeb9d44e27acb225fa1e07bb56299d54a779cd5379b7c02fad52f3c1a2cefea9636d850c6e05ddc14b4bea669505a94fff87acb2ba0321541b2d78d2c58abe48b62d4d828c8ac0f881baadec1bb30d347772729a73390bdb85f0e1c9b93123f7e44a541740c5d0598015c1433c96eaf97b5e0d39c27e60b9ba6cbcf8a2dbbab8259e44d006da65869c75b711939cb38a3ea83dd3c8ae97b4e272a07403c40d127956e969f8ff3bedeeb23c406a20e73a2d589000000000000000000000000000000000000000000000000000000948eff25ea7ec304cb65bf7722f1f355eb12e712dc8469da9b8df5df12e0da9be366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = 16160deb06f8324dca1eb3093b3fc501dad316edb4d5f8b2ec591eff7b65a048b3333532ebd3d961e363157ebbcac231aead8e255abb462fba12955310c6c925b530ad2f4a761d2efa5a3b9a8aaf1929d3630a6244e9ee1ff5839198fc9b4ef47e450d4026b5044120c13eeba48e8fd9fcbb02523814c44874ad950a83bfc21b1ec778c1d5b5efa0f2a9e028b13622fc0c2c08d7acfdc45788e0805aaff92b51532139416982f0fc9931f3fb12ebcda2f72bd9048621208a4a91d42b56f7d810e89bf6e4e7d5171c82f09402d2906b692bdae3088df4b686b9c1925143e07212e13f4a3732f84bdde9074ebf3a549f0d90aa152671d88d88af39364d33e8e14cd0c71e979c045002c3c40f897bbff857f1dd82141c719ac5cdcbc944f6d38978e8f39ab0ea2dd9e8d19e6cc95e0bfab01f8bb1f8330e6241c3a937c70c40280cff3bb6a34b5b247fa970e50361447bc5b163143091f766387d15033cbaf8b9cd208a2548f42f00dee7ab81838ec03aff5d4ac446a55100934866163e3f53931e1f4b86ddc021f39f2305f59c95d336bd070d089526af38416e61cc73f94baefadc73794da7a7c9eb06b1cacef4b37626ef7d1dd381952ef67d8a2959021ca85f4f904f912187294acce58fe364f57e113e1bb4cbfd2913095ba6039677046645cf84e4069bf5f4c0996539eb1d036cd4c8f8e1c2c8e0d775f11d0eab393d9474220186fc3459db73bb864716418cbb90f55abbf9ac57096f566702bdfc668314d98ba91677bf74d91547c7b5302c725b890b4f3f2a8b95f65521a9199a4bb429b31e7537733dee03f7f2f135dfe88e38d1c301ed65a3d5788dd593531c639eecd3b947dc557253b993321d76a61ad4ea37ef2bc43b5d410c7837aa3b706a28051d3c1ade2216cfcd719ceb9ea9aab4d373d535a13da4c9c27c5612b38badaf16ae3a584cb7c057f1c2f4a24a477cfa4a1d834b3ea4f9254ac3f89223bb1c8b9eb514460028ac47b0b38d0b4dec9aa4c2b4ab16e66780ae8589860006ad4ab72bd42cbe4275942f8476928046134b89922b39e3e527dc48f7f5433620dae3ac140747053789149cc1434053923ace9f5205dd3d1d7057dff6b316535fdf508bb91b4eec6503db29bebfef73302300822fc4ec4e39f5a5813bed54837468c739e43a421b2d6478f12ea5a5f37e26bbfdd57ccb11900bbc3054687edfe96f88b59af5856e87e90e594b5555c03add6fdc0b62ff3c48577b3a9ac720a3bba2d10958d79651c3d5e7db9bd701e072a25799197e615f4f4258b7c0cc7982b8ea89033304a0c2c23eaa24d26b56f84d82b139f990698906209ef8df440144941b435c891f6a2ea0276df6f9e9fd36ba636284574d49eae6c09e82e4c0a147bbdb2a636392bb1671862f8c8ffc0929e4f59da3dc02d7461777ba48acbd062c933e1a61857124bed102865fb4a8bcda191894ce19953aa6f922a351702c570cca0e6d95cc4757ca61fc76507b82481ab538f418ad6b225abafb0fb824d0b8f1baa9597e5e095d5deb5a70d7390e1ec308e2e3a15a62ce03a73ee6a827e50d68b173a7e1ca2133c26f2a0b922b06c72383410b75c8911203a7c00a2920ea891c0940d33939e0d5098b42cc31d6bb6c0dd8c03e8aa2465aa01597ceb533acb3059763273ec053c5fe1b72f9db066a1a5fe216004b1d8577849b6d5cac89101ec453bbfd8d571fc08087d0353c0413b02fb8956522fa871db4f4d734e0677339cac50199d070d8f592b66503be23ff44104d5e02ea81f17234cdf33db122b5f5540432610b4700ddc6183d4528288d692f119bfaa81a33e89ecef970b514355bfb0f4bee9800c8227217db2514ba6396106bf603296b17b3b5e9c6512694de41c99c1959398800fd9f0c0cd0975a2df0c477b45d2f433fa28ff3c7bcc6c543428490e9c2f6169edf583775595f265f969dc11d5f1679a8cdda1738e64e2d250dc8b769b08742002f22106d7f752cdfb1af97e4236cf11589f82816b065ca8d1b159f49c9ea06a7b5153cffc0d703a94ed67dd58859311b72b4f032ab50d4b10556ab415c8a6b2bdffe62deb01c654af6f8c1f29a4b91d9cb1c6663485965c0acad445cade15282833c0ba20e821fc443945eb783d4d22b0283522e59ac6b8fce4b00f5a7837bb7943417288442c286f2c869f99cf41c9b91e70307d2424b4b831f0cb78729c7 +expected_result = pass +expected_shared_secret = a2b9e1dc08b711d8744a6533f3c9ad42097526e8e7bdd375b95ada3e20af11d9 + +comment = Rho leads to matrix containing zeroes +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca62e0b7d8cc8d1d861dd052bd9bb622cd8b769551c2307c82aedc92accc3d2c67c3ecf8341290af6c93a295fc027895809a081aaaf3cd0131174c8605c7fc29ece47036866f7fc326f7c947f70852356410e22700b5480897f288dba24c494685ecfbb624bc189dca10d9307595969145b21ef4ca1c435b3d39555434e133f8ec8c00dc49f02788041a6deae40ad5c9a3198804fde6230dc25b7f86a86bc00b43da73b5b40e3943096fa4540a019817881b4421961e293250056300e273f3d87153765ec237a79a16ba89a960fe42aa887c65fae65719766c44b2b8a0e54e97aab5febb1c194939e11928258cbcad6281cd37ad6033b1c9982df721200e36cb70326403422519f3afc3451af15969c2b26957c452fb136db18357516617892214c758cd9b556a827434c9510a5f6094bd32c8633966eb113f9e4902b6306c87732b96542979159ab49a170fe71a23093c1aca70202287d8288fc2f56072ec7aefa293015b6a58a2899ed79d4a09701ba42d26c599d8a2164204563fb90ff7372ea1626b61157361758af813446a455edf8346004c8f1d8882c6833b7d6bcbd86abe3e448006f0598a288c813790256b0c5f0332e06ba2f7f61fa405752f509550f86a18bb5483800a7329486f310228e9b467353957291eefc5ba630715ca177ec73602b1cbaa4956b37f1c6cc8714702b882686bbb8d1a19bffabf06068f72563437d37b33b38c476366404a4a6d17232e437c7bd4b56656b80eb7180e29613dbb4dc4b45f9d6909b07bc479126a4ed1b60d276962c060f725406a6641a29c7b87d17e29209c5473a595f93f6f0b6c4473afe95b2d0cf13710b12e4cc094f71b8f6c3cada16370fa4037cf721d56f1c5efdbaf1c395fa77175abe6c9fdf3a1a0b88f608580c1024dc319cea9836cb3f70e0d7101117a3d8e8841a92990d30cae17b676287795dd9c0a451450b7b75017881a210175af8a6ed69900070192df3195d27756c303bc82bb93a19bb805820177a07c75c5c1c04a8e61566ae62a357d6016e313181a260d678cb646a3cac063caac952ad4830deaa1b2bc4161b7c23c31356442e2c851ba64f1e99abdaa55b3b9a2fab0c172a3b9b26918c0f6933ab74fafc700255a59f3871628d291ff56b8f9241587f5a8681aae851b73b0a26363f2263035a271e883c5fc8bcc653c910924c202b103b4131325273e6246579939dfca8c6e78bc47e686841b629c93cd7dd16339d5b40cd8b34a289de9394c40d63409cc97b87860ce54c647929d2fc84850443a42a74a5dd67cd14b715c7535b28b01dbb3c0c3793b438b6e56f60347bc4220e695459c402c94aca43b9382a47091b0569601ccd7a74b75b868b035a39b9617a10953e468558d5850acc0a7d83532c9a6c5929ca3c9bb8fa16775457c2d9b320dda73bea9d2047a0c8f62f78f5e52ad9188a851860d1015c15f89395cd86822faae4fd2354610a608b36607247956e68bd4c252d7d68a4d58c3107465748a31de880be3230ac6714a33b4c62dbc711f5c0af44a36e6ec7ae6eab7ab954dc1f420a569b53966141df1566c73290a530d4174c198e5c5f427838f1884a2108c85688a16436270002207d58e75412de7255a1544c7d8b43f60bb2b93f45bacd80f2900cb324ac271c98a95f3917008ac3940853c13a516140fdd0064f646aad67b5bf1b966b68a6c795b2f6742a9d68228f86a60cc210aba894ed84859d990c10cba5671161caeb59c497c1b2ac52df6913a819168f8b8343654120a459ce5846a6fa777e82702fc8987368c05a503b57ef7304f862c55b9848a461af1e4383537154da27866a8ca4ab4af01ea4c30dcc59ecc0c9215a141996ecfe34aea6542b3b8c917c98ef574b1ed006977fc7b755b87c6eab128f6bd4b089359aa74eef351302335561303d26c24fb327319b8974c165e77277db30035c84a36534495ca260f7f76bd96396dfca983c89a8b99735486a78d34c9580b691108f63846183659854fe8f1168cfb9d1f5a05ac8106743bb74c1b72cbfc0e8ef6be184751fa449795bb1d0b7ca37dfa8f3979bbbc09a13d4c47163a69b04cc013795d41b0033549c3d84b00c01b1a9d7104a9d37751d08cf0e8132eea86b2462f37d660df4a3a095910b5ca2ca0da78163bb79a181e76dc619283b6cc670ccf2b1f3862c57e69c2b5cc293b87578b190710533bd4fba426f3389848919619c5b41cc5244a368adc40ea2647e4413dc9114e22749684923fddf2192036b83cb870eefb9afaac2961e3869ff0554077caf6d1aea720ccc59734c0a5465b7768170b323ab8c65a2a82f1267db4555565833d9f19ca10400d513bacb055c956c622cd7c0e5c54b33073be531c6586802cc11b75e8b0542f80b99639021d89caea41644029a81084129ffa66a66238c65c0f5562bd74b861293549a1c7cb70b6b3ce25286558a43f318d24052a196639c8b247bae6c59cd27d0768492b6b6ddd2011134cb9d9964ead020fe8da84a1f910aae304a9c3756112331e62ad8650544b5111a0977325c6c9ba242271ecb0c1a3c753543413685e46a31312c68bf9175a8b110a6816b6aec9562b8322b0d932f9692b1f29c6e3424d45686272f00f22db854fb8157594ca7c7b018b01c1f1a23028a4663c6b258af445f83c97f652954d619d7c68bf5e10046e7079f44b05b9c74591988f328443c1df34905200000000000000000000000000000000000000000000000000000072207a6317bb50769a4b1b8fab5169bb689d3c5defdb61fc74b2792eadd54cc011536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 1b5fa7222ee14e61e4532b01189d576a2f0c0019705a424c3a68c27da592c2ad20802204e58a40e5c4b88b34410e000dedfeb719c7541cea51bd176de9fce964a96006c7ac87219b0114d171d89a261a2c08220ebe532c48ce9db09c791824b7373e1237e82a6ed491d71dc997baed4622b5d4e87e5124267a3b87cdef166d6d1109e2258f5deca3390e750f92bec1795f84f33ed51e071cec46baf3704afbd37be4603bb4fae6795589228be43598b1b055cd696377481e6e4c5b0e9ca39358312a27fc1526814d2acfa9f4a2a4820294dbd422715ad3957cc3b30cbf97a4453d9d6e2b340b8a6822963b19b5213cd9707420cbe5183ebf969d9a1d7c02ad9b02e7c0f8e15903891a506ac9182b424e4025c56b8f8adddece1c62a9593c1a1b83e01239f3582b3e97fb55a639b29bd7501c7008801dfb67716540cd9fe51ab5340f6277a57eba60f3fa755b141eca72b5cd33d1f51f32c32f15459a60dcc0cde1ec97cd3574a70fb835a8080ae180b76c6894c01dbc81429ab00fe1840b4ff75887efa840fc89f3baa828bf860c6c394577edd9490f14d9bb25adf5fe7c81f2e1d5ba110e3271ebef0d42a158aa51afe9343036d86273dfcc01a414d2c89a05576545466c1d2e5f238ad901d2b1d042476c71f8a3889202b25a8b73bab3209d168812f2d495849ba309ad8a51195c32a8f9bb35287a2c2d3d75976748d3660db6c398d88fd84693c83312823f886d839dfc7e56d93ccef2c8b8b64045347870489c3a7e95383429dc78978038649742755304daf1289c74eafe56675cf8d7aba5b737c4d8476748d31b2c02fb8851bf719fc36bc45a42dec0a36c0d9b0cc12a8baad50b539ee36db0052942c1a59081f0463a57792e954f609bc14316f674877eca906f3bbd25607a4c076c9fd0e85eec2a02a767478745c563fce06833144074de383ef1c50d1a135d51fbc499267b2f224fddb0c8d392fea01764e38eddf6ead2ae01f30cce05fd7d62543e3dcce21c76524c52afb252eac36e10d8f9aeb3ddd450fe18bce8034e154d4b0c5d5639bf745e2c8e5435c9ba7db121a780be2df8ca2fc98d41348f2830fc5e182e5c88dff7c88429762b0459ca7977d977b14cce7c84ba39c8cd012a3b15f4695338cb3d6ed991ebd20c853328bd81e037f75e82d85695d56e10973c88b33c88d70b321818e62ed15f697c3eb949d1d70e91fb8cfc3cfaba12dd57beb2ec6a2ee80cff28e54ca18e1686b2674156bbe57a9a8a1152b3298c56174550818fff9beea0c2d6ce74785a0cac87c7ce8a11c0a8eebb5070ad79332e15961bf2413a793beb17ddcf0cf805de33ba04b48ec1e3abc05b7c81aa3277f39d40a1509232be61fa8dd5428300d60efa05329162b46fe3f6973ea3adfc6c11440240099a3d65dbc1fb0996fb75677bca40dc764caeba053106f74f2222482ef6f7617ab0ea0f97bcabfcaa8442657419eba2970aa5031245760b0047ddb8868997edb5a5b443277d00f8af3ef9b024ec3e0ef2ec199685d44ab4e06cddbe4dfabbf336488fb82f64edb55d8f7e52f9b21b2f984507170bd4b8881566ce5308401b6a06e06f2217f1160f5550555527b71774b47e619a83d2c129beb5601ab34810fbd16f7cbe6597de399e4bdac009c6d5e891b4e1b776ad16192437ee0b3d98f528a6e65d17797debdf367a202a9cd017332f6e36c4a6a83481bb859ca6613e0d2b34dfbbae2c583e4936dac99f45956b966452a9c68bf1dc3a326d6d38a6a6da2b6975fbecbde9cde0cd6af3e1cc8a0efc7cfab8d4ec0b74288bc319df5c4754c77c5071a68056f9019aa1d51d6ed28a99d7fe9125d04df0d7839810f2d6f129ca61d117169b0f272af6eaf080924c42c52acd3f28abad80c8bf0d2fdb79ec2e22c6967c044432f381eef520d0f99916fcaa184c81e820d894f9c668261d78daa3a62d11f6a82a2a803166b98cb4568f4cf8845fa78322fd07b0692790a80889e0f54c042b61737aa721b62c8b1f1cb5f01b6d41861b1c614d2f42ab82fd0c878f2212271429383de3496757158b50c451542751ecc49b7b7d3bdf697d66b042e47c33cdcb9a084c275fba27a94c349565532da680efd1caf40a4dda1014279d4b6a530206bd90bea3c14c1039b570e351b13da4a1af2612fe67c3ea4ce4c623fc4026005384addb19be959dcc24857de3af02d5652f9770 +expected_result = pass +expected_shared_secret = decadad640367b73f7c6a9e5d1f9e6dd576350f841e9d8eabd8d525fa8b0e1d6 + +comment = Rho leads to matrix containing zeroes +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc8cb39ba3237b6f13c80ef947630578d2d213f1914f94c61429bcaea77c646f1b99d35ac8009907ccf604c1211ddaeccc2f1001b49776df94560e5ac35e0a7ee3f39377e252d83558d6e57651b0b3c0365e6a133dbe3002270a0bfdc524e5d298b42c1408e17d155c82d69c256f78a69937843491153ec2117ac40370934d28783a69d0a02526afaa8600d289c27e9481cb737cdc4b9ddf53caf313b3c4b862b08045dc38428b126622d77ff3864fa93919427b049786042d234429e9858ce7b1d57a2fe92979851b9d4ca23fa7a80aa4738c9b777020b857b8fa2e442522423608d51b78c574569b9746e441bed403ac21391fe327818dc81355bcb2f5758320965e10946cda9a7c1d329f7c1720857c8751e57b87186e8dc21199e3b7ffc1c4c5607cc3c258a30163131c5db5d96e2e8c2f209419d5a03dfc618a53b1799cf102348b89ba289fab2b206f61688fd974023619fa5187b8cb28be778b666294bf029d7fa9abe3ea739f131930a13629bb6fa7221a788591f595911d3c8a6625a0b69847be058806d916fa0a458891821a0099f3618274091336ea37fca742ffa5bf85a845bc772ec2abc4c9b05aa7e51e8291aeef2a05cc185aa2f438d56026fa0ab0a0e8ce682294bb41238d358dcc1016bcb97ea4e01918a516cfd658ae753f4e7756f08b247edb899ac8b2b11862cbf92a5966b68e4cc6fdf66f0f14a135753ae0f5472a3614a46715fdc7cf69bb465c66ca82e65bd263c5bbbcada701844104ca821a6b5a914301948bc20987229c81d2128754122c1cd3c43e2b4b6aa880d0c203cd9490b7796c02109c2875ae7bd284dec49ecd22949539a2f7c792d351bff0c26f8721a86e1948e08a0fcb2135ff7ba42e352ad3c3a4d1930a26034ee75b355cb299f2dc375f7462f3801c1a636a87d71fd0e528191c8b1d6c4a1aca21edb82825056f8623975c54b1aab806ec623ee50c3c9f954b29212662b7530793c4e3308fb5610429519ab35906834923b053b595f19d6be33c5ba4624dc72fc5488a98e0c7cc9835a161ba97e72bd08485b2c59fe2e56cf1c5a091f389f555c7049c9a74b57af3b1af1263c7720880e5d9c3270b338488279a27c9acc04409d612aa8b195dc5c15bca57a4d24d8d10ce661509054a23c0a0b7839c7ca0f77b0524721b06a8f92570aa62091de06d06783562ec9a0a795100c28fdaa06928dc6a9fd106ff05c2c4d4c3d193898661a4a39583eaa9b62cc282c04c872e145b42058de4467e3f22cdf293723299565d452219c3740bb65bab60387a3321bb2b5ebe585e85e4a2a5882c72919caadc9b46495d100081c88964c87521ac22127e891e1b9709954326b45cb35f5778420b08773b926bb79173130d43aa2c586689effb567fd165334b82ae4c6c98f93b64d99a44815877f5476583ce363196d0257ea472a9bd630f2fa64585b9ccfa1a2012822f6a004cd5959d5793adfdbbc5596887b5088bfc5c5af9aa35e5b9205686069c55aa7437026e75ac370bbd40421df7c21350da1a5b13b651159db592bde2078e2d8cc374d6833cc91bdfcc1f19d9676e060f2baca39cda1dee758ccd096545e21fe2cc082c00374d593968fa8eebdc309698020a29910f3910a1679129791c02f94cdd8aafc8c007c96411835280e148c4109743c8d168ea645ade7c23b5bc26d4bb083d0a4833f87e6d5b218dd73b76810216f9658a9547dad241d408bdca43cf792bc2a6438df858ba77d01c34c54ee9a31c83e472d5f945fa504f054443851a9c0d59734f175795a86ee2847d7981654d89633f47a420b5bf65920b9810c5512a4d8e19aebbcb13ed0a87980891799650a88b8dd4eb7985506a581110439a0f5afc8e998a7477e8c4b54872b9479b36f2378a4cc97b3208be2457326988e4a13b02812616d5add646cf0f5a8f5458b8960839f93581db651ccc5238df417b4ec6a445127e29e44563a7b49eb403c10a6edb624395c58738762009a073d1949149ac8e69e8014478a6701cbe140411d2f1b95376afac6988737a1b9278a2ee5b7fa4c1cd89b69f56f2686bbb59a54c676eb357a0602e8f8a8a914c745703bb7542c313461d1075beda6cb685832fea735d0c573fe744c16bb52b8e7a7c8d049ae34891ef0ba338614f300033969403ab4677f2179c8224bb2031b8e891a8d0806819abce1356cb2c906fa2a17d4f3c4ed0b8cca831376f67487847475a5b27206a18dec19d29f6a8d49737e7b14f2034209b0497474a3b0e94b6ba190d2793c945cb7866b3959f7b2721537b77a45ba6a259c0153889141a1f9171e4503a503802b4e856f90433063b37ff00b4fc3347b99539efe3cf29b515dd7b700b37871d926f699499d6699831e18cafc00619b35e58555a40034c22bb430fa23854c81ebe12823b92c0bb05b2eef1cef35a75ba6564db9122ec125952260149cbb8e524391aa92b82d13de624c0368a9df175c5ba9b99703b5bd1b918eacb53d78c86b362729a01c2ce905c4d5120e690911255be11b39dae9b8a9b60191790b59ac5421473237508ab327811ebe955e8acb15ae72019426573e314cd775f4041658e85b3261c3f04c32d04e58b3393a81c7b4f6b2542b2e27b042027f9a0b40947a919fc80e87a8182508d2b4264fdc9ce9786ae8ad3cb041274b9fcc575291d74c3b95afc31acc280297841fd5549083120a2fe78991e000000000000000000000000000000000000000000000000000000bbdd2fface390c0376fbaa97281a683c4dd79d3ef4d3421f88849415c2c37af12e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = a9560cc3bd566af9beeb59a300ddad8de5a70be9cbec8777b625f9df541f3b7e3432edbbae58624ca393a7c8466654ad4e616f302946f2b4e848aad0b16d6ea8d19faeff99df0577f422b17638ae8fc1c23b90de0d3b0aab0e7f77d81d4411af93fe1fb038fcbe8b5dca3aab65b63b767360ff8d314dfd9adc924dd5315a591946d7e3bb9a8d7605d4168255e2c0eb5e5fa2483505cc5e7e25203728ff51504c580ed157bbb7ea59702fff5f39c67334332d5ee17ae551449ad402b9d299d7519a9d60efa56a1bc39c1a3e12936ad533457fabbaeb5f4016c39deeb95bde3d8b62db69aefe698e9ad4597762589f20771171623c3fae08176cc6b9904fdcdcba42b1ce7ac5a4403ba3f38542160bd235f2b1a9d2c8735e86ee7af2e749508252a34a4c36bfc82573b856ad0408a95b7fbbfee254191f744e0f36d698dbdb0e9905e2a5e4efebe76dd2af71578e5dd28974f393afaa581e755030a137ff7a912648e6c1c9cad9a11c2fb22a028cbecb24909ecd07a53b5094d035664ed822561daeb8bc09c3be6f351dbff20f0bd69c6dbd8495460e55710e2e26ca39a1a90f05bb44e74cc0fd932296443a39b968717b5d7bba52b4313005a7e917a7eef4561e340e42c9d4730a8ea2500db48da0aa4c8086a038c00a5698b1675b398cbdc8223bf2ab069503e574873ed015338cdfabd2c4c8b349c6889732dc737501f9f4804c67d693722f3723fdfa21130fe621e1e091dd6dd63cee53f643f105ec486fcd4bfcafa03bf7662b2b31f0b428ba30636e2672b4114c381e2ceb631ee4b59604a656de5b13f556ac60747f00362ec577381cb6263c7511d1b4b6b5d55dfda1861bd8ce2437e47fe8661ce3af193a8ecd2e3fb249a7b82c9ca905f38f3072b25262b50ab205d7c210ac62783f332254ecbb013e0ad36ec963d62e69e085aa6356e1d2027b6831cc7ead70301bed933823d1fa5d157573d9828700668593dcc60e1c8adb12f14d61496d90d38b9be0fc78654762c4cb32ec66fba75063f1d8f7e83a3e78c33a5fab61c80e73af520b6d013daeb5d48b0308a5c30f86aa19e64743d1bca73ad7336b7cf2b9a309e3d86ab39882bb6d3f4c2c2533fa3a4c650463d3992ad0ea1732b2371b62d4c8c98dade19edd0eb1462c830e67ff7413d890d30d2437deb5abbab57d24411fcf49a2cdf997263721f1a36fd7e32ef383c3ba460a983c61b2463279330f24b75abf6d2ca977727696f336220192a827d13d74d833d038647dc6720769cb316ed38e9e60ad35b00f21eb4c9076b16c79f8f3bbbed9fcbcf1f0bd70a4745a697f3a7497996953604f29e4ef850cb96735153fa3f2416229cbb4c36e85ef8f68a607d77c48f4a14e00a080c62bc2094dab53d39c7a75403f35c9f58aeb25b075c9258c2fb23afe18cea496ec56b3f17cad7eff23bfde253eac130494c0715e5dbf5a565bab2998d8d0dfcdd278b863a2776e1c97c8deade022f3cbc190517d0ea91d0e8b224e3eb802795f730fc90284b86c265ff0d9b7a5de627859be4c7c8288d22c19a638fc80836aa30b948617b3d4f086f337443db0eb6f1dde7e854525ce5028d3fa8d45bdec7aea94fd2c4586ede8a23cee74e42024c8875df7c2d22a10dad2ab7c677242bb80d21a52ba9fa299c046111838c5a0555f8d11880d35e6434bd66433dd9500febab247e9c220b2d97d523199e99597d0e83ad6c11846c42fd04b2831b4688b4b338519037e90b68055c4d10722d933b0c90197979be263b884e7ff11d527b532fb17e1f8ea94e0a177308c6e626d6deb681b2083f9960b6d9845069b6bce1512a001a8ed694b16a191023cde941a525b94f225b55d12ec40bf92db4c04c957798be6eec2c1f377be77499739f48c9561e83a01c49012f134b5eada3d662e02127ddddc7569c07499fff9f8f341adf25ce79bc46315c4dc08b65ddec14275df0c38ced826ec2e21e3acac3ba78860bf829b5775da4ec61ed0dafd17b79b671629c0f10a497ddc3734586e8c6689d087ebbd63c9ca5d2edf349469ebcc31e81c2d6d58f2c2ddef32b4b9986bb64ef8816986758a616ca4c4155d126d357f0571b172fbe6b7308e357436945bbbdc70c831f60243dd96a7c617d040a6276e4d9ce07c880cd4feca2537127eb0eecc6febd22c3c92a3110eb4c4080e88923e56bea4e5fcb76c450442b89a5cbc230f +expected_result = pass +expected_shared_secret = d31df13dfb22d68333814c817ad444cfef6378fcba2edc372ac44ace59e4e9d7 + +comment = Rho leads to matrix containing zeroes +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca584a4780ea352e9dc85393457e71ca62e85abb2322aa45c4fb3d29b15d55a027b8a74186000b9a05550b2a343a3ac21b0f7a2b2aaf736a1ca49df5b61fa749266b0696ad7b6c48b0dc82803b10a4b64d6caebb33a13c60effd699ad44c1985c9e3f8ab21a0cbd728ab52e07c4bc5ab3f6c698ea307f435bb7b5545c44758fee3b9077b5a318c2b584012cc9b57560236be789bc4b026d1f26a857365b2d1a6e809a9f71e140ec56c4db3829b74539a90345841483daf6840141100c66cbe057261fc346ab8c36b03cc2b2ac838835cd373836bca05d9f57ce2231980ea1bd9908111e79b602572ab37495e9f6025269713f4318dc472d06b473268bcc7c5cb956b5a1ebf419aa18b9d6f184849240470607fdf6325ed561c270b095079734fb61e04c531be893c2621c5ba48bc897868126b995e75777c8ceb100c67556484b71404be802ded5299cc41a83b0c7a99c8d36d55f7fdb4697c446904c2420d667f5e58e0837778ea960bb6605890b8437f24f7d35acbccc41acfcbf2e35270ab368424b6ee6089ef75bae678c685b685315456ec584a93ab25f67427be85bba701c0566544f8133952936a203923e07d5aadea1130d906daaa1a4d9939ce1e147cd874ca0f777f9023d156070f8998a9607940d15af47a4919c52b831748af51b41712077bb4836d383a33d802c80a133a388bcf0f3cfac305a7fcc3199ea880d271242a3a6adfbaa5a894ceab055a6594436818ce10bc8113c8ce0613fca2533088a9f35c4a161e0035d690e48b4677273ace7d2c70e378047e7b9b7c49b729a612f5abc7551756aa91239cb16aec08e2ee53659954cfe1a5ba8b47f36c47d6ea2885b8332baa61b71a9bccdca58e2f0cd25e9b40d38867f69574f98ceb03c3d18b9b6d5c2ace4a8b1bdea7e5e678f1662932c267f117005be498dda33b97b0c520b1375c75829d8e7cf268524f74656d033bb986977296b4997fca693281896681022dc138fb24d9fa5270626b1dc4375a72c42955529922cb683c225cc76ad1b25c3082b9d2c47491bfc8b83767d274b0473fa753b16b117546b8a755e94b6b6f7048079985632b33664aa50eb072b47a338ec12b3501b3413e6c94488546f2bb142d851fab8260665aa88a75856d1ac719341ba190e941b8d6bf53f76b968fedc28d0a524d7e366efd50c8929cd9362cf4ad9366713c2dcd4b91c45b6fe654fcb87a6674c2f3c9447cc546aa645a04cc3b57d8b1265d91028c3756d216bd671560e29467805a2ddfacfa651a2fe32731ddc74ccdc243ce97ebb7b2ffc7056b334a0fe7813cf5825997690b91073b7f9563749b8eaf46cd8b93161c21543592c21855f577290b9a6616e2c80134a3713f04e6c2cacfafb3daf78b9ab671337931ef7eb58a48a73a96b6739850f2af60ca0917e301610c5731b032ca6cd77554b7a7d7783c26b2cb43ff1c1fc3716fcec4455e516d164c561776a03c77275d52d1ff426d76240b8b5a47c498fe836736a09cba0b32983387f595593800a4e37b3764f054bab91731c748021818e4d149db358ce8b2ca2af45c6e070ab06fbb3a3485698bb955681b95e8932aa30b9d8242bff3618120038b3ec776dc3b635963ab24b8e5f9761162737b04a59fb38ba1b3685b3512133e25e7810c4cb26a25be67b314924728528dbdcc87ec53cade88b1e55c7a9ea43b647655c697331db555e7881e240cce208ab189265db243cc97508889a2fa201a0d1066c5d2a7370eb8137d04fe035c8510b9f21e6bd152872ce6c7cdbba87ec85341c9c23bbea14f9caaccf56cd41c60931a1970867a38fca93fe6a789f5b1cf99ab23fbba5abbbc881aa154df05e9dfb5c92679cb56b0f156c3b67e918de09c5eaf4288885c91fa5366f0854e320451e14a48261cba3cc671ab590ccea69693a25ba90accdb715241754f2f5adb67a6e6491703c0b803d8c55f6364cf64c3f117206013ca309f5c7b4b40774f98ee7738f70b5b9bb19737855bae9958f6b24b22d643753515f79b884c223cb9a734c634306ba20cffa79a5c5fa46e1501aac245523e2b1e42a44a953964727b13fa01b65eaac6188a1c9ab974c613cb5971bc8680e90181b3ae927b3b325a22389c204470e4c6a97e404437858910c61897cad27f00e2f7556639635e3775f7ea351921051684cc6ac224df9ea98bde524863683175447d25aaed72c68b15955dd1639dd978318a8347316690c24bea1d3c64f031aaa2a3b48593a7593b2047a8c29c317c9766bea878cfe5ab947f12d5fdbaa267a18ffe966ce629c25ac16b68aca3ca000e5081faf0b07c7b914dac266dd08109ad52408c0cc06524ed424638d1b7d3175bd977b982b26450b7b3111625d2f64a6055a59168c9ad1cc13773a8f4a2c79d92c08de3567387a2bcfac1186960d3c939f2a601bfa96bf9416022385b2d1aa2dfd570fe54cbf4cfa325bf4a87e734b2bc4ab576387c63590ec3171b41a5b621109ff0a7617030e02962224903d40c5c396413d8793c2d2044949659a92b4480e8123a8738f3cc12e45504dbd40a3a497623e70600378bb32d66dbce08eaa28303e896aa887186ef9107b023b69c49c0ff802fc504431ca0aae2008fbf39c268cce17f1a75dd8c880a34467963cc2ab4d60d78e96dbbc5e5611d955658de04b13d5ce6cd3af9e2bb3caca8e6a088afc7ba31f951b920318ee4f3c26cc000000000000000000000000000000000000000000000000000000c9f4f8131164a4f1f11c42ec9d4f305390b09294a7ecbdebe3659c77e737a1975ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = cb24ab9d59fb286f3ecd5908e34b4e5860bbd08ac3939825156f619e0c005de948e8698deb7a34462c5fb7730ef3ddc05b017b58edd91e6fd6d4df125128d20ff619e3e593364eee7e532f3d962108b31f77216f71bc9d5163acedbdfa48f94f2f587bd5c16e11b5480237e88f1260f7c2fb25d044d5108d199e1bae51f8f14dc5614b75996ecc3d067ad3cc6b294ad60fb9fa21750c7bfb53874c2ee99f73a494d0df220f054a845f2fbf85d1a5727c087a65436433b73013b9a6f26f08c1ab443ebffaa03a7f8f185f33b07b99400f6b03ab985711fb4ea97d058a8e9a948101359b610a6d428a3d10594aea5ad602bd83b05ef6b6aaa2f56b655dffd3db5ad2ba51d8d3138d355f2550f29b40bfecbc43f1a3dc7448640b5b3006b87a23f6b71554d8a54fe0d4db52732e8260c915407286bb3074d2dc56e4cc50bb14313a4117e78e29d83c3b5dbd93ede35d2a47b46a0ed51fe72cc7b86f96a3d9367949abcddbd9988639f8a8555534e23fad9f35fb132396a13f3abed73fed757363207043a84bf5fa6cc2bd862ca46dfb9a124fc0a2958a09f1f35fdb5095bf48b859255cf49eea771f10ee78ee460599342bd76ecc8ea35077c4adfc3e05c37abe4b45cc00ab74247ce6568b0395ec681de4f96af9fe4f053d08ab465ae580bf2e4bb54884bc90c75758a6c9fdff87fe56990cd3d0aa691f97e03d46b5e25bb6a8d2acdd458bdd60aa803f4a2e7652cd9901a385525eb1f2c619fc2ac3bfc655a40102e0721cb842bd1516894e31d972adf9570365c2d3acd23e998c9aa620bbd0f98b07cfc103389df202660a9a66e819e8ad4872cac9d11667ba07e49d0095b1470d793b0520d492b4524521f470c1ad11a917545c3e90c0d09c57153b9f01021dd9af03ca73f0d833a0f7d6d8cfc132c95bdf9713b055acd993f8070095cde23f5782bf1502268ebbbe18e0a2c2579f4277d2487173fdc03f787e960b351c0b0c8b676e6a9a1b2cbb8b88ed59ca6fa351141711349e70f13175f5e1e6c40b495c283f7f10eecd35fe77330b52b1dd5c198c1ab5aa82547b822b59f2eb18d3f70c2fe6d78a5eb960abaae74fc69c573948212efb77b7b58ac24f23e39ed35a0c52f00885c24bfda0336ae6ad827b83a0520710d9a039bbd2c9653d8b3ec38133f06c4bccd714087f5291a37b1ccbb4fa71aa04b6ddda1cfa0e4af9d531c053b4d3b4546894693e32feff3de7df191517c89d34bb3bfa4215d98f5c72bcccfecb97144f1abf05fdb21e2a4017e9423019a26eb70022c74d49926654e986781d9acea4d8008dabd068ded76190b76a6dea78e2aa33b33e5c68b43946c0f83cd3c162dc23392d47e6dff8ae4dc9ba44ede5ed59d6bd399110c513e52a71bed8073d3b791aba2dd34ae5fe07bc9f0b8efd5a275b10477773ed26687be2df6afca51aaadf3df873b7b87b221ed25e053de30b529aa920b14ea96d955ed4452bcc4f40389a9b8dbd8bf25bc02a99d0c1fa92e8d1f39013210268f766c5d9a8f080756791e2b9ecb7c81b10ff643262da8e63870b6e910c26e10c20643ee740bdb73c3ecdae5bfbec98940ae2cd3936c8dceab8c6156840463786e20770d7c2b89546a41b7bf5dc1a441dd8089d03b69942f3ae9823a29aaead42fe77763fe0b51803cfff169b5303594823ee70e56b4aa0d8d77a7a39181169d4c9910280edc3aa6841e54427b962846df3fc73b71ef19cd6f24b74f88740347ffed1c6b299ca9aabe8f17c9425da19518f490ce73b1418a41d7f5d60a14f74a51dfbe6170b4df1c908af859392a4df8e27168a35091c20b2a3ecab2e0713e26f97d7d571dbb2931db0d36997cba78a929f06480326a8ded29b0bf1199b654cf6cee8e982ce057a55ecd2be458bc8f55156be7db5a39dd5b5e62c0b178c0b500d79bbca5330cd21c4e213bfcb2584e2fde2e7f19629710776affb99fb442dfd517d49305d1980069447b09fdb411e3ff2df0fd2e76b35ed65b6abd6771e6e05977ae1a86145a24ccf8b8ea28758921a0f202cbdb629254059ea8f9b5f6f4cb4f69853e7de7cffe70c05c5588ff5e77755852b6782f2565644e6489f62318a7e2a29370f5ea90c6628bfff320d948f715ea88958974a0ff700b08b3712100e73ba7d134f107c304ee0c00c65dca2853e739ff2842beed8e5df18fb4bb3e7edd7ab8d7d6fc0f2afd92f5d15 +expected_result = pass +expected_shared_secret = 751052356086210d8df27a08a945497eab163ac925b059000c89b6e82b2c6bef + +comment = Rho leads to matrix containing zeroes +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5dc9ba816e19d8a177de33a855960b7c464cfd51a7279a48c80091ec357b9fd118e12f00736036fa8268079754a4d565773f2a5d5c913109a4606a276d07372eb96474c7722d85a17a50a956b3ca8132415b2c404a0288aadb44fbb00217c0005ee36137768c3d4169d300ab2876c1b2a92c0cf119fef5018bf7acfd2031929b9671898c64388898fb74a483a100ce2ae67275e53b00d94c2888f831a286631450308aea2580fc5cdbae53b7108a9d3cba88a437a5c0917dfa3bd7fb2266f2b2f57f52724b67e58cc2781a95191f60a34d74199102b5fe941874a4433034ae6c9aff9e2bf16f01781d72424508835e3a587903eefeb0b0d218e11183cc7293c81c09cb5fc4eaba4cdf22284206b23b87566da704665527c6c587aa3070b01e79094747a87ebb2b9e5296a2405528c224ef45ee6fcaf0c537fa2e2479d579d71a3400793188d895323f274077416f94c4e68811ad9c73598d7ccd53bcd18f8b1cca8bb5591298132258f4210d36722217c2fc5925330d03d1c037cc7d520f52b7752f8b3b253b655f962e9475e8cf792f5f99b5c4b440a166e0d18c79de23173d690cfb697f1d072f269b94a78bfd6196ceb655354c31f356806ab5c42bcb9030c6c61e3c3a023327fe813362bb69ed9e783b086a94581c41cc49c03489ed53b585febabaa951bcb642674b74a4ce35db92894c6db484ad10b0dd84b3e1b9f88960f4d7a9b36e580473692930a83a5233dd07a027c8cab7b4165c860cae41b950d970831105902b90805d066da6552b839607880a1bbac123145375115c647d10671e84b85f94206d534cf44bf59416f01994b8b125a0e098a842c4ad6ea108fe5bcdea005a1e3985f656e34c431d456cdf9f624a7d221c2c242cae4c9720a048c760cd2927591db67c951905c67bb42900c44f67b99e508d5b38839a0b31443ac8c241ff7b9ca0a06ad744813eb37142939248c7163262216a4438b7f3aa5eb1c9ae329c0d0bc63b2665d90b17e7a27308449bdce8a861fc08c982266ec83c9aa1422135a9e9be99c0a098df9a5568960aa2c727a18c15e7713c289e502bfa9170788c6a2d01711fc9b4177a491226c4d6a05b03baeec202b98e3af0c7612d474c6b7b912cbb38990f29fa5f15fb12c4a5c417bfe30a8ad88aad5395287376fb3b18b234199273625fc23c79a775586d87dd9466f1cb816466807e5079a270954e8fc8851738dc316369f8344bd1019f6b6624bd50f0cca851eb57c48b126aaa3a97d8044d3800bf344c4579361e3096ca29506b4b125143b2d625c21bf0a001aba2e17aa6075d8177d55324a08cca923339bf5c7c00b5717e7007cc94b61f3207dea1e3bf24b79a09ef07a37c4476e47f79a674693fe00b78d372b6ca76614ec604a86b64106cb61d4324e99873b241a56e063960b5fce306640bac5d46c88c85678c508452a806de60966006663845692129123d2846fff3225529475f51521e3f027d537877797b511043497706f3bc3b77ab6823a112597567e6b4848acea62fb09181fcc556beb8216c76ca6782e2d1234bb8521ec40a0f6d511bf8774d335b9a764a89aea93cc9b21ad62635c1b8fb6a4a4130572e41bc13ec627ea2c631d33a81ab1b6c77078c564957b39b0f9f04cc91b1b9ed89240b03a1c787347505fe4675af30a09d6ba13074431fdd045c44b4754e5682e7c5d49492e0ff2bc7585b631f3cedf98bf774427df7ac847954a139545d3643b1aaac31b49571cb7ac65554356d8aa555a67faea89396aa810a9b1cc8312be7333003d8e1f854a7e35ca0d75b06c499b0ed2a35699114d287bca9571e93948bef4c32de6bbb952a5fee5ac42a14c4ada7ceb5c8bdaa873076b0f7ba4881bd2118ae67ea671482312a35c7c13b1d7af2c9291a8408c3ce985a6311a2c702cbf306c9a7b4eb3ba169992831899c6870a8fd3302079748a835b04791720cc4737c5b7684ff612abcb477c7032a88262a37845f2c46f9f0066d19238689b1b53dcaed0544c06755399da2ff4fb570b299290497937126672a41ee9fa594d40551246cebbca8ab1f5c30ad6bba9b0aff0f06b0dc060e6b58a70cabe5ebb464b3562f1a10990d12e5da525c43040d66461cc396ace7c90c0f1aba06c94dfe7426b922c91744310ebb4e33251f1c47e2a415b95a895666333aed434edcb69dc69a513194ee2013a19164d49a519e0cb3771247e65664dfbc69c46dbbb6ab2193bc5b56abc9034790ff43909e6563c42545bd6ca31045c2228dbb5601895cd397dfd73473b0609bd720f9475482697636df216beba0d1a85b396e6ccb3e41fb8d52b1341b08504bb00a5740a80228118adde4c7d0bfbbb0fe0b8b815bc07885e496324c9806f9d07762f123ddc558aeb387b9858b2117714886bcb2b18b182b6ad2f8a21acd50388959f3b70a258a025c80a0b89d6321f222913484990549fcb98c5c8c88c2832075be378410b70c9b9494a6c1a40e5aebc88ae3d186d0b3896d309710c17ab96c93e629166980325bdc946e022ab80c47f61e01421c780ff336d7ad11a3c28721b09a03a5337dfa6cbb76acdb1846b62225578d17fdf062839878196d1819abb7f09dca6a1d225e2e0bd89a5578730adc5d53d19623203e24597c1a2015accd07a6f83938810bcbf2dc94a99f5b47082336fd11a45ba478c750f3e638d064144818a17f1586d6806353409000000000000000000000000000000000000000000000000000000a0128d824477a674d6f8e08f3b9cbde943c99d33bfc5a722b3e426ea18389e408bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 6fef277df2e04e66e489b1e04fa87580157cf1c84f0b3bd8137afd87cfb0d726e39d9706f177f605e9aaccf3a52e841e4c3c4b5d54935c5a9eacb0e6d8a2cf17ca416bf7ad3cea42c3533706c54779d62a0c8a44d0c0f920db72b7d072738ecc07fe16a8e257452e1197604054866dba1d12cf4745a2808a435bf31aa64db6af2dc4a3af697911adcf9022936fb5d40a9c553774f4a589192d98bf8289c09ea803807c448ee3e99c26799ac051a50ce5edcb57f3e13a13fa1af41befeeadb7c33e513ee8cd9364025ea0b4efc5ff8f095db6f0a9783acc57b2ed7573cde2ae2a8e7b211ec9eb6eeb34bd358d5cb009184c76bd7d1bdb4a920464d1da993787cd284ab05b8d5d3ca474847e64e1e728ac4ae3522cfa3a642eae5c47a94783700a2b758b2342d5dd261715db4f3156a5be96fe219dc8038f2d7afc74fb60e6cbcad3ddb6befd0625c4b2de1cc9039c9486c5c18aa8a796169a93cf8e626ac47e82b752f2e6537287580acfc1b6460bf5db3f71fb1a4f57e67e0d914587dfba55ee5bfbd5841bc04d041526a46053af4de2347fefb071465a7f9b00396b66c49efda179f13f07dfd0278464239436d8bd39dfd048329c89c2c8fcfa54c24ee67d124dd0b2f411772e480dc2a8b40a6792d0cae8ae9c6c883908a0d33e931053dab157d49e11e76ea3a9bde1c24eefff37379b265a52a4a26b507b5a4eed6f60a84595b1b747c96e8656e7759392924662fb43a40f8154b642dad2d8a0624b413a15545da8bc3dd5a5f8d304eaf23299d5a4574ffef0bd5b3d5977daceb80d67df682979abe36cd7d74c063a0b7214336c75c6d047f2bb52a0a5124658b9b53ac5a67a27b001aeed0c6dedadb3c818ca99e52b18dc0a9adba7f88eaf4bcd269132be2462be1a42ed102811b376276780e7a4b399f02e6c00605f1806987a6c1b3d4cc8f9cdb85b2c833702735ec6a61b9fd2c9ba220b108451d1fb8ddc5a07baa2537f71bd82f1f06d7f27e4a374336743c40466e11de367ad4a256e860e6e5f62a38cd2911bfce65b1b29274989dd1016ee6fae7790bdac6a3e1ee05fd4ea743c5609c3e4f1a65953421be132220b1792404d80d68db00ac5a94feb238325ffa44b376a9b6bb3a84928b065995cc7882673f1de566a78bb80b61beaacbe138a5a7e2cb5e3e276057520db7424405c69f719534983fac6ff483b884c932f6b72fd1878ec2ed1edf741159b973e5ae846fbf59ae1aca97fb855c72dfc5181b09a5a52a1f8012629218a8b00968a5c4ca733a07893cdb1ada1380db4b6f4f211996bf9fff20227f7d73aa552d8f9fbb6ed0d4dd278aab1214fce37dd76ad2ddb90e7ec49c4c4bfa61602988bde7f498d5feb0540cc0d6f2ae75018115695482a4264d513780a87bedf78e256f99ad0ad37f910215795fdfbb375d66ad20d1a731003a1ed52014b6183906fc6a0ee544f1b238563cb6eb407875714ba9d2fb48e667962b45127deb0180e317af9d2fefed19ee929b75c97088ba9cf525ad7264680d3a9fda47a6b5168a846a1bd63695f4b3342ffc828f8fd1d5614fb4adf9d64447984605a8846c094f813e991abfcf01c0ec330cff0aa9c8680d424196f173f63e2d0ae359e5e1968fdb6fc72721c23c239e88957f107eb296d7967701d4e9dcdddbc5962085616cb641c17c86d8f33d73bef887a160065f48f5d7b456153c4d2898f092f6a870c49ef615fd22833131b55fb46f73fb399b046248723cdd15d37c46e0460a81840dfec3879a49eef63e3b331cf53c8bc5b10570a7fa23e3228ffcc20cef18ebf8ced22dd37b50f79aea827dc37cee62a849110db97287b366afe64b4b9379586ebe34b313e260e84be654d83dd3fe4f31d622132c06875ddbc70629197f54b400a97180b81b2cc5aa430e3dc6ec4d9aa37dbf811ba2932aebbb9990f0048b4f04930e147b38f3f22c4f026b806d9dbdbfd69914346440d9b37e7ffdb8bec0761e49762f4f87485e2ba5beeaf306253b97cfca2637e7f7cfa175e5565e9df8741b94aa8d808515086a12606cf207878080b7cadbd318ad5667b50ebae48bc923b4b7a7c7f7145f7f223f2afb9536584caf2e8df28bf693c2d4d2ca71e38361f3db5108e28ba11aace9bfb85bd872be837916bb53ea66a22a605683cc112220f894a8dcb16098607ee5e2ae33b4b93dca707fe7f96f91defd1a6105022 +expected_result = pass +expected_shared_secret = cf115ea5c334c9374daa083543cd805b8070de6688c552b82b256628573d668d + +comment = Rho leads to matrix containing zeroes +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00dfa8bb9d8c58e33260020a33fc04021baba0f6375ddee4a6023846a2dc73eb69758edc915ab2446b1c59fed89bbb86a9be2242c117cb719274873c8b0a2857e4076b3a792965011675c23deb8bc0cf7b2e3ee38493461f8a2068bcd899f1822dfbe8444a612f9fbacbf87a0d45f98a541c5141b230be12763a3563f5d47e369b65c10254e5f63934a05c8ab3409d7b4207dc423d537abd4404a9ec6afb1cbb529619bee740a4c71efc952b3b871043c24c0c919f74f508bc23a9c1ea8b76ac449e28379af42bb6140d376c9a4ec76b34042c7d711efb559c8c87170662788b4cc907e4882d4332d90c43175cc56eb943d589a30a5ac1ae312aeb8432a1d7b2f7448fe0f48ad069989e908d28616530246f8e817aecf6ae638acd7030a596d5be06964eeada35f6175bc0d20c26636943f1609eba3b8852531f083a576231c9b222a9f96ab1fb79aa0149155881fae91adf26c4f1e463f6f603511311351c6c1d1832f482306d66a4a2e585b7e223bd539fc45c5b29558e3110cc268356edf4bd5be7aeb3f7b944d964d1a7cf0e1a686e02b0b30195ee2bc6d5c78a8d73caa7726a8bf2cd62f33ec676a2a0c997541a386ebcb3a5d845c0a9b970f35ae0602a4282136a0cc832f34de426a08f05bb89f05c4f23a1d7bbbc81628040fba50077569d99cd7b5c7f19b4cd5ac618a4c489cc08cd55f567a203106be784f6824f276c5b4407cafc0836a69c8d90047803c598db03491110688029885ca112ba18026a339ba7e47a4dbc2386710e87fc74495935b6c408ee077138476b8fe10cab556bd1613bbe8ba72a345f157641873651b314534a7c4bf2979fcc062593c652441340e481a76df717b21061620c946e1250e781661bd10914556552ca3204d44d64972038a68a60358126305dfc2bad91289ea150162333bbe98874930abfb3b13922b2be9fe6bd40c9caba8b9412f85ef64348b6b46695184b212b9e35586df10375f0c0781b6245e2d8c580196a025022388a8b1422a847d388b1cc17f785772d5ccf342c01ac667ca866c49272af0127b8076570ab309fdd096b007843a2dc167837977b459000a8378fa4aaec320874804698524e4111bd1525be985a959ad3c8ee8373511726e88c71f2a839067c4a5a4235ac4a977c444b482087c612752ef0359d1041d3740ce4db971071c0947319a8a2c314dba1bfb118fd093f323c4e41d618f0cb73d6023e7380bd68b9351a825fdb952f13f48b64d99bda8701d040b6da27061ccb36f982611b851cf2e795f02161f58ccb973c6c3b0880915c31b7d59e3ab05d14d7697ba59245043bab406d0286b71f72006a51aba92c8f53e39333cbb273fb7814162c4d87244933ceef702d17db03eee50b48eca264026d19191800e47d1bbc7ef57a4fa0880338922f75484759e2a926391d1f993ace7756fd03c13002950c33cd4a882d90131d5ac4c436bbca02e22c608a3537d21971672b49963a1f867fde42c4b464b8b1e557be884862a68cfe361600f39d38886f8fd97479a0797ccc95c66289a489a66aa9955d1985d518b7c3dca884db56a6bc01d1d21818fc25f43a1b378286eeb18da2706393026dd8295e4e20a103ba97ec7618b119154543875f43bc08d76dd51730672321bce866ae2ac6a6450215439c9510174c90b58a416375e935092bb7469624337a5130c30e27905b0121678480b75d206888c706699b555084a6cf21237b102107bca8cfd4809e3513886b271c45cb162a189568ccf9389ec8017355db91ef79afb172cdc60929d071c6ef927f641a82937a146d85ba668701f14183a5136df8d6b27a87c215363016a21b8ed0bb27173d067349b170911c0607c065b173a429f244199db3affda480d7e3919ee616aba4165cf1040544739b3b2669817ad6f3335c96b731ccb2f0765552a71ab3a32e6509c7d53233b229bbff40c8898544a8a26db655275500bbb265acc4f8cfadecb77465c5c1989680fb37b554b9e5199c53759f27409df229034d9247fc965d453a206197cd840c42b495483faa1d62571b27190aac9c56bf5b992b8019ffac1366925d2b65230e2a88cb3c209ea13a1f273c9c512918637d5e40b92b9546970b341ac0c69a264b90a414a43270e442665b59608919cb8ee7234d113bf6d14c89a7a1a1f489420bcdcd96123349c65984aa9ff083a73c8294a282fecb16179c494ffb33506947c9b59e39990b9b516a3751aae6cb5499d196f6402f7c2a88459639e6c2105bd565380184b3e48691b11598b5473c02917558911afc73bada907ee1c124a1086a949fcd45c0f0c37df0863f45d70125d02ceada9c797a80b1692ce7e7c180079023826f0acb5c80a44a47f724b27b652c10bbe4f6258014a03dd7cd84ea2fe0ccb4c0744b76fb01f0f42d3c5862327c6d2980751f835a9dd741cab5042e685b52f45ae95cafb6229b044b4a3e056c242ac7a44587abe55f8de5b2fe0a9cb8f9aca9baab8b423a2b7c6afed694f275c5ae2157288751e95c2ee45c03935a45a130156a739906f104dd931a6498960fe27aa15a0679d1bc68c9850c930140b6a45bd2c2b5cac0a168aa644760f3c8af61b8bb184cb7dfb784e0f0c5ce739fd881c1856815cecba44a3c4214f7825ac44e77e97c8b8b32c405292d508d2f8709428a39e9b60016908b1ce6847f84b14b555250451be218c2bed841584b3627fd0000000000000000000000000000000000000000000000000000005c9554bc05cb53962ad1017e802d691c6c2f5efb5acd53736737ced8f6063c29e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 3fbe35bddba843a88d1401fb50ebc9a3ba2b42cbc5795ef3f29f3c641287536a4999325b99f6b5e9c2a36f8127e2c09a7fc6140a9bd68300e40e6ffbfdf112e9a50a21d16a256dc2b9b94b2e45d249c40810a6978963b186d543e2154590b9007afcaf9d1791f4b0ad69283ce711467f001e8580693bc7a59928f7b1c228dec882e3a37f6f6ca83efa2a3c2b2aa919328a4b4174c00c9ab4af6d16de60859d3b4cce874366fa93c26457d029d20c186034ad8c4c30a51a2a5547e90456ea1d43ddd1b882681e58fb8e2db2c0ff36201e0becbe530be3cc8c6ebc80b9f7904e8a1009c1aa33fe35649ee91c558882f84c885183a6f226db7dca9af61babd423d2f749e98133744d5cdcb36b541a6486a43a5c39f92e0949c6204237ea64ac25faa8129af4a10f9aba6a0b647e1bc99b19187d3a2a941df726e7f8872e2e4064702ab7bda5756d7ec0afde524bad03e5f80a4bd76790a46bcd2556c31aef335daaa780c2533c1aa5fb2109a597326fa9a88be25f28c0b9577fef5521761802236e274c790891b4966030d08319894e6904745065e417e91d8f06722b159f21e4395143a875b2b6f48fc614fc06aab25f676c665ab98971fd28a7a9674ab15012517860b2a532fe543f50a4b467b2246efd85e32bee86dd067963edac95b2adda65a7255b7e83be377f2831c0e1a2cdf491bfc255bc417661a581ced672ff02e61c097e8103966b7ebd851a63d5d5b5266d2604bc350711df665fd82152a47c723cdd0d43b226145aae4462a233b2a8f91975c498d50a6f4f368e8501b709c0df403ae23b4f559cd57c2597f6e30b1f6047be7630b90f94f8b13b26421386b62ea16fbbfe926b7cc08aff6a216ce84b850d4b3fd2646824a3a95d26480aca8a36dfa1925578eeda4dba9bfd90fc72419c648223d259886d72e728d90cae21cf204f230c57d00be1444a891d4da82a9c9009db64c8fbfa922c205e2d51b50f4cca46ef3c19034be588d305b21d4b91dc2c806b12bfcefac96c6f5294d1d43c5c33365a0d5d21f5067c4b525e1fa20742502441b8d7595a309c7ef52f4bc96d3a4dc09e4480a67aa9ca10cbe640197bd824099448cb7a2cc6d8ed1a036c3dfed788fe64905a0d6b850002b932503eabcc1dab4695b33b48f0fbcddae3b8235333d29080ea2c1b58309c014b13dcdc2335dacffc003e98e2bb2259fef78ca1d136ee25805d9fb757a292175b0c9edd0452effb49cf3cd43aa50009e55a4919d2e1031e17ef2ca0d6d2eb660c159580b1ec821b0dc9af97603bc27611adab6fec6ddeb233ea4c5d068d1936f5e2d0632052512bfbba15e8601f5cb8534f543997d268146799abcde181ae13fe13d1b17a4785012e902f3bf43599b0e287ad3abfab70c2eb79a60d9c7c9e3856d5205b27272e16dfe157f36befeab28785309ff0c2743a36ee66b7b036c6df71c116fb4ba983f80b07817982e084700a24245f377eff62536645699e1ba3072caaffc45a7a3668c4ece26d7eeef7d7e32be0e218b89e88aabfb7a2979c0ba030ce36c47b6c0e4609315fe12b25f66f33de60cc9334a0198e00a81da412c9ad39a036e5e3f9d39b4a5b81543a7001caf176fb1964cbb1bbcdf7e096d762302baa502f0c172ae4f22bd92a969381ea476ff67ff3c96e9be48950b51fd01f3160b5156b66103b40d3274f041640e14d6579870a6bb51c5c27ef6a3f0f5260cb29982becda5fb21114533b5686df14885c36b07907e33b2462c17717f85a700d8c209fde740af48652663d4a67eb09f22322006a63a54fe50a9310cedd9d69b6ba52c1c991b8b43913d97cbe5150ba103951462140bbf02da88709af263eabd1a6db3a1036d2ed6bfb3b035c108b5df06a9b0e64f16891e11460e71707c6e0d5eff6796ae7d054a9026ae1a9daf1fd6e6f6ba780c852b7dd164711167f0fa71ede289aa7e77aab847e9b8852bca0be1e0b22201158f8ef8ed7615ef65f5bfdc3cf3b8dfe33d94a0b4976e621df81f699d0b7b61b3a1881698595a06a46fabbfa2d41ebbd7467fef258b6676fa8e89fab9103cb1505b9a4a2a532ca2c146dca4da88586ebe6b9116e7abf83f0042ba7a8393ce1d7f6ef50d443579eff34a4bd08642441f98ffa908a4adc4893a5a4cda1bd08e271a317950421be1af54ebce11f3928dba1d5c72897f896a9f11266062b5abfe3ca98be59a854 +expected_result = pass +expected_shared_secret = a0cd6965a9282d1db07120d6ca59cbc6939fc4c64c6f980db9ef85b07c047e95 + +comment = Rho leads to matrix containing zeroes +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697c6b844a5959672b08796868e7107108ca4c30a58be4ff7b37b0402697aca2dc4839dc51a8811c34c8183442711a8d055b640cd73d2caff9357bdd9ad36835ae9d55d1a291e040652d020a905027a616b3b5c63c0be2c1068e9cb0a9b4abbf346590237f96422308ba86b055872e156470b53e35b2a604bcbd2b97849446684149a86d9980c5182f1a020c32b14de18c03cd0633e303bf9f8a24ff0c95d5a65c031c18550b7d7d5b8ec672c3953bb3be0c3f13925200394aabb26090a3b9a12bde30418b997abf310c1724a88b9782418d09552a63e2855b7af2196d422761f5c8a877426976c90552bc203f5657f5370258b936c3706f074c11b3b2586391f4c4bcdd959615a819aacfb48d2c799a9abb182c7a9fda6a80ee50c4a827c9f50835b1859033629a9601b5b8b357913b6de142a501974a0c191a071a95cb8c45fa857736a93400141cc325d1b4518d3ea58a94c14f9b261759281b00213f91652b1e52bbc0c488bc0990a136e8e3b5e20f41d9f218646d43745245ca4c27770990375a9865fd5889a51a706c80945812c122ca0ee71178b4ba808bb7a28ec91ddf13affcbce77c1111f692e50f8b6f54b2694266f10c5cf411096c36aba5a292335592d975036db69a823b5ba1d003b98acaa0f6929701653058627e444b63777b6047957bcb749c889b1426b34a10783507bc5e3fa7bd75abf62fc236edb83d65061c2a7671703758b04d0ec738e1841b8256b58ac448285f1cc0495928c78166ec0a5ab8471d8d59606e375935c0211535ee2a47f051b310de23a153451f39179105997841857f7e277918b682de60ea5d70419b0a2de9c6ad708091148514e94249d45c8cb60215996abce1c86c31a780246b0bb937f26313e6fe1ccc963952352c717d303254b5c373752be849c027cb6d3c616fb52375492a4848732756247397a238cb63a6d50b9317bb939fa594c881497f92f5783951e03a3b1496cdff20e22256319405d44c9553f91018197510db2956baaab22009ab153370b25a98ec2c2645661e748ac85976872a47d9716ae7f865ed112c4c522c1825213e68978f0c1654812868c00050c7acc412aabb4a9683ca9c673e129d018a05da0105060931dba7eaee888a2b233cc567d722a447dcb880a46c640592837891d6a4770a46c267f104811ba47b19031bec2a7510933295752d2b28de55326dc71c4caa543b70372938087843bb63d74953453057a3877d2343663c058e218412db1829ed9aaf8574681bb2ff9e217e7d44b2c260b90c18a1b20c5842225a66c9afce760956b118069a4a8ba057eb204e03a85ea1701b85c71fa6ab590345140f58280121c58b42fe74922a99b8c2be04dc76c1173016b7673bf870889ce6520ec537d356c9b55d7680324517ce3066d8551f84c7ba9d70fd9f3ce485b6d1e38b5cf055b38e2b83730ca439a14b7fb7a043a390fc652f74940ec2b906a41b5304140cb5b5412f996cddb40f8ab85b087a42e6ca00a275975495678890ea6a51b6d874235b48295495e951007142b703463c934d10cc88145886c5e7b6a04dfa9b435e27c6c729941802b9b682a6587907254c5b93694de13aec3d93043e4c095e4937e9506867266ddcc601ab9a2649822824aa12846563350caec702f1b493cfce645e2a0758bd5a9e29bc3c72ba74305577c10266099bf884477ef111c6982826ad7b658e8aae4ac69a2025fca407f6b5275ec6572b0a86a16a787a413cf919a39f65074273c54d8fc548b2abd1a7c9fff406c84191a8d4c2e9916b37e652e5e83c879942a559024fc9008e8d008dd39768116b50bf4c94031cdf45cc932210711a443b4d5b1b40875924576e864335f130f2f51348333c0b6538a7efabfc8075306669e7b47cfe5758f7387526e666e93d16777895201f555ca916c5907c80cb003f6b31daa94851d0199493242a2d4ac3ebace84d04b7663a7f922bc277562d984244ab894bebabc8d8b43110b4b1b0ac3f4858be1585a94c46b24252d3bda105521b0c625979b6b251726ce2848b327d36ce3e8502ebb9e67c102c3e6250bc605d71a93e96472c9370dcc3626bac07334954bbbf280c2e84dc2e61b7ebc0035897516d75cb6cb6994a06bde802d0bf986633c0ea0f3a4854059d3e251283bbc3a19ad83902938e2b976c10611b62441f7c8d147023fa88c1803a8f4b5a8915b3454a85e66345218f6c27dec0444d4bf28a024e8d82a86cc40edda2751db4bae70045af8a450c46b49ea7ea01b70424810a5187e2057aa7ca2a36ba56cc94917535c06a827a704d3088a344125215d0b5944e5a91830a663f8a8c4f8e20c6072759290946f153422a62cefb33ab80b037b145dc4f5c49426770c103fd91539b42b52ae74a6b50c50f60650142b39cf595eb520592c0a4be0c16d4f766c29eab0edc03a9b864c19102d08458b1b94292c1915a4f191f6674723285caf177e339c7c8ec7c6b0a502e96a74db0c5102eb519814acc3a6698be62f97e82bb57535ad82cc4a8b90c2c46827ac0adb013954e959364c28e51284252466be14c2141231caeb2bcd975492e500e6c518d22a2b5cd667700bbc741c155ec81481687e4dc98a6f5b5efb9188c028c01b2c94bf858852603ba35924e1ba3fe08c50020b7d142a8bea70aa5ef57eee5ab904b4a5d1b251e93ba6d9fb955fc33e5c961289ac040f2b4af6ec2e27fd000000000000000000000000000000000000000000000000000000dc19745c0fcdbca71ddf4771a35bb3455b0f83c36c9207fa7f3c94e8a3a861fec975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = d7e07ceb0c6e77b3c5adf2682470e7a7b874f6de85bf8a43a6b08a5c9a538058b8c3bdcea97479c5ba6d7aa64a243d739c22bed27507968dbc74427bca924f61d6fb5825c5f74592dc09eabc65508ed637b8908d058790bb97f05a1636f42714e7d829177b49c8b464d0491ee9f00412c38f0a67504499d119acd85a3df5835302ac2ada18cded22f36e7a97f18643c1181bc71fc636827f9b45639744b6dd5d121c2c5651faf11e7752be2a91488fc684419d394d13fb8d8b566a2f4e72f86f6ea22b45aad8f52e2a4e0b9e4b02e216a1c2d924dcd258f84430047c2a999c7b6548edf5ff36bb14ff79534dd18c89d187dbf261db5abe5e9a4a98af5d1d8633690a18ee5ba00b8b606fafa63c9b5a4e58fc32f32f6917436f8aecffa64f70bdfac2d9e5963f0c841a9a2a40bde295a7ee21d5f84f88ad2dfb60482f5224a1ca6f4d0bfc3ff133795478f8d58dfd086ad5bd93571070865723e0cc1171e8ae93c13d565194ef6cbd40f5930c88a2e433120a1b773a9dc93daf21ee0f201fdc24752693df11c0d86115b68e31f4edf4cc672c2c1c75f45e534107317c5e353dc575ece35ae6069993999c2fd5a0ad534682edf567e1c0a960013c7abb691dee608eb269825a71de35bb3441fc422e4604ee2635f73fd3fe18c59b04b30954f81d4e8b6e63a12287dabc50c26dea93a5aee7fc00815af233c9fd510a21be7c9c0fd7276c7edb2130545c9e732980a1402aa639dc713a540fcba2d7d0c2f7058cca6d503c1d2a062ea636e78cfced18a17914394b340f7cf3d5cfdec1caad629133939f0fa0d7eb093ca8bce074716e9b5a8fa39893e1841a14294506b921e34b7680ea79fbf88328dc55b56803411e54a172585e4d119c6b42e089744fdeb34d5c3e0da9a61ff73dc9d41d5483fb7fa90f31aaae4ee2e9068f00e2fa0ed7c37722963639160ec4aef8fc076c4224745310f3514ff50fb36611eeda4b14034c84ea774f3f864dc8d43656648c514ffbb59969b573af2daaf209ce7b99d6b2ea076acd3be5ade1832b8f074e6c721218b99d64c499a26c1b33f2b293900c9d8a5b0b6380610d49ff6a55c6fb9e06640db1e0181fc39a070fb1573acb86ec8cafc0239a913727f8b1f4f58bbdd522f9106afa5ece1be2fbd5259201783c0444a95a4d04aad6fbfc3c514a4c5959191a8baee6459bf086f31204d624d7a8821ee7da353dd95179eb6dfdf95ca7571830f7459f4ce6a5237f4fdfc13e2455a3e94996c2fd08136fd44dfb23d15e9bac5ea07c270f62402cda12df927bac95647d969591b7ec8deaaedfe34f8b4731e578b1b7ad8d0386885552934f6a8f00ef304128a369e78ec7100f9118f0ffe8ad237d2851eda280b3cd2b7f46d62ee0ed52487e951592606f8cd0a2f463781bf3fd1503218d4872a18ece06c18463c075418dd4bbc514ff4013b6a49b4f3676a1654c74552dee3faf897f3695db1d3b75e3336146b78371fbbd5fc135c63bbcbe019b5faf910ea1709c24c0819e34a54f03c27f87b040e07d0f418a04d1d1a9508b70d6f0b4315f37d0daaa0839405f4b781606801b4a5b0d3b2087965e194d513ca64c310ea65192da9179a483adcd1dcbb21f389b1a515160391c1becb9d7ac34f75386c9ba4ef487b4edaebca3545a40cd3bcff1362d5d27a38993eb843bdd2c7de9e81ee87bace1bb4ac6d88a524db65289cf69c9c7be3c1882a39b8fb038ebf531ccb1538985e51b9b494b113933b1b436427bd1dde4540ffe8ab7c4c426a384fe0d9a824ed21d645cff1afe2bab0511e6dd3b0554843931ed277e378d8fa56e8454b8318447712eab10c102588ebb12b481fe8a613bc1a5def7883d0681ed90ec5f3004d04020700848885f1b5fc542fa9085641a5ac2d8b42cc9ca6a484d8c0efe93850d6896dd7a2bb15e3b36b8edffcbb9810cdcf510344070a264d32166ec55ce3764822a8da2377d50749b415077112a1353327bbf38d89a0611cf7e95d0a1a5cc6173555d3b76c13456e7e042dbe22b1123f32528953d2969a966aa37affc93472fad39949ea8db080d58a4460d6bedf80ce4b83a8eb4fe3e29cf72da59d354055a364dbf013d4ad0133fea1c690d8b68e9eb3c01b7a14bf1bf619f8f5fe2d2b3001d3a14eb07e9fba744c4ea8e4700492070bb2792c8a753251eab737267840e4f8b65a8f533aaee2de1bc20a4a2 +expected_result = pass +expected_shared_secret = c6a7a9d970bbe63973359c7c72f190080a27a02b95abd0f588fc163eba9f82bf + +comment = Rho leads to matrix containing zeroes +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe331704aa56092a4204a2293e77935390cb1d2b2924e0bb27d4aa471474fed2b6982b71a1c14b2cd3ae12b12d5d12919235caeb8aa3827c844bda40f5f57e5f59c75c86b645224b3a861eb9d9773b01cbba45122bfb1e4a60ada0fc10f133c546563661064adbf4a89117657366789cfc282f9bbdd0547029c92aced02963f8cf462326db19bdc980149ee0823ecb1d9e22a5effc6cb588b17da70789d813b749be180457e82a5c958b069551748e12bae79cbc0dfb5ecccc85f565c22eea1836b52435b023959b4f4fc12956a09f38d58836891c4c2b0b4502b012b868fb9bc0455c12e83c182f1637c05469708279b1f4af2c275e174ca5ed0a12b39849f49535b8ca73089acd5067b6b57297327c4cdddc7d5c752a5d2cb04c659d04f803c72507f5832e7bd528e903863b932d80c51e8b2833684a084c7100728ca33a4304c85b8cf7b61412e76373566c34a75ca88004cab21a3274bca1ebcbf34222e351a3df4b557f09904173065b460d54210511f4515180b3bc0a87f9125a0a91252c114654532140ab6140d7a6265c3c55223229f1520da71b88cbbaa7dc7b6f79cd6ea1062f9ca88c47b70fd5b78d5a38ea594de590b49ba0ac7b5cc2b324bfc4d26dec413467950eb7dac40f5a60f054662bb9607f8bca39fab368526ee9980498180afc1b6954cc242cb04aa8a01a37c16a805792872b2b1ec63bb4b6bec174cc28631c37953241399edae60e66074dfd9b019fe97e00ccbf5537baacfb6bed8b6d3d4cc9c3b54e006c70ec2269e5081e8bf17371757b9dd40a8f1a388d68226d46bbe0b661a2b4521d143b77e2cb2e567fce825ee9338c12f425466716e67508f7e4882229a85766079194834df17440d0a4533cbfe24b05b503c75dfc9dd4e7a067ec9901b504b5a08a9d340f9ea4b036b218ff6353d8732d08d74cbb4cc19d6123cc237e31768845c628ad754ad9f484f3c3c0587a1b9883b0abb2845fcb7a57b42493d60eb5793926acc86b1a21ffa1a790183e1ca56aac8256c98546c69523819790fd3764ea0670836078dc5105ffc04fa83c50d1e933682c54911348c8627cb6f776d6c79f4415ac0a91c46bdc68711c10b0e34770c4b2d39194f95b2215a9bd453828871789a45164e57215fd4096d9ec05054bc55e2a49206a69e4f998cfc68656840065d242ae067195a5c421db21db766b27c29fcfe530c5e311408328d1b69eb415bc4b30917f957c52c14bc1c01d3f0588dcd58565f500569c539fc67e1381ce86904bddb978467c24352032b975045747235c8932f42276e9a36ff89335d6a042699827fafa84ab12b17db956b0b55c38a1281f5a5f2d9c9104cc5af03a918a5b26fc5585f25cc8ab750c47684623dba4f609827abaa9ad668427b63e1b347f00957041b6b62509259a35542ecb99002c5d388c98e86b7697f41398a3a30aa69158171a63e3397526b6fa4c72008288bcc1c2f7d4572e449d228ba05646a946b512260b6eea7218e47642cada5a9561b867648e41c368b1796e2df7273a7208f26444871756e4d52fed089019fcb727189718f02122853c6ef21d6b3403e50c0cfd447229b3457d7cc63737c6b72c384c8ccd4fb451d82a1b49e88c90c7be28311c25e3be7160bbfc42865b9003d84c1734d44adc8b590465986089bd59f1503d888f7ac2064e03447896074a947487c2b08247328c933cc31a9d9ac828962cc0b7807554f661a7d64ac90009bce5bf00b19c579995df27401fe4bf0dcc459a8c2dac1c55e50bbf0e877abe5b658d128b7f434936e273268442e725116f946738d810119531637b65e14c9d3ef26fba358df92319598c092b936e368a3e0d8a53f438708eb47de814bc90f49c83c87a282640fc02a2f30b56f659717f6234b611b4465347bd990be4ca01e550524a164c6b97a2d64cba75c3aa35924e31d92f008b42c2f701b0d99addb39a045a8cf7ebb868822250db42408c0c0a60785c182231002b0bd9884fc89a0ad60af9699e5d0661b514291b824639517bbf267decf078e8c35dfab769845a2cac1ba4c0e513454151d942a8d4163ced994d166c144ba81b41b1b64b74220b34cd5185086a797b7738a4a6e48100ed5077c1cb4401ad5f173ae4d047da4b5977f3bed56c6c318bb2c11883aa3870b760bef4a71ebcec54b49430ef0b792ffa503947187cd382c49c130dd32797740f335703ddd9703ae163b069cc76d50aac06ab01710785fa5429f79d8cd0c6f4f8711e766796d054b8a99c7c800b4f5c4f75a329c147649a7485cb61c19c0a453a9774585856e65bc9b3d30a20094be3d2767fe0431ce85e21eb9b35d48ed5fb2c2b1c17b13a4c67b09431d7180dc04fe087c827b6a572c446dd5caf68f0b2a1d973fad4352f3a5b22ab45eae32d17a993b24200125720a1255f607a1bf79c3928230dd3443343694bf62b996c3273323997972076fa49c48f094d2e122382b36503e95729e41be8f19eb4d962828959eb56491115bbb5d279a110330b818cb4a139f2290c4771399bc041b5905531b76bf817cc283331e860ab5566b5e7023d3c6a28f0d7151d175dfb9c1c8cc01a45522d0ca6374b8718d04b77a03635ed23c4001145f586a4f252a10bccb3cde193fba4329867926ef0b1a47b8bc130431a563ca97bae83111d309167caf354cbec2e51977094bbc6cec068d339833ca9c7b6492043450792740000000000000000000000000000000000000000000000000000006d8b5ab5e1cfc312b1e6d63c84e3d91a0a378d5b924e94bf13f06c2e9f9b6dc2d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 21c66edfc81eada5da6f03b40842bc67acc6653a816c35c9279cc4b1e956c94cbeda12013dbcf99a31c8579eb911171bf6f02b95e9a75ebbd255f2bee1e78fbb1524cf32afb999b4f39e3084e15b6bd4f6aca7f8cc2228ae48362e3c069426b260e0c5efab5f260f7ace2f1d29d0d9344c56b0a2232c7ad3d0dc963dd6d6bb24d956c47f8ff0dd7c5ad88bfd888de6f81cfae46096dc35739adfba6521fee79b4d74c4e3673ef9d91d26278404af9afbf26a8d8663dd722653c993ef20fb8fcb22057539f0a756d20a4a53710b3076aa90cd7c9f6deb6cd5fdf50b320685a6fde64b3e0580edeb49b63fc0038433088deeacbdba4bde5e07a1952dad8a822e4659ef39c6e32cf5f674591b939cb17db95cd73a18f3d7b4e2305d890d3d8134e78550a06b16eb84d7214748a50297dc409e7b60638878cb6c051621277c47648dd6aae6829b23f5bd6df5925d435fb5a4eb852f2bff1701c68d451760f254ec59f7fe900839afc085adb69b6d640a98c10c49d24d75046b4fe7a945248df6be5331285c42c4d714fde6fbb83cb7cc2c435b5691abee38030da34cffd895cc8231a8b39940e55437bd2856e3adbf2e48807aec2c90452e02d51731eb5eabc223d9eb47fff0fd59480648ead1b14a380bc1a0433a14ca0d815cba125b21b00e54d60aa912ceb7f4976d2a69865377a5b884e259001626303a33c302e4878fdc75be458f1ae041213e85316836f2574394002d248159b74e127012085b3043ac53637ef55ad9941802446d5c165b336a1bdf83736358ef62efca6c3f82bf0ece3ef5a69c6817748091826fee0677995584995e2b73bcd7c185e1bc88c4fb9953f61fc8c3bf3127bb3787da572dd9d99950557120ca64a09a1855d651bb6aed9cf9f791fdcbf92a742bbafedad28112787482810ac3bf3c6c14755c9bd75ad285076e50a30a232c3f6f0d7c4efd1857c239b59552819524690f8b3b3d3ab415eb36418470565248bd10657ef4b46d2b42dd769e386275fbb4ca289fd095d33a86fcaf88cbf5a374e272221b2e771b2e7f5546dade7e11616a722d5ae62d87b9ef777039977d1448e84d385eef27ad070b39a96a610c238945b530f0b1e2ec2aaad1de6c669b60aa1afa4616659de42dcfd2b7437a5952c7601e803de19fdea2564765cdef8b10d300d4df126fd8be3b0e75dcc935352b0e942723bd302f7f74b434618941b02d7872b17be9814549e72326b6b098f7dc15b4dea4806f9c713523a6c9c4166e689fc09bce2e61eab4dfcd82d0ffc0bbac3c419b56a16739d68afbeeeeee17b561c8ed1d26c4abf375e8fbefafc9f9a039bb28e4146a2a6d7a80743c92ce938c3fedf05f2addea12a470379d152eaa1be0d997797d880cda4335d325c2a8b1f4d04afd1ce667ba24c6bb66cb361b0eb97034d6a26bf02a1fbcc8f02e865299ed5cad65dcb1a3fc71966bac09633955f4834b0d9b3222176013aeeb0030b2623bafa7c2011777a6236633a719ebd6c5aa6347c9c8545dc8110668fc5f4bcb9cf070e4da0d60933f8b064271a4b70dc03e813329e421b84ef778ad98b59dedad9b1ef3e1115343100604fcb7f95b1e448639a6a35d2c0a49eafaf18a19f5d6f3c528b6a9cc14f091b19bb57643eebe1deabedcd4a20faa1f308eb88132774091dfb4a7b17c012dc9521ba4d5a0023f284abad7570645aeb798dd23863a66d02c68a91b87ad060fe813dd9894f56511ba7b40436ee063fd67109209b3d6724e4b1dbdb445c02324474399bf144302b9bd49e73f1801304a68870ddeadbee49ba227f7edd5fd288a0b936a7ac25290aa1cc57a0b90120b8eb89bf423511564b764991750a5ecf42938e854b1e4b768c61ecc871ad4eccc18d3196e15ddf3afe4bfa59a01344289a8d19133ac3b63d4e700591a3ad63b3253f6e25705585c56fad7b965732de47fa92ecdca4f0914dc1d78caecd85b6f9a71d057493cbe9cf27fa0923f642dc94b917b7ac52184f75530951fb84d9bb189c879cd75c93895ea9a8f53ee91358351a68eb4af66a07bab5e838dba00ba447642eb3568dc472a89190a2e8204c715a0475353d177f32775b7626cc2f3430dc488a4175d1a574f7be8a7f3a5c89e6ee97a73a5797907ed8c239ac3d93e299e74d01af7651cf3cc2cc9d92000edb5b91f77abf3f5da6500e04ad76ad016371779740b9cf845581ef5 +expected_result = pass +expected_shared_secret = 784ac74e14797b27f5d98bed3d61d66a017ee9ee37a5b53038820b55b130a2af + +comment = Rho leads to matrix containing zeroes +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960116a338d74bbaeac359ab3728e268abf75a8d30b118141bbc56670dc0c5b2d05c9c2f03952338170754e20287c99177c66b810f009002c244f213891c5b980aaa23d15f413d4a80160d24e692c450b68c8c43ac60256ad748ab6aa85aeac5c623d199928f88b04ac7bad2c1249c18fe1b867a02a353a112ef71368eee3210f7082f8b216c975070e9a1a27dc265698bfe4849611716d0fa1b1f9047e8b0905d184b1fdd863377353fae732a5d0388c3c6606a773360734c9ba915d49aa7d358263d7abce563afaf382976b2ca2e1328d4aacdfd78851eb143a1b81c21713442421bb1abf77ba25d4355dd10602ce06754dd9a77aca0e25b1260e994d0fe1b83088a5d385251ad5c6a54c45d93a7d1b25cfddc1612b8b30e753814b505524a5b0b26747645c9b636543ac7a871b6a7cd3865f1d8636cb5210ae9157b567b2ebd17fe3f59b73379d086348c9806848ac3ccc1547e8964f6a1c4b532787dc8620050b7e628274683b79e133969ae154da157bbbab159941484cda4108c84aeef56afb0a389191c8b5857fae399094ca8c9af399152a87ba77181926b78f2b462c92b788ac988303cb8d2a9855497543fc09c7a49055554b9a9b6d868a31fd4922907275ca978fd0a6c3790a72b438c4203641fe2bc4f5f45f492c0abfc9267fc6660f2c4581e53d6f8b57b0d89b2cc29d97aa315fc7c9ae419f38f425c45271a29a9aa3f28f5162a92e317312f218adc92b3c46b8ab8a4c598a78da54107df7720b734f58d63064088766b06fef11a95e76b2b702b3eb0aadd0a23b66429572677304b024f34a0c07c4cc02d51186e406085a90a7352cf9ab502dcb65b24881c6a86d39c49c37f77a15b1b10bda2fba45b5c6c0025452bba0233040c11103084e95c8a51b7743fcd984594208deaa223278c12d191a060ba269eb0083c00b60daa0b8169188ec35c589652bc21da1c3c21ce5b7d6fc5eba8bbbe13216497884f09a1ef04b529805a80da578d8fb3724ecc9b861a3fb457fb47678c0809eb9e24da241900903a71ff446ec4baf09305b03ca1ea1034686f533813921d7137848e962e32563c9f80cf6f564f12999b25c4826699f06fba88234b1d51b77d5583af18868ff1c78a502b414c49319461749b91398832863821381fbcb62b589fd665b78e81297d34df7b44117464dcefc863f850ab12ab338c359ec9383e4957cdbb810e7d4c73c173c23f65ddd8bbd31305d868a496a63aea62014fe21c8ed2c80e8ba56f606a6412a9a34a98c3c0219cf054755b44515d805dbe4879c0347bad7c7cbbc08380aa297623cad5029634b025141b58169c8865c206cf7232c260cf88aa91855a581b750a1ac168fe960e5ca283a1245e0b31abdaa58031b3bd51ac295850772dc0b819cbb07c66e734597f6387ced79392594723cf39c67763e3a3c2c6a009853e510bbf91c4f4b5828a91328073683120919eca166095c7bb4bba5f13b43bc8b7a991ef855399c6019e5a7a83057982e43b099016537760956304479a4a73b57bb76153f58f51d47dc7706542b64e73e00513cd838bbc9800d6b90ca304b06a31bc493035cb1d116ae17c164f8c758f5c7be580997d155b2494e3701137ac69119e47a2f145eba891839f0baa084af96d916a9a64752d4b4586c0626836f549317e4b6bdcce1196a09761928a968a4b74b611960ea2eb34bb18a964c18fb10a15319fb9468134395fef8a40a1b144fc31aa536a473ec9f809c8fa1f74f90262fbeb0b1d980be7a2970563cac92565d6af60be699ae8e692c311692d8852c0fe0426624cd9a0a1a18961a1be613b4a9a03d275e4248809f0226179410fd190c858a41abf5446b2cc3fc1815e08149d5c81c924664e2455fabc46f108259073520446b98b697c36da1602ec8135bd053cc034ee5db4b7b58ae8b59256d93a80b69c6911b14fbb68527da6a3a29a8d1c61f4d7c21f0dab9a5b266c875610437365e2a2a4e38a2e1a8835cf7237fe1483ee01ead6aaf2fb072f9200514a9709d6b4ca51019e782aa590552fec8b5ebe40a0c99ba17c57a7a460abf5ac9a4869f11c7c1bfe8b8eb0b7618895acc88b91ce273df7353b3d083cd72501d0163abab80120a317e870c0a1751600162d633a4a4373fc988ced65b6501844da162c6a4132d8e690246898e3d2a6915ecb013661fbd763a624c8c7c1672f88347d6d28ff622427b669332aa34dc590b3244029912694721551727cc36725861959ddac230b5781ce2f9b5147bbd3b70a499c0bb34c955a1245e7cb16287f357f464aa11e44eb433b6745aad46551e90935be4c5b2ed211e818480e4b32c2af84c61aaa6c01a7e16a08761d80b221772d234c68c97a3355637e3535ffec5bad36b5214a22bed5331b5ccc55e48c4a2a76d0f68759442ca54075ae0accab8f3c9746b129a152343993bc7db74a7e027a523bad3b7cae347328d64180ad396897007a098a590d98a8fc5816aa5ba805035cbc24c685441d5c754efd879c327b56a7194b5391696f0167c0677c48bc8d3701447e052829b3de6c840ce0b7b8d95b5f46695b85037232a7356c296e854842be0a48a758d34fc0d7cc2808d7908667c77a2630ae8a52c06da9215653cf41799eeb5c517f65f6d26152a656d03a685109a955811bf05b6199be9ae97fa62ee2ac65a6354200856c6538646d47f9f974289f0ad6978cb5dea00000000000000000000000000000000000000000000000000000004248de593a7bde030c902d7afab9d96bf9675f28b7f3d93067ffd368d6a7a84a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = bada76528c6a07c80d5f8363c32338250d6ea541cf8d1177bfecbc469dfb47c28ffc75e102b25b880bdf0c8e9977f41592b24b1ccabc2e2de5f38283aa30ac51fe3b4960ab8810ae05a823b52e76f267358a56124a54fe3f8cff35dc8ef24895c83e90773733dbbbda50df879fec084be456a1250980f4ef12c78ff2b59231a944d4c4449956c635d443c92845bc747854ec6e92b0d9339684326c5adc6a07737b27a6fe207639046dbc623f531217a7d6fee0f5c8d6397d05dadcf53e43823daa7a0afceb87b718dfb46e4818f11d2c935c628ff152a0361fde8458e76475682541919b517ddcaf0eddb918c16539a8a04f81ff07827a47b5d72c92b566f4d7afd4db362c855e75dff1c0bd83bb6543332218d33e8f9e6fd38d021f961ac98525371183dbcbbd4875861d5d9cc65da0550279b8055b4bd099109e193a32b862d14faaf1534e29a4d9963e2c71eeee21b0fdf66bcca905c691cad611e4b55329a9bf8aeb55a1445fa2f6ed7782a6b3450f6aa7aaad82dd5a552f5f3d333c49f1677fb34cedcf4243cae779143fa555690402302bc47bc8d386ef9969426cb5909dc7d180a02374614b2bb46fc61988984bcb91a307c40848f7c8fb058ef2712c2bb5aa42c1027cc85f22e3ea91e59ab33cd9bdcd80de2c8ba1879ffe9a79a17948c0a27e4dea267609e96e5c84195d5b0c41178f35266df867a7d32149dedf2beee8a3f7dfa9fd91865e2a1b9e738378304884979f667055f755444c73ee53c36c21c2c9638ec9c0eb4f761a9658a494cf2213b70e9c19e5ae51a3750a34f3c78487a7736623e57e320e63162fb6f41cbe19af57aac75506d59350488368b443269b98300652412bfcf66a37ee5911d9ab94e402abc78515e5e0abe59ce7396ee77c7dfd28382494f96defd6c2d00ddc19d40f256e8656c7eee808e01dda0e04d1e13f3bcb943339934fe9ef9dc3b4a6b2d89ef7f42f9ac7a9dd446715ea4b25d14d37894ec6ed5fb8ea97a101e2a6e324989dacfc10d0634198aa65d65cd7f4e8d60021f288124a4a33bf9cf4a8e3a44c8fd44f6ff7d4fd69c645b37c5860c1f86d87c16e05e16e3e8fc84d4948f19cc8e8cce3012d94b6ee94bae5ee701d585a9af4b48c70055988235861279bbfc1663299dd6ed22a61d2542bac802ea9b0857b5afabf44008a8fd2a46d5b5f6d27be8ae9b13e4522c609f8244bf9b3049a8b49ae60445db69d72be3fa1b5d7756ba8a1fede16dc223cbe27e2d36dcf275e3e42be48a7a4a9674b71a4483d6c6b8d2dab1eb7851e089fb94fd3b18a37243828fc1f40658024200b1284c82d9e5dbbff6974d68db1c4e95532441a4deab8c2904cd5bf210dc3ba1e35073ddeb346976904062ae052c6f5edd46bcbbbae8e4197fbf8a638576618d77aa80c8d83c2365426fedbcb2c5781e08138d700ee544d07267d392b081a281408e5dfdc303dc7940c61e64aec119e0a3b1a78f7c703896d2f1d53ce7fd13245ef67d57963cb4c9231aad8464d2ca36bfa42f282234461b4023a842220c838b1fe7157223d254e0405b81536cc06a3a9f8a6f175054d31b67223fb59ca0df92c84473291e87c9b74bc5207a7fdc966dfc36e503cde19ffe7b284430a865334968c2ad1c1fbdb2951d44d18c898a26ae480f31d55b97190481d48f395e34b4571e2fa5bf83ad9b16d185f34a5b55d65ed5679775f39e63085e67217849b98b54d251b128e5c232fb3fc355a87caa3ba457cb49ee1f0ba692c875079d1cea754f6ca91d28bba83392b420135423420cb680dbeb047c45f4f7bf998c9084900448e8bcfcfcfc87a81d2b586ed4c38931175442595ffb4088ae657e66636c07fb47bf2abd0e32b3d979b1f32c2b3516b9831a57136e4783dfc081dcf8e3666544f2e3f9af6d85b2588811f3335c1260092af225572ac7722ec3a3c00f987b4ded3d1a9d278cc6151ba936fa02d66ff76ea12913db49830283890ce5b87ecb6270d71418d9c213206db87b116eb58eab2530a1bb97ff7d57546d83b32e4b351e3da6c619670974722b6d006e3c288b3a6f684b1db98938bc864433506e67de883749a3c052165720a833dbc412556ea35c437a582588d94eab42f5f7cf9f841f839c7cad07017634e70940453213638d9efed5503def0076eac37c82ecb46b194bd22c6e7db7bff4d5d75e188518d6479fcd34dda34eb70252f +expected_result = pass +expected_shared_secret = fa3ccb03eda9e8299be919496cb2581d3127472eb062a8f2447241f6b4a66d02 + +comment = Rho leads to matrix containing zeroes +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3969fec41d1311ed2545f5281a09df223bc4918e55551ec060dbfeb41c777c79acb7375215002d9afa37b5a126625f7445c3fb51233650037e070648c924586bf7013c203e907332901ff722c35c1991acb2da41cacad4b709ee242a9e71eeb0ca1d05595fcea8d175553ce689ba595b8f98707a68a4d20f8a1fca8c34c3482e88c8b043a9d42e4a9e55a6cdd867e106b271031355bdc71c85c80713c0ef7c3ba3bbb9ad4e32615a2b104e52dc5e7481e258351385f9c8932a074529e327e6c0949756b57ef47094e184517819d459bbe35ac6154a70d004490b03803e58c9bbcdcbcd8451c2b0373656373be77a59beb2d47410d8a8631745653a02956dd0a0fe99ca87d78c273230667f25bddf3a65a216921a12844b8c98c197026e14638a97fa5144b44189621f00c75857fca20342a09ac44a4aa6c336d9ae58a15972f22555139e2b3e00ac0bf67b15d64ca8ae77a79b44e5b47a72ea06930aa9695b96987aa0dfbe63d83a352c9370247f6b21f225e096480b17333009bb785824641306126c5792a30b2ce4856623898d79ba97c3076e54100eb7029df333b5190cb28a8207a557cf78cb88c11b241da951ea96dbeccc90029845c7c8071f584095923266964179910a64c835045922fd520535b35869a147616970424835e913ad8382faae3b756aa51d65306c6b6760cc3aaeb7958b531293e6a6daf0382db834fc7e16811643692ba162db4266e3b2af1dc9227aa7edb2a545b8785e425bbd982cbec02514924844da57e3740881ae68d9c104afc33a8c27782c658bbbff5ab1da73ae2ba267326ad3ad61183e792075033b448a36ab3bd8e8429f9cabd5e3a57f45464487871a02bca6752311d607701b89aac021649f37ccac9a455017495129a45a6b24f07726c0b633c7a333a2c589967c85e7376929205d6291a74335a89381a4b851bf758cfc069be95847da5d6258123bdbae08fe0b39d55c11044d1c8a6d70421333ebd91bec10b73532a6c00e090027b3480e796e69209bfea7f3945350747af2534234fb0801ce11c73b934391b0f7c6574d8c8c8086151f8817bb2082724c733d44837fc7c24355c463bdc0365b8a0a2b15f63ab15f42c6635a40c6d8a502d5000a6b7158a16cbca964363a4c7f9da5d51c2289d7342d885bcfca1123c324e36273fce5c4be83c343e84914ac382fff92869dc11fe80824de3b745e68f55bbc979a0759a35cd91a75a7c649bbf7999d8726134d75691dc7d25b23cb5d16f0d505e6e145f84a4644536827ff982b5b9326324132edb30e02a611aecb749685069baade2545d758aba6c5220bb244e08d01235faa1fd5a0cc4612139466d6ab26093a22c428252bf8491a6794728ecaf421286c2ac5f4117b16d145977c4232f8564fcc5996de99b71f896b5d828105c593fa43ebaa2cd74712d769814d490aa7e2140f942b6e86b734c32bc79187f6275b9da3bc621ab152c8a6148a9327a549727ba02a9a1465b3b9a32d7cf6984c610691061e9c8a55badc65503158bb637ca4c55775649caac535c345a443b27e88e3b0c435dc33aebd5087635be061a37f3a0715c37b0b351681614bae36460c5a34eb7e763af22955167b85542519700511c843e56476f0a977a5a720aef292e0ff94d726a958a63cca8665fc9a943d235a569da3e2a4b5964d457df1243771504fd26527b94aba0e8b547207861b8cfb79bc6abe3054184922d477840a4c221b420af50608a265eb508a651dacdbad403484b59ef9a819466c66c458d172622609065a424024811b26b61b74b8c0adb179d2dbb7cf4e336677132052b1b7a6c6eadf63a15b484a3240c7bb1c9e1160dd6832c727044c012936ea43eee4ba721c489d6b8a6fcc2bcd3c3ac8121455c845978364148bbc9498542ac093a4d1b7a6a666d0276adb218315afb4683d6956459833915862e18056f7c02f9a492388a1fc65c5211e7742cc656bf2a82cc727fe3516288986da5e4b74ed8abda8084aa90285a86a275f8a18fa99934e73f88f42aa6ea3428b6a9d936af53438e51423a9222b81ce7b27d7b015ff06ef98ac62843703b9828f4a0c71a603b591888df2339c8c5b8922a2ba8ea1a85a6163d5205824056176b2cb150bb544667635788338919c21578faf64ca0c980e5a554f1935410b36b5f29b110121c35424cf52cbceb53134f7569594b0677db53f97b570f842a1d27c3e0971343baa872bb2453799b1e5b433a2361d2f1931c185f13cbc0a0e1ab1fb310f4664d8a49289d15433742aa439483d8789a25c2ae77a3689a17807fd544ff4c7d022c42ec9049e683472b490bc7dc8c9766983e32a2620a611da65583479fdb7670d329c33d51af50dc3234e63bfc1306913c66c587b9e3a23143824e84227505b0b34a3399746554bc6037f87b84b0a7a41da3b366578fd6d79cc9a03d34a227e8095b9bca636ae01988dc2dd67722a5db934c7009f812a985598e7e309cd7015d24a5b36cab65e8f91c233474e1473fef76828f2b245231605d079b308a732553600b549314784690d5ab5830c36d824b68881d6a440696d3938f328bd755cb833a8af037a4bf8241c5d9aba41540a015aa0b110410a05e104881f5e41471e70029a9c42ed2aa4e3a5012a7aca6db06b7a847ae624ff7e941ee18bcfce68c58a8c47db56bcbf60701858e26943cffa53661c180a3ba0bfb25524bd60000000000000000000000000000000000000000000000000000006f9b4142950d620669a33b7668565a96eca6eb4d6e843758c2afc1371df63bca53f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = ef250a35ec80dbfe58ffbc7f7f0a97ee1e77dbbb601ef38a8599fe1c50621a7fafb3c2f42b8dc17058d2c5cbf965d1dc6e45fe0f033b1e42326d024ec27eddd00f4af75ae389b6e2b95076862e11c63136698eaae4a9735ddad9613af997976cfae920dc0a08b9bdbcfe7fb168d5712c7d372fa29a656adeefb3cdf8775cbf38ae0134bc024dcbff32ff2575911a98bc19e7ba3b8fa7e5a1df85bbb4bda21427195206a07a1f8ca8b2550fbb9724df204be3cd5f3231da0211d79900cea59a6e394915d208eadba3feb264964e269bbcae99bf7d8caeefc00976687ed7ba1a693008aca00f0e9641293f75fff8e7169e6e149e6695003c544b946898f466a0cfe7a2ec2b531e771094787c75c05712b6b27e55f1fd3ee3bf4230c05059d83eaaa2ddbd4e9fbdc8fd4e694f17a5a634daaae4c125e1373e8103a1feb119a5a6bbbe7d722427182e867e6bf051653d28ba59f68d52271a29bd109b4b55bef30940bdffe931cca17e2add03a2e808c4c2b09cc4978cd89c078abbd1b3a0919421c0e86f1294f07f5c9ae8c6f66369702aece6f1a368dac179a64aac92d445c9a606103b48e2778237178e407de8d576e5931d123caba6f99bbe158ad4878c5dc78bce1c519f5690b12b5421607d5819d36c5bded5a23c46578e564b1c341e47953b80db58830ccbf40edfebd6bd92b99cda2c62c0d3117f5e84f9f7b8dd6871d045c4cb287e689e865a9d1d1f0b0feeab1ff86adcd1952261d94a994869d33cd083e28f158b918f22f0b8a1fc4cc79d800c38ed0d9f746c3b506e6ccd58224886083cee785b1b1ab19eba46e706e8e89abfa36ded66bb7a180250202dea8366b4695434c81f02e0ab5c4cd40451cf5242fe95af132191a89d653550cb76505cf5792efa6c8f074801ee54ae10a36d75160891fc2a670f1f7f1cd628645980376999d86aec88d3ab55a06d987ee62ab7feffee85f8dd7bb925e3a60c8b4c63dea64777e3dfd19eff0c42371820aa81e451b50e6183e762798270a20e94f11efa43ae958f283e05d20faea378d9e94f57c32c47755c400c4a6f17a94e28ccc0455726e309d1b65d920b185ec129088071f557cbaa3372c9bc56d16ad33fb592d8af9076920ede91e6ce659f76b6f8dee15b1ca5a5ef9e5b20e7a136db652c095c883a5cc638a79fe5dea351a485ca8ac83373dea459073528d138da4eb895cd201d88b8c1dafd0d344a430495632e82044b4bfa73237857b5bb2e260a6bb2c7583fb49826ec08cbdf60128677ff1f0c44aa55901b5b9c4eaa6defabd1f6633ecab01cc0a79229ebc22c7451d81846844d229fa74c0f9da3bbd8135630f2311341929c146e7221af95c8f569858f113f32773a8d3cd10f71bb962364279a023518daf7e9a53778c228dcbdab239917a4f963dd221b00a940dc1a1aab798820aba5005b7d80cc84c18e91b6087c7c966015cbb22c30ba409e5fd93d4bd843b35572a8a629e9e2713659ce0b893f1c995f1e61d502b50a62f166f2f3bbefbb534ac139580fd56acfbd232dc507065830377cfecd3bbb377b72450fb615c7971acf1548a2abc79fce191d1be1acc15a8102b50923a8e596537eafdae404d546a90e444e47e04aa6a7d529ce6c74710ea4f8140b3bf7fd8a468aa8b96445b413c9bb19d057bde4ceb98a537f736c9deebcdedfc58c9d5ebdbcdd975b762a20d6264016cfb8bcb57ffc4bad83a5b997ba6263ff34270c10eaf932f85f5cf10cc2ddeb3344ba5dd654eebd67008c3161e4c9f79680c375b2e8b031bbd1293e22323abea7bb04f9eae988c8a9a9d9e7f27cb1f87eeeb5151566e8d22db6389119d33cfae07f1bbaf14a48f0c082e325f2e8d397bcf3a676666e7c2edc85727da4729c1d15b4b820853ef49434372ec50c8d207ff252cefe875f5971a6b102b661d150a782e55019d9761728b752e208bd740fd148e9ed06d872ebfde0489315c46a62ebc6c0a5ff5cd57eadec362a2d8cf87492f557abce463e100e6df8981573e54358c3996209b8758dffea3847eccb6aeeb5c3c5471167e1aeaf6f9a660cd281ed06ff4fa11cc88e04b162e72222c4fac1081a9f991be6c4ca4b1ae02de3b514692b8c144ddf40720c1e1394b38c879c382861bb2285a28975c26a6c1fb4e542794a8e654faf918f79ebba577c5cedf72431ba7d18cdb0da6e90edc2cdb85175fffe80dbe7 +expected_result = pass +expected_shared_secret = cc0c70663e64be7264620b5682f2506f2084b66faf8e8d3916c8b77fafa924dd + +comment = Rho leads to matrix containing zeroes +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d74933a0cba383545cf629d357aa8927a7bd4f6575059485fd455be7198fc01a509920f6c0b8c5a565b4b86c084a60bd9b9b6037727df67b83ae06c5e47aba5d263ce83808f40a378aa43b4ec5458b33a0eac8c816abf5bf76a1220a99205258cc4a9236b4dc252cbbe8884e8ebc1fe921ed408582182b273a199d121153ec38b7f183174754f66332ca98b87a31672720815ff7bcd0cdac810db905ea76e6496742d26b2989b201fbc2936f5a6cd60c35e757f8c33b75277560ab948bab2962df9c38c91b44f08090e5585d852c4b729c52de88fd8c54722162f2d7696946c7b710079500136a28b9abf9a5c0294a5b265865cb04f9796b648f85858f8982f15c2bf31626b236b2c3a6493910be2cc8610829d96693cce3686b8a63b91439118fa661729462ce58e5e28b764aa39911569d1ca5c1b33885400a16f169858930c7f135ab6a95d08ccc70d057f9e73a4c8ca2da7185df37c8a6f727893bb6db74329cccc4692589128867cbaf28694fa747e86cf98619e99b221db88a81afa73b348582fb1b863185bc7a3bd95b15f041c8e3aab5b08d6c32cac121cf003161c05c64b1d90074090605731b5c6c465675ad846cd99cf3fa08f7aa45448fb2fc802529bd69e95d1a21e98242c66266290bfbbb2ba58fb320d660e297ac416b2b0d1c5968b53a95172450598ba30b96472d14522513caf0332c8eb8f846bba02870ac989594f9141d56813a68aa5cc43666202038c29621eb658911027663aa0155262cd86798079a257621ab73a8489fc531f41c1483582a1c92cbc6b329fd09913b1a6c5fa0b3f7116a9866290d4b321cb639f544b0db81a6177212b798f911b0786849b17259232ea74a9963a85d90aa8636a9f4746f7b8ce423a374039907591a54a503f9298b486e907f2d93d1a2868a1d47608a6aad83c1ce7d216dc0283ad56426d7b5cdfba794ffbc3654235501c960b8c9613eb6126d1929c55c1e7cb8cffb180e0d942e199b4bd51721465ba8de1cabb081f1f55218a86cbf6b7ae038421b5278f2d8086041480ea9898880a84ad25ba631b83e953598bc76ec9b36b92a76359fa1e44209139272fb0c9c5c5f0af6a0cac4d4529d18b8070e76b8b173085c12d84bb2bc4eab464a161f5ea69e0318d3719249d112cabf827ef4a4a7c813d384b62c02c608c0b49dfdbb6f34c4ca8db3dd19142e5c53e3d17010f931d0f9c8657551deeb53516149b459238657295cb5c66dd6466f9c1ab7b711ad985a93a46b94f2aa2030405f0b013e12bbd380a6ed98840c1f484ed5c5ef9401880f646f424c052f20278139fecc3a3dfeb7c3cf99979f8b8c6c77eb4d20d9deabcb0648fd07bce67738800a2415f3722595c4267f7a743f5562b1a26ac168602a84b6864bfdc770ebd792543455055a6055117cdbbb6cbec340b69493c7f0648ece7119b8bcadc3282e5a8b0a21b1898fb20781c298ccb750eab8bc9abb3330276639bafc2d9c00315c690593c67896b83d63356e81cd4624c4f39591cac40ac49425af7a5058a651eb4800094b0a32778ebc025910b0e69450cd0657c296c986fc9559b1c3d0a605754b266f0f28a8d5470155906331693e425896a7644d6f340b0ecb4cd2268b536b54a38431e69852d7c443ef97db319879d1b7147411db40a0d7ce7cd358463d8c5be972ba5add85b4f6a47b6e59b58312dc0500457a1a578c93ca9356354834599c41a2853c53d6739be379b9c669e7ff7460a29a2e5126e90902b22a29446b3275dec3d891852c3d3175d8bb3526466a662a163095b8c3587fac94dfb78cf1f3968ba9888f790cd8d7338b2c0b55c12a91a32381fb2427227aa66935cb0a07575c726ba16c92275370fb849aa548967a1077cd2801b858111761230544184883ce385541acb0033f0a5bfbc6779506f7f0063fd5b3136232302b46fbef8c94cf384fe50a97d24a67608bab6299d1de88189b612a43b897c612e9f44a0451588ce9c319b9107fa3c1188986869fa0fa43c248c91c4ba5ca3bbe31c3fe4a5c3147914234aca96b0a58c52288b174aaa5c9b156bff3ace0604aab391411204714ed067e03b38b6654dff57354a311653c40e70017df6b3bb2813a19bd2b128a5001a38a7698386e7f5ba1eac57e183034133cc83a152bbf0b321dc5a4cab8cad524eec35783e93956cd59e1755773f321ae6427b53c33cc91c920448bd7734b57672c9744164b22c9bd0c6258dcbc5fe22b947f6bce1b156967b65b1910c0c57b3076148a627a74f5a42342cca8d757cbf227adba4cb954a562ecc9557c45b76e83a88f9472ba8a4c6a0b670952f173c85e0d033ed74a48445670830c493c8c89b321b26a1c87db34707e5a21bc7644bfac385690fbbb63db72b2de6f684c68b494a461d62f19d0580bca25a878e5077e8617f69c446da1ca1ca81adbc8a6a4055b0bbd2138be99617c9463c873b7a0a8d13f8c228663730171c19462fdf02a164ccce14e53c8cf3baac96af911b328eea6e89d91bfdac72fbb1846e6b071bf7929d486363bb66cdc24e5fc93965e3ccc6f5ac2692087eeb884ed6206c924c0b1952da48a84d919805a7bbbdfc578dfc08020b0ef5e4a49d013a66ab449ed91c3f8390b2f2a7461123ee3b6cbf965e71b824c808ce142995fbfb6f9b0213b0b83c330281a26cac93f94f32c30bc22a13ea8337497b408a0ba3aabbb1c7c48225cc0000000000000000000000000000000000000000000000000000008003f87b0144661a918f149e2341343a53918b5bae7c9ca7ce36d3ebd0d4e1cce366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = b9cc6d4403baa088e562753c1a21c66f1e9ec19efde0365ee8e696bcf2d1e68ff6acde8394205be0269f2cb9bdb974660c8041dea23912b0a154dbd31792e2495b4cfdd1c772b12398b279ae755af3c525c700620e8a30d9bd54a062d8f64b029dfeea3d13ef53f820b71c911eada200b3f90d019a6430d382c187228cd85dd229ec0dc125b0643709486535907d69d11ecfa15b9be98674e3e49c25510b889052d0f53dc225def026fd7ea783093f16463ae4b4f0e1ddac026cd9e00db7b168fe0b9e3a87db01185ff52443ee1cd51a89ffdee88f476de7641b31e44446d8db73991a6b491017ccf55bcef6d6d2b6be1f69f789c545fe233e09da0d5137727b4e7b437c57a12dcfd26fdbe8ded090630ad6be805aba4c4230daedc645616cce15662491117feab609c89d61e0d7bdca2660d7f36dac259e4a100efc4130870f0c2bcf64137b43b7695a1a8790b365aa3ced0738c9e1d170860dfd3229145818ce8cc786e60b1d3b159fdb9dd8af4a2c8002b24c30be007233eb5fffce3ece5f8fef18286851f89b0d741cc2bcb4f8099e5d7c31034d7a3634eb7503b93fc9135c2774127ea1d30261037bb18061fa97fd44adb8fe69ba85e520f3930ce991d74ab849d0af667b6984b398e6b392648b0272045889df3f1f47a17361ef2afa15fc15acab23d4541519f0a8de6d9a82dc3daebcb242706dba34408e4fef0fb03ac7be98b331c9969e738e2e4b4ede9ce70f59ebebd3b9afa9224623aed04721688f8332b1a214c2c8f39f76ba631591f9fb162d867cca0c65041ab7d4ad9355210084813d8beec36783a2f0456074e35d43014d44d8254970f8e279b5e2d7762e7a51937f32b50eb140ad9ceb23bd8101e0e9edc34c579249bff46251139eb54ce0e533ea720c4bf3ff7a73793d83d94c4e2fb17745c18df2ef1109ab6561dc91669600d046dd1e9d6ee68b6fa5b16fb2bff887f4aff76e5bfa6f2352da18312080b62f09322211b54e7ac1a382ab2de1b6e2b2bc0bf15ed700415ef319405fc5946bbece863dcb0728ffbbebba11ca578293f0a1886f53460685e778abe01bf1df7d8babe44bd48b0cc6f69e1d4389e77049694221008b73a8da2761ed862d0127d8ba8f6e4f7d3057c3e32059ab1bb762038ffca50fcf2693d78127b2a65c335905e1fd6deaa5bbd14b350b8afe18c00cc0d4a4271401fe78cda6b89c6381e566c69bc5922bb6a43c10968d754703b5602c93e6f21b1b7432170ea5e62eb4e0c0abe6f6a3317b19e19b5763f8bfbf74f4a910e5d271062fa79fa9682baa5fd0b9db3a5f2a069fdd10aade60a618dffe2ffb2a89bab137cfb73e92a774f57606a30080cb1bdcba5dc6536e70b745161017639187a7a495e93fdc48bc24bc565f603484127ccf13f74130b8466973548b1157709c9d6ddf672efbee69a4223f164f8309cee7d9660a323f834bead26a7cf668fc3e033b68c7abf3ed0e4109ec9e263efd07b3b1bb0ab26899067971158d0cd9ff7f91eedea7c4b7e88728a1177087653bd6517d11c490d9dffefa52d4f09284921edc23b5230c109d3697c881121db8b85e1fb7c2b9cd2fb48db52f18a51374b7e4a6220e8a50d82809c6666b5ae854c2848bf5881cf834ee44171d26b0c0296477b4299b38af261f9ca6620b57fcf276ec790e47b778cadf00fede43d03e70d6518cfbd6581fcf84e81aeb3bba3bc7ab26e562b65e1599d4e8ee7a23992c5039d612855c90dba4c90cd3231d01ed150b8226a95cb87867a2358f11890914a2016c78ffbd31e7ddfb1dd97f2e0e01e3010d6633952d7c16c1755594868702215cd917b315a54f35f92f52bad10b3a7e54df657dd7e168eb8119b28507cac71867180e0914d39b8441b3c5c20ac22ffcb0ca2b201e4b350debd73a0c08b37fcd13a3957d96476d31d26153e7b4bfbb826f7ddd5b2a7d29183a579f05fb36d459026963ed9a694fbbd9b3ac3c5e2be41336b48ff5af60d9c6030dc13981585426d3a0a946b5008ff5cb3fbaae3bc491f536dd80e747f5df92270ba40502409d9b24307d775f4ef7c9c06dca69cb5dfb4d0fb890a816a7b50bebd1ae9e55ced79dc36bcfe04ab83fb2f94e10910f0086e0b5bcac717c5bc73f5e03f09ec94c3bfe05d732fcfe0d6baef66064cdb02b49eb5d938d2b9bb077b5426905865b170590f8ae3a50f823c9f56fd3b390fea9 +expected_result = pass +expected_shared_secret = 5772134d07e1befd82268588f722bcbc7c131d7bac8921fd55d7bf5201074bf3 + +comment = Rho leads to non invertable matrix +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca62e0b7d8cc8d1d861dd052bd9bb622cd8b769551c2307c82aedc92accc3d2c67c3ecf8341290af6c93a295fc027895809a081aaaf3cd0131174c8605c7fc29ece47036866f7fc326f7c947f70852356410e22700b5480897f288dba24c494685ecfbb624bc189dca10d9307595969145b21ef4ca1c435b3d39555434e133f8ec8c00dc49f02788041a6deae40ad5c9a3198804fde6230dc25b7f86a86bc00b43da73b5b40e3943096fa4540a019817881b4421961e293250056300e273f3d87153765ec237a79a16ba89a960fe42aa887c65fae65719766c44b2b8a0e54e97aab5febb1c194939e11928258cbcad6281cd37ad6033b1c9982df721200e36cb70326403422519f3afc3451af15969c2b26957c452fb136db18357516617892214c758cd9b556a827434c9510a5f6094bd32c8633966eb113f9e4902b6306c87732b96542979159ab49a170fe71a23093c1aca70202287d8288fc2f56072ec7aefa293015b6a58a2899ed79d4a09701ba42d26c599d8a2164204563fb90ff7372e86d0a6739947e5cb25b2b10d9573429894601c1891ba3c78f2814e1273c8d2098f19172853b3b590487397692ecd3b6e37f58875b60167fc208e6b813e0b26e1b42b7af60a64aabfc156346c78a225738983a03253d679437504740b872128949d971c619031b51090f54abf0ba2cec479a671d43ddb33c430c8056fa37768f8551ffac4682cbc4755267f7736c3c97002356edd676e0f26c2c0f80bbb04c26a09bc337bcdeb68bf25d183dacc4d17cc68cb8b967b31692b2b6a035c69460bb202937d7ca92cd87651bd7804a1d24826c3be2232310db3cb08ba900ebc4f5bc4052dea72e272596f6373b97aab10e8b9ef713550d9cfd3610432b6710130ab394830bdd4129e0232263bcddccb1dcf9a4f023865f24bad1080c207e02af3b56f2eb1356ae45466a61905807a5156958782b02ee86f69dc3ae5e2b23b8a01e6e30471a7c85eb18216d751645a893ea169f661230d1887e77256a4944004b8415a3bb554e436ed2004f30a19c6099a573ba752f2527e59b00ff8943cc65caf4ac07721c702e05d5ab2970ae55ba7f8a1335aafd7542630f933dc7420cd054bbae009645231a1362c74252e649844f413ac83e544578903c310af5660cbf3e4c4e1b4917eb2a0a8bac4be184341629d0c9b3b1cf38b936828abc520a3c13333c0c2c1c35185028bf1f791fc24a1ba12c49b252ce82c16085623984368269b6dce933410f5b6bf61c13388bfdd87c0b547690d3cb2910b05707865f9ac3c1872a7cde62d2ca43fc391af8328bb5c853c1f1cc06c165394874405734746874a84b2261b5032bf586fe9939a0ccc980724759582669f646406097270e2cc1371b0b6d81e575b5170760004f593a0c377c59b1705bba52eac083cc597a2d03510e8a0bee8c5e39546f193cd8e4083a3683602cb1ddae257b1c1bfc409942d2abac0586e63f3721b4bb921e135759b1efff0306105a71275388ad69c75c5056fdb443e3c708a8a107ba0cae4955e2ae7a310d97a6063690e5c8ba84891e0a9c62eb983578ac0c6a56b710a2d63305d931293ed42887284904c3cc4e1418a9c77b8158916bd028f1272518c0917b7f4b457fb09a31b63bcc9278b529cc98c4351436e02e30b639562c14131f4e7903136157269235508a7aba15519f911fe061d9bdb7b63dc91539428bf1c72861305deb39ee8e226cff39e448a9cd7e50589f85430655d0d027405d991cf1c2aefa28d83d5c7ec8994cdf39ed49b5cef917c55f0136a1a9d8cb38715cc0785d5cf5f9c5db452798348c70c52b5fd89a7fab54b75d22c6958af84bacb21621694d492fb90b71c787e9fac0ac9e3c710739d67598b8dd6428bc2ae26218eedcc4d9015363f8acd9ff043d0f7105bc7c75eb9c376da757f1b9aa2378da73a7a6e4571eda670b8287f4a333412a9c94ca39bba9759bca1c2e4649bae51b1cc10913e0cafc8575629ac866a729674772a16660c1aa53a77f002e4136455da31ec28121a7577150cb3fa0ca2c0d8b6985543d7f90eabf2bf4b85a3efeac5d0b28f70e93dd08073a5529b41ba4e2c736fe3e0192794b00fba1d429498560b2eddb788ac274c06f43ba9da341fc52cb2f5755ce3c1af65027c143f106b587a1b6f18201d9c3b0f19e4b005076834d7830911c449aa913dc6a3ef31c208d014b41ca6ef1b12a796be561b006630c14c03504f87c600ddc20c6477b5b02c5bd337f56a9423f516812a594fd4b2e794442bc8057899aae012c320b64eccda7681274adb72101ec41f99d63648763158323c753b0acec97d96cac9dd35924ba1c0555b09a3ea95d513b138a444bee8608c7ac1e64240d15028cae552855c47beb0c9f6f10cb4a3b9f68c3552a301b6a8cfb9487c241964c4e167e2c1b158a6b1a7c303c0e38fa7e0c53b376b5ee5222cb574d72734e7e90b531aa4ec656160f5a23f6b3bb2e3c72a453f73ac96ebdb128dbb8442b5c7ea842fba805799c811afebaa4bda82b559c624322aabf5a3910a152d5b8402f33ca0176fa5600b8d358d6f5956fe6171cb841ccde5bc76a27550878b5e065364139cb891065467c630d8a8ec6a002626c25c8aa00bba4be3c2305f0b1b18e79dd1a8475d2001324c898c0a43075a7c06697c2ec6baa4d78258e60297081869503b7084aa73756b74776af98b0000000000000000000000000000000000000000000000000000008956b47f0597a8f2c9a115f32c5a1177f8ead69dfddf58fcae3c35bb7d71181211536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = a64e4169d49c70374a2c237a33ac42503c6ddc7239c53aed99ed033992435ad443153362ad3c9cbdb576fea6b87ae15bac3f70c457f5e84bd387f358dde9c5a904db99386d2f5cfdb29454c978a89083c9095b2a2ea1fbe220ed78cf34747528e7559c6b6f6eb168e878046afb0526bef2f966fc80a863ed6e138d6ef2272ff9dd49201d746f82db8122247a3921a058fa62a03f259284177d518538972fb8e3d83c4644c8ca3377801c719f55277894e1d2170719782c6b136b7612eace3f903cd5c5a98f001b2c8e351b0a3f24d48df4b3f639b749c3771d38dfb69c586c44477195853255fd8d36cdcb867c8d4033e5d48a9bae96ce2d839311a5620af3dc42d35126f222b9552e1c36ab21c461cbc7ecfc6eecab244cad16ed8b48cc056ae98b4a0b93c1db5b5976a40a4b5bf58ab01c2a32e045f3db5c5ac00d3d04718c796895a2690b126120222a786520de726b43fa40eaed49f7e86dbae56c7c1d782254277f438db81e56236535b36a1c02c54dfb3974d1ac1f6c814e2fb890fb3c1364d1544e87aef84e3ee3e47e6ee32160393f9610c5ab33ab9e1b49aee4bc8c91bdcf79fd831fb651dd80bd0cd9cc439c811b736337b5ac64d61e6eb1abda5dc67e694f2350a92422faeb7774755fb8bafd5c091b634d229ebae35e3bf93c6f1d79f54c7cb6cb249a589a6dad72a4551b32e1463dce1f50e636b60b70648b81ea9febcf79a3fc8ff35ccafedb3bfd48fccef6e6fa5bfcb44a2fda45ce7df150b9639a9615a936ba1c2fe0c6f2f660cc820b414da22a3dbf9e8139ab3a0c5c0946dbba66a02e2c5febc88d46e6f79d0e669e60fc8f6df1d346aa9caf90c16505886b48a0c6fb41883c93b6e8d307b97f1ae01e5e4af5b9be506dc4a8bea249f50141accce764e85e9121a7cd087b26f5d248113ac7b97517d575bb505fe6048df915fb5e0cf304d636d4767042c609ac823d9d2812b9cdf4207bfb3bd477ec047c1987162e250d2bb57791d1b84b4341bf55f0f93afd75abbc90cbb23e47dde24583d1acb6720e1722231f9b103b0a7d454182b6eec57eb1e4a64fe7c92133302c22d941a0b17e86adc350b47650cc7a1a953b78fb1a80aa44735b3623d2da25ed5691065a467ef15a3dda917d80c1d47f2542a0afc383e75b0e955ca530d61df1aac8da5f1ed8297a6b5fcf950f6cff8521a7096ec2391669742087139cb5665cdf525c7c8f157af19779156beb2fd39c34ac614d2b0a91d87b050f64aeaff74bd894d3a68c1a52da47a42ba04d06debc14d9d82e9bd94aeede4a35b6bee9732bae0f76e9d07f742a430441b9d8af5edfc290a6f30050841c5921084d7df1ecbf8b70637090cfa784d5214839977eba9ca94f3432f47bbc4d60c465edfc7a931e7f569da5e6b4dda05913f7fb67263cd939b15d7a8f7c0d15b2c9c50dfee128ab50821b3fb9b724b643a9464b0ca38d51c751d8d4fe5e378339c9f68d51a245fc0ae76ba14d9539a90e3174199f503231d7bbed22f977b37a34596cc8a3207b852d6b09e254d7aea868b29c6506881644f493eb41875d6c51218b7d79f7f1202c0ae747694403da054128aaab773e092c04a2c34f4a73fba19d99df3a81e4e60c1635f0b34b0a5fd7d0e5a5a236033fea303e819da88131223fee2064e5981d596d30ccd7b744e183bbbb58bbc7c84d4ca59cbe1f52e2739fac45fcd0a706a1123584167946169c3494ac911a02deeea2b487f5d57c4429210cf812f90eacadb7d51ac65a6dc49f9e51ac3b4650bda7966eec378df60e5c98723bcf7cd63d65a93569be54d17a54df9502f9b6b9f6deb46acc37da4451883f7ca49d4075d045296012b6f2584c972c087bf948fe7d9f0fb561dfd91c3e64f8190ba77202331e5988aa9d5df9499eee4119fadbe2b5530233d6873bac60c5da33f4f0de0262eea35b2041c3864731c3a3fcd9aadadd6eadfa55249dbb5a8b63d4c6f69ecfaa9dcdd293b7e85a3062b53e7350141ff7f6d622a1f4978ffbe22bad117aeaa425568cea246d0da900568c70a412fcca2fecd427d14d59ed0867b6905adff8cb33bbf33743378d4a2d0ccbf79e721d22d4c1a9921e296640639a5dcecd93a1ef94a06b25af0628a32647127c10c504f77ea6ecd31c2a035e8baf3fbb1434c59d28d25221c6d71cd063e3d6000130ba62163566e2f8ace8e2031a530787c4c9b25856 +expected_result = pass +expected_shared_secret = bb7c4b5d4fe3d2e310f176eda060f614672dd307e94766a8043b914e9f3e5c25 + +comment = Rho leads to non invertable matrix +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc8cb39ba3237b6f13c80ef947630578d2d213f1914f94c61429bcaea77c646f1b99d35ac8009907ccf604c1211ddaeccc2f1001b49776df94560e5ac35e0a7ee3f39377e252d83558d6e57651b0b3c0365e6a133dbe3002270a0bfdc524e5d298b42c1408e17d155c82d69c256f78a69937843491153ec2117ac40370934d28783a69d0a02526afaa8600d289c27e9481cb737cdc4b9ddf53caf313b3c4b862b08045dc38428b126622d77ff3864fa93919427b049786042d234429e9858ce7b1d57a2fe92979851b9d4ca23fa7a80aa4738c9b777020b857b8fa2e442522423608d51b78c574569b9746e441bed403ac21391fe327818dc81355bcb2f5758320965e10946cda9a7c1d329f7c1720857c8751e57b87186e8dc21199e3b7ffc1c4c5607cc3c258a30163131c5db5d96e2e8c2f209419d5a03dfc618a53b1799cf102348b89ba289fab2b206f61688fd974023619fa5187b8cb28be778b666294bf029d7fa9abe3ea739f131930a13629bb6fa7221a788591f595911d3c8a6625a08eb82cca6371fcf0392e359ee7d96badf47a3a46aca01aa9ee8816ed4939a8da1c7a6cc0c78a2c74dcc482aa9b0f27234d1a418b994fcdd4864ec208e423b97c98ad541878794770730c4e1662ac60a1140a6aa9fe425fcf9098cf9592725712fd995a952a73b0f8c4c312a1ba498d3bd9c742cb7f011216bc816e6cb13324c17a060361b01551692a7456a46c76c994ed067d102947f674b918e5c924c86a5e6172b0f1ad8e7336409cbe7b16afbc48aadfc4a77bc22ea467a2cdc9350313af150a9eea3775a78b45d743afbb33bf2ae2bebb19b800eb18e59a74d79197d8e36f74790645e77d2ec46a5df081bff73ecd31c0cbab6275710206fab518230aa749cd4f5099a304017e937a264010620b80f1d0c7244480736ccc623c8a2d7938de85411d7acb1ea00cc8298d85a5443ee058505b5aa3d88ffb3900567a31a9b25a3082035f5c037e571aa832672a74961e51290cfb0b55843229d11213d18feec5a35ff2160480887ff03c16c5a35e367fb6f5561ea266e973928e3b1304d13b3924be68855cebdc8bd0c3511503ab8e50c828b04ef2934c41207c725c8f1d589956e259a9f3120d6392851469b7fa49b8452389eb2de3497586ab043448c14a13310ab5b352a740bd486e31f0655dd472dc3b3208d06a79cb0dceca7c2efc8cee019c023232342810e3448b5d019859da0ee25526b81422f884438547386c3c38dd707e9ae18b27838556d2398b827dcbac8344c7cea904640f9608c82b4b86d27b3f4ca4882c6da694bc78bbaa08c900abb62379eb00f2ba692b167264802d47d74ab3671620194555b8249857996a25bf8b44892914cce1433685ab210f92253e00a355b96d6716af32e6629cb26771f57c4ea7cc80476d3af5a851f191f35ab646961780e35d6ff449e3b258b57375c8a43718f05262c274344c95ad251ae8619cc6714efa12ac9999b085390fb684c03028615063ae5f472962d49dbe7a65e248152bc73476026cab06733fb57182c9c539553b223b31adc966c8e41cb0e9847236c38ca67c13966c915a9b04088c72d15ad221950e65309a2bad8a58693168b5e7d7be403137f4130f8e911aed444c84e469f98228a55a2c2c22c0061861d866aacad343ba3590145424ae886b52c862cd0036eebb6fd1e33cdc957e2370ae8b42c2c7eab508540a72698810533bdd7a1739e88255e86c8752974986bf36d889fc172d9c434ef3d079697204b778117f1acb520c63462c07679347c4604c78f5acc99cc58c245490250c811bcec2d2184cac261263581769044a232dce38c6802c359e154119c4874fd95bcaa5a67eb4c8c3a5104f15962a725e5ac34e0dd363f5aa667a22268afc4c382a7968017331f4cafa6b76999640283ab672985a27dca0d39c4b7ab102fef1863b06b67d9bc01b8040e1156468960f1213b365d2ab2a877468851fb627b1ed7154c6b83e7f62ccd65ac410e8c97adcc6e37c3b5d7893efd6b2a0b995aaa9171391292aba405b051f5125c8978a15fc479a55ac296d7c278ce5a3724535c91209e1e90cb113423d27845c95aa1258afc49a43532ab873f2a6d967796421a8da73cb2acb14c3981bcab14d1c7647735b25de0ba346bb61acdb8be7f513ce561adea73d19c34d41d12499e8a843943bd21610e3749cddb25d0fe0959f8c0559f774d5ba347c30430684b7535302e4daa90535840cfc9263fb126d23cbe85a43404050eae4badd99a0a1c24e1a2b4df41c8a8593a6763b31a4642830e797541b3ffac28bd7b7a496053fb1e0b4002433dfd705251900a636b7cbe3858874bb9585715bbcbb74dc992f4a5636fa62c2a56989529f7de46bf10845e9e9c03d282261715c7b7c97b4786387411cfe36565c2159903959444c68a0726fbc5a13468714b92cc3f953966fc3bdc3cb1f606a5548e4bbabe2755c56a35664394fec77d9f0646ac5736903a537d29bc6e905bfb5650cea3a5ae0145605c0d81191fba11da630b5c6c866cd09681ff16950b495b9aa6843141236b079ec67cca7c554fba14e534bca50590c1bf40ad5403a1c12578337b55a684038d4046f2c8d4be864c2025cf182592871909e824c24815fe1e206e37001022ab475481c56464a1d258997887c49a052b43108f6b7b8b50271eba002c3d881b4025cdd3b000000000000000000000000000000000000000000000000000000aeda4ee0487346c360ba29019b2937a8010621827eba9d49bc43daa9d25a94552e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = 2c2a21b05890062fab5c11d3d55b8e032fbb07ff61ba147998ad1a4d200fd8fb17defce7723b268150ba8ce7a4d9a3548538e2606377e91658440e10b048c8c4e42289a17f398a664986dbe522ba68f42b14f40f25be762aea2049c9444dfbddfe416c04ca7139471f185a441a515e0d08fa24991e9f02d37520749499266d2d5980f35356c86dab927c39d9276aa745f4f9d1cb33c386faaf84ab03a67e42fccc7eee3818254b7799bf445a491b1f4bc64de499ac4171def329cc94f0c4b0ffcd6ccf9b140c776993ce1a0241d8113c67d852c24a0e4e070ccdbada47e953cf65146087476d1b0dc53c039427f1ad7b466304a4f4b2757f661bae492960f667ac439e3d8d4595d7da06367e69015df630a7292b0dbfcbe2629808ca08e3ade11185ded915fb0f5c599417d2d2c9fe742db9535ce90e49d2e70cb83b29490de8db042530e16d3d35b488ab1693ab4d9642740394fcf6b34d74ed47a16cd2e6dfa80a94eb1261ee6391687ba0bd60ec124cb1c3785c2143b48b6ae5c2a109169a974599daf0c682e1bd74c7fe7b3b76fbd5347750755195f73af0a5ddc35c7415302f34f331fd976a84426c3f1b0bdbbd0fca925e7b2e9f78e77571c761f896ed51b66bd9d8d4dcdb5a8d28c382f322dca57bbf1bd6a4131f162f4d8c0983a0140a3bca10d947efd93774edb8b4d0cab98e83ca40a327d68c8cf5fe4b48583d04612bf65e61f00a4a56a63fadeb321a033ad5f7b65540d74ffd144495ccfdfcd4afa7739811590e4d7357a9f80732cd0ca6355c31eba16fc0671de573de5c73d43999477bf383e35387db6b9e236850cc5a286d5a93e9906b6c53bbb822a43a59a3b47676d30d4c8c4665d73fb275ca0dd493afb80aae9e503518ad8c7cd5486ac10ee2ed63913fa20c4e3ad6231b39ce07256f0e8ab72a8281db22ff9f8c2c655209ccddaccc1752f63b1967b218a872a36f84f5fa46064173f44f4a0133771abf6183923eb11b7676ef55726f62689b4695fa39130718c21145dbb8979566dcde5197bc3ed8381e4bdbbb881998a60a772811c50babd1f7811def20ce5fe1937a28ca433116d6c85d5e8046c7b7640ce5b7ce5e3c11e13c2afcf6c20a633abf9e4b3d6323b71acae281ba73d00d9da20292fd6e6042dcfe154f22b308e78ac3decac8afec89ff500534e6e789459b42358221b37e180d3e0aad911d35d381732682c2b5a50f29d41e7b21f7958ace59f56fc1ae6de40bc26a78ab022b5998c324340e95aa424677d2cfec90ec8785339d20859687272bdb581b29ed49a5463be54770a17ab25214806e9acdcd650d9007f4075659271c3b288c9a6a8a7e8291103d2b750c7c088637a733fbddc39cf0f0a9dd6d9dfa6102d12c5dedefd12ca43e43e807635993be1495c18be1c90f3a620074b86655c40b904c1bd97526d7b70364a2af22ae002844c6741ea35263f08d6be51a6f1c039b52dc08c89b45db2c4091c55b3ea13f28494dc0c131aefda9d3b111cbd1df48eb51f68db738d31e73b03799a57bbbff09a0018ee684b6502422edbb80022498ef6e26065bf5ac7e4992766fef1548bbe43ee1cf9335fdd154a6731cddb9d50165d28a62774f23a8f4cfb381a71e488cebb6eb4f23d97a6f6e3dadfd0ab3e146d0873738f1e3f9ac9f6ac38ad1566dd5d33e263cae86e9162bfaf0de296cbd8508ce6e1d553ec6d8915e69ecd0d460a9d839f66aca1481bb17938c25e6c1839ccfa09e5660452b4de60ba32d3492d2e321236fa62e00f56f9284c1cd2c994e503a69aafadf18e631f5d36890cacf5950364dc8d4f564352df1da0ef6d7749108c27d63f4de76e0805db07b70f35adc2be0cca552bf5211cff3cce4ed17fdbff7351577c14344fc4aea63a3e659d615f80388b2c7d1b75ee007138f76a42a82f8bd948a06cb6d8c2f9d0999063e5dee458e0d18b861c4e298c8a61bdc11d54a3c2a3b50da518bcc39db9252f4298c878d2882248cef7b7b600c455efc13bb3f0f0d16380c86272db86f988465611f208f7d1b3e2987bf60a432428a0fb810d29c1c7ab3ffab55819cd168454603c7292efc59fd7164ba2c53f9bfced9c3da9a4dc9a9f48def429489a5742147c79a3b7f2be6d20a2db79dc808e0f56a721c31b1df888bd19acd89b273f169984109b381a1e449778d768aca994bf8e9740b0dbfc1654e2a7c14e95fe5 +expected_result = pass +expected_shared_secret = fe71e2b85d231f4abf082d4f7ca86f042ba259b24a14a934d79cace53cc10b89 + +comment = Rho leads to non invertable matrix +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca584a4780ea352e9dc85393457e71ca62e85abb2322aa45c4fb3d29b15d55a027b8a74186000b9a05550b2a343a3ac21b0f7a2b2aaf736a1ca49df5b61fa749266b0696ad7b6c48b0dc82803b10a4b64d6caebb33a13c60effd699ad44c1985c9e3f8ab21a0cbd728ab52e07c4bc5ab3f6c698ea307f435bb7b5545c44758fee3b9077b5a318c2b584012cc9b57560236be789bc4b026d1f26a857365b2d1a6e809a9f71e140ec56c4db3829b74539a90345841483daf6840141100c66cbe057261fc346ab8c36b03cc2b2ac838835cd373836bca05d9f57ce2231980ea1bd9908111e79b602572ab37495e9f6025269713f4318dc472d06b473268bcc7c5cb956b5a1ebf419aa18b9d6f184849240470607fdf6325ed561c270b095079734fb61e04c531be893c2621c5ba48bc897868126b995e75777c8ceb100c67556484b71404be802ded5299cc41a83b0c7a99c8d36d55f7fdb4697c446904c2420d667f5e58e0837778ea960bb6605890b8437f24f7d35acbccc41acfcbf2e35270ab368480813ee095bdea49d18f360a690b145d96b0ac56ad8007ffecb7cd198a9f6178add5535e863471cd5198c565b62d912fd3a9040828ac9834ea753c0d77b5f23637e5891a92fe7508b672deaf212c2711137915249b50ed9bbc2f7e804536b382d3a29b6132337e68d363903aa84b08a989f2482c56418b59dd351c54b0b89ba5266d354b91b2fdbf26812b19c79a12224b723bf0b0e6967bb1413cd439789058091ef95c62852075e464f717ab84db9b28b23934f625f08d0a05541a5866343a04216dfe83ea37abac6e273ebf649f7e391df2829ad2aa45e634dfee00fb465bc2b7658b36556e7c813d2e4a92eac6c2b84c8b3ac8d13bc4dec0615199b63860ba29172bd8ee51080071553489e850b1d8026a898c0941ac62fcea1cc83bc02fcaa3b5e76938ff96c3c682fef30c320d3a325d633f16888613550c120b9631235281c6f531b19f8ac1958eb531d11a857843c02e37347c13d8a216c1456a9405111d7e00d0ec2bba81b0a4062908883a3f7e088ffa10118352646964be2ca3ba2f6a4843b836d538c042c693ba928fa1651521894a7f83311476faf50add5952aecf663686a07ac302d5ca15e16baab85230e077acc0ef4b36de2613a1c210fa7c7c37188f1685f067403d4babd15925c470b8559e8abd4db4cf965b845f22156515ce54643f9ec9645c53c5c830344f6c7c537c87f2b6c70938c58139fa6e2237b03aff94b48abb8441d8b0d4c108bd6f4114f98c22c412b0d559a25c0845a68bf6266b7b9e17d80dc6c3631ab0620c0582b0705cc686bd267e8309ad1e33ab0bba9fcb21b13e7c455887d07a83d34d836cec3907026911d799653ac0298fc1bcba7c941823fcc88bdb39541cf989bcf08a0468451bef079a627cd31855667e97e3eeca47e2839ae32bf112b71af0003a42523390bbddb71cb1531264113b990ca286f689a3c660496f68c5d68247677262eb36b7b26ce6807459d7c7dc5e4782964122bd96d1b5b8ed9105ad2e72050d874ca1b09b7bbaec0107c1abc025a557206446745ec8d462a83e6a53c5ec6c0b8133054745762b5b4bd142a1e2c2471a81ee35cbad7d6200924cc367c3a3c55032631418cb6a3124200209a782e2a0036ab9723f511fae105049579bf1051b9b41d388609cbb81dd1191b857699d04486e018779a4011471a241fa9401f9009c90a14ac6a5b691bca69c3c5df7b45a7e77267f1082f0418a8d14bcdc29bbf48758af83cc9331e3fb34a49a2570f75562d0bb7213c230a549498751b2cf0bee4561546907f2aa436f6060bd74c3b06a7812fcbc63523a451b90b4c7386cb5614a97a146637c38cfb77ee1316d0ab981b4874a9d263185908fbfb1aaf9b9939fa2d3d552bfd577de94264740ba291ca4c0f732263617dd8d7bdfbe80797c68932664e414c8ced3a48f5287dddb04655b76cac5ab725763264cbc95dbc2ad7976eb5508482389e6bebb358097c79f2b3f5f6a0249881fa6b932e6906816038f239992fa23e3f1814003c48cbe3542825ac45a00d1c104d76424fac824478471c0349cc7fe5ceeb21c5bcd1c262154fda607fa811aec08856b444544366a62a57860e71b742b61de0f129009924af08a92799213b933739a3a81e7a65002596da271bb19675c02302a0a2cb2d928318c365cef3b828a362166b9a6eda5bb7e610a5e22afdd390c6c5a0e6f955d1740e8fb41347a62abe59752ee6ab13f78b4a3c3fc0f70de4a46d276333d5b51f139cce889ab9e18643f9a18be7349a319913ec923233311d1473b37f39185d872a9547b1702cb096526a8596127411bd1e611d51816198b95bff68bac6538149163330814d4d34a84cf2c174c96b21787348c037ca48aed72b22ebb24afa3924dbe43a36f50f55f3bc5ef41125d400eaac4376daacd71398dee37e84fc007f93b245ab0842015cd26671ab840f74831954d9886e2513c8d752ba15943945109b601f051146824181f258417cb393e8761fed36c5fe36590a589ad52675a9b2c05a1565cf54453c7781d01709ac331e5fc454bf222d4f70517f80afe7d90038987df37990a0a42095a517979a0fbd994fac3a42568687b20c8d4857321edb8c320682638c55c4a352d2e843b52278f78953a617b08b271b4fec05109278ffa5b74856188cdb6e30e800000000000000000000000000000000000000000000000000000049ed9ddc17d39eaa0ccc036cfbc33590cc2879b83448a701412909421ff0eee75ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = ad2de30126428ed97dc602f7d15fa00dbee9bdeace6b9fd7579ecd9c015fae9d9d752b0a56fdbc997528f554879ae42c40259eb4f0d289ad7898ce21b45d0f84981eba7a48df5be7b6c3b07675d5f4c241c04281781e80a9baaf183570f47eda8e535a39f8e8dc562b28c1cf2b24118d87f5c528ba93cd5f4757e23a2a9ded44295ee1e706444e62a94e04df3fe4d2e6e77f77ec87de4527f20f93c62939e08b0bea1a8862f01f7a884de4f77f7f32b6ea6fab67635699f2b19eac1d1c4902432e1f2851bb35fb1e3a1ab79bf2d2589d34eaa4294c4305090b12e3625ee42c8f2e6a6a0ff86eb4439b4fb3371ef04b61f5b7d75217ddd16dea7977ee763f07da3cc3eff2ecea8d4734b8cf67e4f95874fa14ae397854810ab1b593f7eaec2e87650b11079d5eba756ba7282f1bc735e9dda89ab226148552a0a6bf67436149a2d79e1212da11ef87da910ba69e1499314f3cf90fbb4c04730cea5fb1e5d35eb1f522e09590522d6294f212c223249f8f7ff82f3707875e66621235c464a7564df4e0a825311cd915e6ebb0834f6f8a709636ca137a32d405550d97f9dc1e8b970394003fddccaaa1e98185d3dd354f3f390a5e6ef9d293e45ceed7be1583c983eaa6f9489a994ace30441b252c375cd448ff4c7059f6db14d1c65d14c4a6b1696381144bfed51a55827db14584f54eac1073031d7b282fc5a48eca5b164429d9bbf46803cb079924c971aacb0bacf3e58637b813b15794029740f06fef8d80ab7013041f3b11e04df8c6737bbe842c8271d584e5c84fa01870c9ff001864176c967d8aa39d6f3585ab0b0959e37ac8e9cb06e3bea1083c2053cae238c6cf55e9b6052592ac075900eca92404af4a174a2cdb94e202c31807cb5bee36fa4e6e6f67ad4eb5d60a2edaa101408a8e16df3f3ca8cd6e2239b079d70b5dba53a42cc594d595160a3ffae9f16121383ba5b778397518095a4a92d26eadce6840acad84610db923b5583024a5fa682a3e224c5b081a75d9903a870642151329befb6c7f83d5ff8c0001303e7349fdedc44067f894023dbf61557394bae481cd25bb48ae7785db5457a90fb1644f16b9aec60baf5095d4182b10eb12f680b37b779619f59108b055c7e7d0e33f2ef4a8911ac876dead82cba65def0c3015274d14891d1f726f3397f0ddec9929189f7d5498b41799f6a4cb8289744a9ef7d9c620b28ef6cbe88188111a5ca0c5a320c47bf7c12fc1cec6a3dad012f073966ab62ef5fd71a7dd05d774c322c8163b18a6461fb321d77fb26ea2afcc9a7b30bacf3d6bdea1daf3312192632b9a5a5f3938d42f3e7b5b48b4b58d915fd8bc63eb5135e5a617a333a21839e47d7f61e6d206ad88332c1fb55b71369e63d76e9bbf8e7cccee4307db753533b61b7fa2edd1a2fd434ae1ef841c87f6250dfe40d8c045e47f9b93abedea1c4ffafbd0d61499652e3b636e0b6dc559bd3db9b764e4d46c35f2434f23ff3628e9b4c30a65d485d29a57f5a400aac8df42593b33833fd138408e63fcd8f4f1fbd189c05d651065473a88c9e259029f752848d07f80954af01e8cb70ba019e902260a612c24bd8af1e484b280449f335bce1a32878a0af01641bab8901ce362ddf2dc31a2ce8aad03e8931a427b07fa2688114feee300302d193b05db582ea6c1c68c7c4e405e72607dd4df28c905ee38f5dbb6b0eee1864712a1489c974764bf7e79d5520d2695025a04173049057b54c23a3d2b9e4367f6ffc7be4bb3642b7fcbc639614c3e479bf755c343bbb925c7e7336d567eb051479521319be75831191c8321a5a887611fd8353463f245f91c396fb0b5e495dde71b124c875dcae8fb4d597bb84f9045c17949692963aef558be7260973589ca0760fa7980c85498946f90c719adeda096e111ac8b3a215084af549f4d61f8253f4acae2894c7e880111c1bf01124bfcf829ecf809b67b08bfc3fd9c8afc04c330fd67df9a07f2b92f19b56bdd5c621b62ff1b55d7dd0ba5235e72d5e88014c16016178975c14d4b105909e547dfa6486043025e55bcea08dce175cc10bca8c56abbfa688984504f5176a12d975a99d49c30ddc265f1f251bde72ae16b36d9ec61640c4728415521872967a6521acd50faef7d198e78e33e0585a14280ecb2a9f8a75744491d90616ee35b34f50ddf9800dd80bb39fa9e7b523bb03760550ede1a90aaa775 +expected_result = pass +expected_shared_secret = 365bb81ed68c6ebaaa58a3633b096874485c19fccd8661cb2ba8c2634efd0fca + +comment = Rho leads to non invertable matrix +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5dc9ba816e19d8a177de33a855960b7c464cfd51a7279a48c80091ec357b9fd118e12f00736036fa8268079754a4d565773f2a5d5c913109a4606a276d07372eb96474c7722d85a17a50a956b3ca8132415b2c404a0288aadb44fbb00217c0005ee36137768c3d4169d300ab2876c1b2a92c0cf119fef5018bf7acfd2031929b9671898c64388898fb74a483a100ce2ae67275e53b00d94c2888f831a286631450308aea2580fc5cdbae53b7108a9d3cba88a437a5c0917dfa3bd7fb2266f2b2f57f52724b67e58cc2781a95191f60a34d74199102b5fe941874a4433034ae6c9aff9e2bf16f01781d72424508835e3a587903eefeb0b0d218e11183cc7293c81c09cb5fc4eaba4cdf22284206b23b87566da704665527c6c587aa3070b01e79094747a87ebb2b9e5296a2405528c224ef45ee6fcaf0c537fa2e2479d579d71a3400793188d895323f274077416f94c4e68811ad9c73598d7ccd53bcd18f8b1cca8bb5591298132258f4210d36722217c2fc5925330d03d1c037cc7d520f52b770231538782738a75b631f992d3d74842714f03c31164843609092942715aa4227254a57fa5325e39e2763ca679ce680c528b162d18a3b60c6485e4aff926895b4982a64c40b28484a32979d849b380ba867d355ad55a148f811625bc1427c917379239203cb59230460c880754234453779eb7032ffb3b98071546e3300a63f39cf4ec0dba9018c4470c63e920ee79c000f57fdbf504bdf709b70c82ccf3c7f351b2b35a9b94582f61455b8f24bd43f1148b91a123076562e53b23fac78dc4ac6d257b3e882842382b30437e5c208fc7dc15a0eb4948e902a8f13192d401887c4f01a4924248af31db0892ba9dddd6704b6c696870bb87257a0e357d0c908995b0789079c414a0424855c47dd73becca7b13b029afeab7a7860220e4cefb361edc19c961fc2b24d4311803727e5c0669aa5228e907f6394768e7a3af5068b1b7a0bba9a2aa195ae052233e92ba6382548dc201a5d1c9bcc70f1f50694f56277703138787b34f63b407125d402369eae548d12353220b50e36583d9b0b6b33b8f38a8b7c0f20a4c7561d6c80ddca37d2e709263a54b4abb4577800705f068f21b8a4b44cbf4e3c4dabb1e78865c1fea7064f6534b1c1e7d088dfb37c4b5d362f6d19d90db7b9804cc0b5b02a3f091cd073722c82d0113bb64ab2762411cfd91353a8838ff39c2b1da1fc41353d4f02a66dc28930b9aa96088489c6a83822664679457f9868a0ab58f34bc16cc6fc8672e1f35a21891246bb201dff207148b08f02c7bb707a150084b93c44c021ca3d56735744070d0b26d3958c87218accaa424ba20c3522a6e17b5b99a26650c410d6042cefe6493c660c954484a6fab528d034da0d5a92200ab2c36262f074ba54432dd7054d348ce54fbca9e88043d3b63f8193ce57b770f05079c3946f9c33c2c9285422756b3653b4a876618773de5c7b0f2b019dd7c23f39759cec53e95aa0b87609f0ac794632849e5bc76c1619be9688067d93cb87b1f51337f45bc9ae8386d7c98b88cb0b96c583b010656e7f017e972c812635115335af17c2c3518346407c94e25c628002652e2cb88fb0779427fad957d394999c0c369447b06c095381bc909d93a5e0e0c087d71965e296a489ca5a542a41a99529592167e2bc1dda7bda1c5026ea15cdb4bae4b7500f0b1aaac059f0ff8381897c4f3a144728a2ff12453feda091503bf603b16e406288dd89be4884e4f86baf722269475c874b1133de17ce1d51b694c7df5b9a87f19c2648170de3552c7990f68ca7e16a913b6697b5f848c6c2a92a9967d7bd180b74839e233389bd334c80c7772071d84460c509c092462cc1e4072f8a3297558784b68c7359c0adfac975ee4798d26c719e25c16e47850d11569866e3d610c0de0c68e2886e2675f7f59791f4568eb60583a28ac8ff2430bab6e5fc07f1637a59be1cb9b33c93b3ca98674492203a9e9514ef5da006854037b4b4c2a1ac6ea6587d208b505d206f04c7a8df119774657eb549992002bfa75b480fb576d3a0484d695f6fc56dde369154c5509f346c501c12a699354c14478ba95601239a2c48217219013fc51eaba658d4a5662e469b6547f74eb29c10c296d1172d1b0c75df4b2459cae31b33d7e9164025478c75586e25730550216c549ad05c3660459a2653397d60c27b342a5b51836fb1a33bb8bc9cd622af6632245e49c5b129307942eff7c3157b2180112843a61376dec7f6294029a441683a996fa538bcd07a35585558ee09123b7c3f6291ff04cbfb5d9a85607cb086bcd36f3c0a8854bd0f58cfcd5a1f4c51bcb41bf0138c8c7e29d7c43a1b4538f318532b8f30351967efc26a7a683967d770f3c21ad3dc85b7da94c64ec6e66d83f01490ad6ac3567c81b55941ed45a6ed4b2c87f473f900891b5c69d5092087559407cfb5e9c2aa18b491d6ec7424aec12675aa6230303521bab27303244ca2716e83b212783cab442c909c8760ac2d341a24df63315ea42726912fcbc0187d520d70022eb6872c8b1158a804ac86893ac7741e2118bf721c5225853a8e056c0d963dc0b2500147b0f632fbd27594656866167c5bb28994833ac2031bf4998597f6c1da7a0a3d70c3d3b01cfe6a87ab57419491140ae9c4eec0b4bd91a1946233f3cf88a1ae27acc03cb551294ae5ab7606431923b000000000000000000000000000000000000000000000000000000bca466cad40e9531e154b5f4cc77b7b4a5557f7e36b9863c0ca186d8785119a58bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 5afa8807bc581062978485432085e6af37c06780538bd96f798f641949ba3793cb496b51fc455413e47586d44e379daa9058a4bbd2e329e7083db3c99074287a3958682fe1c94c88d175296b78e880eeb27bdd5b550bad0577e9b24ea5f3148ad58ab81a1bd1b63a24c0ebd31f2198cbbb819eae7d30eb8ab49b08451b4eb4c16d1dbdbbc1da5933c284c2b1cf37d9d92af41ff4ebc78f4418c6b9077a4888a3b516fafdad71a517df1b8818c29accb9536f9b0998c3a973b91c87a57a04d48d5f8332a67720f92c8692e8b2eec3fd62dec973b815a18a33e721617110e636301b737ac3268252920c578e18c50b8517c34b38117fbcd282392c14a61dfd30b5e15e10f05fff96f15359a73b8c29ffc44233ae49856da73426bc84305f83e540ecce3eb1c386572fdf2bbc18163c2dff137c05754a43e50d5103c0d7b4cde47457d64dd2cf1b1edf208e225fccd89a47831a7aeb0d1ea313d2dcffcb730532fe151a2ff28c1dcd8212a10dfaa0a6668e3c66c67e20290b285411f9c9ca55c36369b11548048687282e6bd9abe13f4b621a2545d50f530544602626d524306a97be439004d670414bf69f07cde6d82576533fd01fc9e8d8d40eba682f88f228151d5a87097a8ae33ab845d523f709eab85835278d8c9ff1ba2fa639f61726267b033bdc355c5e4b844fce265936e7cc009a99caaa3c76c4d73ce84264b15d1eb3359ff7e8ea4752bf3cd2c9365ec3f5b8fade92e7c1768814b0566bf3a2633b0f8ddbae1da24af6b42bc80a28e9bc1b601ae1addb0d1ed1666fcc9bb3e9fa8ca2dcfa7bd53c96ff0732a00bb1fbafd01b239796d658437c5a42297c2ef395edcf90a521a2ac2a852d329c95e9c9dac1be1948777f794c8e5c5728d4ec2c95036bd7b8aa5a272add19f5c10fc8171fb027956cd3c9e1039795bf6514310d4c2dec7e363320e481a33179ba5930fb20fb351ba3f4c6b72985f12a43d133530a8122e4bf9774e62e064eacf8266803769fb991cce898cf03457241d2bd7f7d104ea07615d8be80f3c2e86b015be16a7e0d0015f69ce1841ebe279233d661209495a728dbc6949650168148227ac08f88a57f3b3b45b7f99552467076ddcddea388994b2d9e4ad91a384ef053b2f7b5f0815d23c3a5c1de5751173353f88b9b4d8f2cd6335f736a646e370ca66fb911525299a5ee382dd49c2b34b654ae7f5b4ac07ba6af9f3b903407eba86dcbda9113fcd00ec8edc4873ddfc54adede668df06968ce5f63335f3834d6172d40d0a7086c9d3e68dac3efd25bd08d4a72b0e19455696c45f1a8f5ae0356cc86e0712aaf8c32393161ba47e519c8fadc19db8f4db41651c1fa90b800172b41fcb88f8bf6843c0503a1451177303f5269e804a73b5ec0b45e46522fe1f939c2f1b4b0fb6568206524990809edfd450e9412e76498109b7b349379aebd5cd6cc9a3c57c7eab0f57ad011f2599ee74f75ba208a1cdfe7a52a67b9a1af206013d28d01f8b4a5680735c8c6adbc3af20063441d5c4a6a6395da2e97151e92da944494c639638d6c2f1d5849ade57c75138a462d3a97adaa4599db5cea3f03a89e4f6c02a874f09768c5c38cce9e8dbc7c4ec5fd6de36f7a06267199ade0e03a2b9c8fe1bb38e4aaea819d9bc2d9a2023372d264231bee7da2f6b853f3441348e9875aa784162c9def07ac747135f445b7645e713e3467856f35fb4179b01ebf0baaf840f4b56681a537afeaf1c9a6f86fe6a9ba6a3f4300d222b9811d4d61f03a8edd7d2a4c1554587bf1e82f97a25dd5b3fa145ca4d92660023734ba7242470b7d784284002e3e4ff3b1fa12a50c159cafc3446747f57c860c7d1755273f9ba906f8568a650a9dd4cc2a31502be833fbaea86bfd4c13a2bc8b713d68c6cd0d6b0ae7ef14dd58fc68c558cdd337318365289c7e5da57bb63422e431d86b5e7e47b71a3d2340c619f0598f5af80e97a0be519d38b03c826ba8f87fcc4b13f8827baa22c46598861351595f8274688919c972b884882026ab739692f9758d12e5597b8e3f5da9cb5a7d903bd8030dc468b2c4b66416dc56ff18c20c78f018d7102bdbbdc9189cba86f9eb1f57b6211f9569cd34737478f6946a2fc2f34da0573db8968690d9ed0dbb2cb6bffaab6d8b28eecd6220c067e1ae1c5e4c8eb2ba179dd4c56860f6f38f5ed3f0fcbf7e7e67f5c92bb9db439b4dffbc +expected_result = pass +expected_shared_secret = ad8e3f1d0b1d2640a6f879f697c81f353f8e5fe17d0d09bd5d21c068b0720147 + +comment = Rho leads to non invertable matrix +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00dfa8bb9d8c58e33260020a33fc04021baba0f6375ddee4a6023846a2dc73eb69758edc915ab2446b1c59fed89bbb86a9be2242c117cb719274873c8b0a2857e4076b3a792965011675c23deb8bc0cf7b2e3ee38493461f8a2068bcd899f1822dfbe8444a612f9fbacbf87a0d45f98a541c5141b230be12763a3563f5d47e369b65c10254e5f63934a05c8ab3409d7b4207dc423d537abd4404a9ec6afb1cbb529619bee740a4c71efc952b3b871043c24c0c919f74f508bc23a9c1ea8b76ac449e28379af42bb6140d376c9a4ec76b34042c7d711efb559c8c87170662788b4cc907e4882d4332d90c43175cc56eb943d589a30a5ac1ae312aeb8432a1d7b2f7448fe0f48ad069989e908d28616530246f8e817aecf6ae638acd7030a596d5be06964eeada35f6175bc0d20c26636943f1609eba3b8852531f083a576231c9b222a9f96ab1fb79aa0149155881fae91adf26c4f1e463f6f603511311351c6c1d1832f482306d66a4a2e585b7e223bd539fc45c5b29558e3110cc268356edf4bd0bb7ab955a1d1ea4113173c05093259a84c8f055148d301f1c72c9eb2ac6e03b8ec47b955fa429b138ab9762705ef19cc3d4019947c53eb361b8a6798ef219ecd086464641a642660bc0086bf97691e81d178007731511bc632097e08453fa02e8a2cbe9e858a20835b8090f56119bbc000c69f0ce0fe49c4e80b41e040f3f3c84388c6eb5ccac37b19420139e19f88b0b99214d06ce660b844b0604b49222e46136539c7084260ad0786a9b790d76c5132068ad6d1763c0207392760de1631783d21c2459c8189c3099245de001aef30a5bea95609759141e8458c3e660aeea2a3f721d15302e46e1a92d213d1ed16168f71e9b21b5fbd62355fc8e696c71eab7cbeee9258dfa4c1b876583f56c6bf37f770aa7c3e317f50ab01a7bc9f7a31d8babb0c9d2083821343d6990e50a06a33985af449c29340b89a59192b37a2a7aa3fad830725aae61c52b5932a2d9eccc98612997a2b76cb70094e62f4c97279c2044eb5b624097c4f2d6a6232b526b582c9897a9ac734096d88639fc4adf548bc9f8905a4a4d13aca80e952aca037cf71151042429a6f30e3f67802055b217900f748844ddfc987623b27e21c869c16396a57da38938625b9298d66d1da767810860df4768f9c26cffd4b0fe4693cbeb321ea69243fc0e0da0948e5c9ad676c058826b9c263c4587b104350e29fbbc9dd91e876b40396a67fe874177dc5013a18c9c1195cf92436c03b0e06b86c7773b0ec37aadaa7bab6214bd296ee820b86d4026a5b13bb0d79df7497d1d27194f3450bf38b9ae7a18aae876de5b74fac93afd26750b9817df000b89c113ae700102fcaecbb2a0f52035c6753be93ccb6e51c6627ac06a121d55845199a69e9b8b14f4f878d7fa9d3bd901fef7b250ac713ea823eef11cfa041bee03abee508f45a828dee681c077c8bf89433ac4c58035a755b27b495678fb051282299f8658bcc5567429798407192e8ee59693853a37f54893974c4fe64bdffcb6d2c660f88c8f489c4ffe716e27d3a157a539a8a6c1c5045fa93b7ba5f0b426d628ab6a1efd92662f802d9287570dd962f44c4a8ff37825444031ac27e26669fa15a90733ac0352819722724419642875cb1a143b5b2a2dc8e31cb4aa171798181feb539ca8407e06120ebbb2aa5a3bcc4600ef64577ed0bf315a05bf4513e3739282732c94997ebf91ab6293b909d935de20a8939071168c10f1a2792b4911bb212914e5781e3ab5b0d1c7c1363bda387118a2b130e07bcf4768c0fbc43cda2d58f44fcce9910deac4b2d11cf89285b1a604b2d6b6832ab2449c35fab65b9f1b6a22872858dc8fa6923450975f55bc7099e355416768af41c657352eee743d51da6133231cdc5c2db54b59ba6b092b63362ee2bf3ffa10f1897b75e329040c31bb3b76440ccc0b6098930072a1a95c70d0b5bec7786c3ac69dca40ffc687efb75325a5b0f9b67b642007ced66b31745828aa89526006be500edc94c69d9351e9139d3d826a3da4177757b100460f0cf223c23680bc233de3ea7950d0b21a3949e3e278a3c058f9eb7751a2ca35e35f88f121646774960574dec686452732d2ab00c863ccda19698456a08de7b4e129a9f2fca3615001720406d3dc90e94665d501246e446cc6225ffe44c8dedc908d7b28fa1437c95323630cba8944c0cbdbc7f1729919795c5b52aa1974647c43297efb030a99a6b0d5a0a9d3679c20c28067786f580506318bfcdaa3417366cc9c93e34488dde73652a6b9ac562747da8109481260502fab5c1bc4636c9d6b555f96462e940cf0b58202d049aac1a3c87b5d950b6701846e948550bb8199831c461e7436a3713c77c0662ed009df341d5de0b697770f12082f04449fb2868a69c68ad14c941130967f0b06b2bc91c0b840c43c20e837147775853d3baf7094c51ec86051b1ac73753f032374e76cc5eed8a0be466c9fcc1ee9a80c04b566decc5a448753c2535fc9c0b3083716d5b049f89c9f191a807b933c2ab912b7127b4ba04c85386372f6bc5db69b972821d54867f440c4697220a12cb5769cb7495a37acf99fb0451f6ac7807087ae83a0b564924e84428cc94538fb0357a7e222f8606ef0404cd7e29d2a4ccdbb22a45f9a7a51499f9764a063788c070a93bc0766923297fe438c6fea2971b887fb4c00000000000000000000000000000000000000000000000000000089f2311ece0e5169b8ae5c1c3567ead089c11f1d703bb293bc1e32d67e3f3093e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 20327e06aef57e606fc94d91141d35db28ab5fb1a7a1c0ea51eb1230a4d8b7b0439722c9b08528ac3c63e93c1f1932e2602e96bb51d8d34930df8198269997430826c455c1feaee04e96bc91c5d19d5ae236a2e90cc23cbb802d4075aa7ceba81689bdf1907ca524a7582f7f6945812fb8f0e07b0a6b5bf1a7e879f4cb725d8c2a11df68aab2447374c9721a13225e23ab561301d3e1627f9973a0e37f76a3b4c3f824fc26f249f8b4cbc9d9f5ad11b93a29167d6f6df17b47c1144c0ee807d296c49e36e78805decd1143ad46b29c310b9228c8d66639de571542806115d8e55143139f976095b88903831a5b40f12772a7aed5cce13ff46c97606abe1ae98f5d43ea40d48d8ae94e89851c4b39d4d426b8a1d5622d1bf03d56739a9f81eb4c62fe026dc51edb57874572d04eb5d3b43e4e17e8d1554444a98145e3bbf65c900a7f378e5d9cc71169e5fbd59259f7a57b1b4c608e863bb6dc0cbe45c402acd789cedfdd3200e2c4e9ca77054e391b457f011486bc58708c44166bac944ab915ffe993591341a5d07bc0b66ca063c5294c3de876d4a57b8a9651e9a5159b1e12b9005bc44e757cb141cc665a2a03158308e7203bcb43a5b913add9e7c1f2a33319bd25e8101e9bf21a4a58de0653b106f22249a05f43c61780f9574ec4180a0d05947b0107bfe5bf368e3b3f9c7a7e9bca0d848d7b76ca57bf0876be4a0a97995d00f7cb65ccdb708e992efac5f1ffb990e107c854c5f15b8540db4573cc52aedf1bf5e4350c4418be50c9664c4bcf113e8d78bfa116a287e5f174770e7f9cda3ee4f9cc4f3e2aaedf97f576e0e71282479ec1fd4801e222893ef7d34919872ab79315547bc687da4ab3fa5e8d330a4ebb79be2a2866788f0e24fd946b689998c5226c0c241d24e3c6dde149fac94311031377dadf8fb263b9d8e055824fff8fff07820fafae7aa9477e42fbf42ea1332eeb572c0070b48ddae20822b45d491c819756afb5fd6f9564d3f71c043229cd9588d0292aecaec74d537339ee37cb9d2d365ea41bac6a811c41b9946dc1963bb6302c6ec01627dde1c2024d5dc9f9978cb963dda825a3bbbdd75dbaf04ff70f8b905abb70bf4bb4db15467de1f37e7a22109395f7b9cc60861888c41c8efdff5942ac6758e8466029cb6378eb4b79ae5c47b8c13dd9176d64010c98ac111e9b9ea8391a1695a7597ad38c016d3d28d44a22847c551159ef9a473bdb98179efb294e85d7819e0a100fd2ef92a0ccaafa07e5320527dc798886a4e49911afeff40e45768f18fbcd79f6204f17bc19cfd6b86f0405e0dd55ce4ff9e092825f0d83cf3a7767c49106dc3b996d011535c316ec78433810173b1cc8e280a7e23d2bf2bb615f3ea576bc8ab9c7ff5cc7d79cd093cc031a58fc7d8b98e7dd127d67696ada28f14082a779398ea6c722331783e77b26a2a496d484ba8986c497d5a038542e192a82d1a1c5f02ed3afa81ebd6348c06a897567163377bfc9bcb41fc3b0a037565871ca9693b1023fb0aabf770571be26e847f9ef822681ecb407c467309b118c24243ce1b64b060d48ee545c094d66d032c9249f877a1b034e9072e5aa63d05a9ae2e7ae037b70b68e0851ad8d99f3a6b6edca98f24a4070f89c92b786db50802cc8bb5d7362e8a17de3a4137b01269d53368836ba7b7e9651f3073f32140a5c86d88ea06d8fb488e20d721a198d43fb530d83f9f67977997bd24af8bbd6469f377e8fe6d4021204869813e11407a310ae89381f05b30257c608d3b6c395428fbef8c5d28a4169c07885c3858de23196e2e3e67819e50fb0bf45734d1ee5e61520cbead2f716f58fb7695b00cc7de362a149eb34ce562b93806c78efb67a62c7abfc5f2a7722f48c496ef6d641a710fb5dbdc0db58398dd401828a6e5ea1387386e9d67fec705df55ab466e3498b1e7ae78fce4626e440117dc16a5d3b849a60a3b6e0030b483ee04c7513c0effee19e63ea7f148cb8f4de75c0ff450bccc5cb85a3187881f3b396e4cedc685894d5ce799320f01b7aff4788af6e90ce97165f3cf7e9eef7f8f86283a99de3864843c6177a8cdf90c50c77d1f81e11cb42da9fbd3b495e7528453844f315b18a3a0be78f3fe0801b1a8f89dfd5d7eae27a8eb608831eefe5cfd0ad9631dd8be45add9da2f73cdb57f062fe46be28462d09c5ee38feafef94269344d765203047b8 +expected_result = pass +expected_shared_secret = 957ed68960e9527bb32460505e0a8b69ac6dc0225501d87f46fa810d98f2e31c + +comment = Rho leads to non invertable matrix +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697c6b844a5959672b08796868e7107108ca4c30a58be4ff7b37b0402697aca2dc4839dc51a8811c34c8183442711a8d055b640cd73d2caff9357bdd9ad36835ae9d55d1a291e040652d020a905027a616b3b5c63c0be2c1068e9cb0a9b4abbf346590237f96422308ba86b055872e156470b53e35b2a604bcbd2b97849446684149a86d9980c5182f1a020c32b14de18c03cd0633e303bf9f8a24ff0c95d5a65c031c18550b7d7d5b8ec672c3953bb3be0c3f13925200394aabb26090a3b9a12bde30418b997abf310c1724a88b9782418d09552a63e2855b7af2196d422761f5c8a877426976c90552bc203f5657f5370258b936c3706f074c11b3b2586391f4c4bcdd959615a819aacfb48d2c799a9abb182c7a9fda6a80ee50c4a827c9f50835b1859033629a9601b5b8b357913b6de142a501974a0c191a071a95cb8c45fa857736a93400141cc325d1b4518d3ea58a94c14f9b261759281b00213f91652b1e52bbc0c488bc0990a136e8e3b5e20f41d9f218646d43745245ca4c2777099039eca02981ac7be932e01087b615a60afe87ff8d93d807589e1d351a5033aea9b032ae80fdada8fc4ea6a72b82929339f23870e620b836634a0594906f5acabf563c97abc1da988aa4344bdedc707e4636d65ba034a7c2a29090e30f677439247f753ca9ff93303a52a9ffb605c7b8fc142b576f14226c2c20828a258bba28bc0b680e60f43c08417946b77d29ed1ea968aa3a268e54b71531e680c09f5b08c01500956a86edcc05633dcb13e173e28e8c983fa75207b537dc37c9356b8ebac5d401a28a6d937f9ac49c3fb267d9a0ad9386f9ad4397442b05f191314356b431892f590290e488f12bac3faf94ec0389ca3d88924671262845bc022ab0856242cdb5fcaec474565caea58395a34c709aa270955104493832d2805a8e05d62437df6993a0f6cbd35040580871aba994eac37955f73ac8b057060426eb068114dfcbf20441405a2322156a5fd491f24402f8b73ab88f2498b04148cc2835901604674867947c3fa24a2d821963ec5180cbc00bba371fa3879be800bf309c0ce9b6ae90c99bd4b9eed787a539c90b31cc4ac3bcd1d2bad5fea1abfd7383a7497483b089297722d27ca0b325bb09272e4ea1182da4a75cb0daf7a6647b15ff0e1cf4a55a061921e55d6c8b5131d88da828dc800eaf4216c283af147939f1cad02351ac8ba79515167d1d2b582292776c300230a9cdfda2ecda65c1456884a5aaf3ed23c8242a3577913cfda45e3bc2adec6aa281051d0d94ed0320397b7ac724b8679aa29a85b838ef9a3c53021b0946c9933a5c5669b65b789e349055404b134671ccd105b453066fcc9949927798670bb011bc76834c37f3b98d2f992fa493fc3850fc64a92c6c17be8ec3ec5c46c4cb415de2c1a7f42700e415825c4376998522bc05f7a61c77f47651dc8a4df012d1aaa85ca5899f67994303c5e870b38557c05eb2a09069397c638674cb868b028b96e4249d2d935abd80278d35fb9668ac0d9999df99a78da32eae376cef69546fc71e3e2975221c49ab03baf048e1823bb8199049443433eb6b42a32ced9f15a9f4a3503598a43582070fc7492d6c1a05ac47f4a8dd3802af68c4aacd778d7693ffbdcb3f5b77f81a1951cb43597f5bdce907671d43bd4f92f70fb7c2a9a09402cbf0b8798f662550e2413992a8419d6a98e709c2c2caf9fac14fbe558b0597979810d62854205530f9b558ca4488470a39c88a37a152b6572c2c57d337a4b7ab261520729132afd067e08035924a14f28d32f6a258dd59472b5db2c6cdc53b9d766dcc030bf54b62a100cd0dbc9b99760df12ccd1e61df0b624b593b004f6712a13aac6934ba8339fcaa64f5d45c05a2a6f970400020380c320adf23377c6f5691dc96cdcd4864cc8254c929c080232a01b1dd9e7808e076d6e729926e81ef57970447c46f6ab942b90505afbb98edc344c47a3510c358bc63b76ca0ade7589cbaa3800e9278eb16a691a54de7cbaedb384ad97bc04a7666c4bb10cfc6ea85855b1c4c18005cf4939130b3a4d55a954805616678671a6353d45bb23fe847dc992cfef322484f7b90b3a45180a214491505ba24572d596cb6a48dd21748b770ae5a8559b287c76c29f3c5636b4400175b8aab65b91bdb09d43db7cc5805673c5a3c509ce77184f4d5ac4f674c0a602363d984e2bd8336d7877b436b6c0a8b68084a7cab956d300c498a86d49965172a78972844f37b5ab703731451854d7558f8f307d74a967282bae40806597ea5984899b54d31d85d159ee245a85ba7181c5bb051c49f2391acf60cc7c211f88d11617bb4a62446c635cbc09165fc590926cc7c4b67acbdca1804abc519af0c7268c0a3ab92123f15ec9f148517162e6d2a1083919570834cdbb7d7c23556a1cc11a55760b0470e6466e595a43a25b27565524618a6f0853781808bc14a97257b6ad9ca5cae8c294fa26053dca2c5fb300e0982df766882d80b33af645688c7a57b5b1a27526184083af969aa4aa5f52d9874a09b8dfa21cf5376b8db101b2b218412a400e02aae7a186f3b226fc018701533ae10c37b3836bcb829c7137a6252c9fd73723ab7169667b8c8ed4401724b36c71c2c8e56dc3785379a55219e63b4f7159dea9225c8b51cb4c8e435c3e19b7413345b12fa3a0f3cc6146860acf104ebe31a52aeaba9a28000000000000000000000000000000000000000000000000000000bb4a30f46e22141ea3a31265e632fb940c98d0609e8306ca0c00b3d2ebb259c2c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = bc99921d5e80c1f9d343ff32fb4a40a3706f750c4f7b0ccd7656ab6111f1ab8dad341e30e9a18c570d4abc4195927cc24fbfc57b1467d82d2d0cc1b7a192d769190a29d0e0ff672d6771910ecc08b2e8559c8677cb8c5d2109c07c67c639db57d9f83e0e67e2347bfc266bbdaea1436afc2ffac8c753c33a8c464c2652fd6bdbb7b78de3c851d98c5903a26d253eec7af773f7060eeb34f721178f8f6b4fb48ed18e0a614be5b35d9059ff8f096796d1c750fbfde317cb9bc95b14a25fb919a9df07d19aafcd52dea0a9b37d3d4d5fad67bce77f25358bcf3f90c09d08ca0afe83501bdcbe63160b7c8fdd8afaa7ef023f6ddc2c966118602cbe64a5450f1cf3d62d7cba4cb2627ab954f65f628843fa661b55a9e3f0d8a1c710b068625985405b29ab4472a4161183795032966e27080a8c3042d616807b49a68f9df5a8f466845b0948b1ef85695a631bbc503f8113318ce81e436e4fa69749bf38fd1a598e6f15f0412519363b76a6559fe068946925da95d5d00707ba0da8bebe3121f859fcbafe80796109a067c4e1ecf970bdce85946830b783e9223dda9ebd84ca91ef9ef096e3174785db6d4aef47043476128313195cc9fb3c009c41a2b859046f9494d37e057dc0723b17d7c1ed99c9ccdfa0349229151b584081bf921cd7bdef7215125d5ac2d2764e1d0c5671845164a77bfc91be29a476da8bbd5bfea6d102890fcea3757d9b323d12aa050a4653a93f5a29f2cdfb30e7df5d36f8dac610dc401b0f6ec0f63a022865f10e119b68c017d083ae4dde05598e02cb22f2db9c69372e23cef10e92536e11fd69baf27e41b578864c7f1a552b739b3369e2fbfdc7a7b6c38a1961cd717c4c8a4ad0d3da4e147766ee94857d0914aa7d18879ec6c5ee0cf747094ef3d681699decb917280bb76874e90c5b70e8f2c3739a22874dedfa8d8b1c5ef0cb72e67a55165abe7c3513ff34286ab8dc690b95b914acde3f63bafeffc2a6672e280acad66e757bcdf9f6650dbf39035c2a0ba75c100aeebfb8d0763074b191e6d6ad86d50f945400568f61a4e8b400a41a336e1179934ca181798f159278146dbd5f6a49481be03dd9538539dda5cce2eb4c149f9f7ef0f1ef5488c4fae38fd49c07a07976ed93e57a8f978e7704a1b316e4dc3482e6eea6181ace8e6fcd37cea7357740b9ac7a3c6c4cc3b1b7f27f25ba500f7b430079ace631bdda634e421b457fb9a951616ad2a15e7fb7af4a9d05473d94bda20fa5b97cdb6bd54d028ec81b09757036bdca2eb2fae32a00a50b21cbf7b2c9e0206ec617870bd18e8e5c05c4d93ebb88f4376f0d4d8629f5e03acfc6c5903564a3fd45529ddf45448174d2b9a36dac4876e601a26b0830546d3232cca2c2a4a5f6f62fa9f9c6c8a88ba83417487c2f838dee3657f4501f46f99467a738ba552ccb69ce20fc576722a5736d30cd2d6f3fa2e6731db14f4db0ec60fa134d2cdaceca19aaed29ed3c9905e98031470e8f06e5a95e25ea98e712b16028fb0641fe92ddd6012b05d3a2910e885135ee75fb9de08ac97fba4b42886bfbfdbd9c831996ea58d3eaa0cd712602d65ff8798b80001a5deb51a4823216d85f8d79eb85bfcea1805571a048f0ebb6944b8b32988014601b161894f736ecbd4ca149b8ca8297f8bdb4d4467b776e96df55df1ff8c192d7632fba09959e18edb38256f13519ca331e61a11c43a1f83f0fc668a62a467d3aa5da3b2875fb0befdb947f57e90f9fd9330d6a8b691038afdee461737f4a1b21f3409c71a09f8e5a26f4b82e7995872c13b023e2afd497eb4c95b949594138d4c52edd4cb446974e26740327d9ce438d3c7ea4e786e74c9981fdbe6a8a63fbb814e17fdf517775ba6946f9e4f802e39d03c829b87a68abfcf25b6b5e20f2b6b2ce53d99eef19b44bff5f76f5a055897a9695d6f83e7c16cc395211a672639134f960f986c75fbdaa7355bbfc1f79da427ef0037d4ce4cc52e972c03886ea3e1e9e66ed98033ee579f951b46839d3546608820bbb1e4361144214c27907f000c5e7866eb2ab5c3902395845c5b3bf14186eafa490d74dac8f1be75904f56a385c102ab9413022ab6da58d2d170dbad5c2a7c935a9c0190bb730448fd3e50dcba8aaed162a4aca6d4d2ecd8c9879765f87d6630a204c05772ca873fd78a7bedd4b6217d3731c0c51998cdc630e5a256200395053d0 +expected_result = pass +expected_shared_secret = 713597a2ec9a4e0cbad958bc8e4929877ae01d034c78947399b9cb1a383ad7a7 + +comment = Rho leads to non invertable matrix +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe331704aa56092a4204a2293e77935390cb1d2b2924e0bb27d4aa471474fed2b6982b71a1c14b2cd3ae12b12d5d12919235caeb8aa3827c844bda40f5f57e5f59c75c86b645224b3a861eb9d9773b01cbba45122bfb1e4a60ada0fc10f133c546563661064adbf4a89117657366789cfc282f9bbdd0547029c92aced02963f8cf462326db19bdc980149ee0823ecb1d9e22a5effc6cb588b17da70789d813b749be180457e82a5c958b069551748e12bae79cbc0dfb5ecccc85f565c22eea1836b52435b023959b4f4fc12956a09f38d58836891c4c2b0b4502b012b868fb9bc0455c12e83c182f1637c05469708279b1f4af2c275e174ca5ed0a12b39849f49535b8ca73089acd5067b6b57297327c4cdddc7d5c752a5d2cb04c659d04f803c72507f5832e7bd528e903863b932d80c51e8b2833684a084c7100728ca33a4304c85b8cf7b61412e76373566c34a75ca88004cab21a3274bca1ebcbf34222e351a3df4b557f09904173065b460d54210511f4515180b3bc0a87f9125a0a91252c11461582ac34c94dc4828091253944b84b01b12106432fc87321a15688d6114c5486aa6d90338d3260de15633028a9a2c501e3e7a88747a03bc4c41f748778fc06adfbb70dd01d706789c49b847b12a2e369341c7b5610f2336730cf1c1bb07df6c1e9a035c6da4f01ac38570256ea0bbe73832f2ef968635765e7b9c823fa326b57b1608c50cb552c5c4b6b509abf2ad9452b76660e69abf2f172a117359b40cb7e972790f4b9bc05b0e866474ce6c2e37a36d74b49d400ab37486e47597afe6a08cacac56a654b1c56cc2dbb944cb6ab12338444d15f0de20265b57f3f7331ce56b374d13d4c89213117a15ef15ed6356778a6a6579356378cabf268be41466fb82c20845bb5811a2ac3609f3d556002148dbda989d8668ed8c26563595da887c657c915bc83923b46034af134a6a71e09992182310b061840afe058556738526469f76b91ed6081bce143e5e223e9a425bd645689d37fc867006092a7305a44537b06c60b168d039751e6b015c7c7d652ce121289920bbb1fd30304124819121af20600c4f0b261ec014153604140a5b8a97ea49c6c065429e08781c7377b73d06eeb909e9222007a7436a8e8a28edb7ff9e78c76683234092b6c97b256f2942eb01bca52a5f192ce1b890bcf0052ee905d66bcbb7ff44462e5c2a92a58313807b884a719cb07a2d8a3a0f5c2bad57cfa692a3d01345807213a2b5cf6a1234278256965464b48bf96fb6d3d0980d2c89dc3171093e80b6fb7391f203fd0e77475b8c8b8e913abc7066b5cceedda8e97acbcf3c6a1b5a590ddb0265b2abd5df28c8d7cb1c6553049d65808a0021d671622f45a5e834ba8498f97a10a15f1c8882b8c28e31b1187207bf5b6577053c5f7af3839bb2997bdfd761154fbc683c68259eb2e2367b2832a0c26a53b6abb06968a05ccf236dd8aaf3422c427368400dab1683832b9c73af3f63827ea16c1bc832f115ff3d00eac20cd353687507cc6d8f97ba12941bcfc714c735b45aa33dd3451ec56c4bbd6c363b3b8f65097d6e0ce03b29fd5039fa0f2a8342514278aad9d4807c1b25fdf035596f8548ca85f2291207694b949b42b00fac43cc6394ab85c0a01c583717d900035463acafed05f6717057e577fc30a92567a080fd942816157146a70ef3427a71478f404c4f613266f95a552578af3b4a7bb8383b1f20a6e47157277a7277086b0c38dffcaa911a1725fd34b04d545cbd924adabba3ef705c6e44c885526dbbb55bfc8a772453397902ea9a2b279e379f65151fc3450a1f471355a97ac0abd0af32a4694cbac06c32069c41fb6af17d684aa05a84689565ec05292d61aa374044485a507ca3478973b11008bcae4cb0a2975c2a471db196dab32bd71397e87240043b1305362a62fa6843010a25fca317993660b705f2637988494b94aa9352510b0bdc352394ab627e5937892aea86ac0e7eb1c5a2b2eb403994df5bb8cf144f3043dfad619e0627c2e661b70d1c4bdb30401ccbba87c1e8e0c1a83802abb5910625344174b6813f89191d23b61f3aa4c458a1886233aa29d6473be06f0906b75b1f16b1e5ef34dcc88007cea76130a70f6d1aae5028ff71ba38e047f02fa1956e7439ce37d13ecb555635e3644cd8c51b53db31a8254b2698a76b96300f7a14847c9ac372820ab779498b15f965831965c158fc196f56aa9dd37b0972c834eb0705b266def50b62636546b96a87ff666b1d5aec3e52679d4ccdd5c9b0dd50a7d916bada24eb6bc0ad94b9ffc986a4899303fb95107a90313fcc3fc0374e0c53c8160567f577402515624d84b15a9b4f18625c7d732aed4c64ad4766945155657b93a81283172850ea5417bf877e5eb95d739079377913529657dca52c756779876954f864b7251a255dc58b723b5fdea551aa299ebb8af0bdc2f9ef1b78cb42401ba62fc1992c5ab95e6288b584bcca263912c25a72a69a3d895aafafb38904a7ea64983637773dac77f0752909161833d3185c5d2824319aed09b0d27eac30bf5ab3849cc9041c7c8bc92e0c0b3bd657e2074963f79a4ccc42ec823c8b0d302d85371c4e928e5cc9d11d0889834622041bc971ac40e00871b27cf052647fab656401782a0685a800850100526cef363fd550cc491225e4c4a0ee319afd39ff2e2b581f728cff590a5a60dd5e4000000000000000000000000000000000000000000000000000000b097441d1eadf6b43e80f795ad83255273dd5995bfb1218e563d457264bd7b43d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 51256f7e688d03d9c716d923b01f95c6266ec20da79ba4dec7268f51319e8bf0b37db4c07ebca73a80a06c25458e7861dab9e675c67ca9ab940dabb117a7e2426a7a81be3dc6ceddd27f073c2daafdb9162b4409ba741c6f16ac6892d7d8b06972d39f22e38c6f2cbec7f0506a5f86c5fc708a1d9a36391019c6ed9281c986103b6099f87ac956b59cad12f69db134f05d9f8f641678da42b276e754a31a77db16b5e85110235c4a4dd8ad1f6be34527d01115b072b82e007abb4e8bfbef65919c4309b8417c4bcfab963ee1110614e57b85195359f48c5c471e24fe3609a5314b5854b695efe31aab0a07d29ec29a8030c2a7a005e3d7ce06a23bd240feeefe6320b7c994fec0134bcd88b2fb91ec37b0ad802e45003049024133f90ccf375abafc7e742542576b026f71dd8f00e8f790178de9912fa850d6c24830354c4927d711a3314bb389fd01341c270eb1cf2626bc19042955196358421c559a107d4274c9bfe232328e9571192f2209035c425224a240f6a9b3dde07b6fbd18eccbcd7b00a6904a801b0ee93011644d64d0c3d58c0f9699af2d4e7f9578aabeaddbf8257e41c2512a5e566577ebe94699e00953126ce91674a772108a433c82b05524c1ac742ae513087f69e67543b93f03f8bec5e5d8dff5251f4bb4d17e721fdd7b9f6c06121eb53bc06a730d482aeff1b09cb6824eb52838d85af90a685e4178e76441ffbe7aa6fcc3126fde29193aaa25cc850cc0e8df7c9699584fedc15ed5e0e7d49f89efb61ae381e3adefe8eae1c6d6f71ecdb418ea36a357f20ebb4faea2ec2826b756daf9a4655102064d036e745932fc63a0fcba1d0ffb99815d03dcaeb5c156f4229ae0b07375cc4d8a9cd22a583c16114aa613dc38ebdb8c06721d32a6293aea51dd7d31ed3a101ff727a938bc70d78f08e3847145c02f4f0f8635be2bdd8958c4265bb27fe915a9206e70e9cf9979f9b47823708102ac1cf12863ac7dad149134824d3f23a621446ad907549b082ab099815e1fff844959bda476ef642299652f2bc801a26b9d4e5c212cbc1c1f23f23aa334300cbb73bcb9d43344cc9b6bc2aeacbf90fafefcd483b791fc3e310643f910de193c788c702f359cf97ca07341dd6f088db0c435bb300f23d90ad23264f9c394d56bdccc23665ca8f802e2907d08e7c825dac31520282c1713701ca29a3175157d7060bb9244f4a54ce1ec2b736e73aed3ff4dfe979e89e241b578197a0a8f37f0d811f429b5b1246ac2205b657e7ea051890bd62ab11c34e1373e8e48d449ffe08dc36e978e4b0530411d9249cbd5e38182e9a7922ab0e51f7feed86201fffd39af6dba54d3129a7ec700145f819499d4bc2d95a47e09e3429a5803f0b2f35d9467671336e3289eeea89d233f9c2a3562e277a81af46d00417106b1d7257b1ebc20cbf7c09f8a5c4f035a314be27fed58571d77ed229662c946b233feebab9e14891fe6e8295c945502c114e6f2117de50fbf7c116e5e151b12aafa3432a2532f66301292ee764cd9dc76fe93dc395c110d400e8d337541e94ea1afda991ac7309de1149dc78ac843317fb95eef99e72df29a0a88f788eab75ea8ad1dd0c2b1d0ac644cf180d022ea8e0b7d7ca12f65d0c1647b2267b971ae1a7d45b3f5c6ae5b5c239bf3b59260005f24cca25a883245d714ffd87e357d987a49ed565ea729b0c9424aa4116eae2e8ebd62c69fe7efe6dee622d83d620ab2a53b24c82ba9aa0406a9be7139092cf97db8fb4c5647bc14e3b3890d482960c7e8b0422e4757feaf66426985d07a0cc39f51faf3269fbf2d8db382cc35f5845e7dd13df13455f4b3ffde636acd70c60e3f3a814173ae1167a69d7af59d61ef0bb800a371e79b60681c20882fe80fd3e6f5cc21b03b0b70686e8b62e5efa48f46b48e349f20b3f0b4212e8eb1d7b2120c0a0fb8f11852dbd144ad22c549914ae1aeeb990a317a6c942ddd07b023352cbd33209326a6ce4d751988a4c7ceb6e7f718df7e9edf6e2b2675429798b013d321da1f0e0c2f50b2db93d9d451209b4411dd6eae8b74a63342785dd492103e9ada05d797ee2027c9ed0837a0f4e9175b6b508cedfc44e00c944a771e40fe4de1e609965a08e2434a4ff5ea969a43274105b631375c4e3b38a7f40c26f4aa202771ae2a9179141ef005aa18a64d6e97ecc1270be6cbb9d5bcbed815b983ff8c2c99 +expected_result = pass +expected_shared_secret = f1b9f6c6304614a31639f9e63a019e699257c5e60ecd5cc9fc950355e0981772 + +comment = Rho leads to non invertable matrix +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960116a338d74bbaeac359ab3728e268abf75a8d30b118141bbc56670dc0c5b2d05c9c2f03952338170754e20287c99177c66b810f009002c244f213891c5b980aaa23d15f413d4a80160d24e692c450b68c8c43ac60256ad748ab6aa85aeac5c623d199928f88b04ac7bad2c1249c18fe1b867a02a353a112ef71368eee3210f7082f8b216c975070e9a1a27dc265698bfe4849611716d0fa1b1f9047e8b0905d184b1fdd863377353fae732a5d0388c3c6606a773360734c9ba915d49aa7d358263d7abce563afaf382976b2ca2e1328d4aacdfd78851eb143a1b81c21713442421bb1abf77ba25d4355dd10602ce06754dd9a77aca0e25b1260e994d0fe1b83088a5d385251ad5c6a54c45d93a7d1b25cfddc1612b8b30e753814b505524a5b0b26747645c9b636543ac7a871b6a7cd3865f1d8636cb5210ae9157b567b2ebd17fe3f59b73379d086348c9806848ac3ccc1547e8964f6a1c4b532787dc8620050b7e628274683b79e133969ae154da157bbbab159941484cda4108c84aeef56a54c26e3a0776f2db61ae55ca140c1056156469333834633d88c59aa9207774343fb3c0bec2aa0c60f25a1761337e9c3823a3965028951e114003dc86e1cb701b3112ea048672e5be40c6b319d88d62731a02290ed9d7429b71afa05964a5f775b855a271759945532eee7a1e49c1518d0b3466d2c5513bc84a69a0770b8f506c5203336691a8189ff8672efc68163b895d7a77b4a50668ca1ebc4bb703756e15605ea9e9c7dbd398aed773040ab89639aa4d005638a839a1e47e113564a33889d72682794cc68304d0a21858def7c8e5d20cce503909bb2064b7775db64c8a87a9e3ec79580a4493a0a845db33afbac74880888dd3070dab2ace759f777c03d0194d23a3b655713932570fb3686eebe97747713050868f72f6537b1b1e80e0a84d24c4a9a888f5b7c3bfd9380362ab98806812d07403463c9438069eebc541e8a8afcb93a18285d0f1a319e2768cf1427123ab458a71f3a44002b93cb84b72856a6688b99be6f2c764f81af231c87b7bbb1f3002705ac905f9be3d4aa584b98927902261f2c8bca677a2a77e8821a1afbc2b227603a75c1bc98aaefcb22fca6908ca2a8b28c813702c64c8fcca8af5c29e3893a1d696e3609312e0286c47bfbd2a562692a8fa28b17865aca8a7b00bc1356c489c4a9c11781c5f465c7c547b1cc464b5e56a84fe104501399a5ddc47c8b3ab0914584bb54f3c7107dbf0a3b8404e35fa22f3474aaf6b24ab562d65654e3889723c201d68f0ca9074769c15613319beb2449b4c2cac246b4f4687b09205c239fa839314a1d90a71c0aa9c74423873b08904a263adf2101b02aa222c2d06e42819094a60fcceba022dd9f50dbf00a96a76528785830fe453d539c2f61b0c999cb90a2bbd3db831cccb813ff1a7a70ace99976bf4308e2894cb4232441c0a094dc78334e2be9e6a830eb9c6458887217a1e6a7cc679838ea84b41e5b45066b32c69731ecbcc4d73f68f964958fcfa6a64b8b05171be99a78c31340486174566f4bd108433dde695762328f0570fda1cb79d60c67b510b7b34b0c341ab8cf8bb70146e0cb2036799368ee78b330a9288625c366b0b0d9a1eadf917b2f7159f25c31d34b422ca5d70d93de8e31b7a6736677c93952807314a2e58b685fd926b4555146ba41bc4f223b42821bdb22a99527699a7c85eb52288a3a4c56296bf20c2be811830fa689633887b8512723c598d8b1f9e88671fe77d9ae923f1b85973eb6ccd7cb5ee15b34022ce5078ce171837472101bde6915c97150b3b712f05435cf975b24b51e2395ad667c7f38a8fb3abae833a939b1a86f4545b3b55119c10a19983b089276ed7ba25c910a726ea3ba02344d33cc666a280bdcc2f99e3991d2491861c3b295668cc0a5c465b1e00c2be482a57b9c4475b3c11d9850e6684768091480e4a1dd0d71e88c17456ca0049d209d1e1a92ba4331dfa7382e2852c98390d4393f4016a98d59ecbb829a0f4b7261b12ce796844458fd393ac69f050317b66f7208afef2113e682552e81d99b3bd8bd30648b1a0bb153864bb7293233230f0b164c1a60d834c2a4a41bca495b57c02113281cf484937745b4ee90a55662860306df33368d7f2390c2b600b0a0314d1741c1a1cfb0940b39070fc1001142a27ff752ba7fc83e296cf62bb76f8a3b06359705ef1759702ae9623b6d365344ba2578ff4c00a4cb48db88e9c5acc8cfc033210857abbcd6132140eb372b9c3c1b69c9fed366efb33b518f99c23d7bceca7cb6b427623286f14b55b6fac869e8a229bc342c96727917a94bf29549c145fe9d95d35e518aa5776ca3678460a49bcf22035d981a4217b6044af11c9710a26466be948f177820d26957573b1575a09c3a87a13552f16234db5152dd2fbc764c88525e3226e2b5ff5571890db75458363bd8791dbca67ae112858908a4ebb7d0d847ecb610541c0791ac73f2432775207a73544491b7a5c03199ce3010a05f764a09cb9afa27023f72d9bb0b3252673ab714b792a35a78b0cc1593f4c5582406b4d44f6c67fb06972fc7a30e937d8c7964359376d896e9d54c05eb6864e583539a348e6d3abc256ad6443013926831513896cb5636aa1062f95bdf5b0acdb49a72581b6d9369c02234ab3dc5e3b4419f27318ecc3c7dcc60ce888b787a3458c342cad1c0000000000000000000000000000000000000000000000000000002abee8bec42254848914dcd794b5a37de56f09de31c30871707a6233f826f46fa9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 6d7218616fcb7c0a8a0ebbc738afeb35b63c00897f8557500d34dc984338ba4d4e9a4228063774f6b19d60e68d67f14a63a0777c4af4b9a0387c8165f368cfc8d603ed70f6df210e9f540cf9d240006bbabe17821d46700b8fc755c5074d4e558d80230b50c298b4a813f6652f6ac92427c168bfc6b63df821d1566b56dcbc48e96e6e9de8c011a3f94e8cb3b11e9928a125b2acdcc5323da857ffc0211dfaa59653a14b408635bf1d1a1ac1f614a6946c98d9ef55e8d5f6c66b980241a0f65c14e5e6fc1c116ae9af9961a7afe535332c5f922f49521672e84d5e28974f8df7e77e7e07e4931f827d94c7576dc16b6f8e0409d4eed15ca747112ea1c9c16602799dc37f31a438f7809db67ec184fbeaf917a72e8ce7d0b68c4eb69b3e4285f0dc3d5494b6ad0e6c9649b75f58808b8cc54258837eda14de7e2f900e8dce47e35df2b529409ab78952779a1006f81e32726d9a6d5a83e541ddb249054956c3a0ab4520b4315b8cae764e42c97af4876ece118e0392b6063a8b38c89dbf8c4e1f7de17aaffdcc9ae30bc71ab4b25b26e0a2526ecce67cae66c6eff9b9a11e8bcaffa5cfb21cd5c576275b5603a852aa08ff1382cb047b1bd6519a6fb1e505fa4fdd06338bc9567d78cf1deae827587006e220777b34fad307a61e955673bb539abeab976bfb545c3e002d5af5581819aa9c932bd2ae210ca29dbdeb33269439f1553f86d44287726d74690e279aebaa526653bc24ee5a94fe70a83c46378d4b2aea5f4da0ac4ce75aa7d21072746a7bd5a4aac231c977e9365488410ed78cc357c9cf36c71c8608b2e233e37ae1f169b15b9b5d5de5c225b60c3ea32eca29501da353218b593c6793829f38a852ee3c575e468734733f8d87f677b5e425a2f96553d554dc52a8ca96b1d711406e04b2d12c0f089ac1001b00e3ab5ca951091876813a1a7fcf4fae9859991f8abcf40bd2430326a0f0ee7582a19416bce4a95f486b146283641091135c7d71e89ae8f44daebd43c7d179be2db238ee7f7723ae782eb4d0da34d35dcb4b8831617f1c82b10dbc8682beb97d0c58d4fafc5fbb8720cfc7718df0883473867433bf7a851a225d60c9e76dd7a7efecd15534dd0e3d14d64f86c4d9a696c61dc520fb79c2c8cb081e72aee2119a3ef76c4f49e9616ef6a85f9b779f99177e0ef427d9a6ba6465f230e63d9700855065b4eeb5ef471698ead0dcf7a55fb1ea54073bdd1d67dea4de22469c317984f21fc421171fea81ac872c779c62bd4e4e8f1ba4faee4e701458a2e21222e9b45b3ba2789d1ddc34bd48f16ef6e4625b1a73aef185f62c73b79dfd40ae3d6d838484b3d9a6825a2a4b9870d87fac0a4b2c8af548b47766e3c92f7821484c406b74bc4b4b88c4d7ac536767fa72dbe413e5ee4ff8d4ca83cef9de71590e02d07d9e830ed7f315d542ccd1d0820374c19967f2ec7b73089a4438e5a94c6580d689bd9cc25bd900c275ce9aa450a5d13fa143e2ed6d2bffd5a1ed96e4c1073ed92f48d575cceadfcde1f0a82941dcf4daaa5399b3775469dc75f150ab41b446e2e3e17cb8c89b54be85dfdfaf1769d022332c3f819536ab3abd1d89f9de0b25399ef5872130255cb0572da109496b44c5abc4b8fc5ce2a9515ba12c38c4e6ee83f4d447badfbf5842757aab335b62c89665a1c42f829a40ca8c470bf79c65e29ab71358063594e21af5bfb2f6b53d2c55a2a1f05652ec8773b437d68ba897c035b781b266b90ae3addcd603febb3f0ad2afa0904cac6b9c04ecfc1547bbb0278c024dfea4c7ec8df54d24c4b7e9f614cd8ad0307cccbf298092ef27add01be5f4631d4e1d7afa0d8bc34d0dfd4922abaf5952062bf86916831d2864404d565ec557ba7753480ada5eecd37e21808cb7e92bdd34b7bdbcc0c93f39e9a4f515ba7bd6071c2b9c7d513b98802111c2ac67bf004f211e4daa201ab61bcf174dd83aa5d98ea1b55b19391ec50b299a56899f51cd476021fba5f5f997a0103049a71cb20da170d38bdec4964acff514b0c4fc77c90e8ae331099f6863b551bb980ae547fa41c12c31c324765bdb09f6d9eb734708b6c0eddba22154b3dce0acf3210ffa58fda8ff718f949da8eb7c7fa4a67775834c1fc9e74c5f7f765920f2647572e9158f6bac6e1240850decbc4772cbf54ac754af22d16ab0abcc3ed51bed9af0a936b82158c310ac457d5c +expected_result = pass +expected_shared_secret = f72431bd4d76ce666c68f35918a601983e117a666e5009b4802e904d0b32d9e1 + +comment = Rho leads to non invertable matrix +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3969fec41d1311ed2545f5281a09df223bc4918e55551ec060dbfeb41c777c79acb7375215002d9afa37b5a126625f7445c3fb51233650037e070648c924586bf7013c203e907332901ff722c35c1991acb2da41cacad4b709ee242a9e71eeb0ca1d05595fcea8d175553ce689ba595b8f98707a68a4d20f8a1fca8c34c3482e88c8b043a9d42e4a9e55a6cdd867e106b271031355bdc71c85c80713c0ef7c3ba3bbb9ad4e32615a2b104e52dc5e7481e258351385f9c8932a074529e327e6c0949756b57ef47094e184517819d459bbe35ac6154a70d004490b03803e58c9bbcdcbcd8451c2b0373656373be77a59beb2d47410d8a8631745653a02956dd0a0fe99ca87d78c273230667f25bddf3a65a216921a12844b8c98c197026e14638a97fa5144b44189621f00c75857fca20342a09ac44a4aa6c336d9ae58a15972f22555139e2b3e00ac0bf67b15d64ca8ae77a79b44e5b47a72ea06930aa9695b96987aa0dfbe63d83a352c9370247f6b21f225e096480b17333009bb7858246413061f4e8aa57f60972f4421bfa448cb92525f41ade71a35261551547b97eaac35ec9607a061483874b19714ca7f443abf4bd34d2729891383cc0a52006a4bffa743cd910d4927fbf792c20e07e9228b56247c2440a3eacc0c231ec949ee7809ae4aa00c46a56aba6db5218c588bc9285261b278b1efc62e52556b130a61659cf09648b57c79647b54ee9658913caa76eeb5c8a6b6eab8a7cf9f2707dd4195fb3939e91bdc5856372b5cd571983c9709c1d854ffa56cdaa34b3c2a51bd0d304570a591f45c2f1e4cc35fb5a00923d71a5acce485b210b39de54a8adf82fd8682fac45430ad513aca5022611038769b29c1a3f3ad751eaf5b058370927e36049d1b0970650db914249d7a2997446e1b746f47b5fe6057bd55801c8c0af94857776d0b60be8a66f46440ba766046a1e08948944525e6d078f1177a60fa3acc2832121c7a428d5cb3ce316a986118d006ad5aa7e54c4c5ab5492e894b484e594b14b8f65752da0239c6a0784e415bcdee96ca0546f81368d8899bf7c372789f62a3182bfc990c9da414e0ff346a4c1025ee1bbbfe99099fa29cb5b744d860e6630c132e521a65a2e00d1561c98afbd434be0f92da317c89926a87dd674afdc8baaf99661c9572ab800e14280b3b08f5df826dcc051a647b96009159ca26f5aa2ccb770b8636b432b564b4183a50ee32a80318c646c7b29d083c718c27ed989535861c385bbaa44b836dbbe49432f63b29bf66923dde69c6d742aa2fb28524abd22433ceb87a4eea71a4180a370305173a8a597aa00bb364bfc167461e33cf4e764d4437e5ea445b7334a31db333fc2b3754bbfa6bab6bec208d68274a4103d16f9069a9c9f6b0901c2281112bca50b475b4d6cb612ecaacf8827b55b6fa8c1821a8a9f602c66cb719c97337c4364450ec2a8ca6b01fcf2420e0b0d27c0bd82a721c74bbe62c5ceeeb906d555ca90fc12450bd0522ca52f4598f3701a50710fa2e53561562e8cfc58f4596cb9c8b8df540fff63359b24b1cfba7ad559a583b04626d03bca5247be964b457bc71e324ffdb758ebbc695b919517e045f6e1162c333c30526bdda31e5f4a6eacab3d97c27025f32e695703bbe7ccc18a87b8e347b7c678f2607e24c888b85454fc738ee0a74720ba03a7651d84c4223b32277b5231bdd1b4e61361a451420891c1a0dba6fc4508119237fe113aa087772659b64c122382bc9aec39bfd2b2a88b32199d38728ca98b259b85df75ca4ee5a671130ac11ccfe19a1fa34954387035c8721e2bec713e635290eaa70660b5b79660334a5d56544aeed1044d6a3f0b88a1c900cc362151a3e0b46cf5a64a5bc38578bad6d0c467028df742be58c3c4c0096c20ac9f5799aeff295f3939ce61a92148ea2313195525cb3da93b30698ab893964d23e72eba952f058c2f74a00081814497a0306a51aee0ac1cfef00b7accad91448f49c8530ecbca5c5cafd66b1b03515a5d6a0ff5a10eceb67493506c8a514b72babd2036674d1a493b598a2850342a52a163226f07568c846a4bf35c502255b9ef4c95c87aa6088226a8033af1f6bd93e642fa8a5ae1263de5e53de8b419ae066ac3d28f159613cc63a163a41b95589249f0747c6a179ac9830cb5c14bc88efa708100aa7a5d2c7fedf0c550a5097f764d948a9e4e821a4c64a125d9c54677848b806debfc2cc5b9c8187b52cff197341904cb21b9061acc7c12aafab320e2f468244852c3720a0ec554d1219561e954752495c423635b92975ce327c18c346b026753a60c5159a33c584a2d297a499a294ef9c1c8b5081f859443f53625d6113ba1a90db33d7b5a32fe399eb0e84e0804adb0e29f4f063892484110121fc6c618a0235a22014dad868ccc55875c37af10062fc8a029a0c458dd80578680757194a75c4350de14100c73c40b616becf89637508074baab38acc741139b31d70bf0568ed5302f3e356dffa01f6da50011313b78016134e4cc15e65206f1ba865180d3f7736076c682566defe87bd676bdd149c76c136d549049990b482860a36e321426e79ecdf4c9d4b0b4953073fd8472268929b8694f07bb7c20f2900db8055893607428b1586c65b4ec7e195a431249a9d1480400d0825c4a655e257ca20175ca47ce081938e724c138592946f344d9eba69db96899f5afc8ec000000000000000000000000000000000000000000000000000000fa011a76273f6f5108afd91aacba2767649faaeafeb78456b5e10131e2e533a053f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = c22bae19c43331e5c52e16ee59188c1fff71f15af20de57409add7604fe7c7a9426ed876726ffeb416a2bc7c698584155935d02338aae28a12625d39b8410b232da09e83c1c5e4b12cdf2a6c540575f232d5e5bbabfc299b9e36f3cd658dc38873fb3d5e9b3c8c292e28b7367299a12dab435bf2eff2602643e13cfaaaf96be846785b3b712a1f7de9f3fc1c340f32d069ead5b68ae6adb183c5d7589bec7e2eb96715ed3f15a336c63b3955fd6329281d069a041a76e7d4bf6d758dab0f5eeb27e74a318c1dcb3a645155c62c5d7710bf019fb0667d88da8d41a226bd45e4b6015166631fcc9f559d405145d49291123baa069febc3b720c2edd2dfbc29145c6665b0a4bd75e95d8118ab1367175464fb7a9a6cdc0aa7818466721f44e6622b40fbbc18947652a1940f885d3977f9a177caa17634bcc528d71ea678b387284f9a33f549052c331ec81398dc9f15bc3f3eff791d31f80324e21e86317e1ceff20791c8c8bd590d8ad3f64b3efdf432efc0e374506697728c84711f84b0f1c1c386f8607a20cfe3177029824df54caff1c525f3b1f8780490439a53a3b0daec32289201c81e4358f8549bf9ddcf2b2991dbc54ee9bb3ec0f7344100ab900a48d0a350546953a52a42d108de591cda14cf5471fc38ca8babad6693b518fc8774f351bb29ea8da5e2eb05f3190a97cb819ef91927e6f1288872a8179a99b0c071c429c5dcc8250d5e9c5afa505666d8b95712605cf9fa557c6c26c574f8fede993ca03ecabaa144911468f8eb0549a5c0f9b7aeeb94ee26d097d6b7bb76360d4d5091feff29843f256507f4bd743a5d2a50cfb0d0d439197802a44f53e74bef67695bd08f242f51d842ecb3c24a05788c75315a54e1f7035b86171b3258dbf49427cc2b871b3664babdd7db14f4d9baae20171ca7798594819f5e2ffb31c2589c169dacfd15b4c890441f0f87a8e503c2135037eb62988aa1fa610c6ceea56ae48017b8a9ad2ff5a86bd1a9d17e5e9a82fee0fa21b7722535b2eeee10573f9dee78d7b6667484f09c8353e6099c09ffab08994d2a6a20344de0c359e8adf05732fd6862a978ad9614986a2ad87cbd87015b2925d6a23a9f02f27fc7507f852cb06539e00ac560461154005a9ac3dc5ffd521abf8d584a1df85cfd64922e0d1e9e4fc731b0728a50c02e184e404b3c5e4fb8fad63a460e45370211bf60e7737df85b373fbee014b11706c9d8b09b1433a96ce62c5c0c08c484cf8be95b7426fcf4878a4eb15e668786af45712c82849f9146a2ecc3380bb473a0d619dd0295401ff9d1f57f2fd5a84bff5fa6e1786466b60169c1ed7e4083cf1816e116e8d0bae7ad6bbfab7625a47eb6d20fc1fb2b91c84adc23c6c14cae79f4fc3f3ca90c3c15315720fbd15d1a70298cae1b6b03dff6a1afaec2018016616dd7c890066e1a36562e55773f8c5fd22ad1f4f1b2fae4e8ceef92c681fb40cc279edc2a834eecb1e49efed02766b9547bd679634940f247eec42b790afc45a77f5e4f6fafa9eb1323fa73fd40727ffb6998cc5c8ceed32252e5c26e57290f336f5831689d54b8797de208f0ca2c75bb6d7f9dbca88946c1192fcc99fbf906c592090d3cd183eccf714c52c39f63cce1044a7e15cd574aca2cc7d6a76a56e945f108d53c51fe67e8212abb7849e7df5ced062bab608b445ffd9422e608ce096791a1cfd3f2b2f61d4e5c800e33fa3a8a38114cfa02385833d435551f2cdd5fadd3afb949437f0c19d7566a5659770441c7dc09768782f574caf781855621099d7602a6eb1935317d25dfc813d12cdabc3897d0493b88ab2eda981c407e0bc4a62f6d18c96bc497c6c9bbb5401b77a77413f154fcd309eb6c4b711e41ea4ec1c7e2f4c503086be4d96394d5b420a813cdb5798b00831139eb57678b790a90aa731ecacaefcff840e0d721dddbe5cc1c3deb03620615f79760b92384fea781c8971820f9636d776bb2c32d596104fb30e0295769acfc39a3101db88a4b5b38a75e9ca10f4071660ae869063cccb409fe921dc1596a517391184894b45a561621eb7c1184f5e69051845eed47021da5073e078e0f872566cff985ed3b866f273b80ef57d88cc1e2f91b72c69b1c1a766b4f8db2e8ec653a618f046fda32cee1f06a6e8b5895b578b3989a4e86dcff4cda1d0b573ec52b0b53dcb1024ba58d10253330fe3fb7c19c6bf30d +expected_result = pass +expected_shared_secret = 0b6ec01df36ce91c82f78ed1b85ab731581e50597253c08745f0f2891a97f942 + +comment = Rho leads to non invertable matrix +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d74933a0cba383545cf629d357aa8927a7bd4f6575059485fd455be7198fc01a509920f6c0b8c5a565b4b86c084a60bd9b9b6037727df67b83ae06c5e47aba5d263ce83808f40a378aa43b4ec5458b33a0eac8c816abf5bf76a1220a99205258cc4a9236b4dc252cbbe8884e8ebc1fe921ed408582182b273a199d121153ec38b7f183174754f66332ca98b87a31672720815ff7bcd0cdac810db905ea76e6496742d26b2989b201fbc2936f5a6cd60c35e757f8c33b75277560ab948bab2962df9c38c91b44f08090e5585d852c4b729c52de88fd8c54722162f2d7696946c7b710079500136a28b9abf9a5c0294a5b265865cb04f9796b648f85858f8982f15c2bf31626b236b2c3a6493910be2cc8610829d96693cce3686b8a63b91439118fa661729462ce58e5e28b764aa39911569d1ca5c1b33885400a16f169858930c7f135ab6a95d08ccc70d057f9e73a4c8ca2da7185df37c8a6f727893bb6db74329cccc4692589128867cbaf28694fa747e86cf98619e99b221db88a81afa73b348581cfa5addb505d4b3155f44c292f958f02c32de979b3b042f85ac3354fa3190993040a01ad5450680026d7e17a0732a54c09329373009a1c3087e8c892ac0aac4793fff2b98cb96a3d0671f998749d716a78c4cb6738879d76307a3a35738a886606a236c92accbc09ac502c03b41ba0a768edf06a2c6162467581eba5083fce8488414068ba06158a9128ff5361ebc06fbd492d69c185d0b5568c1973bcc1604a4c0916a1c03aa9e82c98cb3f107ebf239ab50213db93136013dc11c44f2e55871c7bc34fc76a4383477410f73902f57d229e6851aa182880e767e1386082fc77f20c7a3fad8677f9ac611dc40494ca66917a6a227b9e6e71a325a3a4925640ae59c96d9bc33c919be595aea76a47bd64fc291948d51409d99008073b2f3356a040cb8a27706eb5ac08d8aa71c716f4f9420b5974078f235bca67f2c8161319824eeb892e56a3b7097068be52eea909805863057f1163b1bbfe98b1963e83e1edcc65e88411836a6735b50f8256d54dc11fceb52ea771930a3987a85b2a73a6e36fc946a3716277943aa935953141c167a8fba5545089345ce8a8682672ae718c87dd63511f81ef1185db0c173159928722202b0b161f5b3a1224766ea1264166c2bc83229fe273824014adb8c6630cc3fc8b19e4bbabf24bc9bc3c3adc5e3774c11a134eb1cf491550c9cac68ec89e281b88709ca688597679a2ed6f73160fcbb0b9cc696da6060864c2e0108cf225323129af8958cb5436604ac0e184a68d22110afc91384cc7735d546e6db898e163cdc62a3e8dc4c20652a947396d5973ff8f0b1141bb361530011604f8f85b911302064c69493529869c5284ecb64bbf00612b259b859717f89bad2bb71be41781fc011cd26c93c7028ea35389817bcfa09b727c66f86ec9497ec90dc0a89402611b71ca6a513cd4e568cb02a7f9ab84135f7c1b43aca898780d150636af51b8e78c754067f872438ac7a6270fa9ba3ac47dfd13de72202740ca297f284acd317282733f652ccfb805d628887b1ac6b22fc0ee4748995a685a151aef80cacfa6497f23156805269bc346eab122cc8a16883fb42ebc19dc2c81065a773444617d0fc0cd150c3afda64aac933823864197cc28a672893f926b562cfdfdb7fa62bcab40157f26b0dc0fc805de81719759c9af0abbb998559759b35a58daabb243fc2477caa289fd194c171be2ae5b66b84ca5c480be10887948aaf86149c5f47b137eb3d2a6ba5738c1ed6688ee6eb7a3c8bb022d19165964ffb2746c5e81b39ab7e6f5b3ad8c65b0bb3b7315484cfb62a96f76cdbd715beb261574bad950660f1f155d6a62d29449cafc43e9b0a4b7a747aa65a825b26282a164976d557fa8a135ee58e9cb1bc0e8bb38e7b931e528c7e6a2139b2061d605909375934fb3fd7273cdd7ab28d17b892102149f6cdfad1772f0b18ecfbb9c2583568551bfb33a1eb0cb91cd5609db35379f71a88e1035d875942d646783a8f11e4314d6c97934595165b23df05c1ab8bcf51783b81f435c4c74d652b44e077c7685908abe138755763974367f0ac2a63f5cac37039ad7919d3c98e88f89397a401d7ea1b06c08a717b582238191f17b9ecc1782976ba3737526e4bc152d86f3d4407549a079fb15dee5232f01a05300a72c073be6147053d712887fa909aa787c401b7b08c1e8395809876bd6d423c3e489e152696c12603f0d27ec9e4caed1bb9563a19547400efe30502d99430bb378ec397dab2a553330a34243839876b5ed532fd469a7df044ffe90354205303009cf7f252dd6b0aecba8da45a8c683413577c787ec8ace7d17a277561a7f271283895b380cd294974520556e072a7ada4024a2842e3f20c38cc5da139a1cc496fa583a1b1410a15038002f1a17352972347ca22215739d53b27e53dca17cbd2bc616a804d314373cfcc1d72c0736fcc3f041455443c443e72875f968d095b18a7f111c1ccbbc0c1a5d8485fb207223057b8d4b754076a919f96cab4db533e2c48dc134c190b478fe6635d053c476959ee4b7ff2754bb4e7c8b9675791d1a84845491902c7cc99a300d4a1196a9f43c816d7013794e1b3402622afd8ba997cb9aab2ca302b8f3af098dbc62d44bb3c9e35871554c6d30840ab3c7127a030e19b4c1e382228b5bf481b0759fbf1adff00000000000000000000000000000000000000000000000000000077ff9fc5bb5dc787ddbba2b73876efd905154fd9ec65b71a6253c625d94f53aee366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = 6e78c7085b62594c22b881c61e63674892e8b15be6b3137030cf91834ac0126295c6893f0c386b7670821cbbcafac5d4211cfad5c1f75deb8e7df047b950fa504c189fcef6806e16c7a447187a7877ff91d5aa1f89d9f4c2f8c726dd7cbc688e247c929117e01c8cf93e62440ac3f9affd27ecfd76d525dde13ec8b3a6686e25cea8e46fdb3a264b4e1692bcb1cbfbf6e750a1faf99d8864c1a9beabe0d436b7ec5566c92be999b165ff4f30d6ba43347c326edf4a41ecf2d35cb825bafe62184cfc28b30419f509b631f9affdca2b3b78771fdfb006f5b6cca6d0f5522308543b4a1fc65463d8b0ef14fb3fdc160178692d598e59d71110447fec3d02a58556bd1d17d212bd09d4dcda359fc4ee60dd2f0c73db72ee684a28b550f6b17e7dc8e2bd1867076222033023851676c0a55956e14f2c67874217e5349918243011ace52437a127c1a743a52c7c6fd8a0a007d5d020ec1bfb9f98b0ae36561eadbb5e23b7202d909c7d5fad270542c2e57dd0a54fe7179050b7ca81d72fc8c4f07f45fb2ac905e209a3ced970bcf5334daf441a0ea8f250d41be94cc33d96a42a067654f43047cc500214d0a54920f61728b6e95a014926f03faa1b27f6f5cb4397347dd0744c09ad92608ed7cbc0bae29092d6846fbe0fa14a38529e00c165a7ba098c16e532d43a8e4bff1490c45e0a33bc02738b4a1958cebeb39fd30ed7026b3a015863c2e4a2ca00635475678132e7fc114fc8e891711241942b787384ee22352b2811cfe1a22fb7e8f2e173df93e59cfc98a677a136ec29bbd47bc66070a7a8fa3a709aed2123ce55bf27ff2d23eb87b9762659d16ced5e24b7e825e0b4c2e8a6b6cd1596e4fafc06c9e90a8f0137ad182662f54288da8b590d42c6fbf9bb14cc8f23fff1abcc5885ecccb580d93846b2ebec01bd528547765fa2c231dc1b5ec3b3263617d136a102f6e02458444b158162b80e9acd39ce90db232582ecfd679029c6ed4d5a17f28b4ef2a120455b5933b51d3751728ad07e9d1ae3dc52d690d5838cbfc8c8d5bd7284dca1b753be3cc485aff60a120eff28891e902af0ec3358785a0ac87f99f18f268d73c05ba725de2cbc82d2918f1694c3f6c813d02f341c9f40a7c75bcc5984d5ecc1cc308eb16a9c1971d4f8e6a8d5ba59e855656543c0c7e5b7e49a360bc31c9411da0642bb815703bb64fb550f19fbb0bb993453ab8f15ca9ebddae7ef5acf2910f130f95fe1e4ca602f7e09d605a4dddacdd3cf5c2830a7bd1fafa1d63f7cf4ad511303ce42fb6348397df469a813c822527b933747f8f419177caad0787b63570cdb807a35a190a46f2150fd19c18db91c9435908d79449b23430c1d26a7354b6b9d1d21f31d160e767681580c770bb264dcc24567e88a8bc6512831fba35cf6aa4fcac1040b200df1c60b88a3d7e1550f0a27e8232dd88a9c751624198f811ddbf1c2a833c58b91bab501e7cfccb5374c21482808be44877ed51389234f3bda65c44ab5781da9ee3269a0cd4a3f13f50ec1445c859fc164774cac725a3b561bd63a97170823fdc07bd6ecb46bcfcd76384e7baa0ec3c1f4c89215e26b580962502a4c06aa26068c041ff1354ee9ec07da71b163901784ef525c65bd00c403a9445ade4b0bddfc30e04d278b4873dbd1f18f4587cedf870d958b16be02ecdf3a5cc435b49e0e56775521579530013aea6a081aed4a5774bf72918526eb290a5bc1ef3f0ed9440863c1133a70b1481d46b6f0adb352b3cd4e50bba138570b8e5617e3a10b6382970ace312b95d87f5e8a6baea10d2ea19546acb5fcbac0d20e964b7c0bd0d1825d3955971bd657c316710066d81ccc421c786f7d21df4e748b47111732f1851dc992322d5b50cfcb66321b46588b39184c503666435d620eb03a3535b9611e7aac801e9cf90ecf7671f70eeec6103d6e00a2ca5a6a8424e645d4fa89b058b5f77441437e40bba596d705ba522fae5fb1240d9f9e25c9bcae741b514b9ff33d0132db5f06a73964f05dce8b41a568413bd7f4fc78a4c7dbd2f5815f3dff8f25b2e82a508f5f2fb02087bd23927707bc729574777e01ed0c93557867956d8493c1cd9dc86ef3c1e48986be905101578c8e7a11ea96709929e5dbb1560bd4d9f9acb7957355e09fad7c97712e890234b335fd950e25cf59a4ccc6cd461e6ffbbc43026faa7dcc6df33a8bc5f1dae7e5 +expected_result = pass +expected_shared_secret = 8918cd0c3eabdb8267e24b79272ab6b67c9ea6418cab15e2e3070f6c747b4dc4 + +comment = Rho leads to a matrix with unusally large entries +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca62e0b7d8cc8d1d861dd052bd9bb622cd8b769551c2307c82aedc92accc3d2c67c3ecf8341290af6c93a295fc027895809a081aaaf3cd0131174c8605c7fc29ece47036866f7fc326f7c947f70852356410e22700b5480897f288dba24c494685ecfbb624bc189dca10d9307595969145b21ef4ca1c435b3d39555434e133f8ec8c00dc49f02788041a6deae40ad5c9a3198804fde6230dc25b7f86a86bc00b43da73b5b40e3943096fa4540a019817881b4421961e293250056300e273f3d87153765ec237a79a16ba89a960fe42aa887c65fae65719766c44b2b8a0e54e97aab5febb1c194939e11928258cbcad6281cd37ad6033b1c9982df721200e36cb70326403422519f3afc3451af15969c2b26957c452fb136db18357516617892214c758cd9b556a827434c9510a5f6094bd32c8633966eb113f9e4902b6306c87732b96542979159ab49a170fe71a23093c1aca70202287d8288fc2f56072ec7aefa293015b6a58a2899ed79d4a09701ba42d26c599d8a2164204563fb90ff7372e9d76798256925e67ccd5ccac6d69a85343825b6a20793095e1a29d1b526e183611bad90cf6440bd3e79f847c6b912aa1919a9e7d9357b414cfccb206180067469b294b2c4233960a40e17800ab0ce483c40b653392488df837689fd72da0daae74575da747527b2a116984b2adccba04000ab72402f09c749341be42c79a5c8198488124fe750f66b82cf272826747c68a946d2629a48ce0a777b4a9673ba9c3a2a402305506f4b65b65b327e62de16c696bca3d0b8ca44013cc88d9444a83549af17a3f8270565359b168ca721027479a6e60a28f11b33d88da4faa084b576ba5bea09c2fa8a68c0aa8a309c96119aa52443bae570abbd942d193cc8ccab6e5643d0e362049f1ad00f98d173849afb1248ee2a67873950ec849e9b7042b94222b60bd50720b94d7317053cc86758cfc0bae9c9856c0c4411e74730fb65d8b7b838426123bf68b9804473469c6d8717dff450fcfa208b8f53e2cd8987919a5defbcda5a422ed82b495c67b46264106a613ec138097f05a2f2c5efc2076b9e2475ee162a5e7242cea1598088f8146bc8ea65909723fb7a60b1db157a4f43158457d2d157a1f980925a396401450b670728b2c7ca3aba3e7d4b4fd34b24caa87d45846bc2104e95a1d9a5676b734736fb00f7b3241160c2299b50e5517bd4faa859b79c8590c4322115a7c724f0767c056620bd006c01b5b87d80091bc483e5d341d14149095045d0648acabb46053e78c84045a9606bf82f6124fa9a8a9104ebaa734e3720eb6921553e353e66152f2e96adf34534a06aeeb677fc4f901bea148d28411f1f856b4d2cd261526e3a8139788796690413a50251dc1763703a42ee708f932cdeb9b7ecfb2c7d99002bb93cc248a133b9a4c8e910a045669ef5bc75113ce12f7963d665d6662246d383767f74317dbaaa3d0b855bb0274815442f0b66821cda6aab15672192d20c6aa8537432699ca8a22392a855323ad70f75979b56b392c29caf9c072885710c33967120aeef0bcfca1293df8181ce50dae21577701b1fa216dadf19fee4c35e0d435ffc83de3f92c2b276461b66398c75c98d92628b32a2ac3b571853c4a142bd5e81a8770c9d9359c91ac41aa2b4b063a9bcaf4592cb6626c213bc89c6eee3b75c59a21d6d748825b336f4052c6bb79f4ea13f51b672d1abb32887f1977505a75c13f0b66db14b56956050550ab0d85a814640dd3a36a825682c9cc6d6f13cf132780f5fcce87355007f9021ab5a5a3a69369c7876a5158654bc9f9400a1de60e71e34a370372f24cbc84166ee68b6433b6911a76bd78fa249e850bab6aa96ad820e0dcb438fbcfd9ea81f5f3c0d5d53653ba288815029202807aebb27402660e4b3cdb609bb7145dbc055fa146466b121e673359a8465073d99b63e799cafca95733938dfc2ad7d6007a36a8da027ad396618f1647b1287094737fe518b779f238b1ec0c9351b3c408b8f66b27f5262693826b24842a9153a9d205a7593665fc172c7c835354daaf90574686a8ca7fe5824ab94f29d6a5ac87cc40b999e5e7ade2744e1fe7048e38c804472579d93309986c28962b06e80d0952ab10d1cf1d945b99432ef5074dea9c6f4ed97959fc904e23a3834cc30de35f5350656d027a1e6620925a6840a337d14a82dd524c2077302fd6b72e97a959001d3d81768ccb7937f4aa07f00eef0aaeca877999e5598d30a81e920e2e8489970a31fdeb7d921474500835a01530e0177a44852cba38c3b0c297a0c5bc73db986d24cb0b323402d5355b543468f948976284dbcaa1c87c8b27cc62ce2b8306da3a5e08b0991403e7b0381adb0c897c7a994997a69ac1f5092f8edc480e77a82ae9bdedc724883b5eb3da56648979fd2337fb42aed861859aa6165a800d4c9b964e70195927359378073a84b80219613873a164324a04144c4a5b551937c23ac75e3a664a773966b512a01f3a7a60ec1ee06a068933a8ab0844511488f058b2c5bbc1c8dc07e32b267aeac8285543300bc66f8514ed6aac59cbb9be835b3ec68987a5cff5791643c60841da8c172c1ffc07110c77a43ab34621c474a60a385d153d79831922638740657030481146ca6843f6043cec1de4b0b307c52b288b98905b918bf3af0e698b4ea261db5895f7d02ea0fc59156090609764d09b4a7ed5000000000000000000000000000000000000000000000000000000ab115291ae8961b14e3b7681e82897a566fae64d7340c19370d028ed1b71881f11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 02c49972f757b82c1f5e7ff048b375cf05adac485075ca5a1eeadb615de1306d6712f0cfc452db395c57039fec57708d0a35b7bb238d1e4fd58301473cc4737d72ceab2b097d513ccd17a7f54d1fd145bc28aeaefd2157f2a8dbea391cffecfc2e1fb86c909b45e97a39b30ff59f176b2359a92cab56cf8d04ca42a08c70051c8d9405fa9aa2aaf5724d8b2a00528b7818671af4129c527bffa74702f02172bf51cb8e5b7c07438c785329807bd022fcb5aad5286642b1fbaf976af9816d3f0a3fdb79c2787f6abc1dd20fbb2995bc2a4b2408f5900c68a60f38f78037c3ddee01a3861433a7d9eeb5e7a41a56d2b2a11615d8ef8751d19cf7bc5e5e46b0944dfa61cee6dc16c490f5c7b62ebb6bd9bdca7dee23c3bf1529a4bf40977b307e945efb6451d4ae1c1aa507e30f653ef476c64610edb39201492434dcf36053f668b43746cda8fefd4316425c92f97e1900c62a91004405349c69497438aeecb876ab534220a4563138ceeb3d4edb0d70330ad031aa82dd62e19d17f62bf83dc3d4e2c3850d47efd50edbab06c9661d1ef274e856d8ae58564909625de2acf771334ffc3a3d7a0b1a382e8a17c1a1dc0f29401d9a3dd198a4ad70a740700301da40b468fc4232ae841489a1169170d5131d9b0a036149eedc23f2abba55883ffbfe4788c887e3248bc1de1b3677f286f1269d110d574d01199524d93263517afb76759bcc2728ac595b004508946618b55b0ca734431e85496f07e153f9707d876b6342cc99be864d9d603c645bb9731890d497d85d955e2d80e2e660c93968873eeca1a51157ceca558c0544040db61fb4ac4e20effdccdf950feb214971dde984cff17a75973b8d3a8cd27c92a8686fb93564def326e3cb617411892469be218d663a009c37e2d573b59beb4c5f62206f3a0df818608583e73d12366fcb1d685650d72ca4f533b928c0b4772ae645f0b0ad71bb8313a601723b8f90ffcc53dfcda9d092f8931ef168ca2f53d4600677833b9443fdc05db07f80c03bcf6e364fd4d85c89fab6a08cc9399b10afcb908cc4b6b6a3f6a4725bcf8de94e6515345e333a8324765ca69ddf9c61539d36c67e91ced0396ab2adc022ae9fa8e41d5a00168cd8c9ad0291f653af63e67b90ff2d448fdbb058702c551d323f5916ed90f6b87e354944e167887c5ea4b37703c8b0a94edf20d188ea989999deafe0a6de995434275b18d17a33b100032f2796749a385d972542dbc9989311068e84f3629bbb797f7c6f1057d99185009b5ac0d43d7b944b2e5f528cdb26ca14d995671e72eb725bf2de60289da1f06d78b137a79ebfb75425446c20b4310700053cf3ad58ce01cfb4d97325a27e5b5eda3cfe1009cdd186313ec3d16f005be47c8f38051cf2108b85ec43aa0d527b8d3bdae4e0a7a711c6fa69998bc26a9a8d2f7433f24f79c0dfc74a56083b42de7860b22c45f0c6e31422080c7a21c8d672fba60ce7652a90a3134f54594eb0fafe5a953e4f179ab06ea6b9795bc31a4f6a7f18bd5f1800a5263c48da4ad48ceca613fadea7741dff9d90f6400aa31519bef0b01e3312a5042ac35362df5e61c8e04eb52bf5bce0505ea7233b516321a08185fbdb9ff8434b4c6a88f880f594d100f46924a26f468c754d6af07f4868cbd7aff2caa53e5146df4afde9f7753484fa8be36baf89ebd4741b7260ff1ea398d59e503f5fd6c5c543ae1d318dc1894a48025c76e872fdc3026bf33a91b4618d1618554393eef6f7816b7de65c4bfbb55353cef9a53ad35340049ec65ad5af27db6fa597eae6499a3e5a192ed731915f6ffac811e35555ba5ffcb6628f812bf71a268620c161fe2a571921f5bceb4d0cdca776c7e52f68140845f455d247cad416c4de040bc37f5421e2b8bd6a049db84f0b3c807c3bb9d47cc7ac3ae9599ce82cebce8243306c0f3de6af1526475387c76751b7412a227571450599120570cf3cda19264136e0a93b4d25a160dee03d3d812dbf172618f58d09645becacb5c287b3b01ce4d1121272747648c50112c44728f66d86bd421390f2b36ed7e18b09a985a306ec52f240c0bc0957335483439f146b6c340f7e062a6059b1d47750c11cda575f8a2aea78ee09af0e06dbc2b2ac2b2bbef17fa108681dc90a7b970306522e521aa987e3ab6dfe2e1b3c6d9fa68897efc9e998afe55620cdbe9ddbbac8a0e22395d5628a +expected_result = pass +expected_shared_secret = 6e63c5ca8af98628c02c8f1d520615a1a2c4824d5d155a6e51d181e8eb44c7fa + +comment = Rho leads to a matrix with unusally large entries +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc8cb39ba3237b6f13c80ef947630578d2d213f1914f94c61429bcaea77c646f1b99d35ac8009907ccf604c1211ddaeccc2f1001b49776df94560e5ac35e0a7ee3f39377e252d83558d6e57651b0b3c0365e6a133dbe3002270a0bfdc524e5d298b42c1408e17d155c82d69c256f78a69937843491153ec2117ac40370934d28783a69d0a02526afaa8600d289c27e9481cb737cdc4b9ddf53caf313b3c4b862b08045dc38428b126622d77ff3864fa93919427b049786042d234429e9858ce7b1d57a2fe92979851b9d4ca23fa7a80aa4738c9b777020b857b8fa2e442522423608d51b78c574569b9746e441bed403ac21391fe327818dc81355bcb2f5758320965e10946cda9a7c1d329f7c1720857c8751e57b87186e8dc21199e3b7ffc1c4c5607cc3c258a30163131c5db5d96e2e8c2f209419d5a03dfc618a53b1799cf102348b89ba289fab2b206f61688fd974023619fa5187b8cb28be778b666294bf029d7fa9abe3ea739f131930a13629bb6fa7221a788591f595911d3c8a6625a0452bab83196c047889f7eb13897b3d73db6ecf5c9687c3a97d5b3fca3071a29cb82902c7a4e673f56842129c4e27254d50c2a9741abedcd925a62796d9a98733262e45366a5d7b81cf7c9b3c42a6b2f70626d0adde9311239061dd893669404058da8d209ba6a6825e796c84e765b348414447246f57acad8c933dcaf752ef268bd6246f6b57377cf82607a522dd7028b572319263c9a9805aa6501ca4ec2a182a25cb751ad6f0a0a23955986155e0a1b0957bb9afb35320da2b20e29210b2605122791db13adb91a0fed0b36bca7d6f03b0ca6c8597b56a189c10ee887b4429b0cda99d83728aa6f57a03d182685b2266ac1f70645b123c0ddf352520332fb5ea06e716b010f82c62858c0408446afb0ffe23ae9241be953b3d05a9087f8738143c3c66b5b3c61ba1240b99c2f50b620038d775706aa58cb0f7094d52c755b992e008c2419b3b4bd85a41f65bf633136867caf5872d551340f377c06546495b8882e4e14df8a958a501161c547146fa2132160fce98c830a5b42784cfec7410bfe87f185657a29508bf339c7871ab9de91423d23e90ca2bdddbacf7f4af0f616e9626a3ed4a87b9b900b2412b0b5328104479d33046f54a06cd88a3d0c9780af5807e3517e0c72d45b17106a136e68a49521364e8661636f250fb679d3fb649a0491d349a6bcb49a4e06552ec60b33f947e37fa11b6742ca9119f0c6953f8175deac4576292165f42110c99467b008f53e25308e560fc845df84b28eff321687c45d6d09d96533f1d0078af998a9db59cc51b1ed4ec6c13695fd33a768af521bc9c39bbf6c27c6266ba271e5d8cb89982077f553b1dfb5341b5caccb856a7608cfee57ad3dcbd782ababf70c4f825cbe1279b304c2cf134beb0268655951cd76079b06410737cc10550c16cb9848612b6b7652d4ca9bb5be64f08236b69a097cbd10014e561469b7a68723160d91632d67f4908622876a29c59682579b34a298cd01597887c1b4d100ea724ba3fc8960356b499825c5223585024a478d34561a98d0c23930473ad6da637666b454c7882f0a98254f41caee03e03067b3a001f303c651489c1d00a825537c2412826a73959f085c5d6a836836582d938b9d999b591019219c906f6712fdb52b13bb8708d0c570a00bc40f1168b80b9c11a4e72430943c2544e2bb910ca5c4f0b245f4bccf0f0c3a284757bc6c535c6a205b34cddc15abcd92dcee9717b413568b461e2b9035756a312414e2644422112b49a3a23eed98e07884c80a6291df38d5bb039df15b7d89b5021d691f1a165eab9242b34146f6b223195bff19c6c6197a5e424c59572502f69c7a8b633534786e4d8c1e280680361b8ab5657b74336d72571bcd12af7089d4a23c09a167d0a3bcc540b8be036b24664bdb3a13b62c11eee93c4ff5bc0bcd92f186741eaf56a5f6111f161b9158bae9691b8c99cbae21c9534da07d11930b96751e3c29a804195a18781e016b6af45bd23e8297759a1d1487c6212add88675cc3b92de46c09b4315c9a0cf6a5a20e7fa9ed5d594aa95cfa3681e42a3543429b9ec551e1e74ba46b79234b8c69c0b5f9553aa12455edd971ac29199c04a40d702128cb77f63d50f11184d2d0b66befa6adf7c2bed427c82a632a81497c3831e38256784802fb7195e40b571c26a925de84f6366b3d9aa2ecbe57ac61283f5ea3648b652f0c742b9d7c2a8c00ab5b611fd36458ec71f1c49579f96c1a774a3b4179ea63b4fd1e3b172b39eed1bbbf0d27aabd1befa0232440b336b53230bd60b88da4c116ac47b971de59a214a0752e75888172386ab2ba525ea50492a59467a57713985475108501cce687bca50b6c8840b03bf2a5072e8585f33625a9a8c17160fd7d630ba54c2dce9bc0ab2cae4965ddb9110ad612c65c8203e7b462ff86ba28abedb808f70818f022413ed5a9a3b0ba6aa24685fa91d5938a69693862e31aef5054af2f9849d3b1d22e121fec251c8f358a0d320efb9299df6194cf6cc5cf0c11363114abb8069e57634ba173ae199b080c1d935558c16696c97a5f316a4b8565c20b266802c60d4272e49c2a5ff794bbc914240f81317558a8cc862d9783630d90d99f6a68738219c44b9ad5c07b7242e85d71f2a958398e25047f494e7f6acfe339f98cc2d65c114a537b1259e000000000000000000000000000000000000000000000000000000db721a7dfb02556d4951dc5f3410ec6a5b8b78df5ec7b511533cae60713fb9dc2e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = 841dcaa46434e75228b0bc10733771ae67fdcbef99433463b2aaf2da88a98e1bbc748e1d14239a3a91bd2b6752b83302265c58d36f176b15988a3cdcc0f65cd72eb5486913269eb31b42bd0ccec456b72ff18f3801a1ad44c3ae6eebfaca59f2ee8308bd6c4c05a7262a01f168662dd42153bcf885ca7e84adfbaf6429bfacfde0ba36426b17dec09cee0591eca54dce505b6f23d2b674fba0a9dffdf7e77ee007e7570b31c71723047c3e8a271d6876261fc1766e1e468bbaec2a42960c2f0a3ebb7dc5d5d6d75a24245a375d160bfafb01cfa2c08831b1ccc67bf9d05df3a14d8f4b170e145311a793a92b1d59602e45328e58c5842dfa6d7021e1c65a900e0b04a79b17edec62c5d1c2bb8679174b45da0cfa336f7a0973923b8812d7b2015e73c42e1219900cfc3cdc93824b55724acaff2158d38732c429883b4d461b74a858cd167ba9e47f8157834f2e758cfc1c8f0fc5e762d56ead723cac0759cfe5233473b9706be8d909c1bfb2cdecbe7eb15b74b181e8fb949aba6b82e2c7c1d40bfc43cdc758051d1ad428a43bc7708ea9b46ea3f202974abf44644c7614769c9fb39de6ba9fb3009cff125fae0ebf0ecf5c9dea4ef2b9a8f26fc5d27d875e068ce3d319f816000f1dd560d03cccf97c5485ce65a77a326ed0fb2ece5cd5a55661c7b41f4b08486770cdc510f03b2b85c73b95d0d77b0aa75f677682d0a383a6e69ece0d5bd62568f2f50dd64ce3cd9e51556043323729b165e4c6726dc77c78025faef0653e54c6474834b9e2b51c66bfc8fe90e6e48fa217add307120ee0c00e8ac8988e5765e66dd0dfd92c80a3b19eaefb46585f0078f5f2de0b9c83ee10996b27b7c64d0f7b4d3be78ae18030bcd792e83bbf99529d1e7917bc053846268ded779a622e83f5d2fcfb0c15bdb1a2621188037acb8999ccae846ab2664792b043903c3e6b59c2645ca44e2b19cb21122035f7f3b222bf382800df1d1d8926eada144f880ecc739bb5644986f0a3c1b7cabcf3c9cbc7938802274ba459c1b870ddc516b5ea871fa6bd87b8cc5e47541f1dab3b9fd63865bb514b85155c41780b6ae24a02a06804a319d3f8d81383e7c8167853f3e24b35e220c105dfe14c33441f928c6dcf63a606500539b602f3b3f547a49545fa43f3fa6bbbd6049d9769ae5ac0964d00d68409abac87369f9608f2d244935aefce11e009fdc9a94c4a803eff45f989affe68c4dabbb291de0e7251a82bd5e5d19bc165fafa25465066e23dd905dd456e0d02ec3cf229c330d404b5f214a37363bd997979fd171584a296cab6e37928940f6bde0d1ed593903d86524449ad42248572680f1b573ede4ae27237e56755485657a5f542577700680308cea4a0d249e48138743017078e668e9ee556c7ef5a83cca9f96ca22beb7e30e2df1a793c6e2f402f109770ce7763eeb057f65bc0fec1fde8ccbeef1441dc98d059d1589564debb2a993ce21031c67d4d8c61ec53160be67aee11ff4b901bfd7c91f6e1faf7aa525aa8d15c3212ebdf0e3a5adc57690d446fcc9435caa5b1ed174b96d4da42851545ce1764bcae48c5fa580802eec2d1b83e4307c1da0dbb2a0fa414d2db8d6335f898fec5e391d0d7c2098e35dcd68afa8adc29d5eee9a9cc6a517ed310897e69eb23ce83e5ef0535c0f64d4f8d62a962e8af80f47a7f76cf735ae4ab09db0b806a9c4b2fa9ee493d69e73af045e6a1eb07b5bbd3241ccce8b5196080c2953cbc50a2052126ad754dc971050150d7ad4b319fd85cec8c4be05b55ddcd5ec7e804083278495b1601792464202969dbe01488f876d1655e0a3f4879ba41712c9136ba0f99d4bbf3145f34bd6f4edad036e6db0ba2532e35c6c097820d1fb069f9d69c259fb17b94970f2cc8284e5fd80f4e6070b4389bcb49ca99f207d002e44f6f0c9046fd89c0ddb1d86b01007c02920acafdf28e49d3c209e3bca054b67398b6c6c2561004c129947d87d33390d28489855074a6777dbf72816f0e1bf9488009bb0a247784c8a9b8f13a163d86a614edda8d205058071c12845b21e82ead309ede45872c379417c536ba446272ffb63d924d0055a92c320739d364e3eafcea6d10ee09a58a70c6c9a88550327070d6de72034b8140976856895147e2a1ab4ad062c7d299228a50b605872e3d20daea3e918f2dda9f8182aed61c93b4a47c5796478e182ba54c87fe +expected_result = pass +expected_shared_secret = d0ffac51bd8b7e6192ac5954b26a5c64f4d0ea746b08d9f73602062aa8aaf7cd + +comment = Rho leads to a matrix with unusally large entries +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca584a4780ea352e9dc85393457e71ca62e85abb2322aa45c4fb3d29b15d55a027b8a74186000b9a05550b2a343a3ac21b0f7a2b2aaf736a1ca49df5b61fa749266b0696ad7b6c48b0dc82803b10a4b64d6caebb33a13c60effd699ad44c1985c9e3f8ab21a0cbd728ab52e07c4bc5ab3f6c698ea307f435bb7b5545c44758fee3b9077b5a318c2b584012cc9b57560236be789bc4b026d1f26a857365b2d1a6e809a9f71e140ec56c4db3829b74539a90345841483daf6840141100c66cbe057261fc346ab8c36b03cc2b2ac838835cd373836bca05d9f57ce2231980ea1bd9908111e79b602572ab37495e9f6025269713f4318dc472d06b473268bcc7c5cb956b5a1ebf419aa18b9d6f184849240470607fdf6325ed561c270b095079734fb61e04c531be893c2621c5ba48bc897868126b995e75777c8ceb100c67556484b71404be802ded5299cc41a83b0c7a99c8d36d55f7fdb4697c446904c2420d667f5e58e0837778ea960bb6605890b8437f24f7d35acbccc41acfcbf2e35270ab36804db6353d04f4a88b97b6aa5a6a42a101a535da323cae6c7dd757de67c24fc0c1dd894ba24c26c873172bf2c1ce63c56cb98189d60587cd76c2ff70cbea93a0d0767ff347a071333986226a8812677e2b5e18a15fc5b2d23bc03786b2faf8a9d2705bcb6276d2c140509f67a123a34a98bc879386b5a596b4fe77f0caa5145d766e05834658961a4aa3d5a90bf9da5a53ddac964e62216d0a6e39934f00c6ab988cfe6334a69480bfecbc7b100b621d471ab51725008a21f404142e489cc30cb1aec8dbf99038c8989ae8c477c198cefba1f3420951b660026c820fb406d19fb0878677cbb852bf5978d99d33f6fd7c3aad87585e68e5dd5a444a8369749ac03902b91000c0d986b26029005ac6daab8b0888a75b75bb667469525a70278945e2847cfcf242b420a10af98cdcab58417400b9d58b68f3670aec0ade93996a8e16d63337444d0b7de449f3ee63b30aabc9ac2b77d5bb13d672ce9db86770b9c21e11ca3f42c2117654c657da94c451c319e1139088d008179707eccd6a47d68677c692c9bc7790a6311dfc244d1c67eeb3420109404a86ba668e24c09b6308f3b09e546cb20db4117c74b4124946735ae70ec8147bb2e24784c3b4a24eec5ba8de3269054399a623f0050b5d0c10b5f5139b0786353504216850c85677bb596b2ac6a5fd4c224bf61ced0fb031411a887066d7a5455afeb8309058485386a023b6c58b5b967557a5b291698d488a131826b958df717caf472118d96a3b6882c1e95240909886895a0f5946aad1c690b7a904121688f5685ae775738307786c5a6915baee72b3d71103a96860afd696bc70b880c019e6dc77c38e33817db195ffc2f7cc37b4a6450a2e787d2e65c55748be376af57251974ccbd8b398858971eb5ac62f7156e9f2b43d6c54a51c40c55156971804e21869933771b3ef64d16e48ec5195018425d32b56dcce1844f33600bf366b9237f6ba451fef0816d17a00542433dd7312c474f2c1abe2e3a1a12b303f9d42891b12954473f6eb41ce2014bc083732e7a4a7808831ae478bf2865934437d4874b6e5132ee99c727798aac4b99c7494fb555a594d21bc99a014001b7d06612c2b3a8c7170e99e037a2d50f33e61156c519a1a15dc78a60afd1c2c159375ed570878c319db912c1745b90321ddaa48bfb80411197b2fa146315bcaeb292714ab7576d946b3927a280319395dcc4a0c431692c7848d10a36dbaf5d78af33f62c25e5c4fb009be83a5b93e054e587393c48ac1c65a524a0cb4e6637fdd90e43346fc9a45a720898d05b4d3743a0e2e40f4cc77237e8913ac0557db49eadd7cf00c3695379b06602c332f57da6409b3b888e7c06898fc4412444c677482003c73fdf07ba45ec968591c3445b14053a8077e664b9964956fba6faa50d680352a4c8378d208940722bda766910403970e3b50d863d28400512d7adfb372052f1cfd3b24ff4e46695533449dc232a14604a08b00da1ad81e31232412e72d180826b968513a2dcc724085a3ff0d5c3a7361f861a3e02b0308b897ed9d35b14a4159cf646336ab8c0e273a6915a14297abd937afeaa3f62005a001417d91699e4166740764cee25b91fc2c44753a3bcc2a8144174cea18546fc513028018aca8cff714d6eea7515db543a192d8695b1923642228394dfb428cf167201bcbd1e217ed1e2391c616db739b09c9a0996c5bab53bb5e1bb3aa547937dfc49223897034bcfedd55599e15641bbcd1b0072e11ca24ce7a828776fd0c94bce2738eaf13075aa7340d51b30fa0caf857f1c5b7808048917e7490ab0739147b7cf229953a633f080ac80c495f5b03355bcca47a94b60e95d72a29147f2b677c6a106f905f5349933b0b7600358fb009bace2c229246aaa51a95842cee212c11a205711125c4ea14d68a833c2892e8bd265bfab3e7b16cc2d34adeac46aa6e92598d45d972577fd76a9a7b954ad1bba6ed63132a375aa29b9eaa42366e2aa8da0374a19b16389a1b36c025168584a91a4328071de904ff9162a06a8bb9b9030f4571b1166133bd11f9fb9a2214c3f838a0a6106359e778fa7f504c6e719ed9c2ac66479eb1b662c8571d7e398f80941bf2ca0b8791bfb51693fa95894f25f2ba53882e450eaeb0b3ca706a936bf22f6056588144c1c3219f0eab96c000000000000000000000000000000000000000000000000000000209ba491e8a9350c68a6cb643fe16e7cea65ea4cd099b14c90e7a0f627f502f45ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 8106cd6746bff4925c2620882d571c50b36b066a5ea43fa6528351d97dda7dff1d9e9ee6ddc640ddb88851844c388727c918152c41c814be39f274183e116432a61f9a7c1885f07bf118e4ba631598fa9b1e01e72a68ec43dba62235587c9b9dd1c8e806174ad612a2ffd477e8d0edc2ebaf4036393283b55144b9c83cbb31d1674565abf29a56980dc4a3803a389a20dbf78c78a907a5d651649c27c9771ef436c189d1922564397f5b5594d7efa951ba7d05962df80c49c1f73029c3d7899852d8a1fe03d1245a228028cf713f4403abc64a9093d782cd1a6dfe12a79098e07f40904ad146dbbdfa919058149b051bea097a60aa0373cf9c0803e8da99c03a6b83813f99adea8c87e6da09013947cbbbde8edc3b7ca29f3180882cb11bec706f4048a20c5938560ea83380be5cd75f48d77bf3360fc131509317dd72b9340bab91fc6bf7ce099bfa58d6c5a413fd2801a15ce7ac6f6f2c0447cba39987a37695468cd0fdc982631d9b0354205194323e74d41c54e0a026c4e67467b5595aae7c8346d1bc5538ad0acdd56fcda32f95dd7830b65b2d98c05355a3ad9c84cb43c23ef9845250888ecb6f992da17f769a13bb7bfd621571f98b42a9aaf19d0626d7d59355d9730371b29a3868b97afd7013142866e0b2f1c54841de47c47775940c58475c96a4881bc69c6de346e05f55cab15d497392fbefd2309a834c733eb3ec8df4ae65ccaf690af492e39d0b5c91d09b39966b31b47ddf6751b481966f19758dbbc373debf284640015cb197e53120e0a36ab02203e0992f35b4c8347021f8c4663c996597a466b416cf271e04a20045639635b904b63250817c29451dd2ada5f3011500f705c2f0982d236ee1cd02944e35cfc6704f0e8fa30d8d2d595340b4245d3f3d5246d368062b53f06ad365dbf12c0fe7f492690fbf3389d234e76a618e63f785af41b2f4af70be0bf0a917df6a5f34683d931604c6df9288cb9e38b8d8396ab2e21a1c9a54f4dca2a4985c3c4aaf20af5e6fdd126860df422a894dff4a857f2a8aa54c4bebb70d44a4ad15d47497be7e0b7487003ecd6f92cec84bf4c459eb5f480dc20bb6db735cfaade1ce33782aaffa6a39e4f2ce9e7df44347b91d75bbe71b824d6302608dedab325d00163cb9e0a274ce49717bd6ddf4b9c02fb6986a8f765ed565f48c10dc90f39b93aba1a69a832e41f2b0dc2113fee500c99471ab67e3ab5a1cccc0f92273739eae4747de461ca3ce6161b558577b56af9e695a978970473dc671efcddda2bbd8d15fa6eb8ec0ec9f479bd9b8d3dd4865460846733856fd57664760bbd5ed354696ce6c8b44c6ebbcb07920cb6c3cf769c005503add472c7374b8875d714d25c74e2d4390ea455e00208763f56e475b630a30875bafc70f87f541bfd0a28839d441ce567db3be7a20e2773f08ae73f9686b95623fcfa7b1b3052d64448756f9a7481b1d9c6022898e79afd4c2290a9ed2e0658c6178826ce94e0ab460798a88cc54558c51239bbcc5347d59ac87fb6580f84aae6492e1ca700093438889fd50eb7028153e8b4675fd272667fa022b17029808b88df427ac048d8b410f60a56ac39220f8b509ca93c34c7dd62934f62a7e29aa3b0918299fd5c56b3c3158775a3b3d5c78aaf2f656257fdaaaa5b7daf83294b5fc48d08922ea6f5487d647c30b1c11a30d2b1690958fd90107a0d6cc689441a36d04039bea83c447e79b04bdbcbab04427949855aa1a32790075438ca6ae6f7897581b4489ea1dbc4c025fa1ebe698959a8145e8f11aa1cb6f742d1be789cba73fdea457eb0abf1e814c931922f451a7d59514c3e2526b1378be1ba8ce317ec3fe2e3d983edb346874f5251d197ea02c7b16fef2b7ba8cd3b0179b1f935d4aa4d463bda2d5dadd6ba96c0ad630f1eff86e34dee3f2eafb9cc5f5ed13dac2149a583e2af8db3a789c39f751e645acb58743646c6f65bb12564b8f26697e80b8d9636b0833d71433a0465dd501eb313158275608390568c7130ae5f998d3819ad7f3855d26ddc9f4ec07a36d191450dd6502a28665eaf8235a3f10b90aba654c70974038cdc9b3335d9b865da8a07be70d53f6a5edc7c4a5f4b5220c8e7fc01f5740360db072a4f8d7e80246dced5c75ad642ef1b41841f43e6e422f4f9131c1b3f505197f18571b057ed1cf2dab2f37dcb88082f8d8291d13eb7abdbb14 +expected_result = pass +expected_shared_secret = ab923efab9857dba5a68f9198c4318f54a42aec38d194133eb7f5dc172478e79 + +comment = Rho leads to a matrix with unusally large entries +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5dc9ba816e19d8a177de33a855960b7c464cfd51a7279a48c80091ec357b9fd118e12f00736036fa8268079754a4d565773f2a5d5c913109a4606a276d07372eb96474c7722d85a17a50a956b3ca8132415b2c404a0288aadb44fbb00217c0005ee36137768c3d4169d300ab2876c1b2a92c0cf119fef5018bf7acfd2031929b9671898c64388898fb74a483a100ce2ae67275e53b00d94c2888f831a286631450308aea2580fc5cdbae53b7108a9d3cba88a437a5c0917dfa3bd7fb2266f2b2f57f52724b67e58cc2781a95191f60a34d74199102b5fe941874a4433034ae6c9aff9e2bf16f01781d72424508835e3a587903eefeb0b0d218e11183cc7293c81c09cb5fc4eaba4cdf22284206b23b87566da704665527c6c587aa3070b01e79094747a87ebb2b9e5296a2405528c224ef45ee6fcaf0c537fa2e2479d579d71a3400793188d895323f274077416f94c4e68811ad9c73598d7ccd53bcd18f8b1cca8bb5591298132258f4210d36722217c2fc5925330d03d1c037cc7d520f52b7761e61727c66c5cdab43ea53041e25b36b56a323a12f70c99eea25fb4d387c1aa2d871244021a45ab27a0709583e0c8652db31167da21ca46b84002ab009a8659656876a037e844b6c027545cc66d783713a79b1bb5021e7a2c5deaa900e595503cb1bfc394cf65707c78a97ee522be49c2c08de89336b4b50270ce189bc81fb6a464a853262791c748714aea70e79a6967e62566492157b4bff737804b014c69f41eedeb07e47cac957b4ca937cf4c907189606a9187c700a7b6756c5694b285ea6171625038f1c729a7897e5cf853aae66104fa1e6c66b86b643b1e37838f85bea35132a4176afefb2e6254433af76d5eb455b11a0624fcb63f7310b0c9b171d62134fcc361c2a58b12b2c53530fb658b83107e76006e43ca74d9093fe0ec4127f5866c306b791b5d033cc834652e6ba485efc76b5289304b3c774e88ce0173012e0203eda7a71eea170517114ef93f739501c6f9c9a4d56b77494f82c06753a996f33721a56a003167bc773c44d685a2aa45b61744058a1a097a14299d7a5257e27f8efa796776249878854f458d7e4b70db914e888567e5aa9cf238ac4187bd783570daa77c3a9854c11c80bee12374267da446cb1a3b5177c112a3945a92596093f77c3ea9bc2f95452b89879bb6c0028b653cb6c804d2680da39cb99233067c7b9124a27c4c6558a641718588709ac86d5c57ac7a1f1aac68c9c027cd2c0433a139f17b2972a5a81fc8763ad92391e818a8b77c43fa7e71930ab5934d58301c723825f9079ee9ebcc8096a1c4eaabfb5b73f070b43c3112af289c09d908fb8a2ab48786db29c2dfa82a16c6c8a8b34f83583a6fe3a630b639631742adc422a71798974727e2a80b139872df5420c60954a453633bb99dd40098be6952930cb35cda52a33c4728eb31fc7048ee5176ce947b194885395163af5aa5f2f53fe8c9246bf6143d199d2a797dd62b0fe67042fd455acebaaab2bb61ff778ffdac5edaf8778879c5517911a468a583286bb4d11a7f852ce921cec823647226c96110063d02a2708364e585c5ddb3914a27123a8c6ac89c6f98260009f172f644b10a27201a73812de28eb9f04cd0e4a19080001d082189b7b85c788e02324b2f4b07dcd4aa298b44b0f49efca0b9c0811b57729ec7ab7f0a6a7bd14c220394a2609832a26b3b8c29139af994a5c96bdcf13d8fe21c225b5e5f5aa2e0c7a21ec3a8017c885ab5a694aaad999c6ed14b77dba90fc666c0ef88336d79b3093719df8179e25bb59301a67548cf74122954e34fc5e94fc70b931a3669314605d609cf06f25f74f76fddc056cfa4654094b724636f49fbc3964a5ccd79580cc8a15eb07eb4061d528a32de192413d388b051660d43507c49720ec67ae41461b5ac87cbf91dcf42af4d38680f450acb9c6cec903807153b71613f02900117ccaa11e2cbd2885187a49089b63c3f1106fd5a3070a38b25c9757bb9b40c80c6fc4611334c4463e1aca784af6bc38584a72ca4db482361314fa1b18da660f440ab6c9167a4c18afe6395cbdc5320fca49aea990e12ad6863a0725863dc1009de81abf3d56ed4c70258096f6647cd3c5b1033512a742984af1a08617aa63e1b754ec93e77eb1f379532cebb7d4421a58bd133b9ec264ffb252bb8b546961e2f602aa45c5c20756f51c0ac29983ed95036758b05f6d90aaadc464e914004ea81eb74162d8a1e4bf986120c1e9d13cebc774677577f86c10addfba2b9486f9123458fb20e73c32c8a36a60f457074ba640309a7c9b744413a5622f43ef3785da0b77739e00f1268b50e04056b0c2071f8ab5451cc0d2861310806a4f180867310b03c0fd0d9781b3315c0da53d30b5a84f27962326084b4cf8e88a2087b420a9299c34a517c088e12ab2f54f35bc4542b85d455f6e9307c949cfd617dee8153a46c99fdaa1c00795296e9816e557369e34bb25b1555199dbe0a089cf83cfe019e5d013c6507294ce27e51ca5e805b894c13655ae6a0f9da6051706d46dacc69ec3898fc58ddd5c75e82345fd8137cb606a7707b4d3bb801f77b615527705399c8448f95d3c292662957e48bae0004acb52e55385f0cac2a9c76c471e2654968113c98be84c89e0a49040ef23751521558e677e32089a6969beb0897f74a52aefa2a087c454ef26efd08a555d6000000000000000000000000000000000000000000000000000000d2c662773707380b77713c51b59f8f1c67e6541a410027312c5dea82f0ba5c1f8bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = c60d4aa71649960bedcfd1ba225807739b82f912425f50d32153167826926e51f8ed961b5439fcc7a3804d55ff46d5b873e13a0c8ee7606fbb21c5e121fb8e60377ec46ead034bea9c44a685e7a588875e5bc2dff98e5529cff460ef5fd1ede8d4cf2b02e9a537887028150d0d79ee6a0ef2f0d5507c42ad1d788a75899d0b7243f7179af88cd6b7fa41849f1f49f782eb0bb727a9b0fd51ebe3f05ae80fe7259aac42c8b0a70b7b74da297c03dc1f06c44edf72773958e5a0d38aa91c35e71b27155e875f3378ad6a2d064d6d7cd56689b1a42dc4a26ce2cfc8012e147940980403bb6bc164f3a0f9055867efd0bdd3ff4c36ad8165aaba00c8365d217d4bf208312f3ce9fbd7bde30d6e4d3f1a98b0a20f947d03b45f3a25ad481fd1dc271a0cafdcc04f02d314ce3da2e1aeb00c7d3a88ea3ea2783b75e16768f0aa122db015492b0ac9bab3d3f85fe6d8e32cfd66fab8e3138402f690bfd3a5fcf09ca27cfaffca96181b8a906a67d93303069ff91c2e3e6cb26c5608bb04e05ddeab18ad3ff916bded7e9e27c99492b7525f95e02833ae827c48b1f4ef06b77633a66ef85520768b64641c5b1b3bf319c390006a026b3a77331c530aa5a86d0e329d4c7bd729992e3c574876ad9a29d79b09018e850e2e63d51f75861af33e6acbdabb722d41312294a9b302aba8e3f04ab1f04688e373f86e3753d84070bda2feabf6b94617cccae0fd427f90f43d3b686fd772292fe1c93f355fffd2683eb8dbdf171b69bb6a5c929b7109744f542a21539e04151ac7e46f5d4b8b151981d4860a366d3500c3422a2bb5c24fced0221e1b84b9e5b587e9bcb87220dd92c127be67a396ac18cfd3470e715ebd320fa07097122f696ff81923e4c2d3c0310bb8b70690dabee4e17efe6d871b32eeaeebb448f7d65fd60e7a3f32cd07e61948be330179dfdab4d748d01694d64edabfa95647a21ceafd5261cca24a0548a135ca1f7c262952bee7a291857062d3546dea97cd745050121c82a73ec9c0095847e0563229ec36046ee1564ef3747b49812eb2bd015025f077b56d63500bfe523689a6be7b886fd8aebbff18cfb6e4ca18c2d0dcbdcff8fb7a9e852f81ffb39245abc6ebb9f58a28beb15942cfd5f797dc867f7a855a3e6ecbdd9a8123ecdc30c7240d44dffcbdca05bb17d524a791ea32d60c65dcb6ae3ae3b724ae7da36b88d3563a63f4c059fc83c97ad79602cd7701749f92c02bd65f505f407b64ab3f8417d3de5631804eeae565af62d7fbf95bfe25126aa2494368bab7afabc23825d6cb03151222bec05b09a3fabd5937b7a0ff17246564e163d049e0724456576f250045d13d99aa07a5f298cd76ac73f69c3547ec9a344998dea3448a96480ece462922f76f1fab68d030796bcf570298013001414ee238a8ac4d7047514ebd5c3e55e051846403acbd3d7a581c1d53084eef20edce56c2f50443440ad0fc77a955c1e5c4d610cb45f43435b1a66bcec638ce88126ad88bd1b0d10cc5aa23789d5c8f4d9c63cf796e1ee6f7fb309855f332a648c731775edbcb4968592f1f633a3fc74bc5fbfe9c0e74d8379fc56f869e63d8db3b9ffa92e9b470e668e10acc1c7606839f2ec0abd02629007e3b1300e558e5afd136f949eb1e6ae56b5a8c21d15ec4b62b22af89618501c1af9992a3f002242288fe01140e2476ff900afe32685afac7baee893bcfaa54c1bcae65b2c9db04b1e17dec3821145daa041150f3282a500ca46c535ee47ec02b1a1639713354bc4ff7217ec169a63bbf26a26b2c712b02c76b56a8ed0535e3ee1c3f118f2a68f9c699ed8702f3eb30328118922b15b8399a3fca410dae21e7d762e6e45c8de7ff023a75211e42d1acf1d8f506223cb281fb9615b2de1848ad674236e768a0f315041daab6f491195453081535f9235f6d215e5750226ae7eef4df26469cea1d0541e7932ad917fb360f4a9d5601126b1c76bdd1696e6d59749635b844c9d416a12d0eff4c4a9e7f40860b047ffad7bce7439ef0fef50cccbdcc848b02f66bf67f2d3cd795242896c5f2cff82864b1d1f00974c9142d0b0ef2a8d00289238e822d352a924c689ab15e6e5b201ee7ebca1253b9964a04efb4d7af21c6ecdc03365b4275d72502523d562209a316a88163ca33ea279702309f8c2373514d459a5298ce6999571072852d996fa8421fa594069645f034d3 +expected_result = pass +expected_shared_secret = a6ac9ae3077504c8a7b1e5558a0fb1e7d60cd2bc3e59d615e68d5165e4903d07 + +comment = Rho leads to a matrix with unusally large entries +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00dfa8bb9d8c58e33260020a33fc04021baba0f6375ddee4a6023846a2dc73eb69758edc915ab2446b1c59fed89bbb86a9be2242c117cb719274873c8b0a2857e4076b3a792965011675c23deb8bc0cf7b2e3ee38493461f8a2068bcd899f1822dfbe8444a612f9fbacbf87a0d45f98a541c5141b230be12763a3563f5d47e369b65c10254e5f63934a05c8ab3409d7b4207dc423d537abd4404a9ec6afb1cbb529619bee740a4c71efc952b3b871043c24c0c919f74f508bc23a9c1ea8b76ac449e28379af42bb6140d376c9a4ec76b34042c7d711efb559c8c87170662788b4cc907e4882d4332d90c43175cc56eb943d589a30a5ac1ae312aeb8432a1d7b2f7448fe0f48ad069989e908d28616530246f8e817aecf6ae638acd7030a596d5be06964eeada35f6175bc0d20c26636943f1609eba3b8852531f083a576231c9b222a9f96ab1fb79aa0149155881fae91adf26c4f1e463f6f603511311351c6c1d1832f482306d66a4a2e585b7e223bd539fc45c5b29558e3110cc268356edf4bd6328240b1a7286c71c5cc17284fb5058410381c74456c1ae3ad93735b6c7d0e13621c924a67a44937039df4b4da608ab49978109f077c961c2e6d02cb0f429fb04bf7b32afd9e0748a50162bf49ab17602717b25800ca3c762145636adeeec6543c43dd20a2a194211030971f16139ab86a22fe07664b425e47240ee1101cd171bd681a681804d38bc4cd562b7675a1a4fb113ab476fb7e67009c8ad5edcb053e77e99d10a348851f266919d29204f5bbe27e8672ed92e7777aae4141a8e81a39cd83a30005127289092929a41b42db3ea2c3b9b4e14a02a45906e871b5ed4c5067180aa97a6967642a5ea52639f27665a78aa24511ec6bb8ec7c3ca2fd34fafd5b5397c75c8144894b56d61e57ef77725ed8909afc703c6cb858fa1c600556babf3cf4fbc089595606f450753c727b42c7e8a8c470ae99e40e518d73684f2810e1ccb187441873fe14cce8628efb360083029fad17c1a9809daa08df859a0626365e0f1ba97ab9bb0d09e3b2632812152ec6361cdc65307f916b1782eee7873c2313089f3bd0c5ba938b80f1b43c7fc6c3f801444a34ab9c167629076442b1cb34c9b02941368c6377098a7618ae352d7cb1ed9419d56158f9222c644f58c3efa5209317a165434b86350c1a94d21fbb065854534120e665bb73266b6a392a60fda82b096701cb100aff65b44a40a4d8c83f8c63621f44a6de22f9b4817a2772085a95597c309b6423b9710cf72720598064717b52a336a0d3d9b6092e9a445a3c507e37ea9ca126b1b8f4f702d55959faa7b80322045508b2025ba64575049738699e2e1a42630c80615724dca7e98acb40f6415f6907e3649962c451f31164e88601cc2c37a65c636b6c146cdc24e5ce6976bc3457277a588118712cbabd8dc273fd0c8c3835fdeb500fe035116f6beaf437354c39e9152c3c9999f5f98281096a0f1cbafbef24e87bbce8f88377a0a3541eb128e31a0d77c247dd32180b97bf6f8bb2f611e7a7927f7ca25706cbc7b52598b4865ed8b520aa53e6199a96a0bc79a09002e07bcdf78473b273028b34e7a7c9f71ac38bd6327ea4c9acba59a07b59433908a3b8a4cc5a01d704773621b4c750389e8557498747ebb3b8b41b99105756205b2b578f668de8c293ef989a934cd1c80b18d700f7666986fc445854c9a6bbb8c9ae050c6316bafda5e98aba4ca0b92e3c3a43c504e214193b43c9c9ccacdf4ba85a57c6da6d1a8b310c4f0b7390c7001e8004beb92bf55cc8eaf37ae07738a090018e843288a965d4e8bbbf9a18730106c52758367361f558272f3887762ea91c35a23a708394b8a3b505098f7ab8ba505bbd1763a0339084f3ccdb2e68ce8b032bc217d51110c6cca10f277142a844ce5e7c8800b5bc857613deb0e5e59b4acc72f0fa1bdb0f016ace9b02a43a49e83c207e8ab82e98fa1144a47809a5dbc5be622b1bb364e8000cfa2c203f247706b3b3dc520bb308a62bd893c3bd890102bcdfa1b6ea91cb5f86758d5339396184b2ad4b36d6c875675261658615e55c85839cb10ac8c789959cc675a976c4b88146179d38820344f319b1621248577294d4550a33e723d65f11f3f654f11f206a7b4c4b909a4b1490f41d68752aa4af2723ba9c092d371c0e2459c9361230cea1772ac0990b6626a9914b20769c51b2df3996639fab765164a7b61280049ba14d55a98537e85ca0d8259b14ea4151c787d49c9b2d291c9e2b005c13a3d93a88840f9a19d30c346b14b413c150818850bb8585ef0263b515a74e79032b3c561ea543d652076a38fb4f769318378510a8e277334c148bbf38868d74ab56adb16f75a6c4ecbca6e1ba200874567fa5d1bb42527f123faa69bf2c45e4e79022799a717c21260e3585d6a86b7582a1f166dee7015abe11b42a961d60750e2e40ffc82588448b515bb4afe246c875297ef87740a775fcbe0bd902c67b9830c6d318523e422b0060bcc5a5a5f7b267f5b53e111c7121b86a6025a0fc2716fc11025c857ae1926fa7066ab527045d8244c75bf13a1a3c6688811d35ad23c1435b4cd536c6f14f78bb5d34b4bb34548a375b93234c63645d7ab59580567f9517604837fa6f98b2b4911d9946a54d0ad2cf0747b4081b904a2d6f953c70065b0c4b698e556daa27cee3b40070326f43c3d93a7cfc649000000000000000000000000000000000000000000000000000000bbd7982687ffd48dc0a8badfdd4788bce9b1b4242f5ae1d14b1ba97c0642a6b4e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = b0ea35919c0560ba7caf9fb6352b36bba962cd45d3d2b7f6bd97ebb2a3ba6df22e018390330f75cb4eaef8c9ee9bde4a1f25110dadf363df31f3f8702a3c14d5d2da303bbaf0fb199384a2702f7089fcc63acfb29d5e53571102566866898055258241e5ec4f1a325175cf3a64a84ec50b4e8e511ec24dfdaf0ca79911b1d84b5a0872fb1618edf364ea06d7287c6ac39e842c56d6630ef38f4c812a8d1fcad73f2d4ecf8f7033c1f5ab982c5b6b8c5545237c4a3ba8d5ece30dc93d1d4f4e89d3bba0b8149ee5c2df793c8779d45de92630b292714582387e60769209ea7d00e2f1173f8817567f52fe53d908d11e8e77375e7d2f73f44a01ee3c87c8f4163c579c40ce70dbc006ad2426667650c35d80ced3df0f3f626fb52f57d874625d414aeaa658a220a4ee6350900dd7b1b9e165661b41cd0c96c3b665d789a297f6b7b4f261e6dda3f6b027ed8a308f1168627f71656bb0ad456ed2b197c672d88ea6bd61fde6dc3df7e4d8b505afcaa35fc1d9b5df57b69679811ab5b738d62a5800555fe282dd4d06d5ab25a3847b4f22725a2360d8b47c69458b55f485a1ee75918cefbac2b4945c20a7356d1b7c69f1c047ba355496e21eaa2123b5b545e86c23d4cf27011e68611290161366d6c12b340292113d3973efb312b1474807f8cf735b76bb3a722aeaca7b865530fba177f9016d1ad1a7bd86da6f657c32d6662e57cc691f5acad0faf4f21027fd761ae23456b599333c9af918166927c6253dabe508c7d931d50cc824c589881b39087e02b52276b9d4252c08199dd4943d72b4fc14e603c9e901d0038da715973b0d168b13edc26b20e2649f37d27c9cacc7a8508ab340a1c3ed8d26099171bfaebd39b0b9fedb3c195a381b55c13365139063e5525400127cc963d9659c964ef3415b31c3a2a923ed3b96ffd327d6eb4929ce1d0d26232b46da119e5e38e71a2dc97bb953567bb5dde9c2d19bbd208c85b135bdc885121b5f7195904d2a9141bf5222e98f95ead571db8fe2df9a93501b8fb9a06a3ce0338a37920fc4268e26e71f94cc218d6fad6c2cfdbf0a5855b186ccdf10f66f01f884f22503c530b3c5ecd96d9b55651b1eeb3af62cb7a4cf4cd185d98afd1b942e8f7eff849ce843e113e82c3a875fb996161e0d0185aa99e21e7c99c9636cedf0dc9aeb55a37eb1f744841f5d8fb3eeb5eef76039a40a5c643957cc81dba3fe556234acc512efa07f3a140ef28a93ed9cdd2088456e3bfad0e8377e69fbb3dc67f3864ab36f8f8422837e067c20787b80d77a30995e5d78f84804cd7c897d0ffa5fe1e7b92f17575d94512b6a4b5888a3cfa6e03be3a50b8797f43a87477982fb241f24af59f13acf60ecc4c11e558b1a4feb81f69acd5a67f56bd698888c9f00430dd8f8309629f7c29e96d2951fcd8b521265c368e13e22fefa30bdecd51407387c77259e64a62e5d705d3d46be5b6f710ad86e844e509a3c5c1dce0efe4b1427bcbe56758432301a14d8b882a70cb5c587e1636ecf96c61998bec7a9b6b98eab92be2e30b30174c87bb8bd66d13282dc4d1b67757435807a90a0b268a9f760054c219bef6c8811476a56a14994c760e21a1b786efda3fcda5acd859967b9874eb049a9690b0acd97c907c1ec6b1bc9790b1fa6c8f15518b9c18b3f0cf672d26496be193602d909efc2562bf72e83a3d8244eea1942c6b6708f006963ed1005615abfdb57cff11b985134ef3ca90116a7ae35299d1627fc05cd40cb32a83c9f9e19570ab0b4e079ae34402641e47e1f0bb20b63e551dc7c090421bb1916e970b33a6cee4be985f28ea66cbcbaa21279b45a4d3927eff26dd1d171f18ba8c5e78644d6027e7ace96ab62bc862d8cd69bdc9c07a4d8d66ce2a08601783e6d40665fdc637aa813a447361ccd9d843bfa05f5e88f1f74a4d6fd1bdeddb1c50523d731cf6cb4686018e8518525a83c2aab2fc5ff97ea1562c7cc7347482c96675b0b249f99428d68f180d6590c67025e41c80468a3edcf147368f3612456e9d73bc4d6e0a70364036f75cb6657ea99c8fa365c165d7fc912bc583f0f4e57ba0f531544282e21dc42e00f00fc59273d272a711748bf62760377e5c30c1776542936a10fdfa8acca0b4b5e5c9cabf461ed5caa9124c59a4e867859401c158080970ada9cf76ab49e250411a61ec5e83c781c269b75ed1c193bf8134d7b0dea +expected_result = pass +expected_shared_secret = be6aaee5bf0744e7ca1ca0e545171f3075aba9b4d10a71ae00848c8398e3c52c + +comment = Rho leads to a matrix with unusally large entries +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697c6b844a5959672b08796868e7107108ca4c30a58be4ff7b37b0402697aca2dc4839dc51a8811c34c8183442711a8d055b640cd73d2caff9357bdd9ad36835ae9d55d1a291e040652d020a905027a616b3b5c63c0be2c1068e9cb0a9b4abbf346590237f96422308ba86b055872e156470b53e35b2a604bcbd2b97849446684149a86d9980c5182f1a020c32b14de18c03cd0633e303bf9f8a24ff0c95d5a65c031c18550b7d7d5b8ec672c3953bb3be0c3f13925200394aabb26090a3b9a12bde30418b997abf310c1724a88b9782418d09552a63e2855b7af2196d422761f5c8a877426976c90552bc203f5657f5370258b936c3706f074c11b3b2586391f4c4bcdd959615a819aacfb48d2c799a9abb182c7a9fda6a80ee50c4a827c9f50835b1859033629a9601b5b8b357913b6de142a501974a0c191a071a95cb8c45fa857736a93400141cc325d1b4518d3ea58a94c14f9b261759281b00213f91652b1e52bbc0c488bc0990a136e8e3b5e20f41d9f218646d43745245ca4c2777099032b1a5060745e8525bc617900d53b414dc995772543cc58a6bb7c4868f8999509428a3244db4081ac6b3f3c685865814c318032a678ce19866754c0774b31cc47a6a8e3cc90d6a15e54c7370c0360c38409b126c06d4b06b7d652318cc810c774f0e66e7e547305d03109030fded56940d472ee123438551d6885922ee91889f97ae31954703952f4a3951e8003ca2836fce071e382373c36a27b947ec8766bcafb1a3105aa2b082802b9bca0e4c50b80cf9a4033b44ba4b8a2cd6d480a315b08e7774d68f8ca8778894bebc2ab431d63c931e61c5366699b65ea448c127b82ea493034616fc1b6be01243bc84dc92bcb50aa4c7a417f1b5268e93b35ced9cd6263227c849dc8b107b10120f9f690706cb0ddec8fe2b20a26da422604c9135c58f0b06aa5180ccb55adcce07e51f885998398c4f16162c33b89bb37a09b84dd0a9d0e8c90a71c2851e33b3e9cc5531a76f81992344161a837608872355d57111df72412e58c5ff85b97ab2016b41487f56a9fbb48d2e498c2e12d3972c677caae5e439c598b67520a7ff6ac9c2424482988153b145d6b40973a1582b90a5bb76716c9878dee223046f746f08323ac3a5390a6148d767c3054524b7247c26c9339c0642632710b8a4fe0502dcbc32c35ec2e1e22510ea4abc7c74980ab25f9fa58caf4a70eec2d22c1957f162f5f1c5e5ad0a0fda4c342885081d3070d773cc972928eaab2ed604503257bfe448ef2a9c9c933055e633a339792d24a44769b95123c1f9588c8759a469c049a75bcad2e6087559c8afa5b6415a8825567aa44f63ce5b49ba4fabaea311918b804c7fa2d1742945f39bc9e8256b537128a9735a0939a1150c10418551723154cf4c027a5355e1751a9866bf558672fc68324438f12d83551ea49b358cf873772ae7853b53c9627ec75479c746a116c5e66b20ce0478c490946a0af4a3a3138534c2c94a44bca955e84513f548840b929f4b4ae51d53d52225a21b320d0d8b075358b019720c325814303170b627fd6856a149214eb192659d21001d5ba6953288e5a62d141ad5ff31c413418f332947f1441b8663f95b1a8ea35576e725a83177126719889651e8f20a8fc2392cdf55976651f1c177c5d8bb035993b0f2ca020a8b22b27080c4161cb86abda574deb0c858d14ab4261b1b8718ac12c56db9071a5acb00c4b1fcc9b9880917f53cc12bdfc77103a45ce8a2f4875c7e3711b659b967c5c26497c6e2903198f36b01c56ac5d054672d6914498643ae6b5bdc2447300737883306e4250ec445b543bb06b6113db5369da2b02dde3a11b2c080732979676040ddb2941956068557e65e0c4ae9c2834671f9ff65c246b31dbfb82720c8f014aa35d343b8eb762219b0eb802637574724595ac1c92b85e9a416089a2366ac9002d01af606ee9b21868e72ba96c6d5adb51f97c778cb8653e30a253b333ae5bb600a2b064cc387b38bbc0379c77dc45f7fc45fd060c60bcac60bbc794d18a5a8ab680a0ae202c97c3f153d07058017bc0b74458959c2a358b6c3733c60374a2ad540c75785ec95cb0bc125df1e8359af2bff55026d18348d0eca6672a87671925a8568060c09913993fc6f89e2523023544938a573ad208761e3ba85354cec6d999ee1c5f909bb973e0780c84101cd3cb42319b0d5614b9d103be8477ee9713cf943e038a04259c0958376c1013445731b0a5224402845499f30449f0800de86b614718bbe333b4b8245fc1a8e0c43eadd61f11f532ddb7551686cb8b054b2e90a19c889ccf68394cd501fb92a7211b9b599b2a2b637dd4246a7b8a5f713acfdeba03fb513f998177dd8cb216aa12c27ac3a5b84491738e5a745cbe7a3b5006bae6a08b0cd79a2b27af3da8ab021893e7727192e28787a052df8b434abb0f3a5866368991aba8ae3c891a0870327c3967eac16e8bd725bde990ef882bd6e5663d50b7adf75048d3202b39b44606ba1ac33fbb7a866a59a8c70988705974ec413abf660d5e98b6d9c60454a8825874953d778ac527578769aede871242b04561ea2d6e5c8aa04ba44228125bdb4beb90ca152705716cadd283ca2fd83ed9087ac5b2c7cba9334fe936c69586e3399fa46a174170aa8db62bd7095736012b49111e73bbcbbc89391bf70af7bc3581777c54d74ac2fd37b45300000000000000000000000000000000000000000000000000000057407f828b076da9179f40805f8392d4baaea0bac363dfbac88cfda8ce1ed279c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 1feb4f1d63f08052045012a21c33c2951b16c4b5ec02c00093d54ded6f94309e44d558787273bf593ac4bd77a56fe4dc30a54eb68a2f473c31c239ba18c9ca489cd50611fcd3be42f6f5069facdbcb7166a64ba7c06ba953142e5914ce20ec69038895c9860e69ce6cc3dac6c1b28d30fe83487d40591995f091d4ea116ad2675e32bb83325b7f379449dcded935027120d01ee43b2208deba910ca7ee635c5b928e5f6167307c813c8e7034096878a2915ed2d20898d8412ae61a72378a4eaee2f227ad5467d04ab884340cbfde2400cbdbca7e07a2f14016fa9e403a2b0ed27ad1dbb3cc492f584a6b5a7525baa628303039f69cf1c1e4db920ef7882de21eda5d2bad76231c88a061fbb2829fe93149c69204e2e783009beb4188fb876a6f869eb11b1c32c2ef15f9aef62f699f9692a502a4d87e5a497097ca73f8fddacbc03dd40a53abf267f749f9ac0f7b4ce9417a0f5eafa91fef75441ff7c887dc2eab2336fd257d4cda373121af864d4707fd20965e063fae456f0bef8f587bb385f8e5c96592c9b7d6c284197ca1706e1961dadf16a2264f74be425ce117a95dc9466474c856adb20931cc920177dc3f8c93d2bb3ad5f7c5517f0b7d141b87a8c287207e64158934766c8845ff0a480da124716b11d0e257206f68f2d4334e8e260895ab83e218e032a35f8d792be7b413b2679f8044e1c0ff67c474ef4c9b7e0dfd3d9bc4252fa81922cb146417dcadae7d7a7ee96e13bd480c96a4314f31fea83eef588bbf1435528c51eaf05cee2f193c3fc234d695ba32546ec77a16b1ea8047498125f2bf78dc9510812be57fe0ec77bfb3e28f42a4d15c2a2f0b54aae023ada92395cf384a1524a24e36ee2e69128fd2ab78b5af77d28c2e9ccd6c706315d46887db0c0c4f28666da7437489e3b245a19fcee97f187327a5806d35889e63940b19249d627165727f66f50aee62dd9496d6493c1f01ed0091e985048c2aa85a3b25a4f90f6e9f9cf67d6961ca246d763d3437ad64e7bc5c58b10117a66c40be088c58a27be4bc1360d114e61d002e271c4806b872f5ef7127217d5af6092e4aedf8b5c40198f266f9e10c560d4873668d58c912ec7ec18d27249f5be604a82d50421d436a3230780419bdefd10f049f404184b3530361c5c0644c3205c32fd451f6c6919487aefb12a75c821cfddeaa14c2abe20db3ac57ae0ee8ac4567db2d1e2d0920fa036351e8bcadbc14ab73d0868df6ab06e675ee193722f93f64a5344bd70593c23647152a81acb4d1a08b62b5f0b2669210d5d7845248d95fe9ccd796d73e34af955d1c94edcd2bba91be211cacb0884a90eab8a0125130ae65318f5419810f4df129c8504def662df4879e2a8df02d881e9990148065942c0d52865425f3239c4a4af51eeb85e1baeaf647e794b9fc04ea16eb328b8b1d0550e5dad8bf6248782b530735f8f5da40cf21241a2d62951cc9e894a339491f64b78d436c635eccb855d3a1f7d64f63f23023620408df6b3d190e7965d219a0cabc0933f7d50d9854e4d4aa7a5cf67b37e0475241a5af8e5000d117ebcea40b526c5a669dea1760d7fc30519148649fb00ca434f2cd84862a2755a99531854cdc847b7d5af3ede653ad6959f49c921d4a8675f7f3f51416c39e026488c297d844a8429caab43671093cc3ebf8730a18bae06f10ff8047cafb8d80edd7630c95d008cefca78f2b08ccb330d36eb33b18cf47bfbbcd0e2f81daa87160f421603d10409b8eab53f1561623f5167dafccda4f9a4e6504a0b5e67ab5dcfae98672f4cf62e4f152d09f2c64dd81e3476839aef8538a86f3b616ce55adf1dfe9451ca48acbe210c32ea1cc574730b37d4747b580c66820caf475858b4b6ad0eb7c06ed56b8f16f83595ee3466bdb8aaba3bbf35a177fd6645610b9dc238571e81b27b94757c9004a4c512cbad25730bc6f85255ffdcd052447766219e667095d4058e5f0045e16c0fcae1aed8dcb7c25fbcaf29a71a8abf72c398a61b1a57bec4b11a8c746bcce3ef0f82b9b2bd702d92a7fabc1efe0065e662270e1ab664cb1197f00983f1d265ff738f63b93d5d95aa4ddef2ea3f473440ce7ca1558b28fd68ee09c7b97e9d4c2052fb1dd657ecf09a2f664de0902f23bacab5d64bd449a0ddab34d4c0695c67ff5f6e11044a0db15d2d19a9ce2aeb818f0ecaf8c1522276521b0193f76e2 +expected_result = pass +expected_shared_secret = ff81d45deb69b6890f147710945d1b750cf17e876cd4e694158efcaf4fa2cb15 + +comment = Rho leads to a matrix with unusally large entries +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe331704aa56092a4204a2293e77935390cb1d2b2924e0bb27d4aa471474fed2b6982b71a1c14b2cd3ae12b12d5d12919235caeb8aa3827c844bda40f5f57e5f59c75c86b645224b3a861eb9d9773b01cbba45122bfb1e4a60ada0fc10f133c546563661064adbf4a89117657366789cfc282f9bbdd0547029c92aced02963f8cf462326db19bdc980149ee0823ecb1d9e22a5effc6cb588b17da70789d813b749be180457e82a5c958b069551748e12bae79cbc0dfb5ecccc85f565c22eea1836b52435b023959b4f4fc12956a09f38d58836891c4c2b0b4502b012b868fb9bc0455c12e83c182f1637c05469708279b1f4af2c275e174ca5ed0a12b39849f49535b8ca73089acd5067b6b57297327c4cdddc7d5c752a5d2cb04c659d04f803c72507f5832e7bd528e903863b932d80c51e8b2833684a084c7100728ca33a4304c85b8cf7b61412e76373566c34a75ca88004cab21a3274bca1ebcbf34222e351a3df4b557f09904173065b460d54210511f4515180b3bc0a87f9125a0a91252c1146101738f8f11e10897f9b1b16cc7c57ddfb3e4f6b01ad6239982baa07c56c05827e838c1b4bc99f9cc40608e74ed2d123757aca9d8030a0857ee2676db47bbcb1e10badb32508b87aac4c066fc747ad09a52177b378fc1446ea5aefcc30b0d744d2240e5e94c6f12254945223aa93abd8e71fe926a4fafa2a49273d618a0a5921cbde9c6f9648c6c12bad96d080e39ba128464d8f496b7cb020ebb03fbb2850a7118a7edb1bdc438565ca33850c1b1bfa6be29b88bcbcbb3e6675924550a7427035f60000841603c2b4c9f22040f9205c9386cd1b457046b4fb1521e4fcc47c1a0e7fe072bda26946762167d8bddba8c6d04470a2705fc05a6b00c4cc54409499a4859c4148b2a7596c8c7b2e597f0912742794495491117fec96486035f270363fb88511f756238ac9faf98251ecc06e1495337529b209031c0008e4250f550c3d476352ab82c8ef41c4b8203caab3b81335613016cb71b6a1f2c9b71158526cda75d9057c7597099789782b05164d338593b0a9b5ec85e0e6263c6a54d5a06ab4caa6c8db5b40e099f0ec7c00628373c3189e6c129b76827d160783f183ee14151b3b92e72bc4c65a06296a88b9f75948a18d50f53381f59360a19daba36939c3af104362d725c62f51b72ba1c8526c0be6a36930e19de18c2b1e470136cb7f92d246dc45992879b3762c92da6b97c10a552ff7a8b56788985814d2f9c5cd316dde3b2c7329b42f7492917c9174552219719575196844144a04a0b6718158cefc7833a421016b5193a5b965eb7b689698d14a41c03a408f8713aa46a077eac06a6106796c64b67117acd1bc0220125f4408222159503864eaa8824626c5651959d0f4c250c0002ec513c0817a47927ed99467c1eb6091f91773495d70084a7c344f41e0967925734ad846d360bc2a73c96f754b065112f1f472fcfb331eb8a286bc69cc1486d58b2d4932086f40c90ec601035c3016985962da0ca3571f5f36791a466861527a1ea52dc5a6254303971ce841d165985e2c02ec5b6a92278106117fcb377ad2c6c48bb24899a519626c74da9a3b026623417156aeebadabd418a0a8bc0bec5b43316ba7d7c4145016ca515ae19932a50819ce609b9ee9997c29a9af03a05ae9aaa89aa03b4ac5ca887b7b05a14d283a42da27ed7187369b0108165ef403550c99cad5c3cf7e28bef8a83ac8867341b331c9c02176520e0555af9b8047b3753e1928c849a13900545ba7a5c16bb9b6c689102aeb73eac0c5aa093a1f92810472c29642cd2a549a32bb9029961f6c4a20876ba8f4ab5212539f543c9d247355a300467b5a0a9d130613549d17a185fd045495f06820684c86aaa18a89317ea34eb0923d5600146497729fca9a66e9a544a55c1aa6841c556cdfe7ac0959635281c54e044c025c5b466442f15655474928c617a646c7178bf5b679062ceada6c6d702c22d339e0d3a9563a252e36287fc7975725bbc1a68122f4579a34c9c84318b13a76254c6be35a1ac3b26a8c2b373c6378cc20a7de414924a38ae7e8423fa1a66367a14b198f9980aeef068f346b208aecb13d827b3b5ac088878548171451109ce1535eb0a18ed1c1c677f9ca7f60501e1986ac19764849633c408d476540d6290738633a2e711eddc883ecb5111ce01bdbaa3df0f381facb31389249e261786f79aab0a80992b9a74002c9a7432fe88243f4276599389ce8119b846a75dcaa8eb300a7cfe266bbcb3742bc1e4dca77b986be341a03a75644dda25805bc50818a05a8495fb351c0709a5c37a07759dc0c3a253a3c56740aa8095d402bc65554880c2919dc6375451be6186d18da30c2f35ee4f1abfdbc594ea6ac5799c1d9912fb173044ad995d675751294489be7674d84181f4aaeacd9951dd0be79b919e585560d0b090b750f2f667e2ea21e283577e3aa4f6b11ad2560212f8309fad233ef87c6fa37480217a7b3933147daa29d2642cd582a3ac96ce5026135d5376a586f4604a8d511bcf5d09dd3e895fc3cb7d90a2535a1c31da1b1df5562e1b2a86a116212ab10a6328d2b80921c3c04ca9a4a9424bcc3a75e649ab34481561eb0a0920b71c245c1789770df5a7fc9136d4b573b227614dee4b23276af4b6c3537bcca67b59afa0119e668c910060e04e7c94a1a7fe0e191fe22cc727d12dc6d0000000000000000000000000000000000000000000000000000002d1ca62c220d1a0581d585ab445c7e001ad9056b3d6a44c8f563f136088de171d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = d4952da07911c8ceb643e6b3254f7fcc22242a88df735c9aa9a91fc692f32544b7f30fefed3311dc8a927930c50b17577573f858b778294929b123b180498c22c1ddc92a11cda9c0da3cf300664feda28bff6f1873a682451d24e2c2a5991fa8aa29718a43c2b379ebc7387fad5dc9e3681d233641d1b805b167ae52631b3b6ebb0aaaa6507d4a87a808a1c3b62c97da49c02dfa2c729693de194a1bb1643fff14e0fd8d3749ad33936e8b4f8f6f3106c08a8098c6b903d1cb70c2636571253564fb7dbe54b96b1f999749d0c81c698934756b455bc6ec918ec267b5e54a0a812c62de971d8ccd93e4c1d6752afe3d5308c5257abed2b1c01d0489bc1d5fb5b2f4b199cfec784b2bf92dc85904cf78a9a6c0fc3a9c5c1640f905fb8fee2e08b3c0d5fa029062a5d41c82c512ab0645e7a1d728e7fdbcd95ec59d121fe876b1e6d624dba73cf68f35b23bfff7a435a5afc81947587b60d588c54ba0c999242830e568c3269bc96e001a99edb6ccef086abec634d0febbbaf72d872eae8c5606e86d9bbe279395c5370647f245351ae41358cc26f5447c37f959396dbb03e484c80dfcfdf93701e849e081232e85eb15e034b5421dc63c62190ea54a83ae06c89f395f7cef8eaa41517345a3a0aae4705529d3c2c13f71418817287c860f062c6d0c5ee918c50e613164dfd241533dd08928fc695f3b3c45cd75c740f76f6a896cceaafc9afd64deb69db89cdbd589fd6987b1f5da8b5b9115d675d3ab6cabcd0f793f00418c97b673fa31b851c1209140f76492359f3580c0e4de09d2a3efb2b3dd4afd4abde0e97180b7b24a45063f07f82771991fd2da92e12de7a868e6e84dca6a318dd8ef3a1ae6420d63051306d0582b058b7a96f25766aa0d863059483e9c7a17748a268e896f0d02173606e4381b639b480fbf0b3541a7c1790e66810e064cdc9d4e176cadf3d64ac27648467cd0b8643ad1255347cb6b086788f6c4dcfb3363cfef54c3ba5c13562ce884b53b09e6f149a60e1fbb35b65261406ec04f4146b2de7c61c2fdcf0f714981308774af933b710d1d4f315feefa97a581a98dd083a4d31749e5d0af2ccc2109cb739f8bfe85e4e7844dc3907959ff3c04ab9edebf3317f354c5e0aabe4de2e0711ee771b8dd70a3008eb9936f8b6924ec0dc9897a801e00f6738ec7f31cef0db9608d2c3d3683e97befb02f0ecff93068a46e57c97201608756dc45ca8bad93e0f562f5d74790c87d4ffaa67613b89c22339115d7499a2fd038bc4533e46bfb5eef28b06b8fe9a3182c6a8b18286edd1b57adeb55bacebf7c842d527ff5024c0ffabbf78eeb956a5127555894ca8459d99df31fc0fd1e1c5f7050d2cfb427dbb2f67530e049e23f8310b88c39d25dacbd6c7dccb9e382b0b471980d54974adcdb082825a9d6325cbaf90030a58193d5ef0a4e1e8fc885f04329253408b4de1d25acd097ff10e0afb4ff344063edde277e49b18996cfa57a7617b395a54731052a95a3cced450d38a31f19811ba278c60097aa1e3c91e87c57486b23ccb07d687c48fbaef4e814f9500b1e6f679a749614c86197239936be1f7ad2290b9a421c4f2fdbd4178a75cbb9cb1f7eddaad9d369f79c0e383fc9ccbbfd5e4cb93b211c477cac2786395e92385a4c0815d0ff6849e961395eba07c86e698d5f62466492efdbc326ff7c955840ed2877919d1cf95cdf5f557ad069363caa905c97471c85c5d0e65cea1ca90df82a0f8ef5660f68191c1aa19a180d18ef4a7b0dde8250ff3ff0a97dd4d65c3faf1e3a426f6c4b64f1f2d65ce9c5e5921ac20197a00f2331e810acf4f6b71878f1b785a28970d844ab4b6d1a604824db09f15e96bb711389114a4680b1c8b19be73aa5b039116c7a7cb7d2c2b026f5847afd6d2ac804f4ca24554f5ab27db900a159579efd23d78cf5542a038744cd6bdd64a3b59d233b878b383bc0ef38a0a2a8ab60869b64634df1cfdf3b53a367d3bfbbfb741badc819cb01823a8e8e16f6b4a35c380f99cd45af0edabf9de4fe2e5b0e6c34f7dce2c8d9a4be2b2b8951c27080aa965ae3afc422ddbefe0da8f766c8c63823050d1ba055e42352d305385ab932f99c0309dfa8d6362ec1c07e33909ac63200787f5963653db6ba2994cf308c9763a153b6ba824fb8ee94bd6a38f2a12047f7e0b01d090aaa41b4acce8396c18aece73cce364a7e6d9d +expected_result = pass +expected_shared_secret = bd452a700448a4542a31dcddcd0bf285610aca6570d8bc85e20e163a13db5663 + +comment = Rho leads to a matrix with unusally large entries +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960116a338d74bbaeac359ab3728e268abf75a8d30b118141bbc56670dc0c5b2d05c9c2f03952338170754e20287c99177c66b810f009002c244f213891c5b980aaa23d15f413d4a80160d24e692c450b68c8c43ac60256ad748ab6aa85aeac5c623d199928f88b04ac7bad2c1249c18fe1b867a02a353a112ef71368eee3210f7082f8b216c975070e9a1a27dc265698bfe4849611716d0fa1b1f9047e8b0905d184b1fdd863377353fae732a5d0388c3c6606a773360734c9ba915d49aa7d358263d7abce563afaf382976b2ca2e1328d4aacdfd78851eb143a1b81c21713442421bb1abf77ba25d4355dd10602ce06754dd9a77aca0e25b1260e994d0fe1b83088a5d385251ad5c6a54c45d93a7d1b25cfddc1612b8b30e753814b505524a5b0b26747645c9b636543ac7a871b6a7cd3865f1d8636cb5210ae9157b567b2ebd17fe3f59b73379d086348c9806848ac3ccc1547e8964f6a1c4b532787dc8620050b7e628274683b79e133969ae154da157bbbab159941484cda4108c84aeef56af6036a8efa3d74327dac2417e6fb05e2f1c178023b70214296c3ce65151248533f43a4b50826b181bcb51fbc54279397a6e50113635faca0cf7439be90867a4c548a9af0704da13d12c7549ebcbe5b279afc266fd83b9c4222b717b86fd4724cd0a35238abc2c3390695ab975bd38e0681b67bf86f36cc91af700277998ad3d700e6419105dbc952144561137711a0acaad546e76c66ab5722bae1cc110abdff7044b662beb6acac276317a7799f7ec6bc1282c87cb284006b3e74c361e5c6c8b899ad122880a1219102404fad458170f8aa3576750a9682c830c7c8796daef63042f3607c5c059ff98b7a093ebda2947b861f497202510a6a2cdbad3d7ba3b8da61f02671be3410549aaa9c3140635334f6b4385cf4105ce791db08b73f3ccebac9ad93f1c7abf6289721568d601c2cf5ae2e4690ae0c77b66134f3e1c33bf82771491da4d228ebbb7077312babb47e1262009457a3caf60f0e47145e29a3ec3b37a67b9b418625142937278c50344c05a0a606fe43c229749415064556a55dac28321be77a256637fe2b8dedbcbb02a29ae505c641b004f970b051e028d047cd152477db673875148b71434a80221166698c3cc589374634c06110320b0f249a3ec4856ffeb478979533be7a333eb144550939b00164b6b1b545905612dc24775ac2e4bbb531c6763f934121a8a8d804951b05c8f9c9237046245b422272288e333970f7469a78d543132055c8781ee308382398a7bff70f62b7357bb8093624a3ebe3169e957f3a33019fb0296ea1cebbb484e87b04eec76a3e29cb38b451816a8feba195dfe79e820591d7e73c50139e2beb847ef43e42ecad64b533ee3857dcb35413066c7eb19e8c1bcc42c9959c13ccc4bab6ac81b44346261ebc74af482e34f855e08916e0c1bf33861fb6d706c3a5c03bc62c6d97cba4174b2441a32ce47db7b8703452bc4693be69a4c539c6a6b744211598cb644209e84a711a05b9116574c7a222bf459305f10a68d4c48eb72ea16526ff7619e8391032685e244693ec24b30a257511e00ada5a69b6cb75c2983d53157fbd708fa1e54057757bfe6067d242cee6492a51098913a6b2bf888ccb280dd3cc48c6a95ceaa5a844338cf4985978929e9ed153819b97dbb944e18c0d7530a09cd420aa7ac5f5910325d02368c602d531289db188d30c6fba407f32c41e80133cea869b52e8091f701c3d7a7d4b317e9b0291f05a652165695130c6cb783b18ab1ffeba0f72d2c21cd9844f8ac2826267081a4315927d9ab6123fdb0193f723a3cc3738794f735b1a145b83189b71c597bd8248ba511b9463b9262c80790a09167720473fb77b1da2af8632ad793c10d1916868b99d2d23a06875769d7151c9a524aad51eb4f20bc58b4c572cab2642769fe444362533a04c7350b3c5eb418785e13e05b5459ca2c856b1b4e1b266e9677a27d29f6dca61a2776c92dc9290c04d77d7bc7cfaa8a31a581a623cd1c046a488080ffa8c13f66f4d262aba53cfcad64313c5c2fd838f88e903fd3c7da0942fbb3c84f4581457252e8248a75e185d4b5b64e0634b2ec5c5a088a6251c9c8c76837c95c066a565f9fcaf0cc76a79e1a20fb05a5bc1bcdef32deae76105c581319bad317b7991d062ba1761cf1accc2b969ece35274d7b6a3c8c79142c43b14772ad96fe2f296eca5c9aa4b68cf14c584792b1e4ba1132aab4de7788dd642e307a6b2476caaca69a1f7a3946404a440764e4446c20c216da5965c88bb9e09c165b93845c68a5674105884c46c601d35737649815de052cabbb31b39f95531286e08e64772213280ba64b6467d03ec43c5911854498656a831a366cbc256813d451153a3610e6979671ba7bb7ba41dc832a81885589974f8ebc2e57a1709eab2ae9931a09bc97d486839d6a16b29b7de642aaf1861c31b6ebe82891896b4e75b2360a776678aab892b81c5e2175eb588885b980ca02e9ae7bde1dc6346a13a5964c4391b4a3cc776d9311f0a9706c2c04584d05b58624906417eabc95738407ba197b2a14c6e4655396575b585f7c2a8b262cfc7c7d6f3a1fcbbb4356195b502ca7b278133614379176f3f4aaa49a040c7672cfada79ed5a2400dab4d050560d8a30c3e57ec6411988e941622c64b934833f9225daf42885a5b1f7909d65b5000000000000000000000000000000000000000000000000000000ab6452d0cdf5872a6a7d3c97f59f7d2be589eb4ccf832936a00151b5443fc707a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 021a27d9ee3c76b205152ced9c68003eedb09245954d50316a14a3e1d877bd9d6480d479265cf7a693e77b8761f11a09c1c30d2fa5f50497ae6a4d2afa3e61b0b7fb4b3504024763ac6c10fc2e6bc77dda7fd837ce115b84b1d0c749e8e4a961d3e7de1bf6b36741be282f9df710b46410df07191c3207dd9e74e8c4d43e3c75607966a1894e86caa95cba51a9c3289b00ad0fe59c034099b822654caec138a1b06635d1de59fd469ca3e928deb7873cc3dc2fe03aa4b5729f91b940f01ce83ae5aedac13d0a961cd9420584346346955780974ef21ccbe3208cb019f050fac0b80076b48ac6c0f3c2aa2dc3a13b914ce5343c7a140186728bb335a47515d361466c2d78f3fc6250f13a4d4fe6c8a587512700fd5272c9de73eb698045708e18b86d6b6692e3afa1b73e5ed55614dce4b8e71ba9dab03a246b1469c617f5bbf3e502632b060c7c17145ba7df290ec310661480de58a56cdab7a2e5a8e298746eb1b7b8703c5c650456c567056451e209148059a59af315540e448c0c6a7f48df9e22f373aca8be4df3bc9bda80e94a92634a612afdbfced39194e124c07748328698cc21f39de459b4cb08c6c73e80fcb6d0d86adbea470a207b0575f180ddc0d658d7ae66b2166cdecdee265a02e56bc4880797f0fe09c081788f5bb507db2406f37a2743a3c22ee0caa51ab62ceccaeaa9e189ae412f8dece857b0faaf61f81f2bd968d0f6c9048fca287f74d954e48ecf05806a695d06bfc66ed8b5297899dd4b3942424cec559c33ef0da1ca083e7eea98585f89003ae0ba98fb3f51becb80094ba0091f97b3a32c635a12308851e070f4a94502be51fc6f4e11bb7803cfbee43135c82bdd3bc82d58383636eee387d2c13c1866982d7c4f15f0be3bf5f87c8fa5d43daba703c73135ff3aafe4cec43abf9c1bcd16e56d6df85fc38dca4d09245677ed75b585722a9b20fd5ffe9d0436b3fb592ca6982ec2b96a8af589296b0b0ffcae14ec9027d4815bb9b933470a357d0afe5aba5010eb0d93a0fab2c28f84d7091e607505ecada258a551238a2ff68621bdf5ee1246c27d6e8673f1b785f7abc9b88310e3c1ca5e266f2c974d1c88a31e27a102330f924fb3713adccfd09c4415c1773c8da37e4e18ef274b00d462970873b54ad108f588c8bee6a7b4cce157109aa04ba0daefc9b5119b3ff9f70d4728574cb9f57573f41760248a8a8cdbbf7492083cfbf585c844f03ee2e08da4a08d04717b6244b63bbf80d0f4f0477f94de7ae6b2883388ba05b27ffe8a497541f012f16bd9ec50f64cd0d14e1a6c2be8c77ffd39d1d19ef402b46c0c41718ac406acb1b71fc044b1f93a4fe98fa8a0bbf09caf9dcfcbd8e8ecba42e4bbac9bb5de40f089b86ef71003b92a3fe385bfe603b098185d05f43819f8686b4f4e14a75463f2026baa66789edc52610ca8d3d5b11f10672c70c80effd7ba0352b2079de6910221ed21c487a7367cff076e84e1cd3ec625065d7a9b8ce4eed9d91c8a72b16a4a50d96b8a00921695a00167b53471e79aa445c656fc0d41da64d836ac21a34be767c514d1571e500fcea435d1a1d59a6d07140ee4d1a4014cfa8a6f0be9c334ebdea053c842a06124dfd165232c1a2ce63babadd8a56fd78ffbed64b63bac3b49e5af81c746253bcfdfd045deec785e0e272ef8c7151bcefdad6fa2bea962d621abd97f9b5cbf1eab792139d16b51e1f732326a5e02926817ed0bc4c6c4680e42e7d5847d6e0195c402e59290ce8a8f040a70980eac1a0bcd3867ddc0f2de9b204514011491c8dd63a371d331b2edb870e76e7ec5b27146a0097b969a6b157d00f66ce53b71598b71869063b9a29b23f3623837385571962ac29ac868301e2ec0643bf639b074c8a28f0a66acbd0ad77e5c86d01cabd8fddd77a4fce6185768566a6d98e679986aaf9978c49189a2ef1a218977f4d2c34c5027188d816cc918061ad13421be77fb910ee5aef5e159fb74169d7763b446e523470409c4fc4e76aa6d98f120013d4af284bb0a8e9eecff71b8544f9d3815062173ad6d4e9c4727cd6395bd3da54237501c73390cc5c48683d780efec478d2a15a40a5ffa3455f52c092993859fc8ff9c1ebb308ed03b5b88f6de341c3be3ddc96f695d68c1562b85806e162f1b07c5f10a1213f8d85f6b7d92e06d664cda2ddba47b93e2922d30c3bb110405fc7dd9213812 +expected_result = pass +expected_shared_secret = 8d99392e447dbb7f7eefd329325bd71d1d984cfb01fd609c3283a84fdd0f0138 + +comment = Rho leads to a matrix with unusally large entries +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3969fec41d1311ed2545f5281a09df223bc4918e55551ec060dbfeb41c777c79acb7375215002d9afa37b5a126625f7445c3fb51233650037e070648c924586bf7013c203e907332901ff722c35c1991acb2da41cacad4b709ee242a9e71eeb0ca1d05595fcea8d175553ce689ba595b8f98707a68a4d20f8a1fca8c34c3482e88c8b043a9d42e4a9e55a6cdd867e106b271031355bdc71c85c80713c0ef7c3ba3bbb9ad4e32615a2b104e52dc5e7481e258351385f9c8932a074529e327e6c0949756b57ef47094e184517819d459bbe35ac6154a70d004490b03803e58c9bbcdcbcd8451c2b0373656373be77a59beb2d47410d8a8631745653a02956dd0a0fe99ca87d78c273230667f25bddf3a65a216921a12844b8c98c197026e14638a97fa5144b44189621f00c75857fca20342a09ac44a4aa6c336d9ae58a15972f22555139e2b3e00ac0bf67b15d64ca8ae77a79b44e5b47a72ea06930aa9695b96987aa0dfbe63d83a352c9370247f6b21f225e096480b17333009bb78582464130612970cafb137f0e7c060db72de03a46d8a860b0cb2a45b462e5530eb566bcddda2315a633ae5054957cb74df537c30777a547b0c6e486787c74c3d242ee34158b212f4fe4107885b2d3da2224803e73bb282cdc8ca0365eb70751c3263531b31dae5a29561316003b2d781790cdc2ca09b65ed19995765263f06c8a1f3378d46c19b1b46a43932952a37e4c828e99f95404075b013b7471070422fc65f9c9965a1c0cd0141472fc7004f6319b548c19929f792ca0d588208ba4628cf2bbf7377ddac05a058308b7fb92cf55584a381204523a460310bba06a88d4b69cf62fe2a71097461a8c3b5eb212337887a34fcb278c59931f28a0000227d9cb9b1b3753dafa63e893c9783764bd01b7f668b83cea1e7fd94913a405babb301ffb6b57b2845cb7cd929c0acc7540e1bcb196679380822c7bb67f732a3c9ca778b60451fb03755ba151e6b0bacd1129df5174ebca123805beb8e91b840b70643713272ccbcc2b80008a46b3a818ccfa6ece2c3364f373fc8c10ef4b4c95955052f99202362bc3020cc2528486784784095fbe10b4a44732a2c6c0b2b50d199a93c544a00980baa2f5cbcc6a3456eab71c2798d04c9a85827b8b654c962b7e4125cfc0f82a59632462d656b9b96188cc89373a6165c287bc890d5ed9500ed08ec1f2822d718bb94525ce81cb48b4999e288b5c90bb7e3647ab26a7f5479199f9198fc950948605b9aa0c8d0b133851abe4d77aed7455b70410b54a00bdaa166f0b4712e3916a70846840c8f3f9c80c8a95c912bfef188782974eb372795d96cccfb6c9209cc2cbec64bcd064e238608ea46f841ac02d6aba8ba9bb251a381777b50570a5c79257a964190e56aba3b27c708803a2e6909a6920f546c509a7524d138a9c2c839f34a6a814b10ba4642b7214e447844d553532804154b36f688715b203cd576274445c98abc60192f603d970c988b42d6cc250b4349f2d91b50c123875c608c932a7f85bae2cd54b6de80be13914f2606cdd9b03ed83219ae5623748972a657e0ccc41579b745b3abf6b04b50b945f2f2963504bae804a261254ceedb767e252c64908abeb94669a94cf511b992c475d99939095ab9b19f74f75d30efd58beec598352108e1ca648b5f31bc7071c86aa97c5fcb60bba8884a3c72414916bf68a277a82b78857de531611ab7c7a111a632a64704458dac97dee2442b4b05a378baa74f34154bc8c191591eb2196a4d3174c3848b5f02f2351211f605b2608c9fd8a101b658599b87c65a3c2c7a266c02b3b8beab84feb0071c25a50b23ec8acb1daa290cca2ad6fbc8280c5cadac42993c083a25338150231cd134548661d645c678bcbc0e7815da41a14e8eb123c482e2831a1ab0399ce02cfa1a39a41c714bd8c9206d6c8c922043a235cae2bb6dd1ac430e22947444ded7447e00a51c13308365aaaf4da9dec03495c73295aa9259d4529eafb67dce58b374066796983f06c91d034226aa75afed116c886927e135564e4000cd86016346b56d9864c7abc6211a72cdbcd32fa869cab01f1da8f6bcb84cf1441781c6baa263ea684cf96a1277e2459ea07c6071b06093985b047b791ab6e6593be230099308a79376bbbcd71492a4a4de83a4d70c290aa05b74a8c80fdfb9293317d10e07615acc85d762ae35b187c55060c912d9a2a09e995afeadb874a5526cef75fa4701e9e0a5c082b92ed3b8887f0bcca362b492369881373ab878d00054027c4cef0c07cae57b30fc51e744653316591b5845c0a47492378764769cf3846b263ca6e086835cf0197b5025b2a960097e57597327f28d4b2fbc6bb241863a2c96d3242a031171042fb40afe8a75cc2976903a603b96019f4c7420b77625470b62287e03239e5008c1297888f5322937457b9467e52937996157e50764537ca495ac75fbff53dc1e8cb77002aa7988604b0829976c8e49649f7446495a7548227ce61d963da3bbd2705a8dfc73f091c20e72b77f6640a14aaa30134a1b3fa7083a50cbc720bc9a802a4208568e2a2ab065db245628ef2a138ca1d71fb3f66d6a8aee513f1c80b64a0bf38f01f4979a975054dfca823c4165aeb1876a7a81fd6920974b516d6b3a1aa71776a264a32447240855b84ba0fa1d35f07a8c11361040da933c4c44e88417b585c1a1605c68ce4000000000000000000000000000000000000000000000000000000c07898c8f447decd9bbfef0871a28f3bcaa4eb22ae145d00ea63a463ed3333c253f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 6899d650581d8ddd73d6e7095d24e2962ac573877204768c66a78047649ffd373d4e0cac20e0b98675e6f50962871c33957b5a7ba2af2ab800ad728c2d0e70877cc3f459ba53d432d45f4c9ff4c951c35f14185e01a1fbd735fc3ed84063b579e69c230f41af67c9cd7481fea81ed64bf248c63f56f81115ad8255a172fc99d87d8fdd6db00ee407618c7877a2486b6fac3b8eb7bea62c24bb5c5655e47388f2108ac36d5e55c5511d72bbba65706ffdf297cd0788b4c34ead564e86e78c605359b6b344380a4ec73a4f64b7866a2eaf36a494c76adba39158a3d1d3b41973cad055780ce211982fee596ba61e5e5f7e44cdd8b1d6f866c708d20403760b9fd4abf31a0573afa130aab5bf7493b2365ef5437b7824366fb3ec967016e2da547eb61276be7c5509c2bd5e16d8812c034f6b4c5a7f5f489137385ad5697c4312042303a5d7f62e398bf5fcc758ec1475e7ba671c656911bcc32ddedfdb07252ecd0eeea696046e3fc9e564b2ffca11562191c4a1e4b31d9494961fb66ad44f24c4b0d8d7422df106663600ba380baf53007b6146c923412228936d7324a87050e62b185bf3700959e262fc64bc4f2b55402d57c63539c57272240f4725ea23d389b17d6af64e864ce3429c9c0514c9b384d79b830a9c6fe12f8781755d53b8af9bf81e4784d9780ba6ba0ae36f89a99289307481bb3955075057648129349f1e0ce4e750be53372f82c92230127280f0f393150c89715a43eaac8abf538a031155661b489b066e915505d59ba40cc0b5a4b8de7e731533fd06dda44e65f22b7931c4b8e34a72331d32798aee1c16d81e06eeef892e7858ed2e9c27d21a3030567e40a369e21c925a26712e1ad6344474bf8e9539027040eb4b0cf65b627623ddf81253c6cf002f837673d2389cd296f9abfcd38a36c6976b03432c9100c7ce9bc862d2c98a6dc2f931f62e471369bbfab644f8ae37deb65784e6f5414bf88cba9e6836d3fa3c0ab7ceddd81d31e94c612224270fe79048688b6d8d46acc7d656a647888a469fdfb6ef8c8daf78a2270c5058e9b87d2fc0e4f8a098c1cebf96e06ff1edb382e545387b2314b2f7d4a669dff20122a0165c285258a39e2a1d27c5eac3d79ce0cdc64dff98a8633882db588a34b93a1403f6a739bd056cd2d6531af36a2701acf47617024cd1cd4b9b60a02cdfcc6f34e4693eba3bfb32780c573b4482a5f6bf109c7ee51792252dc119a5e41a4ea8f25557b64e500a83a6d8a839c456775a9ccb906a733391605bc487bbd6ea7272325df31cce2093649fa8a379f4977801240ea2be8b1e6a5ac95ba613bb2798bfd1cedfc34c39e1c43cc094f8bff34607f8419bc3ef2fc0c37075dc49280656304d2f642c5ffe86d5cdea4fe96cc8b4451954e5d898f6cdf7e7ec5af447dbda66a254b964df9e8dd565d46cdf04dd2d19ea1c7400925be2105e45343baa9855c5236dd70e042d0153c904d30fe45d087b0f0863ec603ad74baf1836b18c91d98455f3e6477936dba7379a6072744be6d4c64bca89ac3334ba727e0763f0ea52faff3daa52de9fad1f27e566e7a6e85914a02bdec5f7a8509f80a616f6ed66848d4ce8920757fb7611ee7c70366ce847fcb62a94452dd2523daa21c759f36cd31337afe1a5c8e8ce8799c6f03873f58bac3649e0d0fe6adea0199ef6eed64dd1e2fe0bc606b97ec8ed1e0b567baec2816273b7280ac91b05fb25e7467e934bf79025f5b4060a813c221291cb307f7783d5877987124ecab1d9d8c8e36c10608871a92e8878220f593cbd4ba61c35d2805500cdc0b145cd6ad2cd614481edbc913733e3a5104b0006dd26e871df58f32047701b2420d93bdc2d0a2474f7d9927e7f196993d9792e30cdff67ae89bc6a27236a6f0ce0439d4b04788765943c2be5c9fbc0f139135ded84ce79d876eeb37f30371194c8eba42659c185a10c8941f9fe9fcc722183ba7e22a7885a66d8cd10f214f4534171e0836d86368cd04d87737923da8801166afb398bb345b5bee89eb512cbae07f192aa50a932a5d92e909e65443f4004fca49de5eb19abedbf57d066d134e096e7c63defe4430f8e1886bdd3cfb8077f7196584398589ced5670c7be91d715a20f51603db8ef35724805eb1c270cf16b282ce7c79111e4577a0a1a27a435c070d6b3e89dce1bdb53826fe9a05d86e586ecd950d27247ceec6d +expected_result = pass +expected_shared_secret = 71e358b21b3b98d915b70e9b877e94159aabe9df32737c71c50c2f99d7a074e3 + +comment = Rho leads to a matrix with unusally large entries +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d74933a0cba383545cf629d357aa8927a7bd4f6575059485fd455be7198fc01a509920f6c0b8c5a565b4b86c084a60bd9b9b6037727df67b83ae06c5e47aba5d263ce83808f40a378aa43b4ec5458b33a0eac8c816abf5bf76a1220a99205258cc4a9236b4dc252cbbe8884e8ebc1fe921ed408582182b273a199d121153ec38b7f183174754f66332ca98b87a31672720815ff7bcd0cdac810db905ea76e6496742d26b2989b201fbc2936f5a6cd60c35e757f8c33b75277560ab948bab2962df9c38c91b44f08090e5585d852c4b729c52de88fd8c54722162f2d7696946c7b710079500136a28b9abf9a5c0294a5b265865cb04f9796b648f85858f8982f15c2bf31626b236b2c3a6493910be2cc8610829d96693cce3686b8a63b91439118fa661729462ce58e5e28b764aa39911569d1ca5c1b33885400a16f169858930c7f135ab6a95d08ccc70d057f9e73a4c8ca2da7185df37c8a6f727893bb6db74329cccc4692589128867cbaf28694fa747e86cf98619e99b221db88a81afa73b3485846e77cf311b99822a8fde459d7d01210db0ce68054199939e8156f8f7c33adf5bd5f2c54c6bc70054a5b8e305d526c1322e49f57c47264091e39eb0c72a596ad5575434c4de07c0bbac32f7ed30a0930221bba0aa75140b0c97a6e1775e1211740c23390f0094d144632169e4a0c2534479b85546a7fa65694610b2fc19488a5833aa7bd0ecbc6dee36997a900fad18b1c13b7cd381b1ca598038c2a4e40ac374615ffab46b3cc992df777eb0781aec573783b75cb426283ea01bdcbbdf8f8b30ce92f46cc7d4ce407bacbab2bfa27fd7792f43ac0ba74b58b332bb915be649a573eb22c12b6037b4a8cc109cb4495a337e42ac82c48dac2099684bd01700b7da007dd8039bd6b09900776cc783ca114358ada02cf5443c9bc6c181a6c86daa79371bf6e6c5cb68b7255d592796bb7b38c5f8c655b2e480cec127a2dd4aae4b23c44d4367de78e74797b64b0ce07a36e73613ddee8a61c5c32f865119f1a60b44ab5a28374af3324e68604bfb33962fc1f06d661119c0a081c45dea91190c4cad6b6253ce560d4e7855a64c58bc950bac88ce61b76691a93be4b81c202768c984ba2d9122cab4880942c40d87022b91c5ad817dcb5037b835dffd916a2b35c09f782ecb72cf63239b6c33bd73c0efd115357b283bd6512c1eb3ede4730284328a86021fa805ddc55c96c1caa3832857cacbeb5353453638ee70669c4dcb6a10c723b18c71dfc44fb5600c0f8cbb35c6d0b075335f6bec7ba1306766591575b5d2b4eba76a84e326b1475b5ece6c3ccea5e555616d38c03fe630c3ce56d3ad73858539d1718b915fa703996ce39745831b3c93e4829cc5677e5a79d3b1794f81816dcc2c5babc859b0966c76c23a4e66f1031634c93b8a51550d7850d5407b4e2d00ddfb5862c1c570b778042986f66ec940c5039dddba773c9a6a3c10e370714d0a4a43300a7b06b01aea6b6a4b5c17e7482d59bb9e1fb16897cc0340c5b65b9239d973c06d41f6e7b9f351a22b8eba6ac1148d91bb4f8959395e6a6ab996fc79bc8f0f7309be14fdb65bfb0287771908244033a3975ce2ec096abb9c15fb40d33a074fa2c84bdf7b1ee94746c42044be55484a179ec5c7edfecce56f9845f29c7c535282759c2d0a2546a13bf56dccc6d4463376a46ed05ba7f54577f26c78e2aaefb0928c36820db23a999e4b399b9b4fc864444d665e58ab24577533aca26acc5c512970c3a84bdd6fa7c7fca6c60eb73a1ab79db779c208c61a2f5311a694dcb7ba37ef7c7db92587d4a77fe3665036531d12c1adcd29cd2ab733e1b2d3ca56a2c7c9f7e3b96d6355b73c4bc4061ce276308b449cc0660b0f9c30fa4a62005f836e182a77e0b74d2b86e3bb6a63fb58d362b9496025bc5485a086808d3779ee28038d1939c5e39b645db160059a04e1b8e0e532686f29d34467fedb02236f3bb0b699c68726961f49824d277c8495c9d804a61f5320e61bc57a85bef199700d18a69e25331c41646abc434e6033d4abb30f114c35377365c51f5173769c315edf076e58710449763af61cc316b5a3e75346bba705db322cc683d5258a249a22524db0e88059a423c9b55d173eca88ed47cc4711a2ae295b846fb113834ab688bc2a42435258b9b1be648c5889230dc153273903e06aa2590ba5d77a63a16853d304933157288e03af785bbce36067c296a18cca79a18aefa33855683becd7b19b3890de40a24d6d389460a4a66378da2b82980e61ff0b144bfd64d0ce294e9816b9105c20c2076ddaa1026c68e50982cf79ba879f630d4eb8df663390307902207950b8b9db571c306a033272ac8976133a641c585d43e730a4969d752072bc6f180180e0ca0fd9c27d7845be15cbdbdd44c7c525fd70b5479c18a24800833c9338a5635034704db0443307c616209ab2172a0bc42c239d87ced11779625315ec168c3716ae62a209ed7096ecb83d7939593e519fff06e99a6a09122c5bf20c5bdc09af2402a3a605318d68c2b31a284b33b1719a4b6c7a5fbe4500ce23f7d858456f47d135a8256c9b40f52c37d07c728da600f127738c027d131b19b0070cbf9322d1865fa515471d461d17c424626b305d68e34838d5d7a35fb91816b65a1f9403771fc3a8f22403ca8616f89995b52425d618a63a789a0dcbb9ac196bd6612fb69000000000000000000000000000000000000000000000000000000e07f23404b053d03c5dcbfc340f9406bd010d254685ac2e204a32e68c7ac5afee366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = 09ada15058fa9bf500eddb096fcd572a056beffdfce251252d0e9a8ae0300272e289f4f8868c1f4909b0502fba470989aefee80303e817862fb74080dbd7e872c05bd63162ada055a9f5dc88e9504ac344a517e613113f670c16415e2ebf5ecec2056620d4fd9b905a14a92d4a6af2d34a4aeb21ed9a98d498c25155559fc1b3046a5ea8c519bf320a8e2c0ebfe02cf28bfacb9a6a04c54130d93f1aa33af643d2620060bf578f525b1ece5464114e56c5d21692cb5243f763129a44deb9835f4851cbef64e0f97cc4ffb322c2f3863b26526153db89dca3f55d6727252de17c2021d3da9c1f9e3521f03844a066b047b318baa867c3201a1943c3a8245182f1d3a36b5e4beead76120470b2ef02b85ba13a1dcede19b5e4a7adf09d13e4f873fc5756a37f1ff240f6554683098437a9c374721088c0e0a390c435d8196d94ce94d988510fca6ead810a5da834f86f7bec0e41d83d35d1acae4205dc00a7a9b05779d41c893371bd000e308f70badf03e2f9066540fe2ad85f312db74fb48d054061c869f80bbf9f2c6c28fa691eaf8df27c7e13e076d8a793d7ef70d6cbb3afb059ba176888f569e73426765e4b866148729151dcd89753a68a2e1b76be36559dea6c7e4f8aac70a417698ac9d546f228ea36b01622cfb4405563a43e75c6baf2c626ff14b098ee33b1e9200d7b7fcd2cde35198b3332a3292f32bd1959132fa1510d8f1a43956b1d93820fb9dd88aa04597f65f86166033abd9ffdf9ce1ad4d8ad60d05f298c11f2816a0d375a9f8095aff0725905f508d20b11dd59b7145a101810ee140f86644827f31c64b2a7401048a8a5654934d6e5eb41d43a4957db61f341f5a214d2d09d4fa6fd2cf709264c4a755aeb0aa171a8286e94a354425d795780049f097b3c20ddb6cac39a78f8205f11c4744972263c1a495ab1fd563524f9822deb74a70df9ef5486ccf54e737fba48e3ee8d1c69ecd1c843fc38f4986f8fecfa42be99b056f24a2156a14d10998b4edb501f7edcb9df12bf1f235068b2961455f3513facfaac92d7d5093f00af6834d3e33c5f0271feb31edfa94bb3dcbd1221fe29095d6832f5a5155951dee6ba7a379f73854cf10ef5ad39b1730bb01e315a3c642321a52f4ea7efbd4519ba2192d974d445d6894feb9356a4c4b7512a0b1973568a04d7a45d7a4b0c73cc9df8147a2d0e31d2729c6091bd7a1c1985649795f2cb3b40f4df43e3bd7069683a737347bbca94239bd1e20badcbb702aefb93391c852108708db4949579eb495ada6840755a40fde96a009ed6acb54e98e0f4a084924ef15b25a917d497d25d9032a895a6ecae037af1d6e9f36ba56efc69fb893506a311f1f80b746c8ba0b8e08cb6c980c476a5982ce622e8d7394ddb0f6ba2c6dba68b7c5cd8aff2454dfc92362e82594123d9c200609d2372a7ce4df6e1b7ffa68df7b681c1d5174b3de4eec7d6f1321b13fbf4986b0c73ec6b9583229798801aae096bc5f972e1b3b07b0a40e1280070b2977d6e31aa8f4894d6dbc967a4d0b29c736ab33db11c172d9b771ffe84a8a803306a1b59d7fddf4975e6aef83375299d97d364a7629cf69ed856c689b09dde89fce7ff9e273bb72e768fd7d671d6591c6497f3da0eaee46feb58783f9d0495a62eaeca8e054038efbff4cc599529a9443b9496d1b0734eaa278121ce64d2a59c352b0ade0ffa907846a0ae8bdf02426f270293f1fc40f2b645089d621c18d11fac3d073afa27f20925039258e9d5530137f848d8e3e56f970d523544485cecd847dbc7fd8033f89c04a542f23a12e8e4bac7b9ecd76be797d8195b8f6f4e57b1b779ef41f03739175f1ac5e336fac71cab07f7dc760e4de2a3296c5acdb01dc5096f3f2de463980ab26e6d84b8a0754578de9b0a022281d6d1ae1a4ee40b781f49ed605a387b5176d685d1a29d3581eee4b1bcb050c2567e4f997330105e67f128c28577eee5ba1d170365cb81dafd7b218c8ad0207bcf00a38ea63ea404e3482a110fe16d0ddc8700e185670fc1df89ccc8a712df0c4f69c4db77390f72bb12dd627ba0159afa309e17e3538c313716f7d03a07998f941a7d4b8280975b2c353495747d1e115b770951ce5c924a8adc73eba6bf4146aec3dd27f828266fc3e1fc23f3b5c501404ec19c8030ad8b07d26aff71aef4bd7228728442325c5b880120e1c4492c1166cb27 +expected_result = pass +expected_shared_secret = a2334b0bf4b86c60c4bd971e673427352bf08c60e7730fcd94edb8c34339028c + diff --git a/libcrux-kem/tests/kats/wycheproof_early/decaps512draft b/libcrux-kem/tests/kats/wycheproof_early/decaps512draft new file mode 100644 index 000000000..58a212c33 --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/decaps512draft @@ -0,0 +1,1830 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +private_key = 6c892b0297a9c7641493f87daf3533eed61f07f4652066337ed74046dcc71ba03f30960103161f7deb53a71b11617263fe2a809769ce6d70a85fe600ece29d7f36a16d331b8b2a9e1db8c090742df0739ff060ceb4ecc5ab1c5e55ac97bb66a7f895105d57782b229538e3421544a3421408dbf44910934cc423774f1676ff1c306f97555f57b4aed7a6bab950a8163c8d318dea62751bd6abc5069c06c88f330026a19806a03b97a7696b56da21827bb4e8dc031152b41b892a9e99adf6e1963e96578828154f467033846920fbb4b80544e7e8a81ae963cf368c9ba037a8c2ad62e32b6e61c91d75ce005ab30f8099a1f29d7b6305b4dc06e25680bb00992f717fe6c115a8084231cc79dd700ea6912ac7fa0d937bb6a756662230470c189b5aa1653deb937d5a9c25a21d93b19074fc239d8153539797c7d4ab62649d76aa553736a949022c22c52baeec605b32ce9e5b9384903558ca9d6a3aba90423eeda01c94198b192a8ba9063497a0c5013307ddd863526471a4d99523eb417f291aac0c3a581b6da00732e5e81b1f7c879b1693c13b6f9f7931622429e542af4069222f045544e0cc4fb24d4448cf2c6596f5cb08624b1185013b6b020892f96bdfd4ada9179de727b8d9426e0996b5d34948ce02d0c369b37cbb54d3479ed8b582e9e728929b4c71c9be11d45b20c4bdc3c74313223f58274e8ba5244447c495950b84cb0c3c273640108a3397944573279328996cdc0c913c958ad620ba8b5e5ecbbb7e13cb9c70bd5ab30eb7488c97001c20498f1d7cc06da76bf520c658ccadfa2956424557abea8ab89239c17833dc3a49b36a9ae9a486940540eb444f97152357e02035939d75a3c025f41a40082382a0733c39b0622b740e407592c62ecaeb1432c445b3703a86f6981a278157ea95a6e92d55e4b972f936c2f0a658280ea2b07a48992df8937e0a2ac1dcc974fe00aae1f561fa258e2d259c3e861dce236039127606fc1ce009003a7bac942101dcb822b1f3c12bf73238f546e01c36b5a6936192995cc69c63237409cb53c2e35d74890d18885376fa5503b107a2a392115ace0e64677cbb7dcfc93c16d3a305f67615a488d711aa56698c5663ab7ac9ce66d547c0595f98a43f4650bbe08c364d976789117d34f6ae51ac063cb55c6ca32558227dfef807d19c30de414424097f6aa236a1053b4a07a76be372a5c6b6002791ebe0afdaf54e1ca237ff545ba68343e745c04ad1639dbc590346b6b9569b56dbbfe53151913066e5c85527dc9468110a136a411497c227dcb8c9b25570b7a0e42aada6709f23208f5d496ebab7843f6483bf0c0c73a40296ec2c6440001394c99ca173d5c775b7f415d02a5a26a07407918587c41169f2b7178755acc27fc8b19c4c4b3fcd41053f2c74c8a10a8321241b2802432875ae808b9ef1365c7b8a52902f1317ba2fb0269f47930672107b4726fef64547394d3320c8f120b3c2f4725b0305fab88cc7981fcb09a76a1cbf7f179f43bb0a4c8b0590857f1e69708466c7f8607391e7bc5268bfd3d7a1dffcb4eca2a1c9b597593013d5fc4202ec2b74e57ab76bbcf3632bbaf97cdc418a6f16392838ca9bf45ddf023777b7561833c105190f94f302c59b531900bbc816361faa5b3380ca3a893104ca7388b185671b3e5fe3790e9a626ec46d9b0b33c7a419af7b32b6859894f575d82ac5456b5490a7af8fe61046360589ecba7244236f4123116b6174aa179249a49195b356c72fc6641f0251812eaa98570b046699070e0819dc2713f469137dfc6a3d7b92b298995ee780369153ac366b06d7249cd09e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf598159a7792cb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4932612ec915e4ca346a9bce5dd60417c6b2a89b1cc435643f875bdc5a7e5b3481cf919ea09172febc46d4fc3fb0cb9591704ee2dbb61844b2f3314a06bb6c6d34005e485ce667bdc7d098586928d2d91340f00419ea401351a240a0b041058befb0c2fd32645b7a2df8f5cbfd873327c978d7b351a28088438837024c52b9c295cd713646fb5d6c0ccfb470734ac2b2bc8123c2c13df6938e92455a862639feb8a64b85163e32707e037b38d8ac3922b45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539227ffad1bc8af73b7e874956b81c2a2ef0bfabe8dc93d77b2fbc9e0c64efa01e848626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = 7549998d469e2e479002305b09b44dbadbc2457ffd3125f6d31b0f27b803d581071c1dc6181196fe76df78de20dda609cf1b7cb7a352c4dd9c2cfc18801f036fe40f8f7e6f3dd73f387130be387b1713418f83d93dc7f8074a032455c46f857c6b6b35429c790065420d742252ee53f53f6e64a9b78a49bc29b8ce84831a01c3429e346960dc559526d97853c36631b4773285fafe8e3ca4255a8723ae4f02ddd85a4781b9f4186d67a83b5d9eddc3ae7cd4096c33f4d97fe02030ecb6a1a8ad9b19d3eb32f1b8f271b30353e9e19dd183f06b54c3cb02ef166282752aa11c8158e48bbc6830171ca7ddb75a35e46c35321abe6a742032c772a16b3d1cddfc6f2801e2b817302dbc94f333c0cb91e1cebd5ec61e49fa5a14aaa393755fc3e6f4b8c5c4fa4baa07a08c4f3394626358a15e690ee1e4829b111c17241aee37d5c832f4847688fe5b5d1b19e8e04d9d1937001987f3b4b83549c3e530e4119d164b20ef9d3a72f74c044a974591228b41e680ec5640a97234c2c6017c95e91be2bd498547d57a5222b8162a3546656d59980d51af595bf5f23a632f6d8544b81074aed34c0352ba560deafb07441a55a9376342e50a0ec2537228255a4b5d03c92957f4ea3507b4baadce53ccdfb7364ffc1817b58c50ef28e322e1b945e0eb9b1233975c30a5545368682714bf502b61e1d0457a9753e10de0f1bf35ec3a3f470a3c69ccb04d2d98fab3a0b6729a9875e1db533c96b41e3d98628a6f8cf668406c5f038e6b7b242fdf86a7f1e697aeb136114167b13f89f231bcec7a4166b39eab4a3709237822050c49c92595a237f2eb483b9e1dd6124bed5eb9b7b5121296376b7d2014a77560ca65833d8beb4d6ae68efd7a11acc7de87d82be1ad573ae9f6f0766fd786387d1a8c12d1c8a296b4f72634f70577688848e576851f13be48df335d4acd89793a6c6c0655fc39bc9e1e27b4a500f708cd4a9f2ec672ba5bf8ad23998d4c0c958f290f2a6c4e6cd8c0cdc85f5716ec98a4c8995d378cc6e2a1e8b82800ddf03b3226a2e7817771e509b4955ee2bed4217bdf0630b5840f2524ab +expected_result = pass +expected_shared_secret = c608777086ed9ffdf92cd4f1c999aedd0b42e5e8ef6732f4111246481e260463 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +private_key = e1785b13943f2661c372ca63a0c6aeded27f46c81b837293b9867b9f7cce0611c61b318adfd67c09969c27a095e53c124b048cd99027c9103e85c5c4d72730a34c8adc406eceb4afe02444671319df175465ea9a0d91291c18cfc9367a333475727b64e6f73e50233b81ac0978364d18f72db39a4041d4b25a095df99bcbed090496dab62aa250945a97bd297a539a1af51648c8378c1b21a2fc311b57860c368a819f2b8c15477243256970313b2ae082c2f8bdacb658a89c6bdc788325d48292dc2395f51df765a4a2e927769c84f5fc306568b4b5e7487b8b9f79dcce33c80b988c955544cca478aac902c2a6f2a4bc9a9478a9b318f78586c696942b6f4c2931e85042db27314cb546bebc2236c2136d581ee22978d2b79ea3b662a8bc7cc17ccbdb59aef8b0cd77a4a680672e9ab4adc2d011bf471865f92f4a4769a8157b87769ac3b86448851e80f8babf394907d4c8a51c7ba4ca62cd7ab7bbc4219778ce4dc22955772dbd1330c10055dbe106d11863d7b14b6301a622ec35f3ab9b3494c12e3929bc321950fa1036d98a3b257c20d378a9798bd3b57e50ec88617b49b75022e10130e35432f3abc7165952e2b7652c0bb1fa92a16d7b3273d2709077164bc60cbbe747205b6dbbe5912947ca3914c1a106b66708212d443898616273e006ed507e30d7a7b6e389739b637609834561ad4e227da0289ed9180bfaa48a58ea75cc1744f75007a99611eae775a1f5411f1376a7f25e758c8b69ba731d28bf016970a9a3579ed7150c526b098c4ad277c6d7294462ca65b6f3b7062956551428477b9c57301ecadb9c7adaca67c0423f42704b008a90861b45c19d24e521080c69fd20a5dca45aca18abb356375a983081567e22798f530aa1e0aabc2d7b3a208446e9081ba2420b8afcb8edd37db536689695749b632d99316653e97056260979974e44d135589a283dd1486856bd1af59e24394743c7a036a68161e31010cac462a6a7ac0058e1640aaa686311d939537171b8128965c70fe8eb0f10dc1a2bc50aba436e2af19ffbb3c6451a9fe7784678a519473010f9e69f9601502c421ad4a7848cdc4b73987cf2f85e660c65e468346672ab09ea8b106b2ed51246271bc9d21672f6aa0b3a9b24c8f64722842f2e24cb2a47aac689a5c57318663bc98756c199160f3a39c2148c574c23836dd060d1ac8a06794edd5aa068ac19e42ccaab951051756350c31d584a517fc9bb303276215580fda99551e82449d8675f29c45ab6354107cc94509ee55aa5db3a813adb8b04005200aba8f91b58a2d3b2b7d82c6461363353038099b7a0e981a85c75e0e422c572c506071df54bb7b715b9f4a42da1e89694a06475545d97a09ea36374f2c8ba40a5cc17eb1ad308ae862a26e38b2ffc11b7abe3b58509b21649b86aab9e0d1abb601604c4152257a6691a964657ba0d1f561402545b782960e547a4dab7b71aa95c67e64caf568c3b3144fb29022cb0bf01b895e3327d019b591ca282d22105da99b58be42bae7185e0b56cbd0c56ead56b5dd34e9bc1859b927ed78c4ee1340960256a0b63cf4e1cc9e84a53a48b2f70c3c89e83a0005d65019a8419b5166469999a453418cb94295462d9256ccddb3fcf8365cf0235f1d547498714a8b09553182fba093f447a220146182a3acf062a118b22ca49756505978f21db629799cad72ac5d17b2bfa52a6ea15672537899a313a4f0b7df3f8639906bd0163735dec5923a038fb7b5856570e279275c3093998338cb595c9a6b712c06c526166a725b9098ea02ea10c5d7cbb86b935703f122dedb05233202968b59825f41f2c17ba76ac661fa69a7998c5fc6c2fb68a7820576b1fda2c73daa29cc21dcdca47adaa1b3b5258c1575fc9270712f3b8842978be50a18da45159b99272162891cb8a63cacfbc30bae0a4364c8a6537e1b40e825c4a311488b133956690e494443ab44793d3717582701fac5486da4ffaf02c058ba688fb88deb3c94e7445cfa89a79ca5f4b991abce25cd6b74afbe9c63dfa0f40180b242ab52c1a455c0664f7357c048b27e05ca46b8605e6843c66fbc2a6a29be135c39565a916acadbbf2aa2656125b603bc88c9d710399a84850840169be61bd4ef3687777075f0c7870b61903a26e6391a88b114e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d213f0970c03d32967b06cca4cf58e87559128d14cb3f876a1ed10eadfe03fc1a9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = 4e2c094b4f5e09e17f2c05a8931715dff6d0a395bc9ee327e019b3683bac51f148cc0ff627613a7905a8ed870dd1aeeb7ab9e9055c860e92469e5f6233396e37700af8c4dd1a745acda15142b178f88af9376014d1153c9359562be9e5f87c25c08961e7fbdd00d7d9caa1134f18585a8b887a6364b92495379e6645f6164925064cc8882d42933520aaeb27cccaa919a9796054738ea4f815f70a56192c80faece06005aa0909d8bb58924ed2cc91284f76e33620a1d1914ac0208f1b95fbdd98e34b924c8699b9a0bc9cf686c75ce50e05873d2a95ce6cf5da1e5cc92e7a73ff2caad08dfec1cb84e8ddd6cabb0aca78c42261ceaa6669c917c7bc0b24d6c96cbb2d2519738a50f6a3e233c04a6243111c7fe5fe617770a89e86efa3ac5f510c0c5a8a568364edb478cb43ac0b318893e9a07982d4564cfa70cd95fa10191d9d3c1df1814df49d1353fef8daa5f7130f8b63b633b7afcc3d39256d281993c013a2743ac9f8b5a727248e9336f6d7922133d4caa79e311a64799814cbe22a8c3c9ab8f70f09926c83dc97fecb39aceaa421dd08fb17c72dfb84b7c7fe309bf65214af7d800d7f290f649e5b7e7d3bbbc60cbc89b03882cebdada415c22ece89194d67b663e4d3129646b3ca5ef8310da467b6cce1db6c3016415575315e6601fb7023143ade3ab421f3f7abcc62641d058bc6b25d5a4f719bc218122831ffed894fc5159ea86ae60dcdf69b0fe5a4a2bc6da7eccd007e7167c939c8b0b730ac37e9917fd9bdbb125e6708daf97f6e5273e533abfcf478d8aa22c16724bc7c7bd7c8bbdc01f6610f1527832c3a82b76fd44a2f516cd7c0c650e6736353244c733f9d23b06dc25222c0b100a65464196429760e27b596ea2498b44bbeb9652c32cb960a5c501311188d001dcbe04963739d3653dec28f948f5639e0153690f75567ecdaa21d4a113f077c8372a17f89c08552850317975911307a148edcd4baa130ba91cfae96c2db73d4b46446341a442cb44d47181f3bfd17336b9d0d71d63c825dc606609bc583a59564dc98ec68c908e754ca04989cd7a1dbcf10f3348c1e +expected_result = pass +expected_shared_secret = 9401f92689a452b5e58c35cf06690596faa4ec0937a04493a359b59ab3b0fdee + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +private_key = 50d47ac334a631e3c9bf8aa02bcc7e35272025cc37f8c844641704226029a3ac14bda6458c33790c806430bc478470b94f164a1b074c5fd034466922f41ca7c70a61c0e9727263579de085eb468cf44a3dc112525b878645a7483c0916a28b0ab8ccae79352e45bb186806a29c381caba12e0b505831200f8b874964686e754b66a66b2bde90826fd34938a46711a01599bab22a148c80fb0ba8455ef42c0b5279122be3cedef27907040f9641b681500c50679de3f534c5ac8754f925f446c6a114a989cb7b4269a95e3630c582c9af505ab7d3ab6533288c9316fec5512c21ce2866ac26391c340467baf3ab3be8c007587b77d7c7cc10c036c06d8d1590f417bc2c8909bb85acc8d29fadaa766e89788c406d35da78990a0aa2a1c0d0f92f73c152cb797f976b5173010a35fc649744c69529c354b616a8ba471496970365b1ee822c65201364405838d398ba047e5342ad71d831f2762798e282d8381730184eb5536b85ec8d0f59cb5b7a10d2334f876394f1f154bd6272bbf13ffc243ea0c53b3ad3adf9382f135766d5589769b7672b5126ccd6c8928709cd638c28a38c0ac9cceb239f147ba6ced8bdfb39688e1ab90ce31b44b76c32dbaedec4b84503160db41e19f82b401b7a97d44161dba79d991468635f04545982f7b818585f28a320b744533113515ca95b9cb37512e339e716c92569c8ed8122c131ad265b7859bbb069c136818a24250339e1eccad295cf95f6290be90e2a94b21ee4ab84ea5755332afdb1545cb97effb091221b9b3690b06d66795de7898669609fb26a5d37814ed9b7f55592b02a6c1205c8f0c23f0b691b6f64194d1270f8042a7eb6563cb2b178f808aac06fcea7432b025499499f2d5b8b476ba469e7bc43e4a091e88bcea08454e83d2606ade78a4984d6b6a5586c04090051462ae79680a676735267607b256d5db4c6a7b2846a73093885b277043b7e98ceed99bf743904438c8888064ee2834109a70141f791e5e26bb5281301064935850e40641183b4c1f3776de042a78e0966540aa25cd484182b30fd3cbf0581b7b4a31250c103b6620059720c3d802726470d1c567b5908698650360db82700e7b9dd26013b6a8184316df3c59194fc96a0821a95c666ec5b130262006442cef64428794672b43bc1eeba20de01bc70c15835952164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789de2153b3f64411534cfad0adbf8bc0aa51bdaf396e5746517c5547b3112fe08188da54932b9b458458c55f146feaa9620e7bb6ce21648af047e0027c3553813aa81574f26483e93a5ab3642aa1332bc34f86328e5f80b272aa8971d175ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31a9b27d3b17f63fa0e0da16a3e54bc85da61a0119a95201fa51906d6e2257b2cbd7235abe8b80e80947cecb5ce87f9af68442e8b6336c68ab0b170a67cc14f5e5377c4cb5930705775e522ca466dfebb1aa800b452262a01966ff624ce79561b3a40258be53512d01b749c25ec903923ea58e6677e02b0430e996000c637d002ba09dac9e717ac64b634688b558d598e4017cbd46a160c621dbb2b961638b08a488fe8d814aca37165a43ddd4b3908d84246794678823e794c9191332f344077ffaa50dbd2a6e0692addd353588b3e87e31f3ae4030b2371eeb1cad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4ab1f87235e1f114cb93c3150e25277459c43a6aabe39af63eac248d19f21b17ab5a2ac14169b01563dc818552ceab71eec2c2422c3e5f703b84bcfb457707a0b3edc80c0efa324d407d077cab9b416b3a97713b89c6d65c2584ca652e6c4416bb44d3e7478eb21ce1a555456b94271689828560eaf4394bed93a86d48ec082a7be576b75d00ec418228bf93c7037a49339352828af07f3729bfa739b00d04b5502b9d6054ba525d724a0df8506d9ea56d750072868cfcf07716af003a02c45d4991f4503bf5ac86024857acae4ce24850def0632a6dca9756c5c8a459341c69e93e154858b7c917592bb91c23ab622d3f84b9c81445e5a1e59262bfbf025286bbbb5d03eaa794445f7839f3ab51bf5ac48c978f0310128817d27e658d9f468f77c4c69da09dd8526539c2598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd083553153f7d65cd5cbe201e681245eda61e1ec2c7ee6b91a9ccdeb6b76943b7e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = f58035a4c7772f07420775b5ea7701f30a67a905e93b0131287c8c80727b2ee674004421dd48098281580c8872e3ecda197617d1cae78a4e9c648e64a811f2c11427ac3daa918a67141df332a7ef030cfb2a7f8db782f564010077a5091fed691b8d60a940e1dbf6d11326f13251e0b4cd0a44db1a3958bcc0860a87e430ef1b6d16ab6436ad5a3d79e9f20fedbc75baddafca29be9a308844047e26bae5846e00222aef148fe6e71009ab6c2c5c064f129123fd437f30953182aa76a5d91b1edcf579c59887466afa1589855752bda4e642bc99e61e18546e5324b50a8e012394d93b4c65b0c2f284fbbf1ffacd96e41737bec86540e86e98dfeb9266495d944db588f091d21fe0ec3d3432bf1b4ba4682690bb9b1124a0b9cc2212fcca7701d4cd75f5b91d5644b6746ea6e971b130d554be196e51d979e2f7cf5fd613f4d4a1b689a0028bd5f42f772b3bd1eb6fedece5cbe09bdf6e7d4fc01067c71ccf7ec6679c024764753a7e801a93b1dbb3d82cdb35588551a4365b0a1878ba8a3d4d7ce4f94bc03da0a30ba53873426fbb73d871a94af67fb7bf585d1af2d393a5bf33e063d2aa37fda97dbea3f87c7190944662b0758339ae937b7e60aab7c8350d1d7052dec7734878dfab0e57a84b65f03dcc2bf5bc4874a435962d7f1d41b46531e24b6dc01411e77b6d07a6e962661af91fdfac2c10aa0151aa7f6f47af162c21ba79fbd72f176b81ef412ee9784b8833a3bf76d4075333a2d36c22e8f999cb96aae94221f98c9feecb9843dd8a561a3d09a88e9f514441662e5f1d66a986d07272b4ce1b7575d7c3b0c4542904751307fff429fdfb38e82f004ffd8a3f23fa8c05fe59097f88ba0764a78d749621b5ed51d7c03352b574a1c85a19f3af0ed5916d15ac826caea0ab3d3bd81832246315c76cc0f434be5f517f07c92eb8613b5a736ae66649c4a5a53912e1115232f72927a076109db03aefa247bdb1f00a7d5915c3b6362799d7033cd0f86a43c727e4a293916fd0c2c98a66e92adbe40d562b5dec0dc61578a9c8c10ff30ce8f1dd24633d7db16ca2888d896dd1d1c13375 +expected_result = pass +expected_shared_secret = f2c689c7a8180baf27a4573d3e6154d4f2bff7b3f34d44576e777e2ac1249e8c + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +private_key = 456c6c1d6630bd63c8b0243d5b1a6ecc09a28b09bcbf96cfaf056e936a0184d6774d9524f4a6000e974fa7879574629504f09a12838da39c7a90f4637c1bcbb16677b491b87f653aa41ab5f6e279f917c65403a78d07b136ac8486eacf42252428c3b09ecb91f7a953cf98484b036f48622a6dea3a46e7b33c500b0e39620b640f6c14be17fc6d04cb815d4691687737f413491a8b9e30f28c7e2bcbdeb92b21a1752b6261863c84fc5918efec496311cbc7557223cb65f2169eb6e1ba98b42a56b71ccc6133a7b50ee4442ececabacdc960856b590f5792d973a3ab82b3ff6b36b64757d04787e0c4728c0649cfe16d2febac26a2bfabf985cc8b1b5511ca85760fe559b28072286e9b4c732b156db2a9d08238e54336a87837dc93b4742cac0f05c2d75ccdf06787b21548f19280c05298be80c79296bf9609a8d88347413b426a38001d59cb5787513fb53a51a0cd39c903e12a512891c43d39372ec2c0f3398dc091729ca80061da2484a01c58b8530956268eb6a5e764443190ca2ca896f142c16d83bd93014ef7852acfbc48c8702f1b39513ef20f50d92eafe74cc057adb1c363f59a9b962697c37892759859080a287d5b7ef62a4aec718020519bd5b59da69c60a249b55c68c2d523a507245d39c8374c67ba02d172cc98893761149bcb6fcf93cf779431de95132a029591c92273078a403895c40467be735b6d2346dfa33568f654a25b7586e63b5a820998374a0a01123cb915512c1557b4bd1366be2c259c511492d4b200f9e618608997b2b80fdd873a42859d9b98a279121de3a5a06652be7e948c01045ee41a08c068519d9125a7bcb79c5c713f2c4ca4db7c30f9a7a7052ab68280a4b59d22844551e4028f8740253447a479b5fdb0371ffb4c39104b51c13a3ec7364857a775f3a8837978f560c31052b01f648dacf8440eb3500c447ef81641130cac60748cb1e108facc918af165224b91fd52c7ea1a7fb5f83217284d5e20c951fa0fe47352f3a22d80d0b95875bd80640d95142db2639a830ba302f49a8caabf009104f8b136bb75a38d168274307db8d136ee08cee5dc61cc732b09e221ad8840d101040c4428a798704db118c037476701a79ae30f9b7265038abcd0933d1100492a6b2fbaa7c0d6c22704571520f35e322a4bef080fcb4c83bc62c432f75f6ef22b2b1722351343cbe4460b25b4bc806bac542576ca42f30c7ddef6082199a4edc2237e5271eeb024e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4e0168ccba259bc99b9f4c54cc2a8c1489415c422f70249235235f81404c3601079a3c8095214ae03c86bb4a1487a00710dca3dbac8a89d045de4768e56329ec6709a9208df6d3af6f8c7ddd6284f144120e1449bfccc6cea22bc3917c90f6591062525804054553a46a226093383f12b8529d306ca2fa03f3371de8641463a353513a593d601f91937c3197cd535768f78aa4ec11c4f59267b5fa47b0b2312ae97b77aa1c3631b7033cb17b5a592c89091d0a2062f8c7299a2bd7f77832899b1a84ae67a3c11e87b17a0050523b9a9bb87db0152cbee582b9d821937a2770d07d6e2113832c1456662ab38475a1527fd23287e45822c5d0c19875cc4c60c9ede44722552013b6ad7ee4b860ec2ff8337789832002026d7b54676b44667961654902912e3116402824a64cc67655018803ab2c06540123166d78b87be63997692efc099e4bd72d734b1e9dd6344df12070773b06c5c1ff3b32417546ea5416c204917f104a3e603bf1f09fefc3184fa43f06200423c3026b3a2374186df33344cde1ccde212ebf626410907fda57a9538b165b3911e016438c4b3f0e485b3ca3001ef03466a8749d1488e24685fc1cc89e012758473601b572acab4db6a93edaa6aadbca7924c23115769db3a4185aebcd09a9b045b3437dab3336b47a6bc23370a53a5e327b6654091f9a435451cc26b41ecbc129ae109475793c3977b532c6a8cb3317d3270bbc6bbfbcfa1c2ab2c41908520184000e3b62dbc3005839200b486d6b89b1719505f6fc4a3b7a41ce4a4677b64688284ec18915f17133f81c4f73c13e14632873652554685debb7b987c66d01b9049f6b2e44960022e7916b61a55c12c4f5e099ca059e3f98704ad5ca1d2676496c21782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e225819df5746a44b10c1886f62b068d18152a85792781160e1a1a19a25b5ca00555f4de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = b7fb6e4809a80d079c30383d7428c7b85b84c3725dfa7d4119f5fb21c713207015500d2588003c3db2f2a1c6a771ac4d948565d51e9405afdaa8ae5d93e268a604932041bf8c6e8a69767706a55f0805b2e5d9d9bd3e35c594241bbba3805be580f63186320a8061ece24ad66e5f557de610e321cae9509e31196462d633fe03b0ce992664c223074ee5459c6937aa8632e5311860348b914564234c60640b4c8eb34496e1546bf16393893b065c1b58ea733fd8115f97620131aa216890d8c5b5146f99bb6004d76f846431666bc23a3aa3a6aa6863a82ed11291b1284b4ea014acd1ebbc31c9446c042a1678148b0edd54aa5de979be1c463b6d6c2c86a5b669db2d09c7f6942c795529110144b6d5885e2bd035f82f5115fc8e5c0703bf23403def796e03e6f1a372e25038da584210b1a07cf2ee20e266a7ded2198a76a624d1e0f01c6430dc24e99d2efda1b0fbc9cf964cf31f4eb27f819523180788308729ed77cf2b4960f1855cbdf7f5b15b10ef06e9c18c07d8364f1286aa74ea3497a73467b20b3ac49d6eefa4d70a83245538d7d644f158d0331d10238e929d28fb12a60d76f536e929f128968d401ae554381ca24e8a1e89c5e480a5f79f7be672b7b11590f68a4c319c295962907f4dd309cae63cb00f046082dbe60d768205f69577abfad67139310721025ecca91d77b890a02aac012eac4e87f1a6a3c68f026541123b22d82231c295d387ca7ba7bcb620887a94429a0b8c8194d9ecb533a86c1b178f29d1080f05033257304a5ded43f4c1968b4bde413757b06b565f79f124bace778f08b523ece29a84516c7eff38f56bf89b99fb0e2f6b6e075b44651d146195c6710229fd57c8054c073ce48224778b317aedfaa85ce534370252bb537efa267d5745bb049bc2d53abe121cb4a5290ed77c8974f4c491e93c1b4c5e9183a114cf32ca5e3e8549a00e68fc4dc595f9e5dbfc8be5f2f94c693f87c66203e6ec345f96286f3a0a19d6fc58298ab987203be622df26fb417b00e28be76e57661d27ce69ce2e25df76a82d74bf6c0a5815c90b0c3c166b6f43251ca0a1c0 +expected_result = pass +expected_shared_secret = 1dac4f6f8d96ffd931f67b03cee8c4e4bcb42eb8bbda5cb702dadde8340d1524 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +private_key = 8ba88eb6987ac9337d47b0a4a56748e272cfba9bcd68ec072528aa26b45cc407754cf07202930b42371f012c9e4c2b23b69252f8d82061dacb58c72ee32b0a5aeb7feae54333411e3fa56d7aa46fc4392803925ff2b41273e23428f3a636cc99fa855003d6ca4f71253e66b87d2815f1092898b942c7173bf64832dbb05c4398c9366350d7d9ab146c6208498ce4340e75e7b9bf729dc207c37f1bb554437a6336535a42546bb4b4d8220e8660c785e96e974030d7315c94e394f8b8056fe31634909a0537cb215581ac29cc9e545311eba671c7986722cff1567851e71fc7046b92473227f1127249a7acabc8be252f4136c9b9ab6b5fd92ccc8aad370329d0418cb96a6f02621c01e7b00af17197cc7143653794826fcfc05ee91186daa50ba6336aec812db7218c0e291ffea70782a46d43e84de1b700c3e3a54c1839fa933945c4bf58692924110e72c3a7f9f19f6ec743d4585163e803973b7992fa8f3b087ea14a3d5b8110f2001e72ab8a79a34347a24d74a68b9e0406f2bca624454d1a6c77dc0a1f9fc3801e701db5247b10b0215c474086163653ebcf0b0b66260046599a9668254bfc8871e947c6f8a5212c7245647c25329289616217eebb1577020d4506ba3446a9914c512bf62a2ff26d1bf4cf582a5552332b239776b00c7730bb02be799df92377d16c957b726d89b57b29b13bf290a6c45944d272ce117b6c5d596bba18097429b6bc5b2042919fa83630bd55934ad7400804865b01ccfe84bcd17303ea205b3694cc057ab2dd42cb6826264928a05f2baad530a62ff497e3e09a6439ba8799b3a20865ec340d05e7c4c3a596b59cc62245a1f2b52f0d45b939e177c595a78ba16cba965043b210bfdab8e43241c26973654a737f6a3b8c70c3f2c472109c89fab0ab41fabeb2268095165b8e1ca5a63a53a478b398bc5e84e2b41b8ca6d2d6659101a9c1a97a11ac34fc2a83757390dc00957b124bc1d1be92a4ad3201bdc4924ad3f24216b2894286640546c865536d02508dabd619a3c258756b436b1286aff17f750511d13c0960f5080d1c0a011989bab77db0253b6f70c439f9cda8e34b944822c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b393269fd3478d1836f80a9cf51b03fe697846c44abe549aa16a25819e38c9ca1262ac103f4417cde8138f84050c0bba5ffb5090c81bcff1bbdcd67739bb60d236215b8ecb5c9002dbf41b36ed335dc4778153761472421d2043f06a8a83422ae6fd0680b860cfb589a3f5b85ebdb94b3f21d24f374949563e8a35eef8c70507c47dccb241dfb53be08b129a283367b48894c090b523e6ae0637fb4894707812ea9b528f54395d0bea3bb3a6772881061c28b8c24ade167633c30935a6c4f29a68fa298bd0c0bc1729c330953fdc5bd6c92595d576e4d6cb45a4a213aa299512c304fa2a3f6b1cd8d545150965bca39703efc502608bcd1e42da21cb129400dba7a9a053a6cc17066d9d98899d7c4aa3cab66b1c13d58251eb196959a6a250ba45023b9e6a6a8d192c0eb548e69d20c68f0bac8ec682b366926d62e878123e198add1d31abe91a02a5cb6fdf6a40255bc3355809fc8ab529a00b0d451dce9a657e961b4787829132a7192139532195bbcbb0fdcada2c515e3a83cf2485fb5a28f648981ddec7a80470540c71d53c29aab8009d9067c703643c1062165e3745d3ccc4e5249efc87b9f73afa08b1915065dac1c4c68422f89589526188ceaa19f64f0cad4781327e85665b5c59e8c3797f72642897db4515da47b994b2c6d3e41949363262dd721573021aa3373aa22758fcc22dbac46806c9005001c92aa9b05d0c789dcced4d427ae762f4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a4e194aff46422fb57fe4b2b2de18a060627c3f19b984aa7b738bff9336f80171f8236a3e95372975650d6b28398865f206a1bc81c346ee76999b8b889c83551f42495000eb9f5aa3ac16b9247091469815cf4533eab9be2ca283b962ab0031892999b55822eec5503d7201f446b21ec3319813a4f7b70b68a438c6147c182c48ded8c5fca18b2c7322fc3e4341eb46bb130464a7868c5d3ce5b1bb479e69bbdf20dfc59380099ccfb06789fa1183c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a9415ce164fadececacd75fdad3284af20c52fa576699029d6e0ce77bf347d520be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = e756a73da5006a8722c6b9dc0cf22c88ea6e0675a120dc5106da63743538ce258cc7f2d76aba306cc29a842af082da2ee435af8a36c664f7215ebded56b65778a236d449c2a7127efb4f76b9013680ce3c1f79e3c354c82df0d117302bfac8de889b469cfbc395efccfacc213873cd741cf32d9892d24a671d68c5d78f45f958d77922a25e43ffb8c3d88d1d3a622cc6cc0df3385340689c1dd5b2c28984ad881cd123ba1c3a11d8b20603b5e3a9b6a629b700834e450f267bc706a40835d4872b2b639382195ac0556ab110b68d5994b2b43dfd89c7aeb87ff4bcfcca24fa249d80328935aacc3376377c26fda978d7ee12135afb76e5c4354aee066c0f8eaf53b7497cc2695130fe5e03099b66649a51d7bc772e0c24f1c7a29d0e1a4239e15006e02a330e1e831ba5f0fe864ec8ea2e4149d7361d73ff8c29c4e1555bec5cf7fb7b12382f6df0d4b20901a161bab4c1bfe78405ffc286d3084b9d53a8313f9181df118909cd7fe43058a4e8d95354a6cc31a4955330bd1a8fcd88b65ebd8e3ffb4719387943b9c16fb9c7514a81c15cb9b79c2f48c4b47724933b1192689ca71d662c6c3155b504f5e7e0309bceac043b085d5a2db8736a5ea680518a698c78d03cc2757418f88f8aa4b8901da6555778fd4e82e299af2464bdb1ce8b3b47b4339795edce833463df3446834c15e11214d36f8fb0f9ac4038240c1c618d21063065144680c34b30994029633af967046729ee3490d583307d2324b7e6288bd944f45accd0464f9761079fb0db5f7217f9574b3e4c6a1d356a6333c1939846ba676ed361475b53bd04358510b4ab69da5abc2ad4c55b09d8547169891cab8e96e48127e6c303f2ef3ac1af2f4f30812a47fb4d424ec34a690bdc4e9288c56a747b029bcb6aa81f9494b7e280172b2101c537ffcf8ba2755498c268fee4b4fc1d3392a9bfbb016a987afe70f0fcc4476e440a5ac9aa2e935d89660ecaa98b368a3aa06c5b745c380bc95f854c367fb32b7cd7c84c75c25314bde0353d1323d6550ffd23d3a4bbd8023a029e8513d013b0d5f9f0fdd7091442d6217f17f72f52 +expected_result = pass +expected_shared_secret = 01adaecc8cd981e7f00187622defc0cbb8934464ca4675d86bc7d9b69148c85f + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +private_key = 7c15568ee11684858038fb1bf63793968151c90a6ff875a0b125696ad14347a3130f5665340954928447243254ea8b089fb665a3c18564f65bff5ab648a58c2fa7c7c9c101d055202e1742ef98c68930ccada716e03877ea7c8cacf13739b22059eb0430cc97feb3a41df06d2e35930ef904ac669caca41c9a24cf96075e92d36cd8958d96584dc9c85bb6851735fbafa07164a2a13c253949b44769179a2dc2b655e1f0cb66ea2c39364b5862b070b805a58b4541f8b32e5c2bc6b2c2de13107462cd2b4c5f783184bf61746043277952816ba4c6c259108f91bcc15a951c012310d78d14c96add4c043e3a341e072aa3b1ce83214813005a759519700362fab0226a58a932f71bdcb03ba0a99f3e0656dc1a28ca3328b4fa531b3127ed790398a45cd0bcb95be6c91ad3b2f94092f7c4b99abc864842466290c5f077544b4954ce06a57671213e9a7dc1405b2c1228ca2824b4b433eb65901a2903abb2c4182a144efba1fde9063bc40d5f7940b5044055d106b064b099183ab5aa34ba4480ab6266364c7d9f5689d7abc47822c456122ab2b0679f2c096d4c0c6f29774620c09378a8fce888243bc738a6a3e3607ae261396855989c445f228cad87182951586d21033f32c250c13881a2831f9c738018953ac3f53660b962517a64cbb2b1e26867c77529fc21ad452c7bd562b30b5720eb120d9b517c7f8cbe1123a090359df30c3115e57fb61bb47f4ca5ddb2a443b9a2ca56a6f58010d7d0cc05698e1ea539c32920a8424420b675205b905fd117fe0c7bb1f888c7da6da060a24b450813a613d9c8bde20c38665c918a133ba7da7c4392467cb32f21ca3f7c37206175b242070236a12f5ae73a37000e386130a0a15e06f0a4d97004d8018223726b454623ce9a31ba150cf6182ea4752714b2870a612b9c1484e0c199ada27293648035954da75ba723a82f4afb2c7085111709a63ac5b9f6e201bd11cb30f48732c84f4ee3622dc83ce6995ab81b20a8e16e1b1684062569f4ebc4f2637038f489755cc7126535d65bc6ccc0a00ac27e1700657df77a59f57339323041a2160401bc4870419a0b91a8b97bea251b03c51630381aa802b51353721697c4bd2891f37698ac51942d44c931f205ac15bf35708806a118dc32b51655070cb196246b6a63db0c57d727d9aa812c676880e3532a435e191935a6db1e1b110cd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb78090ca1043ea8ebcaa3b73c768892832c357b0cc48e875f849149ffe63a21a169798b00cfac58eb666c9ab68729dcb60cac6dee1497a64533989c0a68b151f8865db5f421eae77292155f12944322e579d8f61c20ea53b34cc7553b6a97db6c3df847b8aab6b993c4af02c44d2c0ff555ba6c68132cc6b9c4766acd030c33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e10561965e45551398a9632169d6a53da1314a9b4533f4c223fcc46ab0730a8b463c537c2d5ab8c9956c542d6119f76b82afa13ffe637e09297b2e6565277079081c574b05d50ac2bc8e9538d0105f828b539d47f3a9a293b4b9b834b2cab741674b8c61f28a778b736b699bb989705890951c30747896508421068dccc0f990611ebd800c942be5c886a59b008e6fcc86956aba6863bd9558417a37579b7139efb5bc47b1ad598464f287a3d8c56d748c6ae794f31842fc3aca9c5c05fb5f76c5f740d2d7908e01a173b75a35b8a70cd645e66e8a6d290919f227ef5e5bea2816b31829cd291b136520fb1a2825ee01dcbba7ae9a10c60a297d39c7b40f53d02d602627879fe6b4c00ed426a0b065429acab34be641c356be26a7c5012b9643fef007577f79dc99459152c13e64618b9f9b3be0b551dd33df8cb7d890c48ea83b68c42a327ba25fafb5ed65c31f4e6b639230aa989b1ae7a2c5ff3224b33883955890e5c7aa691463e58977c31445fba5c408047d227aeee6bc90697545ce0885c3abea2ec9668359e59282c22a0920ec76a282c545a80896f5a4705c02adedbb0f8dcba46f36c112b578e7b4c236899d81259706c3d99b0adc3ec44e58171a5e21c052767b7692800854132624ff438b03cca42473622a6db189be32c7e906a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9ca2232297ba8b986dacd401896cb6239f557720d91a2cfb7a73274bac7a0f6dea08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = 329030cccae3479b35d7c0ddf09909c9e95e499c46a4843a29b28ec0990ff257f419ea1adeb11186f273df00d61e84d66cfb5b09110d3636bce91e7f7cb9b480dd22cb6034f85c1600a764d510dec4e10daf714bc3eca661c2e1f53b266e63e9c4e92d8d7d34cbadcda42760c02803136037a02d996855764eb55b2713f3cd3ac9c70d59886cf05382478d58816d37f1b13dc0cb5ab6c43071667ecab8d10f5b220ed4ea0775c6f93000a57b80d881a00085d86396119d832fbbe6dae1fd8cae651c2fc5c25c4461edca02c50553b98a21b219b50ee7ac4945c5b6b203ef3d42d243fc789585d009e9035cf5f12322ce47cd04bb5179c065ba7291f46dfec925327f1692b63ba33a2f40666ca546597d335221060afc6729312a7985d3953855efecb6340e1966520e0af12bf88d8bcd413682a74a0bbee5bee9930d4d2d79d194cf9bf72d17995eda7a6ef970335f646693169d904193b35c723cfd2df1f650e54d5321df3847c892ba6b699b4567ecf3e83c4ed2b9fef04a3f544a3dc6fc0eacf6b3f7164b0e482b610e79c2b1bbaaf42df68d4de0a94750d0a4bcf39dc6a60202b7a23eeeddf155e348d4b96d2d23aef6ce8037a4611b5a0cce68b6afd284f137b5041b483d7d2cdd40863553eb99378b53565b364a3e27f88e60a950b2d6099b100b495fedcb094268874db1e341f8b17417570f33c2aa05270b5539b9a72261ffd9948fe243a7faa213144e12429c47c19bdad12ea0113a43ec269e0a0740f3a1c79c5af692359b23ff9fa7e256d32fa4782b6f7722bd0e45e1c7fe1e4fb9e6c3f5b916bf8ec2f52847cfa2eb1e5c5993815261927f2eaf914c24c4d279fec6e2ec7c5bddd79785f225a22f0261c99185bfc0348e7f6b6032e68780d3b939b8a9ac7c44ad8806528f9b5d3b905aa5033e7ff01660439d5b897e9a53036005bd8bbefda602d9ad7d4b8aa68593515a7411b5e965fa265b19df9c8c295e7461d7e8c5768758a806575e55710d157d5235fd5e7789f260a1f02b682416f9bf6869bf076a5a229b2f3445d52e959a03db3b8d859632cf3879c79c8cd6ca6a8f +expected_result = pass +expected_shared_secret = 6f13bdb1452d9e672c8fedaf9450c436e5fa77e8d58ce83300b8e539f20e9dfa + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +private_key = d99596f420a269879b1e577a0a909430147c8a03b654d4b4d42c348c041017965b1202819e666242365779f52ed935a0a7253a38c25e55855667042e4eac0504659d64e83b9a0b2a15428a9052ce450000b215762fe0240e3743ba526226c20a6388b9d0935b208bab0f028ce7d1c2141a2d0dba1161b44dd3269754da10c9538a22eb914fa22d0a364c6433736d7bbe8335a182e14e269488a79c6322304ea2c438bd9b9a6ff700b8babc0f7303398300945a6db091229a44464ffc8d3dcc615d7a7922e62b134770bad9a9f718398202aac3aa23fd927b002d2bb38c990b8c4e5f1789f6d51520647b5a94badf1b148a38a4990836936c0e9c294e95218445e3131ac9c57c88b7da491c15b91e906c4e898114672a9c58eb04c9f0bf79b02a983027d5b5cd52371a11dabf91d79329eac48997a85aa64bea5217c43c257ec2784113a18fe28402636139075b5d76aca968742d62c89fb528ef3ac9f30c5f23a94d8cd19a07e88a25d25167082fab269a0e010979860fb7bbccf580030dd58e34993178097b79034aa5709f7366ced6a4978b5c01c7facadd7c69d856be8eb836dbb9319a575059f9541a12a0bc86976561cab8660ffd4c828ae534bc5a8b9f1368928a2ae6b397347cb7ccb104c6d3654ac497758480ff202c32944d003a7c0bb944753c4472462538f1a34e2a1774e9295abb54a1aa59eeb317e9336a3b868346806a4dcc3055750da202bb87e3c1ac87224e32154627989e252558655b08cb6b878ca8ac403be561211551ae7af8a3c9e748f23c292b81931662515ba3814d7a86ed7668a4f151ad8a1b4ddc2166aa007807c9be492ccba666ecc02c887aaf9f47649fea6d34a40ca39806af384b06b548ee55477b5a2c0d62375bf6c00a9b49f541719452a2a5e01981a8ca034aceeda83932a938a7476c21d6ced1a6874bb073b1646662f0b3c3f6654fe032a510856c67264f32ba16bb4df0d3209a025413692b424b0b01db1b5baa4621eac639c6076f1251b106217c88751aa93d28873ad4e45593164076f0ce79925e714752520c2728b96d2f53cadb79a51c96b6e29100ec15605818b877d7399d4c70c4e3b362a3268fbb7e41d494048740ea222bc38b5ebd3cc8d049a2551a731ef31684247f30fca3f03c0a7d7245d0e81c25359f245b9523040fd2d24ac3941a213b561b974ce45156d268a0d6c5b555e251e18b31b7753c2826bf6654453b81a11478836d08c6a803ae48e0892e927960118d456232025c3f516a99e4818627760c88f3b8813b57e9ebcb37fa391fa1c7c8bbbc358b40db908b526a85ac86a03848820879314ca86a2c326f5eb69e7ff6c5a0c3779c20214581bb5f4973fbf54353fc448b0b2f00fd746f303473717ff829218b22bb23eaa132e31cce576efa0a53015c3788c82ee55a69051a62b6293aaa9a4398d61d25dc679964c33c6028448b92acb7ac1115c50dd3b064818cb0224209193797ea3df48b6ffdd8228d148514ab0c11b1840b3843a7472876231b3bd91822e8469a5095acf5b2bb5b138425b2d60c1e018951951917630b8da2372aa239bc88d5a086b0b6aed50618ab25000abadc6684266939d4468ef5c651ff69b11b928355170fba871a59eca1f7073689516d17ac6298d2520e8328f3cbaf8de33969ab089d6a046bb979c3365b2dd2704c359c04797384c5c7f28c342227b045e40e88d4bb5c792381e639c86a12885596144b1a6cea01ef9794122466e3bb779e2b0ccf9048f50557d536621d280b02547234700e442b6278d2b0cef240946c542292c904ba31a6a38cb9328874f824fca0504238bc090bbb78e60b2eec76c900bb6010240b839d433c4968833715121a884b362fd8c8eaf90a241b66d7522b6908c43890cea4ec80ca232be3ac573bac2428192087b43cd15891585339a6123475209af6c132be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca662742950f431c93a391618c2a410834c2231a92c3d91c471803f22543ce530a17bc924fc326aee4537a5b43fb655e00e46185e809996b87e27c6361fa7b53da5ab393cb56b1b9676155f2e57092566590642bb090571c6a92f60c55b339618389415c259705fc858ab71aa50021c1191359576c8390a70e703f32ec26419602cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f34486689b387ba25dd0e9aedbc53034924ea4ef9497b5772f10ca4d091e9e84684ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = 47e5904f3f55db748f9537a2a365dce063afee46eb5da5469f1e53d601a8883f8d4f751845cbbe9fc664c498350a73b80272d1a56b3089976525f58b2c5d69b7521ba45acee718267c463dc53589ac3b0df5d3d0e32a9bccbfd11571952c64db6e1c6ba8058f95df6b472955ccabe149decb08f8afefd1a3c698b4ef5801c368f83e54f1db222c3c5b51a8fe98819c89d0742e4d9f22df5354e11eaf3abe6b47f436bcda3c3184aa995f3aa44fda6c60f10d82170bd6947015302c51978c0012140d99cbae6b05e63d74ba035a58496ac54a6757dd5c3431b7e0117d1da3b30d8d61ac0b1f1fe0ffca95a0ea6f2934693e1980e6e46c6ad4cb17ee6bb4840d5d2a9e4e18e68fee480c1575f41a865385eb017c7d1e01c9c5ab263585b88642e936fa6600c3e4f6692b68167aa8b357c543e479ae92b47bd037688b017800a07974b01970c4ec61775a52f6828d2a093fc71f5b921f03e8692f512ae3a3c23af1eda49e6799947e4b4f83fe509a476efd5bd8f411c5a349a848d81a011387e3bae39df806fdd847ce885d0a8bf16030363d66e96f6a98e1bce87becf2a86ee6608fba434e8e44ff32aef118a17e5ed6eed801dc057b6f6905c5fc5695e099b229de0a0c30f6ce0b5ff358d9fd329cca06c412a4a94e5e91dfe076d38b7a5ab73b229a94418692fc234e93de64f7489174f8e29c0599a1431d8280830b33c396c591944e030e3ec4ff2090cd901c05b5fd1ca29d95e31515e15500935c2d06ebbdcf655dd9ef555fa2a95ad8ae6f3a7b6d60b0587e92e4b1a812ebce6c8f9f5e5f5e02badcdc5a9e2785dc9eda60c26b687ba214a663cb45feb42555af941b1a565da858a6034c8f2ae5e8fa272585a82e7ecdfc993b2793ceb51e458a8acea14edce88927fac5aa03ec8dbb575625c1773af81ce52ffc7285b3f5f8aea31ae908936e0dca950a383652f3e914048a86cc6473d4701c09150c8de47065d06830dd05579b2fc6849643b50d2d23338e973dc825d1b0c55acce3ea0499e9add6233ba80a134af4d24fbb98bf2e3ea7eba53efaf3af0fa5856d3a5c4b2c3d44af2695 +expected_result = pass +expected_shared_secret = c81a637f63a802a5d2b336dd960175176b2b838ffb6de5adc501bef984fed26d + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +private_key = 5e200d8f0801013081bc4a25b4480561b991d9741778034f86e10caad22023228a6d7b498182bd3c8b7706b3044bc8be88461bf6e96e851bb4149aa60981b061a45541985446a0a3fbe47fbdf9a7680bcee9d9a004968b63e53553911f262500d13cb97e66554d184c2fa005d5c56a096558ca81a20f6066fa0aa22895883f23889ec024c8401460802a6a36c42050adc1475c58f08d4b7135c000a76f26218d946289c3c4ffe80b6b903b4e8999c67b59b067c23390bf134a9acad0cfb150b09249ae101b45a8bb089962b327173801f156984656c63398cec94ddb6454405464cec03d69b0c81b629fa6bb5e15e8a86b2623f9eb7d44a4573ec58de91a2f4672042a49019187870d3b3d810658ac6529dcc145e8f4703238458313cbeeac8f393b4911a40e7f90cf8efcbd0987289a899d09d21e1dc2a810c61dc0312f2ef95934b7a86408c75923616c15594cc3cfed41888500695bf1506707561f0129b60a13e1d7a8dc1cb9cbb96f91122ea3a68668488c3be91965263619d28b22ac557b8b39e7050478e25cc4081f6c255f2c938c224a2d8a11aaa608acbd6a3f9b1a097e36661f979ce7db8a7054006483ad74564fa65b7c52c620ff28b6cb941a70570571523e419b900a16be7bbacbb437ae3f1376d21461672599b38688875cbdf489a0e080714a731c6f147812e688db77a1ac091ee1b1ae24db55aa57282fb3b96da70e4f3594352918ba207b0d870ec9e13491e4b2d51c201c62cb22c896c7f342c1d98d05b87fba883c93a17e44d27a569289ef888dbe63242a029ad207cf54d8a8df513fba39c828049b604a5ced06bc0762c4e2074771364be66263440a6c828359bf1b129eab51d3ac18ec6465ad6215442808b3036714f541abecb6679b37ee76600225c190a2ccd6674b6e95a9564c156df47436491e380c78be7861249647f0474466e781caeab7989838d9d82cb355b0e3c51963129e57153f2e58a7fc843968c331b1cc57eea37ee11424ba6673a8ebac23405e86c77d0dc316f708444649a9d5907318044ebe4857f69a5b8ddaa9ed9b0beb656f41149d4edc45c51bc84c04b516a56479711aae6b9efdc04afb251a0c121b249a03cfd27d8c435892c88c0db5291de3999db794ef43a14ef966c97c02764bbcc6786500cda603062e54b0444e52835c67b5bb524f52e670553c24cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e32207c8a255dd72a3de5ab401e540359575689233e1693f477b8c8e027629b1b2815b27b9b557f8123950b307a9d91e1dc2278a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c862a74730f16a223bb97af8d82331b7421172723473ca0f3e24ba744b2bd561900c45df2f3bd53ca25df405a93ca4ad222989a58136c9403ab5428b908ca82ba0436ea046f548f9c00aefbb27f497a15ab108f39f2829cd38d9db01c05e717df09d0a96b1b24c8a6e5e5354787429e559d61c853c1354f60dc4ae522141beb5f3ad27388363a392275ea8b7d08b68ac583713b714b9cc79bd9cb265d91666242429ac62fa6991c2501638772552ea54652b4496bf790efb876288bbd6cd4500a344f0ff17264f73d0a1a10e4d63b06884f8a5c3562bc8617ba4f33ca14e3b40fd8117bf547b5910107f5863e7ab3c3ebd98522f81923dbb55eb43af41a1af1047b68b940bbba364ff69dc57c60c6cb88d4dc43d84c00b0437dfbd913ed15a3bb84c542137acf1205f4826fe82bbbb701bc00a23115ba718ba5c80ca301aa970d303a0a9e5b64adc04aa8c8c12b39513989a8a27a578309661dc31a5de69bfbb11308fa2ac4d701be266cfe14a03e961fcb6132e7678d5fd06fd1a74262837b8b7228bd297a9685a98f217976b527b1dc0662d6238c8c4f05aa29b3cc182b78a7f29172bb2a8b50fb861624cee1c19f4f0739cbb157d8f60090fc847765209aa4b9b782127f400ef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec48c2ee05996e0535dbab9309d365687a4b61d8a746696182df7126b5b8c5fb27cba016975d4648b006f2b9c2345ab61fa68c7ce7901cc09538fb6349a391403802a26316bf15ccaa90686142ccf5e709cd4b6380088a18c42826330a454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b39d1850f7acb36ed2a35e9af6f94a06c31afadaae3545a069f892ecd8929f76699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = b878da0ca229e1586aaa9e5f0a266d610839eb54c963f659ea670d747a2c7435019b1d3c938f730d41fb9ed03fc028d22cdc011a307c92a73adc45a1bac2439a4d53b936873c83b5bd882e3205e55a7a57f89fc1f4f89f38685d7eb80ada1d3036cd3d1529c49957c6b9f4620389b53f0715ce427c86971b42203849b1183e46b58d5944286e1d0f3196a82a07b4d5cb5362e1a474db1cb98bffc0a45cbd896db14bf7978400be5d1e10d21607478afd45a2bb2f73b598e979d1164341b2c7ef4fd869f40bb6bbf47ff6793f265740f3305a77d13589afb6b7d1d3899f37e04301c449db9f1edd102db8f10ab6dccc8982618a218ec2d9d9cefa071b48aa97cb46a398bc6d1ff9436e8e633c0d3edbf37076a1ae760bac41ed59589737704ad1b051e8d6fd61b963c4af3670b90bde431bee2fa17554ed30d3c01543d602668587dd7c743b1789b15fbd09d15c9ab329edec2d774d7b0ff42b0dd913b4318b3e3ba98101a9eee73b05003cd10ec8ac71b82fe1709a2a678276a235cec6ade3b88a287277f50311a8b8bfecc43bfb01acf64d0eb8cbdfed46009c12ed423292a35023277d7f0388f0efd4e95cd465d92e70cfd7478ad1e0c95d3594ae0e63a4da325d37cb409dfa120b810367d4a92b4fa0444150ab6bce154301bb0cd5528fc575d4b63be3eb35c2b8b4ed8b96d9ec53375f684e7a96829d04a5941562d7c44391d0d857f3265e383eae277c3b3c78fffd31b0de4703a3e31e620bb712bc7537343561fef00e18ec93733da1446cfa3bb297eab64c6554ce1009a46cdab4f01674f9810958d5ba58ba7641afbffef089d80462861bf59b73f43fd20eecab234a506d7a59baef6ecb40ae50ef7ab23db5b2b88d1253ccdfffafebc1bbcbc7e6dd3ac45ee2bb7de893d3b701aba45d80c20aa828b1ff9ce975bc1f25dca609ab2f1952a253c878bd031640763ed9eac99b539b2038d47f59c80d05a8921cbd7e33b373d030335294debbe616d7a3bbcba14c8d92a898b74d7737c284aa5e0354c5b5d6551da0efe99c00c7a7cb0ae56548b6fd36216efbe3b57523b023739e2eec +expected_result = pass +expected_shared_secret = 3031994f1365446186b4a4d6190ac89f928f6706d08c6316d6f522cd7605adfd + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +private_key = 08e63b9dc03310e0b5e8157e478234286cafadd3bbefcb59a7fa6e8b0ccee499bda8c4035179c67ea35f280886f4cb4276a4a63d2823151a4c0670735165ce3b9432bed2a35b72b59f9604e4d6a00d441f6381666ed773e62b9aa159c80dd40b2612b968092a0792bec7241f1f3ac589db824b388c964903524987d4367a22d252dd837fc5552c68215252e8c26248c5118963eae4b81a7c0a8c33054a941c67da34110c45fe28736ba90c2a07c8d6f8123c5a098434025cc82e5c05185a80a53ec50b30c1a0a027cf711baaad56a844c7b1936cb73de5447d0764595c8e0c4908412131fd517fbcd84e14b87cd6c651aa0c975e02654d40cfeee7397a93893cd3a2e81568c53414a11443b0a74532c61ece525b3e98853152bc5738a27bb11ea6d0710af2866e7136f99bb27c146c00d1aeef099d7a398126584815109daa65108e1b942aa6339ef0be33a9a3969938b421b3f4f96dd8316123b3cc16532a20fa0f078c338b8c96ad9b83dd5618f20715cd4cc914f32e9999cd04b34bdbc92173f5472fa68ca0625722374c9bb7bd0656c0a8aa4d16640c8828ca4d4029ed49a8ca4ca6563550f43662e4500b00a2661d680d46435fb2c2a99c8571bf1b8b26783f1ae95ed2b4b009a3b6e74c2ab685667fe9cadbd3143c33641f2a6ae7266d8322a1ea567230f876dd2753f93a6846c2bd3b02520f03147379b4cd3485619c6d4b42ae6f838bfd67bd49f43f3781a88d75b180b9378a924bfcc61853e206ac42cd39ebaaead2700032a3d8d7b9a29c0c6f02970441061869bfd243a676ac27a7e47521569a539712121c3829e40e8f0755d5e6a8230736ee7bc3327a5df26a221cb79c2e2063f3617c54664059fb8053bca2e50a7eb4a25106781adb386c5a8a732d406f0114c246013dc4d79e8f701c053b41135a7edeb4644131ceabbacf3ec546f8d92d556387bd15971ab408feb5004247c06c4187f1324db5780ec8cacecc6772176a2bbde1ae54d38152849bc862c48b73a0ca6c459962b342670357239d0d37095953908db86fbdf66d52ec4f24a420d1f59412974d9ca888c1a6c02fd9251f7b8fb16c6878bb20829260c588bc80195ff8db59ea449209c2476da061db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa6c02b3e531ac550a25db8783c995e2716b143c8a1309572fe47049a65742c632755a7d26e5a3344309e0c14ee313b0a8d214811b64d7351258e80ed9720863368dcc1851a358668dab3f0cc77f074aae24d71e0b71cab858b29e6a06190177f9dc39051b460d338363a9b7f6c691ab17865c4735bf42a72a655155b5106c165085b1c504d6b75187a44ed198c98aa26aa15327c5b35f6b3852a58fa7613337094129367e0660a62fc28e613c762d857f99f057b4e208e39181c63a8a91723352b8c4a4e04c0c02b78ac82e13c3542634484cfc8ce738b31a3062d2579f8394cd0947157443bc9774089689094a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba819b0aceb923918112e22b5591ba032b2a0d4f8301f2567b266473f3f1101a7c9ab95c94dce238db18166cb0c8f558167df937377a2096eb99408a32e3759a88a4cf04cb57923a1b9ae7140281a3cfd6763bd92e0fb91a24e87f1c56471eb334526053db394d39f956a8e45c6ff39cd57303c0ac920af3a480329dc19c43df67c05d889fb778a0208298938ac423534b025a04b141b1eb7017c9d053b7463ee870bb17899abb19c99193b670a23672b0ce15f97f71092cc121a0fc75a4ad292ff4a4c9c78bc24c764d7d4b9e1230bb46e02ee7a66357f25716c386b91193fc5a85cf63a748072478f23b0fd432944a5cc25a7dac2297b1234744a918e7565636c674e4aa4d2c957c7aa55da692324935a4c3749a08956028675ef5b9ba3ee5111dd73f1dac282523cb4a89bfb7973a50d30085e70818ea596c7c4ae332adffc300a5d691836690228b2fc6600c5a3a363e357c66a53a0fec851cd94b29b066305365b6a78fcbe57dbb40c8d02ccb5f541d11d24ce8eba582104bb4da4b9e099e822933b6b74080f8b743b59d94f094cde7c45422317e358adc6877613b7ec0a6ce8b702a1a32b285f475af3769d8a1148b5324c6429ceacc5980b902ef043f00d42484a10ad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165edc8db1ca35744a75ca14516abe07472d0d1b723f70ca8cf0e5c9341fd2e8c26da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 63cf7c70a32a271417982c440aa26959410a79a7e7644ee15cd5af5edc1ecfaa6eb8c539391a486b9a7c64f8edc3f93c4f565c91e2d72c1445c6ca66498993ede26c303e61234552fc5eb14db62cb4cd5e0f66cd72ce07c89006e846d3cfbac98a52c4c4edc769a81864a63ba93f3a6dcc75f21bf4f14527e2e527fcf9649c75bda5edc21e4d13e8c254393c9095e6b80bc09eabc6e088f842ef5a8db89fcb885efcf2033555bbfba69b0713719aabb1fdabc0ca3e368b37a6aca44a4c08565797787f1d7d42aa4d66049514e8a9caae3d6113fab46e033c02665a0a80523b72d59aee48e6b8fc6ebe4d15c3d702817797c1f27c557dbc90f817d59ec2bc1d9680481b8954b5d4703dfcd8c3970b26bbe25d111c678bb5e9210a48741eb7189deb094fbf3f7fbe81c0d9e2e8df169d6221beea1c9db502fac210b7555dbe981def1f393ee57520b75eb25b73ac3cf8577255be45b2e3e065bf4c2adec044d5bd264d82bf3b3630b6130562c7bf0a569058278fbe74ec000d0d45ffcef441cd18357d91e1ad38a7838496dff864d4f8d89abfff9fe654c1f7876c6479f32bd6e6f6abf88e0d9d696933a1c5224689b7db0aa4e300be8a1c8f9b004aefcb3cee44a163404ffa3a3532b007b6b1d135df6cdd80b055b56c1faeac0441731049eb37f2774bd3a4b9d8796759a54fe9f29a956eaa16ea90d78c330c63a4f266b0a1ef06aabcb6d378be79c050eaa83f23fb2afd2ba24c82a331726694ac5fcc24de2b67260664fdf889f930fd4f2a7170f7da1ef4048c108e2ee2853535eee70616d16386ac516f083d585a01568c921a0c830fb01d524815669ba6f268e1f760683daf0a909339b512d8e6a9aa1082f35678c243a3e503154d574182e6df68304e80ece25d3f6cbd01d84fbc6abc62fe7e536ee645c5fe13231921e80c72056c748d2e34774d9b129c1146aee3bdc75295887244f016f501b37239c27ba2a5507c91e0819ae15260589848b7bf5ccdd258ae0d9ac2e36952238925bac564610e4a5a6f35ff57502c7afdc6a790ba151ba41ea0f6c2dfd60f09230af146174c3d9031 +expected_result = pass +expected_shared_secret = 61419eeacf26714b028d2f7e1e3769ae2f181a7e9311f3312911ead00486bcd5 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +private_key = 0fbb5b81752024eaa896950a462bb5a422377d60c59a8baf5295252ddc8a01115c9902d05821b7468773e8b844802a284ac25bf7140ee460373ef5024e40991b9764a7c9212c57bd3d71bd65674078091dcd36a157bb00775aa8676768eb880ae1947106202e848096ebd458cefc4850b15b0c2972b8461a59f8937e5b786635298896a392c11f61a678fe25253f5798e1bc7058b79397b5c190c0a0b178558e55c05c988e497578ab556702ca7ccf04b9e4736f32c002e21993b3fbca77f1ca560a1437b52f43085a551a2cb6abcb7dd07c3310853f374f25561563b68006617e55e2bfaed4b0fe04ac96955101f1933e9684e1183c8ee6cc866a6b9946126f8a257221c18722621bb151d5d0afd98cceace1050d2bb3e1f38796ea02f1f06642692e8982b2196aae69790b6d895fa3eb2245d09e16238618e84a01a55dd3e535cb113117d0b72fe10dc29a344b1a621900883b3bcd8d407b9dc24b8f468665b10ee86c5fb3ca9c6b0217a04c129da05056f6997785a59a4bae30a26f0159a6d98bc3aa4494a3e1bcb84432c2abaf22d43e22d45fc147cadd3a2cf14437ac35709c5636eb932abfc88f12322b50f8553de2c2d69a5622a88ba7d08b1c3cb7ee546c54426d70e400d8080d129104297c2e7a06a41ba345b1a73028817fb5a498ad81cc4a545b32cb70cf8264819334ddd9ad37e14a9a187828645ee0d567dcc6853c48c5af4a836f355d369149a5d32663c5b7d074774bc1720854c66225174028a565e42bb395cc1c8c3e80a23fc664281c8a9b144a39d7eb23b2211a3ce01b175265c6396108671845f4af8e37bffd5a97cad4c11db10048e467eb314275303f1fea05dd895ec5480f41dacf725965d4c3ca0c104acd228c0f10a634a18a0d166c8b69b4ffe604c7940d3aa06234e500c8962e39935976c1081726bec208be7f6b9ca51caaaa7465f03cb8de547d46c762797b7d58b056b78cbf13286a4479c5e5c70286ca6d05b892665435da13ab997b30d5e0223aa14cd2f50a0f80b64cb072cdab19118681376b968df5b9c2a20169759572c6cb36c88036e8c90878cd4e2008000d3e22d76ae0046db986b85ad166052648993355c2262dc8e3477e83bc9a843476da24444b3936db182c608bd044a76ff88cb3c2b4b4f44f35932d0bb3cd8b834ad6e23eb9d9825d4378cc40a94d007fc5d97392eacb9dc770bc2569ee1b92cbf0aa2abcbe1e8a1e10ab1244e14dee474ef3e4531e330eadf71db2a36b32e152a88b5d90b8212b45b69c483cf261ad54564a76fb0b2b0c2589037a294772ef8c0b00666c2cd18cf54bb3b9b910094a69fab10df29620a890bb07e16cd8b55cbb40c074e0aa256253f7159c07aab0a26a9104b73b2942143e9622e07c055f687a5e1c2bc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db19c2fb151ae1d4082103046032603d8716726539dce01c940a78423b37661128f88e74ce04411ae307048c82de6a2af26996b28f91e32c21722554e2c51c422bb2ff5e3a35a0468b3aa02dca384b0ca793d1b524b7c24acaa889175a171b2522a07969249596ada9e76d17395c49648740fc0127beeec0bcad5c98852c3314111d149a0221168af2ccc65c6961ce3690d64ce1554a137b373319c56dcb5152a19059e0128ca872ca6f100d4509f196c7ad4fc65ee6accac6b80a9e8315c7619870b3623d38d2778c788c62d291a32b1ea078bc5a4e5e2bcd34c97e5a6301574c7854a8fefd62ab6657e4eb9371e09b8df2b1a45370ed45214cee3b86a1417c234081047b5c84009bb10351932c3a3078b7cea137ad22b665cac0bc0c6a032778ac437f139970c377b4d651b0e284d48040402685dc3ab6d5d206aab39c361789818ca7b3e4c8cfe2c4719e054a85b383eab160139c377896fe0217d46b98f3d0ac2a44cbddd003344974f30f3b9733579c506659272c1755c9346cb31153cbe133328283637ba5b4d3a906a3ad75d519786c54143101b77b7053977cbca1175a0ac076dfa3c0595b0473495738da76ba0d4a2333452d88c82750c94e745852a1118bf7a03b6f1b448298e8a2b246b166e18760dd5c468a4187b80fab8ccd078837b8223769b2489420f456140e2b911290eb4e780dde03e1a699b38b95edbb1cd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75b1eef6e8c88ff8da9cc4a9b01d4c08b6b585beb5bb9e084c6c47a717b51feea356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = fc4177ca4d90f14447dc8a12e6f8e99e5a76ca88a72108397e804739ad896343801e46355836c2929f3a27cedaed8ce0c4f3b4def76c5812b9336bff95564389438b2ec957d2e9dd55edc9fbd24bbef43dea449123f62e1426397b83cfdb15160eea28bf52311c04961f36f96a3ac142163147d162f9725269193ed174bc771eadaf471347c8e9e7ca5810cde01c83650041af602853c079965bc7bdb674501a00bce0a81ca1cd05726e5f1fe0f0d066e15d9753ece5676d764a1b3e8266d6aa97785b7938f459506c8d71d067152f4fd79d8db6da8322e2aae4a06dcce8569e39bd955325fe780143dac613fd6147b062a8bd567d93a3d73e4f4949699a114484e758e4a29371587a08c0b188db4c9d661fe1afaa5b05260d42e9229f9f973fd96fb8407cf3a77b7e96ff29952a16673c5ff7d5721a52cdd0881ff6ae5c335cfba27362387da9c350450f63154c7676a8fd68759a3fdc4e73a4062792cce00d631c2bbd81f93e25fbbcd5d3282d54df1cc0dbb8fffa2d4727fd8ff612cb711536403c5ca9d20f2d69715248e5ed3d1bfabf721d52517118735f6bafe8bf17bec04a7da805d10e81b3564c871ec16b14975f44a27921d2b7cc41aca148fa9ada39d7bff1b369b3851930b41ec81160866dbbb6863ccd4873c9d23ec01348ba88c56088f072aa39b9aec760dc1d49acd14c4837cfe6daabe6fef2f64aa6f1915e5eff15a3e31637cb840aaf949d3d996faa4d789fd1f141001d450d22acba46de7a0a62ba2fd25353707126a2fea4fd55b310e63d94b8fa801deaf178adc5c749c52b39df05ec38efbe4b9b9c75e411d4118b87d74d3355546698052420101ff6c0492fc425d621b899f83fab4dc5307de45196e6d297976fd5ec9d2627981d90c77afa7537cba9abcadb9824d28c5c3e8507d4950764015966b7168c888237ac323ab9bacaace0aa324be9bb41f8b17433b6697eab07bf42d1ef045d8310bd8727f2979c26fde7ba93273df44df31432d5458a434d40e80830f9e5acbb6b898b7e5842a38c56754632fdaa7e5cf00f7bfb5149a17702ead4aee8da72abbf423b +expected_result = pass +expected_shared_secret = 3871c9637cbea04a2ccd3b62c9399b0a7277a31caba8a8f015d59b0fed845bb1 + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +private_key = f4d14a47f661de38531169cb1b05ca73a3527e599197570adecc4d6d6bb1f9ca0284480a21d57269517f222c9208aa0d021a0f8df20b39682cacb0472d776ce98442feb4a0b5148e62f26bcbc018e0556912f2a847fa8fd3bac8eeab94fa5619e9c1274423aa34056676658af6505445d0347b8554dfb1b61fe59cb3c696367a1cfaa87d47639d311476ac4b859bf2ae8fa86eb042ac5bb97c6e2a5c9c8b0854f73b33cb6f3f029dad0877e79909c4c5a4d4b77b2b0c8bb20540b72494815521d2737e709162d01b7bf324068453b16fe187631aac701551f2a1cc88d1b31efc00ca79ce7a8703fd098570fa2977399b49a59d97c8ccdab74e98e1995aa1c31feca0a46a7b6d855e53e419a814cd0a9682e14c74b80b995907b4735858ea897ee09c9f1f868cc4d9c96e331480e323b627252764039cd354c59679f6d8a56acc5179e9529e481c87603216a74f31e9ace3616ed4567662d7be4b18c0e82b949109793cfc1e722ba85b521d4e68a01816ba5b44bfb4e853cb5b70adb2748270139fe53968303720f72f7d2217e805ab0bfa5f9116a01af1448718155f277f2143a112babdbc211e0cd47ec7d169707c2c4156097a8b02c48a6029dc619ef98a669b555e1741ee6c659fd57856e9214187b51b0361f6bcc1c0f99ede6b5d0c394b1b23641d5c611b588e39103ed9c50843b0630035b868052493800053eba364d95900eba7b0a7088f2629b859c58b7534fd6483911caafdec3126bc0d10a526bd5abe2737c29636383622a2739c8450ac75b029847b23c85ad1624608576772b98f356b34a08012d36c8482c11db931b22a914ddacb9f02877ee00f57f022f6d9543dc3045a304e9305b8499baa9346b42f3889554056698a784d42575c01634175a659e26fb085b83c167fdc30ba62011db428beaf78710f7a659cb5320f25b1fa58618a991b049b7090065367370f3124aa7de80d666b9c6b399013965c2c9b60a89197cc8706e6320c220cc148b60878746392f6b64c6a69092074606617e797a9bcd5588d602ca9f23c5d017aa460add3a95f11e89c8ea3408527c9ce22c3478771e2f15c94962e6200501bb90320cb6a0eabc78fa97f2d69c5a7a00b81db6b2a77a2b99cb1b0598af4bc5da77623fb5a2d3d1709afe65521c5324df95e40d6c20189a4cf80162737801c48c1d4b253a7741dae446162d6a2457574969105e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9c615b63311756d79efa6957766a5de25b89af140a096ca145988e6582bdf1b590c8689a366b9b4e2877c2b5c5a33320d3d532e3958465c9586f604f4f800952eb5f96d73b6287bcead21f7b8863088728ff160d1ab7b3ca594ecee60a8b741903e4892f6154d6356bc308bacb17067772580af8a1cf5157ccdb86aa642b7da9a6a583508d18773b307b2b0ca3a1cc89ff531e0df13948c288fa4aa6d3001c592879649c72450202e39c5f837051db1314be4a25a13a6a00537c20ab5acdc6be15562b1027056bbcb63d6c8227683480b6bdb83c5a74f31b0d1ab84d129d4a883e2cf48ac96ac9aee856a331a5b8a0504a461daef078d3d916f962a9f9a82fe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a3701982fcccc93353b0387df0671abd2140dc9555b8d98251924fb77570aad8737b12533ea4bee7326761e86986273bbbd447e47119b3eca4b7f565de6c0ef8494048a08967cc17ca4231c433864cc961f6193774494aac460f23d978f4267aad92b66678b560dc50c5e797bfd407b5b89b83aa1023a3046d098d939b3974c6626fdb5d4df84b7a3a6d63727ae028560fd79995e6c310cc8b6f33a3f441aba1ba3f44714975b3c3c299aeea9a714058ac74f1334e8c011a748485289af49542df7c2ab7830a3f519c41612f3066b24d594322913e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcc9924dfbb3b052622a15bcf0dc7911d148028c8a8cb574334010e222abf06fba5ce5022da143e5985c7cf277e5db727f6b07f2d8034e033a25b0b1aa9d180f4d403b7072f87c694a5962be49938783613fce30e8bfc204800bcb45c5faba48968c95199297626eac6f4c1099c903a24ab54251c353016418ca774c52294a001c2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43af581c2fec9055830b38cb68fb506aa927443b1afd1b2b6faa6f92a325985c6ce8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = ddfc5b0084ba9e5ca50279df6bc37a9c2390c2762ecbf49be1e050f52bf52c56b6b1aed384ed56bcd8a340f880568a8b16f19e61e355e084bdb5f88631afd27264f1782e05a77c39a2e6e761ca50d093c6666fed23607a62293f3d4b73272c9c7c6ca1457572d8643dadcd420c62d94212aad6db3d5742bacf266569ac74783febf0de88106490251b53aae3a809eae2cfda87bccbbcb99d15c4d4b59f91e926818fef5827241c97b5b70820c701507ff9b7409ce1057f0f78eaa743807a1003fcf20847b63ef101754fcd280ded48ee34da0affb3b8d53d5754875cb10fe38cfae39761348d9bf94b8b6031dde2f04955b27cebc5c934f3377964f64114b92157849be5ae0d88c9fc5130950738e802918caadedd661e807a12b4961f9b58ff7992856aff40af139fe660455f4e7781bfd51cc0391b4b865191cc946cd5f9db076bedee9b04ed9258616847f3b3ffb64dac4c786fa0d069f600ce60d2b0efd796a09bca4e2e0b7d4599adec6771e31113b534e36ceb20c351525ba0d2296e0eedec74e3c6d622a3b823c6e5f39710997ed4cdb3097421d6033ac3907485032d84624bc89cab9507bf824b9396137962018bce76e1741e45a27cb842fd74020198ae5733d1362b43d6fef638422cac4d825f897037eb796426c63d17fc29d2c0dc3666c51c98d4a9c54799f06dfdbd437e389c0022001525d4b2e237da73b95ce62fd9dd06856ad96fd04229ae243b4cbc10cbdccc9d620b51ddd022cb0135dad1d671541ed0c74aee1280a97cba74ce3079e9364bcc9ac1b459e141d5b1f5945943a2f8df962221d263fd985f3e25b01d8f9e93d32cbbb0216dd0a1dc44dbfaac43b1c49b3a942f1e68b73dc4f92ed6a3e3802183d2c386519830876728cf959cc1c7a058cfc7df27f3567f664488b84734ce660461565ba5c4fd0b5e7cb111f0ec33ea8c99626e7821b4991fa9a48d2c0223c740131600e288908059dcce70ed14f1970328e09bb32f2eb16fe729c4e850063a5b987702097d8be6d4e91193700caff28bc6e3c73ba6e8a5e5779f8e82067456b2b3c1ccaa2521f9535ce401 +expected_result = pass +expected_shared_secret = 3775b12681d854b7ff2eec05cd4ac2db91bf06f3c14db2eb35287129a960ab03 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +private_key = 7b174b53307018768556cb04e6621bcd7558aa9c7c9ef9022b561c321a4d1be7b459826a86513bb12873fcbb616323cb1cc83ba8b6bd6de7432fbcc73d7c12b4a76ac59c00bdc431c071993cd32d63c66636337fa8f88697b63acf4a92c6eab4aec503cb352b0e40c2f0920dc94909bdc7b4b26a3826cc8bd03a49481c684fd65348a291379982a0f73e78b59ffc86a1e2b3a79f4a038205ab0c5b705e523b01e022f8a54e2db0b353241b5eaa4e8299ca1b372b3ec10bb128363bf291cf99bc12008bdfec24db711d71f56bd2cc55fdbc223042931fcc51d6d7270d6943d3fc29e44433afb0963bc56bdbd9be6d2a2f28380f2cd420ab844ef32c1e94c00e3cf8c88995ad8d234ad13b2cf45901369835e31b35595c9ea9b8338b125bc2179523328d3be672ec0625280bbfa10814a5ac707f811df3c79ab6966e5bbb8a93b6abaf389bd9a859564c1c223334da1c9cd264cae9b43990209af29c5d5a943de84461c1eb34ddf54339770c38c1b21b5abf691c3540884845d736a5728eb3226a312520d9a51a026a7952457e0f325bdba82a7faabb1d977906b8cb8e91b0034ab07b656944d416a5e9a779c0563f082e604cc673e1478fd5c0ed528373bc5d59394082160414c16fdaf8742a91ac935c322d0668490ba1099976bf908214674b6d7083da2433abb63a53403e35009d8c79ccb88c6704d5a3085bb2fd8c57093c083aa55636410ffc1b6b635b2a8b65a3ad83550fa83a7b1297ca7b1940758515eb115d7cc96e34415996a875d9bdbb0117df107d8f4375e14a835ffb89aed34da8d33dc1a08e7f103c520c48ec3b651ad79198c354330701c04c5878365abad936f8163c7f094a63c43fb793ad98750f0ea9ac18d0bc503b9ff198086e070c76c202882716920c31deab30dbb1c439a03931a6b855ba96cef757460776e8e42b4f86848b019e83667fdb97692b1578662a8d27b8944350864c016275a01062e6924b5b2a4d4454c38b6ebe471cc55981b6085e7f65b3bc6bacb52caa69f3b8e47b6ab0f413d8d138e5c73c89400a9ef7bfa5878155dc6e83b57ad8741f525750707a4731f46a6d2c59e27c013d7834f126719c302c7af3609bd0457173850bac49581557700cc0dcf034aff6b36c2a53a5e8580db101e0f718898cc8cf216fbbe1bc78c8984130c2ea921d872224572ac3dfd0ad0ca32a1075c9c2a97c41635ac9dc7aa2d014dc460115c93fc427c155726830b9cadcd8523c8722c3e4639d83c5898054fc68ca8588c55d89640e5cba32fc3f5cb283f2f9032f2c8dcf3847ee1b67ca698292a99348d194df068db0d46d992aa59a83c08b24017ca1048f77532f22039f92bea7139f1dbba914b10dd27abcd6912a8fdab2ac5c68646ab880554b5512459efac549950270e825e39670f06288a97a5e36a31e61a5257a0534e06c1418593b7e844f6381bf1ff5916be88c697c6a6c1c0b42ca1daba6300106784f125e7fc80a37f08a6889771461ad90938894a54914e2cf759c60b3dca1b86abecad16efed660e4422cae131f827b14b2bc4a7552073ab069365bcec3d3a41b22323fa827ad50793b3186c6a0a7e3b007c892868f18bd62105e220517c0db3057f77a3be29f8e2276a49416737c9990216c2eea6fffa7b4bdc6603aa400cb5675aa5a78458a498056511ad42b8550aecdc4940ab1c1739c33fd07bafbb287ae595fcaca6ea4bc3fa708ad3ff8abb4126d6aa9a4d9572b74cc5567b55412e901ca0c4d5eeb4c9683131522917f0a7eaf56b20d1177b448878b657700ad885cc0134a249970e1ce1ca779196215d104117c3c884c9196f33627d6712a3fc234fe171db342a24577a55c5c68e3a2350e41c14c701b1b01a39d2850b69274b2ca3a20ea2cb444294ea73042939a5a1a9a905856876b0b0e3492b6a328b40a949f1865f54558aa6263789093dea2ae2e8631e2ca5cd2662583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89d51669947f1ab44f9aba94bb239264a0c6ccaa64c0e2b3fe6212924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c4471a36aecaf3868b4b8f034a756020864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d80f31bd314cfc85416b2b2a1973714ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28f12f3ecad62bd327f1c44ae86c0be6e7f15112b7f6f6d5ec7b13f4dfab718965812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = 086277a8a542fd9b516d003d08eb96ad496fcbbc9e55b05eae42c95787402727d46c5e9f916bf992687844a4dc5d82e71401a36822009b0601a9fd396891a6c15c89c638afba7594b8e2ca0b8f26775ade14a1037d868ddc2fd71107932a112772e4c6a83913ccaeafdc4fd809bec26bf3e6e7d7a69be522d9f4e8a265417e36ccb5afcf25387f35fdbcd6170c4d31fa070122e7cdd8dd90fbeb9219db9742191f3bf4c68c95a20bb1d33e2efd99eb2873e98b9fbc6369b9c12ee49c39ea1408bbbba3bc498830a5bae84c72cd18034c27d99e1fd40a5a514b0423355d474b2cd0b7e97a7dfed1ec618524eb2836ed0883f4ed5d2e3a202d1cd2e5a27c6e59d4fa1c79bbfb2c0c4c74c9d515a4960eb468a6ed5519e1ae993ddc86aef51bb20639d063aa99e9e7265996ccfaa700b46c6871f1d40367efe07cf5383b97f14a1e408bbcf7f77aa19d1a5b004956ca61d29bd8d30a1419d2d831fe039ac0d750843c1348c7ce4d222dc4be92d6ff20ccb7cbe28d225575b9b7c1e26127fa6d367225b7a491f34313f73b76300ae25a4b3abf7ea7bcf692bb488daef093a1c91e4159ce21559495cc2bb730e1a9efbfdf7f26c1d2bc55c5d89dcf74e0310f2de14a1499282f9b32f373fb1214074685bbe5a256a083e8c06b221a0d16a9e31b38ae7733ad9644e70fafb18391486e1cb7cf9810fcfa276045863cc5e45bb2e9ea49dd7659fe26be983f6b984dd9c0163a2efcff698fbaa172a180452b21aca550e93a20e049de89a284ecc30eb45068652717f143bf61b5e7a10c35001431470d0966445cd9c118135b29a7aa442809e40ad21d7e52b040a0086e6c99cc65f18cac115fe47834d45521ca6e54f0cab4200ea72319f9c916ba9fd39ef1c404c34c2ae14b2c7f407e099ae8056f4faba6d0b95250cdcc8d7d55d417a8b666fe2b7190c7b192dce117866e8b5c75a07d387455cd195e8963032afab2672d818332c81910eff521a0e1a4415ef86241b14273566afaa97b3e877e0c47589e831bf4783c78b07062b4d523702666fd8f2f7ff509560f1d43cc5fc63b9753e3059878e16d +expected_result = pass +expected_shared_secret = 87662dcdee8b176e2dc60d079be188f63501274bde0829f3595c99d1e564c2d0 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +private_key = 96a50005840f5a5a0e8b1083a57c8402a2cfe227ceea80b5d9e175ae3131eb8bafd291a63e01047fb889d2043a0e814dd55594f4274bfd73bf1828bdef5a97c057091e480f3d6a3723467b989b635a7a70617647eb2060e6158a9dac8b40263062d3975bf88b24a1902ad9c72bfc7d6b69adf340cd2691119bdc67d8f5b28fa8894418ab9a0a97d9e9bd40c5741ae0be90735c1c2c140c8461ff507eac55bb16e65e93132105c46575006130c67b500030fe11be78e4a4bee364bd21041a68a676b398c1237a6864b494c383adb4a1bf369e606894be6917cf614934e145f961b3388ac3de939a309373e47a7134b57cdd5915ae98c842b936a1660187427fe771606be8421ed11412f020e722a3f51b6847391c6d77a100fd484241209efc778496236acbb8a00910820154c77916b8b0978ae3193b1aab565a2bd9790cbeb3293e4910d2631672036e60c6806aa676b8866d3284c4b3b411e7d2b4a6a75d50675529e1b4edfb5365b999711763800bba82f66e8f6712ca652cfe0190b46c377d7bb26fcb7f32160cd031c862cc9a0233578b2bb372cb231e0536d3c88f46aba8bed1a4cb6338efd847d2f5c9605359fc2a830476a027d477324a8b15586c2fc2a942b4ce340088e7e8808c9c97e2b91d9e25417404755cc71caec7c5d82c35b3202008c4221cabc0c83084f4b98b0941019be55b4a874b61e20a75ba25ab9baf806b52c52116d9d17d586289cbd40d7bc42dcb672e76382c420336d88b9c3ed690458793c6126a8c20822a7b1591a27a0de3c0ceba443ee754829a471304cc985013eeb453d7b522b365c32d33baa2d362306819e6abac03a0074b632953155a2250131af6bf6fe910d6a75fae56bc75485d247c5278fc50d5465aa67500584bc6fce25eb3b401eee5365d7c6d6bcc500c99c343476bc99cc433c173d6e74ea054adbedc8daa57a6b8a77ce5e105e759057f20a7a02cb894ec8d72424b16d8925f118375dbbb847393712a4d9c64c5f997636aec817fe593b1754bc8f2ac7afa5a6dfa2580513536541e6ccca60bd7a397b49dd34a8f352882612cc39683cf8f31aa78a9043268c7e25b0c43469ed0a535bb9a8d4ecc65c3cbb32bf2361838a8358b2edc1a1ea2fb66cae5070a30080a84a9ff81b3b020ab1df4548e510f03b13cecd4aa32f380172ca85cc8962acb7a51619632b53bf828a7ccec1b65c72fa0f814cd2c101690b769e452e34993b0a33978c19da61b0061f24661f20ea6a566b1d7aeacda859e52cbf32aacbd1b7e1e66b138d2cc613a26996b6ec8d89c63a34a44abcb70772083140fd6519eef107f91983f2e4557a7e21c62179674031b9e7c2edd845188c12b4745b7a68308e1e19a86968a4ca001268132e493a79595989e7b55a9f2ba83ac40c89cc752a97d6d6b6982e1033298445384c5fd04ccc06692cee0007a8481316bc02a724491e469ed7a2f1b809715da8cd130a2cf4c200b168ff33181430cbb5af152c0510e46b9aa8d83060648c2ecfb74840c5110004c25d9164e1a3dd9e181216901b1169a9ae3a760d1ab96c7bfe405c657a2cc1e62c65d99aef490892e96bd6ac08d9421975af70b16d3a12f898528130f30ba4b9b513bf42b2f5be08264a985b2ca61998a2a30030e3bd51200ccb3d0f66d08a677f6236bb951150e29531ec278f3d013bfd0afa81c009d0c78537c62557b7c5c930614e14d9600a9e8ac38f44761460666d4701782390552693b83736e3e340d5671ce0c5128cc991a984630f1f3349fd80e7756abed753226b456c2968efde96de0a924b926ab75bccec5e69b24a42aa34c110d75ab27495c5d4cab88b1afd49a2fe5c02acf3578fa4664934a1049fa7d89f666e2dc77165498ef61c575b4156ff7c2d7aba435870999d62ae36a6cebc66d04ac54bf4cae14c0ae89aabe90f3c397ebcfe69aae0618475e5512d5534f85f711a20a9699c620181acd1162b06e990096f7799f836771a05e56c99d3402599e713fd0b44be0db130ac3079c583bc0ca266a548da0895c1a3c3d1c28385537465df75b055106a215309309820813b3b8f7895d53611061bf796b47ce1019e3aa09a013764ea8ae0573ca62818acd346fe3012319db7d351c073d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132604cae8b58e0434fb1475312355a8b40145043bed4b269aaddd654d2e562324bc78e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 8e88de0e5b03a5b2356db29ecc828f4ab4dbad32607b6ff0d052eb16aad666d0e1865bc841b8159af2ee85a5bef94f89548f5a3fadd8f7b6c84fa4597f7b2f01ca125beb86d6cd34fa5cb141127831ad2c98e08431102cd332fe1fd9843ebda0fccdd5c116d3367b08229fcd397e7ff2bf7fe4013975c306415b77656a733088648e93ce6813c314b7d001824ae7a5be1c3bfa58453a5f9d9e13782b36db6e3d2489b1349feea7d960f53cd8248d22ab4827bd7fc5d9ebc972939148ef7d94fdab15d89c1fb6a0e6d5f706377dc1538ac6a45566893b5f9aef83f1d24f6fc0ef170b2e33fc712f02ddb6c39e9c4bb0f4543a14b3fa5436b6a6027b6287c3e0e6bf5cea841649eb652297da5772937cfc2f98c8d3b053318cf9218f4ca4c7cdcdddf35d6673a7daabea5a087ad0c78322f86e140f030a0d6b7c745dc632ac5c158074db2da6b4015af685ccf27d8ef7da7e9404f2a885e39ace3ec7f23d8fb02104d8ba46804756dd69520d65b0e9bb0fc1241774e36f76434179047533d5f57eacd067ee85b20263df354006a01ae38e0498b9565614a35fcbadf2f29775c4e6db4f9eb329e9e7e04457ab78af06fb8a60d5914525ec051338cc877b445605a0d8e28d19b16512cc06509253071d6b2d74e328c20e2eafd17e9b8724f51b105f433ebb269a7d94f2750e9cdecd4122bcabbb9636b4a5fd9326f2fb3cea6bbaf0f78deb4f2b33f32278ad75a9c77d84b97865e09595d1acaec269c3a2bbfaefe9dc220083344fb65090e982e49307d525b796f30d27dd3a7a04388167489c9d26bab2589a27f3627b5f97a7e96f56748c75aa60bdaadcd1de91c0db8e7ee5b754c22ad491b7a3c218858506f8e959def527cac09b9208741aef20f1f8ef2dfaa7ca9e7c43c27a526872395a808449ee447cc7c71bd0fa941f86063ac84e6549eeaf90b0cd60b6bc1d932356442a26c07431b490cf53a95d309ffaccd68e3d47e6b9bc2f4be8313adf1ccf2b8fe6fb5eca852de15bfa513c3407ea996f887ec9b744e5e9a0a6a140f6cc7a82141b40a10d094a45268c8ac52af072170f7e2e5c03 +expected_result = pass +expected_shared_secret = c5676cf0cc81871d677bd7f5982e6493aa3ea4dffbb30dbaf59e90e4977d2f12 + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +private_key = f8d65394e770f5185b92393b4f673a030a0740d3ab2ebb263f7561f1ec5b91160832bbc444834f67ac57af33abbce75f31a8bea234af52665997137caad53ea16721e26172d05930896c9b6034680bfb74af68969c8c51dd983a778040fc7c8a14ea792db54d380cba826cb772a654a496ccd3e983642997ea9253c15c958ac162a6ab5a80956ce4e3be95fc9c06a98cabf235c35475fb58ac9e3641c208a0bb481f6c722c0d5b983d8b1f792b71cda7a69db9c0c00ab4c0f0375da298078417a618065f808419180961aa5144d66082b2aaeef26b8b55b14bc395a821c2e87805afc07bdf91874eabaccee0448cdb208f139a0f4c4b2471beae5597789c1f89a988263b8aae549bc13218eb64a5b0ea62a39b0927667f302a277c769cc0e28823817e32793350a83f9b8b2a3ac8153ce6843d65a7fcc75493d414f7c98ce4c583cb66cbf701cceee96771d2c5f94323ae2365be9ab783365b2d5c97a318cd7a4788abd4bafd31a3f19363d4e5bbfc996c2dc7b82fb98ba18070d4b014ee1854c12250b3d18157112838a58e005b3c9ac59fc8a65bd1f281fe7053d3664585b69015f74b16187a5d19cd26c503d0b2bc3ae32799d97440bb3b60c40f0f7c4506c56ff95513ef8b2b7df33a4d3a1388cc5feb44aa208aad6cc972859b15e10541ae29c2234a904f6c6a8cd449c5b86897ec5978b4cd84f189d63a072c7ba846a0884db14826743921e13ea5e105736c2f84c50dde9738a4e9588d22b296fb13d57c4347868c7e4394b5f76af2c18a90dc7491d6a5d510a75a198848737b7ef45970387a29b51c45b5623e9b4eb2a3414a1c285bc866729a98fcc08e3dd31567d63e7c57437f5a90f9ec35fcd74050858825781cc6d5a2ad5608a2d063c8cc369e6a7c0f7c7eb27ac433883a5946acdba84fc32872cf689fcfb50ba6e894185c973c196ddcba52252948c7e159114a23a242b2f5d0996edb7f2cb93408b9cbe68298f8455af632275202c6b2e1370c5c9d1f6403c1a7832343ac2e524709268f06eacd753250486025b691b9235bb2cbe833e0b6086c9959f716b9a8d30cb840b06693535cba8a70d2410f72cf1b69ca2951579da03b23e997146bb3519c521ff325f9f1a1c1d506cf42079f694f0340abda4806719b8df468a53a92b5bb2629ad0b54799103c0c17936565e30d9272f44a657f190cb92887d4612a517a35e87b24fd314dbe32d99c7758e5458038140f1ca660eb8c1e813822f52865f6671cad74ff478514f87afbc4187c0c12a4f388a63613d592c1dce237d13a01ee6db54013590dd91078b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5b9d044a3950377c2ce8a010c9f59ab7e27aadc49baf10521d7b11d3ed707ca2b377912c131484c5e94cacaf88595c711599c081808681c6609227648033011fed686c9a2121e724346426108a5c514306717224f5928063549b268d87ddd91a79ccbc42f884f39d097e6246266173a79c68896235619928faa907d93226db05157319456dd06564f364e8ab68aa1fca43bc419425160a6960ffef152ffb85f24358d2bf3c375888fe8f7245225a27bd710efba2ff73901c1f080f6064c44ec982716b0fc7a88aa41532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe930915d7751fc7b1094d4757fb0baf1aba40d0d443f60cae0d5b19bc4c705567a602402d18c546ad9b8cac337ccf4a0c1a23467e75ca55090ab4435446b9737902a73c69cc86d050a8c11fa928257c5774d3f74547016995633f7c564dd4c962f9865fe78347d8d0a5eb449f6a046bfd6028fb1185ffc86e722239cd3bb19fcc117c34658f00b10914989cc24545e615fa824742a1814d7642ddd21e2a89194d13270835799e23ce97f25ca7bb82bf096358916d73c73259853c37d814425b37e9c67f5630b408785290934a70448132c653afec782a478920a085c46823b960ad795674b937053543b80b98c52fa29961380a8360034674852d151a8c1393fd0c97a0b94695b8adc652ad1d3c69764387e75b1038921fd53171fd43657fba4c919411161004b4db2e079541af110e166ccdf2b77a8709028b18a96e015f13fa6142c63e71f73236d227e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2cb899475c1802b1dd76a9783d93b4225dc558eea558ddc598cdc45a898b7bbfb38aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = f9381d44768a327c751ad39b14ac7ac1d1f215a959bb34d8e1f008911d7c66ca6e9a8657c6443eb4141a46a52ecbf354812128354b697394d97eb5a7477485a676a0fd500ae629b3817ed80920f3cd1a8c4de779d29c2c814136c4cba979d95f2368e015b2480b55de69e5e3d4e58583809cfaa228c7f0a07fb3ecd9c3380cc3adecdec3f7d502f20baae95a4d3a5e13b2719cacf76b2fa992489164e4f9abfd3ad91c795efe5783a336e988995b12f05f8c9a8f199fdbb7790a80eef844114b8f4eb4c2788e25750cb103baf4e02a4d75d1e28e9e39849d2177a008cbfd14ddc4aac135203938e4c058b5864cdec6f4630f698e4982e25100a7de03a7a165b36c20b25a2406db953670785493ac8556e2930bc0005d179fb1cc274eecac96e64768729870bdb0af25a2bf01025222c48d91feb647108e624d075c8f83d762f3ec7097f84479d6f6b052ef975ae641ebd7844b4c525dd05ca9b4fb1f4cc18846935ddd74826a3745e34f3bf0d74f13fe0b497aa98fdaa59b94b60132537a943444cfe213900227ad73c8578030d9c6efa96e863480c3cd2cbf1976134c8b6309b996c18ad1fc84f4a98c5f3db36204c7b178557b0e5c99b0403e4d6e2dac218c925572d8bf7bf33e463fb2c88d24deb81342f9a19172b2f34fc9c86f4e81dc298e35199329806062b916760fe4cc9695d0993d31b1e8fefc67ad4e423dacf63695c13a0388e0601e34052d6acf7bcf7a7f2adb76402c324cb7ac3173ee51ff41f14b9d95fe71e6afa49fde9ddb9ef2b308c3a546c04c345dc0fd2fd8badf779e57490e6e8b25c678c5f1b001044d5d7637f629301843519b4196ea99c9151abc30943b13ea9d9c8ea8f5bd15008c8fd36bbf9845ffd90fb5d8954ea8edb10e53ebf78546397edf86d354adb3fcd3941569ae52d86e07223f2731b6f104edc3fe83c9eb17f1ab4bca27ec1601d45ac2c464f573aeb142846c28dd7f734965a8688b8d2334080634d344cc07bf7767c3d2dcc3e0b72d3e4901f5d3bdb490f1fa8a399e3e53eb3e487452072133613e6c1a0d932b5942c4512e019ada64d3dba28b +expected_result = pass +expected_shared_secret = c5b03a417c10715a53f3a1efc044a81e266b40a1b16c87aa1f754146ac39b80e + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +private_key = 5b013906459962532f06782c95fb2823a230d9610966b0a13d245562e73716a0216f566c8615848b7a481b405314c79cb5b8727408310a447e58d12a9ba69831c5a32828621fda3424b9cab229aa50716cb4b0499c5a4041eb090205131baace04c31f0467b80a663f74ac1e51607fd5d4c8d3b02d8706afbf83b4db3c8f6a72a8a61c9056279ec64c3de62378d01c2b7352357675bfa3b659f03314598611e9437e73bc0d7a7b15e9076213c77d08478d00e10fc15c1a2cb37e3b89930c9342605515b3c88b8a06062a372f8a6448a984aaf45168d891c5f0f4ce5330152459a82fa92c4127a5313b421ac4693b0bbc1d5bbf49d16a69e9482a37c42b07432fe405c218a08a5a22f00a443f258fe738cd8e54626324c6026993052439a0c47e3bc4849216c3340a7621826a778623866849b250bf25a6a28ec6a7f69962f3352bdb216d306423406c946f9b2bb211052706bc6a649dfea411e2061c9f21441ddc8628b69c4529764ae16bea89470f8407faa00bae8715314366bcb797887bcfc57c2cded27cd8089ab564576be95e014330c804673507899e7c6c98441bed4258f439c264c87becf0418fbc9fe87338e909bf3a1897c8c151b0305e1729000e93b92b40a658b871e0da0827a93d39a5a0f6950049f315fcc09843673d3efc140f9551057b5a9fc55c9fb7839084852d677c8dc35e01f7a3f45a3a61c28a38a685b330b8e0675abe736214661dc59409e31b711a6c6392ac1d50ea9da3c845ad678f38b1ca8e313d4819c75c08231ff38ba0e4c33d69286880413d5c77f95b52d54045b44b5c0c453c5c6007a8a561810289b8d192cb5846ac273e4e7420e96c6a8ef78b89842fae3a365b426c99c49acbe24a86bb7cc89759abc94e727b1ba55a5a539c2ec4879e3c040d3d5808ac05b794a46e20f67a5622235e11773b991f9ec55ac598bcfc365b1201008bf0caa360b1ce7121c9304f4629bc65041a6902390f8a5c76d6ce4fb6b357020340327b861b3148743a4eb455b66762e499694f558f19765d6db32b7b075ff6a6c3f49622ec482688964804a6158fa08be2873c3883135665ac3d6b0e710204689c2616487bf51295c5010347b4663b914bef02791a147c20574f1dbc7065e7b2a930236a99304b6529e95b9eadea48fa5490fcb8c59e6b5fbfe5522bc057e3f9aab8e7aca680cd620310a26bb4309a2f2c4c56226114f8ab63de71b74971197d6a52308910188b603ac8523493a751a1cdfd441259b03f5d140f862cad7a794307aa31cfc4624f2a740552266b22240e631638c2c17492adede14997d95e4890002110ce40fa83f416a2ed06806cfcc49bc9a1599512db09362aa01650f7cf56290d2e85424812cbc009afd5520da63b30dd814e25bb1f974b7f3f77c38c638e1943beeba234736a029342a13aac8d21da0747f41b217159869bbda51885ea9b0a99abac1b740ebf40cadc78a6fbe93076e214031264275c3d56486efdc00e9f1ab1d3bc98963c908ad13268d9b068cc2ad5c36f68a11281da7b2c325509383e71d098c22a1de3c3065f1082087338b3ab021b0a3fb2b5cbd1b29f7b3b7d897c8c874b9d71d34dd60bb686b99c82750527704a53c737b157a6c98a148ad0727d13cf770b038e9a275e568b19cc2bad360c958c54900c59b4bb69b8341362ac7fb589ca96f563de54a46d3c02c475788351c5ffccbda1998a87d7a27301095ac8577cb84c0a4a244cd8c544f4bc7b68cf02a99d9af90bbb42a1ce63740ea784e665882c6aa1ae151501e560ebe9116fa9cdfd749153b7310e1583feebc2856384923200a811b2c0f71c23076de6590a89b6b6114316eaf80c90480c1ec1c131990637765fb17c2b0cb1ca1c03a3461bc2c8534b35493b3dd3c8d7b6816d8127d192a6f7d79e805283e3e882e8120aad321bb6a197fc60cf443ace984510bc59c8ba832699c8b145bacbc090965ed08785f72d24f4b9ba70c41ea79c91591b2295cc5903b29e04bcf3566c9b7c001ada05744605f1845f3e13bf9f22744659b2913b2489b073b6f01765c756aa494a41e44b599719ef5968853c0896425085d75cbaf73abe304025ca6006858ee7c1c9cf0067b576c168651e3fdc9b9d978cb1c62354094faca0a4adb426c157166f08034cd4025a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d1a7e0760c345cb5875303e20e4c72076c794e56ab75231750a190b45f374d979a2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = c09c79e80d5fd851248fadb02c75d28926a95c17103cfdb6c190b9c97b77f128dcbed92b368b8610d7644d947f834fedbc5f53a1a40a421870229aa8807ea8e407a099b9eb10727fc7856eb275f18c153abfc89aa426592d159952cc6c4ccdd6b45e1f80de249a42728da33aca44b5868bc7bef745da90e297cdc7156be96de11ea7e699b24e62711e20d19f3b7cfdca8a2e1f09284fc3725973a0f60afe3eb0928bac1ff71b87985af10c522d381a381a54c8c33e3f8f639048391ee7a49806e68e327c5451e5435643f6260f5120260019b4240211929ccc9f243ff78e6b2c5ac80c0ba4d0ce6f2f8b43a44da5056c12e42aa920a819e0bd485e24db4ce6046a4477381bc71085f3fc45c1c0dd95dcbbdccabf7b17315efa3409646911ce8eacddca65b569ddd37005688c70d8f3d2478c7cb223bdfcbc33b98e88a92a7411075a225521ed126c3d708e5b4f4dae946931be4d33b9b6c1dcf0f06b74a71b3e4c7e776df38263b9cd3cc766dcc1bca5ab2c80af0b29277fceee8104afc8d45a68b84b014e7fe301646b0dcc1464bbc09c316b1b3731d85bf1df830b201456d4b7dd7f09809855d98854fd04602417ecf0603290ee6dd9d000e4dedec2c2f169fe46fec554c95d49f17713cb0e9023b2028f2a1f483ff3249d2627a41183f8c09072b3b35792565fef60f784b432266d8d6862b637a2d1d3417b2d4473c0d6311a9814471b28392c742148835350f07c4bff215e1c953b4915e39cc2836ba217adeeb9de4e5fec5c41fa292b0d8c09013d7e9aa61ff33d6e5dd50982b09c0aaafc07dbb7a24ad575659b036097c6a1cdb0783e4a8f33cbe999c188d07824aa0411d989dd9e9d490d9fb0b554a990da565df181a53459ded33a53f8a80484e91a136e02534e80a05c8fbe2d14b606ba681989f436ca2de0b75015fe2e461188ee8fc1623916349f37dd8199a50ea89e134f999de57dd76249a3476bd9f2bc8ce2dc898c7528f8e4ce77f21e84bdcf3e68dc751a660f72123f1658dfbad7627ae64c2d39e6b09a63de0f5e2423d7bcb520ec9c128d86a6e01cb712f524cd7b16d1 +expected_result = pass +expected_shared_secret = 38daf9348e4d89149e4968131370ce3d38a4028727fb85d27f87a95b341340fd + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +private_key = 72a882d4848542a06f83c28df39c2384c2c86bf97fe18255aafabaea22a366da3e6de5b1518465ec60a5d0754fc4c19bea36b63ee04a25617b3a0358b603998db88c05593a637c232fa0b4e417573ea5afa5036f752a0bd8f123b3287ddec26a98b24a464a64502c92d284a2e22c2a50263872649367d39bf1e315e2fc5668590a534b6ad9d6298edc57e9d008203a9206c3288634ca87ca5b7cb0aadee53ce9d58e8b2b6cf340afcfc73d9791c8c2079f352b5e6f0bc67942b58d1a2661b336c37c3be7418f93bc4205f693ad795bd2b2827bb96dcd66ae82346550228ae5c91c2bb9aef4f81924772855f695929b975f7273d4340020f33aedec90ba0691d9924b84f1ac30e4c34ef0949064892c0abc0b7c54c7b0998be1c48bf09b6df143085400ac96637ce7b6cd32b8fe778d9fb6241ee58704737989c9345e88bd46f96c3f43c6482c9ccc99200ff02a9e4c0a3f81468ff5624a050272591c04d5a44fe79ca2a575c9ca4d629001230482fafc9f3030180cf036a875afa17a979c1b8c835931a86b090de5236365acc6e1282593aca8f74172b03d72a9c58cca346d488127046660bc7936a0a78c209ffdc2cb24a4c9686a988b8437cde043ae34c528698643b916ef7b8d66c77d70c5075b1b2ab0975fba08a6ca8403a753a63dd32f7da15b2de025b015cafa85c0409a5b1113371a11243c4626f74a76f3f62911e8851b265a302a5a48a2a22861864e5c8ab094036338c1b5cc7dafcb5f66e585f6447864e505efc363a939bab445c2007973186143d7f38aea5a00b77213a5e053f6f74e9aa92574051a5b281990531182549371b9610f69a3ef3519d06a764d53102bc68c220145f4072d3ce5c7a8840bbd1c21a3034fe5584fa6191f44128652c73b09868fdc947cd90cb7ff9225be48363437c5c45314a69460c3f55882b352937ca65b344c493263ba7a0d1513796916243700b4faacc36f85872f049b399cad9df55f29e93aa6656c3139773536275de5b52699299a6548d626c0c39141d64889f20013f706966d10b60b9b311c83b69ce9888beb2cc77192a1c73f1f34bce7752afb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afba81681b834d55864f8e240a69067ba1384f9279576110a0809b34c81aa350cae66c535d5f24315fcb30b3469e59c45f44915d9a010e834071a60b4e29001674326e8b556943246365c87d9133a7e68a6f57b63f5b72a94d2545dd682143ca0ec892ca3376ddb188a83b3ca5d31899c5b8a0ce014ddc1bec2988171d7bbec2742feb77e286306d53b687f9c04c45a4eedd1c4dc593067086f1728724c282dc8b94978a67bacda824e6a259e12c44340159510526b6630df44bd4eca50c62b77fba073de86c167e9974316962c6805dffca9f5d4a413cc04da0b4a9bbc3db7eb825d7b1f3f942870c559f900bd0082c13dbb59d68b8b7b84906b4c5e86ac94da520b54a5bea0f51fdd12cf53e90ab317117e320afb377cca024d91685a2371612724208fd02a2240b32349893544535ec21655d398914bc53589b5a6a920dba6b76b125c32611c9db77827132a00651f6bc3394eba975bc40e87c34a696a8ebca0cd356517b4b16f53c99feb517337a8231286a0ece32a9208bf90daac845cabb86c8d61d498543c4ad2325cc82a75a11a9751c6a0d1a7015f74ae1e32485b26372366cc97f42ea0840e20bb54800028e537cbe867aee64a1ed4453d27768a55815557e71a3857012e33172b3a6abc6729b207559899043185919883c9e6f74d1c5414e5728d18785ccaaccb753b61a6518ef57b4546c5261ed80d6262ace4d72f423b15f60312a9352e19e0887e7a131e590cf24b499dfa53ac3c5123240469350e097524263cad98a50e46739bd342bcf5d454df2a82004ac7ca8c23a7b406fd396239f74ab0686141d3ce9aa85efafabe79c1bbe2883efc6b18a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637e0259e485203077a2658a73871b70e28358c94143e78802596a4124b75a2376718b548d8eea706a4a256b297271a2a0afda68030504e5c35f7f4cab2a667897774fdde85e5ae01fec059111a1b1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c817505418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc0f96fb9e146a1c22cc5d23e9108af0dc5e13b7810b8f5598bbd5f8d4b54c8af7df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = a1a2955d5ab07eb09594fc40e3f42f6b9b9972f432df202e36c9d06ae6a5e866e3a8311a128f7d6e2478aeedeb19d43cd3b66d21a4896900bffc09445dd07b6eb7ff69c3e4b44111b8176323952489eb1989a5ace34b7af22b90f2b70b71541ddc796f90e4db332fb5a879564bafa9af37b8f3c12f5212a12a1d960a5d67079691ec1617a3a491ed17cd7d7735b4eeba90424de5187672751b3738223af79c70231f12897e2b6fb924dac07174498737ebfac17af295a56f26ccefb75b34ea5a14f17dcdc8ef9ebea5e6d966c8203310898ecd3955a85bcd1b66c64624dc7f83e487c2209f810f026a9230ea8e0cb577db040fe22e5e94120d40484d6baaf90f000972b1d304dea1f0ab2e964c1d46e28a879ab5aa67d4e4434b787d5b04cfee49e913e793ecd38deed4f234fbab2e984787cc3976cf59b0cff5692c53ff83ea0cbe67e392dc31b906593fd82fc34ce1e26393679fa3a2a53a98760ca751334fee40170b90572a77cbbffe7520809dfd35f3d5a336b2c6ab06bea4ebb15a0b06782da865de8a7b7e7d0b4c533bc8d5808e563db58c3937a783ebb0a89c5b20eaca2b8383b3ad8bf8f69566a017a2e8b49eb25571dadd14e799606f6da308d5d3b951f86536cb50aa0ac17c0b846163dd580144513610754f5f2fdde7cf67fe73e75d763699c4e77c6f5be7eec75af73c1a6bb4bd48bf54855ef6d2ddb82b9a3ccf51341f3a8dd946635b96f2e3f2745f948eadaef103cd69ce5c7c0cd87d9b97356aa7e4788333664222c36d5b1e295aaf26a407a6ee0b80b17c8a9d242afb71340ee78bd13657d915ff8f7bdd0d938d6a09d879af23d4f39c8582f5a0cc6a0cfd6256b53ab0896a03904c9a7cf724f98442e37dd5b28c06bbf0d3b9bfbec38283479f54178c04c3183ab8d1ad2bcb745650bb0f27bdf073a732f6a3e97fe98aee80b50bea056dea21395982641278454327301b79e05aaa6e3667cf4da8b396ff499bbfb3f9e6e338c42a2969992bfc8a3755160a93a73457b0a50b2c8d3cadfd52cf2bda2897a98c9bff35c442ae37bd6c4a4044955b4d9f57a4386c4dd240 +expected_result = pass +expected_shared_secret = 60bc23845c0b116208c0ea02849cea3d8025a7220337c617c4bd304aedcdc1af + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +private_key = 2a0ca3aa8c5b212426e4066cbf85c540177324559cb5e065a31aa5daa69448b5469b24587d6cc2a053abfd4588aa657894592c21aa88c3fcb7fc1a7f5032a786cb121e38b68ec0096e253f3caa94cc6a841867a582a77494dbacd97b8adc66299e54444a2b420303429aa55022c961f0d953d9967cdb9397e6631956e59259164e666cce7d40b98072973755408ff1303d29add7770d6b6cc40297648a66c1e7e253cfd631430baa4a701d8803bb834483eb198bea06aeea9a4c6487199bc5badc3526712282edb173b07830dc26bd796661bc677d73d4ae72a5575ee389bd2ace05561651999fe9326c9109a1726a0ea3354bac66794af387ff097e37b316d079c6f22c8932b8b02f33050d20c03770495636cee8a557add61e45a20702e1a2e04a854338af5fc4478be47271c99c24d79f4a38a560488b624ca0ec5991b141b3e62141c73a457ff5635923c7c7e3522dbc937ae5bfe962c297c1c6fed6bb1c4a7b66d2aefa71b272e74559381e04fa6d795143ab6789c06384b6d22a37da12c2a3ce92ea09b705a0ef61379b98a1714c71fb044f3427cc20110c421207a05cb36aa4477c86732d949b64ccbc8f841089c878491c47940ac61a5920eb23ca823c8f45332e4317bff016147145c299db4e8cea71d000850f113f12e0429f596df9cb4aba2329cae2734b3c4c0b2643f7612f473bc0069199e1f08cb03c2eb8e96d92e6305909be11acb29c399d4bf8b48f5cc47e8973b51454e67aa5578359ff19325efb7493382a41665ba1d168bb01c1577495aaea9ad377252b39402c598c60e2b376010c9711c595f81d652c5c39cc8857b949e51a8939f4548a1959dfa464020bbcf599089ac9058cdc1061aa34c78b16688231d98792ec23063712924581bea2a315841a6a49a09e8d47666a8427c811bb839745c83bae65b154c6463b98448bc638cac1064b03565f295495eb9ca032f778cfba4ade47a906379a457c6231c8ceb3fc42f9175dd50c38323c46b71395c114a3bd1044b6176dd58ac0beeab68dc1ad57f7abc6049a04bca06c9b0c95456b19f0a2b8022412463d20e4054a20774e234119411edbb3515e4c00a4987d491c37b3890db4ab249d28aef2c0cee1768c52b70cee7966b31c58ec975ef8b96dd2e156544a88a9772bfc834d422599b117968b648172b2ace7633ede1624b0a4cd031779040128c0e94332b03a798579206873b5583ca9c6be34632fddcc223a76c415e262ec8831fe32225ab2b484758728182eb45c851118cfc5086974403f6b161028534bc0390dc7d7902493440134c784b30289833652e96c58d12867cccd61713b51345c21c865976c0857808422f78de8b95472627cf6b895dd4065c68156bcd16e65494da75ac2e04668e0548e9658cb55d89bc8f98333e030a4720027aba862fb6f3b006f6be711b10b6d5e30b892708f42c49006357da4f637e8b3210e49817a9026b7403d64d861dc65955d75028e596fa68c97edf133d0997d84f342caab0f52db4b1330af6ca57b8b2423275255dc605fb9111907b648834c37ad812a300a715e231dba4551066051d31b82b6c3be14928c9cb78179e16ec0088cec140d3d6842776b30df33a11154a04ea7a6ade981b8c2995a37bd16734f98e95e1f753425f15c1a9b69ac4bb27a9bbff4f1845a734baa620595a66c97b64b43eb2c54f43e506cb8a7b759fb063f7c957155db10fc194171acbbe5eb47e024730a76c04d4525baeac5bef681bc3159bf0821c5b448e3a2c6bcaa55efa55e84e5084d257a0f7a97c322c8c1848fadc7a2f3db817816758220a5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b365132ebe95dc25a9ac3a1838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1d81755877c83b6511e10ce4d52440bd94c246579711150a33c62f42192e90a178f676ddb34a05401a151a4c167391d199211644238e8500bfb94adda266e23c0cc5f422a5c0719cc1a870e768c5fa95eba105e904a9875fcc58ff39375b72f84f12672386b690710b6b96c4aa17816a6a3fcf68e7b724ef4982c05799cb7a502b08b9ecde916b3e47636835c500360f24843c265b1d282a34f04ba6246b6ade8abbdfa13681542e77b17d398088b6243b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f20bb63b48b8cdd1c7242bd4f017c519b43502656e23817bfd683150488f8b0b44df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = 611c29905b1384fabbfe2241469d171ae5469bf944110ef6a79c5e06e36540300649545d479c143ebe97252515c9e3ecc003f03550b35ea31f9ccbc371aabb2702c7efb4e538b451446db1e85d9c7e2f7486a93a72f86fec574a94ca1e822c49ed6b9b06c4f9340c14ed887452c2681feb3674726b29d6ea6bc46f2c6de226076d154190525eb6ccddca62cc2b1ba3e5d1232e5f1117038f6d1d4b61fe754b5b5de5c55457108d37e27b2205686f0332e196974722f7904bf3eb1415fdc89bf92f8094f16ba89911276bcc33705556a4098d0bd66dc1a668f459cf4a7299f49b2df5d1cb248ba17fa613b810c21f864d1e9ea7e78d474a101a813e0825ee47440de187418943ce495cd84da8d5aebe3a347a156c03928fe6c4c0bdd23fcaf0f675fbe2d72e08ca6781730609eb298e346046953b1f915d98bf5bdfa582b1ffe5f200d54b2086f783e69f969cea706ac47501b37457ee208cb678cc12bc4328a21522b91d849d3128e6932bf7f1cbbe494e5c918c97dec505ddee8de0ea977c7822c1525b4335f1db864ce2071b50303a264f8aad6f1965638c97ccebc85fee2b3497401ff6fc02e6b3c4b97560c9df4b2c8601081991d7bac94149e2caff5d2552db4da90380f5e1fc06e85d55634a5570781b752331e39dc86da264fa7d7b627664f110b41f3ba7c702e104a3e0661660b8ea1f7a681af65be2c03f13a2b2e10674b55176a8c4ccf51523eee02f99581c48cc522886826e69b142702218772c25c082c381806d348835c28829eb81930dd527a3d7f8199e0bbd841822668c75bbf44afb9d3ac2219fba4f66e8ab1f40848b89011e417e5df41de43cd2446fbc7537b396e82aebdb03849f19b27f54d2b472b4c4a3517e777440b5870edd45f5f29d830e4368bec78623f0fedef49e49e32d1be375f0f7b0cc152d8d8a75edcd67f31e1959155e5e6ade4caf7494c6465917962707a1231ccbfc9571d5338cd30c0ae7f7ab40ecc9e1f11cfad4e1c98398476666528dd04130a978895a37db9669a0dcdd6426ebaf8c8f24cfa3699b275fca7c1e624c816708d4c0be6df7d8a5 +expected_result = pass +expected_shared_secret = 2eb03b010e291fca1bb6ed09d22d50b9c7bec93c556f1f273e57048c9c56bb3c + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +private_key = 54e04cedf980fa4114c9a285df546391e523d49009356878bb2c49c77462053a2ebdf802d253c694e11169f940295279e9638c126895762a5c0b6ba3c7d44c91b4543163c27bf9650c74cf472cba69f71908004540b83c7f081fb827c2cb4186160362bc0a71d602b41ce5395101b0235662d441429c964b28f4730af20a802529e046b662a72ecb206a18ab7f002b8a224007e312449ca5b9a01ac4d54cc00c1224bf8c0f6034ae9c8862d3c0a58357282a55a8133a95862b168266a9473c7abd0813e9b53fadb619a492a93d708a8db2a84f866edbb0cfe0b18dd8a0bd7281a7ec5079e952a5607c07e5db6fba1a010e28167b28b684bab4dd2b76ff4a227652bf2e448dcf86ba498518f983b0b048c166256aa5f38405db95c8e848df37bd971108ac782343026e473c435bb5a3573b866134996910a5b5d91d35281bc2f928d9144f954c4ff31c3523f80c8a9420e064073dd8a6a6f85c3f4b6245a1900bd15ec21801fdf88c87a105800127d5f1060b6676f7f2cdc717c9b35ba6e6c16f448926679c1006ba0013b2bc35c37fdab07e5db79253e9669af80a98277c65425925a059dccba3c0580e8e5a86ddc8ace81971cc5a06be7b9b8fb2cee4a1b5b614340db5314be2af85c06589f188f4d42738590736a381ce333a866b108cb88ae68803594903faa280532c37a0a4cf082b37dfa7c438d9386d029be2c6bdc3554c6d458d37f0930ac71df99b7468858c9e1a2561bbbc858bcdab73b82768503e946d48e65f3a1253e99c423480cef6979ac96c7b10cc6311375206a90ad4346590d69a3ee848a1c5287841c7d58b5db0b0749026387c93a29b7586a150ca803c3f36997fd523af0014a905e3baa92b92d0d34788d2530fe774e8071830c869e2417b39ecb6f0485ec7770f25e3ba22eacf5c180e665bc8096248ea0a881d59042ab55f7b1c8aa0f348675c5b4eb549dfb770af8633c0089eec5cb979646ae579a99d58554c1a0530a85631f12db116c7e4d2a89e2b42cda77b957962a1ea4b089b42d5fca0034529a4134702f06e989113c284ad2d131a99f592d3f7b50069746c10a1acf866163b55706133db1c41474a3ef0d4c7f131637d32b4803ac902fb5246c858a7426f9145cec60047473666a5e9c37b8ca4b5c1161dc5479341876aea6c515b564d68650b9822c6a817b5938f3809a784010278751d539b75ec07ba09aa34b08178ce5cb5bf70c99df201018b55e21c8a51b9a70be2997ac10b8a783cd9c54e69cb8b8a360d0dbcb9d6210933a5b7c5853af4b22364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a45181be8181ca2515d1394e7ef46ab68a1e93351a6da3684c8272c3e41547eb9e2e397a18f982e95730529c2affb88fef731978388791cb053906a57241cf99525fc87cae12e7360bb2a68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee3b231bc28bfe1534a24e15dbeb43fdb40238443a29d3685f3180d65658aea5b96078ba150623ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f19b1cd92177c4c2019789765790adb3d63c59719a292069922c5ab4b6b9ec2523ac919081764019282b16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e74e10196ec67de372878345213754af4d2affff085c970b6fd7ca06bfa60dbe526114bb854480d519a09bf5b6831f4b2238b99428538ff27c66777a49b4108fe3ccb4ad486f54a01e514266fd96a61fc2757facd39e071a0896e93036db4b110c8d78b586aafa5f182e1d05e17446f6158cd34427624a488fb4650c8883190f1b60374b0e8418a12866aa8000a7b2ca387b4b792c3719ae883a030150a668cdeeb6e8e59ad3e420361361a5a149c85880e245888192560052b490248b91a29adc0708344280b0b153bcbc0b575593245718b0180216d9a3847a186f312c169f42853820e862b90a4429f5d927a340589e193a5bfaa46f5350145ba2e6cd2727fc2545ee5bd74d4a38e181e527a80e2288444d860e7400b3ae3827a24042596124ad345e43a03ca310d37522dd962b71e8b3b1e3b29972934bf00015b6380617c8958303494d03366b6a51e7ccf6d3abdfb242ffb8367fe3a1d44ba87bda4587a9427dac62d280a0cb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2d19bf7937eeab0d2a7570d43cf965547542a519be85bdd4921f7d710747ec6f0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = 7a7a1d8bbe39d2b6835bb8b12574366cdb528f4f642dbc4b07509a753fb71c25357604a06cee0863b279ba50379adf586e20bddc3f925008d1acfca6c0a77172de26a4098808669ff9dc4b2782fc9b5b1a331af04db5499e91f9ed855eb87a177748f9822a686f2bdb5864ce400879d5babe9282c28e175fee97973feadc09625bcf040ac94fdd59835d4a6da91dd5fcd403a5ae336105e36177534c8bd5adb7aae4081f19de5bc251f87a5424b5ec92c13832a68effce05af6d9cfab72d8bd36390f874c551ac5486c632f2d9c19bb12124b2fab29dd4103f0a27227f0c007d73125a3c392029ef290e7649b5d52766b9204ad2e80256426728fc58484441b58e08b769eafe5e5a60e055eb340c6b026c1f567169fab3b33df4b635943db3f4dd97c3f35642ab82740e98ee138d6da37dd01cc55b33993a1a70650d98cdf6b2798b9311a7a5094d442191911b16cbf00595e0cc1bca40d53dcf3540d5d07402275e552c57d04d7a6cfcfacd57010fb4c617a171c4bea0bf726d7f10168512bcf0dd4056ef513aa31416164ce130b8e041556e548e961ca5cecd42c80eeaf0297612c4a71d6c42e11607783e7e44a99cbdc9ff3dba5ec0b1b975c296b09da8e326d1e4d6207cda1dc8677c5659aa6db0ebde94b720bcb7f7b7b46e31b233dcdcd527326625f14debf1d7a7a8a35fcc5868eee21b00f8039af84642772b605a2b72e0d2133b4d7c4915d8e461c67c6e10b94a8c0f7ac81ee47a81eedfb660d28509acbc21dfa08435f61197cfe0fe4b73d2d0025d69fc57787f4b669bc559915157fe394557bffba9df7bd462791d8fc054ec2bf72cb597898b0e2a56a9b24ae93db062ceb59851ec2ae301e51eec0a5f60cdfb575762f227cbfa8a143e6b1ecfeed0682f4f2958b5749b1dac33483832ba37bf50d2ed6b31af31b608794b365cd7015c592c782a965f76f73dde41f4b345b74de4ec9f837b88f53d444eb038ee587d33daf46235787f21c8f3b257024fec18dd26cbb72af837dc30c92a76150dd41a3871a188b9894c01aacf1c302e7972d4d39bd4ce473c3171edee2c707e4b +expected_result = pass +expected_shared_secret = be892649db60b2ce07ef18c4a709714933542ab94ee3250cea6e7c6f5eee5d5f + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +private_key = cc781ef0e49bc86b3f35c4645edb42a0a37a17501f80367cca61c8e6b9715f2536a9c27edee33407a159cc1a59cba30e3d79a058c97e30e36dd4553353b057afd87e4112223e38368988256b9c6a1a2214c24b1ac0aa88391b712270607a284862b192a38c2bd62a7a64d3cd1a9bb88d03138c88880817c11105c761c7cd0fa53a2624307df5ab95b2cbe6d87a6278849bfab67c95abb0ec9c58f33be488bf4e963589fa1263d4ccb0606e7d88911c82791a91c90c674af04576e3e31405708fbfca2bf317ad03c187492a6fbf498a66389c9f5469e450c094530324db1cde5b15fea74c9cb7382aeb76405950648255aea13160e41b00bd05e4921ebaecbb23b6a87cc96d3ea8bba500903a44b8a085c97f4820fe502beb69cd71f58c6a9b7089d4bacddcce28d0b63b04b7e33b44b6cb1623e64141fac4b6d573d222a28ba8c02053515504269c501091536d598336b6391148b460a9407b2fe7ad8c439649a9a17e5554bce7a4673b7a0f048f11104bc5b5c0d1210a898502335ca8ce1c2ed6ba29c59189e6c7ca0077343ffc9e213c8f08a5241ee7a43492386409b72a6a8fd01b81836b794e82a7e4031623c977c5b3a665d05d497abb466b73ef05847cba6c7dd9554ae237f7fb92ae70cc273b44436c0070928116b065577a0acc3255956a84b7e64b9935779147819230721840515d073f2c91722d3b9c76a7ad8ecc7bef809aebdb7ab24ac9782c1caa01b8871b01878039173a9c75c27841872d5538a990b530cda7ab670742f9ea32b8289dfa832cc528260688c645f43a7b81601bd68ed2f6a4f5a61a90968329103caef59f80a9c430064bcda9c7d4710f82fc646cda3454893def63c8b3f11cb006580a8a955d5a55d0387ad9c5051cdb8e9a03520b5a7ae0cc5b63a368f6342587144165d08df4a29455b11e6293a638102c0f0836517b15f6b726b5ea8dfc354d84bcc8c3c965dc3788682a411f904d5edb6a25cb4273214ca26c2a8b787fe468463ea0120798b8c5b78d7f3561ecf59aa81ba0503a2f4e777a4dc2ad49bb29edd64cdbe5ab083905d0a19f347c789b08b2608a70da01862dd25b9717bcce38ac41045d44876aade7c1ed6a2aa638994db7011fd42b3d474b08f87b4b2a3b83ea94b4a21d214bc2c974a078b22598a7cd7895942ac29d876b9723f32fc3bb696b467bea64b176c1219732af5e21ab49b49fdb0bcf9152600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d380130aff7a0ba20a75f8a04238294a4191ebc900d255ba923056464f6621d2b96c493c2e5379a95d16f4b5a72e5c5ba3840517a28ab3d8a8c3b8c63e882ae37f4215a74bf62c54bcb65159f9ccd88e07933d4936f12c2ff174f84a1a93e1a9163d0cce3290324355c1d6b21ed458e2f5883a8806b2d65a5f85b3bc103a692c94333331671f54629e89b1be35c25746130d7a9b939cbe017170fec7d5675b3bba33e4e086d4c6625580536d0c28ab5e073e5f37cad826173cb422f60bc11208fd0023395603d8d047fa57cabacb428d2f361a13321bc20827d5566dba65bbd827a2f952a065ca19fc208f4617e0bc9bb97e82f4322413d7317c14866bc72242134c38a7774d1580485fa4e3905122ea993b03b12a1f6323ab778fce157e3450eb02357a71c3caf9571fb83718748b2adc18296f570b05c4a77502062841ad216389b3b3b71c0aaca94a7051b0b523504209566bc153b3206b822779a98f59842442cd2b5246c674105b450f8e385d1585e651c934c4312d3208f7740a6f8a47e3393221c40747e452e1b0b7918b64d6c018a130416fd32c20ff641ddf25bec731f9bc9a36da09c1f5a058440b920694b2e9437bf23c1bc80835447a33f40a8dcbca09a14cc83d44b20da529b303d74932cd2761d27f5027fd01f93e907bd0538898078f57395ee2972642097944c19ccbcb4cfbaa79289ae31a230c67218b3c7075ff32563089a1e65aab279c3e4d9c07deba0f72a796f601382385568275c8aa6b26a8caffbb09e44409d1c404b6fd957a967a17c83cdbcab30d299a623d4b0da14a1971a09bc83a59f56a05bc6727d91572bac8fe834105616b5ef3c3e0cc2998f5006efb3673f4471b6e9005957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd6907e1096410ab332e10f37c93d86d9b4657159eac1faffcd1688d182d1278444f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = 7732839346a2622b81e6f6393906e2b65189bff14adfb40da9805938d2f55f9199775973a056c5ce0657a05b0a536e07e01bc9d44d662d08431e8ca1ce895bfc2d7431d6b301ca1e4c1da5332c52eb4c31c6a4954d0d421b7d43ca0b80348b6a7cfd20cb3d68af3a9bb1b850b7f74ecdf9d315504e20449b4eaff80f72d5019b5f0143133e3e44e0536d8f141f4648a43092475014a7d6081ffbbf6a6f13f5bb04ce6a2171cafaed5f945e3f167d8d79db5bffee110c267f24ca57c0d76cfdaec5a63a3c812988ece57da484fd646019f609b1b1574d858ff2909712c8c80f14a4a2f3b0daaed6930a450309cef3dade546faf53af8c2527d796ec430335fda2f83daf0722b5bb5edbc0c80234f549e10c306e20a0fd578d02c862073467e9e9e6e9f3c03062a447c7f3b8d2bfe2d7de50c3207176edb6ac36129d10d66eaa553ab94b9317d77bccf9b290c4c44f00a9f764c7ca051b04fb14448a9347515cf0ffd3dfa35e7dac0ea32b6f26f6a34e4763698cc45360dd7037f531bd9020dc5ab4ea337320443e002f40f54d0c90070a9e65007944a40bda666409b318d4d09a1d2b50d8f71004d03cc2ec7afbd4b5319ccbe3b92732d9389e27866465075019f3d986781d5c846c14e5f81c595b2a5e680acc0e82166452bec3bc4a1e4ea0b6acc7db2a6a051505e7508dd5b61bbf8a8652e36446f4025b105cce2cc3a880539757d0e7086226df342b4107f451164bf4e230da1c8fb9d8260c6383e9615856328f4593c3620accc0cda5f70ce070aa7928c1065e1dd5d44ad08905a50b59691559e0f2015add5468bc5be41ffe9b5f3eaae5e865a33dc2b08bfe09ed59a71d49ef3b57e96635cccdca8f7aedc1b7f1584dcc287b23b5e61c48ca7f4c1d0c329cb65c6019cc3f4ab37f79d2c8de8a1229c9357913c20a8e7d2a99dddb0da67e5278757c39821980fca495c213017e1acfef18c8e4128bdc0b7bbbb7100891428ec50bd867a0efbc7e91634731998cbc8e37086f321c32f2b90146999f97caf5226debe2a4e0a670980325bf48293561f8ad6f974484dbf856ff2e3c7d1a30aa +expected_result = pass +expected_shared_secret = 75556d5854c44805ca5c4bb927c837ff635feaae939220592d89caf74592a0be + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +private_key = 9b828ac37baa3ee2be76b5408e60cab8e684e1c16df00c78cfd4700110051efca6161789887899bc71408e32587b52cae8570f9a0c017773b1de06aefa38b980caa7ca23c4534a87bc8b2bf24233df526cf57c7b9ad2b1db465d8529c4855589e9e58f8d52293aea2edf630fbc9968aaf08fbd539849e3912edb91b1184ef56827e104004ca05e75a6c90a4523b39883b66b653dac0ddea5383395498e0b96110c5d62ac3ea60512ca03670dfb89901c089d4c59fa95b6a5911ed4bc0008fbb58f1c0705f152c5846e753482a5f677dd7980ac7a3ea339b1c9112aeaa283b009c466454c8c892b7f8a4be7bb23e057c36e837f67058fc01bae81c259b605a02153ab7874259d7bc593574ace70a22492401e2aab8780ab893a820e33779b9285e0b60a018b3efa88583c76881a1c7277f585d82623c650565e55cdd4708415585abec0bbdb7c8f694b1e998382ea1932a7d9c8fad682d9c62063eccc63cc69f7a7a64505221b2194f24a79f1a10d7a26a1859179bdd45c44d9b04206119ca6ae64b97f4865561a0580941c90acc237e3d3427eeaa15578b6bdc8741ca9a46fea9ea0754208779e9a748a1a648cfc802fb2c1740444a6dfcca13b450c6fe8848eb2370261a1d0bbc39f16320ed4abb7a65ec2ec4ad0838310642f4f752808b3225f112b8e279196107db2407192ec084c5b4010481abcea227ec49f63bace46b67a123a3664fb8df7bacdc8fa44f8c99dca57957b446fb6c871fa64221b3a81c6002208553bcc7a2d89ac403008b1bcb344a2bac20dd166f46212059c429292a36221b6ca51645719002dfa047db11ce9c7a6e26aa77333ae1ee33d8490487f3718f8046a03740aa028871370b0f246cf227c7318558b9241190dca2b6e720e8fc98abd603f77c1a7597c49c3651dbc05540b59bff7912184593c78755421b58ff6c84f1cb173a27baeac109245260f35f14f9f2c2bd694af6146a95e7abec6198344d281b9603a32e45d1a4b359208beee62a60b67288d8663511071fabb6716867f388507a1aaa70d268458504614969c9022a920b45354a89700145941e7a1055323ba95c83ac687a58a7f92701e7c388a4dcbcc611aaf6399522960a44d316b77734f025218e3c2b201b0816cbacd5b9b303297b0361b23d531a77dc965ee89694288460844259a735cf0c4c0add2457c5724fdfa1ef4546e5ef7c2363760ad478aa7806df9e35f0e46ca8dd643c36c6c9ee3b564181893b1b3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f5631102aad2b901d5a7675d541dcfe35e92239776a81e758c1c54e00d380232d5849102117d54144a20247017148584c1038a9329b9ca5c1dd337c1f758f558628c6962eaf49abab214279138db549c04f87bf243bcab3757f75b95c1f08685f20cde8c6d1a353fbdb3abc0599948ebc82e2434aca485d191287bca1678d2ca75497d73296177009bd384a9a5d0ac8b6102760261852b63d0520fe82b9307d1ae2b8c38bc1054c0295f7ae2321dfc82417849a3bba7467232830c35c08038ce2c4562b7a89171864e566121f6278a0b777e02bc50029718709af63a7014d8b9f79627f61b457a25c202a6cdd6f9a59fcc3cda84a1a43620b1394fa65841162638342a24671a6a71e092a7a19866ab7519e723d6ecb836998af8724efcd2941a5bc225f9acf8468b5c68a781b664e3614fee782c20e80cc8f27d1f455397509c86067979d7407b1bb536408c654c624adc0cc126bd3ea29c33f897e168c9c715887474cf1479450b80659f816a7e1999a8f2008cc9cc732a35c8d3b290988dfa31a80fbc1a18a58263c7bf18dc0498260e66fcc6b991b4e91ace50240e7a2a4563460d016314c404b269fa9a8d1b0c074545feb288208b790de67dc3c787a12b0041c52f80ec9f6a96733d874e986a3e06b72cc4b2ad2460b7aa2141f3b186525aa6b6d2901d46ae2f5c7a195c55a48934b4478974370a982414d9a160a8c45aba043dc597a2d2a4acec6708a3ba881c925c215a8063fb80f0114a94c63a1971249368b772a662ac38856c79c7b726884cf5a014527da479c1d7747b4d74cf33f30612b70d1e0c2faea53ea1164bf9733935d51542ba3a47b099fc82cb8ec391a1361c19484f1bd52dc2315e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c379c9176059f3a7ddfe021041301bcebbc91e997a0d5bf2ed1d9d125a71298341c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 9a9b4571820f9c5f47b07bdb1c67abb85c73355083931db78f6325c2704ca2d94938b4254ee3b0f7a854dc5d538ad0acc2d8377a53e660a8c4d21401609c78402fd6b54da88709c291fdb782b71606aba066ccde8a916ecd03c4bd8a2742cb2c73947b2d1e27cd5a11b8e775ce9be45ea145a5b1f30c3f9f1186d070c898e2a8b685926d390aae1649bcdc5ab20793c1d6b6baa9f53e8a62780b65cd7c7df3ce7dfdea8efe17522a23b916a58c34999dceae36aba7e048be1d3bcdd1237ace16b56370c3ba759776b1a11648cb0f903343fd2b4b8f023e85c07bc4a27ff53e9d98c6ce95c867e267f80f93d5bd8aefd0606b37a8d2f6f7f1f4658157fa24419add7037bc7b9218386dfb29142e80c4b8b8e4a85c068061b84e869296a4b1ed7e4390b29d7defb0123e466e2ec2efdc79d47b134834e6fbbe1b48c8121604fca5115ccae3bd7b2e56171e47797074489da8595c995fc55bff27dbb6f6f9ad0a068ccf7369e58e47a02d89b68903f9b05e7c65fbc77eb9f85d00257a09b8bf5ef6a07e4f5c1cc2634c37b822f96dba4481522b9244666281168702e7cba9824ce6f9e04deb7250beeccd74db0fb7331748e0b766c398912c42f226cae3bbbe19e37b17ea3fef017e4bbeabf53313eff762dce9879966ac17b8854e95f8cf7bf007fb13743532deb9ed840b96cbf15f15d83f0f6642808dd917a6eeaafc205caf9e4d4fa6097fb91703a11efb675c9210c75ae4767022c220709af702fb162dc901e0803dc5b3357e88fe7c72b67e53f01393faa1fc25269c874766690aee0e523a2c7c6fdccf17f288f517f3870d1b3a9c02fea5892535b97f55da5efd615b74dcc86b2f077c0f0e2b4e43b043332bc7195af2a2375e55c062fff5edafac0e62a334b24fcc6e5667bd256605ebec5c162cbde1e40c652b4dacd864d144641b3034eff93d75fa59a8681d5e4ee1d582c1fbedceee28839f3ef1fb79d4eb7af134c4984e86d8389dfa7a21690667ca1e6ee44bd66e6c3ffd94e84347d6cc233e33210d737c37f5188d8c9c33d7a41d76c0a60862e0ccc87b787e574634e3b130bc20 +expected_result = pass +expected_shared_secret = 469d60c303b10f517a932d9fc090e61802003e9cba3630224f2c43a4727230e1 + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +private_key = f2dc1b40867ecca65895960fffc60469d809a85cbb383886b9d037785345d57936dd7ab93ae0504df32d8438662f050720262592902489f9a90233cb20a5492bfaae4b444ad1d8c84c0a37f6c928b8a89c22a326835073b978a200212c5b000334bc936fb3c8f2626c862c52025a73425a0e16f40d2d87556440659ab53d6db763b7f19a00ed6a99017a5677b62b141abd908a51672a65e31493659762a04795f80f254ca4d3683cee608df6c79a70994fde528775a991bfa1035eb1bcb6da3c63432bf958790a81620a614e3a330c1dc658e7398739b75e1437451d21368c798009178a830c19b621802d848918ab34440175c825232e70637527c2e276ba02aba363f082142c9e4cca09515c801ec78ac7ac68669c2a054cba8008603f9a3368793c0bb73462182977d202df4abeede70921110ce8e6108b784a2be9b4410876b14a097d50bd8cb933ab160860950656f006a0786f1894736c7c694e8a81a301b28b9a43be14352661a1ecd11104fc52db91c1e9f85f1bfb20ccc971f2ba8505890dddc3118ee98cb2459cb2e003de4b3d4edb74c934056f4a824b721e37d247142bbefe25acd52b3122519fee154d9c098525839d9e8593d3a5b2ddf91be4286a4ff470d45b55f5f75db92b8adc626390698bd780977ff5902e206669e092ecd5002f43801bcc14e75553ddd5a122ea24bfc1b799a727f5362ff90c99b035b3b2c545e985860bf8c1fa517d348a88bf85690e911192a643de17b25363686f6a3f7d643cac6b536c8b536ab84e3e6b1200dc7f71a989d04098ba39cc15d2776d50b391522e4ba60916625941594f76d7469589085fe45793529924d6bcea397fafe8a963311581429f194a76d627583b51675db41bf42650dd44c598c1aafc177dffbbc6bea8bdc76c143f82b032f45eeb770231e8b85c8744ba9507f7dc00b0d05772b927c09cbe92a05c80987080a69d560094b3b021c38a323622c362fa0809259df6cb8138d9774af279d4882e4334aeb7a9b1ec82648d407490d168a95c769869a8e6521156867b1db3ca7559ad74574ed6c61b5260b7eabc54b3384d7f010097591e75470eb931b90d0a7bb708c1b5e97fca41b6161ab4c1cc9ab3cca4ef8804c76c45c44c4bfba29d978014e36195cfcb04ce7487994261638a779fc540b6d0286849b7cf51b8b648ad792bb225b42b637693f967c21758cdaa71134cc68d8bd7198b2a971071373f772f7044b912775652d1b78a9c18c7f00a86526b134aa656801b507714ab6a37fc57051df46a4ffc2899411eb6083df07a9e59c2c55d626d0bd04425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e0a1f9d9416e2b2ca22cb20f8f4ce3080aded2262d885780c9c4f171685b466a5db14bface3cfbd979895586a5f1a2bbb7626e567075c004b92301bb60b0e3208882329cb7de807a38656f98abd1a326ded150401035c816b9e7e677a29849caa7227d57b7969541e11f601526a15631c75f6e9be24d54773f906f394643ae31161898530344c07693c4edc042ae805b92157b6637722146f16f49297370a074962edca884a2cb091568e70e3a57ef2aff79b17ba6226b396a5702673704b01d7959c180513e0ab03a421425274ca53774557a8ba060817b62b8abb20596eaa16810513885435486bbb5fb83c7a9969ac593881173377b1b79ef4b7f20b0b6ea325826667fba3c4e31227cd858578bb771c27abed688844b95a4906c290596ec7b14dca4a60cf8bce7d12545833803351a0266384ddc2673048aa660b9a8db520d37ca59ea19cc6f19eb9e63d6e842076b397f5027ffee9672e91ba1bb50f0ce37410c686e9952d86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637e227c963029e7935814fa0b11c4b0e695aafbc75dc2e90d8c63740c8875601008b8959ff214b513d42056f78457b45e47285440306d15e3607a130a4d6b2bc0904c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382624c07c4f26fb449a412c37b73037131c81af9084eabc16b50956ed9daaee0f4153da0c959c40f78366867e11378d2bccae21762b543d8b2ce2d7ca79cb7ae2d06544982728a7a2ce39ab54df83521312d942c26f618ae5491bea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249fff5515b23187af5dac6d1d090bc7bc01df34ec781561e3d3b8b62164f749468026590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 3e361e9dcb35f7146321e7af1daca34ec0152cceb5775c9247c23eadf5b47059f1443b2231db821d0d66a1cc778842afb8175adb495fc6549044fb548fff25018c18bcf791ffc75c7a3ee1d5939fc226f3e992c8dce24c07642c28aae6dd8cf449085567b97d6687bc5227ff71e12630a8e1710211409b118a6973b485ba8bd7c8f9fafa7184d87d15fffb78bfb00f5cf7e3eba803ea7826f928102a57b197564f48b2e4aa47c020be5e1f389a56958c13e55062270e7988af908fafcd13d4f122ab6f99b3badf31d2c0d15f0bfd23b68b5db9ef1e278ef25521b2ff6716e7c2a45416f02e9e7b2c0ba1fe0b4cab08e0c89b3e69b384522a203c4e905a8917727be79b1991e80a372c38a9ae6a8026f60fae6f262a8277941c718e7d4dcc679cc6cc16555a5555c8385ab2845859f5281d42ca6dcb5121f18bc37de2e04d8c2f238edc456a94ad42ad9ef62c1e0bd1a0df361a59d2a26bd5cacedf7b9a0bb1844ec2aa12f81f693125c149058e5212cb1f2fd6787f3f7d228ae8f87fcc2a8777b39983563c40855dfd6fd8de65f17021c7f553eaafc49a526b8c1bc8ede4bcc4ca4f722e95ce80a192f3e52fc89874f6f0f4fb0f8a396a299c77ee476f2584b41222b42cb0f7a60ba335b65bbdc2c31e80e2fbbac369f2f97380c06c3bab9ab44db05353fee5a8a757718f3093fb1f431046508c2978dffbccb51a0ad9b82a72b793e524fffde51dab47b58a71e1b54d833a31e5a805a80a8404a0e18a60811a9a814da8f16c3f7ddf850cb9a98f5efbb3f26e3370e0b9c9f07bf696afbf35aea332c6879455c48f7a9aa9e44838fc7f4f997b0076e66e263b2dcbcc1cc4a884641b919dc7d502361bfb7cbaece1e944ca5cda40f3d0c1601c5a2514891590c6de08121695e2293a11d70f316b8b3b19059b782a87976163d687221d494de8f66c3f753b460f29abe5e56420118d464c33a955f41836988bdb067a5ba07926fd34d1886dca61324476a3e7c685b16886d077ec7192331b98b850723cd3c10fe294cfcb5e5e05039c5c1ec4ff2d8d0cc437b3c2e64a15cc867a7d6380567b5cf5 +expected_result = pass +expected_shared_secret = b545dc066355b91cef05e65107fa11070c455209c55573cc549cd053c8e4155a + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +private_key = 8416677d2606e578c24f59b59138c6cb1144c6311541839bf79066650180799862d0049ff1fa13d0b2c1b4227d2e673c9cf09af164b7fe7ab10b1928aa910f5e81401920cbd4c8bae6a71fa3f783bf8616a2eb7dbebca74ec94514c9a99a16b75c41a059f437e7cc3febabaac6918ac41b40f3b8bb287009e2c29a4fa586ed8400742b7c05b252210282f7959a72c2b9921ba415b5b2b78106d7c464e0a01c229046d05abf7a611bb48b07835a461264c0bb5770906812a60253570505af040338445ea2e072844445cf1050ffdc7f29f228c66a4a402b98db0c497bba0ecb68cd93b542e8bb6b40393d73e7ac51d093c5c15ef9d4a7a8d056259c06977ba75f4cbf5caa86f5568c422c1424d123721ca09792c16f948d7b84b758375e93b156466b8f0202c7bad31decb489dc0cca1c0788887c0d57f3808e16634b061d5aca96f96b9653827387651271eb05d5320230293b39747e001bb875728d2f2a4fde26981de26c68d542496a92f5871aa7438452073653d14cef0b2b6d380daa531874b26370026ea59884d47528877aafd444a7ef16c03dc780bb938f5fc94cecb5892bda259c9a625e68b89e374b6d134c3291168cb05065953c851aa1e5458e151a3b49f47894e646311575691342552a27116399b3e441d7524b9a923d616a4d9837b05301c1467991fb81492292b5a7dc2e13e44a83265aff2aa03c6465ed1c1ab1681bf0346aff84bc61e5cf3da10525c4ab56a85a053469ae73bbcc77c28decbef6007edd003cd7594b9a30ba6c18617fe15ec8d549530c3f7978ace489b4a9c0864e175680a7c8bff43e7175b393a2432126c945755979b36bf9ac10d806150ba38280a1c7299a64a085ca55b49cb723a9b0ba1009965a0ec66a7e6341b2a5c89a1a0ae6a3a2098319200bb06f52be404890f7eb66e9367ef0a5a92f526ea9e8b43f60bfd80091b4525184c223554023d7e698ec144d1acc6d1f194b73184267a03b6bc43b42a07bd9a5cac4388eb4a2323b723152e6a4f617a0649c469b839b555cb56329186e675b929c8dc4c83977b32967227bb7f971de607ad49579412ac5007438690416fad3acf0bbb1642132613200006b4a502975fee79d2b7aaa8ae2745e16c0a666c8a3a24a990cc4646c8bd9e6744d6245fad4b2acc58b0001a7a351b61debc0cdf85b5b5a188d040d0994027f8131d9706aab35763e4aa232554cebd44886a70a7a846e67c3842e96a3df7233112271ba001105e2a35b5689378c108ef44f8ff858435b7fa1b1376f4c5276a4002732b81974c79ad23143d8134fbbb2426c9baf566b777803a354c5afe8a1b840ca5819a3d612752d047207181bb6c049f70656c22589d1fb5d5b9506f432b52dc933d0e816b180681d7743aca5259f92b8b2309286b680d174b267c5bb01e38224763a26db0b36520477591b0707b09e97ac78fa71e43154afd39266217067fb6271fb4c16c71e277a0ade710562ec287b7493e4fb453c098e5d991fda9abf9e9a29e7b28e0cabb4be5c8a3f490265f5cc93a0b3a52881ad806f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6c7053a48a5168934f0f2341bd263648291078554692815e1b69b1fa97031af13901c4a90546396af914f1dc6d09f58c4af89474ec34614535a6dac8d0301f67339baa610cd5d9c2ac832c54a55175567a5565c478cc5fde74bf2614c6815152e83a615de8ca9ed465a05507b9218ad6f7b9b2799e2ae040084287c19573ad0200c8e683d138ad4e8804eba5729aa81c1e1a9ad034a352c156e9ab635e849f65a37ecba8c0009843016266d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b461cdeb83b637196d757999523097a00920d0677ad5c23906a3fc9054f1a3176d5759d39a03e591bc10a7cc7e05397af2c0f60e84de24318423c0470b82acbe97f3a9889c2f45418ca28fdb092ac703a6a9bafdf6b0d05182dbf9a55dd3397de5a9b0d7c4950653652c035addb2ed3abbce4e755d2519e881266d28524c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c7811966b7e202395d4a46d81b0b3c2d3950fca0cdd208cf462b688919b79366381a11a6e195cf234cbf10724d4c3b9bdfb0816160215bc6d5102689a21af235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb9dc0d69094efe63d751e6f9c1e92d2107a7b45fabb820222d30b11595c351643b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = e1160ba40116fcb1db2135f7820ef78e5023cdbe18b2afc353d0e3c5a98cc7321e542834d83302a0184bfa1a51d1a9b349fd79a8ff843a2135977c50e31e62f4df200df07cd7d40da1c7aa3d7c53b3daf5faf39908af436aa4263f5eb995999961f2d33515219a1b20808039ac45babd25a0d652a13f29f0f86a50352de672935f1d90502a67458955eaf044d1ba388fe89e32671aa122ba382c8a605cf4301fed0065808b03ca94da42c2b074c790cccd18d1b0070873281277bef252b920102af4ae96f464b0c5ed1642322faf0a829a0d86839fcd9bac2db2857e2bd098d3d9efba9a87ea4baab180969c785886b20591dd0bb5083445c068b25cbfdc4ea472097fbc45964866545a54598575d0d61c57d1adf4156f87bdf9069d54ea0381627ee4987af624e3889de5db635bc2c40afb3e83259093e8d952e921d553ddf14b712bb63eb25c6e9673abe27a73d37f33563e55b353631f0f15cba393f7d2e0112063c76dd1da61bf6ea976cdbbcfae79236c28a06ae5453781d4f74d9756fcf021c4e26320d1ca9bbc435522271ddcfb9e2a3b84b2f309286f5936594f52fa8e3e4d4559953239172e7045e5eed928cd1832def8f5ffe577b78526f09e7077fed5a03f0b9f1fb5f56dc51b72eac7bcb2454610b384c974591021a6a2f78fa81436c3c8dc208181d5483f4491319021f3686e51ae5da60276ef5af30c53704ab3025469809d319509f052cc1c4c85c899480f7792d1b9802d1b386175d3aec998ed3aca1e265fb0481aac45b5f58a6f9841d6594295af4c98bd81bb912de6fb5e52ab71202c8280ff34bf4d1a7203d224601b9c7474f6c4b77f549676258109d277162614167382153a462f3bcf1c6437e24a1d02ea67cc7233147300d8ad361775112258bb8b0321ef1c98f694e1e3f86e1833c8d9726280afcc31aa802590421a544beec646706e8d66257f1047d3d98217c42b077815fd8c80d867662327f98fb7d59c3a3a56a8d2e934f963f40ff1e78871a8d059a744152e72e082f061b6a4ac657861af3e152be2107b942ac4e840c7d26e9183c9f8590104c4b3c962 +expected_result = pass +expected_shared_secret = 2c42bc4a172c928bc6ec7480785d63f7281a9e5acfd3f94335d6d7fe5fb9c5d4 + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +private_key = eaebac1f43968fdc3e0f190ffd117773187bf7bc1d0978ad917b84f3cb8232e364456ca6574b004f8831a5972d7fa38b90436a7a773a9fcc83b8dacbacfb57c2323816f26b659a666711588ad7ccb3a1cf7e5c4592684d78fc4b3053467c28943605774b039fac98bbc1f07ae1f192962bbac65226316bcc1dc518aea752963c5d272030458b7880364138850da38c71cd8cb6454b13f9ac8aa4d508155701ee1a643251411825b68312225623be92f379006109b02cc93782a3951465ff49a36918bf4aac8328268c9db387d7936ee37aa896a50ceed6be31a59d1f415e2c6053fc9b8500597dbcb7a0d00b011ad844e37b67e52c9d2684352cf837ce732b7708386b3bbbdce3b52762627baa846ce93b13b8bd655143e6cc7680a864cbc59a64797a9897914a99ca40d4702d35c9c1c22e9804871e4c245e12bc5499c8bcf28ab37a6202f99b6bd3b64ac49c0ff74538ab11ea7194b92258fb2078c1705dd643b0539728068625d21650ed102247f1605b051ead06c00f271f68dbced3014f0026904256a4aec6041b748e6146a59b06c7e2bba5782681e4416abeeab61fc60cc68c53a501412ad07a721ab1002cc2428a1dd0b48c0e53325bf6ceddd2331df849a1939097a578add64352849afb2070c68b596d4573d09060013bbe3cb4a426e3b58414a108c37f5df6091a560e997263a013455257a24becb585307f7d7b6565a8781e33551bf26dcdb9caf2b02841d97744d71bfd3a3be87162ef6570a1caa1a6920ecba83b000242912b7986f7913b418fdcd199b66a015aac03a602767f212aa367bc4f886adf34a1f694a305627113f6074b6737fd2889ff4411605b2df3a7cfaf6ac1be726a0df282ece479abfa02baec549fa98d0c6331c3e26fe9c94d83277b4a08556b9813d4c6b080818fd07244646631671252e52cc5335aa32db09f37e8628f781256d811e84b989dd9b6df174526c9c1fce39168ac20458908a09363ea961d019c9aeca9cd2cb60fcb0c3190a401bfb139583b8c3629caf80432e71a7b657bc7ad2b3725708bc5666be813674068a8079a8a4c471b0ff98354342021507ce3543789ba78abe30d6241382c6292e084319a4aba75374c0f6617bb0a92ebb52e66d790b9106553d5c2931a9534801d37551d9e7a854b9733be2b0dc6b86390886a6330b159f96dd3339ca12a206c3278603a123ac0c1e8a982933b0b29b5671a291ae67c08c7945e71891eeef048dab9370a72865c0b47c2c5b90d134132bcc48d4bb6994b2d6e1567409467bb21868bf17eb4c23184fa9eda3bb6e2187d7e9b7d503a47ab1c2d0837ba25a108805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8a612402091349e0cc0d142e9e763adee2af2d998e8e686fcd76c03b069a558605f572b359fc4bc7b0346d11c1e6f9ad71d1399eb992b9e54268ea8ec5e9af804290a19732cdca883b5062fe1a878b1696eaa0340f071e2c9206d39284d6b2499bf0a7faf99f5f8a6b77499419dcbdeb6725e776a0335286234a84474c54f952b6ae075af4729a277381a94414e8e6ae2a9bcd2e01517b99b299f3aae1ac965c086e59bc6d32a02a26b911be148c7e48385777b841d917c34c8842c9c90ea431b2f8cd71a78a15f185f77cce76959ec1748c44e5aefb140e752c97c5aaab8e936e84b5c89b3080480a4b8be81fb46b12049c6bd67c74fb9095fd95c971a2c813f08b55d9c867aa61783896707a36fcfb175a64013b071447469e768a7a1ac43fb77649802522ff880e59b322f85b919b2424650914d529ac7a147586279f1206338a67c02109194eb493d4b9ce33bab709c333a91079a542bf0d717f1c875d54f11d7fe72abc346000452fbb9178b7c87fc437129797cf38467296889d3e225dca6068583921c9767050f51246900af6689227e709c91727bf41483915b93b3225454979c0ca7b3a2c63a0521a5679caf5c26d5944186f43463aa419b4a660f2414a535b9236868c2c091616fa6522bb859fa61503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1d700ac825c501c986ed28bedac0604b40a0b4f8990597681390b2656857ac712d7d4ab4ce85673fa69c404b0b5410a531f0a6258336d2bb639f9230c16c9a85e363f9c355f8f00fdf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f64816829a8aa9f8c4e949d4e6388448c2c4ec6a977f8c5fb80bd75d93a723bc9bbe76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = 689eab66cd05a44bbf065669766cc8b611ffc6f75f205ccf55a56218d4f9da959eb545f8c47260052b1c2047ba745c6b083d12acb0c482f0adba085e3aa1a536515dca67b8335b06951388dfc6313686eaa664a67d04a0ff60ed3c620b609b4039296304ea987174ca705a5189eab8b53477e3a53a621ba08a2590791514a86ab550aaa853a8e46f60b5ab159c65fe6eeff861dcf102d1b2f71f1862592ed0280ba4f3ac61f0e51525dae128cb664404e702c0fa543e047c55df151853f995a3b99b92bc5bdb77cd3bcbc63e509fdd0c7ec40dacfb878f4e84c4aa9154ced81e814c668834bc4067c11ed28a80a35a478cb72f13c2ce1d70ecf4827d00e3cee83d5dd0ff0b43489a2b7e5ee069b3c4f48ea4fd774f66cebcf5914156cd251ea48c3ad841b5c5531640cb4762c4dfd33bc1f1c3377797a93cdd5b07343a01865cf6953ec2c33c7e2c95044c5a95d1ea8ca2c6bf039c07bb91f64527ec5be6fab765bdfaec1066a95246d95a3a936ffef8f08523152e46ccfabc515b036fc8179481e8a3097b99168825b055e4a916ca8d839a3fa98fac30b1077f4dcc73cae3626e827d17cc50c84545ef759b40e084678aa13b6f7d58cb212c002c837a04cb00573c1d4795795e93e8dcacf317f378ca4f01847f93d5d5e09f880bde0840e471f38570d947f842c683fc851527988dec19024ed1d109c2dfb9220e1c80877174e50eda8f24a513b1fcf730d528064272b7a1c8fa7443a4e996b51a54a0fb90ae336a5085ad6d1310e285bd58011a50dc829d6826fdac4cfaf70508e261c8e85c56942b021c248f1cea0e4edb5548959f7c0d08c1ef04964f5e2bea6a195bddeecc418cf4be8ae7b37a86f4021161962c46ec2b5cff3857423ad8378e21eab4bc4f43be3b8ced7ed1d9a1adb19a0953eaa9f961898bfda24e6ee007ffa4214d00c661a96efd43faf78f2d2cda966839007fcae6c9ae5cf6df4e98460da6ffec2ae929e5ae47e3388d7008fb390118bdfadf37d1f72312279410d47b4f19cd7b607c7de9c3409514c37d137ae5dea9d137d2a85b19f0de7d8ed9f93f10b8497402 +expected_result = pass +expected_shared_secret = 230a69c53e2192eed6c9b876d6b228fb666b19448e0a2ef8601910d624bc173f + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +private_key = c3aa38df508762bcae32850e90e2cef9404bb2405b1c7322114cb440c507f27544a8e65bf08a4e19988feaf3ad91546e95a2a690ca99f54a803794578edbc9b9b955784ac9b0d9207487a2a86baf45b04da2894fe2508c06e49d2c487b87d9adf3f67ee5435f164510052974add5a26fb227b8f029de714e9c39bcad318b2102a04d03c1bd1719a87279f589401db284dc8189d48c897df69da478c5e5763968929a3771c3ad7a2ad2140b5772c091439eea807a35e988b69c531c2b47a500c71948804bb09f682c27dbb39f9bf7b53f47ce81024fb3650f32573d734964a392116fa53808411c8b035203f5564576334af9929ed78e8f6cb29c9b4f171a81c6a34dfd57c59c380180b9b7f38538bd82834fa354d629544cbc659875b1d77b63579a8fa747c93049127b45387bf6c08efb9442f7565901b71c888bb2074eb4c9ce945568d99351fd0a3acc3c54e600436ba5558ba975805025ed07444a9034c30a9c13a8ad85eb4c7d0142a2cc2e06584f37f843b103be4785694d2b2c4dd0487e030f6155bbd52526b0354847b233521312f5c725ab190572554e347183d0902737b96583a87d5774298d4a7b6b9292ea8230412a06def3551b4481d314c6931c8012d43a3eaa0d0df6cb87185b7be43e6ebb844392960e8a65f5f691beea69bec55b24f374c41a1a49560c33296beca0b07a7854c658542a8917c35326a1a1c458448b77d27c3c440c727971b47677e45954fbe9011d00a2f85b3e2cb9725601c97c7b21bda481aa04083576496900a70cc135005221f69420d0f884d35216548022126604cdac4100a74614d4b1206b6fe20a8ac07c31bfe6867362b5d2a67e60061c8bac6620d93b07b87a5bf4101fd645321bab2441185281b933a090686a8cccdb6a1705b07deb9e66ba4a10617a93ab7cadd51047e50f4988c70012a39c787dfdc3ab8c9b19fef0ac4c702bd693170e71c5ff4070b47b3609c5a9f2e8663ef78bc5e27ee6092013a263f2ec172edc4350606840393c9a771999399e948b41ab273ea061744e4a08ac7550c13a265e9b82e674063179811cd7251220943fec7c38a86bfa490bbb6b001c129707b1b765416401290a94dc8e2cab1503dc4cbb2a51bda96c5828397d406386353a75157b09f1776ed5347f3a32fe6b2599827f83ebacba251dedb3c3e514b7add849ac5c40e49b1297634fdb8a6c0d9748a8fc9e98778668bc4446c1444b104db4da7ae5fb5db088cd34017ea6926dd2128e9b39419cb13ef8511705844d4efcca1219453f987cd5d0b532c6b958b202938a90ce9016792035577a4b59ecbe063a8a158b92e89aad62ea507520bab2596ef18778590708dcc62bec78a74715ac69bab4521949e8c0bf914b5304a7384ad25e79c3244e581033841ee8628ad68842f320584068cdfd91467c1051d1a8ae77e4b418343743f0a64635ac313cb722f61d0a672645413e5e92853f06aab35a067eabbf6774a291945e9157255af4008a123a25778d57308328a983c0dc8b4f21c7dd34721db734967a706ffa75e0b052f67c36168ab46c485b1190a6ffb60f4eb739c232b2eef630a00469bd011bc1eacaa9ca60c613039439cfd4ecbef6d7523926ad88b8581e619b02a182b76993b26b3784799a7a314b38bb6a17529650c7a0a556c3dabb0fc44ab8eabc2af522207e90c7c7e113fb7220cac24f45dac26d1605a70c16d1f58b6f766c8d07c56f582c88f6402fcab763f996b164047daaa7cf5048eb51297c50c44d95a664583579f18639772325ca12fae19205742e72803fa4b9991517442be7cab72996ebc50018963f89a5af785c354f7a94241051c80bcd0d9c7f8b09ccad58c0ba22820e859c9a261c6d41a6c310b310a480d0c8950fe1383727b0863ab758b2c551bc99cbaa90f0365961f7727f639183fc652bc4a2782081dc69571b298affc7af09c349124601602bac8c79afeda8531423642ed20075a9b176a75d422740c0c20fa87aad22eccb98d4bfbbf52e7b590aceb660e3982ed3f3cd328cbb6103af5be626b5036ec8460ba1fb8df516b315e1267ba1bc5770402082bd1100ba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620ddb15151b9c67a9c57aa678e7e83b3ab4196b682f20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a90fe22b38a4fafc045cdbe0c9689745fb45760cb2f0f94f7d13cf8c834c4df3cfc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 8b51eb12e555fb46bf0e48c750b6d71a284850a56cd5af3922e92839761b1c085f2d9fbc83226098fdf6affdce428bdf900c8d89c03ab6c389558b3d5ba4075edf430243005829b960f7a87c862af0ac59e689900372e2388af25eb4f9756ac42d72222d4a0b0c351e7da086b4acfea8f4b1081d5b6ab7c8c5b37ce6e7615be7592489432dc253610c1d7896aa3a5e4d7399d82101a1e46677b4edaba777308a8cd9f1525341c9c19d1fb9347cbd98b207c5515d34995f4f2df14f2ae5212088806ee7ca587fc0d7b5a7412347a1cc41572aaafba04043dd593e7a957288c2192f08afd808b74d3fb89ad06a5e3a25d2c182c411a1c2c7fb3f2ecfa07b2c6de5319b9e309f4c3abfa2660b6f59e8db4815e9703eac99469eb78243d92b933f01a24e84443fe52cab14f7ae1febfb0e48ef7930983853dbd9d27f3ed7492fd9c53f20df28b5a327876f75ab1793be950aa007a6a87b8e79a58c6fff43a7c69901021c2bf124a4d22632a68b607f730695f36b014ef094f798091b3abb4da059dad519a80dba1b5afd3d601e4e00d258c6f4be3dd887c547c79f2e5917eacf44db086400e49fa6ccd86b8da13c34e267bfe5d5d247e37eaffbd960627875bd338d9c221b0f930afdddc811097b9c63dd5dc2d661f76954fe4ccc8b86eff95c5fefe71a2854c5b36b706711530a6ffd07e7777eb6bfc53f8ccbf3efd2a24f16bab09934bee06843dd4dced6d4a66bdbd651109193160c9cd363635ebd4079906a499670bfd09e0b360d0c6058be1ae86e305771c118dfaf9e128cf64b8422320b51ed1674bf5f4fe73b0d3072fa7669581a1ca9835564e3ac05621c1a652ee69d695f28d4fba47b2430867e2812b41ff7c3b3545857f01c12f07f6b243894be53b2f409cfe00d5b705727f6bb5973cc9a3f2bf6162a8cbd9d90fccc83f133b3fa15c1b49054147d9f691743ba4902c03eab57374ceb7f23bbefb436f2d5c659f3908071b65cea4b8f744d77ae9cac24df472bf55cf6a5f892d4daa048e1182e61b214cbe2746dcf12c24a64d36d3e01e90f595bd146555368928960db5e161cf4ce +expected_result = pass +expected_shared_secret = 327c548d7df90d813f3b3c92e908c4c55fe4c7277f91b6fa2271c0f149dfb273 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +private_key = e2ac344c36b6a047ccf755bef0f455991c2623a76aef7988d0a072d53054d1d29c147881f65ab97ff40295b487677291fa183831b9a6799181ef2872a935530014187d706015aac1b122567ec54af05361bcf384551c71b2468758786bf61276a9db8a615442cd80b3253c862e5129078168f23757b7489d98ac60bcf04585e29b623a44ee737343e20e30e7ad5d20ce6af1187d738b60374a02b45e60f71a148705c65ac34076ae4e390234c118ecb057ed3aaa422072239a2545021b8ab5419fe79bb7e7b73fc38384437a5ad673cb903a55645d00ba659be07b708367a56065bd0ca8047b3258347871987985917199b4445bdbc4ca90173cf410d1d5179b19bef5b0675155afd0f0603a446269e3487a68569caa1d72c6754b441c00fc0e33d17136a95b990068df699ca6f14001f509c1b7c7bc816ca2548dc760516d9bcfd0a61670d9093a9b70beba40dfec2b5c8086acd164d57138a253328da0284da9ae3343003edc193231b6cbd7a0ae0cc19a72847ef7c01a850209e3b6d579a5eaebb566aa001b6a7ec8c0817859932c9570c290214848c25f9c5676553bfe734cd12b747c88aa0a59bfb389a55aac4fb46ab932f7b4400978ff2a59e8e4af7fd3b04e9b8d6e0a8875764862ab6839844f01014ab131003e876fc17bc4699523bc16af8294192116abc03a8b197852b31caccef20e536713b1699282598a4cb5bb89d56c6829c2df39c0f3494f51107c53cb60d8483d6fc69eef5014e9f9bd5aba580fb25c854a13aee72d86ac059cb7432e514f4d49c3bc2a583255988243c699d520d5d80aba6868ea811c487027412988cb4762cd810fa0f18d39670a5c249bae19b0caf653e7364a1b9557d7998e8562980e275a60b98911f179376c0139a3350d6b8c09ac15086c3780331456f0ad7d40159e705d1f8135d1f5613a71b1c6355ab8799bc950aa4802602214365f90c1acec7ff81c87a1e7a051e3a14249b27a2c5c3c61744d9b61e7355b26189197e44d5356aa2bc235b599a3a577967e689d66c4aa966b9d0da431c6727016942b4c0b9f1275888cc6a25eba388780145ca83cb627b7477480002c1ac0ab41865cb5ad306b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda5835f8189a8f1829d09a379c059f3833e7af4593f6b5736f782215c72f8a30e60262dd776116ffb50746bbeb7565fd1a585dacc7c644c15f6647a25330e6e1301844652ccfb90d4d266e3544fdd7733b89b2326f0378d214b615ca423495cea4965fb586c00dc7243d423c1819be8b97a416293467a77ebb87bf724632657348f2a7b34aa256d0826fbe905267076c92262282291ea620b262355d067c6b882a64acb8aa6892cec15b3d66086a665054c40058c7a4714165a431a8c5021102cfb8168e4b80dd8b0c8d72cc8a07c064b83b5f1800b42aad50664cbe1b671d9373ff700cec873eb8a352081bf3fd9c9aec277cbd21eb8a4a2ec126f378b3b60004426a66f167154145b28770ba7b700b538863907961cf2271daab2118f2c40ac4989ab20a056b40c99a769b25c7a38d7b76a164964fb24a27880d7abc72e324a88a25466657c352486b9b17d4c13957d4b8ad26640c3a6223ad44be71535c3c258de440fb2a69f53e22103597aa8778127e971bb074b4dd704441c1bdb38274058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc5478475821b0fc7528d932874c47df5108f3e06106e18adde5a4e50d134c3648424630c42a20c0178bab98a67714c80922a3ddf431dc1a83a9a0c3087a45731177a22928551cca0e90bc229b95589259b9824a679a5a144c0cebd690620c12df2ab56c3a633ff6a1af01357b87108c4d56e6b694c41e153334b034d568f3880744059a214e80d3f477d67a332d44ba4cee7ab25d157b61416a81024dfc92f3650aa3e9c6f89a7629f347f91ec54b13997eda15bda0412df111529497284b312de5b4b0cc70bf0d2b643e5c2385133749243b678a026b415489c31d0b902f4dcc96981accc8abc5b08b9fadc35022b2cf5888d417b4a0a188d0a305d9ec820eaa4bb89c085f3655c0a2ab3962b069bb0a1ac6932c748cdc611b1949abe4a57b7af0c934c8c0696ba6f39c32f4e6874798bafeb70827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516c277a9588d9a781ddff6aa9ea8d259e5599d0adaba2f459598ebd5bc72786023ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = ffdfa5a0634e6dc6fbb03b34adddf3d909f04934883900e2322421fc88cbfde7c0b09abc772e4157bc04f15e0378e360c19ef33e7e05111136ad4d8c31de02694255b97bb83bb05a1015965b642d141a08d425141d4e870607b349257636bcb6a9a36e02751587595e40675deeb87a641c6a5a52cb60c1aac0717cf53f56c3f8bba3a1934021be629aed1cd07b55d5f4de711f7dd92e2ace7d2245f4fc15610d5383ffa40efd0e39b3e561329589d3e51f851ebcd218400f842c757cdd097f2cfc3c3c646459197745a47592b668feea0213863cffea5d2f0247b50359ea2ed2cc3191ec2e8b7c9ea9880fec929591c17d6a265d898090d752deb4aeb54edb85ecab0d4a5667b38dfa2dbf72837ec641188f33d236d9e54107d6f9c3aa56ec02ddb8fce07dd2e815b893e98d606e87959a34b09d184002d6643645021af942000296df0e15f277b20fd4f17f67b40732be99da749939052a6418d336698c95ac022e9268089d8f15dca44c21e50f789e895f6fba634fe07ebe733f67c320c7f20637a223500acdd080d889b783cdfb3efe600e420b0356d27898af7e4dafe5d84846f3e92fb365a14f254c2eaceb397bfb742cd22d2a114c6c702e2554b3930ad0719f6d07fc843f2e3ab2af7d7a22351ed0adecd8c4e5b3977f9f788e4b5a6dda8836e42c7c9c2a34f6f62079eb9f01513eb43c78a86a55af18d8fe5cb5df964c91dc1908f66e53900ae6e522b6c1b5329e4c285c28e8d76a478fa28576cf42252aa2cca95bd1187ffcae126c2b082441ee7555ccf13a4c665ee8990f2903a6c1a4377049dde70e391271aaa33d0642c160cbe18aae29988778f6af11ad497de92902dafbf5d2a672b2ecbea57dea1df787b048ffaf0eb195eef3cf9c2a06e6fd24d0e791e51affe06207775223d91f5b2c58e3c719ddeb217edd837ce27529f956bd33c874c7e0bc2b5f2d191887aafc62f02f1227e716a37498998fec0b9972f834c71acb00857a6ebefa33018c01fafee9d947241253fa24e3ae8a13149ab23edc8ef45245b48fd5029c3bfea79043f3ca64fcae32e5ef7463bc7b0a4d26 +expected_result = pass +expected_shared_secret = 0d95796efa11ef2b4f05d0cd9e1d8db26f3e5839fbba7cd84e00d468decc088c + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +private_key = ab994d6b166701339677e4b8026514ee41418f1a96b655b214c49e72d54652d82133b0661767a55b60203baa44f783ca78b14b4b9606895a937cc79095bc0f282862f86a7b595236c3f44017403b74148a00ab62a8502efc9522a736181e0205806544e4b4c180366a554019b078bbc5d0aba0252c1b447887ab6b08aa7f2beca0a783891d4a8ad8f11f6c052179534a9686027bac102f85cd06282c79970400600ac19c01edd69c1f0a9e837ccb0bba0c517574dc97551236b843e2b0c12985d544b88da34c78053888191ffe8852b9d86418cbc02a961694e3491b886c3fe4c53525152190431213c931100e108494f787c26c3a4d16e88ffe585e2b158f4e755321b09f1dd770c041518440aebe4629dac3b7fcf89ea9931def8a62f51ac136234e48722804da5570b41e3f041f74444d11e2c6be822f0d98a6fc23b77f2baafca1b8c738cd55e58e01bb33c652c25df081b8a471ba6bcb46ab9996b356088654e2886d7a9b05970958732694869c1f3e216962a21a8df9cd46b128ca64cc59277954110df74a4a51aa455e9a0f353434b611bc25124a3564359c407c11a261f48579bba788a499a35cfc40cc72c41a98bfcc7a0802610ead89236547ae21f6adc6515ed0739e3b9b240e0c19b2b05e2f408f4673a744716dc9d5bcd9a24389c6c2fec41ae4716dac67a43d52b25f02b4349929654abfb8e66c509c38bb4382c4a627b2b12bb6c6321da64344e91c5f989df559b0714b879975431c0448e5878aa3b0c15210149e7808adfac69dd8abf0123d10300e7a53806b7bcdd9743656cb3f8af63f61d7553d13086c71352410c155e89096d879acf5916e69046927a9aea15568660211e405fd0779672aab73452ae2948b44c67650636b1816c3fbdbc5848059fefcc59f796b6d6841aa6982b6664a5b659d7e9a5cb3e9be1b4c22828a76bbda57f79b0622c42ee95b1765292bd7873a0ea853fe46cdf521184fb230ee5284f07888d07a2de9d7a77c3006aa216b45ac1c4298b2d04a5c526096de329c9ea79d0de812b0f1189f3a686cc17c173265f72466aaea293af44462c1b01e0315240833d0f09adee4bbb29459f947897c4b882780c339019161e80b4699924a5c945c1a97c8eba4af258700126747a2800f81092649523dbc47ced32938a783461aa1bf6500f66b6e8307aabe7c4005209826a98a2904becd2853fbcabfc8c24489380bb4f7a1dba07473388508792ae1e7ca257b5c15c3771c92b9d07bc0b83c7e3371177985cb61b7bcd0083fea2075ddd321ce490a483a897cf6955384002be3016f6b9e2ddc5b8d5cb7c4f728e7966e13c04b310b7286021a5551a8b7e8472d969703f54ee4e1b1ae18cf1f6454e360c7ae481ec2b3b72d4049a74514eddb57f71b81b4405dbde79e05a1787dc2b19cf72a0a93b249b15fcc061e700c5325a40b880527f33b78eaf7370fdbb8eeb38e6c1585a12c160cdc7a43a7c45ea0b9bf18c5b5256b2fa2a25c1c29289a72f09560d54662af2c359dd87d9c599288541e36bc7313a4893abcb4ac8269c2829330d26b46cb666c821f49808c79eabc046b110c75a67ca59db9035b7061cdec3486a9b152856c360e021e3c25b4036259044347af18cbe495369dd5ba76ba917fb37d2314cf73607fb0c845463693060ab67785c1c6ba8efc581d21ec2a856ca54170190e61c8ad2c91b2a08791c1cd3ce29b080b342183cb5355b08d4a153c8a9b32bc4469d5557ab6ccc4a41d1f9b6efa405549e30022f64f62e665ab8934a617a4cab60567cb62dde7bd81fb69ee60a603c9138eea88d6823cfb3b6c0448c7d244ca70f5991618c3ff504734c98268f5770fec449ae6b4c47b563b9795a9d58f00b11206f4a26e6460af0531e1c07c54f1a61a86624a64a77019642082cd2cd8464e029e94085a8ab0352710c9f41c23ab47a53f2236387a381648036cb12f3f231624862f36084e1ed6b58309a03c50838a970ea14b76ca064756512b12e0acc6d4a548e63213c746877b4054c41ac3eb6eba4ca759223641613533c2382d53352fea4663d5a121759e97849e7166a50f139f04b2bf9609ab5dc238af2c0dd59ab31c6214c288b21b9b33a5c04845c6283ad0bc16285684d1cef0b11e8b324ab3d2616b71020993959815207b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02aed3c8cc315c4054d09deac08c6d5d364fd5d47a3c09041bee42c561f978e2d98fe1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = db7aae4d860aef5c9e6245e9d5536306065b0057d059c04494d80ac44d0c4e9f6788bb65c10735c22734929fe2d73ad97ca026ec83cfce550fbf3680ca63787e4a48866e162c620b3e2484292368f07bdf5abe38a0c2f548249c01feb4fdefb38d9e921fd87d5d91d3044ddfc2457fa5a81a975783ef8ff36e6bd0e450cf016693d4add665d91a476b01448899b959abb4698a22a79c1799443547327de7069f3ca56cdb964dcf245f302d63e5918ffb7fd31d5677396099b4d5b19b8e5491024947414cd58c682522b84ba8a03e506cff6c5391ea8a3aff70302d4f048fba296810cbd692948efb8377eca49ac6a47b15be7b26383d30824883474fa60ffea5bdcde813218182ee6ac82e0cd8b990fe449ee6ca3b42cb74654cb7f5a6d7bbcea81d0e8b01fd9fefb66e91ab7c5cdbb78a24063468e091b0c50f99880a7cf4a26a275f824e9a23287eadfbd4a425e7f6839a6e6033df2461cada26f9088da492648315dc3404bad8311f85589c59c193c6f1f0a8daaba797c0fcb9824f75a37a01c489d38df6a5962a80c0d4799f557503c3d64c6e5c763c3d9a132341893fcafb8d8ded3cb0bbb4f502d315b17446998c739968e5e1aae4ea917f0bd5750015d94122415ad932872e4123fe026e169578c95876efc592cc822122feaae5f1bb3aa1c665f95c5841e68e3556e1c8d85664b3e1da330eeb6e48dcfc4aa5d5499b246815da8067bd48fa69df4919de2248a77e5790c4813de37ba955b29ddc72cf90fc7daa869aa0fc530e76e6e4b95f71a3d3a1d6f36d416913f48dcd041b3a74252161b343f640463a1ae78b4905a66e71cf70ec285a947e1ea724d4a56347e793160d794df98c367f8a0ed44baa1cd63edaf7d7506806f384e73f438fceda2b88a76ae7dbd49334ccb189c1d95f758366628dde9d872aa8b70d6fba50e120bf08f3c9d276ac5d84a547bf9c16b7667e4277b6ba56ab75a5136c2d17bf3d6b568e050a63b0457fb168f0e6f375eb8b94b907101af14bbbd80321cc74456c9f7cc87a4e21e003c22a1c1e72abd47d484356b2c1fa20c3c7d1be232ae7bd5cbfc2 +expected_result = pass +expected_shared_secret = cc047c6cad36dd056b84e6b9a4fb6b1b349d593e104ba94a67b107b291ca4633 + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +private_key = 4a9b766af1a70935b674049aca04a9c07848a40467f8db039ffa71aeb972758959837c5caa6c9a2ce421ea23b4aea23f4ef4890a8576ad48016af36c384407d016854be31c79c120ce826aae237d33439db2e62035d5c2b34c4b87d546b342b66413ba1cb1be43b34d550c48cc640c6b0c95fbe6427ed086f7064a4c50ad6ef0113ae7130f23ca8ef57730c4817ba45732a79d5ee835bcbbc059e640787aa9edf182d6162cdc0bb9b89b2f9ed2cef4eb5fe0bca19ff21d2825710dcc2de2e44fcff46edffc7b31cbb42a367dc2e6899e19519ff024f6d6416eb1939737250d4a9eb0ab0cbfb94b71a300a648367d099288ca2c703666f4c8ae5c950c5df6457af32842fc04f78334e2d813933616ffdc0e35e11af7f4455646a8a437552d5c3f5ec5852d2704fa40a4bd6ba7ab65c048d4027a682e7f4212dbf890bdfc8a3d2a00bb65ab8f616bc4f34e2aac8f46c83686e5cf7bb58a6a47ab634c361e3871a8b9344f361834c22b234071e34034d7aac431392c2c85c8a5d4b69aa711206b1592e5ccc598c702f36a03290c9728a5fd837f16690954517d07e545bab88cc89916fc6469bdfc4fa4a35b9db681f102bfb8a24d995415635b2a5e3a4db3c937d8a149ccb742c17ac55a0b62879a847fa97c609a13b5aac012d55409f12d98e440a97a33fff52455c880df1c05b784b4d2c63b813599750727a3ec390cfc658da262b791b3cb08a7e977a3a574277db97509201686385e5cfc74af851fdfb9bb0265ad678ca2e37829589320f367222d50b2e263241f6b8860935004bc365c356ea396723ad53a8e367bb7e6cefd1ba24920557fd71624a3a51717c1d17cc886467acc304031917007abb151d91ab93c06d050c32ef97bb02676d96c43152aa3a1b63b26685abe966a89f415cc9c92bbc05c76f126c9197c230679340a95e52196b4e8c3327c644cd430c52b32e2cb50eb9329d03c851465323cb6cf09679df87c15740c50cb3b4a5cc1037e5461adc57d33138de0d4854e46106e4b92eff03a5bc0b5f50001edb0a15da8ae246b33a9135a59d3a0d5d70c396b55f2950da7f788a2ccb58d9b00887179c1e007e9624913b9924878c5db1c9e46faaaba1a2944304ed64cbe6b96c3d61b83c404c498f1ba7eeb8000c8381de471a50957b64a94c4d42005831f4b4380899b5b848c307fc49654438ea062719b20796bc39b72c34fbd717bff95c687eb1ea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b360b3de0055742563a1db2782072fcfa86945f83f8e028f80e08825782b05960005f37992fcc126b9c942a7b2c7a230c30824325228c971335fc3609878509d302c8f1cb7ee3b4a9e58013e2377c1104cddb2cf9f969794f715cc805157ab62b9b52d7e273c2f6b74f8e142b8473ea9aab2ba3cb0e1791831b56dc7d6ac7a41482bf347a63ba6cc072201e19949e7baead45a49922bea808b0ae8000aa1794b4a92056a51ddfa0e90ac818940b57408b9282c0835b2be2aaa417ed6be7328926ebab1bffaa0c2360e60b905834a9db8390bc48026f1136d48c42587693ddc15556e4472daa04d8ffbce175bac214b28b73c0f4ca2a521820f7206ce7daa7491050937d5c3608b024a97993ad0156c9cbdfca0997893a7e412bc5d6b8956385e00d7cb61696a3e94a98230c4295394079ac7b1818f1c4601301850735690abea3ef9aaad82b16b30ec4f7612364fda0f78557249aa1302d94fb9792acd5914693729531ca3bcbc42b9b2bddc768803d2611f01b8589809f15506ab5c21ce5bb9404306026b74b1685706d09163a74ecc51684757a02a9b5fcf21a59c17c894135dbaa37e89229a90130aac7cba14513de24611fa77063f4aceb30a92d3f75c4dabcc5ea3280edbb0297b7b2b842cff286e442834624936a8461752693c335916210c3d6c1c54f9ec4ed60076b281534cd497ec113aab73027d918d6fca080ec48b70c9b6cc57ac527276ff4ba3aea74270c230ab058a135995d39438e5f52649b17be2e5ba1890bfb484805c82a912e9046eb9c2b563ba9fb48bdc9b95bb9276f3d906cca8c89439c8659ba84d672e283890c468cb33877aaff06af640a9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6dd1a07043fa0c6452500249601f25de742ab44213e2718cf0ddc5ff6a2a9aa6a9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = ca97e3afc9e4c923849b77753c240917a39b0c474cdbb1c0d41b9367b3adb4ece5e93ec993d12590298d3b978d2b934723fefe4424f84227b825b1f42e1058d9edfa9fde207392d3216949b0f6088beb7c48ad234d6110e71d02dd44abd2a4d02c7b6f899cce3a5291fcb997967f1a4e3ae433e06a18287b8f9bd441912cf1f7b2c2657eb409931eb1266c5869e284bb886c69de61bdfb468dbff4884d4356acb301ad704e2c6c3db8cc58b3c50315f95e52b7b460117a6fb301c86dd5633bd11cb5a3cc8873703e9caf40cf81b51151e924567a74c9005a33bfefcdfb3247c9454fe4b2ead383f414f747731448e76938ea83674162cabb5e50a7230b03aa795ea7fa76a9d09bbef1fe34ced18398343f3ae07b3f41ee4011f02f112814ccec044d141ccac71996fd42a625be32417319031fcc1b9ea402b76ebcc9289e887aef0bed9f18d732455bfd5ba0feedabdd31bc752782b47a930234e967fae43d7502ed1273c1582fddd81e20d618605f3c72d196b3e1b0d78d4191557d457f1452687d7f5790b3b4acd0b689ed5414b747b7452a17b07202677a5557efc2b346c5c66f5cd57de02c21e55aa0664e14f105d417cc4b4915b5dc00c12838f5d4d593b121f0f40e7a5939ec83f6722b5e0a48740d2d801b8c1fcc7a9f6bbfbebd470573cd5911730efe9a0a6e5fa66f401ddb8fc2c5bbea98f02914a6d0c55751f83d2945a09293e6f07c7483588cbe64e8d948b6c263f34ad8e8352534f97db7fed06704a6647015f6b8cd1c7e7a8a9eeb582da8de50336b7c3f18c8c75bfc1494cb5c296490262de97e3ef100aa559545d8182b0b4d619b7274298b7820e75df66a47074f9f4e40b835af1dc11b9ead78ba8c3339b98a29c64670895016d1a6cb294348bafcd380b292d7e9d28eb6bc83b6af0118fccb8e6bf2a14c1ad6fa666dbefdc3b5658761ccc6e960f7d08a9600d140a71b8ab47ea85ccbaf180a9b3fc478146c3435557adfe33af31faaffa7967a7dc888f72cc00b67fae7d9a3baac1a70a849d557a4790e1f64a2eefcb1b86baefeef4452527cf1368cb3db04c4d0ab14 +expected_result = pass +expected_shared_secret = 2faf2dd50be618b025cd2b53365221f5258e175e4a445cf053c66b3d3a998c8a + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +private_key = 06f16b2689b409dbc0ceac88a1ea262a94b61951499ed4000730753f5a0103b2692f58cdc414c492439a3ae46b8c079be94958724c6d5a68535e5c0192cc3f6af8c601c8280d76507234c5c2742235265316e53365c4157a103d6f7b1df3f4910a965a1663131442c6e8b674f1f078a0738f05390698819556f424ecc665586ac387c0759eab24bf90a06afc5eadc9cce95aa1f7d19e692b211b21b33f8587ccb72a1022085c5b62a282c9d5880b15754e08971f50b769b65a03a630ac9030c06d1418338c3ac8815aa7acbbd9d7831715a05aa37fc5f7c6e4c92698213a750c842ce37110aabb40f47489a8af4f0cbba9abaef132944cf963d86099db5a5987dc7a5cda1fe5a0abf85b2b9c81c3b2784d0de87f311c298e532af380b84bd808d4a71c4e234e2ae4689a23038a83b703c1bab677863bcc4de4f6ca1d805701821e259818ce208948285e057382bbd8ac05b486e1482da7b2abe396a7c6c6136dfabbd4117fd9877f752882863725bc8b3bde332c1e242d2fe523fe2b951ac3003bc90417376f0fc27133c0ad082399afc9272394bb34387ef1b32936d3cd0ac599c74a03e6b2c20f95710d32816c043d33f13110aa7a79d885b51242ebc18add296267f7779500455019c9c3799c9cc050b85595ebac465aa01c7bab095b68c4b71468229425e60c9e708c3332c31a11e5b1b5222fc34b28a4c4331e7a1e7081927218ba30c9a26dfc7369e336e7ca5e32c83d63970817f85b0025ccc65789143961f2a029d87773b72141a3f728c18592bc447d6a0056e214b47e432c54943b10ba25a271b7689711fe145e11bb48df98208b3b1bfe059b30dcc17d63535ee7bc11d47a791a63b6c970e11bad82371e51fb0df938cfb3c957e19bcb8750ac1f5c585e4b755442957392212a2b16ee7848521549ed68c93d11bc35f0c598c44eaddc0f1018bc3de9bdfbac3d59663055315ee2223ab4e2ccdf78ad68256ad3259f0ac044e0c96128c38ae7f76c19a29390844fa69705278b7dbda8bea7d16336b1583f60c09099c3faba7df1c99cc3032537d7bcd163328ae299115b82fc6b0f05192fbd776ea2338c7aa35efcc6a7d3281c50e1521186b785d020868b5052a10288321f363986f6dc5d28033d8e0553d9768241734561416fb1f8cbf623ccb3b74263492cc0d3c086b448073804e3a1aa93d5b1a22b9e02360297791c700a1ddb6880b9413840a828c06c4b5c69a4ae68a8069431f35b9174020e61758ee5eb6e337888bd563e1ff6c05cf568738c2683c50ba4713cab600c55b362f2a3a0907159a30a97054bab56655c273897d168cd41519a3db96c0128803342058e385c802aa7dcb60544921584821b491a4aff9155d2118bc9357bf6e78faee87606941a82129e6a401c15f41ab886b0c262a662c27e7deac9192cce0740ac47481744ca938b901cf83771946c6edec63cb99b1817f5ad4c4285e1ab6c0186463c3318a5a923cddac59a7991bf4279a1324671153def59af647aa7cd454d532a4ace3c01e040789d867d8230095df9c5ae64b1f470660a753cc56aaee948228e7b31e5d50217bc034f351fc1264512b58c6a206b5f844f881c0c833bc78df4c936c49247374590146763404441a4377a105431663394ca183f22789eb9bb96d73a0211b5db155a304584b3fc56ec2c7edf7235ac284021c5771d760edd4abd556800f61c65a263306ea81dac64321fd869e1a369a8594d9b219c26e754e1334269e4aac5fb0424d9c3faea7c0b384006ac250796a8d919ae8cf88d63f848b31c0269a58ffff9ce6f436ed877c33ee72efb5695f9e9c422dab87c6b92f3aaa3333688f5241cc996052f7a27387b6d8cca70fd1273b6473d0501b4155719dbbc464747702de4b45d3c4f0e3a8fb4826752f3bfbaa08f97804f021acdc37887f69060afbc3bebf3818bd064c4fc04cc35658c60be55dab57aa810c98ca49b790871f1a5bcf235192646c8e7b84a24185bc6c4b679586e6c9002e0767aa47b8b23905ce0bceee95f84a1a529185a72a80a95d30bdd74b4a664a0c0864ef0a557938c8e02b92a5de767a27c14d4b4269e22b1e70a869767b1486513809b1b6ad0acf683963da5248296cf1c71295529c9889546b7519212742e86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715accf2a8cad42c743eb61aa338049ce917616899c803358541de1e58cbbdcf3c632871600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = 15d65ce4761f9b6294605daa078df2844415581b516941f7e0324ee9b9da5e209977921e082d18663bcffad0ef1bd0ef4e3de0f929865083d2644abb88a9adc869a65d6feff6a71161b6e5339795cea275ad40909bf7c5a443294a854c63c98924e1f41b0b1936b8ef3747b5c5345cb4fc84422f7058d3f2faaafd18597c9667a3563604f732d3610daae54d9a015aa0c8b86f6cef4476afb389d0b0c0584df617f60c64204ce0fea4732d7465a8e56f5e734785f71b5076521abbf6adaf2a91a064d3f1e0e0cdbe4366435fc4eed4a63be380febbb2865040919abcf06707e18830db6338790f2930b7d941365349d93606796a2eb85a83abafc4b1fbf610f948f0f941be153e0bc91938dd4fd9277bd2db0f53550f2925af336e037266ddd6975cb14fe752a468a5188509dfe54384715556f24d0db3d8d56d13011c58429473df2fc305c03d2a92088e7936946170d6c35d9c7d4139686919af847e2e4073e981644af3889df5cbe922c96a8627b15645d1908678a561d9ce0c7fdd2c1c4f9a02c22461301bce73ae43dc2456cad2bbfc0b45b8a73dab6bf0e59a29c362af6c89f3972b55791472d446f52f7b6b905708fbfd3a5cd59366876f6f94d59cd1e9a009acbc3369123eb11722acfb0c586e9844d397f9e55448834318e051dc69db03a58fac094a641717f3d12eda91354397bd8892a99abd8b241bd4ae09f0d84f8cdf23db8992576596533b3859113bcba8dc9f904f4455aa041877cfedcd950853d672f4d5fb041f30ae623b4a5a1b03f584e115a36f3b94924bbba2bc5a9f4510111c1b2bee8610b578bbcedff2f1e34c7f10026dde18bbca59645dcc586170d3e0c18d33a008263cac232f96a12da8c41a811b8ff8dc3fe13cae77718c079f929b20907c78afe647baa5b1d6690be1379bf03f27bf605053d371a660eeb7bd2c4ac84220df35737baf07a81cc1c1e2d7a3cfba06da738956ffe77c3d456b6116cd048f2d7d2f491a285ee367a3c36bcd1b57cf0469611e91a0cb0b59b7ca6983c74486e77a65d3cd35901a1097104e32d3a8bcfe812cbc41dcf48369aee4 +expected_result = pass +expected_shared_secret = cd890d2eee7f747441ca9448c7192bcc274e8b0c3c80005cb6fdb4691186d85d + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +private_key = 64a73e921150eec8c44dc94084ab4ac7aaac99dc29807b922e902be8c66b103543a6644cb437b4792815f925827360743635717d05b9b39c6247a51ce78130848c1963b7b7507b12aaab27ec848f2953c4272134c29c371c8106edd904a99c84a7d3322c55c1e4467715906dc56004068402a83179cc2c578fbc04ec2a976dfabc44e3aacb429ada191ca27857376a70b535b1d5c56ba0387cb72b9b46b537c1ec436e27a5eed282b4e7b86443842cd80be1011a9ecac84126bb50da5534d48cc8f1ae0253c203520f230c8c474c10715225cd66a0bb031c7cf4bc059bb69b9b6ec3e26406396cafba07de5ac445d60229f30c10f2437bf37aef6232a66c9d989b52f83441f046871b98cca4ac756ee8a8d8ab42b6864a3674b890713ce2f85e5ad2164172b8b8da616e008148e0ca639390df9acf29c829d39cb6e7cb201d0755819b90cba2ce8d18b4c80c065e8a6f83220208c40ef1d7784f589db95103bfd22d09d93b62cc90a3a161ba198fd1d087449a2f3dd634aa7a299c02b724286555c119cc474c55c1752796b40885c99c32635791aa794479fc6a4a989babb20b9738306244080b9a22399145a54a126d31770c9096b626a61ae9394db957711d7a38ce1a17b0f57e6b395f21c3be4590a6a45923130597939765d804272a1c3fdc082810b52e5ae8131157bfee994cab860b17402d3fe2bff4162218396c7a607bf526b346f45922d6753983a8832b7a99aa7ea4674464c33d55a6172f46a6114497b1a8b1ef835df4d1203d96cef9e43da9e97c723587c608a8c2d24ad0194164c944d56166450ca20750bdf52caca265adb71bc5cc06736501c63d626784713c4a575833d5029a19a9997c45d4649e3e942946f61cc5d3215de5b9b6723d4bdb44f9b9848c41cd3dfba38e71927fb4175a7635738487c7fb5446c2c92d70810ec9a827871215fc630e4b9a2dda4df5d6c06c46a60557c20ae26a1d734171e96223f22698055700174b118241b0063c13559cd149ae7f34b6680cb4a3e8854b030bdac739ba60653301a8ff4b63357646cad03d7b2a3032441d08fa53653baddf624bf2996f55293fe31b0704145a4a92534116109e3c0b8f904db4dc70f4ac96c1572248640d73dbb88db3861d108d368b30086cbc72ab177e1bc48431afdf3208df342ddf802787e385d5344e02c49192d105ac0c78c95253ab90cefd870fde5c5315821ddbe82cc1c267bb797492409603c8536640285d396a53c61632e227ae209622725e4cdc5768e96bf3f42e81b6afe853c7fc8381b4aa6070f2371e00619d685973dac323a1513200ac6826b6bfeb9c053508160700ef6238efc37bd5ac12ed744714b45db77ca4fb998745a6012ee042142cc29f9161c72c86f7cb7e834749e647a30a078de01311d908add39b062018bbc81c96b74aa702d4a40e7a596a9720b08496d2f3a990337a1a4396c291c390e1c4cd685dc9a635e7c69f7ca82eebe24356200268c118410706983a49134c2d96365fba38b992967de41ba6a91640857c020ed955a1228e5a44c91eac6a3a6710457baa88d4bf072c32d458b333345f9f6cba68e9a4086516f0641bb311c72d72ca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74b60886a19df5ab7d2f2a8390e44491901dc2b58d327453ae306530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4b81709da8191e2a2201c9e6fb973f7142622fc95d9876d4cd893a8f27db619515b476a1560949db5a893a675e0259e98625f46aa41fb0a4436410591470025305a01fac275d8cae99a5e06561c94e01262c8b878081852d86ad4270bee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912a50c08d17254788b0264933215c74c9ca4de4262ef880571078ec2695f80277e934208c8cac7528205ab523ac08cb8d29a314242606677a8b18616f9a3ae1b4856537831cca23447718edbb056f8f9b746f14d3b466a1c4419c3c155df08960047524a7b39ec3c5778837f0ecb8f49d03204ba6a41710b07f8589667c769b26a66472ab8217c19f2b3037929f8364c09821e80bb1b5b1c2d0078692fb01a9448cd60a59db56cb96b5694fc7b7abb48a23b8a12ff327a5419342577c19d30b0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd3394e8401245fd6348bfa697f6990b6671577ec7b35a45b0101730a8019426430e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = 583d94dd417b8f213c5ed3218bcada4238e632f9705b422680163c81c972f35d447bee75f03b29c364001f44b20f7a18ca86c369df7ce42253e26875c878e4fad2621a033df9635cc8858bbe773608962bcf1215841bcde2eaa7ade1de9fe76810b3487803485b5afba5c4efba4c5ebed878be42b46cacabcfad286ae5c94efad920ab525d5f391f7b0389fe9e24a30c94a0408f6af2fd2ccc0a36c7282a6068616bab9f05ab72c23c25fb5e513a694d0cc1e7a590d2a4e4c2970dd7aa8b48a0042779e1be2415e3f711550e2f02144869c3e57bb3653044736f40fa5c990b1a075c58d30d98e3af49424c7fd72768e029b04f06c4aa7f78426ef953c910cde469c6a9da510f32de2543710a54efcabf758ea0bb53815a6cfaf0cd64feb643de1a60d95969c20673785bfef17a84297afc872779c9a8ef94c63a6d388adf7e02b8cca1be32aae50e6af16cac23aa3aac347e2ee2c43f241191c87cc45abdb535505f66c2a329751d81496ab9f5e9c1baa949f414168957d39808277e6053dffa3d1c705fec93a5110740eba84dd5dce5c8c619be9fdbb1809932ab141b6d7c8bb22322256f25ef6da180701c9d09215dd4da7e755316a0ec3de523e9191352baeb100e0f42a60d495e00e7341eea2cf819f2f42ae1b12e469821d8bdd7f88c820e0372f86af8d89df5d43dd63ae36bcbc0a42e897b2643ded9312143ba5a0c01076274b216737073fbcaf52d9bf8df7440a428242d126c22b00a407dc5e5ace18f18dbb73fdfd4ea7fc4838f7e4d019a58d76b0990ab47ca380551f25a2deb87147ad5880b802a9dc39d614adc2dc6bf35a426ef3a7e1e54c956b061b266b574eb900a1559c8aee07797f9a084b94c1302ef963692fb365168fe0086695cf7aef879e7b5e78d48901213f4794ef8a732fbb5ad836c6b057ca07362886b8b6abff739700ef7e7d6adf53fc2be6f621cc457bf744694f5f7c320a066d0df27e556c695c4433d480a559cea09a5d5d3c34cad6e35e4cae6c7740eee1c09d5d8fe3cb8bc9ccb80b0f2189fbd39454e0f9493932506028cddb42b41fdfdf958f1983f +expected_result = pass +expected_shared_secret = e7942359dfb015d5022b790b5e777a93a5963260ae352567d3fb7e27b2ef0bab + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +private_key = 631c3a29ac6b4acbaa574210be900d21f402a46653a931b8d4618b3d366d35a7628fdb3e25bb8ff1da8c5872b0c65153d23a724a918e1a63b2ac4c43fce7a430572e9ab5a39c4bb5249a7fb723701bdb9f8f900ee363c8c59501f9c2c46b62c4f5fa3b17198b980233ac71aefdf632a28800bc147fe4dbbed75930aeb8023a33288241c373d9ad4e6b14d4092e834a8443344744069591a247cde4ad5eaa4a03c4c9a12799e08b73d762a8b9b1b8e7dc6eef601b3825c399b047955bafeed1124512c72482511117630d5567fb8b0d29b09978938dca053e5306bd8f8950e4c162060734e0a79290878376b7c76b8b1eff5c1aa30a1fbdd6121dd65bdd4216b8727b5cb3cca576035e62b673cb2d95db9dc532955a98b4d90b62b53b22a2a65aae25c08607c17f727da47385da4bac7d6857ff697c22235950b063773a6f15734d1085a24a0a1103e19aac5399608ac8bad386eef981ff5807d25c1ee5291c17762ed0d637dfb82e186893b86637404952877a0b8c8545a52ca481358f5033a90c45076b366f026761621945a3dacaec577313c0ce420aa932d964000aa2c4052e49f90c62a62fb2d377f76355ad961bd8ea7f24a72caee21bd8d4aa037b7c9884af59e5035fc031a053ad276ccc8863cf30a00fd0065770c3995ad637149056d5dcaa2d634969352cb0daae78d3059707292744a513493d13a28383f002b4928eaafb2941765927259b43e36334f7bedcfa39f22292f734b478f96ccefbc5dd21b585770c3fda67337348731080b48762b2f213c3a85dc3d810b360745f5527867586744b46ef068102cb16b0b49c6139c9dc6bb5aaa6863652b358ea322facc238921a0b5650a8c7709d6b95081b4efdd42f476701d2c65633795bcb38055f845f3f788c8bf73dc84364bd1aa343c306c9a548808c10e31840cd889c0e981ed9b3c118e93b1bdc99212788391a532f716fde86c5bba30d8b23abd028c5b788c3d23a824c86667fab2804e7148e8a312c357963db7cbd8b92efc45aeb43404fe78f25529b5aa3b64d0b073a46c1d3884843261ae396b1901c730ae4c22ce79a65a217f49001f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e0a1688182f35446c1e972a2f923c66d2c15bd0534d0b2f418c50e0d81bf309a002c100c55040c6e6b5433a5d47d2bdcbe84823c939c3f76a681982075c90c4c712d1399a0d82c6cf713e5fb28d0ee6368cd4a708508de1530ee89cc53e8b7df748b91ae45bf2a849748a3a54695b3453975082a39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680aff2a80c4c1a07647fc5e8b87b59c8bf97c235f0a56ce2a1b7608d6445b907f4b261dc55cca76a85dc8400895b4a4c03e7e65675f5479fb4cb535240fecc628c180337635af6ac6366c8a778d84980ba659f8482785b5b6fbb1a265a99012a41d5d13cfe07c7bd82cddcc98449d0a2663a468fe9591b0450707a95538bb1c22393f7813e68719a2c11ad8e311402885a54588bfc47c9fab18218bc49c87397be532c0127302089ceaa97102bb2cb219901ebabc69ad1764bb6cb5e7553810b923be76796406994587bd8a0c4216662651b2e8787bfb6b15b98e26481559cd3002c2a03bf0d53467de01bde0bac05e968ae266678bc6945c182d1d66018cc7762ecbb10012208c3cbf3d7671a98388a30b990a4674a8b7c6f958eab221d3e58579e521922abc0b0879b825c9d64791671fc6fe752bf49f87b606580d62c8a17d85a927976daa50ee54a0d186c6c48f61f6955b8afaa1fbc805a53e22ff192161d2850093816d7235d134623d3d4bf20479aef39699426642ac1c084ac43d8657559f817ebb31901f2ac308421a0ea975a4023221080b786049c89a6c451ac076a80e87192d8d8b19a6083b689b128f90afe044d16663fd2ba1ed717c17d5c06ced28446c88f30dc8d89db3d5c531f6d6b63d5d535ffe2671a625d97254223f68e89279198296db0c0917dc338b1b5b33e60210457970aa2c2caca854b07937ae6cca428b8c4dc96029c57ec309ae6e306b077aa1d8baf3df17110207b73d056550aa7ef171b4eab2e8f7990429141c7c518299733b734cfff884aaad95e55b4a65776256d5540a057baa7450574f1266a3091d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219ec9c0d68c84cf3804f14e8daffdd1e28c28d3d55ee782c98c498b0d9bd4ebb2350a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = 6e4059a833118a1b89450531c1c5a9523539a64deb37910815554057f870927dde17a903e3a41ca3a2ba75372a78584ef2cc03fe630ea5f77586e76876ea1f48a1b2478198de60933beebf57158c64de5ba3cd14cbbe35c368561d686cb264544569659cabd15db5b2448ff3231508df4ea379e84f83ac166b94343d3de5c0709d243bd507478fcf330aca5c795571b21320c042719765032621a37c38116c4ec7b0772067f7c0d54d49c9a2e50d42f96a348c034d5fd11011f1748a7b479dc5bea123a3f0d7495c5a5ef948512c3c61e53bd7d087d8c2d8a94575ab04974fe8e9d77bfd593ee0c0feec1f9f74f3ed6a5cf57880ab5699a460d3c19183744eda429010451c0c7a95d721f3ce32f36f2ab850a425c0936b909db7d709a7375cd6759204774d724febf578915417486dfa7fd654b31fe26f90c8d5d49a3199fcff707a5e39e2bd41518a0ce39724a541e142b2019295c70ec0911289116124480a178f1b0527d4eb6040dc862916b454b20104fc7d497b9e751a3832bccfce92e8ace8421988f9a177e4598f19df8348b187aee744ec623294c7efa0ba1684c100265c179e183fae81829621e062d7ceae2cb6891e1485d7f445f72e68846274e5befb9807b8f1c3461912e1f1f6986896015e7ec54c12f7c56f76de4c30aca932d9368023e929c338d504ef7c8c8110adfa29651508477b2c1e1b49eba441333342ff8322b632b5eb067cdda030ab061a5144edf85e0992ee48ea8c4a820367aabc482aeb184348fceea8d183cd029bff843f2aab52bb08092b55b06506cccf5c00530076b027475f6db5c12fbc171bebce17a6e1708f19924d1e06e192f48d36f8b87067121a6f0312750de6175b0f70c70ecc6c1651b237db6a520201a61c17874db3d4dc023e4138342498813bd08470cd834877bf1e92557f5d50f9b050539e6a3163b00c53c5340844643da03ab3884fa84de493e6754ee573bd49640d72aa1561ac29f4c6011824917dfc8b89bd4f8045939b5fb07cf6b06cfca0e9634d895a6bcddd6327c89e73f7c390f562ae5187fa72aea4ec737f3cf0969923d374 +expected_result = pass +expected_shared_secret = 5d7b6ecaadbae69fbaa9e004634ea609df6ec80801bbe73671f4e52169cc9683 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +private_key = cf32873eecc1c6215a531348d22060c1e95acc1128c0e0accc6c5f824a4f2405bcb008785a893962c65b330aadd5d2c007327ef6fab100d52e0da1260e9102d19353f29037906ca08c76367bf669f8b5a4e608a65558a47ce017605226640bc53376920ecb192187ba716842fd67045f928d5df21dd0ec1f648c58e458a86c340c0204654bf7788df525dc396ec7292059830e118ca3b2804e2c621d92bc8c7d00445ab36c38faa84e0697a2a231d550ce17aa6d903b44e9bb9222244a251a7fb2a8bf5393989b1b2f4b5897d2cb300c12b1f763704b26a6b7e1aa5a13a59987c6d6398be32c18f4721cc1c52816b17037d526218a4ffae04d1e22b95e44b9d1e2ab370507095b6062c1b98db588b745571621a5881993580b17e533b81bf1a314311d08cccd1d5a260c19b7355b68d2e5ab671cbcb5aa5538079fed022adc9a25e48b279e47316d634c7b2b1f485391d1e227b61355a38921549ba88a228f66e515e2b31d7677a13d254551646df15733c0f7420804782bf2b520d6a5760b854749a0e17434c49348f13acf502311f1c48e3fbac0dfaa67af77699dbbc34842c198d5668ff3bafbe60abffb3e80a852f8b083e1286009006a23975783f686593483c10054c5a3c9fc8a6553890a32428b0e773a5db9a0bff58257d77baabc9930459d78ab7cdc39a8ec5082a8b1a66b864523acb151220f830269537008ca87b963316a04d2783d857d21a708eca07a701a282025a26b88100772a751acaaaac9890f4449bd1971e45a9f0ae0697e43a27cf7bf4d65583720a63daac323e7ceebc6a8a8819d9752409eb429e6b85adc2a719d411da5dc24e4003772c11e58d849889638bf57bc2d62ab87a4b7837c474ec146a14c543e7a37b258c83f587ad2801dce56bfd8663db8e5a9197591b4871888c084512aa2f624c716a02023566e584155b5a784a964b46ae67c978471da9060844a3811bc67ea87a9878747202c689ee26109cc22ae93ab24c032b8b332d4bb1cbc72c166166c1dbbbbc7d70df1c49c2df2c388e7817d462afe9a3429305e19c929fc065818a2c3304723184b756e1b8a3ba66274e66d3990a19fd84badcb9816036919f23c61077d12d85eb2058bb4b3369a040c5e61573d70c590669f0d394135e30570dab863488a66c1744a165c2e31144ada7b351083890a3d10077f2e556d0271134fd78d570a2fed451572d4197dd90fa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a3c154728080f0e4b910310ce1c948007990df2108b4544354f92a1fa6685ac203c11a58eebb3523b47349fc2ccd19b33c522ddc60cb97671ad011c150a29b51249158d5a131d3583196c828912e7b15572db019904a548e0967c91a684f4965bb3b3e8c008bf8531f98286c005b27a01b7ab2c13ea2c50133c3431db1c66a0b83bb92302fd7948938b4e87c7ad2f430c6516872474185d804c3b8ca891b95f5d0893cf20b90635c84aa260a48aa7b9b3c14130d77e3994e952cf52843069a42a5c285db221d4f492e152c03a51270a35738f51aca012560f84a238da294f2a17bb36bcadac68baa40b110d78966f6bc77b8930bd708a74704549560fc59769399793c26253e67bf4acb629138c277f7826cc00bbdd61dd3b97c2f8277696387196950e1e53b3cf40164c32162416308761e72756c2dac0af7945dce06571a5bafc1968d25a6628b766bc99a5d43c219161ba16a20c5b2075a62d18710dab472550edd2229f8428717b58ddfaa67025c3e0ad97657b20d3be467db6752747961713971d5cbbe287937c12872d305a128f05a53e56b43292c7ce2c2a360381a8610f1a0cef2cba93359c06b3c74e9fb4165f187376a55fff7ab9fe872c9121008579a877099581458713a0683a9425d6072c6b813048649a9f5caa4c606c1ca2f79299feb0ac1b277cebdd82a2396a02b272b4ad196d457838a262be3918dd3db84d7d821ff3aca89450478e8c10997628f9ab23fdb0077997a8ed5b26773377f7a466a69ab4e10b2d93899c66c900fc585391805aee1677695cdbe264158816755f69515d1c3d76046d18c18e07300fff2bf6776cc7ee87000815ca4e83967bc37d366b9ccf74870a678cef2b13a7636d1d311dfd5a37aeb14a3c51c9087b00a2911caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eba9d7d5a52aa2dc226832f6e4603322f60b1dc21207e3360712f9c6445d37e64df072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 5ead2d871610c05553a64024ab82356e63260499ea33a44c47580c7d2fe200565a8ed1ec0f320f855a37b5e2bdf47015c18eff5356a9e172b47dd0adba7a263d73e013f1fe8919b9696b2f5be8bf3ebe97c3f348337892914434a2ed9250ea8c7c90b126cdb2f87d323a98f160c3fd829c086862e77225919f1bf1177cdd51df07906ccb277293163dee1cae366f625de9c534d798809515e0c53a34c3e961784c9b5b552f7d323be6f97e9d532ebd26a4e3169922ffbf39fe12d0e8f409ebe1b8fbf1a8489e32017e00cfab878f2418b1556415179b1377418b53f25c7bf4ad8d38ff83b4c476fc88e6736d4a5fcfa39921d1de65631542238abeab7302695c9776830766a73d0f815b03d832a10b2f2a76bb674b242684d158c658e0684268850b874cf0db2f774b5e6fced825fd369219284890ef92b0ce3bf649d1d897810ac8d17417dd54df3c884824b13a2b256fc363515a103aad47d3085ee1f52a71d4372ab3eff8cde8da2fa74d15af1a84a0eaa052a9fab407aec1f0060ec2bcd1eafa30f9b61c97ab1ab67e948f406d490c977221774198d084fbc626d190d45da4f2952f3191851f51cc0837f8f3274ff34deca842f32bc3fbd54790fc2451a1e8bc7579f631717e97c06be8d61ffbdf7d92bfbfbf52fb93690b5ce1ad3b13b6cd2843b31015597156741d0a15985910218f5912d88338f00ef7e21d42be8b188349e952dc9f1f0f3969806a962a1aed65c8ed0374f4e5d5ea53c99b753924882f072398585c79265c37ef4f19d59125e5639430b072e0b349ffa6911e8d1df2c44202f3aa24445e58296a50fd6c775026ee6b6cf820c26429808242dca5617b125b2ba693c3fbdd672739c7c620624428557ea4d0dea046aa554f1529ab014448a9b1b27207d6590944f5d83fd6cf71a1f8448879b200f764f47bda6f1b785b2976dff1a503e8a6c3e558062455bf3ab98139d2eb429a97da61357c7ca657ca14b681c88fbbf7ae541f493e7fa89eaa30d703cbbb86384f9c96d87848504bd8bd36d708a224b71cda1266b2fe7f68ae5115af37b1e59ae02167a2cd3e82a9c5 +expected_result = pass +expected_shared_secret = 547666f6c72c97a8f06fbd7cda4279165dc82489aba2119416e0dc46795bc464 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +private_key = 9388ce90930382aba7453a3493f87804172002e6c55852c72e550ee0f018afa50499c20914e6575af217cfec0c55d627e29300419657a6575552e35f5d243535e36932aa98f2a64873ec6b72962a2710296b3a74f72827b51a40f7d0a2d8544b586695887223ee1bc71ebab898142e1c4a412464526a7362af62cab1f9bbce33444f43afbe016a0d67c6b65b7872f3c69dd60adb9443e0766005f4ced873a9a22cb99083a3b857850f51af8c3571f18949b932b77e9b00863398355bc97cd07204606cf5eb80092abf1e42ae00315c79b27979d0c8350942dcc3ae5e0086450171ef17a0c48b3387921b92dc8c60d0c364ab7110c59a3fe27b7004a7a0d10f24f66c57d15fed49285b995e4d198d9fa90e46849130167238f24aacfaa4419a627b30c6c8185a5cd751313a55729b854b61cc1ba940a0ab9dafb241b3f81a590c4903c54a43d790c3fc1e2176b26e40375c294839516d0de4615e16302c935824f6528bdc22355ba9dfd77e3a0c6d8ac36011bcc760e6c04175c088d06079709edf3570cc259b57ca85b505a5277a92a5d83f332747b497721c707b44b0471638966d5319a6928f4f10396d192ab7eb340eda4ffa66284d5a7e303175bbd0ca25b2643a5571e8a74fc1828656d737c47347ac120125f12d7efa06d73c2dfac4c38fe34d1a393907ecb44834c4988c7a59d27b26b32420e98723c09fa8b19b730bcf672cb555e3c4bfa1ac2aa2876ef792b5577674eb7ec635c1b692017346bf5a24279d018eccb9aa3e04065a73061d8115bb208277243709a37139058e30b8549b2c00a54093e9d14095f13a9f5b088f1057207096091bb32bf4b85fc3c088a7cd0db9c4301374aeb907b0a73ae15026e0900cce347f2f883223166aa8b012e91b5c67d50d421bab6a6ca88fc373a2943ec7e51651a13554c30de5424852804def43b72858185c38040d6532e2d25b6a6970220200ad352636b4ba3ea8466ad678bfa958472440d5e445c4680701abbef7f2612faa26bba87da1d8b8bb1a3568144a568c4b112263a4a5292be317dad102ea5555ca1b197341040007808d68b38cc33e478b0946e4646e934c7bfaac517294c2a75357f1028b8c32e1314cd097471f15b35707a28951bfdc88590d464750a6c7b5b62c4218bf9c152e30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1ffc00e93475ac669be33808079b2b5e230f838a8b003d77b97672844639f8b7042ae6343f681fb1f77f3c11970ce715b8033ce11c9089c9b79e9470b9b64f4feba92067988297be29413c609a3e245866dc0079ac61a61ba1c90542ce965750f2b57a02d19f59719af9191e62a1b64579bc6bc5b1b353a050d913eb8117c525b8e2a417743c9eb8e589776b885c465e4d02a51ed7072d69c8912ab6493bba5fd186836623dd635d8121ac8b97772b671d76d983c513a45e4068c6636f6f1c1b21647ed762a3fb31615e781134075dd3969366527922868605459a6202428c3b94497978429b7e1bd2384e1154bce5396f71ac49aca4c426cacd1c66c0a19918104e1e6ac72018bfb18019b9dcc75a020c14e35b3e7759487b089a45aab9773125f61455465c19a062ec90954429adca61a62d20114127312dd52903604f943ba8f3e0583341844500ccd7e06403a95328e02bd3ea6bf3b721c2049360930602611f5e9a06a795a4b1a8b8d8fa7845a12d1dd44d9d67971ad0ad0b3280b9f996d3770890582af9757360e7208c8b9766c8c673db52c22cb6e167191d11900df3b2190230f01437bdd8145ce232a1737eecab8b2ca1489d427ac74426dcd39e12a8b510a0b6eae269aa4a0f46724045792a27d7cc343459914a490a170ba0c27e1405639da5141673b8e9606cce509d353abef9b7c96c2249dad3320cd189060662c11069b36b1c75e561fc3a20631862a9b531c41683c30b7879e0c03c49b8e26c7bb59a2bf16950cb7c5eb326481a9161691859932c430e66c1d998a1be066648c569698285695c08d004586408360bb8954f195cc5198fbbe3c16a32c72ea0b577914f5590bf189833b9d38f27433d406a88876ba754d86f4d9bace1665f42092129995fdb3b790a89a2f1fcce9c2048b986c8bf16b5cfb5b4f3d21f4ae84b5057c1ad5922bf15209eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddfa7ba132b5dfa2e3ce67b64bc72d551f3290d428cfbd45ec026f44c8dc28334d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 3de423a447032c7491d31a02eff8be53b289e2e744f301b962ff2781fabf8d90df9f04874361f7fa7b3046de234606ab863f9bd2a63a4074846126b9de7fe2ea6ef048b9d5d3f79398d6aab2f308347291cb8749fb4b642bbb7b4008801c6d1a513ce97de8d674595f19fd4a0335509af86909990001f256bf72baf0c650d8338629d0819e558e7e2499118013ec2337ed91f71495183956e3b8727300b0a1317e9b277357bc761600aee930671e8475fec90fc6a978a2b83cb1e0546955cbe21c14c9ea83631989a52f42f823f955f3bcbaa3d62b72ce441dd6c7f666aaa1020838f7268b98f392bcacc9c7a97e629f9af67cc7bbf2b8df9225c835a5e177766d8bfe67205a90261360963809dcae2d9c847097d0b6a69f0e251814656d84add3d9d7bf54322eea86818526439b4f719721baa2c0568f9a60c7401789b96320140581f18eb326c42ddc63043a7f0c2f8988d7e87c4d85b20db82638e36117d019dc3768260cfd25501b22a3e9fe68085842d9ebe1c10b29d3e67200440e76cd014ecab987c7b587b939d63eca26f45156b88f22fb6e8ab60984a6d2687f9d835c981c86ab34f429bdfa617935e558bd717aac6855239f8c4bf550169acaab015efe104e3cd0c64642af9ef019a01ccd0cd4015317569cac48675370332e385a1a6ba218ded34e2d674e39af443bd79ebf8109af1ad9b06f3126c88bb0513caabe06495b6a618abbe3cf06daac2a629586c1e59380f682d181e92f6d2c025c29bbd9b63e867b5d899ea2843dd6b66342e023508e7cf667dca6ccffd4a2e79a4b30274a82bed3998a4a207782e39a5aa8728b5a226297945b2e8c3171d892a051f18f219e8b6af979e93664c886b925ba158834d82a75db6e4a330d77c8d92a7ac0b67c6cd71c94356c51a63f5d1c812410c3b45aba6466b9fe5043bd84ff80fe3d5cddaf52febf32bf2ec79f66bf1f7682c4371188ba89bf599561bd454d7322681a88988ff8dbe44ad08d420fe7251cfcc0623395f09203c6e3de22a429a51e0d89b9a20447e60ee8392810862f49775405f41dc919145dae208eac80486410 +expected_result = pass +expected_shared_secret = 88c80381cde3db2c1d40aedf8cf923b79b18cf76efe0e46edc3e25e17c7cd8c6 + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +private_key = 5177b63a55465cd09a42fc7c26cb3380880f239415c318be33e486582a40f3a685c060a916ea06b5dab029c73a5756ae52ac299b16151685611bfb5acb3465a591b015bba901765d2c22222338c5de7944f17487d7bc7c444840b3c69aadaa3e87852446b63d80e68e24ca02775baf035a24aed04ed5a54193693006c326f814a7379aa4141320ffcb18e2624e08e27952e75d0aac6cb4b27c9faa6850c035799b229372832bbca68ca915009b8ec877548fb657a73bac7556aad1b6b772f24393ca11eeb53d05d6996c162d785bae9033a23e78ca224cb92a770713d5150cfb8fe570cd24b2c43c2ca60b81c3243234bea625f3a05cfd434688610a7d46bbae25b14c207225fc0c60326cf33566fc340d4ec8b1af40c4584828e7709d4042016cd5cef2b77f5c3b434053a5783a761c1357c6706a490314d8d7c6a94289bb37b999739098da95d63b6b5043036c7a554f148d511b9e190a7f10a3a5f2581002938f2f92678ee28276443387b28a0907641e4371643b9ee4d5a0c2c8b6a2a01c6f427fdaa38001086624f805a7a1b4dfaa24b481c32fa280a8d85726e08f237cb3909b20ec51acdd7424d4c74f6c67bca4b6046b44c16c54a059666ea12c5e68ab7c62705043750aa67538fcd470f09120bc93b9ffb02110a75e3db179c20b125f23967e20b32eeb9b2af1c9927b52834b89e32295bf57428c2cb67c231e80d26e122353186c13ce249b56fa668ea4c599ea62c57c65b0360088fab236b3bb76c60aff1c547948212420b3d322b4770a15ac136aa279918d9003d337ad1b78cb5523903a5cb32a10c17c820d6bab430bb3926ba34a11077ab834835fa78ebbb3b766c25955e46cba5818b6d729c474bf76eb706f93bf74f046971aab7859be78a3a8bb570cede984ec72b5e53566150003cc81250e97774f273e629188e3141c8be771a53a5ffa47126b1898b2512bcba038781304729c6807c3b450335658f3a41ba91795709ff0ba02135a5c762089b8e44deef53a280a198b8275d2a00dfaf27f14c93fc4e949d03561536b895daaccb73506f94a06d5225d94e7c98e5b26a764b9e7abb0be68520a095bca8946289731b5d068114acb1209507e9b20831bcdb2b2b6610c0031f89f6d408003ba57398b5d4bda4479134350994a8190cc1ec6b8ea0905cd38772789c9873a4cb6606e6a591410125786d7140778975c472077e42416d3223d69ac98320de4a1bb45761f04178fb63c92c71b24ff8056844455a45a37969b4231123483b341ff6652e7666ede163e9b614313012fcfdaca544b99cf922de994cf6de08799586bc5810c5c1c54882b935c52046921963865c0b82b5466e29eae6a62fb1792f4e1035308aa5ae81aaa524533ea7a000d7a128cb83bd0587138c73d66b17c585f7037be9c0089e6572f2f68c5ba09a532326419b3c19346267d8887dab82fb0176062f4c6e6707ec2ab7448215e895908d82cceaed528ba75114c7609e0b6b4e27b9b14bb8adaf0413d354f00d33409d5a185d1b95c58b7a86caf903c1de1ab16aa2054c13849edd469899780c34b8c423a27483abcf4c53b4bf2210f602aee904d2dd879054b69247b05f3b86f00a1113dfa29d47bb006a2b1fe8a540021541f412d307433ce71362f639fe39912fc0a6ae4a33ab4b07cedd1813d0009b784bdbb209a58d66ede34bbfb939c09abc80d6c71c550953494c99881a1f874791031a8ee2bc7760cbf75d82bee11668be002255b7a0309527d63bd3707a692bc3d3c927e0a406e852a7215c1850dc9aa9b17af5dc71fe9c57dd5dacb26f95478613c878b7694d74be742c282991dae15267cac6d2bd0b2d2c469bf391efd470a19d59a6db65710ac98905520c863927ec80bbee88513d70d009370d6b04af5ea49e6263d034228644307fb407c4617b8b7977c8f2c8bdab888940c2b1e157193830def0804d58b8f380316f60a3c26e27581d03351237cbf85ce4252c92c19c7a842201826cf698a074044b9b8132236ab6852718e09e033e009a1e8dbaa6ce98a81fa6371407fc2619e5aaccb94f1c8fa18236570abdbc217a0489be14aaecaba1c631b76c5a996d4bb842bbcce6798255d7365fed744865267da794cfa97ba6c7927474647a6c952a68954369297e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad29f8a01ba71d04d6831c03d1ff294fb58ef6f4041772cc071074829c32a3ac9d36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = 4e9dd9f50c039ff75f9b9340310a43a920849cf1e23cd46548010b2fd4ed0752687f956f9bffb4099d03366ab92117a49183512bdc028a781a1ecae340de7c87e6d8efd1eb994d91db17e15e52eb1160b287e5de0bd4aabc140d0b30910358846f520c6944f1a0ba6a57b23724218805d6dab6f0e828b3bf6090ef05d0eb7b93d18eccf19f2571ab467643107bcd2db2276ceb90df30df458e946c82fb960367e0b0a86838a4b155e0d5026e19bf43cef7826aa67302fcabc38899ff6226894aa4730a3a54886d7541e1d7c994cc31e097b3e32f7a1b3cd4c8d349088efb1bcbd60f029429bb686c1a01bfa80e53c6fedf2c462dc573d1f6ee97047a3f0c53ce4c6efd2c7980d8923e70e0b00eca1ee09408affd0b06d9aff7df0e0f81aabb1f1ea477ef2758738bf7cbd6a97cd52f543028b00f16c50b87ffe53d17de0590e6fef5f1ceb223a96ef5afd4bda3e699d28e3cefd84ae069d4a6e652124749ce3e0e3244c97f9844904a26ce6170b37427b4df556b36f31d63f83e400fe28d7a0a018c9ab23ad45802c8fcda36b2f22ca60c5ad3577255b98698412dd5c0e0fca267ebfd0875dba2ae286aec6d955cbb104f80837966a600ca019200e00380689c6cdae7f58fbba574e0a5f26fbaf302ec310c1a53488e2592b2b8d8077c3daaddefd9c73faa2de7f1c2be2896c3635846146df679216332050a3f6564f8861863a336970005312cf06c14c81ef3d9a8b9e53adc27662f25cf014bcf02dfd121a0d98cf7c7a988523f5b98c336dceaef7ff831c0c329d479a7fef21ebf1a6ee39ce801315a38e3722b970968799d72f9446aa0ca103c0d59466e9224e6d55227796bf641139b119d1e616bd811a6744b8f489e146e18f8ac6b18c44b6960aa2a4a0d63a38b107fae88840df3e2439bfee676ee690066d157556e763852a6d6f6ef9028aea80c356a5b4c615ff59ff04b9a06ee788cb3584d096719374da82131ab0960e7d2018ac0b14dd0c89e77a11b5d3df3d5a4a8a9c4da834060cda8130fd4a69ed6bde96209e88eb531578ad9a1ae9580fbd5f05354d1f569388d3427f789 +expected_result = pass +expected_shared_secret = ccda9f28bb09dc0017a1df8e1796a3489c66afd2c3898a39027c843cf022b790 + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +private_key = ae066432f2585c1097a9495a937589eca954fe6b27510a58bbfa35c166a0e697ccdd7a7a648a80e09a461ecc9a1e9b8d288c488c48cf86d9c892b2c4021cc4d5194ab3ea95ba7b73acc48568d9cb1c682bcbc8bb93a8ccc091b5fcf706dfc131af4911a947bb84002ea9388f47e4a0feb26ab1ac35b561bd5641512574647a4677e688610bf9a545f385f9b843a76952012379ac965a1afa8bbea16c6f198a579a6733a40db261b9aa449bd9e89fe72c85171b6f27f45e3c0c9664d7b0661a49b18b5180f760b4a99ebb0a2866d70825489ad817c4ccd00c303a583722a686316261607c1d6cab86fc126cda4e75576633b91614846dfbb35481508c9ca06625c49ba41aaf7aec38b49663870bcb0f331296422cf1b816543b0bcc3806ee113e23d4bdabfb5cdf173b22679de771071ebcc53903227a836084db363d251fec091296fb7556cbcce562ce54b24554e7c6dc6aac7af699aef7b8dea52465557e0fd07547f77d3ebc5a9981cf2cc7729e9aa228f62af4a8bb656932fae1adbb820b96f27617d041de7972ede45151805a59a58e3ec57d02d27d0bf448187413fc886c03d0782a8592446a414a760e5fb384f542cf0a99a57ad615bca14043a252505a6956ec64a8a4603b34426d67a629b278a9774e6873c8d688a3a5eb0690f459ec98003274c010331d73fb34595c1598091f64809b35aa05497b58cc5c5978c095411b2558c88ba2ec756850cc5107b06d2c6930caa0ca8a8eceb3097c759364992fa5d964a70236990024f72039adf5883224b64966c1d98c87018163b21aab404a697db5baf3a1626fbbc218a04ea1e92778bba3621618255257691691c5a3a11a4c1e12a5bafefa8ca3d4bc2ee98faf92accd6301e3fa3143dc6f223767c0112f26cb7e90095f6a116898dac9528c64faab8a8f0828d08302ebd2794ee71cbb47176f62c19d80088d40297977653a3bb7ee277ce0324b9d163d2506b872580f4b60971657cbe1f322a85ab5830599b4dcaca4b73584255f5fcba21e5b966197a5be218149f7cab9a0af6536a528873a20cb8a3830b84a67841a99074804135722c4c5abc6ba118828263017d56e8fc3871b503a8517a0e3b8bd8192746e211a1a09923b761b20695f6a3ca01eb62e7f6b5302f54b8de33fe02b8fcf9c16e7c552977735139877c95bc69bc704fe94c0333115d7ea091fb41c146c07f487961c83b1b18225e91449c961769a7bb434a93da88531a75c207044a46623acb8342d59d1455dc434e2d2bfa5c30b9807789856b76d3a4c65d642fe65827eb7040290c21f2228e40251680aa7aa106a4e150d3226b030407d293929c20bb1afba5187b1c4a300749a323168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439c30850b68f20d860ba262c992c99c2bc37eee195d2e945c1d6336c990a77e9af68eb8932eb3325e362db5a77980274aa3b699be212db904e49e326fd445e48354b1609c0942735dc6480c53bca3c8857fcd90965f61d4de0509891272d31a51f3528fb17acaf669efc1032a4240f097118697842d79239b16313a6f74aba689aac94936a35a21331961397029a823d443244f49a445527b039ec8547c35e83fc2d076225d72b7634fabe64a103283434de705bba284fd2241a7e161435c896e899579caa2cba03c53ef74ba3cb30adb80b94bc407159a5d3b35f85b3ba3491c85b4379cf6472310335dcb0cff3006bbb5c8c37e3a1b758518d4c740ab5358cf8ab6cd92542a79a97dc4498734c8c9c36baaab29472a9cb633ce5d30039bb53b03978c51402fea962b70506642b5f6242345746abc312b6625a96443111a2c78d674a755554266c5089e23c9b63ea4b255890f577bc5a442066a2c448771629b542d2981093e49961f8a87a93c068e25167483872d378c2445f398796970c92b4b42aaaa65771382b53d8c79a0258cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d61a0614f1436e3623a77d38abcbb780059521ac7148c088a89b916a0103f477a15a68489d5f63cd7c84132aab6bc63a5dd30b8f27c835a738f1f619efb31509cc9205a4716b64a3cac7725b79c8c2d304ff4a60b328013fe6cb99d94496b363d03c1a278532780fca35473a000291d8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968357376de9843d74252466888727f9dc1ef48d028c0f52c902aa0dfc3de374c8375d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = 04770373466d1566c3feba571a52b23b743a851c40c59610cc7a6851bca9b83e69bda93360e0d900da2b5ffc34607b1d26bc75cfd8e2d5cb0fa77303b50ee9b0eb4bb55e262a937bc69fbf0a1c800a3d52cab542c63810e496122c11d8e2d2415221522ca95359638c57786f184d093d61e5a3f31bdad6a86aa7084b565a93d059216cb7901cd4705e3f14400e5d5e40a18140c032cdcd64691985bb9bf09ee6c9693a95a345cb405f792c2bd73f3adc17b004ee475cc5721aca4af6030c7fe9185998bcf0972bd6b5a940132c360604ac04ffa25104f9333feef6eb11a13b7c46f67332becb386f58db8714708653653044f40d01cf561997c98789570a9d882c77b5f8db73c366ff5207985326c92c12d8f02de5382f80e9be096206c5d9dad8c68c2d0a6a13dd4174cfc96b34d5fdda384a5e2eecbd4124af20e0a72a042596ba0d02eb199df52d087ae8bf18eb484d6d3b3994d9fc63185b7a5d3be0196c91c9b92957045eaa0192b95ea263d106028dbeba6f42d8465901eaa4ff42768c314deed73737d4a1eb21b511cf17626b92a75914140d820465320be487dd7d6be1399ea1576102b41531c2603173764931c98fdfc3a498f57d977f9e13339951d7f59406d532a46e4c76f185a17b3b3746d887db5341d5619b435543892ba2e68712b583fba2793c217fbf9e417616f4ab924f86d616cbc5d9ab0c303be54bbf0a080ce3f4549e94f55997e528318d9502d6af2cbc09c13227a39284166f258be87783d5c2f593fe956b16c24ba17728586b3cfb8632a057d683ed9cfbe8f19bf7fdea7d73b5fa3297ccdd538c9cf207efdd45a70758184fb8a43d0761e83141e0db44367529e3ac59dcc76d6c13bda70f56635d26a993f04eaba5e351ed12bf736f52608591fc2315cef1f618d31bf15361401045b38d66db05e700ee41ea1f17de9e1855bf965dc4e6a12eed15afe2ad30fee124db9a64eb3abc2c5057fe95e0ce5111042230f825179a751f65c8bfd6f6e3f04fb77dc98d62f75c72db05388f2d2b9b0cb63245cc0f29418736591b72ba1554ef99f5bd8a56fc5eaaff5f27 +expected_result = pass +expected_shared_secret = caea7e78e6f80e126a9f41ddc0ae5946a80cdf617635934b22c9097c5090ce59 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +private_key = 058115385970fe9640387526e37b2c5fa614ee27b6e1512e3069c5363a4b48ca44a523714c37c15c60ae17751822d14a18bba78a6b1d6b2614aab3a09c314307f06ae7c3702f37ba9891b9cd7bbea76098bb5062b1356582167c12a02529f884e05c5aa6b054aea5a58e19429bd7a8fc9c5eb0d0aa59b54526884eb7b740bc2aba74902edba3a5c1b53091f219f8ca1e79575aecb556c082700b844690c05fe0692ff2953673640d96b72889a317df4158dc4475a6993c4feaa1718863eaabbc551a11d462a8e8d5293bf666eeb3481ac80f7c4a3da10b2169ba6fd12619bb96656cba731c430b21c24d337a51fb4088ea57105027228952cc79ea03e85c3e1304b1c7ec4e98acc486c411fe1c2d539927d0b822646b8cac7c971801cec9e07625d50caa291808b4128cc1be98c73bd0b03be97645e0048117f5165d71b5ab11af63bb3d759a899c2176dc828736b50dd7f15ef480578b619f3ba8a9e5ec8c24b472d4886f07c3a07c3b677625296dfa9b64ca7d12e94cc8e18631ca6bb80b820c7a229a62b141c42c31f70075ea73ac5b4d3de973d4e364dbbc13aefc9fe43c39be762f0fec97fc0738368709c426504ea71285db774f6b56b96396b2a683939947888267cb834347dc7f3346694e06c6b024c497b950048c96c1988642f074a9b95aa5018c504cc49ea659ac9310c933af9326bf91fb06ddaa21a8a3af4b3aabc608c6cf89c554386da97ab8eb9ca9bc98c9b1ecbe550a6a53cac0d7a72bfd7bc9f710bc6d140197b465c47094f3663f9c5089175aaa8f23b3faf97a09c7afbb94c2e58baeab36b0ceb1cf194720d54bb98b03c0eb1756b7c376560a7603b306aef22a09791c96e952f077bd2f5040aa2b6e188a776aab6530890f2e34c7ef792777b4b07c4ca8a8a071da13c9fe47b451a009e0a68eec9037f89627e7a979175b7f7469215783c337dac91f55c574d223222a0b71dc4222a4716a69b3fc5533ca9842ba17adb23ba6e300565f739fac07483ec53ef192828ea113199bca45f28b558b96302900ef872f6a7972ac025eefba867f001f40736eb41737ef228a44d99657b40036ba1462e34b668715c8ca2a84b4c5b7e81d11e4acd7c6ae77a7a7e6193b5c8143a45b997dd291d3b08840cc4765b8b4f8c7caa7158f2b939cd273362c9302af3c59b2a08dd545ad119c0522fc60aee902f6a6b49778ba17a97a47b2018e14336cc1cbdf49b90698551059bca80506a4c8533d791bdaaaaa638571398ac85256740aaa5bf4bb35da6b3b6f514a7e364935e769137a300e9811355a9097492ce020aabbc0cfd8398792651f82b887b0d13c3e9c5632029a1670b3f8c8437b09a8cfd6b8482bad74347144661b0cf297fef2bf91ac607ec7b77ed308ac430abe56c69b668cd6201f329875f6454aeb73540e3c0f0816cd7f2b372daab8b3ec1718d362f97c5a05b35964707b4a7558ea1276fa837e4d90be1b19ae05cc7b948a32d1018f14844e1cc3b79fd631d8166d1fc072e538429ab1b09f8a0ac879143f514ed31931878191a0c203b5e69b30d40734904c1bd9ceead909136593b9c51402e5cf0917c3c9541cdfd95fa66018784ac144c610b4182a69a08cbd43cecbb8baeecca48de3ca5d21ce58a69a96ac65778cc9a5dacd663a632e63b1a4e71b012846f0c6c26b728902f64baeeb6718163cba1ac63447cad9d63eeae21855776dee780d1b6443753235f4330edc889094241930c27fac186f46428a60180d239008fcab21ad162f903a7a0984489f8a9d10840f2171734536b67a329174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9cc129e4bce6a519947d17caadc8f3caa6a5b10bf98a526ee0653af3b214b652dce4b3ff3d2c1ca4b3b2f751e3af095d4128b57c46c8a89a1de5b805ffb20d0300e6ae5c57f562fdf493562e1bb5ac0bdd35b8395889f6c7037ed636e56c1aa661289052952ebf386150bb03eda1616478a1dc43f50fb1edbb63968945e05d09d1d320b335433b701caef733a47bcb0e62bcec0e68cd6da26dde55c53d5a289284a7e6b1c239a092c0841c6e7a8292041a04b842bfc8f2430a632d55568a58282018d55876bc8e90bd1686b61d7ceba6b500ce628dce8a5dcd13cf76c81ffa1afe352c6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e30382cb59feee1b6b0fc129fecb8c74034da92987249bc20cc8ad4a2cfc1bfe0248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = 942678a054e276d2543728786e8254fecdbd37a6724521ef40252f1aa2de44973537ce77b212460e448798f197ce133d934f49e18c6a5647b4f846f41ac82045f37bcb1f0e62253c757d251ad3a138b012f7ec3fd7c88f22f8c723a553e371a37131f5ac50183ac462a03fba3b22bd9a0af9ff2eac360670c3991b63fcdbca7a3334817e13b05ab842879e682568d14b2080874aaaa07b77dad8f55703d6d78d49d0e293f59f58b0b8fbe2f29f46f33544687a8c66a2d30f66c0766efc4753ed53a816d04786b36562c001cc39b88e9c4ec4c86d3b09b1ab9a927f22254117777bf8d7236c47c35d0acf8f63f34468a6abfe8c213085e8cffe758065a9bf378a2b1e3fe30fb8c6cf35aad2a8743c53fcb067683d1f67b73a8b48d1cfaaf03755d55b7c3fea0e2617138c333834db6e48fa68332185de4d8a164832f51ccdea2ae602e9c04cdfaa5acbf14739367ad9788559424dde2c9ce5d9b2a1b63de89ad33afa0da0336ab877f2ea73c2f05582889a3fc60fb8fdeb3a5caf023d362e9756a9416b24f8b740e44277c717da14cf0b2c4084c3875b473729f5981928ed839c7d36e51f0b91f345d08b3c9ee1fbf88d638a40695c378cf3b75368b09c1a5ba13a3aace3a4b41774d20a6b766b2be0b086854b965b14a75704a6e0dfe6035c5bee41b89c1b6bcfe23696305ef9d1585678fb1456f3ca44d937cbc4ea7c2ecde196ea2912eed17113b510b63ab32d415ad08e2e0239b986ad9828f0c04993605ff677b17e8ab5925be654999135d33a627d79f108eb5d6be3704b032c1ab1df3de825795bafced52859a5b1a4e64c9bf783abd20a09d320541ae120caea755b793f0b112efdae0c47532f1182ac59f6243ce6b4330aab60c704a8649a24aff47aa1a651b338c6cc87b2d81fa75506202579d59e057ecda1d2efc5c8a4f1f29083dd3b85e7fac6b56dfae8a0e19fee07b3e54da6835cc290ecfc734b5fb9903403aeee16eaf8f61ee317394d39b91a4e3208c1fc50c4d8ea66a71bbbf5cd24e7ead5617bb905ab96cfb02f363b92891044f9ecbf2ea00e833bcd560b9e3dd095bf +expected_result = pass +expected_shared_secret = 431bba421ea89647d815a16f440d47f1604b67d9a2d33f2dcd21dae7e65bd5ce + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +private_key = 48340bb266c646934c7f42388385c1ba2cad8d25b57e17c1d728b767a592505a387a46722b652f941a2d420262c188380aa638c90126b9001f9a4c193dc1a7fbf5143d52a9d94ca6f50444bad7aa84432c18b31b8a40003f393f0ad3346cd740c0637f88975f32db5b6cf2a6c0923993e680e4547aaa9015c7559ccec2823279519aecbcf0314105084c63379d92244fc9839a0efb778fa28490999872933b0e2cc10309bfcd6070509b3a50c292e45c192e0146bdc1bbf664ba93953081ca46a1a5ae374955ac771e29048e830569423a2fe9a30703992bda27257f230b924cb82a3780ba3a5efb0c60eccaaf64c5aa4f037d229342daa9089ea1508ddc1c90ac72dbb68d2324ca91aa3f153a7f2902a5eb95a45ea88ad9ea4f62769574071038917ca015463e0252d3394131090a4081247c6b038cf6a095d2a7d4a22e7ae52552513434442b4e908ec65054a4e08236b4a32f054b9598a1e2f48aa88a6b53f950aae0c183a546ca44cb111974a8d1b494ccca5f176979b008725c27f233868717502275095af902f9c91efdba917a3a1a7f5ac89f660f4c34a0d648614f8cc3dd9738af76c63a4c4b64118baeaa72ce91c4ee3ace9a847d17e996f8119039198aca1b2c71bba11a2bbc05e62b33d2b4f09a8de917bfd4687a151552fc4446edca2ef386bec16400e41864c19b9e2a603d5b1b756e3cbe5b092327d39b0cb6b01c92224cacc6ccf5c4381174ec995435041caa07552d55b8a2e8ab77d720bd31443b2c7ee7395a18d378e9e594edabc504e6c310b8617b9b099af61fe8a0c726c0334f761ef85c609266c4eb56c12b8cce7257c0dd96a1390979ac076167f3441fd91ddda9145af6183ac5810eb56e2ff85fb9db4467dc11e70b99dec0cf0083aa02022bf1a079d580626eb2b653b18e49a64344cc250ef9877d858f248c26e41a28e5952f040572fe800a5c8873194bc4430ab739d56528d1332e14b78b56c47fa0b02fb719ef4003a444c7a4f26ff270a279f44e9cd1c899187cebe1a620386d53b35540b359a84656b8bb47bc712982309ccaf8be6d37267b2166a6e42b945762aa4b7684d18022bb247f593d00f4956c728f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcc3269622355b436610412cfd92458cc5703fe2b01cb3a395927be19c8067a793bca615cea3c2ea55cf10c0cbdd94577331939e6b7332d849ac501750411223d143dc953d648152005a323df711009b81614a657487abd5476bd5d71827ca1b5ba45e9c268c6f826e9263adfd716cdb842d4f31b2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f0590b41661b3936950009c1423153c96351db064a794cb345e3c46abb00b061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345c524ba1a1345d052ae176bf16370dfbdbbeb906996eb41fad306a9153c0e8d98128a82231d73a878a8117529f8ff85be6cca6166cc5b0503134ab298c066c62260df091a15f598311815f3503965695586ba134847b3ada551b62072d03d468360150d0b17ceaf0a1496070778c7a75593acbab2baa4c888bb99d9ebaa34f8b02c27ac7ace0a15ca73905d9582b8137a223bca48b42ebf28d4360b01cd25d644a6f7e831e155928e971627c3c52a9b015e5d8a86a790ff785c653ca920151ab662c3fcbb18af3b9ca27f6c0cae82161eb940fd45555d71fa801bdcf418c5e9879fb33b675d5a27e5b45a4e2a20916c83a1bcedaabc0ac0666b4a2b403f05daea6906e773ee9eb3ff9441c06f86634f01d1c93788a08b76b15be95b296d407a9ea500d89b191c1c68b7d85763d1c2d2633277af163596a7ec257bdaae2a510b8282976bf25936a6e380a778939ee2b44bb1054669a2c5c06c77e712bf2a5b6aa405a1408b5fd2573ef231e2169c165727ee1a19b4c6343f2038537da304909c1cf81862e9676f1e26d7f48748488cd9ab64bbe3167b442719a304500d8c72128cbea470942289fc35c1fe32ccc07361bb1591e43e5a4f9076b7d416e5d2325fe0413a0a88984b048292758fcd080b5f5378d6c508927cfea478be3f68015b12cc1b05b47791ce7ca8c1a98cffea637807931a863b2cba011c8d8c35db81bbac79c5d05171be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2f4e474fd64a6d945e85eb4ee7509cc99fd4054de99f819fdbbb05c54ca6e36da1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = c2f9eac5b635499b944781e09115b12f434ce57cf24b2443d96d071090bc3c4375b9f427a1dbd55c3a0b7540799b311b1d7d64dafeadfd6c7e0418aa9ad342acf67aa6643c29edfabca90cefe4e7e73ed8aa7c73527b84fb149ae33ca1aa10c800add234cdfc458b8c7e98a3465d3290ab4d6b2c6c32a037de59b2261002f940d0150441d5316814b315a394ed4b22f9a8f05e323827e537e13a22739eb9a79ba72162d6858d791cb27429efa0794cc9b918d8a91b282ad9ab35a064ee1a064146a7b3737a31d24aaf2523c0cd4804e5215c4dcb008bbfb4a092013058460336b1db62cc1f7f5e66b7ab7e07a217bb8e2fe7d98adef0358e2abea21daa6d2951bd407cbe012c4c65f0103d9dfd76dbb2ae263b32200734e7217d5cb875f9f470283b777eab38d78e3afcf1b04a1b895986d409a11a7366262a4febdbc2c4009a0e19a311945f9eddb564f0c3b7a68fc0b3a874e45f5bdb30e0aa988143c389a8c8e83cd7028a79194628515c5c521f9b995051aa72a5f6952b6bd087a5e3b3094969e7e64038c895773702582ee8f4827a2ad5567c422ae0d2e155a6ff28c20a24edefad54f358b11a621b010a87beb347c49e8ef7f19c780396f0f13e4603b2920b5ed63d0d2e082bb8fe9d454deb9c9db4e481f8a5591512237c81a6f1ae56b63ce4b6e05c2c46a08ee685986a241431c84180896fb9336b3c62e2b9ec3e27d1d46d6cf28cf21b78fea500de3f77ab2b839abd4a2b1a71947795a0ec31053f4953a31e1759ad3428e6c3b3245b8c49054e237eb22840d0d4a26f540d1efa572cdc19d10f2f2425a05f0dd7f05db66667f9a784228134d50b509237e9422c2bc37b4e8701891028457b084e8e9e89e303d79b456625cedc9b227d693544dc1d26ccd1bb36ff51ae8ec6ce934a8d99c3d6c40e631e730bb993db83ed79fb1c1246a244da68dc093727f586dfc3e39373ad513ca0c1b29ceab5054e3657143c183727c8f06df9ae9059f3a8ad75d2517da7e8ab52e01eb486efc8e14bbd22eb9ccb92b5e839fd893fc74e257a85f56bbb8251144e6d9fb10e79e5e26362838e2d +expected_result = pass +expected_shared_secret = cc0a7809cf6787a4587e090249709f694b709ec8475a42b4705bd1ba312c098e + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +private_key = e5929843493c5ccc19f047539427cb993481145b7899259865758538b160c1ca72877688fac53f0c306237d572d3c11b6a0b05f5f46655ac09b01509d2428e8f7385ebba74c7777c56cb571af991f33063b0239120f894cab3ca804a7e3a5896299601efe290cdc529b8127fec01abfdc930df7bc345179fb6b150a5b5796f12563df87b0dca299d8a2980b5c096b01748c2571c837ff072063c80ac323b05628333227ccbec1c9e55399bc75739f6486ea379b5e728691fe004037399ac73487a03c3f8a5be7eb09174c60f01eac9227a5784d97f0d9420a3e34808844d1772c846c3527fd36fb17490b39698197b644ef15723832df93c344d3a7c5728043a2734f73943b983a3f9c856aac75092588a24cbbf7e3916cb8b6309c287fac67837d63f8fc44dc901697f007ae429479227440f7495845b9af07192b6667db7867c6dfaca947310d956a171f15ba73994bf214c426831c3e0c220582e6d4437bbb50055abcb5a36829f93150b810ac6907ab814aba0c95439b25beeb371761803aa619bbc01137969047953a767c947e4e7115727289bb47c8016b30ee84822fb5ce5683d4f7c61696108c5413fce2a1f3b8378e65215c61b3028f589ce082386d3ae1d01806bbba89d06abc2548bbe9a80914109fa892128951d9d8a2e545aa273b8a9eb66c07af53700a95708d6610040752bb61bbca29a4a814d2485a48446079496c01b3603bdb6209f77427bf750b1c0a836f89ea5b176536b2c011441b49410c99386b15b2fbfa4a6a93226af53a047a49d738cc4af9c30ae026ca24a060895a04f456b19157edea36dfaf57fc32155f8c9a59b08508cf880c401a684440269f12f8a0c8f98b930a1190f302818b308174cd48b40dccd5fb851104b107ce48a62e86553c98570db342b024dcc5c5c9fbb48989a964771620c06859ac63b92898d218a43df21400ddb04d5e70c3abbb890292180d47fd0dcbb348131ba143e666072c8d64d3d435cb57956f5e9142b619a1da05e205bab945a79a154ce34b2b04eaa3b0ad6268c1a330d5c34dffb8116d883ccb4755ce06e2c499c30938500d6638044335765803648b2c7583d29185714c06345c8002f97a0b35641a2457c1f843d3ff637faa04dad093733811f2b143257c37b2f75bbe8a81b107443d071be7ff5c8a89548cdc1b11e20c41e1a6c5ddc57d7e72c8e17a5cd82a60b6c8136bc3b526187fc8774f9c316d9b7c2a9b41f676ab6f53b7e436194dc2cbd8ea324e8701d5dd171b4c20054c87970258fdf259f575a71145b1421667a16812933d645bccc8af72266d55184b1375bdcb15d87b5c1a9b4c0e4f34526194754358de8d655104241d2a30c6021c9d3e727d933147385b3f416b2418924e3369df7652debd6a3b0c457fc28cd88355bb1702d802c0e39773896ecb120a75c171069838888b5cb788990a349b44d5e85712ca91ac8a20e2f03a3c119ccccd37dc783175485be3dca1515723ff2aa14d77a216eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824a7072511b1709a4221b7526da8602cbf11dedc601ba492fde8a5d3bc27c458bb1b994432a61a7a4e333608207fdd700ecb8781887a6fe02702df120f30bab2b30c28cec7d86447371c6a5e99a1c171b64827229527c48b8e343005a58818bc8b9b9be2125aae9ca2d640701b5b204ded33d2cda34ae77134eda9fc2db12b5b12742fb4b4b8a22d8d75cb1f83df409ccdd486303202637a99cc613035ef54257a27ade904e88c13c91e42e841107be386c7ad228459298e01a1cd4151d64064666dbc954e921a408975ab6814752045324a3a9f41f322153e2dc1c8255a5e63280fc2210c52176a4c93cdc9693bfdc73156aa319582e8cd092a0e28a1a8148c13a14fbbc745f5644439905119b44405a27ce9ca446872927e06ebeb11c8fb39ed407042bb2308b90379566a18a32b7ecdb6f832c392bf205edeab45bf0110af1aac076c417923f80ca059f34101d87234b7a288374b2ca0a88950bc722a01ee4e7be48a81fe732998f536ceee8540323ae08f49217ea880de4431bfb74cc80cab0b89f327a28eb9ba932b523907164dc82c961343088002d10f02ac2647a3a532d5cd796abe16115724d37122431a57b1e9b2071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd50688de263a82386f39a7b82592247bf5499f1836a3a941413c75f6331ce403179238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = 0f7175b0a6290fc998515f4604b69ecfcbc7c13d74d59e83ad8adf658736ffc9abf4eb7346bcfc7b038943b37fd1cb8dbb0390e0f42f1940d7ab3d1aa09ef8a4a424eaa75e92b8390f07c1b6bb7f8be764d39955d56d9465aecf075019620d042bcd89a8b957a938cbc9f550170aba5a0b60abbf6ac60a923076a08743564f06a3660d94c27c14870ffd744b788510c12484e2c21840bdb1144197fe29b6923460d6248721f95ad1542c43dd3155d9c8ea37f1419f93f615aa3baf4875c3a4e079c0c83deb91167d9e639c42838ebf72356c021181820675084a90d12e4cec6ffda46a1af2fb5305a925f66222dc9188e8954c510c7f45bd0392243d33d26b41d9db25b3766090a23db02736a6fd5edd84727a7817ea433dd6d3c787f4d928855beffca3c6ef6cb62991b68a27eadb3f6f556856142ec0561d116ee36292f6b03b00ca0d45ec4b95a2f2707e05219d06502e9ffd92e3d2d617c9e4a02d16a1ffebfe80a00f855c4547559f504428e6e0c69383adf03bbb4e2e9aa61c6082147320231bb09075942b1d73812647d3b8fdcb388b9b3088c4e596d72e6abcf6b38420fe7fb10d924287b21561ffdaed70aa8cecd73ba7acc084309106542dfc9ceaf1f180bed5ddc88bc3fcafa30b748eba8050f8c462cb430fa810248dcb2c3cce1902a40fd0143db9527ae34715d2ce124f2186f1c785fcdd67a4977c471ff5063d184453f9f2e4a07548a989bf3d7cdb21ebe5f8f1d701020b71278e6f5e0018e4478228a268860924f856d7677c8cf76e5b3bac29fecc9d1ae363c0abee737149b965962f7135a31f82f2ffe84d69ecd94ccf111e0c8e019da5c2761d9852649b783ba9c9fde2364a0e8e21f14d6f42586e1f08d235731ce0dc19619c2840488c570d528b953b412354d2c43b37d66ffaaedc48d908f3d2db276265118c1a1982eb024956294d97226561952f6704064705569b5c4bc96d15b3e84ec3046d379e4ab044e90d68d94b6c0e1434ebd3616dba4067085410aba01ac424b3f3ac81c9b9d399d069935d75157fb469abe37331a49ecf86d76d723f551dc57dea9921 +expected_result = pass +expected_shared_secret = cf21da86b3e09c38ce5799637b1492a1a268dbf0ac716499c68bac11a774f41c + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +private_key = 8977c913909b2f2050958b52666c3f7d16094a4613e8b1909e1838a3763991805d58aa1ace8209ce5cb8849a98a1616b36778f1e138abb5b2fcaa5ad2cf5372181477f7a4a7ba4769cc0758d911b28e447f76947cb5bceb39359bda2050a91186b37469295040bb6753d043561b84dc345607ce94a8f0693c91096a4c9c69155076490901f85b321b175f808c76c9698eb9036b4645081051a6674b4fe6b90e3e0753e032e6e72b3dcb07671d300e7dc5fab7275719410c685b4bcb885adb74da7db8588e54c280b82cd41a7f85cafc877c6dd212d9a889d8da091ef4974e7e0ab1112a3ce0446d8715cd309020184660d8a7358d137c825cb78a2c202c29e2dbb10271275c5225fd8a57e34b54e7700108e83436e712944848a6a0a7098f1864a42068ce81126895087a96c4d0305ec475825f44418265c5a6769f5d86d463bcfe0f324492716a862859dfccc8781b2e1ca516866847ee3af99c94e41eb9ca9303d6c6717b53444f3f1a48cc66b43883c23848b9cf7902a4722c7c9ba72dba2a1d15b6a762a9cd2182ac927e63663243571afb78c2b00095bfcc889c0b563c249fb1481cc7a4301a6ac7ea8ca194a19c8859505b267dc982e4f339802b997e183115798bc9b104c18c04c6c7727106028b20112d7b0c35e43246f573a0af1793848ba4b412bc5800e5aacb1a197b29ac4afe55567a990176002be852360be346019c310ff8c5adea09fef258ef560accba00b15321e48d6cfd3f5ce6faa85b2d6af453668504989cbcc4fb60b36cedb2eedf36e400491044c3b89440d7c2a1e3352c0e9d616fd4c58898b57d10a459d609de4e58249f172f8549a4553aabf6671a0342888e954270a78c132556f333c07245a54500c5a5b7918d0411447b971901b17ba57415a3db56c597bb4b7e55752d0bcc6356c1566c01fd79c64afe59b8c925baca6adfca4a2616a9f505313c3e01e13700736d8541f406248739fa6868bcdb3954e226287c0c4e7285ef7e040322944c79cc95106052e9289e9a14a087069352a6a0738699a37cf2adc46f13359d7152d0d98217fb3574e787a0d9003d9f893e986491d219b6070ae339c3114e1a64d6c61353411ba2008ea358749866018c802d3dcb05b0c5329a691f57303c0d724fb2a1121d264374aab2eb209412941f7e39eaedabadba71494863f79e34eda632c1da77ebca6283311310f4918c69c6c5036a47aecb3b2433e8991b8d0bab01626034be96f31a41d98c1a2d3354f47e87b9053033b82a6a8f6b167e827cb1c11ebf4758af8c70fa98dc1f35b353c54b5552a0f37257367bc43e263e8a23284b0982ce8a6951a4ae5924d74e3481a4bc141f0a85e90c06e97ae64183c0f469dbdcb081de093ddfbaf9d4318a24615f8a38d1477132aa5c322934d5e92c89acb29aa85292c7971e61c89ab484e69976a57c2181ed5450260c05fd957163c0269e9a3aae27114a5395e398cbc198f65b46bc2108150b40493532d63a35f1882583fd16d5de1bf0a7a9c82d9717bac5e31a15baec1afcd94a352c01dcd73ad51852d618490ee5993dc617e0526556304095657274a738bd4620e80280c828c17d31892fd174a4fd8302d705cf738126c352899026d8795c9afec77f39c87f1567120e70d9211b73daa813497397c0abdbeb7124f942df311067a0ac03fd3c3e8641f202765026b7fc5511754481bc8f227e362cbbce579037c4ccac5564c015318e598cfcb538f1558a1b55e4bb61c372caf23c2a1eba52e7acc5a05f129a469bed6688788c2c68c72b75ca413b7496f3c2505eed19bb2962d82436c16c29db904b76ce5626da57bebd05bfe838725052d1103202e563de581151bba7d46e1cfafd50389a730c9a3c56d88030bd397a9d54af0e763249cad1cb0427580853b3572e705bee6f1bb1f4232f6ec2aec3059d777209dfb32710b9fbef71203f5a1eb11507ecb98e5e4cd384124531490e48a0bcd39be19e21c424c726dbc1900ebbc1bf155256a03a89b3d0537b4e00988447ca3c02a65aaa2ad5be40825d207fa683b9d915a6a5a1e8fe20b0cba4ea14378fb759e1a064ad93b6e5ad712be3551c9d4a4b0819eb7420a4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e79841a29c0f2dc4089a85db6865ec90faf2f4ddd25f210eb56e49741866bbca8cf811f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = 5474f5beeed244e5f164e61c630737d0428d8da9a6e8b55216d9b4f346d34eec261c465a58a9a51d0699934786671e3d52ac72eaf85a346d295f2a4b9e4757edf889b8424e485643de3f2aa5cd93a3b7c1a5378c1132eb4d0ef096fd33fcc6255aff0aaf219ad8b36e9f0c201964a28affa693201c54bf75f0b9b3a9f636a86a19560857153a3ba7bdbd0bbdc034666828e26d090c324e343d5968ca97fefc86a5e905b0135a2463ea25dc67a5b200a50b13f850a5b00eaa424bbf0abb2a627322134d90be38edf7f505b9abb4d49ec7fe8e28599d7c3c75d8a7026a3210187a4cf6e3b4f1374f18bf2cf1d624986c34c4a959bccb3d44b0af3ee25a3bea6b2cc288aeab479a33c62cdd7f0207e7345b2e790a2f2ba25ba5bcdfa1127a397d8cb3ed5d5cb75f3c8554289e91ab9a3d944e365cf97449b26305b58f120b01999633cb39f7653d0afec9cab3da916f773d6d218c0e184fbd24642ceeb73cdf5c68e3b065667eb6785d98dffb150a7c5c96a903e8b86fde7e9284737bc33863ed0881e79c0b98ff9ee93ca54a7fc5937460f1b20d0ae8216c1ca4a5ab2c04906e2164a4a9e344f6d4c82c8dabfa4226540e33b27cbac44715af571d4c48f2d8b24f62a593adeb4d57a49360edec07cb3cffa0cafcc79ec1d89c93544b85a103bd508b264fe59b8047f21da862b2af375fb4029986b58ef79740bc4fe3777ee9f0a680818870a1a7e3b38ba7982028d85e24c37ca2cfe7e92b4a1a705a1eed968390ef12cfa14d6a96a11ca17b26ca83372dafc217149b40377d41668845ef7d14f90d5ddde801c2ce862a7f014e0767aff25819f3e7003b9f274fbb3b42709824138a081606d8900d77cb575ab1d923898af507305bd9f34d21c553443b518f21e562e0bc35e62dfd11dd7cd42116204feed69bf6b6a64117183e5c2b08fc689cdb3a2e6d30a4482de2bf2da1c6bd0dae710fe191892189dcb78394281f57b742fde61bfaf975c00e125399480345b0358644d94e01a5e0f1b88816f630b817a2ce30ead5bd892fc905974975f84205e2a79c9fa02d25cb62b1485487c6a2100f0d +expected_result = pass +expected_shared_secret = b56f557eb758ae10d22b5d65847cd811475b96f5a46b0ed3bc2f1b9b371fef0f + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +private_key = 57343b70b6260fe3406818ada3e422af7036f631c500409e82ca670f894607bb0b067ab280a99e0c7047572ca703da89429559ccb397ec7a6e779abb69cc0edd022b012a30a978b52bc28a1ed118907607d3f81e60a91167a066c061bf000bcebeac072c23738f13b84960c630b81da0d724dfc1c67c42115717bbd51bb974502c11840362c033e1d3c1b9887ed14231a7e54dd9830ece994dfa0117412270a830744358c4fe460a84e01992f92739d6a1a5a91af002371834394da3c8d83022519c292554687d02a35d7517fbc4cdd916845680995f48cd272755dbcc6128039ecbe00043e54a25f2b7a5a14cb48776d278c55ce79d8447b013f063c4b17aa5b8356601931163686c1c6764b0233fd80f0cb6919d19c5a14c41fc7ac0dfc2726cb54a4de38399041668bc88be0a721e86c5de0b3b8df862af7084c3176e0371a704a1738b8c7d0f163bd01c1cfa01181b3bc9d97ba2b8596187679986452fceaa99b2e26f0e2c6ac0cbca10db625fec82363ab746e12db473755b0bae5a71574745c1ac1648fab92675735f5b855837f0c47bdcc23a3c6fdc5550b29a75740c34ee1a42a847756d892fbc2ca334d06d6e90216e2c0884b9444b07c788c08fcda49d95a4a1a13947b3fbce992b995eeb8ab5cb65ad4a67a9335e1b3a53a7431f827b0fb86218274833ec7c00852cb6a4c88e28a99fbdc635119672e7b62d32138fb815cbbd29a7d3005685f61fa8ba60890a3dbdf58eae85310c776216d43c90ca4d68a0c7a2c0033e694bd48c78c48870b3294f6d03b6a4610633211b03a28a6f89b86743273193a6a8521034215b7cc27e72f2197d9482f26750eb6a414a9aa6b05054b111a38ed901a4c479473484fdca8c5757121733c67d953047401e9fc7ab1e06a01cf509ca284e5dba7273644a8c1b3f1f2c52b791910cecaba06b391cd807e0752d0587565d20680374bff2e48711e76155480eea54826485c3a4c12da01a9ee3f95d27a2bf6187b625e72cb02191fc9357e724c769624148a71bd8b36b169ccf23d265796120da0328b6fc4a6551bc91ab809863be6b4a1acb039887b3281828644ffa865c43bf25ca3ee561118497bb2c1a04c50b89ecb6b8f173ac78c0380153b55d551492a95f8013b28d38710ee7b0b3f75cb0307e22f1986b65c9a890bdc7846e71b926eefc4814b255a428cb4de94313da24a17973e5d679ab44057e664217a54f6b16219be642fcd16b35952f0d2a37f37692b34c3639e9400a15c245986134aaa3e0219b98383cfa7223acc31b5a05060bc1523d32c01239c9df8338d8fb2f998634bf71187b3c458d155b01dcbc20a7558d6196b7e0b0fff5c856077853206dde97268da274fadb80ac727555e156ef640c2582c4358aa8cb78a55275393de19792ca0f6f030e2495cf1d169e3b327a2cc17fb87bac4fb92f603c93658c2135322b58a4bbdcc95e56f66104807637d4232fa3868af473355860f9850ea5b61391a8c20537ad23367097b1911efa5f74767ce9b1516936a11327623d371e8d64a753785d09f09157697a48902d4121673e2b904aa94d845a5f17e90bbb60b81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e91822857f40fe1f2c818700d26b882e58a3efde1793ac428d9fa8a94f62ba9fb16ab867a146cc1c7c0a0d45a32dd074a4ba52232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097380d17a6f6369a5dc55616950918b245be7a1a3656ff4075acd957e1df062218bc84887b74da635d9011bc02824603007e9cc594387771ab84f7bd065c741185fac84096aaddebca179355dc365516efa4873e70159e28c714a4e1149befb0a18ad6098d5115419dc4779400f8259c7cadabd41a7a270e5c91a616e5cd0b05976979967baf943b592917befaca4d6827a4a545fdf584b8a48b6fdacb1de775bd259b083693947a31d91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a3d235b870896a558a5fb2ccd7d13885969d2037bee23b3db1025be64b3a5feb95da076019b65685186a445bb2387aad029b9df7f1bc5081a7423c267978c295f2653c785293d65406004806db9f98a8a7d12ba7b87b8032e0cbe218413da907641593ee627831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a13fffc419d3d8a887ff789eb661b2af1ee5b32a302ca267b33eac2ea7e3340b9762d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = 45ead8f635b0a55577e4ab9ad95a454cf7f790bc4bf6ad467a959271156c623fbf3d28189956f4e954bae7058d892d7112934ce536f5d39c69cec5b4f8969d470e63d11c929271782d53969c5b3bc9a21b6fe9c711aedbeb37e4a054303fcd14c88f1d9686077564b164ad0f226a75166b1d9f565d0ba003ae3457c9fe7184ecc97fef220c0ccb52eb174f91e79be2af19d97a30b5af8ec0e6fbbe9b96545612fbc60a83a0c484d4385c222f8e126bc6339412059efc649995de93f891782f39e15374bc40c912cab6745ca8cf2ea0571ec5b4d64527ba97f5c1de81bd4de11fa3d5ecd703d2fcfe3cc073f24d6c40d58c6ca482ccbfff2aa86f430c60e155c8497508b54be5ece269197f50a71ec6713a59bd3c8c224a072cbe5c556332e561e8ff3c1dfb96b09239803f4a637409ea35e7020a83c5530f8b8722efcb6cc3e57837a4b98c6ba10b855673b8d271e0e5f08f178f18777fce80a667e2030fdff1c5fcfb0bf566d06022a980df4a8de2e91f8b4bab58628a70b1be0fcace47c9580bc866e9641265bf1ebe8be9fba7ffd4eafbd62e68f81c1067a4e75ccf6ef5cdd8f18fa8e54ba051ae976b5ed66c4662c9e5e0017c8eea63d82b1dd3a8d7f0224497a4ab7acfb3ea2dc6e2d8048b69082fb9edba6c5e3fcb2f43c25d6077d7dbd5d4da018f0cd1a5d612cb9d139dff309d445eb2c3364b50e98ecb9c96c23bfcbbaec80c6306e0453d7f470302eaf456aeea78a8cf25a9eba87a30900630d53cd9fff2413e7da06eeb119c67270117ed8de87f0c9b9ba2e8652a838d036e5fd815b5f502372b60769223faa504d3f4add01472332d01cf6d95518a8a2cd93b6fdb4e4eda53fdb554c3d91ee4c4bec7bff23f4a9cba2f2723b79f8dc71b521576e6f6111ad0c3d50bf00f9dd1040f4028d9b3a92cb4816360c055918d40529045c68f31090b9f2d92c7586232241cdd4e6fbd492de375fce0da6eb1072228342bc5402bfd63b517f69f62dc7ec0c6c90dcff4676bd95030659077899e5dcc0d9a4c53ad7c1d14cedfc0b25c0d537dda3252aad4d453e1b8b4ac56a10e9a816b92 +expected_result = pass +expected_shared_secret = aec1264f12ddd2ee8e51b71d703ca5c2718dbd79858240635f9b076c749a5ffb + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +private_key = c4f46b76f1730b277c1065622e85451922164498242b836e0b389d25919d8c818e67d64837634cb133bf64f9931ea5b79a16ce7a8826e29c817fa83860177b31198161ba4e2ba142c1e81d0d4347496cb943a2730c3784da86370e51c8000891016c2ff6063f0551aa2ac8b2a9d374ee51b7e24c9a67f47449b0469d75275ef04997334482f8baeaa2a627904a6d8429b266a4573aa0e9435f65cac4bac46ce162262b59cf4aeb79fe17b68544cdfe1b4ffb6b205c131e73091b77cc073e7c85a7559be923208fa6b90d6a3e4e69bc7f486027b2ae3af86896f060dd622777a6768e5406e8943ff1f9254a36bc1fc4178917c46b10c5dff69ea8db2488fc4769277d8b6a4082d8504fec5b4f291532112179282cc740a4db689bca79c1beda6e6ee861f3243c5cd23b18f59b5588c027f2392b143aca675c844975aee455fb8738c1b30543775804034cc01a9e3954967e552dd0b55c6cf86d71234830e453dc357b45c830a162b990f7472c203034341ff5dbb14d61131d35356172cebc60c2acc16496d1182953316bd6140a2aaf87ea6bd8002e61f346539ab1e965ccfb607df0296e258717ce85155fd17433c712cbbca74b9533cac87d30a4764142ccfa610b612acafbcab41b968746a5719014a9d7e840e0e1536daab3b12bc72695875827963a05ba0ce61aa4c0b5da3224ebc42660f87f80e55ea3d23219c5c28779c8b7e287771613f9f30075202225d1bf98a1213687bfbed25dfe61c8e2753ad428c7eccc8e294579af021763d1be13d93f9ef8cf4b700b75526eccccb24fd727ddaaada8a750cb7211ee8aa7ca5b05f06020c14c332fd02bf1c8881c2830f73316681933d84674ecd9033fcb4465ea2dc259522c4b6b14419c78fa2f4bf6114e9c4dc4dc5a6040a01911c18705c7d317252aaa1631d17e28f2cfdc7c986ee2a8d934819ffabcbb7ccaf37a0d42b22e71e609b2873f76ab42bf841ee8f51f3c2b440234a4c344581c28bf5afc9224721ea8a8cc095680bba4a561a8cf54982e882a806e541427b333991646cda51abc3342e0956d4164a96fc4a64303675862c0ddec85c013cc70746f2b268d16f48db17616367981940214020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fb715428542f5e49b6d5c762ceb26c2520863bf025421a29f854bb52b3a5decb8a5bb7ad23101a254b89fdd95afce255eac087651a588e8caa2d5512cad48c9041a7c6f06dffd86341e62935a6ae0d4907cb3a6e4e223cb754c15e2c88d4e13cede42a636724568a1f4507adc8d0bdafc91178d260c262224ec8a176ea573e69c057c491d1234e4f39a2f6c4283a40c70223539697890cc5cd935ab8fea89a0ac513cb12c83bf6be1de55788f8a434001b7233cd3fe859c3eb3ab0d15067422a5fe1acc2286f59b75111672a3ea24515f9157835ba868a6219d2a10e72703ed6b066c036d118bef4598d76d08010967305199e3f46cdfc41ae1565bace1c52bcc89628a84f8b74252566917d440718a48226b4bb2f29c0e7743fc2fc5a3252b93053c0bd1285abf907601b93c83399b104b8b2c06ecb1cacf37059016683d2d08376111f4ed13a3204701271abded98bbcf5141b12b9455687e66abff877aafd507d01395e7da932a2e386947b015e3896d2a38214443d169b565fe8cda1c305fa668ad7d57987ba95a4e8a8e047a6039159f9c94b6e896679c325d2298a2896b256f528ee7b114d0101adc255c893530bec9d1ad397c6776ef185487e6140f2749af802cc1ed60069585d316959b2bca22e224adac5b54d0655c0939f3e29c864d087fafab871a29ad82c5533b40f67d672a16581c3d05aaeab3cdb0636c938c575c611095504fd200b61293ae1ab3c8895b6eaa64d26617afc82c6821a5b1ae4830c526777f1b9d6bb271c48128098925d607d507c9c7382cd2267c4ed7c6e4320372dd88bd5a9a50737663998934b70017386784867c5b9b11aac66c1ac3bb1793cc02df88e54a41a3db8603af791af157665b88b0b9a075f5a805223754a2005c81ac211967a43d7bf625069d098058df21abab95ca1e57d2d6583cff926eab06aa139a3da3b9bca10c9de93ba6c6346e76a88a8e1288deb6832603b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f1de70b1072881eb659a5e890a92c9313c7378d2e960a060b9c918260d4c245801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 2b3aa8988eb65bb1d5c86a3e8163033c7e0f3f9d924e64d260986b74f9a66675ed4fe8c786ddd11eeca0118eb7634501d8a85747d1f8a6b0e2c5c7379bf8ccb6ed35bea047f69c1a09280d0895695c08e6c2fa800d1ff2959ff66a9d425adbcdea825f7bdcfe74cd05b28d4c5f58eb66f825c93e63d998892c52604d14ca32b9f8dfadce0777fbb0d580fecc137476e85500bd909c79a94bcd8b54525dd3e7e4bef4addd1816a873e52a259a42097cdc95b7447fa53a5d0244ef610cb540dc745f78043cbaae20e02262476a21e1319ea75663ebec5960ea56834432a7cbb77ae51d60e3b339e37b2503f78fb14a6b8acef650e27807090c42908ebfddeadc1dd9b27ff1d471f6945b1176bf7260632a5ec6fadaaba637a1e43759cfcb48e5286b164839511020a4c22982b840a7fdec615f7df56bf468b3da925eb05ca7b71ebf67d4a8f07e71f6735f5f03de4e00e3f58b4aa745f421584f59d41a4e5da32980c3d5c58ac9eb22909ea6fe22fe16ce01e0cf5babbcb86719312ed8df46db9ac480cf3408a6f11c45f71a0913596749ebce97edffb095ed16191b9ad1914ea56a3f0ee7d2a2b7e12aade6f6399b9e273c4775544c5fe559485259af1f601f7d9cfffe9d89145aa0567155c1c2f75c83eae156d560aa6fc28e4a309a04d1d723f15b922580adbd4a790d56a0baf32c8d2443ba4358bdee22426a78ebe7580879c3ffe565dbd5b5f1e9a987f37129a255cffeac0d8c1edc65f5c6e1498a0ed9a59c2a9416f2ba0a395a338a4057149665a4c3f0754bb4abade8cb80c3ee101046d05f279624736853693ee9f86b2c237fe2a6efba216949e99a0bc4bc0302c08ebc39437333d536129dbf56b2592e681f10c61fb14a1e50111966e2990080bb6abd9d54abbb442252cf5194d6c907a394378e6998fddc4839caa0ac137cc8233f6ba92fe82dfb1de8a4b1866eab8cc360ccea3ab0493b6bef2c0cf267cbae519c0cc48a40e86a27f400d0629abe01615261ff55643772d990325108ad9142e13d64ef5295c88e00923dc9e4b535f97e6d4862a78ba80517509c05e729215573a7 +expected_result = pass +expected_shared_secret = 6514a3b97760070116c64014c5695df60d0345b29ada92fe24b672586f5bf06e + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +private_key = 22f7af6da8bfe284931c0a69afec56c4e4378c8b563ca29e2b88741ee94875429006f26630bcbf0bb9543ac427fcea1565243d876426500bad4b171d3e31b1f538c5d4602195570ee02ccd004608216c9b864c378ac308b4e0b514e423c96c2ba1b24f68843892b825b4105faa1342abb97488bbae4abb29a7caa75a1b065e652843a52be3f571a74b7b3095c1cc155cd5821c921c193fbc7858fa23ed502bfdf971f02501d3c37c2ee137dab0c63a2909de9c8720c17429d98675748c9ba93235ec2b608451c3bca7a055c913191fdc44b1469b54162c3b037289f1e039f8e3475e259b8e3c899bd28b0a093d7bd65f405cb957912fe015721e45858bf2be4d943303d0860e4496ef85519f393e99d54a15dc69f8459abc707f5bf09073e1ccd7f7821f455da0ccbe95c377ff449b95019f15698384238df4c27f6df48c1d89a0e9c7845cd6b365b13c2a7841275986a05b8d8b6cb3ffb66bc9322141d54cf3a255e3fa3b9a2c236c4201a270bec078c7229973fba093f745bc62c98c8e2c305c75667dd5a968d04ef4655ec0c04333e8b637209d0e9919993ac11424c1629c164b0589e5296266a06d51ba055ec1670fa22359e0a3115a58be094bd0e8bb7a6336bc7b1128359c0b4221347886588c099b16833e93bf8f6010d135020a8ca9489834d88b4127b12803faa030a72c49a7623ea66cb889535880a2d0756eb59936b725347dec4ba9140c33654b05f6b711850ec8154225607b974b55cdc64c41da02e537646f2591078c563e0b0b58fabe99a9696e1424d161aaa1f72fe8e116b1242224ca210dcc248f43ca754014300aa2bb89b36b0977babc2a52d97c615727903072242aa1c3376701892e58e418ea2a3036601e37a42ddc375a2b41745dc9bad55a5443109e7fe23d75f2aeb48ca4dfd335af158f5d7345687ac021f037a8ba19170a41c447bc2e733b5cc10a23ec678ca32c172412873b0e7fc7aad9f53e41fb5aa7928aa8247f157a6e5df313b8aabcfc58c2c8978cc6539498f5aa204189aa996a3fa52274a0170163b56331489734708a8b6c59a66edae8b575d975f839cd5b3685e864c874197e1bf074d30c41bfe01fb82085c8f5c43a26343aaa9184a095beeb6e01753dc7da7482f2199dd798d17660c5ccbad047978bf0a62d3b9ddcd92487f9103f00adc8fc9ca566a9331790bf93a1599cb3daa229f5ba8d2e33a8c7451130e17c9d4c91ba2cb187495c9a9a9916700e4f8551a4f8793a6c7e85327012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8b51fef740b0abb7ef3bbc8dc00599f711b47a4c858798a76494ed5f01796c43688339db7c40d06cc7d205b5a6aa3278f561cfda647f8961da7966efd47b433650ca5405770f5742b919c81356d0dd2a87b21bb9dda76d0b330891952c81c5d84761476063b452a6503f7565d406fb60b56cc14a9734a297283b2601536fcea5a67c42ead903d22b672d4828a93e2a321fac920771c1d038ab40075771a9f0ee97929c69143808578d114c5366fd0b7abda8a7ed521bded7bc6e231057988c362c5befee06895f89b2637c2866bcbba39b152651d5bd912344a9b68145e2ac69adb853d06f513e108105f65622ee25750595a4bf983aaf45921454e70a06ca392a78eec70fd5685b83a0532f4aecc8a09c2468fb2037f73fba689b82f590891bc087cca35772596410969569060a5d5ea0ae34b0be06ca8df188cc458cbff21615b1a4e0259925cb3012105aa50b494b35a45d4e9312038866dd4131fc4578674273e182d7a1a1bd049076d70aeee016a6c1c520d2bc404eb4fb28918f1990024d579175082ea9795f0616e584b2c7f93ab33944401c7bf7ee64040a3336ca5906e89cf406512539c8579f078d957a2f4b625f90561be79bb59244b0537a41fa0202072aa760a0e34e94fa751a49d68602d97c807b9992dd637c652563f7317084946703171db7262f71737518c52082966f96cc386e30bb6f89d02b93f8db8b9713580c7c62c06963a18681a1fa54a20d774e40c0abb98a6da5a148377a264d0cb705710f3f708955b16e8eb22754b26522519ba833fcc3000db88030546298b610451b50a247885e6321fbec37b2572a246e181dcf97b3003727141194337a108a2280d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34cb0c77b5407577a9a9cd8864efb80974aae107fa2801b6ccaf341d5456a86621f0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = 29d525077b2e5a2be67d74f27b2bf8045773ccb65e871518dc134d6236a14f0ad4f22301b3f9857f08eaafbdf3aeb67b19cb6229fbeda1c6da308c1db7df054d94051b1707404da9da700ca4afcba759b2fa27db62794ab19220a9148abc2a2232b16bad89b9af0996a672bb5cc218262a088da32884d1db98490b1fc57efdd6540c06f43e90edccdec19cad00de68622676e68f40b72bf179e900d0734ccd0411ab3a0ae82ae5961b63931b1aa2ba42298b4fecf9b3022da59928c7a2e2c450f94cf1b25f9c7da70102da7be1a1e07858a56f4db2a15b2e878b80f8b3c4b71b6841d96e7e46123f771dacab0c529758856fb6ffa288a037294987344e9a984767885a413a65839be8e5571a3562ac42076ac70c27d4d65ae047b9951e63ff890e3474e309fa24b9f281f8e250fa0d24c193d9e8c865039c6d3c3e9ea18ad2157ce17293784ecbf5948b7a0612c04bf05431eda24516f9ec56e13b6727cb3321a2b9dd456e5e92adba02900590e083c55eb8710d19c7133caaf0dad8f563b61913c2dd3d3dc9244a113537d61f97f7ef7a0554bbaf2011442026a84e4cb81a3d39b144fb91c736e55e1742feb117979da0fca764440ede26797987c2e43d6d7c06c26b3f347e58e90bc37e36402ca8e003581283a1c63e96bf9a37db9279dfba5e8e839c1c2f72015ad781133c436d95f9722e033d83f46ee5a0714e64d959620a386e8ca52894bc54879d672e870662e284451005db72601b71e95ef64c9c36526f1f9da5ffe1fe9376f9c6a53210e557c6454f22ad4b2bf7d90c92f6847181717df0bc270287543ac3ac69c16776c65336869015c2d912dc101589b068ad7e7dcc7957a839c652046f73e85348c4b842cd074a33e8b5b2caf2d3440f650c29241873c2a86e3b7910add04e4dc38c0c0fa7f0adcd4a4d5738441ecf7879827c14cc71e781f28d505238e3223182ddf194f05f06888092e8e964603f9923d82ce9b10218c618613b2470dde0dc11bbd36251db27b5ceca9aa0eed3bb8878ec119525ebbfc4c83c0c7185bb309ddfff96f36caf7701a1c0c3d32c1552300c6f48 +expected_result = pass +expected_shared_secret = 52344e5e173fc6088c9dc555cc90d8e5de19bdfa0d657ad8de1a3c24ea679bb3 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +private_key = 8dbb979547a684b4cac2e4824a251b808a646bc8b49a92c6e4d83bc82a30e9649c42b4b955263725e505dfe8614cd8599689025d0a189e556fb073011908609d86cea8f77d0c687555a88e8f786e2aa65c9154685b038252d06da3eb9f2dc068a14a50d5d641993cc152641881dc27f026cd49540d7ae04e06d99d5d45a056864cef0bbaa0e92e84f4593f59c636f41b7fba346c70239fe511e9c2b39fbc2bec1a452094a9f7cb78c3e9c6d72b5dadc8208a41050925baf9824316b17475e47bb2e7663ecc88a5c60e5308c34ac6aa97c6b5754b434d7b6e1d500d080cb29bb66ccd707254d824a5d84ccf883328033048919747377b9e628e99c41a9756ac4fbb4f81b47b9da81278b99b13b5711b936b42189d8b88ccafba398760738599089f905f2f2c62dd406b1decbf29815cf506971dd32fd3f28870f81393c2ab701a7426b542662c2611043705da7e8090b84645516e37cd4ec48ff2e1c51d0ab393877fdd660fd433ab8f2401a9206ddee1055571258c613ffcc8991a006a30dcc6b56816d0266a0665cc7e0c8ddd48434808289be16d236c6c9f04c3115923d6e879baea0c33c717a4946342b0c31057b848269a5329b8c5218d5b12c7ed3746aef52af89574a87bc90f4864bedb85911a1b6bb5c744a623f96b621430535662ce03b8073d21906636c5d959661dfbb32b3548acb63469b1489abc6988b8732571725cfb71833b4dd959b15783c8e0121ae95100304338d900a741597008f67312414e75c545c1d6af2eaa70eaa65fc742185ec2a0662443ccac36c06426c3dc49a14537cae1b8cd3a647db059e681acd78006df966213a757bd27a4c79b79905556906789bc00177191c0ded1b63629a5e462cccdd772589a24a04ca6f4cbb47323adb755781bc09edc7bce6e10b5aa11067df3b7d7f21cba9692a5d5cdd26ab8274a1c6b8b1fb1c3724f2b42be94758b701a19726a171cb4e8505c8281575106336c90aac7a25bd785ba3b298840f76262d561038348b15a61c6d1b6eba4922b7362f1300f53414dc0bb77cea68d49e676c3302cdf50106da230d1c2319d38351ea1cd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856560e0688f75c96b524fd60bbfb40c18533b11d3f6b24069c5303cbe3e6558f376b71da5161c6310ae651eb0c9a8dfaa2c265b85478c59a7b3519cf95176768d048018e8a24be09bc99f6a459f9cca9600aa8625bec4a76959d157371b2abf19130a6540f2f69821aa161da542861955ddfb729a95841845635bd208ab5a7b85527c01f811a98aafade122ebe57cbc89c5ab551c6645bb40b36026b0b10b40b7e645cb571b664faa9d06270a1902549c507b33a568da51a1a7322b53b95b92158dcad6b85e07adf6042f843a06318b7fdaca35867910b0db0e09d03ae54c22b580c33594b85361788dd12764729b54f92b74dca45a973872b00412da2d83eb12d8c51627c4be48955d8eb67b54eb1879479803b30479b59c578c175448525c514b9e685b3ce751b035836b229012709c679c1bb710b947a27ccf07261d639314c2b1d52a77de2c9c2230761ff5254714af940ab4af7ba85c627a1a633a994752df4125ada5c86a60709f37970d771e96f01eae2b322780c3b2ec01fe086be76710f51cb4690a58be890854b7b03dc04c6f632eb56caebc393bcc70410375457af17b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa240ceb7936fb90c0673877d0635777f8c2a9a5b03d8b731e9a0fda08187b44037653bf44dba3f29074995ab3be5a59e3073e52938561fa9496b3ae0031ae0bb27a7dd67424c39f250b5f9c2512e507878438cc8b086030cc588d0c2dbcb1024167715b52130ce969785b4210da26b8a6a18606597829bb40fbbec83ccdf76913685c48817111bfc216699a9966b94590e80a0d45307c36499c006d37a83a46e12bb9fb0712961db7f33d49d633a98b7a36a3b2ad5402ca190da1766071473fb21529221559526a2e5bc5944009cf2d47075d0961721989f8800307c91e04883ceb97308ce6c03a7cc39cdcbe8723822561132b6705f54345ae1480b9fa11184c999aa8a1efd17944027e1969267973cc3456c54140b57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a255d2e2fe01c87cf70bc30703644fc255f83fb47cc5cc5ae2c0e49d6198cae03f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = 56dd54d42839f333f0a3f8626c6c1c9280110f73f8f164502bd6767bb05d63f3e8eacf81cd3fb3e6313544485c56f5d51053efea6795836680b030ceae61ac68261e606006f89e2801c8f13e092eaa6fd9d4c3eaf87c6f4d101378b0d5f23f935413abaf6c2ec9335444290f877472a33e46534dee227b0eb35adcd01d37fc524d558cf713e511f51aae290ff87077aa8a0ab9cdd0222f3a8e0f6a9ae55d8bb8f16c28115c8fec4ad18955da20c21b08a90dbcce7121ef87c5120e843590f98c3ca2005f9d6b0cc3ed8ccc303b26b79bcdc3e9277423c43761798bd884d7cf3fbf96e67bfa1f65fa07b01d5c06be5d13e5d784658193d1640a0299d62964f156d56ec7cfa0d83b553db4bf6d00de896ee643f44cefd9b01a186634a5210dab6448239efafcf0f905ccc66637ee7c7dbf017610de0e2abd25f91c592ac83531ac0bbf77709463652a7ac98f32b67c0fd6e328975ce02110c8c5d87c0eb91292efd55a597e1c76ef8c87ba517431e486d7e3667c33e621add7e36821dae9d3b5ed22d764b48f8104166379f90e246f97f55b479760a4aa5f9ad703cc3994c7a94ffb1eafe91f5f1dfdcebc5a5dde8314067d1465d424b995e4616efc1afe1960df8709ff33845f6be36ddd9bc66db2c40274bb14ed42ad096d2da00a91cefe4648ea391952bc8d7ae080438fc04221f6de6ab6f1de94f01a91aa9abd8111f3f4036ae47e97316e736f7c6a8190d36284a8255cae43febdcbe558ac088a93aafb6bda5a8098347ac38271e4dadef96397b2f0d54cc0fa1fce77b24f7f9e4927e07bc3535ef779a3e8c693e678b6714ce1b124bef5606210919ae50f1204f82029dc267710329d7a4d8681f2c41c70f287c812fc1960b021733a287f828150bf40acdf723e958c3cb3f3554850dee43d24332740e6573f4779e88900d56422e83b3341985ce10470eb6eae2d5f53ae79d2f77e32da37725e2515ed7b1030dc5f36bd13d8874b0e8f0d07d2d3b8035ff8bbff0abfa7dcc3c042acc1350c643d48598cbe7d5075078d9022e1629b5b88984fef4c05b522e644f59731b399378f6486ad +expected_result = pass +expected_shared_secret = ce80f65731c8fac072f7153bbdc425f76189d01bacee8462060c62dfeddfaf64 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +private_key = 51688c6a414adb473f37a6bd2a73c9a6f6c96fc25e68e45aae8670d003b353c157a8d8b07436c59f1a12b0a63416f798ec80bf84258ae127895748a22e903becdc5fed6c922eb41aaaa0bb5fc2cb22384d81bb53dfc78ed4d4652073c40da785585102add4bda7e90dbe491c06131efb583d6ceb7f09c781e62337e202028e437cce0832b6d02edf5403f04571bac4cc6961729f638821048afd80bf2bb9925c3c1964925fb3b62f615c590f4abd78679b44823117074bf76b3a0d104ae073b7ac0c564c220e727a7e5a958e37ccca5397448dd55b5024a439982a431a6df39aa62146410b477f95473ee07c73662114d14bc7bdc6697e4040354bbdfb511a72434073301cf1b2c4ade05fc291aee99771a8e9863596628da860afcc1674671fb9a6307f562babab6016809a3b88960c0622b9d21b3c632df64bbd68b92dfda06e8f1a14dbb5ac30e6815cf8af301ab4ee508e0099256e290235f683ffa6470618519310a4ff4576444011f97aa9a5bab14ea90475828b9fba6dd4134ad3d684d52660522091b6971ff7d88b74746326e5990467a4ffc78fc8e177bd2871c35195a4790e4683b3ec81a20c39b5a784c8e00508793aa4333c009a907d0707a0fec5697a52725b563984c73a306388acdc57eccc650089b12cfa34a0335fb3039cd786233b5509bdd2787f63468691c8ae72363ef1723c614fd6bb1f229a691369acf0dc84ca205da8d8b9d852cd4f05a621bb5aefd2a26534a7459c76b2212a8883c772f661be393ece185bb0e34c5a9212ead05be4a417b383a11c081b46a67685aa722ccc9fd7d124ae686d1144c5fcb38d0c0896da5944f018886b671801239b13d8b3de035884f30bb91547d26b7a3a058aaac800f2f48715a3bee7bac856b11b455a54d9c84f30b63eb6dc3bd58aba6ce0b05724149f21ac79f6545a3b705d951a5dec9710e44078688449210ef0107949cb0ae720000203870a23849f95602c30c848064959c53a33a400af949c6b0042824299abdc48bce567287a749e0c11285c8ab4669ce6e53558e33c197ac2e96a3d97e5992db7c4c48c5ec42bc2a1f21b5f97535710a214345eabd39b1fea121ca7c866981a22d06c547017d6e16aeb14a105ba22ff5b2304e10c948c0c4a376b9e5c2425920ff94953cc831ad45b3f81056b6f321d4c063f8323b0e23813a5a0873fd71d93f9af8059900c973327a048802a2585f29f9f81714a869047b0cc0f07ae4a9b5d398469c9832a7dfbb79fec3fb99c5f9910183a5651c2077f62817ff62c80c0f3ba5b89a19c8280f62b0162a87cbb2c39d98445fe49072103a63782c09e7bc3bebbb21901b081729b7db37379017453f090e5c672a1fa195c49601735c0cdf7338e0521ec0946ad2784eb1a5e138c21c8c04244d2c8e7e0a43c7551505aad3d85c9d640885ea8004fcba8e64c9da72c0ec19197732156278c3ad64282bf9590934a2806680f4e8aa14a8b030519ccf3896abc085566bc5757a467359018c79b57c149338ac2680c249b94fbadb134be1a911deb09add46ab710f930c4c24eb4298c0a05a1af583059b7724d7abb6702bb6680ce2fd3bfc73203d2a563f6d0b8ca54b0886998a449b70e256f22f7a3837263929b22e4a6c97d4141c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320b426749cc971c6735ac769c2072ee88407998399308a1a81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec325295000157857b664b548fdf9bf3924b508570b1a003cdb5158b4e61a8cc0054ecc9b42491bdb9115b8492848f0b6b236b963571ba882279ca3b6dc2532a481cd24375d8f9a199d955824a48916502beedc12c138998a14cd75190b9dcb65c5b20af7fb254b97bc412bc338a6c0b1873802884475636af09a1f222ccba2363c0b873555360325e18b2be4c33edc29e6b874eb74bb12511ab0364245f058ac90561d144ad230ba7882c893d9a73c4a03f82c5accc04031507971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13eca217b01647db07c8726418251703cfb653bc72e3a32192e489d334c53b91136d5b9794c96a8d3519467571a83e0b754b655c85a818d51014a15b03564b665a80df21264c5ab8ec8902be351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44763b304a19162abdc4234e6046109f99f955695580a8b782017e107e45575bd78cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 393a912358f736691b8e1bbfabd7a3ef373929bcd5413ec74e948c14fb4f6c03eb9b1e58430f90165cc5af167ff8b6a3f8da9d6e1d61e15e3a1d1797c53c4ec8888f06ff4f09d6037b22877092fb93f67f58c085f1dda1707a51ee4eba60291c59f027dac77bf8a70d630d8caef7a16016e7ab3865b6543ed7b413c2f2e031976a47fa9b9e4a65c8417ff7e454ff798941e5f34c57de545d5316d220d2f0f3a863c386a8632926cd5aec6e22c3743bf328cea18d0787f3fba86ed2ed70159df31db98e3e0a7cfbf604f90ed7efb99a92e8126d4fc965e67d9b4a054b130fa3db3f0ed0a98294c40d7ca6b2fe5e69046d4ce1f6ae5d55670cc1456e847ed2d7026c2d8604ed66cf146d7cc48c867d7fe1874c86ebb51c4945e2e149e7d13e0827616f502694b639378165aca5172718dac2187806556917b98bce68b91f9259fb62af2254e14e3b94af2ac7a3b8ed2f598154ef987332f82995cdf04e03768a38701ee44cbed47700091ec13150d56f72a284ab02862262a79fda8c6530ee1d4bd0487bc1dfbf27f54f51228cba703a88607c7bedd776bbac31a9457c92e6e16e44a7cda858d8f3237360885f2b68932acbc1c56e4d8b702dfde44a3b3909b825fa01e8724197862d4b15495a90dcdb1872f4e16ea0ff6496b7b57e5138bfd3170fff042410557f694257cc69e54793fce228c95523a9b7905932b4f4147c342ec54df67afa00b4aa44cc3564cb07faef73c025dde8808c7bc785c4859c6060ad33932d62a73a629863c7f821e234cfea7b3dbb166cbb7a10278311733e47b2b3de8ce818b9ba370b12eb2732ce0f824f1845d859a06fddee009b012b2bf7571e74f283dc419a5adb2f69a7867de48eee208835ff63bef8ec0b5b3cd4177f3f97bd68d770b28199815e3f2257cbf6b594c09636d2e069448450e0f492646b9a6c6efb0b206f12b5d93e0a09641d35b936f1563af0c1074c20d3c1c535ea0ade45c48f73b766b4937ea6a1e329aba02770141e6706eddcb5c639a8103810b29ee5a8167b4d45637ff6a77b6cc1aea1995703c9a498ccf81c893038a074244c3ad4 +expected_result = pass +expected_shared_secret = 3b23a3cfe57897fa9cb691ee9805739f40d2bf22930ca9ee48ebb7163cd66bb0 + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +private_key = ed777aabf42a95e30fed857cd4c4758c2076a40ba9534b56b2749527ccaba7530a422336913283fda435751b6d2158abd1e304bdf91160e389b8a3b94d610fed22268f685350590a44305cc57cc98c97a6a2345c5c29bbe6cb49d182cb499c83f19aa5876ca90ec3bed6592a35744cdc44770ec1094f6989add64378f739aaa85f4f4b98b9750d43a05820444e5536601f71a537ab58d738b7c643c623302d26d70b5b242e0749ca31b95a33581be9770665631aeeabc6e6bb450664aff4116e6e818d72683a442c7c14e21f95937c22d696706383d9e84910c4cfe4c57e487768cfa0066ee79dde868ae6e4a7de470c251c2cfed77a154b0bdd258ec7409a694645ef8326f7195ec8c07de2fb5964478422263a5440ae351917ddc7b7620438d31426ece458a5609e2d404aefa94c1de2275bc46fb9493ee8b54b323150fc5abb4221aa602c9ce36c34ff854da0e3595f2199cc2b1b2750a0a75637239a1266f9a7d50a6c86d68f1ec7886f90c351e7001021be347aa623e964eed3cbad45a6bf92a6f5c61bdef076aaeab527f38ef7304f7e2a158ebc5a06b23e16c356f9b69fc4e37920089a6496237bc86e1e86b24bd1956eb67678aa416249417f0c87a6fb9c88e96e39b7ace53543541c425655b2a5e405cdfc433ab68ca568115c535391dc80db3a3b62f3153637a0c4db1d6434a1c995c093a0ade3b1749a758a83c0c02ef7b117f77c74d2cdee2314d3cc458dd89ebaa56a0c295b57c19a315b3ae3e3ad7c029a9fb381e07ab2f4b07a81415913f21b6df48f8c77418e9a224450aa2731984200c0a7c75d517836a7d7463e3c04a3204ab331aa42d7cc56b52e49fb92101400ff1972a8f3bfebd5a1a6a3946a4152982a10d29c1d04cbcf1baa86140a7fa9915790dba7b311b2f3acc6fde8537193b6b950829ef8438f8c90127c44b780157682486e01928083b552f86f894ca6e638af02c1215c27b33136022a129d7ffc5fbe641680a89535774c2eaa259b158f42ca50ee75a7c9f62604bb5bacdabdd2b304ad837986da0f8c9980945cbb29e64ec0c264be853e02b1af4944187ebcc6700b95f778cec6f514b10c58e323ab7f013904345308601ecf1707f8350b9f29cb39b261580c3dd2651f96e28f89ab9c1ad86cf77cb3db7aa8a05c007d0a1a93a0a83e85be418a7f141078581a5e60c25e4564691e11b5f16171564a1214d8be06c15f6281324997a98f6572adfb62612c6623d4c9cb24bcf0d896af9a16bfe000354a41f9720c53f1574f97c6e8a49886484830d5822751c6e4c94df54aba2ba767b2b3199148bf8a0a89c620866f1ba52c46687af31abc6a7b4fea9e5d6c70a5570f3d6a6113674c92173b6af4902f614f1d508b3b456c406522d986c31aacc3653098b0985ef1879b204261bba81752425d7cd549121983ffb30b17e181d2b8b4dc049f248b55a25b561aa54507141914e580684395e332225089bd29a934ce114f60936d9ab50f568362fcac1153620791d318dc735253085c8c164719b6c0b426c136a311d704d009f226fbd340ece426a25274da929bf5a206b1520bd114c754db2dab0b8a881c03aa569091f40ec3e38422c3b8d4b2c77373853e57068a591663446b17f676bbfb941abc0e1afcb01d939b426a551417acc95988d712600383063dfc5a6be917c3e4041ea5496ab68855b6caa6c92b463692ef2390ce797969715141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e163144d56a191e29c66eb75f86d6baa9e2320b43463b300000083c49a88b6338c374341cd83c1c15266fdb266e1e0933086c7358d82770aa652b7842b2b9b6f9165613d4a27298c0125a2609885d29715f9cb854cf6a0c308b36697cb1f5b530c7625694487252872c70ac1ada8b4959c681f64c46c5ccc2b3972b6188909a1955d99b65b0b80aec1770f60421cda11d7822621ab46fbba61cd0dc6df4082609105839d80ba850c0a8342be5a70d999386167ca06a485368276b4f7340cdc0a9b3010c3fc3726da1ad68043c1665b1aa4413231455078cc898d938d2c5663b1c200fc87a3b2c2b5c5b0c507c1b7f12ba711680951ac8ad9c7e430345f2f6ad3eb9317b044103a82bb03949eaf288b2377b66f629268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf8459233c598a48b06d7474da19ca85aff6b2b3303b5d25b96088c52a08cc7f1e87c5fd8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = 68f8faa185e730d2c069f2c19a319cdcc138ee9bba414fdcad84200063554fa1a49e182b572800af2afd4d0ff9354aa4d5520db148e31c2ba8e543964e07b2fedaf011dc760820dfd9b76b40883a69c9524a9091864c1b2bb79f568d9ad312760480f7c33b1068d89e5264b2735498afebae7ed11b7bb5474ff5bb87923ace45ef4ea7aaf65f0e383acf89c795c417434d21cd7b92ef27685871a0145fdbdfdbdc93089f999099dc060f78ca73056851aed35372119dade9b52039af2388dc3e39e612bd0a70a022a3ae486f11d39632a302a02ad0faeebedf8db52e2737b94145984d0c3866599247b65e566ec2c7cbbd18f3ab2464b75ecc9c0f0fe195e1775fc33ace93fa322060e968954045cb3dea4021ecb89df8fa965095ed8476e3e64052d2e5a72ce5fdaa36ac07a79aefa9f2ab44b31c11d9972263e9a1f04ca95b7d66ee19f97535737f50cbd379ad17e9880abb5c340ddaaa0c26e4ea60a1810dc83ad1804931294751c98d48293364bb3fb8780717e9363ec84fa3e7bc7a21849fdeca93674b2bb90cd88eed2c89b4b989d70fcf49df184fb07b158c9c3cc9e663d20f1d0a5ba555a09fa9359e18d0653be2bc2cfebbbc69aea1c64e8e0bc9b8f0cbb70d60881f86e4340278fa0b116fd36f18d40b4bb12455ea0bb1b4de65f8eedb5ffe7f206e50349ffd501708d452f9d487a9dc6474bc15f59da9a5324b465ff6c2c863184b023d79f02ad257c097f7af07f944a2f4b8ab01076f4ac40230d373538826a63e7d8b451e93e792cc5506aea14581fe1a69d5bb9e96b585967f78500e7bd9b023fc0816de2979dbfeb1d160939570296830e32bb9ea54abb7dc8c0807eb22bf2c2ee4e6b96e1f06352628e64318e5fc0a4c466df465cfe0ffba056a648f4e183dc37820b57ca7f2dac512e87c1bdbbf8b8cb8ce72d9e183a26f957203d3b91729bd1984203ff64ff6ccb5ce1acc1187e8df4435400cbc7c3723f4efe3d876c5e6748052e5af72cff11e07dd7c5e058ca40d289f4d919986015add25ac4d1dbc559bd6fda9af76e1bd7c744777cd5f5a7d7792aec92e0d406377 +expected_result = pass +expected_shared_secret = 272ecae17c3d107a8b008f60c8844ac01e09b8bee17eb4972f5f71774af2d54c + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +private_key = eb7abb66c3c749399680d531ce787eefeb5a80c16c6501056eb314568c776fc320e496c7b55b54b253c669126f612c3a5395268826aedda5cea1a7077f946a6cc0435c35955087acaab395328c91c753975b8716b3647ae8d21c75f613fe461216749171b000fcfa3c0ca38e1da915c15578bd102e06234d59e88c51047f68c4cc12c60d0b536b672c3e6a9a322db89431200532c7bcbfc68cf9d775d0d722fe7bb9f0fc7bf8dbc4c19547c1031d23662173c302b23a022b3c0997914347081b7d433834446ea56b43135631932133fad226010a3b6a07424d2c361efa7f27fb65033c17a1ac3ea85086b3440efabba894762808068ff4e1579b356f6a186d96431af9c2a5724625ab88a36a6b3ed4901e902630da4a101b8445be9ba9738a761c74536f911fcb1178a6a5680035ca0d607d77d07046eb8568113cfb4a02fdfa8fc207d0b9db8eab68296e9a8e33b01eb11c81a8a94def449981747cae41394ffc5ece2581e398c319f557448cb4152b301276519810193b864a09612d5b982f8326750dcc472cb356dbc1cca28a145fea0ceb8803e03c36449b16464a673d3c4b67aab5c1d11fdc06377a41846f60c4db0b3a7568060a970c64989000bcab2eea24a0520a3ffc0916ab67e6e557860164b194b59d552c199a0e2803b0fb2b1306ea6b0ee687db661357739a3c887a8ef551a9132473b2c000aca4b859624e690b6eca49b20c43656397168c00e7ea1335f48f473cc018219985d72bced63c23b4c0fe036322e060619177d1984ab885bf11c0cd20f518cdb8a447356847d8b95bd9ce3285702286949e3c61c0c435c8e312d9092b60437531d8490dca08261ba4a57753661b2f853307cfb071fd3b0f0d005d6155b117f298e2a84a3a34bffae668d91b5235192a0b55cbdd5b723e8191087c847b116ceab7292c17480065c93ba665656749c6264ca53a87b27485c0e2c024893374312a58c7c0eca0b155f5cdb19497c08baa82a71908639e45121c827c7666209cc149cd71f50598672893895521a994b9160dd01baf081aab12681a9f26220e65531f389920b110e931401a986b25b24c36a66d747b761bb2c2a09415fed46551c6a26ab62819aa605a84c9d164b5146c6996f3a33475aa76d055ffb45617f256e22028426b71ea1404cecc96aa815f5cc804d83bba5d417caf64731906b8cdfcbfbaca0e7e0c924cd19475a88668c59f24b7b0aee4a63b936942ba263bf4533dd29e7f51760ba638702ccf6472305e5a0d404732e0a220b269affe711db0a8c2db11c2573b7c3a83b673d37ecd8a725553be79755b803cb866a90e12a4bf7d8275fc7ca07cd20ced0ac9a45c54953220d5caa8210bcb3e43289ba03c6c3a982b5b2d4b73853b1b7548f7aacbb0a4ec2bc676c55dd594aaf630ceeee7a58f076348a09fbb5b335c43535be99d552298acb1bffb30c9adf1c5fd221417874898132c00b83cb367bd79f734fa1c56cb63a8652ca5a12226961131b14018139937c20c82ae6964e0f4bf06f30cac7382bf2341829236ef27119663c1bb34819da72cf71b3faf01460b9a20440947452b52ca4bb9c4eb9cefb8c1a308b2dcb20dd88270bc71b9e95a2c96306ca17c769d301e01021775238fdc6235f89939b47774b5fb5293d2cf4875a698d33827ea2146b4c3aad66f2c918d9e638874dcc883a2399df38120b8baeb9a52b45c6d0cb2a3c766336d0ba7fbe55ca5eb203e26337d29438641bfb3a29d50500947064e65f7319854b6756b2e40c75b755ab983b52e72f9c5cb293e2aa34cf2b23ef9868278c531bf395434fb347f29c079395f70f62342fccbe37cc7fd4ba1eb49699ed30dfec751157003f8bc438381813d0c555183524ba8a248f531495210a6947ed6963da96c85af7bcb1fd8161a07c707019b67f373c4692c27279e67b677c2c4cd42b33c4662b012ba8a59b19391c25aa846814395119d65b585c39e738359a24bb0d31b266a81471ce25270d0715cac1c473c10270039489aaa70b5cf093ac930a91e9ba356d6a76fbbe8903781924487ca4cea7a67558e55011ccd4190c6ac0d8642357441545b477e0538b31230b07b17595e55340ab681fe860b21b9b893408656f920e8a5599fe94dea1b8ddc7a6eac61cc0457299c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e9911b6283fc6dee66e16d411fe39bbc9f53c30bb54f05044b96c740ca051c61ce40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = 762d2b975d7e97164aad923f4551dbbb99cfc44c146af6e270b3288086ce9b768dd9fd07d746a8f076d496729b50b44f972cbb53987762f76e1025741f203efbde6b0c2dee48d4aa224df0ed8ea7ffd70e80cbf50a4dfb099ee701fee01cfe50904e2f1cba82e7ef507777f0ac2d21d1a285cf8de33d59fded7793fc05b7e3ec3176b005e0e9ffa689596c04770848d7efc999007b762d824cade5b9789ecd06d1c73e7309a45805cd167516940dacffacfc9d049c4656ed397c3c5c53606cc927b5442f6ddda90c8dd89a68cefa6796d6ac5c08bd2d337720bdea8a25f0fb656c6d548a326483d6d669b1dbef7f33c26355f34b5b19b0915f7ace782168fe0a112bd4c2cf770660a421771772a53dce19635a4676d430819095b2b29f1d33d742e4d9a6b57bf8f32810bbd8c0890219fcb3c73178264f2984c74f5ba6ccdaad83804ead9ee123e86c394adae7665bc2b962cb8ea82a73b03aec1fb90c45c7d0adfff1acd946ccaeff9ae907b33d01a900b9c98ffe78f22417ccb06e8e735db8d1a9a4b055ba12b4032c19875fbb9efb074d3fd67a2701b34976ef595c8ba84b82af167ff718d14a144cb5dd593a5114d18c3cb8c2f552511def9c6c6d9baccf9cfced749ed26d675aee42deaa64dd3de0985d6eb87da959f55a55151d9b35e6125d0d297b5c70942463bee80d8fd918ce36dedf8a5f7dcdda38af8cf7e227d545b8237a690fdcb78d0fc19d42e872faedbe9b959c23fe484ab831ade77b64d488ab803b9ff82725ea57880248eb27596f9e12b33cb5ce5396158f74a3f0d83af6a8032ca0898b9e436d3e8b3406b5aa6e9de8959e2f215fe4fe444bfc56a97292eca756138556a5b4f074533b484062b0324df72ee28609b69d4992babfb15fb595fb59425f82040f0718a9d2b36154230ac7583079cbf90b52921cb882eadc643b5e601cee1d3629be8bbb5a068cd97a93d30a768a8ef0ad644eede70506c92ed70d6d5d7cf89dc642ca06a3ae69ee0e40f496bec30dae4120bed2e21d89405c062d029270f4fbc85075551858fd6ee48c62738a748593b1685b922becf11b +expected_result = pass +expected_shared_secret = eb456d8919c7e96c4e18d7a0ae27d47996e4f94c46c60b4649b327903acdc0c0 + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +private_key = 8ca51836784896f8268d5256f73a3619466dc1317bf82932e4a62b454657b756c17d810928f742105b41ff16531c649f95490e4f6a53b2bc0eb36cac6195ce6cbc974cb032cfd5505fb77bb3a6638a05b23c47c5b387554fc88f70b06feb8a59d039a5b727c2bfa60ba0e785ff0c66cf88078df29f40915713563b7f33bb89a014d27b54be5a37f8fc8dec209b06ac8000c8816ba97e68f6c01766788b1b732893457a38abd2798eb16920678bab9591b9e4d644ea213f3dac45dc5263cf8782b7f9a5f0e01ae409599112c9041a8823a88117953ae944cc0541851719a66a219d9cec69b554112bb861f859050f456c13c73019684edbab9fd1e127703740ce863caaa602e8c2a765f259ac91a21eb5b9db6a6105489b3cf08e1c58a10b35c7341441ede777dc81cdd6c531e4168743731803fc95ead4979e57676d05004a2526fc9369bd86145003a8b6b3bf5b4699745728a64805fb89336ef991ec97233c6718775969164634438c77b7e1b86c25b60967a9a0d25b50c8a19fbc55ab656a9e354e0f7b20233009fe907a92361a3fe60352e25c3a1c06697113b996b867f307712544274a8975a5855cd39180b1644960b0254ccc9b38c3bb140dd38b34a3b220cc5c13104305c45a1a8461340b4b30bd69497bf3ba0524526fdab58d32b8fd3b03e05b61aae5014f5684c52cac3d81ace4701a4b7199c93a813e549170c562432914bfc02f8a28a3a95a3b12150e8d7ba897e634a8835410741001b49dbe6b82bb50632f0846ce6210bc4c35266b3eaf434ccfd885478ab671c6ac1238cd02b3ae1b1b76dd9418feb30498a8683d01044587545ba5c5e3919f7996ce6d51cbfeb65fd61538f8592462ea268d07ad28325094ba467c6405253c07aa405ccdfb9dcaa5993fac5c407ab29192a3b81462b9bb6e783c3f589122e4848f3402c1c63b4e9cb13dcfb894f29c89044b9739b0c4fb19cafed1390f2936f529007c292c5d7cc22e3a3ee04b26f23cbcdbb87eab79abe9288b0534220ac3b8e935cad8a9494f58ab20573155385628508a3d87b6432314054b2623434c540b196d78c8b0141c2b68b888e674a38351470a3c831923aa3c3e40a2127a28c1a8818d42e4a48c036191681bcf982c0f13a79d643af1fa13eb32444d1577e0c1795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755a8199ec36c2c128c68fa5b5854348d55a1798054ab98a5203dcbcc5121300b15026c8b4d1aa329b804b13e61faaf672f0a304db82cb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b15211950b5551f0722a9b6a7ec554567b2c975af35b6b88041c01a1f182a50853998cc395c1081e0d755d0fbcaf69f85df21567a0a24474571d2f98ba93f37a0f5941fb8204b0933cf3cb20a706a06359cbba272c0df68647318774939d18528b8818ae682743071795d512b29c794cc8a6c0e4b827c1148ebe2a0e72fc50a3f71df0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58cc229d9623983564da34cb71a729abdccc3cf70bcd7d20aeb82c9d306464e132a6b9989c8561d90824f6796420e8b8c08a0bb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943181b16f747b7d04a7f6996983c494b0d527879366c3a4a6872a79c8c3aaa13f11695d36065d7843acbb04014539992ad369024f56636166990c23c661f34a584c12ba06a16aa582c887015cf96b293757a041b53ec695cb520960d959d96f57bd6da44e40024f5e04a3a135a1f112ecdd57ffe459bb22c84008d5a2ee831823b42102017f14a71b1329bddc07ef7bb02e8ba40bfc64362bc369e490675dc68a9c0b54a91b43386cc7a4800c9f60f2a562253904c71924fc7a9257b94aa9f78c6853a85d09ab7b07101b58309424420c744076c446e7e873c67d67a40cc3993d48c1a81495e54a5fb1200d497080bf21b33211e919730dad71c2a1a75ddc983853cab3cb55a3fdc0d778bccb2c42037098956307899123f7c5b7cbcf107fe1788e55c67fa65968f57bd85b53a29005c6a2c2c30ecccbf09904218390fc17f4b07aa2d350e9953705da8bec6b4048e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433e78d350d2836d1d17e6ec375a0cbe0d6b2afe1ac036272dd41f8aa769c9d0668ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 27579d6741c227497fb204ca6f32e119fa6b84377a1171b00f000527e5ce0ad46ae7c20b14b7aa32a048bfe7e491a500853568ce87fadd3a3266d389bc517a99b491329435e0b05d5b2697884528badc7cd42b91a76676a828cda05c94a497815a9f24b6d6073b1568e7ec22fbb51464ce0e78a4cb7115910f9f9c4eaac8a6cc514b4f473a5c7af3199b1296bbda4f71bf10e9001a88e4c91969859ea72340c4c1aa62d58586a9d4c03f946644407d8273dac810d9c032a890196aae72f549b0ad8bb4e15e1d8b07fe2369e104dccd4de63080466051dfdc76407ce6bf2dca8fef785fe60af4513d3f2d7753727b151fd03e9494153ea4e04c6593efd5d162b978d960499c5454cdc3da160454f6bbb64161661921607d07a716db783cc4b2c034e3f95c0ea7886a875c4f4904e29aba83095689da0519e3e9bb1d5d7edbc5ba20e266453573f9a4275f9fee4a85baf8bcedf1eaaa1abcd57169f97339100a784ce74bdb4e448dcc5d6d4566f646ffc8b03180ad0ad8afa1adb11553434293e1af8532bc87b8a7fcea9278eedfe4f92083e1b88a16ae23339cacf95b0727dc0a848739933b150d5eca063d9b6df4acdd3b70dba42c22be1ff37ded54ee50f439327d1b8e67e8a611036a5139ee2b97b3d57f28c1e0f68b976a1de23e181f68553872a5bffea7d7cce6001494b20ac48e9f645ffe5cdfb1edb93f36b33b91629eda556fc121571f6f72f86183adcfb8ba497d3b1e9f9055f0324b9128e37b2828cf99a80e4ff4155eed0a86bfc2da7250966783ef4aa91c38f2821a58f49ed947db17494c98dc32e33733223399f6cde4da72370ed8587917efcf0251c1f51099201159457e44ace6a7dbcd3ab57fc9aaf9a7eb0f3bbfede4b2e6d257fb6c7fc9ffb9ffe4b7e13cf3dd9855b233d781cb0064a00896986afe00889c40c33295c704f4a0808c44e32ee5da7701290fa5352fae93f79995ef6f89d5e061e4428aa73b10e9c4cd82c70b713d009b9847eac80e6f510e629858f2eb00f1d7eefe460cbeb4f10a7c6c508201f6bd916cb52080cb149953540e97b1b5d2365a783ce3d4 +expected_result = pass +expected_shared_secret = 3f92ab2eb867d4e2e658917fe95b19042cd768dbbcd895e83b7bfda621fc428b + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +private_key = 3f609cd3a1a40789a492321ce6309782d8a57b34207ea50472820eb39827d715c49809aeef03166b4169624b7aedca838ef52544c8422e4632162212161117187b0501d08c1c20417044a44627449086847b7867e1c7c4522972508856000db4eb0673d0a07ed0d62ed7f46b0c69cdbe2889b295b5efbaac4989629cd74311097a78fca8188460de2087d467b8f382b030e51b2ce940a032675ed9751f6a7411ec0050fabf4b3a39b678719c692a5886a4175261c1a989fee70255666a0071303e5bcc9f3598cfc840dc7224ab0cbf4f547dcc4b1d7bba4655205c5431445e69a221ab1680985df6d28ffa7c01f7e99228c77926ea4ff6477298f86545289603162c418bb33a824a0ffb8c62d9ab5939cd22d56e5fc8b087c96018e46aab76b194a3aba45280f3401300edcefaccc5c66050b6c194124a221be240e1cb736ecb523d74291ef08312b666b6d5287c56a70fa677065149fb030bbac88fafba8174c349b2a760b36296a66cb7ebe9978de623d064b5fbe8c2dceb34ae2882d673a5eca0bd3b256d81667f11d951f26a8416331ddd0c76bab6854694c43ea50fea5b55518989813482b05484532410bae28bb890c15246c4114746e424a8da008f3886c6d1d99d7898425ff68d850bc0a6b82f7f04bfc0216e71280dc6b44930e7a7d5b870eea9c258d7029aa936decb5c574bb1d4d5244d5a1f1f2371e498b70ca1a035d403d6609fb0867e4eec9e4c46650d1368ea70a8193989c4b8b9b782193d15214fa9c37ec64c85741b6e746eed8698cc8bac3bf0a4f8d332d8b6ab888733b0c1158750bbb9e73682879db3091c96244a9bb0c68f1b2985833009978134bb2d64c24f8f60a40df182b8b3abc2a407f765cb54f2af96277e02075271e901cb360d8b7160da057daf95cfc7bb5cb59563a0359800eb78def9bdabb2c655bb4af0e71e98c38569eb74da86c2ba30020276028b0b59d94a21c5348ef34341fe292a1f419fd9d03030dc7b6f525428781fdba04c25d86fdbb3650c2c8ef5153398d322d338cd7c892cd81b80a17b9c4ec77f64d4476698029c9645dc649b23db0e2fa2cee53ab17754381f14708ccbbd3a19ca2017a1637b08f2e9344ef76d5fd0ad937b027ae58787045b9da90acd172d29c02f2ea83b378690d6e694eebc39dfbbb12e13331503bccfa62b6058792c2642b365a9fc687661464768221a80d529dfd9abcb15813a4a6aa012010ec6a008419a6c8238f068671dd1b3bb3b10ba023aea01a90513518d5c6582329ae43c07a6929c3ce1740aabc291e440f909362c7c8651a64e0eb84d82448e9439351650318293010d718e8762c71dbb6cd0385c5be0c37709924bac6b6783c82431527996523ecc9bb462a1eeb0cb6276c344eac257bb4c4ab0124d6b1b7cf7473c050e9cb9762e856786ab1b5a9bcf69fc90318b3352e0481aab1b97279c088b397b419cc4cba756451e67628f535642b2d0cf71644e6a3b6f9b5409fbeb284356812d613ed338cc28babcdd4b6753f4bce7a7c54b077a5f162e96665a3299b938ca48ac0ccc7710bea5384fc4948dc1b56a1c7272bc4a3fdf53706dec2385db3767c4261e98c49164683cfb420c33cf7ed68cffea4f43e41da5ac727e87a981877e4ff12329e91ecd524790c1ab38784d89258562bcb5841ba8f0f17ab17236634a7019a520f48695ede951fe9042eba78e048791896844025a37575b2be610635ad358d0ac7ea3bb93ca4c8dbf6b566d00654f1541919650c4a88c9a19b4444a5cc7fb4ff087552fe1a288a15bb0941f71f4568ad3bd01c1991110bd2f755a9c7806ffa005803733e2e639e2da05b3fc71dd7a42e834190e4872841215454b294bf32a48c096d4476609e792a4e5465d5750aaea38d9eaba07fbb05d10950ce23256727850d97e16397e9376674c37be4fe3187c2842c797ace9475b1b42c10910270d917ab6cc42a573c51339c04c56a6b0150868a9a330620d886a5e2103248043b44e005a7344742ffab697f086526691b073aa70914b391c3cc31a83ff81a11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb07323c74a7892e5b3ed631370a65cfd4b1a4212348e54506648ccf0732a36c9b9cab979ac6c4c16b9ad0138860a392bf49490068807fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5820c7564d087683c0a4864844335bcbd62afa1ee542c3c1dcd8b72c80824b501c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = 8db4f31b77a098ca2872b02e77df4b56649e19c41cea2e1768b444fe945613d7879febb57bbb20858f50c1a6b6e46da00969fed6e088d740b90d1cbbbfeaa04d1cbd6842a7461c05517136fd5d76bda7d246b5efe5474ea9e6789ee935991f11d17970610c211404e576d8a976ebfbf87196b0a9076eb11d02d0e7f9b8a7bd603733adecb2f16343902d3e477e1eeb6bca301799166a19dc61328f903fd7d132cd07b28bf5715ded3d073626dd69eb14db57036b176e6dff87726cd5ed04ac02f53b49107c560658191925c39a030dbc6d7e9777ff2b6d9710938f455fcf486d5abe02dbc628c1ead2d20e7b1b96f7e7f140ad331318da534708573e84d8c2190e309c68e7d89f62c986e9feb4c23575535276704ade52623074b53dd967bc40b23efa52d2caad7174b9eb16bdf3c5a396ddd494e6c4361ea12b74930cbcbbfe961410e753caee1b36e5dd9b210d6768abd092a419abd917bd5471702f678e882a848d4f9350b435c8e9217959a0e88fff18ff2b0ae6493c6ca3c2a58daf37e770c844cb210256beef3c7efe5d45c98e1b9d16e0fc334752b717fbf1f90e50123d050fcd5df3d719527b78268214ec6c2faf45beaf6707303d18d4b139891fd3bfb632b8ed27e39bb5243fda10c0e093309d22a63939b0fb266525d7fa76fb3727a325977f348262051f9dac4a0bd0169454e2eabdd5e62e2947b29e9ec6ca1389963ef104a995929df72051d7e29902fb4c92efcf2dbb03596279e775b30601cef58d875d07fec568c86ae0d2743093535ebe1d2485da2dfa010626af3ce158ad4f31f48c3735e59aac57d3d5697e842165388836f85301eff17ca0be02cc4d766a5543bbdc3b686b1498a4897747a8aa75546ab90aa6ed033d2e599a897693380056485c7f79d721236bb006f751f1080971d2968bdd380b93a56c852197d737331d0bec9b571c35031c68ed9a40d0481f331192e55ea1fc3f6252055dfaaa010ca17b3cd06d0e2a67873695695c714e57dc1cadf3a58b75dc6cb471303bd2c78284d6115b3b37cedcb7441d10d29187a6f15e26fa13a54314b3c0e44fe608 +expected_result = pass +expected_shared_secret = 5890e86b38f7fb11708a63f5e98ad65d10db5916e6669e1b0161142e6d30d017 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +private_key = af54bfc65182aac49a785108f30c5048428b97fa3843c48a4032397b479ebd8cacfc079444e54c4f764574f11418f73c8bc7bef0a18f5ca7a2cbb6312d4c63405a1cb76823c7a53cd301aeafec586e32118d3c7b966a96b4323e86f7846fc634e3e97659455d4cbc3dee95a519452bc8c50089d87440c7b2c0851a6309a07bd99e5e31520eb458b405763c8b0c4a2261b0f4679d70cd254a5484e02aa747c5ea320d6cd5584d517f7a664e2636a891762594d20557177f66d25c2b551f67cab766599d7aca5e6e8475239bb649437de88079c8ec645f423a9b51b8be13bce19579269b6c36eb16e404c2dbbc7ee06c6daecbad02cb8de945c1c8bb2edc298955f825c870bc29e582a810b27cb22c11497aede1b50c477840488f8b5a3fc730044070a30e573275299e6bc2526171255900743bf46c21ea708925a6ae27a8bbf5a3f30c1a5c99b0a84a7e66910a1f85842a5318c24a6038383aaf5940b1c8ac577359778b0f16350e8e582e19db11e13346dfaa90e132186ea660f9cb21776b4033c5c46d987fbdd5370bb7302047336f1066fae34c074a133ae89ad33c7464db9b4de654608bc71de12c64d7cc24801913543c10d6c77e24be428b2f4dd088e5988c5a76a208f517951b14fa95711d9c6fa6b84101139627e645504c00ad5209bf0bbfa7da39688429308c166b264f4b66a851e24828c23c93dac66980c84ca071c2b4a0db729cf2d73fc98855a9e66ff10693bb36756c4bc724f23f30b075927830f3e55c52607347fa7a09459635166c7f05834f2bb84126cac89421627a8217b9aa488161ed272b98973e63906d14f3b03b7b5fed63484eb545dec0ba674119d4c4bec2a844154797f4866af210bab216c1c9441d4694c0c7a969dd103307525d7b4722552b5489e83de29893fbf76498969534f8cd7aa04931758be6d2ac36983d1ebb2de14130de6bb7966b30a996cf2f0c4f83e78756129587dc5e50a40c69402f840852f2543a90e063d22755fbdc909f60b19ceb33aa749674b6bf03a3224e1891bfa641234ca963bc28968c3a598ab042ea5ece8c0b47763fd918998529117dcb33b7d246d122ab27cb961b63bbc579c27f644213e6825aa1a0d4b44918784e1954b469f106d6464da8db4de1eb8cab31317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f5a1443629def269cf7b98235569c1b396fa9164e2e0336cc8babadb160b082ba8edb209a426b25c435c35c0bc9b15af0d541d0ea5514ea354b828eb3772ba1ab1c81768a1e286ce2a01d1b900dd1ea9fc6d685f1095efc105b71571ae967bd9f9a02028729bbcb53c6a74b37950ef023b334241d2555845e882de3636cdfd45a76e1265f6937130016f8e1710b748959a8add626cb79b65de177c06ba2cd8dd759d86baf1d9b85f4da3b2ea9049ef9545b72cc0a6a736d5581c57a1d7d966f88c578dae60438292cb3ac26909baac0ec8d74471d511bc7e928b67913c17e4cc26818b2f301299da3910458be4bab41d3137cae0189225890ae91a364dbb683288b8d59b6619bb786dcc98a51910fac5c65e05b3c75a4185b99e00acf009535adc07c269aabec98adb1195ab0b5a623d448fa454e90c2a6be925ac912b086b31616337661d0a6ea7154e937a39d1a60a4b7923f4b2e88438386ec879196cc47d9179d382546168a36865246f07b86e48f3629c5b1bb99c62098d800cf2654acc6fb8057d25cd2d48c2cb71ef0e917bf106f99b35df1830d62226a1f7220be6c1afb229982067439934bd27b56171ac3cde09e2c1b3dcbda08c386355f328dc9d01827ea271a43651bba49a5a66f01966cca037fcf02aa074a7059d69de85961c9120e6d89349ada3af4d41175a6267aacc9637b8cf4d513a8f6b3ebcc9319c25064b337c0e90a88193e79a9810d2ba9b0eb089e437f473b9f5dc4b8eb95b24e1b85c5d0267da39bdf35831c1263fe923a2dc7bd54a5210e38203422a6dde30ff9c59325d36e99973e3e991b4284c06f673751bbc8c99b04c4990610dc2906b27369b72187aa2a13791cdcd47bfb37a19e149a32f8cadd638ac0e071771c9dfc58253a864c0e15cca60514f545cbe161030af806872ca2d0c67f54e04b4ca55f41a54b1de405a22ba275a1b919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc56eb5880e9d9d0fe7901747f75eca1996c722ac47b76f34a4dbaaee0ef8a611bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 0d815ea0442fdb719a6b4405d510615c107546c0bde2ddba35109d2ed7eb3383162cb686055c8abf2f2c28c1496c01f88dbb89a1e09dc3a92a618d6a039741e5f979ef5dcec8f1e34835662f0d263a5320084f4798da555d9e3478d75400ea55b90b44ca66c57feb23c7b7e057cbd3ff380587c7c6432e3d2edf1b82dd3cfa8a49b989d0346ae7963e4b6a67c3b85bd3f207561e3d3493929d9614b9892814e5bf988d3d6566404590442dcb7e9e1e738f9002e279f640c9a62f092c7b01d6ef86ab0f45e502553f013abee01a1f6fca018bb04698c78dac494c6f545246647ee370973430d0e59eb8ec9b8e98af04fec8dc4ccb4824cafd1dfc45ae9dc53cc869ee426dd4cd20e0e0b554af5eaca43361d85d50e02465db2b4633d6ce241e08859848ea555e3c84a1196076a091d262bc353cfc28899abe749d57d4b674c10b6826f01c6bb33468329b7954ab05482971635a388374758edc6baf439f7ad489809bb72f729c4890e43654c527906e26076f590b34f19d48e6ab9faa7a6560d187638d2f7dbee6f0cea42dd885b7d6b1be159a208d5537b447b64f870f087b40002068b149a1aa6e25e173298cdf8e2d6db7ebeac3e5ce590bfbfebc19c2bf6d2a2d4253e90fa9b7d8797b9063a92c4ea8cf2e6141817535f5e21055ee4ee3b2f166f9f69d1cfba707d2849bf5d4dabf6bbf1529ad2e98dc74ccd1a65c93ea176d214f212aad00fc1aa9f832569c065a569dc69cef444470f0c6dcc4b310b31fae45e3ffce97e06dbda75fd156df65257beca07cbada601fb5d1d3ccc5df0fccd6b54aa40b06ec064532cbc1897064e1f0c7ff182decff960e88cee4834b5fe3ee4824fea981b47e7793da73ac710972e019665eef1ae92266225f24b01bc008a45d3561a1aeeed40870cefc8a430c5c97e461adb7869cca48835ade731d783be18d12da0beb78190ebe334aa4f8bd790be4638f3f3839d94adaac268efb7d312a9cedc9897868fef597e5b145659708fc53728f0b57969e2d11e7c5b524eb30938a101a31b1febabdcafde3761adff7d9a40a6c29337e3f1dd0d1b1d298cf40 +expected_result = pass +expected_shared_secret = 3b09c4579ad60b17eba6029141a6d9765e1abae72ec32f1b329a5e2af761a087 + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +private_key = 3a77378a267782691cf4b96b2079605ec20b738890d0c73074cc16250bb722d4a07d2c4addab34ed49489873b8b0a1310b96aff2b77e3bac6113f3446aa414d191c8598c8207e8aa35b684e718cfac011ee32093de65346dc1056fe20bd90b0275444605da00573b335670572489ab488243170bc1cfa87e0ea183d691759071b358b94ca4830458737a9ed085d0249a2af3293691bf248016bd966f23077d83a6adad2235c7d1892290a67e485c18dc556a098a546cce24b520f42b6cffa320d91231b2f105fa0a6ef93044cff90a990a12bad553a4b0c1e29761e4b71a5af81e2a8b834a4b2b39b354c7b0719b204f85d259b7a32a08c254c2ec740e27922089cb4e5b5955a34fe9d58cd4c5bcf8bb52453b848c82ae39f0144de978c974b5bbbc7d47b52b62b398b4352e455ccf20f03d38598a435b65dd86bda4fcb5d3a514e5285069b18444823fdcf820e5a093f8b91b7a51313327cd644c19c170ce6fc8126f97664b68a01a887791456e8935022d935fb3fbbd98c45ef57a36edc73dd1468a0e0023fb9b2435b925b1d88e37177789856ae6d15d2b753243386b85bbb879cb48e90a0380a07a7cea4278130f9fb90142e67a9a69bb031b7a7a32aaa9811886977d28922060527175305538d9b1a0b2aaf014c41ff38afba9c2f1e8abdc6bc754ba5c51f2473e378c84db250da85acac43654ac5ad4060cc5fb09c0eb62676601af9c1fee6c8e04537f66a561b93b39da17acc6616abee22692ab867c091f250c5a451b2d181b17fb889d2e91a941d9ccdf639340417641688eb6305bde148e0241cd4818c8f12c5524577a6a4757eeaa2f6fe24084102170b43539f205e7a800c5205e2b036de2302cc7533faff17f72d8a212477187f14ca8a1398a72c77b858becba4d4f75ba02d4b8a640abe0464bac158e531a7b7bd858e20a0159b989b8737698741147062c37b0a030c30bcb2793ce51b28eaa378d2085e99007de2b527396accce8bd1b285b8c2c06f23ca77eb02ce31a1e4a6b53abf43e13a945d38c95f3096a1555cbc5e852fd248cba66991af865a916169e383a3ebab427dc0b5977446a8a2769da6dfa5aa672b16fb8b63a7961433811b6f0a973935587f60c8bb78326448a89bb291a32f1406282c3f8772a4e2b43ec8209fe907d1ddc8d47584a822b6684da85a4c54906320a9169118b1c6eaa058dd3233f13922e249932f65ac9f3932253c4c1e5ac9595d5a10ca6cff03403b641ce79252ea2b999365c2c8ae62b4f369c45eace0d35255dd4703d06ae06f22c25b50d312726e6165a968587a206a7ff789c40f1a195076dd3340f0dd8c6b3049be76b2168ba6aced5cb794516432585bc5a5deaf09bc5eb3306f7633c82bdac28bc27cc1924312462e48e6fb087d3a6b61a4a21e1a8917fe4b2c0c13570d26e8830a0e1923e649a756a5216844a368efa096d65a2c4c3102f80841a4211960070e1ccbe6538be5c7cc09469c76a37089a163aeefba6d340cc18ca86599a7eae767ffea39403792853834423920f2e026e2bcb6a40167e1fe504df7908d1bb7fc8c36a68dbbd30e611742bb9ac65334ed34dab7a8258141e0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e27075c73339d38b4441c7a4ec79e1e6a60c88729a26b8a94739c3b807141713650920d6be7c628551cb3169b3de62afbb746323400411b4039c16bdd4c7ebeb039db0cb8e3d1af20470e5a5b154a7040fa650f69dccbfd44119e4371d527822770557158573943683b32a80ea50241eabc322862cdd9924a00443813b6ef4a7b94fac2ba88542b4454ee27b54edb090bb688e7eb1a3fab22a11a065bbb52a66069aed1cdc3e78d36848a1f8b6bd15108a3846bfe14a51d89382d8332bb311f0b6909eed19d43182ea5044db4d43ef3a9173dcc669fe5a8a36abd300378d6342863cb2e9b4651aa8689991557e9636c92c87cef06848d500f2a3cb85c665f83e64eb54abadd777e10a23fbbb1818eac65d928b1f610851fb7433e255efe666daedc1e52e32a9f1a1d9aa4398253a644806073734c39441d511240798ba315599dac72cda9925e5a8a0183867cd442bee54b7a431253e9ba21f2098bb5350f6e048f19a51d90e7cfc408bb040859bbf59d80f8cb2702798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f717823f0b58cdfacafc795aea529561d11374f02964cf635c27848671043766cfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = af241b120f8d3acc502595ba14a0477c9783a0a442889e99e23b12fc258e9d2339660f7c44b315fcf3fac31d781648d96b4a55af9d3a7ac25386c6e121b29f40183f6195c2971cf50b3a6ace17eac55cb7f145caf9e42d7bfc50264b935f1bc1ed60c5caee8bdeca5a1087171279f0b26236f933cad6e807462d71d8b60ef5bd8a32966d5dbfecd033bf67104d79f7eb10dc4171b0d979c999512f854ff57ba0dbe822cf26b1c7edc4819516d683ea090153bfed9eefa1bf1401335f38751ce92afff775885ecf5c6bee8e58fffe4ea52ebf6bd77707eeddc86d67cf894dab1aa72d99fdad82b9f1b121abadf5bfe79a26317f71a5cbb24854909c60a815c10f26c867643f02439416010b6966c79ddea83bb472b23566381fa179ad727d76382d9370e1256e3d9147d33a646f3aa193818155d2048c892fd552c471e99e09b52a2a5f0bc4c20c9b9a09eed562c5ce6d35e387407db183d7f036f4ce3eadb86f5b8d7483dbccc8415035ad229b78a25f52e9d7ac254058d7aa4384a14f7a77f3fdf449156758ec3598faeba563028dfc5619c34cc814d7525b282747ad5c04d1a9738bb7f1a3a8072c8629ba15e97e9091c7d7e59805c58b165fe17750d21a304f68645ae799c8a059ea1b6e9b4030120501b12c52381d719fe2b5ddf5042ba6509d27e15a07178d476d94766347b2e800edd3e22f6dc37a3935c5624771eaf950c358303266cc4b3056bdb5094d096b66b98d7d3cff283b1c7ab23ef06b443f87af78180f081d9fdd74c8b3e911c611988beab0e7cb7f9ddd9e6233d1cfd4091c4319288714e57c3d851f2213fa41a60c8ffb32c4e9d530ec3a833364317230c4fd33f8ac4540f42f7da9ffeb72f8b2412636677159b1496365bfbfd28e76edcf961b287bc0bf464ab1edd8b0e0e46cec8eb96bd4f38c3b64b71c1206fe1359bf14d1e8c31d4c6227cef0b9964e1a94c183be6b4da3e755849a6299c21aa9995c59de988ad0bc8d519247ec4eb8bf2b0732843c48e45078f0f9fb4951e4e56d73e39c55a809ed0c048c6cdf4bf53318f04dd342b2ce699ca8d5e06988ceedeb +expected_result = pass +expected_shared_secret = f15864351fe8e878ad66b402f012668e8bdf21525f09d5bcf4a4dad656d2e480 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +private_key = b25157949acc7dab5dfe796ce8902e9ba933ad2c91c1c218c85230c65a8084756151317ea17c0d313375dae0afb6e63971333408c86cc3131c9496ad1f745f96379391c48554a939c73a01379479938a7019f55fe294291eb6793eb4829cc0af6a37759cb7a2cad703838039cd3b9e95da69906b2f4a5661ab57a165db6c6d49554ce7bb2b91a17139bb444764d1e7b92ac88083503876081a36e675d76635808a611b4b2823350d1d01ac8be1c75a3b8a59609b6b2cb553f1c9a016cdea341b7c1ab79d0c5a64bcaf47e0b6c1921e8c701b177807b69715fcbb9954794b68f9435332155b8abd33d128f3e9a4707793d7524290da5fc96b5996fcb62e80c5e6e22183293b2871293a0a13354a6f3de7894a920432ebade7a878c06836e7eb3fd108129536ba88046407a72869824370243f9ad048b144badd49af5eca04e5a74f77bc188c665fabf14b0480b0355c8f8252c3a0c33c77b29f43ca629637af1b724fcb7a27ec876cc099c098e4c469300aebc99497da620a3a0037f79ac75cbd7ae35094e98609e1460ba55ddc32660ad239a6614e0413891e2c94ab73114f1020b9976a3193c62467856ab2a2854859ffd3074aa46de6123d7f64b4bbe83ec9483bec29c0fc472671027e1e4905a2219c67f37f54716f13e0a4ffb57c6b0c1671f874bd7399f94a9d72cc86fde021e5a85919087339560ed10110b430570b7c0a7e8ca0becacc37c732773074a2f1bd73bc8d9e1822015944a140ba72e1293b5a392d00bef7bc9fe6777875f32bbe830edd45818ab8a201113a4e8a441426251cf5c84ef678463702e2c01375a80e7f2b4618430683e88b034b64b4ec7b54030e19a0713b459e0a35b2678c2fe8484fc8717765f774ebab72b05687da090412b669f6747041c01bc9a5c1074077b878732b4b922e58b6b96b45a6072ad8f0b7b88ca7bab621151c5aa666b5a3f550fcb136a3b283562c347063bcd9e7226ff5ac4004b23542057da43f998956a77b684d6c1d450195b2d4216de34512048a166761462b27e3b4c47e475551d33cd9b70d9e7a119d1980270b126e84bb1faa49bd413efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816eb0dbb4a0f5232b0c4b4ce98098441227f25ab91ec97319ff68a916910fd0ca1d5209c3420508b64acec450140165620d9bf8b8170ad328286e49fb049386658179986512fc07d47d49a1aa5bef5a4beb499a007065a79e164a1713804b108a95072ec9c6a1be395baeb09fd9a8e0a749049e405137a5c05c80715f9b30022183ddb127cbb1ba7556302d2b1063b798cf164f0f0bd40a202c13785009bad8769c3155b643f7a19f9509987bc2bccf41a3b9c1b9a844fcc537d8a8a28cce0641b16a0fd49969df2051a6b36b5b58741a0cfd49868bd136cbb4763a97660694539a2025649a7884a64761a1059cda78e07c5abeb297c9e61407ae00606cca7d26c0da8436c4343aa216c6b71375e4c9a0ecfda7697e149b72c025696aba086251826435c79c742058b644b7466b857cb5792c539709a59ab15aa296acc5bf5d30bce8b0b11b56d578837f922a7523927b8f0323bf79ce8c372c8655082901ff1630e0d27baf8acadaf284742e73ff5650a3ca80c47586a1d1664128a4518e83a0e4b13352b4ce5838cde93826f0ba92cd6027d0869bb5342ac1c11dad0938c5ab3a836a646e37cc2d42d3a9324ff0282a4d38fd9055bcaa715e8da77d08434f535465c9b880506831b33174b974d41e680000b5ba3835b457768b3936d3810557e72407d9a953111990c741104fa243a922da7b03d65d2b41438449bb0975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba39277797352d24eb2625645995a12c2e69a62f421b510225ff21b817878aa0031d0f70a68433b422a7360f69abce2bac840b57afda2144aa62949093f643a5cd209486b6cecea226d205ab14e76c17cc86345b0d119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b5420ebc19de137c2b4e55b749399c5386af0870250e853438321ee767012483d8b460239350c82f8700e3568dbf453fa275d5f612ec8fc6b6e37854e8131870862f8046881185c3903440008c4b3464cf43b6f5a80a47c473a6870137924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c7a13afefbba39ad59c088825380398f43f1251b83b0ca9debba0102f902d719020a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = f9ff711565761df5ed623814f675b97cb588d69773f3e1c81e9c146c5265a16be66107289d2aebc4f2da0e4c23a591d4eaf9d0966b4e50e431eb270343770a81e56eed0e592d07c3ba75703dc94d7b678348110ef444ec91f8cf5ac270c8e7e068b024999b5719b73002ec8ba9c92e577ea3073f27c0b823eef6879b332506957ce2a3c7df68e9817bb6a908ad241d8ee3a9695f551abfeedae4b9ebabd48d1b7a2cc960f030cced49ec11b9627b1875c582e0cd311d6269a3eb49bc638cccdf57d7712fbef189e770f8f7003a95fead9f12d0764058cdbe2fedf3f09b89dacb61082da216871f1a2cd37bb4c1b8ccba8d9683a20bb7f944bdcac0c98015abdcfd6c6e7d739f0ea39672889a8e4af3635cd7de8ef815bb3b309440586b07b9b77f40cab33c39042749a837c91882203b87f6d32845cffe3ae07edf9105782d823e674d8c81d61f113d32e4bba7725b97cd0ec3f6d1b92a41214776ae081aaa7079bb1c314b01deaf99984f268bd66c1bf6b33b6f570d35e750dee1d4896662a058e7b8cce7ee0f26930bb1ddd918430220f6084410e59b283df7c65b62e17549521b3edf319c747444385aec86fe4b9d676c1136d476692c124819577dde076a8312cff796d585e3ff3841f6678b5324b92fc695b4a83128f4bf49baa5db9a8318508a1150872a8a866a355f7d198308220cf30f5c70bce084f633675ba7c4c6bc971c9a64d5aac31241fc533a844e76706d17d19e2f2cfe81d5c8db420e4cea37ccd045f2bf5062b5456328125a294b5d955d756e2ec87f2fb81e72cad6ced5b6140f05d2a6cccf9891ba777180e681f9341f8d9a072ef67c5bd6612a080172a93e688c34f5d4c10cdafb98f38dcd93f74016881fb11b580002bc897350b017d64d5f54cff571d3b464d3291ae3de049d2eb533f16456d960265d541e1aba8ca41b0648358fa84651e3f77a981a4f36604d1eaa57e5095230e693f6fb83bf1ebe209db0a9d53abf435bd7e663d0e46eaf5f56de05d9483d0bf9838fb780f565800bfd1516c1a6b5137879621f54a755a6ee2ebbd9028417d686a4b64e3274e6 +expected_result = pass +expected_shared_secret = 1f1a7f0d0d86a52a6679c431c322263b185b0c90ce40db054928be438f38d47f + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +private_key = 19d08d4d81b080e533b6a900fb54351f55832d411e4334454a1236ab2ac28e6836b28105ce7b4ac3422dd2367d86bcc33b539b7d855838f665d5d684e932870c567838038588508252f43cd214cef3e259d5e4c79f078c3e3a8098834698c1cdb503780463bc8022b0ed36a14fc606d9141984c41a6611723b74c16e4679945a2f8f47493b2072fdbbc93a143185638869515cf62a0fc842388cdb4be5c90d2f4c13a08a330e9cbb5424be008d13ca09c9a9442763dc09ac61c891aa324fc30cedd2a92d488de28b4ed28458e5b18067f11ccb49cc6e9b25d8f444c574a487a95ae047aa9d6070e100611c5c711ad844aa1a79400a4977ba45a1e686b7ba864f8a75188273f3692fd76766135611c3fc37444c34594005bf251571060e59ac3b9be01a7e50cf4809220bd74437268a119c074be236ff5938bea04ff93815b975181a4c996ee486c857608a9119002060bf41a17fe05093dc8cec793e12c3970650197f4b4a9abb63fb0a1c875b54c9884a4d875fbdda9ebdb68fe4c8a7c5d0580401932bf30c5cbc76ba96722cfb3f838b4101b01bfd41aaf542822f09cf33c40d54f32b894577eb3b4f0706a4a2a67f97568e0ef9a9e10331f84994a2909848d5cffbbccc6efa1ba49725b5c92e0e1918a0d1a8bc4746289906f5992fd6b1922e6104b1264b7f96c7156b2d927c166cc47f2b2c4a58c2550c826b3a9c1ccd6c6fb0cc980c752a90e915f8b0063790a7f09008e91b416e18c7eec2a4f30b2e1294461cb9124b45913339132003b0735c7997e44eb318abded91c753527bca55953e71455247ac0b53c05931d5c8715d674933d889a09e05b590315bc710ad73a772ea4943d810869c98767490b96c6ac83b48b21ea171148bbacdc66220b6ec5e98124e7548ea6bc0ff59c883c96ba8aab5969c6e765c2c9e70deaa17d8035164c240eb03a34e033ac4fb78b99b84c7c5a276e325df1ab83b3801294ba6f56988dbf08c57b59202c928a3fc720a842547016580f66c51e614dc9db8166dbb92e5a576f719e1e986ef39578312c6cc59a9671112a96a40ef27084b72bb8b742adc7c3b4465b0efdac63724548ff25b73b9a0ba6b5004b82a614918e63400146f36aab60c8cdb51600fa1218e9c3d619168d1ca7d1b29a20b995dc254080108bde2836a53c05aae73f95d4997dd002c21c9e16711ddf2603a845a5ad8518a3d3cadfb57a5a994cfa262d51f06d3d1c857de85cdc934bdff1ab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4c3158a99482b7511ccd188b5ad42627a49240257b5bf500e382a577dc57fd84af49731b6a49224815a43d2c6bccf03ed1f09379918c882cbc5fe33303cc37621c21d9e5360b3c4029bc2c9f580c2519591f6ca703283f93e759dfeacfc63101f6a9bcdb30839b1288334562b608b32d211111a79c8c2c4b19a822d18646190051c65c0a42ea51c0009ac976a06c4b3c24ec1b47c117865287b836738473af07f2908935b5c0dbca76c44e48f5478f78aeac138885721e40b8ab84c2bf8c69c3d4ecad4df0ca07e89a6a245bdc46105dd21a9858a819310cfb239fa735186407a88105b3bf156f95f87d9b3b9db0da6bd67075c70384553b28ca89ac9131561b9c8d37a5aef7a4152f6aa0a7f54af2f3819d6ccf8a07d0f4c5310907403020a01e4bb94d4c7bd257ca0944a6aff6cfe00c9182d508ff329505c3cf85290427a2c06366907b2b292aeb2b13b954f211117504a18f37025860cead9717869c60fdea3e31e9845d439989839bbd7ab2222b13fa921133906868e6671659b18a1c0f62d8bbb7b69b0eb62967b85b21375742757ddb960cbfe450b9a415fd083aed8ac0cb05a3732b39453180c97ba6ce5c426392545e2b6d15683300ed697faabf21a2423409ba37a899c602b72a5a4ca1e3a7c4423c5cdc3765d0972f22cb9386bb347617720c6cf9e32964faadd4a625a1586985571d40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041b82479b23f18d51a77f1086098c3a9d2646fea3b822994ef730b97569d05aba38f880909fbc441815850e0beea12403d0024d95c6c1691584c6b548e0068ca7c7333ea8d07f12b615433da2a041572a46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455dd4cfbc29de3568663a3a044c3f897714363b0fdd3b6ee55f796292d34c7c79b7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = ed98e8a3d9b1fa0b2ea9c5ad2a02ffb131b2230df45df43f53b5cdfbc00dfbd6a8f8f7a9faf230d914ed687cf1a9439a5b3981a8e481f79612c506ad17cb8c5e45dea6151ae03814f377f3b3b293d1b9e70206da62bf076b0f7c21f737b00caaec99d012d1842f074ae4f407d2a5dc15a8acfa5ab60bb2cafb7220ea175031544b9c0e4dd2365770b3c8a703b4e5e2f989a2a93c36b38192c85e6836d5b13ad675da7717b4b5994391bd535249a4290042a39ba0c81182f43af051566e34ba7cce505c34f43be5ad99ef5ebcf49d6ca3f525cdb78ddb26615fe5ca02f12f5088af3268a06525e16873aee13ff8f3a2af0cf2472a00f9d5cc91733cfecd0e8f88d2d7d89dc4940a48aa6b905f7497f47718e44adf96721d61e7d3980d6fd72bdacfaec663c7a9473aa36dbc13372600605c9bb7a9e904b19ffcaf39c1324d8a1f2ca5e03a51b682a67559d64e5c505755a1190788ec9fa237cf58e1a98030a6051bfeb4c5731b45ea3297c12746d9131a1d750816c484c77134f5fcc87e36d58ba57e625e288299c194992ed2662a413320c4fcabdd8a0b66c3ac76f5b446387264727b40db09f84291da10ade352e3f3118f66135e2f2e465dfdfe808b13db86eba4e5ba6c035b860bd3e100b86d4cdcccaaca10415f9afed88d72a4ca80e77bfd4a452b93b5916a06bfa9a5489a0264a1d4201ea753b3824af7a71e0541a513cc9cd22da765e9b2d0c4b2ae0c8b7bda62a9e716e5bfc3233bb0294c218925ca7f2d7373eaceb74f3bee889cca5d661dc2f340cd09a8caa0ce74f62a65445419790b26ec978ec32f02f2693d53f29445cf705aac157cc9c946e2e0cbc8b73bb24adc9a3d4b05e5b4f9827b5cfdf8599e31db2f6b12e2df3934afa755dbf163c85ec6bc84533efd9f3ccd328624a96f624c52013455e660502386146c1f9aeef2f7e57c78bedbbc26df6b4f8aee493ccbbe03397e4990e147092b0534196901428a1ff2619490407f04479e28541ca2933b9ac8bf9241a72f5a37f74c3892479de914ec23afeaa5aefff061a18b3f3e1041ac602af40dfb786f528be6975f97fc +expected_result = pass +expected_shared_secret = aae9ca8c35deddcfd7dbaa7780fe31c102aa90cc594eb56edc782fdc4eb53b41 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +private_key = 3c401449fa6ba9280ea8570c68ca244bf821bb5367251b1572008b2d86367a8a1148f6391440cfe1f9bd1bd02d87c984286561691145ff82954341bb34406abb2343cb88a74692bf39cb000884ca13cb8186f1a788e313cb739d48e8365659c324bb6b032a85ef37a25d538ccbb2ad678616f52c86093ba9352822b7f9b0a2307a3ff5a17d8033603220424b7485171fe2a14d1f758cae896cad6842a90ca5a7b69789d356ff574607ea1286c1af8b127449abb495b485c7c6078ceb9e70421667968176025913535879e5cdaa4859b6f02d20f67a0886ba71851a21f55d7b7b503785ca9722c76ab06531b83cf1bab17cc0a5b3c263f8593293068d7790270f1723d7713fecf34b93a096e89c31fc52a2dbcb8129133379866f938b71a2f3265f939d741abea2886ba849c991ac0505fb5c4bb4a78630039b0a0cec5064f7ec2a56126665e02afb71c0732625b76b0015b7cdc3bc16e6e6ad06914e28364fbdbca2c1a653b9a8899f236bebf770e477abd1dcb937b7510d7ca3a00aa093cc9b62bb6407e00cb36199d077856c4682ad78b241cb9c2537cd9591bc4b49798389b3ee21964815a4b6c0ab98e7b318600a0c663e54522cdab923cb809937f2b902fc0fc90bbbe5d48a2f489a857377509b8b74ccb6ac875e07c3429c728943087ae9f5af33155ab0eacecc1445836404b98284acc63a385a2a55a82c758287cd313fbc91bab8baa4c7d3b3ea5412a496ae64a59c58132dadb408552c29fd34bf4e73927b16c81d47188954c0ef9039add7697a9b6ecc7915131b6c6cfa335c3b016d53b3547669d758943d316ad65979473692bde8725247b333eb412b09389e55c97f655d20f9850b1198b1c358a3a87cb93cc47a91ad29b7c9ac7110c886a79a39bcaa68310ff5c9dea81b0c1c37004021ef7cb24029987cb2617f842f2f51417eb51f39ca7aa50c4fbbbaa51a1c97c4f00e582060e95ac1ebab6e267c8367b7365cf43986fb0103a192a0028ca2205a07160e2d0b4d2d82602b288d89f0588e6935054ccbb773aa6955964c637efeb889495145c629794692a20a13b9b9732083fc2701341ac042ba3987b25411406b32a000a12e00f726799b88f2219ab42bc6d08b3396bb77e51a38808b5a00823d45fa46dc142077ac63dd25b5209b0b35c0a3bcc30537248f568018f1324141404c3a603f8bfb30f675710b33b1f986b78475a2d4b1a6c44b6277b881c8f69c7198657db21fb0a9887afc4c3af212d1751a1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6da906e98630ba611eba0b5d622670b33152c3d91311cab5fc052c0050097d0c9bf0a4729a58b216b92537f21948c865e471276918b712037569a079600b1eb611c8d0424f8903404b9338d4ca368c0a42df6a9b6be6692ba24232c68a82b22076b72c5a71b5cd603f52493beda57f12c660f241a6b772bcf007819acc094e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b242eff33c5263685afe47dfda38a8250cc54160e4c22bbcf9765fcdc1b34a94faa088d4927a6d8121ce556576ae682e5fb2761035981b442245c1d114285ca20b3af733c2d3a8121998bbf87734479505644b568301244e31bbdbac05b8c5d93121668ec64080287ea074f02323a91425c7362428c9637e61bae86d03238c96336081a86198e0f31c17a945e50e15634e23100c6499bf1b58a48813bfbc7ceb3322274329366267132a972553c6da19e13898b89277a33836371084a5297bae0298288fa68a27605a60b274620111d376227d157d066181714ccfd42a3d33882335565f9a0babd7154c5f12e67215567676193ea837ea188def143e98c7721dc539914c678e1876d334fb99627b848616190a9f5371251593381bc933bc47c1e5ba50429b1bf71ae7c11ab43273cde9538fe8b21b310c8da5a68d7828c60761f2178405ab96cc3d179e75837f7c69c0990c75dbc2718003862448eb3b03e6abb535ad733f5701699d543ff893003b3674ce997e0c6ab8b7b2bb834c4a437068c9271f55c2fa3abb4608cc88128b13eb17a2f45a7ea9b85fd3ca8cb70bd8c0578f7963ac76c3d39a44f2b87b1fdc24f15d32f2b38831d55722aea8642a7ccddf2011f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f29ca90d64e28a5bbc54c36053ed333c530f72549c2afd77b10c2944fc833408faf48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = c65bcdbbbe19ae33a1a009f022fb5f70673dbc955f18ab4346bae8a9439533fdfd0005a7627d4ff87768a8e478420852bae07d774dfa6c394d3b620c576bb24c3fabc712662cb14706658be7d40034a2d8f0ffc9d838e3af335da39feb0f66412fd83375f3a54990b78563ac4fc08ef20f0e7530346444b71569118bbdb8de85a54912a5cd82bb787f8b4dcd20b10c794ff9f8bff04470fbb576c02fa6d2f2997a9652b4785d772c6ab1fee81cca792a98433cb9a89498de87dfa403288f3c8d2b81ce486bc32c29d11a06dfe10cc6e3732cf9a3b1cba5dc3b820f6a5630b370abb0e4a97aff035685dcce014f68e5146fe0072af96ea57b10b162b0643668224ad8eefb26b29c0438358eadfdb23f30cba357d6dee149faf352adea4503043402326d84f83587eab1386a6ef65fea0612b33819b7175d5be443b9616551e2fc3198ec3c0f6337dd485bf0fcf25866b092a9991ee31e434e3a97e1fd8be7331115d330bbfd4423a432b3c196ae1652445c2b9ca578446883809c9437a41eb29d07b0e1e008f7a192c72cebdcb8cc9baa465f4ea2cd2d2c8918d3d0389e12d847b0aa34839645bae0a0e01b09d8d546307d05747c061b950eb6bb5bc8040362c7b25c3bc320fe50d912456e5c2043400455c0185e8dc50c8f37d51f75a1c88e809c2298a75ff9fab24b43faa33c1406aa68aa81ad7c6c0b3d22b59e9c9c5d94aabc89921412f27a4b9437e64325fce3c716b3dee791e85245c37e9cbedd3eeac18eada39a0a8881777625978672e1b3f9688ce38fd36d79d428b400244275e6ef929016cc40fa6fad3181434d26a3230215fd4739d9b1a0db3f648dc3b1b95feaa927e80284a788e1fce01d0988d194091e3ee0d4381557c3932977cd969be70c88f4195780626c5f091f8f04cbbfdc08ffe16cbb83e7935abf3b3a999412c29b217516d75f93909e75a42bc635a7c25e6ec73b08690ab23d32acac2f917033bb0161daabfd966063f4963863a9ad87f7e7b3b114e1f31b9003ac0d033d5d990be4e2efaed2b9f6c4802c1762d7247df55f849f448935220322c0360dc0a6d41e +expected_result = pass +expected_shared_secret = 970fe36e57a253e88cc80c9da6867dd66fd8da1dc15c85a480a1a45eed708ff5 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +private_key = bdb32bbc8a7399e7a4e9ba59ac9030bc29a6f85c8fe2418c2aeaaeec3509e789a854b7126cb5402c185074a72c4f2a97fa34712ec219a8db1653d214a9c623bd093dc15635a8675beaca02b1b8b065000229464fbb123cac72384cfc5f0205b76abbc3fc4b2b94353d3be038ca780fb5687332279a6fc379ce9c28314c4c4347268970ca5b3c084eda04d8438961f4bdc40ac8bdccca6f14b4db7376f8379b0b5a329c4c5ccc975ed3d85e5ea782ff7a1e23c6491be04f84384e0bb56755b985f8ac2812db5e6a08342772a66fd2a2130b621a84578d444712ac76f3107e1ba6366291a325cb4d0d836427a4a27f919ec234bcde6932f42446d87140e2798837124f3f59045a45993fd82388a2702b014f956c59f7c85c3eab0fe8b948b98714c7a460bd844f7f0a5f0d2aa1b6e0b92c934c28f5a42bb4a08407290807ba03605f676732bf6259ee8bafea9445725b20dcb23b52f969d67c3bf7f6c1b354a315dc2dbc38bfe501a5ed1266b23624c1920bbf493fbd44895607474a455544da28682711da721257709e616b504a5195939621e8255001c281757c4bcc85897951c6026550085460e3c19b8bb26374c24f4b245710c450ebda82cc8abc28ea0b21680bdc26948fbc6e13cb5dbc89b4fbeb5dfa4c338bdb3290d834eb06083b5c4655c571cbf03503404de4860dc80934b2252555b4446cdaa14ea30e2a470ce2715bafb5cca084a7bc5595015892830b4bbd362d487c7cc74095e4e7bd1ad7c95e227c25a96621637edd1b7586b026b32b1f2034075b68406dfb7c81c9ac18e56d12f96cf4e4ca77e280350a35c20cc3fe48398ba14050fa515e116dffd8106d815deb282dafaa71f9dbbf5047125512268eb41e7cb16ec4904d80a6c15d1a130c123bf3f4c99b95a569653e5485a5ce9a6396ba91c3130ead31ab5afa2249d0ce9abc0e27f451283343430b8909552da1db0662330f64bb7ed34c7343e7b61560c1e2e601841a90f21cb177fa55a0bca3089462b8b61c8746726b203ad1581ff830b0caf3067130099ce24fbd550e1a6b325d4a71ea542999f87955a986050b0f8b49619f318f10025f45eb7f63d1875e49a296eb1ef5586a9ddac4a59bc96cb01e0af7655b052f9a08b861f0573b8a64295315b76c3b0a13cadfa47e02c61825226d3fcc25202a862e509d0ed99521b1c46c7064de830cf70497c934c7811733e9c70ec2916075ea425d3a0d03ea272bcb0f294aa32f1541df2bbcab251e9173701d8cc678009f0323677c2b0708a246408b4f37e95c170311bb15787e9b035ffb823db6cd02e4421f3690644cbd4a413bc7e696d7491a6ed4018091a9be8b149ad93c49f6424c218803b72c146cab9721ab22c347787090d9016199e65940e19d6902324d138561592a0901700dc54058a6ab298b3d62453865ac29bc815e65582f9b8bb6b5e44c12316de7169f4988c86f953a61a313e4a2734fcc24afc60f6d22491e97bc688c528ae661c9923d587bb11d512c835a9fbb314c39109c3ca2166127084d282979304265d8a78ef343bee9baa7038b9dc9517200c4a049613c936f80982efa61a3c0f18edfcca724a43c79ec2f03b99b656941d5cc040ba07c8d2668085a1e1d7a8e9448767e32c86315410f590b03b993f5c21665a7339db6386e923f7b50809d528772c27660615acd53a9753085e7b9c025b76b952518b5b11a778a880350aad71b2df3260633a570250805b4b0c8887268f1a572c86469e4a75194d50a6e89bd4b2a6d4d09698b880dff136def5b03e66726dcf26fd4911bf3502ea40b0ce71c2588a62dd378447c5477de819baf0795134001bd1250aec31f39a25c98c59938d97390a309ace0bde67b3d13cb46e89b3d7f8369fd539b639164f9825900b36895bcc60fb98bc0a28110f3a7af4070c6c72d63096946423ef49269176a529b5792e4e10deca940564906a29ca1b6e95352210992718248e664a65263a235b17293b6f4b45836166cc461ab04f91fd9e7ca24a891e44c2df9684b85a5845efa2003709b07a596f36aaf9224ceb70c98bacb06d0a1be3b0a926d9c537223097f420a0c1a1dcf360d87d0825a417382c40f297a989a7bb827ba5eca46395e4351aec09420405e9a919f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccda073c98794493ec169c78eb75a39c1594ccfa635b8707325e0ab6cb8576e30ce6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = d4aa69eed658bcd19e2ad7011f6820e9ea37f36088b98d07ecf74e89e7f6a10dc43404cddb33d50ecbda04455584e7f6eb69ac0642a0d5a55439ecc1737352e89c21110d625f32ac0df847f6ec4d6606447f1b98412b46afa316efda72540ecaf6f2cb867441f7210d5721f9324c1e39bc5121e0fa3c1cc154fa527c52758532edd7899ab00636962d0d26e82e848ecc03f93e42bc4ec42b24f12db20c02431839560f0bc7ffa4df5523b712a863907c60cf414d2724de0db4b6a8277e00204a56234ff642bb4f4f2a477a2365a016c4d844efde38f1c65179c66c6b8284f8cbc52b821b9c0b715496f6074e53dd453e94a6aa23fb0866742a77723eb7a2107ac6d80787b99a7cc3b29fa0d90620d9d740a78dafd17d75f05f611883ac767e28cde536f2288380817c3018df57cb471fc4b0ed461332045a7cd89cadc290fa0b2adc367a76fabb85010257bb8b2818ad02ea515f9d1a686e0140c7e597111220295afe0ed0dad1072fc13fa9435e2a05dbc607f71d4e30f3e818e6aa700f792f60337cf85055fceae614412baaddc9f96efa7674439b96570ac463b8ef0f4334ed50eb8bdcbb5b882629e79f2b70d9e3c9fbe7f77366582ec3f23854004f38c0ba02593492a45672e6a4e345070ac75bedde0cff3ba5dab3238b54727f2d7edd44e2bd2a57ca26535359ddabf207b0c94f67757a09787a7418f2c551af0b57c801f7d7009e116c18b01d6cd679e95b38df127a54dff0fb94349f97b54e0de458d0e22e6f246e038f0b477e8ed6fbd5d8304e7cda6e79deeec0626881c7eb727a68120c3d602279bef6d01b7db70f1a64e9cfcac523d8d7dfba8e8f90f67567164a146937570fccfb3af3a64420e11833a39b67b727e35f407976880d104f05246ceaebca29853b014356601ae0fdebbcfd84e02d75b35db6ed1757691f4ada0aecfc58b9f4d4f6aa919fe8e0ba568399c9ef1aa09c55dc93fef55e871445df705be8d0eb7ff1416cca413403f1900f2bbf46a84dc3588f25b567ba5699a8bdddd55b6deec519bc1f76cc01b368ad3db77758f7bc4ac6e2a33a9f280c8c65630d +expected_result = pass +expected_shared_secret = 8eb310431276a31c1913cfa2e2d6b0dedc8a208c7470251daebc5b1bb6ee78ec + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +private_key = c6420c2d0681c74c90b9ba6bd94054efc357c500bebd15a0ff4a1216271617e220cf7a6f46fa77636c255e9885418991220278023cbabe86770b1c9761171187937c00fdbc10783f47c7388d367b03756eb2804cb53c8cc4989ff3cba449014835b493a452180da54877a3a6daa63357d2408e5aa0a274175e427721989f954942ae7909dbc2a987904946766eb8971a8f1277f4a155e792aaba1cbb9cd09647d589e9863b5bcc2918150444006b509884c2a96a817c9ea900144f834b0cd74ad0121bc1b93f7388925523711327588a74a58dfb7780003e5f2830f15507fd2b5057e5c74e306f8f26844994049b9c5c338909d867c547d64ea6a691613067d3670d8382450f191e206187912425795bbb31d7af1c22a99cb72e05a5a768c855af3a0ca56480b8db26ac36ce8b582b838b8a488c4f744ba785b8bbf4eb4578985f7ba29f3ec60541fbb4a47a84a5504562b1c36f24c0569a7f24998d90c9b1e6d5393dc96cb1748eb4c5c963e46431d45f70b536a2db0132a44a9a98af50087e88a33002a3acd1875fdf91322de0347929354a6c5bd52585fd97c8d111a5494ac1cc269c075ac6361b71294494075043ae6b1039f28a51e51368c419268c5001d44d680c0bacb1304b7719fc6813f9b152764b80ba56588250a035822c4760082a265a7f60ba94acb1d0f00a6b10068f832f4496834e505bbd4a3bf2262b53998001a6c87b0b6abf07184b302df8c04b794079895157cc1211fc6c4e87035dfc08105ffcb811882b3a08c6060b526cc92916131122a449057160dc03c8cb985d921881269b070c35cfba1a95412b8c3f13b63d82641b453bfb76ad4181573a27b1a31c411ebc57594b742e53424c549932624b0675795d568cdbea4803e2180b084a52bc7653385ee4801d09014c0f63c8bd8c7e2d2324eee42176d9a1520185a4cc255b0471159cbb29708183b72d6a22aa3a55b672e28d6f7066e2d47270141c809a86e60389d838c0cee42324b97cf9dccaf435caad008015e83c78217d84ca93dfd165f41c68a7f66c98f21caff200c523c7291c57f8786cbea3734899705684bc32ba5b14f6999a9c794f0c6af04803fa57cd54278313e99327d579b217682b1b86dc02431c6aa125062367798f2c7b1ee7f907dfe42736cac924d169351853f15b944578c5543aa27b626ffe7b3114a11805d8a3fd464ec46b912ab89a3df2a561855fbcb3820f4c11fa7b5e3727612e685830f3aea6c9881bbb06eba102e3f53e6ec502a4ec98f9c1af0d564df79c8d7c403c4843cd6d05732000c6eeeb17cae7032fdcbc275949a8d0501ae182cad756808cace516b72696c618b319f56615bfd0472c76a5b3b4b6b2471e1955025139c5805c095867be34657c5af333c9111b01da84198a8d33655a37f6aa3f35b7e6f34b1e2b158987ccae22198ae605a9a86fb3985f189292785a14fe2a4de8e245a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578b21260625b7ba7339057a94435966df3033c647beaac74bc7014b01dc539445c77509bd481c525a226dd44966feb66684644f598c9493346c9071b16576978f477ea07862863191e02805fe4c54f4153749b222a001af7396a2314054548203bfe66080cc0ec95c2b86223ed936268fe418486a58afdb9fe8dacc49427597e4198ac4c8dd747aa56cc22e38c7f140988ee37dfbb251762868915b6ac205a006846d74e8734a930211941c4e5721ff281551605866db0f6bfbbc9fcb649b45249b9610e647c827cb983d61a6c9e717206135e40780f99495aa3c9c6b619e47b40521db992e5329c4d3c894342e2ab2808c630d9761ab13416c55fa1f1ee2b7c918bf78832b23bc4561f6cade041f4223067db18033eca02d243811132c5d98acb172bd825660e07007125b7428f7403bd2c19f522588d20413162253a95f3e54738ae8694b7a5bd13c7b0a41ada087a8cab72b6927b3ab614cd6a00a00e2545fc7ce547a2f3b320b9711167b694c75ea6494047a8b6c07df344dfa099482d322fed5792d1507b801424bf50fdd2088c0f18a9bf31aefa239faa50c01c8866d0389eca7a521cb9028f94aab585841c021dfe04a008a8d11d23d534105aafb413450a2ebe6918eab0e641bac2d000d7fab0ad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0c2aa254714dac09b9e712572b24154be391063afd3cd8cf4cc4ed8ef21f0cfe55a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 69d2888f5b3d14a0c34b0d3ab04e995e8882390703525db0f3279d967fcedba1ab9bf4f06258ee76bd502f3d72b19ff6e44b241f2191146e64d42483a194a68336fc5197ca6e5147f7e8fdffbe6eb0912518636fe61781af44f39afe4cea8a0546d2b38371025e046f0fe9fe3c243ca9a20245120184d0a1f3cc3ad1b2dabe348ef5478f0340a6fb2b5a80381383ff91a1d4f86896bc7e42204708b7edbe828d209680ba7e6db55f08e164c68d91fec9a0bae1bfaa8e04a1d8556d199642b10ca6fbdf080a026f0df6a88f30101a88ff7ffdd0a98ea95cf470c06056effeff255ad441362d90cf0e1c147649a3cc30495ba769ea88985e82ed0cba5fc1067a5969978d7d7113923e68bb8cacbdce937a7232f1b1cd470e3c9bd0f5307153da5ca5700584ddd5f828e7dfb2d6525a0fbe5dfbde36f282ee3cf1d094731e27fe50a2ce995555007a563d0798a61917cebea339ec32410f8db30fd4606bd93bf7c60b1130f5e6b90ae2d37c3dddb5af7bd23117dff1e550569e36d0e4ab0489489adc94903945534acfeac4a6a8c71f890929686133fcac2b01de93c048a7bcd85ee32483b89e77002718ea0f9cab8fad836bc851dd521ded3d6141373d0daa8b1b824bad5f9750e8f79192e38fa928f4d13f742d88f0f398d6b0efaf0d718b4f0eb20fb68deeaab87ffc9f5e4175aed2ec0b6ddcb0c2b368dcb6e473a6d54b01483e68566b172403e124401ab98e5f18af399221d462231da58ee3b4b57e453fc1e99002fe381f56c8ac2942099077bd32a01be4a89a294235f36545adee763102e6655ced957493c6b0bbf2050e832724df326c3301aa50c6e0c1677b9cda946da86b40f2d8cad42c17a4b7eec870947eb2d98b2f3b7cd3be1f4d4b0fe93c30595c2b0a186e01ce1cfd63307d047eb9c4821f599b50a40820d9fc31e489467a5055a2d60148d1158dcd96ae06a97be24834d683d9848c9139ec7a612c248f655e1e0defc3ec939690b4a8b967611f11d79771df29bfde86e0f3fcc25f0dbe61ba1215c8130cdd358cbafb0cf1d4e2326949d7d3b75762b79ecf50673efa794f78 +expected_result = pass +expected_shared_secret = 425a88aa4cbb6b6de122f1730aee536f1cdb8fc84751fc6eb2b42bcde5febcb1 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +private_key = bc6b78c468375dfa71b708464bb934109c1720cc0b3f0b3165d968390c9dc90584d5f093ccab5f42a44e54d61bab919f73dc93c7823fc9a36ff8c67e5e840aaa5282d035ba6cd41f12655b0d9631cf3722c669bccd01ae3129ba7c1ba1d95544a3cb3c2eb94e4d305948840680e8adc651aa42712358a6419ac5626c52c0b4bab13c03502d882a33b710fcd64a16838e38c682e3a3968f5044dd968232599b5e134850e874aff2a8243ba3869497502827e87282fbdc13040a1569c5023675036364932c445073ba7749d470f98751f6471b4c198c3cb69cd110bf945b1a43489644d0bdb231ae1761a5eb912df7ba8c3f815eca6c2cf71907c6bba149607734a412e2a4587ba64900453600ac72f6740b644265a563ad17f3c4ba328caba49393d4c201c8a03079b482a49188d249869326cc5b7c510258a533416d508b62cb1bae79b361b6b78629aac2f0c47e056e2508cecacba42e0cca57a8c182e203371c7533d3454db6585c855328b31dbdd4bd8c232ac8263cb960bfa9e53e4ba733ad822e6919afa507753fb19e279637d9999e2fc948304a4bedcca20f820aceb36813a36695ecae0ec790ef810d4a2c8bd940b6fe3163dcc5b53e20b608ca76d6f70c6419c1c0886683e506f130315a600d8034b972959d42008d5912c799134eda79c0a4c6324f636260778832358211e3a4277268b7074f04e983890130c85c8545dc374e61cd9c5483430760cd3b218c887c22e0c2dc4c2b8e275c8851105fc08fa8609bf6165a029a153fb38282240ed44126379143a454245028c222c65cfbf2824cd61bd3474e59900e162703adf13b1b394caf948f8cd070e22c78c6a17336c6863d360d2bc08848f964fba4a0aa4a181aca56643667d130267f274446b7020c0b4d9dbbb025ea3f90d5219e753391f2b3d489011a1c34cdac46e30b4de544ae19b530d46571d8c6beddf9c62126089982a02612181bfb9f3913caf9e0732519c5208b2a52a53fcd394583762ed3973165187505f2274efa03b6a79e6a39297732a880638e2ce18178420621e1435e919d00e092cc2571d8f09d5cc7b19a3aa452bbcdc82111a6eaa59b04ba8a78bb9474659cc944e7a883780815b899cc64219dfc583f0ce4103eb04ea7e60e2c627a91b28a32843cb395021ec544005326f12b53144ccea0096d8b186fba2ccbb9e4197a43406fec09f53abac00245ce1a239790ca622401df204a90b4a438d33391dbb10ce1aed56456f4238af548881d188f0976887eeb672cc91078474cc2c289de2459513ba16458aa5ff06ea2746d4293b7ec95078d9346d0197dc9a93b2c153abad1c62758cc2f57544f37cc9597691047acfce10be1246fa51b056ab87f24c38a0fe36813316191612e9cd7a26b745f4c51a1a164422b4502b073185a93725bdb606ad6850ca5a27f7c2e8002aa709517783232514309b3c280444c0706422652b170011122e0ca821b5117e530ce07282873ecaa7d751689657aefd5575a7ccb65515e1dbb647c31b1f8578120252aceca821df0416c6780b9f9988ab68c72c73538ca21687cb4654667d3e9bf8a0bc6263053766c8180b8079aa8c975d867b36b45bb709436265ffb0524a0b143095351c90541f8437e756a028be92910341db30b8a94290cf1f9042b6bbc99411b72176e7c5a830be2569b695e40e63122e574e061278a35c607ac8d491b60bd96917d81154e9a244dd014ee85ce9b0691c21c08cf2b7143b21ebbf71412b873828a66286cb2b4f11c73954aa64b1717769573aab29de4cece271cfc549f7f26aeb28360d22926cd16cb67f0798a1c1a03f706cb3b37ea250b75b1b881c36c86461597292561503e6f3405b19a3fc3a8c229d51b6a5391964a4c05db926ef13401250e4a8235f8ab4fc3039f61446f37c1c3fb01b626e725c8c5031db11093017a0bb5905fca5a2721c35ad2100a41567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a3751bbfa83e7237329a8c118b7b7af9816e0922661869a2e68c7deec83545915cb11570a4737542ec9ab52246e7b58c0df812e2672f86ab92c788257f69a0f62b8f7757489a182de8f626a4a91aad8a06f9013a9ba28d3eb6617a21c9070cc65e3551dffbb66ea449221c17efebc429c489fe107bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a18aaca951e0573f28d50831960a28dd11126f0eb080afc55f394e8eaf6379f6ebb9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 8d6e542a640d28fb329ce4bea19d28f101981c4370cf4174d9b2c8f48b98fd44ca9b5fa723b2bd20d383726158a5e5be76ef74af405fe5b58b3dbdb531f227baf0c6e11b395528cdefd0248dd9bfc1daea59f18bd6c5dc839d50af2a3261ce05aafea3991ebc7367b2e9076ed53f3b79062a874d209651c62858244483fe50cafc9b0184df4ec777c9d8bd2779edd813b8c30d786bc62ab0267ee8b99290d3694ce989097bcd4521a935df12204ff351204e213c0b8fd595aae93f7a92d87a8d6fbb172a3c15fada27c6a5b6ce95661045251ae753d455b68f18c5cf0e1b0623611d81c9b01c0ca687bb6b1a481efbd1fb7611c1fda52ed75892d6550d67e382339c9557308d60dfa6f266f448de5147300931d5b6bb2e1bd43339921275d8739db73987b86dee67d11a8ada02f38ec92af8221953bbf87bdc60911fbfc17a21e395451ae0a63198699463e9bd09e2c1e3b512bd6ed7c09672715856c8f64aaef3c01193c4e8b274a5e793927d73289f7267b98c1e87dab413c54467b8052114751fcc5da30244b2c5a9f02427c7b55e617553ddd8000ab7be2e716584dec63fd94c219f85fa6060f9650e6d504d9bd1cb62d7ae0568d41df889ffa731c5e1b58d08c5c2113d63ce3fad7ba7272753d1aa1b39a47c0e475faca105680e1067bce782537a93ab48e266c6cd0fdafdf40123be2587b8697e775a1597aac1845c9d7db1d4de92dbf7faf9355756d8ea5f637da8d0a56555497f40577fea03eeb7f36e203ff28aa536e4490f39016ec9bba62f7751c1608bfb10ddffe3c7ad3e94a2540fd3ec60ed516021c77dbceac7bd3734c0a85f7930c17aa4f022866347a803eeecec2a3680132e2d4e256c539c35a435c1b2766fad849edcfcdec82628dc9c2b9f4e38803236f3cc1ae5e0cd30062ee83c7b69ceb5867ca09eea75e4ddbcca0d003dc352240b4cd4327f6251e70f7e85521307af5fdf16a4d9b382b60e265e110f2bf02e7ee6c7d24c5ca777d33890b6e9935761351e8eac0ba9d8b79fb70e609d472ebed303e700fdd57959ea3448e7af0e1bb738a2a76fcaf0c248d0451d +expected_result = pass +expected_shared_secret = 457efc40f2e99aa599ac1ef92f9efbfc93d17fcd793837857f6a5c91a8dd7da2 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +private_key = 5722777c9100b2289d443400f2b5aec17c0f4f87a49568870a50ae1e30cb3f051d541a1a5203858fabb4575b472f9b4888cb5ab3900f1e316fef1a89d041c2868b26c7fca4b2ba6fc0e87382eb43e8bc99afe986b26164b5709cf6f5ab83996bdef929f67763d7f51083a414f786508be47c908064d47b7cf0b0ad934c03bc6a6ad89247708c47b49ac1b0cba389eb5281b8275cf8334e89907ac298b86866d2ac854bdcc0d53241d2db6ba1a84051fc809c224ed1c93c0ec67ce9e13cf2e05dc2eb30f19615207c47c69689b780b695f8c70d7970378455be3728c2935bea297b45e9c063025d8309c9037a38364a7cb9fbcbefcb959f64723961adaf07a62d38a961d408cf3276a994b4ad2b3914b63cb196c71be49c9ca4141b02312a5ab1a2b6ac38d13046a05752e431529b84d7b57c75e27404630cab837bf3d32bd41cced982c3f1b7cd1d534feb414f83870df581bb741a3a88515523143dfc353e4c6649dae801e4b531af1164ac2c8ea6a44691998bef1b09a38a057344badb07cc8a2756b9351c2a2c70aee67555e391c3251a997a5071793eb2d508698ba8fc18cd9690ad5af22923c402a951a724931bb395127d63a1acab2a24060e72923cecc40892b04b5cd94a15585f045a9aeab96e1b3ac25eb0a3de579964aa4c6ba5107b41b02e36335f42ad3fcb15849425d0937205120427494953d43ceb514d718406b7f40cfabc5c57911a27b2338c14ca0b505fe26296e259b6b61c73b57cbb9700cdf318359a4742b55a7ebee072280cce8512842d523dc7b969516345812a6585d828fccc8a85c6403decb0b63c9b6384c3d0fb224c2b53f9534881a01c0a642c8064b17d2410d4b73819bb81257b58ca7b0021f6514d7c277c3a751e323ab546b86812a8d660cff93cc3b1e85f9fa0c5da791816c864533410e2345a3b36033e97aac1bac96a280ddd70908b68221353526312cb836915d7352e453c069ea78d8d135afdb8208a16a6ba8b39fbbcafb3fa54e9f808c2b28d63079b5d3b990cd4a94331a9020ac8c37742c9860e487931ef9b9088e5c9f55265adf006025a6bcb0842b8b213052794e18787efe902d94c88c0986acffc72dac4505e4c36cc7b4990353e249112a8251e887aafa1ccc9c627948179a747b5cde3b0409d5158230b56ddc86cef9b241c044fb3d523fb909ce0065e260879690bcdf70c33c24303f81143624446fba37748f820cdd97e50d7a3bec058c404c458294eb812908dd87e4d652d51824518b3185425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444412b20a802c399bb56f461aa7631603b85c18a9bb7c83f6c825b9a421e59718b43d745c3667781f819b2014051bd51758524bac2dc9176cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3555b1950de9907289bdd8591f5994be7f920d25940baea14226cb6907aa5ec878ca37ea698c84819b62c2e13115de0ac334169f3107742f42a9b02912b74c39ccf5181ec5c0686c785e246c424143f5363900c7c22df505d1308f8483108f31003a126401950e2afca878443722b30246344ec2290fffa542d6598f14e803f9d91e5d050541fa2c52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b5491149e25746e262193965815570b9d353eb1ac9ea9875323a33fa4878b06054e3867ad9a302b6a43ff902453a92517c7055b2261c7ea04f3f6051c16aa727c169c421a0bcd036b2eac82adc3efde4bc28381589f36806189b780c327bf4b4b9b11dbe036557cc38898557a8a48693fa70984aad327078c1f851ef3409ce0348c16202385c22a70a0c0d54a7e727c0fd386845890df7687a6f65232a327d8b778eaf5a29f43787646c8eadba0a1a9b5c2a6473252aa6f12954bab410e4aa4108b48f618ba595159ea8737c7870ce4b0791706ac871111b39f71b0a394d0482c5d61c4d4d5b3ad0f5936002477763774cc2a06e7681d616b12cbb18c9e0681eb66a724123eafa52f63b2774829a373ac8211ca3a9369f128b2c810496c8a9b32d0813bfc2ced0904cf0bc24222b96ac4897a7f4686b5b2118780b656406cf42294579036dc995c42089648b63504b756b823d22c54d2fd7428bdcaf74113d6345c1eb505b843291a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273f15a8fc937b12ff78c54fc273fcd7dd5611e5835472ed377652ae64495f9cf5224c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = 4069de96aca28f486c6e7ddfba8d33cc5eeea96de1e2d8bf7eeca884b015b80bacf2fd1e302932c267fb4a2c4e2e906694ff356e758ad383ffc1a106496d3525a47d9a75ba0ffbea3fb4cffad4b0a490235386cca196e168ceae143d66145174f0caaaa02f392bbd2ee43d35cdd41bb30fbb4289288f9de182bb2a2d2d03daac88111bafd2a1414824f23591105f43985d92b87c5ef71891ff72c76ab9c820d48f8796a801bc616ab7ef6ceb88852e80be417443294b70c8d2b9f5d1134b230facde0bd5f5c0cf873160e1f24c9b65744b96770e9a767a76f1b6eb570e97d27f8607cc88b29f8f46e2e79957cb2f583b0977074a9e8688288763a152978a5c976a116fe56e06a108f7e894abbadbeb69c53e7fe653bdbe43f62d7e7d30ebc8835eb532969ca76eaee890564ab3d703556cf9c8ad316dd94b9a5433776697b7a2ccd2ef624f6f1fed1716c7a5615579f51611480d074783b3145e87e42d159f3b1b47e91f3f930871c080511b6e8c8693356e17a892c61957148d16f91984f9ec83b3926dbeff6dd1944a6af872864fad3558bbd8ebd1ff66bc13444162a09c13e4e4183bc6f73e9feb1bec63db3d69c5fe3a65e37ce099c7f314e4ce7b112ab290d97586a72e0f76c4327c3ba084348318b5157fa115ac82087f9e7344b37f54148a367c3230a357add9378e4034482c7f45d0fc0a6c3a84a29a3a31768c352881713afe9a69b82d5ca99c929f7aa9d9e1f391ccd3403bd86a2c842137015da6b0ef0e6473a3dc795d36ed13f36864ea81c83f3da6f0c553098498d9f53a3e41f528e89be041069c11c2c9fc2d7408d2bf133f5334e89536fb59a060d9204a8412b8e6b5832c6031a845c31ea89f6ce1193e2e2e1b3847a926a72e5f31cf3e710a592682a85533a42df66f2505d4736f6c6311f09f7d7fca6084d68035bc48d45e1a1a7e530e58019b991cff624b86378b4060d45db07b8325cb2beac2a3d7cf40b7fb3efa422cf838debfd52e8afe96ebcbee8ae190e157974ec434160b81c4deef7e12cdefe2160c6c6283357403355c2cfaf58650146a2ee703cde07e3f01 +expected_result = pass +expected_shared_secret = 99b58031465868d0617fa795e6be1c33a870a1e154a85a2bf61346f7c55f3b76 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +private_key = 2bf07e4a962b0b87b2b35403a151c7a474a78d33b4a0132b524babe056ccd3ca0992059842a132f34a3178caa549c338355b81f900345863b4150036ce45bcc56660ba511f511a52044649e0a4a73612a767c461d08cb1dc6698e9a8675d408fc3875a1cb402129b71595a2577637bad415540487a65ccc30a5a4d6a520ed069834583c732722ce4b22269c67de135c17f92360b0cb555d5892838c5754a1109cccd93e8aba06863c134a5707b2352d07f6fb0b5df0b6df8c10fd3f807923b1f0135a52770188ae84785f33341488b7e64a40777425f693143a90776ec67fd88c79272b4482a46cb3667406a646602b3c2f6a2c2a4294b14b844bc8f9d4063474a52e1627b3d351c5e20520487bb51d7c4ecc54eaf2a6848a5931194be7fc8b39c508b2cc510533cba6fd671cc77463dcc83902cc18af5bacadc8507b14059c77d3b362d8c91956ed9c1d5366781f5774a28b360b45abde0c56599b2edc28fba61c7893589b8266d3bc66e9d9c73a3e1a35fc47e754b91e7e5328c79b28f48952aa0b982aa7027f0105d020cdc6273ebea851d948c5187b9ed038bc79a64ce5c7ec90b85b3921e1e255990fa98687c8a9a921784f52270c77058f090779279ab7c315f824bed678fdf845e79453afeb48d4df17f38011c1dc66412a22317b15f28070232706d97da10f5942cf485879b8366df4b115d0949ed4670c4c2556e8b5140818a13025c044996a31725be3b70194182487048d9b08d926a2e6a9abfca0997365286960800aa7550806a3fe8761fff81b7d89cbe2d49a445225e401037441b337ea2a6dc3a8d09f076e2d9228d69172135c65d40994a62b3f8e86214eb0e597306e2d30d81392117fbb48ce0c27ce106228067eac0b7437a3d06675e832a153e327471464658eaa6f7866d0cc9b49fe66496b26f2ba26050f670fff80f97494221e633c345417ae33abbd60bc6795fad37a7b4f822e502338cbb29d35a71a2217c1b8c49f0932267ca37eaf0c27c8979f2334873864cdbb03dc860b9815018e7165909768ca9311fa2d0550193c60ce5ad408b8f9d733ee5e0385f8b6b595aab2d5917eee9401f1b23be84c1e1843126763b2d98c83094610e55545e5478f7251d83282d889cbbc4fc2ae7e11e13874a1cac92000949f82b43ec516de9500f51469975f5b6d5a35de6002e1aa68f84879ad6024b8d913096e381e57776b8ebb2ef501e6a3464f3730e668a22fc8224764a3810aac4c4213e9584516041437bea1920321d4e53aeb3336dd677579f84362265a69090464d053447684ad3961adf10605d28ac5d0193c2f59c5304b14da328ec44cf51e83992fc6f69380e694679556b14add4801342cce20a8658b98846827fb2f440ee21061253c3207c9cc8961ca37c4b3d9c0ce74b36c176643e8ac5fc053a7622158e8aa1ae36824a5c6a70b07dcae4846f28321fd2bd6822293ff4c446654f5837856fb98be568405a822f36fb610301ad2f6027ce1391a8bc0c4fd964b7b807b3fc5b684aad79495f78f980524a808419c13bb1437596621d89cad5475fde6887b973ae08f4a9276c2600489d0d773bd18b0bab3016111c3ae1725742f424d31115be336a5e5b9c3020bd7a4b5cb587c593ebcf61981e3cc6b4b19baa868092ee71812a6791a6e02077c48ee4386120700a054290e0c6b792857659ac01d715b663a3cbf1530976cab2ad5b54e6463168085ad60c3713a41722887e83b406cd67a7ab77596f820013fc7dee7c5c87e776c3976706b3013dd45395653fc4a42f0ce85dd9d49c9f299e38480dc1742348306a51d79d6f8a4285c580ad7b66ce5348e44461eff13ddb4aab80f84948f94c856c03188746bef5c8479c9c9cd1092607822eb82c2679966b17c093643e45d28bcfb424239abc55a52a9209bdc3d70042204e69c1926132588a6759ec3776e8794483a6b2f84319c132508c804112865a3a7c804b496294314de47a8c03a71fbbebbcd9e28e5441c654c04cbda9b7345a73db10a462280eb727c2ec31931d592d333378a6d261aad3a90ebb4d1b23b92d7779a0ab56e8d0ba87aa5413a34c8a18cb1406a8696837d7f547acf97132a015f5a76087f292b80835e32a46d250aeae45999ef2669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14ef7ef8d7d81aa907fece4c1920c7ca9dda3bb9d57f09193487bb89d6422f10cb3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 8998abfcaf828a014622c23957c75e736cd62f555987abe26d3bde3a7ce51899da3d5c075297974eae1a19a544b3922fe4a64414304fb534168154c21b10c77fbdde6d458eb54632640cb6319204c033781af0aa0fd9a6cb236743158be39f6282eed6c27544583e060663ebfd3e4e8829481542ceec033950c77d6769913e3d3c35a5767f9be786cbfda254e60c99778ec2892e3c04f29f1a323eb0e3b4b62704e63b6b6317b79af26adc4bfc6f95006deed7d1bd640515b8b3ba4e523e8cbc0e5b8e28ccc13f88e228b188fe3591302b91308002a4c5e1f3f28620bd2897a1e1aedcf836050b7747684c544b62fa813901ee544b6325d74ca87fc716f8cdb3c5263324c01615c860933501d7cbd9807eb7acdc87d4f9af9653f74ae224cfd230680b04cc820ed8cded06dc1dd046b70f4d95503668e2e45bdea6e38c6a5848177b40e8ccaf565ae7d170b2f4f6b87728f95b9828e9852122a9fe1c901d90f0bfab159353792975b46777e9b4c9a85747f9b50a7bb71f2dd090a52b759ffa31619cca7bb791e748f0028f0e0230109e622cf3bf11ec615b4339ad806a8492eb67e00b1369e15f05895c475fb39cda68db0edad0d60b1dc2fba828742df7241dc9fc885aae84e053033db30ae3712a5b002c52feaef4a5a2b0f2313e0a932d83abc4181c334f223cd32e54368ea1fc65727fd7d67dac2c2df471e71e51de7a688407a3da7549b502a28b3ea288abe7242c4b88afcf6218cf535d8ec8eb0d4ad36786614d3192f714f2bd914440b6759c5451da3b2b3cd04ce723fa2e726e497733d044fdbd6865e05d54192b373a4c72f3ae7cf414d79fbf2c5d9155f8dd25da662ef2c70a18c3d304ae1930e08ea81e01fc2777f9d03ee4a380c23095e2027c4f648b1b84d112726bcf837ab10007bcda9b40c1b9903609c61985123143d509a8bc39aec6c16541e869e69e5a282e3155e37876f635ef010d05acba33e3e7b7e61b0a73fdd809f9c7e959dbb24ac7e32134f2b18ec212e0161f297c5d8a705223b3b70891056c8ac524498e0f8c7ed682fa20d713b3abe50dd9594a6e8c261c +expected_result = pass +expected_shared_secret = 387705c2ed600492a0b06f5587ae3c40be55e6d5592597e57cb8015de9e9271b + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +private_key = 4aab84f31c2c167cb7a84377554902e161c51149c4b9da584cf7688eb35d668cc7283c5dc6e7a98ec61388c7b5cff73abe0a703d29396a80a00fe124e6486be3980e53f9c03efc93b7b64964f3bd733aa09a1b4c9ea0bf8460768f82c1068c13b9cb9338497cb6447c97ba84bd63309ce6b5ae5c798d323076f952b8fa9e8bd552b46236d458a42dd53542f4152e12278a282ba3669a20650284f76ce17531def56091da71bbe64477b84197e131b964c0ae909976d62df53697e6422a34d1c268866bbd9048670a8040485a341514b0eb83f028c1ff7583f677334f41b0616063b98c6a6343813bb335e33247977b3bad15bf47824c207348db304bb16332159ac81ee0656d2c6cc5496417d734d7956506e73271962021b1a3c8072b96a7937355709bb613bd336814778684f85107aa079302c820d701b3b4c301dc870794bdadba10e8dc001e41478b540383689f0574673237c730481083a6ae4439afac2605ac8661b0c24417aacd88595030aa1395abab8081c6d98685ccbb1aab1b8d4ec42d67b491d2bca6c0f02f994753ef7babcd51009295c5e1b816a326436ee64511ea8e83d637954388b6c15397f00a5dd85b66a92a82829a28027eb53c38849c315d67a8ed3cc23c3229b98bb4c8c89ce8653cb3f8800f5895eb6c6703642e86562d97f5bcaec2c0c7e3cc3301b6b119a772668447829c5fe43aaaa1c6a1fcbfd8c82277f2859380b77de92bb24b279d021a3188c9e90576cd901f1b64b201a7190793171f8cc16fe69b639318a386bcb2b8cf82998512a691a9f92a92d5b2324343a6137abd2260f8aa7870b78bf864122bb261c2c11d05c24832f413650171d92b8c5a1c65ee04b942f90ceaebaee2cc73538b7cf11a63d8025f1366456f841436a36b98f1bb0c5aa8917cb8674471d57809ecbb2076182261296f1295371a91a736a064e3e5650fabc21564718873b653ea75189b1fa328b9e5169df387a4be50cb392179f1138921aa28843c559b9b53330cad72f17fb20189bb578ebb16bcb5455ae207280658c66b012ad50abe122cac1f5844fc567921fb7714215214938a88ea6a5678c232e9542a42bdd4664fcaeb10c9b8b9c98c7a03a82e25da09a2349361570f46038b3902031128311f04c50824ae86421abb346bdeec824a085f46a51d86f5843c319da7470190d572668384c46149b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85bf822110b942e309d03674d78e49e19a8cffe729986e06c14f87bab772035908096d7382488a7e450b516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd34146e41b811350f8fd9a86b113dce4735bb149eb4e8c04735bdedc8119ef7a5f6abcd94f55acb7276bb3b6000b9a82831209820b89d25946b59a888285e1fc1904d4c1fd0f39625ec2d01360768f57158a5ae7a2193243b009297702d121e52237b4cf8cfe794560f270fa985c949e2c4ed748f2006159d4879492b4f8a14b8d90c9e540b1f993a5236704cc5740a1490461fb23f3540766d249394a144fc434a226b04a38c755de32dc6dbacb70177189c10d8e43e49649840083a93817342d4294f1ca04f9a9ac52846f388bcd784477d5405a6f36c9774bc80909bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b8764f3163a597910c9aa74fac696b0cafd657882004805d36a726ecba03171c7ae41e68d08e67cb7780d7ca135652137613b3dc58b4176eb8ecc9d0b71c5098679d0b2a9d7058c71cc0d64c7a22f37c63a29c4f007d8d62bd8e245069bac1f2d980c0651591e5a4477bc03b47488d08825d44892558009392c0edfac55a2c8fc83a01577192d1dc27efc76b27104e61f34cabd900784c1fefe7125db21d15a6a4fde7780a9a22a0b52bd6a8b7f2120266f9472fc12a02d17c5ec6938ad416201bc2fed6094bc17e86082659863f5ab07c07d20ab6c9b15312a444f0482f5a24f3a96230875ac1121cde130d6e221341d78a30902ff031122f40c6032661f56b605135464185236a91a8e161aa0bfa7a59bac682ba31b5030bfb178cc33cb877796ce20a6e873c921b2c26e63349dfc668f2d3550fe0a914178c9845b23af95b52f86576c71a23223f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9399b151aa6b4654589afc36b8343fcbdc09a3e5255b378d6ee5629cd8b3cfd555230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = 35e3db34d76dd2648d1be8b7edfb0f2f42e478a21277a69ee89ef2fc115b1b49a7d510afa8a10f55f14f8ef4f9926e30b57946e95a1491414623e08bd6475688921a22a2caa5819751f85b0fc591f97a84741be0a8132d612c9cc8e4805f0683e0ac87879ede6d049e856297f9699efa64855c81a91593411f7630eaf99e53d3a189ecf8d5c72acfe4cc3f4134b65b572137f175d952ad539c10e87be71482c02e4200122a7be856363fb52434d46fc8d099b1fb42c2562a8b09d4c501831d12892c820e4f93472d368adf41b937312a3dca33fba0ae00b0056494d11a3c4a649eddf0d728b15bb68daad968613c36c4c15dddcbbbc91a1ec3cb1cae20e8753736425ce146ec3c7ee3dfe4969320e479c2c4496527b3183bd7f933a1baef9f352180e16c855d5bbb54fdc2eaa821f91feb6268bc6c1248a83f2c587d017c66cc15286908b4ddf32b3fd6552f93868ba01b91480c641929bbb305f900b8003b7561dcc4f7b55759ce84992eca6bfbcceea32da4d14cf6601bcf0a2dedd16e8c62f25dc8bdf3f313032aa0a365aeb148ad298342aff0d3aa1ecc6b35eb17078df36a0fde0b607d0063fa971fdf7551935e61c0a278721da1936a79e43fb1d0e9a03789817c3cc6cf1d1fca3722d433e73a5ad12d2525a3f4d4265018029247226a6862ca38af8b1bbcdc408f862076ffe17b003fabcebc049561305afd51bbff6d027e453b8a607ec57b2e75f2bd4a2111cf5b9cb6024a968bcf84a6a60ec48a98295d30b550aa0407294d0e28335e1d683fc4bfb1078f67bf2ab8539f066c02155f510a2434d34389a4fdee5f287ceee6e55ef5e9a13f1e7cdcb323d6d3bf1ba1c686f312cde818af6b0680d41e997df78b9a0a0a9622eb0f36e73a96114c7d7d42dcd2cfe078b872b4eade50742a2e1f35a3752805baef4071ee00a01fdf2eaa01de47a772d35093e2dbedc34f535764852a67d3624425fed334e1498bf8d8fe2daa712b4f8d075bd0e34227d8c8d060b223b83492c3b5d034730736764b6e01b696ac6386ee84519f729e042b9114dec609eafa705858355c425f92f50378cd +expected_result = pass +expected_shared_secret = 2a426534e3c23e28a237047aec83d24abcef8c7f77d85d8b27aedd7c50263010 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +private_key = 3923aec9e98d11c99196b0c711e136e5036c4b9174a0d54ccba085ba5a2f7d38c4fdb81d162415fe1730ca3a645e10be5ea053a9f0acc909c038b73d95a3c94ad476a627036d4205a58b287d38af91913932786b7c235a2e62116ea48c53337a946b96de3635a1873794b90943cbb7a1cbc7bdf9a6d6296973d572eb9c35a24905c405cf7d997dc77233c040a9e8169682ebb57e41306bc6cd6caa7facc098d4571788b406146c9f7b6420617b63b17b29aa07cae97654c9e71808aa3700e04ecb141ac2fb3126da710a2459aa210013336657bb2496926a58b730076a7fcd9912372a541dc12873d31c0619af0f5663d66719de703547eb09d0173cc8ab2a65ecbea08b4cd763c8b7caa8ea1c8ac35c9c3e0baff48097395381d511c37f1b1a4ac1c9489724ae05b3c3e3894d07018c463117eb422dab556ea49f9eb65b7d29b4ecfb791848715246cc85f4374faaa26457982931be3d84256724522252b079f54e356aad6557b65a4182d85b29d847bfc4e3b2c5e81e974c00a00cc3fe81ade2c6211bb2c2d1e503e7f5c5e9f443403745ec50aac78859aff7a38ca28a3de66342d0a409248f8472280b135a8fa77911f554ef078650a163bc27a506cb521de8223e9a729a43010c2806086c059d51a6d01254f2eac6bcac118d7735abc7785c1656e68c4d29b03c5e9c2f5ffc16da202c2dd4c48d91c517c2be222b18cf602a699029aa8778a915693a22371e475a323844ac38a7a806c55f229a0f92c83d7828e28b64f74aabab1c4bb3b50e94e64df6c79a0ada21829a30d3356ab85b4533469ea707c216548de287750ee96229a022bed692d1f2021d2723b2365b8b6a3b2a381a9cf75083b38d57fcb127589f13f522051685bc563cca799b7b4047a0a3915ed34881d26fafcc73fd2c00880241296a27e9c68dfec08b4a465787312a49114be583289f8587763844b630602c7b84718641ba4467279b940bfb863437335ed8a917e3450c18a9c6e83a6836b786660fd8234b1c845b95485238232e6719cc32164aec22c130ab468dc14d44e99c360c97b6571700d5b483fc4ff8678f811637e2faaacf51518bd1668fcb964116b7732c71d6515f51b0a454d0359384a2ef7c5fd7ea6b47350c68fca28d6c35219a359e273fb5489e8f4200f830036c8c6046fb7269290686241fc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b2021bbb207832f7b17d187a749eca9cd8aad1fa0c2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956e821c0bb623f033c0b926303d77cf8c2284648059c9b73afc326b0ce96bc8190d41d849a9a7afd7091527804812a914adb475b1149f090642f1c8c98d6453cd531cad4b886df17975f91b3aeacc23358b13b54e40d8856058bad19088371c7d8d896b2ac4c8f3443b95099000a237d791ba0853a6c0e821b051472bbb1a95c7a480529683a7978373081f30af1a7a6c713557c38b0bc9b281a622c68d7912bee99ad6d1bd541182efc3bef160358c067a3363b6e03a5db440bf6ce2cd8cd09c03985a5dc44ad7219c41b860eb2a8b6b025da63978d0041d9231a4ffb28fe6a6cf918bc6fd59aa6f8260c373b645789b9e0ba4798b4b7d8b468e52b2aa20496ba9cba4e2ae6cf069c86b652fa7204d717a623829218c4b288035b551c6f614805257516276531a6cc9b6260b50576e149acd9fd4b324ba5a89ab60cbdb682a85aea36230eee9215e442aa22679def37947d4846fc7ad5ea3626c9c20d94378834a4f086a05bc8c252d22adcfd47ab0d63c886947ade8282f380730fa7b827374e617582a7a2fd4bbbe56ab7031a51871988ac823181966b6bae54e93fc63d2463cc3b103b745b367b70bd212b79363b2669ba062c75da3f2037c17a290281abc4952de641feb740c1cf2829f1b3ae798c3a128b76f4711121597dbb5755a2964bf886f1208cddd70b759797349e4a8bfa0779da984f43195b6bc24338ca7a4714458068b0193c6556c471ec7586268879582b64d26383a9489a6f525c923a9e553627c365bdcf32a4158452410357952479d84306c3abab55792bc1466beb85bd8917722289534c74559887b0d8250309562910a0a692b0da73439d5e87007a4b0c2ebcf3c124394975657fc07b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454339ba63f705606d8c7fbbd6e66dadbf23f532d5423802c836f2105a636e9e6da1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 733ff770191463a961d8840170e9ad27fa6a5b4e41214e06581c7b2bbda563baf8d029585137f151f99c9fc4b16e4a6347a4f14bde29406f0b8aa277914bf030b7feb3066d09ecbd19605bbb5b97ba890d82f65aaf7af9ce8d346611d11ea2b1af944fd8c5145b7b83ecea24188b510a1c51f876b4910b266e0738919105261b9880ef5c47c984ffb077e754360834012805f346d31e4227ea9e85cf13a787e1207f0b3957c7260ea4fc0186baf4cdbfe650457cee20ea4d38d08f8d761c6bdf33efc6480c684b2f9dcc3902c7f6832d6d51985f571c55017a4e32574b194d9b7ed474d575885b99151fe9ba61fe0d501a0112c1357912fca6f608660a47a17299a12662205cf302fbc9fecea71811eaf38f748839d57e4e1f1943fe7ca6c61a5c6be1fb65d8cf00d6c3126c3fa354ef5965342408e1caa091920ed868f2bac94d4e2a449d98b9b404bd606e6e4529f4dc2d0c8886dc4074773b999afe8818de9f23886fb4913de65c081e2f3712854f038c57d7082198444b7139de2f310478ecaa9b8d1d552aee3fd7e00069c75324c61db2cddd493568fef6e91a4b44015d537739722fd452fd4e6e27dc6d1a3f12bd2281ccdfa0e7474ac89889b370de87037fb06d1bcb712f1e2ebdf238e00477384bf28ea7f410ea3c82764ffcca870c611122f92541569c79989037dd6143058e7c69ea7153a73f54fba2398018f93cedb0b4ede0744c2c68b3b6deac7e9e4dcbb217434b0b472618e102df9a06f5052157d5e6747d430f9d1e5b4a38da7f723f8f4b82125e1653d28912456083557e314a0a2b40e814fc90a1b25a0ef5ca45a5b7f7536548a0eaacf7a0bd6be28d0da8d7234492c7a79e75b2cfa25f69b36edf82e7f883c018157536cf5c331695c524aff16d0f8dabec19d53f0ad86c8f109b07955da0635c894cbb891727251839229e3b29bfea854a2c357aed142272aaf354c2325a3917722932d7122fa88e01256c236f0a517638c5c455e58797c3631f579f1b4fd8ad1c2719bc28031f8f72426add2c250764d9e623d586fcb28c17356edf6debd32ab0208ee19d980e8fd2 +expected_result = pass +expected_shared_secret = ffaf18d4fdb39a4aedc80c7985843f6b87a02e36c69dcb00f3cb01a619a77779 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +private_key = 9a605c2cca636eb3b589f3853b52b59aaa3b7e7a6aaff24b74c6cc2f2022d662b69a018683a5205c0a37f9c88db6737eab28bfa1e12d9613188cfa7a5aa7807efc6ae9ab78ce34ac85b4ca61e8beacb89f23d37fad0c91225b8dd7f10358d8096ad37f2287a175e158cd90a2a4128d2e266ef72708958351eab74f63e45672a16cc4d3aa77260630c663fdf27878e0501079c55b56449f2bb932b42617097126a85a2e5b24e9130e4d02b2cf70b26c2395d2f8996248124416cdf21679c006440fb0aaf570aee279042adbc3fff40ccb122ab7199468273ea38abd8098af3940c65c8951782a650b50211927cde10c3909168d4e4699a154a2714785ffd86c6cdaa85586a40aeb6cc081022edcc27ebb900786c4aba36a45d65d100508a4e41231b58695a53f0d340fbfa128e5e2202a986d471849fcb4947e1c1a2505494a320f288179b5cc5d04847c68449ac100093ccc879bf7a1b892be385844365835a4006011904a235003df8a19e0ea37037202f3b6809dd0bddb43ca5d46506c165bdad665f97ac882512583175818ba0e63942a612b3889645e86dc293d352380b68379fcca92c4c1c7aa5d1a842950365ff465118fac96ddba65dec7a78b1523e0d5681cc7bdbe656d0c440aebb4801ef465a05ca9b51253ef24abba291821f5a1460c0f8ad09f4ae08d83401ac0033f84c9866ffbcfaeca8d4b216eea2b05d92964a1a57250c6b09d7c13e1aa665791471212cbda902c9ff58a0a05120c8364b502187dec8f4dc35843d13e85dccef6448afb8b80fb28763f044684403ea3f110297822c7889b8bec5af016b4fb22c557eacd82a574ee307eb19673b26683f6822c192270ca38044140426b9b4f36cab6ca673f6bd60e67a18d73390eebf88542f976d53ab808116c65020e6d4825f10bc00d664fe0cc23837a9938d70db9304994bbaa56b378d8c5214d6762c1c25d8386328c092d73a9174f6858bab76ca807aa8c376af004a1b4679dd6f500fe139080981b6836a83f05c7471349d1405984fa95bdc3428805c78a4bccefa91f84d8985dba27585a834079b041486a7ad9981ee3723f94a99b7abe01cb641c501f856398369804ab87a2e97191f6c918367c653ed9a2a2559a73db3f04a4ab05e1924d3a9af7392289a894057782ae7139b1e82bb32a228bc7bca367af59519e5ff9319aa987356c97ab724b9169302e0b2924307a46839a4872a57b00ad4f8b30265b5d6a3c95b31c248da1514ffa25d908915635732c1a7e2c938c4e528184ea2facc556eaec7171831aff013da5acca8c500038c55eb8521b14e0263cea2252986c9023c405b56aa85791bda25c73db65126967ac8669c197153c14275a574abf090d5e52821f51a479238360305cd7720fa3e239878635d92315b41b2374732216ac4eeb5650a4896b3747c752827407ca7046a315baa63d9717824cf51513639607cc752ed60e743b5f8ac54168497aae4aa3e4c8aa65b97bb03314501b8644608ff49aa197bc0fb427a13600bd8395c94d534b1fa96341f8cec2b218c1a5745275799e93767c44b128bbb0fcf59f1899593e9176f070cc541949b490bd20790584d3b54b369ac5f2a7eb24043155272534889be150f320019aa29b8585ccedf65ca73211ffd8a60f558b4482a1b0194202c16cab1699cbb9544b221c2cf84726608311416267d065d5a819bc05c54fb0c2406bbd4efac451090ce9dc93437312278ac7f7b88f0b69b80b7982f7989c47a18185d2437c1689d1378d01c14dea68b701378e62173fbad1ac05ac1fa904ad1a22895c52b89c8cb548a4cfe168846f996db569cd252281d62c675c298a62d1a38c019c5c08caa986672df818640a90002c12042c3cfa437887a4cb221b65b94a82d7102d07a16333177890ec100c2a8df22987d0019f65e64d5dbc544fdc3a3945a3a77a75099238d0774e9681ca16ca0e9c0554e0e401b401243bc75390b3b4bad59151128f8cc28c2d40bbfc89b890c64ecb65826f202912707f976a2f76463ccb803a945c946d282cddd40f5916c77e268dee390c7a823e5f3313ded9bdc39c2690f15834e44b2cb1335a01068955a3be7c635b7036a975ba7fb986295c3249916b3997c7f0e2845d24b9b264ca4d49a697d1abf3ca9ea6313f46c0cf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb1f9e26333b637ef9beb8881c63f9412b07c47a276af0e242062a54026bcee2bd7a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = d158917317071d0eff707cf8d3180bc90400198ea03f51a2aecd9352bc1bb1667293927639f77465ed33ef8165b603c35b03b898a2e251d775e77a864d8f842a2793d82e7f9a2bedb5e56046d3a9d5802b7e8580d00da950b709480931ef47ddcb0c16b2aca9f156eb8e1ddbc9ade097f6d6771fd77f44a1404289fe091990b81583784331dd372b27462623d810ec5a402e1ba975dcf833e7b9d13e56db1b048836baf7e62f02d97b1c17c9388a09644e8ace49be91530d8ed23327fc04b4d018cdfb6e78df8db7b978dfcc5629735e7ce98295257f29cd2c08262cc41f3fac96a438d71689484d772a638d5a685a93ea4d7a78372a53282e595b685d663c73929040627036439424d7a176266305ad6e381883562e98090508c139f234fa03b49dfe7c7e708a50c8c0f3426fb392513141856313ff3942d8b7265264846f0aa622c51ab6e5d1747aa930fd92ce17008c06a9bc6244259f666736b4e6a92c9a9460aef716aff767a1ab60d2f39c83b7126f15615adc2acfd109a5fe6e790b990994b1ea3c7e73a3d00cae090ce45a5ce26bf1b6b1bb659f0cd4174c934918df77bda5a227ad04a9f78203594f346754bd780b97467dcb6efa68ca43db645253948ac5ff4a0867a64a4d25322f2151561fc3c2f464a6d2c7780afd3fd45fc97b8fe6f21587e8d627d008433561119adf814683dcbc61f7d733ada0b06f00610492529bcabace21be9168e4a75672448398c924f0f74646cad64db5244d2ef05893a48369ec6185e0590ed71edaddcbcf57c0224e1f54b680eab6e624863d7d90bddbb38524c1b76234e4024bdfa0ae2abcf69c3d06e6c8c658dde6a8e7d67db96eb1a1b238add1be3675bd8d4fe320839ef2573e9edc8f7a3e25976bae5d3a4907e984e1ff007bf5f4bec8a14a614b3e7c7ace89eab3b8d98e4bcaedd40665299e479ef41a74a4d6e3407f7df225191fdb1153ac2a38220fc6eea430ca97cfef6bdf6ed34017e79293ed24552670ccbe37a1d340645331708b3c2f9bd21fdf5cc7dda112f49ab7379b2bd8cb05c9dedfb762bff2da3e9cc698611bd3ce1681cd +expected_result = pass +expected_shared_secret = 1b37c256820ae408a0005a1fe7461d54e53813e6e7ad58ca3dde46a53a44590c + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +private_key = 03433175f23a3116525719b8fb7c7a4cf3c8b360a79bb6c54922bbdc396a7577a7abba86eff8b329075950f42c0c8173eab72f614bc6def934277883b121b0ded70adada3049f5cf30db20dcb313fe3b4c7b60c396b17a80350f0ea38e6f800c7384be35571fb8170aef046cf28c152682cab9ca8fca2117e6baad471a78b24b75518840aedb34ebd3140072abcb9a18427714059b2cb5272baa713ac7a1c98df30042dcb7fd7b2ae996c4cf34168497352d298ffeb5bd64232610c6b7a728b5b383573220053766b1e31720daf91775c608cff42468142a37f3acc06bc113a8cd493abbc10ccc1b660e7f821ba8901ba1374fd51948ad897bdd0b7f4887b41600330a4cc6e77a6910888bb87cbc26bc1ad69450a92bb2c8e0b56f131d0384c90b30312bac22f7b521ec6bbde3112053b246c9880f64c6610bab71d0923190f3ae46a1070658b646351dbc0ca88ca88a987b9e23614ecb72795d2b5cdd31b0b912200a229b657c4bd80c38987332a7296c2c065e1dc42a1aa2525b968e5289bc16ecba39111fa39a4597a1674c1009dc649a6b611a0a513b93e9636eca68c3e461f76840ab73bab8329915020cc9e280c719972afb7d3100224a327fe9e622735097e4e1507e1c0d19a60fc0676bda061bdc06b12b38a0dce0107c39b32847649cd33ece1a65f4199eb348319d0a0a0886ba0db3b7be893ee353b0122a62e95571d3f91316b6ac40270de06a7cbdc76bbaac7896bbaff178a2eaaa1d9adc2102e3b256f43adc249544eb0ead915b9df30fb6ba4c4fdb4cc10a59218446c87512683165ef97735ee11d76a82a8f26c50f45491621a7a3f32df657a900e919204a5df1cc89f0f5b3273632badb3738c501a4a77a76e40bafd478c3f504e54a30884bacbc107f7349ce03930335d171c6c4acdb18951163387b07b233712f3560bbd59182d754148ce13e80142f6f9a02dc2032e8b7516c3749c7fc2891a5c410339cab703feb2b894deb0ca25a785f09a25d1803e50118a1c09eeea85f62c52292e1c560749ae1f3c23b43cd8e430e70931d282927822610bd871f48c337c5da3d501a0171c94c8651b920fcae8eb447d9913047183cdb16374d9b7c6fabc86fdbbe5905805f50bee8c12612115ca16bac13160198873b4f999e4ba1c052767d7d5ccfb364c12a5a6c81232991b5100f21cf47c50c8566c32afc13f7b03fd9a2b09a807b198a4b2ce48d163b0398731c142ca7f13b3f95000fc1345ad1a50952d09c6fa42ba6b5119ca1061a64a5ec4b1323a5be3ecc97bb21383f6c559550ca985c53c4e78d0d660c6baa11527242e61780c52770cc3739edd2ae47c676753bca078266d565377d2aa5cf677945551eac12c61a0a95f6930a95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a48b016de4c331ea591bdd43a51a2109f02601569764b8999bf4cc987f25b3fca822f5771d941ab90a0083d6676a3d743e458381cc3971bacbe8c3a4871d51baa80a1c34462cd46ba338ba319dcaad92ba7e471658097335921728f96b1f06a7b84e8a74cdb635b904dc7a583c4a6208d894caa22265378aa24808ef605193fe186bd0565d2c32ff234b45e2726d0d7c939754592baa93297c28c6462bc0945ec2035e776b2e4526129443c1135cf16620ce8b12825321aefd92010283f6a034fe86474a6e18a62693600d012ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a85a1f69f7aa39fc98938b5bf0f8768c2020b97b1c06d1c3b8773f8d110280a76834fb9643b42fd3dc002e3602ec84b79cea4d9b9c173c58c5417531547539e1d61e7c6ccb5fe2152eca572c7738e2a872a711225e0922e1b219beac2b2f3ac82d68759d83a2998014142491404a6e51b88dd7a21a664a14d6f3043f67cb0a2a697d537f3357bb19a6865172653f183e396a78b7217dd0f18f1cabb936169f6d75498d9027e1c59c7ff8558ef138ed0236d20a23af399067d4ad57d36927bb88b4a0836ea06cfb941617db0efa049b6de6cce0f5cc122239d85391c56487c48b919764536fc11a6b3b3860d6baea255e48d007272a24cc32637665640ffc8c17e013a3e974d6a5aac78ace4a2c9a173240a9cc1c8e18ccf841b4b77793c6028ec75c5e4697a32b591652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d64b9f8198bab9b3b2f2a1704cd4ddf6b3cbc216ddc0f062a72ef40115917fd218f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = c7e28f99c5a07ef7f1c3a5189686dcf99618ea60d0f997ce8cecc5b31e6e817f3aa3502b4945bf769871c8c66f430369d0f7fd9fd6b1ae63a7cc1599e36b8ed2d8970e7e1be12b49d1ffab6aa01d9684b4de5a5f53915a44d454615b5bf52196b5042071075180ad8cfd09f08afb3b1810ed4aef9f9dd5b0437183c22b9b38f17a86a27677e7dc64dc2d5edbbff7a3f3c24e1ccca83e867d4b0c027e6a9a27048a6cb0b1e0f4d9ef9d18702e588b4fa3972aa61ddb24b75911838a420602d2934370b9c73e1b202648801c0eb654db3f75ba67b5b1b40901f679faee7e390080f81df9668f1824027aea2a43c2f1cd6fa9e4e394e8d766bc0e23172e4328704390d54e7a8e7cdaa3cb43397cf4e645e0714e77f5167f75d451483c1d9f97622320b1e9540b9d31512970f416ceb182a30d74fb9a147ee5674d83a0bc2612938e9d7d5a5be9f0e748ae73f94ae7fc8777a1b83f3b53da066adabc238359a5326f7b3079944e550a6e10e87d6aa3a01c5b5a51b4b5ab85f2adc1ca4fc9a1570f9bcc31f57eb521a71cd45a98beeefdced8f9390eb04fa812108e8a59fd3531eba0583f345b1c7cae7f8dec042ad22af364d9f228d594d1c29768205c0197c72db661013551469cfea09bdc4a4c6594c358fbb5c6b236f3ce65efeeaae38b0d78e26afc22087bf9ddbad098e5335de9bcc9258b1ba18a06301a3da939aa63a398ce8e15684909447d51b9d3e2a56b7bf9a4bc7e4e63d5824b58f1979297fc842a362cf9fc8a0b00db5cd6e3cf221e952b821e1f34112190cd623b8643d8d1c76b0299949c47ce4b09c8d2ee956d501b273f371467ebce9aae118c6bce59e65c498436ce4dcd9524351cbfe6aaea71fb2a52e5eeb54a094988960d9035e095d3377ad03fef8176f0a7c682f7794d7ce4d6a5be37e824d3874afa160b51896ab85ed779e7104577caa60250b0f2ede06413e42183e8a00101c8f0dfa2dab6c90e56e5b3a1a179eafc9df1591bd8ee593d0e24605b24aa7b7c13ad482bdf7b95b23e00e06f5274594e270b03a97170bc022004b850bc8daaca34a2c3598f07f3b98693 +expected_result = pass +expected_shared_secret = 12871c83c35db351c2c0b4afe0f0ce9fe1f21fdfbe8c18a485d5c1292faa531c + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +private_key = 6ae07bc60180e5b519e45acd6a33b1e15b0fa2353bff580e32abac68f48610bc9419c0382cf4b4e9cb730a1c44e9281a8d1cbbca26ce94d51aa2871d4065a706505061a991da7960911b76694a94144c24904c82b1266278546a636b6554f12572a9cef82593b35ccf00995553a6cdd0a4357aa7913bc7627d40594530cff8e68c345ac211d3619c2a9c033293b2e41d28db2e6f17136f73952e4a6f2d9364996394cd461894b8b38e85af3e4b1df33b0e44c867210c4680a76a56c16f6f396274362684466a0ef73a3beaaf0c09221e577ef3b96fdf3a196d58415995ab5844b65e8a841202ca7bb24993c53d4658a541a4895659cdb0a342a7808aad10a6bf8253655a58df23af6e40adff94b4f9c3606cdbaba00a8a04b99b275ca465f59e7247308741c738ec40772a12554b62d5030da743439c59a560b31a8f72370fc12238f95aaf8737bfb7015a4a3b3b8a772b225f83fab6ceb0c9629a1de010b2db5b90b427030a186ba159c3a853c5de732fbde798e0643dedf63d8d549bdd746bd8f81cd331476581408b7b8f29334f224239f7d4bae95831d260a46f4c79f7d9b9d0208dfb238ea918222177291087ab7dba59e3720b6bf14ba0c93c7cbb5d79860f1087917db391abf882be366036f1aaf436580a01ab775205810a5049432ef5fb383566c904693d3d645536408875390a9c8319d0a7573c84a9aec892f862a4da685d7b14742d63044012ab74a10b88c60a44319f8b97b404d0784de33153927f19c7aec9f069bd8c88b5f59ff5aa2be104c658e2211448ad236a3520e54251494f64c84355039e60aca4c696b440b8707f3b0ed0196a1d3881d4cb6520c237224a5dd733a67efb33029c67f5da6a2c42ac9a902ed8ca1ec59b1190e0c29245a5a57210ff8526a4163ada06588e73688d410d44fa92c7a7af49f2a0b6a42ac2660ac76594f472648f762924267a90657aa3595c4d672b7301acdc750a53963a49704fb65a7f5877214d7bc233cc4f0495c5944a43e39a6724509e24f56e6fe4b44e453b6b151931a04e6d1b31c049c5ca009554c89cc0d4803b21a14bb316f17c93d23556b9361ab12a87de122ba9264dd889232ca7c301859aeb32611dcb01faaba8f794aa3c0b858ad75e82b51ef707b4266320a6a9ba4b3616896c14db18bcae601828fcaf9e895c571205070562208c45877780fd2a02b3c697634116efd504104709f75426476bac050ababd708f38fa075dd2661d9241f0c31d7b674285ba03cc34c05fb378ef68a3e6a03a1366b8b432186001c56b01169227ad4bb614dbc290e5a085b7b90478b5702edabc9c12544f9a2102501836ecba58763b10751e9db7a29590711ffb3ffc240500995e30318fdd141f6177c2673330fc558c1cab769f202b5aecae19d1479ad32b4e2c59834ab79464770ca619e88535f84c26e219790f24b1bbb17c2b1017464c1f1d102720f111bd2b95d9ab79f866c26c730103aa602fe5ae1710c4a1782caad0674129cdf8791d780095e5d8a659333149b0797472ac623a1a2ff2beec7306a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578e801c35a429e341af97b505df8a46a7055633718d57814bb6e2abb272c9efe0192c2b55ecc5cb8e389b8bc5992b037d1e72074bd361740aa8a86c63004c99ffe50224378d1c28431f599f4a701f3165c8f6030a1ba7590ed49d4300578985add03887d867a3e82b577574c398c56f21c34f6349b6bd072bcf8318e4a8244bec6f93fb84b6716846670945a33ffe53bcf4c82f8c52ae84faafb4b46bed2a9807d2569c90791c087f3af05b88b45345bc099e9ba4f3028c469a3b4f2a1ead50147b208f24b21c9c4582cdb8633a9a58d7820fdd0c761e70855259216e2a3eae25129b2b6808ec1611800d0fbb3ad6179480bc4391860547199ba04b3a97f72c8c4caa93379f559626f6a4a8da750e6ce0651794138c6b68d474bb70f41975b246de5953c5226606102f98a36b66994e2ec785fdc2377ed9c664a05edbfb694a2c5f87dac238841245733852da5427a0b105ea2612a06ee9019b6dd0c3fa034f61da229b5608751bc29bb13ccaba83832c8d37108be5943cfd2173eb8512d16aa1c7b3b7d5ea6491c379c1c66853732d7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112cde4ce515b882c849717a1ab34f2ac0238c868f415630c1155bcfb302d346dc91e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 990880ea7c2b60e73c47ec16e53b62aa6f69b7a63a927834b0adca183d1b8faf02fd4061cb625c7696f2800564d0c9d3c5ce34d34a90054ad4dcf273516e26ec7dd530e2dd83f880be16a432101156b0a211584ce4af6c5b5076e32bb80f2244b615758b6a5be01343dce5c978640ae2f216d0d96980d53b01366a45f066139d851bb6f5d2e22d3346234fe218be963fd593a66acf04c2b3180a01a32d1b440d5413a12a8d89b0a8cd2576cadbe34a73b5927661ff366d6c7d9b0c531cb84bc57029cb1aae06f1174c1de605f10bd043af86e930ec9741f8e1a18892da2378cadea297d2147d7a1ebad21e8567742230e64f5ceb52a1f5bb2576f7542bdc32ce64f5c9289f82f14086e3346fa0f7dc883dbe0515a02f9ecef57ca3338ae60e48f7433a88708e84fe588b68af0caac4f9191483446bb5db9c663bd212ba1f99714c20965d874ae06531f0843057e281ff330415c018aa8028f14a48d1293d2356020707b59829d545bf33ecc5c562ffe2435cd653c70a13def3eb7b1a98290ff8faeede0377072411263846565504b3fd9ce7af2f7dd21a51295c785a97cdca511d1cfad04e0357946c7fbdb5dacb74da3f72b2893b68057c440e19a829995cf19ae1c067b2692081e8abbca54b697fc900bd3fb5b004704e4e4e56be929bd857f2cab50898fa83c65c9a7d70da9cc409d82ccc6fec7bad59faf2ea233e09e3dfaa2cbb91e9a93d7d43000f1922373fe1f8c9428dbc96ca05db0452b58704029d4d8e6f4bc985a3679324f4b454833c9563c23589e8e4c49b357107c3ddb7991ec9f2963fe15c7b51fa9955407e8a0adfb347e0b1f30033c4299293915a11fa4b1a10bbce36f4671d46d5a7094ad05e15361f2e0e9b6b5435383766c4792851bf74ec3afe1d137a7bfcd4e52fc39e856d9dbef28604b160403f5f1c294755690584135bf1a65572d66bd82a8dbe5be91e43a9aa235abb48805067644aa991e4a68014a66002bc5ed3f41661220ee02dd61b4942fff76fd43ac5154197c798418421b2bdb60265986f4ea4064f44e8dbf2e1d39d97829c4cc4008fe82b153bac00 +expected_result = pass +expected_shared_secret = adf49431dcdeb29f729459cbf3c2b94151005c7b841eac921a71262d65dcff99 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +private_key = 58e44706119642d7c64c6293dc8a78da6809cbf38b043c74614caf23eb8f63db45721457c5e22fec94bfd12cb2ba10587e16c31deb45cb66948677c889b4b638286da6d08b062aa5fb825476fa76a5f0b4d7a5301b4b90ba66292f139891a8aa523609e4f975b67830c2a058bb2bca48796f5fba0e111ac682e10e5368cf8f94095f5701384147abcc2f24f6bac2a57e1ed2bbee684bb3321117323d943a4d890340b28035770c8c5bbb39a5b9794432b021d1b7373870e15a60fd8c4f00b650c529095d8a310868c78bc427a583b00f897d0ac81b6afa2dca4bbe4b665efb79661668bdace01f9a30820c91095d586a9b232a1037bedab70c9dd87377447b4a0043546334d3c2c38feb870b1644eca7b957cc097961bdc3e6165c0907edf4b6328894f7a4413b583bc937109777bd84065aee8352471082f162bba087b025ab16c2a04fbf3c494f43471b012060b499eed776ab383c7ae0200b1aa9aff0090f4741c2a1a444187b702172df84600487820c5374986623c1652b9a966bcb02662e5409bfa5bbf166c9f894548221451216adf6e3bd861a268d25a032c838259825b8b4be0d3622aabc24b5e997756b758953c0a2b38a4336b6dbab69a9e89620a1ac44a748171106efd125f953878815486ae621ac10237c60ac3a56b57c92331cba08f2367e80750a872c1ddbe9a24f5b3cf59c8476d4284a094f1b0095784ab3ab0635a24c96bd1b48dfc1817d27300f2654d4063d0d379c7294607a432187451061e50ef5096ca3e01f020610fea83494b197ddaa8e8e15b054f770bef4b564a539c6b786358892b62439fef59cade7843cda8c6bf48a459bcade476e89a73edc002d06f794ce60043ee660e50c71c515148bfaa2beb876512c6af4e48416d086e8ab844d0cb8e3e15063c26373816bcba06124a1a0ca5102bbaa487d87b16d39b181d34f17474849fba7fe12047883bdb6b816c8767808418f948764b7b1beae0bc09e937e0edc9db69a0c2a265275b77ee4071990aa91f5f62b01f5c76a7556cb1662bcb0aa9d2b560a8b813ca04f28021753c446f5a46665f87ad89447623668ba98183ca92c9075804d082ad2d17769032e77c50484281428c00320848073a17bacd2c47ab391fb9472d395a6376b3f44aa625c36c95457cbec00641a1cc4e248ba7a7012904a73179a61c1524578f739f7a5998355276eacbcfe462f2a82776ccc04ddc089cd2407f4b757748089d10baad85a3819d52a6560970353abdaf08dde151555f92b6953c0b6c51a7cb882ec5c574c31619d8c824c605102bb8d836c68f29578432c8515c913189b650ada84a2b5795093b5edb2a6e0b13b38fa3db500c7bdfc8dc796c7f57a9b95cbafb8610780eb6787d36067f89831d98590b91d96144d7a4c0fb1c34455902d49e39fceac427d723b027709338628defc8a771a055cd8bb143108c9724cbad1729b99c8fc675d007b7c38ca20b14c04549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499170a109ae98e53b807ad277dadda57a4d13f2397c167ca0955e3148dfa1b502726c908bb283bb1b41b89e15780dcba45485ab771f19f1f0350b64a4ff983a5e68982523c1e936b9be3c38ad892b0a20b4d4ea2918498065d2431e7f950bb33c68b23167bb4693bb258610404788a37009a24823b81b95753bf09aea4a7b219cc8a9af4632d9c5e4790158071318e9119def243a30a7925f17233098d3c594f1571abaa0744f0e44714d0c8765559cc327e35fabe67066af141127ee7145546c89fd55a852712eb8c9c77bc649e847d229958e0d7a3947cc4284729209a704aa4640f0c73dd63c6e48651f62c33f2351f5d90bde888c3dc116827b16d8071a01fe02d1b4b485e9779217641f0a0af2434574ef92e180c116f44899afa647cea8403a831ecdcc04faab8faf3215d622dca40a95decb5a833206866068a6b49ee588151454eda821a35a5937a63c23ba0a0d8c5657d18777aa10492b1652ec2cdd22a7f800708beb1943ec347fab41219171fa46b7b58006f91ccba3b69cd7603645c9bb584282dbfb9ad584c4ec0c692a25795111a18709072be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca241ca7e50ad46000ad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f793b60f0d00c09af885b5a0cbe942fde6afc4841428104710823bdcc12319eb35393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = 4f215937409d6d013a250084ae82d22c2e96c529b486896b7e92039aa0fe6d9902eb0f0371b022a7a294ce0ea16e479825eaf645005f90c598dfb44ed713b9267f9ff7db6da752462333351a0ef2716a95103b1710eed9e14ba4771b831b89421bcf754eb368fe4c468b43a00f4b91a47d6e2ace48f79b2c034798f8d08757b665f3fe7d0fcb80fa3e76c226311742b0d7d89369166bb208ff705a4248aa1bcb4cf6258fb23d62de3d37b7a1d8d48a3e3419917bb6d54accfea58def098795ae76ebb421254e1d07f6a81a5833d6994ceb11216c66e61194604329e2ccb1889e0a7deb3577049b2fb54a97f1cf38f6d353371cf4e12c0e33c16f6eb9bcb0c88ec350a3b2f4d95172c0638ce580e08800633f3d24dc44ffdcfc93747846ef985c24b2b3f27ef2ca50c72b40297206fbc64f25b801e4ff22ca8198e00a8fbab61c390c9d9aa93c41a5f07f31efa7fc5d3e1ac75eee9aa2b5abb80412360a9df05c5113b64aee78836fb1da8e5e3a4b675250dae4f0a16f34736967408c6bfd0e73a02e3bf70cd27b7b3b0461fd3115de6749621822ee148dd3919de5141a4e5b2d3c61bd9424b4eb59c51d026c12fe983a0ee925d071dfa6f028bbf698e4d5a31e9ed71967f81c9f7967176f353550d6a5a0ceaded0336b9910e740ac439b66dc878b83bf63656fbb1a9ac95f00719295ad6900ca6fbea3c8745deb1ba64f4ddd34240c4bfc9da156a5fdb178bd7ac82d6dd8f8d091175ceb907ea7d07305745b67f1af18ddf260608d058ea034f90c88ec87cd29c5f3351df52f67d63d4d0d810691c16e3f2bdab6311ff03247070e717902f0dd1c3f19bb04aa9be71761359d27c3f62fc40f4435e6a805c4a7284031879289f500fff831963a7099ca13c9cb6068ee7760a6f0704b20810c3dabfb29df713d0dcb96e7e43c3c591b7911ef783559e5ead8895fbc6093c2aa63536c8dfdc77c776e10e425fba44138235db7235bd69ba92ab93aa9389bd814ceaac4bf171173f9b958ce7f10db1aaaea429f28ccc937dcc043b5c0e1eaf4ac5601a0eeec046db5c0abffea6134a27b928fe5464 +expected_result = pass +expected_shared_secret = 35e1521271e7ab9931b2c25d75f0f09a89b3f83a6bb62ceb99e8e00c5cf78afb + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +private_key = 0b107bf998c10ab147262c4e15ac4933a033d6d6a0804468f06b17abda2222f73d17c94c1f30950719cac69a81af4985e8134e67b8cc84064130a11f1db09bfad73550bb5a00696141f35b237ab114aa4688f3b98a563f1e2b7b8f85c5d61aa9d759c2d6d45958b18251e62e8d2c1ac389389cc2278e778b42e67c962a0484e78eb57b0632c04776f41ed69b78eadb9339376844222b7396699238793f617c96292b30b66a0992caed38042f64a34e353132829abca68e7dd119b9954282a8c87c4a5dc4bbcb36eb2ca18876f8c5694be86df3099be1f6cbd17c2fd820693ca0a0aaf8a495b24777fc4a05129e4731517472cd67998de55417d30190da206255c1cb56c2495ebc2f444a0572681ca45a8b63e262c9e4a025cb60abb81008f0a30bb345eda853a940c87fe9b9ff512043770959206912b65a79b5cfc977506fa407180c8e9e7b178253851ff925acf9026849089ea1a80d45a5e39430ad1ba48698a49cc1319473a91ba46da0ac0d51856c93a2c515283903e619a1b852845235be702405524d86b6ca91814d5fecb8a24669de5a2123d320b6589a7a4508f935594a0070737518c76885c82816e6681f172c72d2825e43c82b5e6abd58a3b7863a5e8111893f53b2fc89011b31840aa010aa7c92db4895b3740d2be47b9b5b34bd034f5d7842c2943eb7ea708079cf54b11a4a2074823a17c40cbfc0b5166cf38831e4c874a086bc15cc3db21710e4c0c8848ffcc67520c291dc9aa33456508a52af89865dcdf4a3c8e71900f6b69f6bbec635bbc088bc79d7b69c7a3e3c6413f8a1892275b8ed8a38fd384cabd4cf5c37bb7eb5a818118a8b239f3b873161cc1b81605106540ecad69faaf143e487aefa06056b188aa05a933e1380921048072baa6c01162bf56531ca42d39aa5bad485852743f5626f36a881106cb32142acdc69bf6e234cfcd1696391bd5be59c284869d1d7c34e86628a198ee16021d6e8aeae9279d62725c7107ca250c9ac3a0d1b045a9a1c8c8af89cc88b295998043c307901d9920be770ce97b348180764fc7ca83c889e12bf4d2298e5691865f9928843b50fbcc8bbe4aae3f4c1942926ddb8580ef06adc73a7f869842a3211bbf36172ac6972811c887b350b5189a376ad6e032234c0840dfa0a7dab2cce171e47e3945f2798380583e4e2b1d5188b18bbbab2564a0a06c174c577c91000e1dc3c79c1a7d54c38ffc21dc0e52e62a3c093a30c0986aad289b0c45841253c39a1a00b90712f4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a630a00a4585f6a5ba1c0ab2c16450e0a30ab06670465628d763b5b0326fff11d5306abd4886cb304a515389e3d9cc4664039bcb80509661ff19bb372a8c8e121c94f5103994b91448982bf1627b38741a8560adcb5101b68937673a2ed345a6fa76e10b2a014115eae9b4a7ab8ade144871fb2cef1b10309a6ab67b218671500c0fa5ece8952d2635061524be47a33e4fc06eb1409cc4c7bead4a0ba8007df2b0d475a4312f042cc6b75b3484b08099c208971a07a054b701c193cafb509120d89579e282b07fc6ce1bc55c10012ecf1399c910b827a4ddde8995848861a8caffed9a284b829de0bca22585024d4a2b5946c5385267e9052141a5e27ec2b75188195d7c693f8c64b4351f2bb3076d95db950905087bb14d87831618e9beb5583064fad4952eaac72f3a3079da32668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab6712c40b933d663ca9fcb3441c62477e3209795150c4da33c9fc13b0e421d23a9393a76728f55261b41c8dac98e48c24d91701fe6c719d8964318655a0f9bda8e1c876c04a1b729951f5111735b3558162c1e27e6a9c0ce0ba0953620d6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c098e07607648179121d2ab55b81ac018143724015aadd1b730c274a6ec281ef446a8468515519b1477492e5cb87e0962bd9216f9863bfafd025b0e00c58a709d200be9187b654fbc6f76b76092c1230526d051836ba580f90e368a4b201dccc9a3637c19799465e3685eaf51bba70610d88b6f08bc6179ca607241b62e54e94f97257838acee5a9375b347d9723466b6609330a071a3ff9d1acbeb4c41b0650616689005408bf8c292b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8167a2fec4d72cac2ffd844246eebabdac0c074e4f984433744e31d299faa389ceac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 30344d0732fee736428a73d85200691631752da1285f83dbb6fe91e28e171734a23671d1f4ef6c3946bccf8a4e1125f7b3e7fe573b69a7a0b8d1087c4fb3b6b53962e0c3fc1ad0a90ed96ef38b56f1cacaa428b3306c190985425f6ac32d885472d536a638195356a8b800b16a5af5db8b52da23780ea4e91c8ade09d521efb66af3e5c2435b2f91a486aa44636ff831c043948249d2d302ba900981a6d01ee3d442753f078a2bed76b0d805eb6e5302386ae5867eb71d302d8e4ff8b0fb1fd50c748aa9a0a313cb5774c8652154cc818b6c6ec44adc1bed7f8d5face8306d3ee04aad9f5c5767b790c3d83d37d817daa057020a95ce974270274bb4861dd98b944056f178c5e77835af65823cc779c647242770097eb426d905e5033d8ad7dbd272aef4849801bdb8afe41fae1a45604f6cd89e38775f095262bc72edd6032bb24fbb76010c443233c8df3ec594d30f58413935198880b227d791e06cfca2578ba405941618af7a7ba604bf2787366349e96c498b82c7121478e68bc632f9a02cae8f964c9fb4b7a7c2d2b1f9e45584b505c41c1af3d0f9c46448391506616f97ae657c5cbef42d47d5ba6fd99ca0a430b3ed5567aff41885e542950fce7b7e6a11be1d4ccd0156bede44904ced82160a89c5efa6dc0c360ef0905f4d21f1e6cda38e8422c30e3bcf966d476518fea22628f7b6bc84fcabfb908e203d05c731a7c59e76edd7f47b6f6f1be60ec1cfed497e4c5fb1957a1c02bd64c8523cd2e1e807ec604180cced79f5189473557fb7272c0772391e4f8e4fcf7774c1ff455f2817ffb83a4988d6f8a8cda9ebace4064f5e55d1f258f1a579374e4f2105b5e400f5d03e3d2462bf8a2fd5c64c740448e7823798cabc220f00484379b75561f01f6c911e253f0bec715fd6165a299acb7de62390b754899b76b5085ab75286178895b927e21b08a9c7f96febb4dfba433913da7473145939715d881459ef850b89bcdbd5833268a1b6dadfadde90378ce71f92e462ff402a5205af2b0fd2503159d803d20424ca6b5f2864aca6ebcc1ed24e3265ac46364d60aeb0bbef62342c +expected_result = pass +expected_shared_secret = 715519f07b29bbecfc0776e35417558e3bc50c76b8da6fd4c99391b7bc7873cf + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +private_key = d1d08267ab33fa3a0cca990d20543e59075f87e1b20953ca4b775515a07af10c6ecd7a5e299b69fe05c0939cb6fc789d94c762940925a1dbc9d7a33d42a2970b36a76f5869efd38b2a81b632ac1fe38a114c083496b5bb8b211a174695c29862633c283bcba5be7c2ece82b9d517c0a8099ee1bb1624838bba8b5b73a463e196098986130a84be1cb8080e643f3f4b08f1b84d02b10b932a3cd7a921a1f97ab8f38b099bac9df962ddeccaa1976be86a63b39c59511a07a29046ba6451a2d77f4c29070d9a6cc305ca9d9585010089ec435710452390c80704375458636921ac93e5294dab58040cf309a53ac808e82fc571aa09137ca8504fe2e71455d085f42ab98a9720a85138fea10cf996137e361d1861b7d346cab82bbfd9fc0100949e945279a4757804b29cab22090a8cc6c39495c44273bb0210e1495d139650ccc60097e77573884da44ace0c6755a8454dedabcdc92359ee73246b045f61da9ffa172a95a20315b688461050f052301f0b1700f6070b95218b583f026ba17be6111e0106dde5bae1314dbee2629d5cb291d396bb04cc48b92ecab20c476bc32f155b05964b49649d9e5a8f3f9bcb5a192cc8d9b3858a81e9ba89a9d7a88ec90838f862472c2f60a38d1b444edfd411f8b4c0e4f090c5f353f897cf704801422861879471482a956f591e16046ddedbbd68b5768b14001a335a676b75bff63ae7614b1bc03a04460768a12dd3c99ceaa6964db1ba11173711c7601fbb3fba511c0f63251567b51de163b83373cf02c0053516c152425e0c7adb018571160c0f4a47c026404c0802428c0a373c991ee5c4320ba566705af9490d6af3a53aca021ee11f53b361072688f46526184a23914991f3ac7ea28c20878990563cb96688707099465ff3b65e46280a15a11bf05672ecc7e31934da8226997ab2a9773a53059d3748295aa10b08d394b885944406401470056b645315198d2f42c18df155e053a63d147b436aa8502ca97833c0450bcc48851d82e21866a51dd7418f3c6ab231c7067a874028688469c326b5a49de1fa3c78b31410dbcd5b2572c8485393148da9f0c2475a69f1e96c610badd664c99895021f497c13111930880c02d9c8ad7a1309085826b4116f9a9cd841981f766944137de5587323dccfbba28366f86ae7a7481c054b2dbab86823b77eecbe7d9088a9ca882eb7aba5aa23c27209df4760e70b4876b709bfd225b0ea9644fbac9de01df90648a25b5fa9a48228872ec2cbaa09880100bc24f1414102d92a5a206399295333485f00c111ad49c0fbeb5f4149477e46075377967c310fb5231b9d6204bc877c31c524bd76b5edf23fb9b091ffa3bc2ec64423b02f673505d5c69dfe472d8df62f9775852b901000d84e4237aab4f32226272766234dda706fba5962e816a98586bc2a5bcdc1db80bd9b18bbc3c82d01cb1b67369f32741d50ca57a45c45667d5e5428824463c8a651afd95e995a4b860043cae74e265aaed3320414989a346a63f0f0842e59972a91bba62559422705ac6422d66098747a85737abeb01c00b4b90311081a17c6403726ca39e27c8d426845fb624a956c39bbbb404a8ef5073e37078ef535b9eb581783eba401243b02d750f5034d4a366c197994189846dbd82712663a0fa0beef5847622a904b04983b519955b717025c01d9e5b928d4b860cb0fbff76fbbc22b4761a5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b090aed1c9478a68ce883cc9b8960e8755485099912dd509e9804e33e86a12a75b53d42f0c784c6a73732a471e44900d41ec9c4c0b006910202b1b2dbebb65b5d7471f189faf194e642887c5631271649662f4b235829644198bf8e965d9728778a65405c4417eeb7ee25502618ccb0a0a226945adb0d73ffbd2ca47a5580d0803a56b3c3bc66e877ccf05741e29501bad787d8b588f97c20c8255687ed3aa1631122c387456088d1209c4a5475f61d12c2b60b1776244512a08807c09e7c7aaa3935125f235f8e872bc4356a21379bdb84a25b132f4449561e96bbf8776fab1c681d42575a1bfc0dac357653996d41aac4a9341196da05c49ba84a4cea37c818ba0f0408c8c9335616410b1d479ca035656119236ea9d6979366163791648088fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab955468734662471c953fa516b35b3a53053ff396b7e2798fe07a2ecd549d6c063fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = bd160d98b7f46bf964b76e201dbf59587476e0c3aea4209510772e34afc0790ea5f388fadc8e6bdf3510d4c2d1c3a00f3008866b239005beea93fc2c2f632bd6b30fd8ea0808e066778f310d4e0fa946b135feb33aa0a270e1bf3d2197891a4afac3fac4dafca110a08c120658113ec4caf8e5692b313f02726d8f5369790e0c3c10a7a4d852c8f3f6c7b1e064ae8ab171594cedb913cbc922cc7088aa99660b03905531adf3babed00fa57fcbbc4a9be2ef43ce6fffabb792a16f17cec3d09b16a6109c721057517b50195112a67296a14ab51ff7dd6645c07d1eed75b4ca6b61fb269cf3aa82b937c0ea39412f2900c56b9d7af897b255573c114d23e536880d8f432246b8563841d54b673fc0399dbecb010c535e722b1822de018928ca2657d40e6d934c20d833d8488b44944e2af6754c5bb2255576ad58388dd4051e29fa2e99c8dc289ab8c38162d2c0ed342a8050394c695b4b6c3aa81371ee37f47464337808eb02b8cc78e2f01ce983d43298fcb24ad3f19fb903cb582fefc9a0b966c429c99f1668fd9f56b56a40134da74dd505d6b16d812b1745b47f603c7dd8fd205612c6be07994ea7bc17842d601ab0d54b4983ab92ea8d2202dd69be38bdf0acb384e9555048da6ebad1b28888faa64d5d2104a833f18966cc4a3a30ce23ae37e7b19db70694a2f5198411894d6251b65e7dd3aaf22fd74c38fddf38f797fed4a6204c444fae952bacf6040696e6a0b9412e29779f74679cf4d44bdd9f2c2f154e2a093fa892f71fc65e9854ca64a225deacf54020af1bb62243540262d2cd8c3e74547608f82cd0af6cc1ca3329197958f9b0b64949fa57162afcfd5e087ef5c5e7b6916c316d6278fbeacb8b4cbc16566eaf17b569c8cd80e37afff1a7fb914431b25178e881cf1d0d66199d9080329694e03228457d5dc76e28f32cff849e5533baf254f08d15f223ae5c4c91b1bfbe28266ac99d8c0107d7c32b6df0b2397db2281b43cb609eb25c3f02ae6bf15b6d19ba0c56e878a07fe49ce56830a67b46b44441911c614ae9e491bcc0b99da7db92bb8d2ca38c65ae7a082add92 +expected_result = pass +expected_shared_secret = 5a4ba3737140bf227c0e618f74191b3de1c1b8e24b032036942de66a13ef5a91 + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +private_key = 17061bd1a9b682d6741e754ed82792d3dcc88d3c8e5cd88bed131bf12176af10c5b6d690be325c67ab7b05c67eaba3c3f58838897c5a11861dbf757f9937cbfb01a668c84f2a0ca7627497a4e4417331506cc28c68f550c9ac96eb2030585b306ba62f020281b8b59470f0b59a3c8036132556b381c7cb8d8c365912d2ad91d01442b534fb09bc9a692e5941b90342552207a8d099b0f628cd8acb5f3bea9d5985a050a28f69743f5c22392aa8b185272fa8d19969f5c0f45354eb18b961066305f183dc29891f4784dda37f8c9c058b500e1fa393c2d92f37175c8176cf4fdb746e377f0c97aec1d43da947c889269eba88951d925392225c5eecbe1146b255011236c34517c3b1cff1b91d17823ff4b2273ab1b276c0c89b87b086b3e0588b9ed14ff5e303d465744528388bfb90d42414b1529dda707d2ed515baebb05667580a52ad78a211a8cbc0c8f1274d23504f046e1b84813147255ecb6f18314ab1c3187b876dc97926cee74c00c956ad1341af66a4b89281d1fc2caa2620a806b7a03042c8d401527077ecb91c4fd12f62f0045498b1c43042cf103a9e73430a0c5298f55f4e5517f5e393197a5c9400705758c9a66307d263a5ddf72771857c29a97216a4aad7824e2dda2c3ae7c38bc851bd2c65ed584f789a342f4056f3da3315855c675557cb7b2177c3847b21a777b3b24e74572e1554285347b116a7210248f6307bca828369b8cec51bcca4b707e508c3baf21560b5450e4ac9968ac543485e21722a7f535f26216bd7378fdf28676feb7ede34aafd981a805729c11b4cf9ca7be46a3df96acc14cb4b6908be9a79ae6bd13980e6bd997a1dd8553a98b4569681ce78578330181ec7c1b466d1c226ba0c15a6bfeab52e80a118b0a3c5e9657910063cbc2675b5a724d1f867bf82abe2088e83d3ac0f55827f864b61ccc439906db818319e360fb0707cc0c6bbfca62c7c00b5a1a6341915941d6563acd410afb960c1d626dd7875047129a2b13750e3a6c491616de3b44b1888d2bb5b98e118c4aa6e2e386dc933b441067ec7e6b2bd730fce342c17720ab3d5b7154c8228376c399946f6089f4eaa70736726a20c6e2acc75ddc880fb015477d3ab44c36e047c4bedcba5e2d775628154eca695261b5825ba495f84c925f73c5e86b59fca1a535906c29b0546134469aa2fa9a273e987c50f2b5c1f0b52d79984246c653bcccab49c172a990a72d93ce02c2a9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f4715b977580345b13cb945ee374a980a3152e1690469c47f8310d02ca01dec8f1a149e6c1a1a4ff0496c18c8ebc67b79127195341b132947ba62a89871adc0c9b32d951acfe88334189aebf89991c9b73eb0b68e6c2aeaa1455aab124160179ebbcc40667ec7159d8991897cda76e31a8330793fdb035feffcc74e251993913c6aac99e5ecccf5f9289343989bab7640c9c2a9e2c622d0214cf9c696e803d9e119af0a90fba50199032dbf491fa5e260cce4b92b8c9892c8519ab23031d9c3c53c671a4008e8ba31b3d1bd4c9602f045b92e42040ffa00f441579b105562d507d6117a9f5b9fb6e50146ca47faa64165c84a3c9a77a70963e3a6a8a28b658998078cd91cd4599cbc21ca68d13395b907e395b581b490b3007af66cbbdb222d78973b7b69b37c77547669695c347deac03374c209fd163984f03f59a6ae8de53a169041c35c99a4c95f25a759ab6b2f0fda12e1744a85194ffa736be1d67d7977b32eb7ae6bc04220c8846f157aa7d05c12c02eb8d3053059ce8ecc34791953f00077a4e13c001a48c28500c025c4bcd11e5ff83ae9e31e0a6788ad70a71c1c0d5da418c6e6934fc959d70259b606c986c70348cb7cd11a46be201c474b819d8b54b538c78a06a9bcf905da7469d9c045686a3b38e345e64994cc0785fc12073ce961763074f4d2aaab6c059fb67c947889dde52c8ffa432c9171cd16133d337f10546d864b3cf3243b2f3097f3314976c183128aa1a11916e6365749910600e64d96b663b236c43339cf979c717c6b03056081d9ac4301722330e13cdb0a75de4a4099f7a615419c82e10c6eab027447a78303697d8089647263c0b39834986f8da41566dc254891bcf93014b4b33e2be203b4e2c67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791f7310c0531060051469ffcd2f88e3200bec6c721bca1fa4c9e7bf1773d7ccb19d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = a04e02caf38c63d95694ea94d21ac94fb8439fbf40a4b4ad80642bdfb8cb31c619f2eeb2005a0f0b75c4e07cdc75fbc4f688bc66d1deb0c0c88b19f12d4b5489a04dc4fc98557f97f1181d08e88ecdc16d15462ce5a532c7c3ced03ea2c35e9c7d7b0f4ceca12c3915e252ed94d26e2595ba49444cd22ea89436dd6e77e7ab41c616776af6469266cb500ce53607d1c1c7d6c6900c98a2bfce54877eabafc3b40d09e6cde906d9c86f6e75e80e29c3630184eda59e5fbc7699a2f46135fafbb606dfd6b4375c57864737ecb1ee0acd6ada573d2315885e8dca584263253a07daa6f120bcb35c7dd366b207901aa978756d34c54a0737a0869fd0a0e1167bc4895670ab0cdfbff599d43a34ef1a9eaf8761f98fcf6cc46dab816793f6c4afa2f62f654db94f1eda6539ec7bf7b7173e2de335a32c458ba83098533eafc44093f4297fd1994b809a3e6db0820307eeb75a93012db0932a46229fe025f6fc2fb50b9888ba4f52e628f3a66025df605ac60ff58025972e45f75cd8828b7fd8d338617e3221dbe9f9cc4bab1ccbf2bc1ac0b7c603d15f6268956b18bbe3a9a3fbae369144cc89cdf02896e053ebad7ffd16096a8772dc9c5c1bf29b1a1e3f76d09cc2e5b4324e551a7d097c726c26dee259ca0de91676a20b577b12d02a127a81dcaf489ec1af1eafb246b5f36000f77f57989f4e187862ae403b0e6ebbba782988b3a1151f7d3bad63c4f217f51a351474ea782fa006134469d2d87459ab774eae21823e5fe6a3e400b2da3e42af4f2d47dedff032b11576729e9f6c8f7908b444e788575aff60bfe2c836d8b3db9ebe5cd01e50855ea26017eb9a0590668cc0f1d863961678f2b29e087b42df2a4067d711db59f78fb97b393db0abe343e151ffdde87a9a0d1f5d401e1994d0a37049285ec5eed3ac635163e3c4080104c76ab2f452f20cdb37785ce1ce5aa33f9ca4f599610c4afea560b0779cf0c3b1d0ead1fd8a6f352c6b1ed314d13a5e85abeba7987a0624a9e7a6e9e1c711c88cc2925c853cd14971e67a8977e67e649a975924f63c8784d9f3ee80ad4fc6e1541d38ee48 +expected_result = pass +expected_shared_secret = 87528a4a961de06d5856004eba20a44590a1bd88318fcd1ae1dbfbfd41f152b0 + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +private_key = 96d7a99c7bc70e97783a8b4e9e6c33b02564b94918979154f6117e8edca085a680ed1a205a91a64d62032e0bac503717b040cb5aa25da6c96981069a516336ea5438d97315c4971c3808357ef20c7a9540ba27509ab9410c2a0003c81b0a072f1187239c772829baa0892c22fdd8baf62960fba2118ed5c000d7486dd05e9b252726804078a08a672c12fea5798418cc02c2c8d475833b4ca99906a9b9d91e0c2aa362fbb5962a2ad75a64edabb6f12c1fdd0b7639732c0a2190af04b35409125a3851b4b53ee7591a559986d7f8bab94baacccac6c06c82fdd166f31404da49ad4213c4c7f64941c1a12460abcdb72eb4f6005792cbe2b11707ac56ba54737f082e940004a2a0a57a650e56a45498674df03165500558bfb2a63a9526b0088736c710b2938d7b7a2347277358d8b842ac9127a8bae5cb02a25206f2522bfc0887bec9b13fa170a5f436abc0b3027796fd4aabd3f6054368903de3119b72655bbb30bc4958ef471ce57580cb96b9d875a3cff34b1c8492c412a272db89590cc717006931589e5d546145413a78b7607f38066ab83f8701b874689b5894989460c2fbb108739333ad3928110419c922ade0a21ee5106d7171087d5994951303a4760a99f6ccd75892840ca8947651637cb39266abd80584fd1a197b22b6fea5c50ac1640026bd0e2810a2591440901ece073f29b7c0b2c40f42d71d26997c6db26e77ea3393faa75249030bd0638ec89892fb456e95c1aad8887f00ca3dd704eef8c26560b4caa39874e4271c185ef06ccdf1944fc838a163fb8545f32b107517bca29026878902830524bb51c77ca5b2274aec9106621701664a4eac03268fe109427b2d57f976fbb75a4b39a8d8f663264328ddec9dad23ab87809ef87a16c1b25addf3c308714f57c9489f25a4a7a414c279b7aae576be7c95b2761e242b45b174065d529b480b019cb19c80185a94d6046be2aa95a7c03bf4933fe65765a8cf60577c49c5132865b0f5b265e86543d24a20508157196c5d0bb91b5b247bc200a2cb32215571395e216739b69f69d26905015bbf732aafd63675b12c65156e2972584323c917fc24681b6168eca204b8210bb3029e05cfb2e08d479b413d987152a0203f0ccafc45625647b57e3796ac904643c73e9cd26653600209a62bc6498de68223c990672470c2a2b77289f41f5e07ac7320500a7c30a9e99544f7837dab6e7b7b7652751457d96e23080432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b576a242131aca3cc9c08833304dba85c07c212951af1303e91206f4a54c45e9ccaa1e96fb07bc27707311aa2a1438a9ce7355dc5861592a4cdfaa13e66245ebe67610de4875b57181e118930e671b34104a38859d203ac064b417a30aa8d23af7c5c732f4c57e8359f0b698de6320e0940a4754904bae082ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ad9109146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ed52e2438b6132400f3bc06f00c71b6669f02735229b9b1a5b580cf271003b498a6c6826d553cc736a19a6cafe69058ae8717b91842d92bbdeda0670118116b719264465e61d86b975a843a5c62a056b9af8a7cd402a747a6b758da977b12214608cea52540dd390135e28e6160468c97b713826dbaf27aec20b34e07aad340351a64223068318113c5148861aaec535d15368a6b096b559f57b2842713c44d46bf001477ca0c92bb47c5c502b4e5f22e7aa087c26bbb36d9acb0712af2fc7c09e55f1fb71238e33d05d41d186790ad725afef46173134620656449917d3e52320c8542e5d725ece72390f637af286a8457165f5622608c0813da9c78e83334005732246091aa5877e7ae460c18ba856d030a856a749d2740689ef036fa936ff3e25dedc97a72f539b3a32f286a02b79472f28089a6b4b9b42134b6ab252f377e819c233a16be6361a59b4a9d52aa18c18263fec2602ea9b8e9164bca2946a31a892093af891a3369a01e169594d0e50fd5b3b144405ba1139a8d167564943530a26522f3216517144937cb5a14b98300a03d6bb2b8c13eb23355590cb5989a4e26f242ed7b977a36c65e768f21e9417f3180c304009394cef9bb74fe1306337b7100938260c68dfa7910df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723152c13a9a4dfbade0f98e8a5136358f69c93f0722addc008952cf72e1bf350b1b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = 707921441f685b510f6bb24a1dd8cc65cce11d5ec420667a9455c90991892b0a707ae2d3e1bfd2371927de187f9fe0af99a69916c5e43beee042bb17e88406e6d54de5775b92588124872ebd3ceab5ec658a593514a2c669ff597dec7c1a00c3988f258c6461be0c3bcee5a68328586325cfadb60b9f9ee4824a9b7393116f691b7bd39f86edac4aea70b27c66d6571b3f7d7ff867476b69d8f10158cb013b379d5ee02710948161359c5d0434aa6ca35b82c0d0c23597e7764edbaea53943832207f3f403c40af1afa2af4972cbc91b413a89c0d6ef9432b733cca2ba1f1f6825f74a8986c1224085a81dbecd755057983116241941ddf76b4130095d01787e047711c8cf246c03e1d8c69e5f212415261256d1e232d6711a7d7db344fdd7380f20433a30f60799f39ecedadecd457db4ede782c281dca56a65723af91e57eed98bb1c7d2e4d3f5743e6fb7d1c76dc1225ae2c052e48c14a371699658c66e1b7f074c5335b2b933f259ca993470554cea8c183abfbee8f7d03e16722d8fc82ced63d23f27c3197ee14d71317aed8af580721847ea01af787831e3519e9372254878af3891880ef159992966e5892f4908bfd341cd3d358931c7693bea197877eae3d6dce7c7b5697f504a0bbfe0778dbc8fc55672acf7ef4e061d66856eecd79e8a8e45053b47c42e991516d1a16c20787ee76d855038ef45d3ee412dcc91a68ab1c2c844eb0c1682cf828d9e8e083a1dd0f76e7769eb56e447f8ff9de176e111e76569afedeb62bd77e448cdd24f5199aee96e416a9f7d7497017bf9204cf11eed2d29be791e50b6eb2892ff8cf232db026faeb137dc69fff3889df9cef163268608df15a3fd5280651c6376502e693410d8464b45974b3e6e3d160a5034d13e50bca4a67a189cdfcf955c7f4e10abb54b95123292f33dec86f86735440a18c5b2079a941549e3289047c113247861562a58fb1aadebd01c6249be461fa05af00e22c6aa0d75d4ee41d0dd174c6ca05eeb4fd0b8a904978e632cd2c6d4771d04a4952b3fbff04e86e1de51f11e53e180f67c0faac071dbd42e93b044823aef +expected_result = pass +expected_shared_secret = 3652a13e36459a324958a2c45328fe4ca6163ba833400e643b0a6e51bbc594fe + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +private_key = f3d4a8bba18dcb278d29b99dffecb79ac90496826fa0351f37495ef081b1e0a64b680b95f136caeb851aa2d58905f06d67220eb4834260140be1ca248adc2d78a05e4d41815405be653b1585a78e64cb52e4a656eee07f2d4a39ca50894fc02916f0a86c6939b3514e446cbfa0e05cefd2cd26965260cb967a09485e2cc8dd6c0d7c452f281005e10a62b047217864055c78bf2de7208b92b0e0a01e15315bafac07ed3c1a748a1c8bc6c81ae21afb04ba76017a1bc920fe546c949235ca61b37a3612506350c7eb5202f267afe01350f979ea679f21420c7eaa4818e5180b258edb390a21588f0362647632a00d150fdc540bfa785ea2680e5e90a8d58962cfca3da824138ca3c8e7d448d5080895f85625372028a5176932991779030ae8c04e328e01f1574d1c4ad70acd2b197f9da55d01a7c8920914896584c9fa8a6c9183b05319e2395464893c491a34453451295681b9e15908d16986a80016c0bf2153bc4b18cf59300d45a00ade932ab816c5cf10cd72a4b1a3f831ace60f0116594b0cb96b8b1615099e92887ffa7744a3e769e6bb6072b70385fc0bd30000273291b101cb1bd77ea7abb5bd7a53f70a806419022d873360f96a636b1d0d59257280c94620335603a3b8a73d85a1a0ed709680e04c5aa233fdd67c8ac5b20ed115fd2c892a6579c308bc9a693d3376338c64b855169246a98428e49af4a24b8d53cb4ee5be29112001e103e7589937618556221910401d0471c12b6743a6b2b3c701a72a6a859d933eb7833a423b5622c02d078b6ac1a2582c30cf208895e76b4b226cc547cb1dd6e376b34199534aa103b417cad5a67862531265c28506051ef180b9e67b3ea1a40f598e78908a9e047961b5908501417f12667b0a7a873a856c1ba921b5cd4d61265936542ba1ba0dd619754119fb9c91c5951b9fdc1945f32f02c2b0c7c8c20ad3805b13cb861ac28634828c31595ab163c343aabf1351738514189232369b0c92582555111a35d074ebfa6aa81333890a39b370bff7bb7dc6384000274575083c32bc004c2a88c5a82a38fb682ca00593f72487f3403702c33a090559a1773744077304007ce9af65672c5f221ca99685b84abb134800f5616b734c184107c8c5892c437b8aa3d0882929b8dbe394c1680e33dc2c706c8db227c292fb0a89a8a29261bde4fc1dc12663e8ac502e473e58d6206a90602ed87675287ae301d0ae94ca923ac8672a031b5840de90121b72c58310cd924c12787428adb9b09ea0b8a2226b84e9b5cbc2930122b5027c70a694238f78c8381078393178c936b8de4c204b4a31f9f72bdde751cdd0b31b2c840752181d838ad37c637cfc7584f37686fb3a31020a81db35c5f7af49071470b9c468dccd7c258780cbaece579819d8c766e873b6468718f60da09539fb7a34de11a70c45ad71918925467d8807cf8788318fd010a6a57ac83473d332bb9f2411cffbc7eac87cb7c9b1fd456dcf74896422513ae691cac20d03172728b11d5ecb9b9c8b520bc628eb5724e1b415fb8b99b519c1700537c2a22a2fe52e45a748ad5b7f4366b33b5a2cd8192f9ea406e181b4ba47459aa08033498b6c1cab1fa0327df5afc5a87f0806c6b26159886b40b3c8b068a7208dd12a7c150a679cbadf3b27457883231a8c351c04640099efb363bc962262d9570ff8b425d206227175de94c5cc010d9a3277e2c0055d84475501877d608156868708d5c725357b9df9b47e4c9d7819c310900df9926c0ef230999aa2b420860a6b7fdd020fe0345e8d539c5c839c3c11a270f360e2f93fb61507fd86442379029737823bdc445f05a9ad3c7e29804068fa96035a95459509b53c426e9188a0f016e8857182119ae936656d60072549557891c4fe0278791b58e1d0bcc4b322ab249865650be6946f319c7f0bf58c72b819b79c1b78982b2e24a8b15a1c166cbd3feb06eda478fab90ce7b16935bc4880f78f7d2a80b5b41095a53f19f46ccdb84bfbba460d1c33eb923eb56024dd437cc256a610920a650bbcd3f54b8ed8b1b0814e6f4acf94617e2b68735210bd263597195a6b59864c21e371c1d947f6357a4e064fae992dae617500794af82a5911c15dac3416ffb21ba5815b79a79c30ba72b66bb5d8d2800e581579219b2f0688d87a1346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f97e5b18cff525ef46fd8a6aa6e5e4b8d953fe1e67b5771d1b99ff18e754553beaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = 568cfddad6b6008a4eb850b6d5b35083bc298a468567658a73789915ad9f04631201c39bf6a2b4ebf403c67ce5f110cc92385f93be982591a806fb97a02bc0a7125242faf363a995f4ad0bd6a18fd0e01e832993665e7873473fdce1d4eaf2bc972ccd0debc6dbac91db1e35a12185f26455505095b47e6bc92eb110bd93dc609ed7b85172b6f81a565b77d7d83efd1c3ff7f7a0060ec9ff9cbae48b6a295dd37abc2bba98a94d3d5323e30cb1dfcd1031a5890e8b7545e11c79ec038521f053e6e071c0393b9800383dfd761df12217159f53d4530d26f0ddf8f2f160ddd012e66f733eaa3252e471c061a4b11f5f18576355b8a3c9cc4f8a513d3c7f6a4910fa7fa9351a0dd4bc6772df2ffd6606940d39dc04c46e22a4975c3e4dc2d468025d220d3db4eeb2937a5e5c7840fbfe1295ff9dc4083594bf697afcc8df13a8294f3bee2bc764bf6db52cb72bdf37d4b591c6fd63c93cef89e8cd5e4846f6808d85a00bb69dce35198c2970383f2bff0daf4ee5c807c6d2a3eb33ff61ab871c58932f548bbce5d12fec74ac14b70c948f6011618d067ee17ceab188cbece4543058ac13b16ec58564aaad49816f9a6f2b6f1f58ae891b22bfc37a40077b2f9a73292355edd718703690c48675837fe8caff5cb453e4e4a58dcfcec3aec9eadb0e1c2c9c486d4adeb5be3528e0084326e94a0c847a2e4b55ffb97be791d5ab6fd51f389aabaf637433679781b8874d602aeb40a239814236ebd501ca60c8b6366bcbdfccb9c8496ed05bfe75372d6d44cac9601644c47b93f21fe6087246bbb31f226eedb520833650a77c8232b0f5667bfd28548be72ce7b091ab562705f1e53b3ba27bafab531b490df1317e28b62be14e208f24e647504aec816d11990341920f6eb6a4efc399d1cd97bc20c1f7da4c188f0754ac38e6abd40828f9d719c9a8215207fce4f620a02c972bf0ac48bff55931f3a0ae02f0d4d080cc92afcaf634f39ba847bd4d148f712ed4825f43f06bce1ab6a7dab906c3b05c7573f0111dc8cd9e0754d7c3f00c936ad3eadc1d438a0d3a79aa367da7c68a29c38d0adbf261 +expected_result = pass +expected_shared_secret = c07d965e4a87e89e9fd5db44cdf225b20157a6842e2862ecb4f72d8aac933c2b + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +private_key = d21b758292aa9a363fd0cc835cd370b7c23acc51348efa05e2ec1e6cc6aa13e81f40da39dea5bd71836aaf33196909cc13005c5ad26b75b6b0f4f233268b710277acfe0a3325e384d58abb7ccc0677258dc269a1f312b33f889826061abc5a7cab01cf7d6733a86089dab2c01c8214e21b0237eb4f0b446e083bae64ec26eeca1bbf8b77042226ce478fb44c5aca031935fc9478c401a92abd659c8d3cc142ae72943c669f265ab9d9d6283d8badfda1ad3d533895630dc31559578cb89aa6153563be7366909f949be80b5f4eb12aa49c6400a298a60c00a2fa36b886437223bb55b81598912213e188a210c9b6b49b329310a990c44f96ad8ed42fbdb31200521c5756c1d500a4f9b7c3310827e5c9952b9972e7328c38c668d1d1bb0f199d8b917acf7047278245a6d06d2d8bb800643210f7a1373667c9450447f86e0f067f57c16469409cbbe77abdb65f652b2c33456b1e87428d0abdae211436b46a035b630169ae1f044adf26564841240a3a956fa7ba0b931baed47c93364b6ca8273a195e75fca7bd52451e5c92c78b16c9f19bbe431ab8f26ac3dc797d96793e289882585edb1a7a39c51a60242e330401f0d3b1d0dc29000287d2569139e05d0816421bf03e509278e79ba645c66602592429799d962a6e02a61682b410b38963d0f8363ce43f08759cc987b5986ab366a87e05c430c78281c72864948282d3ca682e42bf42c57c91fb09c2b596b33083289b5a0b39c997d6b585653fbd9122f6123308177bf6d6ca614255989ca6451783e607b06bbb0533ac5634722a267733d67747c8447366587f6be662daa3bf86d078f946070971a1e823c4f0a919f329cf584317b3d9a468c13b5d398c33592272175fbe27bd7a30ce0f0284e5f380ae4947d5170c67b3ac0ed955c81a9ebd5845aa38659f186756cb94d41698b3e1387bccc8eb03186e34bcdd0532e775749ea928c8eb886ee0bcbf204e62b050b199807d216428d48ebaa108e3ea9783a340c6803ba1b206e5fa107982534c33cf9b757af7459ee86a1fed072530d31c411741718b8bb977b60242ba45437f8209871cc61043d28bba4a2b4ed1c19f1369c6d7578ada06533b0dd8ab5afbb3bdc5b601ff108031d017b3d89aa253c90c7a4a7e368d528773b62c6aa38046de9b6651cb1f5c353a1f2c99a3e7bbf1679357219417c10b5c1c60348c5c22424807903ea4e9c685aa5b53da5ff92034c7c15a51777d7a637529a274e767539bd68f2b0281a8e13c08210f17ea7168b210830b0d07bb61e22b2f87323c8debc3c97a399de71590a23806f1903ce109ab804c5657290407463ae5bbe24c7fa62230c83288eab45edbc28248d89890491b32ec4d214263557b053f0642f327c78d3565df61796376a6e04a1d068198125ca6826a4c34e65e30a7946deabddd3062178253847c37f92a9cd1a749f1d12fab1cbc0017b468426d8bcc26422cc85e97199420a9367000e7f52e17b4bd5dbb6400bc42182cced4c564ac160d2932ad801650cdf29ca854a0b2d8918a3a2320c5915c1b37e6b3b0f08280fde7c6f2543d2c27728dfc8eef776ba012860ed55906a3a28ca88d5550b540538272c01ea0f83b78465ab8f062df740da6d31ed95a53b5ab8301b79d8ec6a5fc503bb0a6b57ec99085da37b3262843017f9e572b15c7b8aec40ef66755a1ac91856a8d0c8a0b1572a676b8ac671908c210c82c5900abf4696e2c73ebf3ccc4b76df3f74b930977fd616d31f48248c578a8d63b14bb48fe5c259f9734760944ae78164ceb699b1623ee648330019d79b49b650a33b841622b0061a4b79331a03da78b1b70a3901f42159bb4bf7e1512fe8483eff80e3e241bd94aa8740862a3800313b0c160a1302122951b620255d6c8beb52c7aa2ca1fe1858bb60b6e6077a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6d0058bf5477d358b630b42daf131ecae24e7f33960841415585101de67d96e2349962685fab259c312d175326268c807e036836f75d43e61cc65274e42b37d874b2c989044dec8aef59a2663047d8f6a0eef1649d7150b20230cc279baaac5e2a30c84bb1bb6475bd2d4a201863ad207674f4dc25a3c07cf9fb25b1d83b9cd3942b50c423d0b31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b247b5c67fa6e0ff374f691540fff0b4d14d4ed8a8a8c48b14b2a35facb413a5ee60f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 357e8eb402ee123bafb911311cc4d2400ec533c40ffd581c4dd737bcadf9cc3ac06e694c774926de1840ff94b42fb313978f5000930f5e2b8ffa17785e28d9450aa02c8461ed2432bc73b6a9250547aaa1481e86f34d0a82c4b5ba0911414185b08ddccac3a66b175a122cfcf5c171a89ff088d35ff2ecd044ae7f99ca8eb4b446987a5ab6874737281ffbaeaeb84f868ab2a94e5c0f53c05844047845d33792752ca59ee9723cf3ce7ae02ded0ed4348211d1fa1af4d356f272ed65f3edd4698cebded1167089e7ee17277fe47b16ffd45ce9a7feaf0dc6fc983893648e2a2a6ab5d392b61859d657b3fff61b263f40e189f42940a381e34c20eecd8a1d3a347641bb386bd2b8bec1390a62c8d3c139411daf513b16389b85a8e3effcd5a4d54eb906a36603be4c68de357f5d59a9d8fd11248504928722178aec21c4e5b4a824c52a34e1ff067818eb064ae899b5dec021f53ad07bdde56caa10fd0e1ba32dae976eaa6907259c5ea1ff6270b5d8267d29fbface8dfe1848300e60097b1ecdff39ed0be6845a74d4d271dd74c5df7e513108b84658a5869165642bfa67852090de4bc47e4c9ac130b3eae354c191d108d9a0e9393c9a8925bfeb22d00a1d74819d08cbd16b4af03323d0311c507a350b0a48b0ecb6fde5076a0ab1d9a65aceac7e3a6674b9ab87201d6288c65fc1a15efabd9f6e6bfcd5ca40140a5dde99537026b2a293188a9b181f0f1ecc4b0bbdf46056133ea4eb884569827dc2ad25a298dbf9d701b2087c68badecb86c8cedbff6f4c2ee3f20f1b8b7aa1e0935654dec99fa31ef627d24a3a48095157d037d7716fc1ceccdc705786b7143c11272060b666a7b723aa290ec11e95381db116bde516b977f55c26f35892fa081f323d3e02238f42a3fdcbb7e429bdece8bd51c02ffa135baf406149a471599f24bfc7c7e26acb6489be9d40abafe94c2746f0ce1dd3dd05153aac61926e4d6fb3fd85fa019cad88d67b9b2a408bacea9712fe33951bf8f7735ac4935bfb8cc9750b209e993350581aeee54e544d383d350de3ae5fbbdfff030bf728a4f970ba25aac703 +expected_result = pass +expected_shared_secret = a502041eee317af1e9e6f9a9c12cc98415b358ff179d4d64ba5b7463a1f33b0d + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +private_key = 7d926fb223c21d99084c7a171b6575cc04a2d43349519033fe9a24fa8213c5308774e9b41ba51e4347943d2bb1f32517ab6c5444d97e0840821d2ccec62bb44bdabc9fc22c8aebb96c49ca966ab9949b44eaa196682148adacc20737b85c120bd662546ec98d3221589f3a98dff6a531789a56a4337e2b5f6237caca4b3bbcd756749524ba16a0e4aa9d5bc5090117c342b03335bc01e9dc1ee8e560b90b43cca0bcec177b86810dab7b179a67a56aea2e99b69783a629e08cc4ed4950552b53cb29a82ac68a1bd896262740954256315898c5c58cbba58c7c7173f83bcacbc73067e44a5e72c054d05ef40a9b5304cb4c210798556bad251c11f2a726d3a1eccb8863405e2ec3274285bae1e196a4a26bb7d80888a53ce87641e583600bf148124806417c08e9c76c620536f37940322299edf0caa3b46ec3e05304bc354239625da3293905cd59d666edbb3ffc40428b0347979244ad55237d4c7334e477141cabe315cbbebcc2cb2ba10a48834d83163d937a234c4215ccaaaf1ca13180a1a8f1aa17362635da8967b47c81a172ff3171871453877b89e3ab70b2b43eba3683da73b0549290ca551b74d52343950f97345685b602c9d7566aa394f6707c335954051c0753c1b482514af5bcc61b65cb36896f38b46c5dda7fc2d536035c70f905077d299e7686b75ea5b5beba5739ac4fd0d84d6f7a08dca071b3f43611f48047c7612d638a6af602ff069dedd2379f519b819c369a0ab216543146e83cf654c22241810b437ddcb67629d20eb61086a17c42706460962c15fc0aaec5c5651dd7b9f53b3f7e85c70fd09f14bbb6a6b3213ca6c6d2bc46b13024b6593bfed9ba6c9740b655ac70c33f17b639fa1897d40cad4e98316e457b5027343b4b8d3e20ac082b0001532558baafb43ba273c03ccc36bd17d039d12c316668c33f15cf5e3269da7519d950c19ed35ac1894255019233057bb0417ddf8a7547a93d06f6127e717e0abab754783560c81a782a1805fb55b27c10a2c014230bbfbb808f6f973be9195d2fb5459a19265d0a93d423c8340a4ac1a4cb65b2caaac903647bc98ed95fa3d30d9fbc979dd7cd223a3694b874c8272103685e3bbbb8888117d53abc7667b4eb158a34953147354f6a5714aab10aac07299c3038fedc9b0d3553734401be62862ca82277f57f1e6225c5206a86e175ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae5b1b521c6af59c721ea23ee2ab0ea2e451a8831a82d098e924604d6b02e151bc43e761c2324368a643ea23bce9fcc7e2502285119343603a4cd5bd444798fdab21d5369f4c73477e3891aab51e1b11cc55b3ab67cbbfd5f141715a9ae4681cb0f0391abcbb48ac63c8a707677650aab59c09b43dfae8653d887a6c2c0664096e551929fc0a00167429ece069f0aa266c542d28db4a42250fbff86aeca6a709c9a25f384effc74c0c7b32b4a616ef2a140a8c96c8b56e61f32963505775658b6c81cb40c2b99e43bd8fb8a8459a73d8d083ac178225461e83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91a7250499891698553bcb9d0848abd391afd195cf39a6213a078161d7ad1aa5b28b1c442f6ab732fc14dfc085f2a6475d4bc8f897a7c1d3b3e0c1203aecc5d5a8287e34c6e3f2a920ec8065644a373453cfd796a58c03b7e241bff2986b3c6c6ce4064db18137862d716c54c154a7e294b218bb1df2d76f8f36847288c76ae21e1967719ac92aea8b8e50706ed8cb06492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4626f29fe843623a55c02b1a0250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad196098b1a1383ae99f2ba6384a1c39c69350fe22437c1c00a651aa0932a771e09e4efc1abb893639f1340ca76a8cbc4c605257e14969d83cac02d131dd4273ac467b6db186e9086548224a4a1526f769a90c93101e26a2c1112744844b0584343fc9b35320b841961fa55016c9cb271570bdfc501d68f9557a920db4920d15e2bea64a6aad743eeac97560bb024c70c099608e55d351fd1784673635aa1b26b9248528d069d031658eb2c559876a7fe6adca630e2f2589de2aba5fc24528a982e2e5ce88a73b80121789522f63602ff0340f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9928e49b73bae3b0285bbe1676eb6fad2641e7354e4c0a4feb0b74bb16708b01351b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = 563633a1c79ba64bf677c7ed45613705e7036ad4df441656581c9e68855d25c7a5080070db9debe4e503fa6bf3642d89cb52d5780ec1fb4eaafca477d1e575ffc2d16a73d4a24ada0b16f4fc6fb4db8be6cf5cfd503525ff0840a12473f4a52fa6a9d123177063dfa959ed7f4d4a17d2ce765ce65e6001131bbbbeeabb17059b92bc08b341d9f83a81b29c7b112336e6dfc263590a58abb08face7a7052598b871229b7c5df6a35599a674f97ba24da3471461e609ac76df16fe2496f4bca906133b14b72932ec5b53aadf3d1e0b9c7ff4426ce55626a45e794f1948d935000801f862ed2e7b4e05cd978a360184a48f2e32d5d58f5ae39273f8a24849585f19f3448dea38aa445e37db97a35dd384d1c13689a30421404ba60933f0f3ab4e2e3792f5dcf35fd780f9a113f29b4059312fae64df783df2d4c92835674169cd81d8805a44a3e04b7eb38eb35373831bcece0c56d41c662a0085dab366f52d336230c403f3bbacf23136176058f80115e29fb5e1207622eb6b57a14705417f40fb7916ed6ee40697f67d61fb19f356a5e2f45f0e64d42e0272d112106c531bf4b28f3763f2416f386a2aea3b44e2b4d25951f3723d58d3b1b833c3e573849d55e80716edbb41bb2a0469f160ad070064338c4295b1026f116c155f12aa11cace93bc57d2ba955f19ceb1db3c047380fb77be6c289c35284ece26df6a6e8cdf31a0065bfbfbea7c6fe81348e126950537c44521c835773036f8a7fb2d6632025ac66229c8e687a35c1efe6c59effa7b724df25425ca46e56f95ac36c09eafc00903ee3b821bcef0716b6da4258c544d28478add62025dbc7841abce4291fe8d6c4b58b97ca89f80887078702f4e8f2c823a07386c82086bb72ac8576cf6abbdb61cd195f21f89c842fc0cf8d2564b8c17233a20a048f0266eb658f0aaece01f2677de0c505cf7f07960f174fb32914c25deb4a5287187ed72685a04c9133e4da01e3205dc60fb1ef8bd6ae856244c93049f9a5fe744155f997af16a389859fe98ccfdddb421046bae0f47d91c6392e9a8b0bff226a64dda4d42ad1a443b904fdea5 +expected_result = pass +expected_shared_secret = a354e870cd600e5a5951aad3491c31a80b0545c1662f830d7f0b6d144ed3733b + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +private_key = b563c9c846ca91b6cbb3e138f43c9d8d647d22146889138a615670caf738419b5b67e6c837cc9a15545f33c4723e551428877a4e933bdde9673c5c660b2a64340a927126a56a48660b9396d457b8bb1516ddf8c275753e234590c607be27c81e14d5411c17488c1aa1bf42c74dc4a06b538ea5e9991819a93e6a6ef8f28ceae91fdbe27e6407178f563f7fe272d62746c9228f4ff510d46c1c559644fb3c31c767a8a5ec43f6610488f793328ab819a905d1096645ac1d3c8c49703065bca4a4bf7a16edb2a7605c53b8d0bbe26a0ae4d50eeb4c71df764344184d88c8916952151f18b48d68383e2070e5e57e75c602a48b34c5c4664d7c7ffcc3a6172837b36caf679b40a409761b089ef3ac2f3895969ba9322a074da98b00d29061d08a77cbac871b059179172b9a0a12ebd424d8a2619f94639e28a19cc38b020b30ae00110eab53c5e38516c320e507a3ddb338f3d4bb264157fa452a8a77a79b35a4b25444d7ba020d2aac98c797bd64495c401f1d658da12a9acba8179d6136421197b3c1a4378920b4ec8052568e2c2c580dc08a9fca7d7fd02cebaa91e8d892ea3b23ee3c5c95d037255ca685b62399ccbfe6c88e6c426df43c4e948968ddb3c9aa8a548d7a55c887c211bc50a0870d2c1b00a9383e233b9b1809ca1911b4abd78e2fa23310063d80cb6dd4896adf68829f40c97828c401204d501a6c0f571a48a15d62479e545abec163152b28340f5a077a9c5eca95bb71d256852a6a0b38ae20c3be667cab7a17001014abbdd8c205512f4b546364f6072971a88eba00a2789b34e7a1578909d7921a421cad8f590180ac64637224604166e52233ddc520d5b801349912a5ccc0ac3ba0f5b25b6b6242ed71731afc69597b635f7ac835210947da60b4c6685245bb17f34dab876e553c12fc6619e34237790704881c95f792a5a0070d69e747512218bf99866e417b5bec3c7b664163c7aec73867cddbcc3f3821ed6a92e50119591a667be609a09ba7a7daa4cc0017a270bf568a3a7c373e1a8883057aabf71753d599ca10a13a94659faa71c2694118920690ad71147f77b2fb32553b02b45153901b5951ae055f75a270a6f1b4d37cbb975b979278aff301470513b66f58817e6a5b2ed17891f24a84950be275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb89267f12daea09828f143cd6c7c133a38ce82788a6bb88126956f30943169b2e4a18357e43262d6350b07651a6b2b2b227436405ecb5655e5892ab1a0ce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8fde25fd8aa691a95ccc7da9df35393213322f50a61ad4113c094cdaa568b1f43517692c4918c2590a221fbc0a313d2b4321b9e1a973492bb519c010ced1c590f0a61799832c15012e04550edc12414f4cb7c32ac3a1bace2f9250caca0d027bfe238344e278d6509796155386c1ca904c34727f0772c12b66c2016cd933053106fb4a308afc2619f8a3ec5843bc2c64af8d71f86b6836ac3941022a965bca96de03a5982a8bd7730141b4232610cacb6684db89eb1b55456aace6df449ad5b7964cb4a888148d472ae45196e8096a87b014fb5954719e82d8ec33c285323c7fb4dc2eb768259696b41c489ccb08d8665fef6a7a14ab69dc3a72690b5480c1ccb2cb70d3ac37e4b2e00ba7111905fc6d53f0519c44877c9cb1b54abf3106d90424c6a39dfcb6e6c3b80d96a1dbef922aa762d5433485822b1f28c8776305018023cb3328b9200728d082260ccb07b3241b7c86f90f91f18a582aaba4003f9b8c3a468818619a57a2ee0d636db09762e634400305e4495b49f927091773016c72196e29b2e20034c854608f54d1c7506a6b89f8d1201bf659a53f7c16dc671bc65089de9774ce4b52543a1882c12773bc7cf00b746c5b6ed5026f7e30bcb3cb60a091091c2ac85f816d377167801c47e951b18e239c005bb9612bb03262a6c21306749a60deca6b47b22fd7c7ed472aa3e8b9dca5150c4d3209ae02eb72783594b0c713509410a01de44245258790058ba90ca08cda4c45fa6867b038c7eb99d0b026320070b1a18ace2ca6fed80284d094b72881232144f6422a896d67505e40106958c81946a86e19f153712ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0f5de62d662f480d4ed8ba235b4aaa4bfff19edebbbfbd96e5a9b7c4e89365c3ed8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = 87e9105293d63aeb83d6098dcfdd4be921d9c030090d76a0cef0350413d732b37eebca334490269c3a40716330dcf1c2de212cdcba257dc1531b3d4ef6a56c089d0fb455d306a240c97c99931e9fabcb697fe2b407432ed599aa000859ae50fc5b9f29f055b1762494d53e3269d7dbb309c94d670ba486555c4d9085d9024f4708089d0a64d4d692e652aff36bf30c86e12cc1f8f568f694446d98977687d83c01ad8e38e8c5e09ed47b8c447f275e06027dbc37d3a5e727d8a79eb3b336d94581f5690fc78742463696a45d0fe4613660cf8f0d66c7c25eaa27833b9957b291de30d699cb6ee391019b7de12f942914f47362453540eae89ec96c048daa6c4d34db266141b8f41ff623cbdd8c0fd74d9c8af6d3dfa2125eced0699f2b060e88c955a479e054bf2dd7650328528d0090a636cd796824d84fa382ebe6c0001ebccf5e305442ddcaaea5264685ce3a25fedefc398c3b00edd5d99889ceac23d861589afd384c4f5674b9e0c41c6320c21cd23bb1395e2caf219ca29ad642d374e63e0d41633009debae245bc0f5aef56008fb7220f73e6871c5cd4cc8491700d7977e791f0e30aa7b48b64a03eab107c5a65801ec19c785d7d474471144f6d5610775e93790159ee2a8aed5821085e7ba742ed0a9b369a4551e5eebbc4c919fbba4f5bf1cacee8d6ca26463ea4a17ef34a592b2b111846def0180e9088c855c770889fbe1858906f2d03de0b5a1f2608639a10df35f27eec67d78a517f13e00f31133ef508968e63c456704cdf7069fba554892a6f993a5f3feaf4432b351f20d3d68892ce61d762fea4e2436844573336a528c79878db781422eecdd8e8c70e5e9c25284efda4d732d623f29d288552e18d170ebea121161844d7596d1df22d1f35ca58bcf25ff11211b4faa333932d032261870b0d2da27cd4d4fe1128859c98a5f6100750073c3d8d42459504ffe3a5fc199ca01afb218ebafd57b72ab27213e31086cae52bcc8a83c42b769f3f1a153ba3c6ccc9012354158b7d8ccca22c63db2648f9c1294d283ff91bdc5fcc877837936e5c86b53d53d38f8d8e220398ad +expected_result = pass +expected_shared_secret = cd98ddb938549cc7c4fe56cda7f3ef213f1aea49fed4fb81b940c7e894be1e54 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +private_key = 30ba4f28910160e87263f66f6034ba1de4662ebc3600863de8844620e0a08a46aa83f565c3c33076eaa5a3c689c681beb935349eb517252c738b925be8720683317f79cca1fbe150a32a0573c21a7ca34908a21dd58266b88712519935f88363a1d9c6d253ad38032d09113cb132c709c4bd56ec73b3121674fcb032e8696dd395c9021d47a39a74c2167e084fd4f85df9002c246c86f1b1b498f05b7d41aff082bafb610fe4576c55064459b665fdb03b98b98839e221710466ee8839d846620037cb6516021841063aa1cf8cb59019f52769fb0bd72152f4e74d7c833f66b272be12839b91c8ccfb0466f835ba068e82b29b1cc79e596546567244c3d5520f6371660193e5000feac74b0dbb40c1d46dc82749486c4f40f96f55867fe3f6121b60095ae9bbf6bab7be258a4faca7af20a2dec2b736bb690c425fe91b37e4200234cab1eec7b8834909acc2c8972b127b1113e17ca26dc7168b345f1af411b4917463d8c7ebc1bf55ba555809b1282a38bab43a2528ccbc0a3dcb2445597744d3a5530a69059da7a34d9429952c626e255dfc8b6fe3b6b9a508120284a1d75b01e695a90eba34e3b1a8e5e99be069180cf073b7695119dc3981c0768ad9c31e095ae83675754971b03184ef7025ba19b1d9812f39133719925426ebc421b204900ccb0c813cd0bc9859b0b7752abff9bb1bea8b24f3da4dcf80a03933a85d784a3400708de7820e750518195c9b08a232e09abca31e033495ae72c84b66499355167886be0ec6b5a337cc1e38060e2a0fa0d4ae1ce4ad34ea9e2dd4c66cbb3489507d95520747e472c4ab1a640c672a978f2b1a8e7e732a1b56796300c961b404e796117f1a8a5977a81f04bf4097336ec0148d19164b831e54b9b98d72b18216af8e58af19731d9d92079df04d584ab964a49ed7f31e99022aa86828ea11ab2fa847210ab0428238103abdeb248a663a954c363d516b48cf9bcab1f0a2bcf0b186b46290189c9db9405b873d83f11e5936ce94e42fa56574497c424a91792145352ed167ad076346aaa7cbe074d1f2a6e6e1cb93634f8aa61fed9c4d873b71d9f06a7e367399206aec69c5569ba3fe2816a0862539951ec9f32fc1a2b9ea199b877873f6b13546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1da2512163eeb5c5c3eb60c91890b5992aed81b9992ac238c7c2a7ec41fb4481508a525f10c4e10b448ee4a7ba149649c11a20190cc95c60eb727cf84ec66c24c008a0308f28171f9c74cc7023873b1848b3450e28377d8115bd17462eee419f1c69414611c659449376b88e23061886338126b8ae317123786ade2d6c839f227ec302132fb59f5d3a5e11010adc5bcda4b01a28bc02377a6f3f4a0033249073b18f553ab65b57fc3176e514794db93a941d620f3f19d1103a6f0a02b7cfa8c213347c6037b85817b27b22f47b8a513d606444736af884fde78a879cc77a4d7644ae360004bb8b072b74a1cc99fb32a68770a110432e4c06f08148ff54aa6a5d2ac1b3b8e461b9813c3a16dc0b200ca81d4e336a54341c8d157d1742a0c327b7c0c9390416b59843353443530a5b70b71bf3768873771155617637272b1cd057f1f01b59565228daa20a060970adb811c106491fb32fda5c6fb70415125b1ab6148062100ab78107b37aa064942acf56919216c6fc58732598f0dd82838d8881999b431586a315375444c6a27d14ff8aa3da9d1340d137b885c95f69862b63c2618e28a11211e3b64bd1a678f631494aba55d42d8116b6388e9ea04b51c9773083a207000e83332c727b4512806a2dbceb6b40c644a5294362770f1108c467f6c64b907b0bc142625ac621352d64b73948d88f281ed3a65a1d4bbf920c962e91496718531756026e71a5986990b5bb1f9eac8ba3571052c32d414a5ab07832ff3172fec8ffd1197028a9ee410203ba02e6aa6b9517ba8746317c69304b381bd6d23b3db6605bfb2762b556bcb502cd10a22c8b78b4d0a173cd56ec835aa874c485f733b5e4c0db08558f1cbb11f866544f10a8a5b5cd52053d8708c3bacab400c78a65436febc36e5894d05b163ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff3703bf5150d1a7004c1c84ce25229ce751f8d00340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39ec2fc5834e128c5e1460d8cb0c35ab340d706a6c8b52070a7e41a6405fada53fb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 34391cbe00a1c3943f10790070339a88ed045ca63f0981b0d45a19b1af0df59a50eeef36f8045b6d6b8961811e99cded515be35462c05dfd384cec024c42929be7ff8536c0195c8591975381a2edc28f661f36bb3eafdacce01f47adef03b0464e14b34f1cc92e8e75a835e6b7be8d2ac6f8f8e82bd102dc0019715886202e5adb89e11e8dd3df99a093c62f9a6f5a14488891471660460b5e709636b2f8407546b2f984a9735f86b4dea2e3b7355a998f9bbc468ac7891835904e2681e9e9a445f70ba687f3025dbd9173741aa0131b2a4e421bb09fd162fdecdfecfde16fd7066527e833225f048be68d7fbc4d1bcce4a7baa2a24d114aaa580165ee3dd7605b0568465cc157c0d4fad4cbc1d78dfb3ad9dc1789010677f207fb12a0d616ec68119638e504a8d437600ca01130581022efc11a12cea0904e22dffb824d72b4aa6037a14610956a5884634ff1df9e0ffcffefc7c74ac7c4a202c60d1f0e9db4e2e722e58562811b3876dc7d872c0596a47ca063dc816558207c2fa155410bff0c80969c2c46b4828b2e5b7d78807d88430c254c861cbbd8e49796aca284a2500598e7a6f2cc543d8bc81fac06727e8b4cd1165543dab46c7222a9d58f8d9c15a5969dd77d6090132b9cd05c079a40a0f24abce054e3ce7717704a381a75ef33f06da5f6fe6b63b033721e7aea6c59c39a4333f09dff6f45176c7dfc654478ccac1395811c9db19fa39775f304f618bae8044333db786249b573a73c0b812e7f9657c471d65cd55994b54a348174df87a2ad7d2d705121045dec4df7b59d391b044c1f03fb5840fb8a061911794ea2c9c410565d73c8b7eb6c7f88fd3aaa251619bc066cb511ae055e8d3620654d3fc9956347854cfd59f5363b93cb21584f626263e1a47726375b0fb2c672afb3c61b3e79ca73e279ef3522daaf157d9f82401e955f9e55c70dcde3f784690f2f100771bcb8f9ae307242f8b8a717c7baee42eeb8d890adfabb7d18c9c2ea8d136e9a66a5b6f2a4289729f25c051ef44882d48e9f5d18b6c6162867945f94cda3dd54784e12d4fb364a58f65c039cbcd4e563 +expected_result = pass +expected_shared_secret = e0d0d574b1287716bd7e0a44feea36ec28469bd36713fa8a53b0a104f322016f + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +private_key = afeb5fbf8bc9fa409670dc0f6c94934f53bf3d4b40163278a3ab076086c5bff79d153c890da535b3d291a2a68acde58df67911f17939b8b474306a862be548b6d092aa188fe4419a3ec659b9b8854b489ba2200270e3601ee6973b6287df400b0775ae483c55547a9b7aa66b396753df934c13085f27b978bd03a5a661a9e94b809a19130c92c1de21b26458c675e955ffb20c939028ccd358652b0b9f3c1d3c300bab422603354a6cc0a270e7aca3706487b67b16accba7ca9296661e2a9b2fc7cbcc60f10819a0bdb400662e203a77c84c75824269d662c826ab11f1b35f8754a2870fee05a04353c23146b62d91161a9a10ea028f8b96b082034d4e63359ae565a00ac0e1c8201a86294673beac8394d01935c8c201c76a0143a9c36e737d5bca9a07994d91dab5e10acf3b96aec1dc1fb33c8f260b1ff6e8b39ccc6a20c554e7c48beb3ca45d9341a0d978846382065b4ff6e13f39a9576f3b559a58194d75ce5e48b89e857c45f104cf7781ed5bac03965bd74942759231e8146d4051b86e33964b25a9e4db0655949d04bc73f8916280cc73d175834aa349ec8614b3f072eae445520b64c57bc284781061e72a7c264c05ea9d9bb20f33cb86ad2b080c98a7e7b6a4a31b119bd139f270a8430a7aaa122e5bdbc9760b0c0f562719e6630d3bbf0bbb3311333f0918385c86c851ebb8a306cfadeb4634aabd720387c787833c9b7fddecc117188af713798126039a1b940694cbba5171d2b977876a9d74fc067cacad5865104a627c7ab0715dba6c0945916985bad2d041eb43a584a1c152ab6df0cb8dc6bac599a60b96ac6e5833982d2167f8ca2c9b984ac1450865731aabc3796e8b4a30a6c78ef76fc2f5c829a2b23a33af1325b54b869374493d2d82275fe49ed6760cc90992973c618489c37f53a3e5b605be77ce48e4c05d398cd648bf63c7298ae11faf889d684a522709c7e301956919c419875696bc782c5b160ebb9acb542138f12195ec3d8ed03c64045f37e53970b7856b3b0719d330b603033dc54c81a66cf7a93d8565b3dcd91458158e72962b2bd78a3ca11e6730bcce04a546261fb88a14769a7ebe1ac627d4709ad47e84c44ac01ca4c40c0977a9c8c6871bd929b6e70a8c76a02342ecbfd8a90f1f31470a8708506160f961564db86466d049894437ab1a89dd41363eb597d3265d1f7b9a10c715d40a182e945c9666371431a5a54c6a80222362fa245d9aa10fc115642b3f28ab28bf05c254110a5f5ca553db719a16269d749bcc85388825201c8152c172806c9986f53509a2a3aef9a28e22e58cd1043e19e757b8179e40689c9762bf2138bc02453802869b8f53abb6bb088828726cfa51eea526ccabc971007a0d011315c996ddccc0fcf365f475c578517592c2c48117a63a2b6b854bc7a7a785a5dc4fe4c1b012d78cb3341f9cd826d1d2a13e13083e046de47711e4ba0a784aac886b25dedc2033895e48386e57234ef28590c9f542331a9ce6a0a2dff143b6f542bd752ac6a67a6b319ef15c7203119608a21b1374c5287348e54284dfb3b421b674f0fb3186080553b81f92e403a5eab01d564c9486622bb5233ae0bdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff437197215da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d600260c2e077c1558c8f2abee536999d951bb934cc974b55365495795a6418ac4a9f4491b4e60f992142487457e7359cb5b01e7e1ccc909ca00e6005b213c339c524b26a0b747c18a116026db16239492eb056b12ff700fc56ae35e97ec6d0b787c8aa02e4b828b41996f01d69fc9be7005d4dd89963298838e27c59b79c8de62e4a636bc3ab197326c8eff92c90e4958980a3382365fc65594219ce9d7070a6c3586466ccc031310825ba43ea933d416fb7a73d83f05ec222064f03b635091c25ec0a7aa99b9080844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da88a02883406f1b379e95792c68197d591cb9303b3d5bb2791550da44567d2115da0bb4d380849e1145140d9c6983819f7447332cb697aa2783be169db60249d3cb77d35845a380be3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305e7f49b87bb2319dba8d3485fe814aedb0b43173bc48f3a793554c3e8bf90c17273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = a479b93daebb4d9775a0fb160af4970387139b148c9c328c02e2f774947e1c239c4d179d5c4007a98f2ea22e77878d092e8f27bfcd7aa5e8db486225e579aec679b6e7ff7f2281f32c3805b720fb1410f6294dba996d2eb45dccd91e8225d11bcebd9b0bb21b0e26d8155d630fa6011fcbdacaaa0d60fd16e099158d13cb58a74989a5b981330cabcbde98ec2ff9171cedc2afaa3195f8d6f566b728b3a45610a56f145a5a3e2887826f2b79717454607248fd041b533bd58b0cd52b067b902a4aa0c751ad82899065989fb5612faaec8c27d2d3b3a426bc188ce7c0cb7b64efbcbff3135783315aa327f711f5c02b15e0d878bccc53f6140c4146d7342df087e77016165f0388f2c5892e48a31b03eb5883954294f8d487879b5be80316647e14be9998201ef3fff7a1a2f7feb3ea54cb031e4636358da41af23fee79821a6d3924dee3246f21663b1897a8af2feaed7d66e9791892a86dec4ba230a00082d94718de7ce3db14936aad70f6b90ceaf5529d62e017ee5f6440163d6b43c7f38bba1da3d2fbd573d4a00bcf2262700145dda11f112b46068a393ab392b8900c673fda1d7bc98f2a0904f65501c970785abd9481acf91f85185dcf1971093a26cfbf1084269b55e6a19db1b961f38d820cbb983b8800ae1a215bcd1627ce81c9403adb816019d1774514b25144a0eaa4af61e8ba88ae25393473ca7ba236637381574f46e59d8a210323aadad4bb89143cbc3e3cee36b22bd9de990d2732bdbe1a5119c0c8d8e3afb74d4b3ad171d5517d5450ec3e88f8b976e6134f996fe7ff849262cbd42ee8a77a5b0256d16ce517c3a47b8410e592d9d880ffa67822b1bea078f70042f691e9740653e62879553564052277eb90fd95396f68ce20ba3a3c0e50fb25f58d75f490d94d938659fb51d16d50fd9d01c296d0af891d157fdc0c30ae9a8affc1d86c545fb286e7ee89041fe9aa113fe6d286b38391d1b7f3f35cf0fa54f6ec4c62702bac3310051d32e16dfe9db3193dcd54b087b3dc052443cdd0c8f2c276a493d476adff6a8a0972081874b7970e9102ae5e3675abbf6bcdbb8c +expected_result = pass +expected_shared_secret = bd97eac1e35a06536e713a2ca5e71e35277b948172cafef0c35e1558efb61676 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +private_key = cf59c55278aa76dc467176c58cdc4499667510219cb1a28e973404472c38c4e7bf7e00d00ad5c6e0ca536bb13081e9708857723029c619f1bae117b283c6c96bb61818942a4b63163e957f1a76a1a3c8af61b851c618927ab771098a43261ab16a8a252d25211d1682d2265908e091d10365347380e314bbcc224cf8889bb37759345754c4fa6589c8b055a75313cacc3b0c21959b621a68ae1a5a7b6398693c0194e57ab2e722072c508027b98980e864fb82b7f1e42cbdb9b608b428e9e391922189b54b18f5e66656b236cbe50563f75d84f785dcca6fedc1123ed31892d4289952cd9968478915b5e2e4a2d92bc6281b702a84a02ee740a4250f67f893809bba3c790b963b70facb645969457f91adc732406cf4010b76b478e37bd0771b3e801c37dc1fcf7683adba4eb0c49fa3aaa9cc829c2ec77b39e15d3a8c6873b139cc7c1dc9f8581e829694685c0a06cf9e33370cd8cc514abdc6aca6fa8203e13baa97ab2d55eb8c9c122c1fb55d1de97d95fb9323392a499100d9a5cba9d8cb2423688dec85a5442091398419417749617c66c06321f3a061235ccb799e8f23ce537351e49b59029a59abcc4cc9f27727653a230051d907bc1fa67895c60242c4a945908cbd480904977b6e016c1a27c120e37bd19410a8864e5b24ca2aca3cfd2ba3d9e9bd63f42f3977aa0c815e5d13c4ecb1b7120997f77638dba3cd5ea57883f5ac82222ecb245885904c9b6058b023253917b7af71c2f94b74f3637c45045d75f840191455b6154115555808d1c122d379ae176947984ada6c4ee90870e51185ee5ab0fbf042e3a299b0797e36d2c5fe5004106800868629d0dc48f46c14c2082e66a5a4d6579676624b5aac1fd07c60a0091b1cdab40cc2341f1961a8d882496c21573a21a7a4907d0164960cac9aeb10e62377ca7c2dda72594977225c9b0218b2787bb8b79b54c819418ead17109f950d6ba4bbe1da35fa698ceffa2a52484eeb868d72a784535814b030130852540eb372e7b7218cf499d2ea3915682a30176b08074f2e4336c391b69f1130c4765032649d00f0b397e8bb44c18f4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df08181e5a7343291002915603d891099172597c173a88b41cd45c24e40601c6a5bd379113d876e06614087204cf43c3564980d9630e84b621d6415d0ce224d50bad07b52d58c6ae9ff108948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd6013eb33046060cbcaec21b13549e3df843e9e7b6cd731664808ad4a773237194e9d5a39217457478a6198203f9e6a90e9a8492f96fe28a72c9e2743a41caf07752f52b2ed4fc17efa95493a24c66c93bc6aa846572ab7fa0a808a16279382f87700d8f195e1781803880b07c925256100f7bf223087a85c4f3c88f861e60f92532d60f5cb2033b883cade25f8beb7312520fb3210b2230528644b1ee298161f453b5f32126310899c88ba50690ed925ab0537ebd594567e837471a84c6ea72787176f80c94894c870e69337d939691568edcab008850a6f3a53eb585c01af253d1c9434810555afabc430b7fe69324a3e775e6f2be3638b119a6429ff98d8eb1b5808720e467302798a8ccd8350d36bda8fab17a53bc0c851d91b7cf10c617a1c03bbcc63d93a38ea4653b80731442889ff8200c96b5c37263081dd400d5670959941764a61cde119662325339da81f926affe427e31c6883ce10f5e5705eff1cb209acff5644717e6c6928a41b6e7183590aa524744881aa427c17fe955b306c33447054ac729112568a4cb16806ccc008ffca87e4cc37c3bbcf8e50d3bf07e01132efbe0605a14ac32f6ae2802ca893139f62a64cef28b1720acb282173f2cb4b0f392f8077a325a6259a32455e57964e338a6a731c5aa29beebb0843730ffa93d6b234d51bb87a054968cd07f9c3a2ca79607a97079eba2481e590955e124fa7805e1f03499b7216b6a3a14b9c0c6bab99917a435b88c4314a290e70c7eec8a145037b6531b35b89655e90df5eb2fe53ab33b6c68583780a3b52bb92cc90c45a28cfa8add511ee03bb8bf528d4e94bdfc0cc510e732df4913116a7786e437ef523607126f047a17168824a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0e3f73c56254fac37209f5a59818fbaabf5abff3320b0b3ee00e20679b5728c12a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = 773cfcf14699299bc1818306cec522f63409f9a8bc405b2838155bee43c8e6dcaecd05ce4d6f93e666c601c81b14ad1d79680b7bad56575ad5abbee83d014b44cf7aefea7a4860977a2a4a05351215c569c59938018aae94a5dc231fb72cadc67dd86bad1ca008e129fd1059a7270128b4b40ddf72685c21eaa723f305b6b7435cf3292ccdec873b936b41fc17b48e4d3ca861f66952f7ecd90a66f54dae05816fb7e68990f44710bcb121053505e9ab9c42a324248bb1719c1739660b65b44465c1daa42dee4448b642a9a88cc26c94dbf5a988a861b34eca0b4fe15f28973d9c8eda76f3ce93e9d69663c6cd7c8a0a8adbb1cad5edf5b1b9b67a48c3bd994c76326aca2680cf9e350cf46e6e6b93149ce7a79525d29bd9ed969857a5e7927f511a1f5f343bf1bcda86f4e39ff3b8c7b2b8e2b2a2ab147595c025cde7deffd917dfe0022b1dedbc8f1fd2b0e45b02498a9026e81cfa79178e75ddf5d9cd60fe5af246854665464e2c7fa2aa33901f598b0358326af9eb2e0d5936e1925dba6e356ba103a6ead3524eccc8726746828184fa2f836104d48a990dd90fa72578b9845fe99a9f9470f9a46111242e3e36023196edf9f6c8d3249e4f9480be02938405c3688d54bb95eec7fec06c710a1979d3166c6d247a9edf892c4f96cbb57171d473a03f86f918194b644537f91570abec07fdd2145e9842b36ce82695bc2bf328ef9f85a2fac305ee54ff330ca9f3f7b949eb56e0c5b6b72006905bf4392494ad70f43ed6ca4610c894ed53107c7fe6dd4b9ce821a9fab03f404b7c88645fbdfb655cb4414dfb3d9bc94ed723258f9a76a567cf9a9b37bda6299ed02444da2ac43fe607972a530ed1c634565516c8f1b36d16945af1892ffea7351965827e5231eda57359ab76ec1bb84de0809a44c2f6c963072895d0301dcdf2e58c24fb9f1c7f81b51cd111df67bf9f51b4f41ca15fbcaa4d17335377ddc5dcc6a7a0b7d54a843292e4a8951a691da80586baab781586c5cee2ef0287ac613faf0eeadd32d5d641193f0ffbe787f936f6d879c89e2eb1a01fb6ee4df1719779505df2e755 +expected_result = pass +expected_shared_secret = 2ed540764a77b17c6b9608bf86d8d8703f80718044d52dc79cbc1838f91fdd7a + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +private_key = 4f9166b63489953773ea5abb3d0c6a3ae64910943321a13fce603d2e7190d288612ca63fb1ec86a9d50bcb228f74208d9f6352c5f57e1896972230c36f752b8fba83f9d006ea92350a01474ae53799b117e38860fb5cb37630549b5b3b9e5928b6fa4559f040332ac243b90c01353ffbbb77b29735d5e8463e930444b987456072d6579b1fe52ebaa689e85950f393c25fc0aa29d76306558a6b1c2d461bcd4769c2d29358c891a72ca63e61c12c43bc3252107acae4194780ce0bea39d2daced340416382bf99cb8c12bca7ac94ab1d50809a0b1f18d1c4a4a3aa537519d9772fe0a88e668698e59b77b94abef2f969c9f46fd9a850b9e341ccf588485315648a960db0ca33da481987310455452f3933c8db0e1692611d40233ac617e72034b6e8b1d614bc6f0b29735aaac3c050ba38682cf3a6f0c5638b6097f46a85c32a7cc8b06f34f8542c44064b46663af7acffc0a45a99aaa225a30f2c6fed688cbf789c3b6a7464aa17388b69dca70f3e9a588b6531e9032b883946490c9d9f3a53ee0139ffd6c9db19491bb428ea92c2d830c04cc98fb193b735c599d527c375652a964c58e198caa37c3f97e4251ce369b501cf96656f2cc1b29ec1b88ba8341727496916a4d01c8158d4a5654723de0c418755271834608e72a2b48bb0b5a62abba9a99d07139858c7b767ba2d590fb0715329392927137f58724cb72137ffc08fe2059671828d57e6885b5c09007dc5da4089807cc097fc1bc376bb5197a6c5c932df08066c2b6805490604f6c9cd4a1406661141257e8b1074ff2ccc6f262c11cc0e9c9b30eeccbb824170251ba65aa1bad79a91771cad19226c3962543478be9c48ce4a869d98e16e08e753aee5321fc060efa807cbf54d10c8611064a4e68c7da6120f67b3bb9bc016e5ab61d6a37b9a83a490910c59e91911c33d2ea20f3e414ea08195ab979a7c204fb4582fd52547d4e0758721c32d6ccca0dc34493a52fb606be8785014f9761e704514022db0a322c10a377680c4d274b17aa9472fecceb4cbc3213153aa55af49b808f4c5abf98192bdda571c366e658177f8e055b6712164215d038aa3f9050a35732e408ac91a2635b4c6b502c698104c7e90a26bcd903a4b78c20218ae92d39bf634828a14b529983e92900ecb3778a1583deef38497a336063a31ef9460e8b240fba40ffd4b7b070a4650ec3cd698046c097189237a11a510f6941e6b73a79dd99ee4a8517d25650ff2c0e9b0ac238302ecfac7fd642df9830ffe8714ea8071fa097b39e57919462948a177858c89fbc8bbb2717eee7169b4256606c8abd1e9399df44f12fb8e4ba0b846ec7fe1d65582bbbdd0d494a8a25cc81667ae1964a525016d9ba5ef698c84472ae62cbf10293cb047082a58bdd321c616fcb7a79223e95c8834362da8e60d0feb36a5d1a1a6b6736200213ac3620a113a6d5436ef2064fc360805d2ae84d79d07376123fa1682f80a5e85c87992329d52125a9965d8b039784a3bb472a7f310057dac08e5f41fc1ac9e55f7532f2359c3063726a25599980597da9715117a5af15de88b516f8a41e4ab824ffa8e6ef16cdbcc1fe4f965eac97474a7b235dc0c73140ee7153a835c29289311e1c2a0616a2742c70e27d656ef9954c7643947bc32eb713d9ac392b982400ed275899a04f1b7356b02a54c37beb03215d9e1505380049f9b61b35a61c105980652037142a44c42252663799de7bafa6a042d439c893a37a87b1a792c1689924cc642ae09a299d456c6d36895571572f19c144bcc6eb0cb9aaea09289c8cb193cb9ac33823c11980c950d1106625755b280077f9f383f828824818956ed46755f7933f029a9363054ded02a42f5c56986c541e9ada77084b08b7eeaf4abb700839a59c18fc556a6d528e5326c0b4baec27285b0353e3a152f06fbac742a9606542ffbc14d0ec214757cb1a23aa810945aa8526d3cbbccd11b86ff12b553268abce55d7d723e496071a8bc3a8072ac653cca7c261feb53c95b569a44d52f3d61ae991c38828557caea637e6b130142291dd51ddef7163cf84be7a266e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4a622bd8540b044bb14384aab596147e813f9b1c94f75bac39a1aeb14a035d858892b7e900a2163828f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86bbc0a40ba03d27bbbfb91654fdcfab2dfb3e94d9607b99c1d7da1f2663bfa2598e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = 80f0e07ec92fba925668f52fee7721b4365ce4cd7cf90db7f482de3d8ed0d94b5e79af79026a67fd90a5430d7350b22563a2edc68e796a39c8cd76668ac93136022e933657960ef383100689e067090fce1e15c2fd3a8aa0383de02f585557f0495e53d3ce51e947a127eeab55cb4bfd18eebf7cff30d5eadd29cba4eccca850233dade0aeb8275cf60752fff0a94e1d9f8432c26162bffcd2736a553ee71db05823223f650357d2a2e8728fe050b6242a6fa737754067d629a1c5455ea67e5a8eb6ab907ea17d86ec216b00f40a61a0bbab989f6d1643c020301daac7de7a59e76cf54a8abf6773efbd4b6951acad6c367ca6e9411b8f8640c0fb42e23113b7e1a358ebfb80987f6c7a10a3d0bbe682c20df093489d610be2a3b5f231321053ead86f4e402398c650ccbd8264a5fc3c8e1c1e4bd671b442650210f86d0830f428560d5d535dc734e1c4c8497aae1bc09441c52f3704de83e77b4cba2e3895f6d9b5bce23e31dd2761e3ebccda624b5b86085f18f615696a52de50c56b1caaf188a3a78a623b2f172bfae390df31bc9d41d7ce1ca6111025f2506b54b1d1ddf103a35089b6c25f956963a01401da4a62a570db8f210c8a4e3c94faf34d7b6ba3b3fc66f4a436225549181b9e951dc7b297b8d7fc656a3e7bba2967963fdb6bce347f2cf7c3368d6ac4ab2d00198125fa92363290db13bd15d57a0154cf91e8577a73ddf83ef7006c0da7e52f3b49d14fbc4d7aede982c35587a859bd796c2d35a9225ccda6c6ac15f57f70d04bb079b0e46c7b27c1e05990b9162b52cf95cd3998652c788dda7ae35275446a4edb0385fb5019cad108eeda5e49a6928ecb7659c7d64a60c0f2ed7555cd721fedfd9ecdcaffb0c6e436e9e70521009c51240836a85d71021b2121e4fe1f40afa950b2c8631edd8e4cd0a26b8e298a97b8f042969370582fecb51c933f7cf6d4e5aa81aa1b1c427ed69753cda44ecb992c227de925050fda2196b4668012b81bed5def654a2f17be2b13e10f22aa101804026f2204d7000719ca13053c034fcf608efa2e83dd1fe15dfddce2a61bf954d78621e1 +expected_result = pass +expected_shared_secret = 1e5ba1b64fa8ad0494c96ba27e288ee2b479c24634285f8919e58e9b9c8be78b + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +private_key = 53b12801738266b450385a9729b894208ac7b3e5719acb43d716461ed1513925192b891180b2bcba6a22a0465ce788832be49b0e3b7fb1d44217618fec80b973ac90f4413cd8f54b10848bdc304cb2025a880c7aa3ab1c2743364523361d84c5db3439ab5cb32c38406e3c5b1b7c7d0403aa4e70786f579cec2c96f516bcec6c69c3d969287ab855e55d22ca8379c1286c52085022c1272baa2bb5c6027075a830370f981c8c836a08f08132394113c93ffe345766766687daa59a591d58398262764aed1cbdf8e87f6cc5b881c18aca05187f76a61bb429e9e024ebd58f1090a6961a0aa8706058d90a8091bf7385aab0b27f16485e08a67b5ebba9ea365b7ada2c055a0daf82b5845c992c945960159a50f7aa1a588084c48cb65403101747fd588cfdf43549facac6d78799759f2ef38d06c42422d73b5ec70b512313738027b9b18eeda06332dbb5856ba413e357c07c1480401bac34309aba9ba13825ba5682345511a45c17353789dd302bf6b1af1573245848986890acfe2708523c02dc53165f204fd6a85b44a650f2d2a325477587bca84994025d221967f61c746a12fc09bfdd3b89ec72a23405ad2a8512d89129585080cf0a6a416365130398bcbb93e37c18fa745b6e131908b0400a67470fc4b40e447e2e378222466336f0966fab951cfa3cf72316c7d843880c297e4444633b52a0c317d4a1a9aa6892eee5a538cc0e07c17a135a2f0e6194bad18494e388866b0cf480aa3bb436b91b33d574372fc054c72b82a4a823b1120b9052c41b957f58131d2dfa8529f02e24f50d88017db823457602a22ad78080661ddabbbbb9f6280d0aa59ef37b62594a013c74a03b8c108ab225a218a2f81358fc0182ab7a607ab103591078077d4f1b2b2de6957ad404ad8b30c146be11d99a0fda6b0f254c13ec2daaf4374afba07ea6ae69fb6633990c0e79cb61c9a81fe4bef140cd1ea569a036cf716009bb3b33708327c478826a08b03839afc31663d4f77f74a972e92910d06995390a3e193ca83706aacb884ae6b589c9aa169beb63d4558d2d43b43d0c4f5ef23bdd26092cac54b7665f3a5a380255617309ccf80a53dc03259fd252de0bb4865372fe22148ed6c5f6c111ac00b31460c5c8da7728dcc4c45093f6c38d78432542ec71be51526d588d46bb07ca388088a1c873219d74334070895c396a87ae390cbdf309e41a2fdde955cec2a29bf205e492747dcb39599a49902151aeac0852d6c042b4c0db99c3f3f94eb7db193bfaa7005709933899c04235941969baccb59418a41e603ec62679b2808f25c8565e6954335227e40040d8407147ba15b7a84405c6a6e72251236bb951e18a1f81b84d0126804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1eca19835b0bfdf637a5839c007cb5c5972111aa64bb0f84884d70375e352241bb0dc4acc5f170a7f7b7ed3308b95d975d5c933e5058df99c4e08878523bb98274488aa712529870ddf5211da039bf2e43eb6506f30b41a90c8922880bff2b1630c0048c22c4972690bc965c009e834bbf936581c9da72a70e2a4c2de0220cb4b88296c9716215007ecc9cbf9c1ac081d84d56adb884d2522584cbc5e61d3327bb2002b275683664487a3ca8f767e54e27e541a403754a45b9512368b0c0298bfdd2143ef9c16b49a282e14010591bef728001d0892b939c3fce379c2e96c2b41a9e5cab8c09cafce0c2a14d79137e3b86b25546c86228d008c792496ddcc9ebb01a664e62040d09fa798accce9033bf828d6058c27e79e434904b756afb332c9800312ed69c4cbbcc379b30b83fa4f71c15e86680b6e40b1f79601ae530e7cb8b7b7d536336468ae291d63360814b83ed574c98ff9afb2db8fe0e4561b98001ac783eea99b82d13de2fc5fd59a1e7cdc63e814b3275a0adf318fb2419c76545ccc70066b0abbca763a99901ae6412b43e26090418c09554bde64c1d3767b074901b5e61449e32532f98365b0bcb65cb3b63c03f1d023e495a0f96a258ffac4d3299896055838263ddc85bb3a071ac5c87cc8a4ce8467881f54047759b420d5809489cb2785aff1935835b845977bcf2b275fabe31222e8576e3578a7a56a26a31bd5510d12bc9aaa3a46fc87cf9d0706d20a126bbb446c24230fc82a780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfae16da7f99bb7bceb75a6468a921ab9fe53aab2972ca616ee10697c204df1e3509f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = 8627be55377332874bb930cb309bfc6fd3b38946dcdb8f0ab382d2ab60bc2d0bb29df7b1bf3b3575718369ea8a29e923058894b16fa20d83ee3c0a9c31163ef9c90e33c500f46f1efdfb46e2eb2040f681debd4d93e63bd2d3c79b4d38fa1b78bcca1b5d407dd1c5f4360cb0007c3ac8b42a8dfbb982fa7dac033a8cc46c01e13fca6508c783060825e6775f0e404b95bab4d6e4c1411a0866f0c74d1af869d5ada4d9d6073b25fb5cf8f3a0a6889468a07f6a11359ce1ddf10e5d42a45fc608c2d93bb35aaf106d88508b6eefd66485b8c88012b0d3f421d391e9a7173aab441edce79cf884002b3fe7d1f45438b0a6ac966a390ad40543f7bf1bad961deee15de44b07b3b4a40204bdc8f0abe5143fd95bf8e46c0e5488a3d142300715e9c0b5e4d56756a6f65570d36e7373b8e692a161e06a08b94015f1e0acbfacf5418a36d575a93be8cf61e98fb1f9c0229b50af4da55471c1d4c4cdfe8f859f56a95aa5d4a129f5819549019372e803d8010d6d5f444eaac568580ac0ed2ba98078bd65ad41b6a14102c8e5862803593fa79ff47220f4dbdb25c1725d07a564495259664e14da79d975c1b4fb0a36b43ee1646269ab0ce962bbf970c2bc73d953f5e78e4a4f4ff58dd2616e30dd4a71620142d05ae617df9d38131a69664d62020a0d4edbc0b21dea93e4b567db882d07b28fd392e2c188c5a9792fa01e375ab8e02646aa1f4b24836d2690141f2568314543890b585c687f451365995627ef661e6d16c074b3f1ef2621a03746dc9d930bc9989e6c6044c8410b8ac62b63f3a217c9d0e42b6d7697cd79c7b126fbfe5137c17f47f8f3fc0c907fafebc3e851310052abc266a8cd0907f416935104cfc1db894cdf658a42acf6bad98e3aaa296e85abf8c1217fabae0fce40675e875903042f2439044388ec5528c8f58c0b5147a8cacc393a8da13a52df1a9565bed1fd40503d92955160b7c6cfdce6e5a146b34011e0e052c1a4f7528d1da9667310fc6d5183e003f24699e7d16185b3f2dd8176edb310feed5b70e3f0de4297335cde9bfefcd371d6cba0ea0a6a5e9c1afae5621b +expected_result = pass +expected_shared_secret = 96ba12c7f8a0d864ce1434b789c09753c2d1f7ade6a5a0e679ce2ea0b6d66c83 + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +private_key = 326a5f31691381162b5c776bd677b60c25b49d60661c432859069e849144008d8b8e9636af2013fff55ba4120929662057c2463050040de482875c5f7cc940b4b9bd27c90812fb2405ac42767254ef83b74882c4db071d926604383ace54751415d564ddb16edffc4bd762aa5a6714df4978f3ab1928bb539f921713170df8109d4005135c74c7e6730691739b0dea12d0c1be131228e1b094b0b894cafc4fa0835c2a815bdc288f56f33c7d2c25ddba868da6503b00017b1373df2c2375644de677cfb56838bf3581bc173a588a9f0b952a3b9abaebd27e71d38431e4a8edd398bbc4a58db608aa255fb210cce7247b17e3bf922ab17b811bcff5627ed2480a5c3c26b273ba478a0dfa80e5344b88e9cb7a00a254b8705755b762216b4abc4f74d7cb17b69771729b77e39608835292822ae073bce322701ff37bf06b917d41396dd948632b6dcf572ebd6c2a37271670eb178ed31de5b50d17072d33914b0044a977d0862ef1ab630ab57eb207f445177cd0b3c34b2d7c75ac832b6127c08b71f1579a63b653945222560c3565a0bb77ce8b5761f71a3ff63097f4813871f57dcfb4b3beb1ac7f5938375aafb8197c552801fa07cbfd8575864ba807e0cb37aa6aaf60a48c7202b6a89a75a38b019c6a8f00cc642901e7a98f81b6c76db06fbd0a7852e4291dd05a6be618e1c97b6b70446a7810b3d470bcd01a593314e75b4215c96b049a66ecac66a3021141f9ba12778e729213cb4656eaa80c7d900a079c70f890285356c0a13a6c9a4207315b95bf45c8780138521bc72a3c524c689baae033c80a461c3cc4ffa48c0490517be741b7f6c98f85a86d8814a96b3df6c469a197c0ec5367e37150e9c19a726826be6453381b833377890b0ac6f9176a1214a352a3a49101532b3840f4084574cb76aaeb64881c78d5a8bfada105f7440e3d04a4291bbaacac5a981b6f8777a7d109966cb2a347515ae01801916174826a4124a495d0a07861892fd5f8c90e085bf4e1680275848e24c6627701dafaa17c9b6c3a59a0aa5c87b19a4a23fa4ebe49218f588690f749739a39b523a08152adb6a67cd98268afa159ba69953a085099ba56f4e4c74fdb6759791d1ad738cf320c3cf8c52d607a32059f1e8333b4021d855816496963baa6cb41842fa7ab7297a144758b84a27aa6dd507c097a6c7a19063f2b2baab0604aea5ca1c82dda790fa390c142b3709cb69675b8ba0f4990dc923aa525a316a0c7931aa5e5dab4a4e19f08f898ebe80258ba72127a92e3005611a72022d285bd279332817ed4f13a06a71f8f68a0be49a13eac34c773937da6218401c3fd55577572466a271a4bb10a7938919688629fd1c77b802b6358189e13a52330c4f836bbf41595df29499b42a5a6605ebcd6aaa89ca33580b5ee619d282702b4380b717532e0dcb6dbe3bb0c6431ad480821f0c184e7817616c110f2155a0536a4c65b21306fcb5c343fc38191b8b46dd7a3e27240fb85c365a33e18bc231127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddc52157daa998c392a255b37bea55f1c33a23ff4cdb70a3fd0e019ef82131bd92e5db8ce9230421a670c246695afb5bc33e8569ba69d2843957ee52204e435f85c6a713c3fd677cf7a54cac8d48975f1609cd68659643a1a10558f7397234b583e5665e3d30d1fa26d0788b21bba2ba23507123b89ca5a1f54cc5957737159e93070987613dbc7dbb2ad163909fd167d9e099d8c394a7161417141cec54a24f34310bbec13abbb05a3681c81d7034b8687c1d62abc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa8309812bf6459c26c5fda4abf0ba46544a9146e5247adf99f09622c74b8b90397503e211b9a23bbbeb3bfcec659c936987c87104814a312091fb443acfb87a0863564b9eb9191708ad370ba73d42f35b5ae9b97004793992d13b5bbf00b277a2de699ae41222f28d593f6d3385583bdc938334e724341883a8026cd2ae5205da3b44b9075b86c75fd203b0cb738b4f533efe6117b97105a275edb7b0a15aa1ffaf029f3e13145eb3c500440c0e30c426c093c420496d85ab46883b4b695f30952bba32134189589882f5c297da14236a073ac04579e4e7a70685916e53845c8430e2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1fb80edf4f67823ff4e53a8963a9c9937fa9f8e014b750e11b4c4bb1a361d6484f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = ff737aab09f925bef6da4cdfc9142d86960f28c3e383a5141c7034674610610731b31435b50e2bd894dfc12dece35422ac59ea17beb63f9ad72f6ad81244275e96d8b7c143bbad756e86d9b206df9eeed6a64818902489981ee9b508a227462e2f6dbc3909a91986a71c9e1b497a647492fde143cf9d6730513ae680875c79e747e6b243e70655f560545d1a60315f2a2856cbed6a13f4857fde587e1abf415de2d5c67b1f61496e3f98290e6ba086bc412351071cdcf3a9f5f12881df65dfcef2746a7e1986d9dd5efde2bfb3b70744827fde41f685f694a05413043b14df26205f50f2acdbe893307719819b24e66973dda7f4c948da11ceafc96a20ffae64a4eea610397c2fcfe41bbf8c2764b60745e1883985844b76cd5b664e4df2faf6d2602a987a76a1fdd832e01d830b2f972c2fe55a8daf3263dbf1f0bb1e8ae5adee4bc2fbda1d0413f593d6c330779c0c51249ab91ccc0d6afc6369214fe02b1504c3c34c873e7421918b347a2f0b166259a758f6607eddbdbf87167e57748197fdb63a5501e235ab4ee00939d2e9bd8dde8328b9edefa8c1faed64ef861e088257fdf67369f1ba575473a354a42e6b1855f48cb87bfcc798f21a7681015972f9afa79c48db278437d0b20402d14465fa7a6ed2d919c5fa2ceedc06806f52d3746ece0fecca84e8cf13f8adccd9289e08325ed33d2af1e85326e431ad4380490b07af223ad0ef8e6c4a95e9cafa0c1cb8d61c41c123b27a2ca8e267fb9c63fe371cd5b1177618b7e26441596615d9695e04c77fc87fc6774393ab5e612e5ffcbd54eabbb548c568068b6350b27c7d4c24469efdbfccbd2f8618e266e2072e7b1f8c4d7ebbb15e29293a1c2a5c26b8829411a5f861c2b5404b4c0968c535d42c2b5b0d7b14e30e2a595d780ecb1aedbedbc036e27ce80975fcb381a3b049f936c5026697822e407c7656369caeb7ed574c5a8da357caaa89380940f776cf6880eca251ab1e895870be9dbbe3aa3a6e11315e1cf7b82a4cb183c8b0fd3dd4d6b436a0b259fb8cdc2257cdbde82c358b174087b62aaad99f4a2744b0cff5a04885bc +expected_result = pass +expected_shared_secret = 07dfc04ebbb7ae537b594210a9180f647d3d385d1c1bb56abb8174111eb246df + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +private_key = a3f608e503bfd0261066cc5aba7a1720aa8a9d9b86da5858cd5b595c688b5b29ae3b8b6d9510c484d33e6905b86d9c236171cf825bad4d265630878d8b8b89257a510b907eec6146326ab4aee3cda24c9c36526578c470b3c44934823a6fa71c08f8ad662bb2d290aa0da8ac3aa59a7b7210cf1caad0321c63f07074e2527d2ac4676b68b96a8b74711849d03b2443696e43bb5a34a2a9ac29a43c7c316a1de1cb33b78a5b3bc04df6490c05596671d9a5ee355e4c568ce5aa73855a735bc038fdb254f2f60e8b75bb60a1bbd429a8713282eb149a35c75ba5f4853f735ce9186f7eba0b05e292805987df34c826c34dc8b63e701a3a90037a9b03b835e7874381208987c517b978a1fb0570360af357874b0a0860e6cbd4bac028a9bd2d187255602cbf599468d46844bc5caeb3a3b7bbc6d7503f7ae013d6266b4f054b95616e02690ae54c2d4cf89082790e41b60d4f865bb92584516c2014bbbfaf255d7b47212810777b6710a0db1859482ddc858a5eb6c79ac8795de152361358d895c57587ce0d110e1178aae7c881d0d21f4773096fe57fec3bb96afa475603abad868fbcc61a83aa1d71176670d051d52c4ba56b9eb87bacdef570443353c7d120fa4a1511d247a22102af98c2d6a0b1ff52673f585d09f6034c97c8c08022f75b82a7987de3506362a6785c23934242599c3175b7d8c218855c5110a22ce558d77337cbc36b9d7b69a2314264e0a22252b4cdc54857c40d5edb8dd958cf9156284b95818e009541705885f6663d2549a1508f11f862319b92c03013a1035e26b3658ee21790fcc7296b3841ea5991c5b607caa51d78a5bbd3ccb5316d5e9083b2f9b9ab1937bd120c3b94aa3bf356079592a1144bfef2650b3c5e95e6a98506ac74b8aa4996ce5dd92eb7620b7fd860af0267d8532dd1b85ad95547967627fad85cb2e798998b27f340bd2116abf155ae7baa09d8e6411db306d4b9bd3ad45dc878cff3824c4cf16f08d72ebdabbebf8939cb0b0103e6a47dc64fa325883f73a2bd8c7353938f1f81b7857a03441228d4366354a959a37637f2726e953cc3d90056feb55ffc9306f08b6202ea25968669d4597145180620da32b9b41576a297fb5010948a0516ec3428f1ce8012c664dc5c390663cceac966656cae6110d1a45d4360c420a69014709a70b71c0cf8cffb81958a687656859a8979a24c8c131d1b03e791bb81376db31562367880dc097f04c150a171445283cb4444701bf513887c917a310c87fa30dc3a49a23727e3824f5e2b821875ba8b5288a28b40abc8ba0d130953352f60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c569c2b7fdea81bde50c7b495f901c14b32779baf70c57d84d92aca4163637de873f0581b170e77f4ff840d0e56e13d367c74a23c453c847e208c85cc687066c09c6cb6c397df1232313d93a9ae45352e746c1645528a30d19f6ae36a56cd1116af5d11f6fab71d45544c121895f355657d982fa23554b6525a68a050b1454cd3acb4c32af315b19c9e6ae4a9a3791e6be07f64c1de5782ebc2e54f23782c64d74276f5f060e89c826c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b352b34b71958b0147517061a45c22b0316deb27ebc26b33efac3a1b29c4a301e48e00da82930d4959a13e763cb63035844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544aa3290dc0697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f7625cb0a1d3bf043e304144b559e969264053a53e542bab4e57dfeb53aff658db07c6213586315f57289e2bc66e49c35e28f9a5219c9f653a9f1314406a6cf9115adec8568309388e18fcc5bbe221c323829c91bec116ec1128cb39460c25876e32c08d1c409c581a9360d570ccfe323244f0ba84c19cdfeb6cc761a2e408a9d073511b90a2fb7178fb9cc096ce14a1ff14b6b6600ef99c47de431cbc7482da47d87540b3e72801f8a9b1c6c583ee73bb157a78c585b95c09a868a957709a5305c7424a28a8d731ace8759f5212566388a7fe50705b6045a945b69a52bfb4a61e4dc53f6230773f844ed90c571823c3094912c3a9ba25879d7f4135780596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9d9f630c3838eb161374710d9f01bc70d4ef928fcb1c38bed93e30f3633a05e01a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = 97912e16eb69efecb5ddd7c2f69ad5fbc628db11c4eebe7bd01e3efa8ffd1f30d4a5e39dac57494c313415c2ddd7cfc5c210c146b4e5ff721eb75ca9e54e1a690d4dbf9bc9f84dfcf30b43bf5fd71baeaab172f82ae38dfb3f52fb614cda0d59349cdd43e3b203f79d67654905f08abe48685e7325ddd388c7a93c1dd255db54bfd230412b3f68165c054931f3112095a9fd707bf29b8b520271a722c897193bcd1d0839c47b277207b720c3fa000209b14e1f6c114f9a8c1ba778d0182942904754e0a469415b2e4a4c54090a7a5bed7a5eea3cbeb98841915e0e682583d2f995deb14b2d98994c6b0be50e6b8bf6b3626d63d0395f2486b53109f29aa865e9d299085a4b4176bd06ca74cc67694b89ad39afbc8ff4b97e25e302c3df27b457a5d4bd8346e985a5d01cbd16140c6d7cd8943893703fe46420cc67e89103098e32e18e332cf0bc6ce7322be1a61b271eaf87d99ea38dbfab0f05c8eb849c215d93e1469eb447a160f148aff8a560eeecea86f57d269ba7ad3735243aaf3936462369515e516d3e5cda5bddc5d857c6f005496755d6dba588fb467a1ec8284496509820b359e1dd1be5490e8bd0152e14e54732b561cd0f71a934f2a7920e6f212082f3963e04dba6a5cd01b5736d27c2a8b40b5196fa57f71e069663dd6c220bf7caada8ec9a057373d21748e8dab71e764632a17955cb585fdb1231369a537918194b207f742d004719a84dd9226110e43cd5d3f5ec8da31e86aff1abf4c2fa512e0712d1de759eecd9f3e7cd5b90b32cee8d4b19519204ec4c8b28b9529ae87fd52b43822c7158685600c2b45517ba266032d732bb32ac28e2ab5c1d856d7caeb48540e1e5fe3924e5d8d2fc146fe5f821bd92efcda1aa7533a48cf91355183107734f9a2c1a43c5e8c63fc106ef3c8609919c01aaba3fb65285288623d5fcef62821dc24d04c8c44b3219936f5e6e87f723875cef8be4d1821f08e58a1dc72c2cbb5eef4018b324d328356c508d49c8be9ddafe5335c74303735443e4b366d51cd145906dd8d73219bef3eca694b780cb8ae59f3cb3b6bff77e76d109b0b3 +expected_result = pass +expected_shared_secret = 81fdb9267988ad39ab57e2fc8d4c280e0000dac3471b0936083aec68b49fd92b + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +private_key = 20baad201378db4baaf53b7fc750cadb1558f238a3c0d6b70027adf29398b33a6860e084741669991a2c365bc2c1d53f48741d610a4bc93434707739336b1810f43d57743d5918b002ca40e8bc63d2d047994a7614c9793302193995c18ad19af2a36721dcc32c64a0438778f3351bdb12a778dc6d9386234d82bc20469856a8bcdba5b70ab22caaf6758f29a4660261a45222ae069e5d5b7d5c835358190166c3ccbb7c46ba63a71f1628a41a69410505b68a8808d44e5b7840354739708b956a38501621242a7650521aaa7349b086a72135c6797ea4459380265da9583b8742a040a87599c9d1083b76415fccd9b83b25602eda248864bbbc9b47c8b02176f7a3a2f6bec1faa53492846ffb340b825ed7298e807a8e721092498b37e881bfb44563d606274df771a9e3c78d575865764972cb7c5871136cc990b508adba8acdf672be68927ca1d34ff7e45f70dab80807981f82ca50f7177cf1cb70a27d68c60431dc7f4f026375db70d5930206d3982ea32616b8b3393b524f4899a973272060b78d81962a6a21322acef9441f8d0754ed39370f9c03afb39800042f3405958dd5b7b60209bd9ca6a5414c568c6ad4118abef52f12d192e57713ddbb49e3d34c2f3b5941f5b07f6a3ef799553d67adf7e569ffd8949aa0a120398624b5387c3b8cf7a277baa6410377bd88cb74d814388da2cb8f96cec82a486ca962721a532f455369f269e3098a2c15508e102b0bd79e8781489291451c8a2606a34edf048c6cea76aba3b737c6b20427080788c2884b2782bc4229d2c14f0868f1dc7cccd93277b012f2e731d0f0c03c330a944725ddf53e8eb76b64b7bdb833699082772f9062e1f28401a908aa8187bf160c87185f0c35975ee1cf93e8a3e0ab027c48750b59a4e2887ace373cb34490277cc24a151122d2b326433f0691b09b3b004c21cac1914052aa1bfdc7cd09b95fa71624ca399b7f430d5ae6ada1ec55c28b9fbd19be20a47aed181c816cbfa526599fb054b6a15c529791f8101c579b9ef554aa63e86805556933c15f19ebaa09ea2200ec053f00bba05091eb4ba19d95539a620f09135fe651929f4b299df28fd9943ae75a983b544e62305fb6711e780519b0794d9af7b4acb2bff7c704418bc89c38a9e2b00ffd6854c6f41d38b204bfe220034213c066cb62f721e59521bb6bc039c19781fbb71a546aeef31b90783695c47ae2812523f84f0f462b60f3bf77f2020e793813109d25332e966231a462ccc596a48ccc22677a904e35035ea10ec572b15af3ae770abd79c72a1dfb3a988952c925b461f092dab51726e999bab44806199716f425e21441cd82919787c629c90b6b1975e7b0844ae52df6a5cc7d393ada542f78952be2b001979ca34563b390f712111a24fe33ab65265b70eca7eeca275a993ea2793b0b08adc56ba66d93ab1a65524bdb034a33a9e9f59b79f16aaf12c470a22105ea1e2ca042dde1ac61a982ed40102968437d216cc6387989d652bd59a4d88b625056b40550092a506cb4b0532380b35ddc4d34318e33a797c696c12fa540df4329268ba47c95368473c9a70b0a5b0a3360b73767f16d94e59c79b1c839b0af93f3cc57323b9b815b94f6889cba154fb0c6bfa11ab5fba4f10c83405629b9c177cad4307a7b0e72ca4f8c7ba5f292afad92c566abb319124205554fb538c6a5c630a32655ad56be818aaaadd546b1d04df1121ac167bc09274379f0719f3056febaa36aac0c926512d21530d5b9a8ba838f7a44656e868c915046ea818e19b06afcec6a14594e6a5574eef2a937731f24994ef7dab03e223c0fb0bef2a2661703baca090c50a20da05a64bd764f1f1b5ec5a6ccb7ac59e465146304c272453dcf897ac415a8895511f5d04c24080ce0a1c024815af6fa0f21c7cd0c702bfaf7991d915df9b7a57f513cbf0cbbe6e40854e42a603a6ea6524fb3f49c81d71c4ca27848f51a354bb35020008360201baa7fa2d64d269a598e3919b1076b89b0c894d8cd63924eba5b25a92b351a516c50686b2597828bdc894a08349cb0996b73b2fa0b98d0d39fd2c6952e1a60b69b1b8d41b5f6c002409c3bdd716c56586b7d440eaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80cd502aa28063835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c105c27fa929adc826f98fbf0a7fdce33c8f215b34e70450da0767240741894ffa4e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 145a28ed434adcd1539de7bb777f913e0abf3221b06b68ef080575ad4d159c7c6b2eb313314a5bc69b559d61ddea83986bbd47c8fdcfc95fe19f7e1ce5f177dadcbdc1adfd3c61386935f0fc9a0f5a2887f2f649787a9d764ce16f8cbf54650c67742c166b7a91a2629c9006014a934903b6caac51c8cbacba7edb8369d03a0013557f7fd1d212de89af8765c8bfd679d2c53a652071fb6d975d19d3fbab5b8ac46e778aa9d2b5a6e809923ae3a48826ce6970b0e7c3f6f2d76c12980596beafb127b3c026a21981391ca6e77d753fcd4ab4deba818f8ad7f928435c37a7a5ca4f5e77aa4331a5deb34b86f4e415c2a90963189560d260e850a7106f1b86701e3c03b16081f12f7c3fb6e6d2eb1a05fecb6e9f0df568ca3edb978795e20bf7cf1c430c242321a6dc86b16b0f05551e4e391d33032467e67781ea00e671d79803de7a4b0736e8b94443f677c275e76ec00c4322f879e62161e30b7d94c7c72f9122e6c3827f48190372390e5e447d9bc595c5152a72f719afbd8ada9d1797236f86e51d3acc36ba5f049150f715a53fca607bc49c65ce74550f675e8d4d4fdc0f09c3164fa48e1e29478d3150e34f0f0d5057235737c84681533fbe39265ae58b0ebf7d7a3d6e3aa1d89f020406b0a239a69f24d82ce84941a1cbca00f3e014b4a62f8dd1087439470b7a0754291c5fba3bcedbb023261894729c581c47680854fb23a59a174209ee8896b3ad2fb3f88107dbcbfcf33ce4b33f748ff202e9846ce2fa43017675b17663de364177c0e3d4295c9d88fa0af25789c8d99a87c72f00e650d8d1d7d48cda095df9c5d30b6a7dc42cf5d7cc439b38f30fcbc42749a4b5f20024df0b76f08646a9c48eb26f84c39c6b6af371f62a0d7dadef67af471b8bc2e985127c91db263fafa9715f8de54e5db1a6e28258ddee4e3a9079b80fb0ed6b69d2379fe190b3688de3daeb4f117520399dab1d9d1baed5d42fa50ad5c60997cdf463cbe4add8680d009e52a7c68585d1caef2d2c72b8c07add5c6feafe6636ccc9cd83e6876f3144bb80835303c4bf86679a3ea725bb4b91d1905cec1de6 +expected_result = pass +expected_shared_secret = 703958ce09d7d6a5bb09e88de8df95c8ee2598544d50193be50534947530fa37 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +private_key = ad411082dc4cdadc6267b69f5d8b404583b112d27de6970e12485a7b68bca0e3132ed64ace676c1e7c48d5ec98a60062757057bba2358bf8128b9b918c456a3942906a0275b8b08435b7ad16090d388c428d4b41d61c4e5a3859e2a39a80e61dc4874f51073d02cbbaa08413fdc64639da42d0529b7eb8b424951b9c879fe6656e3462cc13b7909c6471b77b878bb6006691b1c673c0dbb1435b166417555ae0347ee1ca245c049eb40b6c23cb34cec026f3da5c528001fab341bb300c2bd159d6e302e9f7919a11ce539780b5da3d3db112144a385d1a5eb7725693d0ad5c7c9a2b899cd8eb1a04031aaee25bbd624d251b865efc7c303acd18a4aa5c0538dcab5522905caae913995bb0231195ace17c47d05102c44d42287c4e60bf4e42568344b6e287be650921ac55984c572550b9174edc9ea39b228fd4b04371a233747f17a1cbe15145c34449239ba0b3b65355a23f22f26f132ccb281a484048486429258ec487352aa9c87031dad59a806bc71d5ca7ce6311194669289795b9a3cc7a2c6bc756712cb4cb8092ba75430e9ab96acd624f480bbdf515b423134044b6a543f708167a7f6a307a32629b0d8903b97c1394059cd511c2df6bbefb9c81c3ac7d15b05379e214aad30f7c4bcaad99c21e3b00b44022093110c001d04716c5aacca8812b73213c5ad4b473fd5a555756b18bdc02094ab27359037d6a67509271cbc82d3619633f900e5959756bb63ffeba3ab51c1161ab6cc8f47bb30a7849c674c6fa58730bb70a2c6333698761503889a652e5381c6a160407682738d0ba8da898885bb02093bc44e04bc5eb71861790138340ff909549596303e3772d287c77002fb441a72d543da9376206b3802f51aa72009233e69fa3c256fed0b182717299b67dcdf2ae46b8b95a08526429bc5ad5cfaff9898a978855882ae5147af390762ae335936c17de1c58262ac11329a007aa3c0f9a7b95db13c5e24874147ae010092fba13729877d18832c56c71ab9a5d6a2a9b6da5c2b59a20499708382a160aa87bc6f3b4c53ab0558a26da0b81a239472f1941cb5495ddb003070504bda121a1925eae9139af19594444a8953b824f4ba5ca44c07df745fe911f5071975a5b4952c48df7d431a821998fc84f064bbee538569565bd0db70087654203dbc0cc21bf4cba678d1a093ea8b295789d52fb25f4d78d6986a0157145d054afe73a90f25886780044d4b9a4e112259d4a83dce439739a171f5a0fab0736d6731988ca74a56580d3c11dc3b187cd688cf066710a1458a7431c7bd69fbfe67b3532386dda99b9a08368d887414423d6c90cb69736a6a021c70a4c7e33bf3169aebd7227f5fa7f11927b315a52ec3341af239cb88b8137b509c7699b0a8578a4425a0dd535eada924f872fcc719aa785a0e0045b03b24d0f5c1dc9b720a4717e0705cedb88bca8e29a76043a73a87c867223f487c6cd7598bfa4194fb584f4028150513f8692cf17aa5d1009756db4b794f3c7c3d40253991923f098cd7680887935729c4a40a23dc20227cf18c86137482b574c5ab880ebc10c312c5eaaf15870aa4b51e59f70c35d356b11fc6abe072a501bb61647694d6c02a731f13c32a27fa5314a5e641836e23bd6a28c2ae62ddd79039b9365b007110dc95760367ce6a8bc2a358d9ea04cfc302663caab8c710c9f199c2363c4627c14b6cb5c3d3a0d9a3281f07aa5d67029653b2c9afa1375e343c197cad3caadffc0076ce91df0e21436cb368d9c2ff2cba5691acf472b4df839785737842b378cf29567db475622319328dc5388aca633531272b2c164a4a98359b0e9813109640847a8605815a9dcf84531e09b6dda2d1163cc19824baf076f5ef39e67761622cb0bcefc7430c07ef8b8bc84ca8f57131974e5a39244407d376fce88c340030f33ca7c21e27f2cc06b443a12937b978e68a2465b70fe8917da84700365a68ae526316c61fea6b0e5a88813e5251f83ba394b0296475dc1c77878db73ee4671e62bb66d50604efc4a7a91b87de178a617931f9406ec952cecaa8274d095c91062c0e0004093b3e6b36c9db094cb16a34a33a5890a56e973a12af859a7a2557235c50335c6418751952c1e3b3bb8b6490faa78c81d84c724e979cc2b368963552f21518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7dd8aa653122eb5e3a4c3c877e95e8ecfcfef1ac9e0e6af92cce8ee89d09188fa9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = fe68e5f9034567e425a37f97d35037721e74eb7f12591f59c0832afb43e1f3aaf8a5e4e62f86e151a0fe07eb292fe20c6815704bd14f1ff389364cdc1233b74cd4ba240168c9de0ec2f2c2ace3b46c24de977672049595a50c79b8695707bbd72850fa345cecdd9f93d6ae416eaa79659bcb17b98a974e3aa7b03f557aef8e491354b8492abbbf2fe3f39b1fe6b1208e92dd9bd8b40b98968fefed5f9101601b79007519f994b35b300e88c7c05f397e411cb990c895d0bccc3a8779c41452aa1c15071d78526929e2aa3529b996039792b3bb4d9b109bffa00fa796d7fe6ae23d4b96dfd9a16e3d91cbc4860bcec6172208ef190f56ae8ca201da34316fa2f7ee46a16154658b6c6cce17f4917aa711e43253ab2cccaf35d49501a22ca1f482403bfd8ee3cf56b40e7c52a83de9bfce2d20a14f858f7c32379a42865ee73d33d3215f798daf4e47bbc69b5f6a49451526d58f074eb8c0238e25ddbcdd30c8aa841a94e6b0d2cfcd07ee5ac744fe13c00e0563f75f2a63af3130fc72d5681eceb45ace81c8690f43594ac1e9d2a087db9022eeec67f425663c3882dc769abceef4e0b24bc7a42c9fdbc52247b70a93aa9fcc6cb77725a5f7dbbb806fe072a5d2955b2d7fdc5338e9f15dd5b95149f8fad00048c745a56fa7feef3a630489b8e3ea4d8cf8b8f7cbbe2014ead57a3a080b59940f835ff68473aeed19ec1cc163ef8aa9fbfb7308e5cdc7a45d4fb79c2b3082f031df5081fb0f962eef0c1bb967edbdf9b4fbb4eb95e73b29a948f2fc4130942160b80b0a9e402eae296697b3236ad570b78fb1242c14b620be5b0108d275b045396c8e4561a2cb05cd8e9ff877a056731654c6c6a4cd732c8d730dbf06c0bbe494e9472df109286670efe8880f897523f3b16d15e6821bf85af2d8c01a8a361523ee30405b0d4de846fd8faec5907f95db62a3fb4dea2f05ea54bf60c70c0ba664a5a3b777f9091ffb86a8ac9b9e328768700e82b4e7ea5e0cd7640ce0f004ef4ce4a236224288eb9899aa780f6b56b9382c0de0f2a68a7f55bcfb7887726c1fbfed3d75acac91643983faf2062e +expected_result = pass +expected_shared_secret = c86d221cbc5ff6a994d9111acbfff23f7dc0cd934412b17d89f0f27e3cbd1a15 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +private_key = 58c8c996e892ffe562f9aa44f4ca31ef7c174cb24d20c683518c1361e68ca476345f19612c872fdc3307fb876096c96f5e714a5fe794b9dca87534c2e91b167b555aa9b95005c85b9584aa33f09b87b6a8620441f1228b551a29ea8788c26c33deb97fc98aa078d5cee62c5ff45b0417b8358aa55408140f89e611fc641f8010ab30c08a6e789b492cce5006c3ce45434912bdac595e4eb91b4ac820e930c4d4db33a736049f53758bdaab51302fcf0c371ddba37b808cc2830e7fa5605f77250e9a9a2f8819505c035c26b8b6498d28dcb77f0742cd8695591a176d059775c4af51f43ea9935672f42a1419a5ebfb8f1681cb9087613db276695562cc62c3f2439a9aa980a56371bc64b22e16b3e01790a202bd0e48afddb50e8c7783527c162fa838a2f32a8e153b4647bdc490a81a494967849a4c814db1582429d296e96bb18c8b294cf05eeeb4aaedd84aaa0b97e3e1b5276c4b7ab8746a717e2bb0b8f433b85f8580cf884689e4afacc61f32587d5a1356d402483ae96f6ff332faf02d61a7a76d3a1171e9721ba801a98127f82314cee599ab1c52ea948013300ae6b576c80979ec4040380394ac95b420a5c562077758714acd91bc1df8bbbca1768fba4b2b349c64504b70089e7eb820615119068b7665c2c5e5da56032cb75ed159eefa3d99a764deb9453a44201910438d0b1a2dfb4d8e7acad1f9abb9b2720d58b72fe18417200ac289369e019f9c9c1e60262407bc8c3a8478db446df952b10083a6a2b4228d482003228a44fa6a71e1255108954311c6fe281cda968551829ab7794893fb715ad90a022b51907c60ccf5156c485f50005b87e9b219c18ef83883631536323a1e7f9b4db6720c4e311ace289e20ba404037663650aeefc8a07119a9c11a67d91cc0447c4e38f68d828c430a75859db93b57f5c49566931f62b3e5e88e211c0ff0ba03b6b8b7645360243aa3b51c2514c923e4151516d019010aafe51a91ac78695a4a4fec6b754bd30bc27b664816c1d7eb35c2bc5cadfa7b764a1ffb5b48b84402ba5141fa8154e5160648177f210059fe8763fad15fbc43195581cfbb9262be71c820b270d635c0002bbc92e596f5cc0b5cfc114bb2267640308b495c33314b8d208015888159c02831a062d7967691c64b0764966762c2c28666cc1119b4bc8541f016945c200de76f6f5a83605ace8dca54585a5f115434d70094fd540aae769450aaa7af961cd96239d624082ae6a494a000950747188236a3b9b170a597cae821b6d74d7d00c42ad89a31b0383665b4daf70a95885530e315fd75888e76c1113c0b43f80b951a626c5c59706138567aa786ccb7966840c7acc5e70c029fb38f9bd3b9ecd9b11291c808b44803c06f2241afc703834a125474ac3a926a1e24a0856fc27ecab603f0a82c53f94dcd8797ee25ce4f1635e2b18706032191c7834651c1bdb21ea8630884aac48ef3287093a95f7291e9d3bafd94574a41823f2c7f5600c6bfe237e09158e848b59f1702e1b924d47cc64f7b24beb41c3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bda063a3545f0cc8284e40bfa4b99d2094727f8cf006957fcc432c058685072a5653434a92b9ab4211343f063fd44572a23829aa8b19e16a7121b1f2352813d492fd91c834eb5a8e5498cf7fc76874a3ef8b926c0d29f3062588163a24c5976bf48797b694fd9b964b1cbbdf62a23a941c99fc986710a0cf2530f11f84914a916c6f704d879ab4cd3aa51f7c078006eca60a1b53075ec71c11ce0b6d8f9769f9549c2d7a690dc07f79396bb2cbe2e0ca72436879b0c8878d0a9eb9387c5759b1591c5339662009d449184690d717a8a768f0ce3056e477a9dc822b5fa466c0a85b3a0256a61b3d0e433ccbb6a9254222fb779cce1273cccaf7c51760e260e2f566b487b8dded9049e037290d102e03019c8c0b2983687d37c880a17484337a66467abee2b5c8340534ec6017a660344083c7ec21a729c754f3cabd2218dc2f200f48a3b67a07b7d86b072e4553be45cb50a2b424c07719878d4a84ad2d33453b783ad117577f41d6ee58ce4326c4c893711d66c94d6aca65c980a545b5521026a42318cd72e7f7129c60b652ea49b2dc075833c3ac3e7cc094618f003b26421bd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaab7c80e434104e9838cb08529592a5f81b0e8ead186663db8facc569b09e75c9a5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = b58756de5763aa23238a6b3a58bfb99f3498dbade080b1be63bf73d881278678e0bfa122b632887c981aaf81476073f3b193b18c53d8b782c48e73a0cb17f96b623975020bc5b7df38e328c5424b43a25afb4746ed0d6faa3785c9e341600acd68d0ce2edfba1c82eec60ddccf6ff5b14019238329b1b8b0d76888268af21553813cb577edbdf5f74854f0047832e14cf53a403e881d16f2e81ed08233963c3d1fc0e4b4ad599bd5317780e50f4e0551e7b310ab09b06f774c2d7dcc1d531d91b5c0145ed06200c4fe7402609b53a0bbe0c4de58d8d73b86efdeccede513525a8b8dd8545a3d0601b5e9da7c3e4549630f4d856945bb5abe3e5ee920b9f728cba5f27de7bd7f3d6f8721e27e811ac7d9cd1924aa244de8c6e1febb0f8778373e5ec63f8cad7b4524ea16f7d9a1e4dc4dbc36e5742a6f69bb5ecd15f4f4fcb6829e2474caddcfb0fd8cf0a4f6538d919b1583d748d4acd1b80dc584b47e031f1ce445f7c31c10b260c7b68a9d8e1af8c08e630f0e51019a577659912e472ad6d635472a5caaa22f5df159170b33001521a2cea14c4806a213106cdb0378adb90132fc5258c3ffc760bdc17acc309e9a7f43f56e955a577235bb03e2dd4dd1d5082c4d62b5514f34adc25adfb76236a5a44a8ca2f8dcc9b7ad9b807ba078c60a9041009b213e6d0a2df02ef4d60578f9897829016bb5e3e10afda3376308383d067fecc9c677339f19dec358a01684cfe001e17583b36ab232f8136c9cd2b99c0b2d96f46da720ec745c080faba6c3eba4a0f9d54bba436729380c4e9542625f67f7fe19ef75dcfcf6cf4b4c0778892ab036af7e8572660a2a9a0728315ef4110ce8e493fa2a7c98d98f9a307e86a81cb2a3f96fb69999fb728ffcb9b7922e8bba33e283986a9caee1c8316922dbdb2d1ed483f8775b4d7cbfccab2957815e1807ca85d18d49d48bf5d50268d84f3eb127cb90c106299a577d54812db3f8f331cb21af7806bc00f22e5da3c54ad81ce9d2578b69c48134cb117b6cf8057cd5172cfaf44ae88bc6471bb7fc03e13defcdbadb5d559e16642b822d90be575aa090e3 +expected_result = pass +expected_shared_secret = c0146ba47b3d4178919879721f69ac896d6911d6e86de1e8f05797d467053222 + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +private_key = 8dc7329af7a016354818974b6814c962e91e268c24ffc843ced150d4593c4c586efbd608c8517e6f7c520b59133a81c6214baed3a8304220999e30b00241244e9abbc2a4b70d2b042c36843402255e1307be53b7ddf52621ccaac4c266d02ababa0b6567a76e2482887d6b729558a70c6931805a8d8c3739dd95c06a33b42e67c45e19aaf4d859151b75b78b5419f867c4b74dd6ba9f54f533dd51585ed89eb6a22be8757d2915752a14420d99b20d033d4840ad2e83be1207a4fd3020a38aa9e0125d9ed36ba6058551976e5bb27a170aa071b46bd98b7c4c438fcd904d366406a45589af938532135adc2c790e759a1b0713fce38888d626599a7061b6cdd0856c5404b042d73aeda2a613d51852d5526496217ffc4030d8b1d521cc5c3b47a8f513e2688d794a15ef90b7b2c5a213e76a5f652a0d4659444a1170bb3762f55ae46207cb5a015298610023b16d01624845205956ce413c217fea95dc939829434afac49172f5bd6ca5bd1dcbc2c3e94d4a8ac0c7f051f71b53501b8abf676a4c372491c39e5b83492734356bdbbf6ee8ac98fb765ae4a5b26b33c2d09d0accb0c8a3412418a30198b014d62d16ecabeb863fb037575d06b43e33cd0d857152424d9e2c3e4968cba3cb978a9b180d539b7d061fec9095e77817e93b2b3b189ebb7cbc04e4a0862547b1a9270bb4a089a957bf3c439777114552993ce67520567259b7a48dd8534c83bb6f442d652543ac9143f6450908f3cab1c47e92c83077815f5d85891f10a04f0c0cbb0cbad8261a0ed014f09ac33a9a87c5729c7067678c7887787ab7ec7a2a775074c4ea58219c10eeb253a1695d20612ba7a8a68c5719f532cf78b1977e177a0bf4ae76328d7230ac51341f7f4b866e926fd3f44996f3a14af4ccef25296a67a8b71356c2dc6688b9781efc092fda400050910505c7193003de4609842ba365842eb4e19d01fa514322a9915c98be0b48f42b107afaa383351ddfa57f6042bd1c9bc3e47a253ac21b3002004f72a3afb176c7eb9b106c561be17c4375c40b231524b95375b27982970f123b4cbae78fad99c6e6f12a6845671057a2e8e3b4c8a70e757c8b424552b1b79f18eb72a64334ffc70b2b07203ed0870f6630733c26daf928dec6bef96a92064a738b1bc57c10c965d1740b313e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fb72f0caba15c00595af1b0eff68479daa985e79a0c5734987a34847215be37729ba51bbb1311f6f0800a37670d3a2f55023e88a019fb068382902a5d94a8fca972dd291178e039f8d2ca22936896c68976ca2309838416108888f13916089556a277e6958352484f231703d120922d103d6b2badb528a2eac86e174186b3278d7f480ec2195006f36583cc91c1288894759807692f15c22b9fa61ab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0aa1f182357104230349a0c21930f5fc760b821a07aa38b021123b9160d49b2438eca5ec5aca812f96cd7574a0761cb17eb9b71236b19a88d6bcc7e4a0751af543a151417d55093f6530543c678e19c330c63c371f84ee2d07d5a76ac273703b8166e889286da5c5055961084265f2e5817879713d74186fdf56793ec6c8dbbb4dd75196aac4318aa4f773bcf462586566c3c6e980731e7b8273a21c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768ea5026b61aa1698279191b69c39b53183c2745a7c251f48d26812eb4764d9196a18af28d91c54035fc149112ba7eec9df4421121aa6132e7069072a59a8739535c9c76959f8138112d7348c9030b60038a66bac005e38be1449e3b961850c1853450b33d680cbc2a586ef37e323891deccb16bc52eab1b7a6fa13205d38963acc148435cfb72803d6054a18c0de3a217037a257e157a59f8a968d250aa1baf88935dc54272bb5950303ac68495956689238bd2b595d7cd42749ae1b38097ea7ff90600056b5ff674a4c02b26aca5cab4379f0864a24fb14f24e274ed640ae6d692adcb3fe2541b9851ba35893967d39531b0c163d5b7f131cda1976e405029614399b7ea6cad628ac5245ab7552fa4d2acb10aa7fe2a91081707c327cf88192d904287c47014a4c51766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5e619285c692532735f1582d227b9a9e77b1eae4aab9eaa79f6ce7ac2fcac831811eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = e6447c8c12903c678b9e1aed0f6c21cb820f7da79ad704d07098a1c6d2e8757478fb606d38d006fb6593f8ed5e5852288e9625a164abeee5458e88e8a1a1c0ef43442eb5cc22affda6c867bcfc605ad210b7330b7f8d3e8d9a364a9ada51298fc27d27a8bd87f8b6a7b8fe3c9f467a027783ce6f98d3de72425ecdb46c9ca8910fc01b0c20fac06989806f6b4630bac19c73218987d90b1e41a1e81a90a9d278db5b6ebe4f7bc8ce196708a47bb3c1a07f1b05c34cf9b47d07027063b6c01a0484e88726cb423905cc09de48227e190f2d7e6800495d40b5248edc51e5ad6abafb682e3f91de3667b5697d02165d0f9cd409af52512ef65c9f8eafcefc75a92647c16f89b52693c05be2c5f9a8f170ece0e0ed55fd21780c092e48c464e07adc505c38989e692add2e7cc1dbfdbb4b583c01640a25eaf1ad0fd3d241d83a641bd4b8d6585d18bddeba85407531abfb7245588346d8a31f59d115e764595231e66323fa6b6d713177e6740a9ecdfe540afc59a5c659b3cef3805acec9fd0ca03ca0f5c4e5c2c89eca46a02a0026880923a8273fc0a28fe8c9a06ced412174f245eb9942b9f08ebb7690833d24c594e3ab4ed24f405d68890dde20b6d2865f36d6ab4fda470b0e7d4a1ad0623f814a8ea61084e99197123678831e3f6881cdce20eb9176deeb2787f359b8af7e0d4cc85f9ef9dbfbad12247035ea1bcd4c4e75ccc0eba9393ce0152edb04a93a6c58989f5269d86b9f091bf2013c5fc8f2126144e3e1b260f13e54649c91a6ff9156a94ce499e753b0618aeafcc5c0e1867601b0c4e744779ea63ecf0dbb5f85781211e0486e0d1a9b1b0fc01750aa728c8caebe9e7fef5a3bc9bd6a930bfbd4c56996edd1bc329bcf2b5439055e4156404b5231ed8f30baab6ccd8d253616d5cb0cfc8abc9f72ab29788607cb8145f496c85a01902c8d22ffc5ddff075fee2569e1fef59ab5646a85cf925c899cad88159df336733f1147117522ff133974419e7c16a95406717672c538112b00ac0ec01c720fafd85ebcb898882988c9fbd9b5719ff5797002939efd139da7c1f11f35e3ad3a +expected_result = pass +expected_shared_secret = a33f72941e0947735925e5be668b3481e0cece75ef48ae6db0d66f0fb2ec428e + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +private_key = 259193f271825609668f04a250f64b599315c8264bf3104c1b23a4adea1689c16618f20deeacb02dc4cb3dbc816e8712f1192f94c7c0bc2c0f468c2243dab1f351269744701904adf53c3e50fb87e65c4abe161d15759bef01ca78586a6fe64287dc392b94b6fe5b110895402aa843abe89de0689a1674b2b8e29e6bd232dd728ca4447546d2bf29003ee47331d5e1362cc380b6aa0d777a2ef6f38aa295100fca1913e1bdf2bb630c4aa3ff809a9144cba1717f1730afd1d1439998a8bc82c2319c0d46fab3bfa147b9d691d94cc75de0a212009d7fab51a5f216e7aa67336243b2b311cd3638a8c0bd9ff8a6ef699c08374a705ab4718256d476af2ec008e10267767c3548d42e25688db2c8a3dd0874bc34b55637239fd55e2b855cbd431f3a575812c54d57ca19d6e075c5837c8345323657c9cd8b53aeb8a9566a92b12c45aae7958b2920f1574c1e34724e8009d8219b7eba2a0999360e372044e6bc5bb6c658998d307a9ae5d18928e26473e66fe2fa74a6d48cff0834de15b21b11929e4aaecd922803085b78f5551f86c58c560fe639a2c35bcc31271e11fa14d739185c8b062cac95f1a34d6a2b9461a9bf766c140f80baad13be13038844604af313be2006cf79d12f6456c760444a0399562d8220e2496c84d9953779275c808856718f5d3a3908652440700224b0039d6b9abca5a7a1403fc823179e6c0e8784cf86055627b973685cb2ab74b40e85a436c7b66a7453dacb36af915fb934054cfbc36762c17de28b48f5b27a92ad4dd4b8baa16b37a56863bcca1c0505001c45fdec718624a7f6207ec03635edc7c0c793c42e1a7f167a6aecb2a912418c0ff09b771c82e7736b08a09bf54933fae3bf34a593f2d19d90473e499971e214c963b11b427a7aed96b9413ba1fb487045b7359c9510baf04062a907f0a0b8b088bbd0aac738423c5f077ee8da99c0b8166792c63574cb2a5c05f2460b84540a1280a41aa5432ce7445e4aa1d55893a9f1459e6b7811111a1fd98640b35c984503410443f7dc8739d757f4f00d69b3a7dd90845f225932307bc2c92d52ea846bd826781451ec9a7efaf8639ea457c023088684a91cf779fa465940e25955d47a2df9782838648350be44899b198a706c6b5763c2a170c8c5f87b2f9a7b6af7cb48efe386c28c7b0b19a808f24e3e2b6b212a3b8b9a19f6c47d484893ed89cfd3f678207630c3844e969c967eba8926461a58826eff42beae5339c620607a704f91f1b056fa06910746c7e002bc617ecc64add1090ff1d1afaac53a40487b83e9453e6728cf352415a930079abb7e5115bc0745290c706420853d080377e921b5723047c22cfa289d2df186b1908a7bf471e5877fe23b30028a34f3fb27e726b99ba827d347c62997314e39a0f4b2b1e9163f53654e056aaab4718609983bb674a47642a81b000ca7422d3e361af12461b8620064547dfb578959b18bd1b61014d20315a659a5ca65f9cb4ee214b0d123113e34310c56bbd99737f0305f6f3b49f688610a777edd4a3a482163e6cb2c64668fc3aa024d789219078b49471be7dc4395346e7f87c5b150c1e7e30b9d2a435e7c3a32f7c4d33622d7b73cdda989aed858fe4c7e9cb163f35679b84b01096a1e2c3897c290caa996ccb3943e22f789d3c5098aa1a6f117347e0725c358670d678c51a0a9d5f66aaa6923a895cc5fe5c9530b069397a0e4482438e713290c62a94771f7168212a7cda8e2139d573a9ab0137443180c213b78a1b5b291a0f1566316857a72a521c2b79c660792acfc0f5a788962a6ae74e87c48a8010dd6436672817a00b49862721702668ff29f1077a87a96cc27038e0a2752a0d196cb17babc25b2996054d61c68c691c93a6520a97392830a8f157940fa903e75f909bc9691b86391ebe3611e04c9e0678c189b7875d373f0b25b9fe0a9b063cdd4446ab9aa6b23e6ba6c324cac29736447529c76c3398218152607aa5488a5e7b243a0920984b06dfbcc410679ac035ff824768168c758689d0b326831f5c10220c10911540c5b7f9a3510d73cc1153a2fc2a84b8a08cfd7f863e6c93e05f05a39da58cfb57dce98cbf1b7ab960bb14a9b86dc611045d1730f3b82e5eba970018bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab922085c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1dd3761c0e96678a959f30997e96d6a59858528c5e10234398e2da2e50ffcc51711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = 9611839ef5c05fde9b32a92a2bee7ccb6f870070884523b365417e830648467cf9d9c34f5b544ec6c646448f4737db5c78f8d7b2d4009b4912bb68084862a75c090c9819b1d765eefc1574d45f9f9cbae90795947190c9c5acdd3dcaf3804519382b51b2e1d8228d46332be81dd7e211a5c94e88808c2d0398e5bab8f5d68a7dc81ce9cf7daceb7b2395234980dba509ae47bf660f7b9449a3d8213bc73d207d55b97a6253739522cba9490e9514127350519fd67dfbc87a8e008fef806d422a70f703b34c8426911c6cd33c691969b62fabd01716d069d6920acc51facc37d58a69e2a101cfd101b3091496b301b0ea8e881bb36e5fc125f45b7df174bd1450e603ba0f3b66e331585f1b033d9f73bcd4c3c556c88f8e363c47885fb4181bff08b56d8bf0f3e5695e791310ffc5445e91dd7a4ea60e7e9f1ec75c2b13c19310beeb4a30507cbe4bdc9b5e46cca1eefe6748b095a87317c19639934f6d73d55d0be243845aa7c5c56a1ce2d432a8647e6fe9b7cda920cb777c58382ce1fd6a3bafd73c56487e5ec00a5dc0556d6a0c87185ad2527a3efbc03ee3f752dbf491556b68bca5aba0a3dab531445fd682385e8d0d3f49e54fdaf41eb58e4c2287983d013ac3eec0e4d45dbaa93a6bfa6bd9579ebc5e2f9c49ee45ee402fa8702a6e734a2c68e414ec0ff0b69a1da9c6d9ed89e97efca55901b053155c2c9d5d2c83c8fb59d65535ed936ecec4d493fc67a6595178008e1d237de84667e120ccf9f30a2bf571a6c7188726026b14672d49c9afec1c20aa2e7e272d01c09c562102e196464c0fc67a2f4edfaea9dc82000d2469c8968696f7f8e9c89e4941e1f03a9d9bd7052a0cd4be306b5cff1c666cef6c69a150692ee408307ae315a8f72442f63a9ee1bf07f1aaeabf9d473cabd9261abb8cf93ea8c814684a05cc83d3e6008d25a1e4f03dffee7303c6e473d3f2084fd85ebf13c7ade84449244e6f4af792b139a3d7c89e66f2e4083b1ee1cc8d90c0579df3c9ae83635f9a3575289f0720789e04e9e51d4bc6f169ca8ddca8e1695edbe32db5fce382cf61c6c39a520f3fa102 +expected_result = pass +expected_shared_secret = 3d77b9b4ade74443fc573c393b82c0cfd2bc2769327f273c14e66eab9f8d9ebc + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +private_key = 26f5bd7db659ea8288f5e6bc550817956a1beb27bb0c38ab6222718d6718a0022bb637b6d96304bfc7b71515398c52bdea95cb78fb43676900eb5c8644572ccc73c2f52164a9ea434d8444c94806e1495ce193a873927b78e77479b0ae91854e21f9234715a413d2452e20c273c1a17487bab18870a17cbd5351830d30bccf3124b1173bd19baec1d53fe0ba781a2453d0ca148da2349474343857a806f39d0b7088a4b4b5af1abeb51433b01a11df04806a921fedb3376485b356c6c8e059b854710bd003bd49e56e411a56a9682c221ac55cec46bc0298c8017163b29c74880441b5a6f49b6ca47b4ca7b26802a06943bb11ea5a1aafcba476334422b9a62e2469e24a64d6bcbba8a5001edc50e1b85b339c18fcf55a4c392ffd854a588967dca1b87d3639937b37bea9599b6418476713fbf45b833364a9acbf974c70203c27306065e0f69b748297d74287d2c7a14b265d902c82f7dc608f6089bc4707842ab599f798d1bb21de317efb9483c91423ef0025a2432526636d6f773ab381cc2a56948488666f724fba6b57862925b00418abd72c2ae0602ce8a8f33638ccc626c763636c00b416b7cf12bca01af7a112605f8d4c0c5d5a5c5dab5dd9b22e6fa6b5e30a0cfd90605da8874372c001b26591a847522521e8dbaaabf57ac6595c03377e64f8238e4a7648409e98752860684c00db97eccacdb16ca5a217231eec7b9a7177147c76fb7421a3d7129d05cf27d361e3b8c29abc3f46e9a578233a30233dd1e5a54ee94857a8796256100d76490e9953416781fe168680906d46b950d3a18b382c18bec8c62223a08c3cce9c406b25b5b93c43a420bbc7c5216994e88c148621294c6a3181ad5499c07f615287fb8cd9d847d0d485aa3585455231cd170e90a78784f3c05c280cbcb48d87da39c6c9ab0b9b5a0394b482b17dedec0870134102c8156d6a838e509942b029c9659e3c930aa4f6764d7670781936c303938dcc128a7010bf6962c72b86d06a497bb852fa690f1b43b9ca216efa170216c664eb82a0619944d79bc2bb698f7f77b54abc4c6f56b7d6ca2a1b036551561f1534105e4b3bf53b1e728b61cca6adea603ce85425d8f251b4173f288b2ba4e61a1ff409215046a381211a26b897479a5b1b3623362ae7d22410d9a11f72cad7c107e5659731a6c2e0e95c956386cd2527b29095820b6268dbaf16c0754b583e8288787c186de1f516b204705aa1ac8b80ce70b9100c92093c3a7b69ea8976f5c5dce45b391aa28f0640940166741876baf7b5b7c6878a87438db18ff45c7371016a27e572360c4b2fe4552af9a1a47cb82dc249f2c8bae4197de351a48cbc549e236eb895c487f27ec3e765101a2e68860c61e93022292ec7435df62a1012d78824960216c4ce18e060f1c4af2aba5e9ca9134732149d3a57f72521ec9a97d059515ad9c3add828c75c90f6300e5135cbc646af16866aca30b6bcf60fbd9c0d1a2ac95b999e0749a3f5b9a992e18a8257af35fc9f7e4bce74c87c7496cf2a7a16d966cad9d02260f630d2f1b011aca52f78b6f040759068c0f3f553a4fc0dc7c9a4c8c05ef6c9b026b3be38f0c02049b8c89c88ad01a861f2b1b142a961c62f246a4c19d2cf1849484f884119a823d793a5790420a8f74f97a220ab8b91d475717785c12abb83291b3fb32c7bfe836b7b61c03ec76f36d1c8ca01426c28471676302129116d2a5ea5d415bb13188cd720cb96939f21c7d1fa17a59589817011a48cc65ad90a7353232e8a3db9ac87d425771c7b5bd1968498819dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7d61ba11bc93007147ed613c72f756bc367280278f0076addf854e837b62c9458c34f138e576a99f8a4baf5b596d327149616dc1827d2ef5c828d4764193b4f39a4fcc027d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c5449225132b1c764e91cc686afded843dddb97213c28ed00a6e4e4b66c17074181cd26b15ec1f3c53a18bdd85a6dad68562e3b78180066b4c4c3401aa1f752685ebc8316d6bdb5291e0c39cfe778b8ce55564aa50acae94c4962cd942271ef257bf1993ab04904832a9538e0749c97790f26a09c2c81d95543b5d97667c25da1c7ada9e9780aec099fb096446c03fd1a0b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef96d9e513a7cd137583507ad7256844bcb9775ca82ef5f411331a7c37ce451181f6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = 0393719568d07dae3cffd36ff67a93bba3017a81a0d5e83c07c24ba0727ec566987890acf4c49002bae7fcc834196e3b33f944ede0269fef2682e67db70757330e3ede1d8fca6deeacc178ab6b880a3751b1878c40415dd0aaeb1bd33a6cab3a7049a7a72613cb9c0a9957096b827bfd5ad607cf659a03c7cb6c34b2539ca0e195ab35b104d99745254c7863119ca7b03c32774f18542aa3a911bd00c8458ba9cdcfb3f0b6edcc5fa51371d58e82b3cbf40dabde56152b5d4868f82e1769874cb87be8cd62441011b280563bf2036e53b6e710d04e52ae5ee4bc617b60c25b6557537b64f3f671dceb90264aa4018a4d22d9e2dbb67af3b1f03932b93fc8fb78fe4103ee9463933b73a371fcdd66dc2012ce5df74254c440e5ee491b19a8bba884071bfbdd72cf865e4afb79cde00ec9a03b16dfdff64508e3fb5093379b5bcaf11f72148dbaacab35c7e78a9b811da318d109213e7fa5f296acf4f4d1d34278a3e9e9dcb50bad86c717cec38cd6285b743d3bddfa150c7b6f2c870e311ae8eba5edb4837c85da01d1c5f3e33b173dfee1b1c9e77649fde88fbc18a1f9bd7da55cbc96f549da361fd88455edc7e1c772d1d1ed5c7e74da4c9a4c9ecb980ae0ce3a6c4260263b09469cda3bd25242185c5763f982bb59fb2a964930e919e28682bb83a3b1916db2a80d18b1c04119f88969026e13ef30d29b4cea6a02cc29ac4c0e5d8b48155d95e46c7072a25f3a71949aadc4c8d87b0ab3f62c3ae94d963f78939e957762b72f4a77c08cbdc06c6bc82ad0434448b9450dbeb77824db25e70eb43832d06185353122197cbab1c07312d340ff04f3e53a6913fc7dc051274f9081e2c9e452735ef560c8587b09b06d44381a356c7b4d6cadb5cc83489433cc155e5ee9fcc5a3dce297cadccefce8c5e4d9ce70d5ea6e21a0c96a764d5765e7979369459067324291223a8e58c274966ce4d22a4d3df52416ee6486feb3b979ec6f8033f1411b1462b91ea200de02581c13edae24d377c3b1e0d9763c444e270e5f186068450f23765ff74ef284e40a75af0ef07120d16d888c5defa6560d8693 +expected_result = pass +expected_shared_secret = 812d6c4becfdd4a95f234e8fcae1d9b316266d1c519545bbb7fab8a19f3519e0 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +private_key = 0950ad4fc96449f3512042277b505267b339a7c58910799cc125ad58785d88f60f73755c0e26582ff9becf91c8a37307c815a5a5d42ea1d10680b4322b095b1789a7631288ac37b6a8d8168d7852f7a7c4a6c178eb43840f44c9a84a8cad91bcbb25207d2546eb341963654411974fbfe2249501115d861d39b046e903bafd4c6791d75249b32b24705892e67a3182268b7c197a025fe5f0689e96a2e11b822565365718721ce6b39061cb9318069fdbb7a1eb2f7fdc188168c124e1a86ee9530482885443a47179bcbad04dca922714a96314811c910439dba531c4787f089a3ca8c7b97db1482171b9e7c72f0535476104998334a99f0bbf168683b0bc49f2d0aca698b92e285592acc7f785cc1dd71a699c4f5da0b986d48dc30c33c443638c344c76387c07bb545a24504fb119ae70276112cd47a3a15cf3ab78b760807c92e2ea23907948e1e0bc11e6597bdb5fe60236fdf4744be21bbbc18dc057088dcccc60ec17081232cf700b04957fe4f052c6dbc053da79b2d9478d2711b1fb79345788089c8c511c50890a24f4767048cc3aeb03911cd19579e26eb64380f95472c9408a85551f0ceb05efc70c105081c1901cf2e9c689f742bf2b8edd0b8403a825d1ba316a9a7b8438c739d64a55e93821b41895c07314c392016476ab38c806926879a69e2271a7b912a5e785120d035cdc507025ac7e4811c5ba6b517cc194a8dc11311832c38934409233b4917844c821dcf61a8f96538ea6964b88a0b5dbb117db4bbdac9db2b6b15723cffe26a63b663295ac3cdd44cb78488a0f5655bb0bccb7c57889f76fb23442eda09248430fd212542df8aa28979179c58fe68521b9149592b9a81b897918682addc32db685acfee337ba52c0552a6445d076d45102ad828fbe7849195cc44824168572263926cfa76031667bc2851314536114d2eb5e68901f3f20ca5de889e24c5440e969e99071d3f135582c7ece997b2ff84e0a934036f03610c62931c7773648583dc9c83e4432c6b66f1346475df3b2a9814327e1504bc69506244d5057004fd839ed07b88d94137598ad222436cc72494098cfb36505dcb77ea88c2ab18a760aa67c49228b7e5bb524b5c4be081fb3d8b92cbc4b92ccb4a61a1b1c14521ba4a898d46ba44168dc5a47af9484aeb453c4fc56eab73b0cd0407f5124ccf6b21575805e311af65084e2b0100202a1a39a866ed038328b75bcc206b55a90d714a7175c446dc2091b057ca54c111a820e8a75ba0206715a3042dd0ba36d2cbbd72326532b58b02636cae1949175bc51dc2f46ec5736ea91023657cc65aaa7c22158d22d76a304f796cda7d377c0e79a4aa683f341b7d0321b623782cb189ee6eac197860e05a224fcf12f7cfa8208054a56039485b11c1d888f51c479507b8a85a57b51f5b824f3a9e41274cd188d2099765a004bcc64a86844993fa69c0f63190c347e5f015c6bc290b39cabedcc3be8515905a37fd746616faa036666a08d537aba7a645a501f1cf0c0c8d76d07a67f47514c4c49c854d0b8d3fb02fa34abffd46620e886e00700c7c34a2a9199c78c23f58278fd71c0369b3d0288b711ec5775c70334e984c686cd8e3a141f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31eb51329c8125e8079557a63a53a8a31f245db209cb7375272d9689cd94edd20be8a380f27ac993a9287111cab084c196f4a921b6270e43366ff94af4d4930097cc847769cf3b8016e024733233e9ae67f8f1aac07b450d2299eb1c7ca84c28990377ef1150ff12b14f99b9a1bb705d719321e384399d675b382beef53304074c518382d341578e96b8e123312112c2f4dba5dc5b7278ab251bb3c530bf104783819ea985363fa8b44201d4f1c5c46497ec64380fffc553239cab6f543453485b6044b7b5049f85323d0e8614a8b5c28b52633e72c64db6d0438aceae55b8c239c6b06bf660a146c1a0b132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613ee0520dab93b8c15e0a301f9aeccedd16aa71a9570f31c3cffa013b27a1ec259e738bbd69164f5cc002cba96c68a22b35597f41fba0cdcb81729ac1c4ec49507683fa304d00dd398515ad3e92c33ed440e3013daf434712704921123fbf628531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516b252e5abf757e116a92518eb72df9f9ce66b07edf4d31be225585a6a827a35b8faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = f12f2ccb97aeeedb7dc3a81f0c525d2e7171c45ad0853a4bb6156bd163e09a5a27251dc51b0d6911195407f980b0d8d86b65a3045d52060bf1b7c1d76737e3e0e4e1a6604241d4f0ff6ec85396d250a2e61ee3f569fe231b8513986360d029e99023e8f59dda52629c589b60cd4900522512702e68f39ca61d1662fd0bb515f676c76efd31adbc5b488450f1ab845bebfb4fa53ef171f952f6c7de0264c49ace51fdac564ba48fd3967fd83f18e16d827b090b966511f6dbfc435d86532e4f2b25e2e31eee2b71e85dcb923bdca1ba0de1dd46ad8ae00a085ffe0392693329592dc8fb400eb03f3a5ff5d133916e8744a7ee4fb9dd7249764844b3608540a1918e267bfd0f8f6333d241ccae868ad3a8a5fbcbb3aec5fdd3b4bcb94d4dc945f1d02c141f3f07e747f4a481402c7ba2cfc0796d24682bb814b71983b6823671c0540db1fc64b1802dcba49346fbf1490b829972d330639a6026c75e9abbcacfb38bccf271f8e201fedd6974d2a170f6507c4020ee7a2d70aadd79340f1db2a64da4261ade72677a2365dca25c22226a70c1140f709cf3d931b9e347cbdf902996b99b031f3973efea8f17858dd81245d631050acb28df40cbdf7a159203dd8f7feebe936941ec73b342340f9a46af07fe5258cb05a70ec04a8bd7ce4b81c67befcbcb4a4eba394d7bf60804b6afbd4b716987b874d21c0cac713adc3db1ec9ee3925a4f48664068f5866f0017c8056cb59730ffac1db65e235df9cb8908376ed4e06e31fb4cef840f6503923abb60361a18ee52eb59ea32e35521c90a21e165c1235a8eeabfba3d8274364e1f5440413d5f64f5decdffbef85f7b269da98737b30e17e7f6d9ec3a2084d9152b4e2b2e91a1d1992adce1769ba0e10b2d79c4850e8baf6f14a40f7223b301d439eb1caa11fca5c43be5ddc83fd432d1acff9ac9934a0025384d8d8c23eb6491f7d0731a5cca075afe7900d028715bd8d1ee4c595fe15041f253e3569ea5814876b154c05c78b1d1189df03cad56241b49bd8ca4e9ca83e47de19657ea4b3a08725e4d45a1068bbea9463ed57c05a65e46d0a43b73 +expected_result = pass +expected_shared_secret = c8757f45a1e334ad99a0d2adf12e79ef2bcb96ea1876bc29a4ec5cd660923d82 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +private_key = a2753e3fa25fd7824843d5a621205f777c992c7bc7e49a740ca64571804a0910768ea40a6b3780ae95a6c3a0236f3a3f729c232a9b275351a3bca02f09e6828601a6e8b2900017b32da12267a856a8f3147c954574c954daac9c7f1bb90e66c5df96a6213b98f6f470f3095d6b37a3482ba7ce984f4a4789901b63c35a573980216d7098424500359b6fbf953b6e0a662ae160d056cd31c26a699a05b28106fb272119583bfee78e86d7bcc430b28f071236903e39e3316341046073b8d27b1370601df2d901347682527c7cdf4875fdd6c0d3330f51334fcc8946f2363bf9c0b55798a81e4c9e95db7550a7535b1c909a5a8c353b67efbc3892821262671abca02797a5948e53cc32ba32f2c5a8823c84b903c9e7d50669ca6e499c888b64be5b59a758711d49022f4604a11e590fa713135bd521b594331d2783a4d958a8f7b42893a16ea12f2173553e496a3c4089137947a0e55bc20c795ba12d81032118db3bb1363eaa92c24860c72f424836043aa6085c81eccfef70a85e981e017045a1d194f1b76128d1953e92bc1b09a708a51227484928505a4e467c3cd508b9d52591c8659f27bbef053f8ee8a0fca26abfc4a515470545069c1bb8230c58b33f5c591f27ce6dd174ef1621dba035e4c07eaa97a08b92c6a3b52d3b07a6cd3a58518989e9a77ca7125dcbfc7936f506e7d65a9df7c761cbbd67c35dbb89a04053b97eb0b8ac37b22cab34bfac91d7c83850b834beb5c034fc1145b93c2339275dc47bbd828df71b41c32666350ac4c4e3087fd64bcca47f3d0638bd26cc2309578f7c621b56ad0ad912d84054826a02540597e73bc6f015434a55c9ff8c446c23a35820ae4cd220dd3aa454f9c9c153ab640accca49c4e8fc7d946b900ed68bfb33908374382de59d02e4abb581a688f0137e51118253185ea19784a683bfd6845578a348d7bfa2e5a35cdba7bac582926b57e8831c90b3c6b8e6cc3af84556d34e5779bb97b0b2dfc316a54bc57c112f49e9ad3ab98b53e31256996780323656cbcb60522f9edb4593676d9d67c2cd729626147e5c37aa38903333c82c17f97b68517fb17496bc71146b716e9c289410ca7ac5fc5f663abb1b7672f8115917c610dada39ae344dfe805568a0141b6103a9d07bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326043258a62211ebb3568d10b46b08864b637e94a38b132199001a5f34c5e8dfba0f853980f071d8125c12ca665e72673102c05d50b28f71696f90c274e74cf57cbc86be00177930fa0a1164a245d57b4b2fe6c4e0f740d87b8695da43a98e79b3b102efdb35253812336c1058e727e14c08444f24b1415312185b2afb6ccd9b5920781ac0b5a7a483125a1a2300974c429e7957de3a796a48996f1579982adeb538dbfb8867a855059622fa7394fcaccc507013c910c79558b1bd4b5bc696052005c8c413253e6617ee827bc31bc973bb0bca2d6ae0b17239c1210b4866f5802086460589c64963a83a3ef18b5277272030079b3c2015cc1544985c687a438e94145838a14648c5ef5bb46a0988f42e124397bcfa42a2dff898efb586b2c6aa86b75b0eba10b2aba678687822ed5ac8dbccd49966e2f1991e09260f547a4b0d02a6d9b31ed02bee1764f7a5085ebf51fd5862550e0a19d05a78a80276ca0414ffc07b109afbaa9ba78674b92c5b6df20a153051a3c2378b7d05882ea15ac2183a62b8efdc15a9063b041bc1ba601bd9c16c6156c6e4ad82c6be595152174d1527a6555b42086be9d05945a289ee90c91e525b8a69324aff21306f5375d0934b49677b1f288d1dac1d1918adfe3abf0e738c81b0087e22c1b23aed4d742c283ca5530a0960122cb2a79c0a2966c5780034297fb4c1569d2b73127bee4e53016b04188599bfc468df3b091cc0a62a0832137127eaadc7bb0176baa45788e994cb8983c7b08547d340092594cd0f05d3baaae475092c3499e73d16584daa3e3f31df226c30aa49e59313e5dc98a6eb16f40875fddeb735ea6cafc657db8692d28c35c69022ad1e53418c461dcf46d5a40046193ca8277b28ef606a9e152946b04591ccbb1b7271940105436644e275d6f4503b5a32fc9907bf5c98d7f90623b822feb0c033a1b90d87422453a0460087b81098c163c295079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d018c081231277f424c5f3f1f6b4db91958611fa28bcf09ccb2573da64547e1958a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = 7b901088572fd3d5646a8085fc48026ca4ae5d33ea65a51deb6ce1da3d23c4dd748b2ce6d24879e9beab75469b2c31784d5074e5d84e933bcc638445bc01603c6b6c916ef5b3fa0847dabe4c5d62659b40a3e80686b91d1bb274d371b5860c56d042a84a5e0bc2b110a847ec6f6374f8770b5bb2e7eec9310709c8607fc09d3074ddb08a48bce41de572f2745d652f9ac11fc7e4ad465a6b09934f3641e6ecf60b4474a18e176781279be819d7f3a0adcf19ecd22d48038b5f1090cc24ca9ccde889c55c599260d84d036bb7b83697d463c3d52ce6324f6c49ecf8d6f3cef3d179454e6ef23da5c09e80830182adcafc696860b7e461ae9b3a62bb55c78eed94c94f5dd01c42a5fabb04e90faffa1983e6fff3a402f84ec8b400092527a71d613f6c029f92367b67783434dfc83c5e10291983712b66518074780a7d8bc7555e2e8498cee12317d030691065c80a12ea4c2fad1575bf85c2d44b3d90448638db148eff07b07d3cb6fbfc46e0172b9a9aa8665ccd2c53e3de4249f2b3312be8632942c14476bfab2d40ea748c2754f36d10b4a4982a63c6c3618b98c963cdffb219088ae2bae9f4948c61ff8bd911389e8aebe635bc40468d802440c6e84a7e1af45ff0dbcef205bb7da3412f2729b4835c123bd09af81f4edb9931dcb15e3b542e812b0c5d5467a184fc8d858284ca37e3804dd86ecfbf414d18b5975cb0c9effea4fbfc53700cfb32da2a9d0603c35a635d02e16cc33644eb7a4af1370f1052afd81db54a13b65faba18a27a7fbc22c0cb2c6b6af2f1947f6dc3b53d1228b577151e676305c52a5b38156963565404f8b7d358519cbe9478450712b4022e4099a3ec59462fb256ea125a8337fc5e5dee4ca4b68615d8d29133b37d5946f0d022b4b84036e5057ae75fdb638cf8bf5257f11fd2cd55795471cb1a552ae0c533a04f8a00b343431a7fc360474c9b2b5a7e52dc3a0812082a38c235b1fbbc3d960e1149d7d1a816005cdc62d56d7c1ebcc55109e48342f56af97405e3c3805883460e8078510d4f2f7c9599f4dc804ec76311ec8fa6759df7e8a94054b04814825 +expected_result = pass +expected_shared_secret = be765dc236062da9d3fef68c645b9a8a5494c351d37790c1e7cd1089d97971b3 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +private_key = 0eb3ce9a9448f8252e9e4178b1e103fc9c546d5902f2449f375a877e7461d602ab4f68c2ad47b3f9e90ce9271833d40792845fb4c38eb8b231132a7374898032333b8d427272a4afb2c54f5e37bc0446385541201be25df5ab21b0045bd304b62a15c14fcb465e29b845e457430757e5902fe3293837b31b43655978e17411154de442748b1a69d0b728f273769de1544950a69bd4558e032ded3abffa163c30705ecb290896a9b08c34a41a521ca94ac999501c84e89dcb30413cc27e105bb81d88a3ee3678e6a40af492afcdc276a9d67bc7e87aa5d78f9d046ba453c1cd4c26909b916ec8cd7c3877c5eb3e5b4028ddba148500381992b76b3b40fb374a4e45b3e87ac4d4b1434272c68c948f3e777777c78db6f506b79768bdc6657ff298a4252db310025319b0f612a1b8a3509f32418984193d540753da22f151724b264692620af8f661a180109fb0718ee588aa7443f6824fcdc3c28b523b2e822871e32deae143d0f024c7da5572415fdcd9af004848f3fc1fb5b38c0b3c71f88b4266bacb56d38b20538cca1a5eda892e334315213ca163c36beec696372c4d7cb28c2e8a82e96930fdb628eba59e24e208e9857cd63351b6f0911d8618482a41ece8352ada231dc77c3c7ab51e6ac73fc7700fc97a3d3c14297705dd4bcb529247defa600c6504eb38cb7c00a6d2956a3a14b21cca2e6013b954b967050bc5369477c59a365a44057a00ae8b746e57e5540b7199fe200c3917adcf914cb1ea8bafc3cdc2a53c3f70c0ef29394f55cd799c44d309d0a4735bcc4a8dec7160a35211141573eef285bb0c11f7d828d2497f9a63446150c179e6854429a0a2d09a78d4b9d8c73123c2411f2ac72344c7f221c7bf9c3012d6151b496912551db06224bb5743df435c281c3d2cf77efbe606cfd5b79b2ca45f02bfdb123aca61a4c1e512f8017501e2bb68c45585e06858e05621bb4098d870ba679e541a28a380bddc568bd187882a051e34bb8f36bcc8d8f05c4777761d8267241308b0961a267a7caaeca84247421fa8cebcc2b88ad9958ff61aa0c2cdb7f4b0041051254112cf7bc9b130cd26fc457b8ccdc1a7ad81ac5db25945132a6c152b12a29c8149419543a6bab0b8af5dd272c5a7b19b82199e943c5a12280a22453ff36c7b698f40d092e651cbee12cfd3843c07da95fb5168a4f9ae4553b149ec3f0960199f6375499372247cc59f4719916b168f02574e1cbef360cc18c3ba41a3258df742d9f6b32c076f695a7da1479790d9a1809001747002d8f488cd54be71022e134a4e8a9aca21570351248a4daa454fb201b5e57d15b30994b374277b3861898734436c736a2fcf0a9214661551ba8530b6ca4f36a74f8933b3c2bd0fc89b78146871c8849b31acd0fa55726836f8a6a2a36a32d43b78f94810141c6b18b4bb6763290a289ad6363f08816c3bb3a2e519a1dfe276f6814b7f693958f4746ccb68cd320ae60c589ea94023c7adc3c680a5c17075d772b28bcd8d109397407b60c2a7ee00758d7c52630ab0f686b510969404cc1a9110338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed0a283f71912b69b40d6a1f84a56576a02b129409e2429d44a9b45858243279a5fdf07f00e6392c662de780a5b8f82ec6dc248347c9a02062ebb67eb33457e5d36f10fb99db0171ef0949d117be5034ccbdf951a46c7497166294727b59c4b63034435e41c75d70641f800f0d458b23736ecb76bec2702b152389ce91736890af06840cb8d9b8f375a33b03438e9236fa3a221f83186f77aa388c840e2b6b9328710a2092faa59eb8aa2d59769be77046cc334f9704c8b855a787373dbd77215f268946e5c8792aad13e645f292bc73487432897c50e817a1f15002f472e404298a785b26f441ced2b5c7235c7f3b4428d78a7d47cf4b83561ac38da9cc124eb40b44b48231c9078702510326095b2b3492b82ddce7a433e97c65878f8fea220459bf77a81b8f010ac66ca102fc14fe804680fa9678c41746211444d85aba5c57051422c69630acfc7b86a843a74127effc452035b41477ac3ea934008076f09796323cc9d1970864300e5c309f3d7a3419d25fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e40ac7db13184d6ae6e21a14a63a2ab3d6d5d1ee7f4a6011413a0295b752fd2c28ce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = 7bec5e9049219304153fbc35e29817fc3d6d454278f6e0bafb207f7911fc725982a15106817c7626e3925d992de0f1c50d158d3b37fad4ee20628a8d8aa4c8a12e47d2255da69699f6683c6c09e1ceca8e93f3a6b8fbaf9bbb42878931a55d7d2a90c8b48e815fc54ba065049970c9e4323627fc13c908f7c939805ff886b24a659ab7bb41b6f34589978b129d78a95f3272212eb3c51da7234a9e46d86d16fd8fd37ab7361be0fa74707541f635dbb9ad999d671e886f3c391fe4c5dbaf3df0c3562a5825c00357db49720cfe54ce633e10100c4df6fd0ab987abe2d83ea800cb750a812d7e202e2fcb0290bb0b9ca9400884a9107f540504778518b111310526a756c155f107b5f460b5822b61a15b601102f979e521d46823aaecb41500b9aa1d43c47c9fc312752a2e41ef6659d2c3f426e354ad932a0398138045904c53b90fd388d93ea2eab7bb6c0abd6ef5db66d2349351d10ce1eb8f48e4f4306254c44bd798766efc3bae38c4a70f6e0c72c78e76c990b6766b2b2ec349f3e86af0a15d8fcd0c78c6695852be0158e9270605372097054fbe92f5c347a5573dea1d135c43fda7871717149752cdde8daebdf3f901cb70acf4bee19a77b8f1f191beec686265699e939b5693e0c96b8f8537e26af0366f59e3cc86dfa4800de586222e4fe021f92e01d837383bcb66bd217608311a539725d260e96e31cfa76980af8397c0c64362e17b823170e483667453787f31eb4afbaba15e37d000c5677298e7055a09a3b4d0e8c918ae01b17786848b4029f802ac4dc7a5a68cbc020b1fa27aa4c2c48e3042761faf8735bb865e7c521ba2766c11989ee2c5b41ab4d072134f2fac550ecbeca827e664faba269ad09ecc163dd01243580d29e735f04a95dfd58d314853ec9133361033b4729ac1fc7217e13611c486e531ededfbc1c9f3923191dc456684fc09a8e3842ae6d09f42da68df8005ca7735c87c075275074bc98635730fa518c866c52083314b4c31eca355e58382e4d2ffcca578fe1cada896d046a48fac96aa341fa097716cb05c8a3cfa1bea7ebbd7ee2dbec57e0c71da59 +expected_result = pass +expected_shared_secret = e72888e8dc5fe30f0a9c01e2e4599a7046147a81da280c393a48bee1b43bbb5b + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +private_key = 5a3861a9a0670a9ccd72238832c63a956965df07b614cc8073b95c6a3375f9b73e32333d33e96ea3140aeab832b523bc7d55361aac727dd3c22d8059062c37733c241f388199ba39a4f6a08b2403d14b760e525c85a87f8c732d1be726cf11295010bce0384c37e1ac73787d17b2b5aa4b094cbc17b1d2ae5a14ab12d51d7f319f3928ba35ea00cec1706be397ab323c13b852653bb6725121e2793e2f19cf1d54c95d8b7d7520cd63350012e2b815d1ca9e518f7089258a3a217aa1a9d3392bc9aaabec9668a70403ff6c193d2a185f8294da15c9a1d1120184b5fc7a3dac62c1909913f68741227556aaf6c3fa58426c99a5ab8ace5b1614c23cb079084d310a3fd6f738ddb86edca4c1f975508c394637b94a57e60eab053dc74556d950353de0a0f8207f2efb4e1b34642f8b7fd836876f41ce5d152026a3881c375e2a613ec610a21363cf0ecb42f9a7acb0000035e113ad8bbcd279756f60837f9520e4f907c3f79e34b5c852ec3f33b432027076e6968eaf11203f7461548969b472487660beff441cfbdb0e4701804a175e121b10466a51403c095e45517c481199d62ffba850e8d5452f43857484066f7513f6a24289a619cfe14889585271f7aace5b2b43937255d469177c17c2e636d2909f4bf165f49b102e20c1beda46026a14a993127dda10ea989a05cb04f546a663f068abc4cabb32a7a4568023796c39329c9cac6183d9b88e1625c603378aa1c041d0c1436105ee284e30f24d54c79fe332c63fd92e2928892e8401c64c6982b7607127882d633dc87335262920a458938877496976bb122bc09cc40ff6511fa29320fb581563799dcd56a4d36125b7dc5731a3888b3331dcdcccb2dc21eec146625854cbf863b2e0091334af76a741b7db1d69116e2e868d21d942eb99c5b24a9139c63c3c882a879a2c5e341177c149a7f32c0540ae2a9c3d61a4692807afa3469e363a6abfa18103923e908b7d7028497cd3cafa81a8873c7064a7a1c3b310c523b3df396eb71b0bddc12a32cab323017fda4378f919cf8ce660d8a8616f43539f2aa8acf74f6549743985865f2673320558ec426b57e36419124bb8516c6b4232728a1ec4f1a51dd01b932738d9b00c6a50cbefb657969b4dd318295b6278f73963da647156944423045978c50d3c078e6d0729e0219352028970272f34147900370d490c12fce9b22357bf72fb470e748d82b79859133d8db603ac7cb2672ca9c7226b6e99a7488a219966b7b897ab398002090b4900acb068a866c50c3867380ff5eb2e0c9c4eaf497adbeb79632b0c023474837709a3d7cdec9c2f782c9a3ec0c6ddfb37cb3321db6315f0b0ae23e7c6a4e291baa61e4fd26c98f36f69d75369f5af277124295158b2506a39eb43d1a16308b71f3bb5cc26897df2378837d9cfa1ac4745718fc3739f5535c35e07b461a8cd65da18a3809d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcb41d00bac933c3783f05c47ca28058558cc05690bae3c507fa8d5780227a61095f0171a6d826f714146c934b80e07672e6bd66432ad1479136c06dd1a29f00d18b26ab9f8fdb7e6021ce7c657948273268e6b65245101952c73d949c4d82c8144a3dbfa7a82784844d57b354b1598076258fe83a23987de29261b0a8761ae3167d035e96b78fecb9bb51055d86e46466708d79a8b732b686a23b7e36f9ce07ba6956cc46bba61ce934af8ba7738bec5de094010aec2885a8153bf71f002c9eda917f337bbc18da2324b45bc79127d21b1c12774c6fca6a5166c4f03440af4520cd09233d493461420e5ff81ba290cfd23001052a9dd3665121392224746064f00f5b1a4dc19528a7b95c524304aa21164a45c964a7320d2611c68498faf56cfc195373267b01591e6c0a8d1bc0007ed456a4e205c49495ff99b1b1754a9e429346536d16e015dbf7967e851974b19721e845008b76b2c47e7c3b04457c924693bfb6007c918c64cc28126665b01cd18b7a253bd0706d3c466eac224fa12bcfd60417afc1b865029b672663afb3ba51b6a2b20502de6c6bbdb33a0ac4765f967f8d685ef1200ae1d17cd5b47aca963f2ba5cc38059b6937916566a219ac32157728dfec1b9950687ff543169a96f648ad2501948316b55ed4c1e861661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f527ea5a76294070ab10a6edc502d82be3d240672e5fa61377e73e5e19d11f64a37f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = d142e18d4bde68a0ae2591fb29bbe402e1aaf696a66958a5893c12198e950572959be34051a5b1658856699711699b1ea084fd8256daa7670d089941d069d19a321f2fc93cc625a727f1e7e7364a1993a10a03bba6c7c1af4f2cec2b12a452ca1720029d758559f271e6fab4343f96129875dd486ce6c6f14d103284479bee0bcb5ee6921688cc3794bc731b9d0916198ec510de76fff04cc27425b141fbf75f7e12fdaf1aa8e6cd097eab34c1bcca571df37d7c21bc12db3992f74d301762f8df0353ca0dfb827e485cdd8bad1f4a4d0094e008f9363f6cb0c8f355a42b66821b4e1b50fdc237fc7dcedaef8949d7f0f4b287c2c61548f7ae9ea64b7e8f4231e48bd5e37615c9fc9e5847ec4141f4e017ca86fef3f1df6ccd9c4116b4c8203caaf93155d57e3a243c0fda8e817a62609ce9e3723c39e4bab122db3fca8b738e48577a323ebb23528e8d8b69ad9ed322a23e8c4b8b423d2cf6ddf59429751cfddc32ce28232aadac1fff70352b37f727017354c7458f35b8702f15e2936eba3413603ae0ec0c8a17dc39cd1794972001b36d58f0cc83889c51db6656e85a68c6d6d4f4066b91b72d595049991da088bb51d29ec2cd5433aca956143470322beae2e60fad818e27d6da11252edc1fe5cb11ed8f7d0dc857f948ef779c75550c265fd5119bf95101ecafbee7fe603aff7f84c6875c6a48879c581525e479d456d0866024560b215aa572ad31776b2ff9ff1aad59fc013b86acde4151a17234b4b114b90196d0502b3d01ef71d00d6e8db3cfee85f91d8be6b650327fefb86ef186d075d600c3240ec81fa333bef3a0917e0d5b8dfb617e9a1b813f55c4736c9266fc73955cf9fa3824a0d7195ac5b356cc4fd8c967518d5e0b025bec7b2b2a79578a50534b2cbdf0e4b85e9cd69232db99e2015d8d9b4af15aca02173e88564c0f1bfd5a532051ba20cec7d16fbfbb9d83f01f885e72cd50897e6605e540c93502bd634de0b0d9849eedea4c567cc8ae47e14def90ce5d7c0dc93082f1a2ce9773116cda4d59da564ce8fcd0e549e4c8d25efbafc4f0f07a6ed7ac2aaec1dc04d4 +expected_result = pass +expected_shared_secret = e3f13c77fa9eb329c218e1bd5823d6e07249fa1b455770ae57b2a00aa8c69c5d + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +private_key = 64dbcfc86711f74046a26641dd9065f197ad5f2c8f62056b9a2b027452b0fa07241085ae275570f7b248878bcd2664764b76a810c401b16a2de82177c0b93c7f204823643fb92978ef23a81199b9a5c04966d94d59a13270b32afd858f61074bd14b6605a999f940194a127e21507416158bd22155c7c46ae229c57ad4c1d4517bf1977c47a73c1e05998352a9cb76be6d17329ae9b1e42a08499918029ccc4ba00ad507aa10a18d96c5b4c40a78a9f23162f20344d61811323feed16ddc8635f14c9ddb879fc3c5678321af658cacbd3236f9949ed2f1b56a94b05fc0cec8d737b434c341c444c4271faa241487c130cacac5afbbb0b7558372356d5555839d89b9d3a47ae3b9cb596920cc0c19c97c389ed76b2b04c6a764a363d4229989c0d82986889840f4fc716a9a0f08530339b89a3ce468c59607bc45215e771a7e7a86a3880ea776a128b08539655a1d83810aac7ff0c589dfe85cadcc91aef6268115c5e7275d4df19264e98a40275b66f00010f54ff231cdd62abf2dc8cc29d6c3616ba123156049f667755c8a58e93dfcc640eb1a59c6f49b3b4845bc00181fb46279a02219937395318f3d943772ea71c965b15c272d5c92cc71e025147c3a4263bfcb7490045951dfe91f027305caecc152c09150b1aa4893845dd4330172b3db2688a4fc6d9fa9776c988a664c3af8c5a081c9915160a5b7f61b1956ca67b28a63560762ca8ce9260b50827be105bf45ea56fd8a2c2831abeac08f1bc808fe2c3654030d41507277638dcd06bafd909683e6ba5408a3cd358ce90c69a0959fd39169e96bab584b4cda80c6c0140574d4053b109bda0c6e05060628240c41ca0864bc0c516c6d1c45c308125377464114e82d67958c886c5bf0d17b2776a7832a330356b7bd936dcb23ba530b8c63f8583a8051923cb408c01fec645726608130a138e6306d2ee0842e917617ab464712035f088f8f759904550e2e0681f95453bab9c61d16b1c2d64ab37c9f787b1976c6755d27c9be181c44a5bea47b9a6df9abe394b894106a03569e130c6fefaba53a583f7e35781fd5638f5186132c0116d85b965a81b1f55647985ec3f58023574f49003f67d1847c44a40d48a2d3d86a0e66505037b1a9898be7010d98c686d496c646babf8f998833620e287b7464f8005bf4acb8839d93a311e99ca4f889b123b81f6e740b604cb86464837be291d1f4a919b07dbcb9589a228286ea1ff56554a818439a3c8f1753b459dc557ed135149553d7d82b1d8c0fcdacc3043729d6ec9511c6a3f279783a2a8457817df77ac945450732d148f8964b83c16e7319ac67acb7fc903501d466fcfa22ee13a7010615bb7a2edad26fdec633397516ce0c36d2288ef1fcbe2e1b459348cc6ea669d8810740b2b7581a9e1f62825d80c903e57d40732abbdb7736e8a1a1ea9a20d217d55b5355aab672e61ae0d183e660c182b846161147aa1426e34269636406cf142cfdf43982a076be1ac956e114c316a7d6921674f6cab0fa0c49c91e01ca7ff76b61d06c13701892e208390edc717447a2b01c8a2d855c7487c37a0043644b26fb3a446774baeef30d1a09a3ea9680f52449df85262437b14afc2b4ea62504f443af0752b97620ba8145b396ced5366dbc9447c010740614360401be32903f2680817542b356a7a6ff830e944b2af872779f34911d9b99b0a98f3198198d73922f5567aba3b8a55b2341fbac3a2a3dcfb46256885331417f4eb8c209c235921a440e8695032247600c885a82acbe34af41653a33200ff59794fd98840f94745a607931c1a8a4450e67cb23a99b46a4368b6060b4dbbb5a394820a16bb139baa15af551b40a6b01232cb99801cdd4387f23ad6dec96edea64b64a76fbfc35587508733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddc0216d226bed9b723cf846aee457b0ec23c59107caaa49a3c879b761350ed319a828507bc687561a87841e56f37f4b4f6f77e253988f38488ff2a1e9b07257268a209f9b31705bef791236ce9c193f2980ad38c5b9939189a618598ce90f435221214259c6555c7041e2a9a12bcad5b86cc04842d992834425a10a3411f5609af68a525290320cc1cb607974c6d19b662122245991efa06cc6f075e84f2b025018f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa09859898462f05bea461adb40faacdfdde363c06f58bc756f0a8417df63a66d3a544d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = dacd0804d8149dbd55daa5fb79bef7882172b99e1c7cc54be52017ce6dc3fb63582346fedec4d03341a5c26eae631ff62048ed50727c78bb5e1c3198d7397629d2d9bfe9c29d8c22661478b011f69d0aad3d0fe11535c1efe9c787fa88cc530cde42e6b69d4a767f753981e3dc150877851ebab89558d2cda3a9593da09b763cb196b3a1d6b0e94678af167ec61555e30877e31c70e4646238a518d8f590c89a10826e592bad0c1380fb795d44536ac1c0b42e9dbfb52726846b01c3e2e2d55b52f7a6ed8934f6841426d24c6629944749814a032eb3d9c2558cdf0eb990c1837959986a02feeee7f23c611fdcab8c0c422f4ae42c54a21ae3a1d36d25fa911bd48620f6e0d6609324faed384a866ef92eff8de2f672fb0af5ffaa3cdd2689c3eacdf9be6078822c66aef17a03b61b2cd9af1654250a199dd7920ea0eeced766745346ad8ead76164e46eed1df0074dff91054e79bfaefc3df98139ce4875d46b506003172fa69c7ab9d0bcea3452be59c56945323629fc0e6a34041b86a59a44460e5e175ed8fd34f9ee485937bad889ba5344aa9139536479650366380f1fcee5ca33902167bce90ad9bce466bda9c0a8dd04ebdf0dc67688853c2d4e5c6710e867d3eac14a62651be709053474264b65739f7fbc725dd2c9c94b8e7589ce515a741d8955b10f9d447d0cbe90fcbf67aef7d52488cef52f2422968a8c550ff4e85e552e3ee3c8c7467eca1a0b6494ed3b8bd0bc1faa5b8fcbb055c8986912976410d4c0b9e4a81116480207d5f550bbd78cd50e729f4c34a367cf88a5f892770f9d12633cb0faaa484ba2bb50a8f5e0bf99bf26c25b64a3165da9bd53da6cd616fd8209d0f87d80233b2480c1ec13ec8814c0779a4fafad00274ae3b51d058ed077aa3852c0f2b86709314f195c7d35f20eb7c3891199762af63473e40efdfa9012585fd6f19158022e60e5151ca5f091c7d5a28a28aaad00cd15ce6555e16b9ac455e15ce701c2750ead3f933e03317948a2782e44df993802f5da804e96ce48359ca590976765bdbd7c9a3731dd33fd9abbf40b0e9fc494a895fc40bf069 +expected_result = pass +expected_shared_secret = a8498502e012b5cd006e77fcbb9fab801dc3748a0da37587dcd41310fa945e09 + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +private_key = 4a057f90101eabd7270e3b51eaa016e7c88b931bab7839776aacc82fc99530e8544a67cf487c002cf289c57c0e2a4811ba9b168a20b5f78208e4b615dd9354ea67c919673b6e5560421776013749c3016974c6044d3b92f585856437b2f7b6627db363260a0f6138445ad21f527592d0facd7c40bcec70c75c72cad891b66ff533ab40c1989816b4c64177b397bee52a4a8ca07cd64997115d339cbaeebb53a2fcc42f851a6c88766c54b0c6744e41e3c1e0c6b3547ba890129641fc10af94ac12c623f44490967242f9845c4f360bea0c3aeba99ff0984c8c2872ce400f8e924c77741d8a861bd2bab8acc4bce2a34324346aed98353e14b52e27890b984102943a7378b641b6c6425441a57c9f1d594cea351f3ca22b74ec09f47714f7b8b41c186ed6548c5b141335a503701459b30017f364180bb4635a83cf0cc2b48293c0e215239241c656664082e97402478d1fe39a9194b8b585c3fe024abae8a60ef70db89336e06214621ac2b69114d8f0a03e2993715241e2e7b45b852d0aa12c84e941137b17a6379b30e31b64d64dabb6935b758aad601e0fa980331319792072cea89fc4819b54f9501602a0c46bb31f9a5165e5bcbc4453b71a04af9573142c3ed98c3f88e83b0dd4c2f4370915a71e3cc5c29e51c9cc1cb38388b9812127ac59aacd5a2159f34f0f40acc0712e106c87cef441deb6089c3196dce4b6b81a559c0bbf7e4097215795549b52857868c907a08497ad0042bd128460d1c88d78b29fc76ba35ccb7748c6cc85eac37ac05a63e76ce24a81d9888d42c83796a9890c09a604ca6e5ba596a3575276474a63224e0224048911bd501c60bb34871581ca0923bec2790740c26d3babb74063b9f668ae037c0a656467eed87b6f6a18158c4e9c753cc6a570043a278233121776198006be0f28c5744b98f3e33483387b56b6ae138122dfb46d0f1014acf383fab60023d619a9ea7a3355536bebcc3670c742c52cc9312be8e182de09aae8b4bad265c8cbfc6715664dd8c67062db10088b6d3905a5fafc415a0337d878cf4feb29fa307761d981db422b3e5b80ee9accdd08cb516c78a4619895f576bc8b3367f99d50aa502f365a5ab881d18044150539084a918d43a002665f4dd155c6bb9363127412dc05df9c9c2df480937507210c8a1a419c9cbc840e54a0734c8a281bc5fa709a2312798c998b9cec0ea947c0e9fc128a51700a21be8841395a2552ffa4645dc67212117131db3b54989bbbd5569ac4cc7e43b4b6a012ed87757f46a8382ccf1c561868ca741e51a554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759ac091519aafa6a4367e19b376011adfd48d34521e47b10bf497714f6464388121f46a444ca791ab9b84741518ad082153b2944d61a9ab8689410a7424b653443a9089ab110dd83d91f07adad9ccb6bc05f4a34133248524f5347f2473ab0c18b2fb3da280a8364464cbcb1c62dc7505b6c2cd057de444ba218ba49eca1142281e971bbdf531cabe6b7cc6892ab7b304c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627bb09f7dc6609b18a3c92badfba6560574bfe70b4b3578f1778785754146aac9e2a890d368b7144e7b95e4516adbc2eccc82e81627935bc455d9397ff14828a8c0a84f5a876990d909c481cf0668f9787b9f87b7604b392443d4d16a0f201057d578cb7411532528c190523a06120dee1a291e55d0fe860821b9647d289158163b19748a1477fa31b3e7c048cb93287a3d7760caa0a0bc5c880d6723ae61f4fba744808aae2e3742016c81d371638b883447a1e3db611f241255bfaa48811397989382369ce7a59a3a17c559fa29ca4b7a6751526c1db169dcb7fe00a146f6033cb44207836c405a4aa1c1274c9206537c1b767c9948c533e836a2bc7373c10c7b149ec2cad5bb515186ed9865968801dfab0123e3ac729681754265e8c9a3e9745cb9a770b2aecb473631184832b086a7a2217ab2d553d54aa431567a52f25078c10ac6f206e1e198df76cc6f8828b337685fe84abc3151bc6817a98c5beb0db1b2a4a28a7580747b6330da24561c7ce37d8750952945ce7731983b62a1025f322b515e47442b05a01955b4ad8aa63856345151c8142718e7412ba20aad10624ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24a24e6203d9b1aa5cd06c44f048da7225e33952617f12b4289494b3969857c2ff8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 788ec4bb0436a01973f78f3dc40c682ecdb3aedf218663d3574e8bb16c15a8c80591f02dbc1ac351aedade075e310171390e991c4e53acadb3a88e2e0a1ef969197ccef2f7587c2710f48e60762bf8919f7047205a722c0313083d4fc2fde591b4326cc171c05f0050eb9fdbbaa2cf2d4c39d50dc20cb3ecd9062ccfa4b815da7c210371d8fbdd63c2d8054f4da1c8fd991e0ff0fcc55a3c84588ab7b4c4d43c6d00251d401783ccdb1735a0bad3d7d704698e3106da83148ca193a37d0661175a972d43076e085f14e0f59e43d808a99d405fd3d5058f679cebb6fc9a9046ca0d781cbbac8a21a80f4faa82c5f10c809958a6d5125f023b2eed70c337117ebf4a57e98e1e23aa33d302e07fb5a583457e3c02418079e12b9857a91814bf36c5cb5db7aa4ad1852f320868b273a3086fcc2356ac75c8c0f523985c6222c6916b4fb5bd5c550bc89011fed14ce52843a3d18c1c635bba2e22cd57fd70b51642621af48d4e9d83fcafd8530a614ec7c41412eaa2d8b96122194b134dec845b8aa2d0dc54637dffc528285ae31cd2d942510dbcd9079dac55fb5ceebccd795049585ace5b35ba34859f1fcc7335522d3fb3f85075cb7e9d83ed7acd82be9c899266a11ebce385f92bdacfa90214bbf84b20349230a6328f07b711c8d3a9b5ac946d046d3ec485cf57fd96911cc9a4708cf706aa8014f05a3adaa5cd0c6a7fefee494df5b7bde7d40d22470c078bce8f56ac7f1b2bc4bda00365c288a2d8eab84cc35f22efac50076484a57f9e2120ce7550d8c29db5338aa0b823f503dc34fd08e0b19c6bcd655acfb5b3724deaec23bcd7b89155982b0a62f88935e2bcdd47a2289f573b87a7f20c5f12043870344b028fd7197f67f6c403576dba74e482028440ea6f4ca78d81aac3ba453432170f21b2bd2026b837251e828a19a1ce1b4b301245d373336c89194730f5485e954bbc4f4540abf5521d9bedfe928714b6c8f3048ccec8a8b66e6311a46af387ce4da65df7120ba680bcdc6308cda175feb18d4d563a7b8a44d0712fcbd4beb1403c036cd7ccc0d2db0363cf885bf5e585a9ba2e +expected_result = pass +expected_shared_secret = 780b2d0ea585a6ea41dcf43197b9ca4648454e30a3057f0d47f6e79a2bbc365e + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +private_key = 7abb8c9d2275c12685be83c95670454d46c2da45a5ca2c80d033665dd6844ec49465993f8f48513cca870a2b8b80e83c8aa712ac22cd62f0912456c69950a50568ca9c1b257b761a0a452681c484af60b78f7502db391ab51a0099262ae2d65a161ba0111991b5ea15e355cdf0eb5c84c49319169badf29afe15215712299935c2f52707a7dbcf5656568c573e3dc927593bca24c1c7343c268238243018320929c469ba99a7335500032c33ea33a337abeddc3998c19b27f92f6239148a7c0eef419b44d5b2920064ebe56f629319944a11a16868b11887cea11f1d55cf8981738d281baff1877be289b4527eb8a71608b0b292301e4a170dbbc73913203f00573711746f2e021e70499d25559b8a009aef92a661794381a4abdae16ba2eb8db69b67b5a2cc058142b3b9b14272bffb6c22c33008a0d3b4d5981254e28491d81363b24d3aba3b081b9bb7d5522ceb6b77c9403acc6d10db063a68a9d49200c1d6752c36249339ba67f74f79434e75f4858b756387a9b074f32179c958490bc2e6cb10b3615059e50c143bb5d8e3c374e44051c646083c9daee1c8625cca2022511c1b490a593ab8436f76c31dfb8270720b21f360cd8c405a1185927f2a2be09cb81a2a41b4389291a56d7cc90c30699b3bf131da3636e9fc0bd4e582b6a14653d838cb2370e58402a86b65c58c9c70a3ba0bebba2da179856c92c730b4e2ecbee0169408f781b7388b15a6480a3514c0ba5cc1c2545f6547d06588305561b71a514031a5132654f980bfe9e85d5f415422e2815de7c078229740e122b876380c4a80ae6312484c2df2c0612ef55f44c9723faa06259c94947067e54cc3c4651d85bb316ff59c462a67817517004437add183381bcdc554aa820118742901da442679284e0590c4df360d45e428a0a47d397c38b45791fe63b008d2b7830b1eae24005172311736745f935a43f53ecac4411110cb7c335d98b2cd756158bb35c14514c295139c5d46aec9dc377cb0ce7f2040b0852a75fb242da10b6b2a2a152b71dc7cac18c26b2e308202b44d42f17e6261cba326252fe06c0735b647bb2857178f4476049b9483f4357ac027b219226fd5a9c2b9da1f45c9036d55411bb3c8f941b75a844baa7388ddb811abb4cb13d003aee4aeab466a592b77041bae4733b5f1cb6ce2765778b02455c5536a02a2dfa640248c6442398f48a5b8ac7b6e2630b2c1e872a3e752da777eb4607875e0c771f81ccd633961a5c9d5987dde31439dc131f536b083709f7f072dd75533f9c984f08c7fc952878f2b9720da006c3b60f5298ed3921205604fc6cb969aaa69c3f3a230b3865a84a555925c895c58fd19c3b98b7b2d2acb941a44b7e519c7d22aefcab1def18429713772285de2ca225b5489466322538bce1ed99e9dab3443e47a5ce5a9b284008865a4177666345237cb7b796b9582da027d7af4ad28f558e4d7426caa80c3a19400e286799caff5b4bfea5cc04631bf72684983ec67943bc955582575f399fa5c4bf125b65bfb3f2603458c2a1b23925193f6b322a30bf8a566c43032e722961a09386aa2459c249415cc675e27722fe83d53785e2d817391485c7a14c402879a84741b03a87818295dfce827926b34cf045385f26ea08923b7462c5fcb7348bc4a2c207c5d28ce8d71b77d998fda190c41db9ea45351e35c5a4ab51d42702856e8cb07839b89a22c851654ae0cabb3ca66fd0007942789b43061382079bf9b32d3c07d1d903089a78c542113cf086e7d1319fd37b282974db3c41b08e1899fca1ab7f6358ad204a0b937a9d91266da6ed5552baa2535c2ec0efaa9a606dbcc8ce013c1123aceb73809761b0b7523f8981416f819d0803453b58c2bd294ab55b3abd7873371831845a8f4449b798ca3d18a5a4f183b4b16c870f21d36f00d6552907c11c76c547b10c27913d9a39e6340b8d4775a919868689c19e6cc7659c5263529e3f840c0182db1698fb43663e4545b9695889924b5d27a41d014cf8150bb46a59ed6c3890e087b2cb043de68cc98288a1f2bbeebd4ad7bd0880f86cb7093407f393c6af5579adac1f5a35bf08c07a12810b8d28298383ae6a298398b022ad50be3408ca5d11adc6510d1e561eae2b62fe5968e2c826c99a7d9bcad1092a559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcacb2e9159ab5225a75d02268af2dac89a0afb33fe83a45f552e2bf542868c0683c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = b82636cef6a36673297a865d6378f217a3f674ec6ec49db5876a9152c39a09fbee8af20997b04b9613fda009ca49fd502361885f1042ce04ca01327401889f171b5ed396f5f9dd4e09c0ff03d8d4b4b53b1beb1ceb77f16548e21d7d0bb819578fdd9013d902f86ffcc95b3953e272582ea79ac71344417847d7f73389199118534c9965003c48e5a1068e620e50e204b71ef15c76d5b4d23a7accf642fbbb9a501b2e1e6322a4b9e7d0e59c4e866680745b92d930e4f881ec5aa56546951139c69fa11fb37bad4bd545461ace438ddca88b12df72b48430e116bc5c94de41dcb9d7e22902d1677cb02af69ac7e84d1486e4ef00fb9bb9fbc6a0eef3f538996fd0009e68cd74ae8ae461a222edfcbba2f57f3edc49ae381282eba30ae5ada18d44263064f2abdf6bbe9c4a455b48ea433b94a262609a2bf7c565120647c2b75a593a77bf558d0aa4a772a9b29691f4eb91485815463dd403950150727de1887e2db2ae1e842bef00865dccd68345e1b42dd6a8ade97a2e37c4552277efd99248231c2a5bfc9778cc86863614c2da8b742f4cca2870e354b7eb287090514890a9201b198b7a9f81c3cb90055fecea93b61e8d3fdbcd3029e750561405cd99630d4d7f609cb2c9c28d3caaf88536ad8e70c931bc0a98591c1430acfdd604564dcafe564d4323592d4678fb6abbd435b7bfbdbc6db413f5fe6fb5c8cc0ff7d05bbf79b940de596d493787ac99380fe94b3ec5c00cca2f9d75007d5500e3c6d158e4fdb0a8b5563547b2981cc4ddb001b58414df92df3970922f8c2498315615d67c9d7485654766cb86399a026752326ca77ed639db1dbbe86dc5ebb85b42b17f9073be257c92e60223e20cee2a329d1534502ac435452e70c8be71a90c0a154c4e61d610297b38a5820da37d4a5ebb54eedd0ff7ce4f02f98aa8acb58d2570f8f846b975edcc1c1f8f97a063f27c3384a1b581b57b28811bd2156f0b2a96080aa345e99af2d8815db7f3ad01fa1dc969cc60a358febf6d590bd3a9a83bea0c345ad8dd1e1c7b89b53efea31847e1b94afd65d261eaac1249d05c024509d561e2ef +expected_result = pass +expected_shared_secret = 7832b351d71984cb60e6e548e5b4edeedf9749f8b3bc96fd208b6bb557251de8 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +private_key = c5e71ba70a7fbd9046d9657d4a704a9bfc795c663cfd48c95f398aacf1bff4b47bd2f05da81a44f4d900d8b80ba98a1049a83a477012668207ee088e2e46c384c3623a201b651c1aa9a97fe2628b0cb21a94e4ae83514f97e43b23370aeb0444f1a806ed49487096896f629a115cc1bc34a1943347fa4b4237978c50d23e57e9bac04a996480404234c398d8c9d2059278706e72244df23c20111b5f0a94aff729663046025b52ccc67813807b74db53521d64cc88ac6bf08b659a4c23fad33485c7511d6b2ae6497b7766a1ec455b217c9818ea85bbc117a385bbab3797664557ab9675c2858b8ffc46ace6a6a35c70006ca066226be1d5521fc553196271bcd80231378016e49cc2c90a90c531ac02b39e4b1754136be05bb653f3a7b17cb9d0a950b2c04f75f46c4a35ac2c2031d813ae2466149a657a5ae189bf8b898db71c51571993106daf6aa096400e78e129fde3a39c3a4a28d37650078b80a505f656aee9b2c04c942fee7542176acb9f532feec5a047c8ce2b18832f252394d73845305fe0ea9498da4517d93ecc63836f976b0979181e0c4a821a9bba5a62fb27c801da1dbafcc7d3cb5db4e8523500be1318184df976f5c842d5950a9f26015cb60b6d9368554a9c6737b47b44b736681fef583aefb2083fd98691ec4343704bf5bb4aed8c1f99e41558cc72d549c493463037b99fbf8b431233136be5166bf522a7064bac3225ad790998f79bb510c42f0726e95103656b4503fc8af37acfd471bd2314247966cd20d95383b8214e1a2b5aac7e8201312a53c663fa163167afade668f61779f9d82742e9aaa2d25a6c4c1dda295f45f33beac46502f503b99c6473a0904bc7a3fb410f1122a16d073f2535b991729bd29159865b592194bb3855ab2899c7cd2a477c0ac24ce6642004b34dc26173d11b4eda8ea0a60fce857a9f7875b1f0574535a605b5344160c813ea068fdccbd2839441d80a16acb5733c2625739db723a71ef0a8138761b81a7cbbeb679d2406f50557945a12e099466ce4619067a61afc113978aed60025b2bb855159a774984f02e92875846bc60b5b88b88ddb2517569570e3b33d93928c62ab5680c31939a085255311d039144ffa338bc7633516c32144ab0a85869d0809b7ac8d4e4b6e6df00cdf36600e4308f395c1a9821a47126623827c489ab73a68104caa3f75558e596811417c966fb38ea85b703fd13004db91e1eace232664c06a8e85a35346b56a83e89aeea01cf009a02223312397185d9c801aa5672d61a56ff22b34016b7b2b1c20b7b739ca5319206b1ac42fd991c2fd959f63471431035830e122dce7cbe1c416e5a69d5a766d7959b5817177e6b29b450a7ce080969a3603b738b23916265852c837104499c8658e8cab078bbbea91b4a9e2a5394aacd8f2bf0f94107509c69bcc9b7094512f6a4fe9411b3cd77200f63087e4b205f40d9d08a6d093208bc2311a299e7c722c55f50bf01a75bff5bcf95780a4496e00431e6978a6396c1232ac08f6db5a2ee3b5cba66c67b0c431b165fe83a62e0801a3e65f8ae30b0f2477892133bf9a1d03d4a68b96b726392908da8c554b32a5c59a839661e77c6fcbe9bfad441be0bb9767a2368d216d1e136ad5b334f775c296c1bd69930dec23a72dc30ea45636bcd242d5f38b91aa23fed98d7aea5d2d173d33c034311807c480981c141821a962c92951fdd77906817f63000b966311f584b31bbc4ac3469cca648beae1b4582697acf62a832a455f169e07860eaa4856240a1e48814cc7393a2c7552b29911915250ea677a7fe3561229421bdc31c56ab2cdf41fb16040b7f83e198a581fea0753ab8d388b677e693fea102fc5e99fefa215c178ac1a178e64c4227743a98f428b80f91bd1acccf8e4c80df483c5997438748155538edfe6445c7026f7cc1fbb8016260a0d86e19338d7255d84817929a026ac9c96bb215f125997e311f0807224d12322156bb4e320404bb6ed190bb4a1871ec9b274088b0d584a9d405f0ac08114391622f893d6cb8f9a11a9e19c803c4365656129514a49de618aca46b47317785be7493218a5d6f879f121bd1a852110c5145ef7585a0179fa1c1aca7c4b42109efef4886454807bf40a06064b88b740d0fcab975b5d3df74ac7bc20f4f8265f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c597f8d36076b3a8aa13b633650726f7e907806a0573402ef3af129f611def1a813e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 0abfc41da2386424c0c4b6586a07f59f2c7d9ab3ec74d2de590a3ed71309afc09f7c559cd66b91a5ed6a433c631a7317c0fa6d86574266de0d2be9c7a3b5bb01899a1c7b2e5273c6087b3f0dc15cac701d839723bed0146321729e3e770359dd8366bf5c9ca0f31ed5870c44fcdb026a2088ea9ba4ae8746f339074ccbd32780b7b7c8ca777cd161b289822199aa83a6b3357a134821b283a34b714e065b298e8e636361ca3c151e799b733e7da84c1bee4344a23377c14d223ae859d98d8fa8289115c6f08929ecaed4c4433c5ab60fb7b52cabcffcb233cf37b9918f9f0e6286d2dcf266e8cf3342593de1231b2fe16cf189c00af0016191b8e9e1de850491816896c0b8845001088b3cebdacd5cb6a5b16fea748ccdd4dd39037828dcfd4d8b4e3727d452dd2c4f073fb4b61b780be277b79c439c5aee214305df980416f95c00697c1d5280dd142b8acf5c656c3bc4e2d3d180aef6fa133769e781553e32b6c36105caebcac9607818513d452c1850b862ab04452871d75e7e804aa14e555a5e18150109ff038ae73cdd10fab0eccc18670fe55318d10c514290b90e58125b6d07d9cccecc2f68b488637c2e26b795ead932972f7f7bbf2a377174beb7fa06c62b705b2622486eb7cb13e8b7f02b67db3a9748af941629106ffdfe38d89cf2e6db22bba2e6c77d3ebf639f6f2180e84f122de7d493789f7d55b46a8d75e0a33a7ea09552aaf53f82774e1fc4c9b058c84c8f344d5406c1a2ff8e31b730b88e6865deaff9279ebf60cda70e8a6a3d80077dc12bb6bc4c9ceae07b3f4c5abc3fcd67b3ce815d2e256731590d75821cacf4880506009ce73cbb407585a61d9e3bcf68c46ee96801b696732b76328657194baa4a043e14a7f2296d3d7530124fb2b3229443ccc019a33ec98c80c62f33156e04c2b9f52ffd092f6c8799fcdcd5e1c2c5d5a5fbae6fceff3f883469279296657233b8f173e15db42b0bfbfd1a843670a46467338c84c10456a9698f50618d02a1582f297158dbcbd20173fbd0d5d07b5e4b81712f3d7d1346cc5c42061bc9c1fdbd00746c662635c983f70c55df +expected_result = pass +expected_shared_secret = 468ee020867cb766cd0a9ce1bfe9e7dbb56ae66c131a4540f211837c1779e11f + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +private_key = 4dda3333b34f27f44bf9813dc1db6cf44514b2eba571b3208f1209bf2740d3177d9bc40cfd381bc045a6e371707342271cf861e5f8948e2543ce5c72c377b80c96616a677b2ec143f035a51f0188a5a44f0d5798b3d9ae1e4b381e038dbd854eebb768b6cb1303d88297576575a5814cdb58f91ac9b9ec539fc212ad3ac108108eef061afe15b4b751057faccccfc3291d002ff4ea758e9c4781436967881d3969ccabe13789d65928ea3ca697a3e0e4499c0168f9599ae8447ee892094cb376d008979441634dd9475bbc3aad9a54ef37a576e551455196e627107aaba907eb57ed2a38a5db61881b99c5e3bd0ec9205ae363a40473f2e83face2bf613b3e87da3186a2c60571bc36dc4d1be99e8c42ba13745f180833880042bea83915733038ab250fcc32dec0c7b531bd6720a94e3c9dd784984f49cd19c14e74849f3c157b1f708160e4365a816936fc665682796406ab1e213dda2130be82cdb83569d6739fc7405090193a63cb0f31c3a76500a9f1c31663643dd55050ef1b7163768dbc35cc4de9adf01094bbc44556f681cd83bd1b44c02a90323832b8f6d3cb6f706b16373ee00762089b85bcca993f703b1f4833a45497de593794b700c24cada428c9a82627b5f5663f08a440a473d5312ece374914376749c1c71e1b8a17315432707d6db0c4560921989c95d414c9ac2a28e3f226bcb608fd69ccdc5a587291b132e4597184871b8885b22700c1f1780ccc5c27469ee9d811ce1a0880573b7fd392b19374e74ab457d8b1ddf5680852067e02838450209ce87e8fe14b4c068c51e526f7e31cfdd7b10a642c37536926ea6464d0548876610ad3ab54e6a6cdb60d8f4727b3947f03bc8a06897ae8901f686b7b7f96a1318c2ae42bb73c393053343e18f7ccda60bf2f5275c7259b8a6a77b9c9989fac317d9230cce67f14c5121e91a61e9306de506989e96d3be6aa5a7c6198912ba89457b97023872358a7b21bf2198cca4653fe125188218236454dc0174dbba7a462657c56507cc0f02309a6477e0ba6592bcd48c26c414c776cc126a346529ca972c3f272755612c12b185900914fc65434ab614df28f12e7206f50784d52417763b09de06a433b1665ca88c8e303129901536b1c99d284f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb0108323f8224d5b6936a2a0ecfc0874d6139a9c300d2505a2d10d926b05cbe404e5e764a1b353bd5c34d86a1ee2230387857f97d0ca13382f2ffc8ffb23933803c52af449c29042c4ccc7d06a2c3272786be7cd4642588d90ba7599024428c055c2ad6232c02a83a27fa7150c1c503dc421410ac376056933d3305f76bdd399851e8952c110693b99ba35dc3a337b9bf6cbc370c6a69f593add08149d88606931b363a470b2e16b3f688ab1f1478b2b9255942b86718082a2663f7939e893a5dce006da504f38e98c4ccc36432a491ce18217932dee5070ea27779697274457bb6930b4cb34297eb39c01923cae32835aa7803722908e9b3c6b488a7f46676b1c4b4218720423a809116a41e59577c8c89afa582a8a8b2bda1009bc8b48e58d08a1b418f954460b8ebde004870bd0b7e082d3c7af5ddb4980c2acb9510a12352312991368295adc166bdf522ad76a59ffc974e4cb04ff8034896bc40a8ca508300e411732d8e729b78006d69482e1704ee70c4e8576c003964f6ce60bf7d5a2029c03a8b778b65556a70c617790c2541a9a8f37b23096401b984c99e7459dc38436d210e7186bc7f070ce1574a8c17298a82557612c19940cc1056b92b2b13a8a2f93e83d635190ac1c5e093891aa3cc6d9a98c5b30793fab0aec423b09ba6dbff15d5e8522f86aa877000ddf9752f17b082768929ad7ae1122c2da818db93c52a1d921c7ba26fb857d3ef1c11d925635f050b4a89a59262438a7a7eaf30fd5bacaf319ce957b42ba7a1de408346e393d231ccd545081ed338250661a65eb45d5c05c5ee73c99538a7bd4c65442a14759188037670746906b35484fd01b89526dbc94123975087402b558d3c611040c65a9a2cc4c38f4a871b1a764a170b85b5c12cca551e6e466c8889798fa0359149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a72241af2b01254922a708038e5c5658e2ba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0ff2044ee6a3bfd4f7033dc4bbd6283b534cd3fbbf1c4af072fea1ba37d3262d581c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = 19f22971bd65f0cebd5616ebeb36e3fd46e48411ce02feca526f85ac9f66bf1bef78727c27c5a9ebf272d4662263bab49ff27c1b80ca16166e35b3dc923bb3602002001bfe5d77e2150cd320c3ff1c266d2422b781446d626c252da9568ce0861ff8ba507ec0aea2a9eadb200312604e6627b2523f87d907c8e8d3a104da98b3b2d5761da9bbb0c31d8de239f0cf5c803c90f6eb487fd0751d5a364c51005873724a0e85c0938126378b256ce616a3ddc367bd4800d68a114dad7786a4b1357489e20f0510675f229a6136ec16b52646d9d29c91909c721ee41a58ca53a9e222f8d3807e24908d0b93b50732332506ce9d3bef5a0bc2eb640ec5073d6c0c090f83afdede0bb64421cdee403869c5c9a0a6a5332fc3e235d2ed0901a2b2e25b9c14e3beafda2fcacf6975d7696d8d77be066999092570e6571fa85615732e578a1dc194d286f6aa40d92172ccfdd27eedd88f7ca49cb4b47caf1b387ce71754e1aba4ec433c7e8a89b890dbefed95203d111a4d6670081726ba23bd83ae8a8f3293317b14676bf3b02332d7d702048d12654a44981fed2e8ff72582114e646fc17b4a25b078c7e5f1b43b377a2a01750281f1ab737488e2b7fe9591ee4e87331fd0f5075ee1e69f4e89f556e0d567bead916128bfb44013263e941bc0cd388db2003cdb07f686279da84cfe73bfc76e94097295f6e2560fa26529f196efac71774f7a7f061f4a36d28c6dbd7651d2bf1d088b40e5afb1a0f1fe18bb66a861592041d14b87cb2a07c63cfd8d2dad7ca3a6cb8a392f1fb964fe0ab7271c2c56aee3daadaa67410fd15e80a2c59c3b93dd911a849f8d1fc6dc541bc8fc9e5b469856850fcda9c5c8841f30b73af5c2d29f11302aa36f990935a66aea62a5f701eadb27f46c9960155b258324dd71b2e1c786768b56ad2c6501a3e5940b859972590f893abb0355cb629969b23d9cdb7e5d6233a523bf327d58bd4132ee81fa245cf3b87b65445f32e07e3fd0184e909289e694ff19ea46d49f2d939db5e01e5f32cc69d5f749415af8087133aca54d5a95ec148716a577db1d4984fe34375d9c4fd7 +expected_result = pass +expected_shared_secret = f04a17a3737285f2257a6374a0057776ea24bd731724851d12ac2e06e959fa26 + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +private_key = 51d2207e7c29bd90868c00ccf1cc9179e99895d90674571cced7860962cb546069faf329fbd778e7f95baaf5a92dd8ab57321dff0bab97542ec5c408aca59c31882b16f3139e60bbad6c5c67c75b3ee62c22002093a16bfe30a0694046a319a08867225b3766a81231ca95bb1adb6086e57b3ce5a47979b8cbf690dd79296f1c4b77c98268c68dcfaab8ba3509c7d1c419b56187c447b65866e0a7106e33cc3f3a36c8381baaf343c1c9085f7c893531a56d47403fa447a34b4eac391b2d2a15c7f051720aae6d4a66221159cb4b0f32508ff5b8a1af3c08622a7a799622c35164f0a8c0a6b37e869a60eb454cc6db072377064c0ba2ba48315cc76d884aa9d7b6165d0b945f82bcc09c65d6b85315935d98954915e127d726aafc7c7c9db82cb16a7580a6aca450b619d2a983052407ab554c3acc0451c5d008098d53a7e07677fdb65a3eb1b51d74a4f863507bf513e55823ddf927d55218f4390c3a672a37a1385cd43654d28bead7bd93a764c99198cb940079e40031a36029ec42a6863c66836bbf15a29ec5b7b1c1032e90bb5114b2b91a4e50a7a193e80d05cba17d5b04a6d82b0b2186f4402ed49c322356c43af162896b04d846a64a6718f2ab8dfcdb516d354bebc75ef403b049c1829bf7643dc62ac426ce1346220df94f5795684e81bbb8854ccb19b6044253b9ba7ddddb1123c83ff575b2f66902baa287b54b9daa8a4917b248ec139653ca970bd936b5aa51e70163825ccbee184d2fc22078253070591c75e67651b1286d755233e715e4b85f0f4067b4b43360e37cd76ac14ec203b2a853eea82f9baa3e12c52463a78e4f59293279bd1b1c5e35f1275d53bba00b0e8acccc373b2465c9ca2b039586f4b43e47acaa991b6cd26b998aad77f54a6952b67c7a318fa9b6b3499ca8517a635a7e88a75a111b0d78720e98654dd9302ede58621aa97b941a52b395b91537a8ba246b342680b5890b1f911f9e3b360d1241666203dca693d6eaad08b782da628377420d0091af7f4027bb4b920e345e9fc5c26732580fe63a745ba6461ab376013a4855a088404c998038dc3a093629b44f771560c15223c88cf70005d91365e13c0040a79377468104752a66c4aa268aaeca53817a449353d27c75387d2a14242331bb16ecb8e7810d76801bdd3122ef9c6407439e5de3cba26a91e6c314a9fc543ac7cb37fac5f4d24ada0067cf3c97bb195834b635c9b099992c3657d55573160e26874fcab1a8febba997e22843ab7a7adc3106897e2e9215351014b2dba6f68074770b5afcf4b5bc9abd72c97c03e703ef473ef58bc8ca8a6ff0fca028590e2a44a85013415b5c03f3a301ac06bf3d95691664c9d0c76d60015b0398aa44f778473c09746b50d770331c011aa51b1379530daf2ca17fc5bcaf06c59e792f0b117fa2755e1f371edbd17b584ab5b5a7c0c7ac0dd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b063160ec596b9fab9953124eeea8484ab8441a0b2a85b481858a2817e04c9e821a703bc9e55c28643a04e4b431acd7c9e54368e7e361b1f23041439f0d24760827971cd52328793e029b634e792c96fc437d396eb61a08422279e853bc2501bd6cdbccf16958bf4bc133438280e8b28f494a83f61f365646b22cb238eaa2554250aa27202743bfe6f4a26fb2234aa80bd7142caf7646a5874bbfb0900f7016ca225a7f016bc015c9401a87ff339def0bcc7e95197ff4be1728ce9fc4986b58bf933b2d2ac703ac0823ae701e3b5717f74583c5aa5156b744abe535a9dc1cd42873a44c3acc9080aee873fa975fe78547bad901c929c008bb6e9ba24af9d285e7c139a54c72ad525e92384d7d650fcc40686404a8c931410e3c92daf8ab090b5fe48c2435ec7a8f21295c2473eae893c6c46b5e35868a91c962d15b4565461f067ae0036cad3bcfb3b23182fca257e7516fa25e00056144768311144fbf526e43b0a9ef797eb07346d78165e71a8c426abf868a5c251caad2c4a038529211c6a3937098a48b7dfa9322d30723c460cf2eecb0c4b752cf310323caa7ef39779c7754574c6a06a2b9a0a45e35d3732d490541fa7ed66ac5d5b007fc1390b1591a0f19a4dd9c8fb0d91275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568c7ca6ebbe17f30f8ce49e15c40c1ea5456f43624148eaecc9f3018f7beb96bdfc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = eb778fc164763c5452bca98dc843c9b1455df5ba7de8e61394be3074ddba1bcc9c2884c1035c20eae1e7b346211defd9500f915f976a41e74e5848ea63295aa96cc9efc973f2c02a399ed0111938128986a449459d9789c5f3660dd530199cadefd7bfec96acffc2597f12ff6888ae840a17dde142ea6b2f0be4fea618ccff524b7367e1d630d04b3b5af2213d1d76511d0949ad48c99bea1a93407dc0177e5325643ab6c762fbfd6c3b8f0f357626411fc61d399df4c3e7c4a501c17732ce4c5c459a411fe61133a85b8db2f791bdee6a34b9a5abe59691635fc8848017ffbcef77fff7663fdf409e09b716c1a76c30fdc8f95f02e19a4794a21b626ff31aa458cb581e3b700c0d7797cf86774f7e97ed9291399b4847e5b8aeba723a333bc81921fd34df7349edd3bac264badfb0f4342237aaf7783d59fe60669a90a8a2e12b33a2fe7cdea19d41f5939313151889aca63c79fd9aefc857c4034a7f943c0eeab62455c086da18ecddb2504480d421f031a324556be7d93e7d052f5e349b0ff41eec2465e9b02203e0286c6181e12d0d13b3814903ff0d90d44d727533cd4fb696a7c3ddf7bd40d390a9435df5cc710dc5a94ee9f885fa421b1141362391558f6719e1b80af98901f0eb483c6e3c9bca40bf7a0adaf1db8fb96b41c1902729aa1330d4bb17358f3489a6671dbef7e3e60845d214568db16297f1d32cf6472e5667a82fde84a0bf899459e295f7e1653cc1117d22e67ec8d2580b8373170938f38108d5926449f2cf6228f2f1148e42a3d33f7b66c5fcf954274685c5d029b8d19efff7a6f2e3c3ca707252a2df047584c5049de06db510aa0f25f6c40da77c1a43b74e426e5fc685ebc6a2931d34befa497baeefc5f0c2a2c5ee08894db083ded15f78c47db0b3a0d91adc543f33199e827fd0f42ebedf2e9e14d5a43b6a4d04bb818d116b17665297c5fa9e08fde9beba81280bcc8ce8b760e766634a4cd680f0bb179c1fb9b607ab12335ef50ab4259a1a03aca82f6dda87bc14c31d54caa2b6cbce3baff3857e40d2e4af24563b81fedb9a829900519bb8f21b136ce454 +expected_result = pass +expected_shared_secret = fcfab6cb3daf0c64b4ce007499f097f6421e00905fd4daca7da7a29b9c8f6325 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +private_key = 57eb9e1e877cbac8750e89257973465fc92528081bced98496d43331eab13c71848f76542f873121412e5b372c6b8613c303a9389ac2e3eaa125bcb1e1c6b84742a7c5245faf8c01a2a826803a43b1f82a568574aab051fc1067191a36ea724b991b1eab28b08bbaa79ad243dca24c8270655794b6354381ea57745c858468161b312abd8e28018ab6007e9bba3c458ff0e2b94b48bc04bc8dede533c8098b6a95204f28944fb55adad3084b78096df75a5ec44736520a92fc2444e3a5c4a69727e84ffdc8b33b6385fa42368df31edcf57a5601565ff82f0f6a342fa310c9c022a6d3a6e3d870f5e5b6977579fda405c495ba300279ab26897022680d8b16d196cea4ab53c221947a527126e8222feba42f0221cb690d5ed74057911acb25696aea2339213993010cb54ba78c4c4ac3a38240c19169c78bfb349623d067613b94c283856f942b36772c211a19457b890d90cef1586581853c98040e50fac9f89934a7917deed286fd7408011381795532515742a8d2902d2663b9e821b5f20f44a385994588f7f0c3ea6c4728fa1b63a5045d91bfa8e9786d86acb6b32c31c83ca0086978a3756f23bd5d411b9dea6a19a760c1ca24594c1890837b71609933534dfc986b56d05a04e1bdc101a125ec48732136941766b0b13e4d48638dd52bb9098cb711c3d257c560b829532581d153811e4bbfb59cc89ab062b3ca6c1d27bb47a933c1f3ad5aa398bfbb02bf8b3e83094da5c4332229a06a961d28e298e6095a27c078081265f3d2955eacc0459330bf5012fb157d6eac4d50f17946d38611d8bbf7ac3dcfaa6ad1086f5a30728ee53a07602d1248576e2c6f8c14c562f8be9b84a3867793f80a36d6dc37c1d670f747c1b120b5e53505ba52c3d765b4f8a9a7346a417c466c9c8102e43b2d7bd410ecf76f15fc4581f7008aaca8f855ad98213d50d06141394fedd78fbc0a44cf7403eee35cae02125ba15ffd656238d365fac18c1cf81bb91609c6941a1fb196942b13362ac71d782fb194bbf9715538abca8415a4e1dcc621f92494780ceff619315571fe054a4ff2578ad167ea3187be37c2c02582a708d02feb86759511c62580d99a5121ca60d7002246176ee5534c1261b86e831297a95ed8aa7732b58f0975c4445bb00db116ef36cee951006ac2709551872a84ac9b6a2b97b7a4e15011335777687749e7ca1319683840c017a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59da62cad366cf25351525536dc58cb622ab259cb3a6707d0abb088ac242338424baed40c182b15a9144dcce03456281ed2b9006915297fdb96e9c34efb551369ca9cb0012ce2c9af9cf90f2f616468abbb89b7acb5d18ee17a022a98b1fe2c2e8b4b1a2d4b3054d19162a243d4f0837e697f548164caf878366b26772351d28a025b227bd1c135922a43fefb55e3c37231fb188a37a6053a8a0ca88502d82a56f716313a5861f001c28678b23c7f66828dbc492fce22cf1d300bb3c576a1c01f13b962dd1b1c2364900f4a0db48a14cd103a7a5b535da93df79371c832b3e188bd0845ca95044002fa0c4bc92932e95180772ddb860b80063799b614fae43901d7cff686c8a5d05cc5589df1c7841d0312ad4261c8d81ed48b4ac513a88df3071d047d3380465f4a3a4fa894f6757be0f99e124150852cb56a483cee8c4f3f052c7489956f167e529a9c3dfc8256f764c78a4b58596e6cd0ba1c2c0e5aba3dcf5c46a533647195a682092dbdf61fc497a25e8b9c8770bcbca6c154629596f41c19879626392be7715a36570985ba46db7670d257566844a228db612fe32386590322b4a864a6c537452a9de020d2727dd1a0b066b0cb9d7144033765db050c0c363e926107f06b94fa70813c3c8dca862b98a4197be6b9f230a4931b659608ba32936da1904713c043718a8ae08419d0e34b26c6675b45451b392ac717a0e8f5245f035f65cb842ea68c7b2425b2550f12732402d852f5b7305975b588427d3de1b48c9783b19c7b1e486a47414a76449c26f3ab37f275f80413ab159765797d5cc653f2b4542f4027c199752530b6f7b49477ac60791706a4f7610138c8b3614950c06072ac49b6a25b464374a4d2c31483b34f83792db87d868a167aa08f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e161fb6cfc0f388e34fb28ed783c2733453005eea03d3fee4b01bb6364abc01c304f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = d8be709a35560530d75beb89fba0e856d8a76513ceef4b31f86f25a5b9486db6abc27703e7f6502b2dd79549034de3770a83b603f06fb08a818bf40b1da23d7b37ca011cd14df35a5efe7349787f39db24db56f0c2f38f0fc88c6af532a75c157126d8c3585dee3d9cf27d866216148fac12fa2297923ad63c80682e489e71f66e4969fd006b5e30300a7154553bf082a03e5a4ef6bf1d449ab53e75e953cd0acadd3bda97ea266307253917cede6649f2f6944ea8aac6dfc95d8dc4d7e2f4aec12db8845c10170ce01375ee6d6b094ed69461a68fc663355dbd2dedcb2f9bf74c458bff6529230b38644beffb017de9c2dd9b35a1f7ff9d053c1b00b00d7a29a143e7ab2fc4d78e0523d7f58046ea8977a4f91806a51e655c4f18e196ab30755aa5eee1d74bd5ba200cafe60c9f02a236f3ba016cda33e9f5a9361be028f3bec9bf3f560a009b26696533b119f64c0a58dfabee7a3ad2a0ea3595a338219686dd458f69528cc806c93170f5d8b503b29ac125f716c45422d114ffd25dbc180f3e358f8d83b5b7aa5ab6174e40d8235679aebeae5dae15b8852e0e0fdc2f10eb9834ce5a9675b738963120d319b23a550fde300be574cbaaf70a112f5706d5c6476c9ef3b98e3b4f547f3cc59be199126edadaeb831bb8cecaeeaf5d6a4013bf934adf5e2b07e9c5ca28c2ad6a7e2cf1207ef2a760e01a5d07b7bc0a532c0157e430127739a1ad0eaab81d804ac15fb884191537085846416cca4c4e8f1850e8adaa031402d336748224b873a66257408d4762f3228dae78f2a0a4650c5624116fa9aaef10b2be30df5f0d8f65ede7365675ad11b2ed7564dcfa20ef0588bf67988215ca9e604970ff8f1ab5eebc0cbd069620694f59e8e99eff4d788806384bb551486452e6e77bc3b8a0de74ad4be9f29ab7b1364508bba891fcc5b674f433e20ecd1557494ab23ab30392f418cff1f477e2553ea256a0728850dd23aa3665992a93d9bede891e0367c81dc646c2b47ffce6426aeaae2985f7c7768176ad6882e07b3922eb85ee9ef56f3b5b0529bc6836c1b6d54c52454bfa0000a7603a37 +expected_result = pass +expected_shared_secret = dbf4cd1f5cddf15322449ddfe147ae0605d0315ff9da6421069b47c3a67a65c4 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +private_key = 2a541ba3859e76c09675f97ec24138b384583a33c30fcaa3d7b1847788c04ef7113cf63d602740b90c19ded0975e4c470d660fddf9bcb210298bf18bde0569eb24abdf3796d107288e2748c1986d2684a4e4396da599992f63b895134eb331ad1b010569d02c113bab4e1ac1ca15362f2c7586546b4af6b2a3281bd691316ec4c31f06557fc387fd3446df00a73af0264fdbc51ee6616d54c4b29b1b80e44eb90b7727e7136a6cbb4e34ca49e49dbaa3ba3a71342f52ca0fe1332f87b2f1486c6aeca774647c31b00f387224319768fbe96c94f1887c3946d73cbbba863adec9b6f798bd7007a061692e79b734a1a69aa6ea4cd133a78da739b4e376d9750501e538477a6968f944c5d354a26b789ab90c63250530978be6cbc85830715a9b4837690bbf67b89150b8bab2459c3bb82ec97175a459a7eb645bac79a0f4087240551c493849322aa0a3a25c3087c5d667ffea5dd19197c6f3cb5ff4a9dcd61833783f2da504a8fcb58e35b8dc1b26770b7c3d211cf3a9b979d8b1d3746250a74aaf23aa62b6c9acbba545a0ccbe0a1316d5a86ce931fc9a31be4a764c0807928959f2ecc7427b6f344812ffa994748797284b25a26936cda35af397104e235b36b71b5fd9a5072b415d818a250800df540ddf164257882a4126aea50739f4957c823a3caa026182b415ae54c40c8998417131b3924af587022659accb85409c6a8cb9c4a32f372ce061437671b9d56a7e04b1a5dbcb1c0d53960c564096d4777f9a56e47197d1d9c7e144929cb38290066e39a3c25ef866014cabd01852a09168df1a59fce8bed6382d91ecbe6c38979b5b1617e58bf6a05f3318a64df6a5a7a97cab71ccf7069f1dc7ada344006c604633ab3b542b6acd9bbe19fa027c81725f2c4837109bc4887d2d669fcdda0ea6722cca228561477d9a456975e1ae62a25967419eebc55e60203d9cc7b17c51a668a544805aa5470b1e84651215e3bb58447583b5942498c0483a3ca405cd71958c1208a3bd306ca71695d8290cf378a91ae601dbd8cbe6938042a5c886ca27f1eb9b9e3c246383a9a3509ad04bc66089a04611b241fabba8f6435b0b4889a9403e60524f820cd8d875926a2d68b33c3134c90e9230b43cc743921623eb484f7c65a741a8c30cbde4fc74a55305ef8588db967ce70b29049a8e5c821b484390a01761f4850bbc916af732afe9a211419944e6c7457207ccd12aac09c421bc0a4225f84727424b306549738b91eda3a818e994cbc763c176795c1286019183ca6b2e2d3c8ee925937c5a9ad62306694724e0b62b68369a204b0d0d1b74ad9ab5158356035045416a8eb48483f11ba52ecb1e77babb800bcd67245932a237f237410730114ba4241a295ace13ae201b776c29613fa04a82050bc4514e8c532a0848a75fac67177844bda15368f1756bd4804b28bb55bb2e6c610f5e0ab9df749857405dad47c8b16b8063533b1e1c57d4db06f8e6643216cc342b053e3861cb1c71f2f9b52518457056676064abcd0041f1011b1ad3cb297a96200a96d6a30d2960161008cc7d26c1c011a00f857739e223ebd536c61748a1a9c792dcc7351210c8dc6c3e122ad7d9407975a75c3286f0ac032e5a655637c5b6a043aa840905d9623a077489e8cafa1285ea271c25f12cceb3664e3975f0eb6b25a04f18e4537ebb3f27405398d34718304e2a7265268367312aba5c069b765361d907775b3041b391668da99968c198e116530143c781160b80fb5d4b473cb7f60bbad1b83a3c8a80d93ee4e61dd546c5e06a67dbb6c94fe82d7e1b963e744984b849864a22d535cba8408bdab3854be3694515af4a58a4c6c0204f110ade12c0811036f9171635c00af6a29652914ff0cc23e0e67e84072bb1b3a027591ba96959ef3373a3912e1d43ad63449ec2f47de225767b94417a0b918bd83abf4439ead3090ee872f6c0c5967564da6c4a3ad061db656f3b8caf970a690422b914c599fd606eb1a17a3a220a1d86b8ba7343e1048c1d4328aeb57214e077246b7421091821c6299a4b75fb1b9fa124c7f5b3b1f8938ce9dc7551d25898387f5a86bc9a1c49fc8a7c5902b8e2912405a592a8221816570362c43589aa9eef609b0207c9e1f3b564aa6be9a60aad4193001ac4f6756570d983c8982cb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b29333445958cf50f9cfba453f058f562158bc253e535e4e2f07715531a1c6289ee32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = 40cfa27dd5ba61faf78b9609063100aefadb6b2463b41275c33e04ab0e0be914a35bf215aa967a443b5f8af56ca77d74ca47cda9fe03c0714b5788454390f9ad68d519e290782843d9306da1b20392937680ee9a44588cc627e9b44950fccd15f7e734cb9e2bd080c2da64f3df0ce8dc5ef8e293b6ffea9cca7880c396da0ab6c5b82964bc2e626f37a87437a7be4de0b6c34a06fd0760d107ce1a80f08710638d0ad39c838173cfff9e78244bfa1195d887db17815d74795ce3eab5223bb69790c7929199803374e06d68b8f7fcfde7889d4b9ae31e7f19e0b9c956ed8aebdd2109880f504a574aef28df60f5ec74f4a4b4d6b2db06b47c7ed34d2e7b900852e4b3afe9faa8ce60ec55d0449c943181930c27c4c36ffeaf2cf27fb82e1a25eee0a3c39c79a6cd508212771862f055cfb7a64db24e05252b7835a4c6b24dd6067a1c4a624e9466e98b47d584285837558180e4da269c914887d44525c8c25967a6482d4e54b16bb6b22cefb93dcd5cc01c3ee4ae711c47fee03b29a5876a2e434d998bdbccbc5449ea33be532ad0612913064192b44cfafdaf06ee277f8aa4c115eff6cb36ca026b3240e70355ad3b60ea29846f846d7240afa4af97b0f6c7bf6de0b2686875e868a434b28b75d95fcccb1f152c43c785135a7f3e8568e40c249e703ace9a809d005c4967cc6a46bbd305953d6957d94be02ecf83694afdf1b3e053b97d693641adb6e94a123bdf1cd3b1dbf5801aad3d79514702057e9f02fd8f36b988916798ff3b4e6a6bc8b196e067bc117f573563b08dbb94d5b88b0a7f8d69bb60741459bb59e34abc792d70ac51c6d6141340ffd927c703b207b8f66df8d68973e2cc6218cf5c793690f3df49fe6942d00191980ddad5cc9cd5f8c81abfdfb3ab7135f6bc8a86dca7d1a8d38a47631f8578801d8258430bab8c4b777035965814f04d62b43e54a93c064a7ab0c7a96697abd94a1e460d32582adf7479b20f83c6dffe9b45ad4587a13e8f5c315cd46200282951f87dd3447f664129b8a0f6922c5de259042b3d14ffb72e0aeaae45792f1a254cbd576bb6432f183c50 +expected_result = pass +expected_shared_secret = 3f4848a2de1cdd8a0403da22f609809a20c2cfc0ae619be0cac350897fead710 + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +private_key = 79888a9bfccca036909f99bea673c23173c15865c07460cd894c115fa1b673a8c2f60b5a99e3746be64b2ab5a7d7d980ef78131a5c9839714692649458667cb70361faf61a5fcb967f235b80858cfee9b9b2aac5d32202e6c881a150c38fe9c8fc51ad32f57ee2f140f34abd1cd586c754af25e23c60289302b95bb9ab1a90f59ef045ae45698fd57acd202bcbb8b960fdaaa6f9994e4f201e6d024874a68e3618245e993d035c50834062fa16b734ea4e6351cff4b77c4d2724af1b6ac8391736b23bd5caa94e61400877266b266d206b39c8c7563e86633fc90fbad12141715226c071042b1efd61cdc7e32f89e750dd24314f7c594652b9e45c4bc07b6fff66b5344b0548eaa81f189a6fb656ebfa3d46c4c5453b7f183a335a765a58f647f8735900e2159733b01a84789d162966a15134831d9223cd10a7039286703c85c3aae57175314a6a9c83e869aa0f3a77c400c1b705768d31826030391e0c82b7b4694be10f6c902b74d8a1730006534b44f3128cb42322ddf32f5d6b6f1e4524e867383dc52e554122dc0c3042459f14f88bcdcb7f133b8782728635339c5bc2b8cc2366d4ab11049cc96af69b686884694a968cb84573d56f2fe6b71df18d999436171a2c45c88fc4a0983333432e33bfcd1600673078ed512f12804d691c50ca935b5281b809d934ed3a41b41282c4b483d4d1c9487509f120246fe98cb408afe5c2714d57a41b95791164b406e85e9dac5494016b2f4bcf197419740a3b3aa5025436b0c46b7d5a4360cf972c7e9b8f32560747168d0b7818f72b22629074dbb79af74b91f4970844862c30dacad02455e5a512fb82cbf67ca4400ad038d8a867005724e2c8c2727dd0da6b696828f741804d27956f3c3c67508e4be740be8c63b8858af9f74fa19c7333fcb49d4667c9dca264aa5d78cc9f7df99bd6c063493759df3a6fdbe2b5e241a5f98c4ecf78b83be48d55c81e8de43b210378d4f2503de05c2d76b01c3821e0006c2a5542a5027898284709149a58c3b5b3d4b761e73ddd892262d9c80584967c047fe89a409ef879427164ed5708a0150e30d0ae69a047a0a46968f3828fa4314fac3f911a71a10c866e7c035fe4cf00a92ba9471a735b808117722378a879702d59728d66f35d53c34bf5797c2ff9a2f55a0b2cc873d8063a8ce7914eec935f55174cbb542702b1e7736f50215f7a1277968c2d35c711653a8e4af95115c9ae33d0349d4a09504a10cd48c77b411cf079a497a5785e39830cc8a189b9bb56891249d976991b23a4a7a1aff34f3788b148166c40f381bc5704058339bde0c192d307515a6a8fc5747a1058e394cdb79c4142fa5ccf3780f254a10c671543b63bd7d192913480c77517512c0e49ec3fb8d03ffc793e7cc01125226fc4929c8c1c2aadf12b452746306c2a9c36392b23045888c2f4170b5eea07aed4515a819d7c5749b35380cefc976c87270a1237d6f4ac214548268a6da75928e0734eea7887aac0a2bf623e17852501556b03c662e4e9c42b914923b88d502714fe53373904b91598c8d7c6b022e5367a90173fa511005039d9ca5c3cb2bd5ed1404f7373654848ec436115339db37cb3549ba77237c243f25da96a4bb4a8b88e441693f6a80840b0ef7538f8fa9b71ca736d08bd3678c4ff8c480b115452c9c8fcd52529b1481e82236e5a311a204bb571a89b0a60738101b4617b033ba2df6c7967cb7b7f218aff886edaf2464b2a12bf244bab812731f46200ec6e94d24548650e1e1572e4a78157e2ca569c3b1472cd8fe98458c1a5ab8340f3a90e5a854ece60469698cf85d88739cc96adf7048cc584637a408acb79980a8dc119049135795245748683ac8f53b815e29ddcf5452a9504e0fa1de9840e4d489810c35a100687bac18e185bb53d499d266a8758c68782778b533bb9e5b16ea833309a0c8b3e640a2c417ad23b01e27220a7e9cf9bb91bd6eba10c08acff499295e0ac4f61b9e85ca75185af845c4f4330652ef024869ca7d3d33cc188a65cf17aa645b8d9b010f379198e31b7ae448082069b33ab6ff3a235ccac081814b6e063686707721f6006eabc91a4999915661427c85979b93ddfc14e24176e9c0359839a1c16f91afef473652480d4a2261abbb7fcb031de8993a57600220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852ee6cb12a54341aeedc99f1040b01603c35f07c5487ffac7b4fc1925f490269165aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 76203306e49a9d478fa987d47cc93959ab932ce7d5ac52801a01a95e25d772d8cecd1f718c5878e90d9d4a4976a9e6dad07ef015104e81817839ec0ca9ceb6581d911fb08ac2f7a7fcbc200fe5a81d07e6ef7ecbc1aa057b1ba3790ce9694683b1b8b7baf0b0f254f34262ae33834920e510849fe7d931a9bf2f5d0a8fb8ac25e32ecd89d880506a2ce0d51293f849e8d452a8ed509b959ba571c758d93c8eb092367b5b5b5ea3afa27df10794aacece9932f79f1dbe77deef12f9bad1b38dfd479e8bb096731fbcfed2b2f47a06bc3d66807264a4a8c12428fe6da2879e08a5f885c3cf08c73fb130bcf98c0f4d0e1ab32c50c1ebef43a4d7ca59d2d400af238ce00b00f755eaf5e613b7f0f63f412177b8525551f12b32c44273dad7796171c0f962f4b23b03d5ad75782bceabaccee5dd37a3ec588b0583a59c761b83ea851cfdd3b43daa3fd8ecc04edecadd4635557df4acf2111118f5cd0979f106e615ed443b7a271be4be9971f3076abc49e4acc4cb36a4b203fdf49babf4b920b374053b023ade1ca376bac0923192257435e7c2c9712df08cc77ee199b0194af5ba14150fd22343488a02dfbc7cefb730199fe24e92191eb7c21ad5af0fb9cc54e041af6b64e5176829f9f4b67197eeb530054b8bd211b68eb79df559f2ecbf4bdfd675a5a8b2f4cd48b8aab8bc75fc16cf2e49ddb932ca9211981535078ab253cfbc514e11edbd5a32b85610ec462e15ec7f12db1cc32fdaf2b09ec96d1a8bc581d689f1a7b4fa02a4891a77d128cbe48609c40a2a88ae8305dd6cf091f2b50cba5762f946989951df8488a7647d79a59e27acbfeaedd07931caa3d05868371fe32378f025b987467c3e6f33290b33d57455248c5a57e1ecfb974c5b9e5fef8b0da09ecceaf9ff6e6c7ad04b8ac41efb59f6fbcba2bc0ac8acdb6f4972dc8308f2dd0b2a9626637bb4ab4593d8330b38464467fddc7cdc031bd17aad822241f5798c5640552b78055002f145075985ff5b42d72bff8c9addfdb55c18c03354ce7207d842e9f734db67a24876359f33338c5b68045c342b676770af0162d1292297 +expected_result = pass +expected_shared_secret = eed5b71764da1763a01184a1eb51dedb4eaa9dae7890b1c7dbc7e7132c30e737 + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +private_key = 68442641472c1216cff86478bbd31e60e47a22391987da1541aa882a649a482bc06b28a7181913790294e3a4a3429c7ccec1ba4012132b8c26458a7afc514e3c859584bb2768641abff48ef730920f15775fd408ecb1ce3dcc3a10095c96a3b23d6a39e6caa335bab5e143118ddc72ef347426f83907153f0aaaa356200279cb10a6a1922bd148898731b5a82f0977395f00189f244036d8a409937ad9a4550972b165f52b15d851f30b127ff5b3f6b29818501aa2c9b00a7981773c32d2d55d8caace972c8fc097821382aadbe553ed8b8e1e7ac0418002f1901ae384980146aa6cc01b8a939075fb36d4d48b55f489b870afd61768468204acf72eef892141e05d1a1518e01218519249ef45910a06baa4d442ac9a95c8a39d9d474667b48cb669558e301159e1cf8c6748651039c7f90945708ea56979ec42a8e9e86bee5b5554d8a46da0bb4d8b100809203110518534260f321d0adc1fa6993fed33283af10bf0130ca4110b6193a7bf746513a8cd4b84658054623e75272c198fb443af89927faf644824e8cfd7ac3eb2d12efbacbc7f837834c57e31a521977b655d682a34079c89f3c38418ca432242fd7420f990312a722f67269437481abff29b1f4c6795975549d38d6224ba7006046a015d0f770434e597f039767551381474868eac4d653a7bf0b989eef6582b80744a5b91b1473a9e920055e4b5bcd523b7a618722a107470234430158dd887982b79383b7272a4685a854c306b43d36ab89b57736ff667c27a10265a7e15bb5cd9112d6f9387baf21f1b32957e17c05ddc50c176a5bbc2ad5cdcad536185be78c13ca6c2a3220d493213bad32f33f582449070c4b54725e329b1e99a0fa58010d7a22a6a4dcb822e5bb28803e4027dd935cff4c556204531d27c5a462c92a085c7363a214a2e0c8c1d1cf42b069ac623a245a14974d2cacd58f18a8973a02c66ce4f771124e9878e402103f96bd3f00ce61a78a5fc5123d1aae661c8908c09dd457285f435401310a6f4a513822c8261aedd896adaa8ac1d52c1352a1a3e2c7b1ffb13afa0cd6b39875e9c7db636b82bf2278c9845bf1121a0172c991415a6456b7d708cf45a376e689e8c74b1dd589e2ba95d19192e47937b647c21bd9a518644113f44877aab626c40843b078e9a93be166c73772b290164c7ca1454f2b310c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae30b2267aa97bed49c5eac3a9b769c3a9aba51e882d0f5984cd7c39a2d1136fd627b3a204ca30a32efa02d51977eb2145e6c91717e0760f8949caf6b928a59f4d6b24221a291d008679b4b761178909c83d4c035de424c202117132010da0502b75e51705d07da603526fe46f50807af33593b0d59d4b28b31ac48ba7ba35793b194224a4f7577d4a7664e4311841b3908ba57292728a428a516d96c90511ac6b34673dc0127db223b7b27121a2aaee2822744b7f23969cf95b3960826c0ab4a100501bb601b6f2597339a408eea5360b9c6b752a03d648817654a35db7c5fde89357cb1e44a1b800d99e87872f95a17709f72a2a502d8f908cca15a22c14691e219b95b9c3fdcc3fe3c849efeb9cc0dc051f451fbad93ba360b2dc2370b400ce74058dff270757f20603176ef888cf2caabe2f8b337377368ba7aca7131bd6c8615e0017e2b21bd5b9b029085ac668803f66798ab060104ba4e930322b1452befb11c45112da8592fc0a74ccb8a75491120c1b0c1f0cb0a1abc7386948be2bac6bc92c60944ac8482e5a519b3ff36df7ea5e6f939b0c1b662342a08b6059658448b65b65c432b28fb66b92594d0d8938e5d3a0d6a99c7b3173a0796e02195e84b28da2b06fcd5672412420c916c77613b9c69039cf1c6594d90aad857dd319cc9bc9702fd452ad455d5329b14ab033a5910c08124338933f60993c3683433352cce6c484efb072f59b85a6b402d4652d910173caec2adeca708bdcad9d996b60a08f8c3131c571b5faf01a4b65565b18298ff8c6b3f68e77e768a1c0cc009315a4459b0b191c3584bbcd562861c20fc8e2c70944b7eec84c7e427f935b5731fb6e42d8b40b013951852413e94d5e01a04405319a7167b8e4cf638279331a6c3eda1dff9cac99e148bda370c2d00715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8242ad42d6d3b13c72b16287909bc4c0da04900536a1e48a1a28db4f5ee2d2e771e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 7b5be6d0d3b9759d1889322cdb13d7bcf5ce2516ffd803b9acb5435a563dfddb466e640266191317a893c8d2606cb4502e85b787459a018342d1876a554d468ace2bf0e6cbfffb25bfcc5c2855afbd2a799ae6a197b861ba70c521b59da2982ea8b90970ad2f53aa11355058ed95bb01d235e41228ea4e7432cb81b95d69ffb2f48fb868af1ab0dbf410e6774d4fad8d37ef62e83ab2ec1e69eeed8cf39e1392015786ab4c93f1b6e9ca8188ec5e295c0f83bd863bba439493623d05fb6a7afcf8c25ae4fb2027dd56aa0a62de157fecce232d986582f228f7a8f1effb88ff513d6b87f3911604cd4da1bba8beea7837c4c9146de3e21f2fcbaa018cbc372e72ddf0187269d8805a592d09e33ae558684c223d4ab4ef9d16dfb5f034ca235f977d20d035472a711b773ce9bc5cff177207ef81601cea5aa7085c505f92d0bada16db937621dd925659b6ea9f1c6d7e859b012a191d056f602bf263dc4824ff46fe658645dbe9cec11cce5c1e5632e13c3eb634f196e059e42dc19ec577fd5cae7a67a7d70a9bc4484aacfbb3935fbf401d8099935a8d746363dc397477e7831842cb4d22e301125424bc994ca6a62f0b3c6464e93f5a8e18cb71e923ccaee3b6fa1569bd8d046a5d4a5687dcc55fadb5f8023309a31f9825bebc117d6427d4f0e6f48d6f45fdb00228bc42f8b5066a430d38411817c0278d17be7e64cdfa7918580aa62c1ebb5860c36282d8c3e6c2b5b09f75de3ec92895f07944041bb139e8232aa0624639dcb882492c00d5323026e510c7c3058ae66738ca61398bc731a8605eb2ecc4768770af6c4b1f0ebe0f4d6cc8c18c9c961d1003ab867a42187003f2bef281d0c88ef70c4e1927f7b4ad837cb89de4485ff367d082c3a3957c76f8d99f3eb8d0bbade5a5e8ff5f7dfdcfb61dffec0eb24d607fa3a95a53419e9cdd205463365f16579a7451a2264e89bf11d531a34d20b5b0d478b9faeba16d399db32390ba2ffa27434ad6a0b1dccc7df88b6d3a805b45040e18528473ec6591eb0b8ba133b9b48b65233f11a91b43895fbf7c79f199715401f1fa69bfcdababd7 +expected_result = pass +expected_shared_secret = 4218fc9abb402e67ac946c7a7c6f9029108f67de469e1a9987d570f011b685c3 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +private_key = e9c556bea1b6cf3b62f9db44bd74434d6067b1700c98647a5890c35224c1f871c13b80738417c5c78171d61b6b500c907f936a1bfa6125cbb5d41c88e291cbab81a44aa84f4ff4224ccb8a5e05ba5b66927d696c2de24142ea480881c63da0ca5f8820d36a360f345ce4804758d02a3959c2cc876ffe84c6fce10ed111b6e7f594dae12a30a015b30b403dfb1ce3f71fc295b962e22baeb913aabc4397ab4011980dc1d335f2460ae95127071a6fd810248de27004e283e208cd00d91ddc56b60445714679b4aef87f2a844fde365b162cbae33a078ea0a516f6661d66b3c03abef8daaebdb0af32b28a7be042e78b85ff14b421f82c1acbb0bde1c8306821a851605ae83fd8a3135b896d3c990f67da3a37617915f625e7cc7dc8db4fcb6a10723025294c4223aa809ab29c0c4ccfe0330309e4a3d6d5884f3b46a9a0367efb62caa19d9a1ab299b83e0bc0390d011f3c5b5a9b8593ac866591bb284727c52c435105453c0842c9558174ad98283c248ff8392619833cb39a14a22906d2b8738ce2cb4695b8cc60a8682cb7d8356f3af1bba91396b9c06414dc7ecd139eb87158596b3221955baa56265897c78bf65efe116ac27332c7bb529ec52fd1baaf7cea94f9da2444a01f1cd61777840bce32900eb69471cc6d18749824ea94e8183a6c0007a4d6c1289aced952b595582f548713a379b39d47ad348c68d2613491116fe01c6f70a5ac6578a05211a44586c68c982f72d6645e67409fc85c584c253710c800b1a0d1293223f874044ca3fc1436d2daa5751a1b596c58fa4270fdf102aae4179451ccdd913bf0bc36ba7cbdf6ba276f988a3586420ae2afab95940f9116fe5439a71927f9ca087a9891113ac8f9c2bf0d2b091d7accec51afc15708e8972370d547cc9269fa487810c2b2f1c474a6c8858de8414f1895487c10de2cb46cc68cd601b9f0d8059599c7ea620e5e0c0f1b4008aa1a4d1f4c25a1448a51447463a3a88b9a72b69cc5385750fcacb78ae35982cb3ad5285874a5b34c53c00c17913e8b746421aec51b93698c4bc48b74dd65384fda4297f170bd65436453335b5b3208a4c987ac02199a6c057376e2e11015c237bff18c63b730297052d7b9a6c7e15a3f02a9046c23e7d977111524afdb42fcf24526ca4f17ea597a26874e333f40e840fa3c9910c12ed9d86425421e7b585fec42326fd1618db61c9c7ca727e03fa772cc9cb241166cb40d3148b4889ffed89c8b0b772e807a157a6ad3b067c9f43c675c69890a71b996a323376777723cc6a4bd240c40deeb93b9a61bbc306177909e181636353a2f4b3b02f820a9f841a690b50a74f09eab73ac4b13689e267983241b3c9774c42701dabc8c3060381f60c591608431ea91f5743362eb86add70c93078349f4bf4b137d43e06c6258484c92c8457521d54915c96754673a4f981ca7c1a3c228a22ab44a4c1d207988d8a49925724c218efb34c1afd4b56dcc8815622d0e1c206991abb6e50a3e8299d9ea10a8b5c5611455378a5ac2b179c74501896102890171f95bb18d32ca7aa01eab0b272df4b77c6377e9397f8fdaaad0294b59c68607a073a2e021ab8b1ab1205cac74c4bbe21ba80b98225a33b0f18b45a8227c9b6e18f9c25f6b901137a7912ab148849228d2aa374a261073307127c6b09777fa9768c183067bc821f3d77e343874864288518ca21ebb2061828c0a60340e30ce80f60ef5523129f18bed579625e9419185019c8cce24162384cc6eeb7b5f9ef1725ab6034db7c7ef0580c9f0cd0a81c2236c46ec9a3225593e3b11939b9758556cadd3f9967de57f21db4c4af8541b4b813d67159afcc69dbb36d3dc470a829a5d771dd8468a21356d40c80f1c156008b3bff356962f84a48a041f4e4b29b7276111660851f7ced28ba0cbc24cc631942b92691e386bd81a28f66b8d4306bf89f36d0e015542479f3041cebeab2d8e95304795a31e6cae206b40189b4823359382393bae1057a62471c5a3a93cc874f96c294a6a4e00e6bbf8cc4cea280942d0c43729b2576076e73b3edef1be7317cadbb58db1a046b617800d5ca0e352b6d40a16303c596652a4a2209c5c72428de4b0d6b6821eaab1f6824cb35a04e067b5264359a9a6ce8b3a26259b613710a672d13d2690caaf62c5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc755b70c5bb1b7af3b643588aa7c20567d4259dbe6abd7617a61b48185de8f21e1cfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = 19bfab9556d26ce097facb97e1c345495d755fa7df0892460974f99c2c103ba1049b9832918b874254f91d8fb7cfc11da9c7cd1d6bb50701371ea35019ff2a940912d019d2bb18821de100b1391d44abb1f72aeea18cd4f52e1401bdafc49adc65d73b02a5360b9ab00114035052d57ce16828c22bec6afb9331845210ee64a180a30bb684704d1c462e780aab4a55d6d746a68999e583de1a0b147ebac3bab7ba17faa6f58d355d041f0af83de1b4d9a244b83842a9003ab16a14360a97978d8940ec93abce842e8a1a3a172773b317fb8dc59472156665821090492e61a99d65f0da5e97a6a1a3156e2890e4fed146f4df81205974fa0196037b93f52bb1a3f85f02b92c11ddfbe479a30ed62691a82ca807eb35b0eeb8a0095211b44deebeaabe73e616db6bcabf52eb47546e1c6e20c2e14960f233378eb96e356cbb71154aa8d0e342877dcb00ff7f136a02aec66fddd1853a034f050c6155aa981ef2182e190a28dfc480d14b170189d105e565312578ef1a0024314bddf231af846affab5b289eb586db64f27ae9613d79f62c96927b57135d91c8f9c26c48cc81ffb6e39733c8285a2c93b6238fa1f9bedeb5b4368236d22a6e03bbeef92d2dde1d7df5352d892e360e2bf0f2e4c6dc86003c9f2bdbaf5a308a230d8e00e810297a46dbc6c52de5011b983b1adbb754cdbd33b5f1ce7e6b1e9d5424f7d393a53d8d90fd712632b160ea812a4558cdf0e6730932f021474b67586e60a80d97d8fadb44038916bcd5c1c54256cd7e3f61df56a7ba1f1d96c8ad9ef234819cbdfc66835139c57220026cc25fc83c6c31da656a0694dfc3a3a20895fade4d17c0da5033eab105b3a4b464aceb6b653d54ffeedb2b0a009a9e45dba33caae7fa6a4164ed135ed0163fa1179f48431690314d1c7dd342aad752184ac108611b096ec477a6c9333930aa521a3b81e2a0836f0f0dca27cdace35a6569abe904d14822255ab5124df8ca3e17856f12502740a3038cedfc286f81c5525b7830f1d153967f474d2199dfaa139681036d718e8a308ee8efae1dc3035284b80e9b015e1d3f73b9c178 +expected_result = pass +expected_shared_secret = 95a33968866dadc1fd8748768a99f6bb444e3d76a65ec5fee0c8a833978d4585 + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +private_key = 109cbf34136da8c797072085f046541a205922b9b9291acc027173c0d824ab1534102b07a399853c9b5d4fea1f7ce38302c587fa9643af3218afdbb48f52c516b0074cd336242591691402750384db8323f812a8926875014089df7698554391f1d687a1a2380e9c2b81261656632ee78996d404ab4f224c0dd3acd6b428b8d2af81250e7d9825640c3f94d297b2506427505eb3045a8852708b6854f0a99437f6738f22c1dce44c160163515074c3c72e2a4041c8a407dee38ac53335841029bc005705894ab658224134421ad4af7543009c0093b9b38597424a32dc9a5135beea4598d8f2589d72855ad37cd99880c1fa91116c1a933c70a176086d437443b63523145314003884ec19a0b745855002e4b63f4978520661c589d9132ca27f84e9ab5536b60420c89c9a9717082ad58a05e8c808c7155600c199e8fc3ad01b229308071a2b9587e203fd211442f3ab9e9236aaeb8c6555c1d47a75fff45a5d7a5ebe85a8dcb7ceb077393712cf9f7c465d066f80c359c7a3c713cc21a4653078fcc51b7232e48900ed750986156cab756d9af0c685263b19772b35a8ac3e214e8b7b9f3785395b500f76477858b123e24c0e63419cc6db517a148e560a358ef50b8ab238d000181555b46db95d9e8c1bda5273cd58818e322831a71301d092904289cb4c017fd1c86d758c064136f6b937ed222bbff244de7c213ce24c967cc5787b87747a305c73223bc2a6cfca8450d4954cb21e3d160e5b860e89dcb38f8bcfd016a927997f6e9c7c1e2a2ff97c93879cc1a5e30c20d80423f83c84373b85384bb7d88e9feccacf73ab59969750410ae69537c3225d3423acba55174415a259f60e58117712c21acee6a97d281cc6642997833371358f60c35da6e6a833e5bb20d94eeea16e7093501ad54ab65caae67754b9560b5f68b78b44ab26b439d453412206325186bc4ec2479fc103e73b057a972aef6949d7403beda51d82f0c654fa1136071b876704c7c9333db252b4a37a06755a1cd428b8041d8c80a94aa76cd8d65d1e16a8d240ac71db05dfb69d1439b57d9a3e262cca3feca48d9c1145c83435071624067d69587335b97bf564929709c8825a004b028ae09c40980a07e8d4bd604527ee221e8bac67d34cbe762c26df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367d3153e460f497a209c495fca318862d6a57800865479a006012d82f7212b40284d310e01bcb11e122c1fd303e441807849a7ea47976a99abb7ccc4b674ad66f68eca195789b277d23c3d67bc418ca7c908b21e53984983ba0205e4689000ace97238b3699016fa95e7a3a59cec0be813638527562fa9bf10d715e7505f6e1c1433521a918a7df52760a0d8a9549569f10827c423cddff82aae01a90111395487b9c82b7b5a7978d789679e66b75087bfbff0569fc94e94f93531b721315926388431f2a36ae0f701bac254befb437c58641d4560c8738a98f30918945db0a6900ad2c2abfc3e0f4786a4555639d84dcdd031d8f0508d8c774d68298bcac4f42c6a7ff585af491fa7d7c3bbb41727699ebb315c437b210d42626ebc66c916af1f3515374314e4f40309ca7289c7bc51c301d8180edc792d4dd44c41b77bd47a972d8434a9f03bb3954236ec422be0c8e991a79af286b6a7c459a95ed44868ed8052f2db0f3741710228979507cff961564882b5ea19515ee00d657c7141e9b05f9a24136a2f915620b664404b5397cc7842748973d0716cc273b528d51383a63fc8a3c4a3b1a8bc965775d750add6996c929e29f41e42362a759baa76f5a3dc0552f1d83195960e45837901494a87f2a6dc3b5d8b73a9695c1229a0c9bddb0b2d99aa350c6cac657745c1308af354e10595f3682a34dc26d9d28e2e2c4634aca75e94384700c9c06b1bca348330ac1791fab1419099cf1288283bab03dca09ab3593cf3b12739cb44c0c04c6b93d1ea831df6bcb8807aa6aa8cbec64d749a9e47f851c47c6537e196f1fcc4d63b67d29a58e86b9a72a199cbb793c5084e5bab20bd02289b4aaa64e4c119488531e8a651a31750148e1742c5390bb9995c123f3056ad44c476468ded4b88a49130e35b4b00803dd24718674ca708e436d5c15ee1d95367c623512653c83b27b41cb308f8c2929b193b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b801782fce09e644e310c9286f1e381be9ea8c54a1804e61f2958c1f975aec185aae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = d9219659f8d5a0b8c4492b9023910a14eba618ee697528be1c1278effc029ef469b4beb1e081e4fdf32cac697d5da4a859830dc4d15e0e1f3298ef3ad9c4641be0ef901beec94242e894e62d3443c4975f219c83e2b69c087fea2e2309bdb3d64446875f065f18784ef9c2cc0d1989ad1b10a20fbbee5a992fa717a64ebd7fefbc94823f571f8185b4f8bb3886008aa295416877456edf06bace86c81cd01363e29727073a35662b950bbb829758d2ed5862dd8222ce466dd9d2c5139df83856e78b25f39734837938e03c71727080f5ad64b3471774d528f96dd354792607a5f3faee5a605c388ae6b7e26a76dc58926916cc58697634295c6b1f50f18c4492ea1e57519a9c46fd992156a70068c51531ac2a9bf2dba6be5f870b145826e468cfe30620b6c3d5eedd1a769bcae9f091b3b3decfd200d574d61773fa2a15346efee7c8aa7a48a68bdb79853e52cf8805fb19a01cd95490e7b6b53773dd45ea1f1ef2aba510992fb3e8f2fba356361d94fbb3ad30c5af6a26b236f4e07d95b619686334bac20b5838891716821f39dd454cb6409b1d124a11cae63cd67961f3e07f59dad6e161e7c6926311aae61f737c67f30efb7978ebd022d586245b8a2053d04e1a74266cf2c630399f47f239465201a37edca5acc7631f5750e0c7b34f0b27ab7f1d0d14caf48feb2274aeb676c49c10a6e3228fcc290b9cf3d38d2c7b1bd4b2573979a7805b8835fadc25455c5b878666d4e5f1ce4708b55e425d589191354fd665d1fae19fd1870f3067d5428b71ce2057cd29dfde70f51bdd12971ce9ad925efa35a737448d6a2dbd65571e35a6dce15327ef73e4e6e7f2410cfe0edf52fdd1a401d867e12d0ad058fe92b6e7d7f7e3e1131036604c3f64c85dd3fcc3d81d8a58fac4a7804fce5a0294771f86aed396a5f502f3a366ace4bbd48a31c7b19a9e120b127d9933c46cc7f9aecfe8385e775adf11f665b2b4678db5afa7d98ceb913000d9c3a2bb814f547cccb129caf9ced3202b0667a98fd18d33277b31272bb47683179fb15ddee809e90b23ca89a1015c273dadf6fa0d39f20373c763 +expected_result = pass +expected_shared_secret = c9423277519ab439fca3f5fab4c29c8123a55eaf37d94d70e27afffeec1b3b9b + +comment = Private key not reduced +private_key = 6c99fb0297a9c774e493f87daf3533eee6ef07f4652066337ed74046dcc71cad3f30a6d10326ef7deb53a72be1627f63fe2a809769ce6e7da85ff6d0edef9d7f36a16d43eb8b2a9e1db8c09084fdf0739ff16dceb4ecc5ab1c5e55ac97bb66a7f8a5e05d57782c2f9538e3421544a34224d8dbf44910934cc423774f1676ff1c306f97555f57b4aed7a6bab950a8163c8e3e8deb6f751bd6abc5069c06c88f341df6a1a8d6a03b97a7696b56eaf1827bb4e8ecd3125fb41b99fa9e99adf7ee963e96578838e54f467033846920fbb4b80544e7e8a81ae963cf368c9cad37a9cfad62f3fb6f6ec91d75ce005ab3108d99a2ff9d7b73d5b4ecd6e25680bc0d99307e7fe7dee5a8084231cc79de8ddea7aefac70ade937bb6a75666233d470c189b5bae653deb937d5a9c26bfed94be90740cf49e8e53539797c7d4ab62649d76aa553736a94a1ffc22d5fbaeec605c3fce9e5b93859d3558ca9d6a3aba914f3eeebdec94198b192a8ba9063498adc50143d7ddd863526471a4d99523eb417f39eaac0c3a581b6da00732e5f8eb1f7c879b1693c13b6f9f79316234f9e64faf4079f22f045545edcc50bf4d4448cf2c6596f5dbd8625be1860e3b6c1fd892f96bdfd4ada9179de727b8da4f6e0996b5d34948cf0fd0c369b37cbb54d3479ed8b582e9f7f8929b4c71c9be11d45b20c4bdc3c743142f3f58274e8bb5f44447c495a5db84dbdc3c2736411d8a3397944583f79328996cecdc913c958ae6f0ba8b5e5ecbbb7e13cb9d7dbd5ac3deb7488c981dec20498f1d7cc06da76bf62dc658ccadfa2956424557abea8ab99f39c17833dc3a49b36a9ae9a486940540eb444f9725f358fdf035939d75a3c02504eb4018f383ad733c39b0622b740f4d7592d6fecafbe432c445b47d3a86f6981a278157ea95a6f9fd55e4b972f936c3fda65838dea3bd7a48a9fdf8937e0a2ac1dcc974ff0daae1f561fa258e2d259c3e96edce23603a1f76060cede019d03a7bac953ed1dcc8f2b1f3c12bf73238f546e01c36b5a693629f995cc69c63237409cb53c2e35d7499dd18885376fa5504ced7a2a392115ace0e64677cbb7dcfc93c16d3a305f67615a488d711aa56698c5663ab7ac9ce66d547c0595f98a43f4650bbe08c364d976789117d34f6ae51ac063cb55c6ca32558227dfef807d19c30de414424097f6aa236a1053b4a07a76be372a5c6b6002791ebe0afdaf54e1ca237ff545ba68343e745c04ad1639dbc590346b6b9569b56dbbfe53151913066e5c85527dc9468110a136a411497c227dcb8c9b25570b7a0e42aada6709f23208f5d496ebab7843f6483bf0c0c73a40296ec2c6440001394c99ca173d5c775b7f415d02a5a26a07407918587c41169f2b7178755acc27fc8b19c4c4b3fcd41053f2c74c8a10a8321241b2802432875ae808b9ef1365c7b8a52902f1317ba2fb0269f47930672107b4726fef64547394d3320c8f120b3c2f4725b0305fab88cc7981fcb09a76a1cbf7f179f43bb0a4c8b0590857f1e69708466c7f8607391e7bc5268bfd3d7a1dffcb4eca2a1c9b597593013d5fc4202ec2b74e57ab76bbcf3632bbaf97cdc418a6f16392838ca9bf45ddf023777b7561833c105190f94f302c59b531900bbc816361faa5b3380ca3a893104ca7388b185671b3e5fe3790e9a626ec46d9b0b33c7a419af7b32b6859894f575d82ac5456b5490a7af8fe61046360589ecba7244236f4123116b6174aa179249a49195b356c72fc6641f0251812eaa98570b046699070e0819dc2713f469137dfc6a3d7b92b298995ee780369153ac366b06d7249cd09e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf598159a7792cb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4932612ec915e4ca346a9bce5dd60417c6b2a89b1cc435643f875bdc5a7e5b3481cf919ea09172febc46d4fc3fb0cb9591704ee2dbb61844b2f3314a06bb6c6d34005e485ce667bdc7d098586928d2d91340f00419ea401351a240a0b041058befb0c2fd32645b7a2df8f5cbfd873327c978d7b351a28088438837024c52b9c295cd713646fb5d6c0ccfb470734ac2b2bc8123c2c13df6938e92455a862639feb8a64b85163e32707e037b38d8ac3922b45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539227ffad1bc8af73b7e874956b81c2a2ef0bfabe8dc93d77b2fbc9e0c64efa01e848626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = 7549998d469e2e479002305b09b44dbadbc2457ffd3125f6d31b0f27b803d581071c1dc6181196fe76df78de20dda609cf1b7cb7a352c4dd9c2cfc18801f036fe40f8f7e6f3dd73f387130be387b1713418f83d93dc7f8074a032455c46f857c6b6b35429c790065420d742252ee53f53f6e64a9b78a49bc29b8ce84831a01c3429e346960dc559526d97853c36631b4773285fafe8e3ca4255a8723ae4f02ddd85a4781b9f4186d67a83b5d9eddc3ae7cd4096c33f4d97fe02030ecb6a1a8ad9b19d3eb32f1b8f271b30353e9e19dd183f06b54c3cb02ef166282752aa11c8158e48bbc6830171ca7ddb75a35e46c35321abe6a742032c772a16b3d1cddfc6f2801e2b817302dbc94f333c0cb91e1cebd5ec61e49fa5a14aaa393755fc3e6f4b8c5c4fa4baa07a08c4f3394626358a15e690ee1e4829b111c17241aee37d5c832f4847688fe5b5d1b19e8e04d9d1937001987f3b4b83549c3e530e4119d164b20ef9d3a72f74c044a974591228b41e680ec5640a97234c2c6017c95e91be2bd498547d57a5222b8162a3546656d59980d51af595bf5f23a632f6d8544b81074aed34c0352ba560deafb07441a55a9376342e50a0ec2537228255a4b5d03c92957f4ea3507b4baadce53ccdfb7364ffc1817b58c50ef28e322e1b945e0eb9b1233975c30a5545368682714bf502b61e1d0457a9753e10de0f1bf35ec3a3f470a3c69ccb04d2d98fab3a0b6729a9875e1db533c96b41e3d98628a6f8cf668406c5f038e6b7b242fdf86a7f1e697aeb136114167b13f89f231bcec7a4166b39eab4a3709237822050c49c92595a237f2eb483b9e1dd6124bed5eb9b7b5121296376b7d2014a77560ca65833d8beb4d6ae68efd7a11acc7de87d82be1ad573ae9f6f0766fd786387d1a8c12d1c8a296b4f72634f70577688848e576851f13be48df335d4acd89793a6c6c0655fc39bc9e1e27b4a500f708cd4a9f2ec672ba5bf8ad23998d4c0c958f290f2a6c4e6cd8c0cdc85f5716ec98a4c8995d378cc6e2a1e8b82800ddf03b3226a2e7817771e509b4955ee2bed4217bdf0630b5840f2524ab +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e1785b13943f276ec372ca63a0c6aedfdf7f46d8eb847f93b9867b9f7cce071ec61c3e8adfd67c09969c28ad95e54ce24b048cdaadf7ca1d3e85c5c4d72730a34c8add4d6eceb4afe024446723e9df175465ea9a0eaef91c18cfc9367a333475727b64e6f73e50233b81bcd978364d1807feb39a4041d4b25a095df99bcbed19d496dab62baf50945a97bd297a53aaeaf51648c8378c1c2ea2fd4eeb5796dc368a819f2b8c154772432569713e3b2bed82c2f8bdacb658a89c6bdc788325d48292ecf39505eef765a4a2f9f7769c84f5fc306568b4b5e7487b8b9f79dcce33d8db988c955544cca478aaca0fc2a7ffa4bc9a9478a9b318f78586c696942b6f4c2931e95d42db27314cb546beccf237dfe36d68eee22978d2b79ea3b662a8bc7cc17ccbdb59aef9bdcd77a4a68077fe9ab4adc3ede1bf57e865f92f4a4769a8157b87769ac3b8644895ee80f8babf394907d4c8a51c7ba4ca62cd7ab7bbd4f19778ce4edff95587fdbd1330c20d55dcfed6d11863d8be4b640ea622ec35f3ab9b3494c12e49f9bd4fe9500ae136d98a3b257c20d378a9798bd3b57e50ec88617b49b86df2e20e30e35432f3abc7165952e2b7652c0bb1fb9fa16d7b3274df709087e64bd6dcbbe747205b6dbbe5912947ca3914c1a106b66718f12d4438996e6274fdd6ee5d7e30d7a7b6e389739b63760983466ead4f2f7da0289ed928dbfaa48a58ea75cc1744f86dd7a9a6e1eae775a1f5411f1376a8ff5e758c8b69ba731d28bf016970a9a3579ee7e50d5f6b098c4ad277c6d7294462ca65b6f3b70629565524f8477b9c584deecadb9c7adaca68cd42404f704c0d8a9096eb46ce9d24f5f1080c69fe2da5dca45aca18abb356375a983081567e22798f530aa1e0aabc2d7b3a208446e918eba35fdb8afcb8edd37db536689695749b73fd9a3e6653e9705636d979974e45de3558aaf83ede486856bd1af59e24394743c7a036a68161f3e010cac462a6a7ad0d58e174daaa686311d939547e71b91f8965d7dfe8fbdf10ecea2bd5daba436e2bfe9ffbb3c6451a9fe7784678b5e9484de0f9e69f970e502c421ad4a7848cdc4b73987cf2f85e660c65e468346672ab09ea8b106b2ed51246271bc9d21672f6aa0b3a9b24c8f64722842f2e24cb2a47aac689a5c57318663bc98756c199160f3a39c2148c574c23836dd060d1ac8a06794edd5aa068ac19e42ccaab951051756350c31d584a517fc9bb303276215580fda99551e82449d8675f29c45ab6354107cc94509ee55aa5db3a813adb8b04005200aba8f91b58a2d3b2b7d82c6461363353038099b7a0e981a85c75e0e422c572c506071df54bb7b715b9f4a42da1e89694a06475545d97a09ea36374f2c8ba40a5cc17eb1ad308ae862a26e38b2ffc11b7abe3b58509b21649b86aab9e0d1abb601604c4152257a6691a964657ba0d1f561402545b782960e547a4dab7b71aa95c67e64caf568c3b3144fb29022cb0bf01b895e3327d019b591ca282d22105da99b58be42bae7185e0b56cbd0c56ead56b5dd34e9bc1859b927ed78c4ee1340960256a0b63cf4e1cc9e84a53a48b2f70c3c89e83a0005d65019a8419b5166469999a453418cb94295462d9256ccddb3fcf8365cf0235f1d547498714a8b09553182fba093f447a220146182a3acf062a118b22ca49756505978f21db629799cad72ac5d17b2bfa52a6ea15672537899a313a4f0b7df3f8639906bd0163735dec5923a038fb7b5856570e279275c3093998338cb595c9a6b712c06c526166a725b9098ea02ea10c5d7cbb86b935703f122dedb05233202968b59825f41f2c17ba76ac661fa69a7998c5fc6c2fb68a7820576b1fda2c73daa29cc21dcdca47adaa1b3b5258c1575fc9270712f3b8842978be50a18da45159b99272162891cb8a63cacfbc30bae0a4364c8a6537e1b40e825c4a311488b133956690e494443ab44793d3717582701fac5486da4ffaf02c058ba688fb88deb3c94e7445cfa89a79ca5f4b991abce25cd6b74afbe9c63dfa0f40180b242ab52c1a455c0664f7357c048b27e05ca46b8605e6843c66fbc2a6a29be135c39565a916acadbbf2aa2656125b603bc88c9d710399a84850840169be61bd4ef3687777075f0c7870b61903a26e6391a88b114e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d213f0970c03d32967b06cca4cf58e87559128d14cb3f876a1ed10eadfe03fc1a9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = 4e2c094b4f5e09e17f2c05a8931715dff6d0a395bc9ee327e019b3683bac51f148cc0ff627613a7905a8ed870dd1aeeb7ab9e9055c860e92469e5f6233396e37700af8c4dd1a745acda15142b178f88af9376014d1153c9359562be9e5f87c25c08961e7fbdd00d7d9caa1134f18585a8b887a6364b92495379e6645f6164925064cc8882d42933520aaeb27cccaa919a9796054738ea4f815f70a56192c80faece06005aa0909d8bb58924ed2cc91284f76e33620a1d1914ac0208f1b95fbdd98e34b924c8699b9a0bc9cf686c75ce50e05873d2a95ce6cf5da1e5cc92e7a73ff2caad08dfec1cb84e8ddd6cabb0aca78c42261ceaa6669c917c7bc0b24d6c96cbb2d2519738a50f6a3e233c04a6243111c7fe5fe617770a89e86efa3ac5f510c0c5a8a568364edb478cb43ac0b318893e9a07982d4564cfa70cd95fa10191d9d3c1df1814df49d1353fef8daa5f7130f8b63b633b7afcc3d39256d281993c013a2743ac9f8b5a727248e9336f6d7922133d4caa79e311a64799814cbe22a8c3c9ab8f70f09926c83dc97fecb39aceaa421dd08fb17c72dfb84b7c7fe309bf65214af7d800d7f290f649e5b7e7d3bbbc60cbc89b03882cebdada415c22ece89194d67b663e4d3129646b3ca5ef8310da467b6cce1db6c3016415575315e6601fb7023143ade3ab421f3f7abcc62641d058bc6b25d5a4f719bc218122831ffed894fc5159ea86ae60dcdf69b0fe5a4a2bc6da7eccd007e7167c939c8b0b730ac37e9917fd9bdbb125e6708daf97f6e5273e533abfcf478d8aa22c16724bc7c7bd7c8bbdc01f6610f1527832c3a82b76fd44a2f516cd7c0c650e6736353244c733f9d23b06dc25222c0b100a65464196429760e27b596ea2498b44bbeb9652c32cb960a5c501311188d001dcbe04963739d3653dec28f948f5639e0153690f75567ecdaa21d4a113f077c8372a17f89c08552850317975911307a148edcd4baa130ba91cfae96c2db73d4b46446341a442cb44d47181f3bfd17336b9d0d71d63c825dc606609bc583a59564dc98ec68c908e754ca04989cd7a1dbcf10f3348c1e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 50d47ac334a631e3c9bf8aa02bcc7e3537f025cc37f8c8446427d4237df9a3bce4bda6458c33790d8d6430bc47857db94f164a1b074c60dd344679f2f41ca7c70a61c0e9727263579eed85eb468cf44a3dc21f525b878645a7483c19e6a29bdab8ccae7945fe45cbe86806a29c48ecacbefe0c5d58323ddf8b874964686e754b66a67bfbdf9d826fd34938a46712bde599bab22a148c800bdca8455ef43cdb5289e22be3cedfff790714df974eb6826ddc50679de3f534c5ac875409f6f446c6a114a989cb7b4269a95e3630c68fc9b05d5ab7d3ab6543f88ca3e6fec5512d2ece2866ac2649ec340467baf3ab3be8c007587b77d7c7cd1dc037cd6d8d1590f417bc2c99d9bb85acc9df9fadaa766e89788d4d6d35da78991adaa3aec0d0f92f74ce52cb797f976b51741eda35fc649744c69529c354c6e6a8ba471496970365b1ef9ffc663de3654d5838d398ba047e544fad71d831f286f799ef82d848e730184eb5536b85ec8d0f59cb5b8ae0d2334f876394f2fe54be6f72bcfe3ffc243ea0c53b3ad3adf948ff135766d5589769b7672c6ef6ccd6c89297d9cd638c28a38c0ac9cceb239f147ba6ced8bdfb39688e1ab90cf3eb44b76c32dbaedec4b84513e60dc4ee1908fc401b7a97d44161dba79da9e468635f04545982f7b818585f28b3f0b744533113515ca95b9cb37512e339e716c92569c8ee9ef2c23ead265b7859bbb06ace36819af4250339e1eccad295cf9506fa0bf9de2a94b21ee4ab84ea575543fafebe545cb97e00be91221b9b379db06d66795de789866960a0bf6a5d37814ed9b7f55592b02a6c1205c8f1cf3f0b79eb6f74e94e1f70f814fa7eb6563dbfb17808d9abcd6fcea7432c0f5499499f2d5b8b476ba469e7bc43e4a091e88bcfad8454e83d2606ade78a4984d6b6a5586c0419d05156fae79680a676735267607b256d5db4c6a8bf846a83d93885b277043b7e98ceed99bf7449d4438c8888064ee2834109b7d141f791e6ef6bb538e30106493595de4074e183b4c1f3776de14fa78e0966540aa25cd484182b30fd3cbf068eb7b4b3e251ded3b77fd059720c3d802726470d1c567b5908698650360db82700e7b9dd26013b6a8184316df3c59194fc96a0821a95c666ec5b130262006442cef64428794672b43bc1eeba20de01bc70c15835952164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789de2153b3f64411534cfad0adbf8bc0aa51bdaf396e5746517c5547b3112fe08188da54932b9b458458c55f146feaa9620e7bb6ce21648af047e0027c3553813aa81574f26483e93a5ab3642aa1332bc34f86328e5f80b272aa8971d175ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31a9b27d3b17f63fa0e0da16a3e54bc85da61a0119a95201fa51906d6e2257b2cbd7235abe8b80e80947cecb5ce87f9af68442e8b6336c68ab0b170a67cc14f5e5377c4cb5930705775e522ca466dfebb1aa800b452262a01966ff624ce79561b3a40258be53512d01b749c25ec903923ea58e6677e02b0430e996000c637d002ba09dac9e717ac64b634688b558d598e4017cbd46a160c621dbb2b961638b08a488fe8d814aca37165a43ddd4b3908d84246794678823e794c9191332f344077ffaa50dbd2a6e0692addd353588b3e87e31f3ae4030b2371eeb1cad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4ab1f87235e1f114cb93c3150e25277459c43a6aabe39af63eac248d19f21b17ab5a2ac14169b01563dc818552ceab71eec2c2422c3e5f703b84bcfb457707a0b3edc80c0efa324d407d077cab9b416b3a97713b89c6d65c2584ca652e6c4416bb44d3e7478eb21ce1a555456b94271689828560eaf4394bed93a86d48ec082a7be576b75d00ec418228bf93c7037a49339352828af07f3729bfa739b00d04b5502b9d6054ba525d724a0df8506d9ea56d750072868cfcf07716af003a02c45d4991f4503bf5ac86024857acae4ce24850def0632a6dca9756c5c8a459341c69e93e154858b7c917592bb91c23ab622d3f84b9c81445e5a1e59262bfbf025286bbbb5d03eaa794445f7839f3ab51bf5ac48c978f0310128817d27e658d9f468f77c4c69da09dd8526539c2598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd083553153f7d65cd5cbe201e681245eda61e1ec2c7ee6b91a9ccdeb6b76943b7e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = f58035a4c7772f07420775b5ea7701f30a67a905e93b0131287c8c80727b2ee674004421dd48098281580c8872e3ecda197617d1cae78a4e9c648e64a811f2c11427ac3daa918a67141df332a7ef030cfb2a7f8db782f564010077a5091fed691b8d60a940e1dbf6d11326f13251e0b4cd0a44db1a3958bcc0860a87e430ef1b6d16ab6436ad5a3d79e9f20fedbc75baddafca29be9a308844047e26bae5846e00222aef148fe6e71009ab6c2c5c064f129123fd437f30953182aa76a5d91b1edcf579c59887466afa1589855752bda4e642bc99e61e18546e5324b50a8e012394d93b4c65b0c2f284fbbf1ffacd96e41737bec86540e86e98dfeb9266495d944db588f091d21fe0ec3d3432bf1b4ba4682690bb9b1124a0b9cc2212fcca7701d4cd75f5b91d5644b6746ea6e971b130d554be196e51d979e2f7cf5fd613f4d4a1b689a0028bd5f42f772b3bd1eb6fedece5cbe09bdf6e7d4fc01067c71ccf7ec6679c024764753a7e801a93b1dbb3d82cdb35588551a4365b0a1878ba8a3d4d7ce4f94bc03da0a30ba53873426fbb73d871a94af67fb7bf585d1af2d393a5bf33e063d2aa37fda97dbea3f87c7190944662b0758339ae937b7e60aab7c8350d1d7052dec7734878dfab0e57a84b65f03dcc2bf5bc4874a435962d7f1d41b46531e24b6dc01411e77b6d07a6e962661af91fdfac2c10aa0151aa7f6f47af162c21ba79fbd72f176b81ef412ee9784b8833a3bf76d4075333a2d36c22e8f999cb96aae94221f98c9feecb9843dd8a561a3d09a88e9f514441662e5f1d66a986d07272b4ce1b7575d7c3b0c4542904751307fff429fdfb38e82f004ffd8a3f23fa8c05fe59097f88ba0764a78d749621b5ed51d7c03352b574a1c85a19f3af0ed5916d15ac826caea0ab3d3bd81832246315c76cc0f434be5f517f07c92eb8613b5a736ae66649c4a5a53912e1115232f72927a076109db03aefa247bdb1f00a7d5915c3b6362799d7033cd0f86a43c727e4a293916fd0c2c98a66e92adbe40d562b5dec0dc61578a9c8c10ff30ce8f1dd24633d7db16ca2888d896dd1d1c13375 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 456c6c1d6630bd63c8b0243d5b1a6ecc09a28b09bcbf96cfaf056e937ad184d6774da5f4f4b6d00e974fa78795756f9505fd9a12838da39c7a90f4637c1bcbb16677b59eb87f653aa41ab5f7ef79f917c65403a78d07b136ac8486eacf4235f428c3b09ecb91f7a953cf98484b036f497ffa6dea3a46e7b33d6ddb0e39620b74df6c14be17fc6d04cb815d4691687737f413491a8b9e31ff8c7e2bcbdec9fb22ae752c6f61863c84fc69e8efec49641ecbc7557223cb65f2169eb7eeba98c4fa56c7eccd6e33a7c5dee454fececabacdc960856b590f5792d973a3ac8fb3ff6b36b64757d04787e0c4728c0649d0ee6d2febac27afbfabf985cc9beb561eca8586dfe559b2818ff86e9b4c733be56ebfa9d18f38e54336a87837dc93b4742cac0f05c2d75ccdf06787b21548f29f80c15f98bf8dc79296bf9609a8d88347413b426a48d01d59cb5787513fb53a52adcd39d9d3e12a51299ec43d39372fcfc0f3398dc19e729cb8d061eaf485bdec58b8530966f68eb6a5e76444329dca2ca896f24fc16d83bd940e4ef795facfbc48c98dff1b39513f0fe050e9feafe74cc057adb1c363f59a9b962697c37892759859081af87d5b7ef62a4aed7e80215e9bd5b59da69c60a249b55c68c2d523a507245d39c8374c67ba03de72cc9889387ee49bcb6fcf93cf779431dea5e32b0f9591d9f273078a403895c40467be735b6d2346dfa33568f654a25b7586e63b5b9fd998374a0b1ee23cc9e5513ce557b4bd1366be2c259c511492d5cfd0f9f6e8608997b2c8dfdd873a42859d9b98a27a2fede3a5a0675fbe7e948c01045ee42ad8c068519eaef5a7bcb79c5c713f2c4ca4db7c30f9a7a715fab78f80a4b59d22844551f4d28f8740253447a479b5febd371ffb4c3a1d4b52ce3a3ec7364857a775f3a8837978f66dc3115fb01f648dacf8440eb3500c447ef81641130cac60748cb2fed8facc918bfe65224b91fe5fc7ea1a7fb5f83217284d5f2dc9510ae0e47352f4bffd81ddb95875bd8074dd9524fdb2639a830ba302f49a8caabf01aed4f9be36bb75a38d1682753d7db9de36ee08cee5dc61cc732b09e221ad8840d101040c4428a798704db118c037476701a79ae30f9b7265038abcd0933d1100492a6b2fbaa7c0d6c22704571520f35e322a4bef080fcb4c83bc62c432f75f6ef22b2b1722351343cbe4460b25b4bc806bac542576ca42f30c7ddef6082199a4edc2237e5271eeb024e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4e0168ccba259bc99b9f4c54cc2a8c1489415c422f70249235235f81404c3601079a3c8095214ae03c86bb4a1487a00710dca3dbac8a89d045de4768e56329ec6709a9208df6d3af6f8c7ddd6284f144120e1449bfccc6cea22bc3917c90f6591062525804054553a46a226093383f12b8529d306ca2fa03f3371de8641463a353513a593d601f91937c3197cd535768f78aa4ec11c4f59267b5fa47b0b2312ae97b77aa1c3631b7033cb17b5a592c89091d0a2062f8c7299a2bd7f77832899b1a84ae67a3c11e87b17a0050523b9a9bb87db0152cbee582b9d821937a2770d07d6e2113832c1456662ab38475a1527fd23287e45822c5d0c19875cc4c60c9ede44722552013b6ad7ee4b860ec2ff8337789832002026d7b54676b44667961654902912e3116402824a64cc67655018803ab2c06540123166d78b87be63997692efc099e4bd72d734b1e9dd6344df12070773b06c5c1ff3b32417546ea5416c204917f104a3e603bf1f09fefc3184fa43f06200423c3026b3a2374186df33344cde1ccde212ebf626410907fda57a9538b165b3911e016438c4b3f0e485b3ca3001ef03466a8749d1488e24685fc1cc89e012758473601b572acab4db6a93edaa6aadbca7924c23115769db3a4185aebcd09a9b045b3437dab3336b47a6bc23370a53a5e327b6654091f9a435451cc26b41ecbc129ae109475793c3977b532c6a8cb3317d3270bbc6bbfbcfa1c2ab2c41908520184000e3b62dbc3005839200b486d6b89b1719505f6fc4a3b7a41ce4a4677b64688284ec18915f17133f81c4f73c13e14632873652554685debb7b987c66d01b9049f6b2e44960022e7916b61a55c12c4f5e099ca059e3f98704ad5ca1d2676496c21782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e225819df5746a44b10c1886f62b068d18152a85792781160e1a1a19a25b5ca00555f4de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = b7fb6e4809a80d079c30383d7428c7b85b84c3725dfa7d4119f5fb21c713207015500d2588003c3db2f2a1c6a771ac4d948565d51e9405afdaa8ae5d93e268a604932041bf8c6e8a69767706a55f0805b2e5d9d9bd3e35c594241bbba3805be580f63186320a8061ece24ad66e5f557de610e321cae9509e31196462d633fe03b0ce992664c223074ee5459c6937aa8632e5311860348b914564234c60640b4c8eb34496e1546bf16393893b065c1b58ea733fd8115f97620131aa216890d8c5b5146f99bb6004d76f846431666bc23a3aa3a6aa6863a82ed11291b1284b4ea014acd1ebbc31c9446c042a1678148b0edd54aa5de979be1c463b6d6c2c86a5b669db2d09c7f6942c795529110144b6d5885e2bd035f82f5115fc8e5c0703bf23403def796e03e6f1a372e25038da584210b1a07cf2ee20e266a7ded2198a76a624d1e0f01c6430dc24e99d2efda1b0fbc9cf964cf31f4eb27f819523180788308729ed77cf2b4960f1855cbdf7f5b15b10ef06e9c18c07d8364f1286aa74ea3497a73467b20b3ac49d6eefa4d70a83245538d7d644f158d0331d10238e929d28fb12a60d76f536e929f128968d401ae554381ca24e8a1e89c5e480a5f79f7be672b7b11590f68a4c319c295962907f4dd309cae63cb00f046082dbe60d768205f69577abfad67139310721025ecca91d77b890a02aac012eac4e87f1a6a3c68f026541123b22d82231c295d387ca7ba7bcb620887a94429a0b8c8194d9ecb533a86c1b178f29d1080f05033257304a5ded43f4c1968b4bde413757b06b565f79f124bace778f08b523ece29a84516c7eff38f56bf89b99fb0e2f6b6e075b44651d146195c6710229fd57c8054c073ce48224778b317aedfaa85ce534370252bb537efa267d5745bb049bc2d53abe121cb4a5290ed77c8974f4c491e93c1b4c5e9183a114cf32ca5e3e8549a00e68fc4dc595f9e5dbfc8be5f2f94c693f87c66203e6ec345f96286f3a0a19d6fc58298ab987203be622df26fb417b00e28be76e57661d27ce69ce2e25df76a82d74bf6c0a5815c90b0c3c166b6f43251ca0a1c0 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8ba88eb6987ac9337d48bda4a56748e37fcfba9bcd68fcd72528aa26b45cc407754dfd7202a3db4247ef012c9e4c3bf3b79f52f8e8f061dacb58d7fee33bda5aeb7feae543345eee3fa56d7aa46fc449f8049f5ff2c4e274ef3428f3a636cc99fa855003d6ca508ef53e66b87d38e5f119f898b942c7173bf64832dcbd5c4398c9366350d7d9ab146c6208498ce444de75e7b9c07f9dc207c37f1bb554437a6336535b4f546bb4b4d93fde876dc785e96e984d30d83e5c94e394f8c8d56ff3e6359d9a0537cb215581ac29cc9e545311eba671c798682fcff1567851f7efc7046b924732280ee37249a7acabc8be35ff4136c9b9ab6b5fe9fccc8aad3713f9d14e8cb96a6f037fec01e7b00bfe7197cc71436537958f6fd0cd5eea1e86dab5dba6336aed9efdb82e8c0e39effeb7d782a46d43e84de1c7d0c3e3a54c1839fa933945c4bf5879f9252ede72c3a7fafe9f6ec743d4585163f8d3973b7992fa8f3b087ea14a3d5c9ee0f31dee72ab8a79a34348af4d74a68b9e14d6f2bca624454d1a6c77dc1aef9fc3801f8dedb5247b11cdf15c474086163653ebcf0b0b66270d46599a9668254bfc8871e947c6f8b5f12d7f45648cf5339f89627fe7eecbe5781fdd4506ba3446a9914c512b06fb30ff6d1bf4cf582a555243fb239776b00c7730cbd2be799df92377d16c957c7f6d89b57b2abe3bf39da6c45944d37fce117b6c5d596bba28d97429b6bc6bf0439e9fa83630bd55934ad7400804865c0eccfe84bcd183d3eb2d5b3694cc057ab2de4fcb6836f64928a05f2baad63da62ff497e4ed9a6439ba8799b3a20865ec44dd05e7c4c3a596b59cc62245a1f2c5ff0d45b93aee77c595a78cae6cba965044cfe0bfdab8e53f41c26973654a737f6a3b8d7dc3f2c472109c89fbbdab41fabeb2268095165b8e1ca5a63a53a478b398bc5e85efb41b8ca6d2d665920ea9c1a97a11ac34fc2a83757390dd0d957c1f4bc2debe92a4ad330ebdc59f4ad4ff4217bf894286640546c865536d035d8dabe6e9a4cf58756b436c1f86b0fe7f7515e1d14cd96005d90d2cda011989bab77db0253b6f70c439f9cda8e34b944822c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b393269fd3478d1836f80a9cf51b03fe697846c44abe549aa16a25819e38c9ca1262ac103f4417cde8138f84050c0bba5ffb5090c81bcff1bbdcd67739bb60d236215b8ecb5c9002dbf41b36ed335dc4778153761472421d2043f06a8a83422ae6fd0680b860cfb589a3f5b85ebdb94b3f21d24f374949563e8a35eef8c70507c47dccb241dfb53be08b129a283367b48894c090b523e6ae0637fb4894707812ea9b528f54395d0bea3bb3a6772881061c28b8c24ade167633c30935a6c4f29a68fa298bd0c0bc1729c330953fdc5bd6c92595d576e4d6cb45a4a213aa299512c304fa2a3f6b1cd8d545150965bca39703efc502608bcd1e42da21cb129400dba7a9a053a6cc17066d9d98899d7c4aa3cab66b1c13d58251eb196959a6a250ba45023b9e6a6a8d192c0eb548e69d20c68f0bac8ec682b366926d62e878123e198add1d31abe91a02a5cb6fdf6a40255bc3355809fc8ab529a00b0d451dce9a657e961b4787829132a7192139532195bbcbb0fdcada2c515e3a83cf2485fb5a28f648981ddec7a80470540c71d53c29aab8009d9067c703643c1062165e3745d3ccc4e5249efc87b9f73afa08b1915065dac1c4c68422f89589526188ceaa19f64f0cad4781327e85665b5c59e8c3797f72642897db4515da47b994b2c6d3e41949363262dd721573021aa3373aa22758fcc22dbac46806c9005001c92aa9b05d0c789dcced4d427ae762f4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a4e194aff46422fb57fe4b2b2de18a060627c3f19b984aa7b738bff9336f80171f8236a3e95372975650d6b28398865f206a1bc81c346ee76999b8b889c83551f42495000eb9f5aa3ac16b9247091469815cf4533eab9be2ca283b962ab0031892999b55822eec5503d7201f446b21ec3319813a4f7b70b68a438c6147c182c48ded8c5fca18b2c7322fc3e4341eb46bb130464a7868c5d3ce5b1bb479e69bbdf20dfc59380099ccfb06789fa1183c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a9415ce164fadececacd75fdad3284af20c52fa576699029d6e0ce77bf347d520be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = e756a73da5006a8722c6b9dc0cf22c88ea6e0675a120dc5106da63743538ce258cc7f2d76aba306cc29a842af082da2ee435af8a36c664f7215ebded56b65778a236d449c2a7127efb4f76b9013680ce3c1f79e3c354c82df0d117302bfac8de889b469cfbc395efccfacc213873cd741cf32d9892d24a671d68c5d78f45f958d77922a25e43ffb8c3d88d1d3a622cc6cc0df3385340689c1dd5b2c28984ad881cd123ba1c3a11d8b20603b5e3a9b6a629b700834e450f267bc706a40835d4872b2b639382195ac0556ab110b68d5994b2b43dfd89c7aeb87ff4bcfcca24fa249d80328935aacc3376377c26fda978d7ee12135afb76e5c4354aee066c0f8eaf53b7497cc2695130fe5e03099b66649a51d7bc772e0c24f1c7a29d0e1a4239e15006e02a330e1e831ba5f0fe864ec8ea2e4149d7361d73ff8c29c4e1555bec5cf7fb7b12382f6df0d4b20901a161bab4c1bfe78405ffc286d3084b9d53a8313f9181df118909cd7fe43058a4e8d95354a6cc31a4955330bd1a8fcd88b65ebd8e3ffb4719387943b9c16fb9c7514a81c15cb9b79c2f48c4b47724933b1192689ca71d662c6c3155b504f5e7e0309bceac043b085d5a2db8736a5ea680518a698c78d03cc2757418f88f8aa4b8901da6555778fd4e82e299af2464bdb1ce8b3b47b4339795edce833463df3446834c15e11214d36f8fb0f9ac4038240c1c618d21063065144680c34b30994029633af967046729ee3490d583307d2324b7e6288bd944f45accd0464f9761079fb0db5f7217f9574b3e4c6a1d356a6333c1939846ba676ed361475b53bd04358510b4ab69da5abc2ad4c55b09d8547169891cab8e96e48127e6c303f2ef3ac1af2f4f30812a47fb4d424ec34a690bdc4e9288c56a747b029bcb6aa81f9494b7e280172b2101c537ffcf8ba2755498c268fee4b4fc1d3392a9bfbb016a987afe70f0fcc4476e440a5ac9aa2e935d89660ecaa98b368a3aa06c5b745c380bc95f854c367fb32b7cd7c84c75c25314bde0353d1323d6550ffd23d3a4bbd8023a029e8513d013b0d5f9f0fdd7091442d6217f17f72f52 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7c15568ffee6848580380becf63793978e51c90a6ff875a0b125696bde4347b3e30f5665340954928447253f54ea9bd89fb665a4ce8564f65bff5ab648a58c2fa7c7caded1d065f02e1742ef98c68a3dccadb7e6e03877ea7c8cadfe373acff059fbd430cc97feb3a41efd6d2e35930e09d5ac669cacb4ec9a24cf96075e92d36cd8958d96584dc9c85bb695e735fbafa17e64a3ae3c253949b4476917aafdc2b655e2fdcb66fafc39364b596fb070c8d5a58b4541f8b32e6cfbc7bfc2de23e0756fcd2b4c5f793e84c06e746053f77a5f816ba4c6c269e0909ebcc15a951d1ef310d78d14c96add5cd43e3a341e17faa4bece842e48140d5a75a5e9700362fbcdf26a58a93207ecddbd3ba0a99f3e0656dc2af8ca43f8b4fa531c4ef7ed89d398a45cd0bcb95be6c91ad3b2fa4d92f7c4b99abc86494f46639dc5f077544b4954ce06a5778ef13e9a7dc24d5b2d2ff8ca38f4b4b433eb65901a39d3acbfc4183ae44efba1fdf9d63bd4dd5f7940b5044056eed6b064b099183ab5aa34ba4480ac6f66364c7d9f5689d7abc4792fc4572ffab3bd679f3cd96d5cdc6f2977472dc09378a8fce888243bc738a6a3e46d7ae36e396855989c445f228cad8728f951586d21033f33cf50c13881a293ef9c738018953ac3f53660b962517a64ccbfb1e26867c785f9fd2ead452c7bd66fb30b67f0ec2fdd9c5e7c7f8cbe1123a090359df30c3115e57fb61bb47f4ca5debfa443b9a2ca56a6f69de0d8ddcc05698e1ea539c339f0a94f4420b675205b9060eee7fe0c7bb1f888c7da6da16da24b55d813b6e3d9c8bde20c38665c918a133ba7da7c449f467cc3ff21ca3f7c47f06175b24217d237beff5ae73a381dde396e30a1ae5e07fda4da8dd4d90e82247f6b4556f3ce9a31ba25dcf628fea485f715bf870b7efb9c1484e1ce99aeaf7293648035954da75ba723b8ff4a0bfd7095e11709a63ac5b9f7ffd1be1ecb30f48732c84f4ee3622dc83ce6995ab82bf0a9ee6e1b1684062569f4ebc4f2637038f489755cc7126535d65bc6cdcda00bcf7e180d657df77a59f5733a3f3042bfe6050ebc4870419a0b91a8b97bea251b03c51630381aa802b51353721697c4bd2891f37698ac51942d44c931f205ac15bf35708806a118dc32b51655070cb196246b6a63db0c57d727d9aa812c676880e3532a435e191935a6db1e1b110cd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb78090ca1043ea8ebcaa3b73c768892832c357b0cc48e875f849149ffe63a21a169798b00cfac58eb666c9ab68729dcb60cac6dee1497a64533989c0a68b151f8865db5f421eae77292155f12944322e579d8f61c20ea53b34cc7553b6a97db6c3df847b8aab6b993c4af02c44d2c0ff555ba6c68132cc6b9c4766acd030c33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e10561965e45551398a9632169d6a53da1314a9b4533f4c223fcc46ab0730a8b463c537c2d5ab8c9956c542d6119f76b82afa13ffe637e09297b2e6565277079081c574b05d50ac2bc8e9538d0105f828b539d47f3a9a293b4b9b834b2cab741674b8c61f28a778b736b699bb989705890951c30747896508421068dccc0f990611ebd800c942be5c886a59b008e6fcc86956aba6863bd9558417a37579b7139efb5bc47b1ad598464f287a3d8c56d748c6ae794f31842fc3aca9c5c05fb5f76c5f740d2d7908e01a173b75a35b8a70cd645e66e8a6d290919f227ef5e5bea2816b31829cd291b136520fb1a2825ee01dcbba7ae9a10c60a297d39c7b40f53d02d602627879fe6b4c00ed426a0b065429acab34be641c356be26a7c5012b9643fef007577f79dc99459152c13e64618b9f9b3be0b551dd33df8cb7d890c48ea83b68c42a327ba25fafb5ed65c31f4e6b639230aa989b1ae7a2c5ff3224b33883955890e5c7aa691463e58977c31445fba5c408047d227aeee6bc90697545ce0885c3abea2ec9668359e59282c22a0920ec76a282c545a80896f5a4705c02adedbb0f8dcba46f36c112b578e7b4c236899d81259706c3d99b0adc3ec44e58171a5e21c052767b7692800854132624ff438b03cca42473622a6db189be32c7e906a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9ca2232297ba8b986dacd401896cb6239f557720d91a2cfb7a73274bac7a0f6dea08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = 329030cccae3479b35d7c0ddf09909c9e95e499c46a4843a29b28ec0990ff257f419ea1adeb11186f273df00d61e84d66cfb5b09110d3636bce91e7f7cb9b480dd22cb6034f85c1600a764d510dec4e10daf714bc3eca661c2e1f53b266e63e9c4e92d8d7d34cbadcda42760c02803136037a02d996855764eb55b2713f3cd3ac9c70d59886cf05382478d58816d37f1b13dc0cb5ab6c43071667ecab8d10f5b220ed4ea0775c6f93000a57b80d881a00085d86396119d832fbbe6dae1fd8cae651c2fc5c25c4461edca02c50553b98a21b219b50ee7ac4945c5b6b203ef3d42d243fc789585d009e9035cf5f12322ce47cd04bb5179c065ba7291f46dfec925327f1692b63ba33a2f40666ca546597d335221060afc6729312a7985d3953855efecb6340e1966520e0af12bf88d8bcd413682a74a0bbee5bee9930d4d2d79d194cf9bf72d17995eda7a6ef970335f646693169d904193b35c723cfd2df1f650e54d5321df3847c892ba6b699b4567ecf3e83c4ed2b9fef04a3f544a3dc6fc0eacf6b3f7164b0e482b610e79c2b1bbaaf42df68d4de0a94750d0a4bcf39dc6a60202b7a23eeeddf155e348d4b96d2d23aef6ce8037a4611b5a0cce68b6afd284f137b5041b483d7d2cdd40863553eb99378b53565b364a3e27f88e60a950b2d6099b100b495fedcb094268874db1e341f8b17417570f33c2aa05270b5539b9a72261ffd9948fe243a7faa213144e12429c47c19bdad12ea0113a43ec269e0a0740f3a1c79c5af692359b23ff9fa7e256d32fa4782b6f7722bd0e45e1c7fe1e4fb9e6c3f5b916bf8ec2f52847cfa2eb1e5c5993815261927f2eaf914c24c4d279fec6e2ec7c5bddd79785f225a22f0261c99185bfc0348e7f6b6032e68780d3b939b8a9ac7c44ad8806528f9b5d3b905aa5033e7ff01660439d5b897e9a53036005bd8bbefda602d9ad7d4b8aa68593515a7411b5e965fa265b19df9c8c295e7461d7e8c5768758a806575e55710d157d5235fd5e7789f260a1f02b682416f9bf6869bf076a5a229b2f3445d52e959a03db3b8d859632cf3879c79c8cd6ca6a8f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d99596f52da269879b1e577a0b9d9430147c8a03b654d4b4d42c348c14e017965b130f819e66624236577905ffd935a0a7253a39cf5e5585566714fe4ebcd504659d64e83b9a1bfa164f8a915fce461dd0b2157630fdf40e3743bb5f6227dfda6388b9d0935b208bab100f8ce8dec2142afd0dcae161b44dd3269754eae0c9538a22eb9150bffd0a364c6433736d7bbe8335a183ee4e269488a79c63233d4ea2c438bd9b9a6f07d1b8babc0f83d33993d0945a6db1aef29a44464ffc8d3dcc615d7a7922f6fb134770bad9a9f71839830faac3baf3fe9f7b003dfbb38c990b8c4e5f1789f6e5e520647b5a94badf2be48a38a4990836937cde9c294e962e8445f3e31ac9c57c88b7da59ec15c9ee906c4e8a9ee4672a9c58fbd4cafdbf7acdfa994df7d5b5cd5247ea11dabf91d79329eac48997a85aa64beb6fe7c44cf57fcf784113a190ef8402636139075b5d76aca968742e6fc89fc5f8ef3ac9f30c5f23a94d8dde9a07e88a26df516718ffab269a0f1ed97996dfb7bbccf69dd30dd58e34993178097b79034aa67d9f7366ced6a4978b6cd1c7facadd7c69d856be8eb836dbb9319a575059f9541b1fa0bc8697666ecab876dffd4c828ae534bc5a8b9f1368929afae6b397347cb7cdced4c6d3654ac497758480003efc32944d003a7c0bb944753c447256f539fea34e3ae774f9f95abb54a1aa59eec3e7e9336a3b8683478d6a4dcc305585dda30fbb87e3c1ac97f24f4fe54627989e35f558655b08cb6b878ca8ad4d3be67ef1165eae7af8a3c9e748f24cf92c8e93176f515ba3814d7a86ed7668a5fe51ad9aeb4decf166bad07807c9be59fccba666edddfc887aaf9f47649fea6d34b4dca3a8d6af384b06b548ee55477b6afc0e6f375bf6c00a9b49f64e71955fa2a6fde981a8ca034aceeda83932a938a7476c21d6ced1a6874cbd73b1646663fdb3c3f66550ed32a61d856c77f6503fba16bb4df0e3f09b0f541379fb425bdb01ebeb5baa4621eac639d6d7701f51b116f17c88751aa93d28873ad4e45593164077fdce7a9f5e714752521cf728b96d2f53cadb79a51c96b6e29100ec15605818b877d7399d4c70c4e3b362a3268fbb7e41d494048740ea222bc38b5ebd3cc8d049a2551a731ef31684247f30fca3f03c0a7d7245d0e81c25359f245b9523040fd2d24ac3941a213b561b974ce45156d268a0d6c5b555e251e18b31b7753c2826bf6654453b81a11478836d08c6a803ae48e0892e927960118d456232025c3f516a99e4818627760c88f3b8813b57e9ebcb37fa391fa1c7c8bbbc358b40db908b526a85ac86a03848820879314ca86a2c326f5eb69e7ff6c5a0c3779c20214581bb5f4973fbf54353fc448b0b2f00fd746f303473717ff829218b22bb23eaa132e31cce576efa0a53015c3788c82ee55a69051a62b6293aaa9a4398d61d25dc679964c33c6028448b92acb7ac1115c50dd3b064818cb0224209193797ea3df48b6ffdd8228d148514ab0c11b1840b3843a7472876231b3bd91822e8469a5095acf5b2bb5b138425b2d60c1e018951951917630b8da2372aa239bc88d5a086b0b6aed50618ab25000abadc6684266939d4468ef5c651ff69b11b928355170fba871a59eca1f7073689516d17ac6298d2520e8328f3cbaf8de33969ab089d6a046bb979c3365b2dd2704c359c04797384c5c7f28c342227b045e40e88d4bb5c792381e639c86a12885596144b1a6cea01ef9794122466e3bb779e2b0ccf9048f50557d536621d280b02547234700e442b6278d2b0cef240946c542292c904ba31a6a38cb9328874f824fca0504238bc090bbb78e60b2eec76c900bb6010240b839d433c4968833715121a884b362fd8c8eaf90a241b66d7522b6908c43890cea4ec80ca232be3ac573bac2428192087b43cd15891585339a6123475209af6c132be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca662742950f431c93a391618c2a410834c2231a92c3d91c471803f22543ce530a17bc924fc326aee4537a5b43fb655e00e46185e809996b87e27c6361fa7b53da5ab393cb56b1b9676155f2e57092566590642bb090571c6a92f60c55b339618389415c259705fc858ab71aa50021c1191359576c8390a70e703f32ec26419602cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f34486689b387ba25dd0e9aedbc53034924ea4ef9497b5772f10ca4d091e9e84684ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = 47e5904f3f55db748f9537a2a365dce063afee46eb5da5469f1e53d601a8883f8d4f751845cbbe9fc664c498350a73b80272d1a56b3089976525f58b2c5d69b7521ba45acee718267c463dc53589ac3b0df5d3d0e32a9bccbfd11571952c64db6e1c6ba8058f95df6b472955ccabe149decb08f8afefd1a3c698b4ef5801c368f83e54f1db222c3c5b51a8fe98819c89d0742e4d9f22df5354e11eaf3abe6b47f436bcda3c3184aa995f3aa44fda6c60f10d82170bd6947015302c51978c0012140d99cbae6b05e63d74ba035a58496ac54a6757dd5c3431b7e0117d1da3b30d8d61ac0b1f1fe0ffca95a0ea6f2934693e1980e6e46c6ad4cb17ee6bb4840d5d2a9e4e18e68fee480c1575f41a865385eb017c7d1e01c9c5ab263585b88642e936fa6600c3e4f6692b68167aa8b357c543e479ae92b47bd037688b017800a07974b01970c4ec61775a52f6828d2a093fc71f5b921f03e8692f512ae3a3c23af1eda49e6799947e4b4f83fe509a476efd5bd8f411c5a349a848d81a011387e3bae39df806fdd847ce885d0a8bf16030363d66e96f6a98e1bce87becf2a86ee6608fba434e8e44ff32aef118a17e5ed6eed801dc057b6f6905c5fc5695e099b229de0a0c30f6ce0b5ff358d9fd329cca06c412a4a94e5e91dfe076d38b7a5ab73b229a94418692fc234e93de64f7489174f8e29c0599a1431d8280830b33c396c591944e030e3ec4ff2090cd901c05b5fd1ca29d95e31515e15500935c2d06ebbdcf655dd9ef555fa2a95ad8ae6f3a7b6d60b0587e92e4b1a812ebce6c8f9f5e5f5e02badcdc5a9e2785dc9eda60c26b687ba214a663cb45feb42555af941b1a565da858a6034c8f2ae5e8fa272585a82e7ecdfc993b2793ceb51e458a8acea14edce88927fac5aa03ec8dbb575625c1773af81ce52ffc7285b3f5f8aea31ae908936e0dca950a383652f3e914048a86cc6473d4701c09150c8de47065d06830dd05579b2fc6849643b50d2d23338e973dc825d1b0c55acce3ea0499e9add6233ba80a134af4d24fbb98bf2e3ea7eba53efaf3af0fa5856d3a5c4b2c3d44af2695 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5f3ddd8f18d1023d81bc5af5b458d561b991d984e778034f87fedcabeff0242f8a6d7b49828fbd3c8b7706c3d44bc8be8856ebf6e96e851bb4149aa60a8eb061a45541985447ada3fbe47fbdf9a7680bcee9d9a004968b63e53554aeef2635d0d13cb97e66554d184c30bdd5d5c56a096558cb8ea2106d66fa0aa22895883f23889fddf4c95de4619dfa6a36c4215dadc1475c59fd8d4c7e35c10da76f36f18d946289c3c4fff8db6c9d3b4e8999c67b59b067c2349dbf134a9acbddcfb25db09249ae101b45a8cbd89a6fb327173802fe56984656c63398cec94ddb6454405464cfcd3d6abdc81c6f9fa6bb5e15e8a86b36f3f9eb7d44a4573ec58de92aff478fd42a59d19187870d3b3d810658ac75f9ddce45e8f4703238458313cbeeac8f393b4911b4de809dcf8efcbd0997f89a899d0aefee1ecfa810d6edc14eff2ef95934b7a86408c75923616c15594cc3cfee4e88860d695cfe50670756201ef9b61ae3e1d7a8dc1cb9cbb96f922ffea3a68668488c3bf9e96526361adf8b22ac557b8b39e715d479ef5cc418ef6c255f2c938c225afd8b1eaaa608acbd6a3f9b2ad97e36661f979ce7db8a7064d06483ad74564fa65b7c52d6f0ff28b6cba4ea7067d5725f3e419b900a16be7bbacbb437ae3f1376d21461672599b38688875cbdf489a0e18d714a83ec6f147812e688db77a1ac19eee2beae24db55aa67f82fb3b96db7de4f35943539e8bb2d7b0d97decaee3491e4b2d52cf01d6fcb22c896c7f342c1d98d05b87fba883c94ae7e45df7a579f89ef888dbe73f42b0f9ad207cf54d8a8e05e3fba39c828049b604a5ced06bc086fc4e2074771364be76f63440a6c828359bf2be29eab51d3bce8ec6465ae7fe54438d8b3036714f541abecb6679b37ee76600225c191afccd6674b6e95a9565ce56df4743659ee380c78be7861249647f0474466e781caeab7989838d9e8fcb355b0e3d5e9641f9e57153f2e58a7fc843968c331b1cc57eea37ee124f4ba6673a8ebac244d5e86c77d0dd3e6f708444649a9d69d7318044ebe4857f69a5b8ddaa9edabdbeb656f41149d4edc45c51bc84c04b516a56479711aae6b9efdc04afb251a0c121b249a03cfd27d8c435892c88c0db5291de3999db794ef43a14ef966c97c02764bbcc6786500cda603062e54b0444e52835c67b5bb524f52e670553c24cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e32207c8a255dd72a3de5ab401e540359575689233e1693f477b8c8e027629b1b2815b27b9b557f8123950b307a9d91e1dc2278a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c862a74730f16a223bb97af8d82331b7421172723473ca0f3e24ba744b2bd561900c45df2f3bd53ca25df405a93ca4ad222989a58136c9403ab5428b908ca82ba0436ea046f548f9c00aefbb27f497a15ab108f39f2829cd38d9db01c05e717df09d0a96b1b24c8a6e5e5354787429e559d61c853c1354f60dc4ae522141beb5f3ad27388363a392275ea8b7d08b68ac583713b714b9cc79bd9cb265d91666242429ac62fa6991c2501638772552ea54652b4496bf790efb876288bbd6cd4500a344f0ff17264f73d0a1a10e4d63b06884f8a5c3562bc8617ba4f33ca14e3b40fd8117bf547b5910107f5863e7ab3c3ebd98522f81923dbb55eb43af41a1af1047b68b940bbba364ff69dc57c60c6cb88d4dc43d84c00b0437dfbd913ed15a3bb84c542137acf1205f4826fe82bbbb701bc00a23115ba718ba5c80ca301aa970d303a0a9e5b64adc04aa8c8c12b39513989a8a27a578309661dc31a5de69bfbb11308fa2ac4d701be266cfe14a03e961fcb6132e7678d5fd06fd1a74262837b8b7228bd297a9685a98f217976b527b1dc0662d6238c8c4f05aa29b3cc182b78a7f29172bb2a8b50fb861624cee1c19f4f0739cbb157d8f60090fc847765209aa4b9b782127f400ef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec48c2ee05996e0535dbab9309d365687a4b61d8a746696182df7126b5b8c5fb27cba016975d4648b006f2b9c2345ab61fa68c7ce7901cc09538fb6349a391403802a26316bf15ccaa90686142ccf5e709cd4b6380088a18c42826330a454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b39d1850f7acb36ed2a35e9af6f94a06c31afadaae3545a069f892ecd8929f76699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = b878da0ca229e1586aaa9e5f0a266d610839eb54c963f659ea670d747a2c7435019b1d3c938f730d41fb9ed03fc028d22cdc011a307c92a73adc45a1bac2439a4d53b936873c83b5bd882e3205e55a7a57f89fc1f4f89f38685d7eb80ada1d3036cd3d1529c49957c6b9f4620389b53f0715ce427c86971b42203849b1183e46b58d5944286e1d0f3196a82a07b4d5cb5362e1a474db1cb98bffc0a45cbd896db14bf7978400be5d1e10d21607478afd45a2bb2f73b598e979d1164341b2c7ef4fd869f40bb6bbf47ff6793f265740f3305a77d13589afb6b7d1d3899f37e04301c449db9f1edd102db8f10ab6dccc8982618a218ec2d9d9cefa071b48aa97cb46a398bc6d1ff9436e8e633c0d3edbf37076a1ae760bac41ed59589737704ad1b051e8d6fd61b963c4af3670b90bde431bee2fa17554ed30d3c01543d602668587dd7c743b1789b15fbd09d15c9ab329edec2d774d7b0ff42b0dd913b4318b3e3ba98101a9eee73b05003cd10ec8ac71b82fe1709a2a678276a235cec6ade3b88a287277f50311a8b8bfecc43bfb01acf64d0eb8cbdfed46009c12ed423292a35023277d7f0388f0efd4e95cd465d92e70cfd7478ad1e0c95d3594ae0e63a4da325d37cb409dfa120b810367d4a92b4fa0444150ab6bce154301bb0cd5528fc575d4b63be3eb35c2b8b4ed8b96d9ec53375f684e7a96829d04a5941562d7c44391d0d857f3265e383eae277c3b3c78fffd31b0de4703a3e31e620bb712bc7537343561fef00e18ec93733da1446cfa3bb297eab64c6554ce1009a46cdab4f01674f9810958d5ba58ba7641afbffef089d80462861bf59b73f43fd20eecab234a506d7a59baef6ecb40ae50ef7ab23db5b2b88d1253ccdfffafebc1bbcbc7e6dd3ac45ee2bb7de893d3b701aba45d80c20aa828b1ff9ce975bc1f25dca609ab2f1952a253c878bd031640763ed9eac99b539b2038d47f59c80d05a8921cbd7e33b373d030335294debbe616d7a3bbcba14c8d92a898b74d7737c284aa5e0354c5b5d6551da0efe99c00c7a7cb0ae56548b6fd36216efbe3b57523b023739e2eec +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 08e63b9ecd3311edb5e8157e488f34286cafadd3bbefcb59a7fa6e8b0ccee499bda8d4d35179c67ea35f280886f4cb4276a4a63d38f3151a4c077d735165ce3b9432bfdfa35c7fb59fa6d4e4d6a00d54ef648e666ed773e62b9aa159c80de4db271fb96819fa089fbec734ef1f3ac589db824b388c9659d3524987d4367a23df52dd837fc565fc692e5252e8c26248c5118963eae4b81a8cda8c43d54aa4ec67da34110c45fe28736bb9dc2a07c8d608e33c6ad98444d25cd8fe5c15e85b8da53ed5db31cea0a027cf711baaad56a844c7b1936cb73de5447d0764595c8e0c59d8422e31fe5e7fbcd84e14b87cd6c651aa0c975f0f654e4dcfeee7397a93893cd3a2e81568c544e4a11443b0a74532d6eecf5f5b3e9885325fbc5738a27cceeea7dd710bff866f7e36f99bb27c146c01deaeef099d7a3981265848161d9daa75e08e1b942aa6339ffdbe33a9a3969938b52eb3f4f96dd93e6123b3cc1663fa200ae0078c338b8c96ad9b83dd66e8f217e5cd4cc91403ff9999cd04b34bdbd9f173f5472fa68ca16f5722374c9bb7bd0656c0a8aa4d1674dc8828ca4e5df9ed49a8ca4ca6563550f43662e56ddb01af661d78dd46435fb3cfa99c8571bf1b8b26783f1ae95ed2b4b009a3b6e75cfab685667fe9cadbe3e43c33641f2a6ae7266d842fa1ea567230f876dd2753f93a6847cfbd3c0f520f13e47379b4cd3485619c6d4c4fae6f838bfd67bd49f43f388ea88d75b180b9378b9f4bfcd6e854ffd6ad4fcd39ebaaebdf70013fa3d8d7b9a2acdc700f97055ed61869bfd243a676bcf7a7e47521569a53a7e2121c3829f4de8f0755d5e6a8230736ee7bc3327a5df27af21cb79c2f2d63f46e7c54664059fb8053bca2e50a7eb5af510688eadb386c5a8a732e4d6f0114c2470e3dc4d79e908dec053b41135a7edeb464423eceabbacf3ec546f8e9fd556387bd15971ac4d8fec5d04247c06d4e87f23f4db588dec8cacecc6772177afbbeeeae54d38152849bc96fc48b73a0ca6c459a6fb34277d357239d0d47d95953908db86fbdf66d52ec4f24b4f0d1f59412974d9ca888c1a6c02fd9251f7b8fb16c6878bb20829260c588bc80195ff8db59ea449209c2476da061db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa6c02b3e531ac550a25db8783c995e2716b143c8a1309572fe47049a65742c632755a7d26e5a3344309e0c14ee313b0a8d214811b64d7351258e80ed9720863368dcc1851a358668dab3f0cc77f074aae24d71e0b71cab858b29e6a06190177f9dc39051b460d338363a9b7f6c691ab17865c4735bf42a72a655155b5106c165085b1c504d6b75187a44ed198c98aa26aa15327c5b35f6b3852a58fa7613337094129367e0660a62fc28e613c762d857f99f057b4e208e39181c63a8a91723352b8c4a4e04c0c02b78ac82e13c3542634484cfc8ce738b31a3062d2579f8394cd0947157443bc9774089689094a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba819b0aceb923918112e22b5591ba032b2a0d4f8301f2567b266473f3f1101a7c9ab95c94dce238db18166cb0c8f558167df937377a2096eb99408a32e3759a88a4cf04cb57923a1b9ae7140281a3cfd6763bd92e0fb91a24e87f1c56471eb334526053db394d39f956a8e45c6ff39cd57303c0ac920af3a480329dc19c43df67c05d889fb778a0208298938ac423534b025a04b141b1eb7017c9d053b7463ee870bb17899abb19c99193b670a23672b0ce15f97f71092cc121a0fc75a4ad292ff4a4c9c78bc24c764d7d4b9e1230bb46e02ee7a66357f25716c386b91193fc5a85cf63a748072478f23b0fd432944a5cc25a7dac2297b1234744a918e7565636c674e4aa4d2c957c7aa55da692324935a4c3749a08956028675ef5b9ba3ee5111dd73f1dac282523cb4a89bfb7973a50d30085e70818ea596c7c4ae332adffc300a5d691836690228b2fc6600c5a3a363e357c66a53a0fec851cd94b29b066305365b6a78fcbe57dbb40c8d02ccb5f541d11d24ce8eba582104bb4da4b9e099e822933b6b74080f8b743b59d94f094cde7c45422317e358adc6877613b7ec0a6ce8b702a1a32b285f475af3769d8a1148b5324c6429ceacc5980b902ef043f00d42484a10ad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165edc8db1ca35744a75ca14516abe07472d0d1b723f70ca8cf0e5c9341fd2e8c26da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 63cf7c70a32a271417982c440aa26959410a79a7e7644ee15cd5af5edc1ecfaa6eb8c539391a486b9a7c64f8edc3f93c4f565c91e2d72c1445c6ca66498993ede26c303e61234552fc5eb14db62cb4cd5e0f66cd72ce07c89006e846d3cfbac98a52c4c4edc769a81864a63ba93f3a6dcc75f21bf4f14527e2e527fcf9649c75bda5edc21e4d13e8c254393c9095e6b80bc09eabc6e088f842ef5a8db89fcb885efcf2033555bbfba69b0713719aabb1fdabc0ca3e368b37a6aca44a4c08565797787f1d7d42aa4d66049514e8a9caae3d6113fab46e033c02665a0a80523b72d59aee48e6b8fc6ebe4d15c3d702817797c1f27c557dbc90f817d59ec2bc1d9680481b8954b5d4703dfcd8c3970b26bbe25d111c678bb5e9210a48741eb7189deb094fbf3f7fbe81c0d9e2e8df169d6221beea1c9db502fac210b7555dbe981def1f393ee57520b75eb25b73ac3cf8577255be45b2e3e065bf4c2adec044d5bd264d82bf3b3630b6130562c7bf0a569058278fbe74ec000d0d45ffcef441cd18357d91e1ad38a7838496dff864d4f8d89abfff9fe654c1f7876c6479f32bd6e6f6abf88e0d9d696933a1c5224689b7db0aa4e300be8a1c8f9b004aefcb3cee44a163404ffa3a3532b007b6b1d135df6cdd80b055b56c1faeac0441731049eb37f2774bd3a4b9d8796759a54fe9f29a956eaa16ea90d78c330c63a4f266b0a1ef06aabcb6d378be79c050eaa83f23fb2afd2ba24c82a331726694ac5fcc24de2b67260664fdf889f930fd4f2a7170f7da1ef4048c108e2ee2853535eee70616d16386ac516f083d585a01568c921a0c830fb01d524815669ba6f268e1f760683daf0a909339b512d8e6a9aa1082f35678c243a3e503154d574182e6df68304e80ece25d3f6cbd01d84fbc6abc62fe7e536ee645c5fe13231921e80c72056c748d2e34774d9b129c1146aee3bdc75295887244f016f501b37239c27ba2a5507c91e0819ae15260589848b7bf5ccdd258ae0d9ac2e36952238925bac564610e4a5a6f35ff57502c7afdc6a790ba151ba41ea0f6c2dfd60f09230af146174c3d9031 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0fbb5b8185f024eaa896a5da462bb5a52f377e6dc59a8baf52a5f52ddc8a021e5c9a0fd0592eb7468773e8b844803af84bcf5bf724dee56d373e05d34f4d991b9764a7d9f12c57bd3e7ebd6567407819edcd36a157cbd0775aa8676768eb98dae19471073dfe858d96ebd458cefc4851be5b0c2972b856ea59f8937e5b786645f98896a393deef61a678fe35f53f5798e1bc7058b79397b5c191cda0b178558e55c05c988e497578ab556702ca7ccf04b9e4736f33ddd2e21993b3fbca78feca561ae437c5ff43085a552afcb6abcb7edd7c341d853f374f2566e563b680076e7e56efbfaed4b0fe04ac96955102fe933e9684e1183c8ee6cc866a6b9956e26f9af5732ec1882f621cbe51d6ddafd98cceadfed50d2bb3e1f38796fad2f2fd664279fe8a8fb2196aae6989db6d895fa3fbf246dd9e16238618e84a01a55dd3e535cc1e3118ddb730feddc29a344b1a621a0d883b3bcd8e4d7b9ecf4b8f468666cedee86c5fb3ca9c6c1fe7a05ce29ead5056f6997785a59a4bae31af6f0159a6d98bc3aa4494a4eebcb84432c2abaf22d43e22d45fc147cadd4afcf14437ac35709c5636eba3fabfc88f134ffb50f8553eefc2d69a5622a88ba8dd8b1c3cb7ee546c554f6d70f4d0d818dd13aed4298cfe7a06a41ba345b1a730298e7fb5a498ae8ecc4a545b32cb70d08f64819334ddd9ad38ee4a9a187828645ee0d567dcc6853c48c5af4a836f355d379e49a5e3f663c5b7d074774cce720854c66235e74028a565f4fbb395cc1c8c3e81af3fc674f81c8a9b144a39d7fbf3b33eea3dfdeb185f65c639610877e845f4af8e37bffd5a97cad4c11eced048e467ec3e42763d3f1ffad5dd895ec558df41dacf725965d4c3ca0d1d4ace2f8c101da635ae8a0d166c8b69b4fff6d4c7a4dd3bad6234f5d0c8a6fe39935977ded81726bec208be7f6b9ca51caaaa7465f03cb8de547d46c762797b7d59bd56b78cbf13286a4479c5e5d7d286ca6d05b892665435da13ab997b30d6fdf23bae4cd205db108db64dbd72cdbbe9118681376b968df5b9c3bfd169759572c6cb36c88036e8c90878cd4e2008000d3e22d76ae0046db986b85ad166052648993355c2262dc8e3477e83bc9a843476da24444b3936db182c608bd044a76ff88cb3c2b4b4f44f35932d0bb3cd8b834ad6e23eb9d9825d4378cc40a94d007fc5d97392eacb9dc770bc2569ee1b92cbf0aa2abcbe1e8a1e10ab1244e14dee474ef3e4531e330eadf71db2a36b32e152a88b5d90b8212b45b69c483cf261ad54564a76fb0b2b0c2589037a294772ef8c0b00666c2cd18cf54bb3b9b910094a69fab10df29620a890bb07e16cd8b55cbb40c074e0aa256253f7159c07aab0a26a9104b73b2942143e9622e07c055f687a5e1c2bc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db19c2fb151ae1d4082103046032603d8716726539dce01c940a78423b37661128f88e74ce04411ae307048c82de6a2af26996b28f91e32c21722554e2c51c422bb2ff5e3a35a0468b3aa02dca384b0ca793d1b524b7c24acaa889175a171b2522a07969249596ada9e76d17395c49648740fc0127beeec0bcad5c98852c3314111d149a0221168af2ccc65c6961ce3690d64ce1554a137b373319c56dcb5152a19059e0128ca872ca6f100d4509f196c7ad4fc65ee6accac6b80a9e8315c7619870b3623d38d2778c788c62d291a32b1ea078bc5a4e5e2bcd34c97e5a6301574c7854a8fefd62ab6657e4eb9371e09b8df2b1a45370ed45214cee3b86a1417c234081047b5c84009bb10351932c3a3078b7cea137ad22b665cac0bc0c6a032778ac437f139970c377b4d651b0e284d48040402685dc3ab6d5d206aab39c361789818ca7b3e4c8cfe2c4719e054a85b383eab160139c377896fe0217d46b98f3d0ac2a44cbddd003344974f30f3b9733579c506659272c1755c9346cb31153cbe133328283637ba5b4d3a906a3ad75d519786c54143101b77b7053977cbca1175a0ac076dfa3c0595b0473495738da76ba0d4a2333452d88c82750c94e745852a1118bf7a03b6f1b448298e8a2b246b166e18760dd5c468a4187b80fab8ccd078837b8223769b2489420f456140e2b911290eb4e780dde03e1a699b38b95edbb1cd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75b1eef6e8c88ff8da9cc4a9b01d4c08b6b585beb5bb9e084c6c47a717b51feea356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = fc4177ca4d90f14447dc8a12e6f8e99e5a76ca88a72108397e804739ad896343801e46355836c2929f3a27cedaed8ce0c4f3b4def76c5812b9336bff95564389438b2ec957d2e9dd55edc9fbd24bbef43dea449123f62e1426397b83cfdb15160eea28bf52311c04961f36f96a3ac142163147d162f9725269193ed174bc771eadaf471347c8e9e7ca5810cde01c83650041af602853c079965bc7bdb674501a00bce0a81ca1cd05726e5f1fe0f0d066e15d9753ece5676d764a1b3e8266d6aa97785b7938f459506c8d71d067152f4fd79d8db6da8322e2aae4a06dcce8569e39bd955325fe780143dac613fd6147b062a8bd567d93a3d73e4f4949699a114484e758e4a29371587a08c0b188db4c9d661fe1afaa5b05260d42e9229f9f973fd96fb8407cf3a77b7e96ff29952a16673c5ff7d5721a52cdd0881ff6ae5c335cfba27362387da9c350450f63154c7676a8fd68759a3fdc4e73a4062792cce00d631c2bbd81f93e25fbbcd5d3282d54df1cc0dbb8fffa2d4727fd8ff612cb711536403c5ca9d20f2d69715248e5ed3d1bfabf721d52517118735f6bafe8bf17bec04a7da805d10e81b3564c871ec16b14975f44a27921d2b7cc41aca148fa9ada39d7bff1b369b3851930b41ec81160866dbbb6863ccd4873c9d23ec01348ba88c56088f072aa39b9aec760dc1d49acd14c4837cfe6daabe6fef2f64aa6f1915e5eff15a3e31637cb840aaf949d3d996faa4d789fd1f141001d450d22acba46de7a0a62ba2fd25353707126a2fea4fd55b310e63d94b8fa801deaf178adc5c749c52b39df05ec38efbe4b9b9c75e411d4118b87d74d3355546698052420101ff6c0492fc425d621b899f83fab4dc5307de45196e6d297976fd5ec9d2627981d90c77afa7537cba9abcadb9824d28c5c3e8507d4950764015966b7168c888237ac323ab9bacaace0aa324be9bb41f8b17433b6697eab07bf42d1ef045d8310bd8727f2979c26fde7ba93273df44df31432d5458a434d40e80830f9e5acbb6b898b7e5842a38c56754632fdaa7e5cf00f7bfb5149a17702ead4aee8da72abbf423b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f5de4a47f661de38531169cb1b05ca73a3527e59919767dadecc4d6d6bb1f9dad28458da21d5726a5e7f222c9208badd022adf8e0fdc3978fcadbd472d776ce98442feb4a0b5148e63ff6bccdde8e0556913ffa847fa8fd3bac8eeab94fa66e9eadef74423aa34056676658af75d5446dd347b8554e0beb61fe59cb3c696368aecfaa87d47639d311476ac4b859cffae8fa86eb14fac5bb97c6e2a5c9c9bd854f73b33cb6f400f9dad0877e7a9d9c4c5a4d4b77b2b0c8bb20540b724948165f1d2737e719e62d01b7bf334d68453b170ee87631aac701551f3aecc89deb31e0cd1ca79ce7a97d3fd0985700afa77399b49a59d97c8ccdab74e99ee995baec31feca0a46a7b6d855e53f4e9a814cd0a9682e14c74b80b995907b4735858ea897ee09c9f1f868cc4d9c96e43e480f3f3b637f52774d39cd354c59679f6d8a56acc5179e9529e58ec886d3216a74f31e9ace46e6ed4567662d7be4b18c0e82b949109793c0cef722ba85c6fed4e68a01816ba5b44bfb4e853cb5b70aebf74838de39fe539693d3720f72f7e3fe7e805ab0bfa5f9116a01bfe448728e55f277f2143a112babdbd3eee0cd47ec8de69708cfc4166d97a9bd2c48a6029dc619ef98a669b555e1741ee6c659fd57856f9f14187b51b0361f6bcc1c0f99ede6b5d0c394b1b23641d5c611b588e3a1d3ed9d5d844bd630035b86815f4949dd053eba364d95900eba7b0b7d88f36f9b859c58b7534fd6483911caafdec3126ccdd10b5f6bd5abe2737c2963638372fa2739c8450ac75b029847b23c85bde62460857687fb98f356b35ad8012d36c858fc11db931b22a914ddacba00f877ffddf580df3f6d9543dd3d45b3d4e9305b8499baa9346b42f3889564d56698a784e4f575d0e634175a65aef6fb085b83c167fdd3dba631eedb428beaf78710f7a659cb5320f25b1fa58618aa9eb049b709006536747df3124aa7df8dd666b9c6b399013965c2c9b60a99e97cc97d6e74fdc220cc148c6d878746392f6b64c6a690a2d746076e7e797a9bcd5588e7dfcaaff3c5e0e7aa56dadd3a95f11e89c8ea3408527c9cf2fc3478771e2f15c94962e6200501bb90320cb6a0eabc78fa97f2d69c5a7a00b81db6b2a77a2b99cb1b0598af4bc5da77623fb5a2d3d1709afe65521c5324df95e40d6c20189a4cf80162737801c48c1d4b253a7741dae446162d6a2457574969105e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9c615b63311756d79efa6957766a5de25b89af140a096ca145988e6582bdf1b590c8689a366b9b4e2877c2b5c5a33320d3d532e3958465c9586f604f4f800952eb5f96d73b6287bcead21f7b8863088728ff160d1ab7b3ca594ecee60a8b741903e4892f6154d6356bc308bacb17067772580af8a1cf5157ccdb86aa642b7da9a6a583508d18773b307b2b0ca3a1cc89ff531e0df13948c288fa4aa6d3001c592879649c72450202e39c5f837051db1314be4a25a13a6a00537c20ab5acdc6be15562b1027056bbcb63d6c8227683480b6bdb83c5a74f31b0d1ab84d129d4a883e2cf48ac96ac9aee856a331a5b8a0504a461daef078d3d916f962a9f9a82fe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a3701982fcccc93353b0387df0671abd2140dc9555b8d98251924fb77570aad8737b12533ea4bee7326761e86986273bbbd447e47119b3eca4b7f565de6c0ef8494048a08967cc17ca4231c433864cc961f6193774494aac460f23d978f4267aad92b66678b560dc50c5e797bfd407b5b89b83aa1023a3046d098d939b3974c6626fdb5d4df84b7a3a6d63727ae028560fd79995e6c310cc8b6f33a3f441aba1ba3f44714975b3c3c299aeea9a714058ac74f1334e8c011a748485289af49542df7c2ab7830a3f519c41612f3066b24d594322913e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcc9924dfbb3b052622a15bcf0dc7911d148028c8a8cb574334010e222abf06fba5ce5022da143e5985c7cf277e5db727f6b07f2d8034e033a25b0b1aa9d180f4d403b7072f87c694a5962be49938783613fce30e8bfc204800bcb45c5faba48968c95199297626eac6f4c1099c903a24ab54251c353016418ca774c52294a001c2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43af581c2fec9055830b38cb68fb506aa927443b1afd1b2b6faa6f92a325985c6ce8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = ddfc5b0084ba9e5ca50279df6bc37a9c2390c2762ecbf49be1e050f52bf52c56b6b1aed384ed56bcd8a340f880568a8b16f19e61e355e084bdb5f88631afd27264f1782e05a77c39a2e6e761ca50d093c6666fed23607a62293f3d4b73272c9c7c6ca1457572d8643dadcd420c62d94212aad6db3d5742bacf266569ac74783febf0de88106490251b53aae3a809eae2cfda87bccbbcb99d15c4d4b59f91e926818fef5827241c97b5b70820c701507ff9b7409ce1057f0f78eaa743807a1003fcf20847b63ef101754fcd280ded48ee34da0affb3b8d53d5754875cb10fe38cfae39761348d9bf94b8b6031dde2f04955b27cebc5c934f3377964f64114b92157849be5ae0d88c9fc5130950738e802918caadedd661e807a12b4961f9b58ff7992856aff40af139fe660455f4e7781bfd51cc0391b4b865191cc946cd5f9db076bedee9b04ed9258616847f3b3ffb64dac4c786fa0d069f600ce60d2b0efd796a09bca4e2e0b7d4599adec6771e31113b534e36ceb20c351525ba0d2296e0eedec74e3c6d622a3b823c6e5f39710997ed4cdb3097421d6033ac3907485032d84624bc89cab9507bf824b9396137962018bce76e1741e45a27cb842fd74020198ae5733d1362b43d6fef638422cac4d825f897037eb796426c63d17fc29d2c0dc3666c51c98d4a9c54799f06dfdbd437e389c0022001525d4b2e237da73b95ce62fd9dd06856ad96fd04229ae243b4cbc10cbdccc9d620b51ddd022cb0135dad1d671541ed0c74aee1280a97cba74ce3079e9364bcc9ac1b459e141d5b1f5945943a2f8df962221d263fd985f3e25b01d8f9e93d32cbbb0216dd0a1dc44dbfaac43b1c49b3a942f1e68b73dc4f92ed6a3e3802183d2c386519830876728cf959cc1c7a058cfc7df27f3567f664488b84734ce660461565ba5c4fd0b5e7cb111f0ec33ea8c99626e7821b4991fa9a48d2c0223c740131600e288908059dcce70ed14f1970328e09bb32f2eb16fe729c4e850063a5b987702097d8be6d4e91193700caff28bc6e3c73ba6e8a5e5779f8e82067456b2b3c1ccaa2521f9535ce401 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7b174b543d7018768556dbd4e77febcd7558aa9c7c9e09d32b66ec321a4d1be7b45a8f6a875e3bb12873fcbb616323cb1cc83ba8b6bd6de7432fbcc73d8ce2b4a76ac5acd0bdc431c17e993ce3fd63c66636337fa8f88697b63acf4a92c6eab4aed5d3cb45fb0f4dc2f1afddc959d9bdc7b4b26a3826cc8bd03a49481c684fd65349af91379982a0f73e78b59ffc86a1e2b3a79f5ad38205ab0c5b705f5f3b02fdf2f8a54e2ebdb35334eb5eaa4e8299ca1b47fb3fdedbb128363cff91cf99bc130d8bdffcf4dc8eed71f56bd2cc55fdccf2314f931fcc51d6e7f70d6943d30cfae44433b0bd963bc56bdbd9be6d3aff2848df2ce4f0ab844ef33cee95ddde3cf8c88995ad8d234ad14bfcf469d1369835e31b35595c9ea9b8338c1f5bc21795243f8d3be672ec16f5280bbfa118e4a5ac70809eedf3c79ab6966e5bbb8a93b6abaf389bd9a859565cec223334da1c9cd264cae9b439912d9af29c5d5a943de84461c1eb34ddf5433987dc39ceb21b5abf691c3540884845d736a67f8eb42f6a3135f0d9b5ea026a7952457e103f5bdbb8fa7faabb1d977906b8cb8f9eb0034ab07b656944e4e6a5e9a77acd563f18fe604cc674ee478fd5c0ee5f8373bc5d5939408226d415ce6fdaf8742b9eac935c322d0668490ba1099976c09d8214674b6e7d83da2433abb63a544d3e360d9d8c79ccb88c6704d5a3085bb2fd8c57094cd83aa556375edffc1b6b636bfa8b65a3ad83550fa83a7c1f97ca8be940758515fbe15d7cc96e34415996a875d9bdbc1ee7e01d7d8f4375e14a835ffb89aed34da8d33dc2ad8e801d3c520c48ec3b651ad79198c3543317d1c04c5878365abad936f8163c7f094a63c43fb793ad9885df0ea9ac19ddbc503b9ff1a8d86e17dc77dfd28837e6920c31deab30dcbec43aad3931a6b855ba96cef757460776e8f4fb4f86848c0e9e83667fdb97692b1578662a8d27b894445d864d0e6276bde062e6924b6bfa4d4454c38b6ebe57ecc55981b6085e7f65b3bc6bacb52caa69f3b8e47b6ab004e4d9de38e5c73c8a5dda9ef7bfa5878155dc6e83b57ad884ef525750707a4731f46a6d2c59e27c013d7834f126719c302c7af3609bd0457173850bac49581557700cc0dcf034aff6b36c2a53a5e8580db101e0f718898cc8cf216fbbe1bc78c8984130c2ea921d872224572ac3dfd0ad0ca32a1075c9c2a97c41635ac9dc7aa2d014dc460115c93fc427c155726830b9cadcd8523c8722c3e4639d83c5898054fc68ca8588c55d89640e5cba32fc3f5cb283f2f9032f2c8dcf3847ee1b67ca698292a99348d194df068db0d46d992aa59a83c08b24017ca1048f77532f22039f92bea7139f1dbba914b10dd27abcd6912a8fdab2ac5c68646ab880554b5512459efac549950270e825e39670f06288a97a5e36a31e61a5257a0534e06c1418593b7e844f6381bf1ff5916be88c697c6a6c1c0b42ca1daba6300106784f125e7fc80a37f08a6889771461ad90938894a54914e2cf759c60b3dca1b86abecad16efed660e4422cae131f827b14b2bc4a7552073ab069365bcec3d3a41b22323fa827ad50793b3186c6a0a7e3b007c892868f18bd62105e220517c0db3057f77a3be29f8e2276a49416737c9990216c2eea6fffa7b4bdc6603aa400cb5675aa5a78458a498056511ad42b8550aecdc4940ab1c1739c33fd07bafbb287ae595fcaca6ea4bc3fa708ad3ff8abb4126d6aa9a4d9572b74cc5567b55412e901ca0c4d5eeb4c9683131522917f0a7eaf56b20d1177b448878b657700ad885cc0134a249970e1ce1ca779196215d104117c3c884c9196f33627d6712a3fc234fe171db342a24577a55c5c68e3a2350e41c14c701b1b01a39d2850b69274b2ca3a20ea2cb444294ea73042939a5a1a9a905856876b0b0e3492b6a328b40a949f1865f54558aa6263789093dea2ae2e8631e2ca5cd2662583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89d51669947f1ab44f9aba94bb239264a0c6ccaa64c0e2b3fe6212924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c4471a36aecaf3868b4b8f034a756020864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d80f31bd314cfc85416b2b2a1973714ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28f12f3ecad62bd327f1c44ae86c0be6e7f15112b7f6f6d5ec7b13f4dfab718965812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = 086277a8a542fd9b516d003d08eb96ad496fcbbc9e55b05eae42c95787402727d46c5e9f916bf992687844a4dc5d82e71401a36822009b0601a9fd396891a6c15c89c638afba7594b8e2ca0b8f26775ade14a1037d868ddc2fd71107932a112772e4c6a83913ccaeafdc4fd809bec26bf3e6e7d7a69be522d9f4e8a265417e36ccb5afcf25387f35fdbcd6170c4d31fa070122e7cdd8dd90fbeb9219db9742191f3bf4c68c95a20bb1d33e2efd99eb2873e98b9fbc6369b9c12ee49c39ea1408bbbba3bc498830a5bae84c72cd18034c27d99e1fd40a5a514b0423355d474b2cd0b7e97a7dfed1ec618524eb2836ed0883f4ed5d2e3a202d1cd2e5a27c6e59d4fa1c79bbfb2c0c4c74c9d515a4960eb468a6ed5519e1ae993ddc86aef51bb20639d063aa99e9e7265996ccfaa700b46c6871f1d40367efe07cf5383b97f14a1e408bbcf7f77aa19d1a5b004956ca61d29bd8d30a1419d2d831fe039ac0d750843c1348c7ce4d222dc4be92d6ff20ccb7cbe28d225575b9b7c1e26127fa6d367225b7a491f34313f73b76300ae25a4b3abf7ea7bcf692bb488daef093a1c91e4159ce21559495cc2bb730e1a9efbfdf7f26c1d2bc55c5d89dcf74e0310f2de14a1499282f9b32f373fb1214074685bbe5a256a083e8c06b221a0d16a9e31b38ae7733ad9644e70fafb18391486e1cb7cf9810fcfa276045863cc5e45bb2e9ea49dd7659fe26be983f6b984dd9c0163a2efcff698fbaa172a180452b21aca550e93a20e049de89a284ecc30eb45068652717f143bf61b5e7a10c35001431470d0966445cd9c118135b29a7aa442809e40ad21d7e52b040a0086e6c99cc65f18cac115fe47834d45521ca6e54f0cab4200ea72319f9c916ba9fd39ef1c404c34c2ae14b2c7f407e099ae8056f4faba6d0b95250cdcc8d7d55d417a8b666fe2b7190c7b192dce117866e8b5c75a07d387455cd195e8963032afab2672d818332c81910eff521a0e1a4415ef86241b14273566afaa97b3e877e0c47589e831bf4783c78b07062b4d523702666fd8f2f7ff509560f1d43cc5fc63b9753e3059878e16d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 96b5d00594df5a6ade8c1d83a57c8403afcfe227ceeb8db5daee75af3e31eb8bafd39ea63f1ed47fb889d2043a0f8e4dd55594f4274bfd73bf1828bdef5a97c067d91e58df3d6a3723467b989b635a7a70617647ec2d60e6158a9dac8b40263062d3975bf88b25ae902ad9c72bfc7d6b69adf44dcd27aee19bdc67d8f5b28fa8894418ab9a0a97d9e9bd40c5741bedbe90735c1c3ce40c8461005e7eac55bb16e65e9323f105c465760d6130c67b510d30ff1ebe78e4a4bee364be3ed41a68a676b398c1237a6864b494c383adb4a1bf369e606894be79e7d06e4935ee45fa6eb3388ac3de939a309373e47a7134b57cdd69e5ae98c842b936a176d1884f7fe87e606be8421feee4130df1e82fa3f51b684749ec6d77a100fd48435ef09efc7784a6f36acbb8a019e0830e54c789e6b9bd978af3e93b1aab566afbd989dcbec3f93e59e0d273e672036e60c6806aa676b8866d3284c4b3c4e1e8dfb4a6a75d5067552aeeb4edfb5365b999711763800bba82f66e8f77e2ca75fcff0e90b46c377d7bb26fcb7f3226dcd13ec862cc9a0233578b2bb372dbf31e0536d3c88f46aba8bfdea4cb6338efd847d2f5c9605359fc2a830476a027d477324a8b15586c30cfa942b4ce350d88e7e8808c9c97e2c9ed9e25417404755cd7ecaec7c5d82c35b43df008d4f21cabc0c93d84f4b98b0a5ed19be55b4a874b62ffda75caf5ab9baf806b52c63ee6dade7d596f89cbe4dd7bd4fdcb77fe7648fc420336d88b9c3ed690458793c71f6a8d2d822a8be592af7a0de3c0ceba443ee754829a471304cc996de3eeb453d7c5f2b365c32d33baa2d3623078e9e6abac04bdd74b73f953155a236de31af6bf6ff9e0d6a75fae56bc75485d247c5278fc50d5465aa685d0584bc6fdef5eb3c4d1eee5365d7c6d6bcc500c99c343476bc99cc434ce73d6e74ea054adbedc8daa57a6b8a77ce6fed5e769d5802da7a02cb894ec8d734f4b16d892601e8375dbbb847393712a4d9c64c5f997636aec817fe593b1754bc9ffac7afa5a6d0af6815e353664ee6ccca60bd7a397b49dd34a8f352882612cc39683cf8f31aa78a9043268c7e25b0c43469ed0a535bb9a8d4ecc65c3cbb32bf2361838a8358b2edc1a1ea2fb66cae5070a30080a84a9ff81b3b020ab1df4548e510f03b13cecd4aa32f380172ca85cc8962acb7a51619632b53bf828a7ccec1b65c72fa0f814cd2c101690b769e452e34993b0a33978c19da61b0061f24661f20ea6a566b1d7aeacda859e52cbf32aacbd1b7e1e66b138d2cc613a26996b6ec8d89c63a34a44abcb70772083140fd6519eef107f91983f2e4557a7e21c62179674031b9e7c2edd845188c12b4745b7a68308e1e19a86968a4ca001268132e493a79595989e7b55a9f2ba83ac40c89cc752a97d6d6b6982e1033298445384c5fd04ccc06692cee0007a8481316bc02a724491e469ed7a2f1b809715da8cd130a2cf4c200b168ff33181430cbb5af152c0510e46b9aa8d83060648c2ecfb74840c5110004c25d9164e1a3dd9e181216901b1169a9ae3a760d1ab96c7bfe405c657a2cc1e62c65d99aef490892e96bd6ac08d9421975af70b16d3a12f898528130f30ba4b9b513bf42b2f5be08264a985b2ca61998a2a30030e3bd51200ccb3d0f66d08a677f6236bb951150e29531ec278f3d013bfd0afa81c009d0c78537c62557b7c5c930614e14d9600a9e8ac38f44761460666d4701782390552693b83736e3e340d5671ce0c5128cc991a984630f1f3349fd80e7756abed753226b456c2968efde96de0a924b926ab75bccec5e69b24a42aa34c110d75ab27495c5d4cab88b1afd49a2fe5c02acf3578fa4664934a1049fa7d89f666e2dc77165498ef61c575b4156ff7c2d7aba435870999d62ae36a6cebc66d04ac54bf4cae14c0ae89aabe90f3c397ebcfe69aae0618475e5512d5534f85f711a20a9699c620181acd1162b06e990096f7799f836771a05e56c99d3402599e713fd0b44be0db130ac3079c583bc0ca266a548da0895c1a3c3d1c28385537465df75b055106a215309309820813b3b8f7895d53611061bf796b47ce1019e3aa09a013764ea8ae0573ca62818acd346fe3012319db7d351c073d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132604cae8b58e0434fb1475312355a8b40145043bed4b269aaddd654d2e562324bc78e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 8e88de0e5b03a5b2356db29ecc828f4ab4dbad32607b6ff0d052eb16aad666d0e1865bc841b8159af2ee85a5bef94f89548f5a3fadd8f7b6c84fa4597f7b2f01ca125beb86d6cd34fa5cb141127831ad2c98e08431102cd332fe1fd9843ebda0fccdd5c116d3367b08229fcd397e7ff2bf7fe4013975c306415b77656a733088648e93ce6813c314b7d001824ae7a5be1c3bfa58453a5f9d9e13782b36db6e3d2489b1349feea7d960f53cd8248d22ab4827bd7fc5d9ebc972939148ef7d94fdab15d89c1fb6a0e6d5f706377dc1538ac6a45566893b5f9aef83f1d24f6fc0ef170b2e33fc712f02ddb6c39e9c4bb0f4543a14b3fa5436b6a6027b6287c3e0e6bf5cea841649eb652297da5772937cfc2f98c8d3b053318cf9218f4ca4c7cdcdddf35d6673a7daabea5a087ad0c78322f86e140f030a0d6b7c745dc632ac5c158074db2da6b4015af685ccf27d8ef7da7e9404f2a885e39ace3ec7f23d8fb02104d8ba46804756dd69520d65b0e9bb0fc1241774e36f76434179047533d5f57eacd067ee85b20263df354006a01ae38e0498b9565614a35fcbadf2f29775c4e6db4f9eb329e9e7e04457ab78af06fb8a60d5914525ec051338cc877b445605a0d8e28d19b16512cc06509253071d6b2d74e328c20e2eafd17e9b8724f51b105f433ebb269a7d94f2750e9cdecd4122bcabbb9636b4a5fd9326f2fb3cea6bbaf0f78deb4f2b33f32278ad75a9c77d84b97865e09595d1acaec269c3a2bbfaefe9dc220083344fb65090e982e49307d525b796f30d27dd3a7a04388167489c9d26bab2589a27f3627b5f97a7e96f56748c75aa60bdaadcd1de91c0db8e7ee5b754c22ad491b7a3c218858506f8e959def527cac09b9208741aef20f1f8ef2dfaa7ca9e7c43c27a526872395a808449ee447cc7c71bd0fa941f86063ac84e6549eeaf90b0cd60b6bc1d932356442a26c07431b490cf53a95d309ffaccd68e3d47e6b9bc2f4be8313adf1ccf2b8fe6fb5eca852de15bfa513c3407ea996f887ec9b744e5e9a0a6a140f6cc7a82141b40a10d094a45268c8ac52af072170f7e2e5c03 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f8d65394e770f5185b92393b4f673a031ad740d3ab2ecbf63f7561f1ec5b9126d832bbc444834f67ac57af33abbce75f31a8bea234af52665997137caad53ea177f1e36e72d05930896c9b6034680bfb74af68969c8c51dd983a788d40fc7c8a14ea792db54d380cba826cb772a654a496ccd3e983642997eb9f53c15c958bce62a6ab5a80956ce4e3be95fc9c06a98cacff35c35475fb58ac9e3641c208a0bb58ef6d8ffc0d5b983d9bef792b71cda7a69db9c0c00ab4c1fd375eaf980794e7a628d6608d841928d961aa5144d66083bfaaefff6b8b55b14bc395a92ec2e888d5b0cd7be09e874eabaccfed448cebf08f139a0f4c4b257ebeae559778acef89a988263b8aae549bc24fe8eb64a5b0ea62a3abd927667f303af77c769cc1ef88248e7e32793350a83f9b9bfa3ad8e53ce6843d65a7fcc75493e4e4f7c98ce4c583cb66cbf80ecceee96772dfc5f953f3ae2365be9ab783365b2d5c97a318cd7a4788abd4bafe3ea3f19363d4e5bbfc996c2dc7b82fb98ba28d70d5cde4ee1854c22f50b4de81582ef838a58e005b3c9ac59fc8a65bd2ff81ff7d53d3664585b69015f74b16187a5d19cd26d5d3d1bfbc3af3f799d97440bb3b60d4df0f7c4506c56ff965e3ef9bfb7df33a4d4ae388cc5feb44aa208aad6cc97285abe5e10541ae29c2234a904f6c6a8cd449c5b86897ec5978b4cd85fe89d64ad72c7ba847ad884ebe4826743922ee3ea6fed5737cff84d5ddde9738a4e9588e2fb2960be4d57c4347868c7e4394b5f76af3ce8a90dc7491d6a5d61da75a198848737b7ef45970387a29c5ec45b5623e9b4eb2a3414a2cf85bc866729a98fdcd8e3de3e567d63e7c57437f5a90f9ec35fcd7405085882588ecc6d5a2ad66d8a3dd63c8cc369e6a7c0f7c7eb27ac433883a5946acdba84fc32872cf689fcfc5dba6e894185c973c196ddcba52252948c8ee59115af3a34fb2f6dd996edb7f2cb93408b9cbe78f98f8455af74ff7530fc6b3ee370c5c9d1f74d3c1a7832343ac2f5f4709268f06eacd763f50497df5b79eb9235bb2cbe833e0c6d86c9959f716b9a8e3dcb94db06693535cba8a70d2410f72cf1b69ca2951579da03b23e997146bb3519c521ff325f9f1a1c1d506cf42079f694f0340abda4806719b8df468a53a92b5bb2629ad0b54799103c0c17936565e30d9272f44a657f190cb92887d4612a517a35e87b24fd314dbe32d99c7758e5458038140f1ca660eb8c1e813822f52865f6671cad74ff478514f87afbc4187c0c12a4f388a63613d592c1dce237d13a01ee6db54013590dd91078b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5b9d044a3950377c2ce8a010c9f59ab7e27aadc49baf10521d7b11d3ed707ca2b377912c131484c5e94cacaf88595c711599c081808681c6609227648033011fed686c9a2121e724346426108a5c514306717224f5928063549b268d87ddd91a79ccbc42f884f39d097e6246266173a79c68896235619928faa907d93226db05157319456dd06564f364e8ab68aa1fca43bc419425160a6960ffef152ffb85f24358d2bf3c375888fe8f7245225a27bd710efba2ff73901c1f080f6064c44ec982716b0fc7a88aa41532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe930915d7751fc7b1094d4757fb0baf1aba40d0d443f60cae0d5b19bc4c705567a602402d18c546ad9b8cac337ccf4a0c1a23467e75ca55090ab4435446b9737902a73c69cc86d050a8c11fa928257c5774d3f74547016995633f7c564dd4c962f9865fe78347d8d0a5eb449f6a046bfd6028fb1185ffc86e722239cd3bb19fcc117c34658f00b10914989cc24545e615fa824742a1814d7642ddd21e2a89194d13270835799e23ce97f25ca7bb82bf096358916d73c73259853c37d814425b37e9c67f5630b408785290934a70448132c653afec782a478920a085c46823b960ad795674b937053543b80b98c52fa29961380a8360034674852d151a8c1393fd0c97a0b94695b8adc652ad1d3c69764387e75b1038921fd53171fd43657fba4c919411161004b4db2e079541af110e166ccdf2b77a8709028b18a96e015f13fa6142c63e71f73236d227e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2cb899475c1802b1dd76a9783d93b4225dc558eea558ddc598cdc45a898b7bbfb38aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = f9381d44768a327c751ad39b14ac7ac1d1f215a959bb34d8e1f008911d7c66ca6e9a8657c6443eb4141a46a52ecbf354812128354b697394d97eb5a7477485a676a0fd500ae629b3817ed80920f3cd1a8c4de779d29c2c814136c4cba979d95f2368e015b2480b55de69e5e3d4e58583809cfaa228c7f0a07fb3ecd9c3380cc3adecdec3f7d502f20baae95a4d3a5e13b2719cacf76b2fa992489164e4f9abfd3ad91c795efe5783a336e988995b12f05f8c9a8f199fdbb7790a80eef844114b8f4eb4c2788e25750cb103baf4e02a4d75d1e28e9e39849d2177a008cbfd14ddc4aac135203938e4c058b5864cdec6f4630f698e4982e25100a7de03a7a165b36c20b25a2406db953670785493ac8556e2930bc0005d179fb1cc274eecac96e64768729870bdb0af25a2bf01025222c48d91feb647108e624d075c8f83d762f3ec7097f84479d6f6b052ef975ae641ebd7844b4c525dd05ca9b4fb1f4cc18846935ddd74826a3745e34f3bf0d74f13fe0b497aa98fdaa59b94b60132537a943444cfe213900227ad73c8578030d9c6efa96e863480c3cd2cbf1976134c8b6309b996c18ad1fc84f4a98c5f3db36204c7b178557b0e5c99b0403e4d6e2dac218c925572d8bf7bf33e463fb2c88d24deb81342f9a19172b2f34fc9c86f4e81dc298e35199329806062b916760fe4cc9695d0993d31b1e8fefc67ad4e423dacf63695c13a0388e0601e34052d6acf7bcf7a7f2adb76402c324cb7ac3173ee51ff41f14b9d95fe71e6afa49fde9ddb9ef2b308c3a546c04c345dc0fd2fd8badf779e57490e6e8b25c678c5f1b001044d5d7637f629301843519b4196ea99c9151abc30943b13ea9d9c8ea8f5bd15008c8fd36bbf9845ffd90fb5d8954ea8edb10e53ebf78546397edf86d354adb3fcd3941569ae52d86e07223f2731b6f104edc3fe83c9eb17f1ab4bca27ec1601d45ac2c464f573aeb142846c28dd7f734965a8688b8d2334080634d344cc07bf7767c3d2dcc3e0b72d3e4901f5d3bdb490f1fa8a399e3e53eb3e487452072133613e6c1a0d932b5942c4512e019ada64d3dba28b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5c0e390645996263ff0688fc950bf924af30da7ed967bda13d245562e73717bdf16f566c8615848b7a481c4d5314c79cb5b8727408310a447e59eefa9ba69831c5a32828621fda3424b9cab229aa517e6cb5bd499c5a4041fbd90215e31baace04d3ef0467b80a663f74bcee526d7fd5d4c8d4cdfd8706afbf83b4db3c8f6b7fa8a61c9056279ec64c3de62378d02cfb745f357675bfa3b659f043e45996e1e9437e73ccdd7a8be5e9076213c77d08478d01fedfc16cea2cb37e3b89930c93426065e5b3c88b8a16d62a47ff8a6448a984aaf55e68d99ec5f0f4ce544de52459a82fb9fc4127a5313b421ac4693b0bbc1d5bbf4ade6a69e9482a37c42b07432ff4d5c218a08a6af2f00a443f258fe738cd8e54626324c6026993052439a0c47e3bc4849216c3340a76228f6a7796f3866849b35dbf25a6a28ec6a7f69962f345fbdc2e6d3074f3406c946fabfbb32ed52706bc6a649dfeb4e1e216eca02e441ddc8628b69c4529764bee6bea89470f94d7fbbddbae97e5314366bcb797887bcfc58cfcdfdf7cd8089ab564576be95e014330c804673507899e7c6c9854ebee4f58f439c264c87bedfd418fbc9fe87338e909bf3a1897c9ce51b13d5e1739d00e93b92c4da658b871e0ead827a93d39a5a0f6a5d04903e6fdcd9843673d3e0ce50f9551057b5a9fc55c9fb7839084852d677c8dc35e01f7a3f45a3a62cf8a38a685b43db8e0675abe73621476edc5a4d9e31b711a6c6392bced50ea9da3c845ad678f39beca8f3e3d4819c75c18f31ff38ba0e4c33d79f8698d413d5c77f95b52d64d45b44b5c0c453c5d7dd7a8a561820f89b9de92cb5846ac273e4e84f0e96c6a8ef78b8994ffae3a365c4f6c99c49accef4a86bb7cc89759abc94e728beba55a5a53acfec4879e3c14dd3d68d8ac05b794a46e20f67a573ff35f1e773ba9ef9ec55ac598bcfc365b131ed08cfdcaa46db1cf8ef1ca3d4f4629bc6514ea6a0f390f8a5c76d6ce4fb6b3581fd3413f7b861b3148743a4eb455b66762e499694f558f19765d6dc3fb7b075ff6a6c3f4a6f2ec58f688964804b6e590ad8be2873c3883135665ac3d6b0e710204689c2616487bf51295c5010347b4663b914bef02791a147c20574f1dbc7065e7b2a930236a99304b6529e95b9eadea48fa5490fcb8c59e6b5fbfe5522bc057e3f9aab8e7aca680cd620310a26bb4309a2f2c4c56226114f8ab63de71b74971197d6a52308910188b603ac8523493a751a1cdfd441259b03f5d140f862cad7a794307aa31cfc4624f2a740552266b22240e631638c2c17492adede14997d95e4890002110ce40fa83f416a2ed06806cfcc49bc9a1599512db09362aa01650f7cf56290d2e85424812cbc009afd5520da63b30dd814e25bb1f974b7f3f77c38c638e1943beeba234736a029342a13aac8d21da0747f41b217159869bbda51885ea9b0a99abac1b740ebf40cadc78a6fbe93076e214031264275c3d56486efdc00e9f1ab1d3bc98963c908ad13268d9b068cc2ad5c36f68a11281da7b2c325509383e71d098c22a1de3c3065f1082087338b3ab021b0a3fb2b5cbd1b29f7b3b7d897c8c874b9d71d34dd60bb686b99c82750527704a53c737b157a6c98a148ad0727d13cf770b038e9a275e568b19cc2bad360c958c54900c59b4bb69b8341362ac7fb589ca96f563de54a46d3c02c475788351c5ffccbda1998a87d7a27301095ac8577cb84c0a4a244cd8c544f4bc7b68cf02a99d9af90bbb42a1ce63740ea784e665882c6aa1ae151501e560ebe9116fa9cdfd749153b7310e1583feebc2856384923200a811b2c0f71c23076de6590a89b6b6114316eaf80c90480c1ec1c131990637765fb17c2b0cb1ca1c03a3461bc2c8534b35493b3dd3c8d7b6816d8127d192a6f7d79e805283e3e882e8120aad321bb6a197fc60cf443ace984510bc59c8ba832699c8b145bacbc090965ed08785f72d24f4b9ba70c41ea79c91591b2295cc5903b29e04bcf3566c9b7c001ada05744605f1845f3e13bf9f22744659b2913b2489b073b6f01765c756aa494a41e44b599719ef5968853c0896425085d75cbaf73abe304025ca6006858ee7c1c9cf0067b576c168651e3fdc9b9d978cb1c62354094faca0a4adb426c157166f08034cd4025a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d1a7e0760c345cb5875303e20e4c72076c794e56ab75231750a190b45f374d979a2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = c09c79e80d5fd851248fadb02c75d28926a95c17103cfdb6c190b9c97b77f128dcbed92b368b8610d7644d947f834fedbc5f53a1a40a421870229aa8807ea8e407a099b9eb10727fc7856eb275f18c153abfc89aa426592d159952cc6c4ccdd6b45e1f80de249a42728da33aca44b5868bc7bef745da90e297cdc7156be96de11ea7e699b24e62711e20d19f3b7cfdca8a2e1f09284fc3725973a0f60afe3eb0928bac1ff71b87985af10c522d381a381a54c8c33e3f8f639048391ee7a49806e68e327c5451e5435643f6260f5120260019b4240211929ccc9f243ff78e6b2c5ac80c0ba4d0ce6f2f8b43a44da5056c12e42aa920a819e0bd485e24db4ce6046a4477381bc71085f3fc45c1c0dd95dcbbdccabf7b17315efa3409646911ce8eacddca65b569ddd37005688c70d8f3d2478c7cb223bdfcbc33b98e88a92a7411075a225521ed126c3d708e5b4f4dae946931be4d33b9b6c1dcf0f06b74a71b3e4c7e776df38263b9cd3cc766dcc1bca5ab2c80af0b29277fceee8104afc8d45a68b84b014e7fe301646b0dcc1464bbc09c316b1b3731d85bf1df830b201456d4b7dd7f09809855d98854fd04602417ecf0603290ee6dd9d000e4dedec2c2f169fe46fec554c95d49f17713cb0e9023b2028f2a1f483ff3249d2627a41183f8c09072b3b35792565fef60f784b432266d8d6862b637a2d1d3417b2d4473c0d6311a9814471b28392c742148835350f07c4bff215e1c953b4915e39cc2836ba217adeeb9de4e5fec5c41fa292b0d8c09013d7e9aa61ff33d6e5dd50982b09c0aaafc07dbb7a24ad575659b036097c6a1cdb0783e4a8f33cbe999c188d07824aa0411d989dd9e9d490d9fb0b554a990da565df181a53459ded33a53f8a80484e91a136e02534e80a05c8fbe2d14b606ba681989f436ca2de0b75015fe2e461188ee8fc1623916349f37dd8199a50ea89e134f999de57dd76249a3476bd9f2bc8ce2dc898c7528f8e4ce77f21e84bdcf3e68dc751a660f72123f1658dfbad7627ae64c2d39e6b09a63de0f5e2423d7bcb520ec9c128d86a6e01cb712f524cd7b16d1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 72a882d4848543ad6f84cf8df3acf385cfc86bf97fe28f55aafabaeb2fa366da3e6de5b1518465ed6da5d0754fc5ce9bea36b63fed4a266e7b3a0358b603998db88c05593a638cf330adb4e417573ea5afa5036f753adbd90ef4b3287ddfcf6a99bf4a464a64502c92d284a2e23cfa50263872649367d39bf1f3e5e2fc566869da534b6ad9e6f98edc57eaedd8203a9206d3f88634ca87ca5b7dbdaadee53ce9d58e8b2b6cf44dafcfc73d989ec8c2079f352b5e6f0bc67a4fb58d2af661b336c37c3be84e8f93bc4205f693ad795bd3bf827bb96dcd66ae823465512f8ae5d9ec2bb9aef408ea2487f855f695929b97607f73d444d020f33aedec90ba0691da9f4b85feac30e4c34ffd949064892c0abc0b7c54c8bd998ceec48cfd9b6efe430864d0ac96637ce7b6ce3fb8fe778d9fc6f41ee58704737989c9345e88bd46f96c3f43c6482c9ccca9f0100dfb9e5cda408e468ff5624a15d27269ec04d5a44fe79ca2a575c9ca4d63add1230482fafc9f314de80dfd36a875afa17a979c1b8c835931a87bd90df5f36365acc7fef82593aca8f74173bd3d72a9c58cca346d488127046660bc7937ada78d2d9ffecfcb24a4c9686a988b8437ceed43ae34c528698643c9e6ef7b8d66c77d70d5d75b2bfab0975fba08a6ca94d3a753a63de3ff7eae5b2efdf5b015cafa85c0409a5b1113371b2ef43c56f6f74a76f306fa11e8851b265a302a5a49afa2296e864e5c8ab0a4d36338c1b5cc7dafcb5f66e585f6447864f5d5efc363a939bab445c2007973196e43d7f38aea6ad0b88fe3a6ed53f6f74e9ab9f57415ea5b38e99063e182549371b9610f69a3ef45e9d06a764d63e02bc68c230e45f417fd3ce5c7a894dbbd2cf1a3034fe5584fa629ef451f8652c73b09868fdc947cd90cb7ffa2f5be48363437c5c463e4a69460c3f55882b352937ca65b344c4a3f63ba8add1513796926f4380db4faacc36f85872f049b399cad9df55f29e93aa6656c3139773546f75de5b526a9f99a6548d626c0c49e41d64889f31de3f706966e1db60b9b311c83b69ce9888bfbfcc87e92a1c73f1f34bce7752afb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afba81681b834d55864f8e240a69067ba1384f9279576110a0809b34c81aa350cae66c535d5f24315fcb30b3469e59c45f44915d9a010e834071a60b4e29001674326e8b556943246365c87d9133a7e68a6f57b63f5b72a94d2545dd682143ca0ec892ca3376ddb188a83b3ca5d31899c5b8a0ce014ddc1bec2988171d7bbec2742feb77e286306d53b687f9c04c45a4eedd1c4dc593067086f1728724c282dc8b94978a67bacda824e6a259e12c44340159510526b6630df44bd4eca50c62b77fba073de86c167e9974316962c6805dffca9f5d4a413cc04da0b4a9bbc3db7eb825d7b1f3f942870c559f900bd0082c13dbb59d68b8b7b84906b4c5e86ac94da520b54a5bea0f51fdd12cf53e90ab317117e320afb377cca024d91685a2371612724208fd02a2240b32349893544535ec21655d398914bc53589b5a6a920dba6b76b125c32611c9db77827132a00651f6bc3394eba975bc40e87c34a696a8ebca0cd356517b4b16f53c99feb517337a8231286a0ece32a9208bf90daac845cabb86c8d61d498543c4ad2325cc82a75a11a9751c6a0d1a7015f74ae1e32485b26372366cc97f42ea0840e20bb54800028e537cbe867aee64a1ed4453d27768a55815557e71a3857012e33172b3a6abc6729b207559899043185919883c9e6f74d1c5414e5728d18785ccaaccb753b61a6518ef57b4546c5261ed80d6262ace4d72f423b15f60312a9352e19e0887e7a131e590cf24b499dfa53ac3c5123240469350e097524263cad98a50e46739bd342bcf5d454df2a82004ac7ca8c23a7b406fd396239f74ab0686141d3ce9aa85efafabe79c1bbe2883efc6b18a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637e0259e485203077a2658a73871b70e28358c94143e78802596a4124b75a2376718b548d8eea706a4a256b297271a2a0afda68030504e5c35f7f4cab2a667897774fdde85e5ae01fec059111a1b1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c817505418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc0f96fb9e146a1c22cc5d23e9108af0dc5e13b7810b8f5598bbd5f8d4b54c8af7df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = a1a2955d5ab07eb09594fc40e3f42f6b9b9972f432df202e36c9d06ae6a5e866e3a8311a128f7d6e2478aeedeb19d43cd3b66d21a4896900bffc09445dd07b6eb7ff69c3e4b44111b8176323952489eb1989a5ace34b7af22b90f2b70b71541ddc796f90e4db332fb5a879564bafa9af37b8f3c12f5212a12a1d960a5d67079691ec1617a3a491ed17cd7d7735b4eeba90424de5187672751b3738223af79c70231f12897e2b6fb924dac07174498737ebfac17af295a56f26ccefb75b34ea5a14f17dcdc8ef9ebea5e6d966c8203310898ecd3955a85bcd1b66c64624dc7f83e487c2209f810f026a9230ea8e0cb577db040fe22e5e94120d40484d6baaf90f000972b1d304dea1f0ab2e964c1d46e28a879ab5aa67d4e4434b787d5b04cfee49e913e793ecd38deed4f234fbab2e984787cc3976cf59b0cff5692c53ff83ea0cbe67e392dc31b906593fd82fc34ce1e26393679fa3a2a53a98760ca751334fee40170b90572a77cbbffe7520809dfd35f3d5a336b2c6ab06bea4ebb15a0b06782da865de8a7b7e7d0b4c533bc8d5808e563db58c3937a783ebb0a89c5b20eaca2b8383b3ad8bf8f69566a017a2e8b49eb25571dadd14e799606f6da308d5d3b951f86536cb50aa0ac17c0b846163dd580144513610754f5f2fdde7cf67fe73e75d763699c4e77c6f5be7eec75af73c1a6bb4bd48bf54855ef6d2ddb82b9a3ccf51341f3a8dd946635b96f2e3f2745f948eadaef103cd69ce5c7c0cd87d9b97356aa7e4788333664222c36d5b1e295aaf26a407a6ee0b80b17c8a9d242afb71340ee78bd13657d915ff8f7bdd0d938d6a09d879af23d4f39c8582f5a0cc6a0cfd6256b53ab0896a03904c9a7cf724f98442e37dd5b28c06bbf0d3b9bfbec38283479f54178c04c3183ab8d1ad2bcb745650bb0f27bdf073a732f6a3e97fe98aee80b50bea056dea21395982641278454327301b79e05aaa6e3667cf4da8b396ff499bbfb3f9e6e338c42a2969992bfc8a3755160a93a73457b0a50b2c8d3cadfd52cf2bda2897a98c9bff35c442ae37bd6c4a4044955b4d9f57a4386c4dd240 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2a0ca3aa8c5b2134f6e4066cbf85c540177324559cb6ed65a31aa5daa69448b5469b24587d6cc2a053abfd4588aa65789469fc21aa88c3fcb7fc1a7f513fa786dbe21e38b68fddd96e253f3caa94cc6a841867a582a77494dbacd97b8adc76f99e54444a2b420303429aa55022c961f0d953d9967cdb9397e673e956e59259164e666cce7e4db9817f9737554090fe303d29add787dd6b6cc40297648a66c1e8ef53cfd631430baa4b8ded8803bb834483eb198bea06aeea9a4c6497e99bc5badc45f6722f82eebe73b07830dc26bd796661bc677d73d4ae72a5575ee389bd2ace0566e651999fea3f6c9109a1727adea3354bac66794af387ff097e37c3e6d079c6f22c8932b8b02f43d50e2dc0387d495636cee8a557ade6ee46bfd703eea2e04a854338af5fc4478be47271c99c24d79f4a38a560488b624ca0ec5991b24eb3e72e41c73a457ff5635923c7c7e3522dbc937ae5bfea6fc298cec6fed6bb1c4a7b67dfaefb7eb272e7455948ee04fa6d7a5e43ab6789c06384b7effa37eae2c2a3ce92fad9b705a0f06e379b98a1714c71fb044f3427cc212edc432fd7a05cb36aa4477c86732d949b64ccbc8f94e089c878491c47940ac61a69f0eb23ca823c8f4543fe4317bff026e47145c299db4e8cea71d10d85101e3f13ed429f596df9cb4aba33f9cbef734b3c4c0b2643f87eff473bc0079e99e2fd8cb04cfeb8e96d92e6305909be11acb29c399d4bf8b48f5cc47e8973b51454e67aa5578359ff19325efb749348fa41665ba2de68bc0ec1577495aaea9ad387f52b39402c598c61efb3771edc981ec59508ee652c5c39cc8857b949e51a8939f4548a1959dfa464020bbcf5a9d89ad9d58cece061aa34c79be6698f31d98792ec33d6381f92468ebea2b3e5841a6a4aad9e8d47666a94f7c91ebb839745c83bae66be54c6463b98448bc638cac1064b03565f295495eb9ca032f778cfba4ade47a906379a457c6231c8ceb3fc42f9175dd50c38323c46b71395c114a3be1d44b6176dd58ac0beeab68ecead57f7abc6049a04bca06cabdc95456b1afda2b91ff412463d20f4d54a20774e234119411edbb3515e4c00a4987d491c37b3890db4ab249d28aef2c0cee1768c52b70cee7966b31c58ec975ef8b96dd2e156544a88a9772bfc834d422599b117968b648172b2ace7633ede1624b0a4cd031779040128c0e94332b03a798579206873b5583ca9c6be34632fddcc223a76c415e262ec8831fe32225ab2b484758728182eb45c851118cfc5086974403f6b161028534bc0390dc7d7902493440134c784b30289833652e96c58d12867cccd61713b51345c21c865976c0857808422f78de8b95472627cf6b895dd4065c68156bcd16e65494da75ac2e04668e0548e9658cb55d89bc8f98333e030a4720027aba862fb6f3b006f6be711b10b6d5e30b892708f42c49006357da4f637e8b3210e49817a9026b7403d64d861dc65955d75028e596fa68c97edf133d0997d84f342caab0f52db4b1330af6ca57b8b2423275255dc605fb9111907b648834c37ad812a300a715e231dba4551066051d31b82b6c3be14928c9cb78179e16ec0088cec140d3d6842776b30df33a11154a04ea7a6ade981b8c2995a37bd16734f98e95e1f753425f15c1a9b69ac4bb27a9bbff4f1845a734baa620595a66c97b64b43eb2c54f43e506cb8a7b759fb063f7c957155db10fc194171acbbe5eb47e024730a76c04d4525baeac5bef681bc3159bf0821c5b448e3a2c6bcaa55efa55e84e5084d257a0f7a97c322c8c1848fadc7a2f3db817816758220a5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b365132ebe95dc25a9ac3a1838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1d81755877c83b6511e10ce4d52440bd94c246579711150a33c62f42192e90a178f676ddb34a05401a151a4c167391d199211644238e8500bfb94adda266e23c0cc5f422a5c0719cc1a870e768c5fa95eba105e904a9875fcc58ff39375b72f84f12672386b690710b6b96c4aa17816a6a3fcf68e7b724ef4982c05799cb7a502b08b9ecde916b3e47636835c500360f24843c265b1d282a34f04ba6246b6ade8abbdfa13681542e77b17d398088b6243b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f20bb63b48b8cdd1c7242bd4f017c519b43502656e23817bfd683150488f8b0b44df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = 611c29905b1384fabbfe2241469d171ae5469bf944110ef6a79c5e06e36540300649545d479c143ebe97252515c9e3ecc003f03550b35ea31f9ccbc371aabb2702c7efb4e538b451446db1e85d9c7e2f7486a93a72f86fec574a94ca1e822c49ed6b9b06c4f9340c14ed887452c2681feb3674726b29d6ea6bc46f2c6de226076d154190525eb6ccddca62cc2b1ba3e5d1232e5f1117038f6d1d4b61fe754b5b5de5c55457108d37e27b2205686f0332e196974722f7904bf3eb1415fdc89bf92f8094f16ba89911276bcc33705556a4098d0bd66dc1a668f459cf4a7299f49b2df5d1cb248ba17fa613b810c21f864d1e9ea7e78d474a101a813e0825ee47440de187418943ce495cd84da8d5aebe3a347a156c03928fe6c4c0bdd23fcaf0f675fbe2d72e08ca6781730609eb298e346046953b1f915d98bf5bdfa582b1ffe5f200d54b2086f783e69f969cea706ac47501b37457ee208cb678cc12bc4328a21522b91d849d3128e6932bf7f1cbbe494e5c918c97dec505ddee8de0ea977c7822c1525b4335f1db864ce2071b50303a264f8aad6f1965638c97ccebc85fee2b3497401ff6fc02e6b3c4b97560c9df4b2c8601081991d7bac94149e2caff5d2552db4da90380f5e1fc06e85d55634a5570781b752331e39dc86da264fa7d7b627664f110b41f3ba7c702e104a3e0661660b8ea1f7a681af65be2c03f13a2b2e10674b55176a8c4ccf51523eee02f99581c48cc522886826e69b142702218772c25c082c381806d348835c28829eb81930dd527a3d7f8199e0bbd841822668c75bbf44afb9d3ac2219fba4f66e8ab1f40848b89011e417e5df41de43cd2446fbc7537b396e82aebdb03849f19b27f54d2b472b4c4a3517e777440b5870edd45f5f29d830e4368bec78623f0fedef49e49e32d1be375f0f7b0cc152d8d8a75edcd67f31e1959155e5e6ade4caf7494c6465917962707a1231ccbfc9571d5338cd30c0ae7f7ab40ecc9e1f11cfad4e1c98398476666528dd04130a978895a37db9669a0dcdd6426ebaf8c8f24cfa3699b275fca7c1e624c816708d4c0be6df7d8a5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 55ed4cedf980fb5ee4caaf85df546391f5f3d5add9356878bb2c49c77462054afebd08d3d253c695fee169f9402a5f79e9638c126895762a5c0b6ba3c7d44c91b4543163c27bf9650c74cf472cba6907ea090d4540b83c7f18efb827c2cc4e86160362bc0a71d70fb41ce539520eb0235662d54e429c964b28f4730b0fdb8035f9e046b662b7fecc2d6a18ab7f002b8a235dd7e41f449ca5b9a01ac4d54cc00d2ff4bf9cdf6034ae9c8862d4cda58367f82a55a8133a95863be68266a9473c7abd18e3e9b53fadc6e9a59fa93e7d8a8ebfa84f866edcbdcfe1be8dd9adbd738ea7ed5d79ea5fa5608cd7e5db6fba2ad10e38e67b28b684bab4dd2b76ff5af2775fbf2e448dcf86ba4995e8f983b0b048c166256aa5f38405db95c8e848df37bd982ed8ac88f3440f6e473c435bb5a3573b866134996a1da5b5e9ed3538ebc209f9d9144f954c4ff31c352308dd8aa4f0e074d73dd8a6a6f85c3f4b6246ae900cde5ec228d1fdf88c88bed5811ef7d60ed70b6676f8ffcdc717c9b35ba6e7ce6f4499f667ace006cad014bfbc35c37fdbbd7e5db79253e9669a08db98277c664f5926ad59dccba3c068de8e5a86ddc8ace81971cc6ad6be7b9b90bfcee5aeb5b614340db5314cefaf86cd658afe88f4e4f73869d736a381ce333a867be08cb88ae698d35959d3fbaf80532c37a0a4cf082b37dfa7c438d9386e0f9be2c6bdc3554c6d458d38fd930ad7edf99b7468858c9e2af561bbbc858bcdab73b82768503e946d48e65f3b1f53e99c42358dcef6979ac96c7b10cc6311375206b9dad4346590d69a3ee848a1d5f8794ec7d58b5db1bd749026387c93a29b7586a25dca803c3f36997fd523af0014a905e3baa92b92d0d34789df530fe774e817e830c869e34e7b39ecb6f0485ec787df25e3ba22eacf5c28de665bc80a6f48ea0a881d69d42ab55f7b1c8aa0f348675c5b4eb549dfb770af8633c0089eec5cb979646ae579a99d58554c2ad530a856320efeb116c7e5dfa89e2b42cda77b957962a1ea4b089b42d5fca00355f9a4134703fd6e99aee3c284ad2d23ea99f592d3f7b50069746c10a1acf866163b55706133db1c41474a3ef0d4c7f131637d32b4803ac902fb5246c858a7426f9145cec60047473666a5e9c37b8ca4b5c1161dc5479341876aea6c515b564d68650b9822c6a817b5938f3809a784010278751d539b75ec07ba09aa34b08178ce5cb5bf70c99df201018b55e21c8a51b9a70be2997ac10b8a783cd9c54e69cb8b8a360d0dbcb9d6210933a5b7c5853af4b22364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a45181be8181ca2515d1394e7ef46ab68a1e93351a6da3684c8272c3e41547eb9e2e397a18f982e95730529c2affb88fef731978388791cb053906a57241cf99525fc87cae12e7360bb2a68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee3b231bc28bfe1534a24e15dbeb43fdb40238443a29d3685f3180d65658aea5b96078ba150623ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f19b1cd92177c4c2019789765790adb3d63c59719a292069922c5ab4b6b9ec2523ac919081764019282b16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e74e10196ec67de372878345213754af4d2affff085c970b6fd7ca06bfa60dbe526114bb854480d519a09bf5b6831f4b2238b99428538ff27c66777a49b4108fe3ccb4ad486f54a01e514266fd96a61fc2757facd39e071a0896e93036db4b110c8d78b586aafa5f182e1d05e17446f6158cd34427624a488fb4650c8883190f1b60374b0e8418a12866aa8000a7b2ca387b4b792c3719ae883a030150a668cdeeb6e8e59ad3e420361361a5a149c85880e245888192560052b490248b91a29adc0708344280b0b153bcbc0b575593245718b0180216d9a3847a186f312c169f42853820e862b90a4429f5d927a340589e193a5bfaa46f5350145ba2e6cd2727fc2545ee5bd74d4a38e181e527a80e2288444d860e7400b3ae3827a24042596124ad345e43a03ca310d37522dd962b71e8b3b1e3b29972934bf00015b6380617c8958303494d03366b6a51e7ccf6d3abdfb242ffb8367fe3a1d44ba87bda4587a9427dac62d280a0cb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2d19bf7937eeab0d2a7570d43cf965547542a519be85bdd4921f7d710747ec6f0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = 7a7a1d8bbe39d2b6835bb8b12574366cdb528f4f642dbc4b07509a753fb71c25357604a06cee0863b279ba50379adf586e20bddc3f925008d1acfca6c0a77172de26a4098808669ff9dc4b2782fc9b5b1a331af04db5499e91f9ed855eb87a177748f9822a686f2bdb5864ce400879d5babe9282c28e175fee97973feadc09625bcf040ac94fdd59835d4a6da91dd5fcd403a5ae336105e36177534c8bd5adb7aae4081f19de5bc251f87a5424b5ec92c13832a68effce05af6d9cfab72d8bd36390f874c551ac5486c632f2d9c19bb12124b2fab29dd4103f0a27227f0c007d73125a3c392029ef290e7649b5d52766b9204ad2e80256426728fc58484441b58e08b769eafe5e5a60e055eb340c6b026c1f567169fab3b33df4b635943db3f4dd97c3f35642ab82740e98ee138d6da37dd01cc55b33993a1a70650d98cdf6b2798b9311a7a5094d442191911b16cbf00595e0cc1bca40d53dcf3540d5d07402275e552c57d04d7a6cfcfacd57010fb4c617a171c4bea0bf726d7f10168512bcf0dd4056ef513aa31416164ce130b8e041556e548e961ca5cecd42c80eeaf0297612c4a71d6c42e11607783e7e44a99cbdc9ff3dba5ec0b1b975c296b09da8e326d1e4d6207cda1dc8677c5659aa6db0ebde94b720bcb7f7b7b46e31b233dcdcd527326625f14debf1d7a7a8a35fcc5868eee21b00f8039af84642772b605a2b72e0d2133b4d7c4915d8e461c67c6e10b94a8c0f7ac81ee47a81eedfb660d28509acbc21dfa08435f61197cfe0fe4b73d2d0025d69fc57787f4b669bc559915157fe394557bffba9df7bd462791d8fc054ec2bf72cb597898b0e2a56a9b24ae93db062ceb59851ec2ae301e51eec0a5f60cdfb575762f227cbfa8a143e6b1ecfeed0682f4f2958b5749b1dac33483832ba37bf50d2ed6b31af31b608794b365cd7015c592c782a965f76f73dde41f4b345b74de4ec9f837b88f53d444eb038ee587d33daf46235787f21c8f3b257024fec18dd26cbb72af837dc30c92a76150dd41a3871a188b9894c01aacf1c302e7972d4d39bd4ce473c3171edee2c707e4b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = cc88eef0e49bc86b3f35c4645edb42a0a37a186def80367ccb6ec8e6b9715f2536aacf7edee33408ae59cc1a59cbb3de3d79a058c97e30e36dd4553354bd57afd87e422ff23e38368998f56b9c6a1b3fe4c25beac0aa88391b71237d607a284863be92a39cfbd62a7a64d3cd1a9bb88d13e38c88880817c11105c761c7cd0fa53a2624307df5ab96bfcbe6d87a6278849bfab67c95abb0ec9c58f33be488bf4e9635890ae363d4ccb16d6e7d88911d8f791b9ec90c674af04576e3f3e4067d8fbfdafbf317ad04ce87492a6fbf498a66389c9f5469e55dc09463d324ebecde6be5fea74c9cb7382aeb76405950658f55afae3160f4eb00cdd5e5afeebaecbb23b6a87cc96d3ea8bba60d903a44b8a085c97f58f0ff6dfbeb69cd71f58c6a9b7089d4bacddcce29ddb63b04b7e33b44b6dbe623e64141fac4b6d573d32fa28ba8c02053515514f69d6de091536d598336b649e148b460aa4d7b2fe7ad8c439649a9a17e5554bce7a4673b7a0f048f121d4bc5b5c0d23eda8995d2335ca8ce2cfed6caf9c69e89e6c7ca0077343ffc9e213c8f08b5f41ee7a4359f386409b72a6a8fd01b81836b794f8fa7e413e623c977c5b3a666dd5d497abb466b73ef05847cba6c7dd9554bef37f7fb92af7dcc273b44437cd0719f8117bd65578adacd3f55956a84b7e64b993577914781933d72194d515d073f2d9e722d3b9c76a7ad8ecc7bf08d9aebdb7ab24ac9783cecab0eb8872bd1888d39173a9c76cf784197fd5538a990b530cda7ab670742f9ea32b8289dfa93fcc538f60688c645f43a7c8e601bd68ed2f6a4f5b6ea9096832a1d3caef59f80a9c430064bcda9c7d58edf82fc646cda3454893def63c8b40eedb006580a8a955d5a55d0387ad9d5d51cdb8e9a03520b5a7ae0cc5b63a368f644f587144166dd8df5af9456ceee6293a6392dfc0f0836518be5f6c7f6b5ea8dfc354d84bcc8c3c965dc3788682a41209d4d5edb6a25cb42742e4ca27cfa8b787fe468463fbde20798b8c5b78d7f3561ecf59aa81ba0504aff4e777a4ecfad49cbf9edd64cdbe5ab0849d5d1ae9f347c789b08b2608a70da01862dd25b9717bcce38ac41045d44876aade7c1ed6a2aa638994db7011fd42b3d474b08f87b4b2a3b83ea94b4a21d214bc2c974a078b22598a7cd7895942ac29d876b9723f32fc3bb696b467bea64b176c1219732af5e21ab49b49fdb0bcf9152600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d380130aff7a0ba20a75f8a04238294a4191ebc900d255ba923056464f6621d2b96c493c2e5379a95d16f4b5a72e5c5ba3840517a28ab3d8a8c3b8c63e882ae37f4215a74bf62c54bcb65159f9ccd88e07933d4936f12c2ff174f84a1a93e1a9163d0cce3290324355c1d6b21ed458e2f5883a8806b2d65a5f85b3bc103a692c94333331671f54629e89b1be35c25746130d7a9b939cbe017170fec7d5675b3bba33e4e086d4c6625580536d0c28ab5e073e5f37cad826173cb422f60bc11208fd0023395603d8d047fa57cabacb428d2f361a13321bc20827d5566dba65bbd827a2f952a065ca19fc208f4617e0bc9bb97e82f4322413d7317c14866bc72242134c38a7774d1580485fa4e3905122ea993b03b12a1f6323ab778fce157e3450eb02357a71c3caf9571fb83718748b2adc18296f570b05c4a77502062841ad216389b3b3b71c0aaca94a7051b0b523504209566bc153b3206b822779a98f59842442cd2b5246c674105b450f8e385d1585e651c934c4312d3208f7740a6f8a47e3393221c40747e452e1b0b7918b64d6c018a130416fd32c20ff641ddf25bec731f9bc9a36da09c1f5a058440b920694b2e9437bf23c1bc80835447a33f40a8dcbca09a14cc83d44b20da529b303d74932cd2761d27f5027fd01f93e907bd0538898078f57395ee2972642097944c19ccbcb4cfbaa79289ae31a230c67218b3c7075ff32563089a1e65aab279c3e4d9c07deba0f72a796f601382385568275c8aa6b26a8caffbb09e44409d1c404b6fd957a967a17c83cdbcab30d299a623d4b0da14a1971a09bc83a59f56a05bc6727d91572bac8fe834105616b5ef3c3e0cc2998f5006efb3673f4471b6e9005957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd6907e1096410ab332e10f37c93d86d9b4657159eac1faffcd1688d182d1278444f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = 7732839346a2622b81e6f6393906e2b65189bff14adfb40da9805938d2f55f9199775973a056c5ce0657a05b0a536e07e01bc9d44d662d08431e8ca1ce895bfc2d7431d6b301ca1e4c1da5332c52eb4c31c6a4954d0d421b7d43ca0b80348b6a7cfd20cb3d68af3a9bb1b850b7f74ecdf9d315504e20449b4eaff80f72d5019b5f0143133e3e44e0536d8f141f4648a43092475014a7d6081ffbbf6a6f13f5bb04ce6a2171cafaed5f945e3f167d8d79db5bffee110c267f24ca57c0d76cfdaec5a63a3c812988ece57da484fd646019f609b1b1574d858ff2909712c8c80f14a4a2f3b0daaed6930a450309cef3dade546faf53af8c2527d796ec430335fda2f83daf0722b5bb5edbc0c80234f549e10c306e20a0fd578d02c862073467e9e9e6e9f3c03062a447c7f3b8d2bfe2d7de50c3207176edb6ac36129d10d66eaa553ab94b9317d77bccf9b290c4c44f00a9f764c7ca051b04fb14448a9347515cf0ffd3dfa35e7dac0ea32b6f26f6a34e4763698cc45360dd7037f531bd9020dc5ab4ea337320443e002f40f54d0c90070a9e65007944a40bda666409b318d4d09a1d2b50d8f71004d03cc2ec7afbd4b5319ccbe3b92732d9389e27866465075019f3d986781d5c846c14e5f81c595b2a5e680acc0e82166452bec3bc4a1e4ea0b6acc7db2a6a051505e7508dd5b61bbf8a8652e36446f4025b105cce2cc3a880539757d0e7086226df342b4107f451164bf4e230da1c8fb9d8260c6383e9615856328f4593c3620accc0cda5f70ce070aa7928c1065e1dd5d44ad08905a50b59691559e0f2015add5468bc5be41ffe9b5f3eaae5e865a33dc2b08bfe09ed59a71d49ef3b57e96635cccdca8f7aedc1b7f1584dcc287b23b5e61c48ca7f4c1d0c329cb65c6019cc3f4ab37f79d2c8de8a1229c9357913c20a8e7d2a99dddb0da67e5278757c39821980fca495c213017e1acfef18c8e4128bdc0b7bbbb7100891428ec50bd867a0efbc7e91634731998cbc8e37086f321c32f2b90146999f97caf5226debe2a4e0a670980325bf48293561f8ad6f974484dbf856ff2e3c7d1a30aa +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 9c8f8ac37baa3fefbe76b5408f6dcab8e684e2ce6df00c78cfd470022dd51efca6161789887899bd7e408f3f587c5fcae867df9a1cd17773b1de06aefa38b980caa7ca23c4534a87bc9bfbf34f33e05f6cf57c7b9bdfb1db465d8529c4855589e9e58f8e6ff93afafedf73dfbc9968abfd8fbd539849e3912edb91b1184ef578f7e114d04dad5e75a6c90a55f3b39883b66b653dbcdddea5383395498e0b96110c5d62ac3ea615e2ca03670dfb89902cd89d4c59fa95b6a6aeeed4ccd008fbb58f2cd706fe52c5846e753482a5f677dd7980ac7a3ea339b1ca2efaebaf83b009c466454c8c99fb7f8a4be7cbf3e057c36e837f67058fc01bae82cf59b605a02153ab7884f59d7bc593574acf7da2259f401e2aab888dab893a820e33779c9f85e0c6da018b3efa88583c76881a1c7277f585d836f3c75d565e55cdd57d8415585abfcdbbdb7c8f695bee998382ea1932a7d9c8fad682d9d6f063eccc63cc69f7a7a64515f21c2e94f24a79f2bedd7a26a1869e79bdd45c44d9b04216e19ca6ae64b97f4865561a0580941c90adcf37e3d3427eeaa15578b6bdc8741ca9a46fea9ea0754208779e9a748a1a648cfd9dffb3ce740444a6dfcca13b55dc6fe8848fbf37036ea1d0bbc39f16320ed4abb7a65ec2ec4ad083831074ff4f85f808c3f2602efb8e2791971d7db34d7192fcd84c5b401058eabcfaf27ec49f63bace46b67a123a3664fb8df7bacdc8fa44f8c99dca57957b446fb6c871fa74f21b3a81c71df208553bcc8afd89ac403008b1bcb344a2bac20ede66f57fe2059c42939fa3632eb6cb5e645729d02d0ad57eceece9c7a6e26aa77333ae1ee33d859d487f47e8f8046a0384daa02887147db0f246cf227c7318558b935ee90ddafb6f8fde8fc98abe6d3f78cea7597c49c375edbc05540b59bff8aef184593c78755421b58ff6c84f1dbe73a27baead1d924536df36fe4f9f3cfbd694af6146a95e7abec6198345df81ba6d3a32e45d1a4b359208beef6fa60b77f88d8663521d71fabb6716867f3895d7a1aaa70d2684595d4614969c912fa920b45354a89700145941e7a1055323ba95c83ac687a58a7f92701e7c388a4dcbcc611aaf6399522960a44d316b77734f025218e3c2b201b0816cbacd5b9b303297b0361b23d531a77dc965ee89694288460844259a735cf0c4c0add2457c5724fdfa1ef4546e5ef7c2363760ad478aa7806df9e35f0e46ca8dd643c36c6c9ee3b564181893b1b3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f5631102aad2b901d5a7675d541dcfe35e92239776a81e758c1c54e00d380232d5849102117d54144a20247017148584c1038a9329b9ca5c1dd337c1f758f558628c6962eaf49abab214279138db549c04f87bf243bcab3757f75b95c1f08685f20cde8c6d1a353fbdb3abc0599948ebc82e2434aca485d191287bca1678d2ca75497d73296177009bd384a9a5d0ac8b6102760261852b63d0520fe82b9307d1ae2b8c38bc1054c0295f7ae2321dfc82417849a3bba7467232830c35c08038ce2c4562b7a89171864e566121f6278a0b777e02bc50029718709af63a7014d8b9f79627f61b457a25c202a6cdd6f9a59fcc3cda84a1a43620b1394fa65841162638342a24671a6a71e092a7a19866ab7519e723d6ecb836998af8724efcd2941a5bc225f9acf8468b5c68a781b664e3614fee782c20e80cc8f27d1f455397509c86067979d7407b1bb536408c654c624adc0cc126bd3ea29c33f897e168c9c715887474cf1479450b80659f816a7e1999a8f2008cc9cc732a35c8d3b290988dfa31a80fbc1a18a58263c7bf18dc0498260e66fcc6b991b4e91ace50240e7a2a4563460d016314c404b269fa9a8d1b0c074545feb288208b790de67dc3c787a12b0041c52f80ec9f6a96733d874e986a3e06b72cc4b2ad2460b7aa2141f3b186525aa6b6d2901d46ae2f5c7a195c55a48934b4478974370a982414d9a160a8c45aba043dc597a2d2a4acec6708a3ba881c925c215a8063fb80f0114a94c63a1971249368b772a662ac38856c79c7b726884cf5a014527da479c1d7747b4d74cf33f30612b70d1e0c2faea53ea1164bf9733935d51542ba3a47b099fc82cb8ec391a1361c19484f1bd52dc2315e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c379c9176059f3a7ddfe021041301bcebbc91e997a0d5bf2ed1d9d125a71298341c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 9a9b4571820f9c5f47b07bdb1c67abb85c73355083931db78f6325c2704ca2d94938b4254ee3b0f7a854dc5d538ad0acc2d8377a53e660a8c4d21401609c78402fd6b54da88709c291fdb782b71606aba066ccde8a916ecd03c4bd8a2742cb2c73947b2d1e27cd5a11b8e775ce9be45ea145a5b1f30c3f9f1186d070c898e2a8b685926d390aae1649bcdc5ab20793c1d6b6baa9f53e8a62780b65cd7c7df3ce7dfdea8efe17522a23b916a58c34999dceae36aba7e048be1d3bcdd1237ace16b56370c3ba759776b1a11648cb0f903343fd2b4b8f023e85c07bc4a27ff53e9d98c6ce95c867e267f80f93d5bd8aefd0606b37a8d2f6f7f1f4658157fa24419add7037bc7b9218386dfb29142e80c4b8b8e4a85c068061b84e869296a4b1ed7e4390b29d7defb0123e466e2ec2efdc79d47b134834e6fbbe1b48c8121604fca5115ccae3bd7b2e56171e47797074489da8595c995fc55bff27dbb6f6f9ad0a068ccf7369e58e47a02d89b68903f9b05e7c65fbc77eb9f85d00257a09b8bf5ef6a07e4f5c1cc2634c37b822f96dba4481522b9244666281168702e7cba9824ce6f9e04deb7250beeccd74db0fb7331748e0b766c398912c42f226cae3bbbe19e37b17ea3fef017e4bbeabf53313eff762dce9879966ac17b8854e95f8cf7bf007fb13743532deb9ed840b96cbf15f15d83f0f6642808dd917a6eeaafc205caf9e4d4fa6097fb91703a11efb675c9210c75ae4767022c220709af702fb162dc901e0803dc5b3357e88fe7c72b67e53f01393faa1fc25269c874766690aee0e523a2c7c6fdccf17f288f517f3870d1b3a9c02fea5892535b97f55da5efd615b74dcc86b2f077c0f0e2b4e43b043332bc7195af2a2375e55c062fff5edafac0e62a334b24fcc6e5667bd256605ebec5c162cbde1e40c652b4dacd864d144641b3034eff93d75fa59a8681d5e4ee1d582c1fbedceee28839f3ef1fb79d4eb7af134c4984e86d8389dfa7a21690667ca1e6ee44bd66e6c3ffd94e84347d6cc233e33210d737c37f5188d8c9c33d7a41d76c0a60862e0ccc87b787e574634e3b130bc20 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f2eceb40867ecca65895a6dfffd6d469e8d9a85cbb383886badd37785345d57936dd7ab93bed504d03fe8438662f15d72036f593adf489f9a90233cb20a5492bfaae4b444ad1d8c84c0a37f6d9f8b8a89c22b3f6845d73b978a2013efc5c1dd334bc936fb3c8f36f6c862c52025a73426ade1604de2d8755654d659ab53d6db763b8fe9a00ed6a9a0e7a5677b62b24eabe9d8a5177fa65f3e493659763ad479508e0254ca4d3683cef6d8df6c79a70994fdf5f8775a991c0bed35fbebcb6da3c6353fbf958790b8e620b6e4e3a43dc1dc658e7398739b75e1437451e2e368c798009178a831ce9b72e802d848918ab34450e75c835f32f7d637527c2e276ba02aba364fd82142c9e4cdad9515c801ec78ac7ac6866acfa054cba8008603f9a3368793c0bb7346228f978efd2df4abeedf7d9222edce8f6e08b784a2be9b4410876b15ad97e5dbd8cb933ab26d860a5d6570dd7a0786f1894736c7c694e8a81a40eb28b9a43be1435276ea1edeee104fc52dc9ec1e9f85f1b0bf1ccc971f2ba850599ddddd3e18ee98cb2459cb3fdd3de4b3d4edb74c944d56f4a824c8fee38df47142bbefe25acd52b31235e9fee154d9c098525839d9e8593d3a5b2dd09ece4286a4ff470d45b55f5f75db92b8add6f6390698bd88d977ff5902f2d666aed92ece5d02f43801bdce4e75553ddd5a122faf4c0ceb799b7f7f546fff90c99b035b3b2c545e985860bf8c1fb5e7d348a88bf85690faee192a643de17b25363686f6a3f7d643cac6b536c8b536ab84e3e7be200dc7f71a989d14d98ba39cc16df776e5db3926ffe4bb6d9176f5941594f76d7469599d85fe457945f9924d6bcea397fafe8a9644ee5824f9f194a76d627583c5e675dc4ebf42650dd44c599ceaafc177dffbbc6bea8bdc77ce4408fb032f45eeb87d231e8b85c8744baa5d7f7ecd0b1dd5772c9f7c09cbe93ad5c80987080a69d570d94b4cdf1c38a32372fc3620ad909259df6cb8138d9774bff79d498fe4334aeb7a9b1ed8f648e4d7491de68a95c769869a8e76fe156867b1db3ca7559ad74574ed6d6eb536db7eabc54b3384d7f010097591e75470eb931b90d0a7bb708c1b5e97fca41b6161ab4c1cc9ab3cca4ef8804c76c45c44c4bfba29d978014e36195cfcb04ce7487994261638a779fc540b6d0286849b7cf51b8b648ad792bb225b42b637693f967c21758cdaa71134cc68d8bd7198b2a971071373f772f7044b912775652d1b78a9c18c7f00a86526b134aa656801b507714ab6a37fc57051df46a4ffc2899411eb6083df07a9e59c2c55d626d0bd04425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e0a1f9d9416e2b2ca22cb20f8f4ce3080aded2262d885780c9c4f171685b466a5db14bface3cfbd979895586a5f1a2bbb7626e567075c004b92301bb60b0e3208882329cb7de807a38656f98abd1a326ded150401035c816b9e7e677a29849caa7227d57b7969541e11f601526a15631c75f6e9be24d54773f906f394643ae31161898530344c07693c4edc042ae805b92157b6637722146f16f49297370a074962edca884a2cb091568e70e3a57ef2aff79b17ba6226b396a5702673704b01d7959c180513e0ab03a421425274ca53774557a8ba060817b62b8abb20596eaa16810513885435486bbb5fb83c7a9969ac593881173377b1b79ef4b7f20b0b6ea325826667fba3c4e31227cd858578bb771c27abed688844b95a4906c290596ec7b14dca4a60cf8bce7d12545833803351a0266384ddc2673048aa660b9a8db520d37ca59ea19cc6f19eb9e63d6e842076b397f5027ffee9672e91ba1bb50f0ce37410c686e9952d86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637e227c963029e7935814fa0b11c4b0e695aafbc75dc2e90d8c63740c8875601008b8959ff214b513d42056f78457b45e47285440306d15e3607a130a4d6b2bc0904c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382624c07c4f26fb449a412c37b73037131c81af9084eabc16b50956ed9daaee0f4153da0c959c40f78366867e11378d2bccae21762b543d8b2ce2d7ca79cb7ae2d06544982728a7a2ce39ab54df83521312d942c26f618ae5491bea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249fff5515b23187af5dac6d1d090bc7bc01df34ec781561e3d3b8b62164f749468026590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 3e361e9dcb35f7146321e7af1daca34ec0152cceb5775c9247c23eadf5b47059f1443b2231db821d0d66a1cc778842afb8175adb495fc6549044fb548fff25018c18bcf791ffc75c7a3ee1d5939fc226f3e992c8dce24c07642c28aae6dd8cf449085567b97d6687bc5227ff71e12630a8e1710211409b118a6973b485ba8bd7c8f9fafa7184d87d15fffb78bfb00f5cf7e3eba803ea7826f928102a57b197564f48b2e4aa47c020be5e1f389a56958c13e55062270e7988af908fafcd13d4f122ab6f99b3badf31d2c0d15f0bfd23b68b5db9ef1e278ef25521b2ff6716e7c2a45416f02e9e7b2c0ba1fe0b4cab08e0c89b3e69b384522a203c4e905a8917727be79b1991e80a372c38a9ae6a8026f60fae6f262a8277941c718e7d4dcc679cc6cc16555a5555c8385ab2845859f5281d42ca6dcb5121f18bc37de2e04d8c2f238edc456a94ad42ad9ef62c1e0bd1a0df361a59d2a26bd5cacedf7b9a0bb1844ec2aa12f81f693125c149058e5212cb1f2fd6787f3f7d228ae8f87fcc2a8777b39983563c40855dfd6fd8de65f17021c7f553eaafc49a526b8c1bc8ede4bcc4ca4f722e95ce80a192f3e52fc89874f6f0f4fb0f8a396a299c77ee476f2584b41222b42cb0f7a60ba335b65bbdc2c31e80e2fbbac369f2f97380c06c3bab9ab44db05353fee5a8a757718f3093fb1f431046508c2978dffbccb51a0ad9b82a72b793e524fffde51dab47b58a71e1b54d833a31e5a805a80a8404a0e18a60811a9a814da8f16c3f7ddf850cb9a98f5efbb3f26e3370e0b9c9f07bf696afbf35aea332c6879455c48f7a9aa9e44838fc7f4f997b0076e66e263b2dcbcc1cc4a884641b919dc7d502361bfb7cbaece1e944ca5cda40f3d0c1601c5a2514891590c6de08121695e2293a11d70f316b8b3b19059b782a87976163d687221d494de8f66c3f753b460f29abe5e56420118d464c33a955f41836988bdb067a5ba07926fd34d1886dca61324476a3e7c685b16886d077ec7192331b98b850723cd3c10fe294cfcb5e5e05039c5c1ec4ff2d8d0cc437b3c2e64a15cc867a7d6380567b5cf5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8416677d36d6e578c24f59b59138c6cc1e44c74ee541839bf89d66660e80799862d0049ff10ae4d1bfc1b52f7d2e673c9dfd9af164b7fe7ab10b29f8abaedf5f8e401a2dcbd4c8bae6b7efa3f783bf96e6a2eb7dbebca74ec94514c9a99a16b75d4ea059f437e7cc3febabaac79e8ac41b40f3b8bb298dd9e3cf9a4fa586ed94d0742b7c06bf52220f82f7959a73cfb9921ba415b5b2b89ed6d7c464e1bdec239d46d05abf7b7eebb49bd7835a461264c0bb57709078e2a70f535715d5af14d338445ea3ed72844445d01d50ffdc7f2a0ff9c66a4a402b98db0c497bcadecb68cd93b542e8bb6b40393d73e7ac52dd93c6ce5ef9d4a7a9dd5625acd6977ba75f4cbf5caa86f5568c423ce425eef3721ca0989fc16f948d7b84b758375e94be56466b8f030fc7bae3edecb489dc0cca1c0788888cdd57f3808e16634b16ed5aca96f96b96548f738775e271fbd5d64fd230293b39747e001bb8767f8d2f2a4fde26981eef6c68d542496a92f597eaa7438452073654de4cef1bfb6d48ddaa63e875bf63710f6ea59884d485f8877aafd444a7ef16c03dc780bb938f5fc94cecb5892beaf59c9a625e68b89e374b6d134c33aee68dbd5065953c851aa1e5458e151a3b49f47894e646311575691342553af7116399b3e441d85f4b9b9f3d616a4d9837b0540ec1467991fc8e49239fb5a7ecfe13e44a83265aff2aa03c6465ed2ceab178ebf0346aff84bc61e5cf3ebed525c4ab56a85a053469ae73bbcc77c28decbef70d7ede0d3cd7594b9b3dba6c186180ee5ec8d549530c3f7978ace489b4aacd864e175680a7c8bff43e7175b394af432126c945755979b36bf9bce0d816e50ba38281aec7299a64a085ca55b49cb723a9b0cae009965a0ec66a7e6341b2a5c89a2adae6a3a20993e9200bb0705fbe404890f7eb66e9367ef0a5a9305f6ea9e8b4406dbfd90d91b55f5185dff3565df3d7e698ec144d1acc6d1f194b73184268ad3b6bc43b43ad7bd9a5cac4388eb5af323c7f3152e6a4f617a0649c469b839b555cb56339e86e675b929c8dc4c83977c3f9682f7bb7f971df6d7ad49579412ac5007438690416fad3acf0bbb1642132613200006b4a502975fee79d2b7aaa8ae2745e16c0a666c8a3a24a990cc4646c8bd9e6744d6245fad4b2acc58b0001a7a351b61debc0cdf85b5b5a188d040d0994027f8131d9706aab35763e4aa232554cebd44886a70a7a846e67c3842e96a3df7233112271ba001105e2a35b5689378c108ef44f8ff858435b7fa1b1376f4c5276a4002732b81974c79ad23143d8134fbbb2426c9baf566b777803a354c5afe8a1b840ca5819a3d612752d047207181bb6c049f70656c22589d1fb5d5b9506f432b52dc933d0e816b180681d7743aca5259f92b8b2309286b680d174b267c5bb01e38224763a26db0b36520477591b0707b09e97ac78fa71e43154afd39266217067fb6271fb4c16c71e277a0ade710562ec287b7493e4fb453c098e5d991fda9abf9e9a29e7b28e0cabb4be5c8a3f490265f5cc93a0b3a52881ad806f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6c7053a48a5168934f0f2341bd263648291078554692815e1b69b1fa97031af13901c4a90546396af914f1dc6d09f58c4af89474ec34614535a6dac8d0301f67339baa610cd5d9c2ac832c54a55175567a5565c478cc5fde74bf2614c6815152e83a615de8ca9ed465a05507b9218ad6f7b9b2799e2ae040084287c19573ad0200c8e683d138ad4e8804eba5729aa81c1e1a9ad034a352c156e9ab635e849f65a37ecba8c0009843016266d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b461cdeb83b637196d757999523097a00920d0677ad5c23906a3fc9054f1a3176d5759d39a03e591bc10a7cc7e05397af2c0f60e84de24318423c0470b82acbe97f3a9889c2f45418ca28fdb092ac703a6a9bafdf6b0d05182dbf9a55dd3397de5a9b0d7c4950653652c035addb2ed3abbce4e755d2519e881266d28524c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c7811966b7e202395d4a46d81b0b3c2d3950fca0cdd208cf462b688919b79366381a11a6e195cf234cbf10724d4c3b9bdfb0816160215bc6d5102689a21af235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb9dc0d69094efe63d751e6f9c1e92d2107a7b45fabb820222d30b11595c351643b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = e1160ba40116fcb1db2135f7820ef78e5023cdbe18b2afc353d0e3c5a98cc7321e542834d83302a0184bfa1a51d1a9b349fd79a8ff843a2135977c50e31e62f4df200df07cd7d40da1c7aa3d7c53b3daf5faf39908af436aa4263f5eb995999961f2d33515219a1b20808039ac45babd25a0d652a13f29f0f86a50352de672935f1d90502a67458955eaf044d1ba388fe89e32671aa122ba382c8a605cf4301fed0065808b03ca94da42c2b074c790cccd18d1b0070873281277bef252b920102af4ae96f464b0c5ed1642322faf0a829a0d86839fcd9bac2db2857e2bd098d3d9efba9a87ea4baab180969c785886b20591dd0bb5083445c068b25cbfdc4ea472097fbc45964866545a54598575d0d61c57d1adf4156f87bdf9069d54ea0381627ee4987af624e3889de5db635bc2c40afb3e83259093e8d952e921d553ddf14b712bb63eb25c6e9673abe27a73d37f33563e55b353631f0f15cba393f7d2e0112063c76dd1da61bf6ea976cdbbcfae79236c28a06ae5453781d4f74d9756fcf021c4e26320d1ca9bbc435522271ddcfb9e2a3b84b2f309286f5936594f52fa8e3e4d4559953239172e7045e5eed928cd1832def8f5ffe577b78526f09e7077fed5a03f0b9f1fb5f56dc51b72eac7bcb2454610b384c974591021a6a2f78fa81436c3c8dc208181d5483f4491319021f3686e51ae5da60276ef5af30c53704ab3025469809d319509f052cc1c4c85c899480f7792d1b9802d1b386175d3aec998ed3aca1e265fb0481aac45b5f58a6f9841d6594295af4c98bd81bb912de6fb5e52ab71202c8280ff34bf4d1a7203d224601b9c7474f6c4b77f549676258109d277162614167382153a462f3bcf1c6437e24a1d02ea67cc7233147300d8ad361775112258bb8b0321ef1c98f694e1e3f86e1833c8d9726280afcc31aa802590421a544beec646706e8d66257f1047d3d98217c42b077815fd8c80d867662327f98fb7d59c3a3a56a8d2e934f963f40ff1e78871a8d059a744152e72e082f061b6a4ac657861af3e152be2107b942ac4e840c7d26e9183c9f8590104c4b3c962 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = eaebac1f43968fdc3e0f29dffe1e7773187bf7cced0978ad917b84f3cb8232e364456ca6575bd04f8831a5a7fd7fa38b90436a7a773a9fcc83b8dacbacfb57c33f3817ff6b659a66681e588ad7ccb4aecf7e5c4592684d78fc4b3053467c28943605774b039fac98bbc2fd7ae2fe92962bbac76ff6316bcc1dd5e8aea752963c5d282d30458b788036413895dda38c71cd8cb6455be3f9ac8aa4e5d81567d1ee1a64335e411825b6842ff25623be92f379017ed9b02cc9388fa3951465ff49a36918bf4aac8328268c9db387d7936ee37aa896b5dceed6be31a59d204e5e2d6d53fc9b8500597dbcb7a0d01bd11ad844e37b67e52c9d2684352cf837ce83fb7708386b3bbbdce3b5286f627baa846ce93b13b8bd665e43e6cc7680a864cbc59a64797a9897914a99ca40d4702d35c9c2dffe9804871e5cf45f1fbc5499c8bdff8ab37a6202f99b6bd3b64ac49c0ff74538bbe1eb7e94ba2f58fc2d78c27d5dd643b053a7f80696f5d21650ee2df248fe605b15eead06c00f37ef68dbced40e4f0026904256a4aed6d41b748e6146a59b06c7e2bba5782681e54e6abeeab61fd6dcc68c53a60e412bdd7a721ab1002cc2429aedd0b48c0e53325bf6cededf331df849a1939097a578add64352849afc2d70c68b596d4573d19d60013bbe3cb4a426e3b58414a108c37f5d06da1a66de9a7f63a013455257a24becb5863d7f7d7b6565a8781e33551cff6dcdb9caf3cdf841d97744e7ebfd3a3be97e62ef6570a1caa1a7afdecba83b010f42912b7986f7913c4e8fddde99b67ad15abcd3a70f76803efaa367bc4f886adf34a1f694a3066f711306d84b6737fd2889ff54e1606bfdf3a7cfaf6ac1bf7f6a0eff82ece479ab0ad3baec549fa98d0c6331c4ef6fe9c94d83277b4a08556ba8e3d4c6b0818e8fd17f44646631681f52e52cc5335aa32ebd9f37e8628f88e256e8e1e84b989dd9b6df174526c9c1fce39168bcf04599d8a09363eaa6ed019c9aeca9cd2cc6dfcb0c3190b4d1c0be39583b8c3629caf80432e71a7b657bc7ad2b37267d8bc5666be813674068a8079a8a4c57eb0ff98354342021507ce3543789ba78abe30d6241382c6292e084319a4aba75374c0f6617bb0a92ebb52e66d790b9106553d5c2931a9534801d37551d9e7a854b9733be2b0dc6b86390886a6330b159f96dd3339ca12a206c3278603a123ac0c1e8a982933b0b29b5671a291ae67c08c7945e71891eeef048dab9370a72865c0b47c2c5b90d134132bcc48d4bb6994b2d6e1567409467bb21868bf17eb4c23184fa9eda3bb6e2187d7e9b7d503a47ab1c2d0837ba25a108805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8a612402091349e0cc0d142e9e763adee2af2d998e8e686fcd76c03b069a558605f572b359fc4bc7b0346d11c1e6f9ad71d1399eb992b9e54268ea8ec5e9af804290a19732cdca883b5062fe1a878b1696eaa0340f071e2c9206d39284d6b2499bf0a7faf99f5f8a6b77499419dcbdeb6725e776a0335286234a84474c54f952b6ae075af4729a277381a94414e8e6ae2a9bcd2e01517b99b299f3aae1ac965c086e59bc6d32a02a26b911be148c7e48385777b841d917c34c8842c9c90ea431b2f8cd71a78a15f185f77cce76959ec1748c44e5aefb140e752c97c5aaab8e936e84b5c89b3080480a4b8be81fb46b12049c6bd67c74fb9095fd95c971a2c813f08b55d9c867aa61783896707a36fcfb175a64013b071447469e768a7a1ac43fb77649802522ff880e59b322f85b919b2424650914d529ac7a147586279f1206338a67c02109194eb493d4b9ce33bab709c333a91079a542bf0d717f1c875d54f11d7fe72abc346000452fbb9178b7c87fc437129797cf38467296889d3e225dca6068583921c9767050f51246900af6689227e709c91727bf41483915b93b3225454979c0ca7b3a2c63a0521a5679caf5c26d5944186f43463aa419b4a660f2414a535b9236868c2c091616fa6522bb859fa61503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1d700ac825c501c986ed28bedac0604b40a0b4f8990597681390b2656857ac712d7d4ab4ce85673fa69c404b0b5410a531f0a6258336d2bb639f9230c16c9a85e363f9c355f8f00fdf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f64816829a8aa9f8c4e949d4e6388448c2c4ec6a977f8c5fb80bd75d93a723bc9bbe76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = 689eab66cd05a44bbf065669766cc8b611ffc6f75f205ccf55a56218d4f9da959eb545f8c47260052b1c2047ba745c6b083d12acb0c482f0adba085e3aa1a536515dca67b8335b06951388dfc6313686eaa664a67d04a0ff60ed3c620b609b4039296304ea987174ca705a5189eab8b53477e3a53a621ba08a2590791514a86ab550aaa853a8e46f60b5ab159c65fe6eeff861dcf102d1b2f71f1862592ed0280ba4f3ac61f0e51525dae128cb664404e702c0fa543e047c55df151853f995a3b99b92bc5bdb77cd3bcbc63e509fdd0c7ec40dacfb878f4e84c4aa9154ced81e814c668834bc4067c11ed28a80a35a478cb72f13c2ce1d70ecf4827d00e3cee83d5dd0ff0b43489a2b7e5ee069b3c4f48ea4fd774f66cebcf5914156cd251ea48c3ad841b5c5531640cb4762c4dfd33bc1f1c3377797a93cdd5b07343a01865cf6953ec2c33c7e2c95044c5a95d1ea8ca2c6bf039c07bb91f64527ec5be6fab765bdfaec1066a95246d95a3a936ffef8f08523152e46ccfabc515b036fc8179481e8a3097b99168825b055e4a916ca8d839a3fa98fac30b1077f4dcc73cae3626e827d17cc50c84545ef759b40e084678aa13b6f7d58cb212c002c837a04cb00573c1d4795795e93e8dcacf317f378ca4f01847f93d5d5e09f880bde0840e471f38570d947f842c683fc851527988dec19024ed1d109c2dfb9220e1c80877174e50eda8f24a513b1fcf730d528064272b7a1c8fa7443a4e996b51a54a0fb90ae336a5085ad6d1310e285bd58011a50dc829d6826fdac4cfaf70508e261c8e85c56942b021c248f1cea0e4edb5548959f7c0d08c1ef04964f5e2bea6a195bddeecc418cf4be8ae7b37a86f4021161962c46ec2b5cff3857423ad8378e21eab4bc4f43be3b8ced7ed1d9a1adb19a0953eaa9f961898bfda24e6ee007ffa4214d00c661a96efd43faf78f2d2cda966839007fcae6c9ae5cf6df4e98460da6ffec2ae929e5ae47e3388d7008fb390118bdfadf37d1f72312279410d47b4f19cd7b607c7de9c3409514c37d137ae5dea9d137d2a85b19f0de7d8ed9f93f10b8497402 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c3aa38e05d8762bcae3295de91efcefa4d4bb34d5b1c83f2114cb440d5d7f27544a8e65bf08a4e19988feaf3ad91546e96afa690ca99f54a803794578edbc9b9b955784ac9b0e9f07487a2a86baf46bd4da2894fe35d8c06e49d2c487b87d9adf3f67ee5435f1655e0052974add5a270cff7b90dfadf7e4e9c39bcae3e8b220fa04d03c1bd27e9a97f79f589401ebf84dd8e89d48c897df69da478c5e57639699f9a387ec3ad8afad224db587fc091439eeb8d7a35e988b69c531c2b47a60dc71948804cbd9f683cf7dbb39f9bf7b53f47ce820f4fb375df32573d734964a4afe16fa538095eec8b035203f5564576334af9929ed78e8f6cb29c9b4f171a81c6a34dfd57c59c48d180b9b7f38538be8f834fa354d629544cbc659875b1d77b63579a8fa747c93059e27b45387bf6c08efb9442f7565a0eb71c888bb2074eb4c9ce945568d99351fd0a3acc3c54e70d436ba5558ba975816df5ed07444b9d34c30a9c13a8ad85eb4c7e0e42a2dcfe06584f37f843b103be4785694d3bfc4edd487e13df6155bbd535f6b0354848bf335223e2f5d7f5ab29d572554e357e83d1adf737b96583a87d5784f98d4a7b6c9f92eb8f30413ad6def3551b4481d314c6931c8012d43a3ebadd0df6cb87185b7be43e6ebb84449f960e8a65f5f691beea69bec55b24f374c42aea4966dc33296bedadb07a7854c658542a99e7c363f6a2aec458448b78df7c3c54dc727971b47677e45954fbf9d11e0da2f85b3e2cb972570ec97c8bf1bda481aa14d83576496a0da70dce35016ff1f6a4f0d0f884d46fe6559df21276d4cdac4100a74614d4b1206b6fe20a8ac07c31bfe686746fb5d2a67e6016ec8bac6620d93b07b87a5b04e11fd645321bab255ee8538eb934ad90686a8cccdb6a1705b07deb9e66ba4a116e7a93ab7cade5e047f5df4988c7011fa39c787dfdc3ab8cabe9fffdac4d8dfbd6a3e70f7ec5004e70b47b3609c5a9f2e8663ef78bc6ef7ee619f014af63f2fce72edc43516d6840393c9a87e999399e948b41ab273ea16e744e5ad8ac7550c14af65e9b82e684d63179811ce7f5132d943fec7c38a86bfa490bbb6b001c129707b1b765416401290a94dc8e2cab1503dc4cbb2a51bda96c5828397d406386353a75157b09f1776ed5347f3a32fe6b2599827f83ebacba251dedb3c3e514b7add849ac5c40e49b1297634fdb8a6c0d9748a8fc9e98778668bc4446c1444b104db4da7ae5fb5db088cd34017ea6926dd2128e9b39419cb13ef8511705844d4efcca1219453f987cd5d0b532c6b958b202938a90ce9016792035577a4b59ecbe063a8a158b92e89aad62ea507520bab2596ef18778590708dcc62bec78a74715ac69bab4521949e8c0bf914b5304a7384ad25e79c3244e581033841ee8628ad68842f320584068cdfd91467c1051d1a8ae77e4b418343743f0a64635ac313cb722f61d0a672645413e5e92853f06aab35a067eabbf6774a291945e9157255af4008a123a25778d57308328a983c0dc8b4f21c7dd34721db734967a706ffa75e0b052f67c36168ab46c485b1190a6ffb60f4eb739c232b2eef630a00469bd011bc1eacaa9ca60c613039439cfd4ecbef6d7523926ad88b8581e619b02a182b76993b26b3784799a7a314b38bb6a17529650c7a0a556c3dabb0fc44ab8eabc2af522207e90c7c7e113fb7220cac24f45dac26d1605a70c16d1f58b6f766c8d07c56f582c88f6402fcab763f996b164047daaa7cf5048eb51297c50c44d95a664583579f18639772325ca12fae19205742e72803fa4b9991517442be7cab72996ebc50018963f89a5af785c354f7a94241051c80bcd0d9c7f8b09ccad58c0ba22820e859c9a261c6d41a6c310b310a480d0c8950fe1383727b0863ab758b2c551bc99cbaa90f0365961f7727f639183fc652bc4a2782081dc69571b298affc7af09c349124601602bac8c79afeda8531423642ed20075a9b176a75d422740c0c20fa87aad22eccb98d4bfbbf52e7b590aceb660e3982ed3f3cd328cbb6103af5be626b5036ec8460ba1fb8df516b315e1267ba1bc5770402082bd1100ba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620ddb15151b9c67a9c57aa678e7e83b3ab4196b682f20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a90fe22b38a4fafc045cdbe0c9689745fb45760cb2f0f94f7d13cf8c834c4df3cfc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 8b51eb12e555fb46bf0e48c750b6d71a284850a56cd5af3922e92839761b1c085f2d9fbc83226098fdf6affdce428bdf900c8d89c03ab6c389558b3d5ba4075edf430243005829b960f7a87c862af0ac59e689900372e2388af25eb4f9756ac42d72222d4a0b0c351e7da086b4acfea8f4b1081d5b6ab7c8c5b37ce6e7615be7592489432dc253610c1d7896aa3a5e4d7399d82101a1e46677b4edaba777308a8cd9f1525341c9c19d1fb9347cbd98b207c5515d34995f4f2df14f2ae5212088806ee7ca587fc0d7b5a7412347a1cc41572aaafba04043dd593e7a957288c2192f08afd808b74d3fb89ad06a5e3a25d2c182c411a1c2c7fb3f2ecfa07b2c6de5319b9e309f4c3abfa2660b6f59e8db4815e9703eac99469eb78243d92b933f01a24e84443fe52cab14f7ae1febfb0e48ef7930983853dbd9d27f3ed7492fd9c53f20df28b5a327876f75ab1793be950aa007a6a87b8e79a58c6fff43a7c69901021c2bf124a4d22632a68b607f730695f36b014ef094f798091b3abb4da059dad519a80dba1b5afd3d601e4e00d258c6f4be3dd887c547c79f2e5917eacf44db086400e49fa6ccd86b8da13c34e267bfe5d5d247e37eaffbd960627875bd338d9c221b0f930afdddc811097b9c63dd5dc2d661f76954fe4ccc8b86eff95c5fefe71a2854c5b36b706711530a6ffd07e7777eb6bfc53f8ccbf3efd2a24f16bab09934bee06843dd4dced6d4a66bdbd651109193160c9cd363635ebd4079906a499670bfd09e0b360d0c6058be1ae86e305771c118dfaf9e128cf64b8422320b51ed1674bf5f4fe73b0d3072fa7669581a1ca9835564e3ac05621c1a652ee69d695f28d4fba47b2430867e2812b41ff7c3b3545857f01c12f07f6b243894be53b2f409cfe00d5b705727f6bb5973cc9a3f2bf6162a8cbd9d90fccc83f133b3fa15c1b49054147d9f691743ba4902c03eab57374ceb7f23bbefb436f2d5c659f3908071b65cea4b8f744d77ae9cac24df472bf55cf6a5f892d4daa048e1182e61b214cbe2746dcf12c24a64d36d3e01e90f595bd146555368928960db5e161cf4ce +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e2ac344c36b6a047ccf755bef0f455992cf623a76aef7988d1ad72d63d54d2df9c147881f65ab97f04d395b487687f91fa183831b9a67a9e81ef2872a935530024e87e7d6015aac1b22f567ec54af05361bcf384551c71b2468758786bf71f76a9db8a615442ce8db3253c862f6ef9088e68f23757b7489d98ac60bdfd4586ef9b623a44ee737344ffde30e7ad5e2dce6b0ee97d738b60374a02b45e6007eb1497d5c65ac34076ae4e49d235dee8edbd57ed3aaa432d7223aaf5461feb8ab5419fe79bb7e7b73fc38384437a5ad673cc9d3a55645d00ba659ced7b708367a66d65bd0ca8047b32583478719879869e7199b4445bdbc4cbade73c04e1d1e5e79b19bef6bd675155afd1fd603a446269e3487a68569cbaed72c6754b54ec000cdf34de7136a95b9a0d68df699ca7fe400105dac1b7c7bd8e6ca2548dc86d516d9bcfd0b6e670e9d93a9b70beba40dffcfb5d8d86adde64d67e38a253328ebdf84da9ae3353d03eece9333eb6cbd7a0ae0cc19b7f847ef7c01a95d209e3b6d579a5eaebb566bad01b6a7ec9cd817859932c9570c3adf14848c25f9c5676553bfe734cd12b747c88aa0a59bfb389a55aac4fb46ab932f7b4400978ff2a59e8e4af7fd3b04e9b8d6e0a8875764862ab6839844f020e4ab24ed03e876fc17bc469a5f3bc16af82a4e92116abc03a8b197852b31caccf0fdf5377e3b1699282598a4cb5bb89d56c6829c2df39c0f3494f521d7c53cb60d8483d6fc69ef06de4e9f9bd5aba5810bf5c855ae3aef7fd86bcd59cb7432f5e4f4d49c3bc2a583255988243c699e5f0d5e8daba6868eb9eec498df7412988cb4762ce9edfa1fe8d3977da5c249bae19b0caf653e7364a1b9557d7998e866f980e275a60b98912fe79377cd139a3350d6b8c09bce5086c378043e457fdad7e5de59f7d5d208e35d1f5613b7eb1c6355ab8799bca5daa490f60221436609dc1acec7ff81c87a1e7a051e3a14249b27a2c5c3d6e744d9b61e7355b26189197e44d5356aa2ccf35b599a3a577967e689d66c4aa966b9d0da431c77f7016a4fb4c0b9f1275888cc6a25eba38889de45ca83cb627b7477480002c1ac0ab41865cb5ad306b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda5835f8189a8f1829d09a379c059f3833e7af4593f6b5736f782215c72f8a30e60262dd776116ffb50746bbeb7565fd1a585dacc7c644c15f6647a25330e6e1301844652ccfb90d4d266e3544fdd7733b89b2326f0378d214b615ca423495cea4965fb586c00dc7243d423c1819be8b97a416293467a77ebb87bf724632657348f2a7b34aa256d0826fbe905267076c92262282291ea620b262355d067c6b882a64acb8aa6892cec15b3d66086a665054c40058c7a4714165a431a8c5021102cfb8168e4b80dd8b0c8d72cc8a07c064b83b5f1800b42aad50664cbe1b671d9373ff700cec873eb8a352081bf3fd9c9aec277cbd21eb8a4a2ec126f378b3b60004426a66f167154145b28770ba7b700b538863907961cf2271daab2118f2c40ac4989ab20a056b40c99a769b25c7a38d7b76a164964fb24a27880d7abc72e324a88a25466657c352486b9b17d4c13957d4b8ad26640c3a6223ad44be71535c3c258de440fb2a69f53e22103597aa8778127e971bb074b4dd704441c1bdb38274058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc5478475821b0fc7528d932874c47df5108f3e06106e18adde5a4e50d134c3648424630c42a20c0178bab98a67714c80922a3ddf431dc1a83a9a0c3087a45731177a22928551cca0e90bc229b95589259b9824a679a5a144c0cebd690620c12df2ab56c3a633ff6a1af01357b87108c4d56e6b694c41e153334b034d568f3880744059a214e80d3f477d67a332d44ba4cee7ab25d157b61416a81024dfc92f3650aa3e9c6f89a7629f347f91ec54b13997eda15bda0412df111529497284b312de5b4b0cc70bf0d2b643e5c2385133749243b678a026b415489c31d0b902f4dcc96981accc8abc5b08b9fadc35022b2cf5888d417b4a0a188d0a305d9ec820eaa4bb89c085f3655c0a2ab3962b069bb0a1ac6932c748cdc611b1949abe4a57b7af0c934c8c0696ba6f39c32f4e6874798bafeb70827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516c277a9588d9a781ddff6aa9ea8d259e5599d0adaba2f459598ebd5bc72786023ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = ffdfa5a0634e6dc6fbb03b34adddf3d909f04934883900e2322421fc88cbfde7c0b09abc772e4157bc04f15e0378e360c19ef33e7e05111136ad4d8c31de02694255b97bb83bb05a1015965b642d141a08d425141d4e870607b349257636bcb6a9a36e02751587595e40675deeb87a641c6a5a52cb60c1aac0717cf53f56c3f8bba3a1934021be629aed1cd07b55d5f4de711f7dd92e2ace7d2245f4fc15610d5383ffa40efd0e39b3e561329589d3e51f851ebcd218400f842c757cdd097f2cfc3c3c646459197745a47592b668feea0213863cffea5d2f0247b50359ea2ed2cc3191ec2e8b7c9ea9880fec929591c17d6a265d898090d752deb4aeb54edb85ecab0d4a5667b38dfa2dbf72837ec641188f33d236d9e54107d6f9c3aa56ec02ddb8fce07dd2e815b893e98d606e87959a34b09d184002d6643645021af942000296df0e15f277b20fd4f17f67b40732be99da749939052a6418d336698c95ac022e9268089d8f15dca44c21e50f789e895f6fba634fe07ebe733f67c320c7f20637a223500acdd080d889b783cdfb3efe600e420b0356d27898af7e4dafe5d84846f3e92fb365a14f254c2eaceb397bfb742cd22d2a114c6c702e2554b3930ad0719f6d07fc843f2e3ab2af7d7a22351ed0adecd8c4e5b3977f9f788e4b5a6dda8836e42c7c9c2a34f6f62079eb9f01513eb43c78a86a55af18d8fe5cb5df964c91dc1908f66e53900ae6e522b6c1b5329e4c285c28e8d76a478fa28576cf42252aa2cca95bd1187ffcae126c2b082441ee7555ccf13a4c665ee8990f2903a6c1a4377049dde70e391271aaa33d0642c160cbe18aae29988778f6af11ad497de92902dafbf5d2a672b2ecbea57dea1df787b048ffaf0eb195eef3cf9c2a06e6fd24d0e791e51affe06207775223d91f5b2c58e3c719ddeb217edd837ce27529f956bd33c874c7e0bc2b5f2d191887aafc62f02f1227e716a37498998fec0b9972f834c71acb00857a6ebefa33018c01fafee9d947241253fa24e3ae8a13149ab23edc8ef45245b48fd5029c3bfea79043f3ca64fcae32e5ef7463bc7b0a4d26 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ab994d6b166701339677e4b80275e4ef4e418f1a96b655b214c49e72d54652e8f134bd661767a55c7df03baa44f783ca79be4b4ba6d6895a937cc79095ccdf282862f86a7b5a5f36c3f440184d3b74148a00ab62a96dfefca5f2a746e81f1fd5806544e4b4c180366a565de9b078bbc6ddaba035fc1b447887ab6b08aa7f2beca0a783891d4a8ad90ef06c15f179534a9696d27bbce02f85cd0638fc79a7d4017ddac1acd1edd69c1f0a9e837ccb0bcadc517574dc97551236b844efb0c12985d544b88da34c7805388829effe8852b9d86418cbc02aa6e694e3491b886c3fe4c53535e5229d431213c9322dde108494f787c26c3a4d16e88ffe585e2b158f4e755322bd9f1dd770c14e51854daebe56f9dac3b7fcf89ea9a3edef8a62f51ac136234e498ff804da5570c4ee3f14ef74444d12efc6bf9fff0d98a6fc23b77f2baafdaeb8c738cd55e58e01bb33c75fc25efd81b8a471ba6bcb46ab9996b356088654e2886d7aabd597095873269486acef3f2e6963bfea8df9cd47cef8ca64cc592779552eddf74a4a51aa455eaadf353434b71ebc261f4a3564359d4d7c12af61f48579bba788a499a35cfc40cd7fc41a98bfcc8ad8037edead99f36547ae21f6adc75e5ed0739e3babf40e1ce9b3bd5e304d8f4673a7457e6dc9d5bcdaaf4389c6c2fed4eae57e6dac67a43e5fb2600fb434a9f9654abfb8e66c509c38bb4382c4b6f7b3cefbb6c6321da64344f9ec5f989df559b0714b879975431c0448e5878aa4bdc1532de49e88d8adfac69dd8abf11f3d114dde7a53806b7bcdd9743656cb3f8af63f61d7553d23d86d7e35251dc155e89096d879acf5916e79d46927a9afae556876d211f4d5fd0779672aab7355fae2948b44c67650636b1816c3fbdbc5858d59fefcc59f796b6d6841aa6982b6664a5b659d7e9a5cb3e9be1b5cf2828a76bbda57f7abd622d4fee96be76539fbd7873a0ea853fe46cdf63ee850bf30ef5f84f07888d08afde9d7a77d4dd6ab2e6b45bcec4298b2d04a5c536d96df3f9c9ea79d0df8e2b10ee99f3a686dce7c183f65f72466aafaf93af44463ceb01e0315240833d0f09adee4bbb29459f947897c4b882780c339019161e80b4699924a5c945c1a97c8eba4af258700126747a2800f81092649523dbc47ced32938a783461aa1bf6500f66b6e8307aabe7c4005209826a98a2904becd2853fbcabfc8c24489380bb4f7a1dba07473388508792ae1e7ca257b5c15c3771c92b9d07bc0b83c7e3371177985cb61b7bcd0083fea2075ddd321ce490a483a897cf6955384002be3016f6b9e2ddc5b8d5cb7c4f728e7966e13c04b310b7286021a5551a8b7e8472d969703f54ee4e1b1ae18cf1f6454e360c7ae481ec2b3b72d4049a74514eddb57f71b81b4405dbde79e05a1787dc2b19cf72a0a93b249b15fcc061e700c5325a40b880527f33b78eaf7370fdbb8eeb38e6c1585a12c160cdc7a43a7c45ea0b9bf18c5b5256b2fa2a25c1c29289a72f09560d54662af2c359dd87d9c599288541e36bc7313a4893abcb4ac8269c2829330d26b46cb666c821f49808c79eabc046b110c75a67ca59db9035b7061cdec3486a9b152856c360e021e3c25b4036259044347af18cbe495369dd5ba76ba917fb37d2314cf73607fb0c845463693060ab67785c1c6ba8efc581d21ec2a856ca54170190e61c8ad2c91b2a08791c1cd3ce29b080b342183cb5355b08d4a153c8a9b32bc4469d5557ab6ccc4a41d1f9b6efa405549e30022f64f62e665ab8934a617a4cab60567cb62dde7bd81fb69ee60a603c9138eea88d6823cfb3b6c0448c7d244ca70f5991618c3ff504734c98268f5770fec449ae6b4c47b563b9795a9d58f00b11206f4a26e6460af0531e1c07c54f1a61a86624a64a77019642082cd2cd8464e029e94085a8ab0352710c9f41c23ab47a53f2236387a381648036cb12f3f231624862f36084e1ed6b58309a03c50838a970ea14b76ca064756512b12e0acc6d4a548e63213c746877b4054c41ac3eb6eba4ca759223641613533c2382d53352fea4663d5a121759e97849e7166a50f139f04b2bf9609ab5dc238af2c0dd59ab31c6214c288b21b9b33a5c04845c6283ad0bc16285684d1cef0b11e8b324ab3d2616b71020993959815207b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02aed3c8cc315c4054d09deac08c6d5d364fd5d47a3c09041bee42c561f978e2d98fe1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = db7aae4d860aef5c9e6245e9d5536306065b0057d059c04494d80ac44d0c4e9f6788bb65c10735c22734929fe2d73ad97ca026ec83cfce550fbf3680ca63787e4a48866e162c620b3e2484292368f07bdf5abe38a0c2f548249c01feb4fdefb38d9e921fd87d5d91d3044ddfc2457fa5a81a975783ef8ff36e6bd0e450cf016693d4add665d91a476b01448899b959abb4698a22a79c1799443547327de7069f3ca56cdb964dcf245f302d63e5918ffb7fd31d5677396099b4d5b19b8e5491024947414cd58c682522b84ba8a03e506cff6c5391ea8a3aff70302d4f048fba296810cbd692948efb8377eca49ac6a47b15be7b26383d30824883474fa60ffea5bdcde813218182ee6ac82e0cd8b990fe449ee6ca3b42cb74654cb7f5a6d7bbcea81d0e8b01fd9fefb66e91ab7c5cdbb78a24063468e091b0c50f99880a7cf4a26a275f824e9a23287eadfbd4a425e7f6839a6e6033df2461cada26f9088da492648315dc3404bad8311f85589c59c193c6f1f0a8daaba797c0fcb9824f75a37a01c489d38df6a5962a80c0d4799f557503c3d64c6e5c763c3d9a132341893fcafb8d8ded3cb0bbb4f502d315b17446998c739968e5e1aae4ea917f0bd5750015d94122415ad932872e4123fe026e169578c95876efc592cc822122feaae5f1bb3aa1c665f95c5841e68e3556e1c8d85664b3e1da330eeb6e48dcfc4aa5d5499b246815da8067bd48fa69df4919de2248a77e5790c4813de37ba955b29ddc72cf90fc7daa869aa0fc530e76e6e4b95f71a3d3a1d6f36d416913f48dcd041b3a74252161b343f640463a1ae78b4905a66e71cf70ec285a947e1ea724d4a56347e793160d794df98c367f8a0ed44baa1cd63edaf7d7506806f384e73f438fceda2b88a76ae7dbd49334ccb189c1d95f758366628dde9d872aa8b70d6fba50e120bf08f3c9d276ac5d84a547bf9c16b7667e4277b6ba56ab75a5136c2d17bf3d6b568e050a63b0457fb168f0e6f375eb8b94b907101af14bbbd80321cc74456c9f7cc87a4e21e003c22a1c1e72abd47d484356b2c1fa20c3c7d1be232ae7bd5cbfc2 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4a9b766bfea70935b674049aca04a9c07848a40467f8ebd39ffa71aeb972758959837c5caa6c9a2cf4f1ea23b4afaf3f4ef4890a8576ad58d16af36c3854d7d016854bf3ec7adef0cf8f6aae237d33439db2f6f035d5c2b34c4b87d546b44fb66413ba1dbebe43b34d550c48cc74dc6b0c95fbe6427fdd86f7064a4d5dad6f0de23af7e30f23ca8ef57730c4817ba45732a79d5ee835bcbbc059e640787aa9eefe82d626fcdc0bb9b8abff9fdfcef4eb5fe0bca1a00fee2825710ddcfde2e44fcff46edffc7b31cbb42a367dc2e6899e1951a00df5f6d6416fbe939747f50d4a9eb0bbdcbfb94b71b3d0a648367d099288dafc703666f4c8ae5ca5dc5df6457a03f9420cd5f78334e2e8e39346e6ffecde36feeaf7f4455646a8a437552d5c3f5ec5852d37d4fb4da4bd6ba7ab65c048e4d27a78fe805fe2dbf890bdfc8a3d3ad0bb65ab906e6bc4f34e2aac8f46c83686e5cf7bb58a6a47ab634c361e3871a8b9344f46e835dffb244d71e44d34d7aac43149fc2c85c8a5d4b69ab7e1207be592e5ccc598c702f36a0339dc9728a5fd837f1679d9555e7d07e545bab88cc8a9e6fc6469bdfc4fa4a35b9db681f20fbfb9af4d9964e5636bfa5e3a4db3c937d9ae49ccb742c17ac55a0b62879a847fa97c60aae3b5aac012d5540a0efe98e440a97a33ff05f555c880df2cd5b784b4d2c63b8135997517f7a3ec390cfc658eaf62b89eb3cb08a7e977a3a584f77db9750a3de686385e5cfc74af95efdfb9bb0265ad678ca2e388f958a3f0f377f22e5db2e273f41f6b8860935004bc365c356ea396723ad53a8e367bb7e6cefd1ba24a2d557fe7e624a3a51717c1d17cc886467acd3d40329e7007abb151e9eab94cd6d15dc32ef97bb02676d96c43152aa3a1b63b26685abe966a8904e6cc9c92bccd5c770ef7c9197c230679340a95e62e96b4e8c3327c644cd430c52b32e2cb50eba3f9d03c851465323cb6cf09679df88ce5740c50cb3b4a5dded37e5461adc57d33138de0d4854e56e06e4b92f0fd3a5ccdb5f61dd1eebda15da8ae246b33a9135a59d3a0d5e7dc396b55f2a5dda7f788a2ccb58d9b00887179c1e007e9624913b9924878c5db1c9e46faaaba1a2944304ed64cbe6b96c3d61b83c404c498f1ba7eeb8000c8381de471a50957b64a94c4d42005831f4b4380899b5b848c307fc49654438ea062719b20796bc39b72c34fbd717bff95c687eb1ea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b360b3de0055742563a1db2782072fcfa86945f83f8e028f80e08825782b05960005f37992fcc126b9c942a7b2c7a230c30824325228c971335fc3609878509d302c8f1cb7ee3b4a9e58013e2377c1104cddb2cf9f969794f715cc805157ab62b9b52d7e273c2f6b74f8e142b8473ea9aab2ba3cb0e1791831b56dc7d6ac7a41482bf347a63ba6cc072201e19949e7baead45a49922bea808b0ae8000aa1794b4a92056a51ddfa0e90ac818940b57408b9282c0835b2be2aaa417ed6be7328926ebab1bffaa0c2360e60b905834a9db8390bc48026f1136d48c42587693ddc15556e4472daa04d8ffbce175bac214b28b73c0f4ca2a521820f7206ce7daa7491050937d5c3608b024a97993ad0156c9cbdfca0997893a7e412bc5d6b8956385e00d7cb61696a3e94a98230c4295394079ac7b1818f1c4601301850735690abea3ef9aaad82b16b30ec4f7612364fda0f78557249aa1302d94fb9792acd5914693729531ca3bcbc42b9b2bddc768803d2611f01b8589809f15506ab5c21ce5bb9404306026b74b1685706d09163a74ecc51684757a02a9b5fcf21a59c17c894135dbaa37e89229a90130aac7cba14513de24611fa77063f4aceb30a92d3f75c4dabcc5ea3280edbb0297b7b2b842cff286e442834624936a8461752693c335916210c3d6c1c54f9ec4ed60076b281534cd497ec113aab73027d918d6fca080ec48b70c9b6cc57ac527276ff4ba3aea74270c230ab058a135995d39438e5f52649b17be2e5ba1890bfb484805c82a912e9046eb9c2b563ba9fb48bdc9b95bb9276f3d906cca8c89439c8659ba84d672e283890c468cb33877aaff06af640a9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6dd1a07043fa0c6452500249601f25de742ab44213e2718cf0ddc5ff6a2a9aa6a9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = ca97e3afc9e4c923849b77753c240917a39b0c474cdbb1c0d41b9367b3adb4ece5e93ec993d12590298d3b978d2b934723fefe4424f84227b825b1f42e1058d9edfa9fde207392d3216949b0f6088beb7c48ad234d6110e71d02dd44abd2a4d02c7b6f899cce3a5291fcb997967f1a4e3ae433e06a18287b8f9bd441912cf1f7b2c2657eb409931eb1266c5869e284bb886c69de61bdfb468dbff4884d4356acb301ad704e2c6c3db8cc58b3c50315f95e52b7b460117a6fb301c86dd5633bd11cb5a3cc8873703e9caf40cf81b51151e924567a74c9005a33bfefcdfb3247c9454fe4b2ead383f414f747731448e76938ea83674162cabb5e50a7230b03aa795ea7fa76a9d09bbef1fe34ced18398343f3ae07b3f41ee4011f02f112814ccec044d141ccac71996fd42a625be32417319031fcc1b9ea402b76ebcc9289e887aef0bed9f18d732455bfd5ba0feedabdd31bc752782b47a930234e967fae43d7502ed1273c1582fddd81e20d618605f3c72d196b3e1b0d78d4191557d457f1452687d7f5790b3b4acd0b689ed5414b747b7452a17b07202677a5557efc2b346c5c66f5cd57de02c21e55aa0664e14f105d417cc4b4915b5dc00c12838f5d4d593b121f0f40e7a5939ec83f6722b5e0a48740d2d801b8c1fcc7a9f6bbfbebd470573cd5911730efe9a0a6e5fa66f401ddb8fc2c5bbea98f02914a6d0c55751f83d2945a09293e6f07c7483588cbe64e8d948b6c263f34ad8e8352534f97db7fed06704a6647015f6b8cd1c7e7a8a9eeb582da8de50336b7c3f18c8c75bfc1494cb5c296490262de97e3ef100aa559545d8182b0b4d619b7274298b7820e75df66a47074f9f4e40b835af1dc11b9ead78ba8c3339b98a29c64670895016d1a6cb294348bafcd380b292d7e9d28eb6bc83b6af0118fccb8e6bf2a14c1ad6fa666dbefdc3b5658761ccc6e960f7d08a9600d140a71b8ab47ea85ccbaf180a9b3fc478146c3435557adfe33af31faaffa7967a7dc888f72cc00b67fae7d9a3baac1a70a849d557a4790e1f64a2eefcb1b86baefeef4452527cf1368cb3db04c4d0ab14 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 07fe6b2689b409dbc0ceac88a1faf62a94b61a5e499ee4d0083d753f6ad104bf692f58cdc414c492439a3ae46b8c079be94958724c6d5a68535e6cd192cc3f6af8c601d8f80d76507234c5c284f235265316e53365d4e57b1d3d6f8bedf3f4910a965a1673e3154fc6e8b674f2fd78a0738f0549d6998e955604f5ecc665586ac388cd759ebbf4c09da06afc5eadc9cce95aa1f8de9e693bf11c2eb33f8587ccc7fa113fd85c5b62a38fc9d598db15754e08a7ef50b769b66ad3a73dac913dc06d24e8338c3ac98e5aa7acbbd9d7831715a05aa37fc5f7c6e4d9f6992e3a750c842ce37110aabb40f47489a8af4f0cbba9abaef23f944cf963d96d99db5a5987dc7a5ceaefe6adabf86bfb9d8ec3b2784d0de87f312cf98e63faf48db84be8d8d4b7ec4e234e2ae4689a33d38a83b704cebab677863bcc4de4f6ca1e8d57029fee25a8e8cf2d8948285e057382bbd8ac05b486e158fda8bfabe396a7c6d6e36dfabbd51e7fd9877f7528828647f5bc8b3bde43fc1e34fd2ff5f3fe2b951ad3d03bd9d417376f10cf7134cdad082399afd9f72394bb34387ef1c3f936d3cd0ac599c75ad3e7bfc20f95710e3f816c043d34fe3110aa7a79d885b61f42ecce8add296267f777960d455019c9c3799c9dcd50b85595ebac465bbdec7bbbd95b68c4b7146822a4f5e60c9e708c3332d3ea11e5b1b63fffc35bf8a4c4331e8aee718e927218ba30c9a26dfc7369e336e7ca5e32c83d63a7d817f85b0025ccc65789143961f3bdf9d87773b82e41a307f9c18592bc447d6b0d56e214b47e53fc54943b10caf5a37eb768a7e1fe145e11bb48dfa8f08b4bebfe059b30dcc17d63535ee7bc11d47a791a63b6c970e11bad8247ee510bdef938cfb3c957e19bcb885dac1f5c585e4b75554f9574aff12a3be6ee7848521549ed68c93e1ebc36fdc598c44eadecdf1018bc3de9bdfbac3d596630563e5ee32f3ab5efccdf78ad68256ad3259f0bcd44e0c96128c38ae7f76c1aaf9390844fa6a7d5278b7dbda8bea8de6337be58406dc09099c3faba7df1c99cc313f537d7bcd163328bef99115b82fc7bdf05192fbd776ea2338c7aa35efcc6a7d3281c50e1521186b785d020868b5052a10288321f363986f6dc5d28033d8e0553d9768241734561416fb1f8cbf623ccb3b74263492cc0d3c086b448073804e3a1aa93d5b1a22b9e02360297791c700a1ddb6880b9413840a828c06c4b5c69a4ae68a8069431f35b9174020e61758ee5eb6e337888bd563e1ff6c05cf568738c2683c50ba4713cab600c55b362f2a3a0907159a30a97054bab56655c273897d168cd41519a3db96c0128803342058e385c802aa7dcb60544921584821b491a4aff9155d2118bc9357bf6e78faee87606941a82129e6a401c15f41ab886b0c262a662c27e7deac9192cce0740ac47481744ca938b901cf83771946c6edec63cb99b1817f5ad4c4285e1ab6c0186463c3318a5a923cddac59a7991bf4279a1324671153def59af647aa7cd454d532a4ace3c01e040789d867d8230095df9c5ae64b1f470660a753cc56aaee948228e7b31e5d50217bc034f351fc1264512b58c6a206b5f844f881c0c833bc78df4c936c49247374590146763404441a4377a105431663394ca183f22789eb9bb96d73a0211b5db155a304584b3fc56ec2c7edf7235ac284021c5771d760edd4abd556800f61c65a263306ea81dac64321fd869e1a369a8594d9b219c26e754e1334269e4aac5fb0424d9c3faea7c0b384006ac250796a8d919ae8cf88d63f848b31c0269a58ffff9ce6f436ed877c33ee72efb5695f9e9c422dab87c6b92f3aaa3333688f5241cc996052f7a27387b6d8cca70fd1273b6473d0501b4155719dbbc464747702de4b45d3c4f0e3a8fb4826752f3bfbaa08f97804f021acdc37887f69060afbc3bebf3818bd064c4fc04cc35658c60be55dab57aa810c98ca49b790871f1a5bcf235192646c8e7b84a24185bc6c4b679586e6c9002e0767aa47b8b23905ce0bceee95f84a1a529185a72a80a95d30bdd74b4a664a0c0864ef0a557938c8e02b92a5de767a27c14d4b4269e22b1e70a869767b1486513809b1b6ad0acf683963da5248296cf1c71295529c9889546b7519212742e86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715accf2a8cad42c743eb61aa338049ce917616899c803358541de1e58cbbdcf3c632871600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = 15d65ce4761f9b6294605daa078df2844415581b516941f7e0324ee9b9da5e209977921e082d18663bcffad0ef1bd0ef4e3de0f929865083d2644abb88a9adc869a65d6feff6a71161b6e5339795cea275ad40909bf7c5a443294a854c63c98924e1f41b0b1936b8ef3747b5c5345cb4fc84422f7058d3f2faaafd18597c9667a3563604f732d3610daae54d9a015aa0c8b86f6cef4476afb389d0b0c0584df617f60c64204ce0fea4732d7465a8e56f5e734785f71b5076521abbf6adaf2a91a064d3f1e0e0cdbe4366435fc4eed4a63be380febbb2865040919abcf06707e18830db6338790f2930b7d941365349d93606796a2eb85a83abafc4b1fbf610f948f0f941be153e0bc91938dd4fd9277bd2db0f53550f2925af336e037266ddd6975cb14fe752a468a5188509dfe54384715556f24d0db3d8d56d13011c58429473df2fc305c03d2a92088e7936946170d6c35d9c7d4139686919af847e2e4073e981644af3889df5cbe922c96a8627b15645d1908678a561d9ce0c7fdd2c1c4f9a02c22461301bce73ae43dc2456cad2bbfc0b45b8a73dab6bf0e59a29c362af6c89f3972b55791472d446f52f7b6b905708fbfd3a5cd59366876f6f94d59cd1e9a009acbc3369123eb11722acfb0c586e9844d397f9e55448834318e051dc69db03a58fac094a641717f3d12eda91354397bd8892a99abd8b241bd4ae09f0d84f8cdf23db8992576596533b3859113bcba8dc9f904f4455aa041877cfedcd950853d672f4d5fb041f30ae623b4a5a1b03f584e115a36f3b94924bbba2bc5a9f4510111c1b2bee8610b578bbcedff2f1e34c7f10026dde18bbca59645dcc586170d3e0c18d33a008263cac232f96a12da8c41a811b8ff8dc3fe13cae77718c079f929b20907c78afe647baa5b1d6690be1379bf03f27bf605053d371a660eeb7bd2c4ac84220df35737baf07a81cc1c1e2d7a3cfba06da738956ffe77c3d456b6116cd048f2d7d2f491a285ee367a3c36bcd1b57cf0469611e91a0cb0b59b7ca6983c74486e77a65d3cd35901a1097104e32d3a8bcfe812cbc41dcf48369aee4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 64a73e931e50eec8c44dc94084ab4ac7aaac99ecf9807b922fadfbe8c66b103543a6644cb437b47938e5f92582746d743635717d05b9b39c6247b5ece88e30849ce963b7b7508be2aabbf7ec848f2953c4282e34c29c371d9ed6ede9d4a99c84a7d3322c55c1e44677169d6dc67dd40694d2a93e79cc2c578fccd4ec2a976dfabc44e3aacc4f9ada29eca27857376a70b535b1d5c56ba0387cb72b9b46b537c1ec436e27a5efdf82b4e7b86443842ce8dbe21eea9ecac84126bb50da5534d48cc9feae0253c2046fdf230c8c475ce0726ff5cd66a0bb13ec7cf4bc059bb69b9b6ec4ef6406396cafcad7de5ac445e6d22903dd11ff437bf37af06f32a66c9d989b52f83441f046871b98cca4ac756ee8a8d8ab42b6864a3674b8917e3ce2f85e5befe6427fb8b8da616f0d8149edca639390df9acf29d8f9d39cb6e7dbf01d0755819b90ccafce8d18b4c81cd65e8a6f843fd208d4def1d7784f589dba6ed3c0effd09d93b62cc90a4ae61ba198fd2dd8744aaff3dd634aa8af99d0fb724286556dee9cc474c56ce752796b40885c99d3f63589eaa794479fc6a4a989babb20b97393d624418db9b2f399145a54b1f6d3187dc9096b626b6eae9394db957711d7a38ce2ae7b0f57e6b395f21c3be469da6a469f3130597939765d814f72a1c3fdc18f810c5fe5af8e31157bfee994cab96db185dfd40efbff426f218396c7b6d7bf526b346f45922d6753983a8832b7a99aa7ea4674464c33d55b6e72f46a6114497b1a8b1ef835df5eef03d96cef9e43da9e97c723587c608a8c3df4ad0194164c944d66e66450ca2085dbdf52caca265adb71bc5cc0673660ec63e6f67857e3c4a575833e5d29a19a9997c45d4649e3ea4f94606edc5e3f15de5b9b77f3d4bdb44f9b9848d4ecd3dfba38f7e927fc4e75a7635738487c7fb5447cfc92e7d810ec9a82797e215fc630e4b9a2dda4df5d6c06c46a60557c20bef6a1d734171e962240ff798055700174b128f41b0063c13559cd149ae7f34b6680cb4a3e8854b13dbdac739bb6d65340ea8ff4b63357646cbdd3d7b2a303254ed08fa53653baddf624bf2996f55293fe31b0704145a4a92534116109e3c0b8f904db4dc70f4ac96c1572248640d73dbb88db3861d108d368b30086cbc72ab177e1bc48431afdf3208df342ddf802787e385d5344e02c49192d105ac0c78c95253ab90cefd870fde5c5315821ddbe82cc1c267bb797492409603c8536640285d396a53c61632e227ae209622725e4cdc5768e96bf3f42e81b6afe853c7fc8381b4aa6070f2371e00619d685973dac323a1513200ac6826b6bfeb9c053508160700ef6238efc37bd5ac12ed744714b45db77ca4fb998745a6012ee042142cc29f9161c72c86f7cb7e834749e647a30a078de01311d908add39b062018bbc81c96b74aa702d4a40e7a596a9720b08496d2f3a990337a1a4396c291c390e1c4cd685dc9a635e7c69f7ca82eebe24356200268c118410706983a49134c2d96365fba38b992967de41ba6a91640857c020ed955a1228e5a44c91eac6a3a6710457baa88d4bf072c32d458b333345f9f6cba68e9a4086516f0641bb311c72d72ca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74b60886a19df5ab7d2f2a8390e44491901dc2b58d327453ae306530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4b81709da8191e2a2201c9e6fb973f7142622fc95d9876d4cd893a8f27db619515b476a1560949db5a893a675e0259e98625f46aa41fb0a4436410591470025305a01fac275d8cae99a5e06561c94e01262c8b878081852d86ad4270bee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912a50c08d17254788b0264933215c74c9ca4de4262ef880571078ec2695f80277e934208c8cac7528205ab523ac08cb8d29a314242606677a8b18616f9a3ae1b4856537831cca23447718edbb056f8f9b746f14d3b466a1c4419c3c155df08960047524a7b39ec3c5778837f0ecb8f49d03204ba6a41710b07f8589667c769b26a66472ab8217c19f2b3037929f8364c09821e80bb1b5b1c2d0078692fb01a9448cd60a59db56cb96b5694fc7b7abb48a23b8a12ff327a5419342577c19d30b0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd3394e8401245fd6348bfa697f6990b6671577ec7b35a45b0101730a8019426430e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = 583d94dd417b8f213c5ed3218bcada4238e632f9705b422680163c81c972f35d447bee75f03b29c364001f44b20f7a18ca86c369df7ce42253e26875c878e4fad2621a033df9635cc8858bbe773608962bcf1215841bcde2eaa7ade1de9fe76810b3487803485b5afba5c4efba4c5ebed878be42b46cacabcfad286ae5c94efad920ab525d5f391f7b0389fe9e24a30c94a0408f6af2fd2ccc0a36c7282a6068616bab9f05ab72c23c25fb5e513a694d0cc1e7a590d2a4e4c2970dd7aa8b48a0042779e1be2415e3f711550e2f02144869c3e57bb3653044736f40fa5c990b1a075c58d30d98e3af49424c7fd72768e029b04f06c4aa7f78426ef953c910cde469c6a9da510f32de2543710a54efcabf758ea0bb53815a6cfaf0cd64feb643de1a60d95969c20673785bfef17a84297afc872779c9a8ef94c63a6d388adf7e02b8cca1be32aae50e6af16cac23aa3aac347e2ee2c43f241191c87cc45abdb535505f66c2a329751d81496ab9f5e9c1baa949f414168957d39808277e6053dffa3d1c705fec93a5110740eba84dd5dce5c8c619be9fdbb1809932ab141b6d7c8bb22322256f25ef6da180701c9d09215dd4da7e755316a0ec3de523e9191352baeb100e0f42a60d495e00e7341eea2cf819f2f42ae1b12e469821d8bdd7f88c820e0372f86af8d89df5d43dd63ae36bcbc0a42e897b2643ded9312143ba5a0c01076274b216737073fbcaf52d9bf8df7440a428242d126c22b00a407dc5e5ace18f18dbb73fdfd4ea7fc4838f7e4d019a58d76b0990ab47ca380551f25a2deb87147ad5880b802a9dc39d614adc2dc6bf35a426ef3a7e1e54c956b061b266b574eb900a1559c8aee07797f9a084b94c1302ef963692fb365168fe0086695cf7aef879e7b5e78d48901213f4794ef8a732fbb5ad836c6b057ca07362886b8b6abff739700ef7e7d6adf53fc2be6f621cc457bf744694f5f7c320a066d0df27e556c695c4433d480a559cea09a5d5d3c34cad6e35e4cae6c7740eee1c09d5d8fe3cb8bc9ccb80b0f2189fbd39454e0f9493932506028cddb42b41fdfdf958f1983f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 631c3a29ac6b4acbaa585fe0bfaddd2104d3a46653aa3eb8d56e8b3d366d35a7628fdb3e25bb8ff1da8c597fb0c75e53d23a724b9e8e1a63b2ac4c43fce7a43067fe9ab5a39c4bb5249a7fb723701bdb9f90addee363c8c5a5d1facfc46c6fc4f5fa3b17198b990f33ad7eaefdf632a298d0bc147fe4dbbed75930aec8d23a43f8834ec373d9ad4e7be4d419fe834a8443344744069592af47cde4ad5eaa4a03c4c9a12799e08b73d86fa8babeb8e7dc6ef07deb3825c39abd47955bafefeee2461fc7258f511117630d5567fb9bdd2abd9978938dca053e5306bd8f8950e5ce62060734e0a79290878376b7c76b9beeff6ceaa31aefbde6e21dd65bde5fe6b97f7b5cb3cca586d35f6fb673dbfd95db9dc63f955a98b4d90b62b54bf2a2a65aae25c08607c1807f7da47385da4bac7d6857ff697c22235951bd63773a6f15734d1085a24a1ae104ee9aac5399608ac8bad386eef981ff68d7d26ceee539ec1786fed0d637dfc8fe186893b86637404952878adb8c8545a52ca481358f5033a90c55d76b366f026761621945a3dacaec577314cdce420aa932d964000aa2c415fe4909dd62b6ffb2d377f76355ada6ebd8ea7f24b7fcafffebd8d4aa037b7c9884af59f5d360cd31a053ad276ccc8863cf31bddfd0065770c3995ad637159d56d5dcaa2d63496945fcb0daae78e3d59717f92744a513493d14af83840dd3b59f8eaa0bfa41765927259b43e36334f7bedcfa39f32f92f734b478f96ccefbc5de2eb58587dc3fda67337348741d80b48762b30fe4c3a85dc3e8e0b46d745f65f7867586744b46ef068102dbe6b0b49c6139c9dc6bb5aaa686375fb358ea322facc239afea0b5650a8c7709d6b95081b4efde4ff4777d1d2c65633795bcb48d55f845f3f788c8bf73dc84364bd1aa343d3d6c9a548809ce0e31840cd889c0ea8eed9b3c118e93b1bdc99212788391a53307e6fde86c5bbb3dd8b23abd028c5b788c3d23a824c86667fbbf804f7e48e8a312c357963db7cbd8b92efc45aeb43404fe78f265f9b5aa3b64d1bd73a46c1d388484336eae396b1901c730ae4c22ce79a65a217f49001f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e0a1688182f35446c1e972a2f923c66d2c15bd0534d0b2f418c50e0d81bf309a002c100c55040c6e6b5433a5d47d2bdcbe84823c939c3f76a681982075c90c4c712d1399a0d82c6cf713e5fb28d0ee6368cd4a708508de1530ee89cc53e8b7df748b91ae45bf2a849748a3a54695b3453975082a39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680aff2a80c4c1a07647fc5e8b87b59c8bf97c235f0a56ce2a1b7608d6445b907f4b261dc55cca76a85dc8400895b4a4c03e7e65675f5479fb4cb535240fecc628c180337635af6ac6366c8a778d84980ba659f8482785b5b6fbb1a265a99012a41d5d13cfe07c7bd82cddcc98449d0a2663a468fe9591b0450707a95538bb1c22393f7813e68719a2c11ad8e311402885a54588bfc47c9fab18218bc49c87397be532c0127302089ceaa97102bb2cb219901ebabc69ad1764bb6cb5e7553810b923be76796406994587bd8a0c4216662651b2e8787bfb6b15b98e26481559cd3002c2a03bf0d53467de01bde0bac05e968ae266678bc6945c182d1d66018cc7762ecbb10012208c3cbf3d7671a98388a30b990a4674a8b7c6f958eab221d3e58579e521922abc0b0879b825c9d64791671fc6fe752bf49f87b606580d62c8a17d85a927976daa50ee54a0d186c6c48f61f6955b8afaa1fbc805a53e22ff192161d2850093816d7235d134623d3d4bf20479aef39699426642ac1c084ac43d8657559f817ebb31901f2ac308421a0ea975a4023221080b786049c89a6c451ac076a80e87192d8d8b19a6083b689b128f90afe044d16663fd2ba1ed717c17d5c06ced28446c88f30dc8d89db3d5c531f6d6b63d5d535ffe2671a625d97254223f68e89279198296db0c0917dc338b1b5b33e60210457970aa2c2caca854b07937ae6cca428b8c4dc96029c57ec309ae6e306b077aa1d8baf3df17110207b73d056550aa7ef171b4eab2e8f7990429141c7c518299733b734cfff884aaad95e55b4a65776256d5540a057baa7450574f1266a3091d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219ec9c0d68c84cf3804f14e8daffdd1e28c28d3d55ee782c98c498b0d9bd4ebb2350a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = 6e4059a833118a1b89450531c1c5a9523539a64deb37910815554057f870927dde17a903e3a41ca3a2ba75372a78584ef2cc03fe630ea5f77586e76876ea1f48a1b2478198de60933beebf57158c64de5ba3cd14cbbe35c368561d686cb264544569659cabd15db5b2448ff3231508df4ea379e84f83ac166b94343d3de5c0709d243bd507478fcf330aca5c795571b21320c042719765032621a37c38116c4ec7b0772067f7c0d54d49c9a2e50d42f96a348c034d5fd11011f1748a7b479dc5bea123a3f0d7495c5a5ef948512c3c61e53bd7d087d8c2d8a94575ab04974fe8e9d77bfd593ee0c0feec1f9f74f3ed6a5cf57880ab5699a460d3c19183744eda429010451c0c7a95d721f3ce32f36f2ab850a425c0936b909db7d709a7375cd6759204774d724febf578915417486dfa7fd654b31fe26f90c8d5d49a3199fcff707a5e39e2bd41518a0ce39724a541e142b2019295c70ec0911289116124480a178f1b0527d4eb6040dc862916b454b20104fc7d497b9e751a3832bccfce92e8ace8421988f9a177e4598f19df8348b187aee744ec623294c7efa0ba1684c100265c179e183fae81829621e062d7ceae2cb6891e1485d7f445f72e68846274e5befb9807b8f1c3461912e1f1f6986896015e7ec54c12f7c56f76de4c30aca932d9368023e929c338d504ef7c8c8110adfa29651508477b2c1e1b49eba441333342ff8322b632b5eb067cdda030ab061a5144edf85e0992ee48ea8c4a820367aabc482aeb184348fceea8d183cd029bff843f2aab52bb08092b55b06506cccf5c00530076b027475f6db5c12fbc171bebce17a6e1708f19924d1e06e192f48d36f8b87067121a6f0312750de6175b0f70c70ecc6c1651b237db6a520201a61c17874db3d4dc023e4138342498813bd08470cd834877bf1e92557f5d50f9b050539e6a3163b00c53c5340844643da03ab3884fa84de493e6754ee573bd49640d72aa1561ac29f4c6011824917dfc8b89bd4f8045939b5fb07cf6b06cfca0e9634d895a6bcddd6327c89e73f7c390f562ae5187fa72aea4ec737f3cf0969923d374 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d03f873eecc1c72e5a531348d32d60c1e95acd2ef8c1edaccc6c5f824a4f2405bcb008785a893962c65b330aadd6dfc0083f7ef6fab100e5fe0ebef60faed2d19353f39d37906ca08c76367bf669f8b5a4e608a65558a47dfde7616ff6640bc53376920edbe92187ba716842fd77d4609f8d5e0feed0fcef648c58e458a86c44dc0204654bf7788d05f6dc396ec739f05993de118ca3b38d4e2d7fed92bc8c7e0d445ab36c38faa84e0697a3af31d65dce17aa6d903b44e9bb9222244a251a7fb2a8bf5393989b2bff4b5897d2cb300d1fb1f763704b26a6b8eeaa5a13a59987c6d6398be33ce8f58fecc1d5f817be7037e5f6218a4ffbed4d1f2fb95e44b9d2efab3715d7095b6063ceb98db588b74557172ea5881993581be7e533b81cfea3154eed08cccd1d6af60c19b7355b68d2e5ab671cbcb5aa5538079fee1ffadcaaf5e49bf79e47316d634c7b3bef485391d2fff7b61355a399f1549ba88b2f8f66f5e5e2c3ed7677a13d254551646df15733c0f7420804782cffb520d6a5760b854749a0e17434c49348f13acf5033e1f1c48e3fbac0dfaa67af77699dbbc3494fc198d5668ff3bafbf6dabffb3e80a852f9bd83e128600a0d6a23975783f686593483c20d54c5a3c9fc8a655399da334f8b0e773a5db9a0bff58257d77baabc9930459d78ab7cdc39a8ed5d82a9bea66b864523acb1523fdf840f69548dd8ca87b9643e6a05df783d857d21b7d8edad7a702af82025a26b98e0087fa751acaaaac9890f4449bd1971e45a9f0bed697e43a27cf7bf4d6558382da63daac323e7ceebc6a8a98e9d985f409ec4f9e6b85adc2a719e5eeda5ecf4e50d3773deee58d849889638bf57bc2e6fab87a4b7837c474fce46a14c543e7a37b258c83f587ad39dedce56bfd8663db8e5a9197591b497e889cd84512aa2f624c717bdf023566e594e55b5a784a964b46ae67c978471db9d60844a3811bc67ea87a9878747202c689fef6109dcf2ae93ab25cd32b8b332d4cbecbd7fc166166c1dbbbbc7e7ddf1c49c2effc388e7817d56fafe9a342a3d5e19d9f9fc065819afc33057f3184b756e1b8a3ba66274e66d3990a19fd84badcb9816036919f23c61077d12d85eb2058bb4b3369a040c5e61573d70c590669f0d394135e30570dab863488a66c1744a165c2e31144ada7b351083890a3d10077f2e556d0271134fd78d570a2fed451572d4197dd90fa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a3c154728080f0e4b910310ce1c948007990df2108b4544354f92a1fa6685ac203c11a58eebb3523b47349fc2ccd19b33c522ddc60cb97671ad011c150a29b51249158d5a131d3583196c828912e7b15572db019904a548e0967c91a684f4965bb3b3e8c008bf8531f98286c005b27a01b7ab2c13ea2c50133c3431db1c66a0b83bb92302fd7948938b4e87c7ad2f430c6516872474185d804c3b8ca891b95f5d0893cf20b90635c84aa260a48aa7b9b3c14130d77e3994e952cf52843069a42a5c285db221d4f492e152c03a51270a35738f51aca012560f84a238da294f2a17bb36bcadac68baa40b110d78966f6bc77b8930bd708a74704549560fc59769399793c26253e67bf4acb629138c277f7826cc00bbdd61dd3b97c2f8277696387196950e1e53b3cf40164c32162416308761e72756c2dac0af7945dce06571a5bafc1968d25a6628b766bc99a5d43c219161ba16a20c5b2075a62d18710dab472550edd2229f8428717b58ddfaa67025c3e0ad97657b20d3be467db6752747961713971d5cbbe287937c12872d305a128f05a53e56b43292c7ce2c2a360381a8610f1a0cef2cba93359c06b3c74e9fb4165f187376a55fff7ab9fe872c9121008579a877099581458713a0683a9425d6072c6b813048649a9f5caa4c606c1ca2f79299feb0ac1b277cebdd82a2396a02b272b4ad196d457838a262be3918dd3db84d7d821ff3aca89450478e8c10997628f9ab23fdb0077997a8ed5b26773377f7a466a69ab4e10b2d93899c66c900fc585391805aee1677695cdbe264158816755f69515d1c3d76046d18c18e07300fff2bf6776cc7ee87000815ca4e83967bc37d366b9ccf74870a678cef2b13a7636d1d311dfd5a37aeb14a3c51c9087b00a2911caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eba9d7d5a52aa2dc226832f6e4603322f60b1dc21207e3360712f9c6445d37e64df072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 5ead2d871610c05553a64024ab82356e63260499ea33a44c47580c7d2fe200565a8ed1ec0f320f855a37b5e2bdf47015c18eff5356a9e172b47dd0adba7a263d73e013f1fe8919b9696b2f5be8bf3ebe97c3f348337892914434a2ed9250ea8c7c90b126cdb2f87d323a98f160c3fd829c086862e77225919f1bf1177cdd51df07906ccb277293163dee1cae366f625de9c534d798809515e0c53a34c3e961784c9b5b552f7d323be6f97e9d532ebd26a4e3169922ffbf39fe12d0e8f409ebe1b8fbf1a8489e32017e00cfab878f2418b1556415179b1377418b53f25c7bf4ad8d38ff83b4c476fc88e6736d4a5fcfa39921d1de65631542238abeab7302695c9776830766a73d0f815b03d832a10b2f2a76bb674b242684d158c658e0684268850b874cf0db2f774b5e6fced825fd369219284890ef92b0ce3bf649d1d897810ac8d17417dd54df3c884824b13a2b256fc363515a103aad47d3085ee1f52a71d4372ab3eff8cde8da2fa74d15af1a84a0eaa052a9fab407aec1f0060ec2bcd1eafa30f9b61c97ab1ab67e948f406d490c977221774198d084fbc626d190d45da4f2952f3191851f51cc0837f8f3274ff34deca842f32bc3fbd54790fc2451a1e8bc7579f631717e97c06be8d61ffbdf7d92bfbfbf52fb93690b5ce1ad3b13b6cd2843b31015597156741d0a15985910218f5912d88338f00ef7e21d42be8b188349e952dc9f1f0f3969806a962a1aed65c8ed0374f4e5d5ea53c99b753924882f072398585c79265c37ef4f19d59125e5639430b072e0b349ffa6911e8d1df2c44202f3aa24445e58296a50fd6c775026ee6b6cf820c26429808242dca5617b125b2ba693c3fbdd672739c7c620624428557ea4d0dea046aa554f1529ab014448a9b1b27207d6590944f5d83fd6cf71a1f8448879b200f764f47bda6f1b785b2976dff1a503e8a6c3e558062455bf3ab98139d2eb429a97da61357c7ca657ca14b681c88fbbf7ae541f493e7fa89eaa30d703cbbb86384f9c96d87848504bd8bd36d708a224b71cda1266b2fe7f68ae5115af37b1e59ae02167a2cd3e82a9c5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 9388ce90a3d382aba7453a3493f8780427f002e6c5595fc72e65dee10de9afb5d49adfd914e6575b0fe8cffcdc55e6f7e2a3d0419657a6575552e35f5d243535e36932aa98f2a64873ec6b72a6fa282df96b3a74f738f7b51a40f8dda2d8544b586695898ff3ee1bc71ebab89824fe1c4a412464526a7362b06fcab1f9bbce33444f43afbf0e6a0d67c6b65b7872f3c69de6dadb9443e0766005f4ced873a9a22cb99083a3b85785105eaf8c3571f18949ba3fb77eabd0863398355bc97ddd72056d6cf5eb80092abf1f4fae013e5c7abf797addc8350942dcc3ae5f0d86460e71ef17a0c48b3388afeb92dc8c61ddc364ab7110c59a40ef7b7004a7a1eedf24f66c58de5fed59f85b995e4d198d9fb9de46849130167239ff4aacfaa4419a627c3dc6c8185a5cd751313a55729b854c6ecc1ba940a0ab9db0bf41b308eb590c4903c54a43d790c30cef2176b26f4d375c29483a5e6d0de4615e16302c935824f6528becf2355ba9dfd77e3a0c6d8ac36011bcc760e6c04175c089dd607a7d9edf3570cc259b57ca85b505a5277a92a5d83f332747b497721d7d7b45bd471638966d63e9a79f8f501d396d29fab7eb340eda4ffa76f84d5a7e313e75bcddca26bf643a5571e8a74fc28f8656d737c47347ad2fd1260efe7e0ad7d74cfdfac4c38fe34d1a393907ecb44834c4988c7a5adf7b26c3f420e98724cd9fa9be9b730bcf672cb555e3c4c0aeac2baf876ef792b5577674eb7ec635c1b7afd17346bf5a34f79e0e8eccb9aa3e14d65a83d61e9ee5bc2d8277243709a37139058e30b8549b3cd0a64d93eade4096fe3a9f6bd8901d57217d96091bb32bf4b85fc3c088a7cd0db9c4301374aec9d7b0a73ae26df6e1addcce347f2f883223166aa9cde2e91b5c67e5dd421bab6a6ca88fc373a2943ec7f5e652ae3554d3dde64f48538d4def43b72868e85c48d40d6532e3df5b6a6970231fd0ad45f636b4ba3ea8466ad678bfa958472440d5e445c478d701abbef8ff612fbaf6bba87da1d8b8bb1a3568144a568c4b122f63a4b5f92bf3e7dbeed2ea5555ca2be9745ed40007808d68b38cc33e478b0946e4646e934c7bfaac517294c2a75357f1028b8c32e1314cd097471f15b35707a28951bfdc88590d464750a6c7b5b62c4218bf9c152e30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1ffc00e93475ac669be33808079b2b5e230f838a8b003d77b97672844639f8b7042ae6343f681fb1f77f3c11970ce715b8033ce11c9089c9b79e9470b9b64f4feba92067988297be29413c609a3e245866dc0079ac61a61ba1c90542ce965750f2b57a02d19f59719af9191e62a1b64579bc6bc5b1b353a050d913eb8117c525b8e2a417743c9eb8e589776b885c465e4d02a51ed7072d69c8912ab6493bba5fd186836623dd635d8121ac8b97772b671d76d983c513a45e4068c6636f6f1c1b21647ed762a3fb31615e781134075dd3969366527922868605459a6202428c3b94497978429b7e1bd2384e1154bce5396f71ac49aca4c426cacd1c66c0a19918104e1e6ac72018bfb18019b9dcc75a020c14e35b3e7759487b089a45aab9773125f61455465c19a062ec90954429adca61a62d20114127312dd52903604f943ba8f3e0583341844500ccd7e06403a95328e02bd3ea6bf3b721c2049360930602611f5e9a06a795a4b1a8b8d8fa7845a12d1dd44d9d67971ad0ad0b3280b9f996d3770890582af9757360e7208c8b9766c8c673db52c22cb6e167191d11900df3b2190230f01437bdd8145ce232a1737eecab8b2ca1489d427ac74426dcd39e12a8b510a0b6eae269aa4a0f46724045792a27d7cc343459914a490a170ba0c27e1405639da5141673b8e9606cce509d353abef9b7c96c2249dad3320cd189060662c11069b36b1c75e561fc3a20631862a9b531c41683c30b7879e0c03c49b8e26c7bb59a2bf16950cb7c5eb326481a9161691859932c430e66c1d998a1be066648c569698285695c08d004586408360bb8954f195cc5198fbbe3c16a32c72ea0b577914f5590bf189833b9d38f27433d406a88876ba754d86f4d9bace1665f42092129995fdb3b790a89a2f1fcce9c2048b986c8bf16b5cfb5b4f3d21f4ae84b5057c1ad5922bf15209eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddfa7ba132b5dfa2e3ce67b64bc72d551f3290d428cfbd45ec026f44c8dc28334d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 3de423a447032c7491d31a02eff8be53b289e2e744f301b962ff2781fabf8d90df9f04874361f7fa7b3046de234606ab863f9bd2a63a4074846126b9de7fe2ea6ef048b9d5d3f79398d6aab2f308347291cb8749fb4b642bbb7b4008801c6d1a513ce97de8d674595f19fd4a0335509af86909990001f256bf72baf0c650d8338629d0819e558e7e2499118013ec2337ed91f71495183956e3b8727300b0a1317e9b277357bc761600aee930671e8475fec90fc6a978a2b83cb1e0546955cbe21c14c9ea83631989a52f42f823f955f3bcbaa3d62b72ce441dd6c7f666aaa1020838f7268b98f392bcacc9c7a97e629f9af67cc7bbf2b8df9225c835a5e177766d8bfe67205a90261360963809dcae2d9c847097d0b6a69f0e251814656d84add3d9d7bf54322eea86818526439b4f719721baa2c0568f9a60c7401789b96320140581f18eb326c42ddc63043a7f0c2f8988d7e87c4d85b20db82638e36117d019dc3768260cfd25501b22a3e9fe68085842d9ebe1c10b29d3e67200440e76cd014ecab987c7b587b939d63eca26f45156b88f22fb6e8ab60984a6d2687f9d835c981c86ab34f429bdfa617935e558bd717aac6855239f8c4bf550169acaab015efe104e3cd0c64642af9ef019a01ccd0cd4015317569cac48675370332e385a1a6ba218ded34e2d674e39af443bd79ebf8109af1ad9b06f3126c88bb0513caabe06495b6a618abbe3cf06daac2a629586c1e59380f682d181e92f6d2c025c29bbd9b63e867b5d899ea2843dd6b66342e023508e7cf667dca6ccffd4a2e79a4b30274a82bed3998a4a207782e39a5aa8728b5a226297945b2e8c3171d892a051f18f219e8b6af979e93664c886b925ba158834d82a75db6e4a330d77c8d92a7ac0b67c6cd71c94356c51a63f5d1c812410c3b45aba6466b9fe5043bd84ff80fe3d5cddaf52febf32bf2ec79f66bf1f7682c4371188ba89bf599561bd454d7322681a88988ff8dbe44ad08d420fe7251cfcc0623395f09203c6e3de22a429a51e0d89b9a20447e60ee8392810862f49775405f41dc919145dae208eac80486410 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5177b63a55465ddd9a42fc7c26cb338098df23a4e5c318be33e486582a40f3a685c16da916fad6b5dab029c73a5756ae52bcf99b26e51685611bfb5acb3465a69eb015bba901765d2d3ff22338c5de7944f17487d7bc7c444840b3c69aadaa3e8795f446b63d80e68e24dad2775baf036af4afdd4ed5a54193693006d3f6f814a7379aa41423f0ffdbe8e36f4e09ef7952e75d0aac6cb5bf7c9faa6851cd3579abf2947f832bbca68cb9e5009b8ec877548fb657a73bac7556aad1b6b773ff4393dae1eeb53d05d6996c26fd785bae9033a23e78ca224cb92a87d713e5e50cfb8fe67dcd25bfc43c2ca60c8ec3253f34beb6f5f4ad5cfd4346897eda7d46bbae25b14d2d72250cdd613f6cf33566fc44dd4ec8b1b04dc45858f8e87d9d415fd16cd5cef2b77f5c3b434053a5783a761c1357c77d6a4913e4d8d7c6aa4f89bb37b999739098da95d63b6b5053d36c7a554f148d511b9e190a7f10a3a5f268e002938f309f678fef8276443388bf8a0907641e4371643b9ee4d5a0c2c8b6a3bdec704f7fdaa3800108662408d6a8aeb4dfbaf4b58ec330af80a8d85727ed8f237cb390abf0ed5eacdd84f4d4c74f6c67bca4c6d46b44c16c54a059666ea12c5e68ab7c637d504385daa67538fcd470f1aef0bc93b900cef110a75e3ebe79c21be25f23967f2db32eeb9b2bfec9927b52834b89e42f95bf57428c2cb67c33ee81df6e122353187ce3ce249b56fa668ea4c599ea62c57c65b046d088fab236b3bb76d6daff1c547958f1252db3d42fb4771ae5ac136aa279918eadd3d337ad1b78cb5523903a5cb32b1dc17d9fdd6bab430bb3926ba34a11077ab834835fa78ebbb3b767cf5955e46cba68e8b6e7f9c474bf76eb706f93bf75fd46971aab7859be78a3a8bb67dcede984ed7fb5e53566161dd3cd9ef50e97774f273e639e88e324ec8be771a53a5ffa57e26b1898b36efbccad387823d4729c6807c3b450335658f3a41bb9e7967d9ff0cad2135a5c772d89b8e44deef53a281ae98c8f75d3bdddfbff7f14c93fc4e949d03561536b895daaccb745d6f95ad6d62f5d94e7c98e6bf6a764b9e7abb0be68520a095bca8946289731b5d068114acb1209507e9b20831bcdb2b2b6610c0031f89f6d408003ba57398b5d4bda4479134350994a8190cc1ec6b8ea0905cd38772789c9873a4cb6606e6a591410125786d7140778975c472077e42416d3223d69ac98320de4a1bb45761f04178fb63c92c71b24ff8056844455a45a37969b4231123483b341ff6652e7666ede163e9b614313012fcfdaca544b99cf922de994cf6de08799586bc5810c5c1c54882b935c52046921963865c0b82b5466e29eae6a62fb1792f4e1035308aa5ae81aaa524533ea7a000d7a128cb83bd0587138c73d66b17c585f7037be9c0089e6572f2f68c5ba09a532326419b3c19346267d8887dab82fb0176062f4c6e6707ec2ab7448215e895908d82cceaed528ba75114c7609e0b6b4e27b9b14bb8adaf0413d354f00d33409d5a185d1b95c58b7a86caf903c1de1ab16aa2054c13849edd469899780c34b8c423a27483abcf4c53b4bf2210f602aee904d2dd879054b69247b05f3b86f00a1113dfa29d47bb006a2b1fe8a540021541f412d307433ce71362f639fe39912fc0a6ae4a33ab4b07cedd1813d0009b784bdbb209a58d66ede34bbfb939c09abc80d6c71c550953494c99881a1f874791031a8ee2bc7760cbf75d82bee11668be002255b7a0309527d63bd3707a692bc3d3c927e0a406e852a7215c1850dc9aa9b17af5dc71fe9c57dd5dacb26f95478613c878b7694d74be742c282991dae15267cac6d2bd0b2d2c469bf391efd470a19d59a6db65710ac98905520c863927ec80bbee88513d70d009370d6b04af5ea49e6263d034228644307fb407c4617b8b7977c8f2c8bdab888940c2b1e157193830def0804d58b8f380316f60a3c26e27581d03351237cbf85ce4252c92c19c7a842201826cf698a074044b9b8132236ab6852718e09e033e009a1e8dbaa6ce98a81fa6371407fc2619e5aaccb94f1c8fa18236570abdbc217a0489be14aaecaba1c631b76c5a996d4bb842bbcce6798255d7365fed744865267da794cfa97ba6c7927474647a6c952a68954369297e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad29f8a01ba71d04d6831c03d1ff294fb58ef6f4041772cc071074829c32a3ac9d36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = 4e9dd9f50c039ff75f9b9340310a43a920849cf1e23cd46548010b2fd4ed0752687f956f9bffb4099d03366ab92117a49183512bdc028a781a1ecae340de7c87e6d8efd1eb994d91db17e15e52eb1160b287e5de0bd4aabc140d0b30910358846f520c6944f1a0ba6a57b23724218805d6dab6f0e828b3bf6090ef05d0eb7b93d18eccf19f2571ab467643107bcd2db2276ceb90df30df458e946c82fb960367e0b0a86838a4b155e0d5026e19bf43cef7826aa67302fcabc38899ff6226894aa4730a3a54886d7541e1d7c994cc31e097b3e32f7a1b3cd4c8d349088efb1bcbd60f029429bb686c1a01bfa80e53c6fedf2c462dc573d1f6ee97047a3f0c53ce4c6efd2c7980d8923e70e0b00eca1ee09408affd0b06d9aff7df0e0f81aabb1f1ea477ef2758738bf7cbd6a97cd52f543028b00f16c50b87ffe53d17de0590e6fef5f1ceb223a96ef5afd4bda3e699d28e3cefd84ae069d4a6e652124749ce3e0e3244c97f9844904a26ce6170b37427b4df556b36f31d63f83e400fe28d7a0a018c9ab23ad45802c8fcda36b2f22ca60c5ad3577255b98698412dd5c0e0fca267ebfd0875dba2ae286aec6d955cbb104f80837966a600ca019200e00380689c6cdae7f58fbba574e0a5f26fbaf302ec310c1a53488e2592b2b8d8077c3daaddefd9c73faa2de7f1c2be2896c3635846146df679216332050a3f6564f8861863a336970005312cf06c14c81ef3d9a8b9e53adc27662f25cf014bcf02dfd121a0d98cf7c7a988523f5b98c336dceaef7ff831c0c329d479a7fef21ebf1a6ee39ce801315a38e3722b970968799d72f9446aa0ca103c0d59466e9224e6d55227796bf641139b119d1e616bd811a6744b8f489e146e18f8ac6b18c44b6960aa2a4a0d63a38b107fae88840df3e2439bfee676ee690066d157556e763852a6d6f6ef9028aea80c356a5b4c615ff59ff04b9a06ee788cb3584d096719374da82131ab0960e7d2018ac0b14dd0c89e77a11b5d3df3d5a4a8a9c4da834060cda8130fd4a69ed6bde96209e88eb531578ad9a1ae9580fbd5f05354d1f569388d3427f789 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ae066433ff585d1d97a9495a937589eca954fe7bf7510a58bbfa35c166a0e697ccdd7a7a648a80e09a461ecc9a1e9b8d288c488c48cf86d9c893bfc4021cc4d5194ab3ea95ba7b73acc48568d9cb1c78fbcbc8bb93a8ccc19eb5fc07d7e0ce31af59e1a947bb851dfea9388f47e4a0ffbf6ab1ac35b66ebd574e512574647a4677e688610bf9a545f385f9b843a76952012379ac965a1afa8bbfae6c6f198a579a6733b4ddb36eb9aa449bd9e89fe72c85171b6f27f45e3c0c9664d7b0661a49b18b5180f760b4a99ebb1af866e7d825489ad817c4cdeddc303a58382fa6873e62626d7c1d6cab860ce36cda4e75576633c9e614846dfbb354825d8c9dad6625c49ba41aaf7aec38b49663870bcb0f43e2975ffcf1c8e6544bdbcc48d6ef1e3e23d4bdabfb5cdf173b22679de88ed71ebcc53913f27a836084db363d35efec19e296fb7556cbcce66fce55bf4554e7c6dc6aac7af699aef7b8deb5f465557e10dd7547f77d3ebc5a9a8ecf2cc7729e9aa22806fbf4a8bb656932fbeeadbc9fdb97ff7618dd41de7972ede451528d5a59a58e3ec57d03df7d0bf4481884e3fc886c04dd782a8592446a414a86de5fb384f64fcf0a99a57ae6e5bdae4044af52505a6956ec64a8a4603b34426d67a62abf78a9774e6873c8d688a3a5fbd690f459eca8d03274c01043ed73fb34596ce59819ef658d9b35bad5497b58cc5c5979cd95412bf558c88ba2ec75695dcc5107b06d2c6930caa0ca8a8ecec3d97c759364a9ffa5d964a80f369a1df4f82d39adf5883224b64966c1d98c87028e63b21aab404a697db5baf4ae626fbbc219ad4ea1f9f778bba36226e8265f57691691c5a3a11a5cee12a5bafefa8ca3d4bc2ee98fb09faccd73d1e3fa3143dc6f223767c12eff26cb7e90095f6b1e6898dac9528c64faab8a8f18f8d093d2ecdf794ef7ecbb57e7706fc19e9dd88e5df97977653a3bb7ee277ce13f4b9d163d2506b87268df4c6d971657cbe103f3a85ab5830599b4dcaca4b73584255f5fcba21e5b966197a5bf2e8149f7cabaadaf6536a528873a20cb8a393db84a67841aa9d74814e35722c4c5abc6ba118828263017d56e8fc3871b503a8517a0e3b8bd8192746e211a1a09923b761b20695f6a3ca01eb62e7f6b5302f54b8de33fe02b8fcf9c16e7c552977735139877c95bc69bc704fe94c0333115d7ea091fb41c146c07f487961c83b1b18225e91449c961769a7bb434a93da88531a75c207044a46623acb8342d59d1455dc434e2d2bfa5c30b9807789856b76d3a4c65d642fe65827eb7040290c21f2228e40251680aa7aa106a4e150d3226b030407d293929c20bb1afba5187b1c4a300749a323168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439c30850b68f20d860ba262c992c99c2bc37eee195d2e945c1d6336c990a77e9af68eb8932eb3325e362db5a77980274aa3b699be212db904e49e326fd445e48354b1609c0942735dc6480c53bca3c8857fcd90965f61d4de0509891272d31a51f3528fb17acaf669efc1032a4240f097118697842d79239b16313a6f74aba689aac94936a35a21331961397029a823d443244f49a445527b039ec8547c35e83fc2d076225d72b7634fabe64a103283434de705bba284fd2241a7e161435c896e899579caa2cba03c53ef74ba3cb30adb80b94bc407159a5d3b35f85b3ba3491c85b4379cf6472310335dcb0cff3006bbb5c8c37e3a1b758518d4c740ab5358cf8ab6cd92542a79a97dc4498734c8c9c36baaab29472a9cb633ce5d30039bb53b03978c51402fea962b70506642b5f6242345746abc312b6625a96443111a2c78d674a755554266c5089e23c9b63ea4b255890f577bc5a442066a2c448771629b542d2981093e49961f8a87a93c068e25167483872d378c2445f398796970c92b4b42aaaa65771382b53d8c79a0258cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d61a0614f1436e3623a77d38abcbb780059521ac7148c088a89b916a0103f477a15a68489d5f63cd7c84132aab6bc63a5dd30b8f27c835a738f1f619efb31509cc9205a4716b64a3cac7725b79c8c2d304ff4a60b328013fe6cb99d94496b363d03c1a278532780fca35473a000291d8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968357376de9843d74252466888727f9dc1ef48d028c0f52c902aa0dfc3de374c8375d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = 04770373466d1566c3feba571a52b23b743a851c40c59610cc7a6851bca9b83e69bda93360e0d900da2b5ffc34607b1d26bc75cfd8e2d5cb0fa77303b50ee9b0eb4bb55e262a937bc69fbf0a1c800a3d52cab542c63810e496122c11d8e2d2415221522ca95359638c57786f184d093d61e5a3f31bdad6a86aa7084b565a93d059216cb7901cd4705e3f14400e5d5e40a18140c032cdcd64691985bb9bf09ee6c9693a95a345cb405f792c2bd73f3adc17b004ee475cc5721aca4af6030c7fe9185998bcf0972bd6b5a940132c360604ac04ffa25104f9333feef6eb11a13b7c46f67332becb386f58db8714708653653044f40d01cf561997c98789570a9d882c77b5f8db73c366ff5207985326c92c12d8f02de5382f80e9be096206c5d9dad8c68c2d0a6a13dd4174cfc96b34d5fdda384a5e2eecbd4124af20e0a72a042596ba0d02eb199df52d087ae8bf18eb484d6d3b3994d9fc63185b7a5d3be0196c91c9b92957045eaa0192b95ea263d106028dbeba6f42d8465901eaa4ff42768c314deed73737d4a1eb21b511cf17626b92a75914140d820465320be487dd7d6be1399ea1576102b41531c2603173764931c98fdfc3a498f57d977f9e13339951d7f59406d532a46e4c76f185a17b3b3746d887db5341d5619b435543892ba2e68712b583fba2793c217fbf9e417616f4ab924f86d616cbc5d9ab0c303be54bbf0a080ce3f4549e94f55997e528318d9502d6af2cbc09c13227a39284166f258be87783d5c2f593fe956b16c24ba17728586b3cfb8632a057d683ed9cfbe8f19bf7fdea7d73b5fa3297ccdd538c9cf207efdd45a70758184fb8a43d0761e83141e0db44367529e3ac59dcc76d6c13bda70f56635d26a993f04eaba5e351ed12bf736f52608591fc2315cef1f618d31bf15361401045b38d66db05e700ee41ea1f17de9e1855bf965dc4e6a12eed15afe2ad30fee124db9a64eb3abc2c5057fe95e0ce5111042230f825179a751f65c8bfd6f6e3f04fb77dc98d62f75c72db05388f2d2b9b0cb63245cc0f29418736591b72ba1554ef99f5bd8a56fc5eaaff5f27 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 069ee5385970fe96403885f6e38bfc5fb6e4ee27b6e26efe3069c5363a4b48ca44a523714c37c15d6dae1785e823de4a18bba78a7bed6b36e4aab3a09d3e4308fd6ae7c3702f37ba999eb9cd7bbea86d98bc5d62b1356582167c13bdf529f884e05c5aa7bd54aea5a58e19429bd7a8fc9c5eb1ddaa59b54526884eb7b740bc2aba75adfedba3a5c1b530920feaf8daee79575aecb556c18f700b844691cd5fe079fff295367374dd96c7f889b3e7e04e58dc4475a6993c4feaa1718863eaabbc552ae1d56fa8e8e5f93bf666eeb3481ad8df7c4a3da11bf169ba6fd136e9bb96656cba731c53db22cf4d337a51fc4d88ea67e05037f28a5fcc79fad3e85c3e1304b1c7ec4e98acc486d4e1fe2cfd53a9f7d0c8f2646b8cac7c97190ececaed7625e5dcaa39e808c4e28dcebe98c73bd1bd3be97645e004811705e75e7eb5ac1eaf63bb3d759a899d2e76dd8f8736c5ddd8fe5ef58d578c6e9f3ba8a9e5ec8c24b472d4886f07c3a07c3b677635f96dfa9b64ca7d12e94cc9ee8631ca6bb80b820c8af29b6fb141d4fc3107d175ea73ac5b4d3de973d4e364dbcce3aefc9fe43c39be86ff0fec97fc07383697d9c426504eb7e285db774f6b56b96396b2a683939947898f67cb834347dc7f3346694e06c6b024c497b950048c96c1988643fd74a9b95aa60e8c504cc49ea659aca3e0c933af9326bf910bd7ddbaf1a8a3af4b3aabc608c6cf89c554386da97ab8eb9ca9bc98c9b1ecbe550a6a53cac0d7b7fbfd7bc9f81dbc6d24d197b465c57d94f3663f9d5d89175aaa8f23b3faf97a09c7afbb94c2e58baeab36b0cfbecf1957f0d54bb98b03c0eb1756b7c376560a7603c3d6af0ffb0989ec96e952f077bd305d40aa2b6e188a776aab653099df2e34c7ef89f777b4b07c4ca8a9ad71da13c9fe47b452bdd9e0a68eed9d37f8a6f7e7a979175b7f7479f15783c337dac91f55c575eff3223adb71dc4222a4716a69b3fc5533ca9842ba17adb23ba6e40d565f739fac07483ec53ef29f828fbee3199bca46ff8b558b963039d0ef97ff6a7972ad0f5eefba86801def40736eb41737f02f8a44d99657b40036ba1462e34b668715c8ca2a84b4c5b7e81d11e4acd7c6ae77a7a7e6193b5c8143a45b997dd291d3b08840cc4765b8b4f8c7caa7158f2b939cd273362c9302af3c59b2a08dd545ad119c0522fc60aee902f6a6b49778ba17a97a47b2018e14336cc1cbdf49b90698551059bca80506a4c8533d791bdaaaaa638571398ac85256740aaa5bf4bb35da6b3b6f514a7e364935e769137a300e9811355a9097492ce020aabbc0cfd8398792651f82b887b0d13c3e9c5632029a1670b3f8c8437b09a8cfd6b8482bad74347144661b0cf297fef2bf91ac607ec7b77ed308ac430abe56c69b668cd6201f329875f6454aeb73540e3c0f0816cd7f2b372daab8b3ec1718d362f97c5a05b35964707b4a7558ea1276fa837e4d90be1b19ae05cc7b948a32d1018f14844e1cc3b79fd631d8166d1fc072e538429ab1b09f8a0ac879143f514ed31931878191a0c203b5e69b30d40734904c1bd9ceead909136593b9c51402e5cf0917c3c9541cdfd95fa66018784ac144c610b4182a69a08cbd43cecbb8baeecca48de3ca5d21ce58a69a96ac65778cc9a5dacd663a632e63b1a4e71b012846f0c6c26b728902f64baeeb6718163cba1ac63447cad9d63eeae21855776dee780d1b6443753235f4330edc889094241930c27fac186f46428a60180d239008fcab21ad162f903a7a0984489f8a9d10840f2171734536b67a329174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9cc129e4bce6a519947d17caadc8f3caa6a5b10bf98a526ee0653af3b214b652dce4b3ff3d2c1ca4b3b2f751e3af095d4128b57c46c8a89a1de5b805ffb20d0300e6ae5c57f562fdf493562e1bb5ac0bdd35b8395889f6c7037ed636e56c1aa661289052952ebf386150bb03eda1616478a1dc43f50fb1edbb63968945e05d09d1d320b335433b701caef733a47bcb0e62bcec0e68cd6da26dde55c53d5a289284a7e6b1c239a092c0841c6e7a8292041a04b842bfc8f2430a632d55568a58282018d55876bc8e90bd1686b61d7ceba6b500ce628dce8a5dcd13cf76c81ffa1afe352c6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e30382cb59feee1b6b0fc129fecb8c74034da92987249bc20cc8ad4a2cfc1bfe0248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = 942678a054e276d2543728786e8254fecdbd37a6724521ef40252f1aa2de44973537ce77b212460e448798f197ce133d934f49e18c6a5647b4f846f41ac82045f37bcb1f0e62253c757d251ad3a138b012f7ec3fd7c88f22f8c723a553e371a37131f5ac50183ac462a03fba3b22bd9a0af9ff2eac360670c3991b63fcdbca7a3334817e13b05ab842879e682568d14b2080874aaaa07b77dad8f55703d6d78d49d0e293f59f58b0b8fbe2f29f46f33544687a8c66a2d30f66c0766efc4753ed53a816d04786b36562c001cc39b88e9c4ec4c86d3b09b1ab9a927f22254117777bf8d7236c47c35d0acf8f63f34468a6abfe8c213085e8cffe758065a9bf378a2b1e3fe30fb8c6cf35aad2a8743c53fcb067683d1f67b73a8b48d1cfaaf03755d55b7c3fea0e2617138c333834db6e48fa68332185de4d8a164832f51ccdea2ae602e9c04cdfaa5acbf14739367ad9788559424dde2c9ce5d9b2a1b63de89ad33afa0da0336ab877f2ea73c2f05582889a3fc60fb8fdeb3a5caf023d362e9756a9416b24f8b740e44277c717da14cf0b2c4084c3875b473729f5981928ed839c7d36e51f0b91f345d08b3c9ee1fbf88d638a40695c378cf3b75368b09c1a5ba13a3aace3a4b41774d20a6b766b2be0b086854b965b14a75704a6e0dfe6035c5bee41b89c1b6bcfe23696305ef9d1585678fb1456f3ca44d937cbc4ea7c2ecde196ea2912eed17113b510b63ab32d415ad08e2e0239b986ad9828f0c04993605ff677b17e8ab5925be654999135d33a627d79f108eb5d6be3704b032c1ab1df3de825795bafced52859a5b1a4e64c9bf783abd20a09d320541ae120caea755b793f0b112efdae0c47532f1182ac59f6243ce6b4330aab60c704a8649a24aff47aa1a651b338c6cc87b2d81fa75506202579d59e057ecda1d2efc5c8a4f1f29083dd3b85e7fac6b56dfae8a0e19fee07b3e54da6835cc290ecfc734b5fb9903403aeee16eaf8f61ee317394d39b91a4e3208c1fc50c4d8ea66a71bbbf5cd24e7ead5617bb905ab96cfb02f363b92891044f9ecbf2ea00e833bcd560b9e3dd095bf +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4844dbb266c646934c804f388385c1ba2cad8d25b57e17c1d728b767a592505a387a46722b75ff942afd430f62c188380aa638ca1ef6ba1def9a5ce93ecea7fb05e53e5fa9d94ca6f50444bad7aa8453fc18c3eb8b5dd03f393f0ad3346cd740c0637f88975f32db5b6dffa6c19f3993e680e4547aabade5c7559ccfcf823279519aecbcf13e4105084c63379d92244fc9839a0efb7790af8490999872933b0e2cc10309bfce6d70509b3a51cf92e46ce92f0e46becebbf664ba93953081ca46a1a5ae374955ac87ee29048e830569424affe9b3d703a9fbda37f57f33db924cb82a3780ba3a5efb0c60eccaaf64c5aa4f037d229342dab9d89fae508decec90ac72dbb68d2324ca91aa3f153a7f2a0fa5eb95a45ea88ad9ea4f6276957417e0399e7ca015463f0f52d339413119da419ef47c7bd38cf6a096dfa7d5bffe7af5f5535e343454fb4f9d8ec75d54a5ed8236b4a32f054b9598a1e2f48aa88a6b53f950abedc183a546ca44cb111974a9deb494ccca5f17697acdd8726cf7f233868717502285d95a09d3f9d9eefdba917a4aea7f5ac89f76df4c34a0d648614f8cc3dd9738af76c63a4c4b651e8baeaa72cf9ec4ee3ace9a847d17e996f91e9039198aca2bfc71bba11a2bbc05f6fb34dfb4f09a8de917bfd4687a151552fc4446eddafef386bec174d0e41864c19b9e2b6d3d5b1b756e3cbe5b19f327d39b0cb6b01daff24cacc6ccf5c4391e74ec99543514ecaa07552d55b8a2e8ab77e7f0be3e443b2c7ee7395a18d378e9e594edabc504e6c310b8617babd99a06f0e9adc727cd334f86eef85c609266c4eb56c12b8cce7257c0dd96a1390979ac076167f3441fe9edddb9e45a06e93ac5810eb56e2ff85fb9db4467ece1e70b99dfcdcf0083aa031ffbf2ad79d68d626fbfb654be8e49a64344dcf50ef9877d858f249cf6e42af8e5a5ff040572ff9dda5c8873194bc4430ab739d56529de332e14b78b56c480adb02fc7e9f05dd3a444c7a5ff6ff37da279f44e9ddec899187ceceea620386d53b35540b359a84656b8bb47bd8ef9833d9ccaf8be6d47f67c2e66a6f4fb945762aa4b7684d18022bb247f593d00f4956c728f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcc3269622355b436610412cfd92458cc5703fe2b01cb3a395927be19c8067a793bca615cea3c2ea55cf10c0cbdd94577331939e6b7332d849ac501750411223d143dc953d648152005a323df711009b81614a657487abd5476bd5d71827ca1b5ba45e9c268c6f826e9263adfd716cdb842d4f31b2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f0590b41661b3936950009c1423153c96351db064a794cb345e3c46abb00b061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345c524ba1a1345d052ae176bf16370dfbdbbeb906996eb41fad306a9153c0e8d98128a82231d73a878a8117529f8ff85be6cca6166cc5b0503134ab298c066c62260df091a15f598311815f3503965695586ba134847b3ada551b62072d03d468360150d0b17ceaf0a1496070778c7a75593acbab2baa4c888bb99d9ebaa34f8b02c27ac7ace0a15ca73905d9582b8137a223bca48b42ebf28d4360b01cd25d644a6f7e831e155928e971627c3c52a9b015e5d8a86a790ff785c653ca920151ab662c3fcbb18af3b9ca27f6c0cae82161eb940fd45555d71fa801bdcf418c5e9879fb33b675d5a27e5b45a4e2a20916c83a1bcedaabc0ac0666b4a2b403f05daea6906e773ee9eb3ff9441c06f86634f01d1c93788a08b76b15be95b296d407a9ea500d89b191c1c68b7d85763d1c2d2633277af163596a7ec257bdaae2a510b8282976bf25936a6e380a778939ee2b44bb1054669a2c5c06c77e712bf2a5b6aa405a1408b5fd2573ef231e2169c165727ee1a19b4c6343f2038537da304909c1cf81862e9676f1e26d7f48748488cd9ab64bbe3167b442719a304500d8c72128cbea470942289fc35c1fe32ccc07361bb1591e43e5a4f9076b7d416e5d2325fe0413a0a88984b048292758fcd080b5f5378d6c508927cfea478be3f68015b12cc1b05b47791ce7ca8c1a98cffea637807931a863b2cba011c8d8c35db81bbac79c5d05171be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2f4e474fd64a6d945e85eb4ee7509cc99fd4054de99f819fdbbb05c54ca6e36da1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = c2f9eac5b635499b944781e09115b12f434ce57cf24b2443d96d071090bc3c4375b9f427a1dbd55c3a0b7540799b311b1d7d64dafeadfd6c7e0418aa9ad342acf67aa6643c29edfabca90cefe4e7e73ed8aa7c73527b84fb149ae33ca1aa10c800add234cdfc458b8c7e98a3465d3290ab4d6b2c6c32a037de59b2261002f940d0150441d5316814b315a394ed4b22f9a8f05e323827e537e13a22739eb9a79ba72162d6858d791cb27429efa0794cc9b918d8a91b282ad9ab35a064ee1a064146a7b3737a31d24aaf2523c0cd4804e5215c4dcb008bbfb4a092013058460336b1db62cc1f7f5e66b7ab7e07a217bb8e2fe7d98adef0358e2abea21daa6d2951bd407cbe012c4c65f0103d9dfd76dbb2ae263b32200734e7217d5cb875f9f470283b777eab38d78e3afcf1b04a1b895986d409a11a7366262a4febdbc2c4009a0e19a311945f9eddb564f0c3b7a68fc0b3a874e45f5bdb30e0aa988143c389a8c8e83cd7028a79194628515c5c521f9b995051aa72a5f6952b6bd087a5e3b3094969e7e64038c895773702582ee8f4827a2ad5567c422ae0d2e155a6ff28c20a24edefad54f358b11a621b010a87beb347c49e8ef7f19c780396f0f13e4603b2920b5ed63d0d2e082bb8fe9d454deb9c9db4e481f8a5591512237c81a6f1ae56b63ce4b6e05c2c46a08ee685986a241431c84180896fb9336b3c62e2b9ec3e27d1d46d6cf28cf21b78fea500de3f77ab2b839abd4a2b1a71947795a0ec31053f4953a31e1759ad3428e6c3b3245b8c49054e237eb22840d0d4a26f540d1efa572cdc19d10f2f2425a05f0dd7f05db66667f9a784228134d50b509237e9422c2bc37b4e8701891028457b084e8e9e89e303d79b456625cedc9b227d693544dc1d26ccd1bb36ff51ae8ec6ce934a8d99c3d6c40e631e730bb993db83ed79fb1c1246a244da68dc093727f586dfc3e39373ad513ca0c1b29ceab5054e3657143c183727c8f06df9ae9059f3a8ad75d2517da7e8ab52e01eb486efc8e14bbd22eb9ccb92b5e839fd893fc74e257a85f56bbb8251144e6d9fb10e79e5e26362838e2d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e69f9843493c5cdce9f047539427cb993481145b7899259865758539be60c1ca72877688fac53f0d3d6237d572d4deeb6a1bd5f5f46655bcd9b025d9d34f8e8f7385ebba74c7777c56cb571af991f43d63b0239120f894cab3ca804a7e3a589629a6d1f0ef90cdd5f9b91f7fed0eabfdc930df7bc345179fb7be50a5b579701f563df87b0ddaf99d9af980b5c097cde749cf571c837ff18fd63d8dac324bd5628333227ccbec1c9e55399bc75739f6486ea379b5e7286920fdd4037399ac73487a03c3f8a5be7fbd9174d6df01eac9227a5784d97f0da4f0a3e34808844d187fc846c3527fd36fb17490b39698197b644ffe572393fdf93c344d3a7c5738d43a2734f73943b983a3f9c856aac75092588a24cbbf7e49e6cb8b630acf87fac67837d63f8fc44dca0e69800d7ae429479227440f7495845b9af17e92b6667db7867c6dfaca9483e0d956a172fe5ba73994c02e4c426831c4edc22068fe6d4437bbc5d055abcb5a36829fa3e50c9edac79d7ab814aba0c9543abf5beeb3717628d3ab6e9bbd1ee37979d47953a767c947e4f7e15737f89bb47c8016b30ee84822fb5ce5683d4f7c616a7ed8c64e3fce3aef3b8378e76fe5c61b3028f589ce18f386d3ae1e0e806bbba89d06abc2548bbe9a80925ed9fa99f128a5ed9d9afe545aa273b8a9eb66c07af53700a95708d661014d752bc6ebbdaf9a4b8e4d2485a48456d79496c01b46d3bdc6f09f77427bf750b2cda836f89ea6be76537bfc011441b4a4e0c99386b16bffbfa4a6aa4ff6af53a047a49d738cc4af9c30af0f6ca25ad60895a04f456b19157edea36dfaf57fc42e55f8c9a59b08508cf880c50ea68454d26afe2f8a0c8f98b930a129df3038e8b318e74cd48b40dccd5fb851105be07ce48a62e86553c98570db342c0f4dcc5c5c9fbb48989a96487e620c06859ac63b92898d218a43e02e400debd4d5f7dc3abbb89039f180d47fd0dcbb358e31ba143e676d72c8d64d3d435cb57956f5f9e42c6e9a1ead5e205bab945a79a154ce35bfb04eaa3b0ae6f68c1a330d5c34dffb8116d883ccb4755ded6e2c499c30938500d6638044335765803648b2c7583d29185714c06345c8002f97a0b35641a2457c1f843d3ff637faa04dad093733811f2b143257c37b2f75bbe8a81b107443d071be7ff5c8a89548cdc1b11e20c41e1a6c5ddc57d7e72c8e17a5cd82a60b6c8136bc3b526187fc8774f9c316d9b7c2a9b41f676ab6f53b7e436194dc2cbd8ea324e8701d5dd171b4c20054c87970258fdf259f575a71145b1421667a16812933d645bccc8af72266d55184b1375bdcb15d87b5c1a9b4c0e4f34526194754358de8d655104241d2a30c6021c9d3e727d933147385b3f416b2418924e3369df7652debd6a3b0c457fc28cd88355bb1702d802c0e39773896ecb120a75c171069838888b5cb788990a349b44d5e85712ca91ac8a20e2f03a3c119ccccd37dc783175485be3dca1515723ff2aa14d77a216eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824a7072511b1709a4221b7526da8602cbf11dedc601ba492fde8a5d3bc27c458bb1b994432a61a7a4e333608207fdd700ecb8781887a6fe02702df120f30bab2b30c28cec7d86447371c6a5e99a1c171b64827229527c48b8e343005a58818bc8b9b9be2125aae9ca2d640701b5b204ded33d2cda34ae77134eda9fc2db12b5b12742fb4b4b8a22d8d75cb1f83df409ccdd486303202637a99cc613035ef54257a27ade904e88c13c91e42e841107be386c7ad228459298e01a1cd4151d64064666dbc954e921a408975ab6814752045324a3a9f41f322153e2dc1c8255a5e63280fc2210c52176a4c93cdc9693bfdc73156aa319582e8cd092a0e28a1a8148c13a14fbbc745f5644439905119b44405a27ce9ca446872927e06ebeb11c8fb39ed407042bb2308b90379566a18a32b7ecdb6f832c392bf205edeab45bf0110af1aac076c417923f80ca059f34101d87234b7a288374b2ca0a88950bc722a01ee4e7be48a81fe732998f536ceee8540323ae08f49217ea880de4431bfb74cc80cab0b89f327a28eb9ba932b523907164dc82c961343088002d10f02ac2647a3a532d5cd796abe16115724d37122431a57b1e9b2071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd50688de263a82386f39a7b82592247bf5499f1836a3a941413c75f6331ce403179238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = 0f7175b0a6290fc998515f4604b69ecfcbc7c13d74d59e83ad8adf658736ffc9abf4eb7346bcfc7b038943b37fd1cb8dbb0390e0f42f1940d7ab3d1aa09ef8a4a424eaa75e92b8390f07c1b6bb7f8be764d39955d56d9465aecf075019620d042bcd89a8b957a938cbc9f550170aba5a0b60abbf6ac60a923076a08743564f06a3660d94c27c14870ffd744b788510c12484e2c21840bdb1144197fe29b6923460d6248721f95ad1542c43dd3155d9c8ea37f1419f93f615aa3baf4875c3a4e079c0c83deb91167d9e639c42838ebf72356c021181820675084a90d12e4cec6ffda46a1af2fb5305a925f66222dc9188e8954c510c7f45bd0392243d33d26b41d9db25b3766090a23db02736a6fd5edd84727a7817ea433dd6d3c787f4d928855beffca3c6ef6cb62991b68a27eadb3f6f556856142ec0561d116ee36292f6b03b00ca0d45ec4b95a2f2707e05219d06502e9ffd92e3d2d617c9e4a02d16a1ffebfe80a00f855c4547559f504428e6e0c69383adf03bbb4e2e9aa61c6082147320231bb09075942b1d73812647d3b8fdcb388b9b3088c4e596d72e6abcf6b38420fe7fb10d924287b21561ffdaed70aa8cecd73ba7acc084309106542dfc9ceaf1f180bed5ddc88bc3fcafa30b748eba8050f8c462cb430fa810248dcb2c3cce1902a40fd0143db9527ae34715d2ce124f2186f1c785fcdd67a4977c471ff5063d184453f9f2e4a07548a989bf3d7cdb21ebe5f8f1d701020b71278e6f5e0018e4478228a268860924f856d7677c8cf76e5b3bac29fecc9d1ae363c0abee737149b965962f7135a31f82f2ffe84d69ecd94ccf111e0c8e019da5c2761d9852649b783ba9c9fde2364a0e8e21f14d6f42586e1f08d235731ce0dc19619c2840488c570d528b953b412354d2c43b37d66ffaaedc48d908f3d2db276265118c1a1982eb024956294d97226561952f6704064705569b5c4bc96d15b3e84ec3046d379e4ab044e90d68d94b6c0e1434ebd3616dba4067085410aba01ac424b3f3ac81c9b9d399d069935d75157fb469abe37331a49ecf86d76d723f551dc57dea9921 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8977c9149d9b302d50958b52666c3f7d26d94a56e3e9be909e1838a37639928d5d58baeacf9fd9ce5cb8849a98a26e6b36778f1e138abb6bffcaa5ad2cf537228e477f7a4a7ba4769dcd758eaeeb28e447f76947cb5bceb39359bebfd50baee86b374692a5d40bb6753d043561b84dc345607ce94a8f0693ca1d96a4c9c69165d7659d901f85b322be75f808c76c9698ec9d36b464508115ea6674b4fe6b90e4ed753e13fe6f7fb3ddbd7671e3d0e7dc5fac7f7571a4e0c685b4bcb885adb74da7db8588e54c280b82ce4ea7f85cafc877c6de3efd9a889d8ead91ef4974e8edab121fa3ce0446d97e5cd319d20184660d8a7359de37c825cb79afc203cf9e2dcbe0281f75c62f5fd8a57e34b54e781de08e83436f8ef944848a6a0a7099fe864b5fd68cf8e126895087a96c4d13d5ec475825f44418265c5a6769f5d86d463bcfe003f54937e6a96f859dfccc888eb2e1ca516866847ee3af99c94e41eb9caa3d3d6c77e7b53444f4fea48cc66b43883c23848b9cf7902a57f2c7c9ba72dba2a2de5b6a86fa9defe82ad9f7e63663243571afb78c2c1dd95bfcc88acdb564cf49fb1481cc7a4301a6ac7ea8ca195ae9c8859506bf67dca8fe4f339802b997e193e15798bc9c1d4c19cd4c6c87f7117df8b31ee2d8bdc35e53f46f573a0bfe793848ba4c5efbc69dde5aacb1a197b29ac4afe55567aaade7610fbe852360be346019d3e0ff8c5adfad9fef258ef66dacccbddb164fee48d6cfd3f5ce6faa85b2d6af453668504989cbcc4fb60b36ceebfeedf36e400491044c3b8954dd7c3aee345fc0e9e6e6fd4c58898b57d10a459e6d9de4e5824afe72f8549a4553aabf6671a044f888e954270a78c23f556f333c07245a556ddc5a5b7919dd411447b972adeb17ba57415a3db56c597bb4b7e55752d0bcc6357ce567ddefd79c64afe59b8d9f5baca6adfca4a2616a9f5063e3c4fdee148dd736d854204d6248739fa6868bcdb3954f2f6288cdc4e7285ef8ed40322944c79cc95116d52f9f89eaae4a097d69352a6a0738699a37cf2adc46f13359d725fd0da8f17fb3574e787a0eadd3d9f893e986491d219b6070ae339c3114e1a64d6c61353411ba2008ea358749866018c802d3dcb05b0c5329a691f57303c0d724fb2a1121d264374aab2eb209412941f7e39eaedabadba71494863f79e34eda632c1da77ebca6283311310f4918c69c6c5036a47aecb3b2433e8991b8d0bab01626034be96f31a41d98c1a2d3354f47e87b9053033b82a6a8f6b167e827cb1c11ebf4758af8c70fa98dc1f35b353c54b5552a0f37257367bc43e263e8a23284b0982ce8a6951a4ae5924d74e3481a4bc141f0a85e90c06e97ae64183c0f469dbdcb081de093ddfbaf9d4318a24615f8a38d1477132aa5c322934d5e92c89acb29aa85292c7971e61c89ab484e69976a57c2181ed5450260c05fd957163c0269e9a3aae27114a5395e398cbc198f65b46bc2108150b40493532d63a35f1882583fd16d5de1bf0a7a9c82d9717bac5e31a15baec1afcd94a352c01dcd73ad51852d618490ee5993dc617e0526556304095657274a738bd4620e80280c828c17d31892fd174a4fd8302d705cf738126c352899026d8795c9afec77f39c87f1567120e70d9211b73daa813497397c0abdbeb7124f942df311067a0ac03fd3c3e8641f202765026b7fc5511754481bc8f227e362cbbce579037c4ccac5564c015318e598cfcb538f1558a1b55e4bb61c372caf23c2a1eba52e7acc5a05f129a469bed6688788c2c68c72b75ca413b7496f3c2505eed19bb2962d82436c16c29db904b76ce5626da57bebd05bfe838725052d1103202e563de581151bba7d46e1cfafd50389a730c9a3c56d88030bd397a9d54af0e763249cad1cb0427580853b3572e705bee6f1bb1f4232f6ec2aec3059d777209dfb32710b9fbef71203f5a1eb11507ecb98e5e4cd384124531490e48a0bcd39be19e21c424c726dbc1900ebbc1bf155256a03a89b3d0537b4e00988447ca3c02a65aaa2ad5be40825d207fa683b9d915a6a5a1e8fe20b0cba4ea14378fb759e1a064ad93b6e5ad712be3551c9d4a4b0819eb7420a4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e79841a29c0f2dc4089a85db6865ec90faf2f4ddd25f210eb56e49741866bbca8cf811f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = 5474f5beeed244e5f164e61c630737d0428d8da9a6e8b55216d9b4f346d34eec261c465a58a9a51d0699934786671e3d52ac72eaf85a346d295f2a4b9e4757edf889b8424e485643de3f2aa5cd93a3b7c1a5378c1132eb4d0ef096fd33fcc6255aff0aaf219ad8b36e9f0c201964a28affa693201c54bf75f0b9b3a9f636a86a19560857153a3ba7bdbd0bbdc034666828e26d090c324e343d5968ca97fefc86a5e905b0135a2463ea25dc67a5b200a50b13f850a5b00eaa424bbf0abb2a627322134d90be38edf7f505b9abb4d49ec7fe8e28599d7c3c75d8a7026a3210187a4cf6e3b4f1374f18bf2cf1d624986c34c4a959bccb3d44b0af3ee25a3bea6b2cc288aeab479a33c62cdd7f0207e7345b2e790a2f2ba25ba5bcdfa1127a397d8cb3ed5d5cb75f3c8554289e91ab9a3d944e365cf97449b26305b58f120b01999633cb39f7653d0afec9cab3da916f773d6d218c0e184fbd24642ceeb73cdf5c68e3b065667eb6785d98dffb150a7c5c96a903e8b86fde7e9284737bc33863ed0881e79c0b98ff9ee93ca54a7fc5937460f1b20d0ae8216c1ca4a5ab2c04906e2164a4a9e344f6d4c82c8dabfa4226540e33b27cbac44715af571d4c48f2d8b24f62a593adeb4d57a49360edec07cb3cffa0cafcc79ec1d89c93544b85a103bd508b264fe59b8047f21da862b2af375fb4029986b58ef79740bc4fe3777ee9f0a680818870a1a7e3b38ba7982028d85e24c37ca2cfe7e92b4a1a705a1eed968390ef12cfa14d6a96a11ca17b26ca83372dafc217149b40377d41668845ef7d14f90d5ddde801c2ce862a7f014e0767aff25819f3e7003b9f274fbb3b42709824138a081606d8900d77cb575ab1d923898af507305bd9f34d21c553443b518f21e562e0bc35e62dfd11dd7cd42116204feed69bf6b6a64117183e5c2b08fc689cdb3a2e6d30a4482de2bf2da1c6bd0dae710fe191892189dcb78394281f57b742fde61bfaf975c00e125399480345b0358644d94e01a5e0f1b88816f630b817a2ce30ead5bd892fc905974975f84205e2a79c9fa02d25cb62b1485487c6a2100f0d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 57343b70c6f60fe3406818ada3f4f2b07d36f73ec5014d9e82ca670f894607cbdb067ab280a99e0d7d47572ca703da89429559ccb397ec7a6e779abb69dcdede1ffb012a30a978b52ccf8a1feee89086d7d308ef60b9e168ad66c16ebf000bcebebcd72c23738f13b84a6dc630c8eda0e7f4e0cec67d5fe15717bbd51bb9756dfc1194d363cd33e1d3c1b9887ed24f31a7e54dd993dece994dfb1ee7422f70a93d744358c4fe56da85fde99209f839d6a1a5b9eaf10f371834394da3c8d94df251acf92554687e0fa35d85e7fbc4cdd91684578d995f48cd272755dbcc6128039eccfdd043e54a26ffb7a6ae4cb48776d278c55ce79d8447b014fd63c5be7aa5b835670e931163686c1c6765cdf33fe8df0cb6919d19c5a14c41fc7ac0e0cf726cb54a4de3839914e668bc88be0a721e86c5de0b3b8df862b07d84c3176e047ea705ae738b8c7d0f163bd02cecfb1ee81b3bc9d97ba2b859618767998655ffceaa99b3ef6f0e2c6ac0cbca10db625fec82363ab747fefdb473755b0bae5b7e574745c1ac1648fac9f675735f5b855838fdc47bdcc23a3c6fdc5550b29a75740c34ee1a42a847756d99ffbc2ca335dd6d6fadf16e3cd884b9444b07c789cd8fcda49d95a4a1a13947b3fbce992b995eeb8ab5cb65ad4a67a9335e1b3a53a753ef828bdfb97fe8274833ec8cd0852cb6a4c88e28a99fbdc635119672e7c6fd32138fb815cbbd29a7d40d568506f0a8ba60890a3dbdf58eae85310c776216d43c90ca4d69adc7a3ddd33e694bd48c78c48870b3294f6d03b6a57ed6343eeb04af8a6f89b86753f73193a6a96fe0352e5b7dcf7e730fea7d9482f26750eb6a414a9aa6b15d54b21ea38ee9d1a4c479473484fdca8c5767e21733c67d9530485dee9fc7ab1e06a01c05daca284e5dba7273644a8c1b3f1f2c52b89e910cecaba06b391ce8d7e085fd0587565e2d680374bff2e48711e7615558deea54826485c3a5defda01a9ee3f95d28afbf6187b625f7fcb12e91fc9357e724c76a6f4148b7ebd8b36b169ccf24df657a7ef0da13f8b6fc4a665ebc91ab809863be6b5aeacb039887b3281828644ffa865c43bf25ca3ee561118497bb2c1a04c50b89ecb6b8f173ac78c0380153b55d551492a95f8013b28d38710ee7b0b3f75cb0307e22f1986b65c9a890bdc7846e71b926eefc4814b255a428cb4de94313da24a17973e5d679ab44057e664217a54f6b16219be642fcd16b35952f0d2a37f37692b34c3639e9400a15c245986134aaa3e0219b98383cfa7223acc31b5a05060bc1523d32c01239c9df8338d8fb2f998634bf71187b3c458d155b01dcbc20a7558d6196b7e0b0fff5c856077853206dde97268da274fadb80ac727555e156ef640c2582c4358aa8cb78a55275393de19792ca0f6f030e2495cf1d169e3b327a2cc17fb87bac4fb92f603c93658c2135322b58a4bbdcc95e56f66104807637d4232fa3868af473355860f9850ea5b61391a8c20537ad23367097b1911efa5f74767ce9b1516936a11327623d371e8d64a753785d09f09157697a48902d4121673e2b904aa94d845a5f17e90bbb60b81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e91822857f40fe1f2c818700d26b882e58a3efde1793ac428d9fa8a94f62ba9fb16ab867a146cc1c7c0a0d45a32dd074a4ba52232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097380d17a6f6369a5dc55616950918b245be7a1a3656ff4075acd957e1df062218bc84887b74da635d9011bc02824603007e9cc594387771ab84f7bd065c741185fac84096aaddebca179355dc365516efa4873e70159e28c714a4e1149befb0a18ad6098d5115419dc4779400f8259c7cadabd41a7a270e5c91a616e5cd0b05976979967baf943b592917befaca4d6827a4a545fdf584b8a48b6fdacb1de775bd259b083693947a31d91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a3d235b870896a558a5fb2ccd7d13885969d2037bee23b3db1025be64b3a5feb95da076019b65685186a445bb2387aad029b9df7f1bc5081a7423c267978c295f2653c785293d65406004806db9f98a8a7d12ba7b87b8032e0cbe218413da907641593ee627831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a13fffc419d3d8a887ff789eb661b2af1ee5b32a302ca267b33eac2ea7e3340b9762d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = 45ead8f635b0a55577e4ab9ad95a454cf7f790bc4bf6ad467a959271156c623fbf3d28189956f4e954bae7058d892d7112934ce536f5d39c69cec5b4f8969d470e63d11c929271782d53969c5b3bc9a21b6fe9c711aedbeb37e4a054303fcd14c88f1d9686077564b164ad0f226a75166b1d9f565d0ba003ae3457c9fe7184ecc97fef220c0ccb52eb174f91e79be2af19d97a30b5af8ec0e6fbbe9b96545612fbc60a83a0c484d4385c222f8e126bc6339412059efc649995de93f891782f39e15374bc40c912cab6745ca8cf2ea0571ec5b4d64527ba97f5c1de81bd4de11fa3d5ecd703d2fcfe3cc073f24d6c40d58c6ca482ccbfff2aa86f430c60e155c8497508b54be5ece269197f50a71ec6713a59bd3c8c224a072cbe5c556332e561e8ff3c1dfb96b09239803f4a637409ea35e7020a83c5530f8b8722efcb6cc3e57837a4b98c6ba10b855673b8d271e0e5f08f178f18777fce80a667e2030fdff1c5fcfb0bf566d06022a980df4a8de2e91f8b4bab58628a70b1be0fcace47c9580bc866e9641265bf1ebe8be9fba7ffd4eafbd62e68f81c1067a4e75ccf6ef5cdd8f18fa8e54ba051ae976b5ed66c4662c9e5e0017c8eea63d82b1dd3a8d7f0224497a4ab7acfb3ea2dc6e2d8048b69082fb9edba6c5e3fcb2f43c25d6077d7dbd5d4da018f0cd1a5d612cb9d139dff309d445eb2c3364b50e98ecb9c96c23bfcbbaec80c6306e0453d7f470302eaf456aeea78a8cf25a9eba87a30900630d53cd9fff2413e7da06eeb119c67270117ed8de87f0c9b9ba2e8652a838d036e5fd815b5f502372b60769223faa504d3f4add01472332d01cf6d95518a8a2cd93b6fdb4e4eda53fdb554c3d91ee4c4bec7bff23f4a9cba2f2723b79f8dc71b521576e6f6111ad0c3d50bf00f9dd1040f4028d9b3a92cb4816360c055918d40529045c68f31090b9f2d92c7586232241cdd4e6fbd492de375fce0da6eb1072228342bc5402bfd63b517f69f62dc7ec0c6c90dcff4676bd95030659077899e5dcc0d9a4c53ad7c1d14cedfc0b25c0d537dda3252aad4d453e1b8b4ac56a10e9a816b92 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c4f46b77fe730b277c1065622e85451a3fe644a8f42b836e0b389d269e9d8d8e8e67d64837634cb133bf64f9931ea5b79a16ce7a98f6e29c817fa83860177b31198161ba4e2cae42c1f8ed0d4347496cb944af730c3784da86370f5ec8000891017cfff6063f065eaa2ac8b2a9d374ef5eb7e24c9a67f4744abd469d85f75ffd4997334482f8baebafa6289d4a6d94f9b266a4573aa0e9435f65cac4bac46ce27ff62b59cf4aeb79fe17b68544cdfe1b4ffb7bf05c23ee7319eb77dcd73e7c85a7559be933f08fa6b90d6a3e4e69bc7f486028bfae3af86897fd60de7ff777a6768e64d6e8943ff109f64a36bc1fd4e78917c46c1dc5dff69ea8ebf488fc4769277d8b6a4082d8504fec5b4f39e5332ef17938fcc84da4db689bca79c1beda6e6ee861f3243c5ddf3b18f59b5588c028ff392b143aca675c844975aee455fb8738c1c3d543775804034cc01a9e3954967e65fdd0b55c6cf86d71234830e453dc357b45c830a26fb990f7472d2d303444eff5dbb14e7ee31d3535627fcebd6dc2adce6497eee82953316be6e40a2aaf87ea6bd91dfe61f346539ab1e965ccfc6d7df0296e2597e7ce95e560de7433d7e2cbbca74b9533cac87d30a476424fccfb7edb612acafbcab41b968746a5719014a9d7e840e1ee536daab3b12bc72695875827963a05ba0cf6eaa5cdb5db4ff4ebd4f660f87f80e55ea4df3219c5c28779c8b8ef877726e3f903d1763df226debf99bef13687bfbfdf5dff6ec8e2753ad428c7eccc8e294579b01fe764debe13d93f9ef8cf4c8ddb765f6eccccb24fe7f7ddaaada8a750cc8fe1ee8aa7ca6bd5f17df0c14c3330edfbf1c8881c2830f743e6681933d84674ece9d33fcb4465fafdc259522c4b6b154e9c78fa2f4b06e24e9c4dc4dc5a614da01a1ec18705c7d327f52abae632de7e29ffcfdc7c986fefa8d934819ffabcbb7ccaf38add43cffe71f6d9b2873f76ab42bf94eee805f03c2b440234a4c344581c28bf5afc92258feea8a8cc095680bba4a561a8cf54a8fe882a806e64e427b333991646cdb5eabc3342e0956d4164a96fc4a6430367596fc0ddec85c013cc70746f2b268d16f48db17616367981940214020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fb715428542f5e49b6d5c762ceb26c2520863bf025421a29f854bb52b3a5decb8a5bb7ad23101a254b89fdd95afce255eac087651a588e8caa2d5512cad48c9041a7c6f06dffd86341e62935a6ae0d4907cb3a6e4e223cb754c15e2c88d4e13cede42a636724568a1f4507adc8d0bdafc91178d260c262224ec8a176ea573e69c057c491d1234e4f39a2f6c4283a40c70223539697890cc5cd935ab8fea89a0ac513cb12c83bf6be1de55788f8a434001b7233cd3fe859c3eb3ab0d15067422a5fe1acc2286f59b75111672a3ea24515f9157835ba868a6219d2a10e72703ed6b066c036d118bef4598d76d08010967305199e3f46cdfc41ae1565bace1c52bcc89628a84f8b74252566917d440718a48226b4bb2f29c0e7743fc2fc5a3252b93053c0bd1285abf907601b93c83399b104b8b2c06ecb1cacf37059016683d2d08376111f4ed13a3204701271abded98bbcf5141b12b9455687e66abff877aafd507d01395e7da932a2e386947b015e3896d2a38214443d169b565fe8cda1c305fa668ad7d57987ba95a4e8a8e047a6039159f9c94b6e896679c325d2298a2896b256f528ee7b114d0101adc255c893530bec9d1ad397c6776ef185487e6140f2749af802cc1ed60069585d316959b2bca22e224adac5b54d0655c0939f3e29c864d087fafab871a29ad82c5533b40f67d672a16581c3d05aaeab3cdb0636c938c575c611095504fd200b61293ae1ab3c8895b6eaa64d26617afc82c6821a5b1ae4830c526777f1b9d6bb271c48128098925d607d507c9c7382cd2267c4ed7c6e4320372dd88bd5a9a50737663998934b70017386784867c5b9b11aac66c1ac3bb1793cc02df88e54a41a3db8603af791af157665b88b0b9a075f5a805223754a2005c81ac211967a43d7bf625069d098058df21abab95ca1e57d2d6583cff926eab06aa139a3da3b9bca10c9de93ba6c6346e76a88a8e1288deb6832603b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f1de70b1072881eb659a5e890a92c9313c7378d2e960a060b9c918260d4c245801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 2b3aa8988eb65bb1d5c86a3e8163033c7e0f3f9d924e64d260986b74f9a66675ed4fe8c786ddd11eeca0118eb7634501d8a85747d1f8a6b0e2c5c7379bf8ccb6ed35bea047f69c1a09280d0895695c08e6c2fa800d1ff2959ff66a9d425adbcdea825f7bdcfe74cd05b28d4c5f58eb66f825c93e63d998892c52604d14ca32b9f8dfadce0777fbb0d580fecc137476e85500bd909c79a94bcd8b54525dd3e7e4bef4addd1816a873e52a259a42097cdc95b7447fa53a5d0244ef610cb540dc745f78043cbaae20e02262476a21e1319ea75663ebec5960ea56834432a7cbb77ae51d60e3b339e37b2503f78fb14a6b8acef650e27807090c42908ebfddeadc1dd9b27ff1d471f6945b1176bf7260632a5ec6fadaaba637a1e43759cfcb48e5286b164839511020a4c22982b840a7fdec615f7df56bf468b3da925eb05ca7b71ebf67d4a8f07e71f6735f5f03de4e00e3f58b4aa745f421584f59d41a4e5da32980c3d5c58ac9eb22909ea6fe22fe16ce01e0cf5babbcb86719312ed8df46db9ac480cf3408a6f11c45f71a0913596749ebce97edffb095ed16191b9ad1914ea56a3f0ee7d2a2b7e12aade6f6399b9e273c4775544c5fe559485259af1f601f7d9cfffe9d89145aa0567155c1c2f75c83eae156d560aa6fc28e4a309a04d1d723f15b922580adbd4a790d56a0baf32c8d2443ba4358bdee22426a78ebe7580879c3ffe565dbd5b5f1e9a987f37129a255cffeac0d8c1edc65f5c6e1498a0ed9a59c2a9416f2ba0a395a338a4057149665a4c3f0754bb4abade8cb80c3ee101046d05f279624736853693ee9f86b2c237fe2a6efba216949e99a0bc4bc0302c08ebc39437333d536129dbf56b2592e681f10c61fb14a1e50111966e2990080bb6abd9d54abbb442252cf5194d6c907a394378e6998fddc4839caa0ac137cc8233f6ba92fe82dfb1de8a4b1866eab8cc360ccea3ab0493b6bef2c0cf267cbae519c0cc48a40e86a27f400d0629abe01615261ff55643772d990325108ad9142e13d64ef5295c88e00923dc9e4b535f97e6d4862a78ba80517509c05e729215573a7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 22f7af6da8bfe284931c0a69afec56c4e4378c8b563daf9e2b88741ee948764f9007ff6630bcbf0bb9543ad4f7fcfae565243d8774f6500bad4b27ed3f3eb1f538c5d57df19567dee02ccd0056d8216c9b864c378ad3d8b5edb514f4f3c97cfba2bf4f68843892c8f5b51d5faa1342abb97488bbae4acbf9a7caa75a2bd65e75f843b5fbe3f571a74b7b3095c1cc155cd69fec922ce93fbc78580af4ee6dfbfdf971f035d1d3c37c2fee37dbbdc63a39d9de9c8721ce7429d98675748c9ba93235fcfb608451c3bca7a055c91329efdc44b1469b54162c3b047f89f2ed39f8e3475e259b8e3c899cdf8b0a093d7bd65f405cb958aeffe015721e45858cffbe4d943304dd860e4496ef85519f393e99d54a15dc69f8459abd7d7f5cfd9074eeccd7f7821f455da0ccbe95c377ff449b960e9f15698384238df5cf7f6df48c1d89a0e9c7845cd6b366be3c2a7841275986a05b8d8b6cb3ffb66bca4ff141d54cf4af55e3fa3b9a3cf36d5fd1a37dbec078c7229973fcad93f745bc62c98c8e2c305c75667dd5a969dd4ef4655ec1cd4333e8b6382d9d0ea9e9993ac11424c162ace64b0589e5296267ad6d51cad55fce6710bff35aeda3115a58be094bd0e8bb7a6336bc8be128359c0c5ff1347886589cd99b16833e93bf907de0d145d20a8ca9489834d88b4128cef803faa030b7fc49a7623ea66cb88953598da2d0756eb59936b725347dec4ba924dc33654b05f6b71195dec81542266d7b974b55cdc64c41ead2e537646f2591078c563e1bdb58fabe99a9696e24f4d26eaaa1f72fe9fee6b134f224daf10ddcf48f43ca765de4300aa2bb89b36b0977baccfa52d97c6167f7913d72242aa1c337670199fe58f4e8ea2a30377dee37b4fddc375a2c4e745dc9bad55a54441d9e80ef3d76ffaeb48ca4dfd335af158f5d7345687ac022fd37a8cae9170a41c447bc2e733b5ddeda23ec678cb3fc1734e2874bde7fc7aad9f53e41fb5aa89f8aa8247f157a6e5d03e4b8aabcfc58c2c8978cc6539498f5aa214e89aa996a3fb5f275bde70163b5643e489734708a8b6c59a66edae8b575d975f839cd5b3685e864c874197e1bf074d30c41bfe01fb82085c8f5c43a26343aaa9184a095beeb6e01753dc7da7482f2199dd798d17660c5ccbad047978bf0a62d3b9ddcd92487f9103f00adc8fc9ca566a9331790bf93a1599cb3daa229f5ba8d2e33a8c7451130e17c9d4c91ba2cb187495c9a9a9916700e4f8551a4f8793a6c7e85327012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8b51fef740b0abb7ef3bbc8dc00599f711b47a4c858798a76494ed5f01796c43688339db7c40d06cc7d205b5a6aa3278f561cfda647f8961da7966efd47b433650ca5405770f5742b919c81356d0dd2a87b21bb9dda76d0b330891952c81c5d84761476063b452a6503f7565d406fb60b56cc14a9734a297283b2601536fcea5a67c42ead903d22b672d4828a93e2a321fac920771c1d038ab40075771a9f0ee97929c69143808578d114c5366fd0b7abda8a7ed521bded7bc6e231057988c362c5befee06895f89b2637c2866bcbba39b152651d5bd912344a9b68145e2ac69adb853d06f513e108105f65622ee25750595a4bf983aaf45921454e70a06ca392a78eec70fd5685b83a0532f4aecc8a09c2468fb2037f73fba689b82f590891bc087cca35772596410969569060a5d5ea0ae34b0be06ca8df188cc458cbff21615b1a4e0259925cb3012105aa50b494b35a45d4e9312038866dd4131fc4578674273e182d7a1a1bd049076d70aeee016a6c1c520d2bc404eb4fb28918f1990024d579175082ea9795f0616e584b2c7f93ab33944401c7bf7ee64040a3336ca5906e89cf406512539c8579f078d957a2f4b625f90561be79bb59244b0537a41fa0202072aa760a0e34e94fa751a49d68602d97c807b9992dd637c652563f7317084946703171db7262f71737518c52082966f96cc386e30bb6f89d02b93f8db8b9713580c7c62c06963a18681a1fa54a20d774e40c0abb98a6da5a148377a264d0cb705710f3f708955b16e8eb22754b26522519ba833fcc3000db88030546298b610451b50a247885e6321fbec37b2572a246e181dcf97b3003727141194337a108a2280d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34cb0c77b5407577a9a9cd8864efb80974aae107fa2801b6ccaf341d5456a86621f0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = 29d525077b2e5a2be67d74f27b2bf8045773ccb65e871518dc134d6236a14f0ad4f22301b3f9857f08eaafbdf3aeb67b19cb6229fbeda1c6da308c1db7df054d94051b1707404da9da700ca4afcba759b2fa27db62794ab19220a9148abc2a2232b16bad89b9af0996a672bb5cc218262a088da32884d1db98490b1fc57efdd6540c06f43e90edccdec19cad00de68622676e68f40b72bf179e900d0734ccd0411ab3a0ae82ae5961b63931b1aa2ba42298b4fecf9b3022da59928c7a2e2c450f94cf1b25f9c7da70102da7be1a1e07858a56f4db2a15b2e878b80f8b3c4b71b6841d96e7e46123f771dacab0c529758856fb6ffa288a037294987344e9a984767885a413a65839be8e5571a3562ac42076ac70c27d4d65ae047b9951e63ff890e3474e309fa24b9f281f8e250fa0d24c193d9e8c865039c6d3c3e9ea18ad2157ce17293784ecbf5948b7a0612c04bf05431eda24516f9ec56e13b6727cb3321a2b9dd456e5e92adba02900590e083c55eb8710d19c7133caaf0dad8f563b61913c2dd3d3dc9244a113537d61f97f7ef7a0554bbaf2011442026a84e4cb81a3d39b144fb91c736e55e1742feb117979da0fca764440ede26797987c2e43d6d7c06c26b3f347e58e90bc37e36402ca8e003581283a1c63e96bf9a37db9279dfba5e8e839c1c2f72015ad781133c436d95f9722e033d83f46ee5a0714e64d959620a386e8ca52894bc54879d672e870662e284451005db72601b71e95ef64c9c36526f1f9da5ffe1fe9376f9c6a53210e557c6454f22ad4b2bf7d90c92f6847181717df0bc270287543ac3ac69c16776c65336869015c2d912dc101589b068ad7e7dcc7957a839c652046f73e85348c4b842cd074a33e8b5b2caf2d3440f650c29241873c2a86e3b7910add04e4dc38c0c0fa7f0adcd4a4d5738441ecf7879827c14cc71e781f28d505238e3223182ddf194f05f06888092e8e964603f9923d82ce9b10218c618613b2470dde0dc11bbd36251db27b5ceca9aa0eed3bb8878ec119525ebbfc4c83c0c7185bb309ddfff96f36caf7701a1c0c3d32c1552300c6f48 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8dbb979547a684b4cac2e4824a35eb808a646bc8b49b9fc6e4d83bc82a30e9649c42b4b955263725f5d5dfe8614cd8599699d25d1ae89e556fb083d11908609d86cea8f77d0c687555a88e8f786e2aa65c9154685b038253dd6da3eb9f2ecd68a14a50d5d641993cc15274e881ecf7f026cd4964dd7bed4e06d99d5d45a056864cef0bbaa0f9fe84f4593f59c63604ec7fba346d8df39ff5e1eacfb39fccfbec1a452094a9f7cb78c3e9c6d72b5dadd8f08b5ed50925bafa8f4317be7475e47bb2e7663ecc88a5d6de5308c34ac6aa97c6b5754b434d7b6e1e6ddd080cb29bb66cce7d7254e8f4a5d84ccf8833280330499e9747377b9f6f8e99d4ea9756ac4fbb4f81b47b9db8e278b99b13b5711b936b42189d8b88ccafba39886d7385a9d8a09d5f2f2c62de4d6b1decbf2a8e5cf506971de3ffd4ff887008e494cfab701a7426b542663cf611043705da7e819db84645516e37cd4ec48ff3eec51d0ab393877fdd76dfd433ab8f34d1aa2d6ddffed5568ef58d6e3ffcc8991b0d6a30dcc6b578e6d0266a0665cc7e0c8ddd48434818f89cee6d236c6c9f04c31169f3d6e879bafadc33d7e7a4946343bdc31057b848269a5329b8c62e8d5c1fc7ed3746ae05fbf89574a87bc90f4864bedb85912aeb6bb5c744b6f3f96b62153d53576fce03c8d73e2e906636c5d959661dfbb32b3548acb6346abe489abc6988b873267e725cfb71833b4dd959b15783c8e12feaea6ed0304338da0da741597008f673134e4e75c545c1d6af2eaa70eaa65fc85fe85fcfa0662443ccac36c074f6c3dc49a14537cbeeb8cd3a647ebd59e78eacd89dd6df966213a757bd27a4c79b79905556906789bd1de7729ec0dfdeb63629a5e56fcccdd77258aaf4a04ca6f4cbb47323adb755781ccd9edc7bce6f1db5ab2ed67df3b7d80fedba9692a5d5cdd26ab8275aec6b9befb1c3724f2b42be94758c8dea1a7f6a171cb4e95d5c838e575106336d9daac8af5bd785ba3b298840f76262d561038348b15a61c7deb6eba4922b7362f24ddf544e4dc0bb77cea68d49e676c44dfce06de06eaf30d2cf319d38351ea1cd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856560e0688f75c96b524fd60bbfb40c18533b11d3f6b24069c5303cbe3e6558f376b71da5161c6310ae651eb0c9a8dfaa2c265b85478c59a7b3519cf95176768d048018e8a24be09bc99f6a459f9cca9600aa8625bec4a76959d157371b2abf19130a6540f2f69821aa161da542861955ddfb729a95841845635bd208ab5a7b85527c01f811a98aafade122ebe57cbc89c5ab551c6645bb40b36026b0b10b40b7e645cb571b664faa9d06270a1902549c507b33a568da51a1a7322b53b95b92158dcad6b85e07adf6042f843a06318b7fdaca35867910b0db0e09d03ae54c22b580c33594b85361788dd12764729b54f92b74dca45a973872b00412da2d83eb12d8c51627c4be48955d8eb67b54eb1879479803b30479b59c578c175448525c514b9e685b3ce751b035836b229012709c679c1bb710b947a27ccf07261d639314c2b1d52a77de2c9c2230761ff5254714af940ab4af7ba85c627a1a633a994752df4125ada5c86a60709f37970d771e96f01eae2b322780c3b2ec01fe086be76710f51cb4690a58be890854b7b03dc04c6f632eb56caebc393bcc70410375457af17b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa240ceb7936fb90c0673877d0635777f8c2a9a5b03d8b731e9a0fda08187b44037653bf44dba3f29074995ab3be5a59e3073e52938561fa9496b3ae0031ae0bb27a7dd67424c39f250b5f9c2512e507878438cc8b086030cc588d0c2dbcb1024167715b52130ce969785b4210da26b8a6a18606597829bb40fbbec83ccdf76913685c48817111bfc216699a9966b94590e80a0d45307c36499c006d37a83a46e12bb9fb0712961db7f33d49d633a98b7a36a3b2ad5402ca190da1766071473fb21529221559526a2e5bc5944009cf2d47075d0961721989f8800307c91e04883ceb97308ce6c03a7cc39cdcbe8723822561132b6705f54345ae1480b9fa11184c999aa8a1efd17944027e1969267973cc3456c54140b57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a255d2e2fe01c87cf70bc30703644fc255f83fb47cc5cc5ae2c0e49d6198cae03f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = 56dd54d42839f333f0a3f8626c6c1c9280110f73f8f164502bd6767bb05d63f3e8eacf81cd3fb3e6313544485c56f5d51053efea6795836680b030ceae61ac68261e606006f89e2801c8f13e092eaa6fd9d4c3eaf87c6f4d101378b0d5f23f935413abaf6c2ec9335444290f877472a33e46534dee227b0eb35adcd01d37fc524d558cf713e511f51aae290ff87077aa8a0ab9cdd0222f3a8e0f6a9ae55d8bb8f16c28115c8fec4ad18955da20c21b08a90dbcce7121ef87c5120e843590f98c3ca2005f9d6b0cc3ed8ccc303b26b79bcdc3e9277423c43761798bd884d7cf3fbf96e67bfa1f65fa07b01d5c06be5d13e5d784658193d1640a0299d62964f156d56ec7cfa0d83b553db4bf6d00de896ee643f44cefd9b01a186634a5210dab6448239efafcf0f905ccc66637ee7c7dbf017610de0e2abd25f91c592ac83531ac0bbf77709463652a7ac98f32b67c0fd6e328975ce02110c8c5d87c0eb91292efd55a597e1c76ef8c87ba517431e486d7e3667c33e621add7e36821dae9d3b5ed22d764b48f8104166379f90e246f97f55b479760a4aa5f9ad703cc3994c7a94ffb1eafe91f5f1dfdcebc5a5dde8314067d1465d424b995e4616efc1afe1960df8709ff33845f6be36ddd9bc66db2c40274bb14ed42ad096d2da00a91cefe4648ea391952bc8d7ae080438fc04221f6de6ab6f1de94f01a91aa9abd8111f3f4036ae47e97316e736f7c6a8190d36284a8255cae43febdcbe558ac088a93aafb6bda5a8098347ac38271e4dadef96397b2f0d54cc0fa1fce77b24f7f9e4927e07bc3535ef779a3e8c693e678b6714ce1b124bef5606210919ae50f1204f82029dc267710329d7a4d8681f2c41c70f287c812fc1960b021733a287f828150bf40acdf723e958c3cb3f3554850dee43d24332740e6573f4779e88900d56422e83b3341985ce10470eb6eae2d5f53ae79d2f77e32da37725e2515ed7b1030dc5f36bd13d8874b0e8f0d07d2d3b8035ff8bbff0abfa7dcc3c042acc1350c643d48598cbe7d5075078d9022e1629b5b88984fef4c05b522e644f59731b399378f6486ad +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 51688c6b4e4adb473f37a6bd2a73c9a6f6c970cf5e68e45aae8670d003b354ce57a8d8b07436c59f2ae2b0a63416f798ed8dbf84258ae127895748a22f9d3becdc5fed6c922ec4eaabadbb60cfcb22384d81bb53dfc78ed4d4652073c40da785596ed2add4bda7f9ddbe59ec0623eefb583d6ceb7f09c781e62337e31fd28e437cce0832b7edfedf64d3f04571bac4cc6a6e729f638821048afe8dbf2bb9925c4ce9659f5fb3c6ff615c590f4abd78679b458f3117074bf76b3a0e1d4ae073b7ac0c564d3fde727a7e5a958e37ccca5397448dd55b5024a439a8fa431a6df39aa62146410b477f95473ee07c73673ee4d14bc7bdc6697f4d40354bbdfc6eea724340744decf2bfc4aeed5fc39eaee99771a8e9863596628da860afdce67477efb9a6307f66fbabab60178d9a3b88960c16f2baefeb3c73fdf64bbd68c9fdfead6e8f2ae4dbb5ac30e6815cf8af301ab4ef5d8e00a9f56e39d235f683ffa647061851941da4ff4576455de1f97aa9a5bab14eb9d4768f8b9fba6dd4134ad3d684d52660532d91b6a7eff7d88b74746326e5990467a4ffc78fc9ee77bd2871c45e95a489de4683b3ed8ea20c39b5a784c8e015d8793aa4334cd09b9d7d0707a0fec5697b5f725b563984c73a306388acdc57eccc650089b12cfa34a0335fb3039cd796f33b65d9bedf787f6346879ec8af7f363ffe723d6e4fd6cbef229a691369acf0dc84cb2d5da8d8b9d95fcd4f05a621bb5af0dfa26534a7459c76b33efa8883c772f661be393ece185bb0e34c5bafe2ebdd5be4b4e7b383a11c18eb46a67685aa722ccc9fd8eef4ae686d1144c5fcb38d0c0896da5944f018886b77e801239b13d8b3de03588403dcb91547d26b7a3a058aaad8d0f2f48715a3bee7bac857ceeb455a54d9c84f30b63eb6dc3bd58aba6dedb05734e4a02eac79f6545a3b705da5ea5dec9710e4407868844a3edef11d7949dbdae83dd00203870a23849f95602d3dc848064959c53a33b4d0af949c6c0d42834f99abdc48bce567287a749e1ce1285c8ab4669ce6e53558e33c197ac2e96a3d97e5992db7c4c48c5ec42bc2a1f21b5f97535710a214345eabd39b1fea121ca7c866981a22d06c547017d6e16aeb14a105ba22ff5b2304e10c948c0c4a376b9e5c2425920ff94953cc831ad45b3f81056b6f321d4c063f8323b0e23813a5a0873fd71d93f9af8059900c973327a048802a2585f29f9f81714a869047b0cc0f07ae4a9b5d398469c9832a7dfbb79fec3fb99c5f9910183a5651c2077f62817ff62c80c0f3ba5b89a19c8280f62b0162a87cbb2c39d98445fe49072103a63782c09e7bc3bebbb21901b081729b7db37379017453f090e5c672a1fa195c49601735c0cdf7338e0521ec0946ad2784eb1a5e138c21c8c04244d2c8e7e0a43c7551505aad3d85c9d640885ea8004fcba8e64c9da72c0ec19197732156278c3ad64282bf9590934a2806680f4e8aa14a8b030519ccf3896abc085566bc5757a467359018c79b57c149338ac2680c249b94fbadb134be1a911deb09add46ab710f930c4c24eb4298c0a05a1af583059b7724d7abb6702bb6680ce2fd3bfc73203d2a563f6d0b8ca54b0886998a449b70e256f22f7a3837263929b22e4a6c97d4141c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320b426749cc971c6735ac769c2072ee88407998399308a1a81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec325295000157857b664b548fdf9bf3924b508570b1a003cdb5158b4e61a8cc0054ecc9b42491bdb9115b8492848f0b6b236b963571ba882279ca3b6dc2532a481cd24375d8f9a199d955824a48916502beedc12c138998a14cd75190b9dcb65c5b20af7fb254b97bc412bc338a6c0b1873802884475636af09a1f222ccba2363c0b873555360325e18b2be4c33edc29e6b874eb74bb12511ab0364245f058ac90561d144ad230ba7882c893d9a73c4a03f82c5accc04031507971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13eca217b01647db07c8726418251703cfb653bc72e3a32192e489d334c53b91136d5b9794c96a8d3519467571a83e0b754b655c85a818d51014a15b03564b665a80df21264c5ab8ec8902be351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44763b304a19162abdc4234e6046109f99f955695580a8b782017e107e45575bd78cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 393a912358f736691b8e1bbfabd7a3ef373929bcd5413ec74e948c14fb4f6c03eb9b1e58430f90165cc5af167ff8b6a3f8da9d6e1d61e15e3a1d1797c53c4ec8888f06ff4f09d6037b22877092fb93f67f58c085f1dda1707a51ee4eba60291c59f027dac77bf8a70d630d8caef7a16016e7ab3865b6543ed7b413c2f2e031976a47fa9b9e4a65c8417ff7e454ff798941e5f34c57de545d5316d220d2f0f3a863c386a8632926cd5aec6e22c3743bf328cea18d0787f3fba86ed2ed70159df31db98e3e0a7cfbf604f90ed7efb99a92e8126d4fc965e67d9b4a054b130fa3db3f0ed0a98294c40d7ca6b2fe5e69046d4ce1f6ae5d55670cc1456e847ed2d7026c2d8604ed66cf146d7cc48c867d7fe1874c86ebb51c4945e2e149e7d13e0827616f502694b639378165aca5172718dac2187806556917b98bce68b91f9259fb62af2254e14e3b94af2ac7a3b8ed2f598154ef987332f82995cdf04e03768a38701ee44cbed47700091ec13150d56f72a284ab02862262a79fda8c6530ee1d4bd0487bc1dfbf27f54f51228cba703a88607c7bedd776bbac31a9457c92e6e16e44a7cda858d8f3237360885f2b68932acbc1c56e4d8b702dfde44a3b3909b825fa01e8724197862d4b15495a90dcdb1872f4e16ea0ff6496b7b57e5138bfd3170fff042410557f694257cc69e54793fce228c95523a9b7905932b4f4147c342ec54df67afa00b4aa44cc3564cb07faef73c025dde8808c7bc785c4859c6060ad33932d62a73a629863c7f821e234cfea7b3dbb166cbb7a10278311733e47b2b3de8ce818b9ba370b12eb2732ce0f824f1845d859a06fddee009b012b2bf7571e74f283dc419a5adb2f69a7867de48eee208835ff63bef8ec0b5b3cd4177f3f97bd68d770b28199815e3f2257cbf6b594c09636d2e069448450e0f492646b9a6c6efb0b206f12b5d93e0a09641d35b936f1563af0c1074c20d3c1c535ea0ade45c48f73b766b4937ea6a1e329aba02770141e6706eddcb5c639a8103810b29ee5a8167b4d45637ff6a77b6cc1aea1995703c9a498ccf81c893038a074244c3ad4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ed777aab04fb95f3dfed857cd4c4758d2d76a40ba9534b56b2749527ccaba763da422336923f83fda435751b6d2158abd1f3d4bd09e260e389b8a3b94e7edfee3ff68f68535069da453d5cc57cc98c97a6a2345c5c29bbe6cb49d28fcb499c83f19aa5876ca90ec3bed669fa35744cdc44770fded94f6989add64378f739aaa85f4f4b98b985dd44ad5820444e553660207ea537ab58d738b7c643c6244dfd26e7db5b34fe0749ca31b95a3368ebe987d66573eaeeabc6e6bb450664aff51e6e6f8e8d72683a442c7c15ffef95937c22d696706383d9e84910c4cfe4c57e487768d0bdd66ee79dde868ae6e4a7de57dc252cfcfed77a155bdbdd258ec84d9a694645ef93f6f7195ec9cd7de2fb5964478422263a554dae3529e7ddc7b7620438d324f6ece458a66d9e2e4d4aefa94c1efff75bc46fb9493ee8b54b333e50fc5abb432eaa602c9ce36c34ff854da0e359602e99cc3beb285da0a7563723aae266f9a7d50a6c86d68f1ec788709dc351f7d0112ebe347aa623e964eed3cbad45a6c09fa6f5d6ebdffd76aaeab527f38ef83d4f7e3ae58ebc5a07bf3e16c356f9b69fc4e37920089a64a6f37bc86e1e86b24cde956eb67678aa416249417f0c87a6fb9c88e96e39b7ace53543541c425655b2a5f4d5cdfc433ab68ca578e15c535391dc80db3a3b6203e63637a0c4ebed6434a1c995c094adade4be749a758a84cdc02ef7b117f77c75dfcdee33e4d3cc458dd89ebaa56a0c295b58ce9a315b3ae3e3ad7d0f9a9fb381e07ab2f5bd7a824e59140fec6df48f8c77418eaaf2455daa283e98430dc0a7c75d517836a7d7463e4cd4a42d4ab43eaa42d7cc56c5fe49fb921024d0ff1972a8f3bfebd5a1a6a3946b4e52983ae0d2aced04cbcf1baa86140a7faa9e5790dba7b41eb2f3acc6fde8537193b6ba5d829ef8438f8c90127c44b89de5778f486f0e928083b552f86f894ca6e638af03def15c27b33146d22b1f9d7ffc5fbe74e680a89535774c2ebaf59b158f42ca50ee75a7c906f704bb5bacdabdd2c3d4ad837986eadf8c9980945cbb29e64ec1cf64be853e03beaf4954e87ebcc6700b95f778cec6f514b10c58e323ab7f013904345308601ecf1707f8350b9f29cb39b261580c3dd2651f96e28f89ab9c1ad86cf77cb3db7aa8a05c007d0a1a93a0a83e85be418a7f141078581a5e60c25e4564691e11b5f16171564a1214d8be06c15f6281324997a98f6572adfb62612c6623d4c9cb24bcf0d896af9a16bfe000354a41f9720c53f1574f97c6e8a49886484830d5822751c6e4c94df54aba2ba767b2b3199148bf8a0a89c620866f1ba52c46687af31abc6a7b4fea9e5d6c70a5570f3d6a6113674c92173b6af4902f614f1d508b3b456c406522d986c31aacc3653098b0985ef1879b204261bba81752425d7cd549121983ffb30b17e181d2b8b4dc049f248b55a25b561aa54507141914e580684395e332225089bd29a934ce114f60936d9ab50f568362fcac1153620791d318dc735253085c8c164719b6c0b426c136a311d704d009f226fbd340ece426a25274da929bf5a206b1520bd114c754db2dab0b8a881c03aa569091f40ec3e38422c3b8d4b2c77373853e57068a591663446b17f676bbfb941abc0e1afcb01d939b426a551417acc95988d712600383063dfc5a6be917c3e4041ea5496ab68855b6caa6c92b463692ef2390ce797969715141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e163144d56a191e29c66eb75f86d6baa9e2320b43463b300000083c49a88b6338c374341cd83c1c15266fdb266e1e0933086c7358d82770aa652b7842b2b9b6f9165613d4a27298c0125a2609885d29715f9cb854cf6a0c308b36697cb1f5b530c7625694487252872c70ac1ada8b4959c681f64c46c5ccc2b3972b6188909a1955d99b65b0b80aec1770f60421cda11d7822621ab46fbba61cd0dc6df4082609105839d80ba850c0a8342be5a70d999386167ca06a485368276b4f7340cdc0a9b3010c3fc3726da1ad68043c1665b1aa4413231455078cc898d938d2c5663b1c200fc87a3b2c2b5c5b0c507c1b7f12ba711680951ac8ad9c7e430345f2f6ad3eb9317b044103a82bb03949eaf288b2377b66f629268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf8459233c598a48b06d7474da19ca85aff6b2b3303b5d25b96088c52a08cc7f1e87c5fd8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = 68f8faa185e730d2c069f2c19a319cdcc138ee9bba414fdcad84200063554fa1a49e182b572800af2afd4d0ff9354aa4d5520db148e31c2ba8e543964e07b2fedaf011dc760820dfd9b76b40883a69c9524a9091864c1b2bb79f568d9ad312760480f7c33b1068d89e5264b2735498afebae7ed11b7bb5474ff5bb87923ace45ef4ea7aaf65f0e383acf89c795c417434d21cd7b92ef27685871a0145fdbdfdbdc93089f999099dc060f78ca73056851aed35372119dade9b52039af2388dc3e39e612bd0a70a022a3ae486f11d39632a302a02ad0faeebedf8db52e2737b94145984d0c3866599247b65e566ec2c7cbbd18f3ab2464b75ecc9c0f0fe195e1775fc33ace93fa322060e968954045cb3dea4021ecb89df8fa965095ed8476e3e64052d2e5a72ce5fdaa36ac07a79aefa9f2ab44b31c11d9972263e9a1f04ca95b7d66ee19f97535737f50cbd379ad17e9880abb5c340ddaaa0c26e4ea60a1810dc83ad1804931294751c98d48293364bb3fb8780717e9363ec84fa3e7bc7a21849fdeca93674b2bb90cd88eed2c89b4b989d70fcf49df184fb07b158c9c3cc9e663d20f1d0a5ba555a09fa9359e18d0653be2bc2cfebbbc69aea1c64e8e0bc9b8f0cbb70d60881f86e4340278fa0b116fd36f18d40b4bb12455ea0bb1b4de65f8eedb5ffe7f206e50349ffd501708d452f9d487a9dc6474bc15f59da9a5324b465ff6c2c863184b023d79f02ad257c097f7af07f944a2f4b8ab01076f4ac40230d373538826a63e7d8b451e93e792cc5506aea14581fe1a69d5bb9e96b585967f78500e7bd9b023fc0816de2979dbfeb1d160939570296830e32bb9ea54abb7dc8c0807eb22bf2c2ee4e6b96e1f06352628e64318e5fc0a4c466df465cfe0ffba056a648f4e183dc37820b57ca7f2dac512e87c1bdbbf8b8cb8ce72d9e183a26f957203d3b91729bd1984203ff64ff6ccb5ce1acc1187e8df4435400cbc7c3723f4efe3d876c5e6748052e5af72cff11e07dd7c5e058ca40d289f4d919986015add25ac4d1dbc559bd6fda9af76e1bd7c744777cd5f5a7d7792aec92e0d406377 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = eb7abb66c3c749399680d531ce787eefeb5a81ce6c661ed56ec3e4568c776fd3f0e496c7b55b54b253c66a1f6f612c3a53a5f68826aedda5cea1b7d77f946a6dcd435c35955087acaab395328c91c753975b97e6b3647ae9efec7506e4fe56e216749172cdd0fcfa3c0ca38e1db9e5c15578be2dfe06234d59e88c51047f68c4cc12d6dd0b536b672c3e6a9a322db894323dd532c7bcbfc68cf9d775d0e7f2fe7bb9f0fc7bf8dbc4c19547c113ed2376f173d3d2b24ad22b4cd9989e434718eb7d433834446ea56b43135631942e33fbeff6010a3b6a07424d2c361efa7f27fb65034ce7a1ac3ea95d86b354defabba89486f808068ff5ee579b356f6a186d9653eafacfa57256f5ab88a36a6b3ed5adee902630da5ae01b8445be9ba9738a761c745370aeefcc1e78a6a5680035ca0e6d7d78dd7046eb85691e3cfb5ad2fdfa8fc207d0b9db8eab78f96e9a8e34cdeeb11c81a8a94def449981747caf4e394ffc5ece2581e398c319f557448cb4152b30127651992de93b864a0a7efd5ba8ff8326750dcc472cb356dccecca29ae45ffadceb98d3e03c3644abe6464a673d3c4b67aab5c2eeefdc06377b4e84706dc4db0b3a7578d60aa7dc64989000bcab2efaf4a16fda3f0cda16ab67e6e557870e64b194b59d65fc19aade2803b0fb3be306ea6b0ee687db76e357739a3c887a8ef551a923f474bfc000aca4b859624e79db6eca49b20c43656397169cd0e7fae335f48f473cc0192e9985e7fbced63c23b4c0fe036323ed60629e77d1984ab885bf12cdcd2005e9cdb8a447356847d8b95bd9ce3285702286949e3c61c0c435c8f3e2d919fb60437531d8490ddad8261ba4a57753662bff8543d7d0bd71fd4bdf0e0d5d6155b118ff98e2a84a3a34bffae668d91b523529fa0b55cbdd5b723f8e91087c847c1e6ceac7f92c17480065c93ba665656749c6264ca53a87b27485c1efc0248933754efa58c7c0edadb155f5cdb19497c08baa82b7e908639e462fec827c76672d9cc149cd7105d69877f893895521a994b926ddd01baf081aab1278ea9f36f20e65531f389921cee0ea3e401a986b25b24c36a66d747b761bb2c2a09415fed46551c6a26ab62819aa605a84c9d164b5146c6996f3a33475aa76d055ffb45617f256e22028426b71ea1404cecc96aa815f5cc804d83bba5d417caf64731906b8cdfcbfbaca0e7e0c924cd19475a88668c59f24b7b0aee4a63b936942ba263bf4533dd29e7f51760ba638702ccf6472305e5a0d404732e0a220b269affe711db0a8c2db11c2573b7c3a83b673d37ecd8a725553be79755b803cb866a90e12a4bf7d8275fc7ca07cd20ced0ac9a45c54953220d5caa8210bcb3e43289ba03c6c3a982b5b2d4b73853b1b7548f7aacbb0a4ec2bc676c55dd594aaf630ceeee7a58f076348a09fbb5b335c43535be99d552298acb1bffb30c9adf1c5fd221417874898132c00b83cb367bd79f734fa1c56cb63a8652ca5a12226961131b14018139937c20c82ae6964e0f4bf06f30cac7382bf2341829236ef27119663c1bb34819da72cf71b3faf01460b9a20440947452b52ca4bb9c4eb9cefb8c1a308b2dcb20dd88270bc71b9e95a2c96306ca17c769d301e01021775238fdc6235f89939b47774b5fb5293d2cf4875a698d33827ea2146b4c3aad66f2c918d9e638874dcc883a2399df38120b8baeb9a52b45c6d0cb2a3c766336d0ba7fbe55ca5eb203e26337d29438641bfb3a29d50500947064e65f7319854b6756b2e40c75b755ab983b52e72f9c5cb293e2aa34cf2b23ef9868278c531bf395434fb347f29c079395f70f62342fccbe37cc7fd4ba1eb49699ed30dfec751157003f8bc438381813d0c555183524ba8a248f531495210a6947ed6963da96c85af7bcb1fd8161a07c707019b67f373c4692c27279e67b677c2c4cd42b33c4662b012ba8a59b19391c25aa846814395119d65b585c39e738359a24bb0d31b266a81471ce25270d0715cac1c473c10270039489aaa70b5cf093ac930a91e9ba356d6a76fbbe8903781924487ca4cea7a67558e55011ccd4190c6ac0d8642357441545b477e0538b31230b07b17595e55340ab681fe860b21b9b893408656f920e8a5599fe94dea1b8ddc7a6eac61cc0457299c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e9911b6283fc6dee66e16d411fe39bbc9f53c30bb54f05044b96c740ca051c61ce40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = 762d2b975d7e97164aad923f4551dbbb99cfc44c146af6e270b3288086ce9b768dd9fd07d746a8f076d496729b50b44f972cbb53987762f76e1025741f203efbde6b0c2dee48d4aa224df0ed8ea7ffd70e80cbf50a4dfb099ee701fee01cfe50904e2f1cba82e7ef507777f0ac2d21d1a285cf8de33d59fded7793fc05b7e3ec3176b005e0e9ffa689596c04770848d7efc999007b762d824cade5b9789ecd06d1c73e7309a45805cd167516940dacffacfc9d049c4656ed397c3c5c53606cc927b5442f6ddda90c8dd89a68cefa6796d6ac5c08bd2d337720bdea8a25f0fb656c6d548a326483d6d669b1dbef7f33c26355f34b5b19b0915f7ace782168fe0a112bd4c2cf770660a421771772a53dce19635a4676d430819095b2b29f1d33d742e4d9a6b57bf8f32810bbd8c0890219fcb3c73178264f2984c74f5ba6ccdaad83804ead9ee123e86c394adae7665bc2b962cb8ea82a73b03aec1fb90c45c7d0adfff1acd946ccaeff9ae907b33d01a900b9c98ffe78f22417ccb06e8e735db8d1a9a4b055ba12b4032c19875fbb9efb074d3fd67a2701b34976ef595c8ba84b82af167ff718d14a144cb5dd593a5114d18c3cb8c2f552511def9c6c6d9baccf9cfced749ed26d675aee42deaa64dd3de0985d6eb87da959f55a55151d9b35e6125d0d297b5c70942463bee80d8fd918ce36dedf8a5f7dcdda38af8cf7e227d545b8237a690fdcb78d0fc19d42e872faedbe9b959c23fe484ab831ade77b64d488ab803b9ff82725ea57880248eb27596f9e12b33cb5ce5396158f74a3f0d83af6a8032ca0898b9e436d3e8b3406b5aa6e9de8959e2f215fe4fe444bfc56a97292eca756138556a5b4f074533b484062b0324df72ee28609b69d4992babfb15fb595fb59425f82040f0718a9d2b36154230ac7583079cbf90b52921cb882eadc643b5e601cee1d3629be8bbb5a068cd97a93d30a768a8ef0ad644eede70506c92ed70d6d5d7cf89dc642ca06a3ae69ee0e40f496bec30dae4120bed2e21d89405c062d029270f4fbc85075551858fd6ee48c62738a748593b1685b922becf11b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8cb5e83678489608f78e5f56f73a3619466dc23e7bf82932e4b6fb454657b756c17e9ed928f742105b41ff16531c649f9559de4f6a53b2ccdeb36cac6195ce6cbc974dbd32cfd5505fb77bb3a6638a05b23c47c5b387554fc88f71bd6feb8a59d039a5b727c2bfb6dba0e785ff0c66cf98d78eff9f419e5713563b7f33bb8abde4d27b54be5a37f8fc8ded2d9b06ac8000c8816ba97e68f6c01766788b1b732893457a38abd2798eb179f0678bab969eb9e4d644eb2e3f3dac45dd5f63cf8782b7f9a5f1fdeae40959921fc9041a8823a88117953ae944cc064e851719a66b2e9d9cec69b564e12bb861f869d50f456c13c73019684edbab9fd2fef7703740ce863caab6d2e9cfa766ff59ad9ea21eb5b9db6a6105489b3dfd8e1c58a10b35c7341441ede777dd8ecdd6c531e416874383e803fc95ead4979e57676d15d04a35f6fc9369bd96e45003a8b6b3bf5b46997467f8a658d5fb89336ef991eca7f33c77e8775969164634438c77b8eeb86c25b60967a9a1df5b50c8a19fbc55ab656a9e354e0f8bf0244dd9ff9d7a9246ea3ff6d353ef5c3a2cd66a8ee3b996b86703d8712544274a8975a5855cd39181be644a6db0254ccc9b38c3bb24ddd38b34a4cff0cc6ce31053d5c46aea856e340b4b30bd69497bf3ba0524526fdab58e3fb8fd4bd3e05b61aaf5d14f5684c52cac3e8eace58dea4c7e99c93a813e549170c5624339e4c0ddff8a28a3a95a3b1225de8d7ba897e634a883541084e001b49dbe6b82bc5d632f0846cf7fe0bc4c35266b3eaf434ccfd885478ab671c6ac1238cd02b3ae1b1b76dda4e8fec3d498a8683e1ed44587545ba5c5e49e9f7996ce6e5ecbfeb65fd61538f869f462faf68d07ad293f5094ba467c74d5254cd7ab4d5ccdfb9dcaa5993fac5c407ab2929fa3b81462b9bb6e783c3f59aef2e4848f350fc1c63b4e9dbe3dcfb894f29c89044b973abdc4fb19caffde390f2936f539d07c39fc5d7cc22e3a3ee05bf6f23cbcdbb87eab79abe9288b0544f20ac3b8e935cad8a9494f58ab205731553856295d8a3d87b64333e4055bf623434c541be96d78c8b0141c2b68b888e674a38351470a3c831923aa3c3e40a2127a28c1a8818d42e4a48c036191681bcf982c0f13a79d643af1fa13eb32444d1577e0c1795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755a8199ec36c2c128c68fa5b5854348d55a1798054ab98a5203dcbcc5121300b15026c8b4d1aa329b804b13e61faaf672f0a304db82cb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b15211950b5551f0722a9b6a7ec554567b2c975af35b6b88041c01a1f182a50853998cc395c1081e0d755d0fbcaf69f85df21567a0a24474571d2f98ba93f37a0f5941fb8204b0933cf3cb20a706a06359cbba272c0df68647318774939d18528b8818ae682743071795d512b29c794cc8a6c0e4b827c1148ebe2a0e72fc50a3f71df0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58cc229d9623983564da34cb71a729abdccc3cf70bcd7d20aeb82c9d306464e132a6b9989c8561d90824f6796420e8b8c08a0bb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943181b16f747b7d04a7f6996983c494b0d527879366c3a4a6872a79c8c3aaa13f11695d36065d7843acbb04014539992ad369024f56636166990c23c661f34a584c12ba06a16aa582c887015cf96b293757a041b53ec695cb520960d959d96f57bd6da44e40024f5e04a3a135a1f112ecdd57ffe459bb22c84008d5a2ee831823b42102017f14a71b1329bddc07ef7bb02e8ba40bfc64362bc369e490675dc68a9c0b54a91b43386cc7a4800c9f60f2a562253904c71924fc7a9257b94aa9f78c6853a85d09ab7b07101b58309424420c744076c446e7e873c67d67a40cc3993d48c1a81495e54a5fb1200d497080bf21b33211e919730dad71c2a1a75ddc983853cab3cb55a3fdc0d778bccb2c42037098956307899123f7c5b7cbcf107fe1788e55c67fa65968f57bd85b53a29005c6a2c2c30ecccbf09904218390fc17f4b07aa2d350e9953705da8bec6b4048e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433e78d350d2836d1d17e6ec375a0cbe0d6b2afe1ac036272dd41f8aa769c9d0668ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 27579d6741c227497fb204ca6f32e119fa6b84377a1171b00f000527e5ce0ad46ae7c20b14b7aa32a048bfe7e491a500853568ce87fadd3a3266d389bc517a99b491329435e0b05d5b2697884528badc7cd42b91a76676a828cda05c94a497815a9f24b6d6073b1568e7ec22fbb51464ce0e78a4cb7115910f9f9c4eaac8a6cc514b4f473a5c7af3199b1296bbda4f71bf10e9001a88e4c91969859ea72340c4c1aa62d58586a9d4c03f946644407d8273dac810d9c032a890196aae72f549b0ad8bb4e15e1d8b07fe2369e104dccd4de63080466051dfdc76407ce6bf2dca8fef785fe60af4513d3f2d7753727b151fd03e9494153ea4e04c6593efd5d162b978d960499c5454cdc3da160454f6bbb64161661921607d07a716db783cc4b2c034e3f95c0ea7886a875c4f4904e29aba83095689da0519e3e9bb1d5d7edbc5ba20e266453573f9a4275f9fee4a85baf8bcedf1eaaa1abcd57169f97339100a784ce74bdb4e448dcc5d6d4566f646ffc8b03180ad0ad8afa1adb11553434293e1af8532bc87b8a7fcea9278eedfe4f92083e1b88a16ae23339cacf95b0727dc0a848739933b150d5eca063d9b6df4acdd3b70dba42c22be1ff37ded54ee50f439327d1b8e67e8a611036a5139ee2b97b3d57f28c1e0f68b976a1de23e181f68553872a5bffea7d7cce6001494b20ac48e9f645ffe5cdfb1edb93f36b33b91629eda556fc121571f6f72f86183adcfb8ba497d3b1e9f9055f0324b9128e37b2828cf99a80e4ff4155eed0a86bfc2da7250966783ef4aa91c38f2821a58f49ed947db17494c98dc32e33733223399f6cde4da72370ed8587917efcf0251c1f51099201159457e44ace6a7dbcd3ab57fc9aaf9a7eb0f3bbfede4b2e6d257fb6c7fc9ffb9ffe4b7e13cf3dd9855b233d781cb0064a00896986afe00889c40c33295c704f4a0808c44e32ee5da7701290fa5352fae93f79995ef6f89d5e061e4428aa73b10e9c4cd82c70b713d009b9847eac80e6f510e629858f2eb00f1d7eefe460cbeb4f10a7c6c508201f6bd916cb52080cb149953540e97b1b5d2365a783ce3d4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 406d9cd4aea40789a4934fece73d9782d8a57b44f07eb5d4739fdeb3a8f7d715c49809aeef13e66c4e69624b7aedca838e05f644c8422e4632173fe2172ee7188bd502dd8c1d2d417044a44627449086847b7867e1c7c4522972508856000db4eb0673d1ad7ed0e6fed7f46b0c69cdbe2889b295b5efbaac4989629cd74311097a78fca8188460df2d87d467b8f48fb030f5eb2ce940a13f675ed9751f6a7411fcd050fabf4b3a39b678719c79fa5886a4185f61c1a989fef7d255666a017e303e5bcc9f3598cfc840dd8ff4ab0cbf4f547dcc5bed7bba46562d5c553e445e69a221bbe680985df7df8ffa8cd1f7e99228c77926ea4ff6477298f8654528960326fc418bb33b8f4a0ffb8c62d9ab5939cd22d56e5fc8b087c96018e46aab76b194a3aba55f80f45de300edcefaccc5c76d50b7ce94125af21cef40e1cb736ecb523d84f91ffd8312b666b6e5f87c56a70fa677075e49fb13dbbac88fafba8174c349b2a760b46f96a66cb7ebe9978df6f3d064b5fbe8c2dceb34ae2882d673a5edadbd3b256d81667f11d951f26a841643eddd0c76bab6854694c43eb5dfea5b55518989813482b054845334e0bbef8bb99dc15246c4114746e424a8db0d8f3886c6d1d99d7898425ff68d850bc0a6c8ff7f04bfc12e6e7138ddc6b44930e7a7d5b870eea9c258e7d29aa936decb5c574bb1d4e5f44d6aef1f2371e498b70daea035e4d3d76d9fb0867e4eec9e4c46650d1368eb7da8193989c4b8b9b89fe93d25f14fa9c37ec64c8584eb6e746eed8698cc8bac3cfda4f8d332d8b6ab888733b1dee5885dbbb9e73682879db319ec96244a9cbdc68f2bf985833009978134cbfd65cf4f906da40efe82b8b3abc2b4d7f765cb55ffaf96277e02075271f9d1cb46dd8c7e60da057daf95cfc7bb5cb59563a0359800eb78def9bdacbfc655bb4af0f7ee98c38569eb74da86c2bb4dd20286d28b0b59d95af1c5348ef34341fe39fa204e9fdadd3030dc7b705f542888efdcad4c25d86fdbb3650c2c8ef5153398e3f2d338cd7c99fcd81b80a17b9c4ec77f64d44766a8d29c9645dc649b23ebde2fa2cee53ab17754381f14708ccbbd3a19ca2017a1637b08f2e9344ef76d5fd0ad937b027ae58787045b9da90acd172d29c02f2ea83b378690d6e694eebc39dfbbb12e13331503bccfa62b6058792c2642b365a9fc687661464768221a80d529dfd9abcb15813a4a6aa012010ec6a008419a6c8238f068671dd1b3bb3b10ba023aea01a90513518d5c6582329ae43c07a6929c3ce1740aabc291e440f909362c7c8651a64e0eb84d82448e9439351650318293010d718e8762c71dbb6cd0385c5be0c37709924bac6b6783c82431527996523ecc9bb462a1eeb0cb6276c344eac257bb4c4ab0124d6b1b7cf7473c050e9cb9762e856786ab1b5a9bcf69fc90318b3352e0481aab1b97279c088b397b419cc4cba756451e67628f535642b2d0cf71644e6a3b6f9b5409fbeb284356812d613ed338cc28babcdd4b6753f4bce7a7c54b077a5f162e96665a3299b938ca48ac0ccc7710bea5384fc4948dc1b56a1c7272bc4a3fdf53706dec2385db3767c4261e98c49164683cfb420c33cf7ed68cffea4f43e41da5ac727e87a981877e4ff12329e91ecd524790c1ab38784d89258562bcb5841ba8f0f17ab17236634a7019a520f48695ede951fe9042eba78e048791896844025a37575b2be610635ad358d0ac7ea3bb93ca4c8dbf6b566d00654f1541919650c4a88c9a19b4444a5cc7fb4ff087552fe1a288a15bb0941f71f4568ad3bd01c1991110bd2f755a9c7806ffa005803733e2e639e2da05b3fc71dd7a42e834190e4872841215454b294bf32a48c096d4476609e792a4e5465d5750aaea38d9eaba07fbb05d10950ce23256727850d97e16397e9376674c37be4fe3187c2842c797ace9475b1b42c10910270d917ab6cc42a573c51339c04c56a6b0150868a9a330620d886a5e2103248043b44e005a7344742ffab697f086526691b073aa70914b391c3cc31a83ff81a11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb07323c74a7892e5b3ed631370a65cfd4b1a4212348e54506648ccf0732a36c9b9cab979ac6c4c16b9ad0138860a392bf49490068807fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5820c7564d087683c0a4864844335bcbd62afa1ee542c3c1dcd8b72c80824b501c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = 8db4f31b77a098ca2872b02e77df4b56649e19c41cea2e1768b444fe945613d7879febb57bbb20858f50c1a6b6e46da00969fed6e088d740b90d1cbbbfeaa04d1cbd6842a7461c05517136fd5d76bda7d246b5efe5474ea9e6789ee935991f11d17970610c211404e576d8a976ebfbf87196b0a9076eb11d02d0e7f9b8a7bd603733adecb2f16343902d3e477e1eeb6bca301799166a19dc61328f903fd7d132cd07b28bf5715ded3d073626dd69eb14db57036b176e6dff87726cd5ed04ac02f53b49107c560658191925c39a030dbc6d7e9777ff2b6d9710938f455fcf486d5abe02dbc628c1ead2d20e7b1b96f7e7f140ad331318da534708573e84d8c2190e309c68e7d89f62c986e9feb4c23575535276704ade52623074b53dd967bc40b23efa52d2caad7174b9eb16bdf3c5a396ddd494e6c4361ea12b74930cbcbbfe961410e753caee1b36e5dd9b210d6768abd092a419abd917bd5471702f678e882a848d4f9350b435c8e9217959a0e88fff18ff2b0ae6493c6ca3c2a58daf37e770c844cb210256beef3c7efe5d45c98e1b9d16e0fc334752b717fbf1f90e50123d050fcd5df3d719527b78268214ec6c2faf45beaf6707303d18d4b139891fd3bfb632b8ed27e39bb5243fda10c0e093309d22a63939b0fb266525d7fa76fb3727a325977f348262051f9dac4a0bd0169454e2eabdd5e62e2947b29e9ec6ca1389963ef104a995929df72051d7e29902fb4c92efcf2dbb03596279e775b30601cef58d875d07fec568c86ae0d2743093535ebe1d2485da2dfa010626af3ce158ad4f31f48c3735e59aac57d3d5697e842165388836f85301eff17ca0be02cc4d766a5543bbdc3b686b1498a4897747a8aa75546ab90aa6ed033d2e599a897693380056485c7f79d721236bb006f751f1080971d2968bdd380b93a56c852197d737331d0bec9b571c35031c68ed9a40d0481f331192e55ea1fc3f6252055dfaaa010ca17b3cd06d0e2a67873695695c714e57dc1cadf3a58b75dc6cb471303bd2c78284d6115b3b37cedcb7441d10d29187a6f15e26fa13a54314b3c0e44fe608 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = af54bfc75e82aac49a796ed8f30c50494f8b97fa3843c48a413f397b479ebd8cacfc079444e54c4f7645750ee518f73c8bc7bef1ae8f5ca7a2cbb6312d4c63406aecb778f3c7a53cd40eaeafec586f4fe18d3c7b966a96b53f3e86f7846fc634e3e97659455d4cbc3dee95a51955fbc8d5d089d87440c7b2c095ea6309a07bd99e5f3e520eb458b405763c9bdc4b2f61b0f4679e7dcd254a5485fdfaa747c5eb4fdd6cd5584e5e7f7a664e2636a89186f595efd557177f67df5c2b65ef67cab766599d7aca5e6e8475239bb649437de98d79c8ec64604f3a9c5eb8be13bce19579269b6c36fbe6e404c2dbbc7ee06c6daecbad02cb8de945c1c8cbfedc29895508f6c97dbc29e582a91db27dcffc11497aeeeeb50c477840488f8b5a3fc84dd4417da30e573275299e6ccf52628ef55a0d743bf46c21ea708925a6ae27a8bbf5a3f31cea5c99b0a84a7e67aeda1f85842a63e8c24a6038383aaf5940b1c8ac577359779bdf1645de8e68fe19ebe1e13346dfaa90e24fe86ea660f9dbf1776b4033c5c46d987fbdd5370bb730204733701d66fae34c075ae33ae89ad33c7464db9b4de654608bc71efefc64d7cc259de913543c10d6c77e24be429bff4edd88e5988c5a76a20805e8952be4fa95711d9c6fa6b84101139627e645505cd0ae6fd9bf0bbfa7da396894f9309ce66b264f4b66a852ef4829cf3c93dac66a8dc84dad71c2b4a0dc7f9cf2d73fc98855a9e66ff10693bb36756c4bc725ff3f31bd75927830f3e55c536d7347fa7a09459635166c7f05834f2bb84126cac8a4f1627a8217b9aa498e61ed37fb98973e649d6d14f3b03b7b5fed63484eb545dfcdba685ee9d4c4bec2a844154797f4866af31dbab216c1c954ed4694c0c7a969de1d33085f5d7b57f2552b5489e83de29893fbf76498969534f8cd7bad4931758be7dfac36983d1ecbfde24e30de6bb7966b30a996cf2f0c4f83e787571f9587dc5e50b4dc6a5dff840852f2543a91ed63d22755fbdc90a06db19ceb33aa749674b6bf03b3f24e1891bfa641234ca963ccf8968c3a598ab042ea5ece9cdb47763fd918998529117dcb33b7d246d122ab27cb961b63bbc579c27f644213e6825aa1a0d4b44918784e1954b469f106d6464da8db4de1eb8cab31317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f5a1443629def269cf7b98235569c1b396fa9164e2e0336cc8babadb160b082ba8edb209a426b25c435c35c0bc9b15af0d541d0ea5514ea354b828eb3772ba1ab1c81768a1e286ce2a01d1b900dd1ea9fc6d685f1095efc105b71571ae967bd9f9a02028729bbcb53c6a74b37950ef023b334241d2555845e882de3636cdfd45a76e1265f6937130016f8e1710b748959a8add626cb79b65de177c06ba2cd8dd759d86baf1d9b85f4da3b2ea9049ef9545b72cc0a6a736d5581c57a1d7d966f88c578dae60438292cb3ac26909baac0ec8d74471d511bc7e928b67913c17e4cc26818b2f301299da3910458be4bab41d3137cae0189225890ae91a364dbb683288b8d59b6619bb786dcc98a51910fac5c65e05b3c75a4185b99e00acf009535adc07c269aabec98adb1195ab0b5a623d448fa454e90c2a6be925ac912b086b31616337661d0a6ea7154e937a39d1a60a4b7923f4b2e88438386ec879196cc47d9179d382546168a36865246f07b86e48f3629c5b1bb99c62098d800cf2654acc6fb8057d25cd2d48c2cb71ef0e917bf106f99b35df1830d62226a1f7220be6c1afb229982067439934bd27b56171ac3cde09e2c1b3dcbda08c386355f328dc9d01827ea271a43651bba49a5a66f01966cca037fcf02aa074a7059d69de85961c9120e6d89349ada3af4d41175a6267aacc9637b8cf4d513a8f6b3ebcc9319c25064b337c0e90a88193e79a9810d2ba9b0eb089e437f473b9f5dc4b8eb95b24e1b85c5d0267da39bdf35831c1263fe923a2dc7bd54a5210e38203422a6dde30ff9c59325d36e99973e3e991b4284c06f673751bbc8c99b04c4990610dc2906b27369b72187aa2a13791cdcd47bfb37a19e149a32f8cadd638ac0e071771c9dfc58253a864c0e15cca60514f545cbe161030af806872ca2d0c67f54e04b4ca55f41a54b1de405a22ba275a1b919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc56eb5880e9d9d0fe7901747f75eca1996c722ac47b76f34a4dbaaee0ef8a611bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 0d815ea0442fdb719a6b4405d510615c107546c0bde2ddba35109d2ed7eb3383162cb686055c8abf2f2c28c1496c01f88dbb89a1e09dc3a92a618d6a039741e5f979ef5dcec8f1e34835662f0d263a5320084f4798da555d9e3478d75400ea55b90b44ca66c57feb23c7b7e057cbd3ff380587c7c6432e3d2edf1b82dd3cfa8a49b989d0346ae7963e4b6a67c3b85bd3f207561e3d3493929d9614b9892814e5bf988d3d6566404590442dcb7e9e1e738f9002e279f640c9a62f092c7b01d6ef86ab0f45e502553f013abee01a1f6fca018bb04698c78dac494c6f545246647ee370973430d0e59eb8ec9b8e98af04fec8dc4ccb4824cafd1dfc45ae9dc53cc869ee426dd4cd20e0e0b554af5eaca43361d85d50e02465db2b4633d6ce241e08859848ea555e3c84a1196076a091d262bc353cfc28899abe749d57d4b674c10b6826f01c6bb33468329b7954ab05482971635a388374758edc6baf439f7ad489809bb72f729c4890e43654c527906e26076f590b34f19d48e6ab9faa7a6560d187638d2f7dbee6f0cea42dd885b7d6b1be159a208d5537b447b64f870f087b40002068b149a1aa6e25e173298cdf8e2d6db7ebeac3e5ce590bfbfebc19c2bf6d2a2d4253e90fa9b7d8797b9063a92c4ea8cf2e6141817535f5e21055ee4ee3b2f166f9f69d1cfba707d2849bf5d4dabf6bbf1529ad2e98dc74ccd1a65c93ea176d214f212aad00fc1aa9f832569c065a569dc69cef444470f0c6dcc4b310b31fae45e3ffce97e06dbda75fd156df65257beca07cbada601fb5d1d3ccc5df0fccd6b54aa40b06ec064532cbc1897064e1f0c7ff182decff960e88cee4834b5fe3ee4824fea981b47e7793da73ac710972e019665eef1ae92266225f24b01bc008a45d3561a1aeeed40870cefc8a430c5c97e461adb7869cca48835ade731d783be18d12da0beb78190ebe334aa4f8bd790be4638f3f3839d94adaac268efb7d312a9cedc9897868fef597e5b145659708fc53728f0b57969e2d11e7c5b524eb30938a101a31b1febabdcafde3761adff7d9a40a6c29337e3f1dd0d1b1d298cf40 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3a77378a26778279ecf4b96b2079605fdfdb738890d0c73074dce6250bb722d4a07d2c4addab34ed49489873b8b1ae310b96aff2b77e3bac6113f3446ab4e4d29ec8598c8207e8aa35b684e718cfad1eeee42d93de65346eded570ffdbd91bd275444605ead0573b33577d572489ab498f43170bc1cfa87e0fae83d79e75917eb358b94ca493d458737a9fdd85d0249a2a03fa379ebf259de6bd966f23077d83a6adae2f35c8de89239da67e485c18dc556a098a546cce24c5f0f42b6cffb3f0da1f31b30ed6fa0a6efa3d44cf09db991ae2bad553a5bdc1e29761e4c7ea5a08ef2a8b834a5bfb39b354c8bd719c2d4f86df59b7b3fa09cf54c2ec740e27922089cb4e5b5955a34fe9d58cd4c5bcf8bb52453b848d8fae3a0de54de978c974b5bbbc7d47c5fb62b398b445fe455ccf21fd3d38598a435b65dd86bda4fcb5d3b5e4e528506abe84458f3fdc08f1e6ad93f8c9eb7b5e313327cd645ce9c27dce6fd8e26f97664b68a01a887791456e8945d22d935fb3fbbd98c45ef57a36edc73dd1468a0f1df3fbabf435c9f5b1d88e37177789856ae7de5d2b753243386b85bbb879cb48e91ad381ad7a7cea427823df9fc9d142e67a9a69bb031b7a7b3faaaa9ee886977d29aff0615f71763d5538d9b1a1bfaaf014c41ff38afba9c2f1e8abdc6bc754ba5c52ff473e378c84ebf50da85acac43654ac5ad416dcc50bdac0eb626776d1afacefee6c8e04537f66a561b93b39da17acc76e6abffff692ab867c19ef250c5a452bfd182be7fb889d2f9ea941d9ccdf6393414e7641688eb73d5bde148e034ecd4818c8f12c5524577a6a4757eebaff70ef40852df170b4353a0fd6e7b8d0c62d5e2b036de34dfcc7533fb0fe7f72d8a212477188fe4ca9ae398b7fc77b858becba4d4f75ba02d4b8a74dabe0464bac158e531a7b7bd858e21ad159b989b873769884e14716fc38bda030d3dbcb2793cf5eb28eaa378e2d85eaadd7de2b527396accce8bd1b285b8c3cd6f23ca77fcdfce32aee4a6b53abf43e13a945d38c95f3096a1555cbc5e852fd248cba66991af865a926e69e383a3ebab427dc0b5977446a8a2769da6dfa5aa672b16fb8b63a7961433811b6f0a973935587f60c8bb78326448a89bb291a32f1406282c3f8772a4e2b43ec8209fe907d1ddc8d47584a822b6684da85a4c54906320a9169118b1c6eaa058dd3233f13922e249932f65ac9f3932253c4c1e5ac9595d5a10ca6cff03403b641ce79252ea2b999365c2c8ae62b4f369c45eace0d35255dd4703d06ae06f22c25b50d312726e6165a968587a206a7ff789c40f1a195076dd3340f0dd8c6b3049be76b2168ba6aced5cb794516432585bc5a5deaf09bc5eb3306f7633c82bdac28bc27cc1924312462e48e6fb087d3a6b61a4a21e1a8917fe4b2c0c13570d26e8830a0e1923e649a756a5216844a368efa096d65a2c4c3102f80841a4211960070e1ccbe6538be5c7cc09469c76a37089a163aeefba6d340cc18ca86599a7eae767ffea39403792853834423920f2e026e2bcb6a40167e1fe504df7908d1bb7fc8c36a68dbbd30e611742bb9ac65334ed34dab7a8258141e0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e27075c73339d38b4441c7a4ec79e1e6a60c88729a26b8a94739c3b807141713650920d6be7c628551cb3169b3de62afbb746323400411b4039c16bdd4c7ebeb039db0cb8e3d1af20470e5a5b154a7040fa650f69dccbfd44119e4371d527822770557158573943683b32a80ea50241eabc322862cdd9924a00443813b6ef4a7b94fac2ba88542b4454ee27b54edb090bb688e7eb1a3fab22a11a065bbb52a66069aed1cdc3e78d36848a1f8b6bd15108a3846bfe14a51d89382d8332bb311f0b6909eed19d43182ea5044db4d43ef3a9173dcc669fe5a8a36abd300378d6342863cb2e9b4651aa8689991557e9636c92c87cef06848d500f2a3cb85c665f83e64eb54abadd777e10a23fbbb1818eac65d928b1f610851fb7433e255efe666daedc1e52e32a9f1a1d9aa4398253a644806073734c39441d511240798ba315599dac72cda9925e5a8a0183867cd442bee54b7a431253e9ba21f2098bb5350f6e048f19a51d90e7cfc408bb040859bbf59d80f8cb2702798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f717823f0b58cdfacafc795aea529561d11374f02964cf635c27848671043766cfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = af241b120f8d3acc502595ba14a0477c9783a0a442889e99e23b12fc258e9d2339660f7c44b315fcf3fac31d781648d96b4a55af9d3a7ac25386c6e121b29f40183f6195c2971cf50b3a6ace17eac55cb7f145caf9e42d7bfc50264b935f1bc1ed60c5caee8bdeca5a1087171279f0b26236f933cad6e807462d71d8b60ef5bd8a32966d5dbfecd033bf67104d79f7eb10dc4171b0d979c999512f854ff57ba0dbe822cf26b1c7edc4819516d683ea090153bfed9eefa1bf1401335f38751ce92afff775885ecf5c6bee8e58fffe4ea52ebf6bd77707eeddc86d67cf894dab1aa72d99fdad82b9f1b121abadf5bfe79a26317f71a5cbb24854909c60a815c10f26c867643f02439416010b6966c79ddea83bb472b23566381fa179ad727d76382d9370e1256e3d9147d33a646f3aa193818155d2048c892fd552c471e99e09b52a2a5f0bc4c20c9b9a09eed562c5ce6d35e387407db183d7f036f4ce3eadb86f5b8d7483dbccc8415035ad229b78a25f52e9d7ac254058d7aa4384a14f7a77f3fdf449156758ec3598faeba563028dfc5619c34cc814d7525b282747ad5c04d1a9738bb7f1a3a8072c8629ba15e97e9091c7d7e59805c58b165fe17750d21a304f68645ae799c8a059ea1b6e9b4030120501b12c52381d719fe2b5ddf5042ba6509d27e15a07178d476d94766347b2e800edd3e22f6dc37a3935c5624771eaf950c358303266cc4b3056bdb5094d096b66b98d7d3cff283b1c7ab23ef06b443f87af78180f081d9fdd74c8b3e911c611988beab0e7cb7f9ddd9e6233d1cfd4091c4319288714e57c3d851f2213fa41a60c8ffb32c4e9d530ec3a833364317230c4fd33f8ac4540f42f7da9ffeb72f8b2412636677159b1496365bfbfd28e76edcf961b287bc0bf464ab1edd8b0e0e46cec8eb96bd4f38c3b64b71c1206fe1359bf14d1e8c31d4c6227cef0b9964e1a94c183be6b4da3e755849a6299c21aa9995c59de988ad0bc8d519247ec4eb8bf2b0732843c48e45078f0f9fb4951e4e56d73e39c55a809ed0c048c6cdf4bf53318f04dd342b2ce699ca8d5e06988ceedeb +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b35e57949acc7dab5dfe796ce9adfe9ba933ad2c91c2dfe8c95f30c65a80847561523e7ea18cdd313375dbedafb6e63971333408c86cc323ec9496ad1f745f96379391c48554a939c74ad1379479938a7019f55fe2a4f91eb6793eb4829dcdaf6a37759cb7a2cae7d3848d39cd3b9e95da69907bff4a5661ab57a165db6c6d49554ce7bb2c9ea17139bb444764d1e7b92ac880845d387618ea36e675d76635808a611b5bf82345dd1e0eac8ceec75a3b8a5a6d9b6b2cb554fec9a016cdea44eb7c1ab79d0c5a64bcaf48edb6c2afee8d8deb1788d7b6a7e5fcbb9954794b68f943544fe55b8abd34eef8f3e9a4707793d85f4290da5fc96b5996fcb62f8dc5e7fff183293b298ef93a1ae3354a6f3de7894bafd432ebade7a878c06836e7eb3fd118e29536ba88046407b7f86a8f4370243f9bdd48b144badd49af5edad4e5a74f77cce88c665facfe4b058db0355c8f835fc3a0c33c78bf9f43ca629637af1c7f4fcb8af7ec876cc099c098e4c46a4ddaebc99497da620a4ad037f79ac75cbd7ae35094e9860aee460ba55ddd3f660bdf39a76e4e0413891e2c94ab83e1502df0b9976a3193c62467856bbfa2854859ffe3d74aa46de71f3d7f64b4bbe83ec9483bec29c0fc57f6720f7e1e59d5a32e9c67f37f557e6f14eda4ffb57c6b1ce671f874bd7399f94a9d72cc86fefdf1e5a8591908733966ded21ee0b53d570b8cda7e8ca0becacc37c732783d74a3febd73bc8d9e28f2015944a24dba73fef93b5a392e0dbef7bc9fe677787503fcbe93dedd45818ab8a2021e3a4e8a441436f51cf5c84ef6784647d2e3dde375b8de7f2b461853d683e88b034b64b4ec7b5413de1aad713b459e0a35b2679cffe8484fc97e7765f774ebab72b05687da19d412b669f6747042ddebc9a5c1084d77b878732b4b922e58b6b96b45a617fad9fdb7b88ca7bac6f1151c5aa666b5a3f550fdbe36a4bf83562c347063bcd9f7f26ff5ac4004b2365fd57da43f998956a77b684d7ced460e95b2e4f16de34512048a166761463bf7e3b4c47e475551d33cd9c7dd9e8ae19d1980271be26e84bb1faa49bd413efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816eb0dbb4a0f5232b0c4b4ce98098441227f25ab91ec97319ff68a916910fd0ca1d5209c3420508b64acec450140165620d9bf8b8170ad328286e49fb049386658179986512fc07d47d49a1aa5bef5a4beb499a007065a79e164a1713804b108a95072ec9c6a1be395baeb09fd9a8e0a749049e405137a5c05c80715f9b30022183ddb127cbb1ba7556302d2b1063b798cf164f0f0bd40a202c13785009bad8769c3155b643f7a19f9509987bc2bccf41a3b9c1b9a844fcc537d8a8a28cce0641b16a0fd49969df2051a6b36b5b58741a0cfd49868bd136cbb4763a97660694539a2025649a7884a64761a1059cda78e07c5abeb297c9e61407ae00606cca7d26c0da8436c4343aa216c6b71375e4c9a0ecfda7697e149b72c025696aba086251826435c79c742058b644b7466b857cb5792c539709a59ab15aa296acc5bf5d30bce8b0b11b56d578837f922a7523927b8f0323bf79ce8c372c8655082901ff1630e0d27baf8acadaf284742e73ff5650a3ca80c47586a1d1664128a4518e83a0e4b13352b4ce5838cde93826f0ba92cd6027d0869bb5342ac1c11dad0938c5ab3a836a646e37cc2d42d3a9324ff0282a4d38fd9055bcaa715e8da77d08434f535465c9b880506831b33174b974d41e680000b5ba3835b457768b3936d3810557e72407d9a953111990c741104fa243a922da7b03d65d2b41438449bb0975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba39277797352d24eb2625645995a12c2e69a62f421b510225ff21b817878aa0031d0f70a68433b422a7360f69abce2bac840b57afda2144aa62949093f643a5cd209486b6cecea226d205ab14e76c17cc86345b0d119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b5420ebc19de137c2b4e55b749399c5386af0870250e853438321ee767012483d8b460239350c82f8700e3568dbf453fa275d5f612ec8fc6b6e37854e8131870862f8046881185c3903440008c4b3464cf43b6f5a80a47c473a6870137924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c7a13afefbba39ad59c088825380398f43f1251b83b0ca9debba0102f902d719020a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = f9ff711565761df5ed623814f675b97cb588d69773f3e1c81e9c146c5265a16be66107289d2aebc4f2da0e4c23a591d4eaf9d0966b4e50e431eb270343770a81e56eed0e592d07c3ba75703dc94d7b678348110ef444ec91f8cf5ac270c8e7e068b024999b5719b73002ec8ba9c92e577ea3073f27c0b823eef6879b332506957ce2a3c7df68e9817bb6a908ad241d8ee3a9695f551abfeedae4b9ebabd48d1b7a2cc960f030cced49ec11b9627b1875c582e0cd311d6269a3eb49bc638cccdf57d7712fbef189e770f8f7003a95fead9f12d0764058cdbe2fedf3f09b89dacb61082da216871f1a2cd37bb4c1b8ccba8d9683a20bb7f944bdcac0c98015abdcfd6c6e7d739f0ea39672889a8e4af3635cd7de8ef815bb3b309440586b07b9b77f40cab33c39042749a837c91882203b87f6d32845cffe3ae07edf9105782d823e674d8c81d61f113d32e4bba7725b97cd0ec3f6d1b92a41214776ae081aaa7079bb1c314b01deaf99984f268bd66c1bf6b33b6f570d35e750dee1d4896662a058e7b8cce7ee0f26930bb1ddd918430220f6084410e59b283df7c65b62e17549521b3edf319c747444385aec86fe4b9d676c1136d476692c124819577dde076a8312cff796d585e3ff3841f6678b5324b92fc695b4a83128f4bf49baa5db9a8318508a1150872a8a866a355f7d198308220cf30f5c70bce084f633675ba7c4c6bc971c9a64d5aac31241fc533a844e76706d17d19e2f2cfe81d5c8db420e4cea37ccd045f2bf5062b5456328125a294b5d955d756e2ec87f2fb81e72cad6ced5b6140f05d2a6cccf9891ba777180e681f9341f8d9a072ef67c5bd6612a080172a93e688c34f5d4c10cdafb98f38dcd93f74016881fb11b580002bc897350b017d64d5f54cff571d3b464d3291ae3de049d2eb533f16456d960265d541e1aba8ca41b0648358fa84651e3f77a981a4f36604d1eaa57e5095230e693f6fb83bf1ebe209db0a9d53abf435bd7e663d0e46eaf5f56de05d9483d0bf9838fb780f565800bfd1516c1a6b5137879621f54a755a6ee2ebbd9028417d686a4b64e3274e6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 1add8d4e8eb080e533b6b9d0fb54351f55832e5eee4334454b1f36ab2ac28e6836b39ed5ce7b4ac45ffdd2367d86bcc33b539b7d855838f665d5d684ea3f870c5678380385895d8252f43cd214cef4ef59d5e4c79f078c3e3a8098834699cecdb503780463bc812fb0ed36a14fd6d6d924e984d4ea671e723b74c16e4679946aff8f47493c2d72fdbbc93a14318563886a5e5cf63adfc94f388cdb4be5d9dd2f5ce3a08a330e9cbb5424be009de3ca09c9a954f763ecd9ad6ec891aa324fd3dceedfa92d488de28b4ed28458e6be80680eedcb49cc6eabf5d8f444c574a487a95ae047aa9e6d70e20d611c5c711ad844aa1a79400a4977ba45a1e686b7ba864f8a75198f73f379ffd767661366e1c3fc37444c345a5dd5bf35e57116de59ac3b9cfdea7f5dcf4819f20bd74437268a11acd74cef36ff5938bfad4ff948e5b985e81a4c996ee486c857608baee9012d60c04ea180ed5093dc8cec793e12c397076de97f4b4a9abb63fb1aec875b54c9884a4d875fbdda9ebdb68fe4c8a7c6dd58050e932b03dd5cbc76ba96722cfb3f838b4102cdebfe4eaaf64f822f09cf33d4dd5403fc894577eb3b4f0706a4a2a67f97568e0ef9a9e10331f84994a39d9848d5cffbbccc6e0aeca4a7f5b5d9fe0e29e8a1dea8bc474628a9d6f5a9ffd7be922f7ed4b1264b7f96c7157bfd928ce66cc47f2b2c4a59cf550d8f6b3aaceccd6c6fb0cc980c85fa90f9e5f9cdd6389da7f1add8e91b416e18c7efcfa4f31bfe1294461cc9e24b45913349e32003b0735c7997e44eb318abdee9ec7545f7bca55953f7e455247ac0b53c05a3ed5c97e5d674933d889a0aed5b5913e5bd8edad73a772ea4943e9ed869c9876759db96c6ac83b48b21fae71148bbacdc66220b6ec5e98124e7548ea6bc0ff59c883c96ba8aab5969c6e765c2c9f7ddebae7d8045e64c34deb03a34e033ac4fb78b99b84c7c6af76f3f5df1ab83b49de294ba6f56988dbf08c57b69f02d9f8a3fd7f0a94f547016580f66c51f6e4dc9db8166dbb92e5a57707e9e1e986ef39578312c6cc59a96722efa96b4def37d84b72bb8b84fadc7c3b4465b0efdac63724548ff25b73b9a0ba6b5004b82a614918e63400146f36aab60c8cdb51600fa1218e9c3d619168d1ca7d1b29a20b995dc254080108bde2836a53c05aae73f95d4997dd002c21c9e16711ddf2603a845a5ad8518a3d3cadfb57a5a994cfa262d51f06d3d1c857de85cdc934bdff1ab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4c3158a99482b7511ccd188b5ad42627a49240257b5bf500e382a577dc57fd84af49731b6a49224815a43d2c6bccf03ed1f09379918c882cbc5fe33303cc37621c21d9e5360b3c4029bc2c9f580c2519591f6ca703283f93e759dfeacfc63101f6a9bcdb30839b1288334562b608b32d211111a79c8c2c4b19a822d18646190051c65c0a42ea51c0009ac976a06c4b3c24ec1b47c117865287b836738473af07f2908935b5c0dbca76c44e48f5478f78aeac138885721e40b8ab84c2bf8c69c3d4ecad4df0ca07e89a6a245bdc46105dd21a9858a819310cfb239fa735186407a88105b3bf156f95f87d9b3b9db0da6bd67075c70384553b28ca89ac9131561b9c8d37a5aef7a4152f6aa0a7f54af2f3819d6ccf8a07d0f4c5310907403020a01e4bb94d4c7bd257ca0944a6aff6cfe00c9182d508ff329505c3cf85290427a2c06366907b2b292aeb2b13b954f211117504a18f37025860cead9717869c60fdea3e31e9845d439989839bbd7ab2222b13fa921133906868e6671659b18a1c0f62d8bbb7b69b0eb62967b85b21375742757ddb960cbfe450b9a415fd083aed8ac0cb05a3732b39453180c97ba6ce5c426392545e2b6d15683300ed697faabf21a2423409ba37a899c602b72a5a4ca1e3a7c4423c5cdc3765d0972f22cb9386bb347617720c6cf9e32964faadd4a625a1586985571d40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041b82479b23f18d51a77f1086098c3a9d2646fea3b822994ef730b97569d05aba38f880909fbc441815850e0beea12403d0024d95c6c1691584c6b548e0068ca7c7333ea8d07f12b615433da2a041572a46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455dd4cfbc29de3568663a3a044c3f897714363b0fdd3b6ee55f796292d34c7c79b7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = ed98e8a3d9b1fa0b2ea9c5ad2a02ffb131b2230df45df43f53b5cdfbc00dfbd6a8f8f7a9faf230d914ed687cf1a9439a5b3981a8e481f79612c506ad17cb8c5e45dea6151ae03814f377f3b3b293d1b9e70206da62bf076b0f7c21f737b00caaec99d012d1842f074ae4f407d2a5dc15a8acfa5ab60bb2cafb7220ea175031544b9c0e4dd2365770b3c8a703b4e5e2f989a2a93c36b38192c85e6836d5b13ad675da7717b4b5994391bd535249a4290042a39ba0c81182f43af051566e34ba7cce505c34f43be5ad99ef5ebcf49d6ca3f525cdb78ddb26615fe5ca02f12f5088af3268a06525e16873aee13ff8f3a2af0cf2472a00f9d5cc91733cfecd0e8f88d2d7d89dc4940a48aa6b905f7497f47718e44adf96721d61e7d3980d6fd72bdacfaec663c7a9473aa36dbc13372600605c9bb7a9e904b19ffcaf39c1324d8a1f2ca5e03a51b682a67559d64e5c505755a1190788ec9fa237cf58e1a98030a6051bfeb4c5731b45ea3297c12746d9131a1d750816c484c77134f5fcc87e36d58ba57e625e288299c194992ed2662a413320c4fcabdd8a0b66c3ac76f5b446387264727b40db09f84291da10ade352e3f3118f66135e2f2e465dfdfe808b13db86eba4e5ba6c035b860bd3e100b86d4cdcccaaca10415f9afed88d72a4ca80e77bfd4a452b93b5916a06bfa9a5489a0264a1d4201ea753b3824af7a71e0541a513cc9cd22da765e9b2d0c4b2ae0c8b7bda62a9e716e5bfc3233bb0294c218925ca7f2d7373eaceb74f3bee889cca5d661dc2f340cd09a8caa0ce74f62a65445419790b26ec978ec32f02f2693d53f29445cf705aac157cc9c946e2e0cbc8b73bb24adc9a3d4b05e5b4f9827b5cfdf8599e31db2f6b12e2df3934afa755dbf163c85ec6bc84533efd9f3ccd328624a96f624c52013455e660502386146c1f9aeef2f7e57c78bedbbc26df6b4f8aee493ccbbe03397e4990e147092b0534196901428a1ff2619490407f04479e28541ca2933b9ac8bf9241a72f5a37f74c3892479de914ec23afeaa5aefff061a18b3f3e1041ac602af40dfb786f528be6975f97fc +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3d5de449fa6ba938dea867dc68daf44b08f2bb5367252be5730d8b2d86367a9ae148f639154dcfe1f9bd1cedfd87c9842865616a1e45ff8295444ebb354d6abb2343cb88a7479fbf39dbd00884ca13cb8187fea788f3e3cb739d48e8365659c324bb6b032a85ef37a25d538cccbfad6796e6f52c86093ba93538f2b7f9b0a33d7a3ff5a17e8d33614ff0424b748527efe3ae4d1f758cae896cad6842a90ca5a7b69789d356ff574607fae287ceaf8c1f7449abb495b485c7d6d78ceb9e715fe6679681770f5913535879e5cdaa4859b70dfe20f67a0886ba7195ea21f55d7b7b503785ca982fc76bbd6531b83cf1bab17dcda5b4cf63f8593293068d78adf70f27f3d87e3fecf34b94ad96e89c31fd5fa2dbcb8129133379866f938b71a203f75f939d741abea2886ba849c991bcd505fb5c4bb4a7874dd39b1adced5d64f7fcfa571f6666fdfafc7ec07336f5b77bd015b7cdc3cce6e6e6ad079e4e28364fbdbca2c1a653b9a8899f236bebf770e477abd1dcb937b7510d7ca3a00aa093cc9b62bb6408fddcb46e99d077856c4682ad78b241cb9c2537cd969ebc4b49798389b3ef2e964815a4b7cdab98e7b3197dda0c663e556ffcdac9f3cc8d9938ffb9020ce0c90bbbe5d48a2f489a857377509b8b74ccb6ac875e07c3429d7f8943087ae9f5af33155ab0eacecc14458374d4ba8f84acc63a386afa55b8fc768f87ce3e3fbd9ebab8baa4c7d3b3ea64e2a496ae64a59c5823fdadc4d8553cf9fd34bf4e73927b16c81d57e88954c0f09d39add7697a9b6ecc89e5131b6c6cfa335c4bd16d53b3547669d758943e3e6ad65979473692bde8725247b333eb412b09389e55c97f655d20f9850c1e98b1c358a3a87cb93cc47b9ead29b7c9ad8ee0c886a79a39bcaa68310ff5c9deb8eb0c1c37015df1ef7cb24029987dbf617f94ff305e417ec5ef39ca7aa50c4fbbbaa51a1c97c50ddf592d60e95ac1ebab6e267c8367b7365cf439860bd204ae92a10f8ca32d5a0726de2d0b4d2e8f602b288d8afd588e6935054ccbb773aa6955964c637efeb8894a5e45c62979479fa20a13b9b983f083fc2701341ac042ba3987b25411406b32a000a12e00f726799b88f2219ab42bc6d08b3396bb77e51a38808b5a00823d45fa46dc142077ac63dd25b5209b0b35c0a3bcc30537248f568018f1324141404c3a603f8bfb30f675710b33b1f986b78475a2d4b1a6c44b6277b881c8f69c7198657db21fb0a9887afc4c3af212d1751a1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6da906e98630ba611eba0b5d622670b33152c3d91311cab5fc052c0050097d0c9bf0a4729a58b216b92537f21948c865e471276918b712037569a079600b1eb611c8d0424f8903404b9338d4ca368c0a42df6a9b6be6692ba24232c68a82b22076b72c5a71b5cd603f52493beda57f12c660f241a6b772bcf007819acc094e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b242eff33c5263685afe47dfda38a8250cc54160e4c22bbcf9765fcdc1b34a94faa088d4927a6d8121ce556576ae682e5fb2761035981b442245c1d114285ca20b3af733c2d3a8121998bbf87734479505644b568301244e31bbdbac05b8c5d93121668ec64080287ea074f02323a91425c7362428c9637e61bae86d03238c96336081a86198e0f31c17a945e50e15634e23100c6499bf1b58a48813bfbc7ceb3322274329366267132a972553c6da19e13898b89277a33836371084a5297bae0298288fa68a27605a60b274620111d376227d157d066181714ccfd42a3d33882335565f9a0babd7154c5f12e67215567676193ea837ea188def143e98c7721dc539914c678e1876d334fb99627b848616190a9f5371251593381bc933bc47c1e5ba50429b1bf71ae7c11ab43273cde9538fe8b21b310c8da5a68d7828c60761f2178405ab96cc3d179e75837f7c69c0990c75dbc2718003862448eb3b03e6abb535ad733f5701699d543ff893003b3674ce997e0c6ab8b7b2bb834c4a437068c9271f55c2fa3abb4608cc88128b13eb17a2f45a7ea9b85fd3ca8cb70bd8c0578f7963ac76c3d39a44f2b87b1fdc24f15d32f2b38831d55722aea8642a7ccddf2011f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f29ca90d64e28a5bbc54c36053ed333c530f72549c2afd77b10c2944fc833408faf48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = c65bcdbbbe19ae33a1a009f022fb5f70673dbc955f18ab4346bae8a9439533fdfd0005a7627d4ff87768a8e478420852bae07d774dfa6c394d3b620c576bb24c3fabc712662cb14706658be7d40034a2d8f0ffc9d838e3af335da39feb0f66412fd83375f3a54990b78563ac4fc08ef20f0e7530346444b71569118bbdb8de85a54912a5cd82bb787f8b4dcd20b10c794ff9f8bff04470fbb576c02fa6d2f2997a9652b4785d772c6ab1fee81cca792a98433cb9a89498de87dfa403288f3c8d2b81ce486bc32c29d11a06dfe10cc6e3732cf9a3b1cba5dc3b820f6a5630b370abb0e4a97aff035685dcce014f68e5146fe0072af96ea57b10b162b0643668224ad8eefb26b29c0438358eadfdb23f30cba357d6dee149faf352adea4503043402326d84f83587eab1386a6ef65fea0612b33819b7175d5be443b9616551e2fc3198ec3c0f6337dd485bf0fcf25866b092a9991ee31e434e3a97e1fd8be7331115d330bbfd4423a432b3c196ae1652445c2b9ca578446883809c9437a41eb29d07b0e1e008f7a192c72cebdcb8cc9baa465f4ea2cd2d2c8918d3d0389e12d847b0aa34839645bae0a0e01b09d8d546307d05747c061b950eb6bb5bc8040362c7b25c3bc320fe50d912456e5c2043400455c0185e8dc50c8f37d51f75a1c88e809c2298a75ff9fab24b43faa33c1406aa68aa81ad7c6c0b3d22b59e9c9c5d94aabc89921412f27a4b9437e64325fce3c716b3dee791e85245c37e9cbedd3eeac18eada39a0a8881777625978672e1b3f9688ce38fd36d79d428b400244275e6ef929016cc40fa6fad3181434d26a3230215fd4739d9b1a0db3f648dc3b1b95feaa927e80284a788e1fce01d0988d194091e3ee0d4381557c3932977cd969be70c88f4195780626c5f091f8f04cbbfdc08ffe16cbb83e7935abf3b3a999412c29b217516d75f93909e75a42bc635a7c25e6ec73b08690ab23d32acac2f917033bb0161daabfd966063f4963863a9ad87f7e7b3b114e1f31b9003ac0d033d5d990be4e2efaed2b9f6c4802c1762d7247df55f849f448935220322c0360dc0a6d41e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = bdc3fbbc8a7399e7a4e9ba59ad9d30bc29a6f85c8fe34e8c2aeaaeec45d9e789a854c7e26cb5402c185074b7fc4f2a97fa34712fdfe9a8ebe654efe4a9d6f3bd093dc15635a8675beadad2b1b8b0661dd229464fbc1f3cad7f384cfc5f0205b76abbc3fc5bfb94353d3ced38ca88dfb5687332279a6fc379ceacf8314c4c4357f68a7dca5b4cd84eead4d8438961f4bdc40ac8bdccca6f14b4db7376f8379b0b5a329c4c5ccc975ed3d85e5ea782ff8aee23c6491ced4f84384e0bb56755b985f8bcf812db5e6a0834287fa670dfa2130b621a84578d444712ac76f41d7e1ba636639ea325cb4d0d836427a4a2809e9ec234bcde6932f42446d97e40e27988381f4f3f69d45a45993fe8f389af702c0e4f956c59f7c85c3ebbdfe8b948b997e4c7a460bd844f7f0a5f0d2aa1b7edb92c934c28f5a42bb4a08417f90807ba046d5f676732c06f59ee8bafea9445726bf0ddbf3b52f969d67c3bf7f6c1b354a315ecfdbc38bfe60ea5ee1f66b246f4c2afdbbf493fbd44895607474a455544eaf86837e1db8fe2587d9e616b504b5e9593a6f1e8255002cf81757c4bcc85897a5ec6026550085460e4ce9b8cbf6375cf4f4b245710c450ebda82cc8abc28fadb2178dbdc26948fbc6e13cb5dbc89b4fbeb5dfa4c338bdb3290d834eb16d83b5c4655c571ccfd35044d4de496ddc80934b235f555b4446cdaa14eb3de2a57dce37e5bafb5cca084a7bc5595015892830b4bbd46fd487c7cc84d95e4e7bd1ad7c95f2f7c25a96621637edd1b7587cdf6b33bef2044d75b68406dfb7c81c9ac18e56d12f96cf4e4ca78ef80350a35c20cc3fe48398cae4050fa515f1e6dffe8e06e8e5deb38fdafaa71f9dbbf5057e2562ff68ec4ee7dbe6ec59d4d80a6c15d2ae30d1f3bf3f4c99b95a569653e5485a5ce9a6396ba91c323deae3eab5a0af34addce9accde27f451283343430b890965fda1ebd66243df64bb7ed34c7343e7b6166dc1e2f6d1841a90f21cb177fa55a0bca3089462b8c6ec8746726c2d3ad168eff93db0ca03d7724dd99def4fbd65de1a6b325d4a71ea64f999f87955a986051bdf8b49619f318f10025f45eb7f63d1875e49a296eb1ef5586a9ddac4a59bc96cb01e0af7655b052f9a08b861f0573b8a64295315b76c3b0a13cadfa47e02c61825226d3fcc25202a862e509d0ed99521b1c46c7064de830cf70497c934c7811733e9c70ec2916075ea425d3a0d03ea272bcb0f294aa32f1541df2bbcab251e9173701d8cc678009f0323677c2b0708a246408b4f37e95c170311bb15787e9b035ffb823db6cd02e4421f3690644cbd4a413bc7e696d7491a6ed4018091a9be8b149ad93c49f6424c218803b72c146cab9721ab22c347787090d9016199e65940e19d6902324d138561592a0901700dc54058a6ab298b3d62453865ac29bc815e65582f9b8bb6b5e44c12316de7169f4988c86f953a61a313e4a2734fcc24afc60f6d22491e97bc688c528ae661c9923d587bb11d512c835a9fbb314c39109c3ca2166127084d282979304265d8a78ef343bee9baa7038b9dc9517200c4a049613c936f80982efa61a3c0f18edfcca724a43c79ec2f03b99b656941d5cc040ba07c8d2668085a1e1d7a8e9448767e32c86315410f590b03b993f5c21665a7339db6386e923f7b50809d528772c27660615acd53a9753085e7b9c025b76b952518b5b11a778a880350aad71b2df3260633a570250805b4b0c8887268f1a572c86469e4a75194d50a6e89bd4b2a6d4d09698b880dff136def5b03e66726dcf26fd4911bf3502ea40b0ce71c2588a62dd378447c5477de819baf0795134001bd1250aec31f39a25c98c59938d97390a309ace0bde67b3d13cb46e89b3d7f8369fd539b639164f9825900b36895bcc60fb98bc0a28110f3a7af4070c6c72d63096946423ef49269176a529b5792e4e10deca940564906a29ca1b6e95352210992718248e664a65263a235b17293b6f4b45836166cc461ab04f91fd9e7ca24a891e44c2df9684b85a5845efa2003709b07a596f36aaf9224ceb70c98bacb06d0a1be3b0a926d9c537223097f420a0c1a1dcf360d87d0825a417382c40f297a989a7bb827ba5eca46395e4351aec09420405e9a919f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccda073c98794493ec169c78eb75a39c1594ccfa635b8707325e0ab6cb8576e30ce6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = d4aa69eed658bcd19e2ad7011f6820e9ea37f36088b98d07ecf74e89e7f6a10dc43404cddb33d50ecbda04455584e7f6eb69ac0642a0d5a55439ecc1737352e89c21110d625f32ac0df847f6ec4d6606447f1b98412b46afa316efda72540ecaf6f2cb867441f7210d5721f9324c1e39bc5121e0fa3c1cc154fa527c52758532edd7899ab00636962d0d26e82e848ecc03f93e42bc4ec42b24f12db20c02431839560f0bc7ffa4df5523b712a863907c60cf414d2724de0db4b6a8277e00204a56234ff642bb4f4f2a477a2365a016c4d844efde38f1c65179c66c6b8284f8cbc52b821b9c0b715496f6074e53dd453e94a6aa23fb0866742a77723eb7a2107ac6d80787b99a7cc3b29fa0d90620d9d740a78dafd17d75f05f611883ac767e28cde536f2288380817c3018df57cb471fc4b0ed461332045a7cd89cadc290fa0b2adc367a76fabb85010257bb8b2818ad02ea515f9d1a686e0140c7e597111220295afe0ed0dad1072fc13fa9435e2a05dbc607f71d4e30f3e818e6aa700f792f60337cf85055fceae614412baaddc9f96efa7674439b96570ac463b8ef0f4334ed50eb8bdcbb5b882629e79f2b70d9e3c9fbe7f77366582ec3f23854004f38c0ba02593492a45672e6a4e345070ac75bedde0cff3ba5dab3238b54727f2d7edd44e2bd2a57ca26535359ddabf207b0c94f67757a09787a7418f2c551af0b57c801f7d7009e116c18b01d6cd679e95b38df127a54dff0fb94349f97b54e0de458d0e22e6f246e038f0b477e8ed6fbd5d8304e7cda6e79deeec0626881c7eb727a68120c3d602279bef6d01b7db70f1a64e9cfcac523d8d7dfba8e8f90f67567164a146937570fccfb3af3a64420e11833a39b67b727e35f407976880d104f05246ceaebca29853b014356601ae0fdebbcfd84e02d75b35db6ed1757691f4ada0aecfc58b9f4d4f6aa919fe8e0ba568399c9ef1aa09c55dc93fef55e871445df705be8d0eb7ff1416cca413403f1900f2bbf46a84dc3588f25b567ba5699a8bdddd55b6deec519bc1f76cc01b368ad3db77758f7bc4ac6e2a33a9f280c8c65630d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c75fdc2d0681c74c90b9ba6bda4d54efc357c60dbebd15a0ff5ae21637e618fff0cf7a6f46fa77637cf55e9885418991230f78023cbabe86770b1c976127e187937c00fdbc10783f47c7388d367b03756eb38d4cb53c8cc4989ff3cba44a0e4835b493a56fe80da54877a3a6daa63358df408e5aa0a284e75f4f7721989f954942ae89d9dccfa9889d4946766eb8a7ea901f77f5ae55e89faaba1cbb9ddd9647d589e9863b5bdcf91825d4450d6b509884c2a96a817c9eaa1de44f834b0cd74ad12febc1b93f7388925523711327588a74a58dfb77810d3e5f2830f165d7fd2b5057e5c74f3d6f8f268449a4d49b9c5c3399d9d867c547d64ea6a691623d67d377dd848f450f29ee216e879134f5795bbb31d7af1d2fa99cc7fe05a5a768c855af4adca56480b8ebf6ac36ce8b68fb838b8a488c4f744ba785b8bbf4eb4578985f7caf9f3ed6d541fbb4a47a84a65d4563bec36f24c0569a7f24998d90c9b1e6d5393dc96cb1748eb4c5c963e46431d45f70b536a2ebd132a44a9a98af50087e88a33002a3acd1875fe09e322eed347929354a6c5bd52585fd97c8d21ea5494ac1cc269c075ac6361b71294494085d43ae7be03aff8a51f5e368d4e9268c5001d44d681cdbadbe304b87e9fc78e3fabe52764b80ba5658835da0369ffc487dd82a265a806dba94acb1d10ddb6c2dd68f93ff4496834f5d5bbd4a3bf236fb53998001a6c87b0b6abf17e84c4dfdf9cd4b7a4d798a5e57cd2fe1fc6c4e87035dfc18e05ffcb81198fb3a08c6060b526cd9f91623e122a449067e60dc03c8cb985d92188126abd70c35cfba1a95412b8c3f13b63e8f641b453bfb76ad428e573a27b1a31c411ebc57594b742e53424c5499336f4b0675795d568cdbea4804ffe80b084a52bc7653385ee59ded0a0e4c0f63c8bd8c7e2d33f4eef4f176d9a1530e85a4dcf55b0471159cbb2a7d8183c7fd6b2faa3a55b673ef8d707d66e2d4727024ec809a86e60389d838c0cef4f324b97cf9dccaf435caae0d8015e83c792e7d84ca93e0de65f41c68a7f66c990fedb00fd1c523c7291c57f8786cbea3734899705684bc32ba5b14f6999a9c794f0c6af04803fa57cd54278313e99327d579b217682b1b86dc02431c6aa125062367798f2c7b1ee7f907dfe42736cac924d169351853f15b944578c5543aa27b626ffe7b3114a11805d8a3fd464ec46b912ab89a3df2a561855fbcb3820f4c11fa7b5e3727612e685830f3aea6c9881bbb06eba102e3f53e6ec502a4ec98f9c1af0d564df79c8d7c403c4843cd6d05732000c6eeeb17cae7032fdcbc275949a8d0501ae182cad756808cace516b72696c618b319f56615bfd0472c76a5b3b4b6b2471e1955025139c5805c095867be34657c5af333c9111b01da84198a8d33655a37f6aa3f35b7e6f34b1e2b158987ccae22198ae605a9a86fb3985f189292785a14fe2a4de8e245a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578b21260625b7ba7339057a94435966df3033c647beaac74bc7014b01dc539445c77509bd481c525a226dd44966feb66684644f598c9493346c9071b16576978f477ea07862863191e02805fe4c54f4153749b222a001af7396a2314054548203bfe66080cc0ec95c2b86223ed936268fe418486a58afdb9fe8dacc49427597e4198ac4c8dd747aa56cc22e38c7f140988ee37dfbb251762868915b6ac205a006846d74e8734a930211941c4e5721ff281551605866db0f6bfbbc9fcb649b45249b9610e647c827cb983d61a6c9e717206135e40780f99495aa3c9c6b619e47b40521db992e5329c4d3c894342e2ab2808c630d9761ab13416c55fa1f1ee2b7c918bf78832b23bc4561f6cade041f4223067db18033eca02d243811132c5d98acb172bd825660e07007125b7428f7403bd2c19f522588d20413162253a95f3e54738ae8694b7a5bd13c7b0a41ada087a8cab72b6927b3ab614cd6a00a00e2545fc7ce547a2f3b320b9711167b694c75ea6494047a8b6c07df344dfa099482d322fed5792d1507b801424bf50fdd2088c0f18a9bf31aefa239faa50c01c8866d0389eca7a521cb9028f94aab585841c021dfe04a008a8d11d23d534105aafb413450a2ebe6918eab0e641bac2d000d7fab0ad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0c2aa254714dac09b9e712572b24154be391063afd3cd8cf4cc4ed8ef21f0cfe55a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 69d2888f5b3d14a0c34b0d3ab04e995e8882390703525db0f3279d967fcedba1ab9bf4f06258ee76bd502f3d72b19ff6e44b241f2191146e64d42483a194a68336fc5197ca6e5147f7e8fdffbe6eb0912518636fe61781af44f39afe4cea8a0546d2b38371025e046f0fe9fe3c243ca9a20245120184d0a1f3cc3ad1b2dabe348ef5478f0340a6fb2b5a80381383ff91a1d4f86896bc7e42204708b7edbe828d209680ba7e6db55f08e164c68d91fec9a0bae1bfaa8e04a1d8556d199642b10ca6fbdf080a026f0df6a88f30101a88ff7ffdd0a98ea95cf470c06056effeff255ad441362d90cf0e1c147649a3cc30495ba769ea88985e82ed0cba5fc1067a5969978d7d7113923e68bb8cacbdce937a7232f1b1cd470e3c9bd0f5307153da5ca5700584ddd5f828e7dfb2d6525a0fbe5dfbde36f282ee3cf1d094731e27fe50a2ce995555007a563d0798a61917cebea339ec32410f8db30fd4606bd93bf7c60b1130f5e6b90ae2d37c3dddb5af7bd23117dff1e550569e36d0e4ab0489489adc94903945534acfeac4a6a8c71f890929686133fcac2b01de93c048a7bcd85ee32483b89e77002718ea0f9cab8fad836bc851dd521ded3d6141373d0daa8b1b824bad5f9750e8f79192e38fa928f4d13f742d88f0f398d6b0efaf0d718b4f0eb20fb68deeaab87ffc9f5e4175aed2ec0b6ddcb0c2b368dcb6e473a6d54b01483e68566b172403e124401ab98e5f18af399221d462231da58ee3b4b57e453fc1e99002fe381f56c8ac2942099077bd32a01be4a89a294235f36545adee763102e6655ced957493c6b0bbf2050e832724df326c3301aa50c6e0c1677b9cda946da86b40f2d8cad42c17a4b7eec870947eb2d98b2f3b7cd3be1f4d4b0fe93c30595c2b0a186e01ce1cfd63307d047eb9c4821f599b50a40820d9fc31e489467a5055a2d60148d1158dcd96ae06a97be24834d683d9848c9139ec7a612c248f655e1e0defc3ec939690b4a8b967611f11d79771df29bfde86e0f3fcc25f0dbe61ba1215c8130cdd358cbafb0cf1d4e2326949d7d3b75762b79ecf50673efa794f78 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = bc6b78c468375dfa71b708464bb93410ace720dcdb3f0b3165d968390c9dc90584d6fd93ccab5f42a44e54e6ebac9e9f73dc93c88f3fc9a36ff8c67e5e94daab5f82d035ba6ce4ef12655b0d9631cf47f2c669bcce0eae3129ba7c1ba1d95544a3cb3c2eb94e4e3d594894d680e8adc75eaa438ef358a6419ac5626d5fc0b4bab13c03502d98fa33c7e0fcd64a16838e38c682e3a396905d44dd968232599b5e134850e874b0ffa8243ba38694975038f7e97f82fbece3041ae569d5d23685d36364932c445073ba7749d470f98751f657eb4c198c3cb69cd21dbf946bea43489645ddbdb33eae186ea5ecaefdf7ba8c408e5eca7cfcf729d7c6bba14a6d7734b4e2e2a4587ba64900453600ac72f684db654f65a563ad17f3c4bb3f8caba49393d4c201c8a03079b482a49189df4986a3f6cc5b7c520f58a533416e5d8b62dbebae79b361b6b78629aac3fdc47e056e2508cecacba42e0cca57a8c183ffd3371c7533d3454db6585c855328c3edbdd4bd8c33fac8263cba6dbfa9e53e4ba733ae9ffe6919afa5077540be9e279637d9999e2fc948304a4bedcca2109fdaceb36813a36695ecae0ec790f09edd4a2c8bda4db6ff3e63dcc5b53f2db608ca76d607dd6419c1c0886683f5d6f23d315b7ddd8034b972959d430d8d5a1fc799134eda79c0a4c6324f636260778832358211e3a4287f68b7074f04e9838a0e30c85c8545dc374f6ecd9c5483430760cd4bf18c887c23edc2dc5cfb8e275c896ee060cd8fa96d9bf6165a02aae53fb3828234ded55ef6389e43a464f45028c222c65cfcff824ce6ebd3474e5aadde1637d3aefe3b1b394caf948f8ddd70e22c78c7ae7336c6863d46dd2ccd8848f964fba4a0aa5ae81aca56643667d24df67f274446c7d20c0b4d9dbbb025ea3f90e5f19e753392ffb3d499d11a1c34cdac46e30b4de544ae19b530d46571d8c6beddf9c62136d89a8fa0272fe81bfb9f3913cafaed732519c5209bfa52a53fcd39458386fed39731651875060ff84e0ad4b6a79e6a49f9783fa880638e2dee81795fd622ee435f9e9d01ed92cc2571d9fd9d5cc7b19a3aa452bbcdc82111a6eaa59b04ba8a78bb9474659cc944e7a883780815b899cc64219dfc583f0ce4103eb04ea7e60e2c627a91b28a32843cb395021ec544005326f12b53144ccea0096d8b186fba2ccbb9e4197a43406fec09f53abac00245ce1a239790ca622401df204a90b4a438d33391dbb10ce1aed56456f4238af548881d188f0976887eeb672cc91078474cc2c289de2459513ba16458aa5ff06ea2746d4293b7ec95078d9346d0197dc9a93b2c153abad1c62758cc2f57544f37cc9597691047acfce10be1246fa51b056ab87f24c38a0fe36813316191612e9cd7a26b745f4c51a1a164422b4502b073185a93725bdb606ad6850ca5a27f7c2e8002aa709517783232514309b3c280444c0706422652b170011122e0ca821b5117e530ce07282873ecaa7d751689657aefd5575a7ccb65515e1dbb647c31b1f8578120252aceca821df0416c6780b9f9988ab68c72c73538ca21687cb4654667d3e9bf8a0bc6263053766c8180b8079aa8c975d867b36b45bb709436265ffb0524a0b143095351c90541f8437e756a028be92910341db30b8a94290cf1f9042b6bbc99411b72176e7c5a830be2569b695e40e63122e574e061278a35c607ac8d491b60bd96917d81154e9a244dd014ee85ce9b0691c21c08cf2b7143b21ebbf71412b873828a66286cb2b4f11c73954aa64b1717769573aab29de4cece271cfc549f7f26aeb28360d22926cd16cb67f0798a1c1a03f706cb3b37ea250b75b1b881c36c86461597292561503e6f3405b19a3fc3a8c229d51b6a5391964a4c05db926ef13401250e4a8235f8ab4fc3039f61446f37c1c3fb01b626e725c8c5031db11093017a0bb5905fca5a2721c35ad2100a41567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a3751bbfa83e7237329a8c118b7b7af9816e0922661869a2e68c7deec83545915cb11570a4737542ec9ab52246e7b58c0df812e2672f86ab92c788257f69a0f62b8f7757489a182de8f626a4a91aad8a06f9013a9ba28d3eb6617a21c9070cc65e3551dffbb66ea449221c17efebc429c489fe107bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a18aaca951e0573f28d50831960a28dd11126f0eb080afc55f394e8eaf6379f6ebb9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 8d6e542a640d28fb329ce4bea19d28f101981c4370cf4174d9b2c8f48b98fd44ca9b5fa723b2bd20d383726158a5e5be76ef74af405fe5b58b3dbdb531f227baf0c6e11b395528cdefd0248dd9bfc1daea59f18bd6c5dc839d50af2a3261ce05aafea3991ebc7367b2e9076ed53f3b79062a874d209651c62858244483fe50cafc9b0184df4ec777c9d8bd2779edd813b8c30d786bc62ab0267ee8b99290d3694ce989097bcd4521a935df12204ff351204e213c0b8fd595aae93f7a92d87a8d6fbb172a3c15fada27c6a5b6ce95661045251ae753d455b68f18c5cf0e1b0623611d81c9b01c0ca687bb6b1a481efbd1fb7611c1fda52ed75892d6550d67e382339c9557308d60dfa6f266f448de5147300931d5b6bb2e1bd43339921275d8739db73987b86dee67d11a8ada02f38ec92af8221953bbf87bdc60911fbfc17a21e395451ae0a63198699463e9bd09e2c1e3b512bd6ed7c09672715856c8f64aaef3c01193c4e8b274a5e793927d73289f7267b98c1e87dab413c54467b8052114751fcc5da30244b2c5a9f02427c7b55e617553ddd8000ab7be2e716584dec63fd94c219f85fa6060f9650e6d504d9bd1cb62d7ae0568d41df889ffa731c5e1b58d08c5c2113d63ce3fad7ba7272753d1aa1b39a47c0e475faca105680e1067bce782537a93ab48e266c6cd0fdafdf40123be2587b8697e775a1597aac1845c9d7db1d4de92dbf7faf9355756d8ea5f637da8d0a56555497f40577fea03eeb7f36e203ff28aa536e4490f39016ec9bba62f7751c1608bfb10ddffe3c7ad3e94a2540fd3ec60ed516021c77dbceac7bd3734c0a85f7930c17aa4f022866347a803eeecec2a3680132e2d4e256c539c35a435c1b2766fad849edcfcdec82628dc9c2b9f4e38803236f3cc1ae5e0cd30062ee83c7b69ceb5867ca09eea75e4ddbcca0d003dc352240b4cd4327f6251e70f7e85521307af5fdf16a4d9b382b60e265e110f2bf02e7ee6c7d24c5ca777d33890b6e9935761351e8eac0ba9d8b79fb70e609d472ebed303e700fdd57959ea3448e7af0e1bb738a2a76fcaf0c248d0451d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 582f777daed0b2289d4444d0f2b5aec18cdf4f87a49568870b5dae1f3dcb3f15ed542aea5203858fabb4575b472f9b4888cb5ab4addf1f3e6fef1a89d14ec2869bf6c7fca4b2ba6fc0e87382eb43e8bc99afe986b36e64b67d9cf6f5ab83996bde09faf67763d705e183b4e4f786508be47c918d64d47b7cf1bdad935cd3bc6a6ad99f47708c47b49ac1b0cba389eb5281c8f75cf8334e89907bcf98b86866d2ac854bdcc0d63f41d2db6ba1a84051fc809d2f4ed1c93c0ec67ceaee3cf3ed5dc2eb30f1a6e5207c47c69689b88db695f8c70d7970378455be47f8c2935bea297b45e9c0640f5d8309c9037a38364a7cb9fbcbefcb959f64723a6eadaf07a62d38a961e4d8d03f76a994b4ad2b3914b63cb196c71be49c9cb4e41c0f312a5ab1a2b6ac39de3047ad5752e431529b84d7b57c76ef740473dcab837bf3e3fbd41cceda8fc3f1b7cd1d534fec4e4f8397ddf68ebb741a3a895e5523143dfc353e4c6649daf8d1e4b531b01e64ac2c8ea6a44691998bef2bd9a39ad57344badb07cc8a2756b945ec2a2c70aee67555e391c335ea997a5071793eb2e5d8698ba8fc18cd979dad5b0ffa23d4d2aa5ea724a3ebb3a5e27d63a1acbbfa2416de739f3cecd4d893bd4b5cd94a15585f045a9aeab96e1b3ac25fbda3de579964aa4c6bb5e07c4eb02e3633604fad3fdbe584a4f5d09372062fd427494953d43cec5e4d7194d6b704ddfabc5c58aeea28bf338c14ca0c5d5fe36f96e259b6b61c73b57cbb980dcdf318359a4742b55a7ebfed72280cce861f842e5f3dc7b969516345812a6585e8f8fccc8a85c6403decb0b63c9b6384c3d00bf34c2b53f9534882bdec0a74fc8064b17d34e0d4b73819bb81257b58ca8bd021f6514d8cf77c3a751f3f3ab546b8691fa8d76dcff93cc3b1e85fa0adc5da89e816c8645344e0e2345a3b46d33e97aac1bac96a38ddde7d908b78f2135352641fcb8379e5d745fe454cd69ea78d8d135afdc8f08a16a6ba8b39fbbcafb3fa54e908d9c3bf8d63079b5d3b990cd4a9443ea9020ac8c37742c996de487931ef9b9088e5c9f65f65ae0dd7025a6bcb0842b8b213052794e18787efe902d94c88c0986acffc72dac4505e4c36cc7b4990353e249112a8251e887aafa1ccc9c627948179a747b5cde3b0409d5158230b56ddc86cef9b241c044fb3d523fb909ce0065e260879690bcdf70c33c24303f81143624446fba37748f820cdd97e50d7a3bec058c404c458294eb812908dd87e4d652d51824518b3185425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444412b20a802c399bb56f461aa7631603b85c18a9bb7c83f6c825b9a421e59718b43d745c3667781f819b2014051bd51758524bac2dc9176cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3555b1950de9907289bdd8591f5994be7f920d25940baea14226cb6907aa5ec878ca37ea698c84819b62c2e13115de0ac334169f3107742f42a9b02912b74c39ccf5181ec5c0686c785e246c424143f5363900c7c22df505d1308f8483108f31003a126401950e2afca878443722b30246344ec2290fffa542d6598f14e803f9d91e5d050541fa2c52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b5491149e25746e262193965815570b9d353eb1ac9ea9875323a33fa4878b06054e3867ad9a302b6a43ff902453a92517c7055b2261c7ea04f3f6051c16aa727c169c421a0bcd036b2eac82adc3efde4bc28381589f36806189b780c327bf4b4b9b11dbe036557cc38898557a8a48693fa70984aad327078c1f851ef3409ce0348c16202385c22a70a0c0d54a7e727c0fd386845890df7687a6f65232a327d8b778eaf5a29f43787646c8eadba0a1a9b5c2a6473252aa6f12954bab410e4aa4108b48f618ba595159ea8737c7870ce4b0791706ac871111b39f71b0a394d0482c5d61c4d4d5b3ad0f5936002477763774cc2a06e7681d616b12cbb18c9e0681eb66a724123eafa52f63b2774829a373ac8211ca3a9369f128b2c810496c8a9b32d0813bfc2ced0904cf0bc24222b96ac4897a7f4686b5b2118780b656406cf42294579036dc995c42089648b63504b756b823d22c54d2fd7428bdcaf74113d6345c1eb505b843291a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273f15a8fc937b12ff78c54fc273fcd7dd5611e5835472ed377652ae64495f9cf5224c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = 4069de96aca28f486c6e7ddfba8d33cc5eeea96de1e2d8bf7eeca884b015b80bacf2fd1e302932c267fb4a2c4e2e906694ff356e758ad383ffc1a106496d3525a47d9a75ba0ffbea3fb4cffad4b0a490235386cca196e168ceae143d66145174f0caaaa02f392bbd2ee43d35cdd41bb30fbb4289288f9de182bb2a2d2d03daac88111bafd2a1414824f23591105f43985d92b87c5ef71891ff72c76ab9c820d48f8796a801bc616ab7ef6ceb88852e80be417443294b70c8d2b9f5d1134b230facde0bd5f5c0cf873160e1f24c9b65744b96770e9a767a76f1b6eb570e97d27f8607cc88b29f8f46e2e79957cb2f583b0977074a9e8688288763a152978a5c976a116fe56e06a108f7e894abbadbeb69c53e7fe653bdbe43f62d7e7d30ebc8835eb532969ca76eaee890564ab3d703556cf9c8ad316dd94b9a5433776697b7a2ccd2ef624f6f1fed1716c7a5615579f51611480d074783b3145e87e42d159f3b1b47e91f3f930871c080511b6e8c8693356e17a892c61957148d16f91984f9ec83b3926dbeff6dd1944a6af872864fad3558bbd8ebd1ff66bc13444162a09c13e4e4183bc6f73e9feb1bec63db3d69c5fe3a65e37ce099c7f314e4ce7b112ab290d97586a72e0f76c4327c3ba084348318b5157fa115ac82087f9e7344b37f54148a367c3230a357add9378e4034482c7f45d0fc0a6c3a84a29a3a31768c352881713afe9a69b82d5ca99c929f7aa9d9e1f391ccd3403bd86a2c842137015da6b0ef0e6473a3dc795d36ed13f36864ea81c83f3da6f0c553098498d9f53a3e41f528e89be041069c11c2c9fc2d7408d2bf133f5334e89536fb59a060d9204a8412b8e6b5832c6031a845c31ea89f6ce1193e2e2e1b3847a926a72e5f31cf3e710a592682a85533a42df66f2505d4736f6c6311f09f7d7fca6084d68035bc48d45e1a1a7e530e58019b991cff624b86378b4060d45db07b8325cb2beac2a3d7cf40b7fb3efa422cf838debfd52e8afe96ebcbee8ae190e157974ec434160b81c4deef7e12cdefe2160c6c6283357403355c2cfaf58650146a2ee703cde07e3f01 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2cfd7e4aa6fb0b87b2b364d3a25ec7a474a78d33b4a023fb524babe056ccd3dad992059843ae32f34a3178caa549c338355b81fa0d345863b4160d36ce45bcc56660bb6eef511a52044649e0a4a7371fa767c461d08cb1dc6698e9a8675e4d8fc3875a1cc4d2129b71596af577637bae4e5540487a65ccc30a5a4d6b6fded069834583c7338ffce5cff269c67de135c1809f360b0cb555d5892838c5755ae109cccd93e8aba06863c134a5708bf353dd7f70bdb5df0b6df9dedfd308d8924bef0135a5288de88ae84785f33341488b7e64a40777425f693143b9d776ec67fd88c7937fb4482a46cb3667406a64670fb3c2f6a2c2b4f94b14b844bc8f9e4d63474a52e26f7b3d45ec5f2d520487bb51d7c4ecc54eaf2a6848a5931194be7fc8b39d5d8b2cd5e0533cba6fd671cc77463dcc83902cc18af5bacadc8508be4059c77d3b46fd8d9e956ed9c1d5366781f5774a28b360b45abeedc56599b2eecf8fbb6ec7893589b8266d3bc66e9d9c73a4eea35fc47e754b91e7e5328c79b28f48952badb982aa70280de15e1fdcdd6f73ebea851d948c5187b9ed038bc79a64ce5c7ec90b85b4afee1e255990fa98687c8a9bafe78405f370c77059fd90789f79ab7c31608f4bed678fdf845e79453afeb48d4efe7f391eec1dc66413bff318be5f2817d2337d6d97eae0f5a4fcf485879b8366df5be15d0949ed4670c5cf556e8b51418e8a140f5c044996a327f5be3b701a4e82497d48dabd8d927afe6a9abfca0997375f869618d0aa7550806a3fe886ef008fb7d89cbe2d49a4462f5e411d37441b337fafa6dc3a8d0afd76e2e9f28d79e72135c65e4d994b6fb3f8e86214fbde5983d6e2e3dd8149f117fbb48dedc27dfed6238d67ebcdb7437a3d06675e833ae53f3f7471464658eaa6f7866d0cc9b49fe66497bf6f2caf6050f670ff08e097494221e633c345417ae33abbe6dbc6795fad37a7b408f3e60f338ccbf9d35a71a32e7c1b8c49f0a3f267ca37ebfdc27c8979f2334873864cdcbd3dc96db9826de8e7165909768caa4eefa3dd550193c60ce5ad408b8f9d733ee6ed385f8b6b595aab2d5917eee9401f1b23be84c1e1843126763b2d98c83094610e55545e5478f7251d83282d889cbbc4fc2ae7e11e13874a1cac92000949f82b43ec516de9500f51469975f5b6d5a35de6002e1aa68f84879ad6024b8d913096e381e57776b8ebb2ef501e6a3464f3730e668a22fc8224764a3810aac4c4213e9584516041437bea1920321d4e53aeb3336dd677579f84362265a69090464d053447684ad3961adf10605d28ac5d0193c2f59c5304b14da328ec44cf51e83992fc6f69380e694679556b14add4801342cce20a8658b98846827fb2f440ee21061253c3207c9cc8961ca37c4b3d9c0ce74b36c176643e8ac5fc053a7622158e8aa1ae36824a5c6a70b07dcae4846f28321fd2bd6822293ff4c446654f5837856fb98be568405a822f36fb610301ad2f6027ce1391a8bc0c4fd964b7b807b3fc5b684aad79495f78f980524a808419c13bb1437596621d89cad5475fde6887b973ae08f4a9276c2600489d0d773bd18b0bab3016111c3ae1725742f424d31115be336a5e5b9c3020bd7a4b5cb587c593ebcf61981e3cc6b4b19baa868092ee71812a6791a6e02077c48ee4386120700a054290e0c6b792857659ac01d715b663a3cbf1530976cab2ad5b54e6463168085ad60c3713a41722887e83b406cd67a7ab77596f820013fc7dee7c5c87e776c3976706b3013dd45395653fc4a42f0ce85dd9d49c9f299e38480dc1742348306a51d79d6f8a4285c580ad7b66ce5348e44461eff13ddb4aab80f84948f94c856c03188746bef5c8479c9c9cd1092607822eb82c2679966b17c093643e45d28bcfb424239abc55a52a9209bdc3d70042204e69c1926132588a6759ec3776e8794483a6b2f84319c132508c804112865a3a7c804b496294314de47a8c03a71fbbebbcd9e28e5441c654c04cbda9b7345a73db10a462280eb727c2ec31931d592d333378a6d261aad3a90ebb4d1b23b92d7779a0ab56e8d0ba87aa5413a34c8a18cb1406a8696837d7f547acf97132a015f5a76087f292b80835e32a46d250aeae45999ef2669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14ef7ef8d7d81aa907fece4c1920c7ca9dda3bb9d57f09193487bb89d6422f10cb3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 8998abfcaf828a014622c23957c75e736cd62f555987abe26d3bde3a7ce51899da3d5c075297974eae1a19a544b3922fe4a64414304fb534168154c21b10c77fbdde6d458eb54632640cb6319204c033781af0aa0fd9a6cb236743158be39f6282eed6c27544583e060663ebfd3e4e8829481542ceec033950c77d6769913e3d3c35a5767f9be786cbfda254e60c99778ec2892e3c04f29f1a323eb0e3b4b62704e63b6b6317b79af26adc4bfc6f95006deed7d1bd640515b8b3ba4e523e8cbc0e5b8e28ccc13f88e228b188fe3591302b91308002a4c5e1f3f28620bd2897a1e1aedcf836050b7747684c544b62fa813901ee544b6325d74ca87fc716f8cdb3c5263324c01615c860933501d7cbd9807eb7acdc87d4f9af9653f74ae224cfd230680b04cc820ed8cded06dc1dd046b70f4d95503668e2e45bdea6e38c6a5848177b40e8ccaf565ae7d170b2f4f6b87728f95b9828e9852122a9fe1c901d90f0bfab159353792975b46777e9b4c9a85747f9b50a7bb71f2dd090a52b759ffa31619cca7bb791e748f0028f0e0230109e622cf3bf11ec615b4339ad806a8492eb67e00b1369e15f05895c475fb39cda68db0edad0d60b1dc2fba828742df7241dc9fc885aae84e053033db30ae3712a5b002c52feaef4a5a2b0f2313e0a932d83abc4181c334f223cd32e54368ea1fc65727fd7d67dac2c2df471e71e51de7a688407a3da7549b502a28b3ea288abe7242c4b88afcf6218cf535d8ec8eb0d4ad36786614d3192f714f2bd914440b6759c5451da3b2b3cd04ce723fa2e726e497733d044fdbd6865e05d54192b373a4c72f3ae7cf414d79fbf2c5d9155f8dd25da662ef2c70a18c3d304ae1930e08ea81e01fc2777f9d03ee4a380c23095e2027c4f648b1b84d112726bcf837ab10007bcda9b40c1b9903609c61985123143d509a8bc39aec6c16541e869e69e5a282e3155e37876f635ef010d05acba33e3e7b7e61b0a73fdd809f9c7e959dbb24ac7e32134f2b18ec212e0161f297c5d8a705223b3b70891056c8ac524498e0f8c7ed682fa20d713b3abe50dd9594a6e8c261c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4aab84f32cfc167cb7a843775559d2e26ec51149c4b9da584cf7688eb35d668cc7283c5dc6e7a98ed6e388c7b5cff73abe0a703d29396b8da010fef4e6486be3a8de53f9c03efc93b7b64964f3bd733aa09a1b4c9fadbf856d76908fc1069ce3b9cb9338497cb6447c97ba84bd63309ce6b5ae5c798e3f3076f952b8fa9e8bd552b56f36d458a42dd5354204e62f2ff78a38fba3669a2075d284f76ce17531def56091da71bbe64477b84198ee31b964c0af9d9976e6fdf53697e75ffa35dec268866bbe9d48670a8040485a3425e4b0eb83f028c1ff7583f67733504eb0626d63b98c6a6343813bb335e43f47977b3bad15bf488f4c207348dc3d4bb16332159ac81fed656d2c6cc5496417d734d7956506e73271a6f022bea3c817fb96a7937355709bc6e3bd336814778684f85107bad7940fc820e7d1b3b4c301dc870794bdadcae0e8ecd01f4e478b64d383689f0574673237c73058e083a6ae4439afac36d5ac8661b1cf4417aacd88595030bae395abab818ec6d98685cccbeaab1b8d4ed4fd67b491d2bca6c1fd2f994753ef7babce6ed09295c5e1c8e6a326436ee64511ea8e83d637954388b7ce53980ddb5dd85b66b9fa838f9a290f7eb53c38849c315d67a8ed3cc23d4ff9b98bb4c8c89ce8653cb3f8800f5895eb6c670374fe8666fd97f5bcafcfc0c7e3cc340eb6b119a7726684488f9c5fe43aabaec6a1fcbfd8d8f278ff85948db77df9fbb25bf79e1fea3188c9e90576ceadef1b64b201b7e907a3e71f8cc16fe69b63a3e8a386bcb2b8cf82998512a691a909fb92d5b2324343a6137abe2f60f8aa7870b78bf874e22cbf61c3deed06cf483204e4660e71d92b8c5a1c65ee04b94209ddeaebaee2cc73538b7cf11a63d90f5f1366456f94e436a36b99febb0c5aa8917cb8674471d588d9eccbf07628f261296f1295371b9ea737ad64e3e5650fabc21564718873b653ea7518abefa328b9e5169df387a4bf5dcb3a2e79f1138921baf8843c559b9b53330cad73fe7fb30e89bb578ebb16bcb5455ae217f80658c66c1efad50abe122cac1f5844fc567921fb77152e5214938a88ea6a5678c232e9542a42bdd4664fcaeb10c9b8b9c98c7a03a82e25da09a2349361570f46038b3902031128311f04c50824ae86421abb346bdeec824a085f46a51d86f5843c319da7470190d572668384c46149b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85bf822110b942e309d03674d78e49e19a8cffe729986e06c14f87bab772035908096d7382488a7e450b516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd34146e41b811350f8fd9a86b113dce4735bb149eb4e8c04735bdedc8119ef7a5f6abcd94f55acb7276bb3b6000b9a82831209820b89d25946b59a888285e1fc1904d4c1fd0f39625ec2d01360768f57158a5ae7a2193243b009297702d121e52237b4cf8cfe794560f270fa985c949e2c4ed748f2006159d4879492b4f8a14b8d90c9e540b1f993a5236704cc5740a1490461fb23f3540766d249394a144fc434a226b04a38c755de32dc6dbacb70177189c10d8e43e49649840083a93817342d4294f1ca04f9a9ac52846f388bcd784477d5405a6f36c9774bc80909bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b8764f3163a597910c9aa74fac696b0cafd657882004805d36a726ecba03171c7ae41e68d08e67cb7780d7ca135652137613b3dc58b4176eb8ecc9d0b71c5098679d0b2a9d7058c71cc0d64c7a22f37c63a29c4f007d8d62bd8e245069bac1f2d980c0651591e5a4477bc03b47488d08825d44892558009392c0edfac55a2c8fc83a01577192d1dc27efc76b27104e61f34cabd900784c1fefe7125db21d15a6a4fde7780a9a22a0b52bd6a8b7f2120266f9472fc12a02d17c5ec6938ad416201bc2fed6094bc17e86082659863f5ab07c07d20ab6c9b15312a444f0482f5a24f3a96230875ac1121cde130d6e221341d78a30902ff031122f40c6032661f56b605135464185236a91a8e161aa0bfa7a59bac682ba31b5030bfb178cc33cb877796ce20a6e873c921b2c26e63349dfc668f2d3550fe0a914178c9845b23af95b52f86576c71a23223f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9399b151aa6b4654589afc36b8343fcbdc09a3e5255b378d6ee5629cd8b3cfd555230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = 35e3db34d76dd2648d1be8b7edfb0f2f42e478a21277a69ee89ef2fc115b1b49a7d510afa8a10f55f14f8ef4f9926e30b57946e95a1491414623e08bd6475688921a22a2caa5819751f85b0fc591f97a84741be0a8132d612c9cc8e4805f0683e0ac87879ede6d049e856297f9699efa64855c81a91593411f7630eaf99e53d3a189ecf8d5c72acfe4cc3f4134b65b572137f175d952ad539c10e87be71482c02e4200122a7be856363fb52434d46fc8d099b1fb42c2562a8b09d4c501831d12892c820e4f93472d368adf41b937312a3dca33fba0ae00b0056494d11a3c4a649eddf0d728b15bb68daad968613c36c4c15dddcbbbc91a1ec3cb1cae20e8753736425ce146ec3c7ee3dfe4969320e479c2c4496527b3183bd7f933a1baef9f352180e16c855d5bbb54fdc2eaa821f91feb6268bc6c1248a83f2c587d017c66cc15286908b4ddf32b3fd6552f93868ba01b91480c641929bbb305f900b8003b7561dcc4f7b55759ce84992eca6bfbcceea32da4d14cf6601bcf0a2dedd16e8c62f25dc8bdf3f313032aa0a365aeb148ad298342aff0d3aa1ecc6b35eb17078df36a0fde0b607d0063fa971fdf7551935e61c0a278721da1936a79e43fb1d0e9a03789817c3cc6cf1d1fca3722d433e73a5ad12d2525a3f4d4265018029247226a6862ca38af8b1bbcdc408f862076ffe17b003fabcebc049561305afd51bbff6d027e453b8a607ec57b2e75f2bd4a2111cf5b9cb6024a968bcf84a6a60ec48a98295d30b550aa0407294d0e28335e1d683fc4bfb1078f67bf2ab8539f066c02155f510a2434d34389a4fdee5f287ceee6e55ef5e9a13f1e7cdcb323d6d3bf1ba1c686f312cde818af6b0680d41e997df78b9a0a0a9622eb0f36e73a96114c7d7d42dcd2cfe078b872b4eade50742a2e1f35a3752805baef4071ee00a01fdf2eaa01de47a772d35093e2dbedc34f535764852a67d3624425fed334e1498bf8d8fe2daa712b4f8d075bd0e34227d8c8d060b223b83492c3b5d034730736764b6e01b696ac6386ee84519f729e042b9114dec609eafa705858355c425f92f50378cd +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3923aec9e98d11c99197bdc712ee36e5036c4c9e74a0d54cccad85ba6aff7d38c4fdc8ed1634e5fe1730ca3a645f1dbe5fad53aafdacc909c038b73d95a3c94ad476a637d36e5fd5a59bf87d38af929e3932786b7c235a2f7fe16ea48c53337a946b96de3635a1873794c9d943cbb7a1cbc7bdf9a6d6296973d572eb9c35a259d5c405cf7d997dc87f33c14da9e8169682ebb57f4e306bc6cd6caa7fadcd98d467e788c4d6146c9f7b74f0617b63b18bf9aa07cae97654c9f7e808aa3701ed4ecb24eac2fb3126da710a2459ab3ed013336657cbf4979f6a58b730076a7fcda9e2372a541edef873e3ec0619af0f5663d677e9df7d3547fbd9d0173cc8bbfa65ecbea08b4cd763c8b7caa8ea1c8ac35c9c3e0baff58d97395381d61ec37f2bea4bcec948a7f4ae05b3c3e3894d17d18c463117eb422dab556ea49f9eb65b7d29b4ecfb791848715246cc85f4374faaa26457982a3ebe3d94f5672452235fb079f54e356aad6557b65b4e82d86bf9d847bfc4e3b2c5f8ee975cd0a00cc3ff8eade2d6f11cbfc2d1f5d3e7f5c5e9f443403745ed5daac78859aff7a38daf8a3de66343dda409248f858ff80b135a8fa77911f554ef078651ae63bc27a506cb521df8f23e9a729a53d10c38d6087cd59e5ea6d11f54f2eac6bcbce18d7735abc7785c1656e68c4d2abd3c5eacff5f0ce7db3dfc2dd4c48e9ec518cfbe223be8d07dfa6aadf9aa8778a915693b2f371e475a323844ac38a7a806c5602f9a109fc83d88f8e28b64f74aabab1c4bb3c5de94e64df6c79a0aeaf1829a30d3356ab85b4533469ea707c216548de287750ee9622abdf2bed692d20fd31d37f3b2365b8b6a3b2a48ea9cf75083b38d57fcb127589f1305f3051685bc563cca799b7c4d47a0a3915ed34882df6fafcc73fd3cd0890f41297af7e9c68dffcd8b4a4657884efa4a1e4be593f89f8587763844b73d602c7b84718641ba4467279b940bfb863437335ed8a917e3450c18a9c6e83a6836b78676dfd8234b1c845b9548523833fe6719cc32164aed2fc130ab468ece4d44e99c360c97b667e700d5b483fc4ff8678f811637e2faaacf51518bd1668fcb964116b7732c71d6515f51b0a454d0359384a2ef7c5fd7ea6b47350c68fca28d6c35219a359e273fb5489e8f4200f830036c8c6046fb7269290686241fc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b2021bbb207832f7b17d187a749eca9cd8aad1fa0c2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956e821c0bb623f033c0b926303d77cf8c2284648059c9b73afc326b0ce96bc8190d41d849a9a7afd7091527804812a914adb475b1149f090642f1c8c98d6453cd531cad4b886df17975f91b3aeacc23358b13b54e40d8856058bad19088371c7d8d896b2ac4c8f3443b95099000a237d791ba0853a6c0e821b051472bbb1a95c7a480529683a7978373081f30af1a7a6c713557c38b0bc9b281a622c68d7912bee99ad6d1bd541182efc3bef160358c067a3363b6e03a5db440bf6ce2cd8cd09c03985a5dc44ad7219c41b860eb2a8b6b025da63978d0041d9231a4ffb28fe6a6cf918bc6fd59aa6f8260c373b645789b9e0ba4798b4b7d8b468e52b2aa20496ba9cba4e2ae6cf069c86b652fa7204d717a623829218c4b288035b551c6f614805257516276531a6cc9b6260b50576e149acd9fd4b324ba5a89ab60cbdb682a85aea36230eee9215e442aa22679def37947d4846fc7ad5ea3626c9c20d94378834a4f086a05bc8c252d22adcfd47ab0d63c886947ade8282f380730fa7b827374e617582a7a2fd4bbbe56ab7031a51871988ac823181966b6bae54e93fc63d2463cc3b103b745b367b70bd212b79363b2669ba062c75da3f2037c17a290281abc4952de641feb740c1cf2829f1b3ae798c3a128b76f4711121597dbb5755a2964bf886f1208cddd70b759797349e4a8bfa0779da984f43195b6bc24338ca7a4714458068b0193c6556c471ec7586268879582b64d26383a9489a6f525c923a9e553627c365bdcf32a4158452410357952479d84306c3abab55792bc1466beb85bd8917722289534c74559887b0d8250309562910a0a692b0da73439d5e87007a4b0c2ebcf3c124394975657fc07b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454339ba63f705606d8c7fbbd6e66dadbf23f532d5423802c836f2105a636e9e6da1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 733ff770191463a961d8840170e9ad27fa6a5b4e41214e06581c7b2bbda563baf8d029585137f151f99c9fc4b16e4a6347a4f14bde29406f0b8aa277914bf030b7feb3066d09ecbd19605bbb5b97ba890d82f65aaf7af9ce8d346611d11ea2b1af944fd8c5145b7b83ecea24188b510a1c51f876b4910b266e0738919105261b9880ef5c47c984ffb077e754360834012805f346d31e4227ea9e85cf13a787e1207f0b3957c7260ea4fc0186baf4cdbfe650457cee20ea4d38d08f8d761c6bdf33efc6480c684b2f9dcc3902c7f6832d6d51985f571c55017a4e32574b194d9b7ed474d575885b99151fe9ba61fe0d501a0112c1357912fca6f608660a47a17299a12662205cf302fbc9fecea71811eaf38f748839d57e4e1f1943fe7ca6c61a5c6be1fb65d8cf00d6c3126c3fa354ef5965342408e1caa091920ed868f2bac94d4e2a449d98b9b404bd606e6e4529f4dc2d0c8886dc4074773b999afe8818de9f23886fb4913de65c081e2f3712854f038c57d7082198444b7139de2f310478ecaa9b8d1d552aee3fd7e00069c75324c61db2cddd493568fef6e91a4b44015d537739722fd452fd4e6e27dc6d1a3f12bd2281ccdfa0e7474ac89889b370de87037fb06d1bcb712f1e2ebdf238e00477384bf28ea7f410ea3c82764ffcca870c611122f92541569c79989037dd6143058e7c69ea7153a73f54fba2398018f93cedb0b4ede0744c2c68b3b6deac7e9e4dcbb217434b0b472618e102df9a06f5052157d5e6747d430f9d1e5b4a38da7f723f8f4b82125e1653d28912456083557e314a0a2b40e814fc90a1b25a0ef5ca45a5b7f7536548a0eaacf7a0bd6be28d0da8d7234492c7a79e75b2cfa25f69b36edf82e7f883c018157536cf5c331695c524aff16d0f8dabec19d53f0ad86c8f109b07955da0635c894cbb891727251839229e3b29bfea854a2c357aed142272aaf354c2325a3917722932d7122fa88e01256c236f0a517638c5c455e58797c3631f579f1b4fd8ad1c2719bc28031f8f72426add2c250764d9e623d586fcb28c17356edf6debd32ab0208ee19d980e8fd2 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 9b6d5c2cca636eb3b589f3853c5fb59aaa3b7e7a6ab0ff4b74c6cc303df2d76fb69b0e8683b5f05c0a37f9c88db6737eab28bfa2fefd9623e88cfa7a5aa7807efc6ae9ab78ce34ac85b4ca61e8beacb89f23d37fad0c91225b8dd80ed458e8d96ad37f2287a176ee58ce9da2a51f8d2e266ef737d8958351eab74f63e45673ae6cc4d3aa7736d630c663feff7879ed501079c55b56449f2bb932c4f617097126a85a2e6bf4e923de4e0fb2d07db26c2395d2f8996258e24416cdf21679c0064410bdaaf67daee289d42adbc3ff04ddcc2ffab7199468273ea38abd8098af3a4dc65c8951782a650c6df11927cde10c3909168d4e4699a154a2714785ffd86c6cdaa85586a40aeb6cc19ed22edcc27ebb900786c4aba36a45d65d1015d8a4f4e231b58695a53f0d44dfc0bef8e6fff02a986d471849fcb4947e2cea2505494b4fdf298e79b5cc5d04847c68449ac21dd93ccc879bf7a1b99fbe385844365835a50d60129d4a246dd3df9ae9e0ea37048fd2f3b6809eddbddb43ca5d46506c165bdad665f97ac8836ef583175818cade63a4fa612b3889645e86ecf93d45f380b68379fcca92c4c1c7aa5d1a94f950365ff475e18fac96ddba65dec7a78b25f3e0d5681cc7bdbe656d0c54daebb4801ef465a05ca9b61f53ef24abba39e821f5a1461cdf8bdd9f4bed8d845deac0033f84c9866ffbcfaeca8d4c2e6eea3bd5d92964a1a57250c6b09d8ce3e1aa66589e47131fcbdbadfc9ff58a0a15e20c8364b61fe87dec8f4dc35844de3e85dccef6448afb8b80fb28763f0446854d3ea40ee12988f2c7889b8bec5af016b4fc2fc557eacd82a574ef3d7eb19673b26683f79ffc1a2f70ca48d4424d426b9b4f36cab6ca673f6be6de68ae8d7349deebf88542f976d53ab8091e6c661fde6d58f5f10bc00d664fe0dcf3837a9938e7ddba3d4994bbaa56b378d8d5f14d6762c2cf5d8386328c19fd73b9e74f6858bab76ca807aa8c376af004a1b4679dd605d1fe139080a8eb6836a83f05c7471349d24d5984fa95bdc3428805c78a4bccefb9ef84d8985dcaf7585a834079b041486a7ad9981ee3723f94a99b7abe01cb641c501f856398369804ab87a2e97191f6c918367c653ed9a2a2559a73db3f04a4ab05e1924d3a9af7392289a894057782ae7139b1e82bb32a228bc7bca367af59519e5ff9319aa987356c97ab724b9169302e0b2924307a46839a4872a57b00ad4f8b30265b5d6a3c95b31c248da1514ffa25d908915635732c1a7e2c938c4e528184ea2facc556eaec7171831aff013da5acca8c500038c55eb8521b14e0263cea2252986c9023c405b56aa85791bda25c73db65126967ac8669c197153c14275a574abf090d5e52821f51a479238360305cd7720fa3e239878635d92315b41b2374732216ac4eeb5650a4896b3747c752827407ca7046a315baa63d9717824cf51513639607cc752ed60e743b5f8ac54168497aae4aa3e4c8aa65b97bb03314501b8644608ff49aa197bc0fb427a13600bd8395c94d534b1fa96341f8cec2b218c1a5745275799e93767c44b128bbb0fcf59f1899593e9176f070cc541949b490bd20790584d3b54b369ac5f2a7eb24043155272534889be150f320019aa29b8585ccedf65ca73211ffd8a60f558b4482a1b0194202c16cab1699cbb9544b221c2cf84726608311416267d065d5a819bc05c54fb0c2406bbd4efac451090ce9dc93437312278ac7f7b88f0b69b80b7982f7989c47a18185d2437c1689d1378d01c14dea68b701378e62173fbad1ac05ac1fa904ad1a22895c52b89c8cb548a4cfe168846f996db569cd252281d62c675c298a62d1a38c019c5c08caa986672df818640a90002c12042c3cfa437887a4cb221b65b94a82d7102d07a16333177890ec100c2a8df22987d0019f65e64d5dbc544fdc3a3945a3a77a75099238d0774e9681ca16ca0e9c0554e0e401b401243bc75390b3b4bad59151128f8cc28c2d40bbfc89b890c64ecb65826f202912707f976a2f76463ccb803a945c946d282cddd40f5916c77e268dee390c7a823e5f3313ded9bdc39c2690f15834e44b2cb1335a01068955a3be7c635b7036a975ba7fb986295c3249916b3997c7f0e2845d24b9b264ca4d49a697d1abf3ca9ea6313f46c0cf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb1f9e26333b637ef9beb8881c63f9412b07c47a276af0e242062a54026bcee2bd7a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = d158917317071d0eff707cf8d3180bc90400198ea03f51a2aecd9352bc1bb1667293927639f77465ed33ef8165b603c35b03b898a2e251d775e77a864d8f842a2793d82e7f9a2bedb5e56046d3a9d5802b7e8580d00da950b709480931ef47ddcb0c16b2aca9f156eb8e1ddbc9ade097f6d6771fd77f44a1404289fe091990b81583784331dd372b27462623d810ec5a402e1ba975dcf833e7b9d13e56db1b048836baf7e62f02d97b1c17c9388a09644e8ace49be91530d8ed23327fc04b4d018cdfb6e78df8db7b978dfcc5629735e7ce98295257f29cd2c08262cc41f3fac96a438d71689484d772a638d5a685a93ea4d7a78372a53282e595b685d663c73929040627036439424d7a176266305ad6e381883562e98090508c139f234fa03b49dfe7c7e708a50c8c0f3426fb392513141856313ff3942d8b7265264846f0aa622c51ab6e5d1747aa930fd92ce17008c06a9bc6244259f666736b4e6a92c9a9460aef716aff767a1ab60d2f39c83b7126f15615adc2acfd109a5fe6e790b990994b1ea3c7e73a3d00cae090ce45a5ce26bf1b6b1bb659f0cd4174c934918df77bda5a227ad04a9f78203594f346754bd780b97467dcb6efa68ca43db645253948ac5ff4a0867a64a4d25322f2151561fc3c2f464a6d2c7780afd3fd45fc97b8fe6f21587e8d627d008433561119adf814683dcbc61f7d733ada0b06f00610492529bcabace21be9168e4a75672448398c924f0f74646cad64db5244d2ef05893a48369ec6185e0590ed71edaddcbcf57c0224e1f54b680eab6e624863d7d90bddbb38524c1b76234e4024bdfa0ae2abcf69c3d06e6c8c658dde6a8e7d67db96eb1a1b238add1be3675bd8d4fe320839ef2573e9edc8f7a3e25976bae5d3a4907e984e1ff007bf5f4bec8a14a614b3e7c7ace89eab3b8d98e4bcaedd40665299e479ef41a74a4d6e3407f7df225191fdb1153ac2a38220fc6eea430ca97cfef6bdf6ed34017e79293ed24552670ccbe37a1d340645331708b3c2f9bd21fdf5cc7dda112f49ab7379b2bd8cb05c9dedfb762bff2da3e9cc698611bd3ce1681cd +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 03433176ff3a3116525719b8fb7c7a4cf3c8b46da79bb6c54a2fbbdc396a7577a7abba86eff8b32907595004fd0d8e73eac7ff614bc6def934277883b22eb0dee7dadada3049f5cf30ebf0dcc3e3fe3b4c7c6dc397be7a8045df0ea38e709ddc7384be3567efb827daef046cf29ce5278fcab9ca8fcb3ee7e6baad471a78b24b75518840aedb34ebe3e4017fabcbaae84287e405abfcb537fbab7e3ac8aec98d03d142dcb7fd8bfae996c4cf44e68497352d298ffeb5bd6433f610c6b7a728b5b38357333dd53766b1e327f0da09e875d6d8cf04f56824fa37f3acc06bc113a8cd493abbc10ccc1b76de809feba9adeba1374fd51948ad897bdd0b7f4887b4170d330a4cc6e77a6910888bb87cbc26ccead69450a92bb2c9edb56f23ed0384c90c3d312bbcf2f7c5f1ec6bbde42ef054bf46c998df64c6610bab71d19f3190f3ae47bed70658b64645edbc0ca88ca88a987b9e246e4ecc7f795d2b5cde3eb0ba2ff00b2f9b657c4bd80c38987332a7296c2c065e1dd4fa1baf525b968e5289bc16ecba3a2eefa39a4598ae674d2dd9dc649a6c7eea0b5e3b93e9636eca68c3e461f76840ab73bab93f99161fdccaef80c719972afb7d321df24b3f7fe9f6f2745d97e5ee507e2cdd19b6dfc0676bda16ebdc06b12b38a0ddfde07c39b32847649cd33ece1a65f4199eb348319d1ada0886ba0db3b7be893ee353b0122a62e95571d309e416b6ac4037dde06a7cbdc76bbaac7896bbaff178a2eabaed9aecf102e3b256f43adc249544fbdeae9e5b9d03e0b6ba4c4fdb4cc10a59218446c885e2693e65ef97735ffeed76b8fa8f26c50f4549172ea7a303fef657a900f9e9204a5df1cc89f0f5b3273632badb3738d5d1a4a77a76f4dbafd478c305d5e54a30884bacbd1d7f7349ce03a3d336de71c6c4acdb18951163387b07b2348eff366dbbd69e82d764e48dee3e8024ff6faad2dd2d32e8b7516c3749c70cf991a5c410339cac7d3feb2b894dfbdca25a785f09a25d28d3e61ee8a2cd9eeea85f62d5f293eec560749ae1f3c23b43cd8e53de70a3ed2839f78236e0bd97ef48c337c5da3d501a0171c94c8651b920fcae8eb447d9913047183cdb16374d9b7c6fabc86fdbbe5905805f50bee8c12612115ca16bac13160198873b4f999e4ba1c052767d7d5ccfb364c12a5a6c81232991b5100f21cf47c50c8566c32afc13f7b03fd9a2b09a807b198a4b2ce48d163b0398731c142ca7f13b3f95000fc1345ad1a50952d09c6fa42ba6b5119ca1061a64a5ec4b1323a5be3ecc97bb21383f6c559550ca985c53c4e78d0d660c6baa11527242e61780c52770cc3739edd2ae47c676753bca078266d565377d2aa5cf677945551eac12c61a0a95f6930a95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a48b016de4c331ea591bdd43a51a2109f02601569764b8999bf4cc987f25b3fca822f5771d941ab90a0083d6676a3d743e458381cc3971bacbe8c3a4871d51baa80a1c34462cd46ba338ba319dcaad92ba7e471658097335921728f96b1f06a7b84e8a74cdb635b904dc7a583c4a6208d894caa22265378aa24808ef605193fe186bd0565d2c32ff234b45e2726d0d7c939754592baa93297c28c6462bc0945ec2035e776b2e4526129443c1135cf16620ce8b12825321aefd92010283f6a034fe86474a6e18a62693600d012ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a85a1f69f7aa39fc98938b5bf0f8768c2020b97b1c06d1c3b8773f8d110280a76834fb9643b42fd3dc002e3602ec84b79cea4d9b9c173c58c5417531547539e1d61e7c6ccb5fe2152eca572c7738e2a872a711225e0922e1b219beac2b2f3ac82d68759d83a2998014142491404a6e51b88dd7a21a664a14d6f3043f67cb0a2a697d537f3357bb19a6865172653f183e396a78b7217dd0f18f1cabb936169f6d75498d9027e1c59c7ff8558ef138ed0236d20a23af399067d4ad57d36927bb88b4a0836ea06cfb941617db0efa049b6de6cce0f5cc122239d85391c56487c48b919764536fc11a6b3b3860d6baea255e48d007272a24cc32637665640ffc8c17e013a3e974d6a5aac78ace4a2c9a173240a9cc1c8e18ccf841b4b77793c6028ec75c5e4697a32b591652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d64b9f8198bab9b3b2f2a1704cd4ddf6b3cbc216ddc0f062a72ef40115917fd218f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = c7e28f99c5a07ef7f1c3a5189686dcf99618ea60d0f997ce8cecc5b31e6e817f3aa3502b4945bf769871c8c66f430369d0f7fd9fd6b1ae63a7cc1599e36b8ed2d8970e7e1be12b49d1ffab6aa01d9684b4de5a5f53915a44d454615b5bf52196b5042071075180ad8cfd09f08afb3b1810ed4aef9f9dd5b0437183c22b9b38f17a86a27677e7dc64dc2d5edbbff7a3f3c24e1ccca83e867d4b0c027e6a9a27048a6cb0b1e0f4d9ef9d18702e588b4fa3972aa61ddb24b75911838a420602d2934370b9c73e1b202648801c0eb654db3f75ba67b5b1b40901f679faee7e390080f81df9668f1824027aea2a43c2f1cd6fa9e4e394e8d766bc0e23172e4328704390d54e7a8e7cdaa3cb43397cf4e645e0714e77f5167f75d451483c1d9f97622320b1e9540b9d31512970f416ceb182a30d74fb9a147ee5674d83a0bc2612938e9d7d5a5be9f0e748ae73f94ae7fc8777a1b83f3b53da066adabc238359a5326f7b3079944e550a6e10e87d6aa3a01c5b5a51b4b5ab85f2adc1ca4fc9a1570f9bcc31f57eb521a71cd45a98beeefdced8f9390eb04fa812108e8a59fd3531eba0583f345b1c7cae7f8dec042ad22af364d9f228d594d1c29768205c0197c72db661013551469cfea09bdc4a4c6594c358fbb5c6b236f3ce65efeeaae38b0d78e26afc22087bf9ddbad098e5335de9bcc9258b1ba18a06301a3da939aa63a398ce8e15684909447d51b9d3e2a56b7bf9a4bc7e4e63d5824b58f1979297fc842a362cf9fc8a0b00db5cd6e3cf221e952b821e1f34112190cd623b8643d8d1c76b0299949c47ce4b09c8d2ee956d501b273f371467ebce9aae118c6bce59e65c498436ce4dcd9524351cbfe6aaea71fb2a52e5eeb54a094988960d9035e095d3377ad03fef8176f0a7c682f7794d7ce4d6a5be37e824d3874afa160b51896ab85ed779e7104577caa60250b0f2ede06413e42183e8a00101c8f0dfa2dab6c90e56e5b3a1a179eafc9df1591bd8ee593d0e24605b24aa7b7c13ad482bdf7b95b23e00e06f5274594e270b03a97170bc022004b850bc8daaca34a2c3598f07f3b98693 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 6bed7bc70e80e5c5e9e45acd6a33b1e16bdfa2353bff68de32abac68f48610bc941acd382cf4b4e9cb730a1c44e938ea8d1cbbca26ce94e5eaa297ed4065a7075d5061a991da7960911b76694a94145cf4904c82b1266278546a636b65550ef672a9cef82593b35ccf00995553a6cdd0a4357aa7913bc7627e4d59463dcff8e68c345ac211d3619c2a9c043f93b2f4ed28ebfe6f27e36f73952e4a6f2d9364996394cd56e894b8b38e85af3e5bedf34bde44c867210c4680a76a57ce6f6f39627446f684466a0ef73a3beaaf0c19f21e577ef3b96fdf4ae96d58415995ab5844b65e8a84130fca7cbf4993c53d4658a541a4895659cdb0a342a88d8aae1da6c08f53655a58df23af6f4dadff94b4f9c3606cdbaba00a8a04b99b275ca465f59e724730884ec738ec40773ae2554b62d513dda743439c59a560c3ea907f3710def238f95aaf8737bfc7d15a4a3b3b8a772c2f5f83fab6cfbdc962aaede11db2db5b90b437d30a186ba159c3a853c5de83ffbde798e0643dedf63d8d549bdd746bd808edd43e47668e408b7b8f29334f234f39f7d4bae95831d36da46f4c79f7d9b9d12d8dfb238ea928f22187f91087ab7dba59e48fdb6cfe4ba0c93c7cbb5d7996df1087917db391abf882be366037feaaf436580b0eab786fd5810a504953fef5fb383566c904693d3d6455374d887549da9c93e9d0a7573c84a9aec892f96fa4da685d7b14742d73d4411fab75bedb88d6da453e9f8b97b405dd784de331549f7f19c7aecafd69bd8c88b5f59ff5bafbe104c659fff11448ad236a3520e54251494f64c84355039e60aca4c696b440b8707f4bded0196a1d3881d4cb6521cf37224a5dd733a67efb33029c67f5da6a2d4fac9badfed8daeec5abe191edc29245a5a68fe0ff95f6a4163ada06588e73688e5edd44fa92c7a7af4affa0b6b4fac276dac76594f57f648f86f924267a90657aa3595c4d77fb740eacdc85da53963a4a7d4fb65a7f5887f14d7bc233cc4f0495c5944a43e39a67255d9e24f56e6fe4b44e453b6b25e932ad4e6d1b31c049c5cb0d9554c89cc0d4803c2ea14bc3e6f17c93d23556b9361ab12a87de122ba9264dd889232ca7c301859aeb32611dcb01faaba8f794aa3c0b858ad75e82b51ef707b4266320a6a9ba4b3616896c14db18bcae601828fcaf9e895c571205070562208c45877780fd2a02b3c697634116efd504104709f75426476bac050ababd708f38fa075dd2661d9241f0c31d7b674285ba03cc34c05fb378ef68a3e6a03a1366b8b432186001c56b01169227ad4bb614dbc290e5a085b7b90478b5702edabc9c12544f9a2102501836ecba58763b10751e9db7a29590711ffb3ffc240500995e30318fdd141f6177c2673330fc558c1cab769f202b5aecae19d1479ad32b4e2c59834ab79464770ca619e88535f84c26e219790f24b1bbb17c2b1017464c1f1d102720f111bd2b95d9ab79f866c26c730103aa602fe5ae1710c4a1782caad0674129cdf8791d780095e5d8a659333149b0797472ac623a1a2ff2beec7306a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578e801c35a429e341af97b505df8a46a7055633718d57814bb6e2abb272c9efe0192c2b55ecc5cb8e389b8bc5992b037d1e72074bd361740aa8a86c63004c99ffe50224378d1c28431f599f4a701f3165c8f6030a1ba7590ed49d4300578985add03887d867a3e82b577574c398c56f21c34f6349b6bd072bcf8318e4a8244bec6f93fb84b6716846670945a33ffe53bcf4c82f8c52ae84faafb4b46bed2a9807d2569c90791c087f3af05b88b45345bc099e9ba4f3028c469a3b4f2a1ead50147b208f24b21c9c4582cdb8633a9a58d7820fdd0c761e70855259216e2a3eae25129b2b6808ec1611800d0fbb3ad6179480bc4391860547199ba04b3a97f72c8c4caa93379f559626f6a4a8da750e6ce0651794138c6b68d474bb70f41975b246de5953c5226606102f98a36b66994e2ec785fdc2377ed9c664a05edbfb694a2c5f87dac238841245733852da5427a0b105ea2612a06ee9019b6dd0c3fa034f61da229b5608751bc29bb13ccaba83832c8d37108be5943cfd2173eb8512d16aa1c7b3b7d5ea6491c379c1c66853732d7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112cde4ce515b882c849717a1ab34f2ac0238c868f415630c1155bcfb302d346dc91e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 990880ea7c2b60e73c47ec16e53b62aa6f69b7a63a927834b0adca183d1b8faf02fd4061cb625c7696f2800564d0c9d3c5ce34d34a90054ad4dcf273516e26ec7dd530e2dd83f880be16a432101156b0a211584ce4af6c5b5076e32bb80f2244b615758b6a5be01343dce5c978640ae2f216d0d96980d53b01366a45f066139d851bb6f5d2e22d3346234fe218be963fd593a66acf04c2b3180a01a32d1b440d5413a12a8d89b0a8cd2576cadbe34a73b5927661ff366d6c7d9b0c531cb84bc57029cb1aae06f1174c1de605f10bd043af86e930ec9741f8e1a18892da2378cadea297d2147d7a1ebad21e8567742230e64f5ceb52a1f5bb2576f7542bdc32ce64f5c9289f82f14086e3346fa0f7dc883dbe0515a02f9ecef57ca3338ae60e48f7433a88708e84fe588b68af0caac4f9191483446bb5db9c663bd212ba1f99714c20965d874ae06531f0843057e281ff330415c018aa8028f14a48d1293d2356020707b59829d545bf33ecc5c562ffe2435cd653c70a13def3eb7b1a98290ff8faeede0377072411263846565504b3fd9ce7af2f7dd21a51295c785a97cdca511d1cfad04e0357946c7fbdb5dacb74da3f72b2893b68057c440e19a829995cf19ae1c067b2692081e8abbca54b697fc900bd3fb5b004704e4e4e56be929bd857f2cab50898fa83c65c9a7d70da9cc409d82ccc6fec7bad59faf2ea233e09e3dfaa2cbb91e9a93d7d43000f1922373fe1f8c9428dbc96ca05db0452b58704029d4d8e6f4bc985a3679324f4b454833c9563c23589e8e4c49b357107c3ddb7991ec9f2963fe15c7b51fa9955407e8a0adfb347e0b1f30033c4299293915a11fa4b1a10bbce36f4671d46d5a7094ad05e15361f2e0e9b6b5435383766c4792851bf74ec3afe1d137a7bfcd4e52fc39e856d9dbef28604b160403f5f1c294755690584135bf1a65572d66bd82a8dbe5be91e43a9aa235abb48805067644aa991e4a68014a66002bc5ed3f41661220ee02dd61b4942fff76fd43ac5154197c798418421b2bdb60265986f4ea4064f44e8dbf2e1d39d97829c4cc4008fe82b153bac00 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 58e447071e9642d7c64d6f93dc8a78da78d9cbf38b043c74614caf23eb8f63db45721457c6ffffec94bfd12cb2bb1d587e16c31deb45cb66948677c889b4b638286da7dd8b062aa5fc8f5476fa76a6fdb4d7a5301b4b90ba76f92f139891a8aa5246d9e4f975b67830c3ad58bb2bca48796f5fcade111ac683fede5368cf8fa4d95f67d1394e47abdcff24f6bac2a57e1fdfbbee684bb44fe1183f3d943a4d890340b38d35770c8c5bbb39a5b979453fb022deb7373870e15a60fd8c4f00b650c539d95d8a310868c78bd4f7a583b00f897d0ad8eb6a0afeca4bbe4b665efb79661668bdadfdef9b3d820daed95d586a9b33fa1037bedac7dc9dd87377447b4b0d43546334d4cfc38feb870b1644eca7b957dcd97a6ebdc3f6e65c19d7edf4b6328894f7a4413b583bc947e09777bd84065aee8352481d82f26fbba087b025bbe6c3ad4fbf3c494f43471c1ef060b499eed776ab383c7bfdf00b1aa9b00dda0f4741c3aea444187b712e72df84600487820c53749876f3c175fb9a966bcc0f662e64d9bfa5bbf166c9f89454832e451216adf6e3bd862af68d25a032c83825a8f5b8b4be0d46f2aaccf4b5e997756b758953c0a2b38a4336b6dbab69a9e89621aeac44a748182ed6f0eef5f953878815486af6f1ad2df37d6dac3a56b57d9f331ccad8f2367e8085da873ceddbe9a24f5b3cf59c8476e4f84a094f1c0d95784ab3ab0635a24c96bd1b48e0ce817d27300f2654d4063d0d379c7294607a53f18755e061f5def5096ca4fdef0216e0fea83495be97ddaa8e8e15b054f770bef4b564a539c6b786358892b62439fef59cade7843cda8c6bf48a459bcade476e89a73edd1dfd06f794cf7dd43ee660e50c71c525e48bfaa2beb876512c6af4e48417dd86e8ab844d0cb8e4ee5064cf63748e6bccad6125aea0cb6ed2bbaa487d87b16d39b181d34f17474849fba7ff2fd47883bdb6c8e6c87678094e8f948764b8bebeae0bc09e937e0edc9db6aadc2a265275b77ee417e990aa91f506fc01f5c76a7556cb1662bdbdaa9d2b560a8b813dad4f291fe753c446f5a46665f87ad89447623668ba98183ca92c9075804d082ad2d17769032e77c50484281428c00320848073a17bacd2c47ab391fb9472d395a6376b3f44aa625c36c95457cbec00641a1cc4e248ba7a7012904a73179a61c1524578f739f7a5998355276eacbcfe462f2a82776ccc04ddc089cd2407f4b757748089d10baad85a3819d52a6560970353abdaf08dde151555f92b6953c0b6c51a7cb882ec5c574c31619d8c824c605102bb8d836c68f29578432c8515c913189b650ada84a2b5795093b5edb2a6e0b13b38fa3db500c7bdfc8dc796c7f57a9b95cbafb8610780eb6787d36067f89831d98590b91d96144d7a4c0fb1c34455902d49e39fceac427d723b027709338628defc8a771a055cd8bb143108c9724cbad1729b99c8fc675d007b7c38ca20b14c04549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499170a109ae98e53b807ad277dadda57a4d13f2397c167ca0955e3148dfa1b502726c908bb283bb1b41b89e15780dcba45485ab771f19f1f0350b64a4ff983a5e68982523c1e936b9be3c38ad892b0a20b4d4ea2918498065d2431e7f950bb33c68b23167bb4693bb258610404788a37009a24823b81b95753bf09aea4a7b219cc8a9af4632d9c5e4790158071318e9119def243a30a7925f17233098d3c594f1571abaa0744f0e44714d0c8765559cc327e35fabe67066af141127ee7145546c89fd55a852712eb8c9c77bc649e847d229958e0d7a3947cc4284729209a704aa4640f0c73dd63c6e48651f62c33f2351f5d90bde888c3dc116827b16d8071a01fe02d1b4b485e9779217641f0a0af2434574ef92e180c116f44899afa647cea8403a831ecdcc04faab8faf3215d622dca40a95decb5a833206866068a6b49ee588151454eda821a35a5937a63c23ba0a0d8c5657d18777aa10492b1652ec2cdd22a7f800708beb1943ec347fab41219171fa46b7b58006f91ccba3b69cd7603645c9bb584282dbfb9ad584c4ec0c692a25795111a18709072be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca241ca7e50ad46000ad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f793b60f0d00c09af885b5a0cbe942fde6afc4841428104710823bdcc12319eb35393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = 4f215937409d6d013a250084ae82d22c2e96c529b486896b7e92039aa0fe6d9902eb0f0371b022a7a294ce0ea16e479825eaf645005f90c598dfb44ed713b9267f9ff7db6da752462333351a0ef2716a95103b1710eed9e14ba4771b831b89421bcf754eb368fe4c468b43a00f4b91a47d6e2ace48f79b2c034798f8d08757b665f3fe7d0fcb80fa3e76c226311742b0d7d89369166bb208ff705a4248aa1bcb4cf6258fb23d62de3d37b7a1d8d48a3e3419917bb6d54accfea58def098795ae76ebb421254e1d07f6a81a5833d6994ceb11216c66e61194604329e2ccb1889e0a7deb3577049b2fb54a97f1cf38f6d353371cf4e12c0e33c16f6eb9bcb0c88ec350a3b2f4d95172c0638ce580e08800633f3d24dc44ffdcfc93747846ef985c24b2b3f27ef2ca50c72b40297206fbc64f25b801e4ff22ca8198e00a8fbab61c390c9d9aa93c41a5f07f31efa7fc5d3e1ac75eee9aa2b5abb80412360a9df05c5113b64aee78836fb1da8e5e3a4b675250dae4f0a16f34736967408c6bfd0e73a02e3bf70cd27b7b3b0461fd3115de6749621822ee148dd3919de5141a4e5b2d3c61bd9424b4eb59c51d026c12fe983a0ee925d071dfa6f028bbf698e4d5a31e9ed71967f81c9f7967176f353550d6a5a0ceaded0336b9910e740ac439b66dc878b83bf63656fbb1a9ac95f00719295ad6900ca6fbea3c8745deb1ba64f4ddd34240c4bfc9da156a5fdb178bd7ac82d6dd8f8d091175ceb907ea7d07305745b67f1af18ddf260608d058ea034f90c88ec87cd29c5f3351df52f67d63d4d0d810691c16e3f2bdab6311ff03247070e717902f0dd1c3f19bb04aa9be71761359d27c3f62fc40f4435e6a805c4a7284031879289f500fff831963a7099ca13c9cb6068ee7760a6f0704b20810c3dabfb29df713d0dcb96e7e43c3c591b7911ef783559e5ead8895fbc6093c2aa63536c8dfdc77c776e10e425fba44138235db7235bd69ba92ab93aa9389bd814ceaac4bf171173f9b958ce7f10db1aaaea429f28ccc937dcc043b5c0e1eaf4ac5601a0eeec046db5c0abffea6134a27b928fe5464 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0c1d7bf998c10bbe47262c4e15ac4934ad33d6d6a0804468f07be7abeaf222f73d17c94c203d950719cac69a81af4985e8134e67b8cc84064131beef1ebd9bfad73550bb5a00696141f35b237ab114aa4688f3b98a563f1e2b7b8f85c5d61aa9d759c2d6d45959be8251f6fe8d3ceac389389ddff78e778b42e67c963ad484e78eb58bd633cd477604efd69b78eadb93393768453ffb739669923879406e7c9639fb30b66a0a9fcaed48d42f64a34e3531338f9abca68e7eeee9b9954282a8c87c4a5dc4bbcb36fbfca18876f8c5694be86df3099be1f6cbd18cffd92d693dada0aaf8a496bf4777fc4a061f9e483e51757fcd67998de564e7d40e90db2d6256cecb57cf495eccff445ad57278eca45a8b64ef62c9e4a025cb60abc8e009fda30bb345eda853aa4dc87fe9b9006ff04387d95a2d6912b65a79b5cfc977506fb4d7180c8e9e8be78253851f09f6ac09d36859d89faea80d45a5e39430ad1ba48698a49dce319473a91ba46da0bcdd51856c94afc515283903f6e9a1b852855f35bf8df4065f4d86b6ca928e4d5fecb8a24669de6af123e3f0b6589a7a55d8f935594b0d707385e8c76885c838e6e678ef172c72d38f5e43d8fb5e6abd58a3b7863a5e821e893f53b2fc99d11c3e840bbde0aa7c92db4895b384dd2be47b9b5b34bd034f5d7842c2943eb7ea708079cf55ceea4b2d74824ae7c40cbfc0c5e66cf38831e4c875ad86bc15cc3ecfe710e4c0c8848ffcc67521cf91dc9aa33456508b5faf89865dcdf4a3c8f7e900f6b69f6bbec635bbc088bc79d7b69c7a3e3c74e3f9ae892275b8ed8a38fd384cabd4cf5c37bb7eb5a8191e8a8b239f3b873161dceb826d510664decad69fabfe43e487aefa16d56b188aa05a933e1380931d48072baa6d1ee62bf56531ca42d39aa5bad485852743f66f6f36a881106cb3224facdc69bf6e234cfdde69649ebd5be59c284869d1d7c34e86628a198ee27df1d6e8aeaf9f79d637f5c81d7ca35dc9ac4add1b045a9a1c8c8af89cc89bf959a8d43d3d7901d9920be770ce97b34828d764fc7ca83c889f1fbf4e2f98e579e865f9928843b50fbcc8bbe4aae3f4c1942926ddb8580ef06adc73a7f869842a3211bbf36172ac6972811c887b350b5189a376ad6e032234c0840dfa0a7dab2cce171e47e3945f2798380583e4e2b1d5188b18bbbab2564a0a06c174c577c91000e1dc3c79c1a7d54c38ffc21dc0e52e62a3c093a30c0986aad289b0c45841253c39a1a00b90712f4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a630a00a4585f6a5ba1c0ab2c16450e0a30ab06670465628d763b5b0326fff11d5306abd4886cb304a515389e3d9cc4664039bcb80509661ff19bb372a8c8e121c94f5103994b91448982bf1627b38741a8560adcb5101b68937673a2ed345a6fa76e10b2a014115eae9b4a7ab8ade144871fb2cef1b10309a6ab67b218671500c0fa5ece8952d2635061524be47a33e4fc06eb1409cc4c7bead4a0ba8007df2b0d475a4312f042cc6b75b3484b08099c208971a07a054b701c193cafb509120d89579e282b07fc6ce1bc55c10012ecf1399c910b827a4ddde8995848861a8caffed9a284b829de0bca22585024d4a2b5946c5385267e9052141a5e27ec2b75188195d7c693f8c64b4351f2bb3076d95db950905087bb14d87831618e9beb5583064fad4952eaac72f3a3079da32668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab6712c40b933d663ca9fcb3441c62477e3209795150c4da33c9fc13b0e421d23a9393a76728f55261b41c8dac98e48c24d91701fe6c719d8964318655a0f9bda8e1c876c04a1b729951f5111735b3558162c1e27e6a9c0ce0ba0953620d6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c098e07607648179121d2ab55b81ac018143724015aadd1b730c274a6ec281ef446a8468515519b1477492e5cb87e0962bd9216f9863bfafd025b0e00c58a709d200be9187b654fbc6f76b76092c1230526d051836ba580f90e368a4b201dccc9a3637c19799465e3685eaf51bba70610d88b6f08bc6179ca607241b62e54e94f97257838acee5a9375b347d9723466b6609330a071a3ff9d1acbeb4c41b0650616689005408bf8c292b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8167a2fec4d72cac2ffd844246eebabdac0c074e4f984433744e31d299faa389ceac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 30344d0732fee736428a73d85200691631752da1285f83dbb6fe91e28e171734a23671d1f4ef6c3946bccf8a4e1125f7b3e7fe573b69a7a0b8d1087c4fb3b6b53962e0c3fc1ad0a90ed96ef38b56f1cacaa428b3306c190985425f6ac32d885472d536a638195356a8b800b16a5af5db8b52da23780ea4e91c8ade09d521efb66af3e5c2435b2f91a486aa44636ff831c043948249d2d302ba900981a6d01ee3d442753f078a2bed76b0d805eb6e5302386ae5867eb71d302d8e4ff8b0fb1fd50c748aa9a0a313cb5774c8652154cc818b6c6ec44adc1bed7f8d5face8306d3ee04aad9f5c5767b790c3d83d37d817daa057020a95ce974270274bb4861dd98b944056f178c5e77835af65823cc779c647242770097eb426d905e5033d8ad7dbd272aef4849801bdb8afe41fae1a45604f6cd89e38775f095262bc72edd6032bb24fbb76010c443233c8df3ec594d30f58413935198880b227d791e06cfca2578ba405941618af7a7ba604bf2787366349e96c498b82c7121478e68bc632f9a02cae8f964c9fb4b7a7c2d2b1f9e45584b505c41c1af3d0f9c46448391506616f97ae657c5cbef42d47d5ba6fd99ca0a430b3ed5567aff41885e542950fce7b7e6a11be1d4ccd0156bede44904ced82160a89c5efa6dc0c360ef0905f4d21f1e6cda38e8422c30e3bcf966d476518fea22628f7b6bc84fcabfb908e203d05c731a7c59e76edd7f47b6f6f1be60ec1cfed497e4c5fb1957a1c02bd64c8523cd2e1e807ec604180cced79f5189473557fb7272c0772391e4f8e4fcf7774c1ff455f2817ffb83a4988d6f8a8cda9ebace4064f5e55d1f258f1a579374e4f2105b5e400f5d03e3d2462bf8a2fd5c64c740448e7823798cabc220f00484379b75561f01f6c911e253f0bec715fd6165a299acb7de62390b754899b76b5085ab75286178895b927e21b08a9c7f96febb4dfba433913da7473145939715d881459ef850b89bcdbd5833268a1b6dadfadde90378ce71f92e462ff402a5205af2b0fd2503159d803d20424ca6b5f2864aca6ebcc1ed24e3265ac46364d60aeb0bbef62342c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d2dd8267ab33fa4adccaa9dd20543e59075f88eeb20953ca4b775516ad7af10c6ecd7a5e299b69fe05c0939cb6fc789d94c7629419f5a1dbc9d7a33d43af970b36a76f5869efd38b2b8eb632bcefe39ae14c083496b5bb8c3eea174695c29862634cf83bcba5be8cfecf8fb9d517c0a8099ee1cbe624838bba8b5b73a463e1a6d98996e30a84be1cc8d80e643f3f5bd8f1b84d03cedb932a3cd7b9f1a1f97ab8f38b099bac9df962ddeccaa1976be86a63b39c59512ad7a39d46ba6451a2d77f4c39d70d9a6cc305ca9d9585020d89ec43571055f390d8d704375458636921ac93e5294dab68d40c03daa53ac808f8ffc67eaa09137ca95d4fe2f7e456dd85f42ab98aa7f0a95e38ffbedcf9a6e37e46ed196eb7d346cab82bbfd90cd200949e955f79a4757805bf9cac3fd90a8cc6c39495c54f73bc1fe0e1495d139650ccd6d097e77573884da44ace0c6755a8454dedabcdc92359ee83f46b045f61da9ffa27fa96bfd315b688471d50f15f301f1be70006d80ba5f18b583f026ba17bf6e11f1ed6dde5bae23e4dbfef629d5cb291d396bb04cc48c9fecbcfdc476bc32f155b05964b49649d9e5a8f3f9bcb5a29fcc8d9b3858a81e9ba89a9d7a88ed9d838f862473cff60a38d1b444edfe4e1f8b4c0e5fd90c5f353f897cf7058d1422861879471482a956f69ee16046ddedbbd68b5768b24d01a335a676b75bff63ae86e4b1ccd3a0456d769befdd3c99ceaa6964ebeba11173711c7601fbb3fbb6eec0f73f51567b51eee63b83373d00fc00545e6c25f425e0c7adc0e857126dc0f4a47c026404c18d2429cda373c991ee5c4320ba5677d5af959dd6af3a53adad21ffeef53b361072688f475f6185af3914991f3ac7ea29cf0878990563cb96688707099465ff3b65e56f80a15a11cfd5672ecc7e31934db9ff6997ab2a9773a53059d3758f95bbedb08d394b88594440640158dd56b645315198d304fc18efe55e053a63d147b436aa8502ca97833c0450bcc4895ed83ffe866b5edd84e8f3c6ab231d7d67a874028688469d3f6b5a49de1fa3c78c3e410dbcd5b2572c8485393148da9f0c2475a69f1e96c610badd664c99895021f497c13111930880c02d9c8ad7a1309085826b4116f9a9cd841981f766944137de5587323dccfbba28366f86ae7a7481c054b2dbab86823b77eecbe7d9088a9ca882eb7aba5aa23c27209df4760e70b4876b709bfd225b0ea9644fbac9de01df90648a25b5fa9a48228872ec2cbaa09880100bc24f1414102d92a5a206399295333485f00c111ad49c0fbeb5f4149477e46075377967c310fb5231b9d6204bc877c31c524bd76b5edf23fb9b091ffa3bc2ec64423b02f673505d5c69dfe472d8df62f9775852b901000d84e4237aab4f32226272766234dda706fba5962e816a98586bc2a5bcdc1db80bd9b18bbc3c82d01cb1b67369f32741d50ca57a45c45667d5e5428824463c8a651afd95e995a4b860043cae74e265aaed3320414989a346a63f0f0842e59972a91bba62559422705ac6422d66098747a85737abeb01c00b4b90311081a17c6403726ca39e27c8d426845fb624a956c39bbbb404a8ef5073e37078ef535b9eb581783eba401243b02d750f5034d4a366c197994189846dbd82712663a0fa0beef5847622a904b04983b519955b717025c01d9e5b928d4b860cb0fbff76fbbc22b4761a5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b090aed1c9478a68ce883cc9b8960e8755485099912dd509e9804e33e86a12a75b53d42f0c784c6a73732a471e44900d41ec9c4c0b006910202b1b2dbebb65b5d7471f189faf194e642887c5631271649662f4b235829644198bf8e965d9728778a65405c4417eeb7ee25502618ccb0a0a226945adb0d73ffbd2ca47a5580d0803a56b3c3bc66e877ccf05741e29501bad787d8b588f97c20c8255687ed3aa1631122c387456088d1209c4a5475f61d12c2b60b1776244512a08807c09e7c7aaa3935125f235f8e872bc4356a21379bdb84a25b132f4449561e96bbf8776fab1c681d42575a1bfc0dac357653996d41aac4a9341196da05c49ba84a4cea37c818ba0f0408c8c9335616410b1d479ca035656119236ea9d6979366163791648088fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab955468734662471c953fa516b35b3a53053ff396b7e2798fe07a2ecd549d6c063fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = bd160d98b7f46bf964b76e201dbf59587476e0c3aea4209510772e34afc0790ea5f388fadc8e6bdf3510d4c2d1c3a00f3008866b239005beea93fc2c2f632bd6b30fd8ea0808e066778f310d4e0fa946b135feb33aa0a270e1bf3d2197891a4afac3fac4dafca110a08c120658113ec4caf8e5692b313f02726d8f5369790e0c3c10a7a4d852c8f3f6c7b1e064ae8ab171594cedb913cbc922cc7088aa99660b03905531adf3babed00fa57fcbbc4a9be2ef43ce6fffabb792a16f17cec3d09b16a6109c721057517b50195112a67296a14ab51ff7dd6645c07d1eed75b4ca6b61fb269cf3aa82b937c0ea39412f2900c56b9d7af897b255573c114d23e536880d8f432246b8563841d54b673fc0399dbecb010c535e722b1822de018928ca2657d40e6d934c20d833d8488b44944e2af6754c5bb2255576ad58388dd4051e29fa2e99c8dc289ab8c38162d2c0ed342a8050394c695b4b6c3aa81371ee37f47464337808eb02b8cc78e2f01ce983d43298fcb24ad3f19fb903cb582fefc9a0b966c429c99f1668fd9f56b56a40134da74dd505d6b16d812b1745b47f603c7dd8fd205612c6be07994ea7bc17842d601ab0d54b4983ab92ea8d2202dd69be38bdf0acb384e9555048da6ebad1b28888faa64d5d2104a833f18966cc4a3a30ce23ae37e7b19db70694a2f5198411894d6251b65e7dd3aaf22fd74c38fddf38f797fed4a6204c444fae952bacf6040696e6a0b9412e29779f74679cf4d44bdd9f2c2f154e2a093fa892f71fc65e9854ca64a225deacf54020af1bb62243540262d2cd8c3e74547608f82cd0af6cc1ca3329197958f9b0b64949fa57162afcfd5e087ef5c5e7b6916c316d6278fbeacb8b4cbc16566eaf17b569c8cd80e37afff1a7fb914431b25178e881cf1d0d66199d9080329694e03228457d5dc76e28f32cff849e5533baf254f08d15f223ae5c4c91b1bfbe28266ac99d8c0107d7c32b6df0b2397db2281b43cb609eb25c3f02ae6bf15b6d19ba0c56e878a07fe49ce56830a67b46b44441911c614ae9e491bcc0b99da7db92bb8d2ca38c65ae7a082add92 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 1716ebd1a9b682d6741e754ed82792d3dcc88d3c8e5cd88bed23ebf22e76b01dc5b6d690bf3f5c67ab7b05c67eaba3c3f58838897c5a1196edbf757f9937cbfc0ea668c84f2a0ca7627497a4e441743e506dcf8c68f550c9ac96ec2d30585b306bb6ff030f81b8b59471fdb59a3c803623f556b381c7cb8d8c365913dfad92ede442b534fb09bc9a79fe5a4eb9044f552207a8d099b0f628cd8acb5f3bea9d5985a051af8f69743f5d2f392aa8b18537ffa9de9969f5c0f45354eb18b961066306fe83dc29891f4784dda37f8cacd58c6dde1fa393c2e9ff37175c8176cf4fdb746e377f0c97aec1d43da947c889269eba88951e9f53932f5c5eecbe1146b2561ee236c34517c3b1d0feb91d17823ff4b2273ab1b276c0c89b87b086b3e0588b9fde4ff5f3d3d465744528388bfb90d434e4b25f9ddb7d7d2ee5e5baebb05667580b5fad79bfe1a8cbc0c90ef84d23504f046e1b84813157f55ecb6f193e4ab1d3e87b876dc989f6cee74c00c956ad1341af66a4b99f81d10cfdaa36f0a806b7a13d42c8e4d1537d77ecc9ec50eeff630dd55498b1c53d42d01d3a9e73430a0c5298f55f4e65e7f5e393197a5c950d705758c9a673d7d263a5dd07f871857c29a97216a4aad88f4e2deafc3ae7c38bc851bd2c65ed584f789a34304d56f3da3315855c675557cb8bf177c3847c2ea777b3b24e74572e1554285347b116a7220f48f73d7bcb8f8369b8cec51bcca4c7d7e508c3bb0fe660b5450e4ac9968ac543485e228ffa7f535f272e6bd7378fdf28676feb7ede34aafda8ea8067f9c11b4cf9ca7be46a3df96acc14cb4b6908be9a79ae6cde3980e6bd998aedd8553a98b456978ece7857833028eec8ceb467dec226cadc15a6bfeac5fe81bee8b0a3c5e9657910063cbc2675b5b7f4d1f867c08fabe2088e83d3ac0f55827f864b61ccc43a9d6db818319e46dfb17d7cc0c6bbfcb6fc7d0db5a1a6341915941d6563ace4e0afb960c1e6f6dd7875058ef9a3be3750e3a6c59e616de3b44b1888d2bb5b99fee8c4aa6e2e386dc933b441067ec7e6b2bd83dfce44fc188fdab3d5b7154c8228376c399946f6089f4eaa70736726a20c6e2acc75ddc880fb015477d3ab44c36e047c4bedcba5e2d775628154eca695261b5825ba495f84c925f73c5e86b59fca1a535906c29b0546134469aa2fa9a273e987c50f2b5c1f0b52d79984246c653bcccab49c172a990a72d93ce02c2a9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f4715b977580345b13cb945ee374a980a3152e1690469c47f8310d02ca01dec8f1a149e6c1a1a4ff0496c18c8ebc67b79127195341b132947ba62a89871adc0c9b32d951acfe88334189aebf89991c9b73eb0b68e6c2aeaa1455aab124160179ebbcc40667ec7159d8991897cda76e31a8330793fdb035feffcc74e251993913c6aac99e5ecccf5f9289343989bab7640c9c2a9e2c622d0214cf9c696e803d9e119af0a90fba50199032dbf491fa5e260cce4b92b8c9892c8519ab23031d9c3c53c671a4008e8ba31b3d1bd4c9602f045b92e42040ffa00f441579b105562d507d6117a9f5b9fb6e50146ca47faa64165c84a3c9a77a70963e3a6a8a28b658998078cd91cd4599cbc21ca68d13395b907e395b581b490b3007af66cbbdb222d78973b7b69b37c77547669695c347deac03374c209fd163984f03f59a6ae8de53a169041c35c99a4c95f25a759ab6b2f0fda12e1744a85194ffa736be1d67d7977b32eb7ae6bc04220c8846f157aa7d05c12c02eb8d3053059ce8ecc34791953f00077a4e13c001a48c28500c025c4bcd11e5ff83ae9e31e0a6788ad70a71c1c0d5da418c6e6934fc959d70259b606c986c70348cb7cd11a46be201c474b819d8b54b538c78a06a9bcf905da7469d9c045686a3b38e345e64994cc0785fc12073ce961763074f4d2aaab6c059fb67c947889dde52c8ffa432c9171cd16133d337f10546d864b3cf3243b2f3097f3314976c183128aa1a11916e6365749910600e64d96b663b236c43339cf979c717c6b03056081d9ac4301722330e13cdb0a75de4a4099f7a615419c82e10c6eab027447a78303697d8089647263c0b39834986f8da41566dc254891bcf93014b4b33e2be203b4e2c67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791f7310c0531060051469ffcd2f88e3200bec6c721bca1fa4c9e7bf1773d7ccb19d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = a04e02caf38c63d95694ea94d21ac94fb8439fbf40a4b4ad80642bdfb8cb31c619f2eeb2005a0f0b75c4e07cdc75fbc4f688bc66d1deb0c0c88b19f12d4b5489a04dc4fc98557f97f1181d08e88ecdc16d15462ce5a532c7c3ced03ea2c35e9c7d7b0f4ceca12c3915e252ed94d26e2595ba49444cd22ea89436dd6e77e7ab41c616776af6469266cb500ce53607d1c1c7d6c6900c98a2bfce54877eabafc3b40d09e6cde906d9c86f6e75e80e29c3630184eda59e5fbc7699a2f46135fafbb606dfd6b4375c57864737ecb1ee0acd6ada573d2315885e8dca584263253a07daa6f120bcb35c7dd366b207901aa978756d34c54a0737a0869fd0a0e1167bc4895670ab0cdfbff599d43a34ef1a9eaf8761f98fcf6cc46dab816793f6c4afa2f62f654db94f1eda6539ec7bf7b7173e2de335a32c458ba83098533eafc44093f4297fd1994b809a3e6db0820307eeb75a93012db0932a46229fe025f6fc2fb50b9888ba4f52e628f3a66025df605ac60ff58025972e45f75cd8828b7fd8d338617e3221dbe9f9cc4bab1ccbf2bc1ac0b7c603d15f6268956b18bbe3a9a3fbae369144cc89cdf02896e053ebad7ffd16096a8772dc9c5c1bf29b1a1e3f76d09cc2e5b4324e551a7d097c726c26dee259ca0de91676a20b577b12d02a127a81dcaf489ec1af1eafb246b5f36000f77f57989f4e187862ae403b0e6ebbba782988b3a1151f7d3bad63c4f217f51a351474ea782fa006134469d2d87459ab774eae21823e5fe6a3e400b2da3e42af4f2d47dedff032b11576729e9f6c8f7908b444e788575aff60bfe2c836d8b3db9ebe5cd01e50855ea26017eb9a0590668cc0f1d863961678f2b29e087b42df2a4067d711db59f78fb97b393db0abe343e151ffdde87a9a0d1f5d401e1994d0a37049285ec5eed3ac635163e3c4080104c76ab2f452f20cdb37785ce1ce5aa33f9ca4f599610c4afea560b0779cf0c3b1d0ead1fd8a6f352c6b1ed314d13a5e85abeba7987a0624a9e7a6e9e1c711c88cc2925c853cd14971e67a8977e67e649a975924f63c8784d9f3ee80ad4fc6e1541d38ee48 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 96d7a99c7bc70e97783a8b4e9e6c33b02564b959e8989e54f71e7e8edca085a680ed2af05b9ea64e7fd32e0bac5047e7b14dcb5baf5da6c96981069a516336ea5438d983e5c4a7ec3808357f0fdd7a9540ba27509ab9410c3ad003d8eb0a17ff1197f39c87f829baa0893cf2fdd8baf62960fcbfe18ed5c000d7486edd5e9b35f7278d4079ad8a673ce2fea5798418cc03cfc8d475833b4ca99906a9b9e9ee0c2aa362fbb5963afad75a64edabb6f13cefdd0b763983fc0b2e90af04b35419e25a3851b4b53ee769ea559986d7f8bab94baacccac6c06c82fede66f324d4da49ad4213c4c7f64942cea1256dabcdc7feb406d1589fcbe3cee707ac56ba54737f18fe951dd4a3ada57a75de56a45498674df13e65500558c0bfa63aa5f6b0088736d7e0b2938d7b8af347277358d8b842ac9127a8bae5dbd2a36fd6f36ffbfc0887bec9b140ae70a5f436accdb3027796fd4aabd306d64368903df3e19c7f655bbb30bc4958ef57ece57580cb96b9d875a3cff34b1c8492c51fa272db89590cc7180d6931589e5d5461464e3a78b7607f48d66ab83f880eb874689b589498956dc2fcced8739333ad49f81114e9ca2fade1bfeee61d6d728ed87d59949523d3a486da99f6ccd75892840ca8947651637cb39266abd80584fd2ae97c2fb6fea5c50bce640026bd0e38e0a269e441adeece073f29b7c0b2d4df42e7ed26997c6ebf6e77ea3393faa75259d30cdd638ec89892fb456e95c1aad888800dca3de7d4eef8c2666db4caa39874f4f71c185ef06ccdf1944fc838a163fb854503fc1085e7bdaf902687890293d524bb51c77ca5b2274aedaed66227d1664a4eac13f690fed9428bfd57f976fbb75a4b39a8d8f6632653f8ddec9dad23ab888d9ef88ae6c2bf5addf3c3097e4f57c9489f25a4a7b4e4c279b7aae576be7c95b286ee242b45b184d65e5f9b481bd19dbe9c80185a94e6d46cefaa95a7c03bf4933fe65765a8cf60577c49d5e32865b0f6bf65e86543d25af0518e57196c5d0bc9eb5b247bc30da2cc4ff1567e395f2e6739b69f6adf69060e5bbf83faafd63676cefc65156e2972584323c917fc24681b6168eca204b8210bb3029e05cfb2e08d479b413d987152a0203f0ccafc45625647b57e3796ac904643c73e9cd26653600209a62bc6498de68223c990672470c2a2b77289f41f5e07ac7320500a7c30a9e99544f7837dab6e7b7b7652751457d96e23080432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b576a242131aca3cc9c08833304dba85c07c212951af1303e91206f4a54c45e9ccaa1e96fb07bc27707311aa2a1438a9ce7355dc5861592a4cdfaa13e66245ebe67610de4875b57181e118930e671b34104a38859d203ac064b417a30aa8d23af7c5c732f4c57e8359f0b698de6320e0940a4754904bae082ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ad9109146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ed52e2438b6132400f3bc06f00c71b6669f02735229b9b1a5b580cf271003b498a6c6826d553cc736a19a6cafe69058ae8717b91842d92bbdeda0670118116b719264465e61d86b975a843a5c62a056b9af8a7cd402a747a6b758da977b12214608cea52540dd390135e28e6160468c97b713826dbaf27aec20b34e07aad340351a64223068318113c5148861aaec535d15368a6b096b559f57b2842713c44d46bf001477ca0c92bb47c5c502b4e5f22e7aa087c26bbb36d9acb0712af2fc7c09e55f1fb71238e33d05d41d186790ad725afef46173134620656449917d3e52320c8542e5d725ece72390f637af286a8457165f5622608c0813da9c78e83334005732246091aa5877e7ae460c18ba856d030a856a749d2740689ef036fa936ff3e25dedc97a72f539b3a32f286a02b79472f28089a6b4b9b42134b6ab252f377e819c233a16be6361a59b4a9d52aa18c18263fec2602ea9b8e9164bca2946a31a892093af891a3369a01e169594d0e50fd5b3b144405ba1139a8d167564943530a26522f3216517144937cb5a14b98300a03d6bb2b8c13eb23355590cb5989a4e26f242ed7b977a36c65e768f21e9417f3180c304009394cef9bb74fe1306337b7100938260c68dfa7910df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723152c13a9a4dfbade0f98e8a5136358f69c93f0722addc008952cf72e1bf350b1b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = 707921441f685b510f6bb24a1dd8cc65cce11d5ec420667a9455c90991892b0a707ae2d3e1bfd2371927de187f9fe0af99a69916c5e43beee042bb17e88406e6d54de5775b92588124872ebd3ceab5ec658a593514a2c669ff597dec7c1a00c3988f258c6461be0c3bcee5a68328586325cfadb60b9f9ee4824a9b7393116f691b7bd39f86edac4aea70b27c66d6571b3f7d7ff867476b69d8f10158cb013b379d5ee02710948161359c5d0434aa6ca35b82c0d0c23597e7764edbaea53943832207f3f403c40af1afa2af4972cbc91b413a89c0d6ef9432b733cca2ba1f1f6825f74a8986c1224085a81dbecd755057983116241941ddf76b4130095d01787e047711c8cf246c03e1d8c69e5f212415261256d1e232d6711a7d7db344fdd7380f20433a30f60799f39ecedadecd457db4ede782c281dca56a65723af91e57eed98bb1c7d2e4d3f5743e6fb7d1c76dc1225ae2c052e48c14a371699658c66e1b7f074c5335b2b933f259ca993470554cea8c183abfbee8f7d03e16722d8fc82ced63d23f27c3197ee14d71317aed8af580721847ea01af787831e3519e9372254878af3891880ef159992966e5892f4908bfd341cd3d358931c7693bea197877eae3d6dce7c7b5697f504a0bbfe0778dbc8fc55672acf7ef4e061d66856eecd79e8a8e45053b47c42e991516d1a16c20787ee76d855038ef45d3ee412dcc91a68ab1c2c844eb0c1682cf828d9e8e083a1dd0f76e7769eb56e447f8ff9de176e111e76569afedeb62bd77e448cdd24f5199aee96e416a9f7d7497017bf9204cf11eed2d29be791e50b6eb2892ff8cf232db026faeb137dc69fff3889df9cef163268608df15a3fd5280651c6376502e693410d8464b45974b3e6e3d160a5034d13e50bca4a67a189cdfcf955c7f4e10abb54b95123292f33dec86f86735440a18c5b2079a941549e3289047c113247861562a58fb1aadebd01c6249be461fa05af00e22c6aa0d75d4ee41d0dd174c6ca05eeb4fd0b8a904978e632cd2c6d4771d04a4952b3fbff04e86e1de51f11e53e180f67c0faac071dbd42e93b044823aef +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f3d4a8bcae8dcb278d29b99dffecb79ad9d4978f6fa045ef37495ef18eb1e0a64b680b95f136caeb95eaa2d58906fd6d683fdeb483426024dbe1daf48aecfd79ad5e4e4e815405be654be585a78e64cb52e4a656efed7f2d4a39cb5d8950ddf917fda86c6939b45e4e446cbfa1ed5cf0dfcd26965260cb967a09485e2cc8dd7cdd7c55ff292dd5e10a62b057f17874d55c78bf2df7f08c9fb0e1bdee163e5bafbcd7ed4cea749aec8bc6c81bffeafb04ba770e7a1bd9f0fe546c959f35cb6eb37a46e2506350c7eb5203ff67b0fde350f979ea679f225fdc7eaa4818f5e80b258edb49da21588f046f64773fa00d25dfdc64dbfa785ea278de5f9da8d58962cfca3da834e38ca3c8e7d448d518d895f8562547f028b5e76a3f991789d30ae8c04f3f8e02fe574d1c4ad70acd2b197f9da55d01a7c89219e4896584c9fa8a6d9e83b063e9e2395464893c491a34453451295681baee5909de6986b8d017cdbf2153bc4b18cf5a4ddd46bddadea3fab816c5d01dcd72a4b1a3f831acf6df0116594b0cb96b9be615099e92887ffa7744a3e769e6bb6072c7d3850cdcd41dd0283f91b20ecb1bd77ea7abb5bd7a53f70a806429d22d873360f96a637bed0d69f5738dc9472d335603a3b8a73d86aea0ee7d9681ed4c5baf33fdd67c8ac5b20feee5fd2c892a6579c308bc9a693d3376338c64b855169246a98428e49af5af4b8d53cb4ee5be2a2ef002fed3e75899386e85573fe9115ded057ec12b6743a7bfb3c80ea72a6a859d933eb7833a423b5623ddfd078b6ac2af582d3dcf208895e76b4b226cc547dbedd6e376b44e99534aa103c4e7cad5a6796f531265c28516d51ffe80b9e67b3faea40f598e799d8a9e047961b590860e41801f667b0a7a873a856c1ba921b5cd4e7ef65936542caeba0de6e9765ee9fb9c91c5a5eb9fece945f32f03cfb0c7c8c20ad3805b13cb861ac28634828d3e595bbe63c343aabf13517395e4199f3236abdc9268f5562eea36dd74ebfa6aa81333890a39b47dbff7bb7dc6384000274575083c32ccd04c2a88c5b8fa38fb682dbdd59307f587f340380fc33a090559a1773744077304007ce9af65672c5f221ca99685b84abb134800f5616b734c184107c8c5892c437b8aa3d0882929b8dbe394c1680e33dc2c706c8db227c292fb0a89a8a29261bde4fc1dc12663e8ac502e473e58d6206a90602ed87675287ae301d0ae94ca923ac8672a031b5840de90121b72c58310cd924c12787428adb9b09ea0b8a2226b84e9b5cbc2930122b5027c70a694238f78c8381078393178c936b8de4c204b4a31f9f72bdde751cdd0b31b2c840752181d838ad37c637cfc7584f37686fb3a31020a81db35c5f7af49071470b9c468dccd7c258780cbaece579819d8c766e873b6468718f60da09539fb7a34de11a70c45ad71918925467d8807cf8788318fd010a6a57ac83473d332bb9f2411cffbc7eac87cb7c9b1fd456dcf74896422513ae691cac20d03172728b11d5ecb9b9c8b520bc628eb5724e1b415fb8b99b519c1700537c2a22a2fe52e45a748ad5b7f4366b33b5a2cd8192f9ea406e181b4ba47459aa08033498b6c1cab1fa0327df5afc5a87f0806c6b26159886b40b3c8b068a7208dd12a7c150a679cbadf3b27457883231a8c351c04640099efb363bc962262d9570ff8b425d206227175de94c5cc010d9a3277e2c0055d84475501877d608156868708d5c725357b9df9b47e4c9d7819c310900df9926c0ef230999aa2b420860a6b7fdd020fe0345e8d539c5c839c3c11a270f360e2f93fb61507fd86442379029737823bdc445f05a9ad3c7e29804068fa96035a95459509b53c426e9188a0f016e8857182119ae936656d60072549557891c4fe0278791b58e1d0bcc4b322ab249865650be6946f319c7f0bf58c72b819b79c1b78982b2e24a8b15a1c166cbd3feb06eda478fab90ce7b16935bc4880f78f7d2a80b5b41095a53f19f46ccdb84bfbba460d1c33eb923eb56024dd437cc256a610920a650bbcd3f54b8ed8b1b0814e6f4acf94617e2b68735210bd263597195a6b59864c21e371c1d947f6357a4e064fae992dae617500794af82a5911c15dac3416ffb21ba5815b79a79c30ba72b66bb5d8d2800e581579219b2f0688d87a1346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f97e5b18cff525ef46fd8a6aa6e5e4b8d953fe1e67b5771d1b99ff18e754553beaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = 568cfddad6b6008a4eb850b6d5b35083bc298a468567658a73789915ad9f04631201c39bf6a2b4ebf403c67ce5f110cc92385f93be982591a806fb97a02bc0a7125242faf363a995f4ad0bd6a18fd0e01e832993665e7873473fdce1d4eaf2bc972ccd0debc6dbac91db1e35a12185f26455505095b47e6bc92eb110bd93dc609ed7b85172b6f81a565b77d7d83efd1c3ff7f7a0060ec9ff9cbae48b6a295dd37abc2bba98a94d3d5323e30cb1dfcd1031a5890e8b7545e11c79ec038521f053e6e071c0393b9800383dfd761df12217159f53d4530d26f0ddf8f2f160ddd012e66f733eaa3252e471c061a4b11f5f18576355b8a3c9cc4f8a513d3c7f6a4910fa7fa9351a0dd4bc6772df2ffd6606940d39dc04c46e22a4975c3e4dc2d468025d220d3db4eeb2937a5e5c7840fbfe1295ff9dc4083594bf697afcc8df13a8294f3bee2bc764bf6db52cb72bdf37d4b591c6fd63c93cef89e8cd5e4846f6808d85a00bb69dce35198c2970383f2bff0daf4ee5c807c6d2a3eb33ff61ab871c58932f548bbce5d12fec74ac14b70c948f6011618d067ee17ceab188cbece4543058ac13b16ec58564aaad49816f9a6f2b6f1f58ae891b22bfc37a40077b2f9a73292355edd718703690c48675837fe8caff5cb453e4e4a58dcfcec3aec9eadb0e1c2c9c486d4adeb5be3528e0084326e94a0c847a2e4b55ffb97be791d5ab6fd51f389aabaf637433679781b8874d602aeb40a239814236ebd501ca60c8b6366bcbdfccb9c8496ed05bfe75372d6d44cac9601644c47b93f21fe6087246bbb31f226eedb520833650a77c8232b0f5667bfd28548be72ce7b091ab562705f1e53b3ba27bafab531b490df1317e28b62be14e208f24e647504aec816d11990341920f6eb6a4efc399d1cd97bc20c1f7da4c188f0754ac38e6abd40828f9d719c9a8215207fce4f620a02c972bf0ac48bff55931f3a0ae02f0d4d080cc92afcaf634f39ba847bd4d148f712ed4825f43f06bce1ab6a7dab906c3b05c7573f0111dc8cd9e0754d7c3f00c936ad3eadc1d438a0d3a79aa367da7c68a29c38d0adbf261 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d21b75839faa9a363fd0cc835cd370b8cf3acd5e348e0ad6e2fcee6cc6aa13f8ef40da39dea5bd71836aaf43e96909cc140d5c5bdf6b75b6b0f5ff33268b710277acfe0a3325e384d58abb7cdcd677258dc269a1f41fb33f88982616eabc5a7cac0ecf7d6733a96d89dbbfc01d9fe4e22bd237eb4f0b446e083bae64fcf6eedaebbf8b77053ff6ce478fb44c5aca13e935fc9478d4d1a92abd659c8d3dce42af7f943c669f265ab9d9e6f83d8badfeaead3d53389573ddc31559578cb89ab6e53563be7366909f949be80b5f4fcefaa49c6401af98a61cd0a2fa36b886437223bb55c8e599aef214ee88a31dc9b6b49b32a3e0aa9dc44f96ad8ee4ffbdc3e2016fec5756c1d60da4f9b7c33118f7e5c9952b9972e83f8c38c668d2debb0f199d8c9e7ad07d47288f45a7dd6d2d8bb800643210f7a1373667c955d447f86e0f067f58ce646a4d9cbbe77abdb65f653bfc33456b1e87428d0abdaf3ee436b46a035b630169ae1f044adf2656495ef40a3a956fa7ba0ba3ebaed47c93364b6cb8f73a195e75fca7be5f451e5c92c79be6cafe9bbe53eab9ff6ac3dc797d96793e289882585edb1a7a39d5ea6034fe3314d1f0d3b1d0ecf9010f87d256913aed5d0816421cfd3e519f78e79ba645c6660269f429799d962a6e02b6e682c4e0b38963d0f8363ce43f08759cc987b5986ab366a87e05c430c88f81c72864958f82d3ca682f4fbf42c57c910bdac2b596b43d83289b5a0b39c997d6b585653fbeaef2f71f3308177bf6d6ca624f55989ca6451783e607b06bcbd533ac56358ffa267733d67747c8447366587f6be662daa3bf87dd78f956d70a7ea1e823c4f0b9e9f329cf5853e7b3d9a469ce3b5d398c3369f272175fbe27bd7b3dce100f84e5f380ae4947d527dc67b3ac0ed955c81a9ebd5845aa38659f186756cb94d41698b4ee387bccc8eb13e86e34bcdd0532e775749eb9f8c8eb886fedbcc02d4e63bd50b199807e2e6428d48ebbbed8e3ea9783a340c78d3ba2cfd6e50ae17a8f534c33cf9b757af7459ee87aefed17f530e3ec411741718b8bb977b6034fba45437f8209871cc61043d28bba4a2b4ed1c19f1369c6d7578ada06533b0dd8ab5afbb3bdc5b601ff108031d017b3d89aa253c90c7a4a7e368d528773b62c6aa38046de9b6651cb1f5c353a1f2c99a3e7bbf1679357219417c10b5c1c60348c5c22424807903ea4e9c685aa5b53da5ff92034c7c15a51777d7a637529a274e767539bd68f2b0281a8e13c08210f17ea7168b210830b0d07bb61e22b2f87323c8debc3c97a399de71590a23806f1903ce109ab804c5657290407463ae5bbe24c7fa62230c83288eab45edbc28248d89890491b32ec4d214263557b053f0642f327c78d3565df61796376a6e04a1d068198125ca6826a4c34e65e30a7946deabddd3062178253847c37f92a9cd1a749f1d12fab1cbc0017b468426d8bcc26422cc85e97199420a9367000e7f52e17b4bd5dbb6400bc42182cced4c564ac160d2932ad801650cdf29ca854a0b2d8918a3a2320c5915c1b37e6b3b0f08280fde7c6f2543d2c27728dfc8eef776ba012860ed55906a3a28ca88d5550b540538272c01ea0f83b78465ab8f062df740da6d31ed95a53b5ab8301b79d8ec6a5fc503bb0a6b57ec99085da37b3262843017f9e572b15c7b8aec40ef66755a1ac91856a8d0c8a0b1572a676b8ac671908c210c82c5900abf4696e2c73ebf3ccc4b76df3f74b930977fd616d31f48248c578a8d63b14bb48fe5c259f9734760944ae78164ceb699b1623ee648330019d79b49b650a33b841622b0061a4b79331a03da78b1b70a3901f42159bb4bf7e1512fe8483eff80e3e241bd94aa8740862a3800313b0c160a1302122951b620255d6c8beb52c7aa2ca1fe1858bb60b6e6077a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6d0058bf5477d358b630b42daf131ecae24e7f33960841415585101de67d96e2349962685fab259c312d175326268c807e036836f75d43e61cc65274e42b37d874b2c989044dec8aef59a2663047d8f6a0eef1649d7150b20230cc279baaac5e2a30c84bb1bb6475bd2d4a201863ad207674f4dc25a3c07cf9fb25b1d83b9cd3942b50c423d0b31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b247b5c67fa6e0ff374f691540fff0b4d14d4ed8a8a8c48b14b2a35facb413a5ee60f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 357e8eb402ee123bafb911311cc4d2400ec533c40ffd581c4dd737bcadf9cc3ac06e694c774926de1840ff94b42fb313978f5000930f5e2b8ffa17785e28d9450aa02c8461ed2432bc73b6a9250547aaa1481e86f34d0a82c4b5ba0911414185b08ddccac3a66b175a122cfcf5c171a89ff088d35ff2ecd044ae7f99ca8eb4b446987a5ab6874737281ffbaeaeb84f868ab2a94e5c0f53c05844047845d33792752ca59ee9723cf3ce7ae02ded0ed4348211d1fa1af4d356f272ed65f3edd4698cebded1167089e7ee17277fe47b16ffd45ce9a7feaf0dc6fc983893648e2a2a6ab5d392b61859d657b3fff61b263f40e189f42940a381e34c20eecd8a1d3a347641bb386bd2b8bec1390a62c8d3c139411daf513b16389b85a8e3effcd5a4d54eb906a36603be4c68de357f5d59a9d8fd11248504928722178aec21c4e5b4a824c52a34e1ff067818eb064ae899b5dec021f53ad07bdde56caa10fd0e1ba32dae976eaa6907259c5ea1ff6270b5d8267d29fbface8dfe1848300e60097b1ecdff39ed0be6845a74d4d271dd74c5df7e513108b84658a5869165642bfa67852090de4bc47e4c9ac130b3eae354c191d108d9a0e9393c9a8925bfeb22d00a1d74819d08cbd16b4af03323d0311c507a350b0a48b0ecb6fde5076a0ab1d9a65aceac7e3a6674b9ab87201d6288c65fc1a15efabd9f6e6bfcd5ca40140a5dde99537026b2a293188a9b181f0f1ecc4b0bbdf46056133ea4eb884569827dc2ad25a298dbf9d701b2087c68badecb86c8cedbff6f4c2ee3f20f1b8b7aa1e0935654dec99fa31ef627d24a3a48095157d037d7716fc1ceccdc705786b7143c11272060b666a7b723aa290ec11e95381db116bde516b977f55c26f35892fa081f323d3e02238f42a3fdcbb7e429bdece8bd51c02ffa135baf406149a471599f24bfc7c7e26acb6489be9d40abafe94c2746f0ce1dd3dd05153aac61926e4d6fb3fd85fa019cad88d67b9b2a408bacea9712fe33951bf8f7735ac4935bfb8cc9750b209e993350581aeee54e544d383d350de3ae5fbbdfff030bf728a4f970ba25aac703 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7e9f6fb223c21da9d84c8ae71b6575cc04a2d43349529d33feaaf4fb9fe3c63d8774e9b41bb5ee4347943d2bb1f335e7ab6c5444d97e094d821d2ccec62bb44bdabca0dffc8aebb96c49ca966ab9949b44ebae96692e48adacc20737b85d2fdbd76f546ec98d332e589f3a98dff6a531789a56a4337e2b5f6237caca4b3bbcd75674a5f4ba16a0e4aa9d5bd5d90117c343bd3335ccd1e9eceee8e560b90b43cdadbcec177b879eddab8be79a67a56afafe99b69783b6f9e08cc4ed4950552b53cb29a82ac68a1bd896262740964f56315898c5c58cbba58c7d7e73f83bcacbc73067e44a5f7fc055dd5ef40a9b5304cb4d3ed798556bad35ec12ffa726d3a1eccb88644d5e2ed3f74285bae2ee96a5af6bb7e8d888a53ce87641e583600cfe481258d6418cd8e9c76c620536f37940332f99eefdcaa3b46ec4ed5304bc354239625db3f93905cd59d666edbb3ffd4d428b0347989f44ad65f37d4c7334e477141cabe315cbbebcc2cb2ba10a48834d93e63d937a234c4215ccaaaf1ca1328da1a9feaa1746f635da8967b47c82ae72003f71871453877b89e3ab70b2b43eba3683da73b0559f90ca65eb74e5f343a5df97345685c6d2c9d7566aa394f77d7c335954052cd754ceb4835e4af5bcc61b65cb36896f38b46c5dda7fc2d536035c70f915d77d299e7686b75ea5b5beba5739ac4fd0d84d6f8ad8ddad71b3f43611f48047c7612d638a6a06d3ff069deedf37a05e9b819c369a0ab216543146e83cf654c2234e810b437ddcb6762aefdeb71d86a17c42706460963ce5fc0aaec5c5651dd7b9f53b3f7e85c710dd9f14bbb6a6c3f13ca6c6d2bc46b24df4b6593bfed9ba6c9740b655ac70c33f17b639fa1897d40cad4e98316e457b5027343b4b8d3f2dac083bd00163f558baafb43ba274cd3ccc36bd18dd39d12c316668c33f15cf5f3f69da85e9da5dc19ed35ac18942560e9233057bb14e7ddf8a7547a93d0606e37f7e7e0abab754783560d8ea783ae805fb55b28ce0a3dde4230bbfbc8d8f6f973be9195d2fb5459a29f65d0a93d423c8340a4ac1a4cb66bfcaaad9d3647bc98ed95fa3d30d9fbc979dd7cd223a3694b874c8272103685e3bbbb8888117d53abc7667b4eb158a34953147354f6a5714aab10aac07299c3038fedc9b0d3553734401be62862ca82277f57f1e6225c5206a86e175ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae5b1b521c6af59c721ea23ee2ab0ea2e451a8831a82d098e924604d6b02e151bc43e761c2324368a643ea23bce9fcc7e2502285119343603a4cd5bd444798fdab21d5369f4c73477e3891aab51e1b11cc55b3ab67cbbfd5f141715a9ae4681cb0f0391abcbb48ac63c8a707677650aab59c09b43dfae8653d887a6c2c0664096e551929fc0a00167429ece069f0aa266c542d28db4a42250fbff86aeca6a709c9a25f384effc74c0c7b32b4a616ef2a140a8c96c8b56e61f32963505775658b6c81cb40c2b99e43bd8fb8a8459a73d8d083ac178225461e83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91a7250499891698553bcb9d0848abd391afd195cf39a6213a078161d7ad1aa5b28b1c442f6ab732fc14dfc085f2a6475d4bc8f897a7c1d3b3e0c1203aecc5d5a8287e34c6e3f2a920ec8065644a373453cfd796a58c03b7e241bff2986b3c6c6ce4064db18137862d716c54c154a7e294b218bb1df2d76f8f36847288c76ae21e1967719ac92aea8b8e50706ed8cb06492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4626f29fe843623a55c02b1a0250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad196098b1a1383ae99f2ba6384a1c39c69350fe22437c1c00a651aa0932a771e09e4efc1abb893639f1340ca76a8cbc4c605257e14969d83cac02d131dd4273ac467b6db186e9086548224a4a1526f769a90c93101e26a2c1112744844b0584343fc9b35320b841961fa55016c9cb271570bdfc501d68f9557a920db4920d15e2bea64a6aad743eeac97560bb024c70c099608e55d351fd1784673635aa1b26b9248528d069d031658eb2c559876a7fe6adca630e2f2589de2aba5fc24528a982e2e5ce88a73b80121789522f63602ff0340f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9928e49b73bae3b0285bbe1676eb6fad2641e7354e4c0a4feb0b74bb16708b01351b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = 563633a1c79ba64bf677c7ed45613705e7036ad4df441656581c9e68855d25c7a5080070db9debe4e503fa6bf3642d89cb52d5780ec1fb4eaafca477d1e575ffc2d16a73d4a24ada0b16f4fc6fb4db8be6cf5cfd503525ff0840a12473f4a52fa6a9d123177063dfa959ed7f4d4a17d2ce765ce65e6001131bbbbeeabb17059b92bc08b341d9f83a81b29c7b112336e6dfc263590a58abb08face7a7052598b871229b7c5df6a35599a674f97ba24da3471461e609ac76df16fe2496f4bca906133b14b72932ec5b53aadf3d1e0b9c7ff4426ce55626a45e794f1948d935000801f862ed2e7b4e05cd978a360184a48f2e32d5d58f5ae39273f8a24849585f19f3448dea38aa445e37db97a35dd384d1c13689a30421404ba60933f0f3ab4e2e3792f5dcf35fd780f9a113f29b4059312fae64df783df2d4c92835674169cd81d8805a44a3e04b7eb38eb35373831bcece0c56d41c662a0085dab366f52d336230c403f3bbacf23136176058f80115e29fb5e1207622eb6b57a14705417f40fb7916ed6ee40697f67d61fb19f356a5e2f45f0e64d42e0272d112106c531bf4b28f3763f2416f386a2aea3b44e2b4d25951f3723d58d3b1b833c3e573849d55e80716edbb41bb2a0469f160ad070064338c4295b1026f116c155f12aa11cace93bc57d2ba955f19ceb1db3c047380fb77be6c289c35284ece26df6a6e8cdf31a0065bfbfbea7c6fe81348e126950537c44521c835773036f8a7fb2d6632025ac66229c8e687a35c1efe6c59effa7b724df25425ca46e56f95ac36c09eafc00903ee3b821bcef0716b6da4258c544d28478add62025dbc7841abce4291fe8d6c4b58b97ca89f80887078702f4e8f2c823a07386c82086bb72ac8576cf6abbdb61cd195f21f89c842fc0cf8d2564b8c17233a20a048f0266eb658f0aaece01f2677de0c505cf7f07960f174fb32914c25deb4a5287187ed72685a04c9133e4da01e3205dc60fb1ef8bd6ae856244c93049f9a5fe744155f997af16a389859fe98ccfdddb421046bae0f47d91c6392e9a8b0bff226a64dda4d42ad1a443b904fdea5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b563c9c846ca91b6cbb4ee38f43c9d8d647d22146889138a615670caf738419b5b67e6c837cc9a15545f33c4723e65e428877a4e933bdde9673c5c660b2a64340a927126a56a48660b9396d457b8bb25e6ddf8c275753e234590c607be27d8ee14d5411c17488c1aa1c04fc74dc4a06b538ea5e9991819a93e6a6ef9ff8ceaf9efdcef7e6417e78f563f80ef72d62746ca2f8f4f05e1d47cec559644fb3c31c767a8a5ec43f77ed488f793328ab819b9d5d1096645bced3c8c49713d65bca4a4bf8ae6eebfa7605c53b9ddbbe27adae4e5deeb4c71df764344184d88c8916a6fe51f18b48d68383f2d70e5e57e75d6d2a48b34c5c4664d7c7ffcc3a6172837b36caf679b40a409761b089ef3bcff3895969ba9322a074da99bd0d39d61d08a77cbac871b05917927fb9a1ae2ebe4f4d9af619f94639e28a19cc38b020b30af1de10eab53c5e38516d3f0e507a3ddb338f3d4bb274e57fa55fa8a77a79b35a4b25444d7cad20d2aac98c797bd64495d5def1d658da12a9acbb8e79e6e36431e97b4cea43799f0b4ec8052568e2c2c580ecd8a9fca7d80edfcebaa91e8d892ea4bf3ee3c5c96dd37255ca685c6f399ccbfe6c88e6d4f6df43c4e948968ddb3c9aa8a548d7a55c887c211bc50a097dd2c2bd0a9383e233b9b1809ca1a1eb4abd78e30af3310063d80cb6dd4896adf6882a04dc97828c4022d4d501a6c0f67ea49ae5d62479e545abec173e52b28340f6ad77a9c5eca95bb72df56852a6a0b38ae20c3be667cab7a27d01014abbdd8c2066eff4b54636406d82a7ea88ecad0a2789b34e7a15799d9d8afea421cad8f69d180ac64648ff4614e66e62f33ddd5f0d5c8d134a9e2a5ccc0ac3ba0f6bf5b6c6f42ee7e731afc69597b635f7ac8363ed947da60b4c6685245bb17f34dab876e554ce2fc76e9e44f377917d4881c95f89fa5a017dd69e747523fe8bf99866f4e7b5bec3c7b664163c7aec73867cddbcc3f48f1ed6a92e61ee9591a667bf6d9a09ba7a7daa4cd1de7a37dbf568a3a7c373e1a8883057aabf71753d599ca11ae3a94659fab7ec26a5ee8920690ae8ee47f77b2fb32553b02b45153901b5951ae055f75a270a6f1b4d37cbb975b979278aff301470513b66f58817e6a5b2ed17891f24a84950be275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb89267f12daea09828f143cd6c7c133a38ce82788a6bb88126956f30943169b2e4a18357e43262d6350b07651a6b2b2b227436405ecb5655e5892ab1a0ce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8fde25fd8aa691a95ccc7da9df35393213322f50a61ad4113c094cdaa568b1f43517692c4918c2590a221fbc0a313d2b4321b9e1a973492bb519c010ced1c590f0a61799832c15012e04550edc12414f4cb7c32ac3a1bace2f9250caca0d027bfe238344e278d6509796155386c1ca904c34727f0772c12b66c2016cd933053106fb4a308afc2619f8a3ec5843bc2c64af8d71f86b6836ac3941022a965bca96de03a5982a8bd7730141b4232610cacb6684db89eb1b55456aace6df449ad5b7964cb4a888148d472ae45196e8096a87b014fb5954719e82d8ec33c285323c7fb4dc2eb768259696b41c489ccb08d8665fef6a7a14ab69dc3a72690b5480c1ccb2cb70d3ac37e4b2e00ba7111905fc6d53f0519c44877c9cb1b54abf3106d90424c6a39dfcb6e6c3b80d96a1dbef922aa762d5433485822b1f28c8776305018023cb3328b9200728d082260ccb07b3241b7c86f90f91f18a582aaba4003f9b8c3a468818619a57a2ee0d636db09762e634400305e4495b49f927091773016c72196e29b2e20034c854608f54d1c7506a6b89f8d1201bf659a53f7c16dc671bc65089de9774ce4b52543a1882c12773bc7cf00b746c5b6ed5026f7e30bcb3cb60a091091c2ac85f816d377167801c47e951b18e239c005bb9612bb03262a6c21306749a60deca6b47b22fd7c7ed472aa3e8b9dca5150c4d3209ae02eb72783594b0c713509410a01de44245258790058ba90ca08cda4c45fa6867b038c7eb99d0b026320070b1a18ace2ca6fed80284d094b72881232144f6422a896d67505e40106958c81946a86e19f153712ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0f5de62d662f480d4ed8ba235b4aaa4bfff19edebbbfbd96e5a9b7c4e89365c3ed8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = 87e9105293d63aeb83d6098dcfdd4be921d9c030090d76a0cef0350413d732b37eebca334490269c3a40716330dcf1c2de212cdcba257dc1531b3d4ef6a56c089d0fb455d306a240c97c99931e9fabcb697fe2b407432ed599aa000859ae50fc5b9f29f055b1762494d53e3269d7dbb309c94d670ba486555c4d9085d9024f4708089d0a64d4d692e652aff36bf30c86e12cc1f8f568f694446d98977687d83c01ad8e38e8c5e09ed47b8c447f275e06027dbc37d3a5e727d8a79eb3b336d94581f5690fc78742463696a45d0fe4613660cf8f0d66c7c25eaa27833b9957b291de30d699cb6ee391019b7de12f942914f47362453540eae89ec96c048daa6c4d34db266141b8f41ff623cbdd8c0fd74d9c8af6d3dfa2125eced0699f2b060e88c955a479e054bf2dd7650328528d0090a636cd796824d84fa382ebe6c0001ebccf5e305442ddcaaea5264685ce3a25fedefc398c3b00edd5d99889ceac23d861589afd384c4f5674b9e0c41c6320c21cd23bb1395e2caf219ca29ad642d374e63e0d41633009debae245bc0f5aef56008fb7220f73e6871c5cd4cc8491700d7977e791f0e30aa7b48b64a03eab107c5a65801ec19c785d7d474471144f6d5610775e93790159ee2a8aed5821085e7ba742ed0a9b369a4551e5eebbc4c919fbba4f5bf1cacee8d6ca26463ea4a17ef34a592b2b111846def0180e9088c855c770889fbe1858906f2d03de0b5a1f2608639a10df35f27eec67d78a517f13e00f31133ef508968e63c456704cdf7069fba554892a6f993a5f3feaf4432b351f20d3d68892ce61d762fea4e2436844573336a528c79878db781422eecdd8e8c70e5e9c25284efda4d732d623f29d288552e18d170ebea121161844d7596d1df22d1f35ca58bcf25ff11211b4faa333932d032261870b0d2da27cd4d4fe1128859c98a5f6100750073c3d8d42459504ffe3a5fc199ca01afb218ebafd57b72ab27213e31086cae52bcc8a83c42b769f3f1a153ba3c6ccc9012354158b7d8ccca22c63db2648f9c1294d283ff91bdc5fcc877837936e5c86b53d53d38f8d8e220398ad +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 30ba4f29aed160e87263f66f6034ba1de4662ebc3600863de8844621eda08a46aa83f565c3c33076eaa5a3c689c78ebeb935349ec5e7252c738c9f5be98fd6843e7f79cca1fcee50a33ad574dfea7ca34909bfedd68f66b897e2519935f88363a1d9c6d253ad3813fd0a1e3cb23fc709c4bd56ec73b42fe674fcb032e8696dd395ca1fed47a39a75dfe67e084fd4f85dfa1dfc246c86f2beb499fd5b7e4eaff18fbafc7edfe4576c55064459b665febd3b98b9883afff1710466ee8839d846620037cb6526d2195ed63baecf8cb5901905f8690bdcd82e52f4e74d7c833f67bf72bf1f839c9ec8cc0bd566f835ba068e83bf9b1cc79e596546577f44c3d5520f6371670e93e61ddfeac74b0dbb40c1d46dc82749486c4f40f96f55867fe306e31c7dd95ae9bbf6bab7be258a4faca7b02da2dfcfb736bb690d4f5fe91b37e53dd234cab1eec7b88359d9adcfc8973be27c2ee3e17ca26dd7e68b345f1a04e2b59e7463d8c7eccebf55ba555809b1282a38bab43a2528ccbc0a3dcb2445597744d3a5530a79d59da7a34da4f9952c626e255dfc8b6fe3b6b9a518e20284a1d76bd1e695a90eba34e4bea8e5e99be079e80dfd73b7695119dc3982cd768ad9c31e095ae83675754971b13e84f08df5ba19b1da9eff3913371a9f5426ebc422cfd4900ccb0d8e3cd0bc985abdb7752abff9cbebea9bf4f3da4dd08da03933a85d784a350d708de7820e85d518195c9b08a233ed9abcb3ee033495af7fc84b66499365e67886be0ec6b5a337cc1e48d60e3adfa0d4ae1ce4ad34ea9e2dd4c66cbb348a5d7d966fd747e472c4bbea640c672a978f2b1a8e7e83fa1b5679640dc961c4d4e7a6e17f1a8a5977a81f04bf4097336fdde48d29e64b93ee54b9b98e7fb18216af8e58af1983ed9eafd79efd4d584ab964a49ed703ef9a1ffaa878f8eb1eab2fa847210ab0438f38103abdeb248a663a954c363d516b48cf9bcab2fda2bdfdb186b46290189c9db9405b873d840eef5936ce94f4ffa56574497c424b9e792145352fde67ad076346aaa7cced74d2ffa6e7eecb93634f8ab6efed9c4d873b71d9f06a7e367399206aec69c5569ba3fe2816a0862539951ec9f32fc1a2b9ea199b877873f6b13546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1da2512163eeb5c5c3eb60c91890b5992aed81b9992ac238c7c2a7ec41fb4481508a525f10c4e10b448ee4a7ba149649c11a20190cc95c60eb727cf84ec66c24c008a0308f28171f9c74cc7023873b1848b3450e28377d8115bd17462eee419f1c69414611c659449376b88e23061886338126b8ae317123786ade2d6c839f227ec302132fb59f5d3a5e11010adc5bcda4b01a28bc02377a6f3f4a0033249073b18f553ab65b57fc3176e514794db93a941d620f3f19d1103a6f0a02b7cfa8c213347c6037b85817b27b22f47b8a513d606444736af884fde78a879cc77a4d7644ae360004bb8b072b74a1cc99fb32a68770a110432e4c06f08148ff54aa6a5d2ac1b3b8e461b9813c3a16dc0b200ca81d4e336a54341c8d157d1742a0c327b7c0c9390416b59843353443530a5b70b71bf3768873771155617637272b1cd057f1f01b59565228daa20a060970adb811c106491fb32fda5c6fb70415125b1ab6148062100ab78107b37aa064942acf56919216c6fc58732598f0dd82838d8881999b431586a315375444c6a27d14ff8aa3da9d1340d137b885c95f69862b63c2618e28a11211e3b64bd1a678f631494aba55d42d8116b6388e9ea04b51c9773083a207000e83332c727b4512806a2dbceb6b40c644a5294362770f1108c467f6c64b907b0bc142625ac621352d64b73948d88f281ed3a65a1d4bbf920c962e91496718531756026e71a5986990b5bb1f9eac8ba3571052c32d414a5ab07832ff3172fec8ffd1197028a9ee410203ba02e6aa6b9517ba8746317c69304b381bd6d23b3db6605bfb2762b556bcb502cd10a22c8b78b4d0a173cd56ec835aa874c485f733b5e4c0db08558f1cbb11f866544f10a8a5b5cd52053d8708c3bacab400c78a65436febc36e5894d05b163ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff3703bf5150d1a7004c1c84ce25229ce751f8d00340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39ec2fc5834e128c5e1460d8cb0c35ab340d706a6c8b52070a7e41a6405fada53fb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 34391cbe00a1c3943f10790070339a88ed045ca63f0981b0d45a19b1af0df59a50eeef36f8045b6d6b8961811e99cded515be35462c05dfd384cec024c42929be7ff8536c0195c8591975381a2edc28f661f36bb3eafdacce01f47adef03b0464e14b34f1cc92e8e75a835e6b7be8d2ac6f8f8e82bd102dc0019715886202e5adb89e11e8dd3df99a093c62f9a6f5a14488891471660460b5e709636b2f8407546b2f984a9735f86b4dea2e3b7355a998f9bbc468ac7891835904e2681e9e9a445f70ba687f3025dbd9173741aa0131b2a4e421bb09fd162fdecdfecfde16fd7066527e833225f048be68d7fbc4d1bcce4a7baa2a24d114aaa580165ee3dd7605b0568465cc157c0d4fad4cbc1d78dfb3ad9dc1789010677f207fb12a0d616ec68119638e504a8d437600ca01130581022efc11a12cea0904e22dffb824d72b4aa6037a14610956a5884634ff1df9e0ffcffefc7c74ac7c4a202c60d1f0e9db4e2e722e58562811b3876dc7d872c0596a47ca063dc816558207c2fa155410bff0c80969c2c46b4828b2e5b7d78807d88430c254c861cbbd8e49796aca284a2500598e7a6f2cc543d8bc81fac06727e8b4cd1165543dab46c7222a9d58f8d9c15a5969dd77d6090132b9cd05c079a40a0f24abce054e3ce7717704a381a75ef33f06da5f6fe6b63b033721e7aea6c59c39a4333f09dff6f45176c7dfc654478ccac1395811c9db19fa39775f304f618bae8044333db786249b573a73c0b812e7f9657c471d65cd55994b54a348174df87a2ad7d2d705121045dec4df7b59d391b044c1f03fb5840fb8a061911794ea2c9c410565d73c8b7eb6c7f88fd3aaa251619bc066cb511ae055e8d3620654d3fc9956347854cfd59f5363b93cb21584f626263e1a47726375b0fb2c672afb3c61b3e79ca73e279ef3522daaf157d9f82401e955f9e55c70dcde3f784690f2f100771bcb8f9ae307242f8b8a717c7baee42eeb8d890adfabb7d18c9c2ea8d136e9a66a5b6f2a4289729f25c051ef44882d48e9f5d18b6c6162867945f94cda3dd54784e12d4fb364a58f65c039cbcd4e563 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = afeb5fbf8bc9fb4d9670ecdf6c94934f53bf3d4b40173f78a3bbd76086c5bff79d153c890da535b4df91a2a68acde58df689e1f17939b8b474306a862be548b7dd92aa188fe54e9a3ec659b9b8854b489ba33dd270e3601ee6973c6f87e05ddb0775ae483c55547a9b7aa66b396753df934c13085f27b978bd03a5a76ea9e94b809a29e30d9fc1df2eb26458c675e955ffc2dc94adf8ccd358653bdb9f4ced3d4ddbac5ff603354a6dcda270e7aca47d6487b67b16accba7ca929676ee2aabffc7cbcc610ed91aadbdb50d662f2d3a77c84c768f4269d662c826ab12feb35f8754a297dfee05a04353c23146b62eaee61aaae0eb0f8f8b96b082034d4e63359ae565a00ac0e1d8f01a96f94673beac8394d01935c9dfd1c77ad143a9c36e737d5bca9a07994d91dab5e10acf3b96aec1ecefb33c8f261beff6e8b39ccc6a20c554e7c48beb3ca45d9341a0d978846382065b4ff7ee3f39a9576f3b559a68e94d75ce5e48b89e857c460ed5cf7781ed5bac03965bd74942769f31e8146d415eb86e33964b25a9e4ebd655949d04bc73f99e6280cc73d175834aa349ec96e4b4fd72eae445520b64c57bc28488e061f7fa7c264c05ea9d9ccfdf33cb86ad3bd80c98a7e7b6a4a32be19cde39f37da8430a7aab2ffe5bdbc9761bdc0f66f719e6630d3bbf0bbb3311333f0918385c86c851ebb8a306cfadeb4634aabd720387c787833c9b7fddecc117188af713798136d39a1b940694cbbb5e71d2b977876a9d740cd77cacad5875e04b6f7c7bbd715dba6c0945916985bad3dd41eb43a585aec152ab6df0cb8dc6bac599b6db96ac6e5833982e2e67f8dafc9b984ac155d86583eaabc3796e8b4a30a6c78ef76fc2f5c82aafb23a33af1325b54b869374493d2e9ff75fe49ed686dcc90992973c618489c37f53a3e5c6d5be77ce48e4c05d398cd648bf63d7f98bfeefaf889d684a522709c7e40e956919c419875696bc782c6be60ebb9acb64f1390ef295ec3d8fdd3c64045f37e53970b7856b4bd719d330b613d33dc54c81a66cf7a93d8565b3dce9e458158e72a6fb2bd78a3dbeee683dbcce04a546261fb88a14769a7ebe1ac627d4709ad47e84c44ac01ca4c40c0977a9c8c6871bd929b6e70a8c76a02342ecbfd8a90f1f31470a8708506160f961564db86466d049894437ab1a89dd41363eb597d3265d1f7b9a10c715d40a182e945c9666371431a5a54c6a80222362fa245d9aa10fc115642b3f28ab28bf05c254110a5f5ca553db719a16269d749bcc85388825201c8152c172806c9986f53509a2a3aef9a28e22e58cd1043e19e757b8179e40689c9762bf2138bc02453802869b8f53abb6bb088828726cfa51eea526ccabc971007a0d011315c996ddccc0fcf365f475c578517592c2c48117a63a2b6b854bc7a7a785a5dc4fe4c1b012d78cb3341f9cd826d1d2a13e13083e046de47711e4ba0a784aac886b25dedc2033895e48386e57234ef28590c9f542331a9ce6a0a2dff143b6f542bd752ac6a67a6b319ef15c7203119608a21b1374c5287348e54284dfb3b421b674f0fb3186080553b81f92e403a5eab01d564c9486622bb5233ae0bdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff437197215da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d600260c2e077c1558c8f2abee536999d951bb934cc974b55365495795a6418ac4a9f4491b4e60f992142487457e7359cb5b01e7e1ccc909ca00e6005b213c339c524b26a0b747c18a116026db16239492eb056b12ff700fc56ae35e97ec6d0b787c8aa02e4b828b41996f01d69fc9be7005d4dd89963298838e27c59b79c8de62e4a636bc3ab197326c8eff92c90e4958980a3382365fc65594219ce9d7070a6c3586466ccc031310825ba43ea933d416fb7a73d83f05ec222064f03b635091c25ec0a7aa99b9080844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da88a02883406f1b379e95792c68197d591cb9303b3d5bb2791550da44567d2115da0bb4d380849e1145140d9c6983819f7447332cb697aa2783be169db60249d3cb77d35845a380be3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305e7f49b87bb2319dba8d3485fe814aedb0b43173bc48f3a793554c3e8bf90c17273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = a479b93daebb4d9775a0fb160af4970387139b148c9c328c02e2f774947e1c239c4d179d5c4007a98f2ea22e77878d092e8f27bfcd7aa5e8db486225e579aec679b6e7ff7f2281f32c3805b720fb1410f6294dba996d2eb45dccd91e8225d11bcebd9b0bb21b0e26d8155d630fa6011fcbdacaaa0d60fd16e099158d13cb58a74989a5b981330cabcbde98ec2ff9171cedc2afaa3195f8d6f566b728b3a45610a56f145a5a3e2887826f2b79717454607248fd041b533bd58b0cd52b067b902a4aa0c751ad82899065989fb5612faaec8c27d2d3b3a426bc188ce7c0cb7b64efbcbff3135783315aa327f711f5c02b15e0d878bccc53f6140c4146d7342df087e77016165f0388f2c5892e48a31b03eb5883954294f8d487879b5be80316647e14be9998201ef3fff7a1a2f7feb3ea54cb031e4636358da41af23fee79821a6d3924dee3246f21663b1897a8af2feaed7d66e9791892a86dec4ba230a00082d94718de7ce3db14936aad70f6b90ceaf5529d62e017ee5f6440163d6b43c7f38bba1da3d2fbd573d4a00bcf2262700145dda11f112b46068a393ab392b8900c673fda1d7bc98f2a0904f65501c970785abd9481acf91f85185dcf1971093a26cfbf1084269b55e6a19db1b961f38d820cbb983b8800ae1a215bcd1627ce81c9403adb816019d1774514b25144a0eaa4af61e8ba88ae25393473ca7ba236637381574f46e59d8a210323aadad4bb89143cbc3e3cee36b22bd9de990d2732bdbe1a5119c0c8d8e3afb74d4b3ad171d5517d5450ec3e88f8b976e6134f996fe7ff849262cbd42ee8a77a5b0256d16ce517c3a47b8410e592d9d880ffa67822b1bea078f70042f691e9740653e62879553564052277eb90fd95396f68ce20ba3a3c0e50fb25f58d75f490d94d938659fb51d16d50fd9d01c296d0af891d157fdc0c30ae9a8affc1d86c545fb286e7ee89041fe9aa113fe6d286b38391d1b7f3f35cf0fa54f6ec4c62702bac3310051d32e16dfe9db3193dcd54b087b3dc052443cdd0c8f2c276a493d476adff6a8a0972081874b7970e9102ae5e3675abbf6bcdbb8c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = cf59c55278aa76dc467176c58cdc44996675112e9cb2af8e9744d4472c38c4e7bf7f0dd00ad5c6e0ca536cbe3081e9708857723029c61afebae117b283c6c96bc6e818a4fa4b73e63e957f1a76a1a3c8af61b851c618927ab771098a43261ab16a9af52d35f11d1682d2265909ed91d10365347380e314bbcd2f4cf8889bb37759345754c4fa6589c8b055a75313cacc3b1cf1959b621a68ae1a5a7b6398693d0e94e57ab2e83fd72d5d8027b98980e864fc8fb7f1f4fcbdb9b608c4f8e9e391932e89b55be8f5e66657bf36cbf5d563f75d84f785dcca6feedee23ee3e892e4f89a5fcd9968478915b5e2e4a2d92bc6281b702a84a02ee740a435df67f893809bba3c89db963b70facb64596945809eadc83f406c04d20b76b478e37bd087eb3f9dec37ecefcf7683adba4eb0c49fa3aaa9cd8f9c2ec77b3aee5d3a8c6874be39cc8cedc9f8581f8f9694685c0a06cf9e33370cd8cc514abdc6aca6fb9fd3e13baa97bbfd55eb8c9d2ffc1fb55d1de97d95fb932349fa4aaed0d9a5cba9d8cb2423688dec85a554f09139841a4e774a6e7c67cd6321f3a061235ccb799e8f23ce537351e49b59029a59abcc4ccaff7727653a240d51d907bc1fa67895d6d242c4a9469d8cbd58d904977b6f0e6c1a27c120e37bd1a4e0a8864e5b24ca2aca3cfd2ba3d9e9bd63f42f3977aa0d8e5e5d13c4edbeb7120997f77638dba3cd5ea57883f5ac833ffecb2458869d4c9c6d58b033f53917b7b07ec2f94b74f3637c45045d75f840191455b6154115555809dec122d379ae176947984ada6c4ee90870e61e85ee5ab0fcfd42e4af99b0797e37dfc5ff6dd41078d08696f9d0dc48f47ce4c218fe66a5a4d65796776f4b5abcefd07c60a019eb1cdab40dcf341f1961a8d882497cf1574af1a7a4907e0e64960cac9afbe0e62377ca8cfddb7f594987f25cabd219bf787bb8b79b54c81a4e8ead27e09fa5dd6ba4bbe1da35fa698cef0afb52484eeb868d72a7845368e4b14de3095f540eb372e7c7f18cf499d2ea391578fa30176b08074f2e4336c49eb6a01e30c4765032649d01fdb397e8bb45ce8f4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df08181e5a7343291002915603d891099172597c173a88b41cd45c24e40601c6a5bd379113d876e06614087204cf43c3564980d9630e84b621d6415d0ce224d50bad07b52d58c6ae9ff108948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd6013eb33046060cbcaec21b13549e3df843e9e7b6cd731664808ad4a773237194e9d5a39217457478a6198203f9e6a90e9a8492f96fe28a72c9e2743a41caf07752f52b2ed4fc17efa95493a24c66c93bc6aa846572ab7fa0a808a16279382f87700d8f195e1781803880b07c925256100f7bf223087a85c4f3c88f861e60f92532d60f5cb2033b883cade25f8beb7312520fb3210b2230528644b1ee298161f453b5f32126310899c88ba50690ed925ab0537ebd594567e837471a84c6ea72787176f80c94894c870e69337d939691568edcab008850a6f3a53eb585c01af253d1c9434810555afabc430b7fe69324a3e775e6f2be3638b119a6429ff98d8eb1b5808720e467302798a8ccd8350d36bda8fab17a53bc0c851d91b7cf10c617a1c03bbcc63d93a38ea4653b80731442889ff8200c96b5c37263081dd400d5670959941764a61cde119662325339da81f926affe427e31c6883ce10f5e5705eff1cb209acff5644717e6c6928a41b6e7183590aa524744881aa427c17fe955b306c33447054ac729112568a4cb16806ccc008ffca87e4cc37c3bbcf8e50d3bf07e01132efbe0605a14ac32f6ae2802ca893139f62a64cef28b1720acb282173f2cb4b0f392f8077a325a6259a32455e57964e338a6a731c5aa29beebb0843730ffa93d6b234d51bb87a054968cd07f9c3a2ca79607a97079eba2481e590955e124fa7805e1f03499b7216b6a3a14b9c0c6bab99917a435b88c4314a290e70c7eec8a145037b6531b35b89655e90df5eb2fe53ab33b6c68583780a3b52bb92cc90c45a28cfa8add511ee03bb8bf528d4e94bdfc0cc510e732df4913116a7786e437ef523607126f047a17168824a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0e3f73c56254fac37209f5a59818fbaabf5abff3320b0b3ee00e20679b5728c12a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = 773cfcf14699299bc1818306cec522f63409f9a8bc405b2838155bee43c8e6dcaecd05ce4d6f93e666c601c81b14ad1d79680b7bad56575ad5abbee83d014b44cf7aefea7a4860977a2a4a05351215c569c59938018aae94a5dc231fb72cadc67dd86bad1ca008e129fd1059a7270128b4b40ddf72685c21eaa723f305b6b7435cf3292ccdec873b936b41fc17b48e4d3ca861f66952f7ecd90a66f54dae05816fb7e68990f44710bcb121053505e9ab9c42a324248bb1719c1739660b65b44465c1daa42dee4448b642a9a88cc26c94dbf5a988a861b34eca0b4fe15f28973d9c8eda76f3ce93e9d69663c6cd7c8a0a8adbb1cad5edf5b1b9b67a48c3bd994c76326aca2680cf9e350cf46e6e6b93149ce7a79525d29bd9ed969857a5e7927f511a1f5f343bf1bcda86f4e39ff3b8c7b2b8e2b2a2ab147595c025cde7deffd917dfe0022b1dedbc8f1fd2b0e45b02498a9026e81cfa79178e75ddf5d9cd60fe5af246854665464e2c7fa2aa33901f598b0358326af9eb2e0d5936e1925dba6e356ba103a6ead3524eccc8726746828184fa2f836104d48a990dd90fa72578b9845fe99a9f9470f9a46111242e3e36023196edf9f6c8d3249e4f9480be02938405c3688d54bb95eec7fec06c710a1979d3166c6d247a9edf892c4f96cbb57171d473a03f86f918194b644537f91570abec07fdd2145e9842b36ce82695bc2bf328ef9f85a2fac305ee54ff330ca9f3f7b949eb56e0c5b6b72006905bf4392494ad70f43ed6ca4610c894ed53107c7fe6dd4b9ce821a9fab03f404b7c88645fbdfb655cb4414dfb3d9bc94ed723258f9a76a567cf9a9b37bda6299ed02444da2ac43fe607972a530ed1c634565516c8f1b36d16945af1892ffea7351965827e5231eda57359ab76ec1bb84de0809a44c2f6c963072895d0301dcdf2e58c24fb9f1c7f81b51cd111df67bf9f51b4f41ca15fbcaa4d17335377ddc5dcc6a7a0b7d54a843292e4a8951a691da80586baab781586c5cee2ef0287ac613faf0eeadd32d5d641193f0ffbe787f936f6d879c89e2eb1a01fb6ee4df1719779505df2e755 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 509e66b63489953773ea5abb3d0c6a3ae64910943322ae3fcf6d3d2f7e90d288612ca63fb1ec86a9e5dbcc2f8f752d8d9f6352c5f57e189697233dc36f85fb8fba83faedd6eb9f350b0e474ae5379acee7e38860fb5cb3773d549b5b3b9e69f8b6fa455afd40332ac243c9dc01353ffbbb77b29735d5e8463ea3d444b987466d72d6579b1ff5febaa689e85950f393c260cdaa29d76306558a6b2cfd461bcd4769c2d29358c99ea72ca63e62defc43bc32531d7acaf4e9488dce0bea39d2daced44d41648fbf99cb8c12bca7ac94ab1e5d809a1bef19dec4a4a3aa5385e9d987ffe0a88e668698e59b77b94abef2f969c9f46fd9a850b9e341ccf5884863e5648a960ebdca33da481987310455452f3933c8ebde179f611e5df33ad6e7e82d34b6e8b1d614bc6f1bf9735aaac4cd50ba38682cf3a6f0c5638c6d97f46a85c32a7cc9bd6f34f8542c54d64b46663af7ac00cea45a99aaa225a30f2c6fed688cbf789c3b6a7464bae7388b69dcb7df3e9a588b6531e913fb883946490c9d9f3a53ef0e39ffd6c9db19491bc4f8eb9fc2d93dc04cc98fb193b735c599d527c37575fa964c58e198caa37c3f97f4f51ce369b60ecf96656f2dceb29fceb88ba8341727496916a4d01c8158d4a56557f3de0c418765f71834608f7fa2b48bb0b5b6fabba9a99d17e39858c7b767ba2d69dfb17e532949f927137f597f4cb82e3700ce8fe20596728f8d57e6885b6cd9007dc5db4d89807cc0970cecc376bb5197a6c5c932df18d66c2b680559d604f6c9cd5ae40676e141257e8c1d74ff2ccc6f36fc11dcde9c9b30eeccbb834e70251ba65baebad79a91771cad1a2f6c3a6f543478be9c48ce4a869d99ee6e08e753aee53220cd60efb8d7cbf54d10c8611064a4e68c7da72fdf67b3bb9cdde6e5ab61d6a37b9a83a491aedc59f9e911c33d2fbfdf3f4e4ea18e95ab979a7d2d4fb468ffd52547d5ed75882ec32d6ccca0dc34493a52fc6d6be8785014f9761f7d45151ffdb0b3f2c10a37778dc4d274b17aa9472fecceb4cbc3223e53aa55af49c8d8f4c5abfa8e92bdda571c366e668e77f9ed55b6712164215d038aa3f9050a35732e408ac91a2635b4c6b502c698104c7e90a26bcd903a4b78c20218ae92d39bf634828a14b529983e92900ecb3778a1583deef38497a336063a31ef9460e8b240fba40ffd4b7b070a4650ec3cd698046c097189237a11a510f6941e6b73a79dd99ee4a8517d25650ff2c0e9b0ac238302ecfac7fd642df9830ffe8714ea8071fa097b39e57919462948a177858c89fbc8bbb2717eee7169b4256606c8abd1e9399df44f12fb8e4ba0b846ec7fe1d65582bbbdd0d494a8a25cc81667ae1964a525016d9ba5ef698c84472ae62cbf10293cb047082a58bdd321c616fcb7a79223e95c8834362da8e60d0feb36a5d1a1a6b6736200213ac3620a113a6d5436ef2064fc360805d2ae84d79d07376123fa1682f80a5e85c87992329d52125a9965d8b039784a3bb472a7f310057dac08e5f41fc1ac9e55f7532f2359c3063726a25599980597da9715117a5af15de88b516f8a41e4ab824ffa8e6ef16cdbcc1fe4f965eac97474a7b235dc0c73140ee7153a835c29289311e1c2a0616a2742c70e27d656ef9954c7643947bc32eb713d9ac392b982400ed275899a04f1b7356b02a54c37beb03215d9e1505380049f9b61b35a61c105980652037142a44c42252663799de7bafa6a042d439c893a37a87b1a792c1689924cc642ae09a299d456c6d36895571572f19c144bcc6eb0cb9aaea09289c8cb193cb9ac33823c11980c950d1106625755b280077f9f383f828824818956ed46755f7933f029a9363054ded02a42f5c56986c541e9ada77084b08b7eeaf4abb700839a59c18fc556a6d528e5326c0b4baec27285b0353e3a152f06fbac742a9606542ffbc14d0ec214757cb1a23aa810945aa8526d3cbbccd11b86ff12b553268abce55d7d723e496071a8bc3a8072ac653cca7c261feb53c95b569a44d52f3d61ae991c38828557caea637e6b130142291dd51ddef7163cf84be7a266e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4a622bd8540b044bb14384aab596147e813f9b1c94f75bac39a1aeb14a035d858892b7e900a2163828f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86bbc0a40ba03d27bbbfb91654fdcfab2dfb3e94d9607b99c1d7da1f2663bfa2598e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = 80f0e07ec92fba925668f52fee7721b4365ce4cd7cf90db7f482de3d8ed0d94b5e79af79026a67fd90a5430d7350b22563a2edc68e796a39c8cd76668ac93136022e933657960ef383100689e067090fce1e15c2fd3a8aa0383de02f585557f0495e53d3ce51e947a127eeab55cb4bfd18eebf7cff30d5eadd29cba4eccca850233dade0aeb8275cf60752fff0a94e1d9f8432c26162bffcd2736a553ee71db05823223f650357d2a2e8728fe050b6242a6fa737754067d629a1c5455ea67e5a8eb6ab907ea17d86ec216b00f40a61a0bbab989f6d1643c020301daac7de7a59e76cf54a8abf6773efbd4b6951acad6c367ca6e9411b8f8640c0fb42e23113b7e1a358ebfb80987f6c7a10a3d0bbe682c20df093489d610be2a3b5f231321053ead86f4e402398c650ccbd8264a5fc3c8e1c1e4bd671b442650210f86d0830f428560d5d535dc734e1c4c8497aae1bc09441c52f3704de83e77b4cba2e3895f6d9b5bce23e31dd2761e3ebccda624b5b86085f18f615696a52de50c56b1caaf188a3a78a623b2f172bfae390df31bc9d41d7ce1ca6111025f2506b54b1d1ddf103a35089b6c25f956963a01401da4a62a570db8f210c8a4e3c94faf34d7b6ba3b3fc66f4a436225549181b9e951dc7b297b8d7fc656a3e7bba2967963fdb6bce347f2cf7c3368d6ac4ab2d00198125fa92363290db13bd15d57a0154cf91e8577a73ddf83ef7006c0da7e52f3b49d14fbc4d7aede982c35587a859bd796c2d35a9225ccda6c6ac15f57f70d04bb079b0e46c7b27c1e05990b9162b52cf95cd3998652c788dda7ae35275446a4edb0385fb5019cad108eeda5e49a6928ecb7659c7d64a60c0f2ed7555cd721fedfd9ecdcaffb0c6e436e9e70521009c51240836a85d71021b2121e4fe1f40afa950b2c8631edd8e4cd0a26b8e298a97b8f042969370582fecb51c933f7cf6d4e5aa81aa1b1c427ed69753cda44ecb992c227de925050fda2196b4668012b81bed5def654a2f17be2b13e10f22aa101804026f2204d7000719ca13053c034fcf608efa2e83dd1fe15dfddce2a61bf954d78621e1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 54cef801738266b450385a9729b894208ac7b3e5719acb43d716461fde513935e92b99e181bfbcba7af2a0465ce788832be49b0e3b7fb1d442186e8fed8db973ac90f54e3cd8f54b10848bdd3d4cb30f5a880c7aa3bbec2743364523361d84c5db3439ab5cb32c38406e3c5b1b7c7d0403aa4f7d786f579cec2c96f516bcec6c69c3d969287ab855e55d22ca837adef86d6fd8512fc1272baa2bb5c6037d75a93d370fa8ec8c836a09fd8132394113c93ffe345766766687daa59a69ed58398262764aed1cbdf8e87f6cc5b882ce8aca15e87f76a61bc4f9eafdf4ebd58f119da6962adaa97d6058e9da819ebf7385aab1bf7f16485e08a67b5ebba9ea365b7aeafc056addb08fb5845c992c945960159a50f7aa1a588084c48cb664d3101747fd588cfdf43549facac6d78799759f2ef38d06d4f422d73b5ed7db5133e3749df7babe8eeead6332dbb5856ba413e357c08ce4815debac34309aba9ba148f5ba56823465e1a46ce7353789de4dfbf7beaf1583f4584898699dacfe37d8524cd2dc63e6602d4fd6a85b44a650f3dfa325477587bca849a4d25e3fe96706ed747ae2fc09bfdd3b89ed7fa23405ad2a95e2d9aef9595d80cf0a6a416365130398bcbb93e38ce8fa745b6e23e909bd400a67470fc4b40e447e2e378222466337fd966fab951cfa3cf733e6c7d843881cf97e4444633b52a0d3e7d5aea9aa6892eee5a538dcde08ce7a136aff0f6e94bbde8494e388867bdcf58daa3bb436b91b33d5743730cd54c72b82a4b8f3b22fdb915fc41b957f5823ed2dfa852a0dff2405de890e7db82345770fa22ad7808076eddabbbbb906f90d0aa59ef37b62594a013c74a03b8c108ab226bfe8a208e4580cd282ab7a607ab10369e078077d4f2bfb2de6957ae4d4ad8b30c146be11d99a0fda6b0f254c13fcfdaaf4374afba07ea6ae69fb6633a9dc0e79cb61c9a81fe4bef24dcd1ea569a036cf727dd9bb3b337093f7c478826a08b03839afc31663d4f77f74a972e939e0d06995390a3e193ca83706aacb884ae6b589c9bae69beb63d4558d2d43b43d0c4f5fff3bdd36d92cac54b7665f3a5a380255617309ccf80a53dc03259fd252de0bb4865372fe22148ed6c5f6c111ac00b31460c5c8da7728dcc4c45093f6c38d78432542ec71be51526d588d46bb07ca388088a1c873219d74334070895c396a87ae390cbdf309e41a2fdde955cec2a29bf205e492747dcb39599a49902151aeac0852d6c042b4c0db99c3f3f94eb7db193bfaa7005709933899c04235941969baccb59418a41e603ec62679b2808f25c8565e6954335227e40040d8407147ba15b7a84405c6a6e72251236bb951e18a1f81b84d0126804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1eca19835b0bfdf637a5839c007cb5c5972111aa64bb0f84884d70375e352241bb0dc4acc5f170a7f7b7ed3308b95d975d5c933e5058df99c4e08878523bb98274488aa712529870ddf5211da039bf2e43eb6506f30b41a90c8922880bff2b1630c0048c22c4972690bc965c009e834bbf936581c9da72a70e2a4c2de0220cb4b88296c9716215007ecc9cbf9c1ac081d84d56adb884d2522584cbc5e61d3327bb2002b275683664487a3ca8f767e54e27e541a403754a45b9512368b0c0298bfdd2143ef9c16b49a282e14010591bef728001d0892b939c3fce379c2e96c2b41a9e5cab8c09cafce0c2a14d79137e3b86b25546c86228d008c792496ddcc9ebb01a664e62040d09fa798accce9033bf828d6058c27e79e434904b756afb332c9800312ed69c4cbbcc379b30b83fa4f71c15e86680b6e40b1f79601ae530e7cb8b7b7d536336468ae291d63360814b83ed574c98ff9afb2db8fe0e4561b98001ac783eea99b82d13de2fc5fd59a1e7cdc63e814b3275a0adf318fb2419c76545ccc70066b0abbca763a99901ae6412b43e26090418c09554bde64c1d3767b074901b5e61449e32532f98365b0bcb65cb3b63c03f1d023e495a0f96a258ffac4d3299896055838263ddc85bb3a071ac5c87cc8a4ce8467881f54047759b420d5809489cb2785aff1935835b845977bcf2b275fabe31222e8576e3578a7a56a26a31bd5510d12bc9aaa3a46fc87cf9d0706d20a126bbb446c24230fc82a780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfae16da7f99bb7bceb75a6468a921ab9fe53aab2972ca616ee10697c204df1e3509f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = 8627be55377332874bb930cb309bfc6fd3b38946dcdb8f0ab382d2ab60bc2d0bb29df7b1bf3b3575718369ea8a29e923058894b16fa20d83ee3c0a9c31163ef9c90e33c500f46f1efdfb46e2eb2040f681debd4d93e63bd2d3c79b4d38fa1b78bcca1b5d407dd1c5f4360cb0007c3ac8b42a8dfbb982fa7dac033a8cc46c01e13fca6508c783060825e6775f0e404b95bab4d6e4c1411a0866f0c74d1af869d5ada4d9d6073b25fb5cf8f3a0a6889468a07f6a11359ce1ddf10e5d42a45fc608c2d93bb35aaf106d88508b6eefd66485b8c88012b0d3f421d391e9a7173aab441edce79cf884002b3fe7d1f45438b0a6ac966a390ad40543f7bf1bad961deee15de44b07b3b4a40204bdc8f0abe5143fd95bf8e46c0e5488a3d142300715e9c0b5e4d56756a6f65570d36e7373b8e692a161e06a08b94015f1e0acbfacf5418a36d575a93be8cf61e98fb1f9c0229b50af4da55471c1d4c4cdfe8f859f56a95aa5d4a129f5819549019372e803d8010d6d5f444eaac568580ac0ed2ba98078bd65ad41b6a14102c8e5862803593fa79ff47220f4dbdb25c1725d07a564495259664e14da79d975c1b4fb0a36b43ee1646269ab0ce962bbf970c2bc73d953f5e78e4a4f4ff58dd2616e30dd4a71620142d05ae617df9d38131a69664d62020a0d4edbc0b21dea93e4b567db882d07b28fd392e2c188c5a9792fa01e375ab8e02646aa1f4b24836d2690141f2568314543890b585c687f451365995627ef661e6d16c074b3f1ef2621a03746dc9d930bc9989e6c6044c8410b8ac62b63f3a217c9d0e42b6d7697cd79c7b126fbfe5137c17f47f8f3fc0c907fafebc3e851310052abc266a8cd0907f416935104cfc1db894cdf658a42acf6bad98e3aaa296e85abf8c1217fabae0fce40675e875903042f2439044388ec5528c8f58c0b5147a8cacc393a8da13a52df1a9565bed1fd40503d92955160b7c6cfdce6e5a146b34011e0e052c1a4f7528d1da9667310fc6d5183e003f24699e7d16185b3f2dd8176edb310feed5b70e3f0de4297335cde9bfefcd371d6cba0ea0a6a5e9c1afae5621b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 326a5f3179e38126fb5c776bd677b60c25b49e6d661c53f859069e859e44008d8b8e9636b03de3fff55ba52fd92976f058cf46316dd40de482875c5f7cc940b4b9bd27d9d8120bf505ac42777f54ef83b7498fc4db17ed9276d4383ace5485e415d564debe6edffc4bd86faa5a77e4df4978f3bbe928bb53a0afe71327ddf91d9d4015e35c74c7e683d691739b0dfae2d1cebe142ff8e2bd94b0b894cafc4fa0835c2b8e5bdc288f56f33c7d3cf5ddba868da6503c1dd17b1373df3cf375644de677cfb56838bf3581bc173a588a9f0ba5fa3b9abaecdf7e71d38431e4a8edd398bbc4a58dc6d8aa255fb31dcce7247b17e3bf922ab17c9eebcff5627fdf480a5c3c27bf73ba478a0dfa80e5344b88e9cb7b0da254b8705755b7632e6b4abc4f74d7cb17b697727f9b77e396088352939ffae073bce42f701ff37bf06b917e4e396dd948632b6dcf67febd7cfa3737e670fbe78ee3ede5c5dd1717fd349e4b0044a978dd862ffeab630ab57fcfd7f455e77dddb3c35bfd7c75ac832b6128cd8b72fe579a63b65394522266dc3565a0bb77ce8b5761f71a3ff73d97f58e3871f57dcfb4b3bfbeac7f5938375aafb8197c5538d1fa07cbfd8575864ba808edcb37aa6ab06da48d8fd2b6a89a75a38b019c6a900dcc6439d1e7a98f81b6c76ebd6fbd0a7852f4f91edd5a6bf6e8e1c97b6c7d446a88e0b3d470bdedea5943e4e75b4215c96b049a66ecac66a41fe141f9ba12778e73afe3cb4656eab8dc7eadda079c70f9adf85356c0a13a6c9b5fd7315b95bf45c8790e38521bc72a3c524c689babed33c80a461c3cc4ffa48c059d517be741b7f6c98f85a86d98e4a96b3df6c469a197c0ec5367e47e50eace9a7278f6be6453381b833377890b0ac6f9176a1214a352a3a4920e532b3840f4084574cb76aaeb64881c78d5a8bfaebed5f754de3d04a4291bbaacac5a981b6f8777a7d109966dbfa3485e5ae028d1926e74826a4124a495d1ad786199ffd5f8c90e085bf5ee680275848e24c66287d1dafaa17c9b6c3a59a0aa5c87b19a4a23fa4ebe59f18f588690f749739a39b523a0825fadb6a67cd98268afa159ba69953a085099ba56f4e4c74fdb6759791d1ad738cf320c3cf8c52d607a32059f1e8333b4021d855816496963baa6cb41842fa7ab7297a144758b84a27aa6dd507c097a6c7a19063f2b2baab0604aea5ca1c82dda790fa390c142b3709cb69675b8ba0f4990dc923aa525a316a0c7931aa5e5dab4a4e19f08f898ebe80258ba72127a92e3005611a72022d285bd279332817ed4f13a06a71f8f68a0be49a13eac34c773937da6218401c3fd55577572466a271a4bb10a7938919688629fd1c77b802b6358189e13a52330c4f836bbf41595df29499b42a5a6605ebcd6aaa89ca33580b5ee619d282702b4380b717532e0dcb6dbe3bb0c6431ad480821f0c184e7817616c110f2155a0536a4c65b21306fcb5c343fc38191b8b46dd7a3e27240fb85c365a33e18bc231127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddc52157daa998c392a255b37bea55f1c33a23ff4cdb70a3fd0e019ef82131bd92e5db8ce9230421a670c246695afb5bc33e8569ba69d2843957ee52204e435f85c6a713c3fd677cf7a54cac8d48975f1609cd68659643a1a10558f7397234b583e5665e3d30d1fa26d0788b21bba2ba23507123b89ca5a1f54cc5957737159e93070987613dbc7dbb2ad163909fd167d9e099d8c394a7161417141cec54a24f34310bbec13abbb05a3681c81d7034b8687c1d62abc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa8309812bf6459c26c5fda4abf0ba46544a9146e5247adf99f09622c74b8b90397503e211b9a23bbbeb3bfcec659c936987c87104814a312091fb443acfb87a0863564b9eb9191708ad370ba73d42f35b5ae9b97004793992d13b5bbf00b277a2de699ae41222f28d593f6d3385583bdc938334e724341883a8026cd2ae5205da3b44b9075b86c75fd203b0cb738b4f533efe6117b97105a275edb7b0a15aa1ffaf029f3e13145eb3c500440c0e30c426c093c420496d85ab46883b4b695f30952bba32134189589882f5c297da14236a073ac04579e4e7a70685916e53845c8430e2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1fb80edf4f67823ff4e53a8963a9c9937fa9f8e014b750e11b4c4bb1a361d6484f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = ff737aab09f925bef6da4cdfc9142d86960f28c3e383a5141c7034674610610731b31435b50e2bd894dfc12dece35422ac59ea17beb63f9ad72f6ad81244275e96d8b7c143bbad756e86d9b206df9eeed6a64818902489981ee9b508a227462e2f6dbc3909a91986a71c9e1b497a647492fde143cf9d6730513ae680875c79e747e6b243e70655f560545d1a60315f2a2856cbed6a13f4857fde587e1abf415de2d5c67b1f61496e3f98290e6ba086bc412351071cdcf3a9f5f12881df65dfcef2746a7e1986d9dd5efde2bfb3b70744827fde41f685f694a05413043b14df26205f50f2acdbe893307719819b24e66973dda7f4c948da11ceafc96a20ffae64a4eea610397c2fcfe41bbf8c2764b60745e1883985844b76cd5b664e4df2faf6d2602a987a76a1fdd832e01d830b2f972c2fe55a8daf3263dbf1f0bb1e8ae5adee4bc2fbda1d0413f593d6c330779c0c51249ab91ccc0d6afc6369214fe02b1504c3c34c873e7421918b347a2f0b166259a758f6607eddbdbf87167e57748197fdb63a5501e235ab4ee00939d2e9bd8dde8328b9edefa8c1faed64ef861e088257fdf67369f1ba575473a354a42e6b1855f48cb87bfcc798f21a7681015972f9afa79c48db278437d0b20402d14465fa7a6ed2d919c5fa2ceedc06806f52d3746ece0fecca84e8cf13f8adccd9289e08325ed33d2af1e85326e431ad4380490b07af223ad0ef8e6c4a95e9cafa0c1cb8d61c41c123b27a2ca8e267fb9c63fe371cd5b1177618b7e26441596615d9695e04c77fc87fc6774393ab5e612e5ffcbd54eabbb548c568068b6350b27c7d4c24469efdbfccbd2f8618e266e2072e7b1f8c4d7ebbb15e29293a1c2a5c26b8829411a5f861c2b5404b4c0968c535d42c2b5b0d7b14e30e2a595d780ecb1aedbedbc036e27ce80975fcb381a3b049f936c5026697822e407c7656369caeb7ed574c5a8da357caaa89380940f776cf6880eca251ab1e895870be9dbbe3aa3a6e11315e1cf7b82a4cb183c8b0fd3dd4d6b436a0b259fb8cdc2257cdbde82c358b174087b62aaad99f4a2744b0cff5a04885bc +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a306d9e503bfd036e066cc5aba8ae720aa8a9d9b86da5858cd5b595c688b5b29ae3b8b6d961dc484d33e6905b86dacf3627ecf825bad4d265630878d8b8b89257a510c9d7eed6e46326ab4aee3cda24c9c375f6578c470b3c449358f3a6fb7ec08f8ad662bb2d39daa0da8ac3aa59a7c8fe0cf1caad14fec64fd7075ef527d2ac4676b68b96a8b758ee84add3b2443696e43bb5a34a2a9bcf9a43c7c317aede1cb33b78a5b3ccd4df659dc05596671d9a5ee355e4c568ce5aa73855a735ccd38febf54f206df8b75bb61aebbd429a8723f82eb149a35c75ba5f4853f735ce9186f7ecadb06ef92805987df34c826c34dc8b63e701a3a90037a9b03b835e787449ef08987c517b978a10bd67046daf357874b1ad860e6cbd4bac028a9bd2d1872567dfcbf599468d46844bc5caeb3a3b7bbc6d85d3f7bfde3d6266b4f054b966e6e0279dae55cfd4cf8908289de41c6dd4f865bb92584517cf014bbbfaf255d7b57f1291d777b77e0a0ebe85958fddc858a5eb6c79ac8795eee52361358d895c57587ce0e2ede1178aae7c881d1efef4783d96fe57fec3bb96afa475603abad868fbcd6ea83baed71176671dd51d52c4ba56b9eb87bacdef570443353c8eef0fa5ae512df47a33ed2af98c2d7adb1ff52673f585d0906d44c97c8c19df2f75b82a7987de45d6362a6785c2393434f599d3e75b7d8c218855c521da22ce558d77337cbc36b9d7b69a33e4265eda2235fb4cdc54857d4dd5edb8dd958cf9166f84b95818f0d95427d5885f6663d2549a25d8f11f862319b92c14de3a1035e26b3658fffe790fcc7296b3841ea5991c5b607caa51d78a5bbd3ccb63e6d5f9d83b2f9b9ab1937be2fdc3b94aa3bf356079592a1144bffff650b3c5e95e6a98506ac74b8aa4996ce5de9feb87fdb7fd860b00f67d863fdd1b85ad955479686f7fad85cb2e798999bf7f44dbd2116abf155ae7bbad9d8e6411dc3d6d4b9bd3ad45dc878cff48f4c4dfe6f08e7febdabbebf8939cb1bd103e6a47dc64fa325883f73a2bd8c7353938f208eb7858ad3452ff8d4366354a959a37637f37f6e953cc3da0d56feb55ffc9306f08b6202ea25968669d4597145180620da32b9b41576a297fb5010948a0516ec3428f1ce8012c664dc5c390663cceac966656cae6110d1a45d4360c420a69014709a70b71c0cf8cffb81958a687656859a8979a24c8c131d1b03e791bb81376db31562367880dc097f04c150a171445283cb4444701bf513887c917a310c87fa30dc3a49a23727e3824f5e2b821875ba8b5288a28b40abc8ba0d130953352f60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c569c2b7fdea81bde50c7b495f901c14b32779baf70c57d84d92aca4163637de873f0581b170e77f4ff840d0e56e13d367c74a23c453c847e208c85cc687066c09c6cb6c397df1232313d93a9ae45352e746c1645528a30d19f6ae36a56cd1116af5d11f6fab71d45544c121895f355657d982fa23554b6525a68a050b1454cd3acb4c32af315b19c9e6ae4a9a3791e6be07f64c1de5782ebc2e54f23782c64d74276f5f060e89c826c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b352b34b71958b0147517061a45c22b0316deb27ebc26b33efac3a1b29c4a301e48e00da82930d4959a13e763cb63035844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544aa3290dc0697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f7625cb0a1d3bf043e304144b559e969264053a53e542bab4e57dfeb53aff658db07c6213586315f57289e2bc66e49c35e28f9a5219c9f653a9f1314406a6cf9115adec8568309388e18fcc5bbe221c323829c91bec116ec1128cb39460c25876e32c08d1c409c581a9360d570ccfe323244f0ba84c19cdfeb6cc761a2e408a9d073511b90a2fb7178fb9cc096ce14a1ff14b6b6600ef99c47de431cbc7482da47d87540b3e72801f8a9b1c6c583ee73bb157a78c585b95c09a868a957709a5305c7424a28a8d731ace8759f5212566388a7fe50705b6045a945b69a52bfb4a61e4dc53f6230773f844ed90c571823c3094912c3a9ba25879d7f4135780596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9d9f630c3838eb161374710d9f01bc70d4ef928fcb1c38bed93e30f3633a05e01a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = 97912e16eb69efecb5ddd7c2f69ad5fbc628db11c4eebe7bd01e3efa8ffd1f30d4a5e39dac57494c313415c2ddd7cfc5c210c146b4e5ff721eb75ca9e54e1a690d4dbf9bc9f84dfcf30b43bf5fd71baeaab172f82ae38dfb3f52fb614cda0d59349cdd43e3b203f79d67654905f08abe48685e7325ddd388c7a93c1dd255db54bfd230412b3f68165c054931f3112095a9fd707bf29b8b520271a722c897193bcd1d0839c47b277207b720c3fa000209b14e1f6c114f9a8c1ba778d0182942904754e0a469415b2e4a4c54090a7a5bed7a5eea3cbeb98841915e0e682583d2f995deb14b2d98994c6b0be50e6b8bf6b3626d63d0395f2486b53109f29aa865e9d299085a4b4176bd06ca74cc67694b89ad39afbc8ff4b97e25e302c3df27b457a5d4bd8346e985a5d01cbd16140c6d7cd8943893703fe46420cc67e89103098e32e18e332cf0bc6ce7322be1a61b271eaf87d99ea38dbfab0f05c8eb849c215d93e1469eb447a160f148aff8a560eeecea86f57d269ba7ad3735243aaf3936462369515e516d3e5cda5bddc5d857c6f005496755d6dba588fb467a1ec8284496509820b359e1dd1be5490e8bd0152e14e54732b561cd0f71a934f2a7920e6f212082f3963e04dba6a5cd01b5736d27c2a8b40b5196fa57f71e069663dd6c220bf7caada8ec9a057373d21748e8dab71e764632a17955cb585fdb1231369a537918194b207f742d004719a84dd9226110e43cd5d3f5ec8da31e86aff1abf4c2fa512e0712d1de759eecd9f3e7cd5b90b32cee8d4b19519204ec4c8b28b9529ae87fd52b43822c7158685600c2b45517ba266032d732bb32ac28e2ab5c1d856d7caeb48540e1e5fe3924e5d8d2fc146fe5f821bd92efcda1aa7533a48cf91355183107734f9a2c1a43c5e8c63fc106ef3c8609919c01aaba3fb65285288623d5fcef62821dc24d04c8c44b3219936f5e6e87f723875cef8be4d1821f08e58a1dc72c2cbb5eef4018b324d328356c508d49c8be9ddafe5335c74303735443e4b366d51cd145906dd8d73219bef3eca694b780cb8ae59f3cb3b6bff77e76d109b0b3 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 20baad201378db4baaf53b7fc85dcadb1558f238a3c0d6b70027adf29398b33a6861ed84741669992afc365bc2c1d53f4884ed610a4bc93434707739337be810f43d57743d5918b002ca40e8bc63d3dd47994a7614c979341fe93995c18bde9af2a36721dcc32c64a0438778f345ebdc1fa778dc6d9396f34e8fbc20469856a8bcdba5b70bcffcaaf6758f29a4670f61a56ff2ae069e5d5b7d5c83535829d166c3ccbb7c46ba63a71f26f8a41a694115d5b68a8808d44e5b7840354739708b956a3850173ef42a7650521aaa7349b086b7f135c6797ea445949df65da9583b8742a14da87599c9d1083b774e5fccd9b83b25602eeaf48864bbbc9b47c9cdf176f7a3a2f6bec1faa5359f846ffb340c8f5ed7298e807a8e731d92498b37e98ebfb44563d616f74df771a9e3c78d575865764972cb7c598ee36cc990b508adba8acdf77fbe699f7ca1d34ff7e45f70dab8080798208fca5007e87dfecb71af7d68d6d431dc7f500f6375db70d5a3d206d3982eb3f616b8b3393b524f4899a983f7216db78e8e962a7af1322acef954ef8d0754ed39370facd3afb3980014ff3405958dd5b7b71fd9bd9ca6a64e4c568c6ad51e8abef52f13de92e587e3ddbb49e3d34c2f3b5941f5b07f6a3ef799553d67adf7e569ffd8949bada120398624b5387c3b8cf8af77baa6410377bd88cb74d814388eafcb8f96cec82a486ca962721a532f45536aff69e3098a2c15508f2dfb0bd79e888e48939e451c9af606a34edf048c6cea76aba3b737c6b20437d80788c2885bf782bc422adfc14f0868f1dc7cccd93278cde2f2e731d1fdc03c43da9457f5ddf53e8eb76b64b7bdb83369918f77309d62e2ff8401b9d8ab8e87bf26dc87185f0c35975feecf93e8a3e0bbd27c48750b59a4e2887ace373cb34490277cc24a25e123dfb326433f079eb09b4bd04d2ecac29e4052baebfdc7cd09b95fa726f4ca399b7f53dd5ae6ada1ec55c28b9fbd19be20a47aed28ec816cbfa52659a0bd54b7ae5c529791f92dec579b9ef554aa63e86805556934ce5f19ebaa09faf200fcd5400dbba15d91eb4ba19d95539a620f09135fe651929f4b299df28fd9943ae75a983b544e62305fb6711e780519b0794d9af7b4acb2bff7c704418bc89c38a9e2b00ffd6854c6f41d38b204bfe220034213c066cb62f721e59521bb6bc039c19781fbb71a546aeef31b90783695c47ae2812523f84f0f462b60f3bf77f2020e793813109d25332e966231a462ccc596a48ccc22677a904e35035ea10ec572b15af3ae770abd79c72a1dfb3a988952c925b461f092dab51726e999bab44806199716f425e21441cd82919787c629c90b6b1975e7b0844ae52df6a5cc7d393ada542f78952be2b001979ca34563b390f712111a24fe33ab65265b70eca7eeca275a993ea2793b0b08adc56ba66d93ab1a65524bdb034a33a9e9f59b79f16aaf12c470a22105ea1e2ca042dde1ac61a982ed40102968437d216cc6387989d652bd59a4d88b625056b40550092a506cb4b0532380b35ddc4d34318e33a797c696c12fa540df4329268ba47c95368473c9a70b0a5b0a3360b73767f16d94e59c79b1c839b0af93f3cc57323b9b815b94f6889cba154fb0c6bfa11ab5fba4f10c83405629b9c177cad4307a7b0e72ca4f8c7ba5f292afad92c566abb319124205554fb538c6a5c630a32655ad56be818aaaadd546b1d04df1121ac167bc09274379f0719f3056febaa36aac0c926512d21530d5b9a8ba838f7a44656e868c915046ea818e19b06afcec6a14594e6a5574eef2a937731f24994ef7dab03e223c0fb0bef2a2661703baca090c50a20da05a64bd764f1f1b5ec5a6ccb7ac59e465146304c272453dcf897ac415a8895511f5d04c24080ce0a1c024815af6fa0f21c7cd0c702bfaf7991d915df9b7a57f513cbf0cbbe6e40854e42a603a6ea6524fb3f49c81d71c4ca27848f51a354bb35020008360201baa7fa2d64d269a598e3919b1076b89b0c894d8cd63924eba5b25a92b351a516c50686b2597828bdc894a08349cb0996b73b2fa0b98d0d39fd2c6952e1a60b69b1b8d41b5f6c002409c3bdd716c56586b7d440eaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80cd502aa28063835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c105c27fa929adc826f98fbf0a7fdce33c8f215b34e70450da0767240741894ffa4e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 145a28ed434adcd1539de7bb777f913e0abf3221b06b68ef080575ad4d159c7c6b2eb313314a5bc69b559d61ddea83986bbd47c8fdcfc95fe19f7e1ce5f177dadcbdc1adfd3c61386935f0fc9a0f5a2887f2f649787a9d764ce16f8cbf54650c67742c166b7a91a2629c9006014a934903b6caac51c8cbacba7edb8369d03a0013557f7fd1d212de89af8765c8bfd679d2c53a652071fb6d975d19d3fbab5b8ac46e778aa9d2b5a6e809923ae3a48826ce6970b0e7c3f6f2d76c12980596beafb127b3c026a21981391ca6e77d753fcd4ab4deba818f8ad7f928435c37a7a5ca4f5e77aa4331a5deb34b86f4e415c2a90963189560d260e850a7106f1b86701e3c03b16081f12f7c3fb6e6d2eb1a05fecb6e9f0df568ca3edb978795e20bf7cf1c430c242321a6dc86b16b0f05551e4e391d33032467e67781ea00e671d79803de7a4b0736e8b94443f677c275e76ec00c4322f879e62161e30b7d94c7c72f9122e6c3827f48190372390e5e447d9bc595c5152a72f719afbd8ada9d1797236f86e51d3acc36ba5f049150f715a53fca607bc49c65ce74550f675e8d4d4fdc0f09c3164fa48e1e29478d3150e34f0f0d5057235737c84681533fbe39265ae58b0ebf7d7a3d6e3aa1d89f020406b0a239a69f24d82ce84941a1cbca00f3e014b4a62f8dd1087439470b7a0754291c5fba3bcedbb023261894729c581c47680854fb23a59a174209ee8896b3ad2fb3f88107dbcbfcf33ce4b33f748ff202e9846ce2fa43017675b17663de364177c0e3d4295c9d88fa0af25789c8d99a87c72f00e650d8d1d7d48cda095df9c5d30b6a7dc42cf5d7cc439b38f30fcbc42749a4b5f20024df0b76f08646a9c48eb26f84c39c6b6af371f62a0d7dadef67af471b8bc2e985127c91db263fafa9715f8de54e5db1a6e28258ddee4e3a9079b80fb0ed6b69d2379fe190b3688de3daeb4f117520399dab1d9d1baed5d42fa50ad5c60997cdf463cbe4add8680d009e52a7c68585d1caef2d2c72b8c07add5c6feafe6636ccc9cd83e6876f3144bb80835303c4bf86679a3ea725bb4b91d1905cec1de6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ae5ee082dc4cdadc6267b69f5d8b404583b113df7de6a7de12485a7b68bca0f3e32ed64ace676c1e7c48d5ec98a70d62767d57bcaf358b08e38b9b918c456a3a4f906b0f75b9bd8435b7ad1619dd388c428d4b41d61c4e5a3859e2a39a80f6edc4874f51073d02cbbaa094e3fdc64639da42d15f9b7eb8b424a5eb9c879fe6656e356fcc13b7909c6471b77b878bc6d0679eb1c673c0dcbe435b166417555ae0347ee1daf45c049eb40b6c23cb34cfddf6f3da5c539dd1fab341bc4ddc2cde59d6f3d2e9f7919b1ece539780b5da3d3ecee2144a385d1a5eb87f5694ddad5c7c9a2b899cd8fbea0413eaafef5bbe6f4d251b865efc7c303acd18a4aa5c0538dcab55239d5caaf9e3995bb0241e95adee7c48dd5102c44d42287c4f6dbf4f4f568344b6e287be6519f1ac55984c67f550c9e74edc9ea3abf28fd4b0447ea233747f18aecbe25e45c34449239ba0b3b65356af3f23ff6f132ccb281a484048486439f58ec487352aa9c97d31dad59a806bc71d5ca7ce73e1194669289795b9a3cc7a2c6bc756712cb4cb819fba7553de9ab96ace6f4f480bbdf515b423134044b6a54307d9167a7f6b3d7a336f9b0d99d3b98ce394059cd61ec2df6bbefb9c81c3ac7d16bd537affe4aae3df7c4bcaad99c21e4bd0b55df20a4ee0c10ed04716c5aacca8812b73213c5ad4b473fd5a555756b18becd2094ab27369d37d6a67519f71cbd8fd36196340adde5959756bb63ffeba3ab52ce161ab6cc8f47bb30a7849c674c6fa58730bb70a2c63336987625d3889a652e548ec6a26d40778f739ddba8da898885bb02093bc45ed4bc5eb71861790138340009e9549596303e3772d287c781dffb54ea72d543da9376206b380305eaa730d9233e69fa4cf56ffddb1837e7299b67dceffae46b8b95a08526429bc5ad5cfaff9898a97885598fae5147af49d762ae335937ce7de1c58262ac11329a007aa3c0f9a7b95ebe3c6ef4874147ae12dd92fcae3729877d18832c56c71ab9a5d6a2a9b6da5c2b5aaf049a7d8383ae60aa87bc6f3b4c53ab0559af6da0b81a239472f1941cb5495decdd30715d4bda121a1925eae9139af19594444a8953b824f4ba5ca44c07df745fe911f5071975a5b4952c48df7d431a821998fc84f064bbee538569565bd0db70087654203dbc0cc21bf4cba678d1a093ea8b295789d52fb25f4d78d6986a0157145d054afe73a90f25886780044d4b9a4e112259d4a83dce439739a171f5a0fab0736d6731988ca74a56580d3c11dc3b187cd688cf066710a1458a7431c7bd69fbfe67b3532386dda99b9a08368d887414423d6c90cb69736a6a021c70a4c7e33bf3169aebd7227f5fa7f11927b315a52ec3341af239cb88b8137b509c7699b0a8578a4425a0dd535eada924f872fcc719aa785a0e0045b03b24d0f5c1dc9b720a4717e0705cedb88bca8e29a76043a73a87c867223f487c6cd7598bfa4194fb584f4028150513f8692cf17aa5d1009756db4b794f3c7c3d40253991923f098cd7680887935729c4a40a23dc20227cf18c86137482b574c5ab880ebc10c312c5eaaf15870aa4b51e59f70c35d356b11fc6abe072a501bb61647694d6c02a731f13c32a27fa5314a5e641836e23bd6a28c2ae62ddd79039b9365b007110dc95760367ce6a8bc2a358d9ea04cfc302663caab8c710c9f199c2363c4627c14b6cb5c3d3a0d9a3281f07aa5d67029653b2c9afa1375e343c197cad3caadffc0076ce91df0e21436cb368d9c2ff2cba5691acf472b4df839785737842b378cf29567db475622319328dc5388aca633531272b2c164a4a98359b0e9813109640847a8605815a9dcf84531e09b6dda2d1163cc19824baf076f5ef39e67761622cb0bcefc7430c07ef8b8bc84ca8f57131974e5a39244407d376fce88c340030f33ca7c21e27f2cc06b443a12937b978e68a2465b70fe8917da84700365a68ae526316c61fea6b0e5a88813e5251f83ba394b0296475dc1c77878db73ee4671e62bb66d50604efc4a7a91b87de178a617931f9406ec952cecaa8274d095c91062c0e0004093b3e6b36c9db094cb16a34a33a5890a56e973a12af859a7a2557235c50335c6418751952c1e3b3bb8b6490faa78c81d84c724e979cc2b368963552f21518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7dd8aa653122eb5e3a4c3c877e95e8ecfcfef1ac9e0e6af92cce8ee89d09188fa9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = fe68e5f9034567e425a37f97d35037721e74eb7f12591f59c0832afb43e1f3aaf8a5e4e62f86e151a0fe07eb292fe20c6815704bd14f1ff389364cdc1233b74cd4ba240168c9de0ec2f2c2ace3b46c24de977672049595a50c79b8695707bbd72850fa345cecdd9f93d6ae416eaa79659bcb17b98a974e3aa7b03f557aef8e491354b8492abbbf2fe3f39b1fe6b1208e92dd9bd8b40b98968fefed5f9101601b79007519f994b35b300e88c7c05f397e411cb990c895d0bccc3a8779c41452aa1c15071d78526929e2aa3529b996039792b3bb4d9b109bffa00fa796d7fe6ae23d4b96dfd9a16e3d91cbc4860bcec6172208ef190f56ae8ca201da34316fa2f7ee46a16154658b6c6cce17f4917aa711e43253ab2cccaf35d49501a22ca1f482403bfd8ee3cf56b40e7c52a83de9bfce2d20a14f858f7c32379a42865ee73d33d3215f798daf4e47bbc69b5f6a49451526d58f074eb8c0238e25ddbcdd30c8aa841a94e6b0d2cfcd07ee5ac744fe13c00e0563f75f2a63af3130fc72d5681eceb45ace81c8690f43594ac1e9d2a087db9022eeec67f425663c3882dc769abceef4e0b24bc7a42c9fdbc52247b70a93aa9fcc6cb77725a5f7dbbb806fe072a5d2955b2d7fdc5338e9f15dd5b95149f8fad00048c745a56fa7feef3a630489b8e3ea4d8cf8b8f7cbbe2014ead57a3a080b59940f835ff68473aeed19ec1cc163ef8aa9fbfb7308e5cdc7a45d4fb79c2b3082f031df5081fb0f962eef0c1bb967edbdf9b4fbb4eb95e73b29a948f2fc4130942160b80b0a9e402eae296697b3236ad570b78fb1242c14b620be5b0108d275b045396c8e4561a2cb05cd8e9ff877a056731654c6c6a4cd732c8d730dbf06c0bbe494e9472df109286670efe8880f897523f3b16d15e6821bf85af2d8c01a8a361523ee30405b0d4de846fd8faec5907f95db62a3fb4dea2f05ea54bf60c70c0ba664a5a3b777f9091ffb86a8ac9b9e328768700e82b4e7ea5e0cd7640ce0f004ef4ce4a236224288eb9899aa780f6b56b9382c0de0f2a68a7f55bcfb7887726c1fbfed3d75acac91643983faf2062e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 58c8c996e892ffe562f9aa44f4ca31ef8ce74dbf4d20c683519ce361e68ca476345f19612c97ffdc43d7fb876096c96f5f7e4a5fe794b9dca87534c2e92be67b555aa9b95005c85b9584aa34fd9b87b6a8620441f22f8b552af9ea8788c26c33deb97fc98aa078d5cee62c5ff46bd417b8358aa5540824df89f6e1fc74ef811dab31cd8a6e789b492cce5006c3ce45434a1fbdac595e4ec9eb4ad8f0ea3dc4d4db33a746d49f53758bdaab524dffcf0c371ddba37c8d8cc293de7fa5605f87f50e9a9a2f98e9506cd35c26b8b6498d28dcb77f0742cd8695592ae76d059775c4af51f43ea993567204fb1419a5ebfb8f178ecb9087613ebf76695562cd6fc3f2439a9aa980a56371bc64b22e16b3e01790a30fbd0e48afddc5de8c7783528ce62fa838a203fb8e153b4647bdc59da81a494967849a4d8e4db168f42adf96e96bb18c9bf94dfd5eeeb4aaedd84aaa0b97e4eeb5276c4b7ab8746b7e7e2cbdb8f433b85f8580cf884689e4afacd6ef32587d5a1356d50f483ae96f6ff332fb0dfe61a7a76d4ae171e9721bb8d1aa9ef7f833e4cee599ab1c52ea9480144ddae6b576c80979ed4d40380394ac95b420a5c5620777597e4ace9ebc1df8bbbdae768fba4b2b349c655d4b70089e7ec8f0626ee9068b7666cfc5e5da56032cb75fde59eefa3d99a764deb9453a54f01a1d438d1bea2dfb4d8e7acad1f9abbabf720d58b730ee84183ddac289369f0e9f9cacee6036f407bc8c3a8478db446dfa5fb10083a6a2c4f28d58f0042f8a44fa6a72fef5510895441ec6fe38ecda9685528f9ab7794893fb715ae9da022b51907c60cc05e66c485f510d5b87e9b21ace8ef83883631536324aee7f9b4db78fdc4f4eeace289e20ba40403766375daeefc8a07119a9c11a67d91cc0447c4e38f68d828c430a75859db93b57f5c4956693206fb3e5e88e212cdff0cad3b6b8b7645360243aa3b52cf514d9f3e425e517ede9010aafe51a91ac78695a4a4fec6b754be3dbc27b664816c1d7eb35c2bc5cadfa7b765aeffb5b48b854d2bb5e41fb8e54e526d648177f220d59fe8763fbde5fbc53e95581cfbb9262be71c820b270d635c0002bbc92e596f5cc0b5cfc114bb2267640308b495c33314b8d208015888159c02831a062d7967691c64b0764966762c2c28666cc1119b4bc8541f016945c200de76f6f5a83605ace8dca54585a5f115434d70094fd540aae769450aaa7af961cd96239d624082ae6a494a000950747188236a3b9b170a597cae821b6d74d7d00c42ad89a31b0383665b4daf70a95885530e315fd75888e76c1113c0b43f80b951a626c5c59706138567aa786ccb7966840c7acc5e70c029fb38f9bd3b9ecd9b11291c808b44803c06f2241afc703834a125474ac3a926a1e24a0856fc27ecab603f0a82c53f94dcd8797ee25ce4f1635e2b18706032191c7834651c1bdb21ea8630884aac48ef3287093a95f7291e9d3bafd94574a41823f2c7f5600c6bfe237e09158e848b59f1702e1b924d47cc64f7b24beb41c3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bda063a3545f0cc8284e40bfa4b99d2094727f8cf006957fcc432c058685072a5653434a92b9ab4211343f063fd44572a23829aa8b19e16a7121b1f2352813d492fd91c834eb5a8e5498cf7fc76874a3ef8b926c0d29f3062588163a24c5976bf48797b694fd9b964b1cbbdf62a23a941c99fc986710a0cf2530f11f84914a916c6f704d879ab4cd3aa51f7c078006eca60a1b53075ec71c11ce0b6d8f9769f9549c2d7a690dc07f79396bb2cbe2e0ca72436879b0c8878d0a9eb9387c5759b1591c5339662009d449184690d717a8a768f0ce3056e477a9dc822b5fa466c0a85b3a0256a61b3d0e433ccbb6a9254222fb779cce1273cccaf7c51760e260e2f566b487b8dded9049e037290d102e03019c8c0b2983687d37c880a17484337a66467abee2b5c8340534ec6017a660344083c7ec21a729c754f3cabd2218dc2f200f48a3b67a07b7d86b072e4553be45cb50a2b424c07719878d4a84ad2d33453b783ad117577f41d6ee58ce4326c4c893711d66c94d6aca65c980a545b5521026a42318cd72e7f7129c60b652ea49b2dc075833c3ac3e7cc094618f003b26421bd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaab7c80e434104e9838cb08529592a5f81b0e8ead186663db8facc569b09e75c9a5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = b58756de5763aa23238a6b3a58bfb99f3498dbade080b1be63bf73d881278678e0bfa122b632887c981aaf81476073f3b193b18c53d8b782c48e73a0cb17f96b623975020bc5b7df38e328c5424b43a25afb4746ed0d6faa3785c9e341600acd68d0ce2edfba1c82eec60ddccf6ff5b14019238329b1b8b0d76888268af21553813cb577edbdf5f74854f0047832e14cf53a403e881d16f2e81ed08233963c3d1fc0e4b4ad599bd5317780e50f4e0551e7b310ab09b06f774c2d7dcc1d531d91b5c0145ed06200c4fe7402609b53a0bbe0c4de58d8d73b86efdeccede513525a8b8dd8545a3d0601b5e9da7c3e4549630f4d856945bb5abe3e5ee920b9f728cba5f27de7bd7f3d6f8721e27e811ac7d9cd1924aa244de8c6e1febb0f8778373e5ec63f8cad7b4524ea16f7d9a1e4dc4dbc36e5742a6f69bb5ecd15f4f4fcb6829e2474caddcfb0fd8cf0a4f6538d919b1583d748d4acd1b80dc584b47e031f1ce445f7c31c10b260c7b68a9d8e1af8c08e630f0e51019a577659912e472ad6d635472a5caaa22f5df159170b33001521a2cea14c4806a213106cdb0378adb90132fc5258c3ffc760bdc17acc309e9a7f43f56e955a577235bb03e2dd4dd1d5082c4d62b5514f34adc25adfb76236a5a44a8ca2f8dcc9b7ad9b807ba078c60a9041009b213e6d0a2df02ef4d60578f9897829016bb5e3e10afda3376308383d067fecc9c677339f19dec358a01684cfe001e17583b36ab232f8136c9cd2b99c0b2d96f46da720ec745c080faba6c3eba4a0f9d54bba436729380c4e9542625f67f7fe19ef75dcfcf6cf4b4c0778892ab036af7e8572660a2a9a0728315ef4110ce8e493fa2a7c98d98f9a307e86a81cb2a3f96fb69999fb728ffcb9b7922e8bba33e283986a9caee1c8316922dbdb2d1ed483f8775b4d7cbfccab2957815e1807ca85d18d49d48bf5d50268d84f3eb127cb90c106299a577d54812db3f8f331cb21af7806bc00f22e5da3c54ad81ce9d2578b69c48134cb117b6cf8057cd5172cfaf44ae88bc6471bb7fc03e13defcdbadb5d559e16642b822d90be575aa090e3 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8dc7329af7a016354818974b6814c962f9ee269cf4ffc843cfde50d4593c4c586efbe6d8c95e7e6f7c520b69e33b8ec6214baed3a830432d999f3db0035ef44e9abbc2a4b70d3bd42c3684351ff55e23d7be53b7dd05f721ccaac5cf66d02ababa0b6567a76e258f887d6b729558a70c6931805a8d8c3739dd95c06a33b42e67c45e19aaf4d859151b75b78b5419f867c4b74dd6ba9f54f533de5e585ed89eb7bffbe8757d2915752a14420d99b20d033d494dad2e83be1207a4fe4df0a38aa9e11f5d9ed36ba6058551976e5cbf7a170aa071b46bd98b7c4c438fce9d4d3674d6a45589af938532135adc2c790e759a1b17e3fce38888e6f6599a7061b6cdd0856c5404b042d73aeeafa613e5e852d55264a6f17ffc4030d8b1d62ecc5c3b47a805e4e2688d795ae5f09db7b2c5a213e76a5f75fa0d4659445ae170bb3762f55ae57fd7cb6ad15298610023b16e0e624855f05956ce414cf17fea95dc939829434afac49172f5bd6ca5bd1dcbc2c3e94d4a8ac0c8fd51f71b53501b8abf676a4c47f491c39e5b83492734356bdbbf6ee8ac98fb765ae4a5b26b33c3dd9d0accb0c8a3412418a30198b014e6fd16ecabeb863fb037575d06b43e33cd0d8571534f4d9e2c3e4968cba3cb978aabe80d539b7d16efed9d95e788e7e94bfb3b189ebb7cbc04e4a0862547b1b9f70bb4a089a957bf3c439787e1465f993ce67520567259b7a48dd8534c83bb6f54fd652543ad9e43f655d908f3cab1c47e92c830788e5f5d8589201da04f1cdcbb0cbad836ea0fede4f09ac33a9a87c67f9c7067678c7887787ab7ec8afa785d74c4ea5821ace0efbf53a1695d217efba7a8a68c67e9f63fcf79be977e177a0bf4ae773f8d733dac5144ef7f4b866f9f6fd3f44996f3a14af4ccef35f96a67a8b71356c2dc6688b9781e0cda2fda40015d910505c71a4dd3de56d9842ba36594feb5ee9d01fa51442fa9915c98be0b48f43be07afaa38345eddfa57f614fbd1c9bc3e48af53bdfeb311fd0507fa3b0be76c7eb9b106c561cee7c4375c40b33e524b95376bf7982a7df123b4cbae78fad99c6e70efb6845671057a2e8e3b4c8a70e757c8b424552b1b79f18eb72a64334ffc70b2b07203ed0870f6630733c26daf928dec6bef96a92064a738b1bc57c10c965d1740b313e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fb72f0caba15c00595af1b0eff68479daa985e79a0c5734987a34847215be37729ba51bbb1311f6f0800a37670d3a2f55023e88a019fb068382902a5d94a8fca972dd291178e039f8d2ca22936896c68976ca2309838416108888f13916089556a277e6958352484f231703d120922d103d6b2badb528a2eac86e174186b3278d7f480ec2195006f36583cc91c1288894759807692f15c22b9fa61ab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0aa1f182357104230349a0c21930f5fc760b821a07aa38b021123b9160d49b2438eca5ec5aca812f96cd7574a0761cb17eb9b71236b19a88d6bcc7e4a0751af543a151417d55093f6530543c678e19c330c63c371f84ee2d07d5a76ac273703b8166e889286da5c5055961084265f2e5817879713d74186fdf56793ec6c8dbbb4dd75196aac4318aa4f773bcf462586566c3c6e980731e7b8273a21c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768ea5026b61aa1698279191b69c39b53183c2745a7c251f48d26812eb4764d9196a18af28d91c54035fc149112ba7eec9df4421121aa6132e7069072a59a8739535c9c76959f8138112d7348c9030b60038a66bac005e38be1449e3b961850c1853450b33d680cbc2a586ef37e323891deccb16bc52eab1b7a6fa13205d38963acc148435cfb72803d6054a18c0de3a217037a257e157a59f8a968d250aa1baf88935dc54272bb5950303ac68495956689238bd2b595d7cd42749ae1b38097ea7ff90600056b5ff674a4c02b26aca5cab4379f0864a24fb14f24e274ed640ae6d692adcb3fe2541b9851ba35893967d39531b0c163d5b7f131cda1976e405029614399b7ea6cad628ac5245ab7552fa4d2acb10aa7fe2a91081707c327cf88192d904287c47014a4c51766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5e619285c692532735f1582d227b9a9e77b1eae4aab9eaa79f6ce7ac2fcac831811eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = e6447c8c12903c678b9e1aed0f6c21cb820f7da79ad704d07098a1c6d2e8757478fb606d38d006fb6593f8ed5e5852288e9625a164abeee5458e88e8a1a1c0ef43442eb5cc22affda6c867bcfc605ad210b7330b7f8d3e8d9a364a9ada51298fc27d27a8bd87f8b6a7b8fe3c9f467a027783ce6f98d3de72425ecdb46c9ca8910fc01b0c20fac06989806f6b4630bac19c73218987d90b1e41a1e81a90a9d278db5b6ebe4f7bc8ce196708a47bb3c1a07f1b05c34cf9b47d07027063b6c01a0484e88726cb423905cc09de48227e190f2d7e6800495d40b5248edc51e5ad6abafb682e3f91de3667b5697d02165d0f9cd409af52512ef65c9f8eafcefc75a92647c16f89b52693c05be2c5f9a8f170ece0e0ed55fd21780c092e48c464e07adc505c38989e692add2e7cc1dbfdbb4b583c01640a25eaf1ad0fd3d241d83a641bd4b8d6585d18bddeba85407531abfb7245588346d8a31f59d115e764595231e66323fa6b6d713177e6740a9ecdfe540afc59a5c659b3cef3805acec9fd0ca03ca0f5c4e5c2c89eca46a02a0026880923a8273fc0a28fe8c9a06ced412174f245eb9942b9f08ebb7690833d24c594e3ab4ed24f405d68890dde20b6d2865f36d6ab4fda470b0e7d4a1ad0623f814a8ea61084e99197123678831e3f6881cdce20eb9176deeb2787f359b8af7e0d4cc85f9ef9dbfbad12247035ea1bcd4c4e75ccc0eba9393ce0152edb04a93a6c58989f5269d86b9f091bf2013c5fc8f2126144e3e1b260f13e54649c91a6ff9156a94ce499e753b0618aeafcc5c0e1867601b0c4e744779ea63ecf0dbb5f85781211e0486e0d1a9b1b0fc01750aa728c8caebe9e7fef5a3bc9bd6a930bfbd4c56996edd1bc329bcf2b5439055e4156404b5231ed8f30baab6ccd8d253616d5cb0cfc8abc9f72ab29788607cb8145f496c85a01902c8d22ffc5ddff075fee2569e1fef59ab5646a85cf925c899cad88159df336733f1147117522ff133974419e7c16a95406717672c538112b00ac0ec01c720fafd85ebcb898882988c9fbd9b5719ff5797002939efd139da7c1f11f35e3ad3a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 269e93f37e825609668f04a250f64b59a3e5c8264bf41d4c1b23a4adfae68ace66190fdeeeacb02dc4cb3dbc816e97e2f129ff94c7c0bc3cdf469cf243dab1f46ef69744701904adf53c3e50fb87e65c4abe26ed15759bf00eca78586a6fe64287dc392b94b6fe6be10895402aa843abe89de0689a1674b2b9ef9e6cdf32de7f8ca4447547dfbf2a0d3ee47331d6ee362cc380b6badd778afef6f38aa2a5e00fdae914eebdf2bb630c4aa3008e9a9144cba27e7f183dafd2de439998a8bd8fc231acdd46fab3c0ae47b9d691d94cc75eeda2130d9d7fab51a60fe7e7aa67346f43b2c3e1cd3638a9cdbd9ff8a6ef699c08374a705ab4728f56d476af2fddd8e20f67767c3548e4fe25688db2c8a3dd0874bc34b55647f39fd55e2b855cbd53ef3a575812c54d57dae9d7ed75c5837c8345323657c9cd8b53aeb8a9566a92b12c45aae7958b39f0f1574c1e34724f9dd9d92e9b7ecafa0999360e47f044e6bc5bb6c658998d307a9ae6de8929ef6473e66fe2fa74a6d48cff0834de15b21c1e929e4aaeceaff803085b78f5551f86c58c66dfe639a2c35bcc3137ee110ae5d749e85c9bd62cac95f1a34d6a2b9461a9bf767ce4108dbaad13be130388456d4af313be2006cf7aeeff6456c760444a0399562e9ff0e2496c84d9953789f75d8d88577e8f5d3a390875f4418dd225cdd39d6b9abca5a7a24d3fc833e79e7cde8784cf86055627b973685cb2ab74b40e85a436c7b66a7453dacb36b09e5fb944d54cfbc3686fc17eef8b48f5b27b9fad4dd4b8bbae6b37a56863bcca1c15d5001c45fdec718624a7f72d7ec03635edc7c0c793c42e1a7f167a6aedbfa9134e8c10fd9b771c82e7736b09ad9bf54933fae3bf34a593f3de9d90473e499971e214c964ceeb427a7aed96b9413ba1fb487045b7359ca5e0bbfd4062b9d7f1adb8b088bbd0aac7394f3c5f077ee8da99c0c8e6689fc63574cb2a6cd5f256db8464da138da41aa5432ce7445e4aa1d55893aafe459e6b78122eea1fd98640b35c9855d3410443f7dc8739d757f50dde69b3a7de9d84602f59333d7bc2d9fd52ea846be8f6781451ec9a7efaf8639ea457c023088684a91cf779fa465940e25955d47a2df9782838648350be44899b198a706c6b5763c2a170c8c5f87b2f9a7b6af7cb48efe386c28c7b0b19a808f24e3e2b6b212a3b8b9a19f6c47d484893ed89cfd3f678207630c3844e969c967eba8926461a58826eff42beae5339c620607a704f91f1b056fa06910746c7e002bc617ecc64add1090ff1d1afaac53a40487b83e9453e6728cf352415a930079abb7e5115bc0745290c706420853d080377e921b5723047c22cfa289d2df186b1908a7bf471e5877fe23b30028a34f3fb27e726b99ba827d347c62997314e39a0f4b2b1e9163f53654e056aaab4718609983bb674a47642a81b000ca7422d3e361af12461b8620064547dfb578959b18bd1b61014d20315a659a5ca65f9cb4ee214b0d123113e34310c56bbd99737f0305f6f3b49f688610a777edd4a3a482163e6cb2c64668fc3aa024d789219078b49471be7dc4395346e7f87c5b150c1e7e30b9d2a435e7c3a32f7c4d33622d7b73cdda989aed858fe4c7e9cb163f35679b84b01096a1e2c3897c290caa996ccb3943e22f789d3c5098aa1a6f117347e0725c358670d678c51a0a9d5f66aaa6923a895cc5fe5c9530b069397a0e4482438e713290c62a94771f7168212a7cda8e2139d573a9ab0137443180c213b78a1b5b291a0f1566316857a72a521c2b79c660792acfc0f5a788962a6ae74e87c48a8010dd6436672817a00b49862721702668ff29f1077a87a96cc27038e0a2752a0d196cb17babc25b2996054d61c68c691c93a6520a97392830a8f157940fa903e75f909bc9691b86391ebe3611e04c9e0678c189b7875d373f0b25b9fe0a9b063cdd4446ab9aa6b23e6ba6c324cac29736447529c76c3398218152607aa5488a5e7b243a0920984b06dfbcc410679ac035ff824768168c758689d0b326831f5c10220c10911540c5b7f9a3510d73cc1153a2fc2a84b8a08cfd7f863e6c93e05f05a39da58cfb57dce98cbf1b7ab960bb14a9b86dc611045d1730f3b82e5eba970018bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab922085c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1dd3761c0e96678a959f30997e96d6a59858528c5e10234398e2da2e50ffcc51711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = 9611839ef5c05fde9b32a92a2bee7ccb6f870070884523b365417e830648467cf9d9c34f5b544ec6c646448f4737db5c78f8d7b2d4009b4912bb68084862a75c090c9819b1d765eefc1574d45f9f9cbae90795947190c9c5acdd3dcaf3804519382b51b2e1d8228d46332be81dd7e211a5c94e88808c2d0398e5bab8f5d68a7dc81ce9cf7daceb7b2395234980dba509ae47bf660f7b9449a3d8213bc73d207d55b97a6253739522cba9490e9514127350519fd67dfbc87a8e008fef806d422a70f703b34c8426911c6cd33c691969b62fabd01716d069d6920acc51facc37d58a69e2a101cfd101b3091496b301b0ea8e881bb36e5fc125f45b7df174bd1450e603ba0f3b66e331585f1b033d9f73bcd4c3c556c88f8e363c47885fb4181bff08b56d8bf0f3e5695e791310ffc5445e91dd7a4ea60e7e9f1ec75c2b13c19310beeb4a30507cbe4bdc9b5e46cca1eefe6748b095a87317c19639934f6d73d55d0be243845aa7c5c56a1ce2d432a8647e6fe9b7cda920cb777c58382ce1fd6a3bafd73c56487e5ec00a5dc0556d6a0c87185ad2527a3efbc03ee3f752dbf491556b68bca5aba0a3dab531445fd682385e8d0d3f49e54fdaf41eb58e4c2287983d013ac3eec0e4d45dbaa93a6bfa6bd9579ebc5e2f9c49ee45ee402fa8702a6e734a2c68e414ec0ff0b69a1da9c6d9ed89e97efca55901b053155c2c9d5d2c83c8fb59d65535ed936ecec4d493fc67a6595178008e1d237de84667e120ccf9f30a2bf571a6c7188726026b14672d49c9afec1c20aa2e7e272d01c09c562102e196464c0fc67a2f4edfaea9dc82000d2469c8968696f7f8e9c89e4941e1f03a9d9bd7052a0cd4be306b5cff1c666cef6c69a150692ee408307ae315a8f72442f63a9ee1bf07f1aaeabf9d473cabd9261abb8cf93ea8c814684a05cc83d3e6008d25a1e4f03dffee7303c6e473d3f2084fd85ebf13c7ade84449244e6f4af792b139a3d7c89e66f2e4083b1ee1cc8d90c0579df3c9ae83635f9a3575289f0720789e04e9e51d4bc6f169ca8ddca8e1695edbe32db5fce382cf61c6c39a520f3fa102 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 26f5bd7db659eb8f88f5e6bc5518e7957aebeb27bb0c38ab632f718d77e8a11ffbb637b6d973d4bfc7b71515398d5fbdea95cb78fb436779d0eb5c864467fccc73c2f62e64a9ea434d8444c958d6e1495ce193a8749f7b78e7747abdae91854e2109f44715a414df452f2dc274cea17487bab18870a17cbd545e830e3dbcd04ef4b1173bd19baec1d53fe0ba781a2453d0dae48eaf349474343857a806f39d0c7d88a4b4b5af1abeb51433b02ae1df04806bafefedb3376485b356c6c8e059b8558edbd003bd49e56e411a56a978fc221ac55cec46bd0f98c90e7164bf9c7498d441b5a6f49b6ca47b4ca8bf6803ad6943cbe1ea6aeaafcba476334422b9a62e2469e24a64d6bcbba8b5d01edc50e1b85b33ace8fcf55a4c49fffd854a588967ddaeb87d3639937b37bea9599b74e84777e3fbf45b833364a9acbf974c70204cf7316d65e0f69b758f97d84f87d2c7a14b265d902c82f7dc60906d89bc57d7842ab599f798d1cbf1df3e7efb9483c924f3f01df5a253f526636d6f773ab48ecc2a5694848866707f4fba6b578639f5b014e8abe7fc2bed602ce8a8f33638ccd6f6c763636d0db416b7cf12bca01af7a1136d5f8d5cdc5d5a5c5dab5ddacffe6fa6b5e31adcfe9d605da887447fc002bf6591a8475235f1e8dbaaabf57ac6595c03377e6408f48e4a76494d9e9885f860684c00db97eccacdb16ca5a227f31eec7b9b7e77147c76fb84f1a3e7e29d05cf27d361e3b8c29abc3f46e9a578233a30233dd1e5a54ee94857a8796266e00d76490e9953416781fe1686819d6d46b950d4ae8b383ce8bec8c62223a08c3cce9d4d6b25b5b93c43a420bbc7c62e6994e88c1496f1294c6a328ead5499c0806e5287fb8cd9d847d0d485aa3585465f31cd27de90a78784f3c05c38dcbcb48d87da39c6c9ab0b9b5a0394b483be7dedfcd870134102d8e56d6a838f5d9943cdf9c9659e3ca3daa4f6764d7670781936c303938ddce28b8de0bf6962c72b86d06a497bb852fa79df1b43b9cb2e6efa27d216c664ec8fa0619944d79bc2bb698f7f77b54abc4c6f56b7d6dafa1b03655166ef1534105e4b3bf53b1e728b61cca6adea603ce85425d8f251b4173f288b2ba4e61a1ff409215046a381211a26b897479a5b1b3623362ae7d22410d9a11f72cad7c107e5659731a6c2e0e95c956386cd2527b29095820b6268dbaf16c0754b583e8288787c186de1f516b204705aa1ac8b80ce70b9100c92093c3a7b69ea8976f5c5dce45b391aa28f0640940166741876baf7b5b7c6878a87438db18ff45c7371016a27e572360c4b2fe4552af9a1a47cb82dc249f2c8bae4197de351a48cbc549e236eb895c487f27ec3e765101a2e68860c61e93022292ec7435df62a1012d78824960216c4ce18e060f1c4af2aba5e9ca9134732149d3a57f72521ec9a97d059515ad9c3add828c75c90f6300e5135cbc646af16866aca30b6bcf60fbd9c0d1a2ac95b999e0749a3f5b9a992e18a8257af35fc9f7e4bce74c87c7496cf2a7a16d966cad9d02260f630d2f1b011aca52f78b6f040759068c0f3f553a4fc0dc7c9a4c8c05ef6c9b026b3be38f0c02049b8c89c88ad01a861f2b1b142a961c62f246a4c19d2cf1849484f884119a823d793a5790420a8f74f97a220ab8b91d475717785c12abb83291b3fb32c7bfe836b7b61c03ec76f36d1c8ca01426c28471676302129116d2a5ea5d415bb13188cd720cb96939f21c7d1fa17a59589817011a48cc65ad90a7353232e8a3db9ac87d425771c7b5bd1968498819dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7d61ba11bc93007147ed613c72f756bc367280278f0076addf854e837b62c9458c34f138e576a99f8a4baf5b596d327149616dc1827d2ef5c828d4764193b4f39a4fcc027d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c5449225132b1c764e91cc686afded843dddb97213c28ed00a6e4e4b66c17074181cd26b15ec1f3c53a18bdd85a6dad68562e3b78180066b4c4c3401aa1f752685ebc8316d6bdb5291e0c39cfe778b8ce55564aa50acae94c4962cd942271ef257bf1993ab04904832a9538e0749c97790f26a09c2c81d95543b5d97667c25da1c7ada9e9780aec099fb096446c03fd1a0b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef96d9e513a7cd137583507ad7256844bcb9775ca82ef5f411331a7c37ce451181f6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = 0393719568d07dae3cffd36ff67a93bba3017a81a0d5e83c07c24ba0727ec566987890acf4c49002bae7fcc834196e3b33f944ede0269fef2682e67db70757330e3ede1d8fca6deeacc178ab6b880a3751b1878c40415dd0aaeb1bd33a6cab3a7049a7a72613cb9c0a9957096b827bfd5ad607cf659a03c7cb6c34b2539ca0e195ab35b104d99745254c7863119ca7b03c32774f18542aa3a911bd00c8458ba9cdcfb3f0b6edcc5fa51371d58e82b3cbf40dabde56152b5d4868f82e1769874cb87be8cd62441011b280563bf2036e53b6e710d04e52ae5ee4bc617b60c25b6557537b64f3f671dceb90264aa4018a4d22d9e2dbb67af3b1f03932b93fc8fb78fe4103ee9463933b73a371fcdd66dc2012ce5df74254c440e5ee491b19a8bba884071bfbdd72cf865e4afb79cde00ec9a03b16dfdff64508e3fb5093379b5bcaf11f72148dbaacab35c7e78a9b811da318d109213e7fa5f296acf4f4d1d34278a3e9e9dcb50bad86c717cec38cd6285b743d3bddfa150c7b6f2c870e311ae8eba5edb4837c85da01d1c5f3e33b173dfee1b1c9e77649fde88fbc18a1f9bd7da55cbc96f549da361fd88455edc7e1c772d1d1ed5c7e74da4c9a4c9ecb980ae0ce3a6c4260263b09469cda3bd25242185c5763f982bb59fb2a964930e919e28682bb83a3b1916db2a80d18b1c04119f88969026e13ef30d29b4cea6a02cc29ac4c0e5d8b48155d95e46c7072a25f3a71949aadc4c8d87b0ab3f62c3ae94d963f78939e957762b72f4a77c08cbdc06c6bc82ad0434448b9450dbeb77824db25e70eb43832d06185353122197cbab1c07312d340ff04f3e53a6913fc7dc051274f9081e2c9e452735ef560c8587b09b06d44381a356c7b4d6cadb5cc83489433cc155e5ee9fcc5a3dce297cadccefce8c5e4d9ce70d5ea6e21a0c96a764d5765e7979369459067324291223a8e58c274966ce4d22a4d3df52416ee6486feb3b979ec6f8033f1411b1462b91ea200de02581c13edae24d377c3b1e0d9763c444e270e5f186068450f23765ff74ef284e40a75af0ef07120d16d888c5defa6560d8693 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0a5dad4fc96449f351215ff77c5d5267b339a7c58910799cc125ad58785d8806e073755c0e26582ff9bed09ec8a383d7c815a5a5e4fea2eed680b4322b095b1789a7641f88ac37b6a8e8e68d7852f7a7c4a7ce78eb43840f44c9a84a8cae9ebcbb35f07d2546eb44e963654411974fc0fff4961ee15d96ed3abd46e903bafd4c6791d75249c3fb257d5892e67a329ff68b8ce97b0f5fe6fd689e96a2e11b822565365718721ce6b3916ecb9328d69fdbb7a1fbff7fece88168c125eea86ee953058f885443a47179bcbbdd4dcbaff714a963159eec910439dba531c4787f089a3ca8c7b97ebe48227eb9e7d7ff0535476104998334a99f0bbf168683b0bc49f3ddaca698b92e285592acc7f785cc1de7ea699c4f5eadb986d48dc30c33c443638c344c76387c07bb545a245050cee9af8df7621fcd47a3a15cf3ab78b760807c92e2faf3907948e2edbc11e6597bdb5fe70f36fdf4744cffebbcce8dc067d88dcccc60fce7091f32d08ddb04957fe5fd52c6dbc053da79b2d9478d37e1b1fb79345788089c8c511c50891af4f4767048cc3aeb03911dde957aef6eb64380f95472ca4d8a8565ef0cfbd5efd7dc115d81c2adecf2e9c689f742bf2b8edd0b8403b8f5d1ba316a9a7b8438c739d64a55e93821c4e896cd7314c392016476ab38c8079f6879a69e237ea7ba1fa5e795e20d035cdd5d7025ac7e491ec5ba6b517dce94a8ece1311832c38934419f33b59e7844d8f1dc06eb8f96538ea6964b88a0b5dbb117db4bbdac9db2b6b15723cffe26a63b663295ac3cdd44cb78488a0f5655bb0bccb7c57889f76fb23442eead924853dfd31f542df8aa28979179c58fe695f1b9149592b9a81b89791878faddd3fdb685acfee337bb5fc0552a6446dd76d56ed2ae8f8fbe7849195cc44834e6868ff63926cfa86d31667bc28523e4547ee4d2eb5e69adef402dca5de889e24c5440e969ea9d71d4fe35582c7ece997b2ff84e0a934037fd3610d6f931c7773648583dc9c83e4432c6b66f1346475df3b2aa8e4328ee504bc69506244d5067d04fd839ed07b88da4e37598ad222436cd7f494098cfb36505dcb77ea88c2ab18a760aa67c49228b7e5bb524b5c4be081fb3d8b92cbc4b92ccb4a61a1b1c14521ba4a898d46ba44168dc5a47af9484aeb453c4fc56eab73b0cd0407f5124ccf6b21575805e311af65084e2b0100202a1a39a866ed038328b75bcc206b55a90d714a7175c446dc2091b057ca54c111a820e8a75ba0206715a3042dd0ba36d2cbbd72326532b58b02636cae1949175bc51dc2f46ec5736ea91023657cc65aaa7c22158d22d76a304f796cda7d377c0e79a4aa683f341b7d0321b623782cb189ee6eac197860e05a224fcf12f7cfa8208054a56039485b11c1d888f51c479507b8a85a57b51f5b824f3a9e41274cd188d2099765a004bcc64a86844993fa69c0f63190c347e5f015c6bc290b39cabedcc3be8515905a37fd746616faa036666a08d537aba7a645a501f1cf0c0c8d76d07a67f47514c4c49c854d0b8d3fb02fa34abffd46620e886e00700c7c34a2a9199c78c23f58278fd71c0369b3d0288b711ec5775c70334e984c686cd8e3a141f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31eb51329c8125e8079557a63a53a8a31f245db209cb7375272d9689cd94edd20be8a380f27ac993a9287111cab084c196f4a921b6270e43366ff94af4d4930097cc847769cf3b8016e024733233e9ae67f8f1aac07b450d2299eb1c7ca84c28990377ef1150ff12b14f99b9a1bb705d719321e384399d675b382beef53304074c518382d341578e96b8e123312112c2f4dba5dc5b7278ab251bb3c530bf104783819ea985363fa8b44201d4f1c5c46497ec64380fffc553239cab6f543453485b6044b7b5049f85323d0e8614a8b5c28b52633e72c64db6d0438aceae55b8c239c6b06bf660a146c1a0b132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613ee0520dab93b8c15e0a301f9aeccedd16aa71a9570f31c3cffa013b27a1ec259e738bbd69164f5cc002cba96c68a22b35597f41fba0cdcb81729ac1c4ec49507683fa304d00dd398515ad3e92c33ed440e3013daf434712704921123fbf628531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516b252e5abf757e116a92518eb72df9f9ce66b07edf4d31be225585a6a827a35b8faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = f12f2ccb97aeeedb7dc3a81f0c525d2e7171c45ad0853a4bb6156bd163e09a5a27251dc51b0d6911195407f980b0d8d86b65a3045d52060bf1b7c1d76737e3e0e4e1a6604241d4f0ff6ec85396d250a2e61ee3f569fe231b8513986360d029e99023e8f59dda52629c589b60cd4900522512702e68f39ca61d1662fd0bb515f676c76efd31adbc5b488450f1ab845bebfb4fa53ef171f952f6c7de0264c49ace51fdac564ba48fd3967fd83f18e16d827b090b966511f6dbfc435d86532e4f2b25e2e31eee2b71e85dcb923bdca1ba0de1dd46ad8ae00a085ffe0392693329592dc8fb400eb03f3a5ff5d133916e8744a7ee4fb9dd7249764844b3608540a1918e267bfd0f8f6333d241ccae868ad3a8a5fbcbb3aec5fdd3b4bcb94d4dc945f1d02c141f3f07e747f4a481402c7ba2cfc0796d24682bb814b71983b6823671c0540db1fc64b1802dcba49346fbf1490b829972d330639a6026c75e9abbcacfb38bccf271f8e201fedd6974d2a170f6507c4020ee7a2d70aadd79340f1db2a64da4261ade72677a2365dca25c22226a70c1140f709cf3d931b9e347cbdf902996b99b031f3973efea8f17858dd81245d631050acb28df40cbdf7a159203dd8f7feebe936941ec73b342340f9a46af07fe5258cb05a70ec04a8bd7ce4b81c67befcbcb4a4eba394d7bf60804b6afbd4b716987b874d21c0cac713adc3db1ec9ee3925a4f48664068f5866f0017c8056cb59730ffac1db65e235df9cb8908376ed4e06e31fb4cef840f6503923abb60361a18ee52eb59ea32e35521c90a21e165c1235a8eeabfba3d8274364e1f5440413d5f64f5decdffbef85f7b269da98737b30e17e7f6d9ec3a2084d9152b4e2b2e91a1d1992adce1769ba0e10b2d79c4850e8baf6f14a40f7223b301d439eb1caa11fca5c43be5ddc83fd432d1acff9ac9934a0025384d8d8c23eb6491f7d0731a5cca075afe7900d028715bd8d1ee4c595fe15041f253e3569ea5814876b154c05c78b1d1189df03cad56241b49bd8ca4e9ca83e47de19657ea4b3a08725e4d45a1068bbea9463ed57c05a65e46d0a43b73 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a2753e40af5fd88f4843d5a6222d5f777c992c7bc7e49a740ca645728d4a0a1d768eb4da6b3780ae95a6c4bdf36f3a3f72acf32aabf7545ea3bdbdff09e682870ea6e9bf900017b32ebef267a856a803e57c954574c954daac9c7f1bb90e66c5df96a6213b98f6f470f3095d6b37a3482ba7ce984f4a4789901b63c35a573a9df16e7d984255d0359b6fbf953b6e0a662bee60d056cd32cf6a69aad5b39ed6fb37f119583bfee78e86d7bcc53db28f17e2379d3e39e331645ed46073b8d28be3717dedf2e9d1347682527c7cdf4875fdd6c0d343df51334fcc8946f2363bfacdb55798a81e4c9e95db7550a7535b1c909a5a8c353b67efbc38939fe26277eabdbdf797a5948e53cc32ba32f2c5a8823c84b903c9e7e5d669ca6e499c888b64be5b59a7598eed4a1fff4604a11e69dfa723e35be5f1b594331d2783a4d958a8f7b42893a16fbeff2173553e496a3d4d89137947a0e55bc20c795cbefd8113f118db3bb1363eab9fc2496dc7304f4836043aa6085c81eccff07da85ea8ee027d45a2de94f1b76129de953f9fbc1b09a708b5e2274849295d5a4e467c3ce5d8b9e5f591c8659f27bbef053f8ee8a0fdaf6abfc4a51557d545069c1bc8f30c58b33f5c591f27ce6ede74ef26f1dcad35e5cd7eaa97a08c9fc6a3c5fd3b07a6cd3a58518989e9a77ca81f5dcbfc793605d7e7d65a9df7c761cbbd67c35dbb89a04053b97fbdb8ac37b22cab34bfac91d7c83850b834beb5c0340ce245b93c2349f75dc47bbe8f8df71b41c32666350ac4c4f3d87fd64bcca47f3d0638bd26cc2309578f7c621b56ad0ae9e2d94d54827ad2540597e73bc6f015434a55c9ff8c446c23a3592dae4deff0dd3aa454f9c9c153ab640accca49c4e8fc7d946b900ed68bfb33908374382de59d02e4abb68ea6890de47f6ee18263e85fae9784a683bfd6845578a348d7bfa2e5a35cdba7bac582926b57e893ec90b3c6b8e6cc3af84556d34e5779bb98bdb2dfd3e6a54bc57d2eff49e9ad3ab98b53f3e2569967813f3656cbcb616fff9edb4593676d9d67c2ce7f9626147e5c37aa399d3333d8fc17f97b68517fb17496bc71146b716e9c289410ca7ac5fc5f663abb1b7672f8115917c610dada39ae344dfe805568a0141b6103a9d07bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326043258a62211ebb3568d10b46b08864b637e94a38b132199001a5f34c5e8dfba0f853980f071d8125c12ca665e72673102c05d50b28f71696f90c274e74cf57cbc86be00177930fa0a1164a245d57b4b2fe6c4e0f740d87b8695da43a98e79b3b102efdb35253812336c1058e727e14c08444f24b1415312185b2afb6ccd9b5920781ac0b5a7a483125a1a2300974c429e7957de3a796a48996f1579982adeb538dbfb8867a855059622fa7394fcaccc507013c910c79558b1bd4b5bc696052005c8c413253e6617ee827bc31bc973bb0bca2d6ae0b17239c1210b4866f5802086460589c64963a83a3ef18b5277272030079b3c2015cc1544985c687a438e94145838a14648c5ef5bb46a0988f42e124397bcfa42a2dff898efb586b2c6aa86b75b0eba10b2aba678687822ed5ac8dbccd49966e2f1991e09260f547a4b0d02a6d9b31ed02bee1764f7a5085ebf51fd5862550e0a19d05a78a80276ca0414ffc07b109afbaa9ba78674b92c5b6df20a153051a3c2378b7d05882ea15ac2183a62b8efdc15a9063b041bc1ba601bd9c16c6156c6e4ad82c6be595152174d1527a6555b42086be9d05945a289ee90c91e525b8a69324aff21306f5375d0934b49677b1f288d1dac1d1918adfe3abf0e738c81b0087e22c1b23aed4d742c283ca5530a0960122cb2a79c0a2966c5780034297fb4c1569d2b73127bee4e53016b04188599bfc468df3b091cc0a62a0832137127eaadc7bb0176baa45788e994cb8983c7b08547d340092594cd0f05d3baaae475092c3499e73d16584daa3e3f31df226c30aa49e59313e5dc98a6eb16f40875fddeb735ea6cafc657db8692d28c35c69022ad1e53418c461dcf46d5a40046193ca8277b28ef606a9e152946b04591ccbb1b7271940105436644e275d6f4503b5a32fc9907bf5c98d7f90623b822feb0c033a1b90d87422453a0460087b81098c163c295079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d018c081231277f424c5f3f1f6b4db91958611fa28bcf09ccb2573da64547e1958a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = 7b901088572fd3d5646a8085fc48026ca4ae5d33ea65a51deb6ce1da3d23c4dd748b2ce6d24879e9beab75469b2c31784d5074e5d84e933bcc638445bc01603c6b6c916ef5b3fa0847dabe4c5d62659b40a3e80686b91d1bb274d371b5860c56d042a84a5e0bc2b110a847ec6f6374f8770b5bb2e7eec9310709c8607fc09d3074ddb08a48bce41de572f2745d652f9ac11fc7e4ad465a6b09934f3641e6ecf60b4474a18e176781279be819d7f3a0adcf19ecd22d48038b5f1090cc24ca9ccde889c55c599260d84d036bb7b83697d463c3d52ce6324f6c49ecf8d6f3cef3d179454e6ef23da5c09e80830182adcafc696860b7e461ae9b3a62bb55c78eed94c94f5dd01c42a5fabb04e90faffa1983e6fff3a402f84ec8b400092527a71d613f6c029f92367b67783434dfc83c5e10291983712b66518074780a7d8bc7555e2e8498cee12317d030691065c80a12ea4c2fad1575bf85c2d44b3d90448638db148eff07b07d3cb6fbfc46e0172b9a9aa8665ccd2c53e3de4249f2b3312be8632942c14476bfab2d40ea748c2754f36d10b4a4982a63c6c3618b98c963cdffb219088ae2bae9f4948c61ff8bd911389e8aebe635bc40468d802440c6e84a7e1af45ff0dbcef205bb7da3412f2729b4835c123bd09af81f4edb9931dcb15e3b542e812b0c5d5467a184fc8d858284ca37e3804dd86ecfbf414d18b5975cb0c9effea4fbfc53700cfb32da2a9d0603c35a635d02e16cc33644eb7a4af1370f1052afd81db54a13b65faba18a27a7fbc22c0cb2c6b6af2f1947f6dc3b53d1228b577151e676305c52a5b38156963565404f8b7d358519cbe9478450712b4022e4099a3ec59462fb256ea125a8337fc5e5dee4ca4b68615d8d29133b37d5946f0d022b4b84036e5057ae75fdb638cf8bf5257f11fd2cd55795471cb1a552ae0c533a04f8a00b343431a7fc360474c9b2b5a7e52dc3a0812082a38c235b1fbbc3d960e1149d7d1a816005cdc62d56d7c1ebcc55109e48342f56af97405e3c3805883460e8078510d4f2f7c9599f4dc804ec76311ec8fa6759df7e8a94054b04814825 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0eb3ce9a9448f835fe9f4e78b2fed3fc9c546d69d2f2449f375a877e7461d70fab4f68c2ad47b3f9f9dce937e833e4d792845fb4c38eb9bf31132a7374898032333b8e4f7272a4afb2c54f5e37bc044638565ef01cef5df5bbf1b0045bd304b62a15c14fcb465e29b845e457430757e6adffe3293837c3eb43655979ee7411154de54f748b1a69d0c7f8f273769eee544a5da69bd4558e13fded3abffa163c317d5ecb39d896a9b08c34a41b6feca94ac99a6dec84e89dcc3d413dcf7e105bb81d88a3ee3678e6b4daf59fafcecf76a9d67bc7e87aa5d78f9d046ba453c1cd5cf6909b916ec8cd7c3877c5eb3e5c5df8ddcae4860d381a9fb76b3b40fb374a4e45b3e87ac4d5be43437fc68c948f3e777777c78db605d7b79768bdc66580ff98a435fdb42dd25319b0f71fa1b8a350a03f418994e93d64d753eaf2f25e724b2646937fdaf8f661a29de0a0bd718ee588aa7443f78f4fcdc3c28c5f3b2f9ff871f3fdebee43d10df5c7da55734e5fdcd9af004848f30cf0b5b38c0b3c71f88b4266bacb56d38b20538cca1a5eda99fe3353e5213ca163c36beec696372c4d7dbf8c2e8a82e96930fdc6f8eba59e25ffd8e9857cd63351b7fd911d96e8482a41ece8352aeaf31dc77c3c7ab51e6ac73fc7700fc97a3d4ce42987d5dd4bcb539f47defa600c75d4eb38cb7d0da6d2956a3a14b21cdafe6013b954b967050bc5369477c59a365a54d57b0dae8b746e57e5540c7e99ff3ddc3917add09e4cb1ea8bafc3cdc2a53c407dc0ef29394f55cd799c44d309d0a4735bcc4a8ded7e60a46fe1141573efff85bb1ce1f7e8f8d2497f9a6344625dc179e6854429a0a3dd9a78d4b9d8c73124cf411f2ac72344c7f32ec7bf9c3012e6e51b49691265edb17ff4bb5743df435c281c3d2cf77efbf6d6cfd5b79b2ca4600fbfdc1f3acb6ea4c1f5e2f90e7502efbb68c45586ed6859ed5621bb4098d870ba679e542af8a48dbddc568bd187882a15ee34bb8f36bcc8d9fd5c4777761e8f672423d8b0a6ea267a7caaeca84247421fa8cebdcfb88ad9958f06eba1cfcdb7f4b0051d51265ee2cf7bc9b130cd26fc457b8ccdc1a7ad81ac5db25945132a6c152b12a29c8149419543a6bab0b8af5dd272c5a7b19b82199e943c5a12280a22453ff36c7b698f40d092e651cbee12cfd3843c07da95fb5168a4f9ae4553b149ec3f0960199f6375499372247cc59f4719916b168f02574e1cbef360cc18c3ba41a3258df742d9f6b32c076f695a7da1479790d9a1809001747002d8f488cd54be71022e134a4e8a9aca21570351248a4daa454fb201b5e57d15b30994b374277b3861898734436c736a2fcf0a9214661551ba8530b6ca4f36a74f8933b3c2bd0fc89b78146871c8849b31acd0fa55726836f8a6a2a36a32d43b78f94810141c6b18b4bb6763290a289ad6363f08816c3bb3a2e519a1dfe276f6814b7f693958f4746ccb68cd320ae60c589ea94023c7adc3c680a5c17075d772b28bcd8d109397407b60c2a7ee00758d7c52630ab0f686b510969404cc1a9110338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed0a283f71912b69b40d6a1f84a56576a02b129409e2429d44a9b45858243279a5fdf07f00e6392c662de780a5b8f82ec6dc248347c9a02062ebb67eb33457e5d36f10fb99db0171ef0949d117be5034ccbdf951a46c7497166294727b59c4b63034435e41c75d70641f800f0d458b23736ecb76bec2702b152389ce91736890af06840cb8d9b8f375a33b03438e9236fa3a221f83186f77aa388c840e2b6b9328710a2092faa59eb8aa2d59769be77046cc334f9704c8b855a787373dbd77215f268946e5c8792aad13e645f292bc73487432897c50e817a1f15002f472e404298a785b26f441ced2b5c7235c7f3b4428d78a7d47cf4b83561ac38da9cc124eb40b44b48231c9078702510326095b2b3492b82ddce7a433e97c65878f8fea220459bf77a81b8f010ac66ca102fc14fe804680fa9678c41746211444d85aba5c57051422c69630acfc7b86a843a74127effc452035b41477ac3ea934008076f09796323cc9d1970864300e5c309f3d7a3419d25fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e40ac7db13184d6ae6e21a14a63a2ab3d6d5d1ee7f4a6011413a0295b752fd2c28ce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = 7bec5e9049219304153fbc35e29817fc3d6d454278f6e0bafb207f7911fc725982a15106817c7626e3925d992de0f1c50d158d3b37fad4ee20628a8d8aa4c8a12e47d2255da69699f6683c6c09e1ceca8e93f3a6b8fbaf9bbb42878931a55d7d2a90c8b48e815fc54ba065049970c9e4323627fc13c908f7c939805ff886b24a659ab7bb41b6f34589978b129d78a95f3272212eb3c51da7234a9e46d86d16fd8fd37ab7361be0fa74707541f635dbb9ad999d671e886f3c391fe4c5dbaf3df0c3562a5825c00357db49720cfe54ce633e10100c4df6fd0ab987abe2d83ea800cb750a812d7e202e2fcb0290bb0b9ca9400884a9107f540504778518b111310526a756c155f107b5f460b5822b61a15b601102f979e521d46823aaecb41500b9aa1d43c47c9fc312752a2e41ef6659d2c3f426e354ad932a0398138045904c53b90fd388d93ea2eab7bb6c0abd6ef5db66d2349351d10ce1eb8f48e4f4306254c44bd798766efc3bae38c4a70f6e0c72c78e76c990b6766b2b2ec349f3e86af0a15d8fcd0c78c6695852be0158e9270605372097054fbe92f5c347a5573dea1d135c43fda7871717149752cdde8daebdf3f901cb70acf4bee19a77b8f1f191beec686265699e939b5693e0c96b8f8537e26af0366f59e3cc86dfa4800de586222e4fe021f92e01d837383bcb66bd217608311a539725d260e96e31cfa76980af8397c0c64362e17b823170e483667453787f31eb4afbaba15e37d000c5677298e7055a09a3b4d0e8c918ae01b17786848b4029f802ac4dc7a5a68cbc020b1fa27aa4c2c48e3042761faf8735bb865e7c521ba2766c11989ee2c5b41ab4d072134f2fac550ecbeca827e664faba269ad09ecc163dd01243580d29e735f04a95dfd58d314853ec9133361033b4729ac1fc7217e13611c486e531ededfbc1c9f3923191dc456684fc09a8e3842ae6d09f42da68df8005ca7735c87c075275074bc98635730fa518c866c52083314b4c31eca355e58382e4d2ffcca578fe1cada896d046a48fac96aa341fa097716cb05c8a3cfa1bea7ebbd7ee2dbec57e0c71da59 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5a3861aaad670a9ccd72238832c63a956965df07b614cc8073b95c6a3375f9b73e32333d33e96ea324daeab832b523bc7d55361aac727dd3c22e8d59062c37734cf41f388199ba39a4f6a08b34d3d14b760f5f5c85a87f8c83fd1bf7f6d02ef9511dbce0384c38eeac73787d18bfb5aa5bd94ccce7b2dfae5a14ab12e5ed803e9f3928ba35fad0cfce706be397ac3f3c13b852653bb6736ef1e2793e2f19cf1d54c95d8b7d762dcd6345d013efb816deca9f5e8f7099f58a4af17baea9d349fbc9aaabec9668a714d3ff7ce93d3ae8608f94da15c9a2eee20184b5fc7a3dad6fc190a9e3f68741227556aaf6c3fa58426c99a5ab8ace5b26e4c23cb079084d310a3fd6f738ddb86edca4c1f975508c394637b94a57f6deab053dc74556da5d353eeda0f92d7f2efb4e1b34642f8b7fd83687704ece5d25f026a3881c375e2b6e3ec71da21363cf0ecb42f9a7acb11dd036fee3ad8bbcd27975706d837fa5f0e409d8c3f79e34b5c852ec3f33b432037d76e6968eb02ef03f7461548969b57f48776dbeff54ecfbebde480e804a175e122be0466a51404cd95e45517c58e199e6fffba850e8d5452f43857494d66f85e3f7af4289b6e9d0ee4889585271f7aace6bfb43937255d469178ce7c2e636d39d9f4cfe65f4abe02f2dc1beda46027ae4a9a3e27deae0ea989a05dbd4f546a664fd68abc4cabc3fa7a4568023796c3a3f9c9cac6183d9b88e26f5c603378baec042ddc1447ed5ee284e31ff4d54c79fe43fc63fe9fe2928892e94d1c64c6982b7607127882d633dc873352639f0a458938877496976bb122bc09cd4dff76eefa2a3f0fb68e563799dcd56a4d47ef5b7dc5731a3888b3331dcdcccb2ecf1efce46625854cbf863b3fdd91334af76a741b7ebed6a1e6e2e868d21d942eb99c5b24a9139c63c3c98fa87aafc5e44e178ce49a703fd064dae2a9c3d61a4692807afa3469e363a6ac0ae81049f3e908b7d7028497cd3cafb8ea8873c7064a7a1c3c3e0c523b3df396eb72bdbdedefa32cab3240e7fda4378f919cf8ce660d8a8616f43539f2aa8acf74f6549743985865f2673320558ec426b57e36419124bb8516c6b4232728a1ec4f1a51dd01b932738d9b00c6a50cbefb657969b4dd318295b6278f73963da647156944423045978c50d3c078e6d0729e0219352028970272f34147900370d490c12fce9b22357bf72fb470e748d82b79859133d8db603ac7cb2672ca9c7226b6e99a7488a219966b7b897ab398002090b4900acb068a866c50c3867380ff5eb2e0c9c4eaf497adbeb79632b0c023474837709a3d7cdec9c2f782c9a3ec0c6ddfb37cb3321db6315f0b0ae23e7c6a4e291baa61e4fd26c98f36f69d75369f5af277124295158b2506a39eb43d1a16308b71f3bb5cc26897df2378837d9cfa1ac4745718fc3739f5535c35e07b461a8cd65da18a3809d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcb41d00bac933c3783f05c47ca28058558cc05690bae3c507fa8d5780227a61095f0171a6d826f714146c934b80e07672e6bd66432ad1479136c06dd1a29f00d18b26ab9f8fdb7e6021ce7c657948273268e6b65245101952c73d949c4d82c8144a3dbfa7a82784844d57b354b1598076258fe83a23987de29261b0a8761ae3167d035e96b78fecb9bb51055d86e46466708d79a8b732b686a23b7e36f9ce07ba6956cc46bba61ce934af8ba7738bec5de094010aec2885a8153bf71f002c9eda917f337bbc18da2324b45bc79127d21b1c12774c6fca6a5166c4f03440af4520cd09233d493461420e5ff81ba290cfd23001052a9dd3665121392224746064f00f5b1a4dc19528a7b95c524304aa21164a45c964a7320d2611c68498faf56cfc195373267b01591e6c0a8d1bc0007ed456a4e205c49495ff99b1b1754a9e429346536d16e015dbf7967e851974b19721e845008b76b2c47e7c3b04457c924693bfb6007c918c64cc28126665b01cd18b7a253bd0706d3c466eac224fa12bcfd60417afc1b865029b672663afb3ba51b6a2b20502de6c6bbdb33a0ac4765f967f8d685ef1200ae1d17cd5b47aca963f2ba5cc38059b6937916566a219ac32157728dfec1b9950687ff543169a96f648ad2501948316b55ed4c1e861661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f527ea5a76294070ab10a6edc502d82be3d240672e5fa61377e73e5e19d11f64a37f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = d142e18d4bde68a0ae2591fb29bbe402e1aaf696a66958a5893c12198e950572959be34051a5b1658856699711699b1ea084fd8256daa7670d089941d069d19a321f2fc93cc625a727f1e7e7364a1993a10a03bba6c7c1af4f2cec2b12a452ca1720029d758559f271e6fab4343f96129875dd486ce6c6f14d103284479bee0bcb5ee6921688cc3794bc731b9d0916198ec510de76fff04cc27425b141fbf75f7e12fdaf1aa8e6cd097eab34c1bcca571df37d7c21bc12db3992f74d301762f8df0353ca0dfb827e485cdd8bad1f4a4d0094e008f9363f6cb0c8f355a42b66821b4e1b50fdc237fc7dcedaef8949d7f0f4b287c2c61548f7ae9ea64b7e8f4231e48bd5e37615c9fc9e5847ec4141f4e017ca86fef3f1df6ccd9c4116b4c8203caaf93155d57e3a243c0fda8e817a62609ce9e3723c39e4bab122db3fca8b738e48577a323ebb23528e8d8b69ad9ed322a23e8c4b8b423d2cf6ddf59429751cfddc32ce28232aadac1fff70352b37f727017354c7458f35b8702f15e2936eba3413603ae0ec0c8a17dc39cd1794972001b36d58f0cc83889c51db6656e85a68c6d6d4f4066b91b72d595049991da088bb51d29ec2cd5433aca956143470322beae2e60fad818e27d6da11252edc1fe5cb11ed8f7d0dc857f948ef779c75550c265fd5119bf95101ecafbee7fe603aff7f84c6875c6a48879c581525e479d456d0866024560b215aa572ad31776b2ff9ff1aad59fc013b86acde4151a17234b4b114b90196d0502b3d01ef71d00d6e8db3cfee85f91d8be6b650327fefb86ef186d075d600c3240ec81fa333bef3a0917e0d5b8dfb617e9a1b813f55c4736c9266fc73955cf9fa3824a0d7195ac5b356cc4fd8c967518d5e0b025bec7b2b2a79578a50534b2cbdf0e4b85e9cd69232db99e2015d8d9b4af15aca02173e88564c0f1bfd5a532051ba20cec7d16fbfbb9d83f01f885e72cd50897e6605e540c93502bd634de0b0d9849eedea4c567cc8ae47e14def90ce5d7c0dc93082f1a2ce9773116cda4d59da564ce8fcd0e549e4c8d25efbafc4f0f07a6ed7ac2aaec1dc04d4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 64dbcfc877e1f84d46a26641de9d65f197ad5f2c8f62056b9a3bd2755fb0fa17f41085ae275570f8bf48878bcd2664764b76a810d4d1b17afde92e77c0b93c802d4823643fb92978ef23a81199b9a6cd4966d94d5aae3270c3fafd858f61074bd14b6605a999fa5de94b1f7e225d7416158bd32e55c7c46ae229c57ad4c1d55e7bf1977c47a73c1e0599845fa9cb76be6d17329ae9b1e43ad849a9e8029ccc4cbddad507aa11ae8d96c5b4c40a78aaff31630fd444e6e8123f3fefde6ddc8635f14c9ddb879fc3c567842eaf658cacbe3f36f9949ed3feb56a94b060cdcec8d737b434c341c444c437efaa34e488ce30cacac5afbbb0b7558372356d5555839d89b9d3a47ae3b9cb5979f0cc1ce9c97c389ed76b2b04c6a764a363e4f29989c0d82986889840f4fc716aaadf0863d339b89a3ce468c5a6d7bc55f15e87ea7e7a86a398dea776a129bd8539655a1d83810aac7ff0c589dfe85cadcc91ae06f78115c5e7275d4efe9264e98a40275b670dd110f54ff33ecdd62abf2dc8cc29d6c3616ba123156049f667755c8a58e93dfcc640eb1a59c6f49b3b4845bd1de81fb4627abdf2199373963e8f3d943772ea71c965b15c37fd5d9fcc72fdf5147c3a4263bfcb7490045951dff9ef0283d5caecc153cd9151beaa4893845dd433027fb3db2688a4fc6d9fa9776c988a664c3af8c5a081c991526da5b706ec1956ca68bf8a6366d762ca8ce936db518f7be105bf45ea56fd9afc293eabebcd8f1bd8d8fe2c365413dd425d7277638dcd06bafe9d9683e6ba5408a3cd358ce90c69a0959fd49e69e96bab584b4cdb8dc6c024d574e4d53c1d9bda0c6e0516d62834dc41dad864ccdc516c6d1c45c3091f5377464114f8fd67958c886c5bf1de7b2776a7832a330356b7bd936dcb23ba530b8c63f8583b8d51923cb409ddefec6457276d8131ae38e73d6d2fed842f9e7617ab46482fd35f088f8f75990465de2e0681f95453bab9c61d16b1c2d64ab37c9f788be976c6755d27c9be28ec44a5bea47b9a6df9abe394b8951d6a03569e130c6fefaba53a583f7e35781fd563905e86133cd116d85b965a81b1f55647985ec3f58023574f49003f67d1847c44a40d48a2d3d86a0e66505037b1a9898be7010d98c686d496c646babf8f998833620e287b7464f8005bf4acb8839d93a311e99ca4f889b123b81f6e740b604cb86464837be291d1f4a919b07dbcb9589a228286ea1ff56554a818439a3c8f1753b459dc557ed135149553d7d82b1d8c0fcdacc3043729d6ec9511c6a3f279783a2a8457817df77ac945450732d148f8964b83c16e7319ac67acb7fc903501d466fcfa22ee13a7010615bb7a2edad26fdec633397516ce0c36d2288ef1fcbe2e1b459348cc6ea669d8810740b2b7581a9e1f62825d80c903e57d40732abbdb7736e8a1a1ea9a20d217d55b5355aab672e61ae0d183e660c182b846161147aa1426e34269636406cf142cfdf43982a076be1ac956e114c316a7d6921674f6cab0fa0c49c91e01ca7ff76b61d06c13701892e208390edc717447a2b01c8a2d855c7487c37a0043644b26fb3a446774baeef30d1a09a3ea9680f52449df85262437b14afc2b4ea62504f443af0752b97620ba8145b396ced5366dbc9447c010740614360401be32903f2680817542b356a7a6ff830e944b2af872779f34911d9b99b0a98f3198198d73922f5567aba3b8a55b2341fbac3a2a3dcfb46256885331417f4eb8c209c235921a440e8695032247600c885a82acbe34af41653a33200ff59794fd98840f94745a607931c1a8a4450e67cb23a99b46a4368b6060b4dbbb5a394820a16bb139baa15af551b40a6b01232cb99801cdd4387f23ad6dec96edea64b64a76fbfc35587508733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddc0216d226bed9b723cf846aee457b0ec23c59107caaa49a3c879b761350ed319a828507bc687561a87841e56f37f4b4f6f77e253988f38488ff2a1e9b07257268a209f9b31705bef791236ce9c193f2980ad38c5b9939189a618598ce90f435221214259c6555c7041e2a9a12bcad5b86cc04842d992834425a10a3411f5609af68a525290320cc1cb607974c6d19b662122245991efa06cc6f075e84f2b025018f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa09859898462f05bea461adb40faacdfdde363c06f58bc756f0a8417df63a66d3a544d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = dacd0804d8149dbd55daa5fb79bef7882172b99e1c7cc54be52017ce6dc3fb63582346fedec4d03341a5c26eae631ff62048ed50727c78bb5e1c3198d7397629d2d9bfe9c29d8c22661478b011f69d0aad3d0fe11535c1efe9c787fa88cc530cde42e6b69d4a767f753981e3dc150877851ebab89558d2cda3a9593da09b763cb196b3a1d6b0e94678af167ec61555e30877e31c70e4646238a518d8f590c89a10826e592bad0c1380fb795d44536ac1c0b42e9dbfb52726846b01c3e2e2d55b52f7a6ed8934f6841426d24c6629944749814a032eb3d9c2558cdf0eb990c1837959986a02feeee7f23c611fdcab8c0c422f4ae42c54a21ae3a1d36d25fa911bd48620f6e0d6609324faed384a866ef92eff8de2f672fb0af5ffaa3cdd2689c3eacdf9be6078822c66aef17a03b61b2cd9af1654250a199dd7920ea0eeced766745346ad8ead76164e46eed1df0074dff91054e79bfaefc3df98139ce4875d46b506003172fa69c7ab9d0bcea3452be59c56945323629fc0e6a34041b86a59a44460e5e175ed8fd34f9ee485937bad889ba5344aa9139536479650366380f1fcee5ca33902167bce90ad9bce466bda9c0a8dd04ebdf0dc67688853c2d4e5c6710e867d3eac14a62651be709053474264b65739f7fbc725dd2c9c94b8e7589ce515a741d8955b10f9d447d0cbe90fcbf67aef7d52488cef52f2422968a8c550ff4e85e552e3ee3c8c7467eca1a0b6494ed3b8bd0bc1faa5b8fcbb055c8986912976410d4c0b9e4a81116480207d5f550bbd78cd50e729f4c34a367cf88a5f892770f9d12633cb0faaa484ba2bb50a8f5e0bf99bf26c25b64a3165da9bd53da6cd616fd8209d0f87d80233b2480c1ec13ec8814c0779a4fafad00274ae3b51d058ed077aa3852c0f2b86709314f195c7d35f20eb7c3891199762af63473e40efdfa9012585fd6f19158022e60e5151ca5f091c7d5a28a28aaad00cd15ce6555e16b9ac455e15ce701c2750ead3f933e03317948a2782e44df993802f5da804e96ce48359ca590976765bdbd7c9a3731dd33fd9abbf40b0e9fc494a895fc40bf069 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4a057f912deeabe7f70e3b51ebbde6e7c88b931bab7839776aacc82fc99530e8544a67cf488cd02dff89c58cde2a58e1baabe68b2db5f89fd8e4c6e5dd9354ea67c919673b6e5560421776013749c40e6974d6d44d3b92f585856437b2f7b6627db363261adf6138445befef527592d0facd7d4dbced7dc75d7fcad99eb66ff533ac4dc198a8e6b4c64177b397bef5fa4a8ca07cd649981e5d339cbaeebb53a2fcc42f95ea6c88766c54b0c6744e41e3c1e0c6b3547ba8911f96410ce1af94ac12d6f3f44490977f42f9845c4f46dbea0c3aeba99ff0984c8c2872cf5ddf8f9f4c7784ed8a96ebd2bab8acc4bce2a34324346aed98353e14b52e27890b984102943a7378b641b6c6425441a57c9f1d594cea45ef3dbffb74fcd9f487e4f7b8b41c186ed6548c5b24e335b5d3701459b41de7f374e80bb4635a83cf0dcfb48293c0e225f3934ec656664082e97402478d1fe39a9194b8b585c3ff0f4abae8a60e07deb89336e17fe4621ac2b7aee4d9fda03e2993725f41e2e7b45b95fd0bbefc84e941138be7a6379b30f3eb64d64dabb6935b758aae7dee0fa9803323e97a2d72cea89fc58e9b54f950170fa0c46bb31f9a5165e5bcbc4453b72ad4af9573142c3ed98c3f88e83b0dd4c2f447d915b7ee3cc5c29f5ec9cc1cb38388b9823ef7ac59aacd6af159f34f104dacc18efe106c87cef441dec6d89d3e96dce4b6b81a559c0bbf7f4d97215795549b52857868c907a08497ad014fbd128460d1c88d79bf9fc76ba35ccb7748c6cc85eac37bcd5a63e76ce24a81d9888d42c83796a9890c09a604ca6e5ba596a3575276474a642f4e0234d48a1ebd501c60bb3487168eca0923bec289d741cf6d3babb74063b9f668ae038cda656467eed87b6f7ae8158c4e9c753cc6a570044af78243e21786e98006be0f28c5744b98f3e33483387b56b6ae149ef2dfb46d102de4acf383fac6d023e6e9a9ea7a3355536bebcc377dc742d5fcca4efbe9ee82de09aae8b4bad265c8cbfc6715664dd8c67062ebe0088b6d3905a5fafc415a0337d878cf4ffbf9fb3d7761d981dc5ffb3e5b80ee9accdd08cb516c78a4619895f576bc8b3367f99d50aa502f365a5ab881d18044150539084a918d43a002665f4dd155c6bb9363127412dc05df9c9c2df480937507210c8a1a419c9cbc840e54a0734c8a281bc5fa709a2312798c998b9cec0ea947c0e9fc128a51700a21be8841395a2552ffa4645dc67212117131db3b54989bbbd5569ac4cc7e43b4b6a012ed87757f46a8382ccf1c561868ca741e51a554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759ac091519aafa6a4367e19b376011adfd48d34521e47b10bf497714f6464388121f46a444ca791ab9b84741518ad082153b2944d61a9ab8689410a7424b653443a9089ab110dd83d91f07adad9ccb6bc05f4a34133248524f5347f2473ab0c18b2fb3da280a8364464cbcb1c62dc7505b6c2cd057de444ba218ba49eca1142281e971bbdf531cabe6b7cc6892ab7b304c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627bb09f7dc6609b18a3c92badfba6560574bfe70b4b3578f1778785754146aac9e2a890d368b7144e7b95e4516adbc2eccc82e81627935bc455d9397ff14828a8c0a84f5a876990d909c481cf0668f9787b9f87b7604b392443d4d16a0f201057d578cb7411532528c190523a06120dee1a291e55d0fe860821b9647d289158163b19748a1477fa31b3e7c048cb93287a3d7760caa0a0bc5c880d6723ae61f4fba744808aae2e3742016c81d371638b883447a1e3db611f241255bfaa48811397989382369ce7a59a3a17c559fa29ca4b7a6751526c1db169dcb7fe00a146f6033cb44207836c405a4aa1c1274c9206537c1b767c9948c533e836a2bc7373c10c7b149ec2cad5bb515186ed9865968801dfab0123e3ac729681754265e8c9a3e9745cb9a770b2aecb473631184832b086a7a2217ab2d553d54aa431567a52f25078c10ac6f206e1e198df76cc6f8828b337685fe84abc3151bc6817a98c5beb0db1b2a4a28a7580747b6330da24561c7ce37d8750952945ce7731983b62a1025f322b515e47442b05a01955b4ad8aa63856345151c8142718e7412ba20aad10624ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24a24e6203d9b1aa5cd06c44f048da7225e33952617f12b4289494b3969857c2ff8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 788ec4bb0436a01973f78f3dc40c682ecdb3aedf218663d3574e8bb16c15a8c80591f02dbc1ac351aedade075e310171390e991c4e53acadb3a88e2e0a1ef969197ccef2f7587c2710f48e60762bf8919f7047205a722c0313083d4fc2fde591b4326cc171c05f0050eb9fdbbaa2cf2d4c39d50dc20cb3ecd9062ccfa4b815da7c210371d8fbdd63c2d8054f4da1c8fd991e0ff0fcc55a3c84588ab7b4c4d43c6d00251d401783ccdb1735a0bad3d7d704698e3106da83148ca193a37d0661175a972d43076e085f14e0f59e43d808a99d405fd3d5058f679cebb6fc9a9046ca0d781cbbac8a21a80f4faa82c5f10c809958a6d5125f023b2eed70c337117ebf4a57e98e1e23aa33d302e07fb5a583457e3c02418079e12b9857a91814bf36c5cb5db7aa4ad1852f320868b273a3086fcc2356ac75c8c0f523985c6222c6916b4fb5bd5c550bc89011fed14ce52843a3d18c1c635bba2e22cd57fd70b51642621af48d4e9d83fcafd8530a614ec7c41412eaa2d8b96122194b134dec845b8aa2d0dc54637dffc528285ae31cd2d942510dbcd9079dac55fb5ceebccd795049585ace5b35ba34859f1fcc7335522d3fb3f85075cb7e9d83ed7acd82be9c899266a11ebce385f92bdacfa90214bbf84b20349230a6328f07b711c8d3a9b5ac946d046d3ec485cf57fd96911cc9a4708cf706aa8014f05a3adaa5cd0c6a7fefee494df5b7bde7d40d22470c078bce8f56ac7f1b2bc4bda00365c288a2d8eab84cc35f22efac50076484a57f9e2120ce7550d8c29db5338aa0b823f503dc34fd08e0b19c6bcd655acfb5b3724deaec23bcd7b89155982b0a62f88935e2bcdd47a2289f573b87a7f20c5f12043870344b028fd7197f67f6c403576dba74e482028440ea6f4ca78d81aac3ba453432170f21b2bd2026b837251e828a19a1ce1b4b301245d373336c89194730f5485e954bbc4f4540abf5521d9bedfe928714b6c8f3048ccec8a8b66e6311a46af387ce4da65df7120ba680bcdc6308cda175feb18d4d563a7b8a44d0712fcbd4beb1403c036cd7ccc0d2db0363cf885bf5e585a9ba2e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7abb8c9e2f75c12685be83c9577d454d46c2da45a5ca2c80d033665dd6844ec49465993f8f48513cca870a2b8b80e83c8ab7e2ad2fcd63fd912456c69a5da50568ca9c2bf57b86ea0a55f681c484b06db78f85d2db49eab52ad09936fae2d65a161ba0111991b5fae5e355cdf0eb5c84c49319169baeff9afe25f1582ff99935c2f537d7a7dbcf5656568c573e3dd9f7593bca25cec7344cf68248f43018320929c469ba99a733550013fc33ea33a337abeddc3999ce9b27f92f6249e48a8cdef04e9b44d5b2930d64ebe56f62a3e9945ae1a16868b11887cfbeef1d55cf8a8e738d38ebb0fe877cef89b55f7eb8b7e609bdb2934dee4a27ddbbc739142d3f00573711746f2f1fee70499d25559b8b0d9af09fa661794381a4abdbee6ba2eb8db69b67b6afcc068e42b3b9b1437fbffb7cf2c44dd8a0d3b4d5a8e255ef8491e8e364bf4d3aba3b081b9bb7d5522ceb6b77c9403acc6d10ebd63a68a9d5afd0c1d6752c46f49339ba67f74f79434e75f4858b756387a9b07403f279c958490bc2e6dbe0b46e5059f5dc143bb5d8e3c374e44051c646083c9dafeec8625cca212f511c1b490a593ab8436f76d3edfc8f70721bf1f46dcd8d4d5a1185927f3afbe09cb81a2a41b4389291a56d7cd9dc30699b3cfe31da3636e90cdcd4e582b7ae4653d838cb2370e594d2a86b65c58c9c70a3ba0bebba2eae79856c92c83db4e2ecbee0169408f781b7388b15a6480a45e4c0ba5cc2cf545f6547d06588305561b71a51413ea5132654fa8dbfe9e85d604e5423ef815de7c0792f9741fef2b876380c4a80ae73e2485cfdf3cd612ef55f44c9723fbad6259c94957d67e54cc3c475ed85bb316ff59c462a678185e7004437aede83381bcdc554aa831ee87439d1da54f679284e069dc4df46dd45f4f8a0a47d397c38b45791fe63b009dfb7831beeae34d0527f311736745f935a43f53ecac441121dcb7c335d99bfcd766e58bb35c14514c295139c5d46aec9dc377dbdce802d40b095fa750bf52ebedb6b3afa152b71dc7cac19cf6b2f3d8202b44d43fe7e636ecba336f530ed6c0735b647cbf857178f4476049b9483f4357ac027b219226fd5a9c2b9da1f45c9036d55411bb3c8f941b75a844baa7388ddb811abb4cb13d003aee4aeab466a592b77041bae4733b5f1cb6ce2765778b02455c5536a02a2dfa640248c6442398f48a5b8ac7b6e2630b2c1e872a3e752da777eb4607875e0c771f81ccd633961a5c9d5987dde31439dc131f536b083709f7f072dd75533f9c984f08c7fc952878f2b9720da006c3b60f5298ed3921205604fc6cb969aaa69c3f3a230b3865a84a555925c895c58fd19c3b98b7b2d2acb941a44b7e519c7d22aefcab1def18429713772285de2ca225b5489466322538bce1ed99e9dab3443e47a5ce5a9b284008865a4177666345237cb7b796b9582da027d7af4ad28f558e4d7426caa80c3a19400e286799caff5b4bfea5cc04631bf72684983ec67943bc955582575f399fa5c4bf125b65bfb3f2603458c2a1b23925193f6b322a30bf8a566c43032e722961a09386aa2459c249415cc675e27722fe83d53785e2d817391485c7a14c402879a84741b03a87818295dfce827926b34cf045385f26ea08923b7462c5fcb7348bc4a2c207c5d28ce8d71b77d998fda190c41db9ea45351e35c5a4ab51d42702856e8cb07839b89a22c851654ae0cabb3ca66fd0007942789b43061382079bf9b32d3c07d1d903089a78c542113cf086e7d1319fd37b282974db3c41b08e1899fca1ab7f6358ad204a0b937a9d91266da6ed5552baa2535c2ec0efaa9a606dbcc8ce013c1123aceb73809761b0b7523f8981416f819d0803453b58c2bd294ab55b3abd7873371831845a8f4449b798ca3d18a5a4f183b4b16c870f21d36f00d6552907c11c76c547b10c27913d9a39e6340b8d4775a919868689c19e6cc7659c5263529e3f840c0182db1698fb43663e4545b9695889924b5d27a41d014cf8150bb46a59ed6c3890e087b2cb043de68cc98288a1f2bbeebd4ad7bd0880f86cb7093407f393c6af5579adac1f5a35bf08c07a12810b8d28298383ae6a298398b022ad50be3408ca5d11adc6510d1e561eae2b62fe5968e2c826c99a7d9bcad1092a559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcacb2e9159ab5225a75d02268af2dac89a0afb33fe83a45f552e2bf542868c0683c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = b82636cef6a36673297a865d6378f217a3f674ec6ec49db5876a9152c39a09fbee8af20997b04b9613fda009ca49fd502361885f1042ce04ca01327401889f171b5ed396f5f9dd4e09c0ff03d8d4b4b53b1beb1ceb77f16548e21d7d0bb819578fdd9013d902f86ffcc95b3953e272582ea79ac71344417847d7f73389199118534c9965003c48e5a1068e620e50e204b71ef15c76d5b4d23a7accf642fbbb9a501b2e1e6322a4b9e7d0e59c4e866680745b92d930e4f881ec5aa56546951139c69fa11fb37bad4bd545461ace438ddca88b12df72b48430e116bc5c94de41dcb9d7e22902d1677cb02af69ac7e84d1486e4ef00fb9bb9fbc6a0eef3f538996fd0009e68cd74ae8ae461a222edfcbba2f57f3edc49ae381282eba30ae5ada18d44263064f2abdf6bbe9c4a455b48ea433b94a262609a2bf7c565120647c2b75a593a77bf558d0aa4a772a9b29691f4eb91485815463dd403950150727de1887e2db2ae1e842bef00865dccd68345e1b42dd6a8ade97a2e37c4552277efd99248231c2a5bfc9778cc86863614c2da8b742f4cca2870e354b7eb287090514890a9201b198b7a9f81c3cb90055fecea93b61e8d3fdbcd3029e750561405cd99630d4d7f609cb2c9c28d3caaf88536ad8e70c931bc0a98591c1430acfdd604564dcafe564d4323592d4678fb6abbd435b7bfbdbc6db413f5fe6fb5c8cc0ff7d05bbf79b940de596d493787ac99380fe94b3ec5c00cca2f9d75007d5500e3c6d158e4fdb0a8b5563547b2981cc4ddb001b58414df92df3970922f8c2498315615d67c9d7485654766cb86399a026752326ca77ed639db1dbbe86dc5ebb85b42b17f9073be257c92e60223e20cee2a329d1534502ac435452e70c8be71a90c0a154c4e61d610297b38a5820da37d4a5ebb54eedd0ff7ce4f02f98aa8acb58d2570f8f846b975edcc1c1f8f97a063f27c3384a1b581b57b28811bd2156f0b2a96080aa345e99af2d8815db7f3ad01fa1dc969cc60a358febf6d590bd3a9a83bea0c345ad8dd1e1c7b89b53efea31847e1b94afd65d261eaac1249d05c024509d561e2ef +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c5f7eba70a7fbe9d46d9657d4b7d4a9bfc795c663cfd48c95f398aadfebff4b47bd3fd5da81a44f4e9d0d8c8dba99ae049a83a488de2679fd7ee088e2e46c384c3623b3deb652ceaa9a97fe36f8b0dcfea94e4ae845e4f97e43b2347daeb0444f1b8d6ed4948709689706f9a115cc1bc34a1943347fa4b4237978c51df3e57e9bac04a99658d404234c398d8c9d20592797d6e72244df24cf0111b5f0a94aff729663056d25c5fccc688e3807b74db53521d64cc88ac6bf08b659a5cf3fad33485c7511d7bfae6497b7766a1ec455b217c9818ea85bcdee7a385bbab3797664557ab9675c2858b8ffc46ace6a6a35c70006ca0672f6be1d5521fc5531a6f71bce8d231378016e49cc2d9da90c531ad0fb39e5be754136be05bb653f3a7b17cb9d0a950b3cd4f75f46c4a35ac2d2d31d813ae2476e49a657a5bee89bf8b898dc7ec5167e9941d6daf6aa0975dde79fef9fde3a39c3a4a28d37650078b80b5d5f656aeeabfc04ca4ffee7542176acb9f63ffeec5a047c8ce2b18832f35f394d738463d5fe0ea9498da4517d93ecc63836f976b0989e81e0c4a821a9bba5a62fb27c801eaedbafcc7d3cb5db4e852360dbe1328e84df976f5c842d5a5da9f36d15cc6db6d9368554a9c6737b47b44b73678efef583af0cfd83fd98691ec43447d4bf5bb4aed9cef99f4e558cc72d549c493463037b99fbf8b431243e36bf5e66b05f3a7064bad4ff5ad89d998f79bb61dc42f17f6ea6ed3656b4503fc8af37acfd57ebd2324f47966cd20d95383c8f14e2afb5aac7e830e312a53c6630ae73167afade668f61779f9e8f742e9aaa3df5a6c5cedda295f45f33beac4650205d4b99c6474ad904bc7a3fc5edf122fa16d073f2535b9927f9bd39e59865b592194bb3855ab2899c7cd2a477c0ac24ce6642004b34ecf6174eeeb4eda8ea0b6dfce857a9f7875b2fd574535a605b534426dc813fad68fdccbd2839441e8da16acb5734cf625739db723a71ffda8138761b81a7cbbeb679d34d6f50557946ae2e099466ce4619067a61a0ce23978aed71df5b2bb855159a774984f02f9f875846bc60b5b88b88ddb2517569570e3b33d93928c62ab5680c31939a085255311d039144ffa338bc7633516c32144ab0a85869d0809b7ac8d4e4b6e6df00cdf36600e4308f395c1a9821a47126623827c489ab73a68104caa3f75558e596811417c966fb38ea85b703fd13004db91e1eace232664c06a8e85a35346b56a83e89aeea01cf009a02223312397185d9c801aa5672d61a56ff22b34016b7b2b1c20b7b739ca5319206b1ac42fd991c2fd959f63471431035830e122dce7cbe1c416e5a69d5a766d7959b5817177e6b29b450a7ce080969a3603b738b23916265852c837104499c8658e8cab078bbbea91b4a9e2a5394aacd8f2bf0f94107509c69bcc9b7094512f6a4fe9411b3cd77200f63087e4b205f40d9d08a6d093208bc2311a299e7c722c55f50bf01a75bff5bcf95780a4496e00431e6978a6396c1232ac08f6db5a2ee3b5cba66c67b0c431b165fe83a62e0801a3e65f8ae30b0f2477892133bf9a1d03d4a68b96b726392908da8c554b32a5c59a839661e77c6fcbe9bfad441be0bb9767a2368d216d1e136ad5b334f775c296c1bd69930dec23a72dc30ea45636bcd242d5f38b91aa23fed98d7aea5d2d173d33c034311807c480981c141821a962c92951fdd77906817f63000b966311f584b31bbc4ac3469cca648beae1b4582697acf62a832a455f169e07860eaa4856240a1e48814cc7393a2c7552b29911915250ea677a7fe3561229421bdc31c56ab2cdf41fb16040b7f83e198a581fea0753ab8d388b677e693fea102fc5e99fefa215c178ac1a178e64c4227743a98f428b80f91bd1acccf8e4c80df483c5997438748155538edfe6445c7026f7cc1fbb8016260a0d86e19338d7255d84817929a026ac9c96bb215f125997e311f0807224d12322156bb4e320404bb6ed190bb4a1871ec9b274088b0d584a9d405f0ac08114391622f893d6cb8f9a11a9e19c803c4365656129514a49de618aca46b47317785be7493218a5d6f879f121bd1a852110c5145ef7585a0179fa1c1aca7c4b42109efef4886454807bf40a06064b88b740d0fcab975b5d3df74ac7bc20f4f8265f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c597f8d36076b3a8aa13b633650726f7e907806a0573402ef3af129f611def1a813e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 0abfc41da2386424c0c4b6586a07f59f2c7d9ab3ec74d2de590a3ed71309afc09f7c559cd66b91a5ed6a433c631a7317c0fa6d86574266de0d2be9c7a3b5bb01899a1c7b2e5273c6087b3f0dc15cac701d839723bed0146321729e3e770359dd8366bf5c9ca0f31ed5870c44fcdb026a2088ea9ba4ae8746f339074ccbd32780b7b7c8ca777cd161b289822199aa83a6b3357a134821b283a34b714e065b298e8e636361ca3c151e799b733e7da84c1bee4344a23377c14d223ae859d98d8fa8289115c6f08929ecaed4c4433c5ab60fb7b52cabcffcb233cf37b9918f9f0e6286d2dcf266e8cf3342593de1231b2fe16cf189c00af0016191b8e9e1de850491816896c0b8845001088b3cebdacd5cb6a5b16fea748ccdd4dd39037828dcfd4d8b4e3727d452dd2c4f073fb4b61b780be277b79c439c5aee214305df980416f95c00697c1d5280dd142b8acf5c656c3bc4e2d3d180aef6fa133769e781553e32b6c36105caebcac9607818513d452c1850b862ab04452871d75e7e804aa14e555a5e18150109ff038ae73cdd10fab0eccc18670fe55318d10c514290b90e58125b6d07d9cccecc2f68b488637c2e26b795ead932972f7f7bbf2a377174beb7fa06c62b705b2622486eb7cb13e8b7f02b67db3a9748af941629106ffdfe38d89cf2e6db22bba2e6c77d3ebf639f6f2180e84f122de7d493789f7d55b46a8d75e0a33a7ea09552aaf53f82774e1fc4c9b058c84c8f344d5406c1a2ff8e31b730b88e6865deaff9279ebf60cda70e8a6a3d80077dc12bb6bc4c9ceae07b3f4c5abc3fcd67b3ce815d2e256731590d75821cacf4880506009ce73cbb407585a61d9e3bcf68c46ee96801b696732b76328657194baa4a043e14a7f2296d3d7530124fb2b3229443ccc019a33ec98c80c62f33156e04c2b9f52ffd092f6c8799fcdcd5e1c2c5d5a5fbae6fceff3f883469279296657233b8f173e15db42b0bfbfd1a843670a46467338c84c10456a9698f50618d02a1582f297158dbcbd20173fbd0d5d07b5e4b81712f3d7d1346cc5c42061bc9c1fdbd00746c662635c983f70c55df +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4dda3333b34f27f44bfa8e3dc1db6cf455e4b2eba571c3f0902fd9bf2740d3177d9bd4dcfd48ebc045a6e47e70745ff71cf861e5f8948e2543ce5c72c377b80c96616a677b2fce43f035a5200e88a5a44f0d5798b3d9ae1e4b381e038dbd854eebb768b6dbe303d88297576575a5814cdb58f91ac9b9ec53a0dfe2ad3ac1091d8eef16eafe15b4b86ed57faccccfd3f91e1dfff4ea758e9c478143696798ed3969ccacee3789d65928ea3ca697a3e0e4499d0e68f9599ae8447ee9afd94cb376d00897954e634dd9475bbc3aad9a54ef37a576e551465e96e637e07aaba907eb57ed2a38a5db61881b99c5e3bd0ed9f05ae363a40473f2e83fadefbf613b3e87da3187afc6067ebc36dc4d1be99e8d4fba13745f180833890d42bea83915733038bbf50fcc32dfcdc7b63ebd682da94e3c9dd784984f49cd1ace4e74849f3c157b207d8160e4365b8e6936fc66578f796406ab1f2e3ddb2e30bf8fcdb83569d6739fc84d5090193a63dbdf31c3a7660da9f1d3e663643dd65d50ef1b7163768dbc35cc4de9adf11d94bbc44556f681cd83bd1b44c02b9d32393fb8f6d3cb707d6b16373ee00762089b85bcca99407d3b1f4833a45497de593794c7d0c24cada428c9a836f7b5f5663f08a440a473d64efece37491437674acec71e1b8a183e54337d7d6ebdc45619f1989c95d414c9ac3af8e40ff7bcc6d8fd69ccdc5a58739eb132e4597184871b8885b237d0c2fe780ccc5c27469ee9e8e1ce2ad880573b7fd392b19374e74ab457d8b1ddf568096fd67f0f83856df09ce87e90ee4b4c068c51f5f6f7f3ecfdd7b10a74fc37536926ea6465dd548876610ad3ab54e6a6cdc6dd8f57f7b3947f03bc8a06897ae9adef686b7b7f96a1319cfae42bb73c393053343e18f7ccdb6dbf305f75c7259b8a6a77b9c9989fac317e9f30cce67f14d5e21f9ea61ea3d6df5d6989e96d3be6aa5a7c6199aefba89457ba8df3872358a8cfebf2198cca4653ff1f51892e8236454dc0174dbba7a462657c575d7cc10df409a6477e0ba6592bcd49cf6c414c776ddef6a346529ca972c4ff727566e2c13be85900914fc65434ab614df28f12e7206f50784d52417763b09de06a433b1665ca88c8e303129901536b1c99d284f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb0108323f8224d5b6936a2a0ecfc0874d6139a9c300d2505a2d10d926b05cbe404e5e764a1b353bd5c34d86a1ee2230387857f97d0ca13382f2ffc8ffb23933803c52af449c29042c4ccc7d06a2c3272786be7cd4642588d90ba7599024428c055c2ad6232c02a83a27fa7150c1c503dc421410ac376056933d3305f76bdd399851e8952c110693b99ba35dc3a337b9bf6cbc370c6a69f593add08149d88606931b363a470b2e16b3f688ab1f1478b2b9255942b86718082a2663f7939e893a5dce006da504f38e98c4ccc36432a491ce18217932dee5070ea27779697274457bb6930b4cb34297eb39c01923cae32835aa7803722908e9b3c6b488a7f46676b1c4b4218720423a809116a41e59577c8c89afa582a8a8b2bda1009bc8b48e58d08a1b418f954460b8ebde004870bd0b7e082d3c7af5ddb4980c2acb9510a12352312991368295adc166bdf522ad76a59ffc974e4cb04ff8034896bc40a8ca508300e411732d8e729b78006d69482e1704ee70c4e8576c003964f6ce60bf7d5a2029c03a8b778b65556a70c617790c2541a9a8f37b23096401b984c99e7459dc38436d210e7186bc7f070ce1574a8c17298a82557612c19940cc1056b92b2b13a8a2f93e83d635190ac1c5e093891aa3cc6d9a98c5b30793fab0aec423b09ba6dbff15d5e8522f86aa877000ddf9752f17b082768929ad7ae1122c2da818db93c52a1d921c7ba26fb857d3ef1c11d925635f050b4a89a59262438a7a7eaf30fd5bacaf319ce957b42ba7a1de408346e393d231ccd545081ed338250661a65eb45d5c05c5ee73c99538a7bd4c65442a14759188037670746906b35484fd01b89526dbc94123975087402b558d3c611040c65a9a2cc4c38f4a871b1a764a170b85b5c12cca551e6e466c8889798fa0359149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a72241af2b01254922a708038e5c5658e2ba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0ff2044ee6a3bfd4f7033dc4bbd6283b534cd3fbbf1c4af072fea1ba37d3262d581c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = 19f22971bd65f0cebd5616ebeb36e3fd46e48411ce02feca526f85ac9f66bf1bef78727c27c5a9ebf272d4662263bab49ff27c1b80ca16166e35b3dc923bb3602002001bfe5d77e2150cd320c3ff1c266d2422b781446d626c252da9568ce0861ff8ba507ec0aea2a9eadb200312604e6627b2523f87d907c8e8d3a104da98b3b2d5761da9bbb0c31d8de239f0cf5c803c90f6eb487fd0751d5a364c51005873724a0e85c0938126378b256ce616a3ddc367bd4800d68a114dad7786a4b1357489e20f0510675f229a6136ec16b52646d9d29c91909c721ee41a58ca53a9e222f8d3807e24908d0b93b50732332506ce9d3bef5a0bc2eb640ec5073d6c0c090f83afdede0bb64421cdee403869c5c9a0a6a5332fc3e235d2ed0901a2b2e25b9c14e3beafda2fcacf6975d7696d8d77be066999092570e6571fa85615732e578a1dc194d286f6aa40d92172ccfdd27eedd88f7ca49cb4b47caf1b387ce71754e1aba4ec433c7e8a89b890dbefed95203d111a4d6670081726ba23bd83ae8a8f3293317b14676bf3b02332d7d702048d12654a44981fed2e8ff72582114e646fc17b4a25b078c7e5f1b43b377a2a01750281f1ab737488e2b7fe9591ee4e87331fd0f5075ee1e69f4e89f556e0d567bead916128bfb44013263e941bc0cd388db2003cdb07f686279da84cfe73bfc76e94097295f6e2560fa26529f196efac71774f7a7f061f4a36d28c6dbd7651d2bf1d088b40e5afb1a0f1fe18bb66a861592041d14b87cb2a07c63cfd8d2dad7ca3a6cb8a392f1fb964fe0ab7271c2c56aee3daadaa67410fd15e80a2c59c3b93dd911a849f8d1fc6dc541bc8fc9e5b469856850fcda9c5c8841f30b73af5c2d29f11302aa36f990935a66aea62a5f701eadb27f46c9960155b258324dd71b2e1c786768b56ad2c6501a3e5940b859972590f893abb0355cb629969b23d9cdb7e5d6233a523bf327d58bd4132ee81fa245cf3b87b65445f32e07e3fd0184e909289e694ff19ea46d49f2d939db5e01e5f32cc69d5f749415af8087133aca54d5a95ec148716a577db1d4984fe34375d9c4fd7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 52eff07e8cf9be9d868d0dccf1cc9179e99895e9d67467ecced7860a6fcb556d69fa03fafbd778e7f95baaf5a92dd8ab584fedff0bab9764fec5d4d8aca59c3198fb1603e49f6dbbad6c5c67c75b3ef6fc231df094ae6bff3da06a4d46a319a08877f25b3766a91f31ca95bb1adb6086e57b3ce5a47979b8cbf690dd89f96f1c4b77c98268c68dcfaab8ba45d9c8dec419b56187c447b65866e0b7e06e33cc3f3a36c848ebaaf343c1d9d85f7c89363ea56d47403fa447a34b4eac49eb2d3ae5c8fd51720aae6d4a66231e59cb5bdf335d8ff5b8a1af4cd8622a7a79a6f2c45e64f0a8c0a6b37e869a60eb454cc6ebd72387d64c0ba2ba48315cc76d884aa9d7c6e65d0b94608fbcc09c65d6b85315935d98954916fef7d726aafc7c7c9dc8fcb16a7580a6aca55db61adfa98315f407ab554c3acc055ec5d018d98d53a7e07677fdb65a3fbeb51d74a4f863507b05e4e568f3dd09f8d66fe8f449dc3a77fa38ae385cd43655df8bead7bd93a764ca9e98cba4d079f4d031a36029ec42a6863c66836bbf15a29ec5b7b2ded32f9dbb5114b2b91a4e50a7a193f8dd05cba17d6bd4a6e8fb0c2e86f55dfed49c322356c43bfe62897bd4d846a64a77e8f2ab8dfcdb516d354bebc75ef403b04ace829bf7643dd6fac426ce1356f20df94f5795684f8ebbb8854ccb19b6054f53b9ba7dddebe123c83ff575b2f679d2bbaf87b54b9daa8a4918bf48ec139653ca970bd936b5aa51e80e63825ccbee184d30dff07825307069ec75e67652cef86d755233f7e5e4b85f104d67b4b43360e37cd76ac14fdfd3b2a853eeb8ff9baa3e12d5f463a78e4f69f93279bd1b1c5e360ef85d53bba01bde8acccc374bf465c9ca2b039586f4b43e47acaaa9eb6ddf6b998aad77f54a6a5fb67c7a318fa9b6b3499ca95e7a635a7e88a75a112bdd798fde98654dda4dfede58621aa97b941a52b395b91537a8ba246b342680b599db20aeef9e3b360e1f41677fd3dca693d6eaad08b782db6f83785fdd019eaf805df7bb4b920e345e9fc5c2683f580fe63a745ba6461ab3770e3a4855a0894d4c9a8d38dc4ad93629b44f771560c15223c88cf70005d91365e13c0040a79377468104752a66c4aa268aaeca53817a449353d27c75387d2a14242331bb16ecb8e7810d76801bdd3122ef9c6407439e5de3cba26a91e6c314a9fc543ac7cb37fac5f4d24ada0067cf3c97bb195834b635c9b099992c3657d55573160e26874fcab1a8febba997e22843ab7a7adc3106897e2e9215351014b2dba6f68074770b5afcf4b5bc9abd72c97c03e703ef473ef58bc8ca8a6ff0fca028590e2a44a85013415b5c03f3a301ac06bf3d95691664c9d0c76d60015b0398aa44f778473c09746b50d770331c011aa51b1379530daf2ca17fc5bcaf06c59e792f0b117fa2755e1f371edbd17b584ab5b5a7c0c7ac0dd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b063160ec596b9fab9953124eeea8484ab8441a0b2a85b481858a2817e04c9e821a703bc9e55c28643a04e4b431acd7c9e54368e7e361b1f23041439f0d24760827971cd52328793e029b634e792c96fc437d396eb61a08422279e853bc2501bd6cdbccf16958bf4bc133438280e8b28f494a83f61f365646b22cb238eaa2554250aa27202743bfe6f4a26fb2234aa80bd7142caf7646a5874bbfb0900f7016ca225a7f016bc015c9401a87ff339def0bcc7e95197ff4be1728ce9fc4986b58bf933b2d2ac703ac0823ae701e3b5717f74583c5aa5156b744abe535a9dc1cd42873a44c3acc9080aee873fa975fe78547bad901c929c008bb6e9ba24af9d285e7c139a54c72ad525e92384d7d650fcc40686404a8c931410e3c92daf8ab090b5fe48c2435ec7a8f21295c2473eae893c6c46b5e35868a91c962d15b4565461f067ae0036cad3bcfb3b23182fca257e7516fa25e00056144768311144fbf526e43b0a9ef797eb07346d78165e71a8c426abf868a5c251caad2c4a038529211c6a3937098a48b7dfa9322d30723c460cf2eecb0c4b752cf310323caa7ef39779c7754574c6a06a2b9a0a45e35d3732d490541fa7ed66ac5d5b007fc1390b1591a0f19a4dd9c8fb0d91275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568c7ca6ebbe17f30f8ce49e15c40c1ea5456f43624148eaecc9f3018f7beb96bdfc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = eb778fc164763c5452bca98dc843c9b1455df5ba7de8e61394be3074ddba1bcc9c2884c1035c20eae1e7b346211defd9500f915f976a41e74e5848ea63295aa96cc9efc973f2c02a399ed0111938128986a449459d9789c5f3660dd530199cadefd7bfec96acffc2597f12ff6888ae840a17dde142ea6b2f0be4fea618ccff524b7367e1d630d04b3b5af2213d1d76511d0949ad48c99bea1a93407dc0177e5325643ab6c762fbfd6c3b8f0f357626411fc61d399df4c3e7c4a501c17732ce4c5c459a411fe61133a85b8db2f791bdee6a34b9a5abe59691635fc8848017ffbcef77fff7663fdf409e09b716c1a76c30fdc8f95f02e19a4794a21b626ff31aa458cb581e3b700c0d7797cf86774f7e97ed9291399b4847e5b8aeba723a333bc81921fd34df7349edd3bac264badfb0f4342237aaf7783d59fe60669a90a8a2e12b33a2fe7cdea19d41f5939313151889aca63c79fd9aefc857c4034a7f943c0eeab62455c086da18ecddb2504480d421f031a324556be7d93e7d052f5e349b0ff41eec2465e9b02203e0286c6181e12d0d13b3814903ff0d90d44d727533cd4fb696a7c3ddf7bd40d390a9435df5cc710dc5a94ee9f885fa421b1141362391558f6719e1b80af98901f0eb483c6e3c9bca40bf7a0adaf1db8fb96b41c1902729aa1330d4bb17358f3489a6671dbef7e3e60845d214568db16297f1d32cf6472e5667a82fde84a0bf899459e295f7e1653cc1117d22e67ec8d2580b8373170938f38108d5926449f2cf6228f2f1148e42a3d33f7b66c5fcf954274685c5d029b8d19efff7a6f2e3c3ca707252a2df047584c5049de06db510aa0f25f6c40da77c1a43b74e426e5fc685ebc6a2931d34befa497baeefc5f0c2a2c5ee08894db083ded15f78c47db0b3a0d91adc543f33199e827fd0f42ebedf2e9e14d5a43b6a4d04bb818d116b17665297c5fa9e08fde9beba81280bcc8ce8b760e766634a4cd680f0bb179c1fb9b607ab12335ef50ab4259a1a03aca82f6dda87bc14c31d54caa2b6cbce3baff3857e40d2e4af24563b81fedb9a829900519bb8f21b136ce454 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 57eb9e1e877cbac8750e99f57973465fd9f52818ebced98496d43331eab13d7e848f76542f8731225efe5b47fc6b96e3c303a9389ac2e3eaa125bcb1e1c6b8484fa7c5245faf9cd1a2b8f6803a43b108fb568574abbd51fd1d67191a36eb7f4b992beeab28b08bbaa79bdf43ddaf4c837d655794b6354381ea57745c85846826eb312abd8e38d18ac6d07e9bba3c458ff1efb94b48bc04bc8dede533c8098b6aa5f04f28944fb55adae3d84b88d96df75a5ec447376fda920cf544e3a5c4a69727e84ffdc8b33b6385fb4f368d03efdcf57a570e565ff82f0f6a342fb3e0caddf2a6d3a6e3d870f5e5b6977579fdb4d5c495ba310f79ab2689712f680d9be6d196cea4ab53c32e947b5f7126f8f22feba4301ff1cb79dd5ed74058aeeacb25696afaf33a2e39941edcb54ba78c4c4ac3a38241ce9169c78bfb349624dd67613b94c283856fa4fb3687fc212ae9457b890e9dcef1586581853c9814de50fac9f89934a89e7defdf86fd84d8011381795532515742a9df902d2663b9f8f1b60fe044a385994588f8fdc3ea6c47280aec63b5d45e9ebfa8e9786d86acb6c3fc31c83ca0086978a3756f23bd5e5eeb9dea6a19a760c1daf4595ce890837b726d9933534dfc986b57dd5a05eebdc20ea125ec48742e36941766b1be3e4d48638de5fbb9098cb81ec3d257c560c8f9532581d153811e4bbfb59cc89bbd62b3ca6c1d27bb47a933c1f3ad5aa398bfcbd2bf8b3e83094da5c4332229a06aa6ed29ef98e6095a28cd78091f65f4df955eacc0459330c06de2fb157d6eac4d51fe7946d38611d8bbf7ac3dcfaa6ad1086f5b3d728ee53a087dfd1248576e2c6f8c14c562f8be9b84a3867793f80a36d6dc37c1d670f747c1b22db5e545d5bb5fc3d765b4f8a9a7346a417c466c9d9ed2e44bfd7be4e0ecf76f15fc458107d18aaca8f855ad992e3d51dd6141394fedd78fbc0a44cf84d3eee35caf1fe25cae5ffd656238d365fbce8c1c08ecb926d9c6a4ea20be96943be3362ac71d88ffb194bbfa7e5538abca8415a4e1dcc62109f59488dcef06ea315571fe054a50ff578bde67eb3e87be37c2c02582a708d02feb86759511c62580d99a5121ca60d7002246176ee5534c1261b86e831297a95ed8aa7732b58f0975c4445bb00db116ef36cee951006ac2709551872a84ac9b6a2b97b7a4e15011335777687749e7ca1319683840c017a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59da62cad366cf25351525536dc58cb622ab259cb3a6707d0abb088ac242338424baed40c182b15a9144dcce03456281ed2b9006915297fdb96e9c34efb551369ca9cb0012ce2c9af9cf90f2f616468abbb89b7acb5d18ee17a022a98b1fe2c2e8b4b1a2d4b3054d19162a243d4f0837e697f548164caf878366b26772351d28a025b227bd1c135922a43fefb55e3c37231fb188a37a6053a8a0ca88502d82a56f716313a5861f001c28678b23c7f66828dbc492fce22cf1d300bb3c576a1c01f13b962dd1b1c2364900f4a0db48a14cd103a7a5b535da93df79371c832b3e188bd0845ca95044002fa0c4bc92932e95180772ddb860b80063799b614fae43901d7cff686c8a5d05cc5589df1c7841d0312ad4261c8d81ed48b4ac513a88df3071d047d3380465f4a3a4fa894f6757be0f99e124150852cb56a483cee8c4f3f052c7489956f167e529a9c3dfc8256f764c78a4b58596e6cd0ba1c2c0e5aba3dcf5c46a533647195a682092dbdf61fc497a25e8b9c8770bcbca6c154629596f41c19879626392be7715a36570985ba46db7670d257566844a228db612fe32386590322b4a864a6c537452a9de020d2727dd1a0b066b0cb9d7144033765db050c0c363e926107f06b94fa70813c3c8dca862b98a4197be6b9f230a4931b659608ba32936da1904713c043718a8ae08419d0e34b26c6675b45451b392ac717a0e8f5245f035f65cb842ea68c7b2425b2550f12732402d852f5b7305975b588427d3de1b48c9783b19c7b1e486a47414a76449c26f3ab37f275f80413ab159765797d5cc653f2b4542f4027c199752530b6f7b49477ac60791706a4f7610138c8b3614950c06072ac49b6a25b464374a4d2c31483b34f83792db87d868a167aa08f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e161fb6cfc0f388e34fb28ed783c2733453005eea03d3fee4b01bb6364abc01c304f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = d8be709a35560530d75beb89fba0e856d8a76513ceef4b31f86f25a5b9486db6abc27703e7f6502b2dd79549034de3770a83b603f06fb08a818bf40b1da23d7b37ca011cd14df35a5efe7349787f39db24db56f0c2f38f0fc88c6af532a75c157126d8c3585dee3d9cf27d866216148fac12fa2297923ad63c80682e489e71f66e4969fd006b5e30300a7154553bf082a03e5a4ef6bf1d449ab53e75e953cd0acadd3bda97ea266307253917cede6649f2f6944ea8aac6dfc95d8dc4d7e2f4aec12db8845c10170ce01375ee6d6b094ed69461a68fc663355dbd2dedcb2f9bf74c458bff6529230b38644beffb017de9c2dd9b35a1f7ff9d053c1b00b00d7a29a143e7ab2fc4d78e0523d7f58046ea8977a4f91806a51e655c4f18e196ab30755aa5eee1d74bd5ba200cafe60c9f02a236f3ba016cda33e9f5a9361be028f3bec9bf3f560a009b26696533b119f64c0a58dfabee7a3ad2a0ea3595a338219686dd458f69528cc806c93170f5d8b503b29ac125f716c45422d114ffd25dbc180f3e358f8d83b5b7aa5ab6174e40d8235679aebeae5dae15b8852e0e0fdc2f10eb9834ce5a9675b738963120d319b23a550fde300be574cbaaf70a112f5706d5c6476c9ef3b98e3b4f547f3cc59be199126edadaeb831bb8cecaeeaf5d6a4013bf934adf5e2b07e9c5ca28c2ad6a7e2cf1207ef2a760e01a5d07b7bc0a532c0157e430127739a1ad0eaab81d804ac15fb884191537085846416cca4c4e8f1850e8adaa031402d336748224b873a66257408d4762f3228dae78f2a0a4650c5624116fa9aaef10b2be30df5f0d8f65ede7365675ad11b2ed7564dcfa20ef0588bf67988215ca9e604970ff8f1ab5eebc0cbd069620694f59e8e99eff4d788806384bb551486452e6e77bc3b8a0de74ad4be9f29ab7b1364508bba891fcc5b674f433e20ecd1557494ab23ab30392f418cff1f477e2553ea256a0728850dd23aa3665992a93d9bede891e0367c81dc646c2b47ffce6426aeaae2985f7c7768176ad6882e07b3922eb85ee9ef56f3b5b0529bc6836c1b6d54c52454bfa0000a7603a37 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2a64eba3859e77cd9675f97ec34e38b384583a33c30fcaa3d8be847788c04e07e23cf63d602740b91ce9dfdd975e4c470d76dfddf9bcb32df98cfe8bde0569eb24abdf3796d117f88e2748c1986d2684a4e4396da599992f63b895134eb43ead1c1ed56aedfc113bab4e1ac1ca15362f2c7586546b4af6b2a338ebd79e316ec4c31f06557fc387fd3446e00da73b0df74fdbc51ee6616d54c4b2abeb80e44eb90b7727f7e36a6cbb4e34ca49e49dbaa3ba3b7e34305fca10ee332f87b2f1486c6aeca774647c32cddf398ff4319768fbe96c95fe887c3946d73cbbba863adec9b6f798bd7007a06179fe79b734a1a69aa6ea4cd133a78da739b4e376d985d501e538477a6968f944c5d354a26b789ac9dc6335d530978be6cbc8593d715a9b483779dbbf67b8925db8bbbf459c3bb82ec97175a459a7eb645bac79a004d9734d551c49384a4ffaa0a3a25d3d87c5d667ffea5dd29e97c6f3cb5ff4a9dce6e833783f2db5d4a8fcb58e35b8dc2bf6770b7c3e3eecf3a9b979d8b1d3746250a74aaf23aa62b6c9acbba546adccbe1ae316d5a86ce931fc9a31be4a764c18d7928959f2ecc7427b6f3458e2ffa994748797285bf5a26936cda35af3a7e04e235b36c7eb5fd9a5072b415e8e8a2518d0df64dddf16425798fa4126aea50739f4957c823a3cab0f6182c4e5ae54c40c8998427e31b49f4af597d22659accb85409c6a8cb9c4a32f47fce16e43777eb9d56a7e05bea5dbdbec0d53960c564096d4777f9a56e57e97d1d9c7e144929cb38290066e39a3c25ef866014cabd01852a19e68df1a59fce8bed648fd91ecbe6c38979b6be617e58bf7ad5f3318a64df6a5a7a97cac7eccf7069f1dc7ada354d06d6d4633ab3b542b6acd9bbe190ad37d8e725f2c48381d9bc4887d2d669fcdeadea78ffccb2f8561477d9a456976eeae63af59684e9eebc55e612d3d9cc7b17d5ea668a544805aa5471bee8475e215e3bb58447583b5942498c0483a3ca405cd71958c1208a3be3d6ca71695d839dcf378a91af6d1dbd8cbe6938042a5c886daf7f1eb9b9e4cf46383a9a45d9ad04bc66089a04611b241fabba8f6435b0b4889a9403e60524f820cd8d875926a2d68b33c3134c90e9230b43cc743921623eb484f7c65a741a8c30cbde4fc74a55305ef8588db967ce70b29049a8e5c821b484390a01761f4850bbc916af732afe9a211419944e6c7457207ccd12aac09c421bc0a4225f84727424b306549738b91eda3a818e994cbc763c176795c1286019183ca6b2e2d3c8ee925937c5a9ad62306694724e0b62b68369a204b0d0d1b74ad9ab5158356035045416a8eb48483f11ba52ecb1e77babb800bcd67245932a237f237410730114ba4241a295ace13ae201b776c29613fa04a82050bc4514e8c532a0848a75fac67177844bda15368f1756bd4804b28bb55bb2e6c610f5e0ab9df749857405dad47c8b16b8063533b1e1c57d4db06f8e6643216cc342b053e3861cb1c71f2f9b52518457056676064abcd0041f1011b1ad3cb297a96200a96d6a30d2960161008cc7d26c1c011a00f857739e223ebd536c61748a1a9c792dcc7351210c8dc6c3e122ad7d9407975a75c3286f0ac032e5a655637c5b6a043aa840905d9623a077489e8cafa1285ea271c25f12cceb3664e3975f0eb6b25a04f18e4537ebb3f27405398d34718304e2a7265268367312aba5c069b765361d907775b3041b391668da99968c198e116530143c781160b80fb5d4b473cb7f60bbad1b83a3c8a80d93ee4e61dd546c5e06a67dbb6c94fe82d7e1b963e744984b849864a22d535cba8408bdab3854be3694515af4a58a4c6c0204f110ade12c0811036f9171635c00af6a29652914ff0cc23e0e67e84072bb1b3a027591ba96959ef3373a3912e1d43ad63449ec2f47de225767b94417a0b918bd83abf4439ead3090ee872f6c0c5967564da6c4a3ad061db656f3b8caf970a690422b914c599fd606eb1a17a3a220a1d86b8ba7343e1048c1d4328aeb57214e077246b7421091821c6299a4b75fb1b9fa124c7f5b3b1f8938ce9dc7551d25898387f5a86bc9a1c49fc8a7c5902b8e2912405a592a8221816570362c43589aa9eef609b0207c9e1f3b564aa6be9a60aad4193001ac4f6756570d983c8982cb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b29333445958cf50f9cfba453f058f562158bc253e535e4e2f07715531a1c6289ee32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = 40cfa27dd5ba61faf78b9609063100aefadb6b2463b41275c33e04ab0e0be914a35bf215aa967a443b5f8af56ca77d74ca47cda9fe03c0714b5788454390f9ad68d519e290782843d9306da1b20392937680ee9a44588cc627e9b44950fccd15f7e734cb9e2bd080c2da64f3df0ce8dc5ef8e293b6ffea9cca7880c396da0ab6c5b82964bc2e626f37a87437a7be4de0b6c34a06fd0760d107ce1a80f08710638d0ad39c838173cfff9e78244bfa1195d887db17815d74795ce3eab5223bb69790c7929199803374e06d68b8f7fcfde7889d4b9ae31e7f19e0b9c956ed8aebdd2109880f504a574aef28df60f5ec74f4a4b4d6b2db06b47c7ed34d2e7b900852e4b3afe9faa8ce60ec55d0449c943181930c27c4c36ffeaf2cf27fb82e1a25eee0a3c39c79a6cd508212771862f055cfb7a64db24e05252b7835a4c6b24dd6067a1c4a624e9466e98b47d584285837558180e4da269c914887d44525c8c25967a6482d4e54b16bb6b22cefb93dcd5cc01c3ee4ae711c47fee03b29a5876a2e434d998bdbccbc5449ea33be532ad0612913064192b44cfafdaf06ee277f8aa4c115eff6cb36ca026b3240e70355ad3b60ea29846f846d7240afa4af97b0f6c7bf6de0b2686875e868a434b28b75d95fcccb1f152c43c785135a7f3e8568e40c249e703ace9a809d005c4967cc6a46bbd305953d6957d94be02ecf83694afdf1b3e053b97d693641adb6e94a123bdf1cd3b1dbf5801aad3d79514702057e9f02fd8f36b988916798ff3b4e6a6bc8b196e067bc117f573563b08dbb94d5b88b0a7f8d69bb60741459bb59e34abc792d70ac51c6d6141340ffd927c703b207b8f66df8d68973e2cc6218cf5c793690f3df49fe6942d00191980ddad5cc9cd5f8c81abfdfb3ab7135f6bc8a86dca7d1a8d38a47631f8578801d8258430bab8c4b777035965814f04d62b43e54a93c064a7ab0c7a96697abd94a1e460d32582adf7479b20f83c6dffe9b45ad4587a13e8f5c315cd46200282951f87dd3447f664129b8a0f6922c5de259042b3d14ffb72e0aeaae45792f1a254cbd576bb6432f183c50 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 79888a9bfccca036909f99bea673c23173c15865c0756dcd895ce160aeb673a8c2f60b5a99e3746be64b2ab5a7d7d980ef88e31a5c983a7e4692649458667cb70361fa06eb5fcb967f235b80858cfee9b9b2aac5d43fd2e6c881a25dc38fe9c8fd5ead32f57ee3fe40f34abd1cd586c754af26ef3c60289302b95bb9bbea90f59ef045ae45698fd57acd202bcbb8b960fdaaa6f9994e503dee6e0f4874a68e3628f45e993d035c50844d62fa16b734ea4e645ecff4b77c4d37f4af1b6ac849e737bf3bd5caa94f6e400887f66b266d206b39c8c7563e86633fd9dfbbeef1427e5227cd71043beefe6ecdc7f3ff89e750dd24314f7c59475fb9e45c4bc07b6fff66b5345bd548eaa81f189a6fb656ebfa3d46c4c5453b7f183a335a765a58f647f8735901ffe59733b01a84789d26f967ae513493ed9223cd10b7d39286703c85c3aae571763e4a6a9c83e869aa0f3a77c50dc1b705768e3e82613d391e0c82b7b4694cfedf6dadfb74d8a1741dd6534b44f41f8cb433f2ddf32f5d6b6f1e55f4e867383dd5fe565ef2dc0c3042459f14f88bcdcb7f133b87837f8635339c5ccfb8cc2366d4bbe1049cc96af69b686884694a968cb84573d56f2fe6b71efe8d999436172afc45c88fc5ad983333432e33bfcd26d0683d78ee6eff138d4d691c50ca935b538eb809d934ed3a41b51f82c4b483d5dec94885d9f23df46fe98cb408afe6cf714d57a41b95791164b406e85e9dac54950e6b2f4bcf1984e9740a3b3ab5d25436b0c46b7d5a4360cfa7fc7e9b8f3266d747168d0b88e8f73bf2639d74dbb79af74b91f4a7d84496fc30dacad02455e5b5e2fc8fcbf67ca4400ad038d8a8680d5725efc8c37f7dd0da6b6978f8f84e804d27956f3c3c685d8e4be740be8c63b8858af9f74fa19c7333fcb49d4667c9dca264aa5d78cc9f7df99bd7cd63493759df3a6fdcefb5e34ea5f98c4ecf78b83be48d55d8ee8de43b210378d5ff503eed5c2d76b01c48f1e10d6c2a5542a60f7898284709149a58c3b5b3d4b761e73ddd99f262d9c80584967c047fe89a409ef879437e64ed67d8a025de31ddae69a047a0a46968f3828fa4314fac3f911a71a10c866e7c035fe4cf00a92ba9471a735b808117722378a879702d59728d66f35d53c34bf5797c2ff9a2f55a0b2cc873d8063a8ce7914eec935f55174cbb542702b1e7736f50215f7a1277968c2d35c711653a8e4af95115c9ae33d0349d4a09504a10cd48c77b411cf079a497a5785e39830cc8a189b9bb56891249d976991b23a4a7a1aff34f3788b148166c40f381bc5704058339bde0c192d307515a6a8fc5747a1058e394cdb79c4142fa5ccf3780f254a10c671543b63bd7d192913480c77517512c0e49ec3fb8d03ffc793e7cc01125226fc4929c8c1c2aadf12b452746306c2a9c36392b23045888c2f4170b5eea07aed4515a819d7c5749b35380cefc976c87270a1237d6f4ac214548268a6da75928e0734eea7887aac0a2bf623e17852501556b03c662e4e9c42b914923b88d502714fe53373904b91598c8d7c6b022e5367a90173fa511005039d9ca5c3cb2bd5ed1404f7373654848ec436115339db37cb3549ba77237c243f25da96a4bb4a8b88e441693f6a80840b0ef7538f8fa9b71ca736d08bd3678c4ff8c480b115452c9c8fcd52529b1481e82236e5a311a204bb571a89b0a60738101b4617b033ba2df6c7967cb7b7f218aff886edaf2464b2a12bf244bab812731f46200ec6e94d24548650e1e1572e4a78157e2ca569c3b1472cd8fe98458c1a5ab8340f3a90e5a854ece60469698cf85d88739cc96adf7048cc584637a408acb79980a8dc119049135795245748683ac8f53b815e29ddcf5452a9504e0fa1de9840e4d489810c35a100687bac18e185bb53d499d266a8758c68782778b533bb9e5b16ea833309a0c8b3e640a2c417ad23b01e27220a7e9cf9bb91bd6eba10c08acff499295e0ac4f61b9e85ca75185af845c4f4330652ef024869ca7d3d33cc188a65cf17aa645b8d9b010f379198e31b7ae448082069b33ab6ff3a235ccac081814b6e063686707721f6006eabc91a4999915661427c85979b93ddfc14e24176e9c0359839a1c16f91afef473652480d4a2261abbb7fcb031de8993a57600220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852ee6cb12a54341aeedc99f1040b01603c35f07c5487ffac7b4fc1925f490269165aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 76203306e49a9d478fa987d47cc93959ab932ce7d5ac52801a01a95e25d772d8cecd1f718c5878e90d9d4a4976a9e6dad07ef015104e81817839ec0ca9ceb6581d911fb08ac2f7a7fcbc200fe5a81d07e6ef7ecbc1aa057b1ba3790ce9694683b1b8b7baf0b0f254f34262ae33834920e510849fe7d931a9bf2f5d0a8fb8ac25e32ecd89d880506a2ce0d51293f849e8d452a8ed509b959ba571c758d93c8eb092367b5b5b5ea3afa27df10794aacece9932f79f1dbe77deef12f9bad1b38dfd479e8bb096731fbcfed2b2f47a06bc3d66807264a4a8c12428fe6da2879e08a5f885c3cf08c73fb130bcf98c0f4d0e1ab32c50c1ebef43a4d7ca59d2d400af238ce00b00f755eaf5e613b7f0f63f412177b8525551f12b32c44273dad7796171c0f962f4b23b03d5ad75782bceabaccee5dd37a3ec588b0583a59c761b83ea851cfdd3b43daa3fd8ecc04edecadd4635557df4acf2111118f5cd0979f106e615ed443b7a271be4be9971f3076abc49e4acc4cb36a4b203fdf49babf4b920b374053b023ade1ca376bac0923192257435e7c2c9712df08cc77ee199b0194af5ba14150fd22343488a02dfbc7cefb730199fe24e92191eb7c21ad5af0fb9cc54e041af6b64e5176829f9f4b67197eeb530054b8bd211b68eb79df559f2ecbf4bdfd675a5a8b2f4cd48b8aab8bc75fc16cf2e49ddb932ca9211981535078ab253cfbc514e11edbd5a32b85610ec462e15ec7f12db1cc32fdaf2b09ec96d1a8bc581d689f1a7b4fa02a4891a77d128cbe48609c40a2a88ae8305dd6cf091f2b50cba5762f946989951df8488a7647d79a59e27acbfeaedd07931caa3d05868371fe32378f025b987467c3e6f33290b33d57455248c5a57e1ecfb974c5b9e5fef8b0da09ecceaf9ff6e6c7ad04b8ac41efb59f6fbcba2bc0ac8acdb6f4972dc8308f2dd0b2a9626637bb4ab4593d8330b38464467fddc7cdc031bd17aad822241f5798c5640552b78055002f145075985ff5b42d72bff8c9addfdb55c18c03354ce7207d842e9f734db67a24876359f33338c5b68045c342b676770af0162d1292297 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 6854f64157fc1216cff86478bbe3ee60e47a2249e987eae541aa882a649a482bc06b28a71829e37a0f94e3a4a3429c7ccfceba412fe32b9cf6458a7afd5e4e3c859584cbf76874eabff48ef83d920f15775fe4d8edbece3dcc3a10095c96a3b23d6a39e6caa335bab5e153e18ddc72ef347426f83907153f0aaaa3573dd279dbe0a7ae922cde48898731b5b8ff097739601de89f244036d8a409937ad9a4550a7fb16505fc15d851f31be27ff5b3f7bf98196deaa2c9b00a7981773c32d2d55d8caace972c8fc09782148faadbe553ed8b8e1e7ac0429dd2f2adeae384980146aa6dddeb8a939075fb36d4d48b55f489b97dafd61768479fd4ac07ffef99f142ed5d1a25e8e12fe8529f49ef45910a06baa4d442ac9a95c8a39d9d474667b48cb669558f4de15aeecf8c6748661d39c709da467d8ea56979ed4fa8e9e86bee5b5554d8a46eadbb4d9be00819f0321d518544f6104fed0aecefa6993fed43f83b0edcf023dca52edb6193a7bf746513a8cd4b84658054623e85f72c198fb443af8a9f7faf644824e8cfd7ac3eb3eefefbacbc7f837834c57e31b5f1977b655d78fa34079c89f3c38418ca442f42fd84f0fa9d312b8fff6726943758eac0ff9b1f4c6795975549d38d6224ba7016d46b0e5d0f87d434e597f03976765e381474868eac4d653a7bf0b989eef6582c8d744a5b91b1473a9fafd055e4b5bce5f3b7b6e8723ae0758df3454de58dd887982b79383b7272a4685a854c306b43d36ab89b57736ff667c28ae0265a7e15bb5cda2efd6f9387bb0ff01c3f957e17c05ddc50c176a5bccfad5cdcad546e85be78c13ca6c2a43fdd4a4fe3bae3ff33f582459d70c4b54725f3f9b1e99a0fa58010d7a22a6a4dcc9ffe5cbf8803f4d27dd935cff4c5572d4532df7c5a56fc93ad85c7363a215afe0c9ced1c04fc069ac624af45a14974d2cacd59fe8a8973a02c66ce4f87e124e9878f5df103f96bd40ddde61a78a5fc5124deaae76ec8909cd9dd457285f4354023e0a6f4a5149ffc836eaedd896adaa8ac1e5fc1353aea3e2c7b1f0be4b0adcd6b39875e9c7db636b82c0ff88c9845bf1121a0172c991415a6456b7d708cf45a376e689e8c74b1dd589e2ba95d19192e47937b647c21bd9a518644113f44877aab626c40843b078e9a93be166c73772b290164c7ca1454f2b310c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae30b2267aa97bed49c5eac3a9b769c3a9aba51e882d0f5984cd7c39a2d1136fd627b3a204ca30a32efa02d51977eb2145e6c91717e0760f8949caf6b928a59f4d6b24221a291d008679b4b761178909c83d4c035de424c202117132010da0502b75e51705d07da603526fe46f50807af33593b0d59d4b28b31ac48ba7ba35793b194224a4f7577d4a7664e4311841b3908ba57292728a428a516d96c90511ac6b34673dc0127db223b7b27121a2aaee2822744b7f23969cf95b3960826c0ab4a100501bb601b6f2597339a408eea5360b9c6b752a03d648817654a35db7c5fde89357cb1e44a1b800d99e87872f95a17709f72a2a502d8f908cca15a22c14691e219b95b9c3fdcc3fe3c849efeb9cc0dc051f451fbad93ba360b2dc2370b400ce74058dff270757f20603176ef888cf2caabe2f8b337377368ba7aca7131bd6c8615e0017e2b21bd5b9b029085ac668803f66798ab060104ba4e930322b1452befb11c45112da8592fc0a74ccb8a75491120c1b0c1f0cb0a1abc7386948be2bac6bc92c60944ac8482e5a519b3ff36df7ea5e6f939b0c1b662342a08b6059658448b65b65c432b28fb66b92594d0d8938e5d3a0d6a99c7b3173a0796e02195e84b28da2b06fcd5672412420c916c77613b9c69039cf1c6594d90aad857dd319cc9bc9702fd452ad455d5329b14ab033a5910c08124338933f60993c3683433352cce6c484efb072f59b85a6b402d4652d910173caec2adeca708bdcad9d996b60a08f8c3131c571b5faf01a4b65565b18298ff8c6b3f68e77e768a1c0cc009315a4459b0b191c3584bbcd562861c20fc8e2c70944b7eec84c7e427f935b5731fb6e42d8b40b013951852413e94d5e01a04405319a7167b8e4cf638279331a6c3eda1dff9cac99e148bda370c2d00715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8242ad42d6d3b13c72b16287909bc4c0da04900536a1e48a1a28db4f5ee2d2e771e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 7b5be6d0d3b9759d1889322cdb13d7bcf5ce2516ffd803b9acb5435a563dfddb466e640266191317a893c8d2606cb4502e85b787459a018342d1876a554d468ace2bf0e6cbfffb25bfcc5c2855afbd2a799ae6a197b861ba70c521b59da2982ea8b90970ad2f53aa11355058ed95bb01d235e41228ea4e7432cb81b95d69ffb2f48fb868af1ab0dbf410e6774d4fad8d37ef62e83ab2ec1e69eeed8cf39e1392015786ab4c93f1b6e9ca8188ec5e295c0f83bd863bba439493623d05fb6a7afcf8c25ae4fb2027dd56aa0a62de157fecce232d986582f228f7a8f1effb88ff513d6b87f3911604cd4da1bba8beea7837c4c9146de3e21f2fcbaa018cbc372e72ddf0187269d8805a592d09e33ae558684c223d4ab4ef9d16dfb5f034ca235f977d20d035472a711b773ce9bc5cff177207ef81601cea5aa7085c505f92d0bada16db937621dd925659b6ea9f1c6d7e859b012a191d056f602bf263dc4824ff46fe658645dbe9cec11cce5c1e5632e13c3eb634f196e059e42dc19ec577fd5cae7a67a7d70a9bc4484aacfbb3935fbf401d8099935a8d746363dc397477e7831842cb4d22e301125424bc994ca6a62f0b3c6464e93f5a8e18cb71e923ccaee3b6fa1569bd8d046a5d4a5687dcc55fadb5f8023309a31f9825bebc117d6427d4f0e6f48d6f45fdb00228bc42f8b5066a430d38411817c0278d17be7e64cdfa7918580aa62c1ebb5860c36282d8c3e6c2b5b09f75de3ec92895f07944041bb139e8232aa0624639dcb882492c00d5323026e510c7c3058ae66738ca61398bc731a8605eb2ecc4768770af6c4b1f0ebe0f4d6cc8c18c9c961d1003ab867a42187003f2bef281d0c88ef70c4e1927f7b4ad837cb89de4485ff367d082c3a3957c76f8d99f3eb8d0bbade5a5e8ff5f7dfdcfb61dffec0eb24d607fa3a95a53419e9cdd205463365f16579a7451a2264e89bf11d531a34d20b5b0d478b9faeba16d399db32390ba2ffa27434ad6a0b1dccc7df88b6d3a805b45040e18528473ec6591eb0b8ba133b9b48b65233f11a91b43895fbf7c79f199715401f1fa69bfcdababd7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e9c556bfaeb6cf3b62f9db44bd74434e6d67b28ddc98647a599dc35224c1f97ec13c8d738417c5c88e71d61b6b500c907f936a1bfa6125cbb5d41c88e39ecbac8ea44aa84f4f04f34ccb8a5e05ba5b66927d696c2eef4142ea48098ec63eadca5f98f0d36a360f345ce58d4759edfa3959c2cc876ffe84c6fdfeded21eb6e7f594dbfefa31bde5b30b403d0bede307f0c295b963fffbaec9e3aabc4397ab4011a8ddc1d335f256daea6ef7071a6fd92df48eef7005ef83e208cd00e9eddc56b60445714679b4aef87f2a844fde365b162cbae34ad78fada516f6661d66b3c03abef8daaebebdaf33bf8a7ced42e78b85ff14b42108fd1acbb0beeec83078f1a95e605ae83fd8b3e35b896d3ca9df67da3a386e791506f6e7cc7dc8db4fcb7ae0734df5294c4223aa809bbf9c0c4ccfe043d309e4a3d6d5884f3b46aaad367efb62cbae9d9a1ab299b83e0ccd390e1eef3c5b5a9b8593ac866591cbf84727c52c435105453c094fc9568e74ada8f83c248ff849f619833cb3aae4a239d6d2b8738defcb4695b8cd6da8682cb7d8356f3bfebba91396bacd6414dc7ecd139eb97e58596b3221955baa66f65897c78bf65eff1e6ac27332c7bb529ed5ffd1baaf7cea94f9eaf445bdef1ce6e77794dbcf3f900eb69471cc6d18749824ea94e8183a6d1dd7a4d6c1289aceda5fb59568ff5497e3a379b39d47ad348c68d36e34921e6fe01c6f70a5ac6578a0531ea44586c68ca8ff72d6645e67409fc85c585cf5381dc801bea0d1293223f874044ca3fc1436d2daa5752aeb596c58fb4f70fe0ed3aaf4e7955eccde9e3bf0bc36ba7cbdf6caf76f988a3586420befafab959410aee6fe5439a729f7f9dad87a9891113ac8facfbf0d3bd91d7acced5eafc167d8e8a7f370d547cd9f69fa487811cfb2f1c474a6c8858de8414f1895488ce0de2cb46cc68cd70eb9f0e8d59599c7eb7fde5e1cdf1c5dd8aa1a4d1f5cf5a1448a51447463a3a88b9a72b69cc5385750fcacb78ae35982cb3ad5285874a5b34c53c00c17913e8b74652eaec51b93698c4bc48b74dd65384fda4298fe70bd65436453335b5b3208a4c987ac02199a6c057376e2e11015c237bff18c63b730297052d7b9a6c7e15a3f02a9046c23e7d977111524afdb42fcf24526ca4f17ea597a26874e333f40e840fa3c9910c12ed9d86425421e7b585fec42326fd1618db61c9c7ca727e03fa772cc9cb241166cb40d3148b4889ffed89c8b0b772e807a157a6ad3b067c9f43c675c69890a71b996a323376777723cc6a4bd240c40deeb93b9a61bbc306177909e181636353a2f4b3b02f820a9f841a690b50a74f09eab73ac4b13689e267983241b3c9774c42701dabc8c3060381f60c591608431ea91f5743362eb86add70c93078349f4bf4b137d43e06c6258484c92c8457521d54915c96754673a4f981ca7c1a3c228a22ab44a4c1d207988d8a49925724c218efb34c1afd4b56dcc8815622d0e1c206991abb6e50a3e8299d9ea10a8b5c5611455378a5ac2b179c74501896102890171f95bb18d32ca7aa01eab0b272df4b77c6377e9397f8fdaaad0294b59c68607a073a2e021ab8b1ab1205cac74c4bbe21ba80b98225a33b0f18b45a8227c9b6e18f9c25f6b901137a7912ab148849228d2aa374a261073307127c6b09777fa9768c183067bc821f3d77e343874864288518ca21ebb2061828c0a60340e30ce80f60ef5523129f18bed579625e9419185019c8cce24162384cc6eeb7b5f9ef1725ab6034db7c7ef0580c9f0cd0a81c2236c46ec9a3225593e3b11939b9758556cadd3f9967de57f21db4c4af8541b4b813d67159afcc69dbb36d3dc470a829a5d771dd8468a21356d40c80f1c156008b3bff356962f84a48a041f4e4b29b7276111660851f7ced28ba0cbc24cc631942b92691e386bd81a28f66b8d4306bf89f36d0e015542479f3041cebeab2d8e95304795a31e6cae206b40189b4823359382393bae1057a62471c5a3a93cc874f96c294a6a4e00e6bbf8cc4cea280942d0c43729b2576076e73b3edef1be7317cadbb58db1a046b617800d5ca0e352b6d40a16303c596652a4a2209c5c72428de4b0d6b6821eaab1f6824cb35a04e067b5264359a9a6ce8b3a26259b613710a672d13d2690caaf62c5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc755b70c5bb1b7af3b643588aa7c20567d4259dbe6abd7617a61b48185de8f21e1cfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = 19bfab9556d26ce097facb97e1c345495d755fa7df0892460974f99c2c103ba1049b9832918b874254f91d8fb7cfc11da9c7cd1d6bb50701371ea35019ff2a940912d019d2bb18821de100b1391d44abb1f72aeea18cd4f52e1401bdafc49adc65d73b02a5360b9ab00114035052d57ce16828c22bec6afb9331845210ee64a180a30bb684704d1c462e780aab4a55d6d746a68999e583de1a0b147ebac3bab7ba17faa6f58d355d041f0af83de1b4d9a244b83842a9003ab16a14360a97978d8940ec93abce842e8a1a3a172773b317fb8dc59472156665821090492e61a99d65f0da5e97a6a1a3156e2890e4fed146f4df81205974fa0196037b93f52bb1a3f85f02b92c11ddfbe479a30ed62691a82ca807eb35b0eeb8a0095211b44deebeaabe73e616db6bcabf52eb47546e1c6e20c2e14960f233378eb96e356cbb71154aa8d0e342877dcb00ff7f136a02aec66fddd1853a034f050c6155aa981ef2182e190a28dfc480d14b170189d105e565312578ef1a0024314bddf231af846affab5b289eb586db64f27ae9613d79f62c96927b57135d91c8f9c26c48cc81ffb6e39733c8285a2c93b6238fa1f9bedeb5b4368236d22a6e03bbeef92d2dde1d7df5352d892e360e2bf0f2e4c6dc86003c9f2bdbaf5a308a230d8e00e810297a46dbc6c52de5011b983b1adbb754cdbd33b5f1ce7e6b1e9d5424f7d393a53d8d90fd712632b160ea812a4558cdf0e6730932f021474b67586e60a80d97d8fadb44038916bcd5c1c54256cd7e3f61df56a7ba1f1d96c8ad9ef234819cbdfc66835139c57220026cc25fc83c6c31da656a0694dfc3a3a20895fade4d17c0da5033eab105b3a4b464aceb6b653d54ffeedb2b0a009a9e45dba33caae7fa6a4164ed135ed0163fa1179f48431690314d1c7dd342aad752184ac108611b096ec477a6c9333930aa521a3b81e2a0836f0f0dca27cdace35a6569abe904d14822255ab5124df8ca3e17856f12502740a3038cedfc286f81c5525b7830f1d153967f474d2199dfaa139681036d718e8a308ee8efae1dc3035284b80e9b015e1d3f73b9c178 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 109cbf34136da8c797082d85f046541b2d5922b9b9291acc037e73c0e8f4ab1534103bd7a399853c9b5d4ffaef7ce38302c587fa9643b04fe8afdbb4905fc517cdd74cd3362425916924d2750384db93f3f91fa8926875024d89df7698554391f1d687a2af380eacfb8136e65673fee78996d404ab502f4c0dd3acd6c4f8b9dfaf8135de7da8f5640c3f95df97b35d64285d5eb3045a895f708b6854f0a99437f673902fc1dce44c170e63525d74c3d7fe2b4d41c8b4d7dee38ac53335852df9bd0d5705894ab668f24134421ad4af7553d09d0d93b9b385984f4a32dc9a5135beea4598d9ff589e7f855ad37cd99880c1fa91117cea933c70a186d86d437443b635231453150d3884fce9a0b745866dd2e4b63f497852076ec589e9e32daf7f84e9ab5536b6052dc89c9a971718fad59ad5e8d8d8c7155601ce99e8fc3ad02bf29318d71a2b9588ffd3fe3ee442f3ab9f9f36aaeb8c6555c1d47a75fff45a5d7a5ebe85a8dcb7ceb07739381fcf9f7c465d066f80c359c7a3c713dcf1a4653078fcc51c7f32e499d0ed85d986156cab756d9bfdc685263b1987fb35a8ac3f2e4e8b7b9f3785395c6ddf76477859cef3e25cde644e9cc6db517a148e560a358e05dc8bbf38d11de81555b46db95d9e9cebdb5f73cd58818f4ff831b7e302dd92914f89cb5cd180dec86d758c074e36f6b937ee3ffbc0ff44de8cf13def4c967cc5787b87747a305c83f23ccfa6cfca8450d4954dcfee3d26de5b96de89dcb38f8bcfd016a927997f6e9c7c1e3afff97c93879cc1a5f3dc20e8d423f83c84373b85384bb7d88e9feccacf73ab599697515edae69537c42f5d3423acba65e74415a25906df591e7713dfeacee6a97d38ecc674f997833371358f60c35da6e6a833e5bb20d94eefae6e7093501ad54ab65caae67754b966db5f68b78b44ab26b439d453412206325186bc4fcf47a0ded3e74bd57aa7faef6949d84d3bedb5ed83fdc6540ae23617eb8777d4c7c9333ebf52b4a37a06755a1ce4f8b814ed8d8da94aa76cd8d65d1e16a8d34dac71ebd5dfb69d1439b57d9a3e262cca3feca48dace145c83435071624067d69587335b97bf564929709c8825a004b028ae09c40980a07e8d4bd604527ee221e8bac67d34cbe762c26df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367d3153e460f497a209c495fca318862d6a57800865479a006012d82f7212b40284d310e01bcb11e122c1fd303e441807849a7ea47976a99abb7ccc4b674ad66f68eca195789b277d23c3d67bc418ca7c908b21e53984983ba0205e4689000ace97238b3699016fa95e7a3a59cec0be813638527562fa9bf10d715e7505f6e1c1433521a918a7df52760a0d8a9549569f10827c423cddff82aae01a90111395487b9c82b7b5a7978d789679e66b75087bfbff0569fc94e94f93531b721315926388431f2a36ae0f701bac254befb437c58641d4560c8738a98f30918945db0a6900ad2c2abfc3e0f4786a4555639d84dcdd031d8f0508d8c774d68298bcac4f42c6a7ff585af491fa7d7c3bbb41727699ebb315c437b210d42626ebc66c916af1f3515374314e4f40309ca7289c7bc51c301d8180edc792d4dd44c41b77bd47a972d8434a9f03bb3954236ec422be0c8e991a79af286b6a7c459a95ed44868ed8052f2db0f3741710228979507cff961564882b5ea19515ee00d657c7141e9b05f9a24136a2f915620b664404b5397cc7842748973d0716cc273b528d51383a63fc8a3c4a3b1a8bc965775d750add6996c929e29f41e42362a759baa76f5a3dc0552f1d83195960e45837901494a87f2a6dc3b5d8b73a9695c1229a0c9bddb0b2d99aa350c6cac657745c1308af354e10595f3682a34dc26d9d28e2e2c4634aca75e94384700c9c06b1bca348330ac1791fab1419099cf1288283bab03dca09ab3593cf3b12739cb44c0c04c6b93d1ea831df6bcb8807aa6aa8cbec64d749a9e47f851c47c6537e196f1fcc4d63b67d29a58e86b9a72a199cbb793c5084e5bab20bd02289b4aaa64e4c119488531e8a651a31750148e1742c5390bb9995c123f3056ad44c476468ded4b88a49130e35b4b00803dd24718674ca708e436d5c15ee1d95367c623512653c83b27b41cb308f8c2929b193b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b801782fce09e644e310c9286f1e381be9ea8c54a1804e61f2958c1f975aec185aae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = d9219659f8d5a0b8c4492b9023910a14eba618ee697528be1c1278effc029ef469b4beb1e081e4fdf32cac697d5da4a859830dc4d15e0e1f3298ef3ad9c4641be0ef901beec94242e894e62d3443c4975f219c83e2b69c087fea2e2309bdb3d64446875f065f18784ef9c2cc0d1989ad1b10a20fbbee5a992fa717a64ebd7fefbc94823f571f8185b4f8bb3886008aa295416877456edf06bace86c81cd01363e29727073a35662b950bbb829758d2ed5862dd8222ce466dd9d2c5139df83856e78b25f39734837938e03c71727080f5ad64b3471774d528f96dd354792607a5f3faee5a605c388ae6b7e26a76dc58926916cc58697634295c6b1f50f18c4492ea1e57519a9c46fd992156a70068c51531ac2a9bf2dba6be5f870b145826e468cfe30620b6c3d5eedd1a769bcae9f091b3b3decfd200d574d61773fa2a15346efee7c8aa7a48a68bdb79853e52cf8805fb19a01cd95490e7b6b53773dd45ea1f1ef2aba510992fb3e8f2fba356361d94fbb3ad30c5af6a26b236f4e07d95b619686334bac20b5838891716821f39dd454cb6409b1d124a11cae63cd67961f3e07f59dad6e161e7c6926311aae61f737c67f30efb7978ebd022d586245b8a2053d04e1a74266cf2c630399f47f239465201a37edca5acc7631f5750e0c7b34f0b27ab7f1d0d14caf48feb2274aeb676c49c10a6e3228fcc290b9cf3d38d2c7b1bd4b2573979a7805b8835fadc25455c5b878666d4e5f1ce4708b55e425d589191354fd665d1fae19fd1870f3067d5428b71ce2057cd29dfde70f51bdd12971ce9ad925efa35a737448d6a2dbd65571e35a6dce15327ef73e4e6e7f2410cfe0edf52fdd1a401d867e12d0ad058fe92b6e7d7f7e3e1131036604c3f64c85dd3fcc3d81d8a58fac4a7804fce5a0294771f86aed396a5f502f3a366ace4bbd48a31c7b19a9e120b127d9933c46cc7f9aecfe8385e775adf11f665b2b4678db5afa7d98ceb913000d9c3a2bb814f547cccb129caf9ced3202b0667a98fd18d33277b31272bb47683179fb15ddee809e90b23ca89a1015c273dadf6fa0d39f20373c763 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 9bcb4608a99cb00b809ee8549c593c0c74b3961a27290d27c81822b96e4a8c1aca1591b06f81792c90b18b36fb9476d2496474093f4723a3417634d508f03c4ab185489c11ba44e4ade0511ed5848c907897d9a20bfbe087bc377d4513036317a078d808c940c34f4c39e558bf56a8aae30a1049505c42ab9240c88587354be5888fef5bb7b07919936c47800602aa4a4d03a9c1e15175 +ciphertext = 52ccdb91fa5bca01735751eca5ef90fb718b57b552df511d629a8f497db61313aaa321711f1b580bf766cc768342cb9c57fa333959854f7c7641488cba74a9bff729a01737fec4cceabe48a6579e691b738a78dfe04f634ce6a646c2b1b753bd0632873302ca6690e1700a2ceb9fde322eb49beba4e13f594c0f1a0d120606f2dc06c3a944ef3f977e274275b59e18e98c376dfd10a03a42c495eeb72b2441827cd111db50b388f983fce66223c9acc5e0caa78a087293c7e6e3adc5a7e9478b208861ea2ffe84f4ce9a7a748cb60e59b12aff3e48c074d3e7153cf27634262c5c4edda7f6033327f30d9b407d764a5dcbf4839155b336063ce046b6f367b14f849903de0eb4f8183099784ad914813cb81c49a48ae7d699a64535b624be16a2ed7ce54dc9701c89cc5bb3b8cb4274dc1aa436324559839806ebb59e500dfbae6a2d37ae3b2da325db2b44f3b27d332c91bf9d3a837c9bf5ad08991eac197d86ed646b710dcb73907b82cd5f8fe8fa1e0e8ae9225148dc9ac294c7f96fc13d3808bfc517f02e65880f68e80607a29a10e5e6037cbf4dec46d91dc48262505ef2e7849fe7a76fa18b1b9ee3bdd25cc6b11a74411bcaae13870c64972f83624b6a7d34bae316610350fcace66840c182b410813f7b4bb821d479a7504877d0894396338073b8505637239a02e67e2d488192a63a9e6bb54be4a601a9b0b91e147144e695d76878ca68df57a85a24932ab7086bab4a1b6ffe26e8d4ae3990cd484765d0784431cbc15294616d18cdf46f1427b038b90c19db542b05bec4fbecd2961f639524759db6e23dcba55e9df79d68bd524830f05fedd78819e145481c067420905b4f85cb913c274a7e5a98237eef84aecb036ef6bfe60364f601bad89f0d8ccbb1b4c2a46ab2582f458b33eeada19a801a9264e9f880f5d7a011225c496479eb5dc822de413e34b992ed2bdf9b9bd3cac04d8c765451972357bee02373578d2814848e4712cf23bfe1ec0e005825c49af3db22fb30c6fa1d628e343e815063f1357c7b2e8e1a9d6717535c2735dd85c6cfdf84334a6bd6e38919f0e05aef +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = d4195e82403dd19a +ciphertext = 17422150ffd7d5b58b101b6ba6dcff65e234fe6efb8779db5735e74d72556fd2f46954e1a92185242782c2fec307b7f0e3f4bcc3c77f70cdf686e161904d666dfee35e5245e83101793328b31594e65144a0960598ef1a965dbce0f7b176156c05eee53e4ba1941831fb2602f0aedec1b9052d46326d6e2391836fa985bf70b058b994c99505c10a7cae6cb158609ba37a2896f13871d25288edc40eac658089b74d5d44bf9bdeff3c7cbcb511072b370ac17a0c0ca12ac6827bd5cf6b66530b79738b84529ac0d3c29da9c8ed90ac32dcd00dcc965b237c9d02e1bf08664ee18e0bfb366340b88b5099e3829d47e2d150c56cba6d324e46937d56da2aa8fa3929062aabc934c75d357ef0b5f0ac1e9fb75c6be58805ddfbcbde5539fe126001f9022c02e00b9d122befc3cae49fbffb60dddd26240603bfc0414d6c153d4025d114a4fd4f6c32c92828a475605739ca085b1180f852490404c1c823281c3dd3b38f8d9099420d36bf0331e7f836d0d02f5ea83e69319c003fb4901332a67ebbf3f37e8652fa1b459b6dc3d3645948aaf45bbda7e4ef0e580af687d0fa9dd0f5434dd3f887e8deabe1de0f2af7f77258a1d1aa39b99bb27c64337955ed77bfdd0d9896c5e0fae3b448b213282de116d7fa65f6e792391b14751c21b2c4d8a8f018ecf356205429c900e146cf9d3d92174d9133d4dd030a7cefcf07a285f37f6e88a0fc65990ee0db99735a3697bef7e6d42dbce014aa539f4e609999244ff0264984f753de4bebde2b2c8e077e67e5bacdab405680a4366a415ee06421b9f59871148f6e3430518650134a96416841e1328f8ded069c3097582b5ebe8984ed20cc3049ca4c8f05fd8423475f4ad212965d530a483af10f4406625231be0b462e5715818ff0a755ac2391799bc134e634ae33aa0d021169bb8fc9a4db5ed261a03e4bc323da56b4384b7fb75ec992c914b9597a8e308b5cb93ad7638e5337b0fc32008ca8f48c700d6a2c0260cc8958e82f3eaa3714a95e24f0fd29803ae25a24bae0e89c61e2ab0055e73391176c05575634c9216907c4555eb7a77dc96cd564 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 05ff987c +ciphertext = 9dc0247df0a46f04962abcbba2269ee4fb4434ea4badc014aa394e58666cc993e84eb2db6f9a0e1fcd9fe98c5f81ec145af05ac6be2d3623e3132fd94f0368931f820f77b705af3ab6120015c3b2791ca5524815f2bf2ab32af0b89f73e2620634ea3e1e7e6b512fc1d193de7f2c33acbf17ad2ef2e6a536c3ee86027cdad961048ceb6a2a443d712d28b5520d0360f96b586762a84c05fe4e9302037b7c57af03f0709f1a939cc1d8aea7c63408d3567f4a67f865cf5e11ddaca21c2a9d82c025d5c53d3e4fd9205101ea1d19f0d5188f8ff321a25d9d11d469daabef1d68308c8d0cb7871b72ef11394d2b6796599337fe66ae4012c0dc2aafb0496bb9a10c5cc3db06e3be7de6d7dc49b013af72318bddde0b89a3d7f661533747112e98273fc4b32248e242ff24445c9dc55fe11772fd0071106b4d1b910dcf7de5afddb2ed27d1a37a9f293a15bc003e6a6ead2afec9e544624f192f87192b5fdbe12042abc662e3b51f38da1f1ad9317aa2c3e5e93fde337b736e972068d61f040f10b89db62fd093f48eacba06098841baa7069f43ee86ce4312fedcada17b8abfc5936c26347bdf18798def1f34ca685aa3a09b97ab666a7057a6bae86313718ad972b246be37e1adabc179bd0913e16e95cc2880f4baa825cf45c2ae5cc05e83057bd9e1551d7cbd63132889e788f8103add30e807609d746537672e4c54e14c2ec04c3f53bbdb474a62f6bbe1d9b7683f6e7a9219c1319f7896d25cd3c6063edb098eaa36ccd8eb2bb6c5a4d42bd0d78056a7a1ae2f428395ff0fb06481fa46a868d6074b75aa86a2846a20c69aec62050b9e5656f78a37879940a3c6421fa86877fe13be0f29967bf508df0490762c95cfcd3319bd499a44e5ee87a2decd18fcbf31f99fb1e9746603aa008debd0b8521594eebc7e6d8e300f67757420f1b42d90822da77f357c22eaff2d7ee580878475b575f30f00d9a5b1ada21e2e306bee67569805c1ac8234847e382b58c55ecad65d9741094b97865f73f5fcea1aa872639f9ff182af815f89013bf45ad9f32b316ccc6e8f1818dcfe4abb8fb4ba142ff6 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = f59322a5e528d20728d77a5dfd400f30375ce3b58ec2405fe7ac9d3fd96ef4f668351077e19ccd5ea601ecb30f529618a85a87417744ae8766d7e608e4ea6f2b70bfc7266ac47a7f052b29d4903ea123600b4179cb561fbf5b0e43f93a3af01a4324330f307d91a51a9050c23855875f0a0dc123973434070243c08578276d011bc1358b10431613d06e19b24cf7ec0272e650eeac0f3c3015eccc96e5c30614718dad0a917596c1ed94bc5b780c48ea33c2957ce6203ec4c6b5b1bb2eec94b3fb3c7edf9b45aa062a636c744ac6cad7d28b7f5a96b2e431757c3fc769544db53da46406a968cb0c05ce706a2429f979feb8261870ae57391676194d9b07698705a2e0c6a7fe61825bc34ef9f9054068a2f868c1e355ab4ee6b8c05c3e05b41fdf9a403e9b1b371932903186a4893a94747e07fa05bac6674248c49f315cc77897da18032ee05ec570b75ea85233e49d5746c720843fcd79c7298ca6c64c16b84bce8bdb1da8c6baaa26aeaf490e3392964ea48d69d7161bb1c41c937f34ea5491b595ad1052ed64c560a57e14d844e938b4b1f57cd0b469b0da03c07a5d8c96b9c068a9ee8111fcf553c30b871b078ec82842ce035ed7240624e3cf42628ac91b722c1208bcb44f0ee9bb07f37c8ff7a2ddd21cea070f3b8202e21bc0bfdb541a663fa1486e9671a58505292246af848a8f9bd341f9095044d65e43862801e916d8683abc16009b1b35fbc26c0fda06b0aa059af045ce7318d1d6c4db9c9eafeb7a3e25270bc1a013d8686d4710b36494ae24723bd73a7555c4d6b5cc22e57a7d304362eab00108b645a210ae142c3e1790ebd278594a39260aaadba20fc6c4cacdf74033f4c8ce961941949134ba245063cf39e68384d554a6a4066a862db85b0caef3a9151236bcf786f6ec8b5c663c757262597c6f36981cf4f7031d84a45617537d958abb1393e5d92c2434b39a67c0b084a7ee709ffb +ciphertext = 92832847b6ff757e6f4d488cfd2d5b4a8c941686cc847c74d8624895e9d308faa0c261892c9d8506cd8a2a61fecaee56c0d6fb35366bc84bd6de2d2627fc48e291a86399aede50089615632d39a19169f2e14c6f6b96e4bd389f1691a681f6e33a055e3e130f1deceefcec0aac00ea6d1bc1a94fc710dba7306ae940d14293668beae04b3b4d3bd1346d7166a126dfe8dece811460bb88da9f2da4a77fd29feb179ad357a8e3beff8515ab7ee61579c6b3a847b50238142bd67b87c9f15c0276564aa9f0860f009212ca0615b89448b1474aabcb516dd2380f915d78352cc8b33a38f9896b46c5f30a571d59a51b8b6181006fd82a036eadb808fd570e3560053319c8e79c43f2c9b6bc3d4469702bb11de233f6e964e6ddb8f8be9014a3385bb8432fdc71b80111a93d95c65fc336b3260ae58d7d9f95ed6627925cee95122529e0d7e704b43999f8be75cbfe711cd840e3aa29533096d2c9c83a3c82ebe61cd64cd9aa5acbef191d0d8ff69c9be439e81324c359ca20fbebdbe96434d03b214876f75a2579def5d497fca121b5ab0be7b4c5043290ee5c0dcaba9bd97718bbbd79d71259c1cd88ed1f3a93a17175e1e66c598c506467db59a7b4325f0ca69b758ab2fd45dc380d1407a0940f8d34557811b97188f2cea0efd0b61aac8721bc6100ebfab48e805a748ba949b8f223d6efb1aff595a552c453543f5e65058841d8fdbcbd7694fec71e7cfe5403edb4dad1dc47aa3fc93dd645cd8bc182b1c885a4b39ffc7c16df6af84fb4d5997670f38336b66bb93d0089cd64e7dc998adc17b0e420bd18f7ffdb268db91e18f05423fc31189bfeff5bb8ec51847a6f9df7b34350ce969a527a80c8c13886250169b80e9b7ee3dd7cb407652a5e5cf265267904b19c2fb21c8e7d997bff424d0be7e009a38e8d95707c4148d64fb599e90a0c5c8f3516ee767d50afbf42fc573476c3731ac74ec0689b435ea930331686ae56d316348e4a49730a1dfde7d40b615cacc8efdd492ff45e7f1a83025ca61d474e5feae77d6bf069f60ac1185ea370a19e759e9029eae74628bdcfaef44392589e +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 80ac075a9a470aa559309bb9cd7670196b55765c4a57a0634224915a8c8a14b25cd480517201852e582adb9041dd87727c68461b4526be637b72e10c7e848d22528558565d22cc5d26009a06f5787c8942465686ba954cb30341c73a78c559a1bcd45ab73720ff2cc5b063846dd3c2d951c90f40286b9979c8d5b63d290b465ccb92f58e160aaee22a2d8c05403ef1a31afb61849793442311635756ca870b492673f4e243e2e46ebababbef02c2c8a06336818e8a2c4280f72b37d269643a0c33d11063f196c4463f299350c468ac288b1175b63bb6106835e41bd4d9a27cc62548594e52a62b9a916b4d75 +ciphertext = 58e99aa63e841ff694d07c36618bfb98636728cf52794540abb2e2cfbe088e1d48c34d6fc3c6a1523c5788e251b39c5ea23f97d0f873f24139fc53eb44e24a3f6fde22ea16d0aaec82e1f3eff08ef9adc27d1d84a4fb18d216525cb521a89de0e86d0cd1ca2014d82017d47bc68820be778b0e2f229686d17d4427fbe90358f92593eb22e6cfa2384c36ec450985e086a91eb47ac43e7a8975e2d439d55fe5aed162e7f9dfca77cf361b46ae4d27cf124951cd05dde9e23d8643b52af891485683694bb86efa801d4c9c4b967e837d015763c1b65af93cef79c57c08abbdf924060e3921107ccb0eb171ec0138e4312f44db6ec8c2a7ea01cec591a9e67e543753b2566647afcd5638851f8bcc8a5455e83bf0901e18c666a1380007bf6084a9554ac4f336744fbf2585dbc3c529ff7b4d03de1a06c426703ebbd8499997d669a7f9644f45cfa37e42744f365ceb642ec19e9308b5204dfc75cdb7ff587def8082cfce0ad7eb5d95a3ee5bd1c38994162fa3ba85b2387824e2cc77707444a6f6c1f5f84062e4c54fc67df3cd3c0d20a8fb01b4554c64d3d864e7308cf4a138b23642051bdfd10659a38cc8a72ca0b7446434e441e0b40ff2dcd43ee0fd16fc50272b2897c6e1089297c74fca873c3a759649459895467da068b53f303c3d131c0ed9321c429c7f560b280db2c8d8840f675239bd89b1e2839c7a897c29e9c7762a93019f8dff46ef4b30873a1ed97ff7888c33d8346250c0018962291715c886e8b8bf00f9cf266f45b17c2b6b9943dc1d4ffc3a94d344e142412527102b2a7b12413e46ba2837f6256064a5c6b7e14fb681d5ce3b722fb5f3dfbccce4b36b759ca6c9e9987b974d5e354e5549ca8baa04536febb44fe2c603b4045923485db3b4060fe7ede84be026fd281ab158c10e20a3d7fb44ae86aa3e4d0a3b9d185f567e841c2413934fb3ff8ca08aeebc0f4e0ef61f8b14a8c48823cdf7b171406b1c83048b45c731a61666b5bf316ef1ad85800cc0e902e1305500f5a26acd1ecbc908cdb788419cb5af5641c3d47ad3757d5ec425815d84876bc5c603178bb6d1f0 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = b0b8c428bd189f37ebc7828291301c763f37242f67a8f15c3b649266edec39583199c587243fe2a28e30a18620ad3852a8ed74cfdd154073265425733b55eb5a +ciphertext = 322901053c7a24e70003c0d1b215df1904c1be47e251eec673ff1344bcbbe607ad7174e457f27781002ef42ceaec721ed1551ca1ee761ea003ab7ebd5cc60537349adb68fd87319771f6803f63db4f3510aac28f2dc7acd7942734752c9899a2beb0317451fb214ae870370e1868dc69415b1e279074ebf5c04cd9c1d1592d7c1da5306c47f5bf9684dee8f724b90f0355304300e0986b234f676ffd75c2170d3e428388c3ab2e3402836bb59c2eaaa3246cfb9293dee4abf7563881cfa435b4cf915f24e103257e6daa1cfcfc1b26526b29386c058516cab764c6295c105f9c18443addda9f9e8711f7e5e03d409e6c3da46d5435b65cb25139e9d2f26a3b0e22d504b2a44505bd3c71967f8319648654c8cf27bb63479d50df471d723f4e9b61156f705c0da85b09e06692db02d13da548adf32cb26308c446a3f4ae3b831f464cec48ccbf29e0856563c1ce0d017628aa7208bb4c1a06c908926b3cdd7b21ae47ea020929fee7ba42a60a546233daa514a970d76b75ffa7ca732543fa8d6526c25a06a38ba92671b6e69167a37ac62be3af6636ebd791f4f6ade0cb7de83dd27791b9b0de21f53ed69e95802dc28377394094f68d9575b657f8f6910d49e0b2cee2cc406209e8a715fa7e9ae77831e91982e64f47b1a7ecf6ebcc40206339d1d8fb52a19d4c59c94a7b47f267236e02605fc8d81033cd3904df28a3faefa351ff744c05e72bec92fb715c31b18de8435761d131dff4b286055c117cae628ad4b5192017914c23144f3ac1a3bf30887ea558ce3a73d323ad8876de19bd047eed044c911e50a452b852d0a5194ceac4fa6236063197960c940336cfb25ae3c9741731eb3a762746b2cf8108e2dd3a63d00e23d74db7f3bae592e49668612ac1c64cdc4e4dcd70b6bdc2d9ef1af7061c1554977c698258fb26665a7c86bd1761cd668aafd878267b180d0f171b808e53a6f9f2f8d45a979c193f41f9b7eaf1a9a422b74dfdee3eabe21a29ece70b28c10061566f760155cd2f683917bdbe8aebbfd508d95a3047891c40a529c219332e32e25290f077c7d0daed33503fd27df2 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = ecaa4dfb879e2a56ee +ciphertext = 2dc947711c0ccaa1ed7bf4b1d4bf5fe205f9c6a8996cc22bb1850d609f11481f1ab8b29f0b7071cbc288800d50177974d1d2b38cd2ae1d2bb98eba230a40b74fbacacf140276cefadbfac8509d02bb2e683d28d436065231adbe0d9b708f2ada6f05abec50e2ed2c66db8b567240ae193b0088409ad48816764807be65708abefd23a75ed5b8a260be7b8e61dba46829b1e3fc53109bc96ecb36d7d6b628c41681603ae32cbf5e4b77591ad6e8dcccc0dfdf35ef209a737818cecd9812a8561f40525443a020effec7bfac4b66b062267f5926a69d2c501719f95e5f0889ad27485f85dd46dc04f15671dd6eabc926d2d2e52cc29e7edd7d68de800d36d21fc6615fc93cb9b2e78d2b747888188ef7ab9fed3350621a8cf527f8aab051a04d32363e202fe2ff59d01de2c0d15d4da4e5a1282e06d2387ee0a25eea4baf98e8a7a8a720bc6b8c25f61729440128790b17f339b4974d7f3f09fd815c84181aa83def65e49c5ffa63b31089293aca8c42250567a6ab386e1dd8070a8ef3c496a3d859e9ff955a51818a52ae53a2c06b7609bad6ee3b6d384d6ac6db0ae440db282b83690260be5cebaabf8fcf6fd90d566aafeebe40c707bc4d90a2067e89c22428f161b861d67117d196612d7ab1aaad6222bb6fcb5753002b810fcb0c4f58ad1c3ae822b13b5201180b7bada0f91467a245f9566f9f4ac03471154e8c66105c1b7d8f2a97b2805d01a91ac8dee3b96155a2e30db00faaccca6e56f41418cf3cfe701b6b3a14a9c1d83aadc400111a5238e47978b5fd67636c0710e5c6fb0d6ea406fb48c31c645aa149a55829891209d7fcec2c50a6fb754f0149d0d076bb3d83e03ca276533a8a6dd318797fbb9d1aec78de75f2f16b5575b9a876126d220fb01ef9eabd50fc7a9aa4dc3943dc462fbfdc9b39bbac60eb7b8b564cfc17439dcedece938894df11a742528284ba55f86e12d21da4dd432615fe29dd6b86a0cbf3d8048af5d3615b957d992c5a3da067ef964ca478edbb8af96d2d1d6220713ee29c25ab9a11acebbe96b7869b848cc825e913392fcc392729e3744f8a59b08a1e +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = c8abb9a8f0d1fdd822031b2da75dc3 +ciphertext = 266b6d75dc3ce5f50df6a8c30959e8bf52105a84f510197ba4e4a9099f3a0395271776057940c5614df0680e868fc3479c8a3d1675e79dd5ec0a25d587a57504e736b496e4cdc1e406f30fe0ad2c9e6afebe5d11e0766f8bc66e43565b63153184d3780392274f5d58fb566d614232e349c9c321cd97a3590e4b093b9f4ea85be5d733832d2c93f07a2f091e35ab947bc97d707c9cf88d81b0dfa80eab6b06ef9aa6133d07b001f2c02e7ce3ed6349f745f42b91a4871ba206b7a76c54e9f4e09236cffa8211f1616bbe4091613af490d5d0f687763b1369bcf10b854fad20057c7d1cdb4a5a087910c9e131e12a11c2b77c6ac7ca44675c904d3883c37b6e361f3c5f4caa8bededab2f8951195e3dfa1b0a4f27beae20de5668cccf6a69a4999dd717eaf25e3822386b85bfce064efb3dca290707e39c61dcedcf0f68ff27b64408d342ae73ab808ecfb1a4ad33db447a5cf313714442271763a71bd5aebbb4879d103187337e5d15ef8c1a07ad3173361a6435a129f2c962806484267b87f3059d28e0035a417ec98c9033c706a56fe7a56c8d329fad649d724e4cebc9fe0680c7ef309c5090785482f71f3b4a61c061b20608e9558a43a260a753687dcd68200038215a117f20f5bcad6e3ebc6805c80ad4cd87d0602a1993573253ba94dc3ffb833e09713da8188b5394a5bff7c0255baad3fb08ee7b94f0d02d991dea366899e68dd8b12fe263f1a3431df54feb261bfd5a3b38ab256ab094d83e53299552d91c7541d9496501edd03452abb0315d7c477ed545ce2a4e2ac47d1fd3527a38beeb6d5eb3ee173d09e6aabe63ecbbc2bad8d07982e1b5f3a61c0548fe1e07ed546c6228f408085e04f64db55c0cc11ec726d298bcb45d9ad3fa252d281c0f50326ca6533e46f124c2eb97d8a6e4f3be30e14e3e965aa647bd722c98f49c96278ce145c06bfc7b9a6ca89f700495b988e5fcf30fae9dda91d3ba8d7d54da1f1325e8c964a0cc4f39d70307dd639f2fd1472fd48949dbbff6c7fdf956bc5604a203305b2e70297830c375dfd5d872a0e333f041fc07b8abef97c6316823c8cc +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = b7b42ecaf25ee8a5b8961b82fe7aa0a4224a3e820cb0d742d2f290c0aa8846b6216f7162ed239a773718602357ded4cd80d9234be0c1e1ebc07af87c468599eb872473e1a3b8f862533c4a61533fb59b5043249f724a861e283d6ebc74ecea12e2aa0e0d1c6505f94b9d8b9ce603c3d4fc4f84e77a33b34589377300d03e155b04eb785a7e691b615b4ebe1533e126440296152f7186d1256aa10419d26a2b76da62c2c17201604d1f34c005f8126041055c8bb31020bb42cabed09694dc81056fa3cda9b3c659f43893dabd87659cebd168a095745656ad7637139e787af85016a2480a83396456866664eaabdf2799b21676d07c5337563640d1bab60465a5e06e78b9039aa95544528e3b2443fd9491e8cc6358a3a57aec07b1b24185e6321d627d76c1420fb9a6fdab03f570b030592ca2c1341d0680d9c8a528a3a0c8f483655ba9a8b959770052ac957d6f28c803cb3d2fe5334793b6eaac9e64c45173d35945a84bb1db4e6a96baf16a239f4980d36b7b2190547ef9ba232b16bb06372041a9b6fca4f3222341d02d01529362a74bff1654d2632d4d7607917b1adc29824af52f4f613126234ea71008e3d0238281245772c68edc8a69db661ec85ff45b213cecb5c2e69cdc3730a8f42f941c2e7369c8dd359880344ac2c50b6807a7c9d73eb4a0b49884351c2b47814b0619f119608c615c804d99932c848070b6caac17353ae2797e23accce251c3b3b19576592d09aa13d3558b402574d5d9303f5a4ab7bb96d873b6aaf73f194989624b12d1e0a58e5913aa76619d4aae53c13bdd515aa11a118f344ea60c5d40f7824f686c7e9830df5c732f9c3b +ciphertext = 998076beaf224aaf6699432191b6e463423cb2687c32305c512bd67cf67f59b40bb1983a3bfc34b931b2688762d858f595f3e188f11a85487aab55b59501f4554d9413865026e23bbfb35bba16b9b92458db7fc56fafa701de301dea36b9defbf73fafc44b7bd0327f683eb57300c7c79386c4b239345d3ba30807088f202d685e33693db29d7bca9e3442a5f6853955652ac23e93515b16ae853abda0c178c0f8cc54b19cd621081026c8630d0eaefcef7800705272e276b2274232010fc57d4a1e5f7a5c78afbb69126627c71cc8979304ac2c4b6d3b91c1a87e319adfae6ce1b7e04b96c17b7b0a874506f424e8d1885796c890f329ecb352a0d03f726dfc6e6e86f431017b89e4c433dc652682e109eba69795484158dd4116d9da11274309a686c122d03d50e632b7bc934350c5bcc970b06fca9ad01ec375632f7c2de4037e8f64fbcb0ffd9415ec8d2fd31980a1b8fb8a9ff13d3a5ed05578577bb0b26769d8b7ac9ae681551fe0c00fa6db41e004f51e25c6f2599a042e514398943c0c749705d0da54d2ca5c9dc19363e9d081394aad7845521d88ed4002bc912afe2299856c42b7d40a4a93176082e794150b3862e6c30c7e8bd085cae45792d46450bd6bc2da17689091f70463a2c5045fdcbf817c6437a15e60ea352cac90ca7f7fa6c73391d53d906dc76c8ac43d89b4b0ab31d810850a6476c925febb8c275bef819be80aae668884631c9bcc3a39febd9cf16fbba0d69d059f5e11cc44952497cd18c17b3be14a82cd96eba3bcc459369bf8c033a9f97e999fb784b8b9aaf0a17f011ce91e5724338c7dfd7fc6817a8ed791c01596dd1567c9e0b05224f8f0e1dd7b9b79dbb79acd9de3832a9abe0e99fde83a0cf42cf2a98bd4a24f214fed509e43c09348e18f91f5f18a5ff435ed9d163522c6c4fdd070e659504f23d654b060ddb0834d2f25f248be37ed33eeade92c8389ee026c9be4957bbab06c47b895a4318864527b59478aa2f0937b93cdd67ea01070a0e858ccbd2edadb0c17848e32362796f304a218a8f652b66203b2058ac0a83f452a6faf6e8f738d5c78a6 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 27 +ciphertext = 138c460f7832b3e2c613b52a7819f36cdf58312e17b323bebb2a05b5d25aaa343b58dbdcad7cf7a3e8079ce916f6996a92239c98a0dabc04414a247c46bf6f9b0de23785d958fc2e617c5362af117755929b946b2841f98c15dc6e5555ccc6c06b4ad318934d2fdfc6b0ec746548ee102a25a1a24c82bc25d7e60c990949f068fd6ae7426dc9bb341f4a7d29e805329e603a761905235a22445c61ddf19e4ee2c4b7beea0455bdc3a393e3fb1ab29f9b62b77d318500ed0c3307976727704af52e694528bee9d049e434e1412062fe8e592e8b11df65561eea05dea3f2b7196cab9fe9d78a95a2a3f5ee133aa2e94621881f273e33d2ced9171f0dc7575646eee3dd4ff13c0faba98c1a5aa9493833ff6a844c8c5c3f2f5f02e9f4c69cc8b0315b43834d60b36c624d21a46752f852fbfddede0c4e820767795a2a13ddb5772a995a5617efae1d4fa20be515b6d95edf733b7d9106e9dc4d98535694e3f5bd1b79724390451133523115f3fd75f5b5621d1ad74ebe2e5283a0942f064e4ee31a5682784460d89c40e32245e943aece6c3056c033f8e978a7223c7bd3b992d521fa02f88e980d4328119408c7667a2f21446c3d5846aee51671f42983b0973cea636dd00cbc309a0ccabc2bdb3d6e7ba210b652cd1e8a277597c02f6c810b951a42d9d001220b30d22c0a7c2b12244fb6f555ad68ee7bffdfe908aba15a6494d1e93edb6ab1e90115c18dad6f3ed213f67e5b53645a2c47f4d4cb28757b5c28d364266f0daefce94c726cb52c8d13d3b2f72e1bca16ff1a7ee8a758c035b825cb86feb58257fe42fae405a161c7d17c163640e85cb79e72450f4d9cfabdf04516c8065b24104bd096f89061b0093f1a115982f7ddd3cc4e2ccce5339ced81ca45c67bdb1d7448b20be87d56adf39dae1c7ba1961f33d37ed7efa4ff17881ec0898b34a7fabf1a9082ab06ffb516007cff3fa65018841663314d971f3add414ce622cbb17e1c975bb68e6cf6c8869a2e55e8bb7701f6c9963524681ed9096ec3de8402a08dc404293cb44f3358278f2b615e6e755a11c17858c5a25765741ed96f +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 721744ca4a830525cacd638afd833d721ac93ae448ddd99ffcfc194e597bf8d08ff9464493547c25437f346ca9794ab3629a5be2d23418c05b6ac37cce48ba1428406cb2b8f741cabac0b14f237566dcc01e341a71e53076ba08919c3febe64a455876b24b6651a146d0888fb8153179099358a8a70d2b17d73cc612f01f0f16b5faa989f43266362715466a0cc7aba9216032c110329174164b3a1a471c53ff0453acc408f879c4961325a951c4075c015a6b3447984b97496a3c967ffa1573540931bef27e891329315cb53de4c4fce8b7d51324d629b7d0e3bdd58671e63a838ad5629ecc1ae6855e7b703937a05c7674537d2a54a3481cf7412e1a155cee7aa418069436f338eef82a6f9a6bd9c09a5da7588ec9720bb7b05cd12894e569a4319aae9609c8074c490026c2335b2e92b14dc960cee370d9b22964b664df738510b1602c994c4c31889f54b0adf07645bc6d705b0158001edf51bc1118a838834127e55d3e416460868ef29a7756ec7c14a283c0342b05b860dc45990d32a85c21ac3f5412c7cc216cea2b3d0a24c48c6580ab8b4c6bc23de09ae8a762e460b5ad625c63e322e58b380161cb65d28deb10213ae4368d0a39ea7959cc04155951b8dd644e661c17d38cb2ab1c05e4c9bc114b205d84a7a8586595f706a905576d1cca594c08a5eb3dea8c7644ac4d45969809d3079673b6a15576c273600b02982a3343772b2765885e811c2e35b08860e487f638b2c9a45c163ba0fd017d8f199a66da7579a548a4416aa1420022412a2cabb293ea25e9ab12511bbc431002cbc5a8442795d79aa6cea81f44b357534c64b9c7ace2a03e990c642d0aab8235b37b6a99330cb82f004be27345e553566c88b29975aaeeecbbb0b26a3df9cb8420c62aea2eaa625c50368dc86376c1335e3b2566b11b8e9aa781062a594aaabd76b2aadff1988511c7698a0f625cabff47ab20f07374d21a4267a6e214a4e3954f301608518768207223e3fac00b58351d636edc11c7b5f803f8975d2e6c72128153ce94c6196723a58735516b8c559376eb1a244b7464a97172446373de7836cce0c1166ab33b33b4e8009f7ae200348a1e56f96646b412f644b90c58cb3dba2245d270c4d982f7a22ea8325e74a26f75d11bae47955e697b8fa89904a5963ccca6bdf0a7f976773da73908a8488b7ca2245b844ed6c417791f635c9ab9b409fa5598ef4760189a9863a78da3c07deac26ec04b45c9c8717955ab4291804efbb81a6c619677be32987a21a571c21c38b6ea8538f0129732bdbc46086fd748ee7ac21607a9a45c12e8928c75bb41bf00aefd579d816c4aa9e91b4f5b27a14c033ba66cbdfaafcf4b0cb691916e2019e033c1173c992fd9812b57be845c627a054d695c4899d3b781f231bda089f6b52152d64525b6201f33202a5a60bf53681e038997ea5e6e1aaf8e477f0c50236cdc848693be79a66b68429f4286ca2636867958cb7518068f0ac0cc361cfa288e737357220ab57795b4285873e619a0400c7e7f75ac5f2818536cafffbc9f1b6bcab794a72bc6cdbcb37f9aa31d34045452286ef9e6bd165584795a1375b1a2ff17afaa5b1a1030565f918716da21110313672062178bc5bb1135989bb5536b7433637cf7f655283872e8d4825be5347d31ad9c472ac6d81f75abc02935864632bd26f605ef7327ac0077f2861d724c949af35548d251b97943f29bb813d175e646385ad58408b212ef2ac78d65c065994a04468cb55622f96a78f099c256d1cd45f78efa96b6806ac54d68ad8ea7b4412c0d59e9a20e922dd1422ea3693bc5bb620c69655a91847d28094b44649343b488a61adb4037faac46268161d4700889323c2d1267d731ab50dab967490660578dc057511ac09f408325b4f0b666a012b92003e698b873c04b9db49b2684951ea22185356c54f62bb9b78d2dc6714a41697b5b3a0e68b052f74253418185b96ffe4a40cae3c2e714ba7f03cbd5083b568a7b3d7cad1e0a590088733b1b2b53839bd662088cf724d242091e783ead0203e41c8024bc38dfb19a8ba42361889c6c691ad95a5255a97c3f7a4868875489d087d49a99a2e59ed567730289a65cd20900917677562f0497731568cd9b5283da7476e05b81235a50ebba1b229ba956ec75bf51491e0272a8d0f59b07b4c569e4114bc6122934064691131fd6943096cda7ebe854538824001a12712594ca34e9841fe0b8eef91cffae6cd5d848646fd0e6bfe11f473a2f720f1e4c1cdbda8c69df545ba9f2c9f598152ee8f04241f48500 +ciphertext = f3ccff751193635befc1bd254ec1cad649dda90135d08df1794f6c438ec261a1a20a9ef5d99225e22314c602ea16f2084a94ed2ec4a7b6c34dc2280bf39300430d1e785112db9a448198322a4e3cc4ffd2a3b571d146ad6baf69c998276cf372e940d5cc163e6f25d27fe25b63e4912367c37af551e592e42b70671b7dc5a7c1fd038a65f087e3e3aaac4392bb1964a8a33e08e543cd0ad6c5aa3994ed2f8a02f908cebda2b388c3b271c3cc225159b7d9a554deba9557d3c2fa3e1c3d91eb8e360b84f57010eab397dfb8963fe3d2d376eb54ee5822fb373b62f0fcab7c8ca6e331852d844f4a041b67a522a4a9abde3557f4870fff66de195ad6f5fa3cec4bffd6ef1fae578ae27e4e43267cdf8ae48042f1d7214dfb28a6268efde55e1bf7f9affaee0da1fa3c6a6ec684fb83ba59b09632af443292abdc1cf16aec0eec21ac0c08 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 4294c8f4a57ed9f9c6a8c9ae93794f0321805b569c307b7deeb9740e224ee730b29481ab620c8f1b159d876156c298b0bce46f52c834b656645e2b7aa7f8388bd47735fc5a0b9399119b98b7bbb55e6c5819d86aa072bd88f4b11f347229597f3e58bbe3e1517b1cb324751e9d91ade6446ad1147c08cbb91c0031658c09454739b113cc79909ff6349c5de3a4fd6c67655ace3e6433abc24cf890ad1e011292a7abe9b76a797657329b2889138a815c72fa49c9b7062240984e6fc80b39c8899c086cd8c86f7cf200a3433746463f30d9c98bbac9ab495803311e0de903e8c0a61c71c2316963185892125776c667adf7591770c3b06b9b1d6018a227b89990b202fec00b1a7733221701c50708592081d181b2a1323568431b5d24699cd9a85e5963854b567a798ac67c97b1cb576266b3e02b8b3da25598d7880bd9704f9cacb286c369641136b2043796377443795419c0c0a32cc436436a6c2339a78a7c42771f6691848290d31201861bcd1e7170545aaeb96b32e74c0ac694a34d134a0f9bbef281c1ac07c9177297676bad21d61c55347f3de26086638aed432ccd57329b291b40647ad25932a2b7bbac81200e9a3d8b2511fbca525583aa5f40826d0a76a14713f53343e6799df633a5fec15d7025653f75c04d995c05183d792451d5b7a525858d631a7ffc20ccfbc2ad16ab2d393c33d4890099e68b980bc1718a970bda598f2cc7d763797bc389b4c71fa745462e9468b3b175aa4700515823e946c1f5a49162b500a9f859d8f420b92844f68b1bbbe3b0b96148778997f0624693253b86c0c36c4a2fc3d6816cb9bd3be732f2d28916284237000e6f464133497690b55e8621be5ba6ab32f78fe3d5761e5497ea952ed1740391b237f2886bef53c6e1083f88898f9099bd7ab46884023b82d031d62a76e38063c8eb213204bbd705a4a24bc4ea72b00f08832264c6deb5a6532464fc0c8353f1aefaa9cf54c7042259607374ccd1d648dbdcb649451698f8c5a2b6bc4db280226661938123dfbb2444f72f60e6770e64806eb273d0568e76716892db8f49473e35f34fb61c7ffad78b9d621e88110e7318b791758c67ac0727308ded638c7c7676ab5833bd276466d37584600ebef9b286d9cf6f275b965c43b177ce81f2008a2b406cd61862cc5e1789316ae22e0f8825bb51b7010c0e1800a9d24553e52257edb59038400dff772c1c20becd0ac92f756a3a143556735e99bb9096893b619a746142bec7129742335e6bec3de04a1ace8abbb3a5a67ba01034bb951ab77468d51f86a7527d13019645c0cb686e6b88a40ad08ea10404c6e83dad1c07d7786017b1bc95e43760319cc6822b4e938176f8abda834d124b88af15116d5a1494169002265cd1531fba1b4538261427b7c8c7089c28538923e90a39e79e61dabc42c8afd385c041eb05f2a25977508e06fc0e1a828aaa89ca67509f05c53d52b839eb02cc02647408b385f0e405e0790867cc621a9c030f684155d8686a1c0eb0ecc0707a6d36f424aff134a11a6dce03b45226c5ba93a231293b5c9c34dde51aea8b3e7b436b4d53524ef4aba6811259a8948458b460880115968497c69d7e719a4ac899054a871734b222b594f70ba9b55b916e098f78965ff542263cd5555eaa9f24624bbfc3a243e06a3cc21830978d5494c1d5c968b20bbd58a86483d4cf8775190c383d4e1c33254b14b2bba7736c1d6e358104d59e96618026370b3628a913f56ae1c76f09a67778720b3792baf178b148217f6b56032ef6cdc91c6a286a4729c43865490529d9bca0a0649cf173577153ff2c40fd549b6dbc52afeb13143a19564c048b32c4527280db378b74e47a17eb4309e8880b8ab91dc2aaf7b001cd61ba646c39a4986f4bbccf26299106e24ad57066d57c6624a38ab2dc693be078bf16a8c3f770ce579254685045097a1d393b78d5bbe7296f7f95bead2a19feb5038dc4ca3e70b8a1eaa206b28a98eacfe6b81c5d97ab00125504304040d5c8bbe7a3748b4cfecb216dd9b5735c624fe063d92b7f0131cafffab5f39b16a9c55f99395575919087c015feab4e8fe38f7c531ad7b1569f5c97d2929d6ed9794343b7db18c9f85ac37ffa5b59502b53242016350082f5531a1b9ab8717031c88a48667044930ca3b91694e71db5379449fa6e815c3047f2511ded01d2b7c0a414a0912eea2113b05822f79d35c5ac32e1cb1254aa2ece442ba8ee9a83bc2444b2819fa69be9d7914a0b6eb94a085ed9d1641932a245265d8f32222deffe5eb9d53225aa8cc27b +ciphertext = 169a8072fe0a332bea9a649dab6befbdcd71042effe68f66eb4b7cccd6c24f2242dde38d71ab90afd6bbee73f75da87d24c69b642b4fe41e8d3cace4bbe08a38440a7e1b4cfdc0ad672a00390109162e2e140f991ae9a477eaa2b773c26e77b2ca5e9023c3cd717b3b64c2b0320bf3d8b88bb6ea6811dba42c7a327988 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = a9100a86cab1e0312ff8e15cf5ba7e3cd90d5cdb66571691184078b6849323e46aecf7709de322e2356737ba30205985739c53c4905d0084cb2755c95fd331311927a7ccaa25f6943a677364634a426c5432838445723aab2009f9269987b33ca8513cc862a6d6734963d13035d53ef02c4fe2eca1526ac9a87816e58c8516e1092859707afba598fa139bf109c6d959da4325fee63406e0912de91b395ca104c11adc67a724b65515c3aa9d7bcfb455b26b700f4762ce4d80af5f0a13fbd7bdcc9722cd6aad476c58be3556a3b217d4dc8c7e958e849b4d19a68d6af7543ed13c4dc17e128c6e4eb4abe043bde4945fca65cddcc0587581592b26666ac24471e19a60aa1ceb1c476350000fc49fc7b10d35992a2ba016759375235bb4ffe7133c63be38e0b880bab57fa7541a967e1f67b0b2cb1fb69c6e74a11db7755892daae75667a0663cd863456d93c2764058fd91c2f6eba69d92b5c5006c99f2c2ab73791d8309c864722bb382cd1b0c71188079709c55792107b52b049d95937ac9f7427c2553baba0e4551284cc3d9205429935889515a1fabc6c530c96470fc2b97dea80684bd23b3a16b69a5b4e36552a53b51ece9a8f8ca78fc637b1def9b1651834e42057058c98ac19ce4c740e29b4776869a43350bb96c19021d5b777d32a2dfa227240cc5d421fa1ca8b3c6cb4363838b0761c94c503aedb18e727b7d73357c067a653430c0ff730a621044b67b6a64302795b656d497f9e171a9429433977cd66b1cc9b1868cce48d914705fb6220d919a984cc2ce499125b9a1756ac0261669570a39a67076e92a1899b50aac9034e87176204442d298a7c991cc98b620cbee84a61e0786bf655d3d20632da3ae6d68d64006f682b7a0ef068e3863b8922690d08bab328a7e6286819917e22a6b13d18cf0da23239ac55869b95bb66b1a10430c52c1c4f82268699c25bf74e94dca6a38498b070160e059badeb62ca126dbb44591c38be4f707fa13bb5c1721f061574beec2945c4a2c032916afbbd87654b0063b8e695803dc6aade937f07b953a2b60c4b66bfd7799f11c1c576e7517089383deb8e8499b8b7a02f8a435ab71314bc354daeb1a178069bebb3b3b50512fcf48dda991dd9d2811ba4520a30a8218139b8dcb43c4a90c91422b69c23cfc3bf7b5b0dc414732a0787942c7dd956130a658c5d9546880ab2fcfbb91513385e89638d41345ff6c95a8967925c5b4381a279a06745e98656d7a130693a38bab936d140525b85008620ffa14fe30ab1298785bfb64ded15cf21802f0ba476c244094e4aabdcab1c4a280ae06b548e6a5ad0a4108ce31059f22400d79998b78a2baa5674837d32c92273f70f56516865277097c611c7aabb96d5b87dd7a49e21c85ab23c202a15a65329e0f4ca1a9bc372914c0d4833121243d934662af671252a9de91882567a6f3e7052f12c35321b01dc7b3397875fdee1c811d31b56eb42b3858779040a19c82f87cb3819d63c226890977152b1087ba88b2b90e0810925831d7c6745eba9ff895fc4094f9018240290ba06ea4cfcc75d0a86cb141675d9f9acf438ccc361817cb32792e093d2ea652fd87970dac34b12c8ed6a7269bc332a6289800a8c1a98a97cd84f14cbcc13a72ef395c8a80799a9381f5a8081caa13dac3474f4e324f06197d2124ef4683edb092ff392b1f172c7f31503ea755b28b37b208b77f8067d9d8a7c3824057c1775e6907acd688d25655598c2cd88284153b715efb92211ac6f2452403b7b18cd0b2ad684cc6e251735379ba4c582631a664874c4b2c6205c64cf6cc42b453caeeea2bbb95a900d041b1412b48da5c9495b26e0800613e18328852aa4eb65bc3581b4d765a41855b694ccefb3cac816057dab450cd498ba8b4a5f9833d9a884dca3a08aaa9168d51a6543b381399785e4642b5ab1d49b6407075c048c6e4811ad19356cc245379ffa0b69d99441c74c50406ddbe37175885a8f42929361919dbbcb2ff207d09ace0cfa47485062943524df1a0fda60626f7b43ad8348480ab8dea04d655345e7ec1ad07419b335c2eca2c43dd133a8855d9c6a2d1c75c933f2a9bceb3186579f398158721b76fd1598bd971b9565105e611a42eb22a32c17ef1a7d7f0038ccc126b89a35269959938398109c74f12e3caab7d00065058a0e6808afe3cef5edee657a4eff89193bfdbecc54951190839899e3208ee43eb1cdf6107346ec110c340b4b0d92a84a1e1a20a23a6cde017aafb8d57591b8fdfa5745e997b9cdbc90d464b2c12983c31d1bd7a4 +ciphertext = 20b23edee174bd54894734f7df63020c05486c5bdcf81eef2bba5027949f423cbf93e8f8a9a09394f2498f9041f1799bf29c122af5363116a59f9ce5d994d1e1d398e360eb921cd4c87f3aa17f87c867fbff682ec63450a15d2d1546a693dc74027762a5274a1b3aa0274867ca37bd03c92b7f810ce72aef4aeb5cbbb91461f9df02e290dd62c9f6bf2ab4b0dca7cb116698bb75fa7e90c3415a93f721f5559a2cffb6a11b2fc51f9ea5a8018ceb8a05718ddf7baad70ed6bd6e8cf985f525e509737c74abf5a191387ae51bddf9a85b3eb1785240e3c07a1fa36664404e1760960f4a3ecf41b19b70 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 08521f7ef2c5d1f72afde6c83133779373b9e7d5161e54b001d3298af2aecd461eb8d4bf8f099662c9c5f0ab6d0689817284725429585072447a7530319ba86c8c1018530f29ba866e298bf3d4b1fdc34f2ae204c9f99551fc4f8901c3e9a7b3b6497e44f2ca5e54acc0702d54d832a8b637b550ba39408e497ba5b6f106cd1c357491a2852abae4439513a6a03476259fd329c202214c158753b1c1d78055f6473898a633f4cc79fc335857e07c83c326cae9902ff0405970654131c60fa617610b76ea704fcaf9bbec493efe7988aae0b49fb41a65c16ba0f0174cf082fc7470bb75b7a8336169ea1a0ff121b86752db6906909305848b215777123a89c0a4f687ead35fb73b7ec9822c61625801695c11808a23b872c2551310349239951437e26fd854cd11f835e16805f17650c1855359e07b91149102c96a7e405819e099c2880314076f43716e803926ff921894d22a94a6ab6f944a2ac802f585c2f705a004e626772b69228b0e6df051b48b63d8f5820ec318f97152837388ecc3919df0c0ff806a6938b1e1db431800ca4770c7cc889e132a492dc3ca9b0a2904d28b264a18b59b8cdda8045d2081c95c3291686bc75235c6a379fef83573f39f710552b45aae2d7636f885b7e5d3b890044be5d162a2624b801a93b38743d19c99eb37985976a0fcf681778312255abccb2b326d1650bf7c20e78c1347583a18148a0409bf0fe555af6a41190686f405c46fa3a5258bc1d2c573a5894d7f457e7b122fbb62aba73b38d44c415b84c272c56eab5773df2c8166d98c48b5c451d913591090782c40fb10296c91c273a368f9c72e3168217aba4c4c73280a708c46b66c237a462af824ac4b40f89ca7df06500a473078f689d23b3f5d4c7272e91ab94a943e718b5eb13cd5e801f53443c3f315118acecf102e21111166cb93aa3352e2fc28049938a0784f99a559c49c026167a2a58bceb6bba9df6bc74e8c69d0848279a7a346cb5b603a3dac8273c3148fa3a674d18ba507d479a626b364fc9c06e5918e5cc0833b6eff104b209a8721376b9a3b11b7818af679b65a80202fa7a5be304482ec9718416dbe0814821813d915be4bf816d8d05783429e4eca3ad4785ea364132a11a55cab1a7cfa00a6ea5fc61173c848ac7a539e0f300b7730701d5b4842c8b996323f66635aa3699dacec0a5a7755f08859517b60c7f2120a9c42b8779efeb45e60238ddd37b24a47296edc35e9ea4028371dd7eb4df1a5b0b9d28b12812d8ce89fa49bb20f48347fa6b153e9025f0b13b5d63cb4ab3ed94776b9ea0d4b169c3a4749f55b4275182797c8c3ea73ca98ec08c0f35e428a01c677bebdcb6ab7b7975c222f17402299d50b339721ad02064fec3d4625a201586486b41ac0facf36394ae9761288a53c27f967ac2a876244bac995562e42b2fc9259255c758a127f0ba092cf072da3a7be0dd457dbf6837cabb42606826eea0571c819a8c402305300fcac5b8b10aae0c4c118bcbecf66b155d023f3dab684db7bb140188c8649082237435cadfb08b43c142e7d38c2e3b702b5e1bcbd10aa4d434158667cd942146274669d227cbf211846514f28f3715a9c9628e066b475310eb58588f17750a7b8653941ad4923b9223fe11882bafc6d517810ab39578e6465e8b41cab9636a0fa83527336005309a8dca1ecf3bbef120dd81cce9314751d40c099d3054099384c2bac135c02e494bca2c13c03d0c7f3dc53a55b0869871406238ee6f6ba9e5883bf05892183013153515b1a0fcb1168ac251c7f34759256b02f3abff9f74085142506e7c4aca15a39e4cde1c2a65672af0592b7e86c5d83aa28b40728b5f50ccdd13a6c7906e7b183363a650fd47989071027a70f391264082c10f7a969c7f71eca1149b73554457bc0869b13ef14b15aa97e2da02da043238876c4b9839d54a31a0e1c9f3e57290c1a1c93f9cf9ad89254346f85e816c4a31daf0c7f91970b9d33c9521bb8ebba19ffd71ff79623df1496684901409caf3b7c03eba70c6f7332f96043db41a57d97a76a071e43584fbc864120d48d0914c60f266f7d4439a52669251c409f39a4f32c0a1a841d4e8643bf0c9b82c1ac7d5a47f5192a35362c7ae02fa6d36cad9980530a697ad841d9913bdac6861c79cd3b5911bc5703f0268673c76e87750861dce9df773d97de44140f6d3e3a2371d85ff0fc2ddbc0c0c0b167062fdf4851cdd9697e429d2acd09becd30af64f8f58de3603abbfbda0134321c7d3345917739b0d0e67411b2fc071d164aef1cf5e6644c15d7 +ciphertext = 52bc +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 51059fd151b65afcb290d549cf62bc908925db573065da8c5a6c22b59a820703a779accd97a4cf0afc0f47103cbc84a5323a5fd7773c9eea2a4f911b947445b1d61423337ba5f0c5280a50319aa083320160117f1c00701e7499ace95e4e33a430489b16bb225798aa7158ad8b47a39e0615748194b0389667f99ee8f65e86e56f7e564a7cc99e688004c2b96ee7686acfe72a46a7724a85bad0e66913097faa7156ff3bb8bc64a2f865741689b8aa8c1ab3ba313e327213d59adaa47b791159eb05b063a4aac4ea21799988a7973942493feed1cb02902b20dac0d4c7062e8c75e0f037dd42b6d6cb7087463500ecba3a0260f4c5ac2a232e81e65f887b51d3927119f11be14502b851044fba40db0634d0025daaba2cbbf9b513a8377872775b596acd79218c372bcba25e9fe23463d47d38a69f04059270b2200eabadfe257d6fa74cf810aa93127492425973f9bbbd819891a7bb1374a64b19200cc6739d78ce87358828e61a98d358acfc531b27a001813599a5976225c12f540f47699fbc3b6a7f70b2d3255b47807e4f5847aa0866e6d43079fc3de885327c0c86ecf1b4eab9455256b6a355307a950fc8317b9c7830c4734600a339708501cf97ababd70b8838b8dc208501f2014db5c2bf931361d649b183109dfc73bc5b290e2790ed4533e1359549b03a1ee20f2f6185d1b809daa57de1419e18783d0c937361f684d2c292d6e1cca9fb76c32a2d02872ce7cc6d0527ce03f196cbe6a8c9f5b908f4321b5c68d9c085c4b2936a6aac7ff7b6a100981dc86b81f0318ea1be689894a15cacbf9906ecf6416d4c8b6cc73c7e598779f4698f65a301b60c1b873453f55602d146917628d48b28cc6c93c7d93988c09c1a9b56606922ca383d375236cc15baa0acb7fa914228d4cf8186adad55489f220663f12e335b31eec8bdb1418c0c3357f2030bc337c3fcf0088af23196967c9bc39ff5b80d149107e460c110d6b7481897fc2724443027430ca18864325cb7581063774e10097322a48f333c4b604e4ff412ff044412d1555cb51e95509aebb37098172182246d23a34e8c1c16fc965f195688c7fab5ab9b1c3e3097ad065e307c33797000d1f830c334b28b001897554a55b0019bc79361d2945ffa958df209bfc478df78467e0074a2820bb783ce3914225a59048b7998b3c1a98e3bbd47223bfdab23e0c791bdc71f7864714cb2c7427453f6ac9d62ea22f5d476c468428fa3abea797567cc0056b014da889cf70c01e9fb44eb9858430678775315f0c291a50171b55baa34298d23a34a6ba890caa4adee06511ff8301c19c497dcc0f6f8148d84a554c86f2dab2a1611bc7a8c8cf93bb64c61025b5c1d175829bcaa5d29c917c82bc4415c8cfae10e44dbb32524bdbd3560f3a1a6e0b0a662494c2207bc21b873b11994c429717a975e3fe3288236cc1aac942091cbba22c87db1423f21846651b52007b68922b6d3816131a22cc939af7cab02c570b4fbe23dae63926f9c0b50198e59661c690447f4d300d7f3825533095f81802e625695b71ed6e2b512a14a65f856977993ee2210e05a318726b55dd90c4eab8c85f89a7f00387b2c9a6f169bd6f042f3443309f5aed30242f0dc7ba2e13cf04a219fe9374dccaaa6d0222590cd579b00b87a00eed80a80097efa84cdbfe2a382ea79ced91ddd511648b3bf0923b05ac42176a71895a73c4eb3a972754d03209a58d1a9c82a544016260ecc8a40d3818b6956db5c3bffb51a7259580bc04288f99e7acb881e40b53fd6921fbb458a1a86716b91267333bcd8542bc474cd2722e7b6c89062b9b9b97c7e70349f10b6aae607a83b8592021b8d90556b0170d6482088d458056a888d7725c2687a43077efa94bdc7b4795fd81040fb977102176af93f94322c5b979872a33b09890d5d121cf45403b8e0bfa4fc96bffc44cd40742e39428efb3236226ac35240c367817bc1b91a046d3c8bb94fc085a3994ccf8b934b9bcb415539cbab371c894ab267114eca52b871867bb42c52db1d6e708cc1534174c7819956b12f4a0489f691e6b42ac704abdf7282bef7b2e8210d95798a2a432d3f015d118a17ca41731e63912b98ca91074db8292cf15185fc49c0e71203f4198fac495c95930e62b07692dc359d49669aa0955427f0484c6316201403226f41e128144d9c53f18a4f9a8897f141d1aaed3653fbf6f662f8e0b61beb1f1d40537e1c38409b0cef512790f7d78f1c7ccf4c1329d71105855d995f61dbc00028befbcb68a54b75530beac1d20dcb299256fbcc0f +ciphertext = 25faeb937e4cde3327aa79fe919877a8dbcb26ae6d5a07fce3998dfd1df9be682cb6fbd708d3d25722d50e4fba29 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 9c69b166dc21d5b1139c1c9448b6643dc146f3db4079ca8020529497468c0d6b2390a97c9c2211ffbb1dd0dc982126ccbd765efc27331dd0bd93ca6f681373aba038ab886ff99a9dfab5492132173f4a43113a5d82361139658f3b91c7c58b6417d18470426948a83f7136a31ada39a17a95d038b04ee7685a008ee980b717285db1b8c2f066a5643589d8a7579db70f674ab6bc9969399856c58b029a733f84d77add5365a8b8793d945c0a370810e27e8e492c6ff40b66e7a9a1373aad90b5e3a285e1b263ab696923306299d21054d273121980ee5074030a6423a766090a60789733efd300eb38771da48c345952faa17ac4863a2cc669e51b36b6434bd826b5c5d81ae207b6057a3728fa18e275c940636e8d438421ec9ae5203f6f540f16242276701858c98e39597311758163acb2300251280140cbf8525a97b6a1f90b308a5160588d8c535edb80cf641a3ce306725f080458b15546690ce4cb773e05942e5ab88362292ac1ccc932bd0a56934b09818fb08f9c435dfcd87aabc60321fa9e5891642f34a231e8ce9129c7a29c3c03b196b5689249518a3bc949d1241d7af2191429aa4f7a4d1aa22685474eed2827775a184bb217ef3603e7075f7de5acc60c5c86009abb483a3307c60d7426a4149905d881cce68034b38c8932120ba48850fcaec9004630503a7e36646360990b329d584c8839b40042c819d0cacdbf9732f7e18f92575d02871185928610a63b97f48135484158fa85b63ab343065b842c97dd690e9ef21d81c21c22f59b58b0611df3cef2233ae900913ddb03d003a99c80090ff5ac3cc3cb5b38c4f7f780c404643750c5af825ef0dcc46506496f3b9a996c72ed7cb523933e4728a9938294a8226038c656e88c511b6509474b07797b247837aa190a70cdc809a531b225696cc6fc36d2e388fbd98c211bb72560115b8a0f74a9c67ce833c9aa27ec06abdfa80432064c22f29724b7ad91b6a2a79b88b44bc2ce5619679677460c39a40a3f80d3bb0b8c4d41557e2ff4624a7bb307f6c740a993c12951fb83942f9ab66ccb3a0b9babceb85f11792259cacb8e323d61169ec5c621cfb2003428a3e9d4580dc3a7f51a49d66a71802423d5007510b865aa17cd7c46538d3b49cde781baa7b2e6bc6819883a12f568c749a0ffd75dda868e272c1a2401b884f41f319366865c6830861f7760c255b961eb0667c39482f0c5a84869a58710006447a02b6ca6c0558caf253cb81b2487c9cb04e9c9113871f7586afc945361e8a3694c21104bc489d13cb1769689454319f81b0613a1d69656b0f422d0238c58a30ba60773ca3c92494085a841a8751664a8e9825e3cae85726a9125658a6a377855ac5989a360851e43e98c93979e2dd500bc138822e2574ea8c77bf91d68c498f15280c5da68868c8d28b99f14dc18dce34bdbeb7edd32668bbbb01eac851dd238762233e1b49c0ad088eae29a50d76ab90a6f8eda259a9931924cbdef726be2c13abbd66763f1753e9bc173c516f5512c99550c30ec0545ebb5f4e02ec16b34d1f4a15b03c79d6ca36da067fada75984910b9b3512c373d578b6ea433768af4c272836aa6ebc73d3b6239689ca274a16a670e8b827da7f7b5aaf0c07a55c64d088721b92741f64430f2779aacb267fbccaca850dda95109b994d7f7c45207214f81a02fc278e6b13e2ec879e0782b0ba046627c007e3708c8f065cc312f264bbb46b77a91e94835634eb227cd266ca833b87163738a54b011ebe17fb42819e9f487ab2382d20069e1413a49720519f3ccbf97bd2596a013c4c444f987cd1c9070a40d7c19ceb7c422ecf3669f734f1f5a6543774ccafc72f4f8269d101fac729958b45aa78a925ddc25cfd478d4da7c8ad5b0adea65b6a7ab4b86b7ccf0c10a7a2004ec47bfb1939dd76a0931bedc1555312007608368506b00dc6b0bcc2014fcf734a0849b150ab312aa9e3ba57da8ab5bd50273bb917f28a167beb1861f128ea6498f4964b6bd6a5d4628697282235a483425d1ad49a74b8fa834741997a7d318936b0e5a663a6a400494215f34c445412728d1f95e49e46adfc8268f450806d491492b4382983a39a7caebf64c89378b21b8a93407d07dc2b023b1982448cc2c1b6c30fa80c67a90bf37cc0c60172d36ae914670c9cdb0b6c12f5c40a8ee5b0d96dbc7d3c038d9f561f0759ad0ba127591484c88b7fcdbe0d354fbd9efb9f840f636a13b62954dd4eb81f29453a4e7c66166d5b354c719e53705708f030333bdc3807d8cb622508d6f7c392363de0afe60 +ciphertext = 54fb3d07707206d950c0a4ccd10a07538e +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 1ff0bf2f6510329c0fa28808ab24436379be62f66599f48dd6e7453fbc62aeb6ca54f148eb21321bdb695c87a073528cadaa3d5473c1d50925f17cc7ae7a0efaa82cae8b507c61195380a095eacb4f572522940a1c49a38db4acc6677652c8a4b4a099874c096880bbf184cd4d26bfc94947c87aafdacbaaf9429f7d24b55b6717e075c071d605774871d66c3e5b58cb6c983b0dfc5d33baabe463260b2492c61baa9edb64c51307325cbbbc806bc9d0a1a8e146f3aa1dfe7c90718ab1fea1bb3851453461816fc0a710949c7a968cbadba8f42988e0e48c7444433005a703830d9359b750fcc6f7c7cdc890c6cc1a2c7df19aef105eaf0440153c77c0a2062a60694a306537658a6bea7ac4b491f6d974cf925a4bb9966dd91385750059d05115dc0e2c964746764fbac4235bb646b2127f6ed71d0a699faaac1390f3572466bd17a4732175272da51c03d50802a191995aafb0eb87b1e1172280a407d165fb288bcc380b7b760ad46829ec3490adf53b2b09d0f0d85169527f0c80323ff3324f7596f6887e27167f5840b18103913ea4a67283bc93d74c2eb541b4937e0bf5974e05844e8516be5b3882f6325ed195b25195dd30bb18797a397849b45198d71a4d14014314f509c7a7b7046a2aaaa0b7d03563647b6082ab5d627aa8781bccb3e320d6c05f44fa89a17a1bc8903ac467912ac2cf98eb8a0ef83fd7d3264f733c111b5cfce9a4d464420bd5263af2762f58954ad6bdd2b50d70ba01c07a21ba4531c30150deb945905640b9477c0aec4fcff3b767b98556e626aa081e07666b9c1c152e63463b24104b1982932c7c613043a7e8425d6694954bbd4dfc520d9361b8fb8926e163b6f975549184b49529aa1c035df89b4e5ac422fb751af982f553a5d1d3b4af7c3c7c3aa2e3e78fede75ff58740f9b542189bbda4810da476ab36540c9d1163c45a954373ac6a23a5539a8b1029444527a5a08b16c3015cbe5c2a3e33677cf9c91b836cb988320a531a8f627e81b4b3ac945225d61d04c7a419b9a7e148bbc3b597d404c1db968694826c364a4d0291a9dbea3c9a5b64d5c53fa54c4f66e4bec8b01f2a931026194ad77aaa2f3a9e7e38b86fcb07a7d79be6a19216815b15782ab4da4b5073a8cfac5a54c8cb4eb67e5e698c534403761b582715c78a69af10039e66170180eabcf32087348914ca4c2a8ba74326c12cbe6c89ce07407b84526350730e158d39747b5291b81186ce3ae239d721c0443a3175a54ee4eb45d63b6241a530aabc12686a74ee1ca1db4a7275fb8e79c9a7f62c98e6aa39e05816bec587d78bc4c3ec0a01d302c9f4989f463be4f01ac7eb86ff101e2225cbb63c5ca8a87d34629a0f565c9c9c4257acc0d97bb25ee4b14145253bb30d8e7b8883271c7260491d54b2c287510c30ad70c65119658af59467694238cf11837fa28765466485034f70e888d209c6a435a692fb4622755a8f296f83258ebdb90c24c3b744831377972e140994f5c14bba9452a12a8d419a20b89c8b873c398c181c314722bbc875bd60c8477b9c2cca00bfa25f7a263be0da56a03485b093451f8463ecc806da294f7f401878179f25704e93076c12019008f291fae079a5c51ea9368705b248b2b20cc0095180b9630ef4aa794719a0d1b8eacca78f8b73249c295746589a4064c0f5c1120a5ed9fa1931b0ac945a705288ceeee0889e113ef7d82b10729150f433147b5585d84aea2271411587a2a3862ff22d067773bae666758034bc02ae147a64246713cf32067821bed3c447619a90764c869b3cb5de5a04351a58af0b786a52b69925702a2918a03641527c4ba7360b865a5ef17b13895c28b6b2c7ddfc10c6b057c0f035fb9a3917b399284b50ded614841bab973b710816692fca0ca8b977e933cb05542d0395a52d0604a589206c96401f544d415053351700a8d49ade71c838113dc3e88fa5221a3d54c11f0cd0095a7c3bb2764ab79217f3c1f2597a52d12a62b797a4a0801b04ab96b7745ba407ad16c600442b54f21f1fe99413e3583ee52b53519ab4a887278382b1264838b04fd1915daf5bb2e5d68c44b62aafc49cc3ea968d8b50c6103bd50980a9656401f60423d31b81ecbcae5cbc709b02057ac2c3c43b3eb1c19e0414514308dfd12c308ccbd6accdecf1e3f3b2b94b20afb1f18785752bc0b76fcaf0de6c039b71fc9049a796e0fa503d5223dc936dfe0ec23b6ee9a1360e67baacd92b9745222faa724a9005e8463551b565f13d11ce306b70366b4dfe0e58ef29dde16625f944afd1724b +ciphertext = c35570487b9d87fd3b8ff850b0cc4e8eb3ecb083d7d65bd5e76924e6a90f597fe6a65cc1268e67cb67a8e0647a26754a32a2d80a3f5c9636ecfc28809ecd93edd92c01a066aa2a4f73a6ec38f229ccbb32e962dcff9161bff6162bfc3eecd7575a2d9bf08a561e6946fb8bb0f45ab22903b98aef70eb7f888e37e0d08c3f14cd45de990f7130c3bb1b444efc2a5cc4efc644821ea6da786cfaafc6f92379ff40e44fb78bf98ca989f4d41a49af67c033f0cc2d1dc9382a772484c4c207733658c9ff66a55f1a6efc2cca65b6e384211db96b41a19b26bf221b14a17ca7cda7b7a683f1cb67289a3cf51c7bbf1dd32488cdc6a4c8a1fcce65ec539f2efb47d612f68831bbe140c5021ff4b465c63b37b956bea7d2f06fb7f61e2f425064d4337e00599fac155b8197eafa48bad139e4555e65a6ba88ddbb9cc6272d58c9bc05644a7db842d76f258a61c2819e1a1eb07ba743d9535e94c0f81b16d35be91cf9ed831647662d1700bc2a5eab96840b2a2df585be6e7d9832dc086c3c6ab9f368beb839d8faf42a62bddd9188a0539ef5b733f3c2c86ae47703827b0760a41bc22d0044c1fc1d169a4c3a7589d39f8b485966f427e8d5c4d13146da506f7174ff22f1c2c4dfe2561e082c66f26e22652f71543a130cefb82f +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = c307245ba272626819f8141cf1650cc974481be239fdc2c4e8587fa4989b7bf2c0851790e2b9cb4d80026e13c8b8d12f8ea63e4f245c4e3485c871300f570c1ea1a6b48a855e25ab583008e09522ad3b77e32a11d3e56a488bae6f1b7bf616646e5947968a37a36a2fa1711441545496448c3e1b82a3c04806e53dc3b120595580f79b9ad513450e7c2182d417b4e498713a622823940425abbf2972e4992ec6a2652df294b7128d19b3648b423f5ba136ae9ab3a772268ad515b817cd251b0164faac027c6383592e978029b936992b3a764f645af478cfe47a23bdecb1a711a6742655f2d6a3e867a99d4c29ab8b86b02c630a36762bd4a6a6182110fb8021e40337324334879f0b676d4721c63512a33d462629f177e8f75e18300889b57df5f43363f4c2c536be9ef564f0fc8eedfb2ec282163bf4aeb5373d6f9c0ecca77233f4779d081f82c3a87ac576485a3f11250ec9255af7965d4f885c87940dff9375f9670f9e15a8402b2d9184b7da54b8d149cf0f9a7afb896f05cac7c1b834c39c7f120c679f94311888627091251ba61447c1248ad277f3bc1ce9238dfdbbc3bc071e8042c6a647926e167ffe41bbca44701c041d60293fb92314b2eb3c0adc94cd8911f390beb704b1ac058809c43d9bda5f72e62ff2c10ef677a9c6e20870a38cf9b883452a623c550b67d81870883d23fa509a29466e253e2726c4c6e58e4264acc01c9e47825939acbab25b57a1171dda2a5011187fdccc64cad41fce92b93811cd26ea780f14c202dc42cbc626146c4a30b06c7366332c588f8a9a0e76f3bee65151e011b8b72a55cc790f0a1b474906c542a26ea412a5560552ddda82bfd39467b046c4c833119467c78bae88a988c1c347a9a214ff4b2672a42b0343273b4665cde748a159c8d6a0b496e8bf8c5c7924d824946618e5402e5de62f171766bf327d84bb863b5a36e6cbcfb64a1feca4237f47199a0c222f1a78e9ea924c6139af25985f48ae13a55ccd138de2167d2ff4a7a2f939435373da67062832b6d7d3354181758436a8f401c9ab19183fb8184ca0b937d990da34359876695c7806104a13721a512e3671defa2da1550b11858ae8769a8d8c1862c52168a8b12427aeb6499c856090aca64bd18740ae7c07fa7aa0412689a4d21fa5424d4a2b5548691f48632c9a14210f3ab145018e8de744c55454cfb20aeb372569220fdab121ff95cdf3616389065b41f250bed77796186fd0c416d5f3bd9a72677f4c03acf58a41a532cbd1b51cd1038183650fe021789870c84b257d913401f6c9ecc665cdc72585bc762ba00f6ceb14aa6162a3760977815ed5d27aac74080d7354cf05a60f3a2572d81b2cc9a817456ad58009f79ba830872c6d731cdb185f937619769829ad9c3c45a14b2a59237de76ec634043730c9feb280cae63e1d809c58c3a072349ecc32bade7432f8cb4b0809a417aa67462a7102239ccb29970c32b3d49a8b11fc6ed927a35791ccd753578e781065e074187386ded56958c007556658d8f3abc69570d506beb34338cd84902507d0648ba895ac4e32994b7afbad23642f04d4aafbec630f83320ccc7d14348cccb73587ca1d48064fa05b69e4666a310b39d4aa3d66f31016c5b05167a296e17b24a8730820555c081fd9fc66cd16976c7c98e4c49230242a72fa1a35957a03458144899f092b78c9976ac6d0ab7798ca5f38c289813b44596c63501270930fb6e465746b532401429d75adeaeb4b26a0a6775668fb35a73922bc9c409ea5a56baf8011407687b5b51e003b10715cae6daa0093981fefbaa5daf7c17ff56a665ab2d3e43b16a1695d15385d75538059445c342b85066337ca244a2567a08850dafc57bc27a837d4b36cb75a5fd7cc7e793288a299455c222e931be21cba1a2c23add57c5276680942afc0f70a1d3b74d0f15bcf40088f78c2345145dd4a48ebfb8f8e59cec532681594cde1263f8453ba246abb99427b9992bb9735c267e82eb053bd4e97a623aa1962f4134fc7a48eb55f19960cf1a95ad8eb3abc59ab1dd75b836472157279a4009c62a7b7c3f4395cc41d6b4299d1312d3ad644dc05355876c45273bb5a3bb952a465de92ce4f882b04629d736a6620675ac235cb19f07b33bcb2c2963ebf457a964506f1362fe6842cc9b762fe49e700ebce4dc96340891a05488fb40386d43378b1b7a6cbefb9545a421cdfd1c1d21456cddb4b939cbbef6befee009b05f4e58e99d2f2d90ba0884a51069121a69ed599d4c8cad6deddd75e8b377ff17104cc3789a6177b2e +ciphertext = 62e64b7ac9b783e0df44a4051258499c625670589ddc72b5ee97aa80c6f096164ee16e11c97a84f561714808dadc97d8af025443d2d2cba2a39bee926d0f8deba86d2177835c3a76fd931c81745745974c74b1647f81dcacede28583d340f5014218636910fb8c8fe610a8ed4edff1614b66534f6ede5ac8f00d9be0a3ea297ae2ff95c19d8d0cb8a1242c50857402fae90f2b5a6180a4b96bed35782f1607581e394a1fc64de21efacf2e382b5edc4505b850ec9e7ac225b35a16f550799cc070814ee57ab4d8decc5768dbdf58e120aedd625c8838406f8935b0b515afe904209f617b0a4d9679cf6794af70eac744389e4115095a9d2b86bd478c6a67ed07727baee19fb87161992b6a6471c9f1885fc41354b2688f5750caa7e8f99d1a4d0755efd74fb3274cf3a1f22c179eb4b082564fe424439450ce3e8e4691507d301a4604b6f734a58b1f0c327ea05e3b44534c1a42f8db33d68e26972aafd1a0f9043676cffcb0e6ae9b99cc473ed5eb6ac2afe49256f274ae4dd92230e64eef998e141a8ed4dc5cb1d53d5ccce7455cd37d3b8999e69d27c9455456a1c68a760ffeb09e24c4076d1958104d8a4f12b385233670024c2d2ab40fb2a191d1b7c12637af3042593c1db78ebcaa6d195dc1e2dac3cec2e528bd953fb00ce36cbcd724c3472bb7bfc98c71ae7c70a1b72a2dcc87eeaa959dcbafdc55ec6260ebbaa7d2d84a32f6a15b24c0 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 0d825372fbbb64dc0ed84342a67062c88a840ed14783fb04e4198ed025c5cacb70c46686fd729cc55712a07c565c5a8e3a5967c43a0cf669c21864b08a698b77e0a76786acc24b8df2f495b56920eb61629e4039b67b594f3cbbdd98177a47536536ccbf3524c2351ece4729e8877b51458c4fe785b461a3b64536aa92812cf8ba38b1c7fc0b5d0f238305c9a8e6139135e34a718323cac7539354c695f80d559c65437b975c089239d0330ae419b0966f9bf1b4441454fcd944c644487dcc6da1105fbc268b2914cfb7c98bbb5025a4f72244f9b749c202d19118c20a5f8e1216a41577d6045ac0a8514e30140979072bdc0056134795a17df89a46bdf23430d93009019ffb92bb84503720758a60770575fc6365ca389ff50f6962403d592f260c0ba777136f6a9f4ceb0c00b68277faba5ccc4fe94299e2e576cc05c3a41141551b790327aab875bf38b63db7ea6a1cb71fe0f1377d785c1f35419efb2d2959946fdb6933d28a2fcb78e3a08587256157a5685e049450451ea0b27c2d44c38101cca3d63426046641d619ff464e77b5b09ba5c84fa3c186770bdf9352e42a6699d2c4fe646d20101b9022bb788c5a8a43b6978614571661b7b188ff3aa91618421d65c8f0e03ca500845e064790d4295d16cd75f056f2f97b36742d572805b3c34e2c24133ac5bca2b1128c8458e2d42720188cf0213f3c1270226b9018a24166151faf74952c263659fc231a658fbcc159ea15835e76bebf9621ca0304c4096978b58b9bf78c95c45c2926991ae3bedd93b8cec68dbf7959d5928fb6cb49e7036944d124dc46039842a5a1bb6a294c96c1516238f485225828f0752c6b595f3a40915c1c852fa067ac265680a1714477aab5132a56044543db5b07905a79c7221c2ab4c15872fdc003d1b5cacc4793c2c82c1f48700f8253a1888e93e84d31f168adfaccdf230729e2a383d3330d7104dd16658f829ab74a59d5d6051cc9941d5a6606984d15ba7dd9853cf45ba441a56019a8a44a494235493122962597a54d2ca105c2122b62185f1d385dca996d12f7af5b185968e208221613328c362ea2bd32e234f85649465a10da541bd0d570e7673667824754470394f587f7fc7c5b59a8974862d9fcaaa03c02b5c22f4226737c0a2016cc5369e78e9485884561962b972fb2d75c5d281a0f9c570bb082f5ba46bd64c3c7d4aaf6eb19e91a9cceac18bd2bca8c2990ac010055a34c8f74296104c94c5027b45a9472789910ac98064c97ebe39afcd69cc753c18a490316a475c4481b880023848b18b4ab14b7732910939b1091169e7c3c9a9326906a4dc02b58bae88dcdfb3862b39fcc0892bcba8f95e828d963248dc00af5f19d31704017c2b4ac034578d32757181e5321b098b3702874ba9501c883271bd97a87e10c51f40a444f18436202cd03a32d41cc4f7baa700b43a2bc93c300415d7be177ed2075b0850b6e28768ba63f515babf474af8182093af6ad6489b2d57329cf095a2227c17a4a473b5813a81c03e18b4b59310933a740c6314cc998acdafc023098cf8d886f4bcbc69db658e493b7e6c1a5ec038833ca0f5ef3024ad806f8838a30fb6b4285a80a53659054c4df1b0d20a6565126552a00a30de62dfe519bb6044c32b0c0237075e7470fe7975f582cb0c7a5a9d7829598e212e7621bdf72191b061f323c2d98570bbfdbc723dbbd48f42a3d31364c20432d75477023b1c3e372d6a50cbf3312e31969570b45e9c1bf46aba4c1658d5ce78688536ec4dc5c7e79437e5c04104234f73ac4dbc983d542c6904a9e3a333cfd36729a8c20cc06a2204616d05b87e903aeefb363872155d67b7e18788c84512b265562b9742905a483238cbf267b694e6238e25ac89309adb04240429840817338dad4253d250d9c44ce4b73b3bce86219236248f038a789c844b86235178fc5b8272341a53eb059b6029fb9f2908b42b38c9c2aa248349874860395b00e348fcea9585b721bf27b9487292bcbb0bd7bf3b0481a2191d23ffae63712f8cf82fb6dc99bbfd8839792e7653d5c8f8c67a7bcd6cfbc1588e3d22173c4326304039aca5e157774f0d1acb12a84d730a8d2d33e16b99889db804cf1313722a9939556d12258ea4406d3388df0a059779b363f73c92a547cf5391f506830516b9a4f1601c9edcb0ff63a2a7d09496f946189c439561fec3cbd019231b42e18976cadd2b92d66312be5545b609c2c1fdca7cf7f33373205f5b8938a462a7f5614884360a142065ea464760e3e801c1d8b5d05b0e7ca426c9337f87e +ciphertext = 40daabc280dee0f4e47e169aa5a7dda87cfd1ad87ef8ade356252b33997c085c11d8f67b7ac4cf114882e5c8c967c910147dd8807494540ce2bf7cd36a461158470821b781fde2d8b05ed8149d2473d46581afcb54f7addf32d2e48250fb2c8e0372748d0ea56a22cb67b54389b8baa67d3d23bde720100cf40cd19361e69e32c4a5343e4256f4de6a4734f1301c3736aa1e05e3581b0732ceb403d68b68900652590923d212a9c54987b17a8f45 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = d5471f37d12ff759a8955846f7014f97da742a979f94a5a5d9998e093ac8ab7c0965f97835340c93b3529a00cc33b43ed06841ee934f0c6416ec2ab9a8e0b72de45125bc5280f933ed9c6c90a08b258a5997263d9465c4302b7795893e5c002ece97bdfb3bcd178684a9b1c376ca6d3619980e110f878a1fc5f576e3b6906a853daed61b33dbac1da54d61ca9c9fa759e033ba8a2cc7a0e101c84c0b07a503e9cabbe77b3aa918912ef91f99d69e1ef42450e636693581b912840d36572ba86797e2486c83ce8aa327f2904880208d6b8981d6670014bb683e57ca7ab50af8e068d940cebb76572195b850b73c4a482997584982057f99d5118f27979b97b579844608f180058749c5b6419a92ac207c440be12e32e096689cac33235a98421f1930ce175a9162e3b60b712130c515749431de446f060c6f4fb2309208c7671bcb5d4c1756a62520c2ba14f3c72947299970717ab2266966286ffa2feca3044a23a1b9f02691b576a021be6fea7abdb71ee66a2787e69bd7641637501ea621ce0dfa46d444bc9da41f03cc1583364b02570461e769ca982cc942cfc1a210d7a57abe4c46a2dbb2400162f97684b8d5a8433722b030a366d01b94271ab9fc08da64aede75c9a2b61e16b822979890a57c96cf948daae5a7d0e31a50159b453cb8cc53700cc3ac960349171a10584766fbe8c0c661adf84b0fe5ea9f4ab432c3d99452ac658e5a0acbd12cfc6b75add318e154bf58542f6558b60af20b40891441029cf481a8c9002e898c0844d71839634452bb1108ea453c112878c767d9342bb5c52fd17211e3ab49be7a5fa4669730982be16643cad91d3c9154472bad967b373eea7b7dd656c2d6854f4cb6f5d60b21541e5c69a1068120772434e221445d300d3cc1cf51e5935f80526f70cbbe18c788d2ae95e60ad17b266756bfd7d5285e69a506692e7f3babbc243c63c0b79b364efeda918386a61f7a48afa536e1d59dacfbc34cb4a8dd9839eb5b3363898d52b4bfc2419477db2bd601bb3b3ac24a0404ee526ad175b3b2b291176946fe4a0bfd9864576b7a7082cd4e35be94eb7b17f92081a5170673978ed84f1821732dba67aee198b9a10fa6a7900480c34d02309bb01f5dd34cf164161be2a84a554aa53687eda18809c0a874c6bf64e5764c12b4f8b7b5201299df330eded40a67022f830981f05467ec8b6ce6d2342c783fcea4c11557039d89b65372b42e7334d197c84f8193f49623af756b8fdb44ec4956dd751c9502901c490f1c9492e1d271c5aa49c6eba44c5a21176a60f57829cd86b29a968adb5017aba973fcb8b6ae0840f458b20446c42bf93ec0e28fd37137a379859d15270884b0a6c75fae602d9cc72d9e53805f5c6882435787091efaac03b2e773b8a1c4ceaac94bf131f1ac3b382b59da27126093ab8b291ea63b08f4e3196c1093672ca078bb4a3b23043483b5ed964eeb95363ef39d45122e4a8b50903900eff49a220810cca2cb3f7951d3534d6eb84a73144d3fc566e986672673785274c307589212304f83da7469b9aa85132b35657b87366bd4b16f5d312e6cd61600d10cc36482d9a35abff577e8f918edb5ce6c4940338accf7b35685e119e31479957145b3e00c9ce2cef7d50ce61c578823b2fd0a90e2c096c441c5a1e231277a8bfe98b1fecb8eee6527aeb62de57932e56458555628c537c4b55057a0227d41770f6767c2dd279740a61dc5b570a0b51e55499b3c369c61f03154d949d512c0a8fca6cd851542128012199e3ccb90c580612682a43c498d8d855861e819477c02f7266660eba0f7d831c4f73b57d1678c7589884023970856b8a661d2881e56c049e1e321bae17714d744a0ebab118430ef151b39b32822e65533f610aa4684cdb2471b9045d2e463a8c383d4f343184b3fb288ca2bd89058dc9e9627a864587ec62b59a4d65eb3022c4b6638b3d483cbf91e63f50c59e42ef7b7763514998a32b8e9677be69b9ec0661fdbe90aafc6516966588491506700c10d86b8a88a32a3d9b51c699a86437046c68f38dc0433f0b95a84951f29ba4802779b0792dcca88013164cb5121a2229c99fb2e07685d17c78f769c4424b3b8fc226f06d8bcdebc8736b11177b807789b862f80556d6c201f7087b58275473752020a8c477407647103a1411a0524b6b39d041b4b84878539e43afa19eea7dea3636d7a41b66be02a705bb09352c2c67b50db0fd0e4190ff29dab24f7fcdd0471e38e38d66cb035f4da507342504efcf983d61e2fde34e004102073b85a59067c1b380b +ciphertext = 1e6d2d6038b5cad4981b695af3eb1cf0528ffbd5f4d45a0e06b69c2e95d2b85ba590657f09b8ca73143f0f533c8d367c91b67dd2a4a08aaeaa5c772b31ca4ff11a1550ff26e564fc3bb962b6cf4d7b724df7b9561c11e5e18c7b01ac9b39f12e80c8720dc9de1183d0e05548da204eecbffa83b9a286b13c5ccdde03fedc717df1b44cb8155a4920b00b5a1c47c230aeebf574b7ee1ba850a30bfb1ffab69de4afbdb091c08e8f937b8488d0a3819ef7eb98d3b96b7b45828b7b4a3317dead4d7eb2d3499df6558f9cca +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 7d97caaa08598bcbb82680b220a09b327b5bb1b5453469b621e689e0dcbf8ad07db2c4b553663f4d3452f902484d3c997b933f49cb1e4b3c61e485965598a1f108b3031a9249e6b20a0b6796184814e30ea87578ba935b570b9797d4755578c405468f30a3bc9ec16fcb059968a51290b2afa7f6badbf977389b49adec920ff9b338b261977234345116d8b8b4c6266f5562a7ff829a02dabd9c990b90f8a8eea3c5e360042334b7c7715b0d754f304187b08038eb45042f1799c07513bc707c6d1ca5828bbe5d2757f73c0e4e124e40c84e9a7bb7ded998d7f163b1ec08b261742c388311796e6f447ceb437084191dab2295f16251c9435045c613f7c80cc51241981c6ffb372457f4259629a7ded156765316cb212340320c0382c50a1a6f0b84a0eef47bdda37afcb75f8a9372893a2559659d6581443b4c9e4b44b3fe010e1b9033c5d1b7414552733c99eb27a77595722702965e3b15a41206b82a5e397981c223a019014b269886546a0d7c335e03f3374e59847efa97dfa2519cd7c754092287dc7f72ea4309b39c3eb64c068885641c491c4864ef04c4282325d0d9ab8af95a557b02561360637abee5398a915295df9537533308768c587bf95de973237b4294ea6a1811d18b7a171d14f8c91a73961f638bf67344134679d83336cd235ddd476ce7324f98892c3e39976cc14e7dbac221ec972c10c6c6145a07eb23887774dedc2eadd41943a33deda31672852418643d323617f716ac17938b217b64bd7031c5ec72b65502dea0be07d9cee73c843dc23b5b4b16b75b8c80655a3701349f5110cc9a44f6ba3389ec03ac06a83675017e8869cf3b764b727f089cbda17136eb0667c7380571aab53ce99dbbc2838c646d98927a8acc90070aa8b8907b9d27b95af27281d0544a9018f386b270f00ec424342e24c5b34c37127232d8c65dfd68afdd184edba991e9868ab660abf411181f14b1ef9504b3042615b8094638b0fa8aa7c6306f7f8ca5377516e4727f240272a3ea46c79c71ff63873e659f29ac6678a0940908785beb7026f9c9caa3bfb2066be07b01f7224e97c40b4782b05bd2501d932e731b81df2265b7e0465bc885c041ac9d5752dfbb3311b0ccbd213b5397c388eb9424f097499508bd728f991b530ca115d4ab8f049103df477b0cea2c117225d99697cd399613f1254b2ba411313d88f972664271a00793a9397719e6297e74cebf22bd051caa8f7b99621ac122b0ae9810c64a710a85c07661b3850826230b290f62433e8fe8b755c804328b9c3b20b7dc9c2b32f6630a18b4523a4ac8471b5a83c3e1e1a7eda184caea76f213cea1959a255141744b1aa9e742d0679975c925850ac07c5653c49acda7685a36869db77765ebf13c170b755938b9b122107d174b19412138b36dea0145a4463fa45307b2e7452f86133587145b1624c2699e470140aae70ff8c22321e420b315731f3a9bc90c4f08e139109a6e8ca59591d1bdfee7bbdcb90deac0a7866b8db732a9c6218860832dbad1196d99586bc10d53a29e9397679cd765bca4c8db0a0a615c21ab654f925063baf81486f51ee89cbdb1e65547c6b477b7bb696c2779bb7a56015330b25308a80104e378f7dc9a3689cf1155cb672c1a74206de241139978baefe7be2a936a31502d3c3ca58a06af9469aa42047121eb2261cc647ea259e7cb7dbb91ba91373105d2adcd559d2050a30fdb80dfeb400d938dfca7308ce627c0b2167de85cee663fc26055e6175bd9f680bb66a2b243c21c8126bf054df241301cd0a344b00b9466c1850b2c76163e1c10a2ae59c7d12571861b7f726a16f02700ee239505607c72c438ec956ba2f18bc96a8f7cc61bb001aae0b30ed20341aaf810bf587d00d35f1a39863667aee71010e9d02529c74db98b49afa149728aae93dbb31730964c880ac2d2a1a9dc429b375676796fbc02058d598f5554ca7a634b1c368c7185bb1b101b310143156a90d5785c0bab3034cc652d1ca1b54c976d4180aa499b9f6c057c6aa5114140da01b1c3c279c4827dec84065a57b184c76ca67b733a76174ef96657129fba1a703b7c456e958af7907087aa941424a7846c4d05da3e5c32b6d462a44ef0189ef0bb5f705659a975c0118aa37c552d6097a12abb26d93f99f5397e916f656f961770c601da9c07efd38d24d257ca3bb2a1fbc96a084af458bbbc3928bd4f8cfd40b69b2fe928b258c5373ee8639be34680d766c9405014b98cd5d603089ee43713638e4919dfedd6892a77017815b251e431779be82518f5e7acc359676b55934961bd8cbab47e00ddf760168825 +ciphertext = 4d67eecba88bc0b3df60562564c2a49fcde00c5b222c5baf9e9f244f9b50074c4caf6a36bfaf5f0648f580f58dc6ecfe37b4a7e72b3298731498041b509794781291d3e55cdc3516405cd2147ac2b10e52a4a0608f75dc02bd5c0e83781e3f03b8908c86840e4ab10f56c98683c26897032cbb6e94910761607dbdb3b86b1785de76188e8d762a443eeefdcfc5f6b29decb2fc6b6f5e34b48c53a94ccf3e42d6f5c9a913906066d6d2bdd29ae607050d9fb5ae3355c125cfcf61dc8684feeaf5e82b8cddebbdb95bd8e80106e7d709e6ef2a611958ab1d066fbb25c6aca9c0d4968aa20d0074aacbdbcd48b621b74e90e5c439ae542742d79ee76a75b1b4e03d24326a9c155b27c3cfe37010c327263546c111c1d6145b63ede4e5d783dfff42ede8157308ea3bc2b2b02fb76ab5803a7c22766c46b87ec2e8f62ea40b068a4cc23d0e44f436544c6f56aa5b56ceba8e3000c665ec8b4fb689cfbe914f88cbb0ab0a91c55f9d3308d81adda1cac7d9ce93f27959d684de9ca51039f62fdfc1616838c6fb20982dd6e24f98503fcca7c53197b119272b0c4501a0ed4e34ebe237e7fa29771cb4dfe7bd0a08f0b4d27c4552d35d116af09118a4f135d55f70ac7f1571dba86473dfdb9863fcb98351d14e9b2aa4d3a7f749b22dafad45d2dd725d569e730145de3d3abd755fd68408efa95319611d12a788645486bc2175cc9ff791924a123dfb8c7c7761ac8b9ab54d5bb4cf4855f4db0a5e4cd8a331be72f9694a13c0ec5ce6ef15ac864b80b26a6b5c37b4cd6b043181dcb82f1a5ca42a83d7c522a627aaa650b78d49b8bd6c5ac4a896f5b3a19d5ac764a12e9e6b6794c96773e0c5ac3bf2c0697f8016f7485a6707c3803964075dafce67e60fe1c2e040147ec06a88d7639fcd02eb50428a37087bdb53f084ee3901fd103461c104f61ebe9aa7286671a175a9541e033c943d9a8a1ad1df2eead3466e27a30d3630a705c9744c008e37a68f7f22212dbfa407464472ab7be23bd7c07c6853a1b58bfeefca1f3ed3a4fca67645948f0260dd80ae17e8b87c45bd084ad253170d067917ed36 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 7864576a511321b2076b6c2c6d35113da6881cd78797825c24b843041034b5c80488d79eb5c9601375863553998776a130335e65b6a2e0390b25ab843b19753051b72bf31b05d4c311f67fc1b4413e89ceea506b8f7232b2d41292b794380cbb739447c5e6afea0192f1b80143f14f61e3a547ec54578a5ab9c9363bc89d75e796d358503a98209ffb0f65c2611e944920556d179ac7a912a176d056c75794466840fc0502630abac5945221f0b1f304b3fb130a0c5b0dfca2840b955a5a2907be973b1b45781923769fe4480c41245d642e18cc9526d48abfaa6b73e6782947ceffb68c08f3938154b161536ab7c73bb1653b5119a44d02b989c937f204be4c53cc855ca4ec141e67fa40d99b40c257976f0b1640270d7f59406bc24534158711e20bd6645d04eb3b09380f42b2c47ce8b641e0576159490b78376d6331038592a0677c0fe70043c33352f304eacb0836776423e3b0353a622a711b6386bd84e918d7a82b955c8019c6b4c0956b77522a3b4c61aa238de68c631a41001a4646e8e5639a615d09612625bc295e2787e981c6c5a3773d011b718a8c7de4809882bbcd2a92790344865b17381993e4b0c47230a3aff5b9771035f08b9e7b79b2cbe05081818884715acec7c8e6d71e949537e1b8c6a01879bc0c62126cb884cb64b7ac2f6c11225a6a8cac9521c67ac16fa7b56ce67f30f97d3215283e91b24531b6b99a4d4a304efcf03151242c3831bb6438b7e2b31b38f0496992a09f35621ce529ae228d427186a5b970864015392c64321b3b96eb8cc7a14554155a75836e69c2cfc4e530dca97257d661308218e4fcbb1345cab1b63f034c9deb11cd911aac2a91c1519428a4a1a635887bbd98619dfc4400145ff08219376b0071a965692460e019c2d2542b6f0b5e73a5cbf68a746932622d0a0b7d49059a99491667c995639949916d7e6617a973058b7154b5c599fb40bd5299581c8784f2e685db144e2c14b3c5d12577c7132fb1161616255c2c4b24773353342d58cc6ebbe785840a6443ba132d6771d4d4bf6171086620a6f33a1dcab86935c6c97b790ea67a2ce6d118658650c557a0e539941f33b50ce341c4790d7e385de118223721448d22a22c2a083959c7b64a4afc8b742b602f41c70b8dcc7d7ab45b9905ce51c8849797ce1bb2a6af772bb9044cd90445b8046d001a0c8b105b1f920f0d230cc5575b9d8ac3a90403dd05a04c34197102ced44bab2da2c1ef43748ed70ac7c5062f995e711962b7fc151eb889b492a69b486102a69ed0259133a8456db3c0c37591a20606ab1cab8d146cf5e2b19e7225998ca4005d8e5bf08e76135fafa252dfdac08aecafd72598fd3559854a4bce30279c91662b4861d0050defbc8427b1233c097db82755f2e6972729b60e8880e8b34e65280ba86c56bbe30276d8ae57105ca4b03b0125b22da4ae5c60c619d07466994c0a362a7c1a7a3c317951cc57138b3b700a936342a9d138b820c8277d873ba4880af7568076731811ba798511471d973a8d139910f140bc160b652421370c56065031e557ae9d912dcf5010ddb6b07de4553c06ae90c0797462341bd7a98711947c6cb70a07307a41b28e2130266559f8e535cdb781ed5bad893750bdc9c39fea626872c5cbd564f8f00feae466e604c7ac536388fc7e6881398ac4541eea27d7862a8bd16be6f3711e443fa5f939c1037335d7118dd4cedcd85d7563721cebb76fa65569a9cc1eea530246007fa753f1651fbe144e601b5f95dbbb597b46fa37c2d50519cce68bde0232464377a91375fca137da11b037e0680ec014de9c939c0285a199317bf7757598231e536e19d22e6c8b480eb3a804431861382bea8ccdbff056eef20ea5899c144920d69827e8762d80597bc40318f1a36bbd36a1baea84bda61773947d550bb31a3174205b6fd867975e309845f3261b44abf494928d88350a6b426b2a8834502a04d898113cb9ed267a9280453873524cf4c851fb94d91671b59282ff0b9368a745470a9c887c5fc567b077816a390bc9ed6319f7041d29e094b4351eb4290585e4880cbc417c3794a5c61d08b92302a650a193af2b95bf7e5ac1ede965da6ccfd7f46db34b7cdf02a7e6e87f326ab02a2541a53488a7802fe2f39cee703674877cc4b6562fbddbf0323dfa44335dc304e910f02d2338dcdeb13bacd114e6cfdf684f6181b2d0f6098715582ea69fe0642f63607867d5b421061de992e27332d9b8f5f359bebda70029885b17a6272d8b941b8526876776ffaa0488267cd6bdcb26da96fd224d4297f8717737c31014a47ab78c120f2f6985c0f3f01cd11689cd0a +ciphertext = 84f236e2990012e44c1a7f298243ebb480630352c0c022f13932c3d8c7fef848c6595559a237b10850091999edf625c9cfd11c02e3a1f14d33cf56c9074145ba6239f6001d3f1b9c8deb1480640bd4c6168b3a31d0c1a42b385a2ed8d402a73a2c29c425c11a363e5964169a9ecd7ea5741c83036da383c1f289d92b2cd90a80e1d687410eb53231c6ce9aac0015324958d3f3a7ada935bda5207e651ee3f46cf120e70d4777ad74eaa230e4132d0f04b6a7eac16282a6707768d2dceabbd739c671ffb1ac1cf56befa9037868f2abe33bf25a545d74759a272a4d3ad6e31a7973a118912bd50e1e1ce5aa1c771d90f32e1e95494d86a32c7d40e4ab8b63c221cd00d17729724de86243e15691b04b3176d3adcb8b114e70114afb47205b9b17516bab1746b2a22e8688a65229d0e9452f28ce1ea7a2352c1a51794591614ed318c468841235c2ed8aa31d5dd56c4bc78830377ef1322c977908fffc5b2e91f49434222e95ea5117773536a5053f6a76166b08f8ef86c86eaea2bb31d5ef4bf1555b82e50539b35640e1b86e89124e730fa1c8e6c2dd1a3a7c12873f070753bd5311713fca9a5088608f90aa296083f54bce4faaf2f12b34b7209373812eb0faadef87c40c6717faa7a1fd0e1304d4d616d875a91b73f84634f53f4c5502b3375f1cb6922f0bfd90270d3737cac56986578e0ff080fae4def2c4046b5a41a1e0c913689187c91a54b6c2eeb5b6206328f9c048a7938e4da82c558c0bfe0d17afecf2ce550cf654f6e03c6caaee32f936893821fbcf95e5da1493a7fed7ca978f5deea20c4f68f810ab2883a43b45edacbc5653ecf1f67734792d2bba0d1ac4d65d2ff7135f95d622c264184c449d7532fd1e7b578614ab55264188b0e32ec78494a0de8a02a868cdfda534010cf91766be17a93aaf51387829fd5ffe00363fbca33212fd394ebca35bbff1dce0132f476db16cc066d7f27b6d4d20ccde90cfff2cbb09f6082d2a0efe0f5462b45a3dea7ac5fab3a9d6397005c190cf2a65192c9011e73ce31f2022434bb68cf37310a60a386d8dddfa71e35d038c439f1531eb +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = b985c9ccc94bb4f137acf46425e20e676baca5aa149395b81c432fd8eb748323bf3a7825463cb9ebe29f98473714550543c3048fb447efe3ada873c3c3aa59f8b8482421b78fb24e80445424695a5856298e997ba1d7142c741103c29940545612e1a056b6812658239306a4a194c1c4b08a87a1129adc7d9a96b0d2503345abccdc2164b0613df67677bc03261ca73811650755c64d44325e65bb2852d7cef6ba841c27b0c7c561a9f80773411cd2a19183f5b12b0221df8a00099b7905b5729a7913127c3485434528d37c801a6b52a57a755a6569120beb9946d7e9ae4b363be9ecb360585293cb19f7d4c54fc911b849a9d9c57e1aca709ecbbf59402ab4a2ce0cb1948d8a8943289d4887a1c79241f69155fcd84e91042f90c50dece159e2806cdfa642aec5bc1ceb3c7037be3b41a77f8b13374b99df6a147b42632af56ebf345ee13c6e1c275b3eab2d14a71474bb25687c9a3fa27d95dcb25e9c847c369d320012a324aaebf94b50eaa4c0cb210b0260b63b05e06830a381009098909663717d305c84c0a6916693053c89b7d24c2636b8fc663e20079f5138aff1d18e16545b7258ad5928512f400191a20e5f5c2bb255841f4916dee9ab332689006a0f848c3c988c9ceb9584da248bd66b7846948442768196b66127619b34e6490cb36d15374bdcc64ae69c5eed37149806bed8003fbe3419bb292fbad490c62c311e17040cba65fdd677075b04c75c066a1c2c83a2b4f72b6369aa03a1986d388a0d38e300fd7357780961eb3967017606a6e13926d377807aae0b15c7063c72e9d719693b358c243a417c7134c37ccb0cb360bb8773ec639ba222a6f00e8935bdc37c7451817c7760ad4de79d754b07eadc180cf0205f367663b2516d253934a94f53d75ba2d8c4f2725e2c150725685fa8156e3b8b342a783714b7bc154a2f8cc29d47801e141a6c1c7acec1c5441742aa4568a643f86ce99634138c31dc4151ca14ade01302b03c5901f38ffa864bcaf01494611d4c514b40683c104cbe877a56725c5bac056dfa5c91b83cc2a2414d39f563c8a9a6a75700b935b84e281f3665454627a5accc078a4038f1072f1d67be77b4453d95312fa241ae811c0b03a47e8c5cfcc92a8ad460afc632513a96316069a7d338810054968329c2ca66fc55b81354adc6c8319ceb529bcc5a3cfaaf230bc53d888a8beb5ccdfc9de4b6706da39cb55a9653c880839a73a443379efb830af8b2e725b12fa9c90a718a961cb259b29cdc5089907091378b1819d90e42e70af227cdccaa273c5435be9b6446a089303a869c09bfecf619536944578b73388c232cf16e2e5810998b88f516bf6d5c0ddff4c3aae990acdc551078695b269de5b188c5d22b2914a8ab49878f895f64c880619022382abf20ea206d6a148a2164ea39398dab5762a293b7365ee1e6038b97807a414841595e71777016fb65776465f4074c71934bd7eb5f92645671102c66221cc1b49174538a3407ac610b7e387927c725c72da931ae3823151c1098454fd523ccff5bc48501281b021ba3e2cba4e51510144d099b9cd67b69def0c8039270d93c423a132376b0c1ebfa4553497a42299b9f9ac513329afc4180c138344fe321942072ba5a1500860ca55ab04191c244fc300b50530cf0aec62b569daa272d13b1aacb83cab13b21c7b75a5b0ab156b637539b5a23c9cc8828b415567d793d659c9030e93bf9a57d0fb0727069b8f6f9888b743e0fe364e72cbb00d7a84979be7d1b26cc084c2565675713926ad055b57bc103b19586fa27743c4db1a4c4a67213dac2428862b636237af5d3c701d297a86840c57b236cb5755aeb9e22f172a2a3192a6279c2c7c4f943828f531c03f72e24702934ba122e6428d6ecb984e914bc4402671409157b008ae34af0717c785b9777e217263bb015d2c4a9b6cf2fc80fd5e35f20d8194d219ba2da8ffeac991f3a64cf93125b0c9eca5c43f116392b870628633936999a0fb6101f644c479242da33387534b6bf678d0f9aab2cb44d43566fda31599c39144cf40061d08c1a2b594a06003e2c597933ced24c25b8d0a6bb742921603349c74d55181508b6a2c77012abb3717642c7b6eaaae3f23ed751cf273477538911edca33c139171faa8661fab9fb56831c316f85bfdefd47bb64195ef67fa04260712295f858baa7cd9716a179ba16f445495a0bf86ba785df7642e807d3e662d03dcf2f26f216a08e908c953df15f28788e88fecce6aa4cdeccbf14904b4895c791885d5f68e85a4d61cbf7b60d4d9917fba58df4ef79403900c65fe1e369317357d17ed581a1810c20134aa64bb5affc +ciphertext = 5b97446758967a9a4ca9b87e5585daa6253269f5dd2c1257c5bfaa59496edf8b32873e1ce2e099b32f05a2e7b17271fb2705d1a95e08b5c5be0c958fa2a18ac3402e78b0356962bbd004f4eef80f6179474b1bb8085dee0d46a8f12b4b2fa4577fe146eb4639c772081269ee839155a3662157650eebc43f9af5a5ff0ab11c73f51c82e69945e1131137cbf00e757232aee81614f90586b9ab480c087c4f6fd3c58ea55e9490c8026f7f45e36a6b027bb4d2c22845dbae79b5e021add1edb8efd8094a8ce17d1194512e49dd3d8444c8b544f613eb44fe93a4824ceaccfa64c71f62320bd527812c604dc70aa08b0b9e8306a785d23c6186ff58fa490c5df3e8e980157c8283b4cf1fd8daf7b84525f565850ba82fdf5a5d24d204a810cea323f0221cf978bd3a34385ecb37f1c9b3218ee7297316c7cce6504efb918d0ae16ff69195b534d31278de22af206046c7b97d1de78619c9df5cdacf21016217e402ca6b28c0bd3d9a708fa0ef8110bc8d5e942f90893d07d6db8eede2a589180881e5ed47ad29494e2acfcd56273250632fd321058d59aa99552c16f7c2ae055563d715f534eb2c71c2bef4212caa687fff5430988163749842ce91337c003299d69ff494a338504e16d8f53c6e1230cd4066b36e7785c8157a362b91956e44887a2c8e11dcd6cda1c418f438609a56a890e9e78f15a5d722ae970c73d4fbcca9b3781b84e9dcdccbb6521ac3def794c3c6a64a7f978f4ba64a3230731474cf80ac20dbd31e80b7f0546f4566a45577c13c1de99dd0fa003f03c7ef4b84e0393fff9ae33dba2815e3cc724e847984ed8648ef3a9f40c897aac2e01d43e7054f73ae9dad6d4bdb05e51ca8f6ea3fd43de899a052acfc0816f8aeb85d3ef4295be422ce24ce2823bb68e41b49235b6828261e438ec5da1610e4b36dbe016daa91cbb4cd1921280681675c317dbf8f19970dfb4504090e03b5c72678f945f06ddfdab782f47a7e1fbf637819ab4879616815832c437bb7ad1f9fe1a31ab3b5f52d8538790a4c910614d75be115ee3016360df9c42b206759f6aac9b0461e036cd9d2d5 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = c21585f1fc5b93a14ff895c3a3b111a4681c844a6136344ce3845b44685cf16725942cba88766b03a0853dfc7c2e1c68600b99a0a9a6ff6c5b8394649dd7ca16552a40429cda3981eb1a5252c11fd9731fb7c0bd7712472be65ee984aeff685d30d05db435b1e397754875c15948cb5e6bb34b730bbdac586fbb425e496793c7b6ae499342471abe8249827246eb47b01fd45ce149a2c954719449c77f10353d922084961b852033ad80a266572896513020a003f0baa12720b15c8a061005a596174cca4bc867e10434faba5104a1b2e8741d9bb7fc800a17f145b3021fa8334f7e9a6726fa0cbec37f86a5c1993862f7d2c95ad9c624866b6771b37e903a4a20450c83cc73c35f5e713a119928111722162c46ed617eac5243b75c8385189ec5b3ce5b779c1fe016888bc10bac9937e680a4ca144ee1029ceb4628a9800cac0b0f009226d95a8096b3b93885458826ed42b70752c426c0833c47075c549683098130a072c15233350c152ae8c6e208252473397d8229dc7a805dba2ba96b49524642079538f29188031a37b3d277e3033260525cf3e4c38ae5c60a011fba0c3ab3f670450552d00b497d540e6f198231a9bc660880e8b0aa28f48808a336391431099a10d88a702965c77a7bc29fb50a46d96e89310ec46158c95b60d018231625c4e7f1b664a8c48814633e694e90330c506b6075f93211647e906122b6ec533d07158af10b6e12b5f1cb20ea4b7d79316940839c09a42a8571b2bcd00f6f038d81396abd7c26b37612da9738913527761c692a7523ff671afb4b81c324234e242ab296578d3b1849b15520b93208926d53fa386f9692b29548a379514e360aefcb7f57db49017b583c93ad02e931b1c7897c2a92dba65e9f6b9e47fc5b50e7867db2bd7df6b01c2434af064e31212e4c6716d4eb129d37160b0b0cd70383b2b0212ca516c7e49bedf8cc5219ad4cb4747ba74ca54b455c958067d0429ad8a6191a1f5287cb82e828a3580a5d2851e6a149dfc91de0a69a375573f0f9c92581484bd3c31113ac0c4757cc2a54deb373f5e8b2f64383daf914c916915e5b630db07f7b90b92be585cab722c1f569f3e32349dc7b2ab12877a6a9acb491759533e871834413bcfbf43782707305553f187c1601678bdb1149118519e8a8aa683a50a04157c5f90f8e26c22411a75533c5f84319aae836fcb7bdf4a6c921166fc2ebce90f092db5801bb8b7dd7111f4aa528cedb4e5e0a22aac6655ec0bdf1e81cd74c5b93ea605bba4e463124e4e44de88780c162030cf37e54864f32c31070261a37f2ce07d79f1b992eeada6e10a38690e6b14a21aa8e1b18654098a514a8d412c8b7376733a76a03a06c3a2112cf1796aa368506f067092b527aa165cd9699f9eb44620a0f675c5bcc2ba03c47643257bc1b7abc8044b5c374aaac09a34af198cea82be60504d606af42a4209fa3a4f1b59a27713ebdb620fff26a17271cc6ec5426275e23dcb4911624e6dcaaffe2afd0b3892aa303c0a4b9faa817572948c56ca674b34f5dd825ae081a9ee9189145b2c645bde60295176a14a970a048f48348f238cd6138e4579d38f527d3acbf00114c1e7a142bb28930ec7756d086e3f545e093af39c9547498bf2b2a05ce7990eb8a29ad1263c1404c739abafed3455276c7897c86533bb375314bf05335dbd8a7829a797bd31daeeb8f2a5c0086552e76ca02c6023144c4acf766b2b32188b5034d8900a5fdc0241b4087f2379a715c2bd43600d940c22834bd3079b5a189b80ee83658122b4d9b8e0665bf5aa74fdac24b22b403844598a0f448386caea01c2717f6a08b7990896218f48809b49260a23c9f64f409d6a2b53c7b025714b77cc11edebc8ad3faa22c886fd115219af82def132888106be6f113e957b8cd03615c8b3bcbe260794c936eb73bc2225102536d96576d20312adec06ff21b42ae682400bb18027c99820433e1691768f649cb85c680e08bdd8bcfbe178cf4fa52a602506b7303bca03c48f2a43e099ffc516cb24293c921a3e8ca2e3601b5b540067cd6b51ab31409e2b1f2d78d2a5b001873987f741ec5c9a898438293e0800d064f280b0c01d003c6843dce862a8297287075572c13b81ae51fa8e07584882d94c1afe8016f31523a9429749e07504df6271b3ecd16a60182777f06b39dedccb74ee69196499c59268120414b914166061d76df1b43fa26d5f7a98abbf285c3acb8b2a7f99796be34c2f4b31035d9cf7862c203dcdeef509794a9939ad2f9da385ffecbc6b0890e4878e0c0020266fcfc316aaf1d +ciphertext = 5dd3b189ca5586233bf0368c55213d11e77f9654983c996fe24d735d647dde4f9648ca7029a83a233f63fcd83f1bfb2cfff17c772df976a24ae43eda09c723dfb13a856cceaa3fb7f79e147361dcdda4b715ad430c668caa6914f834b63a933c8ddfef7175a13ad1c96e32b3ab13d88d5447a51a9e533c75344b1c776c2cf8d14352557e37f9d206444564400f9865d52a8194b4b56c43cb8ba7e447aea586bf83a703ba8f6ec682ec4601629af46c1b3779b7909eef11c1259f1ded21f85cbf258c28ad0d67278462fc5a55fd8b2e08180a6e9c09c60f732207b8946ac3d971d9e54c80cde6324f8c04770eb5192969fb25438f59abf6be7b6170d4c53ecfdb3a8670d07a3bc4bd197dffa611f2c2ebeb83bee8cded40085a088a3d281041923dd5c3a96e94bb51035335351dd46df6d79c421b24aa73eb5e0d63ed504a5f246ed879ed67f8ffb0cd4479562091537b2b2b3ebc41543c105cfd231e302855d1ca64d46e06536854041075099aa23bd122a6143afbdc140e9aa811ca6747fa9fa528a3ff2aac10798fc10d98118c9b4ed27d8fd8506ce89e258000e0983156cba31ae5e26878192502a203a85c5b216bff4aed8b2fb14083a28d978252af95baa92a7bf5107af9213103b1966e255b8284138fbf3baa23cf5f20d671fb36533d8cab12c3878c09fe3f05c6175ac4b3a9c78a62797fe115a8cf3325d707d12087c346b33bef4c3d62e4b4fd6508e41c5b7d277fe52520e1ae4c81f92f5977c8a7ce6c822f74fd3a2051da6b5f15ea0dec5d82991407268e3bec8a929ed2a17b5f02c28505bc2dd5ab252f6f7c1615529c9d52bd7dccb6e3c0e6f2d394410b1c22d67831ea193bae2fc817635c7270c831ffea0e3ccdda4707e504a62f968ce90eecd0a59954ae4a0d20ff75624f2028e2b08fe7559ca800feb3e3de2419d1b5e9f74f898392433b48584c3f1c3058891fb3d6eb0a40177f0e77e3c72f5fd757b8c7ab505ee4d9c628a064a5d8b6ff6549db0693aba09439567d24f93dba040fb5f614e7f528184fde07819c00a856a5fa8847e3de9683f7a855e7f18485148da4 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 7fc25a97a120f4f181d078b022ea098f91145a8b5ba086c3d114732d4266f5bb4deb34a1f16b5e2cc37855b72ac5d08fb1a3892009c3e4811b16e6a9eee9c7fd513401c970ed801d877c95204abac8d404f2251b30893ef788189e88bf1229c405cb0ce62720d87c1f73431a2f168328c4b9b5199644a7b073d96a206a96bb987ee44679db9b5f921866bf7150e986c69ff924cb69b6c6c3218cac1e26e795dd53575bb6192fdb153f73c4d48063633a7e61768edf1a5bbd1974fdd46124d774f63c9a2fdb358f24a07550b6a8f73156d3296fd66ade3559f1ac9c9af8395f4a977e7a527ae3999b4b6d827abf79f70f2149bddc17ba716987b4e7cf2700a5de5216fb3296f34c126e15171d1c289bd722ed06be2c6ca9c92b3ac5535a6e78585f810412383ca1266c9f8a060369ab631c9a591b9d28b9096a801cf02b8df4e72249793e57bb7a7f5576d7d8c752a622fe1846b0541f529250c59519234490d989617dc11126fb0dea8974a78903c5fb71f458c59df84cabc076a8530ca066b2f11550c63a02804393c93c09cbf846772437027216e071bfca53171219a3bf78185e3871e6550a9a0a7d3f45305ba09b322234f880c75ce8a83825a845ac8ee6d09703797f6ff2c1e6b62c2de726a780370ca50a2dc4326b473c4d24224952053589a0a8767d0a5c54e895567597c4432442f1958272260d50a815aae71517fcb58164211a4cc536c80ab89cb141b529a88b09b56c82fd70876e4291ea351bf639c4f3646e3c092fc2947d9b7436ba903b1114cfefc39a625b690bdc853a6660f26711ce5a04ce340e9549584c9c7a3fd24ee2369748a6bd3fcb4a6a94272a605c625200dfea36934b4a9af6a1416c1bb0a26b3a315af5332c75957158f537fc67c217e69e07c41bb6e130b1c1b8712a2ea567a842e15a1da75dba783a6b896d953aa534ec56685b762459802f0a1307e2c8e193af6809c96276532c84bd3a70acf26804a68c8c8f01c1a5f5be85827a642898de258ef3554ad4f38e229badc21498de3bcd43c5ac31345e7bc44641d855412745568c4a7e6b90f41a59d0992eb2ba98cc7b2609a00d2b152d44906d0e883787aa434c91040772bf89f2a36adc8a8cab7f3d258371183f00b13588d631ae90806b264814f40b09398a7424b741cc1062e4265d897410c7815da455699ca2dc07c58f7c657762cb4cf611db8420aa4a1ad0737e56dc5ea4c14c011c57a55c3e037330e3990094b8b724542b8cc636678c11d33622ec471dc81cc1ef5c97d1427081f413ca89c842e65b0df9701649cef37370d950a00236208e224d7fb6b1c6b9bafdf948172a08eceb36a68bba787c12aa83aacaf3169ba9c46bbac62d8233e41918d95b1593d6b690420bc7965b46a23403362fc0b440da79b602146ff5012437539a347545c0a46583998701fb4e8907bc6e21bb913427e4e39853c59170e13921b4123194cbb2bc0f49fa505102716856597e2a70e36119dea5526a4622c990053553ce5f176515a5a049c297494ba8b1d3bcf77888451731686622475b627f401a61864147ea6d6671222baa867789bb4802212468c3a4b592292a1aa09bc2382896bf01b0fb6b6044540a1693a0fac129e5701d53a4c2dc1a28b3294f3c4b39c521552b260269b78494635082ca6460ec4966032069c884d196877fc1240895af0b72b51b57a872a7b2f22264e6d240d7587ac06c8b19734480687765a8660a7530bb8acf3583a6a3aa3f0b6aaf45f9be512ac2ea45765ce7462a6985a739c757ab9e83a6cbcb6cbc9368562b4484e87940916846296884b0256bd4346ec1c7135122cad583a9c3e11196a65e0a7a210322929f9857ab2877a96c155b959d86a5ac28e18195e1bdbf2195841706573b3aae82aa221489548c6aeaf443a6d8218543349d2c12e4f5a64d389d0d60999330a93bb550bbe32ac7b47aba8754dd235eb77c2bc2d582c9f7aad87b0cb570ba3033c069358356a56eed11352b511511e8833735570d6282f68990c5f32f3a782c470586864485d1538be9d124eb1aae68561cee875a36ca5ce8b0c6e21464d10390f1b7b1f3d81ed52355d2138d7df84b3b91414af9b902fc4c313137ff0a2e851875674243437006806b2aabc634dee3b6c8eb29dc927c0bfb3a2c2f534f711f97dce5f92b538dbe676f367182c0f7b30281503df37bf1ef7e3989f06517dd92273619ce6956c281a135bc060aa74cd3e932104d3ede53b2dd077b4baf0512b42991f567da6dfc98974122b489e6aec71c7c5f46a453c7427d1198ae944e5e +ciphertext = d64b89b9b82445df5c3f1f1ad55fb4ce6359adbde55b6a0968fe27bd84e246489b726cd7c2e607479c3ae79d4490cf67dc6448227d64b33712e81290b7a13062f53b8e196c54d83229cdec8b776e82730a02968b788767993a4641f8fdcb5a3d455662b9e89ee980aa198046661ba8fc3f8958aca46068c7f3ca3506fe8abcde3072c57fbc5ab756524d8d1e3928542880d21279f3da45068e7512e32f11ca26e4c155186f88b1ea80e33c8fde0cff9a418e11b41bc2e82a9a637e522a2bd9a2bddab44a36d755c27d21a2d4b3fdd5625cea7085b0708cc87f179280049dfcb05179a884a0560b76f5a5782c08463c98b42d341f81e3caa0f30a13657b09d732fd40cf4fbeec6f0e7055a8750f9fcc060eeead2f1c91f0a4438d5d0b368a5ca2264ae3898fa079aa11b905e21ec8bf65c8b1e6a92c12681572ba94a5b1c15c3964ca611b55cfdb6d6b4cf367986c2a8cbc834463eda0e0d9bed6d6031b44e2c9f3b09c13cba10e7e05de6c1e39e02c63c9305975a60efa9dc373e3aa25c3343a4f452159d1d4fa43e11664dd9ed2442bc45c95069b37aba77adf20f29218362afeeb1a496c9e0b47438fa5d8540e148394a88dd24761484d5ec853e43f4b4c89d89a15d577f6404dd0502e4859c36599b2c7b6b3cd3be027fe569c7476172ddafe3a08891733801e705d6e18f63004afcb587bd9cb4623c73436912ccf945b9fed986c8a4bf652903b7aeaf723e2701cc7193a14b7d9555826d0abfe8bd6a12594245926aec9a94da0c5a95848657afb6f27057efe2d25264273740188e5b9fcc434c83f4d90e8b1aba5957c7364ebf9d9d61e284ece9ce9b9afe8e9f9f41d0a9ad5f839aced0c7861613f73f74187afe0965d4cb05dad194c67ca5259875c314dcd4483b1e97e00376906a5bb429621d5c7c82ca1faf044263fb4c01cec0f39a038f8937bb8932534de3bf3b07ee8aa21b8daa9b2d1f5305489900258250a498a4f272d7ec96516f8303333babe89041da98d0f9ad2b5de35432c9e0f54e32792db7be00cb75b92a769671f24a51103ff604cf069dff9f8f2a9e9a2d0d697e5 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 44f3c3b9f87619931efe2277fa49accbb8b7d928cc2a96c64b476e2979c17195a3570a59dbab9d4c8b125131c539650b6a10cade0aa72edbb4b9512602795264316f7c062908847febe60399e0441fe71fefb7754cf38644546b6c3554478c4ad2322632b0b68f1670fb5319dc90ab83219aba6326ff3c764ae24e514029421c8f74847ffec0c2f5146bede7543db9660b10b60dec77e813b9aa4c4c65a69d251049a905039911c8ac626d306679027a1f57485da4e0290c4c4b0ae2486a841762a3aea3086ed50a4cc0d70648796813b9a460f185bdd43c8ebbba411253cca768208334b5fb4c1748c1016cb8045932b7f47c0666302467078ea3c3c323094c7c6a3f4c2ebb180f1999819d233ba6b1553857a94605a37ae31fe27cc0fd38109721149fb165cdec3e0d283b1b031944cc64a7602ac4357ea8e307cd2201f8c835c8842a6eb515fe6552239b3d53367270fc34b73235536b27132a3522b76104d43eeee7b21e83618e0313c1512f2e0a2d8d0414bc23bc02e56aeb201177f855678780e968cff1408ec1acaf45b382bd854dea53b4c3690343752dc8d1bfcb355118bc24cb903cc5950022e568a0c622584c1c84cc162be862be03104ee23944f556b0d9a8c556cdeb7abb23a89a91756fe01159cdd26d77e8132cd35e6f98c8c292c7d86b9289973dba335a40a43272863098428c02dcb0cb2c9989f5a026c16b649c17820588448290e9722eea703fcd0084a2b52d1c2c5877a253a108102816adb75b5325d3b129578ad5e771958c0ba6a5a94db18cfaa45995806528ac935d3ab0fca31cc1478ca8c4148e894c06a5b96580683003849dc20c563c8df97c2c81675b295bb17ae57a517133659c4ddfc0601ce222b3ec575d6b06967660338b5ecc257eab57b73869cc97a848b555c2c5857ffdf2c9398678d59028cea98c5ef68347ac0536118a15e4b701d5b4c90802ead18d16b9511fe90d387643fc480d389b6a8ea19f55f06dfe495dd8b65d18aa4007c29c21f81f39b017a2b78c2f483e061b74f114a2e61770367387f6761a0039903e69101de57a9e36a839f8c41d2b25937c9de34cc2104205cc273b59e1cf728c965ce82808aace53a9bf2f4b7e4b491ad032b2b754af6493b8f9a8568cf70af9faad44f329a0116969c13a6de31773d8c31b936bc2d3a02239c82e266b4794a597c307db4243c63b027dc4bfd78a78f874bf3e653b02c55f1dc3abe7826f0624ceb2d4334b15afda988a88aa6aea799d989b86fc876555c2635f095d4fb97efcbbbcd309491c01a9a5526940f80ac4bab6cc3c39fea17fa39974ec5360979cc75cb30167c5bd640a341971b76bcb96036b6b7107ca25b13f526518470484cfb1c21ae70ebc1b2c5d4c1ca6228485506ea9530409d7917fa27910621753b63bf9b3b1a565b8020484328712ffd3378b0294c26a90b93707d0d4683fa66f935c4f97a3769eec3454fa880788a4553b048e43a7d0981b87bcb9a1b59690794e38228bb1cb4ef7f486ae909c063971e32467cfe7967de541d84927367a7fcbb49387e3358cbb66a76319d0c003c04a82cd2ba888b00a4d382ecc17a54974667f2a6630158d721884e5547262742b9ce3800f8593339878ef35cd1da43d95329a68171102d98ba0b601b8f1b5fa903d7f71b1a7e251c378240c9a6762240ec5290fc8e28d09e35b562360be1b26e251100a82a913d2a5f01084e58a7c67c5129a54a62226b96ae6555642403f1b0c3232ab1f9cab12b850583841e8a32597552767009eeb603547a59bf5769256867662746f4f312458f81c9a0a3f83777ec9903377717bdafa0922c209d71a8a502b67cc84bdd048899e8c8481ab57a3cc0fd6e0af7ec83b34f9bb89853547a976c9d46ef9b11728f66a30264a1854192207b0b7c5ad3ca5c48b0c35523b5fcf12b25660bba0806c691aaaa9f14e91535f23e3382e670e04034aa1bc37174c1d9ae0cc5b62191b8c5780f0357adc95134607394aa24bc68a3b4246a9263a47714f13b13d1d80ce37910bd8289e0be850db01c8c6994d12e132a7d534bfb2c4a45552d30a71c96207383430cc3a3dd6b3a3eaf2af401c93a4c62937646e8e0264bcf183624b44057a29a3985ad1759980a8ab642b34606c3b39276a527135b52402d2987dd4a3e733b3fdcd9beca6ff2a2d7cf1695779a273104e2553c4659bfbb7b78efaf10ea7741e3bdba4f6f9973782f0b2d10f7ef6196d530fb4362a02147683d899bd2e75e246b1f64777a665bedff017622077b2b0e12410dc936aa3b48600195b1bcf2cec3b4a95a974085c592518e2 +ciphertext = 12bd8a2f1997aefc3ea5bf2336441fa235eec901fdb0f45ba548563d085a16487adc1a8d2de1973d7613e2df2f979e38abc2215bd29614a5a543af101afb5f91f2079dd1ee52d30a262c7eae07a87bd05a67476037ea45ce7c415bda737ec2ff4273454dce9aea48705dfb2375b0ca2d554e6a02b6d073a442d25b29036e3ba88352abb3044e80c70d15106d582ecc5432288067e5dfa9a68c8b5df8e5fde3e827fa6208118cf2c18ae39be92c4a2e70a3388b7ca18c431920df0170957803fd290a80c8794aab83d76331bb1d8067d41274bed3eaa9bc6d1f5d3044e6d1e3bd9da5402b9491f83b0086787d0dbb172b9f796b7e489475f95bc279bdc9683fda5f182596a14b0fc318701089111453ba38dfeff49554108953d483e873a7d5cfc0475cc7fcbe0eb55db093ce5683fb584a6e6bc5d0996a51a941f5c2170e12fee1e40049a4b6cd4bd8e4ff7e85f4280b38b7156cb20e8087d9b930e124f6901a287d32d2c5beef86d20ef53ed89ce88ebe4377ac1d89860b626df7ea72eaa4510c157e4bb7c47b51890427a9dcf91560c8efd2313787caa205055c0ee7d0ab89ea7730d55e4f4c3964b70e1ce0e527a96dae946785a2b0e51819e0d9811c87f9a8abb2ced37fd0c3d45486800d7584603a9f7f336922b6ea3dbce18b0cebad93c1a75f83042d63561ebcea1c443f4bc30b90176f054cc20a0e58ab3aa6f1928a40a04948f9ddb714f84a29a20fc32bb9bc4ed6e7709062716ba94ab915d231edb95c7a94681e6466ac14b791b4fc13a280c52526cc559d75bb2420b4a162c123aecdefd68fb207dd0a5c9e5e47bd7fefc4c055c459d46df9e15229a2d378dce484a916ce9ca9ae1ca4d4df913c6689c2fd2163cf4cabf3ee9be3b131b7b0af21f2b9022739fa1cf741da46cb4157570db2088582db3c76567d0f967bbeeec85085de92eda19f17f9afa017b41a27cecf1ed64a87ea9844d746a33be62a8507a7c0be008ac1f6a441601bfd608a66fe5461bab0ded64a379521400778510891066ad3572bdc439b2faf27b8713fb0c288397c7bba4f9b75065701e0190b232b4f +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = a3b01cb0107bb87a0fb09b7583b4472cacc7c764707a9230ae4847d48c65546a1a881589987928e1aa10e272ac9ab1baf3c45c59ba81a66a90ab512defc1cb93a30e085938e228031363b8def22f434261861976601395e292899d4c9a3f33cd0766c88f2cb826347c9db769b96210fb8a4ad9331bff6a43d8d65aa4c3391318207c258283ba0ebd661c42a787b7f4ab3fdb799ac00cdefb43fee4c1fd6a5b9ee118ba81c217e39e4197bccb862ca980379ebccdf6290ae3c5c35e546e6d594310399c147c86eb487a5eeb6862712e6eeca4f6ba2ee8c1a8db5c3945b88b2ebc61124758ee694c043cb9238729f08a9cad982593189d254c91f2c31fde60790f5bba29525dd0d73525a48b58109d48eba3876705b2c720fb5b0a18c22b7c467d27b15ebaf1cf11d9af01b010e76a3e81078afe6b1759dbb99e902b9cb541f81a9d7af10f7f0810976797f417a9bffa085ecb4bce31271389cd6092c3c1a09cae7b0b6404467bacaf47c3c47cbab0b7b72013c0606d63b4bf674f116381fb921415a2493ba51a6a25347ef85e03a67a81fa7478e97b366419e80219e52b0dbcd7c5ebd56f2d97a888a234b3417e065206217175b7aa529233a089359d1c647cc4168d0282b25b94337c07669a3794bb69a9c87400ebe35525c63fe5fba6d371193c85652c1c63e15509c8d604fbc74e18ea77a02338f7e78c6b681ed9c62be5fc7368e77278493ceeb9290b59a162b267258b8865d00b7bb66987379c3d255ebcf34e1dc884d1841b87a263928ac61a4306a45aa9f36715c4a731256b42fea3b8b8b996cdc7b694ec41c9386a886989b8358de360917704539da62823965537238870a93ce08594c6a9b352116683453724ba02e9e213b7e136769b4b8cda68c7d897d0259d46f4bd389bc8d4b89a1cf4a246ac9c473a56b075bc52465ec2dc2d5b9b84f44a68c4783b5d19a995ac218ff5a462322ef74821064b5b5936c890b3cb45335726a37ea1e086234998a50b2659879ad04c6916fb360b5b21a191395f184486ac32a9f86ceecc8c1928b3b65185e4576488d603ea2960f185727e7178d02038cb9c81dd433964195333978892e4b474c19361ab800f70611868bf41960f422335f035115ba37284031bedcbb883e7972d7212c5a07b046814cfd4b9eaac9d8e193f13096b9790ad613987a4b171a985165306cee3f59282b523ba584c25c240fa13294eb6c0431a4e496b05c8c4a31a62be53e72a61b064403a58ac9736420b28afc96362bca45519595e495f1a43a25faa6283b09f2e19939c93733b84b176c7b8a530239d507d5396c928e3561fe59adf55c44f18261967bfc64a671c6922aa6b018139c81a948f556a88a5d5168a6859921b8a2f4b4a05e6449bcb5ac3b64df8b15042964ec1b56484fccf05c8cf5db05d7294124f921f31513bffe3bbf95c3fc8947e38dbc2dfd33c48b0105c179cc4eb294c3a9fa4f8a89802938ac975db433df2d39bf3182c225b874ea63aabc9624db5b1bc17b008fa58ec86614f235132fa574a0765bcd67e0bab7e5c58a21a6c46d1307720fcacbc630d80b60eabb629a3f2a85a12b04373b0a653c7e145084c53052549bdda5c730113622a728905293f95b3876e037d9ef86487896a6df7c51b1c7ce11843d4f5a05401be6969c4ddf7a1aa7cce92b0bd776ba107060131d7b397f4461d869503f1c4419715e7b1aeacf1853f9968755275739a1c2e43274f3849136a0d4845743422a7bc51cf8fe07644eb019b42c06c2a1843fab05c89548aa047cc345e40b1173c7848d4da14c1b99219ecbbad978cda0cb7bc0b76d0446bd087911de6730d0ac34fb609bc855d9960080d0a082e807686b161722167f34900b867583ec55f12e607897c56c68279e6f34c06303a6222bc2b0b1a52fbc6c7e44b9e08472256aed760acfaa5cd034850313a0596c57d6f444c9e1b286270b3f31737385c1eb3231491366ee2180fb150625f072332b8a045f78793cb9d2ef23bcb017de6137a78eabb7519437eca5e74f92330e1c9bbf1c128d88b361caf8ae7b771b6ad8d085a037784d7f1122195221c23593949c805eb2d8614a12c78bc0907c3ce370324249c9629ad88136ccf8ba2e87131a29317af0728cd0b75f36280eed1a73f517e13740136a43c3c1a55bb8b4e5babc35f692e374c8164b1d4152db87cf5ab322c5c9334d28501007eeba5773862426f06629ea571e869765fc72f4c7f8685cef69c9634ca3a5ff165b3484f659784a753f6822e194f10a1a18eb748d14e6bad03dfc97fc9f52466cefdf5 +ciphertext = 7e8b7f8f52522e1f0dac958dfa419746d17fedcf2a099d097c9aa07760ca0079083d9fc5753c911d8f0e2daf790985aef2e1051dccb9ee8894c8f6ba194a3b60ee1508c197c383d6ee0a457f576e9c775ad0b10767d3368b3d8fbd782665987291c5bf413e72d474113a3b8375b65e8dac8d74236650a945774f6ac38685ffcd24ee3b730a3995354dab111e7b2a47f7d90db5340ee6ac22d2426c4b2feb8acc0c8c37ad707dd38d4a8c40ed138798b399d82b2ebd85ef5437fa8c8de92821478b07ff9a09c1177392cadf88fcfeb3faed069f336280d945e3694542fc312bb6b9810bb9cad9b44b61340c5cca88c9cfda06f2606d2654233c7540e72a3747e8b62cd18c64f6ac289e1565553fc151002fefac4551a075b94483d715bee6aa3420ab5a192d1d6c208ea58c0a7097b44f4d5d26a02b2ba7f1e1c27b0eb70291e69966e53357bf63f98ce05c59fca5775badb9b2f923caa6a39345d96a36378ef7560c12d8844a48b8d1302aa472d203e433997815420497d2ecb45dce2e434cc1f07b8fba78453d752e6b21b627a1df9de3ab3fb1a0e74059aeac117d2e7f6a2651fc282b6621d3c8c292b2f05e2dc49b0dbf884b708e0c92a18657a83d696a2d336eeda743212a2538646fa428cd7b18895e0b6ea1258e26937b191f546ff00f24fa28663f1d83939f0f55e49f96041fd4b2e53a374eb1a4281c53c8efa84d41684dc9d9dbee3973991bad58bfaa8ae8172c6ebc24e0c4b0800650c94bf8479f6f4efc96c066be3107c30dec3f0a2972378cfbd4129b3723bab58b068864cafb29d232efc1b4b5a11dea19edeb675a622385731e2c52ebc7f2e9581bd01f9344a320aed5c47a6ab60eaa472b13f631698a797a317ec2558f6dc986c428c23bc427c3d2e45fb0e6e7d26b733dc8e61020f0c92eed50d179c8b38fd2539c60f01ca4dff7aa4a4924a48b1099d7a0e5768ab99e2359ac92f384e651f3fbfeb34651f8dd3196319a1cc2e69ae180466e44ff63a3aa9a4919b0f1ac92c5db6567d185bb13aab91925c9534a8ad331033a6266c48ab081e53f71e8699e81d93ff83475 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 31bb4b5c5a4bb786af87840e86052d6b726fca8c8b1830c0760b081b27430d737e5f513778353c96654f710451415b9629ca46d9cb4d3e0130e0194b232799412b66217297a3e030d22347c6e246939ba3b68051899061db8115386799fcd61ed4880e291530c379784bb18cef458e08147891643f28cac960520aa925bf2a8484442c0cf2d3960b138c61670a4a946cbc261e213c18be464aae40a7eb004188d3135aa16212228528c6419538730fd67a85c28dcaaa5d45671743f494d98474d101755e35cc2b010901b9b2ed713df906d0442539c3e02776695b40a39ff71c90ee550d80b20bcfd481c73286d5150dd114405f1b6eca62b8b5594a8574024917436abac0f764948c9a58b63979319427b1321dc9208d82e1caf8a939fda65e49581ac5d07025a19f0d662f27c86a34b89047806d7e1c1de7e32f487ab834c82b04574501f834a0e60db61387e5844c2ee7a06304a918772df86543aae42aca4264123334eb281c002b33715b81de50993ca27f89978a33983a6cc071473595337c97f0415c6688262f25cd9aa92a52245f6082c1b221bfa022ae250b1441566f04189d7a68b4ef4835df9aae1c3b235c900b7479b24fa3bbd7f28b5ab30ce7647cd883597833ac854b2f41856122c7405c276c389192e959648da445ea9abcf856a063c334a8c65fda10024cc040e989a591055e1d836c7021bd8786352423c6d281a60786457d224b52e35a61034a3f86a4b1000b768616df4911b5ba2c241098d582936d253bca1928a1149a709982b158c31b8a235d95cd9a9896d507b333e7cc8ca3a90ed92b5754848059666fc7582ba63c345b53f90a626bb49e65044c1e5c5ae74344bcd118e5bc012999c447b9c4f4d03b7acc2cdc281f0e7a7d0a169d5b3054ad621a81d36925fc61159a9fe26038eee3683dfa0c9e7a26b926667b16a58cd0b39112ac7d594cd498373030b536796ac2b53bd6aaa5cef637758217ea343eb6b3cf6d757c79f78240a194568175cd8a9c3be24f82d8528a1a6ae5e63388b572fe447136b266eb48348fd41ed941ac7113a11e296c3ba38a8c19c9edb4cf2ef6ba0e1b90c8469b8afa6092caaa8b18a1e793a1876948f343c8b3e059d753179973587f9a4d6d7bc5550ba8e71925897a3b4ba9c83100709694255a0c2c0a9b111cb0a1e82c7842b1a800b9292dd72cbb19053b36897669cf1a124580769908dc2e0a510d649972bcb92478fa6adb353831099f76424836f3c650f40d21231114ec5ccc52bfe391914408461ada11a5713fa16417bce658f994b2007701630128f9a087e9578d710909c7318e8cf761fcd973ca678a638aa62ad0775ee353addc412fb32ff7a0aebab6cc2055c9993885b2301e621753755186628c77e7dc84c262284b7588a1bb86a44527fbf9cb0a421c8204ba1a89b7816c19ece324e76cc3955b23fc0715d455c107078be77c61e201379bbb3e1a649001946fd2975bd51033b896c14ec91bc7a0b4a69b9908ea26cef70934b36f791278984941b41c8af9916934ab7dd0d4c0000b9bf99a6a3a899a3270240a05516e0b7d38ca5cdcdb41db6a5602654097c7500387ba43cb715397c8dd433883374bbf847302eb0ae0406570d65b53032971257eca6bb73a6368d223613d0a383a437be5a12edbc0455de31759e17d36604149938e541c7079b82c358b70e7474a5822c2679613c19a7d56d219309915ddc22944a18f28126ba8533a41d62386617c76db26f4593d2e2c4f329052ebd93d100b5e37e6697ddc5975724553b30d55c7197e2243f5f3585c8504e95ccb262b417434c28222226a80242e508c1dcb0993a2b1b2658907a6986a3b8c08f2ab40f0063da3478bb97f27ec83058b9d5c0122e711bc231120e26574731355bf583616fa9012c96354238e8a6524e34ba3d81b3887829d8407897acb700c950d920695def472f8d404b8f68efa14352510456ccb037e994e9e713a99323edb36bc9c211abd5c7c5d3437c0b38c53b4b3ddc90d18450fcfb1b6610b3dea42873aa495941a04cde181e88157f33592f3723a60e8614f4586fac9b6d4e5c38bc3c080f823b58b2bc29b1054047029b205adcb120d512aab80af6b19954a7cb089f9116f121f4a039ecf5c195441084f62052c96ce0168b769b66acd188c800eb6bbbc87e622aa2b3f27eb26c6e2cefe1a72a49e90ef402cf2d47feadb43b1a57c9e47543a80790fb737a176315ae6a7d2656ce4df3329f1195119dc1b3f9b2ccab3673ba5ffe12938733f7b6ff0ca9d41d3a5c09065c176fbab3a +ciphertext = 07acb9b6f0e251c0fad2bef42d71206691e6e8778c270f213f2e12b4f84d503f3c45f52cbabe5a29d49954cea65a1b90cba91da87c97296661bd8437b02804646eacaedfc04a29d74a20c68280c0d8a2d34c320b666ac91b0b377040048351158181eb543eb6ecccee1421289fb7755c6cece11db89e019ca654fd65fbadd0a3fa5d49867ba5a62f398ed2ca22275cfbdb2523db438bf65e9adc353d1031159cbb754eea2be9ab185d281166bd84d8f1bbf9ab8fb593539278edba6ebca765a1b55f630835b208aec27268e725baad856281884f3c3b675ad8743a99ffced13a69fd1707164a322a1bdedff98079ed8138797d3e2da0e6c1c0c96536fd5143daa3cd70a8640fb172e52fb444b97fe33fb042646e09c9c583630c2bff1f430a2f052a23f67c84d995ab5cbde9bc3d53f43af2cd52eb462a9bbe56eeed1c19361de9acbf70b115825872ff5f4d5c6440282f1fbba1aae7e4484f5593a923167249145c791c63cf756959e159aa7998a6c14fa2ea30e02769503abbad972abc59613daa074aaa6b2e591a177aaf47d5bed7975d89400424a72f6410a0299a1e6b5940c5436fd619ebc9d81e7f80915c4c9e2cd4270834a6626a624d013fa2d56c00548a1a9d46e9324e2749c5dd09fcc0eec342b1d972b2ed80026d83934dbb6c7536a1b94654056341c4c56af185fd64f4b49b9407eb2a3217357516ad06642834cda9fa1a8a9367acc6805aad25bf4c02303e91eebb12999c244be9ee6f74a7dc705ae247de645ccc0a5c9a9775ff515f6fafc40e39ac1690b2ceeae38a3a353141186ade0379e1c8d65bc9de059c36b05b87ba56496287e0f8d09a7c4aa4ff237b68b23a83b367126dd8eca43154ef5cc5aa9fbdd874e51665b98efed50b64b3162e686dd8543b9ac2144f21b991cf06431682021399a1f124b50ad928c4b932598e021c1387c1dff9c06bb3e8451bdeed0dfd7ef65ebe79effcc00a2f97e2429ace1c8d51d315bca14f2abfbbfd4539d29f180960c88cac48836c86452c83a5f8587f440ec077ed8745899ddf3ccf09c35c66dab9b0089829c848ef04d47e91 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 12280ec7d56e55208536c713836558555bc25a3b7e28151a5aa40b320c8d310a9388595f7dc3a7555a24e5c08f302a10d3679e0136909955bd3f9a3daeb9cc730457f999c420622f8c20438d365dbcbc4b1d685914e579c0289eeca0a149760827f62485b01fa5c362d0284a490393218a8fe4805a97256f7245481f500768f371dbc40000e739a1d79540221108b40d93f35e7136babae839e81c39a3a56e934391e1211fcf4393d24904103b5e99bac86bca883fe6b3b07b8294567fdf922b58a2b71db015dda32847baaf51c9331a29a3a4d4c1c183611d4397e65657a22204d7d2a8a4a998f5632bcb907d0f62890a690b9564744bd499a3b73b4652cf8ab6132e0a46236781ac378177592326533006c25789e459585a95a2d34794f941d52970829c172ca13a27b58b52dbb16a449d8419c93478aa941590905c0c54f07eba2bca95b250167013405b536ac7323c74b578581e500185293b01b9fac2e629cad225427135b69cf8224e792d994115203300dcd3195520a8f32634f43173edc382049149760a868f9233c3e20043e749b9a6c664309b7b7115f2899b5bcb9a11f84417a879671962ea6ccb78558a2a26c50c8a02008989a0dbb5d4b3ce43001849186435915698c07d9ba1b2d8f42064b35a83f54eaaec6281a1ca2c72128cb9b487c88906313e55893997578a74d3cd65a903c340b8a9f32aeac58297147cde89caf8d94c6f341b9a96790d051833132826c152f3aa4ec4473921bcc562233fb72759177bc20f6ac93e32ab5bc3438f624a2bd623f402b00d33843de29465b37d1b32a2e63b7cdadc16c3b3ac617182887bbe03793f43a8a116e45327c81a1ab7c93a96b3e1490bb5f71eb263c796774b6160aaa05b10a8c7688afb1129512ec5f39914ca7a3d73681ada1373d34bdb082143fa7d3011441113ad4116b3f62b5f36b10e756c6b375494baa2a320f0b556f11d091c3393814ff8768405661dc4b021086831cfec85da07adb178b0af7567c3b248208a27b858cf38b46a8aac2bd1e82265987c103a5216648dd0c5aa794510cbd03d96298bda65ab8cc6a8bf9b08137a7ac66a48a66821b610466da3b4743038b809a49e63927631bc599597bdf65ba1f3a9dc48b9e57370e9e6904b1797af4266e610ad74f756b0577dee6805115378d770b84bcc058e042a2bd9c91e844f2f9ac9d868b1ab25cc2c7164b730b67de139b46a25813303a2eb91f87b53e8e165b6319e0c4a3093565f3fa89043114c3ca2ad39595819f482436053b9b6540298524c096b66a1b4878657f00c6e2bfb24d61a4b49cab09df9c1b2e9b3dda3a9de7119b6924ba79c8198346656d6ac48e9771602d0c455ab9e558abd6341cbcb190b6164cf809a07c9874b7ba3ef5a0913097585390c091a4e56ec393e04acd23c0f614603db7a340e060cb0045de53a81bf413e8a141058e7c286cc0c936b9e57f3a9954790e6f15b02c0bf8410a60ec4a3b2e58ffba1c65954397bf7a758506aa8096c501157a1d9c6cf8a4380d38fe74514766aa6e03996cb32b74dab0173053a50f3cafc1591ef34446c5b899d41ac7ac18a292a2416f38e4e8bce7af7a0a54004cf999e69d96293957935d495c6c70790ab62a527681fca7213d64588162987410e7f79cb254b15f7f0975930befb1c33d67938dc80536a635a874a3e88a785b60c37e2207b37537e0856a7e25a95b29a9208621e388ab160bc248a401fcf015b88d78a39678ab8d20d779ca6ada10ba4539f989171f9351d39cc1a42266c1e821d57cc2d7e63421d796600c39606bb7f2685a32c7490a32b385515331a6072e8633fc6a25f2bb582c2d753f78760b1348a51135842daafd46957ea7019cacc0a47a15bd400286eb7582fa0c817c655809932d6035a4472776ae57e65f1825f856fa4bc95002b7cae2abf3357472e1a750130458f3352e8dab9cdfc6e63b7bd8941552c9aca2b2acff7c3174d07075bf595dc6713338185b5c3940fd705642c385879226d973b743b7b30015db0bb842386216d3cb8d8b8cd78e94e90a37aa2298976610d5807388d1469b9ba77dc90712abb6999123f7e76bdb5f035befb9d29e95572daab1278115fcc0d3aeaa3018226a2d934aa09c9e0287eb3d16c0303c604b4bd1b6c71df6496175db512b5f9867dd7645fd7236a0dff281978585f755d9475ccd13e25d7100b864b080f3851fe4d809a56ef7647543b763a2580ec1aadd975b948443374550963060d4110eb89a3e9bc05aa8f907aea9f597ffb8ce0ee995cfba5238d808638c202653e17ce260b8ddb4026513da1a8ebfb136ecbd6e62f74d1 +ciphertext = 3c9ac77ea41a3f742157b0c54b035d316156a59edb43f9e29546b0f7de42513a295466c97b5abe40118bba7036e0a04152a3205f5d08498bb5a188e9c70acc0beeda158eb9d120307acdfd9b20e3c554af53da48b39797bd250d29badc1cdc2e56c5cbe9d926956778a1c0c554ddad33c564dab1da2446c32ad3ebc58d3e3add98645aa09d300f60cedf7e500d6cc158f8716399593aab9565e60d4904fe80d03954e82d4ceb591e8f1a8f482f3d10e44a5d311ccc4b54504b7c3340e705c0d8fa039d09ebcedcb11bc8d46d0b22d886fa08fb04404627eaedcaa272306bf6a23ac3700c2ead4ea0e67e8f37990f3480a01266e6011f277ce118d17247493a402d8d208d82d19da91044e8fed5ea02446f57c9ca33b0b5c8ce272afc2968bc01a28841c61cb7149ecfaf8b63b657a32dcfc1ae4975c86f025193a6f4336682b811731e9b45e46fcf6186ab0cfe5385b86c7750ba6b98f229629cdfac73c898436a713e86ba8d4a271fe4d43678f1be0cb36702bdcdde43074056e3db9836eb2e4a5e756a4a4eafdd83509a44a818ddff3009db7b76eb323d31c32cd2e6731b1322d25d5a90fd24cd88a290bfbba4fa25034c4de66f03ab1901b31b82e0e45a5f6d7ff62ed6535fce6f2efb2b63b2f4da9694463bb6044aebef56ad4b67e7f3a8336ea0b91ad0f316791d0470b5315825ec4ae3e5877991fb144ff7cc7b4a622dcb4de7e73159bcd69ff5a984642c1303bc365b43835108a5073af287039f34f26a109617ce77f3fa36144046519fe450a7ca7ebb0a8874352a8a2f53b551efe486ed101f405bdb5cd685bfe8442c0f1f8c7e4e9ff2c007a85c19807b6cd6aa95a80d77cda0eec44f22f403e692106609a22c7b5d1233d9e667e49e7d7e422ab0c785e9999829964c2b6465c5a7937d0984dc594c6d68fa0586645b3ffdb6e0efb13743e7f142dc8f8fd189fc9ef721cf3cd15d810d659a25a5509315b3c9bd771ed6274ded516de30acf68fda5f4c32dc007543704da61d3825aac613e9bc86fca91df830fc7c6f7eb0038b0100807d1baa51708ccd550443f2495db04290426 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 82304b64b8429b4b5ecf0681c179cee229c9f84c6332428eb4662884e8c744972d71d410a795340f9a14df311bdd5849936c5deb5cb033234176285026e13ff1636f11260e03718329858e26651f2d814fbd402af832971e2367e79718b2a6c7854c5f3bacc478252332171819bcaa147c8f90a35987422bbf9176c3c51337c4037a4cbbb485077f17a4e77c55316660a13313e5fb5350d3cc98d2474ef534659295cca1ac5c649267297e1b2ccde7ca51eb305ee3c3612f5b0df2d5bf1d7563c84cad61829d7964386b93b38e8a7b597297c12b4132884cd62c2f7fb0a03fd2877a35501a964d02f450f0531b9464a202d05e8596966b951543140feac0cc06550d20e8459c4902c9636afe95bb0ec1928fe18301039458fc09297c528bb4bb24892129a5a8aea43a9dd75b75eb6fbc4c90d9e38266a23363957f323638463717afb1321181ae359115e3465bba80a2831b0aa70b8054035446ebcc6ccba2955a3163d7cadbb87eea488c72587b220a1787146d0a82871fd14394a8727d536335cb052fa06d0530537a8620bb214b3d399cb4c9045b80bec7f0b81b551c6a5711e16a1b040b9cbfd8c1dce5aaa8cb130048ab78078e93b107885715c7d3417427b1ad590f76113f95dca86da9a4d3a58512285f7bb34dd6697472a874182b601b7144b9447aabbb6caba43b8ce176db965777a44c25d0a1b48ba4846333d1948d59606805345361b9325a5bc720351d451abd80178b8aa66dce088710a02357777e5460af02eaab15e8c3bb0600d5b86cd0e525a3215043126d9c533acd40732fb2cdf667472d954fde2b1fe1162abbba1140754696b25daa12abad122c55d6a3abb66013e5610688c8d6808d6ae64ad3f73de8fa7f9d02cc51b22cd39abaf66208a703a551160357f385ae358f455b02d3889e0d45633b1c6d93a73dc3fc506a420886f560a0db06dd86636645720e0b299b1426fb709d2d4129b2c9786a3b2f69f8c3cd090270ea1a076c5d92412511bc01f17b31b27390db6a0105c4782d5b32a8c228f46b931df02234e5ac55ea0702e2bdc6b240dc65a2839373814c9c2466a6095b01a825366ffb0f200162fa27b3be93800cc142dce68e5f0c3f25a013ec496694522e3a4b4353f553c4c3191c56bdd0d6ca8ac0c00432b824a8a593b68cddca4d6a8971a7929b70341c765c67b6521cea87461d1c887bf3b49f0672f5b915a224100dc20b0ce881c4999986f79364d277130346f4cc81cba17c68c4718b52c5dec834527ca83f5b153d201d8436710130909dcc5f4df04e7c1bb8e0143a5d2817b5ab868773aac7542c06c8944713ab44f173735b466bca84297468a904a94a217192c93baa60c23c783bfb04aa53c01f4fdc203b185870ab5499e70d25d5844ee5547de52271fa64c050ac4af616aaf22d12f4632099cdd8ca357ed12badc972351824ce146ba0c4c5a6f837ac353610f946e4582453a045615acbdaf09a7d12a67730013c8b4ce7e6225b5c034c8b842431231c385fc407bb9975a0bff7813d4389fb5815b8f25f1ce834997067b9b00366fbc5cb1ab5fca45405442f26fa8d1e97998d32a96dc08badf097e3e9c7dba6a365981bdc4c7b3179783c619c48c60492f448f5d8173359500c14b40b25140d086e0a33ce93d58beaa727b8b6c1683aabd6758b575ab2b39a2fc4198f337cb87f66c8d1410303bc41d8d7824ff1963c9bca2dba2c3ef03987e58ee3b35b5e49943bb39d4f8aa37ec17b02781b9f2a6d8996bb04a56a9857886c13328ab77612088a944596edf179fe706de12b22d82857ef541dc83813b7cc47510392a40c92b086be1493c694985e7b423c6ee07d2bb378cde8c87ea0c2a2e10eb8cb7432ec052261adab5c59e819c24532c062451398a18133f97f6bf2a63b715502b55245d454da373df3f38337f23f7393947f2b7dd4689e0d95a2d8684d405b7d55c4c805c90e539502e7e4be9688014d552bd8333c95437330f05e36489b30c46e5e1bccc626cef49172763a1e42a12c9af33c50843a4b21b9119421c3e7a8bec1191e26ac7f1c09bf3549c493aefb9639f438af4cf8c2d2ea9d3227c83dd7a1c4faa12b8973edd872c3bb09475c253f59b2df07851f748e4aac117917099b532b33d273e9c41a6d64a2ef7538ee72fd96cafda3b4e2de233dbfbee681131e001115732a3ce551dc8e713739046f2b197941eb6d02cefa88ed4b467b57cb25043b11988ebe847c0faf476155f3acac10285e417b804a952e4558b45a11853aabf16f757a05dfb18c2c0acae47a5ccfa5dc9d8f7d +ciphertext = 2d7125773103eedb334576aaaf1cee61575251ed0a4e5d91a3dcd9041252d62f7798f0e5298f19cfd0e3702e5128533189097c4fe684349ba675a6ba5e68670f1111459ef03c1dfa8af73d467433cd9b5165f52a93918d462a4d60ca83e2a0948317c39a84869c9bb88f2e37b0d42b3f44905381cf5628be8a4a317bb2c71f63765874969c093ff4d8298cd244eae241fb7d368104c214c3f1653794f20882ab2f0bf5b004c99cc9c1135f3981da43a01b03ad687ea017cbb7b46dc67f2f59bdcce0db5de255631128278de7ba61047237913950243c653f3f57e45c7eae117b20925fb3313ed14f534ec2deec001d8ef6b4aceebe7e2e274d682c81713fe1ef61578572e532ff76b7b187c590260f55ef23ac96f37a5af34d19421b7926042fc2fb8f85c4f8d12d3542c43ba5366053e722577df4f771ebe1912e539d2c691fe0ff198da70b066f9cb1250dc7127976c3f7918f7e347e807afc0cf967df0dde2268c0b871f6bae9d2ff7d06569fc61fd3c1c8489fe6bcc12744814e9b342fd458eb00ff2e2c4b67773257aded056a1d8f92a5286db3a3d8a2ba7f234ca5590da6635f0df3107828fa2fde3728fee5b115ea9c59d63eda3f11027458068723042a0fdb9e5d096b9965d336af833ba509c84fbbf879e1dc77ad0705e82c9e20bc5a91d1a3ee4961b808323fff7594820006d89f05e0d1164cb269b947e6c4a2fcfcb61ec60337f9c365faa07c6d3451f6a9fc620688e297f3a643752e30ddcb9459beaf3e9c4ac8dd944017d8910993ab4446376b987bc9f245df06a490cbe9d27a5dab15f89b15c89444689a60a4d749c51316e7f192a5faddc3798507f8458162e4f95868773ccc448e1bd00ee24d9661624296515e34f5df331c945472743cd63ce48f759c287ac57bf0ff704bc4f8ceebcff3f84b1ac487503dac8e97a12abdd9863775a6c5bd20a63bdf08836ccf4681108217fa7ec6b25394815a0cc244c1e0f6d40c6cc07ddb32966e4ad2cbaf60b702926ca69db627aada5bc4fbfce00152b6fa008f22d14db9907f08cd2ab9851854861a2e01c88d5840f6b47b1566 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 97036620a5437720b9e6614514d42756c05ec51b1003db1a78e0c1df335c169c2564b0102ea43098b54ad9b8b1b7d5568d45a83456a1cfecbb63a398ce746f1fd1a39d75b6ce1398f9cc8740039d38863d1f68a4d01796edbc9bcba079d63147f760469cd2c02df34263814a46eabbfe300672f285716b8ebf82539b356d555bca679a6dbbf1b72e38bf8fe209161b400cc0a13526236417bbcce39deb0840eb468acfd7c89f33b8546852fa850645b3753f311428caa9167a1a927650317ac25f28602bf8c0be852c2b499eb0e712fb7c706088bd2b99b695739ad1218dbca96d2aecb9478c241139501b17c8f3d40aaa9418774aaf5ed7229608ac7bb311beeabaa88674ce2981f160a4c8127bfde9ac6bac5bbe31112743956a57671cbb95a3759cda417f13698f969017d5866337e2968676a497e22bde966a5fd7ab5a313f7f2994142078e0080315467c13d713959a4c4499bdf84824695a29b5ec65a222cff3e1cca27155f088abdd4c4d2dea23c508cdf2a05084b71c79f61122146a3088687fcc54abdb76c946a2cc053cabe7ca3a44373a99b87f7263bde67bba031d633286b8e9421e65782110a57e610f5fd1c312450c64687c0153c40a895fbbd889aa8aa391fba65da4280c969692e738f3d21a28e04cbd46cdfcc172162c080ef6a1ea381ae7f3bde8e91e3dd8ce8afa40f5e2981e437829b37bef5a60d45499aab2c4076016e7b2beb513536b01742ec9cc6a42a367906cec9097790bbf68f364202552a76c1e7501b1d2a044d85148f14383e27c195a3b05741643cc216d62f36e81eb19e12a593864c94675863979756a791cc3a60adb87c9a5e8b1c25370859968de1c66bb6239b26040a6d29b37f202207baed9b3a69bd549c4c600f9e49f5d8038ecab605f0c3edcb51b087a9175238bf58c009d9b3dc795b93852183e642d0c94aaad6311e33482a56b46eec53f10476933f18350cb153c6308afc1005f30c1c62c13a5ea9eec40002c73b448219274193f02d89cf39a176d4c7c44495fa951283284b5400c02bec78f9edc61f543c950f28f68172e9ec02756f1582a1782fc64308b234f82a0a59df250be1a6ad3805d003405adb12ed5c590f8158aaf703140883d32a68dff80c28ad04d29669a3880a5baa26bd9385d725896b0b6c1abe6cd3e576804d8a76f79a160f479919b3914d36c4e45bbdbc077298b4e82d1cef7e8b3c3c78282ea835dcace1e129761d309e320660d1641f64c9fccbb4cdc037733d21457242496db73fc6598e6552ab135af72419681fa838519503221cf14fbafc11a10f540a33d97570f57535d5ba8bd8755bf31754621c36ce60ab1e36c4b757838009b376912632aa799117f84064bd503acd365bf87780534c9574d35bf64489b7817a01982a50378083000869f0cc419a62a12f0589510ab186816282cab36278675341461b269b8789aa2ab7f647a179af4a3e18097a78981895964fd2614161c152be66a2c3c4c98006f43fabff1ba8f4330c4afc39f8f865ebe2560dabc8914cb62d640190df0b97aca6520774db007352f8c84e50250cca859a5f824322564ce1b5b9e77843be7573c67102af1cb2628afd767b83ad341699b07e7d912ba4118c89272847bb170a73f4a4c4512bc864c7847b79a44ea63663b5b94826678883419f4a72bafda09550683e46965a1033783caaf1164c3f4d8586059af16709b4f18bc7576a1a454a76765cca28a4e4634457278412cf4457eb719e54844041731f3637fe0ac0c679c6e808215ba8c7c5e6b8c0e36b9ab256fe5804836302fc3e8717c12cefaa5c394b6984e4aa4849519ee34c35ab10a7574c11bd1bb56f30329dc21de899909c809eec88f0412b9c53981eda30e0699c9a34207d710b3178c05b48bcbc8f45e27477ac6bb177a3349e3faa79e1927389c0d72fcc8af94b101c8b56ecba3f9b480cd5a8529333706b002e7106183c649788068832586b6905ef2b672c375b9d568934abc399e475878dc026c3a2825b0898781100cf9592163129de7842a5459c6cc1788e358766600053cb46f67c8306a35755cb8232a85e3e25f564a9eaf092e6f790f405086e714590962025b0a9602b1671b66c443c3945efc0b4e914e56012398464d4bcb10352c0b3e3004c89632cb037580d443669572e0e1c1c4fffdc4038acf5ebbcddddfcd9a31edf554e9137073d1aa9c8a4b0cbe4baae3c8fcaba29ff9b2c5b223aade3b83370a992f0756906465f551bcec29d81ec58251ebd3cdfa8cf1814af69c70d391d57ea221e905 +ciphertext = 50d6544c2fe2cf2e812865e5bb6934daf4672d52910d2790a1807c456138d5587e9f8fdb4cd066f861d506632c7ec3ded42700b24cdca949cab36bae48920de21a7dfcc35158d23324a253705e38442518d7c43669f1cbc473d12b9421aad52d71ec37b523c38058ee0a49389a63ff87a2bfde22523824dd74e9effcc4dcbca8786d6d2fc3d398dc4f93ade54ba25b64ed96a830d8cf7f16451af9477a3a8f2680de011442350598ebebeffae007e8b7a4450fdb91a7c6cb4d0c0b11391c15b2be96227c8d3aca2ba0646c5bae032f2b502931790efa6fe7856f850dd773a3a0b67e35857fbb33f79c9fe9ef06d532686e14a7141d5fafe0450b665febd5d50ac9017bd6536e06fe98055323a8a51fd734b24129b7a950f961525832e239d8cda4c0506512c123a97592a683b9018c0115063ec56ed6b1f6c269d54b7536e85596c05651ace87715e4c5f5743a3513baa8c95d3ea1b5f78926f4b4ff09818518fa248832fb3b29904ebc377ea7ca2ee571bff39a769b82dd30cd93046e992b9d46f56396218463e2a80fcad0c0810f8802c3ba6d2d7c0a30238a44218d57c9806ec4414258c682fa98373fa431bc3a81d760a90d611669ab65d1529518a64f9786f2e99011c071325aa918e9b6edcaffafe6ceaae9f7b5196874c962de89f8b014267d1ecf466a9075959009dff921d08faa90623584c437a063e6701fd083d2ec271b6ca1a2960785460122b07131386df5a062302f82f0226c7f9b19e94b60af4900a2f8f57c9694494c7818998391faf96c2a1cb9ab4a21f445bad8aefe3cb766edda5b85304dbcef5fbc0948cfaeaaf01d3fd0fae2cff1ee7a302af0ec7c93cb97b8ec9a4e6383cf9fc0e3f53d38d1a9922dedabf772504155118888175f1f46657eae4f66ee07199c282d2b92545dcc6bcc5ca47f0838e11a0e959573bcee7788b3ac93d379d7fe8cfce69bc0ea05fd5e8743b03ae3f4ddd4c7fd922baffd23865e4d0d2e28bb271ac7a17f94bbc7b22960616ed69e89ac6665a1735b2ed4f7fb9e96439041003fdfce6cb1819c38aa6c1abb7d9bad71f5d230056ec8fd18c2d688440c577592dbf18ce963902cb8904af998f056e2ff13 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 5e3844b1d2cf9c81973b93533980b4a3e254bb261a0bea68052142dbc26e08108fafbb22dabb210ccb6804950a9b483db4c2b8eb408023371d95ca13a113a18344265c650719a044b47088492a83a5026734c87ea18432bac949a16b4097eb9ac486298f78bc0c7a247935851ac52a94571bd5f89e93ac9c98781b80375fe156820e857e75798be73880f61c8d18752e71228f8ce9b69cb879a994a954a1131263a5fa916583249214e84ed23a0b82e5aed754c4037b7daf78b02299016a400f746b9fb9430cb28743cfe58d7a14937da0509ce4b05eb48049986280c51c24cb22aa51b4b9700446e326fa04c3ec5679cc6abbb9bc30ccb22679b381fb50475755ad60205cf6493386eb5499f26f7acb92e5c2afdb77b94a561a91436bb70b83ad56890a9277df548eeb6032c2bc4b66b8c6c05907305a84471b521a80a2b8d04a1f637460c72340949c66f02c974bbc7b632786c0226222a308222f849113986c9c457b31abb94d99525684f34321d86e130a9a7448142863215dec1f180b617bbb047d76353a4c0ba695213acb45149c28c7fa1bfd1a1e3df548dcb0c811104f0b827544d4378987a3de409b4a5ccfe76808bd846983f0c7c7e2bd81327c17c34be90402b0626aff09713380a434e39a40e53c5d86a90eebb3094913e2d5cac3c27273098d83292c02309a39fb522859233308448c47b40e947385866335800e8931a0cb611ede630cc1f67b480aa65d96a744fb0c45ea597ad90b0a78008e325acd930b2459508652602327bd63ec1c67b413c0120b2097cd7a1a939c874eaa96bc8f2a105d2186ef5113766071ae1b9f459a04e1d1bdca159d82da26be357878e3b7d58387582c3ee87710cc301693bc2f86970642ac3e9c2988a1249e44301cc6ac5578b810a318c07db2bc1930674aa074ddea1bc470666428215b20af9ab57c07837723320846947e13c33d9d8b2a74e1c6d87591cc86953f9759cf6b2bf22b5c8d387d61211a0739b11dc4bd9b35923b42b48668027a78279a886cac74424a371a1f90112c812b0b03a239b439eb7006c876cfe782a1929a4d2989125d58849e186cadd87e3ed17e8eb15f3c97ba43894a2b372a69322cdf2952f511663990a6d3b4a29bf2093143681036ae0dd807e6381089790470a7aaa4148fb2f9c42af54feaec9b76b30fecd76f85351ca70aab86fb26cf99c34ad1254918974ea89c558790fd12977c961f2d2799762bb3c5f4c116f5c276bc3369fa0ba4f98462292d832767470170b228164a34cac5acbf75f4bfcc57a2694580d135039b4223e6e796c28b9e33928156b10f55a5ba3d7aae3da65c3d7271be5760a04500a7e489a72424bfe6103e670776f97bfe4ac2149454a001536f55b9acb6131a10a9108cad7bf6c0bca0910ba29dc420b829777d4d825b714b960eb54dedf34a310c16718b9a0c04cb38dc59e00765c15a2bc4a49597ac5b91aa7cd29254e1341595441f53c38c77dc2427b9a31cecb8f954519afb5395f53115d0ae3ae9302268a10e70c36a768979e70906f03446649c1487040219a9d7aa695e3b0ad595ba52f539e10a92af5293a0abb275192838f35f427b952b061dfb09ccac90308853247e121667d043330c6a78a477246383beb060a5c44f12f8c17d4068bd009457b367602829e23812d0b1687f463c2f899232a36ce7db175f58c34d419790f2acc43bb10426ccd35487c697a8bf0281909aa1bf71ae1f1b887f2629975922fc05aedb7c235aec52769a5ff39b2767940656328a4362a5b3982514a12ba3b888e54a2b25b371dfa18ea29c7b36793abb955ed67c0b05004ea8f61257406db8842e9fc4a6baa774ea5a8c543c9e4aca3614796c3bd8118cc82ed7a1b4219472028c6e7a4b95a794a6585245a1ecac5411cc562922500266acb97fc1264519d845a55606522abebd4a29d988a4f3053281955920527641b45a10e85d86dcbc3c3750b6226937913d2ea597bf47bcfad5b98232b2987307967649a14ccc95d952afa2b61a0631a5a2ad52cb996a42a77a38437096a98c475659cb0582224cdc438d97d2491d7501d1fc8407942248a4737e906a27268b2d01cc949b3e9af62f88c225f91aaf7cd9969ffc3c375311183619619c12e3e933e339237364a48db5a319e2a606004c0f8b9e57c3e0e88e88b990de987b117c7b4963138cf461372c154937167732effd8e9446e3ff0fb13ab372a9a72f5f3fb04d0296e434c9c2b9c4df2b0354aaae4afdcee7bf322d55293b44b4669500a4e4c16b39dd8ec9106b6ae32ab8 +ciphertext = 35b5ebc7ef08f391b1e2de3b5028fbcfb3eebdae9d043f044f814007f43dfadfe5a7a3ac11ef7a0350b68ce5890872074d9be28f416b67f06ab65a03dfc6f2a2490cea4d2025fb9dc0ab9f3ec771e8366496d6d3ed611749574ee2e1bf565c8b9c8f092f193128a5d37b390a5b47663822511f6741c6193f26d5cade1c58f884a3cfcaf748e3c8703a192a0fa30d261c6fba571d9f2377d616da03fedfc665aecc7a540c7d7617b544c2e7404d863585bb572fb7828da87908f0f9e6168e25c2771033a51ea5aa2a6fd72dec9a413fed08c1b7c635a3a981a2441c48cfd6b2869404be447fa8e4c4a0a27f62e5a52876355538e30306e5b3cef0a7f30086443a6528f2d681b1fb920e39256b200aec01f3a14025a2485a993a399b689b64015a3cb43029c56b2b848956bf6c6fcd63b2c5b0864bd728e27bcf0c0407e6d680459b869cca2f3799403e18ca74c73666a38c0363b148158a6b8d8f3b5d469be031f5c4ebbec55d75551546c014dac54ac21005f3147a2cb7149a1b80c44fd20b768c05f5b9c3f1c354474132661d3788ed6f62eb416e46420c732cd87f8cf40b0338a3f1eeef5fde5cc30f897fa8a8b78baec77f4c3c77a938d5ec5d6345395dba0499e431b4b2e270aeb4c39cf014ca7b6dc1936308ffa0f7e480b802a467d4d2b8353306d0b880dc1f727661573f8e4e74dc23c9d698770f63297247afcc59756d86ffb79366f7bd506cf787aba30381934e95446a16d2ce0b811b51e7ffa2c88b68f8a880622a6aee02f53a64e6eb223309fb2f3eadf2c1c7395de75e1002473f85f160bcbc5dd546ac6c5b4eb55b0f05ecd48c2d975875162acd8c9cc2d77a78468059ee952994e87212a53bf544642b7031840bca0df03c24b0cda1aad7e7ec4def3b367417afcc8ef212bd1df8c936045feabc1ab7d971475483fe61a1265bcecc1f64196418eff0d83fc6c4dd777f493e01dc2f87357ece074c8649c0e60d6f2f925851c0e914219b3a9e53d71d90b7b8d344a5a664e179e022c8fdd2c9d9fb76f3d9d6caa9e2db09fd5e2048cb469f4b8ecb58b2f53dce3c1d1d4ae7585f68f4758d7300a16c1289a64e525936c47e4a102e78 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = bec96ef0010030f86dded771d47c2b6c6a8c0098036767b2c7fa2bf14c2a1bd903d9123bf2c3abfb2ba03828aba185ac51355116f87acf4656bebc4dc9898b55584d0bc5bb8c0297eaf1b6a22794457a253c0c1b3aa34a593b3674328861275ed5ab8118cc17068c41ada140e6057a2379cfb971b21f77776facc19f1a4658dc3f1d2a45505b0da88b56532a74ce758fe4f80dc6b341900532ab149e7db047de19af6fd3b68ec63755cb0eb5e7550bc0af6e490234e9609f4a854a643af914948dd8525b061075e0198780b97c7567b580cea4d8463491bb7b00c5e564b8eed36547a1bfabb8214ab9b5a96588d2426d374599b1b2988dd55e151ab91d919e49d707e6b0326d428762a15ef152a3e6ccab55c5cdc9ba9be23a7a3112314dc5322d5c2dd5f16fac46a74ea99706524d16ec7424a11065e14bf8171cd380aeee5485b0c794530232ea40ace20c512b81031dac13a709105f77bab24baf73c690677b5d3db9b48bc8cd3a7ba0764b76db692bca968c3cc994b638787b88816566c3cce510586889a4863660b18cedd461c42839f16a758e3a247ec36d077478fb7a6310013603e83775e3ab56bcc444dc60feecab8a44c2af9acfad657e5337233dc07284bc19782282d0cb6b5b176e76a8cd7df18c95d232e6075c605889067b20a6b7c196609075615f041464a7d1297a139e6c876f25a6b5420a94dcc957ee51a131717fa9d82c63f88eafd47c03c7b336c879ede6aee9da834469b38d3647dde30aeea4a9763c170e96250b4a0c3dc10dee9b1f16d069c52740c6ba0f34e271a1fb4a050b97436b354aeb1cf283466f9344ac125e65d958999986299a7c97f48778dc9b9294c1ab3aa6eacca29ca7b7842a1562b85542fb35863c3c6880c381742967dc677b505fa5e3055c6a058c8b133bac4019d45a7339cf166a2fa1066a5c2413a4b0a87e66cb77c5b2aa91af924a2b9322813deac0c6ea37a331ae4ab228e0d38322f78704d70d5fa8b647a36bb0ac873a70007db22ed45c68225aae03b4a2d5d8c1557aa6e6981deb08153d6b6913644a1ba740124ac51162843dd568c06abe0c267d34c0bd8b7bc544c6a31f26b9e82086d79633f7252cdc8a3f5b3b3961f449f33846023bb02f6a5c1d0616472c0b20e81c4bd9105c0208f0691508ca864aa91825981ac36b024d4146be467fd59aaff6a28c16b5c9c8195a2e695a2edc29ac2ba0ff252d9f7166fe03494593271b37571d7a3437d22038d569f9874369995cb6e5a0442857f1b698d3168ca0407d0c054e4ca48c25c950c3450189766a14f9c62a15b29442360c40671327931de8404584a2f36429176082fd882156ecbb11e1a17db09122fba1fd75cdc26ccaf4a48e17e4c04471863d768e52e6bebb84bca8023c2b358187cc800fc7852c518dcaaa4820a63520d968ff412164b99c3572a69c3a643ca4a8c61601e8f4061cc314fc56cab4e364ee233506d46f399466963a84f32c4f2116361e675db431aab9fb230b840a1718ca08a2a9e67658f2f724ba4ccff4a720073143d5a1160a9a46652488ca174ff9927a4a05669fa9470cd3429ff1157a7344c309cb443191e454aff0534893d8874f9540608671fb5167b307d0b87c6b8155a11c9252eae759c0e858d4656229b2893386624dc92f57f12321d6c97aca7647799681f2536a725161e04f7cb9cd008ac430eb90a1778300d3c858d937628c9fee688a0de58e55bba3bc222fb00b0f3ca252dd741781e9b50a217e4e52cfaf17b98f1c4140177f21393a080c36439a71640295734b4db1b817315c771df3afd8ba9b7f533c5d00a20b75cf0a6ba7321b6a8d372d1a08087fa49b3297304baa919f05513630c4d9e170c031cbf280ac7ac5705b528ae8f9a859023c9f82090ea9746b855e1ea857bfdaa886c42a47fcba84e8133258676ef2a111fc60c302c0b558c4566883b7b09771ba444cd51b6df8629d3c77c331c7f1232f4dc17085a52214e89ac5251c0586584ebc459af65539f29bffb34da3b596605b9fffc79a7a08237e610938a10a8b1371d69c52ae08b251a95c347181e98b94735862c00ca0ea199ac100103291a9167cb86381142e54464e6532e9f54a2919773c55521c6b02664112bdac7a778b59da980a918a1c8502630db01be29230ec243f0fc9f3682ea59c95a1dbcecd044fd1880a5ac1a0cc31bb84a762b325125744d4f35a30de84eb895feac1a6d2b920de086d0fedac5e989a0d1edd4e28519e7a01b3f552913361236a2058d964bfb6127a5d38ce1323ab2a5e7cf7 +ciphertext = 2120c5ea09910d460f8d1a0c63b3b673d290b0a64dc9c36dc9b8bb8ee0423c736196983e5a33f5ce3bdf8e6dcfd41f1739b138cb390cdf8a23b29ef749b91bad64184375aefbf39891f0e667958e912deebd43ae0b7a0437b23af5858d4e5bbdaf040c710860b092a9c4a1915160bfc7de2679699019600209aff014434d58ac7f1cb928340cc3db4267be5aecef554923f895b81a37eb8a280046ca09c7b51fd3e385781e7610dd85f194a213f351102891519d297eeac47672850741518da7beb41d7eaf1be657c2c7a5de37246fda69d4566d77a74800223f627cc691b9ad9af89d1d6baeda30f175679e0afbde716412bca955bae186c101f0ba8f07c94d4e3f8815f716704d2b658497a67b9b4212ccbb8642998a4348635d6436a5458f9c0713166f95cb791b2b3f619656ae495527bb48fec27ce34a4c051145662731387f65c6d21af8fa4d71e19fbf07054b63e132896e7e20665788753824a2f99d1789e7ac3c732bb9899f3c54548f8e92ec057bfe4827e87ab9c8ad82db690a8735f077493e63bd3a73747ad5ee9688901d782fd4ecc9c5568bbeeaafc031523eb166957b484fff93be75306c11aa5163cda57dea9c3ca21ebd30c38e2e8c42a3c6f6ddd02fffbd9117828391ecc229f42ad07af6f3300577b2fa1fe36f926197b03b39ba1b9f9935cfbd07bca3b96287d2a4ac68e617ccb503b63c7ac8f06d360461f9a9835ea1727f147e5b07daa3970317a28a6bc2f7d80ebe156c0328d13e339a865120bde928cb990effe145da74737e9ac8febf52f7b5e60026946b149a6c76aebb4b23691a7d03db5a953dc5c1b00463233d9fe8b530a0b979365ec7773735033d02ff73100ce1f400b8e32a06b3c4043ec0d252ae8f98b50f7b7cb166c5fa31ee144828ef9c7b3d10e41c012baa3124c70258cddc0d1c2b0ab26a1bf1f653e46633c4ee1a9db5196d13f2de73a9f132750c31beae6a2a701fb17bfa3226af81a353f3456bd4bd1ca508a8d324935cd7585b722123b2915b677d956a50c9e6b9cfff4d9d5532a535f2782dc5494c329f1216dd476ab1e36cf1c3ca94b4b6ddda8a5caef03f82d3601776ec3c +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = c9d3b26d798c0a43c884664e1b2267ac3815d55c8dd22c0d4bc82ab4674a6bd626859084e5944f19135750400197e47150fbad44d10ed0658410bb9f69a08c2ce229aa7047dce449c9996855e11b6fd1a7415c5185ca11b75669d5510e970083acc20e4b220302ba289b154d942021de08953c088bf937421cb1ca9b34a19716b1f43222b0c7627c3abd76d9b519866f51c63db3e15e5941105e9b256e492b3b2c69635b03cda679a7406d44d3ae3d172863323e1841bc0a3c8a7b293e7d8b8cf5897c54167168ab876fc2943a8289e3eb6bc67081f91494b8926a2183c31961327d202861d7cd1c0063a7a8c74cb306f04093da6562dd049945a09bb96c0ef643123a37836ef1352dfc57438c8ad9b98a9954b47f17697b5694047860bae4ab18fa52e0328d14f01e3b9763f2136088bc56c0d0ccb5fab8ecbc20f5d89c934cb421b50520785d8c77c482f7074c9c8c3ad4a1e7206635084cf3076d7581c57753c0f6fa39d5b73ca9238752788f2b84a4155575456737fab56847910e81336f647380790c2d3f6cc65515cefa864bd0d010ae644630334319a772f7f0a90bf3852287879793c792b390f50aba2eb077c7d5ccc00236b7f0835f1a54b8bc9c3bd30bdda7bcd55041dea65893962531972dceb2057eccccaa5791179905ad993b892a8ff47bb7e9f869373043b71b3415d5cfeb4c1bf8cc3332c7cf6d517d9107b664e63a1abb188840110994a7f1ac72784b103adc28a982b5708a21f06b944a33cf476b5e5ca66b94cb47e1533f1e336cbd754be77a0ef9459a6bc50323089983a3708a165abe382653a9ae824635804c3bd399bbfd52aad27284af055d7a9398486521d38221fe9697f2f73227b06486ca2c801a592d268498f928fd2815a89a2e9f69185f68ab6af2b8766c99020c99364bbd29e7caa98863604342d5961cb5193ff11a4506418d32a346e744ab46e75f6f92052c7089575c06d0e86dac45751293958b18b30782aa1c93c072749acec3c52a63785aa4699b6a540a0a90cce2cc9c1a3600943ee12718d8075327e7618cabce79132c97261c5271299f9ccd31281629e2c222f446ed6508aba122cb909aa18c757029125c7674cf9c3a16fc86497ca9372a677e01a24c96261db64191ea301338341b482ff4782f0b90a9c08920da04be349661aea4103dea442857c1ea27b3f340ce4568cf70a1a02d0c1494095c308357c37b93833a0b1dd77cbd3310a1db7c57312686e455970095271737dad73b0738b91fea0d4961acd5b6350aa60e67b1545efc0ea53a50dd6bc3a5ca2210e8a3a1f99df35961ddab4982086a7384604e1768ba6164791bc76036265391b6132cb2b9a5a3f0369717b4a51c6530002c768e1660c0352175939e76abc062f6585aa15b8ff3bc7ff42d91c0912e42ce5de448f287b487b15a73c6b78f346d92d064b54a30daa04f8c0057ecd88aa584cb874a3e2fd0ab2e003154c99d2a9509e21324f6323beee214b7e602d702b76b4c713eec442a53c91bf0991e2c3b2bbb0e35955d1bb095102066c0622ce113104af8c709e514d5806dedc513246a7302f9815d26bd8e8722b4e47909350d7f7ba80475309db6c720a852b36b85411bb6d7378f979b450b7731b5c4887fa51c8cc20fa54385c4b8771f300652473c603272dac6838a6b7eac1acda4a668bc458c712c7574e024905874df57b5076542543b42bdf11210b7832454bb2a0350f25a8437547cfc3a3da6a0572a1c7f087bb4618a6bc1c4c6b0c4359a517cc4a85d15542f964b6fe658b87c486120d13a85b080c5aabb41a366cf896e393713847637ceec127ab7397cd0709e051935e1b839bbacd55ba0cd78724ed9b787fb5cccba521e5a35e633142c758cee734de369661b9783b037a0f2c71571fa15d6c447fd797c32da771c3a1e3aa835fd389fc3e53431f0737d6238ada4c8a26a22d1496b4e09aee030c525006f6877200bf2cbed9a373cfb563f54413d77126d1893fe6a5e6e17401efa6bec4a7a69806d639435ad1b9029f4bac5f90682e32b29285c4592562f9a4207b1b22c694b94e026767ac1b9e314e5361b80a95826d737fec0a0dcf1b51d965e88b22f69879b3180cf3d6a03d4dcbe556c3a58c420de75767565510c3355efb5060e891f28b8b8bb85f8f71b8ddc9c63d5c475b20ee3353a19ea72b775dfd3396575c0abfacf09dde14090867ae3c52ff1a6757b98d3de298a04eea222661324c05c27bb02d212abc15a4646a4a04673dfa9865de754ecde1b704b01e31736149b204a62c40c7b +ciphertext = fe0a5c68ac1488d5cda796ff7fda6f5b0f594796d05d7c40931a69c09c15a90d393940d5af7c11df5a1016d28aac6b18e6e8afe870647e0b72f2b8accf0e0da574ed9cdd813e07fa64c0789e59a146a1a91db64bdba3b7ae41e4e0d80952e0d37c4811e511cb19a082aaf5dd39966c154bc70b3ba1a23a0740b6d57c937be6fd0e24409358003a1126ac8539fffff4f8d0035909772a4d1399a5be89f2e54d0f28a5ad3e6a537377034ee4cf3f1cae4cbc203f7dd8c9eaf9493e8a3681cd01762318a32ac577afc58ded3cc18f3b231fd20c33cac3963c175f6763d49c4b90fd52ecbcb697eb8de49600a2f6bfacb345e610d46c4fc6cb47a4995dabf299dffcd8083342b6f74cbb4cdeb86f147acc1b432b719fd3b99aaef2a6cb2784edcde93da4c76a845edb0a3a5db4596e26578297424037dfcc2b5a25057ec675842058dbb2b7fd48b5b75aead4404f1836d17cf6d2e595b3517929c2942c93976bec600d8ed5a49fa7d18b9038552b698b6ed15f0eaa7727b17e6df6c683de09d85b62c5895c0df5b3c381766f2f969583f87ef93351d9d7c4259a92e6127f7d84a57c339f5bcf5f9c8c44dec9187f2de630c78f7381d715a223669fd83d90ac8e81e7a41e9d9b0004d07b8bffc4e0513f2bf071f7ff8821468a0ee9f1b0fc773b2a04920419d8bedb343aef2f2b0cec2fba2aed3b8d82730c849202898deccc3aeae383e1d6f9fb5e7ca3816face2ac2c9dbb53b7d579b8b523add4d7e8a737dff292bea15239eef9521066c353db8e98f96cb0b04f24e3eee24fd4068857ddceda92bfa692c1d8294a499d480a70c5b6b17486d2a058ca33872a7d07959084b575cdad7b040aa1343f2e79c4b63e55ac69e7c5efa5bf0cafafc6923eecd1b9558de6bc9c51982e2467c2798f1ce52e172fc5ab764db569fad0e5310d43bb03013517b9931801083608601297ac447c96f1790014f202f03252aab5307b35a2e30c99949235783cfcbb14ff6d2af20bb607b981a2aec5661e21c6ec7a44b1d9df49ceb381a1bb50ab987e6dcfe76c65e1d6de8fad6103a6a007cdbc820f80ce43671d17bc37cbea5c3a0052579d61804e4911713489 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = b842869840a120211e8e7466b329b7719643ba1c9be7aba15a181bea87c3ba88926b3b5f8c18886e0623f5656ac7f1a41710552bcccb770947b2b6cda409b8d9149fa0d33ce5f54b7e6bb996e072d8b228e83c8d986a9d84d5b2b5379d53ca73a3a594be6926b400b73d3b41a6b4ab3f0a437f01d0a48cbe7aba6e579852f067a405209dc8558f8f8a9916731442d12426287b88bca8a415595fe50b9cbac486970bc8c3173939ccda505e4e6a8500322b3b6b2a8b918a2a4cb98d120f31514b6a1c17eb4723ff4bcbbcf87b2120499e40ac6ad3bbf7964b1418a17594afb00904d3d769ae5b205072a56a176243f30e70b841efc4027c95beac19b235fb68106885b4e316c1d9759b86c2ac5701341b19e6f37643099a6098475bb4076d764dc70a0a1a06c61dbbb7bc115bd2339eeb75bf7293afb16087f964bce0f17e9ea748515c9251d65356630b6a4b2f9524c9394450d2484b6d869155b61dba7263e5c83aa8f1bf5b3304a3994fd5a9787a0ba4c378a8dd07430240cb7aca4209637605926a3f20552c8091915b6431606db1426c40d5962f65a356fa63896aa4a4547f703749a0f879ef2a60efc525ad5203ae426e89d4556aa1b8402567b59087ba557e2f0b12ff78692c8b17438c04980312505117ba59399b25903973a45240c83db5ab9e0640e2b09e72aa53339c8a83f75a76a23fb0e67efb228cc127c565d50019e3287a30b5a13b191fbb566d4800a1fc01d5d78fdd6ba3fef7522deac62672b4f9c52ead1870e7b3bdc66053bc4747a9c7022c5641f52ca8c08c5332b157ff415756199db85cc44d239319f433da526b5822690c046fc52a69d7a783686173d562608a4c23b30bcd2de34adda5378a9ca62c307871a812ec2517e8089341a33bb25c2a4fc81161f2ac43634bdea166d6bb8bf9f6c9bb0c1a43d96b1c38300a026888e7095800141f5b1cce091f6caa7fc01b0158e06b62d9ca2753af04d97fd3b2a30f580a34900a8f4b950be75a9935c293b165a680cf834ac306e68fc81880d6b53c63b91a0aca49a7f805faa5844c270b2762ac98e55a02360b9a964959d52530c03e316457957175eb079db64ab3b717bb507b74f0b9604f3c036294cbc8ec446ba62a0d2181e62498968b1637f31c41f2c21e7a41409a27087b011a62854e52ac3a10cfa8cb296627ae8ad847a0c758e31bc1116042ce536f0cfcb207e43632a6bdadd384efd91bf396aed8c31e0b65bd3358782d78aa7143c5f3c05eaf8bca16fc076ce3c72d7c32d8c9cdd76a892885583db004f0b4aed141784b18765654bfb2b39070ab95de2792d273983d431efdb933fde1c760866aa608c0d0cc2fce733369dc7851e78e2f76a6ae010237a45d53eb651dc46f0f42c387082f53480e143b6266c791dbb525ee6064473231254b20afc4b669a04c51968e4f0ab0db66c9a9544604d7b31ec783e181a49e7353e21a430ce2aace8ca2cc88ab3f836e6ef90080c36e863aca4c1a4d7f779a666784183946817c368aba5a6206ce73ba693844375d42bc2c256980d496a7543cf2a78ab1fc89f5825751346bbe5b1e9b2017eb976705fb55b856c55560677333b672853266f7558d301c8bbb0ae181791d12b95b7aa8895858d7428c056a2655a1a95d986e5b79b9ed791f05d36a0a1b43bfd77fb3d677ae9c4b51f93a547299e66260ddb918ce3c31abdcc567859b3acabaad9b5eea0600436cbcbe796d80534fc59ac9e161874de83cd6e035d20741c0866861e543430b2bd6c361a51b4a95a81fbbc06692d09a69c42647406a2b915fd4d2583dbb81e975c4c7d7ca7831c028d46160e61ad3308a7f65cd19212154e896a3a9741e7a79996c2a763c2f8c57acded53e65685fd7d91beb0c2a9452cdcb07403a209111810ddbab00335a9226daca556c13b9f22f0b76be93ac9bb03c3d8804b7c687a01ffcc6e675185934416b20c0711421d3a8c105b293da84380c848d5a0a75e0e6c0ae652780a946f9a78ebe8caa3429bc7abcca4361cfe9895a4331c1df583b17e1104cc5408dd4ba0ab3391425ce91485132286fcdb787757b0c7a179e14e81f66f71cb7966e6d936ed5d51b8b06afae2111fcc8241f3bba8b2cab186303a0789783e684b925916599251d768a9e2aa6ece91e67c2066dbe9896d60c9df260e77264b0b906f4837b78760e22018b36cc20d535c1c8ad59404ac17b9b3fe2f39e76f3d3aa82e22564a862a0a33687bee9f2c5d6b711c5e7efee801acc87b5364d9691b26ecfe207a18225bd2cd6ae0e90d29fe2aba3a8 +ciphertext = 40045309c8bbf85f5d1696b03955d7f40ca178b9fa82eac84ce3700ac25a5f0ab6949e3d12b0466f5b52f02a6bd2d12082be616300a9d24fee4ad08a5db34ad08c5ac12ec8c53af5b60c5959e52c4458fdfa492ba40691a7e938befcbad3cf2de595cc525ca61fc42e0ad3f9101a67a06782ea8aaf46551e41a7989b21cc84c30245107c867785a6aa2276bc2eb3f9f6581fc3bfefe141af0d91cd0bb0501ec000063a33409523abbd659ba9670c2b1c92e509d5dc89cedc506d5ed1403c6b3b588c4f7a4582e0d6210119894af0441d2dc35f8616a6ed8125117fab73990d2f197a97ea5e5bd1467c7584c423224151727b19b30e4b139cb8704d51decf580a9b36be1af3fe5b7e342202eab0bc08b25694be586d7e3eeb2e77261f991173332dcbf3c9c3258474b7c098a186d0054a17d7f2f28e01984c9e9d7f449e293f32ce623cf17f784ffcb149f81138389e6cf756760dd8059401f96fd5985c2e60a957a768c38eddf509977d5c39587c860c85b9ec7e2a052289688aabbebbd31276f550aa3ac2d6090beef9730fcf6fa28837e2ad9b1da312d0068075aed3d94ea370c0f4d647dd43437b027a4497657e4047e2da5e3230f63b1b44f2ae16eca88df8f2fe01beb09f59efe4cebdca3b5cedf19a6c924817f97c1c95f5e710a6cd793a1ee11d239dd0b035f694debfee8ea39688029db9aec55e826ced68f68a6711390d09c350b8f97a31f5dd7a7f281dfb04b302b8036cf842beec951365a6327d0166315a853f50ab895ee67b7b56aa740ef65fac5f102bd1a2a2909140fc55852cbcb88c2e928f67b9dd9f2b77e3c085c8b857f3369a4663988becf9901177927a2ccdb0466b5b77fd1c902608cf427c0a9c50ee04657ac889b84c4ed51a8a3762846e7972531b0feeb2fd56b01927327b74915c3f18d89835ea6cce4632f328fb1880cffca9abd320daa6f0045ac459b65eb44f77803b5ade7dea74af76b800d2f0278ea7102a99d627820264ce2b2c9f1f114f273f09cf464ce8ce60d1fac731c6892abe91ec28867fdc2d590cc143f9336b75bef06240945327700a38d68d7df2e9e03ec77dc64cfe +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 80989f53b714ac011277c7870bd955a327499fc2101821c397b35fa2f3caace0528e155058b0b573c36a7366c992a77e2aec15bd80303ab073165a4f2a5ba4e11c65ca004f5a7744f3a37f9faabee7500314f7648b989cfa277ac64392ec966632d302d8139d1258162845b1942c6b33d200ee2762e0cc42913c4da7d76ffdf450f3153394451e8d53be09b808cbb42bf90324a18cc62377b100a7463ef72966d39aa662764744753b8b7c367833fa97cc59918fde858e48007047632523e7552bab396ca21662025c12e1519c45ce3f713fbd501b9fc5cdc53a6e954a417edbb39a645951b80a65c84a239b3f92842806615d2656b5996bb45095201572c7d305ca78e9bb64865b64044a121a10bbf033616a4590d4b2f0043c36b6112d318993f6514e5b0ebce0069f3671d4f4127f7cbf3532432867a5def4241d427a3cb8649b7021cc502ab20227758149ad835eebab3fe1287fa5b30ff1390147491a51f10348e0573bc959b0423d1f30916464245e5ac2521409ff647ce8bc89c8a98324d9aa03bc463b8822cd21aa0281c446c97d802c0b578bba7ad21b6548531e47bdaa800ef3c63d136680d447559ef2ceabda69dec75519948b15147e6e3aa12157697baa014a31bff5ac64afc1699ffcb5332b934ab17cc9a4b615dc9bb52bb204500d888676f9b3b9acea32bcab6d03f62e7257353a53b5be14b42adb9c2eac7863638418b6b13d2a56a263bcb2074845ea3410c56d2acb9c7c53b4cf250fc66525f2081229a6398394465da2339ee094162586d7c31fbbac0021f74be7086336714afd5a08478406db6c26ba878a9ae41dc314739e4408ca074be8809f5794690cb367dcb6a534425f6fa89a72c042eee70a92faa34a617fd75b2908e3885072417d8959b1dba76b15c7edb95508424150fca3969bab8c3a9e1d11987021129799ae2445adba627aca5a2eb7e98a6ab8143a413e1b5451c7070200e51133c48102762c39bba098004d1c152ca08c402e7cc832475c37e5b9f1b777b018c33875ac73f06dd82591f58b8732171de947b99f9218568cabe111b8ef97befc495a65f0172b0ca41f981024ecccf4828771a239c4c65d195864c4ea1d2d22af06f36947f80ef0ba674245c51aba0a1d2c4930c08ffd19b8fbd23eec41a0611a45e172345d458e4951b99c825ee846514cbac00ed73bd979720fc0c468259873c540114180e3905439f47a379bbbcf21a50f45cb22c6448b7b7cdf602ceda8881d023d7ef49c17d5a507d632cab9449b3c5799a4c3b0184390418eecd7200b213b6861162ae72d4e05462a298a0edb2fd6ba603abc3e6e69479fd6b0c1e4434cd269a57415612545006366b86884e8b01c65e8097a159375c76134f365860a18e76a4e66a09ebdd5058bf0b059a23a8217812b40948d1488f51c0b1c36b225f88fffa6331c9b3e82298df6891e469124a851cb97111c4a16a2eb9c15b7e81544d635e0647a76ea369c862161975c0aa96a9d28270cd026a88291eceb1bb7367031c52316e61d4d13a2a6a5c5e78c78fe141c7eb98a469a248e1457eee86f65f2683fb873f292c8ad1ca0316747ad8b251868873a4347ce5a06b1dc4083da0d2494becc99c98599c98ef806c7ebb6768661050b509abcc8039ac191562d761631b619bf924c48dc911323a30c8a976c3f57b6b63612bbf95e825307e6603acf113ebb41698be60926199c73a05ed5913d5e716052546f3386296bf6033ec7b66519adc0b31e4b2a36068622e4290658c7a58ce954e451af27393a7285cc8e356d53494fdc1119b81a213267655c485b44893b73b295674036bf386864262c826237f0c006833b06b2ba5465bb61c5760f9179c8c4964336150347e948fe767826432c9f2b0eb4c615fb38836b7aaaa24c2839d7ab7704d0380437fed4a01cc5aba72430afe25b689b86321a9c4404bc03d2015757aa8754c616189fff17b607069a81c792382a7aea63391d940c286a043f51c798a94276e57d79b82d87a503fe5a9ee2315b9a9b49eff502cd01b7e8e5ca36c6ce9549916bd8ca24b4bd27a6b40554603bf79b9a68911dab3d52c30adc08243a6c4ea1428c50b13ae8b19122935446d70179f5c0458681f14a9d95472b85e0636c4190b740b3dc04c709158a710864088c6263e8236e980cedeac3915739db5579bfcb2aff57c796a88c764039dcee28b21134a3db90cdb6de8dc84d8f8515f7aa9da3d12c940d9cc49d5c5a80d7e909368d8649300adf392a1e28ebaa6e81711c5d52d41f932edef173bbac7e153e +ciphertext = 395717df08a9a7472799262667a1546c1fe7e83641f52c89ff719ed39ad04fa07631cd3669a152c2f9dc4a09f1696a5e55527cbfbf7243d9869e685f9d84de2825a784f0b41fd8d931cd75d9b8319bc294777a5e257292e0960e52372b079cb6de6dd97082e78799103022580ee541e2d0d4763fbaee9419f60782e8a8696dcdc5244cd703d79ccda4b1d6888747994c166ac2c7a0b0af6da6bd959589c8d036cc7504238b044a3d8fe83e186ccf7c47641317795ab0b6fdcf3c1e77e2ff0441538d65432460328ad4cb5dc37cb5f6032df24697e43acb1a9265953aefade26abd9d9deb27771b5eb1567fd378f023655197dc96b22323f9f5c3a6f267bffced174dd610f9486c4b1ba68646ddc0b9fbfd60d58873ecccabe2192fe2d0324fd7192763dbca9708623e203c33f973d14ba2d4b9af78f67cb3b89206e86e2e51a76476f49f2222a5d74611d4c5f23edd9fb6e5edba41e04919a2948ab3a28e31789245e3a8d017cfd1650d006c5d03a76fc231a10478e56c864c8a160a8fe1ee41eea5cf59fd8bbeade78e79efa2a713801f5f77cb800da98791bc54fa4185088c791a24c80b623e1ec3c9c362484c192e3acbcfa586720fb3650d6aeddbaf436654ce05625e75e75eeb221db6fd3dbaf70067c936719ef3945771f9ab430b2a1fef168d67000021198d1822e9c120355de25c43d599f0070d526716391b05cd6e785e85f807552c2b45d9e614ccc70e882af76aa16bb4105851a8f7ee19c547885444e42e37ee7365a854c4ba05d0a1191bf3d07c8c0b0a6913d8573b51e06dd639805ee2ef467a3d5c50790337bc04152b0b6875624857679bdc78fba639ef5ad9a0b8614b6ec5ede3aad6be0c2212362fcdd45757e5f67c97a7f2a74407675921c69fa718ba283b934205df7c90c528ab62123ccf01914c47ce95a60fa3339a66c6662174b30b2737819c8ce48b7387e255021743f931f0f6def09e72617878aefdb6be59428ba35193bfe3954b63968b0fdc9d86f21aa929eb3f0d340462c5f2bdde4149b169301cfd2e7a77560f24d66874ff063a1fb32bb1a97024265c5e860e9e7cd1db541a642d7d1b3bb30b18d8820c0dc3 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 0205708362243843b312b005020b1ab4a631a55a4aba76b5b96c1d16569b7c587fac9457fa8aa11e6700fe53b9b1658e42f7014ee19c76062cd6eb009438a4ad017cc31cb3fe46111e8c36ec1c535b819982f6956314a61b9389ee66152e03755293bb225cad65dc83dbe206abc7bcad298bb93387631980b113530d327f8e657818052c0650a8be0909b24a1036c74415ab22bd814e3dc160448574c1207a6f45758550adf1944ff0d6677086be01eabd37b8bbc0f3b0660467be0a5b52f0c9a9294ae7971b81e19c7a556212158845c4c4600cb422ea22ed342b2e0741b567404cf056ec1ac73408917d71a6e4849cd9e6adb3099f65651ca012c82540471871974ca2ce779b12b7b1a82d2a0b006956ecc77ce68775e51bad6ba9ac87c3517c0c19a829169618459f32352ae86c781b7cebb6869a8571e2e08bb0c1692647212997b4c043a2fb255639ab7fdf86ad050b0e1f2bc4e2a06ec7b3080607b23f86802a7aa9ab66981d7b202f528e3ad8232ea52ceac0cb3d016ca64a5a84c9b5e94c13c4fc5966cb18844c9ff0eb2cce08124374c864534f6fc576f8ec3b3260908a391fd29318022a65b4e63668c21748c76f3d72250fa7b158f904fa5104ba232e44069aefd2b6fc3421371abad7a682af72613b6994e07b10b17579ea5594f7448efd98130fb94905449de05797a8a14683e35ebd21850b01cb667c7b0b16ba62623da3b70c5de804dba6256a2b39f0605c72c89b9eb771dc7546a7292e0de3130f501d39223e9a6785f5c442da1ca49655a802b504292c9ec026109864600781a15f28c7bb4c7df743653980351fe6842750736d93a2a49b08c5aabca95741328b496a585d7780276b612ed6325340867b347566c324723ff961794b27b5db722cd149fde81c621a818ba75b68a7208b278ac9885affb0156c71cf9416bb81901426382515106b183a0d395b2fa2320b2e523ed058c520539645543de06919cdf6890ebb0165770281963027843faab64715094a6a6359e7fbb5f1480b7a1b186523349822c01fc902b892601d4bbba95ca8d7460fcb85ae33b36c7f243266721a506431af30449fa130eeeb5766e07d5af64608e4b05002a2c75b95c434827e0422b3fb94317b8dc5447eb3953cf4893f9c1a65025a4d2f948c3c430598b4bc317078bae93e06810aafd5c968055989788dc79067542a054ef4b49205249c7acf57548734830a4842cd85d229d9838bc27b6d9ad7847ac4ce35881f30c19ed88b60a28b4fa959851747595b692438a5258a7533703b00f4f3cb17e470a5c980a3d29e67516f3c8a878ccb00ea40b2fa2c46f3494e9fc1b314f11604e429f6c2cf44302662326bc4fa8b48424aa64a6b9f82a4d038cc964485ad7262aad8337f900643b34134ba3955eb944c512a10faa11bc6acaf52c3f2e34c1947884b320310611210049b1900a873c32add100ecc70c90aac2845f669ee915ed9d37021779c8d14209c4078bb5c5cade37d172ac732724a2138cc48880ed465c4f3fa26f322af3cf59f64d5108b3c5b98a81da3a76c289a3d61c224ac5c60daec88d38c9fedf742102a3d38193ad9823ef9f4358e56307e82282250a160dc1aefdbbb123886f7e8529039749446855035cf82b6b3b5f61e0fe2087f00330eda55c0335bf6e47db9296d6ef84bcb796d72475de957802e28487edcc139712d26039265319f1b3aaa458011910820f958040530b567714aa854cd4d20147812a2d2e179519675b9f74d1fe58594d45690bb745d542b769375f906a7397a42fbe5aff7e916c6ca494b7b8e2cd97c42e41fa5b13071b1a8dfe5ac95c21a5ba95c7a72bd36450448b3c810687d17bc01b4c94a9c0ab6cab143edf52dda19887ed386654584d38864f1467e3cc807b98c6da805c20912249636be08888ca7b1b29aa90b94a144e6b103a2459961ec3f6bb4bcede60cefd0792f70b23d981462064fc573565a0ba6865b0d09fa1ca456075711c84a6628f99a600718c081303b259126d4c4ae5fdb2994c583c2ab7a81b42a3b4493f2f7a40e155e5f342640850b69327d3e19ac53442211d3cc1bc197da6693a543cb0aac04f98b4002c3b28f09bc07a80da87c1f48a07a376c1e366bbcec17a1543595f5b31c69cac645b16bb3cb7ac1e8a8b9ad6a32ad99b134bda9b80f86d43081382039f3f70ac840ef041ead270dbe65407cea7651e473e9917feb820dcbffa785482982294a997a63594ef8301d174cc7f4f7194af2bac10f41187089a21eb948b57dc27f2aaaf3f2f51a355e973f18 +ciphertext = c768e7789c1b4fb01b40ede8aa0f28ca089c09ddbe327678b97d31115cdb6a44524010a5a9804b544bcf2e09327d354df55363454612a866b68a1a7ed529cde57716e605f83363388a8a74e3355e2803ef054d64aef929ae022c3ac7ac597cdfcca98c5cae37e42de2bd33ced361eea7875423896f64d4ad1cb6c06fb6639df6f46449674d8daafa5d4ab30b9c0fe10c54d38d73e03c5d85cee40d92962a50b538f08f4f22412d51c51e37b85836a5aae6c136f353d356b93bbe907b94df9e84f2d9351edcad4317899d37a516a6042dcdbcbfebffcf73649c69008e7defa29ffbf71ad0fabd9ab71f415f65d82079459779afc8663ee24fb831191d38eee912a791fdb8e2c0d517dba616f3b9f03ddc6bc23724dd9e5522eb6c3a058b4c492bd066a6d97e67ff73839d3dfd71a3c9e77f92bb88816fce57f0a0ce580b1c7f5d4ad75d02e075f6a4d84fb484bd965d3c06cf3666f50d8af877b90831edbbd4a05a4e45c5fae4587ca2f38047366b896646ad3b1507f0dc5299710b55a7630bf5d190a7a570a588ae2d077f6e1ad59afe2ac0dbd16132bdc7d9ca70ad4b77394bf4c7e83d7703002544d30d4fd6e0b53ac50cc7c0b0bed5e0adcb0236c5ae3c9f8dc6963180a7403de549e078e8fb321ca7214cc90cdf33aa9c6d3d5e1468e5f46d157873f3db17f54a3b9510faab0d6e83b3d4af475bb0418edf1139536dc504761896692edb8d5011f427ef205651c3d8d6069e8ac01a721882e6f9e0038553ac36b528b5a9b21a8b21ffa22263ddd78f66267e0812feec37db766e08a9cde2f379d16b56346b136c89b7ade92f8040a080d3369186a3e52199e764a8c6f0b02981604f3c0f3fca83d00c441d6fc102483678525da49cb572388563ce0bc3a79e09aa330050736779ad440ef30fd1c6fee3cdc91df87b0896305913a62164a632b8d45f4bb961032d5b03e1c423a0f74399542449a23740f272e2dd59f2b232a335ead308a95f56bd68a0c4028d6b9f9e27241005e6715f36523c95c7663e988dcfd295bc04c3a1d84188b92a6152ef76eead82bdd3aaa68da0319b3a5917a45063576a76cb8d92874ab9e80e4fa1a61d +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = f0ab94efb32607bc67441710a8a65bbe7b739cca54d57a81213a3496ab776f751bba500f40053dbb2920ffc2315eec801028c87af9a3ae54391aac508857ba6365a81ec47320a6af792cc491a762ccc8311527bc276b3279797a84fa9471674ae489af31a309bb66a199f6a441c47df2c251a813224f25798282856c8125d80141c295770a31cadc245e7ad459b5b8986451cdb8e2a257c9cfd9a320db62568ff75c677b3e8e9879a868ca3f48cfe190b633fc365e6045e5311f8348ad91628105fb3f1a87687b39243ce9b5432b633407128f3140bfe7a8acf453d63b4b8f353191194495708f1104c4d26c2a8acc0903a4993d8524f8f71ad130cb07619bcfe577f453654ba11d29c9c3afd87528694727e735d29443b4d4c0b8f72607c34b6a333d9a5147782615893271bd18b4b94646bf2566178314ee2a00b9e255341a425efb3189692b5ff4a6dcb8208a47a0bcc5acba60c0a19c694b3928d19a17561a4487586b32a4c6b202cb7348c40b12b194195b28bb59c7d69eced344fdd74263fb6158422e5bc7523d215eaeb1a6f4e618468bcea08a89e5265935d14f86062d9cc3aec3d8adeb912b39ab7e3e8a5da4852997520716940e20d93e5f9001a6a7ab2b93b3f9a3b931b90a76abc313b7ab19979d561c9e63b72899b36c6c5466a9753dbb832326529e9be1467750961c28ad07377246d8715a11a3a4eb34ca32858fa70aa854407c3a8eeec1c8bd8491d52c4660d11199670c3122b885e256edc3b332f3c57be174eed65cd44c1676a5432a5516eab74231da40b677431c8b056f03439a5a315f42946c216dd19530d3e36dac94129651ae76020fe5a3afd5199d2e481cc20235355c557f0174c4ea3e1e1491205083c417cd57e3a39a7c0359a18a9669087c035991605376691be499a1ce59c33f162926e609ada5cf3c2c65e2a63fe432488d7100ce1218aac1862bb79e9d920d55e87aa3683e0a22adfa005f66e8933777615774a5e40a0d0d3a185e846ef97cc700aa723324b84b0b4cce5330d375afdd95c044ac75353b6f42346207e7792eea98b0d7c159a186c6d61b054a1cb0684546d81714229b7e5c0509c6a7479b3f6e9598d2a5b617dbccd26102ed7746a3296fbbc451e853a8bdc745b46c551c5b0ab81c32e594862fa22fafc9b79f4ac5f4e83032e50db4244091e6b8e5c3cc7366945f4b031998c0dcc0b4eb03b2fc746771926cca4917c69308e09586f579424a6204a66344d081a48cd57aa9d4b15a25668a1c97b4f86d4be1c04a24c8b6e21e77700941baabd5f31df75c3e87d824a022b90deb0b30c896d9c20dd1ba07ce81188ef235c86c42bd078e0c1c90d5012c57816508a8cf7a3b15f207691c0a305aab74fc0a87880bbf7eec58da213fba06462ac2ae0f3c924b1244789784b1d01187f105751751eef848faf976cbe30f03b98547149613f356f0302d68580cd7065bb3b26ca4451cdf09b0d3d82a409a84fdc2be7edbcdcba48a9ea948913567e712258378247d4870f5802aeec971c32945a78819b927a22e347f69026c53f7c3273455d61cc43d99b9ff060215553c7c78666fd11d0feb97ba93c8d69b2caf1209ee4ca9c2755912858866da8d4e0286c321379f2264132b759274a148049c549479f63574cedc12b3c770572a015f462045d465f0575d4ad13f9fbb830a5823e7882db21bb504fac76f0574f3282c7fd809bf5c7674aa7fe7dcbee6d26ea114c9102804ecd19f45e7684006c4613644bf484452d88a869821e5bbb2e53813092b78dc3412719720b82b5e6edb6982c29be8093b985659ab00c2d550c347e67a3e1cc2e20c2dbdb6a683c2321c604fd905aaeedc7967373a6db8127c2888fd83b4cea243bf28c0153542d634ad207398a02a3436f43f546a3366927ac3e4231eda882c325ee798cad77a7b21d079447a9b61068dc8789cbe9549efb7c32999575aa293af3a7b6382a445971c08402a90765e521317110043ad7820374bce0236b57b30880a577099cc2b2c8a2194499c1e7c91a4b6c00b010942a2c155f1591eb598e00b78b7b67271610a681b6444390acf934cdef13bffa13f47f84d1e276db6763df05023ddc50f69e06e5ad688ffa2b83fd7c5618b437ea243bc1b609ca89e1b71338c5b7a29c1b18e91e558aa0d04f74db1072fd9b2b4a8d41accc69c6f1f15abd070cb0bab01366b090f4ea66610ee27127d85aa9dd3a589ff81d9f4cfd5dcedcd0638d902119e84b9d0bdb202d47884b54614b8e661c68015c7fc85b6963212780ea45729d378 +ciphertext = 34e1f936121e2c5ee5ff157ff5898bc26cbbf2476e535a0cf3c80ffc6b47f13d6dfd750181e3c2c812a651523f4714f62766b79b53246d16336f77adc9a4ec2a3f30257a354dbac88c203a06ac610f4c85d61b9be42ca16260c92c15d83caa26ee3b749f42145e0c84bdf815dbd078e4e1703935bf2dd4f7e8b4b1b0aa6bfb7f6d8cfc2c0d65dca17fde4c8d14e55dfbdc6d7206cb2826c0b2d71037d143a799928e24a7d884aaf7387c0097f5b7cb1cf1bfbc2b755b59aa72582b694bc06bec2954b67c823499fb44087de58445e1841506b0a9de42ecbd488cd3903a5314be398dca2a25172fb0d4798d933dc7b2f4acc0a7eef6fbf59244dbf4917b864b0c0adc94e13780ec513f8cdfe52c07087d977b45ae99c1b0040d16f1515d5fd82388e3209ec5f92acf3ff28cec9419c9326d8eaafaee7772ce275ad35ca09b08b8e9ab96de3e95cecb774c22c0da415b0b8fd65a135ebf231a1ea1f7ca6887bef3d93a8f45e2626c0443ec7bed3a63b767455e717db823d42bfebd1b3c656d7fdf15da71f361df96cef2bcc22270d8bf687208853638f029bacce35d63fa8abdd890cf84b7247793aefe728e6981a1156d5ec8a390bfc771a03e266801acbc4037021a2d157e7e4d76b1e9ad439714f6890cc5a1f1dddc1a68e6188b55f30cbb7a41c7e1f6bcddd48f61371df5959e53c076faf0d1bc253debaf8c237a5d3dbd5e4b1d5909dfe795a65272816563aacb656747c14aac7c8677b550d6a100c05775f637abc24716013698d3470844fb4ed9fea26ef98031c9f6f3bf75fbae5b4577e4d6e47b1a08f0292c68472430e065ed568aa79f9c6441567f7b1f95db5d2d697e9328bfb218d364df096a2651f21a868003d1da567b7f0909a114102637cae21a3deead66fa6594583d4c4bd998763e9363cb901dcff4b0adac8cfa28bb2b5effce15ea80d3722e9c1f846184eee669cb9462ca3aa53d3c6c7238aab2a34e4f7efb5c47dcc921f5ac8bde009ff52719fc82d7545aadc23bd508a8684a2c0550da5e5df7276368e3cca93fd7e8990523a130623bbae8fad2dddf2f9b0470b7037ba1f5b661116e92adbe33e979 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 2039ce58a4677999a51c13c99f4220d3065a396096c7865505187a077aadcdaa2207d002ddaa7015088407abc64cfb073bb15a3a90232d0b3978570a347693486c7dbc218ea5839e32938e0c378c90c76bec8765fd9905d4d708244750c9ba1933b03072f30937f437f3b6119072120fe0b207760b5e680da74682b1e559a296a3e3717fd7757a7ad210c8f9b6b0d678f1136390db3e3f58c42b0871e9984a02359057b76454d40f9c808e00d64bdb807e7c2263de620b67974dd27ab1a8b2a4e7c9a94a8834c834a8c8b364b87b07dbc18f1b98851baac8d420457e31bc1edc5131552907563ff46b3702c444bf2b9861e870e84caf8ee10010832a77e308e88636fe2a4805374218d1c010851f78359b125725cdb94bfd5557cc279b87444b04e36aabb3af7d51ad28eb5934e08e5fa18dcf81a31d29156932bb3e82bc1e035809a945107c2098c8827803c4b0954dc01c6adcc796fa636f9eb48b053517bbc70dc4a2615a12235b546d222993dc12539db99d09114915f02862396a04354c28f690338ab850a2af99258188d37e189a52ee3a881f731f76aac82c030e32548a93632b5e6a484ee1c7a11a083b81509f100aa1407e94b09fe6f045673157f2632d5c29c516894c01ac2a58219cc57a05c6a845d4e8a15df8ce910b5e7c6c0875b962836b029d55b637715259397aae7a0e9522cff9d377a919b4b4b8b78143c1d023a15841340514bfc455698e87bb3d68ae236b66d3ac69604c3957a773fa6873b0a564b1c98ca1365f23875167a602be991a13744b128334b08435fabbc1b23b08896aaf4d956b7926714f2b51309a8242863b45602842a958a6db1eef74b24b65c2686a4cb3b7b54d5907b1258cbbfc2a6b461adee1641bab56cb3b2b7df1647d536d8de4b7c959016601b2ada4b0f6fc7ca9eab7b48746fb0ba9663b239cd37cab4591bc946922f78765701122cb2927cb937b81689876ca78e082a731617c51cf2c73407d7551abf59752907200b678be4673eea41eeb36967e10606dc0c96eb3a07051593a69234324b076021541e44ecaf38496fb426d9259b284b015c16a8053a905c75b4661b19a8ab42b7c545ce7662b01c9d8991f0ffbb901651353e485b6e996bf9292a18a53add3915d610b1ca664d67ab9338c727101a9d8b8a16f9b912148b7366acbdd446c20882ba4438b794ba4b1d65abd309d5ed39767226ebf180ec9664a5d15b420e76e437bad65b45387e9c0293b359b5b564cf33dba109f50c536926ccfd478c21a656baf8cbb20c724dbec024fbbc6c0f57acf221c12529d34952fdf94912c041edd0920eb2915b837aa5b8ab69c6bc8ff20a628f49cbea711738031ac79c97f3a38178c6c0a5c2a0bfabc1ae71a14c2a7104702bb772584aa44a1240c0ec15a3e5c3ba01258107ccdeb810bad013826932eead2c6169164173c833ecb687eab23cfd125eda427663a291acb1f5681a0198274d353b8fafc8bb6c925622465ef0c8bf3e0809fc499bc404ea1c0585392505372c5a553620ca382a6e0105db53a04a7412568096be0b516259f46023afe3288966cc1a79a1dcbe33f47b340220b3ae3d54e22c1817fd1cafa1abe328c009094a3e5c252f7279c3e8059b18b8ac1772848a696444177630a35284190380c8fed05654df0736e01ce6e498e61ab6eb2d777f3d7cf818cb8319a35a8d2c0179842c3e4b9b365cde34a80cf1847cc371d13fc20549cc965ab9c136094a9d742e2928f523b3032188235311b5900c9e415249c378ef98c9d75bc9122f213c5f5925d85398a76bee3d9bf1aab7b00bd854ea49cd9f70f99209621f571d0d4acb2e35dbd913ec8580757096755961f1bf290b4e9084491719ba6000608b24c206192a9555e57bd088a47000a0f45399ba9cb5a204c2cf9501f8c8cc8687b48d27bcbe7436339a20697ecaa5db73fed714ee01a7968613f8bb3778d51c8d773ac32a47714548aee54372bb26b22403b5dc64e42bb37cc6acd780b67d39a51a768327571a315a38d2602133af83901f45085f16015d3000f3494d5653b304a28c7640261f31501727972c221880a002c7241534c8572da11808590f4077f7344550ad7748a3865610573b2704388469711a9aa96d6539fd0b64ad86f526344f9842ec9d44a7e7a3916fe7c80387df53659f2921184b6923f2630bc08553c57ed54bbad0d1615be262d195fc3429418e8c428f3699752021b6305554e079978ebb5fe1b0c2a29111841282f90dc4a85d0a422f4833f1cc1c2cd796d928b2d933272ba81253c +ciphertext = afc059d521f46be2b6c579356ad16c6322301aa3e38481bfe9d81db0a937d472185312ca9a5a79905670700ca4692a720f462630c84a92b9f43469594b6736110fc1b3eaf034f7a11f758e491df529176c42f3abd9343e862591c1a213f9db1db9651175877e17367bb6e173389db0abc6a8c2fcf4d74869bd6380a76ab66245d2ec6531147cac14c026c89978522651631956f2835df6612dc387ccbaaec8e987c46c41024c5e286d5171e63aa3eec14212f32ca60258dfa94761cdfe97d5e613d4bce6a9f55fd472863eb1c92504ff46071a58bfecc2ab4a90957d992a9ee8476fc2ae81e330562fccc1c5c8afae04df3ebd6f5accbd7da45295be6c983ca2527c054c85f429daf31534e27ac2789dff2561d94d226e8a7312f6645d047c2ccb8d678f8a28945932fe47c20c35ea2586f3a7c9a3739e3762b8dfdba58476ee40492a35b4cffe410e46e7438960d1fe2122bec43ed151a2d13203b6538d38809fc15a626f0a26ca3f90c55df3e6340cd7ce0ef9a2c221a1209f767a734a583fcd1d275f95a5c50c61a6c2d5f4d7c68e53178a58a0fab71ed0e413e2c6d7a1996b4274776e5566465c83a047e67423db3ec451cfa797c7cbe906fbd1d42d88dc53ed4c543169351f8dbc53474e998dfbd59444a133c7a8769057758325464d38ebe499b15be2730c336bb9775dd0c2c9157e9b8e85bc54db5a107a08d91341b680b85de50d57429a082edbf78c20a1679b39d2fbdaf04f92f1d621d67fa04cb1bf3367e45b4e2ec80e34bdc54adba57d10fe46a56cf89db3287ffd7c04939a8e62c6ab8d20d27f262f9daac16bb69124ddd6593406c53970911e3a9b268b871aa6e8fee6ce2443fb6e790b3264aa014961d8843a64f32c36db6712c61bee31650a74d56dfccb7b58df1cdd302057aa963ab9f8730f10e12adbe6053a4cff2b9475eef05e7a4c00bbc7f3870e5c9cb48d1f2cba99f53416bdfaef0200a8baf124344f854323529b01098801ed27a031a73df1a318966f5461818c9950f9e5c7eb06bb8bf21fb761907c59545493f852132398fad6a26c171acf251abf2ab2a1b580f3c8bd9132 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 503c95cd907ee9759d22c6c75d3365a6850e161349cce75fcf21750b0283a7eb87a85c723a36c7c10c2e51e94c79a03ef372b6ec419223a1c42ef702fdb7bff516cd4ef797c6a056e831b0d903a529149a66972b8495410a11c4b2337ff5fab078c436082a149ef5600d3a4ba554c0ca778949ec073003b238ca11e52a1f788789ec7b07a60c36f0f8ba90685075c466e3520bf6dc8abcabc449e05f39909193c0590eda4c89c51128b82ac87770619167a2d24ad379c9fe3c6604ac38f0cc683d69720e04b94bb6724bbb4172e657e0b481c33435f2e0bf32078bea387d0e654ff8b20c73166e43c376a18240e869182d8ba718134cc7a50915ea0dca282eccf80cec68a08f576de1135b7342a96d5c7095e90722d59387c0ca0775a660e16371b03a0c381756636de530a48cbc330b87763ce34a5dba7457fc5af4c4886ef2a7d6d4a9502a9549275419703423050a2a7a63bfc2097be60358e9cb0b5c3075364e4007292aa9b78319c04728653debb8d7cb519068c70ff8813851a9dba7bd1974aa8a1032a36b32fc1350d7468391c3ba1fc6561b106e20417b4ab51126d3b429575e30558d3afbc657063e9d833a3ae7c971d7a1dd68718f0c4e60a18a2ed2a7df88a249108fac654fea605fd66b09f63a8885c8aa21a707c81b3f76319f370109ff16a0eaec503567438b9b5af9a7556121bcaacba2e8c40618e7b05fc77ebb2800e1c24bcdc21414f73c4ba25e4f665f9882362c809ec7d97cca623b2ac3af0fc6cbb06aa57c184b6f09a1142c9da8c1097f559938fc3faba65d6f31b5dc664101164e0ddcb80f2574369a16102a16c6b5a937394f28fa5f30c4306511749ec97ef300c2c4fa0ae5f0911225405cb2bff051b9202c8e1a4cb349f10c86e6be8ee7c15a096020e5b4f7006ad8eaac9dc845114574018a759ad8b9f0ac5fc51c1d4621baa35c77ceb68dd1b345c537bfd5d5165e8a5c64535512d70d4bd0807a57593bcb2d29d635bad880555c00d2c8a88b0b7bb332505a7c37c69925645c0f67b18a9a50b82363224a360e94418f0d9657255835429a9f3d4b533fe707b354b48ac82c04d49713737d21e522f7315607a0b600878b37503747627e9f4119f1f4cdb6b867da9b3bbe0573a021a74022c643c0ad3b75af2ff2201e2428837651c4f0aed6d1a5501361be417728076e7762a1acc3cfdc250787c79578612693383bd574902d6c9c11a77137d0c20d73a3417818bc48a13af18cdc35835a113d80753e29b2146c0b1371d0aa9debafd09252368c3ccad92460f0bc2fc6a1f6f9a999398a8d9c41717897dd80ab5a0c1a8002a1aafb97b4902cd764bc7a3403213a3d9328ce664744e585220c3851a2435bed3cbb25a81190f281729979bc9a002da4a5cda170fbab1f94d1ac29378e97964a76164358d80efec9c0dc1b214a1376c3b28755fcc5419b66e37c6fd649038c67302eb9cae4d9b94c71b46802b46e4958fc6745d6a56bd132953c868f80f73fb826479caca888bca9f5ba4143db72fb4b6a261675bb54ba33171b5860c9c7c2c51e29ce79f73b3becce3758896f98a39166799063ba52c166ad813b619011413b7c2858a3fb2569ad271e4cf3267853baccd27792ca5f002d32de55468fdb2985509e2526396fe3770a30a71eb8b2cdcc4ba704ab3719bddf50b5417cb3acfc5b4a77c2d5e5848a064df7b3723b57789579ada701212e68649b953e981239f3244f4f257a5f3777c8a4abbb7c61a4311e5e4515dc259d2608a7f640302ae727cd2032b9a4a7ae7c3a8b7404e3ca26638ac53979cc8f0c5102721d94d37db3c26012b9a485f1311233950901b64b582c7484ba251bb4598348c38a7fda319f76683137913b8451356e56245050cf0788cc11d583b4d36b59b929f70a0d9d149ad30660bde3c792e1b286f214998abe23c40effc0126ba202804a900a93623ceab5c64405d675af6a695c3e3c117564c16920960de65faa3576fcb14c3099535485818c0243d56512094415074b08e7b71f9a6107ea8a8475a290a4336c312a0f2706c58136a3a756a37a79568a441b50483b61c652e806af7ce3637e255cfee10986e9ccc9c70c1607127ba23415b39d4955b03c799a3779a9e02cbd865a12aa24c320c689f5fc12a0a39635fa275322f0fd2ba9290d26bf810393f6da716a4f1ffc06821dc7ea1cae6592db78b5d4e40e269c33c9b94e8f78d54d0160e551d89718b10cd8f02da088d5d42468247473e114a3ce7effc663ead84a6c06d616c89521ab268b196b1abaadddc04dfb +ciphertext = 9b82056d6c52a93ef2f7f3adf6f87d56dd7954ab52b868bb5aaf89ea45c17dcdb0ea3a17deb557535b03022db3f9870b001006716e3463831b66eb8ae7cd2d83be374fae797b1523e3667a075d57e870616cfbf84bed50b93d0b9c43e06ffc4a92cf3e731595d24490e89d4287653862540e6c01da89de2f59fa705cbc1987144310e2173f89d8bc8c2d90f09a73e6010e7d61da42fd172fdd5981e34be4c7b5d9380880d2d324c4988b33a5ee41478fc768348a9427d824852e2ce53c22acad1d2209410e06f5025f87e1eb9290979e5521dcf8aaa8a6f7fef7bc04846fe68517940a06386a8611e156773ddb7c3e900d8c9f69645ecc8d06b6d489f90c94dbcd3c4de51a01f53a79ca5763ce3b69de141581d93eccc4ded580f58264935edc502b877e34dbe86fc0c5e068d04bb0fbb2d61d74833661ba137366dff37d8f6aa4883b05876a2b557d4bbe6d927e7d1dfb0dae5746e7a0014c0ebc41278164bb13c5501f92e912a212624c5406d7efa5c0df7a39e36a69fb322f8386f2ba5e4927ce377e7a2886c6e145cffc1cbe5dd392eae7cddbd9b53ff1d45ed2fe763a63d001533266fcd781365034df657f3c8ad91ae8a8ea7d712ab4a6ae9b5f775dc75687b6ddeb52568fa1c56652c65defbe960eb4ba6824668c14a9e85c8dde3088de0db80cad137e78369fee279b10f5293117982cf9c2ea24d66bcc521ee0e6345218e295ea6c08345979c23d43f84e5b3a62b146ce3486899efd126f7c786687218832233fd32bef71e396be4e4820d109038763f6e7af679d0ac356f735faea49b3816876f4f6b30286aa4da71be8794ca1c9a7bebde526547822c50ae1329d4d9380fd8d148e52ea214f44b4eed7fa800d6e3c17f49f629674fe453ca801866c707ec5a499fbf0cef97659b884ecd2ae51a556dacca12b472721c523a6b2ec15d7a981c8202b3bd3b9eb134581439691b2bd57854f3070d8102cad089666b9de394ef9f349242a1a445307c576a33b97fa302bd0f537f1af988ae2f20fea05afc01eb07d13eee618d6bcb2406cc74e3003cae3eb6e0e73af6ecc75d9a0059078e5f95ba6e91fb5 +expected_result = fail +expected_shared_secret = + +comment = Zero secret and error +private_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2bcc23f86fad7bbf21f7ae3b6670c60fa345850ef28f04d442f15fd171847db7e11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = b09dad6ca6c4e0c81dd499ac65414937b26e9ce474cd083f5762b3c84d3a808d6a126a606b181560be684976e83c606acddf25fb47ccae173dda515226bc3e1d79192209a31c9558740376bf3ef8fb076c8d6b24b55fc60ccc24afa091727a84d7aea11e75d70bcec713e2aefb75e5ad80c534726a55a122722473ac762d1f1b1b52030d6da4d6a4e162188d043625048455ac73eded5e0ff32e73831dbd860b6886d684e6893c011d33dbcc435643f29992353257d20697c053521de2779819c532cd842e87e1c1b8cf56e5b2243414b02cf6a9d8df116655352abad59e99dec0d81b1b3f65a821303498a65727508478c88002aaa8e4000e2b5f06303597f0cceab408bb0e1890cb9b0343e8b3cc0a829bcb66534844dde8351943b26cc84009f5363ac6bebfaa311d089beb528bdbe1290f431f6a63f3113176efeb171717f945c662b4dbe1ceb8f58e65a586c4bbb9cda1955f8b97b3c38fe97260c5f00a7e8d906e09b622a089a4e704d7a20460d4bc72aa719728235f7b188516c484dea081af29af275e2e05942a0ed3fcdd81e194b8e99110c4bfb57c8b26d82b81ed9b9cbe45a1a4b163dda9dc07b3f588c16a7a5c5ed6384392f0083f1f9c9f3ca75c0b82b624efa512610f4b5c41001a49d3dfae55d0d7f980cca6ebf85151724cc9e45ccf865c314a949fc12aff91f0ea4a4857fc8212f9231345115d40df1f7102ddf8c3d9776a5199c0d79b0d15049acd167073c631b0453af91422d711fe9616db5fdce9e695357c5d35010ac4ba91c7fc65ec15503af873f55cee8a23d04b30757ca75fdd4290d01f675f3d518dd4f572027f4098c705328dccaab1c47514504d5c6de37e8c69ddbc8df746e2c7cd1f43664d4297e2113aac8836c0be469d0888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_result = pass +expected_shared_secret = 37edbd09946139e6e20ef35ad82ff10c4cffa4be5da8433878f2fafebd29386a + +comment = Zero error +private_key = 67330eca16535be262d62cbe2fda08427c7981d063a309308b516e6875a8a2e870a1309ff7abb9f9a907bb57428a457b48727817bb3bb3b7b459cb93d89a3e8f9a7841c9167f290433f35ee9a33da7a429a5aa448af12348c9c5d74687ed462222741ae664a8b21340c34184e7a5ab9b1a6c842854b7aa1d4d566daf2094b609b410750f4cdc81c0d338921b44247c2ef39a75fec62b81528e08b3202ddbaadfd25770b8bfa77947b75182a868288df703f2152e3faa0f93d80d383864ae87ccaf6c5eadc0623b75b14bf73e1cfc6d14171265d30f4ab46deb986f4f0192f6d82dfa9a252bb0664876a793db36d974b50186883b8932421c29b0a5060f82565a640b73655ea6bcaf6ffc46554652a33230dfba582b635179018aaa02cf49f2187472ae7dc57856f34fa6408998bc892b18484cc5a9e9c040d61a70acfb56e2a120a54ca86e073289ea3c9710c86ea61930e79d381418017090880c07aca1a9b39802a6b0c6e2db13de67bc52f47121539cb5089b27423eddd70395678d2738151e8c6238f4a0eda67364e98b87c1a40ec658fca57bc49a69eef23b4b562c921b5c061b715ecc2fb4f8c25be856ce116dd569ac54a47fb8a54f63bab85bf34a8f4364a3040cc9f681da698b77a26b05e529bb53a965fc7711450833252f2be17a8fd799e1416f8d80589da5462ab078d8aa87b348cb31153d1a097d54a32f354297d643af09e37b8ad272bda697ddc9c094f699ae2002b25178a321be679b7ba82b50442519367cc05f0241a5bb6400c21ef0a797f6948a3b924fd31380789cb177581b8f7c7db853243a9c7a9d933a8d13a017b6727a5b414304b15812414c39081f7103017ac7e5e6b042b96673e87ff37508295443c5f70c27b4bdf563b259f83b0bfc820d994e08bab7e80c287a913003249b7818a7640252a5b9cd52e38e25b2883a758ff7503bd29ac3ae3485bee2af98d13b5db7a147f405eef8865d14c598e7261a6318e2d31254424cf088c69688518127693e22188e8897bcd65f50580d5a7c309ba9cd309a2b3b201fe074027157769352b15026bdc07bc8c925c076148b17115a1ac8afd33c70fb8435f421bc4c2966d30104f8da40ed531460905374c15890a8152db91e71d31d15a078dcb1aa75a0b1b66c482e1520dd789766164ed7864e6b777713391457ca0b29e2442ce51419fbbf715cbe168234fb84828f9c244ae0691b817d1799543343b6d1a61a8105bfc61a448682040f4b775d7355a40b3f447b2e70a54655fb539123156a983ed08b2163e22ae92b4071caa4043aa6430783abd59c541413599ac193d7cdb14275d7906e1c3758a5187ec97c5f2fb0924bc7ac339acf2bb94b831c0c9097055c389e00b15231e3cbce848db5015f2497a5fa8672db589790e71437155e9ad8ad10f4afadc98686090229accf35b43dfaf67e2bbc218da462c8846b890410d98a7760f27247c9b63c8795abeb826921a70939a56e58220624cdcd2b8c10ca5213ec3ee91c3b7a01a9cf2303ab346734d568eedca4ebf598ee97b81825acc80b79dd3a94bfc9c8a041ca9d303843635c917a8d30e4ac4966b86e80999435ba05c73c0621a04841267d5c3dd8c54785a6cba1ec7c3ffc8a8f8ace78899a9ed769e5db3582cb1c86c39f91f24b8ebb01336c5141e86ddb801084ca2ba5acacfeb88484e886127ab31c12776193af6f1574e82742164c0012d55405483d74d511c9d48a87972c73426a4bcb713cb646ef62039e441c459cb1a4b0b088b564e114ce2f25648b8bbe28f198ebdaa1bfd19e0af67f6ee868da759c3b593c104821a50500b3f87327f70714f846e0889a015345f38898390491f2ec5b8af52948ca06e6865787064f611ab31e4b28e1b08d263c0786cc22c0eaace75467272575d337285cd1816b126383604f0de86bf9a1c51a042f387692c6f07073327070f209af85b13529a51cf800c4735f0e3654643119e4705a3e9c3fcea876fee5af72b71351b9796c118bf1182bf2fc74e2354920c102777841ccab3f853b84308a61b0fc51c175577ecc2b01521014b3b82b4674bb9a08e8eb721c4c2b01fb0cd0f1697119c2c77364b53727b195b2b458299140064eb55882104178b5742046981752b03d92b36809b4bbf3c5c2dc18f0e98a0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef239e5ff9fa4e2b445f3c6ae9babbf72a05a498727db785382b9bed6f49c52614b11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 6e4c471c64360a6c0958d5cdfdccc3470956430d2cd8f3e17e28cb2bb247f45719418d0ea31b6228ac8bfaf7985abe5ea5378e591af91baa4a2a8f3d8938ba71d7655f5cce981d2692bd619dce31dc8b4507f025bb9401834f297b85225f889c631937799468fda9fb792bec3989069b572415c18909f6e8f8ae638865517f01f09eabba737d241e7567118e0210524e3aa8e10c77c4a2cf29ea5f8c71ecb41cf972dcbad721924e921ab26664fd7ff017b6acd754ead449a36e805e8112c6519a9f4d3bdfae97b678aa54eb853e47f91d6e902e4d49d9ab9e7d610f769abe6db27af9d29c025b03fc188e4f5070d899f41054fef7f0804c4176b7149205732212eb84d96b54836d622f58ad96e39d4cdcd204c1433750b06e19fbcc36a4402ec2f55fab4dd55c1397e432315c803e5e0c9ecbffdc85a6c97b26ca500e4a613ab4e32d96edb25e862531a6b5dcec1f3f19b350fb8bbe0607c1907155d3d377cbddfac363f32e0da897570529b8ff80ce8cb7b9ea8ee9f7831a48a516a4fdef72c9dc48a491f0cd093afb714c6bdb39def5acb2a35a6dfc5f2c87fc703257f822220f6200a5b3901db2ba6ba8bf99e12c526466ad326ca382ff72eb62a5566f591aea01e28fd0a8cf45fc79423f159479d786084a28da9c0d4a38e65b658f2cd3c099dc7a50e626c416b4e8f133028c1615d2236dde145e94cdfab0512fe32eae9cfe8bd5e9d20d98f2fcdcba65b98a746808a24422b6f77589e644f9201b1bd78d0288f61f78ab22657983b6645d5451b6097fc3a535fdfcba6476427e59e317d71721009b2e768b9f75a92b8b43da45c034cb8a8e38f3ab08d61e6f4ac37039f696d862aabe14c0313bf02a8c56b7f1d1b1de1ad9f3b565bdbf6bb772ca9d1aa1b952dff7a9a8005476e25acb6a4c74403f4aac27ce67a4d633dc765eecd8672c65b54909acdcd537751059acc4034af72d838914a572acd1c9644b2df52928ad72adb09a56fd739fafd7a56ecd64492386c9aa5f1d522db5139ee733e072da70ebe494c638325dfbbe83d7cedb0a9bc17bd665b8a10fa0ef45c11e16b8aa3e +expected_result = pass +expected_shared_secret = 07d4aa5b3eaeb9e27f534fc120c0f0f7789a40cbad1abf26c3de26172bfc28b9 + +comment = Zero secret +private_key = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067330eca16535be262d62cbe2fda08427c7981d063a309308b516e6875a8a2e870a1309ff7abb9f9a907bb57428a457b48727817bb3bb3b7b459cb93d89a3e8f9a7841c9167f290433f35ee9a33da7a429a5aa448af12348c9c5d74687ed462222741ae664a8b21340c34184e7a5ab9b1a6c842854b7aa1d4d566daf2094b609b410750f4cdc81c0d338921b44247c2ef39a75fec62b81528e08b3202ddbaadfd25770b8bfa77947b75182a868288df703f2152e3faa0f93d80d383864ae87ccaf6c5eadc0623b75b14bf73e1cfc6d14171265d30f4ab46deb986f4f0192f6d82dfa9a252bb0664876a793db36d974b50186883b8932421c29b0a5060f82565a640b73655ea6bcaf6ffc46554652a33230dfba582b635179018aaa02cf49f2187472ae7dc57856f34fa6408998bc892b18484cc5a9e9c040d61a70acfb56e2a120a54ca86e073289ea3c9710c86ea61930e79d381418017090880c07aca1a9b39802a6b0c6e2db13de67bc52f47121539cb5089b27423eddd70395678d2738151e8c6238f4a0eda67364e98b87c1a40ec658fca57bc49a69eef23b4b562c921b5c061b715ecc2fb4f8c25be856ce116dd569ac54a47fb8a54f63bab85bf34a8f4364a3040cc9f681da698b77a26b05e529bb53a965fc7711450833252f2be17a8fd799e1416f8d80589da5462ab078d8aa87b348cb31153d1a097d54a32f354297d643af09e37b8ad272bda697ddc9c094f699ae2002b25178a321be679b7ba82b50442519367cc05f0241a5bb6400c21ef0a797f6948a3b924fd31380789cb177581b8f7c7db853243a9c7a9d933a8d13a017b6727a5b414304b15812414c39081f7103017ac7e5e6b042b96673e87ff37508295443c5f70c27b4bdf563b259f83b0bfc820d994e08bab7e80c287a913003249b7818a7640252a5b9cd52e38e25b2883a758ff7503bd29ac3ae3485bee2af98d13b5db7a147f405eef8865d14c598e7261a6318e2d31254424cf088c69688518127693e22188e8897bcd65f50580d5a7c309ba9cd309a2b3b201fe074027157769352b15026bdc07bc8c925c00a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef29132a48f747325d56657294dffff3f7ff488c95aee18088598cd30fb24dbdd5511536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 7ea4ba64f0b48b0517ccf03ce502b22b784682e50048c48a07077f6143ee4900589eb086f147e66b1ec4278092c4bccdee4228477f06d106d800fbbc08f9ece5de9a0299a7de50c14e63100ac6642718e5f35b347665440dc2f66d0677380940aed6840c9b7d429a88974f9a37da8e2684011e58fb607535d5077c7e4d7fef8e3683bdaa30c5b3755454a1a4fcf386b26a8d7f5735c7f344af5b8ff6f89ed54e0c64f1ad2ad886045cf8631bb03b49c50f4074dfdfffdfd3c1fa829b4a8ace4b343c82ca336c429ee427b6a0d59c1f5e0fddd9e0cd2dd7a0fac57565f30547ccf25a6882ef26f44def60acbf1e33c647bae8d4aa9b4e40b9b5cce8626a7665e7bbfab4c02e7d9361fb38e34e4eae23f944ed05a647f771fa068cfa6badea473324670314c8e7b05571378df2707032072c8d42922412e3fab0d4cdcd5f343ee53b7e70a1018dc4f818e3c9d81515ff3c8e57479401e6ea51da695c2f4474ab1fcec2679f780905ce95ebd25ec415a2757cc9b5a0644d0f5abecec155dfcb75f674cae39d4346a7787cc9c0e038a9d599edfccf764250d51d7e56a02d163f97bf60a4e746a74288648b08f0d1f8f0d400f7cb6b44f83fdaadc09146e09f49f347a3a6aa34d9d40f75bf9655a78d76b249d68242fc0da78e69e03d3db8c8a0b9846954128064763ba7d2aa36c2bb6082ea8aef0f0c9c4ce43c93e9c4a861a80009eabece5b7746de3fd7487e3c537d0f7c35cdbe1abea4f6df7714a759ec67e7087de168df199de01bf7eb0460a4e3d98bc3de4e475dce50f921ca53a90336e5c14fb39ee1144e8ed44602f6746924b107918f90cbec9c4eb6a9256380559940b698f184c29d8cfa9bfba5d2b33fe101ee45a662223aee1df9b8c88ed7e645b3e80888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_result = pass +expected_shared_secret = 5d754bda8026a2b0965398cd12fffc357c16a445e3e701403888a18a982cf189 + +comment = Random ciphertext +private_key = 55f588029a6c6074834dd93b3144601a6c8f9e98785f031e30267902b85b48675ef1fa2b959a96e7a5b5a7d3c671da06b65a4b4c388f5f341b99b2291bd12f9f9cb02d384d0943a781e94058481bcdfac84fda7350621750308667c37d21d0a1f0f73b0fcc1aca65b4813b9802a2a02d7a92d536578ad26214eb1c7a3bac67d04110dbab0e6bcd97e337137462c8c73bee600cfd47098f4a13c4c213852c4c685c6f723bb13ee5c4cae00b1a0c235220349cb8b864a4c308c4cc0a80076ee2c19dd83b05fa6e88e286963c912b0569b308beeaf6010e56ad8192cb82c596c33a8117e95112c261584c595b85195d4b695226086fb9566ab28fde38032ea67931fa5b886600930a164ba16ac1fc26fbfaa426e4638815084f016363354feaeb77c9a914486c1abe8495b8fc0d1fec442a8cc81f8a771714ac33c7afd54b1ae403b229256b3723744a729a19a830d0ba83aed1c73905cd72f40a6ff6cd96c62ef2f55e48a608d0789722cb09d1772a5c2cb8bcb3af54297faedba7dd7b39c66064e8e81f05d4cc9ed66f0a2b73991806f18a4b0b73c4e492aaad985a0730074bb559aa35270aa74c11805ca2a88dd2504131f3a39ec996c20c6d317c77798c975aa4493d72c1da229c5d7aceea41cafef041703b5e6911028404959ec0be55c999ef49552fe67b3fa63d8857347201378f5854f0959c5822700d5789dd34002c747551d20912da27c31950ff11077e79a64d442bb3622733c63806538e2d0947b2e1b65fdab889627ff5ebb02c808047205ec97a263589a417c57fa9e2b7aa03766897a1ea918cd7e6b507dc23dfacba8d25c27191670046af6b26100d61ad11f815cd71b4229a943d10c629d67d317158da2044c05239aa2823284c14326969dd9616aebab334a22af3c0981e41c9650803c16c09fa3611f54a1398526c6fc91dbd73143085a4061b17fde83c847245b1d264a2f0449ef9a8e09cba7c6acd5d103c7d254f1c3b0e79596b30d4b97ce39160eb36101b5696869dd9065ae1c863ff571583019b0e377369a108471b0cc0350a0c46b241a0931c5c09ae1ab825b02ea76a2c4563108da741bf80abdcd5b2a48545b5851261da205c8c08dfe996310a7b757bb83f921bf4761f0601c0516147d1f2449e17cd15d3b6c7458b43b00c279b102802aae48709ba1b2cb2b47bcf8a3af1fb5aaa1c2046f63d185339697c2ff3db0dcc09954a457178683be91a0e631cb7ca64b64c766ce44440009110b72c8c2137153927c446ab425dec652b3a3c4647913ad71d9ab4af4ab2327c8b596ea65f280983b0d012fe30a9e080a3ed5942b4320be585b9925c8ff2f28253805f189093a33814772c9c3f36c5084086deb09115fa91ea8c2301558dcf60839417c73d7442d68b0c55494dc5287db20632e9c287b0f5b0366ac97552c0bc2120a38887c974a1c09c7078e16e462a1dbf22c94c143fef5017d08868c6ab140723addc74c6e1c148a3c5979361baa918ce74b04f7e829f8e85cd204bbec7fc5b62a39973b18c47ba2c74eac31ea81d976258df5b9ce12c168b199ea0684b9fe747b41c22683bc2a0d4a08dc9a9a03c0c9e19c8a0416ebaab4bd0fb2b4f6337a8090a0902bc299959d9a4a8f5f91ec3c99aed0c46ebec187ebb5cd5cb2fc037bb30c83fe2f60056b6043a477be0d824ed88b0cbb4601b7973efd9bbe886b57736029419384f725c59d56ad79491437b2cda8b97f95a758e7877a5502f05312685f74b7c3bc808bc5563f22953ab15c002c3189590da07a2917a8c5633a331458835baaa8ac17ebd2c27f7ab1ef265211e0a79d7c643aea113b109048e3131fbb61caedc6df8e3894c434b53343d995a05af611ba6f29604604a45fc1d026c6529d52189506fdfd67137e28a0dd160ccc09f252756161c55798c6452509f0431af52ccc97fb6c54956a8b1920194fc6a32d34fba5c9c5af63915f9a2fb7c700774b9ed504952e52317f46cf5e1abe552a04153736305578fc368233658d325377babaeeb61bbe45473b8517efb600739d80fba7cb33603b7e15961c48a917876148e396f73dbbe250126d25a9a52e01b486259661697cc8b1e70529149e25497573e94a9abfd17873d30a38536635f36b763131ae7f304d91c4202bb4ccfe44c29873ff198b5d88acb6be68e169082c5ae2c39845bf15231d98cef36f30a113f0e781eb85c22f594dc1d822b5a78e117fc2d9da6d77cc34c22b7e292ae5d001e6da4831674047e7e7a1649482e1d9b0de92455cd14d0049bdcb7cea4b867ace5c8922b +ciphertext = 542acf1e3c7dd990f1879ef5b5aebd32055618c4e5b958995f0b22a78f9e2bdd8dd0cda23893c56f48a20d4df878e1cdbd39f50310f2ac0cd502e761329da00d49e7b8721f53af649ef7edfe74f259ffefd492f13b1ac396eb65916e02b3348560ca426e9b93beccad58bcf0c5804f0a10532635fcb74e45c1f8eaa83d56e78d8a7ee5aadcb7e06eddef900b484632bf1bdb0e1a4ef8b6fe34789934d9baa887ec5a39dbc6416f66008751aa193a9c313ef8a57a515bfe046953fa6a1329a770e9e1bfdc33f3a68dbd5cec1c2a55a0e41093583230ac35386645e6dcd166f25706efc779fec0cc4299e8e7501b93a857378713475782cb0b31ab645940f4c875548345ca0138372719c3cf9022034f17c28bb90f6090d4b8be957ec63c297a0ba95dc02f8761c18e7a948c1c20158230e2f9ff809cfd01b9d020b7164f8a3c54a143594d7d35b8e1ad6cb25d96c11c1b7f47f62a8d90c0e2b3d1460b86a463579e7b44ff74b6a29f30521588a26887797c60d86235e0bf4c2bc7166bbeb275996e1f50cfc36641710a52fe08fb5dda30f6129d3a304e336ff0d8698515b2cc450cffb45cceea7ef51a989d036c71367a4d26cd6025479d2f7ae58e700928e176c59b3040b054a09312d9fe529ce784a71513b44c1cd4073209a93a4df73b7097da88cea0b31c3e77e70abcb4b2ba5edd8db8f47ce844750158ddc5609dde43eac393eb5909d9415ee4698d923d8ebc28612f8b0676565010360b9406091ddc881fb6a992b70645b6898d13a8e3e449be589cf17bf9312e5cc58b03d3c181f7f176b67bea210337d6c52913f8cfe145da9426434c1fad0da7911bdb35e68b86b5bc6717dccee9222c4842c28fb13115278f1249b213498791082bab15d32f59481b29b9512945602eeba8af490af99fbb841bd1aead2b4f6f57f19dc970e83bd3928ea2d33ca3c3e50cd5d68e6ef516371cbaecb6b73f57fd5ae5b38a74f20759dcf217066081fee51f0fe8a93aabeab4717f05395e304e86bedbe11d462c1cb9d4e32e75b35fb707e7b509e43b450d6025b2d3e84e00f3d92b717578e820a337 +expected_result = pass +expected_shared_secret = e8ef75424d956245c50bfe599b29fc4ede539344d4a39d3ea607a71ffbc9e5cf + +comment = Random ciphertext +private_key = 0cd7cba139a3a6089b6dfb81f6c8910464be7ce0216a81a3a2245de89b13b3033cc8b1c789bb0eaca5bf4a549603e44f064a6725466acdf2b55dac2465f1238732440c89c43d03ccfed6a9b4d49a74e43ee2a6316370ba27325febc4acf1b457c2da6f195276041111cf9c9d28821c6d837a00d1ada8742333a1bc4e652ac57c4cecca293a41b3a44411e3039eb423623f47a14fc18e778341a664bed3e7200f609993e08a490a7d4eb93d2102c713f655211a0b20c81763d0b205d96cf7335421344b1434b24c599e2ddc79e3453a7f997af0b78d2593234d87b3078845ae4372e399bb1e31a5bddb7392d27a7513219b9067909505d0f4a6942b6d3ca48a7864a2df357a60875472480efa659018812caef593c705cb14f08c6cf42dbe97c4dc95ca798c3449f153cd7b5334611e743329b8b88f2b191e81bc9c7f9692baf5a1ee664cf232399a4a37f6669c47d18ea1eb5237312125f238cbc25ac5f383f4e6567538b27793b2e7e09396e11a7fb155a5f57a88769602d6a47f19535880b07f213e01194691b8ad1bc4190625945638965fa4190f6374b61b66b453b18858c36f989daa87c31175ba76b84d51b805a515164b921099f521eda51c513a088736a5a442a6aa729480e53f6bbca68ba964bae0510442ac2f4826a0b484be711995955c315031b88592caf0ce6c538d01fbbf74d2022b9535d4279088f4787ef7b944f7ac1557aa659543331a10cbe388a7260beada0273e98b8b59132e4a99ac91719617bd0590b151d6451582278b1a4a8e419e93e44eec73cdb1604dca2aaa5a9a669739bef527ac8e04c0930436ed914431a34de969293cf9473a3c0e5a46881b2650a744590722cf58a7894c51cc7f3565c50326e4f399b4a441f66a2066905e3fc9bb24e935a755c11d02393c3484f4c4305b3183474866643521ef289d4aac9e9d3664bf931e00a7bfa7d22fe1242d1499272a0270784490317ca4a65ba181d1bf45b7b337d09786682016dc7562d283d8e31001054b04184323ccb7bf6aabcd4c9d85e7556a292b9966b9c06b5e78c9516be826532692e5c6482d1b4ebef9876710c42875a486b742705562265c9631aaba9ac29469399abff5584bfb0ace196db6720fd9342c71030960e76a0406c1ef169ee7c64136c18f218a0e2c0c01f85cc414eb031ab1b1a487c3369226a97b70f7da210e113fb89a48efd5aa7787bb871c1d34862783a8b9df1ab34c13c671b67d6b06917bbbcb09a4a36198893d0122648b101b46c1d72b510039a58fec7452f321fb738dbb157c890bb899a4cef746ca319c6ee481ce051344a0e6a9bd212cfd7c5d79a4806041189a0720bd5c9617fa6959b79cf0c4bc7c835ab5a8669326c6540b8f9c8b6e5f9037f686b4bf584b7d9476edea24ccd6aecaf92d29901dfc0b11d0f2aeeebc1954f969852832f773acc748571a938d4999004fb732bab05ab53b729af3c5a3e372bef1896b1aac00a7523125b7f2a06e8c5173070b8f05d235cad8605c4a5849b76c3a8222f34b91c5912bf2791887eb7b900a1f8b522173d33384886e6fec37dd81bf61ac801281a2b22899615009cc0886946ace94802ff683acdffa9b17d8b99b5933c9e03dc432c7da72b61989ac51210fde7b8ac627487fa49db4e8131d7c91e68b8f55d3064cac5172343bb434a922fb9ebe5a265138b279f483f939452a1470cf3134c4e088f745c3c64975a8da0db349411612306374b4e021c536085e65d8a1bc59711c04b788910a3fcc6eedc7a57d1160d3160399689dcb8ac9e09c41be015d5e4503d4ebb6376a5675f32a1b287f218ab3566a1c5b605d5a82a5e38a077833ab1946bbc48583b5ac1643909c81d0183abcb4e57bab223a82d7a35986a26e6a18823c9c3b0ccc13bc808a48a85ecc550f78d340ca1a0554eb0985976d67f923d1e484c20482b4c9355792b99b24440c302408fc3aeb7508d826788dda31246b509ab930ae852b8ba93f85363277ec8ea4069f3f332fd1a093aac466bf49bbfe9172bbec20feec559102733ef039d3e83ecaf1c1689cccb4b1063035a162d5c387680c45a59c3f65054e2acc471a392e4a38e3cc59d6605a18b3283371b67f6caf0ed9123e9b42417851d9131fa94b27202098c08157738c3f1e7680f2036e08b8984863ca349c84279c8291cba5962d4397b1c15c5da52549fb5880e03357c4728f8138a87716fa89df60ed857be8693e0c23d028ab3ca851a7fdd1007729c01dbc368019ccf79b85ed02e831f26388705762c0a5f383a38f90ea49e255c8 +ciphertext = 0c3acc5aca31ca6dd2bc98079688c3393bfe8201aff86e2c3fab2ce78ba02227f4905f3fb2e55bfe790cd0db3d15e586a66b8c561a30fca27ae3fdedb9d8e90c8dab0519203fa49dd0641a70a0d8c399b5552984cc72aa8ff7b648b60f467ed8043ddadb603938d32db2319e5817991a36dc11edc2329ac1648bbe0c81828453c919623abef45ccaebbc903562ea3aa11014a1060694db487352fb3e51189bb7cf291cd2ad713cfda6cd1f4cc9f1110f2d6afb2cb30b03df615507cc8d9bbd4199a2b53eba9951adfebcee89a4cbbb0c2471efc6062de2f92cfb606104df9056e3585448ba6243094271436edad0f5ecdad868de56d05326dad98e9220b29ec67d64d702669f9fae9950c02358269e344f6d6f86252995a96ec5750db982b190a284f37c5498e15485dc50fd04c812e0f79a722c2136c32b8f2d08080fd561a21034009abb1fe455f14b5eec484f9c0cf2e003dae677aa05d39adffadcf6998ee6295d50faf95be9472a2f63f26ccaafdcabcf113ea1c6d3eef73e7aaee249e0a82978dcd6422b5e511d344f441559aea37d7e0b913548db8fb2a1db1a8d30df569ca34a160c1b699b945901225340bdc998e34d8499b420ba7678106091e8433f1b9104e7ac2943bced5f07f895dcadd8525c7277b2a3b1648547501b59270da2feacfed703c177786da88f636148a4dc416dba0be375bb7c7f381566556276131164f74ff217e00b1fe5e6a456dd6d057792392f82bdba54b83b447c74d025c37706ef82db0151c88d5789d1af4fb9ab48359b460a54013ac0452f98080b882eaef4ee267e7ff88bc94722b7a5f441273f2c031135a9e936574c02e4b329cad405abadc78a06d4a75903dac2dd2fddb565416258d5a9642b1373a643c0a5086f7dcb63eaaff531e9100b214576eae59e287b00364e6d04d313d8c4c82bfc11ebefed1f8c4b2b8b0067fac3b7bde74b2b33a14bab53762bd3cfb26bd6cad865603dd88925a83fb74bf24ce94872c6511e8e0fb2b527bdcc54d6bc2b18d5468c7dc31f52e21ecf879d90437b323db153c3739ae9e4e4de6a9d4c8910f2415340 +expected_result = pass +expected_shared_secret = 24780a12be5a68c252f0f3d357e05e518669760e9e6e8d849e87a1636c48c384 + +comment = Random ciphertext +private_key = 21fc56c8396a8fb27954e0669faa2438233c16f24553c84068ec96ac294ce282cee4626ab03592325c32a3ca02eaf03ee5b1c366ea02b6299462f257a84b457e94824c1319f1db6685053be0e35d19a33df0605ef33a43e21073df2abf34a5b76c6553b6762b7065373eb53a1382adae599fc5fab1ace5cba0594161a030ba1727beb15f51d66d36d3c57f29c094226977173b4eb01757f5754445aee5765b9736b95f424f6ea2321cd39b7565094e42772b61272f4cc456eb9d179c0ca79059fda7073aa7cb23171f8a13712c15041e023813128cf449c275ca9a600147a3545bde20118b3ba3eb8a93325b8720ab5bba0ba320111b7988aee93c4d0e93cf07e4b0586501ab0b22e9fc49260a01c92b0fd3f5193c489df7dacc03031701c538df645de4732b88774abc354160cccf66c25ab4f4401b1060427c39ebc1b5c5f626ed550da0005dd82a5e73d90993db1530195e8ac454d0d87d1738b42b32aa7b1ab0545c9287753cf1b4cffb33840583b2408a202b20b675c17df272ccdbe33d26e294f591343fc021588b050da76f1172ab2c90ab51fbb402233a7941a189e52dfd6002f3489876b7074249a909b26e96788afc1052f7fb65d733939501c0fc48ae38c767a0513feac6adceb8c253b90ff703beff466cea18a6964a96d1d1247883a8ebca666e5825fa024c3b5c05e006519bab6295629135282b83f55ff7a48fc146ae3528aa2f080106307ed082420ddbc7b46495c92b728b297fab6c132d824e914c78a407c1e21c2af2d1c16cf5b817030f9c67a2c0ba5b477030457bb4b182247b9354aff2bfb9f28dfbf980396a6eadb82d1ee698a8d8a914f1c7c1b28859100b93ca13acc14f609b89d6721c96a0ae67d8b0ac42862db45888f34ea7744e653388b02b6f29c853a4047f282aa09e08280a3a64a925749ac2ca273c061e7c6f15a8a7dd8821f2c688a047ae2db756f7ac7a3ff143c5f12f7288ab6992c5d7a1bc9445cfd82122facc6267586ef81093e1f2259c892c69c9508f188c90e073118b62de7273bbc22099741b4bf568e14c8a6717033d742dbdc276ea75ab96742e52a6a5f75a5aea37b84219451ce806ca918c57800b98d81eeabc08e1e0199ab7932f057b08946142f2a26a2052cfeb4d1ebc9669b0bf9223bc827121d72373c8608c69f2c4c7a640f84934b8c130bc0207e8898ae65710f9e09701db167a9955885b7211a43ee3f43b1a9a69e81c1a5f58a9a250bbf50ccb810b0ca9e482a85bb7811597ec287a57b9aed5abc3de4047aba99d60732924442ca8191ef0fccca87908a0a6c7cca83903bcc59f585f19261195c48739a972ecd8755f203a326496bfe0370a523d8ef8b729c3a6e2d302e3bccdd3b06b9519ca132b288f703ba3321b11baa48ce3ca856284824b162cf4aaca161d8d0c93dc7211268544bf348b3286166deb4aec796517b8c0c75cc55df6b4bc148255e079cf306e0e8146572c73ae8269608c16bed96f8691062c6a9cdb6a0dfb140fb0ea7a7a36a0fce95134fcc595230c0403b2c6d3b0dbbb70d3d3c9d152c9a0e1b7e6f46131e81f3f50bd37c2bbbd3cb59135530312ca893712c30303e7e08b767aab75ea49b4d82e5ba00b6f709679603f3b016385ec8b375c60e3b1c47d592516c84eeb1490d0628f9ae55434bb28448c0c2c595e0e3ab713e95da6b184daf9704a85a64d5a00b653c31c1514c8a0cff8fcb7f360a717d2576a08427113a9e1b3165890c2749ac4a5717646e89da982053cf379e52c50166c9be7b30d33390c7d399215d9c1c02bb7e692a8b3011daf6c1e6bf97010191a03d986a3d1454fc7567bd91f61898da81b1aa0e8912f30c224f4a087289ebc127082358a31b6b2d173a6e4340da5c1555a9895be05536fb1bd66da0e4e133701ba1739f3b4903b41ebd79c5c6c5ef1188e8893b8bbc36b25c950fc08d02125bc9bdc8f2c9cbe71db2a9c772d4ca32283002be2420fe3704bca1c5d328a7c141cb3e5d30a92c7215b250c409c9e7128008c3291cee570cdcc2d98a348663bcf7da9bb21939fda5671a5f47a8933663cc27730f6cd841b9b6d087ef550c00b28153682b844722e22338cdd65a1bec63f1aa9c2276b27720380d2f04b974ccc40e240b920926d60c3285813f2883aaa4633be3c156c47bf10d9987fbe15130d79895230972e16bcbdb128ec0016ec20b1bd768e82fe10f70544ed523e36be14854890f53cb3ac4d42b0ef765d158a0e0de74ddc922ab0178b8e39bbddb9f4088da50763ca088b48d8ff7de0906536e3f1f8 +ciphertext = 80dfeac580c91bfbf7829267a56baa392221b7ff1cc735f9feaf2f0bd4f8224533801581e74acf93b3e90611aba8eb2969df138ebd8d10a2bd3d44cf4ccb7ee39b58845822cd0d35476bdda0eef294af11c4f170ed934b7b362fe753f2e8851c8558672ac260a5ed515a43ade76346f1aea7d98139128ddc574d668d925a8187ca0fa5feef4d7ab0955bf0cc40050d72509b543c5be37649e6089446464f0eada429fe141b6e63f0b8caacb9945a6c06ccac21b3780fe8edc77af6e36bbabe45a417b14856277328616ec2a9f06d7f71eb59cdca1dbd88ca9323fc9354b2b920d9f4ab187dbfbe70420923001682ddf8fb5373a89220c090774e1e4894d5f45e429f3ee00aa135ac01077a643b4553eb8ee3e3257a33b53d76e884425c3824c744c9c80f3cac0bdcaebf9365938dd44f96d0b14ecc38573dfc50837e6d59dceccfcdc9b290866a6fa65034bd93666edb062eb7ca2ecbea0d237ecead074b9e802fa61b74e9e0972a73fd9f969f1d93f19b222efc645ec355cdae96272dbd2535ecba6ee604eebc892509a4894cd8597fbb460e1992357cdcfa0a97132944c4d245610001aab3ab28f12a07df0e2ae2a083377f689a5ff307f607732119c7f84f9cdb7d0e142bd6266680dc069213db3b6ff2247213be974ecdba8b4e9b36561377cb0126d121a3004fb11d4c62c97d55b48e8e9ce6905a65b2d86564a94ebb12f4b74dbbfec20f8d214268772f79ff13918021b68f59b39bec5ad59be310c4bf10edfd716eb1f9548f0aa8335cd643ae8fe5e37b36384cb56fa901bf8f01a2c9c548fe8fd5f9a08a250a7247eac6517f264de394bdc591590b9e1f9ce6bcb0d7497e1f25779724e83614ddd311b6ac026ea9deb42fdca6cd7a6915e04d7b5779a4815a038431265d2829ecf756a75d8bd5ddfd0b62fd74c38b4f1366b9db232c744fc396bfa8d79f812b9e40a4adecf519754ea8ee119e2161506ad2b12c60539be5c14e77cf20cff142c4572dac013270992f61ba00e846dfae31add4ac55ee906948f951e511901c2b4c37958394397671f95fbecf42a256d7940ac9f4d26b +expected_result = pass +expected_shared_secret = bd871684b3bec33b40a3b17c5600197f8f1a7d97e5be6dbd5b5a54f47797511d + +comment = Random ciphertext +private_key = c02015fe265db3068db2eb3da2e7159635ba7677116a28a452d47791aaa624c6c9477278eeea3ed2870bff75c27f15951627130d8ca40c4b80af038138b90e12214e5075c0b8e5ccc0a520f3774f00481bf7c5c845942be825b924c467756768a4d304c91721e91b8d0da95ba5d354eee70581bb743dec2408a6418e78afb912305f7b4e399bc92617592ce8810070c6146164fb06a6c01366b7e7cbf3575ff986664a129682dba7ff030f61651b0d12b303e3ab0e4a0b853770810093e9f1753493c52cd9a614755924962ebb303344e655be6556ecf46c943c7579178980412eab536b013c0a4a7a393e2cba6994202518ced63566cb58bc6142a832f03d1ec091b8ccc97df8800c0254ff612b4986a87fba08bc84a771243bb77121126bc4f11caa6a31a5d1e342cb752e7731b11205ab120845ba67504e734832ecca88d01852876504751eb79106a0e36f844a1e025144bc67ad5cf9ac7490b912d391b6a3ccb37210b2ca9cac9c5fe249aa989792b5a59d76e143c9a1b01b880a6952995c675de741359aa2c3236c54eac57d54453d20eb1d9c62217d511eff01bf53358fb77c1e1f89be273b3495008406059bd2079cff6391a78b87af491102770db6d2400dc3808e8bb2238399294c59d6643250b57b226366a59b57378197751929e53c7b40468bfd9572de4427b32c19c117b09564b0d7a8255237aef35487b1d31906fcc5f411b93abb120f7a08259c116252a3cfaba1a61897f2618839a447c6910c27570853a0c8eb97ad53c293b61134d56575d55919d743023114609b4631e452724d49071971217708bb38492686a1a6a75395ea62771adc50104548e6fc44d5cb81bd8488cac39db9b93b922acf5c74218f858c349b4f7bdc2bc623a9e6e5cdd5473c890779057cbf1f4000edb392cd331fd9e345fa960c1e5a683f494b5a4557a88913a45083ff24b543b35d8a18b4f2030d74ca7614c00da035c5a7ca97282842942a00c19bcf6ed9115bd621b9fc07de9583b9878a5b131a13e4549ea23873807065da2076e24068d1b3751aa1b864b7540637080801bbca2e78bc4e58792009283508a89867d0c5fbf588af7747a68705179c893e8412414209952a778e2b7b3f005d7f2c7ecd1983e06002bae100e304428dcb843ba9a9208648ea8272e1e85b40c222b9aa00c03a8d5002ba8303c85ed94e301753c4937ef9a62b0d127cc7eb8f03b1ac0be26218881ed3d136eb6a4d5b346eb21599fff3010626243e8856f788a2a8e3ab26808efdeb26b38667a10465658353526cbfc7b568c7bc370e247ead256d7856415f7ac7906672f786951c8a98978babba702d769b9fa657357bbc7fa67ca06dd57d41b2851a4a30a42910ef2180500c86c007351bc86e27333ab06623e3793bb4f2b41b39c53a75073ca7888117104a09ccb0d47eeaf228b1ab35ecdb041c0b96390a5f41d915132a1ebb78443b09a82dc092abd48c2a8a5cda804fef5a58f8c64fad31592e5ba376c366e5c1b7c22c169b28c8bcbbb04b473b41f61361b00046f431f52aaa88aabfc59ab4df0b132aa807178c8b529bbe5977b6604ca0d9fc182ce5a583169dd9aba50a657194a316ef451163859d24d807e3a6a4e3648f8b52500f68b292f92a944107dcc21eaeb85558204622203916e0482d8a040c2421f05339df3715265746bd2553211471f935ab399271ec59b3b3b357d60c4b7d9ccdb9e0023f50bfc299ae0dfbced2ac009c47b4a2f1667bcc10e46a53aab7adf6f2174a034f2c1b73ab114136348c66240d1b899e7725060121736b566c96fca8a9555b32262cc0e11aafcb801c4b09e6511f4827b94d464058b397e0a3c82b06536c1c623d419f6d8877f083004e35c532158d4692914b22313840b8a47b1e38318a22520536c8b0bedb455ae63a3379a96ccb5eeda973fc981e2572415ae17a8333843ac56b47793465008567d3b88c7ccae41186d656869f1a6299e76664b9cc6271c292dac2dcf9513954bc16db8c991a0876f53fab5cabe142012e989e393770c0611881ea8cc5d93b58eba21e462986c76bd00cbb96ab53fd6841214c366612a0806219d7c8c0f0230da9d19e3d215e4a149148d6a79a62480ec372966984d37a6a3d085acd9a625932628e2c925b763adfcb39a3638fdf733c8d322881bebd83b9fde65dfd975ee44c5209ebbc44824365875e614ef7d50625cc9f0022d49811580a41d28b2535423c209202429e66a12969c55fb3b793515c6a05781b8e161a4a92b71010f2fc9981d554a7213f1ebeda86ba +ciphertext = 61017980aabb0887581fbb3bd2b65a096ca6c2cb841dac8674caec898aec68d347c56182419978a0d849a772b48af66bf5cc257c1a018a273a220638853a39d25922b1b9e33c321d4ad09b86219b38135ccb6e052c2a3100ccf2d93541e37c1a43dd22ccc989b9df6af36e43d6c94590374c594e206b84db5db5ee9a970471b56c29193f6b2646dcdbbe86e1ce0dc6ffbfd3a0cdb5470e47c784bc3ea3622f70cf2b399c725bcb2c9d421660eac2084d7cc1ef9b5bff0ff7caf326f4aa26fab693dfd8600f54ab534ed251fd0fea70a849b684f8d0476bca35ea85c8d1447fd5194f12ef78dc795bf02eeb177c21acb0e71d76ad971abf29362abb11361c925802ac45992d068ab84a44d53607de8b5a9c1f0a67101dc0a2d8e06d42bdb06557334f597d9fc3232825138a33a0c7bfc9a300a67a394b1f6db98d0cd272192cccc769d7a7ea25d430c5511c3facfb504d827bbaf5cac077849ce6d4924e9864d10b100b4c836110161c844eeb605a50b25aad18174b100f3deb6b341bf5b2ac73ffc7838acee35cbc3015bdcfddd745f9313ec4316ee51b8122f7f9054d97a500a68f5612a5f9843a99d190f2b5def30f8f92f147dc6daf8a877fbdfcf600108d435158433aacd3c714f5f145f25ccf0cb223bb0b92b4d83c614bcd53d84f4b8efc352b3a335734c6b7606dd31b491a06af24b71090d30b87b38edaae8114ea6c4db03cdabc23cea51ec262de60f83845a66be10c560dbfd87f6462e9bde7905757aa55fc60a3881a7f9c5dcc608c74ade7c4c835c12bc7c118e7c0ada5fa852e4d7f98163bd10025fa4eaaddd30134f0fe6c86f2bad6cf76d8375b0b4a00e521e7191217ac2f90da1bd5205655ec0821b343e9564e99a2a52df97c15ec0d4eb6333716d37bb1e0ad14dde911b879b5156053328a7cdaead088b913be6343cce1ccc20f1feed250e49eeee36076d2a641a600133f19183bf791b7f984d8212293dba3070caffe5046c4e16624af4424133a9ac99ac06c3bba6cc287fe316c7b605e054545c79a4ab95a70d2e418625e981794ad12e6cea17a16dd9b770e36d848 +expected_result = pass +expected_shared_secret = 07e51233dab929e3e32acb66739b7165653c8e19c00bf4459594d2d71fa35193 + +comment = Random ciphertext +private_key = 44a445c8723512426734cc07308556d6dca278f8c1ceb3130114bc7bc2768b744eeb947b5b43372aa33dea88ac0c48bb2f9ca9f89baf2d3958ed27214213a02272484ff83add65c96bc93bdfd3911af6cb7dd09c74015925e35b58b7045019b7518b7417c71cd8e05475314e0a2c31b0611728ca9f50646afb7618dde8875897477b6447a595c3a6d0b050a304db9067656a6fc3f9c5d609c344e335e58c5eff94b7091360b3dc2b9acc52d8f715588a06b4591a27b432864bb16d658de0b7a3c229a264eb9c138b27b8a51d04db9ecd937c231010fde408de8c612ca5b323222d78c2b81a5184dd938aaf4a6fed0a01681c38af2512be8a41ee92bcddc34b9c051c7c419a0a22895940a78fdb64f57181b0826e517c937dba3870906a575146c7d86b10acbccff466747b782cfb2e42ebac839a65a8baa1eb310a77e4cde46c3b82b4ca2880aa00cabc8ae81f2412c41c382d8f79a5ae4529cb01c865f74fb2786cde721ac6f40120440964928437305c50fc20a09083e14961f8fa35ae98a815bb9d158a97412a0d37413424a91a4b6b2b7933576cd277c4a2be187619cdfcaf38c14e94f272a29cbe83a7474d3894e1981a494161d1bbcfc936c67b09ba81565fb8c00ce150b49124ce2af823fdd24c55b34f84d877e8b141e016015eac84cdf61bd1722a7030852e2b43c40018a8106cf037a112db34e14a179bc39cf16b3e36586fedb684dbe80a8fb696a497aa9aa2a1b1834947939075a580888b8dec3acc6ab133f14b61c6f91be4c10644343f74f68a041654904013b9647f84d7b28a064d3c58c57d778a3779c35f2960a3f6671f320b512a4e01975680dbae78a120a06b9d6aa31b04551abaa9377aa860af791343e3384d474f84267bf78a81496c404a795aab1bb399257cd1720a24db9e63e75e00577b8c0172c0e7a6d9f1caa81504000b30b97a7c045009eec06744c4a749f27dc4d89b8fd2b27a276601d2a6b9d2b88ee881b51916f262477168421df0450cb0212f1b49eaf5086e414770f72053910fd1795a6ef97e9773b56e06431df475f8e85806e3b5bb9cb232a5a1bfd23172cbb84912923d8cb72a3b8636ba990a94b8c16769a9dc86c652c755260c1b35585657a6daba2883eb241208181f790ce001b943c420f3ea614e74c1e8eb60c8707ae734345ec55e94b1cef31689c9619a37bb71a37a4ccb3634d0e676c2073234cb0e02a7013a008f7819258ea63737808a1cc976d349ae42e36da9eb9f3222b1487290e917204e4814df1392d638895fc2901df0af1a852c2b092d0d24b147715400d1a950b21627f0c78652962de4276370940a9576c9722302924252b85ae5198a39a8b7680334a14ab5bc9c3be6691bee7084f41574954902365ab27a38706553920d877808cb964c42c60f3564f159b2d5a3c5f4ec73460cab2a9a29dbc0720fabbe2d887720c51950372d88e4abd3498bdc9537238c2f9d5704a9c3bb15e03c80a7ca49e877f0e51bd6c1bacc02874d65cccd974ef5398d2cb739a6152741b5b0141ac97a97ab4eacb4e191c786f09251e56a3a71637ba779591819bbc6457e5a13cea2434a138bf7c57f88e52ee812502341b95bc976afd70377b61874c8985b5b55bb41554b0aaeac61b5bc2906ff4307d58317c91c945f233cb8d05889577ee659320c304626e184d03481a2e16388d92650ea5376744084c456ab75985ec78b2ce58ea6d34a26630a19639dc8d9102806a06fa88eceb1876f4410f5878161e0636f7ac5a7d9b961027a6cfc065da89e1b82a8ed6c4fe59c573e568f7c7bcdb205309da962d6bccd8cbb36d51c6fb7640e48063fcb18c79f24aae4dc08df67b381c54593206ff8ba7468b005bad358e2173428f2bbc13b65acc88e6711a71b167fe2aa51e7bc683f1ca964d3be83d069d5d51d47340318a93a8719175278bed1b290db7b530af23058b18b9aa98b5a756f6a32225a537b971920ef594eada396eafb2c26b57213099e4b4a14d131b44792106f2c6fe7e22154bbc14715c6dbccbea1994cb0d0996f63cdb4600f9c8109f5ea8eacf2251611004e182a1a2cb2088ac2316495b2132430c98acce490e253349b8bc4b0616f9b2767919a16c5f19402e326b9b0cf8a93a76bbc72cea182b5414ab6ec5e9414ceae5932c9423c97937397973baf358eb62ce977f875c8b5a45cd06cfe58e6d484267ef2726519bb1db23ad59addbb55ded179ed61120ed640c38fd6cd8a6cd3001c7495cd83731dc6c29ab46331c9e408689301e2a0fa51979f28bbce79f8021a +ciphertext = f4dbf9896a9fee0600f12db6ff41e66168802f982455858134324c0eebcdc063ff28934ee0ac55fda164c7dea0dd3c1f88c63449cf8195addc23ecd68e10ad40a0097b84ee474f0729947dcd1c276e00fc60be7d843d1f4bfa4a5ec5c797f9ee32bc141038c8c47ab7bf1e1dfb7255759bd0fcc34226c2c8ac2cb3f2e482e6988ee3ab10fc28a63938c1469d37388d11aaf52180e62de20b889b09821aa9bfeafe05c27ca4c3382e95d7d019b025d2307b09ca6eb6ed69351a367f5ff20d85cb1b393bb8e7c191436acc58a758c8e400a89c054336e8708c75d6750b6c3ca7b6caaa9dd9a1afb94df70598a3a5259c067e48bc8bdf5e2eb1d0f5bdf99714cf58461c1b2a7c595df5e2858177a4bb59671eb68228452bd3d99c5b5e55e96f1b64ba65096edca3be05a3970b518eab8b1c1cc80ed3beeed2419853b462cc61839f55ca201bbdd925b5710a841fd344942bb8e1e9096fdb34726f7735f7f2ad60720127740643e69201f7d06445ef58c430260983fb8cf03199e357303d113d7edef63b5d0143394dba22e40b79e5bb7e27c1017dccb6239fa1558697c86f11e8edd3bc3e1554943218bf6464c62f00cfd1acff2c41eb0b4805c900cdc003ab1cc91a30c4eb76ba77ae548d2287f5ee67cd56bab37add4968fc0e533f49eaa64fd45c1ee937c7216cc7d9cde627dc743b3eab49e577d97050479bee45576f8b59c189dc73cf8bf6811d2b0d814cddcc721118aafd0969c70816c606732d6d60e679ee7bfb21e9673f3ce49d630db02f97fc9a4b1615779a31994cbb873e03d96e89d6d91e0945108a86be6e56c9d694244662eb2fef48a1adf3016261a50295d9a7e4c6eb180ec79d6b068e7eaac2b860bc07291466fa5ca1af9cabb3865c9058a30cc21457964423ea3922fccf408960df41a4195dc6fb2f0a92d8810e4879d5ec3360d4cd719417fa7b1b1eb8b3bdb27c634c8019b10e6da18cd1a1bdf19f06b1ff6f0b02af3ef01f31decd46828cb893dbe349efb9ac08dea8d786dd133a34a08cbec7a6877b0211ad6fbffe9c54d136068928c4eca619593f7854dae47d33b3 +expected_result = pass +expected_shared_secret = 5196bae396cf5e8143aa3e7f76afbacbd2e19447f04bbcddf61e9a6535c02a8d + +comment = Random ciphertext +private_key = 5195a3d75943884c5b76b21e453323353585de0a58f2d671d7dc9e02958eca3809f94079b030b1dcf38730dc391195aa15e0130a3b31bb81b02f2a53cf6548c82c8f98288b26ab1f5b01c855a534cd78622bc3a21de96e35cb419ee970ba6ca4ac385dba658b349131d456cd87eb69caabacd0b90117300a7bb852e74a0cf2cc7ca422244feb7624e62715633f179bb5acd679f787a811b34f0fa7a704ebc913f964c8b08e148a4dfad5a81ca22c158215ff6cbe5f131384788cab073d10231b938b9ecf146ab1a18f33fc49d28385f8169762f4180d5865dc77054152a0a92b968088bf5c600646b0a08302d0d95974ad722909ac2fdf6babbfc7bab05a3c4fc638e7134c16185aee51709b798927b22e9b047005e97dd3a84baedc03f5442bc111376c04033039441c707a99cb353e2b49176cc62ae5bc45fb7a67e5c264e94f0358675fe65dd66ccce5e6af9bd1661a51a99ab8b977a8533e14b73a059fbec5a75689133a7cb390a71f3628acca7b005142332bc1ae436970ad77a4621b003819ab7f85ab14709e05d660e98c609477138fa49696eb645153393d971170ca4dc3ea15b430153fa6cd44b0762ae32d38e4907e546f233cb3d5b767bca155416a366aa338d3a3355e0820eed0930cc33bea222efe7740cde85946ec510e1321e01bca47dc980d2ab182ac32c29868ed02958240bb9c98006ef6c5ec2a0d45ebc2da0bc24fd0383313bd28708948a85ccc437f464696853c648f9024582458d1b9c35be3b102d628b9a1428832563155845f8241fe44b61f258a44479276ccce404056f2603863b4434db88d3496937f1956c0aace3e124e1376babf415a29345c6f507ec856a0b1c2540c354b05a6950613249cf610abea5f02100fbd17a4fb04c7b64369da981ab8a44b49483357fa7389d9ab85d726992066e1e265a9698094991a668c67eae8bd20b846c7584aed436f52b6b90ce01057e940fbf55fd97a4cb6957a95e453253b5f52e644b569c54215a62f4b5872784f2a92850ce318e274a03925102a43128e784fb2547452f6228daca002b046a1f21fd4d6c2cb68a05b26a29a409e34657c8dcc447db21929fc930e5b81c243a461ec6afaa9062f1b803a5a4393c7c6448023a0b310fbb363638855cbac934d1195e8a21134480737d7272fdc0620d591d6207ffba1bf81707c45526d8d60a77d0a19755875f7296660b93e5d924059e9824760981407a20c0c92c4e3af1108a40fe7799d9ab364e66959c1a7947682864a1fcd2ca1d7f177b0b59648a480b352669d569095cc94b6fa4cd36c51b266c71eb55ab079bb05482ef9505925b63439dbbc344290476022064550fc3b81b466acc62b448c38c740d4b189d54457c44018f117e0a7ba34c07646fcb121f3cdb24c3c1d674d504cc77898b2e2a61d0be225c5c4b5802472d050392d64ba48d441f1440773d1930113201b2aa380cc33eb0210717c50e02523da1868d26b48bf33437d0a7f8a41891b6199416381fe4ab8cd339cea2027d6a7804e919a3cb340143b7d66c4bebf628b60150867f67b11b9432e728e4903670c91a0385b174f2b45b0f3714a1c8965782958b03f7b20c6245b4b5fa9a122357ac0f5a7f0c114494a6d30826d9d6b965925c24d451398907765fbcb8b6902ea051cafda8089f113ecab0949f7295bf7366a89955b9cac108cac46c7153095313f36817af78aaaa7bc4ca974aa42abae354ae3fa947d5b1bdcca1955fc2f3808930ea2ce20e285f872ac4e80245d307893785996243c0ac64b07a79737672fabe7538eeb288ee45ff337b5bb4bb6cda50280c78203901c9edcc3131b29e9eb6609779a938519031155d409c9fce071a6984144510726b54f3c3b49ed4cce9b888bb943b7005bc0ccdc20b3637f1af06d2e81171d969e83f759ca94bd3c2ab13d980381455dcf2c1a42401a26ca972ff072436939fd794b9785aa3246a171580a519b01c5f2b97ca90a1e36811c524730430f4a2028cce1a98f0b4438f6b86f8aa0f6731a3fa4ad61679cbdf75f78137987f3a955b12e675a9e07bcbc766534642a3e6b97479eb792f1383c56d56eac75b035e1a56a04880ad7522f730b483ca8b7e9840ae16366957463211bf221a654b102f0ba43f8643d6e320bd98b25f9e79ceaaccb1923215ccfb4ce46334cc78b3a74b4a271e6c62543f088633228b281ec1550df3a10d1af795def74fef23e23f5727ca03e259bcfa19dcb8ccff348ecab0a6c44537dfdbc115fa3d8af50af04dcdc9e57c2fb00ac306c25f3be7011c345 +ciphertext = 930eeaeeecc782223fdd1fe47e5177c5a6ab4a00113609f7e4599a3dc07812bcd1bb2c2dcd4c7f9df58b3900f8244efdcd48e2274689cc6845763ffbdbaebe18645e5779a692ab69c5d820c85f1bb3e6d442f7a4013db6d747c5764a03a273983bdd761c7b6d037a38ac513ff35e5d3671f0570f5fa050a48805312137262840365a4b8f5aa6783d259b77de31c8704a2e767218daa83d8c925bf8bab57ff70177bb899f08278383d5d7f8dbb4c2b40e44f63e497fd81d84272a0f4a78d757ac6c0ac774f815655fa98fa48653fe67bcc0762229b25c4d37641597561e8495797c60db6191e9554c37e1642fac5cd3be0c0575ece759f1efbc523ffafd54d3043f637339fa0a489d351b6cce5f103af22c998d30134b16f1a67d27e644aaf0da544ec14e208731a82f7dc4b671b743e7b5d556cd1bbf6342bdbee495359cfc445d8a4603ba7db668f53cc169b03551c8a14cd1734b96c12d2b889a6e4db0431ed2a20a6a477ca5e9cf266e2fb1374bffe1d759d4bb95d1390cb6c7db2c83a13189936470cc440fdc030b6c77a5d6ffec8e604e9ef9955a9f2f0cd865d8f0d14e912c3a2ae580bb5f4ebcac73ae60dfea509d484fb40d8fa57721701a3c0d52dfb8fc1a81db56e9edb615bcd20ce37681124c36d7413935fdea4b1866292da3717d2499f43675b91e21338fafa23ec1db723a974ffd1ae34cbb5d5339df784974f6f1e3c2e92b5021b1cb38764168221d1a528c12856fe8c236501a30c8d0803a01fc6770e6cd70c6b0c2c9bef01d85b0188a7551d97064efc9c85b3306c833ea1d4e30bd9ed135a299c5c810f2993cb8a0e017537c2b23b19fab21687243852a76ec74fc2142b7682d36aff17a47a211c961215a79575fc09915a83e63ff364825ab108155445558a0edbde4abe0ec01ea8ddb0880086c815bb04a84b3e1218ad3a68b95d3969d0f29f032a07831b446298b810d27960b67ff0f4969392a25fe5a2fd467a308099cdcf4b0dc06292cd66fd8f21be64639e97c8d3f9692eb69b8871c6cecc5a9dfe233fa8d004bac95f69fe8fd4180b3f520f90ae1215d81cc2c +expected_result = pass +expected_shared_secret = 51e67aaa208e2071fccc2f5ea1d8d039837b80d11532255a8d65a916e5eee9a2 + +comment = Random ciphertext +private_key = e147ca612cb7d840c46ff83e3ca288438959af083588900bc5f2aa172794d13017348595df81687ca80625b76375fba3f601c2f17061e6b2b791c0805bfc2398974104927cca62142ab17e4bb5bf2ee698ae1967d121ce8ea929fb0a24979572b58c61f70b60f1e9b14feb5ea2a33c1d646bed446670f4956db403421ca16c9b330413511ba1960fc6259e67cd89bb780faa5f442a7ed27117d6c03351e6358191cad61695c9680dc06a63a15846e4c71f607a972717428dd87cca1406a5784194c6480351742916892428cb74c4894bc68a5e37a02e8b78118830f1111f180825a4a568680bc76dc23181e450dc010c246caa6e7a85d11a422e9963835864cc93084b2704988b09a90811ec5a626fd2973fd79dd0080dc1657cc3845dd7c10a79c1b56b49a01a255ffd8aa9db467869c7772a3a18d9d5220ea27812787e0bb017935badefc272c5757a56309f6cf3969df6c035800c8c341d545094c51a6e9b361ae9ab152c678d86c74335810bb201c65bf0a36479190e8a6905128170c531999b3f7c5b92c34cc84ffbb0725337f88aa3bba39abdd34fcdaba61f897549b98d88d21a3d740d595706c0247a89cb4feea86e9376bac7fc7f2ba91fb089b4f0866dc872b057fb15601190493375ef8623573b6e504caa3b9711e67839ecd56b8810a5c6fc1bded0379b796554bcca39014cde181dc7b1cdccb05fcc16840980ce42330ce9414bbfb18be6e97bc3f33c79e235c4b54fc466a7537bc9d5133a56934c18052056b1ba6af58a41c5b71553779f498672138d5ff283e7a2b2ea126f9f78939a0c2f56039e2f0ac1ce18b6045b404bcb4aef4350c225addf81cb89a4abf6992f9cf61f6d1761697617a0a838e93c853c061ec40412d77b72ffd3a5a4f8c89d3ac5acc60d3f5872a1b77a45b33b57d2a0bdb22cfbf3c4ea84bc3cf68de0e0a670caa486f668abf77b46a1b491b3b9f1748194e36dffc2b52e135097b835706c045f22cbba890425e18bc6180ba7807a94781336f78b2117c154d678b07c02f6ab3ce4b712da6822b4512e2ce72edcfa4436a7bf86928177fa58b2e0202fcb807df21de89587c635841fc4bca170a10f434c57c4341bfa1d64557dfef8c14217c5e5ba5942ac74deaba98c8638c401bd17c7cb9aecc0927968834ccd85b198209c0f2df27715696eb652afe796aa6a29507f80138f0622e4725f444bc9640436797b4700439a22ca4323b85d9416cb9bd3027562150faa463a087d2f993cbe42205f85a241f633c8568513e97cc644cd7842193a299e9427737e38c24c2caa81587081b79c58e8cd8452c18889b581e483ed1cb56110b23a1ca8fb55ce80b94b604283643a0df02c8bdda840dfeb02764a541e07b44c372a9be75429b560079c5a241cb7b2396a524485d3777f6f97c8dd69052a204c5686497d317f6c6bc6a4f74056db70a38c3e7ec8c6ab203e07b352a3905f1dd2c4478570b9596b5139c094c8874178cf5ae867f942834dd248bff19135940f375007c8606122e8031f88613c8a506ea3c16f228b414b8cec27497b407331c97cf4a08d49794e3a5009166c4b5511221eb4aea29c3bd49513817c7f96929d1f1c97263cc04156524c6b26afab191fab7f67a87da4d5cf3044954e71a0f5c348f0d794a186a8591cc290a06ab11b293f1bcc405a3b6c5c2ba6820bc8b93fb497631ff05e8dc992d59b8255cc4406a2a4886143ff6231897897d482405db6b5ca943398a1c8c3958421f401dca97cd1b7b4e0b1498c4b21147c11b15b995682ac7038c8c2c13b3014145882a0aa061adde8bcc2967a832b7f023c57c092cdc10088b7e4c9b61401f958c219323d5c539fa5ac88c9fc9303cb15a6643bbae8145a00c706b664a4ea875cd5bfd1a0a442e99a2b5834880a172dd58026920656773584a4a20de275f791075f771a5e03691b01aa8df53573f868be955ca6f04ec53024d33c59d14155b2f0348c78414e61bd5337a1854b63b6794aa0277d7d972a976cbd609b29e4c82ea204b7d2c43c85cb47d338c1001785131340f677336b041a41964e937a6e4a18a94fc1283496c56b960913c62efa450002238499c16316635dba0a12c1b8263861c683d442ad8cb91e03ba22b70382aa60121c4fc6e191e6593cda124a22219ec996e3b213c6a46e5cfd19edfc67e23ee96fce506288ea84a65f733c7a32ab3c23636fd3c1fbd64c179d3b54d7db574156b0b3c31d73042010f8e3ba007568df49334c4e6830c2307ca693acb86c4a97364bb461ff0aded410c15e149172c058 +ciphertext = 432ae750d802562ef7e59a80a29ae40a378dd3e8dc6879a0257f9bc4aec23047c57ecb3a4c9fb8212ce05fdec24038da610bbffe43b769f5eea60346e173846e9502bfd3d27116808c7be45e1ee55fd24fd0a9d967c74db62323a498231ebbb5bc5e5edc8334f8cb2c8178dc8b630fae3288bb585ce1e1ecd020148d8ed10f84f7b8cc237691af895b980e74e85f5948430a89ff922ae8c28b90ecbd124af32b521e0f53521bd80d6f8a4e5ef84347e5fe4f7b45c5866ce57d618b0cd8d413ab2605d29f18bec33d1dba91c4bde5942b7afb47d36f2cf915f37459c957f914b2d772ecbf56bb7f7794cd519b781b9795f2a1df201089468da899834196ab633175f562f894287b9679e93669f459117c819b5336799b47cfec3722173eb5593afa5510ead8ce60939766cfc344ce013b1064c326453e59be8df388d957d622868d2400c4b28eeadb339291009e259c316df6b34311972ca5308bcfaa2e2461262dbff7ef4b70a9a3d8c7bdb31a875effea3446ed7ab19fff1035256794a81106efd4f6f2f550b61afeb60a2316111996af6739c6ee095a53bb6f9e7695db60949f782ef6459788533fda64628462c97bbb59384cb69492e0ae2a01428d976427520f48eb28bd2edbc388bb38c572cb14998733711b9691061c8693253ca56ddeccb3feca6b734288cf64f980a86b33b8edf686cae0bf5a930fb577761d551b805e9e98bddaa0f9f22bf7e7b0de48b1616f3cb8384bb74437c3fddec8d68c8fec8bbb298ac1fe66001867d8901a71fa472511cc116c32efb8c68a7234a6aa5872a7807c18f5fd7e7390d62056b49b6917b6e03d652a56d4bb59bc8f85d565a808ee0796a523566c41a664f322b3c4fa41e8e39a28e7143ece43154b516198fdad7b81f2e902395c7594f8dbfdea2efba1f2f07fc397a6daea6a42e163705335a25098b3dc56fd36937d6b8d14d2a2945e69eb36d806be481ad660cf0b7c7f54f9224d9ae9057eb03054014f78a601aaad9a6344351f1313784a79e9f30096fedff4bc55182a35229d2cfccfcca57b23e10acf16f5d2c6f0b434fc229071ee6a48 +expected_result = pass +expected_shared_secret = 41722eff224d73ea4eea4a10d49590c11f593e2304d41d4e63f29f27d2ab2111 + +comment = Random ciphertext +private_key = 6d02176859ac8b877f25b6ae40aba8303a1216965059641c5e9c0e045103ca427d2ca81005b8c52bd09a3c600f7d0ac093b158e448829a735579d4ac05a80f76413f9da99d1f5abe14303d602819ff837ab70b06a474a579d81e65dc8155c44945b07cb74590161556ac377c1dab04bb15bdf39c317d57495853960f857890a83e7f77126491621686ce5d53ba314392a0120b0c291cfd001f0d44a33175966e72351ac23f0b0390d0158e8251c9f64a54e852bc26f6416bb47cfd8969db2516a661132bd28cc3aa5086c9bb10947fc40a6fc9c1851fe5878ef8164f4b616aa7740087c5c490840381c58ca568d098611b776f2a6894bbcb93aa18cfbed579baa22a9af1abd9ccaadfe200cfdb46f0a8c306801be1fb9640408f94f8188a1169b9b88e35c11b3ceca8940c447c668b8df58609567441dc095d0ca988528f9776bc658a0c8f9b550ff4877ac16dbaabc7d473adfe775aa080863d46c8ea8aad83ab9faed60dc1f76ebd2310ba710108cc230675a057a759a10a020dd224af777defd706aaf1b14de30e299506acd96c5579b850bba3c5388d36308d34c35eb5b0662b0c2824a662a3ac51dbf8b15e39a927856882b9240c1013966b597aaaaf0a5744a0f019e8b911a4325e9ab1ae64a5203fcc10ad6c9136924c261a27dab69a355347d90aa683382af4a914e171ad8d997fd5cca3823c9b3a6499695c2a7c2893fb8a19e13a95ccea072a71c38a247c382c709c843954c17c30997bdac34569c39df529158f240a328955f9d82d1ff6a87e027b31755044db03b897ae80c34e6a07388486ac602aab44713d58855578d1c8192989bb4c67adc6829540b3902002fe8443f8e30a62864d9724319c4838f90391fab70877f3797a3c8ed32a652a2a7a26c78df996bfdb157446072172b1cc1da7b496875126d55f1cb5cd3b44a4f45600f021c588e4ccaf16068952a69d351ca39c5b7ad3b49c82a579f40f6f54acbbe60b6d79212c97945aa0c289e285b2899ae7b12fd7a7c4a3c79e63192f21bc5027299d98e37dd9a5485a16ce6b05a7af63cac69a8fc6115ef34c804d72b58a46199c27151921a5f962b221959eae63c6ca14b991fbb87a358dab1c3988d33d1ae0532712ac7944b719aa27f4c1143202be3cfb9d2624720d83a63a150186b58bdf835027cb20e2d62b5e63255a06a947862f0aa403990b62bd225d556a83961163ecc3260d133b2c40a21ad25850332f17a9b9a2fb057e379450a36b4a1219e61c19bdccb27c4373df01b3a68440bc6a4139f145ed621f614a4706cb90bb60c7dabc108373a800206a5e662bcbd94ab896700623076aa8ae68b2c1852847b0411508f71e4e863e25752650d653e08237d59705ea031737c72346f66e688c1c29199a0db4788f1cba9d6b810c964eb97b254b154f7de570005048cb29412f2c6f7f8b5f79483f5caa83062c8bd99b7f158164ae75cd85853798b4cf2a6282d8da47a744c33e90c453e187484815db360446d565682c844e2c193c3b18204100ee5349c8e0079573cec4554849970d5909599c141f8db236eff43b9f4a1ea3765652d01548e6c24a5a78351640923b1afbc5aa2594a8961696d5565764d8b59571545af3cba9c89a9189558d50be7646b393f12314729f4a2b5394b98430898cfe13cb54d0c2f51a5932581e8c1b9ac0877071709aa9dc50b39b641400c0f2c374d56499c336502c92725732c36328bf6091a487c5231ab2009c630936a7b03b1552ee525d63bb71c5396056a2227fe4782bc42156ea8eeee8c21a39ccaa54920679908cb3c0c57544c79397d5402865b9b9c2534957366bf910273419566286071d3a6e0ccb00330a93968a77426b924ca5a06a01cadc7231ba588867207f3b1524991665adc70f600b2cf617169f35bc45ea47833ba5a22cb410483a8c9672535275fc3c98dc36448598222e5516b50c30e4e3977d3b681840275afb15f30a1f18dba613841c9cf923ecb761a01239fa3ca5bc7105c058b67c8c6fd5d5b878c60823db0609486abcb9a635999ada8b88097c5dad281b3fd90bce022360d96e79c7ba8d5b120745142798bf40b964a7f422d335b585c652ac08584d5764a7d7c8215559c31744f98989a3e47b01e55fa9f2c1f691a0e6d5a903ea821cb9b91950e95ab5503862296c12b36e17e66008dcdc599d60a64b6b81cb16ce170578bb48155e75d8b3a30bd385e26c146c90002d06404dd913bf1c27de24263656b8357e2e9c65a23e4290899a225fdf336bfd3b109de17d83537c11ada66774ff5f +ciphertext = 18ad8545cae4f0aa7165673950bc75ec1e0130db194d401a3d2d689a3cafb467168eb4748579e1a6f05c08b58b7a3f2ac9af3eb4590450311d8f5bef6edb8641ae0cb0064f7e9c435f654d67cab8a06268d3ba0e03b8005e561c9027d456fc14c6e7bed60d965889198c6b13024945da8f6c533f8eedc8a5e64b8e18221ca2127317008e42880666054f02e1c850ad83bfb97ffa7c37d754b161cfbad9ac255351661216d45d03a3df8321d23b9df059d58d833987bc440f665d88361d73c5a68ecdd29ff6c008d9955c746e85c377a3df33cc758990928dc76b9c71abfb919eb631578c02700c0dc79e8eada63520177466981d206243542830387f5046ea110bfdf6763bd44ca5ba4400b31b8306163d3ae871ebc55208c42c949edb7c864ac62655529e946496926357223335232edcef25692aeacd776a1096d6eaef3c3a374ef83d9808bcf7468f418ac94b6c3a5405a3dbfbe362b96b769f6ea55b871e5adeb2f5eb0194f023ff44b50de25c1273d3b64db3801724c6eb78e6b8d82d4dc1eb69e3c20e4cc8b560e8009fb9358da663cd2a7e7a3f781660fc6b816d1edeca31b5ef06536a1ad0325d5aae11571eeff444ad7e97fb9629aa3c1239439d2e4946d5350b45ab00480c6786ed5bbff7c6e1bd1c59947bf6e118b0860b0a91e25a5e9d256a42b35af6d64fea6a3e09f097a1b790c811f7869f0353403e89a5460d7ff5735983d8b845728fd57a043f29dd4444b44d95c3b1d637066e73d084e4f2ba5164b090eab5a6397ec66f4be479dabae283fd1e1a523f027ee126981b65725cb1e1ba7658c8290fd05017aca8900bd00ec7e873050a6a018ed88e48daaa4131f0b344caa4a4b667da734d3c2f5f2b9cbbbfb35b81d9f0eb841ac8f2a230ceee43b98b68094ab2efc8237e7c84e0279c939396cc13925fe6cee2406e5b654bbf48c25aa8b00be2f9aa1913862303a23708ba69b32713fd80e5110e2127ff54e49bd5858384e1934a5871179602ae2c8122418e2f9fb7b0f716a22730ba165de0459dcaf372133686ac9d7146cf8160268a6de9425af8bab6ebbd36ef6241 +expected_result = pass +expected_shared_secret = 2c4e2b49df979d46fb86ef6178bb43c7286b7f645c5b5c86e1cf3b3c22163e8a + +comment = Random ciphertext +private_key = dd0009260c1960f6161449c320c60eb3898b813548f8d3214cc624db3036eb919e19c96ffc834833a2aa113a73e1f22c41b85ae11a5383b89eef55083ec9a12302ba0a1465b13b77599a45a8c56af4e6c297197cd738b26f7a69747aae89fb6dc800776c174ebc17c33d6a191b601a1a8c40adc29f6758b061146eef87ba79257967233e256ba352606e96d900d5912068041f158b1adcc84ed2e68b762b1ca5b3534de701bde93599718aaecb4bcd323aa6459ea110928235ac52d5c4ea528aba73a81da7cd26c9369469200f7a32ce540a086c48aa2677b39b7f4f74cd7c97cf1771c0d904941fc99d45d254c21b68d2a4ab8e90ca2183a17b23701e9b9e933a22c53c8ca303c79883cb701440db954bff0289f8c4cb81b10d243b54242abe2910444b5536fc69aec4fc6ae74bb1a9b2c07890bf15c9cabed533d4e48d90e245bcdccd9918c8dad90d7b5069d93abd7687c34a919ab1d51bca6baebb6084ef202d6fcc73c75846331810f2d3b018a4409ec45c6bbb368dda505c51a695109ecada3ee560ccf478710cfb250e80bac8db5a04a85b16b66d5efc7e7f0b47c9593f932b181eb6c75bb48760d94d21f4b49f4b84cfdb6c26341aa690271d7b0bddac88881849cd1b0a29c40dad908ed96c2359f4b3d3baa89602a2af9686d702584af47365830590fb2be087473e1a5aa0d184f4a9686c9098111822043ab4ea1c0d4427c9dd39213626a902398d9ee91105e0141ca14f9882aa24874d992299f94448a9b5098d3b647f3b389e9b1355a462646b8a0a5a94eb760a2b0c44655b0ad4f11b2e127bf6e22c73517c5dd089deeb08eec785bb721a9cf8be0730a8da11cef75886a954a6a0ea1b3729680b2261deb73ee6692a2aa32d300334a457b87f3a68e6c3b10ceb06c679bfd3e75c5d76270e820b78a197fa129f67b3952186863ecca05fa93e27e1687288682dbb1c2f83cd6830763a85afe15b4002497bcacb18c2525f10974886013ad94139d7685f3bb0b998ca108e016ccb9330fddbb89fcaab4b285d94b01cfb8b9444516c77932918289aa3a00b8d5c1ca8fb4be9bc024e37621973ba80b28e7322ad47664584d23a7eb4b0ff5013d2116a8b34a0e9678fe17c4508304590289243497bf77a520d9b0e7e597e2c3624c98c3ecc8801fe850c991b4faf845da3eb2396a055557c78d0a881dda63c617090097848510055fb827da48b029a541df0c09ae6ebc182924bd8c07858a018e5d862956892290a4480e4880ba73b70460e2246c718b3ac4358487de0329d9923ee382e3f9c3ee2b4c7aa966da3c86eb5a39d9c398807a65f4bc44d14fb245cb18654c83664c7a6a0084046141107c424744b9097013730e690ad57bc7bb8237ab74120c1a2dd1823d7ac7e69ba21b6b5cf715b9382292ea26c6e0c865cabeb1b515a8d9ea7a28f284a8ab7c64051199b3673413850f359194300c783d4af57ba842589804536a8f6701021a396a36590d4cb52b6ba4a93bc6479e8a646229364ec2315597f2df8586dc686164366a752bcfa747242da288b7338601a30ad6418205b960a552e4b5067a8225263b456be65cc2aac9ef3bc2c2d1a5510a91456e07a03a80323f1aee9a3272aea8bd85334ba14cae5a23676174342594313e4b558ca1975f456411c7169b05d169b3e3422b5116032c4d797aedb82dad52a265a6249f23cbe5b05d7fa7bfc9cab06b11a2b645f29724c38b23ee1004ea8a97cc5d062464cb173ca8e22a4c68c69c5a001a2c7d37acd59b1265522f2870f6f3200cd0ab9f9d07f26e66d5f1a71c3232661f72a9147a7702c6685101252086c4f6b371a23385042769c33b5843c303f0968f5398edc0b9122088d04bc2cb429bf4dc2aa85b19542b5c4b0f36e56460a1822a4e60506a9c2b6d081b377276e51200879fab405693dbb3271e63633b5061e61aabce1354a15e33a6bf442c71a7a3b54499e252caa585d30ec3179d53f26dcb652e01933b2349a443777122f2dd0b8fcc99e1159bb75e7c51d611df8f12808cbb48af94daf8417d88cb56843c799816878127348c017af93842c8a5b3067bfe3ea2a4725aa0cd44a667655531208228442167130484083dd43b5463636224ac3fbf022c8f06192310cf3d33ad1c4cbefcc184826b1962323d1cf25e80b6ea09efcec2c053df04b6c6e1fa89648ce3ec63a978a8011d421eb1cba03ac8313227a89520a1d9b95041af2ce139d2c1b0e3c8a086ef00fd8933f1c79072120f8cc37fe7f18c60bdedc436a8cf65ded543e8755585b5f6dc1a65f +ciphertext = 0f7eff8713a47942019c0a91f723f8eac45fe264a735ab0643dd1f7df53a8d90fd7cf521e6533745b3cc8da00e42a567bf8465bf5e6e3e0595406de0dd617841c548a64ce7f37de26117384ab2dbdcb7a31087fbb5781a8f60e2075cbc4627edf8f3726fd8befd369e4b21e3cae76c26f1b223205710a9d00a753eeb132559c0880d0e5e0108159ae3d4bf9d4bc83a7ac444f87a11d994eb38b876ae01aacaa9b5ef4690d407b770d0dce6e63cc8f4fb9754db85f0810ea5969ae008bd40dfabd399c865c008bb19f0dc406cf118ae09b0a568330536106c30f7b8c7fc0f921d3d4731de00cc030d85c522b11c966fcb8747769091ed6a62e5174a8676f36cfdee9cf9abbfc1fd08a8584e10510ed72be3919a56878f30f3c195a5792810cd29e6183362c1742f223db881a6b922db4561cc0ffc427ef4d5c93bc8e1983224bac88319d41c8b24bd6d872ed82743b9f86af8c46e5ace4c16f63cbf15f995c92c277d70b3830892ea65f24d79c0ec1a9a29a2471d6bdb3d04df067db7118849612cd73211d2f0009f0e6c877d46191c3c12ac40b83f3659b7f709eeb10f03e73aab70622ad9feda76db27bbe22f85d2eb8f88e49dc50638c67b2c52eb14288ca8ac2310e06633c3213a6ef4863ce7003504463f5f7a3190057cd244b6523847895b7cc7c21ac796fc01c7023d809b4ac3d28c394aae889c2ea0b416869a2baf70318770663196c51cfbdf77ffcc937d8900474907c1fa5ccd01655046c7c2148b6d1e94673516d17b8e540e706e3c85061c8173598f5e00fb8afbfc4214bc78ecaab2f28bbcafc63bd804456a0de1dec91f4b6d7100ca39a30124e5ce8f1680a52eceb036774a4a9382d619b53ea2ee18ac974a796cf54982a3a613d39b87f1a3e1749224c6348b9991f3e15673738f4df8500ceb8e3d6b47d09b625e6e005c43b046804aaa95ffd5c2af12e13401514c213996692006d67f443dff8d76d477417203d384f51e520fb5c5bc3624c2a7e6db3b68120c81fbd3d15137eb3a64bb4007f2ed4f124a164eff4478a6e0d6c0356838042c74dc6e0f2de621fd8d06d18f +expected_result = pass +expected_shared_secret = 35fcc028acafca8b4c7f6e7dc10e13de9d88309ab8ce605f26e1399ae3e16453 + +comment = Random ciphertext +private_key = a1eb5adb581950568dfaf0373892a7747bb6395175f97c734cfb548c55cf87654cb2c92b852a2150882511fb6888987cc1f345bfb71a0f0093a0718816153f75d8a2c1585106d05fa555616a42c55cf461c5b81c73d7911b14190debb41bd77c75667db5323824ac2aa2c38f21752fe4162c8c1c16c71210ad930c996c7c66b562d1e9aef827b1fe03886c99b6a09359720c3f3f554df1c87044b0a8233a6b38148222bba94322237c7179b402529bfbab952c14170593ab77c85dfb886e77b1155b7d672cbfc7b4c9d0b6483b15b6aef30a3c098beac06e4e629b9ec336ba868182364839a83b76556b71f86a6c82602f581923848c75683c63928cb240ca84643291e53e4855ae4640b7a8537e56380394a59a4f5833beb286b521551c4c4bb992c2f4d107e6f90f1cf6461095903b34787450379222460cd0575c9c3bac39a1f2909055046c85fc474a5777b98948dbfa512b0c5f22881f7610791875414c9b581554a1e57402f7684fcbd6a223961823807028d9a901003e08668a7df6088061657540a193862c310c7e01359ded2210e031aacb762d7413cb7eac1d9350a196e13533427b3f53363484c8cfaa5a208904316ccd0bea292354b327a37ab6869ef290b0f2289f94dc3ae86c55e9fb6859accd69c165e61a3afd07083c1960236b095bfc8170489096099c4202912d72bcbea278e529973f805b44f166bbccac8c1a5019c1c1700a688776b5a7c1cb191a0842913f84058a01b165c9348298676adfaab7016825d8c2ae5b7211a5866fe5e493e27684238a9a9da1980132960010c32b785a83bb70849769e2d19ce569ce78b4b15d85c263c91d4c6522293b6019490fe9398e8920733bd581f67836acf50fca5574ec862866309b547994aee9a17ea15365dcb49eb059d51997f88c7a8993c2e0505d20a07ea183957b568e75315711729bce03bbf9a3128a7754e2a696ae96ad7f48bbdd82144dc707f4ca687fbc6245131a6544bbacf002f6279ef5ec6e4c914c0414298dc656aad8180ecacb66776fac282c5a91362c572954992420e4672463a51f3b08c3fc35b428100ef1bb229c848c63b7e5a1a7df041a8d6c42b3c633a3747527d713065ca36fec7f227479689c4dbcb71b67a173eb2c92e1ec45ba822761910d090a1026da771a9b55133c6aec34a88619712f2a868104858e574c20b612c2b3ab5f04b995c07b61c0a97aa016bb0193a438c3407716615559b8944ae1b54c9e46836c9b84dbf4ae0c0b890679c893775718a4b7e849067bb3ca15a9c699d908e6c30f6d29254daaa4652a6f48611dace8442a9a0bc6e2b7bf8579e8898ce91a78fab87c578910d1aabbc01b9eecc84e6deb775fa476748b6df3767b969c77eb6bcceb2459999cc08c350b06152add11782b2a1e4d496dc1f1959dc483d3283aa83a4f28f748ac45224db815e0c88bd4730bba8c50e1910363a96ca26154bafa071b2aa0cb12abd58167ec9b6196cbaa9da702d5fa62b5941ee39159a7e5b90044881857947c763756e4cf13956fa3ecc3a8b1c606485e2783a722eb9ed020019d74c3149432ac5762cfe908e19296da489e72535c4501b8cb022afc3b18e9a49e6ec6cc4aec56aa026fddb69cb7d06b7988454ea482b8d9881b05c9e84b9206068f231836492abd7321302861a8cfd6973eec2c396b18d18b0075fa08ee168a79f2a150fa6db5b6637c956699546873275709a2b574775ff8302412142bcb1abf0561afa0c509c715b156884cabdaa36c427aa57a2d82a9aeff15503fe4897b64483a83067a1088e42685cc6a657f63433ebc554c89a983f30982f14726168ad58945a401616c039464100555a90f34075940d274ec7501bfd5ac7e883fdb86383c727ff23ba47d7095aad3183a2682a2e6ce1772479e2b8bebc49d96275d00b3823cb22ae950ba8cd13717a105306bcb06e10abb8a210cd43b16930cdf2a2ae05357c9c8c41f279cb48b0a88320246bb52b4623880165d6e804348131160a3942f0bbeed0b58103ba36065a769cb17c3939eb6d70b6e947fcee7a97ff892f0fc15891736bb420920687298fbb7a64c0c5558986fb9b9cfe79643d814eb4b0420c458d1e893de2872020377c57b12a37670ccea2051e68b2167aecd6bc6dac5637a400c34310aa1a5771222cde3b61657d389d73d72b8c3518da769103d4ac69f7741f827476035ea42a5101a7961f9fc9c876b602214a6c8bf66e8ca0f7324e7c645ed4fbc5000c1cbfdbf80c057e07b35799e25eeff7609c613bdcdfa40026f114017c296ef +ciphertext = e94993cafbd822e5d74276b1299a9f8644571476b561e9895cd39a5828cbbea67e58c665afadfce725b99061d282cfc39717f980c645bb9af85f60c12fdadd7e488802b49d0587479539dfc275049b8a70ef29335c660ae578416281473a586913c5db505e8f7a995f47b015ac1b6ba7abf9648a3528a8a8236cf22991620191401637ab0730401d537f8411f12f5bd5345584231abe48fc1790f322e0cc2a1648a127393b08ed88a9db4b15c8ea6e8030f4aaf6a17a3d69cad9116fae1cb9f84eff1108b5a00c891e90a7bcfee7ab3409ab8d985c44e8b116cefbaf2b6a6b9cebaae235c58aa1b2410838cbc2ee040c72d33996c0b0e4130e8ec01508b883f0619d02e2b1237e5022ec684cee80f1e822c79d78de9c9c07f61a2a414ea65010ace08da262b7e732ef701c6c64233f350f4dad832ebf0a0bda19b19d602e163e3dac60db1753b3765bd68b547a8c19588227e288bbc24191746b4e48cb30a1c4f470156648224594d439a17ef4ef612b23c2bf105bf1c2ff6588873b8bf3d8299383db6e66dc12c05a89d1e5a7b0601872e1d70758a666b9d9454637d139cd69f55f7b552535d8d175d5ffdb20d03e3c941c6a41a1b859e8a977f83d877e160860146256032e1f8acc95dd939e38fa7937e4c6ec0ccb6f9741f814ccead22861a90a8243f49e3cf8633bb21d56d509a0baf496d203dcf28d35702d84d7c11b30a12204bcd4d4032180132c5f5f415636038b35eef9fd1ffdbc63fca1f2fe773857e01b47d6ad83422675ec9b2d334f9ce5dfa517c5e9c7ab59df31d1ee137e79fb1bd42bf0ac0eda5da1ddccd4c763379922205c97364c1b527a2fde7a4173487335cb3286b5b663912921f71545849412dd0c5e3c86e6b5965470ec4c23605bde8a5c81391ba5c3b09a12870fff537432914b0dc7cb94ca34de96dca939426408d1c1db24d49875fb0501200672496b3694adf2373455b4fb09e8d435ddb995e9849fe98734337b817ea75f1d09bab204fdf6c68ed01fc44165e4d6d477279ff41bf9ce89ba23d047ebbdab55999aaa95ff2d9696f670594f1011e4a689ee97 +expected_result = pass +expected_shared_secret = 07a3787d78105876016a069a03b3ba6517a483d080368a09a0dd0983e405640f + +comment = Bit flipped ciphertext +private_key = 2b970a168b51b6c9048c608c5e131e4d53735fd9ae5b4a0d39f1891bea4ed6845dfea207853b602991538a186dda399c72aaa8c6eabb1977b160f611af371c3c8ca2aca61f90a02cfbc020d7048671061d2124b624c237defa7628da873833cb70c621c2784cbdbb6de659a40bd27c23600bbd132c26e38db6136901a16f15722aa213319c0aa0cde485c32b900df508c09827ea942da4bc1bc9f26a6ab27ceeec9b9071ab3d5c0c46dc1668126edc16b76700750f5b6a68ca8e33d33f5d79c2a508a4f7883a4fe33e3ba9b9cd669fd852b03b152a7c590017f5781ca10becd0a9f350bd7790a64276920192138da2b7e41180e0323e505836a34613f2ecbd40b8443e27603ee337bd7acca99c32a5441db4637a55878d22788ca40294f53645c14ba0037767fa379e9c7a9825342b419b784b4c160e5c290e8ac3da98468a79095c4b6787eab427b37adf844beb419d0c7379f2fc19f24c8e18b40acdc16c5f501ba362043d7c49b4067feb0434db802fbe49944d971cd9a2ccc2a4671dacae1403bbcde67fef023f8306711cc6be1885625f017be6ca8ca490167b85a59b52ce6cc529cbf546c0870633a13bfb24ab78093b6e7b61bc1c95bf6aca987388d2e5b1ab030ec0915617cbaedae7050f269c526c740d249be963cc75478de8501d09e8a268442378cbc97af35de503c750697b74fbb00d019be8049ef6f7a44476630d2b276f7162816c8e812404eab881544c57fd01972d323ef6f7ac4d45c4484b476e94364488945ff98a871750fd2aa38d9bb3b8e909966b5fb8e24fe838437f5c24600186679c796e9242c6d302285cc87b49955e71b559744a8ec338381a8bf08c309ae8be1b7c36ffb523ced9a625227e3b348af3027cfd46070fc6245f29679325c1086c4ddd0c123ebbb69fa7468b414bccc2527e899bf48206f26519e6d657f12891719152686a78d3c04783a51775bcc90edb0ad4d3ceb8fc72e40482e266c11870b630669a01f79bd53545fa76ac77f697dc801602a98fd12626f085083ca45ba03575dc732058b83b12b080081c1f31088551b5b0382475b90c275024423b7996416cb332ab7e8f02728b56233118ad66cab1aaf3a440e19f40d728a464bf9db213d7c446ca8043c1a24e96bba1e02a177ccb9b34c26226939b58f4c9b485bc5c151e0eecc02de229bf1ba489d7cf5c766843387fe5c85b26618383e7c2d8a56ba88a8a88f43f567715e9d4918a56b920e535c5569e1ec30d47c846a63abae79665c75c11eaeb041fdb983ada97cb6354bc5c8bcc65225074bfa010bd4a4427f3b62422e965cf679eaca7454370cb858475f2f889db122c4e9a0d58c1a940bbb747821c2aaaa5ecc5010cb2b5d58cbc86847eb3c36fb966aa6f43cbfeba2cf6d233adf5901974052c3b0723e90be7666fe1cc93096087dc2cb80205a512ba90da1643ac318d60305c1e541042c391ce63283dbb3802f79d423191b32a1e1e0cb4218263018c39cfc570867179b7a701ec6b0bd6b65f13c2b13605cdf6db5f363409b29599b5752fcbc04fe36136db06af84448bdca7601502c13a139531ab0ba9d9786ec6b6daf803cf51a3348266f2a166a44255aaa94bcca59acdac9499cc6001c9a868f9a49e69672025b2f7467a0098006363743b9a0516a4a3e7dcb8609509b40023715397e1a540394cbc4de41b49403f47b1ad30649c6243a91e1b0ba6d2219e169aebf2c187a73606ec9d2536ac260b917d05a946941ea66296267769e9eb0c57e220786cabed62816a14b4780148791a9447c57c5592c3549a305ad632959b443db693865801e2c0b913248df90243b86c2718c95a392b7a5fd294a05a4c46cba4ebb5013b4ac76934b9e5085930a0b3cfb38e19b86836fcb2f019197a886d862c27be0b8159283282404777f91878fa16c4f75e10952e3df62313998443f8a73ea801d6005c5dfab3f753b690c7573583baab5a78fa57b31383061b16c5eddb6d26770721931cf602c99cb55adad86a6eba0d60536863c218e68ab60494c2d52c4e447b90a0b50a35044c9b3a375b7a37e35220da68b9d190c53159494c935565446d402ba89d520fc03178318610cca63369ca17432737e1533c55732ef4f4bcf88931f653a64f978de77b80400c85a0925c6cb1cd987c898d2fae995593f843f4a4f2959fd8b331b1f6355efcc351a58b097c0d49b1dae62d5306ae322da2c5bf343d1d116eafa3a0677855d6e22235e1c669af0c5228564ec33d69910ffd81911d852b55faad837ae3a1fb29e30a2dd0405709bc +ciphertext = b6fd849f20a330d57e7a38c16100bf76c5ebc4a6be388307c7ab765c9b03dc2c9db622c940737f74356c07e5c3c995eb187371e30deea2c3e3df45ff052437a11678d687b7eaa3c82d4d8def0b12a5e0ab9306183d0d233e6a46cf9f9696da6a1485004c581ec3363bd73a263b42c4cee137b7c8f26701b34769581713e9c9becccf332d217937cabe1133750a510606dbeb1e6ba822a3c7134c063306a3f9cf88a8f8dfa01d7598dd0be86bf0ab5395c795f90695f30b25f52159349a36f8787b33b60a1be00073bbe2c2a6cdae92bf64ec04624b28935c5aa8b873ecb52464d12b4190950df04d09cfe39615b7106f4bd34e8baa092941c6d79b0651ebd566ba4e1ebd011da3c4ccae7c1630390fc02fbcbfb55f53b5ab9c547de5edae6694940291f4694a30eaa42e3833bfc7ea617a0d7e469b1c8b967b13aa344c83dd606b201b970ea9369b8dfe9cf7a16238d8ccc0605ec4ffc9c3611c4d26355305b8f1429c2e0d0660e169ab1421d9bc7d9f17f87eb8feb0560e29922b2eaf3d2daa0812842ea60b672f946dd0345da4825cf03ca7c3cd070311d4daf186133960e1fe9dd56e051d76eceb2611ef39060700a626c66d2433679e60aad3c39cd636e704a274705e908561d236725f42b8da75faf5892aebfc8badf8d61b073ecc8f738cc5aa3def0f9b32130a55e9739e5b5cf73ed58ad65b2c834833f095a9275b610d0a2ce08c2b2f799706ccdf2a1e6881ddaeeb8ae194ff25e00fa60268e3ef98e8e4212ea941fe20afbc76231ced84847d6671ddb51bdfb816993b6d2698425017736ddeecc1484d5702b14c95ce367f0bcca67c6af2cbf9d122071de2bbd43c9420848f27a241051f8cfa7f44f9922347afe02477af5b945f32822ed423ae7363bc52a3d492f61f9f7eaf673d07125789cacae03789b91113d2de57f6d757fdf43c66eb90a1902923de86a573cbf1cdca0de94fdd1eb0d76b62a3a4cdaa45a50afd2a2e811990e3f649ba208e0a2286a8f7e9ffae5bb2d62cc976a4b56603f5d1745a53a718af3f7a7d2dccaa437e0e94de9ac4765c4a079411641e43cc7590 +expected_result = pass +expected_shared_secret = 26fe631c1a64bdc6f15ba79f17f4e997ca28ae55bc9af97ee9213c62ec5d99da + +comment = Bit flipped ciphertext +private_key = b7a72c1524a620ac45b6d2924b03c76f54240ef9bc6f53c8328b277e4239769041aac84069722c0e49b08a507621d8807056609f95c8748172a0f871e71c76f6a0536053721ba442ce5029905b33db82407390c9970261e5692729c03efe94563275a8e7d0cdef044a5e434d7571353b1ccc5306320b953ad9eb7855e88745a5129583bf086251761434ea39454e5267816b6f9fba0409475c9fe00793086dee780727f55e159b4ad8733115908545785330980b5e239275e8af8f517cea029896dcc306921f0a7358165cc985f0cfe06b19cdfbbb2f9a81118527795aa78dba0b3b5c1de29c0203015a8beb4993601b136141eb1c159fabbbe0e99c9bc78ccb58124f988c87488451103bd2c984a5a53b39161e993a421716697db57e8aa24d3a686df0641514f386875930b378cacb5079befabaf8814f5817cc4c1672fd860d709832fca59bbd65cd9e6c3b109939a1f049e602b6c8339e1edb024272cb33d3cae7b0852e2bb20f46c70ed9506c72a50385b4dd40073e69279a46a937a9cb9b6aaa3f92ae38dc188dc4786e5261e3722197934f350780954597e9e33cb9e6c670a28ae8a50aa3458f85d768ed2549f4cbc281f5899089af59548f73731b0bb9a679c95085bca17c20b6ff88a3382421199b44cba284638620585caae581a95ae26bcf9c5c10487e479851f5e1ad4992c2ae7497385ac3c8e32deb15a983a6cffc74bc3ea8c31813a32cfa51ea758ade38c22900af2520bd72ab25e83955ed9bad0bea979ef55717037fe0b8c7b076c4d759c9307b4c32a75e4d07318354390f201d5d46afc4767b753135a2208b0d6853dd358439242d72e922e46ac625677ef3fc27157c9b3982c4c2801739b63aa75ba932a6a5054b75db927336c42f50b6c805f42e0c753d02fc4c8d4b0cee4933de1ab63aa36b6d84cd8884228c544bd1f54f419c1782056b70959ccf0a851b82a78c259f2a635ce806b17390c208809fa8232c4deb7f97415ce933b1e0a03cbda81283a9cd4e5950d5633ea1d25b6c269aff641afae6ca7a5a70b8d845551a1c28d7be637442f364badd5c521242cd8917329e9433863b84cbac45fb88cf4d9c0843b8352a66c4bb8b5defb4b7998c3c3a410a8cd37830d44950f1c9688615175c17dc628589153c30c0a56b08c25194450704661a5927d2779d8d82190eb07511968d95400abf957ed38ab24d0c9f88f517ddd938f6a126319ac6b463a7a24253ada31b0fe3009a35404044cca04a2e0ae573df1c7219c8b49da236f5d0b6f2ca27fec22ad2b14173ba6c97316585d53049fb0969f788c1385d9f8c3ce48c8635d90adfe092095c8b8272cdae040010507815a56875b77a4f7658f88715ba107da54c609763be87f1045687a4b324b870b746467b676e171f4254ba9009ad13f39044d32925a22b4c58165b1c348a8b31d23448ebb5545c57404eb87baf31c659e4bd17536e29c43b421cca273248f3f6adcc378cb4c84cdc0451ea44b1b7b08217578239d15ed38b02c3f8cd58b6036db1b69987c9c3502fbef46c0c3c312cea2e0554267c6b616845bab88c501cdc1b865ca3c0692e6bf829a2b591ae93cd6824652037903fa0140d70700047bd13aca534bb499edc5a05d40cc0d9312ba57633421fa5ea829d1bb1b05a634482376bc482af51b0defc505729490e4aa601b8410c4355df0043b0532c68877636b353ee9538a106820eb03da782bd395b1e4b3009c3099e4018ae5797b8e4d69c864721b051bd6c693cd351cb8f79b27eecbce66abc7a25c10ec3c5813bbcd5792996dcb1f1160b63729e52f63e9ae80ecfd61c34c3c94913808a037b43b386052b719e740d9b470681c20bc02a488bc87b87013b8c42bb877200cb58362b88157eb9b41aba4043babae60535f8591361130a23b14235d57c3d60401fec86ac1824529925d834be11a051f1d3baeaebba7cf577d3b3b9b4ca318a494dbf3cccb559155d66b282e763819acdced54bb5d997dc811e66381073d8832418669a076d5b31bf5974b8c68521e8466eb7b025c0681f802936e4bb54c3bb147cd87982fa176e677a65259968d2af30e863233243c32b077da42b53f862027a5129f88f6c014e57413e7a803f1a4901ed8664c63abb7a098d5cc5c382c82c24204fa7a7b3833b701db998d1b921951ee927072762137fc4cbd2f088bee8ae24575a75339d3a0724c57ae80b232f582479207e1a2ba697c00e801300b49bc3856c48c80cc058ad6eb7f7e7425c5e073542023e21f19e0ab29be3f08e214ae8f10980ab44dd +ciphertext = f132e45ade8cedf2c4964852eb5087822abff92f9aba15d75ff7a15b161f1d93aa6c472b0cb3ebcac33bc062405f834dd8a92535f471116b40892c87d6821bd0a2ad9159e6c3f39a3b3402ed9ec56cf70e8497229de20c8ddb3d69809f4ea61df08a77bfab39b34c21798658418c375a654e263269de09c888364d11d4fd745b6b45c0b530637bc589486eafa19a9092952018cda1ba8ab72074d371cdd63d53990d4e609a95d37e060a932a31513570eed50d4ea27298cd98ce95c922c1fd338f6d589c090fc8edc61745d895e2ba44b18484f72451f262fcf50ebbc71fe064857d536161eedb265400e58614ada9fa65d6650e8c27037cc6451bfc0c584deeda91cddb117907ccbbabb91fabc302cedba6b8115a8a0b58f72e96fe856b97f79aec4bb6ed21c006e1e4f1b82660b2c9da4c7144dac0ed934cf3bdc3ae493164bf0491dec432ee250bdcd0dcbd3ba9e6859a9cf9655e0a5ddd750b8cf09e21d44caa9d6edcd32d2b5ec745d3d0184cb7d4bded8a1b7a5697e1a8a5841a9b521407f71510fcc2077e9e59b005f5739aaff12c0ddd6d72c6813015c05e9ae1b53b55f64aa01f659884049183466a1779fd5111420f04d53fe13c4e8e5bfdf7ea4d0741c62629cab5ae5a97df8f5e5f30ce96a6ab721a5c156a929ad60afd9c2e8765668e4bc124ec5fb7886f2f9c8fc332693ce4c4bab33a09790a56174fe5d7b8741ed40dbce0c071b461d77ff10db1003a319786afc20ceae6a93bd72b61a87ff42a1708149af7c9faa1c0267415127442974b1e9107b555c8afc0ccf31f400e32d17cc1250a8cafa44122e19b503d7433603d30d15c0d2d796ca48e1f443077ee0264e1f32e3ffbfa77ae9d526fd53514fff0325c1b60a4a8a9b88f80da1a8b9a475545c1dd2791471c1657abb1d535b05fd689d25f77e88ee787f41bb67079ba23da04d2398f42f548cd5b67da29fc27f46edfe4731ea8184cc90187fcd5cdfe9bc666e300bc9c8593b8d2cb87848254738a959bb62ad8b8e5021d224ee17c66de0d8855e6c9ad9553a773f7ce26839772f92fb79a7529a49d07c18db9b27c +expected_result = pass +expected_shared_secret = 74d7bdef918a98d646d3cc9dd85057d0cd14828b6d3f5aa668e01d089dc389ff + +comment = Bit flipped ciphertext +private_key = b59b21663c73b169375e8c4e397b9720ab5519f4adeda994718b2c63601d9d6cc0a9527dc48a0a05270c1ab699480595bd81263e194184c21ef1ba2bff28722a225aca6a05aea1b0e4e188f1dc239a9021f7873bb262733b57356c49132ba70d34e935a583552093b990d7bdae32c97e828c3ad13f40bc0b28c2c0838aac0c57595ad9879e220a6ec43ef04b45798a0613a73d52028f2492a64a0840129a66222ab237717855c29c34513a4f6c14df742a69b594bb1353c9d315c7510537f82026866a3b727f2f5c2537092eda3b58b2d60e6fb84da215cdff2b7353c72634b2214cc523ab33a06d396bc70a699163258b67006769075f3b3e61817f9c82127ac4aaa6bc1a12ac0d7715cfd9e24ec65ba1b9d9140ae88ad604357cd224d3f450503910681c4656e0ae722b941ce776c0241f9b769a72f0366b20927ad07611c9173956242a807579dc6d846561f109ccd21339fc6308715b9633556f7d193dde334e0ea82bfb718da2acc2a51271df2b98e95cc67f170b27d811c72b0fbf38333ad61c01d58b32128965ab0aa30c4c6eec0138452d1077060027c4165ab45ae2073c9656523a1ed2d065a7a3153da5c2be558384d8600ef8cb30a61e7997324985b209c5aba66c2cd9fb4438758993f3b80bfa41583507cf801822cab6e1d120ded177443a5fd19202fe07c8fdc70512629c32c04592fbb53779798a08c5f1b0ada0a19a417022c8b941b4e6c65519be482caea152cd4cba35318959cc966170c12d7bc5c2c6088461239e9cab257687c122554bab8a037900ab9ac9a219e44832b9150dfb052e109250f77b45f51ba63810895ab6e1089c04463f702c4f4ab866c4a5a0e73200007c5121a7462c4b47ca71c1509b658b3c76cbb167805a2f85782fdd77093c30bbcf9a5f9e12b1f57176333b89da055b5ee9b9c4a592c4bc0440a9191ddb6f31e6b16fab3d4976064978b25ef0af913c9445b2ce0abc160f8506d55ca41648264fb89a7353922a463e475214c28a1c78cb495b24229d72620f0169c9505a37198b2071395e466b056a6d96994bcd379cc5306046f3b04cf84154ac56d9c3a2a9f815eda732ba6b0e87c8623101b1f409050ca86eec29931aaa8126eaae49853000316e1851c65fbb8f2c93b0685018f07455780825a285269caa779bc35643eb808b282719669e5445773dfc74209a170b95a90ee85023266afc659a2361cd4ab989e3e93c4ce51b0f9c38ba600c56bc25fc8666b64c7709b27a7103917cd9a1e0ab9e40db3797543a7a4abf40d0c5170b3792e1895cc360283925ef7a50ba44b081e42ee8bc030c6519b9d65355b3c70c4826897a85533524b2dbcf951c685ab7b38ddc9f2b75445afab99cc822b6b49b10656cf3c998aecc4fc1d728a4264482f7888477bbbe9c1af5fb9111e95fa9f2b764d4c85a07726f544ae5aa885ba328d9b0c935cb179275261c14a265708bd53c1b6189852198a0cbe0cb31196b0bea3d8919508736934fa97e6904697e3972eb01b509694f0533234c794979c79aeb53bf6d830c9b268b0b1baab444a08b6291f046b009131c9a301e20eb2042544aec352d3d177c4cf3a46a6a511dc4af66579d9f3ac9f7327db60b002f481e3e143901b437e185c41e0b3adaa36123599b69872b2c759ef643b7e22bab56c44831727c5a276b6ca299089073a1063b9f154c63b92e1f1ba688a8911e97b506688617740df757b9d1a3c7d3f9a5c72ac737466cc7a6a590cc5754eb3b674a79b774759a00a2a9603599d18884b708d3014215693acca9710b063ca5e811d1b101b14c3c1d520c3ce2b05c656844e027eee984a456023fc100241468a72009c9d2508a3603c421252e861f9810b5d32507721955d0b06bd54b1f3ba409b2fb6218bb8639784a2e547987c34dcc318613c3486dfc7587cc7e4dc97c3af8b1f5e54ba4aa7baa5b194f9318a65918d6d91b3852cbc4b1cd02d3c34e5aa529fc9ec352328b9673c330842c14c2a5112ac7659ae81b3c5a6c5a900c42c4017cce199ee2d08a7f7b9a0a1c82ef981d4175ab927bb803a235d087a9b5a1256f8312ab7839ab0995b84ccecad70628119ac4931661b1b6db1a379670c1766941ffe44f2cc56622ec87f27758b15b3b513642ea08328ae0949de0b36a74ad953b2aff441987ce45189a318fc0af33a7d22ba03113c0f6d971a202f86efb57bb16622885c1dad5158500be512f47f1d59fc539186ba7eb1c7498053908b5bae3b9f09abc950f18b8c4208c723201563082b1d1bbcba458950270defffd9343 +ciphertext = 8062282999b2f57d6831b07a49db3c0c7472e5518d5de615efe3e18ed3732e2ae5c7a94bc7a0eab2a9aa1d839942071689fb1c9fdfa940166050d9614e398e46bf788e362d6b559e97017f4ebbce1a7a34a7cadde0f49f40178bfed6554f5eae28e24bf47d58c0078435cfaaaf3045e80d8f5b2e91053b3b47ef5cc72371df81cab123c10c5e7bde658013d279d790972c8435f8e4dd770ce0577babf2f0fe133bc6daffe608666d473bcbc325ee1d4bb47aaa95b47e90bf6d8a0f12daab330443cc70d8a9f51bd81e79db01eabf1bfc1e92ac5c473109d6f2bb2cadeb8f1a7f27e04c04dde5d70e3d7f0c73c718df09789d5e512faa132800a840f78b4d4a10411ba1a8ee731ef6bc63ab426a16dfad81aad5b16dac0daa097ee150c5a80b5f576232b227eb54580b0b6ecfd7745d53cbb7547bb7e99cbb43416faffd34e4ac032f2d7c0b6edeed596088649e12e8415023c10aaf2c4c566d09a607a3026324f4d99a8f82507a98ec5924d38967d783db1f60a2519c0457a312447178b40a2db3d8eeed4510c8cb24c123466e4d3609ac43b47c7ce28adebb1629e7e43b604850c2eae71837176988b3e9c382f5b40f9022e7703343613b23655f97850a06ae4764dbc166af447dfb1b56e782736f51b9fb18114ba2bb461108c4fff2d7d71880a4158a0fb0da4011a914cfc8a106b919447a0cd15a4586305a6295be65d01a8c6bc65597f86bdcbc7b615b35aaa2f4dfdd70771ed22fa1e10ed5bdf2940b3f58caea552d49e8c714d8e8d6a7901510c2809bf4348de1766bde4bf6b76e064ae09814776363b274280a92aee2f847b942e0d2264cb6b1f21670aadc18136ac39db165b14b3c6c04e6591265f3f1f375755f0b379d136757716a7a0377e6c71dab12045f49fded9b3454c6e820319d8fb91bf8562886470a9561083daeba1e3b61e9f2a7770f10a9114688589f8481e7fbc303bb8f03da837d195b88ec483223d394b9e3e0e10ba6b00d60fc239e8e9676425362a5f9f3db10235747d51ca7371372f93566280995fd4853f8ce095beda7f4d286a9dc029c423ff7e00f3a645a +expected_result = pass +expected_shared_secret = 276669cf548181fc8a907008284acfbcae9b59a1c0685bf81c06bb313e99f267 + +comment = Bit flipped ciphertext +private_key = 7e7022611a3e863a8d805b3b35067824f314a02a11db4a7af49a320ab844752a1328eb626fa7a709257961811c38d4853725459c6c2da2d26226fc2eeaa518c1cb83af83aa426b92fa65ce3fa8b91dfca6275c77f42ab02ff39524937feb707490e2265757c6f005909b838564f72a097762c33c341ef9af0c357950411769aa871fa6228874af768683cde90ffc178d61546898a0522e3c0aa29cbfc84c4bdb264c5615053ad11396d565674b9478e50b783b4b9512bb8ea097ec2aad17d9b7fc6b77f6dba424805b00f481bcbb0f7120ac56b724863223f27534038954999a040092bcba01af96241725c621476c5f45c3c6bf201e4cb93702b7ade301165cf1c8ece81d10575f8e4467d7d9b969218e4c1768df497ce825a8edd414a2a951abb9c8d59560be6533503b026f74a23d81200d3c56c51062582b2bbb518ebc70508fd1ac9aa5c4243592474a332c58c66fe98cda323c59796396713ea779a11b4cbc9d063ff4c6a4e08c4eb30acb18eb8ca963b66cb3427dc67f21377614412e1a0732b1b79783d60a46289bd1d59c35519c3ffb7528b84a172b3f845bab79f33a3db0af4f742dd7440d0bcc1f490b9914c3adef90b444b1633c2a417e774355a2c8def73d2cf2403781b4d74891f0e60a5dbcaffc61b1d6b0917c6aa984541ad10b120c711465763e6e500ea71b7d9e14684ea61358ca098ed92a8f537d61f62def4483911692af6658bff7806767beae091a84b7b964fa07f5063d7f30a982a28abbc65431ab5cdb9528dc0a70c4297a5d9a9d3da582737c83adb8c60e848d7fd70818172653ba0740cc73c33844daa89d74392fb0935c4cdba48673506eebba28774a2fc97498a87d47c7425ba7bb49f93fae9b8d99d08fcf935b4fa213c7582041b95edfbab8f53102d40a867c3b8d2c15a17ea59985d35d127c857253a5ffba25b0f602865223d865a27eab07a4690347ca4e2a31a68901705ee42f5ad006c47932b1a819f5f985d42582636628ce489a977980b0d28eeee7338a88ca31c57666781846b788c0a6ad595922ed76ceaadc627d37898a327331222fa5f1b14ddc4efc583e007170d4b176473a747f445290aa6e4dd09f01639541959dc8aa1ac5d05bd7f223c4b8b0efb54ca3977e0caa7aca1086666a6f714390e2d59fdb630a4adccd45a453aae32cd7d37d1e11b9f9d7092f83572784630d796d5a5a6a297a15a5a52ca1486809d058c5cc5b4c29ca01fb1f645c8ba72b4cfae08681c772f555c534a7761938aa3576a71dc971c3960eb58a922019a155f5a284e10aa02c0539e4690350bca575b17c22abd839258049a5a89c087f4c382286749a05b13a2644715a644d08abf0f2749826547e237c7ea9145eb5cf5fe7b6588b031f5584c232b2fcda5c43d355ce12447692cc36349ab006b89889c25c63b688611e58a71cf8176423e46b03d5bb1e8814fb55acd27c6d54594190e83ab94397af564e7dca41544c98b6f4b5a8f6672cb308df02afd78b5bbcb0a23c84a276487290f33acea210911589deac7fe9eb63044a7f3a16690716b23bc35b94b773c7788f4e1146d420a7647209a6b82e4a7a064dd9bbd026c826f267077553eee42c4a19787ee75661d1c438a23adfd0724ba9cc3297bef2dc7f7cd7732549145f72252f8bcbf5eab0cbea66f911c8a354754d2055ec584c69d647ea2723b7e48db57a4d3f622996c5259b2885506c3b1e74339dca3cede162db681d4aa31ecda95f15a00c0200be75298b81482147bc0977c216893c17a1d1aa650c67f46a2566e4cec1f2c61fa81561cab6bb1644ad47c6136c131c973c25e213085b89874339091c9b4f033e3c2180c3a2961976c9d6700b65d4b8d8a261d2e11e51585b82a146ea476ed50b4016b04afd999ca9454f7a88c24ef92cf5f48743e5aa973948b1b188427847aa82716b8771c818c585c51304e93c9ab7b32f704bfaaa69a40682f35495342ab96b177a1705050f6585c500c6b355a8f7b9615179aaa1e316d4f307c5f3a7da4bcfe4b18179c4cff8a380e025b3d081128394492a8bb8efa4294fea08f4ac223c034147e75c0fb58caa782ef5627b7ee33d95b87bfd053ebab23a4687ce41d3b0eda1488d13b50b0bcf841515d3b06c4994b9a894aed249394df8a54779395067487a0ff8ff183357c0ff415fe53fa4fb7684d446489331dd13f185dddeb611522b2adcabe61fffa321bf20054b3be1f57228148c069d4e3f650dce89ffd67248af639219ecb8b186fa9968039196314e8f49fafedb9fe21001e08b5281af +ciphertext = b29d6a41242dde774cea8a8fb58dbce159359186943bb6c0a473bd83227f40603d307c0df47202f7c69bbdd44416aa0c023ae2cfd99fa6e61b03dad433c4efc8cb34b88e0cc8ef3f4c05ac9ea3efe5daaf8e5105b329355b0ac4d20834ad05ffafa8c11bb504aaf424dc2db505f783b7e2dae7d4716550d7d298f7752e1e560c663c2f3ae4601f2a5862bfd1a434b2334200be2705a0ab82809af0a41c71ba30e5af3a1f35d5e27dff68a40932a62232efda380b101e1ef29d23c63833d6944c9dce829f009d6df2d7e0db8e57d8f49ef268ec19321570c850a95b360b358ff6932d3be4c4af7e1d1502a07306cf16042786f2eaca0cef3ab2633a9c271f891a0c3550947e5e8d3c4a7ae5ed7e9418931cced149060cb0cbe5f4d69a0ce4f87ea2a6600d8ad1dac981e8dfbdae00febfb7c0c6617f314062817c1439d9e18ed0b7ce444d4c2d0dad5c355597df5e39c0d67f82f55f09af0186fd5b345796cf0b9f558e1ecb3dc2e77e1ad2742aa3c1da36646e3256b7d34cdc5dbdbb143a1ea38919f62a66fd5ab75d9ee1d7459e198d6fd09bbf7ed70d86a8d2fb2d9c266f0b1b2f3320c48c409bc1e35f0a07937862799e003d78f085f4163a2b84ff780064fca6edfe19394206d0dc161018a5aa1999c04d8506fd0fc49f579f0a31e77aac9edf11b4889bfe26b3ffc46e1eb0112538a796ca634cb9119fc567ae42523c60e8c7984712cf91f4b56b6f348ddf477c09e1d49c6c67d216da85e667e4a98f7fd5a435b4d299d263f09b88154b1d16c68dc4937eed5aa531687595414564bd0beb426441ec23453040bd759ca1b65791f6e1cad8117073f668588422f205680075fbdef30c7367aee25a3a2764206421dec03cf33749787030ac1c34047899d9ffba95f746384e5532741286ec3eb68d8576d101e83add36d5f345175e6622896059935aa5e7dd71adc10e4f3d439ff3890a9ef43c72a6e09c97cd863466ccefceb434fcd9c22d4b23f2567f65fdd052e444268c0ebd07f236885ea31e82a85978c83b8fd287e03b0874bdaf78628e332c5b252de211466da1e6ebbae0a54522 +expected_result = pass +expected_shared_secret = d117a8d0655254c39d848bb6c48a38e3c50a26c76c04702acd3dd14ab4691a58 + +comment = Bit flipped ciphertext +private_key = 71d2272c57be48b1248a13c307e3122d0a88d7cc184df601fd5502a7154d5b4133b9852ea56258ac3c0bf167578d750a7e65ac42f35b39c171f6a7138e50c8912252d7198f7c93c71583052909448fa21b4710c52e544547d71e5fe0c2cc852491b8c258da23a700afd11bcf120c14222b1e39412a0a9abaca982dd7a1aacb483b072213c2f787e4a599414767eae46ac58191612b718de13d24e592c98092a52bb25de783f2b4224715b06f2b07433932c07505dcb502b3dbcad1d92fd0f11aef8368ecd9089d64387796359ce7be61073751c0b64830b8fda08025a09f4e54074b0bbbd5f8725f8a12f0865dd8012bb8898274c72bcac6a17f3a9a5277aef7264d59d573b60b4f33cca0b3535007644ba291b41b67503dd856b4e9ba3d5acb7df0344db81082b574448b482660aac84557f6a46531c7624af7b111f29072c4ca4ae9ba379656b0f70a011bc5a166428e3c6600a352f5b43898d58753ba09aec382cdcc1efee28b701bb48411bb624b65b2606badf35f6ea16172030e1ea420a065037487cd6e55b15fdc8055f1a213dc5439035aea1c66d5557ab316823829575b0ba5e0b71d6b1c32e5e15e1040569a0a175885913a9559a3a2c7e2ca25cadc0df8a722b0935e0872115d1c3a4e060f92349df0d4515bb3bb69d15874709dc7803b42c9645e0a6791ecaccf7aadccb03710c9ba635363c471b276fbb274048d6173485a009729f5bf5cec5c84762afce60ee1012ba77155e2668554192404985571776f9c538a46b14db9c76471d9295b4a512710b84bf2062497c0e475c6d6e6a13df46e36795b85838f12a82cebd24ea657321c8548d0d3a03828aac8b960329995f6a43754b4388c584fe43209191604215b8d31b3673d0794fa73814c1b941414714860b3ed5090de7bbe447964fdd065660412bad1bbd76928f246a322c64c19a171f44c74f03976dea6aefe365b2764b8f784bfd86ba2f042ad6f4c7a54530e6e14ca9261bd71155b5dc554174008cab574e27cc4f3d5720d8725eb7362ed9b14aab087419a21a14787e2cbb551b282c949982f8c255b689e391ca90c977b8f186311096716089eab2b964b3a860db7b14454cf92fa75c29c3e63e07e0e564f6de7cce81321e0f713bb56a6771ac2434099a61113edd272f80c9c2a49a131797fdd133dce031640f484c0330ad54b75d38c20ca672ecb876604246a82772dc7795feac1121b981ea571737ec11dba491f4b3988ad561988a70c4f9b38158ace27f6c1ca5b8033f6890053851618570e92827cd439c14a84416590bcf994ccc1b3b1c122c7108089f985676b2c9adc372e873d194ab76aa1cd0957bc8ed0c659169e7da38787f07e5e012ee3ea5c59dbb730626bf00492a8293da2d36e058c2e5647c02c186de2f8a82a1a1a684a04ada3229523c275f68eee110363d2652ca6a8208780d129270d75ccffc46f21d10656101f23fcb5c09930bac2b54b796b0e722cb43ba44a251ecaaa75d04386d17a814a8456bcf7b97c620d447885dc081c0966a46173cd49328fd6d159c821481e77a4439154a06b4289419114b56b7717540cd10944ea3f7048a994334c92c96d98703c6042bf5be46f9b1334206ca92c11457a69084965a1f11a9c312586aee8afec879ac878c542702bb03c5e468ca72096a5e7ec29d342c27ad25ea69a29e91274c920a0ef446411034b99128497623d5b3340c57b34c1c29e97561d09c59dadbc53b5742370a50e773c1b1cf6713a39152586bb7f41410b85b77d17a1eee88e55142db6fc29a280aed727a1837ac30397cae19237e9374ee00c12dd0c989af07ae921990de91207c02cf765292917ac00609ab5028f12fa4b3013294821597c7c84d22c737ca11e4fe89493330ffed55277b1cd477033e78a5c0d682fdef294be15a4bc824a8ee47636a68a24cc28cc66000c63ad0690794e667089b77408756141a7c0a023abc4e93debdacf1632697617c7cec87653d44a0b8411972c73f3b30af061865454bdeae05f5f716649a9905589b47b0c2317e98942ba2328e995c8142f418c1f0b939c15125bea6b79a2f16ba1091498d53b96e61836865a405695db92435d379d657399b21193449577c26c0c25c7854a2054d2b00f64833103b00e27a241cc4b1b7a46275a6877fdbf6f8958bd652adece72096b4f648aa18bdb92aec9e3c4f2090751becc0ca1a56b90f18b1f64f9ba788239605ff4c621d6120c825c995a1bd4d215251f6392ed4c96c5f14edbdbbd2483335f698ed135209688291b1462bdea079161 +ciphertext = 0c818a4127e8a253572257f7820a49f2288a651312b461f54b7a8a5873b95fae9479651a43d010e4540b907c21c613760b03ff2737f1eb5664f24eec49adc91f5874c5891f080bca932e1946b033a40ee95a0b67aa37f29bb712562dda85cdc4894b57501a87e4e8d0449613c6e22072a4e58154d04e70b4e85d4d5a8d65fc2a37f135b45c7b7fd490b572372357a21a948f1aeaa8145045ee35438f9c0bf7c48493886f266aa08d2d84cc3017a385c2424590784e220a01dca5f230ee298dc94b64284b4348d69bce049813a3bb3266393a5b65308db8c743b198ec24540e8e5c8ee046f0129082151f5668f86d1c1cf6fe4a31419c44a92589ab7415dd8e2465413534ff46854ac94f9b5329f544f96ea4a8defb16e44c5899e61977021a5a37905fdf966c6ae5343afe7717c9582524d6c420f52568fe8671fa69bc06017fc78d0fa1ab91940798c93e8c3a636769b03998bfa5352639ad42b24606876c90ef147938a464a85d01017427641f74a2bae5f64e2cb1482f1bef73ed0d86465c2d5366e2446b692c322f801a3220f2a6c3ccdddd284058e8d61a0f2c6a21bf30616794df0ae21791f18f065017371e8fff7ec7f59fe6bb646db90d31409e77221c34111799007537e49a27c54a36cc4a53cd9bd2a6ef6caf95b9ed6e81d6eaceefe2199be67362c8a31654d11f2ad0ce65b9f77e9944c0c46dc6fd48f7088ada38919e7cd51549587ae985cf3d7ac412edcca4e54e4e59ce2b4f2f7668a047a0b77fd3f2ab456dd9b08990009070b42388a2b1292351d7af61982427ced681895f705372fcfdc4e9fcdb03fcf204d2c4c1675a0e6aa91d95daf42cc0a0dd6cfa7da719a1efaed076a2692bba42001d82a841f10521e2a6337b42cf08d84acddcee4a81d60b3c848438e2b8ffdace0fbcd1012a51a67ad7c320c1d94288b28ce151dbbf03df2647749e381e84ec8044940e28e54ab98239d51adacd83b808113a54bc38809ea43ed5766ab15a91f422fdb0745f7ec67fcd5f3b2d90a260e27d6c15879492e1da2072a0d3f4fb39c4f6a236c29c718fc209b0311e01360038498f +expected_result = pass +expected_shared_secret = 775d1c169600e756ce80cddadf0586b3954fb5b9b87e76841131c7f07aece36f + +comment = Bit flipped ciphertext +private_key = 8b0bce5ccc18377a17fb4c550c01c1decac0b6287ae08b2a8b0a374305bb9b9040513c197c94ae5dd6a04094a412fb39f8d02664e58166010a7fb570b1a3bb372b67d11a501db849005d238ae0a347c3a98da7053c496dd3281582c6c9b982122fc105e2c3642e77888fc36314293196c3b9ffe10effe54896245018864395e952e0a3432c9c96b0eba18d713e3ee4bf1efb1701939eacd9910981734b2cc00657b5967b40239b06171731df5c4790c49451f0a3d93705e0b8a980cb67db514bd5d188508bc2682260f0422c8a3c4c63bcc1a3a2b6e390738f331cbfd7bead282844e3826ff26f8811b60499b9eb7001cd2aa9580666a0465e0b0929ee78c259b5b65710a78d49020b7697cee65a0cf7b16c7173be17c44a7322cac6783032725f42cde2719f6ef5a11fcba3e7bb678759264070bedad3b81fea91dbc96a8e05c398dc3915522037e728e4f6a6c81b9eedfbc942fa87d2c76966d0caa738b50a300340d95d8b997858b890f34c30409943248bc80a4984cc3ab4d0f953f4e0172e8118d9da8953c94f2ce935c894488f673768c2971ce468eb894c3c39cb6853768182c1e5bc725de28072b67888d19a50c2cc3009befe821b4099a2d5fba18447b91907633ea270fcc4c214bc955a7c9b91e5527662b8f9ba69b694a26a4590617114edb257e9728f9ee2216379adb0907de0d2390684ac301b6e7dbb15ea07458c782f9f433f1bd74de9e12e158ac22b45857ed5301aa21a3266692c8396de76a1c025a798ea8160982d776433a213cb87c5b196b97ab24c4f5ca78d3245b69eb8bcdb937dda2952c2043371a07a7fbc896e136af6cbba4e69589d44a97b0a8d7218440278ce25681a29641316d9c9d9874621629776c420bd59c6a3a44241b048b74cc17968c63ad305de14cafb866219c8cf0aac00d84b6e81e0c105b50c9b4997517ba04e12576ae65e244cb0025b95f606128d043f5f44ae1a6ba8c9c77444470e8dea86d502ac34a48900f51788fc6b9736323c10ba8eda2c975b02109b09457233f9b9551ac316521b63592c5110ccafbac135b6bb685c9b4a748585513a3e159c80f89aa31707865f7954870690439c5eb50203d89159d5f84de0632f5ae2633da3698048cd81a09aa421c63e396f5a329c0e272a22e93bc605b732513f0f77471d446c7180a6610a9de753c3d87b9a89f26c2fb480e4fb95d9eca3736963dfb380d0f14304a127cf2014f035c7f08ba4c190a3ca83477c9c55b7cb5f86c55f6e5341e0e41df534b840841d39f0c7ef5588374c25a9dc274b662f10d3b9acf66ae4371e979471b53bc5c7fcb5febb2e1d049ed87c949172a7b542ba5c82993b870eb1608f4a4cab8ba3cb2896b7fca3528a1a9bc0102904516f1876728c688831230dfcabaad8f90b209845e1fa5d8ca22ef634cdf2c368d0c43dd374ccab0b22c256afe4e97fbc853d7a7753f4db46b5803a4430a5a0c288f9151e3001092eac5848c2aa47e80e3ad352472560cc9b1b4f716535c17a7ab5ae66d193d764c8f4654b187875579894ced57e9e934f895ba3df416a4ab24053d81ac5206d40796592b86acd42324d3bb60d05a0e54847371c7d4e54767a2059ff66b40139cf2ab1a74720c12b7c7961f71569fa7d50d59c0c748952eb742a2a270f8434827a103e697253d20448b33609459f3f7c50403b1b18f07bbba49d62503589ab540c1a96c60042fb219f8d701713237b2ed8b4ff60be29ec456d507ecb8cba25d69631975473eb4256d000d7a03f6199b439997200c37e3d087e6554c49fe91036dc06008d2c93921721d7bef4cc5ff4c6450d1cb9323b42cae56b32fa9fe7fcab175c520c706878cc3c91426ccdeb0a269616ff137481f7aabf694eca998150102487b878ae4a6ca27bb39d13c66545a6f04182638c10ac3210b4ac818abb7c7c557b4be93e18a13624bc50400aa3c097146dd13c2f88742f248514ea1f9d1c429147c7efa39b7616c7824a1710cc7a1a4cb7934503a263ce996482bb61ac08f8ba0c1638985155c280a0a7e2ac38c17e27ab6e16e454d50b9a10f80443eb7fece14dd6b6ba5916465be01e993c4373535a22d27a31fb3a519abb3e97003d42952e06b14938348b35a1f4e573b9f5a094f1b435fb890b210759305a3b5aa338f29b05cd8ffea5815f60054e3060b3cdf93c366b0b5dc961f75a5ace439d911abac45ddfd16d0caacc6a89c59547b1cc852918c3e0a4c29846bb0ca4a43503bd487b99574d19714dafdb3354730242d1e6d570d3668d77b5cff728074c0ea6 +ciphertext = 5e645e3675cde3ad42a9ed016769b07b5ad7485c320ab21d92422b847b2570e240b79cea7d4489cfe417aebe5d00f4d85bd175ea3e4ead2235d495b7153e655ec3022c4a8aff8bf7fa70bab42859d5367746bf73c943b7ed8cecab9772c205c8984d89085d197e0396936d696794d0e4a41199aa1aaaf657fa009f4aa5836c51a32c8159f0df5c7b91569f3eea2fb3c7b0cc11905605ad52450cd963d25fba06ec69ca190a2708454e3c8ed59a967f7a24706248f2ae1f58298fa1800724576ffa88879f1dad9347271be18db50ee93923e1ed3dddcbec18742be9d5ea6f693a51189394c1adbcc510bea30a1179aca7bb3e1acf39aee6a03964afdb94ffd162a17cb425293448d218a677c5bbd428105918ebf1c8d6edaed54e8b019f0a6ef7e6a3a721f3614bd836b5bb3c1f77af4da0a226c92b6c1070be2ce3d9750521216c613f9cf581f49992f54f5937fa74f462d7343770bba45edd61a5e307f62ffdd900b37f02662c8b4b9fde19e1f14733b85aee26ea8d13f33d5c5f2dffb7980c032e2112c718cc611317c56c586a57df975461344a3bf6b6932fea795f249c5f302dc7537d173cb0eef3c6533e82a0cdc443f2d4bd9f33145c3645eb834c4d3129f20fc94a5ff21affb1ad00fc815687c43c9a94b7f07e2b932974de711edb07a849b3bc59d09b0d09d806d5ec18fdfe5b9ea3487150a4476655e9cf0828b432dc87a23fd209926ca76201e06e5e573b08159ab7e113741c76e22b6b2caa9b87e96118d7f0d6b57e04b4e57b49ae1fa4ed0aeff3677bca2c86371d0903fa29caaf55a364a90f9cabe73cca36b884efb0031bd1492e79f0865aa2544453fb9aeb87c1e3297a26d69a67b63db737ae0c70f7f8beacb95f7cbbdc2717b587bf4735b8da26a4a22defd04154446a4ec2f91e8d7521edc242ab748998882d5aa3e78a6cac5961f1ce8e0f9e72229293acac96bf8057e4e2402b4e785173c8366e4b5b0e0b1c19a7b1da9661af6ebe70856e2e1a1adbeb078344aad3f36b56f4ae3889c5a293232fec3876b97cd897baff3a1ed5de3a48d30e21897c89838dd5834705 +expected_result = pass +expected_shared_secret = 51723c37fb596f8bccf997474ce01090f4e7cee3b9d02cef27f8574174896c81 + +comment = Bit flipped ciphertext +private_key = b8170459a064f74121881186c58c0bd209c8ead3b8058aafabea79d4a10b91b188bf83cf58f72ede30b22793ca839299ff080929601b2957041807c19101939223cb970c8bf1606db030bba591b62296c20c1584e419b2e49bb07aa80b482650d6791da02953f4e85bd2fbc79a08963e1a3f650089fcd72c15c8cafef3b0d9f762c511390a415d18870d09c6988bdc5e66d84f34f633ceb738d9002f25277471f30d111337476686db634910771e5614c3ea577160254d63550b8d16c8318627b3d700b7e57bbeb0a6b40625cd00bf9d114543e6b64115780cbcc08b6820013caa4e95ab50b408ab9ca81322767b517f3ea6152c629193d804d7f3073ee9c512b97c3cf81c0d52a4e1bb5da1877e80aab742a918eb04909430289617965055c7270b3a6e90292b50238dbaa9eedc000c041b3156932734aded22858be080a32b8dffd69bac8c1519cb26f8807fc3b2c814c98c4f93344c087562385853e33705e7c591c22d98ac94ca47360ca609795ca9aab7b000fba7d25cb2bddc41ffd436ed3ab127ec554648634a6b27da0118d6ec6617876bcea1440f55684165378a834b535125a6c287e1e86f6405ab51da431d028f383425b4a49c5f90c5565bc4ceccca9e4ab7c7ab2942d08f915b55d15986bcea871d883f7d2b7632269b912469900b6dc827830814585b2a42522a469c6c1e42372403cbaab96037edfb0936dc16ca326aa02b5850d97d1e7b6fb41b64a8a5489e6b2d4b589a52a3a18c2417af8a12bf7008a2599376c98b40fb8d2c824e615479833c9c421506315a3c45127ac3f798518c5f60c4b14f6a7a343bc42a3cc28551c09a392da2a506596a0ddab151173b9091213e2840992ac069198a1321174f86544fcc587d4c484fc2da7f6d456bf1057ac8acb84093a1c1d414d33391cf08185f17a39575547f6a21c68274b08b8008d91e67d76f4d019841b8a9ce1430cde359d60c3e31c205b3940f2fdb6f1563041b27678f01c22b5aa2dfa125406b473496ce523105efe22c43c88ee1f0421e5bb24557a1ccc3ac61c6c3a8e898adf556514306431b5ef91a2933024708f6ba60b11327b07fa090abb18b3344d60308d056c8949bab734b9b066d92847dc990cd05b6951453158cfc8d12021657493073c3bc7e449ebd813a3b5a22aee931b47c38a0ca078620aad5a3017a9324c8ba3dc5e1534ba627213c8474a6bd67d3410de777b8395259fa0c74581855e6a3d8214f14a00a953176c9169313a8243bd43f077a65768998a21281d001459eaab5f30b069ae71d34f8a4453115e2628e6ed6a0256206f7513ef823284301b75386b43208b16508225facbe6ce872f5e347b4c96f5fda0959ab4dac72a70ed33f6737ab4f43b284c2013135c2028506be1232230998fe3476c0d9c9a814a67ef7a6333b2ce7e62d17505e638939114325fb676ee640adf39c43edca87ff4436fcfc6a3b85a118e00dfac38007d1ae05162c78c7bf06d71eee4c885bc69665ba62d1fc21a6cb4fa4b03dd1a34235b20508169578e8ca2eca73a6cb048b9185e270899f09c1b1314265b819bfdc4a7f071db8b926354b5ceb821bf0553084c18a495438f40980f901c1c39b58c8e17cab5bcbef02157ca363b2550ee7931dc2c59fa258330d828ae34b323ac9cb2041810cc26628736c9f394cacf60af9f3218af070b807408c609246c881df447ff9b1869b7918fd5526fac913964831b7f36d2efb176d69c4d4fa88afe79f37d471cf4a446cd29443c1a48329ba6220464203af97989059915c4ca069ac1a0300e7510c860e633736484a50ded657b28c3572d4bdac98b72b500adb3a5a3e3cabc5e50882bba73f671dedc01a5677941b715bd144488c14cbbca398eb931031721e124abb210b0f716c6cea372d8e7c48fa66813b0518e2b37fae47073a72cdb4722ec6f7b5881669446941e876464fb25fadc5b488fb7365d366a0a32df1f02090f90d692c8cfe4a631de55495b51e4b17b973b33c7e3b841f84b5a0f88238d28a67b6796562b39e4011ee99273785685f063709e4aa375079ef26c27048b2aaa126c2ab431f045c897822d1245946ac693c32a8454b9cb3330ea39321dfa2bd52c54716e12122389693d33fb3a89a74fa689b5268fa711026dc3347ab9205233b882ac2aaff39db85b5d42ef3a801ce069aaf80b62e8ae87a959b887dfaf0941f9c81060089c19ac93a3a554a6dd8cbc7d05379a5fb3a8238176f0ee8a4c22427159b711dd9815220cbe7970f23141a42ab17f705014f31db3fa65b279ae44b91 +ciphertext = 15e1d3af26326b5981a96a276936c849a6b405c622908d5dbb53978fb74b0bbbab47521584ba18adc03e4a613821f2bb28ca6b3af1199bfad933c5837a43c58039cbb832a5c2e7473ba7eeca3c0fdf4f87113985dce8aacfeb14bc83bdb0f017713636ab316a7db14eec586eb9ca43c28b2fe0b8879c5d8f228dd2d4dfff67655b3b83cc3ee07bd37ab342567d94c42e9d0c5103d6052615a639f8b53c1c8cc2e170746904ca608625c0aacd61f06ab34087fab5fce1afd7036f3003109c43fab0d9924692a60888cae025f5a0a696bcaae60c06912d009c8536064d6a844822995b6abbb952cf9490b04cfa7f7c4f3fefc6b08de9b831025b7b7cc16c49e8fe1008116abb0968f002dc250ccf1b670475f1fc5c63ac3cdc0fb7f2e7193515aeba89a36228e9721455c7818871a9411c84b95e3b7a02f76b07a65b0123ed1ddba830e3843bdc2b18dfca49aab6fa6c7a480e60199ba95c7581dbd127b4c79809bcd1bf0d806e3fceb364eb481612fd3823484dee860c629c558b10ca9532750397153da40d9f18a37756140c5565db43a0c6e4f98d6c3a5864e661e1dc53d47f939f8d000547966957caff77bf5a5a3ac590a3e99ed2ae41b3f0d9445051dc82df74249a876e3a8714cbaf9fdd06adc6265c8782b7ec9c901e78a949081fbbac41f1aaccd090f2af5bdd81627b5aa4c729bec0599bfb403246d7a27926c72f085ff66a500acb4731f1dd6045d60f5faca4b23a70d8a261f3d11dd2363bd2c1818862e89ca70df62f98c9de2156d1e9cbb09aa256c826fb5db14f25dd0158b8e8e68c27fc3662e313813a68e93880f8974a4b84539ff29403718168ee8bfb53435b738ce9fc1a32d5f5e94cc81593fa6b1c9a740362e5c924f8c583371b912417de5fe62bba896038085ab7886f7b5f77c633e36b67b7a232362fa22e61e3ec0161ab5868fe461e26959571fb14d54410432450a8bb53585e6ca43816e5f8a4c298da6c3b96c2b8f9be915d5a83bfd7a40a533ee26c66702fbad55853b1d2a025823a506e31f0b427fe3b76b4ce4f32bd62af35e515c290f4808c9b05053ccece +expected_result = pass +expected_shared_secret = 67a9dc008bbfa1e906051d0ee14fc5d8100187c8779e275732cfe322b785aaa5 + +comment = Bit flipped ciphertext +private_key = d530a2c7b4302d5c352762434217129f5431fe980d73d486578b2b8dd761433844edd94bc4402f46ea7810d86ec1e03d7260510d4c5fa63469574950d0ca123ef4334301a6171423022a22aee97bc032bf3d9923f8a05bf4913966b736db533be64c138297bcf121677fe3c82305c84437648d117353d9a5fa231eee0998035986479c2a310069027bb94c7a822428bdaf219e0f9a3ee3b2b39d5a282f43be80787712c6bde09258a8bc542183bc3db99a2eec7bab4634b55930bfb432cb32c926b95b26b13bf7d01eb7f24c3f6001c8cb45d008ac18e946f7c5275ec31d1784b78c83562f821dca85bd72681777c7ad62b9602d01834652b997394dd0f257018470432c920146b71213606d101c1d8255cb95740801cdfa771aec4398546cbeb0e680ed37b880719cd3dcafe14ab161eb538bec5f34958d81f2293ec8c8fd13a6474237eea8cc2fd5c54be04582fc7538c7b877fa24c9f6b6683b83e4608a969623ab48aed803380d621566b696a1a98e78892d0ee7574bf84bb15b71a1ba312403aab076218306000f05596272272df88d8114aba15968c25ab3a53a1d9b97b61240c9f0f19ffd3a99e491c08b19749bac4b91e9248f833447a83cc8450dc195917b6c5b47e624d39663e1737b514abbae531faac3afc22ac7ab5145617b308999b37dfc01d6d8b18dc15ace18134a9162f59b19cfe87c0ee53467bb4582515d9dfb5879a7045125111f9b18e3ec6a132b7a40606dfbd447570141706c9fdd931e562c691e771161447ce7e718a88770ae941265263e7341cd8e0a7054306748361bfe71242792af9d44bfe6191dc0b659ddd655ea900f83a989a0d9256400cbb85467d7e7c3f4e58fdd83bcff23adc3013f294301a9f6a0250c8258b21457b67346190d00d8c30d8a54778b3544e9a4b5e41f308a9fca201dcd9631e0e9ab9439655ee401332b9a014382b0700f67d5525030be4692179d28ab2095a8f7ac4da28a0f0fac22cbb60e4445b1aa75509c3351276393c6d64d523a10f3439f0e124065773f5c707de387a17b8952f9a91739043b78bb600c1974ebe3aca2b748944c00d7182cee25a77616245cdb454d6c7c747554b31b282437aa0cf8a6a8a9b708a858a4d513d3273dec9a6a4ea38330aa9a4404b233bc87f8a409a099490fe11e7d6b48fb55893d898bade80fa660bfd20c3b1faa9148cacb60c171a1662fc4769b22f469f7655a4dc6b17c554b3f54ceb5e930d9508b830b58f661909d55c99420285fc29584379edf0057efb51e97865d56686ac2d90a03a456fd8c23f054101c5141a77a84caf112a8671b3fdcbc203338dd29beb3d315972635544c5b4d544e0c3385adc019fb529198c7023e6a7ef4b886edf1aee02090d0d931f0621e0b6b8b0f9686e37b38fe49bfe7a94512082dbd778b4d822036d0ac5680a599388015aa80ac5987ac6b40ba7714c3e23583923e411149b63cc916599a0ac287c0123fc00134ff8089c3eb802ce785522b87a560adf836a0c3c30d9f8b19433215a57416390479ef3449530c0958a1c80e71728b2c9601c9c62dcb14a2c445db7c07318cb8529b0bb21293396680f7b48b83351c4f93918f1a3636c0beba3c5cd77537573939cbb0a030c92b1d468bde343ec11c71fd6494e40964c35033f6f840004a7256eb1922f96245e43a9a707aa496417dc527a61932a88b5c2d43bf0bb178e7b64e9489397607cb9d20681dcace5802291939aafa49ae7b2241676bbb1218a501c31e72ac50b14a970e097980734ddf1954c3a3208eeb9174d9236e011def945152f39e1308bdf85946fc938a745b944fa089bda431c3c374bf11a34eb9bdd58bab361b0b1192320fc69fc1a2bc0ca75a32e1cdfed05f836800a229b3bc9965f1f27b14b040daa375ef3a3edad0603677814ca580b78c1150a717fcbbb939822e0a0a5117c2ac81c10bb8c289a0310d0407049b66039894ce8fa436d936c146c2380183af4f9b34225b5787dca08a556dfc176a34833286668ea59713edd357897abde3258ab1281d042bc6749ac55a549fa8ca6b140b412c8cc8373644b9908da472ab47b4c8d4d2ca53b36851f514a0f636dc664e472852e9437e5fd5604232a324d349c7079836980b8d3a71fb062803823197476ce4478a9a3ab44fd614af0edb50c2df14cf2c4f9fc86894077f337ab6fc03b5939070ec0f551737ddc16da73c668aab127ef22f9735f6da2d5c19ee47010a3f7cb00fc0a408580e733c7df01da42554a8257c6f91594e37f6f89bb834c278501fda8eabc6764c +ciphertext = 24fbf1b0117ba5c92fe46cf5ddcfa54488fb23d134e871f4b2a1ec69319b6da839748fe2a0376c9c99d06b0803529fe3c361dac33abbfc859dd219e031d169962016d1b377861b9bdf1b68571d3b34676df135b1daa2b94aeec60919b01c94fa4e6fbcf93a45c2833699843f1f8b395b40d031de19c36cbcdc05bd52e6cf890f10b80009fc36bd9d3bf66d43dc10de6a22bf0f3c010b2803c292d3ceec463b0086b2c8b9eade91028004d2dfa4b126e05ae1afa8bef3fe433b988c403edce429dd18a0dc052c6c55f933ac06640ec8ce0300f920bff57d111a36700ee59f477e86e8e5d2f19ef83dc3e6ddd6da652cd806feee3f0e5dd009ba8872c1006440d8bd0dd72869f1970773927baf97cb80a4eb58343a5e98d8924bcf4c2ad6b8e5eac37fe8c9197f24c8c5d8f3c7e34908586551652afb15a2aca0bfd1fa879e38fa3c4a72b70601cdaa59a7c5fdec945c680e90febe9ed95e1482f0f2d36797bb766a2a83c8236e1983f2bf0a2fa81803a5f4c2de236677479484223c34ae1594075b59ce1c2523fcc2652b56756f4c2a0d920692567542ef2cd96ed3dccdc330a3066eba0e43f7207a21e11a5f783a08a82085ee43d0a4b53c76ab945254ff6776e37cb64382b098da05d965220fe3d4d20b620ec9b83197e48ee66830f6e45db383ff3932a1dd8d1ba22c3298899ab2cfc2b64e523f9b273bca58338adda86457f2ab5f197d7968c56b8781a255fbdb68692f19f33edea566a785f17a91751eee35c456262a6a29be1b99ae6d8a15a940d1d36086e75569c745778113bf7ef245ada72e460062216e2fc5aa0009e69759baf9967ad559110cc27a0374f5cab6e9a3cd4403d5fbee9ab3e2f74d22ebb372555c2f299b4e449bcfffbc4a07592f8c3d45cb9832322c1628d4d38e17bf35bacb58c93a4d711c8e0085847332b8daa7fcc50da29b620cfe932f898e441bde846e679cdd73bedc323d732f21d0a575c24810c88ee930d241dbf89bebffd4f31b5853ae14f0703a8168c5e0e9e04e5e423bef7a0b46199f354b193174cb8262fb181486af62e68ddace2c68c68910ef4f +expected_result = pass +expected_shared_secret = b3853625cee2c0c83a7e8cc576363bc2a49c735841135e1862b3152013abf8fa + +comment = Bit flipped ciphertext +private_key = dc497345f66881f910b60a161aaa11f7a2569f04219396064e7708072c00b471c46c851c6238c3299308211b012f46789e659009228756f122554111ced3b9b2147c67401a537a3aea43cb56dcaaf9a089f8177f08d7a8f893ca5e368461317c15e95eb209162a430cf287a454650df6277fcd932840f60978372c93fbbeb422a2a40564886a6c52f0b05273ae33f84c484411094144d13671fbcc34f0dca3c5144deca257950cc9c5f81d73fb826318ad728780877c0668d97e57e29197745cc4806de8f13f0484a5c3555dc740029f84c4499298af646bdd609757f645335acb114bb919d4c0a0f045afa7a8e62791d93989dadab9608c1e38c8be4f35624533c27b6b7eac0b3b3127702ee575ebb58e06d8caff89b3ac38954d415783b99addfb85276744d5a00b050c97859ccb9cb31954e1a1135480d6b3692af6774e49bfbbc7210ec3064a36bda953964dac5b5769435f50c3c99cc30f7a8e6db111764ba38110ac65f79082f38ecc366c2e16b90b4113ce6313f5600520f08ab8657c742182b04504d24b0a58c86c664b5ecc742c02b879e4ea8a771a511ffc2c30e058ddf6bee98c5849041f4b66a7f1050b9ec7937c83aa498090852229c37b0680ca12bb9cbe0b3661b0b7664db663c97aba2695ab97446c82a68d7373389abc83425940a0283af037af0287cbf6e3507f1c5465d8a7a9e0036a1159f33c6266734eee611af88b735680b17fc2434eec72d5e57af9c3062b6390fc1b4005b2ca75a943347a7e25d673f7518e60811c3006a0488b9bb41a0f54f645ccb4891c320d5cc10087fb595146833d45781dc9a5ff223230982a3274168de09b6bd26dbbca0c4cf7a98869659fd09b51256a6b2ac5bac8450bb9054f19bb0b6b1cb39540b20005218b8214885ef9a51ade858aeea6c3abba228826a310185ff0091767882eccb98d5f2aa393141987630425c3c422449aafe7117c3123b3b73fe3a25be99cc91cac4db70252f615c34e3286e1bb8708e049c792b7ce9c5fce67a1409862487189deb19ebd9785e8e774ad2b05fb7a7bb85a3acfb44d86d5880dba975066c1e99a8b2f548a46baac022750e79541daaa6d12b4a4a15003453412ce733acd146fb1222d4b2cbf5b758ba195b22532736dc04e64cb6ed6a8365e0cc2dab00b60a7b4e6d89674594690540671012a103b942df2c33f458df3b706ed0c9d9bba41d563370e585f0e768745f73b3abb21a9d49d6684046b353db3ab5d95240051967786859af6f2a2affa657de0172f194882a382f9b2491488a42d893c508232f96369b9a8c5ed325ad1d74b6c77bcf0153b4a03027b796511e394a30c5d849a5dfae12268d55d29e226ef4a3690e9c620f96723c0450c82a6684ac9d4b771f900513221c6b9aa85efea1592fa412b66abee688998079d5406314958ab0cd298cf361e3925ada827a221e20e6d8c5dc12266a8e3231dd493d616b730714cbb1715f7fb938e670e2a299f49e7013036444334ccd7d2bbc7a8672fd7a614f1373aeac93e89ab50a815a925c1cb52618be6b28b6123bb35c919b34321b89ec7e5280ab50042eba97de8a17cea7dff979dcf759372a0c244b27e85c459b715c5cb5a7f3b29aafa1672b4601396745c6a0cc39155c2afe8c6b8307a716631e74716a41a9787292bb13ba58eeac8b7e77367b85fe1d330c98c3331211eefe333cc908a38c9069e71a494a341012c3058334e0e729d64a60bff280a870b3567233e94e37020e9725dfbcf26bb69a2db3f36b46eb54470b8588263c2af127b380a30a7eeca8b550b3a8a95301266a5f38816c1e40436f5797c757e7da091fee705ea1706b707a6eefabda1a528a18657e10525822a8597e13f76e3a970f50f2b968acfe21b67f35fe60aac23b6857b43095a4bcd06f872c12037d4764f31029c590332dddb3ba4b9947967987ea17477b613e848923948ba0f264e310ca808b5c4d15a7bded9cd5d139a25d05b2aa13fc4c609e0f22ab63c89cd585b34cba89e7b7663aa0a3f93140aa2aeaa3923e881913abca07b316bcda249b5a78574ca81b6506c9b18623d994be4785b05f07210602aff6a2ab3c7439889ca0a530903ba688a3a07086503349b665bf1a04e38855aea07d3b148c4192e8df506dc8386433aa509792de1ea6aff1666e4e32723a08c80bf058e2723f96d22a34093d556a1fb668de6c9155578d7b82508da00102ed7f0f0df322b1e448a0963c3345f8fd8c7ab9ea796bf2422857233e3646f9685dd602d983776774c1803c5fbae41bc8523a579dad0 +ciphertext = dfe9348abf2e7d17fd2d837cee035c54ba5bf370d88e00db9b76f89087ef98e7d3fb3b715005a03a445a084643342a3a96899355d8c4bfc952108db4e7820fc729085a093a58edcf4bc1b39253bc4657ef4246e1caa583f783787ee69ff8d8504a43e47f05e26ebc80a2b8b6d342af6bc8c4d66e59a6561fd7249ba79e36612079583c9ebbe3f61d917afe604c8037cbc404c6aadaabb872827f79a70aabc3c0fdb7aa94a6a040f632711244059f08e0c218150fb2d004288870b1116a1eb7c006a65e5a3049b506cd7d51b890d4e14b3c18089d205ca95e25ebaff26d1991c5a27983f152c8c055a04f38e8fc6d6a5c5b5c30db21df54e8bac9148f401bfc08015e207097e8a1478ced29728253a561e6016c9fde2572334aead7650b99850bbbe9e3a39c79c65ce49a871bf3f64a5933e9382da2bf2fb33a0bf8c8cd34e98943ed4bacf237360cc624fb893e3fc8be8a86eab73ddd8a2d964af425261cf1f6c3584ce10d1dd4623bde80e900d211fdbc731e64a72bad97cd4307fd0284c08bf17debf93c3501e92f90c77147c28e73eb667d850493038e4776e8fffdff3914a7a560a9c2409adebcd79a6ba735f39d73859942f8ff5fd9b1292b69d7a9e33e3973f982ea8ff456d32c3bd6cfdc7a4d4d8eaa083640f39f98ac07b36a07c2fbda9a36524e8dcd9cbe216b48b3c28fceb739a68efb6019785c8cc0c335c92f66297fdc880930ee5455596b834b0ded0de10540c71dce500180b7e754bc9707886511734c598ed72e9a9b0396d55420a0d8eec0bfa97e3479e8c446c187432598db5c7bf796b425a7253cc6626c4f4ab57e06a72f038732ec3e7722b688ff0397fcd3eb1669c4160db6f1d3cf46ecd1f74a7149c120b41c3b6e5e616ee07f8d1fbba595c2d08a15b662279669bc2cc6b8a32889ab5ddabbfd0e76aa7a5e21e1b68b6482183e24c49bb82ca466b5d4ec742e700ca45323d56fc3e44dd1c3c99bd09b18105e7c684657e61f8bf3dddaf985d64c7cb2732eab31a434e800a7e7021ce06a91043b19619304c5765202ac20197b4c08a587e38b65e45f8df5c6b1fdf5 +expected_result = pass +expected_shared_secret = 8c36341908f4ce9d24a46b930deb3a372d5a2c6156aebc591caf732c25e0e7eb + +comment = Bit flipped ciphertext +private_key = e4f05d89681b2c924eb7731d308a85e7771465f8ce1a731dd21583ae852bc08a0d28e31a13397fb9981ea24037b275b00fb52ce5ccbc0207860b1a30566833b4c19ee2bb6f4c195c5bf36a5bf86149e16325808f25b1560539016b971d8de1c7114431f95657bef10098459e3c35223de20ffaa6674c83ae399231d521abe8a53c5c4229bc614c0a2583349a10db35b8b3cc3107bbc6a461b0fd9cb9dec8956ab4192892412b17739f1a826af1a6a0d5b0051227cd5938d008b3a3902a2403353b761ae5bb64f4a18550203749252ccac17b97c74cbdd8312b665a1b12ca87c7b871dba4217ba224e4bcf5b697fa282973fb11a76babfe334a6a248a5da744d52850a183b184d948ac471de587590e1babc4dc3895ba76ae6c26ce2836e11482115b0bc710aa19bb5c53e06db97708fb1b857d07899bb550c8997af60373a27658164618cdb8b1bc38056ea1599de143b257457d0356635a8ddad0b7b02739b0811a5b1c212ba33bad9a04ebe9c890a6754accb4ac1a0303065039890ad4e96e2aa14fd0e242e9b01a84a69972d67571e4584d3364bc9b414c909604c21a6efabbabe2144c7a23c6a00e67e67e69eaccf6381774203b68c7bfee054636965a8e283b4c04295b1b0a9abc14c2f44f08d16a129bc8d4141734b55cc0852c0805510956bfdd0a09719aa255f6ba66927662406506798db4ec6ca829bfc4eba38b57681c0836aa58865209098504819ec01cfd607faab229c087ae66b29340f351a8e83becac0410b79b0b7769bf30369b3c1352f39db6297969468dae56377d7256dbe59addd2b8f2309811727bf056955232c254acad1c210521632235b2480e7012323c6063317250a69c75b34bf0455db03945a8e1510a48304525abac322ae4ab2f6e28c255049b34080311ba37b1617b6f5113cdc236552049bf2b5189341408d5742693308adb300cb4759f0ad047e40045ba80cf271c5f13b0b14346eb81ba795c7b7f99b0c789b0bd7cbb108c4034b494960cb6677a1f7334598e8c0a0aba2b6bcb6a596ab9a01c5417f627fa027eac3a97a38a64b7c53831c3548d8a6ba6f8a27ec130c078c084a8bc6e4cbba4d5c1f46569b11786d8ccc59ea3b0e4c0cc9dd8b89ca4c0545646a0d16dff7b75cc37c6675821f566937cc6aa36354b462a797e49988b7700765b13f7f4b1c6469febe3ce60289319b200c8485d5604af7e3b6eee1433a397c1bbf93a65f9a58af6a279376cd168773011c957c5869cd1a495fb8725c6536f105008e819c9739b7aa9498c607965a06dea5175f3f1860a881c0eca39701858edd2bd2a95a4a88b67ba0054e5e5bb94e46d377a157bf5353d73c0589077190c8cea10cd2f42068be080b3f17e0cd370bc35c5632410b9d5b0a226bc0fba3782099280083b2bea7da96713ccdab87064a4a24560484561cea6ac37b81d032b18ac99919ac45f9ff3c99db1435cb0044c16956e4652b9d94d33632d8dcc958724757a027dc1ea1830a9cd33e032c240c7587b459c253066492143158506619da327a7733621c80c26936c8e9665ba864b9cbe7378c3dbad992c68285b879d2b0b7913b10eec7d0fa762f4a40f0c292845a23c918c6e09595b8bc376a337824cf6044ad38ba0770daba898b59271be0380b097c9db8a4d5bf44dfd532c3ea46ef0b35ee1aa232828bddf5245fe44223a180978fb4bd6a1c56103ca9de9177d7c61e35338a17b62cd1c0aefb7879865b8615155b49c3212b67d361b95092c3ce4806d3669c19f576e6d9027150167e61b54370b66b8c7b52968c5a3eb50929478a5474445b98e08391c92e0046fe9b2fd023530787025137c49d23c1d97ac124a0c8dbc3f839c08e6273fb4479e80e1ba988c8b1b8cccb029a247d008b7dc7c1c7b9c2530676dc62bf812436e966cd8e21e921ac6a583366c486979da1f5a67c8e5f00a02d2523a0a5855683828db54f3489cbc3a7a403b54275a9ca106add1ca9cf582b5b1daafa1248ab0d1b51b54242bcc6b5cca49d768b341606280961902bb56d9f090b5782f58578b25b2b4397aaa9758afc21636cfa5c45df37ba6db2612e27839ecb5028ba5e126b659d496f7fc00b3c9296eda941970c1c9ec39d3538c99671198b2be25d62b6a34a9807930d03a0663a1800bf45d6fc5953d1a0f8f11742e69777aa6c645e38060558be189716d7f7e26fc4bcf2dff44c052f918230f112860ea0033ec899fa1e30c1b902c4b8b7c044786179a609d33f08062a62cf66b8e51dc742e4cf40e7e34a35fc318d9a4e68e7bc0cd154c +ciphertext = c4b0b83896d450da4ec0e29ee9517497303235c3be93cf5d232636b5fdeef92789bb4c3bb62e6abea8986ed3bdeaa9979cadc9048497bd3637b0fb91a24340ab26983f1ae9aa7d7d4ef39e7d1513abdfdff67b6d46c999dbefbb57fa7ebaf54e346796ccd29037ae6f954451144f36eb0e9cebce6eb73cfc03dff6edbb965ade552926294eaa1b6d386db8d3782f7a96690087628df103d666e196abee1153461eb6fc36621491b4f6e10d797046876545dc66026561044ce92130f9e444061fd330d3edff63e2b9e672e7aa2abf698fb01adc7dcc56815cee85a708e44150a5cdaa23e6d072472f87674a0c4c8fc6844622fa3f9606ec96e30ff5e4277d8cfb9251c9fcba2d524e29f19fb61378c5bd1f322da4b91e0a6de577a6d23e7fdcf1971d820cb008b383a40a79276251525b16befb423fcfc0f4647ecbfbafaaae3cbfae672ea44f2f2f920922c59e4737aa2e4db75fb11a52b728310cc54afee49243fcada2e1fa598eb6abd5272918ce2e1501c1669e7393cae59d65214151d21102f2c42cce374719df06ae0b21478e5ee54857ebfba66ce947258257f509f4802f8daa1ff2d8f0e18255a719eea698c47864854e9f6d3f0b613ce6a8a3f124184d488973e2cf1128bc4393a122e1acffb5b6fd5684653a684e63d691bde134c1696792e7921f436f59febbdf1840c31cf22b81803b42e29c7097893f6327248a80a8490c5968690898fef2afc3ff84ea7d8da7ab5e13a6bf2273273681c973084931862878d531f94537129a5bc0ee140f7279eaa6316ab304ba13e326b75da6c7f5b814aae40c0269ff2e4016ca478a0d7fe987983a574a93fdeb03b0c420d44a2b9c849a3617fe1b8fb1fc209e4c946abda8af5540ead0ffacb0b2437e4b2c7c202e39a8ea4e74320c90d5d066bfe69e9bb9019ea2225978bf8faa811e782f441685126c9db5ec123eac0d66cbb280a298e83f8ee425adfb012dfef93bb4ccec12dcaef8b96f8de97d999eebbdae11346d0dce3be10cb0d9640d83ea990aa4049375b631a32100d0129bb3259a6ddf9cd866199cc6d3b8442a999b251923a5 +expected_result = pass +expected_shared_secret = 85c5aaccb534d7994f7e4a90d60a0060f9f06bfb58d786cb5982c2fa0159188a + +comment = message all 0xff +private_key = 2df77d8dc45e46658a6ce38f788a0caa38ad189979535335a91825c72a6ddd048c60a2beb9bc48b781054c4c0ed73630b6e9b83081970a464b234a44969a0c51c90c411a11ca51bc278c450c462ba7b904950b5f8414257cbb1efd6048cab91e98b5573b3ba2e894545f873bb0a07f9953693d892689bcae9dfc2cb149522ac31052e23e07134d174967ee37c6b580afb4617ec05cce41a138b7ec37602a0c7170c9b5e3b32ad5a439a0c40ef36dff454c785913d384ac2ac41ea2a34bdfcba95ec71263c0ca70a75f9e8b6b5078420f7acaa69c18b79a8c04962005f2b82bac6d259c4e48d3c2f4f375efb18cd8571d43db8300a70ae1b888f5550bc6153892080757b53a13f03b55c86c6ef85d100711cee36d835b9459032f9a1641175b8f51ba6f06e09b4b337ffb51cf61a6add0000eb7b4c51d991cd3ec01c6e513ef24b122081849138330590664fc551294bf3dc5bb747b00a3cc172293745599403912caf46450bcd85fce1c5c01ca394531cba0d281b3350c37315feacc93dc867af1f28ffb902c7eb98195ba74a9aab043561625c001df0030e4e2474f4214ba670f345932d7515fddb283d4b6c280403d39182e7d4bcb203842f338ab9e33bdc7637ef45bca8fdb1274330ba68582204b74759709f349ce75e9a55e29cb5cfa89ab738c33391c39a94ba8c0b4812abdfd55138c501a2ec1aa28f08c915914f1cc49a09c7dd9630e75ab8decd39d6f77425a8b82933c4747d09c24d78620d8c2793510963128de37c466bccee71a4f6652308d746850b95f786bbe05d8ad0d5c775295339e0150ff3895463318fa62ca286478e801704cc81129e8cc1f0596ea860965809a8fe3c01f53336e7a3f12c28de39782db2ab62b22102693062a44830cabcf7f659ddb3a54a26cce5710894cf2621a6c81d0454d2d9254517500e81654c972812e5476be1985abc6cb1ae86385fb645bf45211d63480d27086142a722aafd2c71b2160c9af51b80d147cd3667466978998c21af03020cc8ca55b89cd2f3ca593b6aa2240c921b1255452338cbc6f28d7baa7abc6b5a8bfa353ab320a405abcb842ba8d0ed57b6910c9ca85b2ccb18cafc0341434ab81e8479b116b60e74c11da4b39104c4cc39e4ad966008106818ac604a02c5ad24531a550898080fea41b1d64329d3c7da7ec2bb5d11574a567960c724fb1c8d10b4ad557cdb0a2431877b6d745bb8978526445405bd64878953f85a634dcb03e21351724c4acc2176e5599377e155211856a3c74362e04b9d76671ed8ccb45d4a2bbb205f646b34ef73a4bc40260842b1037044140a425980ea16c0f5bb49615f95c7a234e65356c28a7bcfa250315bc770d883b2d5b266ae1a8c5bac78cf59d34e00de4d84e5c6389617125e1d19590fa3d68c718a1aa9791d95333a119278879c382b521255e1c4a77ecf5a8a4e35dab07100fb551c7b13dc9830e0cccae0317ad8971325353a570168ccd525104549f7d18ae9f46b512a53e741940af051f9dd6693b5a3bd1a217ffec8e8b85bc4a64b17514b9677249dba21cfa5a736de7136be852668a1972fb1a180b1f16a22e2852081765ca3ce89094e7ccf785680158cdd2b4570c52b920e28edb11a6b3e0a5547c4ff7f463b1dcc565b06a47aab3528c9a4c6413df1112e5c9cc414978647195ddc5550da2782ad7370cd631d0034cf90007821b7791776a75f6bc345b9b90902a6c946aea1ca07f816d16a75131c879f3c81c1582513092ce0b560203f1cc011c670e750e9a1196b59bb554a29c02a250037c79613626772b5705d59819b9840f8765c008b69490673b33862ea24d82dccd5fd3b7f6925dbeb26f3bb4c46442aebd601981396fab425e6b45063d0c5814d74b90720f3ea553d85c0b3107478a3616fcf82b4107d073cc2f01e64f18e579da0a8d9cd0bdebd7667bda6c643013b9d81967d82987395d28b09a54b0169c5b3e64c208a7336b06eca9b019809b3417eb553e01056fd5db53d5447e746b7413eba726dc0c2423214fa31834f15971e56715881073f0bda38b92c7a7365a137482a820fbe83c2bb70f885718ac724c6ae19c159b323a9bc2dab5a2fa36033a01aac21829e8958362f829dce5bca31acf7133ad9a69cbe2202332a6309d275f1a23cd5fa972f88b84766db93c273f1fa87dac67206272fcf6223a555f607f08c7dd15c8305b481d388a3775d703c253bdb233721b0d5f33d6408d693a46f85769ad30e664a3b868b797677ed1458d10d8eec8f1c8ef8fd52b48428f0cb0c29644ac8e2183a5 +ciphertext = 26b0457cdbbed13a08372efda7a49af8d96e614333b3ca5d83c9c44514703637a5dc66ca1cd6583106f90b8ccbeaa3ef98c536171990a07eea563fd95319ad845df09542e7a4afaaac5448a83fff15980b6d62bcb3931f1f92b3f85be03930c54802267d780ffd1f3ecd6e78626e469237d9de8e30e13ed12ebcc8d9a1af01b8ffbdd7534202e7e1d198fc953ebf3178e5d00a588ed7a06f27d0ae448653de96661957b2af277d0ce8be22cf9586e85b09fcee775b9ab5c03c0ec65b8fd254bf28498306fa49d8c1dcbb80472c424c65a0720a2bd60b2758eb270016c624ddca27224c7575a7823e712552f81759277f4112883bcd264a07dd44eb66ccdcc74e877802e06e28c3c6253c65ac734177e465b740727c73238131b2d9c070f365ab2caaf9b4f38c09b08c12b1e361766001f007c306a813948d4ae1567a1eb126e66e67386c78934ef12d289d9fc6031c4e43a8539ae34a0dae586b4456f801f692b9f860db5e068cabad765c167c25b2b5cbf7a53ed2728e8524069bf48ee3e2dadba1b7068571e67922bc1e8821f7f7e7292de613e50f56a8ebe99d6da1479ec9f426010fda3bd36c3684f50b26e973f0354f5372d9c34059e284386ed70ae0ab358384b60c2cc778bc42e81af2a264e282c183756284b16c041f7938f674f4fd3d765f00aa6603a85f617de5b96228e41ba6d6b3df3200fc0d44b7855c2cd217bf494524dddff102d3b87716e77d5a9f1cc09703f6fe22fb7b409394b75e3fef8e01ba91056d1ed7e52ea1eabfde4c249503271e358894e15c8cf3bbbb7324a0c5a33b9c994f8750ac538d84a96ab352e872e8524199282509357ca420c3931f92de8839127d0bf79351bb9def6c588d91982dcf09b6747b8b7f542a640a8646cf37a452b6a2639f4141f7dce43fb5235bdf41bde40f00d31ecb14e81ef8063563508bba5c0a3eea9caa7ae2e20d7bf759c87b0889e94c7a1802a37bdd6d237cd9eb58f5363ee2ac1e0ed1de106ea634fce059f21195c368b9f0b238283484da23dee1087d61a4b623e90485921834f202595d0666cc8fc91a997ce5ce30aa9b +expected_result = pass +expected_shared_secret = 016dd621c5218d3399dd3249f832065040406a9fb611ba2cc2b8beb31f6d5e28 + +comment = ciphertext secret and error zero +private_key = 2df77d8dc45e46658a6ce38f788a0caa38ad189979535335a91825c72a6ddd048c60a2beb9bc48b781054c4c0ed73630b6e9b83081970a464b234a44969a0c51c90c411a11ca51bc278c450c462ba7b904950b5f8414257cbb1efd6048cab91e98b5573b3ba2e894545f873bb0a07f9953693d892689bcae9dfc2cb149522ac31052e23e07134d174967ee37c6b580afb4617ec05cce41a138b7ec37602a0c7170c9b5e3b32ad5a439a0c40ef36dff454c785913d384ac2ac41ea2a34bdfcba95ec71263c0ca70a75f9e8b6b5078420f7acaa69c18b79a8c04962005f2b82bac6d259c4e48d3c2f4f375efb18cd8571d43db8300a70ae1b888f5550bc6153892080757b53a13f03b55c86c6ef85d100711cee36d835b9459032f9a1641175b8f51ba6f06e09b4b337ffb51cf61a6add0000eb7b4c51d991cd3ec01c6e513ef24b122081849138330590664fc551294bf3dc5bb747b00a3cc172293745599403912caf46450bcd85fce1c5c01ca394531cba0d281b3350c37315feacc93dc867af1f28ffb902c7eb98195ba74a9aab043561625c001df0030e4e2474f4214ba670f345932d7515fddb283d4b6c280403d39182e7d4bcb203842f338ab9e33bdc7637ef45bca8fdb1274330ba68582204b74759709f349ce75e9a55e29cb5cfa89ab738c33391c39a94ba8c0b4812abdfd55138c501a2ec1aa28f08c915914f1cc49a09c7dd9630e75ab8decd39d6f77425a8b82933c4747d09c24d78620d8c2793510963128de37c466bccee71a4f6652308d746850b95f786bbe05d8ad0d5c775295339e0150ff3895463318fa62ca286478e801704cc81129e8cc1f0596ea860965809a8fe3c01f53336e7a3f12c28de39782db2ab62b22102693062a44830cabcf7f659ddb3a54a26cce5710894cf2621a6c81d0454d2d9254517500e81654c972812e5476be1985abc6cb1ae86385fb645bf45211d63480d27086142a722aafd2c71b2160c9af51b80d147cd3667466978998c21af03020cc8ca55b89cd2f3ca593b6aa2240c921b1255452338cbc6f28d7baa7abc6b5a8bfa353ab320a405abcb842ba8d0ed57b6910c9ca85b2ccb18cafc0341434ab81e8479b116b60e74c11da4b39104c4cc39e4ad966008106818ac604a02c5ad24531a550898080fea41b1d64329d3c7da7ec2bb5d11574a567960c724fb1c8d10b4ad557cdb0a2431877b6d745bb8978526445405bd64878953f85a634dcb03e21351724c4acc2176e5599377e155211856a3c74362e04b9d76671ed8ccb45d4a2bbb205f646b34ef73a4bc40260842b1037044140a425980ea16c0f5bb49615f95c7a234e65356c28a7bcfa250315bc770d883b2d5b266ae1a8c5bac78cf59d34e00de4d84e5c6389617125e1d19590fa3d68c718a1aa9791d95333a119278879c382b521255e1c4a77ecf5a8a4e35dab07100fb551c7b13dc9830e0cccae0317ad8971325353a570168ccd525104549f7d18ae9f46b512a53e741940af051f9dd6693b5a3bd1a217ffec8e8b85bc4a64b17514b9677249dba21cfa5a736de7136be852668a1972fb1a180b1f16a22e2852081765ca3ce89094e7ccf785680158cdd2b4570c52b920e28edb11a6b3e0a5547c4ff7f463b1dcc565b06a47aab3528c9a4c6413df1112e5c9cc414978647195ddc5550da2782ad7370cd631d0034cf90007821b7791776a75f6bc345b9b90902a6c946aea1ca07f816d16a75131c879f3c81c1582513092ce0b560203f1cc011c670e750e9a1196b59bb554a29c02a250037c79613626772b5705d59819b9840f8765c008b69490673b33862ea24d82dccd5fd3b7f6925dbeb26f3bb4c46442aebd601981396fab425e6b45063d0c5814d74b90720f3ea553d85c0b3107478a3616fcf82b4107d073cc2f01e64f18e579da0a8d9cd0bdebd7667bda6c643013b9d81967d82987395d28b09a54b0169c5b3e64c208a7336b06eca9b019809b3417eb553e01056fd5db53d5447e746b7413eba726dc0c2423214fa31834f15971e56715881073f0bda38b92c7a7365a137482a820fbe83c2bb70f885718ac724c6ae19c159b323a9bc2dab5a2fa36033a01aac21829e8958362f829dce5bca31acf7133ad9a69cbe2202332a6309d275f1a23cd5fa972f88b84766db93c273f1fa87dac67206272fcf6223a555f607f08c7dd15c8305b481d388a3775d703c253bdb233721b0d5f33d6408d693a46f85769ad30e664a3b868b797677ed1458d10d8eec8f1c8ef8fd52b48428f0cb0c29644ac8e2183a5 +ciphertext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000800808800880080080088888000000000000008808080800808080008888888880880880080088088080000008880080008080888088888888088800888000088000880080000088888808000080888880000800880008888880880800888800800088880880008888800000880800888880888000008008008880008 +expected_result = pass +expected_shared_secret = 71e0c701fef1d74d05639704dcad3f0de628bc8238fa7da26d20fa6356581a97 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 13b21ddd6a8ff0259d2229745969188032c7d4506c75d27340079c57e5c41cf374e7671daf33619a11aaa489776f1b36825a839f14158df46ceabb26a02b92a920424f39601758321ea584f9f0442493c168866c55d6ba5af9704dc36371c31852428537a3a68e9030c19895bd2385acb088048752b65a3f1ea25b539635f113a1139a52b9c819b3e05505bc0ccb8570ab48163af4169ddb9b93848494a2cd4a206051f92d3c6a0192714307d228de792cf3109c29267eeea9cd2ed9bf3244bb455a0a58514efcc8190a5973c33963ac753c6bf7c5c5c36c65cc681d433ee048536e3288b8aab6f00c3c6d28b8f325bd838b7643131ea2bab3aca0b1e0d2afb4ea69aed00c4f1061efa259995407ad9583fdc337739152d6bcc74f4185d56520b67818926c5354470bfce881d535979a312cd05719a6e48a262198d441514f600cb804d0012b5632ccc337f155021853b74c34eb950d60bc63b1d868f4945d018b4c37fa77dcc762c62618a3ac29ccea150fcb77ee0b2a925c1e0dc718ed4019507842ed7a40bbc083bd9170724b0386a1c262096119870e35f791381b381d91ab2284a24a9c4759ecad48b15e3171bc3a117482f6148dfb7c005d39ce411066c23e076c90f0eb8ab227c162535e46d364b8f379b916bf462ba2235bcd68319ea5e7a115731153458a831751f98b9822ea43a28728b2b3bdf1ba59011167e221bf79303f15f5c1cf473fa42b0af5f5970dd40c70752f9ae27daf137d38b299f7a6b1e4a3821274199b617cf3b78d272724eb09b302aa382f9019d8d395a0361b7a7118bc125dca6aad29b01ae2839c6a6bb7c594507e8ccea16c8cb33a1262686c052a703f074201d57c38d11dc432c7dd25cb6629167599991a52b5c7b49766f07527bc8003dc27b65b2fd43c5f9a258873b36ba516538771744dc2706004817c4c9d86c554a4ea9af16a78bcb31e6941778c837edbc60470d9025e55508d9829bd4701a2c6b514aba1b4b8759cda898f289cd31c1267eb0e2d7233e5a22c435275f3227a7c67937b147fec106c5e2798ad3ca3d9755e37e21297e8bd942cc2bb46cb622988f1d70ebbdb760f498fece49012b73d71e49866ec780cc83005cc252da512e3c5b43997b29470c6827a729e6acced8a214832915bfb629b83a1f477c835c29ce0e175847a63a1a69870c4adc264663b896b0e7b984871c2c8802f7380cd3c754c8371c33ec82d2d7518ec2638326aca9e0a9bec2abf68ca70390bc2dd2aa691a502f9c0ba9a829ba89925b69a13a6ba5d2390117809887b51b7fcc6c5af31c464cc17e81221813a837562a15a0ac9c81c289689890ccb6635f15d23bbb4ec248a3ebc86bc9b283b5a3460d3a06ca326b519091095836eca075fd6392402955da84fe7538cc18763a91a2df2790039d464b7750250d9b93e774cc656bddcf3c17c7b8820db883e8331a0003de25825bd0176cb3c4051a384b687309421acd0bb8bd2ec6a422a5d6509958eb25a5bc1ba3ee43b5453c53ad7776021b19e2a5b1f553b36134cf3421951cc5645d74813565f3d8b6e83d3607ef5751d09ce8fba792865231d60c82cd78ccd26001ed1b3b0378c87131b0cd3a389b963cc01b8b4255a31522a4c83b8706a7c1981b555730804836a730b45cee7853f771869306896d8c94fd261d057b48a17327fd8634eb77823239f623ac3d4d38a1b1b0d36736aa7f28250912ff5a710ed4776be53c264d687a9a1bd3c0b99453742bc4554fba93841ea2fdae6214f49090a24b93cc287e1c322a1298bfeb21313fa4367b84d928c1d6c1923991341429b3d6a59c3d0721f474c753c3093809bc8894b63f747b2d34a219923467464698e595131e3606a5812ef08351ef931679bb5a36a6fe547a103401c7634a7790283f4db6d15bac3cf81389cc23b74302d7b61389198ca7241870fc351ef159b894c50f93cb24c945bbb70306f1a7a0c5063d642433f852b3ef6c227d2b49c9a4c72ab21aae567c9bc6d93817a6161c12d6200d6a08afc1325a7da9a3782b8191aa5d6f30751d01c6af308b2c06c92084e4086c4f3e306e9d5cd82fc151a700bb066c4f97191a46833b8ac55fce41200772450e826b8e5985d830610fb44f216aae0e889de6857db4a0d4b8479a1800f92fba629a6cf40d7000000000000000000000000000000000000000000000000000000985e2d6a61d4bdba8dcf18c61c9aaf72ab60387eccfc3459a44338d757bf625f11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 0373e3220dc1941e80274f0a09399217246a31b8c86d795898ded46c6e26ce70ca710c80bdcf59b03b2ac1eb66ca6ac9175de57a8fe5b570452413ab628fb9105c8ef8852ee2e012a6c4c1eb6a7fb4e03357c6264b3b9762f10d5be97c340c69218b6b24d61d0c3c411171f22554ac6ea09748cc8585e19c1dfdb6ad7a85f6e264cf9173d9770ee0f6f89391121deb2179bf4a0656575e9a826895d20483285d8b6848705c27762cb9e84bff2c46dc3f978760a68daa900f148c9b2a415e589cf43eb94a8c7a6727facd6c880c9b76dd0b842a9e44b60ec3247602c2e213663d9fdda2e8be79736d2c3ea81f4f875758c56c0af1c6786b3eb6f3710fd276eafce95e0126af288e9d2c12425bca463173bd1bc0b3179383093324e94d5227bcf7b2c37218936b9aecfc6203ad7b868849c56e973adc639b8c116350599891beffdf266c4a4399f970ef41dd15971cc7c385041ef75569aaa7c0acb8d91584bd179ea207febf5839d63c579ad3dd901f4e8b1be181357f01e6060b748002c11a91efa0fdafe81dab1997b761438f91a89187656b2a9be93705677e25c0f99c7660d6cea743dfdf94b3fe9c3755052fff1c2a1e73ee17ffa8ed511e7e8f4d4975f33f694120195eef6408c5ed0fda03ba5358018f0bbb7fe5de78bc7d529e1005620f33183a2cd5a0300f177d7e5bd68a828f97289e2ce23b5cfd5797fe16dc98a5144ea1d326c6d15d2a34c187c172e32e4eb4a039b07825d57d52f8340e8d0d56c02215b2e074e39ac6905d4141c85a2c18c8a63f52a295ed3991c65579f483d46b617148cc2f03db0a25d7a8a9f3874fceefb91b87179025041ddabb11de036f290998c4ea44cca99d36d128a4b1d256fb143d63601583e594fd2537be8079b130223150d8f20b8a325835f324767eba245f4404253b4dc1675476eb80673664d1d6787f83e29e58ba926a062167167ad282825991e217810106bb2373cf75e9766e7f2857cd18815bc3f27a12213fc6481e778a71549382bad377eee688a9895b4ecceb58dcdcf0d6e7b53565cb54e7075cabb8d90278f7c4c884b0ec97a259 +expected_result = pass +expected_shared_secret = 913c02c8ef9cb48a557ba63dd5cdf32125be245f769222bce624e5976d294eaf + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cd28b1e3714f3c797340840f40817791d502671640aecaa4f91089ce4049fbca7b7045b350d36eeb13761605aa4dd87e4d062a5486c5d73367073a0a949bb0852956dbbc3bcb40920d89518dba5320dbaca890ccfca8059539505e3c8ecf80cf404c78b262abf1ca439e132ec99c33328860df5523e2f63232b39d83574ee631591f6cb617268a0b5344d2aa003e4000e821734c8922706bc6b9a9542f993920451bbd131176087d6e53663d46823d5a1da3723149943b6f5c34776a8e7e142fe63b50b6ea600cb859672b57bb07678382a561097dc38740474b60f61656f1331fcf7824004c4300f81fb9bc457f97687c6215440486d04470096b1b5fb1c5c77063fd36254c6464f19a96a8a76644a12663361a36d37e6e08bc76743f812448a8542d037b2bd483214b500ba1c07580b44e6d9093d3842df52c92ac8011f207106c069f7e3bccf06106770a04275231d71c5d1a516d6dac6e362397fa348bd49a5aeae37e6495aa1af2084a42c433756461608ba82534567854dde95efe0335d67a4b37b587abb050bbb999c2e65feea4c89d4560402318f8d89afc7601cf1cc6c663c44a85147e7b4ed39b41e6165b27bb1366776c409b01b0a9ca1e958063ea65f43cc8e7a4b06ea338bfc249e7d2bc150a8595500900f64e1a346fc0e5bac6179c505867f0617baec402229a4c00b267fe479d6e3b34e172c800a45bd0f39177083fd0d15e8912498e6818bddc3084c12d042cb9f2448a0d450b3dbb5eb6968179469998c4a54e7692a7a78fc96998d3844602002de81052e84bb64b693485157f15b054d16a5ab0c593e0118f7745244ffc2b57f939f0845b038832bf4a6d99123a5b95b73044ab6788c000143111065ee4cb9550d06e34b81e70641dc5905faac129662733214b866439937d39b22cfbc203f809d265158f02b7c1a762dce060aaa1117aaa9b002aa0f19a68ba5559bfcb5285a29dc8989ac0ca9e21019311abaa89b5730864817227c0a9d56d15c950453537faec9a9e6c113a023a0a14161bf3ab062c2f9a79a6c7142129bbc80539b785464aa10aab8b5336aee10d7a4741cc16803424af39d20428f7c0d0d80e5461cc46e04bf2f70cdcd1799a2179798acf8d91790b21a634205b7bd75bdc76336251c512886573a053da25afc0002f75d67e4dfc3f0a040a9d4a5cf2b99c1a75805c0007658c58813cab07b62e0c9a05bc1c14f79852b12a89b2c17105c8a6a3ea71daea6a895084a6f2372c76971972bfbe730464285d8ae1cacc5a8f75709a9f343a68e0bc4e994c0a955c25074a27277972bc45bf82125468105d308bc0786ae39c77cb7971c053a1bdd74204eb4f74e876baec8e7ce2c8abba8d23253628f944b0f77534e56ca0884701291918d2af5cf678c7635b2f981e75ac2ba7f7906af87819b63906eb85d551a89bd79d9762664e2b2a81f52b64e907c869cd6f18b88d5b2ff4471d7dd6b4378aabe61337f108aed1f267b275af7746be9d899f126c1b4d096c09a113dd3b1785737e9a2b6040a53904439a95347bf845c45123b73ba22c9a988b19bac9b6c476621196ba0c674f91629aba905871c1dc87ac10ab8806dc65fd27a493d46d9db3ccfd567719280dd8c2a11f8414dd9c4d27064be7862938d3201bf10e5367248169b4e32a547dd44a51b8b9ebba078e05be937c35fac824a606b76d6176fb0037efea11b8625705f8046515b8813b786a7c6c0070a9a13171649c3a019c7db6cc365e49427c3c4ed06bccf12144d77b111a2561b31a0ce28408c54a895ff2b49fa76d88c9b97c0678b5c8a5e912447a3b303167bc473330a24a539c9780d19a3d530440c5344018497d545c48206268f3fc03f1631be9d6143bc77f47fa14b803cb23050c62b06bf699a6a93336f2d62e6ac2bbada62e2c552e98d87432a3561c28b9f5d5034f67723cb7509f06973874c0c889b531f4ae3aa23cee94668ad00b5a10902167b1d09cc702b08a65b21d4f7bbe7d87b549a2c0b58235f8a9b8d8f97a0ee8cf45570355763bf3422f4f6b8730f68fe0c8656a608906d4936b7924adcb6b4388541f061e994b0c03a6c7cf219d81b7abaf2b4b23d25a66f8adf4431413868e8df526b296ad928a0c8aa030e1558aba0139b52a8c139180c0d582bc06cf41cd0933ae0000000000000000000000000000000000000000000000000000009d65c12138f013e0d66e4d0a9a4cb9b34a28d99dd1f113be4ffd151514c194312e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = 1c11f6178a09f65f8ebef2e29b90343c48f646e3a0badf3893c067fd3977f40baaca92f107a1d604f1ec9af888b108420851f22893e252525cc7fc2468f860cf9279c8ded10dfb044e186790aa919c98a108003726154025851988118bee7e2de6bfadb77190ebfc2065ec6ed7693a7e97bb1ceedfb00841030fa5fd950fb9b2652c0668bae0b587aec5d1aa3829fc794546bd2b708ef850dff44adc77832251b6fb78c7fbd207c9180e3d691080fedc44eee5d9582600d855be0f3a49e330136fb2acb5ae5452fca54dabef3ed5c5254ae475217993c75d106c337966d0f702d1857259538c8ce89c3b0d615c500106ee665e2b3f1177ad5a076171ff7f3f9770a09c66595f55af51877124ac0c5e46b09d43e404344e4eef255a9fa146bed156433fc3e4830143b585001307c92f324111bf3a3c21cc035e1e698497c025f721e03f18c69a0f4c00d8d19821b120a0e3245c7a30076eda174c701861c62874ca60a1c5408ad5993ec77deb8c5b34be816d272f384a92c1ead0482e6e3a9646e113af5ebc546d90146a26c56c7a28d5a7fe9f6a2bcd90432469c11b91ef79217ecef2c3383b5f0c46bb1349d02c7fc8ccbd5a695ed2563722e6b4fd522018e6b801809b01dc50b77da143b89a7c075c28642624129aa1dfcde0391c296aea560bbf792115a73ff0ee1ca899341e10eb267ffb819941fffbb5d6ab3a878fe10c9dcccc595bb9644c95ae8b954b6529d786a9dbadfd0d8464f794020753fac1fc57a96405555ed458075dbb39414d3693523e3234f38a1b63e2c4ff1e26afb38bc42fc239af6f64248ba0c853d79717e70033120daa668c2736d3987ab33f297922a4738f9924d2508ae0d50111651987e13739916f58d8c7a5c18d9f7efa0a72190d7d8d8ba9e53bbc1102387e4271c7d320663f83c98b0c0530934fa1c13819e28e68c20b120137af463fb4540986b721f95b35923603f311ce991a7dd2b6cdf4593399a87ef9e72690726eb7def8ef0b5a811e952f54df1af4d13133eafb9b146653e8544fe664659032389b130ba8cd8242d9bd3b8d10d473657c6bc217e4 +expected_result = pass +expected_shared_secret = 4db7174b795d2f909c71406bc69437f5ce58cb0d0bea33a60b5102afd4f57d9a + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 2db0097b4a8afe74111d4b78f8c9a8a6ecbdf4627c00f562b7835f78557e5c3a89cbe1b59d6c019ab574e5ba6951f926f4b274e459260755b4e536513e49607c0a63e718b247d7b5dc91abf1e09d87dabf67641dd3abc47c2a1bff35a17d0cad8a1345d08021149cc5b1c914caeb780b6b865029960ed3af31e976a35c5d2ea8194b875151d52131060c71b660016984810b6ebb31392f9b9b8335adda6199b6438eaa48b1c704c0ebdac2f903051482b3d1d4a97e73779452564b7c9bd2a081dbcc6736e89d1ac7a96518a0851995a8842608386d1eb4bbadac4e70487b05680034f21cf16100b349c356a01c22f45d6585bdaef528375c052ba029ff48156e578915d953413647b5f037ce83aba554c263a3374e885177c0be3850cfeaba9d8ad43c30235591e68a41c9ca7c49a3ec86aefb5438a48bc5d378309152ba9fcbc344a5ab654ace03b823322b3d00e817aed90bbf237e188bb4e4161c86988f9cf3665334b0d329ab34cc13faf514ec989658a33fe751866083b0fef1182413361ff40540b8365a288d04a846a83653ea7a5444e62b83e0535eb11c115c76f52147f4208522788ffd63a0121c29d036cd510169c8c95807416f65f6caad936b0b981f60673a79b378380a321500770f671939b96b701870b039cbbeeb2c279aa5051478bd7c9ae4c1183843260dd67a2201b17bf3865f1787a91c7a3748a9c1462a6632316bc16b63c0714a589c00447b43f38b10bc2d4ca1608fb92ee6d151d9bca2b4836cefcb17f9bcc83cc36ea2fa90fd015edc89c5e769c16a189a88009bf7e00350943223c52548ac8814d3acd6f790a1f102a5f87d11f85e588060655b04c09a73d50227597cc8702a120dabb5e9d5639198488921b336666324e5ca5543070d5b3fbca589fa4282c520bb03132e86f92172d906ae8631f74c46a51b675d7a0d79e551d466382f57a05eaa8aea2395f4b22ddbb3267ef440d099851a049e583382a8e26272813525e8863b4530892127b669b27517122e05a90ad40435330107e90be6cc9733012ac3715ac7994330ec99a36a24386b7dff16b468b08a640300d5eb36a0f86b0d002cd710aae4617b2b45ba0c24ae1cd508dfe9a810ab9870592545933879ba18d47a17bde4a407130f0ac43162894786705d1bdc1bedc58e5d78183481452dd46234c53342f1300908bbfe204a5bd3899ddabe4f687f77f135c6b12b81932983800ab58ab04a59512a51bc7e360bb880813ff69d2395bcefe13880129e4ec78770ec3ddab2386733345d7c159b74ad7b7b4022f2c9b4394eb632927a6153855a48f6e50759925e9b3c8840698ec8924ff1e179e5d784f19187392acbd404c092ca4d84074d3605c7532a3360113036261aebf8ce54fa53f7ab75e3d728e152a4c5ab7f63b63f8e3b93465574a39731446c9b0bcc134bbb115bd9a4b9bc9b86a87b7f5700f3abca23db70dd35342dba0a57495906da5166e49bf56cc86965371078ac92d5afed2a0c3cb9524c9101d0381607406ab227bb77c9142f42cf1b98b83f631dafb58fd7c77e7e7a44285acc679844aa67c394528874d5074c498111dc396e553565c3a80776c432971961d12bcf68204ab1bdc6872e1dcc865907605cb5b79700912e0b68ebf119334b09cf32c986dc729b031278b85cc04c53e15c5330881df74cbc9aca6792999c7e973d8e3805716b7092f9c91497144e424bc95639fcc19028fb73ca8a9947600ce512136ff69ae8728a6b6a562f923565f70e0b09965349a16d06abc731a1d6bb4ef77a887ffaae5278a8a4260c04829ce826cdd7d942fe0874615311ac9191c2f432e3f7861bea471ac4bf137917adc6c5b5062ac8a47896824832529cda569cdae653da857eaab54b2cb960bfb29184ca407f4145717c30ba030ce654aaf8c39e1aa806da7395b63778b7c7757e0c87b2ec3686f05ce4b66df0826223e714d7e83fbaa84ce704612cf7c1df783a704011b3f45024d505bcd268f40400de1c0553479e67407e7fc09ea3c96eb675164d163d0fb1736d1607a34a101f7015dd946ed1105f1bc8706efb2a71b1a2e231082aab392ab3ccde922c9a9411c2b6c997f18b91231ce4d8074ce10db559a092586f72ba7cf681c492501ff6961eca809ae98c38dd35c8dc1ac8664cad99130000000000000000000000000000000000000000000000000000007935420ed4ceefb4124c14a0c36cd9e6bfef85fc120aafc5ef3e72223ebd7ffd5ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 09e690e7e8092aceabfe13640317de9c8401a9f5554bbd1273aea9b5ce9483d64f0dcb38a9749cc9501f193adf4e9413c6aac05e2ef1590863d3a97edd8054b5af31f0be6fea45294f77ea8f311caf06fe9c8d0f7c29831c44e06a2b2c6adddf33ad84f5eeaf2101dffdfaba727c94219fe4a4f64ba4e0af97c342bbdbb75b13dd470994c04af2961be13e772c626bfa2355897b9df1ac4a331726fa3fdd730e669549300d1a308944dfe64baae2f2074dfd57cadc7d5c9bdf72dcc368cd881733ca49107f93a7be5ea90cdb3bb2d037238e0500cbd414c362753c104ea6e51540c2b713d42334642ef1bf4bd1c1ae87037a846810ad6dd0d51625f935ca6333cb3ad2e7ba1cea35e17b34e427977838fe2088ca367f1b8b345fda94173e7605dff4c59b7b9a53435d62f718fd103b3b4c9605f4d57987f70f55c9b0b8e638f5947b7333657833f14313b5b1681da369f884eb76fb1017d9b6abd562c3dc9be60b7ad6fedc3e3a698e698900da80316631ce21961e63ea1453430cefa1106de70657bdf32962b9c7f9738794729692cc73a4b5f6cb5b1ec594c3975a234d0c5544fbbf70cdfe0c83a13b126e09bd86cb2394b1599a77a1dbdf84ac6224a3b3c0a68be739f4de221d69cf00880cc45b8d221b417be5b425482f8c7f7d990dc03d1e23fa48076da2886f9c5b7cb01d5238dd3013863916019db176c4c08512b0444703d588792870a2d497c7dc7a00f240f481101552182c8a8a5a476d4cd27fe1600c6167642fb1a336b4195cfc00acec31b5e23bef26b35dd43f981a0cbca38eaff690068d0167139a433be719a75495070c170d65d2e01db5840cc6abf26247e78ec66d89c783e40ba1ea9d9f5b4d551d97eab32c10a6d5b2ddc9da3c0e885aad5bf8f672cf3f9f0ce26be5afac4150062af63c2f532a2ffea069b546133259164b820c059a01b804861252746ca3722d5d9f5bc11057bdf939bc05ec4066cf2821bb02ce1fe987f15d28c69cec7c25c2be4c3d256821e0aee57c55ac1af279584ca23d5d15c967ec7f2478039894dddf52d89be149bf29324e5797c20c2312 +expected_result = pass +expected_shared_secret = 5d1262f1f1c664bb74f85c0087ca6fb4ad883ef8f777705751ea770de758b83f + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 64a90bf7358dd94798b5cc3a55f8696790b31943588dc892e7673b9f782b905c4a1dc44f660c475df7473cb672eb31c6a55009a768548c52b322f5afec8bceee2105cfc75170f1505f4a8cfb4b39f368c1b09b19f3c41e5bc14dc49c9abf48baad0875af35653bfca37cc01f467aa22e8976b70245b070556318388bf9cfee0b46d1fb6fc92a7df9ba07c5ac23b9e91b73857697cc4ca1a59b09b6a813e1a84570483f036014b89658c26d0458cd983514578115e00553ef0597ac89677bc68c469439be88c425242ea023bed379cdd9b9c80148784d362ab5134446f075f5c11565d37b10a5cf3d8a5cd2b530c3bc40d10375f7a149fe107dbb486a1ff53d72590d3e6abff5d450ec741d4d97218369872ae5ab98b9514ba543e2626dae4c5f09b105fb2b77e6c9c45b61a9c8c73897f3a90f1710609c78c1375159d678bd53c1efe92812bb8060091ea5381f46749fd69904dd423bc882acc6f118eeecb955ea50bdc15cf9001ee5a4a476c5abaaf57c76119906a61c5e9bbbb32c34653b29ffea16c44c14027199b0bc0f66ca2f7c88a86e607ce6ea578d11c7e38133092b591ab251f666b5af532f0d08bdfa98c6ed1805efe16bca96a3b745ca2357824531199ff28505267148d7010cf0c38de666563b41d6956470dc215b709bd4bb4008dbca80377fcd09a34b8461cdf8ca12ab63a6b20001474d287b02e093acdb7197e09205e2950144a935bdd03cccf696139b1c6217491c6c11fee948f517861d1805a8f166b0c92cb0663a77a8105076cbba932483d7265f143a5ad8260396cca5a63e79284c6426321b7359833a4f86106aa9ab846bda35414047c31462d0986ff5f04027b4426dcb34fc024dd93a9e47abce79936a6aa59052089b3bb5af13f480cd1813ef32570e3a00cb712b36c4463f5764cd935d2265a01ef745accbaa086174eab2a4a421b5fc4c9254515d3ba73124f4c155e9caa7b25e183b942b7617199745e5b9b15509c4ae370e32d07ec1dbabeecb47aac658bca87181d950e891c5eeebc7bd3b4d0c3357f67769faccbc9b1c44e651bd6f753233c12e4a8960a6cb65cc52c45a038bbc90cbd865502c1ba70a32265fe3714b89335a1a8cf73723ff95addb6176960a966aa2c4493c3917c25c579a143f42b7005b0b0b77c5d6d169288596abb3bd0b53349a8c96e4eac40d20c6af19bfb8221d82919540f36673f6684c4870ba748ecfd3aa7600b463d1098c8c484c4ba3efb5c08a284672f420fe36b7977a0fc72a801c709f64706b70e4a5df566563f75901172f901a5e9640b40927140b0b529ba8549e4a41420a06453021ef96b7d26b44b3749b244ca9021c60d6e62b96594e5c6b3aa53aa7aa03c4bc6abebaab575b455ff4447f57a6a24c862f8bb16182e9659a780ae0772398f5c917774e59b678add3288eb4a1f4f7335ef7b62a823137b78f2d646b87b5bdcfc304f3154b8e779a31c8bc90051f22333f497b79df8158b8a2232c5270dbb5781db44b9eaaaa76fbc4d02364e7c2963c36b8669a507a7c688e841eb1f1cd230477eafc983171a84c399206047ca7f13906325b54730fb3db1ace32c75bab10b3bb7ecfb9a5937cc38fdc660243842b56ca16707d39d35c8e85212ee1022ff35c632a3f60434008e780a0ccc7e3983649a1426549485575b2b9acc3f3877100caa80aacba1a2c9a01b9531f450fb5bc0d58b21890997441d0410be989d79c237566b6fe14af1c98a05a325fb6139a4fab4e7e406c461a5a3e614893979fdf4948b7906dbc8c67388c728c66c71464ab575a8a39e62222ec8f254545dac2a97fda3b11c815b83c25250636b9d27a11fc536b9aacc3930a58e58f2b777a1b56a1c857989036975cd435d5c05a4e363d7659918ddc78054350cb386477c11f17169d6d5a3c52a9308546ceaac00b92619e35908c4ce92f4d047118709e24421b34818f55196b7302810fc8a61f5ca1953b2a5907665a707ee338b0ba96b419659518ca4501762675835cd191989790adea4b556cd69a7e3c4b36da74dfd1cc02222c0fcb65138172a3538087f1168f6b00ca7974c90bbc5c186d9eac89b6b9046037be796669e0a00affa119cd8b5a4c03ad45035c218ccf282508f6935e75406099504a684cae51f933fd91274d341f28771cc916000000000000000000000000000000000000000000000000000000bfc5c6497cbce378823378b4356750992bdc6f490aa47f504ba5173f6358f1f48bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 898ad47f2ac4802f28b71e6b37850a2bc1afcf1e3e401682ca928c15e9d32f62f7f64d9895dfdaae399568e0394512b94bfa1a7ecd0e71968699fee3c6d7c286cd6d8f18cb87d0b47e43188634d10641014113c6236b44297d68ddb2723560b1cf29267e3e7e1f327594e812a4352c12b977a5c31cf46aa5e95ba252ca7bf65664598407bfed485cdc4d1becda99be53a72636b2a95b07ae44ca1d40674c003fe4d4d2774c9c0de9080fdd0f5ec0fbe80a1410ee7ebf079accbbea215c10bec32c333baaefcdb52efe0d8e3c5c1d65964d25a2da50527fe5f00c77c9f81da7cf7ddc692e5b719d7ac671e0699e5f756c512d5c7daa72975168e0f848e0c065dc04a59667893a6688386e66e922f201c41770f8497eec0628df132cf1460df20d3b8e631e1515395619563cc74520e499f6d20b27798187066e80e4919f039a143e8503aab89eaac1598956103b3579840ed2cdb7e64651e98791868a6c45339482db2bfb06fbc8cb0182d536ee84d684473169ebb977e973abc709ca155ff77d4894735719fe33074d472bdd8fd271badfaf4d245b621432708cf62175f3791bbd14a019061be42d399b6ed48933830a5f6a8ce1109f3ec41ec3e468746c697ccd12e8ede885f00ffed145d33e28901c41e86ebf2c8fe9bb34c653b7158d6f0390ea600f216dfb6104c59eaff3ecf18482d1aa75718239fcac957c3a358a6ea5a1818e147ce6f7862fafbbf3f157fd41a25af87cef36abcd28211fb27969ff6b0d500f507a1b9655e3a318eb7885372449d2b58cc1d09d8bf3139c8750e60142663b43b53567912100694e819ac81f7ddeb3cb746432474e91909192085125a67dcf739aaca9caed78f1242a5614874d189069406a57f2c1e3e8a8a4a1c78add7879d3886f676beaf30eddf8c00dab2d18d668d699eea17441b28ed25fd3b37e2aa1cb74332dc79a71a3616f308362ec4183fe8cc1b1fbf50b19e5514dd219a2c974666a9c803e3730308b4d7f0292ca11f3a3cc75b5ecde01e8a0d6a6563fc013a5e6a30a014378e81ae8112c0fddbed714573c554627916f6d96c66c81286c +expected_result = pass +expected_shared_secret = d9758b5956b4e2bef89ea1c68e6556989ac7fe00906aa943a0234d2bb743f7b9 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = f05ba04ee82ac37492c48a3c0df734cd96bcab955f69675a12973952c486db7b3ac85951f0443b978aa1bc339def4203f8d226ea79b1b1e4c457a461c606556d82b60f214a49bb1448e8c83ef39766e26162bb96139c18ce77c679a176afc2a2e593046045cc4904c90615585c8a0349f066c50c9ef5e586039939ed523155174c54b74e18e8944837b4f46a83da757e935aadb6d920f7996705c6c40a17386fd955875890ea3810c02444704abc54dbc79313b572191c4f7b7473e794567c0964855686184d65b9a7e646cc9d26a559820d383c63c278bd47077664d7041ecc90f4391fe9128cd6d25346a85699a258c1ea2294b78fe1326db7caa845028fe19ac6af212706e00c360c3fa0792c612c1c4ec085d86803e895c8b28aa85b10b350038d1ee4cf1935bbcd62c4fa28272bd0bb96681aa4230e71b698425934e16213593847f83bbd445c689484697ae510e158382d6b05175025078639ebfbb8d0841e6c266c4ffc195054606f54cee5e609684079a2bc07fe616f544c68dcf22d82419b28f4c2c34271b4062de4c23cb8fcceab785ed43a48884013327a6b1580071e30456342bc7144c0be299bc108579283ba397525f1986e89c465e432b03ec3c81f6c813c83c0df455adb658254ccc973465a864b1b6ea4ad8ca551c0a909612238d0a881c2f5a90b831e765011f8e95c924c186e3c490d73770897ca1419900b5a11c1935ae4d096596c821a623a21b727bac63e346c445c8a1566c10257b2815f65c297598076e6cccd62753d053d9cea8a026ca6ebf2375e3824c4f071c4a59142c0c75dfb50e4b61f3767472bf15262bc55915bc8beca2dc858cd0d9601dc70b844768431921ae24a6fa462ac21ac4515d23c24987591d1654b0598a4b58644485136d6642541616438c341dbb97c879752f494d9749bbe47022fc64be243376041a29d26a7e875c2c0aa0cef45a3b01161fd280061e958f09755d5f06a5fc086dfa1991d7b303d7c4c0bf2b8e169bb85263a6717981b34ba3b123a6851cc42e7a00bb09088a1bd0d882024e1155f5716715b7950ab71ed582bfbb79187396ad2bc9c09883042fb3ead95bca9596a49eaa0546a42b1b29a712898fb4babf47b23ad4a6f3ae54386cc8b497c2ee9153b21e580669405d8924fd4c840e08820186446b91698f8f3ceafa1415747bb31eab6748c639c97c7a60990798b0a7f11ad86d2a480e9b17a1835759269c90b9b09004681333ac472ceb822b59a630cb11ac843925876935ca1803d5d245de0874beb12a3ff341eceab0959b22c4bb093dd88421fc12e8cf739d3f5be5669bbd240b4694acb72d1733d4624cc750450cac107599dbe011beefc6c63ca516169c6c741b211291313840430b647181253d70c4a289a6c19343cdee5983fe6a037622b137a4962ea9c6c3b5ef3d239fae089a623a66fc1b47c0a658d3a0c7e4ac7b4fbafbd8919d1e74c559209a62225a989cd536aabc439b02671cc75744b223744623098df5a3555c668fbd7618b3a826bb9685917c05230a0118756a6497ee60b00942a5e615559d7f81970273be9ab34d266555b2682906bc7ea538fd98353c38c8ec8c515ee172685c66f4cf264a65b4e36b9641009288f991b249673d20b908be66f7a2b99d15b3ce6d95de87515675537d4aa8d750b8b8d590b726833bc536eabcb97e27b7445a104bea31c213b9fa7e53064f760f0a681b9194f751a5684040b5622847cd93d2f82acbc5610b042999406089bc769813bb9f6d711dfd57d48ab283fb216ee4a24f95048d4ec25dc1a585b5619ab63cf21c51909e2b741753bd8557904f2164b6c09253bb42e83021e739d48c261ab0103ddf174101b5ae20a543a6929c53c1fdb780375c6c600f450adf169b68c3c63f933de63634b976259a69bc187cf10504fab97934c2880baa5c24c11054fb2897f40264bba56da448ecf94503467ca603ca079c2650d725f9fd8c187c71ebf72bdd5dc97447a3a0686741068b61da9a3d0c25e7c22aeb5115eebf0c1a68702ef89b61bb5c4daf491be498e1365c06475b373faa2bbfb36acdab672c74172f673bb763bc8eb83bc05209ea537fc7271e11142a4fa6715d79f7ab88b09e0c1c583772ea9584555c3d47b358953348ee2c646c6c3d7883f0e73a2d5890000000000000000000000000000000000000000000000000000005c01cf97d1f917bb313d1a841e8a555722f65ede2665578c60d1b871914232f7e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 21605da6d4c4a592ff5164089e06426fa78b7a7cef93278ec2fd9a5cc462c9eaf46ee3725e2ec759eb8ead381c19159b46e63c9150f60c7299a789213b3ac32226f8e019c1043ddc190a02e6899f7162c876e7cc50b2004f21961b4b53f7c52323b6bed0a1201a4eccdb2811cf01adebf731abdcd827e4b2017874db9aad28f5a1fac0fff9b3ab0e1da9be06faf987a4bb3a3c1387699a2223a6b1046956e6243c577284a0aeba8e53a8dba690d2d295d83d1a79f00e552a91dd5f5dadadb9110e4321233364c6d343a87605b35473937afc0258249def33019b71c708265b8876918dbdaf1c64a3a7cfaa0ace08686c5994545bbdbc3293f37a8a8d48ac0157d271111b159624b11affd15d9230ef753188de1771636c562a355bc98d724b62e6b58994caa909152e0da518d95d7d58076eb7490012818cfcf68c247d4cc77ca3888e66cf9ded1bf10063e68c6b2dade61d4f2dab1a2bc6d7365507de38ee1d31c472e9a2abfd373c9e949d539518438b49f534eb14e9a53e4f6e47c1b2870991755015dde9fef3ab4f3b4621e82667a0a3034ac2c87e0a84448c5a61e13fafdd09fae27fabe3089b21ddb1a43fe786e4fceabc33ba8913bf1b72919a521839a6278aeb75497041e03ebcec51159b5c53d9253ef535b324e684fbc2a5239af7dbd54604c90846f53f4ec740dc66f30bd0a85f45c8838d4bcd00e7d6ba7cc45123b7192ae62ea81737edccf8a5c48d336ab5570eef19e1b16ac155c2baa880e9cb027b4728d08504411ade74c5e85820bfcffd14a941655f3b26a564d12ab412e943d56569c1265a965d7eaa45a0d4db00946fbc4cefa0dcc219317e369a652884c67ff61454f0c2633b9ea0501a6809caee9c58b23c6859fc5e16b83001049ec1a05b47325ee6ea145601707465d7ad3f71ab740977c859753ce14e2fea4417d780d3619bb60abec6cf4ef2649e5b4005292b856aa67b175b975ae1bfd8a3dbf99bc26a971dc58b64bd1157b2ff97669d85383e1216e129cc9da30f173d108353d27c415aefeee2fb1a848c1ab5480bf851ae6d7ba96819b3dc776902ee54c5 +expected_result = pass +expected_shared_secret = f00e6bb6cd845396ad031cf285ee86a4dcb919dc5d9e91f816b4471220dadef3 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 476660dd0401afa8203b5c280d87a2e5744ce6d1cf1558c871429147b831149670c365c5f80c4e5c0aaf84ec9108d07e25404049ab6a19415588b44eae659e9eb366cdc5c5e9ca96e9b99014c74514801868f951d841acac4210a3984b25f0717a774aa71753cfb3c9bb85c5b9eccc67a48f271157739cba3fc49c5b262388b2176bf3789b8303eed08b03034cd2f24ba06923bc1644ecf576a1d77283c359edf53f213662dcd6410044af7dfb3ae0a3aeef96857a169fb9a9a586db5094b3773750c0c739a73b0463e9283d219a2b277ac4e76ccb4e785b0d6c9d19025a678c927e041d892b0403254e2bf24345851ae0c759e7f159848b9ad1fb60169ba940b000c42c11f6aaa6fd731e29401d3101ce48c47c6bda5dc818b5268ac7ff0c6a36cb5410927ff8290a363524a55bc8a4208d79e732a53bbf2177c6ea407c313c8d1bd35c489ac161e77d0e54cb767407167c06deb313c3b17f14c3009c308133059eb6663f45d4781e259e9f2a7586c5bc28c2526ee90b845533e18304c5a3801fb9bcfd1c0b03260486d505d5c1afeca04ad984813baa9b636695865b3279617d194296514c9c4a4189c9a645e66b0b798babde151949e8831570490bb227bc01c2f7880d1cd44640a53b1d618fbe19499b25b6c1aaa8016caaa893a87ce65502c8bf4fa4015e74184526562bbb1ecfba8eea78098c629f29c4097a8bc9c6d178e54a3f676a6e40150c865c114d133589c23f6263cc8caa936e03231921cf8fecb748c6baf32c639330b52e9acba2d3907c7b3b03b85fa063ce9669cb2d64c9d70488dc0b252727cb520c30395a67e3aca14d3c8f03c19114e756b2c1c2503b7698c40ce5b84907414658819968f6af91d98ea5a08869d68c86e293b645b11c83461f625b8f0867ed02a1570bac00a8286c3aa9d7f1bead11a763bba0488c428aac1875d265b9b30b1220b4f3cc4830730085ab6125b21586bab169d59847a7023b3bbe164c6ab8746af53a5d5713a5a4969ecf08402095a4b4800be70240262b18e843022d538c3cfc5ef462c8ba3a287be8be6263a832d1a5c808cf5c1480e74b379648cbbd02866ef74c932441672c5c8b511e13e284443abb225a81ddaaa18477c5301483c13c7a45943af0a1805dc361c4a58f12b4bfdff1ac55e64cb42b8d14e0babeb8b99f61b910848545668d9dc7bc8a475b5bf462b5b5c226925277465d1d036a2a485f0dfc04e147a35f568e1fc9cfda1b8b9eca052068283c9945fa9a2c7fe418327945909822a1cba4a41ba8f0b7cc26209b9c84b679981158a855f1e335cca815d33477a0c1affd546784b0c893f7074bea0b770a4f8843b109b774af9986c2ac29c67aa15b98abff9718f2fba27bdb24a48c9043005dc981bcac8790b837ab33a1a8975410a3f396499bc725eb7ce0a87408d9a235b072c669c6cc935f194a950298830501b922d09206faca932a2ff45700cd072dbb9acd7aa5c284e4b60f32561ad142c4e214e047a0663211054b22e57b68e4763209c8c427c767e41678795627ce719969c781e17445de9c1d33494a3b23c7b3447d6bd019303abe67559e31753caae015971a809f602a6bba2002097b553ab481844d4f8486db35970e1534abb2ccd8f52cbae78176182e4079a0d0ecc6425b117098007ad58acb306037b118f0bb27d7741fe3a89f9034b1399acdc464271ce3a9302b994b119d61fa25b3b368338a8f4f51a008399942b1cde51a36ac3c6549a2401116aef240cfbefb6885dc9dcfa86c9ea58124ea3a05150fd41bbb8700550ce2b06c36b368c402832a691445692f299e5da55ff52c42d10bced47275f15433e643212bc260a0084ccf02422359507abbbb91e57b14ac030c2814e45a654af541fd704cf95443c8e2ad149b562549bdde8ab96f032db92b6a37f473013155e228bfac7b6fe856b9783220e05ba1444638bb914af8156294333ecad852e384a0f534288fc05bff2a6efc76cd18479ad9729da9e394d52bc420794b9af127e1938a9f08a8efa35438cbaadec162ca269a601ab42d949f00e741612266c51b969e317657484e5a15891a4249168a7888a903084a2c88f56a66033b262bc6b07a28db0a9d7d4361ebe62c54a3a292cb768e668283b06418232d6bb80ec85034067253f61818650a000000000000000000000000000000000000000000000000000000987c5757fcd728f8fda4bb2ccc34e727b4c935081ce0a204a3d9c54b16b1217cc975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 6bbd4bbf9919ab06b10b5a372d405a88d94ae3405ca26eb6f72d1486cefebaff2dc9d6bc3dc4a01d957b093b8d4d546ec46928ff42fd8fcf64c3dd1021ecb1e75e7acf0ccfa2aebf555a3d23e292b035c3816165e320d9545aa70b728fea21f4c6b2c7fa1eda7fc3b7594ed2754f4e291050e9fb4543190874071f5782bb0aaf683d6f020771f325e2435aa1f6f80dc47810f29f3dd930e24bdb4682d618099ab95569a740b3a1ff35320394cb0d7cf844445691b076c4709605945a8f9ea1c598069b58bb02dc34124791494fb8b7afb393f7e6b22d67a7494d8c888d957012d0f3b2cb9038ec0d7d5c77211f7e224460d2936e85a3a202d9b3e0c04cb076256cd04d4230599a3a2cabc56094dab0a99e1b409db0d8651c96f755552bce554d1034c4243edc31f8215832092000d9570804438ea7c0b0a167aafd113241fdf358d460cbeef621b977444f3edd9539920ccd3ded9a9d6a6d221957320421c388af2ff50bd4a7c27b01f98fa3bbbf32c82ffadfa14cd71025e19952cfabe485b06cffe8703b33258bfc7914f69db35a30de07c7c1908fdb5377493e5b90be1f811e8a10d5ba6ac7ffa202001189dc81e8e758d6192441acea101dcdf471eb74face697a4664ee6199e62b646459c7945c423496b177eb5bf2341a535cef9380554c6b2a859e3a860495912df0791a1a5bf02774f4311d82ab8a9a1c6e7b12dd86735134ba23ec5a553d48eb5c4910e0f850393f7992a1dc5042a0abacc974b4e5b3f21b57c9150a86f5cd8da8ea2cfed830d485e1031be14c1c52e99293fd124703fad579635182704dd9448953b92528edc9173086efb7471fb24ba7df975077e1673e3fde8e3a8488d591cab627cb5a0c39af7d6a2e47138c6616c6d3cadd040aff04220265b5c16ca0283fec6bc0be62be986d85099d679ceb47c73d8a8d4266ce337e81aa6a5f3579ff17eafd4456dec37a88075fc87540898305b480801ed75fcbb7f8e7d15b742cafd0dd23c49a42a8b2216ed47d3a8ef21b31d02ea78c07c128144bc8c714018606e02f7792d4532224f556923b14f3abc644ed983e87 +expected_result = pass +expected_shared_secret = dbe5130e95de9cb4e77e62a396a2a623eb069c1a96ea1c2d7ad37861bd75ea73 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 256aa419a0a0599376df15844bd3a95853520fca2d9b342b55705c896845b0a8a8b35356cad9740f34ab358a3da5b9596de40aec0190676cb1071974c3e516e4da5249da1fb7c1b434d997341751bcbc3951d6265051b0935765ac1a9ae878618ba74f7bb88527c1a433b25eb2f635f4600904814d4118c2137ac368d2abb13b5accdca1ff6b5d8af9a03e3b84ebfa6cab2b0ab1d727fee1954dc818299b9ef1b76bb71570eb6cac914abd084168a88129e163ca69706b167cc1f3b5c72546cb0075a230e42cdcb27ad4a2554c43b66f4ccc55ec7683688e3689282924caebd9890459323563a05888b48569bbffa223efea27c86aaf27263251a9b3b7e00cfc0b1d05d448e291731bd81fd8d2b474d4c325a7a55e7965e514abeb5c9823e53dd55031298978972c4a6f8a4894d19848b39b08a02f89159944fa1982a37ce3c41946f5b907829b3db320a22921a582a94163b3e66b462e628228d82a9e167368358eb4642afe14a6c5870ed36c36b7ea7fc624698cf4c84e725b58841a40d581bb8601273756aae8cd6aab475df08a740a725e37cef92751c515715480cf1a3a52a7173754710b2b990d618b8eb2f532e7d37709ecaca551bd6b556afa1545ac685dd4003e16b016811138f4e280f76303defa440d395559a13ab68b1b6d26c75ee4865238192c24ab52a1c15f2a538a240f9b75cc6dc45b10272ce8048584085f4da6c1e182167eb9c419a1a0891a809f3b0ac8247dbda3b4503248ed4535b77bc7abb44706e12b0493962b302b48023932f18c918451528a81a1c0cf6f5731b8c0680ed257432a4c319007be80a2087c64a3821a8ae08e9012be3d1cb62d229130e41e6d452493035dd5a49b91781f47db395e5bc663603af7accbdaba6473f56c07a763bf9730d18cce1da3968ad114cb831d083a5cf921897325877adb656a483cdb601f2d3ac36a49b3e591379a22063403c97f82aa50c761ed1a289fda7a3d4c2ac67b1ae5b73e5a2bcfc220ced032be54313bd2c15f685c5218113fb822aaf2126cae6904dbc16864223f8ec630debb1ec282ae2eab41941a89147389a08c14015c75ee209f4e6c0e5ba98c5c1272e58646370bbe91c93fda07a3272510aa03afb1fa64d5828adad578a659b8c3916316e368273cb249c5b1f9296429733ea2c77534f79e48f73c9c052191b4b76e6c62c5bb94760ba0387b15097c5bf278ba0768c5c2254d6cd52cb45c8f5fa052696cc4d2275b63fcb7ae1690c24099f86646005b67a79a33993755a35b0c4e0227a8123e88a07fec19566afb8ef95b5f2f4a2bc515a29d99c28795ce7f2538557ccce1698fde928694969dd42397f6c5029e302ac86a4c44dcb3bc7391ca81ca07a5282f01291ab10fda6829cc96b4577107e05bb5afe729462aac67ebbb15d108b38a2da1e9bd0dd90e307347dbe7938309c9bd8974e815597e4985055b7b59706ca6e44b030627a4112817a620db6722769a461f7cac71d2558fc0a076f9837858b634b444776c654ca7436c5164788182f2ba48b59377489373dc364de66608dd1756db27cc1c1660444143ad352576676397b3465f462772015dbf6454120323b6fc64aabc239792ae0c054e5515be13370d4260820884b2c5430c314969d7b898fb4ace52875e2d86c83cc1cea182355e33030cba8d3f077dba818b86b48233f333b7e1b29570181ae68b21675cf93035cdea454e0a207746b71923306e67740ff58ffcc4a2d6605537ab37d3e8cfb6e36de3086ebb8c65042ccb4a2670d669b1850156d06a8ce0383315e05eb96c713d250e977a22cc0881cbb56f80121cc9d697902babdbb1b2974b0b57720ef9038c0892b751b48a54b7c6e9912e9b1b1ec36715bf6a98a6b88cdd81c907948ce36510e0f88c7a4a13fd04a1a78741a87153c2193e035310719203fef365b4ea765d4babfd056cd8ca8ad9b01602115635e2978a8559716b4b7bfc380ec8cbd3f228a5f997a931518de07b0a3058b66960b9f4bba05038fa619ff54053c6840897ec91edac5348849cb39ab55db9c4807168cb4c1147f503344457650701464a35299c94aaea4c8b3b4243fc9f05ea651582719c0cc4db14775227c0e966abff22b995c6aea3909a06c20349a2584f2513389625adb02587b730d8b2bc6d96874fa0000000000000000000000000000000000000000000000000000000098d2d6999cc106baae041fa826eb41a21dcd04c3a0cd50c733d94132671d13cd48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = c824df951ff2d29f7c5dbeb8313c79d27dbcec886fe46554b405d26cc0866915dc795e1b1381609be4b1798922c7584486f1240a9de8d6cc8c2f7c4d4fe92785cf255878b4443fe05749c59e1ef7a00821b9ffe98498fd6521d0bda1e8d865e50a26858b7f52f5dcc3d15433f26cc27c56eebb718ed20c9302e96293d3f8fd9ac89e9e3c86121431d7e3aba78c5adc0814417a57a1e3e24bd220b2824477ada48fd1f96e41bf4262b7245cbb20a813992258628ea6dd762f2b64c2d596562205842c908ee0ae1b2ca8d260448239407f1534d7ef44ec1a0c28a1b8793fabcf7f58b0886c0e545aa1d6d5ae276ed7495889a78793c07b017b4adccf96406ed5e82514a462b01e4d378280ab2467ee6744c4605387571d8e61f6cb75dc4230861e2a9ef8f83b472c39756921e3c9d15cd6b4a1e4057ebdfb5957a91b3c7bf696fc8b26b54904fbb336dd4312dfe5173a5530a03218aed7d5a0488f18a7dc97e137e8254097095d17b1ddec75e1eea69143445cb49b6422029f5437754b34bcd9678eeed4ed05b78bd986f6811d0d7a8ac0a147aeb7c717f49f563032d6a93e0f690e8421e82739f22b8a9a5a37a2d984ef3719ac33991295b351a946cf5ad5cc4259343c914d7fda568f06055f78741768ba45cc3c1f69559bb2086ac1a871e9972adefa2d0fdf305623f1e05325305348048a92e875a7472538c7fa5b501866b482e3c2a9c78cc78b19347e246353b01865085971ecfccb5442c1372b4a054a4687a84c2adbb5261ba834a311b3f4c5f26b658842aec9173c3f6f9497ad2967180d0a43c01956bcc2599d46b7c72f95a4f86c330ce90dfb5ecad75e365da9476cb19148756b223b8a49622f0be648c42cf14df56420f76d7cea997119750707931ee7d4648d2030ed6dc70c9ab1860628dceea1c3ca2ff0d4b77f96cc0965cd4b61c68a3724cdcd13612f13298ca726b97a1b25a68d348942162d4dbbc3b8f6553fc1abeb19f701cf7a15aea7c4fa49e1786f7876a6a249ecde5cb18f0349ee686b23b8dc02dd7f81bd194ee1468904cefe534881a9589a4591f60bb4cd2943ac +expected_result = pass +expected_shared_secret = e9fa60655724cdba8f39d008fdf5f4039630208ea2d1b8592bac692ef1d66bac + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 2bca01078898594b8eae01aabadb52a8812e73d00cc5f4a63c8298a049b146d4257d01c2609b673c256342b21e3dc75644880989415099e10d00754bc9a68371f30d0b5c07ee46259df9a4942c0483705f8468591ca1c6f6d8b83c49be1ce859b2c16ec5dcbdf74895ba7c6b2613709522605a439ba87aae32262695a48f48b43bb5db3fdc259bf5755114d04802734013042ccb8502e4f36aa832164f612ef7886a4fa4a271b114e17b700711b385b7c2abab0d5535128e0c4db8d934e3126e7b35c8b253204df1ca27a5ba991a5d8eb30c09b17a54d672a1e266f6b3460b015fa00aca92162b85f8cf7972a7f6b1a5950280f920903c1c86a97428e3d5b5b2974fa0d22c730308aea2439043646b44ac771c3818bc5537e304de3143d7554b0e464b21ba5cef60023ab18e58442fba49a0c013a5c3a067feb8111f835a28fb3d99384a72f538dcab39eafa67fde22352c542678b3191c53103f399bb0348379c5d3f814405639a8da76b165c39c0784a61ebb997048222b8856ab6a0c71b94c6911475e9426f97b045871571c87ea549707adc2e23a09bb676bed71caf2ce511510b3a10197878fa0c7960a233536e3f724098349a8649bceb09afb8c2bf6ed34633ea6d2451161b76adcdf14a479845c1639336cab5fbb5cf2db5a94e7a7a0034b7325601610386e3078e26129eddac40e9087140d29b7e10c0d3b0322507c07a753d8511af66e43aa1c82ae152351f35061ec76a8c5701870639d138182740cbb17150495ba6984180bfa113175747d9d897479c50ce3328a5355a98136de4e61ea55a144107a397cc798ee99fcbb31fdc222e60bc05616c5009d3cef1f89e8f32a78b22c7412633c4aa309a70492e97c1d8642f01185d15400a4778854abba1f703c2fcd0c7cd5b5326fa9775f39ba62c171525171fb084b6d73d9603c26802cfda46cba85a4bfc7503e06562cc48aedd0b5f2880820209cab73b8194c4106cac8e93c845f9b698aa8351722bb46fa205c4509f726c19b01c49269268a6dc25fe9a59ce21cd5c0caa5be2c76098b5b0a5ac2b185a32f18be4d1a77f0678dae0bea7f6a9ad8c4e5a65827c9413d2200f9ee2450a11b901b92f5d994dcc06b851fa02ae4397aa9653c22bbd64c17da68b7bbef40773b7908686b0cdb5165b090d4ab10996bb8a81819615406edcf933e905a7b1e2904f6480473b1f2f6a26df42981f91c7d85b95f9d09335ac7db3e75a4d0aba5867562cb2ae290c6cc1038b978a58fdd7a16c7167e99b3fd80c5135eb934cccb8e36278e7d73006d4b9cfa2448181aa0cd6afd9386768833a9d222b0575a76fb224950aadb990698133096cf33787d241b4264e4273cd5cb57345a59b8b3290f2bbc89e3a8da2959245f44799918bb6266794d6840dd1422c2a2fd7db4e4da875a87028630590e1a62e3699a2b6aaacc313935e9a836a35b3add49daf5c09adf435a1d293c08b159b3277c38a82f48154c10073e413bb59a996ff9a7bc06069206a51627403684ca1b91bab5b8785314cb1cbd190867836d7158d28985f90417a19e72f6504b51145bd2ba77234073018e8b2d58b0f0cb54d0b0b302a30473fa98cda4c0166d8aea407996ec86c1c153bf2591901517e63f1835f957da9b93f87ac64037cbf4e8c8a12a5069a190f4596b672ba30df0c2c9f7366175695ffe13d8b101d096341b1ca423af9920844b4add700a3fb0a4e6c90948401985b73bd7b395424a18ea90602659dd3d3904e9a2040c4200dd8894020276403800552144339a6ee8262756c31aa125bcc137ce0a41be92873ff83391a439f9d3b6ecf4bc642c0162cd377ff776d95d17f682141205115be702507ebb34afb4709b65820126e0cd1996442c777504ff85610d1ea8f072ca6bec2387a69cd8bd96c0173a4d3a11d73f24220b06d6037a5e0e6a82cfa1d5c0ac078d37265f09a3ff1544e3a4f58069c95761e73227937d24583cc1be0982c241647e983816423628c54bdb82146851a68825168afe1a282638242ab9087854939083175b75945e73c93d7651a02bacee8944a85bbd313505c8a8a6c86394fcc5e3b5367292805d453ad8f99586fa883a8e5b488f14d05b95ee40878538c5db7905ff4a94427701f322a713f2b8747a83e6fa622eba85e5374766b4400000000000000000000000000000000000000000000000000000000b8b9b0ad05879ed8f7f3504b259fa4a62bf9bbe44a8caea81d46e3f0792703a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = e56d39b9ef43351ffb3c948450b3711b97491023125cf23836b9c1a9ff8195b7dcebb487cf2887ab8b42a60e482536839a771e9d2e9ab0f11ce5ff2d8892102feb73a98daf2322ea8ee2d60529ecfe3566ff1de818f60febb56e122f73b33d7b62a1e4a9cf709906237059426f0291b622ce45e486080b26c4b210e0bc25636dc6665f0d93d4e36600a3dee8d3da60545e4e1d58086b57c760057c9e08cafbdc43ebfecce102a965d6b8cf4ca2e7239d5e277ea18724c15514edfa390feeecf758c227be087aa59e22f3cdb0f2d6932bc3421af1e168b70e52cde5063012275ff406290c00a8d99eef619141ed4449491f1d0a16f6d05e39ffc92de2a184dc1a3146276377c4d2780b39a0c41f7e342415ebfd70d3bd25e86c024ca888ce0206e13b193194aeeeb0e20bf845be1409375dc9102d1bac4da34b1919a26b750b9314a56c338ec6adb6f22c1fa11c16fdfa63a791963204fedcaade790027c16d4e654feb89f8f0ebb9e5ec359acbb5173bf2efc6db76df3b57181b6a088e22bd42ca9ce22680dc6e52ed850da1a3f4c9adc29c74c4c0b6a7c1b09c2da1373178ddf731d6bbd537a0e74c9409ceffad4099641b80f3412dd90686868c8cedfffbf26be5932d7e708a08962e493d61cb9f0b065edb481e6f1bd0cc5cb46e8d70b0f98cc0971adbe833a40f1d81ed1cb9f6f9ac915884a9d98045763e1d121590269cc2016a8feef8c753704f5c7ee184484b77cede8a9ae92f446adde8b02c5d3b5a40922430b3cc728ffc214ad9d239028710fbba2da764fa3f0c01fef7df6aada040fa70456dcd68934b1837f36a3b3ff72ab66aae0973c86b508a2ad46edaee59a51c37e521234e303e41088baa8032c805c8813be285f1aa70ab16fd56e2366cb3884ee49320bb365a9394888edb0db117e775a76bce838ce8c73a9cb26340f6bea85f561c95ed8dd4fa51ecada76c8ab0d0a961dc4fbf0e778647bc6152912e0e2d82c22871343e901338336fea4cf780f60e3ebac1fbfcb9dbb78757c59327ad1e853eb26112b06a258f8effa9a46b07742d2c6519a07cdee75d0cba470f06 +expected_result = pass +expected_shared_secret = 02b43754fa1ae3ebf8986efca3a6ecfad8e0f32a779b3f42c88b6f339140b062 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 5e26b7850013f01c602f7c46920760ae15bea4b99a815252ae285dc4009530fa45b8a9518e7b6466ebb8bc624efaaa49a2e99930c760cfe3c7fa4368bdc157ded5ca95652a35200490b60f83eb01cf5158d44869cc50b34cc5514ba1189cc75800d19a1dac261f02905c548d91d283e9b2b47948afc9e0230ffab66276317fcb5f30947186219add4a43132590ecfc94b534432047c446823ddbf9caeb57b277ec090c64766c54836bc58bc8497673cbb8cc1637722978c98c9e9c4b0d332498541c86c9161d5b608cf83b25e3604a13f2071cf73ae94b465bf71589307c010ca5def4b5574327e22722f32a73853cab34a2b36711136b6cb4f69390d5759d33a5629b772b3ef73a382357d4d46f3db5aa29708ac6760d33352466164f4a2291bfa04d51866bfec806c268148de4b909403aa94962c2210f992ba4e68b95f8694b08aa0e3bea88158a44d70b55e6175c32893d1ff72714e3460b863f1b9a2afd50b991a540c1a94047c030b58a11b38b80f5596d21c6911c379f63b46c2d705219277bc5139c45165ac54c28d5ba9fc736ca7966aa842317c1c944ef86800743b53c87433b9c1c426a33983b15b9a1242c17947c0358b8f40fb1609f8c764618834f709b9bfb812207d456ae239fcb8a5107a375fba0669dd8254bbaa9221594e8469912f99da8ca1dbfe337d9e26343b17176128dc70954af1745dd200f9e72b2441557619233e1442147d7710530bb4d51a4baf7a3f1672af0641c3b1b67719929a0b82e34b96254e50d97d125b76815d2bb28e088c5e5b31f162467e284aa8f13b165bb66ad19ce3e6877a477219af8121d3501a89bb1b8daaf4856088f2826947c55887339aafc829a4866e34706bae16df2a6c13aeaa4a3b252b226ccb02919a7cb3229943105506c93c97027642531689236842d2cf059415a87698c02162c37848043df81a2810b75e302772d2a7d073409a7a14e9ce59063367e34f4a78f9a8b9b404a7b6a6eecf110da12b469045dcda4625f5961ce6c52a7853540cc9d5721271ce3cf1b90b1d550107231ad3518243eb96410e5513d4c0362a84b8f244766a14e42916725404f782693e232120dd9c7d52810bcf4c50bd4963da46570d85f3ca320ed980079e640c6802b94d7584d287de856b36c56aaed4135d8276435336d7a1bb9f94b86be9a0f36540e1c0aa9ef93af562c57581b7d8de8aac6343759ea04118c1a43629e3a6a0b0c470f52f7b5a3ecc49079ade9511456cc7513778434fc1e472c415e57c3841580fee24f2482cf0e381bda6b3ec4a6874c5a3b45737b30e96ab312997a45ce92115c0d9c0dd52b054456473a34aeb26c9c981a931b383867718558b887c08c16bd8899ce278154d04daf5817d39499d5e7501e69bb5e5c33cf7c08e5867b101909ee102e766460db12aef713b6dce264135596e422b2d89b61996cb089621a370896a61a06d36569d808a520751676098eaf153853667af01b3d8e852e80f4c8c09665306295436b9bf492b7805a9aa2f414bc00cf8a00418738922f146785a4795a8748d7f4c1bfd82a10a63dda9089caa6273e0518f656532be21393c3912d495a02b5c3ad94c685db282810853087613027b651c02b73d61a38c5a42766be8e16c5c254b6c7a45499493218510b202b141e516a3304933a06ce31741f43973734940626913225021b5c7b9e0ad9240385741f2bcfce3378dc43010ef8c558d3963538311eaa3c45a9ce4070a6ebc240a56ba8f8b3bd3ab42ea701b80584084bb7437e4369bf255d4e939520c3759b8b0968515b11551d585c27e3abb85478643f62b904515002e4842b455354e76b3dab6ac02188d4ea8f97455fadc43b4c079c6bd019f533aaec038374fc34d5d4bca89c1e59685afd74b4d7d370126886548501362bc71ecc63788707abd4a878823a33d788f84b3ec3f43dcb601fcc6c913efa10b1e072fd8a59d1fc159b8a0061b11e1cfb709cac9313ea4639120ebb402946b3554fc967ae480db1ab6cff796d41b84533dc73c7213db5412a526b513a259c9ec62b41ec307a623d461c0588489d3e7954228c916e97858fb8686b2a7d6e70c8a41833c8dc4e90b2c6a85556c923a764a81a0b8c0232f71c296a526a872fd1215b58c16f800578789077c44b3271ac3403920000000000000000000000000000000000000000000000000000007ac23aec209f1d3418738baa824ba428c9177a0441d5e490333db44621e100e753f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 256ba1f234b35f903aa1532622e890454e1d8295b92038377c9c0fcad76c598d5c9f22ebf59a28b5259540a2b3f02d98f6ece8954677ccfcc1ca8d19f904ea4cded34a771d4a0cd8b02bf14b51062af035434662789c4e9b08982eb5a6c3f418ad4588d41e3eeb68e8c411d005ffa06e0919c9066413b6c54f65b2de9b4a9adef2f6ab45746cec985f5ae0a5a53a70bb2b120fd562eb90c9e9431f4d122a90ed2aefdb521d3a6d9754813ea02d4fa4849293c467497a08c2be7a40d4f8a1ece02127416a6f8410e545e723549b7cff46fe9ed40781bdd552067f0d8a127445a05549414244ce4f3c3d2331339c6049470ef70a5e40e7cc686ec634b8c6bf50def47497dafda76250701ae6d5fda6797106b668985bbd4e8d71c015127aff2f2810f1581aea1bd7e70eeb6763e1eae57e20903ef6a431ce354878ccf2330332c785b31e102623586541667e2ab6697f62656ca100f21ffd921b9cac1879f0365b6b402ca8908337e4f16636b31013deb2bfce8cd7d1cf1bab4759b31549db7eb163e552a7a5659970eec9b34ac410897c634885ba0d2374008a3ce74ae8792d86533208a51f822a03b6c0904a88702d55f42b30c0c5a30fbdaf9a1ec7a4c6355a1e384bc16e61bd6b432780ce79d9feff2ab546e260cad223f8d8cbd0a146a5095df37f2ab62b54bd37d62ec5ddca57fef7b7403b63a231347c10250476a96e1201e1b075fd4d2597e91e70ef0123f7c719d29762eb945a6b5d3abc0937c793799e806104fa0647e161e0a56969d71c25db43b4c6e299890e5e95f80311416fc953fff425d84d5accfd9357228560dfbf57b3a051e4446a7cd6df21c5b50eab10cea9cf4c1ca75a6ae145087de8f940522b8a731047a5ce1750bf617ee2313fa3a48631ce89e548d50d3b3f3e44053ab0d761f4c049b38be4ceef113e52da254d0412cf640eaabf6a43d619f6884ecbbae00032991035b111a19d9691979b16cc953b8df4142c3c05568f837f144a9c49da9e8efa52935eb44bc3a2a81151f6c006029c80ace3ef9b708747f3fda9907692d3e3c1ff144c0e3fda9f99b395fd24 +expected_result = pass +expected_shared_secret = ac258358b89112d41e8fa1ed255dbff7d7c46b14e2b3d176befb6d10b66a98fa + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 8ca008eacb7a33b54ca796b5a0642c46e86b3e1324a9740e89d619259a29141ca64e7a06a7bc5e609047461c825bc55475cc983eea8882ccc07825258fa8c581bb2df3616d5d7505543017afd693a8ec808942318bdacc6b5b8b6a859bdc41697816c633575fd3201a301398b128597ea731a8fbb4e57898c5a18fd59ca657c0a68ed7184c58a5f420b88c0c514482ccde3a93f0c93781f14154fccacc50853a15b249088658198faf7470d778b4a8d1ad3b69c3bda9448335ca6cd207f8f6a3d0b762521686855a76d639401b076620cb1e90438ff056c857291367ca5e36d581d9fab56dc3a875813ff348c17ea77e1422b8adfbb9722bbaa9fc140b950db8a040cc9c2469746b00c72330949db387593d494ff1a964e944af6df216bf07aa30d1c87383949b7537ad6b37c0c93bd24a7c2244b3e360057ff03083cac909f54decdc5a729a8743017c55c803f90934bfd1bbc2f18a35310b5343c456b5590fa270367429f590908dd9bdf422758c480e89018e86c39493f2991c17756da60587d05d7b11b5a5f34b2e649d1b18b5ea25692c362f6e369535f943314bcb555895254b47c470ba79031f0c4139f0689ac37670fd497dc01609dd94c6a8d85aa102c92e9a020e9b96f696bfba677a02483be923a2ceec6a75b01d49ecc09b2ccc5573cc7cc2747be9864015b972987e024a5b0aaac78b1119b7ac08b33a2e006227f6036957fa4a03c4a995444215985a7c6147175132f2e6927b85568ed151b0f516b9672cb2a84860b86d02ac0858586456c82ca3068cc8d1a6d15c6142c94a89097dd3d5bff4d616adf02bcf6153de17a22b32880c2827cfea9fb1fc690cf441b7ec9375c6c249f57896c00d7f419265c87e9a99b3148b51fc9c3b9cf85d884376a61674fd89a2aac37119041dde630a873a5fe6075b59bb00dc667d8862539e89944c5a58c4983bac248b3bd19c9690872ff62170aa198f27a2a950a80ea232bb39c47180701a6362d6ea3a96e284f56c25f29566b2816a40096a65c97ecbda3a96224d5145c1d1b3001a26b484a584c5251dbe8695ea64154a5223ef0257a8349f90a3956263772ada8bb1b32f083680796138112c7b2a15089b8b7f70d1af1f4412d20820b820ceb2bb4833b0c7cc2cb9e37309d810c45639137851252f8b9cb8abbe3ad74bff61a3e2771b3e2c459b11c0963492f9e9ab805a0869007797b0cd57fb2d73b2aea9436130e19a8079323376928bb0c26f679621444524a848ed71a1786671e23230467551253c5ff2d8c3c441b33f85a1c1d618574757aa607e98fc170d727318b5cd4c2a8d82e06334045176e736ca7727560406811c3ff3f556b9e55c426a5e32967e9050c8679728722596b1b280e90315fa299345e80ffa484a64321b9e67758f4a72531bcabbea81d528274c1b1bca21a539e42fdb1aa6acb079358888c3449d7a415a99b4a9b4325e03172cac247a232cbf9400c6bcfa4ad2150e6d3130a3882446b0282861b5fdab61668a9d726252c79057c6609381b3a39bd888c9526f2af73a1dfb8c76220037eb0ab88910046b565469adfb17395528bc54556abd867a7032a598786ff1a2b108f2498911703737ceded3bedc99bfb6d88c97ab55338b7a990c994ffc26b7a62901f8a6722b7799f246b113371ed61d9d706026514accca1d35a548b00badbfd1a4ae953023b4492615165b0ca501774dd5b4ccc776b31fd29aff0115e176181f606a3c179941963cfa0a065a4a37eebb3eea45290b917c582078f79ca05de21fe6ab7ad124c23ff027c6baaaad416e551705284b6229a176e3bb9ec92452659bab4ed42fa042c2e7908cdfc04f1904934507878cb453800a407754a5722862e2a4221746226b381a09d277a7776653e65a5f31be6139755719a33fb5be294b8227d87e02475853f59e894cc67983ba36ba0e917293f788b8d7155bce0c1c0293528dbc8339922994e8322cba0a2446686cca83dc600c5ff79530e9b8ce4002a28465dbbaa671b5bb02c2283a71306e83a1d8ac8f0a321425f52ae1e87227969c0ec41fbe5b58b0063e929b60e1e8818be35487d39bce68c55b91324a8789c94c1122b180a160bf3ad2ba76a7321df6c2fde1b20e401ffda0840812c3d59c2f3e88ceeaa0171b1040906362377699d980000000000000000000000000000000000000000000000000000000c8f23faef7ad19206391a540f831ac41c1183d1e5a82b8745b3c711654b69cd1e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = cf388c22568418f011709ed954d76560a7bbffe29f5e734df76545886980387889a0e5c947df7b4431f788ade60203c4d22a3dfaf7909008c69508f33503b0bb12873c71f2f39e11d5ce7d9e9a8cdd22001c089c66757336c4d5840219cf021f27cf118d0354d88c2c2bc7c6d2894a1c41bcfd5a5abac5c17794c972411b30a280a9a3ebdda057b234eb26468a64d04d99ecd741c203993be49b2842a8866c5e85732d74d5a3b429f62eff9858e802aeed9d01c76d683c0f7b396d7436adefd2616033aecf9499a04d3f872fb3e740e9bdb201cde6494f1e2aa77107ed15d2928cd4446254627718760e2e3783333c59e8cf3c3d16ac494d9947af406e4ab0e44fe5fc608f6b69c88f8553d0f749273fa2c2029cec6e5d4a8a9d66e3c2cdda9cc440e0353edd1394c7c044e5765c888239671942d1eb6ead1745146b2cf81c4f196170796e7fb9bec44091397c29af7773347304d9ba51562c233174d2a2aae570c6184f77f85b819d28d7620fd62e1b91edd3ebd65766e3b2532acf887dc8f5c05a9b73b03e4bcbdae701c44b067a4b34079c0b06903261114e56df05b4468bfcdd0d41446336da83ea815c8ea4b9bb88a68bd817b629b2c10fe95f843a83b561db986bbc755737bb99bcdbb6eb45b8cf5891c92b07030a9e3f268551e144e4f1eb827a4c17cf674cc41763faf2a7a6425f7819e54f28f6cacaa060ee1c8979688199b89cb434d22e581788dfefd1c8e6e48ec9c870303a4a217b5be2dac4c93ab1460433f3b77cad66b8b2571f63bab6ed7dc4967e7bcfd5b2de801a1cb3c377d6668b67cfec133a7ed0c67c6acff96d6eefde10bc567e8538e9a31c92a81e4b8e78f4c2f9cd98a99ebe7bc762b251d0e234741888462268fc1efdc434dd96d7325f6b098c5da259b6f3db12d0d66132b69a2813b1f155430185ffc4738bf63478b087c50593de42fc2e637c0e97a0ecd61de9a73a6cc96872d75a61face7ea8c04a099a24d916086fc2fa78cc0b34eac07f831c1c73e1f1be3ba09a30ff5aa0ed6e7272f08ac1bdfaa93e3a1052ca59ed3f5aef40259ee42798e0313e98e3 +expected_result = pass +expected_shared_secret = f88bf7b9d9f65f61c7bbc53ce26d020b4b13cfec03a58edbb011060b32df9958 + +comment = Rho leads to matrix containing zeroes +private_key = 13b21ddd6a8ff0259d2229745969188032c7d4506c75d27340079c57e5c41cf374e7671daf33619a11aaa489776f1b36825a839f14158df46ceabb26a02b92a920424f39601758321ea584f9f0442493c168866c55d6ba5af9704dc36371c31852428537a3a68e9030c19895bd2385acb088048752b65a3f1ea25b539635f113a1139a52b9c819b3e05505bc0ccb8570ab48163af4169ddb9b93848494a2cd4a206051f92d3c6a0192714307d228de792cf3109c29267eeea9cd2ed9bf3244bb455a0a58514efcc8190a5973c33963ac753c6bf7c5c5c36c65cc681d433ee048536e3288b8aab6f00c3c6d28b8f325bd838b7643131ea2bab3aca0b1e0d2afb4ea69aed00c4f1061efa259995407ad9583fdc337739152d6bcc74f4185d56520b67818926c5354470bfce881d535979a312cd05719a6e48a262198d441514f600cb804d0012b5632ccc337f155021853b74c34eb950d60bc63b1d868f4945d018b4c37fa77dcc762c62618a3ac29ccea150fcb77ee0b2a925c1e0dc718ed4019507842ed7a40bbc083bd9170724b0386a1c262096119870e35f791381b381d91ab2284a24a9c4759ecad48b15e3171bc3a117482f6148dfb7c005d39ce411066c23e076c90f0eb8ab227c162535e46d364b8f379b916bf462ba2235bcd68319ea5e7a115731153458a831751f98b9822ea43a28728b2b3bdf1ba59011167e221bf79303f15f5c1cf473fa42b0af5f5970dd40c70752f9ae27daf137d38b299f7a6b1e4a3821274199b617cf3b78d272724eb09b302aa382f9019d8d395a0361b7a7118bc125dca6aad29b01ae2839c6a6bb7c594507e8ccea16c8cb33a1262686c052a703f074201d57c38d11dc432c7dd25cb6629167599991a52b5c7b49766f07527bc8003dc27b65b2fd43c5f9a258873b36ba516538771744dc2706004817c4c9d86c554a4ea9af16a78bcb31e6941778c837edbc60470d9025e55508d9829bd4701a2c6b514aba1b4b8759cda898f289cd31c1267eb0e2d7233e5a22c435275f3227a7c67937b147fec106c5e2798ad3ca3d9755e37e21297e8bd942cc255533942a315d6053fedc19de4f70c2cf7378e8b3ab28605d0f2c7e6f5892f4365e8eb087ec0c00d879ce1c87655e9b7b5292374f8bce4a75422d64d7efac0e8e62df4d952c972727d3c3199627d6d012e1c22a09a1498d423b2d9cc84fe168484b4c8f53198ba39322ae9c20f30601b59949b846708025fade360f8c98617bba23e777e51bb20f23c095bf06ce4b7aa9ce03c80a63f48e83fbe783f718355cdf67b019807eb129932e441db7a5210b85d92b370676685b66220e1cc5f084a55bf073d9562370cfc70250c4c9e2150eeb942b11c09450a42a7e708968786d359af48327693010a21f79106734f30f3220d38afc9b12fe316bd818c2cbeb3be1cf8af8aa119f6e5b939a561634875028ccca426382635273ee3c724d63db832cacf9acee749cd1bb101c5ebaf7688a37595a56f73125be4ab734b5c9b451dfe764f88d524bae85dad3c21573632c2043482fa19e80740275031f62804062535c1b691304696b305674cb9370fcb71c14b45b301ce8793c766f282071123babb74fd63ccadba777168bf2be438a96668d5e3be4304833233bebb282dc01085a906c0662676f41c1d8a5c1fc43b71979183c33b4a2f80b059d9be802647c987167dbc0a3e40067bd4793d093556c53f2684656d52af3e3109d61144cabc8cc124b5be20281db0c9f89b2b54a4933194162f1c62cd453f5bf26b42c85f572b2a961c23b5a1bdba638bb3268575b0cdeed6076a7931dd587df2eb06a73648c085843c94641ed2790b1ca64eda335a6a91b5311282f2a5e86282ef7986d667ce7c9c335dc733c890c0b7234253255876fba9b511a3989766427aacabb83f9bc9468f07323aba6c0588c6e1653db6c7c9b5eaa41d5262e367a2f3d47cfdb404027a1719f92f45735237a4c2e4215b47a59b605a35477887f80091f2a8a17a466251e12ff071a68a485171d5446b5b925fd4a12a7c70eda625933515c97c3cde8436ec461e77c247e29a4a4e114281313e7e86bcd5acc5201328418901f49bacb0b572e6bb5703e312b0eba18337bf34f9b09be2c77a403017c3a434071940eb1047fb8d23c5ab909400000000000000000000000000000000000000000000000000000022d2e8bceb664173752f54d26dc02443c3b546054d03f7f9088908e2fc752c2711536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 20c17972698dddb68954c1d8e88216375343cf60923bba4f5597ff589f23091becf204bcc7146de96a87c151f1d8511f0de53d7f6847b28e8bf06b4fc25be02259160bb0c37b1217de8b751fece804e1a2f311de9aa66a1f6224d888c5157e81daeede2703f50ea7f0108fd1f13629d6d91226f2d099860ab37cc5a79c19e045ab3cf95b317fe2b071e82c1c6cdd830247a07435076f8b30296892f39418e84726ccb63fb8262f655d8e0d08c09842a84f5d09b851efaa6446d50fe45bf0bc60600874b5e6059669b7156d4fdc12a85d80341a0c721799b9214f2468893ad0d4d35b89470d1ff9740ab608e20d4c4e04359be51c7abeb7f5ceff8430236c43f3062e6f700964cb47a470b116cada012d0b79def0ff1650536e10b16cba0bdab69169a1d07a0db4a0dccc74710d3f9fbf8fa9342b3520f598203c6a4a21b88d70a8058d6a8cf33c4c4b70ee9636141ed168d45737f531f6a20c77acc0707951aa4bdc74993c011be7e15a0f93ef4d6b504114f76ec78e902e2ec40736790d9703d49ef2e9a338b66342676820e5e8379ebd16f74ffc1626c6bd8978ab5e6fd2bcfa048919ea762d3a774178477fd1a040fe7d5ce278116889309d0819712b5141b8666f8f51c8b1d2b65a3cdaf1df79caacf4a5845ecc3ea5404728afcbf5551ba692dafb0855154f6dd11237b617d9175b3ed2f9aa3a21c7bc8e69dde99019e35153051e2824c68d2cbd00910b3ed0a44a0912648715ee953602127619bcdc3f778d352978ae01a4be409b49e2ab7da6789c9ee977670adfa408a03c86137cf4175882c36506da106328236f24799d0bde55b75f76fc3bfd67e6bc1e678fc62738631b3df7187f2e8cc6d1717c998545c0e3c23d0ee7c04d0895fae02e23946a07be88bfc10a06087c637b4023ffabfa0a49a8520de75171f150a0b59822e56c210f90d121105c2248523357533ccfd62ee805c2890daaf8b60d17a4fff7ada26fee4725305dc48749a18ea305e94662ab10598cff1d2dec6f04e2a8faea3caa0899334a45700e1e694d0ac0aecf57facba6c47362bb1da6151ee27a601152d2 +expected_result = pass +expected_shared_secret = dd9d02b5461c15bb10613479ccab153855f7af2ffaf98cf6e3ad03c7f0ed0d20 + +comment = Rho leads to matrix containing zeroes +private_key = cd28b1e3714f3c797340840f40817791d502671640aecaa4f91089ce4049fbca7b7045b350d36eeb13761605aa4dd87e4d062a5486c5d73367073a0a949bb0852956dbbc3bcb40920d89518dba5320dbaca890ccfca8059539505e3c8ecf80cf404c78b262abf1ca439e132ec99c33328860df5523e2f63232b39d83574ee631591f6cb617268a0b5344d2aa003e4000e821734c8922706bc6b9a9542f993920451bbd131176087d6e53663d46823d5a1da3723149943b6f5c34776a8e7e142fe63b50b6ea600cb859672b57bb07678382a561097dc38740474b60f61656f1331fcf7824004c4300f81fb9bc457f97687c6215440486d04470096b1b5fb1c5c77063fd36254c6464f19a96a8a76644a12663361a36d37e6e08bc76743f812448a8542d037b2bd483214b500ba1c07580b44e6d9093d3842df52c92ac8011f207106c069f7e3bccf06106770a04275231d71c5d1a516d6dac6e362397fa348bd49a5aeae37e6495aa1af2084a42c433756461608ba82534567854dde95efe0335d67a4b37b587abb050bbb999c2e65feea4c89d4560402318f8d89afc7601cf1cc6c663c44a85147e7b4ed39b41e6165b27bb1366776c409b01b0a9ca1e958063ea65f43cc8e7a4b06ea338bfc249e7d2bc150a8595500900f64e1a346fc0e5bac6179c505867f0617baec402229a4c00b267fe479d6e3b34e172c800a45bd0f39177083fd0d15e8912498e6818bddc3084c12d042cb9f2448a0d450b3dbb5eb6968179469998c4a54e7692a7a78fc96998d3844602002de81052e84bb64b693485157f15b054d16a5ab0c593e0118f7745244ffc2b57f939f0845b038832bf4a6d99123a5b95b73044ab6788c000143111065ee4cb9550d06e34b81e70641dc5905faac129662733214b866439937d39b22cfbc203f809d265158f02b7c1a762dce060aaa1117aaa9b002aa0f19a68ba5559bfcb5285a29dc8989ac0ca9e21019311abaa89b5730864817227c0a9d56d15c950453537faec9a9e6c113a023a0a14161bf3ab062c2f9a79a6c7142129bbc80539b785464aa10aab8b5336aee10d4c8a1121e2446fc9a9dce1641382a75d3a677f2b5a1b44931ad54c36fb75ce4b3e95988ee9ba8cca517c5b6c3da806b75cf2695853637c190585ab6921123deda4a9a659aeee590ff3969d885952205422adb189acc6aace7b3c4fc1ae9f2259e4e81df8926444aca0ba058f0af47c879371373b325ce4bd12753fd0b1021c2c5d51514809fc62b0c61771d824d6035b82b7ae9761c98b45cd6cf978ed852dd610b2a922ce2a134f7d52845d37204e1686fdb61e71068f95a06b15bc9b85c28190da27e0e5302ebb11032b5456c47fe3f9a86df68c9cc546a88bbd0abc3814e03a1752b8fa16523caccab7d4c256973f8bb7a1d860c5ba059ada0c80c88897f99a1530029568c64c8e051db3b083ec53094ef5c48c752e69093058969a5553c03aa755795882887c689ecc767d206971519ad9b1a60d8baee61863a729263d227f9066b2f4e99f4630a541e83d7a9059c060ca1371c162394cb13a1edd4c8d0e230dd56652afd32d571b972da2417da59942fba107a240972a5e63f75bd9c7cdeee61b216c41eb6898f775b957289da810cd41d0301ffc0a80454b166596cff76b8d883fdb0069cee2a95bf10568eb4cf2e744d229571e22c4302c153e5022059044cce93e2d8c9a046218a0e3730ea705f7a021705526bf83146cec2f2ae2cb46843eedcc4c90a59a07e753a8b60a60ba1d863bb3b6eb48174570ce6551d9cb3cd003317c663f1822bec20cae297c113043a891806eaa857d93a7520a4c16338255abdc7f2f95bd06e04af8084a9ed193eda00e76913773d41988b307729b9a15506782545d42ca63632226bbca0ab1f9218423c606a157283397deb0342f38428de8b94a5617bb22c83d38c8f40c5555396a52b84e7b0475f2aa58c42b2cd73a8b6cd7459940c9f1dc0b3a660460e20227d8b688699227ac592e63bfca6107c2e685c1cb5f74518bb14a8a67f35107d507f17529562690f6a06e7aba95fac03c51bc734e8526a3502d26ec5a13b8a8049152cf89901378194bfb5f0d24a133c8b92cfb8db9b033771658ff024302894cc898b28bf031fab3aab966900f446021c5a312b800000000000000000000000000000000000000000000000000000066ef0640f11d433fe716b2313260b730facf43b40748f66cda45bfafe346ea972e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = f676cc7108a3ab8cda5d18b82a372ef0e5b6fe9872bf9f5d04208bb504b149e58cf120e3aa5e6e8ac92956227506163ceb6d6b5457af3e9ef2357b150da229d8e9cd06bc463bf6b549c7719fbdf1f538d037d8abe252fa88d6ca8b8ea4540cde44c7a8d2644cffe86348a404af2e2e842ceb3f9cde158729b4a9694535e96a34c4ae7a41e8cc811f38cb3ec2961478c6f645e676ecd2e8ba6ec1b81a0d951d3853df6cd858a394971778e41049c9e8a6bab02e453aba4a583c4396613b37373564745f96b421a00c3ab2d4f48c2b591d4480f36bf1078c1cf8529d6021ce5d2ac9bbd41a813d347c85cfb64393b2ae0700384d74f023594ad9e30cc1337c89f523de3e69128d8f3d192654236cdab65377aea27bab287b7fa5ed51067ac569c0e3c7de658d5fee317ab76bd7ace11937299186d0ce733c05b64843fefbf33b609af37cd554b5951482d67004c5665f49fd2f247e21be1785d6b27a980b7ee0f75a840b49e1a829b37b9bc1e5ba57627b1dd23f939bb8f3056197c9017b9d47076f80b00116070b4c86aae4636e14794635d675a9bbf103f0085e67fa104884dcdf6f0284e7aad20e87964b39ef097e5c8490d766cb1f7e3439ea316900f23cf0dee1446af965b411fd70f7c6db2a1828d4f9cf793d766bba3c84610a20eac87da4d98d12bce9d4c539f7c329937475a729528e2eb11738039c35a1fc4f6c5c6e103be54e5b6133c6fd18c2144172a95ace73da024b371ea2fcab31bd428a143dc55af7913f63e548ffb709f55e3da9277b8e752aa38421d93b684ca1862828f2dc1f3d0b7b858c88259886f35f3120caa04c601fe25d8fa0c7466747955bb41371a93b88d1523f18076a968031f1baac78e40f9d54bc559d847fb7ce1f73fdbcf81761e2092e29879858b22b385cd4f3a5ecc910789ff8a55a119f90847dee220fd08e3a6a729fd375a1078658c2fd5dbf3ed12676168222886915de5bb41b723ddb902af7e8a892de7a87cb9341773ca113ba774d3a2f1ce31d70c61e3375420152ec6d08c85894382b0f771a4504f8a379f9c859547bf1416093305beac616 +expected_result = pass +expected_shared_secret = 75046ba6d8839f1b5939de533f2dd0c66ec58559c112c853cb8027be7cde6b76 + +comment = Rho leads to matrix containing zeroes +private_key = 2db0097b4a8afe74111d4b78f8c9a8a6ecbdf4627c00f562b7835f78557e5c3a89cbe1b59d6c019ab574e5ba6951f926f4b274e459260755b4e536513e49607c0a63e718b247d7b5dc91abf1e09d87dabf67641dd3abc47c2a1bff35a17d0cad8a1345d08021149cc5b1c914caeb780b6b865029960ed3af31e976a35c5d2ea8194b875151d52131060c71b660016984810b6ebb31392f9b9b8335adda6199b6438eaa48b1c704c0ebdac2f903051482b3d1d4a97e73779452564b7c9bd2a081dbcc6736e89d1ac7a96518a0851995a8842608386d1eb4bbadac4e70487b05680034f21cf16100b349c356a01c22f45d6585bdaef528375c052ba029ff48156e578915d953413647b5f037ce83aba554c263a3374e885177c0be3850cfeaba9d8ad43c30235591e68a41c9ca7c49a3ec86aefb5438a48bc5d378309152ba9fcbc344a5ab654ace03b823322b3d00e817aed90bbf237e188bb4e4161c86988f9cf3665334b0d329ab34cc13faf514ec989658a33fe751866083b0fef1182413361ff40540b8365a288d04a846a83653ea7a5444e62b83e0535eb11c115c76f52147f4208522788ffd63a0121c29d036cd510169c8c95807416f65f6caad936b0b981f60673a79b378380a321500770f671939b96b701870b039cbbeeb2c279aa5051478bd7c9ae4c1183843260dd67a2201b17bf3865f1787a91c7a3748a9c1462a6632316bc16b63c0714a589c00447b43f38b10bc2d4ca1608fb92ee6d151d9bca2b4836cefcb17f9bcc83cc36ea2fa90fd015edc89c5e769c16a189a88009bf7e00350943223c52548ac8814d3acd6f790a1f102a5f87d11f85e588060655b04c09a73d50227597cc8702a120dabb5e9d5639198488921b336666324e5ca5543070d5b3fbca589fa4282c520bb03132e86f92172d906ae8631f74c46a51b675d7a0d79e551d466382f57a05eaa8aea2395f4b22ddbb3267ef440d099851a049e583382a8e26272813525e8863b4530892127b669b27517122e05a90ad40435330107e90be6cc9733012ac3715ac7994330ec99a36a24386b7dff16b468b08a09dc2ba9e9320ed420fd4416a0072f3b73cf83c24e0523765214a4c94c992295baf7e5a87548347ea12be1c03f91445a6de0243ca0cee67680999a1e7b9b209a758420f48724230ad5a4c2b5a673f8a0ca6ca5cfc9a71f00d978a8c82c90a47a8ac0c8f40cc5bef2889f61278ef0a4ef1554f71497ff748a039bb0a3a92d6c67414394618909cd1c89319de4501d99cf1987307629519796c17402ba60da90cfb04618c5944801966a456a43c620f8a94175c33f1e456916d59c9fe7355aba11c66503251c436b633fa90c5b57477b36908ef44ca0fe8cbd40f0997ed27681845f6de1ae64d8a237b3c642d9a834b6034cc507a1c8a36246c1cdb42057e905ce27cbb59b5937107241a904959670471a44a79945f36269b06cbe36223b0e126f6c89b094cb5ad82a54eca4ac4b4a53b08b91a48829379b9e9e99572736a483b17c4cf100e0053844ac18cdd97c9a209c2e000492b34a35e527b91850a99299fb1104b240c87141767010932031ba8df15c6175357698820f56ab54d2093a5c217b1734a8f88e6dab2fb755b091fa07f4f16d5aa461679c365e59640fec05f096b29a02b3f94069f3962caba81d2218347b29c33bab5603594d8a089496d33d1a991649b4a03bf932a9f02eafcc005d34837de0b236cba834e3672bd2b19d47930949c9c62c6831c68a89b6b14f046bd09014dabbca628b0372a25261f30a1a931738578b51e8707254a7992c6ba06ba5b8c8a3f49b8c9a4550413845bdf545ef459c831899241443bd777a823908a8b55b956649023673c836cfaa61be51cb33299c02b2fc679a1acce0c32d5b0ca4f8473441b1c16f10872efc17956b95a198949a89a137e1064e973df40c776e89727feb28108352da4a19eb760bdee94945058006d70e88a1763b8661b228736b405811f56aedab0b43041271e86934650ead8c8543c977ee138f4eb3ccb6896cf7e71d681b599c0877da20c7ff49564c29a293fa453749253f9a2c9460ac1c359bc0c826197871268a12014a6f91c3586875b883a69063308f7722b4f3ea62b3073134c1760b9510a53cc2ba450510a4728b7d3bcc0e0000000000000000000000000000000000000000000000000000003d91d51a21ff5e78fe5674de24006849043c6dad810fae477d8b04210c7a7b035ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 44c20c571d0b1a531c1d01c35dfadec6b0766bd36a8cb3995ab01fc10acab18b999d7d4522927f8164f7e10c4faf5f37f28d1b72a8d0e36ee4a8f5034ae4f7dd16f7f425aa1daf7dc616ae76bfbc7df24c782c93887abf848a3c38fca619dc983156940611d4e6834acd47cefa92677bc9a3bc8a3739349c73247aa48c5393ceeab3f556d01331f5cf71ff106dd8f6e9d67babd0f5bac47404e5dd96cceda5d9efa58a7794662168a3e785306ae1e9f14818d55503940afc5416729f9ae99c304680f6f216e9a94c9f740223124a3249e1724679ab98b5350f9eac4c2f6ab697133f15dc716737c7a6c2b1f6fc41d890b0ebc9471404e4a533dc113e25fa7e6437a847cb49936c487716ea27792f88bc1affe8a9bdfa415ff489ef1266db8f554dadedb23e74f29e90688ca367e23c9ff6f6625d3d0497b3a6c319b889a56f496bfefe2b53b2b397fad8265396967758eb5eded1efd6115c1861e27c07cd700d48554b3edb5d76993ffed5ea3b9e014e85ee57c6bbd77195d65ea99328806653d8dc4dd3b9d7cbf614d2db04fe7203286c12a11b69f7b65c970c34ccf9cbbb4af9f06c2002baa04602fc1b6613392d46ae161cca228a4e535c523c66fc79441116ad5f2ce0c6d2f3594ec8805ef87247a7732136102abd01f9218c6bf816c07d7b755476808b27abf7ff8c36c4e04547ab8eb941d6b5337c6f3db79cc8ba3c627076b37fe8d916935fd395ec54e6985c9f3ac46f289b9647133f1382443ae911b056c86d0232cdfbf36f5b270099e4b79e8500c2f808036b5834efbc1b627e17bc9dc14517b1e19cdcebeb47b45a146248bb160ae913ff272eecc5613adcbfdb8a20c11c008a7f3fee95f0bff86adbc404f928421775582dfbe2fdfa3fa90d967897dff35c49d69b3f3d1f72bd41161f447f512aa5389ade703941da3782a6f879c3b3ebec28d0c80d4348879c58ce1c53d7a20395f5180221c7f8d4acd4f782d027de0325f799bc6a9f552b19154d18636657cf012d6b6b38bdf055cc5b1a31ced2ff446f8bb95eff4205d164a45e3e811ffbada32d0f973c8ac8e28909a5f3 +expected_result = pass +expected_shared_secret = 3909c469503925b00ee957476837e3d4139f2bab99c567ffdb50bc149e4560f5 + +comment = Rho leads to matrix containing zeroes +private_key = 64a90bf7358dd94798b5cc3a55f8696790b31943588dc892e7673b9f782b905c4a1dc44f660c475df7473cb672eb31c6a55009a768548c52b322f5afec8bceee2105cfc75170f1505f4a8cfb4b39f368c1b09b19f3c41e5bc14dc49c9abf48baad0875af35653bfca37cc01f467aa22e8976b70245b070556318388bf9cfee0b46d1fb6fc92a7df9ba07c5ac23b9e91b73857697cc4ca1a59b09b6a813e1a84570483f036014b89658c26d0458cd983514578115e00553ef0597ac89677bc68c469439be88c425242ea023bed379cdd9b9c80148784d362ab5134446f075f5c11565d37b10a5cf3d8a5cd2b530c3bc40d10375f7a149fe107dbb486a1ff53d72590d3e6abff5d450ec741d4d97218369872ae5ab98b9514ba543e2626dae4c5f09b105fb2b77e6c9c45b61a9c8c73897f3a90f1710609c78c1375159d678bd53c1efe92812bb8060091ea5381f46749fd69904dd423bc882acc6f118eeecb955ea50bdc15cf9001ee5a4a476c5abaaf57c76119906a61c5e9bbbb32c34653b29ffea16c44c14027199b0bc0f66ca2f7c88a86e607ce6ea578d11c7e38133092b591ab251f666b5af532f0d08bdfa98c6ed1805efe16bca96a3b745ca2357824531199ff28505267148d7010cf0c38de666563b41d6956470dc215b709bd4bb4008dbca80377fcd09a34b8461cdf8ca12ab63a6b20001474d287b02e093acdb7197e09205e2950144a935bdd03cccf696139b1c6217491c6c11fee948f517861d1805a8f166b0c92cb0663a77a8105076cbba932483d7265f143a5ad8260396cca5a63e79284c6426321b7359833a4f86106aa9ab846bda35414047c31462d0986ff5f04027b4426dcb34fc024dd93a9e47abce79936a6aa59052089b3bb5af13f480cd1813ef32570e3a00cb712b36c4463f5764cd935d2265a01ef745accbaa086174eab2a4a421b5fc4c9254515d3ba73124f4c155e9caa7b25e183b942b7617199745e5b9b15509c4ae370e32d07ec1dbabeecb47aac658bca87181d950e891c5eeebc7bd3b4d0c3357f67769faccbc9b1c44e651bd6f753233c12e4a8960275aa91a11550b155bf1e529a89350d03088faa8168a4c0729001764735ac2f67dcd2b798b8b4ecf876b576b88391c42a25a75b5982021625662f68e7b261600fa6f20b7890c9347cab1c22c7b82227c6eb6c5b0f2f920e21353f87a013dc69c0f4b6d92d19df983931623291c639bfc4781cea5b12fa59d5af527f9c496ed22b408f507d8c62e39f493304aa9640b3155d96d0c0a048f6ca50ee162ec6c1698c37ec2f32dfe5b03472a8041e4802cbc2448c01cf80047489a04f6306b9775bc2d663757b50873a9cc9168454f292db99503955807d77a72e21c206505bcc7853f12a266b2e5b71b7195abe8007bf54c0876172fc939cfeba86b00babda12db24771cc86785d1a185924574f8695c9164968c2764bbc205967ce171978505b4c80e600d1fc4903d59fa20c4f39e5b71ca9b4933650acc12fa29a6ec95240ff2a8e1bc19f53268718b15bc07bb22c800e9ba66e5861c957a42933d5454e3818e343b091562e64b727e3ba20a3051b81605826a7534389a6ed6135ee590510b48b2e58bbe09348734820d708597bbba21de049398303029973c7b33980aa225b0a7ce4547968106bac3acc3008acd49547ec5529310324a4976f30c832596864df6a6b019b49ffc0185631a7e3f75dbfb05af4924a2d4259e3a8b23262c59b4c326a254eac18b455fb1c6c6c3ca1ecabfe4c6fe3124b46169a9e635250c21fba6292dcc85556d2c4e1796482fcb70271ae9809587de99bdddc62258a0777ba626110b2fca7174c1650e7453baa2b2a27c36212a5a7d0894a75b2a270e39448358aa0d129458b789e286587965e93c4c645b7536187644116c403921093767863f28fcbf6400d93aa96236c51c6980f105cbe1a4732d560130c8a3379a3f14653f4d803b3b7ca113672ec0784be05cab2b2a601687a7d8868e9b93ea4dc06b46b390c243c8ad04e29ea419d36b2f0b923bbc90fee82107a9621b26ccecb486a34f44d2f251f4aa9408cc914258b940327226b2c3d2ee98435983924c657e52a03c2732073c188acd2593b46877e02144a5959dbebcb05e4b185419713587ea42aa751099433770000000000000000000000000000000000000000000000000000001616bc71420e87c069afba9fc345007a54e582f2f8f2a2a50fd4ceb684bb06f18bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 925a0915526fe9a47858b182248e94be5578382fe4ac9749fb288d58350a6f70ab08d67ee8fa05f35f93cf9a9390d1409885135729dc047fe787c39c3e9360bd209664136a405a5dfb2a8da05eb4155e0d89a545ba25680a34ae9fc77447f7ccef118377e21336ee06495b9b12f52c0e160a4273535ae6b5e8636156d52f0b8e145a3ddf9e712e7245091e533cd66c99f550fe7f800492d8f5e94bdda722046f6ac6528314d1d8d910fad1adb9aa9353e0b02d5312242365d32fcf32d4cb91aad99eec0601ab5af11f17d130827f46ddfbf629f1421e00076be4296525c3e583a91caefe3b1e8a0fe478c0d46efe347fd98455c8d7147fd26e777790aad1b2235056d51573018590b00d158fcbd5a078707065f73b1ec0db2a60c737d4b39437565f1fc0445f193cc1312c9e845a7efdd4303794ba049fe8ff00a1858acc5f4f030429bb1114e8755ad94c5486a365de98610a6325db614c9ec75954e849df4310f36fe98547c8e43212a6437d8a3b5ac721f3acfa263ea842aa29e84684c154e6bac34b89983b2c4da699d9e2986decc490d80fc90cfba222cfda81fc95a9c572cf44ce317c8d624b44d02139fe8a7d68e2e6090d74effb6af254155da5732ba9e4561bbbb26a95d38feb45f9e1dbdc1710f86f02d9416897b9c0d4cec47a24497f87ae9ea392234a4938b1f751fdbf92a843ad4124243e0e784fbadb1f3afab71d148a393d77cd7e87f4279191702856da914287e5b4bff4944550995d47c875bc83c3b3b7fcbb16b202694f2b4b39a79abb134dc1c488f120b1f9f1fbf782332cd50e6edcbfb1cdcf8d6f6d59d055b463073066afd2b8686b405b852c0be8672da63714c11ac8499df5dcc5d12a349ab041ee42a9de11b4324d5d1311cda2065f469eac42fa14bb5add0d60e7c26e8056e26b5df1c9421382e9a157221e185630aadbc20bdcf41f948c7d866527e2ddb7368d7d139ee4329c522c8791526c1484dbcabd199da3583f1beed3b1fc6fed0f70ce4392a0cfb3b2af262a157a06295dfaf7cda5517f3b677ad46dc8a29a852d1857e5455a42e44acc57b831263b +expected_result = pass +expected_shared_secret = ef8a062fc7c8142a70fb1293c544678ecf8161560ceb65768639446e54c76413 + +comment = Rho leads to matrix containing zeroes +private_key = f05ba04ee82ac37492c48a3c0df734cd96bcab955f69675a12973952c486db7b3ac85951f0443b978aa1bc339def4203f8d226ea79b1b1e4c457a461c606556d82b60f214a49bb1448e8c83ef39766e26162bb96139c18ce77c679a176afc2a2e593046045cc4904c90615585c8a0349f066c50c9ef5e586039939ed523155174c54b74e18e8944837b4f46a83da757e935aadb6d920f7996705c6c40a17386fd955875890ea3810c02444704abc54dbc79313b572191c4f7b7473e794567c0964855686184d65b9a7e646cc9d26a559820d383c63c278bd47077664d7041ecc90f4391fe9128cd6d25346a85699a258c1ea2294b78fe1326db7caa845028fe19ac6af212706e00c360c3fa0792c612c1c4ec085d86803e895c8b28aa85b10b350038d1ee4cf1935bbcd62c4fa28272bd0bb96681aa4230e71b698425934e16213593847f83bbd445c689484697ae510e158382d6b05175025078639ebfbb8d0841e6c266c4ffc195054606f54cee5e609684079a2bc07fe616f544c68dcf22d82419b28f4c2c34271b4062de4c23cb8fcceab785ed43a48884013327a6b1580071e30456342bc7144c0be299bc108579283ba397525f1986e89c465e432b03ec3c81f6c813c83c0df455adb658254ccc973465a864b1b6ea4ad8ca551c0a909612238d0a881c2f5a90b831e765011f8e95c924c186e3c490d73770897ca1419900b5a11c1935ae4d096596c821a623a21b727bac63e346c445c8a1566c10257b2815f65c297598076e6cccd62753d053d9cea8a026ca6ebf2375e3824c4f071c4a59142c0c75dfb50e4b61f3767472bf15262bc55915bc8beca2dc858cd0d9601dc70b844768431921ae24a6fa462ac21ac4515d23c24987591d1654b0598a4b58644485136d6642541616438c341dbb97c879752f494d9749bbe47022fc64be243376041a29d26a7e875c2c0aa0cef45a3b01161fd280061e958f09755d5f06a5fc086dfa1991d7b303d7c4c0bf2b8e169bb85263a6717981b34ba3b123a6851cc42e7a00bb09088a1bd0d882024e1155f5716715b7950ab71ed582bfbb791b2da7fdcb1c22f9290e94c5177d565e6b20860347581a174b5c7c483fa5163a568706bad37944aec0bad755310ad2673e5a15b951bc17b6c5a3345b0bce7af3651bb0d5514e8ea3a4752bc27b4caf0bc3792bc14e8f07ac752b50c13726bdb37f06271bb46a775a9285e3a6431e3be6c29b17eeabcdc95b77c41c9d1273c71d3b3bcf8091850683d1b5bd0c7af2211499750b03194b7684846a91cbec315be1064906b34511ca255a91561f1347d5b3bcf9914006c3694413b14428559ef5c4a6dc32f499b98ad5b60e58a6bedf29dbab685b0988e3f13b763cc84e20342e10b13ca87543b2254c76553b010167310a891cb4632ab1d7c3003393b48a7e7acd44212868997000859e9896178a8c7e8c73ac1166c22ca1ee9a216ce7856cec8bf46615cd7d61da541c1e2a921f9755b0971bf5b535969fc025df15f09e1c42ab5bdf4b76991e5437d5b64a265926941cf0e7956e492b4f5b08514d7bc30c05cf5bac145060052f77047e88c36e00909577dffca1538d83bc72060b88836e55b08b4083493653856784d18bc2d0656287770832896578b6c54e0b601fd53b3ab71301f707865f504e08893f213588b77907d1a6dae01922d6a2d2c72c21cb416ee09706e4972114703533bbd2714ca3b8bbc2c1a2be9f377fe176944065556da6e5a9957ed011014c014b7a63395f9964b45b30d6054e633b0035a0bc6c9827a518dd9980ea8ec72ec2a57feb06ccf8a166f282039e8090b8300ed510ddb35b024665ee96a089ae831b078c92f89ab3e7337a7768b2831915536704d2b1b4e6c8a55464c0879bf65928c70a15c74737bbf159ae4c557f3fc4034090f9eeaba91e83927d11dd444b2c9634499317630d93948f0678ad7cd9bbac8f72ca9b15546b4da3405bc6f0a12494878ca7d58c9d853b3c4b3b6424652193c85f52285d449911455ac7d1579cb3375cd733948d46f238b3f7e391c1ca1bc0a85a44858b029b05925c2ac3557598933957575bb8a8464ad1b88753cc5b40029f25c7fa9d5982a5b51d5cc5d0afa495207492e50482cf81a18a38027f64791d6cd6809c591f605505a9c27a5000000000000000000000000000000000000000000000000000000a14b3f6bd027036f2926f3f20fb27fcabf26d130f180d118d8b444c54bdb1e47e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = e61c2eb131cf65773d6d1724e9f8dfe1c4719ff2fc5f13c5d786965f40efa36e918079c591d03300efb6e5a92b50858e31aaebb73af5b00fdc9c55fb5f2abe77451d5bd08d6790ec05b70a62febc6855b32a11b22a0666a379fc6b6a7a861cc831acc4bc48d683b3d63c91440564ab71a73f2992f91026aeeffa6e7fd12971c8b83055c5ad05ad9a4638e519498519f5ba972207d9f3e70f5d180a78ea8ad4e7ee4a27a3d17c351b596a204bd67e33fb290cf7a766ee0564bb1b891b0ce21e9dc6cfbfdab0e3a20887acba928cfbefe279817608819548b5b0c73fdaf2c3d67aa21d9efded46b797107faba6479244017bb97e6f1d876d71309527027b9209ccd51940252a906a5892852961f0ce153da08bf6809a6141ba4581a3531e948073575b6ae4adb0f90c959221160725979a78b4165deaf5e1810b19b23dffa92c612401ca025a170058227f6f11f6913ba484f059ecb0a8bebd2f99e0b0defdc01ae3fbe1bc0d5e10010ff5b499e5cf5953f2b7488d63df51c876c2a9e3cd208a9e4d1c8c146df1051b7788e3c500b4868feec5d1ced4a97f916dccc355873986a1a67995eb898209a4b04d1007a5122ec98d9d6120c2c1380cf64723949ec3ba586e3ffd90f532e27f0f9a13d93094363fb65595644c4c05f862ba6b991aaf231882cd8c07665677994a39ca3f59cd66336b690f1f0eb50507377f8fe88091537f14b60d9f7004021a2f58b542ed39bc240b142aebf4407feff1d379915919b83a5cf8dc63b401fd05cd475294219758d7c0eda005390359b92aa403ed0feaf98780c4c2d20145967dfc26676a1dc998ece21cbfea9176c72117cec4eaa79d74207bcdc39cebbd53d6198e2a64731ddc14291889c37678f571a0297b041728dda829b0d2daa5db7d78fdc76e2d8fadc2d12249aad02a9548673a2478770812ef9a634f80384f0b21e9dea74e30bfffa64f9b62098b17217a59bb277f74a15525f719be859bcb8f282643e184978f44f006b05959ffe3978f9e2c011ae179ae4c3021ba9e07b000fcb439df5b1f460a34eed835b98e64f7f718692a43e28646885e +expected_result = pass +expected_shared_secret = b5a6cadf49f4200c81fe6389a7a59889614b10c64a221f961894b34feb87fccb + +comment = Rho leads to matrix containing zeroes +private_key = 476660dd0401afa8203b5c280d87a2e5744ce6d1cf1558c871429147b831149670c365c5f80c4e5c0aaf84ec9108d07e25404049ab6a19415588b44eae659e9eb366cdc5c5e9ca96e9b99014c74514801868f951d841acac4210a3984b25f0717a774aa71753cfb3c9bb85c5b9eccc67a48f271157739cba3fc49c5b262388b2176bf3789b8303eed08b03034cd2f24ba06923bc1644ecf576a1d77283c359edf53f213662dcd6410044af7dfb3ae0a3aeef96857a169fb9a9a586db5094b3773750c0c739a73b0463e9283d219a2b277ac4e76ccb4e785b0d6c9d19025a678c927e041d892b0403254e2bf24345851ae0c759e7f159848b9ad1fb60169ba940b000c42c11f6aaa6fd731e29401d3101ce48c47c6bda5dc818b5268ac7ff0c6a36cb5410927ff8290a363524a55bc8a4208d79e732a53bbf2177c6ea407c313c8d1bd35c489ac161e77d0e54cb767407167c06deb313c3b17f14c3009c308133059eb6663f45d4781e259e9f2a7586c5bc28c2526ee90b845533e18304c5a3801fb9bcfd1c0b03260486d505d5c1afeca04ad984813baa9b636695865b3279617d194296514c9c4a4189c9a645e66b0b798babde151949e8831570490bb227bc01c2f7880d1cd44640a53b1d618fbe19499b25b6c1aaa8016caaa893a87ce65502c8bf4fa4015e74184526562bbb1ecfba8eea78098c629f29c4097a8bc9c6d178e54a3f676a6e40150c865c114d133589c23f6263cc8caa936e03231921cf8fecb748c6baf32c639330b52e9acba2d3907c7b3b03b85fa063ce9669cb2d64c9d70488dc0b252727cb520c30395a67e3aca14d3c8f03c19114e756b2c1c2503b7698c40ce5b84907414658819968f6af91d98ea5a08869d68c86e293b645b11c83461f625b8f0867ed02a1570bac00a8286c3aa9d7f1bead11a763bba0488c428aac1875d265b9b30b1220b4f3cc4830730085ab6125b21586bab169d59847a7023b3bbe164c6ab8746af53a5d5713a5a4969ecf08402095a4b4800be70240262b18e843022d538c3cfc5ef462c8ba3a287be8be6263a832d1a5c808cf5c14808faac9377487c5a12c1f3a8cb79325dea5768793b77bf2452eb693116404b289a456b61160697f867151004111fed55c534aab5a2584b6a16fd0e7a80a01137e92931807aeee17b9767a8d862914e899a3ac03670d7b41711a3d5f775e7d01258c584774002850087fd95039e456c059c27448c0066e6a0ca3c22279019ff1dc29803859992214b32b331d06120521929ad42e57504a74caa64f815355a0ccfceb229de85188c1207d03cab1224c350179e53a6e0e46389e06d0f1577a4dd572bd758f92453efcd2515311492b392f6cb1a89ba04b3685afdb97247c049f199a4700e44afeab1a36d553cc8b535925070b250c1720bd54f39d271156dec49dd6466fa6d98dd22b6fbef6a952e38043962dcb4a2bc96582b7314f59c8bdff43a4dd73623572caf0832c4cd9b9cef35e8c25bdfad66fe6932f37f8b493600fe1a954cef720e669951c1a087808840d460b5a4967b9175f31000ddaf216953011008621f2d9991a4973e32862ffa8cef7a6805ab478c1075c0d3b85fef04e8c345cf3d031ce21711279a4d2fa8dd6f984d1fb9d050785e0fa52e0e114d98a6ea5e320ebb7515ca1642ea1a6d8d119962801a23c05df24b1de20073e641eed63996eb55225093fcb21303944cb0a7b8e48490ab13661c443b1dbf0a95748c0dffc3950e91ec8b0640f208b79a6a2d5f03c38537bb571b2d0f93cec8c562a3511e7378fb4c72e6cba9e2f8c60fb160f59f33a537543ad50a2d1933a650ca66a7c5b343933536a3b98aabf42a6cbc24509b074719ebaae5a34b5d250cccd15bff3015d7f087a96710499339af5894a29f978d34c4e97116d182b1baafb829446ce542299fe65c52e032fc45510b36a512a27602fa447c010411537b17cfa59a81b33eeb476562c92a201116aaabeeda4591692b17a3b72e2cb33d03293e668777c04648d91c4b4b729328a230f53039a5518d2a723dd907e1af95365406d93b38c2d4069ae2bbf8c4b8f56262695e371f11a3fd9b46f8864723ae507368a813ec5af68bc8f6ca98c294b7df8e7bc9ddc83c1862e1d919130c12cd56821ff09275c85adfb25524bd6000000000000000000000000000000000000000000000000000000fa6c4badc3106ceb82b0fd0100e27deaaad2ff80fdc8d6bc31e0c360552a7e25c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = d0413e5b700b33eae7fb3f99ebc53ed20c0b645e839b1d2867378a9aecb2761fdbbe63316016a6f94f0745ae10aed7734390f0f88c112bddd0cd8ded64b97702ebe24836302343a2da87e5414220e24b453ceeec2f0c1015b68f8eea433d25401f2de7efdb50fe17e9651a7a13b329af5f4afcbb8056ee66698dbf42b56d2829dd8bb99803a73cd5aaa07ec0e09a01783d97c2bc8a6defd2b150f7c34afc62c823a5210e73ae7bb4ae84770fe33ebc80b49ea69ecf0cbb1d7514fcdcce1d74636df3d970dc81c7bc564daed20249096310dd4e5ce7b91e9d5abe046d228edecf4faeedce6a3c1c232da1b3ea3ba54e352b734b834d5e4fc7c5d0f7d57f752234c0b79ef3b2b29ad4d7a8ffdeaa75bf214c24cc01a92c789716799d8cec0c89317761afe0ccf1282836b2a29260bc9abf2a5f093e6d56a6c69a76ff50fff8dac59c0fda33815ed358b18dea26bfee7911b5f09f54d3ae3c49a9bbfe7ceb41c29072f2d7b5524d027e9c3448fb8c5c7d940b7ddc102df795b7ecd5370860ae3e91a6c5668ca8f54bbbc7256fcd88896730b962cdf395add42038d1c892658c8aa19b8735e9f96b90c7ee4dc93b622b1dd0029774f368ec583feb6ebbe83a6bea3561fdd6992ec6c828c3b0232391acd8041b41e12285ecea66c1589be393096a10fb023e7e6b14f81cf45cd22a95df8d5476e8f8aa6da2e69c4715a1b5f43e3c3ee45b112815f743531e228f7947087248f19fa4cbb2c54d42ac6bd4afa8396ce631cc65403c995f8f110b8e3c228cfd22a82e13cc5b314915ef19ee5fe4c66c8227336ba82591f2e8f9d0f0ade5b9b783c494a084bdb8861cf9990963c72ef48cfeae56257932d2f9242b7fac70a56e35cde75ccaa1ed1f5523c3982bbd54ab54819fdb1750df83523d0433dfd1c450dc9c1e2980e4a4bf4f3eb2ebc2f66c9195d6b2d1ba90f187acceb29c8fa7dbdbca949b69b2d532d36cf37133da291888ccec9a8f23846b0201f12b8da6c7017f78c43ed07b831a72c124a631eeb7c0ae5e630351c5d4eb5df98adf479a54b62760a32637433cb9b461fae6dd86034e7eee +expected_result = pass +expected_shared_secret = d48aca6a05bdb23e15d2fd645f4238aeac249a93d6a6dd6d6e9052d924c67e69 + +comment = Rho leads to matrix containing zeroes +private_key = 256aa419a0a0599376df15844bd3a95853520fca2d9b342b55705c896845b0a8a8b35356cad9740f34ab358a3da5b9596de40aec0190676cb1071974c3e516e4da5249da1fb7c1b434d997341751bcbc3951d6265051b0935765ac1a9ae878618ba74f7bb88527c1a433b25eb2f635f4600904814d4118c2137ac368d2abb13b5accdca1ff6b5d8af9a03e3b84ebfa6cab2b0ab1d727fee1954dc818299b9ef1b76bb71570eb6cac914abd084168a88129e163ca69706b167cc1f3b5c72546cb0075a230e42cdcb27ad4a2554c43b66f4ccc55ec7683688e3689282924caebd9890459323563a05888b48569bbffa223efea27c86aaf27263251a9b3b7e00cfc0b1d05d448e291731bd81fd8d2b474d4c325a7a55e7965e514abeb5c9823e53dd55031298978972c4a6f8a4894d19848b39b08a02f89159944fa1982a37ce3c41946f5b907829b3db320a22921a582a94163b3e66b462e628228d82a9e167368358eb4642afe14a6c5870ed36c36b7ea7fc624698cf4c84e725b58841a40d581bb8601273756aae8cd6aab475df08a740a725e37cef92751c515715480cf1a3a52a7173754710b2b990d618b8eb2f532e7d37709ecaca551bd6b556afa1545ac685dd4003e16b016811138f4e280f76303defa440d395559a13ab68b1b6d26c75ee4865238192c24ab52a1c15f2a538a240f9b75cc6dc45b10272ce8048584085f4da6c1e182167eb9c419a1a0891a809f3b0ac8247dbda3b4503248ed4535b77bc7abb44706e12b0493962b302b48023932f18c918451528a81a1c0cf6f5731b8c0680ed257432a4c319007be80a2087c64a3821a8ae08e9012be3d1cb62d229130e41e6d452493035dd5a49b91781f47db395e5bc663603af7accbdaba6473f56c07a763bf9730d18cce1da3968ad114cb831d083a5cf921897325877adb656a483cdb601f2d3ac36a49b3e591379a22063403c97f82aa50c761ed1a289fda7a3d4c2ac67b1ae5b73e5a2bcfc220ced032be54313bd2c15f685c5218113fb822aaf2126cae6904dbc16864223f8ec630debb1ec282ae2eab41941a891473895ec0a867129c83893eacb17cb75b0b2093ba42166fafc4986c88880783c32989b05c366b7601ceb493cbbd770debf879b69476452c3099c938bf8b45d6c454bff7976c96b0f295915da3b4b7799fcfdc545c3cceab238456eb75deb43e3a5a631d274d14889453f04a93e50b4045196605cee181cb40488bb1c8485aa0b506a51fc6983f5454173039003e4b8c56fb3a18802c6562907b109200cb1a95c10a82a735d4e940fd5195e2da59f69a66d618279dd60def2c80e28771a7d814e1c31d251c3c5dcc7cf64ba1a808bca1e7793bd6ba65a31c60dc1b9897b3917b5665b1698a009bbca6b3a94504d00c0f49078109326bd8a46ef11715de5a9925bc569c577af3515081182f6c4a9106b57589caaaabe54c3bc55f7328a9bf69b3e08a39d9e8cb5ba76f5d5092f7394fd04b008deb993d8b2a203547d9839cb719108f1cc581f561cdfa635ae76bd0fac0bada073de91c986c9e5f04218604a9b6543e931cae754a1f36b63ecde30502c9503ccc9d7a18cf80dba1e0aa1235b326a93922c7fb0fed269bf25a3d720327ad01c09222148a8b8adb1c5d54b8606083c3180b35a5d2c517770124580c32cb9d3c37b1a081438349a53c9c1de3e6a88b854eeac6796d2a6d2e9197a8f21cf1907b13094aff72607ba31b78ab5a3f43256b18a6d1227b65291fa0ca23a9684971f4aae688ae1ae5212cec0252d47fef21429192be0f291faf63880cc4b80d84349a7acdc18cc02798bf4150b54212be25e255f784b9e802033e3c2783243f63c87cb3e005568a77f4e537e8809b78111d701c1666449c38795fd1bb5341788af1a948e780a011004d90c78d4de5ce9625ba1964ccefd81917424b9caa3ca53cae27e933acc33c48593d8e731e2e28c62ac3a691828d1b965699417ece40bcd0b7b525ab0fe1e30034f489568a85709c3fe65a8cbcb4a42a1577d1c5bffdbb0486fac9c99600adac445df224e536a000d3ae463373db34cf42768d5a05b34d76927164b00ea29b511204dac92c7d0a3a36c3b050503912916fa9d69ed8c4a74396072bab6861f819e20b617721a74ce958006ab2f6ec2e27fd0000000000000000000000000000000000000000000000000000004da6ba355f07499e0d07018ecdf08fc84a80a35ed292e98503b4d80219e004afd48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 7b63eb35e66f6f45586d1bd9d76c581952d352babc1df297aba656f1abfdcecec830dadf6006ae178f5a83ae34217dd955629ed59a04f1273b2fad258da48b3888747f05cc4017179f329efeeb591d7b2ec3cc9b510e3e9ab769e77dbc594050fc864bfdf33899d2594b651c2674cb52dd4b0ea7b0ef672bd5689868d0560ca059e1ca4b40e77d5f4bd17569645e349bee8666dd3c78d2680c08e1fb9684908513ca43544913536c593b8411e8726e9210159d0477474a66baf2239dd5dc7e390c2bb5b798c22a9e607ac7b4bedac90c4a414bde3e53428849f3a6ce0ce629d3854d26cf325fb2b8a67c1a896495d4091c95672c45b7ac10d053b540de99ef2f0666af51ada4634ad4707ed7ae593b1f03038e10b01efa66299cfaa9003c333203cda5d1cf95447f96bc41067706e189460c26b6471ada9b800449dad04115df8f9acfd68adf097b0318d32da248bc5d979885bea4e4516e5bc7e2313c7181a676780b9c2abf90dd69e478439813b2ce25a97011f9bc2dcca053fb139cf1c2ae2a7b98a3edd4f872d251eef7e3224a4470cd07dabf219303b7d8a2bbc8fd9aa8e2c1f6a474bad9a3214134cd425077b3c572435c2a36c8dee73ed60e90768efba107d1325b205c53fe8cf121a1ad55bc0956c8bc435dee7d60ca028b7d7b37bae0b1bbb7feaa5cd2d24ac3ec7f9003424468c9d6b784039822c62f2219a96ce629776fb55da80d66fa2dbf6b3b9cf791103c171086411a3be61e9ce2cd7e7c8e2fe7409b6a9d98a0609cb5bb1d5a85175a29ff68b98889efe42556adb997af34f7142d5fe83454dce13825abc0f59a622b2c32a35cda17441594f2774613e117fee88a2cf3470aa000cf9086a57fa3269c354b258872624894455de18d4e92d0156a374c1607466ead0044d30ceff854c5b7b734ba2892cd671c51c9b6ac5bdda9808f486be2ee0604bf9da931ac2be530016fd5917558347305cc0e49d1a1b5ab1fd7da126d1a72936da3730fb70101acd7f2f5cc40cd7f29e49fae66b6cd26a88074e6ef4c52bdd782dea6355bc9ca94bcd07679f555e8831e0e5c058c8ca3 +expected_result = pass +expected_shared_secret = 483cd507c824b8cc9b247bfdfeb2bc33a87af648ef328ad4855fcf93af9aa72a + +comment = Rho leads to matrix containing zeroes +private_key = 2bca01078898594b8eae01aabadb52a8812e73d00cc5f4a63c8298a049b146d4257d01c2609b673c256342b21e3dc75644880989415099e10d00754bc9a68371f30d0b5c07ee46259df9a4942c0483705f8468591ca1c6f6d8b83c49be1ce859b2c16ec5dcbdf74895ba7c6b2613709522605a439ba87aae32262695a48f48b43bb5db3fdc259bf5755114d04802734013042ccb8502e4f36aa832164f612ef7886a4fa4a271b114e17b700711b385b7c2abab0d5535128e0c4db8d934e3126e7b35c8b253204df1ca27a5ba991a5d8eb30c09b17a54d672a1e266f6b3460b015fa00aca92162b85f8cf7972a7f6b1a5950280f920903c1c86a97428e3d5b5b2974fa0d22c730308aea2439043646b44ac771c3818bc5537e304de3143d7554b0e464b21ba5cef60023ab18e58442fba49a0c013a5c3a067feb8111f835a28fb3d99384a72f538dcab39eafa67fde22352c542678b3191c53103f399bb0348379c5d3f814405639a8da76b165c39c0784a61ebb997048222b8856ab6a0c71b94c6911475e9426f97b045871571c87ea549707adc2e23a09bb676bed71caf2ce511510b3a10197878fa0c7960a233536e3f724098349a8649bceb09afb8c2bf6ed34633ea6d2451161b76adcdf14a479845c1639336cab5fbb5cf2db5a94e7a7a0034b7325601610386e3078e26129eddac40e9087140d29b7e10c0d3b0322507c07a753d8511af66e43aa1c82ae152351f35061ec76a8c5701870639d138182740cbb17150495ba6984180bfa113175747d9d897479c50ce3328a5355a98136de4e61ea55a144107a397cc798ee99fcbb31fdc222e60bc05616c5009d3cef1f89e8f32a78b22c7412633c4aa309a70492e97c1d8642f01185d15400a4778854abba1f703c2fcd0c7cd5b5326fa9775f39ba62c171525171fb084b6d73d9603c26802cfda46cba85a4bfc7503e06562cc48aedd0b5f2880820209cab73b8194c4106cac8e93c845f9b698aa8351722bb46fa205c4509f726c19b01c49269268a6dc25fe9a59ce21cd5c0caa5be2c76098b5b0a5ac2b185a32f18be4d1a77f06789a2561f163735f149e6c3320173865ae2862c4204497c19bed7a6f06057ceb2b310bb20f06956bc9db330a6c034d30b2ac6a0094a0cfd7fc05808c3f588345fe70687fe9522622540ee79986539bed02bd9155caf48c62f5099fad44a96976334ea2b2a13992677a71fa8c437d188573b237ece8a129d387ae6a17f09517d599a36a4701ebe4b5254916d818c9e5db1ea6e6a9e472c8f7022807ebba4e80681cb9436da54daa5b611d80cffa4178022759e9632af74c5c5f4bc33e24b8767c2950e705e2183d97aa751086b5ad3649f11c8ce5615037b76de620a24e73b12b5cbfc74c1d036294bff9afb9f70be674a11d7a1ab0571112e329723649a43cc58293be8bfa42a1f6c1c568cbb771250aa46a988cbe93f408f2a117ee26a35939541da8504be197de36b0f17b1f2f0b7450687a0ccbce2fe80be97cb7e59ab3d84720977a15ab756952713a37a8b4f9734beeaa97c3e11496c6396b7a9a6a39ad2854ce57328681daa96322058b1b7f9647741e5345a955c735303812700ec97a2d0710a60ff89cef9053efacabeed5c58f958944953eee1a6d81540ef40b0f3b51c42d8258b259445d114c8749662be08adfc2bcad97191b888259b5a7a6cb0c4c4823f2c05a71c58b57c031f4b63eb4870409f10363169fea196cd1a36717f46cf883717aea530009205285b5635152c154ba7a0845c00202563b0c258516eee09c81b0ad9d05c96a7987de001792c14f280221d99063e9080edf14982ac6aff8f51955c3c3ac25481444b4c2123dd8c448fcb6a411823844801fb6d20ca650bd721464537473d79cb480e44ce7e0596c8633d4b39262ac5fbc3348edea1e4ffb02a41311fdf280ed251bef9b62b98b297112b1a8b09b21c51eccab81b6b81c746b76726b371e2b632f923dfa42bcdf7a9ba5b395552288329c99c02306e7f50db94b371aaac69ac092733b921adacc05f2b9638c7e71d1983d8c567738cfa0fb2be3fbae787cb8e7a016012c11529b410a44474054b7953babf455020f9a5e42f98619658fbe70c50a53018e0454f31a6dfc6c63b226801fe141c7410d40866eede2b90b000000000000000000000000000000000000000000000000000000001cb57b03f7a815315ac7ed74a7fed11a10a39e5ec11a407d019763501ab55a12a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 2da50b6a160734993ab29c5049fd132864ba6a725ccaa46d0bcae2c795f38425862e56550948a6ac0201a93150b9c7418dde1b1295ebdc24e998d1795939a882d7527c36e2c789362b14a91a1d3cbe9b0111b18d70b3d6039dcd90c73d14b0fc9222e32e4d8d56b3c74f029b8f9ea27aa9b9f341b2e35384532e42a7a19693f20087cb4396f0e2fe177ad3806ac8c300710bd095f867de7cc92bc4d2febe7c4e2b84a65bbff9fb9a5d8894773ea449c9e378219a6122ab6e456969e3cf03348f89266bc65febe36fab1a7875cab8143411fbf6f27f731bee85418f7f71172ae58ab7c25995636f81762f77c1d693ce7c04e7d0e852c69a23783a16ccb9af36351440e3744418ab478e63f5773f124332440fa65137b2eec3f5ab36dfb7573bab80d972f45c6f324ea92f346c86356e31c8249e00a1771c61c85e7acffb2b0d96c6415d93941e0c06242da487525e2c318ff30eeed48d0757ff5057f52a2e9be730f5cb7a4698d4ee6b406129a6a577749d1827ef5321b208fe92eddc05239a4cf7037a9c89d2633faa6594785dc7f7447ae0928354ab9443a2f173d9e05cb8106ad4a0ed705e0dd90cf30d18a24fd6c1e669e5956458ffe8b85016fab36832c279560c45ef62a6e8b07d8455058cbbe734e1d519f32ad83ae76b0f39424f24287afd9dba2d5e17311e0c0f2ab0d35c762ed3f02ba2b9e9ff6228972e5b43598ae0666116e7180784595a8bdbf10c8e6340aa67860689fc246370f1ce5d61bea178a60c35850616360f016def374fca8f2f7b25de2311f609b76253736fe748ce098f4b25c3cb4f1307d1c6960f46533368cbdd8e00540f6a01e1c19f7724bd5d39089d3c97c31d99f693bfd680861d15a1ed8b2faeef3c2e0a895958d0fad228dd6b356bc202b207aaff77dd22e6e3a055fdf6abc5d9a028845fc0374a254bbe0cf0618a2441b7d2d03724dc8cdcf34379ce66a761f5425342ebf107157eeea69d26e6309b92b4e5f48a0c10e402574b8a616bf715aade0d2200ffc1afd1758e2779df4dd0c2846fcd13c83fa46c89460611dd30400642dfc18da2019a71361c +expected_result = pass +expected_shared_secret = a254f96b5d57129c97541005163da56f63ae0c63b559716fe001bb26271b1425 + +comment = Rho leads to matrix containing zeroes +private_key = 5e26b7850013f01c602f7c46920760ae15bea4b99a815252ae285dc4009530fa45b8a9518e7b6466ebb8bc624efaaa49a2e99930c760cfe3c7fa4368bdc157ded5ca95652a35200490b60f83eb01cf5158d44869cc50b34cc5514ba1189cc75800d19a1dac261f02905c548d91d283e9b2b47948afc9e0230ffab66276317fcb5f30947186219add4a43132590ecfc94b534432047c446823ddbf9caeb57b277ec090c64766c54836bc58bc8497673cbb8cc1637722978c98c9e9c4b0d332498541c86c9161d5b608cf83b25e3604a13f2071cf73ae94b465bf71589307c010ca5def4b5574327e22722f32a73853cab34a2b36711136b6cb4f69390d5759d33a5629b772b3ef73a382357d4d46f3db5aa29708ac6760d33352466164f4a2291bfa04d51866bfec806c268148de4b909403aa94962c2210f992ba4e68b95f8694b08aa0e3bea88158a44d70b55e6175c32893d1ff72714e3460b863f1b9a2afd50b991a540c1a94047c030b58a11b38b80f5596d21c6911c379f63b46c2d705219277bc5139c45165ac54c28d5ba9fc736ca7966aa842317c1c944ef86800743b53c87433b9c1c426a33983b15b9a1242c17947c0358b8f40fb1609f8c764618834f709b9bfb812207d456ae239fcb8a5107a375fba0669dd8254bbaa9221594e8469912f99da8ca1dbfe337d9e26343b17176128dc70954af1745dd200f9e72b2441557619233e1442147d7710530bb4d51a4baf7a3f1672af0641c3b1b67719929a0b82e34b96254e50d97d125b76815d2bb28e088c5e5b31f162467e284aa8f13b165bb66ad19ce3e6877a477219af8121d3501a89bb1b8daaf4856088f2826947c55887339aafc829a4866e34706bae16df2a6c13aeaa4a3b252b226ccb02919a7cb3229943105506c93c97027642531689236842d2cf059415a87698c02162c37848043df81a2810b75e302772d2a7d073409a7a14e9ce59063367e34f4a78f9a8b9b404a7b6a6eecf110da12b469045dcda4625f5961ce6c52a7853540cc9d5721271ce3cf1b90b1d550107231ad3518243eb96410e5513d4c0362a84b749c7ef6c14b66c025bceb1ac63c8523c5b2ba742588716603246d258449adb11b57a09b54b32ed3f2656c138b16e8055aacbc1d5273c1cc4b3c5213b9f2a9422908efe51fc431b5e7f75a74f39a2ad310a827b743c1376a467061146b5db6149a897bd149b8c8b4978c430c739069349067b063a27024375d8aa5a8157941f586f1846b740ab4bbd2b5cb4243edaaaa802934cbe53202074a6346a599091772916d8d55624f8b16f74cb06d563f845b3b1a62b46bd0bfde75cd9480306d31ad1cda8f1a359f52f338b989c5eac3c1ec90b98124715ee68cd5dbcdbd995c533c175dba8bb3b429bf851e6feabb5114428ae2577197948372a267c57bfcfa1fb6e20ed68c62a266b68d875f41a394e972ba8d08205056722295c609149d363a18bf601cbcb81340270662d22ed3613342d6c7a5ac05a17b8951eb246c750d9fe2ac7e4423978a65a58855ef62094b571f2277b9162b44009331d2e4581676711253cf7fe5b9fed57c4425684a6abc858b2922f7c496f2b6f278a892872ae4f31f23394e77431e12fb6aebd20c460a915547bdd7640ddd6051499169603672b8b1b304b6ada2b3740c24afebd86572e3c8480c04dd43131537131d619079f95dce104eb9f1591d5a7ab1182c74169d083135ec094f56f858a38b0c6f147269a6008bfc11403b27bf66a7384b782668cffe08a4c3173e11056aa2d33d48072b08fb1b37d4964eb92b08dcad94e429b3ba27af65727948bc56e51019d826468b8dc31c8be29116f57b469e974494464f1f906e938bb2b8dba85dd4c3698128ee50c005fb3b3904cb88e313bef89152d4caca29b7ac860da3ac12be8a7dc8e3a259d1aae22a1965e55242f48f66c92e3a434855852db7a467171b5ffc91ac0a506fa50214a4898c60f5c057b32d30483162256285ba8a1a03214f5038d8b8b68b701c928b2f60fa84d64aa105d549c2302ed24b46a51aa676ac73423b431071386bd6bbee9732eee9c932965ceb756075733609eb99c873ca10c35a160b15b767099909a321f553623b2c1453489de3950aa04c574382d5023888e9898c80c5c3dc23508b28774b00000000000000000000000000000000000000000000000000000096a5c811a91591a62eea81d32fc7914b2c43711dcb25db966cfdac782317c36c53f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 7a2556b83d6dfbec6d0c397b9025d4314eb6ca3efc9e954030737f2d72388b7e0eb94a5ba8a078945b6e23092a83e5062594c9606004658c91e8fe2f9ec87a66d99749b828611dfbdc0ccc4369a2f73aa9d5028594fb25c6f35fa3f0959fa7f361d3e60d3ac4ab29135db5fd944e402a2c070ac6c35033eba8d80fc0ab0aa5a0618e00da810a1bd858b15da0c1eee4ad80e0532febabc78e148ed1e7b1f705238615f3224ab36870b4066f60ca0d0b47b807aa34a763e7bbe51d015497f1ebbd3d24a777464e50c06b1820dcec10b2427837e4c73c05a6495fd4adfbd1d0b921e932e8dcb4bc2868bb19cf5fd00855503b8ac059b04ab583b2597bb6915181bdeb20b493d2b993e6816f0a4afc8931f713f274987153246c394133f6c51224ec5919372ea8925a3018ea111bec3602203c5928cb25b895c21678f7eff92cbec847a513652cfba4f2dbea6c9f302c25b6ad189366172ac177e73b5a79fbb9fc832d0257fc2c5059ec31f1f6bc27bd33c81f522107f9f59056b4b165cf4843383ca3923f3f4441400e19b5a232b74d59d2215b0b1f7f52f14797d80f9788b69586ef08bbb8864db10e91721964f0a41cd5af309e77e926deb44c8e7e4d97dc93d909c0ddef9e0b57e0c804690636dcfb9c69078b90ebc41f7d00851219619462ef2d073c8a7c6ea783885fd32399f332ab6274e0ea0e0127d4ad5c1d6a5c643d685d531760e12fc138dc3538293c41cdb23667af9208955a82b5151994ac911099cba768019ea70bc524c67d276d6c3aa21c96cbb63fbb83502f8191547afa6af0adb3fe610da54bf3c7bf863019ac965e5960543c9db210df3475a3402b4d078aff792aebc7f7d97ff01508d01d8a8bd7d4a28b5966c5b360d5967bd8179f0e184acfdbaa72122fa29bb9ab49db1676e5c8293d700149dc0051964c1a9ab9ebe2f1e581362ccf8d3c2f401ffec1a521148be65d1e509bae400721670f2b2aa067fee9f19f35687ac08b5f17789782cc19277d8e6cce0bf775f5a723ba5a68af7650b8bb3e05cd0ace1f10bfb03b3b9d4b1c7733cc5a51760cbae55e7cdae3e052 +expected_result = pass +expected_shared_secret = 0e34d0eec6ab70ad944b0c01940c5f13c83c14dae754e007fef6e5ddba5b314f + +comment = Rho leads to matrix containing zeroes +private_key = 8ca008eacb7a33b54ca796b5a0642c46e86b3e1324a9740e89d619259a29141ca64e7a06a7bc5e609047461c825bc55475cc983eea8882ccc07825258fa8c581bb2df3616d5d7505543017afd693a8ec808942318bdacc6b5b8b6a859bdc41697816c633575fd3201a301398b128597ea731a8fbb4e57898c5a18fd59ca657c0a68ed7184c58a5f420b88c0c514482ccde3a93f0c93781f14154fccacc50853a15b249088658198faf7470d778b4a8d1ad3b69c3bda9448335ca6cd207f8f6a3d0b762521686855a76d639401b076620cb1e90438ff056c857291367ca5e36d581d9fab56dc3a875813ff348c17ea77e1422b8adfbb9722bbaa9fc140b950db8a040cc9c2469746b00c72330949db387593d494ff1a964e944af6df216bf07aa30d1c87383949b7537ad6b37c0c93bd24a7c2244b3e360057ff03083cac909f54decdc5a729a8743017c55c803f90934bfd1bbc2f18a35310b5343c456b5590fa270367429f590908dd9bdf422758c480e89018e86c39493f2991c17756da60587d05d7b11b5a5f34b2e649d1b18b5ea25692c362f6e369535f943314bcb555895254b47c470ba79031f0c4139f0689ac37670fd497dc01609dd94c6a8d85aa102c92e9a020e9b96f696bfba677a02483be923a2ceec6a75b01d49ecc09b2ccc5573cc7cc2747be9864015b972987e024a5b0aaac78b1119b7ac08b33a2e006227f6036957fa4a03c4a995444215985a7c6147175132f2e6927b85568ed151b0f516b9672cb2a84860b86d02ac0858586456c82ca3068cc8d1a6d15c6142c94a89097dd3d5bff4d616adf02bcf6153de17a22b32880c2827cfea9fb1fc690cf441b7ec9375c6c249f57896c00d7f419265c87e9a99b3148b51fc9c3b9cf85d884376a61674fd89a2aac37119041dde630a873a5fe6075b59bb00dc667d8862539e89944c5a58c4983bac248b3bd19c9690872ff62170aa198f27a2a950a80ea232bb39c47180701a6362d6ea3a96e284f56c25f29566b2816a40096a65c97ecbda3a96224d5145c1d1b3001a26b484a584c5251dbe8695ea64154a5223ef025759f2104124373191150cd7242e627ef0fa82e7ea8583221d6d9cc958fc0824d5bdcd51605cd65112318ff5eacfbbb188467852d683180c6715a705cf298b0330e302bcfa0390e4734d41c44974a58e9a56c16327308714371a1df8a72201b84ec7912a609a70a477881fe802e62b2cebbabd668b3f55545529885f96f1494da6329a387945070f5cbc01ad6722b308562ad78388225f42804e88f4a8fc91347bb84aca827ca0959666a71c33843acfab82e469c953a9540a587a7dd661e873cbd5356dce8312f188a8632858ba919552e22de178bd9710990b3122c491531e142164e7936082036c8a1092e4498569afdb9a34bc1371ad92be6de0b49b67687f16acf1047d7e926c349b26025c3d2db2997d9562916c80c672a98b5b1769052519db383a5c2de4621bf4444e3c920f03d4181f277747a6075ce726b9e97f96338382c61365fb64711c5b3e0180a9416307d1ac7fd980059764067742ca9acf027442c71a7a208ac907483578c15ffc9a0678e29cbda6ad344894feb4a6b57bbc5ebc217308b18e178046d983bfdcc5a278061d415004d354182ccfb2eb0a17167e7fba7908903d8d3231f2c49c5e45be8de5a0c44b72151a28621a1ee055866ea497e65016ac104753066fd32978b7354562123491190a1b2700ee0575a5356cee89adf14996c9719df840189e558536e3ab8a3114be5294c083ce394a478e5cb63a1099923246f4a94aaca7cadce661ba90c98a98b79d4c1b460582da062d29ba5b7a0844c8f2267cb5053989350e228f2c489055b4b40c8503fd17039ea1be1443af54d4b292f9599bcc009327634a6a2ae0d6553604ceac4534569896fde76c31d667284264676b57fa8b2c9f10cacb1257b26c7dd27c6ccf96b70b5bccdb437326c39d453a83d05c407a5153a24a87446160486b07d4f6762aa19730086a98727083457eba0c14cf29c5483249974a85f6b112a0b31e580206c3c125a3f893f708afa0d146cf91007fd835116444b78731e1214a52856e50b31b8c929e9a146d1333655e09922784bb3e02068dba8861e4bb84b072176b29284759475205ddbf1a91380000000000000000000000000000000000000000000000000000001d24b997c42a5a8ff9760f8bc7f667deae0c2c92a486d75aebc5778860a0b8c6e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = f55fedc208dcb1c42948aeadf8e7806fac6ae3eccd1d194962b78e2e8f6baa837470bc53e74a6d742ad926800387a6e89f8057d5579485369880d9c0588f66b2e1aad76158b55f5deeffef944b911b6d3e28bb7fc86d2c7ca61a156b1e917ddd4b7273af89ed9520baed2ff60d6a4de0d2c568243c7b9bba5116635a2cde70d8caf1fb17b42cd013e0060422e64f7b68438c50f20c74762023fe544a842eae40a43108adc848d1895c46873d86f0935abe723eb7d2e43374b3370433bcd8ec0cdb4598a1c8149c1a14348abe397f7025b9859ffe64aa258d95e39b44822c09073179b5f54d530a3f6abf41106014c63e621c93b0b41d49f5dca8d4cf8eafd98e35388e2c807e4896bd71bc87eca94987981c6a055c9cdb3a25a5f24c5ec56c550effe30e16b1bc93dbe11cd1891e05bff43d337e34ba79452d6e6a15800f2084183d81d71bce6afbe5dd0e94e7fd9210f0a856f5369abb27804cf432bec0e96881ad8e448d5e4dc1e9f69f9f54f4073d02148ec0505d53acd337a664d6b7e57647b2e74380621c4d0e0755455296eecac9c801e7e416c485547ab2fe9df280a0847c0229ca2c5f0ac581c282d5f30140abd9d09c02ec9c9c6754694c870a4f606b625aeb6e849e827a821e3e1359206081579f13ea3b9362c695bfb6e7254a81f00e30ad61e9a0586ed242b72caec9deb6b4dbecc316e0e36d81a733af4d5052978f8a17d39c8bf3b43e02dd7fce53f8c1e977a6ffacd1228d1d93b8c01b756a0a60c1109a1062393cb7fe58d7001798a123cf5a3361e3dd2ac080160a2c01c5fc4af7636441eaf56a61a3955c27d4ee09654f1200a2ca0605ff53f8112366146c8d5c8b0f53fa04533063227bf7bca696fab752488f8a3088de07c9d2b36d6ed546b4f85873670d4e24eee31f446fe42e5a16eeb9daec4c57e6c2e0ab3724ddd2b07d84828ec7816b567e84db094ef9d518f1072221a3d3035c0ef9b61021693a713edfbc1d956522109f1bd7e9f86d15c5f24193196f08befc7db94ca566d0002b4f635ad1cb333531b214609b32751995376df32eae93d0da6d9663cb916d +expected_result = pass +expected_shared_secret = ca31bf45855855c6eb792343942c149c17fab10e25bbfa1a3ad916e1747fd8aa + +comment = Rho leads to non invertable matrix +private_key = 13b21ddd6a8ff0259d2229745969188032c7d4506c75d27340079c57e5c41cf374e7671daf33619a11aaa489776f1b36825a839f14158df46ceabb26a02b92a920424f39601758321ea584f9f0442493c168866c55d6ba5af9704dc36371c31852428537a3a68e9030c19895bd2385acb088048752b65a3f1ea25b539635f113a1139a52b9c819b3e05505bc0ccb8570ab48163af4169ddb9b93848494a2cd4a206051f92d3c6a0192714307d228de792cf3109c29267eeea9cd2ed9bf3244bb455a0a58514efcc8190a5973c33963ac753c6bf7c5c5c36c65cc681d433ee048536e3288b8aab6f00c3c6d28b8f325bd838b7643131ea2bab3aca0b1e0d2afb4ea69aed00c4f1061efa259995407ad9583fdc337739152d6bcc74f4185d56520b67818926c5354470bfce881d535979a312cd05719a6e48a262198d441514f600cb804d0012b5632ccc337f155021853b74c34eb950d60bc63b1d868f4945d018b4c37fa77dcc762c62618a3ac29ccea150fcb77ee0b2a925c1e0dc718ed4019507842ed7a40bbc083bd9170724b0386a1c262096119870e35f791381b381d91ab2284a24a9c4759ecad48b15e3171bc3a117482f6148dfb7c005d39ce411066c23e076c90f0eb8ab227c162535e46d364b8f379b916bf462ba2235bcd68319ea5e7a115731153458a831751f98b9822ea43a28728b2b3bdf1ba59011167e221bf79303f15f5c1cf473fa42b0af5f5970dd40c70752f9ae27daf137d38b299f7a6b1e4a3821274199b617cf3b78d272724eb09b302aa382f9019d8d395a0361b7a7118bc125dca6aad29b01ae2839c6a6bb7c594507e8ccea16c8cb33a1262686c052a703f074201d57c38d11dc432c7dd25cb6629167599991a52b5c7b49766f07527bc8003dc27b65b2fd43c5f9a258873b36ba516538771744dc2706004817c4c9d86c554a4ea9af16a78bcb31e6941778c837edbc60470d9025e55508d9829bd4701a2c6b514aba1b4b8759cda898f289cd31c1267eb0e2d7233e5a22c435275f3227a7c67937b147fec106c5e2798ad3ca3d9755e37e21297e8bd942cc21fbca0f5a93566588d65880f44d4c1ec8a16e5e508f7726107761cbf026b89c580a62abc82137d9b8b9edbf082980416c43444072c9008e2184b557dbc1a79598c5d2c95c2bd7c12aee084c150b90bfa832859c841b235eb377ebe533469660ecf784faf862c6b026feb36508130c3c09196a146423823a210b4250e2b3135f1686a4c65d3f878f6233a3d48264b3302858774be5b328fd801164b21fd3c7e547c65d83894580536ea919fe00609a8f018f5aace9534c3d98c2508841e448440750747d3e6ba2907928129843825b428f650e8917e26787883276ad1116ccbb551de12755a4b62dccc5ff6ac180672735e354dd1d018cad55bc997bb93ba31d74c49dc99cdbbe359d834a65eb65c044b2b77754cd380abb6442d67440adbca3716a36b321766c6f40051617e716a49475ba2995b73b7fa45d4878517c45358ec0510e849a181be28c2000b376783c238c6c80300d25e4e1724783c182a668f9164c8e31112c2723f88087576a4c58e4a8d345c88fa4674ab9a2c3c0ba849847a64cb00d4d3b512758ea9d3892cd014370940cfcc4fad27c4ca09a9cf9a2fecdc11eeb93d88361914762c95e844d80529f586259ca750d72269b9a28336668855460222bb27af073260297910f1250336169de469e93093596405123398c861cb081c6833a9af25911739e9c1ab1a2817548009ec8e6654521e8b6efa3abf96c9354b7002380ab76f251d7a0436d69345ad46cafbab6edaa66123f2389397af5226c99401291b9722ee634d286619319bb5ee1773f799bbe54b6ec04aa6dde72570e8983e244b8bb1a5b0ecae0ae23618fb307c322d21017a241808cea14c2ad2cd9a474a11a2ba15cb99e29464e724322763914b1cb3a2859e716292fac42367120cefc7a9e66a63ef891ebf21739286083e194baea6bc4f84932443adfcc37eef5452cab5c3e67425fd751189e87cdfc3220e041bc1b5399fb28c5da2093993c66b8c5736190446d698be94abad3a7ce14b11454a8b1f2421c2022a5cf00a3329582fccb104c46f99ecad91d1c6caa2845f4202ca5520ba32376f93bce1e8128518b5e578000000000000000000000000000000000000000000000000000000990c38b95efaa59c0f3db38129527c66baa0a056dc44d47644986f0c777f2efe11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 3d2107ffffe42acc2b1d2efaf99ee30467058ed826f28da60d0559319ce694dbae930a13dc15160ae3fe83b1fd4fb012940af0cba980ef348208095e0806f2c9cdb8d692839fb938b4defe6e230e810cf16122eb214308905940b184d5d388c478f73baab6e72976e97d95956bc75743b628696e657bb1e4c2388fd67947bb6cc24d6240b61eeacfb9d08ca46264cd80e62ecb994a23b29daf74f0f86dfd4a4f8ea52de6332b2736876afa6b68dd1ac516b77495fa8b5e0bff2231b827b02d3eeac779d25d018e6dbdfa352ed798ff497bef3ec7a69f151ebc422abcb0b4ec2a30009227b686f266bf6e2c38077ef08c32faf5ea6c5479a06124d5802865db29f44d169c73b4a2efaa559d312d92c885d4b5f96e7e69dde7381641fbf2a65710f62d592356cccb335242f34f641100fe9862dee601e07b90eb026a7325b4b683cdb46aa8a2c47d2576a5664cfca8d3b23d43836669c926c5e7af08e9835f0d098dad742e0e0e3b811f408167ecf9658f59d659d1c379580293e4ae2a8140b4b2bcd09a9f15d2cc6c137910ffd493d7f192bf6c41f0746b3fb88656eb785bc3d1e2560b8a4def7271488727737ed9a6831cfdde5fb31089e1f04a0e7145fbbab824574d73e191d0f481fad0a6280cb3e94ecf346bfb43e5d87eefbaaf7a0f9c96711d5776776156ea9be4e57c72addb3a31d997225b858b9366c02bd648a12c45143c18307bfa72526d6330f1ca626516d8a789c8ec732e0c7f9f0787f978dff881ad3e9ce009e17d13f0f4f445cdcf2b91ac6f74e6b1cd196370d0913282721b149eb999136b2c82a8172fab828305fef2b446125f258ccda8c2594d134a065b50c03b630b789fa70d14fe143c4e69c0a8ea956da7d4c58b3ae10458c59c81761082f3a3ba38b5e2ddfd223aba80b0bf2bf1d9c4a5d97bf42dfd7756d15b63cced76c1af8964260c9b2785e479c2ff391f4817b6df85a4fc05a576534c1125c2ff27513e9730de228e81c9915504f42f81916e4d30ff3475026859ffe0a8b2f27b752bb4e04a3d1e24b3f3bed914bc2ef674cd23d03fa28270f64d5d11e8558f +expected_result = pass +expected_shared_secret = 07fdb98f4a61857eb91ebe130935bc346ef3bb731281ea97365b3c2d2836b47e + +comment = Rho leads to non invertable matrix +private_key = cd28b1e3714f3c797340840f40817791d502671640aecaa4f91089ce4049fbca7b7045b350d36eeb13761605aa4dd87e4d062a5486c5d73367073a0a949bb0852956dbbc3bcb40920d89518dba5320dbaca890ccfca8059539505e3c8ecf80cf404c78b262abf1ca439e132ec99c33328860df5523e2f63232b39d83574ee631591f6cb617268a0b5344d2aa003e4000e821734c8922706bc6b9a9542f993920451bbd131176087d6e53663d46823d5a1da3723149943b6f5c34776a8e7e142fe63b50b6ea600cb859672b57bb07678382a561097dc38740474b60f61656f1331fcf7824004c4300f81fb9bc457f97687c6215440486d04470096b1b5fb1c5c77063fd36254c6464f19a96a8a76644a12663361a36d37e6e08bc76743f812448a8542d037b2bd483214b500ba1c07580b44e6d9093d3842df52c92ac8011f207106c069f7e3bccf06106770a04275231d71c5d1a516d6dac6e362397fa348bd49a5aeae37e6495aa1af2084a42c433756461608ba82534567854dde95efe0335d67a4b37b587abb050bbb999c2e65feea4c89d4560402318f8d89afc7601cf1cc6c663c44a85147e7b4ed39b41e6165b27bb1366776c409b01b0a9ca1e958063ea65f43cc8e7a4b06ea338bfc249e7d2bc150a8595500900f64e1a346fc0e5bac6179c505867f0617baec402229a4c00b267fe479d6e3b34e172c800a45bd0f39177083fd0d15e8912498e6818bddc3084c12d042cb9f2448a0d450b3dbb5eb6968179469998c4a54e7692a7a78fc96998d3844602002de81052e84bb64b693485157f15b054d16a5ab0c593e0118f7745244ffc2b57f939f0845b038832bf4a6d99123a5b95b73044ab6788c000143111065ee4cb9550d06e34b81e70641dc5905faac129662733214b866439937d39b22cfbc203f809d265158f02b7c1a762dce060aaa1117aaa9b002aa0f19a68ba5559bfcb5285a29dc8989ac0ca9e21019311abaa89b5730864817227c0a9d56d15c950453537faec9a9e6c113a023a0a14161bf3ab062c2f9a79a6c7142129bbc80539b785464aa10aab8b5336aee10da425484dd07076e0993fcb9584c091ce561b3efb7b96e9c02c452d8146cfbec52a83765b1695815f82291b004f28f00b54c936f4a2034c4c861f33c2f31384ceda2c9c85709c072c8dd2ac2bd6ccbfc1bd6d09038196c2858b1d946a9aa9c7588a1642b20c865b52ab5673cf7d3b81eb22a3da7378e56327289a99a3dc301d90605708670b98702bf1c30c21cafd1cb505e46f70ab05c180789f5cc3a06b145937185c3904d88312764bc4a0e1a1f8740b4ec37f9f150fad8b0f102bc733e86cc65c35b220907785c7d530bf631c0a54028336ea30aed13273f95a01bb2e3105a97c06083d9b0c4309b8c6294764ec9184c7102494b2f50514bbfa79c72a11fd9c1e91757e630baa9f124e6aa33533930a07c4bd0c155969143c69392130909e9c859dda1102bc804816d67c268338c0d2be2f624c1e8314e057b31119a008da1bf075ae92e01ec18c7f9f0b99dcc39c9ee3b27bd10b4a987fef3ac23b7a9527607fc8e13d0b1a04f900422b6a6e1b3c44f6b7b4cbf18e18a6336e4651d34052b9eacee2f6be3cc818275137c5254c59d606e3e1c7f6f4083a922aa0bb2457d52ad7e3c120a741ede5858448bcbb70abd2539bb8767c23cca2bf20bd7af644be9476561ab048a92713ec99dc2924d1f445ae570e9d2b5bb0faae7f556842d51f47e62a23f36b043acf69403536c6528b32a83b703ea4341316a03b696c0331e8a0a7820c67b992e42390d1935b8c18722ab723b8674182a02c8119479372981c35bd83d3538e09a3e074243019217fca81256530ca7034262b55a752778242338a7c0fa5ecad8012129e13a4563861f27596257a7fba43ce460722f0d930ff90c252030198a9680bcb1632b0a244f705bc4324e2a73e1c4a61f014857975adcfa1506fb1abc76502b0799cd71348b6689c9048bc0e1511403099069aaccc19019f461ae672541a719c2da50317428000e242d17a9d313164ecdca705d6a2c808105cb10c15d49ea7e07936fbafdbc919e22993640174ebb30bcbf20a14981ec5c1cb328b14c7c93fce56b3fb343bc1cc368f3a63b16bac72e7b130facaeeb34e2d403c4434000000000000000000000000000000000000000000000000000000180ce1a28d737285556ac1395e96d8e0bfbfe65c922aeb2ce11cd9e2905d38a62e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = e0abda2b44a5e6713314a3ff62fcaf75d0542d7f5868463baf62fdc819356deec009c4fc113eacf2db89711bc9b38b30a7d368cef8fe5ff014034c277ac05d1233d0a82db47d3e55415c8b4824860092e796b280a1c805ad7b47b97c2fa35ce57d72f17f1f7cfa0d85531a342c1dee9e48307ba341f514ff8013435f62e04acc594a5ce5470b599ce20bc8ae729be759bf346a92ea55b39020bb2ebffcd2bd6c8dfa9f703416dc2dc422aab577b63cdcf44376c4f0d3257030bbc2c61cc20f0bf6ea0433f7f62afa68412790f471d03fec734332b04e49a7350323efe6634642794237578cf10b3e98efd822c6f014901ee96103f0fc508d9f04ddb14261833dc6f994e3d136a9fa9612725c9de812f9590931b67f0858594cb44628393e625d8c0d1136657743aac7a24157e6cfe0fd703cb42907ff6f6078d35048af75018810c73996c35d75900ce3b72870f58fd8d98cbd14a197c91fefda474abd857e641b8afe1904b1b6fc5c35460be2b640c71982dc7dd3543d85826349db597fe5e1523baca431b43979a24ab0478be960efea436e82a705dfb0850a41575e4e508bb8f78109e5432a255c026854d79ec85b6d0f2d4b6e8d5bb37d5f9ef73f8a2d2b50e7bd041684f6299051e68e60d11bd226401c9fb4e6c1959c108ebafeeab62f7012439aab9d4da8f0286e90b65cab2399d1f9615131cf1fba721a264db0f129c84160b8c6a416d36d3379e0bb02604d6c8a0690b32a046e53e7bbc35cc6c738c4fb021d514c8c933ce27cee04d83543ab444da4e959502d3134d811d7545ca6dcae7c606533d74bb767787a7b141252479f0c76e27d2f9c0c3b9d2bbb76ede717ddb158d7eef059502054f81f8dffa04592fb0bc64cea12b5b3fc517805d6b43cf07a36f018f714032791d933ec6e46b854b6b8535ce685ed5e58ab339d6e859e8689c75d28b3117d6f31a2c4a26571c73e49f5fa733353c5fb5ffa331f05db4dc73ffa4fc7154580722e407629c5931337e5645be9f00a180c406e486432b4ebef8f28a7626fe257519f781f206fa3d5b206a073dd8a2661f6e066c2d5a102 +expected_result = pass +expected_shared_secret = 24f2f27886dc91cd2b97ebd88151bc48d18ede15d133884cd55c65c4c1af4717 + +comment = Rho leads to non invertable matrix +private_key = 2db0097b4a8afe74111d4b78f8c9a8a6ecbdf4627c00f562b7835f78557e5c3a89cbe1b59d6c019ab574e5ba6951f926f4b274e459260755b4e536513e49607c0a63e718b247d7b5dc91abf1e09d87dabf67641dd3abc47c2a1bff35a17d0cad8a1345d08021149cc5b1c914caeb780b6b865029960ed3af31e976a35c5d2ea8194b875151d52131060c71b660016984810b6ebb31392f9b9b8335adda6199b6438eaa48b1c704c0ebdac2f903051482b3d1d4a97e73779452564b7c9bd2a081dbcc6736e89d1ac7a96518a0851995a8842608386d1eb4bbadac4e70487b05680034f21cf16100b349c356a01c22f45d6585bdaef528375c052ba029ff48156e578915d953413647b5f037ce83aba554c263a3374e885177c0be3850cfeaba9d8ad43c30235591e68a41c9ca7c49a3ec86aefb5438a48bc5d378309152ba9fcbc344a5ab654ace03b823322b3d00e817aed90bbf237e188bb4e4161c86988f9cf3665334b0d329ab34cc13faf514ec989658a33fe751866083b0fef1182413361ff40540b8365a288d04a846a83653ea7a5444e62b83e0535eb11c115c76f52147f4208522788ffd63a0121c29d036cd510169c8c95807416f65f6caad936b0b981f60673a79b378380a321500770f671939b96b701870b039cbbeeb2c279aa5051478bd7c9ae4c1183843260dd67a2201b17bf3865f1787a91c7a3748a9c1462a6632316bc16b63c0714a589c00447b43f38b10bc2d4ca1608fb92ee6d151d9bca2b4836cefcb17f9bcc83cc36ea2fa90fd015edc89c5e769c16a189a88009bf7e00350943223c52548ac8814d3acd6f790a1f102a5f87d11f85e588060655b04c09a73d50227597cc8702a120dabb5e9d5639198488921b336666324e5ca5543070d5b3fbca589fa4282c520bb03132e86f92172d906ae8631f74c46a51b675d7a0d79e551d466382f57a05eaa8aea2395f4b22ddbb3267ef440d099851a049e583382a8e26272813525e8863b4530892127b669b27517122e05a90ad40435330107e90be6cc9733012ac3715ac7994330ec99a36a24386b7dff16b468b08ae60b4b1f6b808429aea6f38875b2b5deb376880c321537939840905af7a93d982a5b701b6cd2a5dbea7393c2136fa9a0c9673175986ff071517ce0907ad7c017577063ac826af10e63d49a57b6bb2572a4ca014244e502a9217d22b1813d88c52a564866f0c906fcc21a95c5441a98f2920f06189c212a5effb02cd8440a0be12ce0bc1c8b5720f8e8952e5a823c2432dce607f9b9629fa0315720a951b87b46a028e2d5771114c2c2250c541b1955e01e1b927c89439eab75942f04b009a26a1c12616ec028429c7336173975628af8891aa37c5fc88520b5fb8fe4438bbd4b19110b9573215f27e9ba2c48931348288dd1008f400736719f058c4109c0c374bc3b1d8609f188866c608658f94205f6a478208319419d46441e0fc5cad0ac1d31cca7734b71ab968202834bfef945c2508a3aa5532ae74c962550cd05b15a0c4232246f01c06b0b1c76fe461743f359e5a97bbf5b6d7d110583e2a5b851036aa85731c2bc10502c5c760092a8202137cc656a0d36ac49c1470d854603ec357433808415b09f3018a429d11697b25cd4158c61102874ba8d552ca176d837cb5659d49704ce24823700a3558566871323046c1dbaa6aeaea44e24f4ac9adb6ba0ab30710919fe44a8f61ccc181c6317f17edc64ce5c6cbdce41755eac909c4567d14820d1ea0beffc68adfa37f1f30daa32aa1d993765f195b71298570c9150b2c5eb0687822469d339ade15b6053bb04ba4a67755c9c4a22ad88295149477e512bc45867b365d6556c608363abb53da080a01334d014caa36837fcd5bd95a6132d4abe81865ac3404ebcf57ab1e7bdcfc078ec459da67bb40cb669ed500e464b774ab1090bf4c0c09a848a2cb46ba85ffa339cfc43679f4c1768956a9359945e14836deb87d2b1ad3d6c171dc4803bc58c1488bbe8017b3028362f4b0899563475998657a279afdc57c3b9ca5d9b0b1b12b67bf2ba0b106652c344a583ca911a676ab7cabad6598244c379934a16e973a5e413c7907af84cab87d3a15845b9e18956c33c6b9836bfbfbb3c6b291cfc5a455be3b0ad17bea621a4d9ab495f4671ee78f4ac180000000000000000000000000000000000000000000000000000001b190e543fbd57aaa66ce231edf6ac4c4a85324800cd3db15568642d6bf95a545ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 6cef85fb2ea1e95d3afa336db82db61082560458a43e6f7def896b307e6e06c48922c95b6729b7e2871b75acab3241b3599aa4d15698d6c424f1a4a2daaf9b1e1072e4fe025609443271d51c7a942ab72aae3002ccf911380e2b8b6b3c758704006efc7aca771a7a2909423bca6905d1379a3ff6a7e443ae2dbe5cf544b64049e88e7ae0c47249d7ed63f4258d2d62798f2eeb320df7cc448e678b6c00f91edcda89f3a9e2c7c86950d0768fdc410731711610c4f6962a036766f75991db266e8ad32d73c0db991ec8fda771cfcd0be5cc3cb46e90157158bfb4bd1303a2e4746a095d53572d86ecd74222a85928ded30072c6fabbddc8d205320a922049818934d3e5db9189ff458f6d5acc98ef72ec28dd684bb565a54735799cadaf8528992cb5d0065968a03dfa5ca721c9a00feb2c61f32490205ffec272b99b72c22475219058b76c91340734ab7ebf62efae0dc1c9d8660250d24a94663f22442f1539b64a90543280d52ec3a2e276525f9857cc11b70af128f94401b8bdcf2beca09cd9a156748d212a02a79e281682ea01d75b28facd1b66715782267bbf965117a3ab23609f9a05fb6d3106d57be96975e05693740b28316bb1872be7d8b2a0c9b723f8ac71a4f32db0736da5d57c4a50114d1dbae4814f0bc7450c6c78465bf4cf8b2a9e0a08e7f0250b82975efd82ea6c1319ffaacbfa1c09919c15a66a80bda481ba4f36a0a7d2b02b29aa6d8b4d21b0158a7b4984934c2179626e4d329c2b39c743be34e2dfe9bfa78487940516368bc79e48aff6eb2d02783c88b9f6780b8f1661501b49d8c2f23155ef0ae6dd02f3993c969c95e19c91c1f1153c445a6431307829c8088cd4f8d0d6ea69cbc44b915634b871c0b39d64efba6298d7448d4a654e14a522909efe25072f4fc518c3e694b948fb5f16b41c7c3b91243ba092a951e1cf5fdf1f6347372f9f374225469d552cbf345419b81e27d51ea505226c8aa85c603948c0f959f5ddf9511642dc8b959eb536b11787e604040aad4bbbd1167c9070af73bbb50709072cdeef66327d67fc299c8c903753b03bc69b03fa3e5a +expected_result = pass +expected_shared_secret = e00425c727c86b827edb8052218886f737696f82b3d3d958afd73f3715b9413e + +comment = Rho leads to non invertable matrix +private_key = 64a90bf7358dd94798b5cc3a55f8696790b31943588dc892e7673b9f782b905c4a1dc44f660c475df7473cb672eb31c6a55009a768548c52b322f5afec8bceee2105cfc75170f1505f4a8cfb4b39f368c1b09b19f3c41e5bc14dc49c9abf48baad0875af35653bfca37cc01f467aa22e8976b70245b070556318388bf9cfee0b46d1fb6fc92a7df9ba07c5ac23b9e91b73857697cc4ca1a59b09b6a813e1a84570483f036014b89658c26d0458cd983514578115e00553ef0597ac89677bc68c469439be88c425242ea023bed379cdd9b9c80148784d362ab5134446f075f5c11565d37b10a5cf3d8a5cd2b530c3bc40d10375f7a149fe107dbb486a1ff53d72590d3e6abff5d450ec741d4d97218369872ae5ab98b9514ba543e2626dae4c5f09b105fb2b77e6c9c45b61a9c8c73897f3a90f1710609c78c1375159d678bd53c1efe92812bb8060091ea5381f46749fd69904dd423bc882acc6f118eeecb955ea50bdc15cf9001ee5a4a476c5abaaf57c76119906a61c5e9bbbb32c34653b29ffea16c44c14027199b0bc0f66ca2f7c88a86e607ce6ea578d11c7e38133092b591ab251f666b5af532f0d08bdfa98c6ed1805efe16bca96a3b745ca2357824531199ff28505267148d7010cf0c38de666563b41d6956470dc215b709bd4bb4008dbca80377fcd09a34b8461cdf8ca12ab63a6b20001474d287b02e093acdb7197e09205e2950144a935bdd03cccf696139b1c6217491c6c11fee948f517861d1805a8f166b0c92cb0663a77a8105076cbba932483d7265f143a5ad8260396cca5a63e79284c6426321b7359833a4f86106aa9ab846bda35414047c31462d0986ff5f04027b4426dcb34fc024dd93a9e47abce79936a6aa59052089b3bb5af13f480cd1813ef32570e3a00cb712b36c4463f5764cd935d2265a01ef745accbaa086174eab2a4a421b5fc4c9254515d3ba73124f4c155e9caa7b25e183b942b7617199745e5b9b15509c4ae370e32d07ec1dbabeecb47aac658bca87181d950e891c5eeebc7bd3b4d0c3357f67769faccbc9b1c44e651bd6f753233c12e4a8960a94479c2f250c42387c2bb90148844a47a4bab4740da5b20de8b50e18312978765a1385d853741c4bc33065b7a2d1c9926bc125e86694f2c9913bcc921a446f6f4a7d3b56dfc7152984a65088cba5fc93b8cd96166f43a47a5c126c8a8a11a90e0b38a140448e4464a61fa56157a1256540f8a3c1c3d538eead78f35e796ae60abca6bb15eec4e118005ecc631815189bcd9a69a1b9281f53a35f08e6b5095e598145e303077085725241815c41cba5b3dd55aabb86a8e8fe87cb6870a549702732c0b6440a8aba22cb93558aa8645d7515449c19fbe849e1e91aa6fb744a5119138d5684795086613c0f7a218d5369d3f7728c1f9a124f8c4f36b16db63b49a07c3f93926706863a6674632c4a90ed4857150919a5a89c7215910f71574ca27a6371b9f9165721095f425a0ad894dbb5535552675d9c93f49a574f7316107d967961ca2091b9639626ce4990e7da531fe91781c146c4851497213bf246768b65453e6566707c48381d25830bc8bb6782386e95056371d3df68573329c3e537a77fb8830456afc678d396a15a1457793c6042f33c7d69ca2a3b0a652916de6169233e7be052cc153c09c49f5b4d07c806ffcce1e8712904621caa345bef6ae3229422f526551708463693ec228a05b82ba8231c839847be5d4b9c9c19b61802f2c777ed5778822fc9d51b621222b5fc2a86094e29f782c4e7361c90d071dc0e14d0848172841c465877237938f53eb28319259e56290991b4e0404cdd426c3fcb2a1bb4935fa857fc13473b59985e9da90ea2b3ffb370cd3cc217e7bc3a4f64bed6832d53667eda80961b7bc2ccb5157e3448816251a474a80f824b957794099a74ff81ba39c264426c70e230e6b7c76b272b00598ccb4561d7075243b0351d32222f66a6f9db50a5e65026aaa2713d2549e67442bd482fa197f836166d99507541b6928b59c7d8a16cb6ba0b812690c9416154648b59b937b776d22163045bac48d698725f8b0dc1b11b2866ee9600cf6cb9cb99151678a87c3a1b08975b1a0718ddcab5aeb31a5a3815a090632b48329d106b36a671c61a2bf3b087ce5c17217f14181160000000000000000000000000000000000000000000000000000006bd8306b8c0f9de5138dbf4472607b5f8076b4e960a70119a99202c164ea82238bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 898fc0d2b7573dac9db353fd05267b4f1746996b4a4105c3a4cdd4cedf0c10014d26ee9301a38b9e4d1cd2368cbe357b3ba4c30a85cf2e96ecc046756862ef3a57d1154671bd90770be8e3d90ca391e3cf80b08bfc6ba129e4d1a74bc739cc11ddf11f79728a510c310f27525007154de9dbc7b3cf65bcc90206c2af08cacc78bb43d0884583c872543116afde34a43d2a20651bc9d5d7eeb08a2d0943e71437eacf147be648a4f39929e3c74ee5291ec8cf1327bce41d4cc3284edc113434bb259dd3a2c9d80804bdadfa266359a64eb6215cca836bf960897e796b117e70bf9881daedd2f5ab702b7536f5ea803a67aab344f209b270098c29e419b1636441eb3e9a921db1f3cb687d36e19af3f01240927ad160cd0ac0ae0efb45fd46cc8a043673b76232b2455163c5f3f6ebb43903ef7754bfe8dd58088a8baf3318efb9ed21153def55888e5335a46251bcaf282bacf138f3af7a4295d8448732c5549cc138db33037c41cabf92cec6636071fe0a62fbe269fb7b13d70004cf8c1e3b8c18a99861fef295b8776c1aa2496d2d9bea69b24d84fa6885c043240d98c90bf6203d92e78cc94047215a24d54f8361ae9aff03c70f72c25a88578d90dc7357f54ee15e54588d0630c84e1a13c4bf8492c78391970e80be6e29a4b7a9103539294685fb4df7716ca21d695873eb3661dafef54faae9049c08ccf9d3a94178f7016a5701930f8b604fc88ecd703e68688d7e83c2b5683e983ce7616f45da09312a74cfa6ac7cefa1721b877ad87c9664a556401cab3b9195e21499c6e7a41752fbcf5505d9b0d86769c49d420e646399230ba6625273ea02728c0999523170ef0d94ea29a7d03cf15cf1cb08b7b3ad6cfda0a510dca59fd445df0c706519edbd5949baedb73971a4338959d39b66a9a7c52e4d6abbf71c975ba77a28bbb8762a2823056c8113d927fba7ca31725690d78b6c88e771c6a90f66c581fa339e43ce18f92c1e011af8332fdf21f24b7320b18d6a8ac00a5f786595b002de716778f554f321291b5d175bd82ed0466b52d7bbac855725198cf9ce60739080770051de02 +expected_result = pass +expected_shared_secret = 32ca254e8c907952a1a17523d1a585613d7f40535fd5e1b0920153ec30bd77e1 + +comment = Rho leads to non invertable matrix +private_key = f05ba04ee82ac37492c48a3c0df734cd96bcab955f69675a12973952c486db7b3ac85951f0443b978aa1bc339def4203f8d226ea79b1b1e4c457a461c606556d82b60f214a49bb1448e8c83ef39766e26162bb96139c18ce77c679a176afc2a2e593046045cc4904c90615585c8a0349f066c50c9ef5e586039939ed523155174c54b74e18e8944837b4f46a83da757e935aadb6d920f7996705c6c40a17386fd955875890ea3810c02444704abc54dbc79313b572191c4f7b7473e794567c0964855686184d65b9a7e646cc9d26a559820d383c63c278bd47077664d7041ecc90f4391fe9128cd6d25346a85699a258c1ea2294b78fe1326db7caa845028fe19ac6af212706e00c360c3fa0792c612c1c4ec085d86803e895c8b28aa85b10b350038d1ee4cf1935bbcd62c4fa28272bd0bb96681aa4230e71b698425934e16213593847f83bbd445c689484697ae510e158382d6b05175025078639ebfbb8d0841e6c266c4ffc195054606f54cee5e609684079a2bc07fe616f544c68dcf22d82419b28f4c2c34271b4062de4c23cb8fcceab785ed43a48884013327a6b1580071e30456342bc7144c0be299bc108579283ba397525f1986e89c465e432b03ec3c81f6c813c83c0df455adb658254ccc973465a864b1b6ea4ad8ca551c0a909612238d0a881c2f5a90b831e765011f8e95c924c186e3c490d73770897ca1419900b5a11c1935ae4d096596c821a623a21b727bac63e346c445c8a1566c10257b2815f65c297598076e6cccd62753d053d9cea8a026ca6ebf2375e3824c4f071c4a59142c0c75dfb50e4b61f3767472bf15262bc55915bc8beca2dc858cd0d9601dc70b844768431921ae24a6fa462ac21ac4515d23c24987591d1654b0598a4b58644485136d6642541616438c341dbb97c879752f494d9749bbe47022fc64be243376041a29d26a7e875c2c0aa0cef45a3b01161fd280061e958f09755d5f06a5fc086dfa1991d7b303d7c4c0bf2b8e169bb85263a6717981b34ba3b123a6851cc42e7a00bb09088a1bd0d882024e1155f5716715b7950ab71ed582bfbb79127b4235f044fd07c2fe1a63695e7399d01a373366d8c835c2874031b3ccf980ca026d215b7805880ca50a56b75486b5370bab08fdc09ed724a7e825a3263795c92b3ea389c1e8745334c7f47ca1ca622c6b840c6de4b01656633ffa537edf68ff3f1829d4b98ee59c654ec1dd2b8112eea2700ac92b05457e3714949f4476bc7584d6702653b28931a3b660a97f0c34f2b81475a3b4b2b121e44c85eb9415a94b10c7a533c33ca3aec249b7d4a2a3bfb501005c3bb70b9cea64da54563e86077e19a2eb2f74356aba1001a72b4d98bcf850ee422816ed99d1b154ca88ab740a20471d45c8ce1af24306e2d67254ab4ad3ac54c8fa96799496900742fc6062ca2d969c14c206bc2a1d1c6aa99a75cd4f18616d138e2b28812c38f85138e2c9a21a89855934b83f45b2484da4533125218314c08ca41e21250ca270bb962ae4869cbee927509b0ab6d7238194c0ffa48a33c3187e243017e7cad326445d876aec5ea95bfcc8ab3c4428ea470e73433fc4bc982b364db680503879c24290d15450fc7bc737323ba6f295a0ccb0707054f77c32b33381daad4236351a19b30a7cd0b75cf03c142528b7724555d7403c07a7fba0a55c7122ad7037b65ba90754c2d5bb3a56b91acb5c40fc6145f5ec98f882006ca982831e99badb698317428ff758559951b09e489bf34c70b901703b3a6e2a0894fcbc2c1286ed5669c6a53b35545bbc16a572c3256c0fca995b890fcb401cac41d91455ec4b294683aae5f0843ec994fe046767a112e0f0ab6c1f9716dd68cab92b449b326d3db37548507584259a705ce68003e3ed6cc56586343f4c6b3e4b6714a0bb27365bd0c1531584811a935dbfc477663c5bd6bb53c475a985cbc84d94728c8700f429a0d67136a27593b934133245bee569f74354c7f279d9fbab2e077369c26cb661270733a857403bda5fc5bc61149ea419ba2911d4542a223361f27e5cb2e5a6383146d3f16c945ca4ba23110c773854da8c59c783f32d404d8c4b761824e8ba74dc5952cdc3526b3a62d2a37624aa5c0f6a0a9001505dcb47fbea56ca3389e07d064c033cb0ba62e3789f8e20c0000000000000000000000000000000000000000000000000000002c3a25b15556211d26eb2fcf81df5ad3ff25afe797c69b5fa55d060285c22ee8e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 0c0672109ad2986c89c1b456c35f2c7334e47f8af9f8710e70f9514ee15c0d0067970f042e2029ab269d6ef56f37d85c90b51b24e4e5fb88420c6257b3ec5efba9041bd6c435c1044c4c62f1ab4d06962b3ac45e0077bba067318fd3c7648eabb0a8a17a286e00b0d56bb056e1c5a7e475b192a01b82e647fe87f822954ebd500d1370e29d7bacfb0da4ede93a8539c508c819caca82f6ffbaedb3f512096b597401380dc0d22532c43f348389ce3ce5da6789f383c6d6057a56c8aa5ecc6cc3b1cb7b2fa1a7665911a407b2ee9f9ece9943510c0bc98f08d2294b4f49c9298a66c28593a8330019d3185331cdba4e876d49be06c0f394f613282b03b4fe4eabf2ee57e0cf6f40e31b7614302d4d06a06dfd55ee1d72e5cf1b58992b7239d6e97fb93134541f31124a7acb2e07948a8f55001c7a21899767b9cbd0ab722ffaac73459e768c7dbead24813f5beb65406a41a31faf63d58f36f119e9999612cd09d9b0c929a43d40481a08191c79fab6edfc7dba5e4e4d3c66db2a4232be62b748cddd4445fb38279a13da6e9841e27dde1ab4daafe22a5723e3c62be7bfc4bb4e5fcbc9bac9a5d1d2ba691c56fc7e52ba391c1bea5280af63623445a50c5717e5638b096c13597bcc7117a3a2113fce277047c463a31579d91ad46a0995d5e76065ec2a6ffa8783ff64f1dcc685e258ef28a0a3bd66708cf1da4b3587db7d4a8aed945b69c6dd0f49db376239188e47fad1ded3404c1539351f9407b8a7decce4f3a6c29e9499f2a50b1ba49daa4fe1ad5072af61a71744824c833b2dacf1ccd6ea4fe256f87cb9e21e89a2c55f7bca76150681f17ff1bc36dc153262d843b0fd54363ed5b7a1378e3a970d2a76244098492157fd29866717df359aa260dd5cbe4e8c2edc33adbea983bbffc522a5b0ff52be5f3670687ed69f328c3b8aefbed81938e82f7b2dcbd8acb44fa7f962a4b14f3a4b99ce26ff1aa66a81c004cdf5f75a8c7622d88473605a7ea1868b438a5cb64e8c5e63fcf8bdf659060d7e42965c41a3f506cd19bf35e2ae96439aacf076a4c3983b173e09e3b64aa37197b7d7a5 +expected_result = pass +expected_shared_secret = 74dc5b157e4e45c8a550b2eb28605412b2903b02d1bca02b8b44236815e9d5e5 + +comment = Rho leads to non invertable matrix +private_key = 476660dd0401afa8203b5c280d87a2e5744ce6d1cf1558c871429147b831149670c365c5f80c4e5c0aaf84ec9108d07e25404049ab6a19415588b44eae659e9eb366cdc5c5e9ca96e9b99014c74514801868f951d841acac4210a3984b25f0717a774aa71753cfb3c9bb85c5b9eccc67a48f271157739cba3fc49c5b262388b2176bf3789b8303eed08b03034cd2f24ba06923bc1644ecf576a1d77283c359edf53f213662dcd6410044af7dfb3ae0a3aeef96857a169fb9a9a586db5094b3773750c0c739a73b0463e9283d219a2b277ac4e76ccb4e785b0d6c9d19025a678c927e041d892b0403254e2bf24345851ae0c759e7f159848b9ad1fb60169ba940b000c42c11f6aaa6fd731e29401d3101ce48c47c6bda5dc818b5268ac7ff0c6a36cb5410927ff8290a363524a55bc8a4208d79e732a53bbf2177c6ea407c313c8d1bd35c489ac161e77d0e54cb767407167c06deb313c3b17f14c3009c308133059eb6663f45d4781e259e9f2a7586c5bc28c2526ee90b845533e18304c5a3801fb9bcfd1c0b03260486d505d5c1afeca04ad984813baa9b636695865b3279617d194296514c9c4a4189c9a645e66b0b798babde151949e8831570490bb227bc01c2f7880d1cd44640a53b1d618fbe19499b25b6c1aaa8016caaa893a87ce65502c8bf4fa4015e74184526562bbb1ecfba8eea78098c629f29c4097a8bc9c6d178e54a3f676a6e40150c865c114d133589c23f6263cc8caa936e03231921cf8fecb748c6baf32c639330b52e9acba2d3907c7b3b03b85fa063ce9669cb2d64c9d70488dc0b252727cb520c30395a67e3aca14d3c8f03c19114e756b2c1c2503b7698c40ce5b84907414658819968f6af91d98ea5a08869d68c86e293b645b11c83461f625b8f0867ed02a1570bac00a8286c3aa9d7f1bead11a763bba0488c428aac1875d265b9b30b1220b4f3cc4830730085ab6125b21586bab169d59847a7023b3bbe164c6ab8746af53a5d5713a5a4969ecf08402095a4b4800be70240262b18e843022d538c3cfc5ef462c8ba3a287be8be6263a832d1a5c808cf5c148030717ac9d391f32c6e518a50e0fc5376e5109c0c6652384acddc3e10e230665930cb416d7daa5d4222a59941ce9ef87e325760f9b31eaec17c9cd984e6e98f237b47e6776f3a65baa645139ffb0b233a1c4ad0296aa46bb470332d429490552a1f68a6a769aa37d5a35ec65a6b9341a746b55694b1774279ae6b6edd0b690b041c27b1c36157a871ac5e1b44ceb08050e8f96089f481d3670c61d7901cb03ab0795e00db6f2260868249789aa69503c464cb1541d5a1b43cf8bea2a7c699984c7586317ce7064945cc9f41108d35055a687be910bd9c771b9cfc6a359b9211cc5557f2192267142be32cf37a784e855783cc092297c401b66f48d5bdf6b7c84309b62622312d819a6496a3a4f7b5fe8b914ee24256d7be258967197419084bab578826419a7351f327006726d4686226ebb1d74b151651977dea83a9e07f2dd18e88440f4baa6cbe9289b0f728755564f3914b4a4b24ae06305299b6d8e859620628f3436982949aef359f9597c6ea863964d865aaa6783a07c63374ba8bbcbecb9976f190baabc4ca14cb4b02e5ce1ad784c455b43916684cd7b35042c5c3eb026dd08dfff9a7a8fc9a2bac9d65b7aa0589c7fe036b7d8364fe898e76b798155b1690b21c0f5c0ddb83647ff28387b2c926670d49205625fb45a2177f438b5bcc2abac63b7d8992694b6b6417786ae5c8248fd993833b75d3353c92728612f02578472f5a373e1d797be7a8221efc9b89b12f5db18595ac7e86dc49dbdac352c388152a7272f486f8e88a47070485f5026766586eb0007ae84367ea17bdc868152c5ca9149b49fc14e60100aed892578b834e4a4346936caec5adb39b475e68566f7961a82ba99a591f5a0113a73b03456a050f24ccaf2b835981243cd61cf93318bd09277f4215d2c27c7108ce8a8882f28038799456371cce59db341d321ea57594f76376a20b02dd2334b7e479abf1b10560c6afc819e665b9dd538c0fe1cdcf238566bbc6628326e6d40f0bf92fbba52e07079dab4b9c9d90720f50982469bdae9414cf11506d5a125ccb3a508a127f1c31b771232d67a53a9928eeb3c872208ad067000000000000000000000000000000000000000000000000000000bc89dc30e4435f6aeb9abd781e97dcd8c328325b62a7439b1e2d94296be34d1cc975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = fa64929b4a342999d14ee51ee3cd19d7a4bae89a5cb819fefaffa1063735fd08a371062152b2ebdea921ef7dfe98d92df7be6c7f3e2a997f097e020334d87fb898a99d442c7ed49bdcb82601612b2a160270ce1e78c045754661d9122ddccc7042d19d305021c2adf7c3eeb217c59e3373c4f72f21595f419b1fd993ed9336e577c6823e1d708e2afb5a779c7b3b036b514f3d4ed953022d6e5f1925fdb0024c519f333e60587fce463d21fa6ba972d8ea7d3334db09da0ca2207daaa6634074566f0ba0ce7c7453a86b8001e5b1205677759c0b90594e6e6a0c5852bd9a79053f84527eef9c6fef0367270351b9f8ccfcf10abfe4f08c566a452259cb6acde14d452ef31fad7ff4a4bf7391641fbbfaffa14f9cc0fa6905f0bf0948c69a0e224ad59f8b22d767ef96b73569817435a9129ec6288b3149a45a012c6501d86f8023c8d37cea7026643b61cb2badc74962727cd1164fd5c686af863f3a6e8ad998f4f0314b9438e6df155873cf10f0ddd06aa7992d36d2fbe81b44925a6af66fa773bdbc07cf557b0aa3763261bb19a3559d78e17010edd3e6b0f85e0422f6d75611a46baced3572f0748122528e98934c236d3d41551d23b8dd85a30550e63ff6c82a925c471af1a392b0371890e54f221816846fafe82eadd2ac54de28ac60803955a8ae74f9300faf17376f4ca763b006c35bf4117b60787aff77604cca7c881bd6159b74b1d2c129d5cc6f6e5e6e1f0ea1e2aede05cd4c0bf233b8090287f824164060de841b8801ca977a13c89802e1403224110b651283484974b9d16e9b522e0826d6a07a386791080e67deb1d3f067a33d9a62a35c7c4830ba62733c1c715b03436c9292f40189cbf7d84bb7d7eb6f89fbc17a361297c99fa5e9bc850b7b9c29ea587312083a4646ff7c384fc7f83a7e72841019ede902900c791446827498655611e15eadd9d7260733bb6026b1eea93f66574863c724fdf226bab44b59dc9b5a3791877185c58ead5cd0641c663440124d9ecff5bccfa3bb2c751db7fafa3d71b66d3474acd5d58d63dc49aee2f1bd4a5477704ba8dff36af33d4a8d +expected_result = pass +expected_shared_secret = 6a1ff0115043b87ddf83c59124f7a212cd9951a79764f186d113bbcd1d76cefc + +comment = Rho leads to non invertable matrix +private_key = 256aa419a0a0599376df15844bd3a95853520fca2d9b342b55705c896845b0a8a8b35356cad9740f34ab358a3da5b9596de40aec0190676cb1071974c3e516e4da5249da1fb7c1b434d997341751bcbc3951d6265051b0935765ac1a9ae878618ba74f7bb88527c1a433b25eb2f635f4600904814d4118c2137ac368d2abb13b5accdca1ff6b5d8af9a03e3b84ebfa6cab2b0ab1d727fee1954dc818299b9ef1b76bb71570eb6cac914abd084168a88129e163ca69706b167cc1f3b5c72546cb0075a230e42cdcb27ad4a2554c43b66f4ccc55ec7683688e3689282924caebd9890459323563a05888b48569bbffa223efea27c86aaf27263251a9b3b7e00cfc0b1d05d448e291731bd81fd8d2b474d4c325a7a55e7965e514abeb5c9823e53dd55031298978972c4a6f8a4894d19848b39b08a02f89159944fa1982a37ce3c41946f5b907829b3db320a22921a582a94163b3e66b462e628228d82a9e167368358eb4642afe14a6c5870ed36c36b7ea7fc624698cf4c84e725b58841a40d581bb8601273756aae8cd6aab475df08a740a725e37cef92751c515715480cf1a3a52a7173754710b2b990d618b8eb2f532e7d37709ecaca551bd6b556afa1545ac685dd4003e16b016811138f4e280f76303defa440d395559a13ab68b1b6d26c75ee4865238192c24ab52a1c15f2a538a240f9b75cc6dc45b10272ce8048584085f4da6c1e182167eb9c419a1a0891a809f3b0ac8247dbda3b4503248ed4535b77bc7abb44706e12b0493962b302b48023932f18c918451528a81a1c0cf6f5731b8c0680ed257432a4c319007be80a2087c64a3821a8ae08e9012be3d1cb62d229130e41e6d452493035dd5a49b91781f47db395e5bc663603af7accbdaba6473f56c07a763bf9730d18cce1da3968ad114cb831d083a5cf921897325877adb656a483cdb601f2d3ac36a49b3e591379a22063403c97f82aa50c761ed1a289fda7a3d4c2ac67b1ae5b73e5a2bcfc220ced032be54313bd2c15f685c5218113fb822aaf2126cae6904dbc16864223f8ec630debb1ec282ae2eab41941a891473898bb7254e662ff1cac748b233db944e3346a24fb5b7d4a242831cb3b6e543ce7301f1f74a78479999424952c79598db9e6f4c3598184d3e2925ea6aa57654a4b8306d6522b0e8515526a5caafe9aee40303e49b1225613ae6f8335d744f088c9aa514a1a52151ffcaa6602605090ba8514968c2402e43c7ab0c97bf696025c594284dc813dc604e4ddc19b7365f0d2a1b72c675873c9830122838abaff0133cac656b1555080769344bf5bacb12433459110c8ab6de24c47a70203b90c1699331b95094ff8a975b735c4e407fb4e4334ca144d7428887dc497d7192fcd6c6a3f9b8a365862318525e0a45ede5a711292767c4b6e945b4bd0cd0621c8ad5e2029f4886ca75bb98574d8a529380f75ebd9abb99d6c96ea329e58cbfc4b600d010bd5693265368a1cd8824b18b8a726ca92774639d01a9af2b43d0c606f746ada9e156bef761a2ca8e38b855b4f03566ca8546315b4b3a3c6ecb4765e7b7b262279f8b79d83127fc04aea85595e5f98b2b228fe26a1813f59cd9875b19126dadb6564af57c2a2594be2b01163a2c48392e3b41b626b0ad5b7203319094722a7e1c08595fa3709df919eef59937a8034c3b724e6973f28063a17109af86192e9585b7149ab4d36a44652295c15c1b60c11999a29a67bc1aaaa74cf14554db740a63c33a5a62869a84478606b169ad1ad2362b81105e736ea4b4ac39a092d7a0c3c6f35e7340b2d190af20a88395d751a0841ed4284432c897a6d11a7a493dfb6bb95f179d2e07b9e4fa945503be1129649a4249cff3caef0a825c06760ab907a02c10c8c43b14256ab1aa45849551f3a72249052452e8a550a9cbc4969ec8141850f64fa032a6255649888b52883116b0317b9be8765b7a30f8245c67543ccb1c8db811a730d063b3223a2bf4304ea1472216a561d5c44adbbb64d25867758340c09bf1d1396f47c9a6272ca660bdae8a667e06986cb73d2d429863c92799910c7c29cb4b0464e004a89d90641e085fd8b215e981454d46b8546a5244d4c6ec18c83715409dda64252b205c5461b0693ffdc6a5ac9b9e3db25ad322b66dbccb5288b519363f69820000000000000000000000000000000000000000000000000000009601fff1954dfe57d0b0421f6849dafb2b8496a92340bdf1931f093ef0ace541d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 406c170b05e8cfc0af69e4d84389b3e768edb4532f12da65590e9a9f45629100860f8fbf1545e4d85245e06074ca12414ce74c2571c2ec1d3aa12b2454ca6849ca75b1720afc50e90a9e17f9f9e09c17bfae84766978715c1955b5ee0a5117be7ab2c8a058490ff14f6b13f79737972e920b223e124432967dfeb849b2264e76136b02a7d3b82191d5c3758eb0792a21411a80c9480d77734617e59035fbd883707a5902718fcd4db226ea67ea4d200d105085019bff60249488aade301b92776b00bade4f17a81d3b17bd7431c73a27d24fcef7db267fd2dcbe67958e27b98ed4d326d0a04db1482194bb38f1f0603b68b16da739b25fdb30070ca0886b895e51184a24387b93041e336177e5a2a74097aa903aa1dabc2160a18b3b340283535999f7ab949a8a291cc9627eb537be4c513b5b38ac6199bbd60f3e22b900b8dcd3cbcd5af958d1bd4f8a177bcd790e02e5d5d0bfe5d2a85108c1358ec8fbdea5483fc6cd911b788d78ce045143ac29ce9a99b21d314f7e4ebce120afe64b6676c5c5000dd6c23e141bd615d69906bac419f748d28aaff60b3798c57e7c5831e075e91d6eb328e15c62e26bdf32199dd6f9860900ea051b92991b6e7f187dfae51ec7bdd3d486d0c8fb42bae7cc01225c481937325dc4a2db8ba11911529dd0af0e2af7b3f2a02ce00c6e26392e63e1f79666755039434eea8049a9d5328213d8d1b535fdb8dd332766f8f43719533e4c6f5ef514ef454c11d076e534586681d4a2ebb627bbd911aaa540f52f53fcd8e6442c137dfc8c26e5625817fbf0e43ca2fdf726ba61b2673815188665f3a58024baec2aff32214c0173226ac041842dc35bfeeb34517c260b259ed9184452791e62d7ea865f5e397f0b2de05b51ff0b6fe6db93ebd78cd75a38e1dd8d2c645f9278a377d343e70d7708c0c95341e15c80f54fd97558cc5d339a20a807b644ad9defe60a6cdb71fb82397e714cf37034295c024a25608ba503560b4f131cf2fb2eb0eb8b146b344f04ee8c35a71c6f98d1d07c15bb63b26ef26f5c9879222b82a65f4de1ab6ed9381ca701ebf890adc728 +expected_result = pass +expected_shared_secret = cc9b647a2d22aca68714069abf5a0fc381d407bab547b634fc5e0f904045ac41 + +comment = Rho leads to non invertable matrix +private_key = 2bca01078898594b8eae01aabadb52a8812e73d00cc5f4a63c8298a049b146d4257d01c2609b673c256342b21e3dc75644880989415099e10d00754bc9a68371f30d0b5c07ee46259df9a4942c0483705f8468591ca1c6f6d8b83c49be1ce859b2c16ec5dcbdf74895ba7c6b2613709522605a439ba87aae32262695a48f48b43bb5db3fdc259bf5755114d04802734013042ccb8502e4f36aa832164f612ef7886a4fa4a271b114e17b700711b385b7c2abab0d5535128e0c4db8d934e3126e7b35c8b253204df1ca27a5ba991a5d8eb30c09b17a54d672a1e266f6b3460b015fa00aca92162b85f8cf7972a7f6b1a5950280f920903c1c86a97428e3d5b5b2974fa0d22c730308aea2439043646b44ac771c3818bc5537e304de3143d7554b0e464b21ba5cef60023ab18e58442fba49a0c013a5c3a067feb8111f835a28fb3d99384a72f538dcab39eafa67fde22352c542678b3191c53103f399bb0348379c5d3f814405639a8da76b165c39c0784a61ebb997048222b8856ab6a0c71b94c6911475e9426f97b045871571c87ea549707adc2e23a09bb676bed71caf2ce511510b3a10197878fa0c7960a233536e3f724098349a8649bceb09afb8c2bf6ed34633ea6d2451161b76adcdf14a479845c1639336cab5fbb5cf2db5a94e7a7a0034b7325601610386e3078e26129eddac40e9087140d29b7e10c0d3b0322507c07a753d8511af66e43aa1c82ae152351f35061ec76a8c5701870639d138182740cbb17150495ba6984180bfa113175747d9d897479c50ce3328a5355a98136de4e61ea55a144107a397cc798ee99fcbb31fdc222e60bc05616c5009d3cef1f89e8f32a78b22c7412633c4aa309a70492e97c1d8642f01185d15400a4778854abba1f703c2fcd0c7cd5b5326fa9775f39ba62c171525171fb084b6d73d9603c26802cfda46cba85a4bfc7503e06562cc48aedd0b5f2880820209cab73b8194c4106cac8e93c845f9b698aa8351722bb46fa205c4509f726c19b01c49269268a6dc25fe9a59ce21cd5c0caa5be2c76098b5b0a5ac2b185a32f18be4d1a77f067879f7495333aa1db44f5dd58c8cd7bb42d9521eebcf75e18ebfc69d42f0af5a0a0f1593ba58022245e03903e15034ba17a3468bfafc8e392b684ff0009cf3c385674117cc5844492839b7410b09a9659477fec8263d485e6dea01c2f93a68d08543896815661b216564da04750cb7b86cf540e18a08cd28310db755f81395709b3de9f6044ba009a8550f4a2792c2426b2f0836dc8b42128507f7d102fee97325c4105a2c4413a1417b40510011c8c60979226551dde63ff2d263b79455ea61c708827f33da78d99054d02581c42c4dbfc56cea7723718433865530163c30f6c4a31f7ab88356507063319dba3c10c62bfec7966ba65f71e8991d9b3ef0d705a3762a5bda7c1829baf8d947a360b3e902696a6a8adac80bc025957a639f102a31352aba5f560d2dd45512051fb7d7ce62094c86193b39131c9c7b949de5507ef96036063d77b7cc18e5971273a403f11c6c52534fc31c08aa1b9fe29a58db93d9550740568c3cac7371287d41c8bd51d51258f9316d733c39b27f5f68805d9b0df3d771a7639cb180057e082e17c72c7a575f3f46890793a10ebc2dbe608cb1464b46777aba8321c21b338b4a1fc8865dd577195b3457d436ac0f7ac0444950bc014e9c4ca4b8a5c55ba8599d60c765d19395818e48419cf7d41b048b15f6334dc7250244e705a6e19db5cb160ad9b5d2410db13aaa019988dd62759aab30c6c2c07d185b36e364ec6c2b06735d1d56753b692009721c728cb56115102f177f0b35a2920c1c67464e364a05f2447516f40980c464b206861dcc54a6e6cecf826e3677be04f8387c42cbf4d9ca50ea7fa826452e3c6d93f103e969cbcd60bc1f0a41b67541f75c1c605250491a16c100af86ba7ec503ad278558e61acce955532724a1abf78f38caa10f612e287876a988a35afc217e78a8721a3c4fd78216f48d1a5892b7090b01eca133d861058094d427ba784b30de1361c34a2544162aceab33d788b5a4070bcc3959d5d537e76cccf71432038305c359902889384a842db3a410522232690c2a3cd33bcdc58cc7b347d32b9498a689c5b47d91901a04032a885adc659c000000000000000000000000000000000000000000000000000000843d4912046ceef3650e2f3d5489d0aefe6eb282713e170fabab220d07f44103a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = d2ef2a34e53cb055a34453d5c3f42bcb3d3bfc7a57f62fa8fa4e0129545cabae97ca076213b9bd2af36837a2746a6607c9b5d3b7c2daa929b8e05069206eb0f326b10663d0c3ab4a83549c1e7ba0b816c78fc79845349a78f4a4ec206a7c00589f8a255ef05cf29285a9543d98dfec3eb348fc0811461e840b2802e7563c70ec128d0a30cbedc1d6882fefee3178ce816387f2989aeef6ef8fe779319c758b8e4740639df4f5fcf76dbf7d1fc9aa84712b59c05e8146b580ff5b28594b509abb31256d964eeb701282d3127b2ead3c9dd6db5791f3d3a919c06d764286987c646195d327a769e14430ef98ae3edfa2b177ce6b70a93f61f180f4ebd0a0c3bd0124c4bcff7d5d606e49cdb3ce1eb86a66f0d110c0f1f77d3b525ea3357c4d3daabe91fe76216a01eb2aa367f036c5337f2cb1ef6c902618dad672465a7095f9b2c3ebcff81820976d901e2800deef15dc9c61fe13916f5a54c9119860864be1baf35bd04bad899fc0617057ccc38b1a2e8eb8149fd50994418632a415f7fdb7f5014a591fe1f21925a27d01f1a45198cefaa30225cf105331cb8cf0102c9ff877b8cc4a74ec30514c6346e6ac514304a3f533f0604ea47e5353562193616624d593377cb445e13286b5ded2f2c786bdc2a1b66a1e02fbe16567aa83ce0e7d4c498074901cfc2eb4bf8e474b0dacc25d747cf99ad7b460af3762127638dcd1d51fe503ecae2c20c9265b16ba51ad1e8f953aad0a14f5b7dad9e9aef7e223467510deb83af133089e33fd225cf36d1a7a6ea930f61c06e7f6bb971dcd01bc8641d8a4204884204923c207e923df92a4027a42f4fe5ce6f6c619739b3ea085d1440098e7e989131de4ce60565f118f7ac588ed94e4821c3d2108f3ae07eb733e4d38a64a5b1e11a39c33d4988836c350288454408a62ddf81bd8f18a6a86378b4a6186e4d0a9dccd4dab530c6c8b66a838090e11a23367c52670e92b465306f4fdaa9111523f4bfd3aa0e776db962f9319b7ef19a67cca46d7ecf70acc01034613da030e087d3074d8a4b5dd44263ba320a7e2d444d8dba7420622e4fd607b41feca +expected_result = pass +expected_shared_secret = bc96e9498787ebb9ed9d598b415fd8d1d58156c25f615c6417e213f5a363f250 + +comment = Rho leads to non invertable matrix +private_key = 5e26b7850013f01c602f7c46920760ae15bea4b99a815252ae285dc4009530fa45b8a9518e7b6466ebb8bc624efaaa49a2e99930c760cfe3c7fa4368bdc157ded5ca95652a35200490b60f83eb01cf5158d44869cc50b34cc5514ba1189cc75800d19a1dac261f02905c548d91d283e9b2b47948afc9e0230ffab66276317fcb5f30947186219add4a43132590ecfc94b534432047c446823ddbf9caeb57b277ec090c64766c54836bc58bc8497673cbb8cc1637722978c98c9e9c4b0d332498541c86c9161d5b608cf83b25e3604a13f2071cf73ae94b465bf71589307c010ca5def4b5574327e22722f32a73853cab34a2b36711136b6cb4f69390d5759d33a5629b772b3ef73a382357d4d46f3db5aa29708ac6760d33352466164f4a2291bfa04d51866bfec806c268148de4b909403aa94962c2210f992ba4e68b95f8694b08aa0e3bea88158a44d70b55e6175c32893d1ff72714e3460b863f1b9a2afd50b991a540c1a94047c030b58a11b38b80f5596d21c6911c379f63b46c2d705219277bc5139c45165ac54c28d5ba9fc736ca7966aa842317c1c944ef86800743b53c87433b9c1c426a33983b15b9a1242c17947c0358b8f40fb1609f8c764618834f709b9bfb812207d456ae239fcb8a5107a375fba0669dd8254bbaa9221594e8469912f99da8ca1dbfe337d9e26343b17176128dc70954af1745dd200f9e72b2441557619233e1442147d7710530bb4d51a4baf7a3f1672af0641c3b1b67719929a0b82e34b96254e50d97d125b76815d2bb28e088c5e5b31f162467e284aa8f13b165bb66ad19ce3e6877a477219af8121d3501a89bb1b8daaf4856088f2826947c55887339aafc829a4866e34706bae16df2a6c13aeaa4a3b252b226ccb02919a7cb3229943105506c93c97027642531689236842d2cf059415a87698c02162c37848043df81a2810b75e302772d2a7d073409a7a14e9ce59063367e34f4a78f9a8b9b404a7b6a6eecf110da12b469045dcda4625f5961ce6c52a7853540cc9d5721271ce3cf1b90b1d550107231ad3518243eb96410e5513d4c0362a84b38136aed33c38aa6a772543541825edfe0c47f6012bdb0a55bf780831a2283b628d205722b0932c6eb1243a07c7c051ebec77d2d486e9328849b0c77380c2a2084ab2c665fbee545815149d08863c0e2176836ceafbaa2ed93a163b2a1b53a40e481aaf4f8c3f1b2ad72f9494d8318f354af5819bf35f92efdc2b34831641672af71178d69629a84a6975df3aa9aa86bea805c5a885078cb81f444371df2a630372b14cb29faf62c523972d054047d9b97e40a6b6e852d5349066a1abc737967d3f296803262b0690322eca4afb7544a3321e53b614f66460b54c71e1baf2fdb981ba89b22786e8ce86285e4a6db0b85ba7681e290b41be59075f6cfcf61548ac9c29939882770501d0006e716067083c78a2c5a84db252601bd9a84917f985fbae38b0db9a5441064d62b69d350cd51ccb5876a5650c23bb40919ed058a940acba157118977928e30a2c07194ea6bca28aa5f71199823642e0ff83c41d6970c54ae098b44ff4397272a9290f1cb65a33a4fabad54f62cb43c9c221bb421a82f5ba832a7a00d803a64a00c10fcd159b797a161484c12ea3165608b37398bd83971229aa84be377e412c3ed45042ba49610044b815266b2b9852d8c79b0eaa52b1470a0280cfb00469df52bc8f234572c7f7f59a1cd92a45988cf91ecadb0e32960dac239ab1247113c7ad7385d666d4141c2a6587ee3570be2158a990c538501458b9264ac53398cb946c54b80d8380bdeb343dd2ba21a3c299503548fd3105f4c45785a6c52060363e1509b3832981ca38b120dd8b58fbf19a455a70ac6c1c97f51ae5ebb7c2dca9036805be089636a4267e34128cc28c5a882c9c05649a83c2efac3674ec97da204c64145b1cb1b4a5373a752358aadd15368294ceec4cf9722c0e4d66fd1a97060e696bc210d62335cd5366aadda3c1d5a7f57126fab8aa07ec2b316a45ecf90c001a90074578aa84b73a45c232cf1cc6b518a73430b3cb431c8d7c878920597398eadd4037e9ba13b40c1fdb26c35a4037c75a2d392470fa72eefa6c902ea03dc8a2366f73348b292ec65849c2178464011a8d7ba70013e4e802c64580000000000000000000000000000000000000000000000000000008ae00d55874d67e3cff69dda8a85f57c8740272a897d41c2350f6ca688424d7353f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 4a033a7cb40ad97a70223b8d6aa583f86f75ae5cb87500dc91b62a6f4b007069378c432446d9a1e00c9120667fa09f0202b040b16d1e9b033e2d0c92ae29c3e1324b207ff8a6aa3505c4ae20a5e1e75bd1ee71644bc7d4ede075faf41b1aa38b590991c014ce6d009a6270e9ffa50aedf535f83b17c041aa2c418024eadfcade2e0cd4471de72aba7faec8bb3dc277af6601223c3f505c52546538bd7dd3ee6e1ca6b05e92f4eab2162e0ec5237594869d214642dc7f8ce3acb9e00e4ecc9e7a238de6696dfd75a68bb80c5e1348788971093bf74bcaecf8db9d1e680879c0584cba6003198376245dee9772e939337d952ed8ae4cfafbd50dfd578fbdfd910c5e11b0a8e101454d401229709be9ca60bed47c3cd03dc0c0c35c54ef909626483db5e6e67a5a103fd7f6e2e37f59aaedb0975a9423bb3abc5524967fc55da4fa99167e5c870d05bb3c7d41957a1a8b8d3a440cc211f0bc3019184a572c3cec78b4485466b8f35bd7cc44b4280020ad17d5109819ceb393268c7fa2e70433393d2ececab723b3939d8842789bb47bee43ced41769ac6277e457d1d1c4dd455ff4c83f5f30bebe8925b085c5d4c595177192026f4345ee93a4c40586ff622166f7aa4367704f8fe67fd262cc38ff2ed12f94a5ce6291e9e93c7627c6b3d278212d66202a4347f90ff2ab880985af794b6b556d978d50c61782e0199a8aed609679546de271e8d6d5bc6e9492388860c8275de306981cb1b80936637a4d17cf10876c856dfd5c492201d1037b14edfde1c352837de64c9bec5626ff3b0665d1cec2d9c2e315442ec39d9948838a9ce641b998e7ddd498dcc06f591b272811698c664b909b4d3fb449bfa0e3b54a3ee044d33a0ced7ae9043a8c5b4378ff06da475a6b51d379e6edf689acb808e06df3f7236830e161f2342c748ed06f00e5f147b0bdd8349e330d4f5f6a9fe320ec8a3fa31d120f391343ae27981fb75177cbddb4b775b9a3e26c0b59bac8cec7756c6b7d0081307270060984c989cc9496314e7249a165cb86cb5fdd773fe3574333b851caf1e7a1505e8f357dbfda4f753a1ae4 +expected_result = pass +expected_shared_secret = 1bcc6224357590bc6f231ff2b85b0eaec225a0d51a02afb497d6af1f0ad31693 + +comment = Rho leads to non invertable matrix +private_key = 8ca008eacb7a33b54ca796b5a0642c46e86b3e1324a9740e89d619259a29141ca64e7a06a7bc5e609047461c825bc55475cc983eea8882ccc07825258fa8c581bb2df3616d5d7505543017afd693a8ec808942318bdacc6b5b8b6a859bdc41697816c633575fd3201a301398b128597ea731a8fbb4e57898c5a18fd59ca657c0a68ed7184c58a5f420b88c0c514482ccde3a93f0c93781f14154fccacc50853a15b249088658198faf7470d778b4a8d1ad3b69c3bda9448335ca6cd207f8f6a3d0b762521686855a76d639401b076620cb1e90438ff056c857291367ca5e36d581d9fab56dc3a875813ff348c17ea77e1422b8adfbb9722bbaa9fc140b950db8a040cc9c2469746b00c72330949db387593d494ff1a964e944af6df216bf07aa30d1c87383949b7537ad6b37c0c93bd24a7c2244b3e360057ff03083cac909f54decdc5a729a8743017c55c803f90934bfd1bbc2f18a35310b5343c456b5590fa270367429f590908dd9bdf422758c480e89018e86c39493f2991c17756da60587d05d7b11b5a5f34b2e649d1b18b5ea25692c362f6e369535f943314bcb555895254b47c470ba79031f0c4139f0689ac37670fd497dc01609dd94c6a8d85aa102c92e9a020e9b96f696bfba677a02483be923a2ceec6a75b01d49ecc09b2ccc5573cc7cc2747be9864015b972987e024a5b0aaac78b1119b7ac08b33a2e006227f6036957fa4a03c4a995444215985a7c6147175132f2e6927b85568ed151b0f516b9672cb2a84860b86d02ac0858586456c82ca3068cc8d1a6d15c6142c94a89097dd3d5bff4d616adf02bcf6153de17a22b32880c2827cfea9fb1fc690cf441b7ec9375c6c249f57896c00d7f419265c87e9a99b3148b51fc9c3b9cf85d884376a61674fd89a2aac37119041dde630a873a5fe6075b59bb00dc667d8862539e89944c5a58c4983bac248b3bd19c9690872ff62170aa198f27a2a950a80ea232bb39c47180701a6362d6ea3a96e284f56c25f29566b2816a40096a65c97ecbda3a96224d5145c1d1b3001a26b484a584c5251dbe8695ea64154a5223ef0257600bbb767a033b3a6b70940b52f0739f96064b24b323ac83b698cd6f562493530b4de15c26e3902e1a4fc1b455bbf52c3ef16c07ea8917e94a07f64f1269a17b8c24e79714c4ec2613a928af8788f2889a6d3a1c39103f9da045e0b28c55fcb805d8c48cd6a47952b2df350e1904a334889e90dc79df9b55052a5926d5987fa6bbc4f8156d93ba7c3895d9a655a7e86f2318bde401604c28cc394a70ad466794cc69280695c40abc38436083c59d1ec3997ab6658f123e209b9d2c1a272855395cea6556f8bb44e8a4244917683598d5f2bd21230f4af0b5f8825a0f4b2ffcba0834311681eb9116d110d4c92670a2c444dcb599860fc7f38354eb22ebb5b1d55c02691410f76b41003c293cb436f5e71b2b2bbb104ab04983c167a57655cb64c5861c9b599d259bc406f18a8ffa61e4d9587b8ac009472fe32669f8b99ca1cc5e62a12d0902af096b9ac07145a98b5b7354070281c6b9c53105685690a2291f48c8b3065af6b98b79f1bdef6856b6e9c6df7464c18b3351441e5d3b2e1a487a1c9296a603852f05b490ac4ccd941dd046733508306201abee272dd90239d5f922d2c631009c75e674ba8c2399f0f9268db9a07e1024c744491db86936913ac02733e332226402760b87a0b6117e174c5c6eb640dea607b072c9b150107be5ca37e6bf642a5be4b663c059c8394c33f20c02e498aacb15aea3c16968dc0a8fca9dd2653bc49cbe3c376184387b3d966457a4ae9006357f0c3a23e2b200d6ad377452e37b0480ac6d9a7544cf359a6ca14deca422c4835551c2937500a2144ca7df247f0e0a17ade760784cc26f51c32e144bdbd135924b851104b74aea40aa0266bec063d759b5a2775fa6309c00a3914930526496bda04cc3424c983aa2aa0f0070b0f3625c512a43b3567f642343e0246d262bda42b0dac7bd9e540a776365f4877304f49775283b9ca691a5f8c0b8807299c52e1e149c286309ab568110b64442a553e3ea6b277b02b609bd425a58f3389b941573c681140b7499943733da3c981c75069a3aad306183c421c28a720d5a32b7cafa8a9ae7aac936484b56bdaf321b76a300000000000000000000000000000000000000000000000000000040e08d01264bc6a83714b1dd57299b3b505368d6fb3b80c967783b26f149fcc2e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = a2661ddfb82bee75831653b3783c20d7d2b2dcd1c37b471495c77c6388b29e53357098350d840ebb50b8233e185f540fe4cd9360974949abda32aed4cff401b08d513f3b928106e408561a359750cec108b52875db7f3efb88e0d13cdac15c9ca60294163ec46d82fdd89f650d30ff354d12d1bc7024b131d9e6f13092cec164742c4267eed81949b949d6ab04ce59f0d1938cbd97fe833f4db0ff429de47e161129bd0217907d9ca59066495b8980228ee129ed40cacc2573e322425ed11cd02e50f48b5208ad3dc1bbc43334806c270352a067022739043b9b11f3bd23687146b70ffcc7aa523065abd605509cf867195270ca355f9eff4b4bad0814cbb55b0e7b2a927a57b1711d621409ad8bc850d3b0b4627e38baf0a671b4350a6b697eb297bf523bed95f32a1e1bfd1db8dced27c6af290c7f7d648ad81f07d1a3ffa4acd8d08af8c494172f6b52d028b836e72dd3b9aee7f319c62cae8729ecc69f8fa5b4de68bc4452da20c442c0f09bb0e620f22cf71cb6f629d83dfc85ac6916acf62a2b96c11e2954791e953b31c992d12e838ff2adfc395b84f1e3482ddeef96b1ed04225be90abef29382da3a7cbf8610b09114788cf333daac7434808de454773689676772f5683e076145f50169fc8b63fac55d0ca26b5b54238ff349f2cb28f116ba83db2ba1c3d251ce68669ea1a5a0fa946e345c7fdb656e5472803804323107ec108aedb4ab585a5a3dbc3cda6262bb690b21e3f84bcf1af0a188194dae41508c2a9c721a4ee1f8f59d1c24f88e8f5c287bb5f774ed863f6caf612fb100523671c4ae9e12c7118969dcc5244a1fc5f5cb3edc76457b3d1c4383437e2fa4f70516852fece588d008d5a8747bba217fd19c6dc4cb417e6cf793e8c318689c4e1c7627762b0fd5103613dca5ce18bcf4767fe3e73f8dd9342049b33827f2270eac3cb423001a4f1be6deee114107478da8814d84cfadd93e68f919f0869831d427c8ca7839dd3742e934dd067438ecae87a7076f6c312b9861d640a3d2f4bbef7d86de1c10a4ff63f4c2bcb6cbb0ceb602dc2b88a8a674f4fc3541ce581b +expected_result = pass +expected_shared_secret = d8953400259db576f84162a3c0e9f4e9bb3a50d38518237fab6d284c2e72b557 + +comment = Rho leads to a matrix with unusally large entries +private_key = 13b21ddd6a8ff0259d2229745969188032c7d4506c75d27340079c57e5c41cf374e7671daf33619a11aaa489776f1b36825a839f14158df46ceabb26a02b92a920424f39601758321ea584f9f0442493c168866c55d6ba5af9704dc36371c31852428537a3a68e9030c19895bd2385acb088048752b65a3f1ea25b539635f113a1139a52b9c819b3e05505bc0ccb8570ab48163af4169ddb9b93848494a2cd4a206051f92d3c6a0192714307d228de792cf3109c29267eeea9cd2ed9bf3244bb455a0a58514efcc8190a5973c33963ac753c6bf7c5c5c36c65cc681d433ee048536e3288b8aab6f00c3c6d28b8f325bd838b7643131ea2bab3aca0b1e0d2afb4ea69aed00c4f1061efa259995407ad9583fdc337739152d6bcc74f4185d56520b67818926c5354470bfce881d535979a312cd05719a6e48a262198d441514f600cb804d0012b5632ccc337f155021853b74c34eb950d60bc63b1d868f4945d018b4c37fa77dcc762c62618a3ac29ccea150fcb77ee0b2a925c1e0dc718ed4019507842ed7a40bbc083bd9170724b0386a1c262096119870e35f791381b381d91ab2284a24a9c4759ecad48b15e3171bc3a117482f6148dfb7c005d39ce411066c23e076c90f0eb8ab227c162535e46d364b8f379b916bf462ba2235bcd68319ea5e7a115731153458a831751f98b9822ea43a28728b2b3bdf1ba59011167e221bf79303f15f5c1cf473fa42b0af5f5970dd40c70752f9ae27daf137d38b299f7a6b1e4a3821274199b617cf3b78d272724eb09b302aa382f9019d8d395a0361b7a7118bc125dca6aad29b01ae2839c6a6bb7c594507e8ccea16c8cb33a1262686c052a703f074201d57c38d11dc432c7dd25cb6629167599991a52b5c7b49766f07527bc8003dc27b65b2fd43c5f9a258873b36ba516538771744dc2706004817c4c9d86c554a4ea9af16a78bcb31e6941778c837edbc60470d9025e55508d9829bd4701a2c6b514aba1b4b8759cda898f289cd31c1267eb0e2d7233e5a22c435275f3227a7c67937b147fec106c5e2798ad3ca3d9755e37e21297e8bd942cc2f8a212f2125fa33cb039a714173b5064558605a7bf4dec183bc837efb865191048f9915858024ec37c77ca301008a00c2e03d0b0e0a3d0c67359083433764225363411571d1ef847244c6e4b4b84deb9b902f07460416ff4bc8963e72e1e7748491a635cba3e18659c4dbc20fccb1ff703d0fc531cb54c4800841a10015a3eba0e02194ef7a7aeb1242d25958d168c2b0b83a0da2c3070275bb21420cf7b2273a0184b3776ec117dba1952171b4da13069e09469eda75cb93cb04aaac5a2a75dbd894606964397538c03d41a8c2902b1f26bf1d9acada3010f1593dcac41df4ba5ab0552feb20527570c73bb9087e13fd34ac26787112444bfb4216561585c754324032921fb1321d896b0e917c5906b94917b416179b9fd55324acc5215dc1e6d555627d8b82f611b4226060fe95f91352753c29c3cfc5f889393fb0175b4c4c32f1c78da420337f24fea7282165b10a2172f8aec884e8a7234a2c2239c57c5629511e6526a40730b9ca0f08080afd8274f26343a8a50d061818e4a2305393cce660be9b6c7cff03b3a7124b8ab9d71a69de42ac02e998d67360d1cbc912f308a9a346fc5d3ba7fec24f923a321b362dfb868a7f151759c5a552401d0e8332bd047d081b9cf2444f63879e2b38a84a3c307bc86d936902c31a15ab68424c64ab6e4244916ba70b189a9875c83504054977785e41c3b3434c8c8069196ba7cf6a78409b8da4aa3466943fab47dd01712b4ecb876a8a398d22fa5c9599bd5a4c57c2a8c288046046c79434e874a1050f4a525b83aecdbaa04ac0b9c546a16860b96d5c118777d630c0a4ed33cbac6876ec6b28277bdb7f44b43977116e72472e4482ba55d38457dfe4a6008f5a547288f31fc47646650bf291125955d37944a610a265af15d3182a439c4938e702662f5b288f69c0c68a273aab0998c0796d525b04533e72cae299a98b178066a4897da20c90572265d461afb747cdbe924b1865ce3e3150bb2b454da237ed8bc7a7abed1fab4b4729b05e3adc2297746509c1eb24a0c0191a1d09c9eca79f39267da99c80ec98bb615b05c4b9687ba9001c30d48051b4f63000000000000000000000000000000000000000000000000000000417021ff8c06e546b01a2d8e56ebac301576b58aec29f10cb7141988291c67da11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 4c9b8e26976d7e77089578159dd1276ae2c48a781f8bf78d7959ea9d2649057d9bce12e45c3b994aeed685dff6c4bf5339f7bb8e5e6457ad69addd3070036a4ab978abe88a5a12f427267630b2b6fadc841bc1e441163210c8b60616fc334c5a04cbc465d7cc9b5b1a65ba39746d5ace9ecc091d35cd38993010d8a9d6b995aa473dd77ae9c43b2438b0e1999ecbe99b2680f601871ed2dec989e53953ed1261b020f5e0cdcbac9cc52572bc89d45ca9fe1f98e1f4391ba7e469daebd4f8c9b0281f8c55ae52e4ab4231f9e5edf0dc43e2a2d19d5657744a22d5f7bafd1c2851046d8c9ec4c8bc40ac5f5c7758960a0a87a92ec6bb549025d4bfee9f0b7f9a23a672e96d2814159416fdc8adc83e8556c214fab533ad68a788887c1319c26917fb3cc79a411b73be203a1173e50bc8498d66a352db77fa819a95d07a49687d16ac29c43e20a1a0106cf471e9d9eab0526db47e46f9e318ab655fe44e343b0bcfcd2f2102957b32b072d14af78ee32463f5b1b8c85b10a57d4c9ccd3ab92792f496872a869a111dd764c145a7345c02ecc58cd923bd84ba75aeb418d72490f75e78e87d1f0fa0a451b746cb8c414e12e6c09178b84b10597bbd4617c1d33d33ac0738d9b492f8f597df5de861fea1ba878b45a89caadd1a35ecc6fc67aaefbbcaf61830e9fcfef59e6bbaea87d28d4e4827437553d66b3f58ee76e735b40debe83a92e2563a2b7951494674cbbd346026195a5bc5d82aefd0bdcbe66b6a475a3866d4c4c7523520a48836e3d28bff5024f7ec37702dbddeb0703ef5662df2f27a98b74fa3002a530de453b3436f012693b0fba03b66cbcb3b89ce2d99605c36d8f973b4dcd659a5fe7398c92d11d3277ef56cf986ddd57244d2c3cc67743fd35e8808008b5fe9259eecc4216e5f68fcfc042ccaaec6989e4a31848cc1f933d218e3223e51a8233e314f8e5c7053d4ca0db65c1067460888f27482709df6d114b3462ae9cc91613c619a48ad9ea3eadaa50033b0af1017262dd4443588dd6bf77475f3a510f417d9c7bc0103c96a2f2b26895fc0a06a94f271193dd0744d7687a8 +expected_result = pass +expected_shared_secret = a520c6a9bd8260b1a71efeb0d5878a388715811819e4a54382aa4107e37a094f + +comment = Rho leads to a matrix with unusally large entries +private_key = cd28b1e3714f3c797340840f40817791d502671640aecaa4f91089ce4049fbca7b7045b350d36eeb13761605aa4dd87e4d062a5486c5d73367073a0a949bb0852956dbbc3bcb40920d89518dba5320dbaca890ccfca8059539505e3c8ecf80cf404c78b262abf1ca439e132ec99c33328860df5523e2f63232b39d83574ee631591f6cb617268a0b5344d2aa003e4000e821734c8922706bc6b9a9542f993920451bbd131176087d6e53663d46823d5a1da3723149943b6f5c34776a8e7e142fe63b50b6ea600cb859672b57bb07678382a561097dc38740474b60f61656f1331fcf7824004c4300f81fb9bc457f97687c6215440486d04470096b1b5fb1c5c77063fd36254c6464f19a96a8a76644a12663361a36d37e6e08bc76743f812448a8542d037b2bd483214b500ba1c07580b44e6d9093d3842df52c92ac8011f207106c069f7e3bccf06106770a04275231d71c5d1a516d6dac6e362397fa348bd49a5aeae37e6495aa1af2084a42c433756461608ba82534567854dde95efe0335d67a4b37b587abb050bbb999c2e65feea4c89d4560402318f8d89afc7601cf1cc6c663c44a85147e7b4ed39b41e6165b27bb1366776c409b01b0a9ca1e958063ea65f43cc8e7a4b06ea338bfc249e7d2bc150a8595500900f64e1a346fc0e5bac6179c505867f0617baec402229a4c00b267fe479d6e3b34e172c800a45bd0f39177083fd0d15e8912498e6818bddc3084c12d042cb9f2448a0d450b3dbb5eb6968179469998c4a54e7692a7a78fc96998d3844602002de81052e84bb64b693485157f15b054d16a5ab0c593e0118f7745244ffc2b57f939f0845b038832bf4a6d99123a5b95b73044ab6788c000143111065ee4cb9550d06e34b81e70641dc5905faac129662733214b866439937d39b22cfbc203f809d265158f02b7c1a762dce060aaa1117aaa9b002aa0f19a68ba5559bfcb5285a29dc8989ac0ca9e21019311abaa89b5730864817227c0a9d56d15c950453537faec9a9e6c113a023a0a14161bf3ab062c2f9a79a6c7142129bbc80539b785464aa10aab8b5336aee10d8c39b906f71f9b2565255717c4c1b874a8cfd7226269a74a26d9ca0faa218bf8290a461d86a002ed272674c690413a870fc28f98b2a639429136ea2db2927b341a6e9216c0fa447f7eac8a39c535e9690a2e8027b2627e79138f7ff9a1f71b951d4273eae0ad366202a164b011040a124c0ff8337bc8e74903461b2fa8847684036f3b91f8186c776b51c2a88a77473005f2729076491c00696275759fe2c421f18a39293e4dd6b4f783909d42459842855718c53228c339f28767f94f9dc17f600abd64389917802ffc0009aac74d3eb579c27626cfcbcdec17b182bb48d18a7b474a2f8b5484dc088da064aa45d4a81adc9df11327283b303ed697c75c77730953547a2286951b7991bfa0c397044b34adb4150b0556790764d833b81bf90ee7d3764e9842846c8228917fcb00cb87c39bc05a975d2b8f93530918b14b7387af554836441184e761caeed04d6a5432c8e918360b902b45adbf8b477c57447d36799d6986365b365e369d91e9189e1bc6b3a7975c348f9d40879869bb0a40a0fb8304879b61d5e06aa982b7d87bcc312aab46506c65ac4f91e7180b22b52a393032e29fac2a8a6841a4fa92c3c3233d2367396f57509f7c79719733c99898408b5d229b363dda598d6a924f9a319ac0c247830cc2b9b28d1501c9200d46e13c358a6a9cb07da7494ca9d297eca37ab9e44cdf2b0dc5a121466790ed5782b5ea3aee1734486bb2aef1246cfc9818991eadebc71b0ab4fce11ed7c48f20a6a1bee2b7aa4a0f7aa25a3ee61d844b298be06f24aca8e4464cb9a23379442c57511cad2a8db4c02a9189a1c048643372c9c1247053e245b5b2cf1d92b505d4b6f0d60b26aa16d71ab41202922df51c89d394cb42a905601fb3004b77963af10870993aaf5ce9513f8676d6358b7e77055b793c2b93971e0478d479b9e19198e7f63b7c375426a342756c966e49bd92061c099b7a114651b2dcabc779ce45bccb61d508335b4da5841af57346bd1539eae4853e931e6dc142d96babec750102cb5f8095a8abc82db5a1206953bb24bbb1146369a5e7c1bb78716987cacc75200fb3816581d21cb300000000000000000000000000000000000000000000000000000098428cd4d53c3f54d0741f72e43a3e67c29422df1eacee7be26c3f3ecb259cc32e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = e1b2fca92070d9cf0a781c557edc393c363dc1aaf7069908434012a43395a8aa06326245729610995d39a8bf075297a78c0b1e235393c848069d2ae75fc3205e343cee5529247bb609bac47422d63ff33a191f9bdc9b1e8e7f92d469e1426b0290094e231de8ddd2dc853e39489267528f136adaa42e47466b520cb079e7ce7ddeb96885ea7d3955655f635dd7fced48a1ed5b8ced12e3db55cc2b03c890801b53a817c4f29897d83481b60579813e4d39c8ebb3b195134e617cb08e15cf7e43389be5442ce5431bc3aed76c7a60040dca336a49066a91c682922637e51684da048c5415d1848d61c9197b15fec2d25f0d6ba0b35f2ec945d36d243a73e2b99b359e80efb365e07317d6524f41fb22c0308a4658d40e688dba11987a9f769512bbd51274c96106a5742c119326fd1d94b54e588f1bf5fee850006cd7b7d9c9cbdd09fc9e7e0c397431de35eafca81d91875978a2678841460805cfec9afb863f0ea8dce2a494c581933e4bbcfe5f452899c27b4f0c271a45e2b3ca074db853074ecebaeb80e5a14c420f2b58df10de25c60e44d0da99c5b2aded4640861a342057a20e058525e215d099caba6b48eefea85c48ad89d1c58afd58d08d9e55c2203a79d9b6e0c1d34f7fa90dc47b20e38d13aa9d714dd4429e36e7092c167651523450863e9fb9eedb1a3a927269954845d97f5f36f74f441af8b26dd93590367e6ce9fc46157bbb0df28b1e24443e608dee81a1d7480309224fa6ef28d495221e10c518027e66791b74cb96d71061d402667b53a5570d7eb520536109ff43a535d38a0362b60294d0459afb82159f930a76e3abf7b3585f3951ecd2792ae60caf9659489f424bbc43229fb40385ddecd99cd2245e87d6f0f9af1d3b93c0caffbe4b602f201735cf10bfd3aad6a82fd41f0d5b9144c1c34c4ec0b4ea7ec6b905d9fe514a0c4d106bad2c7f6ad62b9b17677c295cc448a37f888158fb828a43cedbf48e265f4173dbd1f81834ae04ffd9c67a97b6bcdc57acec9596c78a8eba951c7874bc787ff30ec0e5ce616f66253b15033c3795a9a42859d082fff0dd28a9c8 +expected_result = pass +expected_shared_secret = a358bf3ba7aeca1e2498e52a64cf84f555f6537f0bac7e56560a5ca8f965ee1d + +comment = Rho leads to a matrix with unusally large entries +private_key = 2db0097b4a8afe74111d4b78f8c9a8a6ecbdf4627c00f562b7835f78557e5c3a89cbe1b59d6c019ab574e5ba6951f926f4b274e459260755b4e536513e49607c0a63e718b247d7b5dc91abf1e09d87dabf67641dd3abc47c2a1bff35a17d0cad8a1345d08021149cc5b1c914caeb780b6b865029960ed3af31e976a35c5d2ea8194b875151d52131060c71b660016984810b6ebb31392f9b9b8335adda6199b6438eaa48b1c704c0ebdac2f903051482b3d1d4a97e73779452564b7c9bd2a081dbcc6736e89d1ac7a96518a0851995a8842608386d1eb4bbadac4e70487b05680034f21cf16100b349c356a01c22f45d6585bdaef528375c052ba029ff48156e578915d953413647b5f037ce83aba554c263a3374e885177c0be3850cfeaba9d8ad43c30235591e68a41c9ca7c49a3ec86aefb5438a48bc5d378309152ba9fcbc344a5ab654ace03b823322b3d00e817aed90bbf237e188bb4e4161c86988f9cf3665334b0d329ab34cc13faf514ec989658a33fe751866083b0fef1182413361ff40540b8365a288d04a846a83653ea7a5444e62b83e0535eb11c115c76f52147f4208522788ffd63a0121c29d036cd510169c8c95807416f65f6caad936b0b981f60673a79b378380a321500770f671939b96b701870b039cbbeeb2c279aa5051478bd7c9ae4c1183843260dd67a2201b17bf3865f1787a91c7a3748a9c1462a6632316bc16b63c0714a589c00447b43f38b10bc2d4ca1608fb92ee6d151d9bca2b4836cefcb17f9bcc83cc36ea2fa90fd015edc89c5e769c16a189a88009bf7e00350943223c52548ac8814d3acd6f790a1f102a5f87d11f85e588060655b04c09a73d50227597cc8702a120dabb5e9d5639198488921b336666324e5ca5543070d5b3fbca589fa4282c520bb03132e86f92172d906ae8631f74c46a51b675d7a0d79e551d466382f57a05eaa8aea2395f4b22ddbb3267ef440d099851a049e583382a8e26272813525e8863b4530892127b669b27517122e05a90ad40435330107e90be6cc9733012ac3715ac7994330ec99a36a24386b7dff16b468b08aa364bf972928df72b00c233d3ab1054fdc4a8420c8c468a18c5217106b3e609614304b892e1a9639d20b0db01f50eb8f66f3a52579059f0699d012cbc7a0c82a4b9d6090452bfa1cc1041524516ad78a4232e0864a57c49b0427c5999e1a45af002c571142180c91b909b971c33930bb43bcc95b1d21ab85a2a34ba4daa5be382434ab71c6b5011426a81b7587d25b2bd0f329cb24cb777502d7a0507204c06686a51d58257451cecc5a2d2c6b0fdee34f3948ce76cc1dba7b672dca4950019c38e1bcf7a9c5505acecc6b1cfad43129b2c09c3c8bb257443ce152fc8a059ab9afb6f015ef14ab1ff50a4cb60d64a02827578153525b059c0b1446acbcb29ca6957cd3468650cb8cfb59101ae9181c3609faa2897948a31d0092b2c5aa4b16b842b55e117228ed98bb5faa6c5f092c9db050760b10e24c5609786b8cba90fcd1838ff80a2f735ecc9398e291579f449823647d17411cdf5caf2617ab5d77760f6cb7230354b022a72bf49cb3a2c935232d873c5d8c901af429709704cb1fc0827cf40bcb0a8ec151211ac8070890512fa06c48d7c3e25855811bc88590872ff25f5c78c1734c845c18cbee0888b06232d853b1a38a310feb426ecc7b30bc805c998ae742b50d50bd77e6bbce76bd3f51c1f039b3ba892093a88c48e0668a68279202838265b80f2b7f3a33abfab4845f551289f7c4a5274b0e0b41645a6f630329fbe8b5a838c73f73c5dbf3aa0ad763df6a390a4910093abdfab96367809a55325f31871a23641702d10f3a2a652fc292086212345679293c534454aa9daa998ce4039d54221cd49fef5c3e6be6ae6a2b7797e3b36dd673a2941fa98abdec62b67783a618d47b95e7cb372b0844dc133ea174b8fc2fb2d53c8351416f813c7ca15d7d8c8e61c27f765638b163c3f2e172b0fb3c28204ff96c642452cce7a40a7bcb6ae31552d6d78305e3c08165657848865562b7f500c561e752fb154597947f18ec56a7057c2eb5bb99555c2c99b003b115d6214ce093bbb8d712f3e72fab70198e5abf0da17384f6737b3c602296726e316250f4ba15e41644c5b5de6572b168cc21da000000000000000000000000000000000000000000000000000000c7024b530a66f21be4150d64e3d496c80ad7fa6734fe78c8b0708dacefc0e9225ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = ab50d831cf728c58f565ea56c5dddefdbfe9cecd1ec5e5ef7839b594886e58ad3d3d43e8504727507e9fd38a96b5e714967b4fcadf0b902447c6e9d2b857e5a43f7bd68a1f8ab524066f54345a9f1f84c0394474d416e37aabf5cef0b8cb3996d2f28606ab9fe89a263b4aba00a6663588e7af55535f148430f82dc4e3c8d14d469f29039e4cc04c6f431f67544a9902fcec03f72cde536c340a93d07dd0ae4183ecb0ad2a4e5ee6ddb1c476f3a7b4377f05c709461bcb2809eea320423ed00d08c24bb95b0f36dee221bd072c980f94700a8d01ea911392fa156b2a33cc85672a8515b1d0c6c350be5b1f83fe3ef38f7f7f6ca4781c3284fcf590c156df251f25761490017e4a317c187df97131a981d4106f0694fa08da8d72574e4334fab26d31ece0ad672a5fe0773ac7742123765115cc1d60edec1204c170b27974a902cd77183e51a7f229f5be88789543bd243749d6582e9992e9e9efb16c064adbe2578965194f561525049a2eb892ad45822169b9b5d5509f72dc6e8bf4f0ec1645a1820af7e77519eac617c5df3f3ce7b5a22f9c1ad1218d896aeeb0c9bd5d90030139582bcff4834f04592eb36b3e10907897881f241753b83b11c8a73d95d595af5b6d57c96e33801dafecb7bfe3606313500a8186067e28015183503e2d24dd99048b45371db8ea1801b331785fd0f144fe509a68e7b86d379e6ee554be31e800d547922195cf417746b9daad81585e57f86a9e8146a5be5e9c00c6c32d7d3599505c422a5e833d1ded11e231307019767b4690831f3a6baaf10797b4870dc46ff3f5d01ba14dbb88d5bb86e02755a29915e22ebfadeedaa85dd794b6c7dcf25e45b889a2b0bcc34ab6455106b97e801211031a0f19ee0107e810e9180c2916468a1f13e4831c429b543269ae0d60ec349991b04fe7756abd54160645911915779b843405f23016278d377c58b3cb5237553a35ec3859610eb3a6abaaf7b898c8a34fa18a0bffcb7a3039d0711fdcac329f796ec2f821b3809844282b5860af6686d2849ef4442aeeb2e4310469d3ed766e5d9d093d79e27210d995fa1903c8 +expected_result = pass +expected_shared_secret = 5e63eb447ffb9ec9858ad3ac5d6897e9ab3171798167e4abe876f3f0bd8e32bc + +comment = Rho leads to a matrix with unusally large entries +private_key = 64a90bf7358dd94798b5cc3a55f8696790b31943588dc892e7673b9f782b905c4a1dc44f660c475df7473cb672eb31c6a55009a768548c52b322f5afec8bceee2105cfc75170f1505f4a8cfb4b39f368c1b09b19f3c41e5bc14dc49c9abf48baad0875af35653bfca37cc01f467aa22e8976b70245b070556318388bf9cfee0b46d1fb6fc92a7df9ba07c5ac23b9e91b73857697cc4ca1a59b09b6a813e1a84570483f036014b89658c26d0458cd983514578115e00553ef0597ac89677bc68c469439be88c425242ea023bed379cdd9b9c80148784d362ab5134446f075f5c11565d37b10a5cf3d8a5cd2b530c3bc40d10375f7a149fe107dbb486a1ff53d72590d3e6abff5d450ec741d4d97218369872ae5ab98b9514ba543e2626dae4c5f09b105fb2b77e6c9c45b61a9c8c73897f3a90f1710609c78c1375159d678bd53c1efe92812bb8060091ea5381f46749fd69904dd423bc882acc6f118eeecb955ea50bdc15cf9001ee5a4a476c5abaaf57c76119906a61c5e9bbbb32c34653b29ffea16c44c14027199b0bc0f66ca2f7c88a86e607ce6ea578d11c7e38133092b591ab251f666b5af532f0d08bdfa98c6ed1805efe16bca96a3b745ca2357824531199ff28505267148d7010cf0c38de666563b41d6956470dc215b709bd4bb4008dbca80377fcd09a34b8461cdf8ca12ab63a6b20001474d287b02e093acdb7197e09205e2950144a935bdd03cccf696139b1c6217491c6c11fee948f517861d1805a8f166b0c92cb0663a77a8105076cbba932483d7265f143a5ad8260396cca5a63e79284c6426321b7359833a4f86106aa9ab846bda35414047c31462d0986ff5f04027b4426dcb34fc024dd93a9e47abce79936a6aa59052089b3bb5af13f480cd1813ef32570e3a00cb712b36c4463f5764cd935d2265a01ef745accbaa086174eab2a4a421b5fc4c9254515d3ba73124f4c155e9caa7b25e183b942b7617199745e5b9b15509c4ae370e32d07ec1dbabeecb47aac658bca87181d950e891c5eeebc7bd3b4d0c3357f67769faccbc9b1c44e651bd6f753233c12e4a8960523b4e87152ebfa716533137cb8bb472202b29e2a6cc2a6ba8ec39c4c408da635ee84b714a833f60952531b51cf0820496362598241ce3f7578fe562db4bb6b23a8117443ca5a5bb369abd40c779c11898587798ed91baa682c030268246b0bb40b435f460be810a0cf9cb91c8d681f8c1997c07c3b31a1d404488baeb6640419b1acb3648580b2aa03b66c2415789cc06bcaf246c8fa15ba98f043a90bb6478cb257f399e3a765b4e704beaf6751df658d52c4b84389a81e042ace6491ea64e01a473a5e7614f495c1d6177a9d1906c9bc951a1b4ad46a7ecc93ad61205b319a4d3d620d377584f9322a059a55ad782f2db59f8f7841a4c4f8c08a811dc4993cc7b7685729155537028606162bd5a445362f8a82420ba8ed590370b460cf1adf4e1a9c4254eb26791677b56c1d1a9947c8b63e45ff43489d29a88796543759a2887478ac4e87806213bb5f51790832496d958cc1a318e8b793db5619fb107b5d20b5e52bf6ebaafffdabee37157fa821be3681dbee56646202268310ed413536e630e954103a3c6643c3285cfba200b665087831f21ea209e685c0bd71ec5a26730a0a01521610572afcd83014f6104ef56878809cce38579fa9b2702169efdd5c522fb42d9dac80ce834c115087f659575aa0a1d310339033e4ac95f773bc2779529ed65bfbf043132f2afb3eac67d0b1c7989ad08372f728994626ac98b2b385c5b2f3552115f97517775507f75532700cfbef635caa43286720345810764bab180f96e07f40e54fb75b1b9af43852d569133093763f211980786b97f910d04f26d77075002309441b63d4e864609e8afe213144651931c753c4c916fb8f871418c07fa4835b5d8b66e6c3bab45986c09346bc31fbf882ce1ccbd83cc7269269b6fb82e7a75b517540247206d6559bda183b589e726961a4610b081d2bc7f03858ca1515888b88236f62a241275b8472d4c5260cd04c690395beb853459b5762271c0bf676345d96ca0e798fb9a7fe901b107d078f5220306d9cc58f009cc84647d6a51ed3b148ec923049c14894797fecb44a4ab0cc5855c111c32e50c9c6d7ae8fa3a00000000000000000000000000000000000000000000000000000057c20084d159d55e3e7d0469d2c91a32babcf797b6817771ec1251a72bf5a4928bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 5be0852d7859e0229710d1869411914a9d720f9210aef0031279cd456035248af7a387ece9993171206b497ac3b5eb868e7cfde58ec09a4e87dbbff0c101605f548fe27608b4dd46c890ab19824791c9be09e31781a1d1f106779c9ef577bd01054e7ebe250c0a6ef5f1ae8552d0c67f71f132097380de6d233d59db692d35f981cf200b91d2d8ecd026fafaec85d67810604ee2f5b42d190f26d763ea7deca62c89cceb3c46cdd295a34f59c54b3fe27c63f57cdd21f22720eacbb769b457a8e15628fa4fba818a5926c98b7a8b8d6c0a28d1eb4151c18e07e3de588dcde77422ab9a6afb30e0f2f3ca465aaacdf8e450b21b598bc8b62b8c95147697620e031758ab74730323144d45b31108461a3d10115855b9fe72201c2839e6dcc1a006c5966c7dcf5c1987efaf7158b3ac9a5fdbb7ab13990892762780beaabb55a97c35b5f3ae5bd5975f519eadde1c46e83e10db765372b83e5939e5f93f51eb085fb0af56d7a4a70e611411df560a13cc28e7670876b8a6d00407865dd33e9383cc81a227d15b63a2f9d02bdc719713c3c73851b8c7d921c1192a7262c4552ff13d6ba8be7e51f860a6e0af868f98043261b50c2d6f91da089f6c62901c702b4f9d664016ee71baa5b976ae8c6d02d6d30a8b3d41a4607b5bb7bc91fa9255d7e036575a96c6a61711c5eab4845c7b3f50f356f2e10d00ce0703ad9a42a7d7e32e2cbb665c26de8aa37bfc5e2a12474c5f76eb34710df1546b87b0278018d9da82a40aec21235f46028ef58a78fe6d1389f3c7cca0d964b5f1944cf874445d27a00379acb75547e8640e29f7c4186ba0b02a1e0bdebb7a5a0bb5aa237243861a1f09d56bd61ac2283b24dd61bc31d5aa2ed32f11cc78336db3fc5228ac91169250588ecd00032e6ab7b6503d67ff97764f763a9348f40f42afa21015ef11532a182c9bd45bcc80242bf8560b4c7e9dc8d2b858383036beb46cf0023c5d626354f200bf15cb6cbf595296a85419915b521901cd2089a41f6e66dc62477388b9135713dc89f29c7b41a425efab463bacb1835d34ea887dd28bceb6db2757a753c53808 +expected_result = pass +expected_shared_secret = 3eb059e6d6cf65d88a4b359f79253a8fba021f8b00df5e95d62d6ffcccfac92e + +comment = Rho leads to a matrix with unusally large entries +private_key = f05ba04ee82ac37492c48a3c0df734cd96bcab955f69675a12973952c486db7b3ac85951f0443b978aa1bc339def4203f8d226ea79b1b1e4c457a461c606556d82b60f214a49bb1448e8c83ef39766e26162bb96139c18ce77c679a176afc2a2e593046045cc4904c90615585c8a0349f066c50c9ef5e586039939ed523155174c54b74e18e8944837b4f46a83da757e935aadb6d920f7996705c6c40a17386fd955875890ea3810c02444704abc54dbc79313b572191c4f7b7473e794567c0964855686184d65b9a7e646cc9d26a559820d383c63c278bd47077664d7041ecc90f4391fe9128cd6d25346a85699a258c1ea2294b78fe1326db7caa845028fe19ac6af212706e00c360c3fa0792c612c1c4ec085d86803e895c8b28aa85b10b350038d1ee4cf1935bbcd62c4fa28272bd0bb96681aa4230e71b698425934e16213593847f83bbd445c689484697ae510e158382d6b05175025078639ebfbb8d0841e6c266c4ffc195054606f54cee5e609684079a2bc07fe616f544c68dcf22d82419b28f4c2c34271b4062de4c23cb8fcceab785ed43a48884013327a6b1580071e30456342bc7144c0be299bc108579283ba397525f1986e89c465e432b03ec3c81f6c813c83c0df455adb658254ccc973465a864b1b6ea4ad8ca551c0a909612238d0a881c2f5a90b831e765011f8e95c924c186e3c490d73770897ca1419900b5a11c1935ae4d096596c821a623a21b727bac63e346c445c8a1566c10257b2815f65c297598076e6cccd62753d053d9cea8a026ca6ebf2375e3824c4f071c4a59142c0c75dfb50e4b61f3767472bf15262bc55915bc8beca2dc858cd0d9601dc70b844768431921ae24a6fa462ac21ac4515d23c24987591d1654b0598a4b58644485136d6642541616438c341dbb97c879752f494d9749bbe47022fc64be243376041a29d26a7e875c2c0aa0cef45a3b01161fd280061e958f09755d5f06a5fc086dfa1991d7b303d7c4c0bf2b8e169bb85263a6717981b34ba3b123a6851cc42e7a00bb09088a1bd0d882024e1155f5716715b7950ab71ed582bfbb791a82a342e7c5fd5ea38123a97a2e89534757babc220ec0b499b70ba5e4bb37e051124575cb28392825a3d750c6836696272f745309ca7fc54c403003ad4c724b9d4232d34454dd49f47ebb6637a1258fa899566148d54c36dd013d8615124d34abee4a9bf3a3a36f3b308b47e920759159269c3bc5658c37a64079b6848471a184dd9c032659b08bea7753f2683767cb6a44562af66356ec45e663266bab736651c38edf5ba5312240030badf358419e03363f4cd1be8cd33b89755014d40565c15407f2c763b350469f014866e215d4eb40078491f21801c9b9156f87c838613849f52c868c6717c63baaea727af13bb2a6cc7559b9fac995e7e743c14376c9964cd4b7035732424efb57329270ff61abef3076da40b7e797b4cd344a712c7898cc02fecc25ae1d5b4e104af5be64a055b29e1d2a8ddc79fa0b6146b4b5f8e0715fd0b8b87537331aa95cc07c3877137fc172202530e479cad45a2324fa395b8aacf80b92d6b2897bfe978fc7a1900459c4fdb40a2015f2ab9c9faca9837c94bc92a6bc66b906a439b8dbb5a7b6c141428a59a5671194a43859bac30f59dd7e7b83fe0a4647276568c2affa215ca80721decc8d684760d2c23bef6c9891a7266eac437893dddcc8b4c774ad1bb82f0f13688123f23170b15813e51c5b1806c99c00602912b2a99729e5b736dc80b45026bc7e08a2b97229370e2a590da79888b843db001f0225b429c22146b75c37705372b58cb6556810a4818842f321a46136809aa3bbf4bf4a7cc9322a16539cafb109a88891757544260543d25b737612cb8381baaa3a7cac3c564ac62f851077ca0c6e5e47990b9096d01998a9abd4da8cd1c7716ad34c2eda9aeb57aacf8d25816b083d6a18170294fc1fc281a56789edc21853807f3d93bc40743b9f403c9e9441b3b08df5758a16839eb3795ac9a5d051759b5e680a3aacd2b8b1c4fc13cbd267caee21654b1b9fc68ac544aa1e9421fabf075c510c1e7b98404191de64047854bc1e714c854c75faa248146930578123c538621e09c0a7e22757b730d1f6172c8a7adeed087a8b3a5be8b4a07698727512b80c80000000000000000000000000000000000000000000000000000005c418c33cfcf13b2ce09919633fb5054688cd2d8996e995fc1ab4aad1ae35d57e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 7d6b0647a5e86d2f4016277a07c0f48186262312d4c5363b8b5e655aa6150e4c3d96b41fe22ed02520e8a236bd0e9c2c8c47ce54529ecef55854fb4e7b9aa34329f58a113771504c0d7c53107b87b6340d26f8ec893cdaea4e253cd6284d23fe7cbe357045f5311c4e74ed6e36ad5f8ce17afbf73d7e8742fd24d3f07b81e1aa8a2c1acd7789263163a637d96e287c5bc3086806296ed108fe6977b4d29e67a030360623835adedcda4bc333854d7a5c13f675a3205201d14e557422c36bd949d7bda0d626e35e066cdd30c2ea5d335857b09af66c07e4cdea6e44e4f67bfbd0563627c19b4a8d6e04b2d26cc9d0e221eeadc6840dc081d9b4e9526c7420fcd248fdfdbf51db7ee0bbb5455b338bd0913945246249b0953015d4aacccbfc1cacc75b6a1be47a588782b40cf65cab4a2071952b44f56217643a6e181e8bca950cf352a84d7118500da0a8df9d2ceda15becddaab696e2b56d164a1162acd09d545e7ff69288deeca25bfc508c15932ff95d3e8400cc66552905447231a3742f8aacb9dc1f4800c80425381896960a0753d8885188b627a7fb94255992a5974d82166d4e504e491b9339cb0759189bd7d52a5f1e75096fbc39c12f1a7f14cc9509b3d6fd494236f85aa6df4896425ccd5799285249a0e21a51de18cda835b69a9b5c3fed85794bea0342a0c984eba708dcc1842ce676999ad4c46e57ae7427bbbbfab6208cc9e5357f656dd5974dae8246ec958fe4a4e422736f3268fea7f413674a4e8135d0006c723c5545021c537121eac7b066a6d895f3c3c92c66fb9a2bf96129aa6ecb187eafcdb2020c4d1a32b204da9f178cbf5f727b3a70360cf737ee1fa6fef0bd18cac9e90755f56d44eb4514728d7869fc8fb8c762ce80537e38a1d6370ed4fd91be8ac31add922e419306ced9d81bfd8401ac9166faf3f0e07f179e30467526a75ae14e069f511014f5838d2ead5e8791481f5c76639c5cf58b9dc38c3458f75b5a87ea791ae0930b5ed0d90dcffd5236e55195c44a8100881891b93af6a8e88abf31d2a6e0547d22482337562b084a6ffdd3797b20ecf1228659 +expected_result = pass +expected_shared_secret = f2235105b63ed1151103544c9c96b98709816b2678806780d4116522ae82470b + +comment = Rho leads to a matrix with unusally large entries +private_key = 476660dd0401afa8203b5c280d87a2e5744ce6d1cf1558c871429147b831149670c365c5f80c4e5c0aaf84ec9108d07e25404049ab6a19415588b44eae659e9eb366cdc5c5e9ca96e9b99014c74514801868f951d841acac4210a3984b25f0717a774aa71753cfb3c9bb85c5b9eccc67a48f271157739cba3fc49c5b262388b2176bf3789b8303eed08b03034cd2f24ba06923bc1644ecf576a1d77283c359edf53f213662dcd6410044af7dfb3ae0a3aeef96857a169fb9a9a586db5094b3773750c0c739a73b0463e9283d219a2b277ac4e76ccb4e785b0d6c9d19025a678c927e041d892b0403254e2bf24345851ae0c759e7f159848b9ad1fb60169ba940b000c42c11f6aaa6fd731e29401d3101ce48c47c6bda5dc818b5268ac7ff0c6a36cb5410927ff8290a363524a55bc8a4208d79e732a53bbf2177c6ea407c313c8d1bd35c489ac161e77d0e54cb767407167c06deb313c3b17f14c3009c308133059eb6663f45d4781e259e9f2a7586c5bc28c2526ee90b845533e18304c5a3801fb9bcfd1c0b03260486d505d5c1afeca04ad984813baa9b636695865b3279617d194296514c9c4a4189c9a645e66b0b798babde151949e8831570490bb227bc01c2f7880d1cd44640a53b1d618fbe19499b25b6c1aaa8016caaa893a87ce65502c8bf4fa4015e74184526562bbb1ecfba8eea78098c629f29c4097a8bc9c6d178e54a3f676a6e40150c865c114d133589c23f6263cc8caa936e03231921cf8fecb748c6baf32c639330b52e9acba2d3907c7b3b03b85fa063ce9669cb2d64c9d70488dc0b252727cb520c30395a67e3aca14d3c8f03c19114e756b2c1c2503b7698c40ce5b84907414658819968f6af91d98ea5a08869d68c86e293b645b11c83461f625b8f0867ed02a1570bac00a8286c3aa9d7f1bead11a763bba0488c428aac1875d265b9b30b1220b4f3cc4830730085ab6125b21586bab169d59847a7023b3bbe164c6ab8746af53a5d5713a5a4969ecf08402095a4b4800be70240262b18e843022d538c3cfc5ef462c8ba3a287be8be6263a832d1a5c808cf5c148038920633a7312d320c7323c81a39a0a271ac7cd18cf3f2b9a0617c13e84eb6b36a0a242bbe85c86aa5bc22f205f51c0ab36084b4c79efc220efa7301c4d14912e39a1db66b3aa67a4f721c7f988e90939bd55c7f99189367013f4dd0716d58637f5264dcc742cec65dc78273e4dca225b1987f50696648b6c3848450d69712f978f974c4192732c7c7bbeba18a0fe5b38b122cbbec27af82a6c7883265d42ae9d58feaabbba460cfa0cc414bac90f460916d20b632a717ef131c54445d3ba2a1ffe8b156d5a4e0cabde82cc7317cbc14f9a59de92385097ece54a6c1e86de59b8cedf1be838029168aaacf804ee099ce184825647b5e46b42d73a202ce1343efc64e5cac68d18493d26767e2452e0be05c0394242419cde9ec567b272e2b2cc63cc2c50a273231b26e8a665e6881187795410009c4fbc3193256c550f89e2bc4c728a851597628c64b3d93662c5f3687e3c151bccbb13d91a3a0452db4c0965cd1b59ab89fba033760ac0d270829b54ac4c844a6771a43bd39a99f3a0a27516158a52178608322371541da4eaf15bab4a4be25920cf562185eb3742ab033eea81ef77976e8b9ac71412ce968ae6e83bba7f23521727a4da4a54ed56219f8a2965c064b752a6292c737713ddf362b91797dda1b45fc6c5cb1c70dabc75da0292901321aa66c8f6a651d76f24ea022166947197c3383a90bcd73646efec6056d2771e34b931b255676b52278c64c55455431c137313149d948184e4a0e8ff4822f7995771ba32006c7b150cd77acb35795a336b860157c3861d78a57c39705331f2be3931120b031f54ba1521ee8d0153630926ed183a4c2a8b8fc5fbe420b084c14771b3d81d2cdabe2b64beb78f8c4795f45446a9b4b4768672bc9598bd62c802108c5e9932486582888cabb76a56d57262eb2a58ca1a0b7e521eca4bd12f65c0cb717736b7ba3382677fa1403926f1c9bcb20f4ac97e8baf51263f25c3af3d2b77f0253c7073f6184b6d50718e6fcb9ffdc57edfb46cc6658b77a77f2fa38f9ac9462ca0476d47c9c154d087695bad8ae367235dc870de808a4aa906afee167f039aa3ffb0000000000000000000000000000000000000000000000000000005da579f701a5780156c6991c0d2f32cb75b1cc0f3da659f3f3051fa4e1035a67c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 50c85020f18e41a8a1cf467d921bf02ed861aec594810ee77f99b0613d4622739a3a1b6050c5fb2a44b9609668b1bf04fb39f2b91e176141e975ba5ab5a1aaefd790e9ae2db2cb853ea65851d0f88452cdf3987d439997dbc90287c2914efb54d6508e56880956e4f33f6bb3c84d6edb0085b3edd6134c531e0ce46ef8b1c3d2c504095e1de67f5b2593702dd4290af44f7a0487f7eb0e42214de1741573856ff5e63c9de9f66fb135e1be7b759f12641b48c70d2789d68dfda9d02f57a95060aea2957cafe442baf320a3813a4958200cb0c13f983ad13b910aa36aa623c219306fdf8263c9eef8c5d5a21e783d8e0aa02704395da563cf9590daf815178fd867a4e204c053ce2e73ac40cefd418ad0a8d34698507e275a57b784030dbc05d20095a9da9e0454364b12958f7ac8323dab15367a90472e38ae9845ae20e1cae296ac296c4cc001ade00ed9c2cec74bf17cca84e58a26031ac5c4a0d3bbb20c6d57735edec022eb313d3e2dd0325c89b0ccd6a4bc76e9a082c99eff5adc0dd9b5cde0036082d52be2480f5fbdf35079dffe83fc1f85fb03d2a2f4ec68825685ccc7a470b26373f43b9e7824b433a5010cf94a39226d7f4702625eaf9e2e67a2c745b3fe51c66464c395bff2ddfe831580d678f5ac75cd350f1d0b8a778cce43926dd006025f2efb9f6abe18060c00e78734d074b1f1a1f6bd424686ef98355857046879cfda8a8872e3934b858e39ffbaceb60fe828cb78fac861e12320b2eb9514dbb6b7ffb690c12919ef982482fb4d87b7ebc98c4d2d5c270c4b0337ee683fd0289064577a2bdc3d05b330ad7732bf1574c2dd0c449517a77ea29b0f519d75e607d32254ee949256cfc835a66a4c4dcb0297709b5a0773adc9b352cc084954e92989d7ed5c6ae73004ef682c4855ac3cd7c1e2a0b38457fdfaefc96937df19e6ab1eebe500d320e90c3694a69005f610a9f8dbb058e0603b0dcd80d8f4be623a6b19678aa556ac61f8f77affbdff2f2d6122de5da05255973029b0f824f939a27b84e58b53021255a3d81309255124a8f9d9d1923ae9c92f512d8649bb9faa +expected_result = pass +expected_shared_secret = 90e6702801a2634e103160e98754e1b2d96b057d277db4203abb8f52a2ded972 + +comment = Rho leads to a matrix with unusally large entries +private_key = 256aa419a0a0599376df15844bd3a95853520fca2d9b342b55705c896845b0a8a8b35356cad9740f34ab358a3da5b9596de40aec0190676cb1071974c3e516e4da5249da1fb7c1b434d997341751bcbc3951d6265051b0935765ac1a9ae878618ba74f7bb88527c1a433b25eb2f635f4600904814d4118c2137ac368d2abb13b5accdca1ff6b5d8af9a03e3b84ebfa6cab2b0ab1d727fee1954dc818299b9ef1b76bb71570eb6cac914abd084168a88129e163ca69706b167cc1f3b5c72546cb0075a230e42cdcb27ad4a2554c43b66f4ccc55ec7683688e3689282924caebd9890459323563a05888b48569bbffa223efea27c86aaf27263251a9b3b7e00cfc0b1d05d448e291731bd81fd8d2b474d4c325a7a55e7965e514abeb5c9823e53dd55031298978972c4a6f8a4894d19848b39b08a02f89159944fa1982a37ce3c41946f5b907829b3db320a22921a582a94163b3e66b462e628228d82a9e167368358eb4642afe14a6c5870ed36c36b7ea7fc624698cf4c84e725b58841a40d581bb8601273756aae8cd6aab475df08a740a725e37cef92751c515715480cf1a3a52a7173754710b2b990d618b8eb2f532e7d37709ecaca551bd6b556afa1545ac685dd4003e16b016811138f4e280f76303defa440d395559a13ab68b1b6d26c75ee4865238192c24ab52a1c15f2a538a240f9b75cc6dc45b10272ce8048584085f4da6c1e182167eb9c419a1a0891a809f3b0ac8247dbda3b4503248ed4535b77bc7abb44706e12b0493962b302b48023932f18c918451528a81a1c0cf6f5731b8c0680ed257432a4c319007be80a2087c64a3821a8ae08e9012be3d1cb62d229130e41e6d452493035dd5a49b91781f47db395e5bc663603af7accbdaba6473f56c07a763bf9730d18cce1da3968ad114cb831d083a5cf921897325877adb656a483cdb601f2d3ac36a49b3e591379a22063403c97f82aa50c761ed1a289fda7a3d4c2ac67b1ae5b73e5a2bcfc220ced032be54313bd2c15f685c5218113fb822aaf2126cae6904dbc16864223f8ec630debb1ec282ae2eab41941a8914738974652b10690860f3228053844582a35bf46bac784f3161220cd86c1477bab6786f557b7033a8b2d17c30e403879ed87c74ac1b33276246555dd05a30e68495e14ac94844c1d9a350c703378cd92d8fd15cc97a95c45096f0da917353993d3a634cc32fa84428be02448645843c012bb648cb4ff690aee824f3cc18ce8426f28b889767b91e8b0aa25566ad06a44a2263e1d8ca7c315ee873ca0e85cba540751629b8f75c1b661c369424a51db3b15ad12daa501f0fb37ce9404fc8738bd0cbbf7d0405aac3c76014996641bc92a527952bc9f8d839a4f8152725088ea7780f7982c8cbc5509636ede17a315843f4d0220305c3f0c86fa573ccf26cbb83597e0a8320dbf61cccf073949a6851d3c41ce485e71465e232a752c4925ab6a55f309d77c20054a8789c98bd72c42d99093a5b894b6fb73af0d32475334929a08703ec84914404d65b3fd150bd07012854b43df16133ea560ecdb662fe630c910c3781dcbe4d4465e1d828411c8e965cbc046b0d8f87a3832a2adcf73f33e09b5754bd7db90e09900937d228bf0966b1e385d2c98aca792ad384240aa570a4826b4d95423ac49e84a02b5bfb299cf024bf133d7e7cb7ba20bc9ff7025a74ca6459697130a2f088472ffb3fe4e5c965d156e191ba76e7b47eb75038785a641129bef51a9517773842a324dc575171023b76c3b2570475b2a468ba49d1273bb0db29a22284e875bbf69b5d8d08a01a532316a010afe992724c6eb524250f72a76c131d7874b21367ccb294447c317ea3898a4c8bc5e20776d97b9b84946757067280fb4f546356656453e9079c3e8595345a804a641bcba4cfb2089235b29a7cd778c5c534cfb4c77e87ad13bbbc3be133f05656db82924198bd3de4a398944cb3313acb360004445f0dc7a5714868a02204a2668c7fa5023639699220bd85cc2bdf2164ac94084e389062652ea26cc7316c6b9b02b639bb630c6293cd45930f299180ec1549813c411133e9252e83eb22c899c7f4083ca3939c6acbb9d06943a55ab638e82505ab2b8d0487495b767c3c4c97777792179ab3e5a180506cae4b1ddd655e217d7548550000000000000000000000000000000000000000000000000000004e5fcda3a1db9c471972338dabe86a538d2ac2f19d473976beca80d378ceb5ccd48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 1b251f08fdc6eb19ddd0c8d5d5e2da90f71d12944ed19ff97c654376a8eed0936b0316cc3280dbde787ce827ca3b5fcff90a6ad6f99a6060f9e75b1ed6a73151035954efefbd9eab3eaf34e4c4b2ad85ff8a7707330bad673cd5d1af192dc83205473d9b29d817c8fa4630de8b7aea95fb8765429303a6b9105e834121af1cf47d388ad800b33a03f81c41c7bdd42e61a34df294e14623511a59768c8c9184dc0f61fca7433cce1bb7eaa49921d6c840bf607e5c12cc1dc9b93df5fb31494e1a4ea51d4c289641289ef01137d5a4edd272f48038903037dd58dbc9981d6427777037c376559ced6accceb8d6bea9451ef77c1b33238a7863b4467a9be4e54701b642584c3475d6379d5c875d0428c7c918e1ee3bde7e6659596ac6eb1afef9dc53d3020406ce66d52c486633e3f1ee359a6c68f77fb9df77e503b6de14e9e75535129dffe8c83187269b31cf5cbd1e83fd1a678de5d8a717dffcb1ed6fd1dc45b7bde30da96a9a6a4ba2135c51f77e7a2ad347f9af899cc91c45afb2037f55665d4fe185dbfa0af29edd12c984f9eb9ffa4498ac01ae6c9dc276e7369887f957d5ec185ddcb2294204a8abb1897b44466856225f7cd987183d87a4b04f54464586332faf53b85cfb37eb7bb95aa31748f6db76357e31354b866932c8bb5e0a1bb5fbe9a824018aee574722afe77e5ce3b9bc7c98c42d132c1a7419f438338047245ff478c2b91755e989f3c5bf653f94c15d1956a67022cb6122317c88b26b86ca91aaf1c10570df2572cc8f3dccfbb23a3f48d8f8355ee387c314dbde8d13ff26a00df51dc3ce52561ebfd9547adf7f0f249db13b509dd06ff1ede748a4b1a704cd9597279339158307e7304852a91e1a043ced0967a9e1359e65e4f5abd6bff0304a14a182d472c7ac5000b14d27206a9bb74388e95f8c5e6827d268c38722611308496aacf723921217ffc4978e4498b818ea010b9836f9b275ae71335bfc95328a8e02fd281b8d797c29ad6e6c84387f18f7d8345876c5f4e93d33f617c87db2036b2f55f9d46d9e4d55eebbe3657461a14e159dead4ed3dd21da8da4bd0 +expected_result = pass +expected_shared_secret = 4457f4dfec136705b3f85a0ed291390fe059fd12b007cecbe708efe7930631b5 + +comment = Rho leads to a matrix with unusally large entries +private_key = 2bca01078898594b8eae01aabadb52a8812e73d00cc5f4a63c8298a049b146d4257d01c2609b673c256342b21e3dc75644880989415099e10d00754bc9a68371f30d0b5c07ee46259df9a4942c0483705f8468591ca1c6f6d8b83c49be1ce859b2c16ec5dcbdf74895ba7c6b2613709522605a439ba87aae32262695a48f48b43bb5db3fdc259bf5755114d04802734013042ccb8502e4f36aa832164f612ef7886a4fa4a271b114e17b700711b385b7c2abab0d5535128e0c4db8d934e3126e7b35c8b253204df1ca27a5ba991a5d8eb30c09b17a54d672a1e266f6b3460b015fa00aca92162b85f8cf7972a7f6b1a5950280f920903c1c86a97428e3d5b5b2974fa0d22c730308aea2439043646b44ac771c3818bc5537e304de3143d7554b0e464b21ba5cef60023ab18e58442fba49a0c013a5c3a067feb8111f835a28fb3d99384a72f538dcab39eafa67fde22352c542678b3191c53103f399bb0348379c5d3f814405639a8da76b165c39c0784a61ebb997048222b8856ab6a0c71b94c6911475e9426f97b045871571c87ea549707adc2e23a09bb676bed71caf2ce511510b3a10197878fa0c7960a233536e3f724098349a8649bceb09afb8c2bf6ed34633ea6d2451161b76adcdf14a479845c1639336cab5fbb5cf2db5a94e7a7a0034b7325601610386e3078e26129eddac40e9087140d29b7e10c0d3b0322507c07a753d8511af66e43aa1c82ae152351f35061ec76a8c5701870639d138182740cbb17150495ba6984180bfa113175747d9d897479c50ce3328a5355a98136de4e61ea55a144107a397cc798ee99fcbb31fdc222e60bc05616c5009d3cef1f89e8f32a78b22c7412633c4aa309a70492e97c1d8642f01185d15400a4778854abba1f703c2fcd0c7cd5b5326fa9775f39ba62c171525171fb084b6d73d9603c26802cfda46cba85a4bfc7503e06562cc48aedd0b5f2880820209cab73b8194c4106cac8e93c845f9b698aa8351722bb46fa205c4509f726c19b01c49269268a6dc25fe9a59ce21cd5c0caa5be2c76098b5b0a5ac2b185a32f18be4d1a77f06785667878d538c66726d8c174c4a41cc96713830c14bcc072f1af31cdaa7bee82a49a95cc664465b9c059ef7174e99ab696eab718dc78644a3119b81b1ca59bb17754dd91ab874b7038889239ac236f5990113d5495d7673f895216c6b5cc5b55a4e66ce4969504f089d9a5226d89a867061c110a6cb50e66189212d4fd873c0d8cce927941051ab228797cb8b8be5947ec258b7e9150660e7474c71cb73118c4b8a2f327775b9e64b53684a081710fc71b08d306a3e75b72ea0801940c9c225a6e801bb5f3115b9228086f582ef1784475a87cec793f19a729d544d7321222f3384a2d28ff303c62b1560c0c7be39d3adc385377fda9bced80a0780342528622b31371a7a2963ba6df80776409662e33a54ef12a2c459256622257a0a0c5422af4a512037091386b11cba375489766e045a4c23674b658614f9fc77ac0c4a17f84256b60df23a1da916245a0499841b12f0a32a65929988d42cdff22559182134d0c91b199714d73e1244445414801458ccf39040d9bb069f668209d0669eb0c43c5cafb7c34bf3441eac95ce42abc1e7ab3e1231ccf614b7f01119151a91bdc66a52d81134d151be429aea190b96b2cc0af59c6621206eb2955042581941b262288728a3339b1738024b4ce6802e7f984ac438a580267115bc3be0c0389ea00408d13a41c70017e506b0acbb79e64946b9080e835117b49a338ca6ea26bcff6468115bb087e772f690acbf3a4a591357bfc33198b247d116b0ec2003b1393a30f0c28a071278eb4a09bbcfb2bbaea7b7ae900471232c9de63c3f075b0727dca4022592c79793d79a92cf94bb59735bf0146bd8770690408a27645829d70038b16c835b4a775852bc699c5a566418d2368ad82c2d931a04eb39dd79c465b7c2d7ba39f27cacfb44c20d082f2b65b27660560442529604c281ec9f078c25adc15c2a2b9930a21d55c75aae5051d4309257e73def8b434bac47e18028e9e091b3c64b4402a6cdb37a4740a528fc42727025b782c29aa08e9fe22185620c53ca70ccac11f0a036ff0a9eaf7253bda1c01950172ebb77d374599d93b89d3a76eb7298c44816b4e1000000000000000000000000000000000000000000000000000000671c9f4bb90072db7281014695f5ea79e5ea02b582663bf4aa44ab2766df1955a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = c7eb8c4235458a2770e15aacd157db4c09ec8e22442d63513b0c4e519f393f14c9624f293a363fe0562bf5cac85b6b7f0e0e459a32715e72cf58df8893426b233694344872d51f97f7d08542e084f911e6e56f49661f00243420ab5df1b64fdc4cbce946ef58d97b2a44cba85dc3bb6cc90243996561e2ce1c490d01f2fb539925ccce4e81cd3b7f24e0c9ccb406d1715e10e524006d95ab3752562f39a299067bd5581431410e710c5898d52507cd0e9051604aa269f512d4a51efa5fb6d662901f7f5dbebbe8e1d48820c05eeab0b94f19cd28ce0082c42dbbad01ffdc38443890309fbdc22b16c4ee3461f8b4eab6dd36b51392c059debf48103eacad7638cc43c1d6ad333b8ab958f026e914a662db9af9dd1dbb20371f83a660f17e81d52290a449a572fe4de555e8021516b6c9d95725712b867556d474e3832cb24dfe3ad74417190f6346bb3e7115365c3d4bcaac876dc785da3422501e1c45706ff231df10be24e5f55d3d2da1508cb34200d017e562c20aad2d1833356a9f76966a679309dd8de635ef9d11d35eb862c4efe547a667bd6a1edd5f895f63912fca65d6ef897d550d698506cba198cdef1766eebe08c8ee29085ed92f75ed9141c6d2e188e76196971dca72f4d901e50c7daa88b343b7c5ddd3d78e446cf2ffd2ab84fe79ec9883078689d6c0d2ceec4023b7b921219e291a6560214b477e1644eedaf8a0ba89f3b0750d1df45f3627b7786d988cd862b50cdc93af2283e3aeff87ed7b7e258a76d0fcc3b86ce94a90d0e1a5192d01a9e450d1971548144e0537e4dc8523ea2abb9dad00765b0e402d9a558bf1b15bf42146246f930d241bb32bf6ad281126fed40c6a7caea50ee7302b739604d6fbf08919cec975b94eb4e54359bb0b7c1374b8563200b49fe6cb856b1111bd681f31ababbf18164ca4998b16c7649ef92a0a8a47fa89fa92256342a517b3fac6b59d89d7b91baf8d503ec6cb876e0011eed47dbb0ce4c9ce13a4135c10d280d7a67c151a2f9994429f44208ea54a14070b7834241555b35a706db557c42452df918c3d9aa2d412d8b8ef6d766e7d +expected_result = pass +expected_shared_secret = 2720f0bac612a277330b98b0a4633be90f0b0519c8190e387ffb8c602ba6b6e0 + +comment = Rho leads to a matrix with unusally large entries +private_key = 5e26b7850013f01c602f7c46920760ae15bea4b99a815252ae285dc4009530fa45b8a9518e7b6466ebb8bc624efaaa49a2e99930c760cfe3c7fa4368bdc157ded5ca95652a35200490b60f83eb01cf5158d44869cc50b34cc5514ba1189cc75800d19a1dac261f02905c548d91d283e9b2b47948afc9e0230ffab66276317fcb5f30947186219add4a43132590ecfc94b534432047c446823ddbf9caeb57b277ec090c64766c54836bc58bc8497673cbb8cc1637722978c98c9e9c4b0d332498541c86c9161d5b608cf83b25e3604a13f2071cf73ae94b465bf71589307c010ca5def4b5574327e22722f32a73853cab34a2b36711136b6cb4f69390d5759d33a5629b772b3ef73a382357d4d46f3db5aa29708ac6760d33352466164f4a2291bfa04d51866bfec806c268148de4b909403aa94962c2210f992ba4e68b95f8694b08aa0e3bea88158a44d70b55e6175c32893d1ff72714e3460b863f1b9a2afd50b991a540c1a94047c030b58a11b38b80f5596d21c6911c379f63b46c2d705219277bc5139c45165ac54c28d5ba9fc736ca7966aa842317c1c944ef86800743b53c87433b9c1c426a33983b15b9a1242c17947c0358b8f40fb1609f8c764618834f709b9bfb812207d456ae239fcb8a5107a375fba0669dd8254bbaa9221594e8469912f99da8ca1dbfe337d9e26343b17176128dc70954af1745dd200f9e72b2441557619233e1442147d7710530bb4d51a4baf7a3f1672af0641c3b1b67719929a0b82e34b96254e50d97d125b76815d2bb28e088c5e5b31f162467e284aa8f13b165bb66ad19ce3e6877a477219af8121d3501a89bb1b8daaf4856088f2826947c55887339aafc829a4866e34706bae16df2a6c13aeaa4a3b252b226ccb02919a7cb3229943105506c93c97027642531689236842d2cf059415a87698c02162c37848043df81a2810b75e302772d2a7d073409a7a14e9ce59063367e34f4a78f9a8b9b404a7b6a6eecf110da12b469045dcda4625f5961ce6c52a7853540cc9d5721271ce3cf1b90b1d550107231ad3518243eb96410e5513d4c0362a84bcca86fca023c46d54cb8883eacc247d96cb06ef01b246b86c0711f0be3b218751adea46e7bc01555e21136a10cbe872de0540ebb09306cd71c5084612e733f14e0aa5ca67c79a7c30d047902957fc723694f24c66389735cf2cb69a09066b86b1b6c01a88b0a9efc17351a678d06b8987aa54a85a2f2e39ade850c5598898ffb88ee1320998c07619b94ed7cbb896b97c2cb51010c6b91cc54886b5135db4b368a61acb2b415e0b408a010b331c55a6907bc3cce8248aa19501e8ae98526940b26a67d70843fbfc06eb92a817c4a0fbf808839404eed8848e79983d2616ddb52974f21607f6a74bcac68c899534a951865123555150564488887877edf5b1bdd6949d76a6e28812d3a61b0b8160da3a49d67b889e884033419192b6435e79025bd7527e2ea1f6707bfe8683411e6b67a24c69b09297ac24b7348650f8537bf150781259c8e925028f0ace02627ab741aec9a2cf1c5cdaa963f0703184447019b68396ee6646417a600335a4544030cf93148a4b9f7128ff072adf2a71f33e8481a07353a51075030bb7a191be89855bafccdb79c0139260b8d5588a79927ff2a2f67b52e8840a138a95ed52aaf5b61125b60202c082e78598d328b607a9b067f26355df800b0e50e70844426680b69a0c52495c6f558a23fbba14e3b821f6abf80dbacefb53f8fcc613da12f0a352ea0d16a77108ca8b93dda7549612836fb65799cf7c02ed49d90a8baa6538db4c787079177d4c5a2b765c95ffbba6770710b30aa9e2c1be803962f07ca0ce8c8f9d3cf4956b7c736c103fa426dbc17d958a7a25ac70d092ed49483555886e78a3af6b363f41122acb472ebc854e8021ad22c93133cbe058b249c581be6b9c2f8c1173741809dcb748d5b85199a81b8287861d29b13237eff3b1a020bc49a6258c7745c237915d5738247c38d81d6c08bb5c74701660e012b822c3639eb79a5409505d454af748ed767b147940e9c00a2ef5057f8308dbbf060659708f8b1aa9e2778b3a62222f54b6c966048aac74dd514f5c663d0ec05adb99c4a9c5093893384648d21fc92831151accc7850a85b7cd9ada62082f802000000000000000000000000000000000000000000000000000000af61f5f158d0016664f402c91a5df8a25286aff9c284d0ddd9ab1bad3bb6402453f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 51ffbe754500d132a6f0a749236c4ce530ac27606e6a9ddcb0e311f15f436aa79ad04c65d93ed41b39b1b179281aa42aa7100829e7d3c28e0906423e24611945737bca6d767c0e263f8e38698903eee5c197928cc958bf5aae01c6437836e393eb5c29ba869a6fd2374395e8848e75f279d650c10f6e4175ed2d05b73bb37f3d92026e3511dc7d48d8207e4fdc5fdbafdeffa402ccbfcb893f765674b35bde9073b3e508a9ecaecb51e8f0359d2ba50d65893bca9030261a7543f906478760d66e8d8da154b13e14cdc172405d83be4e0f3d24caaf1bffa5841b4c995d47d47c5a28e17ea38d5d036fa6af131926c529db5497082a57b0345d34226ed602a036b8137c470e741710cabaa4e82c35609d030a6d492a3d5b940ef20ee6439376838256f19cda424d7d3e45c8fc7f5d6a78bbbfa2cbcdc8a09efbb9600f26b8be281ee8382a355842e9791fefec1abbf4019e1d31db30b3313ba76c3a0791417739021a8048a98ceaf8bff65b494dd4b81b0d80f25c3f3c5265929d1d5b6fa3cceb46983dae0af05a4c9c2f0937e37eebc91d39ff6da03e080ee0afdca14c85938837e97b182e6ce1bb504fdb83e2ac5f109c2a66448a47c12f9a72498b83499eb7ddf9064146dade1683e814cd41393a64ea066c3bfad7f59d0620e1afef3093c677b1c8dedf8c81273bb581825991b6f282995084b43dfde8ed46187762fee9804463a0ec8c633b68fe0575fc414c85cb99148753a97e7331f10b57768ca3532c3e87d79848cbcc28126f540e3e0d4c18550a34f3dbe1884b4c70d0df97a80d32cbdcea569cc9f4f80b469e5a6bc5d562ee81e95a794dc1ee1c61d51516b4fa905806b4f0d49996e10ab9e226996122f065997c1b4887da7b19b002afad0455de6614a43c049a6df10f2a2549363a791721c95f1c4311babd5b1cf69c8d1cbbd95e8bf056f4424a0877303391a1c17f4e56d8ee0840bcb6ce832e449f9f1580f1485bd5b746cf18635dcc1e0ebc6f416511fa77f4988088781b40a77178ebb2c93b9f213c671c9727a81d1ac6afde0fd09d8618a5f157980e1e49ad44ec0e2686 +expected_result = pass +expected_shared_secret = dd5b87482f6e9fe2922cf3c75430986960650011b03b94d331edfa6d4b249f92 + +comment = Rho leads to a matrix with unusally large entries +private_key = 8ca008eacb7a33b54ca796b5a0642c46e86b3e1324a9740e89d619259a29141ca64e7a06a7bc5e609047461c825bc55475cc983eea8882ccc07825258fa8c581bb2df3616d5d7505543017afd693a8ec808942318bdacc6b5b8b6a859bdc41697816c633575fd3201a301398b128597ea731a8fbb4e57898c5a18fd59ca657c0a68ed7184c58a5f420b88c0c514482ccde3a93f0c93781f14154fccacc50853a15b249088658198faf7470d778b4a8d1ad3b69c3bda9448335ca6cd207f8f6a3d0b762521686855a76d639401b076620cb1e90438ff056c857291367ca5e36d581d9fab56dc3a875813ff348c17ea77e1422b8adfbb9722bbaa9fc140b950db8a040cc9c2469746b00c72330949db387593d494ff1a964e944af6df216bf07aa30d1c87383949b7537ad6b37c0c93bd24a7c2244b3e360057ff03083cac909f54decdc5a729a8743017c55c803f90934bfd1bbc2f18a35310b5343c456b5590fa270367429f590908dd9bdf422758c480e89018e86c39493f2991c17756da60587d05d7b11b5a5f34b2e649d1b18b5ea25692c362f6e369535f943314bcb555895254b47c470ba79031f0c4139f0689ac37670fd497dc01609dd94c6a8d85aa102c92e9a020e9b96f696bfba677a02483be923a2ceec6a75b01d49ecc09b2ccc5573cc7cc2747be9864015b972987e024a5b0aaac78b1119b7ac08b33a2e006227f6036957fa4a03c4a995444215985a7c6147175132f2e6927b85568ed151b0f516b9672cb2a84860b86d02ac0858586456c82ca3068cc8d1a6d15c6142c94a89097dd3d5bff4d616adf02bcf6153de17a22b32880c2827cfea9fb1fc690cf441b7ec9375c6c249f57896c00d7f419265c87e9a99b3148b51fc9c3b9cf85d884376a61674fd89a2aac37119041dde630a873a5fe6075b59bb00dc667d8862539e89944c5a58c4983bac248b3bd19c9690872ff62170aa198f27a2a950a80ea232bb39c47180701a6362d6ea3a96e284f56c25f29566b2816a40096a65c97ecbda3a96224d5145c1d1b3001a26b484a584c5251dbe8695ea64154a5223ef025722e762e6d77baca48b4e27c69245c908a95508f032a0e57f2cb82542e8c4629cc856318c12a402da979de1e1b85136c4a8e897124837add5aa7ee5c35104243f0b154294440d73cccd3a0aef77a548291501c5628322163139be5bb58b438ab9f1136095c1359eab171e783b7227ceab75703ab6b77b0c2621ab49e3c741a2260b0d86021146b88564c8d723cf4f0cb62a674a79ca013905abfa8884b4b37b32b20940c07e513b5c419897d2b33e2a85311df827e9272032a930d8f49a4cc2b80d6367d1ba456a25ab0f774646d0273855c9fb106cf5292042619a4ef2462ee88ae7e5764d36c3da25366d30840476845f82378465bef5b980110a1ce913bc1703121c036b0a6523214c91c337736497b806ec97a2c87756418c38e2803f4835cf632cb08ca8e2ec000b89095b80941dca287e3c703125356b9b2d06c135c6218548cb49c91863d00269738126a6ca44238c39ce48b5990b5aaeec611f768b3c2a544f6a502e69ca73ea2e91c73fbe147762b87dc4446a74723350f1b3feac73cc076216f50b26b7b2eff79edf2430dea28f96871247804155b65935c476c69173c0ba154d7519dae450bd0164e7ac79878712687aa100c71399675e1a4649df88c442c247964b6789ea1be66c7e0a91c9a6066308475432ba697c3a0af47680ab917f3da0311b976ce6b921b62b68a201986b801e03ba85a1a5a0ba567124a84c07c12878bbbda9b562c2a187771559d7aa7b4bda7aecb4c685126b1b343a658416608b6ae4e331b8bc84d4fcb6115204ba1c76f376bd6f5c1c7b9503817758e0a5955775823564cf2a078df488996e364136ca2a9a7b0c6ec1bf57082d60c56e3067b0eb100aee060d70e08201931405c089249487ab749b88290a2beb6632bc5f7390649c4a9be7441a49287f8e4c22c6bc03c5b788c7a0807f1b39b8e6514b8047925b459e2ccc11d1a1bdc29f928c5fbcd8b58f2b6e34b6091500c4dd4979f640c50df0390f2c0da32c1e8fb63f2fb3439ea2b35754559b0a7554e15d2dfc123763213a3b0b40b87362203172519a81b9351b07bcdcd56080fa07714a700658a253680000000000000000000000000000000000000000000000000000005731e949dea008624c8fe87b29e06125cd3da524587dff3593abe3f98169eb9ce366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = ac7ba64dac025d715e62ce9cc4b950a543bda498f9ec1746756aa80c5343fe95673f30c441d240c52834dd8312fbc7745261d61937945c7c581580a12a270b6baafd1df41f8e7e85e2045c7166f39336cbe3c9b51bbf3727de33d5442ceaa6dc479cbcfbd1423ec3974988990e6690940580f93a549f65081c9edcc38d437b775a88dd9899d4fe880975277a4dd2a3f91f4be393f1e259f52cfeabb8ca43a0c89854f2ebe52b2f34102b70194aa01aefbb14c06658ba9c134761df71387abe12bbdcc42f68a0e9389ae9fa8d0776c2a8b4866f0dd37836494f27c0651b2e1388bae97068e1407d4a408b1ffda1e2159c15fc22b6347f6e6b293bd88145c88d17fac0a17c71babca924c994576b0bb86c2e83678759f6e29180204e1c9e167934d459bd5eb3109c4ab027e86150fb0144764fc371c93ee3d2816354e670141065f6a11909a8652ae0b866ee2068cd6846e4a3c99a1de553e36a6d7a38724495dd0ca5d9a1714fbd63f9b11026b81b90bb41b65fbd40370162f0b7f41e11a64f5e188c8e380579556009fd18372010afa3d4e95d8df4dd3d8d86db67639869757ec9ce2339b0df95988bd57df993e027316471a9e037e2824439a524a2f377c6a6cc7336b2f672a78c7d7b26996cd445476b49eea2ffbb7060eaf3c2e5f1ff08a9add038645820ef8eaf436f949113bcbc0700883d5a331f45387b1e6a7e180021a269ff29d9f13133b05517a65b7fe32cad23cae9dc5698e0d23cacffa357faf659cfc8afd4c5417c9ecab5c44ae08d416d57904c1f60801a15fe47cdc727f03952940adbe55a222c19f458913143c3ebe91090df3cc57d31f8c57c1cc8bdeb79792f32eae17da2a08df08fc0acdc4ef12d0ef04dba38833d7116280cd2b19923cb2cc4a3343f3307af7af5d32f3ba62e8e7ed833363df1ed94b27c3b08d4efaf5b394bdeb417aac35c05fae6104b07f804761916d3bd0a8e546466ee22045f84da4d9029212df2ef8486c8480948c7cd49224ad5d553f17b30cbff4ddbf3d8d8d3222cb9043767c4ca794bf9bd85ecf3761325d8d1b83df43d40b6b695aa9d4a +expected_result = pass +expected_shared_secret = fe359fbf7609e7ac0206c4f8b273cd89e699c0f3824d86b2df5e24a6fb2172f5 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/decaps768draft b/libcrux-kem/tests/kats/wycheproof_early/decaps768draft new file mode 100644 index 000000000..20c37ad8b --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/decaps768draft @@ -0,0 +1,1830 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +private_key = 07638fb69868f3d320e5862bd96933feb311b362093c9b5d50170bced43f1b536d9a204bb1f22695950ba1f2a9e8eb828b284488760b3fc84faba04275d5628e39c5b2471374283c503299c0ab49b66b8bbb56a4186624f919a2ba59bb08d8551880c2befc4f87f25f59ab587a79c327d792d54c974a69262ff8a78938289e9a87b688b083e0595fe218b6bb1505941ce2e81a5a64c5aac60417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3683c0b7b10029fc203418537e7466ba6385a8ff301ee12708f82aaa1e380fc7a88f8f205ab7e88d7e95952a55ba20d09b79a47141d62bf6eb7dd307b08eca13a5bc5f6b68581c6865b27bbcddab142f4b2cbff488c8a22705faa98a2b9eea3530c76662335cc7ea3a00777725ebcccd2a4636b2d9122ff3ab77123ce0883c1911115e50c9e8a94194e48dd0d09cffb3adcd2c1e92430903d07adbf00532031575aa7f9e7b5a1f3362dec936d4043c05f2476c07578bc9cbaf2ab4e382727ad41686a96b2548820bb03b32f11b2811ad62f489e951632aba0d1df89680cc8a8b53b481d92a68d70b4ea1c3a6a561c0692882b5ca8cc942a8d495afcb06de89498fb935b775908fe7a03e324d54cc19d4e1aabd3593b38b19ee1388fe492b43127e5a504253786a0d69ad32601c28e2c88504a5ba599706023a61363e17c6b9bb59bdc697452cd059451983d738ca3fd034e3f5988854ca05031db09611498988197c6b30d258dfe26265541c89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9790a26d17b0398a26767350909f84d57b6694df830664ca8b3c3c03ed2ae67b89006868a68527ccd666459ab7f056671000c6164d3a7f266a14d97cbd7004d6c92caca770b844a4fa9b182e7b18ca885082ac5646fcb4a14e1685feb0c9ce3372ab95365c04fd83084f80a23ff10a05bf15f7fa5acc6c0cb462c33ca524fa6b8bb359043ba68609eaa2536e81d08463b19653b5435ba946c9addeb202b04b031cc960dcc12e4518d428b32b257a4fc7313d3a7980d80082e934f9d95c32b0a0191a23604384dd9e079bbbaa266d14c3f756b9f2133107433a4e83fa7187282a809203a4faf841851833d121ac383843a5e55bc2381425e16c7db4cc9ab5c1b0d91a47e2b8de0e582c86b6b0d907bb360b97f40ab5d038f6b75c814b27d9b968d419832bc8c2bee605ef6e5059d33100d90485d378450014221736c07407cac260408aa64926619788b8601c2a752d1a6cbf820d7c7a04716203225b3895b9342d147a8185cfc1bb65ba06b4142339903c0ac4651385b45d98a8b19d28cd6bab088787f7ee1b12461766b43cbccb96434427d93c065550688f6948ed1b5475a425f1b85209d061c08b56c1cc069f6c0a7c6f29358cab911087732a649d27c9b98f9a48879387d9b00c25959a71654d6f6a946164513e47a75d005986c2363c09f6b537eca78b9303a5fa457608a586a653a347db04dfcc19175b3a301172536062a658a95277570c8852ca8973f4ae123a334047dd711c8927a634a03388a527b034bf7a8170fa702c1f7c23ec32d18a2374890be9c787a9409c82d192c4bb705a2f996ce405da72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee868626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = a413be81047259202401ee35989d25a3856cd1c0260ce2391de323736b678f328005c821ad092180b4496f2129280f4f299404362b9d141948b6bb02acd5736559fc9039018c961dddd94ee559198471d4a049e547b5636cf8bbf7db1a90c72b870923dcd54b148c60c9c8ee604d30eebb6901e6df2596121826058d25029ae399c95f6aacbaafe34f118ddba7a69d7cd899b5f4d58d3df2a889b030ce9a7ea6446d41a60a175f127da94c276baa1edfb357d41b2857ad462c83d8ff00236d9bac59325e0c3bddcb37bfe0fda4e167fcf6aec149fe5f9f6393fc4715c6995d67f2b4ddb0c7678ee140bcfdd2365e8122ca92cbba1ac703357edf15210c6892669f1a2b88d792be7d9aa56c5e8df758abb4bbae83141d2759dfc4ea8f2cf00dd86a7312fbaea9cfe6d7fd3f13fc8cb75d252cb3ec7e7b37cd81d88f38ae593ede6f8a81d51183d7dc7f57abb21ce2c593db72f0bf779cccc82420f53c2fe364b1fd3cd2ec54b924a62afa4c3195578e48aa5f507e7928d7527d6577d3fca87e7b7b19a89f69f0018eeb36871baadfcc7094e344fb36481fb14a5c53c30867cf1c5c02cf6227f9aae8d8a12b24c5ac2b8eb912b87de8325409e440a47b5c74237179a6ce5558ee09101ca4e645e24bdc28778735abf98b0688f6289d503251582aab6e81ced0179829f7311731d0615d0a0d955978aafbf8aa440a5c85870c58b3e5c1ff9267f094b742f516e8e9759d0f88021d99a7fd65bbee801217276656d21f3734de0a5589b33fe996ecb99c0d8a52d54b39dcfe707fc11e35638a69d908ccb0edacfb2aa435e3beb981d3fdef59cade6f63cda056c526cdc55b87a3ef2638bcaeedf406711053a09d310699dc8e3d07acc10e1ea8ec8d51ab31c04ca88c2177a51193b418ccc4b2548ecda861598ffaa8b16eaf89d59c8403c39c8d94c428cf19180e1420287b455fb6e4e5bfbd383aef18ca99f810f6cea703be4b9bf0cb6f0c5383e83ed3a723a27d8e3991067656726925b20fb735b12752facf684e5c03dc5be7a63af4bd930754fdb5f749306c2cfa6e398925c346d9d572924b153b7673b7a5022140264fd5a0abe00b5d85c686f296fbc49dd3155ad2f748255506909b355c7060dded4dd2fa21c7bf681251e7d63289e15f85854a25b4fb085ef03a03cd050f4f5021d112f3291a9fd60ad01e0b5797e78d9b94befe9746d754e6ce41da34c57da3d7deda6b233082c4137614e964fff0e38472e36e495f54e2d2371a7581b694cb263ddf80bdd43f6383578b5e18244a69cac9cdabea3d05718f5c23b1d4ce6684457597d01284b38b9d3eb1eba4f5beff990bb749f096a30f1bde724ade3789de5ef183a60163e28f1584500984ca5153555c38c61649683a727921ffcce3007c267783bddbdb9de48880c4e8452dab29e7c4f8d1d5dfd303a908b1ce08be0b9fae98894dcb2692d0b32fa39da98bd4ff0ea10f0b438a4971a7fc47182fbe52d6de71fee3e824a39f19c27f51aec6d92bc7f8b8f071847bca +expected_result = pass +expected_shared_secret = 729fa06ac93c5efdfbf1272a96cef167a393947ab7dc2d11ed7de8ac3c947fa8 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +private_key = 94b49ea42526935245c45a7d580b6aeff8bbe0f5342bb8bd2550212ad5935f45cba7caa6df914007fba79e9946c9433a86a2c4202bbdcea008af78975e6619d3582787530dbb7318a530b7b5a27d24258c7ccaaaf505ca92cb853a5818d4269be812becf169a05e71eb957557787c2f3b72315281dba87476b157a06095a30d52b388ac22840755b43440a931df8a709dc435b415a7babbb04ccd93cda00ca1fb090646b1d6514813368a794d38c907163b5917496b018c519b160c5144d6424495626e3a5ab9ffb8d8d3168d77599a88a1d12c07d86498d88dc1af7fa7de15073fd4b62801c1a902b215e7cc3eac350bb63adeaf9c7594844795a9a6274aa3eca0cd10891f05795a77b30add76b6b1a35338b8156690ca2ea1c9c3b602b23324925314f726535b36dfb355225d37e7c85be15a5976a8a6ad4e2c35d4c45acc954368ba6df88a47dbb8c782336f7ea507a6c2d26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b692729638af69b03e6db9b82e678a42969fbe770fef65723f77da6437c20b203601c884a9b9e08c0b1ddbbc1a66517dcfc76b3f125f7795e5ddabef0cb00119778575513e05ac38a7901a0e8c8794685c0f274050097bc50168818a74aba5d71980f5c76279ec0214cd51efa8a21391567fa052e6dc0cf9bf216cff9287c80693645a53d71b3d7509f6a432d51b2b0aad129b594278da74ffacbb713357d735a744b7c65e482b7e172c67a5b4edabaae11222b8bb6b4564ab4fb20c28b4981614b69bb188db6056607e089f64803d89210c7e604266b00548a2ae27996196a6d6f762c27b22731f7942543ccef3856edf9ad1b1b1652a33c3e038dd9b2cd9a4612ce174315e67b26dac767e50e68508d104bbae1a2b89b78266d27b109f90bce1581a8b8888c90c1c4ea5fc1f009d5073780cb4545087c88026b9b9abddab923db52620713c8b5ac3301e8715ac39d13084926e841fae41a7bbb7912e10680a78c0c363a251720b2d69467b6cac5d894f862595072a7c9b14bfefaa2fdcc75cc42892cec6184b52962b9b73d663b7d76c1ea499d538bb45a4caecee0c8eb93bba5ec1a8c936156382b10102e3211b2dc15663412805f60590ec33dbab80d2a3bc05fa8af5145644f712e004c20f799650159c40dc952c9a54c27e816c3a6a95efbab24a31f6c402300f9baf88a46644b4df8a24979e80dc30425b9e75a753a36510b87c5fa95cbf36e19a12245876003b54d4e008ef7ab9d83c5a2406014b5cc33b6167f4c452af45084b7412ec19556d82b0a6a90c1aea60a72312d8a7a8e5060189717094ff950af2b503988964f0aa227c523487471d3bc905b6672be20bc714729b7a71478b07a19f777dec546c624723af7b5f6c142274ac5652a7c2d7abbf1171f2bdb12f1ecc876681a600806d6fc229e6a8f6424419187bd22e49b8f27486db25371c169b3f61e81131b57659b1030a959790ba5d6424580b1f588326db9cd01a260b21b8c42062b883854fb173ea7613764d41dd6b89468c7ba6c4236d1a0436b945b8b340983023139293fc48c07659b955453bba07b0eb4e2a91f594232a47c65c66e1c5c8279f179925c55ee3a0b6dd406b49b9ca035467fd26c6c0b824bea310f435fbe8bbbd3430b5c39889e6b117e994e2f08823a33789ff858b72715323c6204a241d9835ec0da85c5884a8a96210219099c8c383c182632280356c1b4f298405258a170e81624e861fc1082d31867a9037e3b90b0aeeaa064d27020da7ba79398fa92a963a8a294e7720bd4cd9ea213f08063079c4d55b094bebc4e979444f462b967972e61206fcc80337911b02c7396bc64405ffc0b77cccd2ebc121a734037cb90b77846b2359c30a451beb20a6d72c238284e5df2ad1cc1a33fd5a104965c86251a596360d541240a4828231a827a0168b6d8ac7e27328173886453a9c91498765c2bd9ea9f666bb4a1d60f992538a1a746df845574f99adad23b9744afa81c7fb79a32b175706454438f46b8985132b8e1cca10c2b0fa011eab2428b88cfef9378a5228e55d7463dfa5022c998abd6354118b5116b3bc1004f0008134b85a1cf2a9f409a10e14b6d06c26d8e355864c35bc71b60d5cac33a513efdf6b9bb83bc880983682c8fb8a81b6927ca52e93835956795488181a8cd82b1a50dd18a25f35e2643cdd76c282e7018bb99624f031418fbc8052c4179b43a5998be9a20cd2d8a883b313ec282598202add6471971c88cd9607d3a8052519930bc5bc71ca4652352b4d02620b8d983b9849ce8b8935f1a4decc3250de7b0cfcb49eb7b74e0b5792ae97633b092081c3c6bf58f1b242ca07610c3387098ac3f0f9043901c614590c4ebbc64ce1971e824694a999cbcc430ae923a1432b6a4911162213c429481394a27006b9d48c0ab5801823d756bfd8c6919502d613594aec81f5669bd4e8495292606959292467ccac7f688333b3f48a39fce5c42c9c2653886a5adf4747cc943b2416348f46df5b58e4916ba64e9664a4baaa3e0a9652408c8e5076c226c3a7932c42a846949a2a26b4e2c452f86cacfe5c201ae1321ab5c2cabda557648a849241f077a799edba3582202cb27763047219f5546cf18819322b9c63974b322b949baa491d97c70f20545886c87086721d3ca2aeab441264b516975ed0c6044a425853528424532e4d721e85cb0bf65c26082c790765b062916fac4a0dcecbc2e900c6f600270838e2df20ee0a907e3613dcee049c445640362c980a292f123c6c9b5918f21443c996016c44d2a124c5925a8e0c48e89bb167a129fcbf67adb89903e1249f6028bc176bacc722366139858e583eb582ada714e79b5ad1bc1a6f18754e100624620968d0702e080befec425bc16b650a307802004c57590897c87e65347f32c324569051d798bebdb421eb28b2d1a0c662444c7db32bf97845d7225c7539f457894eb87606fa85b5e804053fb6ecdea773566c006e540ee65101d99bf314181d666680985c78b103dd00a040dc69cff389fea7c18e48a363b943ff042b476dc86be953a5925076cf749a62a77a9406165d31dacdc3a677b9114d8bf84b43f59f647fa4023535140fde04285921184809c5f193a7df45f62187854061a4d6754da528f3b71a134aa487d9b5f7cfc6838108b8b95b51f5540c9ea5f29990f7be07efd502461033f103723093a16dd96c098977f81330249183cf35a636841bd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d22cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = acddfedd604fdb81a6bb89518b9c4542ddfa46f4acf3a1ad092de5ece00c823b4938a85cd32b1c291ffc446adba2fbcd0078e9ad7dac7aa54d9d38d1603a0707e9bd77fe2a41e2d35fdf5d1c3b7a9c4a1a91a1d6b96db95e11df77af9ad3511abc41a8f84cd1e8afe8b6d5bf43a912c3ae871cce1ad968f2736dc856208ed8802a42b164238e7529570be8a3b57954d9b6409727100153df71d3e405a633dac6668440919fdf6692e39505a7dac58268c2b9eaaa0dcdfaeb2ad38d7edc13617eff27e365ca2e015f17804ef7204158fda049ebef27cd80b4d03416cf0d34fd1298440c807079aeaaf86951dae492efcf43d9bf52afd9eb2e2fce0c644f4efa8c5e74f612537d809a64f68145df78d458908e0e8c8901e340e11fa5c0ce78cd7e2923a880f4f069934b7de2a6eb076045b7a3b43a5fbb9e56afe3de239fcff2eeea1d75e96c64779d9713d43de1efe523bbf450fa8236b9b57def1cc381a798b3b77ab02d8a3e944d388932eda80f5eb542b6e275d8c6cb92b31f8bfc0454643dcb9041e0069a0b8f6ac1c4600d4f15543fd5c25453ea1cd5a3cfc87bee71ae1a955a60087ba5db2773fda9c0acfcf22b2fb0804793add6d44413930eaf6f9b2d8c18433da6ce17f9f5352a9922741be5558c3d4eb57f9642f9774ad449de5d672226163174d82c5a00157f4b69d3d5ec3f1bd5586fdd9dd1c9f4e50cf4ab7d60201c7e13c5a3475f6ca877319a845a2f80459d7032b0388742e101c26f2831b7dfa78dca4f3b8a127cc956fc013dc068498901eec716d8f5d8cf943892c98bb435a0c3440512e10c3c6d65926549309e5a83b391b06b2b5e8f51353382527557507654dd895f0b83cee90de518228950d141b968c3e4ebe116905b3d233f8febaaa7e83170d50227ad35283dd31ebd69ceb7352e3351cec82285520ae8d56d6f597e52e360cd9586d99eb3bc1f2cdf1a1917924e58d2db1a813024cbf02f5d0a3458fa55617eefd30a5667c988984fc6e61849edb588dd66ce3be5a52e42abf0a53e93e0e0b92e178fcdc1d5a092f1d9dc9578f555a5286b112672ec8ff7a2aa7ffbf23ab5cc752a45e0ed056b3beb9711b28e415da7bb31fa2c9b5227d5bd30d56c910f58eec5946a15b6af1f69aa343070aa2aad6172a98875ea2f1b33ecacf8c477eaacf56231daba5e91a97f869e0b9f13ae213153e2933f10e55bbea8b8111fcdd68655ce09fd893862dd26e29cc24fede5dedb2cfa720f14fc739088ab28eda8c5b36ee7cc98d104ba6a463e8f6de7b906bfe165efc1fad56c499a64d923d20f49648323527dd6e172b34d79517baf2fbb975e4568c40ec4f19054721055fcb5255a7249c60528a816df084c6bdeb1986207aae2e6e2776bad47c31078891e2bd5a44495ffdd7d0a942879b33195fed959c30dc688666b718d6367867667260eb23229483123ebec5cd2d78e0f99572fd293d453f0691d1d72da92db5c84036e1a0bbfde755c9c1d18eb721856249db963ea546b4f2086f1f4f528c457 +expected_result = pass +expected_shared_secret = c00e4ede0a4fa212980e6736686bf73585a0adf8d38fec212c860a0d3d055d1c + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +private_key = 72408d44c2be6e83c803da2846d852dec1848ee41504b5c91f774f6e512b51f71dd1520203c486f63240bab4c1dbb212299753b8627f9bf2117cd6a83be4075a385782ab804a420972eb25bc553eb981aae7d7a715111338529f6116c10b10bbc20b31c3161d4bc1a5f050220b5584abd6a546ab51a9a10120ecc131220502697e9d61bdbad346fc43824135692204b49b5b377b870b7b28c86946077a215acaa11abd851eca479988bc69ccc9975eb42a33523c525434bc594217912123957dcdc18e410a6d6a811bed8a0b4135b56f4562f343aaec34396bb0556d7962679a76934b016b4b4bacc14650c55c3aec9bc2e85b548b5d3eb891b6596f0c44009bd0982d98bf81ac77c8da98264a719cd8568e48279df9c8e9552b94aa773b43a70742c75f041915752551347f00447d72d934bec553bf1014f4276015e0b4db77cdf8c546af05861804a5b7d92838744511ac6c8be55e883acb7775b98c4b4c9c8789aee317f8f02b4127a6ae879d02c13772a003928041c53351d8d70ce59b14cab5ca31d717f69129c8fabe46582ca5298ed156209c25bc57870eea34255ce1b4c426211f957d74876dec169c4c516c8716b3ddec6c3e610c31f0c52e13650f0b1c70124dee27111a76abef82c8fd3172d554121e6a87e9d3b58e11379cb812b7f4b95d46104934ce75c715771204d7c46aa9439836453bda709cef3bc1c9341994f25c48b5c80fcc8a67e316c431bd302b20904456b3283e9ba1bdde494ce9f8a3f0b432dca69d0ba9c43c703e1616272cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b7631822c529fa48835f8a08f322615e96b9087c71c9f262b68851f00486489d25c92221c2759c89440ce733614b8c7a06f26b374cb4f8a6a7d67da521eba7232c0a4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d09f212c9330c83990ab2db7095d708b6c3589bf929fea31534646537d2ab023887fc286f00f46f8a360476998e4fe7315f03c234929247bba2a05297a5e01aa9cc6158458e2302513274a2e3359d66126f5fd44d348ba2b634642ea26c6cb616f64a2d2c819abaa48bc565ca0ab67e6cfab1129a0144c10a003b44bd3879b4e62e0ad3a58bd86a7030be34309f3309642b017b0aa03ffab4012b36adc49a95ddba67cd81306ef6bb20b546bcc55eac2b815fb38bae991d6ae7aa87d42ecbc740cc816a3ef42e9d204ca0177cdb30cdcb870386c320ff51b137578b029125ba518a5b887d7b9050dff113468608f6335ea81a59b87cb753724ed0e159fa4709ac018a31194247a6a9c65443a35ac36e11bfa6a8559cf20e50116ee5fb3780fa03dcaa77846b18c04894e50486acfc3b8feabb8cf860d79c2734a700ab731739244580653699b51b7fc440b8cb1d6bb1360291bda5b11aeda3c77a25b40f96763a372512561e0d52848fd6a3a8241dea49c4c24692cb43aa22067072fac2dff7898f298cbae17f9ca68a132321932295161a1f31c178932004d17854d7d9c69f6640ee216747102280191a5695433763b6cf3b86756aae22a37f9f6920c361c2ac68a7e11c8f5505af2100651595bff5a35b4ec7538b62289dd1204db91ac492b610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78a4149cf10b6d93283050167e737596b711a9f32a0f6909975055ce6632f4b42cf9a2361cf69047b5bde1868dd745a82cf473ebb30d86a71793364f70b1255b1c2003f166683c936a7977df156a84051e69b95e02616dd3090dd38086ef3bc12353bad25377618965c2810fca929dfbf46f20360fc847818cf90dbc044eed16b3b9052c5c70a5a430441e53a5527a689f49b35ce82b84d6057c5269fb60c710c5731f431a970b86431125910277fa7c310a2285117b47b95054e4174a1eb11da3e3c26ac25619d36712b11b2ef7405bcb943dba10d50c0436b50de5b04d96488a38f53df37895ac20c10d959d81a29fe1f319ff871831d93c54654172a02e65599f9d820ab037438e62714be6c7d868b66ac03c31c8753a062318ca36b6e59d340b9696d47c38f115104765865353a05c8fbc4b0a62a96577e94c17094de259006f169e75b8919bb4c37df6787b59bec8fac999a90b73123a5cc8772ad67585c879ebe05b5c06afdb440adfbc4ad400d0e634822a843e9b165f2f0bb748e231c0e0ceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fac291a0bbe96e9ad36a4a1d9c96939603bcd76a81c040fba27a5a39a1c387cac9d1b086e512468d378e96039aae2622fe5483673850d411ab64b892f2c29853822eae76feaf5716a660b55c2020dd3323a150ceef9ab79925d2bc09cc6faa31727a5912a7f5e9051f8b94d8866c4da173d3f2a388e6c44218338cb85702cba2f602c24e1788158b0129e7c15dcf2cc6ed55c54b456cacc07d179b432a5aa63e8ac59f0b6979a833d99c13aa0c56cb65928032e2f30583fa6c038748ceb77a91c631dd09b575f13126f1447cab00bc9c85fc7601da44ac5fea5adcbb599a409bb1a67b24ef438d750bf87a8814df22449c9256da1286dc623e81546c283b80cc88c48f003678ab35380a6da551ac7041cd5112d59d15a80032c28b61a1bb3b8a7267adf4662b5963468b3bc5918418f980cd7db3946c5a67f864dc1f3adea12142fb71fda590e070007662b5c3b8b31af169a092a2e466aa01ae879641bc4d1d62523ccaa3ed436cc089b2621456114215d1a9eefd1016dc81d5320956fd942bdda40f3a033e5170ca6a2c57ce17eafc97aa0959cf37b92e789636f159faa827ddb895553540d52a61edc1b3dceb22a7231c48037cc78594718902333d0bc4fe6b29352991e2ba5d31217457007057b9d3c07c39b7c7eeecc222d4415d6d9272ec50b81520bc607592947c86d2612e434c22513235536cd08f10022b97675b89f1de58130eb6797380f6b68773dfbba0664bb7caac84f7b06711587c6ecaa383505f62751c8346bdd502a58e9326e4a0d2d29226f794ad0064b2cf0a56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b8372158c1a7bfdcb65d426458edbcf8797383e272d3b18bee68c4d74e25751ab1ce4567d66b714cd62a8e9b886baa812a9f50739e30f296791414727d55003bcb52ab6bb74cab215b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = d4aa3d0de639a1563732d6f6a1d0e8dfa86c667977822bd99f7fad9c2996b5b0593aad975d8a7257c68209d80f676f7083b5f2d2690067a9c639882955c4717ac9f64d01676cd1656a181124b299010cef7094772a6c83b4dbc15320a22b02de44da9e532064f3dc3b6e1e540cdc168612b4271849a1c48efab76c3614c173d973ceb61bef391eecd1e3bc8aae662c4d60db2f55458f4d13c56262961268f714dffdf907aa08a434d7b897d1ecfffa32f1c62c3487adbc6f3c6d6dc38302069e2af348d26b39ada73b2c5d927eea8ab080cffe74c50f6e2a5e2bcfebc73ec4f100710c2283b42cc8f3db9609bbe487d0ab933e970cc30d3f084b179602b555f797bc53a49d56a1ca53a8b0e539b2cb41a08c306a162b902f0e8475d0332ae8c2329b54c45314b598d11be48fc0f9ea0584df93ba3185c94c063968c914e390fc7b04202936acac5c8a7e7677374f62fbb205467697881e3d8ed60b0f3730eadce1d26058e58f652e4e00b9b8c2b94102d1fa39460973ca8cba348cd67c20aaa1cbba500a998b50d1b0f48885edf46b79ea816bf7b1831ce4297a0330521bd131a9e5a43a5d8676619be7a45fe29509179d8eea1d0afd63a758817c3c5ce5076f21887a48fbd2afc142489768ca4bd0dafec9727b1fa77aa1f977f7aa72b628290265d1d3a904f5b4c22fc313f5f75d1b8496b2195742b6eb017eb8d0c4d40df0913a7ca9dd5427708bebdc435ab096d6c2cace5d24e8dac647bd5e7e8060a81a379abb478702341f0376e2ae70de9a4e7ec6213d61983713fefab2e4f7e6611174fe4c0578435cf87fed3171ae5488bded533e9e4a057c6c79e37f93f6727ae9269d0c96bbde650e4163278b54ca865a38ad0ec3a04ecb2eeba9b7f1d55c84fffaa5603a662884baf8f715ea6a30d5350eaf6b4abcaf7bc2a3db44bba3f66e84d7c0ba4afae3950dfef27985198533ca5af7d59b4e89f9dbfd29688978c0bc639dc7b3f06536ea66fe0f7aed7d5eec6acca1ed5d13f4ec5ee9e94a7682d803477d0b31ddb77daf14395bc54cde91caff9dac3cb641a1b7354d1fa9e90756bb59617cf1108e2bfdffa11bf8e6565f7cf3df3501a2193cd03047a7e7b44aced6ae6381cdf440b7ed2efac1ed5f6889d69170490b57335a01adf88fcd6dfbf8bb1e7c97038b13e81f018868ed52516f6bad28043d48abc1bd69d93f6a192d3264f38fd693f5e9b43a81446079369fd8bad5197328691dedd297ad98f1684a03193c6e6ecc469544463a70157f644dc14c341ac3943f3920e9de4a96d8091b282ae5fd5d9fb3bcc94357a67e0f616c6906e555d52bd13a24b05be0866e43ea957b297094f34a3636d3d9453a34b6d1565861fa67a746d2fbb598a6f1aad8b2c7db65043c5b7bf97eca89e32588fe105aa6ce7e30b687194169c4fdc6729079cdabcfb0085d00de34ba57f9d8140ffe1087c469d7fd5af5242e096e18648866bcf24bb5e68bec64289ba207caba330b6c8ee82bd43bb71fa96977909192ef9ffd1ccf +expected_result = pass +expected_shared_secret = 8f50401bc9b1f857fd870902d4065f6cec8cb825db3eb22573c6167442b6e19b + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +private_key = 548a01803a231ca63843872abf16b2c4b9ab7407a093b354f8882c6775bacf2931de0a501c5a7ea7ea5c3baa067290b9fca059d69cc6de9b772cc058470544b64b11abb77f490746384b83283740f0702e17d046759b61e75030f187c2283045b22b4f9e222ca44980dcd0a42e5704504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac0f00a6f592770d8082f6157addb170a956456c7616c856657835970578b35fa87d8f79c2ae54ad36823c6a13a4207453ff324f17d13d43a400a2102b6f6224e6f2132bb14a32fa3f10a446d7944428b66e0e0a04b204c5993c03c294927c60540f836572793c8825376332b64d109bb7273147a878ff0b0bd2808b62104515d0824c90a4e249b4ec8c0f6b572bb621b7a74089de4b49eac5a3cfb61a5d6b420779a29e1c5ae98ab30e01a0b45538c9a14ce61c4dffa27a4e462757a3bdf00c0206c5bf5233132c47b7111771daac633e22132ae82cbd616ec92b4e9d1c88e7285b84d9a12e14897a020c06832e9cab42102ab999838a93a77141d12ff068ac13dc4c685328c7036ccfc2087bd92ca5a675cfe40ae4c32b28eb770da04234a456eb889ef92a93a0d3ada8061599d99cd8a96880a2b5e440766a9c81e7a24f14c295283c333a0576b49c569c99450f8714160c4cc49828090bc2ca390094e14bd6a3011a5c038f0927fb4bad38440ea9f96fee99141c564a91f9c86dc72498f89d05b047461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a45137881c691352f6240abd2298488299331cc03b1a3106f242d2871525587888e448d0f45a61480bd7e377dd5b63e143093fcc8bdaa563264baa458649ce7fa5826e4b9b49159e7541d432143c5093a2a5bc5b835535fe7395ec556bd467a10975ce26304bb892d056a6ea4c5ce08d033e9334cf7f6750cb62209ba21f6b147ac875c3f1195d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ef0ac4b32ba7d563af40228b2957b8a95063a65bafaf86609b4bfe1127c029c2eb224465e1c178c74cb5db4c0c2aa46456761ec4a528ab2bb8f92c120a1b78a9517a29c8ee408ae7fab4fdfb1941cbbae4c3630f407a2c23c4d10a58a8e64546727153d61766d0242c5132236f637b7323905f4a7811c1b8019a808946c11a54f8ca6c16e06ad9a685edb094616a80383a79e482c611760c249988547194266000722743346d13c80f72117c25cbb48490e05789c6a5e85ecbfbc73669f249c10a12eca037dfd15994cbc450eb40868abc2fea05b5058429b6b04dce2c4e2630a13dba2bec9be9c30b9f90b45a97040a1f227200ccb4a4413c8b0c5b169830d451bc7993eb3d5b4d914a02c3183b7423d61101b0e3ac0a2a18673126f69511f27ec55e28b975e22a8ce800c37473cac71788a42cd39c26c176c9c255c4355a62c0b84cda33819a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c392791b84bdb4580326f5128556d160100622affa2756e1cbd0a0a1f217a0c198a6dc043b1c50813bcfb3c2488a5c02c79393b65f39990b610274fa77b814ba93784562e0794c179549ea0927d9b4a25949faea67e908040a25908a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f12118e0685b09d30947ac76f4f72e89bbb7579bba13d3cd4e262fcd385eeca8b780d7b6d3343ca7ec1958569c49808b97586c263903989928ab9b63efac00b27037637897556b8aab33198c144d226ab9284541400138e03a31f10cbf1cc4bf633c3ad70c65218c1b18770c91d139971574dd90317a421b8bdc56c02c2564b2496793a27a12009ecca141aa337e911f0b448d913394ec1abbb46a568ba749f0fb0a2c4562637a220225a0afac0e9a53ca4f506391d7483932814dea886c89879237a95c03684cc0c2d2701b40e5b3a340316159cbc56bae84130f2fa830501257f8a8948f482ad194ccd4f6ba6c01bacc4c1b9c3188c3d002f8f18f62393b373396f6c510308b6754b8ca81f53d5a1512ffc3428a6c2a543a61fe1193a86b97b260339fb43a9f0375b1c2c62ddb4c1f6629db701b2d2a50577cc7d5d55a30766400842938d83a6818a128310d16648614a6b6df6b5d8d9a8d0ea4a127f4233b9a50ba539f5f01b62513a5c7bb8ead8463c0a346252c94f753a34751b078a06dd785ac6532c2730caef7249515514f8e18713c2a72d8949de781c698e708deb35448ca1df99b8e09ac4faf694ca71b7bd41bb7024c0435424831424f680a77f13506a56c97b6966afac4b90fe60bf5e7507e6a7093c47b5f8ca47d86c767455d645c502d82cf5b1ccd8880758bea855dc71b1c98494862030202c06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacc7117980774e12355af27e506a2ac63c4abfe585b2123e2404b9ea9753fa101604663d07e153c07b743b23c56b86a91ca34111803a1f5865e47807c012a81885104495499884b495ea3f457a2ae1363221b2a94be84e27cc9e8bca44f8fbb92746821782b3b92b1bfe87127f34076bd4acabf60e4f9b97a8f63008b584d0221af927c67d616bb9933be9486e38d7befda11a27175f670600041a6dbf0c9a4364b3ffd28eceeb0c8077c3aba19c6123a20ca72c0776aa8e21a582168591c7c1eb146ba820c9ea1aa3374625c8744612bcab37250ffb34a89d305c35169660dc9b09f7c960a4c4450b1a2e56088e8605fd75a35eb620c3c90b93fb001e03c006a15b67136ec1c354d405a61014821fa9590dd212cc6095dd011bd8801a10f08f15da21c14cacfde606ca02b7e2e1483e3514cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d58c033ba2280ec0521bc53dcc3772d48258593a5a1f9974228652b8cb4a08296eeae869c733a316d926d400cbb09a2daf532da06522da9694cec2a29cd4c87f6a6c837c6ef6182a30548afdb807bf447953a3827db3122bcc7e33576a33a943492a61f3625dcf412793996c664a4664b3666c154f90b40c3ec514c4b1a2d265a23b897177342b76c69637d52e356620f468480472923313a658683566dc8f8fc1079f248f9d8ac67d4ca703339ae28a86edb4bc21db231dfa970249aeb1e2138bd4791352151520a73b0792a0e77d4967bc8b46740cf5599d4056f382c9006b79938825dfe2806cb6afe7523d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258194391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = 72251024f554cdac42bdb223557f2c724beb9df0001783cf348f83294177c086dda8f240a793f879b84b7ddf199fab6cc89a5c1a5d9e72351a6eec092567a7fbc0f588b970151d55d1d8391783396c352f1842300fd934a2ad4a2627b455e47102c45e3d23b5ab6cd0db4b40f689762c36d0c90ceb333820e736fcdce8f0f683a3476602a5f3326fd6278ff073cb5833584d8a5317bb6349b6d4a0c86b4adfb9f3e09cad0c35acd652b16646150e40e3653e230fedace908bae8b9411a8b344b90708a468129781f42dfab8476b654ceb3042407d8ba005d7577976e6b5f918d53d3cc3bfa1426633efd8a8a211c57fcf3026daec0d1b63cb874efe2f9b0b90bc43421c39b17884fd1adbb1b7a27189743cf9b785692d2afaef0d8d7f3dc84cc0a04351085550a53cd764ccabe0dfc376dbb140562d8a923fc5d6478e5fa951c1797673db456634f948f840f534f66739943509455deb3e1b7e4249f5b35f0ad810cec14e275f9dc23b00fb89fe12c211f310620ddbb24871a15eee57527e12764f45039695780f3eca702d7cfd9cd85b2411bc426192d6e9b77d65b8bfce6fdf610564402e8be61831caf75fea911112cf42e65ac431c891c03914c1cf6cbcadaac24f654b4f853de2a7ab29f7dfa52b91efeefaeafda36feb7868b4b28f8f987b9117d5049cc61d41b253e4ae985319210509b25be27e4c1a5220503726318debc86321cd1fa4158b1afe3f1677f1474ad276e7adb6ede24cd85a67023e85acc924792bb15a4228bc242426b72672b1a443a188a2b6f95555ae0ea41e1e03a26ad7f7f3f0d1629fed1002e8477693f97d334caa9b448e0e09e9a1216fa03219854beaebb0e932c4b51f9c7f8cb869b05c5c401b3de89cb08b9bbffda04d6b675988fabae97a16c5991a9bd62aa093bbcdcb80f5251def293ebb350a4e8834ecfa67f716f4553beb0731069ef5ce77af83f29cdb75309f8488a5eb7418677b4cffd27415d4057aaf750e9da84445146b21ffbd57e3ee5fe3cb0525a9192539ff44581b96c6ad6131af9578b2d82c0d5a9e9d165d992f34e7f24805cac07d6595734a166e946a7b0e13e972f3a4eaf34b82e5c04f10dea2b31346d5b7321a718f0e162afbe6f80388ff18b4f3d2701e17b9ff3a3b8d62a412b6bfca7ffa618ec1e54c150e2b7b7b94a1ef82bad5d6659b22733105632a0949068b2b78751a660567f1f74f79f81d4bf35250fe1cac57c4bd5bd2a759b23289188444645af0de21274f92c5341781634c9ac6548684a9ffb2960735aa2562fb02562ab8b86cc5cf544e71cc1348f3fe5c25e9bb086e40773b2a860a12a35799dc602a6140e6b29a249aaeb366b2df08fde7ee87ea86a40f195b179bb355a61f71c40151a3e4bfe5298fec2146b968141676c9b24e662253f5579523621cdd775c56257f1fb23bcfbed0fa1a7381330f678493794a0c6d79c26a2171709f615898ff6a71b2af60e410b37ebcaa0de88d54081d6659a670b9d4c2967364f2995e744c884e1832430 +expected_result = pass +expected_shared_secret = 3221d7b046caccbded38e369625f69bac60c2d7efacad8f24170b10c5d222830 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +private_key = 944ab695c2345bb67894d451ea2a5c92561a5467c769352379950879899c9cac9d05e89cb2729b2bb47724923fca357623c69643569d66912b2f9b3249908090d4c5f68388a6141163c931df430d70290950b07de410af913c0e5a215c3059785ef05b824545aba0b95e7279d1c5726b59890b82131d5c62e8b3be33b8016ba0c321c248a5293c71eca570c9536f958b84663b1dd5bb6f272c3e201f014aa3ae05640ed92200274d45d9bf4410ce8ea72d680ace1eeb04cd8b002de72795db60681bc9ecd387fcea796ff7726fb29877f895e6832eb7eb179a5956499ca3bcf3283fc8489d494a88668e6614b1f49824f12a448b31a42861190ce3a9f73c6ffa25622d7a504e0694bb7c75ee71cc8e718ce9d57ac86a11721721e6181f157c333ae098f8a6823f765b60f0300f4733cf65240c779569620213b8a331731a7b31937104becc0995ef57255261ad9b246009f855ca82af2001b256760c1543074d70b3c578279b35137e16ac2089a4c60038b8671d308964b68a2211187154746c27f59c8105981c8c7d0ad58717978c01a66b5ee1697188bfaac9b927822c940c5380409f38459f5b302cf7dc9d6bd823a0308b0da45c35d541d2346bae4173fb0c677eec26a94c4158b28d4d7b4b0f62a4ab06bae0b42208b099a174bb4c482c7c321aaca49c4a517114a5cf408750e8588545134f83a67769cc6e0b413bb800c04093184625a7ee24134a721d5fb1571cd82dd1d7c5f9103e0c2c4416cb775aa28df48643084b391dd2caf39278e9a31d2254871b170ae1b60a4e39b1f5a8473f580c7153caa1369d8e9ca381660a57ca8d2523202816767ca8cac0914c16f1cec8ea4ea5da930e0403e7a876c390ba31fa250d946a2eeaa479888011db7942f7676a120338357bca38c4c95088a4a0884b8b4c14e9c09e831f8aa658ed77cc164124cb281f61856bd6c965b6b6cd60b1b1034888f3970555443f0f5cc29c800f578806beeb4730ab9af4b9beb89502ab48761e188cb9aa95ba06b28cf4b89c200b2145a4339a53406b6790a518f54902eba0230a8c2a45447125b7330f12645d935e00651cb4996e395543b7e643137abf3df59e042abd6fa11927062d73d0a107ba6fea0908ff6759a972c11e864ee7393254051bda558d4b272e6cb2c337747a7ef46f5ac872d5d5238521c09e21495ef98b59c22961e5a4967370efc4865f06a72a41464d37ce4dd1803bc117888b681d35195c857a47b764c6799a86e27327eb0403931e29f90fee8628aa43b333615bc0f251707024ad41a24e3c4f15b99e72f536dd989c0325225dc682e3611640d99c1552506e687e18a883f90882056c14385bc08be82616d811a4fb2dc93670945b7efa17593c4b7bffb76f9a805f5230c50b065dc77b409ca8cc0b7190aa61614c528af2d1ac130c19e4362e85a40693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fdf026207e3b207613d2ed74c085707edd555fe4c00b40b2a83aa219cd643f1d83ec0fc21bcf94fba6a8262d959c9fb345f2221082c40a1501c46c55082db2709230b04090558cb6d6815173525725d8cc0bc93c881c99a16041757d6a05ac71a15e887eb14cbcb226951857be4b3bc2a1b578b148e824a2414412a3d57c8213793c418bf2e0803de4a16eb9c8b5d53718d38ae40299b89793f14741792bb10d9c21d5f06633aa3cf1cc78d0dc99983076f8756b2f96b2095e0b812160fbb9494038a88057671dc692f14a956d5e6565ff752d28237c70b8f8528cb1a04cfe5e6495bd3b46a3264fd7364e0d54f2ad27dd27b022efb3d3a632a7f99551bc3317250207f2658f363164a9631a34b468e9b3c9b34b27a3a02fcbacc516469f69b3a51554b93e05fd6dcb098e8af8a3681ce89548ca311e2f5421ca1496a532366435cfd56a26a245ba68655db99cd113c1ad1170bab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b302c037bab4954627a2363020c4ab5ceef5aaf2e352ded62fd6a52acb70c84723a527ba34f179204b26ac10692822ac66cc56bfeceba65c33295fb805c596a48a0c59477405c21ac3edd2c27e56c19bc84d710584ade48647c681746038ac74ab73591fde872ccdfbc3cb1218fe12acbfec9248c00e19424b1fbca70fc5193151aae1415416ba2d7faa6a2c745cdedb94295438bb182dadb77182b2be5bd1ce0cc028b7eb71ba8cac8585cba3ca01620b63fc91bf3c210f67c65c92f893fc616158c104a5799720ab0fd907798f0678746475c8502029865dd653209a39c0c362258a266b1b244a4f42b4adc1c6bf602fe61125c3b989c018c0a0e0c73e35abc97c9ee695cd265909af82548b865eb4238376a6ab53a6baef185799489f64e200fb542ec3d1b42e8b3960e02730936d620360ff4570b4079b369a83629b599e7b27ff48c37f727a4f93bbb2d4b7e1c73fc0d6668e53c1efe0a0b547b1f38c51f4001654f45bf0e5766ca1c662f2cb99a6bd42a17f89c80a4db03c990a81ae9487e1a52c13720266083e152061aa08c03a7a703de58251f129546a42282515a3e27195ca97ceb39b00566cf4acadaf320d5c88c75ff310f10bb5ad738d38aa47c945235e1730b6cc227a194dcb04ce046a22c37319d910060b594bf8a64f2c4b8f26000031948046721e6546893a341ed2c32804149954e3788ea5054c51a43da89f9c789eda6727bdd4be32b15d47b9c327ec68422813b00950bd73c96c7175274a5ea8bc128a7c0993031b4e8a5d3c074d2d1abde8239d5af58c06509b24109c84297e3feb447fb3926dc19f39211119c4597711a222b341cdecb0698580e422a951db2305d4a7a871967db945a60439de206955c371ea52452f865da438130d2b8eab3669a97911258b08931a2e36c6c390b6845e8076a0d621d7692971ba71bda0b8aaf7ba0ad3c4f05ac23621a146c68bbc501854062b924c3a64916a1b9b19ce5b466f8672ede621ea987f83495106dac22ffab6f4a5cca797587126ce50589f68a2084875bbb505c7ff46922eb496da260e3719cdb2f23950455dc8d36e3932518bc11bfcc067ac533360b86550b6ad09e93dbb092be410721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae1907adea5772276b2929b9507db5c06041e5f9846506055417c6fa091652a4a424bf6396d46365bb40601e3a55801b93a1ccf39126ba7f025a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ac5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = 6416527ba23e80f4837873839feff13b3514abd118bb91d6b361b9bbd9abad576f3a4d8db28cf4461b9371ea96971269360f966cd6220bee62d94f3fdb9857fb66b0a9245fa492d68ee1a9e8e2a49f1610391349377d1810a55258b3529d1195ba41b6642b7c8b5ee3e14cf59216a870790088bb0511ca47eaad07326f2596cb851b00fae41118dbe6f0e3563fac9345bccaae3f1608f10e0541022de77c2f820499042e3e0398e48e8df6cef984c91675c3ea283e00ba9f12e7f3f0b5a4e9a958d648afc3e5012af630b6b64848036d95bcdc79c5d1b11bad1327853623309c5d0cd670a65d64a3737817f5961cde07a2d4adf8e4624f0cd88494b5050ec665fca1991384f9bc93e0c3be752f94d4d0fb3908fe8ebdd8b8a9968c00c4482ede3f60eb6736dd4e6a33e44652e82a4cd16751b760b784bbb778663bc514073a93be9e9626c7979052816fd54514611134fac5a6a7ad1b5c8363336ad8bf44f05daf59d6b66e28f86d1ccb6a776622114190dfdd65f5088f82f6ad4df28369d7c9a7f67f12ac36f143d9e2ebb990c4f87c4442e81d16e8753457183dc14b0dc1aa803a4b016af2bdea1b90e888ca5f15f5e0780fb6ccbe45071fa6f73035a547d1eb8318f735b15b9dc465e6938f5454808358bc4444304e82397db3d1f2b06fb5aec777e2922887408eab4804499268829b5b94e66e75b01e4e8ead235be8bcb68c801d9a92adad2abac3ccd87a486bb4c17d6717d3f679e0d8d549af5c8fad6a0a398b395a57715e8a7ab3870a475d5c30b917d24e69bf0c9fec18cfeefe54953064a1c56c00108f82df8f224469e2fedf46e2a8cb3a0105a3542284611ad45433f7782b9e879f483f4d5ee87b481f8b353741b5565edab5b252c73988c705d7adf1c3f2c87b2f9bdcb94ca5e4a0c5aabfa3ce67e8cfb8f79f43dffb385d8ebbd4e76ffa8ab641a3c8f3bb2291cda186160abc78169568e7daca87a9c536d8a7c345ccf8046c38e165488301872b1d7ca223782f5acb7bb664ad8c7448beff305147e7bb663483899ee1a4c481761f7b65bdc9c0d4396514d48f22ae383c39c9fc650b7b7f166bbdd2ec8bc54161f7524ac69a9fd9c538f584a096636cadfd633d1e64d5e89246a08a51a9c334608631c2687d63836f6fb8dd515bc7a4e769157499638d2611b69058f2615527a04f4ff2b60360e46e34bef1c8e57d499850f44ce7529e80ef0980790a8925184b4b22049b356f4fbfe293ac054d63985540cacb9f25e9180b626bf1e3f5bb3f413f090f5d468402edf672da22212f2d1214b760944f57d3c914c042eecec08aa5d2944fab51fc833d9e374f2be7c5fe94296c0df98392592e0a6b183242db0b124ea728c44a5aefeb2ac1c1437bb8ad49fdacc3fc482aaef9e814a4a8010fa2f0d0cc6a88a259aa8c09b7204e09a71fcf5a0e7a801c3319369cb933a57cbfcceb64f96be35598b4d2dab925014efb66247362e5b61cd56471a3ce4399ede77b09879ee29fa51513d4532bca164dc19be35bb7 +expected_result = pass +expected_shared_secret = 1d746afc4160c75aaa6c6967f4eee941e09546a039027f05f0f8a483710ac334 + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +private_key = ac65af9fc8b905d09638374e58c551da08ac4ef86a8ff04489ba462841a85d907ed0c70e1a790297ab2df7d6cdfc5c6af513144da105dda2c75f00736dd91564a79668e335fbdca1c9d31592e73d60066b959a2fcbf55474f9c21bf058f021457586766fda4fad521f64940d4932b07ad8ca7e1a06662730ea6c15aa1c2f9662552313176af04fa4a98962101492566adb8bbc3ec04f9cab9ebfe5860f886d57a2c73fa050a3607a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661cd000d10d6bc31ca1c249a9b3931a4d1c57904dc6df923839d9a90aa2b93a87c44b5f82e6a925d22e679428064ffcb9621067b75477fb7d51a1d3b9d9de4051cf874ccec12976562752cbfcfc59f56c2c60b8b4610a9bb36e9019b974502407d57289726ab8a38d7a6c880074a5686619abfffa5757dc79e1449408851502beb8196f493f4a724b9d681645a07b193586c5c05d8d10e2c968bd251b88691c368dc18cf8270dad3c22bf5093db4cf05668f8c6315c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af53141eb5e7534fac4de481741e48b414302e4743789e250c39c45c0a15cf42e7b3631b6a8c0971c8a34b8200bbfe11004ab06bfc5949c3615b02947c73e7a0717c6b60f2679daa21afe4c55768a08e70105868aa6ab4aaa848c79bf125883907b9daabe367afce273e2c168aab02acd27855e2944b67b938170a9258f67397770136e466758c260ccb7da226b5a95692514727fd48953c62959c88c8784a8a52131c4ba5a6d757b4311048b602b554e8ad509b0c12b0a64553cd4270ca92f36cec227e16a217c769a2bc1aa6c356a5a39c69f4963ba6273db9232f1d8a28ce65b5b9058f1b8a164ab0380c42a8eddb6c2b8b19f26b557c387e4db9aeb92c4d7d0a2ca1e35f97e05cf590bc511ac5efb2357e70525bd027b36c6781c4b86b0069e7b89c8ca643fb9990ecab2cc5a8a5a5b2b0441076ce934d96bca9ffc10eb6e7bb093675e97b68894bb030581d89123642c1118364115a76ad1c181eed4b691bbc15df182dcde00c71f8685b71883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5057a0886d760460cc4a3a713f4fd4bdebaa93b943c48e6348053703ed818fdd9cbd62e246c0b69a265aa381822d6a474c5aa530aa5306a0c8572c413718a278194367405789e1f749ab4a02af87b362067f3da12ec01a83acec26a390cb5419b351bc95e08c7338fb933b81476ea950881275a186c9e9f99dab63634e6b7314188bfd686d74ec203b71542b62b1c0c7712745940f7b9237551467470e5b1ba2f8e34cf585adbaf980317c9db1147382946c12223c3a45973b879a523855bef121151bce620216dedc6c3457ca03951ff45b662f79a1a7a5cefe9a846dd5774c7c2a22f842e4e465a94314e036bb55a2787a1a0f0f111143872dae74af706a369ca54259b80578bacd497700871842b98cae2ac3b572f98f145cbaaf54569779b616242060b30b2a482daf335c9a502cd318296958c696f7080c7a3926c7b62f36a5dbfb87ea0518358155e8e94390b6c0f808b91c166577037d86b5c9a75157e73ccc2e138518ea98a246145dfb6bac9b2ffc333c0ba5806047ca9ba8ab797937000270e773c9863709e59786f8ec948ed27660aa3758e33f59140e527787fa74a2ce22a4a8f3037a26903665cbfe8a0677ec273f590d64c97f69f396db78448535746b43296bfa2bf0a251bf986a524074c1f96077f5219cfa9124d1458520993f627aa8b7b6a0f191683233e0ba6bde24561a666fd10151b0c52c9982c301e0970c3363de27825a5bab078848aa5cb75a90c1cbd24cf67a68f3417780cca947131e4573934f9959787b6320a4b47bb311048289e2c915e35344e3a144e2708893138a15a03fce3816945464c229c587093b5cbbb519767fc65c078d6c684b8b81c1f9cc2b3ba749fb3074623e3c9124a8e1a513510357656b37087bfd02773fb59157eb885e1501740483f3ec070bd492dfc217d7db99cd7c9d57b937297634c3494deb585b8c93cd4eab1865f8a9c8bb15dfe583c7dc0427274f8df3c693fc351289964a89a3c745967231261d949552e0809ba9b7c5d258af579a4515981e991d93154bcaa170491b06752415b1d52bc2a98b7f39c5b91a87eb759a9a4537218156746930a347a5026911adc0412f10a7a7c200a1514d500805c10a276c327e4899aa3f9b95d1ba2347e0140184b1235a719e6c4a3011576235215d77084034771129c33199b70774b2130898a0c69d8f39c3a50b273c665dcd8031b4454d144a4356b9c2b16641311856cb65466991b06d1a8a74a5aad6b5b935b65dba8374ee690cd1c701a5a28b41732b5f88a9ad919a7fa563bafb529885488f544e1240b3cd673f94ebbc91b4757444a302578aa953161993cc918216bc56ba53ea17664bc5b543a38c3516d4063c35695791d8821240bb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58e507f8a105e2f71f6095621e354b3dec1f9c979ed7b3aab56b4741110fda601fac78c2edc386669118a425c634157875f61adf10c43d2184d3252edeb11a61eb67a349405ec74b9fd307558a887efbbb46c904f9469db491605a3582be433bed57363426055cc4852acc0317f24d89903a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5a0029c1513d5a1a98eae78713785bd4322261d90109a0806e565ebd9308849cc6708b536c83a2fa35995c819d99b850251c1d50ea902a053c7ca31faac37bcb1b40d6123cc4d52002909d0ac566f7d75dc89998036aabb267c5aa70184ab4cffeab018f195f62879be0a51b42b843caf7c494c181c2f06866cb2287a00349ebb136747da52a3c4a3c581798c413929ce3e698fa594f019579ae329a22d4af66f27b46453f22e61aa6ec5d7d854ff6d3c3d4117be2145b5c2ba7a57ac968a5ca43b461f808167fb5a76a942c95145098b95cd46439669c00366960e2162ab613c5ecb151359b093c27c04ab230fa7c0074684996f44939c81fc31373c8231bd0b6679991a32a031002b257b2f31101317b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659c970f94d0942124c17ce3ad50d5a7019146bf51b012d1cfa0f59b220a795dc6b3d7896aac680adad383ec46762b669d35909a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc962e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = e87c238704de82f3b46046f3501bc2f30e57e653fca6d1bf693945caf49a924072cbbb21838970324ef7c44537a67d90dfa64ad9048fdcd9cf15c7cf55af3155afbf69a498a3deef649022a61ab18ab3267c38707d732f479fbc7021038b52e0da50bfbeff9208eb6c09cd5931feed40a8ad8a6fb95fda48a911bcc1dff75e952c1c4f8d66cf7a6c1788de249b7c559c9584781ee0814b9af67205d76fb32df7dd1e6bcb11628aeb198fe307baf9db66158019ae9866263ab0b7bb301fcb36f5f78f7a70b14e8c75dd505bd204ab79519b563572b14f332f7b434733dd3dc06c968540585f07fb2533c6a4599940b92f0afc09afdd0f0e74c13368267ead2ef18b0f4c0799a6abe14c5fe16aa5c81e9189b66c8b2121e4b38422de375272e296bdca2c3632ce6e8558dc8dac44971fc55cbd9eeaa9d91f699ff664b0e8eb096cb007556afd783beb895d382aeefe1a6004f96f48cb0adb49a75612235a2ac318c9ae11e6261f2b90d975d866fcd1d7f330a44325f5ca0f792f3daf1035a5107b90bcf9907f9a3649ffaaf4a31b680184bb3f76899f834958625a91652485d84fe7567d667ba84e7d2c8bd3296a0d1b1f59975f92ed1c16e0e5cb83437a6b9d8c200ccc2e38e53d3ae037869e018958e6bb473d6a009f3c09714760bb2afddafbace214b8e119f0888f2c6b9343b9cc907633583a8495dc4178489e95dd68460b892c27c0897a2e6b2a9499515cc881673577683fbb28c8e7ed4fdaca6a58b8e98b78065c5a4b2b3414d144b17ba898b8c268afd0cd6e1c7543801a13b2218b75cd6ba9eda819bfedd4094c3ca7e439c1e9c4a8df0e6e3518115a3791d8bdc86bc712b613c7708d36f94cd95775334836f39bfe641ed8a4ac9d7e3c9642ba5ba766296154b6af09baff56b7da6c43c848b7518f445f87a31554c90054dbaf3a2fd1b1ffd91306a5888620b90838b7be589c9fa15055aba13b29e57f8b5dcd2dc7dee25d31bc977c05eb0012c261a5916cdd6b91ce7c7f3bc4662bf500d06374d59f0ee21f35cc04ca90ee4951350f2fad026ebaeae4ac28d36882b824e9341dbbbbf2b5406451c8b4eeb4defa8c572e9c83c6d60b98318369b5a2bc88af89dcc6120140f4c5caf432c67a6c51b2c47a3893f80776a6ee726300e5587bf3743d4372bc9e1e3a53bb583412297866c0174e4b81cb4d2363bd5a08355e3573118066eb549d9969205a61e8bd916be103481d0a8fbad57d13cfa057305b469b9ebaf78fcf2a333783956e2cb0e865fe4e9287eb5a608403b1353d389391b3ab57010bdb0838c2b21f8d7c1c063de9a27f4d600aa82737c805b0f0264cda08a3d315613f8741519e9dc16d7cdfab9816e2a639b5ec31cc7f66782f0e382dd1710be19610094c61230ab72f859ca4ace9a63e3dc1e101a95e206d832efbee6c3c1819da9d3a03c42100e309dee54b2d8817bcec51944a39aceb7ae0423f7f8fc7a55970defac02838dfbbc72f0a84869f3f177bde1e403784032e71dda78b484ec1eab5 +expected_result = pass +expected_shared_secret = 722fccef7142c46f74eb57a10b13e420d6554e9d18507f660bd1be96d3cebbcc + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +private_key = 67a93bb27acd00c9b95aa03552809c38a08480dbaa67a9584a460345e20e5f381c9a82710ef1709ca51393f916345719bd3144b3121a8608c0a48017963387f7a31c5febc6b6749e6bd9be3c58a9a77b53d7762f5854a3467a85941ca2c03873c0458b940275e5ab85b83a5c2027894b92246dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451922761ac274b5cc8569ccb93917a748e93c190320e3f1381e08cccca70903975ae25689c12709c8e9096b16a26e4439c2552a088194368b36efe3871a6a1cd54ca0c70974ac936e45dca01de296a14c7d20652999e61841dcba6c0171fcb406e14a95b0c02517447bb9370996176bfdc5beb4316c0ed34a13431e34ab27d9dccd3ddaa49d314659bb8d89325099d0b06931796ce65c0628c817393bb1870f19a10cfe3546d8bbc2509058327626f490a1bbca6fbb653ee1c3555203353509ab14b64cf8a29c32b17096805b8d751848dc4494279266f2cc474228b2b703cff81f0f29152f4570151517995262d705afffc08dd413c12f37b605bc32ecc1292b9ac99e4a34f911c8db990ecc9a3dfb37517446908b91b1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d1929e5721bfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c8b20b3ec750b082bf2cec89a6f8c2881650e5b71a0135c865bb3fb12a4c2c3c917d655a2997984c8557ecf1943436a9fecc5c84808e38701cc26a251f458334f59bd40bb0d8f82e74071a5ae3c9439541aee59c6e46a5852834ce5712b3665018154c5339467d606af189ccf20c68c583c96d969815109cd3ecad4f5ab0a8bb8a7b68359b0319078a7405821c2709a615864422ba0a3970c8ea138ffc1522b1a53ed1c71d396a0ed6b782c6552c70216679bb4761a600634276d553cd703897c6943a859112caf9a7ac99517c23ce6457aa069b6fd2775efb262dbc27b02fe6923d14b047a25cdc6b86d20a55d85108ff276f121a352e098e5d4cc3ef92b3a1c4a38244621b055d5f812189f6941b492330fb1ab0a442a656655455b38b522ded5640cc4136df6cbf4c4b0651531cd8c95280e2af13fc57c977bbd1a8bdd253096ea98c3ab33a516448a8301a4b141ae213bad2f640b2d5846c99a25884360f604333197816ba9dd1d0c427c5b8d3a6b434207b8539ce5092ccda67a755d6a6d7e8bb6bb02af1ca7283e797f24a1042d29b64262f29b0482b840bd70a3d6d54205df412dd6490e3dc38c1236758f65e461b11ca480b476875c692508e7bb90c430797e1917041642d88506c07255aa92ea32508462c2f4a1661c05114c9361f651b7c5ff70b42659ffee71f58cb79e445536b8948142cb4ec16cfe5b21da659c2dce452346323f1632c37f128a6525f40e03d6c073e05476252b2b0483c4b87c1c1fd8c972cf651eb9684fafba3f862c8619c089f01277c14be7cf7790712ca1e8877a48909efa31d814c1c21f4a151b886076840546419a1c8b6ca4466389a3f6dbb69e8494d7b25a4e9b234a8d928a26b946ff305b8a33b0bf8b3eb992d68c312b4074788e69d1a5a211c3b55f8c654ae778fbada1d75fb2305eb362461c4a2e81885084505c3862c3b647d181805205ef3e4ca5c30c46a0c21eb97700b70c2bee78d862b3e19dc1e0cec0ae6998a7b3c4fdac39a950027fb2a3bee027a8e54b4a5b981bba01badc0b5ba6a36a2913f1c1a046036960790ce2cf2583e6c62a778290f242b49606ecf24b3a0dc023b22ad8945a0b8dbccc9356475b36b2a990d7435b12e1536a21079fb7802b998488e690f763646c3b66adfbc8161855b20ea18afd87229d05e60372694e4c4c6215344da04173559d7954b029555e6ca4356f6cbe325a39431a64df06e75c63ed0e40bb0cba6ed68bc7211b02f1165c370ada1e0acf4ab61c87cc32f7017b4a26ff8cc0784f76047316af6398ddecc0c62e9a37fc4ca685017b33aacf597767312192cd330b2f3a84e0bb858480a63a607295a39f61510dc2c6998614013f45d319858da8228fe5bb6eaf3b03aa60f4b721a3f046d3088671930672c61c92d6005254372d8081be322ccead06cdd472cc5a481ee385096a5b8ce64b57781cbfc4457e917162da007bd7bad8e3803e05b08876842d9e6a0a545407a5067ede3510ccc4478c040310aaf46051454d855d1a5521e2514af676846650e0043bebf453e7488b6db8aaefcc16e26a75c52bc0ef3c80da3bb39f73b9852b54d9c606363438c45dac4ff1a1913d81b9a80544177ba7db6503a04a5405299f80a83fb7135fde04f8cecc0962461c0e80298d219531c9cbf00a3bb5b84908b5a807739a63485128512c0478084c8964f9064cd4514ce92c30454ac25b48919b719c5a853010a2eb712b80975660456562c4c448c39162ca63aed14af7f28875149857f9b8965bc1d04cb8ee2e67c14a493a3822fcd0a2dba2677e719b8f2c8bd09431b82ba56007584beeacaa1f081d244b0d771bdb0c8033b18ca9597443ff8cdf754569dcc2dc4d4c212e2bbee88925ce73034e19167cc7ac46059cd3b9ebbf6bc3a476f08438c61971af139a248821002480f42c2b9c0979ad3bc6868565ca3fcbc124a7548d53f56b51c9f8aa387b59b07638c7aa45704420b3c24642035a7884cb42f877260c29697809aa7482e3fc356d8ca061c1c443cf24c4535bdeccb02c3e3b8b1d90e5b47bd11615caf849da5811aa743b9bd7810c470187e81af9bdb4d1307303f615ace2a58e7ecb3be260e9f7c1e10eb3a84f207d2e75a30c7c741ea45fb04a9473c1425f80a9186a7f2625ea6abb4aaea3bb50602df23acf8e452cc01a909ec9034acb47b969d904213f0a79edb7766d0290005c954a1da0155f7318be854fdb038d019c1904b714f0514ac331c3813bd703b45076365be4b47ec510a9f585907bc0f461a6befe13a2667593e12134a86ac139777a50ccdad16b6891a0871621b387684b5226368400164b29109328f672cadadf7648377cd11c9232094165bb1cf12f694f940c3cd784c84925ba74c8a49dc27cda4c553c85334a860a8a55d8a75969977ad1f505b9b20ceeceb24a262c707843310f39434390ea5315a67491f0592bf722a1c2658c8a720991b26561e14b178c3a1028003cab8b69f60828f47b876d43d3f193c3820804068a5cae76dc3f27f5f1323e6a2797b9a13c86713a83ba9c161899cf295cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c284ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = f030991858a580b285c29e337892c953d068fedfdc83b1997d21c7cde737d0215a3629565b8b060f17033dd24a7c957bf76f490c814636e745689ec0582d17bae213f6986f88f9cff9fd86771b36320483b6dbb019ebbe8ca5642a4613d9fd3ebf436beea3590b08f411287b8a0a50a290621f0430364129c3ef1a5730cbb1ec741277965299bcb0b1097a9f9aeab4b4f1f392141897963f1f0f6768a763af9033c2d52988fdf794bafbd357cb19a101a11d0d35eff4039cc8142b834dc8e60c6d87304f5e1065cb982c5d1e5524d3f32b72fe65c42f8ba83be04f54a0d336fbb88a75e121a7a5a895e7a3c1ca80d70b2463b3b589fc35781cf2b8e917139a160522f88188bf92188eadd1c964cb5f2d3b14d0e1a1ad5bff6a0a5048d2b621458b1c088252b5410fa7bb8ba1d9187b90fdf216871382560943d7ffefb0274662982f83445c112a0015444415beb57bd1a6d282e097f0cd3cea94f92c761c54e7f4d3d27482cf2026d5e5bdee65ab969f8ed3d7861947bdd20a7b86b2116772168e5dee105c59cca176527e8762ceae54fc71bb2eb1301b0a3b5d77d26c4dd3326f5cd7dc535bd4e3846f3c4ca211c4e3e61dc276a0e6e1a5b278ad02762a2a6d48a6d06f73334ea229120a9a8ad71c6bef1beddb53478d1e2af606a955ad8d055f12e79b1733db11b67ee5599340e36cddd89d3cb6ec842dd39da1ae7b9b6943974dc24c497cde4263f56e6bc1dd309fe7c6a7905a6080a2dacf1c71d703c6e277c7661c7ee1f0e434a1241ae089444c31a971b141bc717bb10163af514547d7475191aae32d3adb8bcf0bc49f08b40b3860f2ba046ceef3e381675f803cdc9c4f1a0a4f8c1b5c06cad2465f6608ddc6f104494906e79faf03c3c48b89c613b016e7529e5e6494668cbc4092488c1238fba0993a81df3a3b46896a58a44848486429342f4c823c96de88c203c502df63fd6a58765a2ccf89dcdfc2b8e11cd8521c270ab50d3dc97e66a01aba506c713ac7550ca174b51efbe5c90fad46db5375f09ce999ee3ec2f30dbc5f5dcd04224827bee9fd94b56d4d5f0805300a3775c142e7a1e81905ba012c2e62000c9e2a6c2436cc919f46361c0287c56981d40c4d2c571dc7b566d189aabfb904c8177b52f525cfabcd37e22801e9025657245ee339a8f780d6103f2ebd613b7276308fb3eeb7869fe5a7038a0dca12abc39d0e6802317789514a610b265500855376207ebdf94423005af9724744fb94ce218c2c87e15107d71284157ccf6b6ed55d772b4efaaa4687f1c5a0da143ae00687c749a1e9a869cd356c04460868f581771a7e7da3674d221d074fc2d44edff15932008efbdf1ea5f6a023d1e7c67617701b6685f624448e4d2677638558997f0edd44c4ab4cb9a895044f00056c946e07936ed11aee915fe25038007ce395ed773bb281665b87920a7d9ecb49ed8e4a0d9aa277f7e19b5bcfaa45416a7437699ecad80b43e16948c2be55f69f99e7e849f84b92f45f556389008c1a3b89588ada52c7 +expected_result = pass +expected_shared_secret = ee7c5fb6a63ace944e1eae1bd4b182263d918754c33753b904853551b2b46cb8 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +private_key = 0fcbac2fd83a9eeace0215c784e20260f0991b225897e94ecf93368b79565b478731537eac74550cd599d5268e03a25cf327606686ab8864677907a3c3555018b478fbe125498652d5259a31c2b4649c14c89bbc5758a9b53c64e95bc9ce30c306372d431cbc642c0d60e25136c3919f3bb48b280b9d5ca0b21bb4e1510ac49aabdf02c9fd66420b475d0731918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f5604863ba6dca297ee29238ba79eeec5096e9b336cf0b24dbcc9feb8bfd77ac888554472d7732e7492c231302a073680c684870b86a05592355baf2620b51ddc7b17c9328d7a74da6367d9ec2b87e9221c297b5398cfb55c10e8a68323aabbed806c2272c192fb180e7a5b958a02dca5c55654a43c74216b192522bc2a2dc05bf865062cf56839831ebb837a3ed8c7368c15933730667b7463ab7026848bc9ba14616b2e88e17aca4109b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895400e245df8a324899273efb441b564305ec48ab305c69d37e846ac9b77a2917915e82286ddb397936769be7e37fa7f27a003090c7f2b9b395a41370b5a38c07c2d8314627267fa06bfc416d8ac1155df645c6150bee70c4cad8c6a5c564ba2571c9bc9bfaf0c2d12578c8198d49e1414cba5749d712556a537a4131f3f085f9047735482e23342b218101ad30122113060cca4196f778c77cad2ee58b6f23071a85b79c1215f0a7c8745abcdb768c3c26042d09a9a0355a5c45745d1acf52c205b949acf581ab75cac74f2364406a43a74269645166fe167642900d169a1e84929da4cb361e80c42dc702a79364f1d664528b6cec667bf230078af06a0b48466dc90b34ea7101512e37d8ba3a351d7023aee652351ae514b8d217faf09a07654b0cba1850041d7206cecb05c8f6703f762c97dbf82255daafcc3608e8891e3ad8b3d4e18dbcf6a1c2e74cdeb87d15236d70943daa722481692890a548d7c69a14fcc1155202ca4941c3900b57a452f281091a94781c64a9583c8d302c21484cc6159b88a931aedc4291e097982eeb0528c152a43b97dea2a0b36922fc60c226b61068c792f377b9f655940d73702d41bc515086e8f9266c53a4c15a35907cb2fc2a2f19bc5f974034677a33b648322cc9bfcc6b947b5346df2044249623e53430895295327c9b35f59ecd4a9521f4b93a4c031a624c12f40ba17b9f36908e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b5640d683b7a45009a1efcb5e50a35244c9431f21f1b6826311673832ccbc1794fea917268f5323726698f67bdb41bcc012218929649c972149393845dcbac7fb58582964405d4adeb814037a39e512c3fcf72a22ab70e21fba3822b493df9983866412f0439e1a613914042c982739031949b2780d8133e13e632fc4281de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09e304210d5cce3ca3dfef261a809bc5dc44787a20afff49f3e0156e7b428ae1cbd3292c9d818844d4767342708e4016eb9bb0f7099876c26729f443e7cb3b9666441dba01c8397953f586e3da45789c28969078e11664ca1554eca81b9542bae2ea8cc12b44e81b3354818141af0b494543d4674160a086f7e8755a87258e7e6a6aeb96955286924b42636e04583f74184133d8acb9067925f4969642f274085f70fc12361ff96c3130b143e23797f2a3a6cc757c97454cc8aa5d9c062f9254f4cc7335b44cb66dc712b4677c290ccbba08cfc3948c535be29f44736a23b4c8ccb3978404e419a08a67aa555becb48bcc161cbc5492b55e3498e74bb515c28a7a44a3afa0148ec3411d82a1ae103513074a13938a5fc17dfabad006d90455b4b5e45079d7bbe956c7a18a8bec9a64c1db72544cb00c6997d545ac7e3bc5c6565885536af486417e728cc99c78cfa12a1f7697f1ad26efeb7262800ac4e0121e766aa9bf0a74ae635074c62fb6ca79975761419b12a985ed7a2c8788c9020462fb5764c087681be1595a5ea4ee7234aa2d22f4119b559a536e0da0e8d0b2e493c2b5bd576459994acd684a81a0955684818e1b88e348446a22c9143a4eefc7d8ec678624763d4548fe2451f078582c93c986b0417e1aababdd76dc0532e252b59e47370e81951ef75ad48c223316a40237152e3508ec164c7375594f73b5f0483c560f52f250aaef28431e9d1b2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a7fc02eff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968aba093e8f42dd3c7cd68c8028a90cb0c93cb44d42ef9d15e6ca978ed5b88914c4e20768028f2c927a33433d33c5e6a45a6c5ae8c252a83e68ec121347b025865f26912b89a9da7472b75b9aba75581852b97d27ea7c9c5c7e8bebc0094c01947f43a2c6501c97e43231310167eccbc4c3a2022839584a12ad5b51b4cd308c94302e58c70eff7b24faa051cf548b5a73ab4254179eaa038ec95d4d4182d2971084cb33a6ca1106076dfa76ec0c4b3bb5c7266a481001cad07d12051a77e31603bf47c62dbf959c89774587111db1b038ae834e0a08c27f2b772a967179a9bada1ac12bcb8fd3b06ca44b3f11a6762ab51a9a0b67fb83def8c9a712a1469b719f2557e5a03c6bac808d0e0aa304955a3e961618920d0bc2347c74ad6725a9a855d1d8456d2c26addd849e59b7ce7c85765064ed6d63039e368e9f18d4fa11e16f8cc88bb3ffb40b4c6269996da8a6b5586365292b5b1c78bf4161c171e2fc7a6a8293a96d61d683275eafcadfed74473e30a1026809076a1025398b745be723a78e008c85b558d2b76392f5015d1024c171c0fc6c7c0c0e631bef57166e660269231c3216fb08b6cff0a420aa413ec1285b7b5ae9fbb15f9fa6b8af29ec061996a7612de524c7e0724766bb51e1264ab50c3a095815645b1d1021060b90c96555e8a001044d16cffd7719858065efca6c2654ea25506f0541fae242dbb154e420c0dd4e13a79053b431b7c00768bf0f781810a0832a2b814c5517aa1a0949523e12aa35893912256a7370bcd9faa30788b631b87731cc5c831a26e8f48ad7cf9c935301aa8cb006ac59fd2ea5bdc1736b2a5523ff3c4d8f429dc037292e863a087bb29cc2732ba30bf11490dbb1f3adb3448d6110a774b25d242602c250999ce69d1b32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = b053db98bcf8daca0c50a98c575bf2272f8f0c70343d5f78e97744c670f9d436142850638fe135a85d212ef2b4d2e23e8ba9a5d1327ac7a55454f9e1370861409b296ee2dfc6e7a4f1e5cef633489948173be158aa5192c6a9ff129e0b63b311f7595425aa29dfc758de1629be6d167fc58a65a4252863c5016042409da5227fc1c5334fa809235721f6f608a5443a67dbb33a1e5fa690cd34e9accadc99072a1db81386fd42257e1035b6fffe1a559b97fb71cab8e8e922aef2141733d39935d754e487656cb3b9b2bbb0a5a7c6bebaf62f86a407fdaf776e3a973074cdd2cebd67bb2305d67db831fee54826cfd8514be7117ac424548de1ec0628594062c97b570058bff7f0b38b25d57e953cb4a6d748828d56d643b1fd2068983d138e0f0bf67cbccf7a5ce79068eba43bc77d3abd7222ec5a22568874281ed644d5f3627156d35bd56da1e59fef74ce30a2185834df0f74d776f4c1661f6ca1343cd1149624b9bfeafc0e0084a3b68887cb44d51b7abc7f79886fe6966ee47144a78d12f99333a8a56e2a40110b7c505b6164b0a812590b4dd89d66583aed83348f27d88674a26440d423d1ead252edde582049f0f332afbcc54b4ec1ee81554dabcc8422dbedbe38f9c503722f3ca042ea0b51300d078ebb9663016bf61344f26d6bda836cfda3d06c3c1a2e8ec11ba197105b75942938117811cfb78afb5264f02d1c3a7b8cd72406ae08fad11966140a1ebf31cd5df8bd203453db15ace5e8f0a6ed9d36e1f98d55610e5c048c93c173f0bb47299e8c55bf2b2e1276ea90b22473e8f97a7bab2758087067da3dcec80749b66443e819964882f886bb9c232ef91ee1f57879eaff19f8c7472a8a709b3466801ccf756fb2ba6142ebdbf39643530879284ebfba338053479d78eaf70edbf439ec03f92c440aa15bd765d49ec0c580abf7690efd67068f20b5aa5537fd6a44dddebfa0f91bb6124c2bfdc3c6bb0eb6ea3015e202c6a5644c627963d172168c1b522bec3d6f7c83c02936fce8f3e774d91468c652e40c30ce4628927c44790f98c024860b07f758f1e09df4d6e3394d4dd1c0c5403c2c3a208ee3a2948985354929a90163a00e86b481bea2b4f14de01a0592a80695b5ae23996b1ddf4a712931612af6a6fc529f819b8361b3a8e98cd82fe92005b9c147f3bb4dc9d3155656575de568bc2199ba234bdff2ab277207d8615902229c48db3dcc589148d1b33b1d0594da5b27612a996d33b40ba2da0631471afabb3d155b2645958eac3bd6841dae38dc0adfa59b5e1aa809f888504448a56a3c822a613c998535c3aad312a41385a42dd691f7e9bea9dbe2cf0df32a86199a3fbd537aeea46e7c2768958912879115e2dcf76ab592cd3992036c83e2b2c562ad99cf42c9bba8b96aa54f01a4ced5769d22f51826b4217b2b47f721fc58d5ad5016ee4606b78e93194706332569a673425fe02bef35f942b9637c0f428a54f0bc190b6116aef98a2965181faf2f1d31a436e002ae9ef0f2a6bb912046ce +expected_result = pass +expected_shared_secret = 77cfbdae47854e9e10765cf397eca9ab2bf2b7522817152b22e18b6e09795016 + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +private_key = a5c7981510819ea27d27a945a0f6619d730dd196b6f3a158a4c48acfb82d1c348540160b0cc665c43c4c0e4567b46867ced06d2cf228d0b64706227593db7392395b7ea95360105c1bb05472787430654aa03b6e894c2add2a0467ea51b9486f3df18274c0a2079459df3b9aeab15d203b466ea426911572251b0c8fb51a31aa142bdc4142e393d3c527c841a03f796e0cf7cc71dacb47456fdd386527bccf6e43013eeb755924a22e3a55f74a8974b38e06908349fb3da5887d1a041c8acc6f07a75198462353942267d7600d5243095bb012d2a70be0a3fb2bb599832f8aa68652846ba501bab3aa574ad08bc991c8b86717b87a45041657d0264f35f0c2b70324eac43d591202cfdb9a7d357489f70f86d6308d3382cf9139106cb28d947ae3bc389ef18b728c1568436b3ef80644009a80f01ef550c794011e44f2812ef507bd55820a872b90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2053c037b87c51436cc83b884f7634a6950c419684af3b78d41006467105f753194144539df45ac7fa46e71815f53d2304b474a434b02517b083b058aed078dcf86746313bd8108148ea34658613560ca722a126dda147af8c5733705bc8343331bacc5b5b80e424ccf6114955056329a68a2a6403d65197c21da02a390c41ef713a814a798a434145b9e3a5c31a9614cdac8a8bcab6b5274490f5c45b2a307f492c28ff40ee39c2068a5826e8466542559e9409ff11b463e9a4eba0a2172ec8ea6332d3a5bb66531b670c52cc2f8b651b513e60a9e64795369e0c2cf56a9921669299b6b5399537e112ac358112810abc6945bde69aada92552a10219a630e26e4ac7d9b5c7469a960ac64a6d127971296c53a15df4c847d061e69cc030b9cabc6e58903c5adc88882cac147f2888263ecb6ae97a9b2aa245f131e2e2939f5c8bb8ffc012cb578b9babf90db062502b1923ca88b35c424fc6524128fd1d7b5ca719f5a9a538a51a97ababce07b006eb701ad8490b74462f93648fc39a2004db6e951b4c8219ce49395891594353b92b6b496d09376fb28711d87221851a5fdab80cc52a6352c062f06c80f891da2a07573b42bf0f6cd5d6b63fd4b1c5bf2572fc8460385a642e6290fb79a9b1cb18cbcb34bd87f7eb595f0598c67709d72011fbdd07a0eb6616a88b8e33571bfa7597be4cbd6976b93e32c2c088de3ab59dcf2234e553a5b2ab143c46df13211e816aed6d02bf6c13fa7f8b282237f249aaedbd3a6fe8771014c1b811c05fe86102c0b0e7e9b961c1000c82408d8a8aa381552920803418c49e1662c7ed8c3d35763c510585a78664ea0012a8a02f34b2bd7e96ee5c298dc296537c985577cac3e310568353ec2ca8eeab4bb1ee2393d5b3cdd25305b148fd8ab11f60b5871e9c9359a46a5da003e98b61d82c51cd9262764301c86268db87fa6273f9fa3c35b1c1fd822aaf2f74edf73ab5af9175070bdd7d5cc7600a516726c3e49348d138d19836391a54954ac4a0c029b1441c37965422019c2ca49cfca81317a211e22ea2297b865da163a0ae2a9dc25701e71847a05754cb733620a824f090d591c51c345420e226b8f3b846fd356e78b87764b51d1dabf923518de898c5e7cb5e0066fd69522f5889dc05c41a472c983583333132052a1c93a464120b325764b8665ca42555b98d8d6a93c88a0a383ab51280f52873f2be26e12c131677027c616711d478342cb424b0463c88161ed84bf6e869abe9cb915d13534d2756dd72343359e9911624dc7c6e828b19d6cb178c43a5ceb9360d2939df2744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ec91e52c4030f5453e6bc9103b9c19cd83e69048272855b11b8af3edc09b04ab31179bee59abc76726fbe9612d271b7010844f62535f2f30d8417c35f17c1619b055fab6a0f5458568c753310299fcb335a7697e7cbc9b9eb1b14ac2d0ddb765b266b6d68bdb5b0236895328540b20f91bbd2910625e674b33a4f8b6c1b4f66c4130c2e973ab72d809282ca63edab71268c02a9d020bfc805410aae2dd4b699448a56049d1e9a58c5fc2abe159dec69c5027099a3b57d3a2560ce24a6f5017d32e00f3078b792309384421878cca555b7065d57537c804e10bac052788769b7c1121a78911a153fb56a365a2f97b070d7b61724d0c4d14c295d78be57a8aadb873d3af6b74d020b8654cf48543de8ca22371a48ded585b7073ecee0c44eec27c85b5a68f6b454b0cb10692039cc68ec2c2bf892804520c71be5b7badb807b4059a3d87d32548ba3e4b698ca150d784a8c2c35a67a8c92c68ac0037888b65a4c9800ba7a1ec050627af648fb61c87cc55b8243545aa514cbc550a8804c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6326e0bbd4402dbe26cec08a7c1a19457bc2677f15b984a74fbc52cdce48618d50c47400011b392908ac2cf08a579783a80fb2990cea90eee90b7dd81e6cc9c961372d8c720d7eb223d5a6a16d4571c1a93213b32289934f7b30a63527c6399920086940b7696503e623e63a050f4b69810b6e6f6729e5782b572221f596a09a1879bbb46a62a955043a30a2aa3e62e02ce1ab6f3d03693a8cb653e361d8783ffa37274ae06a3f2292f1a6557182006e493ff2653437a64dbea950bf6a8ca8836407fb489d42a6f6257770310f28715bc6411c81486cef3cb9ab500558f070f4a15817f8c177d63cafb176caf3b2b1cb7b7254c18fe15111fcab9e9a9682f41c9fd247ec532ccef514860a3fed330255323dafe46eed198041d732538c9424d43fe2f5481650470f08906791b2bfe65a445bb26ac87d9bd04aa648a54dc13a137b60e5c2779fe4b5a866620dc2829d42384aea9ab1552fca920f8929b7baa059dea53e6a5b3e492a6e45b5ae11f6ad24d035d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124a81ed4420c87b0601de23e3ccba915faad0c2b47ef6238dba9449274c64ccccd85e91712470e8f9a2866720059a8501c7762c0883cf9827bfd62bdc0882ee03b457be2b2794b8becf74ec0da4684282200a294c13c8a9ff376c1187911121bdd886f27514846f740b72aad5544cbd97a7e208635480acddf404fc067c82a45b5c97829f06abca5201429e9a516f66e65d07075cbc0c60c2a9734baadd68f421617fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f616553b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 4d372cbcf55aeaab39558fa7f1b3936da31e6679efee4b0af81d6b6e94e485e0f79a1a54dc8358ba0377a92eb5270b7b0cd814e464e2ee1ebba10ebdfaf6b53b5875a89fa0b0edadb5a60d815bea517523636fa18fe1780d152bb90d47d593409a2fdfa6b39c42214f709a86ddfa81bebd97ad6d18719d107dbc838111987d4f721746d75ceca8fd414f4055d206fec568c13d1ffc34ba1c243899bb5c16cfb6489c4cc018d39eb93873f520333d8cdef4fe3b9fcc117f291c2a2c1bb9febba997341404360213d9f5d7d80314fb059f57e12c884a4c42f6977b5bf3ebd6e0136da4065a91d9665cc141670e492beb0bf2d1fad2d536f2c0659a8d367c282fa5f117e0d4e0ac05610031e5624c61529b144995c155430063ca9a5e654bc84b1ecf790a635c3e5c3dbb1f980ae8b80c1b2ae9a48eee5a0f5e2aa0175eb19531a7ad6995a2d5a62dc236b596e9edc0c2da79aec60e5254c748ca80b90623f2309201ba88731d63794bb1865912866102fc732c88fc9c511d3a86648e8a5c59189941e694908ed80b513684b0cbba9ea16dee6cebf857b8d791175d623b3eece53235086b45b78fff9fe4b742803ceb85518009f5d94cae007e7cfe5cdfa2aa07d397aa97ac75b53b722c4d488ca391ec0c9f3ed196fc4326eb50b3efd27d0b34d9c9f200d7c74d0e30fc04022c331b55b0d7adfa777b0cce009786cfe71a020e33835012da068158102768cf441a078e5b9ffd6a6b1281f2c6159f114599d1096cc74a1980aa6ac45c8c4025067cd6e947c62a908be3a033367f1828e846fbc78bcf0be2d63a24ddf18336b8524c927a03ba76ce527b84a1358e3831a76e955a1b937e0ee2f006ab0d2dc886115c4fa6c9a7c831ebcde5b1aacbe33a82495349bfca371db6beb88e8ccbd8bee3585bae39a435c491292147e4e4833aa80ede11d1b98651e6d0525944106a454d76c3db9d74ecca42f52805037575420fda0ac6e6be3d798531ec283916e76159c79bb054ea23c24a41f124e1dc887e6b45babb35248f5c2ff7096a458acd6430f22eab1e5a6849fe783e612bbe435aaab7bf6efdb27220279e7021c75ceabc76422056a322afea422b17a8abfa6c3160ba885b3e54e70f3be0e304724cbe24d7b95359fc04642d3063d5191173a84f44f1e930c6c2346ab973ea722dee19f8d36065596e83d7e532505add1ad3ebbee0315d07a10c44f288a7c97ffcb03b829db5a01bca183ecd2dadd64bd2dd67aceeb0d34d039c3c4a2ab7a65c2d7479c2350663b754fd9e063bdf4ea73a04cf1cd0fa6782d46a9a834936f25baf39f0367a3e53298259a48cfc6d0c9ef767c30cd175dcbf92a559cae64cc9fd71eb630dbf78d9225e5cb216beea284440ac4497db0b095c094daed5d39695ae2360859bab3cb62673ef2ae5a1d03c4582764f2270644326a0c4143126de4d4600baf1ca099db5b562f33e9e35504496be65ba3e80f62ea820b8f11c91b64a53e6bd53ca5d62be0070762111804109bb8e1a594e5f536ecd8c +expected_result = pass +expected_shared_secret = 8be7a417efbdd3587c6f82ddd1d29956789d28c2413b8383590c5b80cc53e04a + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +private_key = b04c33b257b199352a85b55624f1a1a42b2ab72c4810b839b2bb2f51a502cd498aa258373eb3bd43e03973d129e4fcb61df58986809ec4ea4333659f03dc0fab236cd4e815d3f9524e90a28a3a0af869735b362fed9837855429700cb815c43a6e650e54d6267a832dc0385696274e1e73a12b5960a8409a4b4564de909b797771b4839782526fd69abf516a73f9eb8130f41cd6103a6e67c6724186d1c709d3d90141b1bc1c028e28324de4846bcc6837fc243c54dba144c40fcc6223fd19b8f54c11bc0982ffd366530abad387946e1495a3c05d9cfbb62b28778905ab7d576610a74b3daac9767a051b153af7c6bf0177a4074397be410411cb33ddcb895091990dfb85aee15e9f288d01ec5628034a4adb01da09283493baffd36d224b1efe096289a2afd427b82f8b04ea44319f4a16bb07bd21026f2ef550b919ad01cb3744b37103eb54e62400e03367001510776698e28b4fc367a77f1b4690cc2916e8ccf1fa55aa3495014724f1e66ef7ca8283d917b501c931274d9808a8103004176bb69783c094bbbbecd5b90ea14e7cdb9768498b22332283f6a079991988ac6a85bb591ef299bc57027b0ca9932a41c14c193467374f133bb8539c2d5164ef11b70b4a2cfcdacdf6841cd835c4f4e174be3c26b55770acf4137666a431d669fd5775a71749922c0b223abe36284fc880c3aa2a41f45a4a299c647d6738585287f7a47b88ea1c6c088c6207646d99cef5f56a2e02cd3ea85202c7725dfc99d04b2d52600f0f89366a3a83f8dc74e4a27fc58a622061a6332403ae8cbd0179149b841f5e0ba193ec237ac57a4cd5528c10545cb75e35a20c3ce63950c09a7b0810b84124f3a00c9ebb67bda9b2ab42113e631123b4a85897160637a32eb856d55c2905f7c655d40c84e92e773056d2392d43e33c4f9256dbfc7aa0683802d04d218139f829ae362c1f48096fe47b09756c36873cadc5300cea8094e6f8925c1b81ade69fee5420b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd53d1235800681dbc7657a777bc267637ca2954c09344110a05e2bb90a83f95990986fb559bb1282778933631701393b705a5c122ec3645c1b364367c83444d30fa438eb3a478a0bae14270cd49556399085c566d9e6c467dca66a3f36370693ad5f86a9932773ae5064e9bc73ff7979a5510c88198beea7ee2aa494eb046e4d70a3f9ca0f88b234f6918f7eb41db97a327654836510276e0154e7a4dfa088b8acc5f02f598d1494bfbd07c3132c5ef6c3b466606b3d93da2e69c96744095435fcacc2d24c3016002b5c4b988877ccdb9233c490a8b121ba7821b529de85e638168b0565d50f735d1cb54cba91cfc1b9eff882a643121e877c43b6147a2a8266196346859ce53340208253ca419276b884dbb3b7a30ac3de983c75ad73995a0b62de7563ec9a4a715bcdf376dfb6433de691c54e660f4aaa4b184015026b6189415e66c90dd32c0b015aee63b5d8b3cb9ea206e45ab4938bc86fc54c7598c6553c29ac34b2213b90afd144c8b4629a560382778b28d666667caaad49633a8f985730318eb033374b5cbebacc7f453ccd8e77c5a9abc12da1bc1733e5a1278bf11b37fbab1db212359473012f3b545301ddc833c69a75afe16744557b5e28bc0ee895da16c2c5dd34fe6783949d555e580c1be7994bb008daf27a47f554932b87222e82ec670490ca5139ff49d5ed896218825056a8639b31d3ac8550356a408a01404c6aa9c2b7284e7c7c27036256b7902445dde00630d81930f4ccc518b9efd8ab24fc16a365b8068c90f7e09bbd23c2a6ab12792d245551a9894f704042501c8fc49eeaa0132701e29a3c97834530a7c61f1b8440822cd1bb6b11dca2a5951b4deb0b1268c2f5aa8cf76a6bd0be3013a37ca1a903ac634405ecb3714bc54610baa63bacf0a263d8cb018b03b0a286083998a7e8b2a573e570179712130a19f9ebc2337d43926f9c96460996cc03199d81a0e19259da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f1f211c6d85499c46746bb00ba687a17877e6650c678d13861337faaa7045a16b8eb7173e7c08b6394b5f2b99ea3083ba175c55d350fd61b73aa790ca6f479fd4b01282b6baefa00a1946f6dfb855ce7bd50389d42856823301e01a228ac754cb65a0e323a0943b75741cb498cc499c8649b6bf87e991507194983aad1b57994b7d79bbcf2eb3b5f8734ccf3cea2662e95d486989144aea22c94c363571ac7dcd81f577645cf19b313f849b422afed963cdb701395020c2d18601a40a42429896aa9b0b1c10c4876928aeac59862414e143722a0b94746abd157343d15bb9fe500763b18c61b184407449b1b5ba8fb1554e4bb58ab99faaac9cdc3b698e64179b089b786204bf95eda86474ee799440478348989c91c3462446724340cd2376c682907edb58c85a4ce3ef46cc5d0ca345590ab14844b224735dc05e0e66ede94258f395fe867ab9d8c1b0fa80743002a15da197614295dc358f40758c9cc05e45bbc659b93ed611aa58845d94acc7aa75deba56d4d83c640c252975bc3165254c92957b78c9583b370ad785f2c16cd5cb9913839939c7293e6b956e23cc5d14cb3ab2a2e94f179bb076355157920085236f60b84449d43ac89c2b46dafa6b784438f3510bfc48357a5681043ba7428583bb5e912b08786562579df58a41bdb82114344b3ea3574b997f8564248210d4e50ab2277100b9a5423178b1f138e9d427762253cffc3cd095cb53a776f4fe015b5168b1a9759ac4acc77f90c69b307192b7b866753872a69813b1bcaab5cbb8126d8998e78d99f5a527992b89495a28e3fa83e75337ca2b896172ac244ab7e30761c8e3a00890046e5f599eeab65bf1a4cdeb5791cc10ade7197fb5bc754233f3b10c9ba2240adfc61c05231c36a6cf71aa752ab3c95c3756ef9373b677105d11f86e68036348bdd181f27407e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc4872617bdc17a7baa97af9a9322ff015956678e8d622cfb1a11ed929f29bb1f094c17f49417c09c1c443369123caf8701199c43bff97034efc6999424144c9395d9063bb153c0ed82b1c5659bfb23d4cd2c758a26b6c448525060f686bb14873cbf5046b3a3033c5c8081027bf5e3c51f6fb6a1d54a77c46b0ea4299a9da4ab03b95f9d3601f553d46800f661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a759cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb6356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = dee3cb7f92c8c7b79465a085e92d8061c7234ed5c76ea7548e220737a13fc67d46246d0331fc32d43b0094935c1e709f03f0d40d9f4fefd86aae871ad7bf783e8a8fdd6c690a71901970b882861591ff94792fd0bb16c04a6d5cacf617032f4efb3d032254cd04bc5b8b209c5a1eb3257bfb36e986dd6824ed046852b56f821e931973aff63ffcc586892c58e854705935c44f614dcaac0aff6b78a6aa36ee7914548c9c1413e8b90ab7bfdcde7c5d7c2619394e2dc8508346c187d051683299c041154c3e75939d94afdf3e76676d3acd2cb4de8bd4b6094249ce63155c87c561396dcc300c699e87422df2c8201196b4f320c422b6239e072f6a1ad5dd518298dd0ccaf2da7093a65272b3eddae908fb36e23c00a49d924787210ea21342e014dbf9a335b15c62cbc5c214d27c17a2b6d1c185d5bcd7cf15ebe4a8212e97ac11008ad0e645cc02ce0c7b313f672efc67776516959bec21b66c9a226d95c9dee529990fcbdc8df96b044998b3f1da1ed732e2301f180d0c419a8b95bc6584440bf4fe30b305023570eb91b16dd67c432b0f7dacf63722937bcb45655fe7445abf8ce2c946c03c4c5fe2274a7231df907a5900a3ee0f36bb2009eb4abba41d4f6c372ed7e825d99e0fba3ffef67cd52df38bd2a9588198d9be63cc980e909b978516a25e63302958e3328c10fb61375fa9c218b572b880b13966a8c483ee5967b22cf7dd7f8365e765c71e8f4bd57e70b17c8b79bf259d517826f2780adaf3b8e7774f3d9122809dea47ecb9118671e068b9c9a10cfda0b2a8f61349f0dcf623aabe70a5421427511e48c45e71553072909b8156722be3b301e421e8f9413fef0efb157845c54a593e0e7e37027b47508ba12a75f340a566a4b984226a086497cbf79dcab6611e0a684cf238d7e26c1114829b1e360de4bfe688f7405e5dd46dc3a31ae538d2177b17ec6393c1e973f69ddbfe3a465ab22fd2d2dc3035fe53983c807edceea2c7d157af345cd87c504983502c9d8b52fa86a7fbdb748cd94faa0734b6a0231a1dfa1a36447ae3a27ac1b9d39c0d65b7ea0d8c21ca23d491c7bd64c8c4495fc90247cb5e1a539657e8dda18dac206efc7cb8403d3f9223e800ff2c961321ec5ef918b6f2bf959121cdc940056d06d88910cf622fe70a5af489a069e58277305d9342c05f403ca9fa9df2a80d6dacbd00a6e622043c7f0038da2ca9b49e011bc73df548564e3f55ece3897bbdc95142857aef3f31296699671ade99deb866b55d738e23bfde2ca6d9c2f783d0f1246c3dec26ce19e4b176fbdabf19157a83d308a9e93f65c285c494f4d48b736fbad129c8ed1e12e5174cb49814e1b53ff6e1265e7ef6bd00c969c6a56bd34e4af851a40399a749c4c8f939c43bff06878c7dd80612b0c3cf6afe9c8392ff4ce10ea9ac601523e56f7610d23cacd60609bebfc37b9a063377439d307db2c14d19ea22f19141e80e994d988710045b536762773c12fc42da4f1f9506a38b9003d2eca9a4b971822ebd45bc52425e +expected_result = pass +expected_shared_secret = 79fcd201101e7e277c1b6cdc4475d63ea1dbc42ab94cf873bf0163c2aab0b5ff + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +private_key = a5019e7b82405cac3c8f45bec4e70e20590bd7e543d465ba702cb1447c0f114cc44f404a31b091c638347cf5a464106a2f92a0b4e600a3d86ab9f57efff088d1887865c695c3aa29ba08356da1b4042146e8817f2bd56bc014071b896d5b2cba9fa124cba45e294a0f30fa01e4eb18262059cc987c64f9185aaa12d7ea1f2780308a91a3b2f171d9c41d166872bc7b070d44af8556a356b631a6eb2e804cc09c531eeca476adc8143eeba767298bf29c19fb2496e0c573938babcd749ee2d02e9817a3ee5a687f9324e7e1082892142c04ae9715c4a6980d73c6a54c16beea97a659da476e49c1dd1b8292e04321783e0a66a36267673e92c2c7463668b1742987405c1621f94b87ce88aebaeb7bfd787116b30a5b64a7e8956321463b351a9753a0389937b7aed431a5028d309cbed2d8ae67f859ce371cd1b3cb11a8a70d3b9b92e15530a260d1874118ec505fd451897712ae4104e67b1d2bb2676589aa4e8833e03b017aeb2666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb325144111c75e96a13b5566e8258e36d34a76096f9b013236b3036bda5e3d431aad3ca33e9a0916d8cedcd3466c75c1b5603a3e724c60a796e0844cc0d79686f086c510ca0cb11c2e936ecaba446560aaf0931c6a82298bdc7fa82aa6a0b32d361b3335cb83dda38417720e9e745bb9ca008908cf6931ab2b4a7b78036704153359dc4fdb5742ab3c39a346005374cf3107b95cb771ff1c9592d59c810a93e3593169ab26de85077dd79a3b3aa03c332a9d177d7ef88624c285a90099d1d0209a0bb0c425ce6ae9221613b2cd596aa77ba2bb98a385d2898d504d68117ed06233e69c43b541438b3274b579c1a5c27b0d85159836aa48907f768c97b6b2b19f475655022691182b2d9c80aec12eca0890c9e47bf764684ff1a94d1083d85905212431afe09342004b44a090cd71357d2431c923b3ce08bc836b3edb82ab2fa3c508867eae87bf2768ad61d4894b123b6f861db52b9b3eb77a8c99839e9108704c907e258f8d8001567078037aa1ab87b03a46ad3a0a30c753b8bd790923b7454f84c67ab6bbbcc105edc36ab6ab67c28c1d3a54bd06f9c09c12cac8483e015301db6650ca3228abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6600a0d40489d0534423776184c85057ae00e9636bfbfa76c2d329625747968f53d1eb26cf4f95d6cca45c60b2da0f1899a7a1fc651c12bc2c3a2ca16d8aba4e05c0cbcbb2b72c48ef55403462ab49cf6576d8c358a865de1f795cc0629f4b13837b6b1704250b8e97f7a116fb63a0dbc12c955b49a67094cfeeb0e8c7b23abe4bdabb787d3e45ead108a96d3206a4977aa128866e596dfca9d68996d82021a4380c0991561ae40a96bf490dd5538f0718098479a5763787939453a7a87a359643885bc5d6149ea048b5ef1adc65c78e4a9c917160bdc625352596034b3558f98637b33061f769cbe341f9c764238318882caa978996d1c321a92838d109c187011bf84d17fefa0271eac7d5ec90743130234e79089f5b9a6f0267813939b5a3b22321376fb1792d8bcc4a90087866b29244c3641310e94b8311a1303465975649288713e79ca67a9085c8f7449c0bb9a6ab196245b0da028cc1765a8ba0501d5e360cb3064e11554f3fc2914f1260509073b67b4a0570d7f708ca7c435ea987762f2a5a23cae53907fc9db26942136d72202d0a0bb10b65d422091abaa1c21d152dad59c25d20c016237634741def8ca26b9cce3097ffd896f1bf08300282fcb7000c7e1956673223902ae5b43bc63b6806c469a4ebb8bd34b057b375e725b07ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdcc12892d588d06655f6103e033547cf5933ec237b21b2956e5921cf10a0c55a70e4a24a57b93f6fcaab2a44bb079987eba57223b4b9deb60ec6464faa4058283b8cba6956c792ae8ff9184e93c2e2152823c15412c102518462c2691db1c64412eb1ec6d75d47c82fc5a9214670b3297067e30c6d9ce0cf3eb314cc1a4cf35342ae419513ec2bd47182c4ea52626a56f7831dbdc5719f532a5a421a7bd5a115c2195d0532e7c1c0ffe40166404137a5b45d7b2cd31752e1646588021508293fb881123f61034318700eeac429500905179b283162ed0b69590541eba0848decc94bd18c888170a4c030a89305fe97a2b0292390a3b1fd6aa22909cf0134a2754728b6fb5180276b7d65c2fd530b4ff48cc7c7093dfc2b418b97762c42bb0980c7f41d9651c69387173a6718038010f50b79b233187bc3a0f7c770e50abc62e8acbe297c58c58055387bc7711473d81ca97b6a6e6504870c0de1d806e3603ed0b04d01dc62529434014c5068c3ab3d4a909a079947127a8a2746cc8126f0212e21a0318ef273d5e0be16253848413c5cea22853c6e63b675cfac1d6590004a2bb3bb4974e79aca0dd927607a71d4b4c9980a86e5a2b5a84bcd2e694190491060411b332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d45f72d82ec24fb268537c07b81aa79b5b28ef5a657e0f8b6b2f3a4279abcf06ca2a79401312943d1d1086d91b1ad3030d0c0bb21806cb87b56ed391e6bc6aad974034664b4902336d6e45a7449cb656207d59367f2b142746636e44726f111603b28670f47113d28ce6bb11f464b181cb3205febc13cc70d3fb35924a641a1117df5cb65fd9a69c71bb800fc22a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ea920e4f2275f4f7bb361866647c04c573bf47e6b54cd31810c7814ab5cd27da1905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abaa2229c4c294e7a70f97bb6d119be54553eebab1c80c8da7459258e44a234357a1c9cc46412794116123d21db27455063672245460ebc8b6b1116b34f2401169ace16a514534154e798ae3155809b651ca963f854ba501407920765a14f826dcfa4bc4f21766b05bceac55e6854f1ad080d9b2538848a8dc7857f10c4c843c46b172adece3707e01c03059313bb96bb144996b127a16006db4063ca1251f550836e167adea545b3a0c55c0ac5de3fcab6e8242c2c5c09313646117a95ef46536dc74d869301335a2f9040484fb0c9cb85a3d034d55b03c66725d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = cb8021857be83d6c14856fa999c0296939540b44fa0973d41de5a98a7b8ef1bfafcb9b16885d777ac157f018f00899c739a8dea7feac36c5dc8402456f565488495f4c236456f7775424bfe331013dd60a242d436dc354b06f76a46e23f7ccf3cc398ca8b041f2591245a15452248d193474589b275e1a7f1a9ac3c7bb651bb17e5c4bc116d976dc447565a29497effea01ccb07220b45919790aa8be2f63dde259aef47f135456803471932046a51b0ca0a0b0418f989373d780f865f890ca055eb1bde17bcf131a956be72249d4155d35b2fd4ad28a59540d7334ec453e19561697797758c413829c46c9487a35024c67dd2bfc3cbfb2b35e556c1a271b6455ed7b9ad266a3b246ebbee224616f23cf9aa8ccfcbe019847ec34ede915970f2b7976446133c1862f961f4f059ffc9f722f6d267929819545a9fbeb6f03465339234e98cb6629aaa06a40d6159a94aec36f39b71bf0d3bb8ac93f9df0c8043e9f9cf17e78066a57c5d10d2d27dd9c0a8948275b14c82bbaf7d8451aaeaddc8eb2ee2c768d2d19d590c1be7af7ba30bee182b3de636125c9dcd80d4c64624d2c458cfa5f30fff16d99c97001404d6c64c5fa89bd225abd0a647fe92a0d004f270b7dc84a88e35892abd37a3321396815a63d1305a9dc7e495b592dd80046c82c13347395a6a92dfdbfd8fe1f7634b472f266e603209df3ba334bb0c68cdbd6d6724b32452938ea0dce4c3a6596638b0916865566586cebae4c0ee3ec36c782ebbb85e583c108436852d4545073774b2177de52f9610f7d778d7eb6d2382455965ab5b3ce9816d0995247945c31c9ff479587a9f60058d0867d5bd7ac12a3ad9dc581eaf7e4c5766829f7f8e2935bd1bc159b5e27f827c85bacb41f2ef5ff75666308c6a28765d6f2b261805bce28c6ed48cbe20a0945b31f59826be0742c711054a2623abecf9245fc34bf6c3b5e8f2f66114af277812c773f0470da69d10006e2dd44180713eef89307c3ce79a877ed3cf6f63acd681cff64647a3c08ff5a0c4fbf7c8a80b4bc3336948bffabd460dfd548c62e6167a24e841f13e1b0a868bc20e9ee55f9d89c44f58912cf23333a9b04e3bd813a0d2c61d0d087c9bc2783476dea746ebaa805de06eea87e7c50a20f1518bf6bcddf09f635bc1145932b4b323c4614882277130315ca6e5e3cce1f937de71e39505235f0ebd8e6482a2845ead61224bd8d84398d8816b31a0b178e95c0ba50f9757670e2d23df3475ebe38b6e53d8e95884fd60c38b3502a762f6ff5078188426a87c6502ac7251110f29e16bea769b1ba2bb27458dcaa225ee7e35397d3bd8c2b82401584b666fad035b2b99cc6d518ba1df7918464eba094d8297254c2e804aa06c00191af19acc9139728de08f19689a2507430b6e2597b1e5284815fb60273d80c48d2d4c934d813c0e1bbcc35b855e09ddae9f97111fa3d1f12cf449784012170e594f6e74d0646691a09a6f8956b815d9e3fa6265036ab2aca4ab450a62645155fa81ef4efa44682696 +expected_result = pass +expected_shared_secret = 6c4484b6d7b0a376f52abb1811c712368a9f34bd108ffe7ca31c36a6ec8140f3 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +private_key = 7ec737ebf52eb7905da8b3c58508928dd74462e8968a1265bb3b9780649210c8202e2950ac11863bd78af3123ae9899ceff1992608cf5bd1b4eb0ac1c13ccaab4ca89a869424bc1af777cfc7d90a071273f5aa5df310493fab17ce5b6477c773d8cc81d995509ff3a40ce80e734a9e8968b7fbe79a9900ab85f7b442077a890688dcba0bd5e64ae491ce5d39b554e6b82b7602a149a686c19fcee21b8e3b1792e7529f2307505c77ed84a63a68258e832bf0f118bc05c91a6b216ebcc051b90143b9748b365ec841b6098c4eece8aa8231bc24b03e732a0ec55aa5b0e3231efb7c7f0ab21e2544072c22b6b4075049b63fba05c68a936989baa2e55ad1846fd1e335568b01d4acc869e710357708bdc25db545447e41727224545ca8c16bca5458eb24d746a12e170ef191cc8dd840e26910cd9484b4e40d0c7446959a521618b9bc472c8001ad0d1c8428c43c0fb3230fa9b17694284375a0e1563fdaeab6cad367c9949c4723802d6931f0c212b03004675652b958518d31c8d4b06dfd99820702319e668dffb5c88622170b0c0eaba56ee7b77ef5d7600b9c0bbbea5b99e05a9443bb81a68c22c7904a1755d4c80a47ac148ed13c3981c6bf4122a7880fdd597429a32d6046981146743ae85cc8c0ccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398a9236d02bed9b951f6d43a67ea06f7fb803acc33e9552e7150c34003a2e2e11bfc0badfc537eb2b69122352ffb62b285b6cb0935adfa0385dda074f7a63adb76bcf4a80aa83a1c32f87be3a786537acaa32178b136c8bf817ac1cb1e25b44654266f4b2b14f33358b9b75a2d916d78e89d3cec68b782734fe052449598d847b2a02c3056a64e72c5a3b34685e9fb2c0037736e0a21df39a356310777a36fce908c243a4a50216b6199cd63c7bdb18b95fbe4615e9799757176fa4a88c93459bc3030e09889ede148890cc221362472586e3c026b0dc10ba5a823f07acc1c693e9bf31518b90359b7aaec54473552835b3590174109337b6171eac38de29bdef8095da13a8f7014b3f531fc152ca5eb19859673d52067e28c7513141245376baf368b07627fb1b844fc033361994ffb3b39822a2a2de17597d16601329866f42c3697a6f5132dcea2140b871480e50523c3c5227537a5089fb6742cbfca55ba9c307a321abe440241e34151b2c2aab6ad55817b115330c0b15891fa35bf344be7d93ad44bb27962101982902427242f5b06f85204e738aec7a333a15001252004b21b5e6fa95a41a4456f74c9522657a9a40f8c4a162f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4dfa173b96869fba6c72987f4b328a0e56a08c96a00d78854d6762ea2394c2a102162143cd40192749cfbc5031739711f1ea8c37db5b635bcfe9b6396e2902d56bb135eb8975e1b0a171258d39a7ae84aabd46baf4dc2a6ff18fb6002ce232b7a45a532dd54d3da8c580d6cea4209098930477d207622a7cdedc2e72c24eaf5787d4b2b461889d23ab93a4ba327c371eff58cff7f65738886abd046895834aa06a6cb57973f1011353fcc1452b015a324c406515e9290aff4356fb393b57f4066077b2152819b6a69de9718a491b3262d206be72a9ceb000e81b6be6668d14a124bb49be524abb09b91942a60ed38b1974e36376a7724ddc7e5a993ea9c25f40b80c766cc57e807bd5932603403458b84703ca58f8e57c451227128654df4537fce6a57bd1bd6fd8c5be1135b2c82cbfa4b96d577575406f92538034d22d6198a9cd000fc8dc8988f95608c1974c4359ada14f7dd4870c63bf79886ab2d4cad1c89a8fe232fc1c8c515b7d2aa9cc35759ef583244ea767916478f8415fdf7b1cf85a80f4d6960298b977a7abf380709ef904c1706ee3f51abf415028321e4fc79fb2e15454c47b3572bc09c62c0dc466efaa759f116e8ba4717f91220f125656ba7c52338ab1facb0fa6a75ce61f3135911d5714fcda7a5a271205547018cc0607c5aa7104a4a77266c0525579f054ecc6c62522068e79352ae7a1c3265413459939764a4421caa937c8f9b2b276a2c77ce7814fe9034783b8aec29881e2563a63780cbabbcbe72501d68f1b72c6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c9621bed149be06aa2e72f72d1b24b086836b525915b93a49d90cb3c45877c54204a605cc27f1828de6ca1e95056938a6c9651eb3b4a9b09c5aa9fc4401215d9ea9015a996f9a7b898cea466ca14f0065a5b1f374d422b4a277a011f3b3e8143b053507bee829e582528dcb3c9e950f39d17ad0a849c701779d070e34cc606c84a596650b7776a468659344446bc19186b43cbf042516a7b133065393c83b85313c53b71a5bc4421a91694beeb39760806d3b910aa8ea546f53763b656c99ea50a179986dc3786a554b819317fb58564dd69428bb1d7bc45a642a8ab9cc013f932a67222d1fd42b455930b8147d6175c66330217246c400c4b619b922182101b2d8165f93bee58757c14cbfc958552137b904009fcf845321841f8648b8f9e58d1572119b11cbcd59480246a46e255adcc1649817a052736ed9c18a262c36f7c37918db789ab177ed39add0850a509319888073b54bc3ed81000c780fc87ac5c302235a959b1164b491001b92811d4aa76876065e841b276a27b868822fd1da7c3fd1831d88c9f5d891ff610caf264fbc9280b8d4085251774ee20c23576ace6215b3eb8c1610ca2405115e89421418a7610c05bb526ffa39918e9558c6cb2618a612b6d38bf8a2569b4c3ae902a4ac744ed4bca8ed783c4eba450470aef5ec5370b87daa419145298170d64caafc2eda7c989645b9285a3fbd16c16e0c1e3fe085a6bc05248426ef106e7f6012e80882682660cd05ce49520785ea66325078f9a91e5ffc3ba0833de333326fecbcd8878f286064cd1b672f210133e30d106c61af9a75a7fc64fb5b1e1a1649fab356c0f26b9062c5dceaa7cee502c750a93187a21c11b1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee70253d77065c02926bfd9b031260b5af95846573ad09c42573c8338609fd3e5c0b50092b17a83128a4a9f1a6a232252884504846b3b7df82981dbb036f6a57c5c19136789af9690a978145ea6adb74132ec55840965083f388877a93fc01b006fe4cde4012a1814b327a12cca8991cd18027f4485b4025b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = db57de9e2cfc65b4ad9d944d6b8968d8ef73839c55b96a77ede1793f2b8ed9c8bfb6e3e711e0f947d7789c97960b9598ace9109d603c97474b5829a5729fcb19d2232f5f02ddd2c7b7bee5cdb042d2e255f986b3f6c16666a223e49b0316028bad8416082fd7e837f208ab21fe97d884d05b8bebf05c206006f6c94527398a204377051e15d2115a998faee7dfaf49be6dfd6e3288226106f25f2cd89c576dc74bce95538594b6a72e1a0f422d6f8c49c5a5eecff37d2ac8d86e94a65e6d95a1c421b83719b30cbc8a39fd82fb21ee981a2bf86dd6cb0a964b1fd408d086a86bb2fab39dab3bfa25137f7963e94ebc54dd93148316ef1c6b3b9f8d7af85264c7ff14b69cec63520b5d0e4476a693545c515252f879f7a68b4b2132aadbb212a4ed8c6ca154db4ca7299fce1d218bc95b4f058d77ab04989d918e712c266417d2e9b72b2a7c128f4b06d5131f92e2fe4285fd75412326d29bd9a1cd3efe33cdc3a5f1f404831fd7fee72facb4b37d42d33a7799df32122cf349ce0d64b8be5980d4cc140ec58bf0f52f304fa035cd6e0a9edaf54ff56c9d6aedfb61fb1c4aa597bb87298403fdb140be8fe124f9a2c8070719f1a16c58b2093c645319c137c1f53cfe9c267e00502a442918121c922cb6afb3befcc19321f067a2838a0d89ecf94ec88648a64218dd2f2fd2359b31fdbbe1a616daae89f736bd2e16f05828e70e4b9c0bc610041900a29a29ec5d7f3cbc0254442686eed9ff7aef4f42958dbc30b64352b7dfa97864122a889257a5f4ed365fb13fcafc4845080a8a4607c31eef8e8a3b49a0e4b4f6de1e1d01e871c87ca0a191f69b73c2e773b64912b86406786d4c90a8fa113e298871acfb77de35138e2f68cb2bf8b26fd7d464a02d2f1664d6df49dccdcf869a8f1adefcab1f1148bdbc97855a6ebc160394164663d04205828b711e62e8accde8c89f4fe02b2f1a6701e28a364d10bbbecfac9f113a3db495d2720e096db5562259900ff6a2c6a0be74e66012ac2e7360daae5dbd3ad6825dafc23491c732e6328f40e7af2cdb78eb88f91eee5c8163fbb3f7f4b8cb8671f0d6b0317432b4caf2b6a077a712d3cbc68157a2b340e01838fab5f22a28e432713a33b18556076681ea7f43f48cb0339d360cb6f47247220e23f313959c39cbca191b1911c9939aa541cd2d95c7a56338e09f846c4d38080100e82769ab86164bdfce24e68b6be20483d761981ddd4c963862fae0e9fedf619dd7a3e8e64561c1fc4c778ebae8741cec91a4d5161ca7f975716d2bbb4f50536f11710010aff928a03118e698e2cd20edeb34da6675ba04224cab7f5a25e1b1d9252971bd79d757362363c5491d3f2b2b0b95dff046b7168501e3a25ea58334bba7e1574bbe1c77fd4f66fa424313b095ab9dab5f810f818a9bcbf31edd63980ae89bdcea8306ef416124a06041e8a2459219fb863caa7a010843b4d41fc28abb73cd610208201e5a7ad693998b19946d05c563a8dd60e706ff5c237a17d875df0522c72fdd7a +expected_result = pass +expected_shared_secret = 8554d6af350f13471cfd45c23882e43dc81d8a094f6299e2ad33ef4c01a32058 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +private_key = d62c6ce5e7594be682a8167743106a44482e3a79ce257635773513f0b0bf77a161c8274a705b93d2eaa899d8c0126ac8adb7b3bbb5891711380da1a9de0541e4160dccabc13a165b5c54178da95b919457c684b9cef81e97637c73f22a3ce9295de79bedd83c3ff871087b9412301863e291b04779457807abe4687368c84b3408e26aa30bf58bbe4bbded32adb03607598714464222524b3c2cd4c15f98a2e6695463257bb8fa9a84131a64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51af611d4bc03e20cb12a216072d7834d996ae99e1cc6522a42b48c54282cd0ae8cfdd1b874fbb4ec17434ad584af5b4561bc1597aab63390b60fe7c052e57846e1a8c4f6c6758798b70503507554946382fa6e2004a616a40dbc2b0c596c2cb2873c38e6ff82ff159ba93563d23671dfc433949d3705f398b3752680169657623937a8c357864c39d82c16da5c1ee407fc7fab357c0b114965e89815409964ccdc54cd8d5b17039aa9283a59e746a45a2800e4806064683c292b425c18f73aa2f720a6521a050c5196bdabc9b094895b9527759c1a7210958e11a3411b05e67097fce2c11ed024a85a22684b51edd652ded89c23e1440ca5616bb754361c549776222b8b297f8f4bb7f818d3b29b16c369cc8ba9d91e6012bf006999c7057aa2a44c30237314079b2a55c63990c3ab657cb80d41022651097ed680d200195be82a9b9d08b24f039bffc42c66459b0c8889dda6714b63762494a5e6106f34223990772b1cc12dc660f5be62eb0a15c16d4a0303773d768c7dda7b749711f7c12720c150d30ec6b625624e3f94861483be03271d8b05780ab62e0294a8cb193238530b49455718c872428bea1d84955f54a3bb619dadc6106ea3ef27094a085634624377312648ac46559d7a7dd902497aa9f22879d131a08b9223a05e5b76a00807225b304480f6105cbec8a11cea18e8910a9bba691047c95676c9e2dc7ab76537691dbbee397738c613e1fb00a79f06698c10ec26c97dc00b82a54af572a02801aac20983311f42bca18699a2684e4b5aed83c7ad89a1705f1605a87cabefac499a56058d8b02bd597743524a90c3686d9405e33c3d70880b6449d41a76f83e23759664f1f301d3935998d690a7167afa11a59cf8b87624283a738c0d221b1b55453504ab64fb89824351a49ebbcc291465af92f50d7b53874c1190a766dac5e70706f88097be4500942534df5e5887c48b234c11992f32bf3f2867cc055d7d6c3a4d25d2a141be7d706bc1203814667552888e3bb13221a10dc3a4157d811a7ca23088ba5aa1a3fd60c0c6af29b3b52aa6da319d8e359d842c6dc65c29eccc0523115d15b19a7b90d1090c5949cc66a004f0a0513132640a284a87384c7ed06782607584bf5cdd8f099acb0229cc9588b024b0f3b5ba80b962218b3bce4c0f542bac9e8c235362e33ea30d789094fe82fbf64569907755ed7bfd00c3f6f446deb00a27b37bb92e454aaaacb69dc854532c718c85508ac8742c7180ea805a78999111915bd414275e92d75c1953c10968c802e4aa6429eca0a5ef49fb4046ed2c93914400b0d882b67c275c483037e859c8c015114345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea81212eb91339aaa4bfa87a197a04d46a7b666837f55db6f16c095db449e9baa879ae14016ea4f8ba975da26cfcf59401237accb908efd17146e9439b1473bafa07703f2932d5c598276b59b419402d681d87111f70c20d2710e10a407634ab216907d7363af0bc4647dba208f9c6744d71a8a1c1a99082a3bd8a843e4ce581412f04877edb1709d1a9623c3c428eb111a1189073c9a3d34ad16aa1f1551a07e6880147360e60888ddd5b0956036951021af4699c96382cc0c16b3f0b960135391c6692b0c556a5b9ad2f8a5ed0cb0baea2406868ac6f7a5a44b722721535e098fe832c9af148ae027604c47ce4d3214a1bc974675289ac7bfb9a644db30235a664417c57a8a46a86e18a10f81b87f4b4727f7234017088f447f28680b0600ad1dd672f0ea19e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d0a2042c744555049c48b2bc2577738a698bc58910f55b0ede555b171838f6086ca365aed981aa5354561411990707bd3305cf4d10161fd3124156691daa5cf3795653e2aee1c4ba021b0edd0809b14905e46c2cd0bb1e165c8aa428b180ea394e6c92bd6873e12328e5e1916c94c81393172df3815127b937b9646a783524671fbd8b5f01395178c6a9ff42c47d8b25fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f27640fe59b1ef407110a317cd72023828192b131cb9af96899a69b0f51125b2828f29493a997a33023661bb7811c4593e4e579f8b17d0cbb6037d9273932af4eb235f7d01dd398b70752a925968adbf56cf132b85680abffb937c35425c244345e805bdb608cb0666984775ac1852690908cf2a60214f6a888004aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f52f10d4a852d38f5354981cdfb7a851a675c5a01c2fbe886192582d1f08ab37753bbd81ba6d848949731c99ba92278a2833cc11ac3bf603512bd6557f9684eb980c7588424db0c1e2bb2bd09196a7da29d79208da50c4a0c839284a44d8861706e991edd099e0b1467b88948c89778787c26dd4436fbc4bfd12b0acc00ab4d85b613bba4f928bbfcb04e2eaa51b81845c3a710bbc8458027a4f055061d0b39ad28482646aebc5458d0e70d396c99a0b456837376110488f49a83f48372327467ab87870d11b3c1e6c112ab3d6d486a99bc2b9b368a0695c6c6251d6bea5b56fcb96fc23475719b8cc82806875cad772e4716332ffb02189438e27097e565159e4b1790558273ca887fca2a6e7226c53879adbbc07ac1072e6aafdd2a1dd89677842041f33c447204a3fb91c1e4935111ac739cdc9fd6f2ba8c0c66dff5552f3b2bdfdb19d4f65cb3b23777292cf97cc54bfbc41ed041e53318386173d229b9288c5d68e87d0ce2032d481c46b646ef71940d97af370732533260c6ac943272866bb2bc90ec64424c67b1c877f5d2b35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866a52385c85c241677f75487d4156c85db639ad741e0412438bdbceb6092fa14501fe1c5e95d90833332debc0441554a8cb5a8f7826b047882b415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132606ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e46858e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 434defffdadd10d9567ff7de185a5081952e909d1a43b163483f8cbffb19f07b20cc3152c39709c3769e3152a3870edffc8dd78d5c9e26622d7b6c7aa341c60a5966b69c71265d8881fb94d9e13efb08d0a738b857cec7fdb63d016c025fb66e1cf8ba31961f56ac47871c7598b4cd2679fd7ca0ede0805c76a6f5564ce1bd748559f3db064e1da38f33cbe9c993c7cd1476472b4ca2075666380535d70176864275e438a543766ed89727cdaa4da0fcb36d948618a935ce49fce7148836b35d80f9885e82470f3ea9e321783047b136ab25f3cec80fa385f81722c0b02e924b7906ddabad71b8607353669aa8e3ab3826e895cc43b55aaccff387b7edfd035d39918738dfa7930b4dc7be3b3103552898c590ceebf0660db1b9d1fff96e339bd7845d6542418ce34208e662cf2c18104971673789c1c429aed0f0212868a808a5d6bd5152040285b8e7f5294df6db7129061c22e16595c57a45deca829ea1fefc4e9fe7d25a7bd5d17981bc9212eabb58a6ba17231753571f6f7f2e1efcca7b8e8db179a774da3d2994be50f8a32dc18bbcf606f73b1f72e5f36286ec13b576a013786b5af3621473719a2e069c0e59b1de69973ec0ab482a0d34c0bd4e815df2c36bf79c5e2bcb511043bc4e6802e7fdb358c5994537dd9a6e5535e281627a0a40576befe4d863e1b645585e0935f3cada9e64303effb1e5d8be5418db1fb76d1784aa7b56c2825f970e221e8c8d6b6f43e8b80f03acbedcc4224da3942016668fda692383178faa7328ca7aca8be1c4bc9ef50bcf209289eb47abd34402a7d1e21c9ff6871a3b7f603d77e08ef58853aa0db5789bca441c50ecf6b01726b8cca5656705fd2c670a8fbaac44be77fd6b60c863873dcba0b5d883667f37cdf979ca1a098cf05421ad841ae88d5c235141104b32c1075c5c9b03ee60a33415f3863e0894eb112046790ae65b8a6606c2a295f1d91e32dd37a42ce0fc5be9457fca8babe3bfe142c9abd48df57a848ca966930c1372e68e939e9b75e72d52d6a2babe0992720f3a3452176e13619ab4057a3141aa1fcc82ab50d470b31a9beffc5a57597de1415998a9e5806ea9bc5df191624432543d86c2ba247cb78ab4b6f73afbd5533041b30ac9e2a5c2221721330bbe258a84ef5e9d5a14645cdcded23af731bc9071c66a21c7dc36593173ac63d818965d835d572ca8f6562c048773321f2a546082f4f0bb479c32b5fd6008d417debd9ed9c36c15ac9ff3d990f89e5f26bec912103b5b3ced9193cee7712c6442463cf60c7e613d1215594a2086d3695db7a5f0ebd6bc953a2c388e4866a0c54770cdc3342986beb6591953bf6d0d7ec07b975d01076513d5cda1bcfeea1852ccdf15660a73585a254ef9df4199ec11c30d04935d299908aa92ac5c3a2a549ef139dd061f80f8330a92b52439bc512804b2bb75d1233f6ef04625db0e621f4d817489c34c90b99837eef09fae7484f801a97f21ce732e7f1352429e00420474936f73188eba2000465bd8961f393c87 +expected_result = pass +expected_shared_secret = f9646f73de3d93d8e5dc5beeaa65a30d8f3a1f8d6392190ee66ff28693fbadfa + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +private_key = 212393fa68c40d1153ec29801f4472db30b8e6516647cccc6a160bdac4299d515717d46bb4248673d11558d8af5a6373720a9c96a4c51bf12ac506cbe51b560ab742ec684ddf86cb08121bdd412e2476842d051e3182c415c49b7184c9322242f70b63a960576296a8af5451f5d474019c47e1822e2b1503d30cb8ea20b3cec334a2114fc2381d910a98e633716ef9ca2f7939c7033bab756371d6c2e906061df822113c57dd5992c8826adecbc9ae381931473558ac94fe8a19c9c4bea3dc40defbcbde234a211623f8d80bdefc74f657a797098ebbe2b6b57438c2253f89d13bcbd5c0c4204def79bb37859e36e920768ca7d0651a7ec9bb63336698acbfb6c9a384084defc1bf5d9c050087b691d40344e107bef0241bd99463532a05b795f820213392cb16d668605ca86df134c03c4a7df581f8ca7daf732f5aa75146457163c3abfa9c655f966a607a69aa1234fd1ca2a97213f280a10e84c4aad26c0ea2cba6773d63b39ef7350f6d284830ec3275e5bb9a318b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bcc22d617aaf8b14c10d0037ab970b8cebbec0cb866be5057964b7cae6c9b3084a696602a25961dc53558c065d6d8b25248aba262b1b635322bb82165a8cbede60bbf6b72459d47b64a964b3c32ca563ba5aeaba8ed912d81b2e733b4b4587a99ae5037dd21dfc9aca5d869596e36547c0336ae774b8ba637622a597c05dcd43b092d938429886c708448b24a45a701ce9fb9db54c67bb531bcfb82ebc15c127409b02a3350d6168f1296784b86f7310b9160681f0133a66356843401b9c0414d7f687aae41a36857ccd3b26bf8c11def30769e30630169365aa3c3b53cc89d9cf47c2cc6c166f197c9e5c5b2408b03c41b0613703cc4872be78dcc4b28089d7118ca1186baeac1355d5b9d4e45515897ae233a26810356a373dcbf6cd5f02cdde8c468be006dbc67e60a69908d1171d4a5ec1643b87059cac80c259788eaf195f4fbccfc4c0284be822f94c2978fa119371291657b927f8b332124d61d17e21a36485d2c3f2893865f305589a8d048b06fba7bb9f087f96d5785678a7f2d16c892cbb2273677ed0cb70f5729af0a0403b0bf0608acec1ce32f2924535c16e8423be0c8854e439ea395dd792399dc98aeeb7493b64965858be35977dc053b3c0b3788fb4244cd3b49e40934f90b454c983da38b2b5c88521347788f832e9c64a6cd012511234275c9f6c251442a87b496743333a161d8c04e3d78be3097942aaccede09b9cb673e1fa261be71dbeb5c4e1049b2b2a00311acad4470f8afc85172476b949aefbc0110a261461291b5ff7a74697c88ad40c82770fccf68b9ad5382125879e637b7cebc1aae95b03219cf2488b2e3b2e51480c8cd8022c2092470236fe6042dcebca24cb9ee9379386d80e54c232dec93b99b694e99ab5e41cc8cfb8928d5c08edc7a707044b49b8a131986a3f37bcdbcab5255b64b4905a93a719d01a32384a87543b6ba1a22db75c9baad257bc8b9d8b78641b394c7ae064087454cfb17b307bc35a97cccb842602990747d60f30d220ed3171ffd7a2b77049dc210e2377607b817f24c011dd736d7918874aea4b8bd98be4597242c95c9641b194a093a928b8d3b30f33c10ba326943a8b704c09a6dfa55f700c488c38a3334716cceb6585008a853162e40a544c0a16878328f47c4e67b5aad276a2dec4c320047e2eab345cc14982b96d1d13566da409e93072377a1729546117a04ce291a2090b60030a35d5b360f9f871cad52f37e63954da0e0a8675abcc3717972f89469978730607293267cac89e3c96a98576c2351d8756429722a1278a173a75114baa4f0eec6a12b09cafdc99fee2c1af7acdae3c747b94b06517464f654adae25888a15cb4c5017076c9d3fac3b1560dd9112d88b2bcf31b15ac420fe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a972308c7b040d2fa32bfd1096503a3a0e84b9941188a6720e06e6641b896d365190369766995826b72122d780477581bd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0a423409c285d0e21bbca97be6707557bb0027e755f9a81912d04b9ebb374bd79411b2c283068670431f2de58d346bb525d192f128c9316742115275e9214def7a61da509b5848013b304216f783d77c3f57b76fb8dc984f05ab557709dae4691b519c44d41813e4b61e6664af5c970ae7a810714217745af087bb00575b18081921a854b7d953e29cb1de704e6578283292168ea73a03e2082b8b641c819649270011861a7b301dcef74e9b116a86f717e30ba6c5398e34390072e20c82f570fcfaa2bd8847a7187052e6b9d0d9bc9fec0217373bcc7b8d38245e40a1597077bb00a408e9eb2bb451c31a746d2aa07fd6432cf176382b6665d45343cf32731817023ee046577abc342bbe25416daee417f2971a8ed4c839126e996a8db40a55bd424c0e534cab677fa1c6b692d2b7e322a331305f75289a1ed102ed604722737e76501c7e7acc69842d6ffb2d31d1003c3b3bd8f4458d93b0270cba21db21a7d16e22e18584e68ea5b890ee839de75b68d60b25d5452bbb91658f3220aaab200ee7a8f070a5b5aa7fa30a768275970012324fe01910e8647945ae6f8b3a17d08e5c36af468a7f6308751c4141439b567eab03d72538ddf71debd2aec5db13537a2b0130b4c2f6662182bd08eb750eb681fce77981a3012102c45642bb8a44ad5cb27cda8369ec28190f64987eb600101aceae7a807158cc8100555a82644b3b513d7cb283a363c70a4ea090241c8a96ac562e7fb3c38f3515c3a68fecb271713729fb77a1a68695fcf995855749c1f0ae09f90741ec332e7602cadb69e55438b9d8ccc213119627410488145777907d280ddb7391d2ec9f27371277c266bb1b14f6eb8d46b2c8bccb0c68f3beb2d87b07044904d5b08e84305b0686f923985a49acdcb1a662d1a08948c9b8d95883518d0ad3933976c464a41c18351216d84066d71164a32d41886a153703c584b747555eefe8309f0810d49c0df8c5512b245f637c9448c47e1456995e922460b8210c7ac1063047c3764077288a1345c23ee0c8fa6865fdd52acb49614207285d241c14114db55cc0c92049f3537abff81b8a30a02e5ab013741b36d92191691b3197cce8d2328bbb6ff61932434899ae01412b231b0efa18d8381555866091c77981e753f8a2b95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a588aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = a07bccd6a1000b2d0f27be9021ff90c945731a7f45e8565550bd4196b7fd1b3fc4265aecf0714bec8fff9975ea86b40eed6befb80819936d437df6f83dd6d00d36692ea2c69ca0c93544e3ec86bbd6e24b12e7985e7bd89cbab9cc0167091270095529280eb6520545c07a7d76c99eb452e3fd596ac1c493e05aee285aeb22767bf7482feb0083147361198bab22b7a9b90051c42618443e621761a0e4bbf5444e23aaaa99ddd344dc738a81b1900e546d008c9e51c5a28da10309e35d40415b35fa9823364a0da0a5204a8c67e073128ebe2ae9f82dee1a91753ccdfce4247d9a3620545a8c4b5c5b1e55eecc4e9cd4338b912f5316f206ad53ba83adb62023c6d220fdcd573dfcfccff31616b50182a4f5fa42ac71b2ed506eb260f69b183d0dfb43f9e47fbfefbcc43d5704b7d4e303671dfebb03c83c79b3f7dfa0af964dcbc2edceef8821be9926ed353b9760c1d42552fbb8bc55d793a795bfd380e4616b3384bb6ac4c0dd9b73918c17a7b208138022a2835b5b0f1b8d79f186dbbf4a53300d70a18f3a0a8c3f3a8f57911d9958e5350d835bb4253b4c720675f81188480b62059d7af0935b81ca49313e49dbc2e5ace73cad23d8579218686ce283549e2f39b712dd7570aea5ebeb2fc0896501a39203769b41aa931876a2641f36136b82b53101e0868f000adcaa5157544fd010faa592cbef477f12149e0e45754bc25d66c0cf845cbc78b6bf3f52e6fdcf9e7932eb05f1eadd9e1a8d6640aaf34fc0da9cf0f64ae8398ea5ab0caad93648672d084d27a5e8f036b7390616df5a8536f1260ccbd3b8810f070149df4ba40ddc9633e7c1ac97da236c4269bda5b4a31cc39c5e1c1f2928ae140e67baee27fa30ff122fc431091558d52951b1041772439fe52a867df5c34a5d407249782a2ce947475a59d21463461a556f670801903a194cf4c55e7e2e570f89c93bbbd2e0ea1097c7d971b41c85a2fb20159b6271ce2a8feb0fcae0eb5f5c7ddf1482f6ccc35ebedacf47e67fc63581f79aecbb95d050edba235543e0c9f90a26572674f00b331226d1e00795d0323c331de978bad64cbeb8de9fbc2cecce265b7e8c85d0f334cace439e27f320cc8b475758e6fb4a1eda0021447ed963c8952c6635e6f3e5ad1372e3d4c6ea668434f5a00a9022dc3af451b0b0c8a4d9c705c9e837ada61d85eeaeaecc43f4cc3b0ba795dd712a943b09a5682a25f4a6089df5885c9a3a7e8789419753306134c46c3f6da5c68ffac355a4b8aa0a1708c7f5b66fa9f5c5cb3b4d9eea2ed038253124c3c14f572ac43fd6b817ca6211f0210a3d96e72e38cd415cfd525425536809b6d590b3da32a8c3e87c649896b1d81de6622cee43b5fa022e2bc6a378b4fa6f421f79ba8d6630afed853530d5f3b2d9341e6ce5b16da3c919f8bff21192fa4c3b0b4eb7187e453f0c3437c7407912902fb8d3a85584ec961fe7094d606719ccd89128f636119ed9ddcffbfe1d2c2296036d870fe0903b81446c6cc444bfd20548bdfe8007d4 +expected_result = pass +expected_shared_secret = 1ee252e97b69445f7f109187645cd2879f55e10eb8361ab43b3492ff51f01815 + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +private_key = 69e774db244d05192a2e064257f3a7b9b08941a2018aca28c610b8bfab59176bad88b9a7781222cb03aabe6a4c2937be24645a28c3a7931240503769edd1865f72b44c4842114980ba64a59a647438c5476a700d0dc4a63277c4dc73a3dc9b59bfeb0ddf0817612ab73ab14378e93fa4982d15131c5016b36a639e4f689e9b6b2d2bb2501e130eedf72afe4861ae7cbe7e717b4c4001b78bac719c6afd40969392cfb1d918794b4988a7c03a23c8c5a751ed2c39d3e18474b43cf8b7814a5932224141fd543871ac102bb0a349153eb4a13ad57ac06602bfc6c1b4425284ead058572a1c7c0cafdc6756555b2033d2ce67f9155b16726625928ea26d13e2c0c0a66988eab99643b4cf23ac68724ce635188dd8b3f2f421e8e8a9f838b707a16fbf27445a7555cfc052982cb002130ca3500cc428aef14281564997d5f37d0a1c411cf73d3d2082e4c26c3bb7beb9fba2d9ec631f8953b3d03075318b4b720b4fb5b177d43c11e8979c640639136fa20b718c0846404b2f0604c55ca82f519241d811a697000dbce1c743410e92922e83446410a93150178a4a2b52123174db128b2eb97df4e8a617d5876ab9977daa8b7845537db0a2b6e0599c0cc165438329d1251d6aa09d5b30f27040082a135c2b831b7722c416072c655c4d511e1fdc0284932849126d49b5a03b3593894bca250b0d198601a02900c9406d8f5b69beda735a3512bd355dad587bca7330364031573b44eb9c2bd103bafb7283c1b923ac3a41f0607d4b7b7e1e681aac9b4090538b6b7975b9c5c64c6196577b7861cc88ed6c3365aabcc9b97a6a318a39a2ba8b17376509a563b58dfbf4584e6b00d56bbbec309164982d1b906635a146c04bad613c02c8e2c2d0597fc285779c628f3e290a84d8710745c444410f129a140358991d601fdc787faf4506c6003e2130c2e03b3ffed39ca3b9bbaaa34abae794d4266e59a80efb44528b2b234d70025767a5dea09032767722c61e53423417458de9e809a42257a27001e9c8ad43b775bc853d8475abdac86811d568e9e38747618aff0b0901283a3913b6595cb2a85b6d42101dcbc90146ab85ea5449850bc9d8b1356f820ef365731f176ec0a0a5b7f35d9848c426f32d6a37046574a93cfcc043614e8708026621a06ac00582da7b64421d4f50aaac1bb10d6bbaea31808712b891344b7b865243614cd706c2dc098b0a069fcedb89ecd67de8319c92f3aa0a9b92a1fa256302587a5859408b5cab563ef1814cea386becd756db669fdf87a003ea1e7654cab281220b21cb234ac1c4b459ee48517bc838082191de35b265d5264119c05cb500a05307c806ae8246128a8194f61024f5b2b7c410689150c0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73dd91e9733282fa2559ac53aa2819811190b5827000d98433241a3da2b77f4e588b0088e3d3318cfd049c4777f7b08678144618e2406b9b6b72698888c4529b7e3b272e92620bb36792266c3da4c9c403d1d49650b5530be017c3b99c068890f2705702440aa0bfca823059822c18981a03b16670e127386265487665aca4c171e023621a853965a629757148e37833d31e453dc9b20191c94230833a6bb3b93c181b651918a25235e22779cf052e1d30e6852557ca32aaf841834b423a9e61cc24b5231d7590f863e814aa19f123c0cba97cb3773740871ac23868731748355a85f03b275b3273486142153be4920bc9ee77ab5c05d2b96228906586ec831ebe8cf6f9bac3631b7cc904dfc768b1a717274b33f70d08b6a79c4aec3597e1c9664c9472b6c100c1601f27bc0aed37152e20b327b5d32646f2980bd780c8f476715ac04bf1e03c2d4a31da23b14dc0233c1a2c2d983627bbc845f023e349ca59626a99eeba5dcc12e8b82076ef2295238667308451c2052c6f9b127778a3c656213a23dc7e25660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b881b0365fe513fc661a03689581e045d2f921444c6a76e6344ed8a335b6681ccbc7b42b50b9b03558c64da65088f60b136882012135a8a659355503918ba25da1c167b9fb9f771b5727493c921338c1acccefa80201039d28c968aa3a40c2a28835f63bde23b9722a245ee3c859997f45e10a11f1906c1485b0b51093f51819963393a692ecdb1dda2c88a6133f69f401b124cad796217c818152a528f7d073bfcb9eaccc6cc8825ac4612533126c1ccc736db53f648201ff29a6c3f77b41e01de2087986f237200014e5fa540735513400004b5925cf64b0ffe9575e27ac19ac5644f355231bcdd70348c4507c80780f1d51abf6ac4c5e2957a94325a3f64e83a0a192516f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a723fe1a44fc97543f269f670c593935bdf87a52a1a31cd2b9ad92807407b5851b49eb1a2318611cacaa7710b6764a7e57f8962bc3fc483a8393640e602ca55526eb1be56f2c61ce802b9592f24c14aaa75aa4b002ac9b81fc1327b2a93aa889c9eb178bebdc91579ca7bd30796cc324447892558d2c052308946a451ca49816c06aad39603dd3841ef03ccc1075df164739feb342adcce87aa12f550200ce94765eb4f291a5152941b4eeaba91c3a59257c03017c0b7e0003b07657ba60b4256a8a4b205d7646813246385b348ec157dc6eb3be4546d7eb85c29512840018968743d2ce147f071c8f96c7436596337d69f5074485bf4a288833f2855787f8a18d874c5a2a41422157f65b62b5e581c2181a7023698fdc1ac60a8340a34b29f81b03dc35da2b453fa61293070b1c6db57f3040c3af7766c69b84d624dba1163feb0c71fab6582473f93c8753d67b0259a2eee1c847b1b8a73455a74fa10c3a4c21a35ad20fc36d563be9bc55350f565e4076670f0c77b3c4aa2a06f7bf2ad1bfc4fc8721618454d640189a6f8b3d6c71086dba68b213f4c51100a6037e717147893cdae20a97759204b2c684d8206fdcb10df575799aaa3de388cead4446dcba8e14368f7202520c71e453b41cce426be6c1e29ac475c45742ddacf7c520da15780a9056183900559129e5e3cbb3feaa288b25b6fc69bb8b164c1db8e24391172a8c23859545e98a13725130e45c3d1cbb5d6f5c0dc275608163916013e6e466c29502902c97d3bc33dd006abaaf2aacc40c046e55951d744e31887155a3fa880058a8767b35684445982767c697540ce339a0f4c29c2ae42b5dac5047c12c22bcc155a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815dcfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = e3305af051f2b2d4d411b8846aea1fd866b2e9f2fb4c92c7d70a7c31515dcc9b9b5795d7c1716dee295b1b92703315bcf4a5506b70eecffa872a1c94585d978bf2b610a464499f36e58526a1ea99aadfd0f18ffa916134cdde7b857e72e8440c33de1187032280cb1b9cc7facd37abf84df7fb60b2bddf242dbbe89ba881d4b4a4bae19d706cd24d3dddf19e6619a0db6cfc5311c5f917dbc9eca99fdceb6f240144bca0697c2dc759446abf52f4a960afb3dab2a28c9922f29ad0c93a24b3f276138a980e7c6fe6d4dd349aa4254fa950ccf1ca5b177eb10c13a795ccbfb9b866b6c1d1a7b92e680728f45be3ba332d026820bf1f3b22ae9360d9a80ef9412194c1801838e2eb7467855bae54063ffb4a173796ee577769859812985ed1a0779a1b44b31bee787d6c894f475d1975bcc5b956201fa8029c1a50579893084874099c5d9ca37b33c24e08dfb45ad8c3533161feabf9290666218010de638757d46d8f36da00eb73f88d363382e3c99773c34f925d95da1486be5fa085e6670f34c6ad07453f21b3509bbd1eba6d16d2ca83b7942731a99766ae98f1a16df4a8d9a6c44d4c9c026f0232aa8219f37eaa2764945db0a57ce9700c3fa57849e8dc7848425b7538267b749c1474ca6f9ede161bdf7614f8384438250d13bd9fb3b86475de88bad4ba9cab85e94e3ee8c5f6a17867fae42353de0eb6807abb0180261ba13b5c28f3374427d9b70a49cafe4fe60ccd4264322f313173759383a3fbab05e002fce19a98ca8e8d112ef35fda07636fa8a23b4806497efba14e91608b92a737756d921ee5895c36aab80f5b863ce28ffac7fb55534a7643e27707c6caefeba5a60388f185e2477a66ee285dbba5ca77d79c4f7a10d40dd61e9e161f42d9c8674e3a5fb00dd22483466ef309474ad64850a13ab5e9bfef7df441adce7d678639fe4cdd49d58d23d722ec96127af9819e392f158a0b3d7f69e872349ed4eb81162529f8767a345d00e9588e8238d1fc25722ff23240202d7b1039b2b18eb14ae2da455be3851466ace03d27fafe35f5b676565c4a259634d24593efbbb13a9225f3233340cf8c3cc3504bb43158a57de9307554189d30936d5a9399aa71739074d5d487d7c69c3daaa10e40f6007668e76a7a3013bb6a7ca94cf668847996a7a496e839821cfa586254e21c3c04e3d40f730847b8aa60f4cb1e028899f4915114bec79d17501f8369c7c5b0a16cc0bdaf10a9dd18245ae33b55ab86391cb027a7129713cd130e7327639a7afca5f2d291b1f36069ff0b78979157c938619dfba02c24ca90486ce306d552d512e1a6fcf3f388647232fb0ad4feb4d3c9236e23a53962dd1118dbfe5f4ee1e47677db5f094c3bb3845dc7d9f7922ade82528e0d68a76b9608f3028100e5cfb2a989dd0690cf3bcbea5d1a827ac63a4f14992974e5fcf00981145d40c8d0a943dec836042ef5e859b9c6c12ff19ecd8957579b43ef7960952a020a571ffed0e37f7844cf37e0932f573134bf43ca169f09cd5e69 +expected_result = pass +expected_shared_secret = 1e1ea5d6a18873c5c7fc8da79093f6d3db5b28fdd0aaa42726ad130c78e9bb88 + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d56524122156503823b600236d3726edd9087504705cb4698a1515dc0d80b3f87c63d575170f45d121a848d897c3c0063dfe9b2d616a96552384fb72d6226a193f90e15b364ae667c34ba27fdd0ac0debcf450578c6d182da365d40786522c37b54e0126ed7b3c6bccf28f40770f23736b394210b67ebfa72f6b27799fb1f6e48cb7407261a86884621c529974635b35f5b4c530e68bee8cc213387b66a4127d01223180067a2ec24b2ebb579f74bfd5417fe995bbf816737722912b5b4dbb4c938d0686d1c2a44880fa7231944c195fbd67c67e60861d169ddc41f8150b52a68c14425190be2abbcf5babb734aa03538899678d4290738cc63eee611e4344ea73b9c41f36c712a4c6c72422000cb93e144f3c588a2299d5704cb347b90b2905cbf69cf1dc5c670909c478094e88c01bb3b3e4fe246f8dc3c62da37bb13b6e2046911d85d5790869fa4a54ff16794620480919c0dd74b9887bb5c125c34d76b3527a42a46b689fc4c57571af13c44b7d30a041028e97c0a1e50621567374de7a4207acd4cb18417c7984645cf4f2b5a5434be8f119798c0760229301e14431b0b652c643c0ea0ccaa13cbc6fa6dc8d348b908b78343978fd5a0eee90ca5104184f33f107837b3ec667eb207000570dd33856939bc8ba671b3731edb2a94596a8f2f37bbbf5048087091fd2ab164f5c6a8f92f65239f08844ed4f605e3bc1bf780877eeb3f4c85bf696c691f85a947461331aa33b15973ab4923f429c7913731bc025539232217f801ec7078e2f0af3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfc6165773a965e55034dd1094966694d7806f2f505cebc3b3dc307405431fca21614089c633b522510a5fca73462b32fd69200dc614c5e88454f181d845b19b8866259a2372bb3361b9abd5aa278b1773057e26108bb020a9610bc19af13454df46b4fb5a68c3e7aba6e7197ad63439c7252cf9507e32072e437296883c93902250165a1aee8be0ce6acc2029e10e97536eb958b691ae3e3aa9996986805c6d1f6356d26c1e63c550381b292fb1b95e183ca933d5be1baf6294c4b248b4264724712b2a2816ed3d09042287eb8a17ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb90c0456e1cd663137e11185536b02d8708644539701b193ba52258064b289d053404bc78a397ab86895baf1934e8b2f6cc3ae48869be7422e581a6ff748519bc30bc96c716b0a24a02679acd5151cb2a0fa127c81ea513c3ccc3b84a34025522486ce424bc04c860edc5758aa990fed372db324614fe91589d78acc88c43c2643d540a509f090ebfa6214832c76ca982faa1ca4465f9c14ab4e6459f072558946ceba113b5fc7024a364970c72933331a6a4b0d4196b9e6219595e229f3e28fb2d5c6c4c041db226ab611b04c3a80fb5a7f15e08df3347def02663aa39409ac4e8c8bb0934b46b6a8816cc70c8c0b11a7ec1cce57bf5baa30e69207d7e59c9e386d5cf7863c133ba1b510f5e06c4876ba7849611bacc369b039efe173df6b8a22469e1f200f2aa53ff84390b88302d9f9915c4b8257754b3423097e7c6b8452a77401c4e343bdcbdc985b70189ea976e3d65c47649593c9cfc112a4292238302253118cab8ec52060305392e6a131f0445a0bb4e11a1a8d7465e704b3134c3807d9be9f8b2abd57a00758685392592fa0b01e116410706a669a0ec5acb524d1561a265e307c24068b12897568490458121c572c2cc43b2464f2703212641202a40b27a41fafc4b24bea9f26711f28b1050645a38757708ad607ff6763f14c15a2caadfc2bc4d23c576e5cae6a20b10cc9cf610a5931ab4c59ecbe67ea079bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da3515288f933da602f1a2747a6856657b2102774bc1946163b534d02a1ce2e641cd9fc7f7d48b6f643ab53045bc690a249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4b414c223a52a6c88475405232c78ab3aae8861a45a817ebb16c3a3070b8e842527e965013244fe50907bac3883122393340b1e06728fa0400791b1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a58604599eb6d1d248a37ebcb17335713c4c9a0500fbf893df475cf7c19792fd56fe0a7505de0158f34603e0071b2aa0bdc8a12376a1313f571d33686d505660c4bace8ea40820918e05bc15b381b90d9b31bf52e1b18c422c3935d04140170542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472b409b1ec31ec887fd6e76ceec6812d40ba4469b3eeb028a0a6875a19b7aca51465cc3fe78566a3eb1b98c621eb3bbda4e7beb5f2344b64013ec233fb5714bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f7a228d28a5936968915d026cf683c762714830c1742ab4dff789f1f43782622a070a4ab52633efc52693b695dab939bc24944733905ae86801c4577324c625159b141c5a1014a6e458b71a959001839c461e17a3ac46da47ab687d2342ff63b83d3331510c98ac484f44b7fb6a31f6926cf047982c400008bb3b0d1ebba3cb2345613680531b0708a64b937c88b2985c01a10eea22fe5022912f9ad2bc667cea16b0a091f3fa9bbb9b8c30160717b21cef9d74458241beedc215d44900cf40709f6671f221d39c804eb6756c812364df0503355b8b01102574ac3f07234bbb1b658ea822d52a452545da3544c041c3a3f89ba30005a992b432178bfba078686a07971601f8b12c22b23b69c05a89adc2469287f052a6d4f58798e10a464db4aa71ab30a94854d1b8c16893b432a8dc2859c66a168c8c5ad4d04559056c4588b0a8755013e378545b47efbe90ca97552c9b8711d3281cc7b9057f78a68a59d5aa642d1e9233de093df5705d8639d702097f0dbc98451a46905ae72d876e1243546590599fc5923b37b4cf0a3f7cb47dfe8af00f6a999127a256681a5705bf5100d7096713c49149c7c561c0783e048cc3444776bf8997671970535c2cac5360c9b53e0d952af348a28e4826db9810f07110a48771c2c9b21da3ca719c7a5407b92020aaa0180b4d6b3ae42a1c09ca38fa59d1ed02a3a0079f2e922d0b36d9795c1fa42354ca51ddc11a315515a45bc7e1e21bcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dca19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2aedf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = 9ec0cd62bc32489cf014d70757b26fb83b3bbb19bc0c216f48829326dcb00b90256a7a5c4929fe9aa669803594abda4d1daec5bc98176a0cf44d66619dc04ee086b7dee5ebfec9af3d77b775d88a0d458f2a3d5f7517a98ef5a1ccc287047250d7ccf20be0154833116bcc1974534f3336441fb7e2185c08c6c79a4cb12cff37f05473a508dfdca60d774b4bfc5a52f7338648a8b2e34382c7d909ec79c620f5af5d3458985ea89c1316ecb77eeba08a0b294744601d0ffa16608c76bcec186203028c1bd5d3c285052db30ee906a2183194b790f8fb6d7a74ff6dcd25909b93bee46af942cd43defc71c7a70cc64a146f43546d03ca0ad34d8dcc4528a8f65d3f69fdceca37d78359cbd76416ee442292b3430170fd589eb8bf278df46415c740d31624fab2b73e116ab8b01f61512de5727117818598470179de87f9fd007475eee6297fae76e20df24958782bcfd4b4c3ca2e80de164b41bbf304a31edeb81906b22f9572e4411985349e826f6f2c37d5668f93e6544dab78cf8d4787c1234a04a98e8120bdd2ec23cd69f2f2bc42877091cb42cc459d5ce7a88d19dbc6b52c9783e03931d726219cee1be57fc4c4032143a7855fe1df7df26cfd815f8f67942adaed372d13c55dd90278c3f3563233cc4441a261908cc81598f1ae3812a0c312a6860a35ec0c80173aa24d7ed55732ed793fea7fcec59b3b355102fb286029d448c3ef5a39ddfda82da997782e352b089724bd7e570ea6b2314e30a3b075e37c16e289afb3c2f0eca3577ff385b9faa733fcae2ae01d84fc685676494382cb25b14d41c0861a814eff00ed266e3c3d1f9e5f6a3b11923860ae71b0e139fa3c75a93bd9bfc4286e3d432ddef5a8de2d767cb0fedc1eb5e4742aadae6585dc8c726c8c8c38eac111a3a25e008045e11668bfb48f940a567f80d6f16e03ecd19e00ce59d1aaacf598df4ea754cede6157e5f62daca54f10e8172b92f0dac2183684dd07308a5236c480e3a6a5aaa174fc0cb166897641243b6401ed5cbc31180afd3f4fab3f9246812c5a5382e00ea1cd89d67ab1c3dc80bd52070f9654cb0f9b4c9f179aceb687396cced59ee20cfac6372aa759e9423f1bd96240741bf34af940079840229a120392c6e01a37bf5c24d026c4ddacf9c4a96364dd985ef98da55ca7780d2c75ae85ae08d462e54d2f0db2138e9e373bf65896dc2967ff481cd2b0f724f0086b932f728c201463fac0ab083d4440bd967d4929b7fa19c3a5f2f9b8ab237722d9930bb0f31b932c5538725def050e680bbe4b2f92067e739897d6d860a8087af3fd4faa34d09a9d0362edb5374ed988509ce4a61245eee1c1c531e5e72b977be3992caed8a441ef8ea849ffd4fc2efa3dc9f254d582389632b29718f638a6ae13ca506f117bdd204bdc2f1c07a182b1fe44e5b0a5ee3833b8611b0da300b28aec5d798aabae37a97b76a61af12cd82b017c2e2503e9b1c56311fe79e37af0b881106764fec52e0b1724f3b371a90f225bfb1080dee64f4d45d7 +expected_result = pass +expected_shared_secret = 24619bb17c912fc992bd8272969cd5b6fd6b030122ee5af9365cac8b38e569fc + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +private_key = 953b6e6f452ffab6b9e27b707f600992e228f5fac92680aaf31300154b218ae51a012a4cf53840cfd714cb63cb4c7aa0e8ea6e50803ca370bb38c7205d9365448b38308868c83348acc365be62b4fa763ecc5112a48558e57230d92b5869d77d99a5c0bef49819500b333300910117e05b082d15368ae529923c6bc9d3594ab33c91b81549829a2ee55ad152493e80aa80399f770899ec05417a698e6493aa647691fedc92854c23702caafc8ab3a3194ce8437b8e2a7f69454adf3170c282972abb93cf152dd85587f6272b0b71590c81b3a9f680d19445fff0c395310a17f55272cc3e1364a9aea7a67af4561cf10043b7b7eb4ab0791a8d62814f4b6536cfa69ca0493fec1a53d58709fbab9c87578d83c9441d62c267e7aa4ef0afc7106c9f834a5a13206c4b58d7378af90b85f7e05237559d6d7819f455aa01d68bc297a8dd760a0df971542919979218b4861a49e45aab12be67080d197c25ca53483d781ba27893d23baecd393dd1643dc2a53275c84a19900b364ccc94a8ba3b5768f8dbbe08a7b08fd2746bec62c98c5e5198695b12048ba5c98753aaba88bfbbc6c8de490afaa8343d334aaeb72532c63d60667079b41b6a287b04c797458acd9104c94e96bf18137b0868737dc00a8e2164e0980b9b2135dc7c0e80e1b930c22874fc2cdbe0b5542732e8fa80e407a1a6e5af0aa3168a963587379aa3e6a2b082a8a35604bad827bd6aa1fea76a608100ddc40b17283eddab2335b8796dc1bb57887787a4273c4185867368be581f6e5767bbf0580f07b003556ecffc3ae336260fa0a80a2c9e4c9914144551c89a9d68373ed9c7afa83c75c6b8affb54187d3b46abdc61d9e070b5584be7564f932985ea4c739cc906732a7cf79a65f0f7b0682caa5d2070b3e0699b1bb3ac0b38caf22ca4db9472d06b02954e36c0a3d8890473588c77e43990da1c7103985761ca711109bec0b805607d732a36baf897e93c6d9a988b94c67a4592b7583126fd452ff0b45a033824983715c60478685b9c2d013d41b47eb342a05fb76232554df30990d6f1b37ea9172020c66fac8f415615ebe07833a2588ef622034074b214ccd9395648071821d1109daa87c0e00cd9573254538ec3b8459ce56578c09ca66a508e88c4dbf6183a268b86fa4b7733a8cc89ac81619af8f56d8adb1f665a7ac413005be730aa41cef2b06a7fba535552c8cef73e90a8584a8b799c323f61faad4b8c25d06cb883493147069eb1c9c8fb262b699693d0601262e9ce5b383a0d27c1572c49547bc908c003490827343a690859a15b20119975c35aa991183052f117b53d06c5f4683d19ca5ba6f5595b8b269d96c1b3524cc8fc6eec750ca33b5518603f59b50741d246642bb88ef61a8bd4c54f48af3f573d4cdc5143ecbddab5a281400721544e16e35ea7a05f161003a6c3adaf690189bcb074f546bc2033b1e8b00d56cf32e0733dc81d05eb358d148a91faca963b814a9c5fdfdb4de79b729dfc26c3d9b48a4730337b0bac8c2a3628268159979f6b10aa9ab90adab98b9c0928fc4e3570ab01f02d5a64c5f605596e3498ea532472760f61cb2eb734c174e48237c656636645886b65c566bf95d927a16730c3d8a8484295a1d995716a3bf93c7270671afb7886f397af65f5bac1b1a1a49084d1a672a1f98bca762287e90410ab01098c74869b42479c2cae5906ab354970c05cd256514f5c2e763230b6770884e7b700544977993df1f57969e0265fac4f474b76648b36f5711163638069820232b8a64f16bde83557b0540405d7987cc39069923dfa984ca4045999a77483e04fe6eb0be954a74c13cfcea79ed0d8124b01b740a26ed961b2bc496cbdc539a10b8151e0078f66751fe78d2f3a5100761c8beb514923a7b4f3ae208766fd852222dc31fc1a59a883c401459dc73468eb35af61d28ec1da147c882cc7f5ad5204bd8da270e4c91dc37baae1811cff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6896a288a9722183e199f608cd7a412ca949113e87a956e4ad12737d53c3be4752533bc755f7a1c4b07661e988210ac72131b4496941893a9c6f1180ba622436eeb02f3a3a090c00b1ffd310e811a7a8b87984d275d76b0f99abbfa45cc5096a1562a375f0599d9698b18012a84a0628601c731ce1ce6824907f1b16878a75418c2fb0751202fcc988779be2326e2e5228c9493a0e628441b13d58b3c79df34b7b53c7be816cc7368f2f31c380296250b33269158c4f9706d75b3b5536adfe5b0bcf514899287b4b637bb4249db25a0413533d628597ddd745a7f5270d136763e48a517ca62e116913350e7361580cf77bcdb5b607b38d49e1581654a61ad9602f4415f484bccbd833255a29d2e76262b401f7fa5a1e68bb136771c41b29333b653602b79a2aba21004e8a257df7362163b6512eda4e1376aba1facf04d1aa56c814000d718b5b504f1b9d2e627b8a678d0294c5e3b186a67c082b90abb1c839232912c39c3e02717a65e24a185a5d96e99851eb538a4ab872148c2d7bc52ec4270f708690d0678d43c783ca194b4aaeb6f2156297355d7823e0f80890608768c65073e04e7e5b45acbb1cb6446483e7c315a0a0c2066f080a53818a4ec0e4973f630f6822a437f6684fc9431f20a306a055f9906435172699b3cd0d46457be26560f692864a97f80b493093270b5225980287f1f5711b355f9ccc018d670ed8ba64f10ba98b0068e7714074e14736087819ec2cbc960fe6939a4e9a4de2045b53e81fbb845b0e546de6b34ee9e91ecf0c9f74c569dec949d3ea11785639126bbd45137021e9670735488e46a325342a2b4a959297816d1ac731cb501d628bc09083ab5c4dafc09a36c7c70f2885a6622bb7162aa2c999927a1fb749bae280237db21418e2cec419990288b813e80765b47e4c314171b849e570c7533cc5bb77cb9f10272926c382fc0796f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4da2d5264b282b32933d8c74242aa73c15875934e99d6c570572e03c54e47726e3b0416d3737a29624169778970e99de64bc2b16039ae97c7472a41c9a6c6fd45bd7738cb662505bb26a307a2cfb9680f5cac086f9bbf7799263c0b5367032196f1bd842534601094668a33bd339db59746d63ba6007887ab750f5887453e02b22c3148bf6c48c806a94cb7bf23568789a1260c87af0548c71881401c565268317756a211b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = 7c8e5f4f09ed554cbed6874d860af2b8fb97fc6de51e23a003338d67723b50616d0640c2e7e1492cd5251b0e4f442db191e500b3fb6d0fa76e6112f20eaf1e8f66e6634de166f2a67ace1d95366bc124129a016f6a4d669a643d9d90223b8a8829ca2314e88d76ce49a05e15121fb7116afe19dd38603e994f207e827135be71d62076b75453dcf6588b1a1c98ff2c517a4620f5d951cf06be81f28bbfcd08ff396e1a0894055bea6b7ef41a333df33e5c24cf30da5d78c5de7629cf8bf458255a3348f67127ad36d71641fc7a8bb9bf38c4706afd14e9de0fcc798c0fe35aea08343936f552a1dd7ca42d513c2896ad762fa4c0ab737d94f63330d47aecd1ea50a083f8660a797a9edb47ab2140748a610e981085f7dbe268e25e9b748dccfbdd9c312bb64f41a143a2a7f6e8d0bb7db83325747a414240e9316c2b4305940a42fbb9d5d7b3d0f593f63877d7461934a9a125d16673f288e828f17ffd75c0046564f092d47e99c59f51ce741d736cc26a35fec6d1c2ae909d6b4f4e635221139c9e6ea9f1b1135031ff694e3e12503e6315bd9abd54d0b4fbc9da7d48463e80ae57d3dfc1bbb468b206659f60772a2338f38b274ffc0d391a103e0a1a50833218d1165ea4e88f07782b1722fad72bc409feecbdf6a0bf99862af673488d3c39e9b343c35a5e6fa14b3c6893e727347bb965dbd9f8fd50b1ad0f23f7d3307f650ffdb5d8c085acdecc4c3ea7c52b1119175721f4a382b91c59c26220e40fdb57ba76f44238e1a77a062025daf823219ff117202f5f8ed2789b2b9e80bd98fcb4a4f42d006e299f190836b7e3f3a66e7ba13dadef54a2e5029bdb1d0f29318c3ad3013ce6793f5d4bf15c70cf79883b0fd455e9fb6bbaa0651d72596bf2392e38fa140cbe0f9e42f0beef0eee3263642a52f04f345c672560914e80ffa70b4f2700c8823a6c3352331690b54b3c20320a8a810f4c5f0a7eae739e343a93587846c4acdd4d93ec3e48e9c4e3728701ae9cfff5eb219cab6c50ce52ebe263bd54d29d4e785d80ee87cb4f064d2b38c3b2090329124ee0c74e4e7b7779769b14babd36396e1eeb8614b3af9f8867dc8f93c46376f8a5450a3761d6f4b7de3b4108c080e5e3c4c9628f160458774f0a1994f9ef5ba86933670c800a9f76866e38210a0e26650dcd110ad5f0f621e1c6cce1279e2c8ecfd4055d32d7b7a910eed993222cd2dc83dbfbba7d04e0121a849b545f646ed140e7afb1816982f1f2d8c6549f9d73148c5adeb3a30a9f3a459d3afbc552cb999bbdf104003955221fbdf7f6d06e9087e3c4ef49104ca51510c544b0abb048d1345c72d2c5e873555019487124998a67821f119ebf6ca973cec4e29bfb5704c92ebc7c742870e8de0f5811cff0107b168762d8051551133e3597ef4d56d50fa9333c0b5e6ace36ac36b0bac6ac16cec413f7e9d449f0ac9607b52f5a43f33921f3f226eac9eaa72ec17f0348b04a5191adb2e7571a4e1dfb11a1e2f731c124a6246d94bd253bd88296a9e60363 +expected_result = pass +expected_shared_secret = a990af801ddcf2009c82fe657fe3f068bae7e6bfc661e3e588354ba7d1b176e6 + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +private_key = 87c0b4d44cc9eb48c126c5877ff87929b08485fb81e479139c3299c70c43c3fc8c238a81d4e61e62a33db2499c866b7107d116b7fcb1b0530a7e758a8d487d11575079265b3158302a23732bd07330071bd7cb7199476c39b583a2446109e99fd5c95be21a292cf37490906e84a82605b8455825c82eca4b7e218644460ce581214c78ac4473688bd6a9a826217490ad791b7835a85935782847981ca97b6dfe88b63701cfbe3929a2dbab1628155506c353639d153656b90c5aff36baedf1b87da5bce2a108fb6c3b29e77dae803a0dcba48ac6882f6c1194e88387f30a47c27d02c37d988346a2a29584a55cb5d3c44c05a18619a4fd412babc31a046221b3994c8f22ce272c9e6e948c3d043295f413349796c38911f8dcadeae47351c15e9a1743eb65bdc7471f37fcc93cec867cd4808ecb281fc17efd004dd64ab432d664864b43f8a9b1e763529ae2c413abbcf30a4a478a30a0104d802037c4a8af01b534dd600e31a1630ff13b2f730924cb790166af3b7322baf4409cbba500c1bb32894e65445f04e4b4b4933de51267635037faa44e2775caa4212f4e0600e51069aba662c86145e2117347bb1748d63e412550c004237cf02b02aabb18d8533d19b1a879a079b31d529aacbf5258483c80738b380c83119c12b23cdcbc7d027506f3705ce1316dd24594a4bd32d10382f8ab47478f23763898398d7430264203a76b0c4455237f3e765ea5516388595ce9e2bce2dc2258b5b96c782865fb5354427a2d7806123b0cca782b1c329411c6c133934ba4a959da88a072bc6e2d63a007572e36b82c5643564bec47bc8953d4aaabd146ab5eb36e33f825fb9ca01e223253c320f76c98f810ca52a2c604622f7a60378809a59b19680aa69eed2003e272b8a1f3c8a55bca129640c5a00d187bcaf465204c73cee66a2feea414f02859c9988356d26665196674d25e64cc5689965cfdb2c0e47a531ce32b3daa9c649954342a3f62253fdf826aafca7dc85a7a8e15161435212d7a4a3bd4b57a2ccca3506999d407d9b6abcc97209fa97454b0974dc2c7cf3c3fa40306cd6239dc450536974a8ab773374504b9889cb42bce4ef4606bdaa559346f18d087bf8b7f0d9b21b0c9b75b5903194b0744a1c47483488eb4c1ca2c83d8198cc6a523d9329f6582863cac2951268c01770a8081c1c26587d7610088e6068e020e10472c825c395ac6783f074efa8597feac3734399bfa247e4e1531eac70fe49355e44b3ba5439ea1e65eda94485fb710124bb968490f1c8b68e87a4c4682156fc06a33275b6b202aa0d508b3789aaca627f0f0c19026cec38a95f7547d936b255be7a7525c97ab4282714c32a23c4723a82298f2ce90fcb4761b9eee869e4d3484ba2b222dc28bc612b1f41607cf57781990009f29617549c0b2179705a34916db154aa3747867c3ef6a0693bba5c1d42e14b3247b41059f92607a60afcdecc1c6f3839db943f5ebc4d340aabe21269095b3f7d9bde9ebc21de788794b63e1098cc2903a83ca2027e8bcb78b855fd56fcf16b45e47994aac71fc815c521ac1a1b697a18569ac2816f52640cf9059c4eb95e6fa1b32b77bd7cbcb6ab384de74b6a2708400e980ad735e9e838da63ac7a3e1cd3e574db17c2601d3927cc2a9d228a05f5c1e51a63634383ff5e03151f43c66a07be9e992aa65ca4ca17b1e021e06b261ccaa89b12a4916a5a4e39826a94c86bcba9fc7d65ff04549db70b300b1cb280b3a41e82b6c8b0a4a3c5e40eba59fd18f004ca3e4c15bedf22e099c99a3d114eb0c5988ba02873b9581107a23e54a8e51ae62375a887929f7333d4d763e23b20a246785e07700bb16c531692531433eb6a6594d1464bca7348022c1d4219cd8aa6614862c42376c3a0c4674181983f2a2ce8b7f32659ae87accab6023938592e188a3c1015e98720eacc9aa837a49c4617a850c89e1212478f3c6bba51c30a64a8a1c225274c92ea953872342a96ca3235ca7a9467be55250796126b30694f71b2f75b56d84ac89c4b635118145c7b8967de515ecc719e35804194b7ea9304636283cbf72339474ce1da00106110a596725574747dc07b3f0c7c527aca703cb23baa080bb7a4cfc1009b3e5aa89659121e365fd6cb6fd15afed70779a978b3ff50f915b6c16a350141721efd61085189c3265530c1a17491b317031b4e4667eb8314ad34cb7daa50566a9812377cf24076fc3dc748fd58865b1b02dbb831b25b7b7383579376fdaa6c8a5323230025a4bc66977f6a458374faeb14e47f70e654c42c94a5fc5e386a57abde3f29349623e4de92f900527c165870fcc26a2f95fa1850f2c940fb7b87686e253dd54b6706a84a0c70e3ab04ca8446efb77609e9815a261af5a135836064d44a485b5e850f10153653838e5874b76568516e847a2a9b186e8a50c34c2d2b0839ee58024211018b0a13fc781623cc313b30c26a258106941a66b3cd9481aca7c7e3ce3202f098746c42c58f4c7dbe52fb5f606fbf31b9b5022e691cbef1464f6942aa503147eba081817ae28581ecdd867a96195db320bd2d91c36db01ade9affb6b00f86c13e2e252c988300b05afcd007470cc3022e96af0768dbebbcf62b53345b213c1544491f1bc75ba96bd73be57a2cd6874511b44bf2dd27f4fc87c167815fec59f7a043f699ba4d23400886a7214160c23dc96056bbcc7007a0049435c534b66971e6e5c90effa6645c45031c0c905b9887700181565b53165bab605a51bcaca0dd0c308a46432794c38f21e04172005f4348211c63a40cffd7c32bcd57fde852fec793cb7013e74504721f6bfb7637f73319f75b08e3c25777c969c6ea000c9b79d6f16a00cc4b00ad7ca4f8704b2e54d9d27524f6b80a6d51f85447b22c29af0036c6ba486862c8b4fb03f26042a0e195a3e91bc303770ac844e77805e41ec6aca920ff3a1a3abe81b598c193723b20c8685590131da89c0ace08a592489791911c92c7e6ed55f642caf918173f190b2fb8cc0cb2139fb6caa259b5a4634cfd0a532b719903e32831489a2d390b4c5a5066b4ab5a3316441b162407096a0bc0342599804752fd4f21c45923705a7a04012ae4a900c01d584f9f41676c36681994c2f4037bdfb84a69a81fa561e5be05777b571922988eac714ff249926fc9cc4e93666e198308a434df74dff3c5a440948437a7c500582124574ae225f52d322d0909b5e946a5e22ac8f774f69c48b7874417bb1c0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f40f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = 22f3f2214b8b2b7fdeaab34d714c6c4a7c474464bf0229c2c7f31b323f65f220adf521118a41218c92f737c2e8bb753d6e19649e5fcba1f5c821a7d5603c84400015986d669ef0847ca0117f03ad3ce2928f3b88d079ad95ad6396afbeb8146131bf4d822dc4dfac100f23fb329e23f3123fc4bd0605903dd911a6f9c092259a167445caab38943790b7556469cf37c07f06d604906d4d10af9370dbd8a2e45ab870063ddf1b3f24fac5c7b5b348bc6281dea95547c84641f697ced7b000334493c35df845a12a1cc3d61efaf5a84738c2279128485759c838993d7204706ec6487010e6935d71319ed2dadfcaaae323aefdb7fc4ec8f121ad6a3bf1f31afe622bcbe17ade7db20eb98ab81a5fd91cd22fcba60176084ad5a51aa5c786650fb0eae9dfe79f74e919961e018f1718ac031e46fc3601a6ac4f83d3cedc66225a1bd7879217df9b8fc3dd0be1b9992d0bf7c8b84854d0d9bb82813f3dd74a5b7f38d174d67a00743c4bec322d6fca86ddba4fbb199c5d1a257b5e94b3b1f3a5d8a3b1fcfc4fa56eabc48520a2db9291885d912173ae0bb798b9b5ff15298cd87689964a5ac8283b4d5fd11444ded04b8abbc91727140c93acc3c817cc66176ce64c4b7e5cf3d5063050d28ae924103b0cccdf116d72df01d2b492524aedda5522dfc54bc83912d18b984f7b3e5d5b1bee11e352b44f04f3ca3906cdfd4a08324008665d712ae8ea746cd4dde1c70f4f4299a22ecd16d17d5f66f1060311a378e7b8d7e20d1d7548bd902ba9f4559d5f870d587cfb4a2f39d41743e7610861d24e8703ca8575228ae41a88d3f7d5cc496694873e5fac388cf3c42655cb521d4680ff42a12a6e1f9e4f6685c2a7e786c1ef26fd6be01bfc37ad8618bd799bad70fcc502d9fe543d91b47e10a58a1787a2caac3cb38ca418323ca97a1c0d4427fe31ebaa4d548ffd41e696a541eac93baa53219944510c4b8a891d930d656e66da78d5ee1518fffbce85cc31072f234a0584c97a193737f6044a2ddaaccefffda4ad055f01551cecd853bba68d85f24037d8e34cebb8d625c80b5602a3c6080a393255829f94dca02f7c6f31a674cf37307dc5eb649249236cd8f44281d6becf64f9d301dc2b624c6c0a7ff0cb38461510199b83b42d716c5fd6cfbc0c571bb07620ead1f72ed1960c97d76d51805a48bf594357bfb08a57c504983d1cd8ecef8a6e5cccf0abdea45abf78c044f1dfddf5a884ec3182c3884df3c1e271408712f1d55be61b80e9d4f64fe5f3a4506d85875a59908ce0223e40c775ebb258c0cc9169ed8dae85266a7f191c5729d867fc8d6185798a1bd4a6e9f7594eaafd61a925ce5b18f7e07885bb2d37704a544dcb9152d1822c5ba449fe71c499b46a6590aa8adcdc3be9d5c0a94066a53fc682f5d01800d5b7240f2188600a7f1099e2d42d9dbf4e2831c0e046692548918212ce5d52808c6556ace187ba18e0ff1bf27ef6425ac18ff437de794d546334f940fa5f545128aac740fa0fd0a44888346a70f0bb9c +expected_result = pass +expected_shared_secret = 11a2ceaa0c77f0602c4b2be3499e6df6b0339d9de90d04b2b12829f4758afaa5 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +private_key = 4dba785b32456e16a8e9a20fa7536f1b4555a9b403a09738657a148361788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c12c284f848b89585f76892fd65cb906d39b385a04d2f5b2154abd1e77ad9501abac73237780b33c601fac50ba3fc07e8525819593b7d7e69fdea46f14f1128a475e4784af38985501dca6d20bc8dc1c5c7740b33804358f71b6e97b2a0e7350f7608321736083dc54e0253c6e5c5665d0b7e68355d4e98daa753c1abc1429b397da773b043459e5aabd093a5b0210502bc2cab250041997861286924aa0a190307431719588cc2e6fb68711c964fc20393c73b7c967c603120a3cc11b2efca3dd6616d0e2c835fa92946a40c4cc2f4655301ecb09424286b3c7a07ad3c6ea37bf6132aae2d9a335e34b6c816d93cc7ede020ab723b272b70f494834ccd93bd7800bc39919dea4be4c585f827a4351e233026760dc83377329ccbff180a562ac50833c0f861e795c00ee74b584f693222b28eefcb445f19b06154abd0110c6a017ed525b5fa30c64e60663573b8691ba68e2bc580157f1c66ebe388aa2747c50919af644acd903a801a5c04a6a2eac686c89835cf59a791ad5642274a0f78244491670c66c9bce24ba5cf6b86967aefe6728dce8973fd29045db844dc80022297cf530c8eca4808f603a90a840ad70a803e6a0bfb44b38616816073c5d7ba26a64048f81a3bad3a0c9cb0672c7466e38824529298a7c0d82940540c312f429411b403f64e419cf720e1f73026184cee538b27cfb91f16186dcd3904ba6a34254155b3cb3157937d5618568f46f283c7c0e88696324a4fd77c3e6fa5b5dc0a13116274e5792fed69eaba973730a79878103bf63934d179143dc23ed39585d40c06a99aee0f4462f123b8a6b539dea9e05117b08338dd6754398e7496f612b4d892ca54a13ec9b2dc7022cf779668809ad6db97a6e8b15ff0a862e664d292c4af549195a23c19e2b9fcdb9b4a5b9ae517873ccc644993196de5c2716d58d50e7cf11558f44a16580c980654c8ca581671121cb2f8cc6f90529c9754cf0700b30943eea1a7b05f0bc8fdc1cf776b0cf2c2eab927dc83197a4071dabfc07f983bf4d2c613e087976eccaac031b88420ceceb6df0350f04ba61ab39cad4c6b2b32503d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5c40970c435508e26cba50705c6538686249d344bdb7c820a5c8869b371b8fe13922a5af390bbb7b809c392266541671c75cc2b7a7248d0234fca16da64265e5c70257d770d2e9982d5a1c6d19bf0ba48b53ab900fc8280c754c14774939b83c63592a12f35d198194679942ec227b46cc8f353a0547e929175c3585107239aaafca151df3c835e770921e5c9b134ca7e27a18c7656bfd6a4fd2431ce1743576e575dbba8905f4cc38108e3cdcbf0155b5300a100958aa99940bcb473ef64b05baf55e91952c46851d313b0990ebcf2148cf28130cf49c8d080841fb81384e73367c792a11099f5b898416946826714e252457b23a3a1e33a36ee2612372cb2c04030840a87f96a31913a428cccdd2817b38372da4637f46044f2218c28d525a57d9c0cd2864fd43aa5c9a003a09a35ba786a7520ce0b9190b548bc164bb826874c1800980dab529866b951c01c20cb4ad363c681336b13105fc338b1788afbff321bd981974c33d98a35666eaabe3612e61839d6ad65490d71ae992111719aacf12a060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b0731621cc04e6e2061e93cc4b51209ec92abb303bc638c52ab2ae40d746cfcc43b7576a240540bf410c14744f80a442d0555d474192bcd9b187a56691b63965973c7793668682852f91cfbce70d6d4832a1855cc4b83a847734c24019c508b2d29539fd1a114f787285e197b51bc092f80b559446f1076f02e984a1b27cae7aa1d0b50967939aac74cf2335ad421021e3225d94fa3b09148e60c20e8454c68a8022043206b7bb1e799c9b69286509a188db29a9ebb078420a0844c858cf4b11f9b4959934002be0229e714350451b9c2775a5cc8c45b07e121290eee32a73d46f8d7c55311a8c29027356139f153cb405fa14064c5c31060d7a964b33d76bcd4809d21b34a2f7806486bd2835b7f871164ae496d4264f89fb4eb15b7e5a7232b6c68b11351a41b09bb0c92c8437534d2b4c0ca2538023b29df93d93c98136780ff6f82846cc2868664322ab28dcd7279f68994ba5a5ed406d4d717d16c14dfdda58db1524f7c53f3cb170d45a411b07cd64f001daa0ad1bf63a11550c0c154d20f5096db44d1ab0a1c9d66581891a9314c18f778330a0936e7a2f3e19c18f7bc87cf078627770dfc5a2fe71b27eb8276863c3295c11e08703ef4a4ff6b3a1871c7b42c43a6eeb6bd1526aa95b7dcd6b38edc207c630bed1768ce9505544e9053e5c8cbf6a181a1a0f48c8a98b59c3adebcc3a5c99e61588834024cfc71c9dfab1df558711b311404a739f79b45b1a8a7633081a27a08c3c16478c9d24c1229723addcea225d39bde7851345b18b1b08254181b01623347a9a57f5d902290b10476083949556663309059815626c3ccb5302b978b2ce82af231934ffc7732352b990b21b69210f2acc048387b95c346974c2181148078154416e08564d664db3045dba82c9a7934de51ab5c1d7346a391baca48209c8c7235309943c1cb9cab4771c7eaf59321b510d430c88473ab16f54ae461a5dc613c6fec61a5e899552e835eff57fc34b7992755d178a0365c52b3f020ab40020ce21b45717654634606dfb2917fcc266193e2e5b2c4559cc5652aad1121cca0711e26c23eb33c1f7d389f2d742f384725d3268f8159f8c463585998289e58369fbb883caae21b87139e52d7ebb92b011cbe6426390458247c45f06f2519ab35b35675bf93325351617ad3ac470f73d3d3985e10277a647c96a6c56cc2346563cc496db232fd742aea3adcfbc506ca8cbada7b040a04f6e329fcea77bec0683e1a87c396113639159d9ca52a5a5484d2839869a2e80557a6bf7ce2ee295a464aaf835c542457d021c65c2b2a457c771fcc47f8b1056c8b7aa61d1843a40c4c9b083269b2e89fa3ba5959f89972805fa4b46e35abef0c57d875c54804de77071f1219195bc8b4f7c18a19a7953573e7f4157ca03be2852461a784e736110157ba3f83a6947aaa09e9bcae730b9b212bb837627293a485ed6b42ca1cf26792676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f4f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = ef721977b01338d0f77a3f31f04fb6dd98be2448a7d73e426cbbc87c9eb56ec0a36df6d71a95516b8a6880c9a722ed440407108a41d0dd34893d2a6f243a28d8ca9920ed831315fa207f059c0841e6d2d7f9c5311ac5bfd74a36e81c9da718a87d208c2eb4f1c83676216178022a27a04ef6343e958f206d22a27f565907cf39d521f5d0b4f7025f37c228ec396139233c4f56abc399818001ea2c10a15b4b46bb348df15c2da0ff6ff9851336ac936804a27455449d21822090e6a8962420e742a7ba41f058aab77556bc2be4a59fd6588246b539b003f90efac50784e13814336c4b06838dbba07f6eb287b850b05c9e4f7542ba1412c9e7ef5af7f8cc8f7d3699f9b32db4623357a24e3557bb63612a2705aae3132be9c6a1c143fb52d0d87530654f1c890d40a645df8538a707b35d173259dbbbca97c4f5ab88c047936ac72eeaf415d1e5f8d27817a45a137d66e6c25b0e6b2791f65063166042b4e750d6c445a4b5830c9c2c3ee8a879f1685f8aa7deeb693df158a6f2998560502b3882839c1508cb1611af1966f62bfe50b1554e4f0d70cca0eec02c0d295cba03eeea812a031757af2a147925daceb64f7c0a4bdf728a6536012c2e80b486a3ea82c7ebd7b97005aca5bb3e890a9515d5942de00ea502ef13d620b832c7a57fba93ec30b259512c666e3d325922394c1b4fdfdb1cb24fa6fffe747dff802d277370a97f4d0b7fd78a176a6758bdbb6cc88f1ee95639bcd9dd69f56b45e1c8faf26e205563481860e5c3e999354f38c4a34b56f8ae19848e53e1d319b3dcee667a5495a47b9fb79aa137787d2e1d51784ce0b90e8d6040d8da5b9ff736b22c1eaf1da117b258b5151239543330e33e6a61e821abc31352b41032fd51690bcc65b95280ac5cf1bb146d2cf364e1c83e654407bbd3391d68cc494c93da50e360176c3caee6e96e334a868d6ca8a0873c7a4e300dee289496c71f6d2c81ebe9895afabb3a274f8067035ee602152ecad5fa1597a3fb5e356233c63fc9e339a17204ca879e084bbcc4eb9079d7e41154cbd974231cc5a74f1711109dd06a1611f593e0ed4be5e5f2ad8619e16e424e249e3f3d7af016785582db7d228f7139649d2de795b264a65554f55d4621517262595f5170cfc96176e397e84e247cabe61bf60564a3ddd3c782bb428de86962f1b7510d136013a7dcd72a464180f59e23772843a012d03ab5d38dbf96d424fa371c28e7db3cc123304dc65026fef804d6a24c55ba5ad15b3bda23ee7e61fc2555969d87131a15f29ed7a5abc5e715126a6590e9c1960e8bcf9ab46988e0f3f2d58d5a6dec84aba81731e02d7a862350f8c54d48a5477474a1fd7d58dffeb3c2485ccf956c20dc9e0547454c973d6ed72bae9afe2ad4e8775e5a57f6663fb464077cb812268571672ca5d1a3b49fbf56db19cf7289820538a4c426f1601abcec6db5893a394b8b2f99382948738656dbff1a5c8fde40e29ef40a84a6dbcc4f184842fff1bac63275a3127435e0eb400e204e9fb45c +expected_result = pass +expected_shared_secret = 7571990ef1ef7e15cc920318fb75fd38c4ceb9abf7a4b1adc2175f99d1a0a275 + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +private_key = ed55584416844e1cb3c75acfb3771013d1aaf1fb3ca8a5b718a8ce02a15ae26bacc7534f8b084a665b0608780e532a161686b07faa83884c6a0efb490a8a3fcabb50add21f58ac43ef4355246b1a661c5937562fa6067e7aa66978e4b36ea1431ed41e4e4282d4003d5bbc06cdf7af225b6560c44f43a278677abba8c6b79741b3ce7c0d0769ab407c9b39c032f0e42d1866addf2115e2f3336384c61ce9319cc92ac1350b264cbc4059b94372631c8241ca376aa6f76111537018c01d1346019d628f1f00cdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc957716373460a7a94151cc548f0c78aa5a323581c192d00b4d96219806a04b1a0ac829002b7fcbc8cbf8a8e3abafd3dc2164d03a24c19d50133e967c7668aa8b81977b400067fad2ca802a76716b95e3d28be5603e4977c33d3ba5df2446f6265827464641204ed972286b58567ba129bec0cd6f1644c4032edd6239309aaa259a3d997b1ecc535f17d773ab1c5350e3c82c600175269700a56b0d4211dd02c13d4bc7c54238f40163441702613a1de34ba9b0b42ef0a29300098667e8003588577e64b031139dd2180db113623fc4b74e946eef86a1a6bb52764c6c12911765e37a685400888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2e818ae3b7480f500fb6bb03bd50019c33bd37b060bc2c45e8a2267d18927c0af66076619889ff6b1769fe59e5f131f5fe40db2815bb6886b7bca9da659935db493ded9a808157e4151b04c153e673333424b7aa939559e4ca973f7644a813b8d9c1db8c87cac6365c0e008e329403c69490976cd3f006f3138114a6b3e6b3c4f054451e5bbcb7d232f285a2ef5202b81740053512f8e4b33fda87ea61042d1f9736ed58e9047c8744735a728b636dba7abc33b2de0b1572a28b23c25a8668cef9291990a499bc8935f955e1cf0301a65be870b7f01f06099192431f3436aa5aa6564c4689c1d2e11540355138c91ba6e0182b6daba0e7a177ff320c6b04977d47da0d51672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca611893044460495d8a46b242201886cb52e38d91d25d7fa8262290628d91323dd2a51f8c7a33487232f4934133117699028381751d8594fd94910ee4115389c57262ba579220567a7b5b42441a641fd6630d7bc06802878c76bb9ea576965ee45acb90ba549a01b6e873a1d8c741662067a116e64c8897e83204170c9bf2676ef60c20f3450804c7a1b80725da17f9db18f715b7894ccbb53321cf01755d168d19a96356ec07efc62d9a8c3a8ffb15500433f915137ac42a474b8e43f283bdb2b46cd62d509a5aee8cbe23b74cd48079d82293bfc9cd931289a0aa27d8a930beb2000acc2019e3cce107a18e9c4408c516fbe19e45459ed77231851b88b6b73156ec820a4c097072c2fd61c83d23413ad510662894daeb238992138f98185042b53a637aefa83378b026fa7bc314516b25d343f0e0aa7772cd2da27f8b39a8becb44923792a7d586631b2ab963ae537768e45961f5f96cb42320e75738a964168b9403d5b3591ac5679a61857c818b2a486bb299019c7b03beb50d2d40a17e84712aac01f1390e49f3b488ac39d0e43292b70042c52355eb48b841887ea256055a688fcac5a71c896414ce75f57bba12967215c50d4b5be692b6dcd1ad2190a3d785c19e283f87f784a03c8f52a23e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d062ee1ab3922a2c9b5b02d14557164149c62e8029b139e6950b3f8acc9e8c30274b69926c1658f7836f479c8cc70138b829848c7698b179643b7550e9193d6fa87350503c2b69136b08cc298b5c335b1ab95054d13c9260625e34c6c2fb8186e1916c137ad9907c8b2ac9d88faaaa0375236751a47918f96477b7ec01819f8ae1d72951e21608c87532a9428bdf4cb5658440cb025ce3b271652961bd935624b9eb70047e63184b9503adcd057b6744fe42908cfa325e401b9d0db5ada201f5d64350d392c4fb842823895e15720dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa3917130308f2a2aca964790baf960aa12de3334d146e64db81ef09563c9667381424c809441ee989eec93597e7c5b558a89dfaa976f6934cd18b8eacb6f2f54e8f748e4bdb69b0764fd59352575066dc242dc0f1356fab4467c8064fd23f8823148b77a4acc642eb2c181fd5ca251b323561191cb15f2ff0784900a15f67014b518453c4c3663528ffb53271e195c27533fec8c3b159ac1bf39c6fdc69dd5a5fe5872ffb6b2271a09966a5c738c48e63e141d65315051610f0f5588ac97f14100027b144aa23774f199d0d9a122953aca8782a4136820ffbcc1f2692bb919b674aa1f4d679e8418e8597c74d60c5c287cde6d44492411222636b03cb661ad66fb442193690a5f1d6b80a947442a46bdd239fe3989e6da86949474e395056a5e6cb42b25343a7c73b650d843527444243852518a9034b9efa7a6bb8505bf605ec238ffbc08cbee35a94845d7319144b381819d0928c27023b727656ea843140649c03098fe74c717aabe91948ea7698db0a86d34296b5e50dc0a9949c8ba07f64ce60da2b6e62458da229d52c08b9b696a124a8cbb791c0d255d3e4a69ed2c242000dc6476b4555552deab63ec19fe8783151daaf78e561e1844886d4418e7510bd025299b1c83c7ba22f63335b9823043336da897a44fc6a28b44c68a49b436b0dfa406be642a5bd303bb0d633685364d80440cd7189b6b34f6535101979ba9d251474fc91bf2497670bad0da78ab3c13eeaac864572a2f919546a57c719bcabc9dc8215b492d53118c2d379e879234a700638370a530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d8891b4904b8f5db93d0531caff25be53e28c45c94758e309b83abc2ba66d98d3bdbc53b7d06592f2712663c777db60aff496a217e82d8272c3a218ad8c8b04ae7c66be35c08e3a955fbc18edd07e8e68a806fc3fe218b87f87bc332b86c2625d8ff01c9ff6214b75a20cc465f847511030b47ea664a75b3d4ed9038a9c747c6872de0a57f3b76c60585ade64570a21cf8548a5be4996bc22b3d16a7bbbd20149034764b820892b9394581697e39f9b35077eaaadb06702968a5e5418983110a97d4749d3160ddb2b9c587767fb56b9ed9bb3d91cbeae141769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 011f7beb6c4be8f266d9d6baeb2d0ad7c3f7a4257b770a8cfe675d00d80fe92975ede583a59727628ca1064987718fdcf8f8269a371accd47560caa9daa1cd606b258b1532eb341b47963281d843462e822406a41681bbdd81247255b4ce037514695a4a596ad23b493cd368897e94c654a69b102e4aed52efe1ca2407222ea5874a4366f3fb804b9d482ebe6ba777b9d79701dd04becdd10acd05b0b4281e6db009188cc9a0e263232f233091af61005f8258f05e638f7d779346f59555827b92b190829003f42156dd0da2f43a3ab17731f2e15f7207b11f4ec0dd6ad56cdd5b5a2066d1788cfb060317cf36b90ccbcf0014efffdf291606b615488a762240733fb52e0fae719f434414e245eb8e7ce84ee0a35ed39925b233a219d60458c4434243e6575b2a654c4c6dd8bee20302b442201d846261f1476098459d9c2f548a097dc4043e8403ec21f6df98a2f1020a09e7609dba49a5df6e91fbc705a09d39558d7b12ac4092c96de40c18cf4e0d2e0aa575716ef57165d38f8fab47e40b914d75e5f4dd65fd99eaf77296fc742ce9e52728297729f9ccaf0e58f15726b6b664b3998f3eae5db3803da3a98c11149ca1c7c1dcec42f6b2be604134b381e4ecb044be5b1aa0a912e71f59d56f3d011ab99d3defdc09c345591c79295a528341ca533af543a5777a5a5df06527cb961a28075491da67334ca67f7ac1f8b26855ad3b8e05291fe9d401a6d6ef19d3e915235aa3de6556b7fee9c7faae019bcd21f54a137ba08d305ded214c208f197ab65123f58068d9b770f79ee0f022c85a5e18c0f99d96ea57e3df44475746c3bf59ccc5040b88da34c1ab7e477cefb479377844988d1737e56b52e95b02ada15df5125b6a380cdda6331ac4afb8285638465b6231169523096b49b0d13bbfeb905483893f5aec46d003fcb37165dba2dc96cbe7c269eebebf8f437992dbf4dffc7b69f202580b84184ece0ee39b6e6b782e33e40add26469687b05b06a02633316b8b1bc251aad358327f998dce5a95e7bdc5c4ed526854d5f44b2e1c6403fdfe2091f9e31cf706c18cd02d1a019cfd88d7a9429d81405c1be11d57582ea371b80dc19e89a030982177e3781ce086ea0d633f09e11ee5708d90e37e8c68eaa4a419e2fa01b07ba6c2bedcf57b03e740da6df1479e3dce41a7a1b587b918851b98efc67218c19d2cb71a04961ebd147d247d9834cd8c976d42b7658ebe82194d823865cc5cf1125b0768de6f33c8aaacf45ab11379ff8d920e1f1addf6e570c3a550f8ffeadcdc0d9c8174f2cf3c3fe70f17808f25c49eea9ae043208bdf9d5bb61dffc86adf687fb60bf3f8eb289e22125ab0027383fa2fb04495a9f70c66fe5fdcf1bedf9f9b7b52d6b3f9f39db14572e707a15793d06fbaad499ea36505777455420acc090d2fbd3bea249c225403a6e9c80b1cb49d91926a9acd9c66388386ab198421f2b51a04d914738026e009b022f1d4d513d44116bb293e317e22afe91381d64629145a2aca70d4b507c8fd1a +expected_result = pass +expected_shared_secret = 27ba4cb50ae44cd938585e0a4905d76053dd851e5b6af4fd787446079aa5a4ab + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +private_key = ffd8874d8b37c946409d69cb03529b7d1a43ddb24792d4773cc723643567671b8e0fc2b903d302679a530118ac453b0541a2389c46b38f317b43130972271d8146a66593b8fe659db570c941f1abb4f295493085a85277062c3d4db168e466015ea506b5b8a805a435ef6812a6b68afa9372776717c1042e24e7a10a842182e7c40c4cc547b98fe007a1d98804ac5bc3c31b6511425a558c73e5b1935c7a664ee224955b6d67ca54d47b04e1622716a27b21f12a2eb27c16d26a541cb0c1ba5a1a8629b7f2222b84cdfed9cb6f666b41c92fd0b074f42b5d2ee72e8c5443f34c5dc2920da165558af074e3ccae84c1cbf1f70624e1a3a30a7db045a2c4a79bb1a4b0f01187bbd8b29a8c60b07068a72264d9b305b5e391521bb945d53ce1d65436441932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542cd626637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356146c04bb8391197d54d0f4202f160824d900b27b36bf8abc7876ca331c2c3a8a161d98523adfc1ef9d538c9203a6729cfcf6089f7d72f57093ea3a34113749f23ec21c051ab2c836679b0210a549f2678c7187691de949994a25769d4647fd992be411e24e302c07569cf26c11f3942ca505391a794d42c77da0a324b05908aeb9c70b88b38a95f371b1902e06d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab967770465a056de9c4420662c046aa8ca32093ae23abd80406fe60bdcd1725daab0e50931c575a0c9137fa61442b1101b05686d398a6fdc0bbbbb25a073e99c3702b9268ca91420a1198b5c54501a03c878b6827e6d586ab42c2fa47258d1255711654968fc80e1364886f18e98fc10eb85645b399788dc225b1a233fe564604a86397a4483c102203188df667961bac9ef19b99432475c0a2c9978c81cf5314a2b2ab37479549b14c8d70ed8f0c6625938ca4a92bee5a7aadb286e507ee8890772c3353e35c2de8696041bcc8b81997f8c7800417c91c32e9b8b34b62a25e5c2af2854cf902269c3c5b50a5209dc1c63f8835b3a73137d855c69f9335fc66efb985933f4a66b084aa58909e658998a15ae8b087120f59a00426cf9a327dd48467f8c12cfbaacea7bca7407060c42950cf9543cac1edf9c296d978a2c36aad92b665d6c9513b59278ac1cc781204e555e27f81e976a74d3055a48035203472960e596c7c4c2d0158a006d884f40681c6610f1124574eb9ff5323e10480d0e306f1e398ad1e6cf8057024d072def4719e3a6be9aeaa07b56077be495a635c67066a2945376c9836ebf4c413a05a9b1348c31329884bc7d820a6bad7a63bd62518878a97fb525332433573973df74a00ec02d50198a2b1306005335e6a51191505fb244999cc333bcfa4e7845b766b050cf66607982014d28548a4454f86a06e9321c82781478cb938c709ec5cc81ea1a9269543dc8ebc6d253be1698990c81c587d7263e7445baf53316c23eb8863d151a4e5659928ad704c1c7b2bd2a1987907a05ccbd2f0c78232a10653452e3dabb7598ca83d37166791ef11a2524f371180984bf72a6e2291301606b7351a284a1a62d7b0180596be297a4631abe0d48a046dcc99c8912b8255fc45592a2a61230652bc7c450a674ccc3abb27395738d177e7579afdcc30e74e7c7b5ac5dc235176343cfc4920ed8d9472e13c9b36a6d38bb44756bc31fbab62893656da065901303700a14b2f785d98896ae97953ba358fd53091012b97498cd7516b0e1898e2f6803c5a13d70f5bec346917249940ba35e3ea954f6ca13c343a09cfc02d8e66852c1ae0ff8b22e7424f53b1897ea11268a6b866c09efe8694031754ed1a2a147c0086283284133aa6c324e0b0570469f09e0901f25213ff9b113147990b54cb241268e0b6c7a3a90c638b7c483c71ac1344bd65c988736c4756e0b71111bf5b810fb3cc4187363a94efa020de1c3cb9a005cf472bec5685322faad5bd1cb0f240458b56fcc5a6167f22577565dac1ba9b984c33c348babb70506b87926540547389b805ba01e4443b5d60b9a407f8b060fcd96c4b717baaeb72400eaaa9853b962e8a0c8d966458cc4cff31e960c447c6b205629419478360cdc945d6b9a55504d853c1e51364e7a9aad82b64fc37a02e4139b9e6c392dc83c04005f6d1299d990a89ed68acc31b5d1d224f2c8b3cd5280a12c6e088cc2f9d3c59afcb9fee458af5135c9b4b477d878f34723e3912189d2764f9366ab8752c9248a5684296ed46f404a1739ba72d5d652c614860d41898e45b72bf66d587089fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed880048885355f193ddb1690b9092aa2a86af03a41797120be84334ef25c2e70bfe8e0a658f03435b65787f38bc9452ddc584162955f8b8560991c407fa0c12d770e80fa4a2cf7b853708bef2a44f959b9d05b6faef83f6f41a2454257b0157c55047ae7d0cc17079e118c8a4ee3358d877251970eaf86684ec70858a94bbaa4bd2fd1895c2223320ccadce636c2156471b76c48d53e6a6c12a1317c39c48bf3a0aa0dbc8afc034b43398b9f1c56d407a4b7c2bac134024df6ae9800b230e2592f529f79f0ab048867a349684b242bc4d2284a6106dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b22027d6657f12379abbd248c6967834239e2d3a0211b73a77d681b61892877b7e102a53cb4602e3dc1704ec92a9e260d9817c6393062bf520f7a845fff19123a1662fd241090ac81ee1748eea878d53969fea20fb95688fcb3d235910f154bd09a75556d890409cce0a20c6cd2a59664bc4ecca3d4725910d210db0c848ce7242cca945f1568561bb90d9a4c3dfba83074a16fb3ac934c865dcebaf6fd90d5b458c22542ded5111e77c12d8656908557649e9155a8472d5213b46f739f095b5fd4a2418074ef7db9385f19d6630aa29b28881aa3474b7ac352c5dfbfb20fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b9190064f3a862d10cb5707215f456caa10a2c240619925a140b6cba878a0d40283efb9e1562c227d716d2935e8d96649c06ae9465aebf552d68da1e7991bf987a4dff4371049a0dc9e56f110779d562959f278b069b3c7712af29027aad6109bb0c3201565c0b0892a62aa74ca7bd6b48039066a95dbca4e76a3a323612269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f6196590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 800e73bbc8dc491180b29772408aa58d07cc850910a70660127c54207460eabfaef758520f288cfb6b7f1403986abf40fad912f2ad1d40acf9ce8d2126dd59c4148e5483542045aaeebb0fc8a5d86172ff25f8b65db0b1c2ff9b2f7b10f82662ad06e40370465f74c8ab12396c4b7c877ca8c231ee5a88358be2e6efde24d17cae8d8e9185255e173f465a9df4131cdce630cab9dcfc6a84a0ae35256358e643b068c521bb3a3f1a63f751a0ac8a2ca2771a30fd8f11b6c9dff802ed6f1dab41499ed0290beed78292b1ce7807ec6cd25d934efe72177a91c4e3727956143bc3427eef3cd9daebd5d9f84ee6e335b77e2f0aad546b938a6e92504d3724a0de4e8f0d1b4ca83b119d92fda08793635b25a4547d910f2c90c143f891eeb14e52b5874905996cb88536643a64c931ddf8048430a63e1ff5be1904da5b136ee0f433217d1ae3b2040327f51323fa93a20610f273ad3af90d2c649698d524c407e04b8aa25ab6e5580be5025f34709314f80f06caa9b2e342c404679d8a08453ee3fa0b59c0b04bf14998bee7be578871deda59931c4e665a1f624cb181e22194bf5b0611cf6a41f7c3cedb2d52dd30a434a504e60ab7fe4d5238394d5b340d38bbde7260f3743f31b3637cfc6f3c6777d9f6f4dc3977d962a558bc533725f315ac425f3e2104e754d361dd24564aec0bbf5cd3253909e091941e8b7e828ca70e730abebbcfb3dbca1dbbad3e16f0d68ebfbb2b208a177ca988c8f69874650594e912fffbfc02d274e094c5ace6e480a3e51872488955176664dbc42501d9b0b4671e0fcd8e096539908d0147fc6011cef14dabfeaa9a1ca31f3010f17b1960e8233d8e2425e96c37f229e53390d800a6c059c3f6aa2b74ebb5ed654001cb760531792d796711c4eed4584279fc520a8e78995329d2ae238b1745f7410dd9cf0265caef5411606475735a6c298941cfb7ae810524c870d355211972e1856d471a7f928e4bf400bda5ed9707ec838b43a4dc080f2a96600db1a5759b246f7f870add6ea8f91608375976d085a5507c9a03ee3da29d77f4a2b32e51a90374ddd79e331a99ffd0d8458bfb5a65fedfa7196d36dba0f2fc8e04ea9fe8cee7aed584eeda24437bedf1812d30fb096bd5e3d7613d620f93dfcf1cb0cd5968530e6fe291ada0411daac93a6269d66db7e3908e91f4511551de33da82e74ca2a6fea7006705408260d7aa57387b8bb4cdd4809b2b140e264c25daaf9f50a8fc28274c17fe1dacff35b4006e311bf0bbe7ee895d707cbe2f1c46824a8813882d46d2d6de5eb8a4ac2afaf4939f36459f64a7dbadca53e098f44d8a0f75042ebe6ab566c8191679f6224bc6676f3d68bcbf422a8cae661c231c841df80d9e40566176a58d610e006811b8d0863d73aa66bd59d659135fc05d0568f438f82a2d4f9938d57811c4f1654dd127ee06fe2d99e76a5e716674d389c91ac198ee0fc0afbe93ade71540f2ea0cb2d63c5c45aef6d0cef2d624fdc309c7d312a39be86bfbcbea53fa206442 +expected_result = pass +expected_shared_secret = d17b2738213a98f29ee46747c93308ee7000fa404b9a0c1acf3f89654ca2446e + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +private_key = d32cbc1116ac88219f9af2c33beb59bb94b372f97815278f0fab2c690c94b8f209dd1575bd7c0bc7f48aa133bfa068cf1af1612c3325b8d08963bbc66d938f46843fee424357e535c2259ed958a75ca6203286190be53a9b46373f8b41cb38c1cae2bcb91898669a872f1a8d9cd21227e42ed655569202cc6b494cc6a6bdb08731cde417f48b86554ccaf953b8fb70aec727085510cdbaa7cd2a0ba853928886332fb1e3a419c49b34ec90fd31b716252acce7a79d05cc04074d69ab3cc9809102261a2191a086231dc70aa583e86912e5beb2c1a22e841f39db531d5c26cc333834a20480d6b1ccf19a654149045791d33b414696375dc3c7b0644626e8822c5325d52ba764f2361d853d244416cb9a5bc0540e1238ccb53438c90a196a45571f743894f060f6031fd623abebb4afea05190dd9452c981352a78e09579f05e24db2033aacfb10d9335986e8542d9480bf5603fa932d2d0878c3753e6524a809324ad6f169d7fb6d9c0264423a632996abf297707d8412a6b86160b69980e18add1c372faa406f540c00ed0a75c3544811759c3b5026e6c19102b7160883ed002de5807b5933934fa01559c4a790230ee93c215bd75aff117d0f170b4feb7aef5b007aca616e688161fc00cb037c8232cf2dca569f01a2e1dc2af7ecb6111181f2ebcb1df27c6ea84251d8a2b6b6582ef915e2b8c7f8fb6be8844478fc570b8054a067b34120b47fc6ac68125cca8514db4540b7796c9fd05523e7014db34b8ec94d5eb66c9f5cae2f838191d2234f43c72262a18deba17ab495b7f0529d89b8e1e407bd5a185eaa2444d20c6c9566526b8707b13bb0cc8d9589773db90952a5cd78e43bdc68cfa4401d7912618f456eb4f97ac1b49ab948592976233f962b1916531fd1672bb69be320a2985b38b80279572488c5f86bf3d55fb9fb90449b66fc874b94292000466786fb7e393765c7057051999711d234b4d277419320e0046ec0925b41d6b89c62133bd2734e296dcfe90bf6344219a6a22d2cb50c75bc02b07fd0da11fe0a0a0b9aad76001d5d7c8fede065dde87d5d47821e756a926638395883879a91b94c6164a40895476269917caeb12944dc956174b6cc5154944571a6f6553f604d3212728fb08af6e8c0ea00265ac0c5464595b31a9131871d79298867aab426d009480c0befc08ace14991399079cb62de9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e63c162ec911101c5a49b35475ae68634a7b0cefccfbee608cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687c92cda9ac9c03a9333a866a9639803c76b5b189294a269f389abb5010789d410b88215c554008cb10274f781ed6b0be3903576cd16934c4b6b65296c477aa174043f06792f3944efd0206e34042d827caffd2989b936b91694825c4bd8b10c0777b11971cc1efb93ec1b3674afb4fd07568ffe89c707b5785c140d51b433b7942d88a6ef9bc9d091472833004005aa803a050ce03b2bb551f62fb1fac6649d3e14f0141b2eaca73b700489b73a8d840834a7802a96864610b10f3576ff861541032094855b18cf574d868b0eb783ce9011f28fc14c486b122cc80093897bfc8ac1082421f99767bc42b0ff41b22dc7b50d5556041338e6c4368ab190e92608f6cc69d8b33f1ab04de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f150658715403d1e1c957e5a914b9a3bc4c45489053306329c7984e76f169c8639de4080db1671ed01a24724a101df89e45b5b385ca2ef663586ae58d9b33ade9738f84482e6e28909e7641aa673ad772b125161a316166e1717fdbdc8d02b2b2b6dc21805619d4facc40e9a21bcca9d4da71220a4631e95b25e960192a22a39b904bbb02f1184b79a97b3cc16b5e4b5eaf278913b7a195f3107342a77a68cac90c1b5a3ca9b354a6095c29c09c5ac2b44c6cb28a250834d5f2a307ea3434977d0087017ca2692b79008640b770b41ee2c2c77bcc2605f1857368c8e12983afa8633c870115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68c2198b2fb558f463a7477b9fa7680f1e65706a888b8740a87cc7e7949156f896c182b53e464721e46a258820201887ce9b83d43250b63e2ab29900a115084a6e66584f767853b2e684c547d97266b36b6838aaba73298dab79c58c88f1b51113ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd78106ec0c5e9967a6d81139cd516027c25afbb6c47e3802d56079e6265c4f21f1315a96ab994597214b814cc53e8566330cd51fb4045f605df1c7c9c255166651de6041b7fd85c7e376e28076ad352051c65494a1054c30930621c53ee8947dce3c55bd686f186cd5aa21afc17664d36a2d7f5008ae83950b93ae510847552a5c2f761207b0f478c73c4d6313c8acc25b13ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940b70b68f40bf570c461f11795952e69f21ec4562dec99448263188ef44e71a1681d626cac69c6b56ab51ae656be1ca028672d97d044e43577f26329d50851b0f8a4a1b6c2b673ac6418ccd58005ad400c27d274dd4732e56b5d7c0b6ee731a99e15229f7295c153aa3a873c20c23a35b6137c824f6fb021a0e28f98bb3be8dc07a5b038dc89944952913af7a39a9b00f1a038a628686a735dbd4c45e0b8bcdc1c1a902cc4d0571cbd589f507a0c0dcb81bd39811e723358d6320a3049bcc90d776562eb34877978c9929548286a85efb85f7c6c76ff255f13a0cf5e70304f1cc838fa398fb34e26ca662759c8f3657125dc2aacdc4615653ef074a784500ec60980be4aac94b0c7a9012dbe73cdbf1687a684ac63526778926654a4ae4cc779a600a836e3273acb95a802051f18af32683f52363572583fdfe30287b2632874cb04832f55e0944712c86d37420137c56f6251a1352ae37a0c3fdb885cb561e63a493a15beb5e3b123aca6b6b7294d8002e7ec758ad2c22d336aae3c067703821842cba2dc0b1b7a45cc0a48202a002f927122c040f84a884c1334c1e17347108b91c055d331c0b170c6f06048b40ca0bed838ad963fb8747ca714cf1d3267b701132046699798421acc06a3bc1ade172fc62123235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffbd3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = 9aeab84b3e0a280ae182a9ee4f3e5075883a9e22f0aa84470b1d481a7a1c45acd500e666cccfc98f1d01c1f1dd3fabf4d2a60e8a4bcbc237acd856622431f667719e83b8ba4d14da5131d9b377998414f3ae58a98295396e41cbe34a8a3b65ee20db915136097e6676a96c093da827c206f9619d09d218468ef0a2af7e3c06a647a148c26b706507b792c0eb9ba46f0d7e3cbe4e71488f83cec8af88fb29e3c61d43221d21329271c77001acaa2d47f2e3842d221834d20e232a5ba3a49f33f7a82fe0cacd6aaa96e24d2d75f12a71eb10e5e554c98adfa732e9d5cd6cdafd6a3fbe97d7b464b15909499f6dd739de3ba963406ce45cad0e8e25122d469857b823b821f59ffe138a29d19c4bdea4e839e5191e7187ebd96eb1249b50a0f4a8d7e3f4930162d922d296301bd4955c44775b42b8e06d25f731bb18e8cd13c1e928ce58b101ec64d88a643deff0dda247300dc7de01e1b8d1643c471369528d94534fe54ecd90203c7fc680582140ae1abc4963c0158d26be214eba6a262ee6f35c73209f9ef2611de8c37152c9e0f5d5195492dc8d91825593e2af1f348e4bd228ce205b50f24fe769a5cfb7462378e3c6f87e680501991e8ef4babafad6ac15f1bce68d0333aaefa0b8f169a2431890ea62d99cfbfba14ba9d0a203c967ba3ab036f485f96cf2c5f033919a1795f60c5772f0f6677aba09c56bdcb33d44470b02e7e1af31cf9b449056ac3b2eabd13c7ced8472744e4d0b8fb396b0791a956e97312b376eb045d7cadfe03c7153a4efd25dd393fd7a8a47bcdda4d4279183bf2dcfa553340ea026a034aa7e8c755175330fbce7c176b4f4eb45485519a72bb4d29af2e439460ffc08610c3aedd144749bdad2dfa5d674e0f6ec6e3fbba1e96ff5b3cbdf68b187c98ba31d25836e25a82e8434c0b79c4c5121dbe00d6a45947c2f4b7a6d2b04b5f6f1aea722caea639bac03b282db978e98235ab21c6714e7684ac2aebeab9b4418a77277cd3da7abb0a44c4c3d2fa28be6fd30a295d85c753dface9090ae37e56fda6c1cbdc9d4d5eff7388c3b96a909da4432877263f67492c35a48ab28ab686e1803d18009c62599762611df174ca87a4c5381b062731b3bbbcf07b846040bee6cacea3e7a1b3781a5568e7c3a9213320ef4877317cde72200ec9bd731d30d0a061cda0055761f0221a1f804a4bbc23754c829d94df4952f36664e3f677bc04b6f9a16412cbbb78b2e5a340837f587388eb17e9ec07c29745b22387da055e1e0c8cf8c01eed2140f21a28d38441d1ce9b263aed39dd1b20856b69082ccb797848177535b31f8065cd86c73cabdc68000575afa2fe8e5c539fba6ea5af3c017b6e3d0e40bd1e68278a339e49a4541d691b178758d90e3b8d016d89deab0820e4c0cf14a53b281e608c74586be07f1e0a5492e79a09f2c5464374c2f287c97d0a0b7bce04e55ebd3371c5951f46714bf52721706a1c086a1168081fc1d1a26e7c472fc1c13daf9f98a85568e993fbc14b4a635d9fcacbd698600 +expected_result = pass +expected_shared_secret = 954af53b4add522514b34cd2ab96669a76ca13f82aa2fd70826bc8ee790ccefb + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +private_key = 818b55fa5ac30a81891f3a3643924b2b046feb6765a61cc81c9059d1f82f6a0067a102825c88a530d15f0dd95f0b4742d29abe7044c62d45a05bdac46130305e3c3417d67f60b92edeb6b2a398119ad160ee3cb0fb52144435a5bb5412c0512dc6121bf6e72d0f87a3834ab5338196fdc950a3cb1b7354c4e50369bd4364cee9066a221dfcd580f1b914c0c335f547748bb19264b7879f206a9c610573b8676bd0bdfd777a2a0ca5ec891a1317c5289784de114e84c53b983778bf8933805256c9a9bd05a11af8f5ac271ac3f1e635eb9a8263c855bb230f58ea3b7e8287d76258aa57646b97560e593944c4cb3567a2c382a795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b50722a144737ea38b14be51c41cc55c53340ed158ab4a0b0f0a2612962b89cc2aa8b29198f2e04b0f0cb586f271c6414f31a71a45eccda8c597c38415d262571bf0a7bfa17115e0c7731c70c2d01c492c85de16c511102c5a96973c724f3b58b504eb65f56116aa7779b76b2554736d9d6176dfc6ba007a590a311d4b86a7a6251fffe6086ab3319db48c4dcb91fe680f45a9480241242e4ac9861b62860837cc813fadf00751c8021f7a1c4d7a1e5f13bc3e8462f372cd7498197d172eff98b1f8bbc37974b025295a80e3525d282fba8467f8079d78fa6068e23bdbb3349a31506e474ea228c3927a554d7747bd3621a0343cb155bc786075c3015c3692c0fc65b194a12152a14153a03d5147b0cdb423a3b50ed6461813f9ae1fd63ab7a53031dac2d0f87cacd1cb81461c8c08bf367c4ccae7626343469d417acc705546293498035195240387fb1f2e7c005de000e530b9e21cc7dbe463e7d24adeac1127026843b87cf6fc1bb94674399b0636506b1acab72f623adef866f883762b5b4509cbb2be142c5c550046e10d29fa431f9b7d977253928a8d2d4c33add899ad736b40cb4fc656be02d90bf8d393d632a1ab509c432511f1ca16b01139cb0627f6503bba75440414af97a04bc5239567c060ef94c9ba7221d4612eaa640bdbb8b72e32a4668401aa79421ba68115261a8d94878c90a0468510b247968b7463ff49a0578044c5e9147f0739f6a17b18828bdcf56966b1caa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e742cacb74e1d45704fa4cfc91c142453ba5c08558de1321ad6a6a2804769a0bf69770a1264ba5148b40a3a9be3c513a382cfa3c244c9a138ea9cb8da7627b350cff87ab064a079876893d893250ef59f369c41f9ea40daa5a5984c19ce06cf9bec2947932133a4157bb8cc3c72a1fd25715962a9c88026c018b7202885224019466540c9eb5482a87e665157be7722bc64133c827c20b97d9e692342f23fdb1b75ab2ccb6fa5973820b92ef1bb45c2b5ed1330c1417ccfb39fc6301b8a749d3613b3803a6abba20990151305cb32ba6a5b558265c2e27d8d49aef3e91819920db20360355919d5f641922233a1c24c0045172cb10f9564a029f07578a48a4d215248f3ac7a912ef8e56e366b03c567ab978c750d85454c68a5806ac38b7b3395f19fe78a001c5867d3e90e9b54bd63954761ab7f4a57b1fa32b65f285742c1207aa0684c376ba98c3a0415a3bfb0ab42d0a3d68cb171109c5f83147c33adda2cb07c62a9025b44523b0ae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da2a02d35610787f22966298ffbb45fd78a8d36eab454675d6951a70472caf06640bc1b97d6760e74b41c577855bc0756abe528eb4894e8776f1e739da45a9f84c9bf3c72b43262525b547f75176ab2e12d8ea808d3b0355766bd69d964eb3b450a96c835d7b238220febd62443b03985731333c54382d20200e30e4cbb2b607ac998f20def865bdf47ce78ac3dbc1abe33245d6fa7583b31b6fe7b6ede7a8ec776b20f7bbe7e376578f0933b761bb0952161123d61282cd6c80cdc8a85f9632aba1a8ef5925e410bb80beabc67735d07e4abdd587827745a3220a24a7b3902416befab3073c2cb1fa76ff04315b653b3e7c18343391f92015939829dabd0289b5aabc4cb5335d963ab842865bb7c38106eb1274eccd0140b415901279e8719c0415517b5101394f78a48f565317909371a3154d291698b0bede17052f30786dc2d46e71edc438c288cbd44445f993926bff0a8ca1a033b656c2362a659eabbcf37b2cb5916940aa9b3e850e51039c08c8588347e1099a0d8380ccc4b8cd0c87218bc24f09126a82a3d530a75500254510ac765cc1de612a4ceb14db78a7141109f947b4329158f87e4c8b41a92afccc9eb749d66a71159db90e7a36642636af22cc0d541ce52db7ab44baf30560691a637c93193a11a00efec075289953fdc9df3ec3390342aee44c08d661632fb0303681e1f89ce1300b0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66205c28766ba5eef7062363c19091c61c543d5c1b8a547372515722ee515e8ef52bf8e089d93377e2c8458e626d3391953d658cdb05c7a40077f4e19dc0b132be719014c12b0cc242466112e94809630b63fad12c99d271dbd38e5afa54c894542b940415354203a0c8a785ab94200ee0cb976991c642257d9af6998b61ba27b236fdfab86f834fb2d47cc0904b9d6acd2f8311f0d4b8ad81a24f712d92272587220e8023a8bc13bd17572d38851778f319607752466cb0de7c5c12103fae4c57d953b96be93262ba9cb05405a5d2a9e012b21a22a2ef33a385c898c80aa9663565b63241a1b206f3379abe8262cfa49ba05c3b43e9485e60cd38d66eaed114ef81afd66b2594baa361d3c3b02069b1a164bc387632e24c82a91be2ca390eb585e900173699a8b26b8916e52bd643645d3225df38ba50a50ea013b4b2a86ee1f76278e27f5a4142f034004b567f309c52acca3c7530162ed744a67481ca338861ccc3e8331e1c67886023743719493cc3caea51438e28ac4ea06b906789a65220e3c7407c874c6322be1f9b627386081753ad618a8dcc013395f20f5017ae2b57ba908617490460d5a67fae2660a56c4c4d97babda0bae0f494260877f7077af2536b2ca46e297c61dd8422bbe515519210dabc02e7047b13f16607ac15e4950574c43bf8c39a2528addfa2782506635e5626967a1f30c02fa3442fa93250571a8173999a88dc27b43c476468a6a4739972dc1b68493413a2743b9b563283cc886916eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = 0ed9d867a5a681c5294598bf4ae653943fc39d85798d3ab337f344892209275d9916e72cac7e94757cd91e9c35b23e04a29cbf32320395c0201075f704a0149acb8b3624153e2d9ebcb6c072009850f3fdaf52fb27b559dec221cd22a24080b09b1789e5c7e0e927b613291fab9118ff69ff7876eb2fdab05373240ba5b10339c168b635c811456f2fe6295f1f22f01c04c8ae0e49c9e303edd658ea87a279b48e3a63180a645c40e1d0ea1f7037f53de37eeea6b3ebc8a455d3a2356ea047e09df3ccb32cdb60d7a894c1b708b6be01ed9ab7befe611f3699bbb54c1f9fda9b3fa6ebefcd9e535ff1cd1deb3ed6645498894c8dd29c89b6b4fae20bcb4e05876aa9ffd200c2672c6b0bbf2df9143a1a1383e3ca7ff7691c5c5bb6e94f489d8d269b6f19fb411df8865f0d07168df6fb052a31579be29954d1e6a7c9204e9095824b09e9c99d1b7f7c174dc653ac55cd87b6ad0ffdc49e54afc500d7e9d3674355f199c24ed2499d7f01e789017a33aff2f739e3b60420bb9658f2317fccc39663067fc9197e3d8da3eb414339d87439144b8b6c993ac3d715ddb2603dfd2b73fb1b89d7f46dfd757c1d2b6043f83686d7a8e81b699af1d4071fd4fb30309aa7a730e134539687e9cc2ea29dfdda6ef249ce9ee85b4e1c84da1b91689ded5ca4d1c9c9d8ac446139cae39ba54207e70fb18970078cb8256a0233d8b29a0e7883bf076c45dd9219f2694f616e7f370b53a853095435b0ed5a10210a9fe9e6aaa79076aff0dbbf7f9cc4e267a1098221c9abe8e7d9e8d36401878b4fddea1049267d1928d44c3a6f99be6bc476ed91feec35d9504a085e745e39f2474e1d3d6dfd9b8994014e294093ea397845c0ccc9915bc5c800c1e799a256174ebbf65ee8701e9af4f355c657a7cfd36ead4b475c5fccec52cba88e0e5e0306218bcd333088dc31ef4ded6a2294f29793abb4e3762df8b74e19ddf32a641ad8d1fe16f315c60dc68b2d29fd83d2bdabcd92d7cfa4e02818530787d60b19618a101d71f964dc95d1a921b28eeb343ab4e6008840d226a0e9e8915c3abc535e09351c0d898557027cfc578a07376e878c6b90220fb36aa04834dda6f9b7c1d8313b9242e9df2030474afa0743c9434fd189e64e76518573ab7a054d81e1ecd1321963a078805f9a074fd3920b7d4e1a435a5ecc0a2c25466913be3b209ee3b0693ee561e3d745920029c384f53c3abdb4a49cd4281ceb70eec21a9b47a693db42ae08c88d2ff41ef3d632080d33405a21b516ba377e521e868fa3659890ec0200985469873bf42daf4fa5fb8d0292c5bb8e9435433d2a4dd176c1d27f16e146262de295e2b1046cf5ea965e33ed56fb387ebd0fb39d95893d876e33278a699791930f833f2ed6e5a7defac09e6ace406deba5b19dac8440b6bcecaf85674839f775f279a8152f6fce0674e07603a69d10950f51da09b12e084ba70a828b00067ef26c9d3329532cafa9511f78b3c84b685f9b42d96ca5a1b0b399caafc45483a805b614f629a1 +expected_result = pass +expected_shared_secret = d0bbc576fb1aa43b6e76db0e87bc4ee3fa057c31642b37f3339217a1b041b521 + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +private_key = 91c087e623025864c3c5d9049e865c6226cdd2b39f8a1578eb69a864ccb2fa155db32702def5b50e973495997e18c6c21756568802a4bbb86c5018016fcb0655b09e6a4b39a8ba2d70e32bbb255bdd296c998a21f5716d49968dd02a9c4f4cb9dc72c874c232011225f8e8840f7589c2d285c1e72c8588c0a33a502a385d0527186cc6809185408e9c7fe6262725528a439332f93a5ba2943e6dd7b30d79a25939a4c0802bf57c755a5a0ebbdc8390f8aee407a541c46cb1530fe1642215556d20ab942ddbcd1627826648acc3fa1367db0b45075470196b46697d9ec6974f477eda553f80b701e853398c69a6e4970a746534928631e6b811e533a4d1e89cdd6969bfe0c861d2cec3e16d0035bb50573ed61b5dbd45c8c5b223cef4266c5a6daf104949eabd27d3319bf12a7aaa4e5f636732b28e902a1098972977d98c00a267225b84af1c8c404a52472b8d1a793e370b17a9935ee590331256620e302e390474dd6a17d17a50291b6bb940bc43f89fdd22109a72c8ecf9acb1e67ef6a423396225e6acbff2880c35673135c5183ba37df968330ce992dae04e9455267a195a41893194bc51c67393251a11ed3c0829d99a3d23ceaa387208e00974e73178459bda539bcbe89f5eeb05ee21be3b1159018a3262120c21d4972aba1a1350231d3a646ba70fa5b641ebea1b130470a5ec7c40627035b03d15696be1313b458cc9ac8460cf281a6976a9d2ccaeb9fb157300b4289a55eca386d3d8a7d16c21102aacf361578010042c3a6397e2cb2ea5224141a1d451b38fac14d7b64bd7b72db17408b0a8906cec108bb926df54299261b6b5c6a636b395acb651ce6b6018ea9c92c1525de1624b5570f7000466cc09a909cf36f34687265b61db6bf2882514705fb37346385cbf4df33b98686e0189bddea7268f598db1b6cc7b32792d5546e242a807e760ece7080392823004453048c6f743b87c1670c6d10e3001008a24590294bc9ac899bd588197530fef9c2b85ac66520a195c77a7aff61672c8cb74c07d43a2bab7a764e750663091a005c9af8cc4b55d502169d4293e79b365f60085b1cc2f4900541588819b5edcaa3b80253178639f63a3091701c7e7b04e95435bdd2114bbd3abefb23355591b0ff102bc94b56b338083b82328712733f2762c5b1d0845073cb3b46aa28ce2cb282a4347f2118a6e062d7e8524147545488a01378a853d489c03eb0c6527307fb0ca5f7aab6c328438d33cedc10733ab8a68c7ab88e0b06fc51c92c557fd59488b6245796b7dc291728121bc7643aa5d56c483186cb55086d7e8654691cd5eb97580f0a553a2613c486c0b9566a6f05f9d2b82b57345aeec1368cc126ac53b9e794be471c16a498b743c1848a14d53478fc341a0ada42bc2e0717fb6965737876468515195050d64079d624da1596f88819fdf95653b8217f9885d151821a9529420ac95dd928fc429674025882c9758226194615304f1f5caaa456182c1bb11f0a02b6c758eec4ab6441879a42450a024559697c4494d8aac2f7045342234cd8081c0077c9232e66838460ea26274329988af3a82b898c4efb033ff4101f302a898e84bcedcc45e369cd1bb7f3517280d6655c8735813347c3c7c05f81a176264a5ff791d9801af88047574008c870635457126b4069071242c24dc0977a8c13d43b889d27f08984d9ea657d241922bb12aa28a1408825b02663b970778bf669d585a975abba6bcf8513c11bc73a0c33897991c3428a5cb4dfed155b9a2909e6597dd8cac1ad62f9cfbcb27088860512859761885c5b6c5d89fd6b18f9e324ee8f80b4c507626762a22f4cb7f4527527896aaa97a69b8aa4fb09b16cbafd73a667e9cb085f7ca36067d4f740694e6c83c671071762fbba26a640c86422197894caf01b0af66960651998073ba7fccd3189148187ba22dd2661262766399a6b8bb943aedc590fa048816d1b9d827ca80935d30e1830c8115b18b754f20acd7a376272c119cc8210c9aa112d604b2022326f51ad674aa1579c081f12df04a9a2b4571fc1c21a8a4ae2c701eb2ebb0ce65cd2fc22fee530fb3daa6d82b3d46e33e9c918f6d33abaec34f45391245453ef4d128c4c068227a6511800d69f6a31a1421e2d322f897145961abea377c9393acbfa72ab3c3aaf7f04ddad50077e7c36ac46e083075265c58db4b7b47da253b8a9361c08a1248b53098c6b797622e228939f110ece18c02ac613e00b624c61eff4524f92c1ea632553d9b90cd886fd2c364b25c877459ba6de0ac8cc2a8b0f2c6d71a051f8727c2892d1934857eb995a8d728b9739872ea472e6602f2c39484d290109ba924933d6ae52c30eb4d80935f0d2c87d4dabf07582cae3c2f21692f0825c079ea6700065a6086b197582b76cac90a58451d7479965475ac8a6af662c7d23055c404246264c97bd23d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1e4050f97ca3e9ab31e561ab18cb3af721570380023a9349ed6bbc5df66bb243928dd3a4b5e113a0f99725c9c8bf673818b89030db28edc536c9620a1625c8a647bd3d7055039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651a0234d2325ed82369bcd415089692547b325ef28189482714c80dcdc5bff72a6152b70ac2f16707c63a42830dd6cb88ee646d882338d3dcb202408fc5210c71d1a8ba02b8c2ab7e06e43ccd85ce39a215e67914369c749c3978778592d9e34b7671283dc787446b5b70a32c4c1ca4613b01a5d0bfe55016b897130d1bcfb49bb5f08c5df9f15b6d531b06c53a389500675aafca9700fbc310fff968300360ab631ad95649f0bb47e55b90b2593d9a60bb0477ba848c0db9f8bf6c774cf8348c65695b31b921e4439e976b4306a47069c25e4a7515866c0bd77b44c7881121025cd2f28430383600e4ba0bd28074b7bbf2a2a3bd62a73ba240d644ab1f89ace0c8a83ae62f642237de265765458d6744273e4372add9cf5215bd39fa516575bad72034288ca3e0d3be57dbc7ada731f5f13fc0252bc5a9213f502c342a451b933d3060a2ad8a9c13013e3d93455327c187547809fa57faa299a843a251f8368a715508c32aa57a42f9551520433f9675add0359c5997c341464264986fcf67261d16b7a6989ee33730754a2ca0f66b6c98cb421c8e4b36002561b1a5550b93b144d5552afee236357c8093932829f864963159a8e7ca992b8fae006190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46ac74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fafc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 94f5b9ef5dfd9caea5d92ed4a48ba23b9f55754c1aed2406de032457dddf538e797c2e02272aee5ed23bae0d5cba2e37e7afb8a472c75475b92f89db6ffa08d83b9160768541c49dc9da73ffa6f928bf16882b63c29e9eafb9467d0ffb5e3ac4b95c89a9462432ecebfa096e36901d2192fb2ef06ea10d908a48e9c1b2201b115f19f7b433d74a6ea836836a04e95eb93e1b844df7f36148ba6b218715cddc3ec5766df62ab97d5337869b14d674fc568a4c249f7832d34f05ce36c465ef020d00df336b2befb72659f97cf645d4420dfa0ded164cd10130ec7e9bb371f57bedda294e603f74b268333afc0d943330e0014ee57fd5a655aa24bb8c088637afc0d6300a8a3997f3e513154381a8f240d037791da03f8b536cb4a4a46059b9ef3c16de282cafcf7abf4c840584eef2a4617b3b015a0e3734aed2ca2d7c182181343718934f6f4bfb7bb3806ff6f412ebb0df25b588fe79a60f0118c9f0de2ad09031eb00f635fae0a2dc1e25d8460da9faf3d84c785522b817442fc1c801b5dc0192480649564731eb95aa96970b00677df4b2328988ef813b13c0175f6b73b2646a90107f1c031a920aa8efccbcd888ab6f0c249d22f7a08dc725ff5bb6969ea5d8a319c7c0b905c2c3b9688a6eb0d42e9b6d51f5ee1195b0591e7f279831e427d283b439a0432f77ad85345b1cf997e6232ebf21734b1cbb6d333e73e25f9aaa94de479b7dea838881b766ffc2f5e8813b32bcfde3695096ff2c9d201741c602be13e79a84718c0201a1232a89f6d2540e343327c1c9ce9c1687b4b030e7fc410018453f363d639470f480beb007812fb88d6c3450d13a9e9924b82198d9325c4ddcda7e3b1216753eb9364bc8954f1c3373efaf5bd0b70e260b712a79253459fcb928cc8ee8f770e233eff63b9d1d7e5d15db03c95a64e24c1c121e084f2aeb506dce765d03cec76be9bf8cb26dde32198ee9972ac2a441301e49dc703a8284ff900353951d390be673710d0f8c14b4ff42c15b6d2bb9e360d0b573b608b0e28d8cc8d40b9486217fa3c4783d1bb31e9f8f7f9b6852207b4fc9938c9f2b784ca4946dfa1fac87277ba62cb6a5b69bf34defeef435e6e03ec53ccf255fde48bc843df6ea502efe32f094efa52c991cde63678a5a8c7e5265cb096298f4d32d482a8149157aa4b025ae8ff5889928ffb3fb08499d704f3d146ad259e296fee0b83ec7fc4fd2ad036afa9576d1196c3261e2ceebf52eeeaf5cfaa38ae9f4adf7be4ba96d063ac8ed6fdf3480bc26c1ec8c382539f188e5b64e2016d511af0e8744aea561734efb76a4c943aa452da6523ff6b4c99fc8b13b51c74077cca51cd7d4c17b77f5f966d79e67cdbfd9489a71836c8e0f0fd9da93b4c1edd952d6300413dedc20fc77730811008a39f2b9d2a87e67d9657aaeb98ac4e73f99b4a5d9eddedfe04eddc6665cdc6dc277b5eeb5b86750096708205ec78c20a512bb01fa825ba85c8d1887d01304b10cc482c1219f97b5b7b97e76359c20b4cbb06c4df79de4 +expected_result = pass +expected_shared_secret = 91fbc37d4749ec6175c12f0d8eb6b6a8621e693c79f85f5cd2f557cafec5e7e9 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +private_key = 817471e55466b5babf92a2ad879c9c951ba60d230add630984b2528f9aa07ff755d7d79a2f9ab53d8986fd90895d5401dd97ad3f7a922516279b5858f2087e6491b7bc42b8a52a5952f23622d5603a0a3152990cfd6ab9cd863345d8be5e295c06b79332b0ac89282e61e5534fe0aac95aca140398b64175235b94417b8799a4b6d6933a8b815bfbdccf886664e7b8c5cb0b999bdcb2bdb288d569666c421e2a950d198158c0d36ced3a74d9032ab7a2b9f276be025296a773266e516826480e520b844eb69710120373a94705f9030ca200a7f85a94db1f55d46081570925a476099c3ebdb32c532a6d8f16be4de6416d0c30d450808cd3c08131a92551985b92255282be6087703f182156a13cd144aca3924fd15492dfd253ee5c9e78853590930521e843a0e37a26994197b3161ee1a60861c344720286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb3803f8053591b29bf64c2dc660ea9938200738e2c0c318b77ff86749c43c72f9667d80d462d549bdfea30cb0d9641b29308a461df72914b4b40213b62e68b161f83224c1a45472b5464f97c6d6371c69ca0d520426db8c1e938a934d50ae0b03be706b74cb8c674ea955a4d8ae1f6c0b56263041fca1871a5799921c45d9bbf13c01f0a9c5d973086b33acf923a2721c8b2fa7b058bb2e64f43bd80260b6bb19f26a4f55d53e7ccb1bfe3aa424976132c3b4b3a00908e722557a3657d285c8580ef45b76a207cb31a71402ba1ef280048378b80dc3312f78a74065b2dc873b22d37990e465e425b992722a25009a93a7a005d91b9460ab7c2336bd303883a151e829234c964265e42fbf8252cb89858d590cf0830e59c54021b83da94884a173be6bc454ad5a719252beb52a4f7544a7fbc03ce9091e9acc0568306e5bec2ed942b39a8455fa341b84571ac3fca43c14563f91395d117ab021c8f141a4ec7364ba4abdd8896bc6b281c751a66c767ac960ab52058335e14e7fd8a4e1d44de2670f9bbc67f682a0657530eba11c31381897d989bd392fae02d0afbaa5afa1748a80847af4b326f970c6161e15b212a1c66003a4317348374e66b29fe87f36d01af5f1c75be11bfea21dd8626765c46f0c153d0555b419227d50da5232810d8517b1a5e4147a52ad07012d8da23829f39a40c70d565937c58a11b1a25b27c8207246c4e1b40230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26eb251ab562c0e44bd238874e93a4d3b900a4b2b08a0b68c2b82c0cb56325548da3316279672913d2021d742c3619823c4391e64112b5b77e8d707f9c1a37d3464cd5f96543f720a0cc6c9631458cd9cedea7b6fcaa76d1e60c44f74b986a772cf593ae712214e21179519c39fa533a724fe8177ea59b1123e831e1dc561543a7e559697572157b60499c4c615d02099d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf7d25f49f61bd7363cbe3841aafab88524b0ca3381f5b22dc84c6a112979c3c39e45157c0749c04b022f83f53733a21e1f1842e0e72f78c6ae1e337b53215ae8563b16d99ebd6225766185a0d92f9a28bbf4e2b444b7c8225148f601d014bbb8839b4b04a592c364aacb2c89689106aba29029c58ddf7050a2c78787358571aa506570288e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a181d4107cb723bb6d0729ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b370d37a66ce048a9dd27ad17b38c66880491985b2af8916c547e9c6cb16b506170f29304c4393e8274ee254a3f13c6b0e31105442bf92799f21774be9a0f64970e6ab581626115a1aa3ee4da7936504d036b75be6046e5778f58caba93f8640bdb24982c17ba3445f2ab983b685644b596ef66acf739039ad0a3cd61bb80b000f7e8bf53f60ebe235c0bf22c7873aecc6b3ae2f3b2cc3bb47d1b88423a188393c43c4999c32a886807cc4262bcd5a588c5e1bf8ed6a6ea9910c19a6042679926f314e7c7c85bf550482735e7fa088c857ac1578560a1a2f7e831223cbde33a46632b7e24d400a82a8c7307c23d6ca25075b58e727673d7cb5554042cfb9b7f95b11a55a9fd63b1b9f0b60f6931a0ba1ad28b485753446b0005e8710d7189bf438407b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b6c1729e7ae22e28f2082a5e653b5babb0d147a8748f2606ddcc7847c24f0d32771b910ccba85befcbd2b89c5035b2062e6b9bb40828902b82e12b752d48d52b7a6599ac014731e8da091cb30186c849b61954dff867899e5bf27428229376ac7d97fa03996160964abe56d3d0278f9f91fec6bc821fc822949ad5ec8a9d728b95b19052ad9442fa0527b3935f4697cfa3c7413ca2e81b32a57f69479e89760a46d710032efbb662f9467f0d03c806b619b9228135076fa235d502230e56669e2354c1b412ecfd01a429b5c76b17ae2ab99c73b4110957aa38c22c8fa39c00261c78aa571b953d868690761655ff700803a477917ac8a6105cbfc220a30a0cc1466d7598b2058b3899c567a71a66d5c9da75085686aa4ad4015100360c6102c84c336c13b229ff599dee4cb2c90a1516682330722da110f42f7c0a4f23a2089add65438dc66246671be41e7766641b4c9139777e08cb4d5b953e602931a7db3e1ce70d765516242ae8987454b898f19c5103bad39207bb16771b5d4191abbbdca9b5bea711081ca6521149b60975e02cc2250a355897960a8e203ba148f8be76452420d2134b607976f7809ce97597d8ca57337fbbd6748c03227607fa082195b49753c43047b95a020c7d195b01dd3cddc4c091916c37e447acb606f2d232c37c9871831c1fb9a8d00717762f18e62e7995a7393e0a82617da4674078d8f10065a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e887107d6c14488e604dfa15e55004fda8b65ae19006ea7c8a7471b354a4e746703d5c79857a02ec222b78b966ecf161d97ba7cf39b37fe173485a0156c3712a6ecb14e629899da9163709b672a243d1b87e15c0ad611419d85522252bb5a02ab725cb5eaea5bda73976d534a881b8c32c5328d117306fc5217aab89cf51c6174489ad241d1cb261d449f24a235fcd46fc19a8d14a4281906236738a060061a494947bd91604431b1a2871080616ee2e915863b2bf2d9cd86743b0cc12a5d21c6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db85525167378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = 4f196d816122c6774617c45e22df48ac3e86c3378f3459e569534f574842967a369dfcb6ee004e1d050636654bb9d0f7a2ffb7c574010fb2f321f85aa574dc3e62993a7870475787ad35d68e5f7281ab98488da56a7a871e8a6eb67baa98c09b9ae117427268d3ef7a3f8f012d0e0b241c39d12f3b1d405093dcb3d20ed8aa3f24a0ef8c08fa24623f3b96845f913e96b1896083f7cfa047bf50bda06000b5f8f81ace902062982aab78a5f800a3d7d7268855e8451de5c633ae05b8075f2d6c98cdc8fe55d7ce4364407f4789f0bf91870ddf6630bc84d3d5d5f8a08e20561c8645a95e51b1e657684e6f9b23fa979c97a22dd6a2e3a729f74201892ccf378db23abe5a6c6734db7de54555e033966516b08de0d652186327af83691a5af4a8f806dfda5aaea644bf1f1c32a9e3a50e9c5783623f20e0f7cceac32b57a908d28277430ac7f2d32232353c1e8d34c4a6e5113bf2de9a074d26196459638f76801619a699dce0a7599cbdbc9ebba872a1bc1ae83d07986e534454ccf1cfe526d4fbf599e79cba747f4f2c6b3a6e1fb04b993df44d87517e7657d81d5fcc1b220a3069c16868e279351ca90c20a73345fcaf12cb75f43102fba680b641536345c154cb15bf7592611313f8e958953808b06bf0d5655c74b022e3a731280ff7a7cfc92a60fa6c51161e3534e7529aa310ff848b4a0bb7c00f2425bdbc6cc1c2fb050fd0b2ac17db264f48a025eba86a7b11651108174b5b2d859205ef2480b9adada70ae09162f82c3edf176287f8e742cfb7a233367867ac8bb2c5306831d3c8d399fb5208ae3f15a24a70493b62f7a918312ea3fad7a978beb11c43e679ad45c284a47f68ae2970f5e66972a024ce0d6424e58e0262a0f94ff07621a2d5fd38817f7d989a45282e71463ef37b5687291c4f852a6b13625308f3a4e6fefa0ed84c3cb47725f00cd88687757d3c625da09bcb8910a441faa38212a4bdba9a1b513b003efc55fdee2a3bfc1ce0d0b8a0f2cb4b828c5758a174fb40b9d245f63cbe3bc07fa68067d8feb438ffba418e50ddb8ce6f5548b8319401d1b4193ec59da087badd67665e9b73ef489b5249c8794ede24e70e3a2eaabab868508adafa1c44dfc1363d3d8091a7acfbdeab2fe73de1bab8507b180f570ceaab92bb297557927909045515974c230840faa67d9df34390675fe206bdc4b5a48032b455b45bf85d150703aefcf57af41fb0a094816958193162e821f10b16ad8adb8021b0d5cf27447b9b2c2c3dcc3513832d19b11a85b00afb03e79f3e7cc06178639eccfb943ad60d5705f1e6c8ce1c8b1ac9a62aca9500bf870414aa2613fccdd9eade567c135dfcfd850f5d6617b1dc181f375806fad84bbc69e28c49348cdf09d7714fd35a49d57d75ae6d74f1ee337d2ac2e595152da79059c93452f0f89be3d1b2cb5e2c454a4fbee52fd97f51b4da45c68efa1bc08441bbaa3082f4b633e06251b9859298b2c4201759538bc46874fd4678eb27d7d5ff35b4fb497ed739d5d7119e213a +expected_result = pass +expected_shared_secret = d586b441b8eaf7d053cc96b6835f093426677a7c3acc51aaa3ddbb66dd14a623 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +private_key = 60e93beb5544294bbd612141956430cff041e0f969e954a48298c7b5f321b9e1b70b7c796a753cc5bb93722b20380abd6b8aac4f0b102ddab380b88ab9dc040fcaa8b775882a673864fb757a3453273627df0690c90000b54112dca50235ba14fea59a764736a018a091b822a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb792645325d6755d79b972ae993c9e3413ac040b3bcc85c4f98a2e185bf4ea1d19a4737dc78547847b7ef385d2a07bfe272764cc873be8cb1286a0e7c83539d2b9bad5a17f0893ccf41e2b5cab8f66706955c5e168a99e9820a8402cb25a434f1a149f0148761014d32a51bc73a8cdbcb104c29be554b2724107ef314c25d082c7252e0ce68833a47a619a611b08394960a64d8c22c25aa1121a8033605c9bf35221730b15e6269cc25febcb8e3336870b3c1c9d3a89de4a9042758f517b55f85133b403c501590a0f53542239118f93874b319be0d063ad82144eca6156051424235d785c92ac00c412f8ac0ff5b88f056142f8a0934734b09ba14c00089bba136279a5fe462082ab4b0709a6db3279f8e9544f3909ff78b264399c2ed129c803b341d816eae96bc531952d55059ef0233b0c18e1f7aee5498ff6f11dbe801dfe193bb61b870008ae57483daeb8ca7ccb460193c68a509e8dc738ff227fda89b21eba0053992a4d3a1f8767c0d3f3419838c8c7a2c0b3d68e737ba77221c68a8570948a322a143e5a03888c08a1bb7c42e9db9111819ed94523848bc32781a881a468d26aa7fa4acb926ab8695b24a094b8ccb0423192cea88c1fac818a6b0ca19e423b7afcb51b121d48ea44037963ec1a325dc0bf7555977f468feb49b8346338db983e512b2fdeb35a300495f437cba88c36d01536f7a56bc9dabd1000b77751031102caba7182e2c440919435a14bc1ae1b354499324862885c9c301b7258faf778cd0a4721f26ee32c5dcc7a7283dc10e3cb04713255d0044bf1d9234f5180f32483f7079b2c0558b95c622db01be885b2580931fc8617b6940ddfd54cb327712da02f90a6a8ddb6ba17a31fb1d7231d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fda08897ba1edf959f37029a84e707ef676b89fcb5e94b8997d95542e26cbd28a7d01b1fef76b1c91ac327874c04f01b2d6280fdc60cead3587bc0aa6ec76f064b3263b2419bf3120aa7791053bfa6e089f6cb8bb020b5c5e2517d4b2f34ec3c4237af98dab3f4d44ae161773ed53f391a689d7b38f01155fcd080869656e15baf9a2a6419b38c2ec39112b4216fbc5d94771fcc4369eb90aaccf3a752020e24f97c30c4c67632180e9b928a0941c23c03ce588f7d841aab91b74b7959bfd8b5b042294ebb094b523dfc425e9ef70bd2e2bcb2937eedba0ad018737ba91a3691030c1a6e54c0bd4336a4bbb7c5dc79057ef5c574c04dfcf9c8407cac999a54975b1a45519075ca167b8285b2d554eb81702e30626897413051aa546bc63a42723bb95f0dcc525944c967d7a5793c34c7638ee59608c8680f2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93378f15dcf2959d0e02a15e2277b7ab78cb2ba78703f13dab307ba1b663c86bfd11fc259a2115806f9f68ab15859a763a49d169d615b4999714d550707e8a0c0a93c8db2fb5e4de7c93111206f052a7d7a5e0b5632d94c7a87596d24e950b361a185f065fa96435f312745164693fab8d3a741c56c6f10d8be52c06a5d83cb1bd327e5b28db12291d907a2888136b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861626167c5a17cc2a4cc9f668df0707d26795de7f771bc614b994b574fa309a1e1c8b4a0a4ad6240286bb78ba701ecc430269a37843149e1f1aab731523359c735694f09298e2a1a08c6ec273b4a1d57118b20524fda18190c2029da4095ead53212f609a76a343d5c68ff17ce6b92b340dbb8cc6c03ae4b29df243b93233af6b95eb5a7a8b8643b0cf5a8114152b8ea54f0e3668511ceff536d888baef85a62299c641769023b7b92088546f338448c1977804b71781a554bca5f13c0480b42c5a6626904516139abaa54b429e7a0502b17a5a2727a7f230d63c5764dd497f164b24e5ba3a626785ad1b917a6b77b175e64323783c9791832a7c442b895eb338e6a29ef671d4d7c0230668c14bc794cf11340229ac905891cf1c51ef62b6a4a0553331f7f581054da45c370bf606126b39492e4a3b8592bbe0359bc017557379471ef922367d82635d8494c88bd38a7720669a1f9145367a92090fc5df15c034b82cdd9b7cb9ca76e74b2069c36987556012bf0746424677f60ade29c9cb52c6d9cc2052394691d7306952c65ef498da41279eeabccc66b3a41747a8b447d7ee81116eabc04f4b776923c93a28ffe888652fc34415baaeb6854d4732745a4bd5ba61c35678780063ed874c81823ceae41b9684a05410266f7ecaffbfcb5285472e5b02fb8c15d126410f0ba3ba8536cfdb65d23797414a55f2620be653a98f33c95690714fbd3418c6893f8693908d41d6d69a744e63b2b0c190e3b1696a5c8b1cbbaa4719a0bd184f896c9d8f926dc933ba81b2785c05a51b22a95191f43dc23b42c050dc9133de2b003a5b6f1a5730f490454c58af291cd8d46acde69842df79353670a54e2c88cc693745516ee64c2afebb95df25ec0608ae4aa9c89215d471bbf68dc6530fc0fee495fdfa09e98ba8d37f9636b270bd1102579eb7f1bf0b911cb79f03537168867eaf60d77d48be27bc935b02662929dbf2263270670e0601e5e43008bcc07f06451e54755fcab421d584bb603008c9909caa61cf99a4b43a93ea8a3440991ba402c9a8fc51f90584c55eaa450b7a600342e98420d728a8b6344659f2a0263140e69ab86bdc6b20b3aa0920b90c70c0108358c8a92b27635154af9a0a76080ee593ce3d37e40fa33d0c654aa77171f822e0082c95cb60b54a6a26099443f671e863889f35a0b9597b3442a71fa704f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75448d21926da0938f92b9133a92e426dfd2634a677878ea9820f5c26a2382fdb1c4b8ed59db74b4490b87b0dfc35f5b22112e5110d494e53c50d3fd6c64cb485bf5ab37f7a1b709122c7086d3fa56fddc966db2c53e09b976f986a334290dd8c3c7e6582c4eaab182766ff70503b03b4e68261cd0303f7a83732795cbf84a04d78a541a0929691c94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = d1b9adfed05b0545598a380a908d0630ef5a5b633f1a0f71b7ab658c12b5d41870dc738d16dff8ab4009b04f1681382c91cd87cb1fa19fb83c6edfb215b14a21f6595e50f60d23f65c8651a7acd2d42b8093d36511183caaf38482ec02d0c5495a0ae08d86be9177ed05abc034337e502dbbdee1555a5df175420ef9d13ff88d34e3dea95109e543f83060050c948cb5248bbc30ae8dd31c16c0a2aa6bbe91290bf30ca690edbfdc3122961b529112d1c88b5075fdeae100176b48fc6e954de16894004a33f1150ec182d1978dfd30ae4db0c7abbd069ad761c131617643b25bb42855c05586cadfd35578b04ad23c599b200a42c75cb4614d4bc49e0cd69ae47af58eba9c4d2adfd39631ccc550bd3052e33514b1aef509d9d4156520510eff630878b9612a7afe6e652baa02cadd1cf5875ce07f04345a457a9cc94e4ce3ddafb51314e11701a9062fc38d126d3a5846c99ddc89423396c5dd19ae00648760bb9647d0d4d85aad167452ed2405f1482a9699cf70c99a3d9e7b897d99bb5e2f59dfed7a1c681315a881cd08a0dcff6678c7aed3211417d11f4d40da95e46c5aefa7e88e27ac0e91ebdac1b6961be17fa2c5b7ebcdc67354be0e43abf6a9a611ef02fba24a662b5b6ad31747155dcfc62ccd0149b355cad072e462331298f6b0155db2a00033f6b6aa71b8fdfb4e2db72040dc5b8e7a55efb0cdeaf6127474738fac38a5fd890259f86d5af6339c4cad26d1ccbf98408eaa182026909dee6be1069fdd9dce80f2c9233370a8cbc0a8a52b3eb999161ca9bd8c250dea2358f72340f48c9cfc0a8f347b7480630659e13708a34a9b121beeac05af0bb9f8475674affd1889dd75146d104ce6d50992311e3132c4724bdb1f793ad76bf1f6c3e30d9592aed479e406dc470aa810198c30ef25b549fa49ead13b66db0107201ac624982ba4570f97679afdaf1dd174e1121d6e02b26d8435795fde7a05846323c5dc7f64532375ecc44b9081ade905e4e194d1d17ba0c91507f16e34d4befb2b6ac08a0f0d3a8f09d2a1bfb01580ed0dab28645faa28866135961e2910481f9d39ce5a0ad97390a1d05f40a0645c3ab4b0c749127cd17b176199b5eb9e87f625bf322cf226390f9de5006e207b63c5e1863bcb60c6b05f7d3577cc59e9d9f7c8be6b30ba9a22f17b6d860ca6621e00ec18733645af0e9b63a40810225fbaf470ba8d232420bb004e779ec73eac3d688ee30926cd1ea673ec6ac7acff1d255189ba3ee8dd5d9ef0c0d3fd0bc911f818ebecff8cecb65339b8762492e79d4f69c2efc9e0d6a406b1640f820454f4cec11ea7ec441bffc79de43f9bc224a570aa693edd08bd637a3993de98eb29a2f8db93347875ad3adfe59ef1a1017ea9a2151e8e95c40b92f357e7bab7c5a74349e1aa557483667161762594cf28bc2f837815679729da4e0e1a567c7eb92d4cdbae032364db056ddec3dbab4d2cf2e94ef0719ea60465374d37110bc7d89baca24f7a420870cadee72f58d8504a37bb7acb384a34 +expected_result = pass +expected_shared_secret = 409bfd9102bd4632c6b5d3610eb349fe3e3bc51e73acc78a8e994a070e20e10c + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +private_key = 3a756d6dd157aba65d60721c41eb4edbec38834c22e9ac88f03119b472bda0961d1f5c3268ec6492f92d5d066dcba69ce9c20311e1c15fa81fa5014c6c956f88055fc2d35e6b295d05d6167e4375bff23257ba72c0f97f452b609f22b57f7c27f71a4f259938b5aa18097399a0d32c3602203bb6769015495b4bb7317c9e99c966215c58d3455efcd36003826c2c7b1bb437a66a968dcba35dad7098fce9133110a109c2b91764719ca25866c98550082e88f29e78b38b40a53c4d626fe63390a290b54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f59505809b1095405949cc55c109a1108649552d5f83a970083bffeb6550893b5c5106417b0cf1e44b6b05a9f9093e386c9d43f14d4cfbabd3b17efb49aa2c571ae99197d2e4b7d58775962570d528b8ebb8032e8065bdcaa391837d483a27239a4a8c0b8f13013f4aaa6bac0ca86e532523d9620bf9c2c3e2aed2365e90a1699a4cbf454c4d2e2c4273e93456142f737c8b3697b9821039142c3e25b346d020c829850d6ce2649087ab762c25baa2639c8c7a852bc76d456ee69747fe561e267844a7e51ae05c5820f0c2b880b05cc935a3bbade2c6a4881cac21938a304c4cd2c1cc1bfabd932b777cc459bae4be75389862464367c6318a0521dd62c5f070a139a95522d10d2e4134c06522cf52834562a208b22a95431014934f51ec49f5ec087d1435db935bb5223c3ec87bb7f7427a458232474ad9cc222b422149977c7f366f48b0b14ab260bd0a8c04623f9b12091ae049725064d0bb4a249075816aa249718f1a7768c3469aac7182d2f01d6373038d7c4ca24802693a354c19c66dba1c05eb180ad04c1fb095b42947d16b66139384c71206bd0ba9ad9bbb5dd7593d08616c214fd9013e792a5b4930122d1c571f1315d235562c167d7546c8ef7536a929982f6a55ce7209b0d5735f69ac6c52a824e508d2481a5be01075c54d8743bcd76767b69b5e350989e629c97ac1982a75806126245fa692def22b15a29499c82ef7f993eb3472f850527d900da2f513a9366a4fa978038b9e46752dbb8084fb12cbc591008d692544078343e9ad67909dbd77c18bf18f02607210f4a0f5dc749f8b0bf371309027968968678b0135af65138c5544abd57ed8a646409224d32052bb14bab4d51dac981ccd838b4a513a36a351b81a0785ca281d7106872583b8babbd62a5787bab8ec9019c7009130ec6be4e25d9992aa1dd13da9c1a7f1ca27fd78968741436003789b8c781c599c98d2465c7513cfe85154d7a655216e5b3b800deaa6b9dc7c0d998b9ce2b99da6afc27a5ef6c152eb16184d91cd038cba69835ab3500ac2e87368f37888ba90f219ce9da24109f0b3e1894db5f640a17b0e705195a350a61ec62b2c7a216231c530f557d4c5605346a6500b7c1484012fc87dd4526823c447b71a726d65753716b30c212565dac474ca3acee664218285a5c4a726f681e98619e2a289d08895bea26bd6a3bff3a5c5c1ea894cb6440d075004f879b41a14ebb82b74ab0131d0b3348742db7244e750ae2b7bb57f8a95379502827880f8a50ecb1394db2553c07627c113a300078db1bac7b5007812422cea108045d2888e2c29ce0bcd454b95c09730d6c4698e779987523de0e972332544c34350d29c7bc030bb6273b9f1c98c3a63170abb2641c54dad64790e83387c51aac922814f834c4745409273ab00051b2a819eefc9a048f222626409fa7b3f8d27a0dd754f9372aa37eb92f6454fdbe3116d406b571203dc05201c31a52ba8b2b95b191a7b7b55e743c4ccb80a710863ab741b727f176224012c539af2bd062ba6be7a42eac08c5b6b420becbb41b55454ec1f41347ccd984f11767bfc82665286a56dd31598834b37ca6ee93658999798ead094298160b7e6c76978370db3180273401532315168a161e087d4c6086846a3b60b80103c1ad814843bca7ab329c7914982ed32bf16507b3024a16f231281a732d3d155fa60260064919c484c1741874ba96cfd91aebe5c314e407a66d7cc4c846176d759618654ac2a52fe69c69a375ecf625e2889abebf395fa20561ba6300a72a2091356fcf197c866ab5468a3af7bb3de755836d9784f7c0949445d83b3358721c7db3c09b5120f7f757bfe3366ae4365b677255ea680f27c310f768e56f1aab8792259340bd6b984406148a254bb605a291c0946c83b1e9c5bb3f879a787b9106f98809e94bdc23c062d592318f9854df04bcc343d64387baf398599bb352f82b1f0a5b530e824cfd69d7a4a15cb5624f70cbefe1c61302b8fca337d70d1900dc817837619fa893208da873c350f02892097708cc637093eb25bfb4b3c793331f0fc73c5446cb11276824cbe419378a224a683fa0d17c671fb8c4bdaf18c20c53a21a4bb8fba9ab7a1b7eccc81946bb5fcb15e1d08ada7761a55d503dba912b73765ff93a6ab642b5fb72ed4f16657ac448a1957413cae547ccd76d9936c860c70c5635c28754421af13448959d67cdea3997ee923aa326129b5397c15ab90f95832f263e080a42460cf9f081152aa59cf17263d008acbf146f34a7808257689a3148e58a0a0117fbb47bca97810a42a7e0f734c0a17745afc6ade752080b39f3267399c20b1fdfa195437b83ef5125405aba8d2ca42040371c541a5fc339772948a21b7efc30c909c7938779bd012642441083150118ce431baa72e989425210945a7c47479f4873e3c3ca6698ecb2a050415066d0bbe5e240222a2884b3cc17bacc14164be0d21330456a279547579f8a4e9443d913a154210a3fd1a1a263186445a8e1b884bbe8b54d0196affdc47544c8d10a69378fa139bc8a422c44c5568555f9080f170bc6e97284f448e6c23885d603a732c469b376a762b5068e29e80b74f994588d9822f3e81ba6ffc273a9c905d0910062bbe94aa1e0c8c3424303845779f8c9b515dfa0864578a66da8ad7b56da2810c11e1a2888b88bb55b8c096a145b62ad9d2c98e003658c9729d7b82550527411a9c0b981f3479251c1774014749d211687dda83626c6bfcd5b08f8075954bc10f48623838a736e38c1143b9472b4df5d30d37f0bd7c727a2f16a3cbe0015dab5a12e27a63f7aedb841d6d9bb1a79a5c3e903c9e374da62a298c549b9842b77c33aab6b4939aeb55704cb610d084950c41b746afd7157613618f6f1574ba51b36f7828af0aa4f79c0840ea3d679013df619046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f49da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = d7ebad4e7d0644b802bf0d325f8947e10343dca6ce3affb6645153d9842683b6d7526bb86e2d07892ead2b38662504bf8829b3591bb44eb03822d34976031ee39bccd8b418ed77296b2ecf1517a37aeff2193fb1a6f90cb8b3b46a213aaf471f7170a04b7eb24b8b62f273061fd3f04e567c695f9f85c1749f052a508f04917c7fdea48643f2aaf8d3f4208fa6e5e3ee001054826da4ed89240acbc68471bb06acd6843f639875042454ccc3fd0aeaa0ad416c16ee17afc0b8df9a49153ac2ba53d536fa4587d69df1360d98c82589f9cab145b07a4230e5c82c856a74f0ca95d205ce5d074c9bb54bb1caebfea0fe7afc30b69b852663752f478132d54d26e5372cd62f48e0f33c836a1e5f38562b6728061c2875126527ae4e84ef15c4e29df126fb9c555e9ddeb9cbc6c07036123bc615aeddaba1d53b0159ccede60943e1d00d7eeef769e3eae0181c69556e5daa1520103403f8b16e9e921be7338771d65339fd89e180caa88ac32154b9539289c587738fdf65eb3ee011961e0f0f365a5e885e811fe2db2e12435ea84ebcbb9e70ff8c8db1325578a7e82b1dfc53dc5322f971ba2cebce3772c019504d44f86156740d31d44fde5d877e68c108af3b22dacfee863d21d40e0402209eac16c3ea6934d9031fe217b326451b29130e42788e62a0def2eb2fedb2b01f57447044f0f61af4b71205b6ab352cf46f738d9582e5554d6a1088afae1fe4c7077beed897d13641adf5b6c053cb3d4e11311ad3b07627ab4519e51c0c767c8abc656648524aa42d8d4d3bf4fb82baa022a82e095a39c16b6945779391c3125d8249c6b66453123fd713443dbfefa85f1a74981b40e72065972af07d47e7a1de0f42a159dc1909ab3e8988f43c4a6b729da0a8dd33110c777e2344f1b8179d83de58bb2b95a8998b00008b2022b50a7ab7524d1189d840cb027c3ae29ccc809e3a977bcbb4aefbf16c524497e98acf053e14bedfa90b01750b1cce2c2ec50a701bb8ec8f9f5e3ed0e6923f8926807ff5dfae71256afa331f14fc8e73aeeb30ae63b3881ac4c27f9973eeee6095ec9033df4bb73537c304fc037a9d04932b3aceb69769e71cc73eb020864395e5b4f455e6ba92bfbf8588cd5bd3ecc7e9ec7566e2daa123d4c4037cf1fef134078f463e4c0a901d51071fbebf889245ccf13c0c0a889822a485b06fff11b241960ee95b0518f668c3c663b9fca9dcd911246e1d01d524a309e96cf50839deacf9eddde59ef2602bacc13cf145f23e98c4f033c7ce1896502f88452201fa81f90a16cd2816f19380c0dcc61f342fe479ef17f7f8212c3afb8f607da4673cefb3d58ad5d70ff938db0a593b1fbba0418041093f386761616a851a23fe0cf576ab1c0903c31f3f01e6cb76997f0b7dad2b088abffd67aa942c09635ef3a90b09115a5be2c694f493d076df5152e02756bebcff329abba5ca82bc77a699f650102e4f80d57d6c74a45779e53ac6717f2c449451f65f16a92a76fa87ff7c2dfa5eb564ac66e79a74b1bc75 +expected_result = pass +expected_shared_secret = 5dd151a8015c0b16d79822832ff4cc0da7fd38eb73b7da59bc519d4d2374b808 + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +private_key = 0baa531a985251b6b10153c8fce6938a280e93f9ace7a56dc7f44fa8bb2f88c09290888da8134a0fc43ccbb75b50b6a724d6812183acf876036dc252fc893419280314c7611750875821b2f3ac4f1c20b06365709bc07ad4161c94c41930568996f8cca58c4a0536cd5668488715593e66621f96c87a2178a36438dd4c390ca0532d30b88db712cd3c50d30baa91c98cf0bacf32c60c81468307ca35b47abfe59174e53467cf7b1d376758f1a5926fe225f0078ff288ae24d23241709e471624285c4fbd35a333088dd643cf6cb0ab6b27c8b679792ecb8ba4c28cd8b09677f0a7ebb692eca6777922c4ed6c20402533cbb9a3f1e0c10250209ef128a626b763b30b5e49c4c4691e3a13c2c2601b6666aba1d099987990bd1bb00ab5806390ce8088cae30a5b20567295aca7f0191cbdb4795e78bf150c7954f9a49880c218c23e59014620e18f18c536da0b7807b0c9e11b1e341c2e7e5ba799653fc669c1032aa014cb79769361b01091b5e000cbe100933c6d05714481f491b2355e72638831d0c4f4daa18c6b4ae6e825e688cb812490fa13b43d306e5bc857fbc18a61923f6b685e5fbb5be9c1871a9822ff07caeff40318482144143cecc5b0c579c84fc949ef359f0b24b20fc0a9f3300a3217a8058469c78b7998744024e275cd1c70a96a75fd86019ca031fec081dbdb796a56186d9a1df8c098940527d34a1df2db50b5136b6737829f0cb1da3b131ab238207a011f02bcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae81627011a2633f1c159c3870f7c69126b3c31f50d356888f9077fc207168cb075e0940fb7a0becc556de78089ed512a39a6adcda9c3c5126d874b50c163ba7b091656e52f9813cb318c87abab12a3f8996a4cb446d0793055ca177a1bf455cb956443e56c160f4788cdc6b008c086403bc910332d3e3274f9825e9964484d7a52c91c275e153a496801c0e6c8084b25b53c8eba77a9412291df78bd39895dfed82fd3c92947a1beab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5eca0c6b68090a338eab57a222fbb5a482837c097bd40141659a2a71d81e3bd38d60d0a903592b768b0ce60a7044350a75fb02f19482138603a9d8cb89ba6a32d37a15549548aace4636047d66ca4de6cf7643c2a5939478a39873820578150172f965d4dc6cc6d7adfc360568a53c97d268900b7b20122e50cc5e460304927333beb7bf73446064d76c3af1274b503203804774b00f02534772ccb83caa8475651460b156a7238da2a9847d445f55687a84baa06dd69d4a637efcc1c09f81bb97b541fd77a96883869731ac776913ed6c02ef03183b27b4655639509b1e8bba74837375628152814448f270b6dd865c888180aa071a2ab42740e93f05b32a9c85a069420be2ecc5335738f9d46c90c5af1625779f3a329dd693706618afb300b5c7099c220126c8398fbb8f32a2a35888bcaa187950365f022585c2e08243f53122b6c5ee9a95b84151afd10b2110135c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702e327b3e53555e24abb670ca6e505df0e0aecf7513f7e36374988dace2af54375d684a6cb1fb38bd9c803a158483f91175263779e75b6d42734dc72fa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106e91e32341aaa4808df6528c3ba98886184e0195e3ca09d9cc525980cb5a2e9027c6a88e9042bf77653b9dc02ad3cbb04f594bae08da4683dfc960708d85e39a28ad6e6a7dc81a2f0f8167633901298628b695cc1868756a97d80b1afebb71eba5969a1086de4d611f737af56a83c7378c6e5e04e79a8967514cc668bc8fb7c7a1a671e29d55068e34d883a8320438ae7a44f01db1d4dd07304081d684796a9257154381ec44562a8d005f3dc4c94d5ce9e36705132acc8876142194da54934095c2d5725a10e376432b17bf7d1b085d342cb3c633a085e950248ccc9c7ff350efc341d07d0ca06e6bec943353c479506691f2347a29ccb34ad09c929692ed98640e6b8560529cb17030ebfa4c769fc7707c75d86c234edd78e7b3010fe86bf71748cc1c5b00023944774200b2163b403b8207093dfc959b6aa09fe6b98f6e83f972a50abf113e9da2fb9fa10d0d05789ccaf05c448854249ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf428087d8333b16b1a9e59794d49a40b513b50867979230243b27f3d784932e1caadf8b58fe11bbea62da4875d004a73fbcc90b566ab998a45099194d449cc60b0562570648ad588b213cb99a01283706878287930a71b68b43f87023d2f49829abcbde6a37a941182b78b8cc1b93982c7a24457a9e1683d2bcc97b4259518e0102760100e1c26cdd85022a04a91168486ba3413613ddd6c42ccb563379a08096b287b41a011fc9594d132e33957f2a5bc1db4c57b4c8d9d3135476095ded35b2fdc09d8f996e332baf7939efb1032e529606677bb1144374c41c08807c9c0868b0c32772f18b755d7bc5c5b12f8eb9ca9dab589185553b74408301062c90b2d68504f0718d42a1989f050f9097889aacdc175cd7e6768d626a8c9aa1b0cd6cbe91b10af1a3e507575b47b6ac8c2b7c801a81985a81ad4ac04b32d0dd880d43b3d36857738369b7898b231b24ce6e9944526b9ef370354e21e38f6aaefacbda63497a85327a2112a5db95179c5285d805698209f2a1b67a7730405b02b3507b4e4b65298734f5eb1b66bcb68f9369abc01c7e4545568d432a685a6e038122253987edc55efaa3d926413dbdc43f9908df1925031f45d28712734fbcec3724653b019f7d5698da7b0c3c90eece1a1be3567a253a143723b9550c8f7333ddae88208667353a6184853a85a99c0c463189eb5763fe59d678349f536c56d014cd92b56ed2aa6b0518f1221a49fd6588650057ff00aa29b93f182b3437386f1f846d2a3c60cd900559425b2b7a5ff88cfabe24bedcc825552577b5c12e4856ddcd91b0713526098b5fa555f105a0f1219110347af9016254951c3cb5c7ebe602564242276399b0048ad8d370b544b1cb9789694c7753ef2cd4ab51513cb33f38bbb10c83c9a1a5fd1489d97476d9bb314849581d688c3dba01662b539c50b0db8e889a4654e6af708a64910fc503cfa0abc21b8abc233ab978965059c41d1123a4bb90306aa09263b25be885f4db186d0e720e97524464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d830371600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = fbac7fc21143080d74a75a743e156d9095fdd7cd5a13091f191437df1788125c9f908390b664d8d2ed2b9c56f0805df3254604d1f5bc1a9b49257247ca57863636a9c61433fffeab86eefb6ae8c2cbb725f7baf4d75e1f9ace6420cbf71bc7be58b5df198fd08bb2247bb19397754bcdf63567eef5de89120e40dd879993fa9dabe971abea02b5bf2e01d7cae26b98fb9ea5f253c6db007d06ebfa7047751fe66e471a2bb0781ba873074aa8d6478ca81f090a6134f5808fe60ea283557fe932d8916b675f5fd2f7104e0f652d9effc565288e2d1abea97e5313b482b8f83cb36b203cc63df3eb063c54f2088bb20c6a0d53d982c1803c646e57e6c4a5645b86b71b5890d488991716f3ca3210e9fe4fd7403aebcc5c54c6d59f5a9195d78d8223e459fa223e4f3d54d3c4443b54026128c71ea5d9171b26f63746d592999c63fe4d21a783666cb737351f88acd1428d46db5aaf965f4c55263895018246ad78193ce1e347d9d2fc71b9bb196e79115ad14625e562819d16bba8fc27371afbd77dbac73f4d20d4eb1d748a17ab00e2ef7e51c439ecfa7137c7183c3700e579b1f0ca20f4c2ab04645675d3fe763eb820274538cbee1fbd659e790bab87a9fe7d243cd3ffdce8e3ab157c4b42d354f37105b412ffbdfd0f626f196fcf44084e6d4bef2a77d92b6be9f4cd19a1e48f084982162dc832c36500d5eae06665f241b85467c3687b1ed0c2845fd98862a7426997f70973fbbb16bbb5847e4df7b793cc123e247dda4b1609aca09f9e9e41ff14d70a7fd54a0dafe80dc324d6c8cd03e1d2b7ee594a2c71e8b1bafb227b100b57fe8d04f13377af132f3b0fdc3db4a67163a47a8878f87a98e6956f7346bee24a2f5a3b1a393602e940f21040b4739dc6fddb41024730eb3756f0873e6696a3b8c2f7b507c36e9342a41a774fd55eb91123c54b874fb501b8c7bedab5436b50250f7c85f228b9b8ac016d548680a4554d6019ef68ece514be2a20b8148af168e0980aafe69772a0fc11cbf50c0ee4350d4cf72f4212605477cb2abb6ebf4f492452e194f79abc56f71ff7b00cf68b72a4763e442150a6c507e52e7b47f9984444680f7204a5e848a770cd27cd3364f6e020f2754d852b6fa82bde6f97d41909e66a4855e56c82dfb21d126039d9f06b802959d58c103abf59e90426809492053bf9793ae348d53759573545c3b0b16739938ea6122f77e1a56209edca1377141ebf98b5a79b6c7f1ad3e3afabfbb0e77c4578cfab6104207ae4194675ae9078eed0af2b2cc27d47d66df086a8eb89e17b65a7c5c19e0f038bab8e7f687477b01780ef556aefefe059f3fcecde27e8c1f83b92a4e325e85398aba2de802a6c574824d9bf627187e5562408e6dd53110bffc6269112be727a0bb638f5f011b1f88988faaa12f0fd2de21f969d1ef5e76a3c32b28915b32377a54eba21160ec0e62ad4209f81dee1cd58751967f3529c9590bff1c21a2caedab88c88eddfb7fd7099c3b097f4679d3a79430c2dc9fab2afab +expected_result = pass +expected_shared_secret = 1c729b8e580e124e715f19ea6f2409fc6de741afa3d9919b2b8bf3e54c053b51 + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +private_key = e0c2121f06048fbc565fdaa305202d439ab3a81b31fa257aa6f4273547c1465610ae51c2c1c8603aa36d1575754a86c9194b1cc6a9b8c9f77ce6484c5198a193ea4369293798943f7918142f849c8d7479eb0588e6e6b4abc4ce81a406642414eb4137c2da905ce4ad2b750e7d966d34a3b1bfa8ca5c8070456b1f6d5b71e582c9e1e2bf9dc37ab60a09e797a43f66b27b04c13c034fa6f594264c9d7da884c762b159d775f7750a1862216e8bc992c9b2e0d18513f409df8b0811ea89d2a69b66d34e59bc93f5c7bde25140a976a3195541ee22a7edfb7f9d647616b31399b6c924022f036225af7c34e6d221213ab5f7a20b908325835266da1b456f5649b895bb032142fc5c700cfac4c2a44cf1f96d57b8ba1ef2c9332a612e8bb9043559b5567090873d3f9450f37670b473a96f812ce1d71892e43c9fe61fa594601a27a98ec817dd822c625b98e0fa8f2d5a311a87a6c23b4dfdf44d7511373e64a4a18a833d654a946b0da9694329023086013a919971cc4c8a45916901b45c25c28eb6051600644660796935e65a4700496bc32204201d5c8708fdeccbfe949d1339947c6baabcc67ec901659d220fa4d1a3da1a4adc2b1b323bc4cabb6065d9032ccca3dd3c8689c9a35810bcb30b99b3f55cf2ac8258c5b85c696a372c7aab5b0dd62aba06804466fa4c22b2ca0e09b7d47c4644898aacf6899c79b5321110f010cd40253e40c5920db980a57c01b55c506a6662be1253ff171412820272613940704f63e70340414322b69b60b50bbb4459c1d6a0f25065da032455598edf678505f54b51713209565fc4812ad5f8a05a926340fc3853719146d049017475a09a1fd2d47b35371d715c455debb3a40a8a0e83247b6b8ffc05b2e857b5d8b201e56c109dc155b720b2528301c49237f7a629234231fba25c75d600bd360796a68991bc68cafb5b0b7c748ab7039d8c4fd1b3b4de76c193123e50109ba70956b9556f245ccd4330b888d43a84714e8cf17e5713b5ae5a9fc3a331718c227ef4bdce131f31028d68529f06a218ac32317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d790b0fa67cbcf36c0372c056c268e0c243132db5de7365310f5732151b80bc98a2bb76f9e8c616fb1c90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834ac0f2ac00e91b32e4e7aab452249d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c85823928877954c28d052a2c116bdc325b687d26d1ccb3386cac9bd4c10c3ac381e056f9060c89e25a910c78e677964d153b74554c8f38939f881543f820b6f11989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c5400cb1bbcffd2707be12c31acc9b5c94b806b71dafab1eaaa087efc1419cd2978ec1b973336d27b69af2fa85f6c33b73770c0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a3528de99cbd7a875bb5b299c8a6dfe416104a59aa9e958e3828d3c651b5a9a7e81d7738374692033c4c68254d5170204f83a9b8520016466fd9189efbacaa23ab8f962af7d66aec2e27e468b9c326711673839541262a9c823efc5c946dab44b5b2068d61f00e7b0d87ca67706343927bfe4c12d20d69c4a5ba892f97eeeab7b5a45742cc4ac4d37219ad72ac312051d31b8385ca2293415a13bb8983b8457b8af9dcca9e6322094ca68399ab77dbb9f6aa7ced5f224641c3fa07507da9a08e0d180d52585dfb3b2fc95cdc733a573a888d403cbbb71c120baae2a195278370bf33299b9b2684accc5288a3cba1277fd3999839a6ed29bb91d71a528bb2e4f953778ba23341cba4b9b3c17f9a8366212af3b722397419e24874b163470b3b2b7f24ae62258983b6161c6773b5ac90969c03d01cf4669b9d1f46e05705d4f676d464264d7549e1e2c3290c9b2bf5a71132057531714bedbc7a91bc0ad56254d298908d33d588951333b3cb7924abf14b0d70652c45aa62cc3062d851e45c866c6200df4e74a9e559b9e6ab738f2b0da9693ccec3d968a866f0220ca95b7c6e8b04ec41d39c17eafab77444aad4ca3a9d6b5b5d4611a6c074fdfb01f7df68ad2440efc5588f3b4a5c4106efa3b9b6bb35c327465c7b656d1c1c6409993fd91cc20172e53190dad63ce02691ac326904cbb6424c906bd091312c1bfe6969ba6aabef954b5c8d439da5064a248c92988961fd2254479946dec829c76cba61690e3c541648228b59805d7fb2adb6aaba70718985279452a2fb1414e4704ac3dc84d3eb767101c8f4feb24bc8148316609bf963afa826a9b87638424052067ce8fb393d9ac579ab1080d1c549fd5103312a1ff9988dfe7805ed906fe9228e25942d49484a4510e0ff9a4a54a22cba6be945126ebe461c5940a74e1517c60603b2651e8371973da7051eb7197713f5583ba51b92a9eb3179b45a8a8a5099b40c29f59146f25a563291364f236038c79b784bf09524fc6810f91b777bae252e5b723e8059c06157653e335549784a15553ff9a7a29407d87725aa6b7a2a2669cc776bb810672967cb5b8b9a9ba751a9e69a8ddf796b1f324348712ff0c23f49a1debf210c027995b8a7cc5b288c4c74218e5086112237128cc57f4bfeddc21ed23bad00c58d835b5a3f0c8fdf1001e0ab26c2cad47d5caf2252cafd3520e36ae21119e56fb456f277132059ca18623bfd994878c794545ba4a04436d804231f430b12808fb01647fa15d94b975bb6798ab7c3f6355b9bd50bc1ca00ee76342c8609be0bc893deb398b65a453ba08bef83b805b61945229d98422f59c27e86022da5620d737867828540c20b097076bc6c03e5435aee1b9af19958a7dfb921da414280429da389eefe23fc9578b714b4f2e5b19b792903ff45aca045bec0b3d83c204747a2e24971b440c10119941d9316f45a87c4ab2ac0f7c4bde9bc8ef73a7f42513be3420c56720ddb984cb173587462aed9996d2a848d11344eac02351e6c5a18cc7ae813bfdc50d5b143f4d07ac72a213a0577f9802043a585d95031d017b319358a24b06b7c2ea19f22b6634146cc0a123a8051c51e6ad6a956b1a935ffe00bc65c44a60534d1375570bc036edfbce66255f523bb377b2256c29b870da2c870868299828f6fbbd8e0a109386b8d743a6e7a38384d5933e64565a037b9f520ecf8466f2073eeaf03d1b606f947ca2d2ca49e4b41de9011ffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdd1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = f10dab8353de2ee40f5596160fb8f0be1722abb0207aafc3c475de6199bf2da4bcaf41599880c5c55d27ba1d6de27644a8b42748885222a8f6eed81503421dca84978fdd41f0380fc9b43c1aaa4e4a3437f3776d0f06a88eabf23723970ba13f127ec73d37ecff2593627bbb505362b29d8b6c6dc10474b373a7f5ba819bda564e0d7e24c298a557163309ddc91034eebc1a1bc4efa22909819f7f47a42f2deaa4025d5296288bef197c7fc71b4bd2a769a7bf73883e7d0fec631777d560b74a384a518abd2f660be886618c9c2ff82cf557f2c3ccad1dc29b444fdb5e0c6f82f111c338d9ed7b9a6ad148290786644b9107b2ccf3e78b57807e3b77f2b29bc58a3abca9505d3760b71091d0f6d9cf93a0f5932a194a25d3b87c5aafd8b7679eb75187b62f85fe5f6b12480f34d91b33aaa3c4e279a7b6dc837f203106248a49b9202e0676a6e697168b357a07ff4233dfaa42a2fc255220c33514d65ff3f7f8a41a9982f911b918e720f756b0558e996266b26c4dd7a95e3a7ed8b15a07b2b560276f06eff062be366108b7d6be96fdb25cb210fc1defff0d89f19797d4be632b04047f29f2d6a8485afd5303b1430e3cbe052ce2fab2b575fd07188832661059284c6bbd2862b9b707c954ddb05e7cdc447a7f0e102e348f2cb7a6ff9140b80cbafc20eee2282ce3188549f1f00a1a1a45c26d0de74dd818cedade0a1ab1543c50a05baaa07cf5544a338e7e1f9204b8d883d9c14a6ff983c3012b65b781d9bcf0377c9d8ec7167adda2b2582fc0ad2ae9b96b6a92e393023e785018a4317e69d852bee8566efada3e6de2a290949724dc0fa39067e035b3727040b2bb96be824688e4ad0b8f929987af4927fbb9ba08f49dbab197cd320a276740f48657cba5a295db5b599a3a15e00ea17eb9db3d91929029895912e11c5e0d8550343c4b9f414fe0d4517f3578ebe5d76c78ebfab79c1fc6b528f693a3d58fc2b735498d68f137530e5b992216ba093257425c51027d18acff20f980254beecbbde3c87ba75cb4b3718981bdf0b4bbe00eb30aadc8193a7200a5ef9a3f1361e724dae88fa0e9e329c5fddf8e1da9f77d39b512c263380891d57a14003ab607f44ece6794a1ad41d0aae15aa7367e0a74d04f0138124d583bcc76c9f79334ecd7d8db31e70de23c29276fded2afc2495ae70baaf0ce1c28f249e3d21ab72129093b53ab25ab2f6e66e022dc23c5649b210b208dad52bae848f0522f336f1cc732f9b0d157a7d8059cc851853b7fbc5865d6b79863358284f6493254df3fc3076b443e0539ca8ea7d92f2f738a8b58176829b7c2462a9b43171d4c6a857f4a51f1fabd691e50b350a13e6a2042e7f52ea47d810b77ba11cd0facc56a47b03d0f829edb9e13e355ecb8583b12c935a177191828317856307537b5d4457ec2eb19bef36c67499cdc0d0d5a04b7e80da3c0f82f838154f15106515e5bbfaa6d38a9ca997a54990f1f68cdca6d9512edb6eeb5bd67d733286c9a14680f094c4ab6cce15b6cc603 +expected_result = pass +expected_shared_secret = b95ac8b73c703ab1154152b3ac73f054596ed23d3be328fbe20f936ea95fa926 + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +private_key = 25933617206ae881c4de291b4f269f2e51897ff29d3c6803e1a4c58e53051e879f1af333393c75b366cfe2e84cf9cc930d1928298897480571d7050751601bc119b1071412efe8873ad325bc00420d13a752d33087bb6f884628def98f4fd21d01113219203f93419875c91cd33c7976b7a45f510f70e6002957ac49b862cd35640ce84e6b989201a74eb76422f88b31c94acfa811605a32634199be1639a50b709e89683c5cb0c975d627b76223ea48a2352c8bcc254abc60812a6a5ab7747ca82073d1d31fef708866a9801ad067a6da0d848c409861c350db559a0ab1d91c9be0c149d6c241a13849d9eb2da4b9b9b30b348217491449a43ea4544467824ff954c4869c8dc0b2ba2744c8d38ba584cb78ea6f6188bcd090267ba46882f16964aa003e2c60105415f937cf13b9cd00456d3545bc5e48b6ddf61a14eccbac23bb1d071bb14361b4c9acb7b48805b7890c3676b550238391b388260cb0e2567f725b0382c7174440d82ba8a6d226d325cdd1c26abd510abb195b73d203f9db7db44abba87581a3c57f079b44a9455e3fa16ec87a0cc14368569b35517272220ba7760a8a0508bf0033031d42763fe89b611366b8b93d2d523d5c872bb99bbb099515a5911f1182404b7b4ccea91462c6a5abc16c64f55ab38a763a03ba48e0268819b6df8ba88704ab4c7bcd8f8a150ca434ab0632adc522a49c0e45997375d69901416792f845fcbc1a18789b22870401d6872374b15c851aba4c3cf5a8930d34c74fd444a2c87f90d9353cd77361e26c99c8027b50504bc5b3f2bc27f3978822113e13d71e19e3915a9a4f0646aef6d513e155b41237b2ab08bdf38322bf4c00706c0f22854d080bb8ecf58cc9b75d19a0185412a74b3c7d61a04dd8cb07bb37156c46221a7183beb9321c58a924048ab86032f54815da1bb33ad4312391c1a6778d9070b1a4542aae231aac97bb5e1a1cf42792c9921313c07aba3a8c15db5d1be417c3888a2e0921a7aa1926044ab865935a2738b4378484b44471da250e41925e976beeca9f93d191b0c85b487badfcec4be7c7683c508412e096ae888bafb97cebd3266ef7397004cc56741f53683034fc3160522e6bdabad190c51f31926aa94b2f2a4506d69705623e3047176b46169ab8a715b84848bb4fb9830be744cad7591dd8d128c1a40f8a5b2829a92177d73cb1f319c0f45557a69ad790c87a6b8314e618444081c221c07c4ba5c1c450b8080db278770a0c110dc386fb8411d4b983503964f7b6afa10ac5154ccea9e6222b4a70e5175f125b0a83010474311f8ef84fdf3aab6d508b313a93c29675abe12cde50bd4b5b7e13c7228d9ac9df569cc1bbc995eaacbc2290b0293a2bba70ae8757c5a7ce84386093e02b3201573c56bcc368a7dd404371453c38823ba4752edb663e5fb99c5e91ca9ba94caebc9d60a6318cf62168a86c0c419cad1bc4fe514a745bb2c81701b89ba371cc1f10b50d95086d99778383108dfed849a1f74696464aa1d67f7f40bbc69c1fd907696d6227cf20750d68a3d36c600448c91a523a16e5c84b40819bbb2bfabb2cb03b658fd0656f410752f52bfc9bba4a3a8d09d5835b1540f5dc673df71540f560e71b4ff986bee57636f904c856ac93e0c18775864b7b932af200251b0328f5b3caa38116c5a187305622b4a152ca337ed7a3690c31161862447b847f5639c5851133f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c9582407a0e59a866991564ca55b21a48ee530676a435d26b749c1264f9e58c3fc619d1a23ef5f6300e96665eab70e7350852115f5859bbf1a8308977648ae5cf5a55c9fb42801aca4f0592254461a632a94a9c3a7ccd05c8b7c3b09666be54f072cdc58d8cba687d609d1f021115085c340153ce63a37750acbda01a6944a46cd16cad098464a109bbb611a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534eb80a620c308dd779b074c11f31679ae98ae569bbe79cb04bb127208e24ba008bea28c5db5ec18f31c50712171e27042651701c3004e057a6865d54763843d27873220c174c57154c9a9705da162e8685a035b34e15c411fd1b7220c57265c2ba7579f4bd9ab1461650e8027c0ba79f2ba3f14093cab6015d8cc092905a6b8f09dbfd5743818489ada2bedf88ce592396074a79824457f7caefe334fc84869ff43641821ad60e80407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac382222c193bddb31275b84374cb4679a5ffd803eff07987ed085fbd43e45752dd9a32f5ec03e7b74567ed9674e1070b026801e99ca27ebc0ed24742530507e19b97a09877a1b511da3b9835268ac35ae44187ea14b996dd96c35686eb98a81f1b2ad90a80d0c989b12813e7df2b34573b876289e7c79481c7247e637a60f9b2d3fc129c379a759756408636048565cbeb24c2186a875606a43d20bddd8b9d70781b1848be54a075fe978a3e112a567223d21beb3395921d1a100c578e7ea0455949b7b420b6494688aeac00697ae1914084eab375d86243b50a948874dc973b7670c8f9173228b64647e58761442a2cc90165b188b58025f8eba65cc654575a1bb3823a1a29633aaea1763f24486aacafd611c28774c98d89b3ce8a696e29f62775b5d5c50847c3ad4bb968c441086aa070097508da888b5b202e5a3b5db579943f0861a5b6e2d58415019182262c444fabb77679e019cced4e0a3854507fcd0935bf81b0e8500dc6c0b3c154ecba94d166407c5dcc67bfa6aea8b4ef0c53859ba4416d5c1975c1feb6bcad8076e6b020a62b077f0141deb5ab5986b386d51cb7e8c779654af5e5485a969467012c572f62daf788d1f58bf9ddb4bc6e04b00218cb671ce8b2515b072b76cf253a4006ac5437c107a077f162a3984586978ceb3752b1fa1a2b525961f96c63d7207ecc4c0268a354afb00231b1cb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a53730405c92130f756050771999e469cf07cc8c308ece9b827d7558bf882630556150a602d9400e3d4abb229a9d8b8132a7f0c0c5475bb852000b63228c490472b42488aac0ed647b1e834f248534fe2195adf6952b83b6705593a1e53f0315613d2596aad44e27a26d632b9c71e9c9e5a6ab733c7e81e54db3437d894a19b4710a3cd5075602b176ec369f5116638775574c74425789154b0bde48bad6e52c91c451c87b48ec406674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d2191b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c50950a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = d876fc40a1ee787db486792f9ed3a749a6e996dc5e20935d6b76c8cf2d6ee6cf6c9c05fa7d6a37314a06dc4042088cdb68599f8d27958ede9a31054cc6abf51dbf7cc76e7d6b20408447469d5860fa09448f2e54efdccc8d0255cd6d7b759b7e665f0641df729b4468789cf480c9a606c8d1860245f0995e972b02dddb7606b85e3efc19a93063d095ff068112c6bc4d2b3edaf8205b76b8fca8e956e3984f945b06527a49121a6f1754236e70aeabc770049bcc240d47e003f47bce03c988e8c1731e85f307d0dd74b8bbaffc511e74d04db81f04b0e0317d57c25d5a11b9128280a131ee849efe204836ab46820ba4e03710c67e79e0466a506c8eec2834f465c97e0118f138e8fb7d6aaf1c933ad13e3cffd84b6b2db732048b5720c108a6c1f3d576b57a7726cad853c31e4af74ac59e7620f87e85dc2035887cbc88080c28e49d986c21a9216ffad3b95b3391a52914ebd10f0202fe4d5c5fa11af3cac6e4a7358888ed83cd8567eaa4fabb73fd6a675ee4490722cd3ccf4fc3efed41ec07a5409b24864004e1ec0dcdf7bc630d537a9e303334e3353994d14c225d59f4cd88466185f8e0c01724ee0db468c2ff12aed38eb4a14ac13a50c7396fe0622704a45ccfa27053a15ff14046ebffdcc8b8fcbf1b347f3430db409c4b7b30bf138d712ca9177debaac6a3138e6651092473d86223943e889bf89a498fb0c0c662973408e9398229c76bdd59b5f626a2d06f80dee6db7457b917cd1f2a333f3853d1355a214509cd14db558afd1fd061d10113465d1682bb40044879b8b64910d19fe8c45d27caa82fd7d1370f7205669e1c62e03772d2a0fd8844fbf6a0d09ccdf877429d59a84efff509731d38bb7f0c17b90eb54b2bef365a4f014e6ca6f6f90b3e8adf99cb3587d7ef7892b488119cad921f0607dc6fb7a72aa5f33e93b6b53ecf3eeb3bd735056f8ba8a003dbd99a3563e85a2dddb27fd544a798c8bfc220654c9e3892a0c2fd9664f33243f9bd3660897bc41ffc7c862a139d1178bfc94cf067bd979ab0c66e984bfeda086c3280c9ce101798cfb73eed86cae129d36d72f79a8ce1114a3e74537e990c53a5b30b3334b1be3d2646daa719dbb216df3536bbe800db830de08769f04a6b874c109f7419febeb34e1e30445427ec154f2fef4a288b070996985e255a362224aa33fa5020d7b0b086e76600319f79ddd8984fc3aacd54b2a47e3bf115c7d297ed410649ad557e87f880c49cce91403fe5ecba4904b6dafd2c273d847e440d2b34270a3dca4ab85a1efe5318f3a124058399c4e6f607002314534fd603b4e71819396b5c168e52e3b47d347bb2dfb1c0f2f7c2e1bb0dd86de2dfb4d680d16cf0987d644bb4a38ab0b14309708bab82903f942267de8f6585d82db7af561ece89d635bd61dd9cdae73afdb29b6b7bf118294450696aa15601c2882c9a2d406e1e9ac78a46006bc62e565fda3b5608dea7f528b06b2826dcb07a1ed7893a5767891b6f740b1c88cebb26cc970f28059786cf6648 +expected_result = pass +expected_shared_secret = 8c3851393e5c5997cc95f06da96300f6dd85c041343c98db2e742aaa5f78b298 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +private_key = 719950ed1960ff6c2d7d59bbecb83aabe1ccb569b76cd9b053389c552cb6bf847cf4fc1f18a03e66f02cdb284c15d656151644f78caeeafa8b12cb7c616256c032ce6112735a74285d66a90f3a745ed8733c195f6b1b9b272897520a02fafcb958a9669990b73420bcce373acf5a1c86a555c3c48f78166c0fbb023c49608592261060884b408c9fdb1f4b023506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa32c01ab64a6ab7491d50303b4e8a134086110d220462395b9d89d9651205aea9e1b88bc80c4c8bac44af4f1886ea788a0b259dda78116051059853d2cd073ed8cadad9ab04f7175d57c3224e953509588e788713d5a6714d0aa48e972f4fa55f16579d9bc6988f562ccf1286e87aa785929bf8266d7e340022c0221736c3cb372b85723042382092545a45032eb727bdc750449c786145acf42b85d4618b0d6f009d0224a816620f1db67f59713090b0849559a51b9589532ce2dc25df8f09aebda932073a2ac2115b12c5f94c64750220d645b34c14ac1b2208565377d61426d7f2a25cbd969a2705ea330b676ea6eefcbbc6cd40da9c0716d147b398b7d469a919d83baacca80f0e41414382804b0a321362e14e766db2450f599963cc2899e1048d839754858910d12c23f99158a9a3149362690a9c5540133e5f217a7b66b0d627321c810f7d1639cca948d708616047f85ba41cee9211df72731ac0986d1c3149854b71683faf68179799b12c031a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c048359481ca7a45cbaecbcf34407d8e378733f812926599df5c156a94945fc7911db26bef17074470a7bd6b60f771cc3f396e847195ce26444b641f91b468fa1670d0184942472667aa76e42976fac48e78da72ef0c207fc7400f92699b46345e4c9972a35daea31adbe87980438de4f211b005c8dcec1a6eecb56d891677f9006c49385e8ab20a19b74325a9a95083bc711537480db30719815352616b2c5721979bd4267fb134188a75b9cb303215a76a246d8f69acbd173d069b2b99b727829aa5469a0212c006a88aa4a6b614674674fa75500aa294711c178b741b0275280bda27813647a5dcac3a258991db4bf436c23f37c697115143a2755fdc199ff32b19209d7ff904feaabff7383884c1bae3c0cc20d019066653b99c1cafe366567c9238785b0f0b4d1432a9e02ca2d9a3b37d84646b157684d7ac720727af4533749a9ff99bad8f3877dbe5cff9c75b38c4002178ce30773ee36a14f1497ab386cb36420f04d85c8312ce25b357d3108226925f6b85c7a3729064f81aa66336163c00506bbfc82030f4f33a5be7330926bb3f849d1dcb09f5cb814ba8a722506d0a037e6eb26216aa3c4d4c05d5cbcf0358501936ad2beb3563c341e2315de6d68404acab0149bafa84491ab67a2dd82972220b0df528da7c4d441c8cdaf508cfa2c0224932e7e5215572aa433c9212022899e43a93cc7c8f4aac6ed5acbd0162e4da4b897b7bdcd72a0b2a2354f61a6c211089c11e476715f3369859c3021584b6593b5784344d53b40da0725a90804c45d02f6eb7670071660478c53281b5e290bfc77ac46602b530b1300628a7a4f20ce227688518c8d8dbab01f270c3131ac1586bb783b35db82f3c24ae2b767e2c4a7d15c2a86eb19fdfc41113a7501367cd70d73d0f63705487ac4e0bb1c84001fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b52f1cac91b6c36f37a59780e454c50c5dc354b56a43040804de2394bea14c2d385e082c5f181228d62307f5a6a1aaa1eabb84f90f34310844df95a4e6d423d8c993fa7f390e6984e482024c2968254b54b7d3418d6f859e295665262246e1bc8cd6c9b726581cee69140f85c02024c5b59aa0711813d66433aa384b2a4a3447939378a1e6a98936bf04ad075981d93c53e9635b5e285f96755f8689b5ce5429142af6fa02edeb1a719b272f6b0a6211a5b9807ce6ff368739b51d4d9480bd884c8b456569027b08a3cb928645d450c6264c5fce2a2de2b241f965034a08716649a3c71020a6986fbc8bfb5b4a2cb162749264cc1e44bd66223f3db1b9bd2c68744b52ed7bba0b9773df128883110d2cc4757dacaf7f4c90fe02884e1a581d89af687ac79444c9d801d156325590a3a24441b7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d222a5d36b86ea2aa2006c54940a5f843ab708d19d5937643309c12d522dd479c3b2d57dd5696d25615abbb573fdb62eee5c6a6546cb1fb188f356800ff4177c69b636cbbf9ee9a7c7d512ca156490c96b347a5bc2cb257a061452dab5fd15bdf5026677f14967b6c825d03eb782cd0422bd1078b7781624dc318a33b0c437d6c35997a22e30496e876762ba5dcf5146c5188dde6c684c265a8f05031904572f7554123832c78767ff4b5ff525680c773ab3ba1a93776897d57b0d507b9391712344326f090b3d964df8c293b6638fa36815c7cb9b7962956f903f62c4ce3d7646ebc1a8ec04a815191cb4bb085ec8693f2188f490731c087c23a8bc7cfb32fc019d106934b2d17706526cc6f787be424bce5b26329591c47402d57548110ccb42955c422323addb4987fb0f3441558964bf14021a54277ba14c5773a10b81c1427f51173f5c6cbe1b7575a4b6766ac355bc443e479a2953a51f7010f7b04b23e0ca93d08836432e3ae5a1a6bb62f5476c07914f88532cecd00ceb340588ab675f93c286e7288da1c6ca3621ad6a4ae1fc64aa15b27a7c3eabc120e7460737585b5773ab18e23ee185c900ecc3b765983cb807e2f7047e6c999c6716e26801ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d172db81947643a84fd2173fcb0477ab87b57b55899a308d51311c9ba6916f15947d707d88b9228d0488ddaccb25455cf782b7a18264e55c9b6798f39a53f53240c82fbaf461364cd5202c5c94cdff23e0f731624e69310e5b47964b2bfd3a59a5b0d55a026e260731de346f74938abc607b4f579b8b200ecebb633614a46983e60e442a4914c93fa62219025e4a99d71032f0b00906126365c467e0a235570a544a7640f23800cd5f2a825479a632343f20801f1774f0e8b7db96a860fd40a43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444bfe219452c464eeb2914ec19031152cacaa00dd541fde81ecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 101139d23556eb185fc84b7a91052c0739f48c9850ba8f6886b5c2d4c064d37c525638d8a434f902c4f80b1bd8f87a573f7426b109a3bdf6a1d6ed315e459c73ffc28039085eb8f426868a7b45921e05ee78eff266226b92296339fa679def4d89a2f1d53e3d8d868fedade22da561fcb57297da23688c1617e422ac3a855cdfa30d7454920b68ad591dcaf0a45cf95026841072f304c03054c5322684a8e4b6ef489b39ca40df1d7fdf47b73c4e1d82a538752f59521060e47494b372c8d3b5406fd6e5e39987cdfa03bbcc2f6f6a7cf3d77f1f775c22cd11b4a74b8fab4fefd93a9bcf5bad44993057fc2b8f35d9898acb25ac1574462621c29b74ba64f58336e817d5ad2c9df18f754bdbca516a0b41624ffa2f9a8d67f8ab013cd0a9010c21296649bbd159f3ef908fa368e212232948181b0b8679f658ea55064b59a354db13d44e2d9ffa372492250a8dfb8f1adb1e7593c3d7c3a54c6360488e82ad056071d0562cbcd6fcc82015a9e45109b7d49beec8fa187d4a2a41f1ab0928b0c2bfb20b92048ab9210f0a27f258e90e31b2021a1a94fd0f32dc8911b2ae5363f93e3d70a0e3ed6cee2649e6c4284133c9412aedf464fd83c291c477099cb8e1d7ba347c53a99c7f455872a51204f4c30ae0c41080287a5b247619e2713b79e506e564c3ddb3baf52f15b82733a7b367eb808db1f19f079e9374bc06a0bc6d059458e539cd3ace055e3895e8246a9e888226f05a9022ffadff3ab60bd6a4cae8700429162004532f1bd30843a1cb6b72467522c8e41908ec9c1573551e0b2485c287f48aff967c7a0586986f07c1bce12099d5011a7808b629eae7f3c2e8bd5e79235f958fdfb1377ddd4850894dbd1d78ee375ea3f2165b5acc7f02bc1bb54e7ac58a077c513f0cf17daab0c7934b1a9c3ef073e8543deddd3bca0c13926ebd64823d0ef62b15c26532784b323a67c37e90087a1086955087b1a1a9cc8ec9788609bf404fb2553d7a233691501b37a311968392df5704b8513090bc416d39b5d3ea4a7b21eca56c8b5eceb1ffb124dfdfcb36cb0b84a49808c6105087caa8de272af17df3d99f90e482a704bf135fbcb27c068be5b16d6ae7579c0a046a3c6825df0facc8b9402fa5cfc492c2272f7b325b6b71298c471518de97bed53084c8f559c8435a6b1e9a69a70382f4c35f6bef440a5745dcc98623c9bfe3cedc55be17bb22ee5de49d7b9fe8341137f0ac2907f897a639d816a096911c8c4b84119ae14d459f3377bc7ea7224fb1fb218052f9b03f29cac0aa72daee1170ba56939de8d02d24bd4d26c5814052a125256b083e9e59cf2c7252f6ad6d75eaba807cf4620d4145103f105a6c07f3aad6c4d9ccd783c1ceeec399349d877a82a8d25e56fdf771a56162f5d46ec068e2b7ce7ee89e8565fb95fe3599d8129e3b0737be46484dca61940e9f5f438c1be101ef4aabcc5c23f41121936d0d54af535e53f8880c2a99a70d9a41ac69e137ee32f2eefe7d4aca9c3fb747c3b21f6e7c9eb26214e0 +expected_result = pass +expected_shared_secret = 4b681fff6a755e1dda908d070f0d9ac610d85c73079c1022fc67d255e36f1f71 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +private_key = 4da026f053c3ec1712c7f294dc891e26196894a1b620f97429574edee9568e113feb564d89a1883d5a0329929ca57ac001925c8d616791842dcd291627d61c7c2c3f842b547f074f46f082a06bb4282323a291c3cc07904079125cd5a854168d83ba8ab6b160b5e1881d25403b297c73048e3298287f51529a8ba2deda6b4d7665a373171b03b1c0baab6482c50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2ac0cc80c9d248b97ddc51d00a10ca3324fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48faa514319b8f9a0491f9212da443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995ef2aff817907de5c66899824889a760ca4a38a57b3afa880a3524e138b37487b2ee7332d2689f99a5a3748020fbca43ed6045a5aba65f6c67783cb74c217ba987ad381938b4a651b6908fa4f18e6d073a6992160438ba3c9547e4557e1e724192414c912648d25907bd8b069c845465616969161c483927f5d610c815638e242323465839d36a8149bad494b71f1336a3f0a954369d4265b6cab935f06694c482b500cb77bb32c4d805a295a692648a31611b206d06c2e86c61675577053a747bd3a748f452b480028edcbeca8a10eb843ea8a71e21e9b822d80860764d8c5a77ef0222f8004c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe59027fb424e6c580cc3b41c041984ea552bdd6396d52867887430a2534a44ba544a0b285c061d7d6618c76945a5c3b29bbbb09a724b1ac53e5954f66708c8c0b2d7da57c62fc8b80e73d737741f9141f7164b4eac08822a4c340b5b74cb5c2d407b9d63365c55c14c5e6ab43a8bc68908c34074a9bf4816e000ddb464656c379fdd829b6961c22e5345674243ca64705212d52e616664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1af828bb26263a8a898bf3b7b0ed07988e82dbe3c0405d46b1cdc37600570fc37ad9b2237e3032bab1a0ae420b6f011a653987305aacc8876ac4d014b7e619227b8b35ba2616c9575506870fad2585549a2f902b185d7a61139c027912ee2a00ee460328b16cceeb259149a0881f8152d563bc0243302d29fb98cc57a45369517640bf0bf63a555a900269878c4ba567f8d376176d6941d34957e1373b7520483394c3606089d14aee0917059227bd848bb22e088def4194bfcb36eaa81d4da713e37be79e52f51ba2c32f05d06405947838625e49f5f6bcda5e683d014a12fcc0c81601b52f80c39b6659606a8fea82c62e061a939cb4451869922083268561e16381b026152170104e11f30b2399f4097b94078adc66f23f85ba6651e861237700bcb1ae92e2bc652cbf19bc0fca0d7f7577c9c96dbc9b8b07b917f258c15661da17621db1287ebaa7714a54052fa660f034f227198ea14c2467b46cf9877f4e0c29962992b560a7db93c8ec13343f734d86bc548246a57473d1285463d0942f288245d933ddab7a09766a9f8c178ef539f9ce9a0e97364cac0366b5b08b4c1b081e01d198c2aa5288617a50019eb3a40a300af538119d733f2544d18b9094f387a3f4c17baf01523f1455e55633267468551b3ee117792c80c1a802230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab5f11602e977ed051115508668c244a44e09569a13507d4009ab72b16cc3bc615c12ada7c56d50ba6307d00801bedf8526f0a9366869a4830314d162f63ab8f51996663c1138641275e164ddf60c7708a75376bc235e16d5c22033de1a149153d1868679e1825f638967becab5b9644a6e201906771a703b7844cb5cab61748d202d38b5b8f03cc45626027895e23d0c1c1b526c6d519620436ed593b58732164a39639c813f6032eb902b05db15c5d8825c8b11815768d29522536698a751bc1f9964dc579358adc57eb83a0d2201b9b9354b1b39c6e7008d5f3189902964973af9a9c694eec1298d68d3372783d34700b0280d692998b49a9bb76293d7a95363b317670352a71822f415b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b3905df7f58c6566621eeb25dda29d97b598970684c5780f665243feb854f9f566177200f9331ce353cd1a23cce8aa4529bb667d1b9e59b1a312a7c6ff08871cd95c6934419f475c1c08395ce1a3aff83dd14784303b4ba7751054aa59f5710e4ac6039f3168c1b601a5278562b525abb11e66193dc9d34446bbcc8163578cb8065f89b9f43407f79246cad2b6b8b40f16b839a060a95b76855237bab2fa315db48e40842f8306125fb04145356bc50b00e3389dcca26ff048af5a730ac573b5b80331d2597c4188227682075bc0000186b8fd26a383e1bce5c19f13b18cb21602f2160dab202bb07b63d925b71708095daa662cf25dcbecc99395400a79842f5c40e79b46b5384ce730439f537bbc8a8608f61520e120ea9843456118a0a4cf36384832b12076044c65f06c8f8cc31752469c8a1e33dc529ac05485548a6e075f46a089aa8446c0d465bd43cdf0343acc9668fba2a7f7191a9d29be7e9300cef33d13a11edb2b409de297f30b8a7b077fd4ca4d1ac74b31092aded0503ccb5818d1834a734e15b74d3fe550ee49773a800d86f129b4e0250ea1c43da3a3b802b0757c6401ea090f98a28291621341a9d98c67bb001e46e89973f40c1c4950b0e34f07772ba6379fb6a93ecb57369b48b3aca26ef815c615b4a97ac2190fd2b15e83aa10545fb859635d084a57b0268ff085d9ea4b7ee1763b914e67b33dc46037f39815a1f8c58663c88662b91bab0db6758288c682372a269c64cf3ab5c46de2c8f0f1b7780a068948b9480c6af10251453c1fe213855d74675cacc7b162917730ae74ec7a8e7673a7d0887edc175791309ab28e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a2a1c2456a108a5cb4de1b15356ca737369668b0b5c7bc10e22377d6b5fef7515b4f348015872e3518c2676079b8a06de8b53bd189ec9766c04c084e74c6e747c783ff3a99b930547a72fc3a179cbd62b52d46207e79e37d65c9f3c4839d1afc167ae4041671e2c1bf3324d875b78615067dfe11653e6bd4dd5414579ad8c942081db4f1a10b0e1054fa3d79af6a285f2107d4232700676b8a007057d15c923a7889f115762b4c242392ce7c4438c68c6c3fbcccae4a071e404c24274f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddbdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a75a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 188663b7ec7e4a08f623c7e55c2148f8a6ff30aaadf2adca46e99287a7f8a6b37a1c6036653a321614ffad06f531cd01c62ae6e3491af8c06aa210c42fefe0edb96389306ad1baf1bd911c106ab8d32d681ed8238aec43591644a19b1f3689a1d9fe2a6798a4ebbb55316a2bd3725049621ff553a688e9fd101e4bb9d1c2cb6f1afcd2189990279af782458152379988be07135f061ff3d3af9796aaccaf78f01f4c9f0a89841885b8a015c6de80788fb3787ecb7ef2e36e9dd4b1d3c9df3d0ade0207cc37e23c8f758248a030d7d2d7c43c00c06711d00de431e53405dcccfbe3b21730c453a74365e7d1fbfff706a2c12b060b5ae1dfe6cb211a42a2f0fad86c6b0b2c70667bee5454434093afab1f37f955b895359749c4e61264e0b18a630857c7c3a98e159199e9fb1fa0fd6f07e2c696ede68333465226933c566da073297623168adbbf6d5ad7e9e22bc55d5c2aae513016344a7f2a5ef80d247ff1c71b983ec3fc88b4e2765c0b26a6614292763c14b8612b63ed0bdd43f78b5344f10a28c5df0b635b2f44f9d5c6496a801f7cfa5db18b2018eee66a664c0bac6bcf39f82e00e57a6eeb57a8097af864ef693b871b5857a42e0a99eba019a8ea639895e1a6373a3035bd3148a7b267b5e0e3ac6709a4cfee2085413dfa55000e09b4ec889f2f5456d4b5b9f42d23695e925643f9ec9b2618e09283c99b966f91284e176edc41265d3bb436a6771644460d97ee02afb7f1ae14d06bee9aee03a6279fcb36d069bda332d586851d9e32e9a58bc12104014cf7a167501b086e120a97498d0cf3f3177c2ff3b32a93916665137846bc21545930423e907329d8b57c2ae202f7a7c2cc9dce39a681e6108e233cd955914047a5e20552c9b3a482c8908f536feb396406001f9bb8e24807dc931798a6454fd6ae43600717ef03bef80e6fa53c2b9a74211dd82ce9aefe1e24f6a4f82b6d2b8d8ef6975c0433c14605357379276d58b8ec11d55b4e99cc2d3516198f4eef6901f70d6d74b96c289496adfb0109af4e3da8ba074f5dc936dc1268836a0bdc000ad8dba6bd9c6deca8487dba9324d07e66b07608dd4d884223460f0414228819c430ac30cba5825e889a07eeb75c8fcede709cb12dfe76381381ed76f89818c4d3e177eccedabf6a7ad44888e298b1eb51dc2f6a1d6bc5b0d71a9cc05796abb534330f1c9dcebd5a8144cc7471df50a684b424d8fe1db0f1351926f6c45c1fc120472f0a35a8332fed29b24c7534b90439629ff7ef469785d851703f070bce95d923a88bfd592cba6975619f07f9aa96733eaf9d3e44adfcee1a226bf5c6a006ea58753b9a1b0679a36e619bfce738b2125dbe1a517c6a4ca05417e267081c26653510a1bd1992468c59f6e56b857c8e95bc192f427c77a6bce7d4af50ae875e7b38aabc08aae9132188029576153204575e28035de11efe643e5a5195a49d50d590436912b25310bc4ac0d9e303d6e6c56583b9e11fcf15fc621e45fe7be1c118896918cb09d0a219e8d5c004 +expected_result = pass +expected_shared_secret = bbaa67f1dad879f2fb33bd4ead45aec354bc8f05c7cbea1e433509faac022edf + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +private_key = 1f83902bbb77a97b032277079cd0ca70d09d57385ce5c1b3c08b80ed95b2bbe70c101cc1912b71b29b87dd08254b593d616a31ff4957c7c0c325f82024f6a7b125b0ff799fff47afa6a9a7055382bca08cbfba71ea1b530bda5a4548922c90c6de8927494370efa6c96780086bf585ae6534dc05344dc1941ef793eae214312a371ecccea680c1a166ba97e128064748269922c9a19cee4b8a669abd146491abe31a57b724f3a173740269a33309f651c934e09a564627896150addb8ba181cf2503256512b0dd5588f4372781f35cfc0328c0dac842a1b3f418b6e8c567f410568f2c6be8eac9bab558deb08389ba08bbaa50e1ec5dce044efe5830743402402a167a9369e1d281d37713eb656662600840409c4fb971c0fa7771ba53b6c13ebffcbb85aab3316a3a99a9ced8bc4596932b3d052fbb13a5cbfb762ad7a08ca4aaf33862b6325baddb0e56d395e8f92ebc7347e847956b471695c978dc2431ef7286c0e0a880f7871bb05160209900c0c403da599b988a8ef0a716a9535b71002b3bcdade60053f5a8bc66419fc907f1ea718b7bad6bb76fd3f710e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edb500d884428be2c7cb6a6c86b807a6059739e23f70433d8a7a4aa768975aa6b0c3924cc8827cfc731a464121090a685820068019197f489315a2274a7133422b2968830271fc94b1c775c5a21e3b07bce543b32f00b7250cabd0d04a2529347848830c975261a54717324533ebc0ec627f2064ba693a9bf9a16fce87a8d7270759a06c00eaab71a5cc25034120445334a39d63baa2ab3254d77a921209750f6869e6971d05da1e1bb29cec9cb7b4962370e5c139ba472a75114b28bbb8e7069c5a8201b730db571c1ee0b10e1c42b4a97fb7f7ae54670d12859d68199443157ddea85760445895e7175ef8bb919c7213f427301c4f6561afffb0b03cf1ad05613c52dc5ca71a74545abe77d239576303bc9678272873d9b28f4a4aacfdb46940f59b0a82a75642a0cd794d63d03d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c7b05cf8293d3e23fdfda93506c831455b648e2017fd866c87683ab307c6fd9cf24212509d777f34b0618776864ebae9fa5318e739692c5aa86648d49778b67f81347b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464cd1801d02ab64bbba4f932c0003458ff73011282bf444961c54c5275408c4f79c3c553424aa4aa13a53d59b1b785c0ffb686fda185d5438af5c494d98b80381c821c493bc0e7797cd1995db681ec9e18859a9229c497cc251af12d9cfebc6a19c599c9d364e587c7d32245145a60ceeb54cc7ec5b541b71dae959c800a747eaab53f8cd24365c91f53b7b0b9d3630361d41ade4c82c85e04d8ba243763b3f9dd65d60921f962337a3421051d36889253a423939abeb0ad962ce1e1a9931c960d9f4948723ca17a731adfb4834615693f622470225cfa7b036b931a2240564cc35e59a7acae48707491576cc1410a304e0885534f577692c5a237344a5f674ec7c45bda3242d70b004d5ab620ca2b1ac0a56c0cd5b942529b054e0f840e3c1837e0053539b4a420a3005a17c7b4a08178b83f8540601145b102970b3fc29f30a4ca1a8a5bc4164051931ed68a59efb2b50d549bdc1a65e9909f5aa690b0235d32b1c6b2886ce2959fa189e2ce24224e99255863e6d964d4f422c02646a461bb5abf86f4b4c0975765a5b0ca01081677334af26c3467da771cdf40ec4293608801cad9c61d5f80839774eaff772b139051beaa65632120f00171ad020276a1fbf23517582149ad2c73450b11315ca4b244e7218800350aeb5808da774030635bc247508144740634ac4a078a5af2816e9206a645287de06263277242dba12af2a82ce13ba6787c5ac3020e5d30cbb92452985ae41027056f492bb1a5e23332698240b5038302e552c5acc0443a8795804126e15369ae96cebd7c9765233982458ad6520550baad77bc74296badcd4cc37240d0163caf8c806a0ccc3f4125a0874cdc1c67e4626c9c753453fa37b208caf5f523388d6308248b7688c80f6c925895670a1397880933af0152da1e54f7a7b512aa87499f7a718e62a7cc5bf5687add09060426b0d3cd292ab9b8372083ee462182872815cd740fd69acdd24615110bb618ca1ef662715f028864ba0872b8c199abe40f35f91906a821b8ce0742f931c661c65aa2445371a300e68f23b767382f3701ce685cea5f59c50e82e45234169c3bbac814ab9d68f83842c513a8faf475590b3bac2e3a4685b8f71208357d221ae41310e8454d315670c3a3409a2a95258b9057b42def7a7c6f588f6da61183acfb18a7cedf138c7984b50a940f17c687e5a2f83451d94398f4c82c93a375be195b4b219232e9a766e77040d3b9125e70fa4097d807a6d25323342508f2490a59702575d64af146088f59802aa2cab3537a8b4e92a10ec447bd89f9fe738d92a5f83c2861628601e42bb427b87c2153d4bc44b19413b79baa5ef55325ba8a42e1a88548155d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526df1adbea64930b6995f60181544356c0982e957c5e5186f321b9467d05dd5970a96e226c89673e50a056e7c0a8027aca8a5cd93723353ca1991730dfea1aee943cb0d62537cb5ad88c14f52a78cb6228ef4750eb7db0aa831a4202b178ef47446a06a17e7caf5274f384b36832a07ae0a66069bc59fe439f7b6005f064d865b550505210768bd636c61f0e7a1bdcb3c3065908d51302ee234a3fa113a1a1a2a618750075a6ec277cbdac535fc1524a62e3c0601aad1c46026ab6b8495c1b7093f776f9e6b3b533267ab99801e83bd18570166387f14ecb4d279b86cfbbaf90649e5c514e432561f850497d47c2bda1bc2c398b306751991392c399df6f408ff836f989c41cf76234b9445d9f81f4aaa987c1721c0c726efe44c311a589abb5e0afbc4add9bff6f87597a52e16a53d6c3551b7e6be0a1958a89a739e0717f0a86be0385c5ca433b68ab9506ba3a6e00debeb1ad0519e228b5b2d9aa3c9b4a2bfc8b35bf0a04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996109113446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f1f30d0cd1c40d14b09429215e0c5325bb2b069b85c9e0bd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = cea8231a59705364e56bd14bdfd745a5edf808a710ed23de250ce3d4cd42c931ea20d4a888f594ef8909096758d207e22f7e6f1a0120d496fbbe491a9e7d02f4a332ca25322e7b3d8c5cce294b8858660574748a9eec1a832653b8586c29cff0c33424fb9dedace9204299642f9a34d7391e04be2d2b0b189291373f6238a5e47d959e8b6f1a7e965ecab91fcbf4b5fdd264dec224e291f3248c9bab12c2149139ce73d1409b21c91f02cc9ef9c41124c15796e1a04e7e57d727b9b3d54bd51af1abc79fb6316db1f23ca3e29fbc4812e828d2038408ff3e9164d503ddf3a31ba263cb38ec6b307f01291d680feb21730a7bf3adf21f7ea73e2cd21a2ccbe3b1808039c00d09f60a0e54775510e8121716d6c25ccfa1f0b402dd186a8f623d66f685913fc597d24f63afa8e5b88654019de57939ae9c169f201bc53eed1e5c9a6bf60d7a2ce5d0ff33cc6f9143619e13fcbad787bf3752f1563e9c3d201b8716eafa70b15a7adc241aaeab81e0ddc1945beba409b3bfaab9252e30cb26805e6b42946023c9664764192870cb05ea9bc0692c8ef1408db412117e2633c011ea6ab54ef7750670873284484c754a2d374a381e253d629b09c5402b12a73b90a1c70a4d18cbf3278457039601534745b5bc4a404f17184de598afdc6c38cee8d89af50473e3748ca229715d575ab7e31a05316c02df4d19a594056ca4c250402fff7367e5ce0bc30910982b098360e00a44652e4734e14f490532d5f6ef377d48d69da43d5bcbbdb679e8096298f2e9be4ad3a3dd322f9675f608930f7dc0d00bafd4d2253eedc5dbb1389200157d7b0fe5b49c5f2845884616045d2ca0d4daa45a967606c0e4319e21af8c4eae03c0473b8d902ce55cdfedcec31b3c4923ccb4563834d3683ee3750c39d1782e091862e08dc99e9aa709483e7e0337047cc9ccd4aa1d6ef65a4a4cd1817a85a5a7b0d59c9585073fa0fcde6eca76a83d1cf1f734096d767c9df176f0ebbee8dbb511db823a350c671739dd50913a4220a6d7d9f0d98ada716ac2775348d22f2864b2000adeaf081d730d02246d07f1f1b18d5a7578458387731150eebbe79126ad8a63a2562d4e937c39b9f99ad04df3abb938d29e5dbd29fa640fdd4007964c9e4c27a1b440597a3415c789fa6b241bc7d533518a60adda939f62872cc61ac2e09adb1d3c6004fbdca01498cb37538d5298cfea058853b7d55e0bc3d00bc4ecadebc7ca9492705d7c1db971a8fda2e10e40eaefda7d32338953f138f03fca15d2d0cbd1f89ed97723e8684eb6e4cfec9aa81182e90c695e0a747d2dad465d4dfb7fe28afcfee0a1240858fb6798651a326e0e81e09621da3a529405daceab67657fa4af019191f0ab9898a447eaf02d072adbb028221b509235aeddb4f0d82e84e777cc2ef6df4d3ca6b65b9f40e06db24b62260c44ffa7eadd11e1d05eeb0c5fd163f8595f15c2ab7d3a897341c7bd2c7ee9a0175c113eb454e49f7955a8c17a7a02236778ba7e366d3c1fb1bdd6d0e884959b +expected_result = pass +expected_shared_secret = 2c7b983d66978be80250c12bf723eb0300a744e80ad075c903fce95fae9e41a2 + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +private_key = 8b78635ac351c94bb6b1d2b861e4914dcba415f66ccc465b370578e136330a2c5cb0ca2857e1cb733a75e5cc4fcdf7a12580017f1c0ff484401cb23318a98000637b3d065608678103940d8ba75ccbe58206c130ed62bbc0132317b6556a9c2ae8f71a43712002d795ca52007782652d291dfe535f75034b0d624277527a6ef623168aacfbf721a9e8753195b82eb9855467322aab0ab1701546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830df61fe9600ad5717bfa2c8e59e30c8a20179b27b59341c855677880330afd1a227b6c6313e17c46e87d109a4aec4c1795908db6046598483159907a667378f80bcb84472d5a748043b1bac10ba5bcf61b07a2b13b12c347f3253e26c25ef0af6a003a67b0bee98a7c5a489c9ec9ac1f042c6f2bc7585cb01bb4b55496a93de903ec974398e277ca7cc25e3265a879420ea0bd8451716ac21f1bb806c12b3488d408ebf18b89b79b1f8c09eaca235f1c165f9504ff987139590f9977513ee037249b4e25e51a296526ba76cd3295895a571cac279bc65642cba501c8f131eb52b5c7cb73b17757440b1ee4e9295d404177e542bd744aa587738bfac0ef3c1fa0f19b0a5c5e28b53c2340c7fa061ad354c85ad26993087b61ac2002795d5ada7a3e6747ab8110367c824988ca705b818d7a921dba33371405ad235b18e463a8ac88180c88f071579fa5ab6d904a2f53b03f7c7ec39c473632369f984f8cc66dbd1924206a6376706ca36601be7b16edd17e93cb9a0437b3615374329b0712794f5058790d88182be4863293133a83aa00e07c8e79c6f12c33fa9437ed984a1392903da89bd43184db6c8dace3789af5cbba092010b889ca98af99e5b0b3d4399bf61266e833a55a85e11784708b98efab223a27aea1a16e76a73c2027759fd97a7db870f9fc79afc89435d092db556e0a738c133b259f86c98d78a43a49744f306da8cc6c9098a5a9cb091c9bad94970f03b543d669a9aa4944e0c08ddfcc1d7d485fa414b0765a88f175ab6c94b12a2177dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f084277532841f51c3edc5c1873bce0f07a8871740c4aa82bb5ab164916082b795eb0660be32da9972840c927b7bb4061343d56757258ba4c91624f21da11cb265b00b9aafbb1665679c86eabbda12b74f1c5917101d0ea2bb293c71ad5b556369378a8d5b7297c9731705dd4493dbb173ad01458686a93287b6da0a6923b913989b69612a915a03a0962379bbc466a03f5517aaa0c0b030c6ca420636b2ee8821916e9c7f2ba228bb2aeabbc292f6c07ad85c6f43ca90d42629759536046394936c3ac5ab979d5cec1a1cc19b5c17edb47b0f47f34d616027b29a12725bf14b62fbac4f2cc6eece89ca0467d4868c11c17299373687b657d132c55785080f5b87f0e3c1504673825b98e8a0aa35f2c8d84f41b060ab43a930e7be1c9d04746169bb4ab403ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a9550ee494466a49617b541068f2c57ad4108ab813db58526c7647d55c1cb657ccd1143343aaa8421c23bd0c822f763b6a82b7d0041648a143bcc43163992e0d6a8f811b3f0d30807456c84c8bbb008d3b126a31424954cbc6cdbce91e25b19928f4a41b1371447ba3d173915580bbd7899e9adca37b4b5a21e715101717710bc7eec56ec2e58002127d1898bc55f8a3be385d607b3ba6561991ac6f0913617303830da25f0cf0ac14e67abb8097d17b0ad1ea8c6c267adf51a15a9a363d7aa5c8ea535a89115c984ac5d6bfa922c6fc44a3b35cb667f939fa6b2676ba212c17bcd25c82e8172f6a7506e8b77d82cb21d7066da93a7eb3cab8e881a24c7592bc6b656e459af33a06fc2846d71221f1da641004b68bd65dc28a59036ca678508614b15a93e74f89b8af58200d50e718dab1c41c4556cd47b43f14092ca47397243983406e12e423233c90cfeb661a32ce65ab464db58c922bb693f56553961868b064e17a11162a7f0e3ab0b0aa76b8494ba394c902c598c23721dc16c51d46b8258c635763776b922fcac747985b94c006696f18ba49d0c5eb0525cad1349745691320969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960d61a6f94b317d488d2d04a8b42c7fb7d89d52d89b2de30336333c50895348870bbc311611f27845c7775128a9cc831966fccc06292d86b582a18c6ab2fb3cce03701ba91047227a9fcbc6f16130710756c5dc288ba92402b5b7dc90c39193737c206f3f8230261852f1694258d47c469c7452156e70634384825bc52b03e90720066b609a4102862433e2621987e23af51121bed807810501200b776f847ff615c0f594420dc29ca6573276559c1c84b0723569dc2a76728909d9d1279a8c240a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb434132ed5f1340e2c669430b13a709f7d1612af876454f06ccb7841f84c60f3806d5e423cb34b23bba90ab630403a46783329707388a1f4232785d4723c993cc62284d0e35242e52cfd6981268b86f598b11472900f83333c48627d402abba59c6740b4a40abc3200b5d9e13010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6e3017c94ba93c7518f017695f5bf5b99214c8555bda863fdd11d40053c0d652696286d2ba14d569915e4532132527ce1b88122640ad668a20964476db20afca5ca663c6c17156ab3cc8e4b723b3a5209d2d10767da52b2443764f91a7f3aabb35137ee18a1f744562e22385716892ca77d518c4bec578e0f1145b3241c1831bf782c760f9081a1191812790531648954163b10e6a1f02b2b9e17cdd439c6707aab0df09236ba33d9b271196a398ff0b2c9521e57b6c8833489c5328f4866c14d2cc1ce037400dc610b28cd99150404a175662102f9617205c1cbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d3e12f5b56406cc51796c66a6e871deb601cc767c0b8e45744346de60bb160808210506c5779bc275940e000314f30555677689f23009a583cd6f9779c83530e5b2a5a0a771bf1376f0091c627afecac104fb2ba251c074e359e5fc44dec244ccb78423532a7eb27c8313a341dc1431035162838835c85c677a420b67c847dc6605821587c8064e0bc2f4fe6a6b22113e73519125b92b3a66f15564666023ea99273d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec33075d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = d17ae2301459a388f0adddcc7afd2405cffdd627343e2d01651c3fce83f51eb81a69fcb5ced2966fa4645360d1e89363c3b8104f2799e7a22591cbbd38b2f7ccb8c699bd1c9ed043415bf0f3186a916f854136a4546742d98b1c36084eaad725af2a92bbe8efde8e66a3ae38b0f4221bd7390fb6e99d4b5268dbdea674436f949b4fd7cc00c5424f83c669b3c2ae905501599bb6961fcf2f92bdc83c025285aa3194432fb7e0a1e66ebfd5089db70a061cd8a44527830139fc40e67985412768e74ad81d5cf41411238ed3535075931aefb8006e90c225fc9510d645b59f97c1165082fef535b25bfbc57c38a6e5030a2925b5039b7c3c6bd4e56e5eb2d6b48866b91ccde538bee232a3ec190dc8bb26469e02025bc5659e98ea50813176dfea7f4087beb9c59f825789bba86472714b676041fc385d4773332bec39b99fec6cba68b3de5ee080fed1a65a650c1c193f1dbd98d555320143d1db61db609ad6541c09135dc0054c4056b194321a63cba4142a8f397f4e8c6f5d04ea3988a1f769e191a43c0743644cbae9ee20fe4b1da409fb8c3bfaa2d3e02efff51816c5daf25374f7d5270a807ae7bc94027f8ee673b03e1b860bf4e3856ed5eae78b067b8e1af3cf0c4d9de86908a96472db51e7ee96fc8f21065e6f3ce849b09644e543b27b4573db1ef9e0fb407045ebce6457290d225d490d209d2b762d08e94ffc36c4e717954ac4376acbd322bb745200ca84c3e67115c5ec5566908083f6f9d06fca56996c4ae48e67182fa9bf7b547252a552e037f387fdf4105d147b9919f8c2f9c588bc7787a75d60b57e441687a15e057a379bfe9eae7ef0f222ce5886a7dd4d8adb1a1048ad15efb70b951998c7ff236e5401110c904dee9d34710a429a8bacf98a1f14d9f635db19edf5bb564c8a598de2bd33de9a33a8f96fb7d1742313578f2f83f382545264aa354dfdd9f145914260faeaebdb769df30203e41662e183a5dbb991aed6cfffca5db84058a1eb808beeb3b9e6ec299dc51a0c5a4e89a5cee1be3492eeef9e9e573c427e33291a3fc1efea7943760ed4a564e1b93049902fc35c282e4ea9b39f26290e6c88bf8f7c59dff676604db287af7e3af34b5348dbfebbab5041bb92bf0e114d12bbee1dce00e33bc44130f849113d80e95438de828684c8da1366fc3803f79e893812e81b5dbe0b417ca3426fb994a5b8534e941b9bbda4d9a975cbca174854761ef0f7e2dd14eec51f2926902aa84479044bc3275f5c612b6ab3004771f6b590eafd45c3cfa3c986d203b19fcddda741d6652a3282133353a66c45bf46cbdcd7f996d3b0bef58cf1e0276c34452f88babe26928e608a880baf525895ff3cb1114a5ed5bc4d5ecfe3ea527e4651743e7a036fa21c2794dae4772162a93968ec11385e2d4c73fc13a212cb957e9b40a99fdbd4dffa137926ca298f963f10eb9db3f5fd96744ed1e8c0f38f50a43aa06ebe280607c14ae30ec63bc4750e31a2923680966bf9973d799117bd0f514bce085d28dd49e3 +expected_result = pass +expected_shared_secret = bbc58d06cc14f9e96a10acb1789d93b93933f1429cc53a1735b3cd995f086ce7 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +private_key = bddb6a1bb704f8b530860b719752402098c84ae4809b01c8ec7583a66a3f4bc290bf2173abb41868225606d54991f5b547c2254c74391717045997a57ba534a97b3605e1ad9f7c6446ac08bbfb1999179bb8f67731a63ce1c717f30b57fd17bc00605e8e14127eb0c26e324aabd45138484a51a15dd2464440178ca7e966d4d58383f6bf9bb2a971729074781a8d978965f9a51eb2729ba8c308474d56089f2cc869b523c41c409507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373d5185426b7b3951256154a7b78cb1f5049df0371b840ab21b83944fb383cc84ad9e24ff42b2731276c1d26b6120534438b029c4ac7c0739453c2860d32acd75229c63a23a7201c303032bc0a410319035d38a3c9802d41a56a8c6c2496db10441a2bcd13a81f90cda2564cc9e4020a47595a30994888b383e996115aa282eac3e3594447110c2d07774f9312d796c6b74a7634b6c0da2291458a35d3022bee048483461cfeb152e1d2ca9195afd1f9aa82131804d35e739299c539b913c54a0c58683259b3137aa464b9c6e03b0eb751999b6c5354d6171c78cbbef1b456ec4c88199764a5761d18c0849c1b0a263ea401b86cba549c712e4a251830f7b6ee16b2bfabca3ce018c3833bb881385c272dee151ac35a2c9561b3c1266855219b0c6b485e669fcbc49b24c50c6c3237aa6b116085085405115e0422d956beaff9360b58bf915654b9b887ad9733f425a5c6990b3f0223d8099bc0e95c6a5702cf5667209ace08fb4697d02dc45caca8074185f54ec4641b35bacd2f0b770fc215fdc171c98baa7ab6c0450ba6e47a838575a528f7be221c3c91f02734269a9425a2edb76cb6d077ed76040a716d39c9c87a58ad8867954c752367a905aa158e0a9019dda50a6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aa9a0418c79a948199365a6a1045238104280ac704b33791e156a2377bc83e9b9c86d0a3d2aa3287272be6431bb4e598232312d10d03bcb13b4d838a9a624566c6a25fa44a0934ab6cc333e6d52af3ec26a6fb97615cc3c77102d1a315486bc69c555a3e8271660222a406022e8d97251308a90a15f748153c1168cb133593c1641e164c8a06cc008059c55449413c2b28667b99122ac42b8bffbc15fe395003249c676db7589d2896e7405bef8ac510782ff204454c8a0390c332ceb7a5a3123eb1a1ad0470096058358ba779df70106e24990da77aaf09705110993f16a2320a941d8865b387236cb8528babbf2d9196c15898bf71040d3ba500cb7b1ac85df11003a058d838c2652d4577306023c756ae9715136e91b20699fef425e48953fece15baf27489d929876803eb0b5764e6338bf5970c2f35d1e815bb5b0b1bab630138859b729923343c3d24922a8522e38e19868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5b71ea78c2819113fb3632d5d995b02926663f2ab8e3a73dd6ab93503192e0243f2593618e3a809684bb6a31674e77802828fefea3a50fcaeb1088f7edc036cb84329c988d965071e97c1311643bb1ca2b43cc57c84cd5ea9109ae36de2801cbdca3bb6f977959578954ac17d303841d5726631663f12816edab5192042d43a4271e44d1546306137a4427130c86a2025bcc297eb36d3c44e7cd4b0b1c22005fa702ac12569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb3a268165596fd0470400ccf5e3b56714792f7a87b9e03019751425695ad70e4ce0b2769571901c6c2003b58152fa9757922bd28a094771b0cb1dcc73741b14b402e8ab86dc0f647525c131e9aa1a9729075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4c015ce5f65fd1042a137453462b8710704bea463204c463273bb71056378850ad28f37ede664e38514dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd0a0417c2655a5476f51a68cbdb4aebc53f00c11e78e5ba6692a516c076330c20d0a09f167bbfe1c956a619825a8305d1aa9ac5736e6d24145924b2409a8688b41f33a181a9e4858325140a797f2ba81d50f21af88650cd0ba8e662077708551a947c97c0a3355852a77576ca5b054d3b0b9fd973dada618bd02fff1cb59eb56b12c71b24bb1f02e27282d21281493ac7d07a20b124aac30b7bcb8c2ff24b2c927d3d62ade0357bbf7c1281fc94da2b21d10a5e5ee07a3fd9cf93e34615b871c8da7db5441020d0522c12711e1963be54739bd43949999083115988a09c6020ca88124b35c34ebfb0743b494b2666ccf5b5235968275fabcf9a054ef92833d8ec816d68c07fc53634a02ca192a411c87dd1f17ffea094b6868638716cf593b33483591e4049e4e7c65c8618b242b17d6021bf0a70c7c59bc81c34f5441b063b9a1d95481e6529602b95f874bf1c649d95a072e70a52e9252e1dd1bccdf64332345355f7cc48eb7dd1aa2f2c31ad1fd58b8b3a711d113c270a90aa2c5c79958f3907ae3ba071aa6144b88ba6c5575bdcf5331729a65d8acf3db97aca4191b72a2bc1433fb3483efff09698c291dd868275dc5a86d06d97305ba596515e434a8d956b2b73b3c00821ba055aa7541e4f35896113acfd9320fa91585f3212cfd5b023a77d7c5c0ceb746723c2c7d7417bfb740e4bfb2299b29f987698edfc1b8d7b33de2c80d0cbcb44f05b1ddbc667005b6e4335751ac281022cbcfac0a55226fa69cff845007b9a16d2b6bab3135b325b12c263a81fd423120a6fa639910159b693406411a289863736557a028bbaa23e0c984f04543e61916d9bceb4f64fd48823a4b13e4f83b43d443f62ecc72fd304f71772cce318c1da9a57a67502a1119313b93c4a66d03c2316c2cc5c2285b1e80c413b2f29c447dc975923d9100bec9db958acd7850ab0777d82814929121bb87a6f4f07880510331ee6171797bdf23850d5fc1802e432b2f51b3cbc37631c9729892b6a09baf6717e6ec39ec2b3489b33baf257c35b9cbeffdc1a1334380fc35df386116baa9bad3a0a8381c4fdfc4b1b98836f23ab923175eaf72c59d9c500e10944fb0fd701ba5142b3cc358bfaf2732d643d0b135c8f991b0c73789c465a7e1b3ea6804b5ab9ab2e42ca1e91158019306855a5767893bcd17e92a41470d721f6432448fbc370c64c3e330d83987f3a9479f000c75320a296393e253a68e0e1c05969784f5612adbaa2662459b09638202b74d8d5cbd2b01a915ab2ad06b08670546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26eb86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = f597c7ed20fd0069d448c8616f8ca0a60aa23923c79f3bd31a13638775b7b3507bf4e3145221ce3417a8f22282c56862f8ea58cba7a512dc6a3fdc2da6716961ff8011c58c633ce653d39d0399d2e73d4668464a46417545674138259864e639c1f06d6a7a315805340fc277e17d774d3a74938390f399d53514947eded14cbc65f7e33b12662e956478000bf8f2cef30db0b975a93a7383845be2de01c4e87174db7af718e2cabf1b71cb22f166d9a75211bf30aec147c47a1b9d65d9d82c86e2966eb0c3d3b393360e13d085cabcc195c702e1cc4c696cf1860a9fb9b89116a7def1c2215ba5040cc44da0a908209f3554986ec2b60f967d09cbb6291f8fa38319cec24ad9ba588b0c3c6c46bce7d5ece8496313a3ba853ee2060608fb0ef119ea35ef976c77a006352a86796db6e531dbe6598df8d2074b27a170133cdf6c0110995a39796de53d4d7da5068a0090bd08cec831ce7d19b25b49f133b21670b1a43b52ba1c4f61cfb6c9b1ff1d42425501a054697a1fce811a4801aeaff05643ddde4610df7917cb89b82c22fa3940ee67219c6a0d8ea964a4cacb30e3a7d3e9c3bd83b1f0f815a6c0ec6dd8f21c1a49fc56e9d30245baca996c8480d7855e3c87094f1e1100bfb2e45f36698f69c6f2eb13d57e8e40e30f60abeafd09b435717fc89966077bb4f636b6c97dfc6ca7b3d042dcf04aa866afa00a4eb45d92d45bce0dd436c2e4726480cb543d0e95424c3077ac5328d0114a5749ffcfdb48753da9e8b2a02eaa4427ef17fc98cf6298ce7e793910d8b28649a8362a9715eace1cb82df37a96ef30adca9e945512725c4a1202408e6adedfdade710fb80a81c3ea45890beb0e1224763bb018be9f945f4ab02ef6ef3a143edbe9dde24802b01666946785125fd9dfc47066d4635701aefb93360443c5d38d72e5c0f1ff6d3b6d9c0461a91a91b2ef7af8f6533169f6f215b69a71e038cf1add2c04b8bf8e805b1a2a3c60b74bc236ff4f3adbe3cd3d6d1a245cfd080141f54dc036b6916cb5a8b5121b083d7d89d0df82cb924fa847baea59d016847c03ec506bb33f77baa0ade649403545f0f398a9165ca6e5a07eba51caa1a86514e47bfa152d6259570e04fd5a3976bd7a816266c11ae8b5db9330999e9bb1584c4cf669850fcdb064c9d58d959e4fdf4d732b5c7aa7ee5322ba653ffd4fc376f712b8f35e3832c37986fccf33330b1974655d158f3563f886acbdb73f76556c077812c3113246c03ff3a61e8ad973d869aa5f0537d987c0eb001a634b1a01c63cff5c141bb058ce3923d7e0bdc53c44a88fadc9aa48acb254f95d107954b50861fff2b15e9223ed5d575741ab66e6453185dd0c70cf1ec5a3baa6d677cb79a48f54db2d2e105e70809c78b4ee926b903dfd735f9e1ae9aac04c5ce73f34d4b3e3ee562cff04f7cfc383192adab68ae3cda8ec2153887891284ed5399a24d85287ef0a2669abca1eecba26d997219d98a2b81d9f8f91e508ff0d9525aa8d077591823b7cc28b3f4942f8ae +expected_result = pass +expected_shared_secret = e045e0391e15a66d6208467078f2ba5e429cc586c410ca6c5f3c032c21761955 + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +private_key = c6389f081ca0932ab66f658046c1278b38bc42b5c4e1a7c7a51b09d8a159773b67aae1c2aa8666000c6e6a014b5c0369dff147688ac6fd48c73d783e3025c92d782a479acbde8a7548384b763a868c46178345a773a9852016b9fe765db0bbaba5751e8056b7564c53fee8040d3c0125115d323c62a3f0a2b518330b6cc4abca84f62c792d07c1e1a0bbbd7c5b9a698cb683981f8828ee69912600311a0281dbf9c6c9e69daa26a446d136e8b0310f236d7a5a49b2bc616fd346c3462ab09544998c8d5ef641e7b48c35ba7a68f25414f703fb02b501c69c58a9b798c8c76923272ed9bf432208bab30f2db45e1cdc56f6ec11792a33ec1a62b3fc992441527e63328a46003db49b7dc07f73f705ca0220de94bea4967213d612b5a03b2c16a9bd4c66e0ac893263169a87aeae67843944628e6374b5518bf40919840b8e6c64172be3a35ee5a29777c035463380203072ea50e7daa4f906d01c502560621137b91649c97417cc2d3e1677006226d4621073cb1aa213525199bbbfa78f1899a53cb2b8d00819869867a41b2f48c615efe2c8da15a4e6965bef0c4207a499a2156ebfb611478182d85a71c9f8776d28051d1a6e4a104e54615992e0595ca9b0cb2a0ab0159575863f3145b3401498949502b2ea4392c77728215f8700c93f5846a1a8126eb6b72248bd1047bbe62aa58737268428509e53575f945735e75b42db2ba2f21b24c990a847241d2c3533b10d50847c85d98143fbb2eb5138accb055a8b8bcec8afd7b5697306165af982190821a14301ef0a90c3d829ed9035430725a99c67745ca415600d10d7c29b228998d7402efc1f0d0476c4d74c34754af9a1aa1213c9a0198065378de2d023eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c604760ca679b301ab08ef1a948a5a83debb39651310b368c736a56977f78af0916364f278a4e3973374213f7a28ba70296d1916fc65cad3b33c4e1597f818cbc489ba970680999c373dbc246740c07d97c5e1ea5aa1d627757f4467e84ab9c5bafd9ba484f1212706788cf5ac1829c7ff0a66f26c30aae327bb7e167bde95fb5829340b187162a5fde3a7cc6a0a05fdb6f26902bdb0c6c4f75692e67ab1c8b1b46a40e53fc901dd892a3e612afd1cb2cd52bc5b0c3191137e602b0a5872d3a961ef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2db29b637a5e22559a59971be46004fe2a40f7c330610377a5b0eacf79d85f3c86223a4c90c31c2495314748601431fa1f49abff2575410af33f7367c5540084b75d6736ecaa010290839ee2456ee16bbcb57c601f26aa104916254a689c24cae98296e4bcef8770ed7485511f55a46c75592c88d6f76005356c397eb1e61caa04bf55a05c8409e644055759a7e60c1c8210221fb97780b92c2c8aafb6b94c259a9ce6291e18a801a82456b93c221a625129a1720328f11574a5c35c3650a7b57619c61f47ed6319329f118f4c31358a26a7e9191cab61012a71b27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13d41256a0b442f0428de78f90609a11b8cbb475083712539e1ab034903c30f6b73bb8229ed50f901b142a597e7fe48b38e84df3c6a2dc2389897c3745183e08c1681b5b9f57c16aa2c12778528510868964122c1747662cf97d8b0353bf23693a70b3b2a7c8cd5c5508a227261cb7c3022058e318d3dc39e320770724351ad78010eb423ffbae6714999226895ac23735a9119622bbc0811516d617353c7f769628925bbd49629fe0aa333d1909a16c5c27604b7db0b4e602ab27987df23c3718630ba4c2846444b83fe914d840cc8ed79a85b645a32809ca069ffbb8b3201131cb129db9282b73174f8d4a14a37393552b109d2271edda8d968ac3ff67aa3374a2355c2ec895441873325db71c91020e91f19347d965f1410f606862f69643216b869673b5a70583fd1218639b5036cc11d051a13d219f3969c817326d2b60ba5c13cd8cbc9313aab478833d73716a2a48438fc529084c241bcb4fd67179d1f5494b4bac2b05a5767b9647ec8829a500d1365bca7b8ce7b75bfea0c68f8a28edb7bc4a3817c0d32c4e10169832b9abe271cb0b473aac2c3dd39ce895551a297a61f47162d97c41f051d48b62e5a8882da62fcee16eacfb89b98a12ab626e69d77ceb3b6b02878ce346ae5cf754c3f6097e0b5eb7ac80b9b8ccd9418f63e545d01c7d17a71e45ea3a6d927484d4976ca936fe392cf2052535c201de9464008c932617cad94085c5816aa41973a8d21610430ac4b3080dd480169258e65b53e340759bfb70d68b15b868c4098847901a6b255938ecd15d5ea94232b2971e3bcd56205fc6f0425f50ab880821f56c7b25f51f2412cd7fa023852cad04f2704d4103d4362e965473add3563d9b36e5097c982506865454ba30af132bc17c807309723847257c697c525e27cc570a88a1688134f4193db67eff018f54751e578483a77a119210106fd03066c403b3303ce54b39493323c4334d4a7a20aae04d8ef529a15cb7d0900fbc4236c717310246c9cba14d6874beac61b566593b5ec5887272b914ea655d254d595824288a666f10c7da583f933052f43b0b0fa59248b0584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea50b00a5503cb542c254a26f456aa3286b0126350272638ef0b4a3abc56fc8d0aea2f7396d97b64c56817d58c32103996db88345d377fb7b2644fc99a24258c50730045b897ac908f7fccb81bc2b51c286899c8c499c1757c6b0a6ac0a8482159d564cdb746037a1224ca72177f79ed19a398040426664abfbbb7b7ba99906e7982b665a551881e0f02a97409a3e2acd37fa96a4f9293f786a11b21e1f0bb22cf400da06081bf68111a9bb64469487d4cbc10578106b381b8b054ee29339e1830dd613e19a9baf9a81c2b9ad1d121a47d40234bc9d4b79c2f5f165bab5a2db68c59c0737e0e4786990a92476aea44105f3c77feefc342b458e4310b9b110a8b2c01593b512f069944828a3f6a219354bbdbb1c344f24aa0784160ca704bfd89c4933b6123c4434cb9a6ce16d3f042f1fc571db728119f6a33e4a9f6981193d60be6ab916818b8e1ff9a1d1a59de8824f808043a1949a5520b675d8834ef65c1d47afde2710c6b63998d43ab47a681f0a856d166c24494081e076d5fc05b541145d3155e232a5af0ab96ecc0b09c2c41e285d350500a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c285441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be6241646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = 349dfba896178907a635a6d93910cb4ce0ae4089e9de6c1092bce826d207f0c09a6584f829136258e4fc56f90c21ec74f1984a23afd3515e45b45bd34120e761682de9d9b71670eef80dbc1d5b0131f740c708594e8c66d8096a571be068b6333075773f92a082d2ac79acf46b19de4d595b3ba7ba407cea9d4901617de4f13679af9a45e297aeef0946c2844681134a6d869ac2da7c90b089f66a805518146ec3bee2cd95744d0d2768a1daf931928e9589ee8fccbe3a44d010b794149f0397ac81a7bef9ff5243d98b9492c220e872ff5fea295102beb6f9381815aff179c0b2c26d2416aa41cee61ead73a2e91578d584c8c6bbb5c154a12b94cac64afece0f7081c7c2e071dd1e63e56b44296578a4402cf3775eb713146f13faa0d933e85030d0bf6a26f906f12f826c1b728811ad3ad141b4303763d2e9a651cd6f968af3ab97207b6d17f95c0b40fa6652637d8b84721f3a9802645d5f6f828000e58a4e5bcddf3d19053bd1f8f8b6b125cafaabc09d08abfc852858c7b860542e3b08f4e6661e0799d34ef209bb62df89d5a84e9bfdeb853410e54dedbfe0bc9425226d9aa4b00c51eefd9c2fcff48082e6b65720b45e7175f3bd9f1f4948495dfd9ac595d9b485c779f27af8d4aa8b781cb8b332105e0f38ad554696ce80c4ef5ff762f506214cc8e1e3fb1d7a230b20aef8e55543450eff4289d401861fc37c30d64c4093a2d512394c07340d814aa25476ef992919e6fe58577fb6bf70c6778aa976742bbcfc4677d44b79fedbad1424641915e8599b8bef53ce2c8ed682a1e10716e1d07d546801a7eaed846ae94908475ea20eafda70be83bb7e7211698a2ce33370b83da952140ce4029ef0491d8d039fbf1996cdbf1d04e576c0778b30e83572d05081238743f5b4ebde402629aa9ec70399e364aeae31894e56c397e5430c7250e80dc4d0b749a276ed02ba76e190bb17a2740f098785b8b0e2de69d65cad3e770d853316f7c5cfa508a7ec990c81fb912d1e5eea2f0857893d5e10a1b7a2031169de2ecf3935623c769652de3c48ccc671dab69bf992226d95fa549adf29533f6c58f3e79bf56cb5b0399c2ed2a5550e54b4f9cbaa157719c47f3db6b7ee8f32c04d830cfc4bba8573bd3c43c5f9069704448649bc3e638e46e5ceeac812d356fb616835acbf0711c31455124000d451926c1d55ee0b44295d2fbec5913828b5f4ac5ae3589045192a0e006b3466d8ce6347019f0879e4bb7baff07e53a95044525a843d7f6d91e06f6ec2064b975c1af4017eff586b7681c8c5f7125b6238703bb39333ef122e281229d9c67d495eb3d2c6ac5f176caaf3abc6fafaffd4443c353972b5276f4cce612ab4f2d11fbd30b71974655afecbe8814b9fd088655f1da3a3f7408b36c9292a6d086fab471cc98a21888298fe7eda2c5a1a732c7cbdfa70286ca361914ff83657b7537b84afcb8ad0c653c7bbe623745e95a7067d7cc698e80bd94bf02a0d52b1ff03f22e5e4e62af3fcf152d5c35a20b61cbff2a +expected_result = pass +expected_shared_secret = 0b8584b75838e084839d58c89cb1749e82ec06a0e85464c7546dd96870547d29 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +private_key = f75196a57024be817edc544dbd552f6b42ba121c2b8ea95e55017856a10c5905a8bb2590e63b449364802c6b438fc19eefc875017acf652a8f0d6ab0f7f5aca1f1833ed3551d37419d906d2b55123ec14d5f109abcd9382e990628bb30d882cca8665957346c3a08553c870d32f77e66348ca9dc321960b7d50b09de64178411439c021899f2b8c583762043a4508c3160544ed2264735c600a6ab43c8515532130583298a11450ae3b7c99ff559a1d33115dc2d2489934518bd52fba1cb9a019d918464b59cc90941599253957364dcca9f95a08035f8be5bd36db6b19f1f191a6e4b7fcd493b7a41c90bc76fe882aa0f3b39b6f454785c5dd1d106c80960bbe5846d90bcde837cd277a039dc22427b86a6658f97a60101665f3f69125445647f3bb2d3125c80d89aae6096a01c24902321933909a8a2925faa1e7407b3c90c8a53d958c1c83465e557ab620e53509ee8c960b3c547fea08d4ffa215742113ed9661b57ae1b30ba5768645c632de76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0863273c345c4c7379cf3f873fa5953f53b9a026a4dc120c96e279085566c7d090eba276a0928693e639b5564a59c08aeafd25915f5478dd86e938a11529bb9a2b0b83487c696e79f1fd034ef000fa502328184be42b8959d9c0683f3bc20e71902423ab14a4744e162f6a2b474dbc4a6f21fc0432ca7422cfb253d0f952be9c13125458df8753f5d551caa38bcca1625b533051c5226c8768335854e7477064320cb765ab9eb311a1859b4b5a006d918bd8508a971205e6902897cf95e0b652e09030794b46fcf7a784560c0a18b8e6334a57ec177ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa0104063696f1020bd1b443419989798826e141a24a3533494391fa233cf848451cbd609d014508fe137534c42d6f22ed2cb82363c847865aa243ca993b14992572cbf5535845cc708bb09a1e8a7834c200d8036768755afab53aba85813eb859ee83efea7563ee4bc158599f0cb04033393c829aedbda289ed852e1eb1feda9484777051f967e048041ba3c313a1414d463cf3ec36801aaa1aa540deab122ab530ecaca30101a1089087311972b338b045a1637189020c3030e63f707feea9af844c7e1b20b4a5348c1a432f341bb9f598b8c0c2f6f55c4d2c2c22b187430748f82842daba92283dbc4bd20636b6754b20a7127f01fcfd4013a1155e4746dbf3ca1f34991fe7c39ed99bdf5760d39db8e6c428f2de8157be0139415aea96bcf6fab633f2257b582312d3c7acaf6a5f8e55ad699672160ca01246545059e58502e28199cd0f5505adcb91900a283f0b059f33d1a8b352010a3c815717fb3a9482c946df0c74a526353d5c9ecd2590c5050996393a02286841580ab599bfbc8838a53301bb11d5fd492af40ba26224505969d88f6b193ea42b0348954180e17124ec2c64b962a92aa9c3fe2d72f94301531c4aaf847243702bc8f9c37d64b54f20ac003b844c52417e1436d2e75ac09c313c83b8575e791a7c95d0412cc61521a6826997561485dec26ad7baa8e065e9a279add7301c5c74c5b95c1b6915ebe390596bab505e51b3fc147af616e0f94506635a758964b3e7cc067b80827db21dc87450fe1415ee41fca8a2b56b355fff13616622fd1a19a7cd98f5084610d1ac9f1b8a6e78cad9281a0afa5a7c2a9a87916710ec9c5b3544b76b4808d01399f219b745962536026c79841f11961b63c10c99074edbcb4ed786f7e8c3826609533e5bb4cb80f3e515299eb757c217da2806d26664f154c0cc2b4a644b224933502adf5a66f5b54cd45a71589219aac65be0623cf5b4c0df17e72cab64b91bfbd903d75e164e2a0c9e2c997f36a0b432177de617f5e6746bd82984bb9375b4a0a12e96d06045a3a984667d03d8c08cd980b59cb2b0983b13f9c53790fd43653e78255882f9b0c980ef6b062789332a6b67b2b78e9e370b78181531846b9980a8af905fef403f47b891a6b440ee71cc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36613a15f147938d32673402164b001975d9c4a8ba5ce84d20b47f26eba5909183c6fe1343d062389b9b99cedd21e30d5841fb68f3450a47f4c4be5e8c413c37ea4d5ad629141d7430938158cd04492bba8aedf7477ed13a0b97c8217a300dfcb22de05449547626d21409f491098162d7ab477e3ebaf0e15124f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb6705a467a3d4d9102ff2b6ed976ca9d856e9f257d5d586c7d8a4c2617dca73aaa65719a21538d9e6997c5637df8c5a2ab98a169a5ba8f708bba55f2c0a9463c9b4ef0c9822fa64ecc72c8bda4030157bde5073fae6a6e6f036121125dfc5a9dca1504a1225e6da9db4d0665f6413386153ae25be78b3410369bbdbd84a86c6c7bc924dd70005bec0c54e07b4adfa2daeb8265dd98bcb8968a2f683a3b07633aaa0290550665c01fdeb22398aba31140fa7494fd6a0087194673f51ac7d759d649a2fa4d7520fc67138f445287b681f5c3d1678b497129bc6624163e3515c8381e85c173d6a4cc0038dfc2064a213c557931e2e7138fa1a6bc3eaba08965bd803bd5759332cb1bbc4c41337bccca153905990970c261cf63a53204b6f8cb228d4234f08837425a82f1da9be43775df88a20a0381f70044c76b3524b437cf365cb131baa14ea6f24502336762c8e126afd009e1997b8b3bc20c246070df7b33bc9a7bdfa8ccd576925968915f186ca4a5a4934528dc75282e246b0824ef7118d39dc1f07449a218836d47cbb7365b677ec7d6222abaf33068b5730d9e674cc008125226cbc5382a76a9823db1b42976c5c90c23bc02eb7b874dff93699e6035a838b22a7126aa42d62682505f9bbc77143dca061f5c38e99652fc2e28e30ca8d62127af02186bd9c95602992e20baa636ab050ab870b11c52da19b3a68b7a07a8cfbe7bb016a2537e50464265ff6f065d7a8c30f659998a35d79032f887b4629d07bb2dc895f09ac0387cca9c5cd1aebc08a687798721f24ca43c2c5ad42d1b6641838efc2a72ef210bad10218846f25da336a4c00c4a29eac8a608f2261b8c76b18f10b7aba755771376dc7b876152f9fba5370262919511d4ad50d76aa5cd6566c29225dabb3b668608d9de5bac08320cfc3570a0ac8deb4bbf3d941f9325aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e279238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = d0bdfda854711dd009645b9d16ca8d8f4e44c064c54bba2037633599d73cd05e6473dabd029e5518b3b9a39b6b01f6e36734b5dcd4f8aadb4e4ed8e343b8abc4732753d7942f22cf1bf6e9b7fe074195d1c8f414f856c8175541cf0745b755fd58be49ed7f6e8c48ee393f508eb373e79a8a06fc0d5696bbf3f8f8270e3e2b890b90946fbbfe694c34d4df5e70a92a2e6acec73fec7dd90cdc7ce99dfc563e9bd766779f1460f4776d7fc223e4110ebd68bee47a383bb5adc2258dceb67fabe8933641d2cd6f973c157dff849f6e190837fc795348d9e78b3aee438acf7dbb960f6cd9de2630b730100b913e856256c3c5d71da1c83bc29a584bceecee94a3a1e16cf22b7a610066603c14d44268dad9bec3cf53f72a0774ab0782c0cfcc6eceb9413769d4e6f531656e5592412152ad35d7dd7253b3e9578d11bcfd7f0cda76f89c5a3db06236c73f580d7ec441f67a67aac3ee4a80f9f56b56abf7debc9ce34dbc0bd01d5cf3bfab83a06754ad655c1610137071067feb622ff6afd666b74e52df3d95cadf8b05c5e2a20e3821d6e2620f778cf103af079dee56604169f3fcb4170e5ff130bd6365e3a6de215925f4388204da9579b40e98d5831c43fa0d9b60fe2c9f95cde75b2b324f3353206a3d978b805e524211f9e257ef0ef5d391e4258141b489cd52c8e1aa96e5ceef558308952c3ac6b9a01b5cd6f712545f686f9542632e748bf6b492af2c94e8686687189e2b330a71de41e1a9ee6e6d74b95989dc6412302817081b68d1739c82a2f9a532a58c7ae6fd5934d04aa824c5d1ec5201b755b3761a3756bde866b085778597087f99adccc1ca9fc04fce92a423631d4756cfbc70b7b1b96ce5ac56bb61cf14d84fec2fbfd0f62ef4691603a55b114d2216a24b4f6ab07fdf35d7038610882a7f34cd9958d94c9f0b99ce1e5601c72ed128db8779ab1c3fcf8bd8be63c01dcd14748a01e1d1232210006f4ae5183904137d04c9fdbc76e9cddba4316c7cea1eff42e9d5e17dea82804ee9cc40207e28cab35b342bcaa802555f35cb260cb481daaa76739911a4260f26e9567033d69337bda9b11f6a1f88cb65d17ae0a5cead6cace4b93a1f8184c6303cbe5695d37ebd3a7e27f813ec8afb0d18a72968048d27f38cf9de4cbde27b674a672a400aee9cb90c5c170153f56dc3ca8f01035ad173e6931332180fcb2a74e4ed21d6d27cfe9329dc4e275416be050300a90c12cceefca2bee8bf52c71803cd8cf39e29a51b60f188bcf905eb3c35039193d2d0852a62c8543c82f3b2b3fe3e4d51e752eab0130fa0b89f1141dc2f1e73536b8a963022c2a7914eb8f80f9af9ceaebd96137d17c3172bc2af2f819e0899d9e55fa39d6a6c7139a8a2866dcf41f46a78beec546de4b4b47f408128b9317b04949e6b083976cf9e0fb6031a8b88d82f0f6dc64cf5334483a339f7b1f157031a13c751fc62805d6d01295352df2a48c1520fd40e2924e8e7d5e4728dd21cd7069f85913ed776631125846e2e13301d8ff7f2 +expected_result = pass +expected_shared_secret = 3547a15b5748990a5436bdc4db283738eb7d64bdb6ff566c96f7edec607ccc9b + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +private_key = f8fb5ba9d24c8681558cd13593f0cebb335b6f65bd5dda6de6d19e09f15165051f981ac6472b263cec43883a79149707093066fc129ae148b04f860c2df119f8a51056eaa5dfd89bfc564226e56dc391ade1cc2a1df58edd4572c5a147bbe21283b97f1b213bc276a471b63a7df1cdc86c7a69a34ed17a425b37aef969c1cd079529ba29a2e2c3412c5615e23523f3124c00c778752bb9b3677b90885cc21b0e257bb7f335fd53928b737d19da3b3208219e6c898e96b45f801135a09a1425a0986c597e2b4042c1a4e6d7a4d0e30e729c73f2bbbe85b579c3c13a34344a7403b95d425936486c3b602804c08ef6f5ab22c400b9523ea3345abfe666023bce6a1b63a872c33e3aaf0ccac2c40a4d5a48107d0c7ab09001ea67ca6f4c1fa7137d259c860d032c396bcbcb4177f82439852463b640855ce604f91c8f2e4a0899b2102c6059dc077d5ee6054355c546c2148077b8defbc313c71f1a420dace126b16c21e40064e2522f9e224cc8e3526b1a99a2f4a81efc2dd3609043246d461c7c1af025b56a9c7e72adea57584cf044c2f0bb60352c32400d1631c034572ee46b71edbc0334031aed7bc26af543028c3918109da52a6abf3217a2219c0607ba9edab5b4daad5ec7948393c4a670c340688541aa713b596843e5ccb9616b54e92610539bfd39159fab36d4928ee9cc8b1291ac0134257e242faeb595100ac113ac416ff517866021b550b6d063512dc37477117d025964c95c13535c2f09a96740037fe1846efec4446ec03f93fa6b6fd8b539f0196444a61823b08cb74b7520618c08324f0667f142beb3a34c2c5286b3d159fce3b046079f07e558ba28a8893a8c94f9711c227fac6900114c8bb6aa5369b059dbbca008482a1843b62a1b06c68c6b2f40bac6f02b6cac1633055a178a396ef35f59f1a76543953d3b07e2b8be217c5d5b1a82f9c080f4119d22275958026280bb8c96626c1d0baea6658a29546e09418aaf85a121f8647cb4789484bee0189b9ab10852c397a2e25b9b15b71ef17440dc3554db740289ba05111979614aedcca79699021f4bc3a4c68b39d0256d88cdd7a24e3ac31dac35388720671a12a765d705f8429d0891c3e0d8062ad45a0b882bc53016dfb007d1c550998963d7e12fa51c7361d86156ea3a8ad7018c627a9ea18f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50e8170892a08fd15cf2913749d0c61305c4de45a1ba2550009726a0873c70049705009dc8327be3610f61f9bc60a26d14dc0c3e67cdae4b5ac0d5a0638804d6c6b4ceb351f0c19f0974324cfa28fab704b4677aa3f2bf65686c22100b74cb9ab5f7215452cbe8d6909754304573a9314b3c8362cfc34c6302b3cbd5dc482e76576fc5900b367016c03a860a88744928cae55413231ca8a5008d210cd2e317d1bb6bc8624ecb83002e66092d8aa77fa0c6766532178a8cfb532c70f1114e5156e91486c3c7658e2a22cf0a77873c944a5a4bd70ba1686146e18b328d30813c9850c3003698c5afa2082b3425c785200596592fbfd7b2ad5568f9d278fa24c523251bfc966a69ca882e707426563d2e099295305fe2e2a96f968a92e9423dc4a1f6662f68299899315a88d083bf5196f65cca4541bd4ce3526e514dccaa8ed176ba58014bd0ac486056240ce06c6c182040606dd98978d6cba367eb0ec18401ed348743780ddbd277f2ba22e1b34208f215f8f91a048ca497ec37a7663587ac85f221810e64acf87478a101062535287250907d0854b93a9d4bb39cd5788be361c00faa87bbe078b26353a51b7bdba58d17e5496efb263df826a59296a13535abd799cb931fa5886e35476dfff97e82870653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b27243c42634045506762ab1817534f419591b04622c650b828b3d4a66d9b163d09847bd172ba8ff452759184c07b11183665c0185e0a089c957135dce64bda52338b6492a27a1238aa567f017dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02901b73885557cba188f72ab5a35b489e98ab377691033934029118a34af7d176a436139aab3ac127a8f510c8719936e8676caac2211c8292a42f274c7fa85c542b21422c5790079f34a26f0678c005818bf4981a2b4c7db780c0bd43ad55c0acdf1ae0e0761d7527813076f3174a1d49c74659a453e09c2b4468de6f185d5f3c04f2b7e59e05317586e743285e6817283ca11faab44271a4667912df262c0c03843730acc24e80e2ee0251cca86a83853e6251e3036714576b1c171a112e7a15ca215f63039aaa7632ec77880b89ef8a45cb0b3746202ace1d7221fc98afb73a28a6ac2ae443f16e6072d6b3da1a3be5fac533a9175a5f176fe131f021795f8880d320c6096ab63f53525d01b32a2ca90e1a9138e4ca72502785976bee4e566dc0cc1f3827733b0a7d00cb58b6b89c5e26d2da00429a2450e269da77c46b5c954cee6bdc0339ba357a9b9951802a255b74a4f4ca1297d124056147a0f8123eb903071546d2c22723367308601a22f199f9588734fe1241450a45fd7395df965f46574a030581cc714a50c08da03a51b367b524a2ee4e56752db9b66d9c6b07702ec23bcef798d68300859383c5baca9d8f08b71409ae5552209b5237e697ba55328a1693af7fa0ba27020de2c35f643514db292c061c8e2085d06c101644c94d17c07560811c093afe61c6b4ffb970382ce9fd25f76c6728108842b3841dbbac62504185edc32dfb817c45878189a7ac02859eca77ab445797e030e910243b121a859a05d8caa3c32fa54d033714d20a771c7cca73999f6d91d4db4683a9543d3c978f1d56816d75590642cd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b8290078e2c0ac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4127a214e5532884274646b91f49a1e36a3b42cfb90b27425d2645c5acc2482289d0b4b84a6359007f23b9f528718e6c499590d6bb2a5bb674e89561ab1a48e3988927ac41d05ba143799214701b2f6d708d365be84baa60df8bf7d969a425c93452a0277f218790c80c60b4b59fc6131e7865d1135ac84a6655507c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4152c005ecc44fec299094a285ff50b09388b6ac3972911cfb8ecc9f0ea58761741ed23ce16fc02af5a341f65043f0802c0353d987c718fb72d3d922cdc861bb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd1291f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = 65caf8276607786d9560a0d97f5165b79d5e4c80e07999acacee06bb02246f54a362cde4a2e7ce7f7119e974d8c6fff713df67997041a7cfe52576028d2c90a456390f6004f6e7a5ebde39dbf7aac49faa5060dad9259525da2b466d7da1c3964e94ca16413d7a1ee28e7398b31a0595bb3f06e8eaf26c350f27d348e957bb7ab37da03c120e61be9c4a7dda41775eadc1911a31bf30bda208db0e51dedfe7ef0421f35c2be9c891da2c636eedf8f46395c1ea6d87ca96f17387e444e22a586b4e9818a6cfe7a972fa3a6acc7583be04facf1b9c76cfec8d8d9d4456227c3990ba386bc3b7f8fbdc1a492f3c1ce46424248d6da00e9ac3f868312bee1754539a44816d85d9d2b9764d992728837c0765b9d03c7e8a070de91c655bd3b2cd1268f2a310ae5ec444281e87176678c6f0194d2640459a2b9a7867bd519ae9e092b28910dc45a32190302d34dd90bd068ea9c5ae9443a990b33818beaca0b6c64fe67b847819b943046bba7af092f05170f6a87310eaae2a813ca69fbe6b20fb7d09835b2a134d29b1018d6d05d03119297fb0c53526514aa14921b6cad0b89117cb9b80ff669f635652f67b8e9b26900278ab879f2dfe736284d501b38a48286e29e43eb90f3c6162e3db81ac69722145cb93e57ab98cf7c981ffbce25923ae7c2444bba4bfc007d1f7bfb56beee3425d6420a4c6952a70f85941565c83d9175b98fffa2b44a3edfd3d9665af0ea523daf7d88c739ed491680c1fcc0467c7fb2a4626d26f970f034062acec4ae7a8ad10c3ce34d6d2658a2d3be94e97929faa3e9e76f20e8e1ac5ba996e6bd2be769213164de7fa49d04e2dd010bd56487cf5f00210ffee81030434658e0cbef81757fb3845e3ee5bb126fd6432d19861c9a59a1382a542f5607e7686262f577ee7a5fa51257c286c173e6694533dbe4710e3a9ed6516b61f572bf9a343c0790af2160c97d21510df91ebadd881a8d3b26d5449ace1aa07ad01a192504d95f4b9c352bd000313273a62d099b73d07bffa85dd4bc5ef80b715186e0de4445d30a3eb38059ccf1c3a6f1dde918bb6034bd58975bd891b96aef7f570e9b262cb3b0e9cc721c4e151c1cf055a880ae794acb5bec31b855df972c7a642c28a15339064effa3cc97a9b5136f01f1e8d10b497d4bce88ed4776c23dbd1abc690a233377b39a4559c6e19b2b008484ad5e0ed9b0d449b908e20f9b042105064fa5fc2549e680f038aa3264df28f763db9db51e5e31bf8cc057ce596e23f8dba50c35f44c50e15d08f80422530cf2dafa1e0b9d250ee61b1672f2d01f82c81e396dd1b5d8a68af3635974f0f27242be9e7573d0813e3e77e1811635c0a9341d8647894659cd00ba490a1076cf2ef0c5c605c95cf8ff51ac83a856c45a903179ca136e38425fe005bc5c74aaacfe7f10cdafc5d9690d5018703821b168cd112a45cb92197a50e2dd989744a1da2e70c05ef4c770ab75678ba64a97521a112f579f9e57aa6d966777e128b979b85248793655296fcddd9c8e0c7 +expected_result = pass +expected_shared_secret = 852ba9be42763c5a74a75778eb839a3738a8ceed1520b0588f9dccdd91907228 + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +private_key = 5b47b61ce23572623c431a498e378c6b71a5cdccb58e225310217f6f2b1b7140b97349b965d9c95332a66d7a9879f24c479851a0ea485254755db347bff9a06d00502ae3a910c06771aacc0a51add07a291496ac10e2899b6562dcda7b6b9b7eb516335d222c43498859d87a44cb8ad589a06e609fc5798ca06744051533d5c6154608c790a8abd776cbd2984b57e1cf4e0638c77915dd89249d3c0775b45cc159b44bd32f49a51a1e398763e35dbf5c6ccb100929c9b91047a1ab98a140e00f77f5076310c33179a8c80449591c4156c244eb8c8b3009328139c18f8c59e1961a2b91c840d552c2e4b3897265b16c28de6abb72d218ef713a1d179cea38561663c9bf21b68166aaa45748316877a9a5bed6f5230d3015193aa5a9e1b34dc6576b57692b543fff321b14879a24728de3d6a297c06ac6cb28ec3482da708abab28fa815272624af6e26a879f65c6432812470c52de01edce20681db43a967069dc9bb34f9c540a21b8d7322a3675fee059f5f655cfc480ba31255e899c48a7c25588303d67055434702ecca24d31a9d69796df408328912ada084ab122c6ac53c3c349c105270c9aeac73923614ea9129ce4c9fd8d78bd33045d8557ad3d0a698b34a7c073b93783670662f8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dee04497c997c9e74044230690354b7af23bd94aa02cf599554391095c0d53f5c1db19ac33189b2b9aa3c48bc4e09bcdc5029bd3b45a370c59045abcbfb257ddf30085da053056c17dd0b5ddc6494524875ac189e6c7a7cd483288f03abc155bc2022eb427b7d5093f4616c124b7c29a0043181c7bded83de7592511e3617a75652d4568d7c7b3ab2b7464c514ce6ccf54fa8d73e61834e534966620dc59196ab44b736151a27c02e065a000611542fc296a69a24989331ef980f708142d7274ea863669a52039b59d48b90bcc75ce4b434f5751cef621cf3a29873c003a57276128e70bb4aa5de581834946741a8134890491d37b6051959739fa8eb81c6947141704683124136c1c382760e13f00c59ab5bcbcef98b973831b91ba87fec02216619f012859faa6b01b1649786b626348182398226cf794095681d1c25800b18bf33cc71123898ad2aee46905a8118916ba8651328a051697f8041667789c874394e96a0efcda8998d420684217952496ae9117c6c618513c147148979f5c8bfef8c7ca1836430c3cfb66b17cbca63ed1a2157961cee600617157aad986b5021f4f69c3bee6ae181a076c3cabf076903bd59814352f4ee2c04a138ae0eb018a2193ced58981caa3bb032317499e6ec4bc5cfab8b389467ef295dbe7305bd1cd099364d7596b1801008ed734d7775c5606af0f1a2978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad10a025f46af233512b126230cf928fac14d753160bad961bdcc4d5e1b4edd241609a0adc6b3c6cc9660e5371d6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aabe0bf05f75ed0b092f332aa83808f897ba21906af25e68a88b61a357a10ece1977199203e465ef9bc020e145f6421abd11b182e7240107059c16c3eacf4a1a8342b73911db6a51d3cf12bb168229a1b29f7c334d0d1ad99932f21babfd8153bae937fdd2393d9748518f12689ca7627a1041d868094aa7440c6724b4430ebd20776b602940c9d1fcb5a109978573434da891962b645002508e46992c0c148f5a039609826baf5834ba7271c443b69dc5110c4b7089068d16202cbab2e1e4525738a19c8315fae806fd139be91f4c1e192a2c04983291340dad4018a8a83c27a57c622408f933a51b7618148b16375a80e0a901f10aaf6e7803cb2a693abcd4ca8bafb942086f42f6b743937098e3d2a607f212f766603c9d89accf7ac584491f230bb1108b1465b865f824215d79fed2525d7e95c7976946e22a9e6510afa2a9e8af29ddb65c47be8820561661050b70ef3b7bb249b7fd0cedd688c37d7a3de667626c2b389b38be066089405703bd51fa32199e9c83d5265bd62a2aa2ce521b69973a18777e32151d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64c9d00e55d814536171496037036a078d026164d7b07e3277b7ecaa770b06dd291b9ad29241c3bb43553bccf66a1dd81fe2e2bf79f1a21e1539d0bc517a9ba8ede2c39deac4cdb7c65ff96048461ba2e350017095a35c1bfa25c242b000affc8af29495a2d349133c343d680eea815cdcd89c4fc283cd5136b89abd473b4aefe2228f4cba5e0c10ec7a1083833735f081034aa7bbf20c11319ca263b52262096e505c45805e73619e2ceb242e559883d20dddd4120f0c9e49f4995376284147cc2d2a96a046bdb3f56b6dc1889976ae1ed732eba43af5941831b2202d6091c16b680001a82d98ccccec212b79b5a884756c75cb2545316fc072d903c670864d5a13534e545d836276ee594d3a7841e5f91d6b738d97e73a7274671d6470cd2719b0515fdd67c6e4969ad213254502c5ac9ba23c264a375237369b46d0c45745041a20511459d3321ee9b395978f2c575ebe1c6caed03afc7027bc457e03f527b0ccbaec71850e0955f0a2b54d9bce69b6c8fbf90850168adac411ad5c973b578424c55ce01b3ec2825b0085232469968b8a96fe7b9f26846f789323a15aae6397242a712cd26b0465bc038a4aa30dac42c0036c062c21c3a4178a0c92b8992cbd54a6044b789d943f1eabb0bb24c3d0d4c067251779374579b27c84fb435e6c745334485fba84676750a27c520f79366d008e4be93fe8a958e8d06b8ec323bfd5bd01e86b1f13302eb17aa3aa8fdb3445ae5775111b2124e2a35021c04945661b2c510a29264ad855836c7d8eabc069011f8814934bb4b32176c0b59b04c5fb6cdbc8bc41b0bcfef4423635c0c7ac43e4d5286c74920ef37c951266b92074d239b2bd0a0d6c096141fb6a718a213a3387d75b927ce176169738abe0cfa6b68d3b064157c3cb03c5793a7400c1960351b059e43a7f1b28ae5073780cc606f7e40aeb458dbe95a31c23af7e760001b0bd601647ad1805c4329e46f490575ca928fa908b5a30fd31520c61c9f1cc5ef18578b350a929164de33b008338180ce41c45327152090a91b8c9b3928c2629a48d78abd1992720e841a52ca91a15a1c7953d18b4ba1f990af34ca408ba2d449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a12fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c7262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = 9520fd68f1a0428cf46c71f124f0e6f3f21fb2d5fc390d54127819c49541346d0da18c5e2d1259564aad5a1709d33a87ac8f070e9509c6275217407bdcb1802849d2d6428878a121717b6359e8aeb075304fdafd10a6e77eed31f4dda3dcf7550abc55cdac8476eccdf9b2088559a5cf7cd00c426e9cb3a3d3d533bdac13ea257641a324719a1c92b3f27dbcef88916fe9d7e7494a3b4134d5aab08246923053b3500dcec963dee7d1e483c20224f480fe6c2606facc609e7fd47cb0d70116467153719562501afce27d9d08981254b96836690a369c9fd2cca3ab0399e8eb794295cddf714b543612303b44b6b86280feb547e36e10bbe4fd729f3a93297ad20fbd53b665c91aaa966e7b0e2e143505f4b4c930cbf0c19766e0f045fc3cb21b09df4331157a751c8daeda28a8d515ca09c53dc37bb9c1d6b99c4689316b79f4745c969f10be1f601b81b989ef3599040917d23e20df69b716794bf332e9a31690749319f08cd3de0b3fa6a820fdbede2c8af4c5d1cf5176d6b457b8f57d18821ef22d16544f4b6f3450f87a181fea90893f917f379897ea322aeac04ab1b4207fa1723517e4831ea7b2c8918040c995c3265748931bf9bad6f66a112954de7fa799b75ed1572aa999d91232c29bae2f5372dfabc7bc6d5dfcf96e02747ebf039adcca1036b4b4b13c59aa330f817c2bdfa29edb911a613f5018128f72dcdc73dfe06ead3b0bb323275e3a74ab23763992031f66f20ac134a9e5c781c5948b533b08d777b4cff4d74edaff4cb27025592a670ff2aa74332156b4917f7ec0da54d58fbc7cc63b62d3bc1aa420b80a7bc4cd22a237c797fb633ccb0efaced8bead400b623e0f99d2db72cb5f9e8d44f97470917c303f4b1543346c4482532f795202c131c9cdcae8aabd5df2f3201e9dbd247979c1ad198ffc9aa45d20d052f48d3a675fab69a6e33e1a46f50413bfb73f377e260e5b150a859ece8eccc1d208bb6f9221e145f1a071b3fef1d6c4ec186fe8eff29129a31a323e7c6769eedbbb125c57b4fb13272147f631f5089b6b49b9bbfca3c20fe7d0955b9f9e2bd717a8f14705b5785391d28064499c5c1af95fad2f57e339e14498e1b4f2c59265223e7362042ee6f51541483254c9184130e45372be466796a6349cd59a002a3f0458bc72e824917a13d32efb7dbb3898a2cb830214388db9ab1a60b299e8671d42e92b096b704246140217bf522ea5db18d65480b23cae658bdaf48117aaaf3f555aa9521174247a31847dbfa4e592046fb1f4e60606aa894b2e6a78941c34fe79bfc45143ffaa8954388140e4b369a224067450c6d6e6e39348d8a00b784188a6229e6fb983cb103a30c7c8bbdc8ca658edf638a6acf29c6df500b91ae0c9cb9d8beecd9b58ce1ac8d1ef506d1bd5961e7080e9a78d37aae5f67ff01ab1f4afa1cabe98b5fa66e8f8c6d687a271c58c6003c6e499445e4fb9c85b6dd5ab4af31a33b3fa4e76bbb29283a9bad6ab7d9d2cef241d30fc01123a3df4b47fb270c222bd5d +expected_result = pass +expected_shared_secret = 618a8496b8850609c09dd1d18798ee2bfff3ed7ef6f8b8034fffcec98f291d69 + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +private_key = 2c021f19322a908456f1677d31dc8a4a2a734a2571d19c421c47aecc507c3c53a931113290b693afd1b7ffeca87cc90b0419c48bc4359d64146d9932beec78766408f59216c692228fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c36828224c177d3a3ade3c2c20a907c830bc32906df70b021b47c38c606ef951acf7c1512ac15fc0d761c9057a7db1ac6c56198f9a8ed2f67a0f159a5ee6612109254d57745736cc3cdb634f5658fb684d805888fea8582135bd4890343a545e4e0a6f0c130b8539125ab06358f8bcc0a4b44a7a4903d018c960ca45779bb564a30cf1b340b4c317cb77da50bf899c10b4676f3c295b90e93c2540a9e17c3bde560f351c81c58b545306449585718e9199a6302e3b0ca1e737c07a4b7e21ec154604590d415f4b82778778905360cc2e49be4b08c94a744995f18959d4492f0b7a3f53a98f9a8d914863b9583d866712fe583fd2677e8a3b8ba5341902178824f4c41ba21cbf7a4b666acb413c31cfa744b9a5405efc5b53a2c64481270484134753c1b0407e23b95850a8c026843643e42b329bcbb7422df5cbb968b04f39210a4ec959e1b5c9cb32a180588b9baa690f7459b1282d9e9200bd1a0e910a3efd948c3bd0af04d866edc61c866b48d7aa22e6fb5025c6892c66116e271b998b888e0481abda592c8b36f7464704fc22c51b5ba995928fe03594a8073ad790798aa304579822255e61d11557092bc9b5bd4c94068c60b2940c180831c5167487b7538c9ab47dc268215c8c7f324563d3973fa73bbaf07c771b15070d880478d2693535425fccae0f8272cd7224f3795a70241d480425e4a74922309906e1c11c5107e9f34fac3536354100f911234d55769b763cf2408b9812aa6b7c2601161953cabf0733cd3af819f5158a136621fb159db3dc6c3f3220adb8acaa8cccb7cb2ee583b9909c903ff43612d178c568aa7e9217e345cf4daa9aaf17cca1b5a4a5a73ce9b0581e73bcc019bce2b68c8c273dfe588ba0861c5a73a6edd9bbdd66935af04e5ea81a55d62c9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddb425cb4189ed773d8adb91e2708f12b78a0105bffee30873c1b6d5d5469f6464705741ec4310a8185a1553372f6091c769109f19527e95a6802c2a49127077b21126e7531a5941298bae199309cbe00d97513bde1ac82292ca1a76957d20a306932f83994a00f21d89519e16138f0477667f338a67450e1248a682142a79d9ab6b58b88754362a32af3402d062a554ca8a40da0481ba721a9b023da71987b744c6b9ab5e80830f8b7200241007f0eb72ae3694ee92814df4b1db269f4404cd0c77a844d2b751f5a0bd1cb93d61a628098d0eebc941827f77139831575b98e47b7dc3676d887b56d0ad96bcaa1f280049776339cb3fef6489dbd26205530cb08c53fb0839b49909864ab06b2c3fe15957dda96ccda90c51904df02c6a1e5846f892a1683838b9760ab900664a1a039b6a1c75f9c4b05340ede9881f48869dc881da0191e24bb5aec448ea052e57e69edf254575fca87a1b50e6d39520630688b04328a70ca1a871ffbcb0a8823dfd4747dc859b45fc2d1bb1872a743763f12d29d937f3f2a41d257531c1172af59c90806c7e5a15972a8cb9dca049bc92700a72b4fa5a739033437c946ee062aa86c12103b557822a08084be63c4c74d1b92608c3b02c6520b2991f8499470114fb659f89a937a25897faba6c0dd142d8d4868ee3c6483128241b287cba0ae49430dd6a28d1339605a4b750e6029f73baa1fa8ce6219c36a40e5542ab45cc781a613fdf416502743df8cbb3c4b864d0b448a20c0b0942a829601f2b131fb038587a99b80ef44033061b2e4b8f9a12c3c03193506b62aa1c7ab08569c7d0a88c8a098f87061ee41000fd202e2c3af4e625b34787bce55f74aa58eeb9124de7089e51a581893354b36fe035ce5fecab74018ee6209b75fc2702429c932abf71d89b8c82c047d77725cb6ed98608f2ba0b3462c1d428352c6376f6269d9869aff4bc821870b63f2284d296677b6145683ba6282c12c72512ef015eb19ba86b3571be7438f17311655c118a530266bbc6d9d10636b6347c630607864949dabfa558522c100f6c7941a076109253b5ffd76328c99590f48b3fc7ae7a5847cc958fa5523f540ab54ea0a302174e6c401341759c121b355c9280d2ab6a84f9028634bf7e3ca90679aca188667d5086df35b88d95b262e8478561a414b627f43b0fb8731d3bda73c6396594694a9f7024cfd55d3ab88342516cb34a922e6835eb8c067bd35ce0b3711d7bad2d7529464c493adc40d8ec8679c903e8984850034ef4a828d3fabcae9474f7278cbe79c8e5c1c948b94798d4c68da8255237ad8b0b38cd4a8dfde5abf6b2cfad98a677a8c40e208206774661490c3c212d23327a46a23dd6855275b78d29830b23900b13c638e31b4745a917d4fba95a04956c371212e475271ccf94f6295346118806316ec01d08454b0cd922d6f1a3e4a651a7a931f380042a09244bb39973ec5872c28c8d41c4bcc72ca4409a363c49995c45c7909522128c03814612214a5eb01527b67bce4463202cc14e31225b36a7d7d10e26966beb389877ac0062f9172c0517ca8676f5a44a10106fe75a31a4aa86688c075918a4d8a7461dcc1ea1193913c259e3b44c2d976ec67613468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cb514bf7178e14112c8b31727a38bdd20a5ad087746768957f837179d50d25f6697f4a88d056451a593e385b74de8a01cf0244e70ac9ae36b2d76cb91e5419165c6507d141148869d6676f28645653bc78c96b9e7f382cb0c6768e2968c513c7ab076928781a6530cd3ae3286b0c681743a58d9c524be5120c880605bc139f672e30174095932a000800d58a926cf40873c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaac9f0344c9b6bbb25cb0aa084f616332197295163989e1448784082c327075dacbb7d912025e4786710b0c7452f827aceda11a73ada09c3e54b404419dbf3a8f8b6096a73528dc50fcd230155a97a614663174683d1095d97b7c0e994764df2095ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1ba061302ba9cc20cd46f769e1021c03c43ab07bab1bb0c7f3426d252a15ed5a27854ca7b177a6f79502789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e13486bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 027cf1e2d501b25ffc3a13f5a9fae7f3535a8749d0005ef28c3468d95a2931dc1d4b6908ab8a4d22012d7ae11b21d594275a9288ea7f12fd1c5a18c9bd13741ee16bf946383c8d18de5a8008d98187a7b55a42685a5a79415cc55dc2bc2b81dce12cac0494ee667b948f6bd14b8503a0bd549f54cbec3e1ff25aaaf142e03c8461f8fcfddd4b0ae1a8eae7f6eee9915df2f80c501dfbadd8911463b73d254385dd5c6bf96d3295495b27788822759e13deaf2665b6c5fe0b2d51425c447c7ca06d0d86e803194140433bd02877ca9e47c23c28133e4463fe0bb00292929bb4f7806cf8e71a0b3bab86fa386fd0611f96d6b648a30a079719a283f02116db38ba5b32778f15e9d65d11fcba269dd19f85b4de540508ebee0142a10c11bb0814e0fba0b4d0d951d0f5ea38749534f0c3b1f6d30ed9c17e13a817174844d21d399b36b71241e1b49e2ae1937bc6d1a255f61230e2aaba3432eda6da8c0e3a7906f07982c5ace4d484853c4358401745ede71fd8984acae82d098d9c72a0f8ed9ae7a0ec72d69cfcd56197f082bdcc04d3b81c2a10dab91e3a4e4c15b815d0bbc66451bdd5d7293d0f7823989f7d6e2704ecda52db3562cd2dfd139e0e30603c7f3317aa2d4131ee7bc1f9aeb697f4201505c3c102d42def728dbf05a9d55714da3ab5d4e8c0a0c77439118f804efba1a3953972a62ebf20da30ceef4dbeacf69746baf9c392ebc4d0ace031c46eb4a7fd1466ebe992d6262ed24779c21f17bb3c20b63e716ac68fc90fe5fb1ecadb031ce87f6c2d13abd5c2dabc67e726782f44498eb1dae0b601863c02f13d3ab7eae309c48369fa77a7ba1f185547ce10696da86e2668a67eb3283074c4e3b7b8fe27c6c81060353eaa860a89ab08259ee015deda20bae823e0c15a6734e835ab4e64b540963753782db41b9451083ab2ef38e675e1a792678a9b0a42bd35586576cfe78cd86450db997759dbd4f9c4989b777272ad6adaaaf4dc32199fb0798a11d08a006a47ffea9d8f9a1489562effd9741dcde99d267a40868a781ff3817080eb34bb931b1dcef5e4bdc7bf904615a2e6353e1e6ebdc37a85b9f81f72e2afe2eedf6414c07c95fdca8a4d9b58f8d4313f636c3f6c83aedb5e76c63abd838404b1f86b9ab1ecde167501e9a732ce656efd9dfd39a266f457d3a73879618c46b4c034f0d2e6e76edfd39154c65e8e601f40a5c199e802bfc96af5e557c0addcd3cecdb9e7c7d35a5c66d485b18def8a814321856019808746fa1df56994240d9f0684f6291d86971580f85f706a59c6013eb57a52da5b4d15ea564214d2106a1f5c131a6a8ad3f83f86bcf9a8623069cc8df231b7bc84147155f1f7680bdbb7e0dff61706d849aa7b89c549f04d3f5b53e6440c2ce437c65731e5d76fac50c6f310ae3734e4fa46f75af8d8aee4e25b93e84e3f7319fdd8bff9bdf3bf18ff433bd5a7af58e542bc91ff81393d04794cf85bb719c6e9397f355b201a85202de2dead155fc4ab4d01a1bb379e71c78e053f5d46 +expected_result = pass +expected_shared_secret = cbb8b7a05f48b47d163cf8c2fad32bc586f47f2c2e0911da349f29b1e3286c22 + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +private_key = 47a7741316be87861aec518a9b38146b43aa54a98f47e242866b8d79f731d98c754b572a2a9170a7eb4b0d73b38d6665d1e43af0b61ab95cb54879707805bd787913ee369d231c600b76949bf86366579ab62724caa1beabbb02fc945bf007cf57a225afa67393cc58804a15016a12dfb90d5a52be41f907b1f2c4fe93712f555b0ae896e85931020089642a23e4c38581d4c40a46aa8ddb3c26db0e29fa5f7a12b6ca32cd2ab6b50327ad0dd8139ad83dce676ab2dc0c2774c86a2c72a5fa2d4dcab588a66d6551c040e91ae045698ac0a1dfb95048c545d08654c1b560384561ab07bd8c61182f99c79a2267c961ae66434321e8501d474ad84aa71286a948c5ad187232cf72576f167d63992f62d3423ce75577c2052ef84019404b0e1706ba704fe3d116a518293112b8b80708c094bde829ac38e362a404beb67026ea6782362035cae099302c5660931ce31b93b665059633699ec44c28c2bd230b1942421f12388900081618bb29e315beeaa090a06ac7feda567fd1a12d1a41eba931c279acdb875d9ddb7cd9a6adbfb32239e843012a8cb91776775408316b056fbc42758772c1e53ec0344479c2791b837a6a34aa77710d35593a55e57572fa99711bbe5a83454bca7990e834ba285a09aa11666cb2b2f39704904354687d0524888cf6461ef302139b042540138e322453619b3dd715b617230e08c4585478f9996798e9b47c712f82ba45857551ea4c79b4a0577938666403174e84585e684783d33f3b701420f66d48473fc6bb627b399e90697e760783a3e09d6531cc524568def8507f0437314488af7376bf2a6bacf783b632197d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85afc18dc81a8611bc4adaaaaa440471b530053adb874db67102b6a64ffca8bf8487e18b2f7582b71fd78d85f819c24b892741a83e67585b6b1ae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774e805e001b44c8194660a280d0d59bfeb35ebe9c943e626b98e488f8984275401bdc4959993345c38bc801b95d56bbb47a2b23f5f1223d5a0e2a827d4578948cfc5432627c9586275679202e3c970fcc980af56757912080072a4af234dd030ec481a6ed8030921691d6126839635c6b270497ca4a87d4bef47cac60752383712636752a4aa18af13bb36ef445fe653628704e4dc2cadd62839f9842f9b2c264ab4ff648c59d15708f55ae4a396d5f4bc75d20603c03cdec4252facc579a0cbd1f64a734e8350f03aceaa2734de2b486f6b93c36ac11803e564070aba97d2309078fb43768f98ef5d03b09fa10ffbb0beb3b5fe01310065508100206a640b93de87bd94a634907730e30800803b233b95d1cc7cce49c08ab143734347f3459a5be0230f9481d50b4b835a91736d6a7b351c8082a4d080967b43b0553835bf52943a380051f48c27823c5aa0b20b7b733dcb004b2a7819beba4b3fcb1f991789c2c57ca01b50523214af309fdf421187492c411c14128744bf4a83599a30b86194473c2bc9222fb4ba34108689aa8065aa24ff3559a76f759768c81a8cc5aa2a6792f3033b2437b05068bed096475d9280bf349f6446774b30fef5b426f563962cc29ff78ade42b497dc3b970f1b848b1141d7a5f45a37c25b125aed61863f22732a06128bca08efc8cb176ab6343239b572e1c8c138d829810227afaabb81cca0a73131155377730a120558231e8f8a598a2b730578edc7800b0d6c5627530ee92930eb2b40a9888cf648263b688f0a12e08f004f4bb449a25282029cfb73c32f8d31229d0a58e6aa08698517fbc5f619837ae3331cf763631d305e88c8f85413e9d5420cc282bad24a783011184011a79a3b305db5b3032b75c55907ca5c7f839320028305c439c39484895212b1e87925999681819416dcbc7ead45ac2b1262154bce16866c04561eba2c9ec6022b07a57a67c7b901b5da3bb8025c7585c86bda0810c442c39374040236a82884199159729834663d3b1967df9955de3a387d93d50f5001924c4fe433d016bc2b6614f2d3ba72fda226864ad6ba5b8c31681dc104348ec2b29c39fc9f567cae17bdf1c6e215c92effc60e2d6a3a3106bced0bf301b542f7987b582b0780b6d398631eb8559459b1db01a0443100dcc731291c737499c2f86452394c0b6662401fb57a4db232e40d1b0f2511ee1eb15dbf7b603e2a67808c064fc5103fa7c9c954fcd12bc619582f82590b323698a328cc14acb87c217e39c309421c7e6ea15ba6c3bd8587126c5aa02c26308c9912d7262dbb91ac2c2cdbb9cb009a3ae10761771740b2e6558fae775deba7a66086859270ec07b584334900c278002d8a47d01547dba3036336616a8c12415b86a1423a6c9aab5f085c7fabb6355b3db4023e47c7917c10c284333110bc978b2c08e16512ba95a07237cc35c97bfa51bb1b25e30750e65664377ba49200aa6e935b4c7451e547859edf03bcfc6904df05220c02f5e576604a873ee82b7693b962853b5522a5b0986348da63df86a64671737c17201ed556e92acb56f065eebd31bef43ca85db1feac395e19110a2f0c5b90459838cbf779c27247709765569e5a649bf160301003169e4ac2baaa4c4697f25869ab99179f9f792d9b19df0c148df7c6b9aa20e63426697d83a6e33b35f4c7e798175bfd73ce60a050146a3d893c4dc9b2fabf5960bd80fa0679433bb33bb91915e93c1eb2aa16cb13e0b9870fef99835a674b1bb76946bc4064cafde3063498ca30aeb3983f5cdb3a6b9c4970459d969f4d8b6ba27755b6ca8fbca178dec28dfeb2ac03318be7002a9a4cd7b1749a7fc7f09a6b560740da89baab8130872510c99630f3b588069d50a9550c97f8198b7a46148fa7ac1580632db1ef49528f9125784a5bb2757235fe44e74529a7ce88e91543b2ff81d9ed78e2647aa07033cf3422d34942e7830191b104c7ed56b8951a9c8706e4cb33cb0b918387b869084386420c13b09be75d2a5e9276246b674e96bac7782541e1ca441e53ff3b9c702cb95ceab628d1617704a448ef743e8b811fe52c659cbaae22377f28646c45642a9886628c9b73c510bbfb645d4077c1d8b954bdc8b707b7f6bc4701bb1af0f28b88dd282b78b7ee96732521aa6180b6021aabb415839dc3a1f6f545c1320c58b965b62993abf6a10c18a22ce6a45539685f297b1f04a130465845d189d17552e2f4917e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = 3f6f05da5d7deeea60bb32a85c0fa85f2f6339a48eb45343e20ad802329006d35743ad24a30ea7e1688ac9870485fb2dfcec77a5dad30ba75d613ae6211674f12620b2f84e32f5bab410123f921d8967d7a1b8ff92f4d17885b2bfcac31442ea09e40a41b54588fca2cb4624663895a8e4990d121cc261d97e5211ea06e12278d550d5b0d5cb815cbe7a6b5c31cc01edca9d61917346ffa49163e363b1edb342d496dea50d463c3c330cd453b903dc4b2fa78b93e4a78fff529fd38a1b57ea5e714ff924c14d97654d390b8dfedba47034db426c371e158359c733437cfb5b0bb39b1f4b7cd3874394822b9d137359c7dea734e1bdb51e77373f7e6a37561a8051fcbde5da7f65f5a1e0dce2b1559a4a90c0d0fdfc57e11d8e8ec81cac05299b3f29bb211756e3811622b768eed23d84e20ff27a2dfc7738cac348a938c0b51f6e1340587f2ed4cd05d1ad2298dbe751863be092d8e0f9ca870cc7759f898cf2497249206b14dca4f06783d7b54d417fcb578904d87a674b82967a820e525bf1c708246565291998d83a78feb27982b3d7b9259936eb08239455fa099181df240787c3855e564ca1d53253e45d7f12230ed2d623e7dae75e53dc57c41678b63f66622f5b762abf5374a01265d82eded50bda26177a09007eb30d3ecbecdfd7d7f9ab455949426773a03f628ae86261c11e6c17b276a4fdb7745ac76c7d536ac83a7805f9aab8f86810f0250367a86ad682c070367d6ec4d11581fc9d0913daacc0053f381218f5aba830740bf531fbc9e823d71dbf1d8f3bb2f2997f8a257f02fc8b6b6d9be236e190bb0f83794824e6ac07d6727add717472a0894b27692b6070b9c4197d0af9db339b9eb13630bdc016bb43712b92e79c35f8be95d4469cccf385a15cb76a48d0597ffaa710d4fcdc62e9587eba1713afcde87efc2dc6002a2dcb4105aa473c30a827d8d4ed21bfc7da7293617029f1f0cfc0857dc11c273c86e18ff68a129a74039f717dea458e3fcde1383d70d800b3d369f20163d2eb0b3333267ca8428c8937ec809f33d3f532a6fe3054edc3e88505f6e7001247e21597927729affe877ac665a6d606c36cbe8fb737ca62e2af6f6a3cf6a1e3706e5259ba689c4931b88827250f0e1f5e5fce0e6d2f8930ea41f3a80938d9a50c2ac817302d7f60546ed233185326e8f872558ac16bdb5c16c132cc2ec05c2b2a19912ae41d900274cd8d9c52b025246fcf14ea1bc299efb10cbc74481a58a5a7a284f3357702556441de77647b29a727455f4196960a10b86e434cce0c69dcba15af5b1ed7762e7f211b34c3a9223959725e181f0a2421586c6d36fe7d31944ede70d63e2340feaa54f1983a3a37d834c2bfdb9470fb8df5c9c4ede73d1820f87961448374b19058a23970a63150b730cf6a7816c8ca21145b2cdd46ebb01a65015bdd5d982ff8e03dcc1adee845aa5bf09a590c695cd2ef7f5c1edf40f167b28a894d9c33baedad48da0afb5901a13019f72c3147269bb3f2cbf688b2dbc574ba43 +expected_result = pass +expected_shared_secret = 1eef87404f318351413d52ba8a07cfa5e72f235d6f91afd7fb8ad3e683ce0a55 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +private_key = 35e4451348cfb9a06f1836296178b6af41a1c0196f26525831c081ea779e6b8c4b3f150afe2963aa756968358bfcd47d76415ed4294f02a843f89b87d6803bad504a9165b9bedb0c946058965b64bbf953e719160b53552c100d251cc9c111837e0a7c4c043ba0777e53b39f658b41b5f8900d4721268a8ab868b15a12c3b8f41316dcbe117ab3a027b8fc2cbf3566569a130d6db132ddccc5eed69a392bae8e4a7bd6c9708a48badebaa79fa1ac1e729eee0399803a374d3733ae501f1a846cd2f5166dc31b4d53750bcccf937b1ca43c3a6cd5601eeac251f9aab8b2489e22ceff436f1142ccd1bb17dfc75db6125a1a433325a5599fd23b49bbc3d1b9195b984303735f9f2646efd050097ab23a8aa5569ab744a934c2991ba046cb012467d39c3936eba9cfec4268e1a0eea559980133b4121f9d5a603e092c199818c057b7c841a7dd00af2c0ab3637878a9ea90bf377874fa38bf290fea6131345340857a1a53d4bdd9201b99fb628d975a91001f907a2e9ad37c9b99b8af915070339fdf76125d9556b1716cb74a9f18092afd887880526fd82cb002ca49e879c50e33af2e747104674eb1f30859e3c22f3aaebfd30fd672b6ab855928c4085130488540c8cbdb832ae25249f46b7178af9769a4b359664ba48da4a746c215c58ac2752e43835b5c2a9ef0a3fca159d29038cd60cd60f5bf508521d3d59c4f083653264776501b4fc62337fc37562973a1f9bd9532b4bdb25c21597a11e17096b155cd43c76874c44f25c1aa1bbcea897367536ecf4124feb6cdf2360cd5a082ac03b5e94232dfb44e1f124fdf65a4bd03b16ed729884065d77135f1f730a7a91fc2eb43271c0b2bfb8e615c07df54041917a95b0544e8513e8c6060d14c0fb802c0f2680051341960654f3594c9972c08664b7bd30b2f031827307b95fc525a2632c2456041b1286d6f175bc0b41942e8b8be69bb364a11ab4cc199f20aeb516ced1acc1f4b2b91b860331677290c643bb9a00b4b65644592c5ca5bb19b25d2a7080cc32b08910c137946a3fab6c8e31a1e97a4735a5c0a239b073c6e056053cd6498117497870718d35235019b3ee6050dcaac31a27167fe35ce57586c364c13bcc7587ca066c6e05673e2ba0186281d94843df10bb3a93c05025c0c691a0c41b229a55b7b506724026c4f1b48313788a212b0c951783ec9447e64314e878734ab59401923ada0586225c7a5c00a5f97bb76632dec47c15c06c7c20090c790404b3044136c79f46181cb1123a7d3cf969b72f6cabe063a35774a60863267b1ba34b93a5d3db25fece84a02429a9d142ed897320bfcc114391bcc097a078b04bd9356113b3cb993c19384886df182e37ba659d5b8bee24445411e318cbd092b8f8e53c63bfa3896a2cdbdc66e27f25c83fa85c260a34fd6cfe6872172f1361aa125e6c5c6c902cdec68708c14c175e910cf002ad647a317f78f52f76bae006a3aa51780d37a00aa20c6a532281719c5ac88641a9d15549088b5a4dda23f443335abfc5c2f7c5be2a142740cbfd612a83af271af0aacb43833b56295b51a885d798825c3a2c04b399c528530ca24117b6e762c7b6527b0509b5963b68560015db4d4895fd557f7434fcb61b199e793c5e763764c48df412acb7c756e1370cd117f8c10cafb39cbf0c8c3f5dc8da1855203d02b39647856b55c38e944617b8348d16a8221962a42398fb61978f40328c83a0b49bc843060d1711e289434db4b5b0838cd87949df5ac0727d8a528b8b5bf30ccb9e37a6664050cc5880d34c13ca42c1779b8d098c5e0876627c17a79b6bad44a9a38c56883d97cf2d2b114a1c4f1a502ab4a9b7b5398d9e73e543b860f87062e27a9fd1a2035185f0d98857b0759bf1c39a41984c8c1a1a9027944417f84cca0dd4206e9133f6eb6a989075d004accd9f57cdc928cd455443f0222dcab9a8890004c2596efeb06903b5d0af33a88f14fec760fc074a3dcdc744e9864e7ebc608a56002e483e60b8202b31377dc7f5a486d5a060733fca9836aaeeae05909c6b6b0db4531271fe4f3548bd5bff1e92160321218f963081c518874c0cbb792fda4513f7902be6547745a0879ba6ccd7c0f73b123dc605bc7995bdd14b018d8278c8c3966aa87a24b4a4bd3abafe0c8173c028df14daad39c288943eac139210392bed70c38d7af7439697be96977d23a27cb6e7de7b785673c9d1b33a081a9cd417129430c6c6300c496b04e1796c9c781e4211915162de147501b7bc55f8913c66c5cbd209ba6d115f753ba739417c8eb182200113ce17c935a0622dcbc674553b9dabcda17bdbfb4865d58143c149512cc2e74a2b508f67be8058461252d95042f8b7641e1d85161521b81a616a02110d7ea3bca4723d003a4db1673d64273b34c9432ac981a0c01dc8b8c0ed5a05d20c5331831ce56014ab0732b301ca2f8569fc061ddaa95d63667b9acc7a1ea656f821d55a31b41f32dfb3b66ddd5cd2155438db6923069430b61c85ab309bf56b0ecd990427c1b7d93991e783a647b1dd66696659b5c926485e1642854f0839033138a3a54c349c138977275e71e0fe985493cb85e0923095804037462ae248780006d0778334f664262e88498fcbb22d46d4f4291bb90afbbd40fbf2b302415cf195542dcf3375e78602fe1067638ab995b70e6dbaf7b75bc11701207e489f361512b590a860401a3facc1ef1375d8b64e0e5c7f863786d3984710c2f55ecac578c41170194d832929075671b814fabf45c6e2bcdf8c0cbe2954c5a414e3f8878ab68ca13189d97f316517abb4c5187dbb03413da654e650ec1cca0bc9472bd4bcc60ca6fcdcb26e77a025eb70ec0e60e20b19d30fc261ad11d3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a0531315dec20d9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceeda5036c31a897b65612d2b176e9648352899bb2869f48b1e70c1ff04864487258526226a7dc64306b6838f4286b9a81a3193f5c9c711dfc5b9fe79bc6cc14c934591f93860b66511aab061295af186b8ceff5772fe50dffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b159a1c84c85d717824a0573cbf219fd9b2a32ab66bf8a498a04aa4e22509a5057997b74ab5a1b27b96656bc194af08114551709a41142b715c6e167e5ba5945729bfa702c236073fdddb4ceada972810253d642ec094333c028b0af40ce2e29993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611df89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = fdb35f966ebbfd16a07385adad48cfce34f8e312619d54fa614ae387f2d7c1e80f07d8233ca39dcac87d98d0b0972d96058f3d949dbdd749a759c31ad696837f7e687624d20d6a921ef055a55cfadf48a5952eb98a1d1508dfaf0c83d9623f08f7e6424a5dc45de4ffe226b3e1e5d5ee5ee53ff0a7e12a2497d5d4ca14dccfe23eb4fc26f27a62398d4f1eb268565487124306da0f7cd8a89e4746a9f42180ec5aaa8ac3d821e3f24cde824489fc38f7f26d83f1a134a19929e3ea4f3a3eb13bae2434104e115e451d7a7dd0732f57d764d7aa63399450b5e3a74bcf5cabc0b597919a1a14d6112549483e6d918ef6c0c1c8fc71ad382c63c3b81f14ce5a9c2f57ec3a3c58d643db18637a2e84c1ac4288dbde2660f34f12911000662b519e69e2aab4ff6f7093ef7330bc91b6a808487a5987389e380a2bf5149e955349e378f96eb17131d9d00b218df9f9de4a607614c614447ae1af7b7880412e686643396720978dbedcba4eab3de76233545b578ef85ceeaef3689c0f7a8e1b20c601d96ba4d9f2326f35d60a7c30b17344002cc37698fd84536fc9ed0848b12db94e17862bd2cea1fe8536211bb99bac84097d3a81661a452d05ff7be7f1a9febb4931351bd9d9515b69ce4030157ee5a468dbe9911ac26a93478225cf10d79ad86c75ab0d2c825cd43292515a317c1e9ed74bf7d51b8fc88ee3573634586569375c91731ac0e4eabbcceea2ac9efca2c8f9de612115eb02279826d0212de5fb25327084f1b07c364591e6fe8b1c647eea063dc923f2dcdda841bff87befa0feac5dae47626125989fb007f89632b87ef8318a2b0a669c554a830f29ed10cbc3820f1cd4bba6fa367ec20665858fc1033be26a443257a43329ddac6683649139b13b5a4237643eae57ff3a65dbf70377d943f9a88a8a355f32480a739d6913c0029ef691b6f9e14d8bde603b2788e9d1169086276702ad55fdc02832033c729e6ddbb142cda0fe072fd781072c954f07005189612db4ab774664793f8a00942d4d3304ef7d412f5717d476d67204a02667c3230cbee8ee41c6eec7c2d3fbc3582a7584e24b71e1e204a98c8e0073e068c6bfd607a1bf9ae1cdadd86ba48478b051411adfa3bef3dfb021f0e6acfc17a1722d0fbb802657ca3a1a3bfaad6f244b518284e2a88e7bea955e41556fc97eaec1fb6864a2f13b417984196ccd70d067b1d746d332062b2998c51f89ff9e7493b17562dace6b0f0dc521bfc2f833a405e1e5263006aecebf880dcd2cd489aec589793e4ab46681ecfdb07992f7b32973a179e7bc03ee5237eef3352489d81aec6a0fd039da71590ce193003816b04936935ef214d109c20c02acc085dfc79e4e4dd8b0640e78e8a90d45a421eee92b4ec78db88d63d3d21d5fe2d2550ed3cebcfa7a326abf3883d003b415cd3fedee17b934960bc2c2ce114a5cda73f7aa783070b7d9b04a7085c76d2862c9920e88e91c1639680db6b03b9947947136f301f4bb33048c323e061ba7948e1e058a01a9277bf6 +expected_result = pass +expected_shared_secret = ca2c0bba56645e4fce4b7e38a7bb4b839e754bf2834a302a2614377eddd6ae60 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +private_key = 03a941a829c025261f44172acf806bea5b216b58bab845328c36cb925a5169d6b1ff141ba44010ff2c1a446113c443c6d98ca879e673cccb84d5519067619edf59c23798b9b6bbcdc0d49df5f4b21563ae54e287dcccbe4c53c62918a6a213c460eb8c92377cb57a1b6d6467d40297fb90c6907b6be5b03db314c3ad5b2f46999743ec7ff0b055af2b2753695395c6157c60115e183dda398d136806b7017bb4fb4f36b7653bd17cabd1bffeecbaf2eab65b853c710820818b05afb86388f327fea6c3562a027c610afd9c0bbb23a571489120c2baa0d7aeffd196b2dc8b40d4016fda16062512a64462fe806d5959c49dfc0c9b2955e6480b7af0011edb2d44c6a43d08b5f469656cb9396c9c640bb077cc24ac0f293bab4cbadd998ecdba31534408b74420cb432826cb5dc8224c48159626053096063841153f723761f83315629c945778a24f826a28a90a5854ba7e80c48e44929eeca17e28304babcd0af4198962a045292f09ab5b7197a685a67d07ec9769b69e64ea1457fb8e1a70b23ac4a797132b021244944143e936c6e5d840494b674fdc9aee84a091175f8e3121150b1375e028d0ab6b709a443f14c56ab67e3a8721a4b698eac9615fa12c0e5277e4a412508446ed4999687ac5ac626ccf5468f3e944b8d099fdc319337c85e5024a0798556cfabfd47a40146691d32c0f179b5bb3c3088f2cb29e2b961b630610d1528fab952dc75d23339c26a38f68421c12c2360f369abce128cd64551ca29455e02aec7c359cf9182f5642f1bab42814aea8f2844af15670421e0e113063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a6e070fb665756f98156c65a6f407e1014bd6540a92e8a09ef6c944db876250b951d16332251c5bb6b79f88928adf6bef819a241068b08337136b8bdc33476fddb0292b68ede75490db193e267bbf2f8459fabb17d10bef7018ae895995200453065ad45457e3e86a12c554db3617a99613767598031c86bd5815585444dfa41cbe068034fc0a1cc2636d010230870776d2645db640b409a292acc909aaa11d0d05a1b1469ea2673020bb7ebc7381190c271e2cf73d37f61f12c8389843b0540117c7ab924c140d1409f701ab0c0596103a1aef3c93a2a79be19c7870abe83232a7de265a1a1280d30490ff50c414a006d8a403c50948da4b1054b18be35a8f9252079c5acb2104bd42ccb51617839e07380fb3a62b3a5080295bcca410215ab5c30a89b727363185363027bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bb718dd7facf5f120303ea259fb2bc32a5269ab45e6bd8ab9f9456a68b869a4c13a0b6c98dd1bf276572efc9a31591acb33b9945919fd20495db284bd4ba7c66620754e58396c0a191f20304b545aa2279cbe62d08eb4c82e60569598147f9910ef70abf792d375420bb999e4a9cc28db0193a124d0cc78807a54d13933b25b350a16c842e4b31337bc7734104fe564c20f27ed6ab800717baac4a9c954c6ec5238bcdf309c6fc497a6a9b9e4973d7d44ea53b90db26912ac7796c327d24d3705db5bd0266b17b145fd8ca77624c8eccac1c209073b2a639d5f135d06aa99635c9b53244e1f898d8494b681312bfd243c8ea5b7e71ccb7a5386e477d01fca3ef4122a63934843450a446caff55184d052923a393fd887df6b045659cc282d1424b19b17cc2a2384132eff067a0347f88c6b392aa56a3519a440438d3f90f6941112124c91fc31187ab0ce6752d9b336a1e230f97837a657599e253b7798c912a66a48314447c352b84590941355c6bd1c0951374105858a46502ef39cbb58b8e63a64e2b99c4825912155695893a62af6745e76058d551a946161f25f1b8fc045602344a7f342facc50e9565c1d59a459d34233c1921ceac6e0bd936b496c8fd6a619d8b0649eb458f8943eac97293635092666688db559d255ce9f280227755c3605d6ed007ca718527227fa1f40dbcd88792801d8db6b2374a23178a72276c790f902d7e969f2686c9508186788905e77132dd909397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca64918370809d3b1b70cb09641878e7c0a141573030aa2b687761bf43ac89a81e73376793ecb32db53368ec9e079172e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca582017892a188fb2440ca7240c3c22577230b59ab8ec038bb95cc49c2a2f59a4a22c0c482713544fbca9d7404b3a6ad86e8764a601b7084289858bf62a2828d3091ff015089726ca23b1ca0f87195ba1abf80b01f101f8584c15289196744500000b431a60267174f2cc56860bc5ab4ec20d19ba8ed47535eb42fe1d33f2980ba211805a3618f2ff64d1cc634caa6b40fd23615538366dbaf41971d8b5857298c1e406a293c1b8b7f4a499a97be8cc51b5382020ea9c7cf809fa7323134290fa461218f4a6f495caba2d1511ea48b7e0905b0465f7a6711f2716b17dcbb4b9a1b31933d7d3622315c79f3f11a93c8058fbc01c4839a808a5d2d45b99f7918faf52db1d81d669c7988ba7eb8847187ac7b76404b1a139dc4e4917c9b4e29833fd9fbc36e4bba96e25bde691ce0c369ace7183c762bd04785efcc6b614165c014a0fc4b64b24b3b46418ac5b6b7bf69cbc75090b69aae46b4a12feabd4e134bcaf14922367b50f17976c6705e175ff34612cf7b086ed733deaab0ca815a53c99b2985963db89bdc284d251340b0e3ae20990ee93344dea18063db6ef4374a331244ede00b46676475937a9472c82e124b1751a9e4203becc77ace092b055abf0892637b39c3a9a011219c88139277b8bb73b9508142421939380acfc2b81523c72e923609a0505e2979e086ab85f9663e549f3350a694458ce7b02bd8716c0f8b8946a21d99d97632952bee898989c1adeb710e15bb25b0a22be598a65465bf2b899719d00f9d16367e9436803ba8c17b6b3bf62a10a017c177125396bf6745163fe24c455319cea69393ccbae42508156167b28a1d1050bdefa5a789bc389031bd86e72af5f5bc80a215260737839654998295d5aba8c11a5417b55d67201243393b7593400d46cca1d321c027bfb09cb08a1738c88b7d47e876ef7517f8d96cc1c93b9e93b7062227a55996fa958a684aaeda89587b015a6b336dfb610721298ac6ab713f3a2e37b2aa7b1ccd2a876f03c72546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585ecd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 2726c88c44097de218b782b16c655fc658d29386b80ccc0168220bfeb554b12a3ec13ade45147b3b68cf67384840e1b011b86808e2b922f7b9e0db40b5ebf11ee131a1b4c10a2d350c1cdce92b330de7f838e29062bb243e25f2f62422ff334f7ecb5863419b44024039d1f900d3a21f5f48bb78f066aa726e070711973c1f8de28efd8d71e0cb5ee72a9d675974c02286b56029dbba45e064bb68db2e25131243d9cdab71d2dc8b56263a6fe2b2d6bedf4cdbea2572e333c4b062c91622ee60d1e506384e17a10d08d61cacd407ec924944e9690a81d1f7f989cd58c243607c4cff68058ac8c970376585666d146bfe8816fdd0d20e13bdc0afd88ccc1282a17827adfa9c927c55ddb520c248216378b68908155a718f335c39d0504bfac4a069aaf2c64b8cd935d5494e31a399257997fa8df3c4237e4209deb9da336d4cbb116c531a8cef2f0be5184dd08668630632d030831dc13652370f0d7b54aba8b122f968b2e00af4a5d9c1790554b9077b2fec861ce9e8dc89eb21c23ccb68e9080c2cc0ad9dd4c3364183a164e9f57401653cbf95d0a58d289f481a38b8b13cef56926612848fad81e5f2a1468808ff45bef6de82c121a8d3e956710b5a0a37cde624d1aff6efefda13341a7cf6d1518b633f65fcf0b3b91c06769f307f94347c7e1efcc80e02e823dadbe0ffe2cb7f3bfbf3a60e8dd31506304155467d28b12740ad712177227b4468d5f4bd305ddd6341ba68ceaf4d4fade19fdadaa3db805d37671f1cac1c57882bd710b2a7545594320114ecafd0fda32fd9e06f7cf2f08ef27de1ea119239411a10598bef458b8f3604ba82afefbcfb7b6c92cd65e92e7518f506c684b08d156032fd00c3803cdecdb92351ad7a3b7768159deb534a24c9642684389399205a8b69f52e460be217ae7b5b08e8c1360b6ddd6ff35462d9066618ca07836a136d044794954e3812e29ed9b200d250f3dff0672aae2509b4f32cbd580631627085147c5fd76fabf284b88a836fc4a48911a892f03a92a4a497d62dfda5b71acf4dc4976c7670c88993a23b1bb0c21f6cef59b0ffa88c4c50393355a72299cdb456a592deb3f749e1341826b3e89c4138badfa1503041e50c70f8236ec881b08bba64c46d611e160cc9765c512574d875b50a5781a7871a6b4bdd02cb344a586bc1653ca974adb1175519a0371695d2490a54b2ac21d53916d584f597f7e861a051f93b64d5219339ec403d7d537271d5d9928e1530a6c6d0fe8e1055ce1eb70e5c929afdfd591cd8f9942b6fe252fc98801dc4ba50b9a9810819b1b245ca74a6d8238a4bb7a64cc6f3c7c4541779ccd0f8509d9202a88af0ab2552417b13c075e1c609af2281740847648719ed72e7695af239e0c288bd630c72d5957632c76e89b0c5dbbe74ced4a1536b1e7fbb2b7e6edf8feec8223428616ea5f967ed05eb2254598f3572e2627b6035025404911ce26378e8df914b06c6415e528f9e2901a90992a5eeb0a2326c8076ca8da8a80931b222b809bf62e3a5 +expected_result = pass +expected_shared_secret = 9155619e28de6cc0670ce70e0ad270f0e885e5f5f8d6d38426938ae1036d6ffa + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +private_key = c842401604c8c4c78d8417c804c2723b14733044aa2755897f65987951218361a07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bc306f851c9e93ac266e3c9e9c939be422b07e512d28503a6efa9d3ea8861e39b1ad481b8ad1805a8c0d48179aa1203c2ed7bb59d5c8ef651281c77f83ac7b49eb997965b161db025b47ce6e2c09edd41f5eab1c8b7b4d20783d60c90dbfe6ac387b629be10351868186f6a0bf68905f8c1cf34303fb577c25212919533c7044697d9425bfb76bd9d367f43b2d3613351d95395f4c2bae63b2a4608c69364f41e85d542a08f35b940fbc3b48f63360b50aa88259c7cb4634e5a34300c5957a3644f6ae381389b53210110329fc61519113c17e64782239941cfbb11a647b814372e313205844592cc3c17319b41ff21a0bda3f5acac3f18bad085c8f27b7758b7519316653ba9c253dc94ccad37f98d00b9fe67e2a13662c77921e4a9a86c8089682811e53a60b1089a1038483e615e6eb109a3b7636e02a44c2c3a81b96d84336cf594d24172be1bbb9c7b3685ea45e45b81d731b9b75ccadbfdb768119b20a0c346156cbcd5bb107a00a0e3c6e949b9db0b4ae21026c915908c5f38413c648edb20623f35b382b0cd5f4a8d7062bebbbcc9e809bdbb5c84042bce2e81bb0d795c6786af95a7e7b0629f7978a03558f98709a86319570273bea71986aa92560260d022569d4c98a85bb98aa198deff63dc6bccd1e6032ebab8caee5cf4717b17d89125c67a8a472c371153a4fc9045fd3304a74b983936060f42c80454a005342c1318a284bc5b9a71a39e748a94739536b517dac1619c00db64c81001acbc2793f9f29b42214442fba962f331d48c300da2186d21a4de61c4b5948c7edd1b9fa5865caf2280a81b9f7171137d6a678c92745b1aeb9db686ba84d65f6beabe332ff036bd113161fa068e74032ca5736d3ea3a01f1acfe067dfe5a5b398575bb9b148ee6155be2b4b67b348420ce758c5855102fd06a1fe8d347ef1b073f064f1f7926be5b2343029e5b7468e93b8abec6be231b6bee714031e04ed23c6da37032ecc00374706eff7453dd931d80029382f17e82a85ad7a8b25ea97d1d2aa21238b25517008b0400281168328b02869889f7f142cbf1ae8ddba5ef2713de649aa9ac56229494db211b90b96ae3b2829ae528c634110a3bcd355a243f3654295b0b79b9b7d43272321959b3632313aac107c8b7aeb83172778b7b199e736307fdf5ac6aeb40cfe750b7227f46a00b9000880d405877b63ff6c616bf4a51ca11c863a79b0e099308b42cbb7997420008268a3b762b9a5e181da14a4a92a5b55e7950268a9a83402889a98835cb9562a5a627750a5348b3398b39783009a081a058bbabcc7740af00b8cdbb4e0842c7f14b47ff4cb424b6252ccccee30398023a9b50b4bb4a2c1ff0a007a0a54eaf421fc2113f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c3420bca7c865aa22461b3d95522e9792b37b78c5555a62a3439f3ba7646076111336079bb8352a286e542094bb58b07cb832e2b288021034ed4934469b1723e57e57e358942730196140f47658258a761edcbdc046c08bb89726ab73a3355199a1833a1268a37a087ddb57ab621046db1f407c804c488e4196048ceb762b9024c2157e7dccaa1a762881280715a1467e766dccb159f4780a39bc4f4a59715700070318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa913052119904745ec68cf3502f4663bda74522ddd61a318539e10a853bc90a5b06aa12018c6bac4a8123719c567719cb723b420540ebcd84c2787f37a76c6c40fc983436c26f7fdb14df17062be752af2c1f1cd1026856500f3831cca75eff7a08d4d9c819d295674550c1c951ff9a0155856c3cc143824556c09025d55b0db7192d969926c18912bf5ca8629401b8c53e23832cefdb369020583b360595541f48573ba1557fd0c1058a8cc5ea7ca7f092b7dc7b4b04490fa4e72a37aac0e33b1746aca327258d9d29acf140c5f70b8f94a23195d60d30a498259c6f9d06bd69f82398953b4fd39adeca972851431b59c9614b7867cb1228e2519ac130f003903d801f70bccd776a9b916684cd89cd71723ca732a21fecbb90d547646b987155cf5425abbb2406cdc1821afa8da120a540d1c3af175032444e1fd85f43f47903665be922636755b5e75a90931c66e89345f57ca4a032959bdb4521cb62bb1377dc5c99fbe36c71347b81a80b6b7251fac3732475009a719f4374bd5ff01cce4601e761a754e05756968f33fcac4d6a540d93951d0bb4d0d838a3112872020c2dc67718888dbf408941b877eb6543432675c879aa85f102e608aedf267e32d333ca9c3860f907f17b553580aec75902ec304e6c7996ee34061b40a9f4f8ba2ccc55775490dc9c2a6d5c0134e809bd305d7445c9ebf7b89f9604146b2e55a1090597033bab2a25a3886dc524f4908adbe98dc2d74386806ad641712d9c23a19562e4ac7f57a86fc98663e455bd963c4e63d8471b504c14eb718d8bcd6475cc45687f55099f8fe2035f3812f081b6df2a174999765cd69433e5312be67698346fa1030a40943f8927b2cd8a1e2cf2514333bce85a89a6a99d03c4a5c0b847550972f9d1448d1819b3582b99a50ff97c124398cff30967013c4dc4d374379b4e8b037eb0e570aec147a1c99cadbb651bfb576ad61bc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a192211b4d6918260c1251eaa1014c6f41427465609310d8b665c6763639c71ad48019905cc0874be438023936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953778124c2c92d29cbfedc21678e54861eca5cd350fa09b1365fb74435316f37386b9b510e2bc585da30a71ecc7b9913921ec8d8fba2dbc97807b693b1e306832507cac90410e0576611ba79c1ca9c0b106d0147680790ec5051798592d3035aef57a0174cbc70b435710c51695852841907d41a8180123a4d911787b674acb513c84047bbd5851c3e83a8a046062c06bd84397858241c95b8d8d2a2c53038856247506065a70a5a29b701bae1b488a68c2bf02472d86bcbfe263e7820902102c612747cd60344957a871c7774a0980b70b56f7bc45f8e2bd2085af080cb923b55640bab2aa2c30f206ccbad17bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = 0a307d1a8a695cbb2a421d2c316ba05165535ccd1cc9ddb641b9edc8dacfd10d001d7dc8166a7e405f6251abaac6d5f466438f4a2240557bd7cd6ef811d4e1334b76274dee6c34b79979e02db09a682b3f965d6356e9fe640643b03c9d3cc37af284ff51f1ac542060c0377df1bf3f577d387c8a5adb0b0a615e9d93c7b54a6c7e3593ac118fdd7cd1985414fdfcaaf20b5ebe647a7de9aae9b43f0e1836493fba2aedc459aec78bf697469daa96819fa276113504ea82d956255e0de55f8c6268881e2795527889278ee674580866739fe66b66e94ab71de0f7637214c2e804bfd8414ffd95a5aa0d1f694760169455a5d47bad6d68f277279527e8d2e6e95051c6c92fefea4e07610abfa63ae90fc38d3b819df566ff44379354bc4479007adb0fcc603a346debe6a2bf14afd1da6e6c04b1483637f0814b5bd5f92984ed8f895c35c9f7f2fb5032614e52ab183639e6caad3796b9ffead73a9822a23e997e0c99acd309d93d227b9bf1297edda5a443e4b01a0f67e5a25b2f395635a1fa9d25241649767baae14de7a4bf3d5cc8d7360460ff85ff0cdc646a4a2f8b5d1edd9e88e353f4771b2395095026b79daa65e25bf9c4d19761f3e9bb955dcc6f2f288b1537b263a026b7067a309b08130438db1c6790835695987b705520a215118b20e636145264e37a1577c7466de14c26e4c372b33059bbc913a559880e31820fd0be232eb7d289f5d6e9abeebd9018fa4247acc708f602b1e8692ad10b0dc6499f0293d1b0624ee40d7f13b235210087be1a8e2c709b88f6460db6135ccda532f8061772a5767501750e58ced64397bd0f7a280558e86d7fe81d34a24d5736e4e65e118c7296b020c55af0887743bd53e2a60f809a024c68bd1324f833e8e1d505080fec99b3e2098df4e844341f7becebd889c15706d7dde9dc754b6393da40167a2f00209eaf0583ae4ef4048dd026ccdc2884f17238207afb355a419f3666f80d963f338548b6fad3c9b4a569a964691f8cd20a1abb3e01fc5744aa4db5ba0594cf863f566e7b3eb401e62e05a84b30054b7798d5b81bf994a4fdd3a876b46898820fa4480dd9a1a5ca970b459a4366e5097b6d792ca598ba6785b0e3328aea07f594706af89d88727a0fd7a5d16604766aa73c21081303bd676ccbe0ab287f2ae1ae235fad0a3d2346df4da3cae145a0d2b7f2a70dbe3cc70304ce49e528e1ca56fdf81f33267402d271203b8990773a1fa03f18380efc7dab62ca34e28d5db918dd6365c2d79ecd5d70c95a395211afca1a0542201e731e61c1dbd31316dbc41ded48e70ef47e4fbbab6bab47a56dbdf58c5d741008c74823561937fecba694bd31538064bf242eb926875b094d0282a9583886bee06c948496c24d563210cd96579dee6de96d29066ad4e1f9d1ef1ed463f7c9d21bac44c9cf303922fff1337fbfc5b9559736801f80974dda71ca185baf31f4e0e2936b4d3ba6f85539816b69a8d433d84a7a88d2c3abacc5d4838fd3c2952f293a0adfead7b2829e4d +expected_result = pass +expected_shared_secret = d1f24383d5b8d0c3c0a6a5f8f7d38ccce13ec179a84b0b09bcda4c9988f3eb4e + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +private_key = 0c9c633ff39d1c6c29f8356aa02981dcf189d6535e2ac00750c30b111a88b21024e4823e7d543614f30112f7c78f1679dab68b71aa992538658fd0c8e2984abdc09647453b3fd99dd860238cf40c9112a7dcb57e06540148ea4ad6f97020474afb65c5c67ab4fdb1515c6592941b1e38d4097155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b470ca3fea3314b4bb404cb66e3bbf8f2953f2682cdb65cfb47906b3962443775796564d75cbb4b9bb24a8a98d7723269e8204ba89782f974ae591808e97cb2468252c8539c2454041c9232f33b43ed8359dd6856c98ba4fc09e92f9a4ad497f8f1159e159b5af795ab09c20aa753931f47764b6cbab6968c7a779802b469abb1e7f677a0a485ff5cab2f028112ee8c35152703bb14127b33fb00a0ce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78557b1d31686c6b4c3749958efc60891f12c9e0b7c19613823eeab1d8f672089339e46c16daf0c3b7d53727605c26a723518a2651d8762ac373817bbddbec1ebca2cf91fa2a66896c55a4c946a791e5502ff19aa21cb132322bbfd127c10d87563028bc49b222e5401acdc81991828e4c111a54566e5724b40a452c0f4632b7b85f0445c881938134d516113560b0065beb409fceb25f796c0ba0ab190fac0214007916ca93c2abb11bd88553aa34c3c518bfec423728c86e529c300a1f70225f2f683911040ff9405614e1baac070e0e90337e134e3c93081514a937f9798ea7b57b3a3a0b829a2697b0778c802116c067a5c368576395c43d33882f97c770519c16426284e19bac180a2a6cb85d65b1a115316b08541dc231c123c184e82c691f20749a4b92f2d1040d09519df7678ac282fff9cf5124acbe04388ccab61bf71b87ab3b830a3ef6700a68b06770012424031e89a895ae81c8aca9169d6495cf01cd8ba0c27ae132c16aab0ebc4b13abb37d67ced10a0246e87be1233ff09a6802f6371858972d21b48d410d8cf3a8a1e664f62028cf851a134037142c20e8eaad7de32581b39b5d93221cf72124a73daa2b61f3d7c8f25a973a815b351206800bbcba60ac8c2a86a7758b38339751c23ea5523d84ec982a260256c69af739349d206ce9c9a70dbb0a950a0b63815994a6878711578bc22942914df8489ec5a09258eba796e8a6ff5483a71887e55783a94201e5b88898870e67d32eaab132519624f4b28f22e80903e591331ca792c0cef824bc62168be6eb8f7ba299bc519b0c370509e38377f171761521f8fc882d1b8d0db3c2109a43d1754f75529f7b071b7492b753688feef12fda217ccba484ab79192b7933781811986430bcc010b50a5621ec15dc7bb545cabc77c336892a0df4436e732b905d70769865cdee0a9906438e9d921f521862a3227bab93202da0cd19f6221bb68fda8155ae38132cf2a30a4a5c3dc0b17df0016fac3bdd56cd9d06cc8f2c6b4ac41207fc1aead0cd87506caf5c043941513f0a4abf725818c7686f0745ece93c23f2951ee263f51a3fb3630076dca4ea80a156dc6b4248246f638024b8782c9757e076ceaf18cc27284c321ba91766454640ad32d97e65650b39c9b23fa80405f8cec82abf70ea4fbac16e6e3c5e5d9c8ca207a5c77c7883b917fe0463d3101962b802549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a6204903b9bc9311c66b907c5825621b7ebfb52f6c7cf75c169c17129595631a2fa95920317aad4cb338329adc69c6795158558638c474710c78763e012240cbdc2e586adf93c028522321a94cb766f9e983fb5110a10476ecba92fc0c120cc83632409940db249ec569ed5740471c86623b06962910307781349f342c759886f7c376ce708091019fc407eeae76409387d151c97cf7270319143471a84994bb596f9b5e1a78d33428740fcbab415c575e478db4b4e30771802e409b8c1ad4ecc9cec1b7396e664645cce83a40d512684e0b2750d8445d2180be5b4cfc09bc9fffc8d6e49b49d68c4d849b584512cbb55283722ced5566149811545609a4c5459f523c1c76667859760e690385f65768331b7654c30b8c0b26f2b8089a3c5b4f21eed42179c54ae61d22736512fa3aac6eb018946a47cd79acd545719c829b304477541ea92b10a1ccae8b36ba83d5ad83083fcb51df653ce899227c52581699b7150456cfa1910212f7678056a33755ddc7d0648164aa297f196057060009dea8d87e86b6abc0106a5536d7c83933ab12e294b4f50870fa0bea16ab49b88a60ba7790549ccc0e6571e81875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a5e295e3c3231f4132e1117b835529456a53d3d748c16280f4d597573685b04780f611094c665c66164a1323c290ba8c8b1031b142a3b53062ad5c59d8d112f9926e5aa591aba711ee2ba1509aa09b86c60a969020d74e238b849374bcae7788fae61296d5ac7ad0927ee30912c4287e3981b7851d5823295076365196bfbee4a3cc189020254f31b06fd8d70c43a94cf380c01936465a334fa59b3d39296305dc8b775269ee204639bb3a30ac437936cbd734a5c6477b2a451eaa0159e571bb12473b77698621d5247eb5012f608c6f070a67551f6f63abe87ba12a56b2b2dba44bf72e01c9a2c490579d2c103ce91a841c4f4b3aafddaa0cc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d1421aa91216bbf56bcecb89f11588b4085a62ba0a47ef9a184c2c9346525ce006ca4819857fac8b1498c9ca1222175ca5b01b6bd502f69f8977a0b3b04987a1897a8f2f20dcddb098ad070d15c15c099a5672c17087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c85971fa10d465970d61446f106cca6200f85eb2de2947bb4ec57e58c1f7be6b6fbc025a4a41eb05c516578ae9ba4c197b692d20976116ba35660cc5b612b616269a837012230b65f2913e5d0362d0b510f1272716a4dd2832d3bacc914929ff33354c01217d8a0745c9263b5d80a4f497d99d98a4d895b59a59a1dc173ca6945fa54c398f351c8c3ab8d66cb8971a68157ce3ce82104094fc83c7306d242f1f0497180842beb8e126988c5a830d2a39c2711b033490fe1d53e432c7a453b4ceb05a5644253797135231228f246bc6a1445efc16b2f2bc674327a62ec32dbc209f2c4a5c600920d2856dc34549bc4656f7953e697cea6f2891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = 39acb3d169060aa5a9a7aa6d76e53f8e4cd790e536b1947c3f0e5c084348c8f3f5712ad3ddf33d798b7522fa7e8f570108897391abd2c0ef86e04823b115adc2f106ca8239a4f8a52d38653c256262aee0b5560b9f74e285ae1c190d2ce0e0eb65668087b98ebc9eaf32db83fbc09b83410dab78038cfe192ae229ce2bc82fed7d653ca71fef58d6f3ea9acac45967d09478080760dfeebf095d0bdf723836903b8fde5b3e74cf57a1edc1d178bc29c6cab5c4381bfb591952bfc70444951193c3bb0fb8645c7d9eab913d64cfdb76e1a2f02bd7f9c98c8042146c5428d641a79046d92aa6f926d4409f62ba47f73255ca57a781cc01f2a6c1c5bcfa890ff164910e4780b322c4f2a0ecd2fd2f8fc7a2870fa3c636afb0910d25b4c56e060bb22e969a37bcdc29f3a3de70bdca6a59d803f59a942694db2cbf73de3a787ea166a1c111556c1866468898539a7f36f2ed7d15324b76879af9b9b70bf99546345e0ec17fe6f1311e9f438dd92cbca8a02d7c3778f5b88f9191ad12395ffdba04509f3f338b0494ace5d52b1e8e3534b901fda4001d493f9b83f89a30ec57a5aaf4d5102b82b0451566634ba68e1f7e93cec122e7ab4f250bc78b6df0a9b7d84a4de5fb51e1b7381497ddf72ecb010832b5e0dbd34e41e1189744174dc01a7ff3eafcd717dc2cb56cc145b6a8dfcd404b748a1dd9cae69b1f3db48e414584d1cb902904b7652512a9f191dd7a95ec60d1387e1bc4b6943c7a6bda205343e2e67583dc06c72495722a678ae50ef4a8eb0caacf9a41dc13a56c5dc3e2d0b98d2804fdf7a43d0fa2d20722405bc002d71432424c88ea9dbdac6e8dcc81e660e85e4c650a90c7e6d0c50e5e14a2919b399b1838bbd7543bb95275e341ce086eb85eba4dff4c9d3aecc99829efdd0d68514fc304e5e2529d04c9fbf79897620d9307605bc566fc6ae6f176a25ba26859097a241974cdec07837a0c1cb86e00fc8f8a4365a7c348379eb60f12e0b1253f297fabf6e6b38c9cb226f14a4ca9dbcb1120969fd56c2ab38dd075351d33f853ca3c24f4afd756370b0ea4dba295652354b89d004854cd89f57cd583b7a7a415e48e4a5e38941dbcb1c0e5d55c479a871b8eec04e4d5a73c93ad1a7183093c28589612c6a4041d98809db41238efab617150bd9f9b51a279682ae75fe7a057cee50f9a98d6abb1c7efdc2a0b1c0bbede9e1d19a2762047ecd4f37416a3f86dafa241e078b3defcc414afe25cebda4008af5a356d10ff83dbcb6ca1e71268f60524849dac904d7c0e638fa3a0716141bb8f5c019228c930cac73143953e4cc86c554ee7a700bf5aeae2c8e872da8fe7c6f27d901bb74d87e1f1626fb53ee3bb080c21fcc41f828032214a738e28a51cd5085d0f5a0b15629268461561ed7caffab7f22c2d00a2fc9276bb80e9964d0bad8a5ce2b627479439a80587b9e22e0b579c59b59ace59510c206653842b2a4a75d38f2c7984503ca35a62952afbbe25049ce84f5eed70686848790a96f42a3e3572f130b2 +expected_result = pass +expected_shared_secret = d2dab0b39b7f62de3ca9826f9dd15a4201191a0e0c690d3e52b305a9d3af2d0f + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +private_key = 2ecb7caa911a2f615a13cb82e5a8be85e1c2bcf06c71b9696682532639b57a91537e470e8514390949cfadc80b0e5c3ee3eca869e22250560d8896b5f6eb0fc6ec0a6d01760c9108b7a26cd79039bcb3cf9ea0432fe0581626cfedabc12f758b407c8e9dfa373f45c377fa6d41a7205a7322b737cdabc8114df437e864c4abbb3dd084964f971b36e24406a7a7544a260d917c0ef95ccf33b1833bb6d4232bfce37b96004ed7779258faaedd9abaeb5051d8f605eb85be0f9599ff28b40587488fa376729685a8336c0dd213f55447e2c4895111b98e73bd783b2d08960abce22f6f894ae5456577a81156c66f6f1bbebd9c04d1ac43b77936f13060d3305a3893a825781e47928fc492adc16b31b2669882fca10581603b400f297b7fe7525d20e82958099b2d118ed3a14a8a915731525c470b7852a9b0ef04b4a3b0b65b4c5d7d486366175540a91e752993ba979d8a446f94088c7c3a02fd5c051f900a141957e63cbd71aa012db60a02b3872f3a623218a6b1f628fe8580e8725d9fb647f128c2519a8a0cd0649671616b462b83904ce621c95ff44697ca71ce930eaf0b28a6448a1c6b38c14800427683b71c954e49b6a3b978417b78ddb1a1b9729b89160b4c7ba49f312e23632460913d82d655d6e00b5b17a635827d8a0781e12a68c536ab40909f46a7173fa9cc9990371dcbc0b8a433436133ac123a73664a14e1409b4476ab001c17f26ebe968ed8c6a9d491b92f234499435e2df615c849be5f6422c8bc9de8f148a7c0713d93642dc852b33652287010f02b1d7b77972c797add3a38651b4c11ea968ce53f10d38df4160101fb0ee557bcf5b3328e12150a7c0d769812abf2ad2c1c7661844e6b34b25e7a30ec64b6e7d4282f48344bfc6f33ab3c428c76705cb9b1e9637721c9ee60874017013374082892b4af174749041c606b3f6690146bf1b0c8d2844f80594f265a8fb639e209c9b7fc418a230aaf340bba34c1c66b7d570918ed6caf8f62768620058cc7cb4fe1c762aa96a5015b82216e204c5821022caa84af9b12b9c9bc683747a2724c88e650539779742edca6a6a6c5f5d68faaf73d4cc7aab9b105f3a1b46cc96c915912e807aa6c841f6be63812062ed1d07bc9164eccec7e6662056313cc32f63c6181cf3343adc9073888d5756f508d65025bf6490a5f6b164a942466e60c4410c72aa69d2ca10459b890a4cb22a7613d44e70ac96aca21169f932a6134d27a6c05582e830c0ba137df060c6249b360831cc6b993e3d455c2e61694b11b520c64078bb552a65a3bab407d46c0ee173bbb52a95c7cbd8612380fc0cf1655c8e691bb0493103ec80a5fc92b4951a0d78768504284ad52580f16247b3c44af0a397f28ce3d0c0e4d34cc48b26b3998b060f2a9a013889685446b6281b3341c08e8300a013390a881a3a4937b412bf4745b069acbf5315b9955aa4999ba827bccbbf776829291a9067272059104522d69d1834886bde76c078a6061305833fefa710ebbc0dd0729493a285acbcf2708cf93ecc76b85691e20bfa4379c8521420c231f68429bb5c76e69378f6ef3475fca5760a5be829c2b4fa955e0e0931423b0a615194c26225bc538e2db29b873b2397a7c7ada2f4b0b589ebc97c50174e4317ed5d9cf2878c924937bd258bacbfc83283a218d443d8ee43f8cf3c64459b189e6b3ad100a6c6a3ede9916f89b8bb67cac332c0519f502a4c427f5c9af1a16a59a2122521a0c624a20149765e986339ed63567cc29cff15d7e8ac026c96f08d6ac4e057db4e66361b18ccdc3bcffc300a996ab7346232db7310662c75b39ad7aa080b23763ece54960397b8de836071b8914d56f95a681accb8fcb9529e5e4cfc2ec0601f7b0b291524e180aa0a69fa74ac2f17aa88162c481f51543a5a527da5c42b59f9a72b14dc91574b51e5806ace3f022d1f19e3eb621560478bb70beb8407719a01e16313d2f0c785e3b9886f679acfa465ba974676c0689a149ac04996f4132dc4974f2fc322b56115a64b0b5dbb8dc71869cc655dd61390b032f062b024bb71505640a41cc6174b68870da11eaeac28ad061f3abccf4e12231655eaf9285b205251ea69371d90527793495835715ac005868a78b1cae80025426848c4ae869b52034bb266e1b97480aaa7a31e384780442d9933fdb750efaeac0bfa802e5314d28a17d374caa05b46121e16362e8341dd923a66872df3c942177b58951c40ad1641f53a53d8708ebcc22aac67ef262b6155007dc6880a1f45cad3a5312b282055b1e0b181d9b396591fa78dfccb9d6a92d5cf8189c14c68cf4238654716f0a1e4f2542cd35a7e4e2185814c1f5b16d8c423213c69d5958c46960b8df589c185087ec5474df3c5112b5bb6bbcc6ab7160abdc2ab28801d775caafa049479a837cfc8847763559ea86239889385baa43a2848b489087fb43aa20acd7ac05606767798500f9271271e52032f21fc2a82d8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851116c2cd2fa4671b95cf7e60bdcb4976a2393647b714031870b1a6b2d486a5cf2a8093b7b948c9418f3a27f6296ea12336b8a6dd5a5715ce9a70dc6978038369a10332e3ab6c2971961d5c66441abc3290113b21c46e96c509aaf09e658d9b77928935b9a122e42bba23f920b58ea48f3f19a7924128669c09e135f772c275e55904400495153a691794a8d182ee1314446371501e87c41a944f850c9cd288cc2ea90a4e27864c79e554cc5924c4ca9a217dca424ee8b76e49993ae4b085e9809eae27401eb9c6c794a67a31705876243478f86d5b9f9cb3295422816526439950a412b4d1d28a70c6b9794c959be155aadb39e00b418efd0664b08843d20b71c547f1468c5fdd92b9d818336282f34f19b515946a7961b5a9319d9444cdc1aba840cbb57272e4da4ab20facd5fe4958a57c3c812978fd772c2862dea8b60b30a601b692dadaaba0f361cff27c5c734a42265341641b861b7899cb311e7e0acce396bce2809f24289c5361b91cba88493991987c0aca3b070411481e154104c15780abafe725dd3e1adf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de252a4f24795e9aa631d5198f07511160300a2e02a402b4cf8aa556ce67bd341307ce5a1eb6609efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d04330c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 0899b2fb6c3e1b50c82cc10ece1871e4288e619f6f83fe6c3373b7aec9bc0fd4fadcb8a1cae8c76f7bca200d22bc19130fd47fabe13d5af97b927166a5cef08c3b54a9311ca168f27252a389b41cf76b7ed09405d0805e44134bd0a90c29e28bb2488e063debef324014a7783cbc81741b0b7dc2a471ef3aebebb593d995b91eff21343f19521523e53319a21a03996e55036989a3d2eba8986100188daa5b243ceb9bf10379ac3cfa54ddc3b83f91d038c9dce1238782129682d38b605f652b73ea182b0ac01460fb45f0c05cc545808b87f84f00d96fb14915e1802dd6456f5466f8eeb70571afb129844dc95f87bb88d4270edd50971247ce1a2c2a07573d5a3efe3dec8989e9670974139102270b499ff657c2ef9aec1a1ae2a6a0ec968e58a0bfd58552bc4ad2de49df561e1c59c471990044dbd6f29ce4509a92466337704fd9deb5452b6d2558f2f76d6cce661414872dc0a0b9faca3874a9baf70c07e72562941e9b74b027818cf9e20519ff714f743fa7a53a778bb161739efb49e8cdf3ec9bcca18a72ef9a34f3cda4b313710cfed57e5bd7a6801428f7eae5b531744d8fa5d7aeea0bfd0b58d7585e328e065908fd9b4b853041fabea2acca4875cbbbf2bb73cd8c876fffae08c5c91e6d0938539c1c6f96852ae9c9aa90865f1ba78e5a17a00f8656ebd1e52024c940995b3b38b954d1bd3267636c74498cf4a996ddb024db76445b9d34687edd5ef67bac73c01f3a334bfc866a2fb036d2b00972ee4dfb7c6e8748cfd69698e0ffd9d9062c00ed57285cc96759fb99dc1ce49e6f76a18034f77fdb1dbb83b8926e37ffe62662e49a8f42d7affac1ea512302cf7f590865f01aca869188da43018a3f21a15b917e2878500ba1d1a2ac7e87c0f06a23bd20f7ee2e7399fad9a0f728161b6cf3ed9c4e57e66e71deef1838a56a70d4b59b4b49e0411ea09c91bf5fed61fc9d1d164a9176cd5ea8cf7639eb9896529260a8b76e2c26987278c11e0129f3ca598290ce7ee82353af0f99e15baf1470f6c3a2b3dcc141fe2090f87fc43cbe17769b3b7a5ee05cef079d4a153f8f160744dac6d5a8b208b544e51e75fc9a332c5cf95d39a27b21d4f98ac411273b9605068e167a583f8d43d6c764c6974cfcbaff4966ada842b9a60607b17897ca32793522da30460fadcbfc25e053d3f14877852769bd2d55fc27363b8e9ece93d9194dd65305b0b251479f0a90dae87758e08f0b4ee160e3c31ffa7f1570dced7f8a8a19f64e5df2d77c51696569049eedc6ce026f9228a01aa3d9a9a2d8a571b124763d1c9456fb695ce0284ae655c64315debec95c5587d25fb0fe9be32146733147cb7988bd8e1d9256e460958adbe92dd128327c0d4b7fe9443b01628260ef3edc66da4242077f1b29ce31d9b5b31d328972652e81b7d96cf4661ea5910343cf07007a5a07a87eac17fb52813ba186c499db08b584dafb6331255c53070a5795540ed2927ec82ff2f0cb4e182ef5517b1110646b2216ed6eefdc130fe528faed +expected_result = pass +expected_shared_secret = 6869ca370a496af2dbaa866265d91ba6be54b9686b1b8dd5714f6ba861b0d1e8 + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +private_key = f3ac3178bc3e6b8002eb20046ee3288f9cc63c1abd0b14a118d52e2c9a998d4c67e2014415084f520945f55b985adac8c503079789aecc491eb7ba540f32be8823a4a837786be140d260cff5d46186588f4fe2419e0c4ba1b619567b9d8206b53ab1289640520f2259f5d6854871498b23696a321813d7a544e77fb3100b34c89af2c63856fb43bb0a74a6073958d1199b4098386984847962b353b4d81aaf4cf65349c8197db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b4820369799d352ce72415cf1c692537a48ab603b9dc741a08a66d874bf46daad570b6f1f4133067a1d900ca87cc25e91c4ce1c84b46d3c5baad46fed227268f1a9dba968eff27249b3c6e4c7c19e8a13046a2b45bc24f4304a80c09d37ac289f924f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773707046c362d94ea547c3050ab251953464f4e540764b08103a88e448446f6b82375c15e3ca9a98798639b83638ada857bdc1e3c6705471975c51b8087a26348babefd234d27d6c055d3aab7560b28dcc13d343a79530ac868b5f6ac83af04b8d7a20b64dabe9de32a5c1b2c2acaccc4588c1ba26f5462aaa5c1bdbc36467f346a1ab5c5840a07bd33ceb44093659bb0451c4c87ca4852172dc0bc3674b4275078cd2b9a3afd61bfe454107d092e5840c4968c547adc723c1970cfe705c5d33e3a4533f0028655c6ba44ab22c2a4c85a82b4b6dcc09765124e43c985459cb2ab1519db1ec6f348d017a785484802d90e0222ca2313b4fbc465dec0cd4f3a5675e33cf0db79145867d5f0b8f340526c8a744929728ceccd146b6e66d03f660aa4e2e15d200b5960f3a03b571bb2e59160048e498c15379027e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc789e062571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c8655503f2f970071b40f6ba3544c64c41887184828be6057a9e972631604901a7870733580c6ab8d4aa18b49cb4d567577aa8b0ca2490edc68b168583b8b38415d32f5558996cc911a9470951430c36f71712f1c579a12327c41c441c980c286b71a31748ea54df2a557fd1701c3173944b7b40117ef9cb08a7d03d45531b8de4c753f697ec4b4303448c260b0783c81ed599425d9b16806828bf795c8cf65a95f366bb90110cc75d3e6064bee17cf1497f36c48e68b46ec07417b2a876cb556c705c7ddc387d74f2b0aeec9070d227af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94a92388b1afbb5408cb1c0fcd3c945e2923acdb7e16a45c03ec3298b3c44e9c1e75d049b2ebbcf2f29a2d3b7fc68644530010e052a0d357809009cd786604a39898b385b70ad7b3be011ea83b93d4426f4f20a3d0836fc6fb532fa14536285013050c16d01c5752884e49a82a4a0bdbc8bc2c7598d548278703ab4c607a16b1bab64052f40a06d3915cd03825f12c069d956f2a5662e05804183932b5216ca66274214acf5c01a7f4c77ebf522db776068f94151f7ac33831259b53bc48e99c50b260faec0b7bd3cd4fa9b5a5c2588cf098fce5aaeeb15fe651355537953d9b8580313b56336f0846c63e2c3018bc8733f05f8ce3b614088a787669205ac9889bce2d3b523f366f4bf811f004666b2b654431b135d97a70a00fb9a3928c1a4a2c7285f6f7b19bb766bbe6b966b4013ec06833ec6f1118a772c2465d81b77ba740b7ea33129218542a41e2f1b10f42bb42396e9a6c5011351e783641aa692a982272d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1d901855bbb2b68b988953ab63607d988999ed96e5a4b963497a061ac69bd90c4eab7c0dc17820b6963b0293d4ca30d82f5997a877a9aa71c5c7893c1d153ac6779d0a88190b13df828bf3afac9d7ea392fea899ef844535187af673972399a5fa31034c02d70b57b97434ecbf3b1985c86ec75b23ac0afaa67225f12a257b78341966bfd2569670680e012899c112ad3873aaaf26d2f4a5c8cc133c92b9a446530c169b6b87b118d03329374a71ada1778a2035986ceae200c763a12b6e2b2fdb672b4d58d8be640e61576f2cac617a5ada5d1b874bbac9d272ee4c881bbdcca1c9a84626012b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac252bda1a83ccfaad69e38ceda6b149c1b3ba295fd5025c63225ce88ccdfbfa6b3950cbcdf96e14dc0962745a5fa32d10525f71d895a2085620c89024d922359741be366ce9038aa3b260320a456858a7b8d01bca12316e9c6d1782bedcb590a1d2ad9ada0c26d3818652ce6f3b6403c94dbcd1424d090e9deac559472c9ac19cbb26c16e8b27db9140a1161ea96a171728689cd6b6ba0c8002ba6c46719a1a0c175638770cd088ae29a7fa958209788ade14354a1b0880f05ef7c15a6786be063b357fc7521973abe4fcac0a8c26f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7d316f75accdd1911df10a7e838a7c2023ea1eb0a956abb53fba02c48396807229f492966796805e04ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf171899a911fa910dfa6687b2c28c1d419a4817abcf656ff669b587b72374f3cc20b92858361d21bb85a3b9aba157100875c993b54ccbc84db2d72374bcae29c5479cc95197e625da047447ea5797551595853651912daec4891e68901bb67faa98bc5050bb50e913645874fb7a0e51c816acc88a7f8a4ad383170a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb892aca3941cdfa7a487c13af9787a309779b759cdc037c13e839314803bb10a3ab19b7fae477c8c322bf05bd3ad9cfb0b241371c85ffcb607748cb518a6c896830b191737ba289b15288ab59869e22637c57019818801ef9a6b7160ac1b5b4d7519b41905e6687b3fa7230eb88a3c9530813561308b68bd2b740e7aa08ca72cd6468c008ccab34ab99b6773c533b3914b19b2b80bf7e783e7bd9366c8962e7f3410f34651ee606eb737e6c9c5f6d306af7348ce955228cf02d15b8abaed16994b56260221beb1a29be5596e204b9ce111127989bd2ab49cf27c976f74aa7b084fa6b8400a25f3c36213f7c2d160045d865c75aa14542f5a4e4d1459b5676491c6a3fa0a2f0319ca1a63a401c9c3a14c94f0016a9a69e64c522aee93e8b96b4f6691322242b20353e0d8b995a6a9129e961ae7349f92c92a90b833e82b9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = ed4b1d8efb6224a8c0139d9df0f1dfdafd3a765d70e60099d700efb4910568ca3241f67b34d34aba653d0ee0beb023b5473f34398e5e5a62bc482b81382cda3249bbe50339843c37ecba16481b66da65c38a092a970d949d8e095f474e2deddea94e1d9997001a131e738956253fefb026076dee64e97ceead6b43109ac533ebcb1a05e606f1cfaf62f956bde4963f6b91f3774d4432114a4b14091790ca9a583a3418d1a3adbca8e04944a8dabc7d636819237991837eb8144168f4ad813f56e48aee382bf8e01a837e65a4e0ebb77e5e533bb718ca1bf0374da381fcabc5a38aa37f9a68f9d70656d0381916b7b74dcac08d444f532fa357323534bb7bf1e0413c8074e722ecb22a748636dae0ba5159d071c8a7ab0d2e2b4610e8ab3291492f429ef31f22f9d9a8a209a8fabc2c2e761eafe57c96a71e2cfd119f78c4240e6ef8b0aab89d4a0acd23d319b390a18696892d33de135092fb0035cc5f7e4d221dd4531cf6cca3e0e1c9eb0607cec1bd279ef77681b8ba22a6f8079095f6762d518c7472ab9e7292980bc2486fb8cc80d91fe175c668ba11429bbaaff4dd0088782ebccfae7eb4484800e0a183e598be22a64cc27aecabecd69b73ebe3bba2170db602e9c0e6553081458150f05d50d8a804fd80bfab0cc8119a865d4e558f06a7875b885571be68645b568de8182614c66bf0ed74a9defaf039ee478d1c026112dd94ff4a89b553a015ec5e21503312d7b3e3d163103c660a5312d1b56b009fa393ead12030f50cb495145fa4bf2fb95831aba27609620c0281d2887c2e49503ef4b0dd91db1b6fdba7c133846b775bc861dcc122514a3640c0098e628c8cc8ca313d94a4a2acca1da96ec33efa49eede82545094056ca79ce138b79131ed8ab224ef00839a388b0b5338629449bd5e2614b83ca644ded974a3eea42fa7bf75410a1c52ecc691b9bcaaf751beb00d0acbc5e05c5f1c6593dc674a049f652c2774e8337a72d94be074ec12863f37e6b719993c010a449e80c49998c0b7771abe617811e930300ff4302a3d1901a8a2b8fd5d5a569ea76858dc51c72cebc66f1a2eb7f73296d4bb251a8e9e5e33fc73308ba7cc5412159c0700e8d0a6ba332fa23386c06b4e551c849f11b00deec734870391cff398079a70e3f4f883e5b0c2ebf8d6a52146e62e37d62fc9c1ddbd8b1fb29d6c149d4573c435199056611b3bd76458a02f7f7daacfd2ef1b1ce3da534bca74a4bff0559380569275ba97f51538edc74844fa5a034a2b1b1e99f03de9647172365abf7cf7f3e94f2dc0fcefde3a9a6cb44d0da22d8bf35f9445bbecb3941ab70f0b9a7ea7aac71d6c49789fc72693262aba0a6a16fcbbc0956b8e04b4446b2791865d34fde941716a13bcd76729508a92dc7c5b2d2ff8160554f5fa5ae3cf701aed0d13128a76d0d0ed964da3ae47e50bd49650205effc5fff4d1dc1dbd426aff5d387b47ff9c54d7f1fc4fe65d60600c6f4b98aa53b0fde6a8e7e6320e8e0c98a59cb8aeff013cab388f5ea822 +expected_result = pass +expected_shared_secret = 502d92b2a7e1804892ffb8ff009987a58f35baa30c0392c83859fde82105a9aa + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +private_key = 37f7089480382622ac6687b4b15bbdbc1a9ad7467e8ff4cf44f0614de74b9591b9c5410d2d7084bb57ac27963aafac148de80dda6232f4a0c634d677a80c226fe67063191c05a54afc026080877538f63df93cc6fdecbbc0a9a0a4215488da1a2f7b1ea8f8b917f32f397b94c80170bcd423c1f1ba4c736449f84bafd6711b0070dae72de1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2cc1518fa4bad3c23438e06952c9317d198b0c112d79a89560dc3361f5732f820ce4d16ed448ac2ed221c8ea3601602c27f640dcc394a7ecb5079978cf52b80de15c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb524c2090a54ba793c845420a7c2c29e78a9b8c83c310d780f74127c02a59ab68c1b29952dff1196d0940edc338df3e1c1c8e34fd0dac4d5596f97a2afa98b1e8be46bc0a96df412639ae5b52229086229b5bc79ac020b61a56c04091c10cf9940f798a9c50ba1f5fb30bfa947f20b62a60215c5a88d23b70c0e299c53f49a1ed511ac5812558133d9f195e1fb5d77314559ea79e63a88e781c4224155abb5ca91f089c0c609cecca32e549b0cba167d9307a3a64681a815a69c5d7e787751162483e7701437034f0864d8d53201fab9763c7921eca6f11247e7ea364298c1c3ab893549572bec45c1a8c3b88659cfd526810b23f2095aa6c1424c7178187109f83063b52547b9c731f9933622a33c7a8b927a50191593488f9a0d12331017919159c7a027c3956fe109393a167a6475cebb49224736847319d161490ec52396d7babfb638bdea29f50c9ce37314fc858455f63fcc70cfcb751df12274feeb45a124ab1b997c917a550c3469a0c185eb0238ffcb4dcbf751e12ca17a71b807b1446ea7180ee302e6998ef8d12a857c84ffc377f5e42fd41238a54345229916a715977025b3b4a6060f778de7d426a2f95927335cb202bf4080b8510cc0da12c4eaec4bbfa42997e21504b8c5d32604f1d66e8d55b50c393f973acd37a236db595e3ef08239c42fb5e9243d967181b9b94f4521c104a8aa726dec057abd419bc8c6cf350c91acb78b0832144f409f78992652e30eed7ba2375b3245d877c8e8b873f0427071c956633495381a2c642b15282b9945c758910fe469cd091b4458218105da96a479be0ac6b3ba155d359b2815916e93e9bad3d431945b852e519df0129174b24a32cc9fb8a62de96733d153a799cb8fba3c86b9101cf3d4a97bd3b699467991a57129607c27274d3224cd1848c17f1550be47b71a119873045e215bb817cb92c12a7bdc6347df8b64dd686873d800b4672aade8af56d2995546cc37c06f9212a54745c5597184ea85cedca7b980386fb91b8ae677a035a4547b5848879c2567c8cd6ac285f6f2460dbc0b73f5ae0993c988418c234895380c556042acd15a6c015a13ebe16cdea4be38528a9d244230a0ab053c568e31c64d06a3d7bca0e5207b7669811a3512f8ac6887137b0b7627d2401ccd604ae786753fb6568cb522b28712211208c1849d1f75cc4fb951d2aa081ada952998b0b0e938b77359233a76c135897e91059cc5639e978c12c6bbfb735fef4bcb1d60180df21d964435fc16be2cd2276b7bc78ee8b5c963af2af4673a93940b429131663cc124be5a706bff5c157dc17dc5cbc2a11418dc4b8a28c841c5a831b1a2ba989a20fdd17dd06706ceabc0d20714d5595d54216e9fb6824e3272de0a1e262aa246494152b1cfd95c970f38aa35fc0337b26e76c77a0a76bc2c57b80757550b11807a423b85e32ddb537ab6d4694cb8b9ed58b11c9a6acc746749c21011a66dbd7896329c3a31d0a7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1bc1a133a41565305cd4a09fbb10934e7a3d132bb0eb83559c484ebc92f7cf93e445020b7187e2705a2d1a8386c008ec7f22fe172088360cd3fd160e7020b6d0c747ccbbeddb1b84fa7549f625dbc064621fc2e13f720188c200c1ac1f10394fe4117018b9640632fbed570c942575ff61a7149a51f9993b90827ea2a08c32a330747ca27ecae452154ce1a6a67a8b63676998af929e8a7a9d2ab709e2162a2e0bc0721bfc7e49c5b2c9ba975b3bd881aa3782391f5cee4cc1835c83732c84f54b373eb18869b2c90e9f986a0ea345cbb020333893b463671c95e6aa07193d06f7e62bf4361cd0009b1e528c85d147d0e650cea7b0c67f1b4fb754bf2f1a7b9cc621d4c34682a6195776bbb9b2cc866cfa94c368a2b4b346c75a2a6bfe946cef09416aef21b15d3c72b7cb408141608c058e506271380841656963174c70e09c1f593acdfb9bf4a3a9387b693f882495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b610f00bf4f4a282f752a070582f2f3c141e168f6fa037f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a6f82ecf8863c1692dc2073cf517cbed3c362a853beef1a8cf2247000cc4cd8176ce980d683b8ad89b3eaba3b962624f5ab3695fa10a88055ddd664a2ba0749e439a39c6999496999be3ba7bba2ffe06388b1a6c83068ae70a1c6f8a36e788b8aa148933c896eda61efc86cbb7d5c9cc96c9f137c6a9210347289010979bc1e16700a610c7c990d685550f537ab0c45b2bc57e5ef4c08b2220961c6e17e95e2e4482a4a94da2e17b6854ce57c263d69429e1566bab646fdb216e0444cd8fcb7df4168ae66223a0ccad971583b5917c4805271a17b4a1e17462815cb39332699ac447332a3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd2131b98aaca67343cdbafa3db35661c38c0ba1e18043a4c945067adee46e428a16011abfeb58c1bc8b2330288b57cc319389921857c9d015a0471128c34cbc13417db24b91a3567ac299cfa6d4c2f1123661a3ce0996111d340d9613b966955c6a758fa7f3556f6716e5ac7ad3a93174b2032a983cc0c73c0de302f9f83a0de89a1fb576cd3b41505b5ba712c387730c45399b8cf0b0e548cbed984e7bb5095cf7263b05cba437ac6fc369ebca85e0211715133bcc314723d79c9b93abac57ad3d3a5e77f2986a3539eb795a5b4967ac7753115b916236a97900870b658b9d4b3e35827e1aa9adc3500fd9ba18fc6b03465903858c61c1259cf485338cb700eb731f31643b469bb259210cec78c158e3290573c5228518e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147fbdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 74bed33073033310bbce2a4a3856a92a519570deb8779e7b4dce5147f198bd71ee95be287839ebea96cf5b1fb11f274d63ca2b6d14c15e9cf2394aba065c27a94f7c6f1eaf6ea0655fc0cfbf7a773abc14d174ee861e6bab3c69beb678cc362135a5c2bd55f811edfdee774efc6c2b6675c2a94bc44845ed9bc711cb657ae894e80db0027c88935be4bd91966aba98726e111a549af8664dcfa9a343da9db39dda10ca22af7365da7a14d40dea90cb216c902a9dee17e371a538c85b7832fdbf1c3ed0721527204bfd7b75bae01f56a51b2b8c995ed7b74c1222d849a6df69fcb5502898c3e578668595c405a73514939d9b4a0be52c8e7846765c43771083e49ff08f3d06df2252a98ac8b096c729306b47c07b8000d6af8bca84416d7e45fbd749ce32952ef7ee2359bfc31ab36491f4445f231205d0766884d5ba5c32e361a269605a2836b092bb611e2aa1e8d0a761b36c3d7e2cdb14755ad1c79c104f46ae33f615601033a60ef387df1cfc1e2985f0052076805eb9900e67bb1e9048c6a303b6344422a714162c92c9f724311b7581e18b214e27aa099f507c1614a1582b1ecbcfd23b7809976ca80cc6cde473a7046207bc0d29af3fa4c509adf1f199c7171bf6a8d029d7a19e171dd272a7d95a268c6d1f757a65e4da37b8a63e1ad50fcda5acc1c377015bb942b946a0b6ac718ce4caffd229fa6f1fc2f8e02087c72dcad9062d2b7905a73830577454e6d63b602781056a43d5c0d39450fab97b35fa77456812bcc48670abfaf71cbab2e8255b5bc8113fc070dc2fd00d2cd5bc597631bf798858df26bd5d9398e0d3be2b8fe7d6fd5ded8b2694934b5fde4e1b713453b9397b2c8be399c1c835815485518e6ba6e8854e39d61f474cd4ebd752a61e06d7b76a713a7de9e80c6d34dc4069d0492768659bc8888e3d5a7462f820bab3adb4547e50e9afa891aaf477db8f24bc620405533b2e997f11276043eee6a3002ad901654abf4f3a89f9726c50612af40be942e809a2afa71c30ab00045a8d12cb57896e79ea12989dc79ddd43bc1542142c77af2dd2dbdd808f5d2e52f709f18fcc908338e126ab921879fd1931b720ed9e09c6c1e57c58ac310d8f5149037586a0bae9d8b119ab91f8951811ee7426dea158f32a1b7140d4e9402d68b26150288862277c370a4bbf6c296f440a55412cd1886f69d064bdf1ad73a5fc147129ca5f13ca8b9c1c7c816c2dcc2af54af917910dcabd247b614f4377a236aca35c4f8d29bea865858891afecac4acc0c6726fcb3927c12878a060aa4136b4bc3419b83f64920a63707ec048b5f9f1297cd38142148380f00f6d2dde4934ab78ead5c3414b6dde04c49843f2c54598fd511a5b222b5bd2d349b3bf8c555bb3980b42c7ee256878d3a8c8ba403d710a16e39b96fae3526abaf9ea9b99dfd7fd28579689e4f3787ed8000e1876fb531014e722fd2183371677071a6d2efad5d5725df77572c5d1cc20b9bae3fe89b8e0f393245625dcad1d0531ad787f69692e56d +expected_result = pass +expected_shared_secret = 48eb4b840c0d957f28808e434786c02a8f99d3464ccb3caf91cef4a0f8e70c4f + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc85521d549b978b054a9b8949e519e3fc3a653607d794491341039713037d31c9824eace39e7127a974403441e25b714fafba4b98041e85b2fd8d8acc2a69aea9c80930306b46baf5245a505d48e293a77aa4174d1c095b0b4a45754a4a94bcb01d4543bf7c7def2ae2009408725c58bc76bde03abef3c4ee0831d3c6b2632609707b3b861f093e857902d52a2a48619b1ec20dde7a923412f79c22389601473076965959b2aa3c79dd31b98ca9847731c89b0929ef5174cc6b92972ce2c07c8139a62c901216245cfc92b2da158079e1c93c8e08ff438a02ddca4ca948f47a106d40ab6a5b0afaf52052f237e44f0765b3436271421308611845785e257cae691c39fb8c80bbc1c5fd687a547b7e8e3aa1d7c15a918984b6b359cd24711cbbbb95716ea54a8d3511c5dc983fa1b019e0b0d7de90c3c0a9e7652c18e72cad6f9c510e64f0cda8cbd86502a5880ee1536edd16ab36bcfd859ce879b3f5d6a0d90630668b7385c8599ecb1849a4942d87a91497129e196309156c9ab245f4c637080c963f9648fb2ba6f32d2566f88bce680203dfb827438295f8670c9bcc34a98497851bdb0e631ea06accc26373809986da62fa714012d2579d5d61443330e3b882c800b6c9d02c98e9859a4022db4a09510fc91a3b95bcbf73b3a09311cd13e52b61733e02dbb400e8a54a30668311ac02fae2b55fe05c95ac43875d92f3c2acb3d4a6b53d363d5d75a697061055a3a788bcdfa051edf97c3515ca920ebac9e7a998bb598b8436bdb63550e416d2aea5057562a901b609b129d92b27536e02c26ec6a3b2c5f6b733d0529330e9a89600b089dd30a0bb52530a3062be741b09818a78b4fb9f274b7262ca23b3f2a40542caa64fe38a6ed06beb5498733a38a7fd0b5aec2673aca2b07e00909e68d40aa207fb179cf7a60a9e13719635a15cb221d1cc88b921e950c94cee17d60f80ca5b4a656f501d7136d1245207479a1da42c26c48664297562a0bae0e7906e9d853fc7c490e4078b5b3b226b37101a31b5d05a26f1ca1f231a853f23f59d86a3fd269a0256eebd02cc0c6b77f1b1c613114e1084d8d1cbabd0c7702f43d2ee01db985382c562f1b7885a7015edf59bd8988b5bcea1cb04639bbf5b119e6293f908245455070da3013d2b6e2116776694b44e3a7e433407099a51940870b336f547677665c7066e181ce266ff0e508268731bd13afa2ecb4546276a5dc50772a6fa38541af968ae5c59e2d04c3b6002c7120a6a970ada2671590411552e48e7119c7b7f7ac97429e9b7cc0b5242df277cc10e7c48976266643a9b2308cf1799324780743f95e65851c03599fea7129d5552b86ac35aed10b5f00058a8742c02a3e4f6cbf5df61c66143ebe933060c98a4bb55318566184601bb395625fc86e4bd47377b54459b45e50c145596b9178d57d01bbbaa9a63bf444889fc810f1e40e07d289e0b04a58f84348463b9fca3176aaae6c1c119cf679bacc6eb685b9f443c2a9e304bba0adf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c16029e18d8493a524fc2a41738a25e735c665e79ac423aca37b5222d970358718343322db0162d26965d5e946b700ab88d702fd5a1376920b5be702297aacde28588da91c719d40c1fab0af109742ac26c456961338c44c93c83ab58581635499545cca66160e15a35ba4931e2b91fee68a8734acbf72755e8d452d17215457161284435eb6a7a2933c8d146a12679143b80740f68ae052087eeb988771a8fb43b34d6ec79868a0670551bdd19cb5313892bcac9e4fb500d3375ae471a3ed551b2d9c76142b22607615454a910f8578e44b448aa9200d805cf4c15eb635013bb80a65593ff578c794066f05abddb850ff976c74ed6acb4c41064fb5eeab479a13ba57dcacf7f02421603194a3cb549f08c0d700790809ee0e585dce4088f96a740320c57d5a632c8bf5dc173f0f841173aa47ca42004b808ebc2a6a1770ad9dc06027557f80420db47b0158a1d1ff32007fc058875c4f5d21fabb67bfe8909e10b51bb35c76d0605d0e6a97e56cb93dcc58f722d95f33008b0a237b711420a20269a7097396a4a98be20b8226e103cb1136ea3fa39d438b305b63fa049c420cc378392b9f911bd7800bbaaf2bdd7586780c7078dea622df51c7190841585bb16bab9a0d83625d55826e3949ae018e7c4703ca082466b9a078393c30a4f6b7b1fc775c9dff7cfb5909cafbc66ea946e6f098f881b3039c251fd3ac142029e8728082f838a202cc3586672cb6285b021c41e3c16f5787ce6e319d849483fe40d989c246f7c36c11a991234ae7fea68770c79d8290aae3bb72ba014aa1279fd13977a49b0cdd494ca00c610cc2306059b695686399c1590f274f735142639425dd88026f8be0f260cd66672a12b5c7b5c7323408a2711677f062625eb8f3541098d079c13208415dccf3ff72d1999721db3c271f7521dfb0f129b3cb6885310a0689166a3b97b09610347ceea5579650720db621db20eeec24eec2144fb523ed2d30f64b9c6655928b3d06e1fd9b088ac8b7c964213e5674757c7bd48a3d066355f0249a50548f430c55a6ca0471953eb7c67e140aaf6322b7741225931622db114ed46b9ea997974c9ae2f54b87125ce79e8621d712688b50c7a49877d52091643a4a43148550135f27bb30ea131521583f5b79255309465f4b9f2233027855cc0e7c93bb33705136c88392cca717254640c540573d3a20032c9b297eb5b02c954c744c4c6143a56eb48f1d15439f885803ba5acb524f3d54bed37145cd9173ed92a00f724273787cf1b89c788184de0905bea74fb331ddba00cda70c1547c634c706a8447145489752b0633628ba4f5286851e1b5ffb8a7fa2bbad3f92c542ace74e67aa07b467e70b6a7d3056592b36a7a37c6c7114c610721e9c6ea933742e43609c41f6f3803e99a8d5a27b069bb73c892bf07524a8b2989633c96ccf33791ba29f3d575f249c640093046d1684fbc701ac633381bb349bb7d351230a8bb1a22223de3850258ac7043b887770a307c3746002cada2826e47f7694ef51f94fb9e3645aece6273298592bf00c0fdf14c07d8c9fca401ff351d2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b8b11d0e47c323d6b3c0ba12dc235d5c310ce2c7bc1f0a8467d627568a185855750e12717760355a0b8a756468e95406d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2ffd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = a36c2589f709a16d07ec8ad94f92a168e6ad851e9b19ead54651ae5b5135f38d38eeb1e3ab60526f5724ef7741cb2bf962b4675042a9754227472604eb1ba179142c9b91a7cebf0ed64537618a70dd66f63c0e52f7c548906309e8fdcd30d573b036afb4c17cd882eaeee61be968c40ed5067b4d72a2b6a49e76a3d77dc36f1d9bd051bbaa501bfc89d3eea3439cbea585073aa09887d504d08a5cd0da0079f0698655ef809603d27f5b3c3146983c5fd8ab0df9d4e3f8b6f4781d35972425e13d03701b1aca48b7b9c87aa449bde4e4c37fabd70a69aadf9170359d1cd8d0c87121e468c385f099209575bbde29c5eb745d90319e96a1163867264383e6e908b9aa251547d15f8d95374e4e07b8e10e7f70758f19d76ab0d255d2870086db6070b7acc5242f92eec7a784515c584b9a831659ac86f3a610a09500b3a65a1f1c309adf2e4432111e0ccb6a2403de2d1395afa4d03de5a5f3c9c319ae0dbae6d3c40f6a4c0ca0a371991c7a4c55c21d50093e5257dae97ba3266a312e4647045780091194a40cb4543106dcefe181c104a29e2913d8d0491c0ee792b25fbb87f482abe52a7e38cae57af8ae52ef7c006e34ab21bf93127dbc744bd09d1f275dde2beb763479ea3f77db387703fe0e97a8d648a208379c9f0ace66bd442ae1254b26f0f3cb267f7fed926cafd59df43500564907e2a06eb3b6cd480b5f451f4f94562853e92974a13af6335661e69f16e265d9433a004402d9489f89e631e360c3ee3e0b2bde5ca53309df77a479371dfe9b2bf12734752127358f36a98fad6e60ffa1c3e418ac8c81c3a8f54d5fe592b079a871c0f1cf36bf2229bbfc5cf88f74757bc11dc826c589541d93e771a9870fd8c07562c76d6f4fc1dd2a2e82ed136f5e9981aeefffbabfce661bb5597e7710edcba41cec1059e96f15d667010dae62cce9bbd8a2e239c3dd762974af32e47ecfca58e4643c08e0a972b149749e4aa4a4e97bb89cf12acc2183125117435417dd3bc3d18304a8f56db2e88ad5ae15d20a7f68ffdd9f7a76355e28f8d308604b6945da697d85c5c965383e4247b03702d2cce376b651cce0c9a36f26485562f6b38d4389cb855f74849289848267f17aa874c475ec41da8e4548a3ec47a389d33e20de412d3fc37e630965a3fc919672c43865e9cdd9282f23401e49b9d110f73886a00c839905e3fb7cbf2d4b881b24d5a34a2896a6a93ebbd9cc176f5a00b7ac139f477541e8c2c412ec7ed30b01bac78595fd18194bcd608dea182c741af8de1cab857b551b7a541bf76dc6f706e32b688401435e25f9ff303ce8a487ce1c5140ae2a1b1aefb25320c91cc641cdea55069acf7d261d6d5539c0dd11789ddf6b7ffca89a2166a0ec7391db587faa543f17d98b16991c50f0d6ccd5ed6c80aa44a3ae3172e7e242e9569a1df9b1def0851d9c150d5a8825151569e56d06a53e624827c0b99bf586ec7a71c09d53643386309c74e25e329a7b3b8d0f3eeebccec064d83d98c8f1f6ef19aaf28b6b4660 +expected_result = pass +expected_shared_secret = f9507f70421be90f21138a1e135329ee8228682cc948a6914ea58624d396df0b + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +private_key = 469963001d4d93da7cbaac0acdfc833c47601ae334dcc0022a9220138c16b9eca73ad1863431a34f593addca4f0ea393fc4595d22a7cadd0a8d89827086a955400abad84226541114cfcb3e3a240fb600dd6c0960a7976175c56b0b48c66721e13882e3aa5784e12869f0c8518037955f876997975d27a7c92d4cf005ab859590504c768b02576a94263c87c4bbfe1afb09b8c0a5c067776a0d96a5d12925b44ab3d3e57c6971b0a86617f65a16c7e9b42c283577219409e1ca4de08a92dc5b4e8e87051680c1b24068dda801fe871e0b28ab0611bbb97cd49bcbf159b7785830bc9d302c0a61ad138277afc2374aa64e983506bd11288f4a20376b50ae1c1233a1acf30af1da67301a5a420aa826db58322dc1c7ad8bfd25c3b21025b565c357b4a0802e615a35a384f1794a0612e030228a865a0390197e7c27f45a4258fe26082c850170cae86721bb5c68cb32153b9934de4cb11528c570af363925ab0fedac79748b3489b7180e81ff6db702d5a100336955ec02fd2b9c86c2cc001833b0ba1b7dbc9699c6556b448324d29b0f6a4028bf48a49b1cf60b4a9f91321aa64ca849848cee2be0a29219f783008417da307710f87cafa2603fd206e5698177e81470af4c608a6128908541183a5b4769e74166349e55b4d2a2a84600ef712c2d1f13f4fb3c91bca8cad209cb5ba0ff578bd6e29a0cf07a972d262a2ea3c4dd44a5d55446c174b345b96871076fcf785cca68545eb6be64bc9be17a7d5914d8a50b286d3a2a8e1a53faa53815acf0237b8bf204c34766e97883071e56539361bbdf29187c180414c83d9c09e30983995aa4850a6b2358aa6240642cb9b0fdb739fa5a93ec60c11061aa8b5e71316a517be2baea2f74baee32eeaa0a75d2030f5e8bbe1b517f56511fd8aa499621a9ef6c88b96a9f33b2b3cf04381b5c97b743063a6286751ad9ee14903c4674b308dd5e28bc700134c43c788b04460db78a0e795e24698553722b4c3a095784828960672cbcafc11af32c918ace0580d5bceaa574409854051a2419f148809147133866f9b651a38622f21e0614f10139ba53724831ff312157146169ea29293d2a3f1250ab9cc877d448ecb53139e6c5487dc2931d45b4a74c34bba11cbb965e1e664ecfca54db7bfe7e61db2382e50076a70a9aa028670a354013c894b729945830b1125aa53f4d352bff33fdbe7c64bf70a4c3acff3680976fb26368693d928122ed5707b453a1dd714fa9c5a8e6534d45b53a2ba464e217dc0461be31c5763715bb66b6f3a4c0e7a3a4cc107602cc3b67487a7d162422468b5cf33c8e5a63f801c2016b15c40398f914cbcdac9664b7601680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86408922fdc9650df7577e5a89215c8636d5c376f4596c329158964084200c91af4a7699018c6d139f521204bc521110aa222203774db88ac0ac94cb97720a71411eabee0b2863c35607a617e761298825acd91c73685198be96b84a98ac7295142f6c19bab0082c53a8a50a3a39eec2a34e859cfa2c88c9cbc77b1bdb5377981f61c1fc394d70820336baf21820d44c0956e09a5d8279f9a0681cb98bc38cb551320031f46262799c182b0355eec82cdb58d750596a4e6bf1213490810415a4b347e13c9e8514890a0995843936be342e81c7f4971bf9b75925d61ac8c961492a85d83fa8e33c12fa37ba08d7c681c521ed4060481f58be673007a081321e01e21419e232283a01cb1a4481550dbade263382eb93b7e42470b265027a933c480cda340a9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a3671c18479db082a706768a63109d2c4224d71c7c95755ca24b056c355e9c22cf5006662b3218edd4b317b19962cb514af123245b152eac41391cb432c6caf9295c66da4e5737ae3d60023f46aa7a604c64a6c403306ca4b96fc2929aed5b4ce7e6c631b473d7d61cbcd19826ab82c0c58880d77ce8f9bcdbf59d645424baaccce334809b43acb99248bbd966c88793a273ae857946902649f97b5516fa2ea2a84fcfbc054653852d8421b6b78c289b49080c8efaf85df195ab5562a03e7099c43c439a25ab41390b86db4f57188f002129f3ea1ffdbb9e9c688ebbb26e0d7ac6eea395b698a134f70f98480e87313b79444963557cee82534e9c1cf10b74718caede3bcbd98a68d9956facd8a45e2184c16b14048b9d28e8bfbf5ab43d1b650ee8cf13148caf451cfb144656052cbaf82e2f765c8c9c66c23b0cbae0257d6000f247200ab87f93b5167478a27b42ad7681b6919529bb1430dfcc809e171a334b33a0527a1d9519c18130971c55f6ec172b86248059830fc57c7356c9bd8263f7d571d0f7bd87d2a1686a7c41db9306558cbdf39f0176959a188b4d457b40c152b7ea09f6860d4d945e78c45eb68b579d48774eb26ad43bc1be3c0ac327c80b4c1115c2cb58bbc24a18146470abc223ad51fa10eefc311f1ac02af4c7432210233a4abc408b1db484e7885d239c0c2b9c4952e577a8ebc3d6a7684e711e12db96e1f988df423a395301d2c15fe2f1abf708bc64147a30e2717f7868ff602d50fa9a3d0b3a0097259ac52057dcc14319c438e113da967f6dfba4279245b72cc86cf724c81769dae271e18c0b6cfa84b916ac89b12a1f8b05d88527ad40346775cc832713146806a2b2884e35628169bc12f67811b507bee3bbebca81ab93b5d700aa92898b3f5cb6e9d345483ca3743457fad8cc5bec2a8e7a22a41ba8b67641ab181d42abaf94d0055206b648c81361f8486408b610bb3552299316b5c0b7d301d9f1c3d55621859ab2ee922c59b11ea9f2a1efe277c534128f2cae6b598c0fa059efc2c24e8a0c2337bc2c57a0bc64a7fce190c656b529d21244eb66a900288b5c484bb033020b9b9ba3019b72387f2746b3b893a1427882bc3135f0a17f8271f9c8480eb60732672d44336b32f851a283224144c480aa302c05836edc1ac4569a6020130b341466322d17811229441c4513a2e8041c85e035113992f16799dfe8c1eef3aff8ca2f341628808a81e8b66ee5ba47ad0863c735a904565f036a85fb1203058137aad2206c303f22d3027e732542a342caf3376d6b065a745e31e865fc2243da31ce08eabbf8183b4294700bf8928da8ca78bc08490810c39747fd3851211b22f26451f6772e0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = eb9daf793643df194162e69b6c518b5c2dd3eb2e3a02334fe7d5fbaae8cb5b1946998a06dc8e3ea0c2e5f009e2fe5214d735c46855fdbb1d45cf47b78ace270537aab983305cb7b2d31e4587d71166b463f3ed2c21bb5e2467682ff74ba01cdf6aae255ebda0cf205ac9dde6d55a9e3c0ec9b9383f2a779d2286a86988ede3e055fbed98be3376c7f0421d629d34d753486a0e80a53d12d1a2ad0e8120687a92455d720a072e5df030d7dbfe55a7df9f144b34e7686b3f75b78d41043e945b3d2757e4625d0bf038dc9671b16c81f9c91574caa2d9ecbec25c0486c525a6b08e9dbb3de04670030b580d559159d0c95f0f962c1a0c524f10244fed82ae8c161bf97683f200a3447d3dee1794ae518a6bc7384930a6dba9e761498ab266e73aa99ab3235b65b6d8350652efb94f28e54e86e63628c5d86a88051400deaae123f80cf0e35c3f9b48a2d48e7588845bc327a07a9d2a0edb7ba9adbfd257ec2529e2bf93cebac1243c91508c0ef7b61d913036681468fe9768ffa4789ac24f44327035561df783012e768139313f5c58aca8e47302a5871226855403d9e3e862b20ae66c521135e67ecbc0b947f92cd1cf8f74b2977e826d513c66e00672b2d16e693aa088441a32b64d77387e963876ecb5853ab458ba1e4d5567fababf1c9efa0a255140c94c3f286600f04e87a1cfc5c4253ad5c5c9d7c7e614a2f6808ec8b9633d1bed84e1f6f27aaa72080b69ce6f1885cc63d9ccdc006139e67fbecb07e56a2ab8807f2f0c09d22ee1504a9aaf086656bea5b2ffb8d2f9ec1c586caa86ed3db23284f5952fe2fc4f0cbcc127071b85e1e6c6a64a87b1ab3f708b40812854cd3d187ed627f4c3612433aa2e0c4fd6709c4ef07436cf31801f6f77d6fd28b0e070b54191909d443d24e95617e39f7065066d65eb45353e80bbd11529f2c9385606a96b6b7673f258725a1587ac316dd56dd3d25bf2484d855e59d77a44272240116d11e725ac45766759dc89b3aa9e5cbe96ff7df371f4ec039f1472d241fcf233836b3da13224d92cc710a6caef02b2b77cba408539403e5a9c3f06c6984d43e05b5e278898e3e59c28af7d35a1a2fa982c7e014b185c7456a986ce41277122c50fbf2d7dc3014c5f2d3da0773f31afc83a138461ba19b21df959be21e2e9adbd059d2a141439cfe8210bfff745a5c3108dc34572ed87d3b60e0e6b1ac41e1d7a9cdc10e16ed2ecc2a20bb4669bac747726c8bb112874f48c7d618f0273f098e249e2ef0ac29953737e036ebc361a8512071d6fd3bb6d8661463856e387819ff9201476178f7683b983cf8473ce6688d93ed5e6a4be6d2fba23949a25bb2a1ae3f5634599ac8c83515d8d904357972c659ca5766105ec7108fff659f428f3100ecfc2bfc57f97e87249ed6640d47948ec2376268180a7a627e992930ac7d7cda5076ae04a1405b215d5d5f8bf98a40576615e02c3cf85aa6dac1b47632c66b947d8da73b1c6725032f70278177761ea063308d540a60acd162d83522fa6d188 +expected_result = pass +expected_shared_secret = 24caabaafe2063f812eaf57c58b6c0376ed8ff778cec1980ee9c3228801a75a5 + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +private_key = 3c14bdd913cda0f267abaa8b0a30a5eaa527638c01926623b0bc2ba55b0b596a92bad72e92845828e8050f4c2f40873918e4524cea8505208d345783f71202496721e361a582c5445fa31fb662a64941abf9fc203ab4a741c9214c1b80b4ca617c4976c819794f53cacdb3509978a6df5900016278388234cc1a09b804679f36718255b2db60a7eee5bc3bc78bceea8060354b54031c4c76b30a1a8b1ebb697ff8606ce408fba72dbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895be01ed5c23a0d22707d89467a5b9c662767a0d77d5c49adca983ce7401f34526dab1cb9fe744bde8c54c230705548b9ed00b9f4ea055466cde77019324c0a7c9ba404b641a6530ae64a964ea47e6e80aaa4652c9a8b66061103f385479e50a780249a909c92b7913329a478880162d8857d58fa39d3283f5a2a7f8ff6abffe2463db40728d06166627e9c92283fa57a2e46190ab869b6c21fbeac86911284153b259bd2a442070d1cc581fdd333e5990f84ac67f47491df01128f0959ada0891c236e0aca87755289c0e6c8fb136974c97dbb1b8871a4c70aa001fc950f0cbb3ace4ac44f800252f5bd76fc1dc09a3d2f8860385a4bf8d765b49c5379140e0a2801dac947c23803ab6b467f2bb1b019b9d53771418312f51b28db18be216794a0467d79ac8abaf2c90f4b1b3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935dd429bf8319bc0b8199cca9d3f78c483b8e0771622ea764fa610ee13c1a188c56d0b5c17094c1b7a45321bb69d99a666a7963268a1d0a0491b8b5cb700a7d86ab9039330edd8bb17cf1ac79355a82166458d2323e070ac109c98d201358f22bf9a3b513b8bba43905d1a790a7b1a11f682583ab4fe0a82f3e316b7c70afdd823c8fb7acfd330b22f378e8597ca5357454a71197cb4039e9a81d7995d14587b479657584407b281886d6a7fe9b6170a056d2003bf898027c275b7c1c3d1d0c157145ba52d264699b969d60aa3873a9606041c20b17c90055b8016ea703539638cff8aa0a219542bf51b68cf153a86149881c087d898ef9c3a089cc70a8656117131aa3f233c73cbf439022d224422920501c07243432aeb925c4023185d3f897a79a983d857c6d1422f9b22234005e00882f77c7704cc74adea4c8f3971e7964ba1a530c1f722ef696828c46946f0b329d909a47b83353330630359eb8e9b7e78abc50fca8c3aa9af967c89f464430c815d1959a21a226a966a6434301fa600a4d129886826803ec49a54a34acd62b50e33fd782937571816421341cd76a3570c17ac9c338e4ac4c51077650b98ae445d236904da694f755c1a5b288275b517b4c9b896c49bbc18933e52d34969b6ad8add604b526488c6397842a54b6657b93386b0ed7d36fd2f448efe43b0a144c33f729df530c8b6340cd61897b3c50b0d8ba81228604f7a4bcd120cd2a7bbba3b4818177c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d93589021251d14c920328c4063c2af3c8c41228355527adf41037e1ac6aa69a427a55354ca9d54025306c16f93154776b4a7af9c9ef2298dba9b669c40bd0601abd410357b8940511beb6c96541aa7b69158362a41767486ec3da09ab4335fe2a25dd6c07366478cda91c691c5ed9264f771124c1f3693050802f480f5df89d5be189da765337a69c5c838488a0a4ba7880e91871fe346cf3abb0aaebadb211b5acd3b773c9146cf97920e509dc202f79b14734c9777a567cd44a43500b5eb8005bf4c5a387701286639e6d9ac2574b33f2432b3a787039e34b2ae511a27825cba7a8e09b401cfc6123d3b4c42318e7b032331230da960a09f61a6a196dc185bb8bf1c1a6b691a06cb57f12be1e45269c56490e256a83c13352a878c724242ff0681881160ed03166612d69894951d65b95e690db46129d149afba2c835d3b138036931423d2f84ca51179466a1028d1601d5c397cc81b1b5e468869185b25095a0e5b5dd6a421b5c7eceb58c4cf97b7feb114fbc435c78857c65098d3017ff8a58f5927e5ee7712fa0c2962939b9d8c84bb6428b3902881188df17479ec01e4709b7840235ccd77acb0bb3a05995693781fb711d61f2883827a96ddace29a9cd43ec6abd4691be1a758b72a629f6aae1c795981c0d8bf8160bfb3b8f5047e1a410cdd49c6a42adf0bcafed1b21eeb95d504b1a48b1ace228bb5e1508bf05128f0cb63f5597851b9df4caa5b6ac10f7f6188dc41b02761f840caa42871c55205cd09771ac9125d6265ddc56a466249fbd774ee53756035349ca12a48237221bd53d7ff1ac18242442935ba818a3b50007a3fc14a2fa3abe437ff14705df0cb5af97561a608a3fea42a809a7a7d5491453c849dab7acd99636931c007a70d01655c7302f9a26012c494de47839c1ea2951a87ff73968dae83a86f392f021873be4c75d2b0700a3b540f50cf6fb664a4627dda9c75394032f434655755d12d4c781e2324ae00dd61744cef6c5ec9680f379a26284bf9590a33350905e080e9b70547ac1cf3ad888f30232fdea7bd2c184f9e1a9b6835401e737204c5ebf2b28f2b58edd399f873c7849cba8064b8a20c9c391841875b4963bba2097b958d752739383bf26787e64ec215974b45848185f44b8780c0714b9651a7685e673cd1b6230c5d6639ea5629c20659802bc6f2b95df274836241165a524ea99a941312fefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2d31916522701d80252e9c7fbd7a17d306a4e1e02cda405f3f07b38eb65824d5c9d8b91f7013784fba0df0348f21b00ef5a325c745a829714a5b9aba16acbdf029771d5415e867590cc5a57360a8969407f0749ab8a08a65e37e70146fc1b7bc40d789eae83761e77749a07859bbc046b5a87e3a92a5368251127f12d27789318f8b9c3c1f79211922c852a0b0e10bbb631599190b49a66937920b3f113185d89c6e37da5f7ce9c12d37c12cc24741cb9a79446606eabe8c9ab06d8963c959955f198e03a0bd127242dbf2a2180281a7b65f54c28ec9c6cafe64881d6456c07607cdfb89e2ca2fb3ba8f8357720051c30952734932b08b508402a6a2f4f9c76b053c12a267618928032b5d9e41990a18c2c04ba7c2868ad9f4538ff1b494707eb9da6b81374d7f9731f9a26089d7033a8c24600944d65871d313387b4101c0aaa27ae19d978653638577bcf4caf48083eeeb57f401544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d145572be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = 0b19df76304bbb9eac107e0cde980f205d0be113062aae748fcd6f23badb6faf0dca0b9a52a0c1a45fb39a5434d97795de72799398a6f7729dc32bc0fbb724aeb6a9742bb8e1f5ea50980b79c61da2118aa15b92eaa122bcaf059658bc763cd04a22318f8db35b6cd62d7149e4d5896b651ffce990974cfb4b0342946c13697e68a5ad08cd94b13b83a78ef022754434636363dd2314433a11c96123bbdbb242cb1224f31b1b171a30b975ea7f6e2baf749c0eae2271d33c58a247c56bfe1c362554dec75f8ac8a4d170009efef05ab92f0afcb47b6afbeb88c718430a98a09085f377a34c84922d1f48c004f790d9ece2eefca8daf3f44cd526aa074101a3ab083f05a163601b68e16c63eb293843d0aaa8e438ed68e71227959fa9baaed20eea22ae66b8de0b7c19f2a777928fba4fa17e137cc40d14ae3cb8a711cb4637f3d94f16a47b6be2345cc046a1f64c1aa0886098731cd9809a3b2d40ec95f6c7bddacaf68865cb22c32b38ddfddd008f11065167a4acea5212b1e1013d704ac9048775d6eed6ada96294971b6da0100def9a754e57b9fca70592974ac72a6db96c38c18844f5ef0c213cfb7077b11e8c53dafdb091fa81445975f38709741a295d46ab9e6b1f2c3449bf6b906a610484cc40a2c8ae35ab4311a08cc5f5e9caa90f8c5c03ca1e4c02921d24d38eea84688353ab5724ef73b16bd4e881376b78e992e9105f85c00cb30214c60e70b16e37f5d1c8997d7de9266f7f4cf419fd0e1be6cc1ff2128d3b21b46c2782af8c805c7fb7cb441ff4b5fc97a94902beaa56df272d0be1e48120dac00bee41e8795a210170eefe920682468eba45ca106e6e8a6c963d8587734baad6874229f8ccf5daef09836878e3ccb8edb7d0d3f10c466781ad04d943d478d40a1aead1537073b405ea712b6e879983d6dffda1885e5bf4354508c188246b4e205ea087ac883843d868742247a5fbb66baaf0eac8e5a92fbb8316bb5cb560a72a140ac57fdf41682729a69f2e87bd9d096ea7fe2243e6c958ee394158d70831c9d06660c46d86a14a39c8a2566588d72118eb8d53266dd16e35e3249e16aa16e0d5af04966f71037698e278e129e65de8629e28fefdf3cf399277f0eca62e9ff1f1d18429a3b06402c88e30d47aa4c1d5a9fb1cddd516ec907f3c97b0dd3076504b083004cee7db4a31d98d80c751b3a5ad56c4299434effb58b86149869bc0818738f95ed0dfb269b2d7a4747cd3d08036501f7b20fc0e66635bd89056e3de42228a607511a85dc37682e4c64a89c0592b86026d0f7cbeeef3b436e4d2f399e68334a29f514825ea8cc8e0b0e61d97391b3b62620b5f288e271365e3670d26e2e9faf37d41e3bb0cf937c446185706713b4fad79c5a4e358a3c208c37c66ab57ac40115ac256feacd89bb5ad0ae35c49cdabebee5d1f051f5ce2a5b4b23f00c53ee4adc430f8aa74f81f92871a4f6c87ad22c4d0c0387bb515e3acd8865fc1a14e9fcc5c4082fb0a1b8247736a510f45a2cc31f4724b44a0 +expected_result = pass +expected_shared_secret = 9f734b15fc7dd99bc10d6cc7de5d2c93ac789a5665e508a95d075dffbad25abb + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +private_key = 2d149d32c41889573ccb5166c597c3fe207cb806bd13a8a7bdf86267a93da7110a31f22221a17a5381c367eb1b9cd00810189c1f12358b59adbff2060ed6ac6712c660b51b553402d406bcc1d2444a863b6ff261e17aafffd01baa2b05cd83050ab460ced09bc7c0c2963784b7f9798d837bbc0483001539f0ea65a0574b46785645019b25130095725fb71556add2832ea245e250973f504dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ee31e0fe931d16cc9da767c3a48bad09874f7730fa74c349d2163638aadfb59a462e904c5530a0b485541e391b6037041ec6a0560563f186be2ab97a42520a7daceabf1216e16870437cf012a6b6d082bbb23349628af4dd8ca9ea986498a80edfcc2418c3f5a627ba8baadf3739b3c578b2f193f57b72dc2827a2dc379aa31b6127c65352338c012cfcce0af1b33150d488cf47134e06b5ebaf0432c172090fa6671670bf7b66002e135e7c43d938343d5729e22e5597a06209e0793e65417de945b5e1aaeb2740fb1b350c902c1390a97586564fa94120cf7538b21aacc0ac0831b477e37c9e984b73ec91ed88705ef4cafd2f15a50227c0e4c0627d2a6d7875e9605afec339799690bb6f0a5b01141a6976fd51aa7a079827d37ca89726686ba95d6f275a59341fa229b4c163c260c4dbc4587c50ab8f0ac777849b5f700209f17c15251854c35aa23c20d486122ec8145565966f4a067251b96461950ac2171f1996e94517610338b88c091c356804cc691922449db0645a404ae4a641d1482b58e6230c7965c23605d66e96c8f0418ad786801d7530cfa2b5b757e06abc10518b274e3992e538922b717866c7eef827d2bb4c05ffa3322981cd8069dfe028d878a8b7a002472d302253a83ab84adf5530cc5f4671bf5219fe600ba97abd2555c52857abb76ccf4760adb30346c55aa5340b189e1968f72999e64c0b76297d232412b3c9384783457b83309ba7ef74abd50d16ea1c32a2362aaebd02da7790fb8827ff368261cec14f3a2095323502446703783ca9b6aa595d690031297c59b25414455c155924a47896716ac45330ce7069d131b75a57769fd4b4ca1990170a3570160cdbef1c930063d56e3546f09b1cd913c82057c0bb89111e6b1bba88eb8cbcd72078fcbf5059fe25c84bb5607d7b20bd0733fd96dbae2abd9531ddbe3cdd89a926361bb56ea0e5f9181b2c8c1532312f3f9005135c07dc211b824b1e63ac96e64845c35c41e0313511a5d429663796abf2443908d353766d40f47a910fd04a710ba5d6a5b301832a5b6016338d8858b220e8219512b643b8b60ca2a9347ec39638b787fdb44ce72408dcd2504de24af91130abc09b2e7c9bb26b3393ee06fd77019ed3466e019ac92a416c9683da22cafb1a9ad3475af17a15ee9f97446096647578f77fa02e79904fcc008fe509425446ca2a4c1dff32cdfa4ce120230bb5cc9cb49a2e2841bf69a1c49a762ec171698ca0445201c485a15fef2562eacabad3259119c9ba4185677e03aa0470ca848709c4ba0c8e5814416c5678033c819773db36e7a90c65fa82ffdf6921c38285122163bc0744de5c5363c9a973428a6daad20e5a62d37017b464da7637d32b6c92f059443501427ac964fa569cbb074c71053f179bf1963ac704489ebb9936e23950e51ab7e26a98d6031c652701fa4ac59aa7c15d88c0337a067257b8d916db0456fad9622f44a928df6cce84a3e6634c9caca246208920c487b9a666342abc389c14c499785bcb91a95dc868fa20d25b08ac0e48c72e9b486151f21b11731d1bf049174adf279f9020aa98c38372877299c4f54a4493a3b20f8bc71cbc490b363c4162055cf3a5c13650db1154687462fc01b5e5b78c9f603255a24189b808358e17e01b9cf736a77d78a32520b6ddc9c1dd65a00e84b562b607b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf040dcaa766bcc18d6b8a2f91e51ed6d49aa37aa44531bd9dfa25c116a842e50f53a68bf1617245e8b7da778eb3343d3f2575ea84627c640a6509133f4c5d78151a6695245659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e647223c0154388912ed028ae364a9fa9a018d8558c3e9b179b66f2488c2be8792b1849fac0401a9756f209889fa637cf7ecc4f2c0249eb5c6f7e0219faa2a9433759ac70dabc7baab623c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d467273268a0797b8d6fe57ddfdb03fff7ad3d5b9c80dc1939720ee8810933a04f51b78262910d7e28c0eab06b91980b65056472a293f2361183125670ac2426e514790b945d6b09c9ec354fe7c895a30231d95794f89ee60761ac9b2aaa9a75ef168c0950afb498915b2518e010c3800764bc5a65c0c54b2af686b7d954e77bc4cf8137ab398fe93429dd0ab80fc846d4cc8db2b9b2b4bb36d4c4121639c1e74622e59250701302301b4df96b2fa62736b29caf0866096f842898b2c6012b93b5ac23d1f39e192002ff0b9005fbb8cfeb8930562a4e0aae7a40c5032b8b33d0760d96c7c203920e2439d3ea02372c7f5d80b92259349076ba20c3ad4fd21752a3963cc5126342a963a363c1157f33189732f7243e465b14969f1ca199af45b50851266742151a235a8ba9a595534bd6aa31ccf52b8c5885d571a93d2577c57057e2caae68c9c84f565c72681fb15056a345236b02a1e5b13289388f035a2f8e03402f8b0a44259179a904c94725319acacd28ac1e449b87e8916091940e33861a4a35a8600267f04ffc6a3e06c60858d578bec60ee7716fd4b0225e5cceb5fc5437387522200f66fc880e0c874119c71f462cb4eaa24e67be77ca67278344199b27e2a55b50f372b65345122225d7324ca9504ce4d12bc101639e93b331e3b60e1b520e03c9703a69f54c2b1a52254ac44b86f310a711263a5a9b87a7116ec5654f7297ea76b63f939c1f49ce99d52bc58876160401558193ad98c7c8f4b6822712429679214bb2b6e8b324b58e1f57695dc8968bca7ec3717df12c1279408183b49679b349e2e45686e722c3a57bd9547a65656cbc79aec1d3b129837d84a6975d018c7ab04c88775e9c68839955775fd66ab02aad69b76307f51db2ab33915aca61969aeff14674a557c322af6997b1a8d9c51445884779227ee742986446ea1719808996049038e0d9aecee828ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f20831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67ef48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = b7b48ff76d8b1709c67027c3f1161313114a848d6c0a3460850f2b08556a47dd82a0ea4e4818a1667882dbff42ff428caf7516cf7d32a31c6efb18dbebc69a7bfb17c04eb69bcfd8b8407b85d4e68118efee310f122b077560af4bd157bceca4b72a1b4e927ff144b0443d3fc4b00ddae83dd88c33e728b7520944cad9b1106d3c43f5c469efb9b00068668f0ee8528b0482ed82cebd51bfd0c0dfea9ab42338f3636a369578792e07182f379644219159d90ef9b309b312309f3e1b4e6c86ea904f0f49fff3469b23958bcbf00a4efea040530e20d4b8a19e7a67fad4f017b2e03224f0e2bf9cb88055743cad55c59d7965a490b1cab9be13852bfaeff93799d08875f55a765bb78bb7bd3bfa6573962a233951c99a8a1ce020ac8f2cad10927a766d4fadac01ff066f8b42bc071c1de33c0c0bdfe761cd607020ae3e2c559d77717dad70f62dbf147c86712d92a2cebbd80584f1ec5dc10cf94372d772e6087b9f73c62e7994eaaa8d3a52f2f7a623ecadec7d9cd3634e44cb282e07fe20ff0fe7c29534030b12c1d6e5894536c8815e7dcbdc82f291fc8309af952c489cbfd86560db108c731c877975bbc076435c227c3c6e5546c9c9c475b693625de1896ff066e24ce650483a2a391f31ebfb68e172641a8be54ffc35f09208bd2aa1d837f9302fe2cd7d54dfaa1f833c85222135609b4af0901daeb0f46a81dfe8396aff879acd5ab17754cef6a8f1406563f8899f379fd1ff99371929304338efcd3465100e0e7e3f94fcb26f20b28eb8367b7cf3d34f74ac992b5c37050daebfafb35919ce6703d6cb3c0b1cc40e7b6b8de1120977a5e7d09943423f0939839cb6bc53df64b387ac018fee33ac33d780090ad582432c4d61514198d74acef79ed0c8710243aac73bed13ec6661e46d1e8605634578bd17e1c94b1e705c6ef1307cd7f4e828b30d3cde1f65adfca10439ae9c369f5827b94c3f553d258573f0b7c7884133cbe8277d207681800291c139dd0787f0800763d79ffbe667c1c56ea8bfc020e339f22edde053a4bd05f345e66322216b56c168a7b11bb1e630ec1fc05cd30cc3ea0ffac9a223e3aba860783728f9ecc974a0279f307f984baadee9091ad4f4db905dc75014a29e9ba246b2edc076f7f82cf5a49c4b5f85d3b3306dd9d391ed8500a7d8c567cc25f0e25e46af32bfb44d2f57d59490884b494e30499669d5e8e0ecf5b0f8024e0e1cfb9d25d5152eb7b010398f49d169f57d7565a0b51edcd362a591686d00c6c72bb1a0a93c05b52cf13b82b08e4f28062b558fda675c5a9a2fe5a0fd13d7fa0b54ca094935971149c35c0feb38bb658e929d291920fad23f27818a5184e15a7db054e4dceaa162a1fad1ad647ea7084440e80e54c6805708c4aa9b269c8853f274a6097d313dff1e36cc789806a9acf77f1a18cdd88e1e8527abf12c3ac3bc45b506939f9cf8cb65a66f83fabd5037477cb29a0a32234eb4034692edc2ec6a8f79450f232c443639979d2d4a442963d7c63f04a8863e42 +expected_result = pass +expected_shared_secret = d27e55f2a1f9ef336c8537f11da9875e03cc7dde8951d81b0740457609654107 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +private_key = 85b01a4a587bae308d39792b47f71997fc55fdc2746f881ddf7bc215145c56d399c6447ada39230866384bb718ada160a7349747867cf695cccdb8a4f1fbb3e573ade85ccf38924f36482bacb9798d481521a0cae103cc9fc9675184490f281d3516cbee910287758a4c374c0a4313f1c29251b1655522936dc329f540a1fd887f0c775823436df736c367aa3013341e66854fb39a9eb90b23caec3e84690ad531141f39914a77a767a47b60f2868cf11311aac9da94c72e9624d21814cdc99c89a4b35e1c4c63cbb3edea06888162e180503cfc6616b24d270601d0d275c03109dd9486220b66d523a8111b4de5b99d236586a09a4f77a240cacb4a737c770bc4915f55b609075ee68499654baf90622647052a8369872a93114c80c60fca1345e20114552119669a0d3a7188d3326017ce92112f0b715c26b40851683478e5c719c11088f00aac577f5a8763d4a76e3cd00cd9061f021672847ba0d4785ea7b1b28fa364e64c4fb7f718d2352b1fc26858b6552419a4d8e1b22f8c7992e3b5373183d040948777c356d514fdfb2d0c5a636bc5416a799270e5c975c0a62f3a76fb134646b333b75582f7f2c51cf4bd37835c3fdb2ce1ea86306362f8216d27e40ca43a45edc9554f08c604624659aa10ebd29e59a60f7bd66eee447f4398addc73387579148bc4a26b6749c961926fd34296db3044cb0d2d1312ca6a6755ec48c46865a36a6330a9aa5d39167c6062ef1a7c82ca5c0ac1b163b85e43c278312c4304aa127d66576e7218c2d0c850108076109919ac6931264dc2e919ff441875e607a97772feb45f14881fbcb37b4d00b45f416cf56c9501c6598ff9425249740eacca49d92e31d679a4f16c3ccb4384db45e47621719c6c585ccc03355216d43625c08760254ae3cc4aeb1287cd5c3f0911641b05c7036c9bb360c72902325830bd25eacb5a88abdc926e0f205ee857aa66c8c47e434d8bb4a6cfabbd8b681c427846f0e18a2762152b170063b489a3e6b8ba06b00f14a3f2e6ac00725e5724cb629b7a312b3a1221c9460917c07637b71050bb644a38a8192270c857d43ea9304495206bf62b1c4c11b04a817aaa996b2a266ceb8a80aa46674f16207b61bfb484af461b6dad9a9e6c22c56f81bb355a6705310e921239497809012159e78a8a249796c155a9dc7cbfe7384dd092239c29773f6610e536a77b879eef054c5e539a381043c1b53d69566a96d1931b166c6f066cf0ec81e7492a200876d42007724ac916460a1266ab77a327ef1282479685bc43a2718c93a806c3de3a0cb918c7a734cb04759341c5b1496679987aa5db93b70f903a5f4024c3da6fe8bb2ebc27182e1179611c61f8f6214069ab83c7165a46caa74bbce0897fabea9b6b58cd34e7535b0297b4359960d23e4a498cf7610601d92af2fb6163c4b2761615121b62a7900b08d61065c83a69d51253d48399fc665962ad36275ed3774f114a079f13b8bce420b44638cfa6ce6018b58bea422a8287a6680eb21c75456592e8b24cb6c26ec3d3c1dc4a19ca16888e9b7fea1a863b7a0143307530b533269a8b692cb4522ac1aa27b01d38603fd009e1c02017bbb36da2049a2c5045a63081266d7c6b065ef3308afba0cf3607b2c98d83f76f7c058262b55f7c0746b3c22437f00de9d7cb69f40afd60ae74b0506afb96e30669f51c464a27b4f177666f92459b293dc208a0dac5654a8058a8fabc2d1853009743a598bab2c248068750f01227be5a4f7c4c6948f9167e88894d43b5aa44687ff177de837e2f0537f708a8f73a11fe6632dc285c9026bb23424ac2d1cbce39ac6a0a7686f088d617b096436c9f773e7cc50cea1c08db20c2949a7878d18e7372cae746b04558a8fbe97df0b9a69090449a507e6e1c07a35680412033127037607b2f0502690b47bd300a84c041650dc748ac2c060260c933a0b81847243fb3267f3cc8dbea4cea40790f37cd0373a71ec00634bb3b3b087a82ccb1e1dab77300156d8094a1d61d1f1bb3f977b749c938ab8092d71c93394856ed133075e2bbdd3cc0f27c2a2d34bc0f633f5e55c0a6c989b1e277ee9132f8779923eb2e22f78a1502ba5e55b6d53a05137867c10536e672c7336a3ea1f237263a6046f260ed3871f1d479be589744361a0d819439779075cc47a5a33e18326615134d9f09b68b6873c6ccb682f6b75662cecdf5432c37189ae09faf36735ea01c12f9ce64f4116d509c70e0072a242ff126710d178daae86539226c92d090d9b60dc63539f51b46dbf24cc8d54eda255e0ac19b03d34f5a270b6fda6d6408bcf1d2a46824b5290b8a26a8131402c9aea052d0101759345f86a66a4d238a20c6531d792170c52deed889ac3050ff87c659524337830c205622a989736b788092101933c0073c0b686106a9b88c17958a8711d272392ac448b01507634df4a23846aa9d594c80bca99f17505ac1793f2877bab4f1b211d2985842795c4c1b9fc018dd15b510556ef89b687e6b01701cbce0b56159a90f7b2c6fc1039aa38449a596c087a62b2ee5a7c3799f5a601bfaf8b9c598834fa115ae010f71167fd41b5cccc45146009752f380cdc56453e554cc779604f976fdc34e9f135261eabffbf00afc514f2699aa6a5aba0638542891c6858c7f6c6c4a12e4ce2d89b50b04c33ef262ee8b0d9a7777d3c56c85b1bafac7052fdbaed24303c843110c1892381887eb351134798b9745bc229208b277c2c999570075903deb530bf22f7906b75db35c3b24b04751bf6ed41724058c70988952d86b48519264d25ec2b817894ac370bc081362c841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d21470586510acf76fcc683035b18c05eca7d0702e0453ae00a8144779117d7c19cffb568a3c0959193d689a6adbac13df43907fd45fbf3313d49425d32ab9d81c6bd9b3486c3636e6e0015152c1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fcf020cc611e3e2c8e52f5ae886b8d9480551d012885318e5e6c1ecee0a3d75b342667c691d19f34fc7946e7a7047097f7938516cbb6c7f3abdb85b15e302a5547198ac0b89e7c2bfbf74050970e8dc746cf16bee6147076bb89c5124a89e070a785427cea590301cea7ab28ada228ee7bc7fcc17074063358a706989c8d6c82677287905722cca0a24ff91958c44a3044787eab3599eaf241eadb932b06b151a1a02ba8b244e9262b96144302124dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccb30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68e6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = 0abaa530450dace740e8afd009c206de7c0d5d5e81fcfe4034bebe306027fa8372da9cd5e10572bdd552e82a2e596dbf9b6571f8a009613b4c9795d44d377353eb4f9ca13c2fcced279674bd21d310f5704ffdc74b4ad98d72648106171cdd082ab3f78eeca66e7355c012838a5129cc0084d722948d24f00a91d2be8bc44e6dd949c1e241a22341e3256f7c751b8541332ac389d3c57a8d69365bb4c9a4757dd870f5cc7ef86aaff94e26858c6f006dbd1a63bd7e09cf5e4fa6b1d2c5e03e58c3d6823a524a76336db51447a17e64ed42e7da5e9417cf0b447f32143e689ed01c4e2e5a947bdd5e2f2f701e407276c341ef766238c8e04fd1c051f71227771e36809e6a53cc68c303f190613334737bda59b4375629ac14cf16d7e98bb435b9fe348cce9b216b6ad2e6f95aab87bff03b49f440e4e284ead23353bb85c81811731705fdace139c7264797eb2624ce48122dac337e146ada469011dd6a8e3022eceaf82b27938be256f84e74878aa568930ea88e6d823514491eb9a27d956452a9aa81b9a2068d3e4fa1c27e5eec5649aa395b2ee52ee8e87033be00e7c4aed4e1375d01a7be8b16673bed2758b22eccedaee993bd26b91e8e0c25dd1a5bedbc55cab0dce5e308259efd45cbf7e6185e2792ee36a453c693da35a668d685a8d70d49d75d4be3b567fcc9a978defcc480d2f70888db31de14cf90a2f489f020358095dc8b7588ddc8ce441fb1385be6843a6e36e5775fdfd14f03018e33c5a2c027cbf4328106c33afe57b0da9700e27b3d25f905438adf34a23718cf7e6ca992dc72b32aa1c432ba1792a626fd91ceefed47c8cbec2b9cea537b0f9253cf9a11176f3103c7a98859e4211e995610a4817527977eed6ea70b310f1c91ca5b6403118084159e84b497c9a995e3918216d5ea0706c89031c2d5ebf8febd8e68b594f00d266e41ce12e3dbfd16c130d44a0378b114dce1a6eb50f227d4d43f1f8d615b7b278546bb53dde219677c980f215c8b2b2284655e596a343d1aba0e277b8c98de9df84208a9e045828a75b1573bb15ce0e8d7c39809e57d118e0b8fb2d67d72afbe8e9750c4eacd95c4a69e03a16911d27f1bc5351a35212e69241dc4d780fbd4c9dccf01bb79fc2a40f4c29f0e22dc552758c7f735a9bb13685b1e45772b47a97d4312359ff0d3ab6191e572bbf9505210582a470e58a16b3c5cbede72d07802d973e09f80339684eec8fb84ac613c4c869cfda4c6ab82ec54d8d3aa70bdf89c792ba8b5ed3c2b3632fd391e43fbc66733212d439e5a67d20f237c2a0f782f96a9e2d93adb6f1333182ce55056d4cc807098b5333541269a10935d6132fc5dffc549d99b25a1f48d67999e669ed8b5202f0ce91f3f368882ad1eb67bff3a6941f16ee6349019bd41433c2ddd70f7d5b789b000503a2ec1f48e77869240ffc649b1133374e80a16ecca2e28baee086b973aeccd3692fe9597d934af1c53668af5ba474979d2d746156fbce5cb86367134f0476f06c94c3b52ee1f1b675a67 +expected_result = pass +expected_shared_secret = ed5903d1cf02861444cad7fc3793b4e1b9b6d0324bf6babfb768bb2f84300086 + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +private_key = ce732e28b21f42f2bbd1b049e6b80264b218b581cbab8c9186e325f7617895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b652f86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458e419cd10c10c890c94fd3564aa25f1ec3a3282607d8b1864022cdccebb1b1e48961207e29264a9ca86c94b71d5382c9c6b8004c818f51a52006706285bb3281618a157c80c2c00905c33316516c17f04460124fd79a1c330417984220334c84d96a66fc8a5556814c58f7826ee86f17319da3f504f0124c3f06ca50792c1e1800feea8a8e8805a54bcb90c52eca144677327f5058cca151617f443dabba304b353f4a5caabf0c179a772582711c033b3f3c1225f191b887d8294fd18914850de6b194b91c250374963bdc7215b07cdaa8001372a21f0c3845979386c27949e0bbedc0b004258866a01ec5cb82fc751ba2f4510e514a3fa09b6aea7e5e45762076b81d781c2ba91dd6f40cf13c91e947a7d7abc2a2aa91a1404d87462b42aa71eb15209a9b0d4990c2265b051163cd2ba8319576758237482f500f7e94b3ff099616225737a766c10b6aeb213b5b073eff93c3ac91bbf2b93ff47c84d7ca2e794990e2db4a7e9ab19cb50cd522427e6a935ce3976490b21792cce5e4b971668c4793ca4954b477703730411df1f5ad2557caef78c914d0c223d836c407936ec58825f3b2a1925a5164b097a94a13d8ad3a27bf1ffb0c08c72b92215cb1b67c7d2c4a7bc7a6a8a054d2a34de69c78195bb149e4b4cebab78f41612db19540385f2f74757c662c2da3c7b03a34a9524e2ab90f5cc21fc0d2ad84bb996e6c73426770ffc1c9942cc22aa2934d97a66037a18760c51b0236ca1b1880a2286ee5241ffc220a4c6ec0e296090874b3ca751dd701086a15f419c67eb4514744047d7848980c036107586d36818e74ad98989c8c02afab4134ee0b545ed707876a613ffa10be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d6e29b184a38d8091b6a2c288ee2cae833a68a3cb6b30bac5ad7567c788d8c803a7b622fbd8a253b274b93593115b5b7a5282eaf93706c88c178bab897b7198c23b844219852a60410e8afa85c902edcb9a5e87a31ca84ac6b89a75830566062bc159cb129277af0645d5817c8822e384040f1621d66d41643897df21c1013cb1b426a703f120f21c780c67bb011fb3e8cb746c0b14c9f847dc1235f72e6bdfda1c55bd26e377395c4b17b764a41e0f7312782bf71820dd379befe58901a011fadac1efae549e5933aa9f9c64ce2273c486b56251674d56212c0ad7637854c7b8447a135fb960ffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cc32b395aa73a916514533857b4c3405fc32c2946cf4f4251b2091b6cbb00ce296459c45e558b5048b79cc4cb8aa01bd7e82320637a62e2038d5b3c0593b42d32a38be8312ab022ebb496a5fc4a991a1baeb660a23988fba329a79dc7144d20b5246466f25af4ad971014970ebe2b36316b86b3585f6b0753711a0bf3952c688b4cf6c8a24c0964cdc1f5c1c34b3c28359ba232840063ac30bdda83f0611042fd8b7c2bb439e686b49d538cf32a05ab82372f7525df40085b3413f078226b97c234b815ec615b2683f1d9ab32dc0314c6cce6e9620c8e73b1dc85bed5205cde5a44f40427865a62356ce44751c7278a3b236bc2d208c7b383129661810a6a2962496d058ca4875ad234c2df951612e665984bbae791c279ee835b105202d4751f1a330dc6b0bdcc38fdd6458b0ca7a9bda026bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847487142561863b5f38c5aa4c0158ac28e95012c10a8b8e99ef7db12c05009311a74791c6c8b355e4a861dd3cb6fa085884d7a7e8cd270f656ce29f9bf3b91b798032c16b00f8cd722a1cabfbb25c3002324c56b66df87182504581a76297ee1181cf05a6d89698cc94021b16574264435f2cb137a7a667a4548c96f835cbbcf27805ae37448674aa998818cf26d15a63689777a9b98219ac3b9ecf84203826eae294800f5a07ffa886cc86e7d095f42c471c121a69a1972a7906abbd31003f6c8c0d07ef481b55fe185811084d9a472ccbcc586b6a9a6f24d269ab36126a3f0381b29532d027c2d5e21cc5b9c6ec8303e4b388a6b7216b3e581c0566558107c8b94c599f09c2ecc4b7a824fa3db9a29722317d5bc5d43827f4bc6d3a91f65dca56bc26de9d40bf2f69263cb010a9a24a749c931631ec2d13ea4d5136aa8a97ee019ae1291ea34b0807886ffa323ad3b0f83f82e5d9a2d748945a3ca34b9535d0460a6f734bbeeb66a4e3c257bb079f5d80f6deb0dbec130fe4a182fdb16291403f37a191c381723965c3fd90d9f2b67c36ca3ac141030ab516a01453532aa06b73a91b5ba7d1a308e286fced38f2858801022a453320a857b564179c55f0436b25cb191865de69877b47041d9d0c2c9bc42ca513f207a72ea9a5cc48b573fb402ba8b5ae6d73f2e0b044b8ca67c1031577099b9975fad7103c7f6bf80099bb51138d8a7af7bb509b761a9c6407dd9826b7ff87879098248d779d6f26aa0215084f286ac77c50849ad19f29a32b07ef517000ff71799d6be1d177508bb969d9479c6c037a5a18bf4302720e240dfa603b7f8745144906bb88522505b19336bee5572188853a47b4f8ed8a040b251307299be642e086317e1504784990f2149cb2d89b1a8542e4a19cfafd57ade9a234545142afcb3e544b49df75b0cc78f5aab935752746ee7a7f7936777330a66c1063c50becc4286a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5db8251de0267ea3c0eec342b51505469aa7fe936a5829463892645438a3a182859da136e033b926695421a1891610816e136dbbe36adc08cf00e4b44649410b2a11ef254144c27787e54cc5a533e8e54f11ea94f7e9c2009d25a6248321f04a53c31787c12aca9cc78fcc06b161701852215bc6c29d1779f5c183152cacb583a90399746f75c5bb337f1b580b9029b112579884f792ea5a52187a109f547cda89b7fbba90c66065a33423da4515d13bb5ffa074aadb0c55119065a51239511bb33288f994b121da8913992b979a59bbd64036968621e76ae336096fd6125cdac4f767a883e6448b078dc04b1f2b7aa49a1180c0f3bc65d2a93458291982652063419a9cb7f1042c38f483c4a90e17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b496485a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 5794df0ad781361c6821319687c08ace02ce58cfa47ddb4d8d9659ecfc28c7997b98665da6b0e985ce869168935c6dc81877db1c88d3aeb37515cca3dbdde9eea44707066a89fee8c42d3c64921c97accb8b62249e20d248c7507d5b49a5849c54bca761745c7d2c5f83fe7551795d9c1979cfec5a0b31361a515d95899cc121934065a0cb0f8e8aab6f6789feda87579f26c14c76081ca22bd24f65c5d1824ecf796520e2ea33b9feafaa45da662c032e866b26f5ab26dfc7e7baa2e4a1d14c4a3fe70d3aea96e5a68d7118706a7869e37651524046df15eb0fe51c70b89b9f6462ee7481ab1472d4f9997a65e06650276b1fea8af04fae7746309307aacda58e3af745df5f02e9102b8c5b2d981321cbc3ec8476a2f7873ca3013d4ad3b9d1914d331a97ce1eaacd85f9145759ae255ab80c34564794d2f58c00a1bc10e69f5c28934b163ac554512b43587af22a43cb01471ff8ec21cdbc2d708476036805bee7199078b139009ced9b39a402bf0744842222515aa55d8d86d2fb04e81ee7a8fad1d7b46862cedcf5ec66503bcaaaac78f336107c4b406c4e67283b0e7ea99ac08d222822b6721f1e1669e3ecc52573d477c6784ef31637808a50bd3ae98701bd1a8831e11692be8e0c84474c9ba739dd01fdb24bdcbe8e9a3a12082f20ded7d06ed3bfbefd1f0e90ec2dfcb1cbd039f1e5c4f657296371ca5f2947b27e686541e8991603850422a2091a9ad87ad342e936f0d78e4211710f8b51b947e8a2aa98fdabd660119835eeafbcea6e2bf2895d22d264a9d558222926469d2454fc948e843c0d086ab8980665fdd0f600d03a14f14b0bbb2756a2f17b38fffaba6ade7db5768c0ab9473bc0e1d133e2467020c0ed4e53b94b722a3ea63ef74433a49ee5856848991cf9f0b24bd39e90d57c00dd86ca0bb4b3c0af67a84127a41cfc3d233ea766ed7de7784c9fc0a422f3f0d2b6432583d93d001e167765db6af0aca9b2320640d83d7b41bead197632aeff5b952ca216c0051311b6547d04f5edfbcab178ff1891eb6e42fd6c2986654b58f41c644b00785201b26f4606bf4b5c0b3d4f46d1f606df167be6584979b1d26d3f8b61a08d65c6f733c6ff2288d252052250fae9373d9b3e2b314be7cc454b749fcb6e5207d051be4fa345abde67f1603f12a5433a54d2badeb7a9f5912209b733f2682e7d39208af7a21872e4b64ef835a41e1606f8649823aa236b47579fc8263c2f812ad4846b2a8217c847656e2d54ab774fe8ae617a341aa2b3fd2ea3f6959bfe58c26a9db8c3badad7a7557c7e75ead54c9bf85ffe9e4249dc1250e37c9bfe5343aa0653618e0e651bce7dec72cb14510f1580c43c8ee786ee3ea87499c80183544a48db67b8a8435be1e68d8d3c6433aca5f42c8fdd3c144e96d3dfeb60fb1d9b1d92d8da62e51fa1e060c973ef92c5428e9be6d0a547c9aadcc47e35c0e7865b6493dccf4381da972bb51f99d7b6f4bb7ffb8950798217480a4230859480aab0586e2f09eec53c2f4f645f82 +expected_result = pass +expected_shared_secret = 0d301028c1cb31dedc8a702a9e95b7d3589f68a6a1f600af84ae0f543e625361 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +private_key = f76c7d8002b7ca65bfe6a59aa3645a8e51afe5fb80145241134cc072a60ad4b72d80c2bcbe1630eeda661cb62e01b0798203a1a287c4b8f725dd422beee6627c864149ebabd84280739193067a2348f2861dbb7f1a0914ba2bb3ac6c80d5ca1f483c8b86c1cf5a2c3bf8f6728555799381a1b1f3cd02e445cbe798ac0361e15335380051294667b9149f38d85a1839ae43d331bf14091c4accbb24c8e8105a9d1185ba880b7e13cd3563aa235b899e7509525280a37162c043b089d5a0bd48b225ebb2d0538f49c8ac3c3b0677d8093cf70b3404016b4686d653ce4715a85953171bb937f5a1916271ad53318e8155269dba4d0a520d057963e70cc01e680fe8408d03d3275c95a2c528190924749bc32dc31b21b58c6f5e4b59c157cab7653c0d146dec9a3f94e241993b09bd62446f35ad7772279e116464fb316db8449a3ab7525b3e89b12b54f14fb19057c39510b072894831a5747782d404487926ad756b1bf81cb416d94265dcacea475fcdaa727d0b5f01b376250b123f717fbb0b1976b7704fe5ae5ac10cd17b87fa8bbd3d824d3b91b567b5c20243677d741ae2cb1c1d049a842b7f9da9cece8931851bb35776caed97c27d395108e42661aa60cc181abb2774c67773fb29b445f3554d386c87d489d895a43ef268af0c81f6065e57e744f719120323b013d35801e26bac2700968566512106f5161ee8528372d45a42b41022239fb0b3cd23c4251927b355719a1f2a0689a4abc508660dbc282706b765ca4bc1887fd064cf8285b1155863e15b112bcbb1962255b362ce8fa4c51c97cfcea7004daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b86724c1adc3e67d756c1c8647fb4ba32b75a6da3a05a870fc1e12cd279666ca046e064a74625530e742efc72c1d5f959c9d256389c4c63609fa11a8fb5e70e1e2256c8164d80c69fb8f4008a647af7f3ad960265f55cb786e8726b65689a6a751fe045b7d45aecf50605d135a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b225728eb8836ad1f373f66a2134b8b429a8457b600c5a3274b0157f66f091ec88436d5667802a15749b4c9c499a36c58fc5a7ccc10a604ed00de74bbf433502c02ab0ed949f5da8b9efb83c4a2395e49413a7030f4f95901e8aa2716a3ebb09aaf61c9384586021301de0f8c085421460a10fdd176c68b4c115c91dac04121924213855ac22e8c98e3643c3d7c3b6c6c4ca964308510525c5aa00c32ad9ba258bc44a9f521a2873bedaf7c56bfc26a320c0fe95cfbe12c0038c1a65b62c18c37e61a2b9194c9ec1db8b9fd036c7c3a620b5c661d8ab0b46a6cd3391e53218e40cbdb082c2207630c2715541b10e3c395bf2a5a15ae8b506880dde937432ecb150f9b3c136881058a750024d9b247232b7289bd07462c051b7ba599c985c6eb08c7ac22135c99e85930113554c59ac06ae298d5935658f513644b01132b4c1ab84677e342a1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f782784e4b6fbad380c5131fcae11d4ec89df82490b4f1babd4673d7417b9cf04513718f2cd0cfc29707145034ecd4c65cec93a9b26efe3b667405482e3aa37d48aeea67c1698008da4b68683697dfd34fd72a6f39ec0aa0806ea5c59b4554182f6034b9c5b7cb438e21a14774d58afab0099e478a4ba8568e192c71db7c208b7115d29bf649bfb3d23c2d70599682c549ea28dc16597a43aa6e65c77c432f554b067a64ad62ab71492a1aad6045677c74e3e8773fb8665259abd821bf07d2157c09199435bf41992628534daae814ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0d828174805da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5da2467db42479b478f0570d48071f028110f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b2c12d34027aede4a22fd80abe26a9c93c938c6b1348708d1bda7fe6c55bf66981695487ab81362f50b7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c3a2181b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee4a13b75379d2776a7510abb21941c2b36357e8248686a5d973b946b82e40802290651a073636b367671c9c001ac91ad03b9d6e83721ae1247cc188fc05b0249571656a276eea09b6d3376c208335618b1fc2748655ceef805c39165d0ce9bfed062add0c0a50e43167c80e5301a076c9cdc1f13852a5987aa3cef5e5864a706b3de947d2ac8e8cea0c3f83745bf3185bac9fd0162510f70bd20129d7c5215026114c4b5ef044a8a29a3f01fa02a0a3ce928a65ce8cb566848110994e7ce20ea5c30304d6ccbc7477bb78b3ec527758b7828b836dbb2742af6095a0bb882c2c9d8e162618029c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca85218dc27678719ca0d4a8cd8e9bcaeb944b7c0670ab171927c56c35034ad92bb3e6714d0f7c137c2b9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b68240ad193e95c0311aa501b3c1c44b20ab6ca2d2de1c56b65618ca53f0e91550851bfbc289206d1406b27047fe610ec01a86e8ba94516aa926b99879836dbb27a7056c4d54bbd19a44096d1b3f3e9956cac29e7ab95f175b9d9a0078da633f10a6fee899f400533f0f77102da19fb02610003674828758e23b5ec724c6829b95b8a6750f1988f431e7537ca9d05701ac8ae2034688082c5c20a122c6349db27ab958504fdb4c527b223b2420db7246a4a69b58085a3c1e6997db19fe17a2bc23bcd60b924cc393ebfca864da054ba38bb733b00fdf57ab147b922278fb132c5f5774bfe368dc2b66583790d30d282a248b7e9d43a562ba1892a985b75a7aff961762a05fb35b9420905bb8c4de00a3846e38ca7d71411e89f9e2c9489c597834c7a5315080130648f5347639184f315bff2d580ffd0227c9185adf9203ed50baa43a9174a7ae9b5655f2245a15c30f877bb7dcb2ec184138792738113895a980dca31baf6b5261e10a1d98ab660c066bcb05ac25429775c3bd1550d4a823fc96442cb2770751c812ce67613e48bfbe66a0fdba909317513220ebc3c55fa1364f318812199009af24f9f70c36f81b22b20be53208f0dc44dd3b6abb7236e1fd37c53fb1ee8c86810863a86b0029a58955dc73ec8a436112b5c3a75ceec356bbd91355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 1af07cebe18b64049fd34156f0c1f2920934c333ba89237d4b942881e51f495d5cc4e1607d128519e51b8c59997b6a0c1402df0d3b032f6c3d0b4c34d48a5935ff61319530ec1e6ae306dc8b30e220031aa5549b00f4142201aec84beabf37c661c604bc26825e96075fb2ca24bb539187e1913849f7b9d0e6fabda2304d838021de30fb367172a9d0d0627398f966685df3de86f3d74f501eb56755844eb64f6b739820acebfa24ee515d7043e259353c7744dbce3886122abae686e4a4532a5863f6e898d4fda096266d25ddc674c28614e4d0ad2d38ce80b6855ac742b6f3cba2602056622565b486ade99294683b7de8cf7548b630ff5a6b0f6d52dbbfb9b5ddfae1d98eaf68a43a2b33cff3dd605aceed93f539b3da3a070d30efc2c1e9fbe027af86d87c3b8f84a2f30fb6359570ed3721eeee8efa351da77c69043c19c695e46a5f9535338142395c9e3660aee95765ed84646d6e60cb3343b60a61a4d3cf65975764d735f6aa57cbb07c06ffa651932e698969842dc1709ba7092192154bfc55c3d6362fa419e38b2001439b41a2d149e8ac22a5d9bb7700570b08dc2d3b91f764b43b70dfc2ebd534951701b6b985ad3b3420290b88b42e50b2e3edf857ff854f1693bf0977523e012bd6332381a1155b64e0bdba2dd7cd68d408602ed0912bb5b3f672f8ffa42eacc31da8601cf43fdf187a673b1309ff1bd7d8392bb76f71394a596bda178273192746c40d34eb4f80888ceae88291418b96f333cd1b15d7522b21ea6b57f12415509e932814505053320f84004637e479d1c6a944eee6896c75ec69367beb5cb7ecc5ce284120fbd24be653f61cea186f2f7b37a1f7d2bef08b8e1aa006118232bbf8217171ad0c0a71d0396cfdb42e64a1d0705439e131be2137af000c553d68e7830e3a3fefd5174bbbec523df366b228fca4c8fd4dcb2dbee571526549cac4dca391de5d82e0ed17962c52399aed8ec81c86717fc813139fa35dcf7a4a6c1b110883a86daf45840ef4bf7194122719b50e0980a7098fce047913348755fbc1f23de982560b3ecff6b82aca52f54dbd4f3bbf308ba1be699fab8207dc80ba11a923d7754769608a88c98835903054e66d810341f9809cfab29c53d16b3a804b9b51de50b07e7aeb9e7f378bd106a594c74af3d60e6d6b466d6f5eefe64f7b71a6cc2fb6b82a5c44b768e89dda891891ae853ca43da23068556a857fabd5f1689adae488c6bd4af811e9176b868deeaa2ad31caf71bd6f4ce8ba595c47c80ef6a24aa4d950c090ba805a99df998ef6a6305f176739ef2ae0bdfabb999a44aaa72fded16b7806d99248cd65394743da26358a661d6283c44ce9b8ed089eab79398513f8ebff93ed127709a43f050a7742100941def83b6d526fb499216d04d250e39fe6f80b4d36b303bb6898bc06362734370b3aba94c1a6244a5a8c7caa9d282082514629a0f864ebb91669acc757f9d7b8aa3059c9e44c7f1925ea18c3c80d85549686f74b7e8a8197efc89d42d2a15d195d +expected_result = pass +expected_shared_secret = 354d86b389021a3196b75c6582927b3a005fbfee0951f34d9cd5c8f415fa50f9 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +private_key = ab150a2298917b1707af1ac0941acc5b6b259d1aae8f878bb0a37089b845991b203ee4c8f1a58cf9d2cc0059ade2db131bdc5fe3049e17f350a805c6f30479be91b12a36190a5332eca4737df5a32fd60cce222b592060add75a62f88d5bf6426fb18a944195f1ecb1babac1dcf20c39339ed45ac8c3ab582382480851107683102fa1914e753731964fdff686f0a354703858c15c99f30a19d9c281ae93004c718d1ca5452fe58183d806dd666792da7a76b0927dc77793396e4508200ef5097e45095a33af5683a4dd1a5f6878c1e6fa85771a990ea16f7a28034a897855769db8e4a9a425860fec7031d09e96b665f57662b2bb86e362c3f9a706e354c12423ac6cdc74973a0767d73e75f5739747433c3451f8e5b85e5311b6e009f79c00cc07ba26b74d512520496b1998a4445c19249729225044cffd51679b495511223417b2bac86cc242241f2b70966e9a7a03c3cc0ab526abf857dc1a140ad85825757d2b5a59b97b7f8c5015da02159d013c1f15491ff4cf64c564e50c389f6c85b7c060f98011a4518cd3b48c2df68c67f3497f439c11f8504e577cf49acfae704a2b093238520292602cc2138762d87536f6285c001d6975a242654ddecb5663ac44228bbe5bd58d9b90426c66802b466b21dc8d7a23893a953033874d0a93626c00b6a4fa3fe9eb0dfeba2f3e789aad8103ca153fbd7218b95547de700ca526aed4f159639c59a7699296486188c3ca111479ddaa747f99ac825c7593911d6261683ce92ee8aabb77f82ab14838db54149194b12791c4991181c66bcf05c67e19f05dcb658d8dfab09c180967311f4e2aa03d9b8218889f87c5a5680299a7459afdd69db27302d9761daa20be37900b971694d3b6aea8c6b5d53a686beaa478f2abc17c1c461807597148719925590c1e482aa05bb73077c017c1010ea576bfb5a63031875a23b0a019d608d64a30d0dcb39d750099d1c7583c34ab1cb1dd99a115547e3e4ccdf2a872e821b2330a5f6b30918226b7fcfc9fb4f37d8103437db12ee073a49d29a7359316f8d922f783797e49b8c2b6146f76c7f8a66838c86364a788d3c4ae67d02ca09391e8547edfe86ca1d131c5b96caf479d9562688d1238c6196526b17844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d04810311a28880247236a3761236b068a9a4edf55317e8841218441eb1137342977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e41531204bc0df8243f81367f4d979bf0125b84eb5d5df53318463102938a85214ad7355960300db40719a2acab9297381a6708391c78a8d4029487c324291a7e4a0945a806e0f24368c7a2af91b8bb155d04c557759228673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357be9227f9c4ce8b98003452c1d8d19c7a8332403a41308086346129d3f929b847bab1aa5d88935d816a708c6a5e41023bcd4252569cbc724a53df1b88909267a932186c751339863c8dd49cbe200797186924c26edb976de613cc2c46beb06b39f5c264716a76e67831e4198822d77386592c777a088c5785417b65b2e4235cc67947d7b214627d326ac1adebccc3a64017e004499a8887c4a649e443e74720f0b1bedd52b1a8eb78b3ac2d5516b7a3233be9448575209675f4a813120422684191d6771ef2b44d92b2ca3bcdd5f5ac20a63efc237ff9d99bb4f5094afc187ebbad39b8b9ce75902190741640babf653886162645a84262a24b1885c626403f23136707816acf28950bf181742c98347022cd5941b7b69e21b5cfc2b4c6c5f301bd32a2e7882a1e1a9cd94743fc86af0cd26b51b3512003cbe8628d299663da40baef443677033da8b8c21e0a0f12fb93f4d63809375fc877866394a1a5409e2f13b3e5011a2a5877732415281b7b19991e6ee0a470561b6bcb46d87b4086f18ca29c5fdcd622f4315dcfb11db2c6cf136b7b0a870ae89669ad1011477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f499435118d9143723da05ba8f13e5cca1813f91ce01092917ba1d798ba3481121026713be1889b58375e5c4f9bb0bcc5fa808e2c00a36ca575c68b1d232778f71bf0927c5f2092d0629588826d02005db9bc0dce456e2b928ec9fb9c7a138e7b1065a2b660c287c3d062144cca71e5c1294442073ad48afc555767f1bebaf550d520659496af9237a22c27670a080f8a461778aa42c6ca9a954c28a658c73847a586fc3ef266562240acb6978e026152b1149b8d426aefe37bbd263a00da05df48375e53bacf9c4c11d4bbb055666ad008736b9c323a9974661215495e032aaec611af0e6a9244c2bfb6f3195d5121edc3c0719c3fc1365c2bfc70d5c6140e6a383714a0931ccdff946adcf73993aa113c90aef03374e251ace73770a350428ec32a9ddb4aed8832526968412863966228644b9af9842c2e967957f10d350a3499876f25d157bb2812501c8dc95365f83bc64b6340fa6cb4c2816b31824d028726de0112aa9ccc9e0b6869099d310aa6e5b79609487e7a20a56ba75c45986f92f5a4d1672f3d99927a1193ba15bf5df2586e823292593c49321bac9044e4844a7a6bcb08309e2520b6acf20e73ba5b05931e29ba43b2000a48c72a5df05ef715cd8865cf16a835a83c271402071d1068a426839ca424cb666545664ea5e7461af147b9d84583285ea1a05a02732031bb0ba40b14c828bb0e82807fc57882b31d9cf509be7b712f56994721b55da921eee8ad45c8b4e99931c9b71b473a89a2d4821213a1acfc453a41784d35b522e93c2d994d083674c71583782128476b04fec71f17ccc65b9c83f52c207b08adb10824a505b6da8a78d4c599a5b09979d9491e1383ea155576730614fcbdec1a8c801b94083a0fb55790b136bc5f37b752f3a6c636481debc5da8892ac1b04ac7447953015e7251838acbb6e24b508578b62d7450c46c76272806ac407112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b5b07b861be5a750bedb4a909605e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983be821e79682ffb18553b72cf0797b2d2117add5ac0abc71cf0e4ca83c26d218295aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6124d18b9a4606305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb24c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = 6e4a75139d037fe938768f42f9de93f12feeff1328beb5a9f23790e2eabec1f605207994eefc2cb37851f718bae8b94570cb06fb35ada46207fc9a0e25d535731cff7ba833963352ee9feb501bb3e1365e85ae3997630c5b387271ed60ba872afa7ee2b87867aaa14da0a174f83f7d488ec12b72107372c0a31677a6e933144ce571955be7a06a7b152b6693a5f07ca8f90a0062ff6c88bf45956e13df2e92017c6e246c4228ff0e86b50e0e6224000a44edceda07b3e8d6be399da183ebea434db5e9e5703dd199e340b02797bf62b29f442e378f9b0d99ab7c771d39102ac07341ed6d823a4fe6094622e3a12d74f4615e7b216d4c3da113bf62109b12fdd8046de27fadd35330879359b0ed0085da5578a1330c3755572958001f25524adfb9fa6220e24417a7d1bcaf63ea1044a3e9b02fd249a2c0e281b2f9e2e18b9f7552f4446192b7b65f881954cfeebfaa3075860d1c6c4e819e40873a992b6837257ac50a7fe7e3d759deb249fec5755da72e4c93d2c412e316e22694dba50831ff7c2bf0a294ff6329d0d2022b3aa6a9791de9fe6face1ce67ad828cc0c6293a7e5d6bc26f58e63e025c757576e849a11f122e6eec09ba7025951df26ccb414cdc914f47584d443f06310e86ee20c303ef9e30e269f7a67f8e67313cbbe0b06d318a172d0c47d6a7fbb1aed20fb6da5a28c53277d1d38800593d571b6dbdf2671ff6802d7c346232aaea7fb96134d8d16ae62b07804474cac1b3ecdcd5c26c112bcc9f72a003c4931cdbe1c89158505ab8267e3f5cb5869aee93956bc0334d09b719d898685f04a70a32ea8b0e56aa6b36405221ce539690e6e85f2227fc6cf40d203d55a2de22c902f1eb16339191576f3dbbbbed0c2ef90a5e7fd04011b33fe9a0eb2ec1a8fad089a410995974f5b2ee8d72e80a716b2c389322a279a2bf71c0a563da36779887c8943fb2cdb5dc6396d459acc88d04d09d1d1f0ad82c8e26c89f48c2dfe104483145dfcd2faef8807c4a160fc4fd025fd35f188b55907556dc55bed560970e3046c4b621038194bafc02da0503f3a9828da90b7dcc73add69908421d8169d32225d54111d122a456092b08e012a3c0d8994cc43fe993d7501fb7c7be94ec4b223dd13f50272afeef76c7ffcabdb509f9c1f9baf4b72f9908cb5ce3770a3040557797f666c8927dc08608709eb97942a64c31a1f71ebd7066031f415034f9d8e9c267b539a3274196919959d4f919ad4068b21b53fb18cdcec7391b9ab46f401672a22f2302af1a5104088d9f6628f894a7e04a78b4666f669eaf906e9ed3c8c9bd7ac220104967485cff8df46b064b982a2b552cd521b477e8b8e90b5f1ce11ca9ba16b045f4dc0f36a3b4ca8fe87b1fa6057b5334e993508192c6b46c79b196012dede5a06e4655b46c2540a64ee40830c7ed1c85507809810086d5be4ea8f1197cea21fc56113e45368c6f3d590fddaffd2848481a3424c813f3047dd8697a6316611889a74c0b5a4fa071de935d2d473ac2a0d4f62ac009 +expected_result = pass +expected_shared_secret = 3afcfdc446f93a8169024a24fc0383692843cfd6b4854a8e490892fc35aad4cb + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +private_key = f80c63dd6cbda93b6cee719fbad6bdbe1a03f18b3379306ace5625fb38c5edac9c8c94525c85961e14a76082bbd760ccf9b5ac777088b0cc80e0304fbcfc697cfb13dcf1cf777325eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd2f07c76e8b7a68b92abc870b56202f7634b9b37902d39bca04653fad9a0e4f0be548abb97c7a1fa18c34cebbae3987f4b3c52a5006629159ac6875276053908b389d931bc7e2871751169b6d81c8d8b5f52854a3e644c5c504675d688ba030e9e78a79e7788522516ffda2ec9946aa9791a634b6ab6d04456003acf348bdcd859567a74a7b73556820f8dfc12e467ae2fd11025e430114a5a60d3b42bb43845721637a69596eb953ab7b3e3b28b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e8552bf7135698e15b8d99b0777a0a5af1b7dafc172aa6a4d69202f10351603771876c580a7d24479db0d804b6513a09281f291f2706ab128905663aecb0bb31a41046771449d12c335051a2eb50ca81ace90940a8a6a355b21a9c7505491ea3b48b5323cc567ead909fbdb380fd504c851452bd34f0f65a39ac62d922a3c50a8566edab03358745d701332e4011022bfd4839ae7b6745c66aca80abab8213369e299253b40a7922df02ab70f9723baccb1ad563ad20c5eb8a01ae564be24f40ce91a0f06ec68c0604c74250909d317f8968947a12ea297a279821f1b5377b02653d66897aa526cf51553c268481f7174bd9495da4b0305650358a637a5fc31c99ba7ba304c6811b555e4b1c2f80eb4223c54032d16238861fb650bcba24b127026fba51f5985476103fe1375b94007a06bc2ab048bcb4a78e6d3c748b141be410992733630b8c917f89960273740a595071824a9d02908d52d334373e8a575d5d52e96e5ad0cc95bf2c761ae577b9ef6bead33103e5033e0765d748c409f8a44227b8f55838b38695c5e132f2cb9bfdd7cb8522906e9bc03dda468a04012277417869277e2169c63112e6a8942a1c13aee97300ff4caabf862058b6e7cc16f34c79ba200853701a98d630936a8a595098c8b19820ac91f47451e011069aa688bfbf5ac4ee018c53639a1b0573c8a420c4619166b011e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fb70d52b3ca5d01729935bf7e4bb984576f2acb7466c8248f975bad539b2260568dfa34cf2974d83699761c95405943a7a88374112f8ae79b4d244bf2d683f7cc7a533229bbd8b5e822c8b3449548634ff34bcaeff25a41aa84a1fa1f52f486f89630a7730e4f81ad23c14d6906816a849810951727042ed0782ef26c31281c0aade6c9334a88acb917b781c4f16327196422c24541065b5e80f4374da0853d478625a68f728a20c1c82ca4fcc4d62744fa658059141221a917d6121187d3b621179aa8f7b7cd0904e6e0787f9a5f65eaa78011b6b63290a55542c80a4bfad64677467dd1b12785e6bfbc31c1f3d46db55c0a035604ef658279db3232c675bc0bc97717ca3eb71d4f44caaf1b07bddc90ae982886594f98c41ae7481562cb63d0b2539eec589146735490a4a87b6ec5cc77bfc0810627aa3452cb061a1648ec7cbb4937605471feaa9e92b94016a9a05f585f3c52a993a91a6db73c9ae6364dd2a07b6c2afb449122e76a3b273d424b94343b3bd7e7b1e1366204820819c8ba8970218a22262ca649d8e3223167be77d9a466c860ad7c320b227e873a0d68faaa441c0907805996d64f7759bdeed65cce25b367f02094714be404ca9fe56f6ad99e7d38b5396281314898036493002cb516878db66ab19e09478872c0f76abbe0f754b443b13dd5afe610c1adfc52fb3c82488984dbcc4d9850a0ee4bbc07d0051208c87914a3fa5159c775ad91a552c2fa2ac573787ffa68f456012af600af60183f97cb3e2936ef683fd8e2b5742c6de946b96f825cd0f4807640a532561c70600d4995bf8d2ca543db1eacd68d28b207617c23cd9a57bbf75abcb620d941913e6506aa0123f89c261ce9c39c605646904d22586643f4ad250870afe94dc950913602cc1cdbb77bb9b4df518d1a18ab0c5a25948302c0535908e70f84587eff169114161c3e646740893faaf6b37b42168fdbc494549776d528bfa2c2baf6a00a7498f403347a646c9a58328c59274ae8cff8b82787a29d67336dadd3404fb5509640c29c9456fcf82d4abbcd9899ab108a1fef872617c5ca780970182861c046a594d62757d33247b79e12873493634c16fa70983c9b593814e69bb160120b4129370519327ac2332063992af4370d9871e7a27d13420a6fb16ed9b579d1ca1d36a2094eac96b537109ad83f4df1a1d2e184c309ab65d75a3e409c57578214ea4035657757ab92aa930a76d251a1b87bc6b58f9d900e38156d73a1961c43be2e044314c89ea9601937c0a87d9c4b14cb9e79d83e722cc40b048bec5ccd038304ac0a65bf93b9a787105eb31b5be8845c5c57b9a9caf6243f54438ed84159f5b1b8b246073b1715b0f635e8078991118dfee2ce08887f9680bd4e672d3aa78df8954554d398d1675d785b85dd28a1675944d7597968f22855999f148cceabfabc2358c315076c6b4333a82520a8332543aa100034bb0a6776cd959bcb263074fc28956726d0d99b9d81a7dec14f13ac5ceb5b9eaaecb28e282bb517cac09809073c3d085718d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0eef3233cf91c0bf5a6a9279f6ad136808a9a3515b02e303f4da26f93264c5ab9010a9c8550b9076d6471c196675edb08223672c1a229ad31c05ebc4fab557f46b4bb37dc2b605a87b888a1f475516db87b92451127436eda7922bb45b8b8462122542de969c31622cdd62676a8faac5663a8bc2191711383ef4c1cd7a183bb55cc3c83b566e5514f233d79a2963710c5e5225f7b09b0b6176f451a7f77570b1c17b7ba335511bc3c3feb884e459add3a594dd35662419272499b4e9258dc9aca946ca80911999d455d06407cf9c69e814478a9f5151780bd754a440bc69925155fff0a675e0c322c69174c27cd804279ebd3260feb62c0e24eb63c7a042996c25bc9342c589c340e99999f9c5054ff35c760a43974096c5fd23bb9e51e2483722a132b0277bb24010297c4ba2c58bb286c49ed20b7aae98c5d9b0601f06ee53c1808e07fda53114efc6d36b28b906611be3a29e68a8da76457be5419d70059f7c329aad28692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 0739932f7b5b6ed0d363a0fc2a4829b0e1fb8c071b315c536b97eb6ee3c7e6b4022a5f6bc0770e3c48b8c0711029b6cb454b1e80e807ca35b55c06abb75fe24dcb4327ea8b1a7faa63d3de0f13c0a9be2c9bf101a293a078cb33489ee8b6ff1c21f5c4a42e9e9b16d4b860b0a624e00b5151b7f6c4db7893e485715b09e2964dc97740cba20650522f21644776c28b22a26ebd5e09cdcf07ec0415d3d464bdf785035b98aa1fdad58bcf06f87509b3690b327d9acb8b034a34f5b1061f58872f214b57d6e5451ab568c3e8a700fd8c95c82ed28427c7fc569fd3dc334ff8d9faef54b972da4ad8014cc22db0f1aa82663f3a8f205dc5ff8d1ebe30cbc1a590542bf5872ff6b0390345aa14eb43e06f52b35888915a0d8d64cabddc8194ea6a6bc96fa805113a0486643b79721735c0ff55d28501254faa73caad71600ff139a1a5d0d7930dc5d202512ed49e16f6fbe95913898688f3928dced939f2230aaccd2ace43276e0820c56bb7cfe0a1ed5d4aa4d044d2c6e6e895d408fdfadc689ec2b5f4cb24a89dd87cad740477ec812b2f8c9ebbd77aa73900c9a412c8ec72c39ffe3ec82cd65e036056acd5d37c4f45f25c65fdb035e1afce1e6743e985b8de817bf5d43778a0fc0edb3cf6825bcdfbb42c7cbb3a8c7fa02068ff0e1a1a3bd0eb3fca906a100fb92463c7c221e776d0bb43a13037d9a07b96e0f2c421ced63ff9f5442711a7d876ea5442c1d77639c7eb90d7dfea7a635f887ecaefce74aadc6d3cf722f75172835a24dea2664c09a70ed2ceab70a314f061187297428ca7d65d07e0bc8d161c5cb43b0fe2e3cb9cd74c9b2f3237bbd318c18d8058719ee0e65a3f1cabcfda9e10b8c685bece284a62d514c2e663b263220c29cf3a207066bcc53df0f734ca27f2360e5d67144104f8c13f5d12354d61ab96b939cbde93eec145c7332511127944a26ce2ffebdb03504982d25c86fb81bccb6441edf24d3975df84a0950ab9d28866c796aed23c91d12ebbc0a90774d60fa213cb5459b5e55f8d8a6d7aaa94973d88988832eca7cfccbfb9aaa7c44b08a391c6905fa75cfc6d7f1796168c33f8c4f4b04d89d8dba51c840bd0e08b2d660dce30b9880cb86841ca8ea05c3e6b1444a61c318578cef85c9cbe2146affec98afb815380298dcb39ee3913c63a3dca559ce4d5dcfd17152f68c8db381679ffdda0859b6d09866f296b9bb3c6953a4f3c9de9a6901fb46c5548cc150ed9eb30468e8473e308c9d80ec708f031dbf7860762a020702dc6b92c155f2b7f2af9147ba4012fb23290085fcd6a7590a4ee2542f8bbeb2d55bc81d49bbb439018bade94f8282c4f9bfee804f4b53782cd4e912e76f34839728dbaba746dcbcb94194496dabbc1c0a658888137cfdc6b42f6b8f9c6a83383ebab751e29fb29e97b5546e941e895f4316432cee99460bb680ea561000f268602ee0ae9ad74102f7cc0c212afc97f1532428ed658a59d8b80ec5f649726273ca6a5871d8db2184c52e25dce3ae7e2b20ea7c2532d +expected_result = pass +expected_shared_secret = ebba9a8bae936c829c1445c68595da96919041ee3d9b0fe27ca93db691146874 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +private_key = d809438c90aea78b897a528534fb009d716de8d513d32168a1537489e52255d00f49c424bf5b5db0e15a3a9b9845eccf287776f9700ff5bb7ab9f40ffeab7f148a9633546846b672cda9ab8a37c8f9711b76474e7975ab7e16675a8626f8648b605066a4fb4a5c255a0a39387b03bb7f618c9ed1b37e488d4b7175b593860f6c97d637a2d8761d3b933291b2ccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cab1bb1cb746ab01293a2b2f2638beb06030d476bcd2c335dd5226b7450f8b5b2b130332dc9210640c10daa5faac16c1381c2a0c4aae3174be4faa53ca9cbf29769084715d6f8c163a0185030b0c7c9621336a9875946fbb73bda9774c07615711451f5594a44313878204c291ab7550aaf981409d4d7cbee727ba689400dab7382605f03873f38566421a354b59a3b48bc8f62a09519d932af5800a9a0c6efd5783bd93483a0aaac7853c890c3ba18835d1a2e8f14bd0768cc7d0b951909825c988648f797f5711fbc654380e661bbc41cf89b088e1410f19669aef65fd817564a4a4f40281b5e16a69be2b503495a4b6b680a08a54fe0b80ae668041aa120c7a363e38aaf2156cee293bfd4396dcc503646acb74b9460142e4476807c058d72c9610e3cbb50a29ed7244419c2c258659b3a8a23e7e69a3047298378424b7a12df3cce34f1364732b292b105eee6a487126815bc0013d66fb7099efd4931e4301d570bcf2facba0b433b9a03147242c298052650416651db690ce81c268381032b17c429a8e418b7e2bb63d30b570da588cbc36dc3798c65f81ef05530b9043310e182e88bb3e58356de408898738c9b3c457faca42b9b81ed7c4118869d5153338ef4260006c6be294b528c779bd6c8ffcb16e2aab439d3032b8ac45216282346200cf1c812033a4f9667af842481d807f92245bb322e04343971a656087cca8ce9bd3117013ae816ba745888a4ad51a167a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b4f2879a727028d4a1c61900d0770f15451a01964366d8a6ad1b5bc520392d43bca270ccf9a72df3d68b955c4bed0352b3f78151c4716512097bc92f2cf0a2560923d01358ab1b5f8b7bc687f5c110b04c6512372f119fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494a01c67e232b93080d5df1542dd59f21760a24747e98e26466280c04d1784d9b581b4cabcac1c3dde1ca8e00588e0732f76b99ec844032d99ef65c8a9ef4a661e78a47b0542b3129e850647862132c208cb9b3986eb5b510ea1854300ee966b0d3bc09922260ffc96b894a181a95a41f1bb3acb2572475b3fe8933fe3902c965678b95512289cfbac30a2b159b8f2b3535e40881d81c204cba9080b9a7b23190965eb660754368955c0c7929e9447b92ac78e7867c1b4770596047fa820c03a11caa3c2ba48120e29ad46c289920222c511c9e18343ab20067f926435c6d6b040955f9394601b805e38a751bc8a1853fc05857eae658a8a7cad729373e73253e7728fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ed82b23f4b6796209d51425e9168cb22224f39f0695b668ae6721c79e07ee5d26233936d195b62b192058cfbcb0a5a73ea0154d78224ebe84b7b611ced7256d0726492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9a725c5278c21d896ca5d706e5f03d71526cb175ade2606e3c3a24d510b4d9816aa6846a77663a80f5ac0d364747307068da942b15cd2e02a3eed2818f9056d697897b509bd5048b178240c841580bbb77a79423996072f39497869007b19442f401009ba1a039c18f191cca42f9551713cd791c9fb847690cf6247bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32da070fe29411f17a420521fc69c0d09a6425a20affc98681568b8ccea88e54b8dd9f12aef4b3c10f256eb1519671091984a1dbe972a901bb4b24246d7db01b86665374bb6cb841b3cdb2593ba5c96e32c20936ecbc4abfd24af76158b36a2c752a9bba8946b34c414eedb355a3ccb87431221aa2e936b0bd7540e697142da0817b1b51314fc71cf4017f50544474c572c70bd142c676b69afba4292f5f19e88163f2ffba3b1685073c3bbcac825b095b5d259228a459fa7e866e09735e4cab8fa733d4db6a98172846397883394059c635d23c09fbee3cab350b9976c6a8a900c8e1693c3704e779049cd1221ce767651bc23755a3a49c6be0c314a8c501579f7a447070effe0314fa3687ab92090738434e55280a42f22a66eab77a2932b07e6857a32e31a527a2a909865e053a32148b59cbac224c12468e444916ca375dc204c600899f90ba7c854b3646f2af3981797afc4e261c7a93aabc40a93990dabc82564336d01b2447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad66161890325533818f845301d9311bc8035714a722ed9206967123e65410562a745fe28f90d50d772a9cded6354132688ddb1ae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbae00a91040456f4023174c73dd8a4d50f9714ad1cff718321677a6962587ba6ca82c341f02a7382be9715b41994db91e6d0b487207b9b660793e62470b806a7444b6faab38f48747484062ff443ae1da9e7ef41f797398f0527406787e00e197ac3248ee4a0e5037cf6c754ab9a24d08936e9d3313b99ac18886cfa9972030f1a40e58b25939a21698c434391785a3a98f0445567a9dbc0b4284d49652bb1862bb76fcfc6abe60831cac9aef6469464319411a30f7601b5358568b014e67a76ea42acacd7c3fc2f983bce1bc0667897b92590dc724b5284fecf7c36b3842c61c27af1a2f2ec95899591e707272bea384cb9c8c9409bb26d743faf196d3b8b33119a379d5cbf6823d4176ca83ba4e2a426745f346a42861a7b5343ad3ac26ea8895f24a379c449156123ed91a4ca701bd789da84ba0ed5c707d373634ab7a65680667191f806b6f62cacb4b40afdd649cc9d1650c3a5e40c8346c91b27ec1b1a957c778ec9c968c670fc84645fc07881c54946b5ab0b6033f45afcc6a61fbb99746f3991f5b827c22972939c5ff620bdc4b131eb393d108c56556719abbb978452ff0a12a1d138c9065c304c8514658193232c832b05b0b21a10483c6faab378c6b1415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = fd2b69a027c2fc20dcfad7a6765f0946a637a63374b349868b77d6b6d84a3e32392775e1cbc0d9f986843f3f19966f7a2ea83e4ba64b46efbab4c88649ff6e0532f5ebee8a218b9444bd815a44e2be4bee845a961815fc122598306b1d60c402ebb170402220d97bae5e04cce58470800966acc024c00c5e20aa3f1d4bdb672f1d4731cfdad84388c2e918191dd95d2b70ff1a5228dd38e7f2d936fc7e571d3d288f3c6b3f71c1219669c478a10fa46460340ef9c1ae9a4981c83df9a13d5b5ea04cf9b44d08688bf66e59670b9f13f1096f921604c68a44ca5fa79e12ea7bdf671fe1deda8488ede59ccedcdf265cdd168c3d8e9981f10fe225ab88f714d0c31bb53eac599fdfcdbd24e533327cd6efd32a39b24474da685eaabfa3f50cd290d8d681f684481036a19e741ecf16e4b59059522925ecac163083cc087f4b6d78f0452b429eae2518e7623333bc84bbe39bc85866e41367278b995af06e382d165c6957ce03f303965c94b9d857151840b1ad140923950c931b501a7f97c6ae2cada15a16ee5a7636a6f412d19358bf807130f8bcd614d29d8eea8016b04b8a9e2343c951926417fbf749f7f7bee048daa22d966f98975daf5481f3360a0ad80f501f2e4e5d0f840f48adf8f066541997b67504ad8aa89cfc3c12635b8fd25f5f2611c8b8bf0e88398846c9edf3ea57a49978d1fc704692c29165e6b0f4e8db8d298776e95f36dd21504d42f4ec2342a7354a47f4ed0536e6cb206e88e070a2d8a2c5ebe8e1327b1041eb34fe570b9af85f7945f9e2486966b5abc9edda49cb4d8603328f4a4dd77db3dc569894cb21b6db52665f86729c8def02e53f7051f406bc215827d9c82fb5f106a777f369c39c447cbaf4ed2efd105f93a46e5cfd346ef86af228b39f48c27625385f01f78a1a9622e58fc72a8ab21ccd362c7c27af6cd1844cba5cf0953f5aef4f7ce44e681926c691bbda9d1de170f78669546aac55260cadcb5ae44eee3459e3ebbeb14e053fb4daf6c1d43fd679a120e7da136d931238bb9df93cf2ea88b1112e46007c27164e36b1f8a0827d42a2950f5b58bd3eb1d643034d6c04970e00b686489fb493b8a68a87670d02e85b5097987cddb5f59286322ff9308b6de9a1c5766ea6ed47dfcbe40e42c4bc3a82d5ae872a82951d41bf062063f6f8f87ec5356055d94610ff915f930430330981af065b131bb5352e3172d59a09a4dcc84299ee5fa611f31bb61a011df04d4994c713a8774a6ac21b620c5cbeb7bfbe7e26f2478db2c105e02a194b237c8cef57867592aa3a1d0cad24c30d53be0ffc0fb50fc83e981490409b20e911e9ad3b1de67e51a4bee820dc5e136b26f9efdf38282889283f33f4d8ebdeda6c0183bbb27351f7869c3c59b05da65a152b6668226cd5bea860cb1b06de463fdaecc1853889bd2fcb98e5fe337a727524b7bcf3faa23aeb6de10223cfe128769025375e94f638c55d838bb1ff301db74f03285624064cb20142d9cafd33631038b0d0593a4fb141a48b9399 +expected_result = pass +expected_shared_secret = f063c0908deb2e61faa0c4c0f5051b2c8af7265060681df14bacb30f0228b3b3 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +private_key = ba45541ce7b3de134e6b17030710bcce09bcdba837f23566dbf1928c99cffcb674cab9c41b3151faa3078177b9126c7973e25687452da075965baa804276859b092d9d4095b5e3a27943776da65262511f62a3aa875b258c7929b502ad6cba00e3b38011c943310bb5cb24791a71bc5a2796d6197192d9594936089d88bfe976058ca16c152193838a3d7306b312f8160df15288f9063514a403acb76be298f5c92d65a90a0bcb28a4f438ea447a9c881808a18a2f5c3c1b876b3ae94ed28478fddc1e98a64fd797a0931cc4a18777e5d481d9e92c0cf2b5f5a58635b368cbc8c25dc733550774c0861795939b74e83a23757c212927805663de14a0fa00cf10f51850dbb4cdd7caabd5c09b2818cc0a09a58169e3827969518e8fc7bc8325b45656861a848347a358ef1155e5d43f7910a738a132c8892977075c9a19c1eb6399f2e7bf1dbab593a907bda509ef5b0de35a222fc951a0829a838591a0441294c35ca0b86be6fc02e1ea1b7d4004e5bcbcaa2a280ef37067d72790bb5d59587e050272ddf8b117286fe80c1bbf078e6d259a9b53bd6ff1b43a86b24adb27bbfa3546c179b8f295726ab768bc7fc8dc2a62715030d93581165f1e4a03d42374a31039d55741c9c49a1c807468cc826f0380b90c9c3f319cf1f73811d674b05c147bb2613ba56365ea04872b9244b236b0d480dd0b47b7797a23286269f97450e13791b205c8aa3310b72f3423b263d93ca320ae1ff04fe6e3bb703a6c4fc17dcfb6341aeb485576b53d1cab71d9049dcc68cf86008bdb6152994e70152f96c8ae4a0819102ba5077b26086b2dc6b04b324a31aeccb372cc18976bb9da42c8eba89640149acc544511546c5dd293c3173ef28ca92b85b86188bc6fc09e2725307a2c3802c6086f922cddc62b5989c5a6846496d2bcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a78824aae4322e1a69dbf64336efc3348e414ecab04010b9f7399310253679b48af3c23961bf345b35172c1d472f9a31274c730373a29154a581631a0916a21259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435124101e5d42ff0848bfe2169a49485c094226ec6994cb50ba9f6476fb2a39522a08145b987593f2fe67a2b2ccb036c4e6540145758c6745a389955ce9744cb8030bd85a838a5904198b318a4d265eea61c70e5a34156ba00a53f05c9be7f1ac214f6a75dc8154eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fed709c350a28a34873ce76f0fc7a4237aaea0804e2d3874d726aec41c3ac8e02706da459c01736b7a5e0936b3abccbebf146350ea2a246c225ba897473817f28c8d6bbb55fe98a48de682a91770edb1bdb190a0efd677a7fc29fc62690668924cb5887f4078179aade85c0dc8e3529862b2760b187b7778a56c6b026769e339aca5f8c948801fddc4acc3bcc7ff548dd9fc12cd7a394c24a7cbe18d3d22ae3b48beb295905b217af384393705107f33b02547822b0a2cb1b57b6fc637e071c0fdba2f87f010d0c81c42db454f5c7be69ac0069c33330bc40532248fd0b90a28908f7471fbcc543fa94403818698cca518437873f144e7e261e8465b3720582cf7706d684f84e618e8834f35857d4a8bbc303134b5e235dd1b2387a81c663876c5530293f99571b97ae5a299df0c012e9662947089c9f81687722fbdc30ce50689690b30932a8a3ce7bcf6a353bf988dd310a2c347bfe6b30999e69c455b9f472b9bca0216c84265e5d9486f6a7f1f3125c16467ae41b9f85180497b255adb06a406a13a221388e14c0de8cf73b6a952c2b2501644831c3700b7c273b7a3180a7641621f33b41c0f9255efec1025fc46f658c64fc89352c54c264b97e5a91c2386cd3790605127740da2076eab4876e128f3746843205b8328cfcdc65feb92c2d973bbbfc68fd7a46db51641b7830e73589f41d413fb571c37685dff142863078acf00043395bfab3589b0cb435981b84e54318ab46e398389b8e146cab2a9666330ec4c90a652a0f036951519880a45bf5d000d4e40c6b6554cd222880d0b91b67153c43909eb2c0926354d436c2318c593f9fc214b548e17245c0c9b83174a6783508b97ac6a8d8a88ecd278e2e52c3c9138b1685dabba2bb1425075b298cb9120e790afdcb9792c88698cc156ca5a789474992f470b1d554514823e87bcae52ccc872c951b0c24b4a2b0460f488ee7768d56b07dc79b3b4cc321e5878ac0a5c3146aaeb6ca123206b0c7b5aa6e0bec5d0a903ac9415da345af199cab86ba99234c9526e6e8812f6da8001f31337b8498a8374ae527b6032a0cf3142d1d34181a5afd6aa432a588ae1f644f5a100fa593f0ed2753f441ae5677484738ff694abcec58781b06d0213579f827fb4f97b3fc343a445ba3035aee989685e7b20be6103fd39afabc334417379bd666181925ed369680b851a54c41b6546b9c04ca69742b2a814763674abc9cbcb03e96f9466cbeaec698cb5c9acf814e90887f8d15bee556b28f50b739185eb7a5a06e896ed0048bbd905e016436477a68ebbab1e172928ac8fa9a8b0a0d999b135a753a29a47d0136865b0f382572b0697d0fccadc8a77c1b591bd73b639e13f9c21b6f0969b0aba3ea807303377afe0f49421b68d0712823fc448fa9a468fa000d5964bcf9a9e7fc92dece03bf6732a36935b25023b47fc94c15795dd983bb4531e935a19778305d0e8a75c2cc770eb46b6d5759df503bac33f0669c775729c59eb94d48223d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb0b1ae805b1498471ac1149d578b454041aaa2f5cf13390f10a72df3385c6a8a1f990bb946f4c888e585069b5849882788a1be27da0725276ff9db130519050b74cff69a68534222499cc61f5845a8fc0ac5629e0cda20d3ea2f0046b78a2267fa0187f15721ec53083018772097892be85c1be99480247e6e30aac8fa2c593c630b981e57515e0f7414cfa8b606d931280a950e567c93b319fd23ca1b682fc0b960dd309f80455cabbbc71979c59a025008462c0681465d748ff2a6ae24e86c79922e2845568ceb5063fcb81b78295b93a80b221ae7e14a9a9bb7182c1acf347f2fa73784835f3375a29ed05e4bd120a119cd0fda29f76a1eb873aa88d0cb3c661ff0d5652f2b4604e2bdb1497486687f17b8ce7a096a59e0922260ae99bb7412e306cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d3694543a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a15231100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 39c2464c42bbb75ccc9421eca048aa426c45eec971a442ce8790e14ca23260c9346c2681e7985e4e27e7ccf84f8a03b25b0604b9a64d943c2340d4818e28d774a3b4e04b6840a2cb81e542dc7e4fbd2146db158edc7250fc8ae2bebb24bf2b74c2cff7a9c5902a8963d576185576c4c6c4ced7c6f0878b67aee7ea494c34221d8907059bb989a65ac921c511c3b1f23c649811220f1cd528251a208641774228d513e80eb2ee079e9de73eb9774c2b51445235a262f166ada853256c6b53ec6ac3258059e4bc6fc23c6f0d9fadcbdd15d7f7f3a6a96743815ccb65117c06b2aa9bd134746b20337075f1eb45327942e22816cca244236514db48a46f353d5c0b0f9029ce274820fcf479c1600237028558b9acf943e8986c9f5d21af0bb5b294a421ad1a8a803ad0cd38b085dfdfe8f8f19206c027394d94b2fdf6d752b1eab11cd2ee871870d5f9a444077cd5f563faa1b1574b630704c01be830d9fa56eed3ceb9dfa8f384137ad76a461d17bb062b3b6a0325f787702c26e77cd649f3184a10ef5625402e7c7e1894071f8772331a714a4facbe583a1e1810e75c141440e1f6a903b6077783a2e2fabdb61c3b9a5deb1e7bf2c3852160aa8a366578e873d6d4a9f9b54f6a15f0fa3ca20146b608cb63a449656916b393a0633366b527b7e652eb2315e2921711125f9b2f0aaccd30474bdc2880bdd83ee40f94acabdba84810a02733fbcc1770ec56fdc8cac2accf15d6e739850b48616b7d56beacd5c0c30ee09530367675771567db0b05fe97f0e4f6244c020dcd1fe8b95560c8901cf350c9824b0ed5a4bf06ea63110d97ffeae97b0ed0fb5be0c91856cc0cbc4ee16d78d1fa3f2539570623bf53058e9b6087e252e86e0896c78e5bebb4dfe870d5d3a2d041f45346b559e81e24ff09904230d40125c17836aa20027ebf9fd40f045f9485582c124e01fcd22d05118ec6986788805cf0522e9b9d162e3b1003d7bc913d27c26a9171264f49db8463b5f69936d7abef9f28437b6caef081e1bebd7c9a39a43dc0a00ff49731b15e7f1467cc389b03a020fd94b90f5a491572d167ef6cffd5aa45b3b611fe7b9691721f4d9dd76f9d9ba3d068d8d9578f1e238742342a791e4b59f8271e09575a53f77ea871090907710c40973a8b07945109c1fbefab60add3e8ae3b783ad222db7f584b7bd60671afcca5713c0cfa96048bc3c52d62d73fb5182a70b499d54cb6286817cf85c63189590189eee2c81e05cbfdcf23dabaf7c7269a18b801597aefec507d0772f30e21c1bf49226ca74a8e0bfc334f7de59632b564a54aece295cf745784332e873ae704022af6732657c81d7037f9424920c1bf238921d6b596cc247daa20d763f61ecd3fe0cea7d79e7a6094f35606f19976e1e37ac8f81fe5c63e51129cd8a8ce602ac56d9315cc5d6c68398f01bed2e9fc79121db26e319257c40212220bab87a274b97784f932649517f462b05a423a0fdf88582dffa35f330a0c345755cda858b815b6792cb28b5e45c500f86c +expected_result = pass +expected_shared_secret = 02d2e466e170bf45d3e9d357e2f04c34cda408cf147e9ff7a6e8c715f2c88ace + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +private_key = 2d80a415a1b29961459e396204e5b5e65540a2a9ae9cd52d867a9e20952fc7565b66151653448353697b09723b17e3b1ef375a3e260a5869b579883fd1eb3a06da5c11e493f4cc9d18381856fb2c36223e7214ad78a178b2153dcde882451776478a4e06b392ce9b9d0310a5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc4568682ec2f5506f59742601c46db34efb9665b5815574518ff677be1c0991b644b5931b112220c6eee10c37c19316156bcbf354fb661635e42f6b26b07f9552d7b1a65d51c7eb6a132034bd755674dfc14345aa72acbb85d4724b2ba14925421e570543ae904f9bc4016bc0389fb9922cb12a393a24df219290dc506e501003c0ae8cbbc685a25a91147265207f93f190b12baebe7cc7edec476553762ea45e48694ddd172b6787b7d9719e89d77563c9c2ccb77caeb23d7aa9181b82b6cba09aef1851235c7986194c8322280b4192b94262fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391a314555674cf415292055bb39319dcaa7b07230204c068028b3ae7a7223df112032d60edd1b6b52ea1ed13b86231a1efb2969a691cef0d219835a44e907bb0cd2ce6da1442af1460f2ab882959e0862bccfcc6e3fc2bdb5eb673b218d6e9c5dc6461d8796945b614c81a68f9cf381d256bc1e63285141814077af5f54c2c6b487dd29cdb1d2ce08f09122d09632ab823cb00d86a57f8933743f347c203894d0043f5692a6e12283abfa1b98b39c6d638132ea4b94644e89a0adc35816be01a408f752b3215029d7661b554bd39abaa906af32f877cd4b28bcc217825ac897d06a4c233462fba602a81321db93279a19bf44131b86035db3c4ca911f1fa30146f9be0333650c3c24a5c85bf5e252413853defb040f8a16f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd5b18df1d947e171272ec5aa1137ccbe50ae73ecc106250c0392a41a73a4861acea19257be33cef406b7eac1796f605a709a4bc06bbe40867966e830e8aac19af626a4642a8447276f09cfba6486564079e1aa38d7e179d9634e3398b743a1812f02818e979b4434a4516c2c77672600d5b7d3bb6d7e3253189c3694120dbe2519c62c80558ac1d522855682962df611febc9f33fa27a0787501a42802863b5cdcc6aa81b964cc2c9b8081b63750a6358db5566a0d3229d2989e98199855a2448f54688ed2487b816f5cd651206350fbbb5cdd995a9db37b089caa57ab0deddc9392ea1c0f99031a42c350cab7b6f54c1e4acdd0e28d7975a188502fef055feb5889bf87929b6006562626335b05edfc544f10cbd927ab3c4c9e806700349b9a0099801d5948cff3bf0977a9691a25ac880d593a36d1e5436eab078bd9a6bf25bc3d6b5bdfa02aab06ab5842c440e40d430aad9311015a8767417b233fa8cfc64914533031ab39b845a3c50ce00ba0f1a586053768ea48293044f3a831b456320600404761c7e826a0b111ae37db49b31bb3e9389bd3e354f08879906996df2036ac49b9c773af5fec5375519ae7b8c61ce475ac544d13a5b421b8a686251b6d1c64f8a353406248b0430c8a3a308b600d0c9506d6509aac9a460935645e451e4c8c85a192c91df27c17c0684baa6375b17586f8bf1ef12b91615bd08a340c58629cd45f7a392f10a04916c249af956b180bc418b8a95f66b2d0847e79d247b430812d682b1fb91879faab68f25602579bf0d895073780007b7d61940239913eb217cb16a63ea08b29656712a21a32c754953335c29e769df17125d84c32b3250ec96067b975bf524091ee4013a8b67a19a331daf38a396a765f7820a5e3606a734f5ba854d1e6b6e70cb9ee5b00d4d18d928921ebb8048e284a3a05a3df9469ec53195180ac9f869a8e8866d69019e9730fd6e672db024b6ecb4dc55729024033703b6fdb7bbeeecb2345782815843b7b7664627cad52038f98db605fd23d24080f809a276419c876aac69977998b1400395829656c97be262e053197ead738d9bc995145cb2713b5e181223e04497c8114ec5a05384aa31cb84406f93365d7059dd88db8f94a8f068fcd10be96e32a0e926dca518b3fe9286a755f29d83cf667407758141b2011fbb1764d3334f3a763a17cce33c2816ac79ec4cc4c2d842b004c352aba419be87281779300708bb20143a43413a2a55c41e36444046a3c021a4d7818dd146d1dc335c66152866597aa69a44f39a2814a4830e002672731d93b7fe5f77587b782aa279cc9807d6126392f812e83662d49db231dd3060f882d71d2a0a4c94adb3784ba1785187423d7e8a82f379eecba7e6f6a67b568698ac3a2c0b096b015100bf9acfee522a0192e49880439cc1fa9b30fb7a10544e1867b0c34da981ce6e660cebb8853545994454815178c60b04dca7073531aa2a5095f7b8578cd9889f3428a7d1c72b8fb320f304fe5d23a4291666bf7aa1afb5086532fc5aa347dc29279a4484261614f2774c81374aa453024b68d384b01565a36d98b751297477a61780e98135375af8ef68359332826da01ba6a73d5263abc659454f57d83172d0e515d3754270ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cc407bf027df7e2a505db531d47344552321107b651fa4e47d4b389c5825e02ca1f42839ada4d7eea2ccb24a74e34672bf1bc4f33c88c3603a3fa6ce87aa5cfe30125f99e81550c19b58a807ba8a586415c2924a6e467ca8bc85a5400f910457e8b9d74a11e2668c0f1a2a1d0389361d09900ec6671206139380ebf9390b2401555ba0a57fca36d2742f569a573096a2b442c5992c3fb65271479291f097cb94589fa15bf73cb9319d93860eacf1cd1bf7d380e03587ce3faaeb6360d79574803b5c49841b74918768efb518ca46b26929f68639eb8fa9f73e61a8b69b004cb5d9d92cf0dac9abc03171444a03409714dc1514931182701c19e242ae73b465af335c8d3588ff468346abf76604b6ef887a7eb8e8b44005bb55af328155af7928c732e7805010cf0a50ec68e29acccebc4a39e2aca10084e2543746be6c81d482f6f3c1fe0d31c6a69329d783a1bfa0b43e289a2f843c71196809ca4b82c75c59c7aa5d311350aa55e89735d9c34e6982d17c033937253d9778ca31a14a9894c5d801415056552c410484970cf2ac86b374644a37976ec4a123c0603ccc01c6c6e994514f13885bceb2f8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdbda43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc6467a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = e7beaaf8f14f63e4b07afed36ce1aae517129415537b323347ab73d9154cebfbdf51a20e75b6625635ac552fc88f30866afc1eb1347e7963d1d634b9943db25d14e21030580d7bca1422dae24b0be423349735509ea2b756043498c41a893055f9c7b51a5783aed508a6888416b4f544019a6c0e3766024d804d8c067660161cc17196c98fc0a602b89be5b089e669efe0ad5086971c6b23883567df50c0bdf5508dfc8f62888238b34a0aa1736322838d00be507cd0476739a0903ba622f42f13478b7a127b43799324b990aee9e8bb603c3de3d679e34ef6f22a8d309bb882e61c04dbefa54004eecf710d80bb09d091ec716ad0f4392396ca1c06016fa1acc111308eef78eaf6f4ff1b87743fb7629da989c79f58b69619aa6e3333de32e8ab0df5001b12cf27318d45ba24343a6a1ba4745b3b702ca2799b4428af6360c526b67a2532ac2dc488bf386e7f83fe5dd4049f03293af0459f4879d71483f07dfab14fb1cfeaa7474b45d8a3acc91478723a87a2a16ba6fb69865abdff0e7e18606fc60613ed6f1968bd36b122f345682c2bfde19d0d0cbdbbb051651708d839593dbbe010194280394947ef157a0ee77158398b0d98f7a1f78a528175fde7891e40d7c2055dcb908862434c3875b06922cc3332f3b4acda02402b35514445c90cfaec583aac99100712b3fabbf6317cb7ab57bcfd7057e53580c978ae42be13581f547273dbd53f1c168d0acef9a38b29bc0c35fbb4c534634de64271fab4d9ec326cae654c4b6d8a8b2402e970dfc76a7d31a9649dba063ea5377741216adf8fb01d7aeafb80e8a4ccb9bc9fa2b62118b216815a6fd7c2af7c9b55e666cda56e03ee8ba78886d8b1a19ca0f844d5e2ce6f8ab530baed6057782af9b133a8a01a930c1b900ae48017283fc91f86e81ea77bb6e17c8a00d0212d2c9dc8ab39c90f7bac717c73fc6c05af9a1436241c8c8db904bd2c1d8d2b6df8e83d46220982c0debcedc62c83d547df31374fa85fcb59a4819ff45b8aafd06aac7845137c0dbe64f530c37ab877729222541303a13211c0a9b315111f836fae49fe0c2896a92f6da3786887a42b0c339e0312f6c2849f43a931b5041fe10e277465ea9f6839aee65ca2144668151172a781dc59d7a559f73249f6f0399a80049b15aac6de8b46f64100f31b41c4f0a2d99268b27512d61f69297761bbbc9c61fab51a02c83e13f6b104d89e9efc1f77c7926585cc84a19f3d17c2dbf16f8304fa942002d781be0a3e0aa3347731fd19571700f81cbfa0d7d30208611345023193885bcde430f7868f3f64fb941e8b22192f9974dc8bcf523a3f7c4f9fa73dbbbee9a5c32a1fd7f9e172f5f1d7c0379aa0987fb374018535d5e3c288e855ff53472b5232bec315437513d4905fe3851cb8b5c089da4fd4cc667321e1693a44e598d42ab61880426ff3c27d134db34a7f5f236510cc3474899657de4432ea4b878667ba9140d0257c3616d140cb9b501b0afafe5f2f91ca5b85a528fd920e2c9a53fde5310ca5 +expected_result = pass +expected_shared_secret = 6a5b0842c122ab6ee251399492b061d2ab3e40843f4dc01c12fbd5bd545c600c + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +private_key = ca481db6775f3d276a56ca0e60ca79be147e63b6898f4b814c69a06f55111c9824cbc1c109a01a7baa259da651a1a51d60bb358432550bc1aa1cf3656e0667d726c69a39ae564bb99162c824634b8b8a706d82175bd9657ec09a308b51a3b429822667a5135fe4350a8b3ca10e8b03b6da0bbd616ceec0a08476909c6182ef0314b284cc3f43c337307facf7b617348779d7493ae0a25d415124bc5d9134182169238cea1a46a3001a8165713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcc3032e4c2f1e92841d73859c76cfbe245193816d87c12bb3f12763174997760d6887a429a37f78c32cc1ac8facc587aa235821c254a2341b7c6bcf8b52c908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953554021af73c585b6ef248c07ed23116baa18c845571823d25cbae0af57d4f6ab2473b5919cbabdd7b4cccc1be89150cfc585953389172590edd61c3885446b500495247aed57a9fb1140ceb6b29f7f9a9f524106d8cada3432c12468f9bfb9a50b920cde85654c25249350f6760293ddaa28c771963497c4c5230c05862a4391330f54cadc3b0c92b9798f5bdf8b21016725ac8f565466464c2033872684608111248fccf94c61337eb6b1a9017e342c29eb2b148936119797fdb2757bef51a9a2601a00c6f0547b1831b1ca1118cd2e1cdd601a0b491c588cb5ed88ac36ae183848b9f87264cc5b020b2e965e5b89ff74c58cd2b338177bf1350afda9a74516a5845381e5fe132b4089506e8cde6346fcc760759592345927c5c6a97045b0ad3973e806778759b35988953c80b3e7574b7caa225c744372ee3042e07cce978a3f964395d40176aab7905a4bba98250f594c5a96bac41851e09f897df0376a89516040c1f8fccb93d44ab474c56913826c9e2171ef67510b53eb31153fc028b3625aa7a353bbe79cc76d393e209115dd00b5d6c98f80101705544604351cdb87715618343bc3fa227c1e9fa1ea3989390b02c59ec9174e5165239427592a2d973774ca62dbd9410164bcfd95834c11621f7da54dc55c44c594785fb0016448f2cc39a05e01d8581658a2410caa630347c3f0f6c86f344816bd13b3a04313a730f2de9bb50659b642353f6463d2e2a1a78b722287616cdc266b01098b3544632152db3b23938d67c63e51949496e13182326d5b7d70b81d90cc6c5d84d4e5907833a7a76d3850ac4993a696c4b210dcf352a32b4c83dc9114305308129bb4ff73a91d733303bca92fc0083d95d32ca54557a6ff3c42c2bab46ff913e1d39ba3f6092e30ab47f9985c7c439448c92b245259d388e291c04de427f378011ca983b21b2ba8bea9d6eb36001ac4fa5061ee1670066f9252524848973782774cfa795a2285a2669515d4fda7093bc54439753fb6b4e6b781eeff574155b2438e074b332417d751eab1ba1475436e8fc1b670c3928a3553d2bcfd1a59c46ea2542884f91f98a38d42ecc026ebcf91258acc99a50ae1edc88b90c98b74c3961b70759f39b3c20175fa80386376cde2b66dff213151b800921ab6932b45b720932a540c79cca0eaca0a9d5bc841c3acf3c08096c0446326114f05cb09745ebb986ddb76913faa6a20c8da5745f754b89a990746ef771cf07a6d8109998936b282757f344a1b00b851eaac27a9a7fbf480d44262868542128461598b5597b10cd3a2a26e3f941a9a4719ab2033fa1181ed08e3247bdd396a834e43f5700522cb307ff4b150bba9d8b6aab47361a7947b7a04b8d923202ab1a3d6644be06bc6c1e0735d5d92821c5b8e9b9a83c343d0c456b181b6fa566b0e83602428b6cd33405a95abb623a73299c5b4550a7d6c31d6ef81473489bbe457e744b5d1e39ab74d8a051951abd01a6cff3942a102a33080327437635c1c17966834340c26654a3f38616e5eacb0e489141b14e9d1b15b7fb30927715273547999b93ea2a1ca2189f5645cc4889943f3ccd95496b71f392f78a82aa1a21d66382c37154323c0616804f50125d6b0698e5dca3e2d5658ce153bbf57e4b1908c92587b8c863ff4872e9e1963ae6c971c6ac3932bc974b9f15e5743ec069ed203c3624a022f9a7420ba951425a432b46c5e8bb666091d6f223e357ce96c55bf067b3c3f51abe70abd85a73a42233800853031313ae9971d280b3aed18489e75cdc16cbb3ebc95a8c97a768aaa6c0bb0da7943037bf2b4a523e33abf669c262941f326b11ec6bc8ef51b0666268d6d433b5190bb6996f65925a7eb0761eab6906178be9a923d1c61c0b7683cea681648c44608217d6dc86441a8f423a9d1c288b32ebcd049c15ec151e256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7bd4145e837b756003bab223ff1a74feacc2e449b5dd9b5777d62ff0e20e4b395821474ab428aa2ea219bfa169b95039616598dae0b9282c69ce329b534bc7aea58e17467b1348b1ab2a031324bf835c985371b0f53877dca53570199b23bc4d70a9425a32b54749082e794e10012e9b458205e106da807c03ac3202a4350050815487626bd018706c69a6ab02fcb92621114a16cacfbea02aec424f82fb874800c61cc23bc6618ed75674a70a6c43c4068e2a7c9723a054967e4dab09f337695bbb01053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd7661dfb0b8eecdc2a4134103380988758379d0a73b0f348b00b4b13b115e74674aaac2ba8c2a7ff440340b622b5c0bce05cb601259913c488fee540d7c058a28a0c28b856ea800d26a6a26f8bcde7d78298314cea6056b00a845321a245949a8c7c98d9f8821f1264c658a8061a3014249b7e522d586a54ad7a12ad805544247d74058bc9ac0f603a44ac5199bffb69c1570c4076b345064ec00c5ae0d6a2308947593a84ddb6133ba40577b7b245c20b5d04c5d08281ca0aa10da2a358386d2a4c048c89a2402c9150a7419c0a1aa17562fe786f00486dc82a9809dab08f7b16d9432981087b6741269424598eaa99082525d5db0deaf1b96f55b41ee209f57aceb895babc38828b712724204744834303c496b7171fc458534f46892627ae54800fe6f11d06b6af2b6b9259144f769b1f16c0586c9caf01f8491251907fd213aa6c0bce5b08f060124fb99822d964c502ac49c16ce9fb17eb0c91af559947c056af77ca687c4f675c89be35aae91584cf82202734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff93588f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = a2e6548fa8b141a9e4657c41ef47720a20e1c548a4258cde5bab41b42b58d69e30b6f887f84c676f295266398aeec9b24a7650d710e0211ae2c76b9bdc0c6bf40e057aca0adaba8ad028c66df5ee016268a50ec7a4d5300e8fc128e6a0aa5f781a4108831554b2086f27938a26b62a3f26fa4c9315da5d43e5699e7dbf424f81f6069e3f9512952ba6958108038471aeb5f8317c3767723d1df5f982d6d7a653a561da3f0f0c4f1d8268770230ecb039a3e269ad58cf4e62732eb0a93cbca5611530371675faec5d5a22a86285b2edacb9b79ab07945f7a7d1e759234957a6bfcb47f13853a2d2062543bdee3b833b0925d9410b0fa83f9849cfe70783041a5716842d8d19d26c0e04c9c63fae13ea49197f2150c5b2e59273af8e4c45603e0f3d655e7e1d442e9e6ed3aee5fe0434104a006a3d5aee9f0af9593a9f9b8e7ed1b6b5f4c3be440d970d1b447c0343ea4982ecfc262a35c1567dddbc61439447f2b72fab241632b448e553c05d7e7ace39338a0df928c4a1a47d9230cc89f4f9a596cf5e08d5a724b85ba10132445bd8e5a91b9547bf602036ab50e31d069ba9f542ed462fcbab1915829ddfc05ce4801758d1792271bd4c68a475dac3453aab9ff0271600e80e68dec303b25384bb61febf82822b46efdbdae5a789040f0bd08714dc06fa8fb051f5a74d9a54be204a51e0fa41bc6cf8771dd70ab54e328381b581a809326331bb37783620dc2f7e9f528b7d59d587d3cef8a952f7f96a2bdfe89d33ae7714f3c53aed207c4cef6495ffd94be2673abbf7f3d3a81279b9342ba3093da3f9d280d381211955bfd5f84fab0ee430e63e4d485182e4152bcc715d1bf917987ec85888972645515ac8b2cf0d47c736aa652221c379b4c622bc1c9696faf0895d42d805b971e340291c952b931fcd85e7e56c43a120102252ad42a258791518677f37c5c6c5be67beab159d136304752daf06b210389ec4c07604bd72da410934fd08f053c91be2bdc410fd0b5e5886e0bcbae2033d8a6bfa579e24f2bff7e96e70b880331a4a7211435fdf9f78dbb758b1bc977fa22d3e09611510f84adfac85b151064796623278a0e791c1c38a6854fb344ffd786a8f9cdee2f9be606bd4bb55f57892046fd0d096e1bd577fc71b74c00bfd1c7c683f77f50b57eb93a93fc5a03acf43002dc35025d3731fc2dcadf031a2a0473e2f7530eb5246fc53f32ffbbf94494555d077fe6b01eeae398964c7a7412d5cfe03b758105bcee79d07524efb52065d94f3ebcc34357bfebb2cfacb51481f5368f33b4db2d1a032ed9283dc876c813f2787e14b55de96b6792e73697db908388499ff13a7d14f5a343b8fb37278ec1836cfccf592d47d7d4942332a6a2453af2d82df45fc0ddfc7b83de2c82b28cf7df01ec9171040c434b92f3adfe59dd5243cc80e76bbb95747a2672ea343395c79bd7154c8d6747f3a8cfc93abb97ea2191b0feb819d9649cbb4df6fd9c1835695e944e7815ca7ee52952bfef13a9027598dd893749909d49f +expected_result = pass +expected_shared_secret = 2486c0a6cf17d9635dbca1f8395784cde54dccb7df10fced92183f983478fac1 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +private_key = 90d7129b79c095b3063f53058a4baa74c262a99c822894254a050409215fe67773c26c7a6dcc739d8406a6055b388204604c7b065c0cdccc16fa880858a36d6200c6cec473bf81b245e09c6e5a55a8d8314334c23dc14fd6a9c011a2ca93753afa8609320b1d01fb9a2a4263ddeab8d5a00c40346b8f84afc7b945f521321103a5219b533f52bee42256edd1b9a526013a00ce07d44ebfd66c0bb67775d1acde4aadb7c98731931e54f5c458264894971df5d0ccd93817bb77a2e7d29ce47aba205c0971f34096280cc725a3c22a4ee24a9938cc2fcd9a670272a463c852efc04388ca8ce86a8e9f63273aa208610c2274709c55922ad371c197741af0526218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0ea2075bc25b797d82a8e0385ef1094d0a2b1731624308487991a7164d8a507f2390f354b4fa3a225d5a46463145ebb57b98724f1d3cabf11ad4fdc00bfa267d8f3107ceb7da37c060aa23e247c28ad0069d30681e37807117ab841f23548caa02212afbc1bc54297202fa549def55ddeb5ba4d10ace2650511366ebe9c1d61fa9d5574c86c0714aa523cdf946e1fd259148a7e2ab5c21884314e3b8082bc210b5209ccb6b95eaa2ef62203a0b707bf9c5db1a155169b07d41c0edb9709744caaa36622f189773ad7a59dc142317454d9c81d55d1c637876f104b6836a6842b87174290125505461eea77d63a8dad03c7941b69d7f66e434922e13a8182fcc35e51c9ce81978e35818504cb32e4a6dfc777227a5484409a38b2a1e2243110e84d024b1fe0e0bb36d4aac0622152599fefa177b294bece391d47553983e420de5462c72ab588b2934680a399ac40ef35a5e8819458e0a7bed1afbb29a446ecbcd4e45a50176ee201526e314cde085afda30226039ceb41a14d87256bf566db30ac77acb80b29b1f9d602e919707c96863304372a353771e1ce994241a12369fbf42bcb4315592724cd5085a589b1b4ca46dc49cd65a1247178151e455741c8b5d7c9cafcb75bf27a5b4ed05b22e932b1e3bfb0c93248400e5485486e0c39fd5ccec680c78e6137be96823deca37c6306d31c9142fc03ec540ac0120ebbe9bd5237583e1972d0c4676708ad35b559fb89bd872428a3e0504350451dd65f58bcb292c0ba437394dae55e6df13a8f41827939016a081935d1788c4807a53a011b89528fb60f386632e725b163e83e105324c3914f26f389dac199a926a25a02624d9a530bf0afafa4c5ffe6a5ef9422e422019ff337d1bc2fe16a07d9a046d183137d477dda378e17a95fc7e02ecddc0d551724a4f36ee7648c9aa771bd15ae29b7259abb63d0983917156ede6557be445735ec539b2199f9816c562842627cc83bcaa659075f5179abdd1a7056d27f7dd96a6813a940a9321cfb1946e95c16836ef028106bc26a3ee450d8e569eeb23b70722bcbf828821648b1668e6e47869afb16c0e4b827c4cec3c4c9948a6c7f874968dc80160a811cd06d58a885d033210341a6f7907f53a82c98468f6bdb7cc7a60107973db0e70f9a387673234d6665019676215ee4597c65a13a2636cee74266f373a4e48bb1db019bf44ebfb0a5db55c6cec7b63c0721aad84d2b6551fa941167c78a0c105ed9e5300a24bb2c8b2265251a38ec2b9d05a0635b2849a81a2a7c6f2660504d5602fd2763046820ca168d70b76e35b9641ce46a44f2a394f496dc32353c1a84302381e8d74ce4294a4a260a5b0704797567ae831d7c4410593cb7b9ab74d2042c84805c3aea6ebd193a927c8189082333b3a5e96857e3970be7daca4c884d7bb0b3b9c250cb4135d0b8c90ae320dcb3c423e8a6de79ad594240ae7aa036e320ad8807ccb7a1bc80c704c9532960864a9528347636b4123337db7e2de37823c6ae084418fdd05ff7e904211924fe5a370537762dfa012a2153af96a46987776d245fdcb9434d66aa10524a3ca74e494c9de919c8e23c3ff77c58cbd1cbaf5b8a69803a32e23959b2a7d9f808689906a0985aeff5a8464a2af64ba053a3c18d89b2cae3814cd712484288abf7655063c403f635d7a2afb9d804e2e89677131bbbf7009c981548036726d25f05f004d605a24b7c2bccc4294f065c013c8ecb242d25611b5c82bcabeb9e578758f2f3ad3f087bb6813db1f3990c867a2e679f47f074fd012e87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c870364192c555b81af58962ae771df477ff421a9b46c6e64bacd1a8a6d00da4d9507212c910ed2c62d199c7e330a11982c514f27aac092a5216b13ad54beebaa4049065a68d8ce9b1c969ea01599a71d633197bc33c2f6f958f72ccf14c7c09d973770f170f1f7bb9e458a00936d8677717f4a17655bc7a7ec56119779f7aa391d2356ae3a97d7ca04971cc2515154e148568c176a659a8decbb2c5c449ccd914d3cb7431cb3a0a400a8c7b59b1cc770c5bb5b64e0932c61783c9979d6cbac042216a0cc5800ea160c8c8556e0721d610fce13992396c382e93bad1514d780cee046525c443fae063c5882a01e5a73658a30864b1d6344a6cc46729bab7810c46f5b480d309a263e30461769a55a2965ba6ba0b44054f211b98c6c2355150acab81881e5ac1e561a4bc4b39f9902d1027e56155f5d71b7ca67415185319ba769f88345611ca2c20b233dcaca9ddba42edb204576bd028a79bfca57c9dbb0a54b933c970de35032b9b51d00c9922abb5106897cb896065fca846aa486d9c27f5b616e99ea0ada711729b75d86669645b9a223959b3c1c2f3ab6536d74295473c4c055aef8c2cd2d321e9e73cbb872698b3a60667bc768014332083139d08c321157cff1481f259ed56a7a3ff1717bb64fc951297c709a4ae3c05fe3910d6507ac947f944b970070570fdc9843a8a5ba564141f80f1654766f93048be6297a1cb76c105a7ba3ada06a42ed1ab3c17542201712f11824766c07bf14685ab0a9f69a15ad6574e59709d2411b37b509de3b7fe5e8b0ac65922df23e680c33141418f9551660467accc0c794a67cc530a5b130b4cf1c28747601d26983764acbddd30e42eb96125956a5870142574419977209a12e09ab3c5e8a22c1c5252527c90987a816b8830a757ec44b12e2e2bcbf19097d02b19ae47cc7bc99189370a1aacef36415ded82fa7a63be809b515f79f06612dabca5768201c59e2c92eba6d13b72c31648ee1d504ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112ce2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 459624a950aff4a380db1ec8f9216591e74b0bfb9448aaae1aaea886c781c414fcc95ddae21c478a1f1692ae703b8b80008661919cb910ca02b76b9538fc9dabc00140c0d790a88245d3a3e70823da64629066e039361442e60d25defc22c16e33f910c3ebec5d045bc9dd1a763fd42a9ca61037cbbccd76c64a494c0e2b58cc2a4e8c1210001cf0da6a2595c30b36b3cbde8d08dc0de26377f0a428a35ca414cdcce0f7e3d4b45f0a32b167587521e57c1e677a23ebb39753f1fbdce24a3a8316d2044165d2aebf018dc0e4fa4e89c75477ee02ba8afee69df1720cbf5db1d6658b7fe8fa0c5672bdc7af5fc691cc184fa80c9a4000b37b7bf8ab63ac072309374277e8b01a08b6e717a4ed0c0357487cd7aaa702bc593b6669e63ff8215e684049ee8466654cc978f81514740b20038adebf7cabf9b21dce2405726d7ed474f246867edc20a729434fdfcf2402675d4622230ae94fca7ebb4a273380d53416d587fae57fbb7907068f04ef35d7205806ffbb3ccca0ae38945966b7303ab930dedad2d02a4cadbff6c991c6af14dce43b59c55614d970568bb8137b600401299d2f7bfcb7ecf7b11ffb26a9d0c3b753c7c58803447edf17acf17e77d1977aa8357acc332662bbd3f4a1396091d74203b1f06c1993df3e34da20762a0bf8bbc1d0732d8d011d0f09264ebd1d1977bacf77c4fa030a4d346f152e0f1a132ca1b4f996b548e93104ad66593d8fde6d3c6eace63e1d0b53372f6e0bacf148b0f4bac5fe90e7467dcf62682cb70cd550257445758a6e159e092ed1952bf66e1be065e541e32954a08f8e0eca909ebbe54d4080b1f2e482952d912a32592aa089c82d7621d43ef59640a910f57ece74e5ee0af8a6eb59836c266360ef293339b97c194904bfe37b3462192247132a2407e27fee0639b4e3ce3e62208d0fa299d9113e3430d52eb295b170320511d110f83c05deec70b3e6fd864fb15912ec7e5d358ef277019719bfda9eb01e80b98d98af154aa22604988fc246fc4e1a1a7cf7cff87825ac183f5333391f32049ca0b09d57e1a2bc983c091bf55e048db026372f7cf673bcfd5e88d36fe0faefa7326a057caade1b50cad49a2413f9718f1a01aea81de054c0000dbe33e21f9081202f5c5e824bf240561c2f4f50763cc9718e66746da4443604148be687dedc2075fbb3814d7e0a2d79eb6695e7dcdd45ad9afeeecf58590ea21b1f78e273289259afbc7f97ecd517bbc8f33dd95bd9ba0da7b8e72d8ab1f336ee0dbb6b0e43612f87d558ae2315c91abed8f8c38c2d6b00df17206ba9752a8e958da506595f2c65a53e767d0453da2e70dd14c3beefbcd32fac60fafb379b67ea1d69c0febdac6558bec1f7b190028eeddb618e0aa70f4c65169533eda0a5f3a2e35cddec4d11508685278ba688b2e914ff23997c4d4b4d36e15113fd7bcd644cf3b4995799206e0d2f87f2fe1566b7e7ae721c49b871a30d16ac0cbccdf1747333745a91807ae6dc9b272558fe1eceba01bf5b68dc54d73dafb5 +expected_result = pass +expected_shared_secret = 85690ee044e4d8e0540ff984775b59bb5134383c4e229e79e37d7d77632fadaa + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +private_key = 0246c2025246911b525e6c3421584bfdbc83d73ab936e76a26236a85215c78db7ddd010c2e038e3dda69b5aa2e9f4997d8589bdbf918be1c046cd518e6958ae6925146009d185b53456b5e16d59257f20cd0f6677535510d02602d5ba5b61c440fa07fabb1b5fbb38437e90522665776892ef205a41a1a2083902648844dc9d65e633266af871481f036a2888d3fb9901355397f37875a4494777c781ec40478d09a820204a4115701d25a74b4bd91676ea6391fa160617c80cd05b0a80e040cdf22b29978ca55282f2c40316a35433dcc8ff7cccf4280c0b11c548b5cc08fa45bd0760ce03a02f25689d0f057fae44cb1574c42e760cb331c2ce4be16823dbb2870592ba844f30dc407298590a088425e023b856e106437c6074547260a856e648cba07e51a23e70d7cc65656b4692ec24277f04905c4aeeaaacd36341c705b504cfaba73201c2745ab06b056f1768447981e0d676ec904698edb230f369190d8c1dadaa5ca59001ee8a68c302f04298dc5700c56b2b577d89cd9a585b239089847cd3e96ca80d928867b27f3657987724ff9031649c246cbcb4673f6cb8544150c9975a13938c89a68cd0b6de5237fc8d2b7a6bb94e0c0856f00b821636801e9ac84f35276065ee4108bc1d755c1c428566a1ca3762d050458dbc7093567a4465453ab8656272a3c03b4a3c55929271437724471d5d4926109c9792ba49d117813948106d27c33069eb3c40aa8370b79e23f35934ac28666fe72b43f722151f3c26c96cc3b6a40d9e1876e55970f252811070fefc00d70a009e4871f136a08515ab239c33e2de638c4260d0c89cfe30b8f8e5927f2c59fea3947ffd0bd636b10876c3c387c00e15469b42b80bfeb8681dc7715c2b248ca6fed92a9399b72d1023f9507229593bd9bd936a0f6abba09bc3367782370b60d9cbd0e8b3d5744101c8ca97eab822fa4cc399b5be3195cb1e3c9260030af60bbe3295c4de898c502543589142cf48dbc7505ec9a9d93cb6dd4c9678c1cc0a082c5631a255142603dcc01fc07c27d628d89f09b473816b5d5171c18a3f9737bd6d3420d4bccbd3a5624a2686e54062ce4696e061c83bc2586f1a618639e51e63bc6c64825eb50d4f88334b29145bacc49e28dd564b7a578217fac230ad00a44f3acbf8753aa572d66e1ab9198cecdf9bc722455bd267faf98424eba4031c3bbec8298a9388cabc6b3beec7a7fbb1c814811117a9d550407c9e6099cea65ece641f69454b6a0ca9bf86a3dd472f7c0a7703c6a5b25464c0b091b29258de673220857878434ea14cf50054fb2e63547e9be15107beb7a78cd5c00cbb1462a0347e72b51a15ccb5c333894aba511295b37c97c7f4c2eb6d97219559b40a67310f457108015ac1b8e3ae15acf85689c4058ec8a0bb18b75615011f2701bde8ba70986b39d3368e1f978675a49fbe8509f1239a1c88f1df4adf0ac8b68a87e2a403373fb808a7b1192371c7e68b80854b0e4335739090b953a2b67999f9878a32415b78c22289eeaaefe3298fd38abeb6abcf5a55bca388004e46375a729cc45926a7c3e3bc8b4e2a2b196aabe5651b642c1cb50f666a1bb6da4d1cce8c6344356a68de044214453d03b5c7a2912329482f244226ae33507ba8fc8366736352380b346ca39a936190f09576c5188c5e82315e3532f34d41f1b50bccc42c1138802ccd5b50a7846ffa7bcadd91fe757ab7fe30e873ba233e13b21d25461030593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236218f199c3925142b53500291a3164516fabb941f98f0daaa1e2d619c9622d649a0408ac02d5ccb9b787c1f9b196da37020e362ecdbab03cccb63b659c6347104074b1f8254499c8452364726b1294669a3a24ac8b487752175b30cba68860184d5f78b845b107beba80f8750475d059dad57caf827878b926facbc00b54388f24b7b431347e334ffa046c45e234124c958cf66023dca620e1400cd5c08b89554a474d7d04086e5cbd0d051c03c4580d3442a575255c833026bc19dd301a70367fed300ef27779d2a49819a370519c7fc404acb3fa441a931c67a3033799519c883bea134242f35f92393dc134bce15713ddb33e252b991af10c7134a8acd09408c8cb2ada36bbc25224e8867a4138ed9b4daf403a477321614b3ee5c7bc2281441936b0b05513c1525421871d007346bcf52d6e09b756b4529bb5480aa3165e617cef41720167707f35a4415975a62114c7918ad83bbd8905a283d14d22b2400cb29fb1e102562cbee5a9c10929229f8c60a4b153c430a361812e75b244e4c3954a945459f735d45572e83b505030c13867c720567fd681c539d7094f5558dc5a86da79b38049b0a45a1259713af2c1640ee0279bb7191f0c0ec59c2f91184ca70a2e8b7576ce493e32f2c549c4bad6c925039c4c57114075281ac7631ff4d94ee0723c3400cb2d73c184489aa5b440ad470cde548f2f70903d08b9b4cb6db68a5d4fbb049a5a9727f50f9e6c59295c62bed7182ca96d6093578dd014f7eb0b121ac6faf917fa9b47f6650c6c7336d8848dedb92a0f70971e456e9ae625cfe266b1000c4ea6252de1ce20c014bc161fef405ff327cddda37be4919c2a0c097d6995b0eb743ff66a548307cee1080a13841ed12333e62eff081514a5915022c550c6021a27889bb0421df3a709ab2f9f3b0c0f6019fa8810ce3a9c37f53cd651acb4e5bc1d8b231f373b7a4ca6723a9710681016943f29697b09f6abfc1c60e8fc4c201a9ab05c260d2452c83b88423b904df74f425a9b4d116de0d059d96779d61017c2e984c2bccd6159c82dfa5ae7bc63e59304b1105ca054a71d753e7e583742e715bfecc80e51245ff53c16854ae0ab41c581402221cc8834a5f4556a84c19f6172c7c80c759299a42c71bd67040a29185a45c14b91b56a4af9178e0bbb0c4c197549b5c9765a8874686c63445dea7a85d43ac4d0b979b4ca13a80bf8db634a163fe3f4327210a7a128716b9805bc1920dd322b15c74fc722a126069abb8c95bd090f84497d832a1ab72358d4193b6542bfd627a139374404dc1998416f46054d1b4b538e778d6d0507fbf5571bd01ce56362164793e58355366495aec80eea35463c4044b202451b3604d6ab96acc3617acc1015379564d6a5ff1a6ae4d802712a94422a99d90988206776055545172b0282b5162b479d748a2e9d22356af11daf2629036665eed0642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = da88cdf0e629ad2c8000929d89554053e692132ed02ecf7f3947121c3da49e64e1fbf87f48d8a99818864eab9fe3b715165503b6adfd94b6587c65864d0ffa31a1e2bdedc66d2ba36ecc03ee41520af6302c4150a1ea1bc153edbf1a8736f3d57b22e309118019a6262138f311055e9b3750cdab2b9fe95b8be05934a61eca00f64aa6ecebe7ae12bcc6da07b91001fbc1d3161ef92592d0fa8a86d2a5241991174ba94a054f1c975b16bf36d4550ccced94a96f52433846252043839a01678167bea5a5f613eb41b4b33707999e4380d10097d089a44a721eb888528310188f6d9e642dd7677aa1e19fc710c94f645fcd2ce7514d69ef2e4650c6df9034475f6eada37bb02a268150af7b5181db8b5ab7242d601e4bb2ffd9d508d2988d4e13b5ab0e85094aaf296c8ea577d75de39a08e2bca7e3bbf132d886a2965b3476f04541e47e883e659a8bfe1f4c16881c70425528c5142a389d0a3f96cff2503c77a40d5ed881597fe8e5b9ee4d3db92cbf20e97aecc5a984f4d14445a33c31983353f9cfac3912150c7c6a48a8237f3ddccfc80fac8c8d73e4e527012170b3f485faaf8dbf3ce42f152b16bcdcc40418ec45e78beb00cfa936f31e16626278ba94e8fc0589abd8619aa057880672509a4344500c88f05210705220c0ffc327e73a9751a2e03606d0400d6f3c5bf4405ff0be6dcd9629acc2817b7bd28ffec361892bbcffd220fc3d9813e73aebf0929b814953b3d02a5d5000ac52e3a81cddc5f64e2666d4c86af23b1f45efc634f18f512ceddd5cd52fbcc04805306a794a61b0a502a6eac8e069e3aedf5039fb6ee62876795e874d6cc7cbaac232c73806644b49e10e5d69b5493e3ee647e7f92467cd255da303031270f8366c6e39a91143f92b9a803fbdc42e83251761eef40928e447d43e75abbcd57b97c207cc35a66a64c81e81a6ff33aa58e5e6dc047912171b53e34bb3ada16e57c2d7aae76c430f764b672f60e7691ba73fc1c6eaa57c2d06609ae2a6ed311c6479c9d3c8c12c4be9ae17ea146850f5676464a63d3c688c485e1caaafb515bb7ed4ed7f3d47455002eeb53c6282ff810ad5cb2bec2c5e52a6c6e5e8227c4ac72a882c45c9b2b90262111e58280f0cc6de4c86c667bbac46151d06966641e3cc67c86d06825c3c53bfb03a2505bc5731d0909d384ded3669197a2668c9d9c9baebcffe8a489dd5b6c42a3e2b65b236a9bf62db7342b0dbe07a04e2b8a53e7d4cbb520e1a56d25f427d2bf61a1cfbfe72e6c09a286bda114642237d6416053fc077f0824f439ace9a25433f57896157298f449cab005f4ce8395a904a3590f8940212a9c39c02ba42fc6dae73451e48605f2431d463c2c26f6050a3412c7d5b16a318286f8fd001285b28934f956138d7ebdaea7704451dea0641687eb19d87b96dec22f8a2ba755a62435a51f9246777923a9430310f529219ba8ba0d948c6c6dd13d2c0ea6f8c921ad9a3b4d2c9829aa9571279984c2bda818a338f3af9ab411c29b17fc4caba1ad3 +expected_result = pass +expected_shared_secret = d179d901a0570bd23aa52570c5c233a2240d4724e81d98c9ceedb74187eb75a6 + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +private_key = 34c91f6ec981b1830501d8969f8847b2c6bd5d5c43dfa044c43b551e610d5675bb7e7c9e393b411e69575301bf4ef4c7fd0b4b59e213905a254eb5540aca856c370dd28899541b725091c23907c04390ad32a56385075f42a7545672544fe177b74c7ed99507e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d5201165a47391d21a7ca732fe9b3455c44ee4e54fc3a6518d51402cd5a2d49429b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5cd040245543431c0d2c9091376611cfdc2eb9181b21c8417e3931aa2b1141c1051cb82aca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac7524f3855de2b00967b7bee0668112d51ccbc139fa73374df2685a3cc06838b150f92a64c17772053de2b05cc4d51832b8a2b8428436d99e1f2484b127ce0d861dc8a11ab0b0019e0b3439733b36a7a600f4638d820ba5624b445349a86465e1b25de787207dda0b629cb472d415a42a8ba191b76b5829d4d987a2b0c235521c187a0baddb603d755eb37396cdd57ff76276ccca997b00cd481587cb8728830021dcbb8478a267b744a5bfd08b4acb2c1e726121996e55b60d40f6975637831c392845d6823d4b9092151149992794f4ab29d4164a44239f07c365a87ed9786af7a57ac0bc0d491018007b6bf7705a21b082d1e040a4f4c25e329ef9a8518956044e7683af94728487a4f95305d4e15aad45c040f1cf9c442c519b2aa47a4dfc29063243c21f8b838171701b4b73516944efc4b61fb5bca63c3ed12a123f55b832e6c312e8bc48f145d62953f5901f7530068f2c9c9f51ca8fcb342852936d414fddc2c04f551c827071f99c7c24c991f9c97e10e051694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0bb1c2d3e859d3eb03c0a23b290518ef88ce1bb02fe71399ef71b380ec1aec4c7c6bf3830c1b15f7718d0e471d10234393d94fbd3305abd09cdf070a0abc09d7497d2f9b939794b923eb3f28b40904a53a05216a526132d9f3cc64606b40f26434142645d79481a8316e8cb0a9321a4c530a0ad139ed5953168a4ac864c726874e1366ab09a249f251ce5b1a7f5ca60ad66375bfdbcfa3d7ad23a13649c03327d409fda64581cb00a696557945c58e96c1c889be648c4885958adea79ab212a0bb15506bf5635e437ecee47b60032b4273b8c96806639c87031b6e23b71996b4576626124281ae4ca0a8fc081e1c91667967b25f76c4f72624cb29bd0a865fd67a4dbf14acc7a09871bc7adeaab37b298f12b60b6372b741681627e4c8346c0d34392716ec173b1b711b1c0a1d010dca486bd5167223658a5c55bcd0739dcfe30dfcf9bd8aa45b3ca0b5a90243547767a1843e4c87922031819ef9249800c6db8b0270f9cb8f2624adf4199741870b0630e1bb1b325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310c51eb565baba36be54f6a3151a104911c38ef78e61f1654ef35b2c836c2321a52fac710d6b03811444de5b8403569c8ce0444ef615dad54ae5649e68ab437c00a2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee7c23607c0683a2826fbb4bad4a58ff6e3bb3122bc8e892a62437ce84445f2e82b495c9730fab393dc6f3b36bb2a63759a79ae27b162250076a608522440ac1e04630ba766b4c256341c6ac967b36e6934dc58cda15621827b9558076361192e89708ed88a71826a20e8ec948b9c7915566c70a7c15a72c36ecc7a3cc644eae696022657c53500a0f13a8ae50fdfa432d8d2530999275e5b9c1d341fb34b8a5a7421b7d290cbc3218486b555c92572bac8f1085f058a87fd48796824844553261ca11f06978a03f3a8d68657c22064af83166280af52270e004731d20b18982283e51ca3db7a2679da6fb0aaba1e75a2d283add699a797e1be93502c6823007ba5b9760a338768615b671baedc6a6a6937b9e1c35575776a4a791fec7751079c6683ba29ea28bad199175b9629c44bbf219cd88a19f1089aa551946e58032a9c9dfd29bc4ca3b654f494990cc02bbb8e1280b54ba3920ef98903f171c27a5c0fb679c8e84774f22136e89915a534d973733410a96280a3207407235ca0d81a636a35b9dd628dee9a64a12918d0dc6d4c600989168a163730fab8c78e61a57970c16c813b791a0ee9f625c438ccd1a9429a93062c4ab38da5890188829ad116a6f1564a43a2e4f3bba3712207b65e701995c99b29d691c86bd9844af2471eb5cecd934f764629dc25839c809432e395fd8582cda980359246eef0637b9771fa5853099007f173c8598164da69c8e67a910a50b9940b213547815e0589326b02ff21b89bc4200219652dea6ccd59883e29127e2abe3787738b124d839a67e02195d64989520737e3aa99c6822f2c32249256c45455cbd931a5a1fb27cd56a21e22b51c03217aa387e151631cfa445b2b77ec90ae01828601961ada8a8e6192104f02ba5064c4efc27cf2dc3353fc98f34bb947b21ec5235fba6caffb6bc6b1c09a783ab8ef14c4921a28a3896bac07ae8ba98c117b3624e01ed0496a8c649a38a33fb679bb535a7d1960028ca6c8ba825178e74f0e50b5d74c2a9119b595b863d0375a3da173c63a03d8c60a8d613cc08064588890e3894a9bf4580704038841526ab84e27cabc8fa4cad6dbbde9b53017f100778478b86138fbd6be713a7e695358538bc4cb5a4fff531bff178bb16ace5a295ca0340985f34267a3a931998b29a36935d3b13af0631cd37777689ca0b43b9208afbab88ef886a8672b331224c66c6086b8b15a8eb86107fc0ae260bf08f970cdec98ece9a197751b6996258ffb6dce05306380770dc63498e9b5d65acac5a179d8946b27630525b39c3755c070a120c9f468ab3aa8b1a48848081b888baaa1156bd600733be887abf962c46107c432c34edca8e549977d9a6f7eb77eb9974bb353896e8261502820f599257cd9c2852328b0fbc5c2b98658d67e4a636575a46e074a1efda2cfa50a0594b0a421661d81d95a9ae0ca1c037532ba7eead089961c29765c443d428bf20767d1f08615e85d0c08b0fa5076e297143249283c13486f61a4d9d39780624055d6043120a510d4a686f9b490c74f2da782ab42157a00991be019e093a509c0c00b7c1e6ab611dfc4373c640a2f488e7632be1289666206cba2b096a479b2140c6aa301bc448b13b6839447c4675aa1be46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad865f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 3a289f96c11468b574dc8fba9ebc8e41d2cf47c1e08dd6cc9fad7519975af392d0f0608ff43bed72346208e0de7a19b1b5c6de3ff343cd5647afdc94a8d079b12207802c5b35fe1152c55cb37d5457835251f7d101d540c7fdf80e220bcda0305d8ab89f1105436071ef5c588addb1753756710e7ce507768236bc4637ad18749522ff2d5c238980ce4ff37d820ca43330e680d8cbf149abe46c8c856642191c8393e2471e3078f2860e57bdd8fbd5cc1c696e145f57a179a5c85393e05604a76c70342c2f708ebbf150765d7f018101a0b13c808886974202ffa8fba17e7579ed9a7ff1a97f323d8b3e00a00e19803d2132fe804248b86a13f4615de551a0dc65e2f2704b24c9b43c7efccb42b5ad4159a4e5b74c87f7df156874cbe4fbd91c2048299b27181aae40bdabf64657427570badae13bed38aefbe8d7f130ab272562bc3724a1ee05c32004b3e446cdf04a31e7d1628a6fc3c0ca547d7addbf959ce5038f5f6ea655df4d4d2ff45e124c5395833041582498fbdac6fcd27624e015f652d16cf7d8938abec77ba550807c598dc507105e855ebc717c88082481b92f1687bdb9c7e486774693a9140549dee7b387f28227a83968cc61715f68122e5e46b847056586fdc5037645f44d9654fe0aec4b4132d15056a2afcae3b31f0a0deef2964a7d039f61bd1920fb47facd8718d6ccc429704b8dd2c830d3c168405e9dd90b7a7e1fedf9c5ea36126ace5621404c6806e5a95b1c6495a3885c6c6d62ba4c5122303ee901c69c14f9383e51f8b565b56c1a3d8b54f048dc01a0193ca5af367e4fb92c47a019551becffcd2568ddc7d57b66b3cd5449cf3841c66d901e2c9cd6a9e93831c7b9e78cc26673fe3a7a54c85d3323029e5e9a3bec39edf9d4c00e5e1d939219842255c35265066c534bff32f32887a3a277e96525880bd4bdfa97e26083b4342c4f6882a074a14acfc1985732f732f96072f20e95328d4f52be6f3ba7d3e3972d6bf5d584ff7c5385af1b749af453356cfd6984591269c5014f717fc992b6ce5ff945ebc98e6df117d4e237112dedc2d8f1c88adc466ee74f612564ee5d49e94cf33470f735c3dae296e8fc1642c08308e285f20729c39256cbd63b664a375eec8a04e6e9cbdae34d5f27350d3313727c7b2f2612657865db4364551d315d8849a96e8525ce6e100ba496f6782e11b5d42c6da5f91cc4bce2c77c65c029de1f67f6977217d9256b70f47c4712260a8102a110a94bb3b7e26dade7b0b9cd0c158bc95262f54087eaf92eca527ae4cc835d443ae7c58daa2eddf7680637e42da68564168840d87bdfd5797ba90967299dc367ed48cd1ab7f1a0f094bd2915a9508ff2db189ab6aa2f7d813a9e2eb219620c8a1487993417319254038037c080051a98da562a0176436990937e64d458be7f34ed366aa942d169e486b163cb8153924d750f1c152759f36672de638b3f3afc7e569ec52165887acf342123a9d88d6c795ebdf6f5cafafa6c2a6e03249c33a74e2d12eaa9a63a44 +expected_result = pass +expected_shared_secret = 6d574af7fcb241fed8763b2d0a352870baf85ef686e90eea31f8500c35945ef7 + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +private_key = ab4545850434076342eae8409fe0590c34955e860267305fca05c347bb3e53bc714e3134a6e9b338674a9aabb02f021d1a09a190757f03d573c27687f7e35f2d77294d10cded732218395b344523f1b704b27689dcc286b5c98217f239c159ae5d655436f00517a50c6dc6b7f4f111e7f37a0f319bf6acc7b0e3345c9367b2a2b8d9d644936220c0a817fbb38ceb3469cd55c661e1c58d06807504443448c4e53204dc59c60a5153494478eb4056c9a85967a42ebbc287afda51fdd6b84b285523d41d80a56f7a68a168a4527d902311b18d5e381cfdd578bb7924fe687d3aea5607906815181171a727e4dbce1b678762a8b03c2a2bff1635ca85332ae90f14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83b90bec27172ac85154ef27b91623841e188d76b040f958c38c8a112c05b54103e55a159de0954f2477e798a573339508b7c2ac3872a623429777ba3179060135c083e2198d1e0aa01967c39c27372a1a36a92bac3bb13ee3c94b1f0391e2702c50253dd497f16f39bdcb9c68ccaab6312084884b113e70f38555422767f4e613b2e87affc01395fca37df0a1aef74263c1001392732d9d1047cc7c6fb910ae6136c33094526876a113514f2918909532a759617dbe2c97e72176490995dc82b663655df65324b1996a42150be41b2a1c90f03b2a6f04174da1b1cc7fbb024c3c972b9714300c683c28a90f48b01c28607922c3ed25601a609673481b365544b7c36a9550ef20c37005b0e395a268e90ce1a5271e1421b46303b80cbcc81e2894d7569e82c2f5d8c6996c766bc505976628cadd84a3f468c67c209117c8254bbaa1ba584dc2661728a69e959949ed6c9f1b42f01ec8e55614aeb7168cfbb5e16504eb9f585c7789c48e59c17b5975c444bd6e32a6654bce298a605043bd367400c14b1d8e1a592a034543c04a44c85711aa66c807fb07378fb525600c19d9a4a9a8c920ba7db0b1d912a45f2b6d518b469e9121d25cf40499196376d3d92827e1b96ae255aff288037793c7db07e1d15533c07162aacae3255c0cc368e2fba3fef09540952910eac0fb2f3ae376aa666fc97a3e122570ccf797c79ec575835e0be6e808b3cb1b72d8241c3679bf15020b6a63be65b95a2c9147eb98c6553c71c550e37603e6b73c877c94e7b603a22eca456c1409d5aa049673d0ea17c123b1835692253fcb589186baa498f39481c3d0640a4d34931033b30f26ebed6ca9c49ba6fb219d6dc8461937284235a6417cc9c0ca0ad385b04b01c81d5a7b97a34977250e3679ac55c3d76d83b1f7b99dba039dc179147223b5d6c11fc9109dc062a1e4b7c88c710c449320949bb4405b28ea2c04d48c58aabb46edaa58e442f3ab6c9810b6d702855f7ca91af71b0e574bac1040dbe864ddaa76827874839414cf3418d1702c6f368a10714cb25e208c8a5779f639837a07e348841a11714f41399da175c49678307d3634d6b9921880fd43ccb8d7842e5f34ce44a4923e7ce6b671c7a989aa748604d147ce7ac25a1533e80ab321b7aacb8d523a3a6298beb0cfda435d77714993173d080827fb07b7855769eba987696afdf58231f361d61101724795296a2499158c8e1b50e4c900d65c8ae65503932dca40e058e8192cec2a997cf12c8a1227567b12a1b21bb31d3198c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397a9133d99654e6c56e7465d9b98bdbd624c12e36c62b60b6a32c9086a8eeb9b8919706f4573a33c393f74bb51d5609231f1707e152f23f36f6c6830ef28253c8cb81ec5c27adb02fbda5302212826f0b88aa4b4d72a509e29cb1bfc8177c019c60598e693bce999aabc4621123415235208e7869f62aa7b50a51724c13da2db59d5ba5302c772f2c1820fb0882ef32f73321c17f40d019cad39c3b12c57c3519ca0b38366ac4353b133c39262be6ee47ecf660286f6ca8eb7090418aba0d9833e22b46b761fa2872fb80972b551809c02775be07c796636a2c619fc748b90d28e1e702ffb0653e250c8c3759178c39e42411327a81c7e7887b21915a5cc032c37a11382c4d9186221b1c66afcae8184559910201c8baaacec62bab984e080433b9465e64a2d987028e9d9090cb2c41753742cd77f0998c672441e83d45f2d06c22899c2136362271b731f6ba3965b32e2517463e627aeca0ae5644bb8602f7fc599abc120aa111e2e549a276a18d2a92c39502f6f9519ce76c0bcb514e8084c7122a321479338f59ece08a0acd30f0ad68f2091855d5980219083398a6c0a63c70d3743678a1c0202a69dc526ddb77e30b779c36ac2575704ead94ddf1661a38b2624e733f2e2ae18467ce2c3083b75017411390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae1c29bdd6656cd75d9ba453aa115a32745f2dc1829881a9f4d5cc2cc053ab79b89d107e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b102378d93990cb8280b21a5d5ba8415c48ec17288044623a9631577c16639922978258cee0b6c51bbcfe3f70be07cbafb7c58111cc7f2f922aa023d5ad01d2d31a57e0469ac428b6fb88a97d957ae22beb768c3cb7c9f02f583fa2513db7c580d2986984314e8b346a06501d8972e31ab8ef5b983e9a15e8ffc624d0041fd523570960e09e57d616a06297bb3f9d938f5655628b06c4f6c4fa5f8136f8cc05dfab7389237ea75aef46117bf1b67aa978ba622491260128e743f28f95f533b708f3c59230b23faba96ffb5c239b32b30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a0812f59d9b5812916246228f2523175242cd1f432f9fb054a8b52d824349dc0756091b2f7c21e2a899362157bf9f631287b90d6c80fb55b1469273f79892435d031b62982c49a1464e2274f815f56f3b6f8c949be11388df1151e7077f603ae592623e4259853a2b90159344b041aa29c8afc5074bee81959102e0c57a761f1b1aa65b1dcb66a18bbbbe12b2b2942a37d13c77c77b2bde758eb1901f74c7d57d373a47737d6e23998e35dcee70983359b4162c7135126e90a807604034d52add3530456b66f0da64453150afbb67d67d9b359137c2420250c279a1c537ab06952e4823f09372198c253d5b71a7e70a1c48b1dcac3a85feaac35a11e670b2840a57f2a7c77b6a00cc80a282f0a1c8160080c702d619a6b6d68c757306c93a5b21ba8185b1a46c79b03c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dabb8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef457933fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = 85c0bb95389f7e5801345480ef8cd5aee04a6bdaa435f7198c4478ae8a16110b5356cfa6c84c202c0d7ac5a13fa01a5b08611373ad41db6bab6783bd8cb03964d27ef42e9ca1d123ebec7f32f21bce5ee855a48617e85ba20ec6da894b582a88367ab489b68628ebd5195d7ce2e969e5c4141c9295b95d0cb8bf18ccc65b9f6b36ade0ddd93ceb7c0473d2f1abfcb788d4b92262b8a220ce9d99ac358ded7f108c2c0cfbc54fe75f53cad2f7c8b2e1d5be8e24bb0c554548421d821ee1e8c6187c9ba06ae2c7d0ac58062282a8082713dbfbc536ee7a032f018bc8d85b0d01c4ab2a94ff97eee42322ed7ddf060ddee5803bd30268c29202817f8b698e87e03f5ed608a194d7ba1e89d027b31a4a2b7e23df5553c9194bf5dfa9ae4c3428d31b4851adf635a5f772e7747da34ac8698eb78835258006e4dcd1e2b6aebafa19924864263bad9e52f70cbfcbe8fd31f993515852a431ca984f0460f9f987075a244b8df3a8c6fb8cc5e46c31874ab657a31f32be45511bc49dfec92511335eb15aa3bda5f637349b1cbb8c1a927da6b4eb2af8d603fd988744f677bb7355dc737fe1f161c2181d45fd6b2792501aa6ef68de0621511a7b0bea9132e7b99dda23c074e8f2ae80dc5438123a63152f6305c6dbb156dd572abae44d3530c35b4f1458326d2824e636ea5b8476d9287af2457e528803ae3c546c02a24f3dfe9aa872bbfab2437ee2352eed14a2d94efd9b064c2dc59d076e882177af81e3e7571b8f73c3caae2c5880474f705327c034b6044d899635f16c15b45dbce6f3be9c72b5a9e82ae6b2c2cbd994e88987447d2a1b4f1ba3dad60c0ad9c6544296127aa9fd858cf2015dd5d6cb297744bce70b462dbabb8fbbf124e7723836a84fc613fdc0bc6b07ce574379197598e902912844813939ca8bdcc88f861b97ebe58d8aa250d89ab513c68625358a783b4df50eb5728fdb4a4dfb00a4059c3012a3a67fb942eaa4adea1341b3cfda696d84ccf833826750c27b5d9cd84683e5c3a562c89e8e2e4043d469ea530abdc68641e2171dafb8718ecfe9451430561bbf7c349acde5f73eb3d296b5d1bc0f0a004c4ff8d84e335a9ee548a03e1bcc2903495744637aa2de638ed226b202d126d4b80c0d56cc14e2d23a71f57baa5a866a19b490caa860dd01db946356c0e162727ec75aa5321ea332898de7356bdbf110cf32dbc9cbd9c6bcb844e60f0e7b064bbf8220e443d7385c0967d7f32d6e0f7b68d75eeac8a8c6dc3d8c69caea30222a11d4413c294b2ece3c5c14f8e17e685e0753a393218ff4dad9e0d3be4bcfb6d21274bd2be7bcf4ea0f5147bcbd7117f137d106d1ac6ca8c6c772bf815bed18aef0b16b7a000ac610b1d289626b1a8127879e5312462f657439e220b13cd94b0ac3977b4143982aaa10f2e3caea6457fc8377fd766bcd2c96453f6d0c03450a78d10fc8108ec1a21bef17ce36ae5ca62a5e3e5093d2db9ff8dbf8d9034e450d7b98b17826545a3065ffef40d932d94661681676be4f07 +expected_result = pass +expected_shared_secret = b1090cf26276a81c22ef0e4479a4c705fe294d3b892051ddce7eab16495e0783 + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +private_key = d7e3338b3ca1d6118b7485bf85ab9e8f6c36e158b67d2c3530b0a544b8afaa0a8604710987429d0d1b1eaaba8f06422e992c475dc4cf909061efe673a3547575e8b00ba47d5a158c22e6b2c280b3152165a5a01a43d801e96791b6d99c92c0b0602c94c0b13f2672146a7044e4372c5fa8843fa7974692b0f292af9fc3b5793092c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe061509be046b3a048a73599ac20466f0707e9b46045352f94507659ba428cc6994ee3375b07d09ad3be1872c15692c7394626cfc01bf5435d7922bf9199533a22cc4ff021a97c571db311485b36e2a3344eb880c67819aea18b09919fbc57cbc11cb228f8c24f38a445c512245c3a5cbc65d20269ee849bc268899981b9f334704499b60a891139d9470a1a147f38470752c4eaec5b14d51817fcca22e7bc1c585cd2189131960a9e9284ac7940b2949707ec7a67f22db280775d8163394a3a9557bd48f50c26f177ffe83030a3455de1196a763f8af156df73ce3bd07ac70447573a79dd04a59e8b40e39c6fea736e14f1b1b67b5cf556c3adb29facfca4e6d8b759d37737863da2a7ac4a645a8f202ad61c17068385c21415f7e14146d896020b89cc73aad60135d5a3b94879184e086f1066a9f56041b6029d1f538fb5b18a7a741e04e2c158b69927a1a7708bcc411988c0c315d0d1bc3a31b0cd473fcd3abacb1bb3eb23224379b5350081efcb8c45584d3b845e2500420453718ad83194130983a355b1388bf246b9fe7400443c52629812fc1125c3800c3f824c0ff95bc24a2e8b306d5e3278fffc585843bbfcd06d2ec3482295717a5111aa7b6475040083106a01491cf981197eeb77d9b01c2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57cb0ecb3105d94715c7b1ba7800785edba95a7352583354b93cbef98c78bfa946a7431813ec36ac45488b170859c098b7c6813cab2ffb519814c3a9de3c254ed7a144fb6d15b183cb48a9021972233382fc8c388511add6a86837801f4bea0df0103b3a152648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f6717eaa18cb489b446d24f5ce239c79a6e34215e87bcb8461b5b509c895ec22f94c17c3bcc5904d968c469b200d3322b423761e3749556476d925a915971a62a5a330acbd106ad77da7897815cfa31cd44310d44915d762164b6170b2916b5427c694ff3340fb16b73500e92833ecc35bb25db6e652701d85ab215b366a173604c2797c2a9c420e069e7e4b3d1120dbd1c196d105211134478d23cc4428f8f56182ff3a51c7b84f01a08ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f7c06883c99c4ce934f9b04436d250ef262c42d4862b90c11f4924087469210a25cf4cb29d139d85d9c904004cb246348c60736d707b2b9b111c91acd3937d9e8934032746aa5025bcec8bf637936448a0dd67a27db2a74b60bba82bcc87d73d4a9033c427a85883613eda43829c7ca3c7a8f24364633610d8199a5ec8038d0b6686abbd47692ada94282c40799ed4bf8ecb65ee7c8b2047c41eb255318c139b89ce909831fe3024bac10b4110ca34f1bd657b941f466659fcc971c1174aa4459551848e7a116b751e5e4022c8f2a4b3152a1b26a3096539c9b0bd6a435ea1e33413ac4d5f401f5de8570cc11cd4bb9fac473328d55501702743e2c8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b9571200b05300cb30bcec4a58b06f70830c2b32d28992b70427781854456129cbab53a7c72ff557193d3a221d06177d002095bc04e993b8606245416c3b998b01716af3b43a535f7a6bea71270b34ec808ca00e9453ae660b732963ba634f14378b1691a90e3708125cde31bae3d10451a5643f526cb790a8d6e091a725681fb539e9b05bda7b04c48a31b39da6e39e6be624663b6284de9f958c50149ce4090e6a486b68511ae90a0f093297bf090db3c81d34400a40cbe11d74271e23bbb7a49ea875ea7f7cc25516a899198362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b4314c4c44f44c96f48b29a8e7b85339037acf131f2692b7e7a49282237c8f37267c835c24883d1a189d4dccb7c6bb1fe622fc31301a6d3612a448084e0a210449b7e15a4fd84a9a538b2d5844dc170c911fc1282bc513e8c18c469a01a548d1ce4853128a03a8b1d369b353c3003b0a29d210ab6af23acd010ae3671493c774efad8b3746180746401d0e5862a3265e7969f247c954955b4afc13fc420143c10263eb1c6dabbbf5a8857a7f3bee7658c8399503c21a9a38ba554132344e214cd2036c2b30d0770cc5dd87ed9b246e7f955ea926965748cb9e58351a938f7e4ac249ca5c970cfde48c0ade051ba873d36a581e0fc50d9583109a79549fc5b32ba432444046ac0a66f3c64ae1498f43b1b36d8082442b5aaa7bbcff2c4cda8c0c4d2c62cf9135a75709ceb5b82ba4ef5716c4986a36bd7b4ad5c3a505869fd34aec2d7caba492f4bc30d232382b2651d5923242bb50df87092ace5566bc5a18fb2925cab467b641df7b5b91142318d120456245f2f0887ff13516d23216637393c469ce1f776cf2426c6577844cb3d4e0a92aba85ffb59979a7c33eaf51ea2bac9862160bf8a85553a3d4edc05da102106f632c91b8d1df2a9b2734185283941ebcdfd788107b307738786d6c0a0e7d4957dfb17488c5d6cc11b83e3504ef2923034a06270563e18a18bb29f48c36a64c132aa626dcfc5a615e4416df76746673e500186a117a27c5007a4b04867213c33739e27058adb23c0de35ce6158c99e59b88b147e2ac05f09f7c0a414c3240abaf65c24cfdb6857eca66bfc58e52472861bab1e03ce70d2115480b443a9bf799379af9ac978d0072f75bc7923816a189da5974ed948b8a709a8191cc9be60ac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac47260785c1b86a98a5dd733d3dc2b947d148f698c5a117821847604151068412268169c86d50be92d77683386025704575177aac0b9d3d3196a610985e860e2f799f480b1331ba346db0c379cb1833223836d88fd4e11dbf2985825c78330658b9a189233bc76b172127bc7a98e6c644d28da7b0857f67157ae2c27659297c32a7eb653697a295097a32ac235a11887388265ecb3b46a75c865c239395300d0f8152cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e9779146fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = 175c3b39d3296365a6f8e1e6648985b0c1b353b852a83a7950bc3bcf8ccde62f52514f63823ea758d4e58bbda8b6e95a0483faf6e20612d042765dba9b60a3d370808c7554c79b1ef6454419e80924c202304ec41a6b4d1d12dbe20934727b94e3d60e0f76c37ea60f4c385c3158e882cec48b1433fc62135ea6f05594fd98f13fc6929be35492b354b58e26c8035fb07fe179929649c91a532831df262188aa0280e46f5ea5cccc7eed59586ce55d5aa088692b25cc3ab58c98ca228306b09c26fedd0a823b36d845d90f6e5496e3b6d70c07300df9fa5c90ac1798c4ca5ca25c16d8bc2738c475aa76b8e2dda6cd00279935ca1bc8868d6bacadc33c77656af0e53b10be68cc1679c54404c686837c4aa3f86c9b18c4d98e335f52a80ca28f61520929c8f6c044eda9b7802575051d89287d1af7b47519661d529065eec290dc145a7e496d6408a5a6f067a9e1db3f7d99fb0fc34ec167e747fccba45052586f12d7730a489da235d84d612777b0986c501c1e028232c9090fe6c8fc51a56088c1881c4e09ea9baffe50a6c2491f61c5dc0711d96c7396b8922551a70ade21f332f5236f13d9df8388cb6f0e461106d32ab61817305aa5bed1b9ebfb44f85413634bd424a95d913c9a2ca3b5c44ccb65e65be918dc2917cf9e5aedfae4d4b49dff4a613274f504b7f30b0e1f2c076d2ef31c8395219f9712ecab9df8c0d4b9b843a514d520166323dda4e9a35c212a8fbfe6d16e3b6892282bce66ff727a8472326705726e147761a2128752e2541c5f5331b8962265039b78bda79e326c3d7124294d29c2a60c9a01dd244d7edca5936560fd6323b9aaaec48fecb8e275930a882859a75cf7aa467bab38f54b34f3b35e8d29574dd2e301cb9b4ebe7043a350c14f46c308c5001bf680232def77f2b7c8f5fdcc8cc11d65b505ca393b97c0a6d2d2484401dabdded20fe2bcde15773a2b109952af594a4d943608b066cb78580d77403707d189c8a11c0ec5fccbf8a82967c151c955eed18b395350fc85506f42639a1f1e6382b269ff2611833286310ff91d97996e9c3896fb1c7994e877e98a89f9d0d1e69cc6ab6da66eef7b75cc147d1633450ac4d8baea19dc6bb88a4b93d2d7fe842a36d900d5b52e77165967a003ec5470282891e770369cf21d21d71a982aefd6e2d943c68b51ee312d537ba02a952baa7f6c0fbb6f93d554a4f13fbb8c48c04e2d9416cb9ebdae2ae2bad31d6ca5ed0f7cd01bd4db174bc79333c4d9292e07dbcd48e72cb7e63fb36dc54f0553ca0e43b48ef63ce225781f88a556c37cd2a1fd24130f41f1d778d8d9d0a0eed1a5cb75b924bff5dae57119cb38ceca4b9cbea6b6b7c5ac854a1f115945772b981634f402dd69e536d2bcf51466a20ae144fb853c475c04ae4c40c5828c230532982dc51e53810fc73809c1113ef54015290aeb9bcd736aa8ab1f747d5b90d188fdb45c8bbf14c06c41515f354746c7b08ccd2adfeec6bc02266a78380b972b7ff44e1d29cc4bb1933421cb5450 +expected_result = pass +expected_shared_secret = 2fda9fa72321be3a0946d6d914c7ae714b9cc175619ab8abfd1f1fd499e0dc27 + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +private_key = d338b8576c1fd9168551a681f9c590095b6b8d8474f571226a4b68ee81a83738bb964356edb663d925960388c92896029a201ec7f046cde497e3384f613a444634aa3c41656c6031d5233720241603612bec1032afa7b3d41242ce374c8b118cf6219fb5e645002530781cb4660403f88287d115baaa07ce95496a7232862282a653367fbbca1e337155a3c8905e368c1974418e735f93b6965fec11ce7b43d81710d727a4c4b434003b9110d013568b7bbfb341212543031c862fac505944b86394554772047b2a864a6675ed984583269362759cbb464e7e248a48c3554b8054ed9342aedc8e221439f812697b691bd5c89b7fb11ec716bff96c97dd73c45b00980bc6b1f69117c2329386518058e97b26626d98196025724baf0c5729109399e035ace9a630cb6d7ca9cbc16ab560da5c01e37601bc0dca7a3af891b80418c0056145c7ac8c176605411a39bfe843cafb4fa61463b20a504e984308f2b82ca7081a97951d0961b2664e2d7b41df902571d02c1fe24ec0ea998609248cf51cf2f81d96a983dbd29bb37b9a7d559c72fc0baae894583a842fcac92d910c7d682dde70a4a7b26e3259b290a182392cbe36b68d2e321708e9c00d8c06dca5043c1a461e76438b7801e8faca17045b272b16999471f8fb42f53a43294124c3b2b7f7a13eee8b195a01871909a70e41a0cedb37f3f733ee259f40c1cd12c79daf90788d78ceaaab9e1d20b7ff8800a17ac28953a4e90b257d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a59822bc6382b9cdc6072f0a6cf65c9dff2309d1a433ac52e6cbab472e788f76558d57986bac5c79b921f06e509db18c70ee88af044b527e221e5a5105a19610f059fbf6009b985190ac81640607cc4fb69d4892b5d9ac12bac26765aad5c874fe3080beff77961cb9e747a8e4b4acaf3f3b81d51a4a755ae8ef2994e8a722dcb5b8014c1ccdc6a79046664c3b75c02b91e0b4c5c250b8eda5d67e9a0984a6052053d22266b2413b98d841e8aa686f4e0aeb8d5b2ed2c8bbddb0374d0ad8cd47a0e6945f0ac352307ac0db224eba29bc09397f05b1308828cd42b85c556bf0a938959fa7cde083d3d0163c21b016133145ae0c47ef73604999e76f9ad19432f82e762ba8174f89a23d09333f7e677f33bc15bf996ae6999ada8747bb0c454412c2b651d2a90382937427ea555b3856d0250ab1e3663b8d78f3d96cf9eb90b5a501129715df5db38086076c4b351305a9718903abf12609fb1bc8a59162e2152f8e0c62241ca5deb5260d71ae162b7ea827a342584576b00dc674a5be149c7744d7ff43a5b04a3ebd38c110630ff656f2ff042eb603403d14f18eb17cf675c995c2790e936cf8b60e758484bc04314e50105b28346829077aaaca72acb46d331e9127b17dcae5e639d2b33b9f3cca468f731bf0b332ba41d196ab77b3c436702078730369cf59144540ea08b5025a4c880c1530f40a852e35f96519c91eaa680d90d25a4256feb1878b48e39143ce43378eb3335d3e03f2a358782e0b54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf29e1472c26b4d7f80e4bb3192de06ec05a6aeb9b77f8c16dce72611902a8ccb81e8cd4c5a2fb1d8fc30ce226bb45779f41073ff3ec0362ba152102cf45d3a95874a551c14c8a621436e248ffbbc4ca3b4033d50efa392dbad9c339745803f845736c30bf309546229ef52788ab223758c03491f62913fb4ca4307dc6b4c7fd9503a701ad21671387cb2cbc728ecff4641e312779c7034ce720554a948a021751d4628890ca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934e4144922ccfa2035892c4cc2a8457300946aba4ffe77868d34c7a90507be43748a366c49d0a927e66610a08cd0152a2c1bada92a05694b6e3d2610acd4579d5634fd2675f2101290e2ba1855252b57a438b50fcb854ea7b6a89b109ea9857c23aa38333428b94ca5a524977d72077b56978328c18980382ebc967dd37e6136360a958d5f00c3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347d9b018d437b3b065c120d26e9033078b5838dfc7ce68f244b32c5b4ac04def068f58fa733e99a418176575ec2ba0f78d4c402d67176db5717023b57f8d26c636a11f49b926d20b277d2613941c3e786b1a9a3c1135993bce22a1de16434a5902c0f101993b65777399828ba52330a2f356203521a3c59b6007c3aa41d198a8232d27c05f8e0280c9076d54d5aebdfbc95c7c06bce24507892641f90d2b774a2d98764c42bcf009799432b706da59bd84cde4892427c0586929c99850c7d769ad9a221c85a4062a62b2a1847454554224c4cc47898574fa66d147c4aedc59ff612f49285db54170508c89e6787a8ce6515cec673d4545970ca8ec486802933e319800fbe46d5cc14c8363656dac0600d895fe383fcbc3614fe334cac0a94c185b73db30cb5a56a8d04cb271b13859862f164f980625d78ac35ed120605cbd69e6410eb05168819440816eebf8cc9ad153cda5bc2efbb00a7563a55856711231cd12873a9a56996c174ae43b5c172a1445bb40cb3deef9051035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54b6021d180881d59d2458564acba148b0ac36cb501cc8242919064ee24343f26a87a0696000533a20943445c72b9260b4c8a46a1c921c582600d978c5370b400b2412f73541a13ba0349e66fa4025735cab6402aac51e08a019b48115c49c665f415244fa91c208c6b1f2bb02bc18c47a5aee366edbe3bae1e41a8b405ddeaa22a2fb254a6b70dc5a16c0217e4dfb933a127039b788e6c035df8993ff86923500ba466a81d34a0ada271da4262f33123a1b81a13621211845a167449d93370bd95a89725a56a8452b510a7fd2642af41a4a7856abd9688dd7c85433a868103679a8eb2bdfaa0cb52cc141267e91e2c1e57162c6b4897c9004a3d375c1c8bb87c5ae2cc80c2a107e0f904e5bf8065ac96c9152aeb07322fa181a83a9cba0224c9faa0f06cb67e2787eba832d3f53ac60b7b014d28945361759689c3ec65f8b885eda081443a2afd2a735b1c57c201aa4d273b1302267e5a63abefbcae8e1b2d3883439e2be2436382eb9bd62146de0e446b6e2baf8300575091db145a646c733bf352989938fdd8003218a607739c60da6758bf448bf18a22630b08ac40635382e3bf86d16625c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ceb2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = a79775edf0315a85e2a48145e0ce0e7b2bb5d25d995a78c8b4905aabe811328d595575e87409438b07a0b772e9544246a296961385f20a180addf607531c8aa982b4a5ca6bfae414956a40e52de3c1427a087c74017b0b711696459fc50369e06023bc915cc0f37ce9b1a250bc5e3ffc1404df54edfb9935b7ae1a5d73811515e0c1fa539eb9b11b08d0329c1310d3e49c816249d1142240f605e39abba101adb143a143d7e4ca7abce799e13135033c98555fbfc900a319824691886026b395841387bdfaf4f2cb712e455e48880edf86c40563bece6cda265ed7eed3ed91e649cc086bdc81ccc5d9563567cbd45f032bf78235c2576a12d7fff82170b4e0d0d6dee1cdd075e55fde2e1b00a03edb1615c8f225674525d7a1c8f17e8f8dd6863dd41e990826b482a307ddc522e29d271ab97fa57f2e2020f50701c7151f445fc3a8ef1afb9443aea1919edba5a68d745e3863accd6e3ba32f016d405018890969148785d00ac8830c17a7610376a0450f037ee4f0510096cada7cdb7a38d9a765da618e8b5ba2fb0083cb761e96a753fa119425bd50e4b996c5cd4f58377de02ec10ffd8751e6b513c3b33e7b6e45027d25a910a380cc16cd6e85f079cfe1f985ec15be162efd333d594c2fc333f3389f3c6cba92ea1285d68112fa07ab65d18878c423ae22898d0c63057da644004de424d312d099d1c47ba88fc9e35d6f51691a95e0689ab180955afb49caf3891a329858f625bbc4c54871aa82692bd0b32d0ffa87662bbaa75920f8bb546bd0fa4c67c63aa72501f7e213f72a9d2b767eb5fc2c7b5f83f492bb9eeab10bfa746248d1ce4ea4d497ea4de28878f764a349e2f6c268b7b61fec881f3bdb7910a7fa2dffcf4dce41fa8ca4e3cf4f720f72bb29799c93e7affaac971734837e9e4358508b5570c4946938245c30b566292e7fced74793a089046cf396aa77f277ee2292d1ac516e09213b1a334dae4e4ed4c6bbecb9e6f12840a3a7e111ac10714dc73f2c74a137a7b662b515175b9ee56e76eb21d26b75bd5b4dfc7cee9fb6ff276c27c6d531b06e5fc26b740090cd6830c126a1f32e7ae449507eaff06332b792d82e68a285f5b7af77f030dd4535b8eeb713948ade1ea09559555fefb1a332ee3548d4a29f2a4cba841c7194c7d309bc6aaa4d8d299d99965300347aa16b35c90871c4c7577bd419b2076628adea586d73988828327220dcdb509807b7dc921d5f7771bd8a0de19667c965e3ab22d3198880e837716e506068a70de4b4d300a1f1a386ce65d8127bdf38b2bdbfead80d6b7b89600b880833d84a38b9dd9cce2646a5cf6849595f0ac740b5e65e6d7e1fffdbfad7d36ced685b4fd17911ff697a8ef8bbb37272a95139920727deb0bc7d5feb6fabc89b4d342421b29d71d0796c5312484711af245a0c53629148ebe4c1a61bfdda623775b75e263cee799334be799dc8d26791a7b8ff002ca4f92ea37660ce55199ea6b25134eb9c692b255d3f59c96133c6857ff5aceea9c32a3d90c3e1 +expected_result = pass +expected_shared_secret = 23798e8b9eaa0b369842cad83a2bc32206f791229c830d7593b9150161168011 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +private_key = 9bfc3a71fa83a4070db5064ada8410a770845e818c49b91e09a251e1925edb226ee8ab153f94b2417560d88959113a6bbc854b0065748e6a7db90977ada0216f3c41cff70e5202b306cc22ff8a138c360d75b9cb1bba849c5bcc8c9b55e80647e513c9e3e15f66a144f013822da24266765e3f1125f435bda4c46ef57430eae331e1d54c91960eeb363ca25387d0d441abb930e4a7c329191c5ff7a87996a4b1aa74162611e67b303e284c7098a65069356b55304b11b8bba66c5829647493c09bf62166017977a988333092efe98d9c13a2bce53f8ea2c81a0099b7d5c2b11704971366a5565cc14610df796c604700680226cb165e9acaa6ab507a923b4d472a4b6c9424e7f5a622f87f4f8a1083b4755067a93c285cc0748d241c7051971128cc5af4db5c1f7c144f98b6bf9703f5338628ca22df4b84d10312edda9df71442464a24491a62687928c22455dcc23eca964e9248543520790d813924cb58a0c156aafbcf63906ec5fa891936c7e16b5fafd98026d64ea2012bd75b6c5f376eeb74ae9b29cff7041c650b91a2b852c021562ba33b66ebacf787be40810f22aa43f4174571c77710f775d1719968a5523780b613262f94bc36b611b63f460dc6e02cc588af99f164302276b0386e697469c55928c0e62438c25af90577de0883cf45819262905ed30d9a1a7918b82f9b4a28ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d510245f8834e890662e06774f389c0c623be3212aae5accedb101c43463b68889ea9a2c21aa0acb5329ff80a336f8914fbc602e2b9ae452647777651ccc4bef70ac06423b66ec5982c861ad9723dfbc834ca6a6433174c1d6c1ab9569265a96ab5d48495d72122763b3a7275b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dacb140666610ec7a15ff18bc741aa69425508d5cf682bafb6d3c9dfe02d80349597f56fbebb7ec8031fe71b6d6c065c4e6b5e5d17abf3b412ded81efcc8b6b1935fb37b467a5cc61f318aed20678800726509baa73bba244030500050d4b23e4ad71349cb0877566ad100ba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ed80df4095d59ab482fab7fca432ef5e76affc77f74f4cda522a0085a4917d04167a00b09863850d6caa0621c2d473de0763b7d3168b6147bdb009eb260901fa82013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c43010ad15ea2eb1e05267029e5ad8139728a907b98761b65dd6dab895363159b48875fb6aa80882256a04460b2977280688745c5914c089b37bfc949a8f9864afec2e4dc13f6092070eb561d09b530eba2ccd66b87b0986adea1933448066521e28ac2ed9c57ede492799b401cdba8377d593dafc1a0d233004e25877242c30070779d8bc5bb488dd3988004b5a8554861b560ebaa5bfff7c89ded193ea077f421c216996c1445b165b912901b217315636a168c0216ac026fbbd4239858837b02dab5a39d1be6b072468a264661c5e34f42380c66526377c990092434bcb551a744227445c5108fcfc3cb4526d0b711dbd4539cea05a08a78fba723f9bd11c902a159f41cb5395be189b1b7e98cc23658dccc7bf9a843a77b2a6bfa27bc941b04f391950d998c607a59b49330811200b38b243060b55e381c078100da84975091f3a0acb06f22ae3fb1b7d756d36f54200a367c109b13cf40f3671231d5b0ce9e5908776768767209f4726c54277d0f8b0e05bb4cd50bb5547a01051c89abc4a352745316c8d85a3187d68382ef05dc96294446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c308f22b8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf2325cb060638c723364b27c8e3123fe26cf9862f247cc31c844ae77754206b03b497bb3283cc7e38664b23771f709e1d308cfaf5086f25acbd04cbd9f1612acc2712d129c9c195bc024cb057b0766aae7b533e60f04d947947f920470bc37e5eb4ac4fa1c48066877b4456d4ea2a5ee089de38a7fc7573fae5480bea823727132651a85d873378cb97d6f7be1250a94621abf5eabf0114952665cd2a5005af338b36d19f6e4c8f77e2cfb6f24d3cb7a909315a026b5aad50a9cd4baf3308059a91323b1c226ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91546a2354b59328d411a724cbd8b3689efa335d879996fb0d1d2244edb361be4b2489e84086f4a995f20ffa9404082c4e66061d3ef668fc155bce04916c92b8fa46b77a4a9fa82c8c0ca5a5a5245883d25fded230e74b22394169464bc33fd51fb7f2aa9214b1ed546dcfd00ad554aec80882ec170c6ec44794204170d738ef9341d6034920a7aec3b68fac00527b2812d88969c6207f9aa122464a4d76320ead6271d2836e574155310a756cd4249fa7474b301ca978a0653935b7740a16c50df1eb678c1bc3eb451cf6fa35beb903cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4252b093d2ab40884c39a4abcbd19b108b81172e18a84a288aac2982d113454335423148168bb6b9d97494179bba1ec8760be59d06251b94b4baaf82a6481c4a8f33b0fc3164635452e6497f992308688352cbf44537c618000536f9c41a64361ee162236f9227219b8b84a3984c649ea82211207c974f6c7575027aeef57e496a58ce2719096a58e2e31e82844f4d674a4cd9cfcada79afb0c63e634d2514ba4d8604ccc42b2eeb64691aaf23727c93c4abe1423c27b3b7abf0b649334760056e591c32fe812a753723f7c93ef5524c8e0267db177e6e55620715688cd0ac70b2a90e133caec86945bc74d7ea1cb88479a37b45eae4993bb7048e5316bf66b9715591148c9a20a35412c2404bb62c512b3800b9ae104453d95acffe000d3ae85b96d8092532796a03039ba2154f84afa4a402acb673b8799441bc505e836c3b558e1fe2057fa79153e1630d72afd96aa4fe9c0ed4822ab33a559719b81d274ef0a2773e405761a036521278df5ab3617cbd89d7543cfc7c6ad373b2d0b781dc78dd3b2afa34b6565979231681fffb8c62843dcd11686ea59406e23cdf96aed95554e47027c5b6976f5515bc40b0e3a31c556219f89b73c0871e1ff552ca04c33daa4a363794cc7c0e05249b53d20460eaa8ad217787c8c9423a7eb71058b5a8081b82454dc91f77f8608d60caff30a7c42424542a1746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9edaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = eb2ebc83c36b4b470e983a8f9befb67443567e2c532348990f62418cf62208d84c1e97c114fb76ac3d30491056f2f820178164276804a16267eab23b270f990de9307b5947680ac4d4c070a2c764ad520cdf3f4f0bedee9c2eece09f07df98209e214abf99c07e7f50e78e38cecc268f84ceabfdaa8010b1c8b0450f440923f23b22465770d19fec10e0917874dc78243c3483a38d49fe28526554b217b2a0eec4bb4b45fa8f92954dedca998ff1cb649237e0e056e72216660a10253ac5064dd0faf13d0675ddaa9a3142c399bfcd2efcc353c316e4e8d3bc9b6d27b9ff8bc7cc4f87dc4d4ef9f156b0e80ff45192dee9413e74b83dd98a6b5d3a0348202bf041efe408dceda6e1323c887e414f126ba35cf6d78da697a47ed66f8053d9cd0a096ddd6649e74138d69caad22d856297f4bcb2e4f7fd6930210e63325693adcf4c60a346b34b17fd2193cc3e6d484949106820fe308c874f93f9538365b9cadbe25230dd5b3d7f153bf54fcdfb1f2f668e039f3186d9e4f9f336614e88954ceccc791d584ca318d942917678f511ff1dec3f1534569bf0168dcdd1505fa98dcff66951fc28dda492f0afde670bc4fd0adf3b5303f3ded36d323a89d58c5b37b9df02a21174abc8f2d517bc15f2afadc22aad49a678392d3dc5c96c3969e4b55ffa30daef78b07a01563ed24b214d662648afcaec2ec91b5698b638889b701ae84fe06daf92974b545a007b73ed5a12602bd0fd6cbc5c62949ffbedc1337bd4d1c10ef41040e31168135c45c765245c00386ffb54a6d62eec1266a18daee9d4519214663d307d43e729954807c859c4a6834b1c9b7a47966c6bff8e8b4e062d1f9be53329e0961abf7872e42fa510cfe350c15030a0e12c66e8de05af485b9688112b5c4612973b81f50cee871d816839a2beeba30bba36981e483fe600e2993a60b3493e016596545243c7887f9ee9dc1ab6c875621c1d4b8c600e062d5d37a30421bfdb811b62fbc73c0910d305b71919d1c80169ad86c0205cbeb4bb0df6bf7bedf96c741870d66a78a62d8ee9cd7f7e7fa8ebe0adaa1389a4932245ba6f85b908366d1589db6c2715265e98d0f5e89ec8a0e35eaea4c9f50aaf213158e729e3766c50497e6c2b9f44668b4760e593fb509789ade992d9e7d047a50045093f2d935452648c7afaa320b52465d48b9e15acc640b9e89a2b0b893a6fbc8c257f386e4cc9a52bc5d2ae7590cc2161bcfddecd17e8daef627fa9dbfa92b76942e6fdc0a2f09692fd82391d69546986b364c5a22b2e91819d957e1ca654faa71b11a16b79c37130610c01f4f9c2da974da0940ab94febbd955578b28ce30ecd668c8ea876ec9b313ad41e5a29a04039e50fb24233716a726bb202e7662c37b90adbb942a6cf708eb77abafc6850af6d037024e6c781994c421b3fa916ae07cabe60dbd701f9dc7c29ca13dc810c89970559853066e00152d171823b237a0e189c1fe72d14186f420c1bdf6055270b3782d78a2d924be110794fd3eff58d8493bfd6 +expected_result = pass +expected_shared_secret = d5c63d2bd297e2d8beb6755d6aefe7234dea8ecfba9acda48e643d89a4b95869 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +private_key = 5e484946337e3f4135d738b0862b69f7b247a5bb0812d56201300c53bb87b798b2b551ccea75a87f002d7de7878ed08e976a2cb62b4aa559bc36816e9690973f608b262612f89b5bc784365e33193fe9013c05818e0a7151297ea53c95089388be203071d0335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92914137c33773660aa15557c32b7a086a5a1cfd125dea60183ecba94da22f0f3a18dd2131bc792c4013b7bf84a7840c976c53117653c4f947839d8cb35538bb97899418688a9e062f9fc17d77450d85261aab01bd9ee77e917966bd26bd3d3990aabc8561cbaddc5a22f8c80d99453fa7350b2a022e4ca48dea6c9c07309543611abfc7cda76aa03e51acfdf0cc73921ef2d02f45990aee50ca77b93f14e4bef44576134391f7b67658e1cc7876713742267a556ea8f562bd858b24e04314b025ccb5be0650642a23460c3c65e0d6cb68232cff709204b7b7cab0741807100a712686b982f632095d7730dd9385a7a26c23741474e12cd8fc259ef346b5f287eb01b046104ef8415372b47da145ab0c5c1774626b5dea7d72db4c62fab14c03ca51384420690a799194e8aa05bb914db21956bedc948299baed7289c884ab9833c8669422adf51d4e1a0466056eeca478f11ab55ce2ce34430addc889044a5601357ea6a5b097b54252b046fa83c0211c236953954c36840e390d2707848c0b879aba2354ea200fca56cbb86c0c2269a81c790b966893f782aae9a4bd1b02fa85995a757ff2083fd26347c97711e07560af77cb59c7cd64f7cdbc880ad26a7bd7fcb9b210710e581c49453a3200ac08554a641068e6879ba6665ae9f281fc14c8fbfcb0cac0081c1a06db017d80048b324248f699825a489d0726893e109127a0ae802cca29ac56f6118d209a54cb842c9a8c539e43b9681cb868018c95d872c532a10a77bf52a796d33187fb8aa3fd780bd2c4b30fb7394dc64b0fe05b81128763a1325bd00eba411247b1c22a1146feba1b255c51f74999dd29a9453151bd9869e3d548347b93c1b798fe92a053b88c80d7afa5c561d31435d61251253b9a4c2b0f42830c81e990006dcebddb7002240ee8e276d4e31c2d249b84414f3997b9c4f5c0698cb2a24c48e3605f6d704e5db734ead12d62634dedc68ed6a1248273bad5ecac0651978b098ffcc148667671d4b59ea6095b0b363c31299e5b90282f914bebc66f6291338bb7600c8310b83963336952ec33854ed7c979b71f30188180b11bb66314c93242ecb890123c9f2aaa786acbc7dbf560cfc1625d06c3828998ed51b79d28c583bb38719706d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d7113edf611c521761be671fe37baada7a2b4a114dd458a19966a2a42914d61b47aef5abccf8240c88af752b51bcd0a3788c2aa38aad8dc00d835476c8386dd3a8628b261f1d6b2b9f771842c97da7bbc3d03696f60524be6476430044f6a8aa48c22901f750dc55c1ea7813ec3518b26b3fd0657ea6fcb6be94c026244a0401593664673faa680f866e174143b0cc086fdacc1f7126c3e941f090332d8487d5e66061d5311c9b5c8edc39bdfc34948400a9a3aff3a85a8683354b3c3f035586b50b88c4140f346a05ada7ce4beaaa5f096614cc767af89ffccb95124b00e8379efaf76ca381ae4886abed9240bda4710dac62a71017059b07921c770da1ca2d209338536c3a9b5238313bce565fb861bf8ad3a78f030b3f646b34347f1d215e8ec1789d602d92a971fa3c2e892a09cfa68968f96f206a7535766ed7533497fb051c8036b0aa81c2c802fb7333cc6744ec830e4be56ef1e4874371409486c477cc4ee90092d2919f585ba21f32bc973acaef42b4969746ab2618631b6536ec298b2828abf41e24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d1712e9ffa937ec5194a3541e3fc9c685102f9a47faa077fecd688d607996e5b60c1715e617994b842b46574b87086a061488bb2445b357a38934b612c16168e662112756bfd764a4fcc5f7b1634f6f28094464d600046ee03b4540c1049bb3d18f783fba2ac5bd36ecde662d9e08e2a89cb754b090db7175277941e5973d010ae08a4b4c922aa99f47f657a49c3b81fcdb54c905a3010405ed544bdda9942bc857b6d979f796c859e0627a5212543477ed791c2adc95fdfac9d21d19750b8b5ddb95f02d721a9304099ba6b2cd0a40c1a2f9dc1649b2318acc93a5fbc52e3f4900bb44d20a7250142ae5f3b77c0720c77104b74c78eb821bd32e260051c499b5ccdd9d716521163557b5e4526acaf09a2beda04994188a5065b4a975b215171eb288024581cffa37d6289813773b29f1c0ef5587f9c98049f548d2a0c3a5c71c1693b5ec8c64ce0267fdf625485dcc4b5553c5736a0d0623cfe20596f984c014aac0380ba9b58257a993b1be3bd2cb9ac25912b36b2c085443074f093510a46cde5441ee3cc88dc2cd636a5ef77310f91cb21abb149db2541407726582b54b50306cab4b5356492c220c138c64b4ab293680e01c2aeb369bd611064fd8955b790222bd5997dd76bfbe50a2bd039c1f14f0469b623c53195a3b2ff068182d951dab05ffce9a6c8fab42886987b7999043c12870965bd463980aa6b35e13b5bf9c25b64920d7788a291a98ebc30d3785783c27e53ca9ae809004f23706e3cc0b9ac0bd571084100299c932db2933cd91566aaa367371b16069a706be664e86107b33b1cf05360248c808ea250fcacaf9096715478463932a1c632cc9a185eeb08583a9309259c567743995af013216b1086815b851655d0f14fcc43682720acdfc36f35806894177ea2144f6e28837cc887e560874ddcaaf60a3580fcc7a5f1733180b1f1202a08182345370cc5c46cd28a507ad846d1d9415af679d4b22ee560c6c1b2499d5b74aa2758da090e62713343b3a8b14c68e415a3f196c2573c5e828a16cea51443104f9cd899ad03c3b727774b48ae61db98feda4c1e029b57f89d1735381166b70450215af92120ca61a8a38e575abf2cfaa54c613031a9ba60275d23178ba553a3ed7179aac44fb3607e93c1c57c7bad6854533844bf3d6a9b95a966f891612239cf6cc41df1a859afea9c0cec6d2679cd7c71c2cf251dc9759666c871853a1012294022fabdeb2269b430397f337b3f416e528748903ccb8b24c8fa28197244c0ac3a0345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b242ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf3745163360f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 333ce97c3ce5fa6677ecc0eb829056e8732a4bffb16f97895f2893ef0f27f669208abef07f251184b011f5485050e7dc471ae61c651499318a2634feb720f81edee3a9153a82d840069601e13e8a05e35fa2c18b0fa66745e104319b785c36adcdc4a2dcf03b152bf488fbba844eda7eeb4d289dcc7e926dc0ecd84f651a3f6406929b26223509789a1465817de510542cfd42424b594587c1cea93790e88688a9492146076b87cd9b3d52e772a072657148cd22c6e3f1cb724795d4811330a0469f91b3df0cc389e3e7c6280a20f4a8086f66f1d8f37446060ce019d1781b7900251049389911c0ca210cc2c6741ae7b2ae5ac5bc5905434645116cedd2ec8147ce6021bb953b98d7e7576edb3c9ce8ffd31dfe2aa2bce390e82862def5de968971fc0463666f754317e0e5670d4a573fee33ace8196dc5767be6adc9976ccc07e9a11fb7fe8627cf6b09e07c22da8c829785a3cbe044f8622dd130498ca4aaf6a66e5980c7e4055b6e66666893309345f7e506426152a6ebe811f80e000634c09c356306bc9c4d6d535edf4f72b860d0f52f24acf910ec731743d0856075fe2e0f9432db321d509c122b2bd69b18b62f2d8925cfd35c273c2ff4c0fc184e6c060707d30de3014d8cfb9d291f2d6d31700805da5d41c1c6c3681fb7603ff518b3132fb42f95c23685b6b72652404b1e6dd61ec31d27ade50384541336230c6b2e435ec32fc783972bf5f48666690687642732dc5f7090d81460924e2a7e64c05d189b88d4276bf9c6b51632f197f3f76e5a97571467b83a2d8754ba7fa8e827bb2e7517c30e5ae5c0fe9735897a86ff3359634adf981201f6ea59adc80a63264c776a08b939cc9c5565281adea113cdf3bbb201f5c6754dc2874b9a67e4a68cd2853f2ff5becc9d3a7c43c8d3a917d7829078a76d097f7117f87b7d4054a439c22dd41183d0e74d5e496ec19d66d555b45348ada3ed9d3ae1b3d351921f68bbd1d9fb4c87185614bc7b0bd3a53dc81b9fab161794a9217ca0c5e716214621c2fdfe6ccf9682135a14d52800f7844096dab5c59b0a07623657d505701733e409c8c0ad70a143cbffdfcaab8e8f122942a8197fa3cb2b9e0d4b80d30fbe7a8fff8d49df0f59725db077839398f75961bc5b9ae4f1d03f6aaa4a42b3960b7212b535bfe34360d1809317b3cf268905e41c923752301b0a9660da97cfb14726245e55721637ea2a075c202753e33c97ae9f20aa5ec6ac03202af9bd5700e93b5f94d63a683cbbb8242052549c21b4380f13be398b8d2db55dfd9fb04c21387393183a7f5547dc7af9fdb6cf7fc8b0f1665e57f67d7bb59a06933a15fd7313c38823af5fde333572b15a5f13b2740886a6bce0e942f6dd5b82f4007c224c500b1675a25a5c0732b72391087f2bd04d8c9af2ff040ba18aef056fa13f088b3b564abe07536195fcb800800fe2ff41c79aa0cab8c561cddaf1bad9bb35792f0e61bcb242a3f2e3443f89391fdd0f1951c8b2b615b684abea2be35b1af327620e00a83c +expected_result = pass +expected_shared_secret = 29d6a229adf49a1139794209307b0ca24be5825b2771809232fb718660162475 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +private_key = de4627135b3976b8ac07c0059bb28d09e98e3428228c1786c2e8a1d6029d93cb9eed217d09b03e9a7561af7441e4271c7b6c8c862c5a93e955a05a87b01a63d9e8a334b26e1fc0346051bf31d078860a9afe939f4a90c2a395b2b6c205475164e36a0c2930cd26e26420470b0d068e36971a978b17be984a418a3cc5c6b62ab00d6dca5657f71e08b215edfb88a5b6751eaa525dea4b0bd41430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638d808f78535b9fc6c6bc0c1402e16f0b784f9a22a30e5c6c1932c2063bc558a7b2636c76d5c0cb77e6c5518b3b31d920a23b2bfff3ab93fb03b3386f670b07655989c5185d5d393631e9acee701dad333379a63efbcc636bf2b4fa05b84a375559079c5909651e481da96b01a771befc7bc407db7d9f94b819a468d443a7aa8c9b4741266875268602336c1b1160a4ce5d41c57fb915335c87a72a7345316373d921a6d0ca09606154199c4f06c244a7c568bc5d82449149f92ad3350b51d3c474e77a3a1053160570c876132434aedd92c8961b95588910102c62ae1a75479175cdd666ab85478ebb6133920e9154441f1383b0f147137614dadc823f1848fa478b1f301d3f745c647c216c741dfd3b3195483f24f1a5313cb458273ffeb559689004cd534ec1369b0c68a873651f7413037118c6f98c538dab9c1ec649ff2301a03a650cc0c138e79d15f9079a639737e840a7dc720b173bb329a34cf65418495e4df2805a491a4c96b47d452725850ca8eb3944399f9d14157fa46b76f0891525461113766dc025ee1c2e735198c3db253a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb441cdfdc9fba20a9ce2943759c4d08c57a0e74bb0e1888e94723169437aec19aec1a2a46c81ae4645de32bb18f3527f4dcb8221a0f7be74f3f5a8cab0609be216465819fb858232b008a855c9e6b54439a67aaffd9701967bc46a274d1d6ac1d45cee7c54cf49669e89a44ffd7b73b2a12327a85bf5938e6975b949c03ef3a1d824ccde033cb175a3356c8a998e4c69d94630a896606fc1979dcb5c172a54eea2e99d5ae331bc64d708fae45c514a2544843ca59c3c122947bc3660da7357ac0e33f55485e79eb3117d14c42ec5c56653e0dd1a4e8205fe571823098ad8d9844a25b92238063a92040c500cc0bc2b25b493e4cf69de95c87b03b773a796d13f42014847727345888eb06d9251aede24d03e292cb452a3a38a0a461c8b4f9cd9f87b09bc0ca98e62e5027595c24792f818865777a346004fe3b5b587452648263aaf688154526d591acadb74520f3627d7395ec7b71dc3c6e8414985d591a05c88b6455870c48b12c576d7b328b88795295c051ca6293b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c83c28baa424b19370afe997d8b08e447a2eff376024f5ca54dc8ec0972b96f057acf5a6b0d32869fab3e1797ee2571b1620a076082c4ba6799c27b07fb073092a7a2f7aa110635cb94900e487a6664b318f54956039c57ce509ede489faabac96cb11f58c87708a8ed3408a526701bfb8507d67415fe64e7d41081ac12c21f3092af02810c604f02c4064e348b4f98f6be65d87650eb147b4694b12c461130f3126f8f71673e4643b2147ded2a7270ab360f6303dc05b03a314bb776c488318686069c3a4c91cc62435e829a6a8621ef5cf838311a4278d7f453ea5484d32f94c2e9628f5532ff93771dae106c8ac9cc80ad07d306b1da78463a08226657680e5acaba6819543cd96194aa5973d4f7b8682b13a07e7a5194c91ec95a2d671a2627710a4c78aa107b3707942d0c78f3eb2b3a58b7833fcb0fd7785e349a2f0027aff079b62a68e3f425122f7bc0a0b4c053a6696f90a67088f139b2a39f542d6439091e4c1a0824734d8b6e5e6483f48ca738c39a5bc2016c0746cfa9c1889297f5377d614acff2833ced20abed0aa6c7024221b73d53610575c6d91a262a5e834abb63cf74207437b31b1e989ecd7416b2c4e7bf807b5f8973006877e204a42774c93a1b394e885cf727b7fd286def2b4c8d5684460219c31b1b225aa08ac2ee1da3922e935e981b3b5e2c3d044a784bc965a580d3052ac48000ef6183b94b0a870e65207ba8029c0bd34a10443e5706792207fe2224da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1a518fea187bdd08072e47588527c3b9a5eb244ae9e910f93c92b69faa7250bcf38e68e9c3a2b2b733b18032f37673907097a4cd65a9b396db4859312d59113e07b39746c52126ea697a69929b1b625b5ae1b809ce9a811d13cca70971ae8bd6ad223206691af6897f136cb451699e0a19739d52d60cc89dfd654a320a79b2c7cd55116843239d6847b8bdc1efa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93dc2a395117426a17af4d404151814cec80e856b777eb35085f1ad14285078803c2d76ac1d25c3f8609aeeec4adbcb64136516a2077cff4c13748c5d1fe6386782688d944e0027a2f8c9af77b79352ea5523767cbde4577877af1f8017e4db244e833e99dabd0fc70824bc3c50a38275040446a5c74406873ba0b5bfc2570a406570b424727379e5c1c39ec194a29a8aa249844bea2a078c1c0f25a400d6bada80731a00b87bb5a19325b4e79b78af0bbb2c52c3db38ae552ca972c3927291145438115a952bf2a85e78f6141e1cae8516b056e614b7015017e71d54268ab9919b7eba09d196768d99651d60a334fc443c8ccd9064a420263a68531f0e86cdc48776a3d44b4726916273a0d3002de095526257bc5e6246dcc10814d1907885207a53241a184ab7e40d87148a336a33262a4bb0826b417abcdf957f68737adee682194115348ac58814661765bb321254a874c4a3c6745cf984528c2b9726ac35441015233219e169d0ea761425c06513720881b330185b48bc271b275dc024419d8761eb23801eb704f6326f162656713acc2915a1a6f877a583c8372cc391ebcf2cb22873c5bd22c58c80640cce759b2c09b368ab4ab504c613493479b7725a18811837213f9237734577af09c4be0b3fe07ab78b712b0683060be76920cc5fc56993e56c7b46a543ad675b2d13357c008911320e0d292268768b8370c66ce757af191bb703cb5732113acb8f02618eac98693224abccea04e7b3157c03b27a3cc4f0b880dc4877ac35077c1c2d5584b971261d2c4bb767c75907827ad7370f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7eb28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = cd3583987c6395ecdc3ef180fcfb4262be1bf772a99b337df5eb36eff544d69276d7b4608b69022bd044fce397bea7d55a0a37807b53455ac6fdea5f0435dc71e096568cb19afa1992770c96f34f9f2eb0ce27e5e3200a47bf36336a1104f9de0d11706098fd63bb97123e29bbc4661a4f6237378e23272315a95b587ca6c289dfe0391fe12a18a257e3aea5a362dc0e60875d65ba9524999a010c23d2cd094744cf538e461cf77ee3ad166e54c8f7d2a746998d08d25ee34d5c8127c1f2f13aedc7e1cf874c087e123d9595a4ca40a482fb0696871438f0d3b07058131e532aab8041e95a42cc35b3a5937c59bec36be6b7b7773f60af694ebab7104434c23cc78e122724a912d9921b4aa0b1a44755161264b6f9cec639d4a7059d0d08ad9d1e2c1cfa9f0689dce97c04f070712bc54e19e9c053710f9ab5777fbefca8dd81761f93883f861cf5ab169fd701a39b9ee3d3ae5d1f961ff5b07ba15022f51deb1897983f2bb94050e099b573c2268e788e406dcc1e666734e1c74305bffc3c9a6f6b4ee4726694d5ecf499dc6059a17482b672df791ab1495e3be6a1cf0d7cb6a0c88250c19937f5233cbe4c2680f31c6b440c253fcbaf8de742c2d8af3f3734b0e8c433a7db21b105bdcf8c5717c2dfc8db54512492b0eaf284b1a6b33726d055d5e222ded00da6f81bdc30b728226d0aa46b64da409e2f884c1972fd4d123ee016b9fcbd7abbe92fe028d8b36ed4e9321c8baf833c0dca79d4ba16172adb1225d3db8f597bfa40bf58854641743b40dc28e8de9676f815eb5244499cf8b4a15d83b9f864ac4e8b1c0fbb684c3c2056abad006ec44b0c18ab5366cccc3f4871ebc15cb94d61ab91751d8a559b8dacea2b66409095460b7b352625782ac17c976936d75995d74c6f89318176951474c07b19d31b9bcf63ca772af3f923528839abd1929ca63fc6cf5d67435c34675d4ee6caf474585c65654c3d79c4e6ea59a42e2825c229a364a29ee84eb78f63846a7ff08b21fe077eac0559b91c91452e15147ed5f7109c59b510856f11a63f355923562aa0434b2e16d6067dfcdd619dbb80a68be5790c195e0b9d3b9e9ee13273290fab34969bce02c5eef6867b0fee382a7159b4c927bf56d29fd0d849831212386a786c2a9bc086895db111c7a3797a40c9236f425454380fc5a1f96e2df779f05446d123cdffe072aeb9e64f87f3f7111470061d87ddd0b8e4dfbf1aab0604e90da29ea0659fefdf17748425b2730b8046af71f948af2ca5363eb63d2f0399a22f8d3c01414c1291a5dce3cd654206ade8758077275458c95003452c1078cc787c6a4eeef475b78bccb0419c0716938a1ba1545cc87dfab4b18c253d8b7408093e2305359359f80bea22a69709a89f4b1a70d62b529d14ebe929a64132a1b53c7b6cffe3214eadfd77d385113fe3ca4a743cda6af120b25009b5bdecde4d956beb970b8ec1e2c5b7647dd5bd099f3f843c0aafb2d00e26b1bb368a82afbad3819bb34ab810ab55222ede8f28486a7d +expected_result = pass +expected_shared_secret = 2a56a7a6d5b4c0500ec00a92e322e69be9e93006240889552072482966c54f56 + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +private_key = 84d7070ee80107976bfd1b0db6cc33f3c98178817d8460b63dc012311638aa43b253a705bc994931bab38a62c5d1dba793b8437bd600a8725d36aa898e353d6b955b80f8578f855bcee194ce2c6e4c6179ade8176e34578fb24b6d60c395b674a7a8a4c72550f83a09d24582f94125690428a4e76972b77a53e852ff3718a440b67d6521ca699e5a8c434dc47a38032129bb76bcb4c810028938fc94f1741a1fb26ec95252e259b8f9176bbad8763cb63da6f295b460cde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b24e09d4144ac900b43cec07f1dd2cc4f7c976eb0baa4d8637bcaa70946391109981e978ca023313b200092d26ccc823ebbaa85b8ba1680636d0be656f01769555b058af7825fa00d10a38b0a2b127a773cab406c1d4310a0882889759f20b44aecf68dd24416d9491cb523a1afb1a1ed87b28e5589f4059132603e228b185d426f49031af8fa21b11cb0f37c4557f94b2f158340921f95091128c5616f54105d47253f150ff335081d231f5b308a526b9506b03e0b5c6a88394f0c9c6e7c2b475c7508a3a8b1e0d571d1c364784cc8a7ca7ae6c2b24366a0d2865658d42a8495b24a16c9a9d8b1ea77332a1058dc292ec02c4723fa7204e93eefc24f10c4877425975cbb6142026a2aa649fc6c77e8c72dd3e5b0d9e9495a02c251b12b7ab51f6a9853bfd151a4873cab4102db62676496a8b38c8038e4c6d988880a6b2774875a5fe69693d9726af64a51d77a03e523bad8b2a6dbcea137a051d19e81059d07437e38db7891956c5b2c8abe282b5a02a5530c56a7b4b46daab256588b04344365313a3ad94a2d7aca4ba7072cb9259e2676a5c86215b24faa159bc18bce05451c69d2699a056ed3f6a7f2bc7676f11bb06cb72dc53d7ea6bafee89797b57445f3ae11262543a2882b863cdb455d5ea03eba56946dc61d798a76bdbc4ca7f2a102c518224a2091211ec4d251ccfb08aa2598065a79b8b61a56e925031a579ac5bdeef1a6e0b1381fe180db008f19e775e030052a624b91d1550fe5365260150ccaaf228acb8fe471d2c8b4b27bb57d62ae9ad9ce15a0b72ed98b8a619cfdd3a17ada37cc455d77640ea327088e9c33d4281b65dc9a27c68d27088b1f2a5fc586bb0993753e62a67bc3886048274ac267a95b42aaac3e60c2699321a79301acd350b92899a2c0ccc4703b243660a39c5901e3b6bb146c588dd3431c4a5bead8aa29e04f8fdc0d04783751707cc25ac359952abe7384f839b42d9c9982dc66a21c7fb5cb7316748423e25005d389bcd56fc498080f88cd75ec974ca9ce9f2ba995b50eca85cf09612fcbdc492ccc6d0662a59f8cc0ff3355f17424abb6c774a377b81c12b9982f60777926ba0b860123434cae8f926e902a5e633019e3c62087a1bdddf2186768baf91656d903c4f1ca88163b8dca041823bb6ee525583816cdfafccbcfe63dcae0b93c46a14fb72114194cd084c208921925e7c55ec807ee6c0a8ddb71c4ab3bd5836b7fa160009dabd1e5498d005718548324b0339ec71ac4a75c81f522dfd92b64e3676b337758490e068c3cc747bc004da30cecab9c542ffce826c0c8122855031d7bb0ca735042bb43b8ec6ee13061046acab9b873b13519c22678ace2b59f92aa4e8269844b1de5e3426d66c0451a8d78cc07e719033a536c2bf4c7397c64c6478be5f42a06413b8b44111ad9742b8b020711446d63cdd64490c0917557b884eb429b05dbc0df7acec032adbba55d3e104f7bf391cba28b903a07712a8da3a1a92f5682cd650a628573844032a307704fe77af738696e974181a85c5ca1c14f7546f8713701115883480be2cc686625a37b62292367b5e1546f4189592639cda4cc20974c6a87c0377d15b8ec5c84b70233b64800b79c62e536553b43263532c6bc2b726970cc58bb20f0c0bd35b317d9b66b327bbeb5175d9611985ad799ebb19ad0587aeb856c288464d983256649827de9af0fc79afa1aa5817c06d3447a25ab3eb8248167ba60a4462ed47c007107b1eecb630ac4707b837f24d26da46bcda77c4b6ed5b4118b79294744788b9a9c21b168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb8615262408ae25c2985189ba8ab99643624b70557a984011474586c357f1c7551f0bb069336fe85bb903040f48c4a111113507055f2716d37ea6a6ffa48f40584914c4738397430d65756f298aad345671077da8a4173728364a493bdca944b1879b114166cc3b8293937221257c2e78f8f1c7794eccbf0368ce34921a2ebb01e32a92255a676e77c39564b575aa5d1f9c7d1388226d636f4f12c5636b2e2f712c59ca583a811bdfa56448c013cc820f21a36c3351aec3c2c6f01243ff47bf17181ecac752108c43a97729c6b9472270fcef5a7c08665f7aa9faa55b152163e8446c1bee5082192b5eceab269ec13e7879da3768bbedc0a104c5e9496c63e9507881a4c8e758211076653f369e58b59bd7cae5b9a64772c2a84329e43f492fecabbb56514cbe70970f361e6d3c6595065f6cc668c64bae7d587fa8bbad129136d5c9b6f757a51e653d2754aa0e35307845a55b80086d5a0e86302d306b9ee1550419b495d424f701a098220897fc47333d5a1e994c8584a00d79804e4989a1cf02dcf9a0ac2ac52be1090bb149778235ff6091075a5360ce095cb705c81e3be126984f51aa471f90ff98c21d3989fd936502a8a2b38c4a2320a618df751c7099d1063495a6a5936c744a094cc1ff1b04ba8b56b0464e852bbe06176034cbf5239cd2c687facc2cd37329adbec3a77b4842aec40be902e8af72fa5805345668408cc7b6073097391921e765e4d76025fd5c78e246da268a4db21446f2cc3273861d2081daacc2cc775631927b709dc1fa8993b1e92619590c08940342219682af351495b2e0aac74786c897fab196abb609e216997c2c7b283bfefca4b1f2b1b6e98991bb32424321ab7d61e4d13c44dc93295a75f6145bf2d4b8f1a03109bd7038ef4b16fc15f44ca6ea3411b68400eb20c46c11cbb98201d705a6cf4f4b792aaae80d97a6ab830576aa651142793fa7da0b8bedd877217d54897375ec285849a79268babace85176842c601ef8c740a21c2c5321436a21cb968ecb5410e811912cb0962f713322021516535907914b86e9411d27cf164b580528768ad37b57300dc201557bb0a142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d066f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = a611a3c02dd6d3201596fc2e819f631c7c468d7437c5cb5e1dd20d69079b6397e4735b54ad9f14ce7764e1f7665ee1027423f129ce329d4f89d967b7e9a1f1851a86b9241695db93f77276c8c13e115603394fdce1e29768218f10b051481ba1477b0f50424462f08232899c6d0da4d1760e9baa2523a59ed4bbaa1d56ba1610174e99c81d56aeb8f9811a88cbca115e98b4f16fb0593ab5ac3b86f2c0c1b66d8be9d2774b66c0c2f0f9cc2df6ee453d97f0256ca73338643438b03e3c59ed591646afad1424bee637a50eca224adc62d447c64c3b18a55aa01b938d66ab90099a76a48f201cc66e067d4db6f5b4f58568eefbaa68fea67ad5eb8c253bf4a1c30ce0c1993bf097f9a9b5d04a92fbfe666e326b92ce22de4f11d3a87024c315e94e4c9aa404cd5e4d2ec1d2c7d95657ec50e15ecf10801329ab243f1dc95af92518fb4162656f1aaac8bc8bb8832a6755e29d7ff78fe1e4b93578fae62c4e6b2d896200f7523427f55d6305b3eeb5285a47db7c5e4f628d29d2ad39af473167625cd848efe6dc72e45d4b531b4a0af4dea4206a6087d7a494f7e7e27ea24b5650fe06aefd954da1cfb8691c10957ebfcff92a7683ea584b112bec9e0a67f831b305e72b7f3e58f790988e96ff9fdad1c6b2b5f5f03084fd7a7d6895f8e7bea32a344117dc9be191e89abcc8888b72f091c0a742af35be4af72a657e93df0b48bcd602e3a7141d962d692a3ee90b33a625b83945356b13ae531a5d43f30afa5901bf791f22650f3f2faba02817dbded8b9712b7641372d4af4ef2916b8cdc05bb5800c3289388e2fdbf07f2fdb95b154a2e1cc6998ece7a514bedbd489ee21cc1df314b4fbc452c1378bafafa083ef00842e2dd585668eef7b00e895f013edc2611ad882e76f9b85074be087bb9f8b45990d1a65053eb561a34c8cef2b61d017d50055ac478e82c6fc881e64cef53b0598b0e354c2042325d5a55fa7d592bf8bd8f01fdb18b391a069d3eacc373765859468700234138d0cbaa4cf64862ea30b66afc2ca9effebb733e007fdd6fdeb483d5d6e3523d32092fc0fbf94ffd7918529e192603a609ef632202c37f49e34ccacef9c1be4781dca2208097cdef7365025141ef427b789fa4da96a07d58c2a22e158de7b4394c38e17d98b1e363579560199088bf6bda0e799132ca391849ce59c0742282d20e2ad70df32d8484dccb5247322514f6ab1588723450f4245920c6551088f0a2d204b6806f054c185501b031b0d1885c33ca17ce9124edaca319c16aeb066295b66b86b70ea7762cf502a0b6d785f645a3283e2f9c97fcd54ec07ace7ca8ba0fefc013c201aa18a3c36ea8592984783e128b076d5b99a237cf99bd449d2b92eb66c1c2503ff190ec0eb172f6d6274008c5cef30b5b08a1b295d437b357fb2febc2bc7a480ce7b22fd7af4d2805d786f3502d743fec304d7ccd0c42d25a7062049cb778f4492ef4ad90a97ec1c2e14ad79248c325e297101e73d65960aa0085f688d41cfa95e31744e5e6483 +expected_result = pass +expected_shared_secret = ecb62b03f640ae4a9d89685fa0070efa93c24dfcff0d555142f9de25b62f861c + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +private_key = 47318b2cc6a9d8bc6ebe7c12489017c03214325b61a2a8541fb783c448c3a31c1d82ba7906b09e3512af8d00d0706a3d391281f0315044c9c4f92b0ad72c60e18637577b942a442589cbb466ac344438750b86cc86b97d16339a9db0365e6696b183041543b031c9220e82bfb89c21a5b0a0d301109568b1c00b2b878c9284375949c88394f141abc188ef7607cb8151bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee518202c9119c80081beb38caff81f5ea51811f13be9491f431b127783227bf9b691031145d6a144213fb4f1c89c38c00c81abf075c4415586bdf28b946380c948b94d7a0c3a793100842230663f4eda9174dc7214884e0f552a50d16dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4bb22e174b061bc80e91428547576b6205490ca3934c9b15fcb69611a1639974478800b2cba3d5243a0e2762be2f87035295fff40b56be37ddc71915434c4af6472c1e5c519506e691703c49c715b50b360a5c2fcdb79f59c7ade27380f9905eb7aa6f5042c6a32bae657c699eb85a53395c0303e87e89800131f96969bf45b3f574a40ed813268603a24f1c3180607814914775350b88a1fa7e1034c9cb155879668950ad5950803abc0cc58bdfc408fc1f2bf7d3a2972aa66b58844c048150c0b8c89aca3bd3269474875bf10a94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946d70b8b87c56b81b77024503ba87485ba3655f669770410e89fc84925b87c008c3cc13c7b9447d82fc2932a1c641230725a422b6219d9bdb5ceef17e121132e6615075e0b26cf71e91a1593210a09507214716a3405b2503ca5f29d4479914cd10b3457aa62a6bb71bd08736e1519e69f709b8c8439b4441bbab5d0911bc6737ca742747ca592e5ed734a8aa1b77450a9d4188e05422bd9240e285865d530e718c6f1a816153cc27414446bba8129a1716171aa60ae086ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee6603f7993083724a596069f3270c071b6bab955844a081a896096f76059b9738d819ca3b6588d5f578058d28d2d0710b2bb2e307a5f9e18533713c41e172a99614a97c00ac0a83a25526c399cc9fa9b74cc4774830c8e754231b04274c90c526dea7fe3d203688114e7a90d3ac02ae69a139649b754581bb56825a215c3ba282a26c036e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781cd09ccb64993299745b34b6d7f897c0e05e1a6966e6757dbee29af2eacbbb7701dbc39294db584c7c3a7841112258951d88145cf73404a17adb8cc4d11788225557a83b652f95053e8507093b2a8b00ce77e7bbbe83233dc18880f2274472c05e646b90952fe92440d164092a058d69c96869d8a83377a2da92c2d668607dec3cbefc6242b49a9da97c19c2067722c8d309cb898593b08b5d8138bf2fd1c59081614f764acb392d7feb205a85270dfc1129929cf7b53d41031c92944972b8bc9a9c494ab384996647e177a87a101c45c747660aa4a38088a5f7919ca46dad338576463a1c1425a6c4409e2ba8217827ae83bed4e6c80ab528a6bbc1ad58c868b995d9f72c77e84173c9ca80b3b92647a1dbec6bb883a4b2160e4dcc84c89c6adbd955cc055933d3238e325fa826acef899a555873a5b9c189117844202c65e40eaba07d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885660b1d3df32d1bd50cc50757c5227928b32e0c567872e66bcb58128b15c8696710a7b33bfda469128996f6979f896b93d22910383c90d0d877a56b4b7c77c53c99128719c2995497dd36877276a25fa8b74a4947e223215a314a075585da457daaf17c41711363950ef9013a8ad95f9e07635546485a3568aa502d608321061a6999057e705c46b6691183874fa9ea38bc392f718c99ddbba59a1865a135207a00058a408b6c61772ce777456c92b28a51ce823f7524a26639ac64aa49d6903cc2b2b5b60b59643bc950230362caba6abb5ba4f6964331b1f62099cf385be3f5b43c2b8402006bb3386f5a16354e45118f0b759c3363ab4069ec2c4c15cac4e07a24fab0c682548337d157e6ba213c7801dc5a0a7045a442b4939d611469746e9da665e2e910b51c56b77a035900b25490216c0bb53e04173b3bc454a7a17d77283ee278e7d30496301480c8c1af6b3e1dca213b174f968c8a45a3ba2044bddb1492bef2af610b4ed2481ae0823df53282ba7750fbc7a764db58e3789ccaea778083c27ed101e3c75be5486249f9818a08047f97447773c7dec3ba7c59aecb5778a09cb7f1182b2e0a01c182a1bd13ab7d72af97f96f564607a9a970b35a6adff275c35c22c2444ad6e997d821c065ea49080900e766c0079b7acae7bc7cb3b31301656fd39591e0bfec2c33f05a0dd633bba463781f1c519d902342bc12bd16c1ac8305ea9769e489073297784ee45f99b248670749c728385f601fc84c1ffb298bcc447537785226bb5de712b7bdd04a0ce39226919105f06ecf6bcddb0cb5ec3b5505b5a169b05480b2587ce4934d2b232a44a6683920a81a6038c59497c9b47faa62f4f2120b15c360616e6573bcc5a23a88887b50d1a7dbaa429bb00a9f87b63829b1b641922425016c979db571ba0f1a139267bb362c68f47689715cad6636402049c2b5c616c321cba6e43c1c1a48a0e141cf3a71c0099bd183a5c0e59bca9a2fb637c1b534cb6687493eac495acc7c5fcc4898a52e44094fb1b7014a15c88e11a9e7244ee53c2d5b16708c233ed37859268501630a296d63c094f563f0e559c59453abf05a93722aed5ac0c3cc6a0be7890f8c3191677c21f70c8153ced3e2bd96a4bfdce27f86b809d8ab04dfaa837fe030f420b845d23c78cc82a2d7c440897c91c3b726b4622445899de72bfa263b93c3cceaa8500b4b0c240046387b25bd98b5901aa670180a2a8b27de424f4d804a68dca2e044430d701b67e9b4af33c60fc54bb3a94a8b8604fa5882a401a5647b8dfbb20878e4b4094136bd4b5bc14288463c2e87f0cdf6d9497fdb5f42f26d2f9ca2e048a757a59b440c2c5642232e714d11fba959ab9ac52126bf689864ac98cbd1a633baa3ecf75c09c4c6878994cdcb3e882798ea02aeaf39915dcbcebfe2ba14e620f53b3d83ab58bbf99509033db99b0acbac29fb4674c95cb94982ac398c2771a8ab6da1ce9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab397537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 06cbb7fcb9fd91bf6cbf7f1c8a47511fbe998d1e0c6c20ec92ba6c6d86e71a22e7233c44494ffaf7c9f1075222019d9a57dfd3f9754905a5ebdaae12d2e2b16b537eb00ab967016539ef46700d15ea21fccb92b17b7edc5c87e58ec518f167acb81ad4b96e4e4d51e605b3ae45fa0d6816c9c6f103bee9687ff098f1543fef241b80d1f6ba194fcb9f21ab1f5a90bf7053bafd8fef1104ec367de4525c6f60b01180b9166dfb66f192ded9707cf59c16761ec1970eac7b031821bab340f23758daeb9e36ee899ceed7cf2c42017f0f808743a6f7b97fa7bcdd5a35a72402da6eeb5d10e4a1ebc6eb5489c0bad8d529fcb47f4c6b4254ee64d31ebb149c975d5e14b7ef9ee3fc64bde6dc0019585e66f19a99ffd1db55bc58a3aa88ef7a575f2383f7e781f8b41d36bcea14d03fa9bb65a243dec37efb3fc19622340ab99a1183fd55eedd7c4d12762b7d5de711dc182b9281a5bb75cca2a5d179b2213fd7c940991a30b88297f0a9d307ad443363bf776599ea76bd25ffe9929cdf7a9e148f23e51ee1597e63493d54c4d9487cdb8f524b5004711af2276cfb8377cff0787c615d38536167b8431837492069b2667cc311d3c1be3381931e702822c04ae2041cd3a9e3a96527efc1f427d60aba9b4d0327537346bd853bc6e9486013ba744e922931490b841aa8bb1396f05a11bc1346c86164486add3be92c27b76f1e9edd2ca9150b1ebf682097341fdc85095dbaa32b7201af8b2672d7ac76c5d2eceb2b14eb911c48571a7fbdb6246300701122374e761a0ef1d6392498ff8bc3f82f77a555820e79d4d99e9954770f0259b54f01757bf9f19ea655b2baf3f4edde69613cfcc1cdc3c5997ffe893cb2c65fc70319579495c071ee08b18bffb1066b3202bf75313e45894f328a56a33299f3b9bdd413cf5d8e7c299ee920ea2b26d5e0d44f994f76ed0554ac767427d73ad1604236634a1d294b1f246c544a2aca45b0c35a7cf2f8b66390f1ceef3209f0562c39a5f340c85eb267ca91f2a8786d0bdad4968faf8165c10e2cd52f8455fb7d118dc1f75517a7ee655ef7069840b8ae9a03b788bee0ea758cbad93806896028dd050e6f1a7e62871e7f4b69e5beea271682dd667f01106dfe97a423a4ddbe0efa184985c25a20fafaa0cdecf4c940c43d4b53a10508e13cd703258ae06072a88a4ec02913b6f3bf7a66fd7f207dcb8ba2d988a547fc3d1d267746d0ff35c4975c3814e53041d2937a2a19ca7a639792c132a64b035bc6273223bbffa5cc5b65878f47ab6b56943a2a2ef39918b2874594f803dd5f4cb5228b41ac59ff34dd50890d0e99f24891d4fc04a6f30a4311f958fa8740010f74258e87727f855a4cc466f5d12aeae18a9073071e0c4be2fc0cd130431fd753630de8d347f6949b79c046c0b90e4e636656978f3e5852bbf6044d9964747de482b448dafd3f7b8e169cbd1a56eb7a803e1bf06dc11bf65a0adef9eb33eb2aef852ffbf03afb82459abd087a9f260d776de5f735a311318f41c5273481 +expected_result = pass +expected_shared_secret = 6cc30699701927e07b559d708f93126ed70af254cf37e9056ec9a8d72bfbfc79 + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +private_key = cd28aa8c74142a0508c2534d5adc64284806bb2c653bb9783adc640e9945c253af86f57c19b42c6697ac85d1bfa46b5231559c11f5a0da9b2bf43c40001d4e6c00b81237343e15a41da190cf8940b641a4b42b72d9cc8bac681369dc07d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a63c269a5821557299ff63b9f0161368f6084132c8b56984f4d1626d7436dae2596e1b24a86562374b066d2483a1b354fff9766845480ff396f6ad089b724b0f15a34c2288deb05a8418909803cbfe2f3c63c30056f358fab798f4e385eb0e35ed0c38ade7382787a2502d117ad0bc6cc0a4746aaad23345f10074b21970c18eacc898472766b2313472dd3348c82f69b7d961cd35a8c61984e7ca20ae6382f04a977a72b532a1395707cbb7cd595e0da0202498058e59f22e0c340c438851674e3ab1e0d872fda3baa7f87b67f449e6bb461bdf1cd771475d5b59facc30181599ddac8ce68dc2de5741b21422fdd512b39d9633adb202af3941e323c9326297cb58086c3282f722c4d50b94b32153ff30b91f07a811a9d9e07b7667846806b6f7071ae29323156b668f831a9f79ab7949cb363dcc8d151349db4b5ec1266e7f5af98105c95c0a4d47648aeeb01fbe1113948b407fcbe199bc2cdba40257745d765c6a0766012f19df41a770e96cc95d3cbc70549f7e61914a73dc71062f2a3a377ec26ded59e0cc85b11a74f43c3237c7561cb7046c0e660b5bb0ba0634ff2b211438a9b9b906f241b04b2439f29a3cf0ad9128d683f0c2c26ca050978cc179872b1664a751458c072106fdfa07d97105188278268b0481018782f361d08555fe5799a0654398285b378f7a9f143ce20673184c75e8b662085899812912fb8a60485921b2f7b3feab95cb7aa327d8b9dbcf7c7256a131270b731e33f8f555cf4f8b7a1e6aabb4c83d2938b7b21beb1c3b3cb3bc08bf52fc1f5715fa89ef8e205d85862f6a2cf420592aa24568fa0b8dcbb90d0b654c7c82c7411b6c3e219f46c352aa034c4fa0aa4fc47daac204b351497727b96714359a66466f6c4cc2b83bf6b87785367c7116489d6c5feb975e41c4bbb2a3d8fda920021c523227a438374d96032f62c41b17422584ab5880475cdda8b7f4844e5420c25d97235b0acf71012adab59298bc80052aaf1807e8015695d92184741bad318ba9ae27c306a2e42c80512534963b70b9d0b7f5ae70326c33e7d43249e8c9ce386947c167c8f33c88947244989c45b4858203249fa5a136734153cd94f1ad467b5043f7ed77f58d34490d1b5f9e323f3e2146011921b8a9f94e419bb85ad965443e7f4a73534457be43ee5f677a63a7738762b799600fa0b9cd328ae4cf507c1d9845eda77c30bb7c39c618afb402cd9b016f0092cb61e8be13a18925ca122a142409b8dc637a364093cd76925a194aeda21c61709255ba2de330693b888a6c2c6f0c39fa5b4c7fcfbcc198b3253c0abc5ab5edfb438ed3a82b72b5f54a39d21c37879480c4a648f182a94ea566c598ba4cf697140a20fdf4cabbc540b80e8664216a6e880553899964a7b239d00c68e720706512cd2a58b9c49bc0acb90283b506ca196f7855ed69ab21f059a11fa3fc4670d03a20a0337040adab8bd449e0beaa93b07512485ba33f291af1a44540bd04af4a3dd2a09f6454d7304d0944674a580551061ba5f88217aa57c10640dc1a97396f138c1a32cf40b0bd9286f88c4087f9084a9012d248c63efec072d77ab0e736719a23a913b7b8b62aaa5bb40be97cbbc1c29edb283c776aeb9b032e2c2691aec9ce89617b84b09712b40e2b713e566c714e0baa75957d6ba5062ba76471357252b72ac66ba97e10921ca2313a232a6ba908dea13645b5617938381fbcd748a11f61cbcb615c458d056f0d55a449c4f544c6673322ef106010cf139d1c586aed5a5dc210fff7a60f3138c34a4244398b692c567ade5beb55c1edcfcbd93183e1ed0c2aff5bdab67b51e39a58bdb8388d67cc1ec0d7313b7ec8a56cf3c9b73214c4ada14592794749b6834e9b81a2ba47de929e9ac7856b56549f40f38f0784ba0cdfc195952d3155222bceaba0e3c233ff7e19a65822437217a42721f9c060ac2cbb9c4e6bfa9fc3014d8add7b4bdf78291423511f9874a07e06a82b6369fe349e08333c7f56b7b7b808a0b4e888a95799a2df4873944cc43eb958b1508c66e571268e79a69178793e7a4d430507e1259d01c86f999c16772cfb7b4b330114ff55a51ee5407bce95a6d27875a91773420c24f8734b3023e9db777819ca2163c431de46f22f38398d46ee352b815b6b07e1a242b01a4230b59ea8c7b0c3c3dbe2b7c77b4c860660daa04c452e391c710722c67bc0632c072fc1e5296a2e70932d4d38efbb96bd636bb41260a7bf27cf5e71ce3708e6884cf0b8584adc3cd3b5c5ee1003a13731704472a203c8f9b49534309bf2b60cc3e2448e02b5a46d889ffd78fbe722a709a2d5b5c8a7d805bcff44052c553cb990ad016079bd87db7573eb1d431d1e549edc8ab56a0bf52999f32555e8ef2b03182bd8d812cca638055a73b548c8b432a2a7d4a6a074aa212d50362d1382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1edd04f8f8cb7af4c947af224dfe0af6a42c7b65120b9c18abe9161d88cc5c4780fd74403cd177f7160281884a11cf686f0f523f39cb7ad39b780f13a8ee83c0d646f9d85babeb306d53a7df53ab00b5a1aa8c215914a48222940fee10d1939ba5c93617690cae113a59de071c969436b3771fc50b2f4aa641a4c852922380a420fcdfccb81816f4b474a2ab293a4d97b2b280cef031148ea7e4c9c0db7e7cd0e50b203a6b7519c3cbc8062c9b60b8b81cd956463b8180c67f34be4868e3ba94b9f0226d9f010d9ec5ef0bb62c865c807184b96526d94170af9474bbc100530f7c77e46b98c2aa41f92a48d8027c855c7f84684389bcc8e7c67164a204bc5c0c90828faa439fba235b6f20785cc8ef4c090a708bfbbe26e1933886cc96ad9b4562a119d4c66589c85bf0e55606886206734142d432c1b032e0aa93ee3731f069a8cc069a03b95a8ab873b447a04ead3a32be3054af834882bcc581712be18539b805577e50ff5d982c98c0b0dfccc96a4c6429281068c8429997dc17a6600f0736b8453e3d77636faa8d0ca89f9193bb34819ca1117ea368ea23198ee11345c613993ec052992954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f3082f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = 3a00a38b5cf0894322b8f5c5b35dd486f4e4cd14b18cb3a101345718ff843b13fab8ae89af0bdb731cfbe6c5bca36200e5ac90b9faf0c7296b6ce324513504bc1ab4ebb91e77e9736743722cec11ed929a2d536c25855e7c28d1a6ae521eb9b6391647073c55ed0fab85084ffbb47552721bb6827a0dbc65bff589165f25610ade382367ac20c48dc380bf89c459d98cd5bb01da5899431e29b938262c29e68898602dafbcb9465d0f166986e19d51c00c94131d3a5c0abd1ffbf793d6e9a52e5e11d72233565cade9c20a8810e55f4d2fa80072db2c1ddfd98681e693730b693c3ad8d01230e45aa8822d191a8bdf90cc62829dcd40e75f568b8f562aa61a6a9c6a7d1be451ad6bfa404216c102b4d6aeb4599951b0b96cd81e2a03d825380a96a831b321c6f14ea5af818d008d6d80f28b93f2e3bbe22195d4ab020abd3af6b545473250720bc992ee57ed9f328f0cc1988033728fc2a28dcbefebd698215b3a91a05ea5270cc8bf8b0a1ceca7e9bc13bfd8359892c795aa6360e1fe6d8a2965356cd5ea7f4f8740a2e9073126d0c41f07fad51c74cad707c9f83140a2370fcabe3e9f48673d9f1d007b41c647ac0d195f279696ff29ba14b6841213b7218d769be8f684803bb1d29aa6df3a0d6e52f29b19063a81f1446e54fd8f1a6887b0132da286053836c0cbe97bc36c8770198e203908d3496c43941b35257dd86fd1a9c5f5177b1f75a426b00ba9162e1630779c6aa4dd421b4abffdebf19472a3c3e27d270d30d17812c49dcf3c5b49109800625eb8454098e1f994bbb193c2f6260caa9ea62cc2eae8bf26255b7f3b1a2fa57231f00a7cd97387d5348d68737e167f7f22f6f4438b911a040e142fbf2d9228480d83a474d54018d92635bf2c14ebe728bf901689f35462801aad5545cb411fdac9dd55354e7896c92cb9eac3aa0b88fd6e2b82f8c93281d5fcd7a490a537efe83e9f3b8ddcc8f8a83a081354f0e9939f77f8368fd6f8aaa98c7019ac6c2b74a59067d4ec0b5c9bb1d7f0bc6b6e06b05d2332284eb5f24cc35e14af83d6633020df2e74c124bfefabc42338b4acec89031cbbe5c1ed3f2d464b77b4c479e37dc0f5d5d4497e1b97dd00aad4fcc47013791b2ba6f098bd751b66b51971fd886c03cd6a45addf8ba4af20679c498ef3b92f793d1f6a7a460a665c65b58796f57f1d8da4c127a2cba6af842125ee6f9c10a1cd9c9f06cdbe63ec6ed979b6be2048db2f83e4cd16a80e3ec5908f8090218e2e9f97b60707337dfa770d3ad27076d9c0b0c7aa1eb8e220392e3683cd19519660a17661d2eb92621f59a75a8c2e008119465793477e055c14765262b33347245b96dc1347792ed7271c5d20f73def4056f96100a80fcb89f69c451da786f045fb2556a2b3d84aabec88dcf99d2016c3697cffcb7f8f452c654375d1eb30bfd9a7941c6cfb1193f1d371ab335966aae0c14b68fbe23f6a12f5160d786577b2ffa3af2dbe46fea002bca529419faac0a3c9da0b2c161beaa83422fa6e875f63 +expected_result = pass +expected_shared_secret = 250e7f67bb34dd5477471e3a701fb71a8138a1920eb807824380f88a944a6fa3 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +private_key = 8dc4a33d0a013d102a7ed6a5303693669033816bce0c8a83594695531999647a48f6708c65220be4d9a60f013201a36ee053796356b26e3617126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0e127f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab222318856ba8b6919c5a0a667866c0d2166b69ae04432c044f289bfd7255542cc7946b82c2db388c8b656f234a3b607c2f6611acc3a5a12c8111e42138abca9b8dba79921a177682c2ad1138b133636951f5aa77a52b7554943af52f7b53d0b84ecf44fd77018f7062e564c5e58753994724242d6b3a8f8a66df518f7e13a0a5c1c4b253dce12ae197342f5d72c296498bc9888ec347f528958aa689c8ddb81870184c9e2254f918b7465354826870300790044165216c8bc279ae93854381c28cb438bce444b2258afc3a84cd4f91de8373f877b30137c4ce4664e4d330bf763b344489604e97f4c9c24ffc226d07c5824ccabe38cae22487ea2ea0e89920f304bb911b401f45735089512dca2298ea1a57f643cd7524a3d6c9f055b25eaa62fbda318a7b8c8dc9c5cea953ad5170c0452a7bc04469987712d0522256a1ec52961561175c32abe93dc5ed37289b9d4cbd3966911fab85fe47b3c68692cf5a845286baef91493e15c6d23437bf7517ec5cf609c8628d82ff7cacb54d4a5ead25c85f59ab51151f9350247782459b598a2089a85f2c9bf66797e863a4ca0732268a4e40c57009d0c7d1ab1ff46b78e350dbfc19fcae823bcc040183a27182abde00a966a6075e68c011aa62eef913024ccc85b460098facc9c4c81d17c577bc009b8f9416d225d156c4e75b84691a90948d31883b1b2ab3635dc357ae867b2496983cf9595423c541e3c17947042b3d141ef825c99862302ba911c67619434b3f9cc489e8c8abae92af1ec3045c895edb41f745aa1f3d1a625e47eabb49432129a5608571431c4890c8fa5769563b8b1f9ba3c1b77b034f568038865c90304a4f79f65f74c17fab9e6b52236cb636ef5b686271f955a9e889b7a1ea1a010828aea1a838de1723f0149cf172f48890161c34039e99b36185f068b5707fa476d650bf149479b8c928f93089a4b941047b5b528135685797e0b9e65f595d9016a614393cfd630c6a217d0a03091853f606b238ee13c92c2b5d9e19b2c57638ce82a3d767639e115838b8eeaa5a47b7b686ea05cc088abd47a10ae593ae39a07f55cb4c1347acaf7cf59422182749e6aec39d62ccb876094ba3cc0b871c57a03a00ad67c5c1c6ef911c6dc36b13cab713be1a6610caa46db4ebb86b76572a0bd60adf163b325c89b506c33cc343c37a2bca7cacabd90494f044b550778677c2ebee76e03622705556b509c204087b5c5e5936c0153857691c3149521b800b76c43195897067529a4a87d68e974ed57178b7980eee227e4150af1234025757eaa3b645064202d632eaea3943b40cb10922bf569ab2c44867c411bc8240d110134d78143d3d44b450056be166b57921fe64a44f80968a1941d91a971e10c347aba369702b1ed542984f28b6254bf61d94b69f015b0e32b05e8897502238fd21d87978eaad45bf5997654b40a903319ca64095c9297611ba36d3a65c0d17cb22b7f3a682b593595b1c682d521a16dd621a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf101bec273bca5d606a5e76fdc183175a233c93373e956580a522badd22d97d71199c1a7b4149e652686eda541e69187a2abb68f89ae9492443547cfde7b5d609b4835911d154c33e49248c4cbb244acbf03e93e52e71ed87a75cbc43c3f505422c1ac31c014e82009d4b13bf2cb7dab16896a320fe6c0476f37767ccccd80850dc94b410b983fbbcb484dd09b44a817fd95686106c710d983cd2bbc11dc4ae59091a401a6941bc704142c792c407f7524ede1a71a726e2f921b0626768307c31dab514a783febd67b50e93479d2c7d1787142f591607b7a5626a718d502b37a6f5b8766e8175c6ef276934a12ac1107aa3362840513d3f5c02042ae681181dcab30f6810389db07c3fa1790345e786031e3196bcc01c22bd064b2f9c439d7b7a7b7633232aaa4d88e0288cdb791049b8a8c64883637098def7c88fbcb974554af0f3c51c70a758176215871227869766452871602093d6949e1d078691537d9d7030b36926147aff8151cfba202c0364795122d1d748a18289cdb33982900b38ef9aaa5d10d146985c757ce5cf82ae0a2489e0c00c83550d455a03fc885dc7a5ebcd71529ecb0ca13ce1259186f9b0ceb4b90789aca0762c8bee063780801ce365540f440b0aa0128103ae0f5b4a5d9b98ff3aec5793e8fd046a7e15b517c5c4164105e87c593db19b85792b6c705e615c4d95c38bc4bab4f30737a20241a3189eb38865c6b60f6341dfb931626e729ce39313e122687862bced934ccf88411730fd066be831542abc5b15a1cb2d3f0aeace904cb419754d9a5cfa35d72e570c8d3b0bde5a5b18201f14cca3e3564c16769757a2daa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436bd21282d6a3242417b36211c84b75f388151f087186cfc01e59383e8218039db15da50120aa1c5489743bc42335a774f8494a4244acb6677b22a46224df7bdd8a9292ae58e07f3068cd975abb51e44631172535e52c910b48748a190c50d877903a4c7b9f4b18993669d254ef566058528a157428111d43d360ab54343adebc2a3636720f1e0c8ccfcb0fc3b71b55353c2682946408cad171fb711cf0b3ab561ba6722647acee4b8daf0aee2c43352609dc617549841adac54adfd3319efc715dd917ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a551230a335510f55733ca4f3a6329aa0830894e06a05ee578c45b3117fd07d62718a9842ced5f49710f7b15741ba5b06298c550b96bc6fdb0561926240faf09012e2cb49c66868e27ea318aaac50bf882c5bb8e674381a96645b7a7dfa936201933c31955e24912e436528027b39f74a909aa5ef4653cc23c5e448be6f81088fd322fbb1779be52ad60005c2f57241932ea3b435c47a39e6e0477b989c00bd5ea71ba671d8a37dc64d36216ccebb14e6dc7420c362926b555598b92f6a78061423a4cc8961d57733982fb8c78573c35584185fed801ea674a7fda06008517b42d1a45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = bc05257f294ebb1d9f523ee049a3a6730e4cc5b52e9760cc5d47e7401dd902179a830fc9261554103aed30dba87790961d9524952048d442623264dfeb2e4a4a1da9894a07d994b9054d664efba14181c35da270672e2a96b6c912eed8c5bb9487ee426399cbae893fe08ae6000a4ecddbeaba0187af28aa9f30f11e46e2e622de5f5fbf89e4c84a10c94724cf0810334fb4a9c609619295cdff0a7079a55d7231c05cd13b9fbc381d1b33a3f9170a4aef32889beffb76d91c3f9a3ecabe60430006aff1c59e6781c816fbb4a8338f4af1a1a9a719497b54bd7b753611ce0da6177850f0762d189312670c6028f3af43b6c8d9f9297c636c8e4e6cc926569c81f93e2c1b7844eb83420070b57b5df5357adbde5d794fc5d1c2c6c411b563450dc843a1139a405d16908c277db81f202cf53b2bf3a6231121e7d8445b6d45d7b258ef24483e34bbcda7c2670ff02e23b6a7a6fef8625fc83bdc56baaf2dd7987f37e565dea443b2c2e25363f74009a730f8f986d021af214692a702b38cb56d048a1a5ce2157cb932c9d8a4663c33b500485f7f3147eb9c50a49bc8c3d7eb5dad6cf206e275921ea4fb4e3e7b00abf9eda1c9c2b93f439e979a7b0331bb5cda584e59551564ca3bf065ae9097d0327220d265e6ace108258fc09ea5e0380e5c97114ed4fa4760220568209cf52a79f0aaa1efcab10e58b047d44c2cdd74921aa81ed53d6c98a341bbd0834b19628826691d6aeff3df36f123dbce39a84045011a7d9493911cdf171a63cbd7ef21a6fc206abaf9ea46d491d94e12e88220dc27891d1e4a728538f3c930807ddd5292ae905e22b395cdccaa6431ad6f3b44e299aeb2772db97de93963eacb47d24f09791380d98165ea0e38d579f1b5f6249686a0c1610dfe223ee389c09a7c4ecd67bfbde3348b4c27d7087cae132f88b1ac82d31e1c41c4418b6354b57e2c37cfe8e60218730beb2154437b66db7531b16bbe4b4b6a1c8cd1650c732f872c8cfc6761480da34dfdb6f538bc28f91962bc52447b2898815a8f79bdab2ff82ffee5073e3c90d90960d9b0b6c389969decb7a41686cdbf12005c0e96f3a096175425130b485c94424896ef25a9d7e00bfea40f0e2facfabe7355937901af2fb8da23b69eb2249de3e6bb98b84b3c11f65b2889a01073e75b20b7077df34c4a3da9461ad036c41a926f4c18db0989ae4963ad31c59aa2c14d177bf94a12f73d5b6d61c9a21702fad90a2f7f519f502585e3fec795463eade03bfdfab04f17f3b8dea98e713f91e21f3284a6521d3c051b2388c6c5683f5bbecbb1575db97be5f24418fba1e4d30a3b3ed014fdf028c3b8d80a91274995c21bba4cc272d31466d54fd6ef2a593c5aa5511fb95b02c3aa932aea4bc5341d90ffbed8f7fd8f94c2a511abddb4e2498caa887512d6662ac02fe6fc0a01df4377c05baf88a74cfeb50fd3bc6403a6dca1d794043ca59584bd6c5177731beacd58ffb2f0b6177d0ec260f2df873b594500bba6b7888c772a61326bd69a5574 +expected_result = pass +expected_shared_secret = 0210935a18f1add5ebc2e1107bf40a628ef9cf8f6e7cdac81dc0291bb50a5a3f + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +private_key = 38bbb649e7520a59ac57783e32a5022489365713cce30171ab46ab219b7e81369af44bab6f5badcf613e963938a0829ace625bd8594ed3c0981c5963f68874aa87685599041c4c296b4cc181e57667d499b2f961f44773ca958193e97988d816d702078c0147e41390f503921f139384d75efc91cd08544536b4c9c09bcc2914a807e090d98b5c07c1a4a0c16ff0eab557e5ccc1871ba1a36ff66b1acd113facd6bd16053f22cc85634a3d56e564e30862aa1409d48aaf92643b62009f8e206c2c8bb7f357b9432a8474349c3e1679f1d154cfd4a373665a86c481b9c3163308cf3a1a265a6313d0068ba2181ae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2a429aff3c9eeeb869ec9982d367c5809396987a2efe93dfda2cf45e774cc3541bfe655a7280af9b7601fa5183ab62682465fdb273ab435355b84563047bc4c6204aec310d4b91e8b849182c16a57605a6f5690d3804d8857379e11b324977f30b461954a17cb16c4dd93761224a47f4c680373c51de251cb69a2c737cbb1f76d7278033ae86480c7776cc7ca02393f333b6cc00c200ae58922756d3664a30d7b262302672c27a7496746f8f56797726340c734473522fa880819d76a004a480f48b74f7c6ee1998741d39fec12759670b4e8057aedc67950b929e200526ba5a27e0bbb67570bae100b77d525af70b7b6143a7419a35273c14b492e1e42c5b5918a62f3c829a50c1fd8715b030cec454c90c72e6509ab1936ae7490c6b62a6720a840aa714f7b6b0134335c75c44a421598b790631e2ca497e256be08910b69c01997bcd20591d1967ef5ec5c035b0c1f19a01bc0103de6cafda45db70950cf551da2442741eb7233b36396c124c6365a83b66d9cc896ff448f54194fa05267b8154895173075039143dcc58062cbbb1946a917abb184788052920d1428c856bafb3461a463627ec7430671ce75bc2adc95622eb2925a582a15e487787389bcf14dfd84801a37bc39136cc1a49cab7cb924772606d48d3941bccd3221eb418b12a6342ab6c357f273795339bbc720439aa9cd5a478122b8b01769edb013686c8e872a4e2c049a755a8f954614665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc642c091226667c40957c17b3c92bea102143dec663b6155464ac7a9559c533a647c5a106c38972a26beab45c2f04c974c9bb860bca64615b6f0782305c81862abc973d280088bac791876d3172d4e340f26452f60009a49989bec107b680b62cdc12751f9079ed07c28143a405a600a974230b20719b0953da3c2da574ce2c31786c77600646e25b3c305f6507d91084a836366c273d62c526e0630f9b483caf335d6bbb5bcf4adeb4143443a07055349cfb690948487f7795b67dc2e45430e7a5c9564cc84cac0ad0832480aa844417446b9b086a493b7aa163b76a50f35b7384bd054147a8621674843c3040ce06eaec68b6ce8a2c5b42390c76350e10dddb35c9f4c4a1cc148ba08601f92b2fb12c9088922c3463139239a62e878e4db61a3529a8fa7905a7a1aaf90216dab5026469b27d4122af5561bb91d111a721a78587eea259a4c7f6b743574398e30a119db0a138c9442fd3a7580e68eec01077d31525465babef901806363a2d664ef8c1908a30491e336e27b0f8690ac71c30adb145805a15fc654ab8982565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a20e224e4361977b71c694a88e5252f608cac97e97dd7c80a5ad10d62681b57162269f7b8d812af039226ce2a7930e43007c0b3ec6a4cdb3897ee85796d051cb053881e1b9706a572ccc75d0ef32f92610c40db4553824f1a352fefd979a310124b9456a9106367ec6a50db6fe0b057fdbb00a46028c0d6a638bb7f2139ca6df68f014c4e1e0b79670869353912b5d67edd4b77c70c067aa76d174cced6c7a901c65737082276188cffe28bcfaa2604447e68d490c0f11cd22b8c351c2d63e7a01ee460bc408e174bc4a6cb023492c6eed42f5d85244ec883b1b49b8e3584f27835f21b6b2e6060e0671f289771d124168e196edacc1aba26cec9e09fe7367f46893c2ea3677caa3005e34e722608a3b64a3b987289952dd695a82de89b9034390355c5e33546eb833f602cb9324c095bb4cf66c05fa0ab98d69bbdcff155c3169f3df2a575901724b678fb080b67f32240ab8f0198cb43176f6ffc93fa602748d591f0b2acb9aa67a8d8b15c27140c320b0ee040e737077a8c9fd6a20dcb865ff51c41808757b0ca750c502a356b1c7d821f1bf804ae2b337819c5ea89542e079045c887ba6550e4f05693f5c7012424d37a17e2294669c0538ce69a1f1c1f121784e3c3537424bbc4d73cf1a685f03a24c4ba8fd603b328d2a07fa2b714dc1eed17693727732ec7be2b02c0614caf3d42b222061ddcd758a0674133e6cfc5362f855b717695acdb971aaf16320690606c1c42238856d757b5d610bd64427f04c97abe1bc6b0185116cbbb2dca28b5d7a9aee205dbd37e92bb36311c8936d958aa1744ca67332a600d8c719377273c7fb0029f27c75817746e1058dd196de71b0e4302682da21b4ec1beca3cbdf690509573959d816cf5fa034ce01d6a4ac477e3bfea75732678aea6c0a5401c623dc225c7a9a7ae6a572f738387181913cc71b9379a5a2bbdc45773c6a1167fe756e13731f47226bc678331312b99428b07b2122b2b9dc86b01c5f090ff632fa83b598863c0b42623549ca831f66bdbbbb1d4747d56a97dcef9c81766a3d90043c1a99ce5e81105e9113043342a539de446a7c5f9c4b46a8cadec388fbb8bca527d90a56c649200cb2a7f968611934014f9a7b6faf3015bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e35771947172118eaa02cd95f7137c93e2159d9389607c3011a76363560a97df950b0329258b0126c7bc10e4081ce46b7c7b0af0752b038386e9afa2d0a7543d85ab909376b618c0a2d33875d264b76941430e81c48832f43270160176ed5938492a06cc08392237caa8487abd3c83019000bb6671784109c7bc4c2a0362a5b5122e620aba511c49ca42d75091b3b1abaad9b8162bc27f182ae310872e789cf05f6c949598c41c3b73a1a9cc0808e68f95c8ad8392f021f77c79618685db2fb1d04a9a8acb8441ccc764aa3b191736f5a24ae31c23428390c1c22c6a6052664db63b94960a433584036c05e031a07823a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = ed678ef3105bcfc14050898f388a2daa0d61c5ab310fedc2107297881a1097f329c679ccd9d1cebbe957c137acacb33cb7ee31c9f5c148ac51e57caead59178132f69a7020a8419f4f833bfe4b8718691b26b771ac6e858551aabed2b9ea3c904a8c2723f5fb8b87d519f4a93dc43cba81c39063f732ba91116f359721ff3b6fcae87c5965bb728f4442f35dfb3f2078106078aff64f51cad6c62a5c8b056a5e6fe7e08046f097ebb1311603f7b719d93b53a1efbad985dd5bd5d2375d118f81347104593e6a05118836beb278a62d5479c7bd62e90b2aad04f7c6c0a4b5b410568b9033e72f1cd6c71c53717faaffc9fb72e27a3f00661f2b65a4e0845c2e7aaa391fc1ba253e6ac33abca8a2839eaa0be8e350101af3cfc7363424626ef571c6db515cb8a8ee209aded9f56a5bdc3dfbdb9d4f1a94b73698838550d4e348e5826a8f632d556385d3135ae872580986b43a5d77fe471db736328931dae7f9554604ffa969d5d2e7802130afd2bc5e05b3f3947483fc8ebc680176d792b0fce9f7d121ca199011efd51343a9f68cc40cf3c019338cb6e1b46f3ca920344d1207be283329945c1729704d3baf1953440474be9aadac1f705cb5ee8c41ca4f29645fe9b5044897952899d18ce25b841383ee086ba8ceaf712dc69d23e564e35a3cca5309cae57826907403065e943f255bbcccb64f39a54c18ab26a8164ef5d9d07f6522e7cbb50a2b80040bbadf0799ae1b55abfffd5d2a74c9c94b43eab75f55c2b438475bf4a4f0a123ce8e91e94b6ca6106b39ca34430efd34fa0a741cf93e0286642d45e78d8fb26af2ea594152a87d1737f54238c7a8cdaf174ce7e9e13aa207b627ebb4a92598d184bdc62a643934e114b356b4591ea5415fe42a9f47332d559b9f748752c46e4c8e1196a9d16df310ff2824afbe1abf520ee7c6a8ad7a833e01e1ac3fb0784cc85f3d731b40a12c667e6a0f3ad83505080aeed9309fd7492eccc9a81fc5f047c47c624941a0ba626563813f74eeb0a8a558fa968f809deda218f6a73b821f30700307b3aa52122c81ab3d48e4eab8e1bf8ce95f9d77014b5edbbfd21152305d427abc30c19ef3bd6e206eb128d245ef3f0132008957577081e1863ac3ca83232ec8e3a9d95546948c9fad4275e0a1863d5fa2a54fc42d0846dab4a0d74bd55fe5071c6c514b0f0fb69a8f27347013b87fb48d00a670b6fd28e8c844ebbd6cc93c527b5e0da483b3625e754b5f39257c9a167e5b381bd60f3cdfd5cf0d65fe96e02340922e10c488f35df7fa4ba9296f1e576aec3e425cbf92d648f6095726ac3ee8a6d812fe9ee629413f78978e200fe3eb1816fdd1eda1845382a1bec1ac57b23b79189ee7f67f9ab45731d2a2ee4f208025f0f0530294bc2e38868118bf2464fce482113463325223ef8395f945e0002d395c0e9695c9b8a0ca20fbd1f3b66327b69e6579a1ddb49f50daf499031b090dc2f8486e65d8e715dca3b5ee26a1cb3fba97d4df8e3f283c28a4e2abbfa3ae5ba78b6b5d8c +expected_result = pass +expected_shared_secret = 34169fc520e944f94ff1fa3799db802a4c1b26cb2971bf196259a937ab8362ca + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +private_key = af361347809757c2ae0c4a60393c90222c394cf136e95517552721ff136dcc234d64715a1ab43d15708187f89a6830791e0062cd43253ee486ac54179d320fa6a8bac4d0c07b7158a1eccfe52c4847403849982d73288877d04eaad37d392aa487597f80f19af7444e5a82cfbe51609ae515c1b320b6c75aefc121d5e2904a0185654a418e5c7a379b41838ace149b45c5a4040dd239ada846102a6bbc811ebed4710b2393ecc4bb8c6254dc815d2667831f962887a74eb883a5a8642e0b427450d01321246a8797b7be1211eaf64b0c706eedfa17cba2b010626112ab6b2b2b928df38ccbd9b639b9c6ad090e92da98b5c9914549beb6a9b5505579a56943d210722bf590d63c1ed56534a96552005226c34cc1ac32572d2ac0823bce348086096525188088df229536bac34a1c95083309a0971f31d975de0598e4e009d24661b2a79dfae85343b94fb1bc171493ad77d767e0814837348616205652eb4f98838ce536691de8c3af0a4970eb0c3600b4605841bcb0884e08bca3198b04b2afa6f575229c56462b9516026d32d2ce33a4b1add3b411371ea6516765f457613ccb50f94ab9395f6fbc94395a6c9c104ce3b79171a83a49b22add3a915086b804c3b42301bc1f14630ee3217f059aef485c019a4248b4a78a516d75919eb2b15bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bfe30a7578044867897c332687d925c8bab05d0c35693f557f541b571d6ab7e4a752b80267b0329d7558fe4bbc54c8612aa95c03f81641a129b1793160dba78c4e0269e9361087328a73c67c0044217a25c2e05b64a1b8ebec972606bc220b1a456d8ba86a76ac4a3c06429cfb6035ea50549db887a5f6170ea282bcc295a2ef000f571038fa97b6bd98fe0399ece3755d4b55e16261f7fab678c394c83676cb9f080bcc915c8b1c67dc998d7097074249585e31c5b30bd0250abc570531db43f546c2e05983a7b5219127809987343cf722fc38525b2ecaad2ca703679cbb7500420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04d3259ad003db768559e173df06a08793b10e5a1a46145b6f0fbb230ca504424b4e9617cb3f509993567b4cb94cb2cb39811bc1eab31b5f5691ff4108e5a6eaa9b15dc2aa45fc4ad26b9ca007a7c2a680acefa88f12790abec7e3da1c13a355c1c669117070a7e1976f6859921e273f53632b4144b58e0a74207100d2cade0c8a0410814d40a4234843a44978d0d4a173be52434760423235f5d7c8e1f56c8181487bba930cc9272acd524eb6c9d71d753fe62b0e9ba33a478b7e82b36d9690607550aca261085a08725281b02e531432b35398b7ed1355b8172776926bfe41880df90af6951a58981c708724deba6b6c2bb8af1c0009c71a0b82ac0d14cb0910a8ec3988251dc9e93f17e067608115c85bb6c47d33a2a9359a35beb47c3a04ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc04008873004bc535bd5c74dd49247419601513c4e8125731307bc858845896a67d33902afa4b58b50be969b947851bbd791d66887cc6e92e19a2b92ba6bcc2825c4239ab2894b2467547ff3a63bef65e35a0c8ea287462d8cf8841cdc9016796500e61e89eff672e87c667f453c8ccd148b94c9a9a3765649ccc6e1c05e5350218d091783b6c7e4958a0807e73e9839992c8c36a87891b7ce5d7122e38b5cdd745feb1058fc2827b882df77cb564323746855392247b054527ee862abc91a557c431e55b81d23b1c1a94992ef540e07338fa944d24b17ed4e693eeb8224a0c5307202457c8033aa4651b2b30f85a9bd8070d1b11675fe240a1009dacfab21d50036426a6dc9c3dfc05cd1612ba91da51bd5a0f7ef9b235f1b3b2641747ab8a380b42c060357bf259548cb80788cb41da4c7d3c4b9401925588920df255167240f6b092c1329799f0039b74cbd549b2c053a71d4641071a3a95a460b2b3a8ada727193267de555e6ce87986ac06e647c4b7967cdbe5083c4b99a1b44b5df58959c48beaba0818608fd4046ea0c09a28416c6a97a1066c0650ca619d14a056252d38539f1c2676b69cc53502487389648fe596783baad0d7627cc6ab2da5b6788410b67285841a323e04d037f25e103b38b07672248186c969b04661ac6b2753c5429eeda389599b78e84608dea89556a9510627b29e13b1713a1442158561db8f435bbd6234a420618985dc4f71f0a5f15762fa16084f178e0e76bfc9ec5c35fb52e52301e6809cbb287d42b7591828afe605cfcc93c337bab78b55237b075a8bf08c48c15087e82600655234fa99f6987da7904ef50a1599867d56760ae1d70006925ade67157508289f137def9b9714f4cb72a017ee6a6325f9418f3a0ea3a8762c55987ab406dd9a6d248a33eaf264774aaff6f00607f37bc20041d3a170e07407792a43c5407fb3622ccb065b74bc1a54f86af9f7246d288fee725a6fd85e82477483f778d5388728c4565467a9ba3216d92089bc1c742a20b03bb526b73573cdc91aa8e085f1eccd1866280e791bd1e43d4843a440e050e2967daae26686cc2d32f512332cac82095ab0005133023e75c9c92b0388bc8b2822a82f93fc3520972e2e0a062a388931092bfa8758f251895c641186d1b40f6a332df3088bb24381da133ce40d3461a7d87a93e702472e49ad91cc013c936b02a96c4ce14c2b23ac79869c6d139c8d85b58da27c6eb4c4250bc3ddaa56dbbbbffaf452c09074e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779db92453f7aaa4e58401cbc6f3718a3352013e1383b4222572118878c99289b91b02d929dba06c6deb6f4c2b0459f86d04fc8d287b6a676b17e45997027568bf7bcca05c3d394c1557873711174242ca50cfa30bb3d715d1400807cc5ff1049ce720be3c360febccb61dd7244f4352b655a517485ab13b413983cc089749ac7144312966b2c67ad50096bc176142858881f09e3a075f8fa6bf638a13af572ba026a172b23317a01a999c8c1ef478422cbfa9802f98f2856bd6a11f8584c532807771c19c411a2900c5a57c9b8e44b4c07b3be3477baa738ab2c407653a309d7a82cfc6b86a1b59ad1251e008598e453e04e3306c1877dc703869da25a9b91fec80aaf4f30b4d0a83e2daaac73990f05a9002d6ada0409450454291e37112a9ad97147cc89999dc89a30c809757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee63859f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = ac958722deca4336b0f60c62e7c9e13fcd4b006cb719e07b26fce400e3467d481cfffbf51699fa8dd5706cc65dc69d8ec2c04229c636a94d6a0dd59bc81e90b7538bc0622489f18d445cf2a7082c5062f4534e0a156b4b77095af6ee36d2599ed7a961b0288f40a52a769b5ff92a7bc835cebf20b0aa61a33379b669be2efa997942b71204a97391df9461b2ffa7f58c85f437effcc82220484b1d352f17ff76ab8516411558fa3e3386a79726ada7c29e8195fb41d480b2ead4d48faf6949aeb157ce17f6524f1c0468defe260f6b5f634b265428574e259b546cd48050f2e8144033f686bc08d202563d55833c217bb649d50e68ebbe5084a1752cf479a24332f6b87229ba8f38a3f75668f7478cfcfc4de61e65495b22e746ed7cc8ca5ef1af1b3aad68dc224d8c458eff394747e235c191780c8c405bbfd7ada024558b04e93afc1b09ce5e97474aca4053be829cbf7668c660fafe8296e7f0c625741e5cd0ece5c23aa4e5183559cc09616dadd9fe4a471158d27d54bdce7b95c6374d88353e8f09907b6d910d228598f77faf7d14eb4faf5cfb1aa6cba24062878f06d2c8bf4f57673547abbda6266f26d6893ea8d9f09c5adc8918eeced2aa88c93a6039d53adc5b5722c2bc4bccadfd2768acee766d400c200babf7330e17be15023522123bddebb445274caaf1bde7ea23e2918f9b520a3173d7e060791126668a997c29241af3e531ba30e1c26e7611b32a346f733de31d26c7971beeb6d8a9725c282b2b07947e4a6899de0d7cc703bca6cd09c2f6d24922ef78592106d1dd0fb8ed29173f6d79e82df387526ceb9f0292b8fec498757d1680a1784df0c22fc05f409a908816bb060b7fdd6cc95b180fc3dddd50405c4deb8af5c68e166c841710610ca126b2469f964c8d19b3b0e9d54aebd19553e9c791c0e50b90e9c676e8bbd1cf0571810d6ff0134bb77b451bca63b37325e4574e67b553d834b537c4dc371a69352822844fc8e68786f73826fd3e38b8735966b96caebff7a67b5053f7e18f3fc0133317c6f3f88c0bafee7b1ea9dfb9733c8834f401171cd8837d7466a9114f58dbe278b6882050730eb0a979919a267779cdb35eeb4c2e4d1187c0e0c96f63a067bec7c8a91db1342b95386e062af1e43e619a04c040fa30f40d2ea3123ca5ffcbc00b353e8df0486df38da624cee432284b18d22c6051da022255d16fd85736cdc5a1c635279f28f2348d5ea50c22f5ad445e3e025ea208dfd9be4c42953a578e238150253364530c51fbeb90b9e83d0c0bfc59ba37ade7f001272eaf84e88b82bfe939d43830fe7f6cab1309392352fe2a91d05ab5a93b3b530e1bac3dc3fdd3157dcef43983cbe0a5b4a6f0dae4912126bbe5d4c62fb9ca542a25c2bf463d519ee01642425b0c93893a9adb034ec67149d8d3e91dcd643758094449e1cb3675760cef095c91b52202748ad12bcdd4de0565cb0d214d0f2cf40cf9cdd21ad6eb0ccad52cd6eba41e72fb3ac7b401cadb08fc6a6de0b1ba1f02eba76c +expected_result = pass +expected_shared_secret = b5901e97eb656a09d2dd132528148ad07a0a89f638717eb53516a9ad19aa36bf + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +private_key = 31cb44a14c3ff840758055bf2afabad14a723c048d4d20c5908bb781844d574a96a0807c59d5192548a0089396a78b953aa52677b9a111cb012954b674571c5d0c7c5e6488d498290f7665f4f32dba7228ade2a724413798ec32619901215663b2c26360612558070bd06261bbab86b4f96056a498bf37b1b84238c5099ec8f1af4251c0862b861f334eee85af8d364a54f6bad0e44a23a0577933ca8482889a955086ea3a2c94b057c1c20d540cd6d2976126854ac123cd386a855caa385927318825494861079ac84606ac0f1810eb78a8398740be69cfa1777c61a5cc1d758ae28c072d6087c379a567648558ac8a1883734c64361db33cdd156fd371a2abe534b162c6e336143b944dc2309aac106525d6586793a2b3420358185fc787c2cee3875e3425be5627c1d49313413ee498b17e8c295908b718b3c4a6e03024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd0422ae2569fc37902ab90bd2c236f4da66d78301a61765a77e43ace81102c7355749c1463b55f10e26727086d73a1800924c6b0eab6ec905d5b01adc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67cb20b38bab1a8d81cbd22a5ea8c7587a13bf8eb8a37e5949084c26b4433741a31c502a4c412535fc6a1c5000057c65103027f78f81ddfc4a8843c59f8563bebda15da543be2146a3eb7b521700958bb2a5064923236193d981bd1e2920d00b1cfc504e32495dbb116c5bb7aa21b6cec5c9fc0b1ab73330544e7af5bb1ceb7c159e3509938d0332cf51add245606617dcec688f117bfedc27dc5b8b4884446861b592b720b53fb23cf08513f66c3b51833e51b9a63e297054a8c03f8baa257c64c2c8a265a8a92052c41146bdb3a32ce0b7196aa33564806dac33ac05a20178c2a0cb04000d484f0325c9d16956da0af88f68bb72b7bc6b122a486cc1eb01bd3027aa316c6d7c1ae7d8b9a747443c5d7237989a93ed939d905832e76afae4172d5f70589e54f7b5cbabb536e5f316b3d38911513b400ad83f7b2a3c72a6c09ea3b4f68129ed285fb99442fe61237d61756a2ad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea5920128356c369878855126c22f1ab66a3a4c202892c8863b609f7926175cf1e3967ea93b7ade7a8e6779672023dd5d81bd4d9345af36a38db17e96b8d85b7c0beb586aefc9fd9ebc585f071c1b9c34fa2283a60884a0cc5ea210887aa677d24192db582f05117fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e9410b4ca99a4a880b48053878a45340d0056031068a63113be4b51a630016875541e099935ea92b2668ae84c5a183cbbfed619691038973cc07b72adb803cbe26986c827ac75428cf183cd5fe7c9c719378438058f470b62fa977dd658f219983f97b517bb1aed01a478a18dbb89ac1b916419a3b25f388c276c190b866356ec84c33b29022286c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c7b2473719f4e2b5c4ab8a4fc172a132439e0e3af22a1beae17ba4cf39a155925c62a4c9ca76436496646906630b9349a335a4852c01b018f77da15e4749bcd8577d50a102352b869402efde59f5fb54bbee919e7d4a8bb8cc40fb8c7240401113152ba727cecfc8e4b817c5d537df050902bd03df866317006a2aef59cac269813a47fd337a0c5b694f4b080f100089255614634a2b0bb1ecbcc3f1d84cdfb3054fa749736e531c2e673716079cf45c89b444b7d821d892c7ec39a74d39b815c2b9981ca47f5e56840341ff9d23fc877285f9b90fc78bea1b9c5c647ac52d066ad7b8ca2aa01e0729fa22c39d9c3c6cd833c6aac061aab1c1ee6819d2a245997b8580a9e1630112cc6b62c4952215a3281111675f25a10ca0c32bc68c7bc920bfbc7bcd82edfe130b0434afa29b2b9d90ac3f1143b5664e5e51984b52d976439794507d92cb256a1520078972b843ff3dbc6736602f68b289e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a45a1a62e0b749ee14a38e11a094bae60a38c84079d81aa655782138671a0fa186a727457d351a8a45b6fe05369f7b158de844e31117ddc47af9fe52075c6acd5f93a31c38ec7f608ff9096c8562e0271a35fa7265a56b24bf31c6a727376d1ab3f600573342e60884f41d355b2336e464b94554b7c108614c3394fbd561a2e74ba7045c0d74032877901e4f8a95c41ce9fc72013c51fa93b5c0b3c3b0a8c90ce0960f510a9f6a453b8b0012f7c2430350b8a4b6143ab5adc7aaa6f3533e230c3062b7caa33b1e9a3bfda7bbffef8341ad0a33ab272bada717a4790f4c99cf430bf114b62854810eab7af582a2ea327a599c490e25795cc5c42219771391b33df4c7fc01524c4c520eb4559c2ea8c38ab5cfe27035c756248662c1e969ef478a2d2419ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2941b89b803ed1c7d8de65f64a29d8e7bc2020b723d391987f83db0bc35e96aae7b2772b37159a3257ead277532119cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352cba074bc4714deb09f9cd81624d2782de91efbc30882c45631e96e35c9b53f77cc0d268722ba5eb858a1de719a88ec240da229cd7766b9a237641c1277c006a6672bf61ab5dab4c223b7381fd3c16704cf7920b2f11210c969b6b46a152b72598de4aac1665d72a45bf51370de61559f83081dcb6aa49339e489968c80498550afc467c8aaf0c6c1b9085699b801c75eacc3142be38de6f6a64ad6708c426eacc13b09d8bea819bdc200258d31a8d1f308d0a7470dd35161379191576a03b81d70ec58565ca7c4a6bb333338d8113d70f5bef45b6835917e17c2945a06cbb7f2225675252f351593b06a6db504b6e67c6e88763fb06879187c5053029724b3477281cc5c5294b36b64f12a08084eea098489d5cad338a0cfa61231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b130a103c6244a17870b75023e0014e6d8433ae5cd2b145bfe253a8bba300b6465fce277e2fabe36d6c8112887cb0a6daea4a54e258cf89071e407594de1bf1f4aa2beb50263dc5d5fc729b632957375b5ce6373d9b93211a66a29736a6ed616ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a1f4022e6c3bb3d2294c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f12fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = bef2266443f466793113b5d0fc7413bf46e39fdfb568b88550b25cbe578868d6074a6b2de2dc03b8ce8a7a390cbb67c46c500c7e6a044391db3af04e95c88f2acc12c63613b2a139a4551e9189b118ef4f04de5da17fdff8338483df67b9f683ef87a2ec36185a33bca3147fae6f6121cfe41ad623f9f15676bd40fd7a2802568e9609ca00bcdf1d59c6595ca1b67db3a3bdffdedc7dee22eb33bf9e444c9f115ef088a32fe4c800bd57fc854ba31c53979d48a8071f8f8b83049dff41f729ec4bdd5423fdc088592b7bf04206b920cfc96aa4721a55235520237e1c7cf15e7905d864e6a040f8625a55330a2dda784554891d35862811969c77ae7260f776f1a768606117fc922d936a058151850df0aa94a05a9ef0ba817533073f831b03097ba43b2a3433eaab922a1020cf60b5e02994ab56d8b1c746fcb7f699c42254f3161cd53388b50c9c089a73f30ce34c2ee1168e8acd73c3665c89205c7b1caccb8baf5d94ec9451a6ed00cdff4515fbb8b3cbc0fdfc0d2e249eea42ace1990e519198306dc8c040e6b8822af99755825d2ae48ea94dc5304e7646863a7af04d393a35305f15de1c38e4ab78c061d0006e85074af2e8a7cf53a3ad7f631de6d49c84124271b3a29e32e40ce001e2d21d26cadb65d825a126281a157551c87f712d32e754b5d8cc66f3c0d719ad0c0fa3afec198c8a89d2459d304d4b8fe164008a9432fc62e21199f7a3f648f1d990a55f1ad253995cc848f6e5e7e320c221e33a31e8517aa35a6001f75a75b1e3721aa912ac92e4a4d0c5c847ebdb834bd6ba30addb70c613d4ce7e83e3a17e5273441eccdfb05f9f205d697e0e3c4aba2070fff99e2496fa5e9548767f6b3920eb3f6825c194cb6d720caa133bf75d98bb858bab11d4e1dcf57e251aa4fb82bffc1629acffdf25010ab54a6226c88b2582ad8f6adafdb62723b0d173377e5f7bb894ad70b26a2c22fe0b940805f1b5160aea7a8396729e1428446308e3ca349207d6354e2197b6edb19496146cd71edd1564e07afb401888c22aff7ddc721d276819cd908915e0d7797b20bc7d8e2e63c9fc3d899158a0862df09e506e437bf194807544b3ed75813ae767538beb5f2bb1f25abb08e9b446d8ac4e965d759f033cb68980121660e2c9de083caa42f8543ae4da5dd31a1c1eb9d460b5175f5b913a0cdc99e81c696ea831cf6e87066f479950c852a240f716462773205e5ebbe5b769f844d36729ad0996a40f69ae558da55b9792c328403170f2b917b65a971d0ece55be01f857d67ed4a8ef59ad83f7ebcf3163770bab4f583b32e8213b000b65d5a7c2f276430c4b23cc33d9877a72bd2d755a131ecbbf88d489fa75b36159c17a9f1d61f109048a48507dcce311875a52920010712c6af5a181051de669c4bdfbd370590218f597e9e39afd39adeb31850733df8928d7daf5a6e2f3ce694854d340557647f4b8fc0f6cf633396f2ec7e03bb74b1f8f3615a78555dfd3a35d540151d4ed385967890818f997d8ac26a4c29f +expected_result = pass +expected_shared_secret = df5117706beedfb521f0f021069fe9650d0844194339033de6997dced05268c8 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f2c10c6e197927c89e57088c4960c46b767e27129fe78c7cae38717e6a2a7fc16dbc1582ac697e8915c90281a0a784c4b75345a13161bc6a586166d4385b507748d3b9516b10550f05782125c10f3761aea2c631afa83870c003950b891d96ae721317b192f21a50f2b2caf49f81177790c29c02216759b005692ccab4281927a46739ff7a9583e9a5eb9a62314e4967f5bb375fb627e5a45b918c801b4b1dac24d55c13aa7fc5cfc104647295650b5cadcac2c74aaac28b82233f64c1c01ab50f16213154d0312c5add25af449cfddf494045000a01c449d1084c876163c83c13321b1f6f87757dc186d4c30ce916240e538f196936ab9bb419093fd593409f3a308827ad9002e5a621fb1387ac06b442970cda9c720ac9049cff1c307806e9ff9209fd0cc52b9517c685c36c45801875dbce490163c91c707755cc8701af04deb9aa0ce460f24c72e5d811c4ecc297abcc4c9ba304c75812196409c19be10c494a8b138a6f05fb5558e7f2cbf6f1694e7d417f73781205b941eaa3ecdf91c71e998f9a8b6b72400a048a77ce4ad17eb265313303cc86150d477e42a39cb4b8c5a3723d03550f4b76d5fb7b524ec2658d374a8c955b0fb3fe878072ebc0201b2328b737f9f19bca8411f35980890d71e7bd9707c917545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cdc05fef147fdd625d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22e81cbe9bb0174a2b526b6ba0641456a3cc941569124557d3bc652dc8259ac66552db0ae06cbaedd091c268c2c6f4bc7e948329778cf48c3b37f9a3ed714c5c8e0099036514d9a052631b256fb7e7f7c91ea0311b8db8721d5001ae90991111c5873499bba20a9d08a135abeaa544706dabf7338497c578084e1bdce9155f87417b29313dd39505cc90c45c12c324b5d5af01eb2656d58607724725485465e33a6a64da220421c038f0a625254ad127ac941eb23362649d2049f8ae8c057321aeeaa31e0e98fe3da74d53938f4f900b6a33f1305a383cc12b35894ad498293957950010cf7912174373967c294bb89a90331c828048e3fa862fadc95283025e2f66dca10104be8b9f286c198b8c9f0f24c79a454e8dc0742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc09251fa2780ec0da59d8b12b17179320d23b822a3395466dac34384a364d06882592734f72ab0d2dd7131196afd4da54fc5801d85928cf61bb257274c98479ee0c2f65fb985f6c669d948fac153158530849311f0bc51ae72bb8c23ab5fed55e793a4e8489b423044a1b017273a4be35a305e19934b99b45dd2734ad4cb4c5b368c7a32650f306b7148c199a44bcc3a297429cca6015e906204c827cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648a52bb8302e32098c26e9a51a6571c9c290005265b6359f07598b10c7674f5356b0365ceacbb55b1a1822811c92c44f0e4bbda4a13364749c5384ca7670acce69bc48b6a0b0b2bae8ac5cc40aca6ce24957167cc0f24dd0caa3a0228c13934fbbb0c205f53d713aa441f5b0feb01fe26411e0cb6648d36c6236468793848aa4b7f4510377e0a24bdccb712bc98cb21ceabc08101328d3d032cfe9c82d21372924c69ab5a402e9b3d88c87e9bc5c90335e5ac231a1b87ea3c2527b82445d7c8596b10a609616e4da431c9593b91a1aa21a2e436a359a7a5901902a6b516d562363bf95890501af4c5946626ace3f276af8966709cbb9b666b9842102f3077978e4872307ac65ea11002cbe4dd0bb83677419b89c9e0c9847fa6441c86b8b601663e40357831d1b3c21b4a8985ed50e546c2917f332d4acb59bd64d9be88efb981362458b8d868da7ec516ea9c807a29c5d51385781302072c1f3295da2559003d4265cb330f43ac5b774562c182be83636fa034bdbc3cb25ab6c8c21c69b873329321533a788287a40c1659f457c5e6e15456da54a7fdb18c8ba246447606f2aa340a48b4fc667d7e67efec47910e05c3da4463b75359668821711530835357b6a8ec62a3e7817c508c79754063f7110362be73416a46533341cde577c17a75b3316ac59575eb1a1575ec0104ee77f70941e91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797ef827f0bb0821ea69bd9c43abf2181d0775fb64b8694c74f0323600fd3e5f1bc5cbdacdb2329928247e4759747c02cdd924cf1c93bae5c37be8c3b9c7e09b4660c3b9901ee33b62350a695d799b52743d5158c015cc609e891c87f9ba02616ed2d3a1c14aabef101b4b42ad5c47916481bef01b11b9496819ab76a428c0f5b8a69ebb24fb5b3407e1c22e2020341575c7098e63379406c9b60b6a1733c171682b1776719db5acbd2ac6ac4b97aa0a3c8c168a5ab389010a01b4dd01829ee4a402e54e633a229a94cf96e01f72ec4054c13335b89bd6e91e965bc324924c028b433074c9705ac4ca2682fb1b385f058d574515319397754cac9f68cb70022882a24242d1c3f1242cabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a5849211d831abc2c86834be35bc3500cc44522bf9aca86988aaf580bf45a5ff7f8192e110e163356b8a52486f772204bbbbc19befc631433f081e8556579d288b3b27c1a8209ecfbaa30a82b34eb722fe2be60534e2f625c0ae477826a9e75b7c5aed2398525358bf0ad127c15915133a32a9add47a72270a98f942807fc59f2420e14365a758c534f289160a65cfb34619c7c9b2992083cc699f554bd64586dcf379605581711d607235c944820cc28416ac761498d8b54193a8cac8b815d7b19a21b02a6d5a737c4984f3a888c0b9e3f51b95ed9430327642a082787132e94d6c26b298b77554e7f2237ac286f419266580697fc9316ec1176c4d763b194c52d79b25604974c1bc899560b72094701709797c5183391a268853b9ff3aa277c707906be0b078fd6619050e14b48bc73f877bee69a3ebdabbb8b2198cf51b14b2cc9abe673caa803b419be1c34b6341c2e83d2013152b557a87ac4fb55c5c86ccbba995492cf960479b044b3d6233317677c78a453d4e247ecdab3fb200c3d2a0564c4100a995c4f70597e498cf0897b507ab35e4587e2b875030303dc2ca8ceb41ae2a9725085c12040c8d0cb20ace46f1936725bcabd60d0b880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb93eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = ec483fe1e90af388eaccf12f71eee44a9868b9d22fc604716b42147fce466a3d9499f2ac1a601e1eb6a268ac14025edbbb5d02c0b2f8a60a4b1419cfd3682fb6f08d8d62d51f535753b05d4a3c3bf515dfb7f32ba2dbbf491739ae06850b4ff7bf94bbf18395a3f7ba4f504899f21e27f31c58b2389e5d018aa232cbb3287109d52655efc595e46faf0724426fd47db5eb9db222f9f325bcb97e7a273fa1c1bf3e5a22c2b5d3b915f7b27ce6d7fa9086cf92fafb7e0f1cd466e74add460ca84d518ee5be65c64f5cdd3eb13b1a5447b0e3cf1f5bbe40ced8a2f6dd6a76b175d017400611951e2711fad5a880412b1a29bbb3774b432020e93f90cb7643e0cc43b4425fdabfeef2586ee284e02968773fe186facf694782feadaa1d2c10a54d5eb7d274bf47c22c8e7545c5992204760f8f1fd65e26978da3bae8c85f0117e6837a87e2b4239363968d949ad3af50524733291c72585f21c8e91fbba2dac44e6968a3bed82723b9da8b6bf64eb4ed0b7188aca874835bd8591a14386ef6f6a968b8306a4a5e38ae04acb5533c3aff6e36ef7de90b6e9946ab7a1212714efb564e9464c47a1dc0173e6668c61f7fd24738f2ae66708abd047b582cbf5f8b794de988092c293a21ff273e1249ad499ebd36cc7ec6a7a5e28694bc820e8f9a5e4b17eef4dcf421f6a4a872fc3c5aff93e6f2c4753e84fa352178ee1c2defb18aca27c55a32cd3f09c24d0a5cd1eef3c33f8dcb52e0613b6c45f16d4cb2058f89491310027ec1fe23a61ccf5778053aab940d4091fe34b713205b074e1fdcc6f7f95235d46749879717d64d012facaaf35f4326670cd5d312adb6cdf493645056a13fde2b9e7be6e83e09056e6b54c51bee49551b333126d35987d7a75a494bfc8ce611b2dbbdf954adc160599e14930846ada2e76a457d473f8bd2a3d0e4b4db62ec8e4255369466bc9ad4df424ebe5d6727029e512517a68d7f426e5fd3f8c55d4b1ab1889369da30b38664e77e9b8e6458c70c9ba6d7ee3eecb61db33b71eafb21544ecf68a22b0499912ece6db40c6aa0283b76446ceb8388a7a6929c100b4f0f333ca49de2b1e68495336b70468a43877cfff03f30dd306a813961979ce3118ca0309b4c8be667393e9de346b2cbd730cacf59a2499330e3b0c7c8ddc284f9923ddced65f067bfc7474a4b673f6e1e0a39916be5cd05e71d96b797dc9c072bcc2a4f6690d6bae6594d9ca5333a7b8280150f0debb5e0d2d14a37540efd2ed2691d487d144c42676d96bc902168239667ff39a0d5d82b8ed9af5f79a972fb571dc1b47dca3cecef6f3dcbc045a730971b9e417ec682cedf562e4e129de4285e590006ff03158f4c5de616b0280524c0a50898f13d21adb49483f3dfe51388582e4ef2b3776ae8c2ab36726461a7bb404af15745a751d48c78c3f82475dbaa0e634d4fedcf2714000b16857d8b25e71acbb407bbfce4926cfa5d527e90798c58c820f7052a7dd3cbf506d63ec499e953a9c21cd8144b3da89b6f02a04b32e6998c +expected_result = pass +expected_shared_secret = eed6ecb831c881508f99ea115745448a7b312a4fa97f65044ebcede172dee2fa + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c464442cbe0879fac60cb733496ffa7116011cada07377eac759172db45c9035532a5a48c18f3343e7fb3a0a7a1da9c75f647648a822bb8fcc59a2e0476fe958cdf968433b46ea296056a8460edc0b7d4430252b227cc38c8dfa639a72759de9325d3bbbdb1a5305e546580127b11332bb666236924ff1f13105176b81a777ebc946bd4b962e8050c0f80be026a513f7c9c74308f8336a9bc73bcabc8353aa10afb69aa502b3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be442bf2162dda987c602030770555c0bc62b1422367b95a91399642155cd0b17dbb848b642c765fda2400358040d4cd154a68db36265bb525fc90988fd0c04bf0b66ce052bb216d6183b444cc385bb8ae17388d5e8024aa41563653b5f72899cc16b37d642f6ff7385f557c941571a1c73bd9425fef3c343ed9b88bd02a9be5652736ae69949e43b5c9719c4b8e42c9071c10e3d454b3c90d315c93579cb106a3b16bab7163983f5c514b818516bba802b7fb1166679ee03c4c41ebcffc6322db61a7988927dd83b48c24bfe82a4fb1901f70e2c39c411fa65c43d56c02c79849e7745bee15b70e405939b055c2a76fe1021e094b4671a290f5d708ebf0b1155b94fee9b34cd9858d3a8dd4bc27f5fc0627f2a80d6681c11324ecb74639540b72a23083c3758cb29ad40c979b42679e1436fc56b3a7d1115137015e2a2af9a8bef038b6905c8847c16558ba2bc6ea92ad90b026228695d664720c15e6708b0934064760a745ea4a5587ba211312c7203005f838a2d5b7bb09b8dc7aa39d4956d494472f71a268991ca907aacf8048fc98c095798d0ea043c42c437f6762ed3678b6d701560016f405cad66117c786b56b3a88fb5968c26869f73a2227b129553b220f67cae75b5433b29259553ab4375a0aa6766b2aa0ad480b6969201ed21ccda0a39f8b8f565112565065d8d26dbc1a57425a29fe0a606ba826ffe45a69493b08b11712e88a2b4b0371db5c0ec0125e2659ed08275d18277b9c0ca51797d46cafe91951737868483a418427733ee2637b4aa9496c30fecab67b0b7278a76da2da201874711e6928b7a40e7859378c867b9ba81529656200584ea9a5881b657b68980ef8cb201338ac1b856c4ec5b0c48a80bcd6676c0ca624f05296e59155d5587c2c20bfa1bef1005bbe9840db205d9658935a67614595bb3fe48e52877fc5ba639d023f54d534c58cb90a0a98bd1c2e9e940fdc61193d4753d17463d7eb8c9c6575e0f6845b5c0a5bc69c5f90128d3078960671394b75c5c72eaffc1e8ef4afdb395ffd40a2f6bc75fb9b79e1d8756705b710b0bac1dbb4ac312fff30745590739c08bb25cc9ec62caf1226176c161ece62aedec392a3591ec2ac80e92571c1417be7d82b2f9a1990d50dab78c1dee631304ab5ac57274846a8fdc6547b224c72e0781b233ff8a6c876eca3a3e060a00b560f661042e85340c4a8257660c0592a429c7b81b5137d410b5492864e156dad292dabf59035fb0e02247e6c6847cfd86b6958c74209a8f389041e5389ebf5b9b633b7fcc08cfe14bafb262aa9a031e49084a6127b8410a5a46cbcabe6b18f607c97d4af6c6a598a089bb40c1998d16cd307895035b15df2c34bfc05f634813eec780c96b83fab557075cde3b64eae6ba98b65106e729b81d11c926404e99164bac5b546997d2a842f6aa9ce1f6bb7ab7551a06a3649e1caf7872ac675cb8981a124ca05a318bff9a234853821a3036a86404b0f056491a5b20ae09dedb123df8b4e9eb612a00207c6ccbc580373b0921fe2831f50610340865232c60660655184d8a0867a47811b88bcdc4e6dec5874839919188f63740588ba97405bb1ff2925c1553188c0137336948f7809dbb96d2f910a9c0aa95d49267e543057976e3dc7346cdc7560e68911b8829d37bd0eb20dd5e2b0eb1538a98a76a68798b5469f9dca82a08648a2da13bdc1a9b52a7b6f345626bb691aeccd14ec20f1c252b4fb2595474b2dea0edda47b87cb51f020072d489a2e79cfcf9a12b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a029e1ca5cea27d729065d7137bb518c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee590d1ad93852885db721b85d4061dca1327179acdbfc329416b23234572901b3f63a2cda36aa65b17035f449af2b404691957c30028f053989c501d8c2cf8a8cc0c04aa59f3b19a98777f814a18a0753a7180264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657256015f68a8c887c23205a6655f30c51084925167bb75c98b8a25b7579bdf40a912365164814794bdb0b78824fe9066cc63473496ab9cea06248d883d1846fc8084d59f05277aa3eec0c3186d68bdceb6c240cd0128a6bc1361467b861ab025309c82183233c37b35e8af1b464331cbe7cc3974a48a8e015a491677567472f263e31188966eb556151819cf52772053936abb0d0a48e99357e558301dc8157a8a7853212828269786919a8f9032e17f9b692ba8efaebb602e83bd4b75160541500779d1907b1159170dea870e6f57f5229222e85b178dab32f897bf45510ead084887566942656357b7896570756ab1614994f982841a525c8ec63ccc8e4575df03be2f5cf96505ade252fa4e80fcff664f6fa8c337980251904a9135abcc509db15a49fe4c6d57b41bb6383b3483ca5f5ce11641f9eaa423c0c3254a508d4319dfe72168070cc8c771ed3e06ce74c93240947a8dab87d889f9ad894f37243b25259153324e103b73c708371400ebf007bb5459ee084be938a18d055af7cc7aa98fbb88a156849765936e7273bc385a1bca94a74368168cf26d8806c7901eee2359c8694b5439f1e82c0a6892e4a68c4858a9a00b1496e177d1efb57eb9c0ae382b56626595673230903cc19c79714364cc4b10891823535e21cbcd45c90d471e684af1fe243e925c848565a1989637f7614c900af1bea9049b78e07f00950ac800ef72860e209c192a4aa0b901090987bf15a2db6165516ad0238a40b0bb233a365bbf2bab2f60eeb8a54771a8d8e5279e2740298563aa2868e2df1be582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc3659c03d37240bff084d77f09dee76b60952221ed2c1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47be99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 9e87e3da4198c29968ff7e7ffc34af342463c33e928f1269f1f9dd9da05f7e6ccdc1368ca53debeebe88475d7a820be6266995b186c27068361275e3b2ea5fcd04484f981e77e150612841c15f5d3eec0e42ddde5c8dff60c0357fef646c13656e83947706b402f0bf4e7529b5912d6ce1478f9afa10b33e0ad8e64fc0c511267fc3802c21e8b39904ca88e8336f6eeaf9c9588001868fec48c5417e131345431b56db9b6e4468a2d9990106051ba1393277e9a55666916059e75ef50b399a45bb8de993ca4423ba9eefc797f1b2f4e9b10c63a79912b697d36472c3a53666542bbc5614b1d7e598e04d6d7258ee3a870bf3c715f3fbd0af474edb638cf94d4b000d4aa1f84f938f21e2b64b4f5aaf8d4a64e66a39268eb54c3f283c6ab0163b7ccd7a8c830bdf7cb5e7ecef736dc3837f6db70e18e23221cef0d6d2a3a50bc789116bfd1d3e4c6fb4ead0f5cfdf66e2a8c1e5f769595aae06555f0473247a48edfc9b5952bf5b5aef540eef286955347f4e16423dd6401e34000ebd9e330f2d8c801365c62551250f02c30128422992e34ff615ae123fc30a203382f8e5d190ae6e5347e90086351e4adc328f01557addb597968791490bf99baac1b5a4c7c5fd0348f71f9f62d0e65932e621cddf5de6732b182a7549c7d945a8e03857eacd7578623d993e1b9fabc88bdc9ca1007e79cfd0ab258aa1eb8ccea56c28b6da4bddcd74012d4526a39cb7a6c19175717f65fb02b10ae0ff90189c9672fa53fdabe48469a2fbcbcc5272d26f6ebcecbb5db514a53b2fe5ea45a1498022353918e67e3d53373ccbc0616c3f72d87f13ca8660641ddbc8c6f345aaa4e8ea397a690009fb080b70c7bd7b442ab8c5f7caaabc284fa140484636598a725868235a78b91c748c6e5a5c5fecb7bd9504d35745b1f06fd7ce6f7823375080937f81e8d8c6d894e606fbdfa64c928ad9beaaae76cc5f4ae37bd9cbbba7ba34181442961aae39cc534d44cfae600e79cad2d198969c85b66760dd7aac5c4aac439af9c8c49182e8d1151c33803fdc45a7bc9b3fc7ba063dbabb7670b184ff4092bc2f9e50156f5a85fd75dabd385740eabcb5bd816372b869bc1b751bc8db94fabd51c9759ecbecbc0403b233467fc3f08d2c94f1d0e0a6ff92a6824bcd6088cec85771ed9f6c4006d36a92c0aee038f96cc1378821827cda9ab645391feafcce1df8a6e8dad89abd81e87337db2ec1981159bd6cd17f39fa6cb02759939722e53eb0f42cc4265f85ea042027a36a9d77fe2d9099a48ab1644102538c958b7a5ec3a55a4d6291e885086605c07abd1d21b05e3b54962b87a2db165e6e351d91ba33ef882d83cc3ad5dd01d248db82642df1a0ee9175d115f86b1df2e7a3f5d1b33b1f6a41ac0c9f1eb4311c8720687886a5b9abc0de282f5925bccc89f9b779970cfbedf951ab1c7a06e4a0c04d7d1692f0edfc61eed1eeea7e0e3a440daafc6abe72508bce43e8516bc2eb9f7e2eac1ca693863b4b07ad985fae99980ee736d32c69af71b1 +expected_result = pass +expected_shared_secret = d6cb77dc96f9ae4bf8b2fc0e277935b3b7b7a59f749ff2c08ad42659dbce386b + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +private_key = 52d431d74363ba07b7ec47c2a5b98157f616b8c7b7d3e68ce3f2a31365bf4e21747203c5edd758000a8c09d38a83457fb7b015bdb187e842b46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556a62c8aac92f0ff59651c1abb789970a32c69d153b14a687fc2a56b9e0c382ba4f907a0bef79bddff781776abd042044a1c84c4c80ab9ce9a76bfa6374e9cee06081e3661a09cc3272331936cc85d6b2319cc7873227303191c36842b61013c0a41082b82034a2e1bfc8c47916859eda53033d5427741510e842265ae36d530a19e5d7365127bcab5b506321abe2b69de823b660b4699f8859de76899098159c211cffe51c7198cf1025bf9ee69236c913b16aad84aa4c381a577b6c7a3403627b323f11ebc1f304747f47407db9a8c9e4b866082597f28b6ec272ad2140a43a52188b061650bffae19761ba99ca724b71191b6dc5b16450cac50b247415370d5b207701aaec3a13cb477983f180388050175658ccb4714acb603b6b3aec340dc6c164fcb81331ec194c382fed024e0d962b056627a5b05a00b5511d78badaa489f8bb3f3c5b484f9c1450708b89828ef24b815eb43a6b8b127bfa49acacafc46434987bcaf5f91a926140bd56504fb4525ee1921b63733db2986dc133078caa44518871ba12894a553bd024fb731a0ac44ab80199394a2385bc440515877cb69b73b0c847e40adf238847608908c20bf7e1b86fa84781371d4cb52fcf2cc30306c8d98c679d4cb41eaa0ea8b395c08cac6df2348474a9504592ecd34a93b3262c9751e42193719b617355c59a25679d909a5e756c8db03e3b174e1a063edc733b9350b4f738618648baeaec5b76376d05329be6e706e632bd61292755f361096cc4565573562053b4402c42c85b5299b1cca0b9cfec4605d63665f24561d8c1dcfa896d1c6d8918a3e6f2a8d4224ff97503d1ebcc8d5395f0a64d1454623890bb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6b220a66d96d426b9a1f4c4c4d0349ce2bc790732247ec5d98e43bcd37cd94b652bfca7b988b063bb102ea0772df0aaec74c228261b4fa7a49f3b329f2c7c6d04c859c9816d5ba2aabb85e52dcae066b9af4d9951766041cc783dc672dde42558f50473bb43bc1f93bc6ea7d33f46ac4999cd33698eea603c7da265ad713e48691c8b048b21134c9998da19060cfb6ae31cb5a3b7387f2257fe94bb3ea4c963d01849fb021741395f1862085f031b6b05a7834551a6c8f0ef91397a29e12db6d776b05c7f12c8b260cf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a851be9a82c9a79a25cfa727c632727c765d4c496d466942147a8a7b65aec4ba84e4e2745671bcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ff9a0b663d79bba6b2b8908b32fc145e4f65c6a8a379a99c9e68a10c278130a1969e0cb708d0ca6ff1669d8756d1d530ade051aba3a07903b5d801456315057187758351588bed222785c9fe83a0fb4c59245cc2a72b309767348eedb7c2097b457bbac8aa96a67d785803744e149b3f131a85226aa8edabd5a4a5a7cf6633a394b756ab38bc652ebc1bdb728c74ec316d039ac982b118f1aaefec04e48448d45f72b319289691a93a20283c3cb1fec992364ca83226332107704d3390f71e1883b46bc2f31b4242744e0847e72d5645586ad0b8c0fe48ac04a003045ac2d2101b52c7c1d494673bea69766a5adcb38ce3a978209471b5d7095a720a4c1971d94970884f11fa90c5c8b7009e2e1769b382004c93a2d9187b23929d941468444cdde233db3791656c860705b714e3aaf076921458b8dddd61e09ac461e96a1b1e9af19ac6984129b6c8ca9d4e39d70277b5d9a6a4b605f5e0454ac05729c2691e87a8d79353289678490a822c41c52a2f56b91a35f89918aee8935ef2bbc48485bd747cc5c59066b7577739b669ad21a5561018f021663f5cf48e08f39881d221552c846ad789810030326c8530dbb369681c69cc00c2390fa857a37ad81623eed4262db69929353118a0886e6c1ca3d36c65898968eb7c187b7b866f18a8bb369aec780e0033ebf1b0df846cd60633a461c569683598c7744fbecc54282725e337cec503d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a222418bbc57d7e1325fc2a075608988bdc44e276af10ca2d7e52b045514080597a0ff73732789d0f955f93ba77e8034900251416b43e291984cad36c53c947cc954a8320c11424be43283a6dc586a9fb39b2927867b79772dc1caa16234233adb5ac819f1a172da5194edb997f924a827a85fc7c7a8281c98f7a9cee443f68a2aea6001de7c7475b46b55ee8991dccc6527b5fa1393c9107c4d35a073ce29a7ea205a9279b62f5ce21f3aab0838b42e6679000cc4c182504a2a4e81757b7f6a183428786f09c76c69e2d7598f1e5049cb57738daab6972abf6d8bfd2ac7137493bd2b8b5f997519b2026ef38623294b91999a5419356bfe03e338194e471926fe5842e79740f416adae2a24f441ba4a0c08acc175f347ee3b614664496a5e51c01a55b1d2a3e8486cec4c3ba461970868502a0f9553d776514857bb8a872c7f736ccb432b1392e99568b51b9c9a56c441ac0ccbe785693722f90d63a0f78c8ee777236ea43de2583d0e093ec8bcab7c8c6ddd8254258b7a5732939d953e491a6bf310449083986b2a0f236c5b9a300db22299146b9a0943115845f3fe98045ca844bcb1132e0bc98cb54746937b1479dadac5a4f9320dc572ba81cb250f13869d132fa259604a76a5dd56a7543b96c3096d3046389a917dce53cbdd9ab04a65b31c6c5cfa23a2ad53faea3bff3985fdff9ca3e3965989c072f4659ee8914ddda0acf30a64a1a823b78561d5a9304950ea3056f50b82915c71ae0b6883ef319d061464d8050f37c24c62c7693f204dd4b4d74b66dd7526fdbd707a3490769764adbea61c09a2d7f464d7e932705212d6a9151b46c2ed93a7b99c1148f679d622419a4574310ac20941b3e51591ca5d53cff51a6ed2c081ee7b4bc23c8ba8b1aa2924406618715731b1cc404929a38911020fac6647c24306e349f1ecb4e2f530e8f200eb9c0a315606a3e130498f96ad5865ebb4cbb55265e69316a3bc96e51745b02f4a593b796b5951f48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f79bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b19c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = 7f5651959d131f3dec04f463341a622dbbb71494fb88a8df3c32ba4f398696feeee85b56a6870f77362e5bcce245c5e26e6ac9c8a995cf8b16591a3fb13ca611acb8b464556e1301b742b18b85e79bd8aac5e0c7c69faf37d3fd6c04b22a6a0936e8f3ea4acbabd6e6e1c5254f30061fec7939d165fc83196071a4950da73299adb4797665ab76167b024f7ad115a89f937eed5a9f9223250f54cb496e94509b1368f6ff28d1a5a5428c7f43158fd8b4b962db4e69f95841c82f9b9456999ac0902787c6b94b6327c13c40816afdb3d27f5a5153607d48f79d3dc3a40cee37ef2b255685435af03e82e4ede89cd639c7f66ad44a8a6cb2c6aba3d3362e075d6d11ac78485b6c69c77048db47d59c5662d4ba1462b40d1b7851592a9f442d6ed6e1db0614203a0667589e9736fed1621446b4d92c6dc550964d3436cee676aa72dbc7f47bc053434aa9fe04ee2ac3d37715fb6df7156a3bb5366fc2f50c2082556abda2695bd8b46de24624b11b3f275265c441e946c0b4e37981a4b2229db4b1b04f37fd716e2b54e345c12b231f201ac546386a72d0d2657f5ff3149e6d2981dd87c9bb1e2f067e79935ad015130ffb2186e93fab5be37f141a04ad649ced8f1bd1a5c745a28df4fbf9da9d7650c3cec51980f5bb0117c0c5835eac133f0fb570c86baada7b5d8b6c68fabf9f0c9b76580b512ee9b0d265cefd838bb7d6caa92d7487574d6d4d710e5a6edb453fb3d6227d8eb469539911bc8273524b48957eb32bac6898dc09e8538ea3a0508c860ff7e61580c5a8d146238ea6620be7b435d10093e184ae98228300f9b0ec5eb388953ffd45392dfbff64cff7ebd2f62ef5b4adff8a2dfe16d8d97481ef00ae4cded00e75c6dca982df4c06e703dd6c42ce47fa61cf576cdf11752496003331985b032de9cd03168559d483101a48f4e3febb92bff1ca9a07ffb6e0f9682b346316b567abfbad857e5ee520fa659536959d7082ebfdb86c92ca2189dd74ca92b9af4bba9b989a7cd218cfb3bd58f4cc9cdbf59f42ccfd9f86fb7f68e319753fcc1d2863e730f0f8e0f51ed12b991c8f734b440d7de3fde744d49d1c3e403dd5f5f2a845e157263b514ae72d16bf9ad5634b80f9ef434d9e35c3065057f23cac769f29e2ffbcad8ad08db5b0dd3baa828e035240a5498a87180be4f3afc748da484a877085ff2b2e74580cad830a9e3b98fa6b9db91e902ec2ddde406e1c8e3bacb333be8b6b5e83f81ef20e3bef0a8ffe7da5b0d127c67e64c0e0498f2e117f53e7dc1e052f181b9c8e2320063acf49d8db7645b5222b4a255c22c7ccd050a0c246c9c1512eb6830fe3d93fc820fb3edbc8a6482ee06989dc344489a54ed242cacf6dbe0ce21ec394ee7662dcdfde16c178a890e0f58d6466dd2244881beb22017d0a915a1df3ac4c78d8b67f50748b3937b939be6c36ece06c7908a8fbd9a444da6dc496f3b8acdadd2cfbce80a78e2f4bc1df3aed9eb195aeb01a01714a2c15b28b20460961303a44721b10cb8583f7f5 +expected_result = pass +expected_shared_secret = 1592f1413331f1871b41ff298bfa669bca667241790370d81163c9050b8ac365 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +private_key = 28ba2f24db8e2a5b21092964f1871e97e10f2727c8b27916a5068edd27670d26b91a93332157ac686205e23616eb0271b081b51923c5996743cc114f3ad310cd6791aeb05f77960991513ec655533921a8d14cb2589399ebf18f7ba89bb7d6cd2d7336ece1b7b63b98f26a49d356578ce7275ee67677d1482e1bb3d85b88325bae0a00cfd1288c34078d73965442b7b140705f0fb76ee3d0921112c400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313e82d51836a2dc1b0f37a2e00545f802b417a9406e55420b4d71fbc2210d05a771cdc164ad50932ea40a876051828236153b4e1715edb1453045721e89a60acd0066227704b8ab991e8a06812226bc59943c0814c847a1865c19df4b7fa13ba3ef95543e724ef854ccb28bc1db49b75c1aca3649f848bc6f32c139aa79197543c628238adb755f4da6bd67130772b4790b28c9f1544a4e9860e875e68c1cdd9cc0cf17451434c7c53f3a9be39849720b1b80a836ba4c531d49bad16077e90203c9120c23239cea972454b08a5f10812443ca75b913df98dbe29c3312157e156311f67354d414aa041833f8454aca5b3898b3572e819fb2c4cada43c9c5191d6f7aed8f310cf77ccaf0c478686952e71a8a8173d0c223b04462b96c04ea7b218a13519b90cbe3be8c32b276f90d349acbb6362706dcd54aad0497a058ab0138a8e57d514d5d431043184bd1a07b77c3299ba6c7205938eca8403f31a1c605a942b73775a1ac11c40d81988e69c15079719aa769b5f618052d5290d84714ca57418366c15b74da4e98df96abdd19884ec1703f7978c4dd72b48528789d7148f16c23ef8bcd1f353cc4a76e7c238aeb1035424300f529acd46926874190556133021a6a9283ddfe02edadb7de23a4d141b0787539b68110b4882a51f95403865becea06e2d7a1c1f534fa3366bc1ab387eb867477b92f00c0d09615bfcc1138137cede4098ad57894ff74982d71ba2eca6a0f502cdc9c89bc6a44bd84fd8b62bb5d84332faa830e2a732259945028d2830a8aa866f92c24e46d164c4f4658791c11f0703d906a82546c75f81285c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce770f04f758e6124543e13d2365a915802f75e90997b10b15e650aee33a291c87030517b6c29cf10670d2dc5c8889aab7518b4dc86d86e25c52acc4db175a5957118f983c3a4443b33803a3161ab24004b7a789778c8414a8aa8c819468ebc28b68afe5333f7e666d44b5a961533280b0021bd3b24e2aa51ba58f2f45767a5722e918b1204656a2b44ce628a3a84125f918999a6311cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87b709353a77743949277147928273f112b5e618167a5715157b49ced69a2492203a08730ed07b7aa14bad136cfa969dfa68c28af40b9763872ed1b05d4161489bce1f473d4cc067a86258f6b664d2436d4856166cc60467887f9b97439f607d336114e46b2a2964c228a18eb532cc4c6813dfb841e60c3baa59978234a06fc95aaaeabec0123230ac33bdc48a4452403842bd6158c668f28f20bb5501984c5d3992594a9238e03798d178702b86973350724abfcd15255f0a5efb7783d909031ed02c52a203de570873c7a7c556202d53a6c086899802bdc877bc6a813ab59b781bb95f4fca9ee76028aecb9142a992dd7180bc1c15dbebb66765c5abbcc5ebf764d5234d89a378d5925fbaf63a00e35d568804b973450a045e55c7c5f4907fee390fe6877963e386bc20cbe929c3d247611e346eae401acb972843dc204eeabb043644eea29ba2c1a160b98f0d28caf0677ab2aba362b7bfadaca4e1197f54f03ac8033814a71e1cf407972b3f1d9a986637a972b46d3ac46509c053efbcb9a475bc4055265961c79e1374c2159bd2409a84f22755a1b32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f02270bbb19508e903888aca4bab72e332285837b9ebb466e5cba74d5ab6bb3b2a0fa26209a97f959c905bb4b058ba8abf30a5a6c190a018a9803ac29d84ba710b30da9a0844cc1a1478c289c32737144812355e0d7589b9ab765ca3b23353a350876f05081f3e4b14d8f66c998b81f458a394cc68c3b7bfd37366ec93113db928e5f9bf0e9aaaeafc619e332a7ef3898a66020dfc64f671879691c023409b53686770f8148a2b6f7b62b6aa42981ea0cea7753599585034b9ad99c9ac8b12872b1a47a088bd8afca2d42093928a4fb770198c4cc50b0214c4c94fc7b62b5e636423c6adb553b138591f6372ca6d53343ff7c70782a2ddc4801b262f220a539181c13f3c3e8e0a0d7191a43a54ab008d326df803fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdad2199bfa332b8c22c136350adb9553e3643d0c45413782f3bc9e941965dc051df98738cf50113ab422e4a22759ca016bea6fcba390ed64540112842f5b1373a2847107a43403b4aa5ccae154b9c54831e3911239b79f1fe997bae30a542560fe6647a2e7c4916097fd484c3d040456ea2bf8b63dbcdcc8577b7aed99c05fa28d468272876b614045095e918600f7c94bb0944f62235c169b58789ae8bc3e6f677ca8d238602399e307553e235d11836be120b3bac41b0a668e0841ab11f49e27aabdfc27afcaabbf542911b6a220cdd626d819c44c72556a3946df86c43d1b8693944d399a3b5b1309b9780e34330ca387cde8e4c9b2d0775a962f447828d6295873cc1629777fd93c062098b6149a3e7c383e2c33cc3fe7730537416fc1adb6c09f4caa736e4c796d2a97fa3807c9eab72993b4b876136b856c7bc75ad054288ef491effa872247a99aa39a9c2b7602027d65a169317cafcbb77c37d89ed32489e3c2557998a06689b06ab96615bb5752d439da446354cb0640686aa794444a806c31d721b8c6b820810a5afc00932a885107b5f968b5c8ec98207293d8851892a01dfae4a99832326e3863bcda75190c4a487b46e3914b702017b1b520ccc30a5c475fb2da94ea217f76556bfee825076533973bad3ac7305b5c764cd040d723617090af4a7811e9ab206c6a331a647d9385a5e7d8bad6c89b390b617018c4a0691d262429bba173598b37d7c245452853506437e756a399670ad8e292b0d820e3567047c82870e82236389d99d678cd9b49526aac30d1b830b12f4e62407a59c8f88b7b5d088a2d08b9f114c3f158650f32c682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b32735fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = c1a71212d3e37d620f58b896a7d06bb05b206b6d84c0ed4b08a5c55d1579cebee866e8f58273b10eb698f9769ecf270ad900ee8871d8c89ae01c90228f57eb877f7f6ca888369ebbfe2efd2509ccef519f80b678d33c6f63cebe6e003e9f63d36dcee6e76663677ecf437d59b71e8fe106477a92bcea414662a647be78bcc02c65836f83e0111d4e2eab9b14f5de6b940663ae6edc3cae8bc090116b84ea78ec7e8bff76d91e735280eac3d40556d4389d2a7c39720118dafe3c8a8db614905e620b7b1abebc1a0b17590a25e30cf46abee0c4cf1c498a1c81a68e22165c76e857b9f6fdf4a2a4e3414ed47afc180351dc441c8b3d534703cf2f36f630b1416c12557115dbbf5f0ef3575b0115a9121749a061e2b674d0336e3ba496aa54f376bf594786d5d6de95e27e0615b67f6c318be228f1e89afc8ec7589627abe3e024224b85d9b11542411267ae956a6057ae955ec9ef8848c9a300ef227fc0569531d233713d83ab84afda6481a7ac32b4460ac0df8611384c6e9104048f7fa8f5d6c0bc9b55f52cc0e733ed6b21efa1067bc86311e929e991ed38e5ebd2acfe72964180e775e4abcde3106bdc514f8c47bdf872ae256346dfd90b9109e27f4eceef8ca436c868aa56a9ee277f8152e10658e8643326e3b619d0222f3fcc3ac878073f1ec5db29bac0da0c55e1ae7d818083f3fc071500ad6aad2e84dbf363664b4b54c88cb4598121e45d86367e215bc6a436d864e6431aff34b79c4e6617e9ce5599189494b9cfe0b87d34727c2839b6756434ac84e83e0281dbd8048d2b1b19f831faa198528245f77a102e1b0bdc93649219cace43d961cd86eca2fa1c77b65f2e5cdd785fc5ab7c237d8fd1181e598c4b8147dfc597df9dd6855eebb3685d21c82e9e80707c65c2f84cffb4f44abc15d563ac82e8fb46be179c01318d112c36608db929260c27c280b5e3ab11901de1e15f41dbcc578ffee9a1bed3f31ed3ac49527c442ff392044c98e6805a82fec28f69904e9dd99eda5a473590172478c1d637c12b949a7f6639a86fd8548e2c06fd9b1861c64cf9f9f3a0ad913a077cdd0305227e50f2e38bd7bb726ff7408907f71e68427976104de4d2df0e8e21f4cc601ea968f51a933383f28776d0abe02b5680562c15883b6ebd2fd5a6db063546e13c47036a657bd80b9dd917227a52f5b00b66091dde66f950617c9ebe73a0d464506bb3bf89d6801f8803e770e424a12500ddf6b8fbd45c533a99ef70c42788d4660eb5968cda54df25a994bd2c92aa5ecf72282bfee5c376a2391deab3090b292dd574e630859e7c2a866ec9c557558bad78b236460c05e0fae86b9b0e960974b340ed31ea35ca171308bf54d40000adc56d8b4ee6d10c238c5390dfdfa034e28609e95ae09d4f431c5b96232ae85c537742b3068a4059d3e8894c41dec04d87901fd25a78015c845c858ff75d15cb8c1de7ead6f1487d2fa582156a24d254b6633b7a027c61c2cab286ea16dd9d1799c606cf4102d6455740868fca9ef583 +expected_result = pass +expected_shared_secret = 966f35c6bc47b4525d9af1ba350e8f44ea448cd1d90cf4e9c55ae5878920b7cd + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +private_key = 2f766ad78a0112b8cd4bf28dd0f589873553bf114f19c2719f61a32cbc85c71975b911237bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab4729d02abc5dc07309032c7112540522575d663c89714aa7a456410144d7c2bc1041c03d5a56e08cc7e5663c01f52e5077288bb8cbfba21b4a8a19c055691e05c22f94c62c3cc2b6a9c155e2a4eb2bb9d95b8c9d5a6394d05af87b038c210d9faa266cf07088b3cc7ab56ff3366fbd595b3c790b5497b34b94a72d8153fa13b40be96b51315ca4d22be3828c3556843545c47b0254266a802a44bee6e5a19a446472322c6aaa4cf47218ee3c99247564c552c93ed589ea8bb2c637bcf7277d5b5058dd80342815b2e8864b4c330920a82ec76b4a7bb893e0d18278f47f84743223a67f2983ac8c4a1845a61259670b02d6053ca181ba4c1bcca05b7af2a27c59c1e4e38da723b787aa2f36c71e3be05039183bffea6ab3bc779de2273326b327d42517b6c6ed8c7f96c6330d4c39e3d2a7b81a538693329abbbb5947b068c3cf7b45c173c1ba9964c86ed91d0bf64e209c1910c218434311a50a2128d52754148159891e00475654ab30b9693ad507b2e19acb7fe6b14f27c09c6b2570b861926683a285014631c2d7cb8c0c10a25d073d3c067ab819b9dc27971825ae21cc2e50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d90795719b237238c1f831007c690186949c600c6f587ac0d81c8334c57fe0c59db3e2815d63c26c620fdd75836261644d99327a334ea5a40571f0cda39ca716d2bb894a50bc4cc84d6621b60509dac77ecaa39b9779a3696749ce83933eb70c1e85bb2dc3421ae9a0ef40ac2d83a1fac16c6dccb0aa16aff9a94bb6d125665c3001b845e7f20e7c90a3db636950b0836ba008da33500fe47fd4a81df0e268c62974bad02a6d3b2267f917e2046df3c1883187683f030a28a129902083ce26730438b0dc0042998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913dc261b6274464b656bcb645f87b0cf4512af443959e67c47d679020c2905d45e21da586ee8291085a8a432ac6afaac594081ec298dc13175779b8635fc8eae58982258759999a57b704a5b040245d282a9b6c9cbca838399523f26695f60389ad42f6512783ae65a0c25b7258674398839af28866671329109a58e579c026549f0b7041dbb6623665fbc9a2ede41c0436635325912366ab1364b5a3162c4b8c2a14480aa6bf165588b8d26ea968291cabf66a4e26722f87977dab7807a2c65a26a9cbd339bac0b24e6b46e0a8082be95bb7a41b1b8b670ed3105eaf994a06a6414e9abe2a1b608c29c94b846012a0fcbd6959ed411d8d0c70a32559c68c74d94b2a9707b9d9755e3c69ac40782e97a1f904a32da824c7459b59b174a9fbb6b41947f47b3361d5558d831b2b444818ffa4c17f4bfcf8b9c7ce451f4ca99884c13f85c24d3cc4740d2567a54ab0583a175759fd7e197f3000a39717bfd9c768248518d50791cd84dba795e85388dca21507bc669ff0b906bf515f38c04dc838d0d1357377b1601887ae1b0a0c4490d38a871910c695c50008e5a5a30e92dbf312758b73beb83625df3b8d5c47a7a334d4e140915ca1401d461d7052e9ff05f73a1598dc9622c324c1c8b5de9b0386ea3cd95b86d80085588ac69ae310be6b5b5379202f4f14878fbb5508907b99490e4191b1e13a6890a9209f0a12910a3e096747eba94a337af9e609da4e8a9f8003633ec099983b8e778ca3d72bca1c19b4fb4a0faa4459ea06782367580b7aa49ab74b60c4cef7ab3bb9ba081227a7e1ac2f5400f8f7395f96567403b2401a2abb0b70e92e6ca2102c597f496cc8881d7b688861c7988363112155b5b88271072a7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be3907d15852fced4675547796d3046535390d44580c24bcc3d67a50cfa2ad8936d46121a7f60179be7aad0746e8a2c8cae124d27181a374493da6a68d47387a44460b39a45b2619f1d29b08ba4495230470b87bb926279eb760b9041632317c4d7a19e7753458dac07eb73331d808ce318555e1a2828da2f1d101cdc9b8363990b85064f63226c36c71061444e17a28c3b56332bab4bec2602f5c31394c870dd21030997564de52602c2628c41cb7ac2388ef35371f870a21675ac522660268a1802a2e4ca4c7152a9776410910175fd08c5e0307f4c2a61c877abbd2185ce58738fda15335aba2c77a804f94077a777fb49854c7a78462263e435a1d7b4a5205ab879438a91eb60397704cd937e66c7310625a6276182d86894ef9750f1817d85709bc578092d3b65f5c84514361264909dc2147ae6f3a577097e64bbb2c679c845d827b1ac393497575e385bb39563e125c3a3925a21160201897072f03f45d6ba85db7eb1d5b8ec7111dd785ebde07056653507e967385945389493b95c0a95827583f01dcd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa1323a34432b72c7b68f658868a2ae87306109b1053ed2bcedcb7037ab72d8c2bf48d29a0822575cc91ca1e5698286c9b19a7471a5b652f6a900659df9183c76417f0fc89d743aa635791d588cae6f650f3d314d65a6ae81a935f38b964f290be7a1a75f256776f17383f9bb9f9203415622b60b2a152a7ce3420cb49c3592ab8aaec009a237a12c2c04abaa08a382622dc84a053c94881664a97381ab88ca41846e82c02e00c6033b4721db29b71fd29069297a2cc387f2aa5336816c66e75b594bcd144171c3f7ac6df8a9a10a71f35b39a3da7d53571cb33860315288c2f7843e855d27db6f27b38940f973b2b063eba12b3a8b73d46c6781ac87f44c91e982cb27e534161212b367ab74a318b0f41e7a060823f17814f9a6e4f5a9093a6379fb0291d99916b15abc596550f152bc79703f1b0393b720cb85a510d4c9557acf3e620cf994c0bf8c06c2606041e7c3ce6044879a7612c3a2fa587b1b7676b956291a7ba5a78527a163ae08696c7c881076189bc1623c8d360c8d85c287a9c0c6965d0fa315e2037eed604084416fe31b2f01c7678311ada765acd7f70de59a9a85a8249205c78cac786aac9a0a0a7352b18f9cf936165a9c39d99aac7c175a5025f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aa9c205c1507a8f40512a45cebfb2b39f3330a962ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a564c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = 8111151e8888872490f4154b113ec0c4ebf57a28a670a85c362c7db91f1024cf7b6ac8030cee1081be1531a8af52275a3b94cd0647a949a6211ed50b0b362a034bcb17829dd73864bfe5ca9b2364ae0fd13e9824f8fab68922e937d2103a74e170c6829446e2fab2b7149bf2bbacfa817a68803e6b70a17f7dc65401f6a6813410887e4e8a784bd2d1f492c0052152cebacb091795ca0ee732486c992be11867f70789385adf6c0d82fcaa8eaafeaf706fa6434df3896d859e07d94cc83ca41e691cbc8cdb5f49222d2e883e9c900362476632b102761aa641dbe498c090b39789e88808dbb3ebb7fb7ee3389401e754a812766f7b8525411af6575036714a2be871754442b958601c1b2318b2d381ea5c852b31e1fa7c8db120482048181aa13014c361baabff04cd155e23c16496aa62a65e0ab8eb1cfb2b594f1714ca530f7893e89a3192ed2db714568e04d64fc8358f0735bdbf58570e179492365c1e1316be77c0b2e2ba15f5481c16db022bb314e3ff0593a3159d28ffe314fde190ebbb779590e29ad69136f695750a7d5948132b4e1871ea2ebae888942ac10f3d3c7a6960bdca579b43f2c258254e6ca45211f37e6cc324c646a51cff077271b959c7d39334e1617afe1c6bc54d0da480a5ed7b175d4bca69d97aebf3b9e399b1c498f985f2224f00845a8d78ead7b81ba0c324c5479b430fd8c4ca9c63e2acce7252c1b3530456a572ac3be23291437f1d11abcbe67a8df9ebcd22019b2d54cc3a939c5c72dbfbec61780b3a47481677c069197529c0f436e5b94abb7a731e6bc0622739eb6a9f9e3716c1ae50850d9f104e1193a9d3b05c2fef5736a5078e45b233c4bf9f85521f4b8a663b7a1fd63faae4825a47c0bbc2ce5fec7d492019c7315ea6145e53a91057c0c7245cad154ba809d6d18660cd9195273a83170c9add780de366a4e6bcd3fa5cddb4f84ba8d638b2318649417dcbed7936397e1850ada27b7ae967e6fb1b7a62721e8e70bff0d0de1959ec2978943feae4efe55bcb5de33ab5b71d6cbbeeac12af32c353e34bf53fbc05e1a7cb431a808260153cedeaf20da4a087b69fef49b05a8eec70d85cde26b8313eefff1a458d8d155233a54d025f013aa6cd0cd3d54a714e19fc5fe22aec2557c465144eb9315e2f1b1534678196d98c2991487c29ab085d363bac01f32d77a8d9d1ec055fab8cbbd68c8351a7e62bc76b860fb7829ef3e19c123e60991046305afc39fca4fa79040c7a22be2599749a7fe847992a7a588f8df9407e3692a34a52a9348e3bc5ec05120d5f0541083893eea1f967dfc45ccf4951f613c87dbd9cb3758f4ed4a46af79a11d9167fc931f13bf9356249fc2e3342bbfe977938518d6f807a7c62807e87a4dd6df7d3b205fe5f31898105b7a536aad8ee82018be1c3c331c4dde0b26d8b5c5c55e872f46565576088eec6ebdf37c8b0c36c98f9034ba52b98f225a69e0784a1ee452c2e318a098e634b824ea59ff3d57aa5b9000759cad7bd2a4db030c53906b44af0 +expected_result = pass +expected_shared_secret = aa333af0226492126c6985130ac7df2226a64d6d5c5314ce3f7a99add6696d49 + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e24073df336efa5a0d6fc17b6bb2c615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7e312f81066d516be72680e5a665830f74e371bc411ba86f00704dcd3c40c8c1295d6b52aca51ad41732032535af95bef907127eab1eeb54899a36961793ec47b91d9725643664082c4375f4843b0031b815c8dffcb7f25d4414191746d5aad14093bf2c005df655f69917baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd9f81d730157a59b971e4b4a0fba8ef49754a7c2be0325c8bc623fd2a94a6cc4226677260ffcb64d75167d63334e395df5ba4505495cbc8c3a3e40ab68796d6c646775339c29683a21f921a7c6a79d39a95c876f782a27a6365908381d793b537d1a681cab5599817e050cccf7803bf9a90ccc4084743c96069183b08702979c9dca2b9d9bc26e1de849976aa1465b29eb260ffc64478c39945a9b402520172cd7861c5a0cc089a028c8200208b3e4d7b3a91cc8c209c5e1d201278b01cab34126c701bfc2913df501f6d73d9424cf1176b8616c04c10940ef9832957585ec350e9761505162aecb28884f659ea23125c382cf24f383f9b09feee8aacb981df21a6bcec26e2a67493b919fea06170c18b79e5a01e6e89516707bcc7ca353727825514aa0d52504606013e53ba916bd133814c36b98fff15f847b7383854f692450aad28231f2bb4fd839d2b532066114da65be8cc5073f9992e03836ca3a623c301999a56fb00332d1ba8a26d599d0f5a97975814be81fc9dbc536d1c165a131ca3c55d04a05d7a53fff1299d3860cafd8bc6e3b97e72a595d294303a12994510f74887fd1d7bb18da70bfc5bdd58c1f6c1cb56f5994b7f2225ce0ab29e8cf3dc851f1aa5bf2ba255f7215cc71c5da95115d6a98a2317224bc6de1b2c79353bc5c3c046a7a0933a73419f7b117b88f3a53777143546cd29014e15e37c33770a8a9a11bc2f38777e400132a812a984908b3d2b87fc465b564045e79453c0666e3682a894c269551afe25286fcdb681cb50b260b4327b46c2d0699beca103965b0a218902eb4680c1b8c3ecb2011a396b0dca97d56aad231168fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6dff91091e8b36fd2a2c6b1094a8338ad540c8f53cab80d73e7dec3977452915b616d0f0bf9e842663cc477cdb5dc94579d6222d1b647ef4d358c5435d3d0799242b66818a683e8c5651b0b26ce4909f8656ff35cd7ffa1c5988074ffa32df093bcda32aee2003825593b545b44190787c4c8656d85cac293f615811ccb35eb0413f44b1722e0a182f09481712ac68e3c9d31085ea77946a54baa91c8ab8e814c5b94206070c0a6037bc02a292082018933a5ac32141180a6dc760c2c9aceb3b1a1505464150a732664aa51b02a721b63759379a638bbfd07ff9a7a84e071fda70200c61894a8891dacc375c120a35e0a4f296a02845477bc0484fb5bc539c3b8bea3ed2511d480b1dbe76c640622b67a1a8e000b954057322cc005f88284d6290a5d720e32b5f6cb6b992bc182d66a73b5019572867640343f267133b060545d4b2be0aaff4d255d72c6e8424c2d5d23f0aa4c28094691ac4bf0f56a51ea4799810cfb024c151c35cc3c6cc90a41ab964370c2bc953a84a73c87a02813de34b933f233da28643a93388f944c033236372fa6e6aca085b598123f27122a40074a4af57684d46398e5d58b13a863b0b984e224a7ad52c1c4eb26909451dcf2a15dcb11ac4ca38d93ca350078138e0ae87f1390fc9045eea420260c913c6b54dd93495f31aac32350cd03500da308fd8ba0777c999cb4982c91e569a1c52396edc506ac7cc43264a05cc880191501860f1a32f7760ad3b17ff693508339fcfc05fae095c6a96c1e6864baf147186bc22dd882620e5a5f4516df92b8b715394c5677d0db913efb25459d6c636442a8ce22899f8943957bb2b281a8ed14bb5d0ce6de3086ea8b6165798619b2ecbfb22727cafc6409e23088c6c940c23e86a603788c07ba89d6badcef07d79174acf70c55b7b30c067bd8202a1a70998459c54384196f814515ec9c7f360061270090ef37ad32115242c2aadc0121e1a08623038b311982c669de3dbb1c7789530191b07a947c9637bfa241ed35aa1d03c81f0d70f8b95112a3b1b08b25c34dc7e1d577fd30a808ac574decbb51538c2a017287e62128f32afb0f7a73ec8831e6b975007592b5c652fa636c7315baa474f873a5da2e82fd146268dc951689ba83e046c0f4820447c3b3e6c78cd240bc4d21e0a4660eb1c69402b617b83057874122e203bd6313d7874a987f2987599cd4d7946e50665f7d9a80651cc8dbbbc4df605f48274fba0640f8609b6554a7760856259c32df00d3056aef65436a285583cfc9d9a644f66e382d4907c6d78aa461a2b6ba8887c238f81d31e796a675ee8b7a598afd5d79a0587965420a2e9f2782b71331737680a499aa759824d11acf1a001f9a5865b6568ed8a1f4f4cc38f74c24e231965e9830232924526baa377b2ee933a1fc4677ee74fd98a0881628315aa95085c7415a1a51a98406fa345a69802ba71cfc885816ea30fadea0232b13eafbc24b84347124bb41f8c663506665ce4c3801b09933c19675c1f9ce54c418207b69215c91b10451730de65a4aab6c97804ad33c50233f83599133510bb334d9c1f4b7970087700ef45500ccb31b7933fe74a346aea4c9bd409bc5a186f00bdca67cfa8d041dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e6e1a11fec0938a3a886e9b328a8a539557f6c700285693266742f779bbe2e7a0603060673c7be9591be19a57a0cac91cd1c61860a86356b90715886acac2306190cff686883a61e56140f64ba76123c1b07614ff5c8a4b402cdba738ab68b749c1151da62c30dfaa3bf826d4848c4910c9ea20669735cca4df583e0c5412b610bce816fd17ab9c203a7ea42081901c8cd78940f090efb49718ac90ad6a101093580c13b5ffa0ac0d7b094d913a9ddfab03f835f79173e966746c69a0228d06a2c363e94522ec68312cd312eccdc688c4a88f6a5b7c3464cb7ec842fc1377359a162032c8c504105461936714f451481d8a4942d1715b6a65583999b96b0c47a914f2f721f5ec6315c91b009e714f6518bfdc75e828256f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = b13cbbc323f152b23a9715d1e210086445587a3a62a216ec00b74c0026982b21e6c2fd63d059d5f001deb171703127d47928a6cd9cb5093c3e6dab85d8c36af2815563817e53ea71610b8ffe9f6d969f0515550a62a7712341fa7e3a98b4823bcf0c3a98ba7976cd5ff343aaf0e01872718010bf60f6c28ec3955539b117fe8c0b5e59021462f4f32e5253514d41a31436190b9b4cf0fa55647d71742893a7b83aad7caf98d5bd0394c8ae4ba6dc192288b69e0406fff2b0c61dad7f474e7a3bac1cd2dd2c96ec38521e0a3a37d807d554316d7f2f998d91389aaedc370845813833f147ad4494f7aa59899a9b23be3daec4d79038c746728021e6b341ce04c2904b323224a8eb48e6bc6f81bcd2b3484c5921e2e6c243e1d2b66593144c350ec5ecd7a5939527bcffed92ae72d7e1c71aee263bcbdb50e5bf91b276b3fd2582a8533c4d2088d7d079d821b5f5b25775d60b6512b8fe64d677a67118656ac602b0033661f6fed92237c6a078f037c3ec19fc4a9d8f0a31b9ae80a3e060868b2af0011ee08afffcd0b62c17d91d96c5eb13edc7adb97b6a245d34585094541b138de269f38ad87a3edf3062a24d551d239fd5c409b038b45581fa8529f64859cd5091094e9639f18bfc422190356b6d8bb92368fde8c670d053aff96539ff179e7c8e1385e328b070e9b1e40174d7344e2f552eee4eec8ce9b6e81ba9f67782cbaf0d187caf801d0fd4cc66e88139698eef60638763f90c24f5d072f6895f1d04243b4ffa6fb106d6db627b5e0fddf2452b383f76020ac14be23977a17617666bdaef26bf60ea597407ece5668f334290edb4abf51baddab112fc9486ca90048bdef3bb79a18bc6ce4d7ad1abaae3e593115ffbbdfede454943370a7a5f58a47930f82fa7999a8016028fdd906be7bbf4a21bf4f4851278515d3d18ebac857326aef3273a82a7a78538f9c4a0365acbc61a0cecbaeffb5f66efad5d47b78a690a7aad41fc8c9787af7c09f4a5fb38def3eddee45eceeaff670315cdcbb174b4fa5f0a5bbd7e2d8d65f0b0862e141a9cf6350e6611cbc5ee2ac10d1ec3debafc912627aea0607c4510f9ae4d8ab076c84546a0e76309057fc66e4813bde218346a4fff9e026446dccb73225308605a2ba9b552db468f43f22d81b305bd255f59e4fc62a7e5e0c559b839e2be1a875826fc22dfb4f57eec3bc7cc45064d7438f2b11ddbd319c9405a5479ddaf567c0e6ac8e8361350ccae87e5b2219b6383bb16be9aaebec1df4f736ada17e663afd9f65d68aeadaa66d74b4f8828b14f33466d6ac3173d6c290608d449b493d6f45f9afb00fde8e10007b367596db43f5a931fc83c3e8f5cb3aa218c25b76ccbeeedc17bb1b08f0ee9ee08e380d663b482d39cfdf5167a2b862a65107471852df5f50591212b42fd3942940f5e8a8693d107306ac7b21e4562fa2413b08375c92b1d73476d6d67cca6ac3776de360d3da5d330f2e0ff9df91df9503162d5723fb1bbe2edb8e04a21dba70bd868d403a2c42bdc11 +expected_result = pass +expected_shared_secret = 9535303e6035e30c6605c9e0f10c553dcd73828d8525cb190fea79937e093331 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +private_key = 2220bfa6a447db5013ed5811b45742b6e95c723a35851518e04b1b619c5607944c341a1aca4c0eb297bfe3990d514aba3de30867d646cd76a1ec1176f1e84ee60704b0e04366e27ed0f321bbf42322f5289f5167435b880851b48de717e40a1b56387d4705815701bc2b80c55f33b3c20244e0e27ffcf43c457a3674000a4404b4157cbefa05c54f50021684059939a3aa088dbba13be56047df450afe33c8742abb0cf48e0b1c24e8719eece41ec4a3254836b4e45b4eebbb43d398a813bccc0c42cc4e437050740c892b657765b252943896325e3f4c45887452847aa315ba8c811b39254a5c3ee64f65823fcf2a92e3198d2981289e021530aa4cbd210fabf51094392e25e755d778a02ca145fff47165711ab9397a0f9b3def26bd0e5143c23a815c8582976521d63bc74d8b42b95280cdc77de3528628862f44d475f49ac204c87d2647414a4a136a094b7fb923bfd3496b187592e81b8168bdffd9522f60bc37052fc579cb3f7a398dd677ba14a3fca1248057a59a58531b7a1f1773735a27612520b03121390cf624d46927cec7c7d00ab13dc2ba6445236bc68642ec9659d7bba40aa692c40794bc4bf5f13fbb617e711a54bd825329ac6a9af2a88a54a600c0cd6754b4a3accadb397cabf2af41463c00512d6d206d011baf6d833e4abb8dfbf736df8036278a8125389c3b99940881760ac150967464483242dd52358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0db0edda213302677fb73c493a349704333278b201b6baa8315731a348ded27283dbaa05e057c26c35d68a5252f1715337a1543895dfa4c395f9909b7b1283b450b71730292c32dcffca05221b14849aa5f94888e2a3fd33cab3b380f8093742247ac27012e8d7a6b8702983dfba43601677679568a8051925133fbf6550dc318e387c3e3176ec9c3cad6a739c6ba5b72fa587f000ca8f06eea003cd05970652b0f3f92b8bd4aa1570b02cab21d2bd0a9937a499943ce285b32706589c11cb662461444629f5c755b4a09805dd5659127bdcf5466270a5cb6328fdd0583e701aa98d34095506284b63a6f7b39d0b31fedc43e20e4bcb39b99d82515e041627fc5402290be758a062822c26b750463141d9de8793b385f556a3a3f74bd8ab61f69304ac4082e08f2cd05e5beade17d2c87b9535a084a6b0547389d08f548030b1dda0137d170039e082c5583bc83695aff0898f7e19e54204582989556b924df35a00c518ab95cbb466b5ba0d8aef007a8294294870902e74152832365fdb79508b69e45484139b4342df8c391864b80e807b9dc8ddcd4463fd1a986986b81a62d79aa9565308ac1471f09d09a23f24e4ee5522b00265770674c61348fdb3bfdd539994b20ff22b210162961b56dba538252610fa607372db1317497b85307b61d890a62b90e4dd37246763dc6093af5f4cd0dc20081ba4ce2d6bbdc969580607022c590a1687004b0730af71c60590d1a6b2a5e51c742d2cbbaa826600055f4811287a062da1696a22808507aac327a9194c5c6d49c823557100c158e60b845af953539a855d217c5a77599b1783f7488aa85f222df73b837e4b8d1006a8fd6b5b06083690b34b6586039100e84215eddb39ad2d40ba9f80165623122a2c5faf3437ab0376894ce67397d32a67c3bfb9761850c1c68ad988348725c83a378143d504400f995157903b9d04ee43404ab2cc7c35b8e0e09cce4559945f5640450703f81c35ed332746162f7b8328f78bfc3359e7c1b4fcf06155fc745c70245ffec09eca957c8475c62b05bfff288a5e5a5c78206e48c3ef373658859c3d9636786980578c07b764641d6a87222224557d10436fc72b563883ecb0934e50b6ec89429d7792ec0bfcda416fc2ac323a58df3fbcdb6e023140478868055251b1c09fa023e240e109869c1d2967f598a529042d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f228083de6a04bdf58655c59bf57b107987b88cbc001e010b9c2458bdf138288190f955b62c7013dd5784c809a7b1a29f8c3c33f0311a555306327392ddd44ec8f72fd5893f56f58baf207f9ee98b7e31092f761c390763a8b57409c7c5c665a913e20c9b62a5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5e816ff841456261bf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36674194df1ac3f595a294c28d24c26e1b1b5af5b542e025a182868e1555442e0b0d064865ed5cc1665074e55aaad601779e591e1ed2ab07cc551437603d24ca743218fa846822b2857f871fa26834e0422746a6c7dad256bc0b4bfff21bd7309482d7669f8857543a0436140ec684c959d26f2f827a84b37534b7aa3bc0a08163689f01141b511e7d11a316d2aa7d73909e889dd000c20e38667da048278b5ee87188607b4210642f5c38866fac1549637c600c8be8c60c11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dc8070b5687f7c6a73225b9233685c6b703d33677998c24e40a72894193cca1c5acbe4a133d85a6912587ad4ad522214974cbb1f877e16164683021ea9c335d41b000cf52a3ed45b2d95b7e2d061b5213db4c6bc36d76df5db9ee6984d31bcb1f6757de7e51871f1ae7f388c5134956d3286a49bba39967889c9a424772bf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15df419f6ec22d15a95553831be379ed0489749c495e3b6b8e190049a8065dba8933fb21ba3a751cff289a2e2772b06a4687338ca88c0eef1488b848afa1041f4f9607eb18bc0650055803041b728f2f1922cd984d228096ff29e71f097921423cb82254c40a615240a2482a3f5f095f5b399a8f9addeb6b726f43e3af64d09038cafea26686caa2ce2194cba660edbb083f92dc2a51142bbc922958c86c62ce7a4b3a4c95240d72244a912c3c193485208cddc4514495b35863cfc6cb41fa721a78080fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c832000c1c337fc019f0aac04b2149a469420c15b2daf5281dba5dc3618e0135c043f139cc74b14e7451fc11328f06b73f124766403541131d94506628c30b7ba68564179faed9c9d2a20f3b61793a33a65e92b699a47fde974eecbace22690273a757da903a886778002d283a819cb1ea2d34b8462dcab57c85653e363629d9270738434ab1bb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = f4245573118edd0abc115298abb1c7c118cc0d6a4365febfec360b289f244e1971e472049c9cfcef5f27d6bb6ae106138e1b42573f8dcfe10e41c49857cf586c8e1fb88e14e4e96c51d7a3775b84c38dca2361c4cfb637caf53ccfe6789ff289c1771b68832d0b445b66453699e534d81bd7d9faf248fe49b5e1be19a5e49c837191aa8ab301cde1e69b49481a2788c1aa99eb974ae2dc0a8dfc94f14baf821ef4cecee893b1c296903412c48a4aee3b1eea76370961fde96f772fa1b20a3209299e2926f76605dbd256938a9069c2564ab418c5343cdfcec02ffb2bb5a422615fdbd12a661a067e38cd35b86af9e18537e3c1f041b601e1c305ab6712d6b42ee2248f985787701270a51b052e32a52a4d9db52f1f9a775b387b0c4dccf4b5efcaf4e25c522b515cca2ab912b2cf07b7c421747357109205530c9927a3c9b639c7c473a991459f7b3391c0392a63534b0f0e604a969b3da8c29969301d8be3ba068d9a2723a6277334bc651f906166d78366e632b686145a0afd0b940221a0057274fb16b7f74fe8674c2c59199ae2f296dbffff51082655c19928eaa3bddce0fb27e5d72af612c7484d715c61fe11bb9d8b17b741aeb3b14e501999764dffca386f683d07d1b1e72329c7da38b029a970cfb1a94ac74901e07d0ccd40225ded0a778870419a7c3b32ef6ef05b1419521006706916f7d7663f8603b62e7396e047e1fc78661d7d6346623ea28e80510ddddcf918e2b985180a1a1c58ee5d40bb0a287890c0344d3cde39fda5a8c64a4e4c906dbcca97b593918ebd9f70ab79412bdc4ecc3417eec3a26cd5854b479d623cceb9129c1ab490ec98418737e5501f1fe51299eddeb86655d702d85bed3c4ae44ce16395124706cd763c80af32464504fa0d267f6ee03990b57afa2fd3a8067cd5d34b92a753bf9f590b506e2e81862cd7bc617bba82027bb9f900b55c7fcdb11485904ee2df24ffd095fdd05c1eb5d2da47080a8d3ec103d5ea7d516e1fc59bfb4f76591e10ea9e047b082b9fbeda25fdff8a946acdab298ddab2df2cb3d9ee0a781685b3b47d97009324bec36e9ad95e615fedd28505b969004b5a49aa517eea6d20ad42af18a46361df1caf9d3663fe5bc9d043d407faba0515fed3b6a615b03ef11685e4657dfbc165f20df62644e62074b9d86606e736d362b855f31402f936a2cd8d5cb96e3c209b7862b2687f054306b106b3b92570ce066ae63de2b1523590c7fbc03fb516d17ce1e13ddcc692e15f2d262b87688b9334edc0b33bbe4113e608d16c7e34b23bd3e854ed1cea39cd2548edaf85e1ff413c2afbee72cbc9d6d91ea2e98e4a1afd06c44b419b5a6a75579d89917e828edbefef6aa33c26489d7cda35e9c781b7ef5e41601593c4536aacb5cda2d8b75655f5c807f1e555da5c1415076ab0dd8d925ccd8e9493ec4a8185670d335bc7e348d8e3af544b17beae9d910c3de0b9ad5111dac9e80caa2d9960f3808858cb7be6151b76530254e8966fdb2b27cef7b7b941ebf2716b +expected_result = pass +expected_shared_secret = 0caa79e0054182c15e54159fbe36d9fb09481331a560ccd9714fff81db5615c4 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +private_key = 7934a9fabc835bf9a77bb807332251daa00876e5500d2c59f07485ed01bc934911a336acde5527dd166476ca1d1aa558cd88cd7bd17ce1791958e851991867c0525c9472a953c8b04a730e2e132c6c26811cb86f3234229f4caa2aeacd2e3c840e97b8f1805b94d7317b08354bcab64887a4e6a98ffd90a7544562ceabbcce6489c6e8534119c9589c405d7a96de3230094a459549b6f37078f2c01fc9080f049464b0a969eb742419147c8b39b8065a769d400a17bb25de51a699b69d54ba460d33ac6a6965916829b7a578d0b24bff786cef9963bf961adcc20f9a0cb1c159865a344a0e36879c67852df50aca08a46e72a4a70c027ce283de5bcb219808f2635bd7540915c5485ab70358cb017882b12acb4426b22b02605873f2bd0da59a658075136cbe15418cca0a11386aad43a52e3c5ac97f36bc7f648808c260643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc6007317a165e6a1657d0277c1e683beccc956d973c7624e959724ff9275c1aa2bb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab3709d20601c2a943d5bfbb3d384a7e83a7793905301b1704cf49992077b19f0204f3394717c9ab9a173113004fd325edb797a30155d0d2a1e4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9325f1705613705628458bd525fb333087cb4b967a61a994cbefc504d18c1b8a62898af32bc454a57e264722897d5dc71e32c2495ca857e1a234ae61c77083ba9b780342d7cfdff8b7ec1257b79cad017113a3238510c5683c3a8c396986ed392b0122c16e34a7249691ea7a931c44087fa1731746c1f3855bc72414fe3484d85b5e2586b6231b4bcf27831ea7b57070a815795f43e90b2112b235f5959ea253db76192bcb11d4e16399d40c5dc0a15d98c3b3b0289f07839f7738aba3281d45aa0a9ca1d349a64e79246c2c7770227f1e1cc74db8ab7ea7b0e60a9dc0e45443b30ca656cd6a8897ab105bda51b02179936f04374554a52992710f2a70972479462a2859736c2fe4359a474939ac3531b2905f90bc38860b5615abfb1a1327814c01048bb93c9725c7c3b0547921975766a97e29d529e4d8a090c36820db0fec33277cc679cd4a51f7ca05f204bff20acf63ec403ac7ccab951a8ec166c545abfce8734833274f724e77e68137967da75515e3c270ce79838839721bf3a14c952085071d6b3a555ce62d96e7736a583f44f726aeb921caa340d4bb788d63645deb2621629dff8a2c51d23bfee95caa7756f1884a0cd263039c37f7415e83d4908507c1b17a7308cb329d829c86953422b8b2f1786a4b86b980751255339258572a02ab22ad845632f859eac223e1245ac3533d359246316a3cc1ac58b4e6386592859547171ce05dd7a76bf8e93901eb7f40114175ac45e0b35109ac57be844c52d31a7ba60a24f30ef0e45581242c02e020ec86af106836b3dba8071bb8e8574fdf208100982e55f4b0dca72521440a2aea68c57b2039d14b21a56274972eccac7eed41c4b26cbe2c973507f1cdf4e618077406ccd3c8c5118545178351522485730b1a1ca7971b01766b914e835244bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d7c227ba5c64afd5c87e01c1ad12a294758f45804719dc7369950e9e6398bfcb60a7819585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586056201ffc3cbd92c3a42d6851ec064a89227b4d1551ca7af6b5b3e892b4e44571669412e4240a08c42551dcc50086389f9e0c0290956b5ac58844a84be308d0a5562b57b5cbc594ceae87910a13167f27ce63b822f201af5e9c33bca746ba7c5e8541fff17324228321c7a0ec976646a6b5615f80fb56351d319b31960aa8823426682a610652652994d4a78c25659b533f5b40e6236a6e704cd891502e9c2d1858ca64c94d3734ac0bbcab2db2f9e03450e721a38c82a4c26a487f006e1966fbf8063ab115e74f441837506559ba5b7266f62b17e4d959209b657193689a0354149880d08434fbc282713118d9daa89c52186ea918ce2c170d8380e45a32e9f710cd6f89daf91c9210b767d743f61655a9702051d7c8a46f17a681b136c0863cb62430d084d282099d1636c04d6b1ec212a74046d2d8108470123dd751db685a1a1fb3a3b2c216f51302fa13ad73b919a439d424a4ad9e12994d1963b3c0e0316739ce50a1a7c23d65acea61423a5792321a84ad2e1b3f5b595f11637eaca77fc753260e04cec9ccf55d70d4d567bb78749efd005c9525f6e921f0630c25cb9a129781b9b864b7556272d5b4164e340d9464bf192979a073384f6a5e52aa0b6b74d43faa5412c5914524974161afcd91660705659dca87ba482d67c8c1400b069e66a19905b331243701ac8261952c5b736b25290235669fbdcc254631294fa2e97c440d97a0211c35c2ff4b6009aa66e27cc09bc09307c7b3794a5d189892ea60b2b323e95057ff355114ab48613e2760e00baeb82b0a763067e216aab899e7ca06e195a5e92486ce8911bfd5c7d956318ac3b029436a9d88c56aae2a3dc7b382f2c5e7265a037a827761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abe42cfc463c2f1542ae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0ae91cec8235705805af096cbefd0cad6dc0bb5130907d64e76e4be957a117d121d66071598112ea7d02b9648cf53e57af9e7cc3c9803aab327d87c53e41cb9bbc42368d332e0a963c3385c18936ad7483a5f4292b625c844c2282f25af0c86984ddc09371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dbe147efc2a34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf0b12d7f5453e669be2d805dd6961454ba8b40c6efa961e53da19eea2243c998b504c8ab9eaa2db11b2f9b591990040954a1567074e69154ad6e618d0830d3b554fe4c99f48b51cf6609952cc9693acab000c335b98126b4b45a9f317f80a6049558fe9d855a026aefdc649d295387c530e075ccb32aaa202171c6f6907a4a2202a9c5fcf252d98328f12f927e31c596047140af9b177e0352b120954d00529a07d6b2bce5026a6d7cba01231a85ba39b1692694788c9215b69fcd111fdc8934a1ba24cc7890eb479aef01ff29161b0a7ad921bb72a8b495ffa74c62c880bf03f0bc175eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dcfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = 692da34419ae1d6ea887c5910ad9c1e027ca2717684d8cf8d73519be768bbe6844139f4e75a63b0251cc9842de4aef1473122681f288a19ce658cfb921114e619de23dabd7db3eb80befd83216eeee6639c589aae70ac2fb8f1b839e953a9070d287e498329e5748ac3cecdc3effdb7c75b860a64ef4a389262959b42070bdffeddbf1b41853cd7c5517a6dccbfcf74f392fa85ba62cce1dcf30a3ed8cf6608381a06051767b3f8b9e836c44c20bf54c4e174e1da9cdba988d049ae0f43f1eaf9ccfe4ad537de224db0d54efc313cdc8a16d356bbca595811f6991f80f94fbac41c45db49892ba56b20256c375b130d64a24fda9c9d796554923418dc18fb92f4e93df2ae2351c5a53566472f57e0e206d818e1d1128abf61f984ceea23df1697561fa48d0d6d5a0ff59f705297da6949955091dbb013c091d200f5856bdcb6166ecc42c36038588791f0b47dcf6dcc7a045487ba59b0075e3b53817bb8544e98a9b60a426ecdabc139792367d99e18611ac931680d59c876fe55954e3cb311c683f514520ce59cca491e3c4fc4b0f201d554f9b7667b19642639db4866c1242f0745d29383a2d009c844d2605e93e9c62d65e1d44b7030d3cc943bf0f291547f7a91f9edf37c3d0dbf1ef9d770e838f626e591e751ed64ce5b94e114cd443be38955a2ab79ce76f28800cea4cb662c1dfaef1985dbc955e09fe1156dd87d93701d05641e65127a96853ec478bd59ce855f28674db4f21188ee0572e3cf0840009c1029edad1dbc119ebb219a37f3407427c1dcb96b4f676979bd77ceebfdc0f89a8f0b759fd19787f3105c98d0797ac038d3989e1ded23fa49f3c9c580a5147d847a9f0048ee9d816176cdedc5c3bd97961687d59794dee37a2a9c7c4e6c8028b48976e944c8d45c7d7f637e50b25e4440263a67ef562e2baa5ec3c978ff8e6c390b57ff082c202272fa7e6bd4e482fb5fe7205dc56962d28d6f1ce85659299cd913938cd036268856b564a154af0e877fdad96ab0a185048cd1ea6b7dc8de79412378126be5d10ddfe4d5cdc027f183fbdd80cd9005250d72b5b2b8d824cb4512e1d15f85f68626ac262b4e169b8201ef197da7c208378a3c5d495de78bd780dbdf8e0f1b55811512fd78c1695f028f386d7bb591dd962b403da023977bb66c4145239e61730da1d91741237a65e686bd48fec1be0a6bda744a16db76f0c4622fca5d3dd2f87628deed85f8efd90f8778b2d9ff8a4150028b65aafc318571a8b954819c1c9bf0eaa2d1aeea6373213513696feb1eef11057106a76aaf501ad784326caf958c5c94bb473ad548b8db8dd508d44a667a420f7252d44e46148e76a9dbaaa766ab0578111ebc542aef2a85c0249893053ec5fc19c4fa0979227ca550e46367fd2e09d018cc894d9c24409b946f6464c54987a09b54a96bf5e672129b391b0aa95aab3903066324ade24b51dfaca8af884369f77dfdfb5e5923bb5a497e721f46a6332a6d6b822c25e581f4190080834b2e973263f22f8bd9708d7 +expected_result = pass +expected_shared_secret = 744ce1aa5a9c515c6571ad6e2f5985df8434e35e9f714cf3659f184b5db4086f + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +private_key = 46f47850e2b9aa4a6d209125be58806002c278a6295da7a4ffe85551529f17d83b358b243f2a622f353eb6138cc6380f8ad3340d7575e865a6cfd34bf473a3da8b9fc961cd921452d09b3209d041d6612576c573b08422715160b891a3370268468078f5464d7e5b84b3a3793f0c7cb2a0a13df37b9763cfbf054c768b1e65a00e8366b406251f812c5d428853d0e00f7bd58a8e348275461c1336c2ac6a39783a35d849aa9a847f37f50be0b95f617bc7adb28c0506c16ea3ce89aaa28a9252f0e228d0fca732289d05d9395133a82d8cb76db2023924273b39cb52b5a846f338b96c5b6f3acb41c7265a0c5b13094231f05943d58875ba7c2a6889f16107d325ad1b810a0b3c9e8928169d440194bbb90f771796856f9878158a432eff742fbfd5acaf59521e361f448c0bebd805a1b4435d0761d0448d83e1201a506a0b0a4980172d05e88d7d87b42054680cda74a386027aa4c3c5193fb1a893bec2722d55ab9b840d99cc81408153b383345192649eb99825bb4b1957326c4791a2722951c0ab67472f4841c20c23926c3c331f24c360e81977c2791ff3171c2c489b68c923b65d8ee6bd2d510e6ae97fb771bab401bc1a42935f38a0fd43ae2f8a24d8fc3f6e15c2c6bc800b73ccd8e91c592452484b44e6b2a624881064526182950349c78c7d58180b1676b5191eb6065c50596232b9566e4b8f0635a7d71927f8eb8572e62d57996ddf66cfed2147dc3451e95c034d6b9145bc0d30c915d66b1cce367406212f8bb40755091c9cb0306a490ef5336e21f82c1b7b6ccc8980da28a348815112f00c57362eb163a36e016d60f020bd12b6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f64e07ee6e6a300dd1cbbc840af561746d279beaa71dea5318aa3cb3c4c63c4a91e0fb60d6dd6abf1fb24d1b078de9413f1b0bfd8916577c4cc9e0b0c332625a5fb705e94babbe0659e022234586529a194012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f22a0acf114b90829b43112fdd617089c8b9d872b70d7027d74402b65058347b56074ba33fb91998e5a559d46622f5423808c8236317767a32e4772ae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abcff1be00c7bbc5b5b25a0c1d853424123c98fb330318432d324bbc7330342224baff909849d65e1d08a77e07d07cf16ce6f64fc71374eefb66bf9c742e518f2e30c480f82652b81c4ce7bf42593b990980d94062f96a7178258f31e2b90e86241c04b7b44057bf4700a040b6c0b08e4e8a6bf1cb1eef738f51ca9beb9c19b94b1cc623704a6c2455009f48b4cdd0f4a5d7f06320457670db92c7a4371743593600022da4600c56296d336a52e98888818ca10282d4767010a7abdf81bb6752048b5b163da385d7c5cb134108ecb03398500c1612a1bd563b21a0bc7b94c9719a75bf3b3e02143bf04a7e3d9b0070c4b449cb9594a1a8bbf871e595178bbcb611b466a8677905443abfa1601a9664c5f54f36dcc1ddf35381f586b4aa4566c02be610186df8493a30479f4c72aaf049a6666e806b13fd77c3b738721f81218b48984ef374babc0156f94e9eb92fff176a27197eb4ab0171211dc7fa954c652698c50105b5c2e9f7a2a887bfb40880f8624e1fc67b1b43a51139ac6025b9eeb60925d424bb82c58b4b617618c43c99b07fb14e5b86538d29700e1ccb4f53a52bda2ef566b20d8cce1d7616dc81398d14abd03964940c794e6100da994d5bc0bcf28b04a8971214e7ab9285515ef09a7b486ecae5c84655c9ee15255b715c3b784d9c243993171c604a3e29450728396e7572228610bb9ac04b06577b3636c137a24e2139b48db005553152c6b040cf0b2408248675eb90afb66d6105537a316c7c989746f43c3b284342e2cdb5f2183a16ce71ab39c67797112b0b907c00f6a47f17db08d924826d526cf88234a25676d82449f93b2859076978860e499a0de134a936e35f06a7802456008c23970818318aa2b55a1762a9394dda7a49ebb4b38469410f5945dba2801ac25ba39a2df819b0db194b53c4247fa5065ff99f73e71d51c22f51fc262dd2809ebcc6879b0d90004da5ba7cc9462f6c822ac8fac8ab95b769a465cd743ba2babb26958ab9c3494d329a0c736c28a9cf84f5c90c5a0594485a9b339212d01bf6910105d44109b09bd063b4f2f3b903c94dc650812ae5cc87527754d476ffa82f34f39b5462006029875712cfb1da648dabace5aa1590b5ccea82c20e74795c71bb70826ef4d0bba580a447693a42d8af3256c64ce327b370ce576b6343f2bf8fecc76e1434d5e448aa8a3b326584ddc56496704be54108f8572170c2bc39680598017641422bb81645959b8092e82a54c68aff60b78be78107e7bcacb241b09913461579b52aac5c6c8627cc033be2273580a523d4cb7979cb65d7056643856be187ddac112799559a87168aa96a18089a6c547e87da949c62b8ea876aa0192af409bfbc354f05dc08fed46904a2688fba59fb71b83031a19bc8a6350bba93552be0c01b73c89964563fe588a5b76971dacba69868b588bb2f9076532d6a8fb4316dda4c85c2945a2a29b6ead3900e50abef2b44375ac36bcb0e028a20cce58353c827f1d53a9a0510e3827cbd1383a6d18c0d22c374e2b6061c2197a6cb094ca9dcb42f0418c24a9cb893c45423447cd5eabb0b9b410c9144013543e5c3bad525377ce8073d4a5f4a22bb24874b7e21523cca731265572b487e3b42ae581a617437348c290f00ad09460aa0c7b6a1a53128e4e01b3c406a296cb35ca0bd0d1917dff42a4848ab3bc28a2a28044c719ccaac45c513ca007653bc854dbdb79181157aa17220153ca3563b21be77aceae06bcd02531ff5b7f5453db0119364dc4e97ac7a495287815b5eb512129643aac4f42b3af35afc1207db0a3194302fef097bae37bf382c154e78154b3407bbd90bb2143bc285af1ea0b1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83baf26ef19367724b1c989c39bcb4337deabf7d531fe2b3327f4ab0f6457c5f3869590c49664923993cb2b0103b8e8a41cc5793acd192a047972978a2ea1b9e354cb135f2ad8928574b2c14fbc1a4c02715292c9052b69ab2a8329c02938bfa0994c209f816a24eb13f4365af2d20240ef66f9bf6b39d54ab5d350c7cb3cd6f645379815aa3028232bc89bb89bfa2c62e351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d010e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = 6d7d3b4a4c4089566f5519cff32e125274f9706757ac5e10fd2e3b104025ff7aa64192ecfc2ffaa86e2f48c8afbfbc635b75ddc04d2867a39054d0c3489ebefb7297215a505e7f65d93115592d78a709195f9cdf6a3cd7a7cc1b9cef75aef9fb2bc05136c5c73714d6b078cd2ba88bbe9fb61302e1d0771520509b90163d1514bb510d2e2a0e4e4872e607f303ecd6b9d36bbd694c3ae905d7c9424b604be28ef2e985977a575d778e219dad4a16b0107cd68af5ade5fe9e3ca48910fd2b6545ab2a38fb9e7159ed97b1c8d3aa7b962e4eba2d75439a6846f9c7447685d8208934c6b9dc0a47103fc71ae6612b10d4c71beb667746e9ac680a2c750331d1d79a54b3e991aa7eea7ff896d98a63c7f499f646b349b695d74aa849a4268c450d72aa8f531784641282c7f58f207c085144a1bbb28b657e9dfeabc03ef0784fb4aca22a2fd0678ff1b365b987c170225c6785540ec2112a577c20151dbd47028e88bc2b45723c3b50edc0efc0bafc741c4b8208aeca01f2af5c223d5c6016676b09c8ffb64874616a2891031a3fcb2c4d21c073b5bf14b6e5e313bd252267ea4165b347793de3f4f93b9f269ea07a60548c9fb8560a49e544aff22017ceff150ef44b12dc013b6675c1b709d4f40808fa37a9352dff8d37acf1ac5f7e6a27673dc79e83cae6b1e69fe113155646cd1b6e87e2e9cf67c3f2d2576a2c47a6156caa33fc547f343c51a17932368e1290e0ba91e35482a70c7777eb45a482f261f77cd88dfc4ffdbab03e01740fac45457a6653059975519f2db38c9155a31bafd22c57c5212483bfc55ef9bec51be4860eb574bde711dda9825db976e39f535a7edfae6077e1e1644776fadff2f9e18e98eb238c7bdf35c9c1af1889f08d61f51227387c5b01d0434178b55aabbc1945c78cc4da30d4b799ca4da2228c410bd8d5d4a01a0a8b0530a61277c9db721946cc605d089fd944a8c8787aeaa9f3fc6026bff912cebb5b85923d25cce52e1372b5861957a39db748cf275c4530479b3f0d061ae44599fb392337b2e5f8cfe8a77c73dba4c9a77428e47abc6011cf37e86d8a748d2899bea405b2fe43172ac5361482b69c3b16afeac9f43016f3dd0191f627624e5faff4a92e1853b16f4635b41cc1b256f27f54930139c3b50d5b2126c86121ec72f7fd11d06f728412e309b9df172d2acd8f1f7c1a6c86629e3e0174023e3e73d01379327a59031829aa7d6acf01b22cd550b1fe31af06d91f43fa51cd5b6df75e6081c84875773b053c6e473b8cf1b13620633082a47f1610cd60e64da50902801f0077e65a0d4d2a5467e59d7e1b95b0eeb95db0642ff81c2cf6b76d42e6bdb58fbfc0730a55f81c2886160df921a8c04c6175008743796a4a67494cea3049b8ac89df062aabaab5c277bf1a81a61d4b42000b2fb55b027d9bb6d3e3e984ee595c6a76b66332b9554b38fdb0e93b77cfd9f891f25c7105fd2c1679a04ed526cfa6a26984e19d71b2b57ac3635f233dff02a799e9cdd565bedfca93d2ed66 +expected_result = pass +expected_shared_secret = 726f7d790df4c860a0b2c40de9d62c85d0ff70c704ce5a1b3f6bf1b3e3f66cd8 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +private_key = 8747252c693a0d6c06ab66071b13517e1c45abb370d26aba3fb31641a170b365c5f6235d1fd688d81c72716a3921420d228a7bd5a1c48ff445c47489b8116b7ca14d3ea78b20a7b5e579c5681187a2aa8fc900557501003fb9bead185ba9e7939f247bf1757ea66a4392095ea90239a3c67a8ca70186047d9a6b06b8887fae01ba8e556319a003934c88ddeb05f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad06e116f4542c4322072e3c6713015b1339512419b4daa8c87f5a8bff481964a8ab8a101943230f9527a10a604df6275e1ef18fe54a57d7544402134ab77802333897d4769ac23093f9b951d735b5623452c90270a0896ed3a81bf1191e451a4a67a4542556af78f1690982360ff1bfcff66386827df93bcd894ac8c996be6e0a29de70ccd459b9de46acc9e8043bb82d01c40e5785845ff4b0ddb8184afc5e52a72e899093669a9eb110a100a1159241bdd40612a9b1955b1752810764e7b68d89704a61442adf68108aa229e406cd10b6527a39a6b46068685b5e802cc25614492dbb6e06ba2160e930733956e7b29ab9981d4b477cd4eab880e56eb711b278f540ac204a996b32fd06b8bfcb7729660cf5125fe1626199f6285da628faf491dce2ca3bf285902350d52c0649339f31ea3ab764b90701bd647194fb27383681c13470b8d5ccb61dd74c5f666ffea7b0714c469c4803107235599c998349b5be7ab9e9dc6f01e928593939270411ee2490f16c54ba672ee03b710978760b962319bab3c2fc67cd9c2e9d4c153a8717826bc4c3d6c7444c051a61a06a2c87a1207a20754e9d7725b91077766871509ccc93f5a1fc1c20680263082801f6b81e8f319b92110f2da22f0d8c251ee4531b127c44b378da6a0d26f55de3285190ba1357012e42521cd1855252147d1abcb1582422f55091b5eaade93194cfa0be536343a282c4a948c355984cd20a7ca454ba034ac7355b02730107a71b3986fa01faa38d17e07494fb510e5526f690bfb27294fbb963a0606e140a182a9a247029abdff6bd8e876ec92207312432cc2700ec4c6a4a7037c5b612eeb2099d54872a5884e28981d794c7855590f1f1464017c8724bc92e0b644de92b5b80a573f641e4e65bd6f0396184086d6a5a50662f9cc6241fb7241d194b6d23ae6fa3c59fe60c81309ff7e39f93f72bcb0696edc771a80cc5ffc74138ac9d01b95defe7258bc555e3e28cab6a73372337efa0b4aa0c7d13b312a7313f8b63426c6677407903822aa1acf4acf4a130c4c68dd4dc47dd061ed0a4969e5ab630baa11fa0aa51133c6509c83e603425a385730aa0e07a2bac0754358c812f483f5ca6bef3105cce4cc33532116c6493f19880f693581e08999be24db44b84970c8fa4f6784d50614cdc9e626a31966acf81309ea6a730eb42011663cf10a90a9ec12f3fe133a7d02cfb95cecc6b52cc08571bd03e8315532b7c76c2040b60e9021a24734854b6a3d77cbfd087015410b7322ad5d9b04f651f895ab5bfc25f8cc9703bc67dc5eb5aede41682a17feb1b4339335efaa44a64e8b4eb0bbe17fb00875a06318c1e68c42e6ce0946a59c61700a72779765c405485d51fb10cb0f150b9db466c53e070f5849049d225047bc47aa15f630a6d62c5b179906ee6c067fa3384a4c22748f984eb31ab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b261beb0eb4eebcb8548139bbd6a0a844ca1e4e59f3d7c4372ea8632b278a7e68b59032012c5518a8021bd5367557077c9c1b4a50944ea1a834bb61004b2cba7f6401a57839a3cb85b326449a25457851b4a2bba2e2187f040745fb608079c8b59d2b191813d51c5c3f329b1f5e40771e1b33f63ca400555ce5351cffca2ddd268d7855151618587c8b037e7ca290467e4a7c2c38290b84ab8dc4a839f57102dd559114092165b13b130b41bea2f857c84ae45c1734375a3ea91021014d29ac58f12bd5a44b91ce986e094a66089479dcac23a6275b864195df24f2d4a97f1b26b508c3a5bb89b9f0a913867c1294c252d5022d9fc60ffeb3ff3c29b2dd1aa97f22271c5c8e749cacea39f2c637ff4a235882747ceca1d95e093966462ad401510ec112026bf0fbc106270988b2c35cc7269da693a7d67052f9156d30c916ad6552eacaa3ac2396bc56668686ea8a1578e46658a71b4b7365ae56a263c783973c1b63100b1aff4c3feb64856a781334c6e83519e541511b4d581914c697ff31239dac56662a145316ac4d14e522480782c4ec52b1a2b8a85f657217ed11426a2a606c01c17171fd10824c07042b189225d40919aac5cbe05b031689b1ea61041f6091d961a8910a205e62ff21909c6b4095b270d87c9727a2b611118c84aac033ea9cab5f40efad6117f2160a56505fd775d3f415aae9271a9b2b1fd1964edfb772a9c4875f06826a49c26e93f0b1846e006468de71b98ac6fc0f81ab146236739c9a7b6c13952089d621936e8b265b50dd4016547a2abd52339daa0b459d265558a1d9b61c73e49346396b6155195c9c3a437614e68e23143f09fd28857aaea50aa808600f5c5ca33c5963cc00c4b1c1ce2609486ac4f1b2ddb7b06acb62398a32320f315dabcaf5d4a833e2a01a6e7c971ca15e40c459ef18db8452aabe1584412b4c4dc52e6004ca56b5f48555041cc828a7a6da77c435f05574e5c25efc3c6057443eb77993c987cac2363c3030d88e288f4d08966e624794078a39c53ecf273df178cb022a5fb025a2687409a785cd6c019f5761b0a3087ae91844a69c2a89c1a00b1caec7c1f7a67425b87be02d80b67ca6c7dc3b45bf425dfd33dc5a13e7531907ed6329593c333466d9628668b98422c985182f8c0952cbf5052225363398e516d23678b5320a9cca38e21c6be86822c4fcbb9094277bce80992858c5498c6bcc57db982c196b1a78c317975544ffdf33e57a30dd29a5ca4a22a918746fd9a84ee1008db920432e39b6ff182c930243cf350c6f486832a807a36c8a9242a5c39140eaa7a45bace0086a86fe36be28acec756b5e9a47225638659b250c52b564751ce8c42c39bd1046d2b6cda70b7951707b63073f0eb5ea3fc5229f816ebf4007ce97307c6607b4ca17ca30330570d4f39bf76998147060cc04b33d4b91294f85f4a717ef9c288e3741f70fa5823ab8329f56d9d0b05c996701a050a387362db09427d5587e7751131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e47c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = d1a47ec5e9df73d00ea6c31f8189070b3cdbafbd59d3561ff50a2961820739bbd40cd0dc9183f9dedf28da0dc608b7c0da800fa9ee2b44331062d972cfaf9a08a943f60e4cd3dfb6eee587cb152308ec9c772c566452fcf0e16745d5ea6854a2fd14812c4c08e065464a0d494df56861e6fe82fabb22e955825d303dab2abe42d094f0abe8f10b788a24f90180dc9434b163db2aa4d461566111e6817a92434a2427c365a05232fc31ece1d49463cc3667a92760480857c893a180bbb4b4afa50ca382e9e4cfe5cd3e3a424d5b927fc75387fe72f7e38c267fe94a9cbc12b64141b574c45d6aeccc7cd28ad9ff4563d5ecdba1dc19baa079940d6c71f18819180481fad6025ddb5254e7cf39cca79bbb190cb526c427d15551a9af18c003f92f35c8f8db6bbd27af8e6108f9827332d836dfb5299cf9af20d6cedf3f3bdd3c29d0c46350dc4bfa046ebd38125f4a5480e6543090c4b3ecfb11ae6b31c501d38ae00b21d4889c10d697207ece62b5dc607ed66997bce2a2c2aeb2db1e8e9346456b9bff2f40668d0ffeb8fd3909ef59b7bf2e23c81938502a702c4c531024fbd6265980b2f16c70fbadde02abe62a9e530ac31b2bfae08581146a2c47691c755cc4e08e35bff1acd79cd12dad150e308f0d421dda9539b3d142fa544dccbf9bef3441fb8dd08c21756fac0d4efe441ab6b8c1c21a5e7604914a3181a52ebafdb7de84b0b634cac7cf9c616d851f8a7c3a1e6d1e7362642cfd00870fbe15dbe0fb122ec58ab300e93c65462f8e9fe59be9a05919aefb568edf13e4bde5ecd0b5912b29a044e3f33477a35f925f32d1f52adb91620e8f667d5a55d428737b3fffb76439db79b74e7da3ead61f3c43a13e030cad345415ee18d7415ff6296ab1cd0d306058d3a785fb1cb27a18d245dacee17fe8a0e3aea3299f6d3c211be3165dde7caf805efab878de257a8051fd2650473e6d3ac4eb9233e38ce9452ad85862d3684d864220902358d35027451962ea11492038fcaf2ef3faf3cfd8cf77295e30b7dffaba171f48062e6b9213efd6d2feeaa688191626dbb2fcc89a0175ab32351e7c72005ebae83c13d59bbaf0d4a5f1030168de6a7c76c83943456867435b63fe864550dd99bf934703debf2192d6a1cc1a363e8933f1b5e176941b3189ad53f038423d90b9a2ec584ede715b903f1a9917358bc7616a6d5bfd20c73f98104bf1509aaf19960fa2145caf47915db32af854b2c75abccd0763d06c5977efd369ef5a55df1c3e13ffaebd2a9cf99ea1f75e796c3a6bf38de65fc10aaaf024946d1df9f429115139fd5564682773e5513f2c0ff6838a5e31197fb199284402274c10dc157da502a06a2c610822a1f970adebf555e5832767f21714033581699b1c01e554099a7ac9b31e890ea981cdbc917e063fc162c877c51358431d00875c4270160d54d93841535c582804e1b68bfe87877fc265ef906fb62331e4b7bbceaf9f12f255df44976e4e34e3f5fe186a21b2b411410c45deb34a64911bf410de13 +expected_result = pass +expected_shared_secret = 68f3e22d1b2d8c57bff32160e550becfce535fdcb327394aabeb60eede263213 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +private_key = a32b081d2579d7737a984126b05465963ac3d0fc3d471b94e30b242699ae3ee7a305d187d9371af3568d7bbabdc30ca69be166aaa07c67799dce7345b2024ee41c5a6f35733cd12efa19256ddb74440829c6b52aaa25b258bac8d950ccdea410535bb3a44a46ebc44f5772cdad96596980c32a14916cf5c4a2fa8538491f7eea270543abc467344ff098edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca0165528241b4bc173bf17b4e7873a5081016a1c55e4bb1e7f71b849274d03e05e866656c126485979ce9660afdf3622e3051f76d02243e660a5a78c663880a7f9765df45410926a86acc7962878b4037cf2960b06f072367b476eb24b8c57924a9c699815bbeb0bb10b2a88b0c63f0171c759d59cea91c5c043a41a8155e462325893685f18c5458a0ac3e5bf2c696c8f07727c090e1d3502d075a706551c54a00a710027c52cbd83fb9dbd7567aca2b6eb809c00838e56b209e0c5aad2e6235e2c157d3659d906452f4a8c60b26f838a51f6789e42c00580e4595a5c0a12b796cb44240a4724c298abff1332bb0970a3ec475a434ec4dc2a4aa92c42e22035a4499c66827c882b542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0bc0a0c3b86788459b659a539833629c1b585a13134d766c9e8003282683aac1486a934edd3a7511319a7952b5eb7c5947b69ab5c904b2481a7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0e982a24d344ee8a22221a02c6538154217c453ac0ecd4bb1f820baab94d920765c4ac15972aa79ba974f3b5055efa7fe5bcb454f7ae70e1c017322a20c73ebf278054060687c6301e13b52952459c56bc8d8795044302fc9123921143ec2c73278939826682126b65c7d9bac044ae6cc7ca40f92c8ff28470e41d51895adb53ae30216b1aba552fcc14ab277a872029f3dc8d56794d842ba06770808f1c097787973b0a14280c5fbcc45c102c23821a07eea6c3abb4b52ae116f4b38e4a50cfb849177766495463197bca3197b53ab72b172c163003c9ab89721eff925f56b59373f5abd1430b0731419a12ba80641628d78d712bbb74579c0a18a4cb2aa6edd76fd7605fbf8214a00aa44e486810f3ac6e36345431c23f247f251112cb8a6c76444b1a5277b7c68afd2c49d4a81fc5069b9a004cdf0587a4a193d243bc5f16357e1b1f280706b4c16f9d8b3b6a5815a1597c49076589d5303a5c89ad320cf6042f2f819cdff04b850870e807b4f2b6bf99aa8f3fd16e95b3bedf247cdbdab048586116db7a4530c360bb240fb2964fd41a5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e8461cbe906e93b209742c0abec1c1bba9baa05a8fd05637d26548f48512f5477b93d0bd54f6674158b2f6ea0488191eb023a641b175cc689a2f326214793228138d6da03bfe4466dc962fd2a7c57102cf3f96cf3a6619d2f613ca063a35f4515c0473140b8ec3c53b1d9974021616bca2459bc31502daafc861990c1b97ea1ab5ae018ead781a67a075cc4924f9ea364bec33ed167637f0a643c3a810914a49366af69b3cc25938e77422832b7078c6be562513ee3648758515e3c04f7e395f02d56d41b5c5889bb6b2f149425a2ac8aa06ff23a82841887de199b56c91846392a026b50e87453f44588ee6ad4a443f54d25ecae39aaf286efb47a760da01b6c13fa178811c47a0dfb14110fc6482543e8a3a52abec3a8d7176aa2868b2d46cf68538c27514222a34371c25fe832184206e5abb699d61426027a942581d0bab075a367793c81b7fdc11e2f6772c8040d271be5d07d00b330a6c874b46d26f51db8f43f22dfcd72613f8c22d15c28a2b384051142c148b07f7362eea4771959b635a215b1351f650342d2a071acb16dd8ab50539096f295e44173bcac20f3cb271a8041e3008a742057ef2fb2d78f8a3a3c252f6d38d8e85bd57a75d45ab4dc21b8033992caa623866e8989f98560de33004d3409f233020899340b2591e1a4a0223a79e20b4b85c632ce7609c0c45a0246251468c1b6c20716315a54520c5718f4c5c7066331fc7e953ed91aa5f3b92e69617b29c256657124242ae8305780cc0caf00c92896929a1648be9b47f86f144a3b12d9dd51f347875e6da935f0bd043abbfdc7b85066a7836d442872c56fdd41d9a3a01d9ac6a12531079f74b273ca129f36a7ae463f6464436e50fa70cbc2756bd25234893b50a2898345e588b819c0955e9c50072517d58b0a3e4bfc9832b727c7f2fa924ac672d4d104a8f3ab81200a624c61eb6aa7b4553aeb2084360f1c03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed6b12e8be5a6ccc74efea7cefc7a0f5ee18857250d08f03cd94cb4c455141d7aa2fbfcbe3eb896c2404bfa3580bc63b73265581d87618b206caa9468c65bb1863b18f560413d1b1d392259f37c00f7d89124c56913483513006feff89092f218fdcbb8b118b206b64f2de52be0b553665c32831bb4cba3762991716be65e6a222b30a0a5cb246207352732bc3c8ad7a2c3243c62424af222a922787f7fe44df05299da1105f9ebb0c5aa18b6c6c73f43390af9c2454442110aab4aa629c8f300dd38318c43a25d269885f970ddd8ac1e5918e59a3d53dc8a44873eea97c31f34108b893b634284d69153779230c28b2a1636b6b839a4d91b7e23f0414b111f2e7c1b3ed58613120fec37c78308587494233313950d82ce946778e044c3d245a19c29b09a80c3b55416a811af33032a0068c7a4767f05e9aac3e8b99b967f88d5281a38b072b8c4e194794c40bcd5366714525e846048e55c008cb48b5ea0c61655b8819b08fbb88337e20d63003f2453462598ca66181ace033c707c1ae9760ced165596b2b163e54934540c4f7097bdf14d29ea850b95be6fd42973436144270549a81b5f73192c2c6ac2474686a9a3ee556b6f26a9039866176026e25a60b5864e963850cdc8219d21859b5c5c3714434ea53bb16786dde8036f317c430b3bdb025e6b62c097340f1e961b90e0c5182183de05b293a05b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b835c0e2973261bdaa43e414153118b66c641f834c949e77fcdbcb59dc27089138a2e07a5b40c7666794fd8e6b97685bc4a3c2a65912c35f50a278bbad765c8c775bacf28181d61530e54ae7fdcaa2681a01bf51c0d7a033d6b005893b98da86005381f1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f58aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = 9066923999bae264f53cf96f4712cc8655ec53d9a692221863ac713b2c6febc02e5b43163d008e1a5a81525dab273757a27c568ab980e5f15dc01ba4e370915d2f77cefe1a1e6fc2fd189e7717f135d9b5ef2cb4097715a825092e022bd750abcd7cb3d6ff8f73918443eafe6c2c06a00f0c65d45dec9cf12626e19c1ec4bbb01bac2a34e02d096be6836153d0802eb8e62c1f4e46a53ec661a304a223b0b3c7ae0799f8f0b162b962ab3c92dfb5fc8168632bacdce1bcbea60a0e88956288152d2a2403c3ec1cd483eb119eb62c5878694276a18d58b20c849bf41f42b1bd8abdbe68a9f0504fc106f47ed36c2b1fea208583737ff02c23470fd81597079bde3f56845a3a444870671c410f7010af93f253c1f14fca19737738923a90b78e097fe52a130df7f2fa622203a05a7099378cd22de5511db73715839a043b17adcc7d9ea75fab128482182efe6fcf9d87af3bd80fdc1afef0a635d387f39b27e73948540953976e66df8672115184bd7719248ece5afa6e85e59bac2415a9c242c7e28556d26ef5a298c2d7b4e80d05854e5d8148439695b645cc27e041095bceafa10e3f049f23f42c4a7bae8b58f031a1885ca2a18f1ced48148e52d16ebd12b63931dbb9f21e46209f6714a092535f454a8d3968fddd8022130c6bb989d0dd84dee9849ea3f75496425654634adee5462d6b425ba4e911fc8c47f98a67c3c116d12f372608d0bfa2d066bd5c3b961c64044a0f8186833213551415b2beafcb74d9b77f59f8b78568c9337bf73449f70c08ead3086c50ad0193082925cce5ec4df8df4b841ac1deda751873d1b0698e8037499fc3ee3434fb72b1710e6294909bdefe9e670cf80260066fcad5d7dacf233af61960c651164c40eed1d08e91f87ed638cd3879e2c933921108a4da065b4b2cd8f965a3365b130ddb2d1f0ff017f6d91e9aac01fee659403e00ca1008198eccc6572f0e49dbd0ffd8006a45fb6daeda45ad2a7ec4970406b44f6f0c5252bc2234b9db504810a15ba85ea28dd19ffc0476a38d0b74856836588a31792ac185f5208ce4ca0d1a5e2210d049a7a38c9b6953e8a4a154a34a15d4dcd1a758e5a03a746ae1fd576cd14c85f09d0bc8554ad570dd55e6ca80308a927515b215c1af914f9e409ae14cf99960e8355d6316297c6b18132dc89ee1a5bcd3ea1623a8c0b974e17048a18081ca47c2a22049c98f0c5c640d304a7fd80089bd1c0baf634b7bafe352e7d57c12771c8c4f944e4ee03b50fa3d4561f615f8f87fdd3f3181cc6d74e63b2393e5e38e71b1fd2a3aca442d45f1ffd7776184c5e2eb5637e31aeb60e547ddb12c7d276304f166c7be9c4569f34209875407fe3e273842b4cdb28408515e69313cbef447234f6dd7fb0606aa3bc42293dc31d1be2c18a221dc650644708dbadc53849c80fc2e91abaf51f869796d5e78c5b53d2ebeb3a2efe02dac17a177aefb0a583bc271cf7ab5d73686fc971db994575adf973fc84bb9ca50609c52a22fe421cc3b6f35735de793ce75 +expected_result = pass +expected_shared_secret = 7f6085840a30c6b1fb9dca782e0c78a2264d54726c04c3127956f131165426c8 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +private_key = d1f46e67cc5aea63ca9ec413938661c2f8156cc79e10a64174774545b597e91a8cadb58deb15b27f343073b071873870bf858b5fa3ac3689698deb68c570406972210c2b9909571a12753448e00e6a0c165a101469828e8f60a16b55478c8899d9a38c1751bf220a60a999b0d2a429b375137db8bc9b85ad5fcc073355ae630100f8fc68ebb8534135590ce22d0a0672ab54936c8665aaf476b50293a32135283777c375767b04547501a53b72a14d3c4de4e001d16b2b2b598a22d784a3711c39db183ac82cf895b242954b41c713bf464464917d6b608d21b67b3519a6df161ad237359e262b95c6be3a8522b9248346785fd0db03cd083a21092f4d91af156b12f4c9c77c11cc0b68adbdb813beb21289743758f8136661704d0c5ca9302a064040334017d47815b7c35363f5c730298670536c69c122cc91cdfd18783efc4c39c8c29cb1023f1488a7469f1cfc1d7ebb3d1ceaadba3b07310000bd89c043290abed896e655cb1f43a1c7335aee30044d9652e6d3b8e394218f63072c7050a2984032c45735a3aaa4108aed8b9a19c13b9bac28ccb123d9987c45b91e89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1aa415df9961a4785337535869fb758cd04b798907e36197ea428c66aa516f602404e87341e154a0e09c881725cbf00761fd9645b658d97d21f33059e4a898deb0c826d9057ac302663897d71567117fc4416c860775b026e51a52663711868777d542f1224b277ec005f2bbcfc0c84146591cb36caba82692b010de229797cac57aeb64af446a896527bed9b3e55539c0f6a0e9eca5953890b95b0b282c3a4c46a44a8705a54a8806ccc0d3c736a20d34aab118813651d85f12906958933d69679d0457a4817dc83b525ccc63e94c1bcb1c869cb3a0bc46d47084481c2563754aa8f44682b870ed04996cb8886f43b91ac8767ae12856ce5b85f55c8802830ba1babf5797d0da723eec24616a195ac809371d93f89b19c874c840ee9c39e7370ca561b6e91552cea47f1d09c9cf633e7cabc9ef85f89d01a29d9cfca8143bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a82322793906462c03c20969f76c2c8c8ea2622a373c3e40164a77055ebae05787965b60a861c09658c32d4194dccd7ab1df87826590890b1785f0385b965b5ab3b870a0088696a783b5c7a69962b86f789bd43588705315258c117c4313198af42e2b7fe39894a86189ffc4e8c6bac5e7a0f03d86d18089a6999972f309a6debb365781f64197165d259bda98c7a920a9e790bddc587e7c08040d649b8b08fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5152b049850857308ba1310283a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd7712686200d451cafe599ab0d3a183d2b0df7b8fbf0995042ba0ce682eba8b71dc6c0744262c75b7638b51b9c4931d4f7c842328486a799d06027cd5cc75e4b1b6816c2ad66b86ed047ef978184bd344c00aa1200432c5d142246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375060282b7da42ecd36295fa55f8b5ce94b812bc421bb5d6022ef207e7629736d614527619e33cb92600a1e39a20b25a5b16eb0ec1070e5d566b28449bfb38936f44721ed428ced5768ee647a771b7d76a30c7e5563b515f5aa89ffe994cffd9277b0695049c355267b3a07c61f3c5a2c0d4ab8df76129c19f44f762b51bc0374a43e6f6c1155901b2430b2b77afc9ba4e14d3658607387dbc2d12b99ec0c0b0c2721af298a6ebc92a7e6b97bc460674931e21f68377c8303b24cae8d5ab720c79c4399414a514254603b565397857a7078b36e24a262cf9070a92c034c76614d5ab455b60b3b3388500946677195cd587942342a6fc91bef144ea412ece186a422b85a213c43fd0c361aa00698458f5c5370c6c553a9c238201754e2b2e2785bb03053e0b414e472087a0276bf2d805cf477378ca34d8f01c21b433f33b49a8b9bcf762451460558fb9c3cd071e654c250df04b6541baa278c1669bb49ca3ab4c78cc92d0137a2864bae0c904e23aa28395edcb435d9c1cf742562d603bc61c521145ca16f69192b137ee372f04402527bc557b754e187355a388410751267561a6b1f59e04190ebc604ff64a2b08b244b57abe84f18938c5a9ecdc972191bba33915c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f421281b5763865c584cfda6aad7482d00a0520d947fddb173947865fe178f9800570d4b2b9529a42a514a8691c8531a271c18e5f84380c20cd9a992051d29b5be76b2235b511514904e3b284e8854556334515162db1b09894b18a3127982269509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bca04e2cd90db634a3d52b734e224c4c60ba3c8240d7b2755ae5892a09a0e7ea1b2424402c45a0ad59563ab97ed906a1a15b8c4412219203ce6826b91dd00ad602089ebc5163b416c0d02009a7a5440350a00a7b49309ce39ba26df79ece038f23f4b4300c01287a51f5fc619eba04ab1b78e6396bb23c1cb86a0f3bb11f7d31a161a480b8f33734cc63ea7219d76bab759b1ab3405ca61b535b893b1bf2b678849751a6a4f18923ef44470e543924d0c462d8a078782b80241334f547d2aa474d95b8709747162b228993ba15a0c4fbd8bd662a1a2f01cfa859ca723a011949823fbb55947b9c27c2bad547b0e6d29665071b30f3c8c536651e6437c0d4a314ab38a8f707928c0c2b864a3a67397a936dbfb98fab2c0935441b83157d05072891a43573882be97686534c8bc7015ac267b75f0a79c6991cb6c96c735a4bea90acc9bb6ba1b12388f0821a074018909f76944d9295b5eff73e70ac1b0e1644e3a40685305f8a0626b2f05969fbb4cae07c61f6213159b3471654a88ab58ec3a648f2944625820f6592c67126bc085dce216fa708089d4947ab911ac14c00e53782a01580fd967594e0b2b2a3272d590aa70c7a3f419accd33c1b1294d21242c739a3e8e577316c23ebd4b4c4d0577b2bbb12cca71841b54c0b76729320bce26dbfe5bbc017c92491762a6c938d4bb0099aaea190813a3a78e5685d83975050d719d6b6a80ac313d3018d25b9054b5013f832c1353401e6cba3fe527b8d2906871b79836cb35284725e733d8fb60e6a8410e5f61428a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = 99d62a49c06c371bd6d26ec8c497e9383a842e6374424085f3922951dd554e866a4593f4651c64c1ec8123ace1cc6f54674e685018b756d6d7a5d6ea146ce22f25743c06aaa95093177f25ca0be23e6e76f5f71a5b741a29fef9c82137aeef17392972687f24184bc0c90344d3c51759546dcf761aad332c7d31ec3e08bb6021e07efe3b8fde04f6d1f718eca765e27fec6592b94315e116cae292d94e72004bae5b6d5a99d03801bcd0420a459605498f299cee4b3ce6cbbf0178894b9e20a421b885914e436b7356294e69f1d419a9633a712771931cbdee3b1c02539e4a080ce2be2dffc33f15fff7d3368dffb2fdb4ad6ebccb71b5746ff2bb19c809129dba5cef8d17ae011b64472b38107416b88585645cb3c80a794febed9e0e16c169ed0dea7ef52c079ffd05e2cd3cf2c6b3cb31813ad0780be61ff258b53f04735c2a3e8ed23dde9d44b5e7e182d0bcf1e19fc9d7fe5084f06e311aa4cffe8e2dd79457024b94a2b0a56f2f6f3caadc4ca3c6dbcfb538ad58862306e63b50472194578d708e5456aafb34d4a31dac16c6e596367b636dbb07a5a932b863d86d3b9b9a20514c6aac42b135b98b747b6bf1e0ee53cc9d9ca1b6ba97cd4b029ecf0ba3fbcbbe01392e43593195e34442100017655486b8bfa442f65256ce79a8e1c4c0429030d4d37cedee7d1fd6749de72d187a8b4554756842f035e7e873f06794a315ac8f1b26a6357447813b60fc9d6c4757b696df2290529765e2276418a8df9d22408cb9b8b1b34da3778cb981e9d08c69e003e251d98651050676d4238698a0879209e772fd5db2e552c38e38a822a1d6ca1c0f2fbf8399501991606ece8480f8b5f84a965a0e1e3da39459b7e6adfcd4d4bfe27119a608b0edcb134ed12d5798796cccae06970e1f283aa2ec5c5d736fb7afdda1dbfce7f89015eb195c56ec23ba0c10ef7937ea39ed252a47a812e599ec99048c50456631214fe7e76d11d7f1e2a5ea7b52c93c9b810a18f71309b0ff7aeec8c9243bd8695ed9b8311f18022533f6f294e281a9ecc525e99774627628f8b8bf9da0308e1910f255494d9a349211d4172a2fcb7a135ad940c4bf579667685833b21b7232b818ce2a40d4a14b28eabd8feed6016181c591de5a569e3b663338b9c710649bc7fcc5451785cbf6c2888fc5e7cf992ec049c46bbfbc20f7b4da3df1cfb59f48d8e24eee95597c77a18243544a693010cd2a0b2209a260d6d7d5ecf8d86a57b54fd16a5aab3908fa9f4c4da42a0c4f686dc08dadd5ca536a80213cda1fb230ba45b45f3d6d590b17f6844f54132e6e8c422be287117d35c12ad0707c6daa0cbb0fa039ba168621c78f91b65f48bf23af0c84493c77edc132e1a335e2e15fc3830b90df5d1029c08afb86703d46b1b4e018b9234a54cb76eb906f2b50a414e68b59d44a59d6b1cecde5163684933361055e51337372e239c0f94940ac4a44cbb780594d3419df9a896e271bd2e2306415317278e1bf7ab91ada048ed232065b9df3379ff9cde44a16 +expected_result = pass +expected_shared_secret = 96e30641ea4280168da37291a3063342ced8e77b33b5415819938c0bd7264ffc + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +private_key = 09d0009aa9878c697e2eac9cec9675a9570660346547d7aa8d4548e3aa917e238cbbc10c389445d15714b237566cb44132d6983c9610e779570b74482d5ba2742a1bb51c68142c1680b800f1938795367b6d8a56c32a0d77922c78116643530aac01cfb2692f4bd6bbde615a3335b397487db8a1175a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988766114a80b1979118eca08217540f032966688c99feaba06d0a0a1e701deaacbcff9c2f2948a209ac8ee505c85fe0444b5c70d067100b63cbd6d98f9aab73cb06c97ff31d7aa0ce188707ddc5c07d495b27957b369055650abd5d9b9f75761770920dd0b574a5841c3bbc9f6f1ab0179c118c7a83b2934e950b3dc732c84264c66fcb0df78975fcab5feaba4e6af97131696a0cda1cc9e2c40a266fbe6667c1abb361f063103311a792b95cc525ff872bf3f394ffb48b30b334ca02bb32a901e3478f811505da066de6a5caba425df83c27565ca48b16bb2855a797a72dfd57615d5117b24374c2d306473a349521a8107790d268ac6b5813c593cb9e8621f8c68fd2e8082c491c95c5ac74c86dd37b0a4ea0cb66aa576af50fbdb0a31235bdc9e8107f1859acd2674fc72c6669a3465556f90269cc30b0a8f53563378ee016a7abcb5460d5371b01754bd7373c2314e2a42d98636112f3cbe0638e513b38d4850afd6a1d3d485308181febd88b75f532e4541965e0bc592885fd1c1b3108c33f74725850617b526ad4f2c8cecc19b0a0ade15057c90ab086c26cb014bff92988903bafefa3c4c96ccbcef178f988a40d339db324257de69a119125c52a4147360b1274808299446ee768680170457acef18814559996fa96b418275e031199e0d578e86c946381c369ab839b1a75e9d6845c98aeca24253b3b0f00ec7e92cc6f6a40a4d8b04900ca3e78cc7a5c51886e0901a908bf0a08947e3b524f1c606b055451ab6eda2bbcf832510b3075e2cb0ecd493b71102f4ec69565f96651a3a2c3b738c2d55805798253e055dc8508b98822e6803785130d22e494b50025b0ccbc69667013c4ce4a140c2e9ba928d41d7fb5237da8c5ac0310ef5007b2b0c6737bc17a747c5a2c1f3c1166bc2b0ad7aaab1d870e54694c1ca293665286c4eaa35d34bd6ea7aacea04871c257cf63641264aaa0db4f65337274356f71d02310a57e44d23ec6b4185bc5cb45a65d3b592af3138216332060264a6e53702d766d0f4a0f14f70b75b780688591cc414283a59ad2f84d665354d71c2aaa1c278ab6c8ba902283b286f82761906c9b2796595bf5ac01455ed2b43607207a30c949afb1ba5c50659143c98237279003ca820b4b5963b0882a088ce09c99f4a6368971a7d6885237bce28580e2ec483fa305fffc0aca173a89cc41727a55d4e29a8c410b3fe851b3d58b58c31920759ada529da162cce47618b2f715f3658d71f5455365c67b04748b371a5a96b75f342cc4c031c713c04d2b6cdec0cc92b7596bf4a2a0c91537a0c8174b3456489d2db70d3af2995c4830245120e9411e92ecb2293700973386983a0c6591cd5eaa34d5cc00fd672d20a604e78696d5542646c120e02c8dc5162630e71465accbc55170fe0945513748c0ecc9098a02e9d51e44acc267272633645ad562816d479466b54d2150afb682b4f32265f1f4bced21caf7c7980105b08056cc4192bfe0da9aa5e00864b0a34712204cf6ae82dbad360a7c840b4804826c39a59ae029056c1b2542b6a589eb47c14a70acd1731bb0a4d657656915b91d696b2f92afd82245945c7b77958a5b6a3b6cbb179ab83a0f32591b757e8b68368d6a5ee63490604aae70ea7fb4619c91a455429a6b195214bd28bc717385d3cb8235991c05088c7939bf852125dafc3bc368479165438092b530bb2b869246988b8f85425a2a523ed108c6d2f54358580944d64d801078a4b621f58012f9d8a17a92ab8ad43821e24e2f87bfa844abd0c6b08650ab76d5397f2cb0060b31af689fc8612249d46374848f496b360e733fc991809da804dcbab14030a4bd18cfe37b41cad91a66a263437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524c616babd17a8dc7924f37345dcc32de04273c5a0ac038a133ba01ce2481ffb57ba153826a7cc4123570293c82082b6a75fa05031cc7fdbb9031e10ca94aa283aa26eb3546f894b646b9a85afc5df3b513db522efb340287c64492aaaac5fc25547129b56b9541eb0912222c2e60a11b9304692a749bb174cb47679cc294253b0f768a7872f698c23493fd908c9ff95f9275551b947bfe84780f86c1e0bc105f6cb7c9430369b58bbb07b3b0c87d8541618c76a43d52c98a08166e052b4487177ad222e6a002f7fa3f3601cf1ef0b4c02ab550d76447eaa695561118a46301b544b493c368b5b77ab17c5af4543fa6a8c682a46af39ca48046b1529684a53d0e492e1b8596f55334ade15591dbc4b411537c88a5113458f187a6d77278675b0c85bb017416b6e9543fa1b924b631ac1ddc5556127548fa8ce0c90125139bdf13428e2c7805607a44251a5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343dcb062ea3a039e949a7f151c8900484368f1cfa385bd13cf55685bfa4b959f8634ed7c437fc9c044b401683cc7482722c98583de24ead414c1833858be987672c557db87aefe4ce2db8a676d14083462db35862dc0cae95f88ec1f59426fa2e24e9cfc54813be07c98f78a87b9703276b455e15474d7a283d5738d4b639369077e7790dead3336e1467c871a571080004a91162fcc31d2912646a9406902248fbbf28dac4343b081c327743335b9efa4b7fd13d5177064a5b6e8065b64d8c6580b47e6472c8f5139268145ba7a23a02f59acf680692b20ec2dcc087a99be036bf7e9c8c0df15f168c508ae28e33d951740a9b0f0321e35cc01328b7ba860592b566cb369b21f51b7ae583d26652da729f07f5b8d59caec65aae42c7c9cbe73c68504f26670bedc542fbdc67a95c9f2da1a08e559797170ee63147a4688c8e101e5aab48a4d1862506cfcd297c7ea61a9ed4a54fd3a28380292fc1570fa2ae43920b0e940675b60534425c69f35bba714c88b3a6c323090b4c56b7f89963059f8ccb0994373fc1344412f694175c2eabea110e035bee6abf546396d79472eeda164bf49350f54c2e75754f502de4a42721b37974a8266c49b57c6837b38a28ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd2429b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 39afaab7974b00311d124330c72214db54b573bcd9fc3efbe3cdc82b4b680c4699ff19c1af2b0ba0fd7a2ca1016de5fc566a098d40dabe6c09cced8fc3466bddf7fd4166bf9f69dc4f8dd8baedddafa1c07371f85cee047165b030a99897eed64b7bf34f427ef1fb5ffa56fc4150dfcaa480385b86e215c116de9636b59cfb5c1485c1364bd6ee0c12d471d219701d78d470ca7b6d16d9bba3fd0610611fb7e0d13acff438b6ab4644a1d97814f2563d7159f7b11f632c3f5cdea5dcd4047a9084515441b5e16f22098b6d943cbcb71f705ea675544193fcf2c8b0f0457735840bbebaba9d6dcdacab820de3ea579e8ccad0d59ca19fc1f70578730254ba58fd00235e77dd346c92f4916d7bacdf6597232d18beabe0f7b4f8f916d661094066060b9a0383170758e3f5b2fe0adefa80a2c7b553f03f83d465a1cf090ea5f5d04410f620e509f9b7c81dd0dde465e4c52afcce12f5ffe58506162e888afa1ed8700741ec4d424fc46e1c7baa9d7da6a450019be4522f23088a239ef39d0ce1e3e46a8d7d6dee09450b06dbdd701cf9ca5b920bca236d0ff8d2932acc4b590b16fd314c8fc466809c06c7066dbe7e4716d32cc40d48dbd3a74820ee85b0e8f200b375ae5729b8a708ea902780ad6ade4ab87f8dcde5e9552dafd56599ebedda9e43a220b209932227210b744b7676098cc1a9fca1a325f28c6537d56e6ea922c6a9ccc48ec1fab814631b8eb8d5dc466f6b2d7f5a48a5dd3cc42880751cdf7b6649cb662bb973b0e0b88c95d8de90571989ed9e2ed115bf7f7bfc4caccf262247e90a7f63febc66218525f255329c75e957a6cd8650583560605faaa84676225cd42580e1a24fe7f3cbca951812762adbd5fc514bf094ddf9fefa94c72e22ace942ed493ef021a87d5a794f4c27ba5cf6c06408f79cddc81b21d416eeb01982120e77ea036b11eb2aa6f16ef380a90051a543e45d3aae0b313be0a9332b71db12dfafeb0128623553d69a30b967ee7894e54bc39131c376e73d2b947f0d06d3b5d35bbca914c8896a683ca39947247747def3ade0ee5a4049fbcc26989f792309fe1793becff2235de7434a83c6cb7e5519f8a7c67970d5acc472d3303dbef8fe7491c949cb8155614b692f17cc0ee844f7f0c3b2b538a70d9f3b8e9c698a77753616721c4a26ca766df1af04c8011472166ec8acde6ae95f002005dcbb5ff0f2d6db1eb3b49c258a23c9dc052e8d44a6fe08515537bf5175b7618882703160c285207b64d55c1f9563f50cdb151f4dcc5918f6d34c345160fc405931dd97f7e3403f5117a84a16c17077f6e13119bb5fed5cf8f128c50b46e81105879408ea5a90a128e2bcfd54c3c091633dfd9cc48be1e492d2615b8c3766730b7a9484ede6d646d3c45a09b52e3180c8b281595a97ed66c0ec03b66aa3a364926ebacb166b7699f7dc56f3606538db5128bb8b408c8fea3cf2ab0903fdfcdf5416c8623cc5a700995be6f0bec2ab7283df510d95f6ba323bac70fc058567daed0a06f1cc81 +expected_result = pass +expected_shared_secret = 47e54c85cc0e2503629a8bfdcfe038c3cf692d723d462bab733c7c8e0aa37b02 + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +private_key = 96d9c668915384c2847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef7f405c2911777fb1e2f44721be8cc326a80e524486a16a083527e22d51e4ef624b02625fd6a857bea2c0590a3a4e39f0e041b7284bcc501201842345ed5ceb097a5a5f730ee53176f8acbf9e03c6dc4a069718dd64c47e1d17323d29acc630db2da9922804802cc768070245380cec6672f6a5a9d14e4012bb13caf8c320a320ed63b0591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718a421d3c45bd0426a87589362e52953822cf785802b2c6aa441adaef93dc6451ac68a9867c9b9703abedcaa540146ba6dd8acf7dc317a82a4c1396267032fccb53be9306e20e4713b82842e03b7fa984e5827c441e293352b2e2a51566eaca8d9c4206000655f761729020f7ff9b230d6c4b986bc94551175a8acc7e2a2c174c500666d3cf021a9b40f1a465447291f920865ad16240309b5c838a2ddc5beb8aa11bf987aa9d7c082e8c55c63ab01d0664e545e505b4aae50606136b6b01499a5ba10174852224ac6bd242d5d21758c4342f9a02a3d46a9a845112adccbb73488cfe3055cac398b0245c467b94eb342e1845969d70511bc7100f886308cbf21c13840bc17626ac93dfcc4eb22ba18f62b15b521539901166598f25555c32587637a341017885af1a6d1841aa1c747d918253e1c873c2ccf292bad45805d8946b00dd23cbda03878f66357d175d67a1b743c1e5428ce90661067011874b062e9ac8a0f726b55b76627c53338549c3f2605840a11d5606acd104bfadcb51253af718835826628235878d6160f15033844d76ae946ae6c240053c2ad6c3a3d72e721d9565a6c79b56840cc5a878c6a4033bb9c88dc43b130348082e41c269cc0d3b05ffe356b5695bb01c95f8aa9c30e50cf31f11419e13acffc7192b75948e06a68458db80a8f71573b6edc1513aa5b060cb77b12c62761bc188159a49c95180249b3e35c3100635012637cb9cf17ca9936787aac954bcfc655aec8b4215861a7709f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61e6018ab30146d60a6563b2f980acf66186fee70a458750cc62c433e651f447ccef8a773bb2731a866832ae535f0d82e605371f6b35fd6fc1188a52080c609bdd8748c321ca37190321b286c849d35224bb5107d83e2827ef0c63859133852630b237247aa8c100678e43618289239ef19c99aa6b9156704643285bec89f0b0c21f3a091e2063e5d3029f52c33af97529e701298d3961f492e6b731d4e2064d034533f4611fefb64f1899ef563ad71a52e20b199f0d80c557cc8cedba3cd1746d3a6ac2e697637f08a43d681ece3769c8980c76a26adcc585eb1194d28ab163aba5563a5c7985720248662bbc21470022ef4110b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53a020928f7a55981b520017bc06b36d10a21433797c15124e0892a81230bd6bb4774d46f73b874602588d3f8966469194041bdee87ac54059458b19724949e7998ae8018755d491bffda76a70a64eff902a4281734a7484037c739b7bf71b658b779cf6370420d2073fb820bea1b1df29c3b12c54ed3b1cdafcac7f6d08082da095a7658b3a45f7bf717d4b80a3a050a04cb23e01103ffb1731b2c35a9dc23c4341976b188f5226459a02d348bc9d2064d574040147b41612914cfc2954e4190905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca662024335a083911aa53828d6d79c948425422c32ec471c2fa843b54f6731fc401475612a135aae4b146fa829871c0654c075dce41190483c3ef60b7336200a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0d402147a08a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb3f184d7d6ac6ef64cdfb89d1ce66a059a4659d8137dfb3c95cbc9e8d86e064cbfdfa50c68130a8d82258407bb7b926f7a802b53209f3ab78784102e88fb91e6311d496251f7b574aee5797e881ba1db16af40281586267d826c0f33a0518c26e6533e19ea0ebf29474a131d882a189ac03b835c16c34c9ae7a1c4d9f5159f85b8542284e0409dfb0876fa6488e6519867b5c53896867772210e95399a1733d2e78532b7651ca9704ac063df086cae4aaf65150093f27054f34e2849449c7680ef1ca1a0ac399a01a9b74484a967592ce85086230582518414c247bb7680abfc2a04a35a20a851b73548a8e4cfc2b84cb5ec24108396c28498a6614790d56bf8d1b9f9e40bf574c497218eebc06217c9bd361baa5d0715e666c2d3d299346a79be0bbe4b7ccd49f948a60438514129c126aa1f3875718922c5124728f09fe5437ae83194ddeb81f0d744fd2b9b59fc223e2792501b4932924facc16c1e5444dbd6a823016b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c59910628c8ca22b1138d884842c387b594b544e5d99784b06acc3b5d80ba81cd34739a20af11f7735d645d9ff25c07f8af9b5902524a1953ca2a58d6b796e3695a006ad6c703dd161c12c01b9bc995773c5d2ce59470c765c3f5401cc07885c77bfb3c15d7f766f0ec7cb3f601dbfc210d599093a21c87d82002212b06898a5a878d4ee913eb451dce14a1bc424838d4797ed14d9eea2473b304d6624f1725c820751a9d313cbdc79ac9a26548587fb41371c5f48a4da04d37ab7189685aaa054853f0491a0388ae4b7af4259969e29eaaa2b2eb9503518c7c53ba0e6bd20ea8355a63f1c481eb5e662a0b792014ae4c0981274d902759af794338072a839b05d9d42c1ebb1a3da33b54066d1a63024a3b1d1437b37a83bbe816075cf416275a6f58336905937105e63a1a017f87911cf0b41daa41a5dae3856a606e2a9333176628198b49d2517f54a9182e4ba877760517dc94a079538822251204b4c4a2382cc7889bf84923c09072f86bd1c5879ecc3a37678e6d031568c24012578dde5ca01005b2df71a4a0b0455a03afbe7c366bf1b086973038fb5debd793a303b4c867b611772733f66574cb0d7c303563c389b2f1b46e98945a94b142b2b0d647521f4b58f12326fd86286a448909191bc600bc7578b0169a45c071c77f280c583788f9c2aa1200a73431ad56d23b20471bb67a627a594ba9922b1ffb75d2d030432a954c71235a9278857c3010a8a8906c070b77060fb831842140770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcab990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = 6a97fb0d3fc17256c88c551781f6f142a05547fb8d0d96cdb0242069d0aac67f102232efd259c853d4a5222e4d8b9e5cfd7028afa9de9c3777669fa77bef10515be69536e6dba285206b1a924690cc8882178f04702dbbd541a38dd036ff8e6d81253e7e902c6de5151c04eb29236b261b30cce838b8748c3da04e524f3c71f8344235adaf16b54bfdca539be81daee0c2640a03e69f55f974e8573af1f42813fc32f99f31bd1d462324dcbefa61641e6eb2277a143ba321f3524307976d26ee122a758c330c80c91fcf5c7a7a5709401607f723c3386cf8314cef0c14a69b6868f117811a7c3caddf1935fa2dd230381eb62d1564072f6d3e68d4ad87e4fd2915d2fb80ab2f6f3b18e853dbf0d06a057f930aa61898f1b04148f5387ed19d6c2c36669ec31cce3974dc0717a188f1d2e37cc31de7b15b7d0712d33ff646b11b724b12509ba41735a771c6ccebbea8da3e651cf795c2131f910689f11a2b6a241ddd4b71605d794ac24778e2ce1d47566f8f68d22251b265fb0dd9ba211acd4652b509a6b412536f4348a0cc95a7c8bf736ab2b2a9870bb7e75af32e6b6ca5d318c5ab752234ee9e09f3deef5e0bc52fd7c8dab5c2e965b41397413b063829f194e9fc8d9a92f0dec9619d6d6aa8bb368a5a80167a4511225fd88145be368f210e1dec5cf94f28e1399a53612fd7d4003eef30a0106975c1d198a97055e9e44aaea6f9d21056ed983b54524eb706b89d7cdb6372dec8adb8217a214bc29f02e236530f56daf7966b31997ec4201be6d776880a5b0cd7a8784eba3517c2e7613c53c1ae23e5b1fe3d2f95ad0ef951e06e5a249d8225d48e70dbb406731ae18e404d4bdc2d7e10c43e62b7b18b7308b4effac86680f6a84bcfed751ab5d3d68f093800c1bc243a28ff898c66d3636820db810bb7b5b92087221b2afe6bd8e953694f87c38ea2c59c151929ac831b120c66de1fb05cc39a9b57ab491a7762dfb8ccebbe3194a993b4867c4d336a04351b30ec4d2f0370440acb6bdadad12e4d3db51e701aa49c455296e15b9d13cfa68340915d2f694b8b67b0f34d275867c3a53b6215dcb0c3654e6c77663524301d1e828a0ceaf7d2cc226da11d1cd78b072ac7f3ee14d2b06f8cbb9560c6d7e60dd95ea5d402b5de9e7b96b64c4accb8eece2a4bde33e8d27859d6fa6ff7b609ab159d1201df7734d4c73ad0a4eed2d80f24b8638273e9c0e53ec0b8272ed6fb82a6ec30ae431972f929759d000e4e5b801189473cc3ea318f07dc495b7b9eb7afda03f7e470345c9095bbfc00bd0321eb5498991c75d29731df41db55e24890e4beb84d5bd6666347a53f2dedc5c6480a93b19df229b8d7ee732e02c62db28623fb11c24b2de9d2ab0707e4c174acdc7b1ee8e287b62d1d797a3accf53decd3ec40fb57e571d129f1a7a70da324d094e51cdfe1a648650670736e0da6aaed753822e5bde4a2b69cd0c05a875b5f75148a6a65ff26c670d17a0fb598bff1643ba62d03c2bf9d1ac3d33c044a0348b762f95dcd +expected_result = pass +expected_shared_secret = 8569bd042465a2c4af628425cb102b15ed4f5feee16090e2234f3a884a0fa938 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +private_key = b1c127d24808fb2b9922332832131c4fd67fe8a1a070ac8d17100bf9f6291efa0bc8114d98f65c8f4abac3ab17b4241deccc37688b881bcb68503b54379838bbc100b5bab306327e7965b694644c470a5148666c7fa89872d39aff60bc533c83f280abfbc26f073331ef40b694ab25feea5b2f55196798b70681caa21537dfb5746c66129775852e5850f57c2db2e8a0e90530a57b387b1c429101d04096c3e0bb6e9af19f83b1b0b74c47bac678b0f2269798573fbca5d8e687965b13e495827adba63da8a17564a3e68037b3a4991993401c1c6b149895ffbc03760c13595035a713140eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685205b08d44a3ac8f8948f2b7bed9cace27ab6265722d8f2950e0c9ade053a4c4ca8e3f80a907a39e33db78e6065fe9dc050a5a730595ae5ea32e38c512edb79dcf345f1d9c238a1732c552ab8db2ccccd11822972896b323cc43aa03633617f82e89d63d4a1003cf9c5ce3379b1d53a63eac57adbc91510316acdc30fd74a1a2e6c23584ad1cb28444f9231661079b0913e20b3278d8a2e8b18556f336cb750694066b6c82c5d267a903b624cd440d8e187d9e438d178c8394706f016b835e1522ab6904f80cc24358b7dd3bb271039acc174164021e8a522fac473054d5b4cb3bc64bb107c6b637cd6360e312a85a3b1e3d2b64436a87e81016acb763a23ca9b7463023148b0c4888bfb18d9441841f723b9436b77b09c79fc714385a3ae97b5bde0a2a0c541dcd2b668c696281389ec270bc6d088fc42506cec85bcb4b611342af0a61b1b9d75e0df43be293cee6eb0413363716ebbc48ec6c361a48b9d871bd5742fef2ab286094a92b508cb794f2f69a8ee15c2d748d8fca8cd2284719815e75b3b0df76298e48280bf530e09a34d166cd5379777d472f0994ba8e5629ea7691fb973f45869635b61b277c375606b911aa1228271c85b047942a52187bb231412b50f5be423476720240e62b9d3cfc5b7af5ce9fb38e03349063741ade945e994a2d6492a92b1250880318b9b9ce845ba29bd3733228ae960663050888bb98a0fdc21d6fb34cfb5c1af6d9b98ed6ae454c09b89b6067401fb30a17dd331a845c713715b5bd4a087bbc14cbbc9d2ea83d0f9b0d56d939d01b7d590b3082d2405a20724e2c44b5123bc1407b11da3de5889ac52b7b7821c4af1303d3959eef3888b8847f3e0695b5b844e8e3c221718a25057e707a50e0159af4462bb1d103b9057ff7fbc1740bae1afa44138aa2b7e3270cf80a6ac745cf701040c97253133ea195648e929e6c6394940b6eceb18844f1c862da6597a46f64e0cb5d2803eaba4a08110a011a32452185a6425d9d44b43463893369514957592f519c22d2b06bdc762c519d5cb84e9a68456ac60aeae85ac6453de2bcc103e32dd509309fdc08e3b3698a193d83d62df74719703bb5f8cc5db7b88b80110d74d6949d00469b840ff7fabdd4c0cec1a097a6117c28046b06b82c8ee8204296428ab703840acf7f3333d742726b114d3292b3154b2c4095b6d465657ec0780c488a0c60443717109363c45777271955135e60b46104bc18bac09a18690b37c8078a22645532112b1dd09313b9a25b7094700639775f89b8d0314eef0186adf7ceabac36cc9292c270717f27caea51b1afe1cfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad4841b229fb7a17bc213b969935c672d0993a94ec170bdc8b7c800e66bc6514f84fbc81c7d1c9417b79a82e5b3980acc792a19c46d13a2e75a3af791beb401f7555793d94c0ee1b9e98a5b6c52777e537bfb287268ca9524a4438ad87a0e85279e474c5be7740b7867d8b04781a2436a8d343f62274e236c736dc3c59d5b326563b9c86798ab14a6c9a0e67b36db89a82af690da7016418ba2d6c435e39095bb81a0e49c01a73a31ec9159844d1a3eb233d16b932919421e6a342473a71de629477183e8f34b2b7c8abb7a3b6e516107cb5229d780b93417f9bc94c38bcaa58f34dd88835308c742875cccf4928122199cd932148f48a94c5c2252295890bb4645761d3c2c0f33ab3e1021aa56b573e9c6fdac37c83f678b97148ce573a244b0487f3cf771bc7b6a13fe53a6ba58854b87a67a6a17d6a301c85f7c061071b4ddb27b3f404dc402ebacb8254a0568d48b2d299bd831188886a65aea5cd8d987f6017a2f4392f455c2b4f9b63e6cc1a27ea38f2588b0f8086d7a5c5e4b05b76d2b8918820cb8851704ca6d730861b512fefb0a76b61401e23b01ea710c5e3b73fa716dfa6408a635423c61372592dbf174d6d811eef7c4d885bca5fe669233a141e43810ad10235cb59f824728bd7acf17765bcd354a493aa60438f07d266d728b640cb07d50275bc2605fa6c964614b2c8143b37b184f3c30668662149bc18c6038706c12f0d31b896b69a7d588d0004497e4808d8c12253987f000168ea758a5b32c195f03f23a07c5a546a6607084cf79e073bc6cc1cb372e385ca827c490a42d900035bf735c6242031b8332bc57765ecce4792706f1cba0c7cc390e7bd3595ab876c4e397c58fc325c9607b0ee39692c31730eb4744e967e7ff8139fd1a545622ec870516b2925628ba782cac845b2429c3cc0ebf7747f414e8d35cd4a91c959d2276404a5df4790f4363104e6a0d1d60a48b65bbd92b417b51a5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3c31637e14c5c0279cdd6386e20ca89a53671fb2f04249565491ac2f900ad380d1a68b67693b185f26a232aa1b43503398002085713ca4b2f94cbcf6e837b020404b7f519a2b520f93b901943c918393f26061346a0193ce9ba8a48b5c4b01b0efa231eba0528c5b38cd32cd5d22586494734fa746b411759303a51a12ec58b03fc99a1edfb1cb01375032054878a6ec9dc4425945aae387e7fc6cd399c90049854cf51b3db690eb78a0a2db04d05102dacaa9834620aba427b5733bf1d1693643c88bd265af0280ecc66344b81129c491b3998c6c70ccf03257c2d06115b72aec35b4c8774cc7936c578b29fb3b0a5c66709363b73f41b08db919cbe57ad817cbb5df62b7836af6ff4ab8cbb07c9fcb7e3d601b2117e6a7242abb24ea96ca867b597e9e9b45c01aba9b54d2d323df8b38d3d37b72c2790e1041037355f274cceac2714a92955b31c55d4903a85bca55b2bc22c536aab22557d912fe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 1bd710a00c224ca78beb7e27c43a7541a1618fa3dc2615317cc4aa233e6169785f2b722e6e1c73d77d8ed134a6d56e3cebde5fd64b5a7b6030bdfa7a9c95960ff5d2c0cde027a437f272311bf4e79c00be9b0700aedc165d911ce9e3b7c75d9b4c6230e734c9d1d6b9a835da5d666cdc8c129f4cfa5b640bea9c1da52aecd5272e65d80f1e53d261cf0913ba405eb4019e0f9a54e99239fd8e247ab5db67d062cb3cad1d6e2ec8c0c8f13bf2db8a1596e16966e68454c10b9fa416441d15113da81165f2813a727b7a6b3f598311405b7051532dec40035ad088a5c598e104ef624a06a98f58f28f7fd22ad53d6b54d26449fb289d0fb6c42e6f5039eaab0fd650b627c62a57228119920435aa41190d51418896932e338c9dde3b0e532fdeffd03551d0e039940134695412f2e81a99c73094fbbf9b03335155ab2ed25f0a96d73fdc08b04fbc32a2e5486110997f25a7308d33aa8c051d3e6aa887b7fc5294ce8c4a91812c41fa6160e37f928d9e6e10ad719f3dd7ae18f6444b9645991a1ae8e2d7f284a96e652a7f40d7f132e681f6da4f4041ed9ce41de22f879ed09fb765bccd340345095642a07bbfb8d8d1854c1107200e0288da6790603dff76906b44365c16a3d05e5de2a22c3414ae3e2033218e918edd9b1c3275927df7e771d7b5b1c5e07953f3a30da668b3ed6d408b709791fd5ede9328561ec40123606673a22d496e6ddf6e5ee838a47528f44efbeb9718e4872fc6c63d8c9860ba2c1689958b77cbe94057b6779021b039e4c18de0b75702b2d9c7123a2e281b979b22d1e476e6941b82786355ebb6a76f8ead17349c1e5d779b494d0b7e0153e56e967cd4f5cc5b0f136cbfa965d323998ebfb73ab2563a62bd222f9d4113c16accce74ea94468e0d721fa7f5019c1f9d31439560a5bd93a071f696dec1d0f52f4d671767cf4e25cfc46f4eb5f6d67fa40951ba31ee8aff31eca1a7787c90a4ac7667bcdd66a220e2c69df7b7ec49f7d6d8558da91c4a05dfea6da06d774a420ada78866c2d5cdcf526dcd2738a27fbf2df61322fa7e8964da5b634c7bf19985dfe77a1e0683844b101242b641e7d0913b37bbf9d3f2bf3519c8ce95e917126a7f72a8c49daf48d4bbe37e9cccc9ee4fec24f47bb2bcf661e6c0dc9b2b1753d929430cf923117990e0f22b43a74854a2b3fa62d3618faee0b877061317128ec4553f74bef2633d847141ae3b0b2dae44605b97fd159532cfec972103342b21e6edbfa9f03f483a67c45cfa31d338a668870a26b34023004ddb2246dcecaebdb2305aa4b178c4ed57fb0e1b33fbe37f3246be553b68c240ae8e54b7d36fa4bdd0a0f7602745e2885c7a85832320815eecd846a08c0974a2a35542373092dcc4f7fbeaf61092c43b25616a876ff66d9a2f458955056972c5a7460a4ba22fbf65680ada0d1c9664e5747740c4fe921e2c5671d9c6e30374217578c769c3a8f089c5ccc9f3d19eea5389db458ca87f03087006cefa7f3669753fe6fb712073d267d18bffe82 +expected_result = pass +expected_shared_secret = c184e0b019c2db772e2c1ca6f97f47478d99cf0c4c5ae1406f51d15815022123 + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +private_key = eeeb8866b17cda12a45fcc6f9d05afd103835147647a7301ee071366398473c8103ab3b064e340f4f9866190acede02473fb49635bc38debcff0f34c5175ae0ec025aaf19cccd46d658c2a6ba62b50d1452b09c21b430ee9a3ce05d36a8e1aab2bf0185f35664b4999cc8c0df049c01056af6aacb025708c184534f1172b28fcc94aac2fb7012e20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c7f710f51003777b060f8db5fe06c3520d35e97f6b5792b0ac3304349387b637686cac1a6e45149173041fd7c3cfff5a398ba832dba04dd7179d0768122a701f4e0bfa48149ff140e2978a723fb985b939458b081e1068ee5102e5f540365e6accbb8c28db84125b21e8d04622412c2f075cb57019eb828616caa245a8b099a01bd86268cf491823e440e984335af59924fac1d43263af725895c717e827532d35c7da9ac1420b46aef13c9f33a427bb5a1bc646f7b54a21760527d303bacb2a21aa39c5577bcd5f416f126741fba9c2cf9401ec20a14e9a7bb927cc8135bbb0c3180696093289f4b19539c58655b8698a5d1339c9490be7c04ad3311fd422045a5027b203407cb5755462c21ac51f523389e803f30e12fa9c0aa7b4a1fdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd3208fb6f28661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5bb222e7aaaf9e9149afd11ea5e86990913d2b543913942d148639d9815d4a8908362a84bfb6ad20b8acf9596df4187009e7b773070450010744712f9e7a9b8e9624e3e2b1d6140a9e4789775abcbd2657aa487740314ea1e446db5c09746accaee29783b23ebfb255ba5c9706f1254703c676ea09801762e9fa45d858732ae7218b37107b3708eaba05d2c035fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e55c05e6b5041552c17dd223af273cbbf65a44b4b6dabd51b341464a9993effd671481592c5a655d116b963975006b13503baae38332248f58656620098f42f97a813dfc7b4df880e5e783af5d833b89079474040ac05a6a7ec5e9ec1bdb282443c736514514f1cb7455958608a62503428464d89c66b209c417445416a54aa66234b1a5bf1c0c3f7064b6d0a7243e170b6acb01c033c5b1670a3ba6801024c03b24cc1786025fbc56bf04f3b241e4be701c9764938695bea4316adb6abacfb44f2041d2c29bb867379374b211e990f194b872a7b684a212dc179a4add943aabb1e6beb93f5cb100fe342d0781aa80989406571d1b79d08e31ae15b81740a22df02270f920ebfaa3c9d74392cd64e71f363df221134e9be32b6b855fb76e15b5c91cc6c3f750aeed71071a0803987ca7f35882ac31413a6001a6023c0a183961722b6ebba16f5577d95bea2c5ab446ac8e57acc96281a07599a8d335c2c12388bb0cb9f8633cd2251c8a7563b396072d0cf6e7b8e3af2192e5731341214c30708e128914c124973e759d4221f1735386b874905220c41fc731a22b9c665cef0cc5353b799399905f0acb549f13c6fa56fae2907d0353ff2054accec40310a2c4b62aac3f392b014ba88fc90eb868693eac83516336baa601f600518fc820bc8b0e76c66dbf001bfa28b07e21adc142c75111b9785aa2109a795ab792de4cb7b6298a504200f8850d32cc44e54182761a1c9c9ba591a9fa6873a61025515b068099bb1e63751c5b887d283077f86b733e4344d13310ce12d22322f254a0e92779a87067d19c53c70dbb927e14e1f2892b5273949428eb4c70c49da8aa7fb87048961db4892a6f89f18f0bb69347b9575025a964047ac7bd2c7472838383a6072f8338b23aa07d6b7b221e18d4e3c62641916106694315a2fc5bb88c6d664667680df556c3c046398a88328421f32ecb758bc64cf246815a25922021dcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532dcd138a4c03e2ff5024c52bb486ba7665b27610b822975c412331ed6c98e66721daa1897936371113a4f17d96ea735a5cdc019809c3907c03fa950c00eba9dffc69a902151a39163f2931e1c0271d491562e0a87fdf7b7846c31151017ef08727dfb68f22a8585295659ea358cc1b85c9ab4d107413225b8259804b31850eb347e1fd37f5435617a7a07b15321cc204b1a6b7c30d67e91c088a458bef5cb704e6b662189a9c0079e224a94e21502c0f1a4dff6028ef6645cba38c0c86eaf673e9b2613620bc216914a9781645fc48e33cb9ea06182637439f1d1a19fa50cfd3b5e2cb8310229b74ecbaead4b079d535521b8587a2995fa9b8c6694be6e432343c97c16ca23bf53883e23cc38f10c38e54f5639b9fc0943a4f41cd0acc8db40cb12e644cb74b9d4b858f7d6767830b92381a42368476cf2602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859902d19822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a459c0764cd943e0b6a5b61b8358530459685e2842ae9ab867fa712172207e692a7affa872323779087547c3d8b89f368ce078acecd55aafd5305371a5bef24fb255211b2169f4543927c845a3049f7a88513a682303960c2d12bc277656f15738c4368deb70cff2a32a1d179f4fdca57812cedb21b356e0aa63270788b510e58b4bf613473fe931dc80a9cb8bafe63aaac3913936c8a939c413cca10a1277409250b5da321ee5c24ad3d093c1c7095fba34b81380e5da561bc039e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d1a08127db4cea30340b5589b2327988c97b78f003d1315dacb301520a11f9f0b4fb33ce7c0203ff11c6a66136c0aab83928c145f4b968783b131281f2153925dc13ad133fcc5247b595cef0f03ff0da0a429c0de9a54f66c03f1a616c7210b7ed3624fdd27e99f38472867a9283c6b294b0d7014cf9eb62f0d7b051b190f093450453c056081370b45f5ebc4c03808fbb5c6d8b659bd22612c2872de9034b11c6aa6d356b2baccea0f909da0c775969c12fd5bb0c8a9bed5172a9358e01c29d308636b5d668f5b2c9def1380ba23b5c84259d887d3dc4882702b41d99c72c800dd5b19935d7722610741a105c1d227c38c5665cd5a6daaa991a9868499830c1697fa430bf4f95b03004126fac283a167281e4b847eba8487b0032914edb0b67b1e320c25bab50499378115cb07a9000e0156c9c93c1d90693b9c22623a3eb15618fa1c470481c4cf292b7462410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa09bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd381c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = 56faf8ba810d4962b71cf915ffbb0c4dc4fadbcedfb4d7778d70d364c15a803aa91866c8b086db348f84680b08f13c45d0b154b68e5b355b43e277a6457b3d304f01b5dad75324aeac512ab2aa2864129a10fb287e12fba81843ee33def6c12dd9e4b29c170592a907d3350850a55addcbe92affc8515287f73e4fca3199e536d0c2e2b74dd92ce862c3f302621689d666b8dee9fcf90b4721818cefc3776f9b1195cefebc7a45d6088b3b588ce4275d32685d1c06f0065079c8a73dd8d8e7120907a141f189ffd63b2b7568975a21c90b0cc69f2120bc94e5ed04b8c3628aa1fc7d494a2b8119f939afab0e5e99ad377661b04e85ba80a62e7468ac3e90e4dbd11c196fa678d3246d69928a20e4b9d6bb0c3fda5d33b4ee8b8e8e7c651bde38a9918f9131f60f4ec5b5c340ae3e64b39a1c507b77ced606ef9b93246a204dcc5363ab0302726bc94daad4214807f33103c7a7c57b460f432b8556b54953e6beab1a116b6b73d38bf54758e65a236ba13f10c8abb4345f336660b215d9e43209f8b85363342a930d8d9f229765258bea0d520d6d9710149b26cbbb1929fee006a63de21194cfb90c32deb5c402743c4d6643548e82071ecfe64e6d0a5f333bbfc7eec513a7e4bb5f16f563de4f45df83d220b8df76ef10c750b90f48e18a9fb7727dd64093dfe9fb6c381f7e19189200a53efd6e1d4d534bd3ceebbd3021e9410485465adae7340cb599a987f6792d9c8d675a12debdc06bff40572eab9ba1d405204b6fb7f87c5fedd49603bc743082cb3752e8893ae720668481487e86160d590422f6bdd3ac742081e3ae4fa0c145c795281f0f61cefc18e79fdaaa2d0d6cbb06cc0e4b9e7b3c0c3b02d2d6a9efc4b61f0156d510ff5effdd8fb74b32acc81d31dc38abf0211ae1ae1669f2d7753d209e00d9774434291a105695c9e618800cd518591b1facd18ccd4939b51a410c1b3c0e3503a0d5edaaf37b0b4d55e33aab5ff93ba38fc1ae300d42f1983cf3367b0a300817cb79fedbbda6132e2fe9f815f5f88442ab6d01d0eecb7d8185762d30fdd94978865dcba58a6601f407e1b3ee3c3fddd40439a47ae414aa37410faf9e10d6b661d452b38a1091781f3cb0c7236be1ee528f174c58397fec391f7c02a0627879e943e317a8cc075213218354c81e73bfb9f7c8f95e2953872d42603c844304ff42cbe05da1bcb1880a3d2d5858f79390ca5f60bac06968c5c0b9e159d5c49677f0c8313701579cd2fa921e4e4fed73622a7e783a9542653e000e530144a60622d79a804ff48cb933f84599b5183e6cb93e257de282e386f6b211f093e37c3c2a43247c1e6d97686a5c46d02a5e8c9fbf611f4a0a308f15106e9561e8c5a2b1c78c45ab0d4440972dc28a6d92b5786d5652190bd8f5460ea8d0dea988162fabfe7597a5deaa75e3ad2de1d2172d3147d3332f3160361b41ee990d5a89b4b2d27e97b2d21fcbb3fe26e04672366bb03c34cf5ac6975219297d3d299ce5852c6e63a7dbf632cb14078f31621ee4 +expected_result = pass +expected_shared_secret = 6d72e23c8a4cc60b2f14adc788a5c480033bbf6eb111070912bc83ad7b89280b + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +private_key = b27ca8d40a1cf8aac1a62553ff541ef56b4b4e352e38c0ae8c2cb2240c2d2525adc52b1953a1c239e3add71b5f7693196875babf8b31edc528f3b320e6569997639f1c9b5279c38d5ddb3b691b0228ac4480d45077db55bac24285c5820c49be25632c4aaaa23ed84e10a1256d9cca9b584d423a9fd37276cbfc5953c9284a4097bf71706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450b1289948323f64227960a0b24b442e78c551c5b35e89b34b018b80bd094f7594365195f44c05bacbb2e0a976a86559bd6b23d220b5c900375c6b188fb353c3b064ced669bee6751d5d22659eb89900a92b7ba84eab58b7e95cb8495191ca0491ef75a3abb9469a7939796c2f8c15ca22283235852b0a96daec403c5c057b5ac91d09cb16e01bb0d078170e0ce9596b913e953c5aa67bd8a2ff20c0261ca814f334244886daa0694368293fd858e14e23d13e66ac89a58867574804786c4c48d2fc003336c002a7776217acfe7084588455a0a85b8aa51c33e99b1cdb75541855577911db00475df42168e7a21efe57402303dfe37ab5bf10200395550a1639da2aa8e358748ec38946bbd3dfc27deb08f4f017abe33a2df3b9b96cac0e8c261e487cfff31a1484ca5e04036797cb4fc87ae6cc72f9ec0835ae2b160b425acfa8b75236d92870e4d43bfa7ea5c98827f95db6dd4200068650e3d8812de827c3f660cf8049933daa52793ac10f57ad8f2a7445927ca6022d5a485f9424662a175b2a6349b248aaf4853be709d42228c3ce3b13990794b9698869842b81649cbd9482c2435886441ed9a7927384371d02005a514717abec398bd183b321134a4de85a1fc9b72f7268ccafbae289c15dcec18bc26b81ec43c6b8a3919625165617d60c33f1e6b04cd5492414a15bbca5ce84284557c9cb481a951fa5df2e444e2c20969f38284e60ff15b0ee707115880bc6d3834230c7d22c7cd69229d1eea957f58b2d47b11ca97c926070cf1c1934ef83f5a26241c7c73959c8a0501c2c1c70671987243635fea56ce6ee292b1d6aa26c4cddfaa1751520fc3218e7e20c13c6a1df4835c7d6c0ba45923ceb2ab40fa7fe3732e47ab652309cdf28091d8d86308b73f90d86995220acdd9c544c95fcd24a77e7c90f2f15e52aab595e11b1ac0799a3ca95e0644771420aedc777a9048fa89ce94780c8f2b903548bd46a2c22e453b68736f5cca6c35ebb027c0c7035678f7f69a9ca02fbb4b23746759660251f6757be3aa1767d7280aa75b60a7a0cc892f70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc88514ced3597a594d0e28c7aa25859e57be9fb12691c047a8a7373fe1695ae742027a8f5630cb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc8625a2cb995b548d48294b2fbca97d375b91203392cc27fe835f62db97b14739f6c8b1880a53ddd388e2636f866416817a110258a098d9af4458a64c68654e97099746b9b9e23adab5653970c00719b54e4a2d2092cd7bd62ad9317357e35224184a4e24b4a58014f666b33e1530365070b73aa6da432d04f2588f34ac1cb3b3f7fb4ab200b459966fafc689cc40adad0c26108859a2943e2df84a0272c13da5a495942ba848ac92d302a98a3e55937b8b1b49fe588be32a540ec90b5cebbd90d1b80dd24d32eb85fc041a7ca307e522b8c5fa9c85bc258c8abb9f2678d29569f313a1e660a2454730261a6766945ce42c140e5181c68461eaf12d1f185c358233b9bb4902fc5089f851bac83ce3f07bd7b185ef08626d7029129703334084375bc5ba27ba023ca6722319a916baad529715661e3a413c8137cbbb206e313906df1ca77cba73e5499f54fc53047741af2341d5623278f76131ab47af10bb4dea8f493b6c0e4829ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d02d1131e493da5a0a1117b41d4ab3db35a7a2e95c6055ba70ef159e7aa0dd5452598f91477087bef1396acd48e747b962205af92eb99faa809b4bc47eb93bfd3860102d4adcbfc39be80024550656c42785a6788c7a851b107823a02a3daa4caf25097f1f9afb29416dbb360c4a824e3ca2a30e19f94b805de181d0a028e685c378dcc225112899a6b79869109ca4b094909b21042c179c6cdeb22564cfb6f89135022fca3028caf7abab19a4045dd5a60721c6bb47ac53e40cd932511f2e5473d3b4ceeb44be1a00e090a886d345b13a58620c49ca0893f23058412054ae5069c1014361cfb0379c2215f330abc647114a3c597765fd014c64c8c1b1b45b3bd02be9d5a55b0cacfce297581fb48fe0256f4c0cfc84aae1c542f36730e5f10795c72157c653210686801210418b549a7398ca8b7c70ed007cb153d2a55178ae23a5b095ee2d116b9f3a1a9f19faec40d75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c6701368b8ddc219a9f2295e6e01d22c4a50bd08179a08044b702ffd786faa088f867b63b951a92751cb0f839cd554a83745444c3bb88d3609a9a4bc2e0bc73108a71cc7534217872539bd6e942cd36a09aa0374a3894d279a1f7c38a56e7c0298948c330b8c3a5b6aec3bbdbb87384677ada78017564a7fe40c2983a9ed3acbce5e29e3a78502952a9540a44975572a1512b1d4284d9bb528e538f43a15216f4b4f2a5208e06c43896a19c416c99c3b677564975948468792edb6532f9b0567f407fc6d6c302766c6d1373bf78a18896188cf20ccec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f314827e0b24539e2aa91123b3fe42308f041dfb6c876d079d60a3ef5735ab8a36abae34f4a12729be4a00f753c7e4699572375e6c7b037948684206c08a27ec12b26f7349cdacc3559ac29d5cbc35c310870597e391ac4e4c02991096f37492083bc1c43304bc3d5925843622494c735942dac8904cf195387eccdcfcc8a999b6d1b744a542359e6b167f91022be1660bbd218a6a6861aa17c57152552172f38b43d5281956caa77daf9b94cf60cbf08cd9d9b4c1edb6c4a17bae3b36800891910c280c3e7cbf4aa11f33a7c70e3b419c2b2b9a64709c31878f913fb934d77b4c36e329ba98b44f394631e0a289042061f527d67446d6ab55ce7b43ee1080fbae67085a2a03b36cc9ad9b5b546156c3c5a79b092a67912a19575f6b5546397c15ae334b451c3d919422f28b70727c75fb631a2ab012bd5971b5b2b75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a5687ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26dc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = 4894d82e0c293e45df99ede632043a85e6054b1611e5559a4cef6e13de2f1a4900f0765b01da4ccbcb823fd715242eaef76bfca91fe70349bc1c24b265a0d3c8294e1dbc274fdf5e0e14194c418f5ebcaa17e602986608b1a7456713cca5e121389169a056d1ff870c6f23d44c96c2afa779fefc28a9439a6f17a28c76c80b83f54916db504d15c3d871e9c31da20d957a71fd5553c7b2478859124f74a5bb62891586d6641cad19be57b806e59ef42790ab89a0ece8ddcaa718e965c7cb91f7b2e7e8bda3db23a4f7281d0ec15a6455775705d00a6cd2a6a900e4cf6f584163990c211a49da061c2174444d3794e76fe271e7dd01e580a2dc34c5feefb118fec7bbe3d28505d39713b985a5d8391589ca29f68834db1f5acb42bdc6ddc7fef72b0528c6aef837ba5ddbfa47638cef78adbfedbb93104a8a8ca1d121038bcc3cd29128b8cd93a69872d21b00f64e0c6f64e970d0d5454f08785af96a7f3df920852456b51d1c6559be74ae8b902f499e4f47bf65916cebc9b092939b3fac9097fc29e33d9c60e511763c7d48d05e30db42845c102ecf542b2296fd448b4adb8cf6f3a2b1ecf59477357feea532f41013f6f8494cef0ffeba1c7e88dc31f3a80e110060f9363638aa577f97d56554a9cb48ccefcbdf211665ef0d19c0e5667d4970e46b3a122fd9feb6369ea20dd39bae8ebed4f2ebe7bb388b2c38abff8010403ce5c63a9ce090b2ac371587353fa892cb221a6f104c58c0f24d5071a1a3f2fe15e0936de0853230b8a8ca393182276641286fc393264b4032ca117ccac3b8ab44660213cb645b0a91ef6f40227f13ed27c79cce843569a5e6fe0ac49d1aea0508902f33e3b4a4ea6a54c6e0baf40315291a367950b6bd7efa92d1051c135de04f5e2f041273db77ccc0b6d99886a88acf4848f5c235534ee1503afb3152dbff0fbf85d36aa8854c84c9b4403bab1cec6de2bf0682dead6a5aa800338aca87b7d2627d26bd842ee17effdbdfe3fa6df0db28ef11f01b0a93fda3edb75fcaa9921068a4c1e7d96d99864ddce1eea3f4707abb56bc7a8ea6519462209ace4535f2e119d37e24746e9fd3b56c078f01492b3f800ae10dc633d0f64f106dac5c60d928cd3e15097b92c99a5163ba27d5b0961cfdfb49aad6acb76e8d3c09ae9c3b093e887d1ff0f79ebf6cc2f1377bddb95a2269d18781a4e046fc5a9d13b366906edbd308b546d7584c9533615857680a22dd7865644d8c62d27f5585c1f8699762f86fa3f64662e77157793a33f4babdcc657af6de6267ee3afa991c510be7af8a0aa0b154d78646f0e5df267c9a7b0e46dbcbb02fee8f3c53b2f5388f01674c21dee845450f659bc7fe4776d515a99f248df58bc24819857d672dd2e83d84ef05476ea6cba94b0587d85ddf6214873fcb332b98c087666bccbc8df96687649700471eab9ae063bd544349c5d39e1d43363802d8fe6286401b2ccdea2408280bc53e0087f9905f13c3847ec2687897375c8ddf9de7aeb115b712fc8a7ae189b661 +expected_result = pass +expected_shared_secret = 29e6b1edac0a9aa33066c113167e42c64d70215ed04963d8be2d4c2dcd0f6589 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +private_key = 2735bc066a2488726c89432e56452acb24a2a5407522988c0732ce072128c8d5147c42988f94a8516c77873858394a2bef65b87741c5b9691b6db84e3b1b2b2f851b1305832e4210e5d05710a5bb7195b8bee0cba9b5ba21ba57b962a280565aabe1c9015635cf1a7121a8581fa0a78ab26fc82838b6a405c6fa5d46469136cccc34930664240915ba5c86e67ed9e73f4b123233c92d73bc05408005dcd6cfd62635c3026c990753c55ca8dd385a29b1c79fdb97c0b4cc8f26b28ba573b5194d6bcc065f5b97df702009c43a65eccf452447af91200ef68f18cac25e5c71e62a39fd7a26c6b64b47e29d1e4084801599aba838a3808ed83454b506965507cc6d0b34bb139300d1014168a79d5707c74bbc7b980461249fc31734dc384c9dac4ea6eb4701402084719593b62aae53c8d55719945975cfd25bff31c886640fec37cab3942676c840a453c6751caf16a4743495bcde6528a942a47e7c2d6499b2a872a76e928ef4b0aabbb21604f33231235a7cb47c96d9c976a2aad533a06a24024ad0925007984d99aba3aa8168a8ac92f662348686f756bdc1a23f8537545d13ae9f657caa801788c9368864a05f40af22e33e10705741f06ef577cade6ccbf1d01065565a5b13284690bf611093e45684d6c69fc0f548af852248db6a6e86a2a907c95ce0053fd942a92b024dd18803474b03f73fc022912257454c008d137c5e8404379db2719581af17108a03f58dea58892912c5fab701d28ca845068761f6bab69bbb75584f7d289dd921ab30379248c91106a784738b17cf0044418bb9ce34bcd913bb26d04ca04896109a255a39beba1a2b58490862409e473ca623933ac14c90f64cc74af396c3186917061b5c8c28f3e8b694535fc2c73af9843031c19166d2c8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf2803e2c3ca5d585c4ea63009c7b850f08759c278f1027c59499526a8b2e494203197a9304022fa0c4e47a3a6fbd8bc59a7c1312a6d19d3063e8078b1a1bff964af48151e4cd3cd87f49bbbe01afa3a5bf46a7f9bc97de729285af35a6a9168683658ee37ba6d9499cbaa8cb44c93beb287ef7cc7b1eb6491154c14fc2027ab49316b70b8237a546090c9687cc70cbfb82208a7f61f63aac1a42961568407343a050b1048967c5334f3542860249ff9c2fac8639ef8c125d0b9fd537fca93c1006a77499658c0286267b910c10b12a6136152bcbc03e782c41b1fe94a000cd974a3a9ade3a3b8b4bb8ed8b403683ab4ea3b84b84c4825f61f99d72eacd894337523c6b6af765bcc99393213938d66b18b2b168d6c73c2eacc42ad22255cd3ac6d75200111c0a6076f02f906b1c96213e80310b8752b1b619e72366f9a0ba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3d519e4263b050259a9a0a8823e3cadcd0b81c1ca53820323a9539133c68b0a6cac1fc834b808d9375431f961fe3233c49fc9e88ea1ed0a068a271b502c0a0376a1309f86013b4947bb671c1b048c0905c8ce16d8035c7c05b9cb8755c7d7b6db2907dacc5a91b61b666837f209075e8ac5b86444b49ac878f9b2e18d42e0f791ab7cb7c973ca8e0437f158889fed53d194419c06b92e51498ac2601869a1024eb0370ca3a420c48a765a5b99bab88a759251cb83259a628603c54a831ac0147f3a97b8329474258b7bd6067476605a2b2b8311252fe54565c865e2dd96ea9e43b23121c27ab02c348310acc38d9d583b0d8105dc87896c238069c689027910f9bcb5d29aeebf57c2b9c78f76866768c0699c6bf743c0b43108c128a5277f39b32c351926369fb8754cd0197eb9ab602f391c4ba564be2c3423005266229a10b21d31a7cc3d40c2e7192cb6628afa692d3e75aace66e7bb1169893c8ee45bda5560e7f79c711d32d52c0c783eb40bf8977c3063cb114b6368a8d1486a86cb108d146a648e080751440f4d8087116701987c328d8547d0573f8c03d321ac07138a60954297cd832dfb989fd99aba8b213e7501cb3d25b384c023f66776efa3ad4981037a54400729634a782adfc24404bbb4f2405a27a8500cd79e8521daee48848e485f53a28de91089d849ebfb54d97d0cfb3cba46a27438f426eea1a0122f2180630864ae46cc5f3a828725cae89331d540b5b3633eebc0228000d75908f21277104d7816f56854c3289ad1a5c72c1655830089cfb9c90b1306724cb2828be679b989a3565758b058ae983c1ea9b71f10553795537d454eed50f50a40274592ae165c846d85527e479e3fa8d8865047bf68d200287c0a5b8a6a78c4769bb3a795979b774713a522dbb723f3628f2f4126b639e3b4c5c4b076d321a208a123d82852aa0db6ff8457e745b6b710b396c8106e635a379e22c59f17df7b7070eaab38d5448e4ab67e6b21078d5b9f9979c6d7365cd1423cef6b4c2b186ac6b792ef9351b6040f423ca22e7a1455a0473273e3b53b92a132d7c44556477907fb41f981a06cac9beeb9655fe90c4fe93cc33337d78294f7c128ffee82b0d4211e550342c599c9932a201f3cb8bb253a0559fd667a3d2cb46a4936f5cf9c4d0d105880a446066ae06841e12f259e4e6220d932633f77f9a6b463e180778d53c37e0bf423717f4d476ecab6bfbda7e461ac3cc9806ff4b38fb80c0ac9b0dcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f53816d79c6a1fb40f1ce200334a7e74760999f8a0294c3029bb23ee0cb81700b95ba20140cc5de537aca62c9808240e74d508a93263eb14b7d202a31ddc2147747192ba1f38932538241ad1db35caa40097393038957b64e716d4cb3675aa9ea46257bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cb62c702165c74864c3a7ce67d8af92eb78496c4e8eb78b55db7963b016a252a85e655c95936d6006bc07ba6250e458a387bd7bb43a3f5a16cd8733b66565377c1a74d5488c1a0dbfd7a6dfb474eaf29fa80aadc83267d0b98eb7a8ad3aeaba977a0a5e55b8937ab68e385f94db13fbc6c26bc23b0b8ba331a578b99b493d875f206c278a3b4f63e156fd386fc13104d6dc96ae9bb3055481b846183de71eca09273e58c466ea225b1824246c799ab8b045fb844572882299bd6f1b2787e1094bca102fb20e0a274257062385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac0151687859b155ad62a8539cc6b872aeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e12c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b204114f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = 2f2b7e105dc744c34852481001d4d1eb1d0bcdef8c5845d58258f6bf6310b2edbb26de7891a00b6e217fa62ff257dcae69b6651ee5e074ddd61c8a17946d1ac239e629bc2c99a3076e97cec64c5a626cde2cd58e30192aceea1d0c743ade2914df45089b6fd8dfcce48bfd740d0bbfe76572e2619fb648c2c9abbe128d3c4154c2e95dc29e3f5a362f6e7a54c5a1c903963c5759533b9a6824eecfa1aa486c5008c3039fe220739e8fa5b135d0e68482623d46f4486e9ec5161c070a6ad330027316b5b7fa0a7d6f46c4a18460259a0185f63505442053a356cd3866e2d8652e892e9d4ac7a87e1b0beefebb3ff94751d7d82247264c6701daae5fff0860e72d7cd26596e7d6cf4e01c0e5deff512ad211e516db0a91a0104d0f693fd924702ad578d535a024a06220e24110517c0909c71bc8d1f53dddb4d1d00d87e529b02081ce5ddf7db06613e6af9fe774e81040f37b00e7408c9a6583c273bf7a742d71f14bcc5b84aab2ae54217891f9692c57494e0a13c64d1434f9c47de6677947de61b092ffab34d05488e0277b5e8c29ea908c92ae68ca9873057cf0ad0c1e7ec0f4becf830b8edf3f6a9f3f06850a3c94ee0b62a39efba961f067b2c09d6b0eb774869896924620687037d052ed339853446fe3312c676d28e5bd54f22dc080961f546767a9c683e4267d8e0b412fca766268aeb72aa35111a5eae473ee808fc143113adc424fbf120029493bd311bc6c0f5084b371f20c73dfcaf52c77cbbd39fccfa4c1b0ca5ca1e4002a891b4ca6b0197c34b3e23b001d6367208edaf9085173c81ba7d25a139c4bea5798f4d2fecbcb46261474b1fde3dea181d8b0158f18297eb0eb3eb493dbb5de70543db4e193ec0eb79aa0097729bc8cd5d93303cbfbec0b892ac9f9de71c349f651c75bd327eb8e1c1e3b9c2b6e2244693d000af2a37510adce9e542c4b455aceec3909b1d3d0775466d14e185135b7cfd3f2b5c7d6c33d4def0e55299ac30a129c79e3d66ec9edb0ad0001fb4e18327aa3428659ec4b2ea509921eeab807459c72e214977e4209b294b9c105aa88e432ad017dc2698291ab51304fa00402a6d0085626ae7462ac4e953c6d9f590c7d2593c25a90b9b212b71e4882a4dc449bacdc0a5b338c5712c3d6865ac00e9f4e059d0fb87851c77822f17875563484e3aa7310039fcee3b6e6fe6560a925a1efb23852bdecbc7bdafffafc1c769cf7f1be11185cb0a426f49bd4ebf60e52f6196ab216ccc5fa5ca40b3ac8626626de041e4e14270aab1339c562dcc40adc1de8c3e184ef9868def9f469b035c082a44764352fe03db55beba995197d04f1ffecc5cfd47b31be972de5db28137a6fd1d80a958d80b35d20c6094f36c6584646a644b9357b36cf4d307165dc8849be47363c1c1d7244d1d4bb13f143fe8978ef5089b38966ad6961f2bedb2f51d368798b0b3859a8f165edc5a02adecb9eae1ec60624d523aacd6da4f2ada45004f096a6911227d62e2b9d6ff277e34beb6d2ce6ce428311b500 +expected_result = pass +expected_shared_secret = cfd1b82181543656807880f6e2576f0b095bf84629b3367e9bdede24662ee42e + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +private_key = a680635121c694ac4672c809bb3b913e8ca2f659c756db1d7bb2369f41ab4ac9b3f5141216f3c997b00dcde37352d46463f371fec14b26aab239498d44975f787504815552e727329dd78428f5568b912c76b572ad9b3d335a9f5bc0283c76aef8d81369a0ceb4523bdc4bb0607c29d9998962f76b217774d74a3453a61ff1f40f89a51365212f39a07e913824bf36b6dbf6c8934014dd8716e998a982b124aed8b082c3a2998708bc1c4733773b73e0be315203e8e264a032797280ca0ab023a9d81fbf0565f491837cf031e219084b640ee8710589e05e1701870bdb7bf0b0bb539a0b3ab0028447110288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35308a23e9c9281c61c556ec148c9a663ad9518cea36aaec71b6995110fc01cb66b75e128478280fcd31a3416a12e28c15ba617574730437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0b80033ad52cfe1a155ea1a568f5b2ef77ab74878e0ce42a1f7c3c845713d17105ab2c91b83836e11b9858a66997b22e8a67682588ca78e6b6d736298ee34b100bce61e0ad921a9f020a7032351daed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc999b2b071f84c921c585b9b3233c5bedf82637bb1253a4b29b36b42b54751dc629a215656aa1890c0c56e0cb62a3c02252b771d72375a60374bf8d84552080e0d456579930b3f2a2a3b7913c031112fabacaef75bb2da5202d7671359282cb4707b52740d9ca06ab7034b48a292404d26b6cfd08c8b0da61550044069f4cf27488c028001f2c29292840b60b321de5cbdef1ca216838091c3172ed26d141c957dd93bb6a59d9e883640d87a2a85605a9730dd5333843805374b58747c7262d5a65ef442d6843deb731c943269b4a9bf00f39b4a3847840c1bf4b9907fd7b9a66c5da724cec467102f080d4d0bc519d0b2504a05f7207edce7398d009348f64267e01b0ec207780791942565aeb061bf03719d706f87953c4757a75a126ead15c6c9447c02938c3b75a58ab25ce65a5caa21898fa8050319880223899f5546e0d253df7950691b86f8e3115438c3b80cc2e7a6178a96a0f38a0cc47394be36c9b0721580d646a89b9327210d40728f4bc4adbd8b130eecccf528a5a09595f32c0f64e602f6898b8a4c82d79a8ed31c4172a7812c295c93841929b782b334490eeaa38c17cb4e77664306bc7b01726ec656e24311c51b0524c72f0745665d43073604c59ec88df6fc9ee2f2a0476079bcfb735e562f57e2b0e1987a0220c98f0b4cdebc70f93ca709c5c2fac7098a7b866662accdf09c85974d7c88ce9afb01f48276ee320d70c7c0e15950fc0775e13173b60555a470302d0a0047260e5cf85ea2f3c326968d3c308c15eb400b13bcaaa65ebf941ef59a069ba0bd3d00841b6124574303ba8c2bc9f90f107865882c18eba462f6b09eaee05796e43a8647c59c64b7a8db9c0941299280af728b872c303755b682a3ec10c5876f040543bba028e870c02a4312aee9cf2bd1302df80bd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a53948790234f62ba0e473a9d639b1299251b46d07c79c0df1ceb995a968b5b707b760d8bcb120f6226ef5b742f34548902a7c73338a8cbf8d6b02a83470874b1ec5845dcfd3a4067c420f8485fae1286a23adb7373b9217c6dc173748870bfd164a16d62a3a6608f5e2b7fe78b92364a4b821967db45ae29aa1b11c0cd67cb4299b32d263aad7a26eeb3a69ba56790fd806abe3935d82487aec3205a856b4981e7f53b8f82a30d13c1b725b1418607b6619b0e8a8870bba6070e33545730182fb5f6f9938ab2ca68c50719fdb472a88384ef210b0c22785367dedfc840979ab758479506064b7971426d70af9a95e7d585dc8b67d4ffc2082bc45a4fa9b4fb9541493c3dfb88fca757eccb50f1a9cced9c046f37062e3879e13958bcf063041e858810b057680276d2ca12a307f511217fd626561587617674319382a4a00ce5e3bcfc5ecb5b3816133910650a469ac663f7a4a742ddb87c4e5be636213880c246370b1cbb8adaab6bb7e1185e1f95c945bb001a0210cf56f326b35051b8dbe85245f9bc6d973b39afb3a3b961501862b4caabd0d55693c201390f48fb7511990571985764be7373a7fc4bbd5e82b31f52494b15b6c2c8b5b593182028bd7ac7a40fb446ea756463c396de29d0fdba2569b9001e169f7c824c8a42d313a15b682bd52004867837344324e2f91a06a4c9f7ca447d6291635257cb0934e015c1937f732c1bba2c13591ccf4add16960b2303476000d984a8fc8036772c3b7c5721261387ae535129a7921a1711c98103161a95ebe16c0e0a28555dc3598cac2d701a98ca249801a4bb10379a5c29a1932acb6f6c3d040639fa98fa7297c6d453e35587488576db9bb2f9d1c37f8260cba3ba90e4b779867ad97db03ff005ecfe3470d2c25d54105ca287a9e0c039c2a2b71a1cbc6260d59a268d60c05d61202ec336cb8285b41a043bf58949df50def5937bee1af32d174e8fb463d03449ba747e92a79a1eac8ded247aa0a50821a16ad4c9f533a0fa24684d452a71df461aee15cddc2185551112682b4867c6cc27c43bf835432cca184840b85886a5d970e9f515f7f97151410c401e9baadf41ce2b8642313c295d28587a327c41c24da18967a6426663642dcf389c50892d6847718365cbbbb80723c1397b90447b197842c96a141bf6cd317bf12bb64c664fd237e886a9f793313aab15f668c91c71149c4b90b35b147f7c34b8ab6948799897855b22283050b113d64a60aac739948844a9f99c448d21c414425d77560670c298f493d891128ab1665d8141d2b1c8e67950a68255b7f9376332b1cd7c6630ac05ae7c127fa7acc35e640e94285e78661b15b21685a36c889a8cc890ce53c36ef23c2f17cbd8c31351beba827949f8707a05324abf05aa71857bcbe690405ab0030e648fcd3bfc0f2ae2c627e04f490bc3ba237059ab93085de218029f056b0f57abd342170f5b16db069073a3c16bb1c0bda5136952919b22ac477ac2489237bb0869656614e4ac248b003799c761b2ba5f2711b24a01419c88937dc4ce745acc16c796e0123a4228ec623a2a4e059b80b72beb1329c9204b6555b0a62c14df0b19b4a157bca985090b428dba8587b53ca2714b2ec2a04d306b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = de60b879b315048087f7a044acf1495002d4d8c1fe775d9f05319b141573f998398a2ec9e0a4783497271e5b3ebc33db67f59b721586c2d09e45cdbb77e59dea5f83c2e4a9e7fad83769ed0b29c89a117ff7ef7172a63dbbaeee3c1f6c6ffa92d69cd86a3e44639f718c0b3e713c17449b0ecbf674c8d84d1a33d7a96b4527c270c206c00aba5bb834930469d7dbaa5019dced9408b12774c4a36361a1d9bef01b95af6532ac982345cd45f6926017bb2189031aa64af89b83ac99db3fb349191de25ea482c88f3232d6cdbf02e445f76bc0aa19f35d178684c4715284d52ca3063e2129dbc757ddf36c3fbf08051bef13c498feddcc27591b69ba34be65231e6e4825e28e6cc626902e1ece7a4e08cf7e6f029fedab272f79c928ddc22f78113b9cb94455afbcaa7b7c9a50c1238ad2eb31adcc8a88a4c02a8fa3d90ff586f8a45251b485014a4e8f154181f5ec04f6ee3de1d7c5a0088d4ddb1e9563dbcf0f9c0f2576d87017cbc89a491317f388f06757bd8cb8a34d7125e2c66d7c00602c785104912bb52e9ef681e54425fb384cd443837338cf3f093ee407f3b5989c2d8b7477d2765c1cd97a66d46f1dad4a837389a1e09d0d4a6b56762efd058eecaa8aae088606b8543dddc23dda1bc5a4fa76c94755a7f5ee314ebd22832cdd17b05117919c07dae55aa8419ddbc9ecf4747e38a9780c2cec7e956a58687b082d7d873f5ef4258392b8713b1728a6e295eedc87cd848c3f8fe88340e2a32629a5d373512be9a46b2f6b286edfd3b9bed40c55dafae968340f711d48ebc28aeb93fbcb039714eb11d698a5c73eb3058a015a4d0e01678742a312b8b9fd2a6cf7eb26078cd4c17dcc903d4f51bba698167882912c7f7b6417d30ca0f074c628a6d5b16356c813f592e568fbfff725900a8313fc528bdf6beb60cc5b445ebba573ec49721bc9aeb6025b1295eb536f4287c88d3dbce90d5dca6b9c27a6a879f0032e01fceacd348c92832003bcac4e766888f849ea6e7636687b766ff8bc93a94a7ce3d2d2c8236ee3409404c3394e807c108c3f6e17d69fc3dd5861f95e959049545a4422957b11c65ce6cb926c3df73104d19f67589fdf09b44ff4d4cd0c7056125df52ac7952f8b6800652ca91452ceb11de8ebd09b52dc4bfe9b60559ba1547fbed198001637a4c8abb24b78964f461f910ced77c71d114fa44e7dcca920522100c8470e5699ee58338e715ea09e257f74df146e9b2083b394bab377e472b918a8e94274595ffad4f27e7660f5e29f2c292f3364b2bc758f741f11e215ed45427c5f512b7216270513524814b931f50b1b59a89752318a23b927d432b2876bdc663dc04cd30de442ab832d3e20f77ebbe261d64bf4124f64f6aec0100216f453420cf66a65d4620bdd74322fd270fa502c7f4c100c39c79edb4c6d09d065036d7cdbe0e8da3298f65408f6b010e19e3e9990f46793e32a52713991a9b88a3814a80ae52bfeca0f60388eadf5c51bdddd5853a591d56f9008e491e11710f2b722ca +expected_result = pass +expected_shared_secret = f7331b0a4674969838482b7184fa92e5246f11f5b5e284c3e179effff7eb6329 + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +private_key = cf8293b02a9a6f579f51066bd6e51abd270104634cfd482823102f2b63b18a8bb4f45a5af4d8202523cc1779b44fd283860bd004307c399ca5d8eacade156af824a988f5ac6bb50eafa6177a95b9752c922bd6a7c4265a6a88b11d0403e47127b1e80787742669e763929483393cad6ef91f18143e9d2b7cd3e028c6f56b91768113259bcab926a082a2a6185a1bf18656448a628258e21a3c6cca23449b4f9483ae9d01bdd4bc674e06566300ad2a215809e547e2626f8d9437baa727f3f05c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303d98223e1a4ef6536170f53a0c61004beb75fa34b8aed5156e4a538269775808283cb0ba5282607d50661d2a626fac2737c98cf33050353bb83e1c1136f1c26fe48d81973eb974ab1ba4b97c95c0dee065523430cc06620debba3db92888497658bc5c64b98be65ab2a0738f0750022b95a66c583354a63865b5237fe7098d279c53f731f3fcae8689754194a7b888199b89761fd09ff75677b2c500d7359905e76357163834712659f26d0d8c9b47192404975cfb89969a77615d1a3fb404baaa54511ff1b3b08c1577eb274f5b3b0b825434e87f60d18fa73141f912701a99a7c11305000789229a144a0899685596aa646f13573eba0b54dd3205de2c60c3ca1614066474b89f2377994bd14ee0a77e1d4c0af77748c1e623cb8947a98636694c4efaf0ce2bf779c66a317989a335a0071505831471c8d845a5fa4b3e42d195074244f70578124c4c7894ab84584daec8c13a6598524c023ca99f4c0499a68aca3e6827798b10ef9a4639605e2fe8656606438274ac8ed8c87ae0a16ba3b8e5857a7f25831d8b85bc7105828575320c6baba75489455154b31e50074a313ba9ad10b747f39405544f44949dde165070c8271f1ba80e57bb5bd1320c8a1f8fb47354079532bba51282ae3197026e18c46ae6b2ab9940eaba9f1ee421592770c9a9604263a4917c825c084c3534381f22c057592dd97940adb1a439d5128cf795cdd25640fa9229220a1ce4a6624cc9956105465246334c77ffcb9907159461cb1416637d8df34ab4b401413c27b6d5a1d23331f88273222653adf9685a614bec9840355b1a23a0c4ce60b0b678affed200bcb383bec2580c89127b2870745c15570ba1cec89f5dccc47be517bb020c57959e433c11df10810d5b37aa8ab3392b3358793246f11ece238646724beb859c861463c42b5030d9a1fdba3e1d391f9ca5a99df58a7948c66fa2b50864b73a40b52dc7cff031b3a3b21009268cd5cb00a89b44c156333b802ad03b2f07f70f7c11057ce78705ab6ee43681aff0874030807412a7743399cae832f6f3b65df56ab1b30d6967379e10b4ef53b9efb5632a23b942f832a7fa22cde494b0c7393d51ac807a38af119d526a5a3b91068e107812269ec85410aa739c288c20446b68880343f2e12157094dd424a349d1523e76c0acb9c29c22b6346386b522b0466bc8a85b97430a1df80850510c4825ec4f2aab987c4a07f11693e7bbb4662a4890a3c54ebc0cbbd75ca468428e38276e81c43d81a8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137c41fee75640774c4b536bb1d7bbce797844d960c98359f5719b20dca6d1e2916f2829e73f79b55b468170b64f2f8b0c788796801c8ec244e1973c7e033b768414c55d43079b2711bda630e678b184a70dd161c4dabbcb91c07fb634620d1450664a444e82d22a0a4f54ac6c7c02d74120b2ce205fe49a139b9c8194341f4295ef126b37f3b22e35792a8853b60eb3f7ed01314491c4451470870a5ea5b1d23442019bc1def547fb8935ecbeba0833228b8d7bf2a4aca52436a3f993f6164666ebb3c38317bf5b48cc7182c00d58d4a095d0fd4c60e4229e77803c4f38f22464c7a4259e45ac71e8ccde6e5738dcc798777317f9847f8357dce21b24ae462d0465f1d58203f3b8590d88deb9c6df4722a1420a9ea0813ec3777a6cb11ca0271292b6c662a870c292291164004299c82442a8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c053203f265bab420eee2c95a5960f8a87c3333785e1b89ff841a6aa5aa964f3a853e512acabb60e29c3a4810df33830134c0e49bc5e1ba41b07b671e1ba6bfda82576406e6da854920a46914c8ea986b1d6a0328d4a450fc0ce698b9d16954aaa0c52b6f2b5ff7b5347e84c3af403e9b31ec180238cd5af96f5c6f0d3644ab51717f7255ad6551f44378294778937cc56b610680704bfb37e3ccc07c5276777e37f36623dec8225388c3a5a2c7026eb902c63260ce27ffe657bce34a47db43667b9293e04ab9677b6fdb0b0a429a4435a9f5624628a2c07bbfa8afed562be4233019524e67cae6f955226437433bc59835561c462071ac38058c145787c242d4b6dc055170675190882792ea49726dc8b2cb638763784d3c23e1791c93a55383a8c4b59643626f8948d228b670312893ab3ce5b123401b1b24432545889d4d124d2b846070c1663b87a3475c01adc4f4df286fc91c76b018c05b5a26a696df86c4b1fbb2ed3050cc9b54ca2786839f854b9461655972fe21c3c98007a693a4d0b8aafa3ab73f1c411dd283cce59528477b6e089847ce6518f29b523602f80ac573618070bca649efb84fc3947d43b229e05682914c153809521ec9b7978a6bd667f59b18f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734df18a218c5bacb364c9136b8e055053567a1856c21b96a1a2723913c98cc364bbd1fc4edef37e1853c523727a6c677ca4c82ac4d49238e1b60c1531d1dc9835c4a96124a0011c09350353aac4568a84293e8666f6016e56c38371489eddbb3df3e53e6767bd01e231eb122f13f59a83a35101844ab389954e8068f6d7128c738ac1774edc6465eae8ccbabcbb41271467c407d36928d9e3174c99665e3a9af0fc1b2733925b254a3aba050ec3925dabc511427c0b2930bca63ba7629366c1ba620cc0d7090752157b5d70c098745e37db7316056c7bb37c024226425107da8ba0e9c30e2606752f31a017e50a0e10c05332677ec851eae14f594a55d07392c23a962248ccee1221feb2c8f801860892b33ef2247b801e5ff55ba97675a71037fd133133840050b8b7914125e9d30165847319eb1e483005ca0bb8338b75eed618c47408d0260ddfb1527640a148f29e64f65fcafc59a8715a8126830024767009bad41a3385c0173be51a35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e287096185885264e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d35aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 9ce63bafe883f7e6b5932e071982bc35f643185589ff435bf663b9fe433014e07285e8be328729d3d01079bef62ee178fbf8e7d9ed1c2529fd9912958b8f120dee444881a4634d0e96973b8c47c004b373d513ecffc97911b53cf0686fe2cb8fd33eb7c0f50fd38592e9b7f73d119eb8b7288e7259894812acf13f81191f5f383279dc7c05f290e580f6e0a2e488a002071abbcbf2cefc4bcb73eaa86ffc1314e120b8a96edd6c0ee4faabe7037dbcc63d8dab849a55a35f39e75502c961f1051008ce4c9b0fe062cbfcb6bbd6d99ac1cb24e979d72d39e057233212af4afa92a3284b1b272509d0aea213d5f18e5ecee943d90cf8bbdf9061b7da7329cf363e54237ebc2f07de66ad90cc12744a74c6e5d577c8517e140d64bcd40018995143383f5ddad2f7828163d25f9c3af254119541fbd304b96f70a8cc9822087cc2ba3fdcedd9529cfb7137991dc8842c5cd1ea2cfa9b831f507c04ee4db010780fd3703e54fe7748597f1574683f88c3a0e8a5bb36695b7c5b1d6f566f318263f3777db8f433019b287ca1b8406e7755426e593134880c908ff7cab24f2c8a446dfe1bb1b51a546ef9ec43ded91f7ec7f1f97df2ee83d8f52ac9e174639fe9591deb37b9d9f9dbc9d1be6b2ffa2e8c4b5eac3332ec069e9cec31bc7d21c5253bb20ee61ee701985a8a73cafb73b479cc19ea62b998eb85cabb5b4ff462088255ce5cfead669cf5e17871733361a9e25392a8baf8958bcf08da7bfb12b3b174acbdbb8c9cc1a87b2f6e48568f19b1ccde0e9f59ef624dd525168ce64dcf1e63b0c118a077cbd7b48144234001910dda0094e21d0abaf3741aedffbff4dd92d291180c67e3a253799118eddccb6033e3f450ecd84637b563dfa9010a2c07e9b4d4d55fb71c7cba9485b612561ab34566c40575c4c41eb9ec7d0c08b100421b7e07af4c864b7d8997fe4458867ff0cfc02b001250eece27b8e8b71a1a04983193520762f4b7c4d2fd289af45f1316f89108f19caff5703960efb9ba42823a6b9d9aed333e37e5989c8720341ed60f4b47223bd313b56e6160fae8a3bb56f97ab1092a7e36e2811226f9bc14d63bd3f48db4fa2abfdc2b7b8215d4c5afa301783940d3c9f8f0b48ef9c35b02e272a7725c77af66a4c3f43f7da5852569115857f7036f7fae04db993d6a016913c8c24912eb8c6c68159059fc3c3a4dc6c47da86cbab270506651e2f3a2fd268f81aabf83239d885c886fe85df698f72d019aacae6d59eae99e2e1b10e77207d047659b00bd0cefe7d675d7b4b50669056e536539a0c29d35633c6a059dc09abeb473b99a85b067d665374209a5e2b729642d03bbb9a41df15d8a2f12f65d32c965c0f883c6acce98ec4692cf48c55c7cd4e5ccca0e93048600b3a37fc6b2cc617f03926d033c2b6a4255968cf927c665c601a9a23c58db533f67f65e6b501d42ac65365e14c0180349580ed85e9c5c1f4f0592644460027830ec2470287d6ccb55ca108d34bf1d373f27e46b64b848834c85fd585a239d +expected_result = pass +expected_shared_secret = c89d62938a5caabfd5b30d82ea88aced52ef5f8ec0528e59a654e1f6aff1cc2f + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +private_key = a428a1343429ce9c3dadbb6213410e264426d1cb5c69c68e7f377bcbc454aaf867771258faa622b6367fc5cc46e960682a3984a13230b3d7c25a69ce4ab9af0234a109878e0cc42a9b858dc559ad3fe82c4060539c08828c51b337b7c0ea768ba646a2f04900a235a4042b88e8934d3b62821a13b67a912f162aa80953cb71c396d91b91521b6665062551e0a6ce453c233460789138cb16ac6e598f670c70d6325804cc494466710d984e3ea551f5ec60c5031e94421919f62c301181831b7fb4fc61da443fe12784cf84b5ecf240daecc87d711aad10808b96233d345ba80b0469797dc03583214355e8e9a356e367a593a6898355ad129a8546a0d03b2279021889c118db3583da691a9ad544086540bb2178b2125f00c94ae753038486b6cdf1cf7e5a2202290b4e5ac807eb04bea95678b52ff76c4757c68d2eb9283b8766f1a39e06c999015b1f1d5c3164338aeb432d54b338c361b9a7258981555fc2563e585a6ff60886c32343e0045746e50fe78a0a9bcbb6281abe3474ba50e1267b3276a1327a8f128e2b5ab077618c59902c35488553f745d2a0c942b81c0aab7afd0c869b9b9c66c1847257cb22b018b81b25c468a9bc35a180b090f4bb90c4ec035c0078b799046833cd90f7bc2678cab9b75b95a6b457dca8fcb84937c01479a0b7b6da9643da507a2b8b1ae25373825189729bda8b35fcea315b3b359705cd5b486582379093e64f431309f0389ff899beb4c3ca9689b412a210eb654f183362ab8398b1e3696df7432be662cbe62666471f2c056504a5c1c91017a6326acc7306524058fd0937ddeab972b00734f60d065a1ba8655dba3093d161b99e698fc778b2fe782fa8ec7c62d422e17b24fd107b87a8338ae7af6994c70d959cbfc3720b3174b9658f5d43713cd47325eb926320073f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c2ff2a1f4a87159472e7d7a4db9243a1c6a636ad50735b870f1297b6d6b5303e2552a54aa5991340aa40301ca2d6bd9a765b72fbde1c3c44a7649ea350e00cde59628e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd544295317b55ea9ab1117989ab7b7304304e5612119396727943678c31cf2b1779c946b82420a557a8d6426263d33c7f71591c7857e90a7fa05158e315ae19d1046249b3011b22291cae30501d1423674824b852c34c97258ab972af6c5195ffa20b6cf05ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a529a1872ca25cb4a99c38b225e379ace27485d8b91fef9ceb97c04322b59f533745d23720ae457fa11b3a0b831de777d07f88ed1771fa1d89db9acbc7bac471bd423acac482bfb29de13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65bc2e6e04875754a77025985a026adcd321574ab45cda47134b560219338fc93b0a398d7f85169b4b32c2ec3a06529f8e3a57fd353327b03f87d5cb60c67074146fb460476c92619d9c23ba7a371fd9425cfc6486992959109cfa1c1a75ab9eba4235af63c6f8648ae7855a4eab5c9d3923386996181980b16b02a53060e5a64a8cf3ced087bbb49b9264faafe731c0dee965ac981965a28ff907ceabac477e2c9b6dc95aaeb0531cbcb65d8b3f6251be17ecaa89a5b57c1198ea66af1f4461b91c360e4531c4d49269896107f10ed1f1070e68cddb2a4e06c387f3126087a71a366a250b450be1567dc957bbd034b66ab65fd4eab2d89b8481ec2427a4af3c1b861c799263f492779053a0128508c86ebd6201c876bbe8ab8053b790314047a1901c9f327207b2130be5bce8504bb03817a380975cd81fe0c0416986a7b74a16a21146636abe4d2b2c5c1223d39265a6845804d49e5f160abfe3ca21a345b5d044afa5636c37b976f2894869bf4500c62ae9941b9b3c3e6064fec351268243fd75bf287cae8aaa9aaefc1cfba1032ad2623a6239a7f834a4826f86132b59ab24efc9c57cba929a64ba90271b987bc08a913298911650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348c6063aeb0bcee9066028b3340aa147b09c42752cfd6d491ffa497e17ab6c0726aefe59c2577764a1a996fd879e58c23f1c0ac9e9372b3f0be42c829b7b09acb722e3189a2b3e72124895ccab565dae583c6c76c34c2c0075568379639869325f6e92e0b91a2d4100b2f4aa6486b756cd521e1b781a964a21b8b0c72637a2e4299fe15c1ac275fb077cf42f36453e7603c91a648e09cbf128ed188639b7247584b333003a2175bc587925111654f24680c540b32643b035ff38bb4598785524504ebcb26163d513867d74744c8b562bd48989b3a328374a125ca05fa962ac08b0d22277e578206a165a9e3d31a084b4492c664448aa62986b55fe8c8420816a5a9c035644f592969fd0951b6e9aa57303d1f9927ff6b3de99263e2e11cd8317cfc899a45706746e9850922b9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc56285e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38c807f7274708aa0587f94a107089a99694fc627291c30fd6b0430eca692db54a96019eaf89635cf54f579a63048070b7f32dd2c32a18e2b7e8400344412e9dc5943bf3af11b4aa6c328499da7c220670958a22bffc89b8f0091c8665b6605571d8a1b5c934ce4686c7c047ae416bc6e39b7ccc92cb076de94001374217e9b8820354351cb377b4f06b7fbb69f64c7b48f781ded2cfee998718d875eb94866e7c5135358ea4ec92849978438c77cec1ba1803bf9933c8856657c953125eb76014bacca8ec9be6290936130d166b187e1463e55cae3ad85e96e81bc574220ab0cd374aa1f657abea849259b4431f1a00ee59b35486beb09302bf71b4c2e840963333b4a3be37f8048d42a0f67c886de9b47611555495248ad4c587577d45775f52135518793ea14582bf153c74210c36b9251609a4b28559ade5a93203725a475971b92beb88a69357bf83f384577cc1dfb62c70fc65401073c67a66af878fd961bacf46c633e7cac0e5092458cbba0c3b69494c4c0c0da6025cd6516c1ab89b3216bb9ba123040051563610251974a0b11be7190504522a128ca3107938f5b18e4441b52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb12f40ac971cb475610a0e6c546998dafe5c2ed852d7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c828dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964ce63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 4106b63bd9cec4d8be3ac33234128e2bc1346ae6388357a3258c03ad9689e68cece1992893dd26409f62211674a84155d1af8ba9750add112f33c812c04adb0a1a59685ca91bca59979af97c948d5443c38894543a225f05317c22e6a8afa332f4cb4dcd6638df6b3a0efaeb8f065c576c06f8cfe3cc0b3c823d0dc638e2203b886efbd82e6cf5216a055e364de238948c55187ba2d5503a3fbfbb684cfe76da66ab53f97ffaff0322a1c0224941e8f64e3705a2e4e9d58d022d31e6403329b220546268abc3220bd49db91521cfd149fa186474001c2a86c407ea8ff96ce07cc335b3cb692998ee7929e27e80cede8eda4406494d289f479f15c51d3ea30873cbc9e5ca00ae20df9ee94901542c02ef705e068f589a4056a9521b6e003a345afb85cf66319506ca2f5a75d15baf62c6c5db502afdcdc010f93cbe1d1fe4212d6796f7876c3f1417508480678fe36aeb0715cd76fcb15f4154a7006a073e55ab89fe90b708e05279a9d51bb83d268e729e47a832c2a93642ab79023b6aa81063cc2c82030012cbb2374e005b9f0ded74e82aa174496744434220d74afb7c018b93555d9ceb8a23c5fbe22744d8dc9381d43ebd2c8088db2c699c320f7a45fcbb2003573157a848459f587b22d571b37b94a76575f1f2341085e08e31ec55f330b66ba4f5040b199dc847262f6d87e8ffd3196367beeb904241f7e0c09e9e2b0094a26ef78ab7ed8e7400bab8094b6eb75601427af06fb9a3ceaadf3eabe93a4e3aed4b8e1a72fa616f010bf0642ddfc84dd435e9ed98cae09a805ec5fdbfc740d6d218cc7ba34790debb2141990a3402145d48ad84548d5d2a1c3455379f1c1fda6e6b03cda2c6286f9285e9f4b77aa6c82e7254ad5cab2c9028a0e47084f1494978d58e2f8bc0ee2c7f2cbb38f7c50e7f60049feb80073493b1cca02a700f0d51901869432fae4687e11639144785a8c53b285ab1f9cb7bffdf5c5bcd322684fc871759e6d43bd61bd450cd69ee905724111e11f3723eb87949bdfdfbf769b76e5239814eeef6d5ad7fd65c8e0c32015868b9756f7f96afafef2861506e882043d1f947e7a21572575a475b0ab0d11566428cf7714f1497ea85de68282038563fe43e72ce17ab525e93265df6d62d0254f9c69ceebbc0fd6a30e37d2ad218119ea8d4aa85e302e4e70e25e2428032c00250b14f6c434f2b02557c4d8367792692fb31e79259c76902bcb37c4c00a1beb4ecc502b7c66412358f93382ae592a25505ccc42fc8f02e43ee8e8ed6a3d93c2d9505de290ea8fca4519237b7c76a6ca6fecbaa47e7f519f68f118ac54443a5e7ea238a61a1348ab16fe8bf1a1e39462babacf98e39fad4af8033a0dac02c806ef6715d6d9978e9b91d28cbb6b894898de9cbca5ef3b49ce91e19e23be8b75b187bfdb14fe943f30e11f253065df04b1863566e456c0f4af829d3ce3c88f728bf08e4b38efa11758a308fe6a2a45d0deca930b9929a51e72b7f8da6a45596378e071f7bfca861117f534573b35e994e +expected_result = pass +expected_shared_secret = 204d9272682710b52fb39b1176af3ff737848978770310df0c67996f6cb596c3 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +private_key = fa198bb15b4278509dc232002c75a8bbf1853c474c8248b5062821e4d77fd5880979922016d17377f76a89ab9477a1024c9780fb728f6df3295666828143c52fe817b9688c70eba292d2716ab4970840abc4603f597b5fcdeb0144813602242625a067ea48b426738dad0ab986369aa5326dd199c72212c59ab20c8f63429683721a2c682c5aa853b86542698732ab86fe39c340db2d452286fdd599336b9923599b66c144c0c7848c20a6979133fb7b5efa3726a4f44389cb93d6a9c1b7e300cb852698c236ac00b2855861c88bad062a25423362c7774c1626834ee59880762508fb518f926a3f475d01aa8e5c8c4140537091d494af66b0e9426359032a2264af67e63541c2408b1853f87c68c28c8c13417f94d77f6ac3315f23405c233e14f7762c152609ac34842553de175a6fe1c08b44baa9d15cf09a6049b05b69f71df322171701ae91d050778a6754e374878169181a2e1336677889318cb54218ac055491b918bc2553023167151c98b30e1340403e0c59b3252f4d0c85ebac1877798c41aa43c5c7b738b7ce116428c049370ba6665be646b3125aeb947b1f3b2ec5357c7566c13eab148c453d6b2274a9295a06c822df9222cb2026f19603b5602d08d46d4c71384e776af2a441894826e4559f5975c586e47bc0236b4897622ae4396160334cc97aca101805814ae44786d1e445147a4728275c32554b9bd148ae9605e10c5a6b556704f1c17297a32eb311f1e92ee5f160e8522e06554b93b5c796e44086e75d236ca88ecc533c3b348091891e35639bd6cbdb3a408720b6e3a328c4268454169267a5c5348703c412c58846c192e0a162014600dbb351424fa8d0599775bd2d851db4b07438f655aad6402628563db3a435f75d440636cd64041de162d178c923490839f190f106be0020ab63e7b3eb718a4fb59e01057c416c330cc26e485a6d9c72b707da0b297c0a25247d26d40f044844c2db883a5bbfc2b06f1bfbccc6d10b65c9bdbfb806d7a04cd71774dd60bc423c1dfa897a0512365cd54a90ba6ac509298bf6455363583843925281aa405c291f11695cda995a9ac5f742351560b38f8720d66327b4dcc47626744241679247cbe42695b8d81c37c718cad53d1b318f9f900757267c43b982f26639901028f8f636c35091f1ca90a1e329d5cb069a918f45a078f33ab4dfd248390627926aaddff47ecef1718b2b048304cd40e72fb0872b6207856a61bd764034e82bb426747405e1ae5b93c63cb12c7bf09e47e27117d26acbc102b043616e60b714316dfc17306a77800ee87e03e4b74759794ee6943dc274aec1a08197a841e68f258202b1124803064f6e3295dd51ad18949a5a383a81363bb00118a8569a38d138bf8835362c723e999402d3cf728b0e11f647ce2b9390615b9e50487e23cee6f9cefc4a1ce5e83d28d642e3c16934b43931158ccef3832a457a5e833f317918858807ab084f687a394c257abcd8435cd717d1e6b79e78a37bb71a236729839b89a9905b5d935afdc2c1e6c71c597898c6a69765ba05e9784b7849c685ab5b6de3358c6299d8a4b075045d6ee15b639601aa95603a67378157b54889c3021453e373208cd06c0deb77bc962535672a8d77c9eaf9726cc1a8b8d87d61b1461f33b7f7f5a003a8657297cd100324fea561ba879ffa75287d9a838275734593abc2b842d9353906334d3f9324c7d00eed794c78310421db45cab6900817348d67490bf1485e85a3dfa255694915d286ab5243b62d3a91f8493f0b19626fb89c0b9109c6e1084bd8c848c06b3472a65a2646dd89be2d922a0d2c5e816652c826854ab36f44809ee56c9f7e26a1dc30823535997a05255756704aa1029b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e512b1c767347ae28ae046076c20179d0977d2d54a3f78add2ec6bc06071d9447f0461846fb1a5e91a760112424082c2994a98d07aab29e818fd15134de437c7fbc59469ce8ba80545a4a5bf337fe142b72e602d8a1b3009cc95975759ad38274e234aef0552b8aa65cdfcac975495a84c124f8426a9c87d8db03ce48b0382642cb9e31ce210b774724912b09b16d88ae007ac4542c092f9bbed9c262d823d9d5719b357821d4c245f384fc923cd334b9dff579e324a0bcfbcba61fb7ae9f69b3ab88693e005ee32bd1a6a3ca950a22421125391a060276b07242a795085d0098906969c421cbc469128fb5393b72590fd391dcdfa3cf87b9f7a4c6cc3a1791ae1717478a5280a3b7580bbedf88f0dd7c1c09aa67d6b284334049398ba983bcbacb8c56237bc3efb3fbfdcb358a006457832df7a01efd937e68b3299580cbe1c9f69e165d22683b3721e4189adaaa91846b7717d41baf8d9a1dc76c387f0b55c2552533326597466ecf06aca624fbf73226e471d835b0ee4a24a8f1c5fbe359c61d974a4d57c2f7c49822286ca27116839b784d6782c13b606b87804ba0969c7c47c7a29ce16cecff5514028c3d84944ec8cab4b4acb5b681723511087e25b8ae84f3741a2de6cc21e7a370b35c255c34555f29645d4b420494c4d993ba3f092ee240f1d3691753420891acfc9421c361ca2186b563ed63456096227eaa738a33ab56029976c1125dca790114aeb83aebcf271ed59bbc2e8377301b53d697cfabb4c6b40bae19b6cecd421a1109f9cac7b71c749e60a2005a30179c393d5033cb4f8795de4c98d91538fb9a8cb1654b1e6a82918471470461f54cc71fba50deb3e1221c55aa616ad5262e352adb7a89ca04557a2090fb05704b9521809b8cabfa325892ab46765cee83850586918422212c812373a1c6217ba890b4c5310f7b0d5d8275b884aa9e4914c85023ab53bea88ad4281a7f501a87534ac1d806b0f8691e9f1bc7171001043015b391cfac09b5fa88f840c63194632bd5a012b34b50441ba08c879c44654f136cccbb7114f7b4099016e0193cbbae63522927df4b740b3ca5b32b741ea15a47370b98926a1f90618f5235357e8087443c93444803dd22bbdd5340c876d41f3ac1db59e9ef17db71369a315600fc6801a54483fb015ad3766284a97cbc241ad73461f4b2a0f6645ef428805762a6e57474d29288404ad98fab63ae95e25436626bc66ee10c01e55103597288ac521b463886f863833948455319d3455110b68bf7bc495d1a922191a1a230a5f036c3c4ac05ee2609d09891ce368c01f037d818805a566193a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463fda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = b1ddab92816e9b3d6c9414ca303b6d420087f1f154d8fb5ea6dc1d5508e37f6edeb9e00b1fcb7d14066fc3585c6b61452303e8f76c034cc94efef7c29b703f2c5f997b2e3e73ced4e264bb8d940cb26ee5e048c7baedace34c3404752746593b40806baf5a7d13d1d4f43e7d178a85d3edfc37e840f7d7aebe4748a4a6f862073e18e916f795fb9305fe250574f2e7de19aad589e2a2640167d49da76c63e0dd54065e83345c9672367cf0e64596ef1357c0bc580ec438aae9b9293eea6bb2dc43eb39069e6d409ec1c61633c436959cab8f564858a835fc468815fa445c647fa6b4ff9b32a5fe4bce0ace00e15511108feb69fd12ec24900fdc7ccbb3ace5677279b33be301ef70247b625315439c805eb3f1d68ab316635cd5f5eb8e9ac9439b5278bf7df4e58da1353508c6601af0db94691f15de3d2fa21b5e2ca7052330f55218f207fd956b2aa774e0920dd6ba34041c0c801b69f4c3feeb1b6d64d78fb8d3d8b4d13792ca75894c28c1f172272a99799fcde0c9e10eb3671eec271855eea93d50e8a341ef680056eab4da00cc43c38207aec9d678c0d00b64f695aaa6ae2ba75d11f275d2985ae217514407c952084b123219c2a119d2257c1ca1b635d770cd1a01819d03a2d6880d6b0ce1b8bc59da04ade0ae64b543fcc6e96495bf5fb5d88807d5582c36088883dc14bd616971f1d98ee6083dd74a2bfbe96dd08d2711798643a84f07aecdb2f30797cc98939f61fd5d5ab12ae0dada77ed40c8187ce5e505ca5e8da98c7f5705c252b0a6ea56d8e347912b854f414c606d36bbb60aa9dbf30fbb1152afba2d335d82eb865a38baf10a01ef2cf5f16f06bc826b1f980ef49ce6e7e411a15750adb337b3d3e7503b3b50a3db53ae8a7bf59f26fded1abea8fecd430cbc72f4c6b357bd30d01d4d03d70f07c2644282c133b0408ede5a61f797b01d288d9a8326ba620f071f4823e73328fd2c18e6a3376fe5b41a54f63632338b70ae5e85b7bae061621c35c609a6c2754229a57f65d8be1b0889a148fbd19d58c002bf5d6e4651a3feef2fe29dd8732211e9dc7a68f8e2341c33a573e815e67026bd559c398121ccd61305961194f69ca1c21debc8caf921f54a2ae0de9285966a9d0a8720cebbe6d18363b724be75e402da9d56aa1a13ff4bbcdcff699adf148998f5e47f6ff9a43355687c8c7baddca273b8bd337464a42fd11dd33feaf6f3c218be2b3a3817019a4e4eb9cc88529285274d5c5e5c2329a42392cc28aea4ae431dc29e6d33a8542fb79593d93fc4d7702791d16ed6934e6d1473dfb21305657d2e57b5032388b1164165e3f6446c024bde67994c7d1e9fb32ce1a9ed53094744f08a5e9fcd34c390313555ab80a08b45f91e2137bc555da994a3951711eb699f2c0ee681e2abeed06f017798b5fccb3e0a8ec4eb880deab51ce1b21507d47c3065766325f03032b8b747c63b0feed45cbf1af5eff06681096f49b2f54de23430f165ad9cda134bfc9d1554eea7336094381a91b75e861d39416d +expected_result = pass +expected_shared_secret = 76e5f7623e3e867fd12f28dfda4311f7cd90a405b73e994e857f693573fd2b8a + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +private_key = 55873ec8c5bac259501e025faed327b9b659b0810e7d43b8bf7a25a8c1a51062cfbc9bbeab182747196797913398db1c1ca41c1cc3a883400a29797ab4cbb553076c204167aad2208355279f504dd9a476985362898b4e423821cc2642c335c3c953c866451cece03098d5a2ae366ddae1a06e05547e1c0c0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a921fb14042aac83a1b4897bc6a15c87fc94144828966c49b6cb8f842a3157b60d6b3271c3661529d8a93c7daf7b4de1396308c0cbbfc9f984617cbb5b1825c88bdbc4c74c58ef3d54d089613a6a431e3a59acf4201fbb6828db0061f1bc514dcbfe72023cf8102e9834d5d6bba8a354fe04c6008b37f9b07857cda1238f5a562f288f3217ffd1a1bf8b2a0fcf3af0310c84bd6cd805c246c4a227c9bcf963093a9755cba968e7c06cc4f987b516171461b69e013076cb652c2a0b10f1b0fc9d6b583a929fa3905ba4b6b41f19d862c82b5f170277530a278773fa740eca749c00a61735aa1a27719cfb75eb0768956718239f43239e25a316339db665eb9784ab581137d020b992782956522b824b3ea4cb540a4b12ad7c512046711b0463f779e1279bcd2b7238580c72df6120850376db48978dc717cd1424d0b5e7331b76d0ac0b024c6283c8418e5b1a7a297aa483e5d2a65f2181ede32c69cc4b9a8c4c0b90bb17ec06336d2100766aed931876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb737647504ea1a29d13e0bc2d060bf7480345051e9379cfb0f901b9a426641802e5522ff8b199439026b123cf9b5827ffa147567912c46c88cef0b41d9526d227a72262c0e3b3157dc4898e07caebc8038142b5172a799b8a6db0f7703730c98e1957fef13d5d7b2a52945eff5c4337b6cc5004bacbb419ba73568aa357f61c70383447c6015a5896b9c0c0a2f2c7a76d940278d736d6b685f4fb3cc392caac1830b439468b6bc73585b4205751e55103099986308702a477588611a990580d88657024fa6d371550141405a8240109824788675d2546afad54628e93281abccae4eac11d200aa5c40a9e440d9f2a40deb31c2688a3266c9e16b60461087da271a1973374c99693c8111f9d458f92ac3208268078b177c818038305ab421b6d8297063061bb36f1318bb2108163a723a4bfc3c2a25f958f28b2b806a15e4310b8852103843c8ac26c7773084f1f82151c52083e69772a049123027916f039fd08713b98039f3b84cc83a8f88b2c19f48a958a443339a5a2158dfd7a08d11983601a1892a8c1152c602edb1592c3ae555b2ee54c5dc6020c0b95626fc06d85d78120ac135fd369de6b6aa902bb015a7bc3ba13a7391960c533d2f1a6278494e78b6a3c5b91a2b1aa2a0752e5c0a30e33cc86dcba2e3232c98b9aaf1bbdf9e825b15a6dc3a741d43a53eb10ad18e93541e224ec5a952d673984990af0d81577d1bc83b09856794d11707faac63a1e49a799224b51464916bc07f0a69f06f26696f5806e92ca4ada050cda48a9c90635a9c68acc753a711115c35488758a68256a32f4964c431d50c0a8c5053d1a41126a952270a309f69931c32194fd201bc3809db548a000558528441cc07c18856568c4fc0eddc04175f564bda148788608b71756367551a5709127668efbd60b389877001b948f2c50ce62c7ed63122daa7c1889400a4175ab959d09ab124bea2c9d3659b8b4861e482eded950dbf57a47c87f79fbc143d20420f4162f711963c47dcf7b8ea7faa329d6a70f601d3a1b15a7890804917c84477d95f916a3761e3d94a0b0d69d9b7c39692b7f4acb9091f87583810ccf67bdf86c4be8f08762f2c3428646a3d33df4b67eb87a2662353a208403bf59334bd9758a9439f8d8bdd45195f2255282a73456d168a2b249e8d180d5b310ba828685b3a1daba2fb88783bb5062c13b79c2b0c3a10085664377eadbb477329567d1158882085850b95697248c6271f44988218777d33823ad70791bd40e29825ed124b963e05d06547c740a5ab7a1488e38c464b53b6f016ba1b7648a14aaa111907846c5df162f61cc62747386915724a3b054e868bc04c934d64b7f2ff461aae980fa806cca7a9c4d7255564b420887946f7a72e4d1384d8222c70330b09c08d9a70aa176529f0685d087b8f9eb464a776f93606b05d0729fd2afa7969eec2662ebb7c7fc821d6b5393707acf25c0c2c81702cb195f8cf730e8a46442e91e18fc7577f4aafd6933450491ee24763bf6786d794d889c3005a323cef2a8863c7ae00998d2e3ccc1f5a6c8a933d5d615ce82af312990969c6288b6893c42142ad87ab483362461b87c641f646410ef5b393283230220a34730397188920b6873f16478331cb22a5a2c73273d865985533a1f8e109dbde719c10c8ed87a831ab65562751ebbb15d3d5b6e01f78db26a54e47943d6b31f916a552ed01a39f96dff820765d6ae52265010545162d509f6ac3f9b7c0fd0ecad4008732d6a9df9449b2017b389522f11870704127bc6d018e0a420dd441ebf636c31b3b63da9c00dc15be0b3188371bbc855254217b99294815d78194fdabcd1970e31e38d37b4b1cc69bf428514f50ac9bcca9125e6473028571be535fca274651752dac691ff8a28c555036378b260acb060faba9573b0b65cbc76b892425294d65658f4a1b3309b424c6865bf1ab307b88022087f97f6882d4360ecd91f3d2513059a784bb256e47670afd5c1ad5c177142a2955b082fd0b546577ca5286e0f1c85af8b0bd5650038609e8ec8344e6ccb6df93a056644cb89294fa19266948e9a561bfa66517a900b67f6be5efb853c703ccb4a296a493c24607a6ac4a749361d8f738080a80ca62aaf658b6a972894e6ca402af3c09d2a6e9c181005e0c4d193361859011173bc8b97755fd1085b52808373b29733a7d0488c5f890364abb9716920c074645ae023679bc9c2b3ad29b9051a94a124a43688a1027c35b90f9303664aa37aa92284f97dbcc7ad0f12b5b6ba38ce0a07130110518c74ea36ca6d6a44399a3983101458f926e0bb3357bac5a294446463814806ad1623185f295d27f2c913c9608314174b2bb8bc03a92db6cc6f044d964a7e3e289ea8f064d9b5c0d0eb43357495d09c0fbc4069903bcdc683763bc4c6acc2517b7c94e3e0265029bff55773421bc6143a38f57410bfb50bf21bafec948548a87667d95439bb78cca2c9da670beb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = 968bdb85e8be748513a831e247218d164bda5f1f8f433ac105e0798820c1300777ab82383d265ac6c7464c42f2f1b82734ce4208cbd57abb0a0eed81beea32d430ad955c6535d8576a4258a148d8ea33449ccf1e63b4bedfe1752a6006afabda3f7a6f6bd81bd49065357cc1a2b4252faa112997cb4d8ce361dd76c9dc1015368e8919fbb67709ab3dcb2cac18ad6e8c06e05d1586db41ab3555a43e5b0631022d04f5e784874e3a68b8a2f3ae31f49279fcb83c4fc1600870b1d25e433c68339aa9a5bcd1985da955149fe2fccf0e1c912b435beb46a083fcee0c924acdb192f87504b27018c27a2db9c71d4d870676631b4b94fb023df02f6fd2b97f84741d8ebbb055cb786d0734b83cb2bbb2f094a80b204a5a257c770053e94373d9e9dd13dd345fc4963fc05243ae659ab7be475519f85956d2640068e28bdcf7dad6b44372d1d032de309e4e228cb932bf12f7da347acce0e24bfdd89ff7710afeaa973f735d7d69574dede21e4099181d0c885be477d176b19e79dad497f8d46b8843456a5b338c37aeece04596e6ee4b74dfe3976449627deb97e2fd6ce4e903ba2b0adb9396846cfb0996ea32143c4188abcaa15b3a0f38a44625a52c62fdf3bb9cf81e1e6e0cbc102e251a91eaefe8a3e0c903414397ea25321672985bd8d91e07e297b7472e04fc481ac17ef4a61a4e618d2fb3aa728c80206f367d5c44c29ab4704a405cdff7c6aaa34db06cefccd64ef24370ba1c0d2204069c1a48f0556c7664cdd5b80600c466da748e4c774a4784e15234c20f7258cfd998d764eaf8359e69c3fab08b148b634257ddab72777698e63b55f817e370b804851c40b642df365fc97f73a0161140b127ebd3affa31da4a2f59918b095ffd877739e3d1d7af7455e99a5162c301a66536d198d18e2db6876e7ad5f95422a3e363dc637ce45dc663a975dc0d27b9e92008df453364256c3c12acc52e7e4d228c931dd5fc4465151a4d7b453775ea131dcd06dbd05f8e8a9001dcca04a23b2d4d18abf23fb50484a382e1c07e33f9a2fe69ab38ccbe51510a9389c2d522deb000a66d406b2b09c29fe4dec4cde29f358e813b72b38ca32afbb5990cc37f06cf18386e39a06cae8529400fd479152387f0c60d301344666765405ef92b98a7379e983ee89a5104cb3306a296b53eb2242e6fae55f04cb29d0c875bff6b1856439375ad697c88673e49b8753d4180db24a28ea0c77051d28752ac9cf6c571b129fd91c3b0c79b19a6b1afc1b72d1d986658740dc01a7aa7ac69144e99af53089e072be0f2d0e173f579f91acd0047d28b1259147fedc28d0e66589bea1207479f2c13ba9e4896d45a715e0aa9a401f5b5a35e29bf1f791d45ecb581063d6a82fbe7f623ffa5ebcd804932c81904a4756ab940eda4c4c7a4b69ea22701597cdeecc857b4231fded57126cbd5fd91da14548f5b82cf33605abadab82565ec80bdc6f63b8366f08a2bb9b252f33de69f13ae4dad178897f8ab66565b2e0ebc143427d35215ac75f4264e +expected_result = pass +expected_shared_secret = 874ac966970f29935db73c231e71a3559b2504e5446151b99c199276617b3824 + +comment = Private key not reduced +private_key = 07638fb69868f3e3f0e596fbd96933fec3e1b47fd93c9b5d5027dbced43f1b536d9b2d4bb20ff795a5dba2ffa9e8eb828b28448886db3fc84facad4275d5628e39c5b257e374283c513f99c0ab49b66b8bbb56a41876f4f919a2ba59bb08d855198dc2befc4f88ff5f59ab587a79c327d792d54c974a79f62ff8a78948f89e9a87b688b084ed5960ffe8b6cbe505a4ece2f8ea5a64c5aad6d417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3684cdb7b21df9fd2d3418537e7466ba6385a8004eeee137d8f82aaa1e48dfc7a88f902d5ab7e88d7e95952a55ba21dd9b79a47141e6fbf6eb7dd307b08edae3a5bc5f6b68581c6865b27bbcddbbe42f5bfcbff488c9bff705faa98a2b9eea3530c76662335cc7ea4ad07787f5ebcccd2a4636b2e9e22ff3ab781f3ce0883c1a2ee15f5dc9e8a94194e48dd1dd9cffb3adcd3cee9253d904dd7adc0dd63213e575aa7f9e7b5a1f3362dec936d4043c06ff476c07578bc9cbaf2ab4e48f727ae4e686a96b2548820cbd3b330eec291ead62f489ea5e632acadd1df89680cc8a8b53b481e9fa68e7db4faec3a6a561c079f882b5ca8cc942a8d495afdbd6de89498fb935b775908fe7a03f3f4d54dce9d5eeaabd3593b39be9ee1388fe59fb441f7e5b5d4253786a0d69ad337dec29efc88504a5ba5997070f3a61363e17c6b9bb59bdc697452ddd59451983d738ca40dd34e3f5988854ca0513edb0a6e1498988197c6b31df58e0ef626564ec89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9791af6d18bd399af676745d909f84d57b6694df830664ca8b3c3c03fdfae67b89006868a695f7ccd666459ab7f056671000c6164d3a7f266a14d97cbd80d4d6d9fcaca87db844a4faabe82e8be8ca895d82ac5646fcb4a15ee685ffbdc9ce3372ab95366cd4fd93d84f81af3001ea05cfe5f7fa5acc7cdcb462c33cb5f4fa6b8bb369d43ba68609ebaf536f8ed08463b19653b5435ba946c9addfbf02b04b031cc960ddce2e55e8d428b32b257a4fc83e3d3a7980e9dd82e934f9d95c32b1ad192af3604384ddaed79bbbaa267de4c3f756ba02e33107433a4e83fa7187282b8d9203a4faf94e851833d121ac383843a5e55bc248e425e16c7db4cc9ab6ceb0e9ea47e2b8de0e582c86b6b0e9d7bb46db9804dab5d038f6b75c815bf7d9b968d419832bc9cfbef6d5ef6f5d59d43e00e9d485d3784510e4221736c084d7cac36d408aa649276e9788b8602cfa753dea6cb08f1d7c7a04726f03225b3895b9343de47a8185cfc1bb65cad6b424f339903c0ac4651385b45d98a8b1adf8cd6bab088787f7feeb1256e766b43cbccb964354f7d94cd65550688f6948ed1b5475b4f5f1b95f09d16ec08b56c1dcd69f7cda7c7ff9358cab911087732a649d27c9b98f9a48879387dabd0c25959a71654d6f6a946164513e47a76edd5987cf364cd9f6b537eca78b9303a5fa457608a586a653a347ebd4dfdce9175b3a30127f53616fa658a95277570c895fca8973f4bfef3a344d47de7e1c99f7a635ad3388a527b034bf7b8e70fb7d2c1f7c23ed3fd19af37499dbe9c787a9409c82d29fc4bc7d5a2f996cf4d5da72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee868626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +ciphertext = a413be81047259202401ee35989d25a3856cd1c0260ce2391de323736b678f328005c821ad092180b4496f2129280f4f299404362b9d141948b6bb02acd5736559fc9039018c961dddd94ee559198471d4a049e547b5636cf8bbf7db1a90c72b870923dcd54b148c60c9c8ee604d30eebb6901e6df2596121826058d25029ae399c95f6aacbaafe34f118ddba7a69d7cd899b5f4d58d3df2a889b030ce9a7ea6446d41a60a175f127da94c276baa1edfb357d41b2857ad462c83d8ff00236d9bac59325e0c3bddcb37bfe0fda4e167fcf6aec149fe5f9f6393fc4715c6995d67f2b4ddb0c7678ee140bcfdd2365e8122ca92cbba1ac703357edf15210c6892669f1a2b88d792be7d9aa56c5e8df758abb4bbae83141d2759dfc4ea8f2cf00dd86a7312fbaea9cfe6d7fd3f13fc8cb75d252cb3ec7e7b37cd81d88f38ae593ede6f8a81d51183d7dc7f57abb21ce2c593db72f0bf779cccc82420f53c2fe364b1fd3cd2ec54b924a62afa4c3195578e48aa5f507e7928d7527d6577d3fca87e7b7b19a89f69f0018eeb36871baadfcc7094e344fb36481fb14a5c53c30867cf1c5c02cf6227f9aae8d8a12b24c5ac2b8eb912b87de8325409e440a47b5c74237179a6ce5558ee09101ca4e645e24bdc28778735abf98b0688f6289d503251582aab6e81ced0179829f7311731d0615d0a0d955978aafbf8aa440a5c85870c58b3e5c1ff9267f094b742f516e8e9759d0f88021d99a7fd65bbee801217276656d21f3734de0a5589b33fe996ecb99c0d8a52d54b39dcfe707fc11e35638a69d908ccb0edacfb2aa435e3beb981d3fdef59cade6f63cda056c526cdc55b87a3ef2638bcaeedf406711053a09d310699dc8e3d07acc10e1ea8ec8d51ab31c04ca88c2177a51193b418ccc4b2548ecda861598ffaa8b16eaf89d59c8403c39c8d94c428cf19180e1420287b455fb6e4e5bfbd383aef18ca99f810f6cea703be4b9bf0cb6f0c5383e83ed3a723a27d8e3991067656726925b20fb735b12752facf684e5c03dc5be7a63af4bd930754fdb5f749306c2cfa6e398925c346d9d572924b153b7673b7a5022140264fd5a0abe00b5d85c686f296fbc49dd3155ad2f748255506909b355c7060dded4dd2fa21c7bf681251e7d63289e15f85854a25b4fb085ef03a03cd050f4f5021d112f3291a9fd60ad01e0b5797e78d9b94befe9746d754e6ce41da34c57da3d7deda6b233082c4137614e964fff0e38472e36e495f54e2d2371a7581b694cb263ddf80bdd43f6383578b5e18244a69cac9cdabea3d05718f5c23b1d4ce6684457597d01284b38b9d3eb1eba4f5beff990bb749f096a30f1bde724ade3789de5ef183a60163e28f1584500984ca5153555c38c61649683a727921ffcce3007c267783bddbdb9de48880c4e8452dab29e7c4f8d1d5dfd303a908b1ce08be0b9fae98894dcb2692d0b32fa39da98bd4ff0ea10f0b438a4971a7fc47182fbe52d6de71fee3e824a39f19c27f51aec6d92bc7f8b8f071847bca +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 94b49ea435f6945f45c45a7d580b6aeff8bbe0f5342bb8bd266df12ad5935f45cba7caa6e09e4007fba79e9946c9433a87afc4202bbdcfbdd8af78975e76e9d368f78763ddbb83e8a63db7b6af7d24258c7ccaaaf505ca92cb853a68e8d4269be91fbecf169a05f7eeb957557787c2f3c7f31538edba87476b157a06095a30e5fb388ac2294d755b43440aa3edf8b7d9dc435b415a7babcbd4ccd93cdb0dca20bd90647bed6514813368a794d38c917e63b69e7497cde8c519b160d5e44d74f44966f6e3a5ab9ffb8d8e3e68d77599a89aed13cd7d86498d88eceaf7fa7de25d73fd4b62802cea903bf15e7cc3eac350bb63adeaf9c7594844795a9a6274aa3edadcd10891f05795a77b30add76b6b1a35338b815679dca2faec9c3b602b2332492531507f6535b36dfb355225d37e7c85be15a5976a8a6ad5efc35d4c45acc954368ba6df88a47dbb8c782336f7ea507a7cfd26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b79f729638af6abd3e6db9b82e678a42969fbe770fef65723f77da6437c21cfd3601c884a9b9e09cdb1ddbbc1a675e7dcfc76b40ef6f7795e5ddabef0dbd01197785765e3e05ac38a89d1a0e8c8794685c1ff74060d97bd6de68818a74aba5d71a8df5c86f79fddf14ce5eefa9af1391567fa15fe6ecdcf9c0fe7cf09f97d8d693645a53e7eb3d85d9f6a53fd52bfb0abeef9b5a4f78da74ffacbb713357d735a744b7c65e58fb7e27fc67a5b4edabaae123ffb8bb6b4564ab4fc2dc28b4981614b69bb188db6056608ed89f658d3d9afe0c7f6d4267bd0549afae27996196a6d6f86fc28cff731f7942543ccef3856edf9ad1b2be652a33c3e038ddabfcd9a56e2ce174315e67b26dac767f5de695d8d104bbae2afb89b88f66d27b10909dcce1581a8b8888d9dc1c4ea5fc20ddad5073780cb4545087c890f6b9b9abddac9f3dc5f620713c8b5ac3301e8715ac39d13084926e841faf4ea7bbb7913fed680a78c0c363a2527f0b2d69467b6cac5d894f96f59517fa7cabe4bfefaa2fdcc75cd4f892cec6184c5f962b9b73d663b7d76c1ea499d538bb45a4caecfedc8eb93bba5fcea8c93615648fb112dfe331eb2dc1566351f80606d590ec33dbac8dd2a3bc05fa8af514564508efe005cf0f799650159c40dc952c9a54c27f8e6c3a6a95efbab24b3ef6d5df300f9baf88a46644b4df9af4979f8ddc314f5b9e75a753a36510b87c5fa95cbf36e1abef245876003b54d4f0d8ef7ab9d83c5a2417de4b5cc33b6167f4c55faf55d84b85efec19556d83bda6b9dc1aeb6da734efd8a7a8e517de89727d94ff950af2b503988964f0aa227d5f3487471d3bc905b6672bf2dbc7157f9b7b7e479bd7a19f777dec546c624723af7b5f7ce42274ac5652a7c2d7abbf127ef2bebe2f1ecc87678ea6018d6d60cf39e6a8f6424419187bd22e49b8f27486ebf5372ce69b306ef8123eb57659b113da95989dba5d642468db1f588326db9cd02af60b21b8c4216fb883854fb173ea86e3764e4edd6b89468c7ba6d4f36d2ad436b945b8b44d9840f3139293fc49cd7659b955453bba08bdeb5efa91f594232a47c65c66e1c5c827afe79925c55ee4adb6dd406b49b9ca035467fd26c6c0b824bea310f435fbe8bbbd3430b5c39889e6b117e994e2f08823a33789ff858b72715323c6204a241d9835ec0da85c5884a8a96210219099c8c383c182632280356c1b4f298405258a170e81624e861fc1082d31867a9037e3b90b0aeeaa064d27020da7ba79398fa92a963a8a294e7720bd4cd9ea213f08063079c4d55b094bebc4e979444f462b967972e61206fcc80337911b02c7396bc64405ffc0b77cccd2ebc121a734037cb90b77846b2359c30a451beb20a6d72c238284e5df2ad1cc1a33fd5a104965c86251a596360d541240a4828231a827a0168b6d8ac7e27328173886453a9c91498765c2bd9ea9f666bb4a1d60f992538a1a746df845574f99adad23b9744afa81c7fb79a32b175706454438f46b8985132b8e1cca10c2b0fa011eab2428b88cfef9378a5228e55d7463dfa5022c998abd6354118b5116b3bc1004f0008134b85a1cf2a9f409a10e14b6d06c26d8e355864c35bc71b60d5cac33a513efdf6b9bb83bc880983682c8fb8a81b6927ca52e93835956795488181a8cd82b1a50dd18a25f35e2643cdd76c282e7018bb99624f031418fbc8052c4179b43a5998be9a20cd2d8a883b313ec282598202add6471971c88cd9607d3a8052519930bc5bc71ca4652352b4d02620b8d983b9849ce8b8935f1a4decc3250de7b0cfcb49eb7b74e0b5792ae97633b092081c3c6bf58f1b242ca07610c3387098ac3f0f9043901c614590c4ebbc64ce1971e824694a999cbcc430ae923a1432b6a4911162213c429481394a27006b9d48c0ab5801823d756bfd8c6919502d613594aec81f5669bd4e8495292606959292467ccac7f688333b3f48a39fce5c42c9c2653886a5adf4747cc943b2416348f46df5b58e4916ba64e9664a4baaa3e0a9652408c8e5076c226c3a7932c42a846949a2a26b4e2c452f86cacfe5c201ae1321ab5c2cabda557648a849241f077a799edba3582202cb27763047219f5546cf18819322b9c63974b322b949baa491d97c70f20545886c87086721d3ca2aeab441264b516975ed0c6044a425853528424532e4d721e85cb0bf65c26082c790765b062916fac4a0dcecbc2e900c6f600270838e2df20ee0a907e3613dcee049c445640362c980a292f123c6c9b5918f21443c996016c44d2a124c5925a8e0c48e89bb167a129fcbf67adb89903e1249f6028bc176bacc722366139858e583eb582ada714e79b5ad1bc1a6f18754e100624620968d0702e080befec425bc16b650a307802004c57590897c87e65347f32c324569051d798bebdb421eb28b2d1a0c662444c7db32bf97845d7225c7539f457894eb87606fa85b5e804053fb6ecdea773566c006e540ee65101d99bf314181d666680985c78b103dd00a040dc69cff389fea7c18e48a363b943ff042b476dc86be953a5925076cf749a62a77a9406165d31dacdc3a677b9114d8bf84b43f59f647fa4023535140fde04285921184809c5f193a7df45f62187854061a4d6754da528f3b71a134aa487d9b5f7cfc6838108b8b95b51f5540c9ea5f29990f7be07efd502461033f103723093a16dd96c098977f81330249183cf35a636841bd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d22cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +ciphertext = acddfedd604fdb81a6bb89518b9c4542ddfa46f4acf3a1ad092de5ece00c823b4938a85cd32b1c291ffc446adba2fbcd0078e9ad7dac7aa54d9d38d1603a0707e9bd77fe2a41e2d35fdf5d1c3b7a9c4a1a91a1d6b96db95e11df77af9ad3511abc41a8f84cd1e8afe8b6d5bf43a912c3ae871cce1ad968f2736dc856208ed8802a42b164238e7529570be8a3b57954d9b6409727100153df71d3e405a633dac6668440919fdf6692e39505a7dac58268c2b9eaaa0dcdfaeb2ad38d7edc13617eff27e365ca2e015f17804ef7204158fda049ebef27cd80b4d03416cf0d34fd1298440c807079aeaaf86951dae492efcf43d9bf52afd9eb2e2fce0c644f4efa8c5e74f612537d809a64f68145df78d458908e0e8c8901e340e11fa5c0ce78cd7e2923a880f4f069934b7de2a6eb076045b7a3b43a5fbb9e56afe3de239fcff2eeea1d75e96c64779d9713d43de1efe523bbf450fa8236b9b57def1cc381a798b3b77ab02d8a3e944d388932eda80f5eb542b6e275d8c6cb92b31f8bfc0454643dcb9041e0069a0b8f6ac1c4600d4f15543fd5c25453ea1cd5a3cfc87bee71ae1a955a60087ba5db2773fda9c0acfcf22b2fb0804793add6d44413930eaf6f9b2d8c18433da6ce17f9f5352a9922741be5558c3d4eb57f9642f9774ad449de5d672226163174d82c5a00157f4b69d3d5ec3f1bd5586fdd9dd1c9f4e50cf4ab7d60201c7e13c5a3475f6ca877319a845a2f80459d7032b0388742e101c26f2831b7dfa78dca4f3b8a127cc956fc013dc068498901eec716d8f5d8cf943892c98bb435a0c3440512e10c3c6d65926549309e5a83b391b06b2b5e8f51353382527557507654dd895f0b83cee90de518228950d141b968c3e4ebe116905b3d233f8febaaa7e83170d50227ad35283dd31ebd69ceb7352e3351cec82285520ae8d56d6f597e52e360cd9586d99eb3bc1f2cdf1a1917924e58d2db1a813024cbf02f5d0a3458fa55617eefd30a5667c988984fc6e61849edb588dd66ce3be5a52e42abf0a53e93e0e0b92e178fcdc1d5a092f1d9dc9578f555a5286b112672ec8ff7a2aa7ffbf23ab5cc752a45e0ed056b3beb9711b28e415da7bb31fa2c9b5227d5bd30d56c910f58eec5946a15b6af1f69aa343070aa2aad6172a98875ea2f1b33ecacf8c477eaacf56231daba5e91a97f869e0b9f13ae213153e2933f10e55bbea8b8111fcdd68655ce09fd893862dd26e29cc24fede5dedb2cfa720f14fc739088ab28eda8c5b36ee7cc98d104ba6a463e8f6de7b906bfe165efc1fad56c499a64d923d20f49648323527dd6e172b34d79517baf2fbb975e4568c40ec4f19054721055fcb5255a7249c60528a816df084c6bdeb1986207aae2e6e2776bad47c31078891e2bd5a44495ffdd7d0a942879b33195fed959c30dc688666b718d6367867667260eb23229483123ebec5cd2d78e0f99572fd293d453f0691d1d72da92db5c84036e1a0bbfde755c9c1d18eb721856249db963ea546b4f2086f1f4f528c457 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 734d8d45cfbe6e83c803eaf846d852dfce848ef4e504b5c91f774f6f6efb5107eed26fd203c486f73f40bab4c1dccfe2299753b96f7f9c0fe27cd6a83bf4d75a385782ab804b5fd972fbf5bc553eba8eaae7d7a7162ee3395f9f6116c10c1dbbc20b31c326ed4ccea5f16df20b5584abd6a546ab51aabed120ecc1323fd502697e9e6ebdbad346fc43824135692204b49b5b377b97db7b28c86956d77b2e5acbbeeabd95eeca479988bc69ccc9975ec4fa345f3c525434bc594218aef123957dcece8e410a6d6b9eebed9adb4135b56f4562f343aaec34396cbd556d7962679a76935bd16b4b4badce4650c55c3aec9bc2e85b548b5d3eb891b6596f0c54d09cdd982d98bf81ac77c8da98264a719cd8568e58f79df9c8e965fb94aa773b43a7084fc75f14e91585f551347f00447d72d934bec553c02de4f4276016edb4db77cdf8c546af05861804a5b7e9f838744511ac6c8be55e883acb7775b98c4b4c9c8789aef3e7f90dfc4127a6ae879d03ce3773bdd3938d41c53351d8e7dce5abe4cab5ca31e7e7f7aef9c8fabe4668fca5298ed166f09c25bc5797deea44f55deeb4c436f11f957d74876dec169c4d5e6c8716b3ddec6c3f7edc32fdc52e13650f1bec711f4dee37e11a76abf08fc8fe3e72d564e21e6a87e9d3b58f1e379cc8e2b7f4b95d56e04934ce75d7e5782fd4d7c46aa9439836453bdb7d9cef3bc1c944e995ff5c48b5c80fcc8a67f3e6c53ebd303bf0904456b3283e9caebdde494ce9f8a3f0b432dca69d0ba9c43d7d3e1626f72cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b773e822d5f9fa48835f9ad8f3236e5e96b9087d7ec9f36fb6895ef0048648adf5c933fec2759c8954dce7346e4b8c7a06f26b374cb4f8a6a7d67da521eba7233cda4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d0a0fe3c943dc83a9dab2db7095e7d8b6c3589b09fafeb3e534646538dfab023887fc286f00f46f8a46d476998e4fe7315f03c2359f9247bba2a15f97a6fdeaa9cc6158458e240f513274a2e3359d671f6f5fd44d348ba2b634642faf6c6cc6e6f65afd2d8e9abaa48bc565ca0ab67e6cfab112aad145deda003b44bd3879b4f6fe0ad3a58bd86a713dbe353d9f3309642c0e7b0bad3ffac4d12b36adc49a95ddba67ce8e306ef6bb20b546bcc55eac2b815fb38baea9ed6ae7aa87e4fecbc740cd8e6a3e04ff9e2d4ca0177cdc3dcdcb97d386d3f0005fb137578b03aef5bb5e8a5b887d7c9d50e00ee44696d8f6335ea81a59b87cb7547f4ed1ee59fa57d9ad0e8a31194247a6a9c65443a35ac36f1ebfa6a8559d0fdf511e6ee5fb37800ad4dcaa77847be8c04894e50486acfc3b8feabb8cf860d7acf734b7d0ab83e739244580653699c5eb7fc440b8dbed6cbe36039ebda6ceeaeda3c77a25b40f96763a47f51266ee0e5f848fd6a3a834edea49c4c24692cb43aa22067072fac2dff7898f298cbbee7f9ca68a1333f1942f95162aef32ce78943dd4d17854d7d9c69f6640ef2e67482df28029ea5695433763b6cf3b86756aae22a37f9f79f0c46ec2ac68a7e11c8f5505af220d651595bff5a35b4ec7538b62289dd1204db91ac492b610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78a4149cf10b6d93283050167e737596b711a9f32a0f6909975055ce6632f4b42cf9a2361cf69047b5bde1868dd745a82cf473ebb30d86a71793364f70b1255b1c2003f166683c936a7977df156a84051e69b95e02616dd3090dd38086ef3bc12353bad25377618965c2810fca929dfbf46f20360fc847818cf90dbc044eed16b3b9052c5c70a5a430441e53a5527a689f49b35ce82b84d6057c5269fb60c710c5731f431a970b86431125910277fa7c310a2285117b47b95054e4174a1eb11da3e3c26ac25619d36712b11b2ef7405bcb943dba10d50c0436b50de5b04d96488a38f53df37895ac20c10d959d81a29fe1f319ff871831d93c54654172a02e65599f9d820ab037438e62714be6c7d868b66ac03c31c8753a062318ca36b6e59d340b9696d47c38f115104765865353a05c8fbc4b0a62a96577e94c17094de259006f169e75b8919bb4c37df6787b59bec8fac999a90b73123a5cc8772ad67585c879ebe05b5c06afdb440adfbc4ad400d0e634822a843e9b165f2f0bb748e231c0e0ceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fac291a0bbe96e9ad36a4a1d9c96939603bcd76a81c040fba27a5a39a1c387cac9d1b086e512468d378e96039aae2622fe5483673850d411ab64b892f2c29853822eae76feaf5716a660b55c2020dd3323a150ceef9ab79925d2bc09cc6faa31727a5912a7f5e9051f8b94d8866c4da173d3f2a388e6c44218338cb85702cba2f602c24e1788158b0129e7c15dcf2cc6ed55c54b456cacc07d179b432a5aa63e8ac59f0b6979a833d99c13aa0c56cb65928032e2f30583fa6c038748ceb77a91c631dd09b575f13126f1447cab00bc9c85fc7601da44ac5fea5adcbb599a409bb1a67b24ef438d750bf87a8814df22449c9256da1286dc623e81546c283b80cc88c48f003678ab35380a6da551ac7041cd5112d59d15a80032c28b61a1bb3b8a7267adf4662b5963468b3bc5918418f980cd7db3946c5a67f864dc1f3adea12142fb71fda590e070007662b5c3b8b31af169a092a2e466aa01ae879641bc4d1d62523ccaa3ed436cc089b2621456114215d1a9eefd1016dc81d5320956fd942bdda40f3a033e5170ca6a2c57ce17eafc97aa0959cf37b92e789636f159faa827ddb895553540d52a61edc1b3dceb22a7231c48037cc78594718902333d0bc4fe6b29352991e2ba5d31217457007057b9d3c07c39b7c7eeecc222d4415d6d9272ec50b81520bc607592947c86d2612e434c22513235536cd08f10022b97675b89f1de58130eb6797380f6b68773dfbba0664bb7caac84f7b06711587c6ecaa383505f62751c8346bdd502a58e9326e4a0d2d29226f794ad0064b2cf0a56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b8372158c1a7bfdcb65d426458edbcf8797383e272d3b18bee68c4d74e25751ab1ce4567d66b714cd62a8e9b886baa812a9f50739e30f296791414727d55003bcb52ab6bb74cab215b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +ciphertext = d4aa3d0de639a1563732d6f6a1d0e8dfa86c667977822bd99f7fad9c2996b5b0593aad975d8a7257c68209d80f676f7083b5f2d2690067a9c639882955c4717ac9f64d01676cd1656a181124b299010cef7094772a6c83b4dbc15320a22b02de44da9e532064f3dc3b6e1e540cdc168612b4271849a1c48efab76c3614c173d973ceb61bef391eecd1e3bc8aae662c4d60db2f55458f4d13c56262961268f714dffdf907aa08a434d7b897d1ecfffa32f1c62c3487adbc6f3c6d6dc38302069e2af348d26b39ada73b2c5d927eea8ab080cffe74c50f6e2a5e2bcfebc73ec4f100710c2283b42cc8f3db9609bbe487d0ab933e970cc30d3f084b179602b555f797bc53a49d56a1ca53a8b0e539b2cb41a08c306a162b902f0e8475d0332ae8c2329b54c45314b598d11be48fc0f9ea0584df93ba3185c94c063968c914e390fc7b04202936acac5c8a7e7677374f62fbb205467697881e3d8ed60b0f3730eadce1d26058e58f652e4e00b9b8c2b94102d1fa39460973ca8cba348cd67c20aaa1cbba500a998b50d1b0f48885edf46b79ea816bf7b1831ce4297a0330521bd131a9e5a43a5d8676619be7a45fe29509179d8eea1d0afd63a758817c3c5ce5076f21887a48fbd2afc142489768ca4bd0dafec9727b1fa77aa1f977f7aa72b628290265d1d3a904f5b4c22fc313f5f75d1b8496b2195742b6eb017eb8d0c4d40df0913a7ca9dd5427708bebdc435ab096d6c2cace5d24e8dac647bd5e7e8060a81a379abb478702341f0376e2ae70de9a4e7ec6213d61983713fefab2e4f7e6611174fe4c0578435cf87fed3171ae5488bded533e9e4a057c6c79e37f93f6727ae9269d0c96bbde650e4163278b54ca865a38ad0ec3a04ecb2eeba9b7f1d55c84fffaa5603a662884baf8f715ea6a30d5350eaf6b4abcaf7bc2a3db44bba3f66e84d7c0ba4afae3950dfef27985198533ca5af7d59b4e89f9dbfd29688978c0bc639dc7b3f06536ea66fe0f7aed7d5eec6acca1ed5d13f4ec5ee9e94a7682d803477d0b31ddb77daf14395bc54cde91caff9dac3cb641a1b7354d1fa9e90756bb59617cf1108e2bfdffa11bf8e6565f7cf3df3501a2193cd03047a7e7b44aced6ae6381cdf440b7ed2efac1ed5f6889d69170490b57335a01adf88fcd6dfbf8bb1e7c97038b13e81f018868ed52516f6bad28043d48abc1bd69d93f6a192d3264f38fd693f5e9b43a81446079369fd8bad5197328691dedd297ad98f1684a03193c6e6ecc469544463a70157f644dc14c341ac3943f3920e9de4a96d8091b282ae5fd5d9fb3bcc94357a67e0f616c6906e555d52bd13a24b05be0866e43ea957b297094f34a3636d3d9453a34b6d1565861fa67a746d2fbb598a6f1aad8b2c7db65043c5b7bf97eca89e32588fe105aa6ce7e30b687194169c4fdc6729079cdabcfb0085d00de34ba57f9d8140ffe1087c469d7fd5af5242e096e18648866bcf24bb5e68bec64289ba207caba330b6c8ee82bd43bb71fa96977909192ef9ffd1ccf +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 549ad1804af31ca6384397fabf16b2c4b9ab7407a093b354f898fc6775bacf2931de0a501c5a7ea7ea5c3bbad6739db9fdad59d69cc6de9b772dcd58470544b65be1abb77f490746384b83283740f18dfe18dd46759b61e85d30f187c2293d45b22b4f9f3ffca44980dddda42e67d4504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac100da6f69f770e8d82f6157adebe70a956456c86e6c856657835970578b35fa87d8f79c2ae54ad378f3c6a13a4207453ff324f18de3d43b4d0a32dfb707ff4e70fe42cbe4a32fa3f10a446d7944428b66e0e1ad4b204c5994cd3c294927d6d540f836572793c882537643fb64e1d9bb7273147a878ff1bdbd38d8b631d4516dd824d9da4e249b4ec9cdf6b67fbb72eb7a84d89de4b49eac5a3cfc6ea5d6b420779a29e1c5ae98ab30f0ea0b45538caae4ce61c4dffa27a4e56f757a3bdf01cd206c5bf5243e32c47b7111771daac633f3fe32af8fcbe6e6ec92b4e9d1c88e7285b84d9a12e14897b1fdc0693fe9cab42102ab999838a93a77142eefff068ac13dc4c6863f8c7036cd0dfd87be9fca5a675cff4dae4d3fb28eb770ead4234a456eb889ef92a93a0d3ada816e599d99cd8a96881afb5e54d766a9c81e8af4f15cf95283c333a0576b49c569c99450f97e4160c4cc4a8f8090bc2ca49d095ee4bd6b3d11a6cd38f19f7fb4bad3854dea9f96feea9e41c564a91f9c86dd7f498f89d06bd47461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a55e3798ec69145ff634dabd2298488299331dcd3b1b3e06f34fd297e525587888e448d0f45a6158dbd7e377dd5b63e153d93fcc8bdaa563264baa458649ce7fa5826e4b9b59e59e764ed442e43c5093a2a5bc5b835535fe7395ec556bd467a10975ce273d4bb99fd056a6ea4c5ce09dd33e9334cf7f6750cc6f209caf1f7be47ac875c401e95d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ffdac4c3fba7d563af51ff8b2957b8aa5d63a65bafaf86609b4bfe21f7c02acfeb224465e2ce78c74cb5db4c0c2aa46456761ec4a528bbfbb909fc121aeb78aa5e7a29c8ee408ae7fab4fe0be941cbbae4c3630f407a2c23c4d10a58a8e64546737e53e6e766e0f42c523f236f637b83f3905f4a7812ceb8019a808946c11a54f8ca6c16e06ad9a685edb094616b8d383a79e482c61186dc2499885471942671dd722743347de3c8007f218cf5cbb48490e05789c6a5e85ecbfbc73669f249c11befeca037dfd15994cbc450ec4d868abc2ffad5b5058429b7bd4ddefc4e273da13dba2bec9be9d3db9f90b45aa7d40a20ff8200ccb4a54e3c9bdc5b169830d55ebc7993eb3d5b4d914a02d3e83b84f3d622deb0e3ac0a3ae86741f6f6a6eef27ec55e28b975f2fa8cf9ddc37473cad7e788b4fcd3acf6c176c9c255c4355b6fc0b84cda348e9a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c39289eb84bdb45813f6f5128556d26d1017ffaffa2756e1cbd0a1aef218adc198a6dc043b1c518e3bcfb3c2488a5c02c79393b65f39990b72df74fa77b814ba93784562e0794c179549fad927d9b4a25949faea67e908040a25908a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f12118e0685b09d30947ac76f4f72e89bbb7579bba13d3cd4e262fcd385eeca8b780d7b6d3343ca7ec1958569c49808b97586c263903989928ab9b63efac00b27037637897556b8aab33198c144d226ab9284541400138e03a31f10cbf1cc4bf633c3ad70c65218c1b18770c91d139971574dd90317a421b8bdc56c02c2564b2496793a27a12009ecca141aa337e911f0b448d913394ec1abbb46a568ba749f0fb0a2c4562637a220225a0afac0e9a53ca4f506391d7483932814dea886c89879237a95c03684cc0c2d2701b40e5b3a340316159cbc56bae84130f2fa830501257f8a8948f482ad194ccd4f6ba6c01bacc4c1b9c3188c3d002f8f18f62393b373396f6c510308b6754b8ca81f53d5a1512ffc3428a6c2a543a61fe1193a86b97b260339fb43a9f0375b1c2c62ddb4c1f6629db701b2d2a50577cc7d5d55a30766400842938d83a6818a128310d16648614a6b6df6b5d8d9a8d0ea4a127f4233b9a50ba539f5f01b62513a5c7bb8ead8463c0a346252c94f753a34751b078a06dd785ac6532c2730caef7249515514f8e18713c2a72d8949de781c698e708deb35448ca1df99b8e09ac4faf694ca71b7bd41bb7024c0435424831424f680a77f13506a56c97b6966afac4b90fe60bf5e7507e6a7093c47b5f8ca47d86c767455d645c502d82cf5b1ccd8880758bea855dc71b1c98494862030202c06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacc7117980774e12355af27e506a2ac63c4abfe585b2123e2404b9ea9753fa101604663d07e153c07b743b23c56b86a91ca34111803a1f5865e47807c012a81885104495499884b495ea3f457a2ae1363221b2a94be84e27cc9e8bca44f8fbb92746821782b3b92b1bfe87127f34076bd4acabf60e4f9b97a8f63008b584d0221af927c67d616bb9933be9486e38d7befda11a27175f670600041a6dbf0c9a4364b3ffd28eceeb0c8077c3aba19c6123a20ca72c0776aa8e21a582168591c7c1eb146ba820c9ea1aa3374625c8744612bcab37250ffb34a89d305c35169660dc9b09f7c960a4c4450b1a2e56088e8605fd75a35eb620c3c90b93fb001e03c006a15b67136ec1c354d405a61014821fa9590dd212cc6095dd011bd8801a10f08f15da21c14cacfde606ca02b7e2e1483e3514cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d58c033ba2280ec0521bc53dcc3772d48258593a5a1f9974228652b8cb4a08296eeae869c733a316d926d400cbb09a2daf532da06522da9694cec2a29cd4c87f6a6c837c6ef6182a30548afdb807bf447953a3827db3122bcc7e33576a33a943492a61f3625dcf412793996c664a4664b3666c154f90b40c3ec514c4b1a2d265a23b897177342b76c69637d52e356620f468480472923313a658683566dc8f8fc1079f248f9d8ac67d4ca703339ae28a86edb4bc21db231dfa970249aeb1e2138bd4791352151520a73b0792a0e77d4967bc8b46740cf5599d4056f382c9006b79938825dfe2806cb6afe7523d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258194391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +ciphertext = 72251024f554cdac42bdb223557f2c724beb9df0001783cf348f83294177c086dda8f240a793f879b84b7ddf199fab6cc89a5c1a5d9e72351a6eec092567a7fbc0f588b970151d55d1d8391783396c352f1842300fd934a2ad4a2627b455e47102c45e3d23b5ab6cd0db4b40f689762c36d0c90ceb333820e736fcdce8f0f683a3476602a5f3326fd6278ff073cb5833584d8a5317bb6349b6d4a0c86b4adfb9f3e09cad0c35acd652b16646150e40e3653e230fedace908bae8b9411a8b344b90708a468129781f42dfab8476b654ceb3042407d8ba005d7577976e6b5f918d53d3cc3bfa1426633efd8a8a211c57fcf3026daec0d1b63cb874efe2f9b0b90bc43421c39b17884fd1adbb1b7a27189743cf9b785692d2afaef0d8d7f3dc84cc0a04351085550a53cd764ccabe0dfc376dbb140562d8a923fc5d6478e5fa951c1797673db456634f948f840f534f66739943509455deb3e1b7e4249f5b35f0ad810cec14e275f9dc23b00fb89fe12c211f310620ddbb24871a15eee57527e12764f45039695780f3eca702d7cfd9cd85b2411bc426192d6e9b77d65b8bfce6fdf610564402e8be61831caf75fea911112cf42e65ac431c891c03914c1cf6cbcadaac24f654b4f853de2a7ab29f7dfa52b91efeefaeafda36feb7868b4b28f8f987b9117d5049cc61d41b253e4ae985319210509b25be27e4c1a5220503726318debc86321cd1fa4158b1afe3f1677f1474ad276e7adb6ede24cd85a67023e85acc924792bb15a4228bc242426b72672b1a443a188a2b6f95555ae0ea41e1e03a26ad7f7f3f0d1629fed1002e8477693f97d334caa9b448e0e09e9a1216fa03219854beaebb0e932c4b51f9c7f8cb869b05c5c401b3de89cb08b9bbffda04d6b675988fabae97a16c5991a9bd62aa093bbcdcb80f5251def293ebb350a4e8834ecfa67f716f4553beb0731069ef5ce77af83f29cdb75309f8488a5eb7418677b4cffd27415d4057aaf750e9da84445146b21ffbd57e3ee5fe3cb0525a9192539ff44581b96c6ad6131af9578b2d82c0d5a9e9d165d992f34e7f24805cac07d6595734a166e946a7b0e13e972f3a4eaf34b82e5c04f10dea2b31346d5b7321a718f0e162afbe6f80388ff18b4f3d2701e17b9ff3a3b8d62a412b6bfca7ffa618ec1e54c150e2b7b7b94a1ef82bad5d6659b22733105632a0949068b2b78751a660567f1f74f79f81d4bf35250fe1cac57c4bd5bd2a759b23289188444645af0de21274f92c5341781634c9ac6548684a9ffb2960735aa2562fb02562ab8b86cc5cf544e71cc1348f3fe5c25e9bb086e40773b2a860a12a35799dc602a6140e6b29a249aaeb366b2df08fde7ee87ea86a40f195b179bb355a61f71c40151a3e4bfe5298fec2146b968141676c9b24e662253f5579523621cdd775c56257f1fb23bcfbed0fa1a7381330f678493794a0c6d79c26a2171709f615898ff6a71b2af60e410b37ebcaa0de88d54081d6659a670b9d4c2967364f2995e744c884e1832430 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 944ab696cf345bb67894d451ea2a5c9266ea5467c76945f379a5d879899c9cac9d05e89cb37f9b2bb477259f3fca357623c69643569d67aefb2f9b324a9d8090d4c5f68388a624e163c931df53dd7039d951bd7de51daf914cde5b2e5c3059785ffd5b824545acadb95f7f79d1c5726b59890c9fe31d5c62e8b3be33c8d16cadc322cf48a5293c71eca570c9536f958b84663b1dd5bb6f37fc3f3def014aa3ae05640ee9f200274d45d9bf451dce8eb7fd680ace1efbd4cd9bd02df7f795db60681bc9ecd387fcea796ff77270bf9877f895e693feb7fbe79a5956499ca3bc03f93fc8489d494a88668e6614b1f4a8f4f12a448c3ea4297ee90ce3a9f73c6ffa25622d7a504e0694bb7c75ef7ecc8f7e8ce9d57ac87ae17227f1e628ef157c333bed98f8a6823f765b61fd300f4733cf75f40c77956a7fd213b8a33183ea7c3e937104becc0995ef67f5536ead9b246009f855cb8faf210eb25686dc1553d74e7db3c588f79b45e37e16ac2089a4c70d38b877ed308964b69af211187154746c27f59c8105981c8c7d0ad58717978c01a66b5fee697188bfaac9b9289ffc940c53814d9f38459f5c4dfcf7dc9d6be8f3a13d8b0da45c35d541d2346baf4e73fb0c677efcf6a94c4159bf8d4d7b4b106fa4ab06bae0c4f209bd99a174bb4c58fc7d4feaaca49c4b5e7114a5cf408750e8588545134f83a67769cc6e0c4e3bb90dc040a3e84625a7ee34e34b8fed60be571ce8fdd1d7c5fa1d3e0c2c4416cb775baf8df48643084b391edfcaf49f78e9b3ed2254871b27dae1c6da4e39b1f5a8473f68dc7153caa1369d8e9ca38176da57ca8d2533f02816767ca8cac19e4c17fecec8ea4ea5da930e14d3e7a876c49dba310af60d946a2eeaa479888011db7942f7676b2fd338357bca38c4ca5d88a5ad884b8b4c14e9c09e93ef8aa658ed77cc175ef4cb38ef61856bd6c965b6b6cd61beb1034888f3a7d555443f0f5cc29d9ddf5798d6beeb4730ab9af4b9beb8a5d2ab48761e188cb9aa95ba06b28cf4b89d3ddb2145a4339a53406b6790b5e8f559d2ecbdf30a9cfa45447125b733101f645d935e0075ecb4996e395543b7e643137abf3df59e042abd70bee92716fd74dda107ba6fea19d8ff6759aa7fc11e864ee739325415ebda558d4b37fe6dbfc337747a7ef46f5ac872d5e5f3862ec09f2e495ef98b5adff961e5a4967370efc4865f06a72b4e464d37ce4ede803cdee7888b681d45e95c857a47b764c6799a87ef7327fbd403a3ee2909e0ee96f8aa43b3346e5bc1ff51718df4ae4ea24e3c4f15b99e72f536dd989c0335f25dc682e47ee640d99c165f506e687e18a883f90882057ce4385bc08bf8f616e8e1a40bfec93670945b7efa17593c4b7bffb76f9b8d5f533dc50b065dc77b409ca8cc0c7e90ab6e614d5f8af3deac131ce9e446fe85b4d693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fe00f6207e3b2086e3d2ed74c0867d7edd555fe5cd0b41bfa83baf19cd643f1d83ec00cf2bcf94fba6a8262d959c9fb34603ff1082c40a26dec46c55082ebf70933db0419d558cb6d6825e73525725d8cc0bc93c881c99a1614e757d6a05ad7ea15e887eb14cbcb226951857be4b3bc2a1b578b148e824a2414412a3d57c8213793c418bf2e0803de4a16eb9c8b5d53718d38ae40299b89793f14741792bb10d9c21d5f06633aa3cf1cc78d0dc99983076f8756b2f96b2095e0b812160fbb9494038a88057671dc692f14a956d5e6565ff752d28237c70b8f8528cb1a04cfe5e6495bd3b46a3264fd7364e0d54f2ad27dd27b022efb3d3a632a7f99551bc3317250207f2658f363164a9631a34b468e9b3c9b34b27a3a02fcbacc516469f69b3a51554b93e05fd6dcb098e8af8a3681ce89548ca311e2f5421ca1496a532366435cfd56a26a245ba68655db99cd113c1ad1170bab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b302c037bab4954627a2363020c4ab5ceef5aaf2e352ded62fd6a52acb70c84723a527ba34f179204b26ac10692822ac66cc56bfeceba65c33295fb805c596a48a0c59477405c21ac3edd2c27e56c19bc84d710584ade48647c681746038ac74ab73591fde872ccdfbc3cb1218fe12acbfec9248c00e19424b1fbca70fc5193151aae1415416ba2d7faa6a2c745cdedb94295438bb182dadb77182b2be5bd1ce0cc028b7eb71ba8cac8585cba3ca01620b63fc91bf3c210f67c65c92f893fc616158c104a5799720ab0fd907798f0678746475c8502029865dd653209a39c0c362258a266b1b244a4f42b4adc1c6bf602fe61125c3b989c018c0a0e0c73e35abc97c9ee695cd265909af82548b865eb4238376a6ab53a6baef185799489f64e200fb542ec3d1b42e8b3960e02730936d620360ff4570b4079b369a83629b599e7b27ff48c37f727a4f93bbb2d4b7e1c73fc0d6668e53c1efe0a0b547b1f38c51f4001654f45bf0e5766ca1c662f2cb99a6bd42a17f89c80a4db03c990a81ae9487e1a52c13720266083e152061aa08c03a7a703de58251f129546a42282515a3e27195ca97ceb39b00566cf4acadaf320d5c88c75ff310f10bb5ad738d38aa47c945235e1730b6cc227a194dcb04ce046a22c37319d910060b594bf8a64f2c4b8f26000031948046721e6546893a341ed2c32804149954e3788ea5054c51a43da89f9c789eda6727bdd4be32b15d47b9c327ec68422813b00950bd73c96c7175274a5ea8bc128a7c0993031b4e8a5d3c074d2d1abde8239d5af58c06509b24109c84297e3feb447fb3926dc19f39211119c4597711a222b341cdecb0698580e422a951db2305d4a7a871967db945a60439de206955c371ea52452f865da438130d2b8eab3669a97911258b08931a2e36c6c390b6845e8076a0d621d7692971ba71bda0b8aaf7ba0ad3c4f05ac23621a146c68bbc501854062b924c3a64916a1b9b19ce5b466f8672ede621ea987f83495106dac22ffab6f4a5cca797587126ce50589f68a2084875bbb505c7ff46922eb496da260e3719cdb2f23950455dc8d36e3932518bc11bfcc067ac533360b86550b6ad09e93dbb092be410721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae1907adea5772276b2929b9507db5c06041e5f9846506055417c6fa091652a4a424bf6396d46365bb40601e3a55801b93a1ccf39126ba7f025a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ac5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +ciphertext = 6416527ba23e80f4837873839feff13b3514abd118bb91d6b361b9bbd9abad576f3a4d8db28cf4461b9371ea96971269360f966cd6220bee62d94f3fdb9857fb66b0a9245fa492d68ee1a9e8e2a49f1610391349377d1810a55258b3529d1195ba41b6642b7c8b5ee3e14cf59216a870790088bb0511ca47eaad07326f2596cb851b00fae41118dbe6f0e3563fac9345bccaae3f1608f10e0541022de77c2f820499042e3e0398e48e8df6cef984c91675c3ea283e00ba9f12e7f3f0b5a4e9a958d648afc3e5012af630b6b64848036d95bcdc79c5d1b11bad1327853623309c5d0cd670a65d64a3737817f5961cde07a2d4adf8e4624f0cd88494b5050ec665fca1991384f9bc93e0c3be752f94d4d0fb3908fe8ebdd8b8a9968c00c4482ede3f60eb6736dd4e6a33e44652e82a4cd16751b760b784bbb778663bc514073a93be9e9626c7979052816fd54514611134fac5a6a7ad1b5c8363336ad8bf44f05daf59d6b66e28f86d1ccb6a776622114190dfdd65f5088f82f6ad4df28369d7c9a7f67f12ac36f143d9e2ebb990c4f87c4442e81d16e8753457183dc14b0dc1aa803a4b016af2bdea1b90e888ca5f15f5e0780fb6ccbe45071fa6f73035a547d1eb8318f735b15b9dc465e6938f5454808358bc4444304e82397db3d1f2b06fb5aec777e2922887408eab4804499268829b5b94e66e75b01e4e8ead235be8bcb68c801d9a92adad2abac3ccd87a486bb4c17d6717d3f679e0d8d549af5c8fad6a0a398b395a57715e8a7ab3870a475d5c30b917d24e69bf0c9fec18cfeefe54953064a1c56c00108f82df8f224469e2fedf46e2a8cb3a0105a3542284611ad45433f7782b9e879f483f4d5ee87b481f8b353741b5565edab5b252c73988c705d7adf1c3f2c87b2f9bdcb94ca5e4a0c5aabfa3ce67e8cfb8f79f43dffb385d8ebbd4e76ffa8ab641a3c8f3bb2291cda186160abc78169568e7daca87a9c536d8a7c345ccf8046c38e165488301872b1d7ca223782f5acb7bb664ad8c7448beff305147e7bb663483899ee1a4c481761f7b65bdc9c0d4396514d48f22ae383c39c9fc650b7b7f166bbdd2ec8bc54161f7524ac69a9fd9c538f584a096636cadfd633d1e64d5e89246a08a51a9c334608631c2687d63836f6fb8dd515bc7a4e769157499638d2611b69058f2615527a04f4ff2b60360e46e34bef1c8e57d499850f44ce7529e80ef0980790a8925184b4b22049b356f4fbfe293ac054d63985540cacb9f25e9180b626bf1e3f5bb3f413f090f5d468402edf672da22212f2d1214b760944f57d3c914c042eecec08aa5d2944fab51fc833d9e374f2be7c5fe94296c0df98392592e0a6b183242db0b124ea728c44a5aefeb2ac1c1437bb8ad49fdacc3fc482aaef9e814a4a8010fa2f0d0cc6a88a259aa8c09b7204e09a71fcf5a0e7a801c3319369cb933a57cbfcceb64f96be35598b4d2dab925014efb66247362e5b61cd56471a3ce4399ede77b09879ee29fa51513d4532bca164dc19be35bb7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ac65af9fc8b906dd9638374e58c551da08ac4ef86a90fd4489ba46294ea85e9d7ed0d7de1a89d297bbfdf7d6cdfc5c6af523e44ebed5deafc7600d736de9e564a79668e335fbdca1c9e3e592e73d60066b95aaffcbf55474f9c21cfd58f12e457586766fda4fae6fef64a4dd4a3fb07ad8ca7e2ad6662730ea7ce5aa2cff976f552323e76bfd4fa4a989632de492566adb8bbc3fcd4f9cab9ebfe5860f886d58afc740ad50a46d7a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661ce1ddd10d6bc31daec249a9b3a3ea4d1c57904dc6df923839d9a90aa2b93a87c44b508ff6b9f5d22e679438d64ffcb9621067b75477fb7e5ea1d3b9d9df4d51cf874ccfce2976562752cbfcfc59f57cfc60b8b4610a9bb36f9d19b9745034d7d57289726ab8a38d7a6c99dd74a5686619abfffa5757dc79e144940895e502beb8196f493f4b7f4b9d681646ad7b193586c6cd5d9eede2c968bd35eb8879ec368ece8d08f70dad3c22b05da3db4cf05668f8c73e5c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af5324eeb5e7534fac4de58e741e48b4154dfe4743789e35dc39c45c0a15cf42e7b3631b6a8c0971c8a34b830dbbff2ed04bbd6bfc5949c46e5b02947c73e7a0717c6b61ff679dbaf1afe4c55768a08f8de05868aa6ab4aaa848c79c0ef68849d7b9daabe367afce273e2c168aac0facd27855e2944b67b938170a9258f6739787d136e466759cf60ccb7da226b5a956925157f7fd48953d6f959c88c8784a8a5223ec4ba5a6d757b4321d48b70fb554e8ad50abdc13bda64553cd437dca92f36ced2f7e17bfe7c769a2bc1aa6c356a5a39c69f4963ba6273db933ff1d9af8ce65b5b9058f1b9ae64bbd380d4fa8eddb6c2b9be9f26b557c387e4db9aeb92c4d7d1afca1e35f98ed5cf69dbc511ac5f0bf357f7d525cedf7b36c6781c4b86c0d69e7b89c8ca643fb9990ecbbfcc5a8a5a6bfb0451d76ce934d96bca900dfdeb6e7bb093675e97b68894bb03068ed8a1f3643dee18374e15a76ad1c28eeed4b691bcce5df28fdcefddc71f8685c7e883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5058ad886d86d460cc4a3b7e3f4fd4bdebaa93b943c48e63480547d3ee8e8fdd9cbd63ef46c0b69a265aa3829ffd6a474c5aa530aa63d6a0c8572d4e3719af78194367405789e1f749ab5ad2af87b362067f3ebefec01a83acfcf6a49dcb5419b351bc95e08c7338fb933c8e476ea950891f75a186c9e9f99dab63634e6b7314188bfd686d74fcf03c7e542c6fb1c0c7712745940f7b923765e46757de5b1ba2f8e34cf585adbaf980317c9db1147382946c132f3c3a45973b879a523855bf0ef2151bce631fe6dedc6c3457ca03a5eff45b662f79a1a7a5cefe9a846dd5774c8cfa22f842e4e465a953e4e036bb56af787a2adf102ee14397fdae74af706a369ca54259c8d578bacd4987d0871842b98cae2ac3b572f98f145cbaaf54569779b61634f060c3db2a58fdaf335c9b6dfcd328f96958c69607d90c7a3926c7b62f36a5dbfb87ea15e8368e55e8e94390b6c0f808b91c166577037d86b5c9a75157e73ccc2e138518ea98a246145dfb6bac9b2ffc333c0ba5806047ca9ba8ab797937000270e773c9863709e59786f8ec948ed27660aa3758e33f59140e527787fa74a2ce22a4a8f3037a26903665cbfe8a0677ec273f590d64c97f69f396db78448535746b43296bfa2bf0a251bf986a524074c1f96077f5219cfa9124d1458520993f627aa8b7b6a0f191683233e0ba6bde24561a666fd10151b0c52c9982c301e0970c3363de27825a5bab078848aa5cb75a90c1cbd24cf67a68f3417780cca947131e4573934f9959787b6320a4b47bb311048289e2c915e35344e3a144e2708893138a15a03fce3816945464c229c587093b5cbbb519767fc65c078d6c684b8b81c1f9cc2b3ba749fb3074623e3c9124a8e1a513510357656b37087bfd02773fb59157eb885e1501740483f3ec070bd492dfc217d7db99cd7c9d57b937297634c3494deb585b8c93cd4eab1865f8a9c8bb15dfe583c7dc0427274f8df3c693fc351289964a89a3c745967231261d949552e0809ba9b7c5d258af579a4515981e991d93154bcaa170491b06752415b1d52bc2a98b7f39c5b91a87eb759a9a4537218156746930a347a5026911adc0412f10a7a7c200a1514d500805c10a276c327e4899aa3f9b95d1ba2347e0140184b1235a719e6c4a3011576235215d77084034771129c33199b70774b2130898a0c69d8f39c3a50b273c665dcd8031b4454d144a4356b9c2b16641311856cb65466991b06d1a8a74a5aad6b5b935b65dba8374ee690cd1c701a5a28b41732b5f88a9ad919a7fa563bafb529885488f544e1240b3cd673f94ebbc91b4757444a302578aa953161993cc918216bc56ba53ea17664bc5b543a38c3516d4063c35695791d8821240bb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58e507f8a105e2f71f6095621e354b3dec1f9c979ed7b3aab56b4741110fda601fac78c2edc386669118a425c634157875f61adf10c43d2184d3252edeb11a61eb67a349405ec74b9fd307558a887efbbb46c904f9469db491605a3582be433bed57363426055cc4852acc0317f24d89903a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5a0029c1513d5a1a98eae78713785bd4322261d90109a0806e565ebd9308849cc6708b536c83a2fa35995c819d99b850251c1d50ea902a053c7ca31faac37bcb1b40d6123cc4d52002909d0ac566f7d75dc89998036aabb267c5aa70184ab4cffeab018f195f62879be0a51b42b843caf7c494c181c2f06866cb2287a00349ebb136747da52a3c4a3c581798c413929ce3e698fa594f019579ae329a22d4af66f27b46453f22e61aa6ec5d7d854ff6d3c3d4117be2145b5c2ba7a57ac968a5ca43b461f808167fb5a76a942c95145098b95cd46439669c00366960e2162ab613c5ecb151359b093c27c04ab230fa7c0074684996f44939c81fc31373c8231bd0b6679991a32a031002b257b2f31101317b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659c970f94d0942124c17ce3ad50d5a7019146bf51b012d1cfa0f59b220a795dc6b3d7896aac680adad383ec46762b669d35909a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc962e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +ciphertext = e87c238704de82f3b46046f3501bc2f30e57e653fca6d1bf693945caf49a924072cbbb21838970324ef7c44537a67d90dfa64ad9048fdcd9cf15c7cf55af3155afbf69a498a3deef649022a61ab18ab3267c38707d732f479fbc7021038b52e0da50bfbeff9208eb6c09cd5931feed40a8ad8a6fb95fda48a911bcc1dff75e952c1c4f8d66cf7a6c1788de249b7c559c9584781ee0814b9af67205d76fb32df7dd1e6bcb11628aeb198fe307baf9db66158019ae9866263ab0b7bb301fcb36f5f78f7a70b14e8c75dd505bd204ab79519b563572b14f332f7b434733dd3dc06c968540585f07fb2533c6a4599940b92f0afc09afdd0f0e74c13368267ead2ef18b0f4c0799a6abe14c5fe16aa5c81e9189b66c8b2121e4b38422de375272e296bdca2c3632ce6e8558dc8dac44971fc55cbd9eeaa9d91f699ff664b0e8eb096cb007556afd783beb895d382aeefe1a6004f96f48cb0adb49a75612235a2ac318c9ae11e6261f2b90d975d866fcd1d7f330a44325f5ca0f792f3daf1035a5107b90bcf9907f9a3649ffaaf4a31b680184bb3f76899f834958625a91652485d84fe7567d667ba84e7d2c8bd3296a0d1b1f59975f92ed1c16e0e5cb83437a6b9d8c200ccc2e38e53d3ae037869e018958e6bb473d6a009f3c09714760bb2afddafbace214b8e119f0888f2c6b9343b9cc907633583a8495dc4178489e95dd68460b892c27c0897a2e6b2a9499515cc881673577683fbb28c8e7ed4fdaca6a58b8e98b78065c5a4b2b3414d144b17ba898b8c268afd0cd6e1c7543801a13b2218b75cd6ba9eda819bfedd4094c3ca7e439c1e9c4a8df0e6e3518115a3791d8bdc86bc712b613c7708d36f94cd95775334836f39bfe641ed8a4ac9d7e3c9642ba5ba766296154b6af09baff56b7da6c43c848b7518f445f87a31554c90054dbaf3a2fd1b1ffd91306a5888620b90838b7be589c9fa15055aba13b29e57f8b5dcd2dc7dee25d31bc977c05eb0012c261a5916cdd6b91ce7c7f3bc4662bf500d06374d59f0ee21f35cc04ca90ee4951350f2fad026ebaeae4ac28d36882b824e9341dbbbbf2b5406451c8b4eeb4defa8c572e9c83c6d60b98318369b5a2bc88af89dcc6120140f4c5caf432c67a6c51b2c47a3893f80776a6ee726300e5587bf3743d4372bc9e1e3a53bb583412297866c0174e4b81cb4d2363bd5a08355e3573118066eb549d9969205a61e8bd916be103481d0a8fbad57d13cfa057305b469b9ebaf78fcf2a333783956e2cb0e865fe4e9287eb5a608403b1353d389391b3ab57010bdb0838c2b21f8d7c1c063de9a27f4d600aa82737c805b0f0264cda08a3d315613f8741519e9dc16d7cdfab9816e2a639b5ec31cc7f66782f0e382dd1710be19610094c61230ab72f859ca4ace9a63e3dc1e101a95e206d832efbee6c3c1819da9d3a03c42100e309dee54b2d8817bcec51944a39aceb7ae0423f7f8fc7a55970defac02838dfbbc72f0a84869f3f177bde1e403784032e71dda78b484ec1eab5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 67a93bb27acd00c9b95bad35538d9c39ad8480dbaa67a9584a56d346ffde5f48ec9b8f710ffe709cb5e39309e73467e9be3e44b42fea8608c0a59de7963387f7b3ec5febc6b6749e6bd9be3c58a9a77b53d786ff5854a3467a85941ca2c03873c0458b950f75e5ab85b83a5c2027894caff46dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451a2f761bcf74b5cc8569ccb93917a748e93c1913f0e4fe381e08ccccb7d903975ae25689c137d9c8f9d96b16a26e4439c265fa098e94368b36efe3871a7aecd54ca0c70974ac936e45dca01eef96a14c7d2075f999f6e841dcba6d0e71fcc4d6e14a95b1ddf517447bb947d996176bfdc5beb53e6c0ed34a1353ee34bbf7d9dccd3ddaa49e3e4659bb8d8a3f509addb06a3e796ce65c0628c817393bb197df1abedcfe3546d8bbc2519d583286f6f59da1bbca6fbb653ee1c3555203353509ab14b64cf9af9c33be70978d5b8d85e848dc4494279267ffcc485ff8b2c7d3cf08f00f39e52f45701525e79a5f62d705af00ce8dd413c12f37b605bc32eddef92b9ac99e4a34fa1ec8dba9decc9a3dfb37517446908c9eb1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d29f9e68febfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c9cfdb3ec750b18fbf2cec89a6f8c2881650e5c7ea0135c865bb3fb12a4c2c3c917d655a2997984c8557edfe943436a9fecc5c858d8e398decc27af51f458334f59bd40bb0d808ff7417ea5ae3c9439541aee59c6e46a5852834ce67e2b3665018154c5339467e6d6af189ccf20c68c583c96d9698161d9cd3ecad4f5ab0a8bb8a7b68359b13e9078a74069fec2709a615864422cada3a7dc8ea138ffc25f2b1a53ed1d7ed397aded6b782c665fc712e6679bb4761b6d0644f76d553cd703897c6943a86aee2caf9a7ac99517c23ce6457aa069b6fd2775efb36fdbc27b02fe6923d14b048af5cdc6b86d20a55d96ed8ff276f121a352e098e5d4cc3f09fb3a1c4a38244621b055d609ef189f6941b59f3300bebb0a442a656655455b38c6ffded5640cd4e36df6cbf4c5bd65163ecd8c95281efaf13fc57c977bbd1a8bdd263d96ea98c3ab33a516448a94dea4b24eae213bad2f640b2d5846c99a2588436106d4333197816ba9dd2ddc427c5b8d3a6b4352d7b8539ce519fccda67a755d6a6d7e8bb6ccdfaf1ca7283e797f25ae043df9b6436ff2abd482b94dbd70a3d6d64f05d04e3dd6490e3dc38c1236758f65e462be1ca58db476875c79f508e7bb90c53d798ee91714e642d88506c17f55ab9fea335d8463cff4a1661c16ee4c946ef651b7c5f07dc42659ffef7ef58cb79e445536b8948142cb4ec16cfe6cfeda659c2dce4523473f3f173fc380ef9a75f5f41ed3d6c073e05476253bfb0483c4b88cec1fd8c972cf651eb9684fafba3f96fc861acd8a01ef77c14be7cf779081fca1e8877a499d9efb3ed815cec21f4a151b8860768405474e9a1c8b6ca4466389a3f6dbb69e8494d7b25a4eabf34a8e9f8a26b946f03d6b8a33b0bf8b3eba9fd68d3e2b4074788e69d1a6af11c3b55f8c654ae778fbaeaed750bf405eb362461c4a2e81885084505c3862c3b647d181805205ef3e4ca5c30c46a0c21eb97700b70c2bee78d862b3e19dc1e0cec0ae6998a7b3c4fdac39a950027fb2a3bee027a8e54b4a5b981bba01badc0b5ba6a36a2913f1c1a046036960790ce2cf2583e6c62a778290f242b49606ecf24b3a0dc023b22ad8945a0b8dbccc9356475b36b2a990d7435b12e1536a21079fb7802b998488e690f763646c3b66adfbc8161855b20ea18afd87229d05e60372694e4c4c6215344da04173559d7954b029555e6ca4356f6cbe325a39431a64df06e75c63ed0e40bb0cba6ed68bc7211b02f1165c370ada1e0acf4ab61c87cc32f7017b4a26ff8cc0784f76047316af6398ddecc0c62e9a37fc4ca685017b33aacf597767312192cd330b2f3a84e0bb858480a63a607295a39f61510dc2c6998614013f45d319858da8228fe5bb6eaf3b03aa60f4b721a3f046d3088671930672c61c92d6005254372d8081be322ccead06cdd472cc5a481ee385096a5b8ce64b57781cbfc4457e917162da007bd7bad8e3803e05b08876842d9e6a0a545407a5067ede3510ccc4478c040310aaf46051454d855d1a5521e2514af676846650e0043bebf453e7488b6db8aaefcc16e26a75c52bc0ef3c80da3bb39f73b9852b54d9c606363438c45dac4ff1a1913d81b9a80544177ba7db6503a04a5405299f80a83fb7135fde04f8cecc0962461c0e80298d219531c9cbf00a3bb5b84908b5a807739a63485128512c0478084c8964f9064cd4514ce92c30454ac25b48919b719c5a853010a2eb712b80975660456562c4c448c39162ca63aed14af7f28875149857f9b8965bc1d04cb8ee2e67c14a493a3822fcd0a2dba2677e719b8f2c8bd09431b82ba56007584beeacaa1f081d244b0d771bdb0c8033b18ca9597443ff8cdf754569dcc2dc4d4c212e2bbee88925ce73034e19167cc7ac46059cd3b9ebbf6bc3a476f08438c61971af139a248821002480f42c2b9c0979ad3bc6868565ca3fcbc124a7548d53f56b51c9f8aa387b59b07638c7aa45704420b3c24642035a7884cb42f877260c29697809aa7482e3fc356d8ca061c1c443cf24c4535bdeccb02c3e3b8b1d90e5b47bd11615caf849da5811aa743b9bd7810c470187e81af9bdb4d1307303f615ace2a58e7ecb3be260e9f7c1e10eb3a84f207d2e75a30c7c741ea45fb04a9473c1425f80a9186a7f2625ea6abb4aaea3bb50602df23acf8e452cc01a909ec9034acb47b969d904213f0a79edb7766d0290005c954a1da0155f7318be854fdb038d019c1904b714f0514ac331c3813bd703b45076365be4b47ec510a9f585907bc0f461a6befe13a2667593e12134a86ac139777a50ccdad16b6891a0871621b387684b5226368400164b29109328f672cadadf7648377cd11c9232094165bb1cf12f694f940c3cd784c84925ba74c8a49dc27cda4c553c85334a860a8a55d8a75969977ad1f505b9b20ceeceb24a262c707843310f39434390ea5315a67491f0592bf722a1c2658c8a720991b26561e14b178c3a1028003cab8b69f60828f47b876d43d3f193c3820804068a5cae76dc3f27f5f1323e6a2797b9a13c86713a83ba9c161899cf295cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c284ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +ciphertext = f030991858a580b285c29e337892c953d068fedfdc83b1997d21c7cde737d0215a3629565b8b060f17033dd24a7c957bf76f490c814636e745689ec0582d17bae213f6986f88f9cff9fd86771b36320483b6dbb019ebbe8ca5642a4613d9fd3ebf436beea3590b08f411287b8a0a50a290621f0430364129c3ef1a5730cbb1ec741277965299bcb0b1097a9f9aeab4b4f1f392141897963f1f0f6768a763af9033c2d52988fdf794bafbd357cb19a101a11d0d35eff4039cc8142b834dc8e60c6d87304f5e1065cb982c5d1e5524d3f32b72fe65c42f8ba83be04f54a0d336fbb88a75e121a7a5a895e7a3c1ca80d70b2463b3b589fc35781cf2b8e917139a160522f88188bf92188eadd1c964cb5f2d3b14d0e1a1ad5bff6a0a5048d2b621458b1c088252b5410fa7bb8ba1d9187b90fdf216871382560943d7ffefb0274662982f83445c112a0015444415beb57bd1a6d282e097f0cd3cea94f92c761c54e7f4d3d27482cf2026d5e5bdee65ab969f8ed3d7861947bdd20a7b86b2116772168e5dee105c59cca176527e8762ceae54fc71bb2eb1301b0a3b5d77d26c4dd3326f5cd7dc535bd4e3846f3c4ca211c4e3e61dc276a0e6e1a5b278ad02762a2a6d48a6d06f73334ea229120a9a8ad71c6bef1beddb53478d1e2af606a955ad8d055f12e79b1733db11b67ee5599340e36cddd89d3cb6ec842dd39da1ae7b9b6943974dc24c497cde4263f56e6bc1dd309fe7c6a7905a6080a2dacf1c71d703c6e277c7661c7ee1f0e434a1241ae089444c31a971b141bc717bb10163af514547d7475191aae32d3adb8bcf0bc49f08b40b3860f2ba046ceef3e381675f803cdc9c4f1a0a4f8c1b5c06cad2465f6608ddc6f104494906e79faf03c3c48b89c613b016e7529e5e6494668cbc4092488c1238fba0993a81df3a3b46896a58a44848486429342f4c823c96de88c203c502df63fd6a58765a2ccf89dcdfc2b8e11cd8521c270ab50d3dc97e66a01aba506c713ac7550ca174b51efbe5c90fad46db5375f09ce999ee3ec2f30dbc5f5dcd04224827bee9fd94b56d4d5f0805300a3775c142e7a1e81905ba012c2e62000c9e2a6c2436cc919f46361c0287c56981d40c4d2c571dc7b566d189aabfb904c8177b52f525cfabcd37e22801e9025657245ee339a8f780d6103f2ebd613b7276308fb3eeb7869fe5a7038a0dca12abc39d0e6802317789514a610b265500855376207ebdf94423005af9724744fb94ce218c2c87e15107d71284157ccf6b6ed55d772b4efaaa4687f1c5a0da143ae00687c749a1e9a869cd356c04460868f581771a7e7da3674d221d074fc2d44edff15932008efbdf1ea5f6a023d1e7c67617701b6685f624448e4d2677638558997f0edd44c4ab4cb9a895044f00056c946e07936ed11aee915fe25038007ce395ed773bb281665b87920a7d9ecb49ed8e4a0d9aa277f7e19b5bcfaa45416a7437699ecad80b43e16948c2be55f69f99e7e849f84b92f45f556389008c1a3b89588ada52c7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0fcbac2fd83a9eeace0215c785ffd261fd991c2f5897e94ecf93368b79565b478731537eac74550cd599d5268e04af5cf327606686ab8864677907a3c3555018b478fcfef5498652d5259a32cfb464ace4c89bbc5758a9b53c64e95bc9cf3dc30647fd431cbc643cdd61ef5136c3919f3bb48b38db9d5ca0b21bb4e26edac49aabe00fc9fd66420b475d083e918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f66d4863ba6ddaf97ee39f38ba79eeed5d96e9b336dfdb24dbcc9feb8bfd77ac888554472d7732e7492c33e302a073680c684870b86a05592355baf272db51ddc7b17c9328d7a74da6367d9fcfb87f9f21c297b5398cfb56ce0e8a68323aabbee8d6c237fc1920be90e7a5b959ad2dca5c55654a43c84f16b29f522ccfa2ecd5bf875d62cf5683993eebb837a3ed8c7369ce5933730667b7463ab7026848bc9cae4617bfe89ee7acb5ed9b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895401ef45df8a3248a9f73efb441b564305ec48ac3d5c69d37e846ac9b78af9189e5e82286ddb397936769be7e37fa8ff7a013d90c8ffb9b395a4147db5a39cd7c2d8314637f680ad6bfd4e6d8bdee55df645c625dbef7dc4cad8c6a5c564ba2571c9bc9bfbfdc2d12578c8198d4aee414cba5749e7e2556a537b4e31f4fd85f904773558fe2344fb229ed1ae4de22123d60cca4196f778c77cad2ee58b6f33d71a85b79d2fe5f0a7c8745abcdb768c3c36d42d09a9a0355a5c45745d1acf53dfd5b949acf68eab75cac74f2364406a43a84f69655e66fe167643addd16aaee859f9da4cb361f8dc42dd7d2a79364f1d664528b6cec667bf34dd78bfd6a0b48466dd9db34ea71026efe37d8ba3a45ed7023aee75f351af5e4b9efe7fbfd9a07654b0ccae85014ed7206cecb05c8f77d3f762c97db08f355daafcc46d8e899ee3ad8b3d5ee8dbcf6a1c2e74cdeb87d15236d70943dab8ff48179f890a548d7c69a14fcc1166fd2ca4941c4addb57a452f39ed91a94781c64a9583c8d303cf1484cc6159b88aa3eaedd4f91e097982efbd529ce52a43b97dfafa0b379f2fd6dc226c6e068c792f377b9f655940d73702e4ebc525d86e809f76c53a4c15a35907cb2fc3aff19bc5f984d34677a33b648322cc9bfcc6b947b5346e02d4424a6f3e534308a5f95327c9b35f59ecd4a9521f4b93a5cd31b6f4c1204dca17b9f379d8e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b574dd683b7a460d9a1efcb5e50a35244c94320ff01b78f6311673832ccbc1794feb9e7268f5323726698f67bdb41bcc023fe8929649ca8fe49393845dcbac7fb58582964405d4adec8e4037a39e512c3fd07fa22ac7de21fba3822b493df9983866412f0439e1b6e3924d42ca8f73913e949b2780d8133e13e632fd4f81de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09f3d4210d5cce3ca3dffff61a809bc5dc44788bfdafff49f3f0e56e7c4f8ae1cbd339fc9d818844d47673437d8e50e6eb9cbdf7099876c26729f443e7cb3b9666441dcbdec8397953f586e3da45789c28969078e11664ca1554eca81b9542bae2ea8cc12b44e81b3354818141af0b494543d4674160a086f7e8755a87258e7e6a6aeb96955286924b42636e04583f74184133d8acb9067925f4969642f274085f70fc12361ff96c3130b143e23797f2a3a6cc757c97454cc8aa5d9c062f9254f4cc7335b44cb66dc712b4677c290ccbba08cfc3948c535be29f44736a23b4c8ccb3978404e419a08a67aa555becb48bcc161cbc5492b55e3498e74bb515c28a7a44a3afa0148ec3411d82a1ae103513074a13938a5fc17dfabad006d90455b4b5e45079d7bbe956c7a18a8bec9a64c1db72544cb00c6997d545ac7e3bc5c6565885536af486417e728cc99c78cfa12a1f7697f1ad26efeb7262800ac4e0121e766aa9bf0a74ae635074c62fb6ca79975761419b12a985ed7a2c8788c9020462fb5764c087681be1595a5ea4ee7234aa2d22f4119b559a536e0da0e8d0b2e493c2b5bd576459994acd684a81a0955684818e1b88e348446a22c9143a4eefc7d8ec678624763d4548fe2451f078582c93c986b0417e1aababdd76dc0532e252b59e47370e81951ef75ad48c223316a40237152e3508ec164c7375594f73b5f0483c560f52f250aaef28431e9d1b2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a7fc02eff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968aba093e8f42dd3c7cd68c8028a90cb0c93cb44d42ef9d15e6ca978ed5b88914c4e20768028f2c927a33433d33c5e6a45a6c5ae8c252a83e68ec121347b025865f26912b89a9da7472b75b9aba75581852b97d27ea7c9c5c7e8bebc0094c01947f43a2c6501c97e43231310167eccbc4c3a2022839584a12ad5b51b4cd308c94302e58c70eff7b24faa051cf548b5a73ab4254179eaa038ec95d4d4182d2971084cb33a6ca1106076dfa76ec0c4b3bb5c7266a481001cad07d12051a77e31603bf47c62dbf959c89774587111db1b038ae834e0a08c27f2b772a967179a9bada1ac12bcb8fd3b06ca44b3f11a6762ab51a9a0b67fb83def8c9a712a1469b719f2557e5a03c6bac808d0e0aa304955a3e961618920d0bc2347c74ad6725a9a855d1d8456d2c26addd849e59b7ce7c85765064ed6d63039e368e9f18d4fa11e16f8cc88bb3ffb40b4c6269996da8a6b5586365292b5b1c78bf4161c171e2fc7a6a8293a96d61d683275eafcadfed74473e30a1026809076a1025398b745be723a78e008c85b558d2b76392f5015d1024c171c0fc6c7c0c0e631bef57166e660269231c3216fb08b6cff0a420aa413ec1285b7b5ae9fbb15f9fa6b8af29ec061996a7612de524c7e0724766bb51e1264ab50c3a095815645b1d1021060b90c96555e8a001044d16cffd7719858065efca6c2654ea25506f0541fae242dbb154e420c0dd4e13a79053b431b7c00768bf0f781810a0832a2b814c5517aa1a0949523e12aa35893912256a7370bcd9faa30788b631b87731cc5c831a26e8f48ad7cf9c935301aa8cb006ac59fd2ea5bdc1736b2a5523ff3c4d8f429dc037292e863a087bb29cc2732ba30bf11490dbb1f3adb3448d6110a774b25d242602c250999ce69d1b32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +ciphertext = b053db98bcf8daca0c50a98c575bf2272f8f0c70343d5f78e97744c670f9d436142850638fe135a85d212ef2b4d2e23e8ba9a5d1327ac7a55454f9e1370861409b296ee2dfc6e7a4f1e5cef633489948173be158aa5192c6a9ff129e0b63b311f7595425aa29dfc758de1629be6d167fc58a65a4252863c5016042409da5227fc1c5334fa809235721f6f608a5443a67dbb33a1e5fa690cd34e9accadc99072a1db81386fd42257e1035b6fffe1a559b97fb71cab8e8e922aef2141733d39935d754e487656cb3b9b2bbb0a5a7c6bebaf62f86a407fdaf776e3a973074cdd2cebd67bb2305d67db831fee54826cfd8514be7117ac424548de1ec0628594062c97b570058bff7f0b38b25d57e953cb4a6d748828d56d643b1fd2068983d138e0f0bf67cbccf7a5ce79068eba43bc77d3abd7222ec5a22568874281ed644d5f3627156d35bd56da1e59fef74ce30a2185834df0f74d776f4c1661f6ca1343cd1149624b9bfeafc0e0084a3b68887cb44d51b7abc7f79886fe6966ee47144a78d12f99333a8a56e2a40110b7c505b6164b0a812590b4dd89d66583aed83348f27d88674a26440d423d1ead252edde582049f0f332afbcc54b4ec1ee81554dabcc8422dbedbe38f9c503722f3ca042ea0b51300d078ebb9663016bf61344f26d6bda836cfda3d06c3c1a2e8ec11ba197105b75942938117811cfb78afb5264f02d1c3a7b8cd72406ae08fad11966140a1ebf31cd5df8bd203453db15ace5e8f0a6ed9d36e1f98d55610e5c048c93c173f0bb47299e8c55bf2b2e1276ea90b22473e8f97a7bab2758087067da3dcec80749b66443e819964882f886bb9c232ef91ee1f57879eaff19f8c7472a8a709b3466801ccf756fb2ba6142ebdbf39643530879284ebfba338053479d78eaf70edbf439ec03f92c440aa15bd765d49ec0c580abf7690efd67068f20b5aa5537fd6a44dddebfa0f91bb6124c2bfdc3c6bb0eb6ea3015e202c6a5644c627963d172168c1b522bec3d6f7c83c02936fce8f3e774d91468c652e40c30ce4628927c44790f98c024860b07f758f1e09df4d6e3394d4dd1c0c5403c2c3a208ee3a2948985354929a90163a00e86b481bea2b4f14de01a0592a80695b5ae23996b1ddf4a712931612af6a6fc529f819b8361b3a8e98cd82fe92005b9c147f3bb4dc9d3155656575de568bc2199ba234bdff2ab277207d8615902229c48db3dcc589148d1b33b1d0594da5b27612a996d33b40ba2da0631471afabb3d155b2645958eac3bd6841dae38dc0adfa59b5e1aa809f888504448a56a3c822a613c998535c3aad312a41385a42dd691f7e9bea9dbe2cf0df32a86199a3fbd537aeea46e7c2768958912879115e2dcf76ab592cd3992036c83e2b2c562ad99cf42c9bba8b96aa54f01a4ced5769d22f51826b4217b2b47f721fc58d5ad5016ee4606b78e93194706332569a673425fe02bef35f942b9637c0f428a54f0bc190b6116aef98a2965181faf2f1d31a436e002ae9ef0f2a6bb912046ce +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a5c798161d819faf7d27a945a0f6619d83ddd196b6f4ae58a4c48acfc8fd1c34854026db0cc665c43c4c0e4567b46867cfdd6d2d0ff9d0b647072f7593db7392395b7ea953611d5c1cbd5472787430654aa03b6e895cfadd3ad467ea51b9486f3efe8275cda2079459df3b9aebbe5d203b466eb4f6911572252bdc8fc5ea31bae42bdc4142e393d3d5f7c94ea03f796e0cf7cc71dacb47456fdd386527bccf6e53d13eeb755924a22e3a55f74a8974b38e079d8349fb3da5887d1a14ec8acc6f07a7519856f353a4f267d7600e5f43095bb013dfa70ceda3fb2bb59993ff8aa68652846ba60ebab3aa574bdd8bca9ec8b877e7b87a45041657d0264f36fdc2b713f4eac43d5a2fd2cfdb9a7d35748907e086d6308d3382d09e39106cb28d947ae3bc389ffe8b729ce568436b3e08d7450d9a810deff65dc7951eee45ff812e05d8bd55820a97fb90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2054cd37b87c51436cc83b884f7634a6a5dc419684af3b78d420d64681d5f763e94144539df45ac7fa46e728e5f54df304b474a435bd2518bd83b058aed078dcf86746313bd8118e48ea346596e3560ca722b1f6dda147af8c5733705bc8343331bacc5b5c8de424ccf6114955056329a68a2a74d3d65197c21ead2a49dc41e07e4a814a798a434145b9e3a5c31aa6e4cdac8a8bcab6b5274490f5c45b2b3d7f59fc28f04dfe3acf068a5826e8466542559ea4d9ff11b463e9a4eba1af172ec8ea643fd3a5bb6663eb670d5fcc2f8b651c5e3e60a9e6479536aedc2cf56a9921669299b6b5399537f2efac368e1291dabc6945bde69aadb9f552b2df19a73de26e4ac7d9b5c7469a960ac64a7eef7981f96c54ae5df4c847d16ee69dcd30b9cabc6e58903c5adc88882cbce47f2888263ecb6ae97a9b2baf45f23ee2e2939f5c8bb8f0cd22cb578b9babf90ebd6260fb1923ca88b35c424fc65251f8fd1d7b5cb7e9f5a9a538b5ea97ababce08bd06ec7d1ad8490b74462f93648fc39a2004db6ea5eb4c92e9ce49395891594353b92b6b496d09376fb28711d97f2195ea5fdab80cd5fa6353cd62f06c80f99eda3ad7573c4fbf0f6cd5d6b63fd5bec5cff572fc8460385a642f6f90fb79a9b1cb18cbcb34bd87f7eb595f0598c687d9d731eefbedd7a0eb6616a88b8e33571bfa7597be4cbd6976b93f3fc2c088de3ab59dd0ff44e553a5b2ab143c46df24fe1e816aed7edfbf7ce3fa7f8b282237f249aaedbd3a6fe8771015ceb812cd5fe96e02c1bde7e9b961d2dd0c834d8d8a8aa3815529218d3418c49e176fc7ed8c3d35763c61d585a78664fbdd12a9ad2f35bfbd7e96ee6cf98dc296537c985577cac3f4ed568353ec2ca8eeab4bb1fef393d5b3cdd25305b148fd8bbe1f60b5871e9c9359a46a5ead03e98b61e8fc51ce9f62764301c96f68db87fa6273f9fa3c35b2cefd92faaf2f74edf73ab5a09e8517dbdd7d5cc770da5177f6c3e49348d138d19836391a54954ac4a0d0f9b154ec37965422019c2ca49cfcb8e317b3eee22faf297b865da163a0befa9dc25701f7e847a05754cb733620a824f19dd591c51c345420f2f6b8f3b846fd356e78b87764b51d1dabf923518de898c5e7cb5e0066fd69522f5889dc05c41a472c983583333132052a1c93a464120b325764b8665ca42555b98d8d6a93c88a0a383ab51280f52873f2be26e12c131677027c616711d478342cb424b0463c88161ed84bf6e869abe9cb915d13534d2756dd72343359e9911624dc7c6e828b19d6cb178c43a5ceb9360d2939df2744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ec91e52c4030f5453e6bc9103b9c19cd83e69048272855b11b8af3edc09b04ab31179bee59abc76726fbe9612d271b7010844f62535f2f30d8417c35f17c1619b055fab6a0f5458568c753310299fcb335a7697e7cbc9b9eb1b14ac2d0ddb765b266b6d68bdb5b0236895328540b20f91bbd2910625e674b33a4f8b6c1b4f66c4130c2e973ab72d809282ca63edab71268c02a9d020bfc805410aae2dd4b699448a56049d1e9a58c5fc2abe159dec69c5027099a3b57d3a2560ce24a6f5017d32e00f3078b792309384421878cca555b7065d57537c804e10bac052788769b7c1121a78911a153fb56a365a2f97b070d7b61724d0c4d14c295d78be57a8aadb873d3af6b74d020b8654cf48543de8ca22371a48ded585b7073ecee0c44eec27c85b5a68f6b454b0cb10692039cc68ec2c2bf892804520c71be5b7badb807b4059a3d87d32548ba3e4b698ca150d784a8c2c35a67a8c92c68ac0037888b65a4c9800ba7a1ec050627af648fb61c87cc55b8243545aa514cbc550a8804c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6326e0bbd4402dbe26cec08a7c1a19457bc2677f15b984a74fbc52cdce48618d50c47400011b392908ac2cf08a579783a80fb2990cea90eee90b7dd81e6cc9c961372d8c720d7eb223d5a6a16d4571c1a93213b32289934f7b30a63527c6399920086940b7696503e623e63a050f4b69810b6e6f6729e5782b572221f596a09a1879bbb46a62a955043a30a2aa3e62e02ce1ab6f3d03693a8cb653e361d8783ffa37274ae06a3f2292f1a6557182006e493ff2653437a64dbea950bf6a8ca8836407fb489d42a6f6257770310f28715bc6411c81486cef3cb9ab500558f070f4a15817f8c177d63cafb176caf3b2b1cb7b7254c18fe15111fcab9e9a9682f41c9fd247ec532ccef514860a3fed330255323dafe46eed198041d732538c9424d43fe2f5481650470f08906791b2bfe65a445bb26ac87d9bd04aa648a54dc13a137b60e5c2779fe4b5a866620dc2829d42384aea9ab1552fca920f8929b7baa059dea53e6a5b3e492a6e45b5ae11f6ad24d035d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124a81ed4420c87b0601de23e3ccba915faad0c2b47ef6238dba9449274c64ccccd85e91712470e8f9a2866720059a8501c7762c0883cf9827bfd62bdc0882ee03b457be2b2794b8becf74ec0da4684282200a294c13c8a9ff376c1187911121bdd886f27514846f740b72aad5544cbd97a7e208635480acddf404fc067c82a45b5c97829f06abca5201429e9a516f66e65d07075cbc0c60c2a9734baadd68f421617fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f616553b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +ciphertext = 4d372cbcf55aeaab39558fa7f1b3936da31e6679efee4b0af81d6b6e94e485e0f79a1a54dc8358ba0377a92eb5270b7b0cd814e464e2ee1ebba10ebdfaf6b53b5875a89fa0b0edadb5a60d815bea517523636fa18fe1780d152bb90d47d593409a2fdfa6b39c42214f709a86ddfa81bebd97ad6d18719d107dbc838111987d4f721746d75ceca8fd414f4055d206fec568c13d1ffc34ba1c243899bb5c16cfb6489c4cc018d39eb93873f520333d8cdef4fe3b9fcc117f291c2a2c1bb9febba997341404360213d9f5d7d80314fb059f57e12c884a4c42f6977b5bf3ebd6e0136da4065a91d9665cc141670e492beb0bf2d1fad2d536f2c0659a8d367c282fa5f117e0d4e0ac05610031e5624c61529b144995c155430063ca9a5e654bc84b1ecf790a635c3e5c3dbb1f980ae8b80c1b2ae9a48eee5a0f5e2aa0175eb19531a7ad6995a2d5a62dc236b596e9edc0c2da79aec60e5254c748ca80b90623f2309201ba88731d63794bb1865912866102fc732c88fc9c511d3a86648e8a5c59189941e694908ed80b513684b0cbba9ea16dee6cebf857b8d791175d623b3eece53235086b45b78fff9fe4b742803ceb85518009f5d94cae007e7cfe5cdfa2aa07d397aa97ac75b53b722c4d488ca391ec0c9f3ed196fc4326eb50b3efd27d0b34d9c9f200d7c74d0e30fc04022c331b55b0d7adfa777b0cce009786cfe71a020e33835012da068158102768cf441a078e5b9ffd6a6b1281f2c6159f114599d1096cc74a1980aa6ac45c8c4025067cd6e947c62a908be3a033367f1828e846fbc78bcf0be2d63a24ddf18336b8524c927a03ba76ce527b84a1358e3831a76e955a1b937e0ee2f006ab0d2dc886115c4fa6c9a7c831ebcde5b1aacbe33a82495349bfca371db6beb88e8ccbd8bee3585bae39a435c491292147e4e4833aa80ede11d1b98651e6d0525944106a454d76c3db9d74ecca42f52805037575420fda0ac6e6be3d798531ec283916e76159c79bb054ea23c24a41f124e1dc887e6b45babb35248f5c2ff7096a458acd6430f22eab1e5a6849fe783e612bbe435aaab7bf6efdb27220279e7021c75ceabc76422056a322afea422b17a8abfa6c3160ba885b3e54e70f3be0e304724cbe24d7b95359fc04642d3063d5191173a84f44f1e930c6c2346ab973ea722dee19f8d36065596e83d7e532505add1ad3ebbee0315d07a10c44f288a7c97ffcb03b829db5a01bca183ecd2dadd64bd2dd67aceeb0d34d039c3c4a2ab7a65c2d7479c2350663b754fd9e063bdf4ea73a04cf1cd0fa6782d46a9a834936f25baf39f0367a3e53298259a48cfc6d0c9ef767c30cd175dcbf92a559cae64cc9fd71eb630dbf78d9225e5cb216beea284440ac4497db0b095c094daed5d39695ae2360859bab3cb62673ef2ae5a1d03c4582764f2270644326a0c4143126de4d4600baf1ca099db5b562f33e9e35504496be65ba3e80f62ea820b8f11c91b64a53e6bd53ca5d62be0070762111804109bb8e1a594e5f536ecd8c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b04c33b257b19945fa85b55625fea1a43bfab72c4810b839b2cbff51b5d2cd498aa258373eb3bd44ed3974eef9e4fcb61df589878d9ec4ea4333659f03ecdfab236cd4f8e5d3f9524f9da28a4adaf869735b46ffed98378564f9700cb815c43a6e75de54e6f67a93fdc0385696274e1e73a12b5960a94d9a4b4564df9d9b797771b48397835f6fd69abf516a73f9eb813004edd71d3a6e67c6734e86d1d7d9d3e9d142bebc1d0f8e293f4de4846bcc6837fc243c54dba144d4dfcd7ff3fd19b8f55ce1bc0982ffd366530abad387946e1495a4cd5d9cfbb62b28778905ab7d576610a74b3daac9768ad51b153af7c6bf0177a4074397bf5ed411cb33ddcb89519e990dfb85afee5e9f288d01ec5628034a4aebd1da19f83493baffd36d225beefe09628aafafd427b82f9bd4ea44319f5ae6bb07bd220f6f2ef550b919ad01cb3744b37103eb54e634d0e033670025e0776698e28b4fc367a77f1b4690dcf916e8ccf1fa55aa34950157f4f1e66ef7ca8283e9e7b60ec931274d9808a8114dd4176bb69783c094bbbbecd5b90fae4e7cdb9768498b2243f283f6a079a9e988ac6a85bb591fff99bc67d27b0ca9932a41c15ce93467374f133bb8539c2e5e64f01eb70b5afcfcdacdf694ecd835c4f5ee74be4cf6b55770ac04e47666a431d669fd5775a71749923cdb223abe36284fc98dc3aa2a41f45a4a299c647d6738595f87f7a47b88faec6c088c6207646d99cef5f56a2f0fcd3ea85202c7725dfc99d05bfd537ddf0f89366a3a83f8dc74e5af7fc58a62216ea63334d3ae8cbd0189e49b94ef5e0ba193fcf37ac57a4cd5528d1d545cb75e36bfdc3ce63951cd9a7b18e0b95ef4f4bddc9ebb67bda9b2ac5fe13e73e123b4a858a7e60637a32eb856d56cf905f7c655e4dc84f9fe783d56d249fd43e33c509f56dbfc7aa0683803dd4d228e39f829ae363cef48096fe48bd9756c36873cadc64ddceb8d94e6f8925c1b81ade69fee64f0b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd54eef3590d681dbc7657a777bc267637daf955cd93452eda06efbb90a83f95a9d986fb559ccef8277893373e701393b705a5c122ec3646ceb364367c83444d30fa438eb3a479adbae24f70cd495563a9d85c566d9e6c467dca66a3f36370693ad5f86a9a3f773af5d64e9bc73ff7979a65e0c98e98beea7ee2aa494fbd46e4e7da3f9ca0f89bf34f79e8f7eb41db97a3276548376ed277fde54e7a4dfa088b8acc5f02f598d1494bfcdd7c323fc5ef6c3b4676d6b3d93da2e69c96744095435fcadcfd24d3d1610fb5c4b988877ccdb9233c490a8b121ba7821b529de85e648e68b0565d50f735d1cb54cbb9ecfc1b9eff98fa654ef1e877c43c6e47a2b8f66196346859ce5344d208253ca429f76b884dbb3b7a30ac3de983c75ad73996adb62de7563ec9a4a715bcdf376dfb6433de79ec54e660f4aaa4b194d15026b618a4e5e66c90de3fc0b015aee63b5d8b3cb9eb2d6e45ab4938bc86fc54c7598c6554cf9ac35bf213c9dafd144c8b56f9a66d382778b28d666667caaad49633a8f9857313e8eb033374b5cbebacc7f453ccd8e77c5a9abc12eaebc1733e5a1278bf11b37fbab1db212359473012f3b545301ddc833c69a75afe16744557b5e28bc0ee895da16c2c5dd34fe6783949d555e580c1be7994bb008daf27a47f554932b87222e82ec670490ca5139ff49d5ed896218825056a8639b31d3ac8550356a408a01404c6aa9c2b7284e7c7c27036256b7902445dde00630d81930f4ccc518b9efd8ab24fc16a365b8068c90f7e09bbd23c2a6ab12792d245551a9894f704042501c8fc49eeaa0132701e29a3c97834530a7c61f1b8440822cd1bb6b11dca2a5951b4deb0b1268c2f5aa8cf76a6bd0be3013a37ca1a903ac634405ecb3714bc54610baa63bacf0a263d8cb018b03b0a286083998a7e8b2a573e570179712130a19f9ebc2337d43926f9c96460996cc03199d81a0e19259da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f1f211c6d85499c46746bb00ba687a17877e6650c678d13861337faaa7045a16b8eb7173e7c08b6394b5f2b99ea3083ba175c55d350fd61b73aa790ca6f479fd4b01282b6baefa00a1946f6dfb855ce7bd50389d42856823301e01a228ac754cb65a0e323a0943b75741cb498cc499c8649b6bf87e991507194983aad1b57994b7d79bbcf2eb3b5f8734ccf3cea2662e95d486989144aea22c94c363571ac7dcd81f577645cf19b313f849b422afed963cdb701395020c2d18601a40a42429896aa9b0b1c10c4876928aeac59862414e143722a0b94746abd157343d15bb9fe500763b18c61b184407449b1b5ba8fb1554e4bb58ab99faaac9cdc3b698e64179b089b786204bf95eda86474ee799440478348989c91c3462446724340cd2376c682907edb58c85a4ce3ef46cc5d0ca345590ab14844b224735dc05e0e66ede94258f395fe867ab9d8c1b0fa80743002a15da197614295dc358f40758c9cc05e45bbc659b93ed611aa58845d94acc7aa75deba56d4d83c640c252975bc3165254c92957b78c9583b370ad785f2c16cd5cb9913839939c7293e6b956e23cc5d14cb3ab2a2e94f179bb076355157920085236f60b84449d43ac89c2b46dafa6b784438f3510bfc48357a5681043ba7428583bb5e912b08786562579df58a41bdb82114344b3ea3574b997f8564248210d4e50ab2277100b9a5423178b1f138e9d427762253cffc3cd095cb53a776f4fe015b5168b1a9759ac4acc77f90c69b307192b7b866753872a69813b1bcaab5cbb8126d8998e78d99f5a527992b89495a28e3fa83e75337ca2b896172ac244ab7e30761c8e3a00890046e5f599eeab65bf1a4cdeb5791cc10ade7197fb5bc754233f3b10c9ba2240adfc61c05231c36a6cf71aa752ab3c95c3756ef9373b677105d11f86e68036348bdd181f27407e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc4872617bdc17a7baa97af9a9322ff015956678e8d622cfb1a11ed929f29bb1f094c17f49417c09c1c443369123caf8701199c43bff97034efc6999424144c9395d9063bb153c0ed82b1c5659bfb23d4cd2c758a26b6c448525060f686bb14873cbf5046b3a3033c5c8081027bf5e3c51f6fb6a1d54a77c46b0ea4299a9da4ab03b95f9d3601f553d46800f661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a759cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb6356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +ciphertext = dee3cb7f92c8c7b79465a085e92d8061c7234ed5c76ea7548e220737a13fc67d46246d0331fc32d43b0094935c1e709f03f0d40d9f4fefd86aae871ad7bf783e8a8fdd6c690a71901970b882861591ff94792fd0bb16c04a6d5cacf617032f4efb3d032254cd04bc5b8b209c5a1eb3257bfb36e986dd6824ed046852b56f821e931973aff63ffcc586892c58e854705935c44f614dcaac0aff6b78a6aa36ee7914548c9c1413e8b90ab7bfdcde7c5d7c2619394e2dc8508346c187d051683299c041154c3e75939d94afdf3e76676d3acd2cb4de8bd4b6094249ce63155c87c561396dcc300c699e87422df2c8201196b4f320c422b6239e072f6a1ad5dd518298dd0ccaf2da7093a65272b3eddae908fb36e23c00a49d924787210ea21342e014dbf9a335b15c62cbc5c214d27c17a2b6d1c185d5bcd7cf15ebe4a8212e97ac11008ad0e645cc02ce0c7b313f672efc67776516959bec21b66c9a226d95c9dee529990fcbdc8df96b044998b3f1da1ed732e2301f180d0c419a8b95bc6584440bf4fe30b305023570eb91b16dd67c432b0f7dacf63722937bcb45655fe7445abf8ce2c946c03c4c5fe2274a7231df907a5900a3ee0f36bb2009eb4abba41d4f6c372ed7e825d99e0fba3ffef67cd52df38bd2a9588198d9be63cc980e909b978516a25e63302958e3328c10fb61375fa9c218b572b880b13966a8c483ee5967b22cf7dd7f8365e765c71e8f4bd57e70b17c8b79bf259d517826f2780adaf3b8e7774f3d9122809dea47ecb9118671e068b9c9a10cfda0b2a8f61349f0dcf623aabe70a5421427511e48c45e71553072909b8156722be3b301e421e8f9413fef0efb157845c54a593e0e7e37027b47508ba12a75f340a566a4b984226a086497cbf79dcab6611e0a684cf238d7e26c1114829b1e360de4bfe688f7405e5dd46dc3a31ae538d2177b17ec6393c1e973f69ddbfe3a465ab22fd2d2dc3035fe53983c807edceea2c7d157af345cd87c504983502c9d8b52fa86a7fbdb748cd94faa0734b6a0231a1dfa1a36447ae3a27ac1b9d39c0d65b7ea0d8c21ca23d491c7bd64c8c4495fc90247cb5e1a539657e8dda18dac206efc7cb8403d3f9223e800ff2c961321ec5ef918b6f2bf959121cdc940056d06d88910cf622fe70a5af489a069e58277305d9342c05f403ca9fa9df2a80d6dacbd00a6e622043c7f0038da2ca9b49e011bc73df548564e3f55ece3897bbdc95142857aef3f31296699671ade99deb866b55d738e23bfde2ca6d9c2f783d0f1246c3dec26ce19e4b176fbdabf19157a83d308a9e93f65c285c494f4d48b736fbad129c8ed1e12e5174cb49814e1b53ff6e1265e7ef6bd00c969c6a56bd34e4af851a40399a749c4c8f939c43bff06878c7dd80612b0c3cf6afe9c8392ff4ce10ea9ac601523e56f7610d23cacd60609bebfc37b9a063377439d307db2c14d19ea22f19141e80e994d988710045b536762773c12fc42da4f1f9506a38b9003d2eca9a4b971822ebd45bc52425e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a60e9e7c8f405cac3c8f45bec4f7de2069dbd7e543d465ba702cb1448cdf114cc4504d4a32bd91c638347cf5a4651d6a309fa0b4f6d0a3d86ab9f57e00fe88d1887865c695c3baf9ba08356eaeb4052e46e98e7f2bd56bc024d71b896d5b2cbaa0bef4cba45e295adf300ad2e4fbe8272d59cc987c6409e95abae2d7faef288d308b9ea3b3fe71d9d4ed166872bc8bd70d44af8556a356b631a6fbfe804cc09c63eeeca476add8e43eeba767298bf2ace9fb2496e0c573938babcd749ee3edfe9817a3ee5a687fa3f4e8fed829afe42c04ae9715c4a6a8dd73c6a54c16beea97a659da476e49c1dd1b8293ed4321783e0a66a36267673f9fc2c7463669be742987405c26f1f94b87ce88aebaeb7bfd787116c3da5b64a7e8956321463b351a9754ad389937b7aed431a60f8d309cbed2d8ae67f859ce47ecd1b3cb11a8a70d3b9b93ee5531af60d1874118ec505fd4518987e2af5ed4e68bed2cbf676589aa4e8833e04bd17afbf666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb335e4421ec75e96a13b5566e8258e36d34a76096f9c0e3236c3d36bda5e3d53eaad3ca33eaad916d8cedcd3466c75c1b66d3a3f7f4c60a796e0844cc0d79687fd86c61dca0dceec2e936ecaba44666daaf0a3ec6b9ff98bdc7fa82aa6a0c3fd361b3335cb83dda384188fde9e745bb9dad08908cf6a3eab2b4a7b78036704153359dc4fdb5742ab3c39a356d05374cf3107b95cb771ff1c9592d59c810a93e3593169bbf6de95d77dd79a3b3aa03c43fa9d177d7ef88625cf85aa0d99d2edf09a0bb0c425ce6af9f21613b2cd596aa77ba2bb98a386df898e5d4d691e7ed16f33e69c43b64e438c3f74b579c1a6cf7b0d95e59836aa499d7f768c97b7bfb19f4756561ff69128fb2d9c80afdefeca0890c9e47bf7646850fea94e1d83d869d5212431b0ed93430d4b45ad90ce7e357d2431c923b3ce08bc836b3edc8fab2fa3c508867eae87bf2768ad61d4894c1f3b6f96edb52b9b3eb77a8c99839faed8704c907e258f8e9dd1577d78037aa1ab87b03a46ad3a0a30c753b8bd89d923b7454f84c67ab6bbbdded5edc36ab6ab67c29ced3a54bd06f9c09d1fcac8483e0163d1db6650cb4ff8abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6601add40489d0534423786e84c95d57bfdde9636bfbfa76c2e3f9625747968f53d1fbf6cf4f95d6cca45c61bfda1fe899a8aefc75ec12ccfc3a2dae6d8aba4e06cdcbccbfb72c48ef564d3462ab49cf6576d8c358a865de1f795cc16f9f5be3837b6b1714f50b8e97f7b1e6fb64addbd1fc955b49a67094cfefbde8c8bf3abe4bdabb787d3e45eae1d8a96e3f06a4977ab1f8866e596dfca9d68996d831fea448dc0991561af4da96bf490dd5538f17e8098479a5763787939453a7a87a359643885bc5e6e49ea048b5ffeadc65c78e4a9c91726dbdd6f5352596034b3558f98637b43d61f769cbe44ef9c7642393e8882caa978996d1d4fea92838d10ace8711ebf85de7ff0bdf71eac7d5ed9d74323d234e79089f5b9a70df77813939b5a3b234fe3760be892d8bcc4a90087866b29244c3641310e94b8311a1303465975649288713e79ca67a9085c8f7449c0bb9a6ab196245b0da028cc1765a8ba0501d5e360cb3064e11554f3fc2914f1260509073b67b4a0570d7f708ca7c435ea987762f2a5a23cae53907fc9db26942136d72202d0a0bb10b65d422091abaa1c21d152dad59c25d20c016237634741def8ca26b9cce3097ffd896f1bf08300282fcb7000c7e1956673223902ae5b43bc63b6806c469a4ebb8bd34b057b375e725b07ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdcc12892d588d06655f6103e033547cf5933ec237b21b2956e5921cf10a0c55a70e4a24a57b93f6fcaab2a44bb079987eba57223b4b9deb60ec6464faa4058283b8cba6956c792ae8ff9184e93c2e2152823c15412c102518462c2691db1c64412eb1ec6d75d47c82fc5a9214670b3297067e30c6d9ce0cf3eb314cc1a4cf35342ae419513ec2bd47182c4ea52626a56f7831dbdc5719f532a5a421a7bd5a115c2195d0532e7c1c0ffe40166404137a5b45d7b2cd31752e1646588021508293fb881123f61034318700eeac429500905179b283162ed0b69590541eba0848decc94bd18c888170a4c030a89305fe97a2b0292390a3b1fd6aa22909cf0134a2754728b6fb5180276b7d65c2fd530b4ff48cc7c7093dfc2b418b97762c42bb0980c7f41d9651c69387173a6718038010f50b79b233187bc3a0f7c770e50abc62e8acbe297c58c58055387bc7711473d81ca97b6a6e6504870c0de1d806e3603ed0b04d01dc62529434014c5068c3ab3d4a909a079947127a8a2746cc8126f0212e21a0318ef273d5e0be16253848413c5cea22853c6e63b675cfac1d6590004a2bb3bb4974e79aca0dd927607a71d4b4c9980a86e5a2b5a84bcd2e694190491060411b332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d45f72d82ec24fb268537c07b81aa79b5b28ef5a657e0f8b6b2f3a4279abcf06ca2a79401312943d1d1086d91b1ad3030d0c0bb21806cb87b56ed391e6bc6aad974034664b4902336d6e45a7449cb656207d59367f2b142746636e44726f111603b28670f47113d28ce6bb11f464b181cb3205febc13cc70d3fb35924a641a1117df5cb65fd9a69c71bb800fc22a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ea920e4f2275f4f7bb361866647c04c573bf47e6b54cd31810c7814ab5cd27da1905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abaa2229c4c294e7a70f97bb6d119be54553eebab1c80c8da7459258e44a234357a1c9cc46412794116123d21db27455063672245460ebc8b6b1116b34f2401169ace16a514534154e798ae3155809b651ca963f854ba501407920765a14f826dcfa4bc4f21766b05bceac55e6854f1ad080d9b2538848a8dc7857f10c4c843c46b172adece3707e01c03059313bb96bb144996b127a16006db4063ca1251f550836e167adea545b3a0c55c0ac5de3fcab6e8242c2c5c09313646117a95ef46536dc74d869301335a2f9040484fb0c9cb85a3d034d55b03c66725d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +ciphertext = cb8021857be83d6c14856fa999c0296939540b44fa0973d41de5a98a7b8ef1bfafcb9b16885d777ac157f018f00899c739a8dea7feac36c5dc8402456f565488495f4c236456f7775424bfe331013dd60a242d436dc354b06f76a46e23f7ccf3cc398ca8b041f2591245a15452248d193474589b275e1a7f1a9ac3c7bb651bb17e5c4bc116d976dc447565a29497effea01ccb07220b45919790aa8be2f63dde259aef47f135456803471932046a51b0ca0a0b0418f989373d780f865f890ca055eb1bde17bcf131a956be72249d4155d35b2fd4ad28a59540d7334ec453e19561697797758c413829c46c9487a35024c67dd2bfc3cbfb2b35e556c1a271b6455ed7b9ad266a3b246ebbee224616f23cf9aa8ccfcbe019847ec34ede915970f2b7976446133c1862f961f4f059ffc9f722f6d267929819545a9fbeb6f03465339234e98cb6629aaa06a40d6159a94aec36f39b71bf0d3bb8ac93f9df0c8043e9f9cf17e78066a57c5d10d2d27dd9c0a8948275b14c82bbaf7d8451aaeaddc8eb2ee2c768d2d19d590c1be7af7ba30bee182b3de636125c9dcd80d4c64624d2c458cfa5f30fff16d99c97001404d6c64c5fa89bd225abd0a647fe92a0d004f270b7dc84a88e35892abd37a3321396815a63d1305a9dc7e495b592dd80046c82c13347395a6a92dfdbfd8fe1f7634b472f266e603209df3ba334bb0c68cdbd6d6724b32452938ea0dce4c3a6596638b0916865566586cebae4c0ee3ec36c782ebbb85e583c108436852d4545073774b2177de52f9610f7d778d7eb6d2382455965ab5b3ce9816d0995247945c31c9ff479587a9f60058d0867d5bd7ac12a3ad9dc581eaf7e4c5766829f7f8e2935bd1bc159b5e27f827c85bacb41f2ef5ff75666308c6a28765d6f2b261805bce28c6ed48cbe20a0945b31f59826be0742c711054a2623abecf9245fc34bf6c3b5e8f2f66114af277812c773f0470da69d10006e2dd44180713eef89307c3ce79a877ed3cf6f63acd681cff64647a3c08ff5a0c4fbf7c8a80b4bc3336948bffabd460dfd548c62e6167a24e841f13e1b0a868bc20e9ee55f9d89c44f58912cf23333a9b04e3bd813a0d2c61d0d087c9bc2783476dea746ebaa805de06eea87e7c50a20f1518bf6bcddf09f635bc1145932b4b323c4614882277130315ca6e5e3cce1f937de71e39505235f0ebd8e6482a2845ead61224bd8d84398d8816b31a0b178e95c0ba50f9757670e2d23df3475ebe38b6e53d8e95884fd60c38b3502a762f6ff5078188426a87c6502ac7251110f29e16bea769b1ba2bb27458dcaa225ee7e35397d3bd8c2b82401584b666fad035b2b99cc6d518ba1df7918464eba094d8297254c2e804aa06c00191af19acc9139728de08f19689a2507430b6e2597b1e5284815fb60273d80c48d2d4c934d813c0e1bbcc35b855e09ddae9f97111fa3d1f12cf449784012170e594f6e74d0646691a09a6f8956b815d9e3fa6265036ab2aca4ab450a62645155fa81ef4efa44682696 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7ec737eb05ffb89d5da8b3c58508928dd74462e8968b1f65bb3b9780649210d8f02e2950ad1e863bd78af41f3ae9899cf0fe992608cf5cdeb4eb0ac1c13ccaab4ca89a869424cceaf777cfc7e9da081f73f5aa5df41d493fbbe7ce5b6477c773d8cc81d995509ff3a40cf8de734a9e8968b7fbe79a9a0dab85f7b442077a890688dccadbd5e64ae59ece5d39b554e6b82b86d2a149a687ce9fcfffeb8e4be792e7529f33d7505c77ed84a63a78f58e93fbf10ee9bc05c91a7bf16ebcc051c9d143b9748b365ec94eb6098c4eece8aa833ebc25bd3e733adec55aa5b0f3f31efb7c7f0ab21e2544073cf2b6c4d75049b63fcad5c68a936989baa2e55ad1846fd1e335569bd1d4acc869f7e03587d8becf5db545447f4e727224545ca8c16bca5458fbf4d746a12e27def29ecc8dd840e279e0cd9484b4f4dd0c7446959a521618b9bc57fc810ead0d1c8428c43c0fc3f30fa9b176a4f84375a0e1563fdaeab6cad367c9949c4723802d6931f1dfe2b14dd4675652b958518e3ec8d5bd6dfd9982080f319e668dffb5c8873fe70b1cdeaba56ee7b77ef5d7600bacdbbbea5b9aed5a9443bb81a68c22c7904a1755d4d8da47bce48fde3c3a8ec6c05ef2a798dfdd597429b3fd6046981146743ae85cc9cdccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398b9f36e0fbed9b951f6d43a67fad6f7fb803acc33e965fe725dc34003a2e3feebfc0badfc537eb2b6912245fffc6fb285b6cb0935adfa0385dead74f7a63adb76bcf4b8daa84aec32f87be3a786537acaa42e78b136c8c08e7ac1dbee25b44654266f4b3be4f33358b9b75a2e9e6d78e89d3cec68b88f7350ed52449598d847b2a02c3056a64e72c5a3b34685e90bfd0037736e1af1df39a3574ed777a36fcf9d8c243a4a512e6b6199cd63c7bdb18b95fbe4615e9799767e76fa4a88c93459bd3d30e09889eeee48890cc22146f472586e3d0f6b0ededba5b8f3f07acc1c693e9b03e618c9d359b7aaec5447365f835b3590185ed9337b6171eac38eef9bde08da5eae3a908de4b3f531fc25fca5fbe9859673d62d67e28c751324e245376baf368b086f7fb1b844fc033361994ffb3b39823afa2eee7598de66023f986604fd3697a6f523fdcfbfe40b97e480f5d523c3c5227537a5089fb684fcbfca55ba9c307b4feabe54d241e34152bfc2aab6ad568e7b115330c1be5891fa35bf344be7d93ad44bb27a7fe01a8f902437f42f6bd6f96fd4e738aec7a333a26dd1263dd4b21b5e6fa95a41a4456f74c9522657a9b4df8c5ae62f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4d0ae83b96869fba6c72987f4c3f8a0e56a08c96a00d78854d6762ea2394c3bed2172e43ce5de92749cfbd5d3173a7e1f1ea8c37db5b635bcfe9b6396e39d2d56bb135eb8976eeb0a28ef58d39a7ae84aabd46baf4ecfa70fe8fb71dfce33fb7a45a532dd54d3da8c580d6cea52d9098a3d478efd7622a7cdeecfe73cf4eaf5787d5bfb461889d23ab93a4ba327c47eeff58cff7f65738886abd046895834aa06a6cb57973f21ee353fcc1453bd15b3f4c4075e5e939daff4356fb393b5704d76077b21538e9b6a69de9718a491b3262d206be72a9ceb000e81b6be6668d14a124bb49be524abb09b91942a60ed38b1974e36376a7724ddc7e5a993ea9c25f40b80c766cc57e807bd5932603403458b84703ca58f8e57c451227128654df4537fce6a57bd1bd6fd8c5be1135b2c82cbfa4b96d577575406f92538034d22d6198a9cd000fc8dc8988f95608c1974c4359ada14f7dd4870c63bf79886ab2d4cad1c89a8fe232fc1c8c515b7d2aa9cc35759ef583244ea767916478f8415fdf7b1cf85a80f4d6960298b977a7abf380709ef904c1706ee3f51abf415028321e4fc79fb2e15454c47b3572bc09c62c0dc466efaa759f116e8ba4717f91220f125656ba7c52338ab1facb0fa6a75ce61f3135911d5714fcda7a5a271205547018cc0607c5aa7104a4a77266c0525579f054ecc6c62522068e79352ae7a1c3265413459939764a4421caa937c8f9b2b276a2c77ce7814fe9034783b8aec29881e2563a63780cbabbcbe72501d68f1b72c6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c9621bed149be06aa2e72f72d1b24b086836b525915b93a49d90cb3c45877c54204a605cc27f1828de6ca1e95056938a6c9651eb3b4a9b09c5aa9fc4401215d9ea9015a996f9a7b898cea466ca14f0065a5b1f374d422b4a277a011f3b3e8143b053507bee829e582528dcb3c9e950f39d17ad0a849c701779d070e34cc606c84a596650b7776a468659344446bc19186b43cbf042516a7b133065393c83b85313c53b71a5bc4421a91694beeb39760806d3b910aa8ea546f53763b656c99ea50a179986dc3786a554b819317fb58564dd69428bb1d7bc45a642a8ab9cc013f932a67222d1fd42b455930b8147d6175c66330217246c400c4b619b922182101b2d8165f93bee58757c14cbfc958552137b904009fcf845321841f8648b8f9e58d1572119b11cbcd59480246a46e255adcc1649817a052736ed9c18a262c36f7c37918db789ab177ed39add0850a509319888073b54bc3ed81000c780fc87ac5c302235a959b1164b491001b92811d4aa76876065e841b276a27b868822fd1da7c3fd1831d88c9f5d891ff610caf264fbc9280b8d4085251774ee20c23576ace6215b3eb8c1610ca2405115e89421418a7610c05bb526ffa39918e9558c6cb2618a612b6d38bf8a2569b4c3ae902a4ac744ed4bca8ed783c4eba450470aef5ec5370b87daa419145298170d64caafc2eda7c989645b9285a3fbd16c16e0c1e3fe085a6bc05248426ef106e7f6012e80882682660cd05ce49520785ea66325078f9a91e5ffc3ba0833de333326fecbcd8878f286064cd1b672f210133e30d106c61af9a75a7fc64fb5b1e1a1649fab356c0f26b9062c5dceaa7cee502c750a93187a21c11b1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee70253d77065c02926bfd9b031260b5af95846573ad09c42573c8338609fd3e5c0b50092b17a83128a4a9f1a6a232252884504846b3b7df82981dbb036f6a57c5c19136789af9690a978145ea6adb74132ec55840965083f388877a93fc01b006fe4cde4012a1814b327a12cca8991cd18027f4485b4025b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +ciphertext = db57de9e2cfc65b4ad9d944d6b8968d8ef73839c55b96a77ede1793f2b8ed9c8bfb6e3e711e0f947d7789c97960b9598ace9109d603c97474b5829a5729fcb19d2232f5f02ddd2c7b7bee5cdb042d2e255f986b3f6c16666a223e49b0316028bad8416082fd7e837f208ab21fe97d884d05b8bebf05c206006f6c94527398a204377051e15d2115a998faee7dfaf49be6dfd6e3288226106f25f2cd89c576dc74bce95538594b6a72e1a0f422d6f8c49c5a5eecff37d2ac8d86e94a65e6d95a1c421b83719b30cbc8a39fd82fb21ee981a2bf86dd6cb0a964b1fd408d086a86bb2fab39dab3bfa25137f7963e94ebc54dd93148316ef1c6b3b9f8d7af85264c7ff14b69cec63520b5d0e4476a693545c515252f879f7a68b4b2132aadbb212a4ed8c6ca154db4ca7299fce1d218bc95b4f058d77ab04989d918e712c266417d2e9b72b2a7c128f4b06d5131f92e2fe4285fd75412326d29bd9a1cd3efe33cdc3a5f1f404831fd7fee72facb4b37d42d33a7799df32122cf349ce0d64b8be5980d4cc140ec58bf0f52f304fa035cd6e0a9edaf54ff56c9d6aedfb61fb1c4aa597bb87298403fdb140be8fe124f9a2c8070719f1a16c58b2093c645319c137c1f53cfe9c267e00502a442918121c922cb6afb3befcc19321f067a2838a0d89ecf94ec88648a64218dd2f2fd2359b31fdbbe1a616daae89f736bd2e16f05828e70e4b9c0bc610041900a29a29ec5d7f3cbc0254442686eed9ff7aef4f42958dbc30b64352b7dfa97864122a889257a5f4ed365fb13fcafc4845080a8a4607c31eef8e8a3b49a0e4b4f6de1e1d01e871c87ca0a191f69b73c2e773b64912b86406786d4c90a8fa113e298871acfb77de35138e2f68cb2bf8b26fd7d464a02d2f1664d6df49dccdcf869a8f1adefcab1f1148bdbc97855a6ebc160394164663d04205828b711e62e8accde8c89f4fe02b2f1a6701e28a364d10bbbecfac9f113a3db495d2720e096db5562259900ff6a2c6a0be74e66012ac2e7360daae5dbd3ad6825dafc23491c732e6328f40e7af2cdb78eb88f91eee5c8163fbb3f7f4b8cb8671f0d6b0317432b4caf2b6a077a712d3cbc68157a2b340e01838fab5f22a28e432713a33b18556076681ea7f43f48cb0339d360cb6f47247220e23f313959c39cbca191b1911c9939aa541cd2d95c7a56338e09f846c4d38080100e82769ab86164bdfce24e68b6be20483d761981ddd4c963862fae0e9fedf619dd7a3e8e64561c1fc4c778ebae8741cec91a4d5161ca7f975716d2bbb4f50536f11710010aff928a03118e698e2cd20edeb34da6675ba04224cab7f5a25e1b1d9252971bd79d757362363c5491d3f2b2b0b95dff046b7168501e3a25ea58334bba7e1574bbe1c77fd4f66fa424313b095ab9dab5f810f818a9bcbf31edd63980ae89bdcea8306ef416124a06041e8a2459219fb863caa7a010843b4d41fc28abb73cd610208201e5a7ad693998b19946d05c563a8dd60e706ff5c237a17d875df0522c72fdd7a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d62c6ce5e7594be682a81677441d6a4458fe3a79ce2576357745e3f1bdbf78ae61c8274a705b93d2eaa899d8c0126ac8adb7b3bbb589181e380eaea9de0541e426ddccabc13a165b5c64e78da95b919457c684b9ce08ef97637c740ffb3cf9f95de79bedd83c3ff871087b94134de864ef91b047794588d7abe4687368c84b44d8e26aa30bf58bbe4bbdee3fadb046d75997e4475ff2524b3c2cd4c15f98a2e6695463257bb8fa9a8423ea64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51b07eed4ccd3e20dbe2a226d72d7834d996ae9aeecc662fa42b48c5438fcd0ae8cfdd1b874fbb4ec17434ad584af5b4561cce597aab63390b60fe8cd52e57846e1a8c4f6c6758798b715d350755494648ffa7ffd04b6e6a40dbc2b0c596c2dbf873c38e6ff82ff159ba93563d2377edfc433949d3705f398b385f680169657623937a8c357864c39e8fc16da5c1ef4d7fc7fab358cdb114965e8a8e5409964ccdc54cd8d5b17039aa9283a59e746a46af800e58d6064683c39fb426ce8f73baff720a6522ad50c5196bdabc9b094895ba5f775acea7210958e11a3412bd5e67097fce3ce1ee0f4a86bff684c5eedd75fded89c23e1440ca66e6bb754361c549787ff2b9bf97f8f4bb808e8d3b29b16c369cc8ba9d91f6d12c0dd7999c7057bafa44d3d2383e407abfa55c63990c3ab657cb80d52df2661d97ed78dd210e95bf8fa9badd8b25fd39bffc42c66459b0c8889dda6714b63762494a5f7ed6f45ff3990772b1dce2dc76df5bf6feb1ae5c16d4a0303773d768c7dda7b74a8eef7d1f720c25dd30ec6b6266f4e3f94861483be13f71d9bd5780ab62e0294a8dbe93238530b49455718c872428bea1d84955f54a3bc6e9dadc6106ea3ef37d94a08563462437741f648ac46559d7a7deadf497aa9f22879d132ad8ba2f3a05e5b76b0d807225b30458df6105cbec9ae1cfae8e8a1da9bba691047c95676c9e2dc7ab76537691dbbee397738d6e3e20cdda7afd6699dedec26c97dd0db82a54af573ad2801aac2098331104fcca18699a2684e4b5aed83c7ad8aae706fe605a87cabefac499a56058d8b02bd5977445f4a90c3686d9405e33c3d70880b6449d41a76f84ef3759664f204ded3935998d79da7167afa11a59cf8b87634f83a738c0d32eb1b55453504ab64fb8982445ea49ebbcc39e465af92f50d7b53874c1190a766dac5e717d6f88097be56dd942534df5e5887c48b235dee99203fcf4ff867dcd55d7d6c3a5df5d2a24ebe7e7d6bd2fd3814667552888e3cbe3222ae0dc3a4157e8e1a7daf3088ba5aa1a3fd61cdc6bff9b3c5faa6db3e9d8e359d94fc6dc65c29eccc0534ee5d16be9a7c9dd119dc5949cc66b0d4f0a15e3132640a284a87384c7ed06782607584bf5cdd9fd99adcdf29cc9588c0f4b0f3b5ba80b962218b3bce4c0f64fbac9e8c23546fe33ea30d799d94ff8ffbf64569907755ed7bfd00c3f6f446dec0da27b37bb92e454aaaacb69dc85463fc718c85508ac8742d7e80eb8d5a789991129e5be4e4275f9fd76ce953d1d968d9dfe4aa6429edada5ef49fb4046ed2c939155ddb0d98fb68cf75c493d37e859c8d0e5114345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea81212eb91339aaa4bfa87a197a04d46a7b666837f55db6f16c095db449e9baa879ae14016ea4f8ba975da26cfcf59401237accb908efd17146e9439b1473bafa07703f2932d5c598276b59b419402d681d87111f70c20d2710e10a407634ab216907d7363af0bc4647dba208f9c6744d71a8a1c1a99082a3bd8a843e4ce581412f04877edb1709d1a9623c3c428eb111a1189073c9a3d34ad16aa1f1551a07e6880147360e60888ddd5b0956036951021af4699c96382cc0c16b3f0b960135391c6692b0c556a5b9ad2f8a5ed0cb0baea2406868ac6f7a5a44b722721535e098fe832c9af148ae027604c47ce4d3214a1bc974675289ac7bfb9a644db30235a664417c57a8a46a86e18a10f81b87f4b4727f7234017088f447f28680b0600ad1dd672f0ea19e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d0a2042c744555049c48b2bc2577738a698bc58910f55b0ede555b171838f6086ca365aed981aa5354561411990707bd3305cf4d10161fd3124156691daa5cf3795653e2aee1c4ba021b0edd0809b14905e46c2cd0bb1e165c8aa428b180ea394e6c92bd6873e12328e5e1916c94c81393172df3815127b937b9646a783524671fbd8b5f01395178c6a9ff42c47d8b25fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f27640fe59b1ef407110a317cd72023828192b131cb9af96899a69b0f51125b2828f29493a997a33023661bb7811c4593e4e579f8b17d0cbb6037d9273932af4eb235f7d01dd398b70752a925968adbf56cf132b85680abffb937c35425c244345e805bdb608cb0666984775ac1852690908cf2a60214f6a888004aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f52f10d4a852d38f5354981cdfb7a851a675c5a01c2fbe886192582d1f08ab37753bbd81ba6d848949731c99ba92278a2833cc11ac3bf603512bd6557f9684eb980c7588424db0c1e2bb2bd09196a7da29d79208da50c4a0c839284a44d8861706e991edd099e0b1467b88948c89778787c26dd4436fbc4bfd12b0acc00ab4d85b613bba4f928bbfcb04e2eaa51b81845c3a710bbc8458027a4f055061d0b39ad28482646aebc5458d0e70d396c99a0b456837376110488f49a83f48372327467ab87870d11b3c1e6c112ab3d6d486a99bc2b9b368a0695c6c6251d6bea5b56fcb96fc23475719b8cc82806875cad772e4716332ffb02189438e27097e565159e4b1790558273ca887fca2a6e7226c53879adbbc07ac1072e6aafdd2a1dd89677842041f33c447204a3fb91c1e4935111ac739cdc9fd6f2ba8c0c66dff5552f3b2bdfdb19d4f65cb3b23777292cf97cc54bfbc41ed041e53318386173d229b9288c5d68e87d0ce2032d481c46b646ef71940d97af370732533260c6ac943272866bb2bc90ec64424c67b1c877f5d2b35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866a52385c85c241677f75487d4156c85db639ad741e0412438bdbceb6092fa14501fe1c5e95d90833332debc0441554a8cb5a8f7826b047882b415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132606ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e46858e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +ciphertext = 434defffdadd10d9567ff7de185a5081952e909d1a43b163483f8cbffb19f07b20cc3152c39709c3769e3152a3870edffc8dd78d5c9e26622d7b6c7aa341c60a5966b69c71265d8881fb94d9e13efb08d0a738b857cec7fdb63d016c025fb66e1cf8ba31961f56ac47871c7598b4cd2679fd7ca0ede0805c76a6f5564ce1bd748559f3db064e1da38f33cbe9c993c7cd1476472b4ca2075666380535d70176864275e438a543766ed89727cdaa4da0fcb36d948618a935ce49fce7148836b35d80f9885e82470f3ea9e321783047b136ab25f3cec80fa385f81722c0b02e924b7906ddabad71b8607353669aa8e3ab3826e895cc43b55aaccff387b7edfd035d39918738dfa7930b4dc7be3b3103552898c590ceebf0660db1b9d1fff96e339bd7845d6542418ce34208e662cf2c18104971673789c1c429aed0f0212868a808a5d6bd5152040285b8e7f5294df6db7129061c22e16595c57a45deca829ea1fefc4e9fe7d25a7bd5d17981bc9212eabb58a6ba17231753571f6f7f2e1efcca7b8e8db179a774da3d2994be50f8a32dc18bbcf606f73b1f72e5f36286ec13b576a013786b5af3621473719a2e069c0e59b1de69973ec0ab482a0d34c0bd4e815df2c36bf79c5e2bcb511043bc4e6802e7fdb358c5994537dd9a6e5535e281627a0a40576befe4d863e1b645585e0935f3cada9e64303effb1e5d8be5418db1fb76d1784aa7b56c2825f970e221e8c8d6b6f43e8b80f03acbedcc4224da3942016668fda692383178faa7328ca7aca8be1c4bc9ef50bcf209289eb47abd34402a7d1e21c9ff6871a3b7f603d77e08ef58853aa0db5789bca441c50ecf6b01726b8cca5656705fd2c670a8fbaac44be77fd6b60c863873dcba0b5d883667f37cdf979ca1a098cf05421ad841ae88d5c235141104b32c1075c5c9b03ee60a33415f3863e0894eb112046790ae65b8a6606c2a295f1d91e32dd37a42ce0fc5be9457fca8babe3bfe142c9abd48df57a848ca966930c1372e68e939e9b75e72d52d6a2babe0992720f3a3452176e13619ab4057a3141aa1fcc82ab50d470b31a9beffc5a57597de1415998a9e5806ea9bc5df191624432543d86c2ba247cb78ab4b6f73afbd5533041b30ac9e2a5c2221721330bbe258a84ef5e9d5a14645cdcded23af731bc9071c66a21c7dc36593173ac63d818965d835d572ca8f6562c048773321f2a546082f4f0bb479c32b5fd6008d417debd9ed9c36c15ac9ff3d990f89e5f26bec912103b5b3ced9193cee7712c6442463cf60c7e613d1215594a2086d3695db7a5f0ebd6bc953a2c388e4866a0c54770cdc3342986beb6591953bf6d0d7ec07b975d01076513d5cda1bcfeea1852ccdf15660a73585a254ef9df4199ec11c30d04935d299908aa92ac5c3a2a549ef139dd061f80f8330a92b52439bc512804b2bb75d1233f6ef04625db0e621f4d817489c34c90b99837eef09fae7484f801a97f21ce732e7f1352429e00420474936f73188eba2000465bd8961f393c87 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 212393fa68c40e1e53ec29801f4472dc3db8e75e6647cccc6a26dbdad4f99e5e5717d46bb4248674eee558d8af5a6373720a9c96a4c51c0efbc506cbe51b560ab742ec684ddf86cb092febde5efe2476842d15ee328fc415c49b7184c9332f42f70b63aa6d576296a8af5451f5d474019c47e29ffe2b25d3d30cb8eb2db3cec334a31e4fc248ed910a98e633716ef9ca2f7939c7033bab756371d6c2e916d61d08f3113c57dd5992c98f6adecbc9ae48e931473558ac94fe9ae9c9c4bea3dc40defbcbde234a2126f3f8e8dbdefc74f657a797098ebcefb6b57438c2253f8ade3bcbd5c0c52d4def79bb37859e36f9f0768ca7d075ea7ec9bb63336698acbfb6c9a384084df0cebf5dacd50087b691e4d345fed7bf0df51bd9946363fa05b795f93df1349fcb16d668605ca86efe34c03c4a7df581f8ca7daf83ff5aa75146457163c3abfa9c655f966a607a69ab1f34fd1ca2aa8fe3f38da10e84c4abdf6c0fafcba6773d63b39ef745df6d284830ec3275e5bb9b3e8b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bddffd617aaf8b14c10e0d37aba7db8cebbec0cb866bf5d57964b7cae6c9b3084a6976d2a25961dc53558c065d6d9bf5248aba263beb6363f2bc9fe65a8cbedf6dbbf6c7f459d47b64a964b3d3fca563ba5aeaba8ee9e2d82bfe733b4b4587a99af5d37eefedfc9aca5d869596e36548cd336ae774b8ba63772fa598cd5dcd43b092d938429886c708448b24a45b8dece9fb9db54c67bb63ebcfc8febc15c1284d9b02a3350e6e68f1296784b86f741db9160681f0133a663568445deb9c14e4d7f687aaf4ea36857ccd4bf6bf9ce1de03d869f3d630169365aa3c3b53cc89d9cf48cfcc6c166f197c9e5c6bf409bd3c42bd613703cc497fbe78dcc4b38d89d81e8ca1186baebce355d5b9d4e45515897ae233a2691d356a373dcbf6cd600fcdde8c468cfdd6dbc67e60a69909eee71d4a5ec1643b87059cad8dc259788eaf195f4fbccfc5ddf84bf8f2f95cf9780ae2948ef91657b927f8b3331f4d62de7e21a36486dfc3f289386503d6589a8d049bd6fba7bb9f087f96d5785678a7f3de6c892cbb2273677fddcb70f5729bfda0404bdbf16d8acfcece33ff924535c16e94f3be0c8854e439ea395dd89f399dc98aeeb7493b64965858be35977dc053b3c0b3788fc4f44cd3b49f4d93509db454c983da38b2b5c88521347788f832e9c64a6dede2521f34275c9f6c35e442a87b496743334ae61d9cd4e3d78be3097942aacceeed9b9cb673e10af71bf7edbeb5c4e1049b2b3ad0311acad457df8afc85172476b949aefcdde10a36e46139eb5ff7a74697c88ae4dc8287dfccf68b9ad5382125879e637b7cebc1aae95b042e9cf2488b2e4bfe5158dc8ce8d22d2d92480f36ff6d42dcebca24cb9ee9379386e8de55cf32dec93b99b694e99ab5e41cc8cfb8928d6cd8edc7a707044b49b8a131986a3f37bcdbcab5255b64b59d5a93b7e9d01a32384a87543b6ba2bffdb75c9babdf57bc8b9d8b78641b394c7bed64087454d0be7b307bc35a97cccb94f602a9d747e6df31eff0ee3e71ffd7a2b87d49dd3ede2377607c8e7f25dde1dd736d7918874aea4b8bd98be4597242c95c9641b194a093a928b8d3b30f33c10ba326943a8b704c09a6dfa55f700c488c38a3334716cceb6585008a853162e40a544c0a16878328f47c4e67b5aad276a2dec4c320047e2eab345cc14982b96d1d13566da409e93072377a1729546117a04ce291a2090b60030a35d5b360f9f871cad52f37e63954da0e0a8675abcc3717972f89469978730607293267cac89e3c96a98576c2351d8756429722a1278a173a75114baa4f0eec6a12b09cafdc99fee2c1af7acdae3c747b94b06517464f654adae25888a15cb4c5017076c9d3fac3b1560dd9112d88b2bcf31b15ac420fe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a972308c7b040d2fa32bfd1096503a3a0e84b9941188a6720e06e6641b896d365190369766995826b72122d780477581bd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0a423409c285d0e21bbca97be6707557bb0027e755f9a81912d04b9ebb374bd79411b2c283068670431f2de58d346bb525d192f128c9316742115275e9214def7a61da509b5848013b304216f783d77c3f57b76fb8dc984f05ab557709dae4691b519c44d41813e4b61e6664af5c970ae7a810714217745af087bb00575b18081921a854b7d953e29cb1de704e6578283292168ea73a03e2082b8b641c819649270011861a7b301dcef74e9b116a86f717e30ba6c5398e34390072e20c82f570fcfaa2bd8847a7187052e6b9d0d9bc9fec0217373bcc7b8d38245e40a1597077bb00a408e9eb2bb451c31a746d2aa07fd6432cf176382b6665d45343cf32731817023ee046577abc342bbe25416daee417f2971a8ed4c839126e996a8db40a55bd424c0e534cab677fa1c6b692d2b7e322a331305f75289a1ed102ed604722737e76501c7e7acc69842d6ffb2d31d1003c3b3bd8f4458d93b0270cba21db21a7d16e22e18584e68ea5b890ee839de75b68d60b25d5452bbb91658f3220aaab200ee7a8f070a5b5aa7fa30a768275970012324fe01910e8647945ae6f8b3a17d08e5c36af468a7f6308751c4141439b567eab03d72538ddf71debd2aec5db13537a2b0130b4c2f6662182bd08eb750eb681fce77981a3012102c45642bb8a44ad5cb27cda8369ec28190f64987eb600101aceae7a807158cc8100555a82644b3b513d7cb283a363c70a4ea090241c8a96ac562e7fb3c38f3515c3a68fecb271713729fb77a1a68695fcf995855749c1f0ae09f90741ec332e7602cadb69e55438b9d8ccc213119627410488145777907d280ddb7391d2ec9f27371277c266bb1b14f6eb8d46b2c8bccb0c68f3beb2d87b07044904d5b08e84305b0686f923985a49acdcb1a662d1a08948c9b8d95883518d0ad3933976c464a41c18351216d84066d71164a32d41886a153703c584b747555eefe8309f0810d49c0df8c5512b245f637c9448c47e1456995e922460b8210c7ac1063047c3764077288a1345c23ee0c8fa6865fdd52acb49614207285d241c14114db55cc0c92049f3537abff81b8a30a02e5ab013741b36d92191691b3197cce8d2328bbb6ff61932434899ae01412b231b0efa18d8381555866091c77981e753f8a2b95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a588aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +ciphertext = a07bccd6a1000b2d0f27be9021ff90c945731a7f45e8565550bd4196b7fd1b3fc4265aecf0714bec8fff9975ea86b40eed6befb80819936d437df6f83dd6d00d36692ea2c69ca0c93544e3ec86bbd6e24b12e7985e7bd89cbab9cc0167091270095529280eb6520545c07a7d76c99eb452e3fd596ac1c493e05aee285aeb22767bf7482feb0083147361198bab22b7a9b90051c42618443e621761a0e4bbf5444e23aaaa99ddd344dc738a81b1900e546d008c9e51c5a28da10309e35d40415b35fa9823364a0da0a5204a8c67e073128ebe2ae9f82dee1a91753ccdfce4247d9a3620545a8c4b5c5b1e55eecc4e9cd4338b912f5316f206ad53ba83adb62023c6d220fdcd573dfcfccff31616b50182a4f5fa42ac71b2ed506eb260f69b183d0dfb43f9e47fbfefbcc43d5704b7d4e303671dfebb03c83c79b3f7dfa0af964dcbc2edceef8821be9926ed353b9760c1d42552fbb8bc55d793a795bfd380e4616b3384bb6ac4c0dd9b73918c17a7b208138022a2835b5b0f1b8d79f186dbbf4a53300d70a18f3a0a8c3f3a8f57911d9958e5350d835bb4253b4c720675f81188480b62059d7af0935b81ca49313e49dbc2e5ace73cad23d8579218686ce283549e2f39b712dd7570aea5ebeb2fc0896501a39203769b41aa931876a2641f36136b82b53101e0868f000adcaa5157544fd010faa592cbef477f12149e0e45754bc25d66c0cf845cbc78b6bf3f52e6fdcf9e7932eb05f1eadd9e1a8d6640aaf34fc0da9cf0f64ae8398ea5ab0caad93648672d084d27a5e8f036b7390616df5a8536f1260ccbd3b8810f070149df4ba40ddc9633e7c1ac97da236c4269bda5b4a31cc39c5e1c1f2928ae140e67baee27fa30ff122fc431091558d52951b1041772439fe52a867df5c34a5d407249782a2ce947475a59d21463461a556f670801903a194cf4c55e7e2e570f89c93bbbd2e0ea1097c7d971b41c85a2fb20159b6271ce2a8feb0fcae0eb5f5c7ddf1482f6ccc35ebedacf47e67fc63581f79aecbb95d050edba235543e0c9f90a26572674f00b331226d1e00795d0323c331de978bad64cbeb8de9fbc2cecce265b7e8c85d0f334cace439e27f320cc8b475758e6fb4a1eda0021447ed963c8952c6635e6f3e5ad1372e3d4c6ea668434f5a00a9022dc3af451b0b0c8a4d9c705c9e837ada61d85eeaeaecc43f4cc3b0ba795dd712a943b09a5682a25f4a6089df5885c9a3a7e8789419753306134c46c3f6da5c68ffac355a4b8aa0a1708c7f5b66fa9f5c5cb3b4d9eea2ed038253124c3c14f572ac43fd6b817ca6211f0210a3d96e72e38cd415cfd525425536809b6d590b3da32a8c3e87c649896b1d81de6622cee43b5fa022e2bc6a378b4fa6f421f79ba8d6630afed853530d5f3b2d9341e6ce5b16da3c919f8bff21192fa4c3b0b4eb7187e453f0c3437c7407912902fb8d3a85584ec961fe7094d606719ccd89128f636119ed9ddcffbfe1d2c2296036d870fe0903b81446c6cc444bfd20548bdfe8007d4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 69e774db244d0529fa2e064257f3a7babd8942bfd18adaf8c71db8bfab59176bad88b9a7792ff2cb03aabe6a4c2937be24645a28c3a7941f40503769eede86607fb44c4842114980ba64a59a647438c5476b8ddd0dc4a63277c4dc73a3dc9b59bffbdddf18e7612ab73bbe4378e93fa4a8fd1523ec5016b36a639e4f689e9b7bfd2cbf501e23deed07fbfe4861ae7cbe7f7e7b4d5dd1b78bac719c6afe4d96949fcfb1e9e8794b4988a7c03a23c8c5a751ed2c39d4ee8474b43cf8b7814a5932234e41fd543871bce02cbda349153eb5ae3ad57ac0670fbfc7ceb4435f84ebdd58573aec7c0cafdc6756556bf034dfce6709e65b16726625928faf6d14efc0c0a66988eab99643b4cf23ac697f4ce645e88dd8b3f204f2e8e8a9f838b708ae6fbf27445a7555d0cd52982cb00223dca46ddcc428aef24f81564997d5f37d0a1c411cf73d3e2d82e5cf6c3bb7beb9fba2d9ec631f8953b4dd30763e8b4c8fdb4fb5b177d43c11e8979c74d639136fa20b718c0846405bff0604c55cb8ff529f41d91ea6981dddbdeec7445ede93affe83446410a93150178a4a2b52133e74dc1f8b2eb97df4e8a617d5876ab9977daa8b7845537ebda2b7ed599c0cc16543832aeef51d6aa09d5b30f37d40083ae35c2b831b87f2c426d72c655c4e6eee1fecd284a3f84a1f6d49b5a03b3593894bca251bdd1996d1a039d0ca4d6d8f5b69beda735a45e2bd355dad587bca7330374d31573b44ebacfbd103bafc7f83c1c9f3ac3a41f16d7d4b7b7e1e78eaac9b4090538b6b7975b9c5c64d6e96577b7861cc88ed6c3365aabcc9b97a6b3e8a3aafba8b17376509a563b58dfbf4584e7bd0d56bbbed3d9164a8fd1c9d6636ae46c04bad614cd2c9efc2d0597fc285779d6f8f3e39da84d8710745c4455edf12aae40358991e7defdc787faf55d6c70d3e223dc2e03b3ffed39ca3b9bbaaa34abae794d4266e59b8defb44528b3bf34e8dd25767a5dfad9032767722d6ee544f3417458de9f8d9a52f57a38dd1e9c8ad43b775bc853d8475abdac86811d568e9e387486e8aff1bd901283a3913b6595cb2a85b6d432dedcbd9d146ab85ea5449850bc9d9be35709fdef365731f176ec1ada5b7f35d9848c42603fe6a47d46574a93cfcc0446e4e8718d2672ea06bddd582da7b655fed505daaac1bb10d6bbaeb3e80881fb891344b7b8652446e4cd706c2dc098b0a069fcedb89ecd67de93e9c92f3aa0a9b92a10af6640f587a5859408b5cab563ef28e4cea386becd756db669fdf87a003faee7654cab39ef20c2ecb234ac1c4b459ee48517bc838092e91de35b265e5f64119c05cc5d0a063d7c806ae8256e28b8e94f72df4f6bfb7c51d68925dc0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73de9ee9743f830af559ac53aa38e981129db5837d00d9843334ea3da2b77f4e588b0088e3d43e8d0dd49c4777f7b08678144618e34d6b9b6b72698888c55f9b7e3b272f9f620bb367a2f66c3da4c9d4d3d1d49650b5530bf0e7c3b99c06899df270570254daa0bfca823059823ce8982ad3b1677de127386265487665aca4c27ee0246f1a853965b6f9757148e37833d31e453dcabf0191c94230833a6bb3b93c181b651918a25235e22779cf052e1d30e6852557ca32aaf841834b423a9e61cc24b5231d7590f863e814aa19f123c0cba97cb3773740871ac23868731748355a85f03b275b3273486142153be4920bc9ee77ab5c05d2b96228906586ec831ebe8cf6f9bac3631b7cc904dfc768b1a717274b33f70d08b6a79c4aec3597e1c9664c9472b6c100c1601f27bc0aed37152e20b327b5d32646f2980bd780c8f476715ac04bf1e03c2d4a31da23b14dc0233c1a2c2d983627bbc845f023e349ca59626a99eeba5dcc12e8b82076ef2295238667308451c2052c6f9b127778a3c656213a23dc7e25660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b881b0365fe513fc661a03689581e045d2f921444c6a76e6344ed8a335b6681ccbc7b42b50b9b03558c64da65088f60b136882012135a8a659355503918ba25da1c167b9fb9f771b5727493c921338c1acccefa80201039d28c968aa3a40c2a28835f63bde23b9722a245ee3c859997f45e10a11f1906c1485b0b51093f51819963393a692ecdb1dda2c88a6133f69f401b124cad796217c818152a528f7d073bfcb9eaccc6cc8825ac4612533126c1ccc736db53f648201ff29a6c3f77b41e01de2087986f237200014e5fa540735513400004b5925cf64b0ffe9575e27ac19ac5644f355231bcdd70348c4507c80780f1d51abf6ac4c5e2957a94325a3f64e83a0a192516f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a723fe1a44fc97543f269f670c593935bdf87a52a1a31cd2b9ad92807407b5851b49eb1a2318611cacaa7710b6764a7e57f8962bc3fc483a8393640e602ca55526eb1be56f2c61ce802b9592f24c14aaa75aa4b002ac9b81fc1327b2a93aa889c9eb178bebdc91579ca7bd30796cc324447892558d2c052308946a451ca49816c06aad39603dd3841ef03ccc1075df164739feb342adcce87aa12f550200ce94765eb4f291a5152941b4eeaba91c3a59257c03017c0b7e0003b07657ba60b4256a8a4b205d7646813246385b348ec157dc6eb3be4546d7eb85c29512840018968743d2ce147f071c8f96c7436596337d69f5074485bf4a288833f2855787f8a18d874c5a2a41422157f65b62b5e581c2181a7023698fdc1ac60a8340a34b29f81b03dc35da2b453fa61293070b1c6db57f3040c3af7766c69b84d624dba1163feb0c71fab6582473f93c8753d67b0259a2eee1c847b1b8a73455a74fa10c3a4c21a35ad20fc36d563be9bc55350f565e4076670f0c77b3c4aa2a06f7bf2ad1bfc4fc8721618454d640189a6f8b3d6c71086dba68b213f4c51100a6037e717147893cdae20a97759204b2c684d8206fdcb10df575799aaa3de388cead4446dcba8e14368f7202520c71e453b41cce426be6c1e29ac475c45742ddacf7c520da15780a9056183900559129e5e3cbb3feaa288b25b6fc69bb8b164c1db8e24391172a8c23859545e98a13725130e45c3d1cbb5d6f5c0dc275608163916013e6e466c29502902c97d3bc33dd006abaaf2aacc40c046e55951d744e31887155a3fa880058a8767b35684445982767c697540ce339a0f4c29c2ae42b5dac5047c12c22bcc155a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815dcfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +ciphertext = e3305af051f2b2d4d411b8846aea1fd866b2e9f2fb4c92c7d70a7c31515dcc9b9b5795d7c1716dee295b1b92703315bcf4a5506b70eecffa872a1c94585d978bf2b610a464499f36e58526a1ea99aadfd0f18ffa916134cdde7b857e72e8440c33de1187032280cb1b9cc7facd37abf84df7fb60b2bddf242dbbe89ba881d4b4a4bae19d706cd24d3dddf19e6619a0db6cfc5311c5f917dbc9eca99fdceb6f240144bca0697c2dc759446abf52f4a960afb3dab2a28c9922f29ad0c93a24b3f276138a980e7c6fe6d4dd349aa4254fa950ccf1ca5b177eb10c13a795ccbfb9b866b6c1d1a7b92e680728f45be3ba332d026820bf1f3b22ae9360d9a80ef9412194c1801838e2eb7467855bae54063ffb4a173796ee577769859812985ed1a0779a1b44b31bee787d6c894f475d1975bcc5b956201fa8029c1a50579893084874099c5d9ca37b33c24e08dfb45ad8c3533161feabf9290666218010de638757d46d8f36da00eb73f88d363382e3c99773c34f925d95da1486be5fa085e6670f34c6ad07453f21b3509bbd1eba6d16d2ca83b7942731a99766ae98f1a16df4a8d9a6c44d4c9c026f0232aa8219f37eaa2764945db0a57ce9700c3fa57849e8dc7848425b7538267b749c1474ca6f9ede161bdf7614f8384438250d13bd9fb3b86475de88bad4ba9cab85e94e3ee8c5f6a17867fae42353de0eb6807abb0180261ba13b5c28f3374427d9b70a49cafe4fe60ccd4264322f313173759383a3fbab05e002fce19a98ca8e8d112ef35fda07636fa8a23b4806497efba14e91608b92a737756d921ee5895c36aab80f5b863ce28ffac7fb55534a7643e27707c6caefeba5a60388f185e2477a66ee285dbba5ca77d79c4f7a10d40dd61e9e161f42d9c8674e3a5fb00dd22483466ef309474ad64850a13ab5e9bfef7df441adce7d678639fe4cdd49d58d23d722ec96127af9819e392f158a0b3d7f69e872349ed4eb81162529f8767a345d00e9588e8238d1fc25722ff23240202d7b1039b2b18eb14ae2da455be3851466ace03d27fafe35f5b676565c4a259634d24593efbbb13a9225f3233340cf8c3cc3504bb43158a57de9307554189d30936d5a9399aa71739074d5d487d7c69c3daaa10e40f6007668e76a7a3013bb6a7ca94cf668847996a7a496e839821cfa586254e21c3c04e3d40f730847b8aa60f4cb1e028899f4915114bec79d17501f8369c7c5b0a16cc0bdaf10a9dd18245ae33b55ab86391cb027a7129713cd130e7327639a7afca5f2d291b1f36069ff0b78979157c938619dfba02c24ca90486ce306d552d512e1a6fcf3f388647232fb0ad4feb4d3c9236e23a53962dd1118dbfe5f4ee1e47677db5f094c3bb3845dc7d9f7922ade82528e0d68a76b9608f3028100e5cfb2a989dd0690cf3bcbea5d1a827ac63a4f14992974e5fcf00981145d40c8d0a943dec836042ef5e859b9c6c12ff19ecd8957579b43ef7960952a020a571ffed0e37f7844cf37e0932f573134bf43ca169f09cd5e69 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d575f41221565048f3b610f36d47f6ede9d875057d5cb4698a25e5dc0e8db3f87c63d575170f45d121a848d897c3d0d63dfe9b2d616a9665f384fc7fd6226a19309df15b364ae667c34caf7feddac0debcf450578c7de82da365d40786522c37b55fde26ed7b3c6bccf2804d871ff3736b394210b67ebfa72f7bf77990bf06e48cb7417f61a8688472ec529974635b35f5b4c530e68bee8dcf13387b66b5ef7d12ff3190d67a2fcf4b2ebb579f74bfd64e7fe995bc08e67388ff912b5b4dbb4c939dd686d2cfa4498dfa733e945ce95fbd67c67f6d862de69ddd4ef825db52a68c14435e90cefabbcf5babb734aa03538899678d439d738cc63eef6e1e4344ea73b9c41f36c712a4c6d7f42210dcb94ee44f3c588a2299d5704cb347b90b39d5cbf69cf1dc5c6719d9c488d94e89cd1bb3b3e50ef46f8dc3c62da37bb13b6e2046911d85d589d869fa4a550fe67957fd4819e9c0dd74b9887bb5d1f5c34d76b3527a42a46b689fc4c5767eaf13c44b7e3da052df8e98cda1f5d621567374de7a4207acd4dbe8417c7984645cf4f2b5a5434be901e9799cd760229301e14431b0b652c643c0fadccaa13cbc6fa6dc8d348b908b78343978fd5a0eef9dca61d4184f33f107837b3ec667fcfd7000570dd33856939bc8ba671b383eedb2a94596a8f2f37bbc05d48097d91fd2ab164f5c6a8f92f65239f08844ed406d6e3ccebf88d877eeb3f4c85bf696c691f85a94756e331aa33b15973ab59f3f429c7913731bd0f553933f21708d2ed7d78e3fdaf3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfd6e65773a965e65d34eeed94966694d88d6f205d6cebc3b3dd3d7405431fdbfe614089c633b52261da5fca73462c3ffd7afd0dd6e4c5e88454f28ed846be9b886625aaf372bb3361b9abd5baf78b1773058ef6108cbd20aa6e0bc19af13454df46b4fb5a68c3e7aba6f7e97ad63439d7f52cfa5d7e42d72e447f96883c93a1ff50165a1aee8be0ce6acc30f9e10e97536eb958b79eae3e3aa9996986805c6d1f6356d26c1e63c55048eb2920bec96ee83ca933d5ceebaf6294c4b248b426472481fb2a38e6ed4dd9042287eb9ae7ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb91cd457eecd673e37e21e85537bd2d97d8644539702be93bb6ff58064b28add53404bc78a397ab86895bbfe934e9bff6cc3ae48869be85ffe581a6ff748519bd3dbc96c716b1af4a02679ace5e51dbfa0fb1f7c81ea513c3ccc3b84a34025522486ce424bc04c96dedc5758aaa9dfed47fdb324614ff9e589d78acc88c43c2643d64da50afd90ebfa621493fc76ca982fbaeca4465f9c14ab4e6459f17f558946cebb1e3b5fd7d24a364970d7f93343ea6a5bdd4196b9e72e9596fff9f4ef8fb2d5c6c5cd41dc2f6ab71eb04c3a80fb5a7f16ed8df3347df00f663aa39409ac4e8c8bb0934b46b6a8816cd7dc8c1be1a7fcecce57bf5baa30e7afd7d7e59c9e386d5cf7863c133ba1c5e0f6ed6c4876ba7849611bacc36abd39f0ee73df6b8a22469e203ddf2aa53ff84390b893d2d9f9915c4b8257754b3433d97e7c6b8452a77401c4e343bdcbdc985b70189ea976e3d65c47649593c9cfc112a4292238302253118cab8ec52060305392e6a131f0445a0bb4e11a1a8d7465e704b3134c3807d9be9f8b2abd57a00758685392592fa0b01e116410706a669a0ec5acb524d1561a265e307c24068b12897568490458121c572c2cc43b2464f2703212641202a40b27a41fafc4b24bea9f26711f28b1050645a38757708ad607ff6763f14c15a2caadfc2bc4d23c576e5cae6a20b10cc9cf610a5931ab4c59ecbe67ea079bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da3515288f933da602f1a2747a6856657b2102774bc1946163b534d02a1ce2e641cd9fc7f7d48b6f643ab53045bc690a249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4b414c223a52a6c88475405232c78ab3aae8861a45a817ebb16c3a3070b8e842527e965013244fe50907bac3883122393340b1e06728fa0400791b1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a58604599eb6d1d248a37ebcb17335713c4c9a0500fbf893df475cf7c19792fd56fe0a7505de0158f34603e0071b2aa0bdc8a12376a1313f571d33686d505660c4bace8ea40820918e05bc15b381b90d9b31bf52e1b18c422c3935d04140170542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472b409b1ec31ec887fd6e76ceec6812d40ba4469b3eeb028a0a6875a19b7aca51465cc3fe78566a3eb1b98c621eb3bbda4e7beb5f2344b64013ec233fb5714bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f7a228d28a5936968915d026cf683c762714830c1742ab4dff789f1f43782622a070a4ab52633efc52693b695dab939bc24944733905ae86801c4577324c625159b141c5a1014a6e458b71a959001839c461e17a3ac46da47ab687d2342ff63b83d3331510c98ac484f44b7fb6a31f6926cf047982c400008bb3b0d1ebba3cb2345613680531b0708a64b937c88b2985c01a10eea22fe5022912f9ad2bc667cea16b0a091f3fa9bbb9b8c30160717b21cef9d74458241beedc215d44900cf40709f6671f221d39c804eb6756c812364df0503355b8b01102574ac3f07234bbb1b658ea822d52a452545da3544c041c3a3f89ba30005a992b432178bfba078686a07971601f8b12c22b23b69c05a89adc2469287f052a6d4f58798e10a464db4aa71ab30a94854d1b8c16893b432a8dc2859c66a168c8c5ad4d04559056c4588b0a8755013e378545b47efbe90ca97552c9b8711d3281cc7b9057f78a68a59d5aa642d1e9233de093df5705d8639d702097f0dbc98451a46905ae72d876e1243546590599fc5923b37b4cf0a3f7cb47dfe8af00f6a999127a256681a5705bf5100d7096713c49149c7c561c0783e048cc3444776bf8997671970535c2cac5360c9b53e0d952af348a28e4826db9810f07110a48771c2c9b21da3ca719c7a5407b92020aaa0180b4d6b3ae42a1c09ca38fa59d1ed02a3a0079f2e922d0b36d9795c1fa42354ca51ddc11a315515a45bc7e1e21bcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dca19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2aedf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +ciphertext = 9ec0cd62bc32489cf014d70757b26fb83b3bbb19bc0c216f48829326dcb00b90256a7a5c4929fe9aa669803594abda4d1daec5bc98176a0cf44d66619dc04ee086b7dee5ebfec9af3d77b775d88a0d458f2a3d5f7517a98ef5a1ccc287047250d7ccf20be0154833116bcc1974534f3336441fb7e2185c08c6c79a4cb12cff37f05473a508dfdca60d774b4bfc5a52f7338648a8b2e34382c7d909ec79c620f5af5d3458985ea89c1316ecb77eeba08a0b294744601d0ffa16608c76bcec186203028c1bd5d3c285052db30ee906a2183194b790f8fb6d7a74ff6dcd25909b93bee46af942cd43defc71c7a70cc64a146f43546d03ca0ad34d8dcc4528a8f65d3f69fdceca37d78359cbd76416ee442292b3430170fd589eb8bf278df46415c740d31624fab2b73e116ab8b01f61512de5727117818598470179de87f9fd007475eee6297fae76e20df24958782bcfd4b4c3ca2e80de164b41bbf304a31edeb81906b22f9572e4411985349e826f6f2c37d5668f93e6544dab78cf8d4787c1234a04a98e8120bdd2ec23cd69f2f2bc42877091cb42cc459d5ce7a88d19dbc6b52c9783e03931d726219cee1be57fc4c4032143a7855fe1df7df26cfd815f8f67942adaed372d13c55dd90278c3f3563233cc4441a261908cc81598f1ae3812a0c312a6860a35ec0c80173aa24d7ed55732ed793fea7fcec59b3b355102fb286029d448c3ef5a39ddfda82da997782e352b089724bd7e570ea6b2314e30a3b075e37c16e289afb3c2f0eca3577ff385b9faa733fcae2ae01d84fc685676494382cb25b14d41c0861a814eff00ed266e3c3d1f9e5f6a3b11923860ae71b0e139fa3c75a93bd9bfc4286e3d432ddef5a8de2d767cb0fedc1eb5e4742aadae6585dc8c726c8c8c38eac111a3a25e008045e11668bfb48f940a567f80d6f16e03ecd19e00ce59d1aaacf598df4ea754cede6157e5f62daca54f10e8172b92f0dac2183684dd07308a5236c480e3a6a5aaa174fc0cb166897641243b6401ed5cbc31180afd3f4fab3f9246812c5a5382e00ea1cd89d67ab1c3dc80bd52070f9654cb0f9b4c9f179aceb687396cced59ee20cfac6372aa759e9423f1bd96240741bf34af940079840229a120392c6e01a37bf5c24d026c4ddacf9c4a96364dd985ef98da55ca7780d2c75ae85ae08d462e54d2f0db2138e9e373bf65896dc2967ff481cd2b0f724f0086b932f728c201463fac0ab083d4440bd967d4929b7fa19c3a5f2f9b8ab237722d9930bb0f31b932c5538725def050e680bbe4b2f92067e739897d6d860a8087af3fd4faa34d09a9d0362edb5374ed988509ce4a61245eee1c1c531e5e72b977be3992caed8a441ef8ea849ffd4fc2efa3dc9f254d582389632b29718f638a6ae13ca506f117bdd204bdc2f1c07a182b1fe44e5b0a5ee3833b8611b0da300b28aec5d798aabae37a97b76a61af12cd82b017c2e2503e9b1c56311fe79e37af0b881106764fec52e0b1724f3b371a90f225bfb1080dee64f4d45d7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 953b6e6f55fffab6b9e27b70807dd993fff8f5fac9278daaf323d0155bf18af5ea012a4cf53840cfe7e4cb63cb4c7aa0e8ea6e518d3ca47dbb38d7f05d9365448b38308868c83348acc365bf6fb4fa763ecd6ee2a48558e67f30d92b5869d77d99a5c0bef4981a6ddb3343d0921ee7e06bd82d15368af5f9923c6bc9d3594ab33c91c8e54a8f9a2ee55ad25f493f8daa80399f770899ec05417a698e6493aa647691fedc92855cf3702caafc8ab3a3194ce8437b8e2a7f69454ae03e70c38f972abb93cf25fdd85587f637fb0c7e590d8eb3a9f680d1944500fec3964eda17f55272cc3e1364a9aea7a67af4561d0ed143b7b7eb4ab0791a8d638e4f4b6536cfa69ca0493fec1a53d597d9fbab9c87578d83c9441e6fc267e7aa4ffdafc81d6c9f834a5a23f06c4b58d7378af90b85f8ed5237559d6d88e9f455aa01d68bc297a8dd86da0df9715439e998afe8b496ea49e45aac1fbe6718dd198cf5ca53483d88eba27893d23baecd393dd1643dc2a53275c84a1aaddb364ccc94a8ba3b5768f8dbbe08a7b090df746bec62c98c5e5198695c2fd48ba5c98753aaba88bfbbc6c8de59dafaa8343d334aaec7f532c63d60667079c4eb6a287b04c797458acd9104c94e96bf18137b0868737eddda8f2e64e0a8db9c2e35dc8cde81eeb931dff8740cfddcedb5542732e8fa80e407a1a6e5af0ab3e68a963587379aa3e6a2b18fa8a366d4bae8f7bd6aa1fea76a619ed0ddd4db17283eddbbf335b8796ecebb57887787b4f73d4e85867368be68ef6e5767bcfd580f07b003556ecffc3ae346f610ada80a2c9e4ca9e4144551c89a9d68373ed9c7afa83c75c6b8affb64e87d3b46abdc61daed70b5584be7564f932985ea4c739cd9d6732a7cf79a65f0f7b0682caa5e2d70b4ed699b1bb3ac0b38cb0ffda4db9473dd6b02954e37cda3d899d473588c77e43990eaec710398586eca722ed9bfcdb8066d7d732a36baf897e93c6d9a988b94c67a469fb7594ef6fd55fff0b45a0348f49847e5c60478685b9c2e0e3d41b47eb44fa05fb76232554df30990d7feb37eb9e7212dc66fac8f4166e5eced7834af588e06f3044d74b214ccd939564817e822eee09daa87c1fddcd9573254538ec3b8459ce56579cd9ca66a508e88c4db06e93a268b86fa4b7733a8cc89ac826e9af8f56d8aebef665a7ac423d05be730ab4ecef3bd6a7fba53565fc8cef73e90a8584a8b799d3f3f61faad4b9cf5d06cb883493147069eb1c9c8fb36fb699693d17de262e9ce5b383a0d27c1572c49547bc909ddd34918f7343a690859a15c3de19975c35aa991193d52f117b53d06c5f4683d19ca5ba6f5595b9bf69d96c1b45f4cc8fc6eec85dca33b55196d3f59c5d742df46642bb88e06eb8bd4c54f48af3f573d4cdc5143ecbddab5a2825dd721544e16e35ea8ad5f172dd3a6c3adaf79d189bcb074f546bd2d33b1e8b00d56cf33ed733dd8ed05eb358d148a91faca963b814a9c5fdfdb4de79b729d0cf7c3d9b48a4730338bdbac9cfa3638f68159979f7be0aa9ab90adab98bacd928fc4e367dab020dfe5a64c5f605596e3498ea63f47286df61dbfeb734c174e48237c656636645886b65c566bf95e9f7a16730c3d8a8484295a1d995716a3bf93c7270671afb7886f397af65f5bac1b1a1a49084d1a672a1f98bca762287e90410ab01098c74869b42479c2cae5906ab354970c05cd256514f5c2e763230b6770884e7b700544977993df1f57969e0265fac4f474b76648b36f5711163638069820232b8a64f16bde83557b0540405d7987cc39069923dfa984ca4045999a77483e04fe6eb0be954a74c13cfcea79ed0d8124b01b740a26ed961b2bc496cbdc539a10b8151e0078f66751fe78d2f3a5100761c8beb514923a7b4f3ae208766fd852222dc31fc1a59a883c401459dc73468eb35af61d28ec1da147c882cc7f5ad5204bd8da270e4c91dc37baae1811cff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6896a288a9722183e199f608cd7a412ca949113e87a956e4ad12737d53c3be4752533bc755f7a1c4b07661e988210ac72131b4496941893a9c6f1180ba622436eeb02f3a3a090c00b1ffd310e811a7a8b87984d275d76b0f99abbfa45cc5096a1562a375f0599d9698b18012a84a0628601c731ce1ce6824907f1b16878a75418c2fb0751202fcc988779be2326e2e5228c9493a0e628441b13d58b3c79df34b7b53c7be816cc7368f2f31c380296250b33269158c4f9706d75b3b5536adfe5b0bcf514899287b4b637bb4249db25a0413533d628597ddd745a7f5270d136763e48a517ca62e116913350e7361580cf77bcdb5b607b38d49e1581654a61ad9602f4415f484bccbd833255a29d2e76262b401f7fa5a1e68bb136771c41b29333b653602b79a2aba21004e8a257df7362163b6512eda4e1376aba1facf04d1aa56c814000d718b5b504f1b9d2e627b8a678d0294c5e3b186a67c082b90abb1c839232912c39c3e02717a65e24a185a5d96e99851eb538a4ab872148c2d7bc52ec4270f708690d0678d43c783ca194b4aaeb6f2156297355d7823e0f80890608768c65073e04e7e5b45acbb1cb6446483e7c315a0a0c2066f080a53818a4ec0e4973f630f6822a437f6684fc9431f20a306a055f9906435172699b3cd0d46457be26560f692864a97f80b493093270b5225980287f1f5711b355f9ccc018d670ed8ba64f10ba98b0068e7714074e14736087819ec2cbc960fe6939a4e9a4de2045b53e81fbb845b0e546de6b34ee9e91ecf0c9f74c569dec949d3ea11785639126bbd45137021e9670735488e46a325342a2b4a959297816d1ac731cb501d628bc09083ab5c4dafc09a36c7c70f2885a6622bb7162aa2c999927a1fb749bae280237db21418e2cec419990288b813e80765b47e4c314171b849e570c7533cc5bb77cb9f10272926c382fc0796f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4da2d5264b282b32933d8c74242aa73c15875934e99d6c570572e03c54e47726e3b0416d3737a29624169778970e99de64bc2b16039ae97c7472a41c9a6c6fd45bd7738cb662505bb26a307a2cfb9680f5cac086f9bbf7799263c0b5367032196f1bd842534601094668a33bd339db59746d63ba6007887ab750f5887453e02b22c3148bf6c48c806a94cb7bf23568789a1260c87af0548c71881401c565268317756a211b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +ciphertext = 7c8e5f4f09ed554cbed6874d860af2b8fb97fc6de51e23a003338d67723b50616d0640c2e7e1492cd5251b0e4f442db191e500b3fb6d0fa76e6112f20eaf1e8f66e6634de166f2a67ace1d95366bc124129a016f6a4d669a643d9d90223b8a8829ca2314e88d76ce49a05e15121fb7116afe19dd38603e994f207e827135be71d62076b75453dcf6588b1a1c98ff2c517a4620f5d951cf06be81f28bbfcd08ff396e1a0894055bea6b7ef41a333df33e5c24cf30da5d78c5de7629cf8bf458255a3348f67127ad36d71641fc7a8bb9bf38c4706afd14e9de0fcc798c0fe35aea08343936f552a1dd7ca42d513c2896ad762fa4c0ab737d94f63330d47aecd1ea50a083f8660a797a9edb47ab2140748a610e981085f7dbe268e25e9b748dccfbdd9c312bb64f41a143a2a7f6e8d0bb7db83325747a414240e9316c2b4305940a42fbb9d5d7b3d0f593f63877d7461934a9a125d16673f288e828f17ffd75c0046564f092d47e99c59f51ce741d736cc26a35fec6d1c2ae909d6b4f4e635221139c9e6ea9f1b1135031ff694e3e12503e6315bd9abd54d0b4fbc9da7d48463e80ae57d3dfc1bbb468b206659f60772a2338f38b274ffc0d391a103e0a1a50833218d1165ea4e88f07782b1722fad72bc409feecbdf6a0bf99862af673488d3c39e9b343c35a5e6fa14b3c6893e727347bb965dbd9f8fd50b1ad0f23f7d3307f650ffdb5d8c085acdecc4c3ea7c52b1119175721f4a382b91c59c26220e40fdb57ba76f44238e1a77a062025daf823219ff117202f5f8ed2789b2b9e80bd98fcb4a4f42d006e299f190836b7e3f3a66e7ba13dadef54a2e5029bdb1d0f29318c3ad3013ce6793f5d4bf15c70cf79883b0fd455e9fb6bbaa0651d72596bf2392e38fa140cbe0f9e42f0beef0eee3263642a52f04f345c672560914e80ffa70b4f2700c8823a6c3352331690b54b3c20320a8a810f4c5f0a7eae739e343a93587846c4acdd4d93ec3e48e9c4e3728701ae9cfff5eb219cab6c50ce52ebe263bd54d29d4e785d80ee87cb4f064d2b38c3b2090329124ee0c74e4e7b7779769b14babd36396e1eeb8614b3af9f8867dc8f93c46376f8a5450a3761d6f4b7de3b4108c080e5e3c4c9628f160458774f0a1994f9ef5ba86933670c800a9f76866e38210a0e26650dcd110ad5f0f621e1c6cce1279e2c8ecfd4055d32d7b7a910eed993222cd2dc83dbfbba7d04e0121a849b545f646ed140e7afb1816982f1f2d8c6549f9d73148c5adeb3a30a9f3a459d3afbc552cb999bbdf104003955221fbdf7f6d06e9087e3c4ef49104ca51510c544b0abb048d1345c72d2c5e873555019487124998a67821f119ebf6ca973cec4e29bfb5704c92ebc7c742870e8de0f5811cff0107b168762d8051551133e3597ef4d56d50fa9333c0b5e6ace36ac36b0bac6ac16cec413f7e9d449f0ac9607b52f5a43f33921f3f226eac9eaa72ec17f0348b04a5191adb2e7571a4e1dfb11a1e2f731c124a6246d94bd253bd88296a9e60363 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 88cdb4d44cc9eb48c126c5877ff8792abd8485fb81e489e39d3f99c70c43c3fc8c238a81d4f6ee62a33db2499c866b7108eee6b7fcb1b063da7e758a8d487d11575079265b3158302a23732cdd733017ebd7cb7199476c39b583a2446109e99fd5c95be22af92cf374919d6e84b8f605b8455825c82eca4b7f2e864456dce69ef14c78ac4473688bd6a9a836f1759dad791b7835a8593588f847a8eca97b6dfe88b6380ecfbe49f9a2dbab1638e55506c353639d153656b90c5aff36baeefeb87da5bce3bed8fb6c3b29e77daf8d3a0dcba48ac6882f7ce194e8838703db48cf7d02c37d988346a3af9584a55cb5d3c44c05a18619a4fe5efbabd3ea057ff1b3994c902fce272c9e6e948c3d04329504e4349796c399e1f8dcadeae47352ce5e9a1743eb65bdc757ef37fcc93cec867cd4808edbf820ce7efe0d4dd64ab432d664864b43f8a9b1e763529befc413abbcf30a4a478a30a11d4d812d37c4a8af01b534de7dde32ae6310fe3b2f83d924cb790166af3b83f2baf4409cbba501cebb32894e65445f04e4b4b4933de61f67645d37faa44e2775caa53eff4e16d0e61d69aba662c96e45e31e7347cbe748d63e412550c014f37d0dfc02aabb18d8533d19b1a879a079c3ed529aacc05f58483c80738b380c93e19d1fb23cdcbc7e0f7506f3705dee316edf4594a4bd33eed382f8ab47478f23763898398d754df64203a76b0c4455237f3e765ea65e6388595ceaefbce2ecf258b5b96c88f865fb53554f7a2d88d6124bdcca88fb1d3f9411c6c133934ba4a959da88a072bc6e2d63a00767fe36c8fc5643564bec47bc8953d4aaabd146ab5eb36e3308f6fb9ca01f2f3253d3f0f76c98f91dca53afc6057fff7b6d378809a59b19680aa69eee3dd3e37fb8a1f3c8a55bca129640c6bddd187bcaf475f04c73cee67affeeb4e4f02859c9988357df6665196675df5e64cc5689965cfebfc0e47a531cf3fb3daa9c649954342a3f62253fe08f6aafca7dc85a7a8e25e61445f12d7a4a3bd4b57a2ccca45d6999e4d7d9b6abcca7f09fa97455bd974ecfc7cf3c3fa413d6ce6f39dc55d536974a8ab7733755d4b9889cb42bce4ef4606bdaa559346f19dd87bf8b7f0dabf1b0c9b75b69d3195bd745aec47483488eb4c1ca2c83d8198cc6b5f3da3f9f668f863cbcf951268c0187da818ec1c26587d87ed088f6d68f1fde1057fc825c395ac6783f074efa8597feac3734399bfa247e4e1531ead7dfe49355e44b3ba5439ea1e65eda94485fc7e0124bb96859df1c8b68e87a4c479fe570cd6a33275b6c3dfaa0e5d8b3789aacb6f7f1fdc19026cec38a95f7547d937bf55be7a7525c97ac4f82714c32a23c4723b8f299ffce90fcb4761b9eee869e4d3484ba3bf22ecf8bc71fb1f426d7cf57781aadd09f29617549c0b2179705a34916ebe54aa3747867c3ef7ad693bba5c1e4fe14c3f47c5ed5a09f607b6dafcdecc1c6f3839db943f5ebc4d44daabf3ef69095b3f7d9bde9ebc21de788794b63e1098cc39d3a83daf027e8bcb78b855fd56fcf16b45e47994aac71fd8e5c521ac1a1b697a18569ac38e6f52640d09d59c4eb95e60aec32b77bd7cbcb6ab384de74b6a37d8400e980ad735e9e838da63ac7a3e1cd3e574db17c2601d3927cc2a9d228a05f5c1e51a63634383ff5e03151f43c66a07be9e992aa65ca4ca17b1e021e06b261ccaa89b12a4916a5a4e39826a94c86bcba9fc7d65ff04549db70b300b1cb280b3a41e82b6c8b0a4a3c5e40eba59fd18f004ca3e4c15bedf22e099c99a3d114eb0c5988ba02873b9581107a23e54a8e51ae62375a887929f7333d4d763e23b20a246785e07700bb16c531692531433eb6a6594d1464bca7348022c1d4219cd8aa6614862c42376c3a0c4674181983f2a2ce8b7f32659ae87accab6023938592e188a3c1015e98720eacc9aa837a49c4617a850c89e1212478f3c6bba51c30a64a8a1c225274c92ea953872342a96ca3235ca7a9467be55250796126b30694f71b2f75b56d84ac89c4b635118145c7b8967de515ecc719e35804194b7ea9304636283cbf72339474ce1da00106110a596725574747dc07b3f0c7c527aca703cb23baa080bb7a4cfc1009b3e5aa89659121e365fd6cb6fd15afed70779a978b3ff50f915b6c16a350141721efd61085189c3265530c1a17491b317031b4e4667eb8314ad34cb7daa50566a9812377cf24076fc3dc748fd58865b1b02dbb831b25b7b7383579376fdaa6c8a5323230025a4bc66977f6a458374faeb14e47f70e654c42c94a5fc5e386a57abde3f29349623e4de92f900527c165870fcc26a2f95fa1850f2c940fb7b87686e253dd54b6706a84a0c70e3ab04ca8446efb77609e9815a261af5a135836064d44a485b5e850f10153653838e5874b76568516e847a2a9b186e8a50c34c2d2b0839ee58024211018b0a13fc781623cc313b30c26a258106941a66b3cd9481aca7c7e3ce3202f098746c42c58f4c7dbe52fb5f606fbf31b9b5022e691cbef1464f6942aa503147eba081817ae28581ecdd867a96195db320bd2d91c36db01ade9affb6b00f86c13e2e252c988300b05afcd007470cc3022e96af0768dbebbcf62b53345b213c1544491f1bc75ba96bd73be57a2cd6874511b44bf2dd27f4fc87c167815fec59f7a043f699ba4d23400886a7214160c23dc96056bbcc7007a0049435c534b66971e6e5c90effa6645c45031c0c905b9887700181565b53165bab605a51bcaca0dd0c308a46432794c38f21e04172005f4348211c63a40cffd7c32bcd57fde852fec793cb7013e74504721f6bfb7637f73319f75b08e3c25777c969c6ea000c9b79d6f16a00cc4b00ad7ca4f8704b2e54d9d27524f6b80a6d51f85447b22c29af0036c6ba486862c8b4fb03f26042a0e195a3e91bc303770ac844e77805e41ec6aca920ff3a1a3abe81b598c193723b20c8685590131da89c0ace08a592489791911c92c7e6ed55f642caf918173f190b2fb8cc0cb2139fb6caa259b5a4634cfd0a532b719903e32831489a2d390b4c5a5066b4ab5a3316441b162407096a0bc0342599804752fd4f21c45923705a7a04012ae4a900c01d584f9f41676c36681994c2f4037bdfb84a69a81fa561e5be05777b571922988eac714ff249926fc9cc4e93666e198308a434df74dff3c5a440948437a7c500582124574ae225f52d322d0909b5e946a5e22ac8f774f69c48b7874417bb1c0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f40f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +ciphertext = 22f3f2214b8b2b7fdeaab34d714c6c4a7c474464bf0229c2c7f31b323f65f220adf521118a41218c92f737c2e8bb753d6e19649e5fcba1f5c821a7d5603c84400015986d669ef0847ca0117f03ad3ce2928f3b88d079ad95ad6396afbeb8146131bf4d822dc4dfac100f23fb329e23f3123fc4bd0605903dd911a6f9c092259a167445caab38943790b7556469cf37c07f06d604906d4d10af9370dbd8a2e45ab870063ddf1b3f24fac5c7b5b348bc6281dea95547c84641f697ced7b000334493c35df845a12a1cc3d61efaf5a84738c2279128485759c838993d7204706ec6487010e6935d71319ed2dadfcaaae323aefdb7fc4ec8f121ad6a3bf1f31afe622bcbe17ade7db20eb98ab81a5fd91cd22fcba60176084ad5a51aa5c786650fb0eae9dfe79f74e919961e018f1718ac031e46fc3601a6ac4f83d3cedc66225a1bd7879217df9b8fc3dd0be1b9992d0bf7c8b84854d0d9bb82813f3dd74a5b7f38d174d67a00743c4bec322d6fca86ddba4fbb199c5d1a257b5e94b3b1f3a5d8a3b1fcfc4fa56eabc48520a2db9291885d912173ae0bb798b9b5ff15298cd87689964a5ac8283b4d5fd11444ded04b8abbc91727140c93acc3c817cc66176ce64c4b7e5cf3d5063050d28ae924103b0cccdf116d72df01d2b492524aedda5522dfc54bc83912d18b984f7b3e5d5b1bee11e352b44f04f3ca3906cdfd4a08324008665d712ae8ea746cd4dde1c70f4f4299a22ecd16d17d5f66f1060311a378e7b8d7e20d1d7548bd902ba9f4559d5f870d587cfb4a2f39d41743e7610861d24e8703ca8575228ae41a88d3f7d5cc496694873e5fac388cf3c42655cb521d4680ff42a12a6e1f9e4f6685c2a7e786c1ef26fd6be01bfc37ad8618bd799bad70fcc502d9fe543d91b47e10a58a1787a2caac3cb38ca418323ca97a1c0d4427fe31ebaa4d548ffd41e696a541eac93baa53219944510c4b8a891d930d656e66da78d5ee1518fffbce85cc31072f234a0584c97a193737f6044a2ddaaccefffda4ad055f01551cecd853bba68d85f24037d8e34cebb8d625c80b5602a3c6080a393255829f94dca02f7c6f31a674cf37307dc5eb649249236cd8f44281d6becf64f9d301dc2b624c6c0a7ff0cb38461510199b83b42d716c5fd6cfbc0c571bb07620ead1f72ed1960c97d76d51805a48bf594357bfb08a57c504983d1cd8ecef8a6e5cccf0abdea45abf78c044f1dfddf5a884ec3182c3884df3c1e271408712f1d55be61b80e9d4f64fe5f3a4506d85875a59908ce0223e40c775ebb258c0cc9169ed8dae85266a7f191c5729d867fc8d6185798a1bd4a6e9f7594eaafd61a925ce5b18f7e07885bb2d37704a544dcb9152d1822c5ba449fe71c499b46a6590aa8adcdc3be9d5c0a94066a53fc682f5d01800d5b7240f2188600a7f1099e2d42d9dbf4e2831c0e046692548918212ce5d52808c6556ace187ba18e0ff1bf27ef6425ac18ff437de794d546334f940fa5f545128aac740fa0fd0a44888346a70f0bb9c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4dba785c3f456e16a8eabfdfa7536f1b4555a9c4d3a09738658ae4846e788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c13cf84f848b89585f7699ffd65cb906d39b386ad4d2f5b2154abd1e77ad960eabac83f3788db33d7defad5dba40cd7e8525819593b7d7e69fdea46f150ee38a475e4784af38985501dca6d20bc8dc1c5c784db3380435907eb6e98bfa0e7350f86d8321736083dc54e0253c6e5c5666ddb7e68355d4e98daa753c1acce429b397da773b043459e5aabd093a5b031d502ccfcab36dd41997861286924bada1913d74327e9588dcfe6fb68711c964fd2d393c73b7c967c6042fda3ddeeb2efca3dd76e6d1efc835fa92946a40c4dcff4655301edbd9434f86b3c7a07ad3c6ea37bf623faae2d9a335e34b6d8e6d93cc7edf1fdab723b272c7df494834ccd93bd89ddbc3a9e9dea4be4c585f827a4352ef33026760dc83377329ccc0fe80a66fac50833c0f96ee796cd0ee74b584f693223bf8eefcb446fe9b06154abe1ee0c7bde7ee5f5b5fb3dc64f6d663573b879eba69efbc590e57f1c66ebe388aa2747c519e9af644acd903a801a5c04a7afeac686c89835cf59a791ad5642274a0f88f44491670c66c9bce24ba5cf6b86967aefe77f8dce89740df9045db844dd8d022297cf63dc8eca480906d3a90a840ae7da803e6a0bfb44b396e6816073c5d7ba26a74d4908ea3bad3a0c9dbd672c7466e38824539f98a8cdd82a4d540d3e2f429411c4d3f64f4e9d08fde1f83d26184cee538b27cfb91f26e86dcd3904ba6a34264e55b3cb3157937d66e8568f46f283c7c0e88696324a4fd77c3e6fa5b5ecda13126f74e5792fed69eaba973730a79889ed3bf63934d179143ecf3ed39585e4dc06a99aee0f446301f3b8a6b539dea9e061e7b08338dd6754398e749707efb4d99fca55ae3ecabfdc81ffcf779668809ad6db97a6e9be5ff0a862e664d292c4af559e95a23c19e2b9fcdb9b4a5b9ae517873ccc6449a3e96de6cf716d58d50e7cf11558f45ae6580c980654c8ca68e67122ecb2f8cc6f915f9c9754cf18ddb30943eea1a7b06fdbc8fececf776b0cf3cfeac9f7dc93e97a417edab0cd8f983bf4d2c613e087976eccaac13eb895fdceceb6df045df04ba61ab39cad4c6b2b335d3d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5d4d970c435509ef6cbb5d705c6538696f49d344bdb7d8f0a5c8869b47eb90ee3922a5af390bbb7c8d9c3a2f66541671c75cc2b7b7f48e0f34fdae6da74f65e5d7d257d770d2e9982d6aec6d19bf0ba48b53ab900fd8f80c754c14774939b83c6369fa12f35d1a8e94679942ed2f7b46cc8f354ad547f9f9175c35861d7239aaafca25edf3c835e87d921e5c9b134ca7e28ae8c7656bfd6a4fd253ece1743576e575dbba8905f4cc391d8e3cdcbf0155b5301ae00958aa99a4dbcb473ef65bd5baf55e91a5fc4695ed314bd990ebcf2148cf2823dcf49c8d080841fc8e384e73367c89fa11099f5b8984169468277e4e252457b23a3a1e33a36fef61247fcb2c14d3094da87f96a31913a428cccdd38e7b3847fda4637f46044f2218c28e5f5a57d9c0cd2864fd43aa5caad03a09a35ba786a86fdce0b9190b548bc164bb826874c1800980dab529866b951c01c20cb4ad363c681336b13105fc338b1788afbff321bd981974c33d98a35666eaabe3612e61839d6ad65490d71ae992111719aacf12a060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b0731621cc04e6e2061e93cc4b51209ec92abb303bc638c52ab2ae40d746cfcc43b7576a240540bf410c14744f80a442d0555d474192bcd9b187a56691b63965973c7793668682852f91cfbce70d6d4832a1855cc4b83a847734c24019c508b2d29539fd1a114f787285e197b51bc092f80b559446f1076f02e984a1b27cae7aa1d0b50967939aac74cf2335ad421021e3225d94fa3b09148e60c20e8454c68a8022043206b7bb1e799c9b69286509a188db29a9ebb078420a0844c858cf4b11f9b4959934002be0229e714350451b9c2775a5cc8c45b07e121290eee32a73d46f8d7c55311a8c29027356139f153cb405fa14064c5c31060d7a964b33d76bcd4809d21b34a2f7806486bd2835b7f871164ae496d4264f89fb4eb15b7e5a7232b6c68b11351a41b09bb0c92c8437534d2b4c0ca2538023b29df93d93c98136780ff6f82846cc2868664322ab28dcd7279f68994ba5a5ed406d4d717d16c14dfdda58db1524f7c53f3cb170d45a411b07cd64f001daa0ad1bf63a11550c0c154d20f5096db44d1ab0a1c9d66581891a9314c18f778330a0936e7a2f3e19c18f7bc87cf078627770dfc5a2fe71b27eb8276863c3295c11e08703ef4a4ff6b3a1871c7b42c43a6eeb6bd1526aa95b7dcd6b38edc207c630bed1768ce9505544e9053e5c8cbf6a181a1a0f48c8a98b59c3adebcc3a5c99e61588834024cfc71c9dfab1df558711b311404a739f79b45b1a8a7633081a27a08c3c16478c9d24c1229723addcea225d39bde7851345b18b1b08254181b01623347a9a57f5d902290b10476083949556663309059815626c3ccb5302b978b2ce82af231934ffc7732352b990b21b69210f2acc048387b95c346974c2181148078154416e08564d664db3045dba82c9a7934de51ab5c1d7346a391baca48209c8c7235309943c1cb9cab4771c7eaf59321b510d430c88473ab16f54ae461a5dc613c6fec61a5e899552e835eff57fc34b7992755d178a0365c52b3f020ab40020ce21b45717654634606dfb2917fcc266193e2e5b2c4559cc5652aad1121cca0711e26c23eb33c1f7d389f2d742f384725d3268f8159f8c463585998289e58369fbb883caae21b87139e52d7ebb92b011cbe6426390458247c45f06f2519ab35b35675bf93325351617ad3ac470f73d3d3985e10277a647c96a6c56cc2346563cc496db232fd742aea3adcfbc506ca8cbada7b040a04f6e329fcea77bec0683e1a87c396113639159d9ca52a5a5484d2839869a2e80557a6bf7ce2ee295a464aaf835c542457d021c65c2b2a457c771fcc47f8b1056c8b7aa61d1843a40c4c9b083269b2e89fa3ba5959f89972805fa4b46e35abef0c57d875c54804de77071f1219195bc8b4f7c18a19a7953573e7f4157ca03be2852461a784e736110157ba3f83a6947aaa09e9bcae730b9b212bb837627293a485ed6b42ca1cf26792676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f4f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +ciphertext = ef721977b01338d0f77a3f31f04fb6dd98be2448a7d73e426cbbc87c9eb56ec0a36df6d71a95516b8a6880c9a722ed440407108a41d0dd34893d2a6f243a28d8ca9920ed831315fa207f059c0841e6d2d7f9c5311ac5bfd74a36e81c9da718a87d208c2eb4f1c83676216178022a27a04ef6343e958f206d22a27f565907cf39d521f5d0b4f7025f37c228ec396139233c4f56abc399818001ea2c10a15b4b46bb348df15c2da0ff6ff9851336ac936804a27455449d21822090e6a8962420e742a7ba41f058aab77556bc2be4a59fd6588246b539b003f90efac50784e13814336c4b06838dbba07f6eb287b850b05c9e4f7542ba1412c9e7ef5af7f8cc8f7d3699f9b32db4623357a24e3557bb63612a2705aae3132be9c6a1c143fb52d0d87530654f1c890d40a645df8538a707b35d173259dbbbca97c4f5ab88c047936ac72eeaf415d1e5f8d27817a45a137d66e6c25b0e6b2791f65063166042b4e750d6c445a4b5830c9c2c3ee8a879f1685f8aa7deeb693df158a6f2998560502b3882839c1508cb1611af1966f62bfe50b1554e4f0d70cca0eec02c0d295cba03eeea812a031757af2a147925daceb64f7c0a4bdf728a6536012c2e80b486a3ea82c7ebd7b97005aca5bb3e890a9515d5942de00ea502ef13d620b832c7a57fba93ec30b259512c666e3d325922394c1b4fdfdb1cb24fa6fffe747dff802d277370a97f4d0b7fd78a176a6758bdbb6cc88f1ee95639bcd9dd69f56b45e1c8faf26e205563481860e5c3e999354f38c4a34b56f8ae19848e53e1d319b3dcee667a5495a47b9fb79aa137787d2e1d51784ce0b90e8d6040d8da5b9ff736b22c1eaf1da117b258b5151239543330e33e6a61e821abc31352b41032fd51690bcc65b95280ac5cf1bb146d2cf364e1c83e654407bbd3391d68cc494c93da50e360176c3caee6e96e334a868d6ca8a0873c7a4e300dee289496c71f6d2c81ebe9895afabb3a274f8067035ee602152ecad5fa1597a3fb5e356233c63fc9e339a17204ca879e084bbcc4eb9079d7e41154cbd974231cc5a74f1711109dd06a1611f593e0ed4be5e5f2ad8619e16e424e249e3f3d7af016785582db7d228f7139649d2de795b264a65554f55d4621517262595f5170cfc96176e397e84e247cabe61bf60564a3ddd3c782bb428de86962f1b7510d136013a7dcd72a464180f59e23772843a012d03ab5d38dbf96d424fa371c28e7db3cc123304dc65026fef804d6a24c55ba5ad15b3bda23ee7e61fc2555969d87131a15f29ed7a5abc5e715126a6590e9c1960e8bcf9ab46988e0f3f2d58d5a6dec84aba81731e02d7a862350f8c54d48a5477474a1fd7d58dffeb3c2485ccf956c20dc9e0547454c973d6ed72bae9afe2ad4e8775e5a57f6663fb464077cb812268571672ca5d1a3b49fbf56db19cf7289820538a4c426f1601abcec6db5893a394b8b2f99382948738656dbff1a5c8fde40e29ef40a84a6dbcc4f184842fff1bac63275a3127435e0eb400e204e9fb45c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ed55584416844e1cb3c75acfb387e014deaaf1fb3ca8a5b718a8ce03ae5ae26bacc7534f8b084a666bd60888de533ae61686b07faa83884c6a0efb490a8a3fcabb50aeefef58ac43ef4355247bea661c593766ffa6067e7aa66978e4b36fae431ee4ee4f4f82d50d3d5bccd6cdf7af225b6560c44f44af78677abba8c6b7984eb3ce8cdd0769ab407c9b3acd32f0f4fd1866ade03ee5e2f3336384c61ce9319cd9fac145db264cbc4059b9447f631d8f41ca376aa6f76111537019dded1356d19e6f8f200dcdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc95771637356da7aa4e51cc548f0c78aa5b3f3582ce92d00b4d972e9807ad4b1a0ac82a1dfb7fcbc8cbf8a8e3abafd3ecf165dd3a25ce9d50133e967c7668aa8b81977b410d67fbdfca802a76716b95e4df8be66d3e4977c33d3ba5df2446f62658274646422d4eda8ff86b58567cbef9bfcdcd6f1644c413fede6f39309aaa259a3d998beecc535f17d773ab1c5350e3c82d7dd175269700a56b0e5fe1de0fc13d4bc7c64f38f50e634427d2614aede34ba9b0c4fef1af9300098667f8d03588577e64b031139dd228ddb113623fc4b74e946eef86a1a6bb52764c6c13aee765e37a6864d0888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2f8e8ae3b748005d1fb6bb03be5d019c33bd38bd60ccfc45e9af268de8928cdaf66076619889ff7be769fe59e5f23ef5ff4ddb38e5bb6886b7bca9da659935db493ded9a808157e425eb04c153e673333424b7aa939559e4ca973f7644b8e3b8dacedb8c87cac6365c1fdd8e329403c69490976cd400d6f3148e14a6b3e6b3c4f054451e5bbcb7d33ff286afef63dfb8184d0546eff8e4b33fda87ea71d42d1f9736ed58e9047c8744735a728b636dba7abc33b2eedb1573af8b24cf5a8668cf09f91990a499bc8935f955e1dfd301a65be870b7f02fd609929f431f3436aa5aa6564c468aced2f1e540365e38d9eba6f0e82b6daba0e8ae77f03f1c7bd4977d47da0e5e672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca6118a3d4456d495d8a46b35ff01886cb52e38d92df5d7fb8f6239d628e9e323edfa51f8c7a33487232f4934143e176a9d2848e751d8594fd94910ef4e15389c5736fba58aff0567a7b5c4f441a74efd673dd7ccd6802878c76bb9ea576965ee45acc9dba54aad1b6e873a1d8c74176f068bee6e64c8897e8320427dc9cff676e06dd20f3450804c7a1c8d725eae7f9ebe8f715b7894ccbb543f1d00e755d168d19a96356fcd7efd6fd9a8c3a8f0be6500433f925e37ad4fa474b8e44ff83bebfb46ce6fd509a5aee8cbe23b74cd58d79d92f93bfc9cd941f89a0baf7d8a930bfcfd00adcf019e3cce107a18e9c4408d5e6fcee9e45459ed87f31851b88b6b73156ec820a5cd9717fc2fe6ec83d23413ae5e0662894dafbf38aafe38fa8e8514fb53a637aefa83379cdf6fa7bc3155e6b25d343f1edaa787fcd2eaf7f8b39a8becb44923792a7d586632bfab963ae537768e45961f5f96cb433f0e75738a974e68ba4d3d5b3591ac5679b6e857d8e8b2a486bb2a9d19c8bd3bec5dd2e4da17e84712abcd1f1390e49f3b488ac39d0e43292b70042c52355eb48b841887ea256055a688fcac5a71c896414ce75f57bba12967215c50d4b5be692b6dcd1ad2190a3d785c19e283f87f784a03c8f52a23e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d062ee1ab3922a2c9b5b02d14557164149c62e8029b139e6950b3f8acc9e8c30274b69926c1658f7836f479c8cc70138b829848c7698b179643b7550e9193d6fa87350503c2b69136b08cc298b5c335b1ab95054d13c9260625e34c6c2fb8186e1916c137ad9907c8b2ac9d88faaaa0375236751a47918f96477b7ec01819f8ae1d72951e21608c87532a9428bdf4cb5658440cb025ce3b271652961bd935624b9eb70047e63184b9503adcd057b6744fe42908cfa325e401b9d0db5ada201f5d64350d392c4fb842823895e15720dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa3917130308f2a2aca964790baf960aa12de3334d146e64db81ef09563c9667381424c809441ee989eec93597e7c5b558a89dfaa976f6934cd18b8eacb6f2f54e8f748e4bdb69b0764fd59352575066dc242dc0f1356fab4467c8064fd23f8823148b77a4acc642eb2c181fd5ca251b323561191cb15f2ff0784900a15f67014b518453c4c3663528ffb53271e195c27533fec8c3b159ac1bf39c6fdc69dd5a5fe5872ffb6b2271a09966a5c738c48e63e141d65315051610f0f5588ac97f14100027b144aa23774f199d0d9a122953aca8782a4136820ffbcc1f2692bb919b674aa1f4d679e8418e8597c74d60c5c287cde6d44492411222636b03cb661ad66fb442193690a5f1d6b80a947442a46bdd239fe3989e6da86949474e395056a5e6cb42b25343a7c73b650d843527444243852518a9034b9efa7a6bb8505bf605ec238ffbc08cbee35a94845d7319144b381819d0928c27023b727656ea843140649c03098fe74c717aabe91948ea7698db0a86d34296b5e50dc0a9949c8ba07f64ce60da2b6e62458da229d52c08b9b696a124a8cbb791c0d255d3e4a69ed2c242000dc6476b4555552deab63ec19fe8783151daaf78e561e1844886d4418e7510bd025299b1c83c7ba22f63335b9823043336da897a44fc6a28b44c68a49b436b0dfa406be642a5bd303bb0d633685364d80440cd7189b6b34f6535101979ba9d251474fc91bf2497670bad0da78ab3c13eeaac864572a2f919546a57c719bcabc9dc8215b492d53118c2d379e879234a700638370a530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d8891b4904b8f5db93d0531caff25be53e28c45c94758e309b83abc2ba66d98d3bdbc53b7d06592f2712663c777db60aff496a217e82d8272c3a218ad8c8b04ae7c66be35c08e3a955fbc18edd07e8e68a806fc3fe218b87f87bc332b86c2625d8ff01c9ff6214b75a20cc465f847511030b47ea664a75b3d4ed9038a9c747c6872de0a57f3b76c60585ade64570a21cf8548a5be4996bc22b3d16a7bbbd20149034764b820892b9394581697e39f9b35077eaaadb06702968a5e5418983110a97d4749d3160ddb2b9c587767fb56b9ed9bb3d91cbeae141769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +ciphertext = 011f7beb6c4be8f266d9d6baeb2d0ad7c3f7a4257b770a8cfe675d00d80fe92975ede583a59727628ca1064987718fdcf8f8269a371accd47560caa9daa1cd606b258b1532eb341b47963281d843462e822406a41681bbdd81247255b4ce037514695a4a596ad23b493cd368897e94c654a69b102e4aed52efe1ca2407222ea5874a4366f3fb804b9d482ebe6ba777b9d79701dd04becdd10acd05b0b4281e6db009188cc9a0e263232f233091af61005f8258f05e638f7d779346f59555827b92b190829003f42156dd0da2f43a3ab17731f2e15f7207b11f4ec0dd6ad56cdd5b5a2066d1788cfb060317cf36b90ccbcf0014efffdf291606b615488a762240733fb52e0fae719f434414e245eb8e7ce84ee0a35ed39925b233a219d60458c4434243e6575b2a654c4c6dd8bee20302b442201d846261f1476098459d9c2f548a097dc4043e8403ec21f6df98a2f1020a09e7609dba49a5df6e91fbc705a09d39558d7b12ac4092c96de40c18cf4e0d2e0aa575716ef57165d38f8fab47e40b914d75e5f4dd65fd99eaf77296fc742ce9e52728297729f9ccaf0e58f15726b6b664b3998f3eae5db3803da3a98c11149ca1c7c1dcec42f6b2be604134b381e4ecb044be5b1aa0a912e71f59d56f3d011ab99d3defdc09c345591c79295a528341ca533af543a5777a5a5df06527cb961a28075491da67334ca67f7ac1f8b26855ad3b8e05291fe9d401a6d6ef19d3e915235aa3de6556b7fee9c7faae019bcd21f54a137ba08d305ded214c208f197ab65123f58068d9b770f79ee0f022c85a5e18c0f99d96ea57e3df44475746c3bf59ccc5040b88da34c1ab7e477cefb479377844988d1737e56b52e95b02ada15df5125b6a380cdda6331ac4afb8285638465b6231169523096b49b0d13bbfeb905483893f5aec46d003fcb37165dba2dc96cbe7c269eebebf8f437992dbf4dffc7b69f202580b84184ece0ee39b6e6b782e33e40add26469687b05b06a02633316b8b1bc251aad358327f998dce5a95e7bdc5c4ed526854d5f44b2e1c6403fdfe2091f9e31cf706c18cd02d1a019cfd88d7a9429d81405c1be11d57582ea371b80dc19e89a030982177e3781ce086ea0d633f09e11ee5708d90e37e8c68eaa4a419e2fa01b07ba6c2bedcf57b03e740da6df1479e3dce41a7a1b587b918851b98efc67218c19d2cb71a04961ebd147d247d9834cd8c976d42b7658ebe82194d823865cc5cf1125b0768de6f33c8aaacf45ab11379ff8d920e1f1addf6e570c3a550f8ffeadcdc0d9c8174f2cf3c3fe70f17808f25c49eea9ae043208bdf9d5bb61dffc86adf687fb60bf3f8eb289e22125ab0027383fa2fb04495a9f70c66fe5fdcf1bedf9f9b7b52d6b3f9f39db14572e707a15793d06fbaad499ea36505777455420acc090d2fbd3bea249c225403a6e9c80b1cb49d91926a9acd9c66388386ab198421f2b51a04d914738026e009b022f1d4d513d44116bb293e317e22afe91381d64629145a2aca70d4b507c8fd1a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ffd8874d8b37c946409d69cb045f9b7d1a43debf4792d4773cd7f3643567671b8e10cfb903e3d2679a530118ac454bd542af389c46b3903e7b4323d97237ed8146a66593b8fe659db67dc942feabb5ff954a3d85a95f77062c3d4ebe68e476d15eb5d6b5b8a805a435ef78e2a6b68afa93727777e7c114fe24e7a10a94f182e7c40c4cc547b98fe007a1d998d4ac5bc3c31b65124f5a558c73e6be935c7a664ffff4955b6d67ca54d48bd4e27ff717af7b220efb2fbf7c17df6a541cb0c1ba5a1a96f9b80ff32b84cdfed9cb6f666b41d9ffd1bd74f42b5d2ef7fe8c5443f34c5dc3afdda165558bfd74e3ccae85cecbf107d725eea3a30a7db045a2c4a79bb1a4b0f11e87bbd8b29a8c60b17d68a82f64d9c3d5b5e391521bb945d53ce1d6543654e932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542ce6f6637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356147cd4bb849e197d54d105fd2f26d824eaddb27b36bf8abc7876ca332cfc3a9ae61d995f3ad0ceff9d538ca2d3a6729cfd06d89f7e7ff57093ea3a34113749f23fcf1c15eab2c83667acdf10a549f2678c7187691de949995af5769d4647fd992bf5eee24f3d2c07569cf26c11f3942cb5d5391a794d42c77da0a324b05908aeb9c70b88b38a95f372be903ed6d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab96787d466ad56de9c442076fc046aa8cb4fd93bef3abe8d406ff6dbddde725daab0e50931c575a0c9137fa61442b22deb05686d398a6fdc0bbbbb25a073e99c380fb9268ca9152da1198b5c556dea03c878b78f7e6d586ab43cffa57f58d1255711654968fc80e1364887fe8e980ce1eb85645b399788ecf25b2af33fe564604a86397a4484ded2213e88df667961bac9ef19b9953f475c1afc9978c81cf5314a3bfab3747954abe4c8e7ded9fdc6625938ca4a92bee5a7aaebf86f5d7ee899d772c3353e35c2de8696041bcc8c8e997f8c78014e7c91d3fe9b8b34b63af5e6cfaf2854cf912f69c3c5b50b6fd9dc1c63f8835b3a83e37d855c69f9335fc66efb985933f4a66b084aa599d9e658998a15ae8b087120f59a014f6cf9b3f7dd48467f9ce2cfbaacea7bca7417d60d4f950cf9543cbceedfacf96d978a2c36aad92b665d6c9513b59278bcecc89ef04e555e2708ef976a74d3055a4803520357f960e596c7c4c2d0158a006d88504d681c76e0f21f4574eb9ff63f3e1058dd0f3d6f1e398ad1e6cf8067d24d17fdef57e9e3a6be9aeaa07b66d77be495a635c67066a2945376c9836ebf4c413a05a9b1348c323f9884bc7d820a6bad7a63be6f518878a97fc5f5332433573973df74a00fddfd50198a2b23d6005335e6b5e1925d5fb244999cc333bcfa4e7845b767bd50cf66607a9fd14d28548a4454f87ad6ea4fec8288e478cb938d7d9ec5cc81ea1a9269543dc8ebc6d253be1698990d8ec587e7f63e7445baf53317cf3eb8863d151a4e5659928ae7d4c1c7b2bd3ae9889d7a05ccbd2f0c78233ae0653452e3dabb7598ca83d3716689eef12af524f371180984c07fa6e239e3026d6b745ea285aea62d7b0180596be297a4631abe0d48a046dcc99c8912b8255fc45592a2a61230652bc7c450a674ccc3abb27395738d177e7579afdcc30e74e7c7b5ac5dc235176343cfc4920ed8d9472e13c9b36a6d38bb44756bc31fbab62893656da065901303700a14b2f785d98896ae97953ba358fd53091012b97498cd7516b0e1898e2f6803c5a13d70f5bec346917249940ba35e3ea954f6ca13c343a09cfc02d8e66852c1ae0ff8b22e7424f53b1897ea11268a6b866c09efe8694031754ed1a2a147c0086283284133aa6c324e0b0570469f09e0901f25213ff9b113147990b54cb241268e0b6c7a3a90c638b7c483c71ac1344bd65c988736c4756e0b71111bf5b810fb3cc4187363a94efa020de1c3cb9a005cf472bec5685322faad5bd1cb0f240458b56fcc5a6167f22577565dac1ba9b984c33c348babb70506b87926540547389b805ba01e4443b5d60b9a407f8b060fcd96c4b717baaeb72400eaaa9853b962e8a0c8d966458cc4cff31e960c447c6b205629419478360cdc945d6b9a55504d853c1e51364e7a9aad82b64fc37a02e4139b9e6c392dc83c04005f6d1299d990a89ed68acc31b5d1d224f2c8b3cd5280a12c6e088cc2f9d3c59afcb9fee458af5135c9b4b477d878f34723e3912189d2764f9366ab8752c9248a5684296ed46f404a1739ba72d5d652c614860d41898e45b72bf66d587089fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed880048885355f193ddb1690b9092aa2a86af03a41797120be84334ef25c2e70bfe8e0a658f03435b65787f38bc9452ddc584162955f8b8560991c407fa0c12d770e80fa4a2cf7b853708bef2a44f959b9d05b6faef83f6f41a2454257b0157c55047ae7d0cc17079e118c8a4ee3358d877251970eaf86684ec70858a94bbaa4bd2fd1895c2223320ccadce636c2156471b76c48d53e6a6c12a1317c39c48bf3a0aa0dbc8afc034b43398b9f1c56d407a4b7c2bac134024df6ae9800b230e2592f529f79f0ab048867a349684b242bc4d2284a6106dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b22027d6657f12379abbd248c6967834239e2d3a0211b73a77d681b61892877b7e102a53cb4602e3dc1704ec92a9e260d9817c6393062bf520f7a845fff19123a1662fd241090ac81ee1748eea878d53969fea20fb95688fcb3d235910f154bd09a75556d890409cce0a20c6cd2a59664bc4ecca3d4725910d210db0c848ce7242cca945f1568561bb90d9a4c3dfba83074a16fb3ac934c865dcebaf6fd90d5b458c22542ded5111e77c12d8656908557649e9155a8472d5213b46f739f095b5fd4a2418074ef7db9385f19d6630aa29b28881aa3474b7ac352c5dfbfb20fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b9190064f3a862d10cb5707215f456caa10a2c240619925a140b6cba878a0d40283efb9e1562c227d716d2935e8d96649c06ae9465aebf552d68da1e7991bf987a4dff4371049a0dc9e56f110779d562959f278b069b3c7712af29027aad6109bb0c3201565c0b0892a62aa74ca7bd6b48039066a95dbca4e76a3a323612269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f6196590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +ciphertext = 800e73bbc8dc491180b29772408aa58d07cc850910a70660127c54207460eabfaef758520f288cfb6b7f1403986abf40fad912f2ad1d40acf9ce8d2126dd59c4148e5483542045aaeebb0fc8a5d86172ff25f8b65db0b1c2ff9b2f7b10f82662ad06e40370465f74c8ab12396c4b7c877ca8c231ee5a88358be2e6efde24d17cae8d8e9185255e173f465a9df4131cdce630cab9dcfc6a84a0ae35256358e643b068c521bb3a3f1a63f751a0ac8a2ca2771a30fd8f11b6c9dff802ed6f1dab41499ed0290beed78292b1ce7807ec6cd25d934efe72177a91c4e3727956143bc3427eef3cd9daebd5d9f84ee6e335b77e2f0aad546b938a6e92504d3724a0de4e8f0d1b4ca83b119d92fda08793635b25a4547d910f2c90c143f891eeb14e52b5874905996cb88536643a64c931ddf8048430a63e1ff5be1904da5b136ee0f433217d1ae3b2040327f51323fa93a20610f273ad3af90d2c649698d524c407e04b8aa25ab6e5580be5025f34709314f80f06caa9b2e342c404679d8a08453ee3fa0b59c0b04bf14998bee7be578871deda59931c4e665a1f624cb181e22194bf5b0611cf6a41f7c3cedb2d52dd30a434a504e60ab7fe4d5238394d5b340d38bbde7260f3743f31b3637cfc6f3c6777d9f6f4dc3977d962a558bc533725f315ac425f3e2104e754d361dd24564aec0bbf5cd3253909e091941e8b7e828ca70e730abebbcfb3dbca1dbbad3e16f0d68ebfbb2b208a177ca988c8f69874650594e912fffbfc02d274e094c5ace6e480a3e51872488955176664dbc42501d9b0b4671e0fcd8e096539908d0147fc6011cef14dabfeaa9a1ca31f3010f17b1960e8233d8e2425e96c37f229e53390d800a6c059c3f6aa2b74ebb5ed654001cb760531792d796711c4eed4584279fc520a8e78995329d2ae238b1745f7410dd9cf0265caef5411606475735a6c298941cfb7ae810524c870d355211972e1856d471a7f928e4bf400bda5ed9707ec838b43a4dc080f2a96600db1a5759b246f7f870add6ea8f91608375976d085a5507c9a03ee3da29d77f4a2b32e51a90374ddd79e331a99ffd0d8458bfb5a65fedfa7196d36dba0f2fc8e04ea9fe8cee7aed584eeda24437bedf1812d30fb096bd5e3d7613d620f93dfcf1cb0cd5968530e6fe291ada0411daac93a6269d66db7e3908e91f4511551de33da82e74ca2a6fea7006705408260d7aa57387b8bb4cdd4809b2b140e264c25daaf9f50a8fc28274c17fe1dacff35b4006e311bf0bbe7ee895d707cbe2f1c46824a8813882d46d2d6de5eb8a4ac2afaf4939f36459f64a7dbadca53e098f44d8a0f75042ebe6ab566c8191679f6224bc6676f3d68bcbf422a8cae661c231c841df80d9e40566176a58d610e006811b8d0863d73aa66bd59d659135fc05d0568f438f82a2d4f9938d57811c4f1654dd127ee06fe2d99e76a5e716674d389c91ac198ee0fc0afbe93ade71540f2ea0cb2d63c5c45aef6d0cef2d624fdc309c7d312a39be86bfbcbea53fa206442 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d32cbc1116ac892e9f9bffc33beb59bb94b372f97815278f0fbbfc690c94b90fdadd1575bd8cdbc7f48aa133bfa068cf1bfe612c43f5b9dd8963bbc66d938f46843fef4f4357e535c2259ed958a75cb6f03296e90be53a9b46373f8b41cb38c1cbefbcb91898669a872f1a8d9defe227f4fed65556930fcc6b494cc6a6bdb08731cdf4e7f48b86554ccaf953b8fc7daec737d8561dcdbaa7cd2a0ba8549f888643ffb1e3a419c49b34ec90fe3eb71635facce7a79d05cc04074d69ab3cca8d910236ea229ea08633edc70aa583e86912e5beb3cea22e94ef39db531d6cf6cc333835bfd480d6b1cdfe9a664e49045791d33b414696375dc3c7b0644626e8822c63f5d52ba765ff361d853d2454e6cb9a5bc064de1238ccb53438c91ae96a45571f743895fd60f613efd623abebb4afea15e90dd9452ca8e352a78e09579f06ef4db2033aac0be1d9335986e8542d9480bf66d3faa3fd2d0878c3753e6524a80a3f4ad7fe69d7fb6d9d0f64423a632996abf297707d94e2a6b86160b69981ee8add1c372faa406f64dc00fdda75c354491e759c3b5026e6c1920fb7160883ee1dfde68d7b59339350bde559c4a79033dee94cf15bd75a001f7d0f27db4feb7aef6bd07aca616e6881610cd1cb037c833fcf2dca56a00ea2e1ecfaf7ecb6121e81f2ebcb1eff7c6ea84251d8a2b6b6582e09e6e2b8c7f8fb6be8844478fc570c8d54a067b3422db47fc6ac691f5cca95e4db4540b7796ca0dd5523f7d14db34b8ec94d5eb66c9f5cae2f838192eff34f43c7236fa18deba17ab495b8fd529d89b8e1f4d7bd6ae85ebaf445efdc6c9566526b8708be3bb0cc8d9589773dc9d952a5cd78e43bdc68cfa55ded7a1f618f456eb4f97ac1b49ab948592986f33fa6fb19165320de672bb69be42da2985b38b90f79572488c5f86bf3d55fb9fb90449b66fc874b9439f000466786fb7e393765c7057051999712df34b5df7741a3f0e0046ec19f5b41d6b89d7fe33cdf734e296dcff9dbf6344219a6a22d2cb50c75bc03bd7fd0eae1fe1ada0b9aad771ded5d7c8feeed65dde87d5d47821e756a926638395883879a91b94c6164b4d89547626a9e7cafcef944dc956174b6cd5e54944571a6f655406d4d331f7290bd8af6e8c0eb1df65bcdc5464595b31a913197ed79298867aab427edd9481cdbf0cd8ace149913a9d79cc6fde9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e64ce62edaee101c5a49b35475ae68634a7b0cefccfbef6d8cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687d9fcda9ac9c03a9333a866a9639803c76b5b199f94a269f389abb511d789e5edb892e5c565dd8cc2df74f88eed7bdbe3903576dde6934c4b6b75f96c477aa184d43f06792f3944efe1fd6e44d42d827caffd2989b936b91694825c4bd8c1dc0778be1971cc1efb93ec1b3674afb4fd07568ffe89c707b5786ce40d51b433b7942d88a6ef9bc9d091472844dd4005aa804ad50ce03b2bb65ef620bf0ac6649d4ee4f024eb2eaca73b80d489b73a8d94d834a88d2a96864611be0f3576ff861541032094855b18cf574d868b0eb783ce9011f28fc14c486b122cc80093897bfc8ac1082421f99767bc42b0ff41b22dc7b50d5556041338e6c4368ab190e92608f6cc69d8b33f1ab04de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f150658715403d1e1c957e5a914b9a3bc4c45489053306329c7984e76f169c8639de4080db1671ed01a24724a101df89e45b5b385ca2ef663586ae58d9b33ade9738f84482e6e28909e7641aa673ad772b125161a316166e1717fdbdc8d02b2b2b6dc21805619d4facc40e9a21bcca9d4da71220a4631e95b25e960192a22a39b904bbb02f1184b79a97b3cc16b5e4b5eaf278913b7a195f3107342a77a68cac90c1b5a3ca9b354a6095c29c09c5ac2b44c6cb28a250834d5f2a307ea3434977d0087017ca2692b79008640b770b41ee2c2c77bcc2605f1857368c8e12983afa8633c870115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68c2198b2fb558f463a7477b9fa7680f1e65706a888b8740a87cc7e7949156f896c182b53e464721e46a258820201887ce9b83d43250b63e2ab29900a115084a6e66584f767853b2e684c547d97266b36b6838aaba73298dab79c58c88f1b51113ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd78106ec0c5e9967a6d81139cd516027c25afbb6c47e3802d56079e6265c4f21f1315a96ab994597214b814cc53e8566330cd51fb4045f605df1c7c9c255166651de6041b7fd85c7e376e28076ad352051c65494a1054c30930621c53ee8947dce3c55bd686f186cd5aa21afc17664d36a2d7f5008ae83950b93ae510847552a5c2f761207b0f478c73c4d6313c8acc25b13ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940b70b68f40bf570c461f11795952e69f21ec4562dec99448263188ef44e71a1681d626cac69c6b56ab51ae656be1ca028672d97d044e43577f26329d50851b0f8a4a1b6c2b673ac6418ccd58005ad400c27d274dd4732e56b5d7c0b6ee731a99e15229f7295c153aa3a873c20c23a35b6137c824f6fb021a0e28f98bb3be8dc07a5b038dc89944952913af7a39a9b00f1a038a628686a735dbd4c45e0b8bcdc1c1a902cc4d0571cbd589f507a0c0dcb81bd39811e723358d6320a3049bcc90d776562eb34877978c9929548286a85efb85f7c6c76ff255f13a0cf5e70304f1cc838fa398fb34e26ca662759c8f3657125dc2aacdc4615653ef074a784500ec60980be4aac94b0c7a9012dbe73cdbf1687a684ac63526778926654a4ae4cc779a600a836e3273acb95a802051f18af32683f52363572583fdfe30287b2632874cb04832f55e0944712c86d37420137c56f6251a1352ae37a0c3fdb885cb561e63a493a15beb5e3b123aca6b6b7294d8002e7ec758ad2c22d336aae3c067703821842cba2dc0b1b7a45cc0a48202a002f927122c040f84a884c1334c1e17347108b91c055d331c0b170c6f06048b40ca0bed838ad963fb8747ca714cf1d3267b701132046699798421acc06a3bc1ade172fc62123235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffbd3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +ciphertext = 9aeab84b3e0a280ae182a9ee4f3e5075883a9e22f0aa84470b1d481a7a1c45acd500e666cccfc98f1d01c1f1dd3fabf4d2a60e8a4bcbc237acd856622431f667719e83b8ba4d14da5131d9b377998414f3ae58a98295396e41cbe34a8a3b65ee20db915136097e6676a96c093da827c206f9619d09d218468ef0a2af7e3c06a647a148c26b706507b792c0eb9ba46f0d7e3cbe4e71488f83cec8af88fb29e3c61d43221d21329271c77001acaa2d47f2e3842d221834d20e232a5ba3a49f33f7a82fe0cacd6aaa96e24d2d75f12a71eb10e5e554c98adfa732e9d5cd6cdafd6a3fbe97d7b464b15909499f6dd739de3ba963406ce45cad0e8e25122d469857b823b821f59ffe138a29d19c4bdea4e839e5191e7187ebd96eb1249b50a0f4a8d7e3f4930162d922d296301bd4955c44775b42b8e06d25f731bb18e8cd13c1e928ce58b101ec64d88a643deff0dda247300dc7de01e1b8d1643c471369528d94534fe54ecd90203c7fc680582140ae1abc4963c0158d26be214eba6a262ee6f35c73209f9ef2611de8c37152c9e0f5d5195492dc8d91825593e2af1f348e4bd228ce205b50f24fe769a5cfb7462378e3c6f87e680501991e8ef4babafad6ac15f1bce68d0333aaefa0b8f169a2431890ea62d99cfbfba14ba9d0a203c967ba3ab036f485f96cf2c5f033919a1795f60c5772f0f6677aba09c56bdcb33d44470b02e7e1af31cf9b449056ac3b2eabd13c7ced8472744e4d0b8fb396b0791a956e97312b376eb045d7cadfe03c7153a4efd25dd393fd7a8a47bcdda4d4279183bf2dcfa553340ea026a034aa7e8c755175330fbce7c176b4f4eb45485519a72bb4d29af2e439460ffc08610c3aedd144749bdad2dfa5d674e0f6ec6e3fbba1e96ff5b3cbdf68b187c98ba31d25836e25a82e8434c0b79c4c5121dbe00d6a45947c2f4b7a6d2b04b5f6f1aea722caea639bac03b282db978e98235ab21c6714e7684ac2aebeab9b4418a77277cd3da7abb0a44c4c3d2fa28be6fd30a295d85c753dface9090ae37e56fda6c1cbdc9d4d5eff7388c3b96a909da4432877263f67492c35a48ab28ab686e1803d18009c62599762611df174ca87a4c5381b062731b3bbbcf07b846040bee6cacea3e7a1b3781a5568e7c3a9213320ef4877317cde72200ec9bd731d30d0a061cda0055761f0221a1f804a4bbc23754c829d94df4952f36664e3f677bc04b6f9a16412cbbb78b2e5a340837f587388eb17e9ec07c29745b22387da055e1e0c8cf8c01eed2140f21a28d38441d1ce9b263aed39dd1b20856b69082ccb797848177535b31f8065cd86c73cabdc68000575afa2fe8e5c539fba6ea5af3c017b6e3d0e40bd1e68278a339e49a4541d691b178758d90e3b8d016d89deab0820e4c0cf14a53b281e608c74586be07f1e0a5492e79a09f2c5464374c2f287c97d0a0b7bce04e55ebd3371c5951f46714bf52721706a1c086a1168081fc1d1a26e7c472fc1c13daf9f98a85568e993fbc14b4a635d9fcacbd698600 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 818b55fa5ac30b8e891f3a36449f4b2b046feb6765a61cc81d9d59d1f82f6b0d67a20f825c88a531de5f0dd95f0b4742d29abe7044c62d45a05bdac4623d305e3c3417d67f60c9fedeb6b2a3a8e19bde60ee3cb0fc6fe44435a5bb64e2c16efdc72febf6f7fd0f87a3834ab5348e96fdc950a3dbeb7354c4e50369bd4364cef9d66b3fedfcd580f1c9e4c0c335f547748cbe9264b787a02d6a9d7ed573b8676cddbdfd777a2a0ca5ec99ea1317c5289784df1e4e84c53b983778bf8933815f56c9a9bd06beeaf8f5ac271ac3f1e635eb9a8263c855bb33df58ea3b7f8f87d86f58aa57646b97560e593944c4cb3567a2c48fa795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b5082fa144737ea39be4bf5ec41cc55c5344ded158ab4a1bdf0a36e2962b89cc2aa8b39e98f3ed4b0f0cb587ff71c74e4f31b7ea45eccda8c597c394e5d36f571cfda7c0ae7116edc7731c70c3edec492c85de16c5122dfc5a96973d7f4f3b58b504eb65f67ee6aa7779b77bf554736d9e6e76dfc6ba007a590b4eed4b86a7a635effff6d86ab3319db48c4dcb91fe78df45a948035ef42e4ac9861b62860837cd8e3fae0dd851d8d21f8aec4d8aee5f13bc3e8462f47fcd74a8e97d27feff98b1f8bbc37974b025295a80e3525d38ffba8467f8079d78fa6069ef3bdbb3349b3e506e474ea228c3927a554d7747bd46f1a0343cb155bc796d75c40e5c379fc0fc65b195bef153ae4154ad3d5147b0cdc4f3a3c5ded656e813f9ae1fd63ab7a53031dac2d0f87caddecb8156ec8c08bf367c4ccae7626343469e4e7acd7d554629349803519534d3870bf02e8cd05efdd0e63db9e21cc7dbe463e8df4adebce1280f6843b87cf60cecb9467439abd6375d6b1acab7306f3adef866f883762b5b4509cbb2be24fc5c65d047fedd29fa431f9b7d987f53928a8d2d4c33add899ad736b40cb4fc656be02e9dbf8d393d73fa1ac5d9c4335e1f1dae6b11e39cb16f7f75d3bba75440414af98ad4bc5239568cd60ef94c9bb8ff1d57efeaa74dbdbb8b72f3fa46694d1aa79421ba6811536ea8d94878d9da04695e0b247968b7463ff49a0588d44c5f9e47f0739f7ae7b198f8bdcf56967becaa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e84fcacb74e1d45704fa4cfc92ce42453ba5c08558eee321ad6a6a38d476aadbf6987da1264ba5148b40a3a9be3d5e3a48fcfa4cf44caae38ea9cb8da86f7b45dcff87ab065ad79876893d8a3f50ef59f369c41f9ea40daa5a5985ce9ce06cf9bfcf947a3f133b4e57bb8cc3d7fa1fd25715a6fa9c99df6c018b7202885235de9466540c9eb5482a87e675e57be87f2bc74e33d8f7c20b97d9e79f343ff3fdb1b75ab2ccb6fa597392db92ffebb46cfb5ed1330c24e7ccfb39fc74deb8a749d3613b3803a6abcbfd99025e305cb32ba6a5b568f65c3ef7d8d49aef3f9e81aafddb203603569e9d5f641932f33a2cf4c0055e72dcedf9564a02afd7578a48a4e2e5248f3ac7baefef8e56e367bd3c567ab978c750d85454c68a5806ac38b7b3396fe9fe79ad01c5867d3f9de9b54bd63954761ab7f4a57b1fb3fb65f285743def07bad684c376ba98c3a0415a3bfb0ab42d0a3d68cb171109c5f83147c33adda2cb07c62a9025b44523b0ae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da2a02d35610787f22966298ffbb45fd78a8d36eab454675d6951a70472caf06640bc1b97d6760e74b41c577855bc0756abe528eb4894e8776f1e739da45a9f84c9bf3c72b43262525b547f75176ab2e12d8ea808d3b0355766bd69d964eb3b450a96c835d7b238220febd62443b03985731333c54382d20200e30e4cbb2b607ac998f20def865bdf47ce78ac3dbc1abe33245d6fa7583b31b6fe7b6ede7a8ec776b20f7bbe7e376578f0933b761bb0952161123d61282cd6c80cdc8a85f9632aba1a8ef5925e410bb80beabc67735d07e4abdd587827745a3220a24a7b3902416befab3073c2cb1fa76ff04315b653b3e7c18343391f92015939829dabd0289b5aabc4cb5335d963ab842865bb7c38106eb1274eccd0140b415901279e8719c0415517b5101394f78a48f565317909371a3154d291698b0bede17052f30786dc2d46e71edc438c288cbd44445f993926bff0a8ca1a033b656c2362a659eabbcf37b2cb5916940aa9b3e850e51039c08c8588347e1099a0d8380ccc4b8cd0c87218bc24f09126a82a3d530a75500254510ac765cc1de612a4ceb14db78a7141109f947b4329158f87e4c8b41a92afccc9eb749d66a71159db90e7a36642636af22cc0d541ce52db7ab44baf30560691a637c93193a11a00efec075289953fdc9df3ec3390342aee44c08d661632fb0303681e1f89ce1300b0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66205c28766ba5eef7062363c19091c61c543d5c1b8a547372515722ee515e8ef52bf8e089d93377e2c8458e626d3391953d658cdb05c7a40077f4e19dc0b132be719014c12b0cc242466112e94809630b63fad12c99d271dbd38e5afa54c894542b940415354203a0c8a785ab94200ee0cb976991c642257d9af6998b61ba27b236fdfab86f834fb2d47cc0904b9d6acd2f8311f0d4b8ad81a24f712d92272587220e8023a8bc13bd17572d38851778f319607752466cb0de7c5c12103fae4c57d953b96be93262ba9cb05405a5d2a9e012b21a22a2ef33a385c898c80aa9663565b63241a1b206f3379abe8262cfa49ba05c3b43e9485e60cd38d66eaed114ef81afd66b2594baa361d3c3b02069b1a164bc387632e24c82a91be2ca390eb585e900173699a8b26b8916e52bd643645d3225df38ba50a50ea013b4b2a86ee1f76278e27f5a4142f034004b567f309c52acca3c7530162ed744a67481ca338861ccc3e8331e1c67886023743719493cc3caea51438e28ac4ea06b906789a65220e3c7407c874c6322be1f9b627386081753ad618a8dcc013395f20f5017ae2b57ba908617490460d5a67fae2660a56c4c4d97babda0bae0f494260877f7077af2536b2ca46e297c61dd8422bbe515519210dabc02e7047b13f16607ac15e4950574c43bf8c39a2528addfa2782506635e5626967a1f30c02fa3442fa93250571a8173999a88dc27b43c476468a6a4739972dc1b68493413a2743b9b563283cc886916eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +ciphertext = 0ed9d867a5a681c5294598bf4ae653943fc39d85798d3ab337f344892209275d9916e72cac7e94757cd91e9c35b23e04a29cbf32320395c0201075f704a0149acb8b3624153e2d9ebcb6c072009850f3fdaf52fb27b559dec221cd22a24080b09b1789e5c7e0e927b613291fab9118ff69ff7876eb2fdab05373240ba5b10339c168b635c811456f2fe6295f1f22f01c04c8ae0e49c9e303edd658ea87a279b48e3a63180a645c40e1d0ea1f7037f53de37eeea6b3ebc8a455d3a2356ea047e09df3ccb32cdb60d7a894c1b708b6be01ed9ab7befe611f3699bbb54c1f9fda9b3fa6ebefcd9e535ff1cd1deb3ed6645498894c8dd29c89b6b4fae20bcb4e05876aa9ffd200c2672c6b0bbf2df9143a1a1383e3ca7ff7691c5c5bb6e94f489d8d269b6f19fb411df8865f0d07168df6fb052a31579be29954d1e6a7c9204e9095824b09e9c99d1b7f7c174dc653ac55cd87b6ad0ffdc49e54afc500d7e9d3674355f199c24ed2499d7f01e789017a33aff2f739e3b60420bb9658f2317fccc39663067fc9197e3d8da3eb414339d87439144b8b6c993ac3d715ddb2603dfd2b73fb1b89d7f46dfd757c1d2b6043f83686d7a8e81b699af1d4071fd4fb30309aa7a730e134539687e9cc2ea29dfdda6ef249ce9ee85b4e1c84da1b91689ded5ca4d1c9c9d8ac446139cae39ba54207e70fb18970078cb8256a0233d8b29a0e7883bf076c45dd9219f2694f616e7f370b53a853095435b0ed5a10210a9fe9e6aaa79076aff0dbbf7f9cc4e267a1098221c9abe8e7d9e8d36401878b4fddea1049267d1928d44c3a6f99be6bc476ed91feec35d9504a085e745e39f2474e1d3d6dfd9b8994014e294093ea397845c0ccc9915bc5c800c1e799a256174ebbf65ee8701e9af4f355c657a7cfd36ead4b475c5fccec52cba88e0e5e0306218bcd333088dc31ef4ded6a2294f29793abb4e3762df8b74e19ddf32a641ad8d1fe16f315c60dc68b2d29fd83d2bdabcd92d7cfa4e02818530787d60b19618a101d71f964dc95d1a921b28eeb343ab4e6008840d226a0e9e8915c3abc535e09351c0d898557027cfc578a07376e878c6b90220fb36aa04834dda6f9b7c1d8313b9242e9df2030474afa0743c9434fd189e64e76518573ab7a054d81e1ecd1321963a078805f9a074fd3920b7d4e1a435a5ecc0a2c25466913be3b209ee3b0693ee561e3d745920029c384f53c3abdb4a49cd4281ceb70eec21a9b47a693db42ae08c88d2ff41ef3d632080d33405a21b516ba377e521e868fa3659890ec0200985469873bf42daf4fa5fb8d0292c5bb8e9435433d2a4dd176c1d27f16e146262de295e2b1046cf5ea965e33ed56fb387ebd0fb39d95893d876e33278a699791930f833f2ed6e5a7defac09e6ace406deba5b19dac8440b6bcecaf85674839f775f279a8152f6fce0674e07603a69d10950f51da09b12e084ba70a828b00067ef26c9d3329532cafa9511f78b3c84b685f9b42d96ca5a1b0b399caafc45483a805b614f629a1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 92cd87e633d25864c3c5e9d49e865c6226cdd2b39f8a1578eb69a864ccb2fa155db337d2def5b50e973495997e18c6c2175656890fa4bbb86c5028d16fdbd656bd9e6a4b39a8cafd70f3fbbb255bdd296c999af1f67e6d49968dd02a9c4f4cb9dd7fc875cf32022ff5f8e8840f7589c3df85c1f7fc8588c0a33a502a385d0537e86cc6809185408e9c7fe636f7265f8a439332f93a5ba2943e6dd7b30d79a25939a4c19dfbf57c755a6adebbdc8390f8aee407a541c46cb163dfe174f215556d20ab942ddbcd1627826648acc30ae467ebdb45075470196b46697d9ec6974f477eda553f80c7d1e853398c69a6e4a7da746534928631e6c8e1e533a4d1e89cdd6969c0edc862dfcec4ee6d0035bb50573ed61b5dbd45c8c6cff3ce04f76c5a6db01d4949eabd27d3319c0efb7aaa4e5f636733bf8e903ae098a7f977d98c01af67225b84af1c8c404a52472b8d1a793e371be7a9935ee69d331256620f4dfe390474dd7ae7d17a50291b6bba4dbc43f89fde3fe09b7fc8ecf9acb1e67ef6b4f33a7ff5e6acbff298dc35673135d5e83ba37df968330ce992dbed4e9465f67a195a41893194bc51c67393252ae1ed4cd829d99a3d23ceaa387209fdd974e73178459bda539bcbe89f5efbd5ef2ebe3c1e59018a32632fdc21d4972acaea146df31d3a646bb7dfa5b641ebfaeb130470a5ec7c416f7036bd3d15696be23e3b458cc9ac8460cf38ea6976a9d2ccaeb90be6740db4289a55eca386d3d8a7d17cf1102aacf46e57812dd42c3a6398efcb2eb5f2424ea1d55eb38fbce4d7b64bd7c7fdb184d8b0a8906cfce08bc9f6df64f9936eb6b5c6a636b395acb651ce6b6018ea9c93ce525eee624b5570f81dd466dcd9a909cf36f34687265b61db6bf298f5157d5fb37346385cbf4df33b98686e0189bddeb7f68f598db1b6cc7c3f792d5546e34fa807e760ecf7d8049f823004453048c6f743b87c1670c7eede311ed08a24590294bc9ac899bd58819763dfefacfb85ac66521ae95c77a7af06e772c8cb75cd7d44afbab7a764e85d66319ea005c9af8cc4b55e6df169e4f93e79b36506d186becc2f59d0541588819b5edcaa3b80253178639f63b3d9180ec7e8bd4e95435bde3ee4bbd3abf0bf335569eb100ed3bc94b56b338083c8f3298ef734ff762c6bed0855d73cb3b46baf8ce2dbf82a4347f31e8a6e16fd7e95f4147545489ad1378a853d489c03fbdc65273080bdca5f7aab6d3f8438d33ceeded733ab8a68c7ab89edb06fd5ec92c557fd59488c6f45796b7dc39e72822ebc7643aa5d56c483186cb65d86d7e865479ecd5eb97581fda554af613c486c0b9566a7fd5f9d2b82b57345aefce368dce26ac53b9e794be57ec16a498b744ce849ae4d53478fc44ea0adb4fbc3ed717fb69657378764685151a5d50d74d79e6f4da1596f898e9fdf95653c9fe7f9885d1528f1aa5f9420ac95de9f8fc429674025882c9758236e946163d4f1f5caaa456183cebb12fda02b6c758eec4ab654e879b4f451bdf4559697c4494d8abcff7045342234cd818ec0077c9232e6683856dea36f74329988af3a82b898c4f0bd33005fd1f40fa898e84bcedcc45e369cd1bb7f3527f80d6655c8735813347c3c7c05f81a176264a5ff791d9801af88047574008c870635457126b4069071242c24dc0977a8c13d43b889d27f08984d9ea657d241922bb12aa28a1408825b02663b970778bf669d585a975abba6bcf8513c11bc73a0c33897991c3428a5cb4dfed155b9a2909e6597dd8cac1ad62f9cfbcb27088860512859761885c5b6c5d89fd6b18f9e324ee8f80b4c507626762a22f4cb7f4527527896aaa97a69b8aa4fb09b16cbafd73a667e9cb085f7ca36067d4f740694e6c83c671071762fbba26a640c86422197894caf01b0af66960651998073ba7fccd3189148187ba22dd2661262766399a6b8bb943aedc590fa048816d1b9d827ca80935d30e1830c8115b18b754f20acd7a376272c119cc8210c9aa112d604b2022326f51ad674aa1579c081f12df04a9a2b4571fc1c21a8a4ae2c701eb2ebb0ce65cd2fc22fee530fb3daa6d82b3d46e33e9c918f6d33abaec34f45391245453ef4d128c4c068227a6511800d69f6a31a1421e2d322f897145961abea377c9393acbfa72ab3c3aaf7f04ddad50077e7c36ac46e083075265c58db4b7b47da253b8a9361c08a1248b53098c6b797622e228939f110ece18c02ac613e00b624c61eff4524f92c1ea632553d9b90cd886fd2c364b25c877459ba6de0ac8cc2a8b0f2c6d71a051f8727c2892d1934857eb995a8d728b9739872ea472e6602f2c39484d290109ba924933d6ae52c30eb4d80935f0d2c87d4dabf07582cae3c2f21692f0825c079ea6700065a6086b197582b76cac90a58451d7479965475ac8a6af662c7d23055c404246264c97bd23d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1e4050f97ca3e9ab31e561ab18cb3af721570380023a9349ed6bbc5df66bb243928dd3a4b5e113a0f99725c9c8bf673818b89030db28edc536c9620a1625c8a647bd3d7055039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651a0234d2325ed82369bcd415089692547b325ef28189482714c80dcdc5bff72a6152b70ac2f16707c63a42830dd6cb88ee646d882338d3dcb202408fc5210c71d1a8ba02b8c2ab7e06e43ccd85ce39a215e67914369c749c3978778592d9e34b7671283dc787446b5b70a32c4c1ca4613b01a5d0bfe55016b897130d1bcfb49bb5f08c5df9f15b6d531b06c53a389500675aafca9700fbc310fff968300360ab631ad95649f0bb47e55b90b2593d9a60bb0477ba848c0db9f8bf6c774cf8348c65695b31b921e4439e976b4306a47069c25e4a7515866c0bd77b44c7881121025cd2f28430383600e4ba0bd28074b7bbf2a2a3bd62a73ba240d644ab1f89ace0c8a83ae62f642237de265765458d6744273e4372add9cf5215bd39fa516575bad72034288ca3e0d3be57dbc7ada731f5f13fc0252bc5a9213f502c342a451b933d3060a2ad8a9c13013e3d93455327c187547809fa57faa299a843a251f8368a715508c32aa57a42f9551520433f9675add0359c5997c341464264986fcf67261d16b7a6989ee33730754a2ca0f66b6c98cb421c8e4b36002561b1a5550b93b144d5552afee236357c8093932829f864963159a8e7ca992b8fae006190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46ac74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fafc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +ciphertext = 94f5b9ef5dfd9caea5d92ed4a48ba23b9f55754c1aed2406de032457dddf538e797c2e02272aee5ed23bae0d5cba2e37e7afb8a472c75475b92f89db6ffa08d83b9160768541c49dc9da73ffa6f928bf16882b63c29e9eafb9467d0ffb5e3ac4b95c89a9462432ecebfa096e36901d2192fb2ef06ea10d908a48e9c1b2201b115f19f7b433d74a6ea836836a04e95eb93e1b844df7f36148ba6b218715cddc3ec5766df62ab97d5337869b14d674fc568a4c249f7832d34f05ce36c465ef020d00df336b2befb72659f97cf645d4420dfa0ded164cd10130ec7e9bb371f57bedda294e603f74b268333afc0d943330e0014ee57fd5a655aa24bb8c088637afc0d6300a8a3997f3e513154381a8f240d037791da03f8b536cb4a4a46059b9ef3c16de282cafcf7abf4c840584eef2a4617b3b015a0e3734aed2ca2d7c182181343718934f6f4bfb7bb3806ff6f412ebb0df25b588fe79a60f0118c9f0de2ad09031eb00f635fae0a2dc1e25d8460da9faf3d84c785522b817442fc1c801b5dc0192480649564731eb95aa96970b00677df4b2328988ef813b13c0175f6b73b2646a90107f1c031a920aa8efccbcd888ab6f0c249d22f7a08dc725ff5bb6969ea5d8a319c7c0b905c2c3b9688a6eb0d42e9b6d51f5ee1195b0591e7f279831e427d283b439a0432f77ad85345b1cf997e6232ebf21734b1cbb6d333e73e25f9aaa94de479b7dea838881b766ffc2f5e8813b32bcfde3695096ff2c9d201741c602be13e79a84718c0201a1232a89f6d2540e343327c1c9ce9c1687b4b030e7fc410018453f363d639470f480beb007812fb88d6c3450d13a9e9924b82198d9325c4ddcda7e3b1216753eb9364bc8954f1c3373efaf5bd0b70e260b712a79253459fcb928cc8ee8f770e233eff63b9d1d7e5d15db03c95a64e24c1c121e084f2aeb506dce765d03cec76be9bf8cb26dde32198ee9972ac2a441301e49dc703a8284ff900353951d390be673710d0f8c14b4ff42c15b6d2bb9e360d0b573b608b0e28d8cc8d40b9486217fa3c4783d1bb31e9f8f7f9b6852207b4fc9938c9f2b784ca4946dfa1fac87277ba62cb6a5b69bf34defeef435e6e03ec53ccf255fde48bc843df6ea502efe32f094efa52c991cde63678a5a8c7e5265cb096298f4d32d482a8149157aa4b025ae8ff5889928ffb3fb08499d704f3d146ad259e296fee0b83ec7fc4fd2ad036afa9576d1196c3261e2ceebf52eeeaf5cfaa38ae9f4adf7be4ba96d063ac8ed6fdf3480bc26c1ec8c382539f188e5b64e2016d511af0e8744aea561734efb76a4c943aa452da6523ff6b4c99fc8b13b51c74077cca51cd7d4c17b77f5f966d79e67cdbfd9489a71836c8e0f0fd9da93b4c1edd952d6300413dedc20fc77730811008a39f2b9d2a87e67d9657aaeb98ac4e73f99b4a5d9eddedfe04eddc6665cdc6dc277b5eeb5b86750096708205ec78c20a512bb01fa825ba85c8d1887d01304b10cc482c1219f97b5b7b97e76359c20b4cbb06c4df79de4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 817471e55466b5babf93afad879c9c951ba60d33dadd73d985bf528f9aa07ff755d7d79a2f9ab53d8986fe9d895d64d1dd97ad3f7a922526f79b5858f2087e659eb7bd4fb8a52a5953ff3622d5603a0a3152a9dcfd6ab9cd863345d8be5e295c06b79333bdac8938fe61e55350edaac95aca140398b74e75235b94417b8799a4b6d6933a8c8e5bfbdccf886664e7b8c5cb0b999bdcb2bebf88d569666d5fee2aa5dd1a8e58c0d36ced3a74d913fab8afb9f276be035f96a783f66f5e682658de520b844eb697112fd373a9470509d40dbfd0a7f85a94ebef55d4608167d925a476099c3ebdc3fc532a6d8f16be4de6416d0c30d55d808cd3c0823ea9265e985caff5538fbe6087703f28f157ae3cd144aca49f4fd15492e0df53ee5c9e78853590a3d521e843a0e37a26994197c3e61feea6096ec3458fd286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb380308d6369eb29bf64c2dc660ea9938200738e3cdc318b77ff86749c43c72f9667d80d462d549bdfeb3dcb0d9641b29308a56edf739e4b4c4d213c6fe69be61f94ff4c1a45472b5464f97c6d647ec69dadd5214f6db9cee938a934e5dae0b03be706b74cb8c674ea955a4d8ae1f7cdb56263041fca1871a579aafec45d9bbf14cd1f0a9c5d983d86b33acf923a2721c8b2fa7b058cbfe64f43bd90f60b6cbe9f26a4f55d53e7cdbebfe3aa424976132c3b4b4bdd908f7f2557a3658df85c868def45b76a207cb31b7e402caeef39dd48378b80dc3312f78a74065b2dc873b22d37990e465e425b9938ffa260d9a93a7a005e9eb956dab7c2336be3d3884ae51e839f34c964265f4ffc08f52cb89858d69dcf093de59c54021b83da94884a173be6bc454ad5a71935fbeb52a4f7544a7fccd3ce919ee9adcd5693d6e5bfcfeda4fb39a8455fa44eb8467eac3fca43c1456409e395e1e7ab12ec8f24ea4ec7364ba4abdd8896bc7bf81c85ea66c767aca6dab52058336ee4e7fd8a4e1d44de277df9bbc67f78fa0657530ecbeec3148e897d989bd49ffaf0fd0afbaa5b0ae748b8d847af4b326f970c626ee16cfe2a1c66003a4317348374e66b29fe87f37edeaf6fec75cfeebffbfedd96f6765c46f0c153d0555b41a2f7d50da52339edd8517b1a5f4e47b5fad081efd8eaf3829f39a40d7dd565937c59ae1b2af5b27d8f07246c4e1c4d230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26fbf51ab562c0e44bd238874e93a4d3c9d0a5bfb08a0b68c2c8fc0cb56325548da43e627977f914efd21d84fc3619823c4391e75ee2b5b77e8e7d7f9c1a37d3464cd5f9654307f1a0cc6c973e458cd9cedea7b6fcaa76d1f6dc44f74b986a772cf593af8ef215ffe17a5e9c39fa533b7f4fe8177ea5abe123e831e1dc561543a7e55969768fe57c6d499c4c615e1fd99d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf8df5f4906ecd7363cbe3841aafab88524b0ca3381f6cffdc84c6a112979c3c39e45157c0749c04c1fff83f53734bfee1f1842e0f7ff78c6ae1e337b542e5ae8563b16d99ebe7ff5776e85a0e9ff9a28bbf5efb444b7c8235e48f70ed014bbb8839b4b04a592c364aacb2c89689106aba29029c58ddf7050a2c78787358571aa506570288e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a181d4107cb723bb6d0729ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b370d37a66ce048a9dd27ad17b38c66880491985b2af8916c547e9c6cb16b506170f29304c4393e8274ee254a3f13c6b0e31105442bf92799f21774be9a0f64970e6ab581626115a1aa3ee4da7936504d036b75be6046e5778f58caba93f8640bdb24982c17ba3445f2ab983b685644b596ef66acf739039ad0a3cd61bb80b000f7e8bf53f60ebe235c0bf22c7873aecc6b3ae2f3b2cc3bb47d1b88423a188393c43c4999c32a886807cc4262bcd5a588c5e1bf8ed6a6ea9910c19a6042679926f314e7c7c85bf550482735e7fa088c857ac1578560a1a2f7e831223cbde33a46632b7e24d400a82a8c7307c23d6ca25075b58e727673d7cb5554042cfb9b7f95b11a55a9fd63b1b9f0b60f6931a0ba1ad28b485753446b0005e8710d7189bf438407b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b6c1729e7ae22e28f2082a5e653b5babb0d147a8748f2606ddcc7847c24f0d32771b910ccba85befcbd2b89c5035b2062e6b9bb40828902b82e12b752d48d52b7a6599ac014731e8da091cb30186c849b61954dff867899e5bf27428229376ac7d97fa03996160964abe56d3d0278f9f91fec6bc821fc822949ad5ec8a9d728b95b19052ad9442fa0527b3935f4697cfa3c7413ca2e81b32a57f69479e89760a46d710032efbb662f9467f0d03c806b619b9228135076fa235d502230e56669e2354c1b412ecfd01a429b5c76b17ae2ab99c73b4110957aa38c22c8fa39c00261c78aa571b953d868690761655ff700803a477917ac8a6105cbfc220a30a0cc1466d7598b2058b3899c567a71a66d5c9da75085686aa4ad4015100360c6102c84c336c13b229ff599dee4cb2c90a1516682330722da110f42f7c0a4f23a2089add65438dc66246671be41e7766641b4c9139777e08cb4d5b953e602931a7db3e1ce70d765516242ae8987454b898f19c5103bad39207bb16771b5d4191abbbdca9b5bea711081ca6521149b60975e02cc2250a355897960a8e203ba148f8be76452420d2134b607976f7809ce97597d8ca57337fbbd6748c03227607fa082195b49753c43047b95a020c7d195b01dd3cddc4c091916c37e447acb606f2d232c37c9871831c1fb9a8d00717762f18e62e7995a7393e0a82617da4674078d8f10065a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e887107d6c14488e604dfa15e55004fda8b65ae19006ea7c8a7471b354a4e746703d5c79857a02ec222b78b966ecf161d97ba7cf39b37fe173485a0156c3712a6ecb14e629899da9163709b672a243d1b87e15c0ad611419d85522252bb5a02ab725cb5eaea5bda73976d534a881b8c32c5328d117306fc5217aab89cf51c6174489ad241d1cb261d449f24a235fcd46fc19a8d14a4281906236738a060061a494947bd91604431b1a2871080616ee2e915863b2bf2d9cd86743b0cc12a5d21c6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db85525167378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +ciphertext = 4f196d816122c6774617c45e22df48ac3e86c3378f3459e569534f574842967a369dfcb6ee004e1d050636654bb9d0f7a2ffb7c574010fb2f321f85aa574dc3e62993a7870475787ad35d68e5f7281ab98488da56a7a871e8a6eb67baa98c09b9ae117427268d3ef7a3f8f012d0e0b241c39d12f3b1d405093dcb3d20ed8aa3f24a0ef8c08fa24623f3b96845f913e96b1896083f7cfa047bf50bda06000b5f8f81ace902062982aab78a5f800a3d7d7268855e8451de5c633ae05b8075f2d6c98cdc8fe55d7ce4364407f4789f0bf91870ddf6630bc84d3d5d5f8a08e20561c8645a95e51b1e657684e6f9b23fa979c97a22dd6a2e3a729f74201892ccf378db23abe5a6c6734db7de54555e033966516b08de0d652186327af83691a5af4a8f806dfda5aaea644bf1f1c32a9e3a50e9c5783623f20e0f7cceac32b57a908d28277430ac7f2d32232353c1e8d34c4a6e5113bf2de9a074d26196459638f76801619a699dce0a7599cbdbc9ebba872a1bc1ae83d07986e534454ccf1cfe526d4fbf599e79cba747f4f2c6b3a6e1fb04b993df44d87517e7657d81d5fcc1b220a3069c16868e279351ca90c20a73345fcaf12cb75f43102fba680b641536345c154cb15bf7592611313f8e958953808b06bf0d5655c74b022e3a731280ff7a7cfc92a60fa6c51161e3534e7529aa310ff848b4a0bb7c00f2425bdbc6cc1c2fb050fd0b2ac17db264f48a025eba86a7b11651108174b5b2d859205ef2480b9adada70ae09162f82c3edf176287f8e742cfb7a233367867ac8bb2c5306831d3c8d399fb5208ae3f15a24a70493b62f7a918312ea3fad7a978beb11c43e679ad45c284a47f68ae2970f5e66972a024ce0d6424e58e0262a0f94ff07621a2d5fd38817f7d989a45282e71463ef37b5687291c4f852a6b13625308f3a4e6fefa0ed84c3cb47725f00cd88687757d3c625da09bcb8910a441faa38212a4bdba9a1b513b003efc55fdee2a3bfc1ce0d0b8a0f2cb4b828c5758a174fb40b9d245f63cbe3bc07fa68067d8feb438ffba418e50ddb8ce6f5548b8319401d1b4193ec59da087badd67665e9b73ef489b5249c8794ede24e70e3a2eaabab868508adafa1c44dfc1363d3d8091a7acfbdeab2fe73de1bab8507b180f570ceaab92bb297557927909045515974c230840faa67d9df34390675fe206bdc4b5a48032b455b45bf85d150703aefcf57af41fb0a094816958193162e821f10b16ad8adb8021b0d5cf27447b9b2c2c3dcc3513832d19b11a85b00afb03e79f3e7cc06178639eccfb943ad60d5705f1e6c8ce1c8b1ac9a62aca9500bf870414aa2613fccdd9eade567c135dfcfd850f5d6617b1dc181f375806fad84bbc69e28c49348cdf09d7714fd35a49d57d75ae6d74f1ee337d2ac2e595152da79059c93452f0f89be3d1b2cb5e2c454a4fbee52fd97f51b4da45c68efa1bc08441bbaa3082f4b633e06251b9859298b2c4201759538bc46874fd4678eb27d7d5ff35b4fb497ed739d5d7119e213a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 60e93beb5544294bbd622e41956430d0fd41e0f969e954a48298c7b503f2baeeb70b7c796a753cc5bb93723bf0380abd6b8aac4f1be02ddab380b88ab9ecd40fcaa8b775882a673864fb757a34532746f7df0690ca1dd0b65ee2dcb5d235cae4fea59a764736a018a091c8f2a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb7926463f5d6755d79b972ae993c9e44e3ac14db3bcc85c4f98a2e185bf4faed19a4737dc78547847b7ef385d3ad7bfe37f764cc873be8cb1286a0e7c8353adfb9bad5a17f0893cc04ef2b5cab8f66706955c5e168a99ea8f0a95dfcb25a434f2ae4a00e48772de4d32a51bc73a8cdbcb105cf9be554b2735ed7f03e4c26dd82c735fe0ce68833a47a619a611b08394a6da64d9cf2c25aa1121a80346d5c9bf3522183db15f6f69dcf5febcb8e3336870b4cec9d3a89de4a9042758f517b55f95e33b403c50169da0f53542249e18f93874c3e9be1dd63ae9fe44eca615615e424235d785c92ad0dc412f8ac0ff5b88f056142f8a0934734b09ba14d1dd89bcae36279a5fe56f082ab4b0709a6dc3f79f8e9544f49d9ff78b264399c2feef9c803b341e8e6eae96bc63e952d65d59f0df43b1ce8e1f7aee5498ff70eeebf9dedfe193bb61b870008ae57483daeb8ca7ccb460193c68b5d9e8dc738ff227fda89b21ecad053a9fa4d4aef8767c0d3f3419838c8c8afc0b3d68e737ba7732ec68a8570948a322a143e5a03888c08a1bb7c42e9db91128e9ed955f3848bc3288ea881a468d26aa7fa4acb926ab8696bf4a094b8cdbd42329fcea89cefad8e8a6b0ca19f4f3b7afcb51c2fed48ea44037963ec1a325ecdbf7555977f468feb49b8346338db983e513bffdeb35a300495f437cba88c36d01536f7a56bc9dabd110db7786ed3120fcabb7e82e2c440919435a14bc1ae1b35449932496f885c9c301c7f58faf778cd0a4722ff6ee32c5dcc7a7283ece0e3dbd4723f55d0044bf1e9f3505e80f32483f7079b2c0558b95c622ecdebe885b2580931fc96e7b6a4dddfd54cb327712ebdff90a6a8ddb6ba17b3efb1e7f31d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fead8897caeedf959f380f9a84f7d7ef676b89fcb5e94b8997d95543ef6cbd28a7d02befef76b1c91ac327874c050dec2e6f80fdd6dcead3587ccdaa6ec76f064b3264bf419b03e30aa7791053bfa7ed89f6cb8bb12db5c6ef517d5bff34ec3c4237af98dab3f4d44ae26e773ed53f391a689d7b38f11e55fddd80869656e15baf9a2a6419b38c2ec39112c4f16fbc5d9487efcc4369ec9daaccf3a7531fde24f97c30c4c6774fe80e9b928a0941c24cd3ce588f7d94eaac9eb74b7959bfd8b5b15ff94ecbd94c5f3dfd4f5e9e07dcd3efbcb2937eedcadad018737bb9ea37aed30c1a6e55cdbd4336a4bbb7c5dc89d57ef5c575cd4dfcf9c8407cac999a54976bea465e9075dae67c8f85b2d554ec8e702f3d62689741315eaa546bc63b4f723bb95f0dcc525944c967d7a5793c34c7638ee5a6d8c878df2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93379fe5dcf2959d1fdfa16fff77b7ab78dbfba797d3f13dab307caeb663c86bfd11fc259a2115806f9f68ab15859a763a49d169d615b4999714d550707e8a0c0a93c8db2fb5e4de7c93111206f052a7d7a5e0b5632d94c7a87596d24e950b361a185f065fa96435f312745164693fab8d3a741c56c6f10d8be52c06a5d83cb1bd327e5b28db12291d907a2888136b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861626167c5a17cc2a4cc9f668df0707d26795de7f771bc614b994b574fa309a1e1c8b4a0a4ad6240286bb78ba701ecc430269a37843149e1f1aab731523359c735694f09298e2a1a08c6ec273b4a1d57118b20524fda18190c2029da4095ead53212f609a76a343d5c68ff17ce6b92b340dbb8cc6c03ae4b29df243b93233af6b95eb5a7a8b8643b0cf5a8114152b8ea54f0e3668511ceff536d888baef85a62299c641769023b7b92088546f338448c1977804b71781a554bca5f13c0480b42c5a6626904516139abaa54b429e7a0502b17a5a2727a7f230d63c5764dd497f164b24e5ba3a626785ad1b917a6b77b175e64323783c9791832a7c442b895eb338e6a29ef671d4d7c0230668c14bc794cf11340229ac905891cf1c51ef62b6a4a0553331f7f581054da45c370bf606126b39492e4a3b8592bbe0359bc017557379471ef922367d82635d8494c88bd38a7720669a1f9145367a92090fc5df15c034b82cdd9b7cb9ca76e74b2069c36987556012bf0746424677f60ade29c9cb52c6d9cc2052394691d7306952c65ef498da41279eeabccc66b3a41747a8b447d7ee81116eabc04f4b776923c93a28ffe888652fc34415baaeb6854d4732745a4bd5ba61c35678780063ed874c81823ceae41b9684a05410266f7ecaffbfcb5285472e5b02fb8c15d126410f0ba3ba8536cfdb65d23797414a55f2620be653a98f33c95690714fbd3418c6893f8693908d41d6d69a744e63b2b0c190e3b1696a5c8b1cbbaa4719a0bd184f896c9d8f926dc933ba81b2785c05a51b22a95191f43dc23b42c050dc9133de2b003a5b6f1a5730f490454c58af291cd8d46acde69842df79353670a54e2c88cc693745516ee64c2afebb95df25ec0608ae4aa9c89215d471bbf68dc6530fc0fee495fdfa09e98ba8d37f9636b270bd1102579eb7f1bf0b911cb79f03537168867eaf60d77d48be27bc935b02662929dbf2263270670e0601e5e43008bcc07f06451e54755fcab421d584bb603008c9909caa61cf99a4b43a93ea8a3440991ba402c9a8fc51f90584c55eaa450b7a600342e98420d728a8b6344659f2a0263140e69ab86bdc6b20b3aa0920b90c70c0108358c8a92b27635154af9a0a76080ee593ce3d37e40fa33d0c654aa77171f822e0082c95cb60b54a6a26099443f671e863889f35a0b9597b3442a71fa704f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75448d21926da0938f92b9133a92e426dfd2634a677878ea9820f5c26a2382fdb1c4b8ed59db74b4490b87b0dfc35f5b22112e5110d494e53c50d3fd6c64cb485bf5ab37f7a1b709122c7086d3fa56fddc966db2c53e09b976f986a334290dd8c3c7e6582c4eaab182766ff70503b03b4e68261cd0303f7a83732795cbf84a04d78a541a0929691c94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +ciphertext = d1b9adfed05b0545598a380a908d0630ef5a5b633f1a0f71b7ab658c12b5d41870dc738d16dff8ab4009b04f1681382c91cd87cb1fa19fb83c6edfb215b14a21f6595e50f60d23f65c8651a7acd2d42b8093d36511183caaf38482ec02d0c5495a0ae08d86be9177ed05abc034337e502dbbdee1555a5df175420ef9d13ff88d34e3dea95109e543f83060050c948cb5248bbc30ae8dd31c16c0a2aa6bbe91290bf30ca690edbfdc3122961b529112d1c88b5075fdeae100176b48fc6e954de16894004a33f1150ec182d1978dfd30ae4db0c7abbd069ad761c131617643b25bb42855c05586cadfd35578b04ad23c599b200a42c75cb4614d4bc49e0cd69ae47af58eba9c4d2adfd39631ccc550bd3052e33514b1aef509d9d4156520510eff630878b9612a7afe6e652baa02cadd1cf5875ce07f04345a457a9cc94e4ce3ddafb51314e11701a9062fc38d126d3a5846c99ddc89423396c5dd19ae00648760bb9647d0d4d85aad167452ed2405f1482a9699cf70c99a3d9e7b897d99bb5e2f59dfed7a1c681315a881cd08a0dcff6678c7aed3211417d11f4d40da95e46c5aefa7e88e27ac0e91ebdac1b6961be17fa2c5b7ebcdc67354be0e43abf6a9a611ef02fba24a662b5b6ad31747155dcfc62ccd0149b355cad072e462331298f6b0155db2a00033f6b6aa71b8fdfb4e2db72040dc5b8e7a55efb0cdeaf6127474738fac38a5fd890259f86d5af6339c4cad26d1ccbf98408eaa182026909dee6be1069fdd9dce80f2c9233370a8cbc0a8a52b3eb999161ca9bd8c250dea2358f72340f48c9cfc0a8f347b7480630659e13708a34a9b121beeac05af0bb9f8475674affd1889dd75146d104ce6d50992311e3132c4724bdb1f793ad76bf1f6c3e30d9592aed479e406dc470aa810198c30ef25b549fa49ead13b66db0107201ac624982ba4570f97679afdaf1dd174e1121d6e02b26d8435795fde7a05846323c5dc7f64532375ecc44b9081ade905e4e194d1d17ba0c91507f16e34d4befb2b6ac08a0f0d3a8f09d2a1bfb01580ed0dab28645faa28866135961e2910481f9d39ce5a0ad97390a1d05f40a0645c3ab4b0c749127cd17b176199b5eb9e87f625bf322cf226390f9de5006e207b63c5e1863bcb60c6b05f7d3577cc59e9d9f7c8be6b30ba9a22f17b6d860ca6621e00ec18733645af0e9b63a40810225fbaf470ba8d232420bb004e779ec73eac3d688ee30926cd1ea673ec6ac7acff1d255189ba3ee8dd5d9ef0c0d3fd0bc911f818ebecff8cecb65339b8762492e79d4f69c2efc9e0d6a406b1640f820454f4cec11ea7ec441bffc79de43f9bc224a570aa693edd08bd637a3993de98eb29a2f8db93347875ad3adfe59ef1a1017ea9a2151e8e95c40b92f357e7bab7c5a74349e1aa557483667161762594cf28bc2f837815679729da4e0e1a567c7eb92d4cdbae032364db056ddec3dbab4d2cf2e94ef0719ea60465374d37110bc7d89baca24f7a420870cadee72f58d8504a37bb7acb384a34 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3a756d6ede57aba65d618fec41eb4edbec38835cf2e9ac88f14ee9b57fbda0a6ed1f5c3268ec649209fe5d066dcba69ceadfd312eec15fb8efa60e4c6c956f88055fc2d35e6b295d05e6e67e4375c0ff3257ba72c0f97f452b60a02fb57f8cf7f71a4f259938b5bae8097399a0e3fc371ff03bb6769015495b4bb7317c9e99c966215c58d3455efcd360048f6c2c8bebb437a66a968dcba35dae7d98fcf9e3321da10acfb91764719daf5866c9855018fe89ff9e78b38b40a53c4e6f6fe63390a39db54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f595068d9b1095405949cc56ded9a21d864965fd5f83a970083bffeb6550893b5d6ed6418bdcf1e44b6b05a9f9093e386c9d44fe4d4cfbabd4be7efb49aa2c67eaea9e97d2e4b7d58775962570d528b8ebc8d32f8d65bdcaa391837d484af7239a4a8c0b8f140e3f4aaa6bac0ca86e63f523d9620bf9c2c4efaed2365e91ae699a4cbf454c4d2e2c4273e9345624ff737c8b3697b9831d39142c3e25b346d12dc82995dd6def649087ab763cf5bbaf639c8c7a852bc76d456ee69747fe66ee267844a7f5eae05c5821fdc2b98db05cc935a3bbade2c6a4881cac21938a304c4cd3cecc1bfabd932b777cc459bae4be75389862464367c6318a15f1de6fc5f17da139a95523eedd2f4e34c075f2d05f83466fa209cffa9553e014934f51ec49f5fcd87d1435db935bb62f3c3ec87bb7f7427a458232474ad9dcf22c5ff149977c7f366f49bdb14bbf60bd0a8c056f3f9c2fd91bed49735d64d0bb4a259d75816aa24a7e8f1a7768c3469aad7e82d30dee6383d38d7c4ca258d2693a354c19c66dcaec05fbe80bdd4c20bd95b42947d16b66139384c82fd6bd0ba9ad9bbb5dd7593d08616d2e4fda0e3e792a5b4a4de22d1c571f23e5d235562c167d7546c8ef7536a929982f6a55cf8fd9b0d5735f69ac6d5fa824f5d8d258ea5cfde075c54d8743bcd76767b69b5e350989e629c97bce982a75806136f45fa692df0ffc16af9499d8fef7f993eb3472f95d527eaddda205e4a9366a4fa978038b9e4685fdbc8d84fc1fcbc6aed08d79f544078343e9ad689d9dbd77c18cfe8f036d7210f4a0f5dc749f9bdbf47e309027968968678c0e35af75e38c5544abd57ed8a64641aff4d42d52bb14bab4e5edaca8eccd838b4b5e3a36a351b82ad785daf81e8ed6872583b8babbd62a5787bab8edade9c80d9130ec6be5ef5d9a9faa1ede3daacea7f1daf7fd7896884e436003789b8c781c599c99df465c85e3cfe85154d7a6562e6e5b3b800deaa6b9dc7c0d998b9defb99da6afc27a5ef7ce52eb26e84e9ecd038cba69835ab46ddac2e87368f37888ba90f219ce9eaf410afdb3e1894db5f640a18bde715e95a45da61ed6fb2c8af1633ec530f557d4c5605346a6500b7c1494d12fc87dd55f6823c447b71a726d65753716b30d3ef565dac474ca3acee664228f85a5c4a726f681e996e9e3af89d08895bfaf6bd6a3bff3a5c5c1ea894cb6440d075004f879b42ae4ebc8fb74bbd132ddb3348742dc7f44e85dae2b7bb57f8a9537a5d2827880f8b5decb1394db2553c086f7c113a300078db1bac7b60d7812422cea108045d2888e2c29ce0bcd454b95c09730d6c4698e779987523de0e972332544c34350d29c7bc030bb6273b9f1c98c3a63170abb2641c54dad64790e83387c51aac922814f834c4745409273ab00051b2a819eefc9a048f222626409fa7b3f8d27a0dd754f9372aa37eb92f6454fdbe3116d406b571203dc05201c31a52ba8b2b95b191a7b7b55e743c4ccb80a710863ab741b727f176224012c539af2bd062ba6be7a42eac08c5b6b420becbb41b55454ec1f41347ccd984f11767bfc82665286a56dd31598834b37ca6ee93658999798ead094298160b7e6c76978370db3180273401532315168a161e087d4c6086846a3b60b80103c1ad814843bca7ab329c7914982ed32bf16507b3024a16f231281a732d3d155fa60260064919c484c1741874ba96cfd91aebe5c314e407a66d7cc4c846176d759618654ac2a52fe69c69a375ecf625e2889abebf395fa20561ba6300a72a2091356fcf197c866ab5468a3af7bb3de755836d9784f7c0949445d83b3358721c7db3c09b5120f7f757bfe3366ae4365b677255ea680f27c310f768e56f1aab8792259340bd6b984406148a254bb605a291c0946c83b1e9c5bb3f879a787b9106f98809e94bdc23c062d592318f9854df04bcc343d64387baf398599bb352f82b1f0a5b530e824cfd69d7a4a15cb5624f70cbefe1c61302b8fca337d70d1900dc817837619fa893208da873c350f02892097708cc637093eb25bfb4b3c793331f0fc73c5446cb11276824cbe419378a224a683fa0d17c671fb8c4bdaf18c20c53a21a4bb8fba9ab7a1b7eccc81946bb5fcb15e1d08ada7761a55d503dba912b73765ff93a6ab642b5fb72ed4f16657ac448a1957413cae547ccd76d9936c860c70c5635c28754421af13448959d67cdea3997ee923aa326129b5397c15ab90f95832f263e080a42460cf9f081152aa59cf17263d008acbf146f34a7808257689a3148e58a0a0117fbb47bca97810a42a7e0f734c0a17745afc6ade752080b39f3267399c20b1fdfa195437b83ef5125405aba8d2ca42040371c541a5fc339772948a21b7efc30c909c7938779bd012642441083150118ce431baa72e989425210945a7c47479f4873e3c3ca6698ecb2a050415066d0bbe5e240222a2884b3cc17bacc14164be0d21330456a279547579f8a4e9443d913a154210a3fd1a1a263186445a8e1b884bbe8b54d0196affdc47544c8d10a69378fa139bc8a422c44c5568555f9080f170bc6e97284f448e6c23885d603a732c469b376a762b5068e29e80b74f994588d9822f3e81ba6ffc273a9c905d0910062bbe94aa1e0c8c3424303845779f8c9b515dfa0864578a66da8ad7b56da2810c11e1a2888b88bb55b8c096a145b62ad9d2c98e003658c9729d7b82550527411a9c0b981f3479251c1774014749d211687dda83626c6bfcd5b08f8075954bc10f48623838a736e38c1143b9472b4df5d30d37f0bd7c727a2f16a3cbe0015dab5a12e27a63f7aedb841d6d9bb1a79a5c3e903c9e374da62a298c549b9842b77c33aab6b4939aeb55704cb610d084950c41b746afd7157613618f6f1574ba51b36f7828af0aa4f79c0840ea3d679013df619046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f49da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +ciphertext = d7ebad4e7d0644b802bf0d325f8947e10343dca6ce3affb6645153d9842683b6d7526bb86e2d07892ead2b38662504bf8829b3591bb44eb03822d34976031ee39bccd8b418ed77296b2ecf1517a37aeff2193fb1a6f90cb8b3b46a213aaf471f7170a04b7eb24b8b62f273061fd3f04e567c695f9f85c1749f052a508f04917c7fdea48643f2aaf8d3f4208fa6e5e3ee001054826da4ed89240acbc68471bb06acd6843f639875042454ccc3fd0aeaa0ad416c16ee17afc0b8df9a49153ac2ba53d536fa4587d69df1360d98c82589f9cab145b07a4230e5c82c856a74f0ca95d205ce5d074c9bb54bb1caebfea0fe7afc30b69b852663752f478132d54d26e5372cd62f48e0f33c836a1e5f38562b6728061c2875126527ae4e84ef15c4e29df126fb9c555e9ddeb9cbc6c07036123bc615aeddaba1d53b0159ccede60943e1d00d7eeef769e3eae0181c69556e5daa1520103403f8b16e9e921be7338771d65339fd89e180caa88ac32154b9539289c587738fdf65eb3ee011961e0f0f365a5e885e811fe2db2e12435ea84ebcbb9e70ff8c8db1325578a7e82b1dfc53dc5322f971ba2cebce3772c019504d44f86156740d31d44fde5d877e68c108af3b22dacfee863d21d40e0402209eac16c3ea6934d9031fe217b326451b29130e42788e62a0def2eb2fedb2b01f57447044f0f61af4b71205b6ab352cf46f738d9582e5554d6a1088afae1fe4c7077beed897d13641adf5b6c053cb3d4e11311ad3b07627ab4519e51c0c767c8abc656648524aa42d8d4d3bf4fb82baa022a82e095a39c16b6945779391c3125d8249c6b66453123fd713443dbfefa85f1a74981b40e72065972af07d47e7a1de0f42a159dc1909ab3e8988f43c4a6b729da0a8dd33110c777e2344f1b8179d83de58bb2b95a8998b00008b2022b50a7ab7524d1189d840cb027c3ae29ccc809e3a977bcbb4aefbf16c524497e98acf053e14bedfa90b01750b1cce2c2ec50a701bb8ec8f9f5e3ed0e6923f8926807ff5dfae71256afa331f14fc8e73aeeb30ae63b3881ac4c27f9973eeee6095ec9033df4bb73537c304fc037a9d04932b3aceb69769e71cc73eb020864395e5b4f455e6ba92bfbf8588cd5bd3ecc7e9ec7566e2daa123d4c4037cf1fef134078f463e4c0a901d51071fbebf889245ccf13c0c0a889822a485b06fff11b241960ee95b0518f668c3c663b9fca9dcd911246e1d01d524a309e96cf50839deacf9eddde59ef2602bacc13cf145f23e98c4f033c7ce1896502f88452201fa81f90a16cd2816f19380c0dcc61f342fe479ef17f7f8212c3afb8f607da4673cefb3d58ad5d70ff938db0a593b1fbba0418041093f386761616a851a23fe0cf576ab1c0903c31f3f01e6cb76997f0b7dad2b088abffd67aa942c09635ef3a90b09115a5be2c694f493d076df5152e02756bebcff329abba5ca82bc77a699f650102e4f80d57d6c74a45779e53ac6717f2c449451f65f16a92a76fa87ff7c2dfa5eb564ac66e79a74b1bc75 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0baa531a985251b6b10153c8fce6938a38de93f9ace7a56dc7f44fa8cbff89cd9290888da8134a0fc43ccbb75b50b6a724d6812183acf886d36ecf52fc89341938d314c761185d87592eb2f3ac4f1d2db06365709ccd7ad426ec94d4e930568996f8cca58c4a0536cd5668488715593e66621f96c87b2e78a36438dd4c390dad532e3db88dc7e2cd3c50d30baa91c98cf0bacf32d6dc81468307ca35b47abfe69e74e53467cf8bed376758f1a59270fff5f0078ff288ae25df32427d9e4726f4285c4fbd35a333088dd643cf6dbdab6b27c8b679792ecb8ba5cf8cd9bd9678fda7ebb692eca6777a2fc4ed7cf0402533cbb9a3f2edc1036df09f0ef9a626b763c3db5e49c4c479ee3a13c2c37deb6666aba2dd99987990bd1bb00ab580649dce8088cae30a5b20567295aca7f029ecbdb4795e78bf150c7954f9a4998dc219cf3e5a0e4621ee8f18c536da0b7808bdc9e12bee342cfe7e5ba799653fc669c1032aa014cb79769361b11d91b6fdd0ccfed0933c6d067e4481f491b2355e72638832ddc4f4daa18c6b4ae6f8f5e688cb812490fa13b43e3d6e5bc857fcce8a629f3f6b685e5fbb5beace871aa8f2ff07caef04d41858f144143cecc5b0c579c84fc949ef359f0b24b210cda9f44dda3217a8058469c78b7998744025ef75cd1c70a96a75fd96d19dad31ffcd81dbdb796a66e86daaedf9cd989415f7d35aedf2db50b5136b6737829f0cb1da4be31bbf38208ad1200fbcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae826f7012af634fec159c3870f7c69126b3c3105de356888f9077fc217e68dbd75e0a4dfb8adbecc556de88d89ee6efa39a6adcda9c3c61f6d874b50c163ba7b19e656f5ff9813cb318c87abbbe2a3f8996a4cb447dd793055ca178aebf455cb956443e57ce60f4788cdc6b009cd86403bc91043fd3f3f74fa8f5e9964484d7a52c92cf75e153a4978d1c0e6c8085bf5b53c8eba77a9422f91df78bd39895dfee8ffd3d9f948aebeab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5edadc6b78d90a338eab57a222fbb5a58f837c097bd50e4165aafa71e8ee3bd38d61dda90369fb769bdce60a704445da750bd3f194821396d3a9d8cb89ba6a32d37a15549548aace4646d47d66ca4de6cf7643c2a5939478a398749fd57825d172f965d4dc6cc6d7adfc46d568a53c98df68900b7b212ffe50cc5e4613d4927333beb7bf73446064d76c3b0ef84c5d32048d4775cddf02534772ccb83caa847575e461be56a7238da2a9847d445f55687a84baa06dd69d4a637efdcec0a08ebb97b541fd77a9688386983eac7779e3ed7cd2ef13e83b27b465563950abee8bba74837375638e52814448f37db6dd865c898e80aa17ea2ac4f740e93f05c3fa9c85a06a5fdbe2ecc5335738f9d46c90c5af1625779f3a329dd6937076e8afc3d0b5d7d99d3fd126c8398fbb8f33afa35888bcaa187950365f022585c3ed8243f53122b6c5ee9a95b94e51b0eedb222de35c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702f3f7b3e53555e24abb77dca6f5d5df1edaecf85e3f7e36374988dace2af54375d684a6cb1fb38bd9c803a158483f91175263779e75b6d42734dc72fa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106e91e32341aaa4808df6528c3ba98886184e0195e3ca09d9cc525980cb5a2e9027c6a88e9042bf77653b9dc02ad3cbb04f594bae08da4683dfc960708d85e39a28ad6e6a7dc81a2f0f8167633901298628b695cc1868756a97d80b1afebb71eba5969a1086de4d611f737af56a83c7378c6e5e04e79a8967514cc668bc8fb7c7a1a671e29d55068e34d883a8320438ae7a44f01db1d4dd07304081d684796a9257154381ec44562a8d005f3dc4c94d5ce9e36705132acc8876142194da54934095c2d5725a10e376432b17bf7d1b085d342cb3c633a085e950248ccc9c7ff350efc341d07d0ca06e6bec943353c479506691f2347a29ccb34ad09c929692ed98640e6b8560529cb17030ebfa4c769fc7707c75d86c234edd78e7b3010fe86bf71748cc1c5b00023944774200b2163b403b8207093dfc959b6aa09fe6b98f6e83f972a50abf113e9da2fb9fa10d0d05789ccaf05c448854249ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf428087d8333b16b1a9e59794d49a40b513b50867979230243b27f3d784932e1caadf8b58fe11bbea62da4875d004a73fbcc90b566ab998a45099194d449cc60b0562570648ad588b213cb99a01283706878287930a71b68b43f87023d2f49829abcbde6a37a941182b78b8cc1b93982c7a24457a9e1683d2bcc97b4259518e0102760100e1c26cdd85022a04a91168486ba3413613ddd6c42ccb563379a08096b287b41a011fc9594d132e33957f2a5bc1db4c57b4c8d9d3135476095ded35b2fdc09d8f996e332baf7939efb1032e529606677bb1144374c41c08807c9c0868b0c32772f18b755d7bc5c5b12f8eb9ca9dab589185553b74408301062c90b2d68504f0718d42a1989f050f9097889aacdc175cd7e6768d626a8c9aa1b0cd6cbe91b10af1a3e507575b47b6ac8c2b7c801a81985a81ad4ac04b32d0dd880d43b3d36857738369b7898b231b24ce6e9944526b9ef370354e21e38f6aaefacbda63497a85327a2112a5db95179c5285d805698209f2a1b67a7730405b02b3507b4e4b65298734f5eb1b66bcb68f9369abc01c7e4545568d432a685a6e038122253987edc55efaa3d926413dbdc43f9908df1925031f45d28712734fbcec3724653b019f7d5698da7b0c3c90eece1a1be3567a253a143723b9550c8f7333ddae88208667353a6184853a85a99c0c463189eb5763fe59d678349f536c56d014cd92b56ed2aa6b0518f1221a49fd6588650057ff00aa29b93f182b3437386f1f846d2a3c60cd900559425b2b7a5ff88cfabe24bedcc825552577b5c12e4856ddcd91b0713526098b5fa555f105a0f1219110347af9016254951c3cb5c7ebe602564242276399b0048ad8d370b544b1cb9789694c7753ef2cd4ab51513cb33f38bbb10c83c9a1a5fd1489d97476d9bb314849581d688c3dba01662b539c50b0db8e889a4654e6af708a64910fc503cfa0abc21b8abc233ab978965059c41d1123a4bb90306aa09263b25be885f4db186d0e720e97524464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d830371600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +ciphertext = fbac7fc21143080d74a75a743e156d9095fdd7cd5a13091f191437df1788125c9f908390b664d8d2ed2b9c56f0805df3254604d1f5bc1a9b49257247ca57863636a9c61433fffeab86eefb6ae8c2cbb725f7baf4d75e1f9ace6420cbf71bc7be58b5df198fd08bb2247bb19397754bcdf63567eef5de89120e40dd879993fa9dabe971abea02b5bf2e01d7cae26b98fb9ea5f253c6db007d06ebfa7047751fe66e471a2bb0781ba873074aa8d6478ca81f090a6134f5808fe60ea283557fe932d8916b675f5fd2f7104e0f652d9effc565288e2d1abea97e5313b482b8f83cb36b203cc63df3eb063c54f2088bb20c6a0d53d982c1803c646e57e6c4a5645b86b71b5890d488991716f3ca3210e9fe4fd7403aebcc5c54c6d59f5a9195d78d8223e459fa223e4f3d54d3c4443b54026128c71ea5d9171b26f63746d592999c63fe4d21a783666cb737351f88acd1428d46db5aaf965f4c55263895018246ad78193ce1e347d9d2fc71b9bb196e79115ad14625e562819d16bba8fc27371afbd77dbac73f4d20d4eb1d748a17ab00e2ef7e51c439ecfa7137c7183c3700e579b1f0ca20f4c2ab04645675d3fe763eb820274538cbee1fbd659e790bab87a9fe7d243cd3ffdce8e3ab157c4b42d354f37105b412ffbdfd0f626f196fcf44084e6d4bef2a77d92b6be9f4cd19a1e48f084982162dc832c36500d5eae06665f241b85467c3687b1ed0c2845fd98862a7426997f70973fbbb16bbb5847e4df7b793cc123e247dda4b1609aca09f9e9e41ff14d70a7fd54a0dafe80dc324d6c8cd03e1d2b7ee594a2c71e8b1bafb227b100b57fe8d04f13377af132f3b0fdc3db4a67163a47a8878f87a98e6956f7346bee24a2f5a3b1a393602e940f21040b4739dc6fddb41024730eb3756f0873e6696a3b8c2f7b507c36e9342a41a774fd55eb91123c54b874fb501b8c7bedab5436b50250f7c85f228b9b8ac016d548680a4554d6019ef68ece514be2a20b8148af168e0980aafe69772a0fc11cbf50c0ee4350d4cf72f4212605477cb2abb6ebf4f492452e194f79abc56f71ff7b00cf68b72a4763e442150a6c507e52e7b47f9984444680f7204a5e848a770cd27cd3364f6e020f2754d852b6fa82bde6f97d41909e66a4855e56c82dfb21d126039d9f06b802959d58c103abf59e90426809492053bf9793ae348d53759573545c3b0b16739938ea6122f77e1a56209edca1377141ebf98b5a79b6c7f1ad3e3afabfbb0e77c4578cfab6104207ae4194675ae9078eed0af2b2cc27d47d66df086a8eb89e17b65a7c5c19e0f038bab8e7f687477b01780ef556aefefe059f3fcecde27e8c1f83b92a4e325e85398aba2de802a6c574824d9bf627187e5562408e6dd53110bffc6269112be727a0bb638f5f011b1f88988faaa12f0fd2de21f969d1ef5e76a3c32b28915b32377a54eba21160ec0e62ad4209f81dee1cd58751967f3529c9590bff1c21a2caedab88c88eddfb7fd7099c3b097f4679d3a79430c2dc9fab2afab +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = e1dfe21f16d48fbc565fdaa3063dfd439ab3a81b31fa257aa604f83547c14666e0af5ec2c1c8603aa36d1575754a86c9195becc6a9b8c9f77ce6484c5198a193ea4369293798943f7928e42f849c8d7479eb0588e6e6b4abc4ce81b4d66434e4ec4e37c2da905ce4ad2b85de7d966d34a3b1bfa8ca5d8d70457bef6d5b71e68fc9e2efbf9dc37ab61ad9e797a43f66b27b04c13c034fa6f594264c9d7da884c86fb159d775f785da197ff16e8bc992c9b2e1de851304dadf9bd811ea89d2a69b66d34e59bc93f5c7bde35e40a976a3195541ef2fa7edfb7f9d647616c3e399b6c9251fff047ff5af7c34e7eff1213ab5f8bfdb9093f5845f66da1b456f5649b895bb042e42fc5c700cfac4c2a44cf1f96d57b8ba1fffc9332a612e8bb9043559b5567090873d3f9450f37670b473a9709efce1e7e892e43c9ff6efa594601a27a98ed8e7de9ffc625b98e0fa8f2d5a311a87a6c23b4dfdf44d761e373e64a4a18a833d654a947bdda969432a0f30870e3a919971cc4c8a469e6901b45c26cf8eb615e600644660796935e65a480d496bd3f2053ded5c97d8fdeccbfe949d1339947c6baabcc67eca0e659e3fdfa5dea3da1a4adc3beb323bc4cabb6065e9d32ccca3dd3c8689c9a3591dbcb30b99b3f55cf2ac8258c5b85c696a372c7aab6bddd62aba078d4466fa4c23bfca0e09b7d47c4644898aacf6899c79b5332ee0f11dcd40253e40c5920db980a58cd1b55c506a6662bf1f53ff27e4139fd2736e39417d4f63f7d3414e4322b69b60c5dbbb4459c1d6a0f35d65da13f455598edf678505f54b527e3209565fc59efad5f8a05b9f6340fc38547e9147dd49017475a0aaefd2d47b3547ed715c455debb3a40a8a0e93f47b6b8ffc05b2e857b5d9cfd1e57ce09ece55b82db25293d1c59f37f7b6f9244f31fcaf5c75e6d0bd46d796a68991bc68cafb5b0b7c748ac7d39d8c4fd1b3b4de76c1941f3e511d9ba70956b9556f245ccd443db888d43a857e4e8dfe7e5713b5ae5a9fc3a331719cf27ef4bdce23ef320f8d695f9f07bfe8ad3f317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d89db0fa67cbcf36c0373cd56c268e0c243132db5de7365310f573225eb80bc98a2bb76f9e8c6170bec90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834bcdf2bddde91c3fe4e7aab462f49d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c868f3928877955cf8d15fa2c116bdc325b688df6d1ccb3386cac9bd5ce0c3ac381e056f916dc89e25a910c78e677964d153b74554c8f38939f98e54409fdb701e989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c65ddcb1bbcffd37d7bf1fc31acc9b5c94b806c7edafbbeeabad87f0ce419ddf978fceb973336d27b69af2fa85f6c33b7387dc0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a45f8de99cbd7a875bb6bf99c8a6dff4e6104a59aa9e958e48f8d3c75eb5a9a7e81d7738374692033c4c78f54d527d204f83a9b95f0016466fe9e89efbacaa23ab8fa6faf7d66aec3ef7e468b9c3277e1673839551f62a9c823efc5c946dab44b5b2068d61f00e7b0d87ca67706343927bfe4c12d20d69c4a5ba892f97eeeab7b5a45742cc4ac4d37219ad72ac312051d31b8385ca2293415a13bb8983b8457b8af9dcca9e6322094ca68399ab77dbb9f6aa7ced5f224641c3fa07507da9a08e0d180d52585dfb3b2fc95cdc733a573a888d403cbbb71c120baae2a195278370bf33299b9b2684accc5288a3cba1277fd3999839a6ed29bb91d71a528bb2e4f953778ba23341cba4b9b3c17f9a8366212af3b722397419e24874b163470b3b2b7f24ae62258983b6161c6773b5ac90969c03d01cf4669b9d1f46e05705d4f676d464264d7549e1e2c3290c9b2bf5a71132057531714bedbc7a91bc0ad56254d298908d33d588951333b3cb7924abf14b0d70652c45aa62cc3062d851e45c866c6200df4e74a9e559b9e6ab738f2b0da9693ccec3d968a866f0220ca95b7c6e8b04ec41d39c17eafab77444aad4ca3a9d6b5b5d4611a6c074fdfb01f7df68ad2440efc5588f3b4a5c4106efa3b9b6bb35c327465c7b656d1c1c6409993fd91cc20172e53190dad63ce02691ac326904cbb6424c906bd091312c1bfe6969ba6aabef954b5c8d439da5064a248c92988961fd2254479946dec829c76cba61690e3c541648228b59805d7fb2adb6aaba70718985279452a2fb1414e4704ac3dc84d3eb767101c8f4feb24bc8148316609bf963afa826a9b87638424052067ce8fb393d9ac579ab1080d1c549fd5103312a1ff9988dfe7805ed906fe9228e25942d49484a4510e0ff9a4a54a22cba6be945126ebe461c5940a74e1517c60603b2651e8371973da7051eb7197713f5583ba51b92a9eb3179b45a8a8a5099b40c29f59146f25a563291364f236038c79b784bf09524fc6810f91b777bae252e5b723e8059c06157653e335549784a15553ff9a7a29407d87725aa6b7a2a2669cc776bb810672967cb5b8b9a9ba751a9e69a8ddf796b1f324348712ff0c23f49a1debf210c027995b8a7cc5b288c4c74218e5086112237128cc57f4bfeddc21ed23bad00c58d835b5a3f0c8fdf1001e0ab26c2cad47d5caf2252cafd3520e36ae21119e56fb456f277132059ca18623bfd994878c794545ba4a04436d804231f430b12808fb01647fa15d94b975bb6798ab7c3f6355b9bd50bc1ca00ee76342c8609be0bc893deb398b65a453ba08bef83b805b61945229d98422f59c27e86022da5620d737867828540c20b097076bc6c03e5435aee1b9af19958a7dfb921da414280429da389eefe23fc9578b714b4f2e5b19b792903ff45aca045bec0b3d83c204747a2e24971b440c10119941d9316f45a87c4ab2ac0f7c4bde9bc8ef73a7f42513be3420c56720ddb984cb173587462aed9996d2a848d11344eac02351e6c5a18cc7ae813bfdc50d5b143f4d07ac72a213a0577f9802043a585d95031d017b319358a24b06b7c2ea19f22b6634146cc0a123a8051c51e6ad6a956b1a935ffe00bc65c44a60534d1375570bc036edfbce66255f523bb377b2256c29b870da2c870868299828f6fbbd8e0a109386b8d743a6e7a38384d5933e64565a037b9f520ecf8466f2073eeaf03d1b606f947ca2d2ca49e4b41de9011ffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdd1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +ciphertext = f10dab8353de2ee40f5596160fb8f0be1722abb0207aafc3c475de6199bf2da4bcaf41599880c5c55d27ba1d6de27644a8b42748885222a8f6eed81503421dca84978fdd41f0380fc9b43c1aaa4e4a3437f3776d0f06a88eabf23723970ba13f127ec73d37ecff2593627bbb505362b29d8b6c6dc10474b373a7f5ba819bda564e0d7e24c298a557163309ddc91034eebc1a1bc4efa22909819f7f47a42f2deaa4025d5296288bef197c7fc71b4bd2a769a7bf73883e7d0fec631777d560b74a384a518abd2f660be886618c9c2ff82cf557f2c3ccad1dc29b444fdb5e0c6f82f111c338d9ed7b9a6ad148290786644b9107b2ccf3e78b57807e3b77f2b29bc58a3abca9505d3760b71091d0f6d9cf93a0f5932a194a25d3b87c5aafd8b7679eb75187b62f85fe5f6b12480f34d91b33aaa3c4e279a7b6dc837f203106248a49b9202e0676a6e697168b357a07ff4233dfaa42a2fc255220c33514d65ff3f7f8a41a9982f911b918e720f756b0558e996266b26c4dd7a95e3a7ed8b15a07b2b560276f06eff062be366108b7d6be96fdb25cb210fc1defff0d89f19797d4be632b04047f29f2d6a8485afd5303b1430e3cbe052ce2fab2b575fd07188832661059284c6bbd2862b9b707c954ddb05e7cdc447a7f0e102e348f2cb7a6ff9140b80cbafc20eee2282ce3188549f1f00a1a1a45c26d0de74dd818cedade0a1ab1543c50a05baaa07cf5544a338e7e1f9204b8d883d9c14a6ff983c3012b65b781d9bcf0377c9d8ec7167adda2b2582fc0ad2ae9b96b6a92e393023e785018a4317e69d852bee8566efada3e6de2a290949724dc0fa39067e035b3727040b2bb96be824688e4ad0b8f929987af4927fbb9ba08f49dbab197cd320a276740f48657cba5a295db5b599a3a15e00ea17eb9db3d91929029895912e11c5e0d8550343c4b9f414fe0d4517f3578ebe5d76c78ebfab79c1fc6b528f693a3d58fc2b735498d68f137530e5b992216ba093257425c51027d18acff20f980254beecbbde3c87ba75cb4b3718981bdf0b4bbe00eb30aadc8193a7200a5ef9a3f1361e724dae88fa0e9e329c5fddf8e1da9f77d39b512c263380891d57a14003ab607f44ece6794a1ad41d0aae15aa7367e0a74d04f0138124d583bcc76c9f79334ecd7d8db31e70de23c29276fded2afc2495ae70baaf0ce1c28f249e3d21ab72129093b53ab25ab2f6e66e022dc23c5649b210b208dad52bae848f0522f336f1cc732f9b0d157a7d8059cc851853b7fbc5865d6b79863358284f6493254df3fc3076b443e0539ca8ea7d92f2f738a8b58176829b7c2462a9b43171d4c6a857f4a51f1fabd691e50b350a13e6a2042e7f52ea47d810b77ba11cd0facc56a47b03d0f829edb9e13e355ecb8583b12c935a177191828317856307537b5d4457ec2eb19bef36c67499cdc0d0d5a04b7e80da3c0f82f838154f15106515e5bbfaa6d38a9ca997a54990f1f68cdca6d9512edb6eeb5bd67d733286c9a14680f094c4ab6cce15b6cc603 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 259336182d6ae98ec4de39eb4f269f2f5e8980ff9d3c78d3e1a4c58e63d51e879f1af333393c75b366cfe2e84cf9cc930d29f8298897480571d715d7527debc119b10724e2efe8873ae3f5bd0d420d13a752d33087bb6f8856f8def98f50efed021e321a2d3f944e9875d9ecd33c7976b7a4606edf70f6d02957ac49b862cd35640ce84e6b989201a74eb774f2f88b31c94acfa91e605b3f634199be1639a50c7d9e89683c5dbdc975e6f7b87ff3ea48a2352c8bcc254abd6d812a6a5ab7747ca92d73d1e3eff07d8866a9801bdd67a6eadd848c40996ec350db559a0ab1d91c9be1ce49d7cf41a13849d9fbfda4b9b9b30b348217491449a43ea4544467824ff954c4869c8ecdb2ba2744c8d38ba584cb78ea6f6188bcd1adf67ba46883fe6964bad03e2c601064e5f937cf13b9cd00456d3545bc5e48b6dd06eb14eccbac23bb1d17ebb14361b4c9acb7b48805b7890c3676b66df3849eb38836dcb1ef56807f5b048fc7174440d82ba8a7eff6d325cdd2cf6abe6edabb195b74efd3f9db7db44abba87581a3c57f079b44a9455e40ae6ec88adcc14368569b35527f72220ba7760a8a0508bf0043d31e4f763fe89b611366b8b93d2e5f3d5c97fbb99bbb09a5e5a6aeef128f404b7b4cceb9e462c6a5acce6c64f55ab38a763a03ba49fdf68819b6df8ba88704ab4c7bcd8f9ae50ca434ab0632add5f2a4acde45997375d699024e6792f845fcccea18789b2297d401d6872374b15c95eaba4c3cf5a8930d34c74fd444a2c87f90d9353cd77362ef6c99d8d27c5d504bc5b3f2ccf7f39788231e3e13e7ee19e3915a9a4f0646aef6e5e3e155b41237b2ab08bdf393f2bf5cd0707cdf22854d080bb8ecf58cc9b75d1abde8551fa74b3c7d62ad4dd8dbd7bb47e56c56f21b7e83beb9321c58a924048ab96d32f558e5da1bb33ad431249ec1a6778d917db1a464faae33eaac97bb5e2aecf42792caafe314cd7aba3a8c15db5d1bf4e7c3888a2e19f1a7bae926044ab865935a2738b4378484b44471eaf50f4e925e976beeca9f94de91b0c85b487badfcec4be7c7683d5d8413ed96ae888bafb97cebe3f66ef7397004cc5684ef53683034fc31616ffe6bdabad29dc5203e926aa94b2f2a4506d697066f3e3057e76b56e69ab8a715b84848bb4fb993dbe744cad769edd9eef8c1b4df8a6bf829b9f177d73cb103eac0f45557a69ad89dc87a6b8314f6e8454d81c32ec07c4ba5c1c450b818ddb278770a1ce10dc386fb94e1d4b983503964f7b6afa10ac5154ccea9f6f22b4a70e5175f126bda841ed4754eef8ef84fdf3aab6e5d8b313a93c29675acfefcdf5dbd4b5b7e13d7f28d9ac9df569cc1bbc995eaacbd2f90b0293a2bba70ae8757c5a7ce84386094fdfb330e573c56bcc368a7de4d4371453c398f3ba485fedb663e5fb99c5f9eca9ba94caebc9d60a6318c06f268a86c0d4e9cad1bc4ff5e4a745bb2c827d1b89ba371dcef10c5dd95086d997783841d8dfed849a1f74696464aa1d67f804dbbc6acefd907696e7ff7d02d750d68a3d36c600448c91b5f3a16e5c84c4d819bcbfbfacbfcb03b6590dd65705ed75205fcfc9bba4a3a8d09d5835b1540f5dc673d07e640f560e71b4ff986bee57636f904c856ac93e0c18775864b7b932af200251b0328f5b3caa38116c5a187305622b4a152ca337ed7a3690c31161862447b847f5639c5851133f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c9582407a0e59a866991564ca55b21a48ee530676a435d26b749c1264f9e58c3fc619d1a23ef5f6300e96665eab70e7350852115f5859bbf1a8308977648ae5cf5a55c9fb42801aca4f0592254461a632a94a9c3a7ccd05c8b7c3b09666be54f072cdc58d8cba687d609d1f021115085c340153ce63a37750acbda01a6944a46cd16cad098464a109bbb611a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534eb80a620c308dd779b074c11f31679ae98ae569bbe79cb04bb127208e24ba008bea28c5db5ec18f31c50712171e27042651701c3004e057a6865d54763843d27873220c174c57154c9a9705da162e8685a035b34e15c411fd1b7220c57265c2ba7579f4bd9ab1461650e8027c0ba79f2ba3f14093cab6015d8cc092905a6b8f09dbfd5743818489ada2bedf88ce592396074a79824457f7caefe334fc84869ff43641821ad60e80407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac382222c193bddb31275b84374cb4679a5ffd803eff07987ed085fbd43e45752dd9a32f5ec03e7b74567ed9674e1070b026801e99ca27ebc0ed24742530507e19b97a09877a1b511da3b9835268ac35ae44187ea14b996dd96c35686eb98a81f1b2ad90a80d0c989b12813e7df2b34573b876289e7c79481c7247e637a60f9b2d3fc129c379a759756408636048565cbeb24c2186a875606a43d20bddd8b9d70781b1848be54a075fe978a3e112a567223d21beb3395921d1a100c578e7ea0455949b7b420b6494688aeac00697ae1914084eab375d86243b50a948874dc973b7670c8f9173228b64647e58761442a2cc90165b188b58025f8eba65cc654575a1bb3823a1a29633aaea1763f24486aacafd611c28774c98d89b3ce8a696e29f62775b5d5c50847c3ad4bb968c441086aa070097508da888b5b202e5a3b5db579943f0861a5b6e2d58415019182262c444fabb77679e019cced4e0a3854507fcd0935bf81b0e8500dc6c0b3c154ecba94d166407c5dcc67bfa6aea8b4ef0c53859ba4416d5c1975c1feb6bcad8076e6b020a62b077f0141deb5ab5986b386d51cb7e8c779654af5e5485a969467012c572f62daf788d1f58bf9ddb4bc6e04b00218cb671ce8b2515b072b76cf253a4006ac5437c107a077f162a3984586978ceb3752b1fa1a2b525961f96c63d7207ecc4c0268a354afb00231b1cb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a53730405c92130f756050771999e469cf07cc8c308ece9b827d7558bf882630556150a602d9400e3d4abb229a9d8b8132a7f0c0c5475bb852000b63228c490472b42488aac0ed647b1e834f248534fe2195adf6952b83b6705593a1e53f0315613d2596aad44e27a26d632b9c71e9c9e5a6ab733c7e81e54db3437d894a19b4710a3cd5075602b176ec369f5116638775574c74425789154b0bde48bad6e52c91c451c87b48ec406674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d2191b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c50950a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +ciphertext = d876fc40a1ee787db486792f9ed3a749a6e996dc5e20935d6b76c8cf2d6ee6cf6c9c05fa7d6a37314a06dc4042088cdb68599f8d27958ede9a31054cc6abf51dbf7cc76e7d6b20408447469d5860fa09448f2e54efdccc8d0255cd6d7b759b7e665f0641df729b4468789cf480c9a606c8d1860245f0995e972b02dddb7606b85e3efc19a93063d095ff068112c6bc4d2b3edaf8205b76b8fca8e956e3984f945b06527a49121a6f1754236e70aeabc770049bcc240d47e003f47bce03c988e8c1731e85f307d0dd74b8bbaffc511e74d04db81f04b0e0317d57c25d5a11b9128280a131ee849efe204836ab46820ba4e03710c67e79e0466a506c8eec2834f465c97e0118f138e8fb7d6aaf1c933ad13e3cffd84b6b2db732048b5720c108a6c1f3d576b57a7726cad853c31e4af74ac59e7620f87e85dc2035887cbc88080c28e49d986c21a9216ffad3b95b3391a52914ebd10f0202fe4d5c5fa11af3cac6e4a7358888ed83cd8567eaa4fabb73fd6a675ee4490722cd3ccf4fc3efed41ec07a5409b24864004e1ec0dcdf7bc630d537a9e303334e3353994d14c225d59f4cd88466185f8e0c01724ee0db468c2ff12aed38eb4a14ac13a50c7396fe0622704a45ccfa27053a15ff14046ebffdcc8b8fcbf1b347f3430db409c4b7b30bf138d712ca9177debaac6a3138e6651092473d86223943e889bf89a498fb0c0c662973408e9398229c76bdd59b5f626a2d06f80dee6db7457b917cd1f2a333f3853d1355a214509cd14db558afd1fd061d10113465d1682bb40044879b8b64910d19fe8c45d27caa82fd7d1370f7205669e1c62e03772d2a0fd8844fbf6a0d09ccdf877429d59a84efff509731d38bb7f0c17b90eb54b2bef365a4f014e6ca6f6f90b3e8adf99cb3587d7ef7892b488119cad921f0607dc6fb7a72aa5f33e93b6b53ecf3eeb3bd735056f8ba8a003dbd99a3563e85a2dddb27fd544a798c8bfc220654c9e3892a0c2fd9664f33243f9bd3660897bc41ffc7c862a139d1178bfc94cf067bd979ab0c66e984bfeda086c3280c9ce101798cfb73eed86cae129d36d72f79a8ce1114a3e74537e990c53a5b30b3334b1be3d2646daa719dbb216df3536bbe800db830de08769f04a6b874c109f7419febeb34e1e30445427ec154f2fef4a288b070996985e255a362224aa33fa5020d7b0b086e76600319f79ddd8984fc3aacd54b2a47e3bf115c7d297ed410649ad557e87f880c49cce91403fe5ecba4904b6dafd2c273d847e440d2b34270a3dca4ab85a1efe5318f3a124058399c4e6f607002314534fd603b4e71819396b5c168e52e3b47d347bb2dfb1c0f2f7c2e1bb0dd86de2dfb4d680d16cf0987d644bb4a38ab0b14309708bab82903f942267de8f6585d82db7af561ece89d635bd61dd9cdae73afdb29b6b7bf118294450696aa15601c2882c9a2d406e1e9ac78a46006bc62e565fda3b5608dea7f528b06b2826dcb07a1ed7893a5767891b6f740b1c88cebb26cc970f28059786cf6648 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 719950ed1960ff7cfd7d59bbecb83aaceeccb569b76cd9b053389c552cb6bf847cf40cf019ad3e670dfddb284c15d656151644f78caeeafa8b12cb7c626f56c13fce621f735a84f85d66a90f3a745ed8733c195f6b1b9b272897521ad2fafcb958a9669a9db7352dbcce373acf6aec86a555c3c48f78166c0fcbd23c496086aff6116d884c4d8c9febef4c0f3506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa33cd1ab64a6ab7491d513d3b4e8a134086111eff0462395b9d89d976ef05aea9e1b88bc80c4c8bac44af5fe886ea788a1bf59dda7811615e059853d2ddd73ed8cadad9ab0507e75d57c3224e953509588e788713d5a6715ddaa48e972f4fa55f16579d9bc6988f562cd0ef96e87aa7869f9c08f66d7e340023cd221736c3cb372b867f3042382092545a55d32ec7f7bdc85d449c786145acf42b85d4618b0d70ddad12f4a8176f0f1db67f5a7e3091bd849559a51b958963fce2ecf5df9fd9aebda932073a2ad3ee5b12c5f94c647513fdd645b34c14ac1b32d8565377d624f6d7f3af5cbd969a37d5ea43db676ea6eefcbbc6ce4ddaacd716d147b398b7d469a919d83baacca80f0f4e41448f805bda32146fe14e766db2450f599963dcf899f1d48d839754858910e1fc23fa9e58a9a314946f690a9c5550e33e60fe8a7b66b0e6f7321d8e0f8de639cca948e7d8616047f85ba41cef9f11d07f831bcd987dec3149854b71683faf68179799b13cd31a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c04835958eca7a45cbaecbcf354d7d8e37873308e3926599df6ce56a94945fc7911ebf6bef27d7457da7bd6b60f87ecc3f396e857e95ce26444b74ef91b468fa1670d018494257f667aa76e42976fac48e78da72ef1cf07fc740109f699b46345e4c9972a35daeb3eadbe87980438de50fe2b005c8dcfcea6eecb56d99e67709d16c49385e8ab20a19b74325a9aa5d83bd8ee53758ddb317e9815352617bfc582e979be4f680be34188a75b9cb303215a76a246d8f69acbd173d06abfb99c7f7829aa546aad213ddd6a88aa4a6c6e4674674fa75500baf94712ce78b84eb0285f80beaf7813647a5dcac3a258991db4bf436c23f37c6981e5144af755fece99f03fc1a2d9d7f09d5feaabff7383885cebae4cdcc21ede9066653b9acecafe366567c9238785b0f0b4d153fa9e02ca2d9a3b37d84646b157684d7ac7217f7af4533749a9ff99bad8f3877dbe5cff9c75b38d4d02178ce30773ee37ae4f1497ab386cb375fdf04d85c841fce25b357d41d82279f5f6b85c7a47f906408eba66336164cd0506bbfc92d30f4f33a5be7330926bb3f849d1ddbd9f5cb814ba8a7235d6d0a037e6fbf6216aa3c4d5cd5d5cbcf0358501936ad2beb3563c341e33e5de6d68404acab0149bafa84491ab67a2de8f9733fdb0d05f9da7c4d441c8cda05d9d0afc0224932e7f5f1567faa433c92131ff899e43a93cc7c8f4aac6ed5acbe0e62e4da4b897b7bdce7fa0b3af35406eb6d3ee08adeee4777e5f3369859d3d21584b6593b5784344d53c4dda17f5a918d4c46edff6eb767017e660478c5338eb5e39dbfc77ac4670fb531be300628a7a50fdde227688518c8d8dbab01f270c3131ac1586bb783b35db82f3c24ae2b767e2c4a7d15c2a86eb19fdfc41113a7501367cd70d73d0f63705487ac4e0bb1c84001fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b52f1cac91b6c36f37a59780e454c50c5dc354b56a43040804de2394bea14c2d385e082c5f181228d62307f5a6a1aaa1eabb84f90f34310844df95a4e6d423d8c993fa7f390e6984e482024c2968254b54b7d3418d6f859e295665262246e1bc8cd6c9b726581cee69140f85c02024c5b59aa0711813d66433aa384b2a4a3447939378a1e6a98936bf04ad075981d93c53e9635b5e285f96755f8689b5ce5429142af6fa02edeb1a719b272f6b0a6211a5b9807ce6ff368739b51d4d9480bd884c8b456569027b08a3cb928645d450c6264c5fce2a2de2b241f965034a08716649a3c71020a6986fbc8bfb5b4a2cb162749264cc1e44bd66223f3db1b9bd2c68744b52ed7bba0b9773df128883110d2cc4757dacaf7f4c90fe02884e1a581d89af687ac79444c9d801d156325590a3a24441b7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d222a5d36b86ea2aa2006c54940a5f843ab708d19d5937643309c12d522dd479c3b2d57dd5696d25615abbb573fdb62eee5c6a6546cb1fb188f356800ff4177c69b636cbbf9ee9a7c7d512ca156490c96b347a5bc2cb257a061452dab5fd15bdf5026677f14967b6c825d03eb782cd0422bd1078b7781624dc318a33b0c437d6c35997a22e30496e876762ba5dcf5146c5188dde6c684c265a8f05031904572f7554123832c78767ff4b5ff525680c773ab3ba1a93776897d57b0d507b9391712344326f090b3d964df8c293b6638fa36815c7cb9b7962956f903f62c4ce3d7646ebc1a8ec04a815191cb4bb085ec8693f2188f490731c087c23a8bc7cfb32fc019d106934b2d17706526cc6f787be424bce5b26329591c47402d57548110ccb42955c422323addb4987fb0f3441558964bf14021a54277ba14c5773a10b81c1427f51173f5c6cbe1b7575a4b6766ac355bc443e479a2953a51f7010f7b04b23e0ca93d08836432e3ae5a1a6bb62f5476c07914f88532cecd00ceb340588ab675f93c286e7288da1c6ca3621ad6a4ae1fc64aa15b27a7c3eabc120e7460737585b5773ab18e23ee185c900ecc3b765983cb807e2f7047e6c999c6716e26801ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d172db81947643a84fd2173fcb0477ab87b57b55899a308d51311c9ba6916f15947d707d88b9228d0488ddaccb25455cf782b7a18264e55c9b6798f39a53f53240c82fbaf461364cd5202c5c94cdff23e0f731624e69310e5b47964b2bfd3a59a5b0d55a026e260731de346f74938abc607b4f579b8b200ecebb633614a46983e60e442a4914c93fa62219025e4a99d71032f0b00906126365c467e0a235570a544a7640f23800cd5f2a825479a632343f20801f1774f0e8b7db96a860fd40a43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444bfe219452c464eeb2914ec19031152cacaa00dd541fde81ecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +ciphertext = 101139d23556eb185fc84b7a91052c0739f48c9850ba8f6886b5c2d4c064d37c525638d8a434f902c4f80b1bd8f87a573f7426b109a3bdf6a1d6ed315e459c73ffc28039085eb8f426868a7b45921e05ee78eff266226b92296339fa679def4d89a2f1d53e3d8d868fedade22da561fcb57297da23688c1617e422ac3a855cdfa30d7454920b68ad591dcaf0a45cf95026841072f304c03054c5322684a8e4b6ef489b39ca40df1d7fdf47b73c4e1d82a538752f59521060e47494b372c8d3b5406fd6e5e39987cdfa03bbcc2f6f6a7cf3d77f1f775c22cd11b4a74b8fab4fefd93a9bcf5bad44993057fc2b8f35d9898acb25ac1574462621c29b74ba64f58336e817d5ad2c9df18f754bdbca516a0b41624ffa2f9a8d67f8ab013cd0a9010c21296649bbd159f3ef908fa368e212232948181b0b8679f658ea55064b59a354db13d44e2d9ffa372492250a8dfb8f1adb1e7593c3d7c3a54c6360488e82ad056071d0562cbcd6fcc82015a9e45109b7d49beec8fa187d4a2a41f1ab0928b0c2bfb20b92048ab9210f0a27f258e90e31b2021a1a94fd0f32dc8911b2ae5363f93e3d70a0e3ed6cee2649e6c4284133c9412aedf464fd83c291c477099cb8e1d7ba347c53a99c7f455872a51204f4c30ae0c41080287a5b247619e2713b79e506e564c3ddb3baf52f15b82733a7b367eb808db1f19f079e9374bc06a0bc6d059458e539cd3ace055e3895e8246a9e888226f05a9022ffadff3ab60bd6a4cae8700429162004532f1bd30843a1cb6b72467522c8e41908ec9c1573551e0b2485c287f48aff967c7a0586986f07c1bce12099d5011a7808b629eae7f3c2e8bd5e79235f958fdfb1377ddd4850894dbd1d78ee375ea3f2165b5acc7f02bc1bb54e7ac58a077c513f0cf17daab0c7934b1a9c3ef073e8543deddd3bca0c13926ebd64823d0ef62b15c26532784b323a67c37e90087a1086955087b1a1a9cc8ec9788609bf404fb2553d7a233691501b37a311968392df5704b8513090bc416d39b5d3ea4a7b21eca56c8b5eceb1ffb124dfdfcb36cb0b84a49808c6105087caa8de272af17df3d99f90e482a704bf135fbcb27c068be5b16d6ae7579c0a046a3c6825df0facc8b9402fa5cfc492c2272f7b325b6b71298c471518de97bed53084c8f559c8435a6b1e9a69a70382f4c35f6bef440a5745dcc98623c9bfe3cedc55be17bb22ee5de49d7b9fe8341137f0ac2907f897a639d816a096911c8c4b84119ae14d459f3377bc7ea7224fb1fb218052f9b03f29cac0aa72daee1170ba56939de8d02d24bd4d26c5814052a125256b083e9e59cf2c7252f6ad6d75eaba807cf4620d4145103f105a6c07f3aad6c4d9ccd783c1ceeec399349d877a82a8d25e56fdf771a56162f5d46ec068e2b7ce7ee89e8565fb95fe3599d8129e3b0737be46484dca61940e9f5f438c1be101ef4aabcc5c23f41121936d0d54af535e53f8880c2a99a70d9a41ac69e137ee32f2eefe7d4aca9c3fb747c3b21f6e7c9eb26214e0 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 4ebdf6f053c3ec27e2c8ff94dc99ee26196895aeb620f97429574edee9568f1e3feb564d8aae883d6ad32a9f9ca57ac0029f5c8e6e679194fdcd39e627e6ec7c2c3f842b547f074f47fd82a06bb42833f3a39ec3cc07904089e25cd5a854168d83ba8ab7be60b6ee881d25403b297c73048e32a8f8805e529a8ba2deda6b4d7665a383e71b03b1c0baab658fc50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2bcdcc80c9d248b97ddd5ed01bedca43f4fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48fab5e4319b8f9a0491fa3efda443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995fffaff817907de5c66899824889a760ca4a38a57b3afa880a45f4e138b37487b2ee7332d2689f99a5a3759df0fbca43ee6d45a5aba65f6c67783cb74d2e7ba987ad381938b4a651b79d8fa5fe8e6d073a6aafe60438ba3c9547e4557e1f7f41934e4c912648d269d7bd9bd69c8454666e696926ec4849f7f5e6e0c815638e34f323465839d36a8149bad494b71f1336a4fda954369d4265b6cab935f06694c58fb500cb77bc3fc4d805a295a692648a31612bf06d06c2e86c61675577053a747bd3a748f452b59dd28edcbeca9ae0eb843ea8b7ee21e9b822e8d860764d8c5a77f01ff2f90d4c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe69d27fc4f4e6c580cc3b41c14e984ea552bdd6396e5f867887430a2534a44ba545adb286cd61d7d6618c76945a5c3b29bbbb09b7f4b1ac53e5954f677d8c8c1bfd7da57c62fc8b80e73d737741f924ef7164b4ebcd8822a4c340b5b74cb5c2d407b9d63365c56ce4c5e6ab43a8bc699d8c34074a9bf4816f1ddddb464656c379fde8f9b6a6ec22e5345684f43ca647063efd52f6e6664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1b08f8bb36f63a8a898bf3b7b0fdd7988f8fdbe4cd405d46b1cdc37600570fc37ad9c2f37e313fbab2adae52db6f11ea653987305aacc8876ac4e0e4b7f6e9227b8b35caf616c9575506870fbdf585549a2fa0fb185d7a61139c028aefee3bddee56d328b16ccefbf5914aad88108e62d563bc0243303df9fb98cc57a45369517640cfdbf63a555aa1df69878c4ba567f8d376176d6941d34957e1373b86fd483394c3616d89d14aee19e705a2f7bd848bb23ed88de04ea4bfcb36eaa81d4da713e37be79f5ff51cafc33fd5d074d5947838625e49f5f6bcda5e683d014a12fdcdc827deb5208dd39b6659606a8feb8fc63ed61a939cb455e869a3fd83268561e16381c0f615227d105feef31bf39a04d97ba4d78adc66f23f85ba675ee871f37700bcb1af9fe2bc652ccfe9bc0fca0d7f7577c9c96dbc9b8b07b917f258c1576eda186f1dc1f87ebaa7714a54052fa660f034f237e98ea14c2467b46cf9877f5edc29a6f992b66da7db93c8fce3343f734d86bc548246a57473d1285463d0942f298f45d933ddab7a09766a9f9ce78ef539f9ce9a0e97364cbcd366b6bd8b5ceb082fded199cfaa5288617b5d019eb3a40b3d0af538119d733f2544d18c9d94f387a3f5ce7bb0de624fe455e55633267468551b3ee117792c80c1a802230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab5f11602e977ed051115508668c244a44e09569a13507d4009ab72b16cc3bc615c12ada7c56d50ba6307d00801bedf8526f0a9366869a4830314d162f63ab8f51996663c1138641275e164ddf60c7708a75376bc235e16d5c22033de1a149153d1868679e1825f638967becab5b9644a6e201906771a703b7844cb5cab61748d202d38b5b8f03cc45626027895e23d0c1c1b526c6d519620436ed593b58732164a39639c813f6032eb902b05db15c5d8825c8b11815768d29522536698a751bc1f9964dc579358adc57eb83a0d2201b9b9354b1b39c6e7008d5f3189902964973af9a9c694eec1298d68d3372783d34700b0280d692998b49a9bb76293d7a95363b317670352a71822f415b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b3905df7f58c6566621eeb25dda29d97b598970684c5780f665243feb854f9f566177200f9331ce353cd1a23cce8aa4529bb667d1b9e59b1a312a7c6ff08871cd95c6934419f475c1c08395ce1a3aff83dd14784303b4ba7751054aa59f5710e4ac6039f3168c1b601a5278562b525abb11e66193dc9d34446bbcc8163578cb8065f89b9f43407f79246cad2b6b8b40f16b839a060a95b76855237bab2fa315db48e40842f8306125fb04145356bc50b00e3389dcca26ff048af5a730ac573b5b80331d2597c4188227682075bc0000186b8fd26a383e1bce5c19f13b18cb21602f2160dab202bb07b63d925b71708095daa662cf25dcbecc99395400a79842f5c40e79b46b5384ce730439f537bbc8a8608f61520e120ea9843456118a0a4cf36384832b12076044c65f06c8f8cc31752469c8a1e33dc529ac05485548a6e075f46a089aa8446c0d465bd43cdf0343acc9668fba2a7f7191a9d29be7e9300cef33d13a11edb2b409de297f30b8a7b077fd4ca4d1ac74b31092aded0503ccb5818d1834a734e15b74d3fe550ee49773a800d86f129b4e0250ea1c43da3a3b802b0757c6401ea090f98a28291621341a9d98c67bb001e46e89973f40c1c4950b0e34f07772ba6379fb6a93ecb57369b48b3aca26ef815c615b4a97ac2190fd2b15e83aa10545fb859635d084a57b0268ff085d9ea4b7ee1763b914e67b33dc46037f39815a1f8c58663c88662b91bab0db6758288c682372a269c64cf3ab5c46de2c8f0f1b7780a068948b9480c6af10251453c1fe213855d74675cacc7b162917730ae74ec7a8e7673a7d0887edc175791309ab28e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a2a1c2456a108a5cb4de1b15356ca737369668b0b5c7bc10e22377d6b5fef7515b4f348015872e3518c2676079b8a06de8b53bd189ec9766c04c084e74c6e747c783ff3a99b930547a72fc3a179cbd62b52d46207e79e37d65c9f3c4839d1afc167ae4041671e2c1bf3324d875b78615067dfe11653e6bd4dd5414579ad8c942081db4f1a10b0e1054fa3d79af6a285f2107d4232700676b8a007057d15c923a7889f115762b4c242392ce7c4438c68c6c3fbcccae4a071e404c24274f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddbdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a75a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +ciphertext = 188663b7ec7e4a08f623c7e55c2148f8a6ff30aaadf2adca46e99287a7f8a6b37a1c6036653a321614ffad06f531cd01c62ae6e3491af8c06aa210c42fefe0edb96389306ad1baf1bd911c106ab8d32d681ed8238aec43591644a19b1f3689a1d9fe2a6798a4ebbb55316a2bd3725049621ff553a688e9fd101e4bb9d1c2cb6f1afcd2189990279af782458152379988be07135f061ff3d3af9796aaccaf78f01f4c9f0a89841885b8a015c6de80788fb3787ecb7ef2e36e9dd4b1d3c9df3d0ade0207cc37e23c8f758248a030d7d2d7c43c00c06711d00de431e53405dcccfbe3b21730c453a74365e7d1fbfff706a2c12b060b5ae1dfe6cb211a42a2f0fad86c6b0b2c70667bee5454434093afab1f37f955b895359749c4e61264e0b18a630857c7c3a98e159199e9fb1fa0fd6f07e2c696ede68333465226933c566da073297623168adbbf6d5ad7e9e22bc55d5c2aae513016344a7f2a5ef80d247ff1c71b983ec3fc88b4e2765c0b26a6614292763c14b8612b63ed0bdd43f78b5344f10a28c5df0b635b2f44f9d5c6496a801f7cfa5db18b2018eee66a664c0bac6bcf39f82e00e57a6eeb57a8097af864ef693b871b5857a42e0a99eba019a8ea639895e1a6373a3035bd3148a7b267b5e0e3ac6709a4cfee2085413dfa55000e09b4ec889f2f5456d4b5b9f42d23695e925643f9ec9b2618e09283c99b966f91284e176edc41265d3bb436a6771644460d97ee02afb7f1ae14d06bee9aee03a6279fcb36d069bda332d586851d9e32e9a58bc12104014cf7a167501b086e120a97498d0cf3f3177c2ff3b32a93916665137846bc21545930423e907329d8b57c2ae202f7a7c2cc9dce39a681e6108e233cd955914047a5e20552c9b3a482c8908f536feb396406001f9bb8e24807dc931798a6454fd6ae43600717ef03bef80e6fa53c2b9a74211dd82ce9aefe1e24f6a4f82b6d2b8d8ef6975c0433c14605357379276d58b8ec11d55b4e99cc2d3516198f4eef6901f70d6d74b96c289496adfb0109af4e3da8ba074f5dc936dc1268836a0bdc000ad8dba6bd9c6deca8487dba9324d07e66b07608dd4d884223460f0414228819c430ac30cba5825e889a07eeb75c8fcede709cb12dfe76381381ed76f89818c4d3e177eccedabf6a7ad44888e298b1eb51dc2f6a1d6bc5b0d71a9cc05796abb534330f1c9dcebd5a8144cc7471df50a684b424d8fe1db0f1351926f6c45c1fc120472f0a35a8332fed29b24c7534b90439629ff7ef469785d851703f070bce95d923a88bfd592cba6975619f07f9aa96733eaf9d3e44adfcee1a226bf5c6a006ea58753b9a1b0679a36e619bfce738b2125dbe1a517c6a4ca05417e267081c26653510a1bd1992468c59f6e56b857c8e95bc192f427c77a6bce7d4af50ae875e7b38aabc08aae9132188029576153204575e28035de11efe643e5a5195a49d50d590436912b25310bc4ac0d9e303d6e6c56583b9e11fcf15fc621e45fe7be1c118896918cb09d0a219e8d5c004 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 1f83902bbb77a98bd32287d79dddca71dd9d57385ce6ceb3c08b80ed95b2bbf7dc101cc1912b71b29b87dd18f54b593d616a31ff4957c8cdc32508f124f6a7b125b0ff799fff47afa6a9a7055382bdad8cbfba71ea1b530bda5a4548922d9dc6de99f7494370efa6c9689dd86bf585ae6534dc05344ece941ef793ebffe4312a371ecccea78dc1a166ba98fef806474826a9f2caae9cee4b8a669abd146491abf3ea57c7f4f4ae73750f69a343d9f75ec935ed9a5656f78a6e50addb8ba28ecf2513f5661fb0dd5588f447f781f35cfc13f8c0dac843aeb3f418b6e8c567f51d568f2c6be8eac9bab558dfbd8389cad8bbaa50e1ec5dce044efe58307444d2403ae67a9369e2df81d387e3eb6566637dd8414d9c4fb971c0fa7771ba53b7ce3ebffcbb85aab3316a3a99a9ced8bc4596a3fb3d15ffbb13a5cbfb762ad7a08ca4aaf33862b73f5badebde56d395e809ffbc7347e847956b57e695c978dc2431f07f86c1eda880f7871cbd51612d9901cdc403da599b988a8ffda716a9535c8ed02b3bcdadf6d053f5a8bc66419fd9d7f1ea718b7bad6bb76fd307e1e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edc5d0d884428cefc7cb6a6c86c8d7a605973aef3f70433d8a7a4aa768975aa6b0c49f4cc98f7cfc83ea475ef1090a68593dd68029e97f489316bff74b7e33423bf96893d271fc94b1c775c6bfee3b07bce543b3300db7250cabd1dd4a2529347848830c975261a547183f4533ebc0ed6f7f2064ba693a9bfaae6fce87a8d737d75aad6c00eaab71a5cc25034120445334a39d63baa2ac3f54d77a921209750f6869e6a7ed05eaee1cbf9cec9cb7b4a6f370e5c139ba472a85e14b28bbb8f7d69c5a8201b730db67ec1fedb10e1c42b4a97fb7f7ae5477dd12859d68199443157ddea85760445895f7e75ef8bb919c721304f8301c4f666eaf00beb03dfead066e3c52dc5ca71a74545abe78df395773d3bc9678272873dabf8f4a4aacfdb46940f59b0b8fa7574fa0cd794d64dd3d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c8bd5d08f93d4ef3fdfda93506c831455b649ffd17fd866c87683ac3d7c6fd9cf253ef509d777f35bd618776864ebae9fa5318e739692c5aa86648d49778b6708e447b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464dde801e0fab64bbba4fa3fc0003458ff7301138fbf444961c54c52764d8c4f79c3c553424aa4aa13a53d5abeb786cdffb686fda185d5438af5c494d98c8d381d8f1c493bc0e7797cd1995db78eecaee8859b9f29c497cc35eaf12d9cfebc6a19c599c9d364e587c7d32245145b6dceeb54cc7ec5b541b71dae959c90da747eaab53f8cd24365c91f53b7b0b9d373d361e4eade4d8fc86ed4d8caf43763b3f9dd65d61afef962337a45fe051d36889253a423939abfbdada6fce1e1a9931c960d9f4948723ca17a731adfb48356e569306f3481ff5cfa7b036b931a234d564cc35e59a7acae4870759e576dce410b3d4e0885534f577692c5a237344a5f674ec7c45bdb3f42e7db004d5ab620ca2b1bcda57cdcd5ba4f52abd54e0f840e4ce837f0d53539b4a420a3005a17c7b4a08178b83f8540601145b102970b3fc29f30a4ca1a8a5bc4164051931ed68a59efb2b50d549bdc1a65e9909f5aa690b0235d32b1c6b2886ce2959fa189e2ce24224e99255863e6d964d4f422c02646a461bb5abf86f4b4c0975765a5b0ca01081677334af26c3467da771cdf40ec4293608801cad9c61d5f80839774eaff772b139051beaa65632120f00171ad020276a1fbf23517582149ad2c73450b11315ca4b244e7218800350aeb5808da774030635bc247508144740634ac4a078a5af2816e9206a645287de06263277242dba12af2a82ce13ba6787c5ac3020e5d30cbb92452985ae41027056f492bb1a5e23332698240b5038302e552c5acc0443a8795804126e15369ae96cebd7c9765233982458ad6520550baad77bc74296badcd4cc37240d0163caf8c806a0ccc3f4125a0874cdc1c67e4626c9c753453fa37b208caf5f523388d6308248b7688c80f6c925895670a1397880933af0152da1e54f7a7b512aa87499f7a718e62a7cc5bf5687add09060426b0d3cd292ab9b8372083ee462182872815cd740fd69acdd24615110bb618ca1ef662715f028864ba0872b8c199abe40f35f91906a821b8ce0742f931c661c65aa2445371a300e68f23b767382f3701ce685cea5f59c50e82e45234169c3bbac814ab9d68f83842c513a8faf475590b3bac2e3a4685b8f71208357d221ae41310e8454d315670c3a3409a2a95258b9057b42def7a7c6f588f6da61183acfb18a7cedf138c7984b50a940f17c687e5a2f83451d94398f4c82c93a375be195b4b219232e9a766e77040d3b9125e70fa4097d807a6d25323342508f2490a59702575d64af146088f59802aa2cab3537a8b4e92a10ec447bd89f9fe738d92a5f83c2861628601e42bb427b87c2153d4bc44b19413b79baa5ef55325ba8a42e1a88548155d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526df1adbea64930b6995f60181544356c0982e957c5e5186f321b9467d05dd5970a96e226c89673e50a056e7c0a8027aca8a5cd93723353ca1991730dfea1aee943cb0d62537cb5ad88c14f52a78cb6228ef4750eb7db0aa831a4202b178ef47446a06a17e7caf5274f384b36832a07ae0a66069bc59fe439f7b6005f064d865b550505210768bd636c61f0e7a1bdcb3c3065908d51302ee234a3fa113a1a1a2a618750075a6ec277cbdac535fc1524a62e3c0601aad1c46026ab6b8495c1b7093f776f9e6b3b533267ab99801e83bd18570166387f14ecb4d279b86cfbbaf90649e5c514e432561f850497d47c2bda1bc2c398b306751991392c399df6f408ff836f989c41cf76234b9445d9f81f4aaa987c1721c0c726efe44c311a589abb5e0afbc4add9bff6f87597a52e16a53d6c3551b7e6be0a1958a89a739e0717f0a86be0385c5ca433b68ab9506ba3a6e00debeb1ad0519e228b5b2d9aa3c9b4a2bfc8b35bf0a04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996109113446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f1f30d0cd1c40d14b09429215e0c5325bb2b069b85c9e0bd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +ciphertext = cea8231a59705364e56bd14bdfd745a5edf808a710ed23de250ce3d4cd42c931ea20d4a888f594ef8909096758d207e22f7e6f1a0120d496fbbe491a9e7d02f4a332ca25322e7b3d8c5cce294b8858660574748a9eec1a832653b8586c29cff0c33424fb9dedace9204299642f9a34d7391e04be2d2b0b189291373f6238a5e47d959e8b6f1a7e965ecab91fcbf4b5fdd264dec224e291f3248c9bab12c2149139ce73d1409b21c91f02cc9ef9c41124c15796e1a04e7e57d727b9b3d54bd51af1abc79fb6316db1f23ca3e29fbc4812e828d2038408ff3e9164d503ddf3a31ba263cb38ec6b307f01291d680feb21730a7bf3adf21f7ea73e2cd21a2ccbe3b1808039c00d09f60a0e54775510e8121716d6c25ccfa1f0b402dd186a8f623d66f685913fc597d24f63afa8e5b88654019de57939ae9c169f201bc53eed1e5c9a6bf60d7a2ce5d0ff33cc6f9143619e13fcbad787bf3752f1563e9c3d201b8716eafa70b15a7adc241aaeab81e0ddc1945beba409b3bfaab9252e30cb26805e6b42946023c9664764192870cb05ea9bc0692c8ef1408db412117e2633c011ea6ab54ef7750670873284484c754a2d374a381e253d629b09c5402b12a73b90a1c70a4d18cbf3278457039601534745b5bc4a404f17184de598afdc6c38cee8d89af50473e3748ca229715d575ab7e31a05316c02df4d19a594056ca4c250402fff7367e5ce0bc30910982b098360e00a44652e4734e14f490532d5f6ef377d48d69da43d5bcbbdb679e8096298f2e9be4ad3a3dd322f9675f608930f7dc0d00bafd4d2253eedc5dbb1389200157d7b0fe5b49c5f2845884616045d2ca0d4daa45a967606c0e4319e21af8c4eae03c0473b8d902ce55cdfedcec31b3c4923ccb4563834d3683ee3750c39d1782e091862e08dc99e9aa709483e7e0337047cc9ccd4aa1d6ef65a4a4cd1817a85a5a7b0d59c9585073fa0fcde6eca76a83d1cf1f734096d767c9df176f0ebbee8dbb511db823a350c671739dd50913a4220a6d7d9f0d98ada716ac2775348d22f2864b2000adeaf081d730d02246d07f1f1b18d5a7578458387731150eebbe79126ad8a63a2562d4e937c39b9f99ad04df3abb938d29e5dbd29fa640fdd4007964c9e4c27a1b440597a3415c789fa6b241bc7d533518a60adda939f62872cc61ac2e09adb1d3c6004fbdca01498cb37538d5298cfea058853b7d55e0bc3d00bc4ecadebc7ca9492705d7c1db971a8fda2e10e40eaefda7d32338953f138f03fca15d2d0cbd1f89ed97723e8684eb6e4cfec9aa81182e90c695e0a747d2dad465d4dfb7fe28afcfee0a1240858fb6798651a326e0e81e09621da3a529405daceab67657fa4af019191f0ab9898a447eaf02d072adbb028221b509235aeddb4f0d82e84e777cc2ef6df4d3ca6b65b9f40e06db24b62260c44ffa7eadd11e1d05eeb0c5fd163f8595f15c2ab7d3a897341c7bd2c7ee9a0175c113eb454e49f7955a8c17a7a02236778ba7e366d3c1fb1bdd6d0e884959b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8b78635ac351c94bb6b2dfb861e4914dcba415f66ccc465b370578e136330a2c5cb0daf858eecb733a75e5cc4fcdf7a1269dd17f2cdff484401dbf3318a98000637b3d065608678103a4dd8ba75ccbe58207ce30ee6fbbc023f317b6556aacfae807eb448ef002d795cb6fd0788f652d39edfe535f75034b0e6f42785f7a6e06f4168aacfb07f2a9e8753195b82eb9855467322abbdab28de546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830d06f0ea7ddad67e7bfa2c8e59f3dc8b3de79b27b5944ec85567788043dafd2af27b6c6314ee7c46e87d109a4aec5ce7969d8db604659848315a9d7a667378f80bcb8457fd5a748044bebac10ba5bc06ec08afb13c1fc34703f63e26c25ffdaf6b0d3a68bdbee98a7c5a489c9ec9ac1f14fc6f2bc7585cb01bb4b55496a93df9d3ec974399ef77ca7cc25f3f65a879420fadbd855e716bdfef1bc8d6c12b3488e4d8ecfe8b89b79b1f9cd9eadaf35f2ce65fa5d4ff98713969df9977513fed37249b4e25f5ea2975f6ba76cd3295895a67ecac279bc65642cbb5d1c9fe31ec5fb5c7cb73b17757441beee4f9f95e4d4177e542bd744aa587738bfac0ef4cefa1fe9b0a5c5e28b53c244dc7fa16ead354c85bdf6993087b61bcf002795d5ada7a3e6747ac9ee0367c824988ca705b818d7a921dba333724d5ad235b18e463a8ac88180c88f17e579fa5ab6e9d4a2f53b03f7c7ec39c47373f369f984f8cc66dbd29f4206a63777d6ca376d1be8be6eede7e93cb9a0437b361537432abd712794f5058790d98e82be48632a3e33a83aa01ed7c8e79c6f12c33fa9437ed984a149f903da89bd53e84db6c8dace3789af5cbba19f010b889ca98af99e5b0b3d4399b06e366e833a55a85e11784708b98efbbf23a27aea2ae6e76a73c2027759fd97a7db870f9fc79afc89436dd92db556e0a738c134bf59f86c98d78a43a4974503d6da8cc6c9098a5a9dbd91c9bad94a7df03b543d669a9aa4944e1cd8ddfdced7d485fa414b0765a88f175ab6c94b12b2e77dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f08427763f84105ed3edc5c1873bce1fd7a897e740c4aa82bb5ab1659e6082b795fbd660bf3fda9a7f840d9f7b7bb4061343d56757258ba4c926f4f21eae1cb265b00b9aafcbe665679c86eabbda12b74f1c591720ed0ea2bb293d7ead5b556369378a8d5b7297c97327d5dd4493dbb173ad01458686a93287b6da0a6923c9e3989b69612b9e5a04ad962379bbc466a03f5517abadc0b13dc6cb4f0637bfee99fe916e9c7f2caf28cbfaeabccf92f7cd7ad85c6f43ca90e4f629759536046394936c3ac5ab979d5cec2aecc19b5c17edb47b0f47f34e6e6028bf9a137f5bf14b62fbac4f2cc6eece89ca0467d4868c11c27f99373687b657d132c55795d80f5b87f0e4ce504673825b98e8a0aa35f2c8d8404ec060ab43aa3de7ceec9d04746169bb4ac4d3ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a965dee494466a49617b64e069ffc57ae4e08ac8e3db58526c7647d56cecb657ccd1143343aaa8422cf3bd0c822f763b6b8fb7d014e649ae43bcc43163992e0d6a8f811b3f0d30807456c84c8bbb008d3b126a31424954cbc6cdbce91e25b19928f4a41b1371447ba3d173915580bbd7899e9adca37b4b5a21e715101717710bc7eec56ec2e58002127d1898bc55f8a3be385d607b3ba6561991ac6f0913617303830da25f0cf0ac14e67abb8097d17b0ad1ea8c6c267adf51a15a9a363d7aa5c8ea535a89115c984ac5d6bfa922c6fc44a3b35cb667f939fa6b2676ba212c17bcd25c82e8172f6a7506e8b77d82cb21d7066da93a7eb3cab8e881a24c7592bc6b656e459af33a06fc2846d71221f1da641004b68bd65dc28a59036ca678508614b15a93e74f89b8af58200d50e718dab1c41c4556cd47b43f14092ca47397243983406e12e423233c90cfeb661a32ce65ab464db58c922bb693f56553961868b064e17a11162a7f0e3ab0b0aa76b8494ba394c902c598c23721dc16c51d46b8258c635763776b922fcac747985b94c006696f18ba49d0c5eb0525cad1349745691320969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960d61a6f94b317d488d2d04a8b42c7fb7d89d52d89b2de30336333c50895348870bbc311611f27845c7775128a9cc831966fccc06292d86b582a18c6ab2fb3cce03701ba91047227a9fcbc6f16130710756c5dc288ba92402b5b7dc90c39193737c206f3f8230261852f1694258d47c469c7452156e70634384825bc52b03e90720066b609a4102862433e2621987e23af51121bed807810501200b776f847ff615c0f594420dc29ca6573276559c1c84b0723569dc2a76728909d9d1279a8c240a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb434132ed5f1340e2c669430b13a709f7d1612af876454f06ccb7841f84c60f3806d5e423cb34b23bba90ab630403a46783329707388a1f4232785d4723c993cc62284d0e35242e52cfd6981268b86f598b11472900f83333c48627d402abba59c6740b4a40abc3200b5d9e13010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6e3017c94ba93c7518f017695f5bf5b99214c8555bda863fdd11d40053c0d652696286d2ba14d569915e4532132527ce1b88122640ad668a20964476db20afca5ca663c6c17156ab3cc8e4b723b3a5209d2d10767da52b2443764f91a7f3aabb35137ee18a1f744562e22385716892ca77d518c4bec578e0f1145b3241c1831bf782c760f9081a1191812790531648954163b10e6a1f02b2b9e17cdd439c6707aab0df09236ba33d9b271196a398ff0b2c9521e57b6c8833489c5328f4866c14d2cc1ce037400dc610b28cd99150404a175662102f9617205c1cbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d3e12f5b56406cc51796c66a6e871deb601cc767c0b8e45744346de60bb160808210506c5779bc275940e000314f30555677689f23009a583cd6f9779c83530e5b2a5a0a771bf1376f0091c627afecac104fb2ba251c074e359e5fc44dec244ccb78423532a7eb27c8313a341dc1431035162838835c85c677a420b67c847dc6605821587c8064e0bc2f4fe6a6b22113e73519125b92b3a66f15564666023ea99273d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec33075d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +ciphertext = d17ae2301459a388f0adddcc7afd2405cffdd627343e2d01651c3fce83f51eb81a69fcb5ced2966fa4645360d1e89363c3b8104f2799e7a22591cbbd38b2f7ccb8c699bd1c9ed043415bf0f3186a916f854136a4546742d98b1c36084eaad725af2a92bbe8efde8e66a3ae38b0f4221bd7390fb6e99d4b5268dbdea674436f949b4fd7cc00c5424f83c669b3c2ae905501599bb6961fcf2f92bdc83c025285aa3194432fb7e0a1e66ebfd5089db70a061cd8a44527830139fc40e67985412768e74ad81d5cf41411238ed3535075931aefb8006e90c225fc9510d645b59f97c1165082fef535b25bfbc57c38a6e5030a2925b5039b7c3c6bd4e56e5eb2d6b48866b91ccde538bee232a3ec190dc8bb26469e02025bc5659e98ea50813176dfea7f4087beb9c59f825789bba86472714b676041fc385d4773332bec39b99fec6cba68b3de5ee080fed1a65a650c1c193f1dbd98d555320143d1db61db609ad6541c09135dc0054c4056b194321a63cba4142a8f397f4e8c6f5d04ea3988a1f769e191a43c0743644cbae9ee20fe4b1da409fb8c3bfaa2d3e02efff51816c5daf25374f7d5270a807ae7bc94027f8ee673b03e1b860bf4e3856ed5eae78b067b8e1af3cf0c4d9de86908a96472db51e7ee96fc8f21065e6f3ce849b09644e543b27b4573db1ef9e0fb407045ebce6457290d225d490d209d2b762d08e94ffc36c4e717954ac4376acbd322bb745200ca84c3e67115c5ec5566908083f6f9d06fca56996c4ae48e67182fa9bf7b547252a552e037f387fdf4105d147b9919f8c2f9c588bc7787a75d60b57e441687a15e057a379bfe9eae7ef0f222ce5886a7dd4d8adb1a1048ad15efb70b951998c7ff236e5401110c904dee9d34710a429a8bacf98a1f14d9f635db19edf5bb564c8a598de2bd33de9a33a8f96fb7d1742313578f2f83f382545264aa354dfdd9f145914260faeaebdb769df30203e41662e183a5dbb991aed6cfffca5db84058a1eb808beeb3b9e6ec299dc51a0c5a4e89a5cee1be3492eeef9e9e573c427e33291a3fc1efea7943760ed4a564e1b93049902fc35c282e4ea9b39f26290e6c88bf8f7c59dff676604db287af7e3af34b5348dbfebbab5041bb92bf0e114d12bbee1dce00e33bc44130f849113d80e95438de828684c8da1366fc3803f79e893812e81b5dbe0b417ca3426fb994a5b8534e941b9bbda4d9a975cbca174854761ef0f7e2dd14eec51f2926902aa84479044bc3275f5c612b6ab3004771f6b590eafd45c3cfa3c986d203b19fcddda741d6652a3282133353a66c45bf46cbdcd7f996d3b0bef58cf1e0276c34452f88babe26928e608a880baf525895ff3cb1114a5ed5bc4d5ecfe3ea527e4651743e7a036fa21c2794dae4772162a93968ec11385e2d4c73fc13a212cb957e9b40a99fdbd4dffa137926ca298f963f10eb9db3f5fd96744ed1e8c0f38f50a43aa06ebe280607c14ae30ec63bc4750e31a2923680966bf9973d799117bd0f514bce085d28dd49e3 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = bddb6a1bc7d4f8b530860b71985f402098c84ae4809c0ec8ec7583a66a3f4ccf90c02e73abc4e8692f5606d54991f5b548dff54c74391727d45997a57ba534a97b3606eead9f7c6446bcd8bb0bea99179bb8f67731a63ce1d7e7f30b57fd17bc016d5e8e24e27fbdc26f3f4aabd45138484a52ae5dd2464440178ca7e966d4d58383f6bf9cbfa9727f907488ea8d978965f9a51fbf729ba8c308474d56089f2cc869b523c41d4d9507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373e5e85426b7b3a5e256154a7b78cb205d49df0371b94dab21b83944fb383cc84adaef4ff43bf731276c1d26b6120534439bd29c4ac7c0739454cf860e3facd86ff9c64af3a83dec313d32bc0a410329d35d38a3ca9dfd41a56a8c7cf496ebe0442afbcd13a8209dcda2564cc9f4d20a47595b3d994888b383e996115aa282eac3e35944482edc2d07774fa3e2d796c6b74a7634b6c0db2f91458a35d41ffbee04848356ecffbe52e2dfca9195afd1f9aa8223e804d35e749f99c539b913c54a0c58683259b3137aa464b9c6e04bdeb85e999b6c5354e6e71c78cbbffeb456ec4c88199764a5761d18c084aceb0a263ea50eb86cba549d8efe4a35e830f7b6ee16b2bfabca3dfde8c3833bb98e385c37fdee25eac36afc966eb3c12668562e9b0c6b485e669fcbc49b24d5dc6d3f37aa7be16095d85415e15e14f2d956beaff9360b58bf915654b9b887ad9733f425a5c6a9db401ff3d8099bc0e95c6a67d2cf5667209ace08fb4698edfdc45caca8074185f54ec474eb35bacd2f0b7710dfe5fece71c98baa7ab6c0450ba6e47a838575a528f7be221c3c920df834269a9425a2edb76cb7dd77ed86d40b7e6d39c9c87a58ad8867954c85f367b9d5aa158e0bade9ddb5da6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aaaad418c79a948199365a6a1055f38114f80ad7d4b3389ee157af377bc83e9b9c86d0a3d2ab3f8737fbe653ebb4e5982334efd11dd3bcb13b4d838a9a624566c7af5fa44a0934ab6cc333e6e5faf3fcf6a6fb97615cc3c782dfd1b3e5486bc69c555a3e837e6613ffa417df2e8d972523d8a91ae5f758e53c1168cb133593c1641e164c8a06cc008059c55449414cfb28667b9922fac42b8bffcce5fe3a5d03249c676db758adf896e84d5bef8ac510782002e4454c8a0390c332ceb7a5b4ef3eb2aead057d096058358ba779d07d207ef4990da77abfd97062ed994fe6a242da941d8865b387236cb8528babbf2e9e96c15898b07e140d3ba500cb7b1ac85e02ed03a058d839cf652d4577316d23c756aea7e5136f9eb20699ff04f5e48953fedee5baf27489e9f98778d3eb0b5764e6338bf5970c2f35d1f8e5bb6bdb1bab630138859b729923343c3d259f2a96ffe39ee9868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5c7eea79cf81a1e3fb373fd5d995b039f6664ffab8e3a73dd6ab93513e92f0f43f2593618e3a809684bb6b3e674e778038f8fefea3a50fcaeb1088f7eecd36cb84329c988d975d71e97c1311643bb1ca2b43cc57c84cd5eb9e09ae36de39decbdca3bb6f977959578954ac17e3d3841d572673e66401f816edab5192042d43a4271e44d1546306137a4427130c86a2025bcc297eb36d3c44e7cd4b0b1c22005fa702ac12569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb3a268165596fd0470400ccf5e3b56714792f7a87b9e03019751425695ad70e4ce0b2769571901c6c2003b58152fa9757922bd28a094771b0cb1dcc73741b14b402e8ab86dc0f647525c131e9aa1a9729075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4c015ce5f65fd1042a137453462b8710704bea463204c463273bb71056378850ad28f37ede664e38514dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd0a0417c2655a5476f51a68cbdb4aebc53f00c11e78e5ba6692a516c076330c20d0a09f167bbfe1c956a619825a8305d1aa9ac5736e6d24145924b2409a8688b41f33a181a9e4858325140a797f2ba81d50f21af88650cd0ba8e662077708551a947c97c0a3355852a77576ca5b054d3b0b9fd973dada618bd02fff1cb59eb56b12c71b24bb1f02e27282d21281493ac7d07a20b124aac30b7bcb8c2ff24b2c927d3d62ade0357bbf7c1281fc94da2b21d10a5e5ee07a3fd9cf93e34615b871c8da7db5441020d0522c12711e1963be54739bd43949999083115988a09c6020ca88124b35c34ebfb0743b494b2666ccf5b5235968275fabcf9a054ef92833d8ec816d68c07fc53634a02ca192a411c87dd1f17ffea094b6868638716cf593b33483591e4049e4e7c65c8618b242b17d6021bf0a70c7c59bc81c34f5441b063b9a1d95481e6529602b95f874bf1c649d95a072e70a52e9252e1dd1bccdf64332345355f7cc48eb7dd1aa2f2c31ad1fd58b8b3a711d113c270a90aa2c5c79958f3907ae3ba071aa6144b88ba6c5575bdcf5331729a65d8acf3db97aca4191b72a2bc1433fb3483efff09698c291dd868275dc5a86d06d97305ba596515e434a8d956b2b73b3c00821ba055aa7541e4f35896113acfd9320fa91585f3212cfd5b023a77d7c5c0ceb746723c2c7d7417bfb740e4bfb2299b29f987698edfc1b8d7b33de2c80d0cbcb44f05b1ddbc667005b6e4335751ac281022cbcfac0a55226fa69cff845007b9a16d2b6bab3135b325b12c263a81fd423120a6fa639910159b693406411a289863736557a028bbaa23e0c984f04543e61916d9bceb4f64fd48823a4b13e4f83b43d443f62ecc72fd304f71772cce318c1da9a57a67502a1119313b93c4a66d03c2316c2cc5c2285b1e80c413b2f29c447dc975923d9100bec9db958acd7850ab0777d82814929121bb87a6f4f07880510331ee6171797bdf23850d5fc1802e432b2f51b3cbc37631c9729892b6a09baf6717e6ec39ec2b3489b33baf257c35b9cbeffdc1a1334380fc35df386116baa9bad3a0a8381c4fdfc4b1b98836f23ab923175eaf72c59d9c500e10944fb0fd701ba5142b3cc358bfaf2732d643d0b135c8f991b0c73789c465a7e1b3ea6804b5ab9ab2e42ca1e91158019306855a5767893bcd17e92a41470d721f6432448fbc370c64c3e330d83987f3a9479f000c75320a296393e253a68e0e1c05969784f5612adbaa2662459b09638202b74d8d5cbd2b01a915ab2ad06b08670546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26eb86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +ciphertext = f597c7ed20fd0069d448c8616f8ca0a60aa23923c79f3bd31a13638775b7b3507bf4e3145221ce3417a8f22282c56862f8ea58cba7a512dc6a3fdc2da6716961ff8011c58c633ce653d39d0399d2e73d4668464a46417545674138259864e639c1f06d6a7a315805340fc277e17d774d3a74938390f399d53514947eded14cbc65f7e33b12662e956478000bf8f2cef30db0b975a93a7383845be2de01c4e87174db7af718e2cabf1b71cb22f166d9a75211bf30aec147c47a1b9d65d9d82c86e2966eb0c3d3b393360e13d085cabcc195c702e1cc4c696cf1860a9fb9b89116a7def1c2215ba5040cc44da0a908209f3554986ec2b60f967d09cbb6291f8fa38319cec24ad9ba588b0c3c6c46bce7d5ece8496313a3ba853ee2060608fb0ef119ea35ef976c77a006352a86796db6e531dbe6598df8d2074b27a170133cdf6c0110995a39796de53d4d7da5068a0090bd08cec831ce7d19b25b49f133b21670b1a43b52ba1c4f61cfb6c9b1ff1d42425501a054697a1fce811a4801aeaff05643ddde4610df7917cb89b82c22fa3940ee67219c6a0d8ea964a4cacb30e3a7d3e9c3bd83b1f0f815a6c0ec6dd8f21c1a49fc56e9d30245baca996c8480d7855e3c87094f1e1100bfb2e45f36698f69c6f2eb13d57e8e40e30f60abeafd09b435717fc89966077bb4f636b6c97dfc6ca7b3d042dcf04aa866afa00a4eb45d92d45bce0dd436c2e4726480cb543d0e95424c3077ac5328d0114a5749ffcfdb48753da9e8b2a02eaa4427ef17fc98cf6298ce7e793910d8b28649a8362a9715eace1cb82df37a96ef30adca9e945512725c4a1202408e6adedfdade710fb80a81c3ea45890beb0e1224763bb018be9f945f4ab02ef6ef3a143edbe9dde24802b01666946785125fd9dfc47066d4635701aefb93360443c5d38d72e5c0f1ff6d3b6d9c0461a91a91b2ef7af8f6533169f6f215b69a71e038cf1add2c04b8bf8e805b1a2a3c60b74bc236ff4f3adbe3cd3d6d1a245cfd080141f54dc036b6916cb5a8b5121b083d7d89d0df82cb924fa847baea59d016847c03ec506bb33f77baa0ade649403545f0f398a9165ca6e5a07eba51caa1a86514e47bfa152d6259570e04fd5a3976bd7a816266c11ae8b5db9330999e9bb1584c4cf669850fcdb064c9d58d959e4fdf4d732b5c7aa7ee5322ba653ffd4fc376f712b8f35e3832c37986fccf33330b1974655d158f3563f886acbdb73f76556c077812c3113246c03ff3a61e8ad973d869aa5f0537d987c0eb001a634b1a01c63cff5c141bb058ce3923d7e0bdc53c44a88fadc9aa48acb254f95d107954b50861fff2b15e9223ed5d575741ab66e6453185dd0c70cf1ec5a3baa6d677cb79a48f54db2d2e105e70809c78b4ee926b903dfd735f9e1ae9aac04c5ce73f34d4b3e3ee562cff04f7cfc383192adab68ae3cda8ec2153887891284ed5399a24d85287ef0a2669abca1eecba26d997219d98a2b81d9f8f91e508ff0d9525aa8d077591823b7cc28b3f4942f8ae +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c6389f081ca0932ab66f658047def78b38bc42b5c4e1a7c7a52bd9d9ae59773b67abeec2aa8666000c6e6b0e4b5c0369e0fe47688ac6fd48c73d783e3025c92d88fa479acbde8a7548384b763a868c56e78345a773a9852016b9fe765db0bbaba585ee8056b7564c53fef8d40d4cd1261e5d323c62a4fda2b518330b6cc4abca84f62c792d07c1e2adbbbd7c5b9a698cb683981f98f8ee6991270d311b0f81dbf9c6c9e69daa26a447de36e9bd310f236d7a5a49b2bc616fd346c356fab09544998c8d5ef641e7b48c35ba7a69ff541407d4fc0fb501c69c58a9b798c8c76933f72ed9bf443fd8bac3df2db45e1cdc56f6fce1792a33ec1a62b3fc99254e527e63328a56d03db49b7ecd7f7307d6cb1ff0de94bea4967213e6e2b6ad3b2c16a9bd4c66e0ac893273e69a87aeae67843944628e6374b65e8bf419e9840b8e6c74e72be3a35ee5a29777c0354633812d3072ea50e7daa4f906d01d6df5617fe137c9e649c97417dcfd3e1677017ff6d57fe073dbeaa213525199bbbfa78f1899a53dbfb8d018e9869867a42bff48d6e5f0efc8da15a4e6965bef0c4207a499a2156ebfc6e1488e82d85a71c9f8776d38d51d1a6e4b1d4e556e5993ed595ca9b0cb3adab0159575863f3145b340149894a5d2b2ea4392c777292e5f880dc93f5846a1b8e26eb6b72248bd1047bbe62aa58747f68428509e53575f945735e75b42ebfba30fec24c990a857f41d2c3534cedd50847c85d98143fbb2ec5e38acdbd55a8b8bcec8afd7b5697316e65af9821918f1a153d1ef0a90c3e8f9ee9d354317f5a99c67745ca4167ddd10d7c29c2f8998d7402e0cf00d0476c4d74c34754afaaeaa1213c9a0198065378de3edf3eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c60486dca679b301bbd8ef1a948a5a83debb396524edb368c736a56977f78af0916364f278a4e3973385fe3f8af8ba80f96d29e6fc65cad3b33c4e1597f818cbc489ba97078d999c373dccf46741cd7d97c5e1ea5aa1e6f7757f4467e84ab9c5bafd9ba48502fe2706788cf5ac1829c7ff0a66f26d3daaf3f7bb8ee67bde95fb68f9341be87162a5fde3a7cc7ada05fdb6f27adfbdb0c6c4f75692e67ab1c9beb46b4de53fc901dd892a3f6e2b0decb2ce5fbc6bdc31a1e37e70fb0a597fd3aa6eef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2ebf9b637a5e22559a59971be56d050efa40f7c33071d377a6bdeacf79d85f3c86223a4c90c31c249531474860153efa1f49ac0ff57551daf33f7367c5540084b75d6736ecbbde0290839ee2456ee16bbcb57c602ff6aa104916254a68acf4caea8f96e4bcef887ded7485511f55a46c75592c88d6f86d05356c397fbee61caa04bf55a05c8409e644055759a7f6dc1c93ed221fb97780b92c2c8aafb6b94c259a9cf6f91e18a801b8f456b93c221b6f512aae7213f8f11574a5c35c3650a7b586e9c61f47ed73e932a0ee9f4d3e359af6a7f9e91cac6e012b7eb27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13e4e257adb443fd428de78f916d9a11b8cbb485d8381f539e1ab0359d3c30f6b73bc8f29ee5df902be42a597e7fe48b38e84df3c6a2dc2389897c3745183e08c1681b5b9f57c16aa2c12778528510868964122c1747662cf97d8b0353bf23693a70b3b2a7c8cd5c5508a227261cb7c3022058e318d3dc39e320770724351ad78010eb423ffbae6714999226895ac23735a9119622bbc0811516d617353c7f769628925bbd49629fe0aa333d1909a16c5c27604b7db0b4e602ab27987df23c3718630ba4c2846444b83fe914d840cc8ed79a85b645a32809ca069ffbb8b3201131cb129db9282b73174f8d4a14a37393552b109d2271edda8d968ac3ff67aa3374a2355c2ec895441873325db71c91020e91f19347d965f1410f606862f69643216b869673b5a70583fd1218639b5036cc11d051a13d219f3969c817326d2b60ba5c13cd8cbc9313aab478833d73716a2a48438fc529084c241bcb4fd67179d1f5494b4bac2b05a5767b9647ec8829a500d1365bca7b8ce7b75bfea0c68f8a28edb7bc4a3817c0d32c4e10169832b9abe271cb0b473aac2c3dd39ce895551a297a61f47162d97c41f051d48b62e5a8882da62fcee16eacfb89b98a12ab626e69d77ceb3b6b02878ce346ae5cf754c3f6097e0b5eb7ac80b9b8ccd9418f63e545d01c7d17a71e45ea3a6d927484d4976ca936fe392cf2052535c201de9464008c932617cad94085c5816aa41973a8d21610430ac4b3080dd480169258e65b53e340759bfb70d68b15b868c4098847901a6b255938ecd15d5ea94232b2971e3bcd56205fc6f0425f50ab880821f56c7b25f51f2412cd7fa023852cad04f2704d4103d4362e965473add3563d9b36e5097c982506865454ba30af132bc17c807309723847257c697c525e27cc570a88a1688134f4193db67eff018f54751e578483a77a119210106fd03066c403b3303ce54b39493323c4334d4a7a20aae04d8ef529a15cb7d0900fbc4236c717310246c9cba14d6874beac61b566593b5ec5887272b914ea655d254d595824288a666f10c7da583f933052f43b0b0fa59248b0584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea50b00a5503cb542c254a26f456aa3286b0126350272638ef0b4a3abc56fc8d0aea2f7396d97b64c56817d58c32103996db88345d377fb7b2644fc99a24258c50730045b897ac908f7fccb81bc2b51c286899c8c499c1757c6b0a6ac0a8482159d564cdb746037a1224ca72177f79ed19a398040426664abfbbb7b7ba99906e7982b665a551881e0f02a97409a3e2acd37fa96a4f9293f786a11b21e1f0bb22cf400da06081bf68111a9bb64469487d4cbc10578106b381b8b054ee29339e1830dd613e19a9baf9a81c2b9ad1d121a47d40234bc9d4b79c2f5f165bab5a2db68c59c0737e0e4786990a92476aea44105f3c77feefc342b458e4310b9b110a8b2c01593b512f069944828a3f6a219354bbdbb1c344f24aa0784160ca704bfd89c4933b6123c4434cb9a6ce16d3f042f1fc571db728119f6a33e4a9f6981193d60be6ab916818b8e1ff9a1d1a59de8824f808043a1949a5520b675d8834ef65c1d47afde2710c6b63998d43ab47a681f0a856d166c24494081e076d5fc05b541145d3155e232a5af0ab96ecc0b09c2c41e285d350500a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c285441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be6241646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +ciphertext = 349dfba896178907a635a6d93910cb4ce0ae4089e9de6c1092bce826d207f0c09a6584f829136258e4fc56f90c21ec74f1984a23afd3515e45b45bd34120e761682de9d9b71670eef80dbc1d5b0131f740c708594e8c66d8096a571be068b6333075773f92a082d2ac79acf46b19de4d595b3ba7ba407cea9d4901617de4f13679af9a45e297aeef0946c2844681134a6d869ac2da7c90b089f66a805518146ec3bee2cd95744d0d2768a1daf931928e9589ee8fccbe3a44d010b794149f0397ac81a7bef9ff5243d98b9492c220e872ff5fea295102beb6f9381815aff179c0b2c26d2416aa41cee61ead73a2e91578d584c8c6bbb5c154a12b94cac64afece0f7081c7c2e071dd1e63e56b44296578a4402cf3775eb713146f13faa0d933e85030d0bf6a26f906f12f826c1b728811ad3ad141b4303763d2e9a651cd6f968af3ab97207b6d17f95c0b40fa6652637d8b84721f3a9802645d5f6f828000e58a4e5bcddf3d19053bd1f8f8b6b125cafaabc09d08abfc852858c7b860542e3b08f4e6661e0799d34ef209bb62df89d5a84e9bfdeb853410e54dedbfe0bc9425226d9aa4b00c51eefd9c2fcff48082e6b65720b45e7175f3bd9f1f4948495dfd9ac595d9b485c779f27af8d4aa8b781cb8b332105e0f38ad554696ce80c4ef5ff762f506214cc8e1e3fb1d7a230b20aef8e55543450eff4289d401861fc37c30d64c4093a2d512394c07340d814aa25476ef992919e6fe58577fb6bf70c6778aa976742bbcfc4677d44b79fedbad1424641915e8599b8bef53ce2c8ed682a1e10716e1d07d546801a7eaed846ae94908475ea20eafda70be83bb7e7211698a2ce33370b83da952140ce4029ef0491d8d039fbf1996cdbf1d04e576c0778b30e83572d05081238743f5b4ebde402629aa9ec70399e364aeae31894e56c397e5430c7250e80dc4d0b749a276ed02ba76e190bb17a2740f098785b8b0e2de69d65cad3e770d853316f7c5cfa508a7ec990c81fb912d1e5eea2f0857893d5e10a1b7a2031169de2ecf3935623c769652de3c48ccc671dab69bf992226d95fa549adf29533f6c58f3e79bf56cb5b0399c2ed2a5550e54b4f9cbaa157719c47f3db6b7ee8f32c04d830cfc4bba8573bd3c43c5f9069704448649bc3e638e46e5ceeac812d356fb616835acbf0711c31455124000d451926c1d55ee0b44295d2fbec5913828b5f4ac5ae3589045192a0e006b3466d8ce6347019f0879e4bb7baff07e53a95044525a843d7f6d91e06f6ec2064b975c1af4017eff586b7681c8c5f7125b6238703bb39333ef122e281229d9c67d495eb3d2c6ac5f176caaf3abc6fafaffd4443c353972b5276f4cce612ab4f2d11fbd30b71974655afecbe8814b9fd088655f1da3a3f7408b36c9292a6d086fab471cc98a21888298fe7eda2c5a1a732c7cbdfa70286ca361914ff83657b7537b84afcb8ad0c653c7bbe623745e95a7067d7cc698e80bd94bf02a0d52b1ff03f22e5e4e62af3fcf152d5c35a20b61cbff2a +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f85e96a68df4bf8e7edc544dbd65ff6c4fba122cfb8ea95e560e7857bedc5905a8bb2590e63b449364802c6b4390ce9eefc875017acf652a8f0d6ab0f7f5aca2fe833ed3551d37419e9d6d2b65e23fce4d601d9abcd9382ea9d628bb30d98fcca8665957346c3a08553c97dd32f77e66348ca9dc321a6db7d51bd9de74e7851e439d1fe89affb8c583762043a4508c3160544ed2264735d6d0a6ab43c95e553223d583298a1155dae3b7c99ff559a1d33115ecfd2489934518bd52fba1cbaad19e9e8464b59cc909415a9f53957364dcca9f96ad8035f8be5bd36db7be9f1f29ea6e4b7fcd493b7b4ec90bc76fe98faa0f3b39b6f454785c5dd2eed6c80960bbe5846e9dbcde837cd277a039ecf2427b86a6658f97b6d101665f3f79e25445647f3bb2d41f5c80d89aaf6d96a02cf49033f19349d9a9af925fbaee7407b3c90c8a53d958c1c83465e557ac7fde545d9ee8c960b3c547ffad8d4f0af2585fe13ed9661b57ae1c3dba5768645c73fde76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0873f73c345c4c7379cf3f873fa5953f53b9a026a4dc22dc96e279085566c7d19deba276a0928693e639b5564a59c08aeb0df5915f5478dd86e939ae1529bb9a3bdb83487c696e79f20dd34f01ddfa60f328184be42b8959dacd683f3bc20f7e9034f3ab14a4745ee62f7afb474dbc4a70ff0c053fca85ffcfb253d0fa5fbeace3125458df8753f5d65ecaa38bcca26f5b543d51d6ff6c8768335854e7487d6442dcb765ab9ec4eea1859b4b6bdd6d918bd8508a9722d5e6a0f897cf95e0b75fe0913d794b46fcf7a78466dc0a18b8e6334a57fce77ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa11d4063696f112dbd1b4434199897998f6e142af4a353349449efa233cf848451cbe6d9d0145090ee37534c42d70fffd2cb82363c847865aa243ca994be499267fcbf5535845cc708cbd9a1e8a7835cf00e8d36768755afab53aba85813eb859ee83efea7563ee4bc158599f0dbd4033393c829aedbeaf89ed852e1fbefeda9484787d51f967e058d41ba3c313a24e4d463cf3ec36801aaa1aa64ddebcef2ab63decaca30102ae089087311a7fb339bd45a163719adf0c313de6307d8feea9af844c7e2cfdb4a5348c1a432f44ebb9f598b8c1cff6f55c4d3cfc22b187430748f8294fdabb9f283dbc4be2d636b6754b20a71280df0cfe4d13b1e55e4746dbf3ca1f34991fe7c39ed99bdf586dd39db8e6d4f8f2df8e57cfde39415aea96bcf6fab63402f57b68f312d3c7acaf6a5f8e55ad69967226dca01246545059e596dfe28199cd0f5505adcb91a0da284fdb059f33d1a8b35211da3c815717fb3a9482c946efdc74b5f6353d5c9eddf590d5d50996393a12f86841580ab599bfbc8838a53301cceed5fd492b04dba272f4505969d88f6b193ea42b034895428de181f4ec2c64b962a92aa9c3fe2e7ff954de531c4aaf857f4380fbc8f9c37d64b54f20ac003b844c534e7e1436d2e75ac09d3e3c83b8575e791a7c95d051fcc626fea682699766e485dfcf6ad7baa8e065e9a279add83d1c5c74c5b95c1b79e5ebe390596bab505e51b3fc147af616e0f94506635a758964b3e7cc067b80827db21dc87450fe1415ee41fca8a2b56b355fff13616622fd1a19a7cd98f5084610d1ac9f1b8a6e78cad9281a0afa5a7c2a9a87916710ec9c5b3544b76b4808d01399f219b745962536026c79841f11961b63c10c99074edbcb4ed786f7e8c3826609533e5bb4cb80f3e515299eb757c217da2806d26664f154c0cc2b4a644b224933502adf5a66f5b54cd45a71589219aac65be0623cf5b4c0df17e72cab64b91bfbd903d75e164e2a0c9e2c997f36a0b432177de617f5e6746bd82984bb9375b4a0a12e96d06045a3a984667d03d8c08cd980b59cb2b0983b13f9c53790fd43653e78255882f9b0c980ef6b062789332a6b67b2b78e9e370b78181531846b9980a8af905fef403f47b891a6b440ee71cc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36613a15f147938d32673402164b001975d9c4a8ba5ce84d20b47f26eba5909183c6fe1343d062389b9b99cedd21e30d5841fb68f3450a47f4c4be5e8c413c37ea4d5ad629141d7430938158cd04492bba8aedf7477ed13a0b97c8217a300dfcb22de05449547626d21409f491098162d7ab477e3ebaf0e15124f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb6705a467a3d4d9102ff2b6ed976ca9d856e9f257d5d586c7d8a4c2617dca73aaa65719a21538d9e6997c5637df8c5a2ab98a169a5ba8f708bba55f2c0a9463c9b4ef0c9822fa64ecc72c8bda4030157bde5073fae6a6e6f036121125dfc5a9dca1504a1225e6da9db4d0665f6413386153ae25be78b3410369bbdbd84a86c6c7bc924dd70005bec0c54e07b4adfa2daeb8265dd98bcb8968a2f683a3b07633aaa0290550665c01fdeb22398aba31140fa7494fd6a0087194673f51ac7d759d649a2fa4d7520fc67138f445287b681f5c3d1678b497129bc6624163e3515c8381e85c173d6a4cc0038dfc2064a213c557931e2e7138fa1a6bc3eaba08965bd803bd5759332cb1bbc4c41337bccca153905990970c261cf63a53204b6f8cb228d4234f08837425a82f1da9be43775df88a20a0381f70044c76b3524b437cf365cb131baa14ea6f24502336762c8e126afd009e1997b8b3bc20c246070df7b33bc9a7bdfa8ccd576925968915f186ca4a5a4934528dc75282e246b0824ef7118d39dc1f07449a218836d47cbb7365b677ec7d6222abaf33068b5730d9e674cc008125226cbc5382a76a9823db1b42976c5c90c23bc02eb7b874dff93699e6035a838b22a7126aa42d62682505f9bbc77143dca061f5c38e99652fc2e28e30ca8d62127af02186bd9c95602992e20baa636ab050ab870b11c52da19b3a68b7a07a8cfbe7bb016a2537e50464265ff6f065d7a8c30f659998a35d79032f887b4629d07bb2dc895f09ac0387cca9c5cd1aebc08a687798721f24ca43c2c5ad42d1b6641838efc2a72ef210bad10218846f25da336a4c00c4a29eac8a608f2261b8c76b18f10b7aba755771376dc7b876152f9fba5370262919511d4ad50d76aa5cd6566c29225dabb3b668608d9de5bac08320cfc3570a0ac8deb4bbf3d941f9325aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e279238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +ciphertext = d0bdfda854711dd009645b9d16ca8d8f4e44c064c54bba2037633599d73cd05e6473dabd029e5518b3b9a39b6b01f6e36734b5dcd4f8aadb4e4ed8e343b8abc4732753d7942f22cf1bf6e9b7fe074195d1c8f414f856c8175541cf0745b755fd58be49ed7f6e8c48ee393f508eb373e79a8a06fc0d5696bbf3f8f8270e3e2b890b90946fbbfe694c34d4df5e70a92a2e6acec73fec7dd90cdc7ce99dfc563e9bd766779f1460f4776d7fc223e4110ebd68bee47a383bb5adc2258dceb67fabe8933641d2cd6f973c157dff849f6e190837fc795348d9e78b3aee438acf7dbb960f6cd9de2630b730100b913e856256c3c5d71da1c83bc29a584bceecee94a3a1e16cf22b7a610066603c14d44268dad9bec3cf53f72a0774ab0782c0cfcc6eceb9413769d4e6f531656e5592412152ad35d7dd7253b3e9578d11bcfd7f0cda76f89c5a3db06236c73f580d7ec441f67a67aac3ee4a80f9f56b56abf7debc9ce34dbc0bd01d5cf3bfab83a06754ad655c1610137071067feb622ff6afd666b74e52df3d95cadf8b05c5e2a20e3821d6e2620f778cf103af079dee56604169f3fcb4170e5ff130bd6365e3a6de215925f4388204da9579b40e98d5831c43fa0d9b60fe2c9f95cde75b2b324f3353206a3d978b805e524211f9e257ef0ef5d391e4258141b489cd52c8e1aa96e5ceef558308952c3ac6b9a01b5cd6f712545f686f9542632e748bf6b492af2c94e8686687189e2b330a71de41e1a9ee6e6d74b95989dc6412302817081b68d1739c82a2f9a532a58c7ae6fd5934d04aa824c5d1ec5201b755b3761a3756bde866b085778597087f99adccc1ca9fc04fce92a423631d4756cfbc70b7b1b96ce5ac56bb61cf14d84fec2fbfd0f62ef4691603a55b114d2216a24b4f6ab07fdf35d7038610882a7f34cd9958d94c9f0b99ce1e5601c72ed128db8779ab1c3fcf8bd8be63c01dcd14748a01e1d1232210006f4ae5183904137d04c9fdbc76e9cddba4316c7cea1eff42e9d5e17dea82804ee9cc40207e28cab35b342bcaa802555f35cb260cb481daaa76739911a4260f26e9567033d69337bda9b11f6a1f88cb65d17ae0a5cead6cace4b93a1f8184c6303cbe5695d37ebd3a7e27f813ec8afb0d18a72968048d27f38cf9de4cbde27b674a672a400aee9cb90c5c170153f56dc3ca8f01035ad173e6931332180fcb2a74e4ed21d6d27cfe9329dc4e275416be050300a90c12cceefca2bee8bf52c71803cd8cf39e29a51b60f188bcf905eb3c35039193d2d0852a62c8543c82f3b2b3fe3e4d51e752eab0130fa0b89f1141dc2f1e73536b8a963022c2a7914eb8f80f9af9ceaebd96137d17c3172bc2af2f819e0899d9e55fa39d6a6c7139a8a2866dcf41f46a78beec546de4b4b47f408128b9317b04949e6b083976cf9e0fb6031a8b88d82f0f6dc64cf5334483a339f7b1f157031a13c751fc62805d6d01295352df2a48c1520fd40e2924e8e7d5e4728dd21cd7069f85913ed776631125846e2e13301d8ff7f2 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f8fb5baadf4c878e558dde3594fdcebb335b6f65bd5dda6de7de9e0afe516515ef981ac6473bf63cec43883a7914a7d70a3d66fd1f9ae148b04f96dc2e0eeaf8b5e056eaa5dfd89bfc564226e56dc49eade1dcfa1df58edd4572c6ae47bcffe283b97f1c2e3bc276a471b63a7efecdc86c7a69a34ed17a425b37aef969c1cd079529caf9a3efc3412c5616ef352303e34d0dc77885fbb9b3677c9d885ddfeb0e257bb7f335fd53928b737d19da3b3218f19e6c898e96b4609de136ad9a1425a0986c597e2b4043cea4e6d7a4d0f3de729c73f2bbbe85b579c4ce3a34344a7403b95e4f5936486c3c7df805cd8ef6f5ab22d4d0ba5f3ea3345abfe666023bce6a1b63a97fc33e3aaf0ccac2c40a4d5a58e07d0c7ab1add1ea67ca6f5cefa7137d259c860d13fc396bcbcc4e77f82439852463b74d855cf6d4f91c8f2e5ad89acfe02d6d59dc077d5ef6d54355c547dfe48077b8defbc313d7ef1b5fddadfef6b17cf1e50d64e36fff9f2f4cc8e3526b1a99a2f4a81e0cfed46d9043246d461c7c1b0df6b56a9c7f7fadea57584dfd44c3fdbb6045fc335ddd173ec03467fee46b71edccd33413eaed7bc26af543028c39191d9da52a6ac04fe7a32e9c0607ba9edab5b4daad5ec7948393c4a77dc340688541aa713b596843e5ccba6e6b54f9f610539bfd49e59fab36d59f8ee9cc8b139eac0144f57e34ffaeb595100ac113ac416f05e8877df1b65db6d063512dc374781e7d025964c96ce3536cff09a96740037fe1846efec4446fcd3f93fa6b6fd8b53a0dea6444a61823b08cb74b762d618c08324f0667f24fbeb3a34c2d5f86b4de59fce3b046079f07e558ba28a8893a8c94f9711d2f7fac79d0114c8bb6aa536abd59dbbca00858fa1843b62a2bd6c68c6b304dbac70dfc6cbce633055a178a396ef35f5afea76543953d4bd7e2b8be217c5d5b1a82facd80f51e9d222759590f6280bb8c976f6c1d0baea6658a29546e0a4e8aaf85a121f8647cb4789484bee0189b9bced852c397a3ef5b9b15b71ffe7440dc3554db740289ba062ee97a6e4aedcca796a9d21f4bc3a4c68b3aedf56d88cdd8af4e3ad3edac3538882d671b1fa765e7d5f94f9d099ec3e0e8d62ad45a0b98fbc64de6e0cdd7d1c550998963d8feffa51c7361d86156ea3a8ae7d18d6f7a9fae8f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50f8e7099fa090de5cf39e374addc61305c4de45a1ba255000a7f6a0873c700497060d9dc93f7be47edf61f9bc61af6d14ecdc3e67cdae4b5ac0d5a06398d4d6c6b4ceb351f1ce9f0974324c0af9fac7d4b4677aa4ffbf65686c232ddb74cb9ab507f2555fcbe8d6909754304573a9314b3c846fcfc34c6302b3cbd5dc482e76576fc5900b367017cd3a860a887459f8cae5541333eca8b5d08e3edcd2f3e7d1bb6bc96f4ecb93d02e76d92d8aa780adc6766532178a8cfb63fc710ee24f5e56e91486c3c7658e3af2cf0a77873c944a5a4bd70ba1696e46e18b328e3d813c9850c40d3698c5afa218fb3425c7863dd59669ffbfd7b2ad5568fadf78fa24c52335ebfc966a69ca882f7d7426563d2e0992963d5fe3efa96f968a92e9423dc4a1f676ff68299899315a88d083bf5196f65cca4541bd4ce3526e514dccaa8ed176ba58014bd0ac486056240ce06c6c182040606dd98978d6cba367eb0ec18401ed348743780ddbd277f2ba22e1b34208f215f8f91a048ca497ec37a7663587ac85f221810e64acf87478a101062535287250907d0854b93a9d4bb39cd5788be361c00faa87bbe078b26353a51b7bdba58d17e5496efb263df826a59296a13535abd799cb931fa5886e35476dfff97e82870653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b27243c42634045506762ab1817534f419591b04622c650b828b3d4a66d9b163d09847bd172ba8ff452759184c07b11183665c0185e0a089c957135dce64bda52338b6492a27a1238aa567f017dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02901b73885557cba188f72ab5a35b489e98ab377691033934029118a34af7d176a436139aab3ac127a8f510c8719936e8676caac2211c8292a42f274c7fa85c542b21422c5790079f34a26f0678c005818bf4981a2b4c7db780c0bd43ad55c0acdf1ae0e0761d7527813076f3174a1d49c74659a453e09c2b4468de6f185d5f3c04f2b7e59e05317586e743285e6817283ca11faab44271a4667912df262c0c03843730acc24e80e2ee0251cca86a83853e6251e3036714576b1c171a112e7a15ca215f63039aaa7632ec77880b89ef8a45cb0b3746202ace1d7221fc98afb73a28a6ac2ae443f16e6072d6b3da1a3be5fac533a9175a5f176fe131f021795f8880d320c6096ab63f53525d01b32a2ca90e1a9138e4ca72502785976bee4e566dc0cc1f3827733b0a7d00cb58b6b89c5e26d2da00429a2450e269da77c46b5c954cee6bdc0339ba357a9b9951802a255b74a4f4ca1297d124056147a0f8123eb903071546d2c22723367308601a22f199f9588734fe1241450a45fd7395df965f46574a030581cc714a50c08da03a51b367b524a2ee4e56752db9b66d9c6b07702ec23bcef798d68300859383c5baca9d8f08b71409ae5552209b5237e697ba55328a1693af7fa0ba27020de2c35f643514db292c061c8e2085d06c101644c94d17c07560811c093afe61c6b4ffb970382ce9fd25f76c6728108842b3841dbbac62504185edc32dfb817c45878189a7ac02859eca77ab445797e030e910243b121a859a05d8caa3c32fa54d033714d20a771c7cca73999f6d91d4db4683a9543d3c978f1d56816d75590642cd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b8290078e2c0ac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4127a214e5532884274646b91f49a1e36a3b42cfb90b27425d2645c5acc2482289d0b4b84a6359007f23b9f528718e6c499590d6bb2a5bb674e89561ab1a48e3988927ac41d05ba143799214701b2f6d708d365be84baa60df8bf7d969a425c93452a0277f218790c80c60b4b59fc6131e7865d1135ac84a6655507c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4152c005ecc44fec299094a285ff50b09388b6ac3972911cfb8ecc9f0ea58761741ed23ce16fc02af5a341f65043f0802c0353d987c718fb72d3d922cdc861bb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd1291f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +ciphertext = 65caf8276607786d9560a0d97f5165b79d5e4c80e07999acacee06bb02246f54a362cde4a2e7ce7f7119e974d8c6fff713df67997041a7cfe52576028d2c90a456390f6004f6e7a5ebde39dbf7aac49faa5060dad9259525da2b466d7da1c3964e94ca16413d7a1ee28e7398b31a0595bb3f06e8eaf26c350f27d348e957bb7ab37da03c120e61be9c4a7dda41775eadc1911a31bf30bda208db0e51dedfe7ef0421f35c2be9c891da2c636eedf8f46395c1ea6d87ca96f17387e444e22a586b4e9818a6cfe7a972fa3a6acc7583be04facf1b9c76cfec8d8d9d4456227c3990ba386bc3b7f8fbdc1a492f3c1ce46424248d6da00e9ac3f868312bee1754539a44816d85d9d2b9764d992728837c0765b9d03c7e8a070de91c655bd3b2cd1268f2a310ae5ec444281e87176678c6f0194d2640459a2b9a7867bd519ae9e092b28910dc45a32190302d34dd90bd068ea9c5ae9443a990b33818beaca0b6c64fe67b847819b943046bba7af092f05170f6a87310eaae2a813ca69fbe6b20fb7d09835b2a134d29b1018d6d05d03119297fb0c53526514aa14921b6cad0b89117cb9b80ff669f635652f67b8e9b26900278ab879f2dfe736284d501b38a48286e29e43eb90f3c6162e3db81ac69722145cb93e57ab98cf7c981ffbce25923ae7c2444bba4bfc007d1f7bfb56beee3425d6420a4c6952a70f85941565c83d9175b98fffa2b44a3edfd3d9665af0ea523daf7d88c739ed491680c1fcc0467c7fb2a4626d26f970f034062acec4ae7a8ad10c3ce34d6d2658a2d3be94e97929faa3e9e76f20e8e1ac5ba996e6bd2be769213164de7fa49d04e2dd010bd56487cf5f00210ffee81030434658e0cbef81757fb3845e3ee5bb126fd6432d19861c9a59a1382a542f5607e7686262f577ee7a5fa51257c286c173e6694533dbe4710e3a9ed6516b61f572bf9a343c0790af2160c97d21510df91ebadd881a8d3b26d5449ace1aa07ad01a192504d95f4b9c352bd000313273a62d099b73d07bffa85dd4bc5ef80b715186e0de4445d30a3eb38059ccf1c3a6f1dde918bb6034bd58975bd891b96aef7f570e9b262cb3b0e9cc721c4e151c1cf055a880ae794acb5bec31b855df972c7a642c28a15339064effa3cc97a9b5136f01f1e8d10b497d4bce88ed4776c23dbd1abc690a233377b39a4559c6e19b2b008484ad5e0ed9b0d449b908e20f9b042105064fa5fc2549e680f038aa3264df28f763db9db51e5e31bf8cc057ce596e23f8dba50c35f44c50e15d08f80422530cf2dafa1e0b9d250ee61b1672f2d01f82c81e396dd1b5d8a68af3635974f0f27242be9e7573d0813e3e77e1811635c0a9341d8647894659cd00ba490a1076cf2ef0c5c605c95cf8ff51ac83a856c45a903179ca136e38425fe005bc5c74aaacfe7f10cdafc5d9690d5018703821b168cd112a45cb92197a50e2dd989744a1da2e70c05ef4c770ab75678ba64a97521a112f579f9e57aa6d966777e128b979b85248793655296fcddd9c8e0c7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5b47b61def35736f3c431a498e378c6c7ea5cdccb58f2f53112e7f6f3beb724db97349b965d9c9543fa66d7a987aff4c479851a0ea485254755db347bff9a06e0d502ae3a911cd6771aacc0b5eadd08af91496ac11ef899b6562dcda7b6b9b7eb516335e3ffc43498859d87a44cb8ad589a06f6d9fc5798ca06744051533d5d6e54608c790a8abd776cbd2984b58eecf4e0638c789e5dd99f49d4cd775b45cc159b44be3ff49b5ea1e398763e35dbf5c6ccc2dd929c9b91047a1ab98a141fddf7705d8641dc33179a8c80449591c4157cf44eb8c8b3009328139c18f8c59e1a6ea2c9ec840d552c2e4b38a7f65b17cf8de6abb73efe8f07e3a1d179cea38561663c9c02eb68166aaa45748316877a9a5bed605f40e4de5193aa5aaeeb34dc6576b57692b543fff42eb14879a257f8de3d6a298cd6ac6dbf8ec3482db7d8abbbf8fa825f72624af6e26a879f65c653f81257dc52efdeeddffd681db43a977d69dc9bb34f9c541bfeb8d83f2a3675fee059f5f655cfc58dba41f55e899c48a8cf55893d3d77d554357d2ecdaf4d31a9d69796df408328a1fada084ab122c6ac53c3c34ace0537dc9aeac739246e4ebaef9ce4c9fd8d78bd43d45d8557ad4dda698b34a7c073b9378367076ff8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dfed4497c997c9e7404433d690354b7bff3bd94aa02cf599554391096cdd53f5c1db19ac33189b2b9aa3c48bc4e09bcdc60f9bd3b45a370c59045abcc0bf57dd03d185ead53056c17eddb5ddc6494524875bce89e6c7a7cd483289fd3abc155bc31ffeb427b7d5093f4616c124b7c29b0d43181c7bded83de769f511e3617a75652d4568d7c7b3ab2b7464d5e4ce6ccf54fa8d73f6e834e5349676f0dc69e96ab44b746e51a28cd2e065a0017ee5420cfa6a69a24989331ef980f718e42e7f74ea863669b5f039b59d48c9dbcc75ce4b434f585ecef72ecf3a29873d0d3a57276128f7dbb4aa5de68e834946741b8e34890491d37b6051959739fa8eb81c694724e704683124136c1c48f761ee3f00c59ab5bcbcef98b97393eb91ba87ffddf2176e9f012859faa6b01b1649786b626358e823a8f26cf794095681d2cf5801be8bf33cc71123898bdfaee479d5a91e8916ba86523f8a051697f814e667789c874394e97adefcda8998e4f0695fe7952496afaee7c6d6e8514ce47148979f5c8bfef8c7ca1836430c3cfb66b17cbca63fdea2157961cef6d0627e57aad986b61fef4f69c3bee6ae182ad76c3cabf076903bd5981445ff4fefc04a138ae0fbd18b2e93ced58981caa3bb13f317499e6ec4bc5cfab8b389467fff95dbe7305cdecd099364d7596b191ed08ed734d7775c5606af0f2af978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad11ad25f46af2345e2b136f30c09f9fbce4d763e60bad961bdcc4d5e1b4edd34e60aadadc6b3c6cc9660e547ed6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aacedbf05f75ed1bd92f43faa848d8f897ba21906af25e68a88c6ea358ae0edee9771a9f03e465ef9ccd20e145f652eabd12be82e7240107059c16c3eacf4a1a8342b73911db6a51d3cf12bb168229a1b29f7c334d0d1ad99932f21babfd8153bae937fdd2393d9748518f12689ca7627a1041d868094aa7440c6724b4430ebd20776b602940c9d1fcb5a109978573434da891962b645002508e46992c0c148f5a039609826baf5834ba7271c443b69dc5110c4b7089068d16202cbab2e1e4525738a19c8315fae806fd139be91f4c1e192a2c04983291340dad4018a8a83c27a57c622408f933a51b7618148b16375a80e0a901f10aaf6e7803cb2a693abcd4ca8bafb942086f42f6b743937098e3d2a607f212f766603c9d89accf7ac584491f230bb1108b1465b865f824215d79fed2525d7e95c7976946e22a9e6510afa2a9e8af29ddb65c47be8820561661050b70ef3b7bb249b7fd0cedd688c37d7a3de667626c2b389b38be066089405703bd51fa32199e9c83d5265bd62a2aa2ce521b69973a18777e32151d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64c9d00e55d814536171496037036a078d026164d7b07e3277b7ecaa770b06dd291b9ad29241c3bb43553bccf66a1dd81fe2e2bf79f1a21e1539d0bc517a9ba8ede2c39deac4cdb7c65ff96048461ba2e350017095a35c1bfa25c242b000affc8af29495a2d349133c343d680eea815cdcd89c4fc283cd5136b89abd473b4aefe2228f4cba5e0c10ec7a1083833735f081034aa7bbf20c11319ca263b52262096e505c45805e73619e2ceb242e559883d20dddd4120f0c9e49f4995376284147cc2d2a96a046bdb3f56b6dc1889976ae1ed732eba43af5941831b2202d6091c16b680001a82d98ccccec212b79b5a884756c75cb2545316fc072d903c670864d5a13534e545d836276ee594d3a7841e5f91d6b738d97e73a7274671d6470cd2719b0515fdd67c6e4969ad213254502c5ac9ba23c264a375237369b46d0c45745041a20511459d3321ee9b395978f2c575ebe1c6caed03afc7027bc457e03f527b0ccbaec71850e0955f0a2b54d9bce69b6c8fbf90850168adac411ad5c973b578424c55ce01b3ec2825b0085232469968b8a96fe7b9f26846f789323a15aae6397242a712cd26b0465bc038a4aa30dac42c0036c062c21c3a4178a0c92b8992cbd54a6044b789d943f1eabb0bb24c3d0d4c067251779374579b27c84fb435e6c745334485fba84676750a27c520f79366d008e4be93fe8a958e8d06b8ec323bfd5bd01e86b1f13302eb17aa3aa8fdb3445ae5775111b2124e2a35021c04945661b2c510a29264ad855836c7d8eabc069011f8814934bb4b32176c0b59b04c5fb6cdbc8bc41b0bcfef4423635c0c7ac43e4d5286c74920ef37c951266b92074d239b2bd0a0d6c096141fb6a718a213a3387d75b927ce176169738abe0cfa6b68d3b064157c3cb03c5793a7400c1960351b059e43a7f1b28ae5073780cc606f7e40aeb458dbe95a31c23af7e760001b0bd601647ad1805c4329e46f490575ca928fa908b5a30fd31520c61c9f1cc5ef18578b350a929164de33b008338180ce41c45327152090a91b8c9b3928c2629a48d78abd1992720e841a52ca91a15a1c7953d18b4ba1f990af34ca408ba2d449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a12fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c7262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +ciphertext = 9520fd68f1a0428cf46c71f124f0e6f3f21fb2d5fc390d54127819c49541346d0da18c5e2d1259564aad5a1709d33a87ac8f070e9509c6275217407bdcb1802849d2d6428878a121717b6359e8aeb075304fdafd10a6e77eed31f4dda3dcf7550abc55cdac8476eccdf9b2088559a5cf7cd00c426e9cb3a3d3d533bdac13ea257641a324719a1c92b3f27dbcef88916fe9d7e7494a3b4134d5aab08246923053b3500dcec963dee7d1e483c20224f480fe6c2606facc609e7fd47cb0d70116467153719562501afce27d9d08981254b96836690a369c9fd2cca3ab0399e8eb794295cddf714b543612303b44b6b86280feb547e36e10bbe4fd729f3a93297ad20fbd53b665c91aaa966e7b0e2e143505f4b4c930cbf0c19766e0f045fc3cb21b09df4331157a751c8daeda28a8d515ca09c53dc37bb9c1d6b99c4689316b79f4745c969f10be1f601b81b989ef3599040917d23e20df69b716794bf332e9a31690749319f08cd3de0b3fa6a820fdbede2c8af4c5d1cf5176d6b457b8f57d18821ef22d16544f4b6f3450f87a181fea90893f917f379897ea322aeac04ab1b4207fa1723517e4831ea7b2c8918040c995c3265748931bf9bad6f66a112954de7fa799b75ed1572aa999d91232c29bae2f5372dfabc7bc6d5dfcf96e02747ebf039adcca1036b4b4b13c59aa330f817c2bdfa29edb911a613f5018128f72dcdc73dfe06ead3b0bb323275e3a74ab23763992031f66f20ac134a9e5c781c5948b533b08d777b4cff4d74edaff4cb27025592a670ff2aa74332156b4917f7ec0da54d58fbc7cc63b62d3bc1aa420b80a7bc4cd22a237c797fb633ccb0efaced8bead400b623e0f99d2db72cb5f9e8d44f97470917c303f4b1543346c4482532f795202c131c9cdcae8aabd5df2f3201e9dbd247979c1ad198ffc9aa45d20d052f48d3a675fab69a6e33e1a46f50413bfb73f377e260e5b150a859ece8eccc1d208bb6f9221e145f1a071b3fef1d6c4ec186fe8eff29129a31a323e7c6769eedbbb125c57b4fb13272147f631f5089b6b49b9bbfca3c20fe7d0955b9f9e2bd717a8f14705b5785391d28064499c5c1af95fad2f57e339e14498e1b4f2c59265223e7362042ee6f51541483254c9184130e45372be466796a6349cd59a002a3f0458bc72e824917a13d32efb7dbb3898a2cb830214388db9ab1a60b299e8671d42e92b096b704246140217bf522ea5db18d65480b23cae658bdaf48117aaaf3f555aa9521174247a31847dbfa4e592046fb1f4e60606aa894b2e6a78941c34fe79bfc45143ffaa8954388140e4b369a224067450c6d6e6e39348d8a00b784188a6229e6fb983cb103a30c7c8bbdc8ca658edf638a6acf29c6df500b91ae0c9cb9d8beecd9b58ce1ac8d1ef506d1bd5961e7080e9a78d37aae5f67ff01ab1f4afa1cabe98b5fa66e8f8c6d687a271c58c6003c6e499445e4fb9c85b6dd5ab4af31a33b3fa4e76bbb29283a9bad6ab7d9d2cef241d30fc01123a3df4b47fb270c222bd5d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2d1fef1a4ffa908456f1677d31dc8a4a2a734a2571d19c421c47aecd5d7c3c53a9321e3290b693b0deb7ffeca87cd9db0419c48bc4359d74e46d9932beec787674d8f6afe6c7aff28fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c378f8225ce77d3a3ade4cfc20b9d7c93dbc339d6df71bd21b47c38d6d6efa5eacf8ce512bce5fc0d761c9057a7ebeac6c66e98f9a8ed2f67a0f159a5ee6612119f54d57745736cc3cdb634f5658fb684d805888fea8582135bd499d343a545e4e0a6f0c23db8549e25bbd6358f8bcc0a4b44a7a4904ede8ca6dca45779bb564a30dfeb340b4c317cb77db5dbf89ace0b4676f3c295b90e93c264da9e17c3bde66df351c81c58b545306449585718f9e99a74dfe3b0ca1e737c07a4b7e21fce54604590e4e5f4c8f77877890546dcc2e49be4b08c94a744996fe8959d4492f0b7a3f53a98f9a8d914863b9583d8677e2fe583fd2677e8a3b8ba544e902178824f4c41cbfecbf7a4b666acb413c31cfa744b9a5405efc5b54afc6459ef70494e34753c1b14d7e23b95850a8c026843643f4fb329bcbb85ffdf5cbb969bd4f3a3eda4ec959e1b5c9cc3fa180588b9baa690f7459b138fd9fafd0bd2ade910a3efd948c3cddaf04d866edd6ec866b48d7baf2e6fb5025c6892c76e16e37eb998b888e0481abda592c8b36f74647040cf3c51b5ba9959290ed3594b8d73ad790798aa304579822255e62eee55719fbc9b5bd4ca4d68d6db2941ce8093ec5167487b7538c9ab47dc278f15c8c7f324563d3973fa73bbaf07c771b25d70d98d479df693535425fccae108f72ce8ff4f3795a7034ed4814f5e4a749233d9907eec11d6ed7e9f34fac3536365ed0fa2ef34d55769b763cf34d8b991faa6b8cf60126e953cabf0733cd3a08eaf5158a1376f1fb159db3dc6c404ff0adb8acaa8cccb7dbfee583b9909c903ff43613de78c568aa7fafe7e345cf4daa9aaf17cca1b5a4a5a73ceabd581e73bcc019bce2b68c8c273dfe588ba096ec5a73a6edd9bbdd66935bfd4e5eb8ea55e6fc9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddc4f5cc4e89ed773d8adb91e37d8f12b78a0105bffef3d874ceb6d5d5469f6464705741ec53e0a8185a155337306d91c779e09f19527e95a6803cfa4a1f7078cfe126e7531a5941298bae19a3d9ccfddd985e3bde1ac8239fca1a76957e2da306a3ff83994a010fee8a5e9e16138f0477667f338a6755de1248a68224fa79d9ab6b58b88754362b3faf350fd062a554ca8a40da0481bb8fea9c0f3da71987b744c6b9ab5e8093df8c8fd0252dd7f0eb72ae3694ef9f814df4b1db269f4404cd0c77a845dfb751f5a0bd1cb93e6ea628098d0eebc9428f7f77139831575b98e47b7dc3676d887b57ddad96bcaa1f38d049776339cb3fef6489dcdf620563dcb08c53fb0839b4a9d9864ab06b2c3fe15957dda96ccdb9dc529d4df02c6a1e5846f99fa1683838b986daba0d664a2ad39b7aec75f9c4b05340ede9881f48869dc881db0e91e24bb5aec448ea15fe57e69edf254575fca87a1b50e6d3952073d689bd4328b7dca1a871ffbcb0a98f3dfd4747dc859b45fc2d1bb1872a743763f12d29d937f3f2a41d257531c1172af59c90806c7e5a15972a8cb9dca049bc92700a72b4fa5a739033437c946ee062aa86c12103b557822a08084be63c4c74d1b92608c3b02c6520b2991f8499470114fb659f89a937a25897faba6c0dd142d8d4868ee3c6483128241b287cba0ae49430dd6a28d1339605a4b750e6029f73baa1fa8ce6219c36a40e5542ab45cc781a613fdf416502743df8cbb3c4b864d0b448a20c0b0942a829601f2b131fb038587a99b80ef44033061b2e4b8f9a12c3c03193506b62aa1c7ab08569c7d0a88c8a098f87061ee41000fd202e2c3af4e625b34787bce55f74aa58eeb9124de7089e51a581893354b36fe035ce5fecab74018ee6209b75fc2702429c932abf71d89b8c82c047d77725cb6ed98608f2ba0b3462c1d428352c6376f6269d9869aff4bc821870b63f2284d296677b6145683ba6282c12c72512ef015eb19ba86b3571be7438f17311655c118a530266bbc6d9d10636b6347c630607864949dabfa558522c100f6c7941a076109253b5ffd76328c99590f48b3fc7ae7a5847cc958fa5523f540ab54ea0a302174e6c401341759c121b355c9280d2ab6a84f9028634bf7e3ca90679aca188667d5086df35b88d95b262e8478561a414b627f43b0fb8731d3bda73c6396594694a9f7024cfd55d3ab88342516cb34a922e6835eb8c067bd35ce0b3711d7bad2d7529464c493adc40d8ec8679c903e8984850034ef4a828d3fabcae9474f7278cbe79c8e5c1c948b94798d4c68da8255237ad8b0b38cd4a8dfde5abf6b2cfad98a677a8c40e208206774661490c3c212d23327a46a23dd6855275b78d29830b23900b13c638e31b4745a917d4fba95a04956c371212e475271ccf94f6295346118806316ec01d08454b0cd922d6f1a3e4a651a7a931f380042a09244bb39973ec5872c28c8d41c4bcc72ca4409a363c49995c45c7909522128c03814612214a5eb01527b67bce4463202cc14e31225b36a7d7d10e26966beb389877ac0062f9172c0517ca8676f5a44a10106fe75a31a4aa86688c075918a4d8a7461dcc1ea1193913c259e3b44c2d976ec67613468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cb514bf7178e14112c8b31727a38bdd20a5ad087746768957f837179d50d25f6697f4a88d056451a593e385b74de8a01cf0244e70ac9ae36b2d76cb91e5419165c6507d141148869d6676f28645653bc78c96b9e7f382cb0c6768e2968c513c7ab076928781a6530cd3ae3286b0c681743a58d9c524be5120c880605bc139f672e30174095932a000800d58a926cf40873c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaac9f0344c9b6bbb25cb0aa084f616332197295163989e1448784082c327075dacbb7d912025e4786710b0c7452f827aceda11a73ada09c3e54b404419dbf3a8f8b6096a73528dc50fcd230155a97a614663174683d1095d97b7c0e994764df2095ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1ba061302ba9cc20cd46f769e1021c03c43ab07bab1bb0c7f3426d252a15ed5a27854ca7b177a6f79502789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e13486bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +ciphertext = 027cf1e2d501b25ffc3a13f5a9fae7f3535a8749d0005ef28c3468d95a2931dc1d4b6908ab8a4d22012d7ae11b21d594275a9288ea7f12fd1c5a18c9bd13741ee16bf946383c8d18de5a8008d98187a7b55a42685a5a79415cc55dc2bc2b81dce12cac0494ee667b948f6bd14b8503a0bd549f54cbec3e1ff25aaaf142e03c8461f8fcfddd4b0ae1a8eae7f6eee9915df2f80c501dfbadd8911463b73d254385dd5c6bf96d3295495b27788822759e13deaf2665b6c5fe0b2d51425c447c7ca06d0d86e803194140433bd02877ca9e47c23c28133e4463fe0bb00292929bb4f7806cf8e71a0b3bab86fa386fd0611f96d6b648a30a079719a283f02116db38ba5b32778f15e9d65d11fcba269dd19f85b4de540508ebee0142a10c11bb0814e0fba0b4d0d951d0f5ea38749534f0c3b1f6d30ed9c17e13a817174844d21d399b36b71241e1b49e2ae1937bc6d1a255f61230e2aaba3432eda6da8c0e3a7906f07982c5ace4d484853c4358401745ede71fd8984acae82d098d9c72a0f8ed9ae7a0ec72d69cfcd56197f082bdcc04d3b81c2a10dab91e3a4e4c15b815d0bbc66451bdd5d7293d0f7823989f7d6e2704ecda52db3562cd2dfd139e0e30603c7f3317aa2d4131ee7bc1f9aeb697f4201505c3c102d42def728dbf05a9d55714da3ab5d4e8c0a0c77439118f804efba1a3953972a62ebf20da30ceef4dbeacf69746baf9c392ebc4d0ace031c46eb4a7fd1466ebe992d6262ed24779c21f17bb3c20b63e716ac68fc90fe5fb1ecadb031ce87f6c2d13abd5c2dabc67e726782f44498eb1dae0b601863c02f13d3ab7eae309c48369fa77a7ba1f185547ce10696da86e2668a67eb3283074c4e3b7b8fe27c6c81060353eaa860a89ab08259ee015deda20bae823e0c15a6734e835ab4e64b540963753782db41b9451083ab2ef38e675e1a792678a9b0a42bd35586576cfe78cd86450db997759dbd4f9c4989b777272ad6adaaaf4dc32199fb0798a11d08a006a47ffea9d8f9a1489562effd9741dcde99d267a40868a781ff3817080eb34bb931b1dcef5e4bdc7bf904615a2e6353e1e6ebdc37a85b9f81f72e2afe2eedf6414c07c95fdca8a4d9b58f8d4313f636c3f6c83aedb5e76c63abd838404b1f86b9ab1ecde167501e9a732ce656efd9dfd39a266f457d3a73879618c46b4c034f0d2e6e76edfd39154c65e8e601f40a5c199e802bfc96af5e557c0addcd3cecdb9e7c7d35a5c66d485b18def8a814321856019808746fa1df56994240d9f0684f6291d86971580f85f706a59c6013eb57a52da5b4d15ea564214d2106a1f5c131a6a8ad3f83f86bcf9a8623069cc8df231b7bc84147155f1f7680bdbb7e0dff61706d849aa7b89c549f04d3f5b53e6440c2ce437c65731e5d76fac50c6f310ae3734e4fa46f75af8d8aee4e25b93e84e3f7319fdd8bff9bdf3bf18ff433bd5a7af58e542bc91ff81393d04794cf85bb719c6e9397f355b201a85202de2dead155fc4ab4d01a1bb379e71c78e053f5d46 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 47a7741316be8796eaed5e8a9b48e46b43aa54a98f48ef42866b8d79f731d98c754b67fa2b9e70a7eb4b0d73b38d6665d1e43af0c6eab95cb54879707805bd7889e3ee369d231c600b76949bf86366579ab637f4cbaebeabcbd2fc945bf007cf58bff5afa67393cc58805ae5017ae2dfc9dd5b5fbe4109d8b2ffc4fe93712f555b0ae896e85931030d89643af3e4c38581d4c40a46aa8ddb3c26ebde29fa5f7b1fb6cb3fcd2ab6b50327ad0de8e39ad83dce676ab2ecdc2774c86a2c72a50afe4dcab588a66d665ec040f9eae045698bcda1dfb95048c545d08654c1b560384561ab07bd8d7ee82f99c79b2f67ca6eae66434321e8501d474ad84aa71286a948c5ad197f32d07f576f167d63a9ff62d3423ce75578dfd52ef8401a4d4b0e27d6bb7d4fe4eee6a528f9321fb8b817d8c094bde829ac38e362a404beb78df6ea6782372d35cbed99302c5660a3ece31b93b675d59633699ec44c29cfbd231be9435fef1238890018e618cbf9e315beebad90a06ac7feda5680dea12d1a41eba931c279acdb875d9ddb7cd9a6adbfc3f239e843012a8cb917767764d8317bd56fbc42758772c1e53ec034447acf791b837a6a34aa788edd35593a55e57572fa99711bbe5a83454bca7990e834ba285a09bae1666cb2b2f397059d4354687d0524888cf6461e03d313abd4265de38f4ff4546e9b3de7e5b627f30e08c4585478f9996798e9b47d8eff82ba45857551ea4c79b5ad577938666413e74e84585e684783d33f3c8de420f66d48473fc6bb627b399e90697e760783a4ed9d663ecc524568def8507f0437314488af7376bf2a6bacf783b74fe97d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85b0ce8dc81a8611bc4adaaaaa440471b64dd53adb874db67102b6a64ffca8bf8487e19bff768fb71fd78d8508eac24b89284ea83e67585b7beae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774f8d5e001b44c8194661af80d0d59bfeb35ebe9c943f6f6b98e488f89842765debdc4959993345c38bc801b95d56bbb47a3bf3f60ef33d6ade2b8f7d4578948cfc54336f7c9596f75689f02e3c970fcc980af56758aef08017fa4bff34dd13dec58ea6ee8d30921691d71f6839635c6b37d497ca4a87d4bef47cac6085f3848ef63685fa4bae8af13bb36ef445fe6536297d4e4ecfcade6f839f9842fabfc264ab4ff648c59d15708f55ae4a396d5f4bc75e2d603c03cded4f52facc579a0cbd1f64a734e8350f03acebaf734eefb486f6b93c36ac128d3e574d70aba97d2319d78fb43768f98ef6dd3b090ae1ffcbdbeb3b5fe023e00665d8111fd6a74db93de87bd94a634907730f3d800803b233b95d1cc7cce4acd8ab143734347f3459a5bf0f30f958ed50b4b835b9e736d6a7b45ec8082a4d080967b44bd553835bf52943a49dd51f48c27823c5aa1bf0b7b733ddcdd4b2a7819beba4b3fcb1fa9e789c2c57cb0eb50533f14a03dafd04f2187492c51ec14128744bf4a83599a30b96e94473c2bdaff2fb4ba34108689ab8d65baf4ff3559a76f759768c81a8cc5aa2a679303d33b2437b05068bed096475e9f80bf349f6446774b30fef5b426f563962cc29ff78ade42b497dc3b970f1b848b1141d7a5f45a37c25b125aed61863f22732a06128bca08efc8cb176ab6343239b572e1c8c138d829810227afaabb81cca0a73131155377730a120558231e8f8a598a2b730578edc7800b0d6c5627530ee92930eb2b40a9888cf648263b688f0a12e08f004f4bb449a25282029cfb73c32f8d31229d0a58e6aa08698517fbc5f619837ae3331cf763631d305e88c8f85413e9d5420cc282bad24a783011184011a79a3b305db5b3032b75c55907ca5c7f839320028305c439c39484895212b1e87925999681819416dcbc7ead45ac2b1262154bce16866c04561eba2c9ec6022b07a57a67c7b901b5da3bb8025c7585c86bda0810c442c39374040236a82884199159729834663d3b1967df9955de3a387d93d50f5001924c4fe433d016bc2b6614f2d3ba72fda226864ad6ba5b8c31681dc104348ec2b29c39fc9f567cae17bdf1c6e215c92effc60e2d6a3a3106bced0bf301b542f7987b582b0780b6d398631eb8559459b1db01a0443100dcc731291c737499c2f86452394c0b6662401fb57a4db232e40d1b0f2511ee1eb15dbf7b603e2a67808c064fc5103fa7c9c954fcd12bc619582f82590b323698a328cc14acb87c217e39c309421c7e6ea15ba6c3bd8587126c5aa02c26308c9912d7262dbb91ac2c2cdbb9cb009a3ae10761771740b2e6558fae775deba7a66086859270ec07b584334900c278002d8a47d01547dba3036336616a8c12415b86a1423a6c9aab5f085c7fabb6355b3db4023e47c7917c10c284333110bc978b2c08e16512ba95a07237cc35c97bfa51bb1b25e30750e65664377ba49200aa6e935b4c7451e547859edf03bcfc6904df05220c02f5e576604a873ee82b7693b962853b5522a5b0986348da63df86a64671737c17201ed556e92acb56f065eebd31bef43ca85db1feac395e19110a2f0c5b90459838cbf779c27247709765569e5a649bf160301003169e4ac2baaa4c4697f25869ab99179f9f792d9b19df0c148df7c6b9aa20e63426697d83a6e33b35f4c7e798175bfd73ce60a050146a3d893c4dc9b2fabf5960bd80fa0679433bb33bb91915e93c1eb2aa16cb13e0b9870fef99835a674b1bb76946bc4064cafde3063498ca30aeb3983f5cdb3a6b9c4970459d969f4d8b6ba27755b6ca8fbca178dec28dfeb2ac03318be7002a9a4cd7b1749a7fc7f09a6b560740da89baab8130872510c99630f3b588069d50a9550c97f8198b7a46148fa7ac1580632db1ef49528f9125784a5bb2757235fe44e74529a7ce88e91543b2ff81d9ed78e2647aa07033cf3422d34942e7830191b104c7ed56b8951a9c8706e4cb33cb0b918387b869084386420c13b09be75d2a5e9276246b674e96bac7782541e1ca441e53ff3b9c702cb95ceab628d1617704a448ef743e8b811fe52c659cbaae22377f28646c45642a9886628c9b73c510bbfb645d4077c1d8b954bdc8b707b7f6bc4701bb1af0f28b88dd282b78b7ee96732521aa6180b6021aabb415839dc3a1f6f545c1320c58b965b62993abf6a10c18a22ce6a45539685f297b1f04a130465845d189d17552e2f4917e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +ciphertext = 3f6f05da5d7deeea60bb32a85c0fa85f2f6339a48eb45343e20ad802329006d35743ad24a30ea7e1688ac9870485fb2dfcec77a5dad30ba75d613ae6211674f12620b2f84e32f5bab410123f921d8967d7a1b8ff92f4d17885b2bfcac31442ea09e40a41b54588fca2cb4624663895a8e4990d121cc261d97e5211ea06e12278d550d5b0d5cb815cbe7a6b5c31cc01edca9d61917346ffa49163e363b1edb342d496dea50d463c3c330cd453b903dc4b2fa78b93e4a78fff529fd38a1b57ea5e714ff924c14d97654d390b8dfedba47034db426c371e158359c733437cfb5b0bb39b1f4b7cd3874394822b9d137359c7dea734e1bdb51e77373f7e6a37561a8051fcbde5da7f65f5a1e0dce2b1559a4a90c0d0fdfc57e11d8e8ec81cac05299b3f29bb211756e3811622b768eed23d84e20ff27a2dfc7738cac348a938c0b51f6e1340587f2ed4cd05d1ad2298dbe751863be092d8e0f9ca870cc7759f898cf2497249206b14dca4f06783d7b54d417fcb578904d87a674b82967a820e525bf1c708246565291998d83a78feb27982b3d7b9259936eb08239455fa099181df240787c3855e564ca1d53253e45d7f12230ed2d623e7dae75e53dc57c41678b63f66622f5b762abf5374a01265d82eded50bda26177a09007eb30d3ecbecdfd7d7f9ab455949426773a03f628ae86261c11e6c17b276a4fdb7745ac76c7d536ac83a7805f9aab8f86810f0250367a86ad682c070367d6ec4d11581fc9d0913daacc0053f381218f5aba830740bf531fbc9e823d71dbf1d8f3bb2f2997f8a257f02fc8b6b6d9be236e190bb0f83794824e6ac07d6727add717472a0894b27692b6070b9c4197d0af9db339b9eb13630bdc016bb43712b92e79c35f8be95d4469cccf385a15cb76a48d0597ffaa710d4fcdc62e9587eba1713afcde87efc2dc6002a2dcb4105aa473c30a827d8d4ed21bfc7da7293617029f1f0cfc0857dc11c273c86e18ff68a129a74039f717dea458e3fcde1383d70d800b3d369f20163d2eb0b3333267ca8428c8937ec809f33d3f532a6fe3054edc3e88505f6e7001247e21597927729affe877ac665a6d606c36cbe8fb737ca62e2af6f6a3cf6a1e3706e5259ba689c4931b88827250f0e1f5e5fce0e6d2f8930ea41f3a80938d9a50c2ac817302d7f60546ed233185326e8f872558ac16bdb5c16c132cc2ec05c2b2a19912ae41d900274cd8d9c52b025246fcf14ea1bc299efb10cbc74481a58a5a7a284f3357702556441de77647b29a727455f4196960a10b86e434cce0c69dcba15af5b1ed7762e7f211b34c3a9223959725e181f0a2421586c6d36fe7d31944ede70d63e2340feaa54f1983a3a37d834c2bfdb9470fb8df5c9c4ede73d1820f87961448374b19058a23970a63150b730cf6a7816c8ca21145b2cdd46ebb01a65015bdd5d982ff8e03dcc1adee845aa5bf09a590c695cd2ef7f5c1edf40f167b28a894d9c33baedad48da0afb5901a13019f72c3147269bb3f2cbf688b2dbc574ba43 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 35e4451348cfbaad6f1846f96178b6b04ea1c0196f275f5832cd81ea779e6b8c4b3f25dafe2963aa756968358bfcd47d774e5ed4294f02a843f89b87d78d3bae5d4a9165b9beebdc956d58965b64bbf953e729e60b53552d2ddd251cc9c21e837e0a7c4c043ba0777e53b39f658b41b5f8900d57f1268a8ab868b15b1fc3b804e416dcbe117ab3a027b8fc2cbf3566569a23dd6ebe32ddccc5eed69a392bae8e4a7bd6c9708a48badebaa7a0aeac1f7f9eee0399803a374d3733af6def1a846cd205e76dd3eb4d53750bcccf938beca43c3a6cd5601eeac251f9aab9bf489f2fceff436f124fccd1cbe7dfc75db71f5a1a433325a559a0df3b49bbc3d1c9e95b984303735f9f2646f0dd50097ab23a8aa5569ab744a934c2a9eba046cb012467d39c3936eba9cfec4269eea0eea559990e33b52fef9d5a603e19fc19a8e8c057b7c94ea7de0daf2c0ab3637878a9ea90bf377874fa38bf39dfeb6e31345340858aea53d4bdda3deb99fb628d975a921def908afe9ad37c9b99b8b09e5070339fdf86e25d9556b27e6cb74a9f1819fafd8878815f6fd82cb002ca49e879c50e33af2e747104674eb103d959e3c22f3aaebfe3dfd77fb6ab855928d4d8523d48864dc8cbdb832bef5249f46b7178af9769a4b359664ba48da4a746c215c58bcf752e43835b6cfa9ffda3fdae59d39d38ce6dcd60f5bf5095f1d3d59c4f0836532647776deb4fd6f337fc37562973a1f9bd963fb4bebf5c21597a12ee7097be55cd43c76874c44f25c1aa1bbcea897367536ed05ef4feb6cdf246dcd6ad82ac03b5ea4f32dfb44e201f4fdf65a4bd03b16ee7f9894d65d87e35f1f730a7b9efc2eb43272cdb2bfb8e616cd7df64d41917a95b0544e95e3e8d6d60d15cdfb90fc0f278d05144e960654f3594c9973cd8664b7bd31bff0328f7307b95fd5f5a273fc2466d41b1286d6f175bc0c4e942e8b8be69bb365ae1ab4cc19a0fdbec5e6ced1acc1f5bfb91b860331677290c643bb9a00b4b65644592c5ca5bb1abf5d2b7d80cd3fb09aedc137946a3fab6c8f3ea1e97a4735a5c0a239b073c6e066d53cd64981174978717e8d45f35019b3ee615ddcaac31a37e67fe35ce57586c365ce3bcc7587dad66c7ed5674efba0196f81d94843e0edcb3a93c060f5c0c79ea0d4eb229a55b7c5d67250f6c4f1b48313788a31fb0ca5e783ec9447e64314e878734ab594029f3aead586225c7a6ddda5f97bb7673fdec47c15c06c7c30d90c89d404c3d44136c79f56e81cc2ef3a7d3cf969b72f6cabe063a35774a60873f67b1ba34b93a5d3ebf5fece84a034f9a9d24fed897320bfcc11449ebcc097a079bd4bd9356113b3cb993c19384886efe82e37ba659d5b8bfef44465eee318cbd092b8f8e53c63bfa3897afcdbdc66e28ff5c83fa85c36da34fd6cfe697f173fe361bbef5e6c5c6ca0fcdec68708c14c175f9e0d01dfad647a317f78f52f76baf0d6a3ab5e780d37a00baf0c6a5322827e9c5ac88641a9d15549088b5a4deaf3f443335abfc5c2f7c5be3ae42740cbfd71fa83bff71af0aacb43833b66f95b51a885d798825c3a2c04b399d5f8530daf4117b6e762c7b6527b0509b5963b685610e5db4d4895fd557f7434fcb61b199e793c5e763764c48df412acb7c756e1370cd117f8c10cafb39cbf0c8c3f5dc8da1855203d02b39647856b55c38e944617b8348d16a8221962a42398fb61978f40328c83a0b49bc843060d1711e289434db4b5b0838cd87949df5ac0727d8a528b8b5bf30ccb9e37a6664050cc5880d34c13ca42c1779b8d098c5e0876627c17a79b6bad44a9a38c56883d97cf2d2b114a1c4f1a502ab4a9b7b5398d9e73e543b860f87062e27a9fd1a2035185f0d98857b0759bf1c39a41984c8c1a1a9027944417f84cca0dd4206e9133f6eb6a989075d004accd9f57cdc928cd455443f0222dcab9a8890004c2596efeb06903b5d0af33a88f14fec760fc074a3dcdc744e9864e7ebc608a56002e483e60b8202b31377dc7f5a486d5a060733fca9836aaeeae05909c6b6b0db4531271fe4f3548bd5bff1e92160321218f963081c518874c0cbb792fda4513f7902be6547745a0879ba6ccd7c0f73b123dc605bc7995bdd14b018d8278c8c3966aa87a24b4a4bd3abafe0c8173c028df14daad39c288943eac139210392bed70c38d7af7439697be96977d23a27cb6e7de7b785673c9d1b33a081a9cd417129430c6c6300c496b04e1796c9c781e4211915162de147501b7bc55f8913c66c5cbd209ba6d115f753ba739417c8eb182200113ce17c935a0622dcbc674553b9dabcda17bdbfb4865d58143c149512cc2e74a2b508f67be8058461252d95042f8b7641e1d85161521b81a616a02110d7ea3bca4723d003a4db1673d64273b34c9432ac981a0c01dc8b8c0ed5a05d20c5331831ce56014ab0732b301ca2f8569fc061ddaa95d63667b9acc7a1ea656f821d55a31b41f32dfb3b66ddd5cd2155438db6923069430b61c85ab309bf56b0ecd990427c1b7d93991e783a647b1dd66696659b5c926485e1642854f0839033138a3a54c349c138977275e71e0fe985493cb85e0923095804037462ae248780006d0778334f664262e88498fcbb22d46d4f4291bb90afbbd40fbf2b302415cf195542dcf3375e78602fe1067638ab995b70e6dbaf7b75bc11701207e489f361512b590a860401a3facc1ef1375d8b64e0e5c7f863786d3984710c2f55ecac578c41170194d832929075671b814fabf45c6e2bcdf8c0cbe2954c5a414e3f8878ab68ca13189d97f316517abb4c5187dbb03413da654e650ec1cca0bc9472bd4bcc60ca6fcdcb26e77a025eb70ec0e60e20b19d30fc261ad11d3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a0531315dec20d9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceeda5036c31a897b65612d2b176e9648352899bb2869f48b1e70c1ff04864487258526226a7dc64306b6838f4286b9a81a3193f5c9c711dfc5b9fe79bc6cc14c934591f93860b66511aab061295af186b8ceff5772fe50dffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b159a1c84c85d717824a0573cbf219fd9b2a32ab66bf8a498a04aa4e22509a5057997b74ab5a1b27b96656bc194af08114551709a41142b715c6e167e5ba5945729bfa702c236073fdddb4ceada972810253d642ec094333c028b0af40ce2e29993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611df89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +ciphertext = fdb35f966ebbfd16a07385adad48cfce34f8e312619d54fa614ae387f2d7c1e80f07d8233ca39dcac87d98d0b0972d96058f3d949dbdd749a759c31ad696837f7e687624d20d6a921ef055a55cfadf48a5952eb98a1d1508dfaf0c83d9623f08f7e6424a5dc45de4ffe226b3e1e5d5ee5ee53ff0a7e12a2497d5d4ca14dccfe23eb4fc26f27a62398d4f1eb268565487124306da0f7cd8a89e4746a9f42180ec5aaa8ac3d821e3f24cde824489fc38f7f26d83f1a134a19929e3ea4f3a3eb13bae2434104e115e451d7a7dd0732f57d764d7aa63399450b5e3a74bcf5cabc0b597919a1a14d6112549483e6d918ef6c0c1c8fc71ad382c63c3b81f14ce5a9c2f57ec3a3c58d643db18637a2e84c1ac4288dbde2660f34f12911000662b519e69e2aab4ff6f7093ef7330bc91b6a808487a5987389e380a2bf5149e955349e378f96eb17131d9d00b218df9f9de4a607614c614447ae1af7b7880412e686643396720978dbedcba4eab3de76233545b578ef85ceeaef3689c0f7a8e1b20c601d96ba4d9f2326f35d60a7c30b17344002cc37698fd84536fc9ed0848b12db94e17862bd2cea1fe8536211bb99bac84097d3a81661a452d05ff7be7f1a9febb4931351bd9d9515b69ce4030157ee5a468dbe9911ac26a93478225cf10d79ad86c75ab0d2c825cd43292515a317c1e9ed74bf7d51b8fc88ee3573634586569375c91731ac0e4eabbcceea2ac9efca2c8f9de612115eb02279826d0212de5fb25327084f1b07c364591e6fe8b1c647eea063dc923f2dcdda841bff87befa0feac5dae47626125989fb007f89632b87ef8318a2b0a669c554a830f29ed10cbc3820f1cd4bba6fa367ec20665858fc1033be26a443257a43329ddac6683649139b13b5a4237643eae57ff3a65dbf70377d943f9a88a8a355f32480a739d6913c0029ef691b6f9e14d8bde603b2788e9d1169086276702ad55fdc02832033c729e6ddbb142cda0fe072fd781072c954f07005189612db4ab774664793f8a00942d4d3304ef7d412f5717d476d67204a02667c3230cbee8ee41c6eec7c2d3fbc3582a7584e24b71e1e204a98c8e0073e068c6bfd607a1bf9ae1cdadd86ba48478b051411adfa3bef3dfb021f0e6acfc17a1722d0fbb802657ca3a1a3bfaad6f244b518284e2a88e7bea955e41556fc97eaec1fb6864a2f13b417984196ccd70d067b1d746d332062b2998c51f89ff9e7493b17562dace6b0f0dc521bfc2f833a405e1e5263006aecebf880dcd2cd489aec589793e4ab46681ecfdb07992f7b32973a179e7bc03ee5237eef3352489d81aec6a0fd039da71590ce193003816b04936935ef214d109c20c02acc085dfc79e4e4dd8b0640e78e8a90d45a421eee92b4ec78db88d63d3d21d5fe2d2550ed3cebcfa7a326abf3883d003b415cd3fedee17b934960bc2c2ce114a5cda73f7aa783070b7d9b04a7085c76d2862c9920e88e91c1639680db6b03b9947947136f301f4bb33048c323e061ba7948e1e058a01a9277bf6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 03a941a829c02536ef4427fad08d6bea6bf16b58bab845328c36cb925a5169d6b1ff24eba55de0ff3cea457ee3c443c6d98ca879e673cccb84d65e90686e9edf59c23798b9b6bbcdc0d49df5f4b21563ae55ef87dcccbe4c53c62918a6a213c460eb8c92377cb58aeb6d6467d50f97fc9dc6907b6be6bd3db314c3ad6bff46999743ec7ff1bd55af3bf753695395d6e57d7de15e183dda398d1378d6b80e7bb4fb4f36b7653cde7cacdebffeecbaf2eab65b853c7118f0819bd5afb8638803f8fea6c3563ad27d7edafdacdbbb23a571489121cfbaa0d7ae00df96b2dc8b40e4d16feae60635e2a64462ff8d6d5959c49d0cdd9b2955e658db7b0dd21eebfd44c6a43d08b5f469656cb9396c9c640cbd77cc24ac0f293bab4cbadd998ecdba315354d8b754f0cb53f826cb5dc92f4c48159626053096063841153f723761f843e5629c945778a2508f6a28b9da5854ba7f8dc48e44929eeca17e28304babcd0a04ea8a6fa04539ff09ab5b7197a685a67d07ec9769b69e64fae457fb8e1b7db23ac4a79723fb031f44954e43e936c6e5d840494b674fdc9aee84a091175f8f4ef1151be376fdf8d0ab6b709a443f14c56ab67e3a97f1a4b698eac96160befc0f5f77e4b4e2508446ed4999687ac5ad6f6ccf5468f3e944b9dd99fdd3e9337c85e60f4a0798556cfabfd47a40146691d33cdf179b5bb3d3d88f2cb29e2b961b73d611de528fab952dc75d23339c26a38f695fec13cf360f369abdfef8cd64551daf9456fdfaec7c359c09e92f5642f1bab42814aea9ff844bfe56715fee0f1e3063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a7ed70fb665756f98156c65a704d7e1014bd664da92e9ad9ef6c944db876250b951d1633235ec5bb6b79f899f8adf6bef819a241068b08337136b8bdc33476fdebd292b68ede75490ebe93e267bbf2f8459fabb17e1dbef80e8ae89599530d453065ad45457e3e86a12c554db46e7a9a6e3767598031c86bd68e5585444dfb4ecbe078d350cda1cc2636d12df3097d776d2645db74db40aaf92acc909abae1d1dd5a1b1469ea2673020bb7ebc738129dc272efcf73d37f620efd8389843b0540117c7ab924c141de40a08deab1cd596103a1aef3c93a2a79be19c7870abe8333fa7eef65a2bef80e3d490f05dd415ad06d8a403d5d948da4b1055be8be35a8f935f079c5acb31d4bd42ccb526e783aed7380fb3a62b3a5090f95bcca410215ab5d3da89c7f73631853640f7bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bc7e8dd7facf602fd303faf5a0bfbc32b5f69ab45e6bd8ab9f9456a68b869a5ce3a0b6c98edebf276572efc9a3169eacb33b99469e9fd20495db284bd4ba7c677fd754e58397cda1920fd404b545ab2f79cbf6fd08eb4c82f6d569598147f9910e07dbbf89fd3764f0bb999e4a9cc28ecde93b1f4d0cc78807a54d13933b25b350a16c842e4b31337bc7745ed4fe564c21ff7ed6ab800717baac4a9c954c6ec5238bcd03dac6fc497a6a9b9e4973d7d44ea53b90db26912ac7796d3f7d24d3705db5bd0266b17b145fd8ca77624c8eccbcec219d73b2a639d5f135d06aa99635c9b53244e1f898d8494b681312bfd243c8ea5b7e71ccb7a5386e477d01fca3ef4122a63934843450a446caff55184d052923a393fd887df6b045659cc282d1424b19b17cc2a2384132eff067a0347f88c6b392aa56a3519a440438d3f90f6941112124c91fc31187ab0ce6752d9b336a1e230f97837a657599e253b7798c912a66a48314447c352b84590941355c6bd1c0951374105858a46502ef39cbb58b8e63a64e2b99c4825912155695893a62af6745e76058d551a946161f25f1b8fc045602344a7f342facc50e9565c1d59a459d34233c1921ceac6e0bd936b496c8fd6a619d8b0649eb458f8943eac97293635092666688db559d255ce9f280227755c3605d6ed007ca718527227fa1f40dbcd88792801d8db6b2374a23178a72276c790f902d7e969f2686c9508186788905e77132dd909397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca64918370809d3b1b70cb09641878e7c0a141573030aa2b687761bf43ac89a81e73376793ecb32db53368ec9e079172e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca582017892a188fb2440ca7240c3c22577230b59ab8ec038bb95cc49c2a2f59a4a22c0c482713544fbca9d7404b3a6ad86e8764a601b7084289858bf62a2828d3091ff015089726ca23b1ca0f87195ba1abf80b01f101f8584c15289196744500000b431a60267174f2cc56860bc5ab4ec20d19ba8ed47535eb42fe1d33f2980ba211805a3618f2ff64d1cc634caa6b40fd23615538366dbaf41971d8b5857298c1e406a293c1b8b7f4a499a97be8cc51b5382020ea9c7cf809fa7323134290fa461218f4a6f495caba2d1511ea48b7e0905b0465f7a6711f2716b17dcbb4b9a1b31933d7d3622315c79f3f11a93c8058fbc01c4839a808a5d2d45b99f7918faf52db1d81d669c7988ba7eb8847187ac7b76404b1a139dc4e4917c9b4e29833fd9fbc36e4bba96e25bde691ce0c369ace7183c762bd04785efcc6b614165c014a0fc4b64b24b3b46418ac5b6b7bf69cbc75090b69aae46b4a12feabd4e134bcaf14922367b50f17976c6705e175ff34612cf7b086ed733deaab0ca815a53c99b2985963db89bdc284d251340b0e3ae20990ee93344dea18063db6ef4374a331244ede00b46676475937a9472c82e124b1751a9e4203becc77ace092b055abf0892637b39c3a9a011219c88139277b8bb73b9508142421939380acfc2b81523c72e923609a0505e2979e086ab85f9663e549f3350a694458ce7b02bd8716c0f8b8946a21d99d97632952bee898989c1adeb710e15bb25b0a22be598a65465bf2b899719d00f9d16367e9436803ba8c17b6b3bf62a10a017c177125396bf6745163fe24c455319cea69393ccbae42508156167b28a1d1050bdefa5a789bc389031bd86e72af5f5bc80a215260737839654998295d5aba8c11a5417b55d67201243393b7593400d46cca1d321c027bfb09cb08a1738c88b7d47e876ef7517f8d96cc1c93b9e93b7062227a55996fa958a684aaeda89587b015a6b336dfb610721298ac6ab713f3a2e37b2aa7b1ccd2a876f03c72546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585ecd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +ciphertext = 2726c88c44097de218b782b16c655fc658d29386b80ccc0168220bfeb554b12a3ec13ade45147b3b68cf67384840e1b011b86808e2b922f7b9e0db40b5ebf11ee131a1b4c10a2d350c1cdce92b330de7f838e29062bb243e25f2f62422ff334f7ecb5863419b44024039d1f900d3a21f5f48bb78f066aa726e070711973c1f8de28efd8d71e0cb5ee72a9d675974c02286b56029dbba45e064bb68db2e25131243d9cdab71d2dc8b56263a6fe2b2d6bedf4cdbea2572e333c4b062c91622ee60d1e506384e17a10d08d61cacd407ec924944e9690a81d1f7f989cd58c243607c4cff68058ac8c970376585666d146bfe8816fdd0d20e13bdc0afd88ccc1282a17827adfa9c927c55ddb520c248216378b68908155a718f335c39d0504bfac4a069aaf2c64b8cd935d5494e31a399257997fa8df3c4237e4209deb9da336d4cbb116c531a8cef2f0be5184dd08668630632d030831dc13652370f0d7b54aba8b122f968b2e00af4a5d9c1790554b9077b2fec861ce9e8dc89eb21c23ccb68e9080c2cc0ad9dd4c3364183a164e9f57401653cbf95d0a58d289f481a38b8b13cef56926612848fad81e5f2a1468808ff45bef6de82c121a8d3e956710b5a0a37cde624d1aff6efefda13341a7cf6d1518b633f65fcf0b3b91c06769f307f94347c7e1efcc80e02e823dadbe0ffe2cb7f3bfbf3a60e8dd31506304155467d28b12740ad712177227b4468d5f4bd305ddd6341ba68ceaf4d4fade19fdadaa3db805d37671f1cac1c57882bd710b2a7545594320114ecafd0fda32fd9e06f7cf2f08ef27de1ea119239411a10598bef458b8f3604ba82afefbcfb7b6c92cd65e92e7518f506c684b08d156032fd00c3803cdecdb92351ad7a3b7768159deb534a24c9642684389399205a8b69f52e460be217ae7b5b08e8c1360b6ddd6ff35462d9066618ca07836a136d044794954e3812e29ed9b200d250f3dff0672aae2509b4f32cbd580631627085147c5fd76fabf284b88a836fc4a48911a892f03a92a4a497d62dfda5b71acf4dc4976c7670c88993a23b1bb0c21f6cef59b0ffa88c4c50393355a72299cdb456a592deb3f749e1341826b3e89c4138badfa1503041e50c70f8236ec881b08bba64c46d611e160cc9765c512574d875b50a5781a7871a6b4bdd02cb344a586bc1653ca974adb1175519a0371695d2490a54b2ac21d53916d584f597f7e861a051f93b64d5219339ec403d7d537271d5d9928e1530a6c6d0fe8e1055ce1eb70e5c929afdfd591cd8f9942b6fe252fc98801dc4ba50b9a9810819b1b245ca74a6d8238a4bb7a64cc6f3c7c4541779ccd0f8509d9202a88af0ab2552417b13c075e1c609af2281740847648719ed72e7695af239e0c288bd630c72d5957632c76e89b0c5dbbe74ced4a1536b1e7fbb2b7e6edf8feec8223428616ea5f967ed05eb2254598f3572e2627b6035025404911ce26378e8df914b06c6415e528f9e2901a90992a5eeb0a2326c8076ca8da8a80931b222b809bf62e3a5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c94f401604c8c4c78d8417c805cf723b14733044aa2755897f65987a6ef1846ea07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bd3d6f851c9e93bcf66e3c9e9c939be52fb07f6efd295d3a6efa9d3ea8861e39b1ad58eb8bde805a9cdd48179aa22d3c2ed7bb59d5c8ef75e281c77f83ac7b49eb997965b161ebd25b47ce6e3cd9ede4ef5ebbec8b7b4d20783d60d9ddbfe6ac387b629cfed351868186f6a0bf68905f9cecf353d3fb577c263ef919533c7044697da4f5bfb76bd9d367f44bfd3613351d95395f5cfbae63b2a56d8c69364f41e85d543ad8f35b940fbc3b48f63360c5daa98f59c7cb4634e5a3440dc5957a3644f6ae381389b64fe01113f9fd6e519113c17e64782239941cfbb11a647b814372e323f05844592cc3c17319b4200feb0bda3f5acac3f18bad085c8f27b7758b85e9316653baacf53dc94ccad37f99eddb9fe67e2a13662c77921e4a9a86d8d8978f811e53a60c1d89a1038483f6e5e6fbe09a3b7637fdfa45cfc3a81b96d84336cf594d2427fbe1bbb9c7b3685ea45e45c8ed731b9b75ccadbfdb768119b20a0c346156cbcd5bb108bdda0e3c6e949b9db0b4ae220f6c9169d8c5f38413c648eecfd623f35b383bdcd5f4a8d716fbebbbcc9f8d9bdbb5c8414fbce2f8ebb0d795c6786af95a7e7b16f9f7978a03558f997d9a873e9570273beb7e986ab9f56036dd022569d4c98a85bb98aa198deff63dc6bccd1f6d32ebab8caee5cf4717b17d99e25c67a8a57fc371153a4fd9d45fd3304a74b98393606004fd80454a005342c23e8a284bc5b9b7ea39e748a94739536b517dbce61addddb64c81001acbc2793f9f29b42214442fba962f43ed48d3d0db2e86d21a4de61c4b5948c7eedeb9fa5865cb0ff90b8eb9f727e137d6a678d9f746beaeb9db686ba84d65f6beabe332ff036bd123e620ad68e84d32ca5736d3ea3a02feacfe067dfe5a5b398575bbabe48ef6e55cefb4b67b34852dce758c58562dffd07aefe8d347ef2bd73f064f1f89f6be6bf3440f9e5b7468e93b8abec6be231b6bef7e4032ed4ed23c6da47d32edddd3757d6eff7453dda3ed810f9383fe7e82a85ad7a8b25ea97d1d2aa21238b25527d08b14d0291e68329bd2869889f8fe42ccfeae8ddba5ef37e3de649aa9ac56229494dc3eeb90b96ae4bf829af5f8c644e10a3bcd356af43f3654296bdb79b9b7d53f72321959b373f313aac107c8b7aeb83172778b7b199e7373d7fdf5ac6aeb40cfe750b82f7f47bddb910d880e4d5877b63ff6d6e6bf4a51cb1ec863a79b0e099308c4fcbb7997431dd8268a3b762b9a5e28eda14a4a92a5b55e7950268a9a845df889a98835cb9562a5a62785da5348b3398b39794dd9a18ea058bbabcc7740b00db8cdbb4e094fc7f14b47ff4cb424c6f52ccccee30398023a9b50b4bb4a3ceff1bdd7a0a54eb05fefc31e3f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c44f0bca7c865baf2461b3d966ffe989fb37b78c5555a62a3439f3ba7646086e11346d79bb8352a286e552d94bb58b07cb832e3bf88031d34ed493446abe723e57e57e3589427301a6e40f47658258a761edcbdc046c08bb89726ab73a3355199a1833a1268a37a087ddb57ab621046db1f407c804c488e4196048ceb762b9024c2157e7dccaa1a762881280715a1467e766dccb159f4780a39bc4f4a59715700070318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa913052119904745ec68cf3502f4663bda74522ddd61a318539e10a853bc90a5b06aa12018c6bac4a8123719c567719cb723b420540ebcd84c2787f37a76c6c40fc983436c26f7fdb14df17062be752af2c1f1cd1026856500f3831cca75eff7a08d4d9c819d295674550c1c951ff9a0155856c3cc143824556c09025d55b0db7192d969926c18912bf5ca8629401b8c53e23832cefdb369020583b360595541f48573ba1557fd0c1058a8cc5ea7ca7f092b7dc7b4b04490fa4e72a37aac0e33b1746aca327258d9d29acf140c5f70b8f94a23195d60d30a498259c6f9d06bd69f82398953b4fd39adeca972851431b59c9614b7867cb1228e2519ac130f003903d801f70bccd776a9b916684cd89cd71723ca732a21fecbb90d547646b987155cf5425abbb2406cdc1821afa8da120a540d1c3af175032444e1fd85f43f47903665be922636755b5e75a90931c66e89345f57ca4a032959bdb4521cb62bb1377dc5c99fbe36c71347b81a80b6b7251fac3732475009a719f4374bd5ff01cce4601e761a754e05756968f33fcac4d6a540d93951d0bb4d0d838a3112872020c2dc67718888dbf408941b877eb6543432675c879aa85f102e608aedf267e32d333ca9c3860f907f17b553580aec75902ec304e6c7996ee34061b40a9f4f8ba2ccc55775490dc9c2a6d5c0134e809bd305d7445c9ebf7b89f9604146b2e55a1090597033bab2a25a3886dc524f4908adbe98dc2d74386806ad641712d9c23a19562e4ac7f57a86fc98663e455bd963c4e63d8471b504c14eb718d8bcd6475cc45687f55099f8fe2035f3812f081b6df2a174999765cd69433e5312be67698346fa1030a40943f8927b2cd8a1e2cf2514333bce85a89a6a99d03c4a5c0b847550972f9d1448d1819b3582b99a50ff97c124398cff30967013c4dc4d374379b4e8b037eb0e570aec147a1c99cadbb651bfb576ad61bc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a192211b4d6918260c1251eaa1014c6f41427465609310d8b665c6763639c71ad48019905cc0874be438023936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953778124c2c92d29cbfedc21678e54861eca5cd350fa09b1365fb74435316f37386b9b510e2bc585da30a71ecc7b9913921ec8d8fba2dbc97807b693b1e306832507cac90410e0576611ba79c1ca9c0b106d0147680790ec5051798592d3035aef57a0174cbc70b435710c51695852841907d41a8180123a4d911787b674acb513c84047bbd5851c3e83a8a046062c06bd84397858241c95b8d8d2a2c53038856247506065a70a5a29b701bae1b488a68c2bf02472d86bcbfe263e7820902102c612747cd60344957a871c7774a0980b70b56f7bc45f8e2bd2085af080cb923b55640bab2aa2c30f206ccbad17bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +ciphertext = 0a307d1a8a695cbb2a421d2c316ba05165535ccd1cc9ddb641b9edc8dacfd10d001d7dc8166a7e405f6251abaac6d5f466438f4a2240557bd7cd6ef811d4e1334b76274dee6c34b79979e02db09a682b3f965d6356e9fe640643b03c9d3cc37af284ff51f1ac542060c0377df1bf3f577d387c8a5adb0b0a615e9d93c7b54a6c7e3593ac118fdd7cd1985414fdfcaaf20b5ebe647a7de9aae9b43f0e1836493fba2aedc459aec78bf697469daa96819fa276113504ea82d956255e0de55f8c6268881e2795527889278ee674580866739fe66b66e94ab71de0f7637214c2e804bfd8414ffd95a5aa0d1f694760169455a5d47bad6d68f277279527e8d2e6e95051c6c92fefea4e07610abfa63ae90fc38d3b819df566ff44379354bc4479007adb0fcc603a346debe6a2bf14afd1da6e6c04b1483637f0814b5bd5f92984ed8f895c35c9f7f2fb5032614e52ab183639e6caad3796b9ffead73a9822a23e997e0c99acd309d93d227b9bf1297edda5a443e4b01a0f67e5a25b2f395635a1fa9d25241649767baae14de7a4bf3d5cc8d7360460ff85ff0cdc646a4a2f8b5d1edd9e88e353f4771b2395095026b79daa65e25bf9c4d19761f3e9bb955dcc6f2f288b1537b263a026b7067a309b08130438db1c6790835695987b705520a215118b20e636145264e37a1577c7466de14c26e4c372b33059bbc913a559880e31820fd0be232eb7d289f5d6e9abeebd9018fa4247acc708f602b1e8692ad10b0dc6499f0293d1b0624ee40d7f13b235210087be1a8e2c709b88f6460db6135ccda532f8061772a5767501750e58ced64397bd0f7a280558e86d7fe81d34a24d5736e4e65e118c7296b020c55af0887743bd53e2a60f809a024c68bd1324f833e8e1d505080fec99b3e2098df4e844341f7becebd889c15706d7dde9dc754b6393da40167a2f00209eaf0583ae4ef4048dd026ccdc2884f17238207afb355a419f3666f80d963f338548b6fad3c9b4a569a964691f8cd20a1abb3e01fc5744aa4db5ba0594cf863f566e7b3eb401e62e05a84b30054b7798d5b81bf994a4fdd3a876b46898820fa4480dd9a1a5ca970b459a4366e5097b6d792ca598ba6785b0e3328aea07f594706af89d88727a0fd7a5d16604766aa73c21081303bd676ccbe0ab287f2ae1ae235fad0a3d2346df4da3cae145a0d2b7f2a70dbe3cc70304ce49e528e1ca56fdf81f33267402d271203b8990773a1fa03f18380efc7dab62ca34e28d5db918dd6365c2d79ecd5d70c95a395211afca1a0542201e731e61c1dbd31316dbc41ded48e70ef47e4fbbab6bab47a56dbdf58c5d741008c74823561937fecba694bd31538064bf242eb926875b094d0282a9583886bee06c948496c24d563210cd96579dee6de96d29066ad4e1f9d1ef1ed463f7c9d21bac44c9cf303922fff1337fbfc5b9559736801f80974dda71ca185baf31f4e0e2936b4d3ba6f85539816b69a8d433d84a7a88d2c3abacc5d4838fd3c2952f293a0adfead7b2829e4d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0c9c633ff39d1c7cf9f8356aa02981ddfe89d6535e2bddd750d3db111a88b32df4e58f3e7d54361403d212f7c78f1679dab68b71aa9925386590ddc8e2984abecd9647453b3fd99dd97df38c04dd921fa7dcb57e0664d148ea4ad6f97020474afb65c5c67ab4febe515c6592942bee38e4d97155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b57dca3fea3314b4bb404cb66e3bbf8f2953f278fcdb65cfb489d6b3a6f443775796564d75cbb4b9cbf4a8a98d7733f69f9fd4ba89782f974ae69e808e97cb2478f52c8539c2454041d9f32f33b43ed8359dd6856c98ba50cd9e92f9a4ad497f901e59e159b5af795ab0acf0aa753931f47764b6cbab6968c7a779802b469acbee7f677a0a485ff5cab2f038e12ee8c3525f703cbe4127b33fb01adce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78558bed31686c6b4c3749958efd6d89201fc9e0b7c19613823eeab1d8f672089339e47ce6dbfdc3b7d537286d5c26b7f3519af651d8762ac373817bbddbfceebdafcf910afb66896c55a4c946a791e66dfff19aa21dbe32322bbfd127c10d87563028bc4acff2e65deacdd8e9928f8e4d2eea54566e5724b40a55fc0f4632b7b85f0445c881938134e5e6113560b0065bec4d9fcfbf5f797cdba0bbe90fbcd2150d7916ca93c2abb11bd88553aa34c3d5e8bfec423728c86f5f9c301aef712f5f2f68391114dffa4d5615eebaac17de0f9d337e134e3ca3d81514a937f9798ea7b57b3a3a0c8f9a2697b0778c802116c067a5c368576395c43d3398ff97c77051ace6436f84e19bac181afa6cb85d66bea1163e6b0864edc33ec124ce84e82c69202d749a4b92f3eed40d09519df7678bcf82fff9cf5124acbe04388ccab61b07ec87ab3b830a3ef78dda69bd67711ef42413ee89a895af8ec8acb9e69d6495d00ecd8cadc27bee32c16aab0ebc4b13abb37d67ced11ad246e87be1233ff09a6802f6371858972e2eb48e5edd8cf3a8a1e664f73df8cf95ea144d37143cf0e8eaad7df3f581b39b5da3f21c07f224a73daa2b61f3d7c8f25a973b8e5b362fd6800bbcbb6dac8c2a86a7758b38339752cf3ea65f3d84ec982a36d256c69af739349e2d6ce9c9a70dcbda951adb648e5994a687881e578cdff9439e4df8489ec6ad9258eba796e8a6ff5483a71887e55783aa5fd1e5b8889897de67e3feabbe3251a6f4f5bf8f22f8d903e591331ca793cdcef824bc62168be6eb8f7caf99bd5e9b0c47d509e38378fe717625f1f8fc882d1b8d0db3c2109a43d1754f765f9f7b17eb759fb753688feffe2fdb2e7ccba484ab89e92b79337828e1986430bddde0b50a5621fce5dc7bb545cabc77c336893addf4436e732b905e7d769865cdee0a9906438e9eafef521862a42f7baba3f02eadcd1906f31bb68fdb8e55ae48e32dffa30a4a5c3ecdb17e0dd26fac3bdd56cd9d06cc8f2c6b4ad4e2070cebebddcd885d6caf6cd43a4e513f0a4ac07f5818c7686f0745ece93c24ff951fef63f51a3fb373d076dca4eb8da156dc6b4258f46f638024b8782c9757e076ceaf18cc27284c321ba9176645474dad32d97e6575db39c9b23fb8d405f8cec82abf70ea4fbac16e6e3c5e5d9c8ca207a5c77c7883b917fe0463d3101962b802549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a6204903b9bc9311c66b907c5825621b7ebfb52f6c7cf75c169c17129595631a2fa95920317aad4cb338329adc69c6795158558638c474710c78763e012240cbdc2e586adf93c028522321a94cb766f9e983fb5110a10476ecba92fc0c120cc83632409940db249ec569ed5740471c86623b06962910307781349f342c759886f7c376ce708091019fc407eeae76409387d151c97cf7270319143471a84994bb596f9b5e1a78d33428740fcbab415c575e478db4b4e30771802e409b8c1ad4ecc9cec1b7396e664645cce83a40d512684e0b2750d8445d2180be5b4cfc09bc9fffc8d6e49b49d68c4d849b584512cbb55283722ced5566149811545609a4c5459f523c1c76667859760e690385f65768331b7654c30b8c0b26f2b8089a3c5b4f21eed42179c54ae61d22736512fa3aac6eb018946a47cd79acd545719c829b304477541ea92b10a1ccae8b36ba83d5ad83083fcb51df653ce899227c52581699b7150456cfa1910212f7678056a33755ddc7d0648164aa297f196057060009dea8d87e86b6abc0106a5536d7c83933ab12e294b4f50870fa0bea16ab49b88a60ba7790549ccc0e6571e81875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a5e295e3c3231f4132e1117b835529456a53d3d748c16280f4d597573685b04780f611094c665c66164a1323c290ba8c8b1031b142a3b53062ad5c59d8d112f9926e5aa591aba711ee2ba1509aa09b86c60a969020d74e238b849374bcae7788fae61296d5ac7ad0927ee30912c4287e3981b7851d5823295076365196bfbee4a3cc189020254f31b06fd8d70c43a94cf380c01936465a334fa59b3d39296305dc8b775269ee204639bb3a30ac437936cbd734a5c6477b2a451eaa0159e571bb12473b77698621d5247eb5012f608c6f070a67551f6f63abe87ba12a56b2b2dba44bf72e01c9a2c490579d2c103ce91a841c4f4b3aafddaa0cc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d1421aa91216bbf56bcecb89f11588b4085a62ba0a47ef9a184c2c9346525ce006ca4819857fac8b1498c9ca1222175ca5b01b6bd502f69f8977a0b3b04987a1897a8f2f20dcddb098ad070d15c15c099a5672c17087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c85971fa10d465970d61446f106cca6200f85eb2de2947bb4ec57e58c1f7be6b6fbc025a4a41eb05c516578ae9ba4c197b692d20976116ba35660cc5b612b616269a837012230b65f2913e5d0362d0b510f1272716a4dd2832d3bacc914929ff33354c01217d8a0745c9263b5d80a4f497d99d98a4d895b59a59a1dc173ca6945fa54c398f351c8c3ab8d66cb8971a68157ce3ce82104094fc83c7306d242f1f0497180842beb8e126988c5a830d2a39c2711b033490fe1d53e432c7a453b4ceb05a5644253797135231228f246bc6a1445efc16b2f2bc674327a62ec32dbc209f2c4a5c600920d2856dc34549bc4656f7953e697cea6f2891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +ciphertext = 39acb3d169060aa5a9a7aa6d76e53f8e4cd790e536b1947c3f0e5c084348c8f3f5712ad3ddf33d798b7522fa7e8f570108897391abd2c0ef86e04823b115adc2f106ca8239a4f8a52d38653c256262aee0b5560b9f74e285ae1c190d2ce0e0eb65668087b98ebc9eaf32db83fbc09b83410dab78038cfe192ae229ce2bc82fed7d653ca71fef58d6f3ea9acac45967d09478080760dfeebf095d0bdf723836903b8fde5b3e74cf57a1edc1d178bc29c6cab5c4381bfb591952bfc70444951193c3bb0fb8645c7d9eab913d64cfdb76e1a2f02bd7f9c98c8042146c5428d641a79046d92aa6f926d4409f62ba47f73255ca57a781cc01f2a6c1c5bcfa890ff164910e4780b322c4f2a0ecd2fd2f8fc7a2870fa3c636afb0910d25b4c56e060bb22e969a37bcdc29f3a3de70bdca6a59d803f59a942694db2cbf73de3a787ea166a1c111556c1866468898539a7f36f2ed7d15324b76879af9b9b70bf99546345e0ec17fe6f1311e9f438dd92cbca8a02d7c3778f5b88f9191ad12395ffdba04509f3f338b0494ace5d52b1e8e3534b901fda4001d493f9b83f89a30ec57a5aaf4d5102b82b0451566634ba68e1f7e93cec122e7ab4f250bc78b6df0a9b7d84a4de5fb51e1b7381497ddf72ecb010832b5e0dbd34e41e1189744174dc01a7ff3eafcd717dc2cb56cc145b6a8dfcd404b748a1dd9cae69b1f3db48e414584d1cb902904b7652512a9f191dd7a95ec60d1387e1bc4b6943c7a6bda205343e2e67583dc06c72495722a678ae50ef4a8eb0caacf9a41dc13a56c5dc3e2d0b98d2804fdf7a43d0fa2d20722405bc002d71432424c88ea9dbdac6e8dcc81e660e85e4c650a90c7e6d0c50e5e14a2919b399b1838bbd7543bb95275e341ce086eb85eba4dff4c9d3aecc99829efdd0d68514fc304e5e2529d04c9fbf79897620d9307605bc566fc6ae6f176a25ba26859097a241974cdec07837a0c1cb86e00fc8f8a4365a7c348379eb60f12e0b1253f297fabf6e6b38c9cb226f14a4ca9dbcb1120969fd56c2ab38dd075351d33f853ca3c24f4afd756370b0ea4dba295652354b89d004854cd89f57cd583b7a7a415e48e4a5e38941dbcb1c0e5d55c479a871b8eec04e4d5a73c93ad1a7183093c28589612c6a4041d98809db41238efab617150bd9f9b51a279682ae75fe7a057cee50f9a98d6abb1c7efdc2a0b1c0bbede9e1d19a2762047ecd4f37416a3f86dafa241e078b3defcc414afe25cebda4008af5a356d10ff83dbcb6ca1e71268f60524849dac904d7c0e638fa3a0716141bb8f5c019228c930cac73143953e4cc86c554ee7a700bf5aeae2c8e872da8fe7c6f27d901bb74d87e1f1626fb53ee3bb080c21fcc41f828032214a738e28a51cd5085d0f5a0b15629268461561ed7caffab7f22c2d00a2fc9276bb80e9964d0bad8a5ce2b627479439a80587b9e22e0b579c59b59ace59510c206653842b2a4a75d38f2c7984503ca35a62952afbbe25049ce84f5eed70686848790a96f42a3e3572f130b2 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2ecb7cabaeea306e5a13cb82e5a8be86eec2bdfd6c71b969678f532639b57b9e537e57de8514390949cfadd8db0e5c3ee3eca86afff25066dd8896b5f6fbdfc6fcda6e0e760daed8b8af6cd89d39bcb3cf9fad4330ed581626cfedabc12f758b407c8e9dfa373f45c377fa6d41b7f05a83f2b737cdabd8e14df437e864c4abbb3dd084964fa7eb37ef4406a7a7545af60e9e7c0ef95ccf33b1833bb6d433fbfce37b970d4ed7779258faaedd9abaec5d51d806d6eb85be0f9599ff28b40587488fa376729685a8336c0eefe3f55447e2c489521eb98e73bd784bfd08a6dabdffff6f894ae5456577b8e156c66f6f1bbebdacd4d1ac43b77936f23d60d43d5a3893a82588ee489f8fc59fadc16b31b2669882fca1068e603c5ddf297b7fe85f5d20f8f958099b2e1e8ed4ae4a8b9e57325f5c470b7852a9b0ef04b4a4bdb65b4c5d7d486366175540b9ee752993ba979d8a446f94088c7c4ad2fd6cd520adda141957e63cbd71bad12dc6da02b3872f3a623218a6b106f9fe8580e97f5d9fb647f128c2519a8a0ddd64977e616b56fb849d4ce72ec95ff44697ca71cea3deaf1bf8a6448a1c6b38c158d0427683b71c954e49b6a3b978417b78debea1ba7f9b8926db4c7ba4a04efe2373f4619e3d82d655d7fddb5b17a6368f7d8a0781e12a68c536ab419d9f46b7e73fa9cc9a9d371dcbc0b8a433446e33ad1f3a73664a15ee409b4476ac1dec18ff6ebe968ed8c6a9d59eb92f234499435e2d06e6c849be5f74f2c8bc9de9fe48a8cd713d93642dc852b33652298de0f03bed7b77972c797add3a38651b4c11ea968ce53f10d38df426d1010bdfe557bcf5b3328f2fe50a8cdd76a8e2acffad2c1c7661844e6b34b25e7a30ec64b6e7e4f82f48344bfc6f33ab3c428c76705cb9b1e963782ec9ef6d874027d13384d8299fb4af17474914ec606b3f67ade46cfeb0c9df84508d594f265a8fb639e209c9b7fc418a33daaf44dbba34c1c66b7d5719e8ed6caf906f76873dd58cc7cb50eec762aa96a60e5b832e6e204c58221ffcaa84af9c1fb9c9bc683747a2724c88e75d539779742edca6a6a6c5f5d68faaf73d4cc7aabaced5f4aeb46cc96c9169e2e807aa6c94ef6be6381216fed2dd7bc9164eccec7e677fd56313cc32f63c628ecf3343adc9073888d575705d8d660f5bf659da5f7be64aa4f466f6dc451dc72aa69d2dbed459b890a4dbf2a86e3d44f7dac96aca21169f932a6135df7a6c05582e93dc0cae37df16dc6249b36093ecc6b993e3d455c2f6e695ceeb520c64078bb552a65a3bab407d46c0ee173bbc5fa95c7cbd871f3810cdcf1655c8e79ebb04a3e03ed8da5fd9fb4a5ea0d78768514f84ae5f580f26f47b3c44af0a397f28ce3d1cde4d34cc49bf6b3998b061ffa9a013889685446c6f81b344ec08e8300b0e3390a881a3a4937c5efbf4745b069acbf63e5b9955aa4999ba827bccbbf776839f91a90672720591056ffd6ade834886bde77cd78b6d61305833fefa710ebbc0dd17f9494af85acbcf2708cf93ecc76b85691f2dbfa4379c862e420c33ef694f9bb5c76e69378f6ef3475fca5760a5be82acfb4fa955e1ed931423b0a625e94c36f25bc538e2ebf9b873b2397a7c7ada2f4b0b589ebc97c50174e4317ed5d9cf2878c924937bd258bacbfc83283a218d443d8ee43f8cf3c64459b189e6b3ad100a6c6a3ede9916f89b8bb67cac332c0519f502a4c427f5c9af1a16a59a2122521a0c624a20149765e986339ed63567cc29cff15d7e8ac026c96f08d6ac4e057db4e66361b18ccdc3bcffc300a996ab7346232db7310662c75b39ad7aa080b23763ece54960397b8de836071b8914d56f95a681accb8fcb9529e5e4cfc2ec0601f7b0b291524e180aa0a69fa74ac2f17aa88162c481f51543a5a527da5c42b59f9a72b14dc91574b51e5806ace3f022d1f19e3eb621560478bb70beb8407719a01e16313d2f0c785e3b9886f679acfa465ba974676c0689a149ac04996f4132dc4974f2fc322b56115a64b0b5dbb8dc71869cc655dd61390b032f062b024bb71505640a41cc6174b68870da11eaeac28ad061f3abccf4e12231655eaf9285b205251ea69371d90527793495835715ac005868a78b1cae80025426848c4ae869b52034bb266e1b97480aaa7a31e384780442d9933fdb750efaeac0bfa802e5314d28a17d374caa05b46121e16362e8341dd923a66872df3c942177b58951c40ad1641f53a53d8708ebcc22aac67ef262b6155007dc6880a1f45cad3a5312b282055b1e0b181d9b396591fa78dfccb9d6a92d5cf8189c14c68cf4238654716f0a1e4f2542cd35a7e4e2185814c1f5b16d8c423213c69d5958c46960b8df589c185087ec5474df3c5112b5bb6bbcc6ab7160abdc2ab28801d775caafa049479a837cfc8847763559ea86239889385baa43a2848b489087fb43aa20acd7ac05606767798500f9271271e52032f21fc2a82d8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851116c2cd2fa4671b95cf7e60bdcb4976a2393647b714031870b1a6b2d486a5cf2a8093b7b948c9418f3a27f6296ea12336b8a6dd5a5715ce9a70dc6978038369a10332e3ab6c2971961d5c66441abc3290113b21c46e96c509aaf09e658d9b77928935b9a122e42bba23f920b58ea48f3f19a7924128669c09e135f772c275e55904400495153a691794a8d182ee1314446371501e87c41a944f850c9cd288cc2ea90a4e27864c79e554cc5924c4ca9a217dca424ee8b76e49993ae4b085e9809eae27401eb9c6c794a67a31705876243478f86d5b9f9cb3295422816526439950a412b4d1d28a70c6b9794c959be155aadb39e00b418efd0664b08843d20b71c547f1468c5fdd92b9d818336282f34f19b515946a7961b5a9319d9444cdc1aba840cbb57272e4da4ab20facd5fe4958a57c3c812978fd772c2862dea8b60b30a601b692dadaaba0f361cff27c5c734a42265341641b861b7899cb311e7e0acce396bce2809f24289c5361b91cba88493991987c0aca3b070411481e154104c15780abafe725dd3e1adf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de252a4f24795e9aa631d5198f07511160300a2e02a402b4cf8aa556ce67bd341307ce5a1eb6609efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d04330c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +ciphertext = 0899b2fb6c3e1b50c82cc10ece1871e4288e619f6f83fe6c3373b7aec9bc0fd4fadcb8a1cae8c76f7bca200d22bc19130fd47fabe13d5af97b927166a5cef08c3b54a9311ca168f27252a389b41cf76b7ed09405d0805e44134bd0a90c29e28bb2488e063debef324014a7783cbc81741b0b7dc2a471ef3aebebb593d995b91eff21343f19521523e53319a21a03996e55036989a3d2eba8986100188daa5b243ceb9bf10379ac3cfa54ddc3b83f91d038c9dce1238782129682d38b605f652b73ea182b0ac01460fb45f0c05cc545808b87f84f00d96fb14915e1802dd6456f5466f8eeb70571afb129844dc95f87bb88d4270edd50971247ce1a2c2a07573d5a3efe3dec8989e9670974139102270b499ff657c2ef9aec1a1ae2a6a0ec968e58a0bfd58552bc4ad2de49df561e1c59c471990044dbd6f29ce4509a92466337704fd9deb5452b6d2558f2f76d6cce661414872dc0a0b9faca3874a9baf70c07e72562941e9b74b027818cf9e20519ff714f743fa7a53a778bb161739efb49e8cdf3ec9bcca18a72ef9a34f3cda4b313710cfed57e5bd7a6801428f7eae5b531744d8fa5d7aeea0bfd0b58d7585e328e065908fd9b4b853041fabea2acca4875cbbbf2bb73cd8c876fffae08c5c91e6d0938539c1c6f96852ae9c9aa90865f1ba78e5a17a00f8656ebd1e52024c940995b3b38b954d1bd3267636c74498cf4a996ddb024db76445b9d34687edd5ef67bac73c01f3a334bfc866a2fb036d2b00972ee4dfb7c6e8748cfd69698e0ffd9d9062c00ed57285cc96759fb99dc1ce49e6f76a18034f77fdb1dbb83b8926e37ffe62662e49a8f42d7affac1ea512302cf7f590865f01aca869188da43018a3f21a15b917e2878500ba1d1a2ac7e87c0f06a23bd20f7ee2e7399fad9a0f728161b6cf3ed9c4e57e66e71deef1838a56a70d4b59b4b49e0411ea09c91bf5fed61fc9d1d164a9176cd5ea8cf7639eb9896529260a8b76e2c26987278c11e0129f3ca598290ce7ee82353af0f99e15baf1470f6c3a2b3dcc141fe2090f87fc43cbe17769b3b7a5ee05cef079d4a153f8f160744dac6d5a8b208b544e51e75fc9a332c5cf95d39a27b21d4f98ac411273b9605068e167a583f8d43d6c764c6974cfcbaff4966ada842b9a60607b17897ca32793522da30460fadcbfc25e053d3f14877852769bd2d55fc27363b8e9ece93d9194dd65305b0b251479f0a90dae87758e08f0b4ee160e3c31ffa7f1570dced7f8a8a19f64e5df2d77c51696569049eedc6ce026f9228a01aa3d9a9a2d8a571b124763d1c9456fb695ce0284ae655c64315debec95c5587d25fb0fe9be32146733147cb7988bd8e1d9256e460958adbe92dd128327c0d4b7fe9443b01628260ef3edc66da4242077f1b29ce31d9b5b31d328972652e81b7d96cf4661ea5910343cf07007a5a07a87eac17fb52813ba186c499db08b584dafb6331255c53070a5795540ed2927ec82ff2f0cb4e182ef5517b1110646b2216ed6eefdc130fe528faed +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f3ac3178bc3e6c9dd2ec3dd46ef3f88f9cc63c1abd0b14a118e5fe2c9a998d4c67e30e4415084f520945f55b985adac8c513d79789aecc59eeb7ba54103fbe8823a4a837786cee40d36dcff5d46186588f50ef419e0c4ba1c6e9567b9d8206b53bcef8974d52102f59f5d685497e498b23696b4fe813d7a544e77fb42ddb34c89af2c63856fb43bb0a74a6073959eee99c4d98386984847962b353b4d81aaf4cf65349d8e97db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b58f0369799d45fce734e5cf1c692537a48ac6d3b9dc741a08a66d874bf46daad570b6f204e33068aed900ca87dcf5e91c4ce1c84b46d3c5baad46fee2f7269fea9dba968f0ff7249b3c6e4c7c19e9ae3047afb45ccf4f53d4a81cd9d37bcf8a09f4f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773717d46c46fd94ea547d3d50ab35e953464f4e64d765bd8103a88e448446f6c8f376ce5e3ca9a98798639b83638ada857becee3c77d5471975c51b8088af6348babefd234d27d6c055d3aab766db28dcc13d343a7963dac868b5f6ac83af04b8d8bfdb64dabe9df3fa5c2bfc2acaccc4588c1caf6f556faaa6cebdbc36467f346a1ab5c5841ad7bd33ceb54d93659bb0451c4c87ca485227fdc0bc3674c4f75078cd2b9a3afe6ebfe464e07d19fe594dc4968c547adc723c1970cff7d5c5d33e3a4533f10f8655c6ba44bbf2c2a4c85b8fb4b6dcc09775e24e43c985459cb2bbe519ebeec6f348d017a785484802e9de032fca2313b4fbc465dfcdcd4f3a5675e33cf0db79145867d6fdb8f44d526c8a744929728ceccd146b6e67dd3f660aa4e3ee5d200b5960f3a03b67ebb2e59160048e499ce538adf7e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc78aed62571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c86565d3f2f970071b40f6ba3544c64c418871858f8be6057a9ea7f6326d4901a7870733580c6ab8d4bae8b49cb4d567577aa8b0ca2490edc68b168583b8b38415e3ff5558996cd9e1a957d95153dc3607e813fec57abef327d4ec441c980c286b71b3e748ea54df2a5580de701d3e73944b7b411e7ef9dbd8a8dd3d4563eb8de4c753f697ec4b4303448c261bd783d8eed599425dabe68078f8bf795c8cf65a95f366bcade10cc75d3f6d64bfee7cf1497f36c48e68b46ec084e7b2a876cb556c705c7ddc387d75ffb0aeec9071eff7af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94b9f389beafbb64d8cb2cdfcd3c945e39f3acdb7e16a45c03ec3298b3c44eacee76dd49b2ebbcf3ff9a2d3b7fc68644541de0e15fa0d357809009cd7876d4a39898b385b70ad7b3bf1eeea83b93d54f6f502da3d0836fc6fb5330ae453628501315dc17edec585f884e49a82a5adbdbc8bc2c7598d558f78703ab4d6d7a17bebab74d52f41ad6d49e5cd048f5f13cd69d956f2a5662e068d4183932b62e6ca76f74214acf5d0ea7f4c77ec06ffdb786d68fa4e51f7ac3394ef59b53bc48e99c51bf60fafcdb7bd3cd4fa9b5a6cf588dfd98fce5aaefbe5fe75e355537953d9b85813e3b56336f0846c63e2c3018bc8733f05f8ce3b614088a787669205ac9889bce2d3b523f366f4bf811f004666b2b654431b135d97a70a00fb9a3928c1a4a2c7285f6f7b19bb766bbe6b966b4013ec06833ec6f1118a772c2465d81b77ba740b7ea33129218542a41e2f1b10f42bb42396e9a6c5011351e783641aa692a982272d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1d901855bbb2b68b988953ab63607d988999ed96e5a4b963497a061ac69bd90c4eab7c0dc17820b6963b0293d4ca30d82f5997a877a9aa71c5c7893c1d153ac6779d0a88190b13df828bf3afac9d7ea392fea899ef844535187af673972399a5fa31034c02d70b57b97434ecbf3b1985c86ec75b23ac0afaa67225f12a257b78341966bfd2569670680e012899c112ad3873aaaf26d2f4a5c8cc133c92b9a446530c169b6b87b118d03329374a71ada1778a2035986ceae200c763a12b6e2b2fdb672b4d58d8be640e61576f2cac617a5ada5d1b874bbac9d272ee4c881bbdcca1c9a84626012b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac252bda1a83ccfaad69e38ceda6b149c1b3ba295fd5025c63225ce88ccdfbfa6b3950cbcdf96e14dc0962745a5fa32d10525f71d895a2085620c89024d922359741be366ce9038aa3b260320a456858a7b8d01bca12316e9c6d1782bedcb590a1d2ad9ada0c26d3818652ce6f3b6403c94dbcd1424d090e9deac559472c9ac19cbb26c16e8b27db9140a1161ea96a171728689cd6b6ba0c8002ba6c46719a1a0c175638770cd088ae29a7fa958209788ade14354a1b0880f05ef7c15a6786be063b357fc7521973abe4fcac0a8c26f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7d316f75accdd1911df10a7e838a7c2023ea1eb0a956abb53fba02c48396807229f492966796805e04ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf171899a911fa910dfa6687b2c28c1d419a4817abcf656ff669b587b72374f3cc20b92858361d21bb85a3b9aba157100875c993b54ccbc84db2d72374bcae29c5479cc95197e625da047447ea5797551595853651912daec4891e68901bb67faa98bc5050bb50e913645874fb7a0e51c816acc88a7f8a4ad383170a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb892aca3941cdfa7a487c13af9787a309779b759cdc037c13e839314803bb10a3ab19b7fae477c8c322bf05bd3ad9cfb0b241371c85ffcb607748cb518a6c896830b191737ba289b15288ab59869e22637c57019818801ef9a6b7160ac1b5b4d7519b41905e6687b3fa7230eb88a3c9530813561308b68bd2b740e7aa08ca72cd6468c008ccab34ab99b6773c533b3914b19b2b80bf7e783e7bd9366c8962e7f3410f34651ee606eb737e6c9c5f6d306af7348ce955228cf02d15b8abaed16994b56260221beb1a29be5596e204b9ce111127989bd2ab49cf27c976f74aa7b084fa6b8400a25f3c36213f7c2d160045d865c75aa14542f5a4e4d1459b5676491c6a3fa0a2f0319ca1a63a401c9c3a14c94f0016a9a69e64c522aee93e8b96b4f6691322242b20353e0d8b995a6a9129e961ae7349f92c92a90b833e82b9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +ciphertext = ed4b1d8efb6224a8c0139d9df0f1dfdafd3a765d70e60099d700efb4910568ca3241f67b34d34aba653d0ee0beb023b5473f34398e5e5a62bc482b81382cda3249bbe50339843c37ecba16481b66da65c38a092a970d949d8e095f474e2deddea94e1d9997001a131e738956253fefb026076dee64e97ceead6b43109ac533ebcb1a05e606f1cfaf62f956bde4963f6b91f3774d4432114a4b14091790ca9a583a3418d1a3adbca8e04944a8dabc7d636819237991837eb8144168f4ad813f56e48aee382bf8e01a837e65a4e0ebb77e5e533bb718ca1bf0374da381fcabc5a38aa37f9a68f9d70656d0381916b7b74dcac08d444f532fa357323534bb7bf1e0413c8074e722ecb22a748636dae0ba5159d071c8a7ab0d2e2b4610e8ab3291492f429ef31f22f9d9a8a209a8fabc2c2e761eafe57c96a71e2cfd119f78c4240e6ef8b0aab89d4a0acd23d319b390a18696892d33de135092fb0035cc5f7e4d221dd4531cf6cca3e0e1c9eb0607cec1bd279ef77681b8ba22a6f8079095f6762d518c7472ab9e7292980bc2486fb8cc80d91fe175c668ba11429bbaaff4dd0088782ebccfae7eb4484800e0a183e598be22a64cc27aecabecd69b73ebe3bba2170db602e9c0e6553081458150f05d50d8a804fd80bfab0cc8119a865d4e558f06a7875b885571be68645b568de8182614c66bf0ed74a9defaf039ee478d1c026112dd94ff4a89b553a015ec5e21503312d7b3e3d163103c660a5312d1b56b009fa393ead12030f50cb495145fa4bf2fb95831aba27609620c0281d2887c2e49503ef4b0dd91db1b6fdba7c133846b775bc861dcc122514a3640c0098e628c8cc8ca313d94a4a2acca1da96ec33efa49eede82545094056ca79ce138b79131ed8ab224ef00839a388b0b5338629449bd5e2614b83ca644ded974a3eea42fa7bf75410a1c52ecc691b9bcaaf751beb00d0acbc5e05c5f1c6593dc674a049f652c2774e8337a72d94be074ec12863f37e6b719993c010a449e80c49998c0b7771abe617811e930300ff4302a3d1901a8a2b8fd5d5a569ea76858dc51c72cebc66f1a2eb7f73296d4bb251a8e9e5e33fc73308ba7cc5412159c0700e8d0a6ba332fa23386c06b4e551c849f11b00deec734870391cff398079a70e3f4f883e5b0c2ebf8d6a52146e62e37d62fc9c1ddbd8b1fb29d6c149d4573c435199056611b3bd76458a02f7f7daacfd2ef1b1ce3da534bca74a4bff0559380569275ba97f51538edc74844fa5a034a2b1b1e99f03de9647172365abf7cf7f3e94f2dc0fcefde3a9a6cb44d0da22d8bf35f9445bbecb3941ab70f0b9a7ea7aac71d6c49789fc72693262aba0a6a16fcbbc0956b8e04b4446b2791865d34fde941716a13bcd76729508a92dc7c5b2d2ff8160554f5fa5ae3cf701aed0d13128a76d0d0ed964da3ae47e50bd49650205effc5fff4d1dc1dbd426aff5d387b47ff9c54d7f1fc4fe65d60600c6f4b98aa53b0fde6a8e7e6320e8e0c98a59cb8aeff013cab388f5ea822 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3707d9958d38272fac6687b4b15bbdbc1a9ad7467e8ff4cf45fd614de74b969eb9c65edd2e7d84bb57ac27963aafbce48df8dddb6f32f5adc634d677a81cf26fe6706329ec05a54afd0f6080877538f63df93cc6fdecbbc0a9a0a52e5488eaea2f8beea8f8b917f32f397b94c90e70bce4f3c2feba4c736449f84bafd6711c0d70daf7fde1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2dce518fa4bad4cf3439ed6952c9317d198b0d2efd79a89560dc3361f573309fdce5de6ed448ac2feff1c8ea36027dfc27f640dcc394a7ecb5079978d05fb80eee5c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb525dfd90a54ba793c84552da7c3cf9e78a9b8c83c310d88df751f7c02a59ab69ceb29a5fd001f96d0a4dedc338df4eec1c8e34fd0dac4d5596f98afafa99bee8be46bc0a96df51f639ae5b52239d86229b5bc79ac020b61a57cd4092ce0cf9940f798a9c50ba1f5fb30bfa947f20b62a71fe5c5a88d23c7dc0e299c53f49a1ee5e1ac68e2568e33dafe95e1fb5d783e4559ea79e63a88e88ec4234e55abb5ca92fd89c0d6d9cecca32e549b0ccae67da3d7a3a64681b8e5a69c5d7e78775126f483e7701447d34f0864d8d53201fab9763c7921eca6f21f47e7ea364298c1c3ab893549572bec45c1a8c3b88659cfe5f6811bf3f2095aa7ce424d7e78198ed9f93d63b52547b9c731f9933622a33c7a8b927b6de91593488faadd1243e0189e9159c7a027c39570fed9394ae67a6475cebb492247368483e9d26e490ed5f396d7babfb638bdfaf9f50c9ce383e4fc858455f63fcd7dcfcb85edf22f74feeb45a124ab1b997c917a550c3469a1ce85ec0f38ffcb4dcbf751e12ca17b7eb808be446eb7e80ef3d2e6998ef9eefa857c84ffc377f5f4ffd51f38a5434522a9e6a715977025b3b4b6d60f778de7e4f6a2f95927335cb30fbf418db8510cc0db1fc4eaec4bbfb4f998ffe504b8c5d336d4f1d66e8d55b50c393f973acd38af36db595e3ffd8239d4ffb5f9f43d967181b9b94f55f1c104a8ab7f6dec057abe4e9bc8c6cf350c91acb78b094fe4504d9f78a9f652f3deed7ba2375b3245d877c8e8b874fd42717ec95663349548ea2c74fb1538fb9945c759aedfe469cd091b44592e8105da96a479be0ac6b3ba155d35abf8169e6e93e9bad3d431945b852f5e9df11f9175bf4a32cc9fb8b6fde96733d153a799cb8fba3c86ba2decf3d4a97bd3b699467991a5712a6d7c27274d3224cd1848c17f1550be47b71b1e9873045e215bb817cb92c12a7bdc6347df8b64dd686873e8d0b477faade8af57df995546cc38cd6f931fa54745c55a7e84ea85cedca7b980386fb91b8ae677a035a4547b584887acf567c8cd6bcf85f7ff460dccdb73f5ae0993c9894e8c234895380c55614facd15a6c016ae3ecee6cdea4be395f8a9d244231adab053c568f3ec64d06a3d7bca0e62d7b7669811a45e2f8ac6887137b0b86f7d35decce6d4ae786753fb6568cc5f2b297e2222fd8c1849d1f75cc4fb951d2bad81ada952998b0b0e938b77359233a76c135897faed59cc5639e978c12c6bbfb735fef4bcb1e7de80e0fee964435fc16be2cd2276b7bc78ee8b5c963af2af4673a93940b429131663cc124be5a706bff5c157dc17dc5cbc2a11418dc4b8a28c841c5a831b1a2ba989a20fdd17dd06706ceabc0d20714d5595d54216e9fb6824e3272de0a1e262aa246494152b1cfd95c970f38aa35fc0337b26e76c77a0a76bc2c57b80757550b11807a423b85e32ddb537ab6d4694cb8b9ed58b11c9a6acc746749c21011a66dbd7896329c3a31d0a7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1bc1a133a41565305cd4a09fbb10934e7a3d132bb0eb83559c484ebc92f7cf93e445020b7187e2705a2d1a8386c008ec7f22fe172088360cd3fd160e7020b6d0c747ccbbeddb1b84fa7549f625dbc064621fc2e13f720188c200c1ac1f10394fe4117018b9640632fbed570c942575ff61a7149a51f9993b90827ea2a08c32a330747ca27ecae452154ce1a6a67a8b63676998af929e8a7a9d2ab709e2162a2e0bc0721bfc7e49c5b2c9ba975b3bd881aa3782391f5cee4cc1835c83732c84f54b373eb18869b2c90e9f986a0ea345cbb020333893b463671c95e6aa07193d06f7e62bf4361cd0009b1e528c85d147d0e650cea7b0c67f1b4fb754bf2f1a7b9cc621d4c34682a6195776bbb9b2cc866cfa94c368a2b4b346c75a2a6bfe946cef09416aef21b15d3c72b7cb408141608c058e506271380841656963174c70e09c1f593acdfb9bf4a3a9387b693f882495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b610f00bf4f4a282f752a070582f2f3c141e168f6fa037f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a6f82ecf8863c1692dc2073cf517cbed3c362a853beef1a8cf2247000cc4cd8176ce980d683b8ad89b3eaba3b962624f5ab3695fa10a88055ddd664a2ba0749e439a39c6999496999be3ba7bba2ffe06388b1a6c83068ae70a1c6f8a36e788b8aa148933c896eda61efc86cbb7d5c9cc96c9f137c6a9210347289010979bc1e16700a610c7c990d685550f537ab0c45b2bc57e5ef4c08b2220961c6e17e95e2e4482a4a94da2e17b6854ce57c263d69429e1566bab646fdb216e0444cd8fcb7df4168ae66223a0ccad971583b5917c4805271a17b4a1e17462815cb39332699ac447332a3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd2131b98aaca67343cdbafa3db35661c38c0ba1e18043a4c945067adee46e428a16011abfeb58c1bc8b2330288b57cc319389921857c9d015a0471128c34cbc13417db24b91a3567ac299cfa6d4c2f1123661a3ce0996111d340d9613b966955c6a758fa7f3556f6716e5ac7ad3a93174b2032a983cc0c73c0de302f9f83a0de89a1fb576cd3b41505b5ba712c387730c45399b8cf0b0e548cbed984e7bb5095cf7263b05cba437ac6fc369ebca85e0211715133bcc314723d79c9b93abac57ad3d3a5e77f2986a3539eb795a5b4967ac7753115b916236a97900870b658b9d4b3e35827e1aa9adc3500fd9ba18fc6b03465903858c61c1259cf485338cb700eb731f31643b469bb259210cec78c158e3290573c5228518e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147fbdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +ciphertext = 74bed33073033310bbce2a4a3856a92a519570deb8779e7b4dce5147f198bd71ee95be287839ebea96cf5b1fb11f274d63ca2b6d14c15e9cf2394aba065c27a94f7c6f1eaf6ea0655fc0cfbf7a773abc14d174ee861e6bab3c69beb678cc362135a5c2bd55f811edfdee774efc6c2b6675c2a94bc44845ed9bc711cb657ae894e80db0027c88935be4bd91966aba98726e111a549af8664dcfa9a343da9db39dda10ca22af7365da7a14d40dea90cb216c902a9dee17e371a538c85b7832fdbf1c3ed0721527204bfd7b75bae01f56a51b2b8c995ed7b74c1222d849a6df69fcb5502898c3e578668595c405a73514939d9b4a0be52c8e7846765c43771083e49ff08f3d06df2252a98ac8b096c729306b47c07b8000d6af8bca84416d7e45fbd749ce32952ef7ee2359bfc31ab36491f4445f231205d0766884d5ba5c32e361a269605a2836b092bb611e2aa1e8d0a761b36c3d7e2cdb14755ad1c79c104f46ae33f615601033a60ef387df1cfc1e2985f0052076805eb9900e67bb1e9048c6a303b6344422a714162c92c9f724311b7581e18b214e27aa099f507c1614a1582b1ecbcfd23b7809976ca80cc6cde473a7046207bc0d29af3fa4c509adf1f199c7171bf6a8d029d7a19e171dd272a7d95a268c6d1f757a65e4da37b8a63e1ad50fcda5acc1c377015bb942b946a0b6ac718ce4caffd229fa6f1fc2f8e02087c72dcad9062d2b7905a73830577454e6d63b602781056a43d5c0d39450fab97b35fa77456812bcc48670abfaf71cbab2e8255b5bc8113fc070dc2fd00d2cd5bc597631bf798858df26bd5d9398e0d3be2b8fe7d6fd5ded8b2694934b5fde4e1b713453b9397b2c8be399c1c835815485518e6ba6e8854e39d61f474cd4ebd752a61e06d7b76a713a7de9e80c6d34dc4069d0492768659bc8888e3d5a7462f820bab3adb4547e50e9afa891aaf477db8f24bc620405533b2e997f11276043eee6a3002ad901654abf4f3a89f9726c50612af40be942e809a2afa71c30ab00045a8d12cb57896e79ea12989dc79ddd43bc1542142c77af2dd2dbdd808f5d2e52f709f18fcc908338e126ab921879fd1931b720ed9e09c6c1e57c58ac310d8f5149037586a0bae9d8b119ab91f8951811ee7426dea158f32a1b7140d4e9402d68b26150288862277c370a4bbf6c296f440a55412cd1886f69d064bdf1ad73a5fc147129ca5f13ca8b9c1c7c816c2dcc2af54af917910dcabd247b614f4377a236aca35c4f8d29bea865858891afecac4acc0c6726fcb3927c12878a060aa4136b4bc3419b83f64920a63707ec048b5f9f1297cd38142148380f00f6d2dde4934ab78ead5c3414b6dde04c49843f2c54598fd511a5b222b5bd2d349b3bf8c555bb3980b42c7ee256878d3a8c8ba403d710a16e39b96fae3526abaf9ea9b99dfd7fd28579689e4f3787ed8000e1876fb531014e722fd2183371677071a6d2efad5d5725df77572c5d1cc20b9bae3fe89b8e0f393245625dcad1d0531ad787f69692e56d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc865f1d549b979bd54a9b8949f5e9e3fc3a6546d7d794491351d39723d37d31c9824eace39f7e27a97440354ee25c7e4fafba4ba8d41e86bffd8d8acc2a69aea9c809313d6b46baf5245a505d48e293a77ab4e74d2cd95b0b4a45754a4a94bcb01d4543bf7c7dfffae2009408725c58bc76bde03abef3c4ee093ed3c7bf6336d9707b3b862fd93e857902e5fa2a496e9b1fcf0dde7a9245eff7adff38a7de473076965959b2aa3c79de3eb98ca984783ec8abd929e05e84cc6b92a7fce2c07c8139a62ca1ef16245cfc93bfda168d79e1c93c9ed8ff438a02ddca4ca948f48bed6d40ab6a6bdafb06fd52f237e45fd765b34362724f13096e1845785e257cae79ec39fb8c80bccec5fd687a547b7e8e3aa1d8ce5a918984b6b359ddf4711cbbbb967e6ea54a8d46eec5dc983fa2bd19e1bdd7df9dc3c0a9e775fc18f7fcad6f9c510e64f0cda8cbd86502a5880ee1536eede6ab36bcfd859ce879b3f5d7add9073d668b7385c8599edbe849a4942d87a914a8ef9e196309156c9ab245f4c637080c963f9648fb2ba6f33df566f88bce79df03dfb827448f95f8670c9bcc34a9849795ebdb0e631ea06accc26373809986db6ffa724d12d2579d5e6e44343de3b98fc800b6c9e0fc98e9859a51ffdb5ad9510fc91a3b95bcbf73b3a09311dde3e52c6e734fdfdbc5dde8a54a30668311bddffae2b55fe05c95ac43875e9ff3c2acb3d4a6b53d363d5d75a6a7d61055a3a788bcdfa15eedf97c3515ca920ebac9e7a998bb598b8436bdb63550f4e6d2aea505766fa901b609c1f9d93bf7537fdfc26ec6a3b2c5f6b733d0529330e9a89601bd89de3da0bc5f530b3d62be741b0a8e8a78b4fbaff74b736fca23b3f2b4d542caa64fe38a6ed06beb5498733a38a80ddb5afcf673adafb08fdd909e68d40baf080be79cf7a60aaee3719635a15dbf21d1cc88cafee950c94cfee7d6008dda5b4a65605d2d7136d1255f07479a1db4fc26c48664297562a0bae0e89d6e9d853fc7c490f4d78b5b3b226b37101b3eb5d05a26f1ca1f33ea854ff3f59d86a40df69a0256eecedfcc0c6b77f2bec624ee4e1084d8d1cbabd0c7702f43d2ffdedb985382c66ff1b7885a80e5edf59bd8988b5bcfaecb04639bbf5b119f6f9409d8245455070da3014dfb6e31e6776694b44e3a7e433407099a51a4d870b336f547677665c7067ee81ce266ff0f5d8268731bd13afa2ecb4556f76a5dc50772a6fa38541af968ae5c59e2d04c3b71dfc722da6aa7dada277e5915ee552e48e7119c7b7f7ac984f9e9b7cc0b534fdf277cc10e7c48986f66643a9b33d8cf179932488d743f95e6595ec03599feb8ef9d565fb86ac35afeedb601dd58a8742c02a3e4f6cbf5d06ed66143ebe933060c98a4bb553185661857debb395625fc86e4bd47377b54459b45e51ce45596b9178d57d01bbbaa9a63bf444889fd8e0f1f4de08df89e1bd4a58f84348463b9fca3176aaae6c2ce19cf679bacc6eb685b9f443c2a9f3d4bcadadf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c170f9e18d8493b5f4fc2b4e739af5e735c665e79ac423aca37c5f22da7d358718343322db0162d26965d5e946b700ab88d702fd5a1376920b5be702297aacde28588da91c719d40c1fab0af109742ac26c456961338c44c93c83ab58581635499545cca66160e15a35ba4931e2b91fee68a8734acbf72755e8d452d17215457161284435eb6a7a2933c8d146a12679143b80740f68ae052087eeb988771a8fb43b34d6ec79868a0670551bdd19cb5313892bcac9e4fb500d3375ae471a3ed551b2d9c76142b22607615454a910f8578e44b448aa9200d805cf4c15eb635013bb80a65593ff578c794066f05abddb850ff976c74ed6acb4c41064fb5eeab479a13ba57dcacf7f02421603194a3cb549f08c0d700790809ee0e585dce4088f96a740320c57d5a632c8bf5dc173f0f841173aa47ca42004b808ebc2a6a1770ad9dc06027557f80420db47b0158a1d1ff32007fc058875c4f5d21fabb67bfe8909e10b51bb35c76d0605d0e6a97e56cb93dcc58f722d95f33008b0a237b711420a20269a7097396a4a98be20b8226e103cb1136ea3fa39d438b305b63fa049c420cc378392b9f911bd7800bbaaf2bdd7586780c7078dea622df51c7190841585bb16bab9a0d83625d55826e3949ae018e7c4703ca082466b9a078393c30a4f6b7b1fc775c9dff7cfb5909cafbc66ea946e6f098f881b3039c251fd3ac142029e8728082f838a202cc3586672cb6285b021c41e3c16f5787ce6e319d849483fe40d989c246f7c36c11a991234ae7fea68770c79d8290aae3bb72ba014aa1279fd13977a49b0cdd494ca00c610cc2306059b695686399c1590f274f735142639425dd88026f8be0f260cd66672a12b5c7b5c7323408a2711677f062625eb8f3541098d079c13208415dccf3ff72d1999721db3c271f7521dfb0f129b3cb6885310a0689166a3b97b09610347ceea5579650720db621db20eeec24eec2144fb523ed2d30f64b9c6655928b3d06e1fd9b088ac8b7c964213e5674757c7bd48a3d066355f0249a50548f430c55a6ca0471953eb7c67e140aaf6322b7741225931622db114ed46b9ea997974c9ae2f54b87125ce79e8621d712688b50c7a49877d52091643a4a43148550135f27bb30ea131521583f5b79255309465f4b9f2233027855cc0e7c93bb33705136c88392cca717254640c540573d3a20032c9b297eb5b02c954c744c4c6143a56eb48f1d15439f885803ba5acb524f3d54bed37145cd9173ed92a00f724273787cf1b89c788184de0905bea74fb331ddba00cda70c1547c634c706a8447145489752b0633628ba4f5286851e1b5ffb8a7fa2bbad3f92c542ace74e67aa07b467e70b6a7d3056592b36a7a37c6c7114c610721e9c6ea933742e43609c41f6f3803e99a8d5a27b069bb73c892bf07524a8b2989633c96ccf33791ba29f3d575f249c640093046d1684fbc701ac633381bb349bb7d351230a8bb1a22223de3850258ac7043b887770a307c3746002cada2826e47f7694ef51f94fb9e3645aece6273298592bf00c0fdf14c07d8c9fca401ff351d2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b8b11d0e47c323d6b3c0ba12dc235d5c310ce2c7bc1f0a8467d627568a185855750e12717760355a0b8a756468e95406d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2ffd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +ciphertext = a36c2589f709a16d07ec8ad94f92a168e6ad851e9b19ead54651ae5b5135f38d38eeb1e3ab60526f5724ef7741cb2bf962b4675042a9754227472604eb1ba179142c9b91a7cebf0ed64537618a70dd66f63c0e52f7c548906309e8fdcd30d573b036afb4c17cd882eaeee61be968c40ed5067b4d72a2b6a49e76a3d77dc36f1d9bd051bbaa501bfc89d3eea3439cbea585073aa09887d504d08a5cd0da0079f0698655ef809603d27f5b3c3146983c5fd8ab0df9d4e3f8b6f4781d35972425e13d03701b1aca48b7b9c87aa449bde4e4c37fabd70a69aadf9170359d1cd8d0c87121e468c385f099209575bbde29c5eb745d90319e96a1163867264383e6e908b9aa251547d15f8d95374e4e07b8e10e7f70758f19d76ab0d255d2870086db6070b7acc5242f92eec7a784515c584b9a831659ac86f3a610a09500b3a65a1f1c309adf2e4432111e0ccb6a2403de2d1395afa4d03de5a5f3c9c319ae0dbae6d3c40f6a4c0ca0a371991c7a4c55c21d50093e5257dae97ba3266a312e4647045780091194a40cb4543106dcefe181c104a29e2913d8d0491c0ee792b25fbb87f482abe52a7e38cae57af8ae52ef7c006e34ab21bf93127dbc744bd09d1f275dde2beb763479ea3f77db387703fe0e97a8d648a208379c9f0ace66bd442ae1254b26f0f3cb267f7fed926cafd59df43500564907e2a06eb3b6cd480b5f451f4f94562853e92974a13af6335661e69f16e265d9433a004402d9489f89e631e360c3ee3e0b2bde5ca53309df77a479371dfe9b2bf12734752127358f36a98fad6e60ffa1c3e418ac8c81c3a8f54d5fe592b079a871c0f1cf36bf2229bbfc5cf88f74757bc11dc826c589541d93e771a9870fd8c07562c76d6f4fc1dd2a2e82ed136f5e9981aeefffbabfce661bb5597e7710edcba41cec1059e96f15d667010dae62cce9bbd8a2e239c3dd762974af32e47ecfca58e4643c08e0a972b149749e4aa4a4e97bb89cf12acc2183125117435417dd3bc3d18304a8f56db2e88ad5ae15d20a7f68ffdd9f7a76355e28f8d308604b6945da697d85c5c965383e4247b03702d2cce376b651cce0c9a36f26485562f6b38d4389cb855f74849289848267f17aa874c475ec41da8e4548a3ec47a389d33e20de412d3fc37e630965a3fc919672c43865e9cdd9282f23401e49b9d110f73886a00c839905e3fb7cbf2d4b881b24d5a34a2896a6a93ebbd9cc176f5a00b7ac139f477541e8c2c412ec7ed30b01bac78595fd18194bcd608dea182c741af8de1cab857b551b7a541bf76dc6f706e32b688401435e25f9ff303ce8a487ce1c5140ae2a1b1aefb25320c91cc641cdea55069acf7d261d6d5539c0dd11789ddf6b7ffca89a2166a0ec7391db587faa543f17d98b16991c50f0d6ccd5ed6c80aa44a3ae3172e7e242e9569a1df9b1def0851d9c150d5a8825151569e56d06a53e624827c0b99bf586ec7a71c09d53643386309c74e25e329a7b3b8d0f3eeebccec064d83d98c8f1f6ef19aaf28b6b4660 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 469963001d4d93da7cbabcdacdfc833c47601ae334ddddd22baff0139ce6b9eca73bde86353ea34f593addca4f0ea393fc4595d22a7caedda8d8a8f7086a95550dabad94f2665ee14cfcb3e4af40fc7dddd7cd960a7976175c56b0b48c678fee1398fe3aa5784f1f869f0c8518037955f876997975d27a7c92d4cf005ab85969d504c768b02576aa4f63c87c4bc0eeafb09b8c0a6cd67776a0d96a5d139f5b44ab3d3e57c6972bda876e7f66ae6c7e9b42c283577219409e1ca4de08a92dc5b4e8e8705178dc1b34d68dda801fe871e1bf8ab17eebbb97cd49bcbf159b778593dbc9e3d2c0b6ead148f77a0cf474aa64e983506ceee288f4a20376b50beec1234aead03daf1da67301a5a420aa826db58322ecec7ad8bfd25c3b220f5b565c357b5ad802f6e5a35a384f1794a17efe041ff8a865a03a0e97e8cf7f45b4f590ef6082c850170cae878febb5c68cb42e53b9934de4dbe1528c570af363925ab0fedac79748b3489b7180f8eff6db702d6ae00336955fddffd2b9c86c2cc001833b0caeb7dbc9699c6556b448324d29b0f6b4d28bf48a4abecf60b4a9f923f1aa64ca849848cfefbe0a39f19f7830094e7da307710f87cafa36d3fe2d6e56a8e77f8e470af4c608b6e28908541183a5b4769e74166349e55b4d3afa857ddef81fc2d2fe3f4fb3c91bca8cae2d9cb5cadff578bd6e29a0cf07a973df62a2ea3c4dd44a5d55446c174b345b96881d76fcf785cca68545eb6be64bc9be17a7d69e4d8b5db286d3a2a9eea53faa53815acf0237b8c02d4c34766e97883071e5653946ebbeff9188ce80414c83dacd9e30983995aa4850a6b2358aa6240642cbabdfdb739fa5a93ec61ce1061aa8b5f7e316b5e7be2baea2f74baef3feebada75e2d30f5e8bbe1c5e7f575e1fd8aa49a7fea9ef6c88b96a9f34bfb3dfd4381b5c97b743063b6f8685ead9fee4903c4674c3d8dd6ef8bc81de34c43c789bd4460db78a0e795e246985547f2b4c3a095784828a6d672cbcafd1eaf32d9e8aded580d5bceaa574409854052af419f148809147133866f9b75ea397fff22ed61502de39ba5372493eff42fe57156e69faf9294dfa3f135dab9cc877d448ecb63e39e6c5487ecf931d45b4a74c34bcae1cbb965e1e664ecfca54db7bfe7f6edb248fe50076a70a9aa028670a364d13c894b729945831be125aa53f4d352bff33fdbe7c64b07db4c3acff378d9760bf7368693d938e22ed5707b453a1de7e4fa9c5a8e6534d45b53a2ba464f2e7dc056ebe31c57647e5bb66b6f3a5cde7a3a4cc107602cc3b67487a7d26f422468b5cf33c8e5a63f802cf017be5c40398f914cbcdac9664b86d1680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86409afffdc9650df7577e5a89215c8636d5c376f4596c339e58974d8430dc91af4a76aade8c7de39f63ef04bd5f1110aa2232d3774db88ac0ac94cb97720b7e411eabee1bf863c35607b6e7e771f98825acd91c73685198be96b84a98ac72a5e42f7ce9bac0d82c53a8a50a3a39efcfa34e859d0afc88c9cbc78bebdb537798106ed1fc394d718f0336baf229fdd45cd956e09a5d8279f9a0681cb98bc38cb551320031f46262799c182b0355eec82cdb58d750596a4e6bf1213490810415a4b347e13c9e8514890a0995843936be342e81c7f4971bf9b75925d61ac8c961492a85d83fa8e33c12fa37ba08d7c681c521ed4060481f58be673007a081321e01e21419e232283a01cb1a4481550dbade263382eb93b7e42470b265027a933c480cda340a9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a3671c18479db082a706768a63109d2c4224d71c7c95755ca24b056c355e9c22cf5006662b3218edd4b317b19962cb514af123245b152eac41391cb432c6caf9295c66da4e5737ae3d60023f46aa7a604c64a6c403306ca4b96fc2929aed5b4ce7e6c631b473d7d61cbcd19826ab82c0c58880d77ce8f9bcdbf59d645424baaccce334809b43acb99248bbd966c88793a273ae857946902649f97b5516fa2ea2a84fcfbc054653852d8421b6b78c289b49080c8efaf85df195ab5562a03e7099c43c439a25ab41390b86db4f57188f002129f3ea1ffdbb9e9c688ebbb26e0d7ac6eea395b698a134f70f98480e87313b79444963557cee82534e9c1cf10b74718caede3bcbd98a68d9956facd8a45e2184c16b14048b9d28e8bfbf5ab43d1b650ee8cf13148caf451cfb144656052cbaf82e2f765c8c9c66c23b0cbae0257d6000f247200ab87f93b5167478a27b42ad7681b6919529bb1430dfcc809e171a334b33a0527a1d9519c18130971c55f6ec172b86248059830fc57c7356c9bd8263f7d571d0f7bd87d2a1686a7c41db9306558cbdf39f0176959a188b4d457b40c152b7ea09f6860d4d945e78c45eb68b579d48774eb26ad43bc1be3c0ac327c80b4c1115c2cb58bbc24a18146470abc223ad51fa10eefc311f1ac02af4c7432210233a4abc408b1db484e7885d239c0c2b9c4952e577a8ebc3d6a7684e711e12db96e1f988df423a395301d2c15fe2f1abf708bc64147a30e2717f7868ff602d50fa9a3d0b3a0097259ac52057dcc14319c438e113da967f6dfba4279245b72cc86cf724c81769dae271e18c0b6cfa84b916ac89b12a1f8b05d88527ad40346775cc832713146806a2b2884e35628169bc12f67811b507bee3bbebca81ab93b5d700aa92898b3f5cb6e9d345483ca3743457fad8cc5bec2a8e7a22a41ba8b67641ab181d42abaf94d0055206b648c81361f8486408b610bb3552299316b5c0b7d301d9f1c3d55621859ab2ee922c59b11ea9f2a1efe277c534128f2cae6b598c0fa059efc2c24e8a0c2337bc2c57a0bc64a7fce190c656b529d21244eb66a900288b5c484bb033020b9b9ba3019b72387f2746b3b893a1427882bc3135f0a17f8271f9c8480eb60732672d44336b32f851a283224144c480aa302c05836edc1ac4569a6020130b341466322d17811229441c4513a2e8041c85e035113992f16799dfe8c1eef3aff8ca2f341628808a81e8b66ee5ba47ad0863c735a904565f036a85fb1203058137aad2206c303f22d3027e732542a342caf3376d6b065a745e31e865fc2243da31ce08eabbf8183b4294700bf8928da8ca78bc08490810c39747fd3851211b22f26451f6772e0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +ciphertext = eb9daf793643df194162e69b6c518b5c2dd3eb2e3a02334fe7d5fbaae8cb5b1946998a06dc8e3ea0c2e5f009e2fe5214d735c46855fdbb1d45cf47b78ace270537aab983305cb7b2d31e4587d71166b463f3ed2c21bb5e2467682ff74ba01cdf6aae255ebda0cf205ac9dde6d55a9e3c0ec9b9383f2a779d2286a86988ede3e055fbed98be3376c7f0421d629d34d753486a0e80a53d12d1a2ad0e8120687a92455d720a072e5df030d7dbfe55a7df9f144b34e7686b3f75b78d41043e945b3d2757e4625d0bf038dc9671b16c81f9c91574caa2d9ecbec25c0486c525a6b08e9dbb3de04670030b580d559159d0c95f0f962c1a0c524f10244fed82ae8c161bf97683f200a3447d3dee1794ae518a6bc7384930a6dba9e761498ab266e73aa99ab3235b65b6d8350652efb94f28e54e86e63628c5d86a88051400deaae123f80cf0e35c3f9b48a2d48e7588845bc327a07a9d2a0edb7ba9adbfd257ec2529e2bf93cebac1243c91508c0ef7b61d913036681468fe9768ffa4789ac24f44327035561df783012e768139313f5c58aca8e47302a5871226855403d9e3e862b20ae66c521135e67ecbc0b947f92cd1cf8f74b2977e826d513c66e00672b2d16e693aa088441a32b64d77387e963876ecb5853ab458ba1e4d5567fababf1c9efa0a255140c94c3f286600f04e87a1cfc5c4253ad5c5c9d7c7e614a2f6808ec8b9633d1bed84e1f6f27aaa72080b69ce6f1885cc63d9ccdc006139e67fbecb07e56a2ab8807f2f0c09d22ee1504a9aaf086656bea5b2ffb8d2f9ec1c586caa86ed3db23284f5952fe2fc4f0cbcc127071b85e1e6c6a64a87b1ab3f708b40812854cd3d187ed627f4c3612433aa2e0c4fd6709c4ef07436cf31801f6f77d6fd28b0e070b54191909d443d24e95617e39f7065066d65eb45353e80bbd11529f2c9385606a96b6b7673f258725a1587ac316dd56dd3d25bf2484d855e59d77a44272240116d11e725ac45766759dc89b3aa9e5cbe96ff7df371f4ec039f1472d241fcf233836b3da13224d92cc710a6caef02b2b77cba408539403e5a9c3f06c6984d43e05b5e278898e3e59c28af7d35a1a2fa982c7e014b185c7456a986ce41277122c50fbf2d7dc3014c5f2d3da0773f31afc83a138461ba19b21df959be21e2e9adbd059d2a141439cfe8210bfff745a5c3108dc34572ed87d3b60e0e6b1ac41e1d7a9cdc10e16ed2ecc2a20bb4669bac747726c8bb112874f48c7d618f0273f098e249e2ef0ac29953737e036ebc361a8512071d6fd3bb6d8661463856e387819ff9201476178f7683b983cf8473ce6688d93ed5e6a4be6d2fba23949a25bb2a1ae3f5634599ac8c83515d8d904357972c659ca5766105ec7108fff659f428f3100ecfc2bfc57f97e87249ed6640d47948ec2376268180a7a627e992930ac7d7cda5076ae04a1405b215d5d5f8bf98a40576615e02c3cf85aa6dac1b47632c66b947d8da73b1c6725032f70278177761ea063308d540a60acd162d83522fa6d188 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 3c14bdd913cda1ff67abaa8b0b3da5eab5f7639cd19276f3b0ccfba56bdb596a92bae7fe92845828f8d50f5cff40873918e4524cea85062d8d345783f82fd24977f1e46ea582c5445fb3efb76fa64a4eabf90cf13ab4a741d9f14c1b80b4ca617c4976c819794f53cacdb3509978a6df69d0026f78398f34cc2ad9b804679f36718255b2dc6da7eee5bc3bc78bceea8060354b5413ec4c76b30a1a8b1ebb697ff8606cf4d8fbb7fdbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895cfdeed6cf3a0e2f707d89467a5b9c662767a0d77d5c49adca983ce85def355f6dab1cb9fe744bde8c54c33d705548b9ee0db9f4fad55466cde88de9325cda7c9ba404b641a663dae64a964ea47e6f8daaa475fc9a8b66072ed3f385479f5da780249a909c92b89e3329a478890e62d8857d58fa39d3283f5a2a7f8ff6abffe2463dc4d729dd61676f7e9daff83fa57a2e56e90ab869b7dfefbeac86921f84154bf59cdfa44217dd1cc581fdd333e5a9df84ac67f47491e01ee28f0959aead891c236e0aca87765f89c0e6c8fb136974c97dbb1b8871a4c70bbdd1fca5df0cbb3ace4ac4509dd252f5bd760ceec09a3d2f8860385a4bf8d765b49c537924de0a38d1dac947c248d3ab6b467f2bb1b019b9d537714193e2f52bf8db18be216794a0467d79ac8abbffc90f5beb3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935de4f9bf93e9bc0b8199cca9d3f78c483b8e087e622ea764fb7edee14cea188c56d0b5c17094c1b7a45321bb69d99a666a7963269aed0a0491b8b5cb700a7d86ab903943dedd8bb17dfeac79355a82166459df323e17dac109c98e3de3590ffcf9a3b513b8bba449d5d1a790a8bea11f78f583ab4fe0b8ff3f3e6b7d7dafde8f3c8fb7acfd43db22f378e8597ca5357454b7e197cb4039e9a81d7995d14587b479657584407b38e886d6a7fe9b6171ad56d30d3bf8a8d27c275b7c1c3d1d1ce57145ba53df64699b969e6daa3873a9616d41c21be7ca0d55b90e6ea703539638cff8bada219542c05eb68dfe53a96e49882cd87d898ef9c3a089cc70a865611723eaa4ff33c73cbf44adf2d224422a2d501c17f4353faeb925c4033e85d3f897a79a983d857c6d24f2facff2350d5e0098ff77c7704cc74adea4c8f3a7ee7964ba1a63dc208ffef696828c46946f0b329e9d9a47b8335343d630359eb8e9b7e78abc50fca8c3aa9af967c89f464430d8e5d1959a22bff6a966a64353d1fb7dda4e1f98878f6803ec49a54a34ace6fb50e33fd88f93767e81652e341cd76a367dc17ac9c338e4ac4d6ed7775db98ae445d236904da694f755c1a6bf88275b517b4c9b896c49bcce8933f5fd34969b6ad8add604b526488c6397842a54b6657b93387bded7d36fd2f448efe43b0a144c3307fadf63dc8b6340ce6e897b3c50b0d8ba822f8604f7a4bdeef0cd2a7bbba3b4828e77c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d9358a1fe252de4c9213f8c4063c2af3c8c52ff83565f7ad04e138eeac6aa69a427a55354ca9d65df5307ce6fa3e54776b4a7af9c9f02f98dba9b669d4dbd17deabe5ed357b894061ebeb6c96541aa7b69158362a41767486ec3da09ab4335fe2a25dd6c07366478cda91c691c5ed9264f771124c1f3693050802f480f5df89d5be189da765337a69c5c838488a0a4ba7880e91871fe346cf3abb0aaebadb211b5acd3b773c9146cf97920e509dc202f79b14734c9777a567cd44a43500b5eb8005bf4c5a387701286639e6d9ac2574b33f2432b3a787039e34b2ae511a27825cba7a8e09b401cfc6123d3b4c42318e7b032331230da960a09f61a6a196dc185bb8bf1c1a6b691a06cb57f12be1e45269c56490e256a83c13352a878c724242ff0681881160ed03166612d69894951d65b95e690db46129d149afba2c835d3b138036931423d2f84ca51179466a1028d1601d5c397cc81b1b5e468869185b25095a0e5b5dd6a421b5c7eceb58c4cf97b7feb114fbc435c78857c65098d3017ff8a58f5927e5ee7712fa0c2962939b9d8c84bb6428b3902881188df17479ec01e4709b7840235ccd77acb0bb3a05995693781fb711d61f2883827a96ddace29a9cd43ec6abd4691be1a758b72a629f6aae1c795981c0d8bf8160bfb3b8f5047e1a410cdd49c6a42adf0bcafed1b21eeb95d504b1a48b1ace228bb5e1508bf05128f0cb63f5597851b9df4caa5b6ac10f7f6188dc41b02761f840caa42871c55205cd09771ac9125d6265ddc56a466249fbd774ee53756035349ca12a48237221bd53d7ff1ac18242442935ba818a3b50007a3fc14a2fa3abe437ff14705df0cb5af97561a608a3fea42a809a7a7d5491453c849dab7acd99636931c007a70d01655c7302f9a26012c494de47839c1ea2951a87ff73968dae83a86f392f021873be4c75d2b0700a3b540f50cf6fb664a4627dda9c75394032f434655755d12d4c781e2324ae00dd61744cef6c5ec9680f379a26284bf9590a33350905e080e9b70547ac1cf3ad888f30232fdea7bd2c184f9e1a9b6835401e737204c5ebf2b28f2b58edd399f873c7849cba8064b8a20c9c391841875b4963bba2097b958d752739383bf26787e64ec215974b45848185f44b8780c0714b9651a7685e673cd1b6230c5d6639ea5629c20659802bc6f2b95df274836241165a524ea99a941312fefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2d31916522701d80252e9c7fbd7a17d306a4e1e02cda405f3f07b38eb65824d5c9d8b91f7013784fba0df0348f21b00ef5a325c745a829714a5b9aba16acbdf029771d5415e867590cc5a57360a8969407f0749ab8a08a65e37e70146fc1b7bc40d789eae83761e77749a07859bbc046b5a87e3a92a5368251127f12d27789318f8b9c3c1f79211922c852a0b0e10bbb631599190b49a66937920b3f113185d89c6e37da5f7ce9c12d37c12cc24741cb9a79446606eabe8c9ab06d8963c959955f198e03a0bd127242dbf2a2180281a7b65f54c28ec9c6cafe64881d6456c07607cdfb89e2ca2fb3ba8f8357720051c30952734932b08b508402a6a2f4f9c76b053c12a267618928032b5d9e41990a18c2c04ba7c2868ad9f4538ff1b494707eb9da6b81374d7f9731f9a26089d7033a8c24600944d65871d313387b4101c0aaa27ae19d978653638577bcf4caf48083eeeb57f401544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d145572be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +ciphertext = 0b19df76304bbb9eac107e0cde980f205d0be113062aae748fcd6f23badb6faf0dca0b9a52a0c1a45fb39a5434d97795de72799398a6f7729dc32bc0fbb724aeb6a9742bb8e1f5ea50980b79c61da2118aa15b92eaa122bcaf059658bc763cd04a22318f8db35b6cd62d7149e4d5896b651ffce990974cfb4b0342946c13697e68a5ad08cd94b13b83a78ef022754434636363dd2314433a11c96123bbdbb242cb1224f31b1b171a30b975ea7f6e2baf749c0eae2271d33c58a247c56bfe1c362554dec75f8ac8a4d170009efef05ab92f0afcb47b6afbeb88c718430a98a09085f377a34c84922d1f48c004f790d9ece2eefca8daf3f44cd526aa074101a3ab083f05a163601b68e16c63eb293843d0aaa8e438ed68e71227959fa9baaed20eea22ae66b8de0b7c19f2a777928fba4fa17e137cc40d14ae3cb8a711cb4637f3d94f16a47b6be2345cc046a1f64c1aa0886098731cd9809a3b2d40ec95f6c7bddacaf68865cb22c32b38ddfddd008f11065167a4acea5212b1e1013d704ac9048775d6eed6ada96294971b6da0100def9a754e57b9fca70592974ac72a6db96c38c18844f5ef0c213cfb7077b11e8c53dafdb091fa81445975f38709741a295d46ab9e6b1f2c3449bf6b906a610484cc40a2c8ae35ab4311a08cc5f5e9caa90f8c5c03ca1e4c02921d24d38eea84688353ab5724ef73b16bd4e881376b78e992e9105f85c00cb30214c60e70b16e37f5d1c8997d7de9266f7f4cf419fd0e1be6cc1ff2128d3b21b46c2782af8c805c7fb7cb441ff4b5fc97a94902beaa56df272d0be1e48120dac00bee41e8795a210170eefe920682468eba45ca106e6e8a6c963d8587734baad6874229f8ccf5daef09836878e3ccb8edb7d0d3f10c466781ad04d943d478d40a1aead1537073b405ea712b6e879983d6dffda1885e5bf4354508c188246b4e205ea087ac883843d868742247a5fbb66baaf0eac8e5a92fbb8316bb5cb560a72a140ac57fdf41682729a69f2e87bd9d096ea7fe2243e6c958ee394158d70831c9d06660c46d86a14a39c8a2566588d72118eb8d53266dd16e35e3249e16aa16e0d5af04966f71037698e278e129e65de8629e28fefdf3cf399277f0eca62e9ff1f1d18429a3b06402c88e30d47aa4c1d5a9fb1cddd516ec907f3c97b0dd3076504b083004cee7db4a31d98d80c751b3a5ad56c4299434effb58b86149869bc0818738f95ed0dfb269b2d7a4747cd3d08036501f7b20fc0e66635bd89056e3de42228a607511a85dc37682e4c64a89c0592b86026d0f7cbeeef3b436e4d2f399e68334a29f514825ea8cc8e0b0e61d97391b3b62620b5f288e271365e3670d26e2e9faf37d41e3bb0cf937c446185706713b4fad79c5a4e358a3c208c37c66ab57ac40115ac256feacd89bb5ad0ae35c49cdabebee5d1f051f5ce2a5b4b23f00c53ee4adc430f8aa74f81f92871a4f6c87ad22c4d0c0387bb515e3acd8865fc1a14e9fcc5c4082fb0a1b8247736a510f45a2cc31f4724b44a0 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2d149d32d4e889573ccc5e66c597c3ff2d7cb806bd13a8a7bdf86267a93da82eda320ff322ae7a548ec367fbeb9dedd810189c201f358b59adc00fd70ed6ac681fc660c5eb5544d2d406bcc2df444a863b70ff61e17aaf00eeebaa3bd5cd93d50ab460cfdd9bc8cdc2963784b7f9798d837bbc0483001539f0ea65a0574b467856460e9b2523d0967f5fb71556aedf832faf45e35d97405d4dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ef3ee0fe931d16cc9da767c3a48bad09874f783dfa74c349e2e63638aadfb59a462f9d4c563da0b485541e391b6037041ec6a066d563f186be2ab97a435f0a7daceac0ef26e16870437cf012a6b6d18fbbb23349628af4dd8ca9ea986498a80edfcc2418c3f5b6f7ba8baadf3739b3c578b2f193f57c7fdc38f7a2dc379ab3eb6127c65352338c11fcfcdedaf1b43e50d488cf57e34e06b5ebbfd432c27f090fa667177dbf7b66003ee35e7c43d938343d67f9e22e5597a16f09e0793e664e7de945b5e1aaeb284dfb1b350ca0fc1390a97586564faa4e20cf7538c2eaacc0ac0831b477e37c9e984b73ed9eed897d5ef4cafd3fe5a512f7c0e5cd628dfa6d7875e9605afec33979979dbb7fda5b11e41a6976fd51aa7a079827d37ca8a7f6686ba95d7ff75a59341fb2f9b4c163c260c4dbc4587c50ab8f0ac777849b5f81df09f17c1535e854c35aa24dfdd497ef2ed8e45565966f5ad67251b96461950ad2e71f1996e955e7610338b89cd91c356804cc691922449db0645a404ae4a74ed158fb58f6f30c7965c246d5d66e96c8f14e8ad786801d7530c0afc5b757e06abc10518b274e3992e538922c7e7866c7ef08f7d2bb4c05ffa3322a8ecd8069dff0f8d878a8b7b1df472e3d2253a83ab84adf563dcc5f4671b05f29ff6d0ba97abd2555c52857abb76ccf486dadc3d346c55aa544db18aee96907f999e64c0b86f97d33f412b3c9384783457b83309ba7ef74abd51de6ea1d3fa246faaecedfda789dfb98f7ff378f61cfce4f4bfd95323502446703783ca9b6aa595d690041f97c5abf5414455c155924a47896716ac4543dce7069d131b75a57769fd4b4ca1a9d170a357026dcdbffec930063d56e3546f09b1ce9e3c82057c0bb89111e6b1bba88eb8cbcd72078fcb05d6a0ef5c84bb5607d7b20cdd733fd96dbbefabd963eddbe3cdd89a92646ebb56fade609e81b2c8c15333e2f309d15135c07edfe1b824b1e63ac96e64845c35c41e13e3511a5d429663796abf2443908d353766e4df47b9e0fd04a710ba5d6a5b30193fa5b70e6338d8858c3fde8219512b643b8c6dca2a9347ec39638b787fdb44ce734d8dcd35d4de24af9123dabc09b2e7c9bb26b3393fed6fd88de9ed3466e019ac92b4e6c9683da22cafb1a9ad3475af18ae5ee9f97446096647578f770ad3e7a9d4fdddd8ff5d9425446ca2a4c1df03fddfa4ce130f30bb5cc9cb49a2e294ebf6aaec49a762ec27e698dad4463dec486ae5ffff562eacabae3f59119c9ba4185678ed3aa057dca848709c4ba0c8e5814416c5688d33c819773db36e7b9dc65fb8fffdf6921c48f8523fe63ccd744de5c5363c9a9744f8a6daad20e5a62d47d17b464da7637d32b6c92f059443501427ac964fa569cbb074c71053f179bf1963ac704489ebb9936e23950e51ab7e26a98d6031c652701fa4ac59aa7c15d88c0337a067257b8d916db0456fad9622f44a928df6cce84a3e6634c9caca246208920c487b9a666342abc389c14c499785bcb91a95dc868fa20d25b08ac0e48c72e9b486151f21b11731d1bf049174adf279f9020aa98c38372877299c4f54a4493a3b20f8bc71cbc490b363c4162055cf3a5c13650db1154687462fc01b5e5b78c9f603255a24189b808358e17e01b9cf736a77d78a32520b6ddc9c1dd65a00e84b562b607b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf040dcaa766bcc18d6b8a2f91e51ed6d49aa37aa44531bd9dfa25c116a842e50f53a68bf1617245e8b7da778eb3343d3f2575ea84627c640a6509133f4c5d78151a6695245659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e647223c0154388912ed028ae364a9fa9a018d8558c3e9b179b66f2488c2be8792b1849fac0401a9756f209889fa637cf7ecc4f2c0249eb5c6f7e0219faa2a9433759ac70dabc7baab623c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d467273268a0797b8d6fe57ddfdb03fff7ad3d5b9c80dc1939720ee8810933a04f51b78262910d7e28c0eab06b91980b65056472a293f2361183125670ac2426e514790b945d6b09c9ec354fe7c895a30231d95794f89ee60761ac9b2aaa9a75ef168c0950afb498915b2518e010c3800764bc5a65c0c54b2af686b7d954e77bc4cf8137ab398fe93429dd0ab80fc846d4cc8db2b9b2b4bb36d4c4121639c1e74622e59250701302301b4df96b2fa62736b29caf0866096f842898b2c6012b93b5ac23d1f39e192002ff0b9005fbb8cfeb8930562a4e0aae7a40c5032b8b33d0760d96c7c203920e2439d3ea02372c7f5d80b92259349076ba20c3ad4fd21752a3963cc5126342a963a363c1157f33189732f7243e465b14969f1ca199af45b50851266742151a235a8ba9a595534bd6aa31ccf52b8c5885d571a93d2577c57057e2caae68c9c84f565c72681fb15056a345236b02a1e5b13289388f035a2f8e03402f8b0a44259179a904c94725319acacd28ac1e449b87e8916091940e33861a4a35a8600267f04ffc6a3e06c60858d578bec60ee7716fd4b0225e5cceb5fc5437387522200f66fc880e0c874119c71f462cb4eaa24e67be77ca67278344199b27e2a55b50f372b65345122225d7324ca9504ce4d12bc101639e93b331e3b60e1b520e03c9703a69f54c2b1a52254ac44b86f310a711263a5a9b87a7116ec5654f7297ea76b63f939c1f49ce99d52bc58876160401558193ad98c7c8f4b6822712429679214bb2b6e8b324b58e1f57695dc8968bca7ec3717df12c1279408183b49679b349e2e45686e722c3a57bd9547a65656cbc79aec1d3b129837d84a6975d018c7ab04c88775e9c68839955775fd66ab02aad69b76307f51db2ab33915aca61969aeff14674a557c322af6997b1a8d9c51445884779227ee742986446ea1719808996049038e0d9aecee828ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f20831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67ef48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +ciphertext = b7b48ff76d8b1709c67027c3f1161313114a848d6c0a3460850f2b08556a47dd82a0ea4e4818a1667882dbff42ff428caf7516cf7d32a31c6efb18dbebc69a7bfb17c04eb69bcfd8b8407b85d4e68118efee310f122b077560af4bd157bceca4b72a1b4e927ff144b0443d3fc4b00ddae83dd88c33e728b7520944cad9b1106d3c43f5c469efb9b00068668f0ee8528b0482ed82cebd51bfd0c0dfea9ab42338f3636a369578792e07182f379644219159d90ef9b309b312309f3e1b4e6c86ea904f0f49fff3469b23958bcbf00a4efea040530e20d4b8a19e7a67fad4f017b2e03224f0e2bf9cb88055743cad55c59d7965a490b1cab9be13852bfaeff93799d08875f55a765bb78bb7bd3bfa6573962a233951c99a8a1ce020ac8f2cad10927a766d4fadac01ff066f8b42bc071c1de33c0c0bdfe761cd607020ae3e2c559d77717dad70f62dbf147c86712d92a2cebbd80584f1ec5dc10cf94372d772e6087b9f73c62e7994eaaa8d3a52f2f7a623ecadec7d9cd3634e44cb282e07fe20ff0fe7c29534030b12c1d6e5894536c8815e7dcbdc82f291fc8309af952c489cbfd86560db108c731c877975bbc076435c227c3c6e5546c9c9c475b693625de1896ff066e24ce650483a2a391f31ebfb68e172641a8be54ffc35f09208bd2aa1d837f9302fe2cd7d54dfaa1f833c85222135609b4af0901daeb0f46a81dfe8396aff879acd5ab17754cef6a8f1406563f8899f379fd1ff99371929304338efcd3465100e0e7e3f94fcb26f20b28eb8367b7cf3d34f74ac992b5c37050daebfafb35919ce6703d6cb3c0b1cc40e7b6b8de1120977a5e7d09943423f0939839cb6bc53df64b387ac018fee33ac33d780090ad582432c4d61514198d74acef79ed0c8710243aac73bed13ec6661e46d1e8605634578bd17e1c94b1e705c6ef1307cd7f4e828b30d3cde1f65adfca10439ae9c369f5827b94c3f553d258573f0b7c7884133cbe8277d207681800291c139dd0787f0800763d79ffbe667c1c56ea8bfc020e339f22edde053a4bd05f345e66322216b56c168a7b11bb1e630ec1fc05cd30cc3ea0ffac9a223e3aba860783728f9ecc974a0279f307f984baadee9091ad4f4db905dc75014a29e9ba246b2edc076f7f82cf5a49c4b5f85d3b3306dd9d391ed8500a7d8c567cc25f0e25e46af32bfb44d2f57d59490884b494e30499669d5e8e0ecf5b0f8024e0e1cfb9d25d5152eb7b010398f49d169f57d7565a0b51edcd362a591686d00c6c72bb1a0a93c05b52cf13b82b08e4f28062b558fda675c5a9a2fe5a0fd13d7fa0b54ca094935971149c35c0feb38bb658e929d291920fad23f27818a5184e15a7db054e4dceaa162a1fad1ad647ea7084440e80e54c6805708c4aa9b269c8853f274a6097d313dff1e36cc789806a9acf77f1a18cdd88e1e8527abf12c3ac3bc45b506939f9cf8cb65a66f83fabd5037477cb29a0a32234eb4034692edc2ec6a8f79450f232c443639979d2d4a442963d7c63f04a8863e42 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 86cdea4a587baf3d8d3989fb4707ea97fc55fecf746f98eddf7bc215145c56d399c6447ada49f30866384bc7e8aeae60a7349747867cf695cccdb8a4f1fbb3e573ade85ccf399f4f3658fbacb9798d58e522adcae103cc9fc9675184490f38ed3516cbefaed287758a4c374c0a53e3f2cf9252be65562f936dd3f9f64da1fd887f0c775823436df736c367aa301344ee66854fb39a9eb91bf3caec3e8479dad64ee41f39914a77a767a47b61ff868d0ee411aac9da94c72ea6f4d228e4cdc99c89a4b35e1c4c63cbb3edfad6898e62e28d503cfc6617bf4d2716d1d1df75c14ed9dd9486220b66d523a8111b4de5b99d236586a09a4f78af40cacb4a737c770bc4915f55b609075ee68499654baf917ff64715fa8369872aa3e14d8dc60fdae346ffd11465f119669a0d3a7188d3326017ce932eff0c7e5c26c4d851683478e5c71adee0890ddbac577f5a8763d4a76e3deddcd916ef021672847ba0d4785ea8beb28fa364e64c4fb707e9d245fb20cf6858b6552419a4d9eeb22f8c7992e3b5383e83d14d948777c356e5e4fd0bfe0c5a636bc5416a799270e5c976cda62f3a76fb134646b333b75582f8ffc51cf4bd37835c3febfce1ea86306362f92e6d27f4dca43a45edc9554f08c6056f4659bae0ecdf9e59b6df7bd66eee447f4398addc73387589e48bc4a26b6749ca6e926fd34296db3044dbdd2d23e2ca6a6755ec48c46865a36a6330a9aa5d49e67d6d62ef1a7c82ca5c0bceb163b85e44cf78312c4304bae27d66576f8fe8c3ddc8511d80771d9919ac6931264dc2f9e9ff54e875f6d7a97772feb45f1498efbcb37b4e0db4604e6cf56c9501c6598ff9425249740eacca49e9fe31d679a5fe6c3ccb4384db45e486f1719c6c585ccc03355216d43626cd8760254ae3cc4aec1f87cd5c3f0a1e641b05c7036c9bb46dc72a0f32593dbd25eacb5a88abdd9f6e102d5ee857aa66c8c47e434d8bb4a6cfabbd8b78ec427846f1ee8a287fe52b27d063b489a3e6b8ba06b00f14a3f2e6ac017f5e5724cb629b7a312b3a132ec94619e7c07637b81d50bb644a38b8e9237dc857d43eaa3d44962d6bf63bec4d1eb04b8e7aaa996b2a266ceb8a80aa46674f26f07c6ebfb484af461b6dad9a9e6d2fc5708ebb355a67064ede931f394988d9022e59e78a8a249796c155a9dc7cbfe7384dd1aff39c29773f76e0e536a77b879eef054c5e539a391d43c1b53d69566a97de931b166c6f066cf0ec81e759fa200876d53dd7724ac91656da1266ab77b3f7f01f82479685bc43a2718c93a806c3de4adcb918c7a734cb04759341c5b1496679987aa5db93b7109d3a605df4c3da6fe8cbfebc37e82f1e79611c61f806f24069ab83d7e65a46caa74bbce0897fabea9b6b58cd34e7535c0f97b4359961df3e4a498cf87ed601e9faf2fb6163c4b27626e5121b62a8addb08e6e065c83a69e5e253d48399fc665a6fad36275ed3774f115ad79f13b8bcf4f0b44638cfa6ce6018b58bea422b8f87a678deb21c75456592e9bf4cb7cf6ec3d3c1dc5ae9ca16888e9b7fea1a863b8ad1443d7530b533269a8b692cb4522ac1aa27b01d386040edd9e2ddf017bbb36ebfd49a2c5045a63081266d7c6b065ef3308afba0cf3607b2c98d83f76f7c058262b55f7c0746b3c22437f00de9d7cb69f40afd60ae74b0506afb96e30669f51c464a27b4f177666f92459b293dc208a0dac5654a8058a8fabc2d1853009743a598bab2c248068750f01227be5a4f7c4c6948f9167e88894d43b5aa44687ff177de837e2f0537f708a8f73a11fe6632dc285c9026bb23424ac2d1cbce39ac6a0a7686f088d617b096436c9f773e7cc50cea1c08db20c2949a7878d18e7372cae746b04558a8fbe97df0b9a69090449a507e6e1c07a35680412033127037607b2f0502690b47bd300a84c041650dc748ac2c060260c933a0b81847243fb3267f3cc8dbea4cea40790f37cd0373a71ec00634bb3b3b087a82ccb1e1dab77300156d8094a1d61d1f1bb3f977b749c938ab8092d71c93394856ed133075e2bbdd3cc0f27c2a2d34bc0f633f5e55c0a6c989b1e277ee9132f8779923eb2e22f78a1502ba5e55b6d53a05137867c10536e672c7336a3ea1f237263a6046f260ed3871f1d479be589744361a0d819439779075cc47a5a33e18326615134d9f09b68b6873c6ccb682f6b75662cecdf5432c37189ae09faf36735ea01c12f9ce64f4116d509c70e0072a242ff126710d178daae86539226c92d090d9b60dc63539f51b46dbf24cc8d54eda255e0ac19b03d34f5a270b6fda6d6408bcf1d2a46824b5290b8a26a8131402c9aea052d0101759345f86a66a4d238a20c6531d792170c52deed889ac3050ff87c659524337830c205622a989736b788092101933c0073c0b686106a9b88c17958a8711d272392ac448b01507634df4a23846aa9d594c80bca99f17505ac1793f2877bab4f1b211d2985842795c4c1b9fc018dd15b510556ef89b687e6b01701cbce0b56159a90f7b2c6fc1039aa38449a596c087a62b2ee5a7c3799f5a601bfaf8b9c598834fa115ae010f71167fd41b5cccc45146009752f380cdc56453e554cc779604f976fdc34e9f135261eabffbf00afc514f2699aa6a5aba0638542891c6858c7f6c6c4a12e4ce2d89b50b04c33ef262ee8b0d9a7777d3c56c85b1bafac7052fdbaed24303c843110c1892381887eb351134798b9745bc229208b277c2c999570075903deb530bf22f7906b75db35c3b24b04751bf6ed41724058c70988952d86b48519264d25ec2b817894ac370bc081362c841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d21470586510acf76fcc683035b18c05eca7d0702e0453ae00a8144779117d7c19cffb568a3c0959193d689a6adbac13df43907fd45fbf3313d49425d32ab9d81c6bd9b3486c3636e6e0015152c1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fcf020cc611e3e2c8e52f5ae886b8d9480551d012885318e5e6c1ecee0a3d75b342667c691d19f34fc7946e7a7047097f7938516cbb6c7f3abdb85b15e302a5547198ac0b89e7c2bfbf74050970e8dc746cf16bee6147076bb89c5124a89e070a785427cea590301cea7ab28ada228ee7bc7fcc17074063358a706989c8d6c82677287905722cca0a24ff91958c44a3044787eab3599eaf241eadb932b06b151a1a02ba8b244e9262b96144302124dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccb30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68e6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +ciphertext = 0abaa530450dace740e8afd009c206de7c0d5d5e81fcfe4034bebe306027fa8372da9cd5e10572bdd552e82a2e596dbf9b6571f8a009613b4c9795d44d377353eb4f9ca13c2fcced279674bd21d310f5704ffdc74b4ad98d72648106171cdd082ab3f78eeca66e7355c012838a5129cc0084d722948d24f00a91d2be8bc44e6dd949c1e241a22341e3256f7c751b8541332ac389d3c57a8d69365bb4c9a4757dd870f5cc7ef86aaff94e26858c6f006dbd1a63bd7e09cf5e4fa6b1d2c5e03e58c3d6823a524a76336db51447a17e64ed42e7da5e9417cf0b447f32143e689ed01c4e2e5a947bdd5e2f2f701e407276c341ef766238c8e04fd1c051f71227771e36809e6a53cc68c303f190613334737bda59b4375629ac14cf16d7e98bb435b9fe348cce9b216b6ad2e6f95aab87bff03b49f440e4e284ead23353bb85c81811731705fdace139c7264797eb2624ce48122dac337e146ada469011dd6a8e3022eceaf82b27938be256f84e74878aa568930ea88e6d823514491eb9a27d956452a9aa81b9a2068d3e4fa1c27e5eec5649aa395b2ee52ee8e87033be00e7c4aed4e1375d01a7be8b16673bed2758b22eccedaee993bd26b91e8e0c25dd1a5bedbc55cab0dce5e308259efd45cbf7e6185e2792ee36a453c693da35a668d685a8d70d49d75d4be3b567fcc9a978defcc480d2f70888db31de14cf90a2f489f020358095dc8b7588ddc8ce441fb1385be6843a6e36e5775fdfd14f03018e33c5a2c027cbf4328106c33afe57b0da9700e27b3d25f905438adf34a23718cf7e6ca992dc72b32aa1c432ba1792a626fd91ceefed47c8cbec2b9cea537b0f9253cf9a11176f3103c7a98859e4211e995610a4817527977eed6ea70b310f1c91ca5b6403118084159e84b497c9a995e3918216d5ea0706c89031c2d5ebf8febd8e68b594f00d266e41ce12e3dbfd16c130d44a0378b114dce1a6eb50f227d4d43f1f8d615b7b278546bb53dde219677c980f215c8b2b2284655e596a343d1aba0e277b8c98de9df84208a9e045828a75b1573bb15ce0e8d7c39809e57d118e0b8fb2d67d72afbe8e9750c4eacd95c4a69e03a16911d27f1bc5351a35212e69241dc4d780fbd4c9dccf01bb79fc2a40f4c29f0e22dc552758c7f735a9bb13685b1e45772b47a97d4312359ff0d3ab6191e572bbf9505210582a470e58a16b3c5cbede72d07802d973e09f80339684eec8fb84ac613c4c869cfda4c6ab82ec54d8d3aa70bdf89c792ba8b5ed3c2b3632fd391e43fbc66733212d439e5a67d20f237c2a0f782f96a9e2d93adb6f1333182ce55056d4cc807098b5333541269a10935d6132fc5dffc549d99b25a1f48d67999e669ed8b5202f0ce91f3f368882ad1eb67bff3a6941f16ee6349019bd41433c2ddd70f7d5b789b000503a2ec1f48e77869240ffc649b1133374e80a16ecca2e28baee086b973aeccd3692fe9597d934af1c53668af5ba474979d2d746156fbce5cb86367134f0476f06c94c3b52ee1f1b675a67 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ce83fe29cfef43ffbbd2bd49e6c8d265cfe8b68ecbab8c9186f3f5f86e7895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b75ff86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458f4e9cd11ce0c99dc94fd3564baf5f1ec3a32836d7d9be86412fcdccebb1b1e489622d7e29264a9ca86c94c7ed548fc9c6c8d04d8e8f51b5f0077d6285bb32826e8a157c80c3ddd905c333175e6c18fd44611f4fd7aaec3314e7995ff0334c84d96a66fc8a55578e4c58f7826ee86f183e9da305d5f11f4c3f06ca5089fc1e28d0feea8a8e98d5a54bcb90d5feca1446783f7f5058cca25e617f443dabba304b353f4a5caabf1ce79a87f5838eec033b3f3d2ff5f29eb887e8f950de891495dde7be94b92cf50374963bdc7216bd7cdab8d0147fa21f0c3845979387cf794aedbbeecdb004258867bdeec5cb82fc85eba2f4510f5e4a40ad9b6aea7e5e45762076b81d88ec2bb9edd604ddf13c91e947a7d7abc2a2aa91a24d4d8756fb42aa71eb25f09aabdd4a9dc2266bd51163cd2ba831957675823748306ddf7e94b3ff0996172f5737a766c10b6aec2e3b5b073eff93c3ad9ebbf2b93ff47c84d7dafe794990e2db4a7e9ab19cc5dcd62f427e6a935ce397659db2189fcce5e4b971668c4793ca4954b4787d37315eedf1f5ad2557caef78c915ddc223d836c407936ec58825f3b2a29f5a5164b097a94a13d8ad3a27bf1f0bdd08d7fb932e5cb1b67c7d2c4a7bc7a6a9ad54d2a34de69c78195bb149e4b4cebab7904e612ebe9540385f2f74757c76fc2da3c7b03a34aa5f4e2ac9df5ddfefc1dfad84bb996e6c7342677000cfc9942cc22baf934d97a66037a1886dc51c0f36ca2be881bff86ef5f41f0cf30a4c6ec1ef96090874b3ca751de7d1087ae5f419c67eb4514754d47d7848981cd36107586d36818e74ad98989c8d0fafac4e34ee0b545ee7d7876a613f0ae1be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d7ef9b184a38d819eb6a3cf88fefcae833a68a3cb6b30bac5ad7567c788d8d8d3a7c7fffbd9af53b274b93593115b5b7a538feaf93706c88c178bab897c7e98c23b8452e9852b6d410e8afa85c902edcb9a5e87a31ca84ac6b89a75830576d62bc159cb139f77bfd645d68e7c99ffe394d40f27fed66e4e643897df22ce013dbeb426a70402fdf21c780c67bb011fb3e8cb746c1be4c9f847dc1235f72e6bdfeaec55cdf6e377395c5be7b764a41e0f731288fbf729fddd379befe58901b1eefadbceefae549e5933aa9f9c64dfff73c486b5635e674d56213cdad7637854c7b8448ae35fba6dffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cd3fb395aa73a916514533857b4c3405fc32c2946cf404f61c2d91b6cbb00def96459c45e558b5048b79cc4cb8ab0ebd7f8f320637a62f2d38d5b3c0593b42d32a38be93e2ac1ffebb496a5fc4a992aebaeb76da23988fbb3f9a79dc7145efdb5246466f25af4ad971014970ecefb36316b86b3585f7bd75381ea0bf3952c688b4cf6c8a25cd964cecef5c1c34b4cf8359caf3295dd63ad3dbdda83f072ed42fd8b7c2bb439e686b49d538cf32a05ab82372f7525df40085b3413f078226b97c234b815ec615b2683f1d9ab32dc0314c6cce6e9620c8e73b1dc85bed5205cde5a44f40427865a62356ce44751c7278a3b236bc2d208c7b383129661810a6a2962496d058ca4875ad234c2df951612e665984bbae791c279ee835b105202d4751f1a330dc6b0bdcc38fdd6458b0ca7a9bda026bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847487142561863b5f38c5aa4c0158ac28e95012c10a8b8e99ef7db12c05009311a74791c6c8b355e4a861dd3cb6fa085884d7a7e8cd270f656ce29f9bf3b91b798032c16b00f8cd722a1cabfbb25c3002324c56b66df87182504581a76297ee1181cf05a6d89698cc94021b16574264435f2cb137a7a667a4548c96f835cbbcf27805ae37448674aa998818cf26d15a63689777a9b98219ac3b9ecf84203826eae294800f5a07ffa886cc86e7d095f42c471c121a69a1972a7906abbd31003f6c8c0d07ef481b55fe185811084d9a472ccbcc586b6a9a6f24d269ab36126a3f0381b29532d027c2d5e21cc5b9c6ec8303e4b388a6b7216b3e581c0566558107c8b94c599f09c2ecc4b7a824fa3db9a29722317d5bc5d43827f4bc6d3a91f65dca56bc26de9d40bf2f69263cb010a9a24a749c931631ec2d13ea4d5136aa8a97ee019ae1291ea34b0807886ffa323ad3b0f83f82e5d9a2d748945a3ca34b9535d0460a6f734bbeeb66a4e3c257bb079f5d80f6deb0dbec130fe4a182fdb16291403f37a191c381723965c3fd90d9f2b67c36ca3ac141030ab516a01453532aa06b73a91b5ba7d1a308e286fced38f2858801022a453320a857b564179c55f0436b25cb191865de69877b47041d9d0c2c9bc42ca513f207a72ea9a5cc48b573fb402ba8b5ae6d73f2e0b044b8ca67c1031577099b9975fad7103c7f6bf80099bb51138d8a7af7bb509b761a9c6407dd9826b7ff87879098248d779d6f26aa0215084f286ac77c50849ad19f29a32b07ef517000ff71799d6be1d177508bb969d9479c6c037a5a18bf4302720e240dfa603b7f8745144906bb88522505b19336bee5572188853a47b4f8ed8a040b251307299be642e086317e1504784990f2149cb2d89b1a8542e4a19cfafd57ade9a234545142afcb3e544b49df75b0cc78f5aab935752746ee7a7f7936777330a66c1063c50becc4286a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5db8251de0267ea3c0eec342b51505469aa7fe936a5829463892645438a3a182859da136e033b926695421a1891610816e136dbbe36adc08cf00e4b44649410b2a11ef254144c27787e54cc5a533e8e54f11ea94f7e9c2009d25a6248321f04a53c31787c12aca9cc78fcc06b161701852215bc6c29d1779f5c183152cacb583a90399746f75c5bb337f1b580b9029b112579884f792ea5a52187a109f547cda89b7fbba90c66065a33423da4515d13bb5ffa074aadb0c55119065a51239511bb33288f994b121da8913992b979a59bbd64036968621e76ae336096fd6125cdac4f767a883e6448b078dc04b1f2b7aa49a1180c0f3bc65d2a93458291982652063419a9cb7f1042c38f483c4a90e17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b496485a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +ciphertext = 5794df0ad781361c6821319687c08ace02ce58cfa47ddb4d8d9659ecfc28c7997b98665da6b0e985ce869168935c6dc81877db1c88d3aeb37515cca3dbdde9eea44707066a89fee8c42d3c64921c97accb8b62249e20d248c7507d5b49a5849c54bca761745c7d2c5f83fe7551795d9c1979cfec5a0b31361a515d95899cc121934065a0cb0f8e8aab6f6789feda87579f26c14c76081ca22bd24f65c5d1824ecf796520e2ea33b9feafaa45da662c032e866b26f5ab26dfc7e7baa2e4a1d14c4a3fe70d3aea96e5a68d7118706a7869e37651524046df15eb0fe51c70b89b9f6462ee7481ab1472d4f9997a65e06650276b1fea8af04fae7746309307aacda58e3af745df5f02e9102b8c5b2d981321cbc3ec8476a2f7873ca3013d4ad3b9d1914d331a97ce1eaacd85f9145759ae255ab80c34564794d2f58c00a1bc10e69f5c28934b163ac554512b43587af22a43cb01471ff8ec21cdbc2d708476036805bee7199078b139009ced9b39a402bf0744842222515aa55d8d86d2fb04e81ee7a8fad1d7b46862cedcf5ec66503bcaaaac78f336107c4b406c4e67283b0e7ea99ac08d222822b6721f1e1669e3ecc52573d477c6784ef31637808a50bd3ae98701bd1a8831e11692be8e0c84474c9ba739dd01fdb24bdcbe8e9a3a12082f20ded7d06ed3bfbefd1f0e90ec2dfcb1cbd039f1e5c4f657296371ca5f2947b27e686541e8991603850422a2091a9ad87ad342e936f0d78e4211710f8b51b947e8a2aa98fdabd660119835eeafbcea6e2bf2895d22d264a9d558222926469d2454fc948e843c0d086ab8980665fdd0f600d03a14f14b0bbb2756a2f17b38fffaba6ade7db5768c0ab9473bc0e1d133e2467020c0ed4e53b94b722a3ea63ef74433a49ee5856848991cf9f0b24bd39e90d57c00dd86ca0bb4b3c0af67a84127a41cfc3d233ea766ed7de7784c9fc0a422f3f0d2b6432583d93d001e167765db6af0aca9b2320640d83d7b41bead197632aeff5b952ca216c0051311b6547d04f5edfbcab178ff1891eb6e42fd6c2986654b58f41c644b00785201b26f4606bf4b5c0b3d4f46d1f606df167be6584979b1d26d3f8b61a08d65c6f733c6ff2288d252052250fae9373d9b3e2b314be7cc454b749fcb6e5207d051be4fa345abde67f1603f12a5433a54d2badeb7a9f5912209b733f2682e7d39208af7a21872e4b64ef835a41e1606f8649823aa236b47579fc8263c2f812ad4846b2a8217c847656e2d54ab774fe8ae617a341aa2b3fd2ea3f6959bfe58c26a9db8c3badad7a7557c7e75ead54c9bf85ffe9e4249dc1250e37c9bfe5343aa0653618e0e651bce7dec72cb14510f1580c43c8ee786ee3ea87499c80183544a48db67b8a8435be1e68d8d3c6433aca5f42c8fdd3c144e96d3dfeb60fb1d9b1d92d8da62e51fa1e060c973ef92c5428e9be6d0a547c9aadcc47e35c0e7865b6493dccf4381da972bb51f99d7b6f4bb7ffb8950798217480a4230859480aab0586e2f09eec53c2f4f645f82 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f76c7d810fb7ca65bfe6a59aa3645a8f5eafe5fb80155f41134cc072b6dad4c7fd81cfbcbe1630eeda661cc6fe02bd798203a1a287c4b807f6de5ffbeee6627c864149ebabd94f80749e93068af349ff861dbb7f1a19e4ba2bb3ac6c80d5daef483c8b87cecf5a2c3bf8f672855579948ea1b1f3cd02e445cbe798ac0361e15335390d51294667b9149f38d85a1839ae43d331bf24d91c4accbb24c8e91d5a9e1e85ba98db7e13cd3563aa235b899e85d9535f80a47e62c043b089d5a0bd48b225ebb2d0538f49c8ac3c4bd677e8d93c07dc3414d16b4686d653ce4715a85963e71bb937f6ae91637ead543e8e8165f69dba4d0b6fdd057963e70cc01e78dfe94d8d03e3f75c95a2c538e90924749bd3fdc32bf1b58c6f5e4b59c157cab7653c0d146dec9a3f95ef41994bd9be6f446f35ad788ff79f1e6464fb316db8449a3ab7525b3e8acefb55fe4fb29d57c3a5e0b17f89493ea5747782d404487926ad757bebf81cb416d94265dcacea475fcdaa727d0b5f01b376251be2407e7fbb1be976b7704fe5ae5bdedcd17b87fa8bbd3e8f4d3c9eb567b5c20243677d84eae2dbec1d049a842b7f9da9cece8931851bb35776caed97c27d395108f4f661aa60cc28eabb2774c67773fb29b445f3554d386c87d489d895a43fff68af0c81f6065e57e744f729e20323b013d35802ef6bac37d0968566523ed6f526eee95f8372d45a42c4e022239fb0b3cd23d4f51927b3567e9a1f3ad689a4abc508660dccf82706b765ca4bc1887fd064cf8285b1155863e16be12bcbb1972f55b46fce8fa4c51c97cfceb7d04daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b877f4c1adc3e67d756c1c8647fb4ba32b75a6da3a05a97dfc2fefcd279666dad46e064a74625530e84fefd7fc1d5f959cadf56389c4c646d9fa11a8fb5f7de1f2f56c8164d80c69fb804d18a647af7f3ad970f65f55cb786e8726b65689a6a7520ed45b7d45aec05d706de35a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b2267f8eb8836ad1f373f67af134b8b429a8457c7ddc5b3f74b0157f67fd91ec88436d5667803ae5749b4c9c499a36c58fc5a7ccc10a604feddde74bbf4345d2c02ab0ed949f5da8b9efb83c4a2395e4a4e3a713df4f95901e8aa2716a3ebb09aaf61c93845860224dede0f8c0865fe461bedfdd176c68b4c115d9edac14e21934f13855ac22e8c98e3643c3d7c3b6c6c4ca9643096ed525c5aa00d3fad9caf58bc44aa06fea2873bedaf7c56b0cf7a42dc0fe95cfbf1fc0039cea65c6fc18c37e62afb9194c9ec1db8ba0dd36c7c3a620b5c661d8ab0b46a6cd3391e64fe8e40cbdb18fc2207630c37e5542cede3c395bf2a5a15ae8b50698ddde937432ecb150f9b3c136881058a7510f4d9b247232c7f89cdd7463cd51b7ba599c985c6fbd8c7bdff135c99e85a3d113554c59bcd6ae298d593565905e3645cde132b4c1ab84677e44fa1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f88f784e4b6fbad380c523efcbfeed4ec89df82490b5febabd4673d84e7b9dfd45147e8f2dddcfc2a7d7155d34ecd4c65cec93a9b26efe3b667405482e3aa37d48aeea67c1698008da4b68683697dfd34fd72a6f39ec0aa0806ea5c59b4554182f6034b9c5b7cb438e21a14774d58afab0099e478a4ba8568e192c71db7c208b7115d29bf649bfb3d23c2d70599682c549ea28dc16597a43aa6e65c77c432f554b067a64ad62ab71492a1aad6045677c74e3e8773fb8665259abd821bf07d2157c09199435bf41992628534daae814ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0d828174805da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5da2467db42479b478f0570d48071f028110f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b2c12d34027aede4a22fd80abe26a9c93c938c6b1348708d1bda7fe6c55bf66981695487ab81362f50b7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c3a2181b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee4a13b75379d2776a7510abb21941c2b36357e8248686a5d973b946b82e40802290651a073636b367671c9c001ac91ad03b9d6e83721ae1247cc188fc05b0249571656a276eea09b6d3376c208335618b1fc2748655ceef805c39165d0ce9bfed062add0c0a50e43167c80e5301a076c9cdc1f13852a5987aa3cef5e5864a706b3de947d2ac8e8cea0c3f83745bf3185bac9fd0162510f70bd20129d7c5215026114c4b5ef044a8a29a3f01fa02a0a3ce928a65ce8cb566848110994e7ce20ea5c30304d6ccbc7477bb78b3ec527758b7828b836dbb2742af6095a0bb882c2c9d8e162618029c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca85218dc27678719ca0d4a8cd8e9bcaeb944b7c0670ab171927c56c35034ad92bb3e6714d0f7c137c2b9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b68240ad193e95c0311aa501b3c1c44b20ab6ca2d2de1c56b65618ca53f0e91550851bfbc289206d1406b27047fe610ec01a86e8ba94516aa926b99879836dbb27a7056c4d54bbd19a44096d1b3f3e9956cac29e7ab95f175b9d9a0078da633f10a6fee899f400533f0f77102da19fb02610003674828758e23b5ec724c6829b95b8a6750f1988f431e7537ca9d05701ac8ae2034688082c5c20a122c6349db27ab958504fdb4c527b223b2420db7246a4a69b58085a3c1e6997db19fe17a2bc23bcd60b924cc393ebfca864da054ba38bb733b00fdf57ab147b922278fb132c5f5774bfe368dc2b66583790d30d282a248b7e9d43a562ba1892a985b75a7aff961762a05fb35b9420905bb8c4de00a3846e38ca7d71411e89f9e2c9489c597834c7a5315080130648f5347639184f315bff2d580ffd0227c9185adf9203ed50baa43a9174a7ae9b5655f2245a15c30f877bb7dcb2ec184138792738113895a980dca31baf6b5261e10a1d98ab660c066bcb05ac25429775c3bd1550d4a823fc96442cb2770751c812ce67613e48bfbe66a0fdba909317513220ebc3c55fa1364f318812199009af24f9f70c36f81b22b20be53208f0dc44dd3b6abb7236e1fd37c53fb1ee8c86810863a86b0029a58955dc73ec8a436112b5c3a75ceec356bbd91355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +ciphertext = 1af07cebe18b64049fd34156f0c1f2920934c333ba89237d4b942881e51f495d5cc4e1607d128519e51b8c59997b6a0c1402df0d3b032f6c3d0b4c34d48a5935ff61319530ec1e6ae306dc8b30e220031aa5549b00f4142201aec84beabf37c661c604bc26825e96075fb2ca24bb539187e1913849f7b9d0e6fabda2304d838021de30fb367172a9d0d0627398f966685df3de86f3d74f501eb56755844eb64f6b739820acebfa24ee515d7043e259353c7744dbce3886122abae686e4a4532a5863f6e898d4fda096266d25ddc674c28614e4d0ad2d38ce80b6855ac742b6f3cba2602056622565b486ade99294683b7de8cf7548b630ff5a6b0f6d52dbbfb9b5ddfae1d98eaf68a43a2b33cff3dd605aceed93f539b3da3a070d30efc2c1e9fbe027af86d87c3b8f84a2f30fb6359570ed3721eeee8efa351da77c69043c19c695e46a5f9535338142395c9e3660aee95765ed84646d6e60cb3343b60a61a4d3cf65975764d735f6aa57cbb07c06ffa651932e698969842dc1709ba7092192154bfc55c3d6362fa419e38b2001439b41a2d149e8ac22a5d9bb7700570b08dc2d3b91f764b43b70dfc2ebd534951701b6b985ad3b3420290b88b42e50b2e3edf857ff854f1693bf0977523e012bd6332381a1155b64e0bdba2dd7cd68d408602ed0912bb5b3f672f8ffa42eacc31da8601cf43fdf187a673b1309ff1bd7d8392bb76f71394a596bda178273192746c40d34eb4f80888ceae88291418b96f333cd1b15d7522b21ea6b57f12415509e932814505053320f84004637e479d1c6a944eee6896c75ec69367beb5cb7ecc5ce284120fbd24be653f61cea186f2f7b37a1f7d2bef08b8e1aa006118232bbf8217171ad0c0a71d0396cfdb42e64a1d0705439e131be2137af000c553d68e7830e3a3fefd5174bbbec523df366b228fca4c8fd4dcb2dbee571526549cac4dca391de5d82e0ed17962c52399aed8ec81c86717fc813139fa35dcf7a4a6c1b110883a86daf45840ef4bf7194122719b50e0980a7098fce047913348755fbc1f23de982560b3ecff6b82aca52f54dbd4f3bbf308ba1be699fab8207dc80ba11a923d7754769608a88c98835903054e66d810341f9809cfab29c53d16b3a804b9b51de50b07e7aeb9e7f378bd106a594c74af3d60e6d6b466d6f5eefe64f7b71a6cc2fb6b82a5c44b768e89dda891891ae853ca43da23068556a857fabd5f1689adae488c6bd4af811e9176b868deeaa2ad31caf71bd6f4ce8ba595c47c80ef6a24aa4d950c090ba805a99df998ef6a6305f176739ef2ae0bdfabb999a44aaa72fded16b7806d99248cd65394743da26358a661d6283c44ce9b8ed089eab79398513f8ebff93ed127709a43f050a7742100941def83b6d526fb499216d04d250e39fe6f80b4d36b303bb6898bc06362734370b3aba94c1a6244a5a8c7caa9d282082514629a0f864ebb91669acc757f9d7b8aa3059c9e44c7f1925ea18c3c80d85549686f74b7e8a8197efc89d42d2a15d195d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ab25da2298917b27d7af1ac0941acc5b7bf59d1aae8f878bb0a37089b845992bf03ee4c8f1a58cfadfcc0059ade2ebe31bdc5fe3049e17f350a805c6f30479bf9eb12a46e90a5332eca4737df5a32fe6dccf3ffb5a2d60add75a62f88d5bf64270be8a954e95f1ecb1babac1dd0fdd39339ed45ac8c3ab58248f48096ee07693e030ae914e753731964fdff686f0a354703858c15c99f31ae9dacf81aea3d04d7e8d1ca5452fe58183e8d6dd666792da7a77bd927dc77793396e4518f00e05da7e55d95a33af5683a4dd1a5f6878c1e6fa85771a990fae6f7a38d34a897855769db8e4a9a425860fec7032dd9e96b665f57662b2bb86e46fc3f9b7d6e354c12423ac6cdc74974ad767d73e75f5739747433c3451f8e5b85e63e1b7fdd9f7acd0cc07ba26b74d5135f0497be998a4445c29f49739f25044cffe5e679b4955122f3418bfbac86cc24234ef2c7d966e9a7a03c3cc0ac5f6abf857dc2ae40ad85825757d2b5a59b97b7f8d6de5db1fe59e0e3c1f15491ff4cf64c564e50c389f6c85b8cd60fa9de1a55e8cd3b48c2df68c67f3497f439c11f8504e577cf49acfaf7d4a2b0932396fd2937dfcc2138762d8753606f95d1ded6975a242654ddecb5663ac44228bbe5bd58d9c9d426c66802b466b21dc8d7a23893a953033874d0a93626d0db6a4fa3fe9fbddfecaff3e789aae9ed3ca153fbe8fe8b95547df8ddca526aed5fe59639c59a7699296486188c3ca111479ddaa747f99ac825c7594aeed636e683cf9fee8aabb7708fbb14838db64e49194b1289ec49a1e81c66bcf05c67e1afd5dcb658d8dfab09c28d9684eef4e2aa03d9b8218889f87c5a5690f99a7459afdd69db283d2d986edab2dbe38addb971694d3b6aea8c6b5d53a686beaa479ffabc18cec4628d75a7e4871a9f5591cee482aa05bb73078dde7c21edea576bfb5a63031875a24bda019e6d8d64a30d0dcb39d85d09adec7583c34ab1cb1dd99a115547e3e4ccdf2a872e92eb2330a5f6c3d918226b7fcfc9fb4f37d8103437ecefee073a49d29a735a3e6f8e9f2f783797e49b8c2c6e46f76c7f8a66838c86364a788d3c4ae68edfca09391e8547edfe86ca2de31c5b96caf479d966f688e1f38c6196527be7844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d059ed312af8880247236a3761236b068a9a4edf55317e8841218441fcee3744f977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e4163e204ccddf8243f81367f4d979bf11f5b84eb5d5df53318463102938a862e4ad73559614dddb417e9a2acab9297381a77d8391c78a8e4d29487c32439ea7e5ad945b8d6e1ff4368c7a2b09eb8bb155d04c55776aff8673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357bfaff7f9c4ce8ba8d0355fc1d9de9c7a8332403a41318d86357ef9d309fab847bab1aa5d88935d816a708c6a5e420f3bce4f52569cbc724a53df1b88919f67aa4fe86c85e339863c8dd49cbf3dd797186925cf6edb976de613cc2c46beb06b39f6cf64716a76e67831e4198822d7738669fc778ad88c5785417b65b2e4235cc67947d7b214627d326ac1adebccc3a64017e004499a8887c4a649e443e74720f0b1bedd52b1a8eb78b3ac2d5516b7a3233be9448575209675f4a813120422684191d6771ef2b44d92b2ca3bcdd5f5ac20a63efc237ff9d99bb4f5094afc187ebbad39b8b9ce75902190741640babf653886162645a84262a24b1885c626403f23136707816acf28950bf181742c98347022cd5941b7b69e21b5cfc2b4c6c5f301bd32a2e7882a1e1a9cd94743fc86af0cd26b51b3512003cbe8628d299663da40baef443677033da8b8c21e0a0f12fb93f4d63809375fc877866394a1a5409e2f13b3e5011a2a5877732415281b7b19991e6ee0a470561b6bcb46d87b4086f18ca29c5fdcd622f4315dcfb11db2c6cf136b7b0a870ae89669ad1011477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f499435118d9143723da05ba8f13e5cca1813f91ce01092917ba1d798ba3481121026713be1889b58375e5c4f9bb0bcc5fa808e2c00a36ca575c68b1d232778f71bf0927c5f2092d0629588826d02005db9bc0dce456e2b928ec9fb9c7a138e7b1065a2b660c287c3d062144cca71e5c1294442073ad48afc555767f1bebaf550d520659496af9237a22c27670a080f8a461778aa42c6ca9a954c28a658c73847a586fc3ef266562240acb6978e026152b1149b8d426aefe37bbd263a00da05df48375e53bacf9c4c11d4bbb055666ad008736b9c323a9974661215495e032aaec611af0e6a9244c2bfb6f3195d5121edc3c0719c3fc1365c2bfc70d5c6140e6a383714a0931ccdff946adcf73993aa113c90aef03374e251ace73770a350428ec32a9ddb4aed8832526968412863966228644b9af9842c2e967957f10d350a3499876f25d157bb2812501c8dc95365f83bc64b6340fa6cb4c2816b31824d028726de0112aa9ccc9e0b6869099d310aa6e5b79609487e7a20a56ba75c45986f92f5a4d1672f3d99927a1193ba15bf5df2586e823292593c49321bac9044e4844a7a6bcb08309e2520b6acf20e73ba5b05931e29ba43b2000a48c72a5df05ef715cd8865cf16a835a83c271402071d1068a426839ca424cb666545664ea5e7461af147b9d84583285ea1a05a02732031bb0ba40b14c828bb0e82807fc57882b31d9cf509be7b712f56994721b55da921eee8ad45c8b4e99931c9b71b473a89a2d4821213a1acfc453a41784d35b522e93c2d994d083674c71583782128476b04fec71f17ccc65b9c83f52c207b08adb10824a505b6da8a78d4c599a5b09979d9491e1383ea155576730614fcbdec1a8c801b94083a0fb55790b136bc5f37b752f3a6c636481debc5da8892ac1b04ac7447953015e7251838acbb6e24b508578b62d7450c46c76272806ac407112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b5b07b861be5a750bedb4a909605e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983be821e79682ffb18553b72cf0797b2d2117add5ac0abc71cf0e4ca83c26d218295aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6124d18b9a4606305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb24c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +ciphertext = 6e4a75139d037fe938768f42f9de93f12feeff1328beb5a9f23790e2eabec1f605207994eefc2cb37851f718bae8b94570cb06fb35ada46207fc9a0e25d535731cff7ba833963352ee9feb501bb3e1365e85ae3997630c5b387271ed60ba872afa7ee2b87867aaa14da0a174f83f7d488ec12b72107372c0a31677a6e933144ce571955be7a06a7b152b6693a5f07ca8f90a0062ff6c88bf45956e13df2e92017c6e246c4228ff0e86b50e0e6224000a44edceda07b3e8d6be399da183ebea434db5e9e5703dd199e340b02797bf62b29f442e378f9b0d99ab7c771d39102ac07341ed6d823a4fe6094622e3a12d74f4615e7b216d4c3da113bf62109b12fdd8046de27fadd35330879359b0ed0085da5578a1330c3755572958001f25524adfb9fa6220e24417a7d1bcaf63ea1044a3e9b02fd249a2c0e281b2f9e2e18b9f7552f4446192b7b65f881954cfeebfaa3075860d1c6c4e819e40873a992b6837257ac50a7fe7e3d759deb249fec5755da72e4c93d2c412e316e22694dba50831ff7c2bf0a294ff6329d0d2022b3aa6a9791de9fe6face1ce67ad828cc0c6293a7e5d6bc26f58e63e025c757576e849a11f122e6eec09ba7025951df26ccb414cdc914f47584d443f06310e86ee20c303ef9e30e269f7a67f8e67313cbbe0b06d318a172d0c47d6a7fbb1aed20fb6da5a28c53277d1d38800593d571b6dbdf2671ff6802d7c346232aaea7fb96134d8d16ae62b07804474cac1b3ecdcd5c26c112bcc9f72a003c4931cdbe1c89158505ab8267e3f5cb5869aee93956bc0334d09b719d898685f04a70a32ea8b0e56aa6b36405221ce539690e6e85f2227fc6cf40d203d55a2de22c902f1eb16339191576f3dbbbbed0c2ef90a5e7fd04011b33fe9a0eb2ec1a8fad089a410995974f5b2ee8d72e80a716b2c389322a279a2bf71c0a563da36779887c8943fb2cdb5dc6396d459acc88d04d09d1d1f0ad82c8e26c89f48c2dfe104483145dfcd2faef8807c4a160fc4fd025fd35f188b55907556dc55bed560970e3046c4b621038194bafc02da0503f3a9828da90b7dcc73add69908421d8169d32225d54111d122a456092b08e012a3c0d8994cc43fe993d7501fb7c7be94ec4b223dd13f50272afeef76c7ffcabdb509f9c1f9baf4b72f9908cb5ce3770a3040557797f666c8927dc08608709eb97942a64c31a1f71ebd7066031f415034f9d8e9c267b539a3274196919959d4f919ad4068b21b53fb18cdcec7391b9ab46f401672a22f2302af1a5104088d9f6628f894a7e04a78b4666f669eaf906e9ed3c8c9bd7ac220104967485cff8df46b064b982a2b552cd521b477e8b8e90b5f1ce11ca9ba16b045f4dc0f36a3b4ca8fe87b1fa6057b5334e993508192c6b46c79b196012dede5a06e4655b46c2540a64ee40830c7ed1c85507809810086d5be4ea8f1197cea21fc56113e45368c6f3d590fddaffd2848481a3424c813f3047dd8697a6316611889a74c0b5a4fa071de935d2d473ac2a0d4f62ac009 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = f80c63dd6cbda93b6cef7e9fbad6bdbe2ad3f18b337a3d6ace66f5fb38c5edac9c8c94525c85961e14a7618fbbd86dccf9b5ac787d88b0cc80e13d4fbcfc697c0be4ddfecf7783f5eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd3fd7c76e8b7a68b92abc870b67fd2f7634b9b37902d39bca04653fad9a0e5fdbe548abb97c7a1fa18c34cebbae3987f4b3c52a60d6629159ac6875276053908b389da3ebc7e2871761e69b6e8ec8d8b5f52854a3e644c5d5d4675d688ba13de9e78a79e77885235e6ffeafec9946aa989ea634b6ab7dd44570d3acf348bdcd859567a74a7b735579fdf8d0ce3e467ae30eee025e430114a5a60d3b42bb438468fe637a69596eb953ab7b3e4bf8b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e865fbf7135698e15b8d9abd778ada5af1b7db0ce72aa6a4d6a3dff1045e60387e876c580a8df4479ebdd804b6514ad9282ff91f37d6ab128905663aecb0bb31b5ed4687e449e1fc33515ea2ec5dca81ace90a4da8a6a355c2ea9c85d5491ea3b48b5323cc567eae9d9fbdb380fe5d4c95e452bd34f0f65a39ad6fd922a3c50a8566edab03358745e8de332f4d1112fbfd4839ae7b6745c66aca80abab92e336aef99253b40a8affdf02ab70fa7f3baccb1ad563ad20c5eb9bdeae564be2404dde92adf06ec68c16d4c7435d909e3e7f8968948befea297a27a9fef1b5377b02653d66897ab5f6cf51553c26848207e74bd9495da5bd30575d358a637a5fc31c99ba7bb3d4c691eb555e4b1c208dfb52f3c5413fd16238861fb650bcba24c1f7026fba51f5985487ed3fe1375ba5dd7a06bc2ab048bcb4a78e6d3c749be41bf5ed992733630b8c917f89960273740a5950728f4aaedf908e5fd334373e8a575d5e5fe96e5ad0cc95bf2c761ae577b9ef6bead43e03f5d33e0765d748c409f8a44227b8f55838b38695c5e23ff2cb9bfdd7cb85239d6e9ccd3dda468a15de22784e7879f77e2169c642efe6a8942a2ce3aee97300ff4caabf862058b6e7dce6f34c79ba30d85380ea98d73d936a8a595098c8b19820ad9ef4755ee021d69aa688bfbf5ac4ffde8c53639a2bd573c8a420c56e9167bd11e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fc7dd52b3ca5e0e729935bf7e4bb984576f2acb7466d8f48f975bad539b236d568dfa34cf2974d83699761c95405943a7a883752eff8ae79b4d244bf2d683f7cc7a544ff9bbd8b5e92fc8b3449548634ff34bcaf0ff5a41aa84a10af052f486f89630a783de508ead24ce4d6906816a849810a5e72714fed088fef26c31282cdaade6c9334a88acc9e7b88ec4f173f71974f2c24541065b5e80f4374ead853d478625a68f729af0c1d8fca4fcc4d62744fa65805924e221b9e7d72fe187d3b621179aa8f7b7cd19d4e7ed787f9a5f65eaa7811eb6b73f90a55542c80a4bfad64677467dd2cef785e6bfbd3ec1f3d46db56cda0366d4ef658279db3232c675bc0bc97717ca3ec7ed4f44caaf2bd7bddc90aea8f886594f98d4eae758e562cb63d1bf539eec58914673559da4a87b6ec5cc77c0cd810627aa355fcb062ae648ec7cbb4937605471feaa9e92b94016a9a05f585f3c52a993a91a6db73c9ae6364dd2a07b6c2afb449122e76a3b273d424b94343b3bd7e7b1e1366204820819c8ba8970218a22262ca649d8e3223167be77d9a466c860ad7c320b227e873a0d68faaa441c0907805996d64f7759bdeed65cce25b367f02094714be404ca9fe56f6ad99e7d38b5396281314898036493002cb516878db66ab19e09478872c0f76abbe0f754b443b13dd5afe610c1adfc52fb3c82488984dbcc4d9850a0ee4bbc07d0051208c87914a3fa5159c775ad91a552c2fa2ac573787ffa68f456012af600af60183f97cb3e2936ef683fd8e2b5742c6de946b96f825cd0f4807640a532561c70600d4995bf8d2ca543db1eacd68d28b207617c23cd9a57bbf75abcb620d941913e6506aa0123f89c261ce9c39c605646904d22586643f4ad250870afe94dc950913602cc1cdbb77bb9b4df518d1a18ab0c5a25948302c0535908e70f84587eff169114161c3e646740893faaf6b37b42168fdbc494549776d528bfa2c2baf6a00a7498f403347a646c9a58328c59274ae8cff8b82787a29d67336dadd3404fb5509640c29c9456fcf82d4abbcd9899ab108a1fef872617c5ca780970182861c046a594d62757d33247b79e12873493634c16fa70983c9b593814e69bb160120b4129370519327ac2332063992af4370d9871e7a27d13420a6fb16ed9b579d1ca1d36a2094eac96b537109ad83f4df1a1d2e184c309ab65d75a3e409c57578214ea4035657757ab92aa930a76d251a1b87bc6b58f9d900e38156d73a1961c43be2e044314c89ea9601937c0a87d9c4b14cb9e79d83e722cc40b048bec5ccd038304ac0a65bf93b9a787105eb31b5be8845c5c57b9a9caf6243f54438ed84159f5b1b8b246073b1715b0f635e8078991118dfee2ce08887f9680bd4e672d3aa78df8954554d398d1675d785b85dd28a1675944d7597968f22855999f148cceabfabc2358c315076c6b4333a82520a8332543aa100034bb0a6776cd959bcb263074fc28956726d0d99b9d81a7dec14f13ac5ceb5b9eaaecb28e282bb517cac09809073c3d085718d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0eef3233cf91c0bf5a6a9279f6ad136808a9a3515b02e303f4da26f93264c5ab9010a9c8550b9076d6471c196675edb08223672c1a229ad31c05ebc4fab557f46b4bb37dc2b605a87b888a1f475516db87b92451127436eda7922bb45b8b8462122542de969c31622cdd62676a8faac5663a8bc2191711383ef4c1cd7a183bb55cc3c83b566e5514f233d79a2963710c5e5225f7b09b0b6176f451a7f77570b1c17b7ba335511bc3c3feb884e459add3a594dd35662419272499b4e9258dc9aca946ca80911999d455d06407cf9c69e814478a9f5151780bd754a440bc69925155fff0a675e0c322c69174c27cd804279ebd3260feb62c0e24eb63c7a042996c25bc9342c589c340e99999f9c5054ff35c760a43974096c5fd23bb9e51e2483722a132b0277bb24010297c4ba2c58bb286c49ed20b7aae98c5d9b0601f06ee53c1808e07fda53114efc6d36b28b906611be3a29e68a8da76457be5419d70059f7c329aad28692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +ciphertext = 0739932f7b5b6ed0d363a0fc2a4829b0e1fb8c071b315c536b97eb6ee3c7e6b4022a5f6bc0770e3c48b8c0711029b6cb454b1e80e807ca35b55c06abb75fe24dcb4327ea8b1a7faa63d3de0f13c0a9be2c9bf101a293a078cb33489ee8b6ff1c21f5c4a42e9e9b16d4b860b0a624e00b5151b7f6c4db7893e485715b09e2964dc97740cba20650522f21644776c28b22a26ebd5e09cdcf07ec0415d3d464bdf785035b98aa1fdad58bcf06f87509b3690b327d9acb8b034a34f5b1061f58872f214b57d6e5451ab568c3e8a700fd8c95c82ed28427c7fc569fd3dc334ff8d9faef54b972da4ad8014cc22db0f1aa82663f3a8f205dc5ff8d1ebe30cbc1a590542bf5872ff6b0390345aa14eb43e06f52b35888915a0d8d64cabddc8194ea6a6bc96fa805113a0486643b79721735c0ff55d28501254faa73caad71600ff139a1a5d0d7930dc5d202512ed49e16f6fbe95913898688f3928dced939f2230aaccd2ace43276e0820c56bb7cfe0a1ed5d4aa4d044d2c6e6e895d408fdfadc689ec2b5f4cb24a89dd87cad740477ec812b2f8c9ebbd77aa73900c9a412c8ec72c39ffe3ec82cd65e036056acd5d37c4f45f25c65fdb035e1afce1e6743e985b8de817bf5d43778a0fc0edb3cf6825bcdfbb42c7cbb3a8c7fa02068ff0e1a1a3bd0eb3fca906a100fb92463c7c221e776d0bb43a13037d9a07b96e0f2c421ced63ff9f5442711a7d876ea5442c1d77639c7eb90d7dfea7a635f887ecaefce74aadc6d3cf722f75172835a24dea2664c09a70ed2ceab70a314f061187297428ca7d65d07e0bc8d161c5cb43b0fe2e3cb9cd74c9b2f3237bbd318c18d8058719ee0e65a3f1cabcfda9e10b8c685bece284a62d514c2e663b263220c29cf3a207066bcc53df0f734ca27f2360e5d67144104f8c13f5d12354d61ab96b939cbde93eec145c7332511127944a26ce2ffebdb03504982d25c86fb81bccb6441edf24d3975df84a0950ab9d28866c796aed23c91d12ebbc0a90774d60fa213cb5459b5e55f8d8a6d7aaa94973d88988832eca7cfccbfb9aaa7c44b08a391c6905fa75cfc6d7f1796168c33f8c4f4b04d89d8dba51c840bd0e08b2d660dce30b9880cb86841ca8ea05c3e6b1444a61c318578cef85c9cbe2146affec98afb815380298dcb39ee3913c63a3dca559ce4d5dcfd17152f68c8db381679ffdda0859b6d09866f296b9bb3c6953a4f3c9de9a6901fb46c5548cc150ed9eb30468e8473e308c9d80ec708f031dbf7860762a020702dc6b92c155f2b7f2af9147ba4012fb23290085fcd6a7590a4ee2542f8bbeb2d55bc81d49bbb439018bade94f8282c4f9bfee804f4b53782cd4e912e76f34839728dbaba746dcbcb94194496dabbc1c0a658888137cfdc6b42f6b8f9c6a83383ebab751e29fb29e97b5546e941e895f4316432cee99460bb680ea561000f268602ee0ae9ad74102f7cc0c212afc97f1532428ed658a59d8b80ec5f649726273ca6a5871d8db2184c52e25dce3ae7e2b20ea7c2532d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d809438d9daea78b897b5f85340bd19e7e6de8e5e3d42e68a1537489f5f256eddf49d4f4bf5b5db1ee5a3a9b9845eccf287776fa8ddff5bb7ab904e0feab7f148a9633546846b672cda9ab8a37c8fa8eeb76474e7975ab7e16675a96f6f8648b615d66a4fb4a5c255a0a39387b03bb806e8c9fdeb37e488d4c7e75b593860f6c97d637a2d886ed3b933292bfccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cbbebb1cb746bcde294afb2f2638beb16d30d476bcd2c335de5f26b7450f8b5b2b23d332dd9f1074dc10daa5fabce6c148ec2a0c4aae3174be4faa53ca9cbf297690857e5d6f8c164bde8513db0c7c9621336a9875946fbb73bda9774c086e5711451f5594a453e38792d4c291ab7550aaf9824d9d4d7cbef7f7ba689400dab73836d5f03873f38566421a354b59a3b48bc8f63ad9519d932af68d0aaadc6efd5783bd93484adaaac7853c99dc3ba18835d2afe8f14bd0768cc7d0b951909825c988648f797f68eefbc654380e661bbd4ecf8abd88e24e0f19669aef65fd817564a4a4f4038eb5e16a69cefb503495a4b6b680a08a550edb80ae668041aa120c7a363e38ab02e56cfef93bfd4396dcc503646acb74b946024fe4476807c058d72c9610e3cbb51af9ed724441acfc258659b3a9af3e7e69a3057f98378424b8ae2df3cce35fe36483fb293ced5eee6a4881f6815ccd013d66fb7099efd4931e54ded570bcf2facba0b433b9a13e4734fc29815f6514e6651db690cf8ec268381033be7c429a8e418b7e2bb63d30b570da588cbc36dc3798c6508eff05530b9043311ee82e88bb3e58356df4d8898738c9b3c457faca42b9b81ed7c4118869d5153338e04f70006c6be294b528c779bd6c8ffdbe6e2aab439e3d32b8ac45226f82356f00dfec812033a4f9667af94f481e8d7fa2f45bc4ffe04343971a656087cca8ce9bd3127d13af8e6ba745888a4ad52ae67a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b5ff879b7f7028d4a1c629d0d087df1555ea01964366d8a6ad1b5bc62d392d43bca37dccf9b7fdf3d68b955c4bed0352b3f78151c471662fd97bd9ff2dfda25619f3d01358ab1b5f8b7bc687f5c111bd4c661f37301e9fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494b0ec67e33fb9318dd5efe542dd59f2186da24747e99ef646638dc05de784d9b581b4cabcbcec3deeeca8f0d588e0732f76b99ec844032d99ef65c8a9ef4a661e78a48bd542c4ef9e95d64797fe32d2d8cb9b3986eb5b510fae8554ddee966b0d3ccd9932f60ffc96b895ae81a95a41f1bb3adbf572475b3fe8933fe49d2c965678b95512289cfbad3da2b159b8f2b3535f4d881e8ec204cba918db9a8bf3190965eb76d754368955c0c7929e9447c9fac78e7867c1b4770596047fa820c03a11caa3c2ba48121ef9ad47cf89a3df22d6eec9e18343bcfd06709f7435c6d6b14d955f939470eb805e38a751bc8a1853fc05857eae658a8a7cad729373e83f53e87f8fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ee8fb23f4b67972d9d524f5e9168cb232f4f3afd695b668ae6721c79e07ee5d26233936d195b62b192058cfbcb0a5a73ea0154d78224ebe84b7b611ced7256d0726492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9a725c5278c21d896ca5d706e5f03d71526cb175ade2606e3c3a24d510b4d9816aa6846a77663a80f5ac0d364747307068da942b15cd2e02a3eed2818f9056d697897b509bd5048b178240c841580bbb77a79423996072f39497869007b19442f401009ba1a039c18f191cca42f9551713cd791c9fb847690cf6247bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32da070fe29411f17a420521fc69c0d09a6425a20affc98681568b8ccea88e54b8dd9f12aef4b3c10f256eb1519671091984a1dbe972a901bb4b24246d7db01b86665374bb6cb841b3cdb2593ba5c96e32c20936ecbc4abfd24af76158b36a2c752a9bba8946b34c414eedb355a3ccb87431221aa2e936b0bd7540e697142da0817b1b51314fc71cf4017f50544474c572c70bd142c676b69afba4292f5f19e88163f2ffba3b1685073c3bbcac825b095b5d259228a459fa7e866e09735e4cab8fa733d4db6a98172846397883394059c635d23c09fbee3cab350b9976c6a8a900c8e1693c3704e779049cd1221ce767651bc23755a3a49c6be0c314a8c501579f7a447070effe0314fa3687ab92090738434e55280a42f22a66eab77a2932b07e6857a32e31a527a2a909865e053a32148b59cbac224c12468e444916ca375dc204c600899f90ba7c854b3646f2af3981797afc4e261c7a93aabc40a93990dabc82564336d01b2447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad66161890325533818f845301d9311bc8035714a722ed9206967123e65410562a745fe28f90d50d772a9cded6354132688ddb1ae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbae00a91040456f4023174c73dd8a4d50f9714ad1cff718321677a6962587ba6ca82c341f02a7382be9715b41994db91e6d0b487207b9b660793e62470b806a7444b6faab38f48747484062ff443ae1da9e7ef41f797398f0527406787e00e197ac3248ee4a0e5037cf6c754ab9a24d08936e9d3313b99ac18886cfa9972030f1a40e58b25939a21698c434391785a3a98f0445567a9dbc0b4284d49652bb1862bb76fcfc6abe60831cac9aef6469464319411a30f7601b5358568b014e67a76ea42acacd7c3fc2f983bce1bc0667897b92590dc724b5284fecf7c36b3842c61c27af1a2f2ec95899591e707272bea384cb9c8c9409bb26d743faf196d3b8b33119a379d5cbf6823d4176ca83ba4e2a426745f346a42861a7b5343ad3ac26ea8895f24a379c449156123ed91a4ca701bd789da84ba0ed5c707d373634ab7a65680667191f806b6f62cacb4b40afdd649cc9d1650c3a5e40c8346c91b27ec1b1a957c778ec9c968c670fc84645fc07881c54946b5ab0b6033f45afcc6a61fbb99746f3991f5b827c22972939c5ff620bdc4b131eb393d108c56556719abbb978452ff0a12a1d138c9065c304c8514658193232c832b05b0b21a10483c6faab378c6b1415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +ciphertext = fd2b69a027c2fc20dcfad7a6765f0946a637a63374b349868b77d6b6d84a3e32392775e1cbc0d9f986843f3f19966f7a2ea83e4ba64b46efbab4c88649ff6e0532f5ebee8a218b9444bd815a44e2be4bee845a961815fc122598306b1d60c402ebb170402220d97bae5e04cce58470800966acc024c00c5e20aa3f1d4bdb672f1d4731cfdad84388c2e918191dd95d2b70ff1a5228dd38e7f2d936fc7e571d3d288f3c6b3f71c1219669c478a10fa46460340ef9c1ae9a4981c83df9a13d5b5ea04cf9b44d08688bf66e59670b9f13f1096f921604c68a44ca5fa79e12ea7bdf671fe1deda8488ede59ccedcdf265cdd168c3d8e9981f10fe225ab88f714d0c31bb53eac599fdfcdbd24e533327cd6efd32a39b24474da685eaabfa3f50cd290d8d681f684481036a19e741ecf16e4b59059522925ecac163083cc087f4b6d78f0452b429eae2518e7623333bc84bbe39bc85866e41367278b995af06e382d165c6957ce03f303965c94b9d857151840b1ad140923950c931b501a7f97c6ae2cada15a16ee5a7636a6f412d19358bf807130f8bcd614d29d8eea8016b04b8a9e2343c951926417fbf749f7f7bee048daa22d966f98975daf5481f3360a0ad80f501f2e4e5d0f840f48adf8f066541997b67504ad8aa89cfc3c12635b8fd25f5f2611c8b8bf0e88398846c9edf3ea57a49978d1fc704692c29165e6b0f4e8db8d298776e95f36dd21504d42f4ec2342a7354a47f4ed0536e6cb206e88e070a2d8a2c5ebe8e1327b1041eb34fe570b9af85f7945f9e2486966b5abc9edda49cb4d8603328f4a4dd77db3dc569894cb21b6db52665f86729c8def02e53f7051f406bc215827d9c82fb5f106a777f369c39c447cbaf4ed2efd105f93a46e5cfd346ef86af228b39f48c27625385f01f78a1a9622e58fc72a8ab21ccd362c7c27af6cd1844cba5cf0953f5aef4f7ce44e681926c691bbda9d1de170f78669546aac55260cadcb5ae44eee3459e3ebbeb14e053fb4daf6c1d43fd679a120e7da136d931238bb9df93cf2ea88b1112e46007c27164e36b1f8a0827d42a2950f5b58bd3eb1d643034d6c04970e00b686489fb493b8a68a87670d02e85b5097987cddb5f59286322ff9308b6de9a1c5766ea6ed47dfcbe40e42c4bc3a82d5ae872a82951d41bf062063f6f8f87ec5356055d94610ff915f930430330981af065b131bb5352e3172d59a09a4dcc84299ee5fa611f31bb61a011df04d4994c713a8774a6ac21b620c5cbeb7bfbe7e26f2478db2c105e02a194b237c8cef57867592aa3a1d0cad24c30d53be0ffc0fb50fc83e981490409b20e911e9ad3b1de67e51a4bee820dc5e136b26f9efdf38282889283f33f4d8ebdeda6c0183bbb27351f7869c3c59b05da65a152b6668226cd5bea860cb1b06de463fdaecc1853889bd2fcb98e5fe337a727524b7bcf3faa23aeb6de10223cfe128769025375e94f638c55d838bb1ff301db74f03285624064cb20142d9cafd33631038b0d0593a4fb141a48b9399 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ba45541ce7b3de134e6b27d3081dbcce09bcdba837f23566dcfe928c99cffcb674cab9c41c3e51fab3d78177b9126c7974ef568755fda075965baa804276859b19fd9e4d95b5e3a27943776da652636eef62a3aa876bf58c89f9b60fad6ccad0e3b38011c943310bb5cb24791b7ebc5a2796d6197192d9594946d89d88bfe986d58dae6c162e93838a3d7306b31208e70efe528809d73514a403acb76cef98f5d9fd65b9da0bdbf8a4f438ea447a9c98e809ae8a2f5c3c1b876b3ae94ed28478fdecee98a64fd797a0931cc4a18777e5d481d9f9fc0dffb5f5a58635b368cbc8c25dc733550774c096e795939b74e83a23757c2139f7805663de14a0fb0dcf1005e950dbb4cdd7caabd5c09b38e8cc1ad9a68e69e48f796a5e8e8fc7bc8325b45656861a848347a358f01e55e5d43f7a1da739ae32c899f977075c9a19c1eb6399f2e7bf1dbab593b9d7bdb5d9ef6bdde36af22fc951a18f9a838591a054e294c35ca0b86be60cd3e1faeb7e5dd4e5bcbcaa3af80ef37067e7f790bb5d59587e060f72ddf8b117286fe81cebbf078e6d259a9b53bd70feb43a86b24aebf7bbfa3547ce79b9ff95726ab768bc7fc8ecfa637e5030d93581165f1e5ad3d42374a41d39d55741c9c49a1d8d7468cc826f0380b90c9c403e9cf1f73811d674b06ce47cbf613ba56365fad4872b9245bf36b0d480dd0b47b7797a23286269f97451ee3792cfd5c8aa3310c7ff3423b263d93ca42dae20fd4fe6e3bb703a6c50ce7dcfb6341aeb485576b53d1cab71e9d49dcc68cf96d08bdb6152994e7025ff96c8ae4a18e9102ba5078bf6087bfdc7bd4b324a31aeccb372dce8976bb9db4fc8eba89640149acc544511546c5edf93c3173ef28ca92b85b86188bc70cd9e2725307a2c3802d6d870affcddd6fb5989c5a6846497dfbcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a798f4aae53f2e1a69dbf64336efc3348f4e4ecbbd4010b9f7399310253679b48af3c23961bf345b45e72c1d472f9b3e274c730374af9154a58173ea0917af1259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435135ed1e5e4fff0848bff2e69a49485c0a4f26ec6994cc5dba9f64770bfa3962fa08145b987593f2fe67a2b2ccb036c4e665de45758c6745a389955ce9744cb813dbd85a838a69d4198c3e8a5df65eeb6ec70e5a34156ba00a53f05c9be7f1ac214f6a75dd8e54eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fee7d9c45da28a34873ce76f0fc7a4237aaea18d4e2d3874d726aec41c3ac9fdf706da459d0e736b7a5e0936b3abccbebf146350fafa247cf25ba8974748e7f28c8d6bbb55fe98a48de682a91770eebebdb29da0efd677a70cfafd6f690668924cb588804d78179aade86cddc8e352996fb2761be87b7778a56c6b026769e339aca5f8c9499defddc4acc3bcc7ff548dd90ce3cd7a394c24a7ccee8d3e2fae3b48beb295905c2e7af384393715e07f33b02547822b1afcb1b57b6fc637e17ec0fdcaff880de1d0d8ec42db454f5c7be69ac0069c33330bc4064ff490ddb90a28908f7471fbcc543fa944048e8698cca518437873f144e7e261e8465b3720582cf7706d684f84e618e8834f35857d4a8bbc303134b5e235dd1b2387a81c663876c5530293f99571b97ae5a299df0c012e9662947089c9f81687722fbdc30ce50689690b30932a8a3ce7bcf6a353bf988dd310a2c347bfe6b30999e69c455b9f472b9bca0216c84265e5d9486f6a7f1f3125c16467ae41b9f85180497b255adb06a406a13a221388e14c0de8cf73b6a952c2b2501644831c3700b7c273b7a3180a7641621f33b41c0f9255efec1025fc46f658c64fc89352c54c264b97e5a91c2386cd3790605127740da2076eab4876e128f3746843205b8328cfcdc65feb92c2d973bbbfc68fd7a46db51641b7830e73589f41d413fb571c37685dff142863078acf00043395bfab3589b0cb435981b84e54318ab46e398389b8e146cab2a9666330ec4c90a652a0f036951519880a45bf5d000d4e40c6b6554cd222880d0b91b67153c43909eb2c0926354d436c2318c593f9fc214b548e17245c0c9b83174a6783508b97ac6a8d8a88ecd278e2e52c3c9138b1685dabba2bb1425075b298cb9120e790afdcb9792c88698cc156ca5a789474992f470b1d554514823e87bcae52ccc872c951b0c24b4a2b0460f488ee7768d56b07dc79b3b4cc321e5878ac0a5c3146aaeb6ca123206b0c7b5aa6e0bec5d0a903ac9415da345af199cab86ba99234c9526e6e8812f6da8001f31337b8498a8374ae527b6032a0cf3142d1d34181a5afd6aa432a588ae1f644f5a100fa593f0ed2753f441ae5677484738ff694abcec58781b06d0213579f827fb4f97b3fc343a445ba3035aee989685e7b20be6103fd39afabc334417379bd666181925ed369680b851a54c41b6546b9c04ca69742b2a814763674abc9cbcb03e96f9466cbeaec698cb5c9acf814e90887f8d15bee556b28f50b739185eb7a5a06e896ed0048bbd905e016436477a68ebbab1e172928ac8fa9a8b0a0d999b135a753a29a47d0136865b0f382572b0697d0fccadc8a77c1b591bd73b639e13f9c21b6f0969b0aba3ea807303377afe0f49421b68d0712823fc448fa9a468fa000d5964bcf9a9e7fc92dece03bf6732a36935b25023b47fc94c15795dd983bb4531e935a19778305d0e8a75c2cc770eb46b6d5759df503bac33f0669c775729c59eb94d48223d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb0b1ae805b1498471ac1149d578b454041aaa2f5cf13390f10a72df3385c6a8a1f990bb946f4c888e585069b5849882788a1be27da0725276ff9db130519050b74cff69a68534222499cc61f5845a8fc0ac5629e0cda20d3ea2f0046b78a2267fa0187f15721ec53083018772097892be85c1be99480247e6e30aac8fa2c593c630b981e57515e0f7414cfa8b606d931280a950e567c93b319fd23ca1b682fc0b960dd309f80455cabbbc71979c59a025008462c0681465d748ff2a6ae24e86c79922e2845568ceb5063fcb81b78295b93a80b221ae7e14a9a9bb7182c1acf347f2fa73784835f3375a29ed05e4bd120a119cd0fda29f76a1eb873aa88d0cb3c661ff0d5652f2b4604e2bdb1497486687f17b8ce7a096a59e0922260ae99bb7412e306cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d3694543a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a15231100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +ciphertext = 39c2464c42bbb75ccc9421eca048aa426c45eec971a442ce8790e14ca23260c9346c2681e7985e4e27e7ccf84f8a03b25b0604b9a64d943c2340d4818e28d774a3b4e04b6840a2cb81e542dc7e4fbd2146db158edc7250fc8ae2bebb24bf2b74c2cff7a9c5902a8963d576185576c4c6c4ced7c6f0878b67aee7ea494c34221d8907059bb989a65ac921c511c3b1f23c649811220f1cd528251a208641774228d513e80eb2ee079e9de73eb9774c2b51445235a262f166ada853256c6b53ec6ac3258059e4bc6fc23c6f0d9fadcbdd15d7f7f3a6a96743815ccb65117c06b2aa9bd134746b20337075f1eb45327942e22816cca244236514db48a46f353d5c0b0f9029ce274820fcf479c1600237028558b9acf943e8986c9f5d21af0bb5b294a421ad1a8a803ad0cd38b085dfdfe8f8f19206c027394d94b2fdf6d752b1eab11cd2ee871870d5f9a444077cd5f563faa1b1574b630704c01be830d9fa56eed3ceb9dfa8f384137ad76a461d17bb062b3b6a0325f787702c26e77cd649f3184a10ef5625402e7c7e1894071f8772331a714a4facbe583a1e1810e75c141440e1f6a903b6077783a2e2fabdb61c3b9a5deb1e7bf2c3852160aa8a366578e873d6d4a9f9b54f6a15f0fa3ca20146b608cb63a449656916b393a0633366b527b7e652eb2315e2921711125f9b2f0aaccd30474bdc2880bdd83ee40f94acabdba84810a02733fbcc1770ec56fdc8cac2accf15d6e739850b48616b7d56beacd5c0c30ee09530367675771567db0b05fe97f0e4f6244c020dcd1fe8b95560c8901cf350c9824b0ed5a4bf06ea63110d97ffeae97b0ed0fb5be0c91856cc0cbc4ee16d78d1fa3f2539570623bf53058e9b6087e252e86e0896c78e5bebb4dfe870d5d3a2d041f45346b559e81e24ff09904230d40125c17836aa20027ebf9fd40f045f9485582c124e01fcd22d05118ec6986788805cf0522e9b9d162e3b1003d7bc913d27c26a9171264f49db8463b5f69936d7abef9f28437b6caef081e1bebd7c9a39a43dc0a00ff49731b15e7f1467cc389b03a020fd94b90f5a491572d167ef6cffd5aa45b3b611fe7b9691721f4d9dd76f9d9ba3d068d8d9578f1e238742342a791e4b59f8271e09575a53f77ea871090907710c40973a8b07945109c1fbefab60add3e8ae3b783ad222db7f584b7bd60671afcca5713c0cfa96048bc3c52d62d73fb5182a70b499d54cb6286817cf85c63189590189eee2c81e05cbfdcf23dabaf7c7269a18b801597aefec507d0772f30e21c1bf49226ca74a8e0bfc334f7de59632b564a54aece295cf745784332e873ae704022af6732657c81d7037f9424920c1bf238921d6b596cc247daa20d763f61ecd3fe0cea7d79e7a6094f35606f19976e1e37ac8f81fe5c63e51129cd8a8ce602ac56d9315cc5d6c68398f01bed2e9fc79121db26e319257c40212220bab87a274b97784f932649517f462b05a423a0fdf88582dffa35f330a0c345755cda858b815b6792cb28b5e45c500f86c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2e8da416aeb29a6e459e396204e5b5e65540a2a9ae9ce5fd867a9e20a5ffc7565b6625e653448353697b0a7f3b17e3b1ef375a3e36da5869b579883fd1eb3a06da5c11e493f4cc9d1848e8560bfd372f3e7214ad79ae78b2153dcde882451776478a4e06b392ce9b9d041da5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc456878fec2f5506f5974270ec46db34efb9665b68e55755e8ff677be1c0991b644b5932be1232dc6effedc38ce9316156bcbf354fb76e635f4ff6b26b07f9552d8bea65e5ec7eb7ae32034bd755674e0ce4345aa72acbb85d57f4b2cae49265fee570543af9d4f9bd4d16ccd389fb9922dcefa394af4e02e9290dc506f6de004cdae8cbbc686af5a911472662d7f94fe90b12baebe7cc7edec476553762ea45e48694ddd27fb6787b7da7e9e89d77563c9c2ccb77cafbf3d7ab9e81c8fb6ccad9aef1851235c7986194c843ff80c4e92ba4f62fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391b3e4555674cf425f92055bb3a3e9dcaa7b0734df04c068028b3ae7b8ff3e02ef032e6dedd1b6b52faeed13b86232aeefb2969a79ecef1efe9835a44e907bb0ddfce6eae442bfe460f2ab882959e096fbccfcc6e40cfbdb5eb673c2e8d6e9c5dc656ed8796945c6e4c81a68f9cf381d256bc1e73f8524e814077af5f54c2c6b487dd29cdb2dfce09fd9123dd9632ab823dcddd86a57f8933743f347c203894d0043f579fa6e22f83ab0aec98b39c6d638132ea4b94644e8aadadc368e6bf0ea408f752b42e5029d7661b554bd39abaa906af32f877cd5bf8bddfe7825ac898dd6a4c233462fba602b8e321db9327aae9bf54e31b96d35db3c4cbaeef1fb3d146f9be0333650c4cf4a5c85bf6ef52413853de0bd50f9ae6f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd6be8df1d947e28ef72ec5aa1137ccbf5dae73ecc10635dc049fa41a73a4861acea29f57be33cef406b7ebce79706d5a709a4bc06bbe40867966e830e8aac19a06f7a474fa8457f76f09cfba6486574d79e1aa38d8ee79d9634e3398b744ae81300f818e979b4434a4517cfc7777f600d5b7d3bb6d7f3f53189c36952fddbe35e9c62c80558ac1d62f85578f962d06e2febc9f330af8a0787501b4f802863b5cdcc6ab8eb964dcfc9c8d81b63750a6358db5566a0e4ff9d2989e98199856af448f54688fdf487c8e6f5cd651206350fbbb5cdd995a9db37b089caa57bbddeddc9392faec0fa9d31b4fc350cab7b6f54c1e4acdd1ef8d7975a1896dffef055feb5889bf87929c7dd65636f6336bd5edfc54501dcbd927ab3c4c9e8077d0349b9a0099801d5948cff3bf0977a9692af5ac98dd593a36d1e5436ebbd78bd9a6bf25bc3d6b5be0bdfaab06ab594fc440f4dd430aad942ed15a8767418bf33fa8cfc659e4543d31ab39b845a3c50dfddba1fea586053768ea482a3d44f3a831b45632070d40486ec7e826a0b21eae37db49b31bb3e9389bd3e354f08879906996e02d36ac49b9c773af5fec53765e9ae7b8c61ce475ac544d13a5b421b8a68635eb6d1c64f8a353416f48b053dc8a3a308c7ddd0ca5d6d75d9aac9a460935645e451e4c8c85a192c91df27c17c0684baa6375b17586f8bf1ef12b91615bd08a340c58629cd45f7a392f10a04916c249af956b180bc418b8a95f66b2d0847e79d247b430812d682b1fb91879faab68f25602579bf0d895073780007b7d61940239913eb217cb16a63ea08b29656712a21a32c754953335c29e769df17125d84c32b3250ec96067b975bf524091ee4013a8b67a19a331daf38a396a765f7820a5e3606a734f5ba854d1e6b6e70cb9ee5b00d4d18d928921ebb8048e284a3a05a3df9469ec53195180ac9f869a8e8866d69019e9730fd6e672db024b6ecb4dc55729024033703b6fdb7bbeeecb2345782815843b7b7664627cad52038f98db605fd23d24080f809a276419c876aac69977998b1400395829656c97be262e053197ead738d9bc995145cb2713b5e181223e04497c8114ec5a05384aa31cb84406f93365d7059dd88db8f94a8f068fcd10be96e32a0e926dca518b3fe9286a755f29d83cf667407758141b2011fbb1764d3334f3a763a17cce33c2816ac79ec4cc4c2d842b004c352aba419be87281779300708bb20143a43413a2a55c41e36444046a3c021a4d7818dd146d1dc335c66152866597aa69a44f39a2814a4830e002672731d93b7fe5f77587b782aa279cc9807d6126392f812e83662d49db231dd3060f882d71d2a0a4c94adb3784ba1785187423d7e8a82f379eecba7e6f6a67b568698ac3a2c0b096b015100bf9acfee522a0192e49880439cc1fa9b30fb7a10544e1867b0c34da981ce6e660cebb8853545994454815178c60b04dca7073531aa2a5095f7b8578cd9889f3428a7d1c72b8fb320f304fe5d23a4291666bf7aa1afb5086532fc5aa347dc29279a4484261614f2774c81374aa453024b68d384b01565a36d98b751297477a61780e98135375af8ef68359332826da01ba6a73d5263abc659454f57d83172d0e515d3754270ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cc407bf027df7e2a505db531d47344552321107b651fa4e47d4b389c5825e02ca1f42839ada4d7eea2ccb24a74e34672bf1bc4f33c88c3603a3fa6ce87aa5cfe30125f99e81550c19b58a807ba8a586415c2924a6e467ca8bc85a5400f910457e8b9d74a11e2668c0f1a2a1d0389361d09900ec6671206139380ebf9390b2401555ba0a57fca36d2742f569a573096a2b442c5992c3fb65271479291f097cb94589fa15bf73cb9319d93860eacf1cd1bf7d380e03587ce3faaeb6360d79574803b5c49841b74918768efb518ca46b26929f68639eb8fa9f73e61a8b69b004cb5d9d92cf0dac9abc03171444a03409714dc1514931182701c19e242ae73b465af335c8d3588ff468346abf76604b6ef887a7eb8e8b44005bb55af328155af7928c732e7805010cf0a50ec68e29acccebc4a39e2aca10084e2543746be6c81d482f6f3c1fe0d31c6a69329d783a1bfa0b43e289a2f843c71196809ca4b82c75c59c7aa5d311350aa55e89735d9c34e6982d17c033937253d9778ca31a14a9894c5d801415056552c410484970cf2ac86b374644a37976ec4a123c0603ccc01c6c6e994514f13885bceb2f8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdbda43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc6467a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +ciphertext = e7beaaf8f14f63e4b07afed36ce1aae517129415537b323347ab73d9154cebfbdf51a20e75b6625635ac552fc88f30866afc1eb1347e7963d1d634b9943db25d14e21030580d7bca1422dae24b0be423349735509ea2b756043498c41a893055f9c7b51a5783aed508a6888416b4f544019a6c0e3766024d804d8c067660161cc17196c98fc0a602b89be5b089e669efe0ad5086971c6b23883567df50c0bdf5508dfc8f62888238b34a0aa1736322838d00be507cd0476739a0903ba622f42f13478b7a127b43799324b990aee9e8bb603c3de3d679e34ef6f22a8d309bb882e61c04dbefa54004eecf710d80bb09d091ec716ad0f4392396ca1c06016fa1acc111308eef78eaf6f4ff1b87743fb7629da989c79f58b69619aa6e3333de32e8ab0df5001b12cf27318d45ba24343a6a1ba4745b3b702ca2799b4428af6360c526b67a2532ac2dc488bf386e7f83fe5dd4049f03293af0459f4879d71483f07dfab14fb1cfeaa7474b45d8a3acc91478723a87a2a16ba6fb69865abdff0e7e18606fc60613ed6f1968bd36b122f345682c2bfde19d0d0cbdbbb051651708d839593dbbe010194280394947ef157a0ee77158398b0d98f7a1f78a528175fde7891e40d7c2055dcb908862434c3875b06922cc3332f3b4acda02402b35514445c90cfaec583aac99100712b3fabbf6317cb7ab57bcfd7057e53580c978ae42be13581f547273dbd53f1c168d0acef9a38b29bc0c35fbb4c534634de64271fab4d9ec326cae654c4b6d8a8b2402e970dfc76a7d31a9649dba063ea5377741216adf8fb01d7aeafb80e8a4ccb9bc9fa2b62118b216815a6fd7c2af7c9b55e666cda56e03ee8ba78886d8b1a19ca0f844d5e2ce6f8ab530baed6057782af9b133a8a01a930c1b900ae48017283fc91f86e81ea77bb6e17c8a00d0212d2c9dc8ab39c90f7bac717c73fc6c05af9a1436241c8c8db904bd2c1d8d2b6df8e83d46220982c0debcedc62c83d547df31374fa85fcb59a4819ff45b8aafd06aac7845137c0dbe64f530c37ab877729222541303a13211c0a9b315111f836fae49fe0c2896a92f6da3786887a42b0c339e0312f6c2849f43a931b5041fe10e277465ea9f6839aee65ca2144668151172a781dc59d7a559f73249f6f0399a80049b15aac6de8b46f64100f31b41c4f0a2d99268b27512d61f69297761bbbc9c61fab51a02c83e13f6b104d89e9efc1f77c7926585cc84a19f3d17c2dbf16f8304fa942002d781be0a3e0aa3347731fd19571700f81cbfa0d7d30208611345023193885bcde430f7868f3f64fb941e8b22192f9974dc8bcf523a3f7c4f9fa73dbbbee9a5c32a1fd7f9e172f5f1d7c0379aa0987fb374018535d5e3c288e855ff53472b5232bec315437513d4905fe3851cb8b5c089da4fd4cc667321e1693a44e598d42ab61880426ff3c27d134db34a7f5f236510cc3474899657de4432ea4b878667ba9140d0257c3616d140cb9b501b0afafe5f2f91ca5b85a528fd920e2c9a53fde5310ca5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ca58edb6775f3d276a56dade60ca79be147e63b6898f4b814c69a06f65e11ca8f4cccec10abdea7bbaf59da651a1b5ed60bb35853f550cceaa1cf3656e0667d726c69a39ae564bb9926fc824634b8b8a706e9fe75bd9657fcd9a308b51a3c4f9822667a5135fe445da8b3ca10e9bd3b6eadbbe6e6cefcda08476909d6e82ef13e4b284cc3f43c3383d7facf7b617348779d7493beda25e4e5124bc5d9144e82179f38cfaea46b3d01b8e65713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcd3d32e5cff1f9f841d73859c76cfbe2451948e6d88defbb40ef86317499786dd6887a429a37f78d3fcc1ac8facc587aa235822cf54a244eb7c6bcf8c5fc908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953564d21af73c585b6ef248c07fdf3116baa18c8455728f3d25cbae0af57d4f6ab2473b5919cbabdd7b4ccdcebe8925dcfc58595338917269dede6ec3885446b60d495247aed57a9fb124dceb7bf9f7f9a9f534e06d8cada353fc12468f9bfb9a50c9f0cde85655cf524945df687df93ddaa28c87e963497c4d5f30c05862a449e330f54cadc3b0c92b9798f5bdf9cfe0177f5ac8f565466464c20338726846092ee248fccf94d6e337eb6b1bade7e44fc29fbfb148936119797fdb2757be05eb9a36d1a00c6f0547b1832beca21e8cd3eecdd70ea0b59ec588cb5ed88ac36bee83848b9f87264cc6cdf0b2e965e5b89ff74c58cd2b338177bf145dafda9a74516a584548ee60ee32b4089506e8cde6346fcc86d75969f3469f7c5c6a97046bdad3973e806778759b35988953c80b3e7574b7cbbff5c744372ef3d42e07cce978a3f964395e5de76aab7905a4bbaa8f50f594c5a96bac4195ee09f897df0376a8a5e6041cef8fccb93d44ab474c569148f6caffe71ef67510b53eb41e53fd0f8b3625aa7a353bbe79cc76d393e219e15eeddb5d6c98f91ed1705544604351cdb877166e8343bc3fa227c1e90aefa3989391cdfc59ec9174f5e6523942769fa2d973774cb6fdbda4e0164bcfd95834c126f1f7da54dc55c44c5947850bd116448f2cc39a06fded868e658a34e0caa630347c3f0f6c86f344816cde3b3a04313a83df2de9bb50659b642353f6463d2e3aea78c7f22886e6cecf66b11d98b354463225fdb4bf3938d67c63f5e949496e1328f326d5b7d70b81d90cc6c5d84d4e69d7833a7a76d3850ac4993a696c4c3eddcf45fa32b4c83dd9e14305308129bb4ff73a91d733303bca920cd183d95d32ca54557a6ff3d4fc2bab46009f3e1d39ba406d92e30ab47f9985c7c439448c92b255f59d388e292cd4df4f7f389de1ca983b22bfba8bea9d6eb36001ac4fa516eee177d06609f62524848973782774cfa795a2286af66a5e5d4fda7093bc54439753fb6b4e6b88eeeff574156bf439ed74b43f417d85eeab1ba1475436e80cec670c3928a3553d2bcfd1a59c46faf542884f91f98a38e4fecd0f6ebc09e358acc99b5dae1edc88b90c98b74c3961c7d759f39b3d3de75fb8d386376cde2b66e00fe4151b800a2eab6a3fb45c8fd932a540c79cca0eaca0a9d5bc841c3acf4cd8097cd4473f6115fd5cb09745ebb986ddb76913faa6a20c8da5745f754b89a990746ef771cf07a6d8109998936b282757f344a1b00b851eaac27a9a7fbf480d44262868542128461598b5597b10cd3a2a26e3f941a9a4719ab2033fa1181ed08e3247bdd396a834e43f5700522cb307ff4b150bba9d8b6aab47361a7947b7a04b8d923202ab1a3d6644be06bc6c1e0735d5d92821c5b8e9b9a83c343d0c456b181b6fa566b0e83602428b6cd33405a95abb623a73299c5b4550a7d6c31d6ef81473489bbe457e744b5d1e39ab74d8a051951abd01a6cff3942a102a33080327437635c1c17966834340c26654a3f38616e5eacb0e489141b14e9d1b15b7fb30927715273547999b93ea2a1ca2189f5645cc4889943f3ccd95496b71f392f78a82aa1a21d66382c37154323c0616804f50125d6b0698e5dca3e2d5658ce153bbf57e4b1908c92587b8c863ff4872e9e1963ae6c971c6ac3932bc974b9f15e5743ec069ed203c3624a022f9a7420ba951425a432b46c5e8bb666091d6f223e357ce96c55bf067b3c3f51abe70abd85a73a42233800853031313ae9971d280b3aed18489e75cdc16cbb3ebc95a8c97a768aaa6c0bb0da7943037bf2b4a523e33abf669c262941f326b11ec6bc8ef51b0666268d6d433b5190bb6996f65925a7eb0761eab6906178be9a923d1c61c0b7683cea681648c44608217d6dc86441a8f423a9d1c288b32ebcd049c15ec151e256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7bd4145e837b756003bab223ff1a74feacc2e449b5dd9b5777d62ff0e20e4b395821474ab428aa2ea219bfa169b95039616598dae0b9282c69ce329b534bc7aea58e17467b1348b1ab2a031324bf835c985371b0f53877dca53570199b23bc4d70a9425a32b54749082e794e10012e9b458205e106da807c03ac3202a4350050815487626bd018706c69a6ab02fcb92621114a16cacfbea02aec424f82fb874800c61cc23bc6618ed75674a70a6c43c4068e2a7c9723a054967e4dab09f337695bbb01053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd7661dfb0b8eecdc2a4134103380988758379d0a73b0f348b00b4b13b115e74674aaac2ba8c2a7ff440340b622b5c0bce05cb601259913c488fee540d7c058a28a0c28b856ea800d26a6a26f8bcde7d78298314cea6056b00a845321a245949a8c7c98d9f8821f1264c658a8061a3014249b7e522d586a54ad7a12ad805544247d74058bc9ac0f603a44ac5199bffb69c1570c4076b345064ec00c5ae0d6a2308947593a84ddb6133ba40577b7b245c20b5d04c5d08281ca0aa10da2a358386d2a4c048c89a2402c9150a7419c0a1aa17562fe786f00486dc82a9809dab08f7b16d9432981087b6741269424598eaa99082525d5db0deaf1b96f55b41ee209f57aceb895babc38828b712724204744834303c496b7171fc458534f46892627ae54800fe6f11d06b6af2b6b9259144f769b1f16c0586c9caf01f8491251907fd213aa6c0bce5b08f060124fb99822d964c502ac49c16ce9fb17eb0c91af559947c056af77ca687c4f675c89be35aae91584cf82202734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff93588f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +ciphertext = a2e6548fa8b141a9e4657c41ef47720a20e1c548a4258cde5bab41b42b58d69e30b6f887f84c676f295266398aeec9b24a7650d710e0211ae2c76b9bdc0c6bf40e057aca0adaba8ad028c66df5ee016268a50ec7a4d5300e8fc128e6a0aa5f781a4108831554b2086f27938a26b62a3f26fa4c9315da5d43e5699e7dbf424f81f6069e3f9512952ba6958108038471aeb5f8317c3767723d1df5f982d6d7a653a561da3f0f0c4f1d8268770230ecb039a3e269ad58cf4e62732eb0a93cbca5611530371675faec5d5a22a86285b2edacb9b79ab07945f7a7d1e759234957a6bfcb47f13853a2d2062543bdee3b833b0925d9410b0fa83f9849cfe70783041a5716842d8d19d26c0e04c9c63fae13ea49197f2150c5b2e59273af8e4c45603e0f3d655e7e1d442e9e6ed3aee5fe0434104a006a3d5aee9f0af9593a9f9b8e7ed1b6b5f4c3be440d970d1b447c0343ea4982ecfc262a35c1567dddbc61439447f2b72fab241632b448e553c05d7e7ace39338a0df928c4a1a47d9230cc89f4f9a596cf5e08d5a724b85ba10132445bd8e5a91b9547bf602036ab50e31d069ba9f542ed462fcbab1915829ddfc05ce4801758d1792271bd4c68a475dac3453aab9ff0271600e80e68dec303b25384bb61febf82822b46efdbdae5a789040f0bd08714dc06fa8fb051f5a74d9a54be204a51e0fa41bc6cf8771dd70ab54e328381b581a809326331bb37783620dc2f7e9f528b7d59d587d3cef8a952f7f96a2bdfe89d33ae7714f3c53aed207c4cef6495ffd94be2673abbf7f3d3a81279b9342ba3093da3f9d280d381211955bfd5f84fab0ee430e63e4d485182e4152bcc715d1bf917987ec85888972645515ac8b2cf0d47c736aa652221c379b4c622bc1c9696faf0895d42d805b971e340291c952b931fcd85e7e56c43a120102252ad42a258791518677f37c5c6c5be67beab159d136304752daf06b210389ec4c07604bd72da410934fd08f053c91be2bdc410fd0b5e5886e0bcbae2033d8a6bfa579e24f2bff7e96e70b880331a4a7211435fdf9f78dbb758b1bc977fa22d3e09611510f84adfac85b151064796623278a0e791c1c38a6854fb344ffd786a8f9cdee2f9be606bd4bb55f57892046fd0d096e1bd577fc71b74c00bfd1c7c683f77f50b57eb93a93fc5a03acf43002dc35025d3731fc2dcadf031a2a0473e2f7530eb5246fc53f32ffbbf94494555d077fe6b01eeae398964c7a7412d5cfe03b758105bcee79d07524efb52065d94f3ebcc34357bfebb2cfacb51481f5368f33b4db2d1a032ed9283dc876c813f2787e14b55de96b6792e73697db908388499ff13a7d14f5a343b8fb37278ec1836cfccf592d47d7d4942332a6a2453af2d82df45fc0ddfc7b83de2c82b28cf7df01ec9171040c434b92f3adfe59dd5243cc80e76bbb95747a2672ea343395c79bd7154c8d6747f3a8cfc93abb97ea2191b0feb819d9649cbb4df6fd9c1835695e944e7815ca7ee52952bfef13a9027598dd893749909d49f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 90e7e29b79c095c3d63f63d58a4baa75cf62a99c8228a4f54a15d40a2e5fe67773c26c7a6dcc739d94d6a6055b399fd4604c7b066cdcdcdce6fa98d858a36d630dc6cec473c08eb246ed9c6e5a55a8d8314334c23ece4fd6a9c012afca93753afa96d9321bed01fb9a2b4f63ddeab8d6bddc40346b8f84afc7b945f62e321103a5219b53405fbee52f56eedeb9a536d13b0dce07d44ebfd66c0bb67776deacde4aadb7c98731a3ee54f5c458264894a7edf6ddccd948e7bb77a2e8df9ce47aba206cd971f3409638dcc725a3c22a4ee24a9938dcffcd9a67037fa463c852f0cd4388ca8ce86a8e9f73f73bbfd8611cf2757d9c56affad47ec19784eaf15f6218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0eb2d75bc25b797e8fa8e0385f01d94d1afb17326f4308487991a7164d8a508ff390f354b4fa3a225d5a46473e45ebb57b997f4f1d3cac01ead4fecd0c0af67d803e17ceb7da38cd60baf3e248cf8ae0d69d30681e388d7117ab842ff3548caa0231fafbc1bc542a7f02fa549def55ddeb5ba4e1dace275d511366ebeaced61fa9d5574c86c17e4ab5f3cdf946e20df59148a7e2ab5c21884314e3b8082ccf10c6fd9ccb6b95ebafef73fd3a0c7d7bf9c5db2ae5516abd7d42cdedba7d9744caaa376f2f189773ad7a59ece42317454d9d8ed56dec637876f104b6836a6842b97e743ade25505461eea77d63a8dad03c7941b69d7f66e4359f2e13a8182fcc35f5ec9cf8e978e35818504cb32e4a6dfc777227a54854d9a39bfa1e2243110e84d025befe1edbb36d4aac17ff152599ff0ae77b294bece49ed47553983f4f0de5462c72ab589bf93478da399ac40ef35a5e98e9459eda7bfdeafbb29a446ecbcd4e45a50176ee30e526f3e4cde085afdb3d226039cec4ea14d97f56bf566dc3dac77acb80b29b1f9e6d2e919707c96863304372a353772eece9a4f41a12369fb04fccb53e55937f4ce5d85a589b1b4ca46dc49cd66bef47188e51e455741c8b5d7c9cafcb75bf27a5b4fdd5b22e932b1e3bfb0c932495dde5485486e0c39fd5ccec78dc78f6e37be96823deca37c73d6d31c91420cd4ec64dac12fdebbe9bd5237583e1972d0c4676708ad35b559fb89bd8734f8a4ed50445d451dd65f58bcb293cdba437394dae55e6efe3a904e827949d16a18e936de788c58d7a54ad11b89528fc6df386632e725b163e83e1063f4c49e4f26f389dbce99a926a25b0f624d9a530cfdafafa4c5ffe6a5efa4f2e53fd19ff337d1ccffe17ad7daad46d193e37d477dda378e17a95fc8fdfecdecdd5527f4a4f36ee7648c9aa771bd15ae29c7f59abb63d0983917156ede6557be445735ec539c2e99fa8e6c562842627cc83bcaa659075f5179abdd1a7057df7f7dd96a6813a940a9321c0bea46e95c16836ef038e06ccf6a3ee450d8e569efbf3b718ffbcb08f9821648b1668e6e47869a0be7c0e4b827c4cec3c4c9948a6c7f874968dc80160a811ddd6d58a885d043f1044ea6f89d7f53b8fc98468f6bdb7cc7b6d107973db0f7df9a387673234d6675d19686f15ee4597c65a13a2636cee74266f373a4e48bb1ebd19bf44ec0bda5db55c6cec7b63c0721aad84d2b6551fa941167c78a0c105ed9e5300a24bb2c8b2265251a38ec2b9d05a0635b2849a81a2a7c6f2660504d5602fd2763046820ca168d70b76e35b9641ce46a44f2a394f496dc32353c1a84302381e8d74ce4294a4a260a5b0704797567ae831d7c4410593cb7b9ab74d2042c84805c3aea6ebd193a927c8189082333b3a5e96857e3970be7daca4c884d7bb0b3b9c250cb4135d0b8c90ae320dcb3c423e8a6de79ad594240ae7aa036e320ad8807ccb7a1bc80c704c9532960864a9528347636b4123337db7e2de37823c6ae084418fdd05ff7e904211924fe5a370537762dfa012a2153af96a46987776d245fdcb9434d66aa10524a3ca74e494c9de919c8e23c3ff77c58cbd1cbaf5b8a69803a32e23959b2a7d9f808689906a0985aeff5a8464a2af64ba053a3c18d89b2cae3814cd712484288abf7655063c403f635d7a2afb9d804e2e89677131bbbf7009c981548036726d25f05f004d605a24b7c2bccc4294f065c013c8ecb242d25611b5c82bcabeb9e578758f2f3ad3f087bb6813db1f3990c867a2e679f47f074fd012e87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c870364192c555b81af58962ae771df477ff421a9b46c6e64bacd1a8a6d00da4d9507212c910ed2c62d199c7e330a11982c514f27aac092a5216b13ad54beebaa4049065a68d8ce9b1c969ea01599a71d633197bc33c2f6f958f72ccf14c7c09d973770f170f1f7bb9e458a00936d8677717f4a17655bc7a7ec56119779f7aa391d2356ae3a97d7ca04971cc2515154e148568c176a659a8decbb2c5c449ccd914d3cb7431cb3a0a400a8c7b59b1cc770c5bb5b64e0932c61783c9979d6cbac042216a0cc5800ea160c8c8556e0721d610fce13992396c382e93bad1514d780cee046525c443fae063c5882a01e5a73658a30864b1d6344a6cc46729bab7810c46f5b480d309a263e30461769a55a2965ba6ba0b44054f211b98c6c2355150acab81881e5ac1e561a4bc4b39f9902d1027e56155f5d71b7ca67415185319ba769f88345611ca2c20b233dcaca9ddba42edb204576bd028a79bfca57c9dbb0a54b933c970de35032b9b51d00c9922abb5106897cb896065fca846aa486d9c27f5b616e99ea0ada711729b75d86669645b9a223959b3c1c2f3ab6536d74295473c4c055aef8c2cd2d321e9e73cbb872698b3a60667bc768014332083139d08c321157cff1481f259ed56a7a3ff1717bb64fc951297c709a4ae3c05fe3910d6507ac947f944b970070570fdc9843a8a5ba564141f80f1654766f93048be6297a1cb76c105a7ba3ada06a42ed1ab3c17542201712f11824766c07bf14685ab0a9f69a15ad6574e59709d2411b37b509de3b7fe5e8b0ac65922df23e680c33141418f9551660467accc0c794a67cc530a5b130b4cf1c28747601d26983764acbddd30e42eb96125956a5870142574419977209a12e09ab3c5e8a22c1c5252527c90987a816b8830a757ec44b12e2e2bcbf19097d02b19ae47cc7bc99189370a1aacef36415ded82fa7a63be809b515f79f06612dabca5768201c59e2c92eba6d13b72c31648ee1d504ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112ce2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +ciphertext = 459624a950aff4a380db1ec8f9216591e74b0bfb9448aaae1aaea886c781c414fcc95ddae21c478a1f1692ae703b8b80008661919cb910ca02b76b9538fc9dabc00140c0d790a88245d3a3e70823da64629066e039361442e60d25defc22c16e33f910c3ebec5d045bc9dd1a763fd42a9ca61037cbbccd76c64a494c0e2b58cc2a4e8c1210001cf0da6a2595c30b36b3cbde8d08dc0de26377f0a428a35ca414cdcce0f7e3d4b45f0a32b167587521e57c1e677a23ebb39753f1fbdce24a3a8316d2044165d2aebf018dc0e4fa4e89c75477ee02ba8afee69df1720cbf5db1d6658b7fe8fa0c5672bdc7af5fc691cc184fa80c9a4000b37b7bf8ab63ac072309374277e8b01a08b6e717a4ed0c0357487cd7aaa702bc593b6669e63ff8215e684049ee8466654cc978f81514740b20038adebf7cabf9b21dce2405726d7ed474f246867edc20a729434fdfcf2402675d4622230ae94fca7ebb4a273380d53416d587fae57fbb7907068f04ef35d7205806ffbb3ccca0ae38945966b7303ab930dedad2d02a4cadbff6c991c6af14dce43b59c55614d970568bb8137b600401299d2f7bfcb7ecf7b11ffb26a9d0c3b753c7c58803447edf17acf17e77d1977aa8357acc332662bbd3f4a1396091d74203b1f06c1993df3e34da20762a0bf8bbc1d0732d8d011d0f09264ebd1d1977bacf77c4fa030a4d346f152e0f1a132ca1b4f996b548e93104ad66593d8fde6d3c6eace63e1d0b53372f6e0bacf148b0f4bac5fe90e7467dcf62682cb70cd550257445758a6e159e092ed1952bf66e1be065e541e32954a08f8e0eca909ebbe54d4080b1f2e482952d912a32592aa089c82d7621d43ef59640a910f57ece74e5ee0af8a6eb59836c266360ef293339b97c194904bfe37b3462192247132a2407e27fee0639b4e3ce3e62208d0fa299d9113e3430d52eb295b170320511d110f83c05deec70b3e6fd864fb15912ec7e5d358ef277019719bfda9eb01e80b98d98af154aa22604988fc246fc4e1a1a7cf7cff87825ac183f5333391f32049ca0b09d57e1a2bc983c091bf55e048db026372f7cf673bcfd5e88d36fe0faefa7326a057caade1b50cad49a2413f9718f1a01aea81de054c0000dbe33e21f9081202f5c5e824bf240561c2f4f50763cc9718e66746da4443604148be687dedc2075fbb3814d7e0a2d79eb6695e7dcdd45ad9afeeecf58590ea21b1f78e273289259afbc7f97ecd517bbc8f33dd95bd9ba0da7b8e72d8ab1f336ee0dbb6b0e43612f87d558ae2315c91abed8f8c38c2d6b00df17206ba9752a8e958da506595f2c65a53e767d0453da2e70dd14c3beefbcd32fac60fafb379b67ea1d69c0febdac6558bec1f7b190028eeddb618e0aa70f4c65169533eda0a5f3a2e35cddec4d11508685278ba688b2e914ff23997c4d4b4d36e15113fd7bcd644cf3b4995799206e0d2f87f2fe1566b7e7ae721c49b871a30d16ac0cbccdf1747333745a91807ae6dc9b272558fe1eceba01bf5b68dc54d73dafb5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0246c2035f46911b525e6c3421584bfdbc83d73ab936e76a26236a862e5c78db7dde1edc2e038e3dda69b5bafe9f4997d8589bdb09e9be2cd46ce5e8e6958ae79f51470d9d185b53456b5e16d592580fddd0f6677535510e0f602d5ba5b61c4410ad7facbeb5fbb38437f9d52266577699fef205a41a2af084adf648844dc9d65e643f66af97e482fd36a2888d3fb9901355397f37875a4494777c781ed4d479dd9a831fd4a51e5702df5a74b4bd91676ea649efa26d617d8dcd06bda80e14dce02fb29978ca5538ff2d4d316a35433dcc8ff7cccf438dc0b11c548b5cc08fa45bd086dce04ad2f25689d1fd57fae44cb1574c42e760cb43ec2ce4be178f3dbb2870592ba84403dec417f9869da0894f5e023b856f1d6437d6d74557f60a856e648cba07f5ea23f7dd7cc65656b4692fcf4278fd4905c4aeeaaacd3644ec705b504cfaba743dec2745ab07bd56f1768447a8ee0d676ec904698eebf30f369190d8c1dadaa5ca69d01ee8a68d4dff04298dc68ddc57bfb577d89cd9a585b249d89847cd3e96ca80e9f8868bf7f36579887f4ff913e64acf46cbcb4673f6cb8554e50c9975a13938c89a68cd0b6de5237fc9dfb7a6bb94e1cd85700db821636801e9ac84f35276065ee51d8bc1d755c1d4f8567aeca386fd050458dbd7d93567a4465453ab8656272a3c03b4a3c569f9271437724471d5d4926109c9792ba49e1e7813948107df7c33069eb3d4daa847db7aef3f35934ac28666ff7fb4408ff151f3c26c96cc3b6a40daee876e55970f35f81117dff0dddd71bdd9e497ef137ad8515ab239c33e2de638c436dd0c89cfe30b8f8e69f7f2c59fea394700debd637be0876c3c388cd0e15469b42b80bfeb8681dc7716cfb248ca6fee9fa9399b72d20f3f9517f29593bd9bd936a0f6abba09bc336778247db60d9cbd0e8b3d5754e01c8ca97eab822fa4cc399b5be3195cb1e3c9270d30b06dbbe3295c4de898c60f543599e42cf48dbc85d5ec9a9d93cb6dd4c9678c1cc0a18fc5632af5524f603ddcd1fc07c27e6f8d8afd9b4748e6b5e5e71c18a3f9737bd6d3420d4bccbd3a5625af686e64d62ce4696e16ec83ccf587fea618639e51e63bc6c64825eb50d4f88335bf9145bacc4aef8dd564b7a588f17fbcf30bedda44f3acbf8753aa67fd67eeab9198cecdf9bc722455bd267faf98424eba4031c3bbed8f98a9388cabc6b3beec7a7fcbec8158e1117a9d5514d7c9f6d99cea65ece641f69454b7adca9bf86a3dd472f8cda7703c6a5b25464c1bd91b39f58de673220857878434ea14cf50054fb2e63547e9be161d7beb7a78cd6cd0ccbe462a0347e72b51a15ccb5c333894aba511295b37c97c7f5cfeb6d97219559b40a67310f457119de5ac1b8e3bee5acf85689d4d58ec9adbb18b75626de1f38debde8ba70986b39d3368e1f978675a49fbe850a01f39a1c88f1df4adf0ac8b68a87e2b4d3373fb808a8be19247ec7e68b80854b0e433573919db954afb67999f9878a32415b78d3ff89eeaaeff3f98fd38abeb6abcf5a55bca388004e46375b7f9cc45926a7c3e3bc8b4e3afb196aabe575eb643cecb50f666a1bb6da5decce8c6344356a68eed44214453d03b5c7a2912329482f244226ae33507ba8fc8366736352380b346ca39a936190f09576c5188c5e82315e3532f34d41f1b50bccc42c1138802ccd5b50a7846ffa7bcadd91fe757ab7fe30e873ba233e13b21d25461030593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236218f199c3925142b53500291a3164516fabb941f98f0daaa1e2d619c9622d649a0408ac02d5ccb9b787c1f9b196da37020e362ecdbab03cccb63b659c6347104074b1f8254499c8452364726b1294669a3a24ac8b487752175b30cba68860184d5f78b845b107beba80f8750475d059dad57caf827878b926facbc00b54388f24b7b431347e334ffa046c45e234124c958cf66023dca620e1400cd5c08b89554a474d7d04086e5cbd0d051c03c4580d3442a575255c833026bc19dd301a70367fed300ef27779d2a49819a370519c7fc404acb3fa441a931c67a3033799519c883bea134242f35f92393dc134bce15713ddb33e252b991af10c7134a8acd09408c8cb2ada36bbc25224e8867a4138ed9b4daf403a477321614b3ee5c7bc2281441936b0b05513c1525421871d007346bcf52d6e09b756b4529bb5480aa3165e617cef41720167707f35a4415975a62114c7918ad83bbd8905a283d14d22b2400cb29fb1e102562cbee5a9c10929229f8c60a4b153c430a361812e75b244e4c3954a945459f735d45572e83b505030c13867c720567fd681c539d7094f5558dc5a86da79b38049b0a45a1259713af2c1640ee0279bb7191f0c0ec59c2f91184ca70a2e8b7576ce493e32f2c549c4bad6c925039c4c57114075281ac7631ff4d94ee0723c3400cb2d73c184489aa5b440ad470cde548f2f70903d08b9b4cb6db68a5d4fbb049a5a9727f50f9e6c59295c62bed7182ca96d6093578dd014f7eb0b121ac6faf917fa9b47f6650c6c7336d8848dedb92a0f70971e456e9ae625cfe266b1000c4ea6252de1ce20c014bc161fef405ff327cddda37be4919c2a0c097d6995b0eb743ff66a548307cee1080a13841ed12333e62eff081514a5915022c550c6021a27889bb0421df3a709ab2f9f3b0c0f6019fa8810ce3a9c37f53cd651acb4e5bc1d8b231f373b7a4ca6723a9710681016943f29697b09f6abfc1c60e8fc4c201a9ab05c260d2452c83b88423b904df74f425a9b4d116de0d059d96779d61017c2e984c2bccd6159c82dfa5ae7bc63e59304b1105ca054a71d753e7e583742e715bfecc80e51245ff53c16854ae0ab41c581402221cc8834a5f4556a84c19f6172c7c80c759299a42c71bd67040a29185a45c14b91b56a4af9178e0bbb0c4c197549b5c9765a8874686c63445dea7a85d43ac4d0b979b4ca13a80bf8db634a163fe3f4327210a7a128716b9805bc1920dd322b15c74fc722a126069abb8c95bd090f84497d832a1ab72358d4193b6542bfd627a139374404dc1998416f46054d1b4b538e778d6d0507fbf5571bd01ce56362164793e58355366495aec80eea35463c4044b202451b3604d6ab96acc3617acc1015379564d6a5ff1a6ae4d802712a94422a99d90988206776055545172b0282b5162b479d748a2e9d22356af11daf2629036665eed0642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +ciphertext = da88cdf0e629ad2c8000929d89554053e692132ed02ecf7f3947121c3da49e64e1fbf87f48d8a99818864eab9fe3b715165503b6adfd94b6587c65864d0ffa31a1e2bdedc66d2ba36ecc03ee41520af6302c4150a1ea1bc153edbf1a8736f3d57b22e309118019a6262138f311055e9b3750cdab2b9fe95b8be05934a61eca00f64aa6ecebe7ae12bcc6da07b91001fbc1d3161ef92592d0fa8a86d2a5241991174ba94a054f1c975b16bf36d4550ccced94a96f52433846252043839a01678167bea5a5f613eb41b4b33707999e4380d10097d089a44a721eb888528310188f6d9e642dd7677aa1e19fc710c94f645fcd2ce7514d69ef2e4650c6df9034475f6eada37bb02a268150af7b5181db8b5ab7242d601e4bb2ffd9d508d2988d4e13b5ab0e85094aaf296c8ea577d75de39a08e2bca7e3bbf132d886a2965b3476f04541e47e883e659a8bfe1f4c16881c70425528c5142a389d0a3f96cff2503c77a40d5ed881597fe8e5b9ee4d3db92cbf20e97aecc5a984f4d14445a33c31983353f9cfac3912150c7c6a48a8237f3ddccfc80fac8c8d73e4e527012170b3f485faaf8dbf3ce42f152b16bcdcc40418ec45e78beb00cfa936f31e16626278ba94e8fc0589abd8619aa057880672509a4344500c88f05210705220c0ffc327e73a9751a2e03606d0400d6f3c5bf4405ff0be6dcd9629acc2817b7bd28ffec361892bbcffd220fc3d9813e73aebf0929b814953b3d02a5d5000ac52e3a81cddc5f64e2666d4c86af23b1f45efc634f18f512ceddd5cd52fbcc04805306a794a61b0a502a6eac8e069e3aedf5039fb6ee62876795e874d6cc7cbaac232c73806644b49e10e5d69b5493e3ee647e7f92467cd255da303031270f8366c6e39a91143f92b9a803fbdc42e83251761eef40928e447d43e75abbcd57b97c207cc35a66a64c81e81a6ff33aa58e5e6dc047912171b53e34bb3ada16e57c2d7aae76c430f764b672f60e7691ba73fc1c6eaa57c2d06609ae2a6ed311c6479c9d3c8c12c4be9ae17ea146850f5676464a63d3c688c485e1caaafb515bb7ed4ed7f3d47455002eeb53c6282ff810ad5cb2bec2c5e52a6c6e5e8227c4ac72a882c45c9b2b90262111e58280f0cc6de4c86c667bbac46151d06966641e3cc67c86d06825c3c53bfb03a2505bc5731d0909d384ded3669197a2668c9d9c9baebcffe8a489dd5b6c42a3e2b65b236a9bf62db7342b0dbe07a04e2b8a53e7d4cbb520e1a56d25f427d2bf61a1cfbfe72e6c09a286bda114642237d6416053fc077f0824f439ace9a25433f57896157298f449cab005f4ce8395a904a3590f8940212a9c39c02ba42fc6dae73451e48605f2431d463c2c26f6050a3412c7d5b16a318286f8fd001285b28934f956138d7ebdaea7704451dea0641687eb19d87b96dec22f8a2ba755a62435a51f9246777923a9430310f529219ba8ba0d948c6c6dd13d2c0ea6f8c921ad9a3b4d2c9829aa9571279984c2bda818a338f3af9ab411c29b17fc4caba1ad3 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 34d9ef6ec981b193d501d8969f8847b2c6bd5d5c43e0ad44c43b551f7edd5675bb7e7c9e393b411e6957540ebf4ef4c7fd0b4b5affe3906af54eb5540aca856c47ddd28899541b72519ec23907c0449dad32a56385075f42a754577f5450ee77b74c7ed9a5d7e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d63de165a47392efea7ca732fe9b3455c44ee4e54fc3a6518e5e402cd5a2d4a4f9b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5ddd40245543432cdd2d9d913776e1cfecfeb928eb21c8417e3931aa3be142ded51cc8faca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac85f4f3855de3cdd967b7bee0668112e5ecccce39fa73374eff685a3cc06838b15009fb65ce7772053de3bd5cc4e5e832b8a2b94f8436d99e1f2484b127ce0d96edc9beeab1cdd19e0b3439733b36a7a600f4638e9fdba66f4b445349a86465e2bf5de797f07deadb629cb472e4e5a42a8ba29eb76b68f9d4d987a3bdc2366fec188adbaddb603d755eb37396cdd57ff86f76ccca997c0dcd481587cb97f8841df1dcbb8479af67b744a5c0dd8b4adbfc1f7f6121996e55c6dd40f6975637831c49f845d6823d4b909225e149a9f794f4ab29e4e64a54f39f07c365a87ed9786af7a57ac0ccdd4a2de8007b6bf87d5a22bd82d2ed40a4f4c25f3f9ef9a8518966d44e7683af94728487a4f963d5d5ee5aad45c041fecf9c54fc51abfaa47a4dfc39d63243c21f8b83827e701b4b73516944efc4b61fb5bca63c3ed13ae23f55b832e6c312e8bc49fe45d62953f6adef764dd68f2c9ca05eca8fcb34295f936e4e4fdecfc04f65ec837d71f99c7c24c991f9c97e11ed51694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0cbec2d3e859d3fbd3c1af3b2915e8ef88ce1ccdffe71399f07eb380fceaec4c7c6bf3830c2be5f87e8d0e57ed10234393d94fbd43d5acdd9cdf17da0accd9d7497d2f9b939794b923eb3f28c4d904a53a062e6a536e32d9f3cc656d6b41ff643424f645d79481a8316e8cb0aa4fea4c63da0bde39ed5953168a4ac864c726874e1366ab0aaf49f35ece5b1a7f5cb6dad66375bfdbcfa3d7ad24ae364acd3327e4d9fda64581dbd0a696557945c58e96c1c889be648c4885958adea79ab31fa0bb15506bf5635e437ecee47b6013fb4273b8c978d6639c87031b6e23c7e996b4576636e2438eae4dada8fc18ee1d9e667967b25f76c4f736f4cb29bd0a865fd67a4dbf14acc8ad9871bc7adeaab37b298f12c6db647fb74178e627e4c8347cdd3449f716fce73b1b711b2cda1e1eddca486bd5167223658a5c55bcd0739dcff3ddfcf9bd8aa45b3dadb5aa0f43547767a1843e4c8792213e819e09f5990dc6db9bd270f9cb8f36f4ad04ea984e870b0630e1cbeb325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310d5eeb565baba36be54f6a3152ae04a1ec38ef78e62fe654ef35b2c836c242ea52fac710d7bd3811444de5b8403569c8ded444e06e6dad54ae5649e68ab437d0da2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee8cf3608cd683a38f6fbb4bad4a58ff6e3bb322fbc8e892a62437ce84445f2e82b495c9730fab393dc6f3b36bb2a63759a79ae27b162250076a608522440ac1e04630ba766b4c256341c6ac967b36e6934dc58cda15621827b9558076361192e89708ed88a71826a20e8ec948b9c7915566c70a7c15a72c36ecc7a3cc644eae696022657c53500a0f13a8ae50fdfa432d8d2530999275e5b9c1d341fb34b8a5a7421b7d290cbc3218486b555c92572bac8f1085f058a87fd48796824844553261ca11f06978a03f3a8d68657c22064af83166280af52270e004731d20b18982283e51ca3db7a2679da6fb0aaba1e75a2d283add699a797e1be93502c6823007ba5b9760a338768615b671baedc6a6a6937b9e1c35575776a4a791fec7751079c6683ba29ea28bad199175b9629c44bbf219cd88a19f1089aa551946e58032a9c9dfd29bc4ca3b654f494990cc02bbb8e1280b54ba3920ef98903f171c27a5c0fb679c8e84774f22136e89915a534d973733410a96280a3207407235ca0d81a636a35b9dd628dee9a64a12918d0dc6d4c600989168a163730fab8c78e61a57970c16c813b791a0ee9f625c438ccd1a9429a93062c4ab38da5890188829ad116a6f1564a43a2e4f3bba3712207b65e701995c99b29d691c86bd9844af2471eb5cecd934f764629dc25839c809432e395fd8582cda980359246eef0637b9771fa5853099007f173c8598164da69c8e67a910a50b9940b213547815e0589326b02ff21b89bc4200219652dea6ccd59883e29127e2abe3787738b124d839a67e02195d64989520737e3aa99c6822f2c32249256c45455cbd931a5a1fb27cd56a21e22b51c03217aa387e151631cfa445b2b77ec90ae01828601961ada8a8e6192104f02ba5064c4efc27cf2dc3353fc98f34bb947b21ec5235fba6caffb6bc6b1c09a783ab8ef14c4921a28a3896bac07ae8ba98c117b3624e01ed0496a8c649a38a33fb679bb535a7d1960028ca6c8ba825178e74f0e50b5d74c2a9119b595b863d0375a3da173c63a03d8c60a8d613cc08064588890e3894a9bf4580704038841526ab84e27cabc8fa4cad6dbbde9b53017f100778478b86138fbd6be713a7e695358538bc4cb5a4fff531bff178bb16ace5a295ca0340985f34267a3a931998b29a36935d3b13af0631cd37777689ca0b43b9208afbab88ef886a8672b331224c66c6086b8b15a8eb86107fc0ae260bf08f970cdec98ece9a197751b6996258ffb6dce05306380770dc63498e9b5d65acac5a179d8946b27630525b39c3755c070a120c9f468ab3aa8b1a48848081b888baaa1156bd600733be887abf962c46107c432c34edca8e549977d9a6f7eb77eb9974bb353896e8261502820f599257cd9c2852328b0fbc5c2b98658d67e4a636575a46e074a1efda2cfa50a0594b0a421661d81d95a9ae0ca1c037532ba7eead089961c29765c443d428bf20767d1f08615e85d0c08b0fa5076e297143249283c13486f61a4d9d39780624055d6043120a510d4a686f9b490c74f2da782ab42157a00991be019e093a509c0c00b7c1e6ab611dfc4373c640a2f488e7632be1289666206cba2b096a479b2140c6aa301bc448b13b6839447c4675aa1be46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad865f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +ciphertext = 3a289f96c11468b574dc8fba9ebc8e41d2cf47c1e08dd6cc9fad7519975af392d0f0608ff43bed72346208e0de7a19b1b5c6de3ff343cd5647afdc94a8d079b12207802c5b35fe1152c55cb37d5457835251f7d101d540c7fdf80e220bcda0305d8ab89f1105436071ef5c588addb1753756710e7ce507768236bc4637ad18749522ff2d5c238980ce4ff37d820ca43330e680d8cbf149abe46c8c856642191c8393e2471e3078f2860e57bdd8fbd5cc1c696e145f57a179a5c85393e05604a76c70342c2f708ebbf150765d7f018101a0b13c808886974202ffa8fba17e7579ed9a7ff1a97f323d8b3e00a00e19803d2132fe804248b86a13f4615de551a0dc65e2f2704b24c9b43c7efccb42b5ad4159a4e5b74c87f7df156874cbe4fbd91c2048299b27181aae40bdabf64657427570badae13bed38aefbe8d7f130ab272562bc3724a1ee05c32004b3e446cdf04a31e7d1628a6fc3c0ca547d7addbf959ce5038f5f6ea655df4d4d2ff45e124c5395833041582498fbdac6fcd27624e015f652d16cf7d8938abec77ba550807c598dc507105e855ebc717c88082481b92f1687bdb9c7e486774693a9140549dee7b387f28227a83968cc61715f68122e5e46b847056586fdc5037645f44d9654fe0aec4b4132d15056a2afcae3b31f0a0deef2964a7d039f61bd1920fb47facd8718d6ccc429704b8dd2c830d3c168405e9dd90b7a7e1fedf9c5ea36126ace5621404c6806e5a95b1c6495a3885c6c6d62ba4c5122303ee901c69c14f9383e51f8b565b56c1a3d8b54f048dc01a0193ca5af367e4fb92c47a019551becffcd2568ddc7d57b66b3cd5449cf3841c66d901e2c9cd6a9e93831c7b9e78cc26673fe3a7a54c85d3323029e5e9a3bec39edf9d4c00e5e1d939219842255c35265066c534bff32f32887a3a277e96525880bd4bdfa97e26083b4342c4f6882a074a14acfc1985732f732f96072f20e95328d4f52be6f3ba7d3e3972d6bf5d584ff7c5385af1b749af453356cfd6984591269c5014f717fc992b6ce5ff945ebc98e6df117d4e237112dedc2d8f1c88adc466ee74f612564ee5d49e94cf33470f735c3dae296e8fc1642c08308e285f20729c39256cbd63b664a375eec8a04e6e9cbdae34d5f27350d3313727c7b2f2612657865db4364551d315d8849a96e8525ce6e100ba496f6782e11b5d42c6da5f91cc4bce2c77c65c029de1f67f6977217d9256b70f47c4712260a8102a110a94bb3b7e26dade7b0b9cd0c158bc95262f54087eaf92eca527ae4cc835d443ae7c58daa2eddf7680637e42da68564168840d87bdfd5797ba90967299dc367ed48cd1ab7f1a0f094bd2915a9508ff2db189ab6aa2f7d813a9e2eb219620c8a1487993417319254038037c080051a98da562a0176436990937e64d458be7f34ed366aa942d169e486b163cb8153924d750f1c152759f36672de638b3f3afc7e569ec52165887acf342123a9d88d6c795ebdf6f5cafafa6c2a6e03249c33a74e2d12eaa9a63a44 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = ab4545850434076342eae840a0ed590c34955e96d2683d5fca05c347bb3e53bc714f3e34a6e9b338674a9aabb0301fed1a09a190757f03d573c27687f7e35f2d87f94e1dcded83f218395b3455f3f1c7d4b27689ddcf86b5c98218ff39c159ae5d6554370dd617b5dc6dc6b7f50ee2e7f37a103e9bf6acc7b0e3345c9367b3afb8d9d644947ff0c0b8e7fbb38ceb3469cd55c662eec58d06807504443448c4e64fd4dc59c60b5e53494478ec4d56c9a85967b4febccf87afda51fdd6b84b285523e4ed80a56f7a68a168a4527eadf312be8d5e48ecfdd578bb89f4fe687d3aea56089d681528e171b7f7e4dbce1b678762a8b03c3afbff1635ca85332af9df14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83c9dbec37e72ac95e54fff7b926f3842ee88d77bd40f958c38c8a113cd5b551d3e56ae59de0954f2477e798a573339508b8cfac397fa6244f9777ba3189d60136cd83f2e98d2edaa01967c3acf7373aea36b9fbac3cbe3ee3c94b2fd391e37d2c60f53dd497f16f39bdcb9c68ccaab642fd84884b113f7df38555422767f4f6e3b2e87affd0e395fca37df1aeaef84f63d2dd1392732daeed47cc7c6fcaedae6136c33094526876a1145e4f39e890963fa75a6e7dcefc97f8fe7659d995dd8fb663655df65324b1996a52e50bf4eb2a1d9df04bfa6f14e74da2becc7fbb024c3c972b971440dc684cf8a90f48b02cf8608affc3fdf5601b6d9673481b365544b7c36a965def20c37006bde396af68f9dce1b5f71e25feb473d3b80cbcc82ef894d7569e83cff5d8c6996c766bd5d59776f8cadd84a3f468c68dfd9117c8254bbaa1ba584dc2661728a69e959949ed6c9f1c4ff01ec8e566e4aec7e68cfbb5e175d4eb9f585c7789c48e59c17b5975c444bd6f3fa6654bce298a605043bd367400c14b1d9eea593ad34544cd4a44c85711aa66d8d7fb07378fc5f5601ce9d9a4a9a8dafdba7ebdb1eaefa46ffb6d518b469f9e21d25cf40499196376d3e9f827e1b96ae255aff288037793c7ebd7e1d15533c17e62aacae3255c0cc368e2fba3fef09540a5f910ebcdfb2f3ae376aa666fc97a4fef2570ccf797c79ec575836edbe6f8d8b3dbeb72e8f41c3679bf26df0b6a63be65b95a2d9e47eb98c6553c71c65de386d3e6b73c877c94e7c6d3a22eca457ce409d5aa049673d0fae7c124be83579f253fcb589186baa498f3958ec3d0640a4d34931033b31ff6ebed6ca9c49ba70cfe9d6dc8461937284235a6417cc9c0ca0ad385b05cdec81d5a7b97a34987f50e3679ac55c3d76d83b1f7b99dcad39dc1791482f3b5d7ce1fdaed9dc16fa1e4b7c88d7e0c449320949bb4405b28fafc04d48c58aabb46edaa58e54ff3ab6c9810b6d702855f7ca91b07eb0e574bac114ddbe864ddaa7682787483a4e4cf44e8d180fc6f368a10714cb26ffd8c8a5779f639838ad7e348841a127e4f41399da175c49678307d3634d6b992198dfd43ccb8d7842e5f34ce44a4923e7ce6b77ec7a989aa748604d147ce7bcf5a1533e80ab321b7aacb8e5f3a3b6f98bfbdcfda435d787e49a3e73d18d8280bd7b7855769eba987696afdf68f31f46ed61101724795296a2499158c8e1b50e4c900d65c8ae65503932dca40e058e8192cec2a997cf12c8a1227567b12a1b21bb31d3198c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397a9133d99654e6c56e7465d9b98bdbd624c12e36c62b60b6a32c9086a8eeb9b8919706f4573a33c393f74bb51d5609231f1707e152f23f36f6c6830ef28253c8cb81ec5c27adb02fbda5302212826f0b88aa4b4d72a509e29cb1bfc8177c019c60598e693bce999aabc4621123415235208e7869f62aa7b50a51724c13da2db59d5ba5302c772f2c1820fb0882ef32f73321c17f40d019cad39c3b12c57c3519ca0b38366ac4353b133c39262be6ee47ecf660286f6ca8eb7090418aba0d9833e22b46b761fa2872fb80972b551809c02775be07c796636a2c619fc748b90d28e1e702ffb0653e250c8c3759178c39e42411327a81c7e7887b21915a5cc032c37a11382c4d9186221b1c66afcae8184559910201c8baaacec62bab984e080433b9465e64a2d987028e9d9090cb2c41753742cd77f0998c672441e83d45f2d06c22899c2136362271b731f6ba3965b32e2517463e627aeca0ae5644bb8602f7fc599abc120aa111e2e549a276a18d2a92c39502f6f9519ce76c0bcb514e8084c7122a321479338f59ece08a0acd30f0ad68f2091855d5980219083398a6c0a63c70d3743678a1c0202a69dc526ddb77e30b779c36ac2575704ead94ddf1661a38b2624e733f2e2ae18467ce2c3083b75017411390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae1c29bdd6656cd75d9ba453aa115a32745f2dc1829881a9f4d5cc2cc053ab79b89d107e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b102378d93990cb8280b21a5d5ba8415c48ec17288044623a9631577c16639922978258cee0b6c51bbcfe3f70be07cbafb7c58111cc7f2f922aa023d5ad01d2d31a57e0469ac428b6fb88a97d957ae22beb768c3cb7c9f02f583fa2513db7c580d2986984314e8b346a06501d8972e31ab8ef5b983e9a15e8ffc624d0041fd523570960e09e57d616a06297bb3f9d938f5655628b06c4f6c4fa5f8136f8cc05dfab7389237ea75aef46117bf1b67aa978ba622491260128e743f28f95f533b708f3c59230b23faba96ffb5c239b32b30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a0812f59d9b5812916246228f2523175242cd1f432f9fb054a8b52d824349dc0756091b2f7c21e2a899362157bf9f631287b90d6c80fb55b1469273f79892435d031b62982c49a1464e2274f815f56f3b6f8c949be11388df1151e7077f603ae592623e4259853a2b90159344b041aa29c8afc5074bee81959102e0c57a761f1b1aa65b1dcb66a18bbbbe12b2b2942a37d13c77c77b2bde758eb1901f74c7d57d373a47737d6e23998e35dcee70983359b4162c7135126e90a807604034d52add3530456b66f0da64453150afbb67d67d9b359137c2420250c279a1c537ab06952e4823f09372198c253d5b71a7e70a1c48b1dcac3a85feaac35a11e670b2840a57f2a7c77b6a00cc80a282f0a1c8160080c702d619a6b6d68c757306c93a5b21ba8185b1a46c79b03c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dabb8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef457933fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +ciphertext = 85c0bb95389f7e5801345480ef8cd5aee04a6bdaa435f7198c4478ae8a16110b5356cfa6c84c202c0d7ac5a13fa01a5b08611373ad41db6bab6783bd8cb03964d27ef42e9ca1d123ebec7f32f21bce5ee855a48617e85ba20ec6da894b582a88367ab489b68628ebd5195d7ce2e969e5c4141c9295b95d0cb8bf18ccc65b9f6b36ade0ddd93ceb7c0473d2f1abfcb788d4b92262b8a220ce9d99ac358ded7f108c2c0cfbc54fe75f53cad2f7c8b2e1d5be8e24bb0c554548421d821ee1e8c6187c9ba06ae2c7d0ac58062282a8082713dbfbc536ee7a032f018bc8d85b0d01c4ab2a94ff97eee42322ed7ddf060ddee5803bd30268c29202817f8b698e87e03f5ed608a194d7ba1e89d027b31a4a2b7e23df5553c9194bf5dfa9ae4c3428d31b4851adf635a5f772e7747da34ac8698eb78835258006e4dcd1e2b6aebafa19924864263bad9e52f70cbfcbe8fd31f993515852a431ca984f0460f9f987075a244b8df3a8c6fb8cc5e46c31874ab657a31f32be45511bc49dfec92511335eb15aa3bda5f637349b1cbb8c1a927da6b4eb2af8d603fd988744f677bb7355dc737fe1f161c2181d45fd6b2792501aa6ef68de0621511a7b0bea9132e7b99dda23c074e8f2ae80dc5438123a63152f6305c6dbb156dd572abae44d3530c35b4f1458326d2824e636ea5b8476d9287af2457e528803ae3c546c02a24f3dfe9aa872bbfab2437ee2352eed14a2d94efd9b064c2dc59d076e882177af81e3e7571b8f73c3caae2c5880474f705327c034b6044d899635f16c15b45dbce6f3be9c72b5a9e82ae6b2c2cbd994e88987447d2a1b4f1ba3dad60c0ad9c6544296127aa9fd858cf2015dd5d6cb297744bce70b462dbabb8fbbf124e7723836a84fc613fdc0bc6b07ce574379197598e902912844813939ca8bdcc88f861b97ebe58d8aa250d89ab513c68625358a783b4df50eb5728fdb4a4dfb00a4059c3012a3a67fb942eaa4adea1341b3cfda696d84ccf833826750c27b5d9cd84683e5c3a562c89e8e2e4043d469ea530abdc68641e2171dafb8718ecfe9451430561bbf7c349acde5f73eb3d296b5d1bc0f0a004c4ff8d84e335a9ee548a03e1bcc2903495744637aa2de638ed226b202d126d4b80c0d56cc14e2d23a71f57baa5a866a19b490caa860dd01db946356c0e162727ec75aa5321ea332898de7356bdbf110cf32dbc9cbd9c6bcb844e60f0e7b064bbf8220e443d7385c0967d7f32d6e0f7b68d75eeac8a8c6dc3d8c69caea30222a11d4413c294b2ece3c5c14f8e17e685e0753a393218ff4dad9e0d3be4bcfb6d21274bd2be7bcf4ea0f5147bcbd7117f137d106d1ac6ca8c6c772bf815bed18aef0b16b7a000ac610b1d289626b1a8127879e5312462f657439e220b13cd94b0ac3977b4143982aaa10f2e3caea6457fc8377fd766bcd2c96453f6d0c03450a78d10fc8108ec1a21bef17ce36ae5ca62a5e3e5093d2db9ff8dbf8d9034e450d7b98b17826545a3065ffef40d932d94661681676be4f07 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d7e3338b3ca1d71e8b7485bf85ab9e8f6c36e158b67d2c3531bda544b8afaa0a86058ed9884f9d0d2beeaaba8f075ffe992c475dc4cf919d61efe673a3547575e8b00ba47d5a158c22e6b2c38db3162e65a6bdea43e8d1e96791b6d99c93cdb0602c94c1be3f278fe46b7d44e447fc5fa8843fa797479fb0f39faf9fc3b57a3d92c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe16e509ced46b4ad48a73599ad2d466f17d7e9b4604545ff955d7659ba428cc6994ee3375b07d09ad3be197fc1579fc73956f6d0ddebf5435d7a2fbf9199533b2fcc500df2a97c571dc3e1485b36e2a3344eb880c688e9afae8b0a9e9fbc57cbc11cb228f8c24f38a445d5e2245c3a5cbc65d30f69ee849bc268899a8eb9f334704499b60a99e139d9470a2ae47f3847085fc4eaec5b14e5e817fcca22e7bc1c585cd2189131a6da9f9f84ac7940b2949707ec7a680ffeb38d775e8e63394a3a9557bd4805dd27fe77ffe83030a3455efee96a763f8bfe56df73ce3cdd7ac70447573a79dd04a59e8b40e39c6fea736e15feb1b67b5cf556c3aebf9facfca4e6d8b759d37737863da2a7ac4a645a903dfad62ce7068385c224e5f8ee4146d896020b89cc73aad70e35d5a3b94889e84e086f1066a9f66d41b70f9d1f538fb6be8a7a84ee05efc158b69928aea7708bcc411988c0d3e5d1debc3b3eb0cd473fcd3abacb1bb3eb33f24379b5360d81efcb8c45584d3b845e260d420453718ad8319423d983a355b1388bf246b9fe84d0443c5262a8e2fd2ef5c49ddc408f4c0ff95bc25afe8c3d6d5f3f78fffc585843bbfddd6d2ec3482295717b6ee1aa7b647514d0841d6a0159ecfa9ee97eeb77dacdec2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57dbdecc4ed5d957e5c8beba790d785edba95a7352583354b93cbef98c78bfa946a753e813ec36ac45488b27d85acd98b7c6813cbbfffc5e9814c3a9de4cf54ed7a144fb6d16be83cb48a9021972233382fc8c38861eadd6a868389def4bfaddf11d3b3a25f648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f77e7ebae8cb489b447df4f5def39c79a6e352e5e87bcb8461b5b509c895fdfff95ce7c3bcc5904d968c469b200d3322c4f3761e3749556476e9f5a915971a62a5a330acbd106ad77da78988e5cfb3ecd454edd459e5d772e64b627db2916b5427c694ff33410be6b746dde92833ecc35bb25db6e6537d1d85ab215b366a173604c2797c2a9c421ed69e7e4b3d22fddbd2ce96e1d5211134479df3cc54f8f8f66e82ff3a51c7b84f02ad8ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f8cd6883c99c4ce934fabd4437df50ef36fc42d4862c9dc11f59f4087469211af5cf4cb29d139d85d9c9050d4cb246348d6d736e7d7b2babe11d9eacd3937d9e8934032746ab6df5bcec8bf637936448a0dd67a27ebfa74c6dbba82bcc87d73d4b9d33c427a85883613eda43829c7ca3c7a8f243646346e0d8199a5ed8d38d0b6686abbd4779fadaa4f82d4d799ed4bf8ecb65ee7c8b2047c41fbf55319ce39b89ce909831ff4df4bbdedb421dca35febd657b941f466659fcc971c1174aa4459551848e7a116b751e5e4022c8f2a4b3152a1b26a3096539c9b0bd6a435ea1e33413ac4d5f401f5de8570cc11cd4bb9fac473328d55501702743e2c8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b9571200b05300cb30bcec4a58b06f70830c2b32d28992b70427781854456129cbab53a7c72ff557193d3a221d06177d002095bc04e993b8606245416c3b998b01716af3b43a535f7a6bea71270b34ec808ca00e9453ae660b732963ba634f14378b1691a90e3708125cde31bae3d10451a5643f526cb790a8d6e091a725681fb539e9b05bda7b04c48a31b39da6e39e6be624663b6284de9f958c50149ce4090e6a486b68511ae90a0f093297bf090db3c81d34400a40cbe11d74271e23bbb7a49ea875ea7f7cc25516a899198362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b4314c4c44f44c96f48b29a8e7b85339037acf131f2692b7e7a49282237c8f37267c835c24883d1a189d4dccb7c6bb1fe622fc31301a6d3612a448084e0a210449b7e15a4fd84a9a538b2d5844dc170c911fc1282bc513e8c18c469a01a548d1ce4853128a03a8b1d369b353c3003b0a29d210ab6af23acd010ae3671493c774efad8b3746180746401d0e5862a3265e7969f247c954955b4afc13fc420143c10263eb1c6dabbbf5a8857a7f3bee7658c8399503c21a9a38ba554132344e214cd2036c2b30d0770cc5dd87ed9b246e7f955ea926965748cb9e58351a938f7e4ac249ca5c970cfde48c0ade051ba873d36a581e0fc50d9583109a79549fc5b32ba432444046ac0a66f3c64ae1498f43b1b36d8082442b5aaa7bbcff2c4cda8c0c4d2c62cf9135a75709ceb5b82ba4ef5716c4986a36bd7b4ad5c3a505869fd34aec2d7caba492f4bc30d232382b2651d5923242bb50df87092ace5566bc5a18fb2925cab467b641df7b5b91142318d120456245f2f0887ff13516d23216637393c469ce1f776cf2426c6577844cb3d4e0a92aba85ffb59979a7c33eaf51ea2bac9862160bf8a85553a3d4edc05da102106f632c91b8d1df2a9b2734185283941ebcdfd788107b307738786d6c0a0e7d4957dfb17488c5d6cc11b83e3504ef2923034a06270563e18a18bb29f48c36a64c132aa626dcfc5a615e4416df76746673e500186a117a27c5007a4b04867213c33739e27058adb23c0de35ce6158c99e59b88b147e2ac05f09f7c0a414c3240abaf65c24cfdb6857eca66bfc58e52472861bab1e03ce70d2115480b443a9bf799379af9ac978d0072f75bc7923816a189da5974ed948b8a709a8191cc9be60ac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac47260785c1b86a98a5dd733d3dc2b947d148f698c5a117821847604151068412268169c86d50be92d77683386025704575177aac0b9d3d3196a610985e860e2f799f480b1331ba346db0c379cb1833223836d88fd4e11dbf2985825c78330658b9a189233bc76b172127bc7a98e6c644d28da7b0857f67157ae2c27659297c32a7eb653697a295097a32ac235a11887388265ecb3b46a75c865c239395300d0f8152cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e9779146fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +ciphertext = 175c3b39d3296365a6f8e1e6648985b0c1b353b852a83a7950bc3bcf8ccde62f52514f63823ea758d4e58bbda8b6e95a0483faf6e20612d042765dba9b60a3d370808c7554c79b1ef6454419e80924c202304ec41a6b4d1d12dbe20934727b94e3d60e0f76c37ea60f4c385c3158e882cec48b1433fc62135ea6f05594fd98f13fc6929be35492b354b58e26c8035fb07fe179929649c91a532831df262188aa0280e46f5ea5cccc7eed59586ce55d5aa088692b25cc3ab58c98ca228306b09c26fedd0a823b36d845d90f6e5496e3b6d70c07300df9fa5c90ac1798c4ca5ca25c16d8bc2738c475aa76b8e2dda6cd00279935ca1bc8868d6bacadc33c77656af0e53b10be68cc1679c54404c686837c4aa3f86c9b18c4d98e335f52a80ca28f61520929c8f6c044eda9b7802575051d89287d1af7b47519661d529065eec290dc145a7e496d6408a5a6f067a9e1db3f7d99fb0fc34ec167e747fccba45052586f12d7730a489da235d84d612777b0986c501c1e028232c9090fe6c8fc51a56088c1881c4e09ea9baffe50a6c2491f61c5dc0711d96c7396b8922551a70ade21f332f5236f13d9df8388cb6f0e461106d32ab61817305aa5bed1b9ebfb44f85413634bd424a95d913c9a2ca3b5c44ccb65e65be918dc2917cf9e5aedfae4d4b49dff4a613274f504b7f30b0e1f2c076d2ef31c8395219f9712ecab9df8c0d4b9b843a514d520166323dda4e9a35c212a8fbfe6d16e3b6892282bce66ff727a8472326705726e147761a2128752e2541c5f5331b8962265039b78bda79e326c3d7124294d29c2a60c9a01dd244d7edca5936560fd6323b9aaaec48fecb8e275930a882859a75cf7aa467bab38f54b34f3b35e8d29574dd2e301cb9b4ebe7043a350c14f46c308c5001bf680232def77f2b7c8f5fdcc8cc11d65b505ca393b97c0a6d2d2484401dabdded20fe2bcde15773a2b109952af594a4d943608b066cb78580d77403707d189c8a11c0ec5fccbf8a82967c151c955eed18b395350fc85506f42639a1f1e6382b269ff2611833286310ff91d97996e9c3896fb1c7994e877e98a89f9d0d1e69cc6ab6da66eef7b75cc147d1633450ac4d8baea19dc6bb88a4b93d2d7fe842a36d900d5b52e77165967a003ec5470282891e770369cf21d21d71a982aefd6e2d943c68b51ee312d537ba02a952baa7f6c0fbb6f93d554a4f13fbb8c48c04e2d9416cb9ebdae2ae2bad31d6ca5ed0f7cd01bd4db174bc79333c4d9292e07dbcd48e72cb7e63fb36dc54f0553ca0e43b48ef63ce225781f88a556c37cd2a1fd24130f41f1d778d8d9d0a0eed1a5cb75b924bff5dae57119cb38ceca4b9cbea6b6b7c5ac854a1f115945772b981634f402dd69e536d2bcf51466a20ae144fb853c475c04ae4c40c5828c230532982dc51e53810fc73809c1113ef54015290aeb9bcd736aa8ab1f747d5b90d188fdb45c8bbf14c06c41515f354746c7b08ccd2adfeec6bc02266a78380b972b7ff44e1d29cc4bb1933421cb5450 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d338b8577cefd9168551a681f9c590095b6b8d8474f68ef26a4b68ef8ea83738bb964356edb663d925960388c928a6d29b3deec8fd46cde497e3384f613a444634aa3d4e656d6d31d523372034e6047efbed1d32afa7b3d51f42ce374c8c1e8cf72e9fb5e645002530781cb46614d3f98f87d115baaa07ce95496a733f86238fa653367fbbdaee347e55a3c8905e368c1974418e735f93b6965ffce1ce7b43d827e0d727a4c4b434003b9111ede3568b7bbfb341212543031c862fac505944b8639455488fd47b2a864a6675ed984583269362759cbb464e7e248a48c3554c8d54ed9342aedc8e221439f91f697b79ebd5c89b80ceeec716bff96c97dd73c45c0d980bc6b1f7aee7c33f93875e8058e97b276f6d981960267f4baf0c572a1d939aed35ace9a630cb6d7ca9cbc16ab560da5c01e37601ccddca7a3af99eb80418c0066e45c7ac8c1776d5411a39bfe843cafb4fa61463b20a504e984309ffb82cb7d81a97951d0961b2664e2d7b41e0adf572edfc20ef4ec0ea998619f48c05edf208ee96a983dcdf9bb37b9a7d559c720cdcaae894583a842fcac92eaedc7d78fddf7da4a8bf6e3259b291ae82392cbe36b68d2f4fe708e9c00d9cd6dcb5d43c1a461e76438b88d1e8faca17045b273be6999471f8fb42f53a432a5ef4c4bfb7f8ae3eee9be95b0e871909a70f4ea0cedb37f3f733ee259f41cecd12c79db09d788d78ceaaab9e1e2db7ff98d0a17ac28953a4e91bf57d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a5a9ffbc648fb9cdc6073fda6cf65c9e0ff309d1a433ad5fe6cbab472e788f76558d57986bac5c79cafef06f5d9db18c70ee88af044b528fff1e5b5e05a19610f059fc07dd9b995e90ad8e6416d7cc4fb69d499fb5d9ac12bbcf6765aad5c874fe318dbeff77961cb9e747a8e4b4acaf3f3b81e5ea4a755ae8fff994e8a722dcb5b8014c1ccdc6a79046664c3b75d0fb91e0b4c5c35db8eda5d67e9a0984a6052053d22266b2413b98d94ee8aa686f5edaeb8d5b2ed2c8bbdebd375ddad8cd47a0e6945f0ac352307ac0ecff4ecaf9bc09397f06be3098f8cd42b85c556bf0a938959fa7cde083d3e0e63c22bd16143e45bedc47ef73604999e76f9ad1953ff82e762bb8e74f8aaf3d09333f7e677f33bc15bf996ae6999ada8747cbdc4555efc2b75ed2b9d382937427ea555b3856d035dab1e3663b8d78f3d96cf9ec9db5b6de12a7e5df5db38096d76c4b351305a97199d3ac01f60a0bebc8a69e62f2e52f9edc6234eca5deb5260e7eae26fb7eb8f7a342584577bd0dc674a5cee49c7744d7ff43a5b04a3ebd38c110630ff656f30fd42ec6d3404de4f18fbe7cf675c996cf790e936cf8b60e758484ccd4314f5d106bf83478f9077aaaca72acb46d331ea1f7b17dcae5e639d2b33b9f3cca468f731bf0b332bb4ed196ab77b3c43681fd7883d369cf5914464dea08b5025a4c881ce53104da852e35f975e9c91eaa680e9dd25b4f56ffbe878b48e39143ce43378eb3335d4ed3f2a358783edb54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf2aee472c26b4d708df4bc3e92eed6ec05a6aeb9b77f8c16dce72611902a8ccb81e8cd4c5a2fb1d8fc30ce226bb45779f41073ff3ec0362ba152102cf45d3a95874a551c14c8a621436e248ffbbc4ca3b4033d50efa392dbad9c339745803f845736c30bf309546229ef52788ab223758c03491f62913fb4ca4307dc6b4c7fd9503a701ad21671387cb2cbc728ecff4641e312779c7034ce720554a948a021751d4628890ca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934e4144922ccfa2035892c4cc2a8457300946aba4ffe77868d34c7a90507be43748a366c49d0a927e66610a08cd0152a2c1bada92a05694b6e3d2610acd4579d5634fd2675f2101290e2ba1855252b57a438b50fcb854ea7b6a89b109ea9857c23aa38333428b94ca5a524977d72077b56978328c18980382ebc967dd37e6136360a958d5f00c3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347d9b018d437b3b065c120d26e9033078b5838dfc7ce68f244b32c5b4ac04def068f58fa733e99a418176575ec2ba0f78d4c402d67176db5717023b57f8d26c636a11f49b926d20b277d2613941c3e786b1a9a3c1135993bce22a1de16434a5902c0f101993b65777399828ba52330a2f356203521a3c59b6007c3aa41d198a8232d27c05f8e0280c9076d54d5aebdfbc95c7c06bce24507892641f90d2b774a2d98764c42bcf009799432b706da59bd84cde4892427c0586929c99850c7d769ad9a221c85a4062a62b2a1847454554224c4cc47898574fa66d147c4aedc59ff612f49285db54170508c89e6787a8ce6515cec673d4545970ca8ec486802933e319800fbe46d5cc14c8363656dac0600d895fe383fcbc3614fe334cac0a94c185b73db30cb5a56a8d04cb271b13859862f164f980625d78ac35ed120605cbd69e6410eb05168819440816eebf8cc9ad153cda5bc2efbb00a7563a55856711231cd12873a9a56996c174ae43b5c172a1445bb40cb3deef9051035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54b6021d180881d59d2458564acba148b0ac36cb501cc8242919064ee24343f26a87a0696000533a20943445c72b9260b4c8a46a1c921c582600d978c5370b400b2412f73541a13ba0349e66fa4025735cab6402aac51e08a019b48115c49c665f415244fa91c208c6b1f2bb02bc18c47a5aee366edbe3bae1e41a8b405ddeaa22a2fb254a6b70dc5a16c0217e4dfb933a127039b788e6c035df8993ff86923500ba466a81d34a0ada271da4262f33123a1b81a13621211845a167449d93370bd95a89725a56a8452b510a7fd2642af41a4a7856abd9688dd7c85433a868103679a8eb2bdfaa0cb52cc141267e91e2c1e57162c6b4897c9004a3d375c1c8bb87c5ae2cc80c2a107e0f904e5bf8065ac96c9152aeb07322fa181a83a9cba0224c9faa0f06cb67e2787eba832d3f53ac60b7b014d28945361759689c3ec65f8b885eda081443a2afd2a735b1c57c201aa4d273b1302267e5a63abefbcae8e1b2d3883439e2be2436382eb9bd62146de0e446b6e2baf8300575091db145a646c733bf352989938fdd8003218a607739c60da6758bf448bf18a22630b08ac40635382e3bf86d16625c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ceb2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +ciphertext = a79775edf0315a85e2a48145e0ce0e7b2bb5d25d995a78c8b4905aabe811328d595575e87409438b07a0b772e9544246a296961385f20a180addf607531c8aa982b4a5ca6bfae414956a40e52de3c1427a087c74017b0b711696459fc50369e06023bc915cc0f37ce9b1a250bc5e3ffc1404df54edfb9935b7ae1a5d73811515e0c1fa539eb9b11b08d0329c1310d3e49c816249d1142240f605e39abba101adb143a143d7e4ca7abce799e13135033c98555fbfc900a319824691886026b395841387bdfaf4f2cb712e455e48880edf86c40563bece6cda265ed7eed3ed91e649cc086bdc81ccc5d9563567cbd45f032bf78235c2576a12d7fff82170b4e0d0d6dee1cdd075e55fde2e1b00a03edb1615c8f225674525d7a1c8f17e8f8dd6863dd41e990826b482a307ddc522e29d271ab97fa57f2e2020f50701c7151f445fc3a8ef1afb9443aea1919edba5a68d745e3863accd6e3ba32f016d405018890969148785d00ac8830c17a7610376a0450f037ee4f0510096cada7cdb7a38d9a765da618e8b5ba2fb0083cb761e96a753fa119425bd50e4b996c5cd4f58377de02ec10ffd8751e6b513c3b33e7b6e45027d25a910a380cc16cd6e85f079cfe1f985ec15be162efd333d594c2fc333f3389f3c6cba92ea1285d68112fa07ab65d18878c423ae22898d0c63057da644004de424d312d099d1c47ba88fc9e35d6f51691a95e0689ab180955afb49caf3891a329858f625bbc4c54871aa82692bd0b32d0ffa87662bbaa75920f8bb546bd0fa4c67c63aa72501f7e213f72a9d2b767eb5fc2c7b5f83f492bb9eeab10bfa746248d1ce4ea4d497ea4de28878f764a349e2f6c268b7b61fec881f3bdb7910a7fa2dffcf4dce41fa8ca4e3cf4f720f72bb29799c93e7affaac971734837e9e4358508b5570c4946938245c30b566292e7fced74793a089046cf396aa77f277ee2292d1ac516e09213b1a334dae4e4ed4c6bbecb9e6f12840a3a7e111ac10714dc73f2c74a137a7b662b515175b9ee56e76eb21d26b75bd5b4dfc7cee9fb6ff276c27c6d531b06e5fc26b740090cd6830c126a1f32e7ae449507eaff06332b792d82e68a285f5b7af77f030dd4535b8eeb713948ade1ea09559555fefb1a332ee3548d4a29f2a4cba841c7194c7d309bc6aaa4d8d299d99965300347aa16b35c90871c4c7577bd419b2076628adea586d73988828327220dcdb509807b7dc921d5f7771bd8a0de19667c965e3ab22d3198880e837716e506068a70de4b4d300a1f1a386ce65d8127bdf38b2bdbfead80d6b7b89600b880833d84a38b9dd9cce2646a5cf6849595f0ac740b5e65e6d7e1fffdbfad7d36ced685b4fd17911ff697a8ef8bbb37272a95139920727deb0bc7d5feb6fabc89b4d342421b29d71d0796c5312484711af245a0c53629148ebe4c1a61bfdda623775b75e263cee799334be799dc8d26791a7b8ff002ca4f92ea37660ce55199ea6b25134eb9c692b255d3f59c96133c6857ff5aceea9c32a3d90c3e1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 9bfc3a71fa83a417ddb5064ada94e0a87d845f8e8c49c9ee0aaf51e29f5edc2f6ee8bbe53f94b2417560d88959113a6bbc854b0065748e6a7db90977aebdf16f3c41cf07df530fb306dcf2ff9ae38c46dd75b9cb1bba849c5bcc8c9b55e80647e513c9e4ee5f67ae44f013822eaf4266765e402ef5f435bda4c46ef57430eae331e1d54c91a6deeb363ca25387d0d441abb930e4a7c32929ec5ff7a87996a4b1aa741636e1e67b303e284c7098a65069356b55304c1eb8bba66c5829647493c09b06f2670e7977a988343d92efe98d9c13a2bce53f8fafc81b0d99b7d5c2b127d4971366a5565cc156e0df796c6057d0691ff6cb165e9acaa6ac5d7a923b4d472a4b6ca4f4e7f5a622f87f4f9ae083b4755067a93c285cc0748d241c7051a7e128cc5af4db5c1f8ce44f98b6bfa7d3f5338628daf2df4b84d113e2edda9df71442465af4491a626889f8c22455ddcf3eca964e924854362d790e8e3924cb58a1ce56aafbcf649d6ec5fa891936c7e16b5fafd98026d64ea31efbd75b6c5f376eeb74ae9b29cff714ec650b91a2b852c12e562ba33b66ebacf787be419edf22aa43f4174571c77710f775d27e9968a552388db61336ff94bc36b71eb63f56ddc7fdfcc588af9afe64312f76b0386e697469c569f8c0f6f439cf5af90577de0883cf4581936f905ee3dd9a1a7918c8ff9b5af8ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d520f45f8834e890662e06774f389c0c623be331faae5accedc2dec43463b68889eaaafc21badacb63f9ff80a336f99e4fbd6d2e2b9ae452647777651ccc4bef70ac06423b66ec5982c96eada7f3dfbc834ca6a6433174c1d7ceab9569265a96ab5d48495e7f122763b3b7f75b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dadbe40666610ec7a160fe8bc84eaa6a4f5508d5cf682bafb6d3c9e0fdfd80349597f56fbebb7ec813efe71b6d6c065c4e6b5e5d17abf3c4e2dee8eefcc8b6b1935fb37b467a5cc6203e8aee2d67890d726509baa73bba254d30510d50d5bf3e4ae7e349dbd877566ad20dba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ee8ddf4095d59ab482fab7fca53fef5e76affc77f74f4cda62fa0085a4918dd4168bddb09863850d6caa17fec2d473de0763b7e3e68b6147bdc0d9eb36d901fb8f013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c4311dad15fafeb2ed52680f9e5ae8e39728a907b98761b65dd6dab895363159b48875fb6aa80882257ad4461bf97738d688745c5914c089b37bfc949a8f9864affcfe4ece3f61afd70eb561d09b530ecafccd66b87b0986adfae9334480676fee28bcfed9c57ede59f799c4d1cdba8377d593da0ceb0d233005ef587734fc3017d779d8bc5bb488dd3988004b5a8554861b66debaa5bfff7c89dfde93ea077f422cf16996c1446be65caef902cfe7315636a168c0216ac026fbbd4239858837b02dab5a3adebe6b17f469af64661c5e3404f480c66526377c9a0d92434bcb551a744227445d6ed8fcfc3cb55f6d0c8eedbd4539cfad5a08a78fbb7f3f9bd11c902a159f41cb5395be189b1b7e98cc23658dccc7bf9a843a77b2a6bfa27bc941b04f391950d998c607a59b49330811200b38b243060b55e381c078100da84975091f3a0acb06f22ae3fb1b7d756d36f54200a367c109b13cf40f3671231d5b0ce9e5908776768767209f4726c54277d0f8b0e05bb4cd50bb5547a01051c89abc4a352745316c8d85a3187d68382ef05dc96294446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c308f22b8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf2325cb060638c723364b27c8e3123fe26cf9862f247cc31c844ae77754206b03b497bb3283cc7e38664b23771f709e1d308cfaf5086f25acbd04cbd9f1612acc2712d129c9c195bc024cb057b0766aae7b533e60f04d947947f920470bc37e5eb4ac4fa1c48066877b4456d4ea2a5ee089de38a7fc7573fae5480bea823727132651a85d873378cb97d6f7be1250a94621abf5eabf0114952665cd2a5005af338b36d19f6e4c8f77e2cfb6f24d3cb7a909315a026b5aad50a9cd4baf3308059a91323b1c226ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91546a2354b59328d411a724cbd8b3689efa335d879996fb0d1d2244edb361be4b2489e84086f4a995f20ffa9404082c4e66061d3ef668fc155bce04916c92b8fa46b77a4a9fa82c8c0ca5a5a5245883d25fded230e74b22394169464bc33fd51fb7f2aa9214b1ed546dcfd00ad554aec80882ec170c6ec44794204170d738ef9341d6034920a7aec3b68fac00527b2812d88969c6207f9aa122464a4d76320ead6271d2836e574155310a756cd4249fa7474b301ca978a0653935b7740a16c50df1eb678c1bc3eb451cf6fa35beb903cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4252b093d2ab40884c39a4abcbd19b108b81172e18a84a288aac2982d113454335423148168bb6b9d97494179bba1ec8760be59d06251b94b4baaf82a6481c4a8f33b0fc3164635452e6497f992308688352cbf44537c618000536f9c41a64361ee162236f9227219b8b84a3984c649ea82211207c974f6c7575027aeef57e496a58ce2719096a58e2e31e82844f4d674a4cd9cfcada79afb0c63e634d2514ba4d8604ccc42b2eeb64691aaf23727c93c4abe1423c27b3b7abf0b649334760056e591c32fe812a753723f7c93ef5524c8e0267db177e6e55620715688cd0ac70b2a90e133caec86945bc74d7ea1cb88479a37b45eae4993bb7048e5316bf66b9715591148c9a20a35412c2404bb62c512b3800b9ae104453d95acffe000d3ae85b96d8092532796a03039ba2154f84afa4a402acb673b8799441bc505e836c3b558e1fe2057fa79153e1630d72afd96aa4fe9c0ed4822ab33a559719b81d274ef0a2773e405761a036521278df5ab3617cbd89d7543cfc7c6ad373b2d0b781dc78dd3b2afa34b6565979231681fffb8c62843dcd11686ea59406e23cdf96aed95554e47027c5b6976f5515bc40b0e3a31c556219f89b73c0871e1ff552ca04c33daa4a363794cc7c0e05249b53d20460eaa8ad217787c8c9423a7eb71058b5a8081b82454dc91f77f8608d60caff30a7c42424542a1746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9edaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +ciphertext = eb2ebc83c36b4b470e983a8f9befb67443567e2c532348990f62418cf62208d84c1e97c114fb76ac3d30491056f2f820178164276804a16267eab23b270f990de9307b5947680ac4d4c070a2c764ad520cdf3f4f0bedee9c2eece09f07df98209e214abf99c07e7f50e78e38cecc268f84ceabfdaa8010b1c8b0450f440923f23b22465770d19fec10e0917874dc78243c3483a38d49fe28526554b217b2a0eec4bb4b45fa8f92954dedca998ff1cb649237e0e056e72216660a10253ac5064dd0faf13d0675ddaa9a3142c399bfcd2efcc353c316e4e8d3bc9b6d27b9ff8bc7cc4f87dc4d4ef9f156b0e80ff45192dee9413e74b83dd98a6b5d3a0348202bf041efe408dceda6e1323c887e414f126ba35cf6d78da697a47ed66f8053d9cd0a096ddd6649e74138d69caad22d856297f4bcb2e4f7fd6930210e63325693adcf4c60a346b34b17fd2193cc3e6d484949106820fe308c874f93f9538365b9cadbe25230dd5b3d7f153bf54fcdfb1f2f668e039f3186d9e4f9f336614e88954ceccc791d584ca318d942917678f511ff1dec3f1534569bf0168dcdd1505fa98dcff66951fc28dda492f0afde670bc4fd0adf3b5303f3ded36d323a89d58c5b37b9df02a21174abc8f2d517bc15f2afadc22aad49a678392d3dc5c96c3969e4b55ffa30daef78b07a01563ed24b214d662648afcaec2ec91b5698b638889b701ae84fe06daf92974b545a007b73ed5a12602bd0fd6cbc5c62949ffbedc1337bd4d1c10ef41040e31168135c45c765245c00386ffb54a6d62eec1266a18daee9d4519214663d307d43e729954807c859c4a6834b1c9b7a47966c6bff8e8b4e062d1f9be53329e0961abf7872e42fa510cfe350c15030a0e12c66e8de05af485b9688112b5c4612973b81f50cee871d816839a2beeba30bba36981e483fe600e2993a60b3493e016596545243c7887f9ee9dc1ab6c875621c1d4b8c600e062d5d37a30421bfdb811b62fbc73c0910d305b71919d1c80169ad86c0205cbeb4bb0df6bf7bedf96c741870d66a78a62d8ee9cd7f7e7fa8ebe0adaa1389a4932245ba6f85b908366d1589db6c2715265e98d0f5e89ec8a0e35eaea4c9f50aaf213158e729e3766c50497e6c2b9f44668b4760e593fb509789ade992d9e7d047a50045093f2d935452648c7afaa320b52465d48b9e15acc640b9e89a2b0b893a6fbc8c257f386e4cc9a52bc5d2ae7590cc2161bcfddecd17e8daef627fa9dbfa92b76942e6fdc0a2f09692fd82391d69546986b364c5a22b2e91819d957e1ca654faa71b11a16b79c37130610c01f4f9c2da974da0940ab94febbd955578b28ce30ecd668c8ea876ec9b313ad41e5a29a04039e50fb24233716a726bb202e7662c37b90adbb942a6cf708eb77abafc6850af6d037024e6c781994c421b3fa916ae07cabe60dbd701f9dc7c29ca13dc810c89970559853066e00152d171823b237a0e189c1fe72d14186f420c1bdf6055270b3782d78a2d924be110794fd3eff58d8493bfd6 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 5e484946337e404e35d738b0862b69f8bf47a5cbd812d562024ddc53bb87b798b2b65eccea75a8801dfd7de7878fdd8e977afcb62b4aa559bc378e6e979d97406d8b2636e2f89b5bc784365e43e93ff9d13c05818e0a7151297ea53c95089388bf2d3072dd335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92924e37c33773660aa15557c32b8ad86a6aecfe1f5deb7de83ecba94ebfff0f4ae8de2e31bc89fc4013b7bf84a7840c976c63e17653c4f947839d8cb35538bb97899418688a9e16ffa0ce7d7755dd8536eaac0ebd9ee77e917966bd26bd3d3990aabc8561cbaddc6af2f8d8dd99453fa745db2b1ffe4ca48dea6c9c083d95447eeabfc7cda76aa03f5eacfefdcc74afeef3edff45a9daef5dca77b93f14e4bef44576134391f7b67659eecc787671385ff67a556ea8f562bd858b25ed4315cdf5ccb5be075d642a23460c3c65e0d6cb6833fc007e9204b7b7cbbd741817e00b8ef686b982f74fd95d7730dd9385a8af6c2384e475fefcd80cf69ef346b6ff87ec0eb0471d4ef94e5372b47da145ab0c6ce7756f6b5dea7d72db4c62fab14c03ca5138442079da7a9e94e8bad5bc9e4db21956bedc948299baee7f89c884ab9833c866a4f2ad05ee4e2ad466056eeca478f11ab55defce3453daddc889044a5601357ea6a5b097b54253bd46fa83c0212cf36953954c36840e49dd2707848c0b879acaf354faf00fca56cbb86c0d2f69a81c790b966893f782aae9a4bd2bd2fa85995a757ff2083fd26347c987e1e07560af77cb59c7cd64f7cdbc98dad26a7bd7fcb9b31d710e68ec49453a330dac08554a651d68e6879ba6665aeaff81fc14c8fbfcb0cbddd81c2ad6dc0e7d80048b334f48f699825a489d0726893f1d9128adae802cca29ac56f71e8d209a54cb94fc9a8c539e43b9681cb8690e8c95d872c63fa10a77bf52a796d43e87fb8aa3fd88dbd2c4b30fb7394dc64b10ed5b821f8764ae325ceddebb5ee248bec22b1e46fecaeb255c51f74999dd29a9463e51bd9869e3d548347b93c1b798ff9fa053b88c80d7afa5c561d31435d71f51253b9a4c3bdf4293dc81e990006dcebddb700234dee9ef76d4f3ec2d249b854e4f3997b9c4f5c0698cb2a24c48e46d5f6e7d4e5db734ebeefd62634dedc68ed7bef48273bad5ecac075e978b098ffdce48667671d4b59ea6095b0b363c31299e5cadf8309e4bebc66f639e338bb7600c93e0b83963336952ec33854ed7c979c7ef30188181ceebb673e4ca3f42ecb890123c9f2aaa786acbc7dbf560d0ce625d06c3828998ee5eb79d28c583bb3871a7d6d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d81e3ee07eec521761be77efe37baada8afb4b1e4dd458a19966a2a439e4d61b47aef5abcc08f50c88af752b51bddda3789cfaa38aad8edddd835476c8386dd3a8628b36ef1d7bfb9f87e842c97da7bbc3d03696f615f4be6476440d44f6a8aa49dff901f750dc55c1ea88e3ec45e8b26b3fd0657ea6fcb6be94c026244a050e593664673faa680f866e184e43b0dcd86fdacc208ef6c3e941f19d332d8487d5e66061d5311c9b5c8edc39bdfc349494d0a9a3aff3a85a8683354b3c3f035586b50b88c4140f346a05ada7ce4beaaa5f096614cc767af89ffccb95124b00e8379efaf76ca381ae4886abed9240bda4710dac62a71017059b07921c770da1ca2d209338536c3a9b5238313bce565fb861bf8ad3a78f030b3f646b34347f1d215e8ec1789d602d92a971fa3c2e892a09cfa68968f96f206a7535766ed7533497fb051c8036b0aa81c2c802fb7333cc6744ec830e4be56ef1e4874371409486c477cc4ee90092d2919f585ba21f32bc973acaef42b4969746ab2618631b6536ec298b2828abf41e24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d1712e9ffa937ec5194a3541e3fc9c685102f9a47faa077fecd688d607996e5b60c1715e617994b842b46574b87086a061488bb2445b357a38934b612c16168e662112756bfd764a4fcc5f7b1634f6f28094464d600046ee03b4540c1049bb3d18f783fba2ac5bd36ecde662d9e08e2a89cb754b090db7175277941e5973d010ae08a4b4c922aa99f47f657a49c3b81fcdb54c905a3010405ed544bdda9942bc857b6d979f796c859e0627a5212543477ed791c2adc95fdfac9d21d19750b8b5ddb95f02d721a9304099ba6b2cd0a40c1a2f9dc1649b2318acc93a5fbc52e3f4900bb44d20a7250142ae5f3b77c0720c77104b74c78eb821bd32e260051c499b5ccdd9d716521163557b5e4526acaf09a2beda04994188a5065b4a975b215171eb288024581cffa37d6289813773b29f1c0ef5587f9c98049f548d2a0c3a5c71c1693b5ec8c64ce0267fdf625485dcc4b5553c5736a0d0623cfe20596f984c014aac0380ba9b58257a993b1be3bd2cb9ac25912b36b2c085443074f093510a46cde5441ee3cc88dc2cd636a5ef77310f91cb21abb149db2541407726582b54b50306cab4b5356492c220c138c64b4ab293680e01c2aeb369bd611064fd8955b790222bd5997dd76bfbe50a2bd039c1f14f0469b623c53195a3b2ff068182d951dab05ffce9a6c8fab42886987b7999043c12870965bd463980aa6b35e13b5bf9c25b64920d7788a291a98ebc30d3785783c27e53ca9ae809004f23706e3cc0b9ac0bd571084100299c932db2933cd91566aaa367371b16069a706be664e86107b33b1cf05360248c808ea250fcacaf9096715478463932a1c632cc9a185eeb08583a9309259c567743995af013216b1086815b851655d0f14fcc43682720acdfc36f35806894177ea2144f6e28837cc887e560874ddcaaf60a3580fcc7a5f1733180b1f1202a08182345370cc5c46cd28a507ad846d1d9415af679d4b22ee560c6c1b2499d5b74aa2758da090e62713343b3a8b14c68e415a3f196c2573c5e828a16cea51443104f9cd899ad03c3b727774b48ae61db98feda4c1e029b57f89d1735381166b70450215af92120ca61a8a38e575abf2cfaa54c613031a9ba60275d23178ba553a3ed7179aac44fb3607e93c1c57c7bad6854533844bf3d6a9b95a966f891612239cf6cc41df1a859afea9c0cec6d2679cd7c71c2cf251dc9759666c871853a1012294022fabdeb2269b430397f337b3f416e528748903ccb8b24c8fa28197244c0ac3a0345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b242ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf3745163360f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +ciphertext = 333ce97c3ce5fa6677ecc0eb829056e8732a4bffb16f97895f2893ef0f27f669208abef07f251184b011f5485050e7dc471ae61c651499318a2634feb720f81edee3a9153a82d840069601e13e8a05e35fa2c18b0fa66745e104319b785c36adcdc4a2dcf03b152bf488fbba844eda7eeb4d289dcc7e926dc0ecd84f651a3f6406929b26223509789a1465817de510542cfd42424b594587c1cea93790e88688a9492146076b87cd9b3d52e772a072657148cd22c6e3f1cb724795d4811330a0469f91b3df0cc389e3e7c6280a20f4a8086f66f1d8f37446060ce019d1781b7900251049389911c0ca210cc2c6741ae7b2ae5ac5bc5905434645116cedd2ec8147ce6021bb953b98d7e7576edb3c9ce8ffd31dfe2aa2bce390e82862def5de968971fc0463666f754317e0e5670d4a573fee33ace8196dc5767be6adc9976ccc07e9a11fb7fe8627cf6b09e07c22da8c829785a3cbe044f8622dd130498ca4aaf6a66e5980c7e4055b6e66666893309345f7e506426152a6ebe811f80e000634c09c356306bc9c4d6d535edf4f72b860d0f52f24acf910ec731743d0856075fe2e0f9432db321d509c122b2bd69b18b62f2d8925cfd35c273c2ff4c0fc184e6c060707d30de3014d8cfb9d291f2d6d31700805da5d41c1c6c3681fb7603ff518b3132fb42f95c23685b6b72652404b1e6dd61ec31d27ade50384541336230c6b2e435ec32fc783972bf5f48666690687642732dc5f7090d81460924e2a7e64c05d189b88d4276bf9c6b51632f197f3f76e5a97571467b83a2d8754ba7fa8e827bb2e7517c30e5ae5c0fe9735897a86ff3359634adf981201f6ea59adc80a63264c776a08b939cc9c5565281adea113cdf3bbb201f5c6754dc2874b9a67e4a68cd2853f2ff5becc9d3a7c43c8d3a917d7829078a76d097f7117f87b7d4054a439c22dd41183d0e74d5e496ec19d66d555b45348ada3ed9d3ae1b3d351921f68bbd1d9fb4c87185614bc7b0bd3a53dc81b9fab161794a9217ca0c5e716214621c2fdfe6ccf9682135a14d52800f7844096dab5c59b0a07623657d505701733e409c8c0ad70a143cbffdfcaab8e8f122942a8197fa3cb2b9e0d4b80d30fbe7a8fff8d49df0f59725db077839398f75961bc5b9ae4f1d03f6aaa4a42b3960b7212b535bfe34360d1809317b3cf268905e41c923752301b0a9660da97cfb14726245e55721637ea2a075c202753e33c97ae9f20aa5ec6ac03202af9bd5700e93b5f94d63a683cbbb8242052549c21b4380f13be398b8d2db55dfd9fb04c21387393183a7f5547dc7af9fdb6cf7fc8b0f1665e57f67d7bb59a06933a15fd7313c38823af5fde333572b15a5f13b2740886a6bce0e942f6dd5b82f4007c224c500b1675a25a5c0732b72391087f2bd04d8c9af2ff040ba18aef056fa13f088b3b564abe07536195fcb800800fe2ff41c79aa0cab8c561cddaf1bad9bb35792f0e61bcb242a3f2e3443f89391fdd0f1951c8b2b615b684abea2be35b1af327620e00a83c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = de56f7135b3976b8ac08ddd59cbf8d09e98e3438f28c1786c2e8a1d70f9d93cb9eee2e7d0abd3e9a7561af7441e437ec7b6c8c862c5a93e955a05a87b01a63d9e8a335bf6e20cd34615ebf32dd78860a9afe939f4b9dc2a395b2b7dfd5485e64e37adc2a3dcd27ef642057db0d068e36a7ea979be7be984a418a3cc5c6b62bcddd6dca565707ef09cfe5edfb88a5b6751eaa525dea4b0be4e430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638e8d8f78535b9fc6c6bc1ce403ee6f0b784f9b2fa30e5c6c1a3fc2063bc558a7b2636c76d6cdcb77e6c5518b3b31e9f0a24bfbfff3ab930bd4b3386f671bd7655989c5185d5d393631e9acef8dedad333379a63efbcc636cffb4fa05b84a375559079c5909651e58eda97bd1a87ebefc7bc407db7d9f94b819a468d443a7aa8c9b485ef66885f6870f336c2be160a4ce5e4ec57fc9e5335c87a72a73463e6373e9f1a7ddca0a6d6154199c4f06c244a7c568bc5d8244914909fbd345db51d3c474e77a3b1d53160570c886e32434aede9fc8961b955899e0102c62ae1a75489e75cdd666ab85478ebb6134afde9154441f1383b1fe471386e4dadc823f1848fa478b204ded3f745c648cf16c84edfd3b3195483f25fea5313cb458273ffeb55969add4cd534ec1369b0c68a87375ef7423d37118c6f98c538dab9c1ec649ff33d1a03a650dcdc138e79d1509d89a639737e840a7dc720b173bb329a34cf65418495e4eff805a59ea4c96b47d55f72595dca8eb3944399f9d24e57fa46b77fd891525461113766eddf5ee2cfe745e98c3ebf53a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb54ecdfdc9fbb2da9ce2943759c4d08c57a0e74bb0e1888e957f3169437afce9aec2afa46d8eae4645de32bb18f45f7f4dcb8222adf7be74f3f5a8cab16d9bf2e64668e9fb868f32c0d8a855c9e6b54439a67aaffd9701967bc47af74d1d6ac1d45cee7c54cf49669e89a44ffd7b73b3ae2327a85bf5938e6975b94acd3ef4aed824ccde033cb175a3356c8a998e4c69d94630a8966060cea79dcb5c27fa54efafe99d5ae331bc64e7d8fae45c515af544843ca59c3c122947bc376dda7357ac0e33f55485e79eb3118de4c42ec5c56653e0edea4e92d5fe67e823098ad8d9844a25b92248d63aa2d40c60dcc0ccfb25b493e4cf69de95c87b03b773a796d1304f114847727345888fbd6d935eaeeef4d04ef92cb55fa3a38a0a56ec8b4f9cd9f87b09ccdca98f6fe5027595c2479308e8865777a357dd4fe3b5b587452658f63aaf6881555f6d69eacadb74520f3627d7395ec7b71dc3c6e8414985d69ea05c88b6455870c48b12c576d7c3f8b88795296cd51cb6f93b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c84cf8bab4f4b19370afe997d9bd8e448afeff376024f5ca54dc8ec0a7fb97fd57acf5a6b0e3f869fab3e1797ee267eb172da07618fc4ba6799c27b080bd73092a7a2f7aa110635cb959d0e487a6664b318f54956039c57cf5d9ede489faabac96dbe1f58c87708a8ed44d8a5277d1bfb8507d67415fe64e7e5ed81bdefc2103da2b0df910d6d4f02c4064e348b4f98f6be65d8775deb147b4694b12c461130f3126f8f71673e4643b2147ded2a7270ab360f6303dc05b03a314bb776c488318686069c3a4c91cc62435e829a6a8621ef5cf838311a4278d7f453ea5484d32f94c2e9628f5532ff93771dae106c8ac9cc80ad07d306b1da78463a08226657680e5acaba6819543cd96194aa5973d4f7b8682b13a07e7a5194c91ec95a2d671a2627710a4c78aa107b3707942d0c78f3eb2b3a58b7833fcb0fd7785e349a2f0027aff079b62a68e3f425122f7bc0a0b4c053a6696f90a67088f139b2a39f542d6439091e4c1a0824734d8b6e5e6483f48ca738c39a5bc2016c0746cfa9c1889297f5377d614acff2833ced20abed0aa6c7024221b73d53610575c6d91a262a5e834abb63cf74207437b31b1e989ecd7416b2c4e7bf807b5f8973006877e204a42774c93a1b394e885cf727b7fd286def2b4c8d5684460219c31b1b225aa08ac2ee1da3922e935e981b3b5e2c3d044a784bc965a580d3052ac48000ef6183b94b0a870e65207ba8029c0bd34a10443e5706792207fe2224da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1a518fea187bdd08072e47588527c3b9a5eb244ae9e910f93c92b69faa7250bcf38e68e9c3a2b2b733b18032f37673907097a4cd65a9b396db4859312d59113e07b39746c52126ea697a69929b1b625b5ae1b809ce9a811d13cca70971ae8bd6ad223206691af6897f136cb451699e0a19739d52d60cc89dfd654a320a79b2c7cd55116843239d6847b8bdc1efa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93dc2a395117426a17af4d404151814cec80e856b777eb35085f1ad14285078803c2d76ac1d25c3f8609aeeec4adbcb64136516a2077cff4c13748c5d1fe6386782688d944e0027a2f8c9af77b79352ea5523767cbde4577877af1f8017e4db244e833e99dabd0fc70824bc3c50a38275040446a5c74406873ba0b5bfc2570a406570b424727379e5c1c39ec194a29a8aa249844bea2a078c1c0f25a400d6bada80731a00b87bb5a19325b4e79b78af0bbb2c52c3db38ae552ca972c3927291145438115a952bf2a85e78f6141e1cae8516b056e614b7015017e71d54268ab9919b7eba09d196768d99651d60a334fc443c8ccd9064a420263a68531f0e86cdc48776a3d44b4726916273a0d3002de095526257bc5e6246dcc10814d1907885207a53241a184ab7e40d87148a336a33262a4bb0826b417abcdf957f68737adee682194115348ac58814661765bb321254a874c4a3c6745cf984528c2b9726ac35441015233219e169d0ea761425c06513720881b330185b48bc271b275dc024419d8761eb23801eb704f6326f162656713acc2915a1a6f877a583c8372cc391ebcf2cb22873c5bd22c58c80640cce759b2c09b368ab4ab504c613493479b7725a18811837213f9237734577af09c4be0b3fe07ab78b712b0683060be76920cc5fc56993e56c7b46a543ad675b2d13357c008911320e0d292268768b8370c66ce757af191bb703cb5732113acb8f02618eac98693224abccea04e7b3157c03b27a3cc4f0b880dc4877ac35077c1c2d5584b971261d2c4bb767c75907827ad7370f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7eb28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +ciphertext = cd3583987c6395ecdc3ef180fcfb4262be1bf772a99b337df5eb36eff544d69276d7b4608b69022bd044fce397bea7d55a0a37807b53455ac6fdea5f0435dc71e096568cb19afa1992770c96f34f9f2eb0ce27e5e3200a47bf36336a1104f9de0d11706098fd63bb97123e29bbc4661a4f6237378e23272315a95b587ca6c289dfe0391fe12a18a257e3aea5a362dc0e60875d65ba9524999a010c23d2cd094744cf538e461cf77ee3ad166e54c8f7d2a746998d08d25ee34d5c8127c1f2f13aedc7e1cf874c087e123d9595a4ca40a482fb0696871438f0d3b07058131e532aab8041e95a42cc35b3a5937c59bec36be6b7b7773f60af694ebab7104434c23cc78e122724a912d9921b4aa0b1a44755161264b6f9cec639d4a7059d0d08ad9d1e2c1cfa9f0689dce97c04f070712bc54e19e9c053710f9ab5777fbefca8dd81761f93883f861cf5ab169fd701a39b9ee3d3ae5d1f961ff5b07ba15022f51deb1897983f2bb94050e099b573c2268e788e406dcc1e666734e1c74305bffc3c9a6f6b4ee4726694d5ecf499dc6059a17482b672df791ab1495e3be6a1cf0d7cb6a0c88250c19937f5233cbe4c2680f31c6b440c253fcbaf8de742c2d8af3f3734b0e8c433a7db21b105bdcf8c5717c2dfc8db54512492b0eaf284b1a6b33726d055d5e222ded00da6f81bdc30b728226d0aa46b64da409e2f884c1972fd4d123ee016b9fcbd7abbe92fe028d8b36ed4e9321c8baf833c0dca79d4ba16172adb1225d3db8f597bfa40bf58854641743b40dc28e8de9676f815eb5244499cf8b4a15d83b9f864ac4e8b1c0fbb684c3c2056abad006ec44b0c18ab5366cccc3f4871ebc15cb94d61ab91751d8a559b8dacea2b66409095460b7b352625782ac17c976936d75995d74c6f89318176951474c07b19d31b9bcf63ca772af3f923528839abd1929ca63fc6cf5d67435c34675d4ee6caf474585c65654c3d79c4e6ea59a42e2825c229a364a29ee84eb78f63846a7ff08b21fe077eac0559b91c91452e15147ed5f7109c59b510856f11a63f355923562aa0434b2e16d6067dfcdd619dbb80a68be5790c195e0b9d3b9e9ee13273290fab34969bce02c5eef6867b0fee382a7159b4c927bf56d29fd0d849831212386a786c2a9bc086895db111c7a3797a40c9236f425454380fc5a1f96e2df779f05446d123cdffe072aeb9e64f87f3f7111470061d87ddd0b8e4dfbf1aab0604e90da29ea0659fefdf17748425b2730b8046af71f948af2ca5363eb63d2f0399a22f8d3c01414c1291a5dce3cd654206ade8758077275458c95003452c1078cc787c6a4eeef475b78bccb0419c0716938a1ba1545cc87dfab4b18c253d8b7408093e2305359359f80bea22a69709a89f4b1a70d62b529d14ebe929a64132a1b53c7b6cffe3214eadfd77d385113fe3ca4a743cda6af120b25009b5bdecde4d956beb970b8ec1e2c5b7647dd5bd099f3f843c0aafb2d00e26b1bb368a82afbad3819bb34ab810ab55222ede8f28486a7d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 84e7d70ef8d107976bfd2bddb6cc33f3c981798e7d856db63edde2311638aa43b253b7d5bc994931bab38b6fc5d1dba793b8437be6d0a97f5d36aa898e353d6b955b80f8578f855bcfee94ce2c6e4d6e79adf8e76e345790bf4b6e6dc395b674a7a8a4c72550f84ad9d24582fa5ef56914f8a4e76972b77a53e852ff47e8a54db67d75f1ca699e5a8c434dc47a3813f129bb76bcb4c8110f8938fc94f184ea20bf6eca5f52e259b8f9176bbad8763cb63da7ff95b56dcde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b25ed9d4144ac900b43cfcd7f1edfcc4f7c976fbdbaa4d8637bcaa70946391109981e978ca023313c3dd093df6ccd8f3ebbaa85b8cae680636d0be656f01769556bd58af78260bddd10a38b0a3be27a773cac4d6c1d53e0a098f889759f20b44aecf68dd254e6d959ecb523a1b0bea1ed87b28e5589f40591336d3e229be85e4f6f4913eaf80af2b11cb0f37c4557f94b2f158341afef9519e128c5616f64e05d57f53f25dff345d81d33ef5c3d8a526b9507bd3e0b5c6a88394f0c9c6e7c2b475c85d8a3a8b1e0d571d1c364784cc8a7ca7ae7cfb24366a0d2865658e4fa8495b24a16c9a9d8b1ea77332b1d58dc39fec02c4723fa7204e93ef0cf4f10c4877425975cbb61430f6a2aa649fc6c77e8d7fdd3e5b0d9e9495b0fc252cefb7ac5ef6a9853c0de51a4873cac5ed2dc6f676496a8b38c8038e4c6d988880a7bf774875a5fe69693d9726af64a51d77a03f5f3bad8b2a6dbcea137a052de9e81059d07437e38db7891956c5b2c8abe38fb5b0fa5530c56a7b4b46daab256588b043443663e3a3ad94a2d7aca4bb7d72cc9f59e2676a5c86216bf4faa159bc18bce0555ec6adf699a056ed3f6a7f2bc76770eecb06cb72dc53d7ea6bafee89797b57445f3ae1136f544af882b863cdb455d5fad3eba56946dd6ed798a76bdbc4ca8ffa102d5e8225af0923eeec5df51cc0bd9aa2598065a79b8c6ea56f9f5031a579ac5bdeffea6e1be3820ee80dc0d8f19e775e14dd52b6f4b92de550fe536537de50ccaaf228acb8fe471d2c8b4b27bb57e6fae9ad9ce16adb72ed98b8b6e9cfdd3a17ada37cc455d7774dea337d88e9c33d438eb65dc9a27c68d27088b1f2a5fc586bb0993753f6fa67bc3886058f74bcf67a95b42aaac3e61cf69942ea7940eacd45db92899a2c0ccc4704bf4376da39c69d1e3b6bb146c588dd3431c4a5bead8aa2aed4f8fecdd047837527d7cc25ac359a5fabe7384f839b42d9c9982dc66a21c7fb5cb7316748424ef5005d389bcd56fc4a8d80f88cd75ec974ca9ce9f2ba995c5deca85cf0a7effcbdc492ccc6d076fa59f8cc0ff3355f184f4abb6c774a377b82ce2b9a8ff60777926cadb871ef3434cae909f6e902a5e644de9e3d6f088aebdde0fe96768baf91656d903c4f1ca88163b8dca14e823bb6ee525583816cdfafccbcfe63dcbedb93c46a14fc7f114194cd084c209afe925e7c55ed8d7ee7cda8ddb71c4ab3bd5836b80ae60009dabd1e5498e0d5718548325bd339ed7eac4a75c8105f3dfe9fb64e3676b33775859de068c3cc747bc004da30cecab9c64fffcf8f6c0c8122855031d7bb0ca735042bb43b8ec6ee13061046acab9b873b13519c22678ace2b59f92aa4e8269844b1de5e3426d66c0451a8d78cc07e719033a536c2bf4c7397c64c6478be5f42a06413b8b44111ad9742b8b020711446d63cdd64490c0917557b884eb429b05dbc0df7acec032adbba55d3e104f7bf391cba28b903a07712a8da3a1a92f5682cd650a628573844032a307704fe77af738696e974181a85c5ca1c14f7546f8713701115883480be2cc686625a37b62292367b5e1546f4189592639cda4cc20974c6a87c0377d15b8ec5c84b70233b64800b79c62e536553b43263532c6bc2b726970cc58bb20f0c0bd35b317d9b66b327bbeb5175d9611985ad799ebb19ad0587aeb856c288464d983256649827de9af0fc79afa1aa5817c06d3447a25ab3eb8248167ba60a4462ed47c007107b1eecb630ac4707b837f24d26da46bcda77c4b6ed5b4118b79294744788b9a9c21b168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb8615262408ae25c2985189ba8ab99643624b70557a984011474586c357f1c7551f0bb069336fe85bb903040f48c4a111113507055f2716d37ea6a6ffa48f40584914c4738397430d65756f298aad345671077da8a4173728364a493bdca944b1879b114166cc3b8293937221257c2e78f8f1c7794eccbf0368ce34921a2ebb01e32a92255a676e77c39564b575aa5d1f9c7d1388226d636f4f12c5636b2e2f712c59ca583a811bdfa56448c013cc820f21a36c3351aec3c2c6f01243ff47bf17181ecac752108c43a97729c6b9472270fcef5a7c08665f7aa9faa55b152163e8446c1bee5082192b5eceab269ec13e7879da3768bbedc0a104c5e9496c63e9507881a4c8e758211076653f369e58b59bd7cae5b9a64772c2a84329e43f492fecabbb56514cbe70970f361e6d3c6595065f6cc668c64bae7d587fa8bbad129136d5c9b6f757a51e653d2754aa0e35307845a55b80086d5a0e86302d306b9ee1550419b495d424f701a098220897fc47333d5a1e994c8584a00d79804e4989a1cf02dcf9a0ac2ac52be1090bb149778235ff6091075a5360ce095cb705c81e3be126984f51aa471f90ff98c21d3989fd936502a8a2b38c4a2320a618df751c7099d1063495a6a5936c744a094cc1ff1b04ba8b56b0464e852bbe06176034cbf5239cd2c687facc2cd37329adbec3a77b4842aec40be902e8af72fa5805345668408cc7b6073097391921e765e4d76025fd5c78e246da268a4db21446f2cc3273861d2081daacc2cc775631927b709dc1fa8993b1e92619590c08940342219682af351495b2e0aac74786c897fab196abb609e216997c2c7b283bfefca4b1f2b1b6e98991bb32424321ab7d61e4d13c44dc93295a75f6145bf2d4b8f1a03109bd7038ef4b16fc15f44ca6ea3411b68400eb20c46c11cbb98201d705a6cf4f4b792aaae80d97a6ab830576aa651142793fa7da0b8bedd877217d54897375ec285849a79268babace85176842c601ef8c740a21c2c5321436a21cb968ecb5410e811912cb0962f713322021516535907914b86e9411d27cf164b580528768ad37b57300dc201557bb0a142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d066f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +ciphertext = a611a3c02dd6d3201596fc2e819f631c7c468d7437c5cb5e1dd20d69079b6397e4735b54ad9f14ce7764e1f7665ee1027423f129ce329d4f89d967b7e9a1f1851a86b9241695db93f77276c8c13e115603394fdce1e29768218f10b051481ba1477b0f50424462f08232899c6d0da4d1760e9baa2523a59ed4bbaa1d56ba1610174e99c81d56aeb8f9811a88cbca115e98b4f16fb0593ab5ac3b86f2c0c1b66d8be9d2774b66c0c2f0f9cc2df6ee453d97f0256ca73338643438b03e3c59ed591646afad1424bee637a50eca224adc62d447c64c3b18a55aa01b938d66ab90099a76a48f201cc66e067d4db6f5b4f58568eefbaa68fea67ad5eb8c253bf4a1c30ce0c1993bf097f9a9b5d04a92fbfe666e326b92ce22de4f11d3a87024c315e94e4c9aa404cd5e4d2ec1d2c7d95657ec50e15ecf10801329ab243f1dc95af92518fb4162656f1aaac8bc8bb8832a6755e29d7ff78fe1e4b93578fae62c4e6b2d896200f7523427f55d6305b3eeb5285a47db7c5e4f628d29d2ad39af473167625cd848efe6dc72e45d4b531b4a0af4dea4206a6087d7a494f7e7e27ea24b5650fe06aefd954da1cfb8691c10957ebfcff92a7683ea584b112bec9e0a67f831b305e72b7f3e58f790988e96ff9fdad1c6b2b5f5f03084fd7a7d6895f8e7bea32a344117dc9be191e89abcc8888b72f091c0a742af35be4af72a657e93df0b48bcd602e3a7141d962d692a3ee90b33a625b83945356b13ae531a5d43f30afa5901bf791f22650f3f2faba02817dbded8b9712b7641372d4af4ef2916b8cdc05bb5800c3289388e2fdbf07f2fdb95b154a2e1cc6998ece7a514bedbd489ee21cc1df314b4fbc452c1378bafafa083ef00842e2dd585668eef7b00e895f013edc2611ad882e76f9b85074be087bb9f8b45990d1a65053eb561a34c8cef2b61d017d50055ac478e82c6fc881e64cef53b0598b0e354c2042325d5a55fa7d592bf8bd8f01fdb18b391a069d3eacc373765859468700234138d0cbaa4cf64862ea30b66afc2ca9effebb733e007fdd6fdeb483d5d6e3523d32092fc0fbf94ffd7918529e192603a609ef632202c37f49e34ccacef9c1be4781dca2208097cdef7365025141ef427b789fa4da96a07d58c2a22e158de7b4394c38e17d98b1e363579560199088bf6bda0e799132ca391849ce59c0742282d20e2ad70df32d8484dccb5247322514f6ab1588723450f4245920c6551088f0a2d204b6806f054c185501b031b0d1885c33ca17ce9124edaca319c16aeb066295b66b86b70ea7762cf502a0b6d785f645a3283e2f9c97fcd54ec07ace7ca8ba0fefc013c201aa18a3c36ea8592984783e128b076d5b99a237cf99bd449d2b92eb66c1c2503ff190ec0eb172f6d6274008c5cef30b5b08a1b295d437b357fb2febc2bc7a480ce7b22fd7af4d2805d786f3502d743fec304d7ccd0c42d25a7062049cb778f4492ef4ad90a97ec1c2e14ad79248c325e297101e73d65960aa0085f688d41cfa95e31744e5e6483 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 483e8b2cc6a9d8bc6ebe8ce249ade7c14fe4325b61a2a8541fb783c448c3a32ced82ba7907bd9e361faf8e0dd0706a3d3a1f81f13e5044c9c4f93bdad72c60e18637577b942a54f589cbb466ac344438750b86cc86b97d16339a9ebd365e6696b193d41543b031d9f20f8fbfb8acf1a6bda0d41ee09568b1c01bfb878c9284375949c88395fe41acce88ef86d7cc8e51bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee528f02daee9c90d81beb38caf08f05eb5e812fe3be959ef432be27793f27bf9b69113e145d6a1452e3fb5fec89c38c00d8eabf075c4415586beff8b946380c948b94d8adc3a79310094f230663f4eda9174dc7214884e0f65fa51de6dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4cbf2e174b061bc80e924f8547576b72d5490ca3934c9b15fcb69612ae6399744799ddb2cba3d5243a0e286fbe2f87035295f004eb56be37ddd7e915434c4af6472c1e5c51a5d6e6927d3c49c715c5db360a5c2fcdb79f59c7ade27380fa9d5eb7aa6f514fc6b3fbae657c699eb85a53395c13d3e87e8980023ef96969bf45b3f574a40ee8e32696d3a25fec31816d78159e4775350b89aefa8fed34c9cb155879668a5dad5a5d803abc0cc58bdfd4d8fc2ffbf7d4af972aa66b58844c058e50c0b8c89aca3be3f69474875c01da94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946e7db8b87c56b81b770255d3ba87485ba3655f6697715ede89fc84925b87c008c3cc13c7b9447d820cfa33aec64133d725b4f2b72e9d9bdb5ceffe7e131e32e76e5076edb26c07ef92ae59331da09517f14716a3406bf503ca5f29d4479914cd10b3457ab6fa6bc7ebd08736e25e9e6907dab8c8439b4441bbab5d0a1ebc6737ca742747ca69fe5ed734a8baeb7755da9e4e88e064f2be9f40e285865d63de718c6f1b8e6153dcf7414446bbb8e29a27e6171aa60bed86ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee76d3f79a3d83724a596069f337dc071b6bab955844a18ea8a6d96f86d59b9738d819ca3b6588d5f578059df8d2d17e0b2cbfe307a5f9e18533713c41e27fa9a6e4a98dddac0a83a265f6c399cc9fa9b74cc4774830c8e764f31b14f74c90c526dea7fe4efd3699ee4e7b9dd3bddfae6aae39649b75468ebb578f5a215c3ba38fa27cd36e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781ddd9ccb64993299745b34b6d7f897c1ed5e1a6966e6757dbfef9af2eacbbb87d1dbc39294db584c7c3a795ee12258951d98e45cf73405ae7adb8cc4d11788225557a83b652fa5d53e95d7094bfa8c0dce77e7bbbe93f33ece88810ff8457fc05e646b90a5ffe92440d174d92a058d69c96869d8a83377a2db9fc2d668607dec3cbefc6242b49a9da97c1adfd6782fc8d309cb898593b08b5d8138bf30dec5918e614f764acb49fd7ffbf05a95f70d0ce22a9f9cf7b53d4113ec92944972b8bc9a9c494ab384996647e177a87b2dec45c747660aa4a48d88a5f7919ca46dad338576463a1c24f5a6c4409e2ba82188f7ae83bed4e6c80ac5f8a6bbc1ad58c868b995d907fd77e84173c9ca80b3b92647a1dbec6bb883a4b2160e4dcc84c89c6adbd955cc055933d3238e325fa826acef899a555873a5b9c189117844202c65e40eaba07d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885660b1d3df32d1bd50cc50757c5227928b32e0c567872e66bcb58128b15c8696710a7b33bfda469128996f6979f896b93d22910383c90d0d877a56b4b7c77c53c99128719c2995497dd36877276a25fa8b74a4947e223215a314a075585da457daaf17c41711363950ef9013a8ad95f9e07635546485a3568aa502d608321061a6999057e705c46b6691183874fa9ea38bc392f718c99ddbba59a1865a135207a00058a408b6c61772ce777456c92b28a51ce823f7524a26639ac64aa49d6903cc2b2b5b60b59643bc950230362caba6abb5ba4f6964331b1f62099cf385be3f5b43c2b8402006bb3386f5a16354e45118f0b759c3363ab4069ec2c4c15cac4e07a24fab0c682548337d157e6ba213c7801dc5a0a7045a442b4939d611469746e9da665e2e910b51c56b77a035900b25490216c0bb53e04173b3bc454a7a17d77283ee278e7d30496301480c8c1af6b3e1dca213b174f968c8a45a3ba2044bddb1492bef2af610b4ed2481ae0823df53282ba7750fbc7a764db58e3789ccaea778083c27ed101e3c75be5486249f9818a08047f97447773c7dec3ba7c59aecb5778a09cb7f1182b2e0a01c182a1bd13ab7d72af97f96f564607a9a970b35a6adff275c35c22c2444ad6e997d821c065ea49080900e766c0079b7acae7bc7cb3b31301656fd39591e0bfec2c33f05a0dd633bba463781f1c519d902342bc12bd16c1ac8305ea9769e489073297784ee45f99b248670749c728385f601fc84c1ffb298bcc447537785226bb5de712b7bdd04a0ce39226919105f06ecf6bcddb0cb5ec3b5505b5a169b05480b2587ce4934d2b232a44a6683920a81a6038c59497c9b47faa62f4f2120b15c360616e6573bcc5a23a88887b50d1a7dbaa429bb00a9f87b63829b1b641922425016c979db571ba0f1a139267bb362c68f47689715cad6636402049c2b5c616c321cba6e43c1c1a48a0e141cf3a71c0099bd183a5c0e59bca9a2fb637c1b534cb6687493eac495acc7c5fcc4898a52e44094fb1b7014a15c88e11a9e7244ee53c2d5b16708c233ed37859268501630a296d63c094f563f0e559c59453abf05a93722aed5ac0c3cc6a0be7890f8c3191677c21f70c8153ced3e2bd96a4bfdce27f86b809d8ab04dfaa837fe030f420b845d23c78cc82a2d7c440897c91c3b726b4622445899de72bfa263b93c3cceaa8500b4b0c240046387b25bd98b5901aa670180a2a8b27de424f4d804a68dca2e044430d701b67e9b4af33c60fc54bb3a94a8b8604fa5882a401a5647b8dfbb20878e4b4094136bd4b5bc14288463c2e87f0cdf6d9497fdb5f42f26d2f9ca2e048a757a59b440c2c5642232e714d11fba959ab9ac52126bf689864ac98cbd1a633baa3ecf75c09c4c6878994cdcb3e882798ea02aeaf39915dcbcebfe2ba14e620f53b3d83ab58bbf99509033db99b0acbac29fb4674c95cb94982ac398c2771a8ab6da1ce9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab397537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +ciphertext = 06cbb7fcb9fd91bf6cbf7f1c8a47511fbe998d1e0c6c20ec92ba6c6d86e71a22e7233c44494ffaf7c9f1075222019d9a57dfd3f9754905a5ebdaae12d2e2b16b537eb00ab967016539ef46700d15ea21fccb92b17b7edc5c87e58ec518f167acb81ad4b96e4e4d51e605b3ae45fa0d6816c9c6f103bee9687ff098f1543fef241b80d1f6ba194fcb9f21ab1f5a90bf7053bafd8fef1104ec367de4525c6f60b01180b9166dfb66f192ded9707cf59c16761ec1970eac7b031821bab340f23758daeb9e36ee899ceed7cf2c42017f0f808743a6f7b97fa7bcdd5a35a72402da6eeb5d10e4a1ebc6eb5489c0bad8d529fcb47f4c6b4254ee64d31ebb149c975d5e14b7ef9ee3fc64bde6dc0019585e66f19a99ffd1db55bc58a3aa88ef7a575f2383f7e781f8b41d36bcea14d03fa9bb65a243dec37efb3fc19622340ab99a1183fd55eedd7c4d12762b7d5de711dc182b9281a5bb75cca2a5d179b2213fd7c940991a30b88297f0a9d307ad443363bf776599ea76bd25ffe9929cdf7a9e148f23e51ee1597e63493d54c4d9487cdb8f524b5004711af2276cfb8377cff0787c615d38536167b8431837492069b2667cc311d3c1be3381931e702822c04ae2041cd3a9e3a96527efc1f427d60aba9b4d0327537346bd853bc6e9486013ba744e922931490b841aa8bb1396f05a11bc1346c86164486add3be92c27b76f1e9edd2ca9150b1ebf682097341fdc85095dbaa32b7201af8b2672d7ac76c5d2eceb2b14eb911c48571a7fbdb6246300701122374e761a0ef1d6392498ff8bc3f82f77a555820e79d4d99e9954770f0259b54f01757bf9f19ea655b2baf3f4edde69613cfcc1cdc3c5997ffe893cb2c65fc70319579495c071ee08b18bffb1066b3202bf75313e45894f328a56a33299f3b9bdd413cf5d8e7c299ee920ea2b26d5e0d44f994f76ed0554ac767427d73ad1604236634a1d294b1f246c544a2aca45b0c35a7cf2f8b66390f1ceef3209f0562c39a5f340c85eb267ca91f2a8786d0bdad4968faf8165c10e2cd52f8455fb7d118dc1f75517a7ee655ef7069840b8ae9a03b788bee0ea758cbad93806896028dd050e6f1a7e62871e7f4b69e5beea271682dd667f01106dfe97a423a4ddbe0efa184985c25a20fafaa0cdecf4c940c43d4b53a10508e13cd703258ae06072a88a4ec02913b6f3bf7a66fd7f207dcb8ba2d988a547fc3d1d267746d0ff35c4975c3814e53041d2937a2a19ca7a639792c132a64b035bc6273223bbffa5cc5b65878f47ab6b56943a2a2ef39918b2874594f803dd5f4cb5228b41ac59ff34dd50890d0e99f24891d4fc04a6f30a4311f958fa8740010f74258e87727f855a4cc466f5d12aeae18a9073071e0c4be2fc0cd130431fd753630de8d347f6949b79c046c0b90e4e636656978f3e5852bbf6044d9964747de482b448dafd3f7b8e169cbd1a56eb7a803e1bf06dc11bf65a0adef9eb33eb2aef852ffbf03afb82459abd087a9f260d776de5f735a311318f41c5273481 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = cd28aa8c84e42a15d8c2534d5adc642858d6bb2c653bb9783adc640e9945c253af86f57c19c4fc6697ac86debfa46b5231559c11f5a0daabfbf43c40001d4e6d0db81237343e15a41eae90cf8940b74ea4b42b72d9cc8bac78e369ecd7d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a64cf69a69fe557299ff63b9f026e36906d84132c8b56984f4d26f6d7436dae2596e2bf4a8666f375bd66d2483a1b354fff9766845480ff396f6bdd89b724b0f15a34c2288deb05a84199d9803cbfe2f3c63d4dd56f358fab798f4e385eb0e35ed0c38ade7382788af503eee7ad0bc6cc0a4746aaad23345f10074b21a7dc18eacc898472767bf31357fdd3348c82f69b7da6ecd35a8c61984e7dbfdae648ff04a977a72b532a1395707cbb7cd595e0ead202498058e59f23edc340c438851674e3bbee0d97ffda3baa7f87b67f449e6bb461befecd771475d5b59facd3d181599ddac8ce68ecfde584eb225fffde6efb39d9633aebf02af3941f3f3c9336f97cb58086d3f8308ffc4e5db94c4fe53f03dc92fd7a811a9d9e07b7667846806b6f717eae2a3f3156b668f93ea9f79ab7949cb363dcc8d25e349db4b5ed1f66e7f5af991d5c96cda4d47648aefbd1fcfee13948b407fcbe199bc2cdba40257745d765c6a0766013fe9df41a770e96cc95d3cbc70549f7f6e914a73dc81d62f2a3a377fcf6ded59e0cc85b11a74f43d3f37c7561cc7d46c0e660b5cbdba0634ff3cfe1438a9b9c9d6f242bd4b2439f29a3cf0ae9e28d683f0c3cf6ca15d978dce7997fb1664a751458c0731d6fe0ad7d981d5188278269bd481018782f46ed08555fe5799a0654398285b378f7a9f143ce20673184c75e8b76f085899813aeffb8b6d486afeb2f7b3feab95cb7aa327d8b9dbcf7c7257ae3137db731e33f8f555cf4f8b7a1e6aabb4c83d2938b7c2ebeb1c3b3cb3bc08bf52fc1f5715fa89ef9ffd5d85862f7afcf420592aa245690adb8dcbb90d0b654c7d8fc751eb6c4ffe9f46c352bad34c40adba4fc47dabcf04b45e4987f7b977e4359a66466f6c4cc2b83bf6b87785367c81e6489d6c5feb975e41c4bbb2a3d8fda92012ec5242f7a438374da6d32f62c41b184f2584ab5880475cdda8b7f4844e65fdc25d97236bdacf82de2adab59298bc8015faaf28d7e8015695eafe8484ebad318ba9bef7c307afe42d8d512534963c7db9d0b7f5af7d326c33e7d53f49e8c9ce386947c167c8f33c88957f44989c45b4858213f49fa6ae36744e53cd94f1ad467b5043f7ed77f58d34491deb5f9f3f3f4ffe4611e921b8a9f94f4e9bb85ad965443e7f4a73534457be43ee5f677a63a773886fb79a6d0fa0b9cd328ae4c05d8c1d9845eda77c30bb7c39c618afb402cd9b0170dda2cc6ee8cee3a199f5ca22fa1434d9b8dc637a374d93cd76926ae94aeeaf1c627d9255ba2de43d693b888a7cfc6f0c39fa5b4c7fcfbcc198b3254cdabc5ab5edfb438ed3a82b72b5f54a39d21c3787958dc4a648f182a94ea566c598ba4cf697141bfdfdf4cabbc64db80e8664216a6e98d553899964a8bf39e0dc68f8fd7076efcd2a58b9c49bc0acb90283b506dae96f7855ed69ab21f059a11fa3fc477dd03a20a0337040adab8bd449e0beaa93b07512485ba33f291af1a44540bd04af4a3dd2a09f6454d7304d0944674a580551061ba5f88217aa57c10640dc1a97396f138c1a32cf40b0bd9286f88c4087f9084a9012d248c63efec072d77ab0e736719a23a913b7b8b62aaa5bb40be97cbbc1c29edb283c776aeb9b032e2c2691aec9ce89617b84b09712b40e2b713e566c714e0baa75957d6ba5062ba76471357252b72ac66ba97e10921ca2313a232a6ba908dea13645b5617938381fbcd748a11f61cbcb615c458d056f0d55a449c4f544c6673322ef106010cf139d1c586aed5a5dc210fff7a60f3138c34a4244398b692c567ade5beb55c1edcfcbd93183e1ed0c2aff5bdab67b51e39a58bdb8388d67cc1ec0d7313b7ec8a56cf3c9b73214c4ada14592794749b6834e9b81a2ba47de929e9ac7856b56549f40f38f0784ba0cdfc195952d3155222bceaba0e3c233ff7e19a65822437217a42721f9c060ac2cbb9c4e6bfa9fc3014d8add7b4bdf78291423511f9874a07e06a82b6369fe349e08333c7f56b7b7b808a0b4e888a95799a2df4873944cc43eb958b1508c66e571268e79a69178793e7a4d430507e1259d01c86f999c16772cfb7b4b330114ff55a51ee5407bce95a6d27875a91773420c24f8734b3023e9db777819ca2163c431de46f22f38398d46ee352b815b6b07e1a242b01a4230b59ea8c7b0c3c3dbe2b7c77b4c860660daa04c452e391c710722c67bc0632c072fc1e5296a2e70932d4d38efbb96bd636bb41260a7bf27cf5e71ce3708e6884cf0b8584adc3cd3b5c5ee1003a13731704472a203c8f9b49534309bf2b60cc3e2448e02b5a46d889ffd78fbe722a709a2d5b5c8a7d805bcff44052c553cb990ad016079bd87db7573eb1d431d1e549edc8ab56a0bf52999f32555e8ef2b03182bd8d812cca638055a73b548c8b432a2a7d4a6a074aa212d50362d1382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1edd04f8f8cb7af4c947af224dfe0af6a42c7b65120b9c18abe9161d88cc5c4780fd74403cd177f7160281884a11cf686f0f523f39cb7ad39b780f13a8ee83c0d646f9d85babeb306d53a7df53ab00b5a1aa8c215914a48222940fee10d1939ba5c93617690cae113a59de071c969436b3771fc50b2f4aa641a4c852922380a420fcdfccb81816f4b474a2ab293a4d97b2b280cef031148ea7e4c9c0db7e7cd0e50b203a6b7519c3cbc8062c9b60b8b81cd956463b8180c67f34be4868e3ba94b9f0226d9f010d9ec5ef0bb62c865c807184b96526d94170af9474bbc100530f7c77e46b98c2aa41f92a48d8027c855c7f84684389bcc8e7c67164a204bc5c0c90828faa439fba235b6f20785cc8ef4c090a708bfbbe26e1933886cc96ad9b4562a119d4c66589c85bf0e55606886206734142d432c1b032e0aa93ee3731f069a8cc069a03b95a8ab873b447a04ead3a32be3054af834882bcc581712be18539b805577e50ff5d982c98c0b0dfccc96a4c6429281068c8429997dc17a6600f0736b8453e3d77636faa8d0ca89f9193bb34819ca1117ea368ea23198ee11345c613993ec052992954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f3082f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +ciphertext = 3a00a38b5cf0894322b8f5c5b35dd486f4e4cd14b18cb3a101345718ff843b13fab8ae89af0bdb731cfbe6c5bca36200e5ac90b9faf0c7296b6ce324513504bc1ab4ebb91e77e9736743722cec11ed929a2d536c25855e7c28d1a6ae521eb9b6391647073c55ed0fab85084ffbb47552721bb6827a0dbc65bff589165f25610ade382367ac20c48dc380bf89c459d98cd5bb01da5899431e29b938262c29e68898602dafbcb9465d0f166986e19d51c00c94131d3a5c0abd1ffbf793d6e9a52e5e11d72233565cade9c20a8810e55f4d2fa80072db2c1ddfd98681e693730b693c3ad8d01230e45aa8822d191a8bdf90cc62829dcd40e75f568b8f562aa61a6a9c6a7d1be451ad6bfa404216c102b4d6aeb4599951b0b96cd81e2a03d825380a96a831b321c6f14ea5af818d008d6d80f28b93f2e3bbe22195d4ab020abd3af6b545473250720bc992ee57ed9f328f0cc1988033728fc2a28dcbefebd698215b3a91a05ea5270cc8bf8b0a1ceca7e9bc13bfd8359892c795aa6360e1fe6d8a2965356cd5ea7f4f8740a2e9073126d0c41f07fad51c74cad707c9f83140a2370fcabe3e9f48673d9f1d007b41c647ac0d195f279696ff29ba14b6841213b7218d769be8f684803bb1d29aa6df3a0d6e52f29b19063a81f1446e54fd8f1a6887b0132da286053836c0cbe97bc36c8770198e203908d3496c43941b35257dd86fd1a9c5f5177b1f75a426b00ba9162e1630779c6aa4dd421b4abffdebf19472a3c3e27d270d30d17812c49dcf3c5b49109800625eb8454098e1f994bbb193c2f6260caa9ea62cc2eae8bf26255b7f3b1a2fa57231f00a7cd97387d5348d68737e167f7f22f6f4438b911a040e142fbf2d9228480d83a474d54018d92635bf2c14ebe728bf901689f35462801aad5545cb411fdac9dd55354e7896c92cb9eac3aa0b88fd6e2b82f8c93281d5fcd7a490a537efe83e9f3b8ddcc8f8a83a081354f0e9939f77f8368fd6f8aaa98c7019ac6c2b74a59067d4ec0b5c9bb1d7f0bc6b6e06b05d2332284eb5f24cc35e14af83d6633020df2e74c124bfefabc42338b4acec89031cbbe5c1ed3f2d464b77b4c479e37dc0f5d5d4497e1b97dd00aad4fcc47013791b2ba6f098bd751b66b51971fd886c03cd6a45addf8ba4af20679c498ef3b92f793d1f6a7a460a665c65b58796f57f1d8da4c127a2cba6af842125ee6f9c10a1cd9c9f06cdbe63ec6ed979b6be2048db2f83e4cd16a80e3ec5908f8090218e2e9f97b60707337dfa770d3ad27076d9c0b0c7aa1eb8e220392e3683cd19519660a17661d2eb92621f59a75a8c2e008119465793477e055c14765262b33347245b96dc1347792ed7271c5d20f73def4056f96100a80fcb89f69c451da786f045fb2556a2b3d84aabec88dcf99d2016c3697cffcb7f8f452c654375d1eb30bfd9a7941c6cfb1193f1d371ab335966aae0c14b68fbe23f6a12f5160d786577b2ffa3af2dbe46fea002bca529419faac0a3c9da0b2c161beaa83422fa6e875f63 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8dc4a33d1ad13e2dfa7ed6a5303693679d33816bce0c8a83594695531999647a48f77d8c663fdbe4d9a6100e3201a36ee053796356b26e46e7126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0f1f7f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab2233e8856ba8b6919c5a0a667867cdd2166b69bed4433cd44f289bfd7255542cc7946c8fc2db388c8b656f234a3b607c2f77eeacc3a5a12d8e11f5fe38abca9b8dba79a2ea17778fc2beee38b133636a5ef5aa77a52b7554943af52f7b53d0b84ecf44fd88de8f716fe564c5e587539957f4242d6b3a8f8a66d05e9f8ee3a0a6cec4b253dcf1fae197342f5e7fc296498bc9888ec347f528958aa689c8ddb81880e84cafff5509e8b746535482687040d790054e65216c8bc279ae93854382cf8cb438bce444b2258afc3a84cd409eee8373f877b30137c4ce4664e4d43dbf763b344489604e97f4cacf4ffd2f6d07c5824ccabe38cae22487ea2fade8aafdf304bb911c4d1f4573508a5e2ddbff98faea57f643cd85f4a3d6c9f056bf5eab6ffbdb3e8a7b8c8dc9c5cea953ad527dc055fa7bc04469987712d15f2257aeec52961571e75c32abe93dc5ed47f89b9d4cbd3966911fab85fe47b3c68692cf5a845286bae09e594ee5c6d23437bf7517ec5cf609c8628e8fff7cacb54d4a5ebdf5c85f59ab61e51f945d24788f459b598a2089a86ffc9bf66797e863a4dad732268a4e40c5700addc7d1ab1ff46b78e45ddc0ce9fcaf8f3bdcd40184af7182abde00a966b6d75e69cd11ab6fef09e3024ccc85b56d098facc9c4c81d17c577cddd9b8f9416e2f5d156c4e75b84691b9d948e3e884beb2ab3635dc357ae867b2496983cf9595423c541e4ce7957d42b4de41f08f5c9996f302ba911c67619434b3f9cc489e8c8abaf9faf1ec3045c895edc4ef745aa1f4dea625e47eabb494331f9a560857153ec4890c8fa5769563b8b1f9ba3c1b77b034f568038865c913d4a4f79f65f74c17fab9e6c5f236cb636ef5b68637ef955a9e889b7a1faea0118f8aea1a838eee72400e49cf27ff4899d161c34039e99b36185f068b5707fa476d75dbf149479b8c928fa3d89a4b941047b5b538e35685797e0b9e65f595da0e6a614393cfd630c7bfe7d1ad3091853f607bf38fee3c93cfb5daee9b2c57638cf8fa3d76763afee5838b8eeaa5a47b7b686fad5cc088abd48ae0ae593ae3aad7f55cb4c1347acaf7cf5a5ff182749e6aec39d62ccb886d94ba3cc0b97ec57a03a00ad67c5c1c6efa1ec6dc36b13cab713ceea6610caa46db4ebb86b7667fa0be6dadf163b325c89b506c33cc343c38afbca7cacabe9d494f044b550778678cfebee76e047ff705556b50acf04087b5c5e5936d0e53857691c3149521c8d0b76c431958970685f9a4a87d68e974ed67e78b7980effff7e425daf1234025757eaa3b645074f02d73feaea3943c4dcb11affbf569ab2c44867d5eebc834dd120e34d88e43d3d44b460d56be166b58afefe64a44f80968a1a4ed91a971e10c347aba36980fb1ed64f985ff8b6254bf61d94b6a0de6b0f3fb05e889761ff390efed87978eaad45bf5997654c4da9043e9ca74d95d9f97611ba36d3a65c0d17cb22b7f3a682b593595b1c682d521a16dd621a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf101bec273bca5d606a5e76fdc183175a233c93373e956580a522badd22d97d71199c1a7b4149e652686eda541e69187a2abb68f89ae9492443547cfde7b5d609b4835911d154c33e49248c4cbb244acbf03e93e52e71ed87a75cbc43c3f505422c1ac31c014e82009d4b13bf2cb7dab16896a320fe6c0476f37767ccccd80850dc94b410b983fbbcb484dd09b44a817fd95686106c710d983cd2bbc11dc4ae59091a401a6941bc704142c792c407f7524ede1a71a726e2f921b0626768307c31dab514a783febd67b50e93479d2c7d1787142f591607b7a5626a718d502b37a6f5b8766e8175c6ef276934a12ac1107aa3362840513d3f5c02042ae681181dcab30f6810389db07c3fa1790345e786031e3196bcc01c22bd064b2f9c439d7b7a7b7633232aaa4d88e0288cdb791049b8a8c64883637098def7c88fbcb974554af0f3c51c70a758176215871227869766452871602093d6949e1d078691537d9d7030b36926147aff8151cfba202c0364795122d1d748a18289cdb33982900b38ef9aaa5d10d146985c757ce5cf82ae0a2489e0c00c83550d455a03fc885dc7a5ebcd71529ecb0ca13ce1259186f9b0ceb4b90789aca0762c8bee063780801ce365540f440b0aa0128103ae0f5b4a5d9b98ff3aec5793e8fd046a7e15b517c5c4164105e87c593db19b85792b6c705e615c4d95c38bc4bab4f30737a20241a3189eb38865c6b60f6341dfb931626e729ce39313e122687862bced934ccf88411730fd066be831542abc5b15a1cb2d3f0aeace904cb419754d9a5cfa35d72e570c8d3b0bde5a5b18201f14cca3e3564c16769757a2daa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436bd21282d6a3242417b36211c84b75f388151f087186cfc01e59383e8218039db15da50120aa1c5489743bc42335a774f8494a4244acb6677b22a46224df7bdd8a9292ae58e07f3068cd975abb51e44631172535e52c910b48748a190c50d877903a4c7b9f4b18993669d254ef566058528a157428111d43d360ab54343adebc2a3636720f1e0c8ccfcb0fc3b71b55353c2682946408cad171fb711cf0b3ab561ba6722647acee4b8daf0aee2c43352609dc617549841adac54adfd3319efc715dd917ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a551230a335510f55733ca4f3a6329aa0830894e06a05ee578c45b3117fd07d62718a9842ced5f49710f7b15741ba5b06298c550b96bc6fdb0561926240faf09012e2cb49c66868e27ea318aaac50bf882c5bb8e674381a96645b7a7dfa936201933c31955e24912e436528027b39f74a909aa5ef4653cc23c5e448be6f81088fd322fbb1779be52ad60005c2f57241932ea3b435c47a39e6e0477b989c00bd5ea71ba671d8a37dc64d36216ccebb14e6dc7420c362926b555598b92f6a78061423a4cc8961d57733982fb8c78573c35584185fed801ea674a7fda06008517b42d1a45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +ciphertext = bc05257f294ebb1d9f523ee049a3a6730e4cc5b52e9760cc5d47e7401dd902179a830fc9261554103aed30dba87790961d9524952048d442623264dfeb2e4a4a1da9894a07d994b9054d664efba14181c35da270672e2a96b6c912eed8c5bb9487ee426399cbae893fe08ae6000a4ecddbeaba0187af28aa9f30f11e46e2e622de5f5fbf89e4c84a10c94724cf0810334fb4a9c609619295cdff0a7079a55d7231c05cd13b9fbc381d1b33a3f9170a4aef32889beffb76d91c3f9a3ecabe60430006aff1c59e6781c816fbb4a8338f4af1a1a9a719497b54bd7b753611ce0da6177850f0762d189312670c6028f3af43b6c8d9f9297c636c8e4e6cc926569c81f93e2c1b7844eb83420070b57b5df5357adbde5d794fc5d1c2c6c411b563450dc843a1139a405d16908c277db81f202cf53b2bf3a6231121e7d8445b6d45d7b258ef24483e34bbcda7c2670ff02e23b6a7a6fef8625fc83bdc56baaf2dd7987f37e565dea443b2c2e25363f74009a730f8f986d021af214692a702b38cb56d048a1a5ce2157cb932c9d8a4663c33b500485f7f3147eb9c50a49bc8c3d7eb5dad6cf206e275921ea4fb4e3e7b00abf9eda1c9c2b93f439e979a7b0331bb5cda584e59551564ca3bf065ae9097d0327220d265e6ace108258fc09ea5e0380e5c97114ed4fa4760220568209cf52a79f0aaa1efcab10e58b047d44c2cdd74921aa81ed53d6c98a341bbd0834b19628826691d6aeff3df36f123dbce39a84045011a7d9493911cdf171a63cbd7ef21a6fc206abaf9ea46d491d94e12e88220dc27891d1e4a728538f3c930807ddd5292ae905e22b395cdccaa6431ad6f3b44e299aeb2772db97de93963eacb47d24f09791380d98165ea0e38d579f1b5f6249686a0c1610dfe223ee389c09a7c4ecd67bfbde3348b4c27d7087cae132f88b1ac82d31e1c41c4418b6354b57e2c37cfe8e60218730beb2154437b66db7531b16bbe4b4b6a1c8cd1650c732f872c8cfc6761480da34dfdb6f538bc28f91962bc52447b2898815a8f79bdab2ff82ffee5073e3c90d90960d9b0b6c389969decb7a41686cdbf12005c0e96f3a096175425130b485c94424896ef25a9d7e00bfea40f0e2facfabe7355937901af2fb8da23b69eb2249de3e6bb98b84b3c11f65b2889a01073e75b20b7077df34c4a3da9461ad036c41a926f4c18db0989ae4963ad31c59aa2c14d177bf94a12f73d5b6d61c9a21702fad90a2f7f519f502585e3fec795463eade03bfdfab04f17f3b8dea98e713f91e21f3284a6521d3c051b2388c6c5683f5bbecbb1575db97be5f24418fba1e4d30a3b3ed014fdf028c3b8d80a91274995c21bba4cc272d31466d54fd6ef2a593c5aa5511fb95b02c3aa932aea4bc5341d90ffbed8f7fd8f94c2a511abddb4e2498caa887512d6662ac02fe6fc0a01df4377c05baf88a74cfeb50fd3bc6403a6dca1d794043ca59584bd6c5177731beacd58ffb2f0b6177d0ec260f2df873b594500bba6b7888c772a61326bd69a5574 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 38bbb649e7520a59ac57783e32b5d22489365713cce40e71ab46ab219b7e81369af44bab6f5badd06e3e963938a18f9acf6f5bd8594ed4cd981c5963f68874aa876855a9d41c5cf96b4cc181e57667d499b2f961f44773ca958193e97988e8e6d81fd78d0e47e41390f503921f139384d75efd9ecd08544536b4c9c09bcc2914a808ed90d98b5c08cea4a1ce6ff0eab557e5ccc197eba1a36ff67beace1e3facd6bd16053f22cc85634a3d56e564e30862aa24d9d48aaf92643b630d9f8f2d6c2c8bb7f357b9432a8474349c3e1679f2de54cfd4a373665a86c481b9d3e63308cf3a2af65a73e3d0068ba228eae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2b4f9aff3c9eeeb869ec9982d367c5809396987a2efe93dfeafcf45e774cc3541bfe655a738daf9b7601fb5e83ac6f682465fdb273ab435355b84563047bc4d7fd4aed3e0d4c9ee8b849183ce6a586d5a6f5690d48d4d8857379f1eb324977f30b461955ae7cb16c4dd93761224a47f4c680373c51eef51cb69a2c737cbb1f76d7288d33ae86480c7776cc7ca02393f333b6cc01cf00ae58922756d3664a30d8bf6240f672c27a7496746f8f567987f6340c7344745f2fa98d819d76a004a480f48b74f7c6ee1998741d39fed1f75977db4e8057aedc67950c9f9e30d526ba5a27e0bbb6767dbaf2ddb77e5f5b07db7b6143a7419a35273c14b59fe1f4fc5b69e8a62f3c829b5dc1fd8715b13dcec454c90d7fe6509ab1936ae759dc6b62a6720a840ab7e4f7b7bd134335c75c44a421598b89d631e2ca498ef56be08910b69c01997bcd20591d1967ef5ec5c036bdc1f19a01cdde03de6cafda45db70950cf65eda254f741eb7233b36397def4c6365a83b66d9cc896ff448f54194fa15f67b8154895173075039143dcc5816fcbbb1946a917abb18478815f920d24f8c856bafb3461a463627ec743077ece75ccfadc95622fbf925a68fa15e487787389bdfe4dfd84801a37bc39136cc1a49cab7cb92487f606d48d3a4ebcce4ff1ec4e8b12a6342ab6c358ff73795339bbd7f0439aa9cd5a47822fb8b01769eecde3686c8e872a4e2c049a755a8f9556e4665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc74fc0922f6667d4d958ce7b3d9fbea21fe43dec663c6e55464ac7a9559c533a647c6ae06c38972a26beab45c2f04c974c9bb860bca64615b6f088f305d8e862abc974df80088bac791876d327fd4e44df2655ff610d9a49989bed1d7b680b62cedef75109d89fdd7c28143a405a600a974231cfd71abd953da3c2da574ce2d3e786c77600646e25b3c305f6507eaed84a836367cf73d62c526e0630f9b483caf335d6bbb5bcf4adec4e43444ad7055349cfb690948487f7795b67ecfe4553de7a5c9564cc84cbcdad093f480aa844417446babd86a493b7aa163b76b5df35b7384cdd54147a8621674843d3d40ded6eaec68b6ce8a2c5c4f390c76351feddddb35c9f4c4a1dce48ba0860209fb2fc1fc90899f2c3463139239a62e878e4db61a45f9a8fa7905a8aeab0adf16dab5026469b27e4e22af5561bc9ed111a721a78587efaf59a4c7f6b743574398e31bee9db0a138c9442fd3a7580e68eec01077d31525465babef901806363a2d664ef8c1908a30491e336e27b0f8690ac71c30adb145805a15fc654ab8982565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a20e224e4361977b71c694a88e5252f608cac97e97dd7c80a5ad10d62681b57162269f7b8d812af039226ce2a7930e43007c0b3ec6a4cdb3897ee85796d051cb053881e1b9706a572ccc75d0ef32f92610c40db4553824f1a352fefd979a310124b9456a9106367ec6a50db6fe0b057fdbb00a46028c0d6a638bb7f2139ca6df68f014c4e1e0b79670869353912b5d67edd4b77c70c067aa76d174cced6c7a901c65737082276188cffe28bcfaa2604447e68d490c0f11cd22b8c351c2d63e7a01ee460bc408e174bc4a6cb023492c6eed42f5d85244ec883b1b49b8e3584f27835f21b6b2e6060e0671f289771d124168e196edacc1aba26cec9e09fe7367f46893c2ea3677caa3005e34e722608a3b64a3b987289952dd695a82de89b9034390355c5e33546eb833f602cb9324c095bb4cf66c05fa0ab98d69bbdcff155c3169f3df2a575901724b678fb080b67f32240ab8f0198cb43176f6ffc93fa602748d591f0b2acb9aa67a8d8b15c27140c320b0ee040e737077a8c9fd6a20dcb865ff51c41808757b0ca750c502a356b1c7d821f1bf804ae2b337819c5ea89542e079045c887ba6550e4f05693f5c7012424d37a17e2294669c0538ce69a1f1c1f121784e3c3537424bbc4d73cf1a685f03a24c4ba8fd603b328d2a07fa2b714dc1eed17693727732ec7be2b02c0614caf3d42b222061ddcd758a0674133e6cfc5362f855b717695acdb971aaf16320690606c1c42238856d757b5d610bd64427f04c97abe1bc6b0185116cbbb2dca28b5d7a9aee205dbd37e92bb36311c8936d958aa1744ca67332a600d8c719377273c7fb0029f27c75817746e1058dd196de71b0e4302682da21b4ec1beca3cbdf690509573959d816cf5fa034ce01d6a4ac477e3bfea75732678aea6c0a5401c623dc225c7a9a7ae6a572f738387181913cc71b9379a5a2bbdc45773c6a1167fe756e13731f47226bc678331312b99428b07b2122b2b9dc86b01c5f090ff632fa83b598863c0b42623549ca831f66bdbbbb1d4747d56a97dcef9c81766a3d90043c1a99ce5e81105e9113043342a539de446a7c5f9c4b46a8cadec388fbb8bca527d90a56c649200cb2a7f968611934014f9a7b6faf3015bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e35771947172118eaa02cd95f7137c93e2159d9389607c3011a76363560a97df950b0329258b0126c7bc10e4081ce46b7c7b0af0752b038386e9afa2d0a7543d85ab909376b618c0a2d33875d264b76941430e81c48832f43270160176ed5938492a06cc08392237caa8487abd3c83019000bb6671784109c7bc4c2a0362a5b5122e620aba511c49ca42d75091b3b1abaad9b8162bc27f182ae310872e789cf05f6c949598c41c3b73a1a9cc0808e68f95c8ad8392f021f77c79618685db2fb1d04a9a8acb8441ccc764aa3b191736f5a24ae31c23428390c1c22c6a6052664db63b94960a433584036c05e031a07823a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +ciphertext = ed678ef3105bcfc14050898f388a2daa0d61c5ab310fedc2107297881a1097f329c679ccd9d1cebbe957c137acacb33cb7ee31c9f5c148ac51e57caead59178132f69a7020a8419f4f833bfe4b8718691b26b771ac6e858551aabed2b9ea3c904a8c2723f5fb8b87d519f4a93dc43cba81c39063f732ba91116f359721ff3b6fcae87c5965bb728f4442f35dfb3f2078106078aff64f51cad6c62a5c8b056a5e6fe7e08046f097ebb1311603f7b719d93b53a1efbad985dd5bd5d2375d118f81347104593e6a05118836beb278a62d5479c7bd62e90b2aad04f7c6c0a4b5b410568b9033e72f1cd6c71c53717faaffc9fb72e27a3f00661f2b65a4e0845c2e7aaa391fc1ba253e6ac33abca8a2839eaa0be8e350101af3cfc7363424626ef571c6db515cb8a8ee209aded9f56a5bdc3dfbdb9d4f1a94b73698838550d4e348e5826a8f632d556385d3135ae872580986b43a5d77fe471db736328931dae7f9554604ffa969d5d2e7802130afd2bc5e05b3f3947483fc8ebc680176d792b0fce9f7d121ca199011efd51343a9f68cc40cf3c019338cb6e1b46f3ca920344d1207be283329945c1729704d3baf1953440474be9aadac1f705cb5ee8c41ca4f29645fe9b5044897952899d18ce25b841383ee086ba8ceaf712dc69d23e564e35a3cca5309cae57826907403065e943f255bbcccb64f39a54c18ab26a8164ef5d9d07f6522e7cbb50a2b80040bbadf0799ae1b55abfffd5d2a74c9c94b43eab75f55c2b438475bf4a4f0a123ce8e91e94b6ca6106b39ca34430efd34fa0a741cf93e0286642d45e78d8fb26af2ea594152a87d1737f54238c7a8cdaf174ce7e9e13aa207b627ebb4a92598d184bdc62a643934e114b356b4591ea5415fe42a9f47332d559b9f748752c46e4c8e1196a9d16df310ff2824afbe1abf520ee7c6a8ad7a833e01e1ac3fb0784cc85f3d731b40a12c667e6a0f3ad83505080aeed9309fd7492eccc9a81fc5f047c47c624941a0ba626563813f74eeb0a8a558fa968f809deda218f6a73b821f30700307b3aa52122c81ab3d48e4eab8e1bf8ce95f9d77014b5edbbfd21152305d427abc30c19ef3bd6e206eb128d245ef3f0132008957577081e1863ac3ca83232ec8e3a9d95546948c9fad4275e0a1863d5fa2a54fc42d0846dab4a0d74bd55fe5071c6c514b0f0fb69a8f27347013b87fb48d00a670b6fd28e8c844ebbd6cc93c527b5e0da483b3625e754b5f39257c9a167e5b381bd60f3cdfd5cf0d65fe96e02340922e10c488f35df7fa4ba9296f1e576aec3e425cbf92d648f6095726ac3ee8a6d812fe9ee629413f78978e200fe3eb1816fdd1eda1845382a1bec1ac57b23b79189ee7f67f9ab45731d2a2ee4f208025f0f0530294bc2e38868118bf2464fce482113463325223ef8395f945e0002d395c0e9695c9b8a0ca20fbd1f3b66327b69e6579a1ddb49f50daf499031b090dc2f8486e65d8e715dca3b5ee26a1cb3fba97d4df8e3f283c28a4e2abbfa3ae5ba78b6b5d8c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = af46e3488d9758cfae0c4a60393c90222c394dfe36e965e75537f1ff136dcc234d657e5a1ab43d167d8187f89a693d791f0d62cd53f53ee486ac64e79e4fdfa6a8bac5ddc07c7e58a1eccfe52c48484d3849a8fd73288878dd4eaad37d392aa487597f81fe9af7444e5b8fcfbf5e609af5e5c1c3f0b6c75af0def1d6ef904b0e85654a418e5c7a379b41838ace149b45c5b4d40edf39ada846102a6bbd9eeebed4710b2393ecc4bb8d6f54dd8e5d2667831fa6f887a74eb883a5a874fe0c4f7451ede321246a8797b7bf2fe1eaf64b0d7d6eed0ae8ccafb0116f6112ab6b2b2b928df38ccbd9b639b9c6ad19de92da98b5c9914549beb6a9b5505579a56943d31d722bf590d64ceed56534a96552016ff6c34cc1ad3f572d2ac0823bce358d860975f5198d88e02f9536bac34a1c950843d9a0a7ef31d975de0598e5fdd9d24661b2a79dfae85343b94fb1cce71493ad77d767e18e48373486172d5652eb4f98838ce536691de8c3af0a4970fbdc370db4605841bdbd884e08bca3198b05bfafa6f575229c56462b95170f6d33dfce33a4b1add3b41147eea75e6765f457613ccb50f94ab9395f6fbc94395a6c9d1d4ce3b79171a83a4acffadd3a915086b804c3b4240ebc1f14630ef3f17f059aef485c019a4248b4a78b5e6d769e9eb3be5bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bff3da7588d44867897c43f687e9f5c8bbbd5d0c35693f557f64eb571d6ab7e4a752c9df67b13f9d7558fe4bbc54c96e2aa95c0408e641b1f9b17a3e60dba78c5fdf69e93610883f8a73c67c0044218af5c2e05b64a1b8ebec972606bc221bea456d8ba86a76ac4a3c06429cfb6035ea50549db887a606e70ea38fbcc295a2f0dd1f68ed38fa97b6bd98fe0399ece3755d4b55e1636ef7fab678c394c83676cbafd80bcd9e5c9bec67dc998d7097074249585f3ec5c3dbd035dabc67d531db43f547cfe05983a7c6fe91288d9987343d08fffc395f5b2ecaad2ca703679cbb86dd420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04e3f59ae0d3db768559e173df07ad8794be0e6aea46145b6f0fbb230ca504424b4ea6e7cb305da993567b4cb94cb2cb3991ebc1eab31b5f5691f04e18e5a6eaaabe5dc2aa45fc4ad26b9ca007a7c2a78dacefa88f12790abec7e3eaec13a355c1c66911717da7e1976f6859922ef73f53632b4144b59eda74217e00d2cade0c8a04118e4d40a4234843a44978d0d5ae73bf5f43486d423235f5d7c8e1f56c8181487bba930cd9f72ace5f4eb6c9d71d753ff6fb0e9ba33a478b7e82b36d979d60765daca36e086ad872538eb02e531432b35398b7ed1355b827f776926bfe41880e09daf6a5ea58a8ec7097f4deba6b6c2bb8af2ddd09d7ea0b82ac0d14cb0910a8ec3988251dc9e94fe7e0686d8115c85bb6c47d34afa9359a35beb47c4ad4ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc14d08883d04bc535bd5c74dd59f47419601513c4e91f57323d7bc858845896a67d33902afa4b58c5dbe969b94795ebbd89ed66887cc6f9fe1aafb92ba6bcc38f5c4239ab2894b2467547ff3a63bef65e35a0c8ea287462d8cf8841cdc9016796500e61e89eff672e87c667f453c8ccd148b94c9a9a3765649ccc6e1c05e5350218d091783b6c7e4958a0807e73e9839992c8c36a87891b7ce5d7122e38b5cdd745feb1058fc2827b882df77cb564323746855392247b054527ee862abc91a557c431e55b81d23b1c1a94992ef540e07338fa944d24b17ed4e693eeb8224a0c5307202457c8033aa4651b2b30f85a9bd8070d1b11675fe240a1009dacfab21d50036426a6dc9c3dfc05cd1612ba91da51bd5a0f7ef9b235f1b3b2641747ab8a380b42c060357bf259548cb80788cb41da4c7d3c4b9401925588920df255167240f6b092c1329799f0039b74cbd549b2c053a71d4641071a3a95a460b2b3a8ada727193267de555e6ce87986ac06e647c4b7967cdbe5083c4b99a1b44b5df58959c48beaba0818608fd4046ea0c09a28416c6a97a1066c0650ca619d14a056252d38539f1c2676b69cc53502487389648fe596783baad0d7627cc6ab2da5b6788410b67285841a323e04d037f25e103b38b07672248186c969b04661ac6b2753c5429eeda389599b78e84608dea89556a9510627b29e13b1713a1442158561db8f435bbd6234a420618985dc4f71f0a5f15762fa16084f178e0e76bfc9ec5c35fb52e52301e6809cbb287d42b7591828afe605cfcc93c337bab78b55237b075a8bf08c48c15087e82600655234fa99f6987da7904ef50a1599867d56760ae1d70006925ade67157508289f137def9b9714f4cb72a017ee6a6325f9418f3a0ea3a8762c55987ab406dd9a6d248a33eaf264774aaff6f00607f37bc20041d3a170e07407792a43c5407fb3622ccb065b74bc1a54f86af9f7246d288fee725a6fd85e82477483f778d5388728c4565467a9ba3216d92089bc1c742a20b03bb526b73573cdc91aa8e085f1eccd1866280e791bd1e43d4843a440e050e2967daae26686cc2d32f512332cac82095ab0005133023e75c9c92b0388bc8b2822a82f93fc3520972e2e0a062a388931092bfa8758f251895c641186d1b40f6a332df3088bb24381da133ce40d3461a7d87a93e702472e49ad91cc013c936b02a96c4ce14c2b23ac79869c6d139c8d85b58da27c6eb4c4250bc3ddaa56dbbbbffaf452c09074e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779db92453f7aaa4e58401cbc6f3718a3352013e1383b4222572118878c99289b91b02d929dba06c6deb6f4c2b0459f86d04fc8d287b6a676b17e45997027568bf7bcca05c3d394c1557873711174242ca50cfa30bb3d715d1400807cc5ff1049ce720be3c360febccb61dd7244f4352b655a517485ab13b413983cc089749ac7144312966b2c67ad50096bc176142858881f09e3a075f8fa6bf638a13af572ba026a172b23317a01a999c8c1ef478422cbfa9802f98f2856bd6a11f8584c532807771c19c411a2900c5a57c9b8e44b4c07b3be3477baa738ab2c407653a309d7a82cfc6b86a1b59ad1251e008598e453e04e3306c1877dc703869da25a9b91fec80aaf4f30b4d0a83e2daaac73990f05a9002d6ada0409450454291e37112a9ad97147cc89999dc89a30c809757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee63859f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +ciphertext = ac958722deca4336b0f60c62e7c9e13fcd4b006cb719e07b26fce400e3467d481cfffbf51699fa8dd5706cc65dc69d8ec2c04229c636a94d6a0dd59bc81e90b7538bc0622489f18d445cf2a7082c5062f4534e0a156b4b77095af6ee36d2599ed7a961b0288f40a52a769b5ff92a7bc835cebf20b0aa61a33379b669be2efa997942b71204a97391df9461b2ffa7f58c85f437effcc82220484b1d352f17ff76ab8516411558fa3e3386a79726ada7c29e8195fb41d480b2ead4d48faf6949aeb157ce17f6524f1c0468defe260f6b5f634b265428574e259b546cd48050f2e8144033f686bc08d202563d55833c217bb649d50e68ebbe5084a1752cf479a24332f6b87229ba8f38a3f75668f7478cfcfc4de61e65495b22e746ed7cc8ca5ef1af1b3aad68dc224d8c458eff394747e235c191780c8c405bbfd7ada024558b04e93afc1b09ce5e97474aca4053be829cbf7668c660fafe8296e7f0c625741e5cd0ece5c23aa4e5183559cc09616dadd9fe4a471158d27d54bdce7b95c6374d88353e8f09907b6d910d228598f77faf7d14eb4faf5cfb1aa6cba24062878f06d2c8bf4f57673547abbda6266f26d6893ea8d9f09c5adc8918eeced2aa88c93a6039d53adc5b5722c2bc4bccadfd2768acee766d400c200babf7330e17be15023522123bddebb445274caaf1bde7ea23e2918f9b520a3173d7e060791126668a997c29241af3e531ba30e1c26e7611b32a346f733de31d26c7971beeb6d8a9725c282b2b07947e4a6899de0d7cc703bca6cd09c2f6d24922ef78592106d1dd0fb8ed29173f6d79e82df387526ceb9f0292b8fec498757d1680a1784df0c22fc05f409a908816bb060b7fdd6cc95b180fc3dddd50405c4deb8af5c68e166c841710610ca126b2469f964c8d19b3b0e9d54aebd19553e9c791c0e50b90e9c676e8bbd1cf0571810d6ff0134bb77b451bca63b37325e4574e67b553d834b537c4dc371a69352822844fc8e68786f73826fd3e38b8735966b96caebff7a67b5053f7e18f3fc0133317c6f3f88c0bafee7b1ea9dfb9733c8834f401171cd8837d7466a9114f58dbe278b6882050730eb0a979919a267779cdb35eeb4c2e4d1187c0e0c96f63a067bec7c8a91db1342b95386e062af1e43e619a04c040fa30f40d2ea3123ca5ffcbc00b353e8df0486df38da624cee432284b18d22c6051da022255d16fd85736cdc5a1c635279f28f2348d5ea50c22f5ad445e3e025ea208dfd9be4c42953a578e238150253364530c51fbeb90b9e83d0c0bfc59ba37ade7f001272eaf84e88b82bfe939d43830fe7f6cab1309392352fe2a91d05ab5a93b3b530e1bac3dc3fdd3157dcef43983cbe0a5b4a6f0dae4912126bbe5d4c62fb9ca542a25c2bf463d519ee01642425b0c93893a9adb034ec67149d8d3e91dcd643758094449e1cb3675760cef095c91b52202748ad12bcdd4de0565cb0d214d0f2cf40cf9cdd21ad6eb0ccad52cd6eba41e72fb3ac7b401cadb08fc6a6de0b1ba1f02eba76c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 31cb44a14c3ff94d758055bf2afabad14a723c048d4e2dc5908bb781844d574a96a18d7c59e5e92548a0089396a78b953ab5f677b9a111dbd12954b67467ec5d0c7c5e6488d4a8f90f7665f403febb8ff8aeefa7254e3798ec3261a9d1215663b3cf63617ef55817dbd16f61bbab86b4f96056a498bf37b1b94f38c5099ec9feaf435ec0862b861f334eee85af8d364a54f6bad0e44a24ad577933ca858f889a955086ea3a2c94b058cec20d64dcd7df976126854bdef3cd386a855caa3869f73198f5494861079ac84606ac0f28e0eb78a8398740be69cfa1777c61a5cc1d758ae29cd72e6d87c379a567648558ac8a1883734c64361db33cdd156fd47ea2abe534b26fc6e346e43b944dc33d9aad1d6525d6586793a2b45fd358185fc787c2cee3875e44f5be66f7c1d493144e3ee498b17e9cf95908b718b3c4a7ed3024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd15ffae2569fc389d2ac9dbd2c236f4da66d794dea61765a77e43acf9ee02c735574ace463b55f11ef6727086d74ae800924c6b0eab6ed9d5d5c0eadc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67dcfdb38bab1a8e8ecbe2fa5ea8c7588ae3bf8eb8a37e5949084c26b4433741a31c60fa4c51f535fc6a1c61dd057c651040f7f7808eedfc4a8843c59f8563bebeae5da543be2146a3eb7b5228dd958cbfa5064923246e93da8ebd2ef920e0db1cfd5d4e32495dccee6c5bb7aa21b6cec5c9fc1beab7343d544e7af5cbeceb8ce59e45d9939dd332c05ebdd2456076e7dcec688f117bfeecf7dc5b8b4884446861b592c8fdb530bf4cf08513f66c3b51833e51b9a64ef97054a8c03f8baa257c64c2c8a265a8a9215fc41146bdb3a32ce0b7196aa335658d6dac33ac06af0179cfa0dbd4000d484f13f5c9d16956eadaf88f68bb72b7bc7cef2a486cc1fcdebd40f7aa316c6d8ceae7d8b9a747443c5e7f37989a93ed939d905832e76afaf4e72d507d689e54f7b5cbabb536e603e6b3d38911513b400ad83f8bfa3c72a6c09ea3b4f78e29fdf85fb99442ff6e237e6e757afad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea59211f8356c369878855127cf2f1ab66a3a4c20299fc8863b609f7926175cf1e3967ea93b7ade7a8e67796730f3dd5e8ebd4d9345af36a38ebe7e96b8d85b7c0beb586aefc9fd9ebc586fd71c1b9c350bff83b6d884a0cc5eb3ed887aa677d34e92db582f16ee7fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e951db4ca99a4a98db48053878a45340e0d56041d68a74ee3be4b51a74dd16875541e099935ea92b2668ae84c5a183cbbfee6e96a1d38973cc07c7fadb803cbe26986c827ac764f8cf183cd5fe7c9c719378448d58f57db62fa977dd658f219983f97b517cbeaee0ea479ae8dbb89ac1c9e6419a3b25f388c277ce90b866356ec84c34bf9032f86c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c8bf4747e9f4e2b5c4ab8a4fc27fa132439e0e3af23aebeae17ba4cf39a1569f5c62a4c9ca764364966479d6630b9349a335a495fc01c0e8f77eae5e4749bcd8577d50a102352b869402efde59f5fb54bbee919e7d4a8bb8cc40fb8c7240401113152ba727cecfc8e4b817c5d537df050902bd03df866317006a2aef59cac269813a47fd337a0c5b694f4b080f100089255614634a2b0bb1ecbcc3f1d84cdfb3054fa749736e531c2e673716079cf45c89b444b7d821d892c7ec39a74d39b815c2b9981ca47f5e56840341ff9d23fc877285f9b90fc78bea1b9c5c647ac52d066ad7b8ca2aa01e0729fa22c39d9c3c6cd833c6aac061aab1c1ee6819d2a245997b8580a9e1630112cc6b62c4952215a3281111675f25a10ca0c32bc68c7bc920bfbc7bcd82edfe130b0434afa29b2b9d90ac3f1143b5664e5e51984b52d976439794507d92cb256a1520078972b843ff3dbc6736602f68b289e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a45a1a62e0b749ee14a38e11a094bae60a38c84079d81aa655782138671a0fa186a727457d351a8a45b6fe05369f7b158de844e31117ddc47af9fe52075c6acd5f93a31c38ec7f608ff9096c8562e0271a35fa7265a56b24bf31c6a727376d1ab3f600573342e60884f41d355b2336e464b94554b7c108614c3394fbd561a2e74ba7045c0d74032877901e4f8a95c41ce9fc72013c51fa93b5c0b3c3b0a8c90ce0960f510a9f6a453b8b0012f7c2430350b8a4b6143ab5adc7aaa6f3533e230c3062b7caa33b1e9a3bfda7bbffef8341ad0a33ab272bada717a4790f4c99cf430bf114b62854810eab7af582a2ea327a599c490e25795cc5c42219771391b33df4c7fc01524c4c520eb4559c2ea8c38ab5cfe27035c756248662c1e969ef478a2d2419ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2941b89b803ed1c7d8de65f64a29d8e7bc2020b723d391987f83db0bc35e96aae7b2772b37159a3257ead277532119cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352cba074bc4714deb09f9cd81624d2782de91efbc30882c45631e96e35c9b53f77cc0d268722ba5eb858a1de719a88ec240da229cd7766b9a237641c1277c006a6672bf61ab5dab4c223b7381fd3c16704cf7920b2f11210c969b6b46a152b72598de4aac1665d72a45bf51370de61559f83081dcb6aa49339e489968c80498550afc467c8aaf0c6c1b9085699b801c75eacc3142be38de6f6a64ad6708c426eacc13b09d8bea819bdc200258d31a8d1f308d0a7470dd35161379191576a03b81d70ec58565ca7c4a6bb333338d8113d70f5bef45b6835917e17c2945a06cbb7f2225675252f351593b06a6db504b6e67c6e88763fb06879187c5053029724b3477281cc5c5294b36b64f12a08084eea098489d5cad338a0cfa61231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b130a103c6244a17870b75023e0014e6d8433ae5cd2b145bfe253a8bba300b6465fce277e2fabe36d6c8112887cb0a6daea4a54e258cf89071e407594de1bf1f4aa2beb50263dc5d5fc729b632957375b5ce6373d9b93211a66a29736a6ed616ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a1f4022e6c3bb3d2294c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f12fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +ciphertext = bef2266443f466793113b5d0fc7413bf46e39fdfb568b88550b25cbe578868d6074a6b2de2dc03b8ce8a7a390cbb67c46c500c7e6a044391db3af04e95c88f2acc12c63613b2a139a4551e9189b118ef4f04de5da17fdff8338483df67b9f683ef87a2ec36185a33bca3147fae6f6121cfe41ad623f9f15676bd40fd7a2802568e9609ca00bcdf1d59c6595ca1b67db3a3bdffdedc7dee22eb33bf9e444c9f115ef088a32fe4c800bd57fc854ba31c53979d48a8071f8f8b83049dff41f729ec4bdd5423fdc088592b7bf04206b920cfc96aa4721a55235520237e1c7cf15e7905d864e6a040f8625a55330a2dda784554891d35862811969c77ae7260f776f1a768606117fc922d936a058151850df0aa94a05a9ef0ba817533073f831b03097ba43b2a3433eaab922a1020cf60b5e02994ab56d8b1c746fcb7f699c42254f3161cd53388b50c9c089a73f30ce34c2ee1168e8acd73c3665c89205c7b1caccb8baf5d94ec9451a6ed00cdff4515fbb8b3cbc0fdfc0d2e249eea42ace1990e519198306dc8c040e6b8822af99755825d2ae48ea94dc5304e7646863a7af04d393a35305f15de1c38e4ab78c061d0006e85074af2e8a7cf53a3ad7f631de6d49c84124271b3a29e32e40ce001e2d21d26cadb65d825a126281a157551c87f712d32e754b5d8cc66f3c0d719ad0c0fa3afec198c8a89d2459d304d4b8fe164008a9432fc62e21199f7a3f648f1d990a55f1ad253995cc848f6e5e7e320c221e33a31e8517aa35a6001f75a75b1e3721aa912ac92e4a4d0c5c847ebdb834bd6ba30addb70c613d4ce7e83e3a17e5273441eccdfb05f9f205d697e0e3c4aba2070fff99e2496fa5e9548767f6b3920eb3f6825c194cb6d720caa133bf75d98bb858bab11d4e1dcf57e251aa4fb82bffc1629acffdf25010ab54a6226c88b2582ad8f6adafdb62723b0d173377e5f7bb894ad70b26a2c22fe0b940805f1b5160aea7a8396729e1428446308e3ca349207d6354e2197b6edb19496146cd71edd1564e07afb401888c22aff7ddc721d276819cd908915e0d7797b20bc7d8e2e63c9fc3d899158a0862df09e506e437bf194807544b3ed75813ae767538beb5f2bb1f25abb08e9b446d8ac4e965d759f033cb68980121660e2c9de083caa42f8543ae4da5dd31a1c1eb9d460b5175f5b913a0cdc99e81c696ea831cf6e87066f479950c852a240f716462773205e5ebbe5b769f844d36729ad0996a40f69ae558da55b9792c328403170f2b917b65a971d0ece55be01f857d67ed4a8ef59ad83f7ebcf3163770bab4f583b32e8213b000b65d5a7c2f276430c4b23cc33d9877a72bd2d755a131ecbbf88d489fa75b36159c17a9f1d61f109048a48507dcce311875a52920010712c6af5a181051de669c4bdfbd370590218f597e9e39afd39adeb31850733df8928d7daf5a6e2f3ce694854d340557647f4b8fc0f6cf633396f2ec7e03bb74b1f8f3615a78555dfd3a35d540151d4ed385967890818f997d8ac26a4c29f +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f3ce0c7ee97927c89e67d88c4a6dc46b767e38ef9fe78c7cae38717e6a2a70ce7dcce582ac697e99e5c9038ea0a784c4b75345a23e61bc6a586166d4385b507748d3ba5e6b10550f05782126ce0f386eaea2c631afa83871cd03a5db891d96ae82e317b29ff21b5df2b2caf4908e27789dc2addf216759b005692ccab42829f7a46739ff7a9583e9a5eb9b6f314e4967f5bb375fb627e5a45b918c801b4b1dbcf4d56ce3aa7fc5cfd1d4647295650b5cadcbcfc74aaac28c8f233f64c1d0eab51fe6213154d041fc5aedf5af449cfddf494056dd0a01c449e1d84c886e63c83c1342eb1f6f87757ece86d4c30cf9e6240e538f196936ab9bb429d93fd593409f3a3098f7ada1dfe5b7fefb1387ac06b442a7dcda9d7f0ad9d49d0fec3088d6e9f09f1a0ddcc52b9517c685c36c45801875dbce490163c91c707755cc8701bfd4deb9aa0ce56df24d7fe5e9eec4edcf97abcc4c9ba304c75812196409c19be10c494a9be38a7fd5fb5558e7f2cbf6f1694e7e4e7f73781205b941eaa3ecd09ed71e998f9a8b6b734d0a048a77ce4ad17fbf65313303cc86150d477e42a39cb4b8c5a47f3d03550f4b76d5fb7b524fcf658d374a8c955b0fb3fe888d72eccd202bf328b737f9f19bca95eef35a8d890e7ee7bd9707d9e7545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cecd5fffe47fde6f5d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22f8ecbe9cbd175afb526b6ba074e456a3cc941569124557d3bc652dd8f59ac66552ebdae06cbaedd19ec269cfc6f4bc7e948329778cf48c3b37f9a3ed714c5c9fdd99036514daad5273eb256fb7e7f7c91ea13e1b8db8721e5d01af9d9922eec5873499bcaf0aadd8a135abeaa544706dabf7338497c578085eebdcf9e55f884e7b2a3e3dd39505cd9dc46defc324b5d5b0defb2656d596d77257f5485465e33a6a64ebff0422cd38f0a625254ad127ac941fbf3362649d2049f8ae8c0584feaeeaa31e0e98fe3da74d53938f409d1b6a33f1305a383dce2b35894ad4982939579511edcf8aef174373968cf94bb89a9043ec828048e3fa862fadc95294df5e2f66dcb2de04be8b9f286c198b8c9f1ff4c79a454e8ecd742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc0935efa288dec0da59d9cefb17179321df3b822a3395466dac34384a364d0698f592734f72bbdd2de7e31196afd4da54fc68d1d869f8d06ebb267f74c98479ee1cff65fb985f6c669d948fac15315863d84a4eef0bd5eae72bb8c23ab5fed55e793a4e8489b423044a1c0e7273a4be35b3d5e19934b99b45dd2734ad4cb4c5b368c7b3f65003d7b7148c199a44bcc3a2984f9ccb7de5e916f04d8f7cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648b5fbb94dfe32098c26e9a51a6571cacf90015f65b6359f07598b10c7674f5356b0365ceacbb55b2ae8239eec92c44f0e4bbda5ae3364749c5384ca777dacce69bc48b6a0b1bfbae8ac5cc40aca6def4957167cc1ff4dd0caa3a12f8c13934fbcbdc205f53d713aa441f5b0ffcdefe26411e0cb6648d36c6236468793848aa4b7f4510377e0a24bdccb712bc98cb21ceabc08101328d3d032cfe9c82d21372924c69ab5a402e9b3d88c87e9bc5c90335e5ac231a1b87ea3c2527b82445d7c8596b10a609616e4da431c9593b91a1aa21a2e436a359a7a5901902a6b516d562363bf95890501af4c5946626ace3f276af8966709cbb9b666b9842102f3077978e4872307ac65ea11002cbe4dd0bb83677419b89c9e0c9847fa6441c86b8b601663e40357831d1b3c21b4a8985ed50e546c2917f332d4acb59bd64d9be88efb981362458b8d868da7ec516ea9c807a29c5d51385781302072c1f3295da2559003d4265cb330f43ac5b774562c182be83636fa034bdbc3cb25ab6c8c21c69b873329321533a788287a40c1659f457c5e6e15456da54a7fdb18c8ba246447606f2aa340a48b4fc667d7e67efec47910e05c3da4463b75359668821711530835357b6a8ec62a3e7817c508c79754063f7110362be73416a46533341cde577c17a75b3316ac59575eb1a1575ec0104ee77f70941e91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797ef827f0bb0821ea69bd9c43abf2181d0775fb64b8694c74f0323600fd3e5f1bc5cbdacdb2329928247e4759747c02cdd924cf1c93bae5c37be8c3b9c7e09b4660c3b9901ee33b62350a695d799b52743d5158c015cc609e891c87f9ba02616ed2d3a1c14aabef101b4b42ad5c47916481bef01b11b9496819ab76a428c0f5b8a69ebb24fb5b3407e1c22e2020341575c7098e63379406c9b60b6a1733c171682b1776719db5acbd2ac6ac4b97aa0a3c8c168a5ab389010a01b4dd01829ee4a402e54e633a229a94cf96e01f72ec4054c13335b89bd6e91e965bc324924c028b433074c9705ac4ca2682fb1b385f058d574515319397754cac9f68cb70022882a24242d1c3f1242cabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a5849211d831abc2c86834be35bc3500cc44522bf9aca86988aaf580bf45a5ff7f8192e110e163356b8a52486f772204bbbbc19befc631433f081e8556579d288b3b27c1a8209ecfbaa30a82b34eb722fe2be60534e2f625c0ae477826a9e75b7c5aed2398525358bf0ad127c15915133a32a9add47a72270a98f942807fc59f2420e14365a758c534f289160a65cfb34619c7c9b2992083cc699f554bd64586dcf379605581711d607235c944820cc28416ac761498d8b54193a8cac8b815d7b19a21b02a6d5a737c4984f3a888c0b9e3f51b95ed9430327642a082787132e94d6c26b298b77554e7f2237ac286f419266580697fc9316ec1176c4d763b194c52d79b25604974c1bc899560b72094701709797c5183391a268853b9ff3aa277c707906be0b078fd6619050e14b48bc73f877bee69a3ebdabbb8b2198cf51b14b2cc9abe673caa803b419be1c34b6341c2e83d2013152b557a87ac4fb55c5c86ccbba995492cf960479b044b3d6233317677c78a453d4e247ecdab3fb200c3d2a0564c4100a995c4f70597e498cf0897b507ab35e4587e2b875030303dc2ca8ceb41ae2a9725085c12040c8d0cb20ace46f1936725bcabd60d0b880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb93eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +ciphertext = ec483fe1e90af388eaccf12f71eee44a9868b9d22fc604716b42147fce466a3d9499f2ac1a601e1eb6a268ac14025edbbb5d02c0b2f8a60a4b1419cfd3682fb6f08d8d62d51f535753b05d4a3c3bf515dfb7f32ba2dbbf491739ae06850b4ff7bf94bbf18395a3f7ba4f504899f21e27f31c58b2389e5d018aa232cbb3287109d52655efc595e46faf0724426fd47db5eb9db222f9f325bcb97e7a273fa1c1bf3e5a22c2b5d3b915f7b27ce6d7fa9086cf92fafb7e0f1cd466e74add460ca84d518ee5be65c64f5cdd3eb13b1a5447b0e3cf1f5bbe40ced8a2f6dd6a76b175d017400611951e2711fad5a880412b1a29bbb3774b432020e93f90cb7643e0cc43b4425fdabfeef2586ee284e02968773fe186facf694782feadaa1d2c10a54d5eb7d274bf47c22c8e7545c5992204760f8f1fd65e26978da3bae8c85f0117e6837a87e2b4239363968d949ad3af50524733291c72585f21c8e91fbba2dac44e6968a3bed82723b9da8b6bf64eb4ed0b7188aca874835bd8591a14386ef6f6a968b8306a4a5e38ae04acb5533c3aff6e36ef7de90b6e9946ab7a1212714efb564e9464c47a1dc0173e6668c61f7fd24738f2ae66708abd047b582cbf5f8b794de988092c293a21ff273e1249ad499ebd36cc7ec6a7a5e28694bc820e8f9a5e4b17eef4dcf421f6a4a872fc3c5aff93e6f2c4753e84fa352178ee1c2defb18aca27c55a32cd3f09c24d0a5cd1eef3c33f8dcb52e0613b6c45f16d4cb2058f89491310027ec1fe23a61ccf5778053aab940d4091fe34b713205b074e1fdcc6f7f95235d46749879717d64d012facaaf35f4326670cd5d312adb6cdf493645056a13fde2b9e7be6e83e09056e6b54c51bee49551b333126d35987d7a75a494bfc8ce611b2dbbdf954adc160599e14930846ada2e76a457d473f8bd2a3d0e4b4db62ec8e4255369466bc9ad4df424ebe5d6727029e512517a68d7f426e5fd3f8c55d4b1ab1889369da30b38664e77e9b8e6458c70c9ba6d7ee3eecb61db33b71eafb21544ecf68a22b0499912ece6db40c6aa0283b76446ceb8388a7a6929c100b4f0f333ca49de2b1e68495336b70468a43877cfff03f30dd306a813961979ce3118ca0309b4c8be667393e9de346b2cbd730cacf59a2499330e3b0c7c8ddc284f9923ddced65f067bfc7474a4b673f6e1e0a39916be5cd05e71d96b797dc9c072bcc2a4f6690d6bae6594d9ca5333a7b8280150f0debb5e0d2d14a37540efd2ed2691d487d144c42676d96bc902168239667ff39a0d5d82b8ed9af5f79a972fb571dc1b47dca3cecef6f3dcbc045a730971b9e417ec682cedf562e4e129de4285e590006ff03158f4c5de616b0280524c0a50898f13d21adb49483f3dfe51388582e4ef2b3776ae8c2ab36726461a7bb404af15745a751d48c78c3f82475dbaa0e634d4fedcf2714000b16857d8b25e71acbb407bbfce4926cfa5d527e90798c58c820f7052a7dd3cbf506d63ec499e953a9c21cd8144b3da89b6f02a04b32e6998c +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c46454fcbe0879fad6dcb733496ffa71171eecaead7377eac75927fdb45c903563fa5a48c18f3343e7fb3a0a8aeda9c75f647648a92fbb8fcc59a3ed476fe958cdf968433b46ea296056a8460eecdb7d4430253bf27cc38c8dfa639b7f759de9325d3bbbdb1a5305e546591ef7b11332bb6662379f4ff2fe3105176b81a777ebc946bd4b962f8d50c008dce026a513f7c9c753d8f8336a9bc73bcabc8353bae0afb69aa60fb3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be54fbf226fdda987c612d30770555c0bc62b25ff367b95a91399642155cd1be7dbb848b642c765feaf400358040d4cd154a68db46f65bc5f5fd9d9890ddc04cfdb66ded52bc2e6d6183b444cc385bb8ae17388d5f9df4ab4e563653b5f72899cc16b37d74ff6ff7385f557c941571a1c73bda4f5fef3c343ed9b88cedfa9be5652736ae69949e43b5c9719c4b8f4fc9072ce0e3d454b3d9dd315c93579cb106a3b16bab7163983f5d5e4b8195e6bbb8d2b70be266679ee03c4c41ebcffc73f2dc6ea79899f7dd83b48c24bfe82a4fb2adef71efc39d5eefa65c43d57cd2c79849e7745bee15b70f4d593abd55c2a76fe21fee094b4672af90f5e7d8ecfdb1155b94fee9b34cd9858d3a8dd4ccf7f50cd728ffa80d6681c123f4ecb7463964db73af3083c3758dbf9ad40c979c4f679e1436fc56b3a8eee15147d15e3afaf9a8bef038b6905c8848ce6558cafbc6ea92ae9db0272f8695d664721ce5e77d8b0944d6486da745ea4a5587ba2123e2c82d3005f838a2d5b7bb09b8dc7aa39d4956d49447307ea268a9eca907aad08d48fc98c095798d0fad43c42c437f6762ed3678b6e7d1571de6f405cad77ee7c786b56b3a88fb5968c26869f74af228cef9554bf20f67cae75b5434bf9259553ab4375a0aa6766b2aa0ad58db6979f01fefecceada39f8b8f576ee2575d65d9df6dbc1a57426af9fe0a606bb8f6ffe45a69493b09cee712e88a2b5bd371db5c0fdde25e2659ed18f75d28f77bacdca51797d46cafe91951737868483a418427733fef637b4aa9496c30fecab67b0b7278a76da2eaf01874711e79f8b7b4de7859378c867b9bb8e529656200584ea9a5881b657b68a8def8dbf01338ac1b856c4ec5b0c48a80bcd6676c0ca625fd5296e59155d5587c3cf0c0aebef20d5bbe9840dc2d5d9658935a67614595bb3fe48e52877fc5ba639e0f3f54d534c58cb90a0a98bd2cfe9ea4dfdd7ee93d4753d17463d7eb8c9c6575e0f6845b6cda5bc69c60ade28e3d78960671394b75c5d7feaf0cef8ef4afdb395ffe4da2f6bc75fb9b79e1d8756705b711bdbac1dbb4ad4eff003e74569d739c08bb25cc9ec62caf1236e76c26eecf6faedec392a369eec2ac80e92571c24e7be7e8fb2faae990e5ddab78c1dee631304ab5ac67f74846a8fdc6547c2f4c73ed781b233ff8a6c876eca3a4ed60a00b560f76e042e85340c4a8257660c069fa429c7b81c5e37e5edb559f864e156dad39fdabf590350bdf02247e6c6847cfd86b6958c74209a8f399d41e5389ebf5b9b633b7fdcd8cfe14bafb262aa9a031e49084a6127b8410a5a46cbcabe6b18f607c97d4af6c6a598a089bb40c1998d16cd307895035b15df2c34bfc05f634813eec780c96b83fab557075cde3b64eae6ba98b65106e729b81d11c926404e99164bac5b546997d2a842f6aa9ce1f6bb7ab7551a06a3649e1caf7872ac675cb8981a124ca05a318bff9a234853821a3036a86404b0f056491a5b20ae09dedb123df8b4e9eb612a00207c6ccbc580373b0921fe2831f50610340865232c60660655184d8a0867a47811b88bcdc4e6dec5874839919188f63740588ba97405bb1ff2925c1553188c0137336948f7809dbb96d2f910a9c0aa95d49267e543057976e3dc7346cdc7560e68911b8829d37bd0eb20dd5e2b0eb1538a98a76a68798b5469f9dca82a08648a2da13bdc1a9b52a7b6f345626bb691aeccd14ec20f1c252b4fb2595474b2dea0edda47b87cb51f020072d489a2e79cfcf9a12b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a029e1ca5cea27d729065d7137bb518c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee590d1ad93852885db721b85d4061dca1327179acdbfc329416b23234572901b3f63a2cda36aa65b17035f449af2b404691957c30028f053989c501d8c2cf8a8cc0c04aa59f3b19a98777f814a18a0753a7180264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657256015f68a8c887c23205a6655f30c51084925167bb75c98b8a25b7579bdf40a912365164814794bdb0b78824fe9066cc63473496ab9cea06248d883d1846fc8084d59f05277aa3eec0c3186d68bdceb6c240cd0128a6bc1361467b861ab025309c82183233c37b35e8af1b464331cbe7cc3974a48a8e015a491677567472f263e31188966eb556151819cf52772053936abb0d0a48e99357e558301dc8157a8a7853212828269786919a8f9032e17f9b692ba8efaebb602e83bd4b75160541500779d1907b1159170dea870e6f57f5229222e85b178dab32f897bf45510ead084887566942656357b7896570756ab1614994f982841a525c8ec63ccc8e4575df03be2f5cf96505ade252fa4e80fcff664f6fa8c337980251904a9135abcc509db15a49fe4c6d57b41bb6383b3483ca5f5ce11641f9eaa423c0c3254a508d4319dfe72168070cc8c771ed3e06ce74c93240947a8dab87d889f9ad894f37243b25259153324e103b73c708371400ebf007bb5459ee084be938a18d055af7cc7aa98fbb88a156849765936e7273bc385a1bca94a74368168cf26d8806c7901eee2359c8694b5439f1e82c0a6892e4a68c4858a9a00b1496e177d1efb57eb9c0ae382b56626595673230903cc19c79714364cc4b10891823535e21cbcd45c90d471e684af1fe243e925c848565a1989637f7614c900af1bea9049b78e07f00950ac800ef72860e209c192a4aa0b901090987bf15a2db6165516ad0238a40b0bb233a365bbf2bab2f60eeb8a54771a8d8e5279e2740298563aa2868e2df1be582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc3659c03d37240bff084d77f09dee76b60952221ed2c1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47be99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +ciphertext = 9e87e3da4198c29968ff7e7ffc34af342463c33e928f1269f1f9dd9da05f7e6ccdc1368ca53debeebe88475d7a820be6266995b186c27068361275e3b2ea5fcd04484f981e77e150612841c15f5d3eec0e42ddde5c8dff60c0357fef646c13656e83947706b402f0bf4e7529b5912d6ce1478f9afa10b33e0ad8e64fc0c511267fc3802c21e8b39904ca88e8336f6eeaf9c9588001868fec48c5417e131345431b56db9b6e4468a2d9990106051ba1393277e9a55666916059e75ef50b399a45bb8de993ca4423ba9eefc797f1b2f4e9b10c63a79912b697d36472c3a53666542bbc5614b1d7e598e04d6d7258ee3a870bf3c715f3fbd0af474edb638cf94d4b000d4aa1f84f938f21e2b64b4f5aaf8d4a64e66a39268eb54c3f283c6ab0163b7ccd7a8c830bdf7cb5e7ecef736dc3837f6db70e18e23221cef0d6d2a3a50bc789116bfd1d3e4c6fb4ead0f5cfdf66e2a8c1e5f769595aae06555f0473247a48edfc9b5952bf5b5aef540eef286955347f4e16423dd6401e34000ebd9e330f2d8c801365c62551250f02c30128422992e34ff615ae123fc30a203382f8e5d190ae6e5347e90086351e4adc328f01557addb597968791490bf99baac1b5a4c7c5fd0348f71f9f62d0e65932e621cddf5de6732b182a7549c7d945a8e03857eacd7578623d993e1b9fabc88bdc9ca1007e79cfd0ab258aa1eb8ccea56c28b6da4bddcd74012d4526a39cb7a6c19175717f65fb02b10ae0ff90189c9672fa53fdabe48469a2fbcbcc5272d26f6ebcecbb5db514a53b2fe5ea45a1498022353918e67e3d53373ccbc0616c3f72d87f13ca8660641ddbc8c6f345aaa4e8ea397a690009fb080b70c7bd7b442ab8c5f7caaabc284fa140484636598a725868235a78b91c748c6e5a5c5fecb7bd9504d35745b1f06fd7ce6f7823375080937f81e8d8c6d894e606fbdfa64c928ad9beaaae76cc5f4ae37bd9cbbba7ba34181442961aae39cc534d44cfae600e79cad2d198969c85b66760dd7aac5c4aac439af9c8c49182e8d1151c33803fdc45a7bc9b3fc7ba063dbabb7670b184ff4092bc2f9e50156f5a85fd75dabd385740eabcb5bd816372b869bc1b751bc8db94fabd51c9759ecbecbc0403b233467fc3f08d2c94f1d0e0a6ff92a6824bcd6088cec85771ed9f6c4006d36a92c0aee038f96cc1378821827cda9ab645391feafcce1df8a6e8dad89abd81e87337db2ec1981159bd6cd17f39fa6cb02759939722e53eb0f42cc4265f85ea042027a36a9d77fe2d9099a48ab1644102538c958b7a5ec3a55a4d6291e885086605c07abd1d21b05e3b54962b87a2db165e6e351d91ba33ef882d83cc3ad5dd01d248db82642df1a0ee9175d115f86b1df2e7a3f5d1b33b1f6a41ac0c9f1eb4311c8720687886a5b9abc0de282f5925bccc89f9b779970cfbedf951ab1c7a06e4a0c04d7d1692f0edfc61eed1eeea7e0e3a440daafc6abe72508bce43e8516bc2eb9f7e2eac1ca693863b4b07ad985fae99980ee736d32c69af71b1 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 52d431d74363ba07b7ec47c2a5b9815706e7b8c7b7d3e68ce4ffa31365bf4f2e747203c5edd758000a8c09d38a83457fb8cde5bebe87e94fb46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556b6fc8aad9ff0ff59652ceabb789970b3fc69d153b14a687fc2a56baedc382ba4f908adbef79bddff781776abd052d44a1c84c4d8dab9ce9a76bfa6374e9cee16d81e376ea09cc327243e936cc85d7bf319cc787322730329ec3694fb61013c0a51d82b92d34a3eebfc8c47916859eda63d33d64f77425e0e95ff65ae36d531ae9e5d7365127bcab5b50642eabe2b69de823b660b4699f8859de768990a8e59d3eecfff5ec7198cf1025bf9ee69236d9e3b16aad84aa4c381a577b6c7a3403627c3f3f11ebc1f304747f47407db9a8c9e4b86618f598ff8b6fcf72ae2e40a43a52189bd6175dbffbee9761ba99cb7f4b7129eb6dc5b1655dcac51bf47415370d6bf0780eaaec4ae3cb477984fe80398d50175658ccb4714acb603b6b3aec44ddc7ce64fcc8e331fce94c48ffee0f4e0da6fb0576f7a6bd5a00b5511d78badaa489f8bb3f3c5b484face4517d8b8a8f8ef24b815eb43a6b9be27bfa49acacafc46434987bcaf509eb936e40bd56504fb4525fee921b63733ebf986ece33078caa455e8871cae2894a553cedf4fb83ea0ac44ab90e99395af385bc440515877cb69b74bdc847f4dadf2388486d8909dfdbf8eeb86fa8478147ed4cc5ffcf2cc30306c8d98c679d4cb41ebadea8b395c08cac6eff348474a9504592ecd34a93c3f62c9751e52e93719b617355c59a25679e9d9a5e756c8ebd3e3b174e1a063edc733b945db4f738618648baeaec5b76376d063f9be6f7d6e73fbd6139f755f361096cc4565573572d53b55dfc42c85b5299b1cdadb9cfec4605d63666ff4561d8c1dcfa896d1c6d8918a3e7ffa8d52f4ff985d3d1ebcc8d5395f0a64d145462399dbb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6c3fda66d96d426b9a1f4c4c4d0349ce2bc79083f247ec5d98e43bcd37cd94b652bfca7b989bd63cced2ea0772df0aaec75cf2836eb4fa7a49f3c3f9f2c7c6d04c859ca8e6d5cafaabb85e52dcae066b9af4d9951776d41cc783dc77fddf4f55905d473bb43bc1f93bc6ea7d33f46ac4999cd33698eeb6d3c7eaf65ae7e3e48691c9bd48b31e34c9998da29d60cfb6ae31cb5a3b7387f2257fe94bb3ea4c963e0e84a0cdf1741395f196f086fd31b7bd5a7834551a6c8f0e09e498af9e12db6d777bd5c80efd8b36dcf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a95ebe9b8fc9a7aaf5cfb7f7c73f727c765d4c496d466942147a8a7b65aec4ba84e5ef74577ebcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ffaadb663d79bba7bfb8908b330ce45e4f65c6a8a379a99c9e69ae0c288e30a1969e0cb708d0ca6ff1669d8756d1d63dade15eaba4ad7903b5d801456325d57187758351588bfeff2785c9fe84adfb4c59245dcfa72c3d9767348eedb7c2097b457bbac8aa96a67d785803744e149b3f23ea85226aa8edabd5a4a5a7cf6633a394b756ab38bc652ebc1bdb728c74ec316d039ac982b118f1aaefec04e48448d45f72b319289691a93a20283c3cb1fec992364ca83226332107704d3390f71e1883b46bc2f31b4242744e0847e72d5645586ad0b8c0fe48ac04a003045ac2d2101b52c7c1d494673bea69766a5adcb38ce3a978209471b5d7095a720a4c1971d94970884f11fa90c5c8b7009e2e1769b382004c93a2d9187b23929d941468444cdde233db3791656c860705b714e3aaf076921458b8dddd61e09ac461e96a1b1e9af19ac6984129b6c8ca9d4e39d70277b5d9a6a4b605f5e0454ac05729c2691e87a8d79353289678490a822c41c52a2f56b91a35f89918aee8935ef2bbc48485bd747cc5c59066b7577739b669ad21a5561018f021663f5cf48e08f39881d221552c846ad789810030326c8530dbb369681c69cc00c2390fa857a37ad81623eed4262db69929353118a0886e6c1ca3d36c65898968eb7c187b7b866f18a8bb369aec780e0033ebf1b0df846cd60633a461c569683598c7744fbecc54282725e337cec503d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a222418bbc57d7e1325fc2a075608988bdc44e276af10ca2d7e52b045514080597a0ff73732789d0f955f93ba77e8034900251416b43e291984cad36c53c947cc954a8320c11424be43283a6dc586a9fb39b2927867b79772dc1caa16234233adb5ac819f1a172da5194edb997f924a827a85fc7c7a8281c98f7a9cee443f68a2aea6001de7c7475b46b55ee8991dccc6527b5fa1393c9107c4d35a073ce29a7ea205a9279b62f5ce21f3aab0838b42e6679000cc4c182504a2a4e81757b7f6a183428786f09c76c69e2d7598f1e5049cb57738daab6972abf6d8bfd2ac7137493bd2b8b5f997519b2026ef38623294b91999a5419356bfe03e338194e471926fe5842e79740f416adae2a24f441ba4a0c08acc175f347ee3b614664496a5e51c01a55b1d2a3e8486cec4c3ba461970868502a0f9553d776514857bb8a872c7f736ccb432b1392e99568b51b9c9a56c441ac0ccbe785693722f90d63a0f78c8ee777236ea43de2583d0e093ec8bcab7c8c6ddd8254258b7a5732939d953e491a6bf310449083986b2a0f236c5b9a300db22299146b9a0943115845f3fe98045ca844bcb1132e0bc98cb54746937b1479dadac5a4f9320dc572ba81cb250f13869d132fa259604a76a5dd56a7543b96c3096d3046389a917dce53cbdd9ab04a65b31c6c5cfa23a2ad53faea3bff3985fdff9ca3e3965989c072f4659ee8914ddda0acf30a64a1a823b78561d5a9304950ea3056f50b82915c71ae0b6883ef319d061464d8050f37c24c62c7693f204dd4b4d74b66dd7526fdbd707a3490769764adbea61c09a2d7f464d7e932705212d6a9151b46c2ed93a7b99c1148f679d622419a4574310ac20941b3e51591ca5d53cff51a6ed2c081ee7b4bc23c8ba8b1aa2924406618715731b1cc404929a38911020fac6647c24306e349f1ecb4e2f530e8f200eb9c0a315606a3e130498f96ad5865ebb4cbb55265e69316a3bc96e51745b02f4a593b796b5951f48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f79bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b19c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +ciphertext = 7f5651959d131f3dec04f463341a622dbbb71494fb88a8df3c32ba4f398696feeee85b56a6870f77362e5bcce245c5e26e6ac9c8a995cf8b16591a3fb13ca611acb8b464556e1301b742b18b85e79bd8aac5e0c7c69faf37d3fd6c04b22a6a0936e8f3ea4acbabd6e6e1c5254f30061fec7939d165fc83196071a4950da73299adb4797665ab76167b024f7ad115a89f937eed5a9f9223250f54cb496e94509b1368f6ff28d1a5a5428c7f43158fd8b4b962db4e69f95841c82f9b9456999ac0902787c6b94b6327c13c40816afdb3d27f5a5153607d48f79d3dc3a40cee37ef2b255685435af03e82e4ede89cd639c7f66ad44a8a6cb2c6aba3d3362e075d6d11ac78485b6c69c77048db47d59c5662d4ba1462b40d1b7851592a9f442d6ed6e1db0614203a0667589e9736fed1621446b4d92c6dc550964d3436cee676aa72dbc7f47bc053434aa9fe04ee2ac3d37715fb6df7156a3bb5366fc2f50c2082556abda2695bd8b46de24624b11b3f275265c441e946c0b4e37981a4b2229db4b1b04f37fd716e2b54e345c12b231f201ac546386a72d0d2657f5ff3149e6d2981dd87c9bb1e2f067e79935ad015130ffb2186e93fab5be37f141a04ad649ced8f1bd1a5c745a28df4fbf9da9d7650c3cec51980f5bb0117c0c5835eac133f0fb570c86baada7b5d8b6c68fabf9f0c9b76580b512ee9b0d265cefd838bb7d6caa92d7487574d6d4d710e5a6edb453fb3d6227d8eb469539911bc8273524b48957eb32bac6898dc09e8538ea3a0508c860ff7e61580c5a8d146238ea6620be7b435d10093e184ae98228300f9b0ec5eb388953ffd45392dfbff64cff7ebd2f62ef5b4adff8a2dfe16d8d97481ef00ae4cded00e75c6dca982df4c06e703dd6c42ce47fa61cf576cdf11752496003331985b032de9cd03168559d483101a48f4e3febb92bff1ca9a07ffb6e0f9682b346316b567abfbad857e5ee520fa659536959d7082ebfdb86c92ca2189dd74ca92b9af4bba9b989a7cd218cfb3bd58f4cc9cdbf59f42ccfd9f86fb7f68e319753fcc1d2863e730f0f8e0f51ed12b991c8f734b440d7de3fde744d49d1c3e403dd5f5f2a845e157263b514ae72d16bf9ad5634b80f9ef434d9e35c3065057f23cac769f29e2ffbcad8ad08db5b0dd3baa828e035240a5498a87180be4f3afc748da484a877085ff2b2e74580cad830a9e3b98fa6b9db91e902ec2ddde406e1c8e3bacb333be8b6b5e83f81ef20e3bef0a8ffe7da5b0d127c67e64c0e0498f2e117f53e7dc1e052f181b9c8e2320063acf49d8db7645b5222b4a255c22c7ccd050a0c246c9c1512eb6830fe3d93fc820fb3edbc8a6482ee06989dc344489a54ed242cacf6dbe0ce21ec394ee7662dcdfde16c178a890e0f58d6466dd2244881beb22017d0a915a1df3ac4c78d8b67f50748b3937b939be6c36ece06c7908a8fbd9a444da6dc496f3b8acdadd2cfbce80a78e2f4bc1df3aed9eb195aeb01a01714a2c15b28b20460961303a44721b10cb8583f7f5 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 28caff24db8e2a6bf1092964f197ee98fedf2727c8b289e6a5068edd27670d26b91a93332157ac697fd5e246e6ec0f71b18eb51923c5996743cd1e4f3ae3e0cd6791afbd5f77a6d9925e3ec655533a2ea8d14cb2589399ecfe8f7ba89bb7d6cd2d7336edeeb7b63b98f26a49d356578cf7f75ee67678de482e1bb3d85b88325bae0b0dcfd1288c34078d73965442b7b1417d5f0fb76ee4dd92121fc400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313f8fd51836a2eceb0f38afe00545f802b417aa4d6e564f0b4e7efbd3fe0d05a771cece64ae5d932ea40a886d51838f36153b4e27e5edb14530467f1e89a60adedd66227704b8ab991e8a0692ff26bc59944cd814c847a1865c19df4b7fa13ba3ef95543f7f4ef854ccb28bc1db49b76ceaca3649f848bc6f33ce39aa79197543c638f38adb755f4da6bd77e30772b4791bf8c9f1544a4e9860e875e69cecdd9dcdcf17451434c7c53f3a9be3984982db1b80a836ba4c531d49bad26d77fadf03daef0c33f39cea972455bd8a60ed912443ca75b913df98dbe29c3322e57e156311f67354e4e4aa14e833f8454aca5b3898b3572f8e9fb2c4cada43c9d5e91d6f7aed803e1cf77ccaf0c478686952f7ea8a8173d0d2f3b0456fb97cd4ea8cfe8a145e9b90cbe3be8c32b276f90d349acbb63637d6dcd54aad0497a058ab0138a8e57e5e4d5d431053e84bd2ad7b77c3299ba6c7205938eca840303eb1d6d5a942b73776aeac11c40d81988e6ace507a7e9aa769b606e8052e5f90d84714ca57418366c15b74da4e98df96abdd19884ec27d3f7978c4de7fb495f8789e7e48f16c23ef8bcd1f353cc4a76e8cf38afced3542430105f9acd46926884e90566e3312ea6a9283de0fdfedadb7de23a4d142bd787539b692edb498fa51f95403865becfad6e2d8aec1f534fa3366bc1ab387eb867477b92f01cdd0a6e5bfddee38137cedf4d98ad57894ff74982e7eba2eca6a005d3cdc9c89bc6a44bd84fd8c6fbb5d84332faa831efa7322599460f8d293da8aa866f93cf4e47de64c4f465889ec11f17d3d906a82546c7609ef85c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce87df04f758e71f4544ee3d2365a9169dff75f9d998cedb15e650aee33a291c870315e7b7cf9cf10670d2dc5c8889aab85e8b4dc86d87ef5c52acc4db175a5967e18f983c3a4443b348d3a326eab35dd4b7a789778c8414a8aa8d8e9468ebc28b68afe5333f7e666d44b5a961533281cdd21bd3b24e2aa51ba58f2f45767a67f2e918b1204656a2b44ce628a3a95ef5f918999a73e1cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87c7d9353a77743949287e47938f73f21fb5e628e67a67e5157b49ced69a25aff03a08730fdd7b7bae4bad136cfa969dfa68c28a04dc9763872fdeb05e4e61489bce1f473d4dcd67a96f58f6b664d2436d4866e66cd6d467887f9b9743a06d7d347ee4e47bfa2964c229ae8eb63fcc4c78e3dfb841e60c3baa59978234a06fc95aaaeabec11f3230ac33bdc48a455f40394fbd6158c669ff8f20bb5501984c5d3992594a9239ed3799de78702b86973350724abfcd15255f0a5efb7783d909031ed02c52a203de570873c7a7c556202d53a6c086899802bdc877bc6a813ab59b781bb95f4fca9ee76028aecb9142a992dd7180bc1c15dbebb66765c5abbcc5ebf764d5234d89a378d5925fbaf63a00e35d568804b973450a045e55c7c5f4907fee390fe6877963e386bc20cbe929c3d247611e346eae401acb972843dc204eeabb043644eea29ba2c1a160b98f0d28caf0677ab2aba362b7bfadaca4e1197f54f03ac8033814a71e1cf407972b3f1d9a986637a972b46d3ac46509c053efbcb9a475bc4055265961c79e1374c2159bd2409a84f22755a1b32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f02270bbb19508e903888aca4bab72e332285837b9ebb466e5cba74d5ab6bb3b2a0fa26209a97f959c905bb4b058ba8abf30a5a6c190a018a9803ac29d84ba710b30da9a0844cc1a1478c289c32737144812355e0d7589b9ab765ca3b23353a350876f05081f3e4b14d8f66c998b81f458a394cc68c3b7bfd37366ec93113db928e5f9bf0e9aaaeafc619e332a7ef3898a66020dfc64f671879691c023409b53686770f8148a2b6f7b62b6aa42981ea0cea7753599585034b9ad99c9ac8b12872b1a47a088bd8afca2d42093928a4fb770198c4cc50b0214c4c94fc7b62b5e636423c6adb553b138591f6372ca6d53343ff7c70782a2ddc4801b262f220a539181c13f3c3e8e0a0d7191a43a54ab008d326df803fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdad2199bfa332b8c22c136350adb9553e3643d0c45413782f3bc9e941965dc051df98738cf50113ab422e4a22759ca016bea6fcba390ed64540112842f5b1373a2847107a43403b4aa5ccae154b9c54831e3911239b79f1fe997bae30a542560fe6647a2e7c4916097fd484c3d040456ea2bf8b63dbcdcc8577b7aed99c05fa28d468272876b614045095e918600f7c94bb0944f62235c169b58789ae8bc3e6f677ca8d238602399e307553e235d11836be120b3bac41b0a668e0841ab11f49e27aabdfc27afcaabbf542911b6a220cdd626d819c44c72556a3946df86c43d1b8693944d399a3b5b1309b9780e34330ca387cde8e4c9b2d0775a962f447828d6295873cc1629777fd93c062098b6149a3e7c383e2c33cc3fe7730537416fc1adb6c09f4caa736e4c796d2a97fa3807c9eab72993b4b876136b856c7bc75ad054288ef491effa872247a99aa39a9c2b7602027d65a169317cafcbb77c37d89ed32489e3c2557998a06689b06ab96615bb5752d439da446354cb0640686aa794444a806c31d721b8c6b820810a5afc00932a885107b5f968b5c8ec98207293d8851892a01dfae4a99832326e3863bcda75190c4a487b46e3914b702017b1b520ccc30a5c475fb2da94ea217f76556bfee825076533973bad3ac7305b5c764cd040d723617090af4a7811e9ab206c6a331a647d9385a5e7d8bad6c89b390b617018c4a0691d262429bba173598b37d7c245452853506437e756a399670ad8e292b0d820e3567047c82870e82236389d99d678cd9b49526aac30d1b830b12f4e62407a59c8f88b7b5d088a2d08b9f114c3f158650f32c682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b32735fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +ciphertext = c1a71212d3e37d620f58b896a7d06bb05b206b6d84c0ed4b08a5c55d1579cebee866e8f58273b10eb698f9769ecf270ad900ee8871d8c89ae01c90228f57eb877f7f6ca888369ebbfe2efd2509ccef519f80b678d33c6f63cebe6e003e9f63d36dcee6e76663677ecf437d59b71e8fe106477a92bcea414662a647be78bcc02c65836f83e0111d4e2eab9b14f5de6b940663ae6edc3cae8bc090116b84ea78ec7e8bff76d91e735280eac3d40556d4389d2a7c39720118dafe3c8a8db614905e620b7b1abebc1a0b17590a25e30cf46abee0c4cf1c498a1c81a68e22165c76e857b9f6fdf4a2a4e3414ed47afc180351dc441c8b3d534703cf2f36f630b1416c12557115dbbf5f0ef3575b0115a9121749a061e2b674d0336e3ba496aa54f376bf594786d5d6de95e27e0615b67f6c318be228f1e89afc8ec7589627abe3e024224b85d9b11542411267ae956a6057ae955ec9ef8848c9a300ef227fc0569531d233713d83ab84afda6481a7ac32b4460ac0df8611384c6e9104048f7fa8f5d6c0bc9b55f52cc0e733ed6b21efa1067bc86311e929e991ed38e5ebd2acfe72964180e775e4abcde3106bdc514f8c47bdf872ae256346dfd90b9109e27f4eceef8ca436c868aa56a9ee277f8152e10658e8643326e3b619d0222f3fcc3ac878073f1ec5db29bac0da0c55e1ae7d818083f3fc071500ad6aad2e84dbf363664b4b54c88cb4598121e45d86367e215bc6a436d864e6431aff34b79c4e6617e9ce5599189494b9cfe0b87d34727c2839b6756434ac84e83e0281dbd8048d2b1b19f831faa198528245f77a102e1b0bdc93649219cace43d961cd86eca2fa1c77b65f2e5cdd785fc5ab7c237d8fd1181e598c4b8147dfc597df9dd6855eebb3685d21c82e9e80707c65c2f84cffb4f44abc15d563ac82e8fb46be179c01318d112c36608db929260c27c280b5e3ab11901de1e15f41dbcc578ffee9a1bed3f31ed3ac49527c442ff392044c98e6805a82fec28f69904e9dd99eda5a473590172478c1d637c12b949a7f6639a86fd8548e2c06fd9b1861c64cf9f9f3a0ad913a077cdd0305227e50f2e38bd7bb726ff7408907f71e68427976104de4d2df0e8e21f4cc601ea968f51a933383f28776d0abe02b5680562c15883b6ebd2fd5a6db063546e13c47036a657bd80b9dd917227a52f5b00b66091dde66f950617c9ebe73a0d464506bb3bf89d6801f8803e770e424a12500ddf6b8fbd45c533a99ef70c42788d4660eb5968cda54df25a994bd2c92aa5ecf72282bfee5c376a2391deab3090b292dd574e630859e7c2a866ec9c557558bad78b236460c05e0fae86b9b0e960974b340ed31ea35ca171308bf54d40000adc56d8b4ee6d10c238c5390dfdfa034e28609e95ae09d4f431c5b96232ae85c537742b3068a4059d3e8894c41dec04d87901fd25a78015c845c858ff75d15cb8c1de7ead6f1487d2fa582156a24d254b6633b7a027c61c2cab286ea16dd9d1799c606cf4102d6455740868fca9ef583 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2f766ad79ad112b8cd4cff8dd0f589873553c01e4f1acf71a06ea32cbc85c71975ba2ef37bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab57f9d02abc5ecd730913fc721f54062f575d663c8a7e4aa7a456420e44d8cfbc114ec03d5a56e08cc7e5663c0105ff5087f88bb8cbfcbfeb4a9ae9c055691e05c22f94c62c3cc2b6a9c156efa4eb2bb9d95b8c9d5a6395dd5af88bd38d3edd9fbaf66dfd7088b3cc7ab56ff3366fbd595b3c89db5497b34b94a72e8e53fa13b40be96b523e5ca5effbe48f8c3556843545c47c0f54266a802a44bee6e5a19a4464734ffc6aaa4cf58fe8ee3c99247564c65fc93ed589ea8bb2c637bcf7277d5c5d58de8d342815b2e8864b4c43d920b8fec76b4a7bb893e1de8278f47f84743223a67f2983ac8c5ae845b6e25977db02e6d53dae81ba5cebcdad5b7bffa27c59c1e4e38da723b787baff36d7ee3ced5039183bffea6ab3bc779efff73326b327e4f517b6c6ed8c7f96c6330d4c39e4dfa7b81a538693329abbbb5947b068c3cf7b45c174ceba9964c86ee9ed0bf64e20ace911dfe84353e1a51af128e5f75414815999ee00475654ab30b9693ad507b2e19acb7fe6b14f27c09c7bf570b861926683a295d1473ec2d7cb8c0d1da25d073d3c067ab819b9dc27971825ae21dcfe50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d9079571abf37238c1f94ed07c79d186949c600c6f587ac0d81c8334c57fe0c59db4ef815d63c26d7fdfdd7583636e644d99327a334ea5b4d572fdcda39ca717dfbb894a50bc4cc84d76f1b615d9dac77ecaa39b9779a3696749ce83933ec7dc1e85bb2dc3421ae9a0f04dac2d83a1fbce6c6dccb0aa16aff9a94bb7eef5665c3001b845e80fdf7d9da3db636951bd836cbdd8da33500fe47fd4b8edf1ef68c62974bbedfa6d4bf26709e8e2046df4ce883187683f13da29bef9912d83ce26730438b0dd0d42998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913ecf61c6f74464b656bcb645f87b0cf55e2af443959e67c47d679021cf905d45e21da586ef8f91085a8a53fac6afaac5a4d81ec298dc23e75779b8635fc8eae58982258759999a57c7d4a5b14d246df82a9b6c9cbca838399523f2669606d389ae4ff661f783ae65a0c25b7258674398839af2886677e329109a58e579c026549f0c7d41dbb6623665fbcaafedf4ec04366353269e2366ab1364b5a326fc4b9cfa1458daa6cfe65588b8d26ea96839ecabf66a4e277f2f87977dab7807a2c65a26a9cbd339bac1bf4e6b46e0b8d82be95bb7b4eb1b8b670ee4ed5eaf994a06a6414e9abe3aeb609cf9c94b846013adfcbd6959ee4e1d9ddc70b3f559c68c74d94b2aa7d7b9d9755e3c69ac40782e98aef904a32db8f4c7459b59b174a9fbb6b41947f47b3361d5558d93eb2b444818ffa4c17f4bfcf8b9c7ce451f4ca99885ce3f86cf4d3cc4741df567a54ab0583a175759fd8ee97f41dda3a7e7bfd9c768248518e5d791cd84dba795e85388dcb2e507bc669ff0b906b05e6f39cd4dc838d0d1357378be601887ae2bda0c459dd38a871910c695d6dd08e5a5a30e92dbf312758b73beb83625df3b8d5c47a7a334d4e140915ca1401d461d7052e9ff05f73a1598dc9622c324c1c8b5de9b0386ea3cd95b86d80085588ac69ae310be6b5b5379202f4f14878fbb5508907b99490e4191b1e13a6890a9209f0a12910a3e096747eba94a337af9e609da4e8a9f8003633ec099983b8e778ca3d72bca1c19b4fb4a0faa4459ea06782367580b7aa49ab74b60c4cef7ab3bb9ba081227a7e1ac2f5400f8f7395f96567403b2401a2abb0b70e92e6ca2102c597f496cc8881d7b688861c7988363112155b5b88271072a7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be3907d15852fced4675547796d3046535390d44580c24bcc3d67a50cfa2ad8936d46121a7f60179be7aad0746e8a2c8cae124d27181a374493da6a68d47387a44460b39a45b2619f1d29b08ba4495230470b87bb926279eb760b9041632317c4d7a19e7753458dac07eb73331d808ce318555e1a2828da2f1d101cdc9b8363990b85064f63226c36c71061444e17a28c3b56332bab4bec2602f5c31394c870dd21030997564de52602c2628c41cb7ac2388ef35371f870a21675ac522660268a1802a2e4ca4c7152a9776410910175fd08c5e0307f4c2a61c877abbd2185ce58738fda15335aba2c77a804f94077a777fb49854c7a78462263e435a1d7b4a5205ab879438a91eb60397704cd937e66c7310625a6276182d86894ef9750f1817d85709bc578092d3b65f5c84514361264909dc2147ae6f3a577097e64bbb2c679c845d827b1ac393497575e385bb39563e125c3a3925a21160201897072f03f45d6ba85db7eb1d5b8ec7111dd785ebde07056653507e967385945389493b95c0a95827583f01dcd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa1323a34432b72c7b68f658868a2ae87306109b1053ed2bcedcb7037ab72d8c2bf48d29a0822575cc91ca1e5698286c9b19a7471a5b652f6a900659df9183c76417f0fc89d743aa635791d588cae6f650f3d314d65a6ae81a935f38b964f290be7a1a75f256776f17383f9bb9f9203415622b60b2a152a7ce3420cb49c3592ab8aaec009a237a12c2c04abaa08a382622dc84a053c94881664a97381ab88ca41846e82c02e00c6033b4721db29b71fd29069297a2cc387f2aa5336816c66e75b594bcd144171c3f7ac6df8a9a10a71f35b39a3da7d53571cb33860315288c2f7843e855d27db6f27b38940f973b2b063eba12b3a8b73d46c6781ac87f44c91e982cb27e534161212b367ab74a318b0f41e7a060823f17814f9a6e4f5a9093a6379fb0291d99916b15abc596550f152bc79703f1b0393b720cb85a510d4c9557acf3e620cf994c0bf8c06c2606041e7c3ce6044879a7612c3a2fa587b1b7676b956291a7ba5a78527a163ae08696c7c881076189bc1623c8d360c8d85c287a9c0c6965d0fa315e2037eed604084416fe31b2f01c7678311ada765acd7f70de59a9a85a8249205c78cac786aac9a0a0a7352b18f9cf936165a9c39d99aac7c175a5025f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aa9c205c1507a8f40512a45cebfb2b39f3330a962ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a564c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +ciphertext = 8111151e8888872490f4154b113ec0c4ebf57a28a670a85c362c7db91f1024cf7b6ac8030cee1081be1531a8af52275a3b94cd0647a949a6211ed50b0b362a034bcb17829dd73864bfe5ca9b2364ae0fd13e9824f8fab68922e937d2103a74e170c6829446e2fab2b7149bf2bbacfa817a68803e6b70a17f7dc65401f6a6813410887e4e8a784bd2d1f492c0052152cebacb091795ca0ee732486c992be11867f70789385adf6c0d82fcaa8eaafeaf706fa6434df3896d859e07d94cc83ca41e691cbc8cdb5f49222d2e883e9c900362476632b102761aa641dbe498c090b39789e88808dbb3ebb7fb7ee3389401e754a812766f7b8525411af6575036714a2be871754442b958601c1b2318b2d381ea5c852b31e1fa7c8db120482048181aa13014c361baabff04cd155e23c16496aa62a65e0ab8eb1cfb2b594f1714ca530f7893e89a3192ed2db714568e04d64fc8358f0735bdbf58570e179492365c1e1316be77c0b2e2ba15f5481c16db022bb314e3ff0593a3159d28ffe314fde190ebbb779590e29ad69136f695750a7d5948132b4e1871ea2ebae888942ac10f3d3c7a6960bdca579b43f2c258254e6ca45211f37e6cc324c646a51cff077271b959c7d39334e1617afe1c6bc54d0da480a5ed7b175d4bca69d97aebf3b9e399b1c498f985f2224f00845a8d78ead7b81ba0c324c5479b430fd8c4ca9c63e2acce7252c1b3530456a572ac3be23291437f1d11abcbe67a8df9ebcd22019b2d54cc3a939c5c72dbfbec61780b3a47481677c069197529c0f436e5b94abb7a731e6bc0622739eb6a9f9e3716c1ae50850d9f104e1193a9d3b05c2fef5736a5078e45b233c4bf9f85521f4b8a663b7a1fd63faae4825a47c0bbc2ce5fec7d492019c7315ea6145e53a91057c0c7245cad154ba809d6d18660cd9195273a83170c9add780de366a4e6bcd3fa5cddb4f84ba8d638b2318649417dcbed7936397e1850ada27b7ae967e6fb1b7a62721e8e70bff0d0de1959ec2978943feae4efe55bcb5de33ab5b71d6cbbeeac12af32c353e34bf53fbc05e1a7cb431a808260153cedeaf20da4a087b69fef49b05a8eec70d85cde26b8313eefff1a458d8d155233a54d025f013aa6cd0cd3d54a714e19fc5fe22aec2557c465144eb9315e2f1b1534678196d98c2991487c29ab085d363bac01f32d77a8d9d1ec055fab8cbbd68c8351a7e62bc76b860fb7829ef3e19c123e60991046305afc39fca4fa79040c7a22be2599749a7fe847992a7a588f8df9407e3692a34a52a9348e3bc5ec05120d5f0541083893eea1f967dfc45ccf4951f613c87dbd9cb3758f4ed4a46af79a11d9167fc931f13bf9356249fc2e3342bbfe977938518d6f807a7c62807e87a4dd6df7d3b205fe5f31898105b7a536aad8ee82018be1c3c331c4dde0b26d8b5c5c55e872f46565576088eec6ebdf37c8b0c36c98f9034ba52b98f225a69e0784a1ee452c2e318a098e634b824ea59ff3d57aa5b9000759cad7bd2a4db030c53906b44af0 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e34d73df336efa5a0d60ce8b6cbfc615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7f3e2f91d66d516be7278de5a665830f74e371bc411ba86f017d4dcd3c40c9ce295d6b52aca51ae4e73213f535af95bf09d7127eab1eeb54899a36961793ec47b91da7f5643664082c4375f4843b013eb815c8dffcb7f25d441429e746d5aad14093bf3ddd5df655f6a9e7baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd908ee740e57a59b971e4b4a0fba8ef49754a8cfbe0325c8bd6f3fd2a94a6cd4f26687f60ffcb64d85e67d63334e395df5ba4505495cbc8c3a3f4dab68796d6c646775339c29683a2109f2a7c6a79d39a95c876f783af7a636590848ed793b537d1a681cab559a8e7e050cccf88d3bf9b9dccd4d84743c96079e83b097d2979c9dca2b9d9ccf6e1de849976aa1466bf9eb36dffc64478c39945a9b40263de72cd7861c6adcc089a028d8f00208b3e4d7b3a91cc8c209c5e2efd1279bd1cab34126d7d1c0cf913d05d2f6d73d9424cf1176b8617cd4c10940ef9832957585ec45de986e50526faecb28884f659ea34ef5c48fcf24f383fabd9feee8aacba8edf21a6bcfcf6e2a67493c9e9fea16e70c18b79e6ad1e6e895177d7bcc7ca3547f78265e4aa0e5f5056d6013e53ba916bd1348e4c36b9800ff5f847b7383854f692450abdf8232ffbb4fd839d2b532077ee4da65be8cd5d73f9992e03836ca3a623d4de999a56fb00332d1ba8a26d599d0f5a97975814bf8efc9dbc537dec166ae31ca3c55d05ad5d7a53fff1299d396dcafd8bc6e3b97e72a595d294304bef9956edf74887fd1d7bb18da70bfc5bdd59cef6c1cb56f5994b80ff35dedab29e8cf3dc851f1aa5bf2caf5608fe5cd7ec5daa5e15d6a98a33e7224bc6de2bfc79353bc5c4cd46a8ad933a73419f7b117b88f3a53777143546ddf9015ee5e37c33770a8a9a11bc2f38777e51de32b9efa9859d8b4dfb87fc465b574d45e79453c0666e378fa895cf6965eafe35f86fcdb681cc5db260b4327b46c2d0699bedae03965b0a218902eb4680c1b8c3edbf011a396b0dca97d56aad34ee68fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6d00afd91e8b36fd3afc6c1d94a8338ad64dc8f53cab80d73e7dec397755f915c6e6d1fdbf9e94f663cc477cdb5dc94579d73ffd1b647ef4d358c5435d3d0799242b66818a683e8c5652bdb26ce4909f8656ff35cd7f0aed5998d74ffa32df093bcdb3faef3dd3825593b545b4429d787c4c8656d85cac293f6168e1ccb35eb14e3f45be722e1ae82f0948181fac68e3c9d41d85ea77946a54baa91c8ab8f8e4c5b9420617dc0b6d37bd0fa29218f018933a5ad3f14128da6dc760c2c9aceb4bea150546425da732664aa52bd2a82eb63759379a638bc0dd7ff9a7a84e17efdb8df00d6e894a8891dacc375d2fda36eda4f296a02845477ccd484fb5bc539c3b8bea3ed36eed481bedbe76c6417ffb68aea8e10db954057322dcd05f98f84e6f90a5e7f0e32b5f6cb6b992cce82d66a73c6de9572867640343f277e33b16d545d4b2be0aaff4d255d72c6e8424c2d5d23f0aa4c28094691ac4bf0f56a51ea4799810cfb024c151c35cc3c6cc90a41ab964370c2bc953a84a73c87a02813de34b933f233da28643a93388f944c033236372fa6e6aca085b598123f27122a40074a4af57684d46398e5d58b13a863b0b984e224a7ad52c1c4eb26909451dcf2a15dcb11ac4ca38d93ca350078138e0ae87f1390fc9045eea420260c913c6b54dd93495f31aac32350cd03500da308fd8ba0777c999cb4982c91e569a1c52396edc506ac7cc43264a05cc880191501860f1a32f7760ad3b17ff693508339fcfc05fae095c6a96c1e6864baf147186bc22dd882620e5a5f4516df92b8b715394c5677d0db913efb25459d6c636442a8ce22899f8943957bb2b281a8ed14bb5d0ce6de3086ea8b6165798619b2ecbfb22727cafc6409e23088c6c940c23e86a603788c07ba89d6badcef07d79174acf70c55b7b30c067bd8202a1a70998459c54384196f814515ec9c7f360061270090ef37ad32115242c2aadc0121e1a08623038b311982c669de3dbb1c7789530191b07a947c9637bfa241ed35aa1d03c81f0d70f8b95112a3b1b08b25c34dc7e1d577fd30a808ac574decbb51538c2a017287e62128f32afb0f7a73ec8831e6b975007592b5c652fa636c7315baa474f873a5da2e82fd146268dc951689ba83e046c0f4820447c3b3e6c78cd240bc4d21e0a4660eb1c69402b617b83057874122e203bd6313d7874a987f2987599cd4d7946e50665f7d9a80651cc8dbbbc4df605f48274fba0640f8609b6554a7760856259c32df00d3056aef65436a285583cfc9d9a644f66e382d4907c6d78aa461a2b6ba8887c238f81d31e796a675ee8b7a598afd5d79a0587965420a2e9f2782b71331737680a499aa759824d11acf1a001f9a5865b6568ed8a1f4f4cc38f74c24e231965e9830232924526baa377b2ee933a1fc4677ee74fd98a0881628315aa95085c7415a1a51a98406fa345a69802ba71cfc885816ea30fadea0232b13eafbc24b84347124bb41f8c663506665ce4c3801b09933c19675c1f9ce54c418207b69215c91b10451730de65a4aab6c97804ad33c50233f83599133510bb334d9c1f4b7970087700ef45500ccb31b7933fe74a346aea4c9bd409bc5a186f00bdca67cfa8d041dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e6e1a11fec0938a3a886e9b328a8a539557f6c700285693266742f779bbe2e7a0603060673c7be9591be19a57a0cac91cd1c61860a86356b90715886acac2306190cff686883a61e56140f64ba76123c1b07614ff5c8a4b402cdba738ab68b749c1151da62c30dfaa3bf826d4848c4910c9ea20669735cca4df583e0c5412b610bce816fd17ab9c203a7ea42081901c8cd78940f090efb49718ac90ad6a101093580c13b5ffa0ac0d7b094d913a9ddfab03f835f79173e966746c69a0228d06a2c363e94522ec68312cd312eccdc688c4a88f6a5b7c3464cb7ec842fc1377359a162032c8c504105461936714f451481d8a4942d1715b6a65583999b96b0c47a914f2f721f5ec6315c91b009e714f6518bfdc75e828256f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +ciphertext = b13cbbc323f152b23a9715d1e210086445587a3a62a216ec00b74c0026982b21e6c2fd63d059d5f001deb171703127d47928a6cd9cb5093c3e6dab85d8c36af2815563817e53ea71610b8ffe9f6d969f0515550a62a7712341fa7e3a98b4823bcf0c3a98ba7976cd5ff343aaf0e01872718010bf60f6c28ec3955539b117fe8c0b5e59021462f4f32e5253514d41a31436190b9b4cf0fa55647d71742893a7b83aad7caf98d5bd0394c8ae4ba6dc192288b69e0406fff2b0c61dad7f474e7a3bac1cd2dd2c96ec38521e0a3a37d807d554316d7f2f998d91389aaedc370845813833f147ad4494f7aa59899a9b23be3daec4d79038c746728021e6b341ce04c2904b323224a8eb48e6bc6f81bcd2b3484c5921e2e6c243e1d2b66593144c350ec5ecd7a5939527bcffed92ae72d7e1c71aee263bcbdb50e5bf91b276b3fd2582a8533c4d2088d7d079d821b5f5b25775d60b6512b8fe64d677a67118656ac602b0033661f6fed92237c6a078f037c3ec19fc4a9d8f0a31b9ae80a3e060868b2af0011ee08afffcd0b62c17d91d96c5eb13edc7adb97b6a245d34585094541b138de269f38ad87a3edf3062a24d551d239fd5c409b038b45581fa8529f64859cd5091094e9639f18bfc422190356b6d8bb92368fde8c670d053aff96539ff179e7c8e1385e328b070e9b1e40174d7344e2f552eee4eec8ce9b6e81ba9f67782cbaf0d187caf801d0fd4cc66e88139698eef60638763f90c24f5d072f6895f1d04243b4ffa6fb106d6db627b5e0fddf2452b383f76020ac14be23977a17617666bdaef26bf60ea597407ece5668f334290edb4abf51baddab112fc9486ca90048bdef3bb79a18bc6ce4d7ad1abaae3e593115ffbbdfede454943370a7a5f58a47930f82fa7999a8016028fdd906be7bbf4a21bf4f4851278515d3d18ebac857326aef3273a82a7a78538f9c4a0365acbc61a0cecbaeffb5f66efad5d47b78a690a7aad41fc8c9787af7c09f4a5fb38def3eddee45eceeaff670315cdcbb174b4fa5f0a5bbd7e2d8d65f0b0862e141a9cf6350e6611cbc5ee2ac10d1ec3debafc912627aea0607c4510f9ae4d8ab076c84546a0e76309057fc66e4813bde218346a4fff9e026446dccb73225308605a2ba9b552db468f43f22d81b305bd255f59e4fc62a7e5e0c559b839e2be1a875826fc22dfb4f57eec3bc7cc45064d7438f2b11ddbd319c9405a5479ddaf567c0e6ac8e8361350ccae87e5b2219b6383bb16be9aaebec1df4f736ada17e663afd9f65d68aeadaa66d74b4f8828b14f33466d6ac3173d6c290608d449b493d6f45f9afb00fde8e10007b367596db43f5a931fc83c3e8f5cb3aa218c25b76ccbeeedc17bb1b08f0ee9ee08e380d663b482d39cfdf5167a2b862a65107471852df5f50591212b42fd3942940f5e8a8693d107306ac7b21e4562fa2413b08375c92b1d73476d6d67cca6ac3776de360d3da5d330f2e0ff9df91df9503162d5723fb1bbe2edb8e04a21dba70bd868d403a2c42bdc11 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 232dbfa6a447dc6de3ed68e1b45742b6e95c723a358525e8e05beb619c5607944c342aeaca5cdeb297bfe3a9dd514aba3df3d867d646cd76a1ed1e76f1e84ee617d4b1ed4367ef7ed003f2bb04f42205f9a05e67435b88095eb48df7e7e41aeb56387d470581580ebc2c8dc55f33b3c30f44e1ef7ffcf43c457a36751dda4404b4157cbefa05c5506dd21694d59939a3aa088dbcae3be66d47df55dafe33c8742abb0cf48e0b2cf4e97e9eecf4eec4b3f54836b4e45b4eebbb43d398a813bccc0d4fcc4e43705084dc892b657765b2529438973f5e3f4c45887452847aa315ba8c811b39254a5c3ee64f668f3fcf2a92e3198d2a9ef89f1fe530aa4cbe3edfab05e19449fe25e755d778a02dae45fff471668eeab9397a0f9b3def26bd0f5e43c23a815c85829775f1d63bc74d8b42ba5f80cdc77de45f862896ff44d475f49ac204c87d2647414a5ae36a094b7fc9f3bfd3496b187592f8eb8168bdffd952306dbc3715ffc579cb3f7a398dd677ba14a3fdbef48057a59a58531b8aef1773735a2761262db0322e390c06f5d479f7cec7c7d00ab13ecfba6455f36bc68642ec9659d7bba40aa692d4d794bc4bf6fe3fbc6e7e711a54be8f5329ac6a9bffa88a54a601cdcd6754b4a3accadb397cacffaf41463c016efd6e2d6d011baf6d833e4abb8dfbf736e08d36278a8125389c3b9994098e760bce50967464493f42de5f358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0ebdedebfe3302677fb73c493a349704333279bf01b6baa8315731a348ded37f83dbaa05e057c26c35d68b5f52f27e5338ae543895dfa4c395fa9d9b8cef83b55db7183d292d3fdcffca0532eb14849aa5f94888e2a3fd33cab3b48df8093742247ac281efe8d7a6b880f983dfba4370e677679568b8d51935e33fbf6550dd3e8e387c3e3176ec9c3cad6a739c6ba5b72fa58801ddca9fd6eeb0d3cd05970653bdf409fb8bd4aa1571bd2cbcfed2cdda9937a499943ce285b32706589c11cb66256e4456f9f5c755b4a09805dd5659127bdcf5466270a5cb73f8fdd0583e80eaa98d340965d6284b63a6f7b39d0c3efedc43e20e4bcb39b99d835e5e14e627fc540239dbe759ad6292fc26b85d46324ed9de8793b385f556a3a3f74bd8ac6ef6a3d4ac418fe09ffcd05e5beaeee7d2c87b9536ad84a7bd547389d08f548031beddb0e37d28dd39e18fc5583bc83695aff0898f8ee9e552d4582989556c9f4df35a00d5e8ab95cbb466b5ba0d8aef007a82a4f948719d2e84e52832365fdb79508b69e45484139b4342df8c391864b80f8d7b9dc8ddcd44640dea986986b81b6fd79aa95663d8ac157ef0add9a24ff4e4ee5522c1df6587d674d6e348fdb3bfdd539995bf0ff22b21026f961b56dba5382537edfa607372ebe317497b85307b61d99da62c9de4dd37246763dc6093af5f4cd0edfd081ba4ce2d6bbdc9695816d7022c590a1687005bd730a07ed6069dd1a7bfa5f5ec743dfcbbab8f6610d55f59ee288ad62da1696a238d8507aac327a9194c5c6d49c823567e00c158e60b845af953539a855d217c5a77599b1783f7488aa860ff3df73b837e4b8d20d6a8fd6b5b16d83690b34b6586039100e84215eddb39ad2d40ba9f80165623122a2c5faf3437ab0376894ce67397d32a67c3bfb9761850c1c68ad988348725c83a378143d504400f995157903b9d04ee43404ab2cc7c35b8e0e09cce4559945f5640450703f81c35ed332746162f7b8328f78bfc3359e7c1b4fcf06155fc745c70245ffec09eca957c8475c62b05bfff288a5e5a5c78206e48c3ef373658859c3d9636786980578c07b764641d6a87222224557d10436fc72b563883ecb0934e50b6ec89429d7792ec0bfcda416fc2ac323a58df3fbcdb6e023140478868055251b1c09fa023e240e109869c1d2967f598a529042d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f228083de6a04bdf58655c59bf57b107987b88cbc001e010b9c2458bdf138288190f955b62c7013dd5784c809a7b1a29f8c3c33f0311a555306327392ddd44ec8f72fd5893f56f58baf207f9ee98b7e31092f761c390763a8b57409c7c5c665a913e20c9b62a5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5e816ff841456261bf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36674194df1ac3f595a294c28d24c26e1b1b5af5b542e025a182868e1555442e0b0d064865ed5cc1665074e55aaad601779e591e1ed2ab07cc551437603d24ca743218fa846822b2857f871fa26834e0422746a6c7dad256bc0b4bfff21bd7309482d7669f8857543a0436140ec684c959d26f2f827a84b37534b7aa3bc0a08163689f01141b511e7d11a316d2aa7d73909e889dd000c20e38667da048278b5ee87188607b4210642f5c38866fac1549637c600c8be8c60c11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dc8070b5687f7c6a73225b9233685c6b703d33677998c24e40a72894193cca1c5acbe4a133d85a6912587ad4ad522214974cbb1f877e16164683021ea9c335d41b000cf52a3ed45b2d95b7e2d061b5213db4c6bc36d76df5db9ee6984d31bcb1f6757de7e51871f1ae7f388c5134956d3286a49bba39967889c9a424772bf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15df419f6ec22d15a95553831be379ed0489749c495e3b6b8e190049a8065dba8933fb21ba3a751cff289a2e2772b06a4687338ca88c0eef1488b848afa1041f4f9607eb18bc0650055803041b728f2f1922cd984d228096ff29e71f097921423cb82254c40a615240a2482a3f5f095f5b399a8f9addeb6b726f43e3af64d09038cafea26686caa2ce2194cba660edbb083f92dc2a51142bbc922958c86c62ce7a4b3a4c95240d72244a912c3c193485208cddc4514495b35863cfc6cb41fa721a78080fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c832000c1c337fc019f0aac04b2149a469420c15b2daf5281dba5dc3618e0135c043f139cc74b14e7451fc11328f06b73f124766403541131d94506628c30b7ba68564179faed9c9d2a20f3b61793a33a65e92b699a47fde974eecbace22690273a757da903a886778002d283a819cb1ea2d34b8462dcab57c85653e363629d9270738434ab1bb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +ciphertext = f4245573118edd0abc115298abb1c7c118cc0d6a4365febfec360b289f244e1971e472049c9cfcef5f27d6bb6ae106138e1b42573f8dcfe10e41c49857cf586c8e1fb88e14e4e96c51d7a3775b84c38dca2361c4cfb637caf53ccfe6789ff289c1771b68832d0b445b66453699e534d81bd7d9faf248fe49b5e1be19a5e49c837191aa8ab301cde1e69b49481a2788c1aa99eb974ae2dc0a8dfc94f14baf821ef4cecee893b1c296903412c48a4aee3b1eea76370961fde96f772fa1b20a3209299e2926f76605dbd256938a9069c2564ab418c5343cdfcec02ffb2bb5a422615fdbd12a661a067e38cd35b86af9e18537e3c1f041b601e1c305ab6712d6b42ee2248f985787701270a51b052e32a52a4d9db52f1f9a775b387b0c4dccf4b5efcaf4e25c522b515cca2ab912b2cf07b7c421747357109205530c9927a3c9b639c7c473a991459f7b3391c0392a63534b0f0e604a969b3da8c29969301d8be3ba068d9a2723a6277334bc651f906166d78366e632b686145a0afd0b940221a0057274fb16b7f74fe8674c2c59199ae2f296dbffff51082655c19928eaa3bddce0fb27e5d72af612c7484d715c61fe11bb9d8b17b741aeb3b14e501999764dffca386f683d07d1b1e72329c7da38b029a970cfb1a94ac74901e07d0ccd40225ded0a778870419a7c3b32ef6ef05b1419521006706916f7d7663f8603b62e7396e047e1fc78661d7d6346623ea28e80510ddddcf918e2b985180a1a1c58ee5d40bb0a287890c0344d3cde39fda5a8c64a4e4c906dbcca97b593918ebd9f70ab79412bdc4ecc3417eec3a26cd5854b479d623cceb9129c1ab490ec98418737e5501f1fe51299eddeb86655d702d85bed3c4ae44ce16395124706cd763c80af32464504fa0d267f6ee03990b57afa2fd3a8067cd5d34b92a753bf9f590b506e2e81862cd7bc617bba82027bb9f900b55c7fcdb11485904ee2df24ffd095fdd05c1eb5d2da47080a8d3ec103d5ea7d516e1fc59bfb4f76591e10ea9e047b082b9fbeda25fdff8a946acdab298ddab2df2cb3d9ee0a781685b3b47d97009324bec36e9ad95e615fedd28505b969004b5a49aa517eea6d20ad42af18a46361df1caf9d3663fe5bc9d043d407faba0515fed3b6a615b03ef11685e4657dfbc165f20df62644e62074b9d86606e736d362b855f31402f936a2cd8d5cb96e3c209b7862b2687f054306b106b3b92570ce066ae63de2b1523590c7fbc03fb516d17ce1e13ddcc692e15f2d262b87688b9334edc0b33bbe4113e608d16c7e34b23bd3e854ed1cea39cd2548edaf85e1ff413c2afbee72cbc9d6d91ea2e98e4a1afd06c44b419b5a6a75579d89917e828edbefef6aa33c26489d7cda35e9c781b7ef5e41601593c4536aacb5cda2d8b75655f5c807f1e555da5c1415076ab0dd8d925ccd8e9493ec4a8185670d335bc7e348d8e3af544b17beae9d910c3de0b9ad5111dac9e80caa2d9960f3808858cb7be6151b76530254e8966fdb2b27cef7b7b941ebf2716b +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 7934a9fabc835bf9a77bc8d7342f51dbbdd876e5500d2c59f07485ee0ebc9359e1a336acde65f7dd166476daed1aa558cd88cd7cde7ce189e958e851991867c15f5c957fa953c8b04a83de2e23fc6c26811cb86f3244f29f4caa2aeacd2e3c840e97b8f28d5b94d7317b08354bcab64887a4e6a98ffe9da7544562ceabbcce6489c6e8534119c9589c405d7a96df3f30094a459549b6f47d78f3ddefc918df049464b0a969eb84f419147c8b39b8065a769e5dda17cbf5df5ea699b69d54ba460d33ac6a69659178f9b7a578d1bf4bff786cef9963bfa6eadddfdf9a0cb1c159865a344a0e36879c67852d05dbca08a46f7fa4a71cd27def83de5bcb21a8d8f2635bd764d915c5485ac7d358dbd1798fb12acb4427cffb036d5874ffbd0da59a668d75136cbe164e8cca1ae1386aad43b5fe3c5ac97f36bc7f648809cf60643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc70d7318ae65e7ae657e0f77c1e683beccc956d973c86f4e95a7f4ff9275c1bafbb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab47d9d217dec2a943d5bfbb3d384a7e83a77949d5302be704cf49992077b1a0df14f3394717c9abaae73124dd4fe3f5edb797a30155d0d3aee4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9326fe705613705628458be5f5fb333087cb4b967a61a994cbefd5d4d19ceb8b6f898a03fcc454a57e264722897d5dd7ee33cf495ca857e2af34af6ec77083ba9b88d342d7cfdff8b7ed1f57b79cad028ee3a3238510c5683c3a8c396986ed49fb022fc16e34a7249691ea7a931c54d880ae731746c1f3855bc734e4fe3484d85b5e2586b6231b4bcf27831ea7b5717da815795f43f9db221fb235f5959faf53db86e92bdbe1d5ee6399e4dc5ecda15d98c3b4cdf89f07839f7738abb3f81d45aa0a9ca1d349a64e89f46c2c77712f7f1e1cc74db8ab7ea7b0e60a9dc0e45443c3dca656cd6a8897ac1d5bdb5eb02179936f04374554a52a9f710f2a70972479463af859736c2fe4359a474939ac3532bf90609dbc3896db5615abfb2ae3288e4c01048bb93c9725c7c3b0547921975766a97e29e5f9e4d8a090c36820ebdfec43f77cc679cd4a51f7dad5f204bff20acf63ec403ac7ccaba5ea8fce66c545abfce8734843f7507f4e77e68137967da765e5e4cf70ce79838839721bf3a14ca5f08517ed6b3a555cf6fd96e7736a583f4407f7aec9f1caa340d4bb788d63645dfbf6226f9dff9afc52df3bfee95caa7756f1884a0ddf63039c37f84e5e83d4908507c1b17a7308cb329e8f9c86953422b8b2f1786a4b86b98085e25533925867fa02bbf2ad845632f859ebdff3e1245ac3533d369f46316a3cc1ac58b4e638669f859557e71ded5dd7a76bf8e93901eb7f411e4175ac45e0b35109ac57be844c52e3ea7bb6da2403dff0e4558134fc03fdf0ec86af106836b3dba8071bb8e8574fe02d8100a8fe55f4b0dcb7f52154da2aea68c58bf03ade4b21a56274a7feccac7eee4ec4b26cbe2c973508fecdf4f6e80784d6ccd3c8c61e85451783526ff48583db1a1ca7972bd1766b914e835244bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d7c227ba5c64afd5c87e01c1ad12a294758f45804719dc7369950e9e6398bfcb60a7819585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586056201ffc3cbd92c3a42d6851ec064a89227b4d1551ca7af6b5b3e892b4e44571669412e4240a08c42551dcc50086389f9e0c0290956b5ac58844a84be308d0a5562b57b5cbc594ceae87910a13167f27ce63b822f201af5e9c33bca746ba7c5e8541fff17324228321c7a0ec976646a6b5615f80fb56351d319b31960aa8823426682a610652652994d4a78c25659b533f5b40e6236a6e704cd891502e9c2d1858ca64c94d3734ac0bbcab2db2f9e03450e721a38c82a4c26a487f006e1966fbf8063ab115e74f441837506559ba5b7266f62b17e4d959209b657193689a0354149880d08434fbc282713118d9daa89c52186ea918ce2c170d8380e45a32e9f710cd6f89daf91c9210b767d743f61655a9702051d7c8a46f17a681b136c0863cb62430d084d282099d1636c04d6b1ec212a74046d2d8108470123dd751db685a1a1fb3a3b2c216f51302fa13ad73b919a439d424a4ad9e12994d1963b3c0e0316739ce50a1a7c23d65acea61423a5792321a84ad2e1b3f5b595f11637eaca77fc753260e04cec9ccf55d70d4d567bb78749efd005c9525f6e921f0630c25cb9a129781b9b864b7556272d5b4164e340d9464bf192979a073384f6a5e52aa0b6b74d43faa5412c5914524974161afcd91660705659dca87ba482d67c8c1400b069e66a19905b331243701ac8261952c5b736b25290235669fbdcc254631294fa2e97c440d97a0211c35c2ff4b6009aa66e27cc09bc09307c7b3794a5d189892ea60b2b323e95057ff355114ab48613e2760e00baeb82b0a763067e216aab899e7ca06e195a5e92486ce8911bfd5c7d956318ac3b029436a9d88c56aae2a3dc7b382f2c5e7265a037a827761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abe42cfc463c2f1542ae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0ae91cec8235705805af096cbefd0cad6dc0bb5130907d64e76e4be957a117d121d66071598112ea7d02b9648cf53e57af9e7cc3c9803aab327d87c53e41cb9bbc42368d332e0a963c3385c18936ad7483a5f4292b625c844c2282f25af0c86984ddc09371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dbe147efc2a34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf0b12d7f5453e669be2d805dd6961454ba8b40c6efa961e53da19eea2243c998b504c8ab9eaa2db11b2f9b591990040954a1567074e69154ad6e618d0830d3b554fe4c99f48b51cf6609952cc9693acab000c335b98126b4b45a9f317f80a6049558fe9d855a026aefdc649d295387c530e075ccb32aaa202171c6f6907a4a2202a9c5fcf252d98328f12f927e31c596047140af9b177e0352b120954d00529a07d6b2bce5026a6d7cba01231a85ba39b1692694788c9215b69fcd111fdc8934a1ba24cc7890eb479aef01ff29161b0a7ad921bb72a8b495ffa74c62c880bf03f0bc175eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dcfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +ciphertext = 692da34419ae1d6ea887c5910ad9c1e027ca2717684d8cf8d73519be768bbe6844139f4e75a63b0251cc9842de4aef1473122681f288a19ce658cfb921114e619de23dabd7db3eb80befd83216eeee6639c589aae70ac2fb8f1b839e953a9070d287e498329e5748ac3cecdc3effdb7c75b860a64ef4a389262959b42070bdffeddbf1b41853cd7c5517a6dccbfcf74f392fa85ba62cce1dcf30a3ed8cf6608381a06051767b3f8b9e836c44c20bf54c4e174e1da9cdba988d049ae0f43f1eaf9ccfe4ad537de224db0d54efc313cdc8a16d356bbca595811f6991f80f94fbac41c45db49892ba56b20256c375b130d64a24fda9c9d796554923418dc18fb92f4e93df2ae2351c5a53566472f57e0e206d818e1d1128abf61f984ceea23df1697561fa48d0d6d5a0ff59f705297da6949955091dbb013c091d200f5856bdcb6166ecc42c36038588791f0b47dcf6dcc7a045487ba59b0075e3b53817bb8544e98a9b60a426ecdabc139792367d99e18611ac931680d59c876fe55954e3cb311c683f514520ce59cca491e3c4fc4b0f201d554f9b7667b19642639db4866c1242f0745d29383a2d009c844d2605e93e9c62d65e1d44b7030d3cc943bf0f291547f7a91f9edf37c3d0dbf1ef9d770e838f626e591e751ed64ce5b94e114cd443be38955a2ab79ce76f28800cea4cb662c1dfaef1985dbc955e09fe1156dd87d93701d05641e65127a96853ec478bd59ce855f28674db4f21188ee0572e3cf0840009c1029edad1dbc119ebb219a37f3407427c1dcb96b4f676979bd77ceebfdc0f89a8f0b759fd19787f3105c98d0797ac038d3989e1ded23fa49f3c9c580a5147d847a9f0048ee9d816176cdedc5c3bd97961687d59794dee37a2a9c7c4e6c8028b48976e944c8d45c7d7f637e50b25e4440263a67ef562e2baa5ec3c978ff8e6c390b57ff082c202272fa7e6bd4e482fb5fe7205dc56962d28d6f1ce85659299cd913938cd036268856b564a154af0e877fdad96ab0a185048cd1ea6b7dc8de79412378126be5d10ddfe4d5cdc027f183fbdd80cd9005250d72b5b2b8d824cb4512e1d15f85f68626ac262b4e169b8201ef197da7c208378a3c5d495de78bd780dbdf8e0f1b55811512fd78c1695f028f386d7bb591dd962b403da023977bb66c4145239e61730da1d91741237a65e686bd48fec1be0a6bda744a16db76f0c4622fca5d3dd2f87628deed85f8efd90f8778b2d9ff8a4150028b65aafc318571a8b954819c1c9bf0eaa2d1aeea6373213513696feb1eef11057106a76aaf501ad784326caf958c5c94bb473ad548b8db8dd508d44a667a420f7252d44e46148e76a9dbaaa766ab0578111ebc542aef2a85c0249893053ec5fc19c4fa0979227ca550e46367fd2e09d018cc894d9c24409b946f6464c54987a09b54a96bf5e672129b391b0aa95aab3903066324ade24b51dfaca8af884369f77dfdfb5e5923bb5a497e721f46a6332a6d6b822c25e581f4190080834b2e973263f22f8bd9708d7 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 46f47851efb9aa4a6d21aef5be5880610fc278b6f95da7a4ffe855525f9f17d83b359bf43f2a622f353eb6138cc648df8ad3340d7575e865a6cfd34bf473a3da8b9fca6ecd921452d09b320add41d77ef576c573b094f2725e60b99ea3380f68478d78f5464d7e5b84b3a3793f0c7cb3ada13df37b9763cfbf054c769bee66bdde8366b40635ef812c5d428853d1fddf7bd58a8e34827556ec1336c2ac6a39783a35d849aa9a847f3705dce0b95f617bc7aebf8c0506c16ea3ce89aaa28b9f52f1fff8d0fca732289d05d9395133a82d8cb76ecfd23934f73b39cb52b5a846f338b96c5b6f3acb41d7f65a0c5b13094232fd5943d58875ba7c2a6889f27ed7d325ad1c9eda0b3c9e8938e69d54d194bbb90f87e796856f9888e58a53feff84ffbfd5acaf59521e46ef449cdbebe8d5a1b4435d0761d0448d84fef01b5d6a0b0a498027fd05e88d7d87b42054680cda74a396d27aa4c3c5193fb1a893bfcf722d55ab9b94dd99cc81418e53b38334529f649eb99825bb4b1957326c4791a38ff952cdab6757ff494ec20c23926c3c331f24c360f8e978cf791f03e81c2c489b68c923b65d8ee6bd2e6ede6ae97fb87ebab50ebc1b4f935f38a0fd43ae2f9af4d8fc3f6e15c2c6bc800b73ccd8f9ec592452484b44e7bfa62498e0655f6182a5d349c78c7d68e80b1676b529eeb6065c50596232b9566e4b8f0635a7d729f7f8eb8572f6fd57996ddf66cfee2e47dc3451e96cd34d6b9145ccdd30d9e5d67becce3674073eff8bc4d75519ec9dbd306a59def5336e2108fd1b7b6ccc8980da28a3498e51130ddd5746feb163a36f0e6d610df1be1fb6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f65ed7ee6e6a300edecbbc840af66e747df79beaa71dea5318aa3cb3c4c63c4b9ee0fc6dd6dd6abf10bf5d2bd78dea4e3f2bdbfd99e6577c4cc9e1bdc3336f5a5fb705e94babced659f1ff23458652aae94012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f23adad01e4b918f9b442effde6e7089c8b9d97fb70e8df7d754d2b75d58347b56074ba33fc9e998e5a559d46622f5423808c82373e7767a32e487fae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abd0febe00c7bbc5b5b25a1ced8544f4123c98fb43d31853fd324bbc743d342224ba009e9849d65e1d08a77e07d07dfe6ce6f64fc71374eefb66bf9c742f5e8f2f3dc48008f752c8ec4ce7bf42593b990980da4d62f96a7178258f32efb90e96f41c04b7b54d57bf57d0a14db6c1bd8e4e8a6bf1dbeeef738f51ca9bebace9b95becc623704a7cf4560d9f48b4cdd0f4a5d8fd6320457670db92c7a437174359371dd22da4600c66f96d336a52e988898e8ca20f82d4767010a7abe08ebb686fd48b6be63da385d7c5cb145ed8edbd33996ddc171fa1bd563b22adbc7b94c9719a75bf3b3e02143bf04a7e3dabd070c4b449cb9595aea8bbf871e5a5e78bbcb611b466a8677905443ac0ae601a9664c5f54f36dcc1ddf35381f586b4aa4567ddfbe72de86df8493b3d479f4c72abfd49a6666e807be3fd77c3b73872209ef18b48984ef374baccd156f94e9eb92fff176a27197eb4ab0171211dc7fa954c652698c50105b5c2e9f7a2a887bfb40880f8624e1fc67b1b43a51139ac6025b9eeb60925d424bb82c58b4b617618c43c99b07fb14e5b86538d29700e1ccb4f53a52bda2ef566b20d8cce1d7616dc81398d14abd03964940c794e6100da994d5bc0bcf28b04a8971214e7ab9285515ef09a7b486ecae5c84655c9ee15255b715c3b784d9c243993171c604a3e29450728396e7572228610bb9ac04b06577b3636c137a24e2139b48db005553152c6b040cf0b2408248675eb90afb66d6105537a316c7c989746f43c3b284342e2cdb5f2183a16ce71ab39c67797112b0b907c00f6a47f17db08d924826d526cf88234a25676d82449f93b2859076978860e499a0de134a936e35f06a7802456008c23970818318aa2b55a1762a9394dda7a49ebb4b38469410f5945dba2801ac25ba39a2df819b0db194b53c4247fa5065ff99f73e71d51c22f51fc262dd2809ebcc6879b0d90004da5ba7cc9462f6c822ac8fac8ab95b769a465cd743ba2babb26958ab9c3494d329a0c736c28a9cf84f5c90c5a0594485a9b339212d01bf6910105d44109b09bd063b4f2f3b903c94dc650812ae5cc87527754d476ffa82f34f39b5462006029875712cfb1da648dabace5aa1590b5ccea82c20e74795c71bb70826ef4d0bba580a447693a42d8af3256c64ce327b370ce576b6343f2bf8fecc76e1434d5e448aa8a3b326584ddc56496704be54108f8572170c2bc39680598017641422bb81645959b8092e82a54c68aff60b78be78107e7bcacb241b09913461579b52aac5c6c8627cc033be2273580a523d4cb7979cb65d7056643856be187ddac112799559a87168aa96a18089a6c547e87da949c62b8ea876aa0192af409bfbc354f05dc08fed46904a2688fba59fb71b83031a19bc8a6350bba93552be0c01b73c89964563fe588a5b76971dacba69868b588bb2f9076532d6a8fb4316dda4c85c2945a2a29b6ead3900e50abef2b44375ac36bcb0e028a20cce58353c827f1d53a9a0510e3827cbd1383a6d18c0d22c374e2b6061c2197a6cb094ca9dcb42f0418c24a9cb893c45423447cd5eabb0b9b410c9144013543e5c3bad525377ce8073d4a5f4a22bb24874b7e21523cca731265572b487e3b42ae581a617437348c290f00ad09460aa0c7b6a1a53128e4e01b3c406a296cb35ca0bd0d1917dff42a4848ab3bc28a2a28044c719ccaac45c513ca007653bc854dbdb79181157aa17220153ca3563b21be77aceae06bcd02531ff5b7f5453db0119364dc4e97ac7a495287815b5eb512129643aac4f42b3af35afc1207db0a3194302fef097bae37bf382c154e78154b3407bbd90bb2143bc285af1ea0b1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83baf26ef19367724b1c989c39bcb4337deabf7d531fe2b3327f4ab0f6457c5f3869590c49664923993cb2b0103b8e8a41cc5793acd192a047972978a2ea1b9e354cb135f2ad8928574b2c14fbc1a4c02715292c9052b69ab2a8329c02938bfa0994c209f816a24eb13f4365af2d20240ef66f9bf6b39d54ab5d350c7cb3cd6f645379815aa3028232bc89bb89bfa2c62e351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d010e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +ciphertext = 6d7d3b4a4c4089566f5519cff32e125274f9706757ac5e10fd2e3b104025ff7aa64192ecfc2ffaa86e2f48c8afbfbc635b75ddc04d2867a39054d0c3489ebefb7297215a505e7f65d93115592d78a709195f9cdf6a3cd7a7cc1b9cef75aef9fb2bc05136c5c73714d6b078cd2ba88bbe9fb61302e1d0771520509b90163d1514bb510d2e2a0e4e4872e607f303ecd6b9d36bbd694c3ae905d7c9424b604be28ef2e985977a575d778e219dad4a16b0107cd68af5ade5fe9e3ca48910fd2b6545ab2a38fb9e7159ed97b1c8d3aa7b962e4eba2d75439a6846f9c7447685d8208934c6b9dc0a47103fc71ae6612b10d4c71beb667746e9ac680a2c750331d1d79a54b3e991aa7eea7ff896d98a63c7f499f646b349b695d74aa849a4268c450d72aa8f531784641282c7f58f207c085144a1bbb28b657e9dfeabc03ef0784fb4aca22a2fd0678ff1b365b987c170225c6785540ec2112a577c20151dbd47028e88bc2b45723c3b50edc0efc0bafc741c4b8208aeca01f2af5c223d5c6016676b09c8ffb64874616a2891031a3fcb2c4d21c073b5bf14b6e5e313bd252267ea4165b347793de3f4f93b9f269ea07a60548c9fb8560a49e544aff22017ceff150ef44b12dc013b6675c1b709d4f40808fa37a9352dff8d37acf1ac5f7e6a27673dc79e83cae6b1e69fe113155646cd1b6e87e2e9cf67c3f2d2576a2c47a6156caa33fc547f343c51a17932368e1290e0ba91e35482a70c7777eb45a482f261f77cd88dfc4ffdbab03e01740fac45457a6653059975519f2db38c9155a31bafd22c57c5212483bfc55ef9bec51be4860eb574bde711dda9825db976e39f535a7edfae6077e1e1644776fadff2f9e18e98eb238c7bdf35c9c1af1889f08d61f51227387c5b01d0434178b55aabbc1945c78cc4da30d4b799ca4da2228c410bd8d5d4a01a0a8b0530a61277c9db721946cc605d089fd944a8c8787aeaa9f3fc6026bff912cebb5b85923d25cce52e1372b5861957a39db748cf275c4530479b3f0d061ae44599fb392337b2e5f8cfe8a77c73dba4c9a77428e47abc6011cf37e86d8a748d2899bea405b2fe43172ac5361482b69c3b16afeac9f43016f3dd0191f627624e5faff4a92e1853b16f4635b41cc1b256f27f54930139c3b50d5b2126c86121ec72f7fd11d06f728412e309b9df172d2acd8f1f7c1a6c86629e3e0174023e3e73d01379327a59031829aa7d6acf01b22cd550b1fe31af06d91f43fa51cd5b6df75e6081c84875773b053c6e473b8cf1b13620633082a47f1610cd60e64da50902801f0077e65a0d4d2a5467e59d7e1b95b0eeb95db0642ff81c2cf6b76d42e6bdb58fbfc0730a55f81c2886160df921a8c04c6175008743796a4a67494cea3049b8ac89df062aabaab5c277bf1a81a61d4b42000b2fb55b027d9bb6d3e3e984ee595c6a76b66332b9554b38fdb0e93b77cfd9f891f25c7105fd2c1679a04ed526cfa6a26984e19d71b2b57ac3635f233dff02a799e9cdd565bedfca93d2ed66 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 8757f52c693a0d7cd6ab76d71b13517e1c45abb370d26aba3fc3e642ae70b365c5f6235d1fd688d81c72716a39225fdd228a7bd6aec48ff445c47489b91e6b7dae4d3ea78b20a7b5e579c5691e87a2aa8fca0d55761ed03fb9bead185ba9e7939f247bf1757ea66a4392095eaa0f39a3c67a8cb7d186047d9a7bd6b8887faf0eba8e55631abdd3934c88ddfbd5f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad07fee6f464fc443fd72e3c67140e5b1339512419b4daa8c87f5a8bff58e964a8ab8b2de94333df9527a10b6d4df6275e1ffe8fe54a57d7544402134ab788d2333897d4769ac33d93f9b951d735b5623452ca0f70a0896ed3b8ebf129ee451a4a67a4542556af79fe690a8f3610febfcff663878f7df93bcd894ac8c996be6e1af9df7dccd459b9de46acc9f8d43bc8fd01d4de5785845ff4b0ddc8e84afc5e52b7fe8a9d93669a9eb21da101bee5934ebdd416e2aabe955b1752810764e7b68d8a7d4a6154fadf78e08bbff9e406cd10b6527a39a6b56d68685b5e802cc25614492dbb6e06caf160e930733956e8bf9ab9a8ed4b477cd4eab880e56eb81eb278f540ad2d4a996b32fd06b8bfcb772976dcf61f5fe26f619906f95db6f8faf491ddefca3cff85902350d53cd649339f31ea3ab764b9080ebd657e94fb2738378ec1357db8d5ccb61dd74c5f666ffea7b0714c469c58d3117f35599c998349b5be7ab9e9dc6f01f9f85939392714e1ee2490f16c54ba77fee03b710978760ba6f319bab3c2fc67cdacfe9d5ce53a97e7826bc4c3d6c7445cd51b6ea06a2c87a22d7a20754e9d87f5ba1d77766871509ccc93f5a1fc2cf0690f630838d1f6c8ee903e9b932edf2ebfff0d9cf51ee4531c1f7c44b378da7add26f55de3285190cae3581efe436fecd1855252147d1abcb15834f2f65d91b5eaadea3e94d0adbe536343a38fc4a948c355984cd20a7ca454ba034ac7356bd2741ed7a71b39860ad2faa38d18ed7494fb510e65f6f79dbfb37f94fbb963a16d6e141ae82aaaf47029abdff6bd8e876eca3fd7312432cc37d0ec4c6a4b7d37c5c6e2efcfd99d54872a5884e28981d794c7855590f2fe464017c8724bc92e0b644df9fb5c8da573f641e4e65bd7fd396194d86d6a5a5076ff9cd6f41fc7f41d194b6d23ae6fa3c59ff6dc823d9ff7e39f9307fccb0696edc771a80cc5ffc74138ac9d01b95deff7f58bc555e4ef8cab6a73372337f0adb4aa0c7d13c3e2a83e3f8b63426c66774089d3822aa1acf4acf5ae30c4c68dd4dc47dd16eed0a4969e5ab630baa120adaa51133c6509c83f6d3425a385730aa0e08afbac0754358c812f483f5ca6bef41d5cce4cc3364fe16c6493f19880f693581e08999cef4db44b84970c8fa4f6784e5d614cdc9e626a31966acf823d9ea6a730ec5fd11663cf10b9da9fdeff40ee33a8edfcfb95cecc6b52cc08571cdd3e8315532b7c76c214db60f9d21a24734854b6a3d77cc0dd870164e0b84ffad5d9b04f75ef895ab5c0cf5f8cc9703bc67dc5eb5aedf4e683ae7feb1b4339335efaa44a64e8b4eb0bbe170bd1876ad6319cee68d4fe6ded946a59c6180da72779765c405485d51fb10cb0f150b9db466c53e070f5849049d225047bc47aa15f630a6d62c5b179906ee6c067fa3384a4c22748f984eb31ab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b261beb0eb4eebcb8548139bbd6a0a844ca1e4e59f3d7c4372ea8632b278a7e68b59032012c5518a8021bd5367557077c9c1b4a50944ea1a834bb61004b2cba7f6401a57839a3cb85b326449a25457851b4a2bba2e2187f040745fb608079c8b59d2b191813d51c5c3f329b1f5e40771e1b33f63ca400555ce5351cffca2ddd268d7855151618587c8b037e7ca290467e4a7c2c38290b84ab8dc4a839f57102dd559114092165b13b130b41bea2f857c84ae45c1734375a3ea91021014d29ac58f12bd5a44b91ce986e094a66089479dcac23a6275b864195df24f2d4a97f1b26b508c3a5bb89b9f0a913867c1294c252d5022d9fc60ffeb3ff3c29b2dd1aa97f22271c5c8e749cacea39f2c637ff4a235882747ceca1d95e093966462ad401510ec112026bf0fbc106270988b2c35cc7269da693a7d67052f9156d30c916ad6552eacaa3ac2396bc56668686ea8a1578e46658a71b4b7365ae56a263c783973c1b63100b1aff4c3feb64856a781334c6e83519e541511b4d581914c697ff31239dac56662a145316ac4d14e522480782c4ec52b1a2b8a85f657217ed11426a2a606c01c17171fd10824c07042b189225d40919aac5cbe05b031689b1ea61041f6091d961a8910a205e62ff21909c6b4095b270d87c9727a2b611118c84aac033ea9cab5f40efad6117f2160a56505fd775d3f415aae9271a9b2b1fd1964edfb772a9c4875f06826a49c26e93f0b1846e006468de71b98ac6fc0f81ab146236739c9a7b6c13952089d621936e8b265b50dd4016547a2abd52339daa0b459d265558a1d9b61c73e49346396b6155195c9c3a437614e68e23143f09fd28857aaea50aa808600f5c5ca33c5963cc00c4b1c1ce2609486ac4f1b2ddb7b06acb62398a32320f315dabcaf5d4a833e2a01a6e7c971ca15e40c459ef18db8452aabe1584412b4c4dc52e6004ca56b5f48555041cc828a7a6da77c435f05574e5c25efc3c6057443eb77993c987cac2363c3030d88e288f4d08966e624794078a39c53ecf273df178cb022a5fb025a2687409a785cd6c019f5761b0a3087ae91844a69c2a89c1a00b1caec7c1f7a67425b87be02d80b67ca6c7dc3b45bf425dfd33dc5a13e7531907ed6329593c333466d9628668b98422c985182f8c0952cbf5052225363398e516d23678b5320a9cca38e21c6be86822c4fcbb9094277bce80992858c5498c6bcc57db982c196b1a78c317975544ffdf33e57a30dd29a5ca4a22a918746fd9a84ee1008db920432e39b6ff182c930243cf350c6f486832a807a36c8a9242a5c39140eaa7a45bace0086a86fe36be28acec756b5e9a47225638659b250c52b564751ce8c42c39bd1046d2b6cda70b7951707b63073f0eb5ea3fc5229f816ebf4007ce97307c6607b4ca17ca30330570d4f39bf76998147060cc04b33d4b91294f85f4a717ef9c288e3741f70fa5823ab8329f56d9d0b05c996701a050a387362db09427d5587e7751131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e47c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +ciphertext = d1a47ec5e9df73d00ea6c31f8189070b3cdbafbd59d3561ff50a2961820739bbd40cd0dc9183f9dedf28da0dc608b7c0da800fa9ee2b44331062d972cfaf9a08a943f60e4cd3dfb6eee587cb152308ec9c772c566452fcf0e16745d5ea6854a2fd14812c4c08e065464a0d494df56861e6fe82fabb22e955825d303dab2abe42d094f0abe8f10b788a24f90180dc9434b163db2aa4d461566111e6817a92434a2427c365a05232fc31ece1d49463cc3667a92760480857c893a180bbb4b4afa50ca382e9e4cfe5cd3e3a424d5b927fc75387fe72f7e38c267fe94a9cbc12b64141b574c45d6aeccc7cd28ad9ff4563d5ecdba1dc19baa079940d6c71f18819180481fad6025ddb5254e7cf39cca79bbb190cb526c427d15551a9af18c003f92f35c8f8db6bbd27af8e6108f9827332d836dfb5299cf9af20d6cedf3f3bdd3c29d0c46350dc4bfa046ebd38125f4a5480e6543090c4b3ecfb11ae6b31c501d38ae00b21d4889c10d697207ece62b5dc607ed66997bce2a2c2aeb2db1e8e9346456b9bff2f40668d0ffeb8fd3909ef59b7bf2e23c81938502a702c4c531024fbd6265980b2f16c70fbadde02abe62a9e530ac31b2bfae08581146a2c47691c755cc4e08e35bff1acd79cd12dad150e308f0d421dda9539b3d142fa544dccbf9bef3441fb8dd08c21756fac0d4efe441ab6b8c1c21a5e7604914a3181a52ebafdb7de84b0b634cac7cf9c616d851f8a7c3a1e6d1e7362642cfd00870fbe15dbe0fb122ec58ab300e93c65462f8e9fe59be9a05919aefb568edf13e4bde5ecd0b5912b29a044e3f33477a35f925f32d1f52adb91620e8f667d5a55d428737b3fffb76439db79b74e7da3ead61f3c43a13e030cad345415ee18d7415ff6296ab1cd0d306058d3a785fb1cb27a18d245dacee17fe8a0e3aea3299f6d3c211be3165dde7caf805efab878de257a8051fd2650473e6d3ac4eb9233e38ce9452ad85862d3684d864220902358d35027451962ea11492038fcaf2ef3faf3cfd8cf77295e30b7dffaba171f48062e6b9213efd6d2feeaa688191626dbb2fcc89a0175ab32351e7c72005ebae83c13d59bbaf0d4a5f1030168de6a7c76c83943456867435b63fe864550dd99bf934703debf2192d6a1cc1a363e8933f1b5e176941b3189ad53f038423d90b9a2ec584ede715b903f1a9917358bc7616a6d5bfd20c73f98104bf1509aaf19960fa2145caf47915db32af854b2c75abccd0763d06c5977efd369ef5a55df1c3e13ffaebd2a9cf99ea1f75e796c3a6bf38de65fc10aaaf024946d1df9f429115139fd5564682773e5513f2c0ff6838a5e31197fb199284402274c10dc157da502a06a2c610822a1f970adebf555e5832767f21714033581699b1c01e554099a7ac9b31e890ea981cdbc917e063fc162c877c51358431d00875c4270160d54d93841535c582804e1b68bfe87877fc265ef906fb62331e4b7bbceaf9f12f255df44976e4e34e3f5fe186a21b2b411410c45deb34a64911bf410de13 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a33bd81d2579d7737a995ef6b05465963ac3d0fc3d471b94e31bf42699ae3ee7a306de87d947eaf3568d7bbabdc30ca69cee66abad7c67799dce7345b30f4ee41c5a6f35733deefefa29f56ddb744418f9c6c5faaa25b258bac8da5dccdeb4e0535bb3a44a46ebc44f587fcdad96596a8dc32a14916cf5c4a2fa853859ef7efaf70543abc4673450fd98edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca016552834eb4cce73bf17b4e7873a519ed16a1c55e4cbee807eb849274d04ed5e866656c126485979ce976dafdf46f2e315ef77edf243e660a5a78c663880a7f9765df454119f6a86acc7962878b4037cf2a6db07fd72367b476fbf4b8c57924a9c699815bbeb0bb10b2a88b0c63f027ec759d59ceb9ec5c043a41b8e55e56f325893685f18c5459adac3e5bf2c696c8f07727c19de1d45d2d075a70665ec55bdda721df7c52cbd83fb9dbd7567adafb6ec8d9c00838e57cfd9e0c5aad2f6f35e3ce57d3659d906452f4a8c61bf6f838a51f6789e43ddd580e4595a6cda12b796cb54f40a57f4c298abff1332bb0970a3ec475a434ec4ecfa4ab9fc43fff035a4499c66827c98fb542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0ccda0c3b86788459b659a539833629c1b585a23e34d766c9f9dd3282683abce486a934edd3a75123e9a7a5fb5eb7c5947b69ab5d9d4b258ea7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0ea8fa24d344ee9af2222ad2c65381552e7c453ac0ecd4bb209fdbaab94d920765c4bce5972aa79ba974f3c5d55efa7fe5bcb454f7ae71eec0184ffa20c73ebf27805416d687c6301e13b52a5f459c56bc8d87950453d2fdaef3931e43ec2c73278939826682126b65c7d9bac044ae6cc7ca4009fd90ff8470f4ed51895adb53ae312e6b1aba552fdce4ab277a883df9f3dc8d56794d842ba0687d808f2cd97787973b1ae4280c5fbcc45c103cf3822ad7eea6c3abb4b52bfee6f4b38e4b5dcfb859e77766495473e97bca3197b53ab73be72c163003c9ab8a8feeff925f56b59373f5abd153db083e419b1fba8074e628d78d712bbb74579c0a18a4cb2aa6edd76fd86d5fc09fe4a00aa44e486810f3ac6e3634553ec23f247f262ee2cb8a6c76444b1b5f77b7c68afd2c49d4b8efc5069b9b0d4cdf0587a5ae93d243bc5f16357e2bef2817d6b5ce6f9d8b3b6a68e5a1597c49076589d5303a5c89ae4fdcf614ff308e9ce0fd4b850870e807b4f2b6bf99aa8f40de6e95b3bedf247cdbdab048586116db7a463dc360cbf410bf964fe4ea5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e856ecbf9d6e94cfd9743cdabfcec1bba9baa05a8fd05637d26548f495e2f5477b94ddbd54f6674158b2f6fad48829eeb023a642be75cc689a303f6214793228138d6ead3bfe4466dca6ffd2a7c5720fcf3f96cf3a76e9d206e4ca063a35f4515c0473140b8ec3c53b1d99740226e6bdaf459bd3e502daafc96e990c1b97ea1ab5af0e8ead88ea68ad75cc59f4f9ea364bec33ed167638fda643c3a8119e4a49366af69b3cc25938e784f2832b7078c6be5635e3ee36487595e5e4cd4f7e395f02d56d41b5c5889bb6b2f149425a2ac8aa06ff23a82841887de199b56c91846392a026b50e87453f44588ee6ad4a443f54d25ecae39aaf286efb47a760da01b6c13fa178811c47a0dfb14110fc6482543e8a3a52abec3a8d7176aa2868b2d46cf68538c27514222a34371c25fe832184206e5abb699d61426027a942581d0bab075a367793c81b7fdc11e2f6772c8040d271be5d07d00b330a6c874b46d26f51db8f43f22dfcd72613f8c22d15c28a2b384051142c148b07f7362eea4771959b635a215b1351f650342d2a071acb16dd8ab50539096f295e44173bcac20f3cb271a8041e3008a742057ef2fb2d78f8a3a3c252f6d38d8e85bd57a75d45ab4dc21b8033992caa623866e8989f98560de33004d3409f233020899340b2591e1a4a0223a79e20b4b85c632ce7609c0c45a0246251468c1b6c20716315a54520c5718f4c5c7066331fc7e953ed91aa5f3b92e69617b29c256657124242ae8305780cc0caf00c92896929a1648be9b47f86f144a3b12d9dd51f347875e6da935f0bd043abbfdc7b85066a7836d442872c56fdd41d9a3a01d9ac6a12531079f74b273ca129f36a7ae463f6464436e50fa70cbc2756bd25234893b50a2898345e588b819c0955e9c50072517d58b0a3e4bfc9832b727c7f2fa924ac672d4d104a8f3ab81200a624c61eb6aa7b4553aeb2084360f1c03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed6b12e8be5a6ccc74efea7cefc7a0f5ee18857250d08f03cd94cb4c455141d7aa2fbfcbe3eb896c2404bfa3580bc63b73265581d87618b206caa9468c65bb1863b18f560413d1b1d392259f37c00f7d89124c56913483513006feff89092f218fdcbb8b118b206b64f2de52be0b553665c32831bb4cba3762991716be65e6a222b30a0a5cb246207352732bc3c8ad7a2c3243c62424af222a922787f7fe44df05299da1105f9ebb0c5aa18b6c6c73f43390af9c2454442110aab4aa629c8f300dd38318c43a25d269885f970ddd8ac1e5918e59a3d53dc8a44873eea97c31f34108b893b634284d69153779230c28b2a1636b6b839a4d91b7e23f0414b111f2e7c1b3ed58613120fec37c78308587494233313950d82ce946778e044c3d245a19c29b09a80c3b55416a811af33032a0068c7a4767f05e9aac3e8b99b967f88d5281a38b072b8c4e194794c40bcd5366714525e846048e55c008cb48b5ea0c61655b8819b08fbb88337e20d63003f2453462598ca66181ace033c707c1ae9760ced165596b2b163e54934540c4f7097bdf14d29ea850b95be6fd42973436144270549a81b5f73192c2c6ac2474686a9a3ee556b6f26a9039866176026e25a60b5864e963850cdc8219d21859b5c5c3714434ea53bb16786dde8036f317c430b3bdb025e6b62c097340f1e961b90e0c5182183de05b293a05b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b835c0e2973261bdaa43e414153118b66c641f834c949e77fcdbcb59dc27089138a2e07a5b40c7666794fd8e6b97685bc4a3c2a65912c35f50a278bbad765c8c775bacf28181d61530e54ae7fdcaa2681a01bf51c0d7a033d6b005893b98da86005381f1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f58aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +ciphertext = 9066923999bae264f53cf96f4712cc8655ec53d9a692221863ac713b2c6febc02e5b43163d008e1a5a81525dab273757a27c568ab980e5f15dc01ba4e370915d2f77cefe1a1e6fc2fd189e7717f135d9b5ef2cb4097715a825092e022bd750abcd7cb3d6ff8f73918443eafe6c2c06a00f0c65d45dec9cf12626e19c1ec4bbb01bac2a34e02d096be6836153d0802eb8e62c1f4e46a53ec661a304a223b0b3c7ae0799f8f0b162b962ab3c92dfb5fc8168632bacdce1bcbea60a0e88956288152d2a2403c3ec1cd483eb119eb62c5878694276a18d58b20c849bf41f42b1bd8abdbe68a9f0504fc106f47ed36c2b1fea208583737ff02c23470fd81597079bde3f56845a3a444870671c410f7010af93f253c1f14fca19737738923a90b78e097fe52a130df7f2fa622203a05a7099378cd22de5511db73715839a043b17adcc7d9ea75fab128482182efe6fcf9d87af3bd80fdc1afef0a635d387f39b27e73948540953976e66df8672115184bd7719248ece5afa6e85e59bac2415a9c242c7e28556d26ef5a298c2d7b4e80d05854e5d8148439695b645cc27e041095bceafa10e3f049f23f42c4a7bae8b58f031a1885ca2a18f1ced48148e52d16ebd12b63931dbb9f21e46209f6714a092535f454a8d3968fddd8022130c6bb989d0dd84dee9849ea3f75496425654634adee5462d6b425ba4e911fc8c47f98a67c3c116d12f372608d0bfa2d066bd5c3b961c64044a0f8186833213551415b2beafcb74d9b77f59f8b78568c9337bf73449f70c08ead3086c50ad0193082925cce5ec4df8df4b841ac1deda751873d1b0698e8037499fc3ee3434fb72b1710e6294909bdefe9e670cf80260066fcad5d7dacf233af61960c651164c40eed1d08e91f87ed638cd3879e2c933921108a4da065b4b2cd8f965a3365b130ddb2d1f0ff017f6d91e9aac01fee659403e00ca1008198eccc6572f0e49dbd0ffd8006a45fb6daeda45ad2a7ec4970406b44f6f0c5252bc2234b9db504810a15ba85ea28dd19ffc0476a38d0b74856836588a31792ac185f5208ce4ca0d1a5e2210d049a7a38c9b6953e8a4a154a34a15d4dcd1a758e5a03a746ae1fd576cd14c85f09d0bc8554ad570dd55e6ca80308a927515b215c1af914f9e409ae14cf99960e8355d6316297c6b18132dc89ee1a5bcd3ea1623a8c0b974e17048a18081ca47c2a22049c98f0c5c640d304a7fd80089bd1c0baf634b7bafe352e7d57c12771c8c4f944e4ee03b50fa3d4561f615f8f87fdd3f3181cc6d74e63b2393e5e38e71b1fd2a3aca442d45f1ffd7776184c5e2eb5637e31aeb60e547ddb12c7d276304f166c7be9c4569f34209875407fe3e273842b4cdb28408515e69313cbef447234f6dd7fb0606aa3bc42293dc31d1be2c18a221dc650644708dbadc53849c80fc2e91abaf51f869796d5e78c5b53d2ebeb3a2efe02dac17a177aefb0a583bc271cf7ab5d73686fc971db994575adf973fc84bb9ca50609c52a22fe421cc3b6f35735de793ce75 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d1f46e67cc5aea63ca9ed4e3938661c208e66cc79e10a64174774545b597e91a8cadb58deb15b27f343074bd71873870bf858b5fa3ac3689698deb68c67d406a8ff10c2b990967ea12753449fdde6a1ce65b2de46a8f8e906da16b55478c8899d9a38c185ebf220a60a999b0d2b4f9b385e37db8bc9b85ad5fdcd73355ae641ed0f8fc68ebb8534135590dfffd0a0672ab54936c8665aaf476b60f93a42e35283777c375767b0454760ea53c7fa14d3c4de5fdd1d17bfb2b598a22d784a48eec39ebe83ad8fcf895b242954b41d7e3bf4644659e7d6c6d8d21b67b3519a6df26ead237359e36fb95c6be3a95f2b9248346785fd0ebd3cd083a2119ff4e9eaf157be2f4c9c77d1ecc0b68adbdc8e3bfcfe28974375808e4676e704d0c5caa4dfa074d40345de7d488e5b7c35363f5c730298670536c6adef2cd9ecdfd18783efc4c39c8c29dced23f1488a7469f1c0cee7ebb3d1ceaadba4bd7321dd0bd89c04339dabed896e655cb1f43a1c7335aef4dd44d9652e6d3b8e3a4f18f73d72d7d50a2984032c45735a3aaa51d8aed8b9a1ace3b9bbcf8cdcef3d9987c45c9ee89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1ab4e5df9a6ea4785337535869fb758cd04b7999d7e36197ea428c66ab5e6f70f404e87341e154a0e09c8827f5cc00d761fd9645b658d98efef33059e4a898deb0c826e9d57ad4df663897d71567117fc4416c860776bd26f5ea52663711868777d64ff1224b277fcd05f2bbcfc0c84146591cb36cabb8f692c1edde229797cac57aeb64af446a8975f7bed9b3e55539c0f7ade9eca595399db96bdb282c3a4c46a44a97d5a54a8806cdcdd3c736a20d34aac1e881375ed860efa06958933d6967add457a58e7dc83b525ccc63e94c1bdbec869cb3a0bc46d47084482cf563754aa8f44682b97ded04996cb8886f43b91ac8767af1f856ce5b85f55c8802830ba1babf5797d0db7f3efcf4617ae95ad8d9371d93f8abe9c874c840ee9c39e7370ca66eb6f9e552cea47f2dd9c9cf633e7cabc9ef85f8aedea29d9cfcb8e43bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a834ff7949d6463cd3c20969f77cfc8c8faf622a373c3f4d164a77055ebae05787965c6da862cd9658c32d4194dccd7ab1df8782669d891be785f0385b965b5ab3b870b0d88696a783b5c7a69a6fb86f789bd43588705315258c117c4313198af43efb7fe39894a96e89ffc4e8c6bac5e8adf03d86d18089a699997303d9a6debb36588ef64197166df59bda98c7bafda9e89dbddc587e8cd8040d649b9bd8fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5153bd49850857308ba1320f83a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd87e2697fd0d55ecafe599ab0d3a184dfb0df7b8fbf0995042ba0ce78feba8b71dc7cd74436fc75b7638c5eb9c4a3ed4f7c842328486a799d070f7cd5cc75e5beb6817cfad66b86ed047ef988e84bd344c00aa1200432c6de42246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375070f82b7da42ecd36295fa55f8b5ce94c8e2bd5febb5d6022ef207e7629736d614527619e33cb92600a1e39a20b25a5b16eb0ec1070e5d566b28449bfb38936f44721ed428ced5768ee647a771b7d76a30c7e5563b515f5aa89ffe994cffd9277b0695049c355267b3a07c61f3c5a2c0d4ab8df76129c19f44f762b51bc0374a43e6f6c1155901b2430b2b77afc9ba4e14d3658607387dbc2d12b99ec0c0b0c2721af298a6ebc92a7e6b97bc460674931e21f68377c8303b24cae8d5ab720c79c4399414a514254603b565397857a7078b36e24a262cf9070a92c034c76614d5ab455b60b3b3388500946677195cd587942342a6fc91bef144ea412ece186a422b85a213c43fd0c361aa00698458f5c5370c6c553a9c238201754e2b2e2785bb03053e0b414e472087a0276bf2d805cf477378ca34d8f01c21b433f33b49a8b9bcf762451460558fb9c3cd071e654c250df04b6541baa278c1669bb49ca3ab4c78cc92d0137a2864bae0c904e23aa28395edcb435d9c1cf742562d603bc61c521145ca16f69192b137ee372f04402527bc557b754e187355a388410751267561a6b1f59e04190ebc604ff64a2b08b244b57abe84f18938c5a9ecdc972191bba33915c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f421281b5763865c584cfda6aad7482d00a0520d947fddb173947865fe178f9800570d4b2b9529a42a514a8691c8531a271c18e5f84380c20cd9a992051d29b5be76b2235b511514904e3b284e8854556334515162db1b09894b18a3127982269509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bca04e2cd90db634a3d52b734e224c4c60ba3c8240d7b2755ae5892a09a0e7ea1b2424402c45a0ad59563ab97ed906a1a15b8c4412219203ce6826b91dd00ad602089ebc5163b416c0d02009a7a5440350a00a7b49309ce39ba26df79ece038f23f4b4300c01287a51f5fc619eba04ab1b78e6396bb23c1cb86a0f3bb11f7d31a161a480b8f33734cc63ea7219d76bab759b1ab3405ca61b535b893b1bf2b678849751a6a4f18923ef44470e543924d0c462d8a078782b80241334f547d2aa474d95b8709747162b228993ba15a0c4fbd8bd662a1a2f01cfa859ca723a011949823fbb55947b9c27c2bad547b0e6d29665071b30f3c8c536651e6437c0d4a314ab38a8f707928c0c2b864a3a67397a936dbfb98fab2c0935441b83157d05072891a43573882be97686534c8bc7015ac267b75f0a79c6991cb6c96c735a4bea90acc9bb6ba1b12388f0821a074018909f76944d9295b5eff73e70ac1b0e1644e3a40685305f8a0626b2f05969fbb4cae07c61f6213159b3471654a88ab58ec3a648f2944625820f6592c67126bc085dce216fa708089d4947ab911ac14c00e53782a01580fd967594e0b2b2a3272d590aa70c7a3f419accd33c1b1294d21242c739a3e8e577316c23ebd4b4c4d0577b2bbb12cca71841b54c0b76729320bce26dbfe5bbc017c92491762a6c938d4bb0099aaea190813a3a78e5685d83975050d719d6b6a80ac313d3018d25b9054b5013f832c1353401e6cba3fe527b8d2906871b79836cb35284725e733d8fb60e6a8410e5f61428a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +ciphertext = 99d62a49c06c371bd6d26ec8c497e9383a842e6374424085f3922951dd554e866a4593f4651c64c1ec8123ace1cc6f54674e685018b756d6d7a5d6ea146ce22f25743c06aaa95093177f25ca0be23e6e76f5f71a5b741a29fef9c82137aeef17392972687f24184bc0c90344d3c51759546dcf761aad332c7d31ec3e08bb6021e07efe3b8fde04f6d1f718eca765e27fec6592b94315e116cae292d94e72004bae5b6d5a99d03801bcd0420a459605498f299cee4b3ce6cbbf0178894b9e20a421b885914e436b7356294e69f1d419a9633a712771931cbdee3b1c02539e4a080ce2be2dffc33f15fff7d3368dffb2fdb4ad6ebccb71b5746ff2bb19c809129dba5cef8d17ae011b64472b38107416b88585645cb3c80a794febed9e0e16c169ed0dea7ef52c079ffd05e2cd3cf2c6b3cb31813ad0780be61ff258b53f04735c2a3e8ed23dde9d44b5e7e182d0bcf1e19fc9d7fe5084f06e311aa4cffe8e2dd79457024b94a2b0a56f2f6f3caadc4ca3c6dbcfb538ad58862306e63b50472194578d708e5456aafb34d4a31dac16c6e596367b636dbb07a5a932b863d86d3b9b9a20514c6aac42b135b98b747b6bf1e0ee53cc9d9ca1b6ba97cd4b029ecf0ba3fbcbbe01392e43593195e34442100017655486b8bfa442f65256ce79a8e1c4c0429030d4d37cedee7d1fd6749de72d187a8b4554756842f035e7e873f06794a315ac8f1b26a6357447813b60fc9d6c4757b696df2290529765e2276418a8df9d22408cb9b8b1b34da3778cb981e9d08c69e003e251d98651050676d4238698a0879209e772fd5db2e552c38e38a822a1d6ca1c0f2fbf8399501991606ece8480f8b5f84a965a0e1e3da39459b7e6adfcd4d4bfe27119a608b0edcb134ed12d5798796cccae06970e1f283aa2ec5c5d736fb7afdda1dbfce7f89015eb195c56ec23ba0c10ef7937ea39ed252a47a812e599ec99048c50456631214fe7e76d11d7f1e2a5ea7b52c93c9b810a18f71309b0ff7aeec8c9243bd8695ed9b8311f18022533f6f294e281a9ecc525e99774627628f8b8bf9da0308e1910f255494d9a349211d4172a2fcb7a135ad940c4bf579667685833b21b7232b818ce2a40d4a14b28eabd8feed6016181c591de5a569e3b663338b9c710649bc7fcc5451785cbf6c2888fc5e7cf992ec049c46bbfbc20f7b4da3df1cfb59f48d8e24eee95597c77a18243544a693010cd2a0b2209a260d6d7d5ecf8d86a57b54fd16a5aab3908fa9f4c4da42a0c4f686dc08dadd5ca536a80213cda1fb230ba45b45f3d6d590b17f6844f54132e6e8c422be287117d35c12ad0707c6daa0cbb0fa039ba168621c78f91b65f48bf23af0c84493c77edc132e1a335e2e15fc3830b90df5d1029c08afb86703d46b1b4e018b9234a54cb76eb906f2b50a414e68b59d44a59d6b1cecde5163684933361055e51337372e239c0f94940ac4a44cbb780594d3419df9a896e271bd2e2306415317278e1bf7ab91ada048ed232065b9df3379ff9cde44a16 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 0aedd09aa9878c697e2eac9cec9675a967d660346547d7aa8d4548e3aa917e238cbcdedc389445d167e4b237566cb44132d6983ca6e0e779570b74482d5ba2743aebb51c68143ce680c8d0f1938795367b6d8a56c33add78affc791e664363daad0ecfb279ff4bd6bbdf6e5a3335b397487db9bee75a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988776e14b8db198aee8edad821764df032966688c99feaba06d1ada1f8dedeaacbcffacff2948a209ac8ee505c860ed444b5c70d077e00b63cbd6d98f9aab73cb06c97f03ee7badce1897d7ddc5c07d495b27957b379d55650abd5d9b9f7586e771afddd0b574a594ec3bbc9f6f1ab017ace18c7a83b2934e950b3dc83fc84264c66fdbddf78975fcab5feaba4e6af97131696a0ceaeccaefc40a266fbe6667c1abb362fd631043e1a89fb95cd5f5ff97fbf3f394ffb48b30b334cb0fbb32b9d1e3478f8125d5da066de6a5cabb4f5df84cf7565ca48b16bb2855a797b7fdfd57615e6ee7b24374c2e3d6473a34962ea8107790d268ac6b68e3c593cb9e96f1f8c68fd2f8d82c59ec95c5ac74c86dd38bda4fadcb66aa576a05e0bebda31235bdc9f8e07f1859addf674fd7fc6669a3465556fa0f69cd3db0a8f53563378ee016a7abcb5460d5371c0e754bd7373c33e4e2b4fd98636112f3cbe0638e513b38d495dafd7aed3d48530828efebd88b75f532e464e966edbc592885fd2ceb3108c33f7472595d617c5f6ad5ffc8cedce9b1adade25d57c90ab087cf6cb014bff92988903bafefa3c4c96ccbcffe78f988a40d339db334f57de69a12aef5c52a414746db1274808299446ee768690e70457acef198e4559996fa96b418275e041e99e0d578e86c94648ec369ab839b1a75e9d6845c98aeca34f53b4bdf00ec7e92cc6f6b4da4d9bd4900ca3e78cc7a5d5e886e19d1a908bf0a08947e3b524f1c606b055451ab6eda2bbcf93f510c3d75e2dbdecd493b722dff4ec69565f96651a3a2c3b738c2d55805798254ed55dc95d8b998f2e78d378523dd22e494b61df5b0ccbc69667013c4ce4a24dc2e9ba928e4ed7fc5f37da8c5ac13e0f06dd7b3bdc6737bc17a747c5a3cef3d1e66bc3bdad7aaab1d97de54694c1daf93675f86c4eaa35d34bd6ea7aacfad4872cf57cf63641264aaa0db4f65337274356f72edf310a57e45df3ec6c4e85bc5cb45a65d3b69faf313821643f060264a6e53702d766d0f5adf1407dc75b780688591cd4e4283a59ad2f84d665354d72cfaaa2cf78ab6c8bbadf284bf86f82761906c9b2796595bf5ac01455ed2b436082d7a30c949b0beba5d5d659143c98247f79003ca820b4b5963b0883ad88ded9c99f4a6368971a7d6885237bce28580e2ec483fb3d5ff0cdbca173a89cc41727a55d5ef9a8d5edb3fe851b3d58b58d3e920759adb5f9da26fcce486e8b207e6f3658d71f5455365c67b04748b47ea5a96b75f44fcc5cd31c713c04d2b6cdfcdcc92b7596bf4a2a0d9e538adc8174b3456489d2dc7dd3bff995c4830256ef0ea5eee92ecb22947d0973386984adc669ecd5eaa34d5dcd0fd77fd20b6d4e78696d564f647def0e02c8dc526f630f7e465accbc55170fe0945513748c0ecc9098a02e9d51e44acc267272633645ad562816d479466b54d2150afb682b4f32265f1f4bced21caf7c7980105b08056cc4192bfe0da9aa5e00864b0a34712204cf6ae82dbad360a7c840b4804826c39a59ae029056c1b2542b6a589eb47c14a70acd1731bb0a4d657656915b91d696b2f92afd82245945c7b77958a5b6a3b6cbb179ab83a0f32591b757e8b68368d6a5ee63490604aae70ea7fb4619c91a455429a6b195214bd28bc717385d3cb8235991c05088c7939bf852125dafc3bc368479165438092b530bb2b869246988b8f85425a2a523ed108c6d2f54358580944d64d801078a4b621f58012f9d8a17a92ab8ad43821e24e2f87bfa844abd0c6b08650ab76d5397f2cb0060b31af689fc8612249d46374848f496b360e733fc991809da804dcbab14030a4bd18cfe37b41cad91a66a263437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524c616babd17a8dc7924f37345dcc32de04273c5a0ac038a133ba01ce2481ffb57ba153826a7cc4123570293c82082b6a75fa05031cc7fdbb9031e10ca94aa283aa26eb3546f894b646b9a85afc5df3b513db522efb340287c64492aaaac5fc25547129b56b9541eb0912222c2e60a11b9304692a749bb174cb47679cc294253b0f768a7872f698c23493fd908c9ff95f9275551b947bfe84780f86c1e0bc105f6cb7c9430369b58bbb07b3b0c87d8541618c76a43d52c98a08166e052b4487177ad222e6a002f7fa3f3601cf1ef0b4c02ab550d76447eaa695561118a46301b544b493c368b5b77ab17c5af4543fa6a8c682a46af39ca48046b1529684a53d0e492e1b8596f55334ade15591dbc4b411537c88a5113458f187a6d77278675b0c85bb017416b6e9543fa1b924b631ac1ddc5556127548fa8ce0c90125139bdf13428e2c7805607a44251a5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343dcb062ea3a039e949a7f151c8900484368f1cfa385bd13cf55685bfa4b959f8634ed7c437fc9c044b401683cc7482722c98583de24ead414c1833858be987672c557db87aefe4ce2db8a676d14083462db35862dc0cae95f88ec1f59426fa2e24e9cfc54813be07c98f78a87b9703276b455e15474d7a283d5738d4b639369077e7790dead3336e1467c871a571080004a91162fcc31d2912646a9406902248fbbf28dac4343b081c327743335b9efa4b7fd13d5177064a5b6e8065b64d8c6580b47e6472c8f5139268145ba7a23a02f59acf680692b20ec2dcc087a99be036bf7e9c8c0df15f168c508ae28e33d951740a9b0f0321e35cc01328b7ba860592b566cb369b21f51b7ae583d26652da729f07f5b8d59caec65aae42c7c9cbe73c68504f26670bedc542fbdc67a95c9f2da1a08e559797170ee63147a4688c8e101e5aab48a4d1862506cfcd297c7ea61a9ed4a54fd3a28380292fc1570fa2ae43920b0e940675b60534425c69f35bba714c88b3a6c323090b4c56b7f89963059f8ccb0994373fc1344412f694175c2eabea110e035bee6abf546396d79472eeda164bf49350f54c2e75754f502de4a42721b37974a8266c49b57c6837b38a28ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd2429b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +ciphertext = 39afaab7974b00311d124330c72214db54b573bcd9fc3efbe3cdc82b4b680c4699ff19c1af2b0ba0fd7a2ca1016de5fc566a098d40dabe6c09cced8fc3466bddf7fd4166bf9f69dc4f8dd8baedddafa1c07371f85cee047165b030a99897eed64b7bf34f427ef1fb5ffa56fc4150dfcaa480385b86e215c116de9636b59cfb5c1485c1364bd6ee0c12d471d219701d78d470ca7b6d16d9bba3fd0610611fb7e0d13acff438b6ab4644a1d97814f2563d7159f7b11f632c3f5cdea5dcd4047a9084515441b5e16f22098b6d943cbcb71f705ea675544193fcf2c8b0f0457735840bbebaba9d6dcdacab820de3ea579e8ccad0d59ca19fc1f70578730254ba58fd00235e77dd346c92f4916d7bacdf6597232d18beabe0f7b4f8f916d661094066060b9a0383170758e3f5b2fe0adefa80a2c7b553f03f83d465a1cf090ea5f5d04410f620e509f9b7c81dd0dde465e4c52afcce12f5ffe58506162e888afa1ed8700741ec4d424fc46e1c7baa9d7da6a450019be4522f23088a239ef39d0ce1e3e46a8d7d6dee09450b06dbdd701cf9ca5b920bca236d0ff8d2932acc4b590b16fd314c8fc466809c06c7066dbe7e4716d32cc40d48dbd3a74820ee85b0e8f200b375ae5729b8a708ea902780ad6ade4ab87f8dcde5e9552dafd56599ebedda9e43a220b209932227210b744b7676098cc1a9fca1a325f28c6537d56e6ea922c6a9ccc48ec1fab814631b8eb8d5dc466f6b2d7f5a48a5dd3cc42880751cdf7b6649cb662bb973b0e0b88c95d8de90571989ed9e2ed115bf7f7bfc4caccf262247e90a7f63febc66218525f255329c75e957a6cd8650583560605faaa84676225cd42580e1a24fe7f3cbca951812762adbd5fc514bf094ddf9fefa94c72e22ace942ed493ef021a87d5a794f4c27ba5cf6c06408f79cddc81b21d416eeb01982120e77ea036b11eb2aa6f16ef380a90051a543e45d3aae0b313be0a9332b71db12dfafeb0128623553d69a30b967ee7894e54bc39131c376e73d2b947f0d06d3b5d35bbca914c8896a683ca39947247747def3ade0ee5a4049fbcc26989f792309fe1793becff2235de7434a83c6cb7e5519f8a7c67970d5acc472d3303dbef8fe7491c949cb8155614b692f17cc0ee844f7f0c3b2b538a70d9f3b8e9c698a77753616721c4a26ca766df1af04c8011472166ec8acde6ae95f002005dcbb5ff0f2d6db1eb3b49c258a23c9dc052e8d44a6fe08515537bf5175b7618882703160c285207b64d55c1f9563f50cdb151f4dcc5918f6d34c345160fc405931dd97f7e3403f5117a84a16c17077f6e13119bb5fed5cf8f128c50b46e81105879408ea5a90a128e2bcfd54c3c091633dfd9cc48be1e492d2615b8c3766730b7a9484ede6d646d3c45a09b52e3180c8b281595a97ed66c0ec03b66aa3a364926ebacb166b7699f7dc56f3606538db5128bb8b408c8fea3cf2ab0903fdfcdf5416c8623cc5a700995be6f0bec2ab7283df510d95f6ba323bac70fc058567daed0a06f1cc81 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 96d9c6699e5385cf847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef704d6c3aee7770bef2f44721be8cc326a80e524486a16a0845f7e22e5ee4e06f5b036f5fd6a857bfafc069da3a4e39f0e14eb7284bcc61ef0194f345ed5ceb097a5a5f730ee63e76f8acbfaed3c6dc4a06a7e8dd64c47e2de7324df9acc73ddb2da99238d4802cc76818df4548dcec677ff6a5a9d14f4d12cbe3caf8c320b4fded64bd591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718b4f1d3c45bd14f6a87589362f5f9549ffcf785802b2c6aa54eadaef93dc655eac68a9867c9b9703abedcaa540146ba6dd8acf7dc317b8fa4c139626713ffccb53bea3d6e20e4713c8f842e03b7fa984e5827c442ef93353bfe2b5e566eaca8d9d4f0610d655f86e72a1fdf7ff9b230d6c4b986bc9465e175a8acc8efa2c174c500666d3d0df2a9c4df1a46544739ef920865ad26f40309b5c838a2ddc5beb8bae1bf987aa9d7c082e8c55c63ab02dd664e545e505b4aaf5d606136b6b01499a5cae0174852224ac6bd34fd5e2e758c4342fabdfa3d46a9a855e12adccbb73488cff3d55cac398c0f45c467b94eb342e1845969e7d511bc7100f886308cbf22ce3840cce7626ac93dfcc4ec2fba1806fc15c5f153a9d1166598f25555c32587637a341017885bfea6d194eaa1c747d928f53e1c873c2ccf292bad468d5d8946b00edf3cbead3878f66358de75d68aeb744cee5428ce9076e0681ee875bd62e9ac8a107f6b55b76627c53338549c3f36d5841ae1d66d6ace1d4bfadcb51253af7188358276f8235878d626df15033844d76ae946ae6c34d054cfad6c3a3d72f7f1d9565a6c79b5694dcc5a878c6b4d33bb9c88dc43b130348082f4ec269cc0d4bd5ffe356b5695bb01c95f8aa9c30f5dcf320ee51aee3acffc7192b75949ed6a68458db80a8f71573b6eece513aa5b060cb77c1fc6286ebc198e59a49c95190f49b3e35c320d63511f637cb9cf17ca9936787aac954bcfc655aec8b4215861a87d9f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61f7de8ac4de46e6da6564bff980acf66186fef7da45885dcc62c433e75ef447ccef8a773bb2731a866832ae535f0e8fe605371f6b35fd60ce288b5f080d6d9bdd8748d4feca47e90322bf86c849d362f4bb61d7d84ef827ffdc63869e3395f630b237247aa8c100678e446e8299f39ef19c99aa6b91577d4653f85bec89f0b1cf1f4ad91e2063e5e4df9f52c33af97529f8de298d3961f59fe6b83ed4f2d64d034533f56e1fefb64f1899ef563ad71b5fe21be99f0e8dc557cc8cedba3cd1746d3a6ac2e697638fd8a43d681ece3769c8980c77af6adcc585fcee94d28ab163aba5563a5c7985720248662bbc2158dd22e04e20b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53b1fd928f7a55a8eb5210e7bc06b36d11af1433797c26ef4e099fa8133dbd6bb4774d46f73b874602588d3f8966479e9414ebdee87ac54059459be9724949e7998ae8018755d59ebffda76a70a64ef09d3a438e734a7484037c739b7bf71b658b779cf647d420e2d73fc9fdbea2bedf29c3b12c54ed3b1cdafcac7f6d08082da095a7658b3a45f7bf717d4b80a3a050a04cb23e01103ffb1731b2c35a9dc23c4341976b188f5226459a02d348bc9d2064d574040147b41612914cfc2954e4190905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca662024335a083911aa53828d6d79c948425422c32ec471c2fa843b54f6731fc401475612a135aae4b146fa829871c0654c075dce41190483c3ef60b7336200a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0d402147a08a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb3f184d7d6ac6ef64cdfb89d1ce66a059a4659d8137dfb3c95cbc9e8d86e064cbfdfa50c68130a8d82258407bb7b926f7a802b53209f3ab78784102e88fb91e6311d496251f7b574aee5797e881ba1db16af40281586267d826c0f33a0518c26e6533e19ea0ebf29474a131d882a189ac03b835c16c34c9ae7a1c4d9f5159f85b8542284e0409dfb0876fa6488e6519867b5c53896867772210e95399a1733d2e78532b7651ca9704ac063df086cae4aaf65150093f27054f34e2849449c7680ef1ca1a0ac399a01a9b74484a967592ce85086230582518414c247bb7680abfc2a04a35a20a851b73548a8e4cfc2b84cb5ec24108396c28498a6614790d56bf8d1b9f9e40bf574c497218eebc06217c9bd361baa5d0715e666c2d3d299346a79be0bbe4b7ccd49f948a60438514129c126aa1f3875718922c5124728f09fe5437ae83194ddeb81f0d744fd2b9b59fc223e2792501b4932924facc16c1e5444dbd6a823016b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c59910628c8ca22b1138d884842c387b594b544e5d99784b06acc3b5d80ba81cd34739a20af11f7735d645d9ff25c07f8af9b5902524a1953ca2a58d6b796e3695a006ad6c703dd161c12c01b9bc995773c5d2ce59470c765c3f5401cc07885c77bfb3c15d7f766f0ec7cb3f601dbfc210d599093a21c87d82002212b06898a5a878d4ee913eb451dce14a1bc424838d4797ed14d9eea2473b304d6624f1725c820751a9d313cbdc79ac9a26548587fb41371c5f48a4da04d37ab7189685aaa054853f0491a0388ae4b7af4259969e29eaaa2b2eb9503518c7c53ba0e6bd20ea8355a63f1c481eb5e662a0b792014ae4c0981274d902759af794338072a839b05d9d42c1ebb1a3da33b54066d1a63024a3b1d1437b37a83bbe816075cf416275a6f58336905937105e63a1a017f87911cf0b41daa41a5dae3856a606e2a9333176628198b49d2517f54a9182e4ba877760517dc94a079538822251204b4c4a2382cc7889bf84923c09072f86bd1c5879ecc3a37678e6d031568c24012578dde5ca01005b2df71a4a0b0455a03afbe7c366bf1b086973038fb5debd793a303b4c867b611772733f66574cb0d7c303563c389b2f1b46e98945a94b142b2b0d647521f4b58f12326fd86286a448909191bc600bc7578b0169a45c071c77f280c583788f9c2aa1200a73431ad56d23b20471bb67a627a594ba9922b1ffb75d2d030432a954c71235a9278857c3010a8a8906c070b77060fb831842140770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcab990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +ciphertext = 6a97fb0d3fc17256c88c551781f6f142a05547fb8d0d96cdb0242069d0aac67f102232efd259c853d4a5222e4d8b9e5cfd7028afa9de9c3777669fa77bef10515be69536e6dba285206b1a924690cc8882178f04702dbbd541a38dd036ff8e6d81253e7e902c6de5151c04eb29236b261b30cce838b8748c3da04e524f3c71f8344235adaf16b54bfdca539be81daee0c2640a03e69f55f974e8573af1f42813fc32f99f31bd1d462324dcbefa61641e6eb2277a143ba321f3524307976d26ee122a758c330c80c91fcf5c7a7a5709401607f723c3386cf8314cef0c14a69b6868f117811a7c3caddf1935fa2dd230381eb62d1564072f6d3e68d4ad87e4fd2915d2fb80ab2f6f3b18e853dbf0d06a057f930aa61898f1b04148f5387ed19d6c2c36669ec31cce3974dc0717a188f1d2e37cc31de7b15b7d0712d33ff646b11b724b12509ba41735a771c6ccebbea8da3e651cf795c2131f910689f11a2b6a241ddd4b71605d794ac24778e2ce1d47566f8f68d22251b265fb0dd9ba211acd4652b509a6b412536f4348a0cc95a7c8bf736ab2b2a9870bb7e75af32e6b6ca5d318c5ab752234ee9e09f3deef5e0bc52fd7c8dab5c2e965b41397413b063829f194e9fc8d9a92f0dec9619d6d6aa8bb368a5a80167a4511225fd88145be368f210e1dec5cf94f28e1399a53612fd7d4003eef30a0106975c1d198a97055e9e44aaea6f9d21056ed983b54524eb706b89d7cdb6372dec8adb8217a214bc29f02e236530f56daf7966b31997ec4201be6d776880a5b0cd7a8784eba3517c2e7613c53c1ae23e5b1fe3d2f95ad0ef951e06e5a249d8225d48e70dbb406731ae18e404d4bdc2d7e10c43e62b7b18b7308b4effac86680f6a84bcfed751ab5d3d68f093800c1bc243a28ff898c66d3636820db810bb7b5b92087221b2afe6bd8e953694f87c38ea2c59c151929ac831b120c66de1fb05cc39a9b57ab491a7762dfb8ccebbe3194a993b4867c4d336a04351b30ec4d2f0370440acb6bdadad12e4d3db51e701aa49c455296e15b9d13cfa68340915d2f694b8b67b0f34d275867c3a53b6215dcb0c3654e6c77663524301d1e828a0ceaf7d2cc226da11d1cd78b072ac7f3ee14d2b06f8cbb9560c6d7e60dd95ea5d402b5de9e7b96b64c4accb8eece2a4bde33e8d27859d6fa6ff7b609ab159d1201df7734d4c73ad0a4eed2d80f24b8638273e9c0e53ec0b8272ed6fb82a6ec30ae431972f929759d000e4e5b801189473cc3ea318f07dc495b7b9eb7afda03f7e470345c9095bbfc00bd0321eb5498991c75d29731df41db55e24890e4beb84d5bd6666347a53f2dedc5c6480a93b19df229b8d7ee732e02c62db28623fb11c24b2de9d2ab0707e4c174acdc7b1ee8e287b62d1d797a3accf53decd3ec40fb57e571d129f1a7a70da324d094e51cdfe1a648650670736e0da6aaed753822e5bde4a2b69cd0c05a875b5f75148a6a65ff26c670d17a0fb598bff1643ba62d03c2bf9d1ac3d33c044a0348b762f95dcd +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b2def7d258d8fb2b992243f83223ec4fd67fe9aea070ac8d182ddbf906fa1e0adcc91e4d98f65c8f4abac3bbe7b434edeccc37688b881bcb68503b54379838bcded0b5bab3073f7e7965b694644c470a5148666c7fa89872d39a006ebc533c83f38dabfccf6f073331f04db694bbf5feea5b2f65e96798b7078ecaa21537dfb5746c76e29775852e5850f58cfdb2e8a0e90530a57b387b1c42920ed04096c3e0bb6e9bfe9f84beb0b74c47bac678b10ff79798573fbca5d8e687966be3e495827adba63da8a17564a3e78d37b3a4991993401c1c6b149895ffccd3761ce35a5d35a723e40eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685206bd8d44a3ac8f8948f2b7bed9cace27ab62668ffd8f2950e0c9ade053a4c4ca8e408da907a39e33db78e6065fe9ecd50a5a730595ae5eb3fe38d5e2edb79dcf345f1dacf38a1732c65fab8ebfcccdeee822a7f896c3f3cc43aa0363361708ff89d63d4b2dd3cf9c5ce3379b1d53a63eac57adbc915113e6acdc30fd74a1a2e6c23584ad1dbf844409f4177ed79b19e3e20b3278d8a2e9be8556f336cb85d694066b6d8fc5d267a903c6f4cd54dd8e187d9e438d178c83957d6f016b835e25f2ab79d4f80cc24358b7dd3bb271039acc1741651fee8b6fffac473054d5b4cb3bc64cced7c6b637cd6360e41fa85a4bee3d2b64436a87e92de6acb763a23ca9b7463023148b0c4888c0be8d954e84207f3b9436b77b09c79fd7e4385a3ae97b5bde1afa0c64edcd2b668c696281389ec37dbc6d088fc435d6cec85bcb4b61144faf0b6eb1b9d75e0df43be293cee6fbd413363716ebbc48ec6c361a48b9d871bd5742ffffab296d94a92b508cb794f2f69a8fee5c2d748d8fca8cd228471a8e5e75b3b0df86f98e58f80bf530e09a34d166cd5379777d57ff0994ba8e66f9ea7691fb973f45869635c6eb277c375606b911bae22837ec86bd47942a52187bb2325efb50f5be423476730f40e62b9d3cfc5b7af5ce9fb38e0334906384eade945e995afd659fa92c1f508813e8b9b9ce845ba29bd3733228ae960663050888bb98a0fedfed6fb34cfb6ceaf6d9b98ed6ae455cd9b89b60685defb31ae7dd43ea845c713715b5bd5ad87bcce4cbbc9d2ea83d0fabdd56d939d01b7d590b3083df405b2d724e2c44b61f3bc24d7b11da3de5889ac52b7b792ec4af23d3d3959eef3888b8847f3e0695b5b844e8e3c2227e8a25057e707a50e0159af456fbb2eed3b9057ff7fbc1740bae1afa44138aa2b7f3f70c08db6ac745d08de040c97253133ea195648f9f9e6c6394940b6ecfbe8845fec862da6597a46f65edcb5d38d3eaba4a092eda011a32462e85a74f5d9d44b4346389336951495759305e9c23dfb06bdc762d5e9d5cb84e9a68456ad6daeae85ac6453de2bcc103f3fdd509309fecd8e3b3698a193d83e6fdf757e9703bb5f8cc5db7b88b812edd74d6949e0d469b94dff7fabdd5cdcec2ad97a71e7c28046b06c8fc8ef8f04296428ac7d3840acf7f3333d84f726c1e4d339fb3155bfc4095b6d465657fcd780c488a0d6d443727e09363c45787f71965e35f6db46104bc18bac09a18690b37c8079af2645532112b1dd09313b9a25b7094700639775f89b8d0314eef0186adf7ceabac36cc9292c270717f27caea51b1afe1cfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad4841b229fb7a17bc213b969935c672d0993a94ec170bdc8b7c800e66bc6514f84fbc81c7d1c9417b79a82e5b3980acc792a19c46d13a2e75a3af791beb401f7555793d94c0ee1b9e98a5b6c52777e537bfb287268ca9524a4438ad87a0e85279e474c5be7740b7867d8b04781a2436a8d343f62274e236c736dc3c59d5b326563b9c86798ab14a6c9a0e67b36db89a82af690da7016418ba2d6c435e39095bb81a0e49c01a73a31ec9159844d1a3eb233d16b932919421e6a342473a71de629477183e8f34b2b7c8abb7a3b6e516107cb5229d780b93417f9bc94c38bcaa58f34dd88835308c742875cccf4928122199cd932148f48a94c5c2252295890bb4645761d3c2c0f33ab3e1021aa56b573e9c6fdac37c83f678b97148ce573a244b0487f3cf771bc7b6a13fe53a6ba58854b87a67a6a17d6a301c85f7c061071b4ddb27b3f404dc402ebacb8254a0568d48b2d299bd831188886a65aea5cd8d987f6017a2f4392f455c2b4f9b63e6cc1a27ea38f2588b0f8086d7a5c5e4b05b76d2b8918820cb8851704ca6d730861b512fefb0a76b61401e23b01ea710c5e3b73fa716dfa6408a635423c61372592dbf174d6d811eef7c4d885bca5fe669233a141e43810ad10235cb59f824728bd7acf17765bcd354a493aa60438f07d266d728b640cb07d50275bc2605fa6c964614b2c8143b37b184f3c30668662149bc18c6038706c12f0d31b896b69a7d588d0004497e4808d8c12253987f000168ea758a5b32c195f03f23a07c5a546a6607084cf79e073bc6cc1cb372e385ca827c490a42d900035bf735c6242031b8332bc57765ecce4792706f1cba0c7cc390e7bd3595ab876c4e397c58fc325c9607b0ee39692c31730eb4744e967e7ff8139fd1a545622ec870516b2925628ba782cac845b2429c3cc0ebf7747f414e8d35cd4a91c959d2276404a5df4790f4363104e6a0d1d60a48b65bbd92b417b51a5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3c31637e14c5c0279cdd6386e20ca89a53671fb2f04249565491ac2f900ad380d1a68b67693b185f26a232aa1b43503398002085713ca4b2f94cbcf6e837b020404b7f519a2b520f93b901943c918393f26061346a0193ce9ba8a48b5c4b01b0efa231eba0528c5b38cd32cd5d22586494734fa746b411759303a51a12ec58b03fc99a1edfb1cb01375032054878a6ec9dc4425945aae387e7fc6cd399c90049854cf51b3db690eb78a0a2db04d05102dacaa9834620aba427b5733bf1d1693643c88bd265af0280ecc66344b81129c491b3998c6c70ccf03257c2d06115b72aec35b4c8774cc7936c578b29fb3b0a5c66709363b73f41b08db919cbe57ad817cbb5df62b7836af6ff4ab8cbb07c9fcb7e3d601b2117e6a7242abb24ea96ca867b597e9e9b45c01aba9b54d2d323df8b38d3d37b72c2790e1041037355f274cceac2714a92955b31c55d4903a85bca55b2bc22c536aab22557d912fe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +ciphertext = 1bd710a00c224ca78beb7e27c43a7541a1618fa3dc2615317cc4aa233e6169785f2b722e6e1c73d77d8ed134a6d56e3cebde5fd64b5a7b6030bdfa7a9c95960ff5d2c0cde027a437f272311bf4e79c00be9b0700aedc165d911ce9e3b7c75d9b4c6230e734c9d1d6b9a835da5d666cdc8c129f4cfa5b640bea9c1da52aecd5272e65d80f1e53d261cf0913ba405eb4019e0f9a54e99239fd8e247ab5db67d062cb3cad1d6e2ec8c0c8f13bf2db8a1596e16966e68454c10b9fa416441d15113da81165f2813a727b7a6b3f598311405b7051532dec40035ad088a5c598e104ef624a06a98f58f28f7fd22ad53d6b54d26449fb289d0fb6c42e6f5039eaab0fd650b627c62a57228119920435aa41190d51418896932e338c9dde3b0e532fdeffd03551d0e039940134695412f2e81a99c73094fbbf9b03335155ab2ed25f0a96d73fdc08b04fbc32a2e5486110997f25a7308d33aa8c051d3e6aa887b7fc5294ce8c4a91812c41fa6160e37f928d9e6e10ad719f3dd7ae18f6444b9645991a1ae8e2d7f284a96e652a7f40d7f132e681f6da4f4041ed9ce41de22f879ed09fb765bccd340345095642a07bbfb8d8d1854c1107200e0288da6790603dff76906b44365c16a3d05e5de2a22c3414ae3e2033218e918edd9b1c3275927df7e771d7b5b1c5e07953f3a30da668b3ed6d408b709791fd5ede9328561ec40123606673a22d496e6ddf6e5ee838a47528f44efbeb9718e4872fc6c63d8c9860ba2c1689958b77cbe94057b6779021b039e4c18de0b75702b2d9c7123a2e281b979b22d1e476e6941b82786355ebb6a76f8ead17349c1e5d779b494d0b7e0153e56e967cd4f5cc5b0f136cbfa965d323998ebfb73ab2563a62bd222f9d4113c16accce74ea94468e0d721fa7f5019c1f9d31439560a5bd93a071f696dec1d0f52f4d671767cf4e25cfc46f4eb5f6d67fa40951ba31ee8aff31eca1a7787c90a4ac7667bcdd66a220e2c69df7b7ec49f7d6d8558da91c4a05dfea6da06d774a420ada78866c2d5cdcf526dcd2738a27fbf2df61322fa7e8964da5b634c7bf19985dfe77a1e0683844b101242b641e7d0913b37bbf9d3f2bf3519c8ce95e917126a7f72a8c49daf48d4bbe37e9cccc9ee4fec24f47bb2bcf661e6c0dc9b2b1753d929430cf923117990e0f22b43a74854a2b3fa62d3618faee0b877061317128ec4553f74bef2633d847141ae3b0b2dae44605b97fd159532cfec972103342b21e6edbfa9f03f483a67c45cfa31d338a668870a26b34023004ddb2246dcecaebdb2305aa4b178c4ed57fb0e1b33fbe37f3246be553b68c240ae8e54b7d36fa4bdd0a0f7602745e2885c7a85832320815eecd846a08c0974a2a35542373092dcc4f7fbeaf61092c43b25616a876ff66d9a2f458955056972c5a7460a4ba22fbf65680ada0d1c9664e5747740c4fe921e2c5671d9c6e30374217578c769c3a8f089c5ccc9f3d19eea5389db458ca87f03087006cefa7f3669753fe6fb712073d267d18bffe82 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = eeeb8867be7cdb1fa45fcc6f9d05afd103835147647a83d1ee17e366398473d8e03ab3b064e340f4f986629daceefdf473fb49635bc38debcff0f34c5175ae0fddf5abfe9cccd46d659cfa6bb6fb51de452b09c21b53dee9a3ce05d36a8e1aab2c0de95f35664b4999cc9cddf049c01056af6aacb0267d8c184534f127fb28fcc94abcffb81efe20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c808edf520d3778bd60f8db5fe06c3520d35e97f6b5793bdac43d4349387b637686cbcea6e55e49183d41fd7c3cfff5a398ba832dcad4de7e79d0768122b7d1f5edbfa58e49ff24de2978a723fb985b939459bd81e1068ee62dfe5f64d365e6accbb8c28db84126cfee8d0462251fc2f075cb580e9eb828616cbaf45a9bd99b0ebd86268cf59e823e54de984335af59924fbced43263af725895d7e7e827532d35c7da9bce420b46aef13c9f33a427bb5a1bc646f7b54a2186d527e3d3badbfa21aa39c5577bcd504e7f126741fba9c2cf9401fdfda14e9a7bc9f7cc8135bbb0c3180696093289f4b19539c58655b8698a6de339c9490be8cd4ad43e1fe5ff045b5d27c2d3407cb575556fc21ac51f523389f8d3f31feffaacdaa7b5aefdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd42d8fb7ff8661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5ccff2e7aaaf9f9e49b0eeeea5e869919e3d2b543913a4fd148639da8e5d4a99d8362a84bfb6ad20b8acf9596df4187009e7b77317d4511ed7458eff9e7a9b8ea6f4e4efb1d624da9e4789775abcbd2657aa4877413e4ea1e446db6cd9746accafef9784bf3ec0bf55ba5c97070ef64703c676fad9801762e9fa45d858732af7f18b47e07b47d8eacad5d3cd35fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e56cd5e6c5d41553ce7de2f3af273cbbf65a44b4b6dabe5eb341464a9993effd671481592c5a655d116b963975007be3503baae3843f248f586577fd098f42f97b8e3dfc7b4df98de5e783af5d833b99d79484d40ac05a6a7ec5e9fcebdb38f443c7365155e4f1cb7455958608b6f503428464d89c66c2d9c417445416a54aa76f34b1a5bf2cdc3f7064b6d0a7244ee70b6acb01c033c5b1670a3ba68020f4c04bf4cc1786025fbc56cfd4f3b34ee4bf7d1c9764938695bea53e6adb6abacfb44f214ed2c29bb867379375bf11ea9df194b872a7b684b3efdc179a4add943aacbee6beb93f5dbe00fe342d088eaa80989406571d1b79d08f3eae15b81741af2e01ff710afdebfaa3c9d74392cd64e71f363e03fe134e9be32b6b855fb76e15b5c91cc6c3f85daeee7e072ad803987ca7f35882ad3e413b6d01b7df3c1ae839627f2b6ebba16f5577d95bea2c5ab446ac8e57acc9638ea07599a8d335c2d1f388cbdcb9f8633ce2f51c8a7563b396073ddcf6e7b8e3b0fea2e5731352fe4c317d8e128914d1f4973e759d53fef1735386b8749063fdc41fc731b2fb9c665cef0cc5353b79939a9d5f0acb54afe3c6fa56fae39d7d0353ff2054accec40311afc4c6faac3f392b014ba88fc90eb868693eac83516336baa60207dd518fc820bc8b0e76c66dbf001bfa28b07e21adc142c75111b9785aa2109a795ab792de4cb7b6298a504200f8850d32cc44e54182761a1c9c9ba591a9fa6873a61025515b068099bb1e63751c5b887d283077f86b733e4344d13310ce12d22322f254a0e92779a87067d19c53c70dbb927e14e1f2892b5273949428eb4c70c49da8aa7fb87048961db4892a6f89f18f0bb69347b9575025a964047ac7bd2c7472838383a6072f8338b23aa07d6b7b221e18d4e3c62641916106694315a2fc5bb88c6d664667680df556c3c046398a88328421f32ecb758bc64cf246815a25922021dcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532dcd138a4c03e2ff5024c52bb486ba7665b27610b822975c412331ed6c98e66721daa1897936371113a4f17d96ea735a5cdc019809c3907c03fa950c00eba9dffc69a902151a39163f2931e1c0271d491562e0a87fdf7b7846c31151017ef08727dfb68f22a8585295659ea358cc1b85c9ab4d107413225b8259804b31850eb347e1fd37f5435617a7a07b15321cc204b1a6b7c30d67e91c088a458bef5cb704e6b662189a9c0079e224a94e21502c0f1a4dff6028ef6645cba38c0c86eaf673e9b2613620bc216914a9781645fc48e33cb9ea06182637439f1d1a19fa50cfd3b5e2cb8310229b74ecbaead4b079d535521b8587a2995fa9b8c6694be6e432343c97c16ca23bf53883e23cc38f10c38e54f5639b9fc0943a4f41cd0acc8db40cb12e644cb74b9d4b858f7d6767830b92381a42368476cf2602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859902d19822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a459c0764cd943e0b6a5b61b8358530459685e2842ae9ab867fa712172207e692a7affa872323779087547c3d8b89f368ce078acecd55aafd5305371a5bef24fb255211b2169f4543927c845a3049f7a88513a682303960c2d12bc277656f15738c4368deb70cff2a32a1d179f4fdca57812cedb21b356e0aa63270788b510e58b4bf613473fe931dc80a9cb8bafe63aaac3913936c8a939c413cca10a1277409250b5da321ee5c24ad3d093c1c7095fba34b81380e5da561bc039e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d1a08127db4cea30340b5589b2327988c97b78f003d1315dacb301520a11f9f0b4fb33ce7c0203ff11c6a66136c0aab83928c145f4b968783b131281f2153925dc13ad133fcc5247b595cef0f03ff0da0a429c0de9a54f66c03f1a616c7210b7ed3624fdd27e99f38472867a9283c6b294b0d7014cf9eb62f0d7b051b190f093450453c056081370b45f5ebc4c03808fbb5c6d8b659bd22612c2872de9034b11c6aa6d356b2baccea0f909da0c775969c12fd5bb0c8a9bed5172a9358e01c29d308636b5d668f5b2c9def1380ba23b5c84259d887d3dc4882702b41d99c72c800dd5b19935d7722610741a105c1d227c38c5665cd5a6daaa991a9868499830c1697fa430bf4f95b03004126fac283a167281e4b847eba8487b0032914edb0b67b1e320c25bab50499378115cb07a9000e0156c9c93c1d90693b9c22623a3eb15618fa1c470481c4cf292b7462410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa09bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd381c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +ciphertext = 56faf8ba810d4962b71cf915ffbb0c4dc4fadbcedfb4d7778d70d364c15a803aa91866c8b086db348f84680b08f13c45d0b154b68e5b355b43e277a6457b3d304f01b5dad75324aeac512ab2aa2864129a10fb287e12fba81843ee33def6c12dd9e4b29c170592a907d3350850a55addcbe92affc8515287f73e4fca3199e536d0c2e2b74dd92ce862c3f302621689d666b8dee9fcf90b4721818cefc3776f9b1195cefebc7a45d6088b3b588ce4275d32685d1c06f0065079c8a73dd8d8e7120907a141f189ffd63b2b7568975a21c90b0cc69f2120bc94e5ed04b8c3628aa1fc7d494a2b8119f939afab0e5e99ad377661b04e85ba80a62e7468ac3e90e4dbd11c196fa678d3246d69928a20e4b9d6bb0c3fda5d33b4ee8b8e8e7c651bde38a9918f9131f60f4ec5b5c340ae3e64b39a1c507b77ced606ef9b93246a204dcc5363ab0302726bc94daad4214807f33103c7a7c57b460f432b8556b54953e6beab1a116b6b73d38bf54758e65a236ba13f10c8abb4345f336660b215d9e43209f8b85363342a930d8d9f229765258bea0d520d6d9710149b26cbbb1929fee006a63de21194cfb90c32deb5c402743c4d6643548e82071ecfe64e6d0a5f333bbfc7eec513a7e4bb5f16f563de4f45df83d220b8df76ef10c750b90f48e18a9fb7727dd64093dfe9fb6c381f7e19189200a53efd6e1d4d534bd3ceebbd3021e9410485465adae7340cb599a987f6792d9c8d675a12debdc06bff40572eab9ba1d405204b6fb7f87c5fedd49603bc743082cb3752e8893ae720668481487e86160d590422f6bdd3ac742081e3ae4fa0c145c795281f0f61cefc18e79fdaaa2d0d6cbb06cc0e4b9e7b3c0c3b02d2d6a9efc4b61f0156d510ff5effdd8fb74b32acc81d31dc38abf0211ae1ae1669f2d7753d209e00d9774434291a105695c9e618800cd518591b1facd18ccd4939b51a410c1b3c0e3503a0d5edaaf37b0b4d55e33aab5ff93ba38fc1ae300d42f1983cf3367b0a300817cb79fedbbda6132e2fe9f815f5f88442ab6d01d0eecb7d8185762d30fdd94978865dcba58a6601f407e1b3ee3c3fddd40439a47ae414aa37410faf9e10d6b661d452b38a1091781f3cb0c7236be1ee528f174c58397fec391f7c02a0627879e943e317a8cc075213218354c81e73bfb9f7c8f95e2953872d42603c844304ff42cbe05da1bcb1880a3d2d5858f79390ca5f60bac06968c5c0b9e159d5c49677f0c8313701579cd2fa921e4e4fed73622a7e783a9542653e000e530144a60622d79a804ff48cb933f84599b5183e6cb93e257de282e386f6b211f093e37c3c2a43247c1e6d97686a5c46d02a5e8c9fbf611f4a0a308f15106e9561e8c5a2b1c78c45ab0d4440972dc28a6d92b5786d5652190bd8f5460ea8d0dea988162fabfe7597a5deaa75e3ad2de1d2172d3147d3332f3160361b41ee990d5a89b4b2d27e97b2d21fcbb3fe26e04672366bb03c34cf5ac6975219297d3d299ce5852c6e63a7dbf632cb14078f31621ee4 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = b27ca8d41aecf8aac1a62553ff64eef56b4b4e45fe39cdae8c2cb2241cfd2525adc53be954aec239e3add71b5f76a3e96875babf8b31edd5f8f3c3f0e6569997639f1c9b5279c38d5ddb3b692bd228ac4480d45077db55bbcf4285c5820c49be2573fc4aaaa23ed84e11bef56d9cca9b584d423a9fd47f76cbfc5953d9f84b4d97c07e706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450c1f899493f3f75ff7961adb24b442e78c551c5b35e89b34b018b80cdd94f7594365195f45cd5baccbfe0a976a86559bd7bf3d220b5c900375c7be88fb353c3b064ced669bee6751d6eff659eb89900a92b7ba84eab58b7e95cb84a5e91dad491ef75a3abb9469a7939796c2f9ce5ca32f83235852b0a96daed4d3c6cd57b5ac91d09cb16f0ebb0d078171edce9596b913e953c5aa67bd9afff21cd261ca814f334244886daa0694378f93fd858e15ef3d13e66ac89a58867574804786c4c48d30ddd3337cd02a7776217acfe7084588455a0a85b8ab5ec33e99b1cdb75541855578aeedb00475e05fe68e8af1efe574033d3dfe37ab5c0ed300395551ae639eafaa8e358748ec38946bbd3d0cf8dfbd8f500e7abe33a2df3b9b96cac0e9cf61e487cf003fa1484ca5e14d36797cb4fc87ae6cd7ff9fcd835befb160c4f5acfa8b75236d9297de4d43bfa7ea5c998f7f95db6dd53dd06875de3d98e2df8f7c3f76dcf8049933daa52793ac10f57ad9ffa74469f7cb7df2d5a485fa4f4663ae75b2a6349b248aaf4853bf7d9d432f8c3ce3b13a9d794b9698869842b81649cbd9482c2435886441ed9a7927384372edf005b5e4717abec398bd183b321134a4de85a1fc9b72f7268ccafbae28ace5dcfce8bc26b81ec43c6b8a391a6f51666e7d60c33f1e7bd4cd5492415ae5bbca5ce94f84557c9cb58ea951fa5df2e444e3dfd969f38284f6dff16bdee717e1598dbc6d3834230c7d22c7cd6a2f9d1eea957f58b2d48be1ca97c92617dcf2ce934ef83f5a36f41c7c73959c8a060ec2c1d7d671987243635fea56ce6fef92b1d6aa26c4cddfbae7526fdfc42e8e7f2dc13c7aedf4835c7d7cdba469f3cfbfab40fa7fe383fe47ab652309cdf38d91d8d86308b73f90d869963fdacdd9c544c95fcd24a77e7c90f3fe5e52aab596feeb1bcd799a3ca95e06447724f0aedc777b9d48fa89ce9488dc8f2b903548bd47afc22e453b68736f5cca6c35ebb028cdc7035678f7f69a9dbdffbb5bf3746759670f51f6757be3bae767e7f80aa75b60a7a0cc99ff70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc895e4ced3597a594d0e28c7aa25859e57bea0cef692cd47a8a73740ee695ae742027a8f573dcb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc96f5a2cb995b548d48294b2fbca97d375b922d3392dcf7fe835f62db97b14739f6c8b1880a53ddd388e2636f8674e6818ae10258a098d9af4458a64c68654ea7d99746b9baef3adab5653a7dc00719b54e5afd219fcd7be6fada3e7357e35224184a4e24b4a69de4f666b33e1530375d70b73aa6da53fd05ff588f34ac1cb3b3f7fb4ab30db459966fafc689cd4dadad1cf6108859a2943e2df84a0272c13da5a495942ba848ac92d302a98a3e55937b8b1b49fe588be32a540ec90b5cebbd90d1b80dd24d32eb85fc041a7ca307e522b8c5fa9c85bc258c8abb9f2678d29569f313a1e660a2454730261a6766945ce42c140e5181c68461eaf12d1f185c358233b9bb4902fc5089f851bac83ce3f07bd7b185ef08626d7029129703334084375bc5ba27ba023ca6722319a916baad529715661e3a413c8137cbbb206e313906df1ca77cba73e5499f54fc53047741af2341d5623278f76131ab47af10bb4dea8f493b6c0e4829ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d02d1131e493da5a0a1117b41d4ab3db35a7a2e95c6055ba70ef159e7aa0dd5452598f91477087bef1396acd48e747b962205af92eb99faa809b4bc47eb93bfd3860102d4adcbfc39be80024550656c42785a6788c7a851b107823a02a3daa4caf25097f1f9afb29416dbb360c4a824e3ca2a30e19f94b805de181d0a028e685c378dcc225112899a6b79869109ca4b094909b21042c179c6cdeb22564cfb6f89135022fca3028caf7abab19a4045dd5a60721c6bb47ac53e40cd932511f2e5473d3b4ceeb44be1a00e090a886d345b13a58620c49ca0893f23058412054ae5069c1014361cfb0379c2215f330abc647114a3c597765fd014c64c8c1b1b45b3bd02be9d5a55b0cacfce297581fb48fe0256f4c0cfc84aae1c542f36730e5f10795c72157c653210686801210418b549a7398ca8b7c70ed007cb153d2a55178ae23a5b095ee2d116b9f3a1a9f19faec40d75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c6701368b8ddc219a9f2295e6e01d22c4a50bd08179a08044b702ffd786faa088f867b63b951a92751cb0f839cd554a83745444c3bb88d3609a9a4bc2e0bc73108a71cc7534217872539bd6e942cd36a09aa0374a3894d279a1f7c38a56e7c0298948c330b8c3a5b6aec3bbdbb87384677ada78017564a7fe40c2983a9ed3acbce5e29e3a78502952a9540a44975572a1512b1d4284d9bb528e538f43a15216f4b4f2a5208e06c43896a19c416c99c3b677564975948468792edb6532f9b0567f407fc6d6c302766c6d1373bf78a18896188cf20ccec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f314827e0b24539e2aa91123b3fe42308f041dfb6c876d079d60a3ef5735ab8a36abae34f4a12729be4a00f753c7e4699572375e6c7b037948684206c08a27ec12b26f7349cdacc3559ac29d5cbc35c310870597e391ac4e4c02991096f37492083bc1c43304bc3d5925843622494c735942dac8904cf195387eccdcfcc8a999b6d1b744a542359e6b167f91022be1660bbd218a6a6861aa17c57152552172f38b43d5281956caa77daf9b94cf60cbf08cd9d9b4c1edb6c4a17bae3b36800891910c280c3e7cbf4aa11f33a7c70e3b419c2b2b9a64709c31878f913fb934d77b4c36e329ba98b44f394631e0a289042061f527d67446d6ab55ce7b43ee1080fbae67085a2a03b36cc9ad9b5b546156c3c5a79b092a67912a19575f6b5546397c15ae334b451c3d919422f28b70727c75fb631a2ab012bd5971b5b2b75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a5687ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26dc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +ciphertext = 4894d82e0c293e45df99ede632043a85e6054b1611e5559a4cef6e13de2f1a4900f0765b01da4ccbcb823fd715242eaef76bfca91fe70349bc1c24b265a0d3c8294e1dbc274fdf5e0e14194c418f5ebcaa17e602986608b1a7456713cca5e121389169a056d1ff870c6f23d44c96c2afa779fefc28a9439a6f17a28c76c80b83f54916db504d15c3d871e9c31da20d957a71fd5553c7b2478859124f74a5bb62891586d6641cad19be57b806e59ef42790ab89a0ece8ddcaa718e965c7cb91f7b2e7e8bda3db23a4f7281d0ec15a6455775705d00a6cd2a6a900e4cf6f584163990c211a49da061c2174444d3794e76fe271e7dd01e580a2dc34c5feefb118fec7bbe3d28505d39713b985a5d8391589ca29f68834db1f5acb42bdc6ddc7fef72b0528c6aef837ba5ddbfa47638cef78adbfedbb93104a8a8ca1d121038bcc3cd29128b8cd93a69872d21b00f64e0c6f64e970d0d5454f08785af96a7f3df920852456b51d1c6559be74ae8b902f499e4f47bf65916cebc9b092939b3fac9097fc29e33d9c60e511763c7d48d05e30db42845c102ecf542b2296fd448b4adb8cf6f3a2b1ecf59477357feea532f41013f6f8494cef0ffeba1c7e88dc31f3a80e110060f9363638aa577f97d56554a9cb48ccefcbdf211665ef0d19c0e5667d4970e46b3a122fd9feb6369ea20dd39bae8ebed4f2ebe7bb388b2c38abff8010403ce5c63a9ce090b2ac371587353fa892cb221a6f104c58c0f24d5071a1a3f2fe15e0936de0853230b8a8ca393182276641286fc393264b4032ca117ccac3b8ab44660213cb645b0a91ef6f40227f13ed27c79cce843569a5e6fe0ac49d1aea0508902f33e3b4a4ea6a54c6e0baf40315291a367950b6bd7efa92d1051c135de04f5e2f041273db77ccc0b6d99886a88acf4848f5c235534ee1503afb3152dbff0fbf85d36aa8854c84c9b4403bab1cec6de2bf0682dead6a5aa800338aca87b7d2627d26bd842ee17effdbdfe3fa6df0db28ef11f01b0a93fda3edb75fcaa9921068a4c1e7d96d99864ddce1eea3f4707abb56bc7a8ea6519462209ace4535f2e119d37e24746e9fd3b56c078f01492b3f800ae10dc633d0f64f106dac5c60d928cd3e15097b92c99a5163ba27d5b0961cfdfb49aad6acb76e8d3c09ae9c3b093e887d1ff0f79ebf6cc2f1377bddb95a2269d18781a4e046fc5a9d13b366906edbd308b546d7584c9533615857680a22dd7865644d8c62d27f5585c1f8699762f86fa3f64662e77157793a33f4babdcc657af6de6267ee3afa991c510be7af8a0aa0b154d78646f0e5df267c9a7b0e46dbcbb02fee8f3c53b2f5388f01674c21dee845450f659bc7fe4776d515a99f248df58bc24819857d672dd2e83d84ef05476ea6cba94b0587d85ddf6214873fcb332b98c087666bccbc8df96687649700471eab9ae063bd544349c5d39e1d43363802d8fe6286401b2ccdea2408280bc53e0087f9905f13c3847ec2687897375c8ddf9de7aeb115b712fc8a7ae189b661 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 2735bc067af4897f6c8953fe5655facb24a2a64d7522988c083fce083ef8c8e5e47d4f988f94a8516c77873858395afbef65b8784ec5b979eb6db84e3b2bfb2f95eb1305832f5fe0e6dd5710a5bb7195b8bfedcba9b5ba21ba57ba6fa280565aaceec9015635cf1a7121a85820ada78bbf6fc82838b6b4d5c6fa5d46469136cccc34a3d66434d915ba5c86e67ed9e73f4c1f3233d9fd73ccd5419dd5dcd6cfd62635c40f6c990753c55ca8dd385a2abec79fdb97c0b4cc8f26b28ba573b5194d6bdcd65f5b97e08df009c43a65eccf452447b0aef00ef68f18cac25e5c71e62a39fd8af6c6b64b48ef9d1f4d84801599aba838a48d8ed83454b506965507cc6d0b34bb139301eed14168a79d67d7c74bbc7ba8d461249fc31734dc384c9dac4ea6eb47025df0857e9593c6faae53c8d567e9945975d0df5b003fc88674dfec37cab3a4f676c840a453c6751caf16a4743495bcde75f8aa4fa47e8cfd6499b2a97fa76f9f8ef5bdaabccfe604f33231235a7cb47c96d9c977afaad533a06a34d24bdd925007984d99aba3aa8168a8ac92f662348686f756bdc2af3f8537545d13ae9f657cab9de788c9368864a0604daf22e33e117d5742fd6ef577cade6ccbf2ede065565a5b23f8479dbf621d93e45684d6c69fc0f548af95f248db6a6e86a2a907c95dfdd53fd942a93bd24ede8803474b03f73fc12f912257454d0d8d137c5e8404379ebf71968eaf181d8a03f58dea58892a1fc5fac7d1d28ca845068761f6bab69bbb75584f7d289dda2eab30379248d9e106a784739be7d00d44418bb9ce34bcd913bb27dd4ca0489610aaf55a39beba2afb5859d8634d9e473ca623933ac14c90f64cc74af396c318691716eb5c9cf8f3e8b694535fc2c73af9843032ce9167dfc8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf38d3e2c3ca5d585c4ea63009c7b851fd875acf78f20f7c59499526a8b2e4a4f03197a9315df2fa0c4e47a3a6fbd8bc59a7c1312a6d19e3d63f8d78b2aebff964af4825ee4cd3cd87f49bbcfdeafa3a5bf46a7f9bc97de739f85af35a6b9e68683658ee37ba6d9499cbaa8cb44c93bfbf87ef7cc7b1eb6491154c140cf127ab49316b70b8237a556d90c9687cc70cbfb93fd8a706f063aac1a429615694d7344ad50c1d48967c5334f354297df49ff9c2fac8639ef8c126ddb9fd537fca93c1006a77499658c0286267c9e0c11be2a6136152bcbc03e782c42befe95ad00cd974a3a9ade3a3b8b4bb8ed8c4d3683ab4ea3b84b84c482506f099e7feacd8943385f3c6b6af765bcc99393213938d67be8b2b168d6c73c2eacc42ae3ff55cd3ac6d85f0021ec0a6076f0209d7b1c96213f8d310b8752b1b619f7f366faadba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3e5e9e4263b050259a9a0a8823e3caddddb81c1ca5392d323a9539133c68b0a6cac1fc834c8d8d9375431fa6efe3233c49fc9e88faeed1ad68a37eb503cda0377ae309f86013b4947bb671c2bd48c19d5c8dee6d8035c7c05b9cb8755c7d7b6db39d7dacc5a91c6eb666837f219d75e8ac5b86444b49ac878fabfe18e4fe0f89eab7cb7c973ca8e0437f158889fed53d194419c06b92e51498ac2601869a1024eb0370ca3a420c48a765a5b99bab88a759251cb83259a628603c54a831ac0147f3a97b8329474258b7bd6067476605a2b2b8311252fe54565c865e2dd96ea9e43b23121c27ab02c348310acc38d9d583b0d8105dc87896c238069c689027910f9bcb5d29aeebf57c2b9c78f76866768c0699c6bf743c0b43108c128a5277f39b32c351926369fb8754cd0197eb9ab602f391c4ba564be2c3423005266229a10b21d31a7cc3d40c2e7192cb6628afa692d3e75aace66e7bb1169893c8ee45bda5560e7f79c711d32d52c0c783eb40bf8977c3063cb114b6368a8d1486a86cb108d146a648e080751440f4d8087116701987c328d8547d0573f8c03d321ac07138a60954297cd832dfb989fd99aba8b213e7501cb3d25b384c023f66776efa3ad4981037a54400729634a782adfc24404bbb4f2405a27a8500cd79e8521daee48848e485f53a28de91089d849ebfb54d97d0cfb3cba46a27438f426eea1a0122f2180630864ae46cc5f3a828725cae89331d540b5b3633eebc0228000d75908f21277104d7816f56854c3289ad1a5c72c1655830089cfb9c90b1306724cb2828be679b989a3565758b058ae983c1ea9b71f10553795537d454eed50f50a40274592ae165c846d85527e479e3fa8d8865047bf68d200287c0a5b8a6a78c4769bb3a795979b774713a522dbb723f3628f2f4126b639e3b4c5c4b076d321a208a123d82852aa0db6ff8457e745b6b710b396c8106e635a379e22c59f17df7b7070eaab38d5448e4ab67e6b21078d5b9f9979c6d7365cd1423cef6b4c2b186ac6b792ef9351b6040f423ca22e7a1455a0473273e3b53b92a132d7c44556477907fb41f981a06cac9beeb9655fe90c4fe93cc33337d78294f7c128ffee82b0d4211e550342c599c9932a201f3cb8bb253a0559fd667a3d2cb46a4936f5cf9c4d0d105880a446066ae06841e12f259e4e6220d932633f77f9a6b463e180778d53c37e0bf423717f4d476ecab6bfbda7e461ac3cc9806ff4b38fb80c0ac9b0dcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f53816d79c6a1fb40f1ce200334a7e74760999f8a0294c3029bb23ee0cb81700b95ba20140cc5de537aca62c9808240e74d508a93263eb14b7d202a31ddc2147747192ba1f38932538241ad1db35caa40097393038957b64e716d4cb3675aa9ea46257bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cb62c702165c74864c3a7ce67d8af92eb78496c4e8eb78b55db7963b016a252a85e655c95936d6006bc07ba6250e458a387bd7bb43a3f5a16cd8733b66565377c1a74d5488c1a0dbfd7a6dfb474eaf29fa80aadc83267d0b98eb7a8ad3aeaba977a0a5e55b8937ab68e385f94db13fbc6c26bc23b0b8ba331a578b99b493d875f206c278a3b4f63e156fd386fc13104d6dc96ae9bb3055481b846183de71eca09273e58c466ea225b1824246c799ab8b045fb844572882299bd6f1b2787e1094bca102fb20e0a274257062385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac0151687859b155ad62a8539cc6b872aeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e12c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b204114f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +ciphertext = 2f2b7e105dc744c34852481001d4d1eb1d0bcdef8c5845d58258f6bf6310b2edbb26de7891a00b6e217fa62ff257dcae69b6651ee5e074ddd61c8a17946d1ac239e629bc2c99a3076e97cec64c5a626cde2cd58e30192aceea1d0c743ade2914df45089b6fd8dfcce48bfd740d0bbfe76572e2619fb648c2c9abbe128d3c4154c2e95dc29e3f5a362f6e7a54c5a1c903963c5759533b9a6824eecfa1aa486c5008c3039fe220739e8fa5b135d0e68482623d46f4486e9ec5161c070a6ad330027316b5b7fa0a7d6f46c4a18460259a0185f63505442053a356cd3866e2d8652e892e9d4ac7a87e1b0beefebb3ff94751d7d82247264c6701daae5fff0860e72d7cd26596e7d6cf4e01c0e5deff512ad211e516db0a91a0104d0f693fd924702ad578d535a024a06220e24110517c0909c71bc8d1f53dddb4d1d00d87e529b02081ce5ddf7db06613e6af9fe774e81040f37b00e7408c9a6583c273bf7a742d71f14bcc5b84aab2ae54217891f9692c57494e0a13c64d1434f9c47de6677947de61b092ffab34d05488e0277b5e8c29ea908c92ae68ca9873057cf0ad0c1e7ec0f4becf830b8edf3f6a9f3f06850a3c94ee0b62a39efba961f067b2c09d6b0eb774869896924620687037d052ed339853446fe3312c676d28e5bd54f22dc080961f546767a9c683e4267d8e0b412fca766268aeb72aa35111a5eae473ee808fc143113adc424fbf120029493bd311bc6c0f5084b371f20c73dfcaf52c77cbbd39fccfa4c1b0ca5ca1e4002a891b4ca6b0197c34b3e23b001d6367208edaf9085173c81ba7d25a139c4bea5798f4d2fecbcb46261474b1fde3dea181d8b0158f18297eb0eb3eb493dbb5de70543db4e193ec0eb79aa0097729bc8cd5d93303cbfbec0b892ac9f9de71c349f651c75bd327eb8e1c1e3b9c2b6e2244693d000af2a37510adce9e542c4b455aceec3909b1d3d0775466d14e185135b7cfd3f2b5c7d6c33d4def0e55299ac30a129c79e3d66ec9edb0ad0001fb4e18327aa3428659ec4b2ea509921eeab807459c72e214977e4209b294b9c105aa88e432ad017dc2698291ab51304fa00402a6d0085626ae7462ac4e953c6d9f590c7d2593c25a90b9b212b71e4882a4dc449bacdc0a5b338c5712c3d6865ac00e9f4e059d0fb87851c77822f17875563484e3aa7310039fcee3b6e6fe6560a925a1efb23852bdecbc7bdafffafc1c769cf7f1be11185cb0a426f49bd4ebf60e52f6196ab216ccc5fa5ca40b3ac8626626de041e4e14270aab1339c562dcc40adc1de8c3e184ef9868def9f469b035c082a44764352fe03db55beba995197d04f1ffecc5cfd47b31be972de5db28137a6fd1d80a958d80b35d20c6094f36c6584646a644b9357b36cf4d307165dc8849be47363c1c1d7244d1d4bb13f143fe8978ef5089b38966ad6961f2bedb2f51d368798b0b3859a8f165edc5a02adecb9eae1ec60624d523aacd6da4f2ada45004f096a6911227d62e2b9d6ff277e34beb6d2ce6ce428311b500 +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a78d63522ec694ac4672d8d9bb3b913e8ca2f659c756ebed7cbf36a04eab4ac9b3f524e216f3c998cdddcde37352d46463f371ffce4b26aab239498d44975f7885d4815552e727329dd78428f5568caefc76b572ad9b3d335a9f5cddf83c76aef8e8e36aadceb55f3bdc4bb0608cf9d9998962f76b217774d74a3453b6eff104e089b5e3663eff3aad7e9148f4bf36b6dbf6c8945de4dd97e6e998a983cef4aed8b082c3a29997d8bc1c4733773b74edbe326fd3e9ef64a13f79738dca0bcdf3a9e8efbf0565f59e837dfd31e229d84b74dee98ed58aed5e180e870bdb7bf1bdbb53aadb3bcdd28457e10288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35309af3e9d9f81d6ec556fce48c9a663ad9518cea36aaec71b69951100cd2cb66b75f1f847838dfce3ea3417ae2e29ce5bb6e757483d437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0c9dd33ae5fcfe2ae55faea568f5b2ef77ab74878e0cf4fa1f7c3c8467e3d28ed5ab2c91b83836e11b9858a66998cffe8a67682588ca78e6b6d746f98ee34b100bce62edad921a9f020a703245edaed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc99abfb071f84c921c585b9b3233c5bee08f637ccef53a5bf9b36b42b54751dd6f9a215656aa1890c0c56e0cc6fa3d1ff52b87ed72375a60374bf8d8455218de0d456579a3db3f3afa3b89e3c14ee12fabacaef75bb2da5202d7671369f82cb4707c5f740d9ca06ac7d34b48a2934d4d26b6cfd08c8b0db6e550044069f4cf27488c039dd1f3cf929294db60c3f1de5cbdef1ca216838091d3e72fdf6d141c957dd93bb6a59d9e883640d87a2a85605a9730dd53338448d5374b58747c7262d5a65ef442d6843deb83ec953f69b4a9bf00f39b4a3847841cebf4b9907fd7b9a66c5da724cec477e02f18dd4d0bc51addb2505ad5f82d7edce7398e0d9348f64268fdeb0fdfd7780791942565afbd61bf03719e7d6f87953c4757a75b1f6ead15c6c9447c02938c3b75a58bbf5ce65a5cab2e898fb8d50319880223899f5546e1df53df7950691b86f8f3e15438c3b80cc2e7b6e78a96a0f39adcc47394be36c9b18fe580d646a89b93283edd417f8f4bc4adbd9be30eecccf528a5a09595f33cdf64f6d2f6898b8a4c82d79a8ed31c4172a7812c295c9394e929b782b334490eeaa38c17cb4e77664306bc7c0e726ec656e253e1c52bd524d7ff0745665d53d73604c59ec88df6fc9ee3ffa0486d79bcfb735e66ff58efb0e1987a032dc98f0b4cdebc70f93ca709c5c2fad7d98a7b86676faccefd9c85974d7c88ce9a0bd2f58f76ef4fdd70c7c0e15950fc0775e23e73b60555a57d302d1ad04736de5cf85ea2f3c326968d3d3d8c15eb400b13bcaaa65ebfa4eef5aad69cadbd3e0d841c7ef45753d3ba9cfbc909e0107865883ce8eba462f7bd9eafed5796e43a8647c59c64b7a8db9c0a5ef9938daf728b872d3d3755b682a3fce0c5876f040543bcbdf8e97dc02a53e2aee9cf2cde302d08dcd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a5394889d23406fca0e473a9d639b1299251b46d07c79c0df1ceb995a968b5b707b760d8bcb120f6226ef5b742f34548902a7c73338a8cbf8d6b02a83470874b1ec5845dcfd3a4067c420f8485fae1286a23adb7373b9217c6dc173748870bfd164a16d62a3a6608f5e2b7fe78b92364a4b821967db45ae29aa1b11c0cd67cb4299b32d263aad7a26eeb3a69ba56790fd806abe3935d82487aec3205a856b4981e7f53b8f82a30d13c1b725b1418607b6619b0e8a8870bba6070e33545730182fb5f6f9938ab2ca68c50719fdb472a88384ef210b0c22785367dedfc840979ab758479506064b7971426d70af9a95e7d585dc8b67d4ffc2082bc45a4fa9b4fb9541493c3dfb88fca757eccb50f1a9cced9c046f37062e3879e13958bcf063041e858810b057680276d2ca12a307f511217fd626561587617674319382a4a00ce5e3bcfc5ecb5b3816133910650a469ac663f7a4a742ddb87c4e5be636213880c246370b1cbb8adaab6bb7e1185e1f95c945bb001a0210cf56f326b35051b8dbe85245f9bc6d973b39afb3a3b961501862b4caabd0d55693c201390f48fb7511990571985764be7373a7fc4bbd5e82b31f52494b15b6c2c8b5b593182028bd7ac7a40fb446ea756463c396de29d0fdba2569b9001e169f7c824c8a42d313a15b682bd52004867837344324e2f91a06a4c9f7ca447d6291635257cb0934e015c1937f732c1bba2c13591ccf4add16960b2303476000d984a8fc8036772c3b7c5721261387ae535129a7921a1711c98103161a95ebe16c0e0a28555dc3598cac2d701a98ca249801a4bb10379a5c29a1932acb6f6c3d040639fa98fa7297c6d453e35587488576db9bb2f9d1c37f8260cba3ba90e4b779867ad97db03ff005ecfe3470d2c25d54105ca287a9e0c039c2a2b71a1cbc6260d59a268d60c05d61202ec336cb8285b41a043bf58949df50def5937bee1af32d174e8fb463d03449ba747e92a79a1eac8ded247aa0a50821a16ad4c9f533a0fa24684d452a71df461aee15cddc2185551112682b4867c6cc27c43bf835432cca184840b85886a5d970e9f515f7f97151410c401e9baadf41ce2b8642313c295d28587a327c41c24da18967a6426663642dcf389c50892d6847718365cbbbb80723c1397b90447b197842c96a141bf6cd317bf12bb64c664fd237e886a9f793313aab15f668c91c71149c4b90b35b147f7c34b8ab6948799897855b22283050b113d64a60aac739948844a9f99c448d21c414425d77560670c298f493d891128ab1665d8141d2b1c8e67950a68255b7f9376332b1cd7c6630ac05ae7c127fa7acc35e640e94285e78661b15b21685a36c889a8cc890ce53c36ef23c2f17cbd8c31351beba827949f8707a05324abf05aa71857bcbe690405ab0030e648fcd3bfc0f2ae2c627e04f490bc3ba237059ab93085de218029f056b0f57abd342170f5b16db069073a3c16bb1c0bda5136952919b22ac477ac2489237bb0869656614e4ac248b003799c761b2ba5f2711b24a01419c88937dc4ce745acc16c796e0123a4228ec623a2a4e059b80b72beb1329c9204b6555b0a62c14df0b19b4a157bca985090b428dba8587b53ca2714b2ec2a04d306b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +ciphertext = de60b879b315048087f7a044acf1495002d4d8c1fe775d9f05319b141573f998398a2ec9e0a4783497271e5b3ebc33db67f59b721586c2d09e45cdbb77e59dea5f83c2e4a9e7fad83769ed0b29c89a117ff7ef7172a63dbbaeee3c1f6c6ffa92d69cd86a3e44639f718c0b3e713c17449b0ecbf674c8d84d1a33d7a96b4527c270c206c00aba5bb834930469d7dbaa5019dced9408b12774c4a36361a1d9bef01b95af6532ac982345cd45f6926017bb2189031aa64af89b83ac99db3fb349191de25ea482c88f3232d6cdbf02e445f76bc0aa19f35d178684c4715284d52ca3063e2129dbc757ddf36c3fbf08051bef13c498feddcc27591b69ba34be65231e6e4825e28e6cc626902e1ece7a4e08cf7e6f029fedab272f79c928ddc22f78113b9cb94455afbcaa7b7c9a50c1238ad2eb31adcc8a88a4c02a8fa3d90ff586f8a45251b485014a4e8f154181f5ec04f6ee3de1d7c5a0088d4ddb1e9563dbcf0f9c0f2576d87017cbc89a491317f388f06757bd8cb8a34d7125e2c66d7c00602c785104912bb52e9ef681e54425fb384cd443837338cf3f093ee407f3b5989c2d8b7477d2765c1cd97a66d46f1dad4a837389a1e09d0d4a6b56762efd058eecaa8aae088606b8543dddc23dda1bc5a4fa76c94755a7f5ee314ebd22832cdd17b05117919c07dae55aa8419ddbc9ecf4747e38a9780c2cec7e956a58687b082d7d873f5ef4258392b8713b1728a6e295eedc87cd848c3f8fe88340e2a32629a5d373512be9a46b2f6b286edfd3b9bed40c55dafae968340f711d48ebc28aeb93fbcb039714eb11d698a5c73eb3058a015a4d0e01678742a312b8b9fd2a6cf7eb26078cd4c17dcc903d4f51bba698167882912c7f7b6417d30ca0f074c628a6d5b16356c813f592e568fbfff725900a8313fc528bdf6beb60cc5b445ebba573ec49721bc9aeb6025b1295eb536f4287c88d3dbce90d5dca6b9c27a6a879f0032e01fceacd348c92832003bcac4e766888f849ea6e7636687b766ff8bc93a94a7ce3d2d2c8236ee3409404c3394e807c108c3f6e17d69fc3dd5861f95e959049545a4422957b11c65ce6cb926c3df73104d19f67589fdf09b44ff4d4cd0c7056125df52ac7952f8b6800652ca91452ceb11de8ebd09b52dc4bfe9b60559ba1547fbed198001637a4c8abb24b78964f461f910ced77c71d114fa44e7dcca920522100c8470e5699ee58338e715ea09e257f74df146e9b2083b394bab377e472b918a8e94274595ffad4f27e7660f5e29f2c292f3364b2bc758f741f11e215ed45427c5f512b7216270513524814b931f50b1b59a89752318a23b927d432b2876bdc663dc04cd30de442ab832d3e20f77ebbe261d64bf4124f64f6aec0100216f453420cf66a65d4620bdd74322fd270fa502c7f4c100c39c79edb4c6d09d065036d7cdbe0e8da3298f65408f6b010e19e3e9990f46793e32a52713991a9b88a3814a80ae52bfeca0f60388eadf5c51bdddd5853a591d56f9008e491e11710f2b722ca +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = d08f93b02a9a6f579f51066bd6f5eabd37d104634cfd58f8242dff2b63b18a8bb4f45a5af4e8f02523cc1779b450df83860bd0053d7c399ca5d8eacade156af824a988f5ac6bc5deafb6e77a95b9752c922bd6a7c4265a6a88b11d14d3e58ef7b1f8d78784f669e763929483393cad6e09f018143e9d2b7cd4fdf8c6f56b91768113259bcac9f6a18fa2a6185a1cfe8656448a638f58e21a3c6cdaf3449b4f9483ae9e0ebdd4bc674e0656640dad2b2e5809e547e36f6f8d9437bab7f7f4fd5c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303da8f23e1a4ef6536170f53a0d7ed04beb75fa34b8aee5e56e4a538269775818f83dbdba538f607e5d661d2a626fbcf737c98cf43d50353bb83e2ce137fec26fe48d81973eb974ab1ba4b97c95c0dfed65523430cc06620debba3dc9f888497658bc5c64b98be65ab2a0738f086dd22b95a66c583354a63865c5f37ff7d98d279c53f731f3fcae8689754194a7b898e99b897620dd9ff75677b2d5d0d7359905e763571638358ef65aff6d0d8c9b4729f404975cfb89969a77615d1a3fb404baaa545120feb3b09ce577fbf74f5b3b0c8f5434e87f61de8fa83e41fa1f701a99a7c123d500078922aae44a0899685596aa646f13573eba0b54de4fd5de2c60c3dae614066474b89f2377994cde4ee0a77e1d5cdaf77748c1f6f3cb8947a98636694c4efbfdce2bf779c66a317989a336bdd7150583157ec8d845a5fa4b3e43de95084f44f70578124c4c7894ab84584daec8c13a6598525cd23ca99f4c0499a68aca3e78f7799be0ef9a463a6d5e2fe8656606438274ac8ed8c87beda16ba3b8e5857a7f25831d8b85bd8ed5828575320c6baba75489455154c3ee50074a313ba9ae1db747f39405544f44949dde165070d8f71f1ba80e57bb5cde320c9aef8fb47354079532bba5138fae31a7d26e18c46ae6b2ab9940eaba9f1ef4f1592770c9a9604263a4917c825c084c353438202fc05769fdd97940aebea439e5e28cf795cedf5640fa922a3fda1ce4a6624cc9967ed5475f46334c77ffcb9907159461dbe416637d8df34ab4c4d1414cf7b6d5a1d23331f98f73222653adf9685b6e4bec9840356bea24adc4cf6db0b678afffefd0bcb383bfcf580c99e27b2870746ce5570ba1cec89f5dccc47bf5e7bc1fdc57959e434ce1e01d810d5b37aa8ab3392b33587932470eefce2386477f4beb859c861463c42b5030d9a1fdba3e1d49ef9ca5a99df58a7948c670afb50864b73b4db52dc7cff13eb3a4cfe009268cd5dbd0a89b44c156333c9dfad04bff0707e07d2ed57ce78705ab6ee43681b0fd87413d80751fa7743399cae832f6f3b65df56ab1c3dd6967379f1db4ef53b9efb5632a23b942f832a70af3cde494b0c7393e5eac807a38b01e9d526a5a3caed68f1d7812269ec864e0aa739c289cf0446b68880343f3fef157094dd424a34ade523e76c0acb9c29d2fb6346386b62fb0466bc8a85b97431aedf80850510c4825ec4f2aab987c5ad7f11693e7bbb4662a4890a3c54eccdcbbd75ca468428e48f76f8ec43e8ea8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137d4efee75640774c4b536bb1d7bbce797844d960c98359f5719b20dca6d1e2916f2829e73f79b55b468170b64f2f8b0c788796801c8ec244e1973c7e033b768414c55d43079b2711bda630e678b184a70dd161c4dabbcb91c07fb634620d1450664a444e82d22a0a4f54ac6c7c02d74120b2ce205fe49a139b9c8194341f4295ef126b37f3b22e35792a8853b60eb3f7ed01314491c4451470870a5ea5b1d23442019bc1def547fb8935ecbeba0833228b8d7bf2a4aca52436a3f993f6164666ebb3c38317bf5b48cc7182c00d58d4a095d0fd4c60e4229e77803c4f38f22464c7a4259e45ac71e8ccde6e5738dcc798777317f9847f8357dce21b24ae462d0465f1d58203f3b8590d88deb9c6df4722a1420a9ea0813ec3777a6cb11ca0271292b6c662a870c292291164004299c82442a8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c053203f265bab420eee2c95a5960f8a87c3333785e1b89ff841a6aa5aa964f3a853e512acabb60e29c3a4810df33830134c0e49bc5e1ba41b07b671e1ba6bfda82576406e6da854920a46914c8ea986b1d6a0328d4a450fc0ce698b9d16954aaa0c52b6f2b5ff7b5347e84c3af403e9b31ec180238cd5af96f5c6f0d3644ab51717f7255ad6551f44378294778937cc56b610680704bfb37e3ccc07c5276777e37f36623dec8225388c3a5a2c7026eb902c63260ce27ffe657bce34a47db43667b9293e04ab9677b6fdb0b0a429a4435a9f5624628a2c07bbfa8afed562be4233019524e67cae6f955226437433bc59835561c462071ac38058c145787c242d4b6dc055170675190882792ea49726dc8b2cb638763784d3c23e1791c93a55383a8c4b59643626f8948d228b670312893ab3ce5b123401b1b24432545889d4d124d2b846070c1663b87a3475c01adc4f4df286fc91c76b018c05b5a26a696df86c4b1fbb2ed3050cc9b54ca2786839f854b9461655972fe21c3c98007a693a4d0b8aafa3ab73f1c411dd283cce59528477b6e089847ce6518f29b523602f80ac573618070bca649efb84fc3947d43b229e05682914c153809521ec9b7978a6bd667f59b18f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734df18a218c5bacb364c9136b8e055053567a1856c21b96a1a2723913c98cc364bbd1fc4edef37e1853c523727a6c677ca4c82ac4d49238e1b60c1531d1dc9835c4a96124a0011c09350353aac4568a84293e8666f6016e56c38371489eddbb3df3e53e6767bd01e231eb122f13f59a83a35101844ab389954e8068f6d7128c738ac1774edc6465eae8ccbabcbb41271467c407d36928d9e3174c99665e3a9af0fc1b2733925b254a3aba050ec3925dabc511427c0b2930bca63ba7629366c1ba620cc0d7090752157b5d70c098745e37db7316056c7bb37c024226425107da8ba0e9c30e2606752f31a017e50a0e10c05332677ec851eae14f594a55d07392c23a962248ccee1221feb2c8f801860892b33ef2247b801e5ff55ba97675a71037fd133133840050b8b7914125e9d30165847319eb1e483005ca0bb8338b75eed618c47408d0260ddfb1527640a148f29e64f65fcafc59a8715a8126830024767009bad41a3385c0173be51a35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e287096185885264e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d35aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +ciphertext = 9ce63bafe883f7e6b5932e071982bc35f643185589ff435bf663b9fe433014e07285e8be328729d3d01079bef62ee178fbf8e7d9ed1c2529fd9912958b8f120dee444881a4634d0e96973b8c47c004b373d513ecffc97911b53cf0686fe2cb8fd33eb7c0f50fd38592e9b7f73d119eb8b7288e7259894812acf13f81191f5f383279dc7c05f290e580f6e0a2e488a002071abbcbf2cefc4bcb73eaa86ffc1314e120b8a96edd6c0ee4faabe7037dbcc63d8dab849a55a35f39e75502c961f1051008ce4c9b0fe062cbfcb6bbd6d99ac1cb24e979d72d39e057233212af4afa92a3284b1b272509d0aea213d5f18e5ecee943d90cf8bbdf9061b7da7329cf363e54237ebc2f07de66ad90cc12744a74c6e5d577c8517e140d64bcd40018995143383f5ddad2f7828163d25f9c3af254119541fbd304b96f70a8cc9822087cc2ba3fdcedd9529cfb7137991dc8842c5cd1ea2cfa9b831f507c04ee4db010780fd3703e54fe7748597f1574683f88c3a0e8a5bb36695b7c5b1d6f566f318263f3777db8f433019b287ca1b8406e7755426e593134880c908ff7cab24f2c8a446dfe1bb1b51a546ef9ec43ded91f7ec7f1f97df2ee83d8f52ac9e174639fe9591deb37b9d9f9dbc9d1be6b2ffa2e8c4b5eac3332ec069e9cec31bc7d21c5253bb20ee61ee701985a8a73cafb73b479cc19ea62b998eb85cabb5b4ff462088255ce5cfead669cf5e17871733361a9e25392a8baf8958bcf08da7bfb12b3b174acbdbb8c9cc1a87b2f6e48568f19b1ccde0e9f59ef624dd525168ce64dcf1e63b0c118a077cbd7b48144234001910dda0094e21d0abaf3741aedffbff4dd92d291180c67e3a253799118eddccb6033e3f450ecd84637b563dfa9010a2c07e9b4d4d55fb71c7cba9485b612561ab34566c40575c4c41eb9ec7d0c08b100421b7e07af4c864b7d8997fe4458867ff0cfc02b001250eece27b8e8b71a1a04983193520762f4b7c4d2fd289af45f1316f89108f19caff5703960efb9ba42823a6b9d9aed333e37e5989c8720341ed60f4b47223bd313b56e6160fae8a3bb56f97ab1092a7e36e2811226f9bc14d63bd3f48db4fa2abfdc2b7b8215d4c5afa301783940d3c9f8f0b48ef9c35b02e272a7725c77af66a4c3f43f7da5852569115857f7036f7fae04db993d6a016913c8c24912eb8c6c68159059fc3c3a4dc6c47da86cbab270506651e2f3a2fd268f81aabf83239d885c886fe85df698f72d019aacae6d59eae99e2e1b10e77207d047659b00bd0cefe7d675d7b4b50669056e536539a0c29d35633c6a059dc09abeb473b99a85b067d665374209a5e2b729642d03bbb9a41df15d8a2f12f65d32c965c0f883c6acce98ec4692cf48c55c7cd4e5ccca0e93048600b3a37fc6b2cc617f03926d033c2b6a4255968cf927c665c601a9a23c58db533f67f65e6b501d42ac65365e14c0180349580ed85e9c5c1f4f0592644460027830ec2470287d6ccb55ca108d34bf1d373f27e46b64b848834c85fd585a239d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = a428a13444f9ce9c3dadbb62145ede2654f6d1cb5c69c68e7f377bcbc454aaf867781f58fab6f2b6367fc5cc46ea6d682a3984a23f30b3d7c25a69ce4ab9af0234a109878e0cd4fa9b858dc559ad3ff8fc416d539c08828d5eb337b7c0ea768ba646a2f059d0a235a4042b88e8934d3c6f821a13b67baeff162aa80953cb71c396d91b91521b666516f552eda6ce453c233460799e38cb16ac6e598f670c70d73f5804cc494466710d984e3ea551f5ec60c513ee955fe91906fd311e81831b7fb4fc61da443fe12784cf84b5edff40daecc87e8eeaae1d808ba6f33d345ba81bd469797dc03583214355e8e9a356e367a593a6898355ae1f9a8546a0d04bf27a1fe88adee8db3583da79ea9ad544086540bc2e78b31f5f00c94ae763d38486b6cefecf7e6af20239db4e5ac807fbd4bea95678c5fff76c4757c68d2ec9f83b8766f1a39e06c999016bef1d5c3164338aeb53fd54b338c46eb9a7258981555fc2563e585a6ff60886c32343e0045746f5dfe79ada9bcbb6281abe3474ba51fef67c3f76a23f7a901f8e2b5ab0786e8c5aadfc35488553f745d3adc942c8ec0aab7afd0c869b9b9c67ce847257cb23cde8b82bf5c468a9bc35a181bd90f4bb90c4fcd35d0d78b7a9d46833cd90f7bc2678cab9b75b95a6b457dca8fcb84938dde47aadb7b6da9643da507a2b8b1bef53748f518a7f9bda8b35fcea315b3b359705cd5b486582379093e64f4323d9f0389ff899beb4c3ca9689b413bfe0eb654f183362ab8398b1e3696df7432be662cbf6f66657ef2c056504a5c1ca2de7a73f6acc83d6534d58fd0937ddeab973cdd73406de066aeba8655dbb3d93d26eb99e698fc778b2fe88ffa8ec7c62e4f2e18bf4fe1d7b87a8338ae7af6994c70d959cbfc3720c3e74b9658f5d43713cd47325eb92643dd73f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c30ffa1f4a8715957fe7d7a4db9243a1c6a636ae5d735b870f1297b6d6b5304ef552a54aa5a9e340ab4d301dafd6bd9a765c7ffbeeec3c44a7649ea350f0dcde5a6f8e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd5442963e7b55ea9ab21e7989ab7b7304304e66e2119396727943678c31cf3be779c946b834f0a557a8d74f6263d33c807e591c7857e90a7fa15e58e315ae1aeed46249b3012bf2291cae316ded1423674824b852c34c97258aba7faf6d5e95ffb2db6dfd5ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a52aae872daf5cb4a99c39bf25e379ace27485d8b91fef9ceb98cd4322b59f533745d23720ae457fb1eb3a0b831de777d07f88ed187efa1d89db9acbc7bac471be4f3acac482b0bfade13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65ccfe6e04875754a77025985b0f6adce3f1574ab45cda47134b560219338fc93b0a398d7f95e69b4b32c2ec3a075f9f8e3a57fd353328bd3f87d5cb60c67074146fb56d476d9f619dacf3ba7a371fd9425cfc6486a9f95a1d9cfa2cea75ab9ebb4f35af63c6f8648ae7855a4eab5c9d49f3386996181980b17bd2a63d60e5a64a8cf3ced087bbb49b9264faafe731c0dee965ac981965a28ff907ceabac477e2c9b6dc95aaeb0531cbcb65d8b3f6251be17ecaa89a5b57c1198ea66af1f4461b91c360e4531c4d49269896107f10ed1f1070e68cddb2a4e06c387f3126087a71a366a250b450be1567dc957bbd034b66ab65fd4eab2d89b8481ec2427a4af3c1b861c799263f492779053a0128508c86ebd6201c876bbe8ab8053b790314047a1901c9f327207b2130be5bce8504bb03817a380975cd81fe0c0416986a7b74a16a21146636abe4d2b2c5c1223d39265a6845804d49e5f160abfe3ca21a345b5d044afa5636c37b976f2894869bf4500c62ae9941b9b3c3e6064fec351268243fd75bf287cae8aaa9aaefc1cfba1032ad2623a6239a7f834a4826f86132b59ab24efc9c57cba929a64ba90271b987bc08a913298911650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348c6063aeb0bcee9066028b3340aa147b09c42752cfd6d491ffa497e17ab6c0726aefe59c2577764a1a996fd879e58c23f1c0ac9e9372b3f0be42c829b7b09acb722e3189a2b3e72124895ccab565dae583c6c76c34c2c0075568379639869325f6e92e0b91a2d4100b2f4aa6486b756cd521e1b781a964a21b8b0c72637a2e4299fe15c1ac275fb077cf42f36453e7603c91a648e09cbf128ed188639b7247584b333003a2175bc587925111654f24680c540b32643b035ff38bb4598785524504ebcb26163d513867d74744c8b562bd48989b3a328374a125ca05fa962ac08b0d22277e578206a165a9e3d31a084b4492c664448aa62986b55fe8c8420816a5a9c035644f592969fd0951b6e9aa57303d1f9927ff6b3de99263e2e11cd8317cfc899a45706746e9850922b9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc56285e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38c807f7274708aa0587f94a107089a99694fc627291c30fd6b0430eca692db54a96019eaf89635cf54f579a63048070b7f32dd2c32a18e2b7e8400344412e9dc5943bf3af11b4aa6c328499da7c220670958a22bffc89b8f0091c8665b6605571d8a1b5c934ce4686c7c047ae416bc6e39b7ccc92cb076de94001374217e9b8820354351cb377b4f06b7fbb69f64c7b48f781ded2cfee998718d875eb94866e7c5135358ea4ec92849978438c77cec1ba1803bf9933c8856657c953125eb76014bacca8ec9be6290936130d166b187e1463e55cae3ad85e96e81bc574220ab0cd374aa1f657abea849259b4431f1a00ee59b35486beb09302bf71b4c2e840963333b4a3be37f8048d42a0f67c886de9b47611555495248ad4c587577d45775f52135518793ea14582bf153c74210c36b9251609a4b28559ade5a93203725a475971b92beb88a69357bf83f384577cc1dfb62c70fc65401073c67a66af878fd961bacf46c633e7cac0e5092458cbba0c3b69494c4c0c0da6025cd6516c1ab89b3216bb9ba123040051563610251974a0b11be7190504522a128ca3107938f5b18e4441b52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb12f40ac971cb475610a0e6c546998dafe5c2ed852d7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c828dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964ce63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +ciphertext = 4106b63bd9cec4d8be3ac33234128e2bc1346ae6388357a3258c03ad9689e68cece1992893dd26409f62211674a84155d1af8ba9750add112f33c812c04adb0a1a59685ca91bca59979af97c948d5443c38894543a225f05317c22e6a8afa332f4cb4dcd6638df6b3a0efaeb8f065c576c06f8cfe3cc0b3c823d0dc638e2203b886efbd82e6cf5216a055e364de238948c55187ba2d5503a3fbfbb684cfe76da66ab53f97ffaff0322a1c0224941e8f64e3705a2e4e9d58d022d31e6403329b220546268abc3220bd49db91521cfd149fa186474001c2a86c407ea8ff96ce07cc335b3cb692998ee7929e27e80cede8eda4406494d289f479f15c51d3ea30873cbc9e5ca00ae20df9ee94901542c02ef705e068f589a4056a9521b6e003a345afb85cf66319506ca2f5a75d15baf62c6c5db502afdcdc010f93cbe1d1fe4212d6796f7876c3f1417508480678fe36aeb0715cd76fcb15f4154a7006a073e55ab89fe90b708e05279a9d51bb83d268e729e47a832c2a93642ab79023b6aa81063cc2c82030012cbb2374e005b9f0ded74e82aa174496744434220d74afb7c018b93555d9ceb8a23c5fbe22744d8dc9381d43ebd2c8088db2c699c320f7a45fcbb2003573157a848459f587b22d571b37b94a76575f1f2341085e08e31ec55f330b66ba4f5040b199dc847262f6d87e8ffd3196367beeb904241f7e0c09e9e2b0094a26ef78ab7ed8e7400bab8094b6eb75601427af06fb9a3ceaadf3eabe93a4e3aed4b8e1a72fa616f010bf0642ddfc84dd435e9ed98cae09a805ec5fdbfc740d6d218cc7ba34790debb2141990a3402145d48ad84548d5d2a1c3455379f1c1fda6e6b03cda2c6286f9285e9f4b77aa6c82e7254ad5cab2c9028a0e47084f1494978d58e2f8bc0ee2c7f2cbb38f7c50e7f60049feb80073493b1cca02a700f0d51901869432fae4687e11639144785a8c53b285ab1f9cb7bffdf5c5bcd322684fc871759e6d43bd61bd450cd69ee905724111e11f3723eb87949bdfdfbf769b76e5239814eeef6d5ad7fd65c8e0c32015868b9756f7f96afafef2861506e882043d1f947e7a21572575a475b0ab0d11566428cf7714f1497ea85de68282038563fe43e72ce17ab525e93265df6d62d0254f9c69ceebbc0fd6a30e37d2ad218119ea8d4aa85e302e4e70e25e2428032c00250b14f6c434f2b02557c4d8367792692fb31e79259c76902bcb37c4c00a1beb4ecc502b7c66412358f93382ae592a25505ccc42fc8f02e43ee8e8ed6a3d93c2d9505de290ea8fca4519237b7c76a6ca6fecbaa47e7f519f68f118ac54443a5e7ea238a61a1348ab16fe8bf1a1e39462babacf98e39fad4af8033a0dac02c806ef6715d6d9978e9b91d28cbb6b894898de9cbca5ef3b49ce91e19e23be8b75b187bfdb14fe943f30e11f253065df04b1863566e456c0f4af829d3ce3c88f728bf08e4b38efa11758a308fe6a2a45d0deca930b9929a51e72b7f8da6a45596378e071f7bfca861117f534573b35e994e +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = fa198bb15b42795d9dc34fd02c75a8bcfe853c474c8248b50638f1e4d77fd598d97aaff017de7377f76a89ab9478bed24c9780fc7f8f6d03fa5666828143c52ff8e7b9688c70eba293df716ab497094dabc56d3f597b5fcdfbd1458e360234f626ad67ea48b426738dad0ab986369aa63f6dd199c7231fc59bcfdc8f63429683721a2c682c5aa853b86542698732ab86fe39c340ebfd462f86fdd599336b9923599b67ce44c0c7848d2da6989e33fb7b5efa47f6a4f44389cb93d6a9c1b7f3d0cb95f699cf36ad0db2855861c88bad063af5423362c7774c1626834ee5988086f508fb51909f6a3f475d01aa8e5c8c4140537091d494af66b0ea4f635913fa2264af67e63542cf408b1853f87c68c28c8c144e7f94d77f6ac3315f23405c233e14f7762c25f609ac34842553de175a70eec08b44baaade5cf09a604abd5b6907eef43fe7180eae92dd50778a6754e374888e69182afe1336677889318cb54218bcd5559eb918ccf5540f316725ec98c3de144d403e0c59b335ff4d0c85ebbce877798c41aa43c5c7b738b7ce1174f8c049370ba6665be646b41f5aeb947b1f4bfec5357c7566c13ebbe48c453d6c2f74a9295a06d8f2e0aff2cc3df6f1a6d3b67dfd08d46d4d7e384e776af2a4418958f6e4559f5975c586e47bc0236b4897622ae439626d334cc97acb2de8068e4ae44786d1e445147a4728275c32554b9cde48aea6d5e10c5a6b556705fec17297a32ec3e1f1f9fee6fe60e96ffe06554b93b5c796e44086e75d236ca88ecc533c3b34819e891e35639bd6cbdb3a40882db6e3b3f8c4268454169267a5c53497d3c51fc58846c193eda1630e4600dbb3524f4fa9dd599775bd2d95edb5bd7438f655aad6402628563db3a435f75d440636cd74d41eee62d178c92359d83afe90f106be012dab63e7b3ec7e8a4fb59e01057c416c330dcf6e485a6d9d7fb707eadb298cda25247d26e4df044844c2db883a5bbfc3bd6f1bfbccc7eedb65c9bdbfc8d6d8ad4cd71774de6dbc424cedfa897a061f365cd54a90ba6ac519f98bf645536358384392538eaa406cf9201e695cda995a9ac5f84f35166db38f97f0d673f7b4dcc4762674434e679247cbe42695b8e8ec37d7e8cad53d1c3e8fa0add757267c43b982f26639912df8f8f636c45d91f1ca90a1f3f9d5dbd69b9e8f46ad78f33ab4e0df483916f7926aaddff47ecffe718b3bd48304cd40f7ffb097fb6207856b6ebd774d34e82bb426747406eeae5b93c63dcefc7cfd9e48ef7118df6accded2b043616f6db7153e6dfc17306a77800ee87e03e4b74759794ee6943ecf74afcea08197a841e68f269fd2b21f4803064f6f3f95de5ead18949a5a383a81363bb11ee8a8569a39de38bf8835362c723e999402d3cf729bde11f647ce2b93916e5b9f5d487e23cee6f9cefc5aece5e83d28d642e4ce6934b43931158ccef3832a457a5e833f3189e88598d7ab084f687a394c257abcd8435ce7e7d1e6b79e78a37bc7ea2377f9839b89aa9d5b5d935afecfc1e6d7ec597898c6a69765cad5e9784b7849c685ab5b6de3358d6f99d8a4b075045d6fee5b63a6d1aa95603a67378157b54889c3021453e383f08ddd6c0deb77bc962535672a8d77c9eaf9726cc1a8b8d87d61b1461f33b7f7f5a003a8657297cd100324fea561ba879ffa75287d9a838275734593abc2b842d9353906334d3f9324c7d00eed794c78310421db45cab6900817348d67490bf1485e85a3dfa255694915d286ab5243b62d3a91f8493f0b19626fb89c0b9109c6e1084bd8c848c06b3472a65a2646dd89be2d922a0d2c5e816652c826854ab36f44809ee56c9f7e26a1dc30823535997a05255756704aa1029b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e512b1c767347ae28ae046076c20179d0977d2d54a3f78add2ec6bc06071d9447f0461846fb1a5e91a760112424082c2994a98d07aab29e818fd15134de437c7fbc59469ce8ba80545a4a5bf337fe142b72e602d8a1b3009cc95975759ad38274e234aef0552b8aa65cdfcac975495a84c124f8426a9c87d8db03ce48b0382642cb9e31ce210b774724912b09b16d88ae007ac4542c092f9bbed9c262d823d9d5719b357821d4c245f384fc923cd334b9dff579e324a0bcfbcba61fb7ae9f69b3ab88693e005ee32bd1a6a3ca950a22421125391a060276b07242a795085d0098906969c421cbc469128fb5393b72590fd391dcdfa3cf87b9f7a4c6cc3a1791ae1717478a5280a3b7580bbedf88f0dd7c1c09aa67d6b284334049398ba983bcbacb8c56237bc3efb3fbfdcb358a006457832df7a01efd937e68b3299580cbe1c9f69e165d22683b3721e4189adaaa91846b7717d41baf8d9a1dc76c387f0b55c2552533326597466ecf06aca624fbf73226e471d835b0ee4a24a8f1c5fbe359c61d974a4d57c2f7c49822286ca27116839b784d6782c13b606b87804ba0969c7c47c7a29ce16cecff5514028c3d84944ec8cab4b4acb5b681723511087e25b8ae84f3741a2de6cc21e7a370b35c255c34555f29645d4b420494c4d993ba3f092ee240f1d3691753420891acfc9421c361ca2186b563ed63456096227eaa738a33ab56029976c1125dca790114aeb83aebcf271ed59bbc2e8377301b53d697cfabb4c6b40bae19b6cecd421a1109f9cac7b71c749e60a2005a30179c393d5033cb4f8795de4c98d91538fb9a8cb1654b1e6a82918471470461f54cc71fba50deb3e1221c55aa616ad5262e352adb7a89ca04557a2090fb05704b9521809b8cabfa325892ab46765cee83850586918422212c812373a1c6217ba890b4c5310f7b0d5d8275b884aa9e4914c85023ab53bea88ad4281a7f501a87534ac1d806b0f8691e9f1bc7171001043015b391cfac09b5fa88f840c63194632bd5a012b34b50441ba08c879c44654f136cccbb7114f7b4099016e0193cbbae63522927df4b740b3ca5b32b741ea15a47370b98926a1f90618f5235357e8087443c93444803dd22bbdd5340c876d41f3ac1db59e9ef17db71369a315600fc6801a54483fb015ad3766284a97cbc241ad73461f4b2a0f6645ef428805762a6e57474d29288404ad98fab63ae95e25436626bc66ee10c01e55103597288ac521b463886f863833948455319d3455110b68bf7bc495d1a922191a1a230a5f036c3c4ac05ee2609d09891ce368c01f037d818805a566193a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463fda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +ciphertext = b1ddab92816e9b3d6c9414ca303b6d420087f1f154d8fb5ea6dc1d5508e37f6edeb9e00b1fcb7d14066fc3585c6b61452303e8f76c034cc94efef7c29b703f2c5f997b2e3e73ced4e264bb8d940cb26ee5e048c7baedace34c3404752746593b40806baf5a7d13d1d4f43e7d178a85d3edfc37e840f7d7aebe4748a4a6f862073e18e916f795fb9305fe250574f2e7de19aad589e2a2640167d49da76c63e0dd54065e83345c9672367cf0e64596ef1357c0bc580ec438aae9b9293eea6bb2dc43eb39069e6d409ec1c61633c436959cab8f564858a835fc468815fa445c647fa6b4ff9b32a5fe4bce0ace00e15511108feb69fd12ec24900fdc7ccbb3ace5677279b33be301ef70247b625315439c805eb3f1d68ab316635cd5f5eb8e9ac9439b5278bf7df4e58da1353508c6601af0db94691f15de3d2fa21b5e2ca7052330f55218f207fd956b2aa774e0920dd6ba34041c0c801b69f4c3feeb1b6d64d78fb8d3d8b4d13792ca75894c28c1f172272a99799fcde0c9e10eb3671eec271855eea93d50e8a341ef680056eab4da00cc43c38207aec9d678c0d00b64f695aaa6ae2ba75d11f275d2985ae217514407c952084b123219c2a119d2257c1ca1b635d770cd1a01819d03a2d6880d6b0ce1b8bc59da04ade0ae64b543fcc6e96495bf5fb5d88807d5582c36088883dc14bd616971f1d98ee6083dd74a2bfbe96dd08d2711798643a84f07aecdb2f30797cc98939f61fd5d5ab12ae0dada77ed40c8187ce5e505ca5e8da98c7f5705c252b0a6ea56d8e347912b854f414c606d36bbb60aa9dbf30fbb1152afba2d335d82eb865a38baf10a01ef2cf5f16f06bc826b1f980ef49ce6e7e411a15750adb337b3d3e7503b3b50a3db53ae8a7bf59f26fded1abea8fecd430cbc72f4c6b357bd30d01d4d03d70f07c2644282c133b0408ede5a61f797b01d288d9a8326ba620f071f4823e73328fd2c18e6a3376fe5b41a54f63632338b70ae5e85b7bae061621c35c609a6c2754229a57f65d8be1b0889a148fbd19d58c002bf5d6e4651a3feef2fe29dd8732211e9dc7a68f8e2341c33a573e815e67026bd559c398121ccd61305961194f69ca1c21debc8caf921f54a2ae0de9285966a9d0a8720cebbe6d18363b724be75e402da9d56aa1a13ff4bbcdcff699adf148998f5e47f6ff9a43355687c8c7baddca273b8bd337464a42fd11dd33feaf6f3c218be2b3a3817019a4e4eb9cc88529285274d5c5e5c2329a42392cc28aea4ae431dc29e6d33a8542fb79593d93fc4d7702791d16ed6934e6d1473dfb21305657d2e57b5032388b1164165e3f6446c024bde67994c7d1e9fb32ce1a9ed53094744f08a5e9fcd34c390313555ab80a08b45f91e2137bc555da994a3951711eb699f2c0ee681e2abeed06f017798b5fccb3e0a8ec4eb880deab51ce1b21507d47c3065766325f03032b8b747c63b0feed45cbf1af5eff06681096f49b2f54de23430f165ad9cda134bfc9d1554eea7336094381a91b75e861d39416d +expected_result = fail +expected_shared_secret = + +comment = Private key not reduced +private_key = 55873ec8c5bac259501f0f5faee3f7b9b659b19ede7d43b8bf8af5a9cea5116fcfbc9bbeab28f7471967989e3398ebec1cb4ec1cc3a8845dda29797ab4cbb553076c214e67abeff08365f7a05d4dd9a476985362898b4e4248f1cc2642c335c3c953c86655eceded3098d5a2ae366ddbeea06e05547e2cdc0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a9220be4042aac83a1b4897bc6a15c87fca4e44828966c49b6cb8f842a3157b60d6b3271c36625f9d8a93c7daf7b4de1396309cdcbbfc9f9856e7cbb5b1825c88bdbc4c74c58ef3d54d08a6e3a6a431e3a59ad05fd1fbb6828ecdd61f1bc514dcbfe83df3d09ed2e9834d5d6bba8a354fe04c6008b37f9b07857ceae238f5a563ff88f42e7ffd2aebf9bfa0fcf3af041dc84bd6cd806cf46c5af27c9bcf973d93a9755cba968e7c06cc4f987b526e71461b69e023d76cb652c3adb10f2bdfc9d6b583b9f9fa49d5ba4b6b42fe9d862c82b6fe70277530a278773fa740eca749c00a61735aa1a287e9cfb75eb07689577e8239f4323aef5a316339db665eb9784ab69ee37e1fdb9927829575f2b824b3ea4cb540a4b12ad7c512046712bd463f779e1279bcd2c7f3868dc72d06e3095d376db48978dc717dde424d0b5e743eb76d0ac0b024c6283c8418e5b1a8af97aa483e5d2a65f228eedf3fc69cc4b9a8c4c0b90bb17fcd6337efe00766aeda3e876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb7376485d4ea2af9d14edbc2d16dbf758d34515ee9379cfb009d2b9b4f66428d2e66ffff9be9944adf6b123cf9b68f700af475689e2c46c88cffdb41da5f6d227a7236fc0e3c3e57dc4898e07caebd8d3824fb5172a799b8a6db0f770383dc98e1957fffe3d5d8bfa52945eff5c4337b6cc5004bacbc4e9ba73568aa357f61c70383447c70e5a5896b9c1cda2f2c7a76da4d278d736d6b685f4fb3cc49fcaac1830b439468b6bc73585b4205751e66ed30999863097d2a47758871ea99068dd88657024fa6d3715501424d5a834d10a8f4788675d2546afad54628ea3f81abccae4eac11e3ddaa5d4da9e54dd9f2a40dec3ec2688a3266c9e16c6d461087da37ea1973374c99693c92eef9d458f92ac3208268079be77c828d38305ab421b6d82a7d6316ebb37fe318ccfe08163a723a4bfc4cfa25f958f29bfb807ae5e441db8863ed3843c8ac26c7773084f209fe51d6fd83e69772a0491240f7917fd39fd08713ba8d39f3b84cc83a8f89bfc19f48a958a443339a5a2158dfd8ad8d11983602ae892a8c1152c602eebe592c3ae556bfee54c5dc71fdc0b956270cd6d85d78120bce35fd369de6b6aaa0fbb015a7bc3cae3a749e960c533d3fea6278494e78b6a3c5b91a3beaa2a0752e6cda30e33cc86dcba2f3f32c98b9aaf1bbdf9f8f5b15a6dc3a741d43a53ec1dad18e93542fff4ec5a952d673984a9daf0e8e578debc84bd9856794d127d7faac63a1e49a79a2f4b51464916ccd7f0a69f07ff6696f5806f9fca4aead50cda48a9d9d635a9c68acc753b8ee115c35488758a68256a32f4964c53ed51cda8c5053d1b5ee26aa5f270b3d9f69931c42e94fe3debc48d9db548a000558528441cc07c18856568c4fc0eddc04175f564bda148788608b71756367551a5709127668efbd60b389877001b948f2c50ce62c7ed63122daa7c1889400a4175ab959d09ab124bea2c9d3659b8b4861e482eded950dbf57a47c87f79fbc143d20420f4162f711963c47dcf7b8ea7faa329d6a70f601d3a1b15a7890804917c84477d95f916a3761e3d94a0b0d69d9b7c39692b7f4acb9091f87583810ccf67bdf86c4be8f08762f2c3428646a3d33df4b67eb87a2662353a208403bf59334bd9758a9439f8d8bdd45195f2255282a73456d168a2b249e8d180d5b310ba828685b3a1daba2fb88783bb5062c13b79c2b0c3a10085664377eadbb477329567d1158882085850b95697248c6271f44988218777d33823ad70791bd40e29825ed124b963e05d06547c740a5ab7a1488e38c464b53b6f016ba1b7648a14aaa111907846c5df162f61cc62747386915724a3b054e868bc04c934d64b7f2ff461aae980fa806cca7a9c4d7255564b420887946f7a72e4d1384d8222c70330b09c08d9a70aa176529f0685d087b8f9eb464a776f93606b05d0729fd2afa7969eec2662ebb7c7fc821d6b5393707acf25c0c2c81702cb195f8cf730e8a46442e91e18fc7577f4aafd6933450491ee24763bf6786d794d889c3005a323cef2a8863c7ae00998d2e3ccc1f5a6c8a933d5d615ce82af312990969c6288b6893c42142ad87ab483362461b87c641f646410ef5b393283230220a34730397188920b6873f16478331cb22a5a2c73273d865985533a1f8e109dbde719c10c8ed87a831ab65562751ebbb15d3d5b6e01f78db26a54e47943d6b31f916a552ed01a39f96dff820765d6ae52265010545162d509f6ac3f9b7c0fd0ecad4008732d6a9df9449b2017b389522f11870704127bc6d018e0a420dd441ebf636c31b3b63da9c00dc15be0b3188371bbc855254217b99294815d78194fdabcd1970e31e38d37b4b1cc69bf428514f50ac9bcca9125e6473028571be535fca274651752dac691ff8a28c555036378b260acb060faba9573b0b65cbc76b892425294d65658f4a1b3309b424c6865bf1ab307b88022087f97f6882d4360ecd91f3d2513059a784bb256e47670afd5c1ad5c177142a2955b082fd0b546577ca5286e0f1c85af8b0bd5650038609e8ec8344e6ccb6df93a056644cb89294fa19266948e9a561bfa66517a900b67f6be5efb853c703ccb4a296a493c24607a6ac4a749361d8f738080a80ca62aaf658b6a972894e6ca402af3c09d2a6e9c181005e0c4d193361859011173bc8b97755fd1085b52808373b29733a7d0488c5f890364abb9716920c074645ae023679bc9c2b3ad29b9051a94a124a43688a1027c35b90f9303664aa37aa92284f97dbcc7ad0f12b5b6ba38ce0a07130110518c74ea36ca6d6a44399a3983101458f926e0bb3357bac5a294446463814806ad1623185f295d27f2c913c9608314174b2bb8bc03a92db6cc6f044d964a7e3e289ea8f064d9b5c0d0eb43357495d09c0fbc4069903bcdc683763bc4c6acc2517b7c94e3e0265029bff55773421bc6143a38f57410bfb50bf21bafec948548a87667d95439bb78cca2c9da670beb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +ciphertext = 968bdb85e8be748513a831e247218d164bda5f1f8f433ac105e0798820c1300777ab82383d265ac6c7464c42f2f1b82734ce4208cbd57abb0a0eed81beea32d430ad955c6535d8576a4258a148d8ea33449ccf1e63b4bedfe1752a6006afabda3f7a6f6bd81bd49065357cc1a2b4252faa112997cb4d8ce361dd76c9dc1015368e8919fbb67709ab3dcb2cac18ad6e8c06e05d1586db41ab3555a43e5b0631022d04f5e784874e3a68b8a2f3ae31f49279fcb83c4fc1600870b1d25e433c68339aa9a5bcd1985da955149fe2fccf0e1c912b435beb46a083fcee0c924acdb192f87504b27018c27a2db9c71d4d870676631b4b94fb023df02f6fd2b97f84741d8ebbb055cb786d0734b83cb2bbb2f094a80b204a5a257c770053e94373d9e9dd13dd345fc4963fc05243ae659ab7be475519f85956d2640068e28bdcf7dad6b44372d1d032de309e4e228cb932bf12f7da347acce0e24bfdd89ff7710afeaa973f735d7d69574dede21e4099181d0c885be477d176b19e79dad497f8d46b8843456a5b338c37aeece04596e6ee4b74dfe3976449627deb97e2fd6ce4e903ba2b0adb9396846cfb0996ea32143c4188abcaa15b3a0f38a44625a52c62fdf3bb9cf81e1e6e0cbc102e251a91eaefe8a3e0c903414397ea25321672985bd8d91e07e297b7472e04fc481ac17ef4a61a4e618d2fb3aa728c80206f367d5c44c29ab4704a405cdff7c6aaa34db06cefccd64ef24370ba1c0d2204069c1a48f0556c7664cdd5b80600c466da748e4c774a4784e15234c20f7258cfd998d764eaf8359e69c3fab08b148b634257ddab72777698e63b55f817e370b804851c40b642df365fc97f73a0161140b127ebd3affa31da4a2f59918b095ffd877739e3d1d7af7455e99a5162c301a66536d198d18e2db6876e7ad5f95422a3e363dc637ce45dc663a975dc0d27b9e92008df453364256c3c12acc52e7e4d228c931dd5fc4465151a4d7b453775ea131dcd06dbd05f8e8a9001dcca04a23b2d4d18abf23fb50484a382e1c07e33f9a2fe69ab38ccbe51510a9389c2d522deb000a66d406b2b09c29fe4dec4cde29f358e813b72b38ca32afbb5990cc37f06cf18386e39a06cae8529400fd479152387f0c60d301344666765405ef92b98a7379e983ee89a5104cb3306a296b53eb2242e6fae55f04cb29d0c875bff6b1856439375ad697c88673e49b8753d4180db24a28ea0c77051d28752ac9cf6c571b129fd91c3b0c79b19a6b1afc1b72d1d986658740dc01a7aa7ac69144e99af53089e072be0f2d0e173f579f91acd0047d28b1259147fedc28d0e66589bea1207479f2c13ba9e4896d45a715e0aa9a401f5b5a35e29bf1f791d45ecb581063d6a82fbe7f623ffa5ebcd804932c81904a4756ab940eda4c4c7a4b69ea22701597cdeecc857b4231fded57126cbd5fd91da14548f5b82cf33605abadab82565ec80bdc6f63b8366f08a2bb9b252f33de69f13ae4dad178897f8ab66565b2e0ebc143427d35215ac75f4264e +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 2c2248ae4f3164c9838735fcbf25fc5e4eb308 +ciphertext = 21b025a34632b66c0b44eecb9c03cb7f59a7ab0c69921735159e9f61a93e835872d753fcf9c63092c52603d1cfe925fc743b0733ea1ad6b5eb612e8c4a5fcda21d9591cc850df2ff062a0c597196f003974a2bc2ebf17bdfd2e83deb5a9ae17f97b6218401618d8e46a6d4c8dc9664a455aa8a70afba1d4a233f6428d89ca8d42afcc441664d717fa8bfd11ba3a70be3187bfa4143b17c3b67b7c351e8978261a7f2d2cdfb1c402f2409994f0c14ed786c7cfbefbc13a72a2ac14da5d3f20dc4aa4a31baa7d0d0161374c030aa3c9211145c846859c5bec34247a06aacb48e4d3fcdbf5edf69eb46062150403de20a0f2dd98023dcd1a555c946284d6abaf785ee7eaeec63b457aab6abe1c7b2eb56de16d66693189eade5e97630e32d785daa3b91aad9eb51d464ed8b8a9ae5e8ac9382087e5f9303417dbe3254afb4229a1851ca451287229919783066072a8528f15cef27a9d61711e9704340d93fa608b4a5fc73120615b308ede1a7e7210ef4f32bbf32f4dc5a30049991550eb8a5c2b9189936f0f7bc5caf0e3b66ca5665e0a390a912ab0128a92c5977f697c88dbc39219a410fb89db2405319ce1bd5dbbf3b2cb15858f1e7465490eec4687bee43f5c3a65a232ba4cd5f38a126c7c268f9af5fd4b37c1653703ce89d5d574c9adeba9b729659ab6992e8c1adc8745b64270d39fa93e9ff66235af80c9047d2f37dd6dea72c507a7122dec0a16d7146e63eddb2df5ebd1e5ab592259b82a1d2e21707bf5c32641d8a947b81a2fe841529e2c76a795428dbf2ce21c321ac9f37b493cb31297844b16db0c81eb8329a21c60c6762d331975c935f21809b65ea29d318f5e8856f69f80a63118026e821c4a9731227d4b8949e6c3caed5a2f2b2c39698ea6b34bbc5a4779d3a6b850f2a92a3990505e4ab4c139e53a8792036ba32f5b6d77303cbd14c0f2cafd09675176468672ce9d798c9f8c27189314a219eed4d3d9208421cd7ee3584d5ab850870f7a8aa7e828382a6107d624855a58adbf10213039cd4f471e888c6aa5d3300b875e4bce31f4e4bdeca0320000cac4240bfe0dd427408d108a5ae0aeb81b69ceca597a143efaad463872bd7f16c387ff8b445c831e9732792b9a3636543eb53aa309a91b3a6546828458d7aa1ae52f1ec81ecd7b1f18b23239323b500f35ad7110aeb61d9d9e34ba92e1e742835f5e835e797fc82f672168a6eb9bff147e6420177a772f0e24193ba0c945d15ab469717a9fd8ec3c3eea417e657c4c59872cbd5c51140a9877a88dc9617a041f8226b165733d26a6f5915eab25cd1f86bfb47b7388370d72057bd6a3d1e2818dc61256f92857a35085841d1797b5e10bed08b4b3aa3a9addcdc312c7c5a1262b01276a6cdb7125cdfb18598ae1e1d7cfe0d32b5c45b01f59d828ca855d832a6f1793e30756f4baa0c33edc020f83bd21b079d67474c249abc29f6d85eb81f6570b9af5952c1b3621ca811944e958ff2001bdaa200b9de8b359cf7c697dff273a8d46f7cb18a4f60 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 3d5fa297f8d78b222ca23f9587f8a38141699fa5f254e24755e9611f0db532abb855d04aa4bcc7a0f1a860c297180c0226e3f2a4a70397bb319f0d226a6d424a6c22c2c3092038079eb6b19d0b8c5caf718ebfab20e5795504f927212377bab18475b62729216f20020dd5a80664572151a42ebd0095f1b8be255b6599e789b632b58e83bc49b11696f435aa9441df2284bd03054ed353bf4c05d6e94c8e3cacc5e5400f1b8857b12f335412df647252a66b97c451f29387afa58ae17b1a22bc939c1b96182aa706047246a4070c0142ec3119cf75ccffa214b6f4091824bc5aa169fbab3993b05a5c9c81cf6522b2c156d6ecb8a22a20fc6c81ff35c0f19723042710eef807c42b1c6629317e8a944c44453dc416d3650d2f6397f4fab9c4d476aab7cefe238fc4389059fc42a9e2cce7f02e584456606a1cfcca9ababa178d330a39130ed5657b60245aee91863f4451cfa2c3837010bf31cb7675a291d5649d39877a878c183a9555e7746ac575e9ca65dc17ccb3055e26e74cffb6a71d4179a1c90e6e7646f650b264b4a11475284e8199086024c294caa177237e596f40a1ab93976a7761b61ecc28f2a33a0ee0 +ciphertext = d3530b8125ed3854a1d8e51840c36b2aa92023cbd414d5c2bce81475772d24c026e46c3690368a9b648879f6b16fca9c0d630f080d89216f82dcbf8be821d840057a9a181221de67dff1679f3d217848ec990d92b32c42e71704c0d00c2177501564d3f901e643b6067caff86ad78e7107e6d0550cc7fa08ce33174b1f3dff43dff1cda1822e387ac8c764ed9ff3e3681ca57d96ecc15655a2f798ecedc56514af10d89de6b7adcc0869c33e36b18db22e8c3026765096d06329d75140d1c89ef1055374a85d04569e3faba2b3a8ad61eef170224e26137d05c21f0401e7816e741c457eb93d362670ace091cf2eb51b11486e3ff32bc81d75370c3da42b40de4291238d26d809cb80b8534fc01437ba75c76c39352f9aceffc307684a6ec085c615cbb653016de4b16d51781a57cade3c00060f09beba44a9d1cbcd8c18e3b0c611437e1ed5b723bfd9bf3a96cba62b08d3138ef712fb560b2e1dda1a3dca48da30ab1985b67ab418d3944f3249dd2d83e0494fdd4eec01a70b910bd88de68cd65e76aceba76f60edcca6ab974b4d3bf008e64698837ef14414e83ccd35c0d0977699313edae259d67c0e263232b592ebc8b0b76838c28b2b2a61af160de716a3d906bd05b5fc204cdd964fc1d9bdf4ed7f6d214f0b4929d0ea315fd7432409e2d1708352bd299d77f66bb33caf4ba7009b92275a9a9acd9d32c4a47caa286ef5b40cea600bc1de35b63c1535f2de19a745572f2a3bd33245fdd514c157c1086ce588d85056f8f5f8a81003bf08fa80c8b9706e6ad1d8ef668ab3cc26e6b5c2ccad41c6ff1cc6d1166290a1e31cfdf47270ce8cee1b8cb54a9d1d2fe8a67cea0f438f19651bc823513f3ee6e16b87efaf5d9a02058344acbba45e747e18af3a4bc3a195b51d7464299c5b107e72b1a9dcc9b8cb7fd981af7158cda6ade0ee77c41452f0ce91cad83a7c9484c46e779648bcb072929753e6ca135d4554c90da8db3b26fbc431c5503528863c88feb9dc4a15104f8c06c7942e3654782f62fbf7ca38b82483eb4fdd0826bb94422b326b259014f43ca92170098136be9e44c69f93136e9a4646fc5c6d1d27965d979457ab0ec066dfb1dec4a5357bbeefc040bcb038380d768d43a0fea9d38a317520fc4c7929bf5dd150eba0c43d9ce699040f13484c15f6b3e141849ec1a84a88e5179cc618b04b8ef3c3c9e22057a377e715a017802b098f81de10b40b1c8c1fc6a69ae504ceade512871a2cfeaab0a9bdeddca67337b2405d605351840ad4fec22e0bd698201fca5752f79fdd3d1d75842d2fe2c83d96522a4b0bb093103e187e96d5eefc4c866f0431e1f1673dd835e55f44ff677505122040160098f60225e6afde694e02ff334dd36872ccd337a3e34c712f41dca19a126a50d9eeb22395ae66e5a57af6f3724a92af8184a27d0877bdbe0b7ecc40d353638a665ab57def5166ad72fdc1bb403dc908994cb5f4239d30d617ba578dee7ae76b8bd11c1db27583cb27b9e719fb5cf140980df8dd71f665 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 5a5614c1fce9a15ef542b2014409c54a67a46b2a8ecb94fa3b64de40d539094da2441a0e94b40221f07c708e931eda1462aa3b3f422f952239d76efd1703ebd6705052273dc329 +ciphertext = 459df0c90aab5487ec4867659ac8a4f4f267aa5070fecb108b92736dfd3150c1136294006d7bdcd7333c9c2711f9cfed3a2b45830b88370673158075f2b48f10791da3e44443dc03b2aae46f8df2eb3a49e15706ba868984a9cef65366e3555ab85b8d6b74fe1283fb7ac91ac0878fce2490a6dc7d27ee2cd502d52e5c912784f11bc97d05fbde370c3717ce238a983d95090f72159abc25adf7a3e82e43480f9f3eab0c3a9f3affce662116f4652933581f8eaf42dc2db3e3fc83ae28f173db0873149f0ab20f4cac1a49951e7aef93cc4797c0b75ac8dd5886d1b29260f84fa4caaf1c4ce63fa85b7f3f84662d3ffe7d9719fd7851e8147e756428b5c18521b6efb7a03179fa579db331358ec903db86e44d57e90cfcf3a606d48d9c0c9e1e4150b9ae472b613b553963064f1d1750e9fd66272a99df6080b98b1743d7f7e4ab167a4f91d4a2faeadbdffba622457df3d3d4a1a7838ac44095e0c4f0bf87b2c6d3bdde2530ac8a7470cfa6fa2735ebdff1af7820d96b22ce8714d4aa50b204764b1b957e207ef672828d8a1dd3cf37083afc0e94433b0df63343997bcfd049e43394a522a9046108bb4f3cbce31fa8a8b8c985a443f1d3c4eae6035e571ebcdfd7cb127683967a408ef07c97357fa3fee17fe3a35bf2ceea157afbfedb0396bc1b7c1eef44b9273a081e6acaa38aac8a3ec41d7a1a5c3b4f3a0fc355fb1a1ed260afe9f2b6b55c17934739cb13d1a46159575b8c3b98a8355243431d989f3db11d77ed9cc7c9e436a2122abb9ea259cc30841a36a5944ca1fadddad23b3f59987d65d3323679d80759ac0c014592648167e3840d60e5e0a60ee27b25fcb9154423888934b928e791293f79fc80bb44dc4b96284f499f1f7cd6c77c3ab4963fbdb7b2fbe002e8494eb5fc510e831121fded7309de23ecbee75e914931d9fe90fa46483f49554a11cae6a0a6b9ac5d469d11864b773549f43feb11aeeb0e792a28ec2d1452e75c94647992fc519063b9bc7faa8cd8c86a2a5f591af19d6bcda9ad724ccaf274460c337c72d2cb201c6cae935b2cb0f2f5a90b4f19ee06cd2f41a0fcc076516598373a20f364607b979fd696f6a7a4cfa30e2d7fc99ee2a636695432f49e9443c0c9c5e78bbade9cbb899cf3ce2f55fcd716544ede6dfba53134ed7c2152eddedb8dc79a30fa10ab9b8d2eb8891ac8caf5dae32c60bacf495e8e8e15eb21bb45f8a2019cf3c3e1055fe20eb1f94c4c51664fb4056d6cf8e0439d1a6fd5f88338727feef7099bf4470ece96a6eb45d0d4c2961df8193da89301b5fca33eded610a7258aecc184a4c9edb05612f6141ebe66ad9996096fa1c26481b787b45dcc84195cec8e2abb8cfd1218da91a55444ad5bb3b27414e8f46a459fcd43e30e9b1b39e2537529717e1bd80bc5c75a499fe49c5990b601e2f37292ba067281984b1941277856dec0664a3bd02d3be8c8f7b4f0ca783c6d059b463ed4ad1bb3deecdd8eea3e77b72bfb84919946887c7e40c3183a9f5a6832a5e1f44b +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = f581cb84b960b66fc7c75d890a2cfa47863102a265dc47f48039d0b32d4df65bad915ab76a6a11160b71a1ad104a920109890c851b2c56b5d0717df60810e067ad3c672ab3f50e6f60634c1c2e86e6b628765ecc71629afb04d2f628db3c60bc3085a4b472965c77f44c7346db9e3c554404cb852bd6804f63a71da3cef22775011bc22d94176c986c5d361a458c7fbe99c2fd895bc46a9f05ca97dd1a49e60816dfd22fa0a2cbe2e0c276c2b0558b4f90bcc596a62346d9266dcaa125293305a072afe960d745c1ecac422593315264be95a062fd67206791bf44233250f59be9d31c19b41524d02ea5f57b0095361ae50029f20166d362ae621327c566d9d4ba5bc703b4f785ef8abfa8554fde57acfb507255a60bd22680e641084e6c6ebec28b4acb0575a7474cb84cffb56b6f87c07e9268a08571df8c3c01fcbb3b46af10f06574d848efe09b2e84b9b8f1825e441166f2164dd4ad1ec482f7646c40b0afa7610a22a8b3e05b85441a632ef43d15f6180a55cc36811860299aa2a5bb5e80575c51b701961bb8a2b6373285b03c30dfd4ba7db418093b93cebb5f4c7450b01579e7d8ce4e6c11b9e40b120580722c621873794c47c966187435f5459565cee8615c919b9581a857771842452154db760453aa0cf927c5ab92bc9f990499360f03fa5bc6a1b7603baaddb797f5a6be7afaa43194693ab7abb0d36fd25b1910d77028c2475dfaad0af708eeb166c6d09d04255594312356b7a9e0db3bc8c14605f86f1281071f34c591987ef13ca087e2071c15aaaadabe9d969b4a014e76c04d58783df3d258b999ad5dd06e55c7120caacecaf3a0da2c35afd68f90d4cf5fa30340c7938cf36467705408104bd47a685aeb8f11c851d2f38704888b83443e9651039c1c2d4f7b4b50080ca766b2d737c861a4b83ce4674221a574f8c4c510620313c8e8694f74d708a7ea9df2554b472b667f214d76661b11ec81852a9dee446db80649f4e5a4ca4c43a77778d242cfa8fc71fa397ff5073c0cc10b39abb0e106516665bee016493b52ccc078608d58c17e147540e17e559657c774af6c7201a869cf28e6c457e9a294f344ecc10817e5530b229d85e24b6a8b2cad776ba79ccae5a95048c1405cf12ac3162681da826590476e3068a760ab67c3befd3b8c2b5085527630cd415d2389a60540725fbb8f9c3160a2fa69201538f1bc09dad3bd2336103d1893a5d966263abbad926f3f9a5dc1a8c544b6868947b845c57648fb1fd1897dce87c251f998fa294fff5c6b971418e3eaa1b67345971b2338745d5f39790962bca98c07069b202ce5b73421ce3893357f8248609c4697da62ea0c5802cc48decb21fb33a724c492cea60af9c604ef9c8a19a2ac3660c0708acd218bc8f297632d50523be4c028ba1e4ee7bea014c818a14ad43b6855f97fcee148ef577ad67806ce123e37a544ce1349b986a974e1162a41ab33cc10647a778c9abda3c0bff943938aa00b6e3b1a37ba3d42616e2bc85caf2c941042b74bb53698456cf4088f04c44eb1736e64ca63686791829b641b69b178c506682b42437b9598b21d6d832f3e463a862623c26c841ed03749e31757e73f49ac935406509d00c458e18686ecae4ecbac9218a7fb4a704a00693c61c713cc8994e64b0d +ciphertext = a77212bb2249f2a642189278609707cb3b70f032ce9aa1a2dc74b8eeb711a5402a3d2fc08761bffee933148e9e545d5d5ebdd293701e94db1a4d389cf41212cd998a440838b71a4dfd742c7ceaf23802871ddcf478c3e2d4ffa50c50bff74af6119fd35529230864e83298f25642ee00b5347f858800bade118488ac1862e8ec59ffb77287e316ee0a3c371e5428d09598b3630a61a7e818ebbda4a6c04f449c633a81d6899ed1991fe24bc977edac926fcfdd86d712af9745e55e09204a76bba32b2813c24cb34b0e860fbd8a46e18fd3e441d4cbd3beb29af4a9ec0600a71a060c6321527daac169eed064a3bee0d4537e667d23b67a736188f71ddd23ed3f352e25f641f66a2d0917753f3052481dece5a57b0651c3724fb1b4054d00f8ffc46a7072931b19b4f94bd8bc8eee986b4c6031a2346dba99282b091ec65f3126f6e16fe2b9289f5900d13036fa0d5ce4a7c02ca53818d4b4ee9dc6c392bffc965473c2df85191935eec8ea9fb0aa8fae62af870a083264004734d82fcd2fce2a0acacb5e1d97496602613e19ff12d2861d2ed8bacddd10677660b445abd5b1605af96272ae18652c8c17e569c52181873ce3159e31171d72debb20f90d21e6126865c172960f97b216c20b413e5cc9e35bf33e62ef5ccec7cec1df84d73aae0869f586ce07b7afb734be6cb10cdccd471311876e989521a73781dab43268adac6ade1f33408971a8ab32e5d465cbaadb31080971b96f22bc75789d9a8c911e932455bb3759a345f46231d0a364afa81fd2e8c3825b27f0363bfdb1c6dadebb83536a3c6b28433213b191d1063f090b0fc0f4f47ded5191a90d3f00b3d19db2c22d1b6ddf5c9b95f9d90fe9c755bc950655a8732177cac21d4de19efa7454bae19bdd24cf669454e2b0c7eaf5e9129c66d30ea7ae8e3edc876a9eeb5cb7b951a4937cc1286d0b2fe4a076f76a152fce417d298e98db9856aa73595759c113b9014e1bb17f8d6261981e59d35bd2597f989eba89184c3dbab7d92af30502e334b2046745f008c2505b2d2f63a3c5bb804161ebe8b619f65b196fc4e7f07807fc4fa6b86fcce3127381e06eec63b8876360a233594089b1071cb2552e97be179c36f34ca7a341fa7af14122fbfb7aa347751eb5d835a6f4a0dd64c9a73431214324e31f139bbf07160178953899979c6de8bf7ce4c762c7ba144e25655b8c40d06745c612f4bccb10e6060f3367d8bd5d2a4d1768ffc804d9c45a9aa9169bb9b0802f364119acc926110167fefbf905fdd2139cf4039c08e25d1511d59719904e972b653961babef96992ad5a0b934c11d1a2ca982c0126e0615e43a874df67b56b0fb0c526fce9692d344728481341ac81f1d4fa46b81de8c624c9119f9689ba7704c259d3de3199c596d25ee367a3f2731cc78179ba757ebfedcdbfc6b62d331b30a731d02961e066eef629271e2228f31829a77022b1ed4efcdaaad9114b35579ed61a252af1e41a0e1467ed754ab3946866ea9b572c2992c4dac16ec9d0bc2f +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 082c79c723ab483c71493a2cf5287e5cfc0872a8876c3a363b7c00c7157266352e9ad54562d6a5c957c0d2c47b315851a4e9a3ed4b99d0c6bfca65c97a34677c671e493a8765202cd00c2afa39422ad18ac14c15b2f014d0d5c9366a87d8e9b0e8b081a924058a111cff812ccbd394d055ae46aa6d13540628f690d026cd3194974a0558f07641bd597c6028bca894914ee90b9ea38f04cba934553a576317fd88b88fa41c98e17327e0c4fc1a04faea2e4fa45493197c14a35b2b37af1c8637e3c8323d1a5d01203cdf845642c7684cbbad0f1424bc8751edb251df1c2a707419ad2c7503607817e4864e215774a6a6754a34a0c1804c95bd573747ca9b5b5f6169221bb552022a4979bf87c917cf569ffea8964cb4250813ab9da0200d82c5e1a58ebbebacdbd5474eb15aac4986ca490a73164b331c71789c2afd8a55ce91778b8368189127c1647abbc8259f95455536b5a3a933da169cb83a5d59b97592063501cc9b9cd31ed75a7f0e213b4e8c1478bb4d6da54cefc4c1e79c8d07fc5bdcaa9b92d78365e28444d38108ebce06626715f0abc5d52f93ba02abbcb6d4984e08b84881f7693ba873e0c1a35fc00a75743546594eba089abf48c30d49b4179599873b428fab9a8a3b182f8c318b9014f6ab77bc4a0d00319874183f3d276f4e54b943aa59b26abc67002b3f365949b922bb3b9ee8ca25f5797b0c9849c4b2c7ff5783afecb57a5a6ffaa9504e300ed72a9dd3835ba79b3d87754e056c199fc6c98f089edbcb0e13463aec7437b6f695f2839550048c2202a4acdb6d9383b6755b066fbb6ad6e524b68411c12616c63a4fa9a544dfd2576e6287d47689a3197216d289c7f5179e126966827af7963ca5ec0232cc62de0512d409937ae0371b7b910b4133f3067131824943d82612f637ee0101832a90eef9b12ed81b5c47076448b916163caf65b43e22c42053284dd2cfcc146e3d42620a0090cd1183031abaf0c402bddac272c30d166c7becd48dcb037f65f91bf7770b09b03a13238a19a1346c1b1b42361632c22c27600a11f1c74619a9d4f051ffb8c7bde61575e0c4145549ff977300e27f72f8342157395e719707867887b009d9cc6c4c89cd8265b372490dafca137b568cc66667f2693ec3f4c79b303fdd5098d011a169c6091174787fc98594d28643d2240dd4662ee0694e09c4b2db2fbf1937571c1ddfa78f6e72790522247105c6370762b6a88001bbad994847d0566b533787a1f802327b23ca7b519502b598952c404a95643a23d04a61b1b000a376a0f602c0fee10dd73c1fa8d93abadb2fbad0427ea531da9b0513f8cf9b339d24b8b39648b0125830d8db0dcba782752770c89983262bcd576b88af9b5e4e23cf17a0a3070a9646776b3c11274151846ff9a4b9220c96622e7db52ab85972405426ca071902e28c3801d085e33af1f522c46a974a3078362abc5539424e564f074402f5c748a5e871a96484910aaa865126d26cbde85abfe0b58483b73014a59d74a037a1a566a0d49387104f8f6cc4c9bb4287a80aa665bcdf59bde93271c6cbb215e7cdc6a740d8e99051c89154b1c6f35ca2cd3cc4dba0a738090beb92c74d024f2450141721b07722ae31c1966b73136e664e5fa6b7397bcce66816f8ccc5e0f2c11c843e64e42d8c242cc3d02325917b0fd96ccaa389142250750c317ee53d7359988a57ccef3020730c5d453b7a08690d1120bf72 +ciphertext = 4e495e7a574391de97c5bfc3277ed8a4ecf4d2b2179de0314c8dc4441dd9f5a2c635443d8d5f4d28f72bfa54538535c459b67382ee9e85e06b8e360286b8af099e788c6891c19b963cad77d709184ac20f8e798d7e8d8caa95d05485734b7d50442a36067cd563009c50f39f83da223740eceee76117637e27820946af5fbc2b87d9fd1cd21599da63c345e248e2142584077ad9f91b85862a870b9cf743b1b885429890f07cb9e0dc01d0f9d17bd38085bf5e7795be9ea295611659200e00b1cf5f84e241f661e849bf0f83de14b0c69abc7e71918f9108f7e46b9ba392780692801afd00ac66395b8770052d0938bda94dd6fbd9b0a387df57af385669b011bd91aed5de9e1568e90b8b003c33d65f98f92e954369379caa199fe9afcb35b8e82fb1c55a40a8934322362b4e3898c278b9cad1a117c7da119b90aee59569cc836d5257910b967b870ffe9bf14383320a4fa81e354bb6db33815dc7418d9e77579871b0799d6183ae0139b46a4df8f9bd1f097f50a4cc6784efd578096d7d2a53c451f97072e3f9b3d63d34eb0f1c99ded463a5e9c707903794bec889b37bff39dc2baa4662d66633db83c09331681930de6754c2d40e57d8f190494c6181b8b0f53d218fdcad220468690ee951cc8a8feeeb648c8d36c9eece0870ffb81e03d63f8a3d2ef4fbd44bf4944eb9d1bf260b2fe085b769021584b3a455162f97b35c711172acf0fb0b66f4c3e3361e989a864f16456014e2e333d5121d8157ce825c3951b1053ea9f494542789d84c9ed6f001a1c3b83554270d3587cc2e7a5b8f8ae4d07802f469ced0400f48c12fa4bf4911f70a4dddd2da4ec3e88c77140f000f7c19fe6385b28b9070367031f0d078cdb312b6b37fd0cc0d85ac16326aaa07b82d98f1ee8552c526ff31d46bbbf669789d1c7458af8dd8a55744854449a9311f88bc56167641b229a7c662c14eea0a29812590e9cdd34e7791d32a3d834fb2e57ba6af7615a3fc764c64f9d6d4f2912f756d621e8060e7226059c35927c4ccf9cae6d0255f741dc54d85a02e5e4c3c73b8246431703d8f27571548fb8c144742dae02f84c6c799e781454cbc4d6d4cb35a3c4bb80f142a5bae6a5d2e6ca7fbc6287c33245966a4040e5fbfc71c027bbe82e622da577fa7405b8fce77783668a1cd5653dd5ca5bc91a4595a6e5a5b59fc07479b20a7cb2b00ea84dcce520a34a55221239f8bd0755b3ac5e73297f0125826e3a55692da4084fa08b03e744ec00a27511409cfcc22ddb3f12e8b620c39793b4340eebaf276324dbf7dee3b6edebdb9ff096d294801a78520592eefeef9df130b5255f375f05bd625089ae9b90872130f1b852f57914cd535c24c0bca42f46f3d75ba28132f10b934a4bd9948df1d721a71f613f738c0032b36179c85767643b7727eda3f31414d7aff0c50a34ae212a87549a5b85d9c1d47fcc2374c2403651230ebf3f6d51189c82e33b372818b3859a8194193ee2f581dc4d42f8f4b06e22a779be09d6fbbcbabd4be52eba0 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 65b4f0219ce98a017a5029716a580598e1bb7b2b97adc1563173c0a9dbfc036f1598f5246db48bc10552a7a6f6918c8c7f4fa6040d83825b270db5224173e234a74609014c92521b0a4bb212afaa0f514816f5511002998b4f0b1e9b4255db6097ea907f2c474a2f6a4a2b077b1fb685569848328b907018559bfc2a3d1c4e56c947ed10bad8784f548578d274c41ed7411d37c7a0ca4f40da7d98084550b73bf4255b4be3bb576a40d54b15b8ea59deb2c73ab179a5cbb77d40a7e929be4b346fbd8340ddbabe358ca731413ea1aa46dd79a5af051ce57a0e8953b4aa269b09b004cd81ca69a9 +ciphertext = 7fff312026417a838b7e1e6dad4d1e2c8a7f61b22df9576f1ab55b44ad09dbeba6c3d15db62f0c2672b26e2bc642816c0336a5ec17241b6b4a6f3fb673d953ca49538920a599300193d6a63577f663fa77be28b8cdd21419502841733c61409196272a64659269bb90df42b23d47c326ecc276eb134434bcd6134050238f629079f7b524936273f88941e39565cd98092c5dab03be58c3f24e3987c18c8583551d7c1096e91a7ce4e8f9d1f283c1b59fc746bd14de4217b3be7df0e7654410f5025bf98d21cd6d3df266f6f498d70f148212d69aa5f9c5e65eb26a832dac323382c0f1b60993822581583afeddadbbc67689f7bd5d00f1212a1f4bbfce5eacb5ac56f7f95f3aeedac0bcdcc85d3eec5245a48fa0f0a53bda4727611582a604b2bae7590c0625bf0a06f4699b047647664fb25bba2b9a4523d9e8564dd1a1904c87af8a0470db6fdc09642136a71bdc0058643660c06f02195f5d425e4bd0460ceaec9b7474f3bfcd2e991b2ff812ba41c427bec2abc052c3faf478b3545a551a12577348b1d98732ab5f43d8b931258b87f3d1995fd14c94801593d39e8c633adcaf5c8c366903e7e58225bec0e8af377e46453f598dcbffbb94a60407fd90a3839ec8a89e2aa82d0f6a42d43d60e9ca98a9c68515b2b198d7608e3c13b0343433bc5ba6b594fa19c516707f0c3e2618372eba8562cea74e90de4cf7c218daba5eea4421ec3d7e7dab23d1d5362b1a61437d38e5a0090988921c6c04a0329e4bce300c08a845dc09b34e9d59ebe13ae7fda164594935a25a16481f73503aba2e9154688748239904064430db3ff60d95326057dd262f04e039cfb0028766aac8584ffc7158cb98696f1b2cff8a3be79f8713ef174f30efcff20520aaab76564c43789f8b1c465cb5e404a2bc2b64ffd2615f931a598a4ac3340fda6b955484327a3801e810d4338653995c8ad439e52291307aa99f0e57932dab514d5ec1a66c30c2c0e62cfa4eaa4fa8a1c77d183f45e01572f33e207d4a9476d0105d6b09e68acad1c776c1f7e2fdae12093912db7c59af61405aaa992cba2400b0b23592d62edf61ec6a49b077e8c9cdc036dfe3366186e04f199b5950719fdd6c4fdd50fede2f657aa1ec95fe02fabb946276292c231551ebfcd505cd8b179a30c03af9f57a5a8816a743642eca5cd4df76efdf454634f4ebf7f8c86bcb86a87623e560c145535e94ef15b6ba747f1d076a5df0f391175cf1ff666c9a518d304b68a5b21dafa87cdfbc71fbde0728273aef0475f1cb193991c179668c795d3c67d11278ee56aeefb267b51f369e489da7dd0859b67dadade73d69582240e409e48d5dcaafe6d430c2561cd64893031e8acec993bfae4ee548ad62bc08c2ab822bdf461dc803b64d35ea7826f59f96769ca22d406ade33006eaf3e733ff8c2552065751d394a845b1039d05cd6a5595cfee9cbf1469464a84c642834d29d2135cd75106f861b3bb439d07479f354f115b7c33f00d8293eeb1ecb3ff8a6d6548854f5e6523a +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 7852c0a87e5afa8ac5a7aa4d5c6a6ba3ae58b2999de89a3dd61fe9b97f3fbc334ea469f9338bcc1076dd00d06f7459d0b5a5a6b396f78413fd763a44b790eaf721ec306af83c13875a79cd5648fa303e3fb17899659e33d48f79d254e2a89a1ba59ad24c4ed829a2576774a42243435b4ce9b7a03d3cbb7b877bd0d0597d358e4b42a9b8a11ddc84b17ea57374bc54028019e9e487a3b94c6e4bb0f0f347f23ccf48d875a5c0177aec548f2a7b5298ce8b3185b608a47cc32000e83b20bc39981a8cc9d46685a0bac47bc56c91cd064a2aaea95814b43f641434cba0be83f00b1acc02d04640225213898a3e3fe224a18b8bcb9c05c6c49dbce12172192949306e2782ac4eca87c86c7953d2003ce767f5eaca70cc36e691037fb53f6a0798a99828c21b6fe5b076a892aeca718f326a4d5100519468716ba801d4c64ff13a8f77a6233dc7a31db83707a48435ec48599bc45ef90be3f482c9c09b50d3ba60ac4e46052149103ea888983bc35445d96e000336461284ea9b4119478a61220ca80c729c1126a4d64999368efb339d08d2381cf77aaca29d8234bf4c5169aa51767006aa82320ab45c6a99a959f80996d82214b1606713919566faa955644384a63e2274099778343f914af2fa97776657b786787c951cfe3482c9628dc048991428bf75a95874444c44219ed726212db4790c611c871b4959546925261e93b358a13aaed1a8b5fc34bfa2f59b9855c8967baccc7269359819a33560f0d6c032907168d47a599202bc9c50c08b1d13aaa959c40ba16a7a80361703ac2c5154a77cf869b2d6a9b946ccb31416ffab696077ac423b61ae198631d638eca4a43caa205dd6a624691f462bc7ce9ba80bda270e652716238285d12de2dc8a51d81e55e9253611859b3c0eb4a015d9884e4313cad7a50c7fca68a4d17fd0e864f24395d79543bba46ef4c6945fa466abb70cdd54c542a1a54dfbce31577e7ed20adf12c6a20b2e86a19e67b1053eb450b5c355740712e7c277429405b0788e3fd626a9cc4f34400b9ae8a8e54823e6d7aba72cc7f1c7abe0fc059f8403fc9a74fedc2662315f16c4b33a6157376721b1183ed1479f53e06fe48c4113ea11a083a575c021dbf506a2241b2a555971998787079b3dcb31e379652a172799662dc0a55fbbac3e149b3fd69383aed33ec6d6c7a1685252b23857f09004eb26939a4d436822bea07cbe6a07b9817e00566aa8e45197f1cccfdc1b1f036527f29c7e62cab6b9acd92647321b4e2e6aca778532798a1fff24cde9443c8fb2b828d098f557b0bf9bcaaf8a91778912bcc7bd4ed53bd3896f10fb5de09204c71bbfd425500a8158a2f20007c28afbf5a60e1c9d3ec815d31bc910d95fe5eabe6bd6a01df4cc357baab1da245f41ba187a8225c94706085fc92b493307569da317e88c5afa1b4c90e6a1d3e48d5c944d883c790ba0b670001eda258379eb2194e1b10c839ca97ac492139d78021da7e20c1348117cdc22c2f3796d40cf6d007ca81c76f659c58b973a1311699da4b257159ef2367578732838b221e5972073741f16877abf321a5e249a7015651fa72c08a0a138d19a3bb8730e84a2988510ecd36737b985055a316eb39f86a804bac7b02ce34ee8521b5a761fc0231580259b373299db2a568bc184a311550fdbca2828a4f3378cf69a23c652591a559f2972335ae4ba07549f6185509f03b0c77a92dbb5cc4e70b56c908b77a980b968823cbc77e5d124dae20a77633112542fd50930af23b1a53a679637c981c34667cb5c98c84f38b07e9937b10e55b115c376f897416da531e6163b5310670e8c553e515c07b099b960a5e0a70c95d56584bb9d21627972eab2ab050e6f329c15c76587909714a5cbccf2768dfa7fbe838132711abad63d538948dc738ae8173a04d3bccbf65d6c6791e789029fdc532e48c107d805814b0a770cbc96e6914e88af0eb0267a4c07b30a826612a23be74d714365ea07595ac72c18a65e257335b218623099bcf832813d908f4a80cde6d960731248a8d65925891347d174f5b48690045b0bc231ab02114afa50f0f74cd3e575167508324c24b05c +ciphertext = 594aad63010a90ccf8b896c4d69694c855fca489d510ebab935620366b5be7f00eec6f43091f9ed2cc06b208923f0c3c681c22c8a28d7b71c995281992937a7e9e15c3fd705e20457a33e8392eb76fcf4e78df2f1e5c11a07bd5fa86459fd9ed0c0b2560ae171faf3eafbfe35f30409e5c3c7a05615f1b530f37a79a0151798da7821f34dacbcd5238248df2b5abac8f34edaf739d15754e89eeb9f1e21b02a4f491c32fdb81dcca20156f0c758bfd3f8af48c59c4444b725451146e3a25db82662bcac6dc63550a5451356fc2a49b721882eabecc739427246a8001af640c39cc3725705656f85eb5cd2fd6ae1b56795bad29beda60a74b0804fbe244de7b2c653588364e6c02a817ae535d492b6ba59959fc6366e695e0937635148b837fcb84c4b506f4760f5cbaaedec167f56ff8a14b0316ab0798f8316c2fd4bebd31f290e7b48e4d46da6cba8e54735887dc869af8557a69f6e4699aa9aa6681b3cab1081e099be9fe3881673f2ba7d850e0dc5b07e5276aa49c73de697526c05204594f78baa8f42a4bb7e15053677bed8fede2964e14ae45a0846016f39a76205875e87511937b975bba9669c91e621db64700695f61bd141a68a3521b29d4629d38d4d8e5d1dd3cf5b9282d9d678c8634cb736aeb23a393a10e59d4675b8be9e861e9b8f46bbb93d484147c91fbd6119a36e29fb191e7d0957d59d8c58835a03f7fb2f7cea07d710c4fe11d86e3bc8ec3cf940afe43ed1f7b81f4c97770be404f50677c103dd4313f77115484f15e6bc76c7a5e16a67f5221f3162af37572cc11c2d0f040b43b433ceab117b833e4a96c476cb89b279708a2c59362c80166b7731bab8bc0b9bc03586c275397739622500dcc3365b2de315c5e5572603de6dd3f999abe6729e5e524788aa2ca65f5364ae247697538907760a05aa30f9515ee917af12d57df023e39a52abea1cb8fe688394c6c1ef94e0143b3e2fa264d109ce194fd07505aaabbc02b970cc5eb41d40dccb0e71a9f21a843b95bfb36e5b37e78d5b3dbfa1fc273c58060a9675aabd13d6be941f1b5995ed80675bdf99ed1241f9b3bc898598031e02ebbe88b403f771984901595b874efcd8ecd1909969297649cb6ea939cf563118631bdee6eff24589041ad3d16113d383c98282a97cbd15dd37690ab5d4158723785da11694a9aa65b0f0338e045e48a7acc1219156cb657e96b0373ec8406814d0d7e01f9e5c488133a0d4826b38193f3218c01cc060631333c36d9b448908f530f0115e2c3d15924711eae106a72c816654fbb505bd56a12ce1fd7022532932e6232d5281a44dbd2779ba27d903de5942f5c9ed46fc45ae50d18ea774281e15540f2c44287ad096048ab1561950ce3c3d5cd6f5e47399043259981abd67fe0b06b4678b2e18c1415c7273ac5a24189078c5d3b46464d1f700a264d44137e68b8500d420626f9404f5e31cb7960fceb61a6ee01281d48a58bbee436ca57a22c3a6d8169024a2f5686fc491f3d1a0f80b7aea57a06f161b18b +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = a884916f3192a7f4fc71ada327c6999bb5751f79eac7b5554a8b201a8de390a8590f244a1816ec403231b90f69ccea9caf62049582d4ba0158ba274259a14309ea6ba98fa6608e2b70bb4cc1ce680ecdf17151b8c198f2842cb75d3be7cd846c825fec2704c457475b4a29b6b1e683cb82cc6b94dc1b5a1525158ab69a8653e752c65b43a4e389414998c66bc10d4a3bc5b6a528451bb8540002e28197aff60b8c3509fd0275e5b9764020c5c7c538eba23e75f18fda6c81426856703b392dc27b72194feb8c9df0e7605b97b6cc820f9e29cfd8c41e8e6a6fcdb7a25cc124fd7b734b6546e7716aa0049acd23abda96c6d115061397b907433e91375a9a0b1859149633eb572ac02df21c3ea4d1a75d312560c9197c77bd5373426e5b458561b82376c828257dd8e80fd2e10da9d0662161292c92aa7d509fbf8b72a571c3501121c17952e7350d1559c3df4c2314e73ddcb22fa6b424ed38a76b6b4ece1a441e791e32449adf959d1bda9fda98a9f02b903d440e4675568e6a6def667854b2c3e00935d0a95d087573d58464685757ea87ced38ba53bb23121f4bf125393a832769976326ed593596b52baa2039c263f9ec75b7403379947a2139b883abbcd2994ccdf8b006ec34af8cc92f4b71eca166736a98e43431461052270c10853eb84b8acca315260f9b3a97721188bc28c74c453b0ea515adb772e06870f395ea45a2b25b2c77b29cdb8a74ec53255b2e0257ddb5cd45b9807a724cf7553f7c87a40d77b5a8697f1f750115255efc41d56a5ba16f71942f69fa36554fd9904fcf5489800b4546abe8170317ddbc5d80bd0b2ab622c389824e295704686f67bc9afab481d2b0057d147f2b87f9294b98fd119f1a032cb000e14f41b8d1685ee8564bf7027bcd06b1b3c908da70b96cb72397505aa564362861b47972496f9851d22841d942b4d7c5af7f616ace345ebdcc2d46c1e612a7d38439b8f374f07e476a2187b4f19be1c096c7766ad20c6441e313497610733856aa5c5007fc45298758e2f34ce85f86633537aad275704a4818bf24784674dea00001e788f6706bc4a9cc562919fecb82c6151795137089ad70452c79be1b13227875c712267ae9a96ce18669918586a0122ef379d9ed48c1e0153b1f2b571c5267cc53d2954ad9b0b3cf8aa489590697742b158047360e59177cb272839af3f3c248467358f31caf57039525b395dc909a19c1716fb96adfca0f3c11a41c089f008279a067fc3a92a710145ed25063b01435c29b0c6a8637e24cafc3cb15325b91a748451c9594c79bddf80836fcbabb8e40052591a4106ae594bced7b4646e176505a7106423528c04d0698584fea210da0b721868871f187bedeb1265ac4b9a3a62f6b5c8030868fb1b37857454d9731873db11f1ec510e261bbfd735810b3456342a1b80115a53b60ac9a5e6b777e05636016c0f0728a92086c6146710e9f172074cc66d647521a95b4804a3d2245c4035935456b76d90c3177485e60c530fe61e6bb0c88a01b8cf16984c654ab2b42d6a0468865b2eb115be76cc2327e82e98717c4791b9559575d8a8357d2b7f08ec3ecd33b7e24542c4ca1ae4c06fe86101bcc30d3d79cdeb83c54c8917e58254ea991e7f85c56bd87ed01460e8422183d17543577fddac69adba533d336693aac5bb9a2080d18235f24bfc7899279638e3d8595e9c3a8ce053fdfc2a49f05cb89244bf6555964305bb57958e647b5808b549eaa78ecc2172363903610b1f7b452649991ffaa2bc67144b46319e41b72e23c5e8260b26b364eb4b219cc9c79ff1940b5a1c89eaa5e3cc880e75ce6173c9e993149e538f972764640679fcc539403cb0ed08945fbaaf62510c34ac9ab789441e01b8e667ba6efb4fdd0b4f1a8b5691eb6fcf1054404c8bb487a2c7d975d936b76765cea7f467e096ae9938c565878e8f86b4bfcaaa3be30d5a25c31f62a1c11478fe122f3a542471476cbc9102f0165e504279e8f10a615c6e0378760a08711bc4c6c0aab607b49ed38c3b99a714a1830d9dda50ac1356eac497ee648e25256588146370f6473d5a10fddc83a903cc2b44b373743c534a928dc43e3e4050ef09b8394916c9b742af2c98625961b3457b2df15d4e8b5adf900a50666837e73c2fe64e7d5abcff919b139902f41c3ac3d71551184f8d235b030a2cd3a9bf0a50887d79019e6742f3f49971bb840f888cb5333ad7248b7efa0ee4311fa05254cd2887d7757810a7596ac488fb7a56264b1ad92944d4438e8299a1e86a272fc2a9020a61bfb1939ae089041ab8ded7454ef6c1667c5db8cb6a0a6037f6393480236eb4a50189688541b24c8060b6dbf90b74c421c66a26a59bb8436c586c2222aef6a73d967278d386de5a11fbd214c19326b0e3c84c062cd0848a770082bf427932024a7119cd1b7890a9c979e82b8913775cb69131a8f7a332467e5b960e7d24caf487c209b00cb698703153332df2030e6b8e8d90cb79a2bea6641fd73bb678fcb6207a031601bedc25a1a38570d3427e05740a0559252c57ce95bc9cb6dc06841986cd6c2b87dc2127f0c79c3c87dc42ca5955c1afeaa51e88b1eb3949 +ciphertext = 145a3f597cec2eb6a94bb08cebb4198672ebfff7333a46efeae68bed9c95f9c5e92438bff519f8edb309ba9232772b19fd23fb23bf7b28ee59554f734809c8a5564af5ba710a66bf49d83e1d1a22380a536dd5c00261c724cedb33f5533dad0896d50220ffe4c26c438e443d2953212aafa08d26f7bdc71cd1806601d8afe68082398949f0aece599f671703267b026d5834eec3bfc0996cc4f2a42e4732b4c0b72a95e6015466e40409f90ca0a700f31bba486a5aad6bbb6c56755a193899634a5ed84cb479885994fb91443cd71472bb84e2a3195391c357a646c5e1dcb6a10c57bb471fb193dda8bd54d250176d8bf060d747c1687e1030c99b898f0d14808dbd8e4ac5294a2883e261ba72deea8bd07e71a5c34204051898468ebc51026cdb2e1aaf33e4eafca3f9546b1ed4f1b8fccd82c85f1f670a66fe82423f8be804c2a24777a8f4c1f42593ef2724780cc26aa06f848fc1730a07ba82dd45af80b54a08b34e3c078d65de8adbefd3453fb900c5cbe4cfc7dd34b193faec99a38ce6708aae8a59b74b19b76f9644d6b5912db74dc4b65585839d9a1ba9ed1d3cec11819ca8a8ae0b78661dd24651801348a8ffd9b4bc575bdd0ef8d47faeae376c8cce96c2b1b6dbab80dfb9ab6998c4c7dcdf438fd3c4a41cd4ba00110237e76a0d7ec65672555dc850cae8bf8203c8ffc8b4397d01be433e9fe0d8e1bfeacc4dcd9c521853b1ed51c17d97da751959b76f5497d0a0176ea2e26a13ba4f307a4fa642aeb68a9d7f0145c1501e0f5c05808866d8341f1434f1c3336d5642217a8ea9ea68fb53f96d19e77ae662f8db2a6add57783a28d766ca605fe5443a5ad1b56cb4ca3fc8b11f6d21e5cd5d434d7149b50e6a3c7b436be3f716e3cc9072d21576021ae54aa5721bd85300f82bd63dd9b88cb654c116f42c63d54e6bbef1d42bdb734e57028ce7032e8512d14539188b5f73e6ddce614a759f4079a241ab254718d7395c5f49f58510f06f1c87bbe4bfd3b15e178f04dc5f8b9f362692c2f695d2d794487ec8f7b59771464b14172d9bfbc1397eb17c913c926a4a3eb465af3fc5fb88b52c79a864f62349bdfd307f21a0df0539fc25b66802b4e61c7d9991ebc5dd73b3800ee55ef363607ac0a39aeef50d5186bc57673fb67d5d791f30ee3f73e51da25842b7266bad00ee33463b376818ca0d02ec08fd80c090947529da6fb74d8bebe2ac8ff2425ee95f49c7db4223222f10b8881fac940f944d3a0e47de5c94d29a45e5f46fda57e340b0ecf5d2b06ac443bf7d4ffdcd07e0305b9ff5befd3e49a7b99d8ceda81079188cc2e5a36c27c68f88681bb3fa0653dd26798721c5b68fedad318e567fc8e54a71d7cf790916f43cddac06b02abd4875a55eefa8997eaed57ccb9a794ea1e21f63b25e7e2e34f33e44b577b372ec4a6a071f03914c004b344c0608a6d3e52b65fca9843bcab2bbaf6b1efdf3b7897fe202ea0b9bef184f25d4a642cc0025a5f3b083a3905bfa579170b512dc36f84beaaa3a4a55f6 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = 09ac82d89314abfb6019ecbcb7d74fa2e3624ac16c19f3c713bab82d342b7670c589245d1515cbe0bbc7a9f13bf2276d3813ae503ab442186d5ce291d86581bf1bbe3821aab5fa8fa03a46593abc5f13c78669bad8787303179cf9ecabdf0648a809424012520f480d17da22c3984247651539 +ciphertext = 26c79949c58ca86bb58723456486121d6a485fab41a3c6c1d137d1f3e2b13adc03d8a1ca2d56332e47266bdd990bac11d2a2679185c0ff5ad0884c1a6f2f1ec31f949bc1df40d8da44b777d651c38be813543069c7bd40fc3044f2cb3d254e4d32108cc419545dd1d9a5bb51f1179bac5f1a9f9dae901a1853d877dcce8e7713a70441e8ad2a9a6a6cf3b4773ff96423b92093eae559d7e8440e6b545bd0508c010192c2425b581a8c4f9badf29269cf851b958689cd421bc65b8b3e3d33879a2e0c53383b479e4d12cb7516e194c809694a54d742fdcd0026573ab772853bab9fa8b19f411022394fefe84773c662e91f37d06b42640f39785205ba87d104c34179074a391e16330bf2eaa7507c4bc60fa1513428d762e776256362ce208329cf2e68a18fa772eea125e83b89aacf5be3faf02a7b55d855ac20e6d811b1b8ebda8537dd542436dee4acddfea06bfa7265f20e13a9c88c158252d5d9bf0651a62435d543c5b5aa45f32d84a55bfaffd2b9fb4029ebd3d9e79e69be774afdbb9371ac3bfdb50b13e7032878173a46900a9280e252003067c0820980ab99c445eb804756b5e48ee9ef2627efbbf2f09d02bd27d971c193612da50dc5ef0c45d7d2e00c28364c7200ac598ed8721f0d0af1bab3392f5004bcd815c8c94f66cf514fd18fbf3849e2f85e90adc547c913b734bb39b653f9c349737047ac3bc41d6fe1704caf9776c172e3c60c740546ca09a28fdce99efadbcda12116c263588346602dcacea32928aca1362de134de5293b804a4e8659339c73a06d1734517d835a3ddbee540b5dbd09b7948e585d016be68dea55c880a45624c3e9f1a0ea8d414b4a90f5684d39aa98b498e4c70235801cf382b6e3d681608f4c94c51d3dd6781ea3ee1ea1f9ec88ddfe82ea3e8671316a8dcb6e5176d4d83cbae94cebc9b038d8169de232424a07b10785d5c27d512f9d804f2801049f9a9a2995fa07f446e0d6a10a7d8c54800dfa996925f5f1963aef87a8c21519641f93303ef6abb66fd5a022fb706156b13f854f4095a6fce495597abc3c9b63affafa38603873ded0e4c673324d11e17e9da1698295f19bf3e614c11a3fe6f5de63561967d21589be16d4582668cc30235912e3fc8c467f6d12642691d6ffec9984a3b508fcf3afbbc7c5de8179aa4ffda5e1080ee4a7e5f7fc127b975e9c05a82d229b21efaefaada519e82fd0084be118c73a32f40624aee7558a89ac7aa6938b8af8946133e884c38f6bfe17922032fec3f2d9b4804fedcbe786b82ecc1b9f18bf8496f860f64052344b80f3f7f7dafc568a9f386268ad9810c93fa5041aa2630b1ad4f3084fda4195ac170ac17b7e66f004083a5e141bf7c547e2a924fc64360b31d604570ec652dcf8e3b9081f09ab70191c40e516f520b262a6cb7d6cbd8f1f7e0d26d7d723a7ad88551dc541834efc19ef493cde07d690060054223f5455b479f2008d4db007dd7f033e38a6d45bc91a12abb1a07412f5c085ce714d0420f377777c7b432252e46 +expected_result = fail +expected_shared_secret = + +comment = Private key too short +private_key = a8952b960a3c65e912b5b7480a243c62a6ab236b6bcd159c1b1b23cba6674f1ae621d818a22bac78f6b04dcec1a13c7ac4ff521c43c9a59ccb2d30573a77c80d9f244955d88414b479053c1f3fa69f74f221af0ab35b8978ba966502714ae94b2cab0867e25c2743b8757127884755b6e255939f113e0f89c2cbc56b1c021bc90c46579158c9ac8347069af5e81e1828961f99424c6934fd0ccd69ac892cc76799407010ab4f7fb64874778940683b53a9ca97b69a9e1a7b5908ab5d273a1a673859423ca951042c3bb2b0a1cd216aa7927c125d276a772959274aaed9684e2a0202cf503d1536ab21e730743ac658e7518f74b3b2aa3f1f629010875b4cd0182c6276b3803ad6300d48f9535961648b9c8aaa4a31d31906d3830078a58ae0175d062203e2711bd36b9234e8aee6c932769b2a7216059e59b8a8c37783b0b7bfd02959723bd8769d32224c4bca3f7ed68e47b234d22705c1f72bae2b2d57c904ebe4c0d1d3c4ff753424f95541fa8f0f588c3844618f4c9e8171235496230110ccef30870bb23b3c01820f9c9f915a8dc32acc812a6ea9811d3e9997863794f8f3851baa0e53e66121ab36c1840671699744b24a64788b17059bced231f04491b217749236367b86b34811113bd77ad6b3337478abe15acd5b74963c51ac09f27974a416e9c18ea112b463c391a23965e7549af0627043e006f160cbbcecad0b364c273c24a08c635d1b67abc48c2bf2777789cab798729e0a0d00cc76e9772bb76b53784038b9da3dfef331afc39b99880d378413f3d362f62486fe65a12b75923345c3b631afd9d01f805311ef69551367917a945df1d10c1d8c8a823c9ca5f036b6932814154f6f379e790250ffac4cf6a5c3bfd910e01637366cbccac57d67877a84819d5aab3c9b169ce7701e0bc48dfadabcfc657a1bb32f37fb233ca717e1174e5878b3f83902c9d8af2be9b3e8cbc5fae5a255e0caef4892385baf5688c33237681efcc92577931493c92bf6bd150005040452be47aaa90981273a01a640015c922102c51a61e42d679c4db77a04b998bbfe998b4bd9224ca805aa4a48f7226a91dc68da121fb3926d510604e87a2cc339a9d8accc40e79fdea64f7d82405b49a378c4746db4a7a777824d48ae69a8978202759a3610558598e083568d4b12c9b118b0f781f5c9b334795105d000aed31ee4d379430a8206b2356ce91404a5c370e679819007ca69942a55084ce837c6534b266562576486c25289b7f4690b295e03218a5ac38d5ab789b55a0222c015d700ce2726af3ad10a +ciphertext = c0266d91ebcadbc8aa09478711eb234aed58eb979047530e6e56b8e0fda779ae52cd9f1607810c90022fca9da350e86e0d52412e289ccf0e57a5a4567587256b39be77d243dba78d340ac504d7efaac5a263de4d264fb7d4627ebdcabaeb9f72fe4bb73ae7557a0d0ac1b0d3fe9a3623fd7a95e0bfd095835b5296080a5bf47b8eb5c08918f5a706fdd28cacf031f97e22d7fbbe375d3298f3c418b07bc24ad1d822822498e3a7de297b325456081eb505343151fe139ece0987a2c03197f21572ab9cb6cf331bcccd0b43b0c2f96c0319f79960a7475be47e81148fe33c252405596bc14e585a319ce6b78fb67d0caa0e6f6ba32f80d6e453b5f85cb770ada3b4848c159b0e6b733675ef6a2a53db85f2cf6f1645ee2feb4479b6592bed8222e6f10b12568fd44ba2b4cad3bdc1b8feaac7e54aedab7ed422ce9a61b7f411b287f09984e0e800c9b459bc40950f26707a79ae21b4237be2bed08d7ea8f4b51c6a87aabb16ae9fb3231baff800d2e95a8290c1ce4a66a2c435304dc155f961e14083247381c20e168d18912162ff7616cab1576f57a0ee89ce9107d9468cc18af75b5051bff84d554ffdfdf153278b52870d8df14c90069cf30ed00f5ee4ef6bc3dc8874ea5f8dc92a2a115055911cd7d805a5ddf938c940d773094925e23393c272dacdbcb25f2c4ab6473075bba4576f7503e435f5a0ac592c28fd8b96b93c006dbf654e7e1ffe5e9a81a95b2637c98b02a1bba845dc18c72b5fbe21b2d5d194632ed3723f5bef2ceb38d70bc2d78fdefc20950e456217f5cf9fe5a06b308b4a3b68ff26ef904b127be2cf0b5ebf7c10cc799d5821789924fc9b4f2eb1beb1406293a06bd25a4504fee8bf1f4725aa0e06b9614529389e8e9a9530a2eab640eda16c63493a977c356794695247cd3bab61e2e66eb0adcfae47f2b5279e7bcb0b1928ed9376452459dba1cb9fa275136ac0318bad75f3a0768f8db51ab5f59f7875fdc4fdffec198065f11d6662239b9f64aa604c56081cc874eaeb3ebda8e97b24ba5612750afff5219ecd924efd50a658c0e65839e9880c43f651c7a000d30d72586ff3e8fd623279f6bd62b54b111f90a9372aed19df9a5d0b1e79f0176e2b3b187c1769c44839c6c920019b816b01fb2e04f5a24ac3e9d76b144df778c2415dc34f8b9e8de9ca4cdffac8089818c1b44cf1ea741f1515a53e965d542362ec82e08addba4b635a53d26b273df246a915993d3b74b2854774ece40fe454ecbc67b179eaa08bd12ba1af4b43c1d29f0c920e9e04371d56846fb536a06cf5bbd0b21b107211b37c4650fb2f0e7b9307c704f18b139bd4ff94bee3e4cd08455d92bc220d765d217e45709f9ffdd0b6239147df1279b04c561332cf689b2c59d557f6663b7b74f95a0ec601a75bd7f5a0a7edd626c22869a0248a49a3b3338aac2698c48522828a1f94089b9e1b4b72ab62861fe19e3015de7ea59c5e72e9e42920d604c4b80f3fb95cf52c33b73bc5066126261ddc9257ca9803ef82e25cc4df +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = ebb2722d9399e9e3556d2ca77e773c2beb7beab8371a50c312da3f71e59205f46d09f4513ecab7454876752b5d7e9918a487305ea52718288170926d1026b03f604a645180721c35ade44ef0882aba250b3af274608b96f77a78c8c84ad0c61cdff09ec8756e06bc237a06945c931c8fd3b6e625159161115bbab663cbb072f117250995df412f0387c59be26548cbce54d7cf3b7a1917d0679a1818e49324d73c4b09e521794ace3962176ad5c4b47896c389cdb39b3b34c8ca788bb6b712baa5f4b9c5923b4f10abcd6670dca40ebf90a1a9ca6963f8bd04c872cf14228ba188e81979961a1442484801382e22f2b656946d72d0b7cea86d0d22b5d946639c2c053e2b23f99b501a6aa31b84a0d3080eba32bbc4178ce52b1e905767ff21a971eb69a04a78a636308b91ac001c5bfb6a784a5c7d82a3be9f960ee56bafc592c285f2b03a037ce886479f236e00b522755308a449ac19c78235eb7fc5c8b05aa87c5c52ad0dfa257b62aea7b7a1f1959d6f488620cb0189c50526a4be12c6833a4672c158cd08e8584503ccd0e92dce081ffafa8986787ec513a3cbb0493329473d05240d3768fea867e8d17f7f756007c16b77f26eca15199ad70b21a2cffeb3728f057e4cc35cb9f6c653c1c534ab5838882eaee80def0b3235a41cf103bd44cc90e6639e5d34bf3e479b44e4942b95c8c692b4aa985e996cae00d55825b00658abb407d13413237385402f15c057f471c56a35b399c870fa60c2dc276095113a12d6144a938b5c26a08ad001c8ea14b6994f58f42eeaf959734a6ca91b2b4af25ada8721bdb905b9ba652d844e8fb5c44b1a627b35204ab4b642f744300221668106af831edea552d948aba19448988bbb12e1b5a3f8a58f115735764eca0c3ecb1c5b37527e80fc1f481475b4176376f300b626968b9689822c131983a727a3cdd2493f245c0edac9965806604c3aa0cc2940f11152b46052aa15c3913c5f06cb9544accb235878dd0217602b652f7ac2e5aa43029acc7a6c1903d19a18982b06021c3367294f693936746294223a6ef54f3a19055675014d512cb9e6530c654a2bb8388b007063ba97817ca5cf56270e430a6a12c322b1b623f3aea320c4bc827840717da75c4b0f2ca860a53ad46cbde1e788554649bed41230ca3a1fa440e0fb7e356a95c5500fdf3510331c49b17b5943fa6c8ca223d4dc77d30895a7e96b7120a2e8723106aa29348c86f3994eebbbbe80f2bfb0406f8fd18ccbd045523659d218324edb5475139b06434e9c61a65b358febe8cc681c5bc069626c432224cc546f50769bb78c905059b064b636669cf491ac7e39c480c18d73b0270724bb6cca7175551eeda85166317b393081368b73678858bfd5a276d124561518e8b17017d072d94a1660176d9e8221fee774075c0a86c03aba902836f306f756857bc991854a2aeb1963a9f5a4b5e2b3c3aba0f28a4b997a66e5dc71b0566382799007084b311b4e55991c22e25ef6a39e3099bb89001ae7e29cbdc6b46e08106f694b189306a5b83cb6b11c7f47694e583b81d854f6a468c61cb69ca390b491a22f392439148a55b78f925a5e67214408d5b3f4751dbe6bbdbf62b3b3d794d3e6b0d444136176a539ac8cc848c272fc21c72c2785807c2c4a5392979287635a9822c760a9ba41a8034c344e35720a88aa104ab43614d47aae21b3644a519724a2c4192a4a73cb7cdb948b1c01b99c2c1ae093b45c79a6e29a3f0bc539c54b77420616e28d1ffb5f5e5768b6dbc9e112507280c306bc4892e61669017fcd640e68351b74299cc5143071e171ac7a933e3c13dafaba3c8c7cb7305c6a1aa846107be82093cecb66835a4c137c868e2b6f866796be2495cd20a772149b7720b6aeb9bd281c26bf4310f40ba9d9fcb6451396f291034af57d09b535cc712a4656087e120d6f08125fa80b74289955ca086792a6fd1040e8bb04633ccc109151c8b120c9825d02891b9330cb8019618f30ce29c5a7425390271551a8726c0a2872c179436c5c98de40ae37a15d734bc03295601da2cc153c57bc149f45e2138cb164136baf3e09bf64ec7c0ad9ac546c7f7cf2845b2c4c855ba3770ab35837143ca1b7f0c949e2085fda12c71992bec53626865637b359c576a08d39a6341dd864cc870f5282ac191a84f01a8a2ac92bc1fb8906547a28c7ce20643d8e328cbb403bb232567b724a13975e29337317780a60041d916b3165b0901af12a453582e84002bfa40b127100cb49063684adf77960d621803b58baeeb113cd175962513d8843a33d53c779f66f697c6d764a31c4b1230cf29554d6b0ec89bd7dc9a20ef6b8bf98b98fc71aac5559230b707bb352c5f38d3e7044e732b9c6e73cc1bb55b2f6294f1579b2272b31db59c4582194d67b2bf7b6486c94a0ecb8adba65e1498c87204c92b852e8027f0d8a2d1c6cc5a089bb611866bb284016f1773f2267bada4cfd26765a96a61ce398009c7ad5144ba0390a349440dafa11b2caa5ad025dbf28c3278133241602679a854ce13f904b618a7537223b6a57bc9b02b50376f2779f348ca61750645979aa9531ddcc99d1c0a34bf2b19ca53f73776c1edcb1bbf07d88e58bf1c50987c368edaa1450e0b3bff1c5cc5a6f0a814e47f21ff2a3658454c71dab744f7c8c028a4b1f423a9e428a9aa47dcc723f5bc62aa6136f877286cd76250d3a15f81a0d49bb9d617975bd3824e86601b6d883beb4038810a495533a8250267a619b3aab4dbdac0cbc6b3e0edbab4006a30121202a5cc4664a4822e93e0e45745ac4ce154cb2191815e709bf7db274b9f95785cc29ce34a9940670983045a434c83654231787447c05bd7b1029f3462365463915e1cb35183800a69b56e1ce9e8b561abc35c7d921eb9274d56b2f7464306ae86243339c8cf2b1c8762f5be66247d350a9212e7e31a07661c80de16a10f80ced926ccc17503c630fc84211a5380aedc88fdb3591019791653ccc41c38e7f50cae0f5b4b6f8cff7d470e1412663fb21c3e2a59b5545e042a6d4f8a71a7961d010339910ab93b783369a59779c824f6026c38932721a5cc88638f7e75b24c266e7fa6e844397edba755f1ac1d7a07825745a04db7f012717bfc547dcf858a7f912c51b9746469a9d830b81ba93507069244528e18305772745ab042d9ba206c3fc58ddf824b7f3a7e4d7b4028c3bf1985fca76369a3a675911ccf1163bb8f2a642554f367382cccc12e5bcdfcc17a9c0bcf576c1347851a8908034c7826003244c80befbd19559e01c59e9928c65172d48d9c47ed71c9005b9f8b24708129737459b6a21409e4b20a80ee946e8d9f731facde93115d1e27e2319004a45802c2bf328744eced7dc1493 +ciphertext = 0c4b16b07ef600f626a7fcde367516d5ddef3d0df463b18b8b8476d39ba07b476e20322d0526bb32be11efcac4190444dc0938b5aa77536c85a2e188d83cda7c188a86fee6318a33c209a3a8fa7b0df9d3959d5e7406616b37d15ab7124c9b9333add7e62a697c48144a181b105df046667c1c43d2d771c1aba0e536b959904cf878d4f50dcc1efa6b60eda0fe8f6dee31ea44d455a7b33004e602b45299f37502fba7dd4a23cb036051086e1ce67643066e0b306d26cf1c7bed88f7e911dc94b8f3c6192545b64a9a0f1726a70b963191b9b8e1cc71896a59d001b40c18c9b91ebda5adebd9a304c41c8d92 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 46c38949d6113f9094bc222806e2580fc3c938046971c7087462b48a11a358fa0ae1060905cb77b0815269fb631a6a012d2ac281d892c88aa7aaf96000c674ab182ed8a9a1961c073fcc830dc1067a83c37230674fb84c03588a3a980fd5dc61f802c0a728a03754b044e82221921c8c75b94ac0807188599190a0cf567eac0c5cb352b662e0518e98b6b5225f2bc4836560beaaf5218ed33df12b739b21ac4f1abba420bc7ae2aab82acc0df76f6d45a871a84a1a55054359825781bb57bb3c8d44ba50d66f42a221f4515235458b2612b91f0833b510242aab27e7e39e137a86ca8769abd62effbaaca6d6626c8b98610b2980875603f955bf7c5739f00ed07a9ae72938e65469d65b5df09964c72a93fd849b51a2c5f2a91eccbc298dac495da7cf12d0b5826c8419360588145a66aa9237385b30ccb276d07ba68706bc9aa6e6b2a87166045b142be457ab87b653eeea9163f0cee81c12006479d3c00e0f5878077527490109d7393935a361c8714dd508d0e3987addfc5528e06507833db9f086a5329c62f4512e6b0c60919f356538ce175473b1ba59136bbdccc7ced85a45101e5ee897b34b84260c21fc656d7d935c1983a2bbf4945a615c25587d9d1504311041bf350cfb263df1d2c65dcb95053255e64310f9344a2e81c4ace5904d2a58187a4af61336139b1353b77582a99c1e7957f08a635ea83855d148fe5a43dd6368787c6b8460340ec9676163135c09043041c9d06b440e2b962b731cb42ac93b148cb0910f74e48097f149914581f6079014070b63f8bde91a524982bacef6a86c530d2277beb0f03ea39577c8523ae9211d28e62283e22a66b7029ff2721fab83ffbc32d4aa2ef49237c143a4e5b621b9c24bd8e46412dc54fad077bb67cdab7c1d3c775b4cfc25c7553de68693932c84876caa7a16aac3454a3e7c5b27ac4b2ef6acd79c7c601888f84b1558fb17573b23fcb21765f8c919294c3ac7984f5b6270589dfb011bd3259e62d85b042208d9c24a8d045cc12a50f20b4d6e4b9f3d32a0527482b12c3ba5e94ca1873d223a38111839a1632d4d703594b6baea31796a478b50220154a8aabe91cbd8ecbef9abcd750ac3cd2365a8c6b22614b4b30ab25048780b567f542a332286a6bb36307e294207858f6d8c6c4296c53ad2713ec9500dea71b2890fd1b067750649a623bb6246a292829d97467a915c59d4a61200b5b261a1a1c9745f20955b058394fb858401633c69a18770a545599b9b05388480651cba8c8a79661de5179e1b31332f5cca5e8c083b019577819510e90e0c9aa2b21b1cd5f81394580009a03c1eac6e797083cc660408e7ab8635494d4ca1e7c94846714a33414f63b22992f49f3d2c3fc13b20761370c7131133301ac3457c5d560d5c14b47771232b954083201a2db052140aca5149a4eeea2bd1377826fa2b9bb339d337755a1caeadbb40a4d87b65d54e2c731858a470d5d53e17354d7a2106c1725928c53d7078ce9ba37bb2d13290ca850d475cd3d556ddd1be8ed08373f24a7bb37c9bd6a0b3d0ccc0e34efe28862beb71403c005fd67a3ef02aeb6440181332d0045810c33bd246136e9abd439b461b8794ea629a7d94131df909a8186bad61279f7c9870286f8430656f93cdf768a92bccc7a5c2c625eb5fce09198f48c4826866bab769022c66372402de89471e5340e8c36f929cbf3151b5f385316cc932676140b22aa69648b9f57054517cc4d8d7b012fcb6bac1105e356ef168294ce605f0626585b19d35814d14a70e9c911c17b33a1b5991a4c49f1939a0eb59951bc12f0631cfc35053df6a7f2ce2a0ad709c70f85c6b067122255882a0c8c849a9e5b3a4fe558a301890dea6529343992d01a86e744853f2adefea08a5f9354be119dec79ae1942ea9eba8f1401c9a67cc9c9b121b229d07904a860b8354f452ccf27250027004939d1a870142545c943019bc4402cf457f377495f2b4913bc8b1dbe448992229c3152449c16067402e3879813ed04124ec5ca42091e9b9a719c43a8db0076f3817d88aaab6075b0d658ed8250cbadbc4cc4b11d0d27e3901ad3ef295f5dc963865906742440d315e27a6b426fa8744a53f67ec4f45b05d6c69bf44ab21d8437f838011aaf920684a318988b1e23491a4f993b5192799e50dcfe6636112bcf7e6b09b9c33bf1222ef90b479187547f175ea7b1c82a28277025fb5e9156fe0618de6aeaf6196ad7204c381491ff99ab2aacd56e2cf6a1a00d3d6476c851274220328719988b235003575a939c4fa5a0385c68841f2cd0bb75823683c9b89350e061cb647819df2b8ae561f4e3678800b9ed9d846fe0c9aa14564301295c8ab6a89d917eb9ca1af72a64354b367cabb14e709f670be0bf8860ef421f563cf594936faca8ca17a2d2bfc956e7a2d6587ab1ca58a1f4a2ab410268e08b28b090da9e9251d1542625157102316ffb8c3847597fa6c885379c5cb2076d4003bd2c79f71238fb2f74382e976c49a127932aeb90497ca492ca0205fccf54c32278d274b80ff3a00dac59750d8347d45c6ae8356db8980d70883e3a6c9e03acdd9f662d4d18cf1051303b0116e5b3a57b57df2911a43aa901f534e3362769b66b7819917d51900d5974f28ca22eca471ddb538579bb53c20060a079bc29c9b7e696d654c4c5e31c221bb947872c9176064a0cc92620c7f607796ac0945a6591b836a22aa44b30f1a9bb16c98dfe123c3f2b7f3392c0d9468f0569eac27b29da4383cd879e25b590a86711e432f0f62816e647091238ddff90d0410cb920b9f2c628cae270a37712cb6872c37753a79517b3dfa87a655c40cf408700b781fe9693eb6bcd84a8efb103807a95c313a3d937b35148b06521271b672bbe8cc00779b76ea296cad716828936f4453898d884d2c71393af7069b18a62d7661d2458e8b767775783aaf374efe3c6952074f771065243c8c571a8d56eac30ab40ce8c11894257cd938259b5b6430370d2e2021c8716096905ff5c01aeac08f6779351ad18beb915bdec72b0dc6418dfa58dd37ca78b58bb00813aaeb1771ea2e13d98dc137908866990a8104caf70cfa7094fbf4812c8b408542461862acd2641c00bb695f61399f8a55454443cc328fed1bcac7ba8c8f822b2b0320bc72b3aaf96c331051728c78ef86039ab04b93340054439635c3331698782a16cd4f0a2cb958ae4063b6dd79297ca85b55fa2fb85c8b87f011649c632d44962eb1dedc2a727e6fa5abb5e6c7c334e858e94f2e501bcc495ed60c2ffad86a5ea0f0dd637b59a272b0b7f435628f1c9f0347fe9d831eae00bd96b4605da145b058842d32c0c463d56bf65dfe67e63a8e4983b33f880379ae53764dc1cfe0de4c +ciphertext = 0bbe90db +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 29d39ab1a8a69c9893a743374c1310d5721c1e80b33264c46f9995b0370fb4814114db6034092cb6107b1b0a13323ac6c3cb2d194c22b9ba5518f243052a56ea16758cd0bfbba991cc687abf35b5b659ca602a972d6654e8e46211b40e04f77aa68bc6c431c04d6a6cc1fb1c3be51d49366cbd250412108ce375050b75055ce32681127a1a70a33adba318e46211e71088ab9a16cb9497848ffd3bcf76b45d5223b65331038f14233b81a11d2c982aa16d73869c6e37c2a5d86dac515f83d023d72b21fae8a6b045bbb73b5695ca32ae6c4eeb38b0d7cb9c05c31d0e763857a18c94bcc2f4eb37ed14889f12cfb77b2f7724aa0f871ec9986604365147d120ada3cf2447352e3980a1e27401e6b85cf16ade72b78aa16ec1b5c8ee3b82c0c416018b344094594f936be0b504b9b11ef1e64b3cfcc686293f60f7016289a827200e319184eb8ab3187566c0d91eb75694f6f1ab21027c8e757d16203fd34aa25bfa1bd8ac0c32d63e52c82403e14e58507ef9b09f61070e21c19b325aa821f0965620cec7c32e17888bbf197855925d322890987bb49d5968a6683b1a1484c660214b254c27452415b78820a758d6cb805bc4770b9a6000f61d3a8b845aec01dcc4845ab82f6a880e75634b96789a53d0371e562736e36e83e820b0136d6977a296f5b8f40c0aaa91bf16084ce8e4092f0298378c1509a690aed64be11c3ef3909850f65a8a45258091346e67cca7e09d14613b84f42483252e026781803c39b47b2b2a6b7a5f80806a56294946a1f2d0c0db7c08e56a4e2229b81935ad5b31a396d59a4bf91f0cb6c3efa6b2a762a12335021f78579444367dd0457ae53e5215519f8454a9491adb07a97016b0d87cc7e167a35ba0181cbb298859c11d4a8b43bcbc793695f2030873251e72c75c435c1bb207c0c1fbb9b4aa0507221c7acbcac25cc4c71735da4781a72277ca416fe2b7c86f992104c825b37245067b8f9f095c1fa87b54e45456ea97da79b39a38262db81219ebab4b229b57cabf78769e0842017df68bd7fa3b88a1c54d9174f3ac5565872ea0e753d2a87265b60a3cb05b5bc4bb5308766974591f0692a58359006559555b929fe2ae3ca43dd6562ae71c3fa8355e1d69cce1fb420428c49981023409236615291ee27891755b7eeaa2d48710a9b86d02e2042cd20f284a5325e95c13c28f0bc8c2ea78c535f60df9761aa5e6a452c96e3f150f730a9333676e7f66363be3bd9756cb6f0c75cd509419dc0e095205b08ab356a43d936ca8daeab26bc32f67321abb551007a27ac5b63cb7f1b4c4608c7d87455ec020ad8425160c5ac2dac19157728762686ad08b4aa5544018c6296b845adcb39c7b1db32c3f633c55fc2981e1e9687f1433ad55b6ecb53bd45a8f6a262d0b8c6e0c0c10f821275d0b330fea22fd6400813658176259c8a93d0ee72bddd48f35b1a8cd7a221c995c43b5353996990da2c515a005247a7e7f670c027c73ba820108365651a9afa5f7a6af8c6b757055bd704126fa8d4571b041b39e642c95b6897e6f611db75168b077a5e532a299117342e7bd58458097d09f1a3a465af9c8e5a8c64ab0cf6c976b6a03c5f20743b2d0679d3ac559d6bd21582cd2ca9ee3709ec577415301af41a993cccb8a738c149ed5674ba60270948ac8360156b3abc633050369b2d568c0d218ad9c56a80da1ad485b8580409b17d4a0be13264c96aefaa9a2d3dc74a0336f956182ce72cf2e70bdc320b906632d85b45698e346ea436270722666d0ab2492978b389d19f11eb470c66a160c64187a23c8bd80c6ba96f8bc705c6f6628537c6676f1954b36092ae794311341455d401fde2a1153a64d26a65ce4394c90b5631aa37a90a2386f632fa91773fa3240f9e51ef83885c4c221472954b7772a2cbb14004107ba82533a888c306631990a9973366c4495a708b047a3e6572dfc3a44fc0bfd2535b0a08555710ead6a6b5567506d2a0a0c867452271d50ac1cbe61114564c5432a6683350b40aaa9afdb2100bd5641db6c24f474f63966fb97bd7f9c96eec52d5894792ff85f8eb98849387624493d3855b9ecf00a28b759da9a6ba69b0b825882fb275423a178b7972ef46a0f7c370608f6722bf87c5a051ce9d06b550ab0de0a79bc3a94d6c423f88c34820c64eea26b000208efbc467bf0084c107ed4149242a890362199e67327311253a0f1b1019a0eb81504bcc056570a9fb640191fc250729309ec51616c6015e3b10ca84ba18a2087c8468a0cb47bce9a0406a9778e776ab1206a174357897814a8c7b4289a71c2155041a95754c283b04b0d98d607547809f1068e2a2280c3a68a9840167ed74a93e85cd5c03911a374b1c826932696bbb27e95b9be7246660d649e1335a6f86cb8d0050ce2aba27d0a6e609177a431c9b773b9dbdcbc7c10c06d5c2f25149b4fc92d7e168b468a9c01d3b3f92344daa155c95c6d8d6837518736d027ce5dfb833bb8ce3ab991fe644575859e54980f9749412bf5ac5afc909017c9ff58970329a9374091d77a3f38d37c528210e3d7709821cf9925135bbc1184038b9e4bba36e73018e05880ccb2ba8b225a5211bc874af1975c4a92c17b420e8b6b06abb97f364a96aa0332870c097bd927e38c5d13c3bcc170528b892938510334596389cb90f7fba9ca09746aabbd24ec6fde933a11b706c61bc83d2a37d38811c3e4237dd4ce5c27593b256b745892859302b8803a3a6a0b2c24ced5f256cdfb01747816b3891301e07c73b3b845693b51015e48448966f58483a375bc3a402fbc0fc670af97dbc351124f933878310890ea81c24b541c05f041f9aa423c363a61d4abf7313ec09367a0e6c968706ecf3a7f49f46e151729afbb3c904a6d463478bd54cda44b633fbc2baec272fb463f9fb706d3d56d48789c8bf09d7fdc24e8b0a7cd4a0a549b7a9ee1353c1c62f8ac5df15cc2ad026203809f18e62c7d2129af991d01918b6ee76290c2200a37b400ac23efb7864eb3798434b4d4659ab914a601d2ad1f6371dd2ba75ea79bfcd9043ba5b2b3255bf87015fbea464251ccaffc61c3c19b69f5ac59d89e9aa97881cb19c4a65be4028ab6c2a2e8f339978265a12a3568e14e1fc26186314fa9928fea9a12aa825f22060bf3dc3ca16644e7755be0842a4d8464e1017d29a461498939eaa4b62bac0f61024c06f3a78ad81d07b5cd6c100c1ed63c4936c840d92d7c8b43c8a126e20b73b7e0b8dd0100cc6c3fd19e68e4bd15cc3e49a945a6fa25e859f131186a218081d3c32cd7367b64b156542a318df76069930fc9b98b00075502ee5308c2ff56fab8631b3fba8965ec0422b6a8bfc77cff0f4dade8d6881ae14b752dff539a255438a15f078df6 +ciphertext = ca830982817a5205f52345de9cf999a3f25ed3c9ee0615e85c5aedb235bf3364d529142dfd5278d9d93c6bfed13cc936c1a1257a3877c0ac20d01b865ca402bffc9cd91ac09972a59c47e1e1cbc3f5aeb0d3f1f7b81ace0e95d95af1b94bdaddc53f754d96075e8f40d2fc33876719a8a54da9482a36fe4ab5eb4f43a77db5a3e1b70f0f4c916def94a3eafb294ad3dc1aa4cc813efd9d902819235717025d22a4e8555329c3c29f870e510152ffa55d2c270053cef0ffe1a6a61921247c0c42b35068a270d7eed767e764504a9a5a76af986001ae11953369ca6ff5fcf89ead899daee3f3e3aed338c0af4dc452039ea1e547ab4835d54bdd13425d7cb858e9edb742cff399a71a24ad68adb39629bea78707ec7cd49968085253e5c18f4172398be96b2ef73524390e135a +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = c38a68b7c471e0bcba04068c9932b582cb13f19aa3c0132e608a7ef4a049bb33a4463ca5eac07906e64d503a13106b8d14d03500059f9db10554f26c1e63aaa5d011b9dc6d783c2a46a3aa146a08b0d40e477a1978da24dd331c8b4840921c8668b4b051d2a3d2525a67999c0270a4c2f6c6505c5c520499ef0a46b66b7fc3f585b1768d1a5238e00b96ae3466c511013caba627b099739c2f151c811c2a71af698141e709c5774c797a68a146180192a5f0a4c2a5033f9412c8dfb5789cfab9e6f916824696c130b18233ad8f4812a9daaed4fa53fe90463104af1ad7a6305300d4e91492f840afd8b7c2d93a1947ccfb2bba9c66c533d538343261cf7721abf803811c7d99e548e871a3a4f6b12dec0af25787f64585fc59acb465832d58b0c1027c5ad0ad34165e9698312862b5860042bed6955b8b025efb731455a87bc96af6db8a963a6da14b5fc456102ee1128ab2829da2aae361962f123af0f63ee5848e1024bbfe575d62980881b77fed127ec977023f4a08fb1042e832739f1cb28a9b161507368e595904b03d5ec904a9f39c55a91441169023011dc4755dc576c9aa73a751653161956ef2a368c6db5854594edfcb0abb726a4cd26440198e93566dfe6315448caddaac75e5fa9c4f29296b58b0cc0bbe66310589e9687a383434ab046612afbf4cb797db7aeb4a1ea7237e1c71a97941be6e9a34fa8a5f614034c41b7bfce6733d373744ec7e1bd0956c5bbe3fa28db16b5fa612992a27058f0a6af8283add9a46e6e52955cb6e150c89e471cfaef2ca9bf3aa2c77b8e43ab610b79b8362a1868539027b6d5bc9c34606a69c5a281d32506724cd9ea24141530d400a6f66193f35108784f0090ebb36cb24671f411f8f0068519761054ca8a0068686f497ccdbbd4096c087d6b436b79b2199a5bca3c36bb1ab9406bc945bb7f60411d1835a582c05c153409b899f99d4b10979711aa9b24f21b32c1082e8378c132b8511d373c6ebcc09056643dca47ca33d607575e5588a5c21a0267655e5764c7a6c92d911562c57018c774719a09f348ba8d8663474586e26b6a3c7a187ed342151c32053340ac6cb6166c28549624ac0e995a27b8a2779163fd213a02825d3d68e996b8a2dfc1db0e56d15c5bab426b5071a14ed5423013c9be8a2a8460a934afb8a5cf31f240758a808b2bec54b9aaa0518e24b61f35dac14c6a1623213593a65506fc7c3572800888cba27d7412b9b6715f4b0821fa3bf995a95f8e57938b9c78ec71fbef112c0ca5cd355107830722227b65eeb82d52a088c360102161e459a63515344eb0975c0854fbb282e7cd77cbc54b90fcc7c270769ead6380aa49021a25e53c54917326a80400d356494335b3c1d94af9ed3730b3973027b9e573b29dba18000dd8b03ec34e8f092026b5564d45d59a793709c48b988c9163c81e49707536497e473b0e35429b0e7239cd6793c26ac090c91cfe25961b43dd12923c5245f1532731a0bbc10fccd65d4368ee2a81ed50350a06de92a880933bc2ce74fe3520e0e864cc9fc54a40318c21774d75674bc98249b7b7d968ca85869adb2a2ccbbd1714c25870cdb05acc95048a6abda43a30eb003fba1c1f49788028cbb5854058eb335f6b08e3cd358600a846baa010d685e01fb3ba8939dc74753658953bfdc40c333b45beb8a2d65cef9ea4e47d0b75cac7fe0924a9fd4086e06b20da75d62174cce098699dc796bdb5621fc7e2b6751c07bc4ba2b3912ec902146a0f1f392cb470ea68ca2b391602e34c1d0c157d926b7af580ee207986a96661b296f15813016ab47e3435b1b11cabff5212c97214051b399f3384deb3c76125d5fd4a807229d57bca317cc2678042f7bc99d3fb107c8a81f9d076b35fb0e521249ee422c5a281d13e5856e582df24a6dd246b4ec26633d0a222b5051bf76bed0d09cdfeb8598e24f450c264ce67d50480aa9fb5ae771bf73974d17592153d5bff8523d2f98154a1b4d515c193e312ba9575c606c5b65260d22199601d03577d91400c70686961192357129db8ee4f015ec3446053a2d3d1acf1279784867308a43a0700c9017d60d9663ae3c5c9820e19a7bdb58f397121246162a9638a213600cc7a1817c42ae930220cbc160b3b2a504221629498a082090f778bd55c84e49142f8215f592254ad3762ebabbbd90313d43298f99b6f1ab7ed98a0eb4ac30ab9792a911049f9bb9f205776d879906782307c9ca594bc5490552847ba15ab1340d67b35ff94a7b61399fd7165651cb6c460fda0250c14ac79cc3c3e9484482c43a2d3083bde65e835909ceb47d587552ba481b1a03bcaabb46b3b652fe294bd6950c430a885ee495d02a6173664f2569be4b7c26ce4b815686af09fc2478c06e9c220828c78fa4337096055337e144335b3e92876c71965ceedcb31f2c0f72a2423475351bb15a3ff4a7bc54a670da3135816aa42b4c293a2a3290b49e16c6cca40d5b71c3128c3f4563b47940cde1c5501573329cda2d0d95c572004db0816408c04f12143ad806cb89370214eab8da9884d679a3332a2684f451a405176aa580e2f6336f8c45a25061383c323e2136baab2bf17a8bce002b639180bdb5522db7a36bb33d09c38e58345073f2a6640045b2f3133203a0dda48f625200710350c79132544c2670e9a095209ca309a799bc274b371eff582415f6c6201236fd7b0147b52ea0c11d68d77120b7af50b14b28c5788fd5a30d31c128038bd8607e7d427870c126bd816a4f53026f4274a077c10c6c3b9ab066738ac254143fba8712a2fab21cd62435ba4e70b8507560b75886cc35959bf1bbbe23ba03c2788c9f5284ce2449d5901ad9d125ffab841ce0437a41206927109d2c22e964a300e14e76500614e9bc8fccab46547bcfa855f18567a18a6027b5740346b0f96bbc0bb97432950f12903379eb8a51a2a9acf6afca00ccd5bc6fe218410772a19142599b7b4f74b36eae8a648b2812fa0ca9f4b57e4de16d4d07b0dac3b2c96844331044c876b61c4b95a3bb45fc08b6ebe17b63456046e79bf4871238b1124da74a73e30a53eb91e417176224c08218b0a86103dd811c9dd152fc90671a1c43294163b237b48517042da50c32fc703cc067f3e0bdd4ccb558f7667fc6baeec73e9b423c54cc70ff6319b1e6ce7f8b6dc347345b9abc3b3c948efa6e02e60c459851dccb5bf7d20d7ff3787ae55fe3455cf0172ce4685936cb0e50b64305794d7b454b3fb1a476666fc368613e5a01119188c18cf6a4065f7c62c5ccff60a432203a00ca4b5b44149266a373894346e963ada1ee0537ba2e499ff422d22a656c1abaf85b0a6b2672d3944f48d7ba79bdfe223a0df0303581c94dde083450c85ecf4d50 +ciphertext = 2d8ee9c8c9183e29ed6a7f09bcaba8d6229e31f667953f +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 00898870d270ff2a15992c7a9dc06110073492cc8be92b678032a790d2571aaa47f562cef776619dd0ba14105028c99824839505b81c72979948cb66a7218efaab7ddcb0102cd6848131b8ab589624ea2f6f5655dbfc0b9db5ccd49c081cd294f467055b770f2d1c41a1918d094a5c2020831dc48290b4a38af050392b441a58b5c4877a3fe847d9a521f4605b38a4471168afa8b544971361a990931fe1a7b066596a290362299cb12a9a7111195250287795274fb55166840a29a30199b06082767eda376c7db9b6ee868f9e7a7f87dca231f160b1f64a3a573fd1e70acb04438f22561de341f9a31408706b6c723dbaa9a2a0ec8e6aaba2f95036b6843f9a9b0256091ee1e43631396b2c3891f424631b93cd47c7533ae3a317fc2e71310cba26322db21dcb2788709bb58a1bbecd703d5f55ca80ea3565c925817551e2433bb174a2873015b2e62b51c0bded35b2678574f4d0719a571bfd8a1738429152d19f2bb3354083ae503344d5257f7b7276f6b33bafd918efd12c51e6aff19cba860cbc87d1857062c925fb8d7fb30ca6c718386c2b747b6e58062f641c8d2870193dd1c7b0236e6a291c5afb485970c8237368bc7ccc834675f1c051ecd6617cd24b5d405607cb38e94132c6087e87d85194760b259711eca333b3f094f0857fb97bbea6c3c29b10caff2439e2b0cd54675569744bc8c90a957275d6e664e83727be50afa2f69a42722e3f25bb3e6ca0cdf88668795071b6ad69d46339623b85b3468976794fdc33aaaa238c9700c9eb1f533a243c472cbc3c0b1591782a382d0925852e63289137b316378dd8620803f2bb21a88fbfe1bc2b85392be885a1a0b7dd1a42bcfb93a0c75be7499c64a08f6d0c9d72f350df424309697aeb76777eb33cf1e81b8dab5662308ec5412a465b5393d49777b688827c7c86018c37f0c617da35aa973864d02074b914d45262f7d7c51e286ee122360b430cc079c8a141bc24d13ffdd34797b3b175c6407307464ff388540078fcd5692f8a5a207929c47baa40207183da214eb16e7b245bc265148ce71f9f87c56fc8096966c6d4f4af51423ac95ca14d4426070ab38f6c10d8d5cf64e611ea67006249a4bc918e008a55c9e70ecb478e515a33f385099e07a89eab000635b1f6e93f905338cf048fcfe00a940395d4924c95e3a1ec214d26db2c363036b7033c0bf5a505c3c9a6c3836540a39369ba942473e3e32567484ac561b37904ce8f3929f1e468a830070545a817941254b94e28cc8d47143bada20889a562f8c355de718aab0061b4e8b1e616a595e990d8dca12e823bd7794516d0ce94733c71974ab98b1831b581ead05694806ce447931bfa2c1769b15a6a00c9fa0bf6144715a22135c403126b2b8566b6a9378ae605c378d72ee7c97eeb268173261ba0c50f5d565051597ec89646fd979f79211f465b3087b5834bc83b7ecb9d38c399f0fc3aadaab5e1140af1501844e55b9d14bb6f61630a0673a70b4408e051231a73417753b998222e284539f452724010407233e45bac21148989e78fbefbb2258a5926e23f3d2a439bb55c13c9a87cd93e3850b43f58c41de101d5d83c6ab7b765f22ed78775421a3df9f4a8bd35af693b5814e54a52b305794c8e64507742f9823926889881514ae9b6d2986a167326cce5ae6a3736b203a472b8bcee509d3a76c30a8518a2a4240c2981b597584469a5cbd7b5e3f81ef2233056971ba53c941f94a7717a7f3f57a0d4a8b500135595843612fa479a799e62a51379eacfe193b59f5a9f7b754a7c279f77156f7ed7ad122b0ed1a277601b4f1bf9a015c83a5c089a42c75de57ac0d7a5648f0657968220ac569d24799c33c297f4e8cec5019c71c75b79313d87b43d20b9a2898a36217c2fde3956357736321013fa375d6a985aa110c47d69850fa362a1f02f82a5cbf0b3c7ba16ac5b53a0fe2761db31c063e32f476676ecc02b05f38bce8c1552b29f8bbc3b73b54c6d0ca4327c383f4b3012c3a59e8b4c26b58622c749a55c2ff84022e101b4d6d5b3c4d475cfa863e3979a326c4116813dbef80f15e40c70833ccae6bc6e059343e9cbf721b641f73715d50f284a427b16bf84481b2b32c790910f40e54ad23115346671311aa9aa399282e6243325070fd43a985c77abf52121858e739577dbbc58ad93151f736aee9507f05a426c22b474b1aa55036da93007d275168d0c2e66aabe37b52ce778146134bfdb249d289b41eb6047a0aa852d231aaf233ea7a6ac020684e37a42dbb00ae965ae398c58238ba41cf59215e15e9cc0ad1a7b3713d03217d2bfdc8607c7e94dc52a9515f2253679c5a14119857451c5342c6743a2a7ac9e1c534c42b56085702b5fc57592d425ebc3215786ccf357077a7ab7e95237ceb5930924acb67645f7398282440781684ab400a8435bbb7da50ab0495637a96a55320e99515601da00c353260c9c11f623602f8a132fc9c83a1659887a474bf98f26628e0221b6e636966749a51da5b983bb6109d99bb28c9df5e916c41762eff7a3101c7e0bb22eba1b80606cc5029a4cb720b19495b94688742a6879cc85b676316f5f88609557c868bc50eb26c1b76b3fc0e491127a9989739ac281ba26ac3a09d4ab115744151307d17c281ffa02a67b17c329a8444cac9ac8b1b1505c80ebcae04239b3526cb00246a4827c31e150b96658b81b8ea8c27db041664b0481be775fa678a08eeb93be0291f9e776951479a48ba2210623f0fa12ad456f0713346bd12177053c33d471986425c9027ebd6a392296a1e66503b1f841f8c568d9655f3c4980cae92cf38a9412359b12f773af16c1ee97ce83557f7178478029bc3956c0d78728d4818a622574f4e1201040791a415d70d4b960a74793b77fc6094328b6319f461a0979a925c64d237126bee5502bc21359069e9fc22ee4d73ea9ec26a1b65f5ec18f52279b2f06555634b7f905c37e499003ea9124f8ba892c65bfea9905379076b84eeeb68ee9837c92a600e94a2f9c999bf4c38e4f04cfbfe17a4b5c75a4690b85733e37ab25a3796e82d6bbc810b59d34595a0c54912716b3e28ffe62483f3c05aff35fb67249e0c1a433b285f04294e3b7ad1497114bf8a949f0b62f17659655490ed9bc5b434df9214bdeb6b2a87211785c0fc3b93ae0b1967b6a9ed4cb6ed7412c01f6ae41c47427f4033ac98c9558514c76bc56815741d2cc808ac652ea1db769680fc0309c145f60160773d9e295c66afad698ae4bf31c4501c132413be24e021c8ac037df668838c20caec776de8e1b086bfd881713432939d9b3e11ca24d9b41e489334966878af72f822efb5625bef5639463dceb90e569861dd289eb7497e22f561e93502ad61e0d +ciphertext = 7740ebe479fb814c785d4af508ce60b038d92185cc0a31147a1bde6a145c4ac5958f33857e14c34c3aca6b891067b8bacddc7513a9261d1ed31b9414ce41d19329a7f6a470294603788c3824ce2bdb3d7630fbb0cac6cf691b8613f715976a698b828878aa916f32963362d819a1d11a37fa9955026b3f96dac7ee293a6809b381a4d68004548da64c59119317b3cd07fec52e1fec724161796f603a29481eb0177769a499162685e37c28fedf250b6c33d590fb84ee75d1cfb18b21f747330d1b60fa36df5510a2a7535050c2ff533fa9400c0604e0b4a39800677375c53840b864c5df4a87fc945da7aedac43124c1e4c096a561f6bf3ef2c42db57a3700b7 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 3c5c0d53c500edcb0d9619849dfc8a93e32bd13365387353eb3b423ad58200dc61d0d3783758cb289336275687d71687b4e451fcb88494f9bc61316d73718192bc95e2578b1118c58ce14fc14195721042fef22fe41862484b47a35c724be764bee25f884540b12854227b9c0c5ca5375c0c3a84244f09ca639cbe15e59ed3d69d35856d4e2b01ed82cea25979f7848570aa594912457cc8a594742bbf5a0ea0013ca3d589f26637031881108181b71645a2f7726226967ff395c877a706a55dfa5ccbb84519ffd618ebd8484112bd8f3366bd84accf4c734aa8325e135faa562e1e7a9ceab673f4c77232c481a98a3751e93b361c01cc0656a32a960aa5699a94c374b71417f28cb8b9b04ac343d5b444defc91f129b3ad55744624bd3349a21d63524d59c4fe8cafd8b9511961771aa4648139a68d1910a01b56ecf7c71f973d29bb0a3901974c112a5f766f3aeccf5cfcb228c6927093872fb027514baf6ee47428822155cccee6b0aa758b8b5eba3a192806a8bb55a4c603399c13e9f100c59bb75a3001e1443062f8c630c7a8524037352c72fbc86d8ab0b0d3b670f68770106a8c6b2a70c1bc31bc1254487421b637bdaee605a065bcbbe44cde262dfc3643bb124535f7bdd7c41745d7728142c889718c72c07beb85a1c73c0546411dfebc9d49b899ef35bd69d5bf98284e74817ab347376f6972ea5440745386179b4de60bb40f2ac320647c473255eaac7dab60a8a7ea3f9c1523ccd519209892301b9e88803804da05e7aababcf576425a72936579df36bcb9c83fac2c95e9a990bd171a2a0cae3cb86fdee357a24408a5099cf3d723b55c5faa1b1337d26d6029bf0c021517e54bed6bcab9db3c23e7b657216000e2775a2455fb1089597437388b86a89863ada2598d1597ee830271f57dee1253afaab16e50c54a88b1576ca12b83321894515f0bcb7ce5ba2648ace1b44ec0d80df29c1d0949727fd447e8601b7a064e7e5cab55ac7900e18b1b1787ba6b00681968e3f15d1112451fb34112e09bfdd7124d88ac181a545752a0f94b5f98971e47492f9a5914f1052867c4763ab90183652900d53f4e278624ac1e625a421f8c399ecb8a1a26011de3a7a47aac319a86cffa8646053c3382afb7a7ae0a7692f92b045adb6e82e769e6053a3d03928c58c0c92c63a1a802b7d89c1a2530b2d118722b698bf2b63fa9026a95a998c6c8b549c4c17437b0e9c4e1ac65e1f443eb77c3cc646d251c538502b98d3c36808bbad2008f5e4016f4abb4817c9a523b9e6cd7167c3cb9e16a7bbe3b75522b4bd89272e9f33fa1462015215f3b592e2468176da0345b5a00bdb5bd93c50a6eba4e9de37d1637bad53b9600b54ac4dc2c08902c59a8a640a2c47233bedb307ce6f386d0c81fd6b7141e9b1b81db41e318c7f819a35d89445d532baf2c97ccc5690febb62fd77bb4fa55b6a4cfaf0a577873c4a655980a39bbbbe57e8ed480c1702854d8bbe97b15abe3948746ba74b62af9671553cb4a3dc9408c52cf7d960698fc9540831deb67a8429cc6300bc51ef7b8357ca7d80a03729a49b41c465612935c739f57e577a90115ee83719d902036d5b48c4b824d3939c1ca90b0f699b1471faf802870ec3ea53523bff916cb86c506460fcb0ab29d7738ef7a04dba0b51ec5c0a53bb5b08572fdc91e5aa336e9a54303286496b90877f6c30591840cd8780d216a8a27c4aaa04064d7551f2c2b00572a10d5c40e8b145b06213411cdce7c137c812c7e092dec3890b4ec288e07807a632158c7acee2c05d349a4ab4229d3bc4d9f3715074532eec4c8150866f6c9277c021431f0aaa42b338a48c269a47943e2afcf349f220093fcc2147ee02cdee62531523759c86aa6c12ace0bb58228a90aac7b3c356b9e841d3e5a86110062e5204f05d5a4f37a918874aa42166258a8ad7770577052b0db5143637c81e702a0b80b627071cbfc2c6e76560def065fb9222e0f225bf82787b84727ebab58850c3576201af8e56716572beb3601d5f3933dc66179675b396b6e62386c76a67753c891d6d54eb97c780d74633de87b51c3975dc0064d7081e08647afb78c882619b74017cf5958be5a579fea4919f18e4afbbbd9c9cb89862505b7b15693896be8067f99275212b149c343f448c3ab04adff7a7d23f039e773007a4b875252557d1a558ab46c81792fe8e9738750c4743a5b98a45f813759d283491a276c31ac24fdcc469c1a9d97a4bf0cc6360bfa7cb99020ce2954a21408d1231c3032100e782c9da54cc48a21015490b5ca7dbf36acea0581a466ce833080465638e067b1d7b004f0108634f04ec70a4c8d068d08314c74cb26e4a35910ac8739c2a6348b7d53e581f0c99f74d4cd2391237b6a9a35097d18260b9ad6a0e8f431d8f67a04435b11386feb9472159cbca5b30c3e3708bf6541c6a881c46046249b2d97040ca9faabc31544ccb0137b08a7b34888aed9ac7a046c4ca4acc7eb349d6b0fd3f41e8bf9a1c2d0cb7f5064edebbc478ca6fc334a11f35fc6e83b5da631f9fa6ab55abee5cc876e2cc1988c264f2a95241c6ab12a672ca8b32b1139fa883c54c60a85c8963d5615f081b5b93a0be6f1928087178d3497d8709d10d9081016bd3e31492347585d8973308873f72c624e55358a6a59855070bb2bb388c39174ca3316d55a422869dc02633efc6be851005e3a8c3951a6c19a5e9bbb6e6c0c5e47786de86976fd261757c8a38d5a27a80518eb990df8b2600d1966469281c3e941c5e32b2e8923726498513b0f29b7a796660d47f20653b9a7b775c46d8428bba6277995cfeda931e2bc25b062aa6e579069388053e607ed49a7a547219f324cdc0c743bca0a68cc388580afb97444a6b802bb7abdb29433896b63ccb92445c4489afc2b5cd7b2b6c34e2b2539500598db359f1aa9b0e025abae722a9908a039663646f077bc55cdb49a25aa2a4a02b77affa7196e5c036d2473a0113744f0a5fdda0419f17303c7b3684239d5744e36c6a2e9697583e723644a3cc0f8cf324487cc3c4cfb6c545dd7bb267087200b76a0704c28a2496ba22f9a02684f226d0d2a7c1caa75c6468c8358333b71300a810b26aa4da633974281aa5c97925eb19b844974f6c68bf31a5100863d45e50131d801667a0911671bb9220c138b0223b84181aa6e892a1954f5261ceca06604123b5a960e123468ac6c8fc55c6e813e88e64d4df269e176011bca3ea336099620969280dc13ef94e3997898ad7c1104d5263fc40bb74f033d76ef2f00d27b8a8a955b3d3b69b0f9eb43907ff1b3d28967eb20fc7887eed16ed0f3bb57249121453422a0309cd19aebd84e1ff4989a0392b5052fc6490b251f2c5987fb4023b33e98 +ciphertext = 5fa025b1aaf7491df0f54fc7ebc30b4aa0ad58d447ad03a6b8cdc8d2367606516f72ff74f97f9a59a092dfecdf78c5dcc49a386a0a727e88023c1dfbe2e3e6f98339abf22cb8ffe1fc47de7ad9faec111eea17cef0817b7fbdfbf15aaa56eb97180cdab46452af9c45af +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 6b652faddc68f13cc7efa2c6b3e640aea46088801f2c95177a1b6cd5199b23c337422b113607cd0a57c479e58bbf241b200a9cba92c35e753eb6773b55300397718249e25eb817c8b12b5fd252b143dbbc4167bfd83a998f9244c48a7b436c5ed0c5b59d2789b07c6873c23682497f4ec8004b792c46f619fbb0a783fa14c477a6cc32916ada5192021141fa36e4c5439ba9389a3543c12c3a9d679c1d6c14887754256147ccfc9d198cc3283b3112d8af12e81e1521987de534d1d95fab18aaeb30036c08a0d2808acaf1672ce1131a94474143b6a64c8a28850cf866a3c5dc9634929052e96e1745b04145881d253548ac1e1df0292cea326769bb5e990ef1c5419e4845f793435a6c450362c5c5e1754310a386446442d4148ea7530ec52153c4c38874a913892903dc0289b3b559ca092f8908abe556bf96ca5d058776ccbae45bab7820b820d6a9f346622e13820918af3422c3e273002e27810fab162a481c5cb241e225a7d84cc788256a602b935cc7bc18da63a9189a43d03d192748e3a69d9efa2c03c628b758c25dc19c94411dd883728979c9c26c880aeba9c1a2b7ac068bf7561c8052b58c2477b0b5348806566392c28322cf38460e29e31ea65791d9a0cc7f9759f3112682e19fee942fe7688e5937cf75513ad05a1ba0468ee8c17e7f3a9ec0531a3643c97d337e2952b6ebbc0134e2c280ab2c8f21b4269b5019a466ba1434ca855624527161f903ca71527ba4cf83e73702833d59642bc0d7962e0a0ad348883baccbd6642346f91b7966ba9db25760d72bcf890dd6735dfe4a85a3571dce891034cccbd9427e9c7226a1b211b12536b92b30d19cce9c521273fa30412903f2aa62bae39a795743d5852436f843082791e2e86f096a15f9d542adc7258baa5054264d417b28d67423ba5816052219107a1b44f361bdbc8121774a520ca57d54bd9116a56f28a5076c78cca66eb2f00090fc17857b60bf6379157227e28ab4de40670089429d8177ba263ce963ae68ac595a986b48c6787800b78c06c1c2021c79c693d57009986923a26c17f77bab3b6260351634b4fc5e6859475b931ab4048e9d83301f3cb1671080ac84aa4318bfbf9174dde2b7fc80928748007b647c95637f2e1ca998b8b31f720dbdd8821f07736a087a80a3ce8ba8cb28da901e200939b095177c09016b8f06463a57b06aaa6959530144d770b5bedb09b9516c4653b35f546dec9ab68bb74449ba3e76356ecf48c0a9734ffc09791019637c97491a2b7fdf7aa00d465a2c94cdddd8450b6b139fb2671d3c2abf16c16a9c4455826c5998806d19983e7b13acb328d751240235520bbabb4fd78d2de29044999bbed17fa816575834b1928a20872014ab9b9b44477da7058fe700430481726ba354fef1471a86122ed46cc7365df0e7b61614c833962b16b84480d06221d6a131b59ee689117f05b6f0da57fe1c024c32b18a67060b459d685210033a5e0f5b8db752661099621733caca4c0fd6015287174c51d9c79ba3790282c99361beef8a28b6b84c4bda5c7254c81b98af0a53a27ae40bfd94010b81651b991894533877ea78b9e4a8c61a69a8c14eb3a8763f1207c6e6293bd69c1f70385c67844d5450baa975f5e376255b4bf38426a1390be6d047696a357089c0c2c3c3a968ae279689cc58cfe6e0bad474206a1889d125a695787720fba7debab84afba6e7b45ddf8405df9c8c88cc87db2247e3c16342ac53939c6983590de0aba7acfba21063a642fa7b40dc090f9a718800829d369372c4462c32ad9266c314c3a9d3ba8820363d19a0b21130103f44496ee5ab359b91c2eab4200481990698a39bc2dae05ab0e169a9065378cb952d845534c73220524699cc94b701c862e2cbf9b6ceac6b4e3c003da37a963137655bd99fa55a88fc5140c29465788532ca92a314d55a4a7b84f9f7729296a984700b50d45a5c051ca4f3ac37f85795a74319520acddac8f4cb22ac3149cbd67f00e6a90dd01e9013c1ff8b654cf38b17253a0b165af5b31048fb0aa5b18645d47441a84ff33121985456aa66363aa61053b11354f2b426aa285077086f099ddab0898e052762ca4dbe1ca341f95ef89b53cbb74de9e5573c8c2e49dcc8e1dc0b0ae15a66b7a8578242cddb4d2419b743c1bd889a1c8df61ca196b6c1cc63c8e5a36a513feb4672f18c358192013e946aa79023fe65a62cc3acfeea6cff90384c31b909347fbdd87ee0e98984e4a4eb56be1b13b008d9b9ce30a6e2e34771db4eda636cf285c0e1397d57608fbd28b09881b54ea153f8c67335515d803a33a64526c86c02e3ac2f6e236fdf9105beea7ae046ada825340a0a50c35a3f1e2a5548746e24419793fa4695a75429534c5aca1676e4b1545747c1513f50f2a1c25c0bbcc1c25a3566a8f6431a2668fdb0aa66f2a021a582f5aa099651b4e1028381ab75fbd7745342164ee6a772806828198315fb0f78ca4cf9e43fa9e8c37018672c5808037375f3d295141b4ecaa088ba05af1298b14b135869f12258b61349e7c55d65585c00ae95570e67ca332fd984cdbcae02781868230531f04654f445d5135cc29359bd905b33f418e20b4410acc856f641a825b44d6a74c18416f55a4b270690f44b9f96d332fc220629739a3be83afe669d2aca1e64e738e0253c5323609a513dcf169cfdca145e3801d8671398d66aa66b76201c26ab542a6ee52d9ac86c72bc6d48a6528dc2136e6169d2e145aea9ca77e4c66968444ea28444927c0c7547fa68052ce435f377ac9b421c04c4a0b679964913773f91af21c8a3ef589ad03382ef20c80fca33334106f8031f043c6e28c3783387c14365c1d4e724fdc2579ba350232a4654122421588bc70628a7d74196cb228cac2ba563646fe28a5c664f6bbc519acb0277134364e9af4917cf6d044fcae443fe7995c3d6c75be1be68f9535f742ae0631da926c1125a217d085499983344a56eeee814167c6bbf206e3e1b50ebe056cc68ba5f555d4b1512ed6226ede5503fa192a913a15c6616d7967091419a9f174752797bb50ccf063116edb389b30cab1bf423abcca4843b8cbf37ad4893b6c0003b2e81757d283d59d75f92f8960585b16e06b6009688c6462511994b626377dc5742261b24f069944036b33b5231fd0133bbaa97d4588cc481a96ed47de5664d9abb708c613795e056e095b4bc39a693c120dea4489d8c5eaf10a686b82ab1e5cf348507a6579f8cfaa193f16609f692e32dbb7a1a3c7b7fb6ebad772a8f9a8ed39e13e5dfbe99266a5ac4c24930b6a5e666c42a90b159a95bd257b37b9d5059b9a6c9fce2c1ff8d283fbb1448f52782f1038cd22aca84778ebb5d9c3b10b1b597d3ea3bee7c36e51b67 +ciphertext = 842007561121c3499621d5848c5947b32dc90aedf6e48207d5843e60140c82f8a1c74d5ad2c5326473167976f8b57e0da871901a00f166d0d089098d534ce887238c2aa1db86c45c3eaf035d5c47cece1140988ac508917bfaaf81e0f4a0004d30d720e8ca70b9a87d0446df45dd3973e2f30eb62089f9ce30eb10b7b2c2829ddbc9ecc06e378f421c380508e96bb684161c49610695d2fa5a3c7a1e34aa80a73d283881df82ba2749cdbb85b39c252aa60e517866958c9e7a507f19fb409e19d16a08d0fe5fc23eec20bfb73624494c1ec8258eb180daf9552547ae2fccf5c0a0c3ac1d96a51208f842b5c67c3b3a8952ad1d722815b8f4eb5d97c735231bdaaf62a9bb3e21913bab5cb6787cf4b7fcfa436fa08ef7314dff2c96df80b27bdad2db2d5ae244cbf7633f389ad2eb5011b5755c1f48b246e1ccad02750b1470191ba9d19dd900932a13e62342bf7a22db107679ac5c0f8a1d60614eb64a6a4b7eeddac2be87cbddf44a226c160d +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 008890c48166e3930f3e91186e065655f19f713c1993eb7bf14919792ac68e37b3af6334dc4862b5a96243841650e9b9711684ada66cb423986f79818e522b2ec17236934ce99070f9f48ce70681153572d5f01f7f9a824523bbcb9766db6b792a711b14d69c441132c94aa96a368c63a65109c89b53742ca34177d4564c28352ea60a6cd69905a5c7375cdc227cd434db2652aaea96c143afbcb075f88086ccb8c318f165b236aebda0c9a1d415b20c3f833b754ca863e9b018d8e2cd584366d33698fc76013d8c265bf3cb3382225dc1b92af39c91f21731cc3801fa89cceac0e5a319a8042b902bae4b774f53987a39116a72b99387a3520e563411a0185f36b663a3bcda336fb5b30e9f5480f57572febcaeca6c172c49c9b7e1ab0b32935089cf870061daf11367e19aad67986a258e56812fd48a7ffbb409d2817ee275926825c272e9b2fb9ac342fb67137772f199440dca7be46774dd9cbd2a3804dce2ba1d364c00b59740f95aaa0003fbd5b1d3791f0d4c1e9119ca1037b611538416513f12b671d57b9e7372a98ddc71eb103399d38f1ce5329f91381cf9c02d965080b639173a079b751f45ec8b326a2cea676ad3594eb93492d292a48ab486fe3361c1891f15f618f591ad251c7a086c1876f7601a10b04952c4adf440abe6077f49903964088a000003eb6a84b254bdd3315bca1cfb454eadc4a375582f670cc9e63b77dd505a02f7577c6003e80aa4a3f81358970f94c0a5b4fca74e811d58a3955d18be95922f53ac9e6a506a3358ae110a89352c9b08826e5bf462585b103efb943ac1372e305253ab3672e92ad793456c53cfeed643545455d5f907f5407c91b811f6cb4ff2296b3ada7d43023272675d1ff20e5db71ec8307bf82973ad6c15c67b8268f9aee7564f7c84633df3a9414a47fa4611f8458047785226e0191784703d020f47b9898480b985e77e01c59eb59a601aa182e5cc1d71e88a0a298fcaa495fb739a35322b5e3908d03c0f3a701479c50cc60b62e59390445c5d9d4b902a385a25a11a80a343ea7996ff258362292d71991a90990d3b860fb6f5ba930ab09f13af95e507bf278a480956caf183e1ccc1be4628665c036acc3b56e742a21c5e1f394190290249d5363359b88cf8468f90ad47aaca89a561fc9313260aa75c5802cb3ca89ef98913729ec52708ab837a1b97c5f2e3a26e290439cc7977173080aac81d58517b952068d39176c96d6e174e869546a504748a24c6acba501cc21e0266893c1223e09a87d94bc707e041c96cc5ecd0b8e6d22e79951c7be25511a91be3c460643c113cf4b0bf989c93570cb8040c8e7384cca5785317666f1b5def71300f5994ded95b72b6bb9d2767d5a30804a30dd555c2a284bef3e8b872a709951c1cccc99aa15887494013b26c2290c93e451697ecb300117b54dce213d5cb3f3a0a61fc0bc9cd9891a348c086718a8b1ca3f1ab8fb28a75e3b3909303c6cd4a7413cc13b3c503258cc1deb667af92c6a4507217568dc1c9abb1572e703320b0278f4df046554cac0295b7fc78863c67b886f00c23468ad08266c4d07615cc69742775e31a392a8473b34368d422a9932c1dfe23887e2a712df4a28510c17086cc5f89cacf65a3f9a310529bca97d93a70117e10e438f63b3fc653aa9c42b9080bc71e456fc9c5405a949d3eb20bbab8528ebca3eb6ac25a4b13f15934ca9b42f7c24ff8d3cf7d4bb4e2f2afca7558df338ca8267235a21141870465671e1daa1175cbc590838abe6a83b9e62b99a852b936b45d0561d00a160a3b416fd9105354529a8384a682a5dda35b7a99029932056324b07dda26b2a57f1acc4c5691c93ff8918db92012277d9b1636f2f4ccec8c6e6358a88062468efb5e997265cb12863d01735e367a51d49e0f0ab59836909de619d144cfc83a2c367319d3d389fe8c1aa50a4451713fa969301e01059357b4595baccd84137d886c27b483549b012da0bbe337be770364ef4c32e62c6425a1bcd256a70c0cb7fe690ba5f973a5851cd98690fab101e10c9545dab0fa966fd369c301973ae48a84320ba52af428d354aa6459cc1164ca37d88c59d49ee9124d6eb284f2c5c70b9c4eee44652fd82981e5ca515478ee43b6b742ad6d1519c6a73baf3831d447169ccb23c1c85d77b7709c311de0930829e16e7a16b82c21013f69334bd99e2a893ccac92b031307052bcac496c0f4405ef9bc2399ac3045700d3fca503450736db99e1e21ca00465f81712471a889dfc990644474d3e63f2e36881da07355d52ff7b924a9b45b5a3667076650bcaccd54b383e3e75953b75bdcf81fcc47c248a6a161f157ef495d51674dcf85cb1cd6688796804995b5c547abe326c46c76822b81a0f29594e8c1bdf41cbbdaf53f4450ac0d3740a538982b61bdc0419dce473a3dc906ad194a6b82adb1a1c172f1c50e4c1b4ed4222e1c6ea227c007cc793bdc8d1b78432d0632f7e38986b3137076c6a9737e701975f299b37066c587b87e1e0825d77231931b1ebe764d7ce80874d9a116b21495aa944c416b0fb022ca9758240997db6b05e3bbb0d10ab98231c18f00c750c4bead0766e150b951cc618711c917f2c06d24162bd99c4ad170bd4c7a709079079b68193bc426548094a4a5197a910d921c2050bf6cac59a5d9b8fdd66dcee032612a198a677011698a70797f8584c9cdfc23fc01214766ac1ecb95f5f0cc8b0a167bf1165e569f0d802b412390e768b2260b351d3752fe617c1df3c5fef947e334cce5c272f148386f1609e18152929547f5b091e7789425e04cbed63dd2c26ed0fb9d5e5786ead995a1ea6600e6162344ad2c1bc1038254d04c4ff2e7521d959088cba103eb68d7892c5105423fd422ae3919b6aa285c44056e8362122545f194a11da74921acc276e1cf6ae7432f88098318132ee8bd4704cf612945d974635f847628f19174d80c06a9322f81344c13a5ae16504668566265c8e0d4cfce7039b3709cddeb7e57f9635fa714ae807c2641a819e323670ca44b1015fd6c79e3db9caaecb71afb8b27c36044b25737841593d614c15b7006fa47b869a651f9553a35490e56cfe5924d2c168acbe7463c478e75d39f9bf19bd1b71864b5add80b376e4285991b27f9d781057a275884421682c38cc1becad068f72b949b5b3c70e33107bccc11462369036505f09b15a7435983ccdc645c68034fcce2a1f9eb7db9c0c9c072b8d161363c422bb0f100a19b83f60f9438e993cf8e23bf91d0dcda24623b37f0ce57a46ee0251cb5991a685161462e8b317d0969d59f5abfdb082b13a55d660f5cb081d6ffe425f77127ee4a479f469d52cc407eb065df1cc3210922ea6a569861b8def505a209959925 +ciphertext = a87da5e7c155f4d0f092294d0eda148c1ea2c6f9c06ba6247ea595f7ba52588e486e5178162bb322ec8486c2ba4cdfa62291c5f6156ab8fbc0b1b8a96c5e54b1307d9af026195a4d38f16fda525d003b2d4fef1fb3b19ac7c5140ca69ad2260ee4719baa046836bc89bfda553d80e00debc7f259524e62e6e259bf812e292fd9021ba640356f7b1e86b8dd96091c22cd6de38b820860cb17815310eeb9dc3cdb449a3f7541dc29a9ee10b6380aebebae19346789633f965f94faa99cc438a2efc069e0b7ec1f690e1d9f0b35857bc22d79de2be72633ea72142a201898ee5a5e7ceb47f03c2229212fc2ead29a2e6fcf8f47b2762d2eefaf47003d14e1c76ab5dc3ca426dd784c8e +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = a4c1a11879c134e51307c0c100e638d792a4241b75f71c07ffec41081a1787dca821d20c39cb3a28e0259fe4bb67227b038343c1d69e2c554d29996c1be914ad2ca0326c6ab5b946cd932e05c175cb497a7cf81d9c285b55d6368dd62e837ba38a8c1ffd5b6138bb03e79b88bd06bd6b1b761f5748fd430dbf0a1198bbc277c1378fc45fed6ac022264a3a71c2468c944c56c6ded71f05fb9a2ae4ad44f87a0f808081b53188bc3f339cbff9379c4422846ee28a357502a6e1558b977713ebbf889736285107b478161e91c82b9a7792c6870640a103f0c855e5281048ab17a26d6f145f319838aaaa31b392b402dc4847755059405aff0bb6a2ea2a93910dd968c43b4089a0aa972c7a061b32b2169b93e1e858945355fa167e0d271f9c4b5fd70cb791976f1601b8136c3519634359e49ecae6a6ed2b2988609502f16a78c97f206843bd817893d177ed8681d6279991a9a93e90300d59291200a6e9a251e43b468a8c419d54422aa42879e9cc44ac4598740a43bc83c2f4ab82c48cea7ca8fe354530560ae37757c8365ff6b4c7fdc8579dc554b723833e757bfc976acd5094aea0ce5198c933f10959f0acb05c77f793c37278ca00c7a6101298a5949f79b12ea2857cd18898043456f5f858cd63527a8a96459c5f7fab7a245688598655b1ca6939a01f53d262037b96e1079c5cf1c85fca830be17c2c215a4b30cd6d38b5642b3a957938bab702b5f382c5d56a94818cc9d4a4cdf2c94d43a6f8da9b33993be6fa08f6b9cfd4484c47168a50cb7b89d410f2aa8a2a141de0594ceb2ace2d3b0764da3183612400ec3215746ec2011248102441b357334603537662f0314cff0795398233e303208b539b8b4b07793023a9c9b6aec534ef828804b378c056c524e02165a055233c3f5131c77c800aa0da7fc950527efb3437f268305502e3e91ebeb3bc20bb20ae57a54caca94ba57a50510cd56861864a2ed4fbbd21b540940816ad559a82430863e57597f0304f099b7658947fb642846c5a61869bf60108dd0ab501611403b7b886470ebf37c1a750901babc7b9335b6ab90c0d7a45b6d86589391a59e6cab7774b30589a28266cb6e468c920c3f6d2b7e6aacb7ad410bb36cdf1c64de5697c4cc73baf20b353d18ce74751f242198acb8dfa922ba7629f02768476720c4f606a3a9170f2a03666680ce5b802a6561bd4f69dd9750dd38387c739b273283b6be4a51b686326e95a766a2bbfca3016206f0431052bf7a57f69cc5a001302c2920c1669235203468b7563677b723ac57812838d977201e58ac721b6bb9825698acc6a92a484c00a34bcbf550502e7c008fa50b1ec00275607727c753859f58b7663c7cbb90ea92606fb2678912aa92bd47264da59e5c580e52664f20038fcc9a1a59b3c96ea3981880c32677d209b0fd7873ca937744fc025f1395d1b4cbc6ba526bd26836177252d7c56c91067ae1770e86b82fb152a5d9ca52af550fffb8b9779142d9c4c9e3852f8869e9e72cf2524c624628cc0b76a1e10b344a1608fe2b82e2674804492c267c3cf0a6512750191982d1c9b3ef78acc6c181a082c63078b2b750550790a381733854bc22768cb24e4e9765e95c2fd770d77d2ad3d636fc40c4a3125af30d977102a3e85399201f717986c3be63797b0b50c0f9078b6f09b57c861c0c52df0c60b1ef16db95c96d7a6351f651c35f0ceb5aa43589067af8b9bb2e5b64c24b311e3af4ef4aa1e80aa42636ecd7870b9c5c9b8931362a6317544ac4cb6557c3599f1c4c9d7c24146f3aa720b42ea276354e603844ab3b70b235ae2872e2274c8fa8a920a525474bec30414c7cbb1743c0882f474fc5c5ec2b03fd3a909f539588d5b6aa9a224be59256cbb1fb9928f20c62ce2f58036dc275a745b2b8a6073138730bbc83fc09edf0a0903b3be53f9567251057f311783474c789c2ee696b3c8f83aae05b41b466146d6c6dce7b782443ebbd2bbd8d96c838c741a44883407cdfe8649bfc20160da9681ea11c2f439eaccaa0c65778a95c610b55185717bd48310d34c226b84c2cdb8c16540cbbfa22fe706082ad9c6722011e8198b25ba10d52c9502ca76d998b3b7d469db403934f0509fb847022a4efd386895685de7a3abd01172e40152f7c22d485160e54a31df76ac0b3bcc55cb7b50c10724085cf2749d779194768b305dd2bfb89b19357ac32948a10765a6ac37a1748590bbacb02e570df87bb2f6ac6bf139ad5697ad06f94dd2675e6e0b5a8b43a8cba5a1ea341f650846c96382a54b3a4d896a26a16d6ca428213726bd6c6a0b5bb10ae345a660c87fac7f3c973550d8cc404b2c4a4337c2d8c287f3bfbc7a01ccfa8630517308822d7ad5337477a3d825725ce610f0948a9eaa9fafa79cb247b32389290db697f85a12efe489340a21d9411864610933124ffde72b144a04f7e02af5310b24cc62a2fa53e4fc1b8d9b27c8664c8cacc20f760601c11a1d7774d34a2089e66030055c5d9c32d58a151337378a353fdc3620e2e11ed21408eb3cce2a23a5392577ec7110b135285e2655bb6540a7d933e367bae2b9706244642de5aced835aab198e27d2b098534a73c0bae73002d2f4c11783287855430d4c0ad9297c54e386d55a2bd3fc77bc508bb0179ec8c5c7f0aa5204e1174d14003415caef4a1b77640da70a83fd6263bcf13c20636d6f8c28c9d300a0f7807fb37a94ca70feb3562ff8c0ff89a8db43af408ac283b75213fb6e814941a393051cd7b84dc3b84b7a9d0c9aa8db125276f5156b452ddb14cd1f385dedac8a5a680afe7acf19ebc722b663bafca725999f7a28593b3c578ac9598ec46936f17556730a4d6793cd8a3c3aa91949a31357558a0875b51e9b87dcc5104991367ab4aff460829698b8ca936a7aba46df8146216a9581fa5b169495972676d41534bb98a0a46950475273f809bb8c4998169156cc2326c9605a3089a960c2508510690855ac98a66dd47488effacf9ca347ade4054499c30d98022deb49dad826bf5b112d6b59e3f9cc10804c0403a936dc1f46a2c0999999fa9649ca8c3752782d02f08410a88649941377cb2fd0b630598c2526c21c556222e8f94b363b3653888713126a6a9a3ccbe55cee413c630a995258c998cc83c0718d05a9689293395502b0dbf5af507005b38b884cb9cbbd186edd383119aca6da795f83821db2e2388be77d0fc60690396a0f00cf1a4669599c22e7dc7ed44ac83dcb42a1600cb295352b140064485b32b5d0c0f7e746def389cf07d13023cb7a5ae44922498869dbcaaba3623ac955d0deb456b3288eeab781d66028dcdbdde11ed711d44ecc0715e998611f3af8f7e5238f6383033842d4edf747fed8f24c13171413 +ciphertext = 01c0cb8d94c94c86f90b320df9f42613e29cacf5efb10ab8d6bd8ca00f724d475c8ec82dd93f9c4dc6b5e3b2015a5dab9762967503afad1a223d154b3a4d17e962e06adcb359e32b663a51920a483eb7592d89916f35a1c9f7bec2164f427cdcefcf61f206f20b7f +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too short +private_key = 6c8961b3d15df993337dc82eb852b2c7ea2e2572a4c6308f80488b55f4778dfa6646daaab261735d1a4a856cb0b845489341892d30c8d0274180c01d7b730e539118fce1739663c951322780079e7c0273b717697e275d33737d004690ccf0afe9b01f51b953bd721df421770d5035a2207e8e66645f9960a8213fbfa11cf7b7b2eb77b640977d9cd9bd9bbb37f7f7005eb42466a9817f8050a4bbab612546eba8b4e83cc6e600a4941b0352e724b6c84bafd3b036f7696c48a95241b93776802df05ee2d287b690a0d5b0569a750d15866a3ed8b1c045308e102687ba7288e735a87134865b6d421480adf52dbd220557a239d2d8bd77108b01f1c327ac3e1e8087d8625bac19c70d401d3624a318468626a1422b4663f7dc159dd062a4f1b9b654258589478d75453492a780e91235a4b502d096722427f05217d9534bdbe1a607873a8ca6c340640e9209514bca81830337c0f99d8efa4b8c194eef2934b20b2d596741be9a8429862720e872a61b007a3a767de71e2880189186c8e5d246deba6d3ddc679405b336fcc35ff32743a97a1a8ccf3ba40a0bbc16173a7ae0d5b2a29aa94df2508138a2bc31180f578c3ba62ebd35b676003643e0b6b827104f46789b30674b25305aa9442e067c1f83549ff03837306760b9bd79f947e3d38825f724bd15ab6ea85d2bbca9abfaae5724802a9926ae3a236d911c826561141431a9757b7f0b29b1218b364c32aca63cf1e663a18cb84ae3432719654a10509bdacb2c55c053436d25b0ab16e43d7d361d33f429ec027de1895638d7b486a91d14cb73d2e5c97a629e81843995864e70666e3f6a7a3743487a6523548a6e291ba6c190212a892b9b9a422cd5ca8067a92f79034866c67bb8ad76ba2aefd61ef5005f1bcab82108aabb6cb0f4a99e7b84497f03c3016843dec128e207afe27baf9824bae7608461a23a43f291b020b91503c5fc93235237b10fa65e64754b89c66af2489a2ee81785888f5ba0131d6b764a33352ba2895b8545cd3724cea3c82624937ab5c08e41b41b09c787c7062a90a838ebc2dc444adb76b371d790728a9de2b76bb7354b1efb0d8699586521b12d4c1220b36e0e63430ca1c2ad6baade0b89efac0f13f277f2dc4254ac21be64591c3ca69c67a3d0a36a8357b4709b810e3b3d8690bf95d248efb653465794f863b2e2cc51e90186c9e055bf60aa9bfb614df593065168c1e44e9c14b66424b1f6accfbd5237ada954c9016de6411337c025c8d47af9f19a7f695dbf65608c9313434c2de0ca23fab59a366516fc1743fd82239c754ae795caeaf633662a6f4c892a48312c38392d1a21c9da02bac2533fc4526d46066c0b10b6976ca5eb86018481396cfa97ee9aaa97760f23ba9a79b45712a8cfcf53494a25622ef89c2477a443b537b45659b5f6ce1d74ae8becb89db3c904fa36861ca7ed42915b515e3a9050dda71a2e140fe9c95bbc17bc868c9944eaa9eb7bc743596a31fc942444bdcf6c19cd1084fd99b109ab4708b7ad748608af304dce9a5b27538b9406c02db97546035e86c855ff7786139a9ec5bb2027ec3629477f17c55eb239acf73a5b641955cf0351932a4b080b827f5a4d4319c38a81171a965e7c5a939404b4ef8bc6e6a512e994688d09af38c786345316d518cb9f5c2b0a6a5baf8c01a499558943a811684af30601e72ac7271237892589953b35c657a58d7242d1d3671a535c20d70b4ca89b05605d9de2174f279ce6d75864bca2cde0411869c1c24151b386c69c22473ae175f1c90edbdc7b7476a91f3c01476b796ad19c30a98dd3256dc2e19f317557a751a2fb7063f875a9972011757c2cd8961bfe46a7b8e26a3c319543961211453ff3e0a915e99e6dc1521336934d876278302eb6646570414ab0b6ae92d36e6080a741874425e894dbc822d3a068a7e51c8737403c165f0aa93cd6a316665a309bf06231f25832908108b34f96949a1e172eaa26161bf918bf8a6c37519c9d9893909163e3820507026b39b939e2f46884d0a18c1ca4fa060a935c918ddca3bb85008ef64c6f0742f9c676c1e981105b5d7238764a399459935886047f2dd0cbf182390b4131e9e5661b242534919ac5cc62b195b77d3c4206739443461ecb433d1e25076562105db525b844a980ba4ce6d27a0bb80fe43ba768d5ac2eec0c2f6a815cf4b3ed2320b7467a29f0a6cff474e938cfc2f8c386756ff4a96e89bb2cae4b5353d5a5411b0927567d5bd71b5b67563028773acb0297c06e701923503a5f6b69c615a501d9501b8ce785a5e3b4416294c411265e3a9738e32424282df1e580cc2932d3439cb9aac082eabc3381554ac91fa0c218ee1887aa077470905854341e9b058f52762f4a9372fa4bcf38c326c7ba41ff021ff831c9040a7766097544267585e71571f2bed6a36a59b34b439c94a3a3b72fc401b6509c3741844187b717457e642b6dfc5187a4271c75a48c9d9bbd0d7a175051115af48949626d9e9665bb7280df9c16f06345035ca37c29c13ea32abfa007db106db0938df2708e1a0a9f1a00013c58503d36901ce084e18510d7a05a0eb03c254a15e546840938229c46695715545845ad1db3860e84714579b41098cdb0694eb4057e8035b10db6123549079d5708e176a33ec5bef6d50b7aca1d7eb2389469356e3727bc820f4fd3af2b8355e3c857e13c789ee5c9e5e648b9e8851c0193601cc992d753726a363bf20f34739b7a7b45916985acb2a62bf5008a4bcb91e718300010bc2139955779aadb17dd85814cda5d89e88c5b86280a54b3d2c02134544c2df8bcae055ca5ea9d459278ffe698c7399787aa4497463a292004c4f4509793c98384a71b75a0fff5a7b99217265c1f6f0b2e696ab66cf9673b0c4611477cd9137ee0f37fc4e71b4ca80963d6c3800167b8cac3d46c1a55e51b0b7478265053d36086b77a06984270a841641860941537a37aca955fb0c75d4c70bf499afe2759e3a8243e3843f8e088dec58984ba2985010e605462def2cc50963172d3ccefd66d184c95e41346b8d0cba2f4482adbb455217a13366eebe79549d68ff3eb18fa0a0ce3a1a778ab88892769b4fa21b80354b6305fee3001867a52aa24b5eee7c9cab8b1abca556b2c00d9f85e0e4421e951795afc5317010e7cf0cc0af287b4a28c3b11855100a81f703909e49259bb9841f38ad05a11fca7bb4e3aa3af09c5e274845391222b38538af39e07e71d6a6351fae69bcf17a4b8900b391b9715ba3dd16d2e86797addddd417f44d6a1c6d0dd250e8d3accfda5920108f35e4765a780f91b22eed4f99f7b800c4d4b481d7197a450105316a4893db60d390c59ab679dbd10e3cdbe4268d649f40d432cd35d8c2 +ciphertext = 0236dfb957411dd7d293fbf29a088cfd93f505a0c4fb082673363135067a2b7df72d75c5b00420150d1e6526987af00a6cf4e1c6a7e8d268dd7555402cdfd2cefef6c394d97f1a58f76967856d5cbabc542229f18de6952e2fdb33491b546e77a2075ee67b60533dd1a0d220bd668a3c96d2bca97269f050300a0d213f1d6bbf03e8a2f441c27bd996c9e2d5067b83a1b574c859da32a821f9d3ef42aef9ced4fb51c942dc75eef68501cc289606d66c5bcdd720ad4a2b48f481089508c333ea0a0d15d8ebed679a3d13f0a20fe326f4aebcc000914387a793f896fb63ced84a832808c0d8020984cea7be4840ffabe49521a4cfd6f9d3243c7d7d90672c87f849c07ab7163ec70f7de5472585c19321bc6b32d91c5206b5228f1c12dee5209a1ade5a0fcea43efc85f0145082565cf6d4b35fb7d7e491668a606763ff030026a6806a27c38a36cff34200dec0704b7ac29685d1e6ad8eac527d6bb180bcc73614e6ebaeedbab580f37d2e8cb05e666f50d21693694717d209af44d4ff71aeafbf8daf8bd415a9a8045fc7547f3fde1700cc3858c2d679dea3a49fe6ed24f45df886f3bfa37ec612f5736a4c7dae594418fc1e732816d3c2211e633547aaac71aebc6ef0820f8521d74eb7a7550e068385e325b513ef55c2525ffc9f4a0f67ba7411d7425e6cf0a80e35492258623efb71ccdf24a7cf9dd389bc3e8d3571a89e5da0ba987a8e699bf2de0b6b115624fd975c9ffe19633d1dddef01240979d319b3dac822f44b306bac5cf0f8646823a66864adeff437df593f3a246167a9c04948ca9b5dad000b0e8251eafd9b27abea11823e86d8d4555f9e373e5a041b305200eab82d6119794c5ed70f1346471809beb2113793db0e3749449fced9586b765d209d7acd8e7502240e57c9f2227fd19431533bc2e864df7346b848f14dd1e3f5ebfe5a08ed9d9ede04e1c3b3c7ac81109a7f5143bc31ea415602896d6a +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = cf139b4decb597299c80c063552ace17daa0e9300722b07f10a6af12911564223fd35c88dec05e0c82648983bccad28ede6150728699adac62020692d97c80dd270a0c103abe0430318a42d7c531a5b1afb37c19f747cee25429ddebb05a5836b6c42d3f7516d8763eaacc9137132fb7cc11b8610af84b76ca2967a8da46b9aa429953b8074650f0f873f3699c6ef606f4f4aea57538a9639208bc5d9b644770b83d39507a6c889e397980c88ccc739c286bf840ab343fe25b09c5431ad72a1cb23b54152b62b97422efd20bf03582fb36738fe517b3c899e532b596225f4fb074ed0308d2a3c01b930e22d5439d5399cbd70700a877bf374a732b07db0ba101c84bf6e43e0095aeb607b08b0c275a696c249000b072bf44058378a7c53622711e67ae41d871d0249090c5185f5371d00c36e1d81d6de57c7a092f9614550f9641a17867bd613d673789deeb50f1a97035b4a7b44780d24625de3016bd2cbaadacc4acaa7d56fb2f5d32968b1267fb978cbf5498ccc98be8e095db80950cf9a74630bc2be14b501ca1ced5a0e0a7bf13599b7efc5465ea938091bfd53283dfd62276d373e0778a1bd88820a99a2534c0a7451077a9861503c2c76ab46b9713970cc76152990efab35b54575c6553d938924616143e56080b7466c7771eba57904a178d7794766dec348145573670b0c8cc6f29f02a3b57800cd0c79950119327a88f4a2def59a7e89a7d1f9b76998094f3c3cb94cc44a4a76ee662cda1d40a51007ebc1bba763645a8108e8e081e8b200a36e2981ee735d8633150839e4d9698de93bd13c854aae07281f969485781f8d962eda965450bab29068f96c21b83b5701f4c65737033015abcfc5c91cbd4529d66430cbb39b64466473798018759a9db6fe4b27072da298c6676c61323f9f853fd145cf0e89085d5c302c21151e30e17273de90a7793c56f5fc0ab985b5dc2334f3f8bb3d8d42ac2fc7a3cacc584c1c3115059ea0a5cde8961eca536f9b5a196a4473bd737f42b482fecafd241903a976ae5e179f6eca12094ad2665b0a0eb34fe94bc27f881df6a68efd00e8a53752c988557d14d939c34967076af749766d730b068c51717c634e0a429d841ead7295ea42420941f15c23852b68ddcbac1218212f29576f17c9d9450bcffe82a94606ed5733660b8c598285044062155c65f4f388b08d126fee53c27f98db8400bcaf27f3b655d12f58bf533750242bf0433c988224e40634005304e3fba177114ac26632ea0a441c1d70517a872e23a8c58355a4761a05c183aeb91acc759bfb2b9847fe914f1b6766cd889c24bba56093b4eea025b941ab67c27b94c4d0f264221a361e1403f89bc8a2e46b887ea6f99ba9966aa21a25a89d61551d4c10e47b11daaa17e614a4f0bba729e8954ba200aceb009e9b59266044b9acc11df3497105651a1a00f196101ba4b76f50c6e0794c2ee0612afa227b960537268b76a027f6bd6675d649631e6b58a3735f536ad8a088cb029968c070223bcc92fd188151273f75815e81bb0f6c0892a00734002b08f8c38f5645c8ecc3d0efa261e5780316ca9ee07c1b324cb5c5abccd0b1072f96101cc36c38b8b17f56bb6250439e14f62bc0ea81b4788f6a3936a535963752c045a906380fb090746b91375849496f479ad855ee4cc8cd358b9a506bfec097f78ac219ed0b438088c6ddaca83b950bc24c71d23bacde96dfc9a625775a060268c99f32aac471f0c9ab06e44b66210b85708c5bfd26cb3b59ed14b299d8b323482185e861c29f71753f313dc313e4325076c6b1f1a3793eb975835652c5cdc8690f695b9b7bb0310cf119b960df22ba83574ad6229f02a524c094ca318b150a9032a390964b5cc53e2b213d24a30739ff3d5b319602358c7ae48507343b99603ea08bf84be4c63c02569ad2dd6a758a68d16443bd105191119334de6134038ba71d29de3740f94cbc639c2300b799402832e11595ca8b69d808046acd9076304b9d01b37a9442915c068a87a32f8d3b7f5147ea0437413f33db9f69e594582ca83028b9417eb0b7344c617671252d7ec9cadd06278a1bc8f28154d8c411ec961818c078af634a40c08be0b818b5a2169ab1796f59880c1bbcb1a4e8b73a8a060c038d6a4dcab4b76f10af23412b0f262ae6aa85688781916c61a55a1cdb27bd588062faa33c6e202b13ccf67b092a19c69d5d3080c7871299575b2731cd89219c863b34d60b32aab227ee189bb2986751bb37ef413353bbcb4156b2352b725593a8da18a0c560f430805ddfac06a245236833699c0581445c2e958404a9436562b3e30a18d4aaba268420cda30195c116165e2ce83dcab60440c216800296bc961b01026477d3e618edb809749c8bd84d98153816b177c93ab9675e5420a29db11f194cb048a59e01983da5284b725400ea9762cd22759fc5a2c83422820175733530136c3aac353365bb417b6020774298c32715f11bace60334401472872552d5694da008d305364ddc59e28049cd1570b213ba0e546cad8027725fac43b307132c1994f68162004349089385c3379f56b60ea82195f71a096dba636d6130df24369619e5363cfc46bb43f15a3e5063693a983ea12cffbf727178c3405f2badf8b7956113b30cb928f510c045c0ab0bb2aeecc213f168e72ebae599914dc4072ed2108eae6252759c7dc851bffeca8267ab0041b34ec46511566a00635645ef2522c0c9fc3a571e127140138bf3bd6a456c08a25da5c874ab0857208b05604ccb8180f31ba8be71d302bbba194c96a4504e21a35e1395c6e0c6273ba4de4f03069f853485b527ed189515702206896963564a8075f7d126005300740d68a2a6046cfc900fc47253a0b97a3842641c926ce4125122b0e8e7a523fc17524ab435c2bac3c8a5d20db243e82389438ad70291b29c4518c0b85bb64acc2e430a0f8235675251de081b07c56c98abeb0186dd9881e8f276777e23a014136c177176db6613b5238dc8c98b6a68d3c5a1150b60dd6e6ca954c6634a33784c787a17310c48b78aad9a11e621e512b0b09f9399d0b18843592fee4661b36ab2adcb061909521d64b64863343c47aaa47ad96449781801c8cc48f8da24721b7465d6755f8ba82c26359256460cc832964d9152fa6a397908518d9654401b495f6be1e093dddfcba6a096041e8b660679477ea79ecbc6f6502c330f2b6c2a355da258726917791c757d9c56441da3b5fdb6a96889766bda123ce305d82d7808b59937fe104b42b7bec2ebc2d3d42202f9af657acbc77bad492b1c3576643b41ac344b3f35eda04f3ccf74d75bb2585f1280c1252c94d7df0510a1fa29fc1f84ee51f36c2b9ef4c4b9922c0f2fa048e4a0e799cb5ae7111bbc2466b6f0289e2 +ciphertext = c7d4fe09f990dc2d63f0e8e026114f7f916b56fbf6044f63266c2f07a4483ae52fa9db3daa5d097e5ad21f4853c0e1293801dac07cc2fb27ae16ea4a06bf2c82a4f13d8b01c42d4b480d0c3f07d5d13bf1eaf0e615a5f960a4332f2a7683c2fd189a557afa1170002c305ea32c7d5ed4528ea03451c8540cece1a4c5942e6538bf64f282784fd97bb5b605de4cfcfd5acf172747b53b4ce4b46b8bede87092926fe5ae4e8fc1cc8a37c12ed06b1fa3ca6f91daec1bf3eab138b1b482c94f521c85dcb3831b503bc8d4a634e26789fb8c949532e4e86a7fe040c115a463a97c4afd3ec9a15d39e76c4cc8b7f67fc165274b3ca584faced544e27cd2a5c3b2c7b10e437509827e3281ee471ad580b61351c961e2be6f21da1e5753b4f536a7c1c49f81529c0494f7e1afa4647a1f7269748b5f2cd5a331e2648ae45077cb96966b78613f6296697249012f8abfd98b3e1316269d6f05a5710e4120d230d045a3f33c2664b69f5f26f6d759317023713956d614727d93b1fcff3fb172e213c61bb9388c6d7501ce9d61ff859fc642c6744e0142fefbfdb942c054e721bd415da07ba20de207f9eb487646f122a2a2e4be35cc0a6bf434f8c309c90825facc6a142a6578aafbdc8b661cd9f47cca20bf5a78017499325b77dacdbff4f1cec7ac2b712eeb5696e7494563f12f42ccf483f80d90f230dce5a2d8a44237db16bf54517ab8cdfd09a5e550cfc08c3f2a10414c9ac4ebb2d909b2ea7f539769571f58bda3eb7f0f8ec9cadaa4291d7dcd0f8a15105795947b6f431e0aace476c4d22f1ed4d621992bd61a1a05ea5f1e89794f0f464380619d6ee472759c26568f9991f06ff3b248e3760f6f2c716e818fa284fb468fa8d139cc6dd606c0f4f5dc515c200036aa3e7402bdce6fc666f3c2ba1ceb83b2a8ffa29b18221ea31d7db46a5d48966501aa47c95b3db7e6eb9fd599741da93efb73cc663290d7417f96e496454bf559303c8eac0cba0fc75b5d298dcc7d483aa96864f25e442978cbf7fd3f1c5ce9769841dfc9c766e3b70bc854dbc86fba0930b23a6db16d00329c41f951d54edef04b03e259b38ddcdf8548f8e6c67dbc9af1fa16f6ed306652c393e01ae5083e3399e124c314c61b54b1e2bd1e53b43e4dfbb2a7706d9b04848e5905e9fa09bc3ec63ea6bc1883102160af24e1b58d0c5686e337ff191581ec38e0142cd71be50af9985233d762366226dca69d2c3cc776ac145f0d60af6bcd2564cffdb5d1a26835b0f57598214a557cfec207626d7cb83950d5b1f25d7d679359613fb70dfaae1be07508299b398e0fe3e00b4859f4bbb4b66b206d035eee057c129392555fae232827ba6a942b16a35037b675b51caca638f871f0d5aeba68fd4870e04f99d548689b06e903acdf51de650147e48029c01ff8b1260af706572fdb44ea8ff7e6c72d3085f438858a0e3201b5d61b8a31f69938ed9a53a3723320d6369a4bf16a9c7260be8d54917a65b22508affd8e8993d0e37c61e17847ed4d61a7b5f2b1 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 0c62cb684b9d6de85e74226ad6672c0a3339fa974b648856f8479d9954411bf56b59341f19f16cf1086a5b50794b8512866a33b4f0191c15b0d253907c72624d83960d385f1a69c868832eac567099927f0d2181929164fb84cb1c9149291737ae5959fdf623bf14402651ccd468be138104e8a42d7db581629b7756259ec05171e5b12db7c4bd5e8540903c8e49b9a797e8b360f209e1d2579d5bacbf914d5c92cc2a9a18b8b2b8622584bc220aa8208a547cb2cf59bc60a384195808f429ce0ea449e7b10828fa6ce278259d051bf3b036b2d4bab1728372d29e6282a6cac494a7e3448913c847700d3afb6db3b455946a747670483bd06fcbd74eb76704a6100e2e5a9340578540e9176d905957d890e6821868c01da4a47e5aa65d665904d8a5bf68db5508298a3fe659947284f18c1882235fc194b3eb88c6f5c878cf79ad58d1be039839f74a288792464c7a9d80656518b1af8475cca91c7e3e6328e9281dd2fa341b5c7e68d84729fc24c8fbae336560b6c9c56402507a1c313e15ca5fdb9dec9056b34092eb5c6f08446aaae7b8c5a04fffe0b2cae01c6244987d84a4e2e78ad6c3a44997329494c058b752a0a83a2ca99d391447765c5f1fdacccb9c1753c45d53c42d4ad31b3cc6ac6468269c9a6cad95a9795033067b8e1d9807eda8b31dd37843414f402a6d1c347d000a6d222188b5d97d13a4a09c6c5e23bb0b61750f17f2cc6b9b8e371c30f3b20c5f41157c410297c6a7518a29b981ca4b44a5463205cec7a34a1c7ef32269909864d8f2839ec25b801c107813995b4bc990771018ba2755b4ab140699ccb035bc0c8b601b96627c71f87c16b1227512c75914c30c00a6569623c0ad73b87baaa2343c5061993f86c750c98a986ef75c6e600d032cce801a74e8e62cd91c863b8a422bab50a85558a76b034f8c477d5629d8480507722da1630f55e441e9405891e414b1abb69d5a10e5d85d9dc36327bb7ae27b99acf96995d303d474301524cb2094a7d7ac2d921a276e983bbe0a2caa4606b0364e8bc67444a939c394664f3286e766b013d651ec655a8798ba89537f3005a74786a8edf3827ef12ea831b0f6448d1e17aad46608f6098e46e87c18a7a9c4953d36f51b29f9a51d0b0c14d35846b881b674337c2bc526c100fcf02c4605cd8ea8cb0d09a2bbf90a009db12e12025fe694aaec0943243177c50a87d2a456c81c3c89ce25787d9f737cf7aa9366d98985721127d26a2a94c15fba112900678d87976e56a55d0a63e4290cf0ac86124776e2b53fbc466c2cf13890c01d11f72ff1a269e27694720433a1e9543fb67dc125325b30a3d23a705152277986025b4a2bbe8688482a3ce165254554079c4242171522d5f8a352421740ba7c4158ac11085f52b677b7ca2e76319c75225f9f89c9a9506c31617a128c6867268b69f171b55559cd63ac6d3056a56264971048828675096abe8ca8a959a230e900bf7259899f4025db182bf7c5968f084c8b63b199e460a7d0c3bf316306b86573410048083cbcc19ddd3a890ffbc8db97519f7bac4450858a322deca2312fc9546dc731f0853cdcd151283a06e133a88f0710dbe78970920cd85700e69548f4e6c4f669a4aa77421c3c1a9552cfe9fa6427eaa846f7cc47b3c77a9a547bb66efd0b90fa2c33e6c9928f46cf98058013121476b431798c00be0aac5e00a9b0945fc939b86410c20d11540e5a204097b8c1baa9665676c5d9a8a5da272b43ae05b9142ae3b74ca37faf1ccd6cc14cdc1539925c284d41cd89387dc468b0929739238b9644898c1864abe196c4eac53d3641119c380b69956615825e14a7b90d43b118f79d20e6459104554168433bc36c1b9a52b3902e9e0a5448ecc9ec41240730488f567762bb9783c5a88ab708ef573f10996288d01a979cb6f3b7b3b65abd09b481c4f26e8eb0241fa4c445678ea29ac7a8e14ff7425f9e93c79f175c7605cb8e10abc3309997a37415677ca68aaccb471dc3b72515e4af81c825d1a7768cd70984da193ca2c542b756f8ac0958966deef8258863bab258b34e98174018128546c192bb2f6655536a535bad046d009d374f969d44b00165d649f018c3286107a0a16d101345bc625ac253748b23be9fcb61521c708f421126cab64c9a2813a639a0fc033e4295f999013a3329cf59077e12669922313a75018d712bb6a2a4b809331359c9f05b5e0e759293a93b016abb5d3659d19c1e8abba214694240f4263fea28590b9c0721c1d2a12874d91f3d8a58053b59415b0a0c1941a0bc12c5c47acfca37d986ad0c3891a62338a5396777f642a12b9822a04decb56508955d4e1b5114f100f6807d8ac9081967058fe2bab969a3078208bce654def6839fc5012ce389fba55c0a5c5959749ee405a52be77c2c8ca6170689acc9b99fb85900101810e55c116b3842e7cc18b4cc195488a298821ee54f3911a1ecd53b8d98b8bafa416b01be5150562661a59a662ca4c28515e07d73eba971309c402856bf24835df501099abdf09a4b3e439101c20f6945467213a5b532952c784f7d4bad36e792e9262c3288bff6b50493d86b698c85d6c02c1e072ff11618f0416081229557b3c954a636d713ca75555bd0358c84165e113109c3e9a959c92b365c1bc5da49e92a6938b30583743594f05a9b37482a1c7fed12cf6c568b6c73c7d1ac2b4b279a03f8b88d4408410085a74468fe466bc55b4f2ac57ee55016afdbc242793b02e8ca5eaa58b45c0c7e621012f1b80d12b2dff2185aa25405c6cf81c224430034ba62c949b3ab0bc25f79e3bb291c2d4dbc8ea0cc70afb860cff8214e5656b5ba614bccb96d73153c67b6a5f117a25b76c9f429af7113264c8722611f781c6b8f658bb1b35b960c1791dc08d183bb1ba87b8cd7948fe84a7fe977696091ce84300c4912aeb6b72067c6378b946408ab5411bde5968befba312351930d31355a3a636f9130901c852da327d126605f0b95f294780ee1a6e7da97d4970cb88bbe3223b2bfd45139dc6bd650817e32ac2cdbc375f17a44920eda107cb39b6026a109ed0c52a79b76ab5a9e0f531d386a6b8aeb3d5f064c07a12236a83fecf59a57d2889e479cd4544ecb5ab750b2ad4cf381f976bc1b3ca40bcbb52f1b87067057296801b15b3ab6d99544d31e05504110f104639b91813b677fc076353826cd9671eae0a4688c5433d96e71407da3d6a2c64b83d9c445d3602ecfe58c01a3068e6c8822c4ca6a78b8f5af1e9dd49618be9c8c827116763e88e640ed5ae3f564e8c77b83a45227c5cd9166c5f762c426f60d885864db4046e6306dcda4f6164ba82ebf8a46b73f256d19beabc074728e12fb1fdf0973e31cee5b79b48855c1951cd3813999801753b8fbd824565da62b7d81165eea69fbbdaa31f88c +ciphertext = d672f30344960faa4f84b988a5ab4b3aae0b96086ca9e6108ec0552a9f3a46f69841825579ec101d25c2d980f9be9b70843a876c2e9e7e69304b66f2cfabd9373981ad9baf3f490e390af6247807762e523d20e63893ffcd27a02d767a5854e11221a91547efa1294aa2f4da295950bb31d479adf0b18637cb4d503118ba62dada06a0e48526fd77e829a3baef75cb6dd17a0c3d59ab0f7edae5612b56e5820c41d325a5c54ab6a5f62c5dcc449c4f48ab8bf60168e3d75046fd2a315685ac01fa78cb4594203c7a759a4511cf8ff2e09c11c5e3cadc81061ab6ff0e3ac9c0f7501d2733b60a79a505534aad396eb9a466eb594046c68a9492e1277e144ae0db203541f51b07b0fc453387984da279acb588e5946606a142ca311188e00ffca3378a3a0c7d61fa871090c87a148872b5ffc6873436a364f660fa5625a69a11111314e4153c036c970b883bfc9c23db232fe7757a82b7a0d654fb03c8afb77425a5688fc9299fb091f4a4ffe275671d8b7116d79e4eb0a26f4e3c6c2e1963822034243c45c53ae769228683e658dff839418422633937a33150e9e5bb126529f11a2a47837f510186e4381bb28374eda594267e2f6660bac83dfe59e288ced5bcff2f0cc02c6a4cf9ccab08be144b0721148d8db99708ec7f6d2bb3574a0235caaa4b3ba1ec9b66610707de8fe07fbc60f5b2b2b70c260b030e581966086d564a52c44990db1e811a5c18beb4cde03ade88d81042e34b78e91d021ec29a62f903e0f83f244d98fa8d82b6bcd6a68241cda27caff4de9e1cede0bb61ce23843699c586c0e9c07b449f3d438dd629979cfb144a4ce5fb09d0ff9ea5baa3058abbf3a9543450fe28556898f1e15fbd52fafca575016e9e287bc149420f37ea0c43d95c03b2eca4c7d2c636b8fc5cb5cb4ae8bb373fc3f253daf56e80c451235cb3ae52b8d70f4f6ab619df1e595c5d5ba3d5b1d1c63e49a745037942ac1972aea11a9e5200b62d1d1f4eaf81c9832e71774abae489a63e928e2ccfee554c96ad2eddd57ab836b7f3af4d31e9c1fe63d0342484d12f9e75b8a7d152985c019de90a24ac8c778d1d9972e60eb03b15ebb9c2af7665d492925091901c7ba1d3d0b5e9d4e67e90cd3cbbc403e6b60f014e1a0840fc2e573963de4ac33aee796bf16aaebfde049ddbff999c5783ee35e398f1e76b9028194a5f11c536f374416f6ab6d59c2bef472eb88a9272c780a3ea562601da28b2f433722c2fccf7de977803bb9e313138b36b3eaffa5dff4a70e81e48b97fadaba8a2e4071f858ebb5408cd658931ae6fc9541e2d2675443ab6462cf172085cf4476cfa5fbe4fa1646745087e6ad9a2b420b85039861e99b3b74820c37627e3fdd240577c533a66d4ef1d65e13586a1e85e48b13bd97ae20a24652779d75bb34630fec1935857cb5858fe56ea22fa5ed0822bd18ce58b6054f0a1a13a9da1e2ce01efc4b6950af3077bd859463a771952c2be35a62d83bc2d79380d77b61f30794e2470c5f8be06c6a6ce10b01224 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = f44565b21b7400ab817b6193dc5c2b9ec10f2d37834c2b6124a95befc2b7e204a15cb7862ad57885fb982f14a1d1f14f5875ae4ffb824b652652847396529972472ca292b6685473c5d57c7a636310159a616b1f180a1e5576361473af46f9a28f08952f5301c933c86d036a665cb2a4db3da8e80197d0cc9b9a37c0266cd39034f7b1a6b7d64bf0e7b5f3a36087e749bf948d06e93277198670b0bfc831bccfa0ad9afb5d1bd94051d3c3eee17f43329d91db330165a21f506d8daccba47942e9cc729a22229c6ca7a10c809d19b45cb1b77f40c838078d34a14cfefc1b9a3b55b8f577b6d38bdfb792c1b96be6d12adcbac76337730e1c8c85f8796283b66bf99ccaf2817057a9a3e9c004772861b190bf607b250c9e6fea0d173b70eedaad3efb4982b722255555e68bc76b662d7fe84e66b39d5cabbb7c38010c158d80a10435d438de42a958761f48603713f775c82736d71605b9f9456d93682c228bb5b1166a9aa0d16b7d6b06b72b314ed9156637657ad0b7a1155b8ea27265454abe47c1a3607c228332009dd7941f086ce9d08a2f132a55e2acc590c75e34222e2740bbf53bbd9bb002fa47518cb5eca0c997f99d0f798bd66646bc412519197d029479bb86bb670a61b245cd45135a9572c71104890d72ba1bf7694e82a6c428cd8298b9c5284fda5ca8d40650596b5438225cec4b72a38c8648e998a3d63ce7f78e4a922ebc2776ddc7581188c3277967b55773b4d2c26ef40db4719f5653bcd5714d4c7626e523a49c21708a45b64dfc48a5a54bd2b641934895263c96ed0c072bf5575a3317c107185e59741fc19a83ccb1358c06d26a6ec295350bccca21b6346f524c43244e0984517be5134654c5c612236e6c8a6379a910e9b10a10b268753916e856542c07330504230b212c7a006ce53736cc62533a71e793bb79d1191103c803f77001653f08da2697f2cdc2147dd576092cac809ca8a7b5061b1bf63921402201295376c29493128d1d747322c9732a9317e4eb8d33486b7cd13634a125f4073a90d420435b2e4ae118adbb0c6da67011c8c8cde16ec095cb082561c804327ad5c88d363649130eca9923ef0177635aa94cc87a371b530b5738f9aa4b9da975f4e9a215541252390c384739bfb57093891ea8848536f43d1d175469a551a3621d4b6976b1cc1e4a305c4062beaae63fb6925ec5b75a99c4b8b94c7e6f02644d25ba7d54c4d3ec3a96f62db144091d23bc40727692e229c4dc52faf17f551a4d645bce2b30656f407fdcb69064225593983339d10d35a5b87b358f1ce685018607864a1c34a25c9a31c5c8c845b4686ee9c4086b9302c5231029e2c92a2316f0fca683712eadb9cde11c99daa16162abca69802b2a712014e4436cd982dfd0c6b965218092024f67079742aea677573e517fb5cc3403b1a7c90439f0f61639fbcdcc213a02b975656501744458610531bb41c3b373cc0b06306fb95a7d7a08f32799e37b83f1957f0c8371677bcec0d03e59160aed34b2f5f10cd9f44e508180baa5baf6015731f5cc3114cc2261818bd644a856a6e9ba316d7b4cde571b2a23a7f6dcb13dc49d6b59c3c3b698c4a814ef371f49fb98a74b7923857541c96e7ec1157647a274c19dcfa817476666b64407082c884107762a126a8bf3519ba53ac2fc9229c221b466185b719e35b851a04719dc948c7f4484a7f3becf24b2ff39c2161773bb97c5db7137a7a35a8e96044df03c086b0501612782392cba2759460a8a14d84571d47ef9d47387e36bb6982b687bb852957ebf27ca8704bbdf5c7bdcb952f1b3799079918478afd7b4ae1d629e163a68f2c027b229a3c109508d335fde543fcd52c80b55af0f03c32e66a8f45360697bb2c2134532e6724fe2cff998be809514c3a20dfb1909ba3b3b87d2761d3c91b883771fe15ae175bf26c7c8088276bdbc80ed16c31155b217f05d40eca21cf439b9f8478b441a247a481bb1889c6417f956223f451652799c27029353d503860c4900f584825b378d199116e46a0f15c3a428cde1353caf518e2a7a1f90f40b5c6acfdbcc1dee031275249f27d4a0e5980f09b77c1a21cb81037eddb95368a614761a3223f23d2364c6d3411e471c2c7c405b85683b9670364cf5063d7a49d161391d7cc46a6512910b6ff55b2e7c9394471a77a690cc2670258cb78366b58f4a158c2060c329205c3c4157972219baa619753a1ab392c7f1e7ba6818c527c25dd943892248637b6c6bff045d46eaa9b8e8ad3f37703896c0849023b278503f63b87ce5b7ececc0b4bc04aa5c42c92a0bbbd605b2b10f921985fed16fcd7549add085559a543dc6c45bf39356c96a7e876e28b75bbbf273b5f4408721080f6777dea088f904043d785465b7b9475857f5e963e0a44e73d40f05d2bd91d06e0ea359cfb3607980b6a7bb5b2b07cc5915605d5bbc03d7ae2a172ede182667e4bffba848812414d9d72dfd311ff6681a47a3c3cf5684d6323bf4e83c6e523356c4baec579743e7036016cdc395b0dc576d081418b1284f4029125e9a39565c9729f5317d12799ae627bdf3bd895a90138799e2097e9de596085c1240f11e91030cca2bc4edb44be5079c52c192b19336330b77599563c3339430d5c6e87249a1aca244323f4af9b325a57bcde77be243ae63f4b81e2c7a05015e4446a5d0cc5d324632d18c4d8a740ba9f2ad87768775cc7442961381b65c8a48acc17024ab2c519bc00ed158a5b90944bb89bfd7bc759c4395e0fcc0ea038c33282058eb1bed930b91d4a2f5573003011132004a5b0b6177f179e727bf6e68c93fe3b520e1a971361bc2b4201b6b5f5e860abbac5d2015a9e164733e33bb6e0c19eea4aa18fa3adbac4725c9283a1572d3253c2a00471ae12f1172289357ace43842d2d2942c80ad646bcd0e787cc2665939d8463235021ff92bb6c042239972f6522722f4a8a23453cd6b4c7c077cd25227fe9628484a05644828310bcbdd61007c63ced14921473b7eba4360c439bbe87a9086d95543f55cdfca5044815da9a1b4f11211fb637aa49576311c5a7a4c248b5b1867b97c33062e6c5ba883e0c1f427498e951d880869568cbda7cb477a1569df244d12da59f31137191b0cb8fac7de607151c422ebb84dcb3837f908ce5cd895df772c41eca48b6131e1a709b3668650f70e2570866d8208b35826491a4af0695e52c91a2421b34a051e76ca820405ac55598b05f22446653a44a12ec38bb9ca03a3514fb1a1b04167ffce3f4cb0916dbbaa0f5a33b74ad397246e5f7368cdc4e8ce12ed1d4a9b24081ad12d9bbb0a12952546b4b9d8d4379e0e235d96ffd939addb0ad3fae21e07e1ae91c5d95908e2a778806fc69ed8f7b6c07db39d8a24a476e37ed0f2d201ebb66ba71a27772a19a3783fbb16e346a4d4 +ciphertext = 74a9f53517658b9ad6f54e9a2eddabf32a35d98c95b9967e7aba33aeecf124c7b8df997328ae070e9186564e8a0590ddd9aa62b677303d9c5c3764934c8f7bb49f2d14825fa882ff4364293159fd94353070d6d1888eb217e866877b88071861f17efcfda8abff54e696dc3d8b9833960a26806bc3fe159f7df7a60cd4c80773447e256a4ad796f72cb78078306ef0bec16e70181fd0ce889f3d24eb2253d2853aed7c5003138ee3767770d8bc776074e39c41d3e26d4b0176c89163cce7a2aadc0b0591f99f83d00071bb94e1f452d7f4b3f39cc1203f781cfe7a3aea711c82b859012aa2cfa6fa6e4779774f7d5f273259944f856ecd998dbb1080d1cca03a8ab343e5238fce587c623544d95118d8cad281a5c92eeb16383206b23a13a750f90eac2d8385aaf19b312ed68af21f35b9a047e4d07ebecc7a7e9e124b4dce71b58fa01ee98f9f4ea82f20fba33f001bc1746e240c4f850b7641a289d97b9f68548e849c8de79f7a6f9345e553d263ec80266e96efff17b3bbcba1d2c507b82e836daf27f812a177a6cbea159c8b61690d678bb377e32b7cc62d49c71d9ea7a5443da80fecd660109f4a61c0d96cb724213c1001db478e936e88346816686fca42ba68075958cd5fdf99e28b1c00bd233f9b533a43abc927b64e880a6a47cd34aac705d67cbf25f5b49fdadc57537d7a0bab8407d8064841f0df8123baca32474784e87474ca6e334ae7ad8df1f627005e892dd526e0baa33a0d9fdad7e21005fd36ae3d1082e1e92e57226f8a7e83e4f2e5ce1b6106dbfabe2e5b4e1c5adb64625e4481749f25c263ae6e12ea4b841131afdba7e0e33c0fb382d62e3e43c9def735e62ce8be67480418d6da183ea4d8a7308f507ebba959a62011aa73fdb8afa940a5a7ab30e51603df03b277fa5fbf16feac6139c08c92da5301a9d6d33772f9fe36cfc3a8e0169098faf0f01289463f0208070484fc7b163aad6208b9e70e92d1f72f06a23941f3eaebd63c8ac65d87ac8378ee7df9beac025cd5e1c32eec87a6d5b04347c3d148067c176f5b989704a455bb01a030d8efa6d70c94a07166da52de6003c267b707adba598dba7cd6350ad0cdf1837f107c5e5bec0ccd066ff7d4fcda9f97093ebfab7dd13c2181f63d1169e44f8d6f59149cec68ee76febcdc91d5f50f3bd7eae5db8cdddf5b23a68d4d574c06a2bbb0e562f0d6665c80955977692183dd1d981dabccc857728e652a1a2065ad5ced557ec2474178abcf5e282892241416425950deb5c849645c560bcfd5591f3a09f59daf3dac74aef01928e516fb5ed138091bade0ac0edb98986e6033639910366d70532d5be00e19783e9ea1d0df664dfde3c47e9e29f05040f02b83de69df487e7d7dc8fd8e69c4fbe2a916bed084a66e960e71ea365192fc3644700d14d836b78cf4872fe6287164728274dbe981a82f3b05c3399738399740f9e71aec983bc8c1124416b0ba0e7f9d447b69a919aa3a7c10e8c416bc455b5f16e271724446aaa7df397678d2c63b +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = fed5acac8b7b5d309d37175fff16435e7808e5f61113e77eb8ba903758b91f365ebb4641dd416f18132460b7b9e4c91926e9cf03e87903c496d8118d3f5b3ab990a0d6674f7007287f6b49f3f991d6e6038a6b4ed3225cd01c198ad17e94f7222a690dcf56a5b0b272fdf6825725bad5c9c02df1112f32ae400a6087b521d1b7851edb359ab498c8db3576a361e7a18d2841cfca2c73d7f871fe28703c6a7f4ff18315a56f06ac6b7cf9b36882ba72cc37710817193c776fd1a0cee00b0b6ab60fec193fc64f5ae3895a521036067fd6a12c78b15d359575ef6cc1e507aefca3592400b11cea84855979a8f20cda4175b1b9c7a483aa3ad88858f4685ff6202f2c060d4693e7c201ace6a594849230685e6c569a42d42f8c47be8dda225daac937e03f7bcb8121055484c3a91b1a0143d4c593d35ec5923f4d4cc45a677c51f43af8d16997422a26a8172eb032ca9896ac7bc778a7cc96c1260093c28598ad7209621840c6d35b18b2a7c3515599f485567544af1cb7a0cf877092936e98876254e50c4f5866c6200b74da63e6a4cf27608f64d713e3ea226375bd555aba93a0a9c07a7742850c7432affa906e68519879a7150948a14ec9679af14e579651f9173c3b9443d4902bf38a6f67e97d2be8bdb2b396b311b62cacbf7da470d4b242f325990ea07258dc09aa764d92198076a28f0489a57aa4c072a37dad8576dd1111b91b28ab14702d05070885a4ff0527bd6ab608682f4285637232656304222c218a0ba769bce25f268a7b243a1e8743a23b645b4d02a96db34845d8a6c014bf13fa0c53851712875bb946939cd44058d26b9a79ca8d679a55e961e37161fa5abf9de90fbbca876865bfd4f3ccc7ebc5c0a628b9951510cbbf1ac81574b67b2ad91402040ea7d3704839bc5ff2ada5c38d7684cf9dc64b6f45c4c3661edfe24f2d9491c22241a652c64b5159ebdbca7ac02a09526835b8b258044cfd45782aca47e59a1e2f53aaa1652bdaa5af42d18fc50a8252f97f48f4995ae31c9dd34a4777ac182c5aaec71c8f319ae97b87c0052d70c905fbc32e04142136a817ba3281510923271069a048b9db6b9c76b378794b79b09938672843d9b1ab8afac512a51edbf084dc548a92da7b57e06698305446e3a3d4b13fa8681616c0508ad90c2c4815fd34b11bc00421fac998c12ff354bcabbc74364b9ecd50cc57b17921c829aa1b0baba69f5e64c0809a3d09792e379a2e6aa00ca1273d39dca6d5484ae6dc2822217eacd68627a5c03ca040a80ad02c8959f5f767059bb94d1c8595ca4545b04a28b5195735174eab199fd976ff85838930cada2931ddc41919821fc5996749c9bd28e51fd967b338ab2db6912380f51a106930cc992a802310eef497ee94a19dd95bd009319c52542fbc1a6e614d471a2a6a156ee8349e722026e9b6271a0356a9a29e07f28874137ab2d6b8c4894dfa431c0f795d725b2c3233667c35be1fa03528d3bfe4f942456898c4a371f7a350ac560787b85ff4ebc185a22e468ac97f6c817243c0acab2564160689d2aff670af47cb9b77ec7d2a159a9bf7054176182d70c006f5093dc2aca4105942ecc51ef3abc2794c01caa007b015fa29637cfb0357e41199949581a1a48d048a26f0a1af82c22b72b2596956eaac632c9c6346f04b6779cdd2f4840e03374af79401645d66521d4d29190c65427a2040b6f5c0a8cb5679532ab8c43855a6761cf5826d6140a1986b55259332ea835601bbce575683a84ab4f29997681ce8d91256bb4f4300a634c59806941f32e592dd6c3b491a4c6bf57ea78a699641cc8f4462043674b7f3aefc987a8020a5ad075ceba826fb075de49413acf9038e385b2c648972112c2974c8c67536df33a7ac8565df2a9fbff09d1b3b9edb566603753bbdf1224e991053b63cdfe6ac6c46afe8fb62b9a638e41883a40c71c4f72e0b24b9614766bbb5878712366ad6cf148007fba703f5b443327a200c6683fdb45aa918532ba2a2e948243d870ba120b6d6c57b5a77cd5489598b444fb7133f06f514ce90c386840a87d317336a774ea458f9e325c9042008f59cc9e72df1f526c7d22fe934b018a033ca586e27c1afe3717b9eb01f34c53a4fe32930cc6c91f088afd95332561629494185589cf753bd277b229c6bbd54161f5280cc1722aacc801fb6777f965b5b82476d55b80e75ac67208bbbdf970afd1c55e55c2280076202e572a324881477a2b892a0c06b64dd6780b8aaad082587f5a7416c583f56fb7c5ae86edc4513dc041c2ee4b854b24cbca0b7e70915be317fe7e1ad3a230c27d4bc80432c7b16948f32637b7873a736a22223284c18162e8373d365bb6ea5be020c7c7377cbba95a7d0f74e5bd9c9824562d3548e121847fe8b1994b8c03abb80e02421eb2259423ac3592013045387cb804ac16b0afc6c7f6674939f085533d6cc019c66dd0a7d4ec4a8cb663d0748b6641434196c5f7226b80d171b43ebc23afb2f1b8c61f4e7afa3fa73621b030c16ba4de830fa064018eca149b4cb3e599ebc8a8c0c83716cc6bb4df572245ab7d2f6a0e7bc96b50a9b583aa3d7b977d1579422ecb1a48baa535cca348b9d90f67b5b1b88ce44ab10882d8310934d84c70e401ba07292755ba38c4a75810406184ca9fe595c4dd1a84db12f8f0620b883c40402734b6c49ec49c7993150a9c29658b9c07b1abc6b71c8194356d1bb68257a71e7d39fa06a6966dabda978a7abebbe4ac3a09e7261e52319e747738c485f36f917b2f62cf577a60fb6bb990bb35756ae9239784d8426d5e8495a9608d0da4d7ff9344f02b4cd65b2470046fb1431be507097e549df658190d19c3f5772bd662cb4496b34d93dc4a99c3f54313de5028d78327d578227f71bf1fb37a9252b92813f94e20dfb719ff9869fdd74abeba9c2576a8aa3b0a9db0158ed6276a0000c782a1493f66c960ac4d4f4b553666cc51c84286255bf041afd03a1cfeab3f2464c048c7ed02b65e18b89bfb7043891cf59a3538007117180489388503c542ca10a0ea3899ca5227af255702182128d987dbc11c80dfa849459bf351a12c468c1b9d44df0e0bf09a5ceecf47fd926397ebcc9cf46508cf413992ca429fb6034443c14f2567e3348c60920c216b54ce1879732899702b7cf13944ac6c649062793c02b27e63ba2083975573c03d66640ac8b962871bb309beb4543b7316234a0c3877ac5f128b53b3669c60ac88b469fceaa3f26b57680f7634bdf975c4be56e94683cf5510318329a45cc2313b30bacdde7ba464457f0d347822f709963c2870a3d7b72c6a7607c1d4414303690f2517cc476cbf835f0e64d787a09c4e5cdcfd910d016b2f3717a98e7bbab9e4483eac9f365b9921888544812339d3a203c6ac4 +ciphertext = 32b732d3f57c8a79f7b170366847c412215aec6d873046b2e7eba8baab765010a89e8feb8dc64435ac4d7eaeeba51f1046a158c28dc79a01f7106eba3ef70ddd2adfe9119565bb1e9af958271af6403cb5f8e7b6571d84eddcbad51f0af6d1219151fa7c6ea84ef780ada6c8726bd4c3a1ce59ee2680d124ad304f595d036873f703457c2ffb8ba2a3bf96f2767c01259c61760102b414569f5727a1acec0531b031f5b01ed5186734c36cbda45e6f584cb59bbebf4ab2ed097ca16635a929c3e66d3d4db54cf202c58bcdf28ae12f73642a86cd30eb8a9856f857104c85e45a6404c1b48582a2d6a679ca6a49eebfb90810461a7c0e3f62ef1500298418409b24748db0eed922d6b6e4c9e77ba054fe5c33357310f56be74c127535e74d96c58ab9128511422eed18a1069eb68321bb409706797023f0f8988eaf5852c825f7a3d2d9165d72b8c6ecdfd8b5ab8f1bc9193a340a5189618c668ff959309ea68da7c08b59ea4eaffd7f408d66816f3ade57abdabfa745ce9517489a13f63fbc68b86562be68434a239c3f319cccb5651202e6826245e09c06901aaabc44a4a8e9416850d4ab8f966f15a1aba9baf2cd5fce746a6ae807ac622bc0e13d1dd7c8defecda954559780fbdf1df19d4989ed0727b40bd41322171d508527c0db7dc562a3f55ab4869b78798c0cf4564de2ecacaf5a98714edf2c89e4b82808349b5adc9553e3cd0908a94ab71f8ab9137ccc7d778339bf9139381ee268f158a49ce0e5d2fc60c0583cfaeaba11bb9a9085a2a246c0421b05bde8961e8ad6126688be67e9166430645ee41855e71bf0a3a8af722d74348c2cfb747169ed4c448e2c72b79411ac88d842c385d85c83f89d757c281588b3009b70b4594101a528f4aa78cae24ebebe2520aa7c403bd32e5081b76cc424592babe96673f776b474720b02c57f685e2c351320efaebb0c178875dd6c3ce46b2ab0174102f5c5d863f1e9a77e0a8377a1901e7a746b4fcf5680afdf67cb510e961d76dc9067c40d0b7df9c5189754401bed93d5a3bbc2773129572bdb1e687c941ed7d3f0b0e2a7fda2c1088f76abc842091fbb96957862c94bf81c024a6f3fea008c1ce6aeedb4d2cbe868783a0c2623158d0c0a61669d4f29280611a84b9459234f571f9234d86faa2e32892bc40e1c5e3d32aaf2b6b7199b3f34452e76beece92014c61fc17fc4ea12b6c8df47cd90e88b0c1aac26114cdafeae4bee001cbb122db8d344eb85c11200f3f360d545201792dbee70748079de0c81c15eb7fc43fd90a5647ca34d831eb36f70b4c1f96d48c1c874ee0b60a1dbd25b5f7ecf53c40273de43d60f7cfea62f392be7c92773d18b667f18c3f5ee0631e08c0a7ed94b96582eba17fb33f110612fefc9a3109f0b1dd3b409d6f0935d6f0d31192c3a1092f8ffcd13924d56a8558c2af2766738c1cbbf732d440ccf0008ab1ba34e220efa91a830adeba46196ebb794f3da3916d95faa59310bd4378efd1740a46074bf0073785aa6f4479806adeb83 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 25f25b72a97f24f2a96d1c966188a5487a230c8c2b590884783236e7976d4428c881b65057852663a51b7e731a5b94ada6742ea6e405b113346781ce7c7c119e5177ffd466f07988943a26157480f970b3eaec8bfa61315205cf19315d0c0b393e05c8ae943e1bd569fa99632d644d16074a27f4cab7173b165900084a3f8901178d2154a7c1341c023882e85b86ec91fee6a2c54662c305c3169c69cd22bd8584166820a31740640c95a143a0288ef1896f5090bc163a3c716def0014c4cc8cf222c1aa884d6bc495bc718cf386a806c825bda10de9535b615167dd373d1caa062d0977368b67b5b8126ab2bd6246866c45451e89c0ec2c30116007f5b17806105a47821de02c606821bede27231383a62c65b82c5c9996bb8b749676536c2194a40e1e1c81f02904a4e1b8ed344980e851b3eb9b383a596707291951102fb07effe6bfc0db4f5a1a71cb90917e522cbe5710daca045d97ae48499ccda81a4cab310be80e7371b5e76b5325579feb8228ef5ca162c553a1d5a4a7894c77834d03d023cdb695d1b09214e3c00d9296a3928012622df8dacf17e89763048b5317c2d3f09f838699504c3ee1d82aa8342d99e46cc63c1daba453be71b4c6d46388d0333aaa9c6f8699fcabbc4241c819991f5490cc9a873c65ea1459597530352bf58ab3a5a99a2f60228f67041bc96e34f774a6f5a905e7c378d5511a4b248adcb6d3800319e536b61826b7d36820835e10076267f28d41d2843d98c403761266d7b248958f97009833d17f12dbc991d16a40698afa0b598148b3a11a1e0a6a9b72c145d8f18330e644b1301e995b2bf8b53cd536160fa273974a45ac2600cffb8fcf591dd5f2892b6457856b22c9c03032e241a2073fd9b1b32fc8196ba8a5143708bdcc2b3b22775ac6234b2c1c9dcc1b7b4075787b3bf4140e63f22a2ba77864d7622a589538ca71744b9235d9a0b539824e204f3a7bbcb12022a226c61ef06e84803909c29875f6304b0a51d63a1e4d303cd3ca72b40031d41993ce076e2754bad197280a536ab2bc57b6e71a2f4898d4707987e32055e87d98d23810b464d7c1261616bbfe131b8015b23b6207a6db8a484633c0c861419806b41a75a0fa6e537110d26aa0442061aa1154c0c199459c546c548ab8a731d0d6a9c53812c68a9123380ae9e7433df31becd48133686ad4f9b72e374568023a9e691bc8261feda4c7d54400fa51c7e051160bf16b6832b842135be534a4a2929df9251a5099331ac1a9b70869c324bc6033cb1180cfe6c6770afc05007895d0d88a06aa734dc8b06d0ca91f17371e83b36db86ef772a302e59e8aa297f15c9636356f8b175830d396f502317db73f9ae989291795e4a10602f900f197a1baa0722326514754ab8db35b78f85f0fb74002726b7c7181154c8c44688916c1abb85800a265206f5227c0e6a847075e52b2b5d4c941c516846fc3520fec7a0b0372bea25a3446b0df22ae99614840b07a28fb722efc3f29b2bf9afa577e69181cb98698d308086a16a72300fac62f5ee0a106814e171aca405886d0ea60b3461c6151a5d32baa55d3bdf0a4c0efb356755b6ffeb3b7f0da4113f5bd2fbcc2c44a65fcc27fb17193f6760eb9826d825161b940671141b99c74742269252f6605ea72109dd831dd335b4f3c0419d7598a8828482470eefc6adcd51c6dc7a8b8007ec6ea33445c85f1771043840f25d58d12199088403de9455f3f1224de0869347c842aac95821570d803307836390f939885178d59bb7b16ec14cf32872fa232213910a646642d178b4a8772ce015154d00b70ab3f5c436802224b1f283eeb4671668743bbd240f30584b899183c113da34718f557c5b74860ff895d97628e4952ce5c6655c8e6a26bc5678d404a2c9321deaa2ce7790f5ed759fee6c8ef21ccf211517059934ea77b2314407f3b88ab2600d710237051cfd8055bcdc4356ee52e04f606ecf14d45aa9f9545978eb78651ecbe5d4b8007474bb7a33e9b0947775c15c4726dc8931e2a112d79d7292b32895cd654992aa4dc78af8bb4a8bfb3b66aca2a7ea90e6e9382efe807f09b27ddf10144c3c68c308dc2d808aa93a4bf1b51948829e0432a40a7a047cc7376d2267efb2c6de375eb3a442442b81208a59e327c3f765855fcc7a4a8b7199a304bb388bf072096815bb0a3863a942b6e6c952b3099732c8ae1cb445de60582bcae824b5c20d6764520bbe6ca3aed0368576763401b75ad80a9bf3029e268094734275d275276fb26cfeb88c7c605206096c5531a2ecb1d8a4406bbd636c15a0fb0b74eacb4135430586429928b8546449a9c760366dee339aa95c175ea8252046c9ad13a82babb617c8a443aa476b256e4b8b17fb427b887c2d70bc3f108b0b6c0121b75ab3ceb33c999a7b3a6234bc2b9941461d1887c92f131fe11a01ce399dc368706d50d5f7a09f94cb8212a1e41923495a14094079a6a86915428a6d8b4913a3a49b6774d3ae10c5f73c0c1a282a2bc8f6e76202e2571b19bb8f5b8ccc4e8cba0888cd7e60550871337ac862a0913a0d7ab38c399c486a731797cd02bbaeb42a8ae9860375b1ceb1a043f068f2ff7c10e241eb12287e2d08c31179716c93325c887ebd439eec6be6abc7e6447770cfc05cd4b9b5c4990baec89cef0517e94c293da2ffca46ecb050925572ebc4311fd383dfa04b477c0c5a319359150bc2020a796ba7dd391cb65825e7b6c34dcf097866c1e2aca4e29999383727a59620138db1d71866f1e2b01989b253bd97828e302fbb1bfce536bca64336d5b6555a5aad0e1b81b2b81bc72b68d573de982732a207deaf73e102b8ddbcc69e40388d6f632ed8c8cc9487861f5143ff4a6f0633edc810551b92fb80b8e3f788521acce269072da514a6cb314409c601409a1b343bb98734360263367b379c047949092c1cfd7004c770d9b9319d915a6e70a0a0106996c312d54d70ed46698b2b86c370420caf9a25f57cf7873c13ddc9f54e13e6bfb3ca90a699c8bcc26d021404763c260a0763a626d25882596c1c3072923e9bb53d8774b690d189662c52231ad3948b79924ac31255ce319303637cad8c60ed82f7a1bc33362632384ac93aa7845880d12e901cb70a567f2c99be88a951c94982870eadbc0ccd19ce239744c290e810b39bc3cb186001203b118f599a5952aa00c5915b6f0631ba8bfbc9950aa1abfd9a777e33c968941493f7134864382756124ed3acb83b0109732bd48a6863fd9ca85e739beaa22198dbb042744a529ae71d1bfe1181fe021112d39b9728afb37d96a51c5bf5bed1c8c64337886dd49401479b4e4790366941c8173bab7c63436961be7bf3fbdf22ce5dfc9ca24334fc79219bf6096805aa24ca71197e8134055fb611a79e489cec3a6 +ciphertext = dfad5c8d269799ff7ef2ac889956b32df137b59637c72e489e11d2b99cb926b8b0c54519dab7a6ea4f4f9a835a3a7a13452f3ffb3a46d35cada4ce15ac24807375e5fe1dd4983601cb528e19645dff10b4c5c418660e5b9fb7bb157c05f79773952eac21123d3a14671d04740a2fe00695af4bf7bac924ed8ed5a4e9ad8629f9f6b30c635ee82481ea85e1cece4895b8e9a071434f3e3d09a8b5480b1dfbd79860795ffe5f57acdbb6f1d649f22cfa9e5ae7e847bcc5e06dd8a0b693c7297a5fc2e1d10484a7eee8ca4ed26d5e4a9b31d50298b484e4ad7d5489e6088ec3a00810f5e612801e0000d82a15dcfaf07ed81cc11a05e592a95201bc8d8b635ffc86a6cb92edacbf36762a0f11942509885461ff515f3213561c0afca40ba0d463ceea8ee2db4507243f7339811292f49947359725d8bd92f3d5bdd774de00147c86be378924fa8a9f1e0ce13f83b4ae395c75d4f29732be51fe3bb9898b440ef200a6187e36b5d25632ee1b4722a0423e9d83eb81eb3a46434137106159f7a6ac4234ff2d779039803b2f6e9696281fbbec952c913d04301e1281083dd0031818ebe6abdfb6037b696a515a66e3c0f7f6f5d5cc247785c9b760b0560d6c257c96c5a99c536932c07320077586d2a578897bdd50f1c8012b7c327765bbdc9688530afc1b2b0ceb93f76cdd6133d36d70463d97488e4dabf47088b6285c36ee8a81a5f76a87399a3600793c184f9562be043ffd6655880ee4917a721746c973f2ebd1defc2eeea0159b759aceffbfd9353440396dff1488904d5a99199cece8a9efb10c8196146318f3862fa2c061979fac26dde4bbf1144322b57593105335095acf01219d501b054cc8edd2155899bd6285158aae4aa8e62efb4b2480e34b54e7fd9fc15c35378cbdeae749393d646e57701d06eada6e7c1b08020ea47e6aff5a5891be538055b80e2105607c83cf0e192b19defd93e6b86fecadaabd799485fc0aba454be3734ce9c692aad1cf59a8c542e326631cced5a5fe72a9c1cef2aefb10cfe9c4a1af9f62e778cc5d8ab7297bca165c2854beddd279bc5afc4fd77a4da4ac1bb0eb0ca623185e5793385a79214ac68c2017049642a3517cc70f0ba8bcf4393397355bc2fbee726afcc4d245b9325071c84e76b0b9353f56b18e2ed9a3f46745251fa59ea4a7fad3092f8421bb9a6f00820ea9096b373f7ebe937259c3f29dc29b5a0c7ecbc0549ac98471ea665ab6ef33aa04acbea326c92058ec108167be62e12df6470beab5f6a97d1bd409778d548acf880d994aaf559c1de66ad04858789aa159bf97b2d79cef3e33106aca85d9eadf56f5d0803de834e0f6b09d8b147d2286778480826c72bc077b32543eac4e01a607ba6c0c3bd30a31765892a2ffeafdef9464978e2d20510ec1099e858888504067c0197e3456009448027cba063a1da47f15c84637cb27c21079a9a5a1aab293f5a95aaac3f5dc0b08349648ea54c38580b5af8db6e568936ef6a4e84c41a4564ec7875e018822910772ed0d +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = c4c920adb44d07a485c9c486fea90c3397251cf86a0fa36190a00ab2b3cb7f4c3b1c30003a7a481923cd6526c1b49b658dea2519fb80b0c0376268c7d687791c247bb6e3058e0c79bc36c231cbbfdca70e7bf6ae2ff5554fc6662a3c23422686f1c07498d629fa92009e69353367608b84066991c695228228c260d16289b2a2670a39b65727b20deb8582ea6aa6585ffa808268f554b47546f962c64f857799a59e65e69be66bc81577af60e9268324466230cde9786633f830246888057b23e2c96ecab07691b4a8ab8757ae4a1ce9b767da3c520c826d457514ee0605b3dccc33906e43c07e920510c27c1ebbc75124ab96afe9705d0131580a9edc3636d7937b1f00365b0c82c7caa6c4c0cbcbe01d8bec5eaf4647a4fb2218951eb68109aaa08f69e2862aa186651427effcc10a42ca8971353673ad25949cf2ba60bbec218033abefca7ea35a85758863d06b47845108076ca09834be3b8081e525666b0a8707cb8e67421896c73436ac8112412e8bf335cb8188d3d9cc612559b021338f758b09a672cb387f13419675715e61559752a428f02096c469142b6c1b74c51709a515b9f7a278c0c96507b6ce615dfa647f085105734cb31e801c56da2ad0553807c698eba02587b51769a298c806b8d3ac274ca98a88f4a48e022ea065aacd5c8b3a37227f55c9d7288c67f5cc5e05a56e573fcefb0eb90164acb9363ef75fda42cc4db7b131bbb9d8459ae095631e563ff22817dfc38622899cfbac0d03b6a9b91a8fea9775e3b835ac99792c2ba2c66cca9b2768b07a9fbd471b1ec78bdec406437241983951d2435aaf30930e667d3d5c42a113a4e151a546c012f1b84ade126ad3c89e5c60552dc657b11a067182303e450a2629bc7b624174179b38e28a1e717030429c394389668455a4fa432d400978d5259e3316f8a895539b2730384c17760870f9a794b653715aa612fab2d2f896214a4151476f3fab01bbb50b4a392b45764db90095361a13b19b9415364cd3f392d20a4e182942186167ceeccfb0a7ae9c0830c9f48479270829d1776bd555b1715891365e7e6a1ba726272d16ae3f0b8a843170f0b9bdc304b051f2271b3bc424d1b997bb4ed757a20e2b57535a96b786b1f859592c870c24d23151584ba9958078458d2e6ab4eb629962ba6ba80a4ebe2a00273a1eb6110a09236129a0a6fd15c6ac5063a547a8408ca72c5a4762c4234029927c7992f1066039181b11fb9add5c7b24f443fd6abe55186c1a70c9ab0605ba4612ac6381e8d07642c24a6d63a2f2c7957b505424dbbc9e220ee70063f44975a9250c6116ab9a15c3b15847356b7e947339b044177ee9a98e6a00f8d98da605537ac70c677c2616d4c73ee72380dbc247e00bf07c3adc9452d721701a4b938a10b384340d4cbbb0a42219bcdb6609b4ad96e298c949aa00338baa9c34a3a152b956a8ccb90dfcca88f9bb7903d6c210f86d8316958ef93570ba100ec5753e1ab331ba6554873680fb9f03e3aa7d243281224f93ea333848231d024737a80696fb0755e967078a261b424f1d5304ffa934ade978a6181d5754cfdf4b1001d3012e220338f60bcda6a0f1b857889c2c1dc31fc0688ed5d78bc2206e2215b867428d361549719a0f32437f32a4a72a652a5acbb41842b42dc9b59ee04ad950adaec019df6a2a0ab392fefb59336b576337a612509a70a543f902be91e5331148bde43a23c894c00b67c7f9c02e9a21a304b46c92711dbe6b023b054ce9131f048923175c120ec0c381465897dbab68fbccd0494eda12ad17e7208ca74564065cde29b404bb0ef7c265457a49f40bba27c436c1923250f741e821cffd690ce9d8069a106d0b446474b72aa23a6bc5ea40ceecb96cf522c9c3bfe4ec39e6a64d3166b9d381aa173954fa3bc12c015fe560c9d509a938d09658115415c14cdd212a427c13ffc618fb457767358ddd21cf131aa5e18ab5d997026d3cb4e9c595d405b8320c98d7711297817e6fa85f8a6cbe4e7cbe31a95b7430470e95365ba22d8406c1dc1195d6d1b0db9360366129e8c23516f1157c6163f59227e763c63c709fcec5917e653376f91e8d081299b312efc036d1498c59bb43f466948c3307a47a1701b292bdd5c180925f8c65b36780b50c2695221b7fb9ca209e0b8fc1eb02caeb63b1348a463c195273079e84ca4249bcd6c84d27f309210aa0fd8855354058d09b265d0b34dad44a1bd72ee1b101bf4aa33e2bb5f04375113834b2eb942430be993c25d2d54ed41a38f52713e3723306255131c41637a333129ca8e8392e5005b0f6940f560555fa500e349b342f7a0d27998b1aa70d1518b80dd2a0de6770cddaaef1dc865ae7123b0612c5f0c19a8ab8df4006162447ad693c9d93383b0931f67c84d92b25e3398cdf4a3daa2aadb0b74e99a276316b358f5537a0f37203622262f791eb803479376e30375180a227ae894bb24496546715a530b936f99d008365d9db1fb5d2a89b2a63e19acbe90b8e7f615f79f2cbaa9c9c175056471c0112860449e6783a69a462916fd71275015c128bd41fede8164a410bcbf1392fc47975d017b1cb188d3889aeb449743bc16505698ac25c0e02c92db2393d562e9d3197ab94cb70b110e80959bf48861190774ec9005757784273c8396210e3032adf4663dd6054f76b9d9af118d067241cf6499c052258561b31b8096ed608ec83385aea6d24dccb3000a4701cc343658353192f764b7c000902018a744cf2c4c5d57ced96880538c2b1fb466d5995e3f7230b99076722baff267f2c625e3109b904c09b1585ce4ec18322691c9b083ac65bc27d731127360a6329182c2756b8e98765cc32d728263aa36c8c68a11652b8aad1879c437ea3fa6b81723c56fa880672c89f982dde0a6e192350d761452c62b3bc49ae0a6900b7267f6145ce9cf1bf2bb128a2c6c6d84182e4e8488016cf3fe773e2b0b8daa078f16a032b2bb59e933e0d1a5b0af7c1e131289f79700720044e5b4a23033459472d9bd451d4acc2539011ee79a76c4005997c119093282e09a4c7ca9794481abc8725f14265f2e9746a106673f87756834a694738e839beda599f51e6170c9a5afa2120f3532654e3abbacb58139371db15a66243a58d51309b33acddb42e7ae59ed7f72af354c7cb728160636bb971ca050a8f6b41a13f584aa1a1bc2a43b00caa1fb20bb594064e2ff2091e62aaf7b4bee4203d082c6ba6e66bc776549e9419dedc37899b4d5c44d38654cc635d620b8a1a98881abc5f26457f4015979b879f2acee70cfb1128d242ec8c0dace45d172b95f83bf4c993d1ed571ce7ddd0a8676f60fbd61c1d49688213a953a73ff332475f2e44df9c77f572e9cead0cb7d1317a66 +ciphertext = e74954216a08f66ab9612f05ac2551f16201e226753d4e719692c3ff2be1099d1ce54d0f78aafcb9a8d9113f8789830560ef2f0a0620f13a6605c786fc9d7836709b4e333c6374c206ffd63e88897f495d45f59e3c48f7114780a809e8048a987aaea0b4d2c1c565424012f3465800d609e77728aabc2343a26b64b9ba9e4ab6413800ba3b7e250ce222e04364753dccd2ed1d4987fa163ee75f5e28eef35c532050e3c3e66f68e2e8e85f8674db0080054c9c3aa68bea140e140dcc482091fb7a2b75dd452fbc50e1a9e46637f0820856d6357c3c219f389eee8b60d8ad970b17e2372ceb0871fe73dcc0b2884ecfad7913784bfbbdb3815bbcacaeb9a88e9d44b6c1bbe614c5c2ba170a8b5c3ca2f4fb23950c28f3f4c9cbd04bf293e9f5274d123a706fada70ca228fea20f2234d298e1b56249424618b7bb8e67b1b2de85c0ccf12253cdd97ddd2689119491e720d4744a6ad220a51fb0e522d85e2b8d85d2dfb23d3e457a19da89027d3eb15a11a618b5bf8630ad533f7bdd5ec141008441f623f6687f345aead9f7010dbcd251af350b4aaf49868c77bc0e15447bf42e9fac667895b69aad5dfddc5ddc4b522d1ba8af17968ab6dd9ba2e41c94668f87cb00516150497e807a90988d1e70b95e05246b9dcc35ef3c2cc15ad45ede2fb2d0e07a47ac6c02bb9eede8259193f893ecc0e2682040b19a20625b7493693bc26625a4c5a136594d8e1ce4de13eb196e019914f229cada7d5c48dc2c3d6a1524bb383e7e3580396119af69cf817c8debc0afb67a0bb39bccdd48002fdfd5020931766ab681d39b1bfaeacc5149aa8a7d44b6e0574eeb427900b825836ca0659ee8ccb0192f8c86d1233abec6f63e8c0f601cd56d1ef95d96d640106258c73165dd2d98d0025d34cbc4e5eecec7c2aec3280924877b5b105bdaab4b3d18b9b33d6fe8be22c097a10b992d1ef2178e9570acb665ca1d0f63a61a21c3c7bdda23bc25f1ffc40ccccb73e67b22f3361f20844e677fee23111207ccc0d2bc8f8877a0d70e8faa9e2dc0c59e5005cf90ad3708d22e2e26bfb14c51105904c9bb7cf7d33a45ac030532f8f91395f4d8e3174c63b96cf12df1839e9a2fb506ac9736c6a1bd9b6fa1926fe0db8e012022f795c8e70fd35c1123eb5eb47c244831f0e616e7a34681b1d4a67a57ac1a7561fe925fbbf3a2d1f9d84e198fb9c0f175cd46a322aed3c9c24b08a5ea7095cb10bb1189c4b2f1fa4c1ffb586f4a2f73dbb29c2d232350890dece63f1730ea9f7baf4257ca7f7f0bfa2537b10626502b9ed4b4faeaccace898d2bd56999a7d0b18e34d553a8f86d908a23b8b90c9b76074000cf9f1ce78d0db7e29ce7407ed97fbfc0ea879be1083de5b14960ea3ed06f23ba7944f17c06c594b25c5b314b482ed90c0799833b2e7bebc619e386173ebc50257be64868532d301b5db07995514286eef451ab4ff3a8574daebbb97fc225cdedaf34517582568b0c2e1c59ceb0f97509f32856a63b27e42cdf01bd47f902cbf39b5c3 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 285caab0ac5386daa20ba59fbfa2b83da79a106aaeaf9b741a347c66d65dc1b83edbbb920c479740d703cd54054c6981197a17f29808ac595f1b0c514d2bc55b6743de913324b18f7787b7878324cd434fa63885e9c221f8e72436f764e0c88ee8214c2a623be971a80800b84701a44fd5c1995b5b39a7c213433de2ab48a7f52cd6b28a2048bde0385addb9bf194a6934396361ba98714b7a8dc56d0041290f857dce0aac01d2928e875c94c22984f041691b5125148590277c7d434a32c30fe5e05074393b86b43e61542c3554648fd09b3044381a8c5d914935dae972913a42f47715e44b8b00c81012675467236e6824a8bbf7a8279597d5eca1b721203e6b2e20f9ba4930247598b150a24dfc3119a2d74561115df0541ab959ae14302ca91ac0c7292073052b86fcbdc6b3c1935aa2086b488352b813fc617b76b2ac06774b6618203a4e08833078c41b3a33a0798a4fc0fb1b6733b8c4ccb82d60a06da84a4551b44a70030fb56411da6bc5758c70b90cb0024bb651ca6b25850968b7bad0b74d773ce611b204f0c5e1cbbf78426e74d42eb85c01e5a7a497103973908b1e9a4654c61c37309167e4b82328363eb91704ca68823203829c8c5b0461bc0a024902391ec6370e8990eca8b67b11460a30cf520cbf158818f5536790d869be3546008547bb1b28f60aa905937d6818088c70325808c5c74354f0b65989709bc76a05d2929856a43867089ee805b0dcaa38cafcbdb370a0893708abb12aec9c8256c9ba6959106698440ab73a0686956376611290b98b38b58f53bc1d9b9d3d8790f1ac773f9a0befb95199343c1f321f15ecbbcba97fcd358dc832c97e0872976211867228c3f327409b7ff2078019e1b88612cfab807b9873a74c4633572ab50407ce3360a65a8a5e431c1244749fb50a2d64d45afe2a27c36216389155ab2b126e521b4d323e568a3602354732531c70d9a348403fb63144e10c34da216c15f673e3ba7e2e1760e49b74f17668ff103c9c3c7d22e8b925267dfe0b125436443a194eae6042ccd67ba7e93b4d81cad21c90fa0a25eb5390bd788f35dc10d1448be135b51794465bfb3eb10cb1841ba7fd83574177a4264b3b9c1700433c906b1c38b93ca4fb377c7f1180d823a9d9735b7c7707501b3cbc50a493f87a541c3cb3573a9fa94f02e0a5eb80b5b4b2c84c345ccc41b7688077197bb993ec588538738a9113610146e6db47104bbe8fb775aa8a204d6121bda0754d753303a5473ca251ba45655e449b2957c718cb48eed2634744c11a02a674d304830a2cb5ac378b073e539a638eb0687aa6a3706194fcbc68c7e80c6be09ced00b5ad08457294974c9419b10978bd3a9a0c97ce3b76a0928c34f0a2be80b24d36c97c46928ca823bbe751b26e1abbac67469dc1cb3547755e7057ea3a56b8041666d84fca9aa4565798c77694be45cc91581e85eb5fd60c71d78094aad995fe27a796d27ceef8118eb31e4279b2e67bb7c12b65cfd2551076130831859cd7605e223a32e586d4737be543b87bd2494a4c92c51c0172a1b554b3651f70aebbf89294ab1fac564ec8c218c3d9239e40a1e0b9799a07935e8133d26b71637a091d780fbaf299d56291d5395d17c00e998353b89419c6b607a97c99d058843a59428d400e41a32a664a9c2759aa271a586457baddaac3777cc19cd762bc48948d799245c99423bb4fa1eb829b04b01a6b9fec724f5893a859f427c93213051c7ecb6743c9fa4ed93ac98ea0a50e1a5b52fa87ae137bc947ca2b03a8eef6927c0297c99b9010010d541a6a3775b89f82b33f9c1d6bd8be6db780ac0194c3947e55ac232b301bf831722a671860cc35d51ab441b846c3b261ccaa60d2b25792dca529b6be20fa3c13b81ab75062ff22613d3882a6c1719c2c0374c84db00a1b50677c7a2b40c2721a86ca4d548b50e4c764e2d004838cb1dd0cb88407b3b49033d2f37d15089ce2ba0b24dc5744b7cd07074e7b2bbed5c1582d019dda7196da202e7adba5a115591dba791562a8cb57a803fc99c9e57237fb0ef56996a40a1ced86813e4b5a675a85d2e26dc09b2bb158510eeb473af23c9b549e298b1a2ef02383a5103e137b43105d7ff40093a688c26789383c55f3a064b8a41d51e057ac993f15d475acb6786ffa3f261949e8658437466663f543c0d4597a39204029691bf741c1f14fe57a5f45967db3256d3eccacdfc025627a33896465eec4767f6390bd661596f965bdf25f74ec901ad907cfbb8c96a17c2dc8a0212b00f8a2b9a46c26f02c0c647b7cd8e3328ac1849b9024f402bb294a0a6e24c5386182752c49970962b2d2b47da3991444c082a2cd10c3a764d808aa94c601ca89ee5ab8791038690b6290b91b9aa1cf79a9363dda4fe4b876c379337c5423843427e4fca39d238d152459a1c5a4f2e7559ef4ad5e8701fc496ccbd63bbd2046fa151ea1ab2ceef1aa44aa34a63b43a0e4859e831a4dc98dc1b007bee26ff5336ff5bc87bc446ba9e16dc74917bd494945579dac34cdf91b10476bc2a8a88af5027d95310bdda047820798f2a806693021e7907dda61b613ecbae5b1a0e57117af380f053ccdabc86362334105fa6dc45445c4da56d55c1ffa0b1f7a69691b673b68a1b1f82a4ee708a7ff3b3b10ab4204d72de353bcd05c0c9f2745e307b679e165f02cb7616b838639cd746a0134b3a1f7422665f69503c4177a691b9b965e3ce8c303d02c5e6caa095194ec12592b51ab17f56fb380305d364582159fe8399f3eebae9b11a19dc29e58869415f9aa590925b7c185c93774ac91589ec860113b11fd1c5bf8a74351e25ad5cb89a965238d056ba1993646e37dee30cfc0161302c379c4268c49f2489b057abfa406bcaa8cd53904dae8c3c2a3a3660ca2dd073e47f54f7f85ac9196b61c55b6e4660a8418a384075d31eb4653fa271a662f5c1a6fef68349579be243a5d9cb6c3a2eca682b56b0d753a44fb2feb2a83732a83cccb7626ac2720921c4913339a5421ebfa25af7028a20016849484bfb9439feb837f355d783012a922204086267461bfaa3026f397332ae358f2a55f3051c8fb1a026a385f185ab7927b307291ba7c504ff3d95ede5b1ad3e471472a0e1777aae797107eec70532b6b8a1a90e0cc6cb8ac8980fa4e21c7ca8643b77859216059935284567c61a0b5555db9cb17823024cefc7edd18410892a623d07e855c608a098b36b7748fa9b764520878fb8d6f4571e4e74a6ad348ab45bb9cff5177229794d2a59603e9cd50f147e36225724a946774db2dda42ee0bff8ae5fda93089d76dace76385618f46d74d1da70d198ab3cdc38ec3bddb27231c454ca335d9a4df69a925660c5bb6cb34eab79fabbaab +ciphertext = 4b72363dc9be952d09f3a3b7df969c76f6b6345f1bd386e7f5d4fc372ec86f1bb3ef16e1fc32773dd274586a69c8946d3a965f6733a9bfbdfacc986825c1fcedcac4a8880a3e0b9768c81dcf429f6e092d853354af4c4a532a14ff0a2142133f43920241de89c87aabbbe6fa20c10172b84cef53277f97cda9bc24b77f4e88c2bca0b53ead2b8548cb963dea82242280e1852f0d1902b1a662112bb29dfd50a0ad3012a511e69029e7f6931a6d50c8fe603e7db1d73edb92bc3f1c0c834ad87a259b6620b080c996838417f3357198ef7c3b42f4ab7c270a04d5fdc208dcece81a03eb1e66b41dde74dd22c355cc2be0fd8a41524348d934c8ba2886d1258e3ad1da4e137538d474e0415752b970fa62afc09695f0f178642c599c0154a16cbbe2c2843b4fec25c6583ca73f54fcea017e4c69ba71c7b26dd3420d4d61549956d2553337b74975ddf9ca19b7630176879e0e0e4b43dd1a5a892305a00984645135c575f6f4d7b3e6ada77558f50cb9ada4caed92f6b0ae7dc4f6353e09efdfb1b85808a433849849742f025a37a15010d32fd132dbd1d05a0e7fda0976dfa27361d2b75c41b23745e5e026fe97f08b1479b4e41a355160c2ba149aef4f929638d80e81c401931bf17735971dd92537384bcbf12a6ae5207aa6b6afdb7dca3f5f4c0f826b2dcdc785f11cd38792c1debbb75375323f3ea1847ba9d9c5fb8fecef13a48981283161ae70de4afcf681e4e5cff3b3dce017639e14a2cfdcc977a1c772403c13d22386e9ca4061e5c905234da915d30cd82535e29ff8cb7aef918d14d1fcdf280ee584cfc00f0d815e13045b466bfd191276a2c7bb33a0015599b090249aeaa711d822f0deed44da03f231f43cd61515ad8d1a885c648f9771df0cbc77d12d9ae5f2481f2e24897a18e4eb0db9df4765e4487fdf3b369d03e70078392cf06a916b2054ad08d98a1c05ce9e6b3c0f38c4fa631205fe0754e1375b1e373127b68d9a773fd4cbce22f28faa4e1b740db390ce5c346e2d8802670208744f5c8a573d130485b1f7313f219263053a46dd5dc2972411cab5a62600be21f616a987316b411ae685e34c61807772e274e98f9a525cfcf56ffb0a68be8e9115a3bc0e02f793067efb3220d3c89655550f78b8b11fa95b3505651bb747d0b86b55ae7023633fddcfd2508d87456ddaf788fdd11ed73b46c27fa24bde79cb26cf77285253bc2da18cf0126e92a7ab7658289a7d306c0c6d60816152ac9d66cba8dc8c603c9cf39096d1285e8c277a7ee5272ffa789eb1d70a1ab88419f5a48e17805a8ceed0999724e8a93d763f514693fac9a525243f9864eaa4c1351d37f9bcf9c4ff1de7e617e4c575f47945ed3711650fc6371eb09d0edef0e822b46446c12bf410bf3abbeabd272fc8b6d3d9ed57164820d33599652fa1671768ee76b95d6e1bdb9a121aabfb234bedcc50134eb8406f415044e904064a8e06ee6c7cc44fbfed3f68f79a75cdf38b4d9d06ff9198e7b06e4659d9e435011a4a40d50d223f05 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = a21459d961914fab4d882c9172971dd030ca9fa2b8c8c24aa3571595ac02a0ca41b50069bdd6708bfc8e291baae23310d440177837c4c0b43e2d640d900c2edad5c439b99187b190a9a4ad73086e9be2cf22682d16342bbb5b3794e68cfb12baf01b788f21295aa4b4418ac13439b2b224aea21b98fdf6c96a6aa33643aaaab016f277c9a4f6424e9b54007533a2f3b2483745ae160697eab14fb8aba44563c5259c6d8465bf49a7be9a69ee85b93d71271307647b68a61ac8541784ce22ea8d33f57df3d4569fb68ada6692d40104a2e221770137e2273bb25b337946bd4ad258e73a64789614bd28bb0e247cd3d112cad0c8fc393687cbb1e3657f71fb34543b8d83050f2cd9c11525bcf730ad3eb77c2c722e04577ca0c09805a3af6c68c2c73254ee0a100be92318e011cf51a3a3eb003763ce7847690ce1349774c620402c8232cb98d751d22631d2bb4e99562aa47ca461f39f3f371e853ba25c78462d48053175a4b8aa87e9524ab3f24057f19a7823aa5ad6a91f7409b6698826b1ba85f387120c4d1312974c82a8ff50554da032d013860ba1567afc1f8ee63dc8347d5f617c1097a5fe085e01a5a0dab65733eb1860346bc6441438b0c0e2e78d362987da746a985b36394064f4fb645ae31c8a2404dba9a1831011c6a8b299c1abf4fa2e394c6c8c5b7b77c43859975320d5825e7650aca90777b95e8d4a72082a4136fb9f54f4ac20733096221ecd970d669469118973e682999f80a871067e93e1a5f2911001a41aed86ca65884ea7a8b89a009b01eb8b62250591741cdb99c8e361411ff947c726bfa419b1b527c487e15489f5895e7206c4dc5f6b9b76bdda20b2965f02f1300be0c4d9327619286a7ff86d254b4a28b0085b19b2a113abae5cc7073a8a01e92d77b8680aa78055e88a246355045acc45327970034ee28a2d997941ffd54c13a95e16cb1a8c1917418291c7248959c0c361161c45e9b9ab5124c5c0315b86c4ca5b6f1a4c0c15e91f5327a2ad7c90a0c3cfb62832b20ccaa519037c61008a862c34eb1a8fb5208f817103d0431ae17729863a0f9b61ce2648a2a91083c58ea3d35a7a438ba4ba6dc187b4b8829aaa8530a3c2a89e29217762affcd69ab312be7adb28ef7290ff851564c93210f793c2c80c76f6958266640bb48f24a30951447c106748f7d64f0ad157ca2a0acf572794b1adbb4b4658d2a504e0a7cd3230f8977f46ac9a3dd16655e953f8e48c06391d07c2363a2c280b693fc232be7aa073f84580bf1c5918577ec3034c66753d535b1d40f78372956272440f532230b6175256c71ea3bbc1f9b88208a37d3312ccf6534e005355e4fc1d9d658d4b457c9e37893cdb3c649a9157c99bb074496697121f97512bc83c536a81120c071b6a95a6c9420eb777fa00981c7569b3752509c461d8b48055c1285593570f0586cef488158288d962206db02e38c97584e28a790b28033b784ba4ca9b8073b9f1000c596195288a996c1f96d416c0bb53c1755e8afa7499e88577c3513e4375a6c10cfa3ba60bd6486d29ce25bbbd0dd26153d9b8565ba1cf912f9f0c4413b76f8d5203ff67cbc774a16cfbab0453a0410a5a951bb45fa30b3961c4b73b278e481c49e89c3581a5000d83d654851cfb0a65293d13e31ca71756164c5672cbb7991ac2173229ba26948cf834e65a99950bb87ddc050edc0f77c98ac2714bc7e6b64aba4a1f0a4463b22a810a2986fb37b667cf230482f51b3a96188357e01bf9e8b03518a577c759649827ef1c3aeb677413fb61ca620dd65262ab6b60460c9bc543b051483d26ac90b4374ee0a157d7797aad86c21c534610d93692b84b26a82b0abc9bf105a44ab1c9c332871ae55d0ce62c20f7a290053500e3b827150cdbc00b9c314e685ca936c26d6196c6f5bbc05fa1122df62e9d484ed572a94096c86d49655ef26d9c47582452a1f334bf0889cd9880a79ee4aba2022d7e46b308ca96568a7ec9472192d175d2cbc05257897039bea039cc3c82532a0b8454739b0ce0137d1bcc892704fe01b766354e13777e46282c4ac144b2c8c08a8c6855d4971029304771cc4f6744407670e0a489048cbc92e05f5c1667b4a71ed628c01c34891208b7a1e24d6abcbba0ba8e3aa5b8ea0a3d79fb0ea9119c2c84c9bb5b06ae5430e73a0c31e15656b7bf3a1b40d1c88704b85839f66fcddc322047601da7b04a8950715953851932cc5ba5a9cc62a75a5a84bc389218161f91774682643a01539fe319fd0a7b97855b92d1ce42e0aa28048aa8a00cc161ce42273a77d74efd60a646775bf1c746ba5c7e2421a5d2ac62700066ab283d5d299c9e752760e13c05b315b5f8903de78bd29324e9386cf792669a4cb8623c465d0915d33314216a9ada34a9a9341280592d3336938a0926da099f9b01c9f855855302662c1bceaef673a6bc1344451b1c8453915cbd1e33060cc865d773074d5c72ca36039eb949fb9490f76c634fc160b1445f7f27b64f4413387811a10c26fe6c54adc2827d691fa18b1159814110000d55f78f80d152b25b47193bbc7d51b92d8010c438bb6318086d5c5070a75ed21451d7cc4a63d42f24986e476b485d36b04a47c9d754bd841ba39c987f8d87035a10482e16a8b1a24a5e5cc28bc0a28d42320c89149fe52e95305690ca00c3d13eb94530fcfca2cb5091310a44afb60f013c1419f43cfc733c5f218bc78a528052065ce85f80cacc8fb4a4a1a30082a47d40e84d0b9ca44418a9a49c46e5baa002376687f81c95b2cb9a1369020968d3e9c6120444c5d126aa03485d2a0c038a7cbdec24aa3865ad0073454089a31b302ddb040798ce4289c00cdb1285e85414f4342bd63978c723bde75b91c708b4c318e626cd5598a9c3390ea154ac4d91bae2b07935815b76f566640001098882e0ac2a81a641a2227572c8b7df7705a0e24283a6acf5536b07da327a73af1ad32bbd80892cc4113a012332326eca32a16e04a9b897323ca3c817b65272fcb3c8c5570d16323d94334594c6fc55c372a325f3a42ded47411c8527d6baa4828368eae4b5471687698b89961b6cd7c91d8e11427f3abfd6c5c67169629de4872c253e45d610bf610a8152791fcaac86b4cbf2fb485f8538b851bcc42b13ace6ad99937549338f4cba87d84a1321fa8527f097aa4044838178f6bcad1c718d389729b803726314ba6ccc3e7f3191d9a4ae1da6a814401357428a4c6a7c63116c05f1530a9c2d36117a43207ab469d47dc42d652fa9206d61d50f75aa6b26e9230a35c52187c560b6857ebde38cb2ffa991ff8a1d5110a8f4aef41705484f7f0e139d1aa3e77dffdb00f32bb6035910e85cf52db3160dd064812d3af252d98287ae1d3bf4a70b8289466a970ed23f2e57767c221b84e2aa0eafe409ad00f8c9b0 +ciphertext = a32c668884e0a4f2ea91c2c0f18fc7c6158532697c4ed52182b9a5e781163cc6388077178fc41cd77909e1929cccf1b14585a8b17131be20e9fb4b1a63963f77ce6cd35d3e8755ba8556b4cf83ca39cf370695bc960b436fe94085cee21b132e039bfc7f7d1d7c6ac287422e775e16f244490d3b9f8b4c42803af1edb6f88fab0625fb4f8b81a13810db43666a4853d6c32010cc6b89fb5c46a8d55a9703a2edf2ac16a70479a95756b2d0c52602912b0237b3e8dac2ed54cdb1efe9afa59133435e408ef4b3100d4b13ec36025d7dc1678c4a02c74a1003f00db41389adc61db85a066de8791adb0386f99893731be04a2bfca725bebf6f95fd247587e6f29b879712c8d96d826faee91b868187b253175325d6774794e12acfde38a729c32a9532eb2c606347e16c9bf057326da26cec7958a5783093b2d8d0c4d3a3a7eb56247c8d94d7692f9800d2eb1a67aefa98265c29ba67aa536334bc4a970ca42baea00dfeb2a1e06f73b88a3eba0565d1568c1a8065fea82a156ec7afd52d3ef094a8ea5566006b081dd0bcfbde612168ef50e2d48c1ab8c607642eda4643d85678d9717ffbcfdee9b6071c1a2f98f38a313e91036c2d8a99895ca3cbf2c8404e9ad5a8d5bfc2cbd873e79d8053e6723f6cf37e1894d0ecaeb09ac0e7f473a401f240870cc7d277729e206d0c10c9621b45298118a8c268e46503ba707fffab13d9a16ee7c0b864c0d2fc388223e0fd0bb9d8b05ae69773cdc944b58d95dc4cdc8dd09dce9eddd6a3acabbac3e7d2b75581441312de3ffcfb62b21cf8e9bf7bd6c638df0c4a340b809174de18c056474bb543eff6748bf4752e0d054b7d31c4ba00b66eb628eff2774179e02b2ec6eb9cdb9b5b54cea3ba49f55acf9f8da5718afaec914abc01805f76042cda00fe52eaf7cbed30a066d38330a27a15560beae021b4f78f24ca665e3efef69ba3e01592bb12fa65dfec707311345b9908ae04d18eda9d0abfd69b93758583b76e8e79e0ad9701594d64d75eacaf562f4eb1287b69cf4f91297b60c677a624f221561c440bc15b16975b5a98d3e10b3ed06bdec4bfa50764896f9f9261115b9f3fad309322c734a26c745f9026762490571acfa3fb2a2c9769906353667e850640797323c373e9d9758467c9b57f423fb70ef18e41116b72f4d1df55fdf99427bae4bf68c336a60fe861cbfaafec271b7268eef450762ad7757a4ab0e78fd23831652bd21051a53c0dab1bc1f573eae61cdad2dce9514ef53e111076be3ca502aadddb2a7def10ff1c96ac0aab76bf82a8330eb20837f806b40bbfe864d90dea74c9692521f2b73ac77d422429b81e363570a8463f8ff8bcffc46510fd6cf631380ba764c7abf3b0282046aa13244443f1568d036d850942240544fef6b9a486a8ec81199ad7895e22da8be8ee01cae87c4b84cc5d2105f4eab737554321eedc077540310a7972e0258a66c25343d7abfb4c81f84455ed0a27172b45bc7d6fc0771db1ac8d1a088293635ea42e25b0dd81201fa2f2 +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = a3f43bcc938fce127bab21ad82a304a1a4290c8b2ad82245c1606d6ab3b313d853c6155cdda10f1307b9926a404c777a6470a9321459eb5669274954ebb6748a67b716083dda13bf873abe76d91b3115093e8144f575513aa80f715b349c734c711cca52b62dde9865407871709156a49006ad2978f1a7654ab61866536b9ac5ae095a9239e795301aadae4b55dca5bc5dfa379db805bf9327383324f44b0719ab34130b1fdb639a93338bc10b12b673727674192e84ca48456194c7375ab055f56a64fff5bd2408092f6803783b7168224045a989bd19c615a7825f9cbf8250c6738c94ba835bc2252037f38b9884234052afc4643133e835f5b27e4d2252afe319bd616bfc993bf4bc9eef327f8226a2fa8aa0f418495ef96564a3a80cf4774d06813db54f7f7457199711c63c0e0fe90c4aa9197cb11a75b8783cfa09b2ea57f8bb70b08044c658c64ce82ea57701e121add0ec8cf67561abb6961226091d2370f12b5693f750be704696a6a2b1c08f3b5a29fd883fcbcb58a2010b159c48e99bb351c5b08d3c078d2b34cbb7333ea72b89c1a002d01a66c064507b5f91469ed7eb09f1120f22b32ed308b48a75690c4a43afb7a44b4c7054e797a6d43e6a63c227e56dec43afa73619b5300001e5366145162472046e7401f05b3f63c9a2ed72032cf33e90db6740c52ca1d17861945181061b55a18d0fbc3b67c74d0a789327f576f9431006e5a4ee5a06c183329ab2160c327244586500e4cf90739011e1689d916d4a7807abd6495dfba715323464ecc66e69470f733c43e856fd594f32b06a69c4bb70793263c76605dbcfffc1beb4c4702df1a9956c2857d581b7f122f4169dd6c00a81169dac8cc43c79320ed685973a79a76548669b4a7c14af7a71a802d852acf5982df6518ce87b086727cd9677163552a6259547884ee1120fb1a210b802013b956816ab31e747080a67cc5f013c9e424d081027d10185280331671c1c78a90f6e40450786895ee46786c90c22f744f75b1150d97175e4a48493bb62e6927d340da37a324d02cc9f911eef4cc0bdb645c3c09f5d511272ec71d3dc348ca5bf52567f84e09d7a0073caba497377bb16a9425e6ca0bd9458f8da37e3d2185b2036056882973a332f0b705cb258d579bbc6fc4908575c4bd306ed0103f6a09d05d410c690b8d12a08a2d53757b1ae5aa965c0c5c7af93669f0b17b4183b834b291e119ebc8713eb0a09380c54d96a6568751a2083ba0fb3a45e4bb91b77613cf9962351a48086133d1155881802df7cbd5c4cb31b71504631c417bb7c82f883fec7c246a97563d3c4d0d8a80cec9e261453ec870e7933177799a3d0fa0d313794d1191de81664c74b45435089400287c4ca63e8676ac9a2acbca426dd2064cd808cdebc571ea193eb72c96e17a0f5c3b4a93b2062b4381d054af0c5b60ac27698746755c1943f2a460f67a601067148e83923490690b5c3e45862a36646d7593760e9cff0ec36e38786f995a08719b84f3795c5da4539dc93ec480e7400a0e369a0e5514c6f370ae0b9c70636161d7ac03234cf09d537903ba66321627576a76841ad7f69ced0e478f5b4998ccc92deba5540a462bd2807d0d3bad1ea22a45b6eba4cceeba4342ff7ce3c20150e75339c0c60130a1a60304843aca576993f467ab4ea9ab8178506fee531f4b154aef995d8f3cb4621239fb763f3b91d29688cb1886539265c7a364490aa2400a41816daadc6342ac4880bd91a02b04b2dc44619111513d9194774d6b5baa82967e162cdf239c19887efe416b46258deec8ec6a2b6fa5c5570f1372250c9e0e7be3480cf4c42a180300e106445531cbabd735cbe11a0cd52b4ab8511389bb985a0a82f227ec90022c38b27d8494de21696dc71cda717a8318bc5f7068d7b70840ee390dc523a23d41cd37955a99c253427bc4dca4506fccd75eb5acd38081096b6f1e447fda10123c8971e06ab28330b0116454ec28926eb448bc0021e3a9ae8827561ca87caf8cf48fac84053a34231294e8bcd53a9cda27b57512c1a4375a3ca8c124ad403ba458a831aaff28b67fca09efc8cab6ae4a829249389f929af70a9c029910b21ba5e18650fc37da37a288ae1083b7b6ebe80a302b43bd2a08215ca49954271be98904d465552027d644a0f5ab2910329a3ac65902f9858c8e94342a8bb72f481d91b860bb3af81c0acd8657f91e82315c385b759636b315152b81e9649088b79439c641577d3b8e9e3c86f7cb95d6bb98850cfd06bb5ac1371f733b8c63071a5a91043d92a116272ec049551a9aadb2155aa861819986bf42b9574303aaa766ae8389b6dd1703eb8b3f2687c83540ebcfb0c5b04bcef3c795bb03365e127ba4506f902b9d0fccab1078d40ac193d0c957cec5899f0aa57c179d1402295857db51a271ef584eac42d0fd011550aa239c62854562dff30746a9670b7bc993fa92bbd772f533b90ef2480f80225606515c003beaf2a99be196cac962e0b4159fe9b3e821bc0b992afa3e1b0226a26f08989752731a1d9810348ba2c267d2a4a289ba339481089afb582e144ab8fcb19e9f4850ac64974574918e403ff8177411275201980822a3afbfca266fbb1f1992fa031b38d1ac737bb729fb751d31a47c1eb0785518889eb3fcd3bb620b85ea8f95ee74c17bd2a9882c90df92989d597350b660aebb314822026788458a2d8656c69b36d979b3e64c36422aa94e236ce1043a47257031cb54c61548b2c56730746b50924eff75205087361084cd9c91bad3520e1c3c60e616999818e1e2b0a44d448ad772b0f03a2c2f72890fc6506e037baf9857e23063ada62fe793d92615e6843796b067019005a9466661b7bbd151b971b27b9c3c231f7a11df04c5123730f3d254841720cfd5a3ff937442ddc15dae3a9267743ce6c5f3b0356d7e12ed755adfe85c72a842fd81b138d33ba9ff9ad41f62290d29236a7bf21a37485a43d7c29babe431cc78bbcafb0395fb5ce987a1a812122d3673cf33549cca9bc8724cc21d278ce6a77f337a2a442556d0994e8dc05a42378a6d78ca817cee6b10febe9374eb00a7381750f002dd814124faa54feb663fcf0c9aae202b5ab0842ba3d85054c65dabcf7c3155b97cbc7c334ddf60c18f8c5741342aa1753e333bf77198f7a53b8ca9253f699c8bba269215491f1294489c00bfeb31fde11aeac592b0b8991807772c2a83256793ecf73395ce45f2767062ca1962b361dff5da57a13d80a7b706f916150682c2cc499658f1bd4e080463414954164e6d6407ad0c5f87405aac595a51ac4db0856971b78625a371b667f0e4567a8070ebf8445a483cd24dc70350db4db912d0df7c6bbc43455d3f063b4868fcf92540362e976931e3168daaa165fda43dbba4076f5 +ciphertext = 3628a9f418432027d732bb8b4d468b6726db296a8739887d9aa988349fca7616f53670b15cd913dae04607d5c361e1414316d1d72291b790882b90aaf74213e1a45f333cf6efd36962589877c52a5c27a4f2f011639951e8d7e65c81b9099445e923493cdc6eaa3aae43daf6a58995bbfc49945f6e1a68f74dce4c4d42d4ff43578d296dfd016a5c35ca0f57ebb9af15903f705933a9bc7e75aaa61e12085cb7d9761673be3b63c03378146ec67c0b7a49fb4f93f14b932b64136e4fd2a45eedf72f87f698cacbc6bc38b4cf599b4772a732431d1e4ce7a90e0bb1a319dc1e6ab35489ad4ed850fadf98fe9ebd9a136e49dad728b5bd2f1384363767a107dc5919d81c15dc691e69556387d85b48bbd56fc945f710aa31ab839b3582e2c193088c34bfda2f0516b3a925ee66ce5bec2c55833820596ba72dab0140b7dde0428dd9339c38a3df34f24e45152356af9c5ddcb0bbc2cebcca208cc0c439a97ca84541e80ce51fc3ba1693e2114dc287d62198c555ef1d35fae5536e9c5ed4b8f68ca3192b4ac9c9f0cf8852a17ebb7471ba1d58c0655872d0b7decfc097a386480ef7e050772555c38a7081c4128c12674e4a3513e30d56d1d79c89a86c3a72de13373789f76d8c2c44ff6a30afc9ededd3aee2f37618259f591a6f4db413be3cc87953252e9bc0976017ed54a84122b041c286da18070398d240e54d5dad24add149cd1b127354522359408a614e601c746460039edaf9d6c306c1dbbe2e672855fbe1271833933897003603b87e49e9032248ddac4c20b2d9fadde7e932cc26a2a683d8fe76b7d5fbf8d00011a752ae64a03694083d36be19a931cce9fecc5ef766f2c6253dbad389a87d017d744494971a0fe137d97f8776458d3a51d763e073535a1ac4b20d00d5f5735e701386c4d639ea58cf1f8d89738ad59acf6020b27f0c5a1ecde46f2936d29aeea6b5c4cd66f6ec045f211c76eca4f8ddc47315d93e6fd5f3f295fe22fafff13a44dab06d50c2b6ae8e23e84224ec3500f29692be8b890142f00b1baebbd751760eb4b818f6b5c203637c3b41c40b5d88bff5b3705f2a063d5704e8beeeebe00c5258338b99f05fe136e2708a262ef9ee7449185ccec34de11a525bb6c63d75ba1204b43600951af4bbd193156edfaa5490cdcbf96432d4d67608bc86a2b0cca0806d931173ca92bcfaf3788131d465b0d669f57db5e1cd868d367d2bfce4f40b59c3972cb32382e793eaca89716355d749260c34c9c9b28ee77d21660c4fce35f64a0dd263ea2b8acfcf9f76f7835a74fd0458be86d988c9d594ad5874969192643711fd98efe336e80d0bd32a4bc8ffe7788e6f8b97dc720a7d1ead4a089c2e6ad5fd4661483a8eeacbd6214a9aedf7bc46d14a7fe6655b0da37b60f83b839b5ec42eb58d5ba37beb0db88a2067383109c75092d76b491c1ae4d1961d7820cd0d96b1c674d6b077eb3e42ff1cf511f189520fd4715f891a9236de9ef2b211e23c4c948f7adeaa662cc88c2932b1e08896a2ecc83b +expected_result = fail +expected_shared_secret = + +comment = Private key too long +private_key = 86096e25d9692c020313165513219b1314887346b1eaf46a8089aaa7c44f5ebc549c5babbdbcbaf18a6b6dd10b6a0bcd6043bbc046b271dc8304a1372487725e722ab8703af4930e6c134cd0c488d3130a7f629d9a82ccedc74dc6f21b1ecb497c40c59efaccad261220039c5512c86992cdf283abf1880526d678139582776ab48e943fda96731f0aca9ac924a62776b236440d465b8f15cdbef4298b42c502b2cc34e6afb4628b97ec976c5c7276446216b7b1508771ec8c88a8f79fdd979cc9346a049720118026ddd5339169a76107a9e0dccbfc83b49445100369cb25a26ef6898b9cd19e36dc3d8724563dcc6974623c4b9849a09a09c9a6c28593434cf602623c84cce3327b18ca5fd1bd1555219b33afee973da198b8d71256e8c6949a915e92b080a0a08774e20fb6a71c24f3c145d7467167b7c300b8eb698485b6761c9506b91625d537a900da41106c05141453e9793928300b4fdb770ec8cf292a98f2b25aaa269d9d9c576f377de0f56ff344569eb82866b25985ab49643bb8b6ea19014650efc1092d9c37f733c679a439a9314a290ba8a407aa88a34e015c08bffc8021622c261b50e1842003377f5ab2bd0f14b46c165a5c1a5d4d54b27f9a4a66a7076451671a5604e70a535c992d8326549cdb2437763387fa1c041095aa2939f6593a17f652066b55059c79d4484c0ab54f23c573bafa8107dba86008363013af3024bed4a9242c9c2c3323b01cf974b9a50279ab311aec4562dc54d1c29f812864fbea75c1d11e87b5319a64aa67252660ac608e1cac86f822e90524aa73b44ba94f6916b3db740bfd7072db938b62b21cc34bc0d367156b669134cc7e50b534d636c0a2c200849b06ab796de777669c2c97064a6abce004c48663f472485eb693989337ff15774668cc5b0b0cf318b80c73bb07576b71f88688cbc1e010b41ebb28a58a21937a54d379698bbb71b5b96a29a5a5762392d2f4266bd65bfef8cf889601f76b29c2e8abb24abdd8877e83132dd60778545c548f8a72bd13c01cf340f4d70175b275c45a583b39515fa9a0eb3b4e3560265ddc86ec127b615599009a40daa32e5879b975dbc8f9cc21f6ea907f5495fcc8bb5e4a8850d0a92ee36eed083297d4868e457ff91362ffb654e59bc5ea4868a9852fedc515d1526a4fb5c8f2aa4eb72527bb8587f828897bb7b889d328c5046ad9f0c8ae00c246580b75c874088b964a6b143dbb196a55b21a076cbc85c204753e0b495fe2a614cbeb4e6ef114feaa8356800f54f287967b1f8eb9467ae0018664ced22c12b9282f991a88e5497cad366b6686478f2c3b4ee80949706b80a428cf971248d02f41d18121a94c60b38c294358ca001cdd85757712b3535bbf77e950b186c0ae81c7205c9b02424924cc104e473cc9f3a7dae26256306f4cb2285d653ca247a750a25dcb537b589c58cafc49c5a931e2d87312c2c72cc4111ae198322a5f76588c2f2c35a7973059878e193c405a94c6f622b38790a5b0572546c3348373bb806ca1a51c3f0714640eb61a35b8b4dcca751710b68208beaef51f4248587b3a0386c0b088f838375a322534745e436262d25e5d7a1b65d88f101736df176f2fb41fbd1c273093a8004bc75544618ea1926afb6f9352154457163f4343bda3a8ca708014954d9744c9cd246e18ea0a8483a8f8e28b74ec1a243693b63260a1977dbc2bbaa7d60977832840d24d7e7750d65388290266428a8042790fc417afb101b29dc25c1490bde7d555219a8fdb9576f1d656088a962099afa02a6fa3745dd7e07e732b8bdce20e95148f110cb3374a09f4a14e730b00b313c6c723345c8420c8223953bc0b523a2c63c779b5375b8241970000ab2dd5afce0118b2269ed89a018e547d5c4182a0ab42606245d589ada6a03715f9aaff4539735b3509bb87f145258741508421ae22392ccef3c9cd62bd3068a7affb066cf8169a802b15ca19953c57c37328a4a671f7a9cadc0b7dfbc523b857be6069c51460054e23470246c902b62f049c0d0a7c60ed981bc2d1c0694c6b2ce0b60cac7745b76f6a72384ef354d9763afa75baf4f23cbfc590af7a00aef4207f98a3c6ba60ed076b2fa0584a913c82d393a7f09724fb468be664985c5f5e3aaffb950c25b8210dc1ad6d7cb04d2a7de16492d15b318c684963d19df4ca4bfc364ceb054ebf79a1c7e89c17d29b933a0fa7f10f23e2510834030dd212a755c5fbd39bc0ab9c6809b9f408574ae8965f974b6615820bc37f1a0a5c761681275a7659b688327982c1bcb604a5b89a275eee78a3544a2b58772ab351526a4a213ea6915a7c0c772aa4cf2b67f530858c139bbd66a27331686c2aae47e9872d7341cf0c5a8adb5f46023c013b82b3287cf858757c92a604c7bc9e8026b4c93eb09164471b290d5a826b25b359413e816435d29059d817221b8779aee80a8c9419e4d0756a71c819e7a58a6337eb537be7a873db0104c533ced767a9a907b4c56350b20bc676369f21135b72265b4b044311cb3ae475a8300bd08fd64bc13a6a177c4c7b936fdf0a2536498e12e01bac986d5eeaca268bcbe1d6311018479e461f998aba1642789be186b21c802b1b704e2238fc11af798a2df4f4969d8a17ad2a75c5cbcdb5f645906034b9659aa1f0b2f60a7ec5bc628a569b7bf4238ac070d5d0b78f5cc6dd1753556b70e871138b0a235fd70eb4d47a7eb941855946f7d11b0ab6176fa0b3999020a4aa8b72987167b229a0b56d76a4ad161c2e9e6a14876304da430dc7c46f1cb47345a91462a26662543e918093c4c1c1bcfaa41362b6b6d0b619a09ca3f07d20e8610bbc5a9b04c258676f4c48c5c7fc56678a7cea5914d94c294a61bde6f1584815a13cc53d874518d9d4ad90f7659ba882d87c0e2a43b71576a3401a39ae833208c309cd5ccb32d60e460211b959b8dde284ff9030e57c931db669818b6fc9c5942374bf4cd477611bab19191665bc10796603dce4b5f14038c560b6daa418002c3b233cccec62a50ef304c7a02d862743f2e3c2e2988e8ec56bf18a236540b3332837b97213449b6fbf6a9a2662ae55451d13243462da702efa934d573fae71a58d03200e477029228c25562ac61b2e348a1cb58bc3b38891134642295021f1eb85759413ea026eeaf00bbc1324b8035ce9a398f8a02ea749aac4c90849c63c02e51f7a230f41abb46f709278ea084d068379e0adc33b2ba34cca209ca282573d23d2292690e2fd19587ac7a38c8329a1f86dfa7ed01d57d200ad56efbea2e2d8352ae9d8ffb4fffcaa5d83d17180f754b921f6d45242d6d18cf367ad7cf7934dc331c91e3312a1bdd23d81647b94f09ceaf385e212241ec964c6f0890be494df30fad68bb02efd167ab7468daa8a3f2761016ce4e51ff8121050a1c1f1 +ciphertext = e23d5f4bd853f60e1a92d7333702ddcfe6b121036794cc0d534fb4029938764b26c0a32420835560d363461a7adb502f879caa79d7187f00cb59309f4dbe35a689d3d44733efc1e1c966b376da3b91b8b3a4459e25c2bd1b11eb4abbb430f3e1dcfc9958d6deb422647098babe70d6eb54d866d2a33ed0048e4f87de72cb380ce6413d912addd3808860357dc609a0884b0a60a0ea7d26886da4fcab51f0da434c11a1fefb3f4095f74a90bab962e0493e79fb231e12a7b1195cdabe204faf8f69ca6087272c9ef66cf9483df8776c6a2ebab9f21231ebe5d0e9e10e3cd38bdeb34572e2783ba08d505f55838ed636ad6f72110d71c5c4d8f4fe881cc5c23081b8e08e218db2fb30219f1b30e99f97ff147e461b9fb865e879c2a4f56cb9d9acf3b9eecaa7682f2e0c3bf04c7107396e13bddfdc8b1249201853e2e5cae07b2aa1686538ad8c1cfddab275dc3b438b737f5a57a4813cee8c58b73a178a161ea50fd10043a643d2da7f30fcf528e008d554e3d65cfab349a3d49c698ddd8ef2e68832a68848ee8de896b3d4f3431764b03181426a0f467ec56e419bccd098ac6307af5638794f89ff2a907b625dddd1151780d94331174b55d0a1780e4a50b8706b3890133aaa11a846619ae7a43134f8d7f1227a82ede5ddb0b0b40d5b2ba8363bc7c2d909062c39b65d03ac302ff04db52942e7a899eb59b4b41ecaf31847c417ab036353fa0ce8a687c009ab7730675d11f50dc4f766cb7340b714eabfa0eca8872bea8fae0ddcb268a59bbfc8d85859e23d858e151e2f46d71be11dd0c5e4f0e2732efd3b91dedc1bebca69f32b39f837ba35a2b1128742b360754e046e839869600203c8d18ab7396818b50fd8a35a27bdb40683cd1cefc3ceea7382ca98a99cbb1ef56d920a22af5cdfe0e67304ce5987af3c5ee9b16df65a87f47944ea6c801f13bf4dbea5b88d37f059fe25016478c378be62e028169a247588bd1bdb41eeac60bcce09937c2f76cd8ce2683bdfcd52c5c857a1f22d854a9fcda27df92cc52c159165a72f93929137a469a9e070b708aab8cd921c0bac6a3fd12b5d55cf728710c310c2e10870fb5c67c424ca2474fd5c6d3e0c1faab1b6505aa87a25b42b44a15780c7a06d01382a2304527771069c83261d868692a2d862a3e6c51cf77492dc0a337c9e3f1f318acb6ff3bc8af3095c8b21d9868950cf8ac811fa9e20ef2c72e2a9f82bb3b4c35abe58bf066c302c6bdcd2a207d8dd3812a7db64d8077341e7b89d994b24312754ea7a8f551e87e5f1f845e575812f783b69a8b2bc69885f2c928fb9cfa648cbaad500fcf1d5f0ecf8fef36a4dcda6a230536a612cd4dccb115120da76f441ca66ba874389250fb016d8ae7852fc8b773bda6da633919195263eea56608e32d2a46b71869b7d9a0f9be3c150095dd95538fc4fa7e6d37d813b840f72129412eab822fe40b6f2b1fb461a190bd778bbd6c7f3a25102f1caac54e8079bce316f727db9c30651715d4ab7b6e97bed9a00e3885c0847e6 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 768c4924f92e767a93da1303a3b590c536c3d9102aa65a2344db4f560946285ab82ec90ec65bc29f678aca883f5510451d6184f684159639b17f695e258170ce8b9555a794c77b77ed4b05f905285465918dfa029aabb6f438724de8774de1b5f2d339ba9527c07aa23c578d696657e889c4dafa58b68393e7e23b2934c103d4b9ed5c27c4408a099aafb2c89ba977926986134be894536885dd4a9f322359ab5a33b637483fe63462a38c730073cc730c4ed4b07fb5956eca35a5ba18b2e52af23206ea72605276540aa9559e597847cb039b7c4b5b0294581890f7f5c3df4ab92b778a02b286fca959b0720a5ad3022a2a6178d65cda5b78a1c556eed1a3a1c10d7a4bc76c862426012425fb760e1a49cf0657d8d1bd857a1fc6662ad09c51d0c47e600741e94057a9b74ae7a2b62931c5b504cfe8e4789ae68613944a6110a34ad61cb91144dc22849acb12a61091f4abb4665b3f2b947037329a0411766a39bccec82f8b941dc34bc246ba5a91273a0c346d6c5b8284e07d45d18d22f02c3c44baac404103925bc34b5b2bd22a2e762acf33919485bc5159cf0ed322920372e6c7cfc9fabe8c58bc1a8cb8d834bceacb01668705dfa963270c429416b79379affebbb60e9b3d9fc39586e52da1c6aa2a14211e74b479fbca5dc3725d7a4032d74530ca74e530a59811644a45558ff8a1b401090966acd8f69a8bcc3099b569513bafe6505f1cc014c34b78ba4a7cf8934bee69c6d1e55dd43a1700d876b3075bf0e201b3d9b932818f8292ae7f213a1a180c5490bf3b030773d55f7cfa7861d19d18a4c155f59d0ab26c17d58c5818a54b45635727bef548538bcc37734a31eaca3ada37a69ec854bc3a9ab204068ee45207143b7981ac7502c513b5c4645768ae7129552a94858c9485e3411a2125e4dcc284f1a005d2b9dc086f8226b3a43c4d38812d001944e79a664a851f8de83d54b18e9c228f98e24982743e65562a804b82dd847996427fd69060c6e0907ee3c0cf687b0f5b7c5b518fa3a30742e359ef04a710387f7374a47093c60b6c5d6592b5bca66b5e0137991c132dc1642f4abbd77669c555c1b24c70ea8256df74907de71109b9ae0590cde9fb13af869915d39e9813a3f48a900619a40010a779db8ed606100c4a05696c9ba0b14ca7a5a1595092f8238a59a944e7f85c4a138c9ec67fb9cb9ac7835ee6c0884e480e57e68b2706a48e3923ce0112724a3c04a74d67342642e79a6cd4c4110bc97e387877806cf2f71af1554851f54b01db27957602c3e1b39ac56178c2a8ace100d358a58532a1e5ea5d35b6bcf0da123f515e8bb93bf47938b40869f819c6f88a53b596b2ed0b4814b4baac5303862144df747d93c8bbd34b0be5c6ac4ac7b45fdaaff4462fc12378ea146285c27ad86b7cdfa05c883866c7e86a3396a65029809d743666154219c92525283187db6b55e58b573aca67c218206884a68433f8dc276983662602a989943cfdb03125492bbaac1d58bc6b8436a890c32da97b4cd7ea26d6a79e99917491e9b0d6fac5885cbffc1b8edfb43459ec6ec2f2a57c21bc93903c3ad668abea57462892c40715417b5c7e1bcc8bf398d47715da056ed7365f62f804281c19605ba1951195135820dd52c9b8c55ba8faca1b6b778c053f153a6e848b9e7fc5a3ac1a09ed741f5a3b258e6ccbf15c4722c13e9ad9cc67645c0c44a00c75baf6547c3bf436dc7028fb199afb43bc893268a1fcb62aa19844a33bdf58b7bef9bb33db5623827c4c02c71f428d966777fb4a3ba6e72a14c96fc4704ffb4695572ac376f36eba1721fc13c4575cccff179eddec9bc068869997a884400e75eb5911b4510edc4ecba07b75e6088416c2fa43713b7966727c5413bb5c1e0a131e517a36d93c0ec4727a0a74b2483be7214091c643d7e210af2aa8d3c9269c5bb37d29c58fec5d04050f18a75a0cdaca1427a1f0f157147060260407edaa103fb77742187fdd024e9a8526024066a9f59d829420b9809792b052e53044cc7088c25c4e868b409aa67532705daea3202b5cad41e604ce8730ce6144c16ac4b079b34a49c50ea51693506111e5cb585c889543c0f830519010bdcb8c2761ba03bc176dd816762d6a782f616d60fc071de6b6ae89b86c66313be2cb043c51edfaa6c2a698d68456614986b80527fb8a554781276a4b20d1214ec44ac651ea9a7340530b7a5208abaeab00657936c6bd522fdc497adde9b5fab93e2b887f445c6ecf67372a163a4c5c96a9ec81e2a2bda6987a12e6168578940d1253b90b6ee1669a42e85c30f860bef78d21eb8ec6393681f8bd60a559a57596a9053687500e66d14bc7470b32070f7945b6fcdba9b4040ae97640ded9162a9c096535b632c2872b299e2c0babad7710b2f4a072b1464fa3b1f59ca809b01030dc039ae80179115b45bbc839a7510ff5404356a3cfb89a67095067da82772c5e3c4ab5e9a883d31b159a02a2e739474075a15afa7230abb36264c5c3b7832399314e495ff9898736c95aed65c334f76297b093c1b96bd7e5accea83e1606bd1050946bfb91528ac0164c1b78e19aa0472b6857c00a9a163ad3c63c5851816c007c5b742b266f5b2488c860551da3c99b09327638a4c3724530c8094392a59a138221c041379cbed7bac2ac2241fe01c9483128eb4265c82657258a94bbb1147ff16f8aa25cd171107bdb2a9e1a2d2e7567b7c0c24ee67d45f1366d6b373b076ba980850706b64bb42cc7c12625a7333a42cceab621d8806b5bca125f32a67db917bc20285b15496a5291b2566ea36903183ccdc38053062957fd14c6b1db5e4e709d7e7214adda4c7da7101dbc63989bc8f547342d8286200288e3c9cf3ca6a045925d677b2e3c2a9e95767c60a92ec5332dfee53b675a3e81e2377538896544348ba27fdd5cb6fa66b9afe1422f09a398ca951275199b6b7c65002986e6032da91b55aa88a3cc31893cbfe6195abdec0fd7da413f5c340353026f9b250cd336f78cc03f15b7ea03b4ffea275fd941e0e75a9e0943d124545c6203baaa1f72326b3826be721c5fe41a682b78b24a1a4e7b2c9c1ca124fcda61a3baba97e8562c9cb55016587c1923d02143a03aaaa3d8856f9a46504777836304620b88dd726275cc32c7f571ec755b5867c421ba170bdc03f5da0be6461e4e42ba63916062011446e39fc1e35cfa7aae484acdfa0717e5d2963de42ccc97671aa4a529512b1736b79879a36c79c6b090d211a5429e4fb626c955757ee6d963d8dba9d277b72b2492252726592fa690f37ee172d3ee815fa516532544c0e32a10cdd5adaf2eacb890edb889fa11715c296d1e75806175b305dad7b7f53b991b17935881975ebdc118e5e3ed +ciphertext = d26412b70b8fa2ec65c5406ede06355f3a8fc6e0e40f2c763c7af6b8e6d4ec4fc0ec7a58ccc572f87ea8af6060e2510e714084a349ff5e1ca14d895c3f7eb2dc09180a8bbe905f9dae8c1e2fb071c511563a799d351f020bc8861da4ad8928a14db9262085cf41c13ca4a6a088f134521f1884ff5125c4c2af49208a0e785ba2a3f87ac1baf2da2e6342c719e8784e5c5543734ee3861f84e51c07e6840a4ecd02ee245a707f7091d9d7eeef38196fada17f0f08c05e7b496ff899a2444444da62b7c7ed9a98fe31cb1e89d2a31387bd7d47c8ea089b74f101d5654ebb9aa2ffc83d5871d638a59ff22c89e71f0d56eacf829c404a3d399788a46c135ef7a4a2d9e774cba3b970703a0177f4c9b60575c092fa12a4be354b1207c2ce6d2791a7438299df89704194ebec3a425100465d4c40a620079d43549f121e3bafb2eafbe2e6f40158856a925768b4f0a79bcdddd7e4462cb9451aa91fa59e1f83adb96cdeef3e79716723a7c8278f82df44234278c34eb05b79ba557bb071802db569da19cf66396b8ec39ad64c9a929f40df83e0e4dcd8ade68ed88f91463f874d345f8f91974ec4f71f72c6884d0d52dfeacc00f8dadc8463adee09f308b727a8d2d4b1b64a39316b960757b3472540bbdbb1e1d0b463db3e2a61c9850c02b8c0e1ddf4e67c7e5ce7cbe27b80148d52ed2ae5a6d3c19a397a599c5eb1c87fdb05284a2c1e9c40425a185b15aa84a26a8ac8eaea8ec70b9e4234b164f42176f98f120a7c6fa17634f17259ccfc0abac41625e672b7afe05359f90382ad8484cc5a8131ab37a249fbe349f5f40d671c12a226e8a47e7f9c2c0ca24e3980a276253cf21f4e8c36f858ba12e5b412dd1b9d1d202267aae13d1a9ae8bfcc67397e561088d42217a1400fd9bc76caca68116070947052ce3c14c9f40a5e32fd7f1500288d9b7d1e68c6fe92a0010ae57eb293d59bd7ab2e7c442a6b54afe20ad5348338b9d45648dcc832539bbd3519f3556c617fb0025c4db073999a63bd91d5862aeb70d88696a909074c7b1c49068b0c9bf775b48425e737561a2f86a522aabec1faee0d9ffbd6e32110f26d7f4b39f55c9e97828ac45664cb952a21c8e58eb09d9f4d473244cde0594afe104a3e29b0da2c989bff96c9b7873c7fafcfca6651d3d6e88bfaa37a9dcb58eae5a6046466edb3ddad66c6c13f0303f444685c4b3cbea14cf9c2c6fc938ec19cbaf22db7aadffe45c843709c58eb468fc53ab2dc2db8532b10ed920add3b1e06ba646bfceed0bc1ae1003d18c34b1a52900ee212c0a1d373568a0fbe153babca71b5a155565fe62c89ac1cfbbf26eba0a696e5ea5ce1a1666ef2fdf347b5b400d832e3b21ba3bd39f1cf3cbb307323f0a267a760bf3d2f6c772772acb3a84c068707a9cba3942bc58ba894003d0c627535bf0ff67f2d0fb857ccc723f1d71b649171969a207b2798c25d8e967cc4bb9cf9b416b293b53a6c6472f32bd53210c1a2e15e24261f1242d0ddf10d73195afce2a0c8cf0dc6b7830d09 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 0da53a32261366053f86d8cc77574b09d8ce400160f38c0465aa2bda61b362bc91dacbaacf8014913076bbc84e53eb3743e81586b3afefe66425172911cb371fe49660444ab3b750013a3af19818c7cc2f02c07c03f713e6d6c646981377d6376c4643859c95bc895fb28878b6c4712eb2299ea7543db278899458a4b6968487339dcc5d59c37c4271018504cd43c48ae26a3ea77aa23380cfe69037d64168c3356d0ec48780d3146df3b9de2019e0f1c796088c450c5129946f96795a1992988a410a2394265a95331692511df6cd2a9064ec527e1cc73e0cf78041bc267310381f66613b30141d6420b0c48207b893fe44bca3f3342cc232805971bb39822cec278d26638457550e47921b191a2b64914373c7db595aa381b9952c3476055c85c010c8fc87ee3bbaae77055e9232ff59c61f63ae2d7053c2f531c6a96395c1b7bd53b1c6e217746aafd80c2a5bb55f163cb23089111585c5cff4cd0a4abe52ca1ca1f9c759142053f97e0e396528d06427f95609f95859e3a0b5b092a1aa0c09ab2c755700d0205821dc22ff695b2b851b18f8a69ba842580a1e811239c40bc3ed50cb0be4c277d35e876402a36a35e6d21252209cee5cbd7fd5465e3a78bf686c3ecc784d8b2452c331e2d56afea4b581f97141c9a019a34698518f9d0c238193035e258a9b941d8da2b7f17a8be077745cab3a06361908320b2295acab767cdee951f628b825108380f3b0ce671fe0e697395b6f608a4c22601293a8237fcc6d043216a33a76086a5f1b37c6f57152ccbc0c61541b8dd85745a57450a7772403a245b41d9dba837559210016b2c8712f6b675411223aad634ddb5c4026d73a7f0bb330979624da6431580f08f098b00b8150173da96a2e4b189051466065d6be5ba83f60f90cba95c24eaa16191b7590920501fc39b180499a1c54d0b785bd541b60217bae6b8c7a1409eb4a10b8f5593374591947a1351a6ae30102594819d81939ecb704b8eb1f439752e9612727a78945776b335777dc2632419528873739fb9233c8e481dfe74c260b612784b35a79c929d8a1c126cb5fd1bc56fb34d21542bb01b9beac23710b8da821283b6a5d97130f7c855a34346f474466352ba30ca1050b839b637b0ac06564a9258ef45597e235247218c71d3c1ebd17158e1c16830453312563ac381a518712d7c94b3af8c363025346d4a6c0e3bd8a7c0ad25945b49c4d52a95b75f93964a20b802b876e948dd2d2b489109fdd510b4cb60b39943e2da49b94339a8848243205bde7e9b289416b2327940a483d1d80bafe56776b9394cc0bbea8acb57b07cc775712cc7949a3017f2061c4d4a58eb3b575c706d0d6fc932ca782355bc4b678744ca4b034c79b20c0743e2681ece12f11c28a67208de89071eb70322d6073e00c8dfe17898217cc833410e9e54d0f3614cd3871f0b2142c888f6274618cb4402668925c9c671e599d7061372a119f936743515a490bba1ad3b8cfa8f68c281c33933c91d9427426a8875a695cc3b8905d41b4336380c7c60c6eeba4586c2d7ca099d2c03c9dd18074861e58d1bf9858940cbb3a54113003e84868386c474472857b14e13cce9d0a0350d38c76d395b6ec7410a58af7066be1f59d096352d9b42aa5817a70c7685f90522b487458f48140854809531a4d137bd48a349f970346d34e5bf99ff8b681896baf9a52769b3362d2b8b5b5b3a7040683f8abaf49e20f14d6520ab739b785750467a48984a83895716bc9cba3035d1f92792d4bb8d0974e2dc35080f75fe0d4b388377063839452b450c28607bca64bcd465e3f81a9db87ceb48c0a113979965327b7e47d7f58a396997d8f860d061b34abc945df65a3cdb516a420b110e05c88550a8fb835d824c3487450cd87ab34c645b9e86814090ca71780296a6a75853448892fe11921f7873299e30c4026264cac7381b363c2fccbfa880eef16a9a617131ab8c5d9684adf123eabeaae6480a3f6f15f9ca146055607daa8aeb22c6e371484acd8c4e097b87ba0c391470f37e34782784f0d03a276c8aab23b20cbbb08d976491937a18001a2c02b5aba15920d810024e40bc74861fce8a8abe5202cfc7e50ba54bac3508984585043beca169e389632a08b6e13ec102f351df808b45a2abb13c8c03547b031814b2ff227e4d1b9b2547d33d63f30a5c19ac69b91d6947c7a941f5c005dd5a00e6cb8e3c82eacf19364aa8c82428c9f945d727b77b790a2742805b28855eccc04c88868b6482f3df00376f7b1764779dbc125d1e33d90e55e7ad96d6d8aa929204ccc5cae1654a8adfb3775bcb3dfc69ef65c490f3ba39007cf9d54cd9471bcce64b3ea82a049777adf80a55736bacaa3bf7f9447d14318dad705bf3314cd5bcb4cd219436b6844a00132e768d4b9a1bf62a04e638d6474cc38b1a5b3f5a0455171c6d2b040cabb77d4bb917cc252452d754a16d67baa98a1c7e061c99ddb9c5b02a05cf0609863ce493aa193e1a889f91a686309bb5497c837aaf1b70a94d2bc72034a8ce551ff79844c195ab1993218e1a8cdfb94b37ba31783b4459269ce428481548cdec3aab87490a966ce5cda8f29c4aeed19243811672b6561ab2a468da474b5b3798dcb27fbf1935e13644c13c9d7d74092bc2f8831c17270ab1d65c07887bda31798762183be47b9b8723b61d2a10e102befa95b8ffc4e2617705c3cb142941f7c9a056c6c083567b63b6491973767578c290851ce7f5097deba06f8b0cb3bcb64bb58c06ee44d004da22e1cbaa2bab52fa2a074e946f7b33e51a77efe61a59618b751557adc272cbc1745a28b52764769147b0b0ed98e3f9168a4f1808d982d882833a86b2d3b547fbb1257b821967be90ff8575c540a0d0c05017e0253c39778717395f4930400e4a77cf79bb29b8b8e757b51db691e3c18e1ec6944a2b9c8c215fa18c1a8e63a5f7baa91b33e50668a82cc5761442a931c88eb27342fe7883f25bd65872749a8a446822cfbb9486cd7207e6346a38988f5b4919416b340b68bd769569d457d179b415b1c0d783c5924d7ac8a348948986de7db0b704753c863b444d427704b71dc9279ecc777c688231d156b08a4789ff955c9274d1e85b62e8720cee5168ef4b240e96e23849435fb54683a46399a9b135599d538aa3a2574c5f16ee52ba8370770a842af768015ac6721572225969708837b25bf8b5beca314768b3c27f5941d085273117e8eb33d6a724e0091120efbb792125f69e5b9d049fca6706fbf51c21e1a07648362c3449256fb6166525f618b1fe2947f68fedf2263d5190e690e3713de4e6872423118f7e1fe7b900d9fc1fb827dace101ea2d0942f26e76e7d157d298cb773b82180423c86a3216f3cb1a08 +ciphertext = c3d01d72b9136931f0e433c82135eeceea1390aae3754f0eaa9d2cd01b964f249455c35b68352ba8a8917130d4ea7950ccdab52d8dcb1abe85227ab2a38a0e92a727c3404f564d186b98c306cc49a55ed879d1a7c276b5f2314d773ed4ada7cc6cc0d4c69a634a7098bb3a25bf6d1fe7d24766d3f4495ecd4e8b1f1a33bc71763a1669ef19642b9da176090c308b1007b54d1d772ce662ea465dc1da2ce3a912dc4f3ce7f2758163558b8f641e2974dbc9da4ac4d7eba4c4385c79aec715257921350765b15888c543bfcbf64f0756edd8d3a1b92644619a2967e3b66a052026571a2bb8cdaaffc11acf00db84772e546f0a41e3730fbd96952927daee58925a60a918adf9fd3572d5b7bbd3a6f45b8e733115a98de544d70752ac8404a4dcb3e872d92ba37f26f679ffe555e8120e3af2f510b5659de059f9ad2fdbcda1628ec875b64cbf3345c2299b3cbd5fd245b7665d1f79100396d34bd8c0e8658a7e62e9f050a3fd37ff025db20b57c86a80d754e21b4727c586456eba0bc9f1caf139488ed622e2051b91f6f4334c24420b3120e2dbcdc1ffc2a0acb26bca43b857e84b2e3336887b0e4e741776adfafbb39a68a799e826568f2af97bed6d1cbc6772e2f05b8722f8a1e75e551779e362496356a50a278b71c537be253f04daa125c0070fe6d8a4f169e83552d5fb665e202239b2b8286647cd7083a8f9ee17dacad5dadc5359082e709d2bf9bc5a7518d75be8fe82b9135f55ea8374ce61b0474665988a864efda286468d8e9091b27862777655905a4a63b9c0dec4a97ce337a46012f21fd717f311a641b2a396efd69516bc726b775f9960616e72223997bc6003605f19b286b2e58e19776991c259f059dee1750410f8fcab13202d75759c5b6ea83844f97fdea11a33c2c6ed72b725f1f5211ba36d90c83c70567120e3877c830946129ca3d9393fdf3ca180aee76edafe15d9e8317bf1d7842d987dc5817e8019ebccd4553c3fc46af6f9f3fba01d3868359a5bf7d0f324a9f3b3c0a31a4e64e2df07ad82787bcb3a4d5d4c0b7f756cb15baf2b5e85b9419f03f7fdbcb5aaae196b02b2afa30c1a19b26a7ffc6516b64200ae123f0dc49eec9443e91b152fec3b14fcdf99ed5a7e7ca44e4e1df33ca413bf1c3d32866544b4bd50b616f004d6aee6473df2243170cd0534b378f90861807d88c2bf4e76634ac0ef2fc8a85f36e5a41504d45919e61c130f26c843045474a1311120f35153788fd148162b8f7fdc0f61bfdf9cedfb7e04a58cbcfbe6553b753056cc69816d28cab64fa80d94c42fbc696735be179a093d31a0f2e3774e3d6f22eb684da502c7f4c6632d2926871a4279ded7645c9375a5544fd22438af7a240003bac51bd077492ffc60e1f4ca921fde3ca24f660ee62b20289a5bd08b7c11e22e315f050c796aecd944300375ab4025596891a394f4ec417648f7dad95f7dfdd1c3903b54ac1a5a3c05cb2429bc258ff202d08e332ae37232cafbea27492588923f3ca955484b19333a91fc0b6fa252d161c03e82 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 396062657c2f614485798a999461a087318815dc39e4c28600764485a7a613f16e02630e565783bb1b0e5cf42aabd96e670cced6cc8faeda04c4290987caa237819b0f61583a576e621b81acd649bf7a27427726cda8b1b6416336ba69fefc7ff1020f2a30248a6718263a56cc9a82fcc8c415e94132387761b3373fc8c98d55a1b9870214766ebba3ccba36513c277b327a95af84115f7a34ff286c75d33fbcec9e3b4a2ee99ca4e1f168ea538b99700cb008ca16b331b73334fcaaa391e092f69133e18a6931129012937e9dc85fa398758f515ceed04520e6bf5a437c545694f6a059dd5c347584c448f09bfba9939504007d697d3a10667dd1834c4ab23800c36d4769e98198cbd8368df14edd62c98ca73ad1d8682810bb5ef48811310c0fa901b1b186cb073dc3b71794f21d4cda0153827f47eac68846a5a90b8eafd9069a4113f73c06426132b6628518310e2f676a72187d36d3c4d4ca7cc9c24b5caa3bdb5198c2f330c4e799b271918ae7a950c996934a224725236c1905b5f8acc6fbce87078d5cbc1b98c4c2b7c7b958d85c58bc1e11b9322b1807f149c39a88ae49430687a8a83510b029f6c741301d7be03d4c7249c9413b0f3745b712449e121ed0e530e591c66c0734f2cca732f1c6e7fc41b4b9a2109924b69a21de2a46dd5bba19f704da213a0aa4979b7c1ba5dcbcff1104384cc94284a05abc544742b9190326f4911359441e153c0e0de87e086746d2abae6e673de3ab30ba931501f969c185cf87934ddd3729384cb3bc656badb6a38b1c933fa77bc1123097316a6c6867d9b79e042522fd46704a90a0355297a5d3114f85bec2f129e5010107192132e6a19124c04f9c924a38970d12c86c75abddf4184dc85a4491ca6a93932354084b3a7ffba64d89f02e5d875f868bcb6665c6e3098615b775ef8406ab411503e1041811152a157729e79295654e03a6011b0a430c9a78cb1930c3e13d6f2782a8fbc4aa8a3872a02d23ac0237d44536084b6e6683a36a242cb5093c649d7accb8de524aeb36a3807b2ba4f10ce3e768bb1b09488507d6640da4b9a9c2538bcf901309a284691b4b6c530afe246a2ca1577fb73c06b000061540a427a11fb181cd87c922638a3de121432825b64b3a82535b728509d389894862174b7a640054359764bdc6417e005a41d5578485178b29f14114d088fcc821aa5370761341e27c4b5bc69f678bc89ad3981e703142fcb362e390b431c56b212025c63e30eb9ea3298014fc05cc989f6d19bd5ba84404e74ecf298787089c33e5af6f7c0fe1ba67fe036166a46df1a6b96c707b302b6a1f0231093142cf413601524064e93dc9f8792358b8ff8cba4535acfca461c57a0c503633e205cf9183bee9c24318647b35054bec2995f14cce0e972893fb60e5b670c3025679bb0113daa3670482ff067227f875dd7b43c33111fd2655f16373e821a28926877c13a71c447ff8b1bf532815f5aa9e1500a1915112ef782561311b213c0674a8cb26604b0ab823ef8c0652b1451a76bb31017557eb74110b08a5953c1d5572a6a29e5cb364670c8d50a2bc681c1d93310036e91fc485bbe9d3171cf325942680b2b988adfa9889f42aae452ccc0cbd5da6ce1c9512470a9246d29b4dc17a0f54620618b69468b4f8207373e7b3962907f4d363d093cb00047ec45ba2738142ea941ce28c4b5aec248b03a4513a384cacceea78856c0424f9226fc823b474e7ca2c1b5238dbc8bab072edea1eccc35171129632e61744bc827110b59d5929edd24bcca70531b8008296385e61c397f80ec7571206fc331bf41432560e91a85a30ea9ae719c63727608d090716b75e8e061d5df7bcc79b85ae23069182425b850443b77630f7736fc580b638a28e77489ac9326b2817887202069b62a4b33971639c022437cd574c33449ce483440fa175b4b0398e3852883c2321f8b72a794870665af9001a65fcc85a6a62ba681a7e908c9e23788b127268ab30a8622cb1b957d00b3def16b998b5939e60b89da931a6331c3c4344d3726ae96a1fbd3948b2683842ec4b2fa86cd3e881a76093e6e26dd6701b05469ce6f6998dc9b7cd44a2b550086102128b824a58ca185e8a7b20ba280d492d705ab2a3b51447766d4d096a7b958d9850091aa6b8ba7c658ad8925e5031f3534d1cc33da511283c611474a4c537d98fa64532ed83ce95da5df3e667b6b49ef2656fa633ab7d702523a3abc176b380801c02e6811279ab16816e3d3333e209be2f69cf09aaab7f4287797c658bf19f33663bc70c51f4c0b97ef342103300d74082b41417a1a589c1d52598c2c6a4565ce8c1549578c062cb4c36b2858da247ec54943f7aa78e06bbb2b8157d36bb594278f59ba0fe4c37a94632e875443b52265007067611736e5224c8bc05b5380e0ea563bf58093dabbccc6a2c5f7949e19584f4ab69d944ac04ecb8dbd2763b06cd3ba6bab8443a9700367f879e57d3945bb96de53b3493594ef241304bea46914228608962a3a7550c9b6c204153811b4212413b92f2b457b923b8e97913e2195e9144de0acf18675e26d0bb9af67f0daa6a35c0a1ec4b61b5a96c2bab2f6e766e65f459f1dacfa7c3623c68afd192c8183b1847e24523947ce0b2700dca4c64b8692c5c1918db148c4cc2eb982548c47a57c609e03792a21b943f59856b5266e7a56953d4c8fc12c8102491497696206b03df38c46001cc51e65fcf607541e866d823010e6b88310cba6f73c8f1a77b06b426da30c9c54c044c516383e8064d01735736a05af479133786f0e18fa811c2f110048b42048ab0639db1ad0251a2f43acb85ac969df35b81849303acc73650c79d6a1e38a15c82b3621f94abdcc9427c0bb68ec7346e32b555f00666342e0a40ba6f92334e47be4b0374fbb291eba2ab1d3563eca69e861911180c129c09a33f52426b66c0fee28a89042131178bec9129dfd3c501c9666f07cde930a824814df0f2bbd1e20680c3a200dd3af95c7a7bf0b5efe2782aa7c52f52b6c2e8694ca75bbed49fb862af3da545a2d11236b174ef9c0c60e43e66f2a63b89246e3ac77df3197a8c18ef0518bd5c68debbcb3f60ac7b0355e34398e7bb8a937878928b54efd87572446d6436c1062a28e8d63eeba97ff3db397caa04e14bbf29711416a653b47b36e93ba0141a16d067b47095a563f43195fc76762281d4aa69842638d29360468b6166b39ec8a6950b2a40afdc4ab6a0c7f204726ce9485b6d414d3ec7fc6398a3bc69b8e7f4b09172c4034422e3afdf5300b056881a95863c380295ca52272524855dac027a7b41305ea5495c893be29fc8b9408bc1bb2d8621eefd59024e39ef59d8f2205cae5dccf97278a5554d20ec +ciphertext = a279c395dfcb8d910e951a91a9dfdff472cd34be78ad4ab0101308ffa2a753453c367c2ed4845a559f250134d2c766550e8bfa21c34dd0964a42b6e4935f8067b6d64fe210ec68a4d8941ba1a3f233e6bd0cf351442087a5e8e941690002929b3910285a3e151b1f6a86e24f8227137161559fe4e6bfa0a3ed5cdd10ae029a36ad58536d6727226a87d9a031d5cafde5873d05385a630eca3004feb186af512867ad5499a8a91056f8dfeacc5adf2b9ee6efe6f9b451295055c425c6ef26bb32104c94ec8cf23155b5638070beec7591952ffafc4c9cc788a4552fb778eee575bceaf75039427cd6474e236a545c9a154ec0f6ead33f549323d6ba8d8bba3aca50e43891278aef2d5deeb045db59f7aa059b1c59fe865f9835b5e384881b3dac5ff85549697b2bab82fc4526608c9e10a830c8d1cb69ceac7ae73f59875014776082923707477d8a4efc386537acf95e9848d0aa70d5277cfb7da5352d842dae00763435b3b68efbca62280f58ff0a382f8e7ae620b28601af1b8187c2494f2c499f74801f8c96b98b276dfec3d1d6b575b84569e5181cf3a1c2d566c743b9ba2f9521ce75a81a8e2acd6fd02aeda8a3b4ede85905756feb56f9d25db711b9b3102885d702ce570dfd80d5f295d8d0811930d7d39a670a02b9dc5f294484d3c036500674c9c851785e82ae7a37942e0f03942ae295c0df3dd2614acee412206bfdabb7689e92a73d938189975501f12608c231aeb33ee32d945c4c3563ee52df75a9e4b9806ff5737812ca218e815a01f3eb4a9be59f8afe9ca3f9629f0d63e0507092a3b9aaa719c082b3d774cbaf3994b9b280a53208763f46ac49a848a5845a3b94eed21dcf9b9273915d575d3c448c43e442453c3be0cc863b81e650f0cd22e43aeb3646032f8578d1725e1565a8fce269bd6167f1e8a68678ffe990006e9c7f1cf4fa262c50418dd1cb2bbcdc9c2a40181ee45ab3b26a59beedf9db19123c002eac8386a60e8da44c1acecba15e3b471d54725a5f54b1ea27b82fd1865b47ecbf096e281e4789044e591285f90d364a70bb2ef07713b97968b23c7ac3a47c1ec35e99cbbb22dc5336fedf157f9d4b1286b21db7921ec98dd6326e52abf06991a99bf1fa0c3346d89118af306df503d78e139197058b0fed0f039c5215ffbc1b908c2629634934a6e25241ee86eac100b9575291d8d4e99052d580d6158bc2c5bb0bbdb2110be20a79dab008768f2e005b60f55432fee57407e219a303d9b93e08f3f5c4354a889e8c611cc578325d8fbb0d5e1c6e0fc4050373f1534f41e4cd4d1b881ef6c2d46ba5ee9b0c85905e1ed79b81ebf6c5e7498fa09eeccfdd87fb769a315d5d4a2d135875213ff93b23bb013a81bab2056129501f46b52716fe715a4e3f374392365c0bc958f59490c59e3cb93600a959368244d929408267e0702020302d69646754ff16ba20d6c292f6db8b76b76b0ec246812ffe14a0c2c0c1ba6343a5f7e7b40e3c448923326ef3e2a0e57fb1ba452b1de7cee0def7579b3b427b35b8f0803399fe1bc78a5349114f5f181bb9c5b82ae0d5c8 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 5b8b4eef29cf4ae937401c2bc054569ca35d7fe3affc4511b15a44cd30b1153054716abc66d93c483c540001ced3527cf9376dafe5cded598343d356df06461c2a2292ec54d046b68b844d4bdc2378b90aa8e2266683534c69b0287ccd24f687829c68d85b733bb343d0998b6da074fd523c9751700731aefe164f592849f4f74716221f7c364db8a3b7dd17c25e5a316bec26387ba15de11accfa75e4415dad701193242f71e69b67437a9d908a67c2652018b929684ad724cff8d8a066b1c5b8ac1164a5cf03e1ad91d87f5b053e3c413d9d55382270103df65c7e6c706daa8e05381fe16c9f48044ec5ba8bfb883c4e790692bccbc4554d55fc6d0bf15710b12cc60791be7cc132e2bc49100070668a6b2721ba018ba82174718a0a1459cc39db3a5034881f1ba2e226a87d333308e7a8d9a3290ce9978271b8821a34aa392d392553ad9c08fc4023e5cb78fc6018662419edccb51ca6c8b4b35090b9cc49bac28948ae3dfc6a656a525eba2656f386c9ca62bab9bada82b09b3521ba57a519832ebac38bb7d430e0a00dda460f3f7529f6d4b0caa01c322552f5fa142eaa97fad6a14d817fe149590334ae27f33e7cb267458bba08c84e58c37f145c1ee3ea37d09621963bc9ebfc7a8f6a4968342e7cb98be6346c75594fd154cdc7133f9d5a993099924dfc6a69e621353939c029a2548023e4454b44f3831b32174148a81b6777fd475c8a42529efa2797a18b45425f4f7bb8e96a163af164970bd0cce692deb719a0f41b5ce92bbe0571f439c95ef92f159b7a41b273ced49a3807b9e6072f07a76020070980016d6c2119cdb90203103c09018e937239ce4208fa054137b163c08b3b3882bc440185299c55f5878a3b727f8dea1fddf65e6fc978739b873f32552cbb41e0dc1297345ff3d691767b4af46675b6241d53d1aa4060c843d5c900c02eec1b81bbf21dc2925d85155ca46771eda16ec30464f3739da7d6580b27720b53b8a1495416c5cf3b96a223c3c1eb464ace401a1f6649f1d3b93f76c58040071d301d80b264fba64f09b49bb5da656111aebe99629e95104ac81454e5ce526c2130c842e231748ff277945a43c8a195364813f192547976b761a00d46db4ae453beafea64c2d44c946322d868abc1a11875421b7032c355a44f78d9090e86ca2f89465641a3ca23b8b1d5a0e209b20ab6152cf328497172405b8be302ac1e8a707329a0a62561568660991b84da6b330c5043992cbb19f85bacf28e3434bbd27029f48c18253711fe818caf43b1b5e202e3c54a4c5461f8ec4934fb86499453842387d9c52fe0506c95d36c62d0b9c059acee627087335a5688a775249581f523978c0ff6f567e3496df5609beb838f841439428ccd00621f3c099579c109188a972ef9715fe173929a3cb0db243a105b80861dae2c81057c183c6aa14ed20fe2315b88424fec8c47cc2155ca4ba6d57929f7c91ee55203e5355380baa4ceb20967627a3ad11448660a00040c402068bd6099bf057068621db145c6012793cc97af462568169bb96f6c21ac6b774f910591287d61d93029e4b446437d7e7579e8f0b7932ace43f8a1a3cb50af571d8e89a8c5790451e0b3ec5b0c17bbc3c1463b96a112a3f66846692be36c91656a7229962348e55b36a75d2b408583a291a7356907dbc332a6ccb18a0e5ac53b57caaa09357da4a82da7e88f3af5786de8543c889d86051f8517a6116a09a87bc1c8cccc25c1cbd6ac220cb026797c6c4845754d37c2c8f847b1728846b56357fb8abc179dc49019b8c5ba3703240196c344f3832a293341053d966958b987776705caabbbb2a7ac9445844a22450b8fa1295436b6a035081ab8019e05176037c7eca5a0d6b6382f678716578c0200009b82b988ba861d506419a5b790e69a63d6c4bcfc7e41d25593559475fb9050402aed9c67cd272963c31810e3a360801e98e2a20443171e1b4949b835bd572cad6763a501c7c7868d9da5a4e976bb3db872cc9142b1c800a6893c8514611db63b31db80f86bb6f062cf142195f2d6b4d77ba4d7e1b7d9273761e6b8f21a08ee65a4ac46c15725a778a85b8f1012603c470d86bf1baac93d5a0546f8b5a922c0d3a96592367c3b909aed10cfaefb1fa17bc4f336751bfb736da43cbdb70e83545cef6455f779757b3c6ebaf009bb8873496bc66e8b02b22687debba355826868e408b40ab075b11a7cf7b575652093405fc31263b4471c83f1b1c2881b5d7857d18285df0102f5b8bef0ca5870ba031f30c3cb0cb45671b5dd99416e64011bb8b86fd63ad8b2b33a4848ff7a13c8e83e5546af0ac543a1c72a71289ea214a7669227e777c44069293f77133ee2bb0086b4a042786ab6908b6c3b5f9b88087293e39a7dd3640d4307bf7b74b61b6b29a7411ab7c085c88570b826b4a4d16379727cccc93e0e340e888235a4881479f8c075aa61e5c029e57915946433c1500576d165625c7367d0bfb7515538b233b13c7fdb46501ff816f64cb8f60717b748c74da5b49d899c263c7e1ce66cbfb3bb503cc504f3968cc4ccfa11893a3855a784a3dfe4b8b2ebba7a2c90b5e256b6f68d63015da94a41f155c9891c5573cb156406b16cf5abdb89c3a2ec6c73a13bbbcc513f02952a122138d94fa71685e48a2364022238508643b940d194978b09cf803913252845d6347e3a41aa9a09787e2a63ab03bdbc5baafe395785e73cd02807c27072b040c9f98353cfd25a9f7017be5550980a851dd48a8df43558d128d63bc4c857b8a87b4af5418710dc97f8156cac845abb5848abb0c97721c3864769bf15407779526687659e51236bc6754dc47c65fb1a074110c27495422739460b37f032905a4a7b5150bfe763c90e6c45b6e676dcea1e4f967544ca8304561317b3a56f981f4e96ceac10a3cef7ba776b3b304603285b51ad99a8d19bc010ecc7a1e7023d3ab457a89613e67530e4283b99569a8c65b9e10bc658658d16a3761643da15355eb5275000bb194c5e8b7b56d590a07604b1154155b9c7cf91b02ebcf98a140548e5f30b0e6459722c92bdf6aac69b4e1d79b28459cdaf28c4f32c08abf65375022aa9785f0d2001f3f41bcef92fa53703c1d336afa6a4e08c6c5e4040e5b259ea2b2042931f21816c2f94c63eb56eb305997eaa9a64489f31469515245885da45c4e59be59b9595da1923a07c50fa5646498c3e83bc33f947b215284e379f0635aa9f6593d736ca6a5b557d1fb9ed5c92354592c5d8c7b79f79628f71cca5878fe85f8019af297ce20b8b5189f94d77870cb993b83ca06f086bca451cbb10522a6a408dcdcce1d58309b516020d14307fdbfe089e2b4a70e29c575cbea1f8b097a37c2e7773b9d26bec16 +ciphertext = 70aa7de3a6af636fc8d75f06e558513d2432ffff1cd3b36bd5f145d19a505298a1264ac50023f26e3b0e5abcbde666ff72bda7ce2d228d6d6a37b7288d908840e12fe9d031a50a6c8a4c599225e8d297e9b80a391d5d8291f27a5e0dfcb1ede346defcad2d1029a464e19cdc90df6457d2d3bdf89fe0cb9d3a98f2b7f538c3f5b109cb1f389c6762a5f269ba512cafef19205a57a7b49d8d9733de9bb6be7df1c60a85fc44fcdda04ff090172cf8a669195b166d79d53e525123f37d97242fbb6e2b4febd83932631380a346e9dab98d0623da9898d7ba40d246b3bdb06d094f2a57ba96788c056a2ff05389aafd6433b683f5783c514d69ecbe90f54ef028f74f71ef8e1ecf7603d83b07d09af48134ffcb7f49ab65fb361b8b76ca47104074f169cd411d4bc5085f4cc2337a4066c1e5444e25149ca0c69bc7665edd96d261ba007f888828407463424988a3e5b078987686c3300f5190e1163994ce6d46118756cf6b25d9a0affc4db48b6ec7691fcb5bc57fa9f15a027440e4a3522e1f84960f12289a093700f67d3264dfd044ef4cd6e2dd490514a93c8dbe6f1d31f2c27dd4dc00e3285918d2a9fc330b041137fcb7097f68e53138b81201632b635d605aa3392c5cd25911193fffcb82cf4903c836082ca296bf7b2ccdc23c0c07514f4e348f221703de44f67e05e9de412b649ee77ed7c276f4458789b445016b14cca29574f69ec80b0e096caaf30f0e6cd0c51863abc9a32cbf2c42f83d9e6aa0f853f67d152003bca937114390042e01e07c5bb03085de193eb8b0d0c3b1730affbeb1cd562f42cff225713bcdc51bb9aee3c32cb99f16afdb4f0037748c26c0db49ea3c21c6f45d076d3e26ec12d56677d07957d4af1b5f7fc0d274e654e1d049106e6b7d396cd8a925ab11f80540f6c3b2d9bd17a95d05efc0658ea1a4a8267f7995b5dcf20d198a26f4b5cc513ca973cea135737639f0fb2cb0f08e7639306db843123f2d49d85a149301d2eda9cfbaf7dbc3b6bb49ff9c4f0c4dcd773d51da6997a58fc4c10877c171b26a37868e70fcf106a8cdbc6a9bede34b5f9e55db945090bcd111ac7e970fca318ee6411e5d3e8d78912f5cbc36fd010859da78441446a971b68f05e2b902dbf25c31593e4b31dcbd6c4071b6b6ed08f6872e072fd87ce10dc64bbe8fdf3d6663407693c59d9139e1d0996cf6f6121a9f5d6c0bffa4c463cb0701128bb8bbd21796ff4a40398c95d4102a5581f69286c13465a428b7759e98e6659d81652b4e6e2cbb12bbca08405efc0d1d4dd489fe233f7579716af2a5b757ceb5920ae1cbf4fd87b8b68cfc2115e95d9a271ddb76fe4beb5b024f9652ff3cd93ec1964dcb76f419076bed0cd707f926ac62826993fe094253b2b23619a4ba8cb8fbbe2a0f84ad573ee966f676fdbe2884585e86563d39de333e4a6dc1729f67bfb3fa91374a5f76aaa8f47c44b27dee8cf7e79ed670a1ac75ce89540e59ccc000a5baf284aa99218faebd740f21635aa8b51e25b8962eb06b34ee5cb533f7169afd07e690f2 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 18e1cd995314a5754ff31a266144451a733126f38d439aae50db4cfce28099b37ac8e6be91e355965482b7b134d9215912d22327f4b28ee649cefb4e9dcbb1f53c5a57f8a49e8c430574bbc9b71cce63baff401c93541263dba3c3a3a30d72bc869253e751b829b0b02d02ac2eea87e9f62185024eac7515e43c4170f1410e90a1b7d36871cbabb7f0c7a67a20ffb5a7dc44bfa9289a00031ec16790b9e5596f7352b3c98592495715d03426ab6e4da38ba0d018590a1d97048a29304e28d2230b1924e1f05f85c62e50f20b5439a03ecb2e39528cc2270145433c768c84b6d132f3e91bb4a82994339279519fa24a82cc6267a95454e4452fe464c82b025ce4f2106205bd248572c8e35bf89bcdbb84154743b669d996b2362d80949b63a507829c81dcc3600a0c9fcd6b5f7d865577bc2203472f31fba96b143e63fb966f396aab7970f80852b57578c0e1ceaf4ca608466c72662ea1f6c9a9757db3e83fbf11cdc31245998a8056c0b4b1e8748bbb9171c54665b5803a1a837d468b6846b779638d56696525559d46189868011f3fe875bde64432bbc27357247912338ec305bca034c039a8d5965b6173a464d9c373e50378193ab2e95e15d43ca559557c5123da91413bf99fa6d15c20ba4ac16297b250970eea15ff75cf12178d7eb848fa77acdc610ee0c390d881b859cba9f08c648b34a50fb396bb32680cf347f136baba03a3643c9588faa254f4ae1064a46dd5bf7ae1b3482649e6603f35f0b4a00b6e02d91f41a56fd7db7ae03b14ae8341ada2903ae2cd65560d53874aba635e35c83a35e48ddf6730f6b576f6b36bc73aa92a65350f06722181a5cd49ca79307188b8c649a0bd786320beb372b027726cbcb7e1b1bc28e520ce9bbb2829b765781f0519b234bc538d867cf7f7574538b3f9d6234419316637baed3920e5719c0e3471c405246db9ad6c13133eec34c7c2a6e8802f3da43f5ada73c91830d29baec491c31eb12a57c02061d4850b0c4b0ca62f50864b480b10b89345725a803fb34ab285a564e4abe6366c656a63419792652296ac6644afd5001ee98d6b2498b04c8a67f73d816441eb2a1f0e89bd4e0bbaaaf6075fd69d43f7ba74a6a9c89a96f924be0f41733b6a718c632b1574bbf90a50fce6c308a969f5d394bdac6c2a6a0c194583034b01a3c520d6b3583feb97a5fbb1955c9c164067a2e7599f0456307bc4e51567247676878ab11e41204b3988482b46166ca482089c58a31063c99c69e63298691045086296742fc2975c0c4972dfc88dff26623fd3abfe255ab8e17f85ec738384a633197d409bb327c1826771b08356c5c00ab2aa727783453bec9b3d49180ae3c89ad4833c26a65ddba077c07a4e5a11473cc078de81208863cb0ab89af1105d1a270547a48233156143c68e7172508bf74fbe1c745c785872a24742b3099c890b72e070ab6423c96257dffaca56d20a0da43fc0255dcef4b14b4878c937578b5250a6c15dbe9b54d8416c0bf023993b375c6050405818544b1b88fb8ee0c3bde2d472e3fc5a75f945317b0659d02e3a4a45f93984f4059bb75aa448a92511034e50336621634fcfb420fd4605b99324aa864039da87bda7c2952c0388f3162576673b765c40a9727b41ba985663f0c5a4d0d50c2c617ed30baeb89c82fde091763bae601b00c1b9070969c62c591857a3841245ccd7e3a4944446c3fa38e5b7c62ec42df13a0604f00802d74375354162a583d31147273786f72507c201a648815ba87aafebeca1865ccc01e75b8da614b086586027bfb8731a96a27d39d668a9b4418041ae017b451faa521746aa5eb73b68464ba281b0ea2236e6725391fb573f068d68f12d0aa3a254f299ed2ac521f73a37cc880ec9509cd50ef7230057a389b6ea948ea977df7b6023497fe727227fcba1f30c7337b3039860a00459c57457a8bb9a1ff52191921a8621abcc152806e7530ce561356b957f39c88164e81b1784ad5b567c7437cba72272d2387563e106a1113ce8c98bd8f2a2fb4a87489c5782357dc1ba54f972c06ca81e2bab3d5147ba66e8c09fc4912566991b281c897443620a85f5569bbfa877d0180bc006c155e752224576fafc66e946712de7ab61c5ce637290218074b44ab8cfc84e74ea01ea4a683f2c7054b65b14ab80bb16c702e91571e4b80853adb901b9bdf595080356a3591df3521257dc240f3b8d38521d9e242cb0fba192c5cd8649695d680c009cb97766b421998a32fca16aa2002dea3531723d73e7ba24e8ad445a82fb53a9ac64ba692160551a76ce194591134693099747c3ce3907072a470c4d802d6c6527d7700e193188c0a9631889161d621e3f1750e7bca59b3445a999b5c84092ef264f41f121fcb894a7d6611386034b7a2246e7a388b20f0d57a7a2b5219d28a8ded4353a6a74e106cbbe88b11eb931d44a08d97721ce20b11ba758440bc73534cf97777cdcc02cfea7b823b6cfc7418b2ac500b872af001b22aa0014d1978c7ba3b86311607dc214d29a83716707bc4698b7f3bd5be1a98fd67a41daa810938699428a00b3563cfcc547f76de8918f5e9ac941a9915f715a3afb19a562904703b6c9036e4aea85316905fcd437e684278af9b93505ccdcf8ab231773e941570b9bbc97d525aa47a06ec26015f7783862410495a3052400c3105abae5270bd418384a141d52b34fa151dd071b7eb44cb394a228cab20fc545d2404701ca33a0ba05683c14b6301afa30b363570178630594f184993aa1ae3ca60734106800643e16410e8a5a525a2e2f4a937352513668adfc19b84d4bb94ff1919e105a329cc115eb7702bc4fc6d724de246c6a78a5b581cce9d196e1f18c4d82b1083c6ba29421ca003df15a995be09b86387774473bbc544009a17884d4c55012bb6fb70c774326ddeb93385753aa5a5f3042062a4558ef85385b24568830b9061612e341520093c53a9417df2b3930619671a38b4bf8ad0ecb7b98e436b266434ec9b76790054f576e67fb41047c1d36a0bc24745dfec53bfda02656f04683c041bae3b3f6065f16440577890eee3c6ccd38a0d705c27021312c0303d22b5a66e6bde0c45c1bbb0e22f1637e635dc812287d191ec9e68313b70af7a8765075205391001e7c26cfdbcc03e96dd9701f0915c46efb7cd3e80c6be24ea1962b2b544b72892f4ab5226690bdd059ce108563718a93bd1541aa496d9c617d078cc94db47236b568b27bc12cdb7018ce762743af52505060c7c414dbf1d96a9af3d23673068beb35ac32b0d6034b10a35eed8dfd8740de00e9e54d22c76f4bef3d64f7bf4ab036165288b4bd2b1d29b2dbbefc68c462c4184e3096ed25774d236960ca5796f62e5e59599b972dbf +ciphertext = 3c324c5e73d136b7d0bcd8e05af06310fbe58a99274f219ef9a7c2324a710975656d48e5dd5d4dcf9b3d5bb9e66c1e7dddc5f330d6e2322dc1703d8a7fcb39adee5c6f3334a7aba266d7a607184e9a4d59335cb067c27b20ee84fbcadac6d1afb98723192481e37bf27a20353773411b57caaf090910d57b92969cee9a71c9ac72d61f5d74b0cd572b896411512dd2d45456745a78c6a84f51ffcaf90f59fb53f94c457c71e2d7c01c98366fcbf37ac1006ca840707a4fa3aca958424c0f0114dc8a592d0ae37a1c3f6bb381ea19fd8e1642d329fab9ac9b64c1595238c7f3f70d14342cdc269052e6dc473a71e73f2dd863e6c94240e23a2816b81062b0dfae7efdd3629a84543ba6b7134887144e51ad0e73aacad51137d4c0dceb84d105728fe278574124d0a29ba9577a0b27a2fd1301781db8273733bfd239ab0795791aed0018719bc7305c359d207892d05b4f3b21b3419800076ba1d024dfe5128800b4847df25971f9e2257fcd9c52f843b5830bcaf6d25212ed238cde65d751451a6fb33ddc15019ff58437a72078330c57bbc081d1c0caa7d8d342f585ca5bd7e7c5e2037d9d32979c946d2a88a2bbb7b59522ae6e7a9f33773bdf39b8e6411dda81ab1811e8a6ed013cb01d7aee546c10a97da343cbb7e4e6b7e6117f4af3c2dc0e41f167296c81ccfed8e2c535cd2b63ac2d7040550a2b435a326c2b634566182961db625cab675bc7ecb5c428b610b6eed46bfb724f251e6accd57a967245eff0ce56ab2f8ed7e5f1b21e2e441661a1756a9a5b932313765c4d24039e1c63dc44f50619fb825d96beb7d74b434c3675f8e8b44c112e5c65070d51a5568e3fea44dc2980b56a6f8360c0377f0d1683a5d63b8f2a0179e385c13278256e665ebfb761d72c2b45ecda698f03c525a50c3284925ed57f89f0c34f3ebda831ec75272e6da7d32fbb1d41a24f84ba34be8707647ccecb2899de8c405ad92f01403fc213ae416d521146192b8c6a5aaa56dfb50818d0d9c198c0b01e6e398f3481e3238a657d2cbd44b22390957680cd4a7e434293f2b4a92a61e91b700cbbc5025c77c77ddb82e4ffbdbd807de96cf41e857d89ae7f561c88f9ac7823900e82924d871a87e546c807406a0f5d5ee5345f3fd886bb704f8ca0aee54f264c6c7ca70bfd11619db302736f5646f7f53e12c1d8c6e88920230d2d3496b7151ded737d7c06978c771308e2605011d9716ed1364c05cd9ecaac5d82e84c97c61f9c4c595fb3dc1b473758c1ab0c0b5c43a2b4922f66520a28370313b236915694c3d6318a271b8594c64ab33b015087d175a79e0e4b51a283bafe65959a98daf05a25e26d6a2525a0ef12c870d3b2592db478194b2a86647fd93cc6c8d4cd3552c7bd00cc78d626cbe41e9f43a78b232c4ed02e7a350047f53a2c05fd247c4bed1204e7438e76965f13376e29c5b6f5bf08cdaac20d62c4abd05b9a07edd533d481daa9248dca06126ef6ccfd265b11d7dff6caebdf72d9d3f5cb34cec1c150f7d6df270afeac9b6ae1c177c1e39ee963d8f2d76963e9cce1 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 74ea33c4e6367672b97262aecdbb9046d8cc0ed71ca2139b070679932b2c6fb12608bcb6c3d82b82e58fa5d9a9aada2cd50c69e69045f83771ea452dfa651967b18ce35b6ff4c238620ba1d1a3922e5c102aa30f18f0b920a42208d64db69310094a74e8ac610515734aa29eb4c4761338594c046fc1755d12e5c2bc482165d4b02be14e8495ce57b652fc5c90ee227e18391b3c4c05d58c98ce2b396a5a9ac0634a1386031cabceb8bb1dc3fc4204355375b6ace48a728f563e51b5a10666b61d925f5a65072dab05481808d355ac64d6b4591acde0ea2b10b54832c56e87202c3f460309c49edfab9085f1a03c6458bff13913dcc3f604b38f248313a69d9997176de08cf58983b669586cd400d21c9de8e284d4a8482373c5ad413f4f0015cba9ad058071b550a0175823f065a497f5097768272d695f04fbcff1825fd842bc429c4a846492785b81bc828310a52fcd806b68184b924c53612c19dc88200c5b483ac551eb045efa5a9c295889f84529920b7b47533957126345ba9e7c885962c4a4cf4845d1500642403327472462894a0c591b7516a5f76a4ed1124ce1ea4af1556996db98a70719465955203c7cfab3b6deb90c9d6982ad54391280cdbb7632a1a48e17b946e842738018970f781500f69322225ff263c8d708cd8b510954b889a5436a94336c195c9df839446a1b15c50bc9f2d26d4c73381e056941d0b30e40a084967a2dfaa5cd501c440066178b264280203304adac9a82f7818991a7b5db311146623908ab1a8f754b06936049f7378227820443915e3857395978687ca54d4143a43a883f05bfba28085607681b70b4cc2c5b78d203af868a17ea8602290436f21ffe7aa34c825dd1db380c319d26280e6d6393587b503d702dcd949b91b3531806877e0bccde452c55f95b9e975b2b70b2cec5ade4e29ea3f69f19accfef0b34ecc4c436f47c0ce45860d67397199165bbc2c305a8a9dbaf27617387673ca3eb1ca8f20f5afb92a2d106a2001697b147e53361bfb449a0440d7c9533d54014c740253fd484496566c95bb72cc8c43adb930f9c2a5b9c27bff459d9d618a4b26c40815fc97921c218cfdc73c61d648083525c5d17427484cad6819a32372688e1370e9201bf573b64fc9e0afc78738a35907439c5e50b8a8c744bc987199233edc0b81a5b138d5b6606702b97b21009009d1ccc1a073a823bc5c5fa590bacc753f7612ab87a722f8ba0ee2a3576baa0e00a07ac3bc2a2d20dde6ca370631c64da89664b204ab0ae13a23a84da2982db74dc68120d5771403c243f2808b9311ce020b413c67581366931a0cb582a15855162639b1d01fa287d884af25ab38a8b9abc7141a92489342bb178865f74a93d6f16bbe3d840174805fa839b98b9c72ea42d306c8ee63bb5c2776aeab13049d63ba7c99fabeccff247b4a5d7a02846654a801b5a5a763c53628aa2a2114647128aa7866b3ade5366cb8264780273f039a6ced7be8c8411afb12881426c06492d935639ae9a668883a2b9916658cc78cfa064c9b08ed79795bdc4be94933dd441c2f3d627445b33daf12873ac08893020724a3b8f4000ace40b5135582cb091ea0212bdbc4637bb9c8130c226538da47a4109f2c44ffb1a3d02803279c9022c2f9b1304f7c6424e10381afb1285d49e4a35c1da96a874dbac80924bfe213eccd929f7d9c087053d5a326137e65e07c30eecc3b0be16a12a746b1802429dab1f8fea3fea27bb4fa355f679cc485920ca348e04f92656360823284710179b9ce60825902045a49b1c62713a5c2669616a34a005acc598264c687ac27443f627832c8a123b8087091257927e6ae9993b2b0072f8282f083eb836764f727b8a9714e623a74adc16243bae40633c50a344ac6592e9c5b7be840980db774cd6a90ad878b9929d6e5220fbb32fd6d989ff4395eef9bd9de525e3b386f03189ebf654467b78cc9b4161ecbc8ab87ab662353e5015d89a95d622a056a50d1b618560276341e1adac02c0e5685962f14cea500b9e12b9f36cbe9e26af99592e4ec214ee9c390b13aa492aaa78d475c3f547976bcdc4571dd36b1a3c493aea1008211b87587828b055a5ba2356f3ba5137400dc99314ee1c46b3317520807708138b142862af659d55b6c4d5c026f711864d267992cc8c1cf00fcdcb981b3bb4eb4cba23eb770ad30834601f84d553dce2348bb7cdab6a73b150c1919c6b5d3707fdf2460ffc9076d066310c131c28084211073fa77d9a786c19a2bff1d116bc2b9dad398ff7056d1af447cf9a7f38a940534a819057268889bc718c89d00723c3ba617ddb08a6d807fc08a7506549343121f6421f39b681134b2d0680b249376769152bafda63010a7a8143487b04514693770252b3ee126140a5b5fe62bd9e260ab1800c89b1ad9d711a749270e30a110debada325603b50a2cd7b2676b096635366a57b42129a6e58aa58340364a1486cb1f35742f880095996b7628b78c1b80b95533c348a65201dcf6b7a8668ca25c4268910cfed611ecf25a77798028c640e33926faff63a1202744fc32a1af700a6c0828d3a849b040067762953d30603662db10b016ad24755c8bc8d8c840371acf8f955c30c862e85a3f65079f9a9c26f62ace19015cbdcc337f9b1d4ea0708c8231b4435debb5745a693a5161a56325fedb7510c90591f40743a9620a35752d3755fc674910b46399cd71f79c7807e173a20abba598919585067a93c6a33601d934c9939a00ab2742ad4fba952a71f09747eb93885185ca185a00731f9c3072631c7924a38fa907bd034ff002976877bde5cca0a04a78995510c5912853cc0351c90f8727ce3f7796a15c58b37b6d471aa1a9c8b023086c6fbcc5d6c1375e14dfd636b64dbc4703368cbc791c552c7094a835ca750f5299af3e31486412046e74fbab27cae701acaf744b013a1d68c3ba5cb3bd14b3929ec3b7feabd9847965edb9244da54eaf12503a47adff31b568b176ed7635e5a792451615c0cbf9b57aa3a8355b1db3aab41938383beb7d946fa63ceb164ae1220a83182c1aed7799174792e7631ab0b273f7a8e5124a5764824326cc82b920ac2c034bcdb8f9c8960a8869aa1b6337c3455fe01804d50af44092708d72cd058c797c1a22ba6cd7553c8ef104561812c79633887a54f5dc23c53c691ff4a881f7187e872499ea5afbea8ac0216a520ab80bca7828cfccf677bccc5bb5d0ba0860f51909a8162b3a4125c4c6f3d4d6640c4e98855c29f3e2336cf86563894e05ce742bd54af34191aa4c4f0c9c22e12fe68ec1816bc0a7b8026ea3112c7c72e0798edf990bb0ed4ee31557a90c5e4c8f652a9ecc2cd5993781fdb5f8439018af1b5424f910093cd2144 +ciphertext = eb13457aa0f1eb3bd2cde06212a5f02d29a01276aa6b76a34a326777ed3e12ee8850f8bfbdac297419dccdfcda70b1d3b5dab4ff6a650a62eeacd523e35a0952738c335b2068fa1cdb22e9ba32d7a5ede495da24c7ba970e11d53f75456d5b781361e7636104b1b9c11b566f87156828e12d940eaaea9d535ac70115c498008b2472a58cc4f7f33ff0dedbb1d9a06571af4323756478a3b5b6b782b8f1986c8d11df1efdc82477f220ea4e38be779103ded5e44bc44666e8254adb10498a4edc171bdb83c9eb46a9bad652eb6e8191748cb79f6a0c609ae052545bb8cf1c5b3a9ba40ab4fa7319472cd9136437306b15481e81f3e6dcb3bcf2c8007abe81ba30316ec3fea3709dcf8af148a2051e0f7fe4595ea2e666e8e8f0d9312a1aec39b63dd41b12e8fc1d970e6939ab0f924ea3e445b9b472f5678e3a8c03239d3fdf4c7d4ed819d0d9adce73952c17f491c6ccc9ce35a6e8b48eae36a9f2f6f7f8ce5a61f751124c7c0979c7c94c455f66075356e55635a592233249be949a65cd3d9ed990926ed69b06c118a97a2ff9131f9112b9bef34e10d356c25df34f77b90129a5b7205b5f9c5714a791883888bb08bed71384e59a103188ecbffab852f859345f242f160ad5f30385d6a2e85d895e8d3976445a00f681b8d3ed8421736464a047dca824a8c4cc4a23e48e63a8009b22a1379aa3214b8d74561999f4e8ea676099c8edaed3b9404b20582e574b09c55344c5d5e1d1e5e7a9971b78bae1dde0db572ae2d865428840d8d284b0377d3653b86c0b5f4ec09ddb0082a7adba134fb5e34a27a4a5207cceaa70a21570233b846bf38045ec0e1601d9975f8bfcb853c88cf1a4b4b3e5fb254900108217869ae5c41ed91d394a336683b0932e239713f53c65bd5f4517a2e2bef696554ecdc2ab357b69ffdae377e7f19ab9f471ea1651889543cfe69d887f88601fd2c17b59de80f574c23c6c6dfd87049c2b71f769b529bb6f45ad3b403a4afec0b746526bbcf3692df3d5a98c6a0afa6141dd6c9ad97e3bcad3a3142418d509e247c26e6a07bd6f9b5dd6acd0aeeb129ec58b8482444f063c4342387afe9fceb19868a75eb7b2ab9f8ded8a355e50ff232e02d93f98a31719d5fd7b4492c3f7464b361b7fedd9472ad8625e8c8caa14fc959f92f2fd0a9bf321601b911865bf1794f7a7469c35138d6248561bd6b37f8945a08efd91caf9d036a35081b8d90e8448b49a93e6642279aa12d7465c163a9de66c81f4771ad44f0e1bdfea583dc92b57d0e334bde27a6c3831574e9e239648f466195c3e475b827f6fc53cb2f605e273f62cc5b0b14e12039c8ddb3ccae8d7395cdc898a720966c0e631e73e17eeb834f0d18c824baea12b13161a24aecc78c61ebc99fc6863d2c44094e13650c3571a500767a1ca82f22c9397b093dc1dad2005e72f003fe2df5a47850001b6a70d3b27f7e26e79094a61092941b7fd006d157b912a850939424dae51952ae4893fc5261b6160a046e01358798f1c0c653274b97159458ec10a914a45d06fa3c1eb +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = b606c8fbd4177cb8bdcc4543ff8837a267540d53bf90e33e15064f6c635261505a6d17b490278301289e99f78ddc73077bf00b4fe66be2b582747552675202b9e9ccf47b2c52a363cf51153ec1cf7cda2b4a34a393cccd75d1ccbcb3189b691d84358bd0a4556b94b67891a628e50d221ca58b227f83ea4bd3d368e13c3e4b498905e62f71d07698f972e3279055e0afd84a5006f76ef3bc50d5c12b14fab2f7e5433759cbcc738fd411150ee93072694d73d652f660584864a09bc1cd50832222cb09a1269bfcb3b26f46a9f4f190ea512225c0a0b14cb8c8977d0048b2dd565ad682849895a2aeb54d3b2c444ab045e4b156087b2e4ac9b6116932aa460776ec97d7d963ce24b3d0fcb3f2987ba3fbbb80f41dc6d036ac11a65f6c0d09d17c0d4059aadaad80e38f68608b0c101b1977168db57748c91bf900ab29157a45211296240f2f75c4e72a2458b9355582c597e96cc328af943510aa05857f411732b924b7c370c620c6589aacb82450d477629879267c518afc1c7bd85bc4a2f6583fda10086798abe984cf775b16a568b66c4e4c48b86d33a5ea87cdbc2571bfb0a4eae5880d986b84a10349524eef5c2b60f6ad02d1130305c50f3a3e14f385e784712233a3b7b1274e4992519a45a7bbb29c4606e7b6c10a471a3b9795c49355d47036d8238053091c713139fee86d54d2b5f296ac546767aaa68a28f59e83b04da58775241a5300cbc4d5219b91a95f1f574222991fe302149831189657b88d96cd2ee29c1451185dc5be5eb9c607c3b64828500c90a6cc5b87e8a829327b12023c107647055217933ebc79eee0309ef886bf7bae78a7abb8a6b435c07e5f8b3479b124efaba06387493597b3501a743d5c055eaca878a82a2a9a4d4816361f1b8244ccc583f50985b5942f71aafeec46b9c451ab66a2cd3073ea80964c8c757693879d030d5c838109b0341a3a2ae4b9951ba65751057a84b5269d9829f9c82746a16cd9957b07cc6accda2910f19a779c64bdcc1712f146ffb98c91379023901852fb5277251e82e5077bf046488aa3a3d6bd859512b41891b569b8209aa42182445b7c9cf7a5185a49159376c48a8519a663bf5fc6a2123c23b6250cc41578a726b76972bf82e8564182c90f8cb3b6b283d51a1aa91a3fa5aa16b55320f4d008026057a316b4a0ec0b73e700f6baacf7a24c95f869cc847a366a6a8fd74b5b37b28ca9c56a5537d2193f9cb9a882d56b43eabd6c3aab1d32ba01f11c95c7abd11a91f9812d46d806433a9cb95b141bd5b31682aef8f53ab3444b568c6bfde9be9cc6c86b339cf7482e1a97b44939b80ca5a829457f100c0984f5aa71ab4959e4c45c392e86549faeb59860a30dc6960a1ccb5dd8c88a60776154349b12b9afea762178a4b78b9c00ba674592047fdb0447307cb30ec20df518461fd208e2f3bcbd459d0d155ebccc20104bba3dba842421657fe5b9d8401e07455a11783619397838c775f9a973152c93da95ca2f9c1c96cb0094361e5881ce7658805f73a1a95965ac771196d37298ebc9ee0980d5eb24741015f0844e4429c65f07be382c11dff584386576c15bcd27ab7be9056f07336555db41e63084ac280692543237901ec6d2336490cecab04dec92239ae85a40a49d36243dda4483dd40411b94683b629441367b8e647141b72ed4a90b72c2c89514a3c18aa0d29c8fb0c670cf205c00c26571a631d37571e5874446bc77fe520f20d4b9bfe5a8d94098688890e591ab83946ba49226058b9a2a1cb6d0a51ca5ac1337416be2f814d491b7984260368136cee7aa9e280cd2945c1ef21bf86869ab94471078c11140244e5b94306333b5478f51a151992a9c1b2524681a26a6ac6e3a2007aac2b39e2538c6176cf9958ad5d2cd67c8c71cf73e1873c3faa788a4095038f53f14295655e81eeb332eca786ee3b404d1515324409c73534610da67ebdaa57d67187f963caa13ce6b509ccac4054ef526f2a7b2fcca4b98e0c2993b928c5cb2561956767b8e51286994506aaeeb6c34f496777143a4a682c5f745bab3ce8e825f92c9aaa54047e8f8bfb1b37cbd2b21094a271fd64f173c7d859825ec436fe31abc9fe258b416468f848b8c359c03d94247a441a7dc43c4f2a7a4ca89aeeabcfd414b978012a8f498e75a3a8d01260db028aa326edcec365fc888b2d48f3622ce5b81b692559601500a30e6b56c37885a778294856696e37f20316851bc41efe67bc79b1294e3ce9fa50683f9b74646ba42b4364fc648e75a027352b3bef46811476f61ea115a68163b4494333400cc727f7d523d262ba7b1c60f2a12af31d36852e995cdd595d51c56bd64199ac6b2a4d38528f4a81b523c6468b5578784a8985ca7989b95d9c138624f78a108d71380090353d9fa32b437c290e0b49eac235d8231da76a4f66aaac2e080f5b123c3837b6aa93046e83907829c07924cc2ac4fc4a3ab6d2587f14286b88b46adeb7528163e9f783df3a0b6f3e02edd5c70a5159983970b3cca35ff42ca9d874e1c05af6e411e74b1c144434cc93c485f83cb3ae786b8377b0ac9a4ac2231b70187892a04e35ab3b3c6728a685af9541af3168842058c662bc6a94b9bd9514cff0ad03eca4ebfab1837180f1c55777ff30aaba38ea1581d955c346053b5948b47eaf0454088654804519196b402fa495c821847146d2e44821e862ddafb0ad5bcbdc0a1b2ad0ca722d019a376280950b8aed2489ca0c084eb437fec2f42276a1493be1d1268cc7700016037c613b4b1db09470952e84140e1129de8a904ef1ac263b3200815cc79852d2e8c0f5af1741ae5692cc304e98b5b6921b493b85cd82a20e0373141d24f8bcb181939672a5abfae59b175eac43d003c989828820a88c5300bf60b2871449c91503234cc47aebb5d6894ce37477d81c29631f6c0376c5045c1c30699895c3740ae190d02719cbbea50f42c12c324574bb53a61c336fdd1092c033d24b95ad5a4786cd1295f14a91ce7228fb3517caba9ead38320fc630f79c4b49b233984a6ff7a382bf5cbf8d7393cf923af32b0bffc427901062d417b7349550104a66689affca6c9647b176dba838c0b5c50c0b7be89832628a4f085ba282178b849b6fd2ccefba686d5a8b645c9c57504620b23c5aaf645c5066ce45212314b547a335f9c29b9fd3a6a9b31836d89ad758368be853aa74209deb37a7c4023beb2bd34b7c909f9066f0063cec52c10b82b07f07ab6491ef871b621115538468d46668545efbed73b23e6f078bff5b9a66860ab10881f9438aec48dbf59d116e117e2882b8cd9bffd3f79232a1b2bc10a2353cd7e1bd1e3204bbfe19adcae426ccbc269bcb58c92acb6544c1fbf17ede65abd4716ac135c +ciphertext = 83cbf67e7ac70adebf2fd93e80143ca3eb88ee1026faf41cfed158d6255d910ebe75b280c6cbb1dd06d8af4c26916d3a02dc9b38a0e9bf1dc6f91e164e39c7da0ae42c63046607c7e03fa111186be6de5eb957b4ab2fb2c839647a49dddd25aa6b4ace9ea6f59b676c5df513b97d80644725ab5e134cfbdb4be199d3f53f57aa8f5f56530444a8ed3a71349b80f5a83096cb05442b9cf640671c4d76e5ecc5ba0b7b79ac49f860322d887b680b84b7447eeef703ca6b9d3505b3c6e2fc74c0aaa780e2c1509f9070b9e6d672efbe17de683369b78479c6594beb04a7bc9a87a6a26c420cf0cf01d57f82790906c9068df999b935cdf0a337541127412ac3a125ad92344d79950b513bfd941ec52fde4cf2b0091082fca4248d691a3f76b218e04bc9ac05906c5a4f4274b5797c5ca3dfafe66f9393bca2859b8886b2548a05e31676410a602f0df6bf79bc7018dc0a9f13ca9d1e01bcb39dd9a80900a88c7e515a88f9fa66a1f107f38a3618a6af4e77b2f96b601abb85de2c0eae24ac9628c8dc3dcf6e130062584991d26bee22d783bedab4a5081a2afd0aa08e48d73d80a59ea8f6fa247484bac85f97a1f840b5294e2983b947592b4e69a55cafc2017f3d94e95b3b6ae31fa4d29301c305954c1e887abc6fb8dd22791739fbfb6f0bc25fc0e9666c4f530a95dd0361c453e6e63fe880e7d0dc4f0b18f7c451f93d4e0c198ea97611a2b4b578319205e8fedfa45ce300872201425885a4394daf806e6c539bda9ffc110718af24e1c66a64d3b38b505cfda44ef01645235312ef15c0f39edf7315f06517254369bf653047a4a4f608e5d8b22ec939eb634bf7a640e92e7d871f100208877d6b671b574d5b7b7ba99d6fbc0eec86342e20f0a1318a3787ba34c7e5b33d65a129ed9db5f6deb501bada2c126ba62d26cfefb86b2cbde1a5523c9e50c227046061e0881b68d72cc56c07a2d911ff6158871ef3782b9248e90b666811f37a082f93f4b30fba6bb2b381b64266b331b8abb796372ccec48bad87765ec5a6eeb6e6e2afdef304709c0468313eca33cc1db1e6d10358dad4c5398cc0c8c20cb70a946c97479f78b6ba776eb5ba0148afa81bba05c1604b797dc6b789333e0d5debb808d7119eb8bf66de36891287569842e9c73b9582c59e8b992d3e09dea9ab70f16c90b662412e2f2eb41961c1cd5b2a922066fdfba2142aceeb84151c3fae734969ca3d953b77b2a6f37f265dab5aff240960797820850f15d5cd23b3ff79ecc7519b95396b769d21943829677c96834fba21a979eb9621839f7d0b6d6010d41407629d0907b74299efa9983dd798e310b235aef69491ec034ac56a088dafb27c4710d8e18911443988be8911221266a50c3e4104f6c180f3d35fe2e890fac4d17dead7215e859b0c80da973fd1ef0c7e5a0dd45bc74f55067ff7a89146de7f3390bd1313982f2e0f0f818bc6043afedd4976ab60149a0d70a5d3f938675eac11c49573ce21714c5dc118357723efbdeec2a62c952e5ae71a1f498a +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 538cb63584899f135cf0464c1ce43a30809ca85a893430a03ec4bb510c913fdbb87c77621bd1816e626523229f5aa1776c1c56788c8885332787593687fc2c6ef4bf8a98139aeb75078b2257618615b030d7d77ef637aa62930ea0994a470744437468f084b5c505bb66602663f7b9b9a8098c2406f7527775804b1cec3cc29553aa3368aad332c065bd0ea1841cf553e3ab349b4a5f0e334255d9bb12b9abe975471fe04b8586398a68c986b43499584409a98b1be1c271d6180ccb69c7f98f001b63d0700d1908461082677e540b0322831af36713835b636088735555ea3a826be2b9b2388f3cd017f9066998f4492982b5917071513436d898247fc72f80d97469a7ae206743c6e6c35fd6cea9a50679a31a21242fb5656316e5cdb4c26f5ba39b6b79725be53eded4422aa4c7a3a3b2ab3ca89fd8474c11221c483474824b4a596428d8b647a692b6a0b08a212b97b4c0260ac53925bd198a8d2c7152db40af0f876476a111e1e9449da78fc246b91c372845ea198b4667e59b644012770213b16c2b319c544ccf9481fa69a8f5749fdb9aa472d2af44c49d14c3aee4765d2c257385a691b70098773793a6073bd2ba1d6360ccee01092e42532b664657703d43e05d73370619136cac23707f835cf76656ccdb509ef61dc1e87f8fa31cdf22c16dcbc58e892ebf2ab0faf75662b195078b96b3e1468f2b1bc317bd495a4f4cd2967a54cffa792c764310b8310a9ea6c1c827c913fb08a6f7413c5164e932b77a15a808637d4a9c59c91ba9ea5812fef244df638fbe88311a3c87da138a6c429c04d55bceda4c0ab02a12bc9cbb4a6b1af0672851034a398a41d26327442ea9db58e60bc44d0c4811947742da2926799a7a6433aa814851399f836856fc8ac743525dcff5b99be6b41a99a6828a54c3b92f9b088475e74bac897971a98fe1c70be1630f8eb389e0091e7d3148aa3531683b24e64b9c3146b5773461dc89298f31ce43a55a39531f9077331270c0ded842fb36a5075c889ad258e2725f0ac11757343dd6b13d6c0c8c039a4a9e42a417a63dd36c228be3c1945451d7ba996fd0c6708092305053d9da71fa0044d065195cbc23ceb12b3cf6abb3037231c450ba244510c83f03c98ce0644ad024a106e40bc5c06ade0106bdab1317e11fcea0c3e7dbc186350bdf9c73aea46bc7cb3c3e35499149c06a253bf473c039c2410c49382f08b21703b356ccc551415fe91c914b02ccb78701bc2c3e211428268abf678c6b0baaaf987767d2f60c60c176ef1b188d76b79c37585d6589e25629f1b994b7f684d5aa3ea4528ff4b56c332b46e7b96d254ccc4a56b1ba731082676aa76bb56c095b7001a79ed1130ed58358a18ff49438276b25a3da7d7622654f5005c44070db34809b79971396b74b0092b163495b246b52b7b329f3557d792c6035c868363ebf445948a756139127b1759e52fac5f953c2ad249fc7c48d0670383e055b65c55775092185907efe5baecf6c98ebf7524dd23fca8585ecd62088da0f0ee3c3b266710ea43334a8960b28ac3ab55178ac23a4c59bffa365ba08c3c9d1c8ddb026926c972671a656fa27c7775a172b3339b0709ce6548c4c5d11b08a40c348f926272326c81d36417a787d9b1728adbc77db24b131a1978a6412c3057b238a58706c4c3801b1587abd627a4c16e31fc5dc40a3634a531855e1a23b29f69791354148c16bcb09c7a67236ff677b186816ff3b184e438bb9a8442b755e9e48c4ed1cc97c15b8fa990eb4413c19d78a9253a498b38d6db8b3530944e86c7152772ea3dba9a9113319d0398774c4e7f9842714655edb7e8e37cee16a5e5da434ca6b3d87a2c8a255b24d5ccae0092962084e0b486157431f94a1124ae8a02f4796fb19ae06f91c17b50d905994f4912dfb7c435822cc94802817ab31d8c7ae25a81edc0bb131d5b8ecc108372cb953249e01e903a78ab628b7bd5290185a8b2dc06c7e91802fe353a3b70b3edc176238b678f723055852ad78146e83d65c38c33d7a52b667118249fcc855aa2c4f60087f8680fe9c237448741dc61f648ba57ce933ff568546c195c87b947ab155f9ec9105ccb48e69606682bf71334a5f09664e8b5161e09c2a75ca3378a361aac8fedc315e26996c57713f5264ec9cba309ab7b677c4c2b6546cf11cb471ae0435684a9005b6820b6f618af7831cb9396a1898abbc2616d2fc976b3129ab1053b0b01fb03282b75a6cfe80b404018c04070cbafa28f1acac8f7c1cf0f54234511a6a1b0e62fb19f2ba5303e14763e4cfede460058ca574a4200b5765d37cc79f2b51f9a2cfff3816f31bafeadb57a6f0c03b938968c095de9c7113c079e5aa096ee0afd3d72089818ff258c8a9d2b59708643f9b8bd1fb66fb68a21b323594f8cf62417b581cb1e8909da60a5900128e807468a9010205280774a3431056c68e11736420b7adc041e8f83f78c2a8f1c21225c4c00f819ef1279d26f13f21157495516d25835f09ac2811272c0cd53f3a0a0f4c077393c5a21956ae8e1a6804712063d56f7d0077bfe569102066766715cbe9949877c54892608ab3c334dc6bb2b7a55e0453cc91615111c45f495f44306588c403dffb9306d6c4c54cc45aa0bf6a486068879b43c406544400e6550602ca1d4c54c3e1089d42e3651c9c61998847898738eca237a7b887f293028a41aa9e18416f95a2ac3016e6b83bafd0c345d450a0b47b1b02917ef840c532c3cb6987024cacbb6110701681d12b2d1611033a622df0402752f6988ff8429e1077d811c6fc092daec013746c6d21b8a4c3b25989898c32a3088d50598ae464a149656e72c9e3c1c4acc0c8da0284a586a520b27bca913c7018afd8a27bcfac1b2c9791454994a7d05350d3caba345e58244883fab4b8ab45d95872b7e21f46d923e656b6d563b17557559a4cb3f924874ae92d99fa6cc6827a27463259e9578559b360b354ccb5a65ab9391aa5ca5307c1fcc029e1a5095f1ac57920a9798b27cce6adc9f2b71e8577d2048d36e60a63a913eee3803d175485a170df0641ab11a949678893717cba814e5041c1d928a3cc489c56a374a557bb333b2e850b9b27a5b1d896839532c70c835854b7196e33b6c77cbb3448ca937997c339cb6367c7b4487ff914473dc11b6285321c3bc5bda304cf241b53c28e85b679d1791ee6ec6f0c750972323d2417b49d793e0f06c514f81d367aa20cb20bf3520621417a764926e17599723cbb43304019d03738feae9ebfcdeb46411976221801b01cd1ff30523d044959fdbff8bb67b3733482b8a04d9cf5f4d3b396acfe69a7859af894fa20d50d8e05b66a0a51979553243a2a5f911385d3748f8628d1917d283eb0750829 +ciphertext = d290544404da20b5d8a192793a7d4c407eb2d16bc42af0baecf90bd3dcf95f5ef1d3349d7201b494d3267e77798e4301220fedec9805af34ccffb742d278be3dc694885022cf95bc7691b7d90a2a979bbe491e72087ef0b75300e5c67a55edad19d13bb897c7b6d737166026aa1399436f9b6d8a0dd9df5a4bb485be8245c8b4f67e70bac9bc11b12d3621277677f12038e6561f3f8eabb65b55469fe5ea49fe222f189b53d60a2fbd7c4a6dd1adbfc55f12c2c98b9ab623caf1ef3bd74caa95e308c8bfaedafe2215dccedd1a995c4fdd284786c4f53f30cfa95dd97492341d2265508f2caef42f48d6c5b5015804520a26e1182f78fc2dc1742c9e8bf7e037be0415aac88e68e46cfe681cb95f5b5386963615cd427d742f599499d535ffa977222f9ff581dd6385df0a24579fed78f9b0866046c27ef65f77ac97ea37e13d6df59cd16bae704601f966861cd8bf704ec06680d01e00b0d3673dff72ea412c25f3db82a3802f621902b966e5a5e437d29ac069cc4cabebc338ed57815c826c19402ab54226db1b99ac3b138304c89144d17cf7ea6bbbe9904667cf5dc64938bf6b0982bb93ea413c02edce8a301c6c033e3bda9ab9b638777f7cd4e9c1d362349439b8841bf0880971aee1f2f8472d8dc79c7ac669f4150e5d4661cf4d864f0547d65925e4514038740e812969dd0af48568840642964febe1a66bc077d99dfc41d27b558c6dfddb600dd59e05137d63d6f925f32270ff9bb0ecddbe592f48737808a12d6508b35db514dda246515ac4b6edab59f730564d5ef80f97bc90aa84c70d1b1bb9ee832a6c7a770e741d5e56ba0055896f4f4ba72a3e6b62bb9abbd10d3c9acca1870fc25ab657b69db7c1da303b8f646d7898161ace87a5f23c66b114d8c74513eccd9f32f7c0f61934051b2cb9f16f0fabfa9cf4f8693f7cedd3aeb3aa2ec8f7adbfe4b0a1bc489f2aea500ebe757a0a4ab6d181b42005c3096f3266e5267d1afe1637247fbda48b85e5faeaf2f55a30fb30013eede21fd1d1e1a71775815d7975a1192d4ec4dbb3426bfee55ac8cd54c2a926af0b34cbd8d0ac7dd1e91ae4186d418bcfad56632de33cc9fe445f515dbae1e76009883a5bb6ca76b9c0828b0a36e04b97d166b2349e7d9bb9f7a8588740e4c77fe88ccd769497d1132b11333851baaa8d23860a0a4d5496fcdaa20fd2b84517510f5056fb72e20441acd843b0ebb5b1944c2cd091df4b276a98a73420d61fe322f5e7b96c8fcf7c8acf344787a01efb0cbde83b9ac7243809b45bda3a1c2e1399c406122366d94ddfe3110e3607ca92d9a02a316128f9f978f42325a0f8c7baca3d2c21e1a25d29293d868aa522597d427a1aaf9c7d95ed20f13407c2bf924db068fd026025499e73d078876b5f15bf59cf3390e4ae886dd07a8f0cb1ed1a6e999d3cb160d33c6908a433e754c88de49945d0741ac6469ec6b4a17c0081e59ec479a25b31138bf6a73ff72d08a9aeee31b6313b46caf9f0be920ad95a376c3cf481bc37cc7e821e985d731ab93436fb2c13d9f46546fdb40b05 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 083b84c35752f8307e0ecba842295b45cb800f7a324495973beb8bd1ab046c46492b59cbe06bbfce33b74972c23db9556ea7956189a33b337c522920b0772f88b4152e413d841c4d641c07821a352b65234c1b40b9771488d13592a2992b205d723476e00cc1c4e0354a72600f45b83525ceb15b97491c4f4e98443f6c31354c02ca92a924269ee7f38b70219d9a7b59b8c1af7e198f0da784abcabe06022cf018654e62a3a3099ee503b276aa3e44c4254b9152da0a4d411b6cc21313464273e0eb6939489e28164ee7da1edf0b4ee6d5b804c49b3f4b9ac1260ba4e937bdb77176c7bf9df36fe4919298827d02413ce4a330b8dc074cd8c95839335053718ababea3d40f34778ce31831d9bc056694a022a4aa3eb8288ef196653045f70418972524a1167282dc74298a0cac5cbdfe348e87fa1ccec6bc73a84cf4642766c59d1531731dc0491cc86bb9babddf5769b69b453de31323353703b99964b88aa1ba049ac60cc237c2c8361ec4c4b5b95ca5a96a9969870de1f7affa84ba01b801500c58949618e8f1b37b151d2b649877bb217726299d1b611b112c234c3f4d7a608ec70aabf4b7cf3b4b34e8b22beb53dfb764a3805cb260ca31a494a3aa637450190ed725a5d913c1592fe0c3c8eda49c99a57599a65ac92b96dbd2c42f9a8b2fac212910121e78bcb77243967a6e4c382b1b24252540cd275b55e9a57833438787372415cb76e0ebcdbe1493897243e9eb9f47a83add419bc08c54905865d5b7375b21a89c3922ee948e0fd9cb057a1bfc55a5d07cb4f84733f8678fd7c29363e736919410515a6de201c7e6e3c8c9b3933b169428f1433cd50e149507eab4712814cce06879d6271284578b9adc9213c021e3f03b4f57806640356cf23d1bc2c13d044f3b3273f4f849306736e017aeace3057292018797b777d48992a43577056edd55bd9370ad7f082cbdbb3a02f2a8fb88106f963996c36c118511c2648123d09eff7028eff6023b2016b0f8a0ab975922551cdaa41638e38bc0254e47bb0b21f3a44d6749e1923563c6927a027d16abab8f42bd6e447321a0aaf317205cb343ca3185bdabb38ec53e40d540dba1b7d6a74e17b94d45546a83b519ec225548d9cd080227fdc6aecf2ccb5c0c5572a59cd25b6426f4b0c35761f66b491cdb9e187977d5b36ac2207d4238983371327d2c630af04dfa671bb1e72630862bf13572f92c3606552378208d967752a32290068896ef769c0a65a2ec1a1967a3b458f85725e6cfaf08b4d01a02f8dc80dd7357f6b83fac00c0472456eac98a8f83b052c01cd4c69fb140be53849b2a36c92ddc90dd0ab215ca3a39987c6733781d65807963b9b1720ea0591117ebae9d915f30d7abf7f487bb19cd1f6cba9d741240ca77d9bb5306838e7938320e14ad745a3580b5717dc54634a23fef3b05dffa83fadc65a041467d4a90da672f27d069b7c608491ab86d5cb5a02b9732217aef7abd1671cfc8275f24324ec7c28bd769a033ac910f5a4d25506c10b05f83cc4f98945e02fa41fb1539d37c944df15b41d781cf27368126992184c4eec5973fb9457b30396b7a9d8a29bbf5095befc32937026504ebb662bc5d5f32460af9cd60b8234d5c74654415253c6f1455146738384657b9ae58a8a1ba05c388419b648c2031bb315bb7ba99c7131a52b57314a6801c99d5221750a3a68641d604c0c21c4a889c6304348733141e6b0b13b068cb2146886f127de7bbc8260366cea995b109a065208539a81114471290980eafdaa680bbc8334c0617237f9ab5bf6205ac77e68d3866aec8c866f4f3207d91a5880c9c355873e25855d82b4a95986eebc31da0581859b758d887bd034204ced0064013131294376a9b8be76ba8b362525154283e574af7964e40330739009321f45277882e1ae6721cf6522e8561e7a8664fdba5f9e01ee1d183549c668332c7b3d6781cbb8d57eb04c6ca58a5024cb15a126b2cc1708299ab326de982333de728c1ba9c08524f1a877e0ac13e447c7f1eb02e01c296a105bca110b0a15313804ca5aacc7a7a0376e6d78da94b232936c9bb2a9c1cab5ebb932edde39b69b6b361c155235c6b5fd7938b4b4fd9b484440c7ecd6c05b71166210cbbbdd70bb98926dbe157c4f482362ca88f47c776888db3c8c0fd2206b65055c624a85d578690ba7f0e93b3b6e088f4997e1ee5b134d25330b128589c4389d6c2f8c0c243a31dd2a60c4be1af33f1837048aa7cda0df1f8264e6881db236eb0d44418b864a27ac96a65ae85d280f0141e6d782ac355a8965683345bb33591c567561f39b50cefe6ccbaf1a1c9aa35d6c3cc5679a1e74c2972d09356fa7ad3485b7c903bab511bb11454f4743ac98b7d82e87dddb3cf2274cebfb4c0388c2e4bd823183ac92fd345fe724fa064c6cca902382aa970accecf566d062821362031e7b1b2603435f916acf4b467de3923fc547595ea35ad4b3e8bbb778ca64009a7adfca04267733283337972b97904dc8616798a5a92a53229a944e5101da566a7f37a50c98ba5705144801fbb9c9c982549af3578a1e1021628b902604f233691c3c5b16c9acbf9d7a73956c89d763fe8ec2dd1c520564c1cded29d02188c6732423ae339b700b70d8ca22ee54d7639c027884b9729447ae29822a1c1deab6d62f579f50a89ec91afe6cb39c5120fe8aa0cfe820dbaea50c72121f97791caf59e41b350c75c352514285e9960c2bcb8a37a0f7da7400abbb719d6849f20401d074f6e0b4c9c26aa3104c10363bf2b854b4590b2d82a3f15942b7cfa44db26b4c3075ea51027048c3ab4d388b9f93a85134a0b061125bc29d4631fa5cc5fec1163ed29b59dd0c02a240d3d52278cfc5cc561456cb572663038b702132566b173b1588e972e47dc5eb66258af751d2a7acbacb395eb23c41bb1802a22b505959012e07afd2aa3bea26eb5b77cd7c058834ba3a40cad20052ddf02167a8c0756a1bba428159255bd7a4775d5d0973c0b25da4069ee026c066073ca4b2278012fd402328127c490d4cb41cb65642aa18cbb385039cc01829e824cca808c2e65563d9d9c0592997915ec895e663568f242e4aa07f2f3cf11c5256371444807be476593357c5c0271a24b80c813dc1b22d671dda07b647a4bffa0200b97961cb30d63aac034ac093a705899c65ec2322dbb69c5a6aa189dd35a42308193e797a5f9138afa5f220ab42fe03cc0d68b245a9c528470bfb0a3beec9c5bc07d3d16982b742681ff7ecc959f4d3007ec9f047ea474269c11338746d67e03df6cd2cacece0cea4aea4c4bedd2a9b7ed8df51920e00f9e845e0fc1cad13a599f1691dcecd088a3c3a380d1627e179ce48a82dbf7b8caa767167fba3d4b08 +ciphertext = e58cdf97fd001d328c4a68fc204f5c01d1467481bab092ad19b4ef4d98fe704117656e56867ea60c7c0623072b01678be7b974e3c78e6c8453a1517cda0590c7bf2b5a1dbe95fb39b40eb4332c93026d25cd5580582ad5878a82ffe9fa349e2d1950acc89f1d4d8f42438433f601b368a0c3042d254742043030cc0c855651a2c57fc106fea3ae43d44d9353e3b9563eba3020d9a7e81d196e18fab854c9e5c52264927938f726d921d6f5460dc86a7d872731b02411c73c28cf867e089a7f1bfdf2bcf48f4b651eb7ac4529656547ab3d3300adf1fdf62ff118eaa08c14c786b98809ffce7657dc4987fbc0d9cea870679bf94c34d4ff5b1470a446333ccacbfa0a0d6ac08c7de8fcbf2801e0877bf13631eb4ada206b37a86954c66f3ca260c28d65f93cbcf394b00b72b4efb46e3d9a549a0f68866533320486f46908e44c6e384d6ab70fdb6de5b7764fac8d3a417afc29ecfff5c57e6651245b862464277eeca5c616f5fece16d93153e642a17cd912266c426a32b524e9d4ce0ec32d7a7c8d2ac7cc0c03a4f45133b5ed35ffc2593cf5c2f1edc6f91c910b7502c1f489cb500568aef3fb4c1d53ef6ef3ca54a3a32b9f14c851d5470e0991564e1de56b0f03efba20653a3fb5afe7be49b3c9eb91c609acdcbc0b53961627b2d07828e7310286803491d498dd8e01c0b73f9d4ecc76c9fc8cddf1414486204bd3209b09e21bc24370b2981b7b328462af0d5d0647d7306f8fb08b646e138b2f3a96f316fe8214b9369822419c664ea5b9f6eebee89c057e0b32063c4d53d5ef72dfb119a0e1f6b0b4cd01d703b950750e003581f09ffbade550ca9ddcd9102be542363bb2040f6a2774b7143b491baf401d3a87036802b40b4d2040f9ac9aa310d1fc05b2adfb61edc5ef4cc35be9f7a5e14c62e8f48f371e515659cdd40fc532629bceadae922afff868344ab5a637a6205e9e9cc989746e93604c2632e99de53094063e88d817916dca5743308479a458f8cce6f9a7abbefb52518e354e1b6cc7bfcc181ee36b0925a60238775e213e15da9eab79c978f464bfb62487d9431bb02248b0b74dc730723337389d0e9902f0ee08cbb2c2c028e6a1f7a02981a3effcab960ec9ba59294862601b21c042305d9d437e46e05eddf3069d4633ded296ee33088a722e86bedf5e2ccc46870375b6f7948aa87a144573d314c2c0675403cb0ea5daca81fb68ecc6e5fe82f4e8583f56180bd1493a760caf072e963d7ce78f3dcc962ee164a94fa42ef07038c16d387c898c2d0366245059b926588587e67f9b28ba95ac4f2984867358c9d0ce5a365787039d262372560d832dc0a25dd60c055b06a7cc6775fbb99aa1b7b40a91a4517e43a24f96b1b3b9cffd7d9b626deaebddcfb9edd71cb6d801ed83cf4d1f59ef21f4757a55d60c4f0f3e42f3e7a1a63bb3e830c7affe20d0d481e232bc031e20d0af96df0d1646ed016e592a347c0510824ece687227ab603c7d262e79c4b9ec8746d03c85d52ba36972c1524073fbd87b75bbcf051d5ab1da6cd341d8693119 +expected_result = fail +expected_shared_secret = + +comment = Ciphertext too long +private_key = 908860dd317e8f758ba5b856c09a14d588c3dc105545e74cb4a3cafca5c95d706fcecb0b456004b8142de9b0194d6b811d0bcb238acbb562a9e4409c7058c0bac82fc563cefbb00523295128295e14f8024dc72db09993c6ab6fd5361801cb9d1bf73b3e563c872999379a29d6a50bf163992a65199288cb678b31bdd9c49e204506593e17826bd6c2a79f04148a35671dda52ca23c9312a6cbcd0a18bc66c9e905f4a2275560b25a8ca99acd791fa531889c16925644e00d281f4ba6d1936379ec04b6d00ac86ea334467627ab50e612a051c3c3d53f9531f5750e7f0774fa378a827220ae91889f0c21f4a4a7d6573adb1287b028ffbf7349b2792881c089608aa602ab0ba081e6736cc419159ad94b6e3497cc527c884a12e4e973d58bb2644d9bcd0eb95ec63acfeb5c61bcb398804492972c21a9b576078897228bf671926188784b0a5110bb0010ce742fba2cef94aa12f230f75c6cf943cbd8a428d1d233370cc34abd3725bb7ae37422c45f4ced6d1983b8590021c35e37697e3cb62d9016486226a2fd268bef894ffc15fe8dabdc2ea431f227d17daa98cc2b1b7786ecb1bb53dc60f2a8b3e692938a1e48688d79220d7be17882264e48513fab14eab66d66637eb4aa96d623373bb5579d086ac70c3e4469a15c513c08073edda7704f811d2c72f08da9b41d51f09aa838bf6a53d7baed31bb152d7131e475e83920f5643c66210919fa88a18ca6a7c118e04416233f39d5a09b38497cf1d1b6757b85f8e4545b1a36d1336cb49309d416c5803eb206d70aed42749b6f9c66896cabf1b49c0771840c525fd08c92882c95d2890b80154ae782e0bcb3bbd0b3f9f2993be1294f5965df9d2527303ab9bbb7643c4b56c564fbcf08d79f4713eb5a61e816e665610f9c2c3b6d2856241627808b35c950614d25c9b58991399617068cd83ca46e041ca592498e7e36c56430770b6bd5890375cb69b93e5c11caa8e443b459e962058c72fbd710004613e1b888b1b78306928cce0c33134f72ca080672b69100a2ac9c793cf0f967d834262c2979919fcbf369cb22b8766bf28bc15247652f5787d48a51d021ed199a1b83b5ffca73c8286bcd0d09594159736c0106cc09566d018edd2151b756db2f2cb2cf039f597ab62e62b452513f75a2bbba64262c7a972f1b5cad84f77363c651a8f16820e3ed4b5c1523f8751c6d13b32bccbaef7124ca2db9ee4e746103640076a201073015ae13c13d9c41783a5dd3b4b98f45a137a27fad2cecd80831d426313a24ebb0826ea323658b88b5c942cc447238ef4625ccb609ad35c77dc465438a5ca670151d06e8f5593aac7ae07e24cfb581603c155bf974c57a8aff13a9544b4234a27a46f4b9c0f5a53ce623f549184bba037eb58c30cb34294c1b1940a0868f52c1c7cac60588c3449c8f820af542a4b33f6b2f8f522ece22782070caffa91951b1b758739272704af25a1f0561782cac8f737439454314758831a228e00b35d6b7b13515871a131a250a1480f597053db72d51766873947f4c6c5ef136a792c80938a79124932051b57efdb61efd2b5fee266fa500be19248014582711040ec066350c02306b218f6cc267dcc1ed370249c43ab5291515ce12f17729bd70233ac64b121993220b369f1852d9af71526a78bde57815eb497e23a96714c2c19906b347746ec117f18f59386a971e4b1c093ab4f17127873d41314c1aa473c17876c3073a282bd9b8e51f5a45e831ee9c442c5c883cdb5504975ab0616842d237f54cba4e04cbf8212abe7779fd23b852d7a15442084df45433928630b65b059f7980c461089773ceb637cfb93af9a2c7331654fdb0c901130a00ec27813458352719b8a73676d0b42d2ac571531cd9307b6fc6625a933af61897e5ceb7ea1c63d7da32326aa32e8416f9ef62c2d49691b1babc8d280d4db2f7118ac0a348f3645a3a626247f6838fdc23f53f99c13db0afd729cadf91d1288687fd2a52e57c6e420cad4b12990513091997d7da87cb1303caeb7406a69a7c0981e0f47546eb4cec2d1a28d6451ba964682423ea7f4472b812e986003182919aff13dec07a253293ae1ea94294b0deacc69e353773ff06bd034cf182c61b8f1af0583954f51c69ed13c1401355a2b5189aa972964c7d6c4887483ad6ef984dc1c0e8bf27ecc24b2ee6c0f21929a04f5245f22743ea13e5af86a5ce60fca0a24932184a6c8016d4a2507c065ea56bff7d7a8c598320828627bd3a7e745bae8821391b3223f0132aa0a20fe847e1751619c3054ae7c75832726465aa8a2ba0b1b048ec1246b54bc0f9f72a7fbf86145163f8397b01bf03b4530c29338168e1a82afa25ec7b24e7aa12d8059819b3095af3b0df7c0757033070b4c0383531ed6c911fb492d16e5542586089bca396a149debeb8a11ac9e9ef0ae478b96b32479c244267b535b14a92b59019576fabe3f928bc4d6cc00249dc5e126c1fb51bc59b76f04a97ea07dcf64c7ae6c32eb73722c284313337ff38b61a7f3784af68e1f352574033a6c4519edf8475deb9ac297be9dfc175244a52f0b8044e5012e4c77935a64abea643607a5a6b7c7fc2564ef5bab29f661223b71174346a0140eaeac62e3dac091770d9adb6c36f08623741e928098bc13c3d5863cc4b128dc53ba8d76a7663a08d227311da2333e31b948130a220017697c78d8c9cd3107a4d6b844821c65d31404e9192b7fa651b4f686c30044e02bad0b574664b8bfaf01218931b2980b995dac7d2f9c2629dc5e52b40711629d41406f95211017c649339b9264351c4a6667e3260842052816120c7b446f53287d52390b196a57ad649610f850789c5967441b6725929fbc24cbc1a558cc925e57ba3c371c2f672e312524e91805fe3b565e62c87d3058f4d65638431e9cfc5602d3879c51794dd8059370a5ca099b67b1b3eed840ff7c76f9b469132c458760c64288833ab09af5a7a9fd943621b88addd51d9fd4961fd124df4826308a3ba826b97ef5a43bfa641c4a9d680ba088036d93633ab612b1b3d258fb8492e98013265c659ee9aaa77b4696565cd23522bfc09dff375ee63a2ab63958432219dbb0604544955f33788b86cba1f2cf2d17538d06b2801ba4a0e34ddb934f730a6c9e043086e354f4a80cb85a55615921e1c247806c567f7019c7e2428be9c17103b70948bc536b1122038a383b06f56a57e201a5ddb8bd11413c51a32a08a3c275d32b1eb8a450006e5a7b71da834ef87e2f31301e3eae5311cac4c0fc468e00ba5d109d89b1f66fd6b56d92166658ea26037fa634a19fc6209891a31cb79e8d748529f9f07ce7bc62a9fd694370642121598dc9fe98734e034ab9baff8c41a46491d5397b70296d12 +ciphertext = 80242d29b922100f3c04da9f211331627fc431749b103b911a79f11ccb80acd8a03fb336877d2ed125e19c8620168aa5a81fc52ec81562aeeeb62c2f972a3797e3cd96a5a65ba7b228df44d4c2f7d31ae967e4bccbb53a19af66bdf44bb2ffbe64ae4331f4c49d3088695503af456036f896f7591c99894d36b32cc1debe91f4737e23fda321165d5e5fc205db826bda8f40352288a174c283bf1c817c94620625c4283167dd3fa5100fa605bd598959f559714eafe222da58758d0d436a40c455f18a5df742dffa2562dcb31146751fbe1a67c587da94284fe20a668045e302f6d17564033bf0114c65283112ef7822afab4bc2aefa7859075c66debe6ad441fbff3c150dc62b87b83add674394bee61c15630b8117dc5c069766fe0946709f51db964a80ba7fcabb28a1a516914a87f97e24a0446f8374513de9859a7e9ff113b474870ce1011282b11f828272a36d054fce938ffe0c581d99fb10c2b8fb2378148a840da0dedb73211bc3620771ca3270e80f8b3a989930938c831695d5f5579f6570f7c5a4eec855b93d0a8920647b0940e1c4ba14aafd8b00b640ca192af69c7afcbb83cce9de5b61877831857e9621f1728195e490fe846d2c139c8c439bb7e9b801dd5cee859f75ca2058e0c56edfc8895a6c64b31edadd829e36020b0b0f7b807c22d9d3e92e643868f774d38429e77d2461e36002158e7737ace17a2e82a35585035ca51e73d59715cd5bfd72c347a11016e400eff5fdb4c19f3cdd2d2c044d56a6d64768c012fb4a45002ff5274005f647d9691a75f23b5e9b1d0a702225c824bfc5e02b4f3da9c05e99059ebae5f02111202f22e255e347b3ab1d8133193a0d3354b362682781c6e007904acf76587534e8937ee5e7f896b83aa6fa84c4962a6648cf56650653a39114206c3f2a82c182d8195de7dfbf3d5125158b6f204b4fc7bb12e0e97a52dfd2abbc293796ffa918ada84ef3a2fe5b119fcd030aa98ee04c3dd01d9620d9cc461a513be55d711a5aed657200214ce2fb5e7b00bd2ece61996ec32b88a676b92f30f789e07129d87e17e914f2d709e861e316bd20aaada70e6943d5895476d4bc0ce0ebcf1f5aa79a9bb2fa8b433a3e2778f466fe1f960d4c56f2c928483d3ee26e3a93c133aa0da0a3e7920f8e14492c8fe00d4a4b7777d82e66a105aa92cbc8f956a90f2dce80142d30020248e5bf908c50ed16c0aa7f0675ebb0aee9c87d85a1b323692c81d1b66444aeda770ab086672871273fb36d438c25262524e27f4948197e2e8b0d00c9f3740d76cc4f556731cf810af4ae5697cd0ae07f76913780f6afed660a1a514e0a0e783562a350484dd5bb664f4be8233aa680963862db422a24bff26c13a657797e71ff49e93e946a45c7588e48c2df1d91993ed35d5933b75f65d6438e7e18909c3c7c89cc7f3bde077b000291f6179e8322b2d0a7fcf3f0ce88a6ff757822cf7e74a261e7d7c794e764e01ce8010e00b926825f20d3dec373aba1d6034200b5f8e80d62027312d54fd8a0b391cd220714157b657f487e51e659ce62c40e426bd1b347b5 +expected_result = fail +expected_shared_secret = + +comment = Zero secret and error +private_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef21fd867d2b0695ede50dbb4994a8ca35e185f176bf1f28b3854d6e5f2dca7c8cd11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 7d3db5cd14b6db21e23580dcef17133205df090d24fb80487306aa6d894143dcd9bf9c47f9ae2634d4c2bef2400f839d42fa417a2b53baca917ac3e8e6c62083d8d1e849603ad45a6522f8e1058b328e38f66aec79c96065470ab0d15947dc61aa1ee1bd4a178c957bf81b8247c68425c4bc3f2e243b8ccc50fa0018ecbc215f3487b4f54a0fb18333ea2da8e2200a608a83554ac5649445a53da1177a3a11f69fe12c6ce093ac3cadb9be5ce9e6fb895345dea2a4cf386ff6ed2d477719af3bcaf2dd34f2f6746d039f82063fc589e5322b02dda783f524bf59fe9ea30b101ffd83be9d1965ed3eb16c52df822425f9029209e303df1725842e94fd806476e684f6f53fa74ae4960f498088b5eecf024b24eca054cff625feba4d133e6263b07617a467e0d9c0bdc0aa8e1f12620ade63643fdb573a798ebd81e1b0cda60a08ade91c92c3ff8c5877593ef0a90e6c20fd9bbcc3797d3dcc7a5bab85ec1e08471c73c3a19dac7d7690eafe2ecf5d19f3d0d3de2b700a622d1ef40631dae81f725849a2fc8a0225598b5941d74da237376e3c4cb72749e3bd76a81701d79f1423b2787a5b4276ca277e5279a820aa9abf164d921ec41a5a3598f13665c19311d0a75a0968926ef664869b8b2e6628db1887ebb2a7ec06432662b9c1494eb399142b2f05b6ec71d37ab33392f755f2a9c772f60a802648e3e54494c6006067f95946c09c6db484c526a4bdca4a663b329c45d7888cf8cf6cb20192b57b21f06800d711d1a79301d05eed76bfe406f85c2bc32e8680bbf7742719686f59564e39ad7f77e1d6226efa41e5918c4e4fefd8f24e7d3bc885af5a3e4965dbcac0b0ca594df119af883309ff10183b2f6d26a43f0cb9df9284c04e5780ea2bb2c160bcfe25a764fc0789bf40da40f7001c5d92e03ab1907e9287c7879c3fd3d30a1fbb3f4b5684d73b8cb0e7e0b8cf455ccceea2c5e92e8f90e0a1f99ab2d2353c391d20d9d9fcca8d449ea1b2d7b2e161bc198f34aac1a9221f5e6178be1f15dd26fb5973ef7b56a9214ffba6683071370e619ad805f6fc3aca3dcbea742c975f72d3c1c8b6f7a0fb86e9b4dd4fb76c5531d8d5a48be510e3c3454c2ae8196efd398bf117c2dc8c9891c8ac7db5317d4c98b5b300d6422ff8ad7c0b748d8dadedbea0a0742afc0383f6082c8428c97f49f1225a40e9f10ff3cd42d701d7a8d4d24fed319fd3b601601a9e9eea1552c1d169b4b7073b3212bd86ba3efe733b549950ec4b71078b3f7c09880a810492463d8152b11ef165a1ac29b81a17b844ef04bfde87f9c090a1453299c231c7453376f3a676f75e4836ac80ac294d69da31f60f1e470888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_result = pass +expected_shared_secret = b30f8bbff487ef7613d1676569986a72ed98afa9f37842013a2467a9ba6d013f + +comment = Zero error +private_key = 76da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af1c398b2065bb3d95582d63859ec7006f9c80b1d0c26c22666dec1784f76b4096b4fc5892a49c925ad388a3e31ab2bab228c91985b295b730861ae72cd0f733a0ecb85d26844ddc8d28766dfaec97486105a4281663c67585864367b7521e968357940bb31ac0658ba60e23baf9d5cf4b2600ed8b19f6a7c974fca655b0b2e5bc019c8398bfda6bd6442e51d365c3839e6e4cc124cb5529782692bc68a58617517a9d6a316ad9e93695e48791897a0ee3010c43809d0a6f5127ad9f43578d5842ed91902ae068ce3ac8cfa419e0dc8c90b0cac51a47a2a16162c515d0b98099a02c7bd82cce9532590c2588955c8c37c5d957736c25cdc7329f3951653747b7b8f9b1da32027121a53d62b949e9b15a7a29d07716a74486ca28bf6ce3b8bed381cc391890f2259e60a12dcacd293908c97c503606a78a4c035a10a966415788033cf870234986820ac71db9e322392652547a6f5836c138b869dc409c16d67f1deb186454ba33e6c45cb24e969734d4da25946a427346915d598a0cb45986fc73dbd63c387421bf95c11f6a0956a76697d6216485352da8932f697e8a02c293bb76688c550c63ca633a18f1e07bdc07951a996cec3644755c4a0f55230c48844ff6a82511976e4a0a17a499e768207df0c309b814e30a099a6511d6f3a499994a821c9dd41872860a977e7406cc2b3b69768b7ea720b2f5858df28f97b77f05d2361c62b100271db35c660493b12b66938845c1c799b5231251980a99ccab6356a0b445e86098108126812121176f13979e59a1029cb040bf36aef192aa622523866ab99459a01dd94535477e1755101478b53ec165c3197d0110a7b4b4892a3bb82831b300e55807c44df5f6c1571ca125b74bc33863603501abf51120acb848eb1daa2a7f50e640fedb74e01307f68798e98acee0e91bffd8150f2bc9780956b4a2697a825da419aab3d3946797762aab8cca9a5a65dc2edf507e8a9474d803c8fb637e05c94cabd721eef5716ca4410e69220c4a22deb89c82526a5b506bdde8789e2359352c07cbb90f3faa867c538d1926051e3c318939302dd31c34e894e3917e4ddc60f3ca9d3775242003ae7642035267757438a5deeb96c46489670abb8918c3c4b42ec7c7c3f2bc74f1269989080782c8941a2838439c3425d88f0d5537282a677ae1102ed695dc447668113481f89e60659f1e017dcd3336ed47710a8721cc421b024595a86125af941203392fb0f9cfb2fb7af950772319070ac60f97c2932ffa71bba6a94d47c695bca3922835d86a94cfc360ba637939034a7850579c7c5e6ef90cd7ccc983d28f357ac379a6b7d6f328bb0283d79356d6b28041aa0151d16605798fb65652ff270114f29241b8774f94553351536526aec996be9396282c66c77b63399310019ad8474912bff5bb1503d481bb4aab4fa23824c68ae5058230ac2ba43a4805ca8cf6b07b810ba6d415c4bad388d17373b4535af6234e42187d33ba51dc75a8cdd3c80870cbbbba89277c1b79e631f959c8f45689fdb7a6e72a97257aa188f8548da934533076937a140ac62c598a40adcb0bc0e0af7af639efa4128d10b8dc0197a12ba1e3c9c68b461dc3a7ab2975482c62810a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2d1eb791335eb534d3f66b1e40c2a9eb888bd36454b2a069805f787b8530ad7c511536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 8d0f4960c3b07ce8148731d6f2424e614145f9bc98adf02c0c9faf944c708502d96b8142b0823b6283faa03ab500500684ab8646951f90a09ddb241f5afefcb2a75c3bbe742961ee3dde84518933dd19dddc08fe0c2157743a5d464738f430fcb0940e3b12d8a2458234cf3d2dc475fbc589d90f5918dc8c1be0bae511d6bfa0c26598529a3646453019008df6bd4d2689ec76d5b0bf1efcad50bcdc1945bc670b24db9e0fdf1880aa9d90687bb1f4d4186ab444d2cd1c91b7a7c57324aec0e96240f9d817929f6b91d136447e46cfcfe0d6e11ab16d47dd095252e13d61ba2ba1f5ea4fedcdc0cc16b2780edc9b4e4941e8b2dddf791da9f8aa6b67906c52fd368e1808035377af67def8840fc44bd11896e594deca14d4cb942b28df99583081a3e9c0f5c8a989d781a062765214ca381cd65683faff599eb6db4752fc667014a8dbd7d2fbd64016fa33c7c8d39a36265f300501d52ad4c532abd18f43662e9a0110b5c54797f1148615e52ebfd60b07f9dd61c5f22f563620735a5c55dd3173366b0ec207722afa4e7791453f522a898b9fe97759e6112e096185e40b7447c112d508ef6f8afd64b0c2bf1f75cdaa42c9db11f0d997c38dc5417fe39d2f99f00abb50b66cf1f9ba5472b05605d492b8d483b7708568753bf415938a3c26ccb361873d0a1d1d42820cf5ec6986cce388b0356b40ba6d572f19be691a654356dc7e90b31bd04e8ba9e27fdf179037c0c8e2d4440eca4d849bc85d61f2df423bd09d90ba00766e5e6ba946e53a66c119611d5b017032c5a39c9a533097dcae083d3832821668b1633ba1aeab81f556d61dc96d3052b6497f7cc349b548f90fde55604c33ce018095d72e8c1a2468da1c6c5f679234636352e5ac1b08c7508a887b1fed6fe466520f88cb5951b86a4aa6c94398db200f4ad7e51b3321af70124f7f34823c4af599ccf925c3002d297760bf4baf7fd1465e95cc824853562623540c544c8d46a4c4e006837983f976d47cbce04b703dae965111948159ef0c95093df21d80555016265c582b19b0dc8403e4e297c980129485311ee1ab7ee9e4f37f627ab239f5c6158a7434b8c6a654dc305e338b2e7c9da053d6932bf4640c2215f68e2020658ec82ace46300fab43412d12b2cfd7e09954acc0e7b928b2fb791f68f7fb455230292eab955b4818031e65a54bfea008ee5605205fe4d68b26de0e60e99ee5acd069a23e5d83ba43745985bb0cf05da32028e66bba8516889e6dba565a006624433c6cb23147008dbd238163739adca132ee73b4eb0415a3b754fbdece10f926f7979c6f85d0a6e9ee0e881f13f50c657cbfc345185f55167c215d35dd0a0f88c3736119d1c5891fe5555dc3350c86e2df0383aa876ed91f03207811e0d6d752669b8832de3836481c33d416f63ac05234a996d7330b00837c3f267f09c74f0b4b85a2bf0b0ffbcc23ec403fb621f7f94ff5b14db6bc699545f15e448223e677906f8d4eef5a162e0b2d4b95e205b57ec7fb50a03c7ce1f53d7b +expected_result = pass +expected_shared_secret = 6f68f7fde8fdc93b27a91e7989842c6132d60007d2bb9d99fbb91d4e1c79fcd9 + +comment = Zero secret +private_key = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2e866bee46434ba9cf83567a32eadf682184ad0feb178fc612796d9b870e80fdf11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 591416ed43f689aa76a117f623b7647c6ebade29bec5e089f06a7ba3048178df0aa0c26680f99d0186432f9fc3987e0a511f2bd3d075603d315956b2319b4a61c250c09a5f8a49445050e6c2260daa43a6e12e7f25bde3a94fba40f990c950bd30f9229d5c65b6bb4e13fb8ea50baa866cdda065636656941dcf58907f6bc45c778dbb8e1e8a9bc1eaacbd3ed5c034136afd74228e70c4cf735a82c696ba386a451cecf4b43a71340012ff8676c7d5b4b80e0e59f1c548a40e7c4d25b8526bc4fc14aa9fa7935c9860efd43095538dc081982ae2c81a96f9634685f506bf7cfb1fa7fde39594c5252fdf753818be40ec6191fac29f9512ab94e8c03ffaa7990e3b788ec43d749d78da8f729803eaa864efdba24dc3db1a65d1110922f612ac60c3cc731d65f8a1ee946ab348d5ca8f4d749d5b07d0ec91c0f74923533f86640cbb30b470650d2b710c690651c99c03caf4792d923e5a094ce709678efad3b474e803a87b7d390ef05ce6fb2b84eee8c31f9cd325479f78ed7dcc82d06d390c616019ad6bf8d7c18cc5f719afb06ca331034d620b108da68656c2c5bcf206046cf954ff9aab6f76833312f55b0ae36330035afea8e4b9c3fb522599d7158f3584d7d0d70e4557568b7838e437f04bb41d4f8e8d41969fc8dd2d35fdef69b85d331fffbc5d47e1fdcd60e8a10979f35722a430c55e9564126182a8d9140e8cff41386b6e81a1033a9b40d75ca6aec60beb7e3080223dbde023eb59decb9054663fe1170f2da33c352c86b10c4cba4cd79878a7c4e83745764355b3c1a8b4a61384e1e9db00bcef2068ac7d4a4e67a1aea96c52ae35f998eceaef3db46b43b85dfcab0a2994dc700868125e3460e2f9c11a0402432e34a0193ac2cde8fbda0f1a81371b43f271f737d7af2af211f5287389989f71cff7c107fadf8010bb837d3cf2ac884653ad9854caf494d5196d4fbe49585525e50b009332eb86303ba5cf5ca11cd19b687b5f3ab06c2e36327c89e0ce03efb32a813190a1849382e82cf554d86caa9cc2c9385bc3b203d20415d0282543ed33ccec14b2275014a13121aa206a98ed60261e22acf4a8eac9c853e96f99d09ad7c0c46fc8e93db918818ebf249f871dda0c5220c4a46475266d2dca6b609167e120930861bce88859a822f18d044befb231ea1e6c7459bdeb14b6e988a85c50b4969215451d96a653ca2990c8db43f44df0809dd894b072037e647251aba319267f7448b408aa959825d79e011a5792ce8dccfad35553e4fc662867811081836a839927a4060bc9be4ddc69391e0824bb16d6376f03077919e3525a6865410c71a5fc8e86b9cbe9043a294c90650888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_result = pass +expected_shared_secret = 1ef65648be69ac3ca3ade1382a2b4a4ba1c0c7a04eecbcdd9e34af67665bbff2 + +comment = Random ciphertext +private_key = 3e52918647ce7b53adc5493a377943e758a00697bd0b831ccce27f0148c3dcf18878705db008cd1e637929d3ce7499592d0190662131843c155ca52ecd145c69d21e42b6a07b0830af558a32cb23b37c20b6d25d91464828f84425289459696ef84401ed0561f6a38b9f58554fc072ba9b78e9769620aa43a6d6200ac1769daa6432f89aff793388f1179b3a36e2c397d98a9ae1778ae5c41d5a88cb299bab1bd5aacad4a9f0a68aaa8c7cc227c4c99a7a08c9cc0ccab4a0cb66ee8432fda46ee16aa6ee051b11021c04e870cc80c6a7dbb2c33260e98c007d80bfcfe93ef8344c14d49c6ff872fd8b828b7ba1eca73628b6260ecc4af1e440ec073c340c0140c4bc07f05376a25fd40171ed621d1e2137a3b8c995e1921b14331bc269f835b3f5a81d4c25cc1a47c0d2225f3cfa8cf082855176634e22bbd04a9c05924c01d6bc223200c2b8ce85fa4fc3381966c14840680d0137adae5340e5221358b235d162a3b65a3a27529af9815ca6502c2779b09606a8926602893b6fe2dc34254911a5e46b0aa8069ef122934cbdc3f4b03150854c362f0f6c4ec3451c53c57a93d39b1d18c5a80bb7b7840ad951adc7962911836b65e4717d824d7c66a6d6c27575f83e50b91a25864ecf7133293bbfa3e5cf635c1babe7b70e0048c23a6a93e4a75e162e86649b0b1b0fff680d34d4cbe191b200c766cf0b936ef59ba9328dbe445a2838c2d3c68e4d32b74e5754f5b785412cabf1e1c121cabbe23925289a155d858e026916e80019415c69f36c0ad5fc914fc4bf26079113da984c664f7f379fcae92cfe7903d66695607c016eec95fe28aae5f72d483a464399bbb39a2a8ec3cf6a4a449c179759b126c352bb503709017777f7cabac4ac6d15eba9411c5cafe202f85379556b70c368878079a5dae88ce10228418902dc4b43759b650af7165dd69a2b440ff789741b7cc6ecdc2740b497a88502daa7a661316bc0fba5e90bb90bc9cebd0bc4d7a3653696040cbc1bdf3c46a5c9046cd512fa5694085b2a874cb613a97d1f654441564a5f8382b6751fb457793f429ac09a30c3a6bc89007c65d6a189a77ca0a820f6b773f51093ff94bcbd4cadbf79a487d76b62f81316484b5c005bdc84133eac7cd12a418500545a95505f912dd0082921670a134326cf2b69fb68aedd45602fb77cce8b177326239b60bb94f741a232b52cb219e7822016e70ad3bc102b86b95e0c51c8424346a85e66fc6f200573c73ac4ab287de53027e0a544dc127705492d42974b0080c551f37d1efb0cdc076b0d0b9a55dc33ceb4b798988e7544c44fb98bb23aa25bfa6783e55ad7304b9e222c997576d5f27872e00ba9097ba1a99750f00ab791b638c32028e655f9167bbeccb72eda40b0b648c5981ab2479cf3c6cdbd7034f2f0cc78a86e05c2c1b2baae9d102dc8c57ed11a8efa884028647c380c8eca1a45ceac7365db470b8a8375b7274bd727bafcced80a8ffad1745ef76cf9b898e9690b2fd477a7100673937f09325312598ccfdb5073e8768203a61790c0e0476dc7ac6131271776538839d62fa3b8b081278277bb23ab6a3e1eca841a6830bd48b77e324618ba6eae2544ac245cd1c5ab3ddc0e34835c8c2113f498b32d960bf8fc7170c60f8be7473e26942d57b4980291b9b6ad71533bee777e6de254dc8c129f97b1aa13c980f8495a857ab9747e42451125c4807eea3806740a3b341bb2fb63ae735001f7755ca21eca4980f64a167b1833eb76af3734b5e3a046d5a638b8b8313e5199c1e064616a09041141f6318286a203a0693a6b38817c7c70467c1098ac9750e2bdce8b0d905a9dd7b9ce561c1634c878f3fa48f881109c4a1f72772ec8c3b6f12226e780341b7570f0f64efb7b9efb69bdfd1493a19bba96fa62eb927152dc77525c17c977694e67a53328634c39bbc20212b9f08152215c91b1ceae891d75d6462cdc3934650dad29018b8b0a5f0929e4e586286ba2acd53b659aa1997c2adcd0a35861328e57bd7ce042d63acf61367548f31bcc31c32b7b70ac467ea4e34980727479cb6329ea2fdcf74c22bc4f65e16924b2a3216b448b920c737a58cbe510818c0820d520fb06252255459eb8ce7624aa90e06c7b361d9647221248061c5a789a127ee6b126f5939f3e712966e61991875ceb83ad9c71bb013240816a048ee21320ccb28f4ba5973563ecb2346a5a941ea374025784844b48701441ba603cfbf5cd7ee59e479a53d08b7c9b854ac374a0fc50294774b20d47127fc8214cec866673b70caa3d9ed2c34b11cc55162a6c9b2fa25645cba59e9a3126df5a4f1aac1b9bdc0afd772c55f00954a8aad0c7370993551beb2262a51773b5bde6acade0574cd2662fdc434c23da5845a8b7d3344430a215725003aa5337ef583c3f4c55bbfb4796d947a91454287389b729462f85727de20c6005456cf366a5c956c5fccf921a691b40c8a3ab858c248f2dc771e5751e8848c20bf03725043ece7286ba1b2ff86b8bc8f04fc4d65217149c1b579dbc8090274aadb36790a7d15e52e875e8c6973508039f06a3d2f13a9268bff901ce677262377b94cb71b33428c89e27896db887d525493ea4403c6b2f94866d9635a59f706a26036fb6c471529c45674c30dd42cd6c5b21b09bc554239c55c573dcd9b23ff05c8111aa9c05301ca45c424a77e3247d6fb5602a05cd2aa5cb9f1b2e28c27d7e91c21c026f7c08bb55047a14c02d09873ec76062f6fc2052e6bf9cf79bff15abb4ec86721044f71577b1e8c9b77b3f2804a4f8b7898a79a670963b69f65aafb1a56dd3545beb94838a704c82c111b194d68ac59c8a60faa6661c847265b86b82736437aca6ba3c109d6b778a84cefe1bb9e612c5d371ce86607f3c07864e87281832a8037270fb9662cd7a24d326948b0c2a260b05bea9ce8355be1d539768748fadf57e23c9b1f547bd08078937253c45b34411561bdbb0997308c99cc738a6550d2931997a0573f7d8650f26933d82a417480601977f998b4a147825670bc0d8f4b0c2213650f8841d3a2f11006915b6b84fdb7e29d16387fb01cc0580124cbf1aa2492c631816e7897c0c9821792f96017e5ea716134506c4f7aaf8b902147c3be046b48a85b7e2161577386fc4004542851f7c452e6f568b7323b4963753bbdcc840a99f30a22bbe4ac1bfc07dc76826af992ed955815dc7491553743c4a6a7699233fc35885e917c3454c988c4bb96c13e3e703f198b5d88acb6be68e169082c5ae2c39845bf15231d98cef36f30a113f0e781e0f8ce874313159eb9992dc0a3d1bcddc5435cb7e863065d04c789fb951565d6f1674047e7e7a1649482e1d9b0de92455cd14d0049bdcb7cea4b867ace5c8922b +ciphertext = 542acf1e3c7dd990f1879ef5b5aebd32055618c4e5b958995f0b22a78f9e2bdd8dd0cda23893c56f48a20d4df878e1cdbd39f50310f2ac0cd502e761329da00d49e7b8721f53af649ef7edfe74f259ffefd492f13b1ac396eb65916e02b3348560ca426e9b93beccad58bcf0c5804f0a10532635fcb74e45c1f8eaa83d56e78d8a7ee5aadcb7e06eddef900b484632bf1bdb0e1a4ef8b6fe34789934d9baa887ec5a39dbc6416f66008751aa193a9c313ef8a57a515bfe046953fa6a1329a770e9e1bfdc33f3a68dbd5cec1c2a55a0e41093583230ac35386645e6dcd166f25706efc779fec0cc4299e8e7501b93a857378713475782cb0b31ab645940f4c875548345ca0138372719c3cf9022034f17c28bb90f6090d4b8be957ec63c297a0ba95dc02f8761c18e7a948c1c20158230e2f9ff809cfd01b9d020b7164f8a3c54a143594d7d35b8e1ad6cb25d96c11c1b7f47f62a8d90c0e2b3d1460b86a463579e7b44ff74b6a29f30521588a26887797c60d86235e0bf4c2bc7166bbeb275996e1f50cfc36641710a52fe08fb5dda30f6129d3a304e336ff0d8698515b2cc450cffb45cceea7ef51a989d036c71367a4d26cd6025479d2f7ae58e700928e176c59b3040b054a09312d9fe529ce784a71513b44c1cd4073209a93a4df73b7097da88cea0b31c3e77e70abcb4b2ba5edd8db8f47ce844750158ddc5609dde43eac393eb5909d9415ee4698d923d8ebc28612f8b0676565010360b9406091ddc881fb6a992b70645b6898d13a8e3e449be589cf17bf9312e5cc58b03d3c181f7f176b67bea210337d6c52913f8cfe145da9426434c1fad0da7911bdb35e68b86b5bc6717dccee9222c4842c28fb13115278f1249b213498791082bab15d32f59481b29b9512945602eeba8af490af99fbb841bd1aead2b4f6f57f19dc970e83bd3928ea2d33ca3c3e50cd5d68e6ef516371cbaecb6b73f57fd5ae5b38a74f20759dcf217066081fee51f0fe8a93aabeab4717f05395e304e86bedbe11d462c1cb9d4e32e75b35fb707e7b509e43b450d6025b2d3e84e00f3d92b717578e820a33788013b2bda42f2701a9c6044ac2082e0387e141bc97a60bac45e0c1f4787bb5b892cb190e4b6776f5139082850494bc5ac56a6f759a0505ed4757009c35a4d36bad276185f1fc75399043168b22cc668a4b1202e03407b9fbb6a0799ba6a396ea78e137f7c68996f18f1636037179c4b920ef68526fc9008aecbfc0a2b02432e2b15832b35a61f438e06ce977c4d447612c13eebd0549edf316f64f5e7f3ccb0b46d19b79d103c1ab8f1551b6b3d22ab75a85660af2a9eab9c734875fef1d526da819829b66d65c8459a1aa404ec83842aa97a595e0271630644ade4df047f06778fe1bd1466bd413279940f15b9b848fae294bf4964286629682abed221e1ede635f315273854d57f68872bd9cb503545ef7b949b36df853eb7a4f47805406555d361aeeec6b77a0b6030b5a124f34cc121a927740aeaa6a381083f4e645b0d +expected_result = pass +expected_shared_secret = 0483742b451a5b2364318ed5cc233ce07dbb3fd4ec9386050cb8cf0adc8d41e9 + +comment = Random ciphertext +private_key = d1a0a90b4bc18a2a117ac39c6edb2de4c40d0cb2204a2a1740579b5ce7b69b1bbc20f332c99c2bb18cc241f1c2d349a0d5003cc0025f77b0beb648c94c6bb3ae6477c314218728293777115805aed692576edc99ce835433e8ac175b735c32c5c0fa6e11403be1a63472378c68695c0bab6a40c2a10f7218df2a2dbfac5078a99ffb4811764308525797e100329b8a3c2be7b2b0f73acd553991a5c808f0864a486a4e97069d38b095f1516da985dd172425d46123ca5dc8cc64190986d073ca62d5808d0653a748338600475c862fdd192f61659cc39c856475270af5691e579481ba108a5cc991fb6a48862feb8cbef42c6afbb072a195910ba32ea24b8fda6bc8efc21985f778a703b5db332e6442a387a91e6bc046a8d951df585e839cb6d00cafdb53bb4ed62476c66bc3e90c6ee47522747852aa05ba9bb2a1d3b3d9d8c9fd21bbe7bbcafb5769bab6c5f6a224d600bb27462f2184ce81318d283214b31758120b630c54c1de338407a378cf8aa33cd0ceb99a3f0ab635f7a4b32677cdaeebccae83a45283b263e3cf853c7938f13b6917681e28006b6646ff627740744a4f836d79bc9490c803c586236c8121861c3133f312059707b6a95711533e2d2b34e827638c31710c8706881aa3f041225e7234784599d2c3cb83c6881a63ccc194c566405038e5267f72cbbd51b8f48477a1703cfb6c18db3683d814cf16929f8172941a539ded701971e8178074ab2ba08a98214d39974a74ac3641c33996d218095b76fd795733602531ba6689e50bdbb25894f0c1e3b079a246070b991bbce65a24e629006a9b588ca5a3146bfef264e56b446b9a8654815f395218b8bc926b965bafd11bf1e4966be9b457e25b5cc2a45e519739090c9edb805f44699cb17aa487bfe256268dd6a2a0aa99e763a8e2b4496f35c0e604611341953cf7c326fb7a1421761b21ad153466c255020a324d718a4ced46b5405b74942535cd6801bb57533603b6d3904102fa9edab0541e5c90b0772210e51cbdc87e3681c4850114b3997af96a93889897542b9096f34750b09f16599d95466f0943c068ca588d923a35c7846aeb3e5764a29d7851f1aa554a901d4097004b980d6f60c079102b98726cf295603ff3b73a716feeec2fcee981ab126f33875f7f091b9af95232d8a9177144a8905e246547ebb8b50680a57e6c45539060ce091e77a214308b0414c313fed13846bb71c1c5a7b56638c800c1cbc086cfa41107c5b3c82528dcfac959e4a654c13993c639bca81128498f6e073e7182abfb33a17a4c024ae15893561a6e9702e83c2ee49c7a3ca2869fc48ae453586fe498cabb66766159f7001762372687b76a91aa0dfa418e1500a66fa296c99c711a971323b3442ab42fcf5688e263bb9ea977a16c65035b3f77985eb0736fc1aa8de9d427061884762c88d0a49456930f555726d3a387ff44cb653070a6f0032eb291f07209c66a1cd17410e2a6b639239f95873c003b6f5341bc66672e7c1c0f87687fb1d451d3625f43694928126a8dc328c2d6b30b616063167d0fe7464e855ad7e6ab4ed44fade0769b23b2e425ae5eb049560c5e1256c3e5f1b498241a938399fa260fd61313390649863ac639780ae5843a82c1c9c712b9605648f673927dcc81d4da647e4b379e7a9131398bab2a4aacc8b0f54b4db5c21e69a03bc6e7be8af7184cb5615429a1d2e60ba4d24777da8000a30934a4bd99283e445971b894c87239b9a8f2608a397cbd184c8bd4aa2dcac52ee15b1a87abc2bb7a07bb33c0ecac97a71fdbcc4aa267404fc64f528b988b0ca0fcb483f335b204fa4940324019ebb5d3a77ec5d553459346e7152e0614a6afdc323b078036f6397785547651acd0a0c03e11953520b7d307bbdceab228e48686c0c19c48539ea4c49fd77fe1386f8f6937905a9aee024966387017919a38048609f9be9d7a281c7a02f0458fd87cb36a6223db34cd7ed0cbd2ab35a1785d8afa98f9a64c4d2a48def73abeb985c5d79785671f1207cab5d30fb3e109c7ab8ea4466d48f602788a40d2970ec5f05853773700b4a2e836bb4b2c6e9d44ba7cc83ffdc25faa048bd72245a4366dbf48300ceb19efa132377697543b60edc04b08508b62dc62dc8c61b609b621d508d5f0162a639e4f1b8ddfb8206fc48f06d2513ec8567e12cb877b572bf99bd0cc1905bb7c42c62011a469b440aa9ed029cec13febf605a09c7ac2d33b3a812aa0a380fb297f48f65b6c26612e042eb26bb89a254b4665a78841c14cab28a556c056e01d0f283f0aa6236066225333209309584810585a2878d5eccf0d23746c4348474852a370ac82b38cd9546a4f414d127ab14b517def8386f07b48682ba321eac3395418da2475c2543e652a2262e56ddcb240a4b80670857aa40058e7d66b6c802d15191bb52bca8cb0a449bc50eb6c73f67c13ca3a0f33769890b4b797502e8911737d9744c584229935afa1716e6730add8a73306bb7d7742ae0a05a6f739cf52b7437968be39010fe842a590b0c770e428be79564c11587d46c613f418bf65b6881166cd417dde5ab98f0465b9c8b30c030caf8a8ac69ac65cb53919468dcaf5b6d7e88a1a949604073d6b0386dd373ee85017c777575bcab597b0ccb836265ca0ccbc595e51699788ea9d4c96264b8b1df65c3ea3a56328988d4a3b124f2375638427350b3db109514e472becdba0194bc95fe89582911e34b2c739d771224ac4d6ac41d1b6272d6296ffb424d9c6c322424e37038bbf1c47a5c7ad3d5178a522a52054adf0fcaba41caada77a15467cff9ca3377c8c240d4c902a5a8e6925f74baa146d0b49c7c386b1a45b31697d73620b6c36d4f5cc89a495f191883ad673200d282e22b60d5f03fdb901d7fa115fd23984b106d677203b9bb29c99a19ca0523d59c15d99c9952466b5de359c741c7a6b6957fb2322465721ce45f070397067b84a0f06744b2c2d207cc7db03cce9c1c3550c667003edfa2341fc359fb4640a9c0560ae7bd8fc6b4bfb033b0251e37f06d5754a2b336b47850b9dbd5ccc6b50580da245644beb0d0089072810e1b30cc180f55e75ee2e65bc353839ed3c697479bb1383b24b31bb76c0b9458c780121d9e694aebea6c8bf32c804518e99916431c8bd7d03b1dbc563c9940d843271ec555b037cbad5ab1a4003db6aa60cd515f1f047891677c4fe80f76239a5a7c7433eb7ab7370386dc1c66eaba111b0a0f52809370c741539c91a529c1defc0b6bd4482e6e5e4739a0b71b8001a0c201ad3847a6ca7ae267fe21a482ab12789f3613438f6547dcc642832e742810a7c778871d8010f90440ded913ef40fa68b4079833a9e34b24965c61d3a0ebf9866c9ff613a2af4a +ciphertext = 2036904d3d5f2c54ffb9debd5e80a77fda6ac9d3bdbe6ad673b9442507f68cc10d98116d37e8dbcc11d42b7787436801e52ac957040fce6ced2daae1d7b254b82e5aa8ab17e519956f40613d4bcad0171ee7850ae5adffcd61d10ba83486e8bda501e9a8e004b7b478b885b0fce034c9ce1673dabca43d12def5d81fd52ab8316aef232d51f751c574b05ba66dbd93a4012f9ab31e571148e7c649b4a437596250c5e8c91bc675b42c0c480723071fcf1a6e9612b684d78c25b8f645c127de0b9ff04ad51362b612869ef64507425b89eddcb4d3d69f693b0e0e0c4042f74545e4ab11fafe4aeb97f1c3b02d4f20c8e0be11c3d9b6ae778cc90ce2b029d2790348442c52562e73442f4e558019fe9a59c15d552801130a32d4cb6e4cf8ffeada36799490d3d33f29347a4518ea89bc127bc80da6d883a8db9700edbf62a8815a7542ba20a58724a50eb33cf25af24a974a0e85436a259c1ee27cfd8435e7588533c3e7f2b7ab02b6561bef18048dfe4217f6bc9767d481a7053e96539147854ee48b93ced985af30685d7ff3a0c1e7cf0a45b893d7d8badfe9e9e97ad772b8dd6d60f75ffb9b9c3b0661cc1c5b2296ca101528a32075bdaec375f20feadb56e1d8fa011f588795379748aa34ea25a8bb7564ee250a2f648085d04a9c8cdd0ccccb7d8bdbeb03318588da507c614598bf0c7640f9c6a15771b8edce1acbeeb4b1c5ec60769391e0b5ed616e8a49f054bed4e39ab9c0922f95f9f93319251721b6ac5ac90b61ec4d6cf25a55e36a7b2eae23bbf287a98de7adf1102b9cd45e3805fa8590cc39fe1b23db203c6e789dc9d78751a2da38509875cc3f755135bf4a27a0bcb7a0d1706a2c197b6883702f68c80b8634dabf75ac987623ef38d4cd7ef648e57a4df13dac839bed8959b558ad338636c3e04e67859cd28edd68d8cd47f8381b5ec5e92ddc6b07f7ff6d02f2edd8a1c4aa01a22821a90a9b11913f0a549efdb82df28370bd2186e798c47834cd23d1a6662e3f4eeded40f6ced0844c4b797d67095d3669aeef795ead942599a99b4d84164f42c312b215a4663c98c316ebb0b599f016d90931adbd41ad7cf5375a891e2f86da9da068ea44b9d4f2dae558622add24abf0ab1f95ec797082aa3c92d1d727f96b31bb2d0bb6764610a7459d30c90526db4e636207a26256cb3df10362bcbbba133d66587200aad59e1beba2fbe5df63d4434324bfc7daea0951384ed4bfb07e668ad2876ff781e133acaee564f701a721a6033a3928d8edd599cbf26bb0209b76bb5dfdf421dae28818a8925d3395c60ee3fa6e1b2ba1975b2d995f1ddcd8ba2e8cf2e14ba099b5ab34adbb63cd4f75bba2bc3a0a1bc147f0a1f3aee817f6d4b5a24e88792a9b64dd967e0514ecbf536116724356b38ff7b67933f777be2ad9baa93ceb7b101a27e6017ec571d5666078617a07b0f5b2c61325ad5fa9cb05b5342c8d38f7c76eaed5531801376486a1a2a507ba48af291a771aaa8fbf75f3b15f438010a3c5cb2195262395 +expected_result = pass +expected_shared_secret = 83979b9c20391249e9a0630a7220c29414dfbb2528b8faf2bd3802abf0d97453 + +comment = Random ciphertext +private_key = 33b26c26cb2bdb93ba803048568c3296eca696f62524d77f44a9603b53930cd22c8deaa61113a3080a626223b8f6165d871a6483e77cf8e8a68d3363519a0bb67858ef426fe5199a75a83ca9c5a6b54836b7e25eb1c2862e619a2c69114e82013a38a8310b4a82c813256b783b6613957384e46359e32c65a0639bcf415f1188438ca532720502613a3225404ee9349707e662df85868f210932db789c1849d5c6255a0284edc84a7ce88142fb2ee1ebb58ef4bc3730464df408ea94b0a0b5358f09283f6758ca031f9a64c356b03d9fe58aea082222841a974a192b649efad0b037e8275750c62dbaad739a47d1271f8af47405465d7078b749dba574a42b21baa28a751bdab46042d35acb57b1abf265f3d91fc58c54c7241761da5569f490dfa2b02e7916a8bb95b44ca74e356cc7040ad40087be3c1e34e6cd76b8cae9e814503aa74d93cd71b99dfa45c0764cb7b681a6bff29eb246868c00112b4c1bc9ab4eee0cb9fb57cb959aa8c44054c4576c462b60c17a5e9ed02207d757b843ad375c74247a47b4336f44d11b74265de54ca11ac07fc7e755332089bd2503b0e985a18b2146c699b29141145b3512c8ab1ce2cc23c5947227157299523a363388c34b63a9080e115e7e888d043c21ac9483c638125745aecec22b1aa60c52ac21d2cb2d527ba3f9e99c71bc47419b5f9500615ea9a1c5f75fcd910a1e4ca6506a5aba550bae09bd4564c7f4bbc87b616c7a1ac7d46002bb678c36b151fe8b76ec3476f25aaadcc45aa571c38a55af0f1c4987552e8ecb90ca14a0a18824681a038c70a1bb75aae0892a01fc2833b9320423598f0a5c0cd843ff2335c347ca6b8c9873c332681258c1c179207232b4229e4c137d6b399f01ea8111074a38638878052e70636ca7eb0d4788a5c1158e4bd79c85897b39329d499827f05b21d0e5236c2c7175557262cac923168fc9571f1c627150187628087f87b0a74215ac49c6cf09e8a008678b22d901ff90a34b011c190cb025361cab392623606a197cb7f2907e8e3aa0f7649dec9a26db12ac4dd572992085076c5ea93a1a6cc3458953c7faa28a4d3b16844170d928530ed72ad41c142a66c49fb7b344b122558b3df473c9f3d75490047c3dec11313352a2e4ac80f59aafba9cbec43c739746c8db2cf8577d69e0cc0a1bc20f3184af5c022500378d5771db2b3197516bc29841c42260eaa7c5747a324508ba270b2391d96bb92acc71ea9557309c23246c4b8c58965b541edc08c94096449c89c7328c25aab6ad3b3c8bf94a3d141e74b22a57b47c2646bbfa792a60a69601a375a481459ef855fe7a027b105896d8665cb6a0d43b7b1503216961cc20b38b53d154d16c0455835a81759c59618ebd82b70edb543c5b8c7427166d4c65ad961f898bcdc8f6c7813b7c780c437b22a738732adb9739ad35084fc538364c792baa2af97926dfb9c52c4813b6905c53731692875545d81f5035837d5362ba8c425ed602271a53ac75245f850b89d7190d31a3b404365c6a602927b9d29424c62c6b18d84879d14c1893a62f54458f34a612b80dba5835230c7374e2c6c40a71d7d9cee9b733f0000b851693f0210cc5e502d5a03a36a0c090da9d26f3a8443374c6457fb5a9a2a622aadad9a2b3a131a13c8ebb82b02d562ac526b7a5ba61c2c0427cb09cdd0c5a55a8397bfa02d690856d3a4e861acb16652261b05158b7ae1070910633b3bac026138188191730a1598e488a0cbf547907477772514f27e11524a2588b7ca4faac499b692e389955e3d25fd38ac62e8a2cee42081ba84f1b768b34134ecde68c22e4132036440215b84a2a290e4269e86278223290ef58cfb6e307f1904a33e71ab7397934a32ff46724bd45af42908ada6574a63632545168ef69ba6e4641d3309b3f1a1de960950812373b184330b08607c0bf9bd6049b86b7704115821b5ff9f55511767c3cd7b5b8a1700e26ccb19b7b91414c48f9a8670a6a5879273eeb0442c60697680c4ab13c5b302285a214e47a54fdd12f2dd57b4734bdb986cae3495ed1722c1cb03a2ca148846b437bb14ea3175d947181ccf2b9f3ca6d39c4147eab074f5901bb67b745867b0bf478928687fac6593d0029c4d461223c77927106da39aec2f102d1b3714174600cc97db096187f507fcd429eb87b8d0733c907d3768887cdaa7cc20a40b1ffc77fae431d2670a981fc28287a5716e016a039a9c15ccbb7ab2e2a933aa8c45068aa3c5cba75ccf1b63a033b6f5b74da5c105b78b9731b045cf397ab6702bb79274e333a7cfc03d9982fb3247fac19814b5c1319c2b042fb9a4e4896cd42777869c2c1a83b078597fb74128a590e3f00561ca89c1af6a2e5abb0ad799c21120e2af4cd87a843fbb0265b2485af591148679c2eb2c7c32ca5bf8c07401a8ec9c3b8e59b3417373b05633d3ab7af27bc7627279f310c61a963572d23a3383573d656c3b6c814725208fe560f72032a797567f568ad918b6448b7ac62342248440ab676b588f4876a086321ebb31963a0a5a147ce032800c8c04786256415a099e4c08076800293b28f09ce4ef92505608208549b028a96fb553bde76485cc853b14058e4fb65b53c7a5c69ba6f5786c22765ff552de60b7f06a2485996cb2f76138eb40ecefa27da98c6d5fa9d55ccc225bb06f3c409a39a278f6c05bb742b5a0c2ddb832207a6be60e8371b4cc916528945f1283f37c41cd5af9965403326a3a2babc5cc8c1863b7cc7318f07a47b95b98caffc72e514ca2f506ec485bc7bf44b0b6ba1cd097fd441c6813c16a4789b0b5c9ee85640c0d7099ea7c10a4192ac59a9534161262756abcba134e59e5124b4f325137a26ae961a99203a9a6dfb026dd3290b14bb52e90200bab1b95b269127103bdb4d49eb5a783680497885a43010ff598f0bfb9108f7a19fc22dcc085e37ca28a29a0f5729595102aff8623e0d6a4ccd32975b9cc30f5262917014548a0dad577c1e5515dbec32b5380cc3fa9e8196a54d4051615723893c062264014c0a3e12fac72db7415e87ce0651aa7d247e80a97194fc888e945ee750750d3cc330e85bbc98baea086c0bf384b1e821a569880f49bbeec8c5eb8871955c816930c51135a496c91793fb5f32e45d1e4a9a3d0ab69b5483bc0b451ba005411a14e234581d367180451657bc6034939ae43b5cadb5bfdca90c6057a9b03a3d8f227c14a3a12f7827aca8b0c9c11e062042b14959ad2b83ecff2aab22866ea02ddcf1684170f38c3e381eb061e44ee1c3aad6fee55aa0e2b598e1ab8cfc9fdee2d87dc57d019b2c4e4934ee1ee36b0ab27021f81c345650cb150ce09f04a2b867682356e033b1811c2ed0dee885674ce196bb5ff3aff6ae +ciphertext = 78c3ec20811d7388fee659f579cb5b4aacd7d217aead43fa1cdbd063d9deaa331cf6222dc834fa8a6ce74c36659206eb558c1a7d533ddc4bc9d6d363a07597f6a6c9102be7209e5cad6b613e70967ba861c5dd8cd419ca9e532aeda76c8ea1c7d9da58c0320a52378d01a48f4141d0fab529d494f86b80b2f1d5b36afb4ad90f25f4290c6854d2d2e44d2d7506101f4a18de268d388789e5f2f89132afbe6ff855e24185ee01d028d4d9ea6b3220764fa7d5b2d9a24433e848c91dd8f1e5496cb88820644359c20ae0be33a0e749700f30f0a484fb18d695883b493255acfbc8a285bf477f8f102212b8613e8cb72b59e6456aab7a6c767a26aa8e8a6c9443b5dade8101e6afec8d7d4eb3bf9f068c68f206277b40bdc7519f719bdcef914e481303bfce7ed672bd84c32080cc83db38ae032c5e4c47d0f9883e511a540b90d254ca6e26efaaa6dde4cb53074dfd568f73d38122959ca47f9a2ee58bf593835c9df43f145f5c9bfce2c44d2047b8fe39bb9aee898d757cdb1a11136f8a558fc15968f181c9f496952bdbc60638c05cc2f159842ec9879d6130a4fe867e49c8c294f4d97130365293fba41d79dcdc6e8d20568294c56cd28a2ce4887b2d7a2ea273b61912be611fe8b9f0029c304d62d2a8b4de6adafd62d50bcc5d497e542e9065dfe03a4e57fde3dafc007446567576bc34b6ebf844ea8ee7e88d5cd79d1c5b76a631d22778818dc15ceedaedccf88ea551705f52444d4a8f4c1cfb3859ae5c4707341fd7723786d9ec4024c7d7b48efa44cac071b40c61b45d0bc707ced0565ecaac81e4bb567684f0974ad727db1b218396e1c2e733acb8ac1fc09cada03dfae5b995b8ffe8b866c8019796d3eba80268b3f1341e2ddd9162a1bde8566d58d39cb7cef1c7b32d28e5da23dcfe39d24ba929eecc8e35620d26acfb625200b1f2cd102eea2f4036256a31a91bc8b237f82b17c7109f87520e709a849b694343ef60358456e69ee3831a8386d3889e963f9a9a39b796b12c0443eb11c53990cb0e113f677a2f97a2305f007c07b682526d7dfffb92c51efc7404c44eef5ef33c7131695a67184e876f4fceb90029a17a543c8dd24618fc0530a32eccf727907b00e7b5e9d86ab96427702c99cdd1fe59f7d7b4c38eda17226646528192077299a71607a823242937015828ddf1006061344d65b2a6b4bef4fe42814ee5b97bbb7044694f2f7c0540b2aafebb13a48249ddb91a0603783c45947de5beba31e6b10d26e231e6a9f50b8307577874bd39d7ff4c3e3c2ce647ec90463a5920f934a6b7c7cca4faf96e54f3f9b9814444ee9dd031704edc5c6e7dced1bca24971dedf55ac2ff16c12037d10bb4f31ea649d134965caf76b13479d4acca397e629e15727eaff7b6a81f06271d94a6c2cfe59227bbd9063faecc9d611f6d8140a55236fbc1eac5dad404bbe7a5f02acc1dd4fdc7dc1a93e0bb6a6548096744e39e3810d7e19245ec38d9cd779842eaea9d676d65522748299029f92f0d5df94d823bfc7 +expected_result = pass +expected_shared_secret = 560ee82de0d28ffdc1644150918fe6261095c4d8a1b15894faeff7f2d46575d6 + +comment = Random ciphertext +private_key = d423525d09327815b433291ada52b7c7721c7d30b7aa1b43d99517729a6d5334a808d1be0ec493086633b6222f39e17a6bf43f88f19d84fa7d0e12639cd421303077c606351ee3c8723ab4d4421399484c34e047fae79c6a4cbf37526d82c4a79b28badf46a1f9e60e79167e902871e70c360b35a525f938ebe7ae77555701b14446f67ec9434786b57ce4e5b2582a917c087031f7c49719aed88c741047ae43dc69a3a1655f66b9928a5e6b8c3dde069ce7706d9c4c1716e72443ac9d9b235321416da5703c6c39bc3733c9a6a1384291a1bf837bbcd67379d6282c43ccc6379444b43c7cd3b11ac4325f940016419077f963a4645952889fd7e565085040ebdb40fc718b6b671e7b9b5fe107b4dfa84e06842ef1fbba4d7c4709dcbe843338b6275edee1042dc06ffac01a69bc5b0b18b10b77bca6da30e7ba020f13749435802643c8ca092b19ea1767b930c482337b451e09875fd3d7704f23548a261940261f8a5cbf059a0076a40b40abc97fca2f2b1a73316784592c57e95aa462dc67d7255d63cc5858d41616507e0c33a276e2343bd5287e4c5317ac9b401bb8b0542b594383ef933f07c6336a962a8e9980d7766bba37358d1cce6b22572c567e41d5bc6b64207bfc7bb3dc18a419a4dc6c0a43aca1a3d4508c1a3df26328d730c19e923c28394e843a7bc549b22b9b6bb4ca49d18115528024d7d5a9444492b20b359a24273b2c9ccbfaad1f451b4b6a5df93331ada69af7c52eed440cce68261ee17ee5e97947d6a87dc2b7eb5b1c7518c68bd6130c2b72d58170c2d213b4e9193fe053d6192e0cf2aded77379ae9191aa6ae5439ba1d54883ca2a7d39747cfd26c652aa2861332518a1cd486048ca43955a38a80f93f92e03e2f30355b7a36a0c046a3709b872b73a9291491a1a401e6423b7b557104ce69f57e0d852f387475baf1637cd85d86467491595da99a098ca9772f5745d32671d6187c459c55d636baf78818ce421e5fa6b9750407e25036f886119831cd4a6b2cb83a8ff7e4bb65611bffcaad49587f766b492c67c9ff1862293b499df747ec03a1cf4c43ba55209929ab0b61321ff77fe6a74e03c764b5553ee9fb6286474a235739ddca24a4767669944e530b05a7646e113c89d2f6c103aaa979067c4b804ffe82394f15aa3b5a73e8f7309d6ca111a34511958693db9c16f049036605c0d9b41ae41375d9b339e37dac215860726376456453c0005e32bc07dc791dcc4e576b0df31695b0728cf34c5ba7738acde0c446ec2bf4b06bd4c420430b28bfe8aea87617187335ae984b3524703f05cb568046bd4cab6af145823922a0a821e1a7b42cd0c7e6a429b634723b23c84e650007e9bbc782374f63454ed6a74ea3c4191361992326f0bb2e74066b808091eb316749aacd1c45678eaa640d88a78f099cf6a22d92c415a96195bbf6a51337647df98b6423bedbc842c4d1b4a0bbc18521acc106896fe655d158660d4ba9e0e696d03c9ac9850d0df17db127604c3774f2db5691f9184e6b8bfe692f59153013b1701f119d4b173e6723800db65e3c113b9a750bc6082fe8c16a44e9c1d7bac64c397f275ca7d2b528cd669aaab5b66ee3b6e3fca91e3c6bbb551030752fbdc14f4c589d99f26b3fe99c015b88fed1017f7605fe58590d8a70ca2527dbfb854ba06581785a5912cac930c568927d696c3c993168b96631707562e2d83d4609792f0414dd9085f47c84d4386bacd1c73c980559363c0db1cb2d5b14853207dc15b3d2923ba21353e6e198d521ac5b4b57404b41dc625536d405a0926c4feac4bf9c3cb0b335dce8851f516c0a96268b049a780202ad031d0c83b813da1ae648ba58a483a1b609e0baba74524a4ff52428bab0204ba849848d1e5c1d0465454b72878df990dad2bbd14a18d4b689203cbeaf47c8e59a33bb22ced17ba91d5ca6be17938b2448a470712ffab18bdb6f29f98eed3bbce3c0a032717847844388da84b0e6c95f4222d6e970d14cc5f8546939e47c91f9bddd430fd2e0c1763aa472c710d0f14d7d40774df815dd83cd7df45daf79912d607414802dafa34bf117889b925db7bb553274bb64dab76f0523b020808fc79b37f5a7d25925e84bc54a922347000ca48965f79b762a4c440339720d1b00014ab8eeb2353f9b7c305405ba535da6dc719ac0813ac84839176f6e30623c652f4912244cda1e13f3b74f0c45b2dc6ecfea2d6194027d1a3869ea4bb9d24b8c1b5e57bb6b2306c95cd6431c880ac0d1bdd4c6818f87b34d046ed002283cb876fc509604651e7e5a119aab4c4466a807361a0824237b58a9c1c889c509620f7ba6dad16ff93412b0c04159015166176746465fb28c0df94312eea5888626c4e0a2560c25baadb05a5af3089e546bd5c72f4d26984beb6f1f75c1199189fe5a254dc4c935b57d2d63173b774c7b09007e21cd36a64c6215a43a5c2fd08c65c63683d5b74a1707c0dbe5a357b90376d192209791f649191f924eced60aecb5a625f1208a432fdcf9228929b532abbe63d741ed8542c288a9d85382d676440ca1a4cefa4d003cc8436a0cacf706db7a8a0a137dd0d9353faa7ceb197c6d2257a089bf8c18b9b0246c78bccfe4059087e4aa2a8031737a93062a852a036ce1a356b17b8e869868723c731ddc6a7489890f8b07c6fa4502871c1b3a8292a154d50796e97290b1d028526827021457a7ca73bc09731efa734f9028f1892bab703aab52923b6a53214177a4529b7c0b77d8e42a7ec095082aa89c66b2327aa8c0cc4f87c8196d747d05aa9ef3a609a11c09dc08bbdcf17beca49a2fe48dbadc7f1cd311067920051405a9f00f54d64ffd8252777a687b7baab64136ee88258c20c0ee385807817e33827884ec15cffb7668865ae676bc2f6bb24bd4486905502fc096812c03138ac5e7b906e53b2d47317b0db569713939b97b2ad46b12537715617748da3948e45c92e8b9b45f903973524c019987a2c9a64c88a658b89c2938359f139b52a394b2d4b51aeaa3f5e36a6af90d81a15263d36e2cd62a7cec9d5dd55e9eaca4e1868466610b2b5c52da4788769c94824aaf43a9afc5e2bd357a86a1138d56fb3377e8321b67af3c65920e2151997b752d3c8c128ab54c75934eeb8faf83c9f2684186e84c6a96187929395386842207537c7b01d9b434b10084fe7a842470b0080cb402bc838724385c025bb3d97616474158e5287bf2863ff88e77d25593a03a3742a2d92c72ef8a936677855850845b52b4778b9ff057ed22666468e72b6c430b65c52d214b2cf775b280c6aa96a6985ab359bcdb4429ed4d1fac6c3d1add76f5ef0e3fa0d00163bd9cbbc3bc5fbd9afc31e665d6d4950e89dd8e6a9cbc778255c69f +ciphertext = d1c30ae263bc893b6c0475e3ab25a8d4649cf2bbba7a721745636562b6794a997219d65563534e62f170a093dc52396f85d57f29d2486774fb5cd3bbdb79e09587736aec48ce664c13fc71eb4a0b0d45a94354da57f89ee8294301e6f1e42971347e99c12329a24b73cfbd07ddc629ed87dbb8ae1dd82a696a526e63721cbf3010d5e327a6b4854327e9dcb8528585320a4135bec448901a14b7037da06a7699dbacf03919f776990a847ec127890f2423ae7e86863e90732a40928711f5dcbc38eba531e5b12234fbbcebc6f5181e23463807fc8f7d8677f514aeac12afaf988c68d8afd5917bdb15bfe9303acb804f0d1c126e848aef4351000619bfdc31bf74441116bc9d1ae5771debce8131058aae07ba87c503a07f85e21ca25910d10fc9872b56f8c7d68aaf2c8e525dfbc9c50570c0747af243741d3dab4765587d8c25d393acb2417675d1faf59851bf853d6e6c3a6f789ffff296bcd2001331e8e79143db36b0fd1e4fdcc6d98593e19a69c3caeb71358ed8466ff2294acc9a85df4b81dca83ab0bf508eb6321d294001f95afad4bab0e9bb2c51220864b5f2b5b17db45257a0f89d890703a84f9f4284fb1ad50bbb7b933aeee30d8f872c200dd003d9f48a8ca490501241f964d3c70a544a71dd8871ce438104b80bb3dd3da8e3f0663caeaca97f15c89627da17ffb69a3a16282cb9d99166625a52cd6ad4ad911c81f5086a445b8574daad901d7db029b9efffcf93bbab71fb9a1ec072f67e7628dec0d21102c05e24fa8b9b97a3f64175e55329cdc64cce560e442c836a7e627038a5fa81888919d42f4c4f5ed7132552a21361759274eb2dc866f8de9c325bf4cc4a6fb3c9a4d1ada4a0d1fcc3828f93ea8d54e4dabdfb6b57bfc926466d51ff7471835a474866dc9da441568e8d22bb55c36c494d9ee6c34b908ac4f513623f4ca74e29c9343ea47f73bc5a937621b61f409915219cf3f21e4eb3b437d0e9d7d0e6416a1a2c0828bdbe8a3794f20348c4d72b20a8e3d13044a0500cfe1181a7b5a7ef144906d18a273b7655a13eb822b2063dca8324e7594761a3dbf2555603d25c6686dbdcb0af2747088721e70e18272dbeddfb02384c3326b30c074a78729954378b6b49202f29f6edcbe45e9eb26a8b3295d791423a933ebc310d29e3a8cbbdb0f09cd3dd1e985f798556f4e9d599e6f54c78f54ce8c3d84a0ccbb8ec8ba11c01a8f1569804ed3d009179e1cadba10266465e2c156dac73b8c4170a58505fa484d3470f0ea752829c59fd489d6e0306b1bb1f87f372918f399cbcce15f4ca31f07d2638547be292a1716cc32d2c786277fe6cd859ae46752002e4bd318fe9884387b8a8453f6f54dfab9041e776f9c6cfb4fd71865bdf735cabdc2e474a1188a3bacadfabb4a3f01342679f937de7c7e7438d54ff0dea35a7899a672cc0bbd92f9098fc28804236c0eb9ef98e88263bc4b7bdd2377e9df62667b424c0b791871325885e9d588da86ceff1492fb4a4829a171f2473e2d14b5a861fdb34 +expected_result = pass +expected_shared_secret = a9d1121a137441b98f2d6abc730eec6cf3ac8231bee94c5462ef3cbbc34aafbc + +comment = Random ciphertext +private_key = 5563263a166cf2404024339ca688871432987386208dcb4d3b058e004dbae9817324b9ca2bf4cc2aea824f70a557852346988695c71d4d860bc53ab1a0007a21ca02ae32b12c096bf675943d141b0556b7f51c86f2a770c23108e9799a3e04be57f97ff393c1cf314fd5866ea258bca9aa64fc640d57e235804b53f5bc8e99c5a4524a3d4b1b7cae4c63fa23a09af3c4eb72a3b0a557556bba881713c500c29ea4bcf7c50a285763ff684377d7262f29aaf3445bcfb496517b09e4b4a2c1d7808cfc4ecfe79c9737114253a96d2ab40ef3c8eea627b96303f95b6f0b54807d326b6426ce22011e5fe16b12263038432576686027d81dc32894437b797c88b5fb723a8c9a0e57370600220b2ffbaf09acabee5582bd32604711b44cbc920d150b54e291d23c68dea799f2329df22a94416797b0427c8515207565408621cb5d342435335116532e623343424b087f84c61ef8c1b3eacae5593938c8aaee58a3029b899ec4c845903716325830616ea0c9ca8b489342eb363630923ca482ae172a3219197c61caa9e15be4077c48f349042917d2f94dac53c995bb235e5cc092d547fddac38469b0d11157d59150803ccb38c1c6379a1226f6581c52505a3c5f8731b8a198705cb6685ab8620f8bb068a5893366c786f63ac385583906881ad668ba893d5d2acb356a6b77bb908ab8320be110c1e3867df71fac250e36687f0a902e9f3224d24311693923ab84c7e93a7d0607c0b0bc140bc40c771185a0e06e116c8dea55cec0e0ac9c72313ff31e331ab0a93b25050c2c57769d5d74456c00374f8098c8f5478c8a64d595a7304446b52aa0f40505e7b5923df54411834706320015e6c9b4470abcb4ba667470eab0b9c457960f7a034e34810f23a9ff54bf81e35e5191122f696335574ebfd436f4968b0e07a2de13441c486bd4c220e9851e165781e38b65f0b0a85e157c719199da281e174a74dd3c1e553b401db476069579222bc1a240431305a87ee6b314d094d234a71f93c8d1609351773c1314b6c9d3351531bc8273901d3197abc85a71c57fd7b956d9e960792489fc766cf4a9848ce2a74071206c576e63082b9ab0802668882d824e8293989bf522bc9b91909cb0bd072010a0300073123ef08c132a098bc0b736d6a1bd466473007bd523954be8167de829d271a3f5f4c788bbb8b609637a381d8ce289cad04098cb307bca6e653b99680ab38f0ca087e175730017da9108b44325372ccc641829a29215e5d54cba5b88ea13ae22fb79f9b4cf43843d75202762a89540c65a6fa96440f891a7d1a259d46856375e793a98c1232bda7a3335891101916931357ffe46261d058201f625e0d5398a963a3d524ee6cc8400e398e2f92194678171e856e9a8ae77fcae53d9ba54374f9e000dc32c2141f0ac901c27875a39e30ba97a043a59bb4b37f094b4bca9afe33748bb1e88a343f9273ac209503471413659bcebb59f0f6c8e1a36baad183654eaa131694217c94c47098f6975653120ba5aa015d84127299bc22318410098a1c4a405dc4c5ef54c695bb4594f0a8c924b381343bf40e2a8b33985cb750c1cea2d1c2a80009605dc98809e71496e193e11c2007b6a93ff747a15c52711072988767718f917eb6c5edbe97a8e30a90e9b5e7935146a9000490789cb0ccbd198cd2d70bfb2936e4e6b13384120194c2e41c6bb982803023204da3641c93b316330cc0f6cc1890b69c9cb1ac41797d3aa0fd4da23f2a403cb077a0cf3b0bad55bcd0ca1899475dd7c391f61bb03458af1454b4c34c655c9bbd1d54336461889150577c9336192b43716ba4515897b105f53f8b278f291fc9c9608806d6b8863b09b272b9408b096700901204eaa19aed8b051512cf58c7aa92c3b462a0dae90c5cfe222afcb455a7c58917a2f61d788fcbb6e0bccb426ecb7dea379ab974c3953579598a3bb9c0497341f9b34c82af370986c860476ab81b9a6a01571483b43f9ac35d8072190876636a5b55d3256f3bc8f7f36c7cea737a4281274f0c0bb115653155d67c5b4bb38c0ec7967acc288cbe82654f521adb31d2fba7546eaccc853878ae5425b8a389d1a92acfbadec133145f2c8874aab1a756c5c81191227045b8663729a0ca4e6c2148c0236a973ffe9bcfa81169d1c00d4e7483b75a600a76f3f2549b8962909ba6fe43885edd4ab4996cc7443bc3c073523e26000b4395174ba92415ff8a16657a16c564a0e41b26ce2208a463a4dccd69db676500da330fd283371a7bf8148547554353a3360cc825471d3959d33aefffca8b84579055aaedd47626b9a0f237a0fa2baa4b036b9960cb6d9b1a2b4934fd069b6025307fe4bb708e4bdd85508e07b47cb1a023242a25e40ca87921623c1ccbff1974ac9cc71d55bf574b545d3362c001d10868bae06487443704c2c3816d147280b935a4a163902aeb656ab504a54a22ca904c31b181a63cd55363b108d3118a51134abfe051ee3b6175d023fa1b292db134b081095d6d56cd998cfb6ca0e3e5617b1412cf5eb5bb3d8b149143a284081de600faac52b234431d8385c326b2b3a4736e767abaf62cac98a826c01c4b1a644f489809478a9ab360ced063662689809e2a89dd466dc6ac9ccc9c5b0873134bb0055a371cc8a0596921e90440fa0a40e51cc61abd74e73879c7a8132425ab0581102b5488e6b85280eab70710607f9281054abc9cc1c4d7740469e2066de2cbc3221779aa6096e9a618d935b3e9b88af1926cf7ac1b419bb1ca824e237a7dbe05df73536b69523ae90c580f9541e0bc836869325298ee4f8ade4a022f20795869cb77ab32b6895853df150d8117c72247386da591d098bd739bae1332aa098c827983debe99d86bab33bc63c7e925983f416e4f0c371d08799d85f45378f0cb44553498ccc82ca8a1b758c3a81fb75ce2cc26bf5da1f1c24468755602347353e791fb05609a3d4aefcf3ac9842a660f42634b73fa47b78e97c7c93f4bb721c58ca584fece4890b049e05e507fa07725dcc4010d66ff6d9b081ba68a7143a9eb91818b5b5564b86cff09f8bf0907980209e890966fa499103a1771c15ba417bb3dc7a37d261ff5cb62fe312603ba9c4db33d2718e0b8807325cbadc121dacfc965ae1053640c26d5335fd391d80d2b381274a21030df9135558f886525a32e4fa589d0bbeb26376c74962628c1748f00ed0b229180926a940be0a509e52547b1d7c07f91cac2c93bbd3923eee545d8f591b889be661767c2d198da889b00e7802d93add43a6e3e9591e1d1522f8f030c772290fcd107c8a1f9006f4aff8a6aeb4439fb0410e7169ff4e847f885b501b032b69edb4159adfc163e9e34e9eed04221f62dcad381aa78eab653f6a9afc +ciphertext = 88d74278dbc5a94b5d37fb5a172029902f48b84ed6eea29d26e2094d5553790afb59d992cefae6532d5f224c96dae06a9e39641260fe6d9682a74ba9ac11ea1721eb79f7345adda7d1f2f5b12b69a0db708bfdfeaee55613a7dfe67ff8099d9677bb633a9ddff300dae09fd8b9f722c2fdbcccdd163b549ac2e52bb8569935cb030d0e032a7a2b59e9d518892bda8e9f4b569f8892d02a32a547311ac32c5ce16467e11b1cdd25ae274c734dfd84836146e7755dd0de590daf446213ed7da37358f1a49964fbb65d5b512b9bcd2be2fd24e4ff9263971962776c3eaa8b7a5af83a5291a7e19d8ca0fb7516f4e5bae5b064678f839e29f8f85ffc3e16245d8f7a117f7b32b20825f8efc5778232cc1be8702d56ce61d5e3a54f7aac7f25fdebf5fe7c953e03f103c6fc9563a5414b321e0fe4f739d7bb9c51177766dc89ab66215e1526b35eda38b91da4ee26b2d6d2935d912267df162176028dfa448a748b66299393f5bcee9ecbaff19bd40f8e2bd07c8de938d8d1f1ffbedab2a4bf8f9cadef421ee7ae07d0c60d89ea81f18e1c8c36a6adc473b1b9684f325832a2b5e067a9f275d2881a3d569a8c9ff5a41ba2109f03174a8e28f0c4396647b69fd3547d345e3dff677a56f7e9fc1facfa393f0138133f9b173d571cc43ba3174ae4f7ab52a3437ae127be2a352e99a6a176fff9d60ee2683b5e7be29d4043da6d139d879ca57e903d0ebb59e2fccc1059a10e583a2c3e2d549aa940c8f586b7b4b33f575e133f5d01941bb138ebcd8e5bb1772804818ab602b7bfe50ec5439ec3249ea21636f6b3db85dd17879f8102fa072537a8913bed1e11655dbdc88a49cc95454b7792fd3b51aa2fc361ab6efe6b3f146cdd476300cfc0dd44deed24d89464b6fe3ecd3beb341aa45ffe1612034b2907ba2865ed681251e87bd14e46ddfbf59e822dae952de16da4812c083c14ca6998fe7d46827d73bdde6e79fcaafc83bb0f3f168bb36559e6ac3ea6c8ea1381c180805b6ec6658f822518b380c7c8eb7ba961f35ee8cc7133eceb952d6d48e0c58f7be6e5ec78297865f09653ab1a2af694334ac2a9da3a1131a6bab197d72b3e1acd1c7082d61e643696ff56dbca20c3dfacdcded9d0dca5535188080b85135fd2d4ceabeab2e3d81413949ac4385eee258f54e12a5691532b8f860070952a7df55cf5d84fe7baf9f13a488bd32fa8754f7851cffe67252f89bd164c38aa6cb5c48a68bcb3b350a01f29dd8d3d7429bb774cc42868c6b835f1cd09fb9fb5719180b662adcb9d44ca2c2032338e38228de0c429c1d92ffd745b0cb1502a3af031ce1793b76125a2c97fd14857dc4bb6f214e99e2ad9b6c505e2c120af5ae41f3490698dd3b6a454033e121821331045c92059ccb2beffb0c8f48c9c7909431488d20e6dd83275e7dd05a65ee2e651c119bc16b2d29394f12ce4b65ffbc94a8dfa2f3868fdfeb6a88cc9c6ba68ab40ea58dec5c94bf6d57f15dd7bb79d39f62d969a3313ae5adc4a4510ed56bf9b58a229dd77 +expected_result = pass +expected_shared_secret = ddcbf4a8e934a4eb0941d6e3032d16c60a551a285e9a4782dd34daa156837f2c + +comment = Random ciphertext +private_key = 1fea5fb8b10feca39a9dc800a252a99308961a566433a34f8461427a81a5776a22e228ac574627ba135198c3bdac99befb7322cfa84194000fce9942c7948b8957c43d877574736ed2e27c3125b02b3104c45725426581741baed9777de39875ab347f1ec92229279524ab361c1a161e93395c6346bb19a87c458b653434a0b4160632a077060fe9d1cdff9773d5ba180ffa980a4829e5a8727799c9339198b00ac14b559399a437de074344033aa5d8caa2a840158209fdeba99c048fac95af17633f01313b1c70389e2900aaf636aaf051f2792c93a40c0fa55ce44b970bf96c4fa5b357a6ac4342275361c0e0d978709b22b4f83b76e7983426c86c360017225db6e0484818289d462749f69aa283c8b7fa3edd90afbbe053790b60da7b5b958403bde76def2aceca690b07925aa843547c0c6b8acb97bde3af4128ae48183c8fa75d819c8a54736ecdf44f6de2cb753190c82118c8542671758099667117e3413e0a0eeb7a4ec246879e321e170bce7067c4bdf7708ed3119d5b057e975b612367bfd8508b2c55e952282bb0ca1c6178f2c59ba655316cc00b80e0522067bd971b787e2a1f796285274742a7091b17734e3c21a63d4c0a7bb171fa49618d115a2739a244b3cc6fa610b7ec6e712c3ebe37235e29ac15424846331827824da669ccf94a9884226a774010746a072d7913de32619536970c5c2092da5130660f45f36bab11aec8535ae2547a9c318f02204c70787bc0ac4e5b2a4d5e0c25ce7730fd079304d004c7451b24e0556bcc91f1960ef4761d485551e8c5a099e5add29a3d90922a5e59bf882bc00a6b8928468d0f8cc54a183b928078f604ae9706c54d71c4010558bdcb4330bb7c0a054f19aa9cd59c1271c6a78c80cf4df5200a880a8b266187d8821e7874cf367408b4948c8cc2448814eb913f29c5cb8d201f608467cc49b1ebf4cf210430d78698e044724e4c6b083b1ebfea7f8d992b958b8f901b1b62d42d40127217a09be895c158d64be733244d650091db8e8db739a2706f28ea8b072b0583303d2fa1afacd44fb9464620bb55deb337b86905b386b80611b29491b6a5291b4472669506b865318830db4b17e0044b25ba6590041ca9c25c3111eceb05175b385d2862d1478e5168491015b84f730081a8a7995002f58537310b5f4df729f915cb3bc297116ccecfbb27412461bcbcad58bbca05534890f5256ca8bb12363b0116511771ceda10a4b0d0a3f9a0571f5a2d8ba479d68407285349bee9978a684dcdcb3c3e86653564c986165d21168d4fe94bcf66be6e926168923063d7214582a3f817b97f61a93205cc2c122518ea6567d23c25d9bc14a61bbc1338af1c05ac879bb371c39a984aa9b8bf0f0a7c24444e48ea05346b28a7075a6929cdf1a23560cc3a3dc80c9d8c41d82a2b052b131f03b9cd42c56810a6b17c0d49d4a27913c2fc83883c874c5b743f32d188535310c632273c96763ed65dc484c7c24480928462dc847489b00237371dd96310b354add3b2b361ea4e50c03f7327466b4472ce3ccb2a14540402351cd647f3618dc562c91d162b6febce168788dd6b7259c46cc901bd690c79e3c9010e2c460c0742e95ac6f718ae8c831bc69bb869b8326465592bcc5ad49052dcb78f83268d200aacf0a00e1c8ccfee84a0b48c2bb4889ed99230d78778e940816ec620a0a971e882c44036ba44f55874ea3bd5f391de34c62e084378745f1a3501c53675cfc79aefd77f90f64dd4068bc69436a0e93a91c02abb48a31a9c8469c49c8af3034464bc3c7926d1418609dc3367b1a41841070d60b5b451755036cd3b6a2dc72896ef8402e83024838a063723516ad6301b15cd4a271adf9c4442e9166585509e4694d2eb3cccf36fad407ce1abbaed7846d12b5b542b151475861d3cbbb7d5804986529f0430f24c4cfcc826d9c57e2fc6caee6216c8105a8b40877660cb201c07cd3725ab3719029a2fd7400c6c6c91870238acf8770cb8982e650c454000780c748ccabd765843fa033b1b17b1fa672ca36874cec79203367e8f8169c211989654cc76c28537d823bd715e07f119a1a94f915c69b6a97c559c7744b950d254411b85be575a9e97589cc1f94d6c3bbfb29b35296a9dabc6c2bfe53d31277a76e72e99d4cdfc6536289a8b16a7b88faa600dc644993266a428cc07d22e8b253f2403bb86793862574f4a756b2e1b0b58f6b11973c7a87915d2a09745a0441c5c583d8a518b311e38e69d74a495761c5e976993d7498c142913eb6784ca12735fdb2585b1501a044b56c3cb25901df8972dc879119610146cec02224b523540a9f3515d79245e9a99a035a7605977c3bfc41e5650b7caa490ec5bab98c33b630161772ca58c90185a634ea515187bc6850d766a94c8ceaec32f6fa688455802118132bc0c957ef4b07db33f34aa22d644165532c92e3208ae86042d267a5308a2a9ec22c660894acc48101636b85092f4633e91285c0cf7be206bcb7788b6e12a5a71c9428017c93ec3af0794779492c5a6f096d37185baabb1c77c3a6d314d1eaba8215b12ca4a31761cc4a48cceeafa1a098a2ee16b8ff5248b69aa9eb569369b59555032571b515cc8c2af35640649e2c89d59be34b384745c094a8b5e8a851efe2579044014293b2545658c5c96a75c8047f801a71a486c5b651879d3aa4888576d5295ce5a6928b41a03d462dd0167f6f4ca2109acbf390be67a73ff951262a8c115970503411f78bb8744e484f26721e90bcc305b9c7a219e4f279f425239b890a4ada1c13dab99ac293d7f1104299a7bbc37547d3871321ab222dca70e0772360321b46b6b52d328ed877ddf1c67a10b6c12154acf7ab05d52ac79a18e47c3955aec53cd4bb338da670056cb594509d0588bb03506040a7b57a8984e3629ea5265f015b5b0d0af508a0fa96757c7bc2176d2988f21154a067eb1765ed9da12ced898e93573a3081191c721b88a3e692202798ba1899a34990c628b9531c43b29d1c8c82d759c3b2801659ba812217febd26a932c3cbf90a2806c6aefa088c16b4138c1ceded9bc52841ffbe1a6ce2b2c9df57fc22449a3bbc4888171ce873f6ad0c2a136c5ff354fd16a089fb7300e9056a57297ba411706515c4ef337f41ba6683ccf3c486063785a3f24c52e3242df8a190b3662d54ca45c4129309333df5914fccc2ad3c782e8fbcdd1750f199a6e4b37a24510101083a7a288493b0b10e7737e9b9914a96290c238bcb91856729ba633020e8f4f2742230cb64f4b7bd3c39aba4ebba70f72ac26c9f41d3fa9fa0d351e055132508e714d4e38a781538a92ab90e8b40373ed97a2d5c30d0b2df6abcec95bb27e2336fdfceaea5522bf1cc5804ea06903 +ciphertext = a3332a7d121e4fe145c2788bd6199c27c4ade8d0705795a0a0d8c7fb392940599d936addba522349f4e07a451075d88362211cc692ab4e7af11294ebe881ceb263667bb291b5d3d419424daccc5d275bd2d10c7a2f8f22ef0c117cd12741fb3dfc8449d877def1f9988d486d21a084c60faf2402ea80f2e03c85e58ea23b0f0b700b8f3ecb3e43373b6e307391a0af9bb81b2e351d1dbc3715931f094d00b64bc1683501cfbef95de190023f0150c543e91184597b57c1a228418eb7a185558719ef1527d9b8bfef2684037f18fa987ba982ef99f135b827971639b4ce4cf0c5f2bf031a687590a29201fa3382668be4ccd3b807fbffe54e01176faf7d92163d1cf058d56e84e8890a6b9d1bb7ea5be4428a84bb41f5f481cdfe533046f04d6e83f5b9fe9b0a383e9dbafd34aa8acf1b6e66edc6d062a0cf0de5dc16dd5597e87d8fe84cfe182a1218a554acb449d3aebefe41c7d7827402b5e66a6572735bf21b1cb3d1c01f51c2b07dac5fc024e6ea9c690ecb66eca01e65ad4947b69155f7bb297058363c5f6cd093564a240500bf5f7d2579a3c7f4d9c97325fd10e2842056a4e246a30cc2d5f0c5b95904550eb81d9ea56dad663a766a79685a7cb64e4b784bc37bd123ef66ba43ed61a9456a0a4177c0e1e4112181caf2903d6b57575c34f5df89232204edf02268168b44f0c2acd435f7ba45cf2113c3fbc0303541b1c7554f1b68a01436becab80e86e88493f658755ef88e0db8c2d7379ead05de98aa787af70614b95b660ae28f53ebd12f582d1ae367d7570fa9777bf3d05aba1b7b75abf863ea0a5ca91d42bb4d282b213666c87630ff4a9615b35388d7a6f507cb4f1fa8a30d98eeb08843d7628864da17ac38e42eb9adb9045a2061173cdb246a5a55f019dd1bd5ec8c4357ed2e45dad105b6afa74580d5bbcb9151153ce50d7ecd0bfd88d22a57c373e6246dd665d7d8a917730970308fe7d8cae9a63e03ccec6696d59fed80e2ba99dfe417fef7fe2261caae76c5db20392fe3add53102787a06ea9a851f595be131654d08bd011726070074058f2e04b282a85f006f935576c9b1b6c1609bba178269bc8c6d4caeb45df28e827ec75f3dfd09348e3b92141c2f6384336c16497bea7e8694170e57b0ed67a0dae1b869f9361ca50b946eefd4e5503bb93d5c4eefe0e911f7fe19f8a68ac2efa942a1712609dff5bdd04d202ce423214d61f75dec6d3d86372c0b4ea1572b8225b5eb16ac070254b94dc6108f52bbae81a239a521587a9f15ba38c5207dee5ec0ec28666b0578dc514bd57d50534ce43b92814c4025b9f6105a05da50385f20b0f313990edf80ff3fb4cd97c1d5da137851fba5cd1d846ba384a7b36efee3f95d195761deb8f43b4715d99e37e88efa1c4f1b75f1d3ad2bd508809eb2dfe127e977fd378b83c90a2182764cff83be78263bcecd78ea3cbba374855339d917db298cd747452ed3394367e255f53a4cf4e9c4c2838a1483b980bd613f3c0687c01db555ce991cb14cc42af550 +expected_result = pass +expected_shared_secret = 54893c7f77cf00610344e4abdd8300f1598ae8efd2c55d8b038ccd8116b61962 + +comment = Random ciphertext +private_key = 62648f7bac2e9ec9a682d09a992ccc1eb2720942006a0502c4e1a33b641da8225aadc39a86c13e76c7b2b0fc31842340cfe231ade71f887c6af3055461eb85094894b69092e9d8ae04293809451887c61d8bbb629e14c41da75092eb0c8145a0940a3a400a4aa2d9440796210f04cd6c613065b62ed0a1b77ee354f8f449f3b027f83522cf64678a162aab1ca728e25abe817de214bed3d4a6b863c1250a1a23d2830a34b8456052caa36e0251340c1b7efe7683746362d4f7bad9679ef1284f0ca655a4dc094b5047b26912d3a8b0ddb13791e8c83589c1bdab3051e533764578fb517415576dd6acb144f1760b075221120f1cf638ccab8b63ac21fbcc419103628a84365c61319d326cc3411e00f296d9802806c2994b57acf5f7c9a642a0759269780763038324e3e3bd1a22c248b386dd880eb54247d435c989623bfd73647fa621d21c6cddc041060a4c6586409b644750b88ddb136b2cf40b05d27de603bd4715b8ed053805803706241eb4f7a32c2c56d190229f380a718a0b47a484a00c3efd6127c486771245312c7837ff2602a84b998df0bcebf433d95649cc6cb786f182c9e169a02abbc6282684169777e3ac1ec55d0ba23ebd8ccb94634b3949858a853dd5a7a1e3e1548d6baeee439784792f37a8cc820a0750d3450f776b58f35ed55439c865b0d4c5016fdb2eed5215eaf5972cd4a97da23f080c796fab11ef0b3419d766ea687b3e30ad0ae6a347fb04b61827d285706cf373879c0831b32268373591d75638e68b729c9ecc5a17565b325b42791c8823c62b39c4a4cd626b2e411253ed091192501db674194b1645378cae4460b2f4d5917a5478aa3a6ec8b51546914dda5754b81746dd6877e000bb006bc6a861cc7a4badf6303ff2c406156bb4b9f7a324b5b4b70129b2b63c53d35e1b30c0e07bcaa83a94c3f24bfc093c074c263285446c129def9c9e7ef8abea755360368d321c3b6a93c2bd676a4d583afd0704ad5880b45b7face065c0ec1c20930c720252c76ac785622c05d629918b89889445831465ecd16f523ccc6c840e6683053f481ec25b9f79d930d62a86bee62b92a6affc0ba0676707d6c4674cd0cadb6b5f9ac4a573c6256b81a047a5500153864e3b6d7b125109d44adfc4cc1cb15c42c8b582d23c00da8de4f994064c56ec8b778037c0a022b577774484e47316e38f9e998f58c19b2cd49336b2a2d3b84fbe0593b948421eb036c04860462a17b5f47e8b340ead20a26e63bc942ca4a8d255e916ac0ae4ab67d1a2ba9ba000e4b941dc9955475c0eaa295f7103a5254499c52dc1d35aa569911d420d1750caf8c89b0ad6329557963e2568ecc6a9560c480fb343ab3a158229cb9ffa7a0ca85147961c2e1b94dd0b3b597b4123da772103a724d6c3758603cdf314e285a2a24144bca792fed08bfa9956e936c90348064e8b962759c47e51320e095118e2360490809d055b695ba25c2694a895b1486030d4f71c06395bc6c56880d0671510bbc7246dbce4b6cfbca2ff23ca807a120be22c4599a2626014964b6fa1c9aa0307c7a3982d12182796642e44039f23686796d0ba0eb58b8ebc4a3a68b516004a95a779bdd43d73e5bd43876c117c31ed734e436456deaa91115241d850161edb4c351a93fbb0cd9eb4a82e41cd7ea0396500cc0d7a95b895ca5731469231804ed727db3866ff3173d6d16de44a083ba02826bccd06f28a5b40551ac33735bb44f5c1ceabe63ac43b4195654f22f651e9a2043a062f066340ab319c879817a0760c0032743ff65390c3a0aa1903cb06b4569a234ca4243f6826fd574f94284bb8d19f4f10aa56545b14d6a02c4178603ca2235378f0a05ca4d999b627c8fb9209903b4cc19696fe0b0327771c1dc91df2028572118259409347f160d9fa2cf2c366c759207bbc2296a7b3119c82122acf4aac1910b3c2e91b29fbc376bfe38956974b41d3a35222866136c0df6a75d9c715eb9535a022b25fb931880a6fca3787ac81731ef35060b38ed56ca7715461e8f381d7aa762c02939017c41b60c2d2a85a7e129ef3c550cfc41b2cd04b66ecb3c2fab9c3fca5407c51a1b212eacac6cd3c9ab7bc96eac45410803c14b9ce4180a1798302f9a55e0cb95c581abfdebb5ca5d8ccd9c55f33881cb9791f41a210f716a6d7dbbe83907bda1825e09b32e5d96661d961fc838ec9260961da4c7adb9ffe7488adf25cd6e95eae9666dcf200597446aa1204838aa71351c5370a4282e60443f59ffd69b396e14b5a863f07307b86c65459127bc6326b368c90cb3ba98d235fcb9b577c027b3be03baa35587e4b8c05d76571266a222076beb68fac111bcb2a7802c48a123c0f8382104c79b59ee5c44d7b6157301cc78a60fdf57729470c80a08ffba469e0606ff083cfef44034ad7bdc06139011c0da6b6aeba7681efa56553045f5787b170fab6fec81e5fdb839eb42b8d3b8c5ba3852a32ba332245478c8e35b9767294b118376b28124b94068697f41af5e90773c6c420003eb9813126c74b20c0a7dac02998c99d6e371eeef35591c63ed6c0b5a8434c948bbde53105d6ac98827204d69b7088b9624f18468c549064363607d2b5c5193939901ab257cbe7bb0b329a01601a337e38a9c33ccc53fc7f43250e11623cba670bdbc79146a05fba23cede150d7527970d633b9600cc6415ccf4756d50114ba92740be9116418334e5a463c6cbb79902bc7bbbc8560441d6e81dce820818b0067628554c1581d1f4c57cf3612f630d2c946b1ce963d66358ec0443a7f860b9b871eedc636bbc90edfa6e09532523c268a3337862549439001c89180b5800c5aae56ae725042d48ca8877ab3de16a2698b1b800109f6ccf7e6a18e0856c90071229b63f97519f8fd19576fb3965fc54776318ea279d7892a8db98790ea8908a708a56333917a29d679092f06169184c87f548914a168dcf5676b310a4c909aa7c348443c142aaf489d9ba3dc204984fccc1a6963ff8ab0728d4b51459655f152ef03c7490fa4ce43407c2b45d96b0051da8b797476582aac9bdca94621a3bf75178161c96f88cbca0356af47422e4606a6abcb0b4e9a8e17557c10b58566924644c0cddd8096f8481b65c11bb2748bcbca48ac2674aa81f8aa3cfd97998acd7c0e8e8057a1601c03cc7f473beeceb35cd5b8e5820b54b0b6660c84ac5bbcd0f596f494a176f93a505053ff2718268ea882245a5947ca9adb0bab95cbca280c14cb074f09030b6a09a5910b7b3442af83136461c1f0a5da885702d1fbcba7b21859e4c2f1a2beab03c306a4273ad3a20baaee30e9b33f67c47474427d10369983f60f939b11ddcd2dacf4d7863869d9625f7cb6b5ae2b782a988a0245044b29b +ciphertext = 8f3c3c0bd7ab261fe7816a9e37c7132fe93864a447226c84d69d8f5e6823f60679d2beaaf8db5c9b4564882a4b696441c5abfb3e9c84c177363e203dfa1d9bdad52748d97813c5e4ef7e62619b005a5934962210d88009b0678f1b8662ad7dfcb10400a93406cc809ea06810c21d58f0282ccd099b616f846bf7c093972e84403c90868fa13ada9f7fec375e464367ac59f7ee6bd971f6eda3aa1a8780aa22364acc453e9a0c60f22640d7db10119f87c4a20e04697b6681196e9475134224d6ebf7cccf87f72c721acaab099c66f4c0ab6669f1d1c74e31f6e5ce13ecfe006684a7b670fe9dea8eab1016252a96f50a20540895c6d0d1c869466b62c35ed4b6e5659dfcbd0da8db530518bd89ba1eec19b01073e7f51ca548b888a586e7100cbc6a8e436aa94a6dabaed9d889093c56b7c89d80233eedc8127facbd91e3b517a8c8dc1cc20bfe23773ade950a79b053df9e1e25765b06cff75ac4562748d55161c5425ac5c8ff824d4b6331cb729bad065f30d9be54fb69e8b01fe712f041d156946accb855a01af8465247240b102d1e50540f744a266bb35245ff6ca3f72183f4df551efb148cd717b1446b01ab774eeed39ae847b8d61c04538f452f54de89138bed8f553eb781630ceb5f80338b9af3d1919f5742907062caf83ea89973262b41825b0fce41b6ad6cbebcc17839a6ed1cd671502072524d409aaf6d149c71ceea7980fe65a568163dcabf38a9facb26abaf2e712429bd463c7d4d25410ec4a59213db4017e9c19ffe993cf08f797d20ccfb1d9351c1ec24b06277e3055f89fe5c5044f16a046222d3484e34a03410542ec15a0eb73a86fa25b9d36a239d0fb03e8646aa60a435cad13f806f7c806094da905acf7c2150da4d462429a11e2f4cbd63994614ff7d292936e74ff3a1d936aef30b133969dbbb9430918361ac3ccc52347d4b6a5c963011134b6985d2a542df1aa59c789beed11c036a1df3e94ceb4417f521689e339ee341d79945b20a4e3dda4d34dad8608ed4cb5fff2e33cccb698a18b743cc29d8300a93a709b0b88abdcfe335f92de475c0e477e2f4fb3e75407d8922790bca55e517550861a7e63bdffa31f96157836019cfaead37d9675a71c742a32951526fa01ae9ffdeeda1537faeca534bf9ad0d3f2968d1d4a017addddc7ae547ee7d9b2d9d05980ceb1171fe3bc5c26895e4c5805743e05f52710798de8a7e9846139dd0d56d3762029e9b8fb2b4dd3e9b8a33b77118b79ad5a2c2d665e10dce38c2de2695fb54cb84027c2178881bffc1a12eae5506baf6ace611764fbe9647c752a8653fae47fe31d36870754921c66d2bc2f8f919ba727be30bd2ceedb541d412fd211b926bad736d0640f9f8a8c111a1ceb26976d5cf92fce56242834a1a999498f1f17cf96736d21dbefe9528951dda9631566b5696a846c0fa9757992072aa401cefa7127d189303519a10218f62d62e79099a9e4efcf032e496b41f2e6031a011a68c9720ee1b6b3edfef1d5567afcfb65e7b9c6649 +expected_result = pass +expected_shared_secret = b794ab6a6b7844d506eb46737dc78c260b475d8a18cb8156ccf5c883eed5dc9f + +comment = Random ciphertext +private_key = 0b9a5c6ec924f1f27a38b89ee508c58463cab26889afc49ece74225fe1c41a3145bae0be2f25619e276f441400f3d13f4c51a7e8d909f5736a04a366b265cb8574a6e92c51e76099f4f646e688893a36a199da2cdcd1a7e35a5f6b8c053b0cd066585f3f328af3934a165b20d5287f441a9d82db734a23b5ba9a35c59ac948c9b0240aab95597c26c4c8da8a339eaca1d8d8b4ea646160e17e1151b6a56a33b2824d7e44b267368f0b4914851a494349abc2b8061ca35b606039c76aa7f2c39257225ac0fbadda057665b068fada12f662161de1acec016cec59b841d8ba85b5015ad9896227b832d80eb7e71dcb18aafeb65063949f3d270d6a70396fd954bb247b9d8c034d438e64576bd738ba141aaeaa44ba0f345ef29385799cc71f48956d4c7edb2b5c7808b1ac9326533568a632b8fe39ca4d953b7ef8c162e53d1ce8aaecc7c9d8a5565b5195e0c8c4701181c1d171920c3f8bf71e2f394bd2905999c3bb3ee756673360a5694e342c83a9e09e47c68b44e3c4ee576e86184ec853aaffda13e44602c715b88a2449a1302bd7343319c9ca56e45ff5827640a30b35a992d3d37cea803bf220a7d3f30556da3e7a03251f44981317b6eec773015a062e4b1c886023b8e37662c7c5d90a9801442259611f17e25072659beaa30f499bab956b56ec0c9e060c31c58b297d561c681a7af7b8565ea2413488093f414b97c1183f8566af2a3c08f7303f9a422fd8cc64b4a4ba8ac757d366a3bbc1a1c100ae79687e49a5118b6304d970106b9f4fea45f1cc4e85916d76d48a9c54cbb6c446e4b40bf3490289f6a27c2297bc0270138ab55b522fe0f6ab01f66956dc5719b4315f22038b17363f9843ab116f104122d5a4a492843039d6bc56126e691652a12b8581511c74801513677970d71a1154a31db66c846835bf7639c13ab05964483fe99cd674a1b8e32fde773c8a210602b635da960ad4e7b6477947b3015b77f879bb034878895504caa5b11a2825e101657c0ac7f8708b59c760e02d4be2637f7a007f202af17223d99094e0090e3db2a27b48373c79cb72f7b91aa85352a28b5b4b91e41acb8f491cddd0a19ca803be573b4fda6cecd54818378955f50a61209c3c251e0807b9f6688f64eb6aa5619529fb55165c791aab1442699ca9d8aea7cb1836448d2a8aaab79299e496441b37547279acb918b03ff164b5da9f21898b1e76351aec8013705d965a9eea6b883bb7977f1c5a70681c623bc12818a468d3329d85cb80b66605a01bfe633525a4aac136877f5294756182b5bc496a7c543151397ee07dbdd3c8086a42b30b7f38f22da36b59d5e18c1c78c3175300e8f293d3d6c23d03108872bb56450031489ba41a4967f45307c49ec68197c70b2208b9c487e84a006920c5c9bf91b55ed6fa8da011c8e3c827f8b55c750ccee1e7cd84b1575923596f950c91fa891c45b1cc0494fa616802980dc314a94dba3cc5b15ded9b0a94fa2156796c1a325304ba8dfef2471cab7c202515bf056afc7496702b95e4d04880a6b86429c32b1994c41b84270047ecbc77e831a7f893181bba4a07fa44a3b455da846d099884f7a740cb8acc8bb480475619db17c8ef920dd6153e46e43ad5c6334eabc5ac515e6280793955359ef8a751836d89f51680c240df25b36c845c53c42638b686780a2b6cbac8afa3573679bbc2387a0ae494d6114242e60f17601775464c5201cf9fb3836081455b00b19497864e5c006347aa36f419c4705319c78b84b9700307b482f291835203f8f372cab666bc0265dfe052ac32cf7e57a3066640cd52c3b00c0d6ada830fb3c6ff0869665538cdebb9ae2068bd32029a292302c20ad3d40276e0be65d7c3f5e5141b0c3b34ba60160b193a57a6ab042ba1f1430037c605108afa042fd4c0af4c1596513a745d226279564a35c7b77ba75e83554991a0a88ae00f0baaa87d91717f0998261b78ac8b5e6fb4bb32146c59ea22d42466824889480582f0b33dd7b093f0549bee030abf13a656e24bc7c105a5007b0da7365967a867598e88340d65f551b229804f09b8c6e29ffc3bb52953909d0215124086f4c3a09cb27486c2b2cb90a0bcb1be84d854af86b7867b8fe0081a7e94c6ae98afd4349811910ca0268a058aac16c4a24bb5102783206a125a48e041d5f23f7c24b73af7943571088fac1bfe87401996454b5c84e10b89c871c8c550210f495f88e1c903044d904a09b8b04fa7aaaf2f70391d53896f16c5686b8a24119020db60051a24796384ed6543de913645754bd52a314a47880cc002eb1491ec8b625e4c30aea0402c992fb6d2aa51e336d933bb74772d59d9948e778c1d60180901aa13e4154a320a37fc0c465415138b35ec9b0917ac563c791f645011c76a8b4df076bec584d0a847f9a76bb4e849eb5826a9679e28f30d542a0819fa3775db3a09168c182a8ac03ccd9c31b8f50931eaf37ed476c5d211968c38410fa59d5f00b41838a748308fa87999ecda8397e690012968f1004df39543d9353936dba221d84d2b40a4b0d434350954e8192fd2419046d6069b831e6269cf91a355eb7aafe75b88728251a1bb44e0a0234d78aa7700c88e192e960a624bc583d371c87f208e527bb6fe9b6820c0122a8cb500272fdfca2049c86a1fc71fc029c096c758b28a6390113213c2607ce193b5c7ce48a12bd6c842f1f92b0f559cf6cb53a6d5086e80ba276ace365685231aab9c852a6ed049e1731a52c2b15328a59900c74c52492583c755c74dc2e315d73709aad112e8c97c2c901701aa9d4be74dc87a5d5e12ace4a8455e140b7431c4d3b103f936018d2c8f81d110dfd13a62bc535f70a4ba5252c5d495ff56b67d7ab14ad29b7c26683f92442ff914ddd2b5c9c944ec103d4a99ba70f99da040ce0efa55179b9640723071ec6eca07be24fc7b4208b74231409f75bbd84303a28750f5d92755d937713827577712008612f9983bc355b7224a918dd3b19e1b9b48937414772a5cdc0c9f83a71f45a92b35367f1826748b88df7ab0ae422054d3bc7037be1d731da6388512ab878463a61e28c3df39433d365b27f5a1bb068986f99ebc33bfa99541125452d8547c3a5c5281b75fb3c8192ed4a31ea360188c0838158169964a8bb389f4a83f9f651592658525e67115476cafc18aa1338c43095debc5519fcb17d225954ad42e2c7c163519bb1eb1a695c85e8924a2ca7658ecfa0a4e23807c40699ccbab7e70917632ffc33bce0b408abade2902e37fe12346b47789233d0355b3b2bae02a9fe88d18dc0f28cbf2105bda0af4576360cfbe1b3ffd00e604003a4fa719caa4645acf7576162664a1deafd5b003bd9f09614e07c0bd0d96da003a8fea91c4ee0bd3 +ciphertext = b34f9ec31bcb31d121a4845322e2fb19a9fec82ddc4f3fc9b027698042f5da9cdc623b95fe1098a2f7ab61313f76e0e8d119b5ee1bc5aadbc4a70582f40d5bae56ae8515f712d4bbdacbd4e01e9406f577b0336f76345e67a866f4cdbfd8a8c341341b4d5f169900379e90a68cb5d3f80f4f2d9c563473d4891f0cf7f181ccf44855a295420b8c9d93a2b2b759066f5fa4f14572fe31febb882a950b295345a25ac68ead21c497c924490e604d6643c790ad356fd907c948aad261b2a206618543a2d05471e7c63352c90c29d3fa19e52c04b1f147e7319e796c997e2c6de273a6a417c1942defae5f361215ffc1953795579fb37028acf68a4acc6cde46a99bd81d6d54ca9781c903e772c339fa75286334fbd3f0a2e5640a3508ea00353cca5660f01bde3d1f8739b14f5eca89d2a99d3296c94db7a4782dfb2aa33e676e6e0e1de0e758f3804b39fc79089b47bf0ff7f4357fa86ef6c5c5de0a3a7f67d16ccb0c1e26ae4de28ef3ef8be7e57b4d1df58787780c750e7e114e71cc57f23037e999510f727c9eaeb50024728d332e4f393d05337c3e997c5bd3b2c6575a0339dd80818bf6e65920bab775212475eeeb02edfc1f307ff092fad3671f37d95de70c354f02c88a0ff2b14debc6ecd8ff8a3cf9a9f3d96aec075d706da2e9eea5e93bf02dbf9bc385b1c7b5c4f20015540b06ff086e4e91eb9a45d43b0a73f45605991f22a7cfe34fbbb6302d31a43d07cbfba9588ac6d93dc5058fe152e50895d8cbb3741bc79c77ff13c0b26d331503b4fbd491a5633a9d3c95b482ac86342075670bad0fdb6b5463e038b4f100f9acd8f9fcd651e1e514bd9c4b7e5f1f152526ae0f0f7aeb8c195abfc4030f66b5920800b4d4d04fc9f4e8178013d1d0f915bd9b92923699570baf512c66a79b5897380ad4938b4802ebd30a005afc57af45327de2866c73dff619efae173687ef44bb8df3ebc08ab29f1cc22f4831f75ee70b681ebd159164fd1834513c382bf47d15025dc6e85ea69a2cbc4b74d753d4c014714495540ff3c1c598cf593aacf905a2dab3a034ff81affd95344d64dca032b1f95612e5d7be6cbde26bbbb092d7024b3efccc7e3a9efbf5493a1bf2c26b824f37b2817a39e7728b687ee73d0b329e5106cda9e0eb986027d75a9607e9516cb86ab0753fbf675e157b8893bdc565174600c54ff7e81310579d1b849e215669437b4811fd0950e5482c70d29b22ac55b175562534b1300639a2079c295e66f4471fac9eb54ea6b83ec3cb06ae560545737d184be403fc13a8f1c31ed374f1b7ebb878d084341a5c62fbb834f6d7a03374b832af4c762c8959c15ba620922e9f5e2de7e03adc1e22fa9ec3c76f9f2ac4ee5628b017e3efb526cff693aaaee13fa36c5098998bcb62f5827927afb363bab182ebc987aa70588b56fc6951e60354b95705d634744684a453666609752d8c8ae29764ec02b4bdef9cc702549ca7890640af7292b7eab518cabf8cd231b83e119b79ee6cf12ce7fb51acb6f7da7163dc +expected_result = pass +expected_shared_secret = 822255fdf2b40392a52e30ea1010f61b8d9e13d0843a859136e53c6a87803cfb + +comment = Random ciphertext +private_key = 31586f3cb882cac18accea629f8535b5cab166fcc252258fcdf97cff8c6b89f0c4b725a225f17ce14a54c8e984c2604cd538aeb73941404913aae4c4e76468653275beeb13fbd00e941979fb48af62c35a4b01991b6c8d7a25b78e0084457ac179928bb6f13780ba5daff3062cb8b610c1cdb36001ecacb58ad804e445a3b37c3f96a4121d50b35c2bb96104ab174233378b2fc2d86149ccc4c423aa51da2c45b3a0f5962e670785d5b5c85a1730cabcc9e1aacefadb2c8cb32ee8561e7719c716f885c60cabac054cc16060afb21279977c98a2141a8823769634f3d1547ab23f9eab7e738b057e104e305272e04b06feaa3cae7c89713746ef4c5982f1ab683b69e4c3bc5cfb6167a39dffc6bf9a138670485eed8cc29898a93e60998a9a3d9ac77a298288a734ae2b40cefab7a99df04ec1346b82b51956a03e6cc5a7d2e23148c5344bdb7dcec81358d06f45bc4a67a1c871d989e718267af18d12a38297f918bbf22993f60401773690e2afb7b740dbc3a7d1e122402981ddf74484b30aa56281e19c2447c544d75632b85c29ca4117103062c46252343c203040b1f6f0abeca550d401941b7794a15932aeec6aa0519a81998026855ff9aaafcad98c096327758c90d308242c413e977906db1327ca984dc97b2cd63800a8d9643230808b53545cd7203c213957247a811ccbebfa43772cc1dcb1bc921577273413de8471a81775bbe3c090f76aa6b6ce80cb98609697b9b78473f2878d67218bf6b47200868e8a6017566d3c40a1b6626dc850a9b2b8a72c81297df525d1930bfc9c541305665296b534b675bbf8c175eaa76245041c838df1b16b83ccaabe81040e13b2d0197471282b15d44b00621c98a696f52491d86612344203a8ab794e0c710943cddf4a2823094ff4bb427e54a34ba84bc1848d38305e481b5bfb7cb73788b37b3837cd705ee99252f8a0a6e51723031b82fb350769775c19599ce311559416b5dc69c3dce7502b31aed531a4ab97ba93590736a88ddc47c06a707c9daba7ae10157ac56ced392644aba644e174c5926657d438695ab3bea6106f62b07463a12b0a00b0c35e5fabcbabda3880a3840d2733f7c2566c75bfc7f12f133314c1b710d5ab9d6581675eec485771bd9168b72d065815d0bbf42096d296be646408ff31ad25411f82a0750139942900765520bba86004721ba71c16a38b2cc9ba8878ef1ab55f321b7aac4ac08420143b75bc17c8a93091471cc7bc20a4adb84181547d30fa8d6cb81b8dac214ef06574e62ab1d61ccac34d66f71ee9e2861595cba14a4a1a531a5b96ad5d1b79cd403599121e9dd17e2d604765e40af9166f024526a8f4a00f787467c22c0b887fd90c77e61a8fd973ab121a3daf8a0ee9a54985a1004a22a1847b7c2a70a1c7e053f626b2d767428aaa0770c3166f506558aa05191677c161939817866fa9c6853ac957a9cf75d80b82544d473834d1d54d09c0721ebb02dcb54e1e123fab1764fba4b285c41a61650f65901ba5da7168778e18382b9ee8be4e72caee8798410180ff0bb23c086cdfe7711697c89f97b9c67a53ffe67bde3117ce77640f2a9af4f7c1ca48118c7376d346114d0c2b47538767496cc9467aa8ba28afa33c78cc784cf59122c2cb32ea15a6f3a44f452c83b409737529f790c2e1f239319125452a9c470c403200cfb2262c7eb2a5b053244e3553c1013f598a3506176c05e6a790b5186163bb83372aa2a63fc1315b5b4193db3cb8a632a904fc19a79847c652295ea099846aa4acc2a142105f3cb13a8ec73faca1a06baa2e79701c72f75a66d2b0368880e5acad01814fd884c0561776866005671c0f4c8a5d6f211706554e64736cf9a4c54505957f947f3db8b88ac696960891be643c30ebb27f919927647d0805203dca1e9a26c9d6b0a2b3281503e611ffd58c0696604c566655d18ba439bb97f3877bfc45abb599f90408187aa8be2695087884d580493fea0ae947c4823b918257cf676168edebccc7b447d69867889296cd246fbefb3bd921cc858295e9666fbfeb11b1510d01f171ce829769b150f194984fa290ee3b35a9c6b881d39007f18e5b142fd95525c1407a93f505a92394ce29528d538c9449a369808263004e4e2b47b2b034e5facff5ec0848a38a5cc9690009a302125e1a60335ee48875d6a0ebb51d1c452d4b8565fba210c28a407012b1e6383948380fea88353a7899e719702467be3989a9996154f6f05bbc82c7fe1b7f07d74225f21d4ef09aa2b5ace0211371402f70327a0f1585255640ec02071f62389d66b4242564d7b98a418c0456d2b920396100c2aebb53abd5372ea118859ee9ad6ce62517e65426154b7bc826eecb0a3fa10c5c351d0db2c6129899bf04c1dbe51f0fb91b22d97c17ab0987708c2695184527743af78d1b633b484aa1a607c49d3b9d98f23b6a9c4061a9b75ceb35d20103de99bb10930668098d3fdc491d129ee8fb7df49a576954cfd95cca21a75fd24187655c47c4817debc46979b1a78f237c52503a0503bbbe4c942d1c8217c71fba346d327c9c80122dfc2030cd397851d261e19999395a829d9b3696f2cbc6e1c12a9c53c35814bba28670c55444b1917fb625e61c549b9ba0586611d6c846e4f030c4f03986bcbabd7cc06198a99ae33e7ab17e76a159bc87280e9028d1a591ae89b228494c5c6695b496a2d757692f6b7a93c45b934a59a7890433d409d4f57602697edb127071a02a3740cccfd0b312c5086e63951bc8cb784251f3d90fadfb418b28a848e11bdd778ff7cb7893276bde39069f818488424498415a7d2451e9f66f30a56087510c8934b804934f9e9196f1eb2b55a924c121b8c68700b75675bfc99d68ea13c89247fefc16fcc0ae6b603decf35f78da49e809af332c573be82b52eb65679540aec76acf045e9b4788963b6838d93d60c07ef615677a4068fbf143fb69cfb066225f828789cb5c7d19c0da984049f25da441b0b20c01f7022e4b46a4677baf3af61fb3c98698eb8d578661b9606b0e643eea480dfa0658f4f0bdffec7fe81aabb2895ed71c1ecaf297c3d301e7672587500f34b015850c3232a29e9d5119fe7118e2d9897373347595512755ab3cc4c7a4c12d866036e4116e4140a2300434d0e841b972aee75b910e12c97a218339a2a8f8654dc8e93664d37a59e3109669267d31a533bac8b042652f5a3a6f7c116630b336ecb16982390b893da8901ef0286a069b7bd9681669b1af93155535d676b2ba24595965ff802a9554c920b99b9bcc842e459709d99e687d49ddb05064fd5e206bb000e60007765b3201d7e313fc0fe7ec241436778320b4a906531aa225f830c1467a823974226337d0d27700a6f0fae0cf +ciphertext = 3f65a74eacdd023bcff1a27d6c23a8e2a3a186874bec8fa4d351a2ab31dc56dba5742784beb47b640a74656f10175a0215e82c9ec86a6b1c32ebf9c1d5153e8f26fa8fa2e9c4c9e54f66d025eee9c8dcf6dae71afb6b9c40f951b810ac4c8873fa60ecbd800efa86b6a528504defb434ff3dc02e03a3926f1bf88af42445b00e023ed5d08d1f2ef3531b16713f93a0a82666fe83605cff715a0eaa4652352bb5c6875449066567e313434d58348facc180fd516c121e500e475f9cdd20308c358c5b6504da818d80126c2b203290ac355f1ae10372c27a04a5b24cb092dda152abc052b927fb332630dd712b74f96707b4626858c93edd5d08328e6fb9c8397a339f4b1f34f715af75265930002a8aeae099808d1da69ecb6dd4eddcad7c1962be136fffdf03be5a0b689252638285b2b6f30d5da86bb24cd4c182141d3acae716766577663c2cdcea6d27bd59a1c3161894cdd0fbe91e35220a597196e37ba7b9b48d4b6fca7eccc9b9c6f1c7d26436f2ec2028dc0a541fc180f263cddcb26d9c8ef80b732ee66a806ff317c81d51242f81a48b91662a78c6b430160a3c358d9be74b671af5b2f5d1088ca951780d9b528a7c014b67f11b711732008ec8e30e2d70548afc2792eb52460c37cdc8caa77efcffa0b8412d0730b79ef953a9b90b112aa871dc65192d988abc8b3aa8377eaa76ed5376f850712b2dbe0cf67ae6bb215adfeee94eb2eccaef0a6b57cce7a721daf0f9f22e26f71d52900bfb2eaa0a2edc96c81af6d03a93da2ee83582ad542c9c81f7c5c6a37b484082d426b36e6a26ab4fda7fdd82f692fc186de8148efffdbbfedc7565192e74ed37d5494daf224632850adf2df1e11d9b64f8bb8fdcb4d1ca8b662271332b2f87ccabfc7da0243b84a7726cf2681c07be79d1b0e2de3322cc4f5f221d10b030d51c410ec6ae2dcbde994fb86ef7ff8565f51d4e0fee2a0a10d93862fd275a11e46b34182db8d12e01cf5992f23145a0ade46fa3ac1ef566827b3537373ea431f779f267ac781e519025d84e7e8552852d42b3420cb5316e0e68610a5c7ad4decc5760f75dfb20fa67945be93e95a025c4476b7f7a9257820e26ffc88109de705022d0990d1c210070ea338ccce7143059919907bd70b0db618ff3defcbf7c9ff885ff03ce8e92965b0f6d3ac3a48ac6297136077530bbcb06445d953f118b648dd172a5290902700ee9fc8ed8ecf4cad560262c2539ded77ff6beadf90080e5cba8fd39554733d2acb6a401b1b3e458b6a10afa2dfd346fe7f978163c8f280d6973630604864fa6519608c148bc86b6d24ef4c7dda82cfbdfd6a0abf4a17076b817ff87d972c6d69d4300f17f2bcfb48afe82f0c433eac03055d0d4a09341ece6f706a3976aa928d95a70a9995601cab1c2f12c2a75fa87a0c23407d95249f18b2aceac24470297dd0aab16b2a1f50722c55f50a024341784daa2e23787c12191247f4acf2cd806fd76053699aca7b44d322679dc763cb7419c54375f9a46ed63f74c36e03e46 +expected_result = pass +expected_shared_secret = e4863d639f68345af3cdbed85e317ec8b87208a25ebaec91633fecdc0b97433f + +comment = Random ciphertext +private_key = 3a2ba549277afe7646dcf6923a61875a55033415b8f88085e1d514a268a37ca28c4a904c4c037e67664235c27ac1038f19999c2407c266dca369eb8f859312c8512e7f8466c87a6edf9b947bb76bfbc3b28071baf8fc5aa2fa3e5b4080d82a70c0fbba7fcb4e37fa68f0b0486b5944bd822146479940e70c7ad74a46e3cbd82a56d747158b7c37dc3c1d4349a9a39543893597ae957069dc976cbb21a18bbdb988cbda32cc3d5569458166ad7498b603248902b82f2079dea70c710a45f3f8cbd7f9ccd72a528c1c10a4c4b86ffc81323cab8b5aa2bf57a061752badd9798ef19281f89acca800d46573a5f9c484ac246dd4be2e0b758138a967f65ddac38422a34b2f65560ec4c6f493aba92b3dba681e64678fdd249b8bec6b2d685717bacbb953cc3f7321c2ba9fd82b388cd95d57a5770c7335e7b5aed5aca187408e95081d879054d332c2c5340273157b5703198b2997ed0944b57c91b016cba636273125176eb77c11c00402da8ad482b9ade35639b57d1491ba45496d61682a47744fa483b2d6e5a5e33cc9f00bae7d51c1b667316ddcb0accb468e65129cd49acb6596a498b43c7b56b4a08d2225076151408fc78c86c73c086038761c82163909af865e3de836b80ac9c68a3930460399091e242124889643f0238864b550173224a107a574e7b63368a11ce54935753a97617ed0473919602a5deb94e54b703e1abcc0dabf6dca679af22e091876f0787370a4188db13ac5607f3c273d9ed3090136b75d00178df50e1d5747edb80b87799546283ea5653e9523b78cd6614b113225922696a1b55c938d80b96e3218b68bfa5afd8363f87a0d4f58410c8299eff8907e46026b339d22007e4074761ae420999726b8365808786d7be38cb56493a4001e04b80df36cbc8f9a9ac311afac20c694d9cb87ca59b7f76810913133f8908d229e10dc9c00ec8327a053763a8560328c2c572c7fbc7dfa0acc50a623b4d68a4994ac05565eac5a90fe8451f8276bade020890b66faa6a86b975e675460255971ff8b96cf227e755cca5b562971610b526093fae965e11b77c67b47d60ca5829126df4059024bacc92c4763b1391b9ab59f2c788706c79c427cb7fb920ca19f292a41bd4942fd193eae80cb4bac2eb51672c9d08ab2d8812d8a9e0f5b5f80750f98e1677c18c068ea58f03c5fb393c4bd32bc931175529666e01134d2e4193ef0850a41c1f2148122846bfd529817927b93b49a7a348ca1007fcde814f5f88edcb82ef7751cf423c9bd8a0703f1101087932bf857adccb1b5a9946b3562d079ae8a818cdba4a525a44ba7792ffd11618d1ab0ed344cea884918824c4e19ab37f48fd74894f9d08b91dba53639c9e8ec5aa021abffc476f396720a193ff10b1ab9e62f566a3f51925433c95cce784e9cdbafc0a23d13c38f0a086920082584569b889403e0e2cb67d66dc848a551b53086431ef5846d9a1555fe0247eb10173abb328a97c654d741c06b5b1dbb61443a8fd0a08b9b2923d44c5876dc0e26d83ec89b0b91e29e9497c1a83b5e315bb026e837975c535ec6903cf385955b89df613ddc0999d69abb2d596b07ac939782494036b9839377d8a028ebc01dd2f75bf1e2cbf6f23e3085651c8271d57676986c44a5f048b22c592985528152331151534b06971c835487d315fd340522ea493d51ca1885bc5019cf30a4c169d64180232a4e647609c9493a4650cc5c8a5aa879f21151d0c1b5cec96c09c2637ba20ba0478fa1662fc0ba28ac2438b860b28c1a819b42885a8560fe838bb1ebb5c2135bc29a5ed24290b4f73fbaf498da2868c0c44c490c3bc38805e5e63e93e23ef50293cc84242e85780ed715343444b60b5a50142d86836b8098189fa3bf5c381d72789cc2d1666a188a318c76d8d3a712189018953a029aab1195157deacac1f1bb7605c037fc839fd548b22344a881095a479e9d530c594c6a9e7aab10e53e41ec53e20113e32b34a82649935acc94b44dd428c30a02c9a730c75de223956315b6520bb4685faa26a7b2ab747038935ab48939860a53712a4b9873338caf2a7c5f53d87af6dcb061c8affbb99cbe069e3c38af4c292f4106cc9c973e5b327d78970623b0332b8332583003a0f9693406a636882aeb091ceb6111bda11be1b434d3e4af93237f40819e765bacd7ca0cbe32407468004e73ce5789c25691a4beeb733a4b146b985ba4b29e425bc448bcc6558c6f7b75a2204a4386d73066cb646fba30c7b6466bc2bcc7818b891a160ac0549de5008349ae7fabbd9c2060dba34349a31da9624cd38238ed711a5555cd86f22081e4b21683ae7342353f60554501a66af424b4885b8f0c23402b58b6528c185834f7dccd3989952c63b8ea90a696b473b795120839232d9c1aa2a90decd8902a8ba423966628f2c1d4b078a0612abf982de6a305f2ab1983404a9ab3783ab9bac14a5ca2903cd0345fe7a133dea511d3f4947ad903782a5f7792970439baddd328a23380d2d0148e7c8c296a26977b4000a67e6483bfc45518eba33adec9c5c67c42b5dc60846a0125e5c5d523039a1c579a0147caf090f2a9ad4d37b04a29aed3c67c130304a3ea7a8e524d638c31c20832d0a41b7b89901b7c5745f3662ceb46b14a77d357650f85a323d847ab7863573b3d8aa0223f56ce4a3a18b279607e736dc4f3a8a1b5b70e8baaf4530b2f7cb54f826440a61b27d33b492054077777f1b15ea9b5af969174b667cbe994a475b71729f64ccf7bc305acc67bc87802575b3874762e85bc7b81406d5105dc3c3e7f5c452bec77edb4c7f07b3e12607e1a00b07f6b82e27a9e5dd8be20838dd68a9f8e61c1409b2b123a6b71c3250599c1708a661a6917239857b363c1fad00632b08ec2c01be7e0c314c07b3e9b667c1c125ed64a4248a43cc39d3fc5c23fc0948a0591acf2bd8ac2cca25c5f79c95b7f99ae5116535354c79e370f118a114fd66edc817e2c09c210117397a8282f803d8b492d1602983161695e444d9d090f3478982e3b702ec28615d981bb76c130e4b818150d5f7b411ce3907ea8a1dc90358b9b9ce9a2981b7191cf84aae8e4926472945d02bcfc848b04c1870c303c163713e6c1c15febcbf01432e6812c702867dd14cecff43e20248b6d1abe9ab940482bc773d92a679955f326867945bc736a362ec67972b78546e941f58a5d496b9a98ebbd7a5c586d3733baf2141c1053180c3c4cf12200720f27b32b7f972bd2eb966aba012b5f2e9830940fa8c3971f12c682617b427433074393551e335d8a5adce9ec67eea42b28edf33a7c68a6993fcbce0bcecb172c0183d278ffdad695dbc072134d67f2d4c55d939741894ba538a0b7643bbe840a92170207d225aa +ciphertext = 6a09b4a4f5c7f9d08d4dcb12c46960bbc4ace0f99696b181be447dba0f84c8340fceafe4c1f4843672b0ea8f952f81d25a8874ae726405d340ee9c00297b85117f30ac4de4b68cfa913310641f54c700c9379eef6b0417f17f1186f7fdbe88d439f5d2bdba170c4e744a9c4c3d6f9112018fe0feb67392b0539f3c72738779fd986d33c1697516b60729cf3539b26c0dc8c7fb923d9a482e6ddeefb4ccbcd644f3f35b71e247a1d784e904c13b0408aba79016f095b1568067c0bb7f8dc77c2cce87128e7df71fd5c645c0d5be57a0d5f8d4e4da7240ba10110e45db4931691dd43054a69aee7889575ac21514ad05e0cf59235ee25e9a696ac78008ab7421f8672cbeb123b7e43f44397f9c12a52066e9dc752e4e415dc14866701859e89e3383d58e87d97320b0a8d7e55532da19a7c7610f788af5b969aba829bf968fa892611f5debee9c5ed7c000bba5141289148308c1d0f3318adc27e9b73c0ccd38c86996b39ebe4733e1b3fe74dc384f75e7f2c0f5a6f497065109c43f3cbe5438f38a049f410505dbfed98bc0011fa3e5c6b0da063058fc7942599910f29cdbd826a34a078c22ab52f43cde7cf85e987dbbb9c39ff2116755e3d571a355cdc3a1b120940a2ea3d70690927382a7e22d1bfec3b8423a71db3f8875f0275c3ad01d5409811425b224583429672e5a80d0f7ad1ef4bb2b8e97c878e9bdf820292528dffd99d5cf4f2d4bd08076abd00429987812d35cf4dcf8c1d0c2af6b6f7eefe42e533b702382aa064107c979667d2a501c5129235524cb7a79cccbb28ab725376f246b262b23dde0ac20e29ec6677278ad62668abf356667667255d5c08dd2f7f9eb89f8ae4af57976b2499762fbd07f35b5137e21b6c298d82276e31607d86480eb449b6f6ba268d739ba6e656a189c010e593ae058dc2fe2e4f94d864fda7a2b0cd863be16b20266d1485ed997c4a9791f8ff4cdee24616d1f853bbdfdcd835a0591a099e26b47601eb379c5eb032cf72b2d0369855354254f595998800af5bc0f09434edf252cca91ab921738b816d6b3b08d168bc3b0523f10f7ca0d6762777a2ef34b049a8cbb6140eef689145a86ecddad542783247c2b439be003820bb7d4922c26207133bde6b89c79bb2f26cb324abf011dfc9b19450336feae29acc7d9df4f39204429b0b4e2e4bb4a1bbf6fea04418eeb9ffe10a34f09f86b2d2f2aecc46ca43aaf08ea52374a69319e3c332d286c3f2fb2482239fd0b550f73673511386a9c052ab47f60adb1a8683160f140a196dffdf8430dc97e5e21e9ecc82792db9de624233b7a621851813af23ed418c6c2c155a822de0f7cf1ca76403078a00c76ae2ad4a992cbc9a5e17e91896899988eed8157ee391a4397b36f899574794568cb62bcf45e4a5178d9d7e5c6ecdaaf8b5bf714ee1da2dd902c14aa2243a16cdf1cd9bc6889ae6ffb04be1213338183fc5208ab36a2708cea71042412f98181ba0500b76c17c375762bb07812ddbcf693185aa385252cd810793b331a8b +expected_result = pass +expected_shared_secret = 12511f92b1c44bf6e2c5330640b54b83d09bd9560f7ceae43fa6a8f5a2386911 + +comment = Bit flipped ciphertext +private_key = 8f74492c941f826964d11008db0904218859e243853194392c8c06102bcef6c8321424ac726c74b091583a645d3c08a0a18b856bd37433697dfc80593e506bf8f896e9b87c06a90708761970036c5d36cba2ba792b39bf49517321ac6963b90ab0e39a6da0c9ffd18445b0919831798101926dec3c195997c1250beb3436cf78cf17e62f91b916c366a0f66155d65b9a9ab7258248cc40e21418ca8e7a4b07260606c393bca17494256263833a1cef3700286aa849139575543c23f4cccb60598f411b1d09bdab65ba6712b3fd2198406b1d09a38e604930ba658fe0ba245a0c972534befc357577677ccea52ade8791a3f5b754e8ca4749bea240956ca19ba87cb94e01b32b245fa158603c0609aac788132b28714351d4b9c93d425171d02c64943ee0148369920aac399d87673884b877970a9a5fc86b0b74a613f582f40b86eb197b5eb7536a1343c9e296e975a26e680e97cc15fe2b6b35d62ff8b9c305f187c7776f591a5348f21aa4f17e716b67a1878e62b03e237c15a3c0987e27413915293637169fb1aaeb8489284b9e801a327d885e09ec647245892757957d64c02866bfb4a8a3095c14418a6261d9c496bbb99fb403af88cf4057bcc6e716c8a0afd0184d4b263633964863011578c40131f6b2bef4c5f73a85b730954c8121be0b14b9656e972b4db79ab4f2936796802920f8418acb64c2200f96b81503ec2bf8ea58f79c700fa815d5ca96cbb7856749a059d6c145280ad837986c7957f5544afe8b51d234189e21392413354848a135758e4cc975a5416dc1560ecb4691bd8071c8d45322767016414aed929c86c727d44724253293cdf167b08c51f0a1819b27746743a8eba38ead61125c278b27f68410527c12869955b460984b73b6ac009a61841cf9912c79185a3a4cdfb5ab71566a2d6285ca68c771e650615059af96b3abf891e3c7aae0939d6b12c1d4e585fbe2b379e49fd30938aeac7e31a6c30ecac70ce521a748ab3f81451a0119bd90a3986445b63731c960bb9fdb4e5f0296a4c4b88c22cca6a5002f20690f5056d417ca8c541b0a9637075bc03c3327e52c678a6c87511b79ee108e266a8dc366217ea33b0b499474657b277418de73a9288b913fea17ff44695c39916a0bc8f1bab87d18c7a42295e9115838b71d271542c73a34f6790b1402c806021c04f4bd2c7890d13076f479be5dd8731196477c157f169abe0ffccc2c46a138003a38dbad72ec38ed529d03d6705ecab8b299b8e32b314e2744d77aa5c47870a1509a78614ae37bcfc07c20e6d9401780b6cfb93a91023e6eac75eaa687294b1bdd685587604ce8398cea664d63cb70de0b02b1315d53a0299927739ab7102ab8942f418b84a72039257b7c9b5879cb6f81c61dfec7b05625a57d6228edb04054398bc205702b714a040c710fb34f5be2bd58895dde50c034101ca54394ed2a27cc3ab6ab1b2060194b6d32cf5e6a09896b40b0115b84e56fe3341cddccc1916b23ce55b0419993adb189185a21c47562c3779231c534282340b3c98c2e086a13436ff35a138077592ca26223e4bca53a457c7856a76823be0c178d556998f7ad68d44f98e2462bf1031750718d940d1ff510a7e1918767c13836ab70a40bede72dded902dec35566c26e9869bc4d31b187f5997d942c04b7403652bc125ab6f37071a46b904120b096b023d68765081acb0fa177f0387fb2c36404c21ae14a12ed96b8e580c04ec72623c88ef11b9ff85544d6c36675848aa0bb7af0d719e29a13d5a55bcf30be295980fa1b8101385699b17e8049704715b04c13c159184c9dc6780f446a98255b4421649dc55052f3a4d1f82984b8819d527bbfd94955ca929f983ce44b9ad8b05c5d4c551f355199197916359bb5bc60954641650690d89487206692159aa485a3bb62180d967a73434c728552724a3914e7b398c54cca02f67d21c55382730222851f67b249b2a2a84bec5cf3a8c63ed17c05281b38d279a0ec37a3b7278cb8808fd79a2cf04844039b6254c9dd64bd19b85e80590db1125994126f7c846dab13b73eb5c1e05521e1205f1a493254a3937c87850368cc8509bf504413a855c7e5ba770eec08e7504949090fd6647f898913c2fc5f5d671310c73387a4b2a515208675786d9899d1f3c92d1ba4c09700fb405295f2416a417615b68cd2408cd409ce11929f1c34681fe06746f7c997c5ac729c19ea24b85b40b1dc93b896792d9e3c48c5b148dc6674af7142aaf4c0feeb1fd1a9ca2d2858fba7c047e2524ff488fe26b005fc5dca18326dbca9d798c14263ad0a4c36c5e0c36c5a612fbc49beea0a42991520661122f324fbc1120a132a9034a6407bc2f35485ac0ab65ff00566b0af3ca09d382106b8076c603817da72a35fdb71e1e9cb307257fe79a1436398a6e3cfbb2221e0d4cc7d252efed45520b3465407346e34884d6587f06526aea200c4f3cf69cb7e6ca48c7b337ae6c00c387b6a5035bbc4480ef4d2764c8b752eb36e2bf89eeec82510b62a3fe95f7d705d0474539f6c2a17d3905c6105ecf493d93bb3d55c33c974967555b29afab17691482b56491628c00478a361955550b9c18f8601075820cdd4cc41555625b727888521575265a69931f9182189988e782ab4323b409837acc70b7ea96a5af43c5a1f04a24c37c354b6102ec5cd6da895b7cc5fbb90251bc4615d47bd080852ea18397a47064df46cbf199ad8f93ebdc012c9335e0ad80e930c7896342334db427c3a3a5e823dda412d9cabb2d633ce4fe1cf3f2b209ae64fb516931540b0753860068c631403aed6a5744b07a80c31b3cc1c67f1aaa7197a3c06056c1023bb06231a6558109a504ac1b8a7b9fa14c0e13ecf74b0b4b34b1dc2b2add316c91699c57a7fa239c230d2535b68667ad3a1b7f7cdb5b68ab68842d9a5826b723cd7fc4ba8a121afa1029278c6d219046e492acdba3d0403595dfb5248e03508d620a3581e6fb1099282841e997739d864e03678b0527868fa1fff674ee1b57c00227622d60e83e38177eb44424071152b51cef555ec4bb08ca7ac5ba549535b3587c332401327f9212c4f375987db232718a9265598430395d1b27f90332711d4bed94583582b931505a73555b18c130f2bac351f10a4e0a644a69194ca3621537145aa329f8bb28304881b7c29b3168bc56e48a8730950a80c38b2f67787673fae8c7287c375a8c7acd6425e973a024e6812f635711df2139402738338ca002245c54c4f81a401704c8618f5cdc2dcb9a0db36c603f3b164867607a380743865d6070b24de7e081681668d4e405c3cce4bda8b8b19b80fff29bec291376ac7486036995c3088f66641357cbb4b78df57965db17ba4a4c561da976b +ciphertext = 0ea9150e4a805ae98b71141dbde77fe6e5436b685dad98fb2cecdf3a8483c0c0f4626ffaa1893a7f046b66be119b1138a1c39b0a47ac69f3cfbf8111aeb6946995504f746374e4dd298ffb74a7a1c615c7446d834fe59850cd572c9477d1e07c2c8b0958e3149931630e4725ecbe7b54934f9450c50fe4342dee3c1658db38c3a167db72e8fe6338505b043c1943fbd341b9ddaaf9bb65082bdc3ffc288104ec2caca86144a5937a5953fdce7a23f83ea69c6e16e5449289b0e1687c0fb0d810d24e3f3cd3df6c6033fdb99e56cda860dfb0ce5401b1b41d56ac7bb279574c4adc583444c83bde866d721d1ba9db52272c4d10826566ee98505251b563c0de2655b446c5a1c94231b0b8074ba1fc9847086c3980f13a1c79f3ce43c5a5d3d88ad1ea22d821dccfe0416092275403d644573c393e7121fe3947e64e21886cdf4eb06f6fe1e5d94f591564633bdcaf2761e248fc1924fea2b2d7be9ebe70706a3beb8ff8e8ebf69ff09295dc7c65e0f6442ac82241a945d5c2d3772d1f32c83cad36479438bd3191fb86a32644377be9df661e0466580a725e7d4f6e851c6d7bc26d1b3d96e748cdbcc4aa6cd71f5c2acca2a9fb10c6ed2f4f1b6caa9e9c5690fda98714c70c58ae87e449f5370040ba66a6455ecb9cc2d03b28d438cf1592d07b1b3123673531da943579b844e97bc3a2a2260f8675630c8f8e14e70d8ae13faba0ba56f120fa74906104fbf0ac609a2d383983cd0c60fb36d0cf50b373105e2892f71e563684479b7b7f2f98feba866e6b15f06e893509d08d7f094adbd3318b6ce6ac6e8345ed7e8ddbeab8599fd91119773198129194d69cee252ec6ab2942b7629c3e692c861caad3c0cf4fef4fcfe94e3cab2679574e6eea0799030bc9e2ba1946275b8697dabdcf28337ab6ec2e62ece2fc8155bd5f5a6ff6a67761b7127726a5b6c87187fcdf3e49a2899bdcf92b942e0b566e2a5b025ab00db6994c75bc84dd4edad52078539ebbd7ed784b66311971cf3d142f6e402c88ade14e767ca2568419ad222a0955f1ec8658522c1d62c470918561ae086268e3387701c7140f30416c184a8efd00767f5f34a37b139ff0a2eba8302d7a1d7a5793c7e9a15c7ad65ba4c8f614e6c5146290e1cf07e07b168e3a6018de5de0e2a9c6c8d657055301c488220119db5cd1f2c27dae930a06962d1b63d4f88cf292aa8eaa2a5a96e13c7d0ea5c4e98d86828b6c83416d5c6899d3bcd4a08181135678e6abebc4ed2cf557f9b358fd9e88068dd186e338c20841f21a8692f9d4d7d944b569ca34d52901a31dacb6fa5a6427c6dc1e28ee854a402d100569eeebad9209fc63b7f0490a47025805be7cce21095d4dfcab88c5069886e8494cb722526662b30c3e36c975fd8feb1798010b5170bdc9141b4fed2649f140a98981bec7cf8bcf7b14b0a9237e40eadea2b6ca8f78ebe7c6b7c3468f08ad5d3d3a8c58a1777146c251981c0c71e4150e406175b98a17a4910d56598e8c9fdaf53971bb1b317cb5f3b395cc +expected_result = pass +expected_shared_secret = 0fff63ddfb838b54d94a870a3054e06ad99add93bc1368eaa7b106abfb11554f + +comment = Bit flipped ciphertext +private_key = 86c588fe37038418cf19bc45cdb1c987fb57f2301929694fb52cb042da2889bcb8a43a1e5982884c139a9129003ac5b092009d6a837422b199d8505fb9022295f74818a9cbb6e57b4667c3b1962441b41f9dd02b5eec39e9561a8103ad5dcbb47ad427351b89126b18773bbbe355379cf222d8a9a2fcabb5e8d575f4659759570b2bf9193f606c4d45ae7bac23d2455add3a4eb8c87f36eb1d65189565c9354d395be1884e7ca8caa7e27f3c9b68873c4b1b2a2d39094d173a604798b015201cdd2970bda85253f6c7419b107de4ae83878f3c97a9b741c4328227170a5170d30d8ba38c54616da95a3156dcae5fc95a21397a62dacb0273afa3fc9a51537c23978b4e51529fa124177b92c8199fba5c0d6a9529f3364580333059c39dc2d93ec9cac2d11052eda371da798e7c486b5efca3432ca02955a7fe857622511f3240b36375a86e3a2ac039c67cc71eeee33e527ca879c8c68283319b9815ce27b12dc0869d37a688850a66c79100cdbdecf6b5a09405b0c2220344410a20c38547c0b224cf4b624a173894d0f53107547b22326c36b7ce28c56d9f180046a07c41e868ddcb15e0e20e3957bf985b9f2a990bd9f91025469163d9c61f1795cf398434c9708c5c17c999bba9f8196950c484e8544a3b9db5b6009cbc5728343b87c3859e323d1409a2fee61e7cf72b9cc1ba40d546820486914631de2a50ff424c7f5acb60aa2e76fa3c57f19045a910a72b544ae01d340729464551dde806292ba1d63baf290a251825a74a6a482e0277601c3373a4b969c54324a1b2b6e71201f11d20e3bd838acb5d6c5710745917b1b7aab28405012f5bb722c41c2916c98ec73928c211bb26102329a62b969912f4a5a4617c3c6718906d190f1351ce1ca73e7495886b243cbf6c55957689111b008392b59d03b830cc1dc9e0acf6816abca2425f68b452f37fd557570bfaaddcb7b397e7490a860820a3aeb8d17feb123af1ba8b2ad8ce43bb37446c1e3e3b46cb905a35a52be9b7855faab02f1aa0dc0c34049a86d3f02c4da03bb0a8763085cbe71057223a5132a422931379fe5c570e892b058c7e3cf46f01c2224ab75d6e907a491078fdd5cd9e4c1f14b46b4dcb29c29a7ac11096243830a1a45613aa909c895d575c69424a77dd515358cacd4c1829715570764003f5e74030e42e5d645059309750ba7478aa54fb496ab733a8b446987198530b5871180337c7208506a1776a08b1ed5028bbdc07eca201b101c7e3e7c788646f467a812e851db8cca2e039cb5cb3ae4bb1a006375f85f7587b3c9267294a6af0b48c056adbf10ff2f7987af22d9fc28c88cc6adfa18e71ebb1ef08a59a9474b08aad8cd360c8ec62ce103b63a4a6684966a3c4bc01f3afb31467edc40b8560c906eabc8f4361efa6c78fc0245e308d7461a26d490969a00d2631c40eb292f83436cd1339331612cc02ca14fc3ea8a90e5ab33a98c1a1422b53e1220ba7a50817408d0fdb2cbb06804317ba76275f4fb70fc2c702133a797ab04e8e7462d1734aa6bcc267703f3b27b1c3ac0a7b233206c561378370ff10b49300ceb8c8b8f7b5a5dbe6034d3bae79f5cfd6c7a934189bb7098d061a9b44c408cba534ea1481aa7605ad58a235ea2204716e3ffc6f663b894ba151f9c343c4a498e7f65354a22a0f8517c7d1c5f16518d40a84d61a90e6192fad2635b0c472497caaf5dc82e4f0602e48cc859761fa09095d903631e736e5f7b0b536a2d1e453863257e9f5cb846a136fe8a02542bd4c374ad686a09866c77c48c2f3c78bed0cac6cab6a473c30f71aa75575779f199c50dc628ad7a110b98758e72e8e71b3133444f0368a1fc22090c53227c3043b8a7326a263344657a209b9d08b31f4381b6dba7f9b277115c43d55cc465c00b64f679d0531bbf58c6397d659e9859d6f7205eb74169f231801f08145515463a2cf3c89457a21bce358a2f6f762f6acbe8014547e37742b994728d99ca3e0aab004364a86afad01b7277085e27ab8fb4c8b29e1ab18a43a3d96b574e517491a64a2d63b1d44caedb2ca30b9947a2788880b869957879eb9125adc7896328e9443a218e97ab87b8bb4f96741dc5ca30485fdf207313aa4ad141134701c9bd17189c2bc0fa30d9fc0c1b406a03afb4bbe8c96834a80bba8bdc2c851a64907d4ac9593763d245b9b62b9b79817551e7c3de357b8bfa734b53a4e2a947557b6678506a5049b77c983b7c9f32cc2663556151a0e453eebf1bb86121fc8eb97ebf448b1783636e00dd6159b80703be1993cf0b346b960a67d158d5ff04ed0966a6d63c72f629f3f33bc15896145212b106348635732ea166ee351acbadc71af578c23c8c292321dfbfa1129e41947577654a67a1cbab1f7b0289f9040a213205274637fe6945c2886ece79d1d146603c9cd67082d8d9c6f82e29188dc5cb9b29c6ff9709bf76722f78c86aaa1c9959dfe455170ac89e677049f82c056459913e3c98015552df63349c26761f9cdfa21566f19a7826b4a7c693d4a7410b2e579d8e59703436c76183ec1e84f06f572ae7195cb6a9f02b5239b2a8d90660c9665b362b8a9bf3a8faf436fae4231b0e125aa136ee51304c923b26d9a22b4e660439a9a9970b6cce714f45ab6e17c4abb216b55f57a7b68364657c59ff60eaa629b906b8cf7352091b256f57ac3b8c31e58b1bb2711a232bab7924521b8b0863b4a2c45666ea0b4ae2a1b03063a765ab5aa683988492518da4b623fb8968c967b589288542a1f70bb599cb87226f306b8911a8fb79f5beb18319781c4f840df735b11b40d49489bab043b6681cf44a110c4bb4a5642b71c313947749bc84b387d030abce367356a77c2990bc885ced82897a7e489b678a694d07edb105580d638cfd235c8c42b6f200c374c1e4d676453239cff003fc211aad00a91daf65af05139db3095f065811efb3df0c96ea2e1c480424c43104855e98056ec50014353f1917aca6111cd00b9c9e9ad159734a8dc4ef404a9eef0acd6cb02feda24eef886c1c1224ae00dfd23349e40071394be3e27b5c72643519646112541d41abc1d53691c0ca1f7a0bfb5ac405551b821523c8092487515096a3aad26c521fe91bb74d2b1407b4b102692014137c7403b68a61104393980509b74c1a7b374a093403511a56ff21a38c5928b6b8a4ef9c0655da07c85eb5d8ad7c2ab9b8d006bb04e5a1f881abbe3f409f1269e20173a30037936ecb8d2e93f858630342b242ce1ff688760eb8766e0cb3cd5bcd931967ba5759ae7ea8bc14464ca37a4f599054d319529004fccc129bfcd9636f4fb1b13034d3c64b79f3c109e863470a68ad68f34aa279c731c2bed5bace26b636ced453492fd80cb48e34792f12f +ciphertext = 28af6e6b0c015b2c64be668f8a1ab68880abc86f56cb089adb8159819b72a5ba0661f2a35d05662dcb97293e306f734826d7bf440374364204e7a214be1e4e8ddd99302b773c75d95280290c8afe88b9f8be3dc3caf29f64bc78c5a021f8d48f108cff4c86a695136b32bf1b3661e9d8eb7516450d8f595a9f76c5d4add204b1725ad6eef221649690e6437118a2cf27d366b84b2bbfd06924f829f04d0a77c07af58ba8b88421abcf785aad4d19ef0952079bf0c8ad8b8fed68b7bdf05b71acf84bd246b985cb0062f3090e83c9cefe8d0f3a5eb296f8593936b9978ec8e1ab3c3d7d452f3c1e787e1cfc263a243c6247b4f190ade0d966bc4be86ca5bfd7df7fd9e0e110c1c417849439b5b9dbff055a6896187af6aed7f64d4dc0372fc8a556383c80dc87e9a5a9470ce05d3fc13319f14aa8948cf10fc9aa8f10835454f8075614b8266eec2adc1fdd1ed4d88c97b6844f43d9626222aae94de805e0764405e7a3b5ecdd64a770bc1d9d6a75f1aef220d6a76a1f0c3226e2362fa280553268eb85c5de4b1a71de9e927491847365d1f8eb119c333feebc8725c05af24994c01ad12b27b1a2b32dbb6cc736258772b00620158b6f46fcead32c97fbfe0b5dd4ba15ccdee56c5c96ca25cbeda43025308ad1949b3ecb888afa36346da3c5e4ea68a99a7c4ee55af2275729dba99ae5f8d70b70f5da00807eda9b365e1a73bee0c4c31a96854441b6d36a4bf6776775d8cda1b06a30891f81dbecb3717966a7a0af3e2bd08fde1deb0108d75f7fa01a26876e6c5af282458464f9530025f6166284c57ea7fe97af282737899d0d0520eb9ff0f1562ebf21f649d26bc4975fda4e94ed04121d6039f5c78040a236a8e3009789205f9b9d003041e38462da35f202fa6af667310bd46bed1e05fe293d8af3a991d6469f8e8412e2bfaa7a4271d77e789717b5075327d6a9cf74fd48e1f2d835cfd7115a0b1fd3723f9edeca01a5e29e97211cfbccb1dc08ff84e7f0a429a82b5f23f2a56058b26da049957965b9f0a4658bcc759bf260214641267086294023ddf7ddbbd7089eed2a536b2720efc2290f6bceefa4223423a51ca8c6542cd95af98dde6d0159260128153d384daf377d58056367d15d032a56ae5e5f8ef253acbc87587c71200df8fb9bfa21561f988b3d24b0ccadda9865fcb7f97723b270f79ad7421340c438e40a7aa8a0539a79faf5ba6d5407ea30feeaa660f9be5ef45a6c879df42108822ee322392498d28f86d353739e8a9c3abfd24e832dd7d08859a20aba7c69a6603aa37806738e05723ea846261aea5172e367361f241c0e369307f00e636907c99883ff47201946e832666f2618387877d73f181a7f0d51804692447b5f18f118be80e55f2f0ebd22fca32f114b54fe4072e194714766b4c11a26021bea320a132397f928b7bf292be99d876f608ac8ebef0bce6d0d903ab82157df549c931a1edcf0a7a02a6d8e8d6c693d19af38237651def030cc9793fc9474bc93833a028d8024807e69a6d1 +expected_result = pass +expected_shared_secret = e507bfd87b7f20255179d2bbe1a271362e744434a51ada43390e7769c55668a7 + +comment = Bit flipped ciphertext +private_key = 92a15e70405a120190425c0a62984e7360649cfcc5d38c7c5a4a1cf7968ab46c1650a063fdeb46bb2c87870c3aed9a05ed60250ce18ba3220caf7c4037303687faa35fcb5611b3869b18368c160c540b4d81612be4a72c08068fde75735f85a2a69c0ccc12695cdc0e1826902488866d71b22797483ea2ac65429ac8fc5da8980305814e43d8775e55c748b2355b565d0ac54460d346590225d9e6701afc8979070d03354da95ba38a82a465236acc6ac6b58a1ecaba4662aa8bec6c1c2b461b7f012665e448209c0d2a9ba3a00259556b8dcde74e35d7747f132341263041937a20f684abd3c090d8c7f06c1abf07b00549ac6514834d369d2d7a45b7b18794f80c7ff57d35c808d1b4c4d35b4699c62e7973ccbad30c472205659bb96b4c10023a63b968a68e0242f3a9971803b4b792a35d89c049b685aee0207a714752655bb83ca5e0e77f78fa150dda7f58c1b1380a51cdd95a37034e4ac1aecde2ad03877ea82cbc5df48f155580c578b1bdfc5b206a00dc0bc917b2bd58baa96ca35e651085c786bb8b98cd6b202d8bec5d426a242b925fbcbaa61962bb37381327679b5fb82c23b7377577354be80b42da3f8966acca3ab2386aa3d545631d0ac0c1bbae942a0062b0b83b404b2f3050ec4a4ebd831e58a0111ad43d9f35c7916843fd3380e827333977021b8b3a7e233b50c03b1d7417c2451ed9c25bd3914c9d836f6da983b3e87aa0225263db6818091c37281958f46d6237b8bba52219f4a025e924700b1653244f4cd30dbff757f5eaacdc39743e4480a919a1c58c7de95825bd70b96c6624f2315c91bc7be0271502cb5ac4d8010d3a913faa3cb742b3c9180ca5aa02e7a180bccacf37d6b39da79975878b0ff2a6174226e01740446468ed5a861a6364430a764a471a9051b2ea11b5f194a739996e15a37ae7092f795162e5144cd802c7847925f0909133b761bffa5049038c26f51625107ac7c228565874512c0ba8e7b042ab9560a52e5e579f6ce79ef4e29e644005e7927fff6118e329475221398d955561999ae7da860ae756cfd00e34263ff8c863b03253a14989b2b92cb1710537cb0e99f737f5f02e98ec578310ca45775783c900eca25b53a6bdcd5a1c1017708227c6339b9d2c3a8373b4c424b395a59c5136e4120d6a0f3a05b0d064c7ea0c0cbd1210ca07cc61405c7505b7b640093d171061774ed51b2daaa24fe9473cf8595c51473762d45309a83d6d296a9625041afc26fdf5af3423bf5ef15e929cbc9ce4857cf45fe8f97164fac200bb843ab399efb8802024888e7c467a42939a4723f381c052f6340fd03dfdf8697749b8618481075b0afe585d3e644abb301dc1dc9d14a30ca64973c8c06811fa6732d3bd69404c862269b9566973e41394fbad0d3b578442cc096a4856106fb38b00a61163221187a7133cb8aab14797c3a4433ddcec1a4f69c5657c1cd947b12bb1190250827ab03dc3f1044b701da68a6509bc861ab09fac996fb39165800c88a803264e4a6bf777614efc543fb2c900e61e82d426b57217fc73371ef34344215feff04e21dcb04a67280674a3ae7626864b847fca6c9d6c86c57116910067b85912e69781e36849fd70b1f855265e73c5c8ab71bc4bb88619bf94fca93e6b62f452cc77d4531b04c7949b0103fc15c392cb9e4869b31b04384458b0834a5b70050a7ca4b0f769576250090800f6912f76e15bdc165e3272c99afc07f4e532e7836aee331440d245c64a65acd991abb966495571ee0a240ca83cc05572ea525843545c37ba90763489bdc47f48e330207501c610a95170856bda9447bb572006473dc904c2679bc9d03daea42a2d0581680a0b642a61f80296b3133046f39e5c9068bf1431d4707de631bf3ce35f7576797a48856723764be80d1615bdf67a10174657ebc608c3ca77a42711793007415299f3733b99b61fb32355676829a36c383b620175a19d00475bdbca9d6516287afb692a017b83e468f3f52f80942be3cc540b242b3a851ffc95281082004b28b8c7b14f2723871a2ac72af0a315ba651ba1197c13a41df152e201cd64f051da9987da823efdc7036a6a26a96227c3888a66e77eeb847dc350af785acc3b38497e633a64084eafc0c8e4638baee568263393b61c1902483adbc89d32f8b8c103783aa095a9f2ac1402aef5a5063fb432e1bc4122763326e022e6a93ad6005b094b2f2cea8af170a9c76009302906ac9628863095d982a353e8aafad9cb3db41a20c898f8294269ea0f8df4ce59a525eac511e67a235e134f350539175278158a26cbf21bc64b3e8ec2c10cd3c8064c01e1d5c8ab38401d2140ef845e677972fc64901c86862967459628893ea75c3bd7b2a8db919828490f788ffd115281a33856129b65b5829b715f10d43083a31cd186ab3f35592563a85f35995894091ba930cb0137bb4a292942789a7bc098f8208b82aa92a38d32727e74d245a3b223d59bb70032b73e9abde3345879aa14157b40268a32c48002a089ca5fd008e033bde8156c651727e6dc0319500804ac8f0274a245313ad0e36a5c546e80113986f427bad601a17a334a41131364bd8296125624b0a3c7aa31da91a9cc15297b209f83b836216aeeeb3706e62830aa854dc0a91188bec54100b7ea0f5a30c24311a6dd09af9acb10ac235821d82bbac0b26403911b8853d50c2e9361a21b92be63c3468058b4307268b6342f09811a62e3bde45b007728a1e70c0b55f772080470bac382559886a0d4c1cd175f868442a1a355238a651b013a0de47f669ca995a07e6d59097c744c559b75db349b8f4598baf5062a7a2ab3c917ebdb14397374a86a4295b791b4b5329e826be65b69e341c1c54759df05c3f807ce25fc6d1e53ab2f3993224a7aabf6a61442bbfb44a068083f6d47cc003acd84511962e227e129a81a5a13c158889b359d4a352c0a928807f710bae5b3a7b2904aec69318b68586b48db49413ab6115fa6592b9a20e36bbc1ea3723b3890db323ec286a29864188a424929094246f428e71614d4a530981621d2330089b22c2660a5a740437da7707f156618691633b79b3a19bb12b4c2ed8c1118e19207b9ca9be91a1ae05ef690875c1a3ddcf39a5e80bd18e0c60477c7a44bc79286bef511b4199c5aa0b42a40676d78e14532dc8bd3a42a926b25243c3a6e5b7296a4960157a27c02b9e50973500a6745daaa463473d409b7365b59ca279a8dbab56d19030a213afeec0a8300570c09e6431b7ee5d693d4e53f3a16fdee1e4c127001d4cb198e0bf40261d7dc707943e015b1d9b0634c3522f8dfc9f568a50aa078e2e7cc46c17383326c786f3f8d1ab73e72a4cd1a0cc37f59299e9cce622f072ad25cac91c699 +ciphertext = 7367bbb3e6646f54dfbd661a55047f1798a7f0f2ba56d81598f4c96a5f740efac9b428a0385cfc76ccb5c45a0a8be25a0587c46259c9aad26e8cd1b7466dc2c347bd4fe4784a77b55b187440f49ef6d091963e59e8b58ae0411deba0d6911af14ce9a411a6e5b9347fc6d69ac8a86b4b1fd3b7dce4f8e4552a642eb04ef88737fe22eeab7eaa9f349869e6807a89c2c3f5bc97cf3eb4c4c6beb79b0dd72496231a1d4a6257648399d83e011ff93751dc3dcf990524ed22530d8524c91e453e9f974ac14c48fc0583f3c1a0c2ee939a86ba510503018be7a6a647b007eef2d36c6acf14724c1a60568a9ddec8d1c86096ca19ce8cb50a3fd4d69dfd56ab9697a1b4320c4d7d2c9097c1f0af269a2a40282a132c37c4a06cf3e8451e2767d1d521c12a2e684348770ad7194fc4d66d2cd42a7ccc3044fe6abed8f65ef5666d03c544a2e613e74b10d03cc8a0e43185b3179eb78b10ad0576d389326743d4cacf0e4a6df2399c335817d4c1b126958cda7a602e18dc5bb0b0ff4ebaa6eaeca9ab663bcccd92d255d444afae88d65a3a231bc98a81688e79f20009b398effbb1d7f3acd102b81d36542b2cc10ebb683834092afe806d98b64f5305ee86cbcdd19a95d027efb2e660e60d1c3cca42850a7b37899f288066c48c85539715e17ce840994e986d7859dd5e9a4947f7345090bf31f6417de9899a82e920c6f73f01dcbf0f018c7d9a175390ceebdd218bc6156a7fdb929c0a8eaa0963ca9731836d2b95c52f5f333280f17702fb3b5d3d4134deaad3baba38fab2c36fd8700be2452fd971c14d84876a15e5af610c66d37f931383b5fca4927fe6602f10dcc52d8410530eaa9cd1ed8a5ad889750c5b9d4af517421e47239d2ba808ffd8d307f56c5ef4bfac89ed822c1a1467bdd0d40a484cf05ce46602142a0ae0deaf1d9e2d0fc572b340e72d2da42710f0208ad7d99b478b0602a45ac582253b7ef411102da14fb21ccf4443af461e93bca4daade119e326a34da2628c191e7fd69ac032f86d61a36e9e0417d09ec6302f5eb713e8746e6cf27976234a24c8c70569fbec8674bb83ea21137a4ca16701a91456c940f949297ccdc4c758c1f8f17b3931b8b6c761ffbde75baa869645ab8373463a8c28c9d0996041935a71303828b5b9f03c5664704a3a9f14d36028794c23075bf99ca05805a7dc7164daf3511d0165f1c6bc087cf4e5993330b8937e2bce66db0c4cba2c8b00350c291bc4f828c759d02cf3e1789fc0861d3fa4b5a3a084464bbaf7e08e7f19e2ab818904497c5849830a4b6ff810bc71feb4e71bbcd39d3e9dc7edc5cf2ec2bf768b91f63f2b46970dd61d8949df3e86b0a53f84a7d562b69e400cd72f3715b6c837b19fba455975fcce16c74ca6a466f0d011011d7a8c1cbd1b7a9dbf49509efd18de6475aa816739c6d72ab02a9f32de270eaf09ba467da4fbfa4a134384f5f818877096a56a9e1e1fa3630f8b1d0508e653f1f4e308774e85b28b1a50be1f70de2499344d667dfad214ed8063 +expected_result = pass +expected_shared_secret = 65578d0dc97fdae0bd65291154b83c0639dd4fc80514eee7a62acf510934003a + +comment = Bit flipped ciphertext +private_key = 78084efc5099493305f98089fee9820d74a915f88d63b2585e6c495ebc11ebd491d0c83cfe2aa412360fe89637d2683f316c388588a17eb4ac653a8970d9114549286822abd1495a6c091392356ded00bb447302a7d182f6bbadd985047a51422ce79c24d2b611cba9eb490b3e88976b19bb34bb64ceb7a8af0887e52c7265d60534628ad021313fca9e51f603a53434c520cdc625a45b57aa16224983c63f2b075d066962db9cc9ae16649c8735399c4fd0e07617f14d329ca4e0751af1da8c551a0fe661b2c2a5b99d96b3533c4dc62a3222d25a97729b3e283d4b582b4cd7a3ff5991a54bce8934736b21305723ce1c249beef9021e410e8e505769b87988b945e0990fe7e44ae798720fe4b7f8a24735c21b6404391b11acb9f64f06c17573746d14529f946705e613cb74a0b679d60e441754fab568ccb2143565bbae6c2488332eeda48ce90367d84515824c6cd4012621d830c36b469a69468df93dfcd16926c04fc0a5b2af4aaf7330463e916d807acd2993c587602593598e880c2c3bac4b91dcc4adcc48e76909cc678741d965ca39b31ad8c061fb6ec171c8a219a55d29ccec278cfb2c97f77c0ee49a83e8434d6ad0ae65ec6caebbc2193a8e669b5f53326957b71e65371af40ac77931cdba4b1bba46c95de311869a354b957d4a0807557a35da47884a735110930998bc3f8e9b353895885728a5900c175f1261e92374d7e0667e984b51a566e8838cca8924c6f1808f768db4998e141822fe44a69b99140343bc56b3c6adf05ce41aae8038325c42ba21eb3f070355d38385750579630003fb21c778659194f697c4a687b36517eb4c9616394e82eac0ac12bfbefca613d48678d5085270a2899c455df77d21872284d2b155296c9d0001cca15b55056c4c9a0b7d048de2823d6ccb56ee321f4c8576b088c1762c0fc90702f9ac073ceba76fc0628e11b4a7079bdfe03080fc27fbe3171c18b86d16bc5ce33c239224a2177a19d1ab4a20995815486b68cf5b006c289372599057c8f7b89409c62f06095ad95c4155c20f4c888962a4a9a4bb276baf3f4c6cb97c8cfc280c0b02bc22139c2c8b8d9250b01b1673ee8a4b7bdc34b8f318ca88a160306c03260de147312841c28adc9f864b0275b03faeb163658bafdb321cdf1ac826e73f58c7765d522c05a06d3a0a18b995629b159637fa50b8f4cee572a5e6f506486a6dacc86d94baca00376825221879ac8215b2658b71493574459b2265ec191839f14f3f0302b9f775f7421405b79a69d1c727607565456b05d92f5a7432441c5ca8126b7973c0f78684762b45cfe824cb824ca13b9e63fa58789694a325cdd8985dc3e51dff7b506eb21d26528d02c2cfe1797e08a3c1924060138b2dbe89512f661db77c373e44ceaa213147c25680ac14f01bb474275ac3a03214994668d5bf5febc8870b8f5e50260a9141cca2ba4874544e692fe939a00503041f0b78cf7c368eac1038b5852e14600fd212a2199f6da26d60f105c1a32b9a338fc7b93a266b0c11868e8323b2b21c4036a76442ea44ac88029cbbb26707ce6c44c2f5909c0eacbe51668edab408eb3b10c15154e2f4879704c19ea5c9a6b45fda2ca096870979dab901827f3bab7800976315461188d7c7e2ba248dd49a219bbe23e108ee35131d64b270c0754aa1b5ce0820b8db05af1aa9de3a9fa7c22756c08eeed28320585e76c921d1ca912c6c868d86a30a9153661582dbd010ccd88465151668ec35c45772eed41ac9756a1bd78a52bc7eb4bb8c7ee9b22ef066c41956b5986e7f9a2735a51e92d87059c81cb1a5427d94197de091b5a047670124410a87f7627fd96cbafed54282cb910e1758bd62a23f13c2493642fc2c4a8e280a13ab2202c66038da9e37639971cb112620b902a0ba4da4656487a2d0020d75f12932420f277387bd8137bc9a1a8d54943f675b835b64f0d90ed76545e50746bdec2a53480cf221a6e22293b40b763cb46e33862f7c4228337a97fed52755ec2a3de4c931512677b283b853a334380c21f09b57ba2a0a669dc8d59594a6bf96971c8d48b3d02049e35910f0d403feb00852868414c067d3b6c375e09e247207402c435e92b90e0ac8c1993dfb8a2ba1b52680104b83237beedaa1dda384d4c0b405f23bcd125d81f15a425561c91861e52826a2b2bd89c7359a3898b790bc67b152e7b95a6051b0d3b9a689627d76d822e8828f14d6ce1530305d9061f0d740ef88aabb159a22c20406fa9b536285c3a44264f3a050181659371a934b1558da909db670d2a90a318c588c4bb25ba6af02a204d3315c021344c3752b7b754e9359cace657bcc430e2d61cb341102331796763924cc2b9936cab4499b1f54149466d0a3e003756eea046e077ade9b6242fbb4936003c67028da43bf4332293fa7905902c4a36c171e933ac9820fefb589cd2b1108ebbf0349309df87b71f25dadc607f5529c76c48441d1879c51512b909c2dc75b912337cbdab117a688d1a98ef596630b0278e84776949a0975c33b1959ad2232a93e4304fc0373dd3b5e77d57ef8bb709720356ec6092298b3e6f1415fb2052149c0a5e912bdac4251581f3f13947508475c395fa2b18b3a28b43f2a51394bb9bb7a92df24cfc7cca3247b9428877a651660ad696e6e8a07f312464656263b85c9f57012b4909bc3f058a2b16a939a59825634f41497c91c5f911942c1156b86782ff6931ce75856ce76204ac8a22bcb5c109c2248206d1f51190543a78cea0df995300661aedf768ec964cf799510f1539203d13018f74b75140ab9fb45ccdbbb1b040cf3e094e8b43715197d3873bfb984003df149a722c788454741aa0f700b6f98f50cd3a77cb205577acc372b208f37c10809d34fb2314d38bc2a89756e08c39be1fa918c0b9403b7cc0bdaaefd24b6a4e06a11646e07362f49b0818e62696f0c6efb04c6170b70dfd96ba48b66f8703cb51930c7b3453c6743ff3a9ad6e21e8b5b10d1670351a46509367f58d7549af82a12a259f8750f19746e1ee111bbe391fa976ca1c273a3564f1d4a699d4c55347042206b9f28aab8cc174df67a1c62447f879174ebca736f6042dde2617818c1a22695fe0bb5ca10c6c73a287b1868fd8644a7e49964d8c401c1496cf50bc9a596b183baa31acc3270c8acb2070847168ef04d5d88b46b233692e5973f0904de899b92616c4d536e527bad75182b5a563bfe47a63530cdfdd4626c6c3bd80478f9964e839fde877006aa9fa2a59f5af4e3e0ffbb8f77698bff559e172cad41270dd5a20fcac84bbe8dd3b0a543b686787bf8140edd4b69472e7f6a50a5f9405bb88ae4110a6b14fbfc53537c5c826a8531b465a13abde01e6be7290384656604 +ciphertext = 4f6ae8a736fdb9f76d6e51e712d2cafc508c87d510101411181a2fb4d1f96747d14370bd05633d3dc4f8faedf0390e4ba532760fd6878a9edbb394d068be06b400f2ca3cb0078ce97756153069d63b7fc17a7ff539e0423eac0c733f4ca5f7b6f07aed98dc3cf74fa888719f08dae73e455e53230c16bd33e18e2732ddad6227d0fd82e329e2d832ab1cd52ed709d2f276da9947a671d03525b016a2a30737cc072f154a07453089829cbc3b8ad3345dc90e49a17703e7c3e30dd047690786b4547c299c819b8f31fabfcb131c3e5fdf0a7467b85ae3523ed34ccfc6d0df280efe0822cba36ed0da6985dd1ca6af2a82f733f5881b84c4ac56778ae36321acddfd0a5977ba89cf7b3f3d06fab82d917ca48965381e410f40e588e96d5ea80d0215932e394b61d10b31bd6e4cdc7c5494b6d0edfd9ed1ad2fe4998f730d9849beff0fcd8d8826dd831c4e384808af9bede76dd5a5073a3f72c241e4ad45d384dc42d8c446126b2e2a438deb3f94a25f18b45caefbc252403f8c47711008ff9ae4f00a3c4a8d87cc37905df2abaef0b2503358eadabc53d927eced04a5497b33d22cac5ec88b2ecee7727711602b8093ce66843c193881950f0d897cf2629eeb92089ff491d742e0287a42321ddcecb41ea510553ce92f124dfc0a06fd470c0be6f640d847d65618f1805a943e34c06aa8777d4bde320fc2460d3aed8a663d0e4fa407d14e1716b2f4e8b75e8a35cc40b72e5b501473ad154a5995db4b81b1be8a4cc76a37208d486d0c7877748db9cf206f704e7e5bbc956410974bb9b2f6d7351e1b765c9d4e0c397f02ccfff2a03c85146886a8716b3287ec0a87014a3eb0c78cf26b44ac976c1fc199c7a3f6ae1e011dc402a3a896db3fb6b917dd1156fbc4aba2b774e0e5f85006dffbee5cd7f7e02972ac8f26c5cdceb1467be5f5bf2e0e8aaf70b4acec9f300b1faffa67b5a1872d640f5a8019e4a4ed0a65f4835cf7875d869b8926b64b22453587a33ab671c3f82a5683a17777201bbafd41fee14a31b7c4fba8a2a744231f9860c0d133ea13c9b0cae2e685db1d1461760d851700f8edee62e3e8550d7c1a7a720bfaef799ec3b91d53a042340975eb4d1ffe230eae9fb2e5eea9350950ef7f4836c2a0279ba2eea06114daeb6215feb9c6f1689fc8d147be828dda1fa757bbf1eb5df008f022d50313b2124884ae99bd70298beb83a18deb2f1cdbed89f910d016fdb1ee54da020ba79f3d452fc9d07fb388a708c3cdbdfe3ec77acdd8a2c5b8564a5b64d05c537d755782f8aea44f7de527c6edbd44a89471d62b01e46732410750ec89ae88429d3cb35a3184fe86a376a8eec0886525f86c3292bfc4ab8661822245411d7cb93ca0eb23ab3b0273866b3a44a2d04ef1939b6a25e85318fbd26e856d0efbec50605cd7f2342e3c45a05afd4b5b1168ea02e690719fc6502190a9d17befc93b47e271ba56f68527c57caf024b20df11ee817fce29e2eacbee1d358feaeab4040c66b57b72dac2912e2962254945b3 +expected_result = pass +expected_shared_secret = ec51edeac7809c8324569a6c0f6ee7784af37e82fd6d364e601900143adf63f8 + +comment = Bit flipped ciphertext +private_key = 350c93c7888ebb8aac526a21beba78b9640b242077121800812679f2174de2172260c6088cd85a44a56c6d54549929030914a15c857d7bc183aa703ef0e574259ac6df4165f70216746599674009ca8ac17dc8b6fd642cd45218c3ba6953b1869f0223fb673cbd30809673c9afa83be3f08a98fb4ff353a189e22f1f212a8f642103e8199220958a3b8c2961407e478ffa809205e9a3f9cb92896021510944fbb514560247cda072c5b94474cc799fd4cb7b4800a5042069ec06b2e55617c82589933f5f08ba8f538e68292bafcc77be8a7427b59a4b161bef09b8c5a1c50da97a2b0228954bbb367c5cd745171b2bc31ddac119500d67c55d64c817e1095a088aa1a733adbaa30223249e25253b5f0b72fdcb05358c3256a02abba12e95054ce5f552d4b1808bf89b9a34486d349c77697975cbb7a30966c3b69dcd2c85e867529518148f46b2abca3309493de6198e126769b35a7a049143ca862d4ff1cbf47420163c0eb8a3924e616de48b01322c716010696fc31158a7690a7a72e79b411eaa34dbb09f2c17581ad5a882d490b6a009755aceda0a82faf39f4fa6c8d6837d9ef32f74c92d7940b0e0ab9d3a667a07a3c4e3b2507c4914d1db693e787f5e97560b258248a7bcb2d32f2b84ab3c688857510761ac691fc77ee07b47cadc1b8adb8d7b3489fb92109ea3350e217de6449edf58023fb881c8858acb3a1cc117ada0e7268c925081563508812972bb6fe433cba52b55219596babc26d26c67b63c85a77898093ab6bd6038b04c1df0860ee46541b6f094421a71149377064605a8caceaf0cace4ca7cad353f733a712ae0892eb35196a3981e67aaa6aa8f796ccc68551cd0f9b10d372a4e554eb841a32794bc48b59c904b5e0e799a7147b81495c5b015359fbc9be61b6ab6471e5f44afd51429958c5ede30bff5f38e9ff783b8b893a29c7df95953daa817e3108a913a05cf4a6c4af8c481109362388cdada776948431706126ee17fbe56423060484fa80c053641ffc548dc605febb4a0827c1165f69e96a613e672acfdc86cf0962408481b4011c5bfa0b380f7ba125219541a25cc9a2d7553947cfbcc85a29b7300c7e6c3c4ea0597d58c7d5275a765dc1c66e1aa80749c64432b80b4885ddc86260c816771624895cf2903648c94ad1ba3a4b2e88d17b0bf0b046aad8189555134ef453d08e40715c714231b92d817495ecc99d9400fd842a8bcfc2ead949bd349660343bade61808af57bbd3ab8b535a5c583769f0ba0f3101979309308807b80106999766861b4033901a8570701b96c6dd99ac547a4266640c3b276a2e05a870c8501dc8a37fe167f14a8773a06344db78fd8e7cbcf7161e6c904ac2bb8b653b1923a5fcc6947627535534b90d8364701d397fb42beccc977ae7055db28408e5991ef6c7024b66fc1030d9efb6476509bc605cf775106b17a9fdd46ca1ea41d4767accf058f271a305426c9425901c4538aceb28db1798d70bb8f62a33dbce0867c749e09db9299d13eff871843a658a89b5a51c4ba1a60496edab6760a9955f351fe317972a63df9142c4de77c81934927994540b49b52542d6dda6d260a9e5fb5bbf9878bff6a8b2078ab00270684cc43008d7428239d57e988a11c3ce94015cc4b4ae85170aaaca7162002feb9501f2176cad02bb906c864010bbccaaecae0807395256e2ba720f72f02687c86036ce7d89e4258c55b3b052fa1c3a58778e5e15fbb370d98d936adb67668f4b3e23c8d71048ac7e37a240b6b4edb218f968208072237176decb25e53a57c42c497438338386c241ea94cae25b42c101f93823821431585a2a435e63717b7564dea8297ac4597731dc9c7b0c44286fa19b4178718092a8b07f50512470a8d5a7a3cf04e44091b2ca3b0b7912c60d694cf28183c7104841045d1613aec395704750478b416dff33344e59363c937ac4834f2240715ac503357ba819675a20c6503347e1251c5b473779e651d6e33a0620536521baffb92a70ae6cd7de601222583ab6187bd96a9094c7437730b32e5a5e4ba41dc80bcc7aa004301608f7b9960115c511b5871a976a3d51f482608878c1440561ed4a1900530b5c98557a84344de33020d3c0273c5376f7b5161a8b445b78431c273a8b1207ab63438a6c894cc6a6c52322dca482a981f9bd9aa4a6227297433b0ca995eb4678799284dd79f51cca160c8b061a258da998aa4ea645dc397b9353b6221ba43f030a7ec2324562028cab47c357ef21b1c2bd942aa0706b6d8109aeb8ffdb2b1b1684b49fb1138007bef1814acc828079291e751868ada997c21b7c3b73ca2fb4c50f52135075fa98cc7be3263599803f87c89ce748c9874819fd199cd6a690a1b277fd812412017c49a92a300bcace149b757a5e3a02c35e4b3f1d813351063a77b2c63427c1ed185f6a3836b1acd060061207cab12435c50f29342d99539770f36e09da581aff663b4f4911c5fbaa310c4a6700cc70cf53485082106ec10f9e767d4436709885c519080cd18bacda342823a32b729804e96c4623b9fa717665902443bd96bc9ab09c39055dba8815dd63d2666a29b38050e0994bf346e1b6c74e8dc53e733c5050ca76fb07bbf217bdfc3c9aa00006a11ac6723a3d69c7169375735ea79a9631a69ec241a3529009b6d41e41b87fb3048b35bb7b858d25a7c5a5069496b54f82889adc02174307d81990ebe019b4f87c5c792b0162b5ec3a12ad624984a94a4b11135b01bba7f001ae11b2eae1c634e7a2111a371949c45142c10b9b00455895f8b83386cf5101157842182c2f96ba5923cba7e52602b6ab62ce190e1b4ab9aaca6a8d24bdb3336b18221b12b01157b3cc01758b2366fc9f2413f8181d2a3528d49c36eaa0c4f5a0182f0b115a40d6b178738b99ee4bc6adbdcc4ddc0869a2aa34a60affd195f5dd228f7c9cac3d346af9361dfe9b7bb8c8300d63b7eba831aa9a73127a2b0ec2d728954076abda92465069c12c70a73dee83b01d3ae7c7224312ac31ab31a6c186e665c88fd4c31afa5614e244e361bc9d58b25c17781ee2b87cf79ba719780bcac6551a1b32f727d7dd92c58a3c440671695954dc23544e7016b940a2472a5bff6d1cf1ccb931a1082b64892c6759ce3ba720ef4c9be3b2a1f63c177eccff69b199aaccd5f8359827520270acda31b1ccd85bcb9585657946b01ab9bc4f662af4873418621f1095a044682a56342470c6d69f5ba837174a6f8151354ec743afdf5d23457805cefadf9221471a94611cdaae2495f0d1a90c781e18ee73fd5ef6a0bb5a766360a5abee350405bd87b11bac17d53092f97a58e86d6e8481086ad358ce7a53e20788500ad424163952272968204ae63125ca906449b +ciphertext = 1af89f09702793c7e58342a5bba2497ed23e5c0d64d5d664dd2cb1b6ed305fc5cd15f7f94bfa3021fd3c0411deff867155beaa293c68508faaf68957713ee3adfb38808553a55b6b98d2d514e21e6a9036c4b28baf7baf6cb00a88a666b1eaf3737eaeedc920336b0d31b9028fa676c4cecb3c0668df34c51cce7b9bd5b1be31927f17d668a390d7fe3b33897f4ff599b99e27a4578385960423f6c3846106bb601a9e1d2fa0092985d96383e358037740b07a1a617e1723d2ef1e9b3c767953bf7654765a62fff99b71b9bad600e70de3be11e67a89099bcaa097c9f13492a0ee0966c86e0b5b07be026d8a8654c8f8cf89158e9bf8cd07f4d444e5918bac6038467e2d84cb2011d79d890002e9dd7cab07d9ccf2741d5125d8e254980a498b4bf3640eccc759a4b9b2773814625099eedf0eb9dbcd6afc98557e400ff900b121707669ba0fc03988c2f8d575426a30181c0278b66766aa6456970a867c4518bce6e58a190ea688224368817206428c57df39671bbf8b9583ece5c5f484d01342b26edd8035a2fa7aefe8338fb051858c619d3c817052cb18862e34e312b8e6e9fd554497ed75e57dc97deb92164f8c649e234551a8fec5fd1a9509722ec764fca41a1475f1cca481daa96190c981e15c3c4043a19e01df2b82459bebc8534d17d49cbcdc7edb0b2d83367695cd5e89d3f5340054c29b48c17bed5c35458f6149bd9beadf3bc9d98cea66bbe685d986cfa0da184a1f953a11ff1d1428461573d0df651819a60ab234148007c2862bb4ea39945e3ede70b882400d55865a5afe4e1635820637c760471ee070448c09ab33a679fced06050815c9f00d4d15ec6ca69eaf4a9b14a1741e804346c8028ef1cea954d3107e50eed83708c231ed32f1a350ca1b64ab3b772b72a74c734401f6693d34b359c65515885ff2af3cb9cd2afc877882590e5339a5ab277bc3603f437edfe995eeef7224ae9e1c18edb722d2d20011510d2dcfcc15c3be444b50ccaef1acd4ebc243f9c0e87d988157fc061bbbb303b6ee5c2dbed55d779acec0d64fe7c9b5442eb99ff34b61acf1545ab48a91fd5781a4115374513aae182e79e9d64c01edc340d7e154a98ad60c8bb0fc5048b65d79e658b95af25aa7a67e15c620279eae112459cbdaf185da7d228bb2dfb865737884c3675a83c0657b106fb0e2c78a4098e44c900e3be0c0d90cac8b9511ae22f59e92de8c6e269bdcded9d5f9cd94f3e7392833203b105682774eaf5c33e29a86c1580de80e2c86772bd965e94ae0131e241e83f0dfb8e9a73938d5a941bcc8d76137264776751c6913c4b7691623b21712ff21c496dafade642755f72f463f2e5d16c24a2ec28df9bea616b8cc6672a0bfa404dbe9135f9a76a5023053efe4d30e7a334099f540e3cfd847679f37c62898a7f32fb0187b016e2104fb9e827d8120472d4e9fba4219380ba8f27c58297efc6584e73e4bfceb92898adce3e81c2de451d043e9b7a05f0115a5c16aaef48f3e219bf4b99c9873b4c8a900 +expected_result = pass +expected_shared_secret = 6ad815b04ad6733802832d53606b39ba1a125e2331ebb2b6f3278dc1ea7dffb6 + +comment = Bit flipped ciphertext +private_key = e96008714c9e6a8a1d2e53815be607437c3b944a4f77e836f165785258b4a196b648f154597b49b09225ccd604e52ccab9f80fdb5b27e72c3b4733abdb27c15c5bcdc4d38b8d4caf222cc792c0c2b7252b3fb82671000215f04888b3955f1a666d432dfaa023bcb34a9c284b0757bb7d9412e132656de708a289ad9592c75225c892e9b5a15bb1cca682c5409bf9bbb0c51478641780cd981f69960ddd8a287a08145af3bbd9303d39a70a5b1188aca89ec659cbc589ba4b30c047889a2549a9a3b26e5240864cea925c37a9c5ea64c8139c7c336e7eb7896221440e050ce6800b56c82acc826672f04ae11bcee0f82ab7a43f49e7357dc73aa66c3493ba540a1628472a70d25bc513447ffa9c5ef2d006cfc04af5ea796ef07d89a57954c6be031c8b0e3c3ed6691d405a6ec13821e0927ff01c425c19b2fc8a8ab78651b75b573a0984d7ec20abcb7b6f5739cc2c7f544677ad02667bca30ad15c24deb0249cb4100ecac187129ea7481c5d14ec572a646d594bd40a5bfc10486d3b3e296366afa6c9cd719cdec9258847dfe9103a7955ff007cad088681342c12758112f143e0c5c0976505cf7680ae8ba5a33235c8b3a07b278a31888bf33d00dfe163e30c288fea25a4ad7807112936d9157d2a46a1973a8c2e48ea5465c12fa374245160dd4057f22c0988c68b399049ec8ae29a3be1f107046ca0d3e0284a329889e5a70d50c46cc368becf729ef1c4157f8032f4ccc71e9a1f631b4ca0c763c8b82af9a1d28fb5679f79460b7b829a1a0118aacc5f0a8be832539329e8ac53df17399449797c523352c16710bb327ce237a2c86560fe9b9fff774645437a6939884e19fd749641ff44bf2a318a39b9ada9122aae998e00646202206d41a536059aae088bd08977ee5158eb66b535f9758fb505c35aab26e40b78bacafb2c51d3afa0e71717394f8179a93a4fbf68e860175df264f3611ce099540fe849d7ca0a241ec51e8c8835e4713e3ecbb644807dc64505dda66d03cb72fa0508291ccbc28588790b623c94da307725c83714ad340d7090bb5c25a5245c2285747f3185327282c287b7313261f35a794497b0fef870031b4601585828ce4226fba4595d7ccd8d27deea9724c0802dc02a5b3b58cfcf58fae582e729baddc470047c1c00ae913eca185ea33b1dfe98c60d475bb7111a99871a7b7082e7b02e505c004716cfbd98f2ed8c85016a9ca428b937130f1479b8f9cc822e11855a6c83ed9601bfc422c6288f3db851ba3a57054bb55bc49133576d173a013d09be4dbceaa0c232bf941fc22960da3ceadf45ff508108fd161c9ec31d52c46b4002d9bb6a77ab38eed2704e53a77cf124f1c762eb87715f0d254506c6645a956e3723bd2a65c1a27283777af64a21b6442c291a2096e8b72d6dc76e7cc4cfaeb0e9ada324b8a030262a8849053de64bbf05505e7730b92a3a37e07399126ce228a40b3fbb1c0f88f39e25235b35be0d71e94d3a59e51976ecca583313a91ccaad9ca0f916331d281aab31a469e54b871a470cda3612689404df59f4c2a58b1a0027bb27ae9e64fead12f164b2f7cfb5ac7eb0c8e195ffcec05e6a4a45f403454820e39e68aaa6c266fb8905088204c4c44f1f42c4acbb7470498bee9c3ebfc86d3201b35291ea8ec2e7c39c81cf0a94eb5cfe3c59651779ee9567c1b7b77425a351be835f28590837b8612a736bf6000650540b31c7669d6ac26511e5094c8e0d299b2e0436078773b75462a2281bc31afbc12277f7ca61a79627bca647e91c8d5362b33007319026ac2c5978b24c2ff82172bb1c42365cbf34468fe51867df1326d0ac432127901003cf5696088939ddee1709e2274b8e56b0e657989bc110bf79cdf7c766d6b8f4843915535267132b57d35a8afb7c124093db61b6e8023b870121f5e003b57763c39299ebfd35a7a03afe04187aa87a947221f8bc9657b0405b05a633b2188b99167cf931d6ecb4f14bbc91b9927a010c47d087bb3400ab5690d3b585ded2482a75606f035268698829eca28092334f732a7c99c6c581844bfe085ecf765b7a22f34735482611dad0b4a23491d3334a980cb93334a035994057536c387386dbffa9b174c36108188a02669be0cb6347c277048afb68964493b3b3dd659b0f04a4ee57780c62a4b316837f13e462994b91a20046543c5427551c42ec432a01125c4849c4d1a4a2fad25144d2516fc6c9d0ac4265e565f10497a80f5bfd1924c4b1561186a0b3c123323970f1e86af31a06ad6d31ee3764718e13b30d50e41416000039ef9cb5e1144357cc17b9b26a69667b6be9b7dd3d55532655d7b9c94e4d91a75697ad04118ac9852ad4c9bafe72c16acc557a22617b82d710695adb4bf176c5d75c5c97d1225a8dc838beca6c0a7bb6c3822bcf985076bbcbd014b8aacaa5c36042d9a73b290bae7aa0580460c8aa435ddb7c894d706fd2b657de2146802572055069049931af40ebbc562ca5b137cb44d812726a93ba4fd96763bc865abf85b0c5702ab287d0fab695d017c35269a8b178de3267f9d4c58e228cbbe9b68b2534b84156ed969b43fe311de437314278909705458bb57a2bc35584364ea33c2d2cb8d52593d08523d0b7915ce158400bb8b36fca452b08c45309fe18bb3045279456b309018a8a0c0884cbb6d46d3ac56390fca6c0ad5717d8b94a15a818a314119e6426839d7632ca2057e95b3eb878446597012353f21ec3e8d376e8f281c0eda90657b0858528f3481275f340064e625956311d7604e10f516f89c7911f35236f169c9c89aec679576c5a44fc935c7582d5da36c136717f2808f1584af0edc7810446fc5b156bc6c13efd968847415a840855af79d0379642c7855ef3149a0f8965371c774ab35501a23aa43c51bfa1b435029419acd8cb435cfac522b33448ba20f3f1875c2d8863a105fde34887cb7c3c11b7c2490a8e3458579b87b3c2a3a437115dac56bb2dc7b2355cf485b8d7f36219d102e3a111a818447f1725cc499412701a78f1a0c0dd2063a1c53f0e87c3b9bb60aa2ba352b29714bc7bd417994074b0dda3fb22a4237f30ead94b1ab85949cf18432b17c75a6cd80a05007d12bde5ab2cd6a3a37674047ebaca2a52e96f07b1168bfe85a10a2b25971d13d6511c61ed325ab928337b424714223fe779363180886d7ae25a35df4b98623023366f14b9f23244480017d5a0edb7412202283fb448e37cabc555ba6839c4b966c7f21154f8087c640abf185903a94f837a922482e3fa8d60bf4bab7b397802278d1a4eb15b82fdfe47ea995ab1932b77bab79e20c9311ead592a7c90f3d59686898d5a6249a8d980a807e8d7a9325a5cecb74d55069f213bb4dbd95297795ce9daf +ciphertext = 233386cd08f6db00eb0ae4a97d129d5d94222ce09f1fa26540cc0574829a80841b94b9254e2a054b176c9af689a9d3e481f648749094e496fd0405ade4b58e5aa5026e9306070672cd8e3d54b78461bfe727d80242f3adf538c57f2b8e7a69b109b68cd971c446a2df0b7f1d6dd6ba07312cdb4ebd137398dddf0de744348b7f2ef4471f9a8e0caa6eb5101275498b9106691b849232fed735dc7fac97760f70c389a9312e8f3a423cf3c8a0f13ff0ca395ed55b95c725f2f578a29dd890b590be9925722f85892c0ca19faa2366a9636ee8dffd1a2ef147bcb4846280cc54049a114a78ac1a923633fdd3017f72cdc755132ba7b13b1c0a49d48182e51336cfbe5ffde7def0b62bbc6d47a53160420b94103e5bc32052851d61a9dc60fa4d7f00d4017bdfcc024c9e4646c86333f716fbd50cd30c9e411899ce336c5d336daf138c1986edad25bfdd8e039715869f773b6fa81945d007e413bf796882e7491458dd0b92effbfca0cf780da91b1e5369095838e40426e3d26b4b0536aedace2f51c2ac3a3c811c46d8b297804e711bab78b63be6d466bb20d9ff2a1892d31a2d5f6ceb2c1e865af1a1718552cd4ebfa9914c1a4175b8ac8e86b4ef453cd73e7f6f2467e3307cbf95bdbf01cf3fb35323070510891d52fe6c2e23463c2f9a6abd43a1a0acf0f0a0a543ae3777296ca25554ba42f5bc065af5930c98b336861d41f3cdf39325e3254932c92bb7fe10126e49f58916d19a2a64a9f16aabeb9cecdbc85bea9027a5b8eb1c7de0ed13118b4213dd44e74885186f51d4921e52772a0bd82f13d38f91b9b424f720a4b973ae3a47821209d3a6ea65e4e3e69afdf90480557630553a314178d1d54c3ba24a3cd34f36b0443c6f9bb3924c530694ad3ed40c71b63f33fa430b496a82ed178d906a39f6907b62eb40cdc9943b316db08e0d904476691695ad117b1428d40f12f645c5cbf753077ddee237ef23deaffe728d94bb9e971a980995b5a7a36f390293814ae807851056ffbb7c75403bad54f75d8a01e90bbc4e8b9515d7e1716dcf5c7e21261cd74c7671a9944ae119983c2aee8100a1350700939e3df4e9f9c571ef88c98aee9d0fe51b54d55982883cdbc491a0b746ba3e4a2fc8437cec0ca6462dfcd12e1d62ed1895b8b8066655f77c110fec000a1699442383dbd05ac085dd92e6127b1da3cfd06f41929ad50a6890f467d56f685bb2701debb993f382984d3ab43ed4e019042766644cdbf251acc4ff0bc73aef48cdac235aee5aac41091a1bf706cffe4f30a9eab327e3735fd45ccb2f2cc6bdab4f3f95fe36630de1f8371c292ffa31a52ab114c9216005aae16fd8f9aba657734de2322f3a7572884432c0ff163c8d969deccfa83c820aff65568ddd2e873168ebbaa1c74b85f2c28213f81be23d2763bdde5c5b86f4212d5fc227eedf5c1c6562904c46a48420974423bb2948e58117931027374583b10882f23c3d32d61cba8782855e93eab003825800487d39c76adae5bc766faf533776d3ae22 +expected_result = pass +expected_shared_secret = bef44b6f28d370feef3bae40b137b9eed09773bd5e91295be769fd77b3267d4c + +comment = Bit flipped ciphertext +private_key = c8e95172ca36c7fa65fc7765b248ae30d86beb6bad97fc8f6ab243ffdaacc977ac612978eae0bfb91043ae87732740cd25f5983d24cfa9d465bc5bb6c7844f6a08558291759e236ab4e384fb1b146cab3fff93381bc2804769cd24961825ca450f4c1d9bca148c1a94b223a74533cc227ba736625e8822404a046eaf05686f95c44ee5876b11be7e859b294a3e2a3aac56f42b512c98ffdc2bbd73b5ca35af8c3882932494711636a1373241f78786ba2745735bd816a9b77b5ac8f91cbbe88b4cc3b6fc934454d7c917646b8b3c80a8559afc3c4bf71991318c5c05cc2ae4b5669a33c2d5d8bd4ca0188b389708675722e898798a59119676c0d5ceb94ab984a3b78468c686e9b5f7f4828536904cd845b1063f921278ab28861f01a138644b01447dd247476f66b47bba30b387a77126074c5b7ff7e26db8db429301416fa544daa73a27021fd9d7582797a9a1d06e7c502e114364a726acb45a5dccc44aa7a4adfbe258ffb10b69ec1ed5089529a52ab3675843422ccb5b7e0eea08f48c9a6f24cab0c214e5c90587f07204831f964b266579ba0b0848909c96a93450b6822f3f1128d33726adf4bb1cca22c9472d066200fff6633d05ab5380c802549cd6466b9251cb4b1755410353d4a0ba4969bfa46c698bd198cf4ca9d6a4146aa190a272572d87502dd929e3f86433facc1a161f0b8a0b3f27ae3362b0c5e75e1fca0bdc76080f060578312eb2357fef9ac5feb28bd93439e6d84912b3b0c14a326e5b2c48e2b22cd639e052b3563a8fe0310775b15456449abee4b0c66485a741b9d3b35311b4ac9253b371901d8c1c9af817b7dbfb851a221b8bf914d5f268b324a363490e8d5260f2b129ad7042b7c99acac8bd92a6432e353fa14243c49757b149784b31a3632422aad795f6e14855372a422b76dfc420a611311d55122e68b63aa12dae8432bba235e7d81e6a194b2f26936de2984e4c5be7e7896640426258cde5744d686cb0e43459af2196a3c48f404409c5e092371c0bdef80e5d5161cd6882a97c3a97acbf930960837a9cf05c9d0930c5cc69a0b01831ee521d04cc102de24d24b713280bae93b2637f2b0e5063aa5dc173f3b2bb94140ca7d155fde026af1b9c6fa67f8c7b84b84782ca71c3866837ade8bbbb9c9db7e003d99608c1563136d384984418471c05a56b1b4ef61e99d1514b21595fd6730d9109ebc5a5e6b02da1733270bc3c9cf83b606b37505788b7d514310286c911583dd51278870f1f2b88aa7224a65069f60307cc500648804a1e4baf9155c05c6a1399757a07c31f2b1cb38a176d58c43015866b903cb6ff207a016236f4378bd8c9606251cbb4635215f3358a86cc8213c5e4d94700002182040ba5c09c2a942874d9bfd2f83bda816de6c8209f87a94c125b23686b8b3138b6115325a88b69560be4d9aaa90c7ae43527d3377d66cab2b2e6c04d55c1a8473fa8bc9b76ab826bca6b9f083fc0666ba9aa0865625460475e4b25c7f3b48487c857eb651b887830acf4b4ace69bf9427cf5844472a4b3219958ea6487c7322f8beb2952f74fe4c7417e46ca44674c4c898b760a3dcf0078ce6c77385caad2b52ed3bb9d50731d285a0c73c3135002ab9e2032b572a88f288f52453b65078e0ef38e9cd5c492396123130d8e214119dc75b1f72f508bc87df661409cb12d0b93e06274410b39abaa812b8b00ceac270c969f092713b4c8c1a921092783036e42bb541a534ea83562a59bfe247dfb78cc4f2211af44b0f097a6ef90b23da5231e644dffa5b1b808c728bb9b4738476dcc5fd29b1237c54283b69cc394678144a150f6b177495d939cc6c2cc52850b72d1b5489018c457fc55c261a540f671311b044307b590579a8c762006d5094e47553931495c12668625b41fc04074541139d85f075a69a4a60707c31254472c8c3256443827414320d54983b310c3411b855dd3c06811865ed22690394bf7c268e748a678d382567593750477ae65079332aa72a9c964751feb99530e7b8c52c6aa44ac77d5622ecd45976a742a3fb9414338b9a1e4345db0ac6fdb766d84cb7c708d2c8cc6890154445c8357673d5418603746028d2726e162af9a45b381dcb25a088e3d4272e8b24bde7795c637ae835580bfb9820298609bc75ba7431714122ce8988d9189815c181e819c55883cac1c69094f7a77f43b3c0ac5196b26326b788f86b35d2d68657b31a960977c9f3a4ce431941e396cc06a623dfb1bd5548e909a7ec27bab32c958ffa3366926c29b80747ce6577ed3426ed449492cc2ee9a4906b9605235af7ac72253493ad96654b9a261feb731c57b0bf5db92d8d72d9e039c0e4b2e9926346ffb4ee087c5b5173763f3af449c02f2fa1d9c023fa22194dc9b36bcf8a6c69cc10a932e121160a6090009d02036e965e4301c8e2b2eee24ce19da9bda33960b2c3b33e180ec96bd43aa6a1534a652444e4efbb8fb9388fb31c72994145d3b6acb45485aa1b2ff4315423b70ffb046ec1510a0547feb673fb4441707d631f5c25e15170eb7bb67714c5fe15878997cbd038a05d91189dda72e19494ca77258bde9414d494a431495ef8832e677651ea89bad764465e87362e14d1f7a92ee03a8444202b5bb5d29611f667267cc624e11952866c5a8b4b59203b9c7d926a3c9a25c62d6aa404c9787630176015cdca4baae57bfb8e135da0832a38b197302ae8631c712d6c434a88477d6aa76b77a5cca2a84e01d710855946325da5761a869070a5c0534c382a4509ed187681fa09fdb028d99f8151bd44b20218dfee9bbc2d9ad2a997b956316e89c28afb262e309b2813b33dac4225e8a6781e2c9f12616582160aa21745d3c00c1e37ffb0b159c1b8778da93e4c20d1ec1647da9b7bd6b2c1777662e920f706a6b4b11bf4852b3ed9ac468a1332df07d2409c1c80a4d1a0ca343e71c83793f53182013cb0a17a78879f5ad35057032935fd34874bf2bcf9cc576dc14ab80200b15d45dd31549410ba9dc594f0cec8557e09dbda86bb573c7a5d2839183c900d13ec6808547f9b299b00544c325312a60b7bab34b757e9a862fed90c3f801c4dd80284b654035ccb463252ec6c90081da9b9dea0cd5e55e87d08c946c30e6c30f50f5b8f41b75fd1912948164b5f1c60964b5f687583c474b65522dab8687616740b521c67540cfeb14bb8125a8b9f2bb8b27abc3e27fb40a1d2c1b403c834b55f6b0b019a2e965b2ab186f881a726398de06800facbb48f2064040f9b98e57dce112acd2a6ef543f610377163b3dda8047125538b655d947d4c7e3d9f467d5a62cdc586799edb9afa1a2d7b513ffb998834f7a69485ab536f1aa85afd7246d1c350ee5b293c6bddf9d9d6199ce49 +ciphertext = 8cae9b7a7be03873f71f97d39940840028031d15d7b434102146d71d4a6a0472ecd440af3b7e3a32ba47a05d8c29ecd29eee8b5ee7ba1d36d1241f63750dd5f0b912b823c1c3a7ef98105262caf6ea9386173c6750a01093d2e8ebd27d26987e2174f2a57bb98501b1b9fb47f293a3974e33a44a1940a7a015b062a873afb48b3b719a213e1eda837b1d83b91b74a0f964f72714a1fc58a97fb6d2a9aba313476ca234a41bcfeefb534b55ff968dd01bbb9e0940a960cde0d06dd4a8ccc149377082f27fbe16cf8047de159a1e8e3d374d544ba818ebe12ad8a9981d132999dbe05720ac5c732a864d43576da12fb85ad0832c6ef51d33792eb9278ee8b23d57e3962d7fdbbd77f1475fb7d3532e141ad249eeec6c089e03bedb09c7f2e1b80f90e43cb56400a0833972730e1a7fcce7b7052a057a59a8cd67053abdb1054e40ce044ff379579f2c8c0379a70de1ea7af8326554989f8e55acdf3c0f680b9b3c666abad6461c29f7ac2ee2d0b71d56a580029a6bcf1778eb82ba33ff74d82ff9f69b0bbc1478b08e95b4b4b974ed32a279e430210e001f345917f1aadec46d346a9588aa03e32b8383bad3a60618d0cf9fdfb2ca43b437127ed8066966371f943d6f985553b46fc189855d4b514128134dee749ce0a671448cbb6e28bca4fd8333fbc61706f00ac1025850d51e4cf7ac22ca6d2f7e85fd5466f57899ae958c6ac38dff5ac078cdd135fa8f15963f56e88d3e0c9eb5127194e9cb2b4014fa5ea002c79ce43173cb93fd7870a8528c4a5f23efbab60c28e515e39587ad13536ada47f3e36e730209061620255f150a194c33d97d6a5e046e627c292315ae000cf87ec0fcc5ffc6df3e4febc7cececaf05d0ac96299fb57a71d6d3dea8d58a662d5bc91ede06da36620ffad7416cbf8cf4e7370fde479a09e50300be811897e38ad0e825ed8409f7b6fa3a39994e6b19b44c1c4b1c6c5a22c8f6424d7ec4c57f646c92fa1f6b66dfb72686dfe957eff308388ba9638b3d70d3a27b8a7e09a9baab79ded822ba94118028bd8b3f943ae80a9ecadac91c0524550e1729e0ee2b3f1883475c1d6e6e262454941267bda6e818cb4e21be8a06bf73c5d1346ed23e85da2485cac8980b06662018eb6011f19fa8176900ad4797e180ce376b0ddff1f1fa7abf8496778a0870322683db0de46a5d99cefdd5c7ced55ac4fc622ba30fda5d114c1edeabde104166b9c5badd59ed1bd34fd1412750d89fb1697ea741fe52ebaa2f72ec13e4f72e0d5abc4f02cefad4f9e9ceb97d7a80eb098f564c6b61e08c95b431fdc06ceb4aea61a8d1f0d2d73d6cb352e09367d5b8ee901c00e0496f90043da4b71b2549571ef1a708ac6c6f83a8fcea684db863d146b5fb8a52fc51bc2fcf58fc9bcaccbc36e4af0cdee88f9a0db316f425f48abdeb34830d495a5b640659f5cda38fe2e423f4b7d6340f0de1c965288686d34ffd89867435526ad1e841f5a39bcc0acb14bb4ff5a255f0d4388bad336cba29830309eac31c89ef687de +expected_result = pass +expected_shared_secret = c2e8d6b2952dad6e674de082b9daeca5ecf8fdda7e4c83fdcc46d5eb70fe52a4 + +comment = Bit flipped ciphertext +private_key = bbd94203643645578eeca072c3eb177db98f639b9f6eab675750c837207ac691036dd34e9e46b986ec2880637e552370e7a7a161287e07c1a7f84491ecab2b7ad01ce1a4b58aca62b09c88f3224a6b13c6a33444b6a636a3f9260f8b1a5b46b5259a21299a3ee7d79e3595473bc8237fec2b9216455838b9280ca0d3395ba3fb03e7b727f7e660d6143d5ea49257cb3d8bb102009342043168b57632f4a1be5c57a4e5f77393ebaab911b628ac41e74735a3db2f7c857a5b442a45f82bd338537e3245c6a66989f33cbad92350eb7d22e005cad42d922ba8ccf1299d05a433201b6165ada41034464562bf8a485aa088d4b15cbed80161c74f4976aa2088307fc61a2cd9457040aea51b4505265b7405247671271362b828b84131007c8b07ce6f40772e4786115c63ca3b0a1b7c86b1d677023aab6fd09cee027d36f493a5598db7db6ff4d96349e928555563b7bb961f70a56287363566a9dd08463cb2ba3b758726c0bf0184ca7b460ba2e5aa54b5453b1ab89f0243edbc1429950a18570bd776765190a26bd59dfcec4a2248310d0c65d8153ad6b3c6afb5a642632aa6f373447a7698d804f9070150762ccd94aa5bb847c02b9498986a9806accd8529dc4a16aa221ca01b8c1c1041a273b1141a6b2974701d0bcb5338a3638799a621bf3c0210cfbc11843c666481b0fb062ec511b8b092a7e323b381c52dc524461fccafa7d8b51bcc1dc5d73a48331b17100c57887ed2f04afc4229e237365107d00002695edb0ed594abbb83acfe9871a1c1bbd3db07c77792602b67f7820771b85e8ac95583d12da8e36689825cce715845a90f03aa1e674643397c3c6a2358f0e7870337b8368a112ae6761616433830a220a4151522470d097aaa3cc6feb8770a62772162b80f3c438fa3469d556188cab96b070a4bdb9354fac4afa7c92ac37222d741cefa568c460b756810d2fc83a5d4032d00569aba0a2867c092a0bcec2c24f44459f85bc78b472c5925801cd03bbda889e521ade8d39d3245682026cd27bb4d6f1209f793b63a988800fb00d68b19ef4077613c9dd3e6b4404374ebe5497a48b14ffc42fda27692cb54a3a13e3d2769141225c340c62b4c6c14da3b9b29be18822a7c050cb97765dba230b5d263c1317dd4a99d8ac96276810ba943a594d4a3ed1a51100676c1dc1754a92274db2f0f734dcbaa668cf3c25ad72935fc79a392850c9308bd03cc5ca33eac009b4a702c871369b165ccbcb3782817272a090e34e263ec96bec9006d19e899c325a6e18b62b38464100266d0f714fafc9f5c4a2b8d4872bda509d6dba0344045dff1adc3171ee6274c1239a510835a1ce9905f07bff859b8698840feb9c6ef091d2d1cbccabcbeb51b71ae320c868b3022c089a0e1c21502cf22c369300b45bad483c7209122e9c9f363411eccc938b92e6ae8b910f24046f203db48b934b5244bec7ca75b3a754621ea239a29e327150733fbab55b93244e7704409da995fa2b9af31ca4d350fe26a3e705cc9cf4c042c9c9d74b77b6afa48de837aff624bcc37a2e9317faa377cccd05777a6abc1c3157154bb80c59019202af55b3195285fd7612e75d3bd45a9ceb1d13c47a27d7867afecd803d448877560422e849e8c3641eb999ba2ba10d9754e70675442ec665671a16bf40af280cf6023b704f4bb2a7428ca4a7be90970e549bf2910867184a664bc85fca0b70518cc9eb98b15b340710a589335a081aa4815e362d4124bb81c17256621e284bc564480dce164d8c94862d9416b7496e1c62724c14373609b3dcb30adca581822795c0ab6020b3a25bb2dc596026507508d076041e0ae3b5581e1c39a1bb7c893ca9005633e2cac168447b1b93c5c38c53d2472b8c39a112ee40c23b8a6b0e97eb5eb294549c7bab57ea5cc22e0cbb515792484782a5a83a1202cc81bdc6886da1ffbcc54454999a1db6b8717ba32c3578265759ae153651b04a7540f3c85b790eb77cd438fb01891a6d0495ab34e01d87bc76cc6d1f48116eb30faa40bfb23b16d82c506fa3daf4bc3e0f12884e25bab378b3d6541a2cc934276ae5d59a19b865f55b19b5922180acb3c97d78b5c134261bc336e028430904f7b4bb1a31b2b47b1836cb600cbfc407b103b29f86b7143380af85916774f10c4355256021e991bec6048fbe54e7e62ce8343a2e0b8cd348941db13a7572b1ecc1824c3d00dde7c6bf2a98dbae64e3602470bba151e6ab748f7c2b1fb95f2e77c2af34b8d444b5952c67eb440e7ba9518c53b29237697f4191ea7ccc4804ff2f12fcc46a7ffdc140813c92d41cd2480250c48ab4e979a78d751acba980d30a550338056f6aa57e5057c6c37705a2b90caacec80b1e0e9caa966bee8e411f943794a1c148212032bf463f5c673a2d9a6c8f405bcf71822911b2265bd961a2ab4b335236574d5054a54743d8ea0379ca13995202906f1856a454a26fa363a8b9e9e3630825957d19312c0718146e03a50632d967012f5d26562c2bdee9b77ff5a78fe4613ba88be7fb58f1119cf5870a83e210ff2dac2c186746a630c2d556393db1f23319fdd15a33c64012d0a0bb69c226b25c29ad898b211adb8056276b56e2c3c70dbc35b6726900c26414581a16bc364e803a3d6f83f4b98c827288840e96481f27bebf134b6e60e81833b927c9e085929d2495231e1263c7a740c7a0ef6379e38b20a15aa867b437bd0c4808692b76755c5351639b224c086b79a15c46f0ed2397cd20917d20df98600e3532deda4b95561bd60b037f0a27b65000872815efee37bd83511add120d8d0965d6035bd548fb9505ab3b703e9ba117f192f740261785158cf5895a46080d1a72598793e995a1a673c4345c62f528b084788c5a5e186f24556ab418787a498c3cca4541a03866bb696288196ab627c8a4c046967188ca1c4f347f537317787cd0208bafef92aaf7b4e7ce03a4fb213f9581b5ccbc1058b620e58c460020c17b565f02ccb33f9961cbb31a8f119aec66a821012f2d84bba5a4b0ed17a4f204f5f083f0ad0ba53d86f61c72e7130ab1ecc1a68a5a922b3609e018f74a2ba6a137c62c86187021524a8afa4d29ca3f81f0ce096aedcb2d29a0f0ec73d91445b4c4cc3d349c8ba1b7160727fba8b12e1fb75e3bc5a6bdab4ae697df72bbc86852cbe142d008d2a8ba97d1f7458a88697c6806354d484fb1557b9f710d5738d24c61344dc6a1d20c9d9399e005c50442068a8d3372cd20640942ffce99ad78e8f318fd23901dd3309bc14af9489c8b786eb37d9de1d5bacae9d0695d1d6f67c770e4896b33e6c27db507c87226db2f309eb3bd06e861e1a41cdbb2d50a62d85e38482b01af69a14890e73789cc93bbfdfb192eca7b1f8d5 +ciphertext = 71b3f7b1854b718ba36ec5ce644707a4a57fdfd5317d511777d2089ee664a5fa7f9a2bca7cdc48673389275b75037557f43aedebd0ee05c23b683a00cd31a250ac7dc8c5c0c7cfe81118b605c61c2310b04d8ae56268f34d1dc3b1bcf4792322b15df2e651fc3d41137e2cb3fe163a21a7bcd79674f4e622abb6bf9a31f3b2d94b723ba2f5364080920833059292335459466f16c991c067e879f97fb9a0c7c68be505edd288fa73faaf57d8a97ce7d1d91dbd97ad3580b170e7080e62fbb3ba715209959f5780d89e6fa5718b9e4c66c9d996fe87d8890153090dc9b8f4654f67f074b90636d320d759c0c9d1663ac38baf9aabf835dcb4fd1f6d69814ef4c41e14c9a59876bb290d339d9cd3963278040869ba1f959b8fb6f114cd884075135f3c00e96cc6b11bfe9f44ce1e4e1d8fa39cc87bcd149beb49d363fea1ef0b4367afdfa073fda2060dbe15298684c9f2aeb0343855c5f4fa587e280ca74f933179a9031cffd3a36cb058fcaedb76f7ea1da36f0c03898fd249e496357da2455d946015a087b68fd96a700b4021adbcf5248746b48b0cb8be202224e89e450f4ac9bac943718210412eb36f701393cc8e3c81c4e99862f2f95e7b02a5b9abbc76ec04ae1614b900179d38bd3a2ae332add17d1d410f8e6e204ebeedd263260e7167675f8af00605cacc33d02f80e7e7561beeca0e5375c2b45fa681a73b835c92fbb68124ac6c9961c88c94108aa65aa39173d132f9d25795a0df44bbabde521f99a8bcc01f870cbeb1cf3a7ff767fa5db326c09d7d140310027a7b0c0ec0e041a9ea76643b0713c91dddd6f1aa3b5b36b1f908845dc07b2bafadcf5a9e116a79248691dc6f289f405ea49d11fa4fde79402241c008fad1e1f18b0e06a745d4fb364e2187e6ec951f745e889c110e19b0adddb72eaa07b3675af5c6323ec6e751db7dc0d798b02547a831993398eba9e1210b640eac019df302b8f674115deb3290f7e2059dc1b468be5c8129e721de81ddfbcbb5b10e31e5866848db502d7b1a5be7b57094d0071b8dfee745ef2c62e14959e8c4b3863000a2603734b125d45b26b20ce187352f469d2a2030f92cdf92e8f27e2cdb87eac8be1c1fc89a9a9e025b720b8d693eaf924f40fa1cf130b4992871fc9bb0b6df5246d972f3f52903ab95b15119df7ce7f4290e392b75664db035f9c5964f24eb38653143f60f311d6d2ec1ef3da9adf623ab99ded8628282458d921db6f2e83f49e6b26bb9af23f1ea6f1b3c385246ec225044c69a59358c7443c4ded4384621d463c64465c0aa8a5cb6752146d5d00258e63ef40978c29b229f326673123008bab2fa809b69e69c4ccd120fefa2b0baf7d0b1d5058cd9f6b544ef1facf31a77d412c244ea015e3d97a9d9bc8639109fa243cbf4f90260887b5e9d1ba0806fc8c19637dcad48b21412dd76493b9f0c6fd06361b5a15c800607163c590fd71a6e6e2212d9948ad98aedab07340643413d7a93e402e72a450bd7c77aac8139913858def99d51b24821c6 +expected_result = pass +expected_shared_secret = 4ef35572f3c80100a1b6b7fc163787abb0dfb77208c7163d459009374e6f5780 + +comment = Bit flipped ciphertext +private_key = 75a71d4bc3a1b082c6babb87fc872d7bf4197d47a4b1229f9840200d7c6977da77f9172df98b139a0c40d0824bb0d6687570600ed898ae6a847b92368d55ae3bb9010f8575f638cef777b26765724275cb1e84418a76bf2066088e2690bcc2ce2dc2617e85b047ba36cf2c1007761407cc9f77982f5822aaa36809da46616302252a830e895a1e66c6cc1028a0058568134b0df954cc199ba5216b462f741f8d7b291c482776893ab2068e9be65f740002b8dbcfad0873e83c4654f5cd1f3c2f974c591b33983a759bec44ce8e204bb2b87a1b70396c7082d8a2562e673c88b6990096be0df955c869bb4d6c1dd7c83408ca1b9abc165f96502d9c1c273a82184cbf058bb855f4bf5b4cba5fdc6f4d4a3903348703166d6c7860b227b74113ab54c12c7850b1f1402f2d696f99c85e222b84945c8f515cc86b81c3a7e018b7c6297182beb2fc28fe6652c5bcc8c5942dedc8c61e04795665242dc034d71438be0c0425712821e72fda3c3a0edc39a6e51133347fbfa0a14c8ca6dc401a7ae2acd0000e39ba8a701c3554067edfa6118414411a0c04e55b88dccc140e275d39eac3f593c2c6ab3baa9065d41a091cd21d5b86cb4882c5cc4063d84935b541ad0b86bcdad10a8d1b3d33ea831eb2cfc58835cd2446199022576ca26c194d4b700b75b240e1d840a5546968fa74c6512121535158a21840d795fa13019f494ba9763a69f38197a5c20fb1b29454102f424b6567caacbab0abe8320dfc200eb76b8941429793731f709d1408b15f5ba91fec4ef70183c6399a9a47bac3bcc46790555078afe9227a5c02a8a985cee661b4850754b79440b0407db1e78fc065ae8bf539e3d189ba19c8d2416a829b376b449d444991e8bc149c56a0afcc67b6488e9e860a56ac2ef3b052efe1860f211b24166d83d36838268e90309950482af8dbcbd3d6bae494c377170521e5bc91433558519507c35958c723d40c42e97b594e23635f7463b3bc72f982b5eb94003b62a3f081c47e2096695098a9a746d5b525783cb9784c2315db254f82c8cc7676a66396923507e04b5449cb41e988063d7a487475544877314efa149763602ae523591c711de3c3d4315aa896b84b578fa8616e4392a928a4014edc09365073e0679885eb9ed5d6412d35a016b69d7e09cb954402285ccfcb06922111a8ab731854f4afe3e5780d789d0ce53b3cd46c74d534dd21b469488359311ab0587af11cc6004914ce986b743cb8ca5517129b42d8d10dd981665a272f2d22b4a8f1889a166aea1b3675145dc9c8c0d8426be48178bbdc8fefba817e83439c42be7a1058bc06c78b835aea135b12e5673d5b4f7685b43c1669544b0975b72c22e61a52eaba46f12409ac1fc454a54360a7f4506a5515c9006383e30aac0e266b2a56b955bcc2fa0286f601538938a349f08256c9488eb333e82169e37c68928c2fc7e013d828746776461080c83b63a29e474ba68153b9316d9c549e4b12bb382075b0bb8c0e04584a5c2ece9467ce296b24028cecd33b8b03438957715c3c19b799a65e572fc38b50c5c80073d03dd3cc52b02b71a49c154b82a0b6ca55ed570a051019a132a1fceb85872418651b8e6d7762a31019177c39ba3c61e5e0373b65115fc24d4739053481319c489352485366fc0b99cb630f448d065854a3f094d2445fc22a2750da7b6a7977636b81dfb7b5e1c7073efc4a971a543138c08545b0e9bc3075200d2aa45ff4c400cf2312ce915127d85ed89cb608f557ad000530bab5c1153b8e32562e1303635782ae480e49fb3f14b72357d61ce184966631b8e9f73c3b43cbce163ebfd88feb6b087b637dbae0be186074299362604805ace90296357f4b297f2dc55da1517d2b1495b74b4cadf8655db24e512c89104a139a4318a9cca294a18a3cd7ac971a535c783d7f235ebc821deaf50ae99a78d832903f573e5a0233c0f78e116c4b2e360c6ef93ac9f121af6a90bd331f37e3ad81367a691a2eaeca43664845a2ab871cb6c3e92051e659c8b0b5c73a60457c616aa33717809239d89211bbc288ddbb634f1387f3635483d5c67ebcc1e12592c3648409437818458995b9bd44e0abe99501ae261a030013491663e62a657ebc77dc71739b238c2f4a907c6c7246ab7e138874f38aabbfc72f9370cf4d6c9bb84b3ce6aa68fde31d9cf83224dc90bc0c08f4854682e578cb530183c21fd1c7516e424eb1e645110c8a5a4cbe39719e8fc90eceb03f94246ab713b2cdc371ea375af66362240b7f46fc5f9d0c8728fb6d1af05e04ba62a5e9b317e88b489963d19150c0f1256f423ddc1350fd8c5e55b8567220babe93346914665d55b2e9e77cbe87bf82f66b5d45c214b7805969884ee49556b73310e98974168567b504183b11e6131a89109ee6168695c29bef5360b9fa08cd6ac1d8353cf69a5a77f6cfc7dc2ba06ba15ddcafb80931f2fcbe230804b505941fe71ae88029280a21e5d8af68771ff4a7158da0c31801039056034df5a8c0a1b93e15cd7769141381026dcab830e4891c78324b09ca40c6024ad77b6dda69d6741f2ba844e50c747b621282717805d55e21e6900e426dbf8b20206c786232246b5b91c1f67fe9a4126074174a85ad2824762ce892896b749d6890fe941408e50894a3913b1a6509d023565c261cda7069626c7a95c85964b3373a69c3e9322d3882ad0c21ab6236b842a5e129021c3b2509cca4b20ca15b6bbb909526d953c272e44fbd76767b47b41d4a5701ec39d9420f2ab298ed492d278592076320a0e0c6c10c716bc5af21a69b981498fdc1c312b5c68fc098d962428c77c014f91251775fce74643d11033c871ac3c579e6835efdf8b3f601af313448f113c8a5eb6bde7750fc65355c0269e800bbe817089bd2747366bfcbf11539193c5eb8a6b9c21da611a0ee169dcf9a8dd8795a581a4455388823c7961b46a98edc4eb2b56732fb56e12b902d3935a9508e5f101a5cb893911b3f717b0505261c65d86e059485d46b90bae48100070aaa9612d1068f28d8a5537b4269c65251648466757275734ceeec4245fa5d6f99131c4a9de9e3525a77bcde109dc8d400df593f4d978e217a5ea7f4179160af6764258f7ac0ec8c00ef16749a966136b75498146c7dac6f4a718299e9455af065974610f3b80e1c5855ff4346416661dbc06289289a373533012a3b02f7b59ec7481ab18f91321b09531bc273a6ef77347a7aa045333a1749b1a165090adcdca57e65533f679bf3b34d969d935358163ef477137af717498437836721000cd814b1d77bba699d660079c3f7313d049c85c7efc902e3758499e80d421846d5653b79317045e807ffbba9ffcead4faf3288e5eddf041415e7a6590fe691 +ciphertext = 5f3e8c65b679b36f488455e5a0f488fb4efe643c7912ed07de11ac03ba29042e144a7ce6b7907a9090650ab673bdd56b2b3eb493dcdedace52dfc6b8d06d76e1751d95e212aa9870b6fcea1bb34312c7d4cecc61d01bd564cb907867af50e9f0d132be5ed6ed9b8450727231f7776ddfc78a7160da5ab2115db25fdb598d7494411f0e939486e6cd6c6206d926e8a495bc0a98bbfac26f7a3f9d6bae01bc2fcd74a505a3aa9cf34d7d51f5287260e7dfafffcf81d95bbe32105ebe041b57305873debd5815d511c33d3d31b1dea59b0d06f5512309ca92e7d0d9796cb53355ac9e83524b0e2d1b111138a426eb8d9c786405ecd9cb7adef4f222188e16a360c7bfa8860e1b3038d615f0a980a33ee10aa0c259c6902032239b19a73945a9e794912c745f9b02f4e816f59f8a9523b0e30befa6f6d3cbf47107ce4e8a39f30b104b29fdabc378da84a0107f7af75e41d5b61e309fc4a67e98bfdab101eba2e243e8c5a83bf3c80d2afaec8f47c9b88d71403fb0788e654c558422220e2cccd27c6b4e63d67761a737fe49275d2cbf7ec2b4b6752972d77045dc34c7a46ca09ecdcade64b9fb06b5b08e33d6ac3d0ee5ca40a5c8a44050c1d89ea06fa53ca3dec63336cb66cad9a59b192299b3c93b8b6d268966cc7f1cfcc90b78418405f3058547dcf6206f72c7812980e2ffe30655c7eb60c945d5d289b1fc04378be480e8a0e68027b92fa543cbc6fadfb8a7054fd650eaa23e67b75d2ddf6b6011ee2452b41daa6be1ce2f1a24e856bf3cb8cd0e75fc927f74bc62f4136d8aaaa4c888965bc61d80f295fe57f7a1246648d8472d561358fa403d8df15baea09cc446efeebda2eb42ae37c3eaecbefa04db9316a80441f80f4528d5d8f5a36276131e4b6e21ee4dfb9f31338e009c631da600d9d47349a56722794f34c9118984f4528e4941bc28cd23acaf6aa1adae9593d20c0a08d1ef2e25519f6de660c683f36375025a6bb54857cb65ac10988ef93a51226e564e734a4af0364db5cd7002091869ff3f83c7832f8531df9705336802c4b414dfd7ce6970f3934e3e780c1005d3c8eac3db3aade8c1d0edae80ea0530b90d5fedface48b0e05f00e8a78ecabadddd54456fe749189dea741e191951067c6d9f6c976b085bee055512f2c17fcc8b4c8af47037a58364091fcd9a15cc55a1c2d097c0a5c81cca16120900e62a6dfea04907abeadb3e05a8354fa33398c9b75dfb41712bf87830ac4bf1002d2d9a6b1796ae4f17441d8f7eb138aaf49d29cf8c52e8edd7d191dc9c5474dcf99ce8cbfa3273ce92fd983556454c86ac80e1c342257dc917f55635462f91c96640e6b95b23a177987ed87f0ec48ed930e9db49631dc594adb310890f82ba341c6b87f04a527cde94d965e5692f2e184c2460d5fb22be5072c79f092c5f1ef71dbac16d0828b746892f4ae309766b4c1f3c9c44e6478acbb5d3602da96301f78f563d815fb33594c19ba97772976bb08cf8cbc2195f587c2a5fc0ee0f0359551adfc4fe552fd6 +expected_result = pass +expected_shared_secret = 7eb8c5ac7c5ac2eb2e227791b4dab72f5b63603d7d973bedaadf66780d0750f9 + +comment = Bit flipped ciphertext +private_key = 7b6acae743be39e1bec705984fd68f029aa580067dcfd00eb2b6246cec916942ba6b6c675859823af080d5e1cc4a8650828218d57ca6ea2772eec62a00903c1d2b58ea247f97c469e7c4b615681ca56361a69c3d93b11bd600603a16c75b0c205b564c595aa3c4758f4cd696fa55a7769011844b3a98982127f31d5405232fc9cd0358735a458349452d447c35701a28a8b57b782a103ce292501519f7513f29cb6de8d8bba5bbab78f262f33153b119c6d7456c772582ced621aa2336f8108bd1017e96b620e4f36445f0545bb77fe8b74509a53cbff2bec7b2cca3067ac9301269189d4631b1e23748e1743887c0b1b87a4f2fd8ccfe29603273cd74d0c661f22383d23eb5b5c6004d489b468a03a635ccc93678485af0b0a58c488f4df3a4efac5923797ac4b789db22c48704669be322d61b766f2b8f3c0c71a9c64d8d1808e4fa2988f53235f967a488c272035640a8c1bd4b156aaab33806434cbb46cf670da96cc705b39c73184248241e3edb9a8e34ccc6f27757db16a9650e76f8217b697d063b33c7a745aefcb2b24c217ab64110f05dca5810cb4bcecab17bff94ced13432a015cbd0384a31124821f5c2ff8765f02c7b02a4776892359800c2e048b4379180899cb17b66aa0417a5f1c3709342a1359614398a1f89e9be1dda0de7f34703e192bbdc355265b977db3f4345bedb7a40e0705cbba18517ec74ba7c55672797403cba2a1921448255b4f041ddda737e2750ba027c3ea2549ea1a1ea8a94fe58c4eac7547cbc9c7ae99177caa984bb12cf999543e88897f1a67cc2a7c1949c5bfc657cbc35c5ba1b5ec073c19032ad354774f777f0c1ab66f390aa48bb1821942bbb45b76114ea4a27a57122f8fa756de72b64572aac324f4d4784c8c383483487cac873e6200d963ca8641aa484a76379db21b2b9449acc6784536f6eda239b2815d0f51d3755b45c85565a781447b01a65ab536b94ab1e2a2da10bc2914c60afd91b36e8429ef378db161835033eeecc17267815c78b08bc66bb94ea6d3640024930a951b9c2dd7300661c02fd911e0cb85365a1455f3b60a627cda7656ccf5c7dd5123a885b978380671e4c8235fb6e0c7781661414534c8643451cd4216a95611e6b73562f2b108a308dbc229473d4bf2eac8969171aca8c78615582155373e2e9132c7b6380962b734ba8b820ad66d33c8344bbd121af58d3044f916d599c08b22c6350a18ce1c00f68c3873d221a087234b807832b17bc146045b82c7c5074790131be40a322c10354a2c7acd4525315667767e4cac5d13c2a8092aed188faa94536f9746e907cc49a60751cb606a10ab49336729090426a4d7d4119d34a7f01aa93ec22714d879da4243f08376828a43c45b31a4a26c7b3f517e43242b1349b29da4cbbda8b7e1a82f0da690566841cd69b588c6b25750a2c406c53a2aba7eb83f2e626a37618cd3a3e7efa8ae0d70566db7ff228b5e025ae7a38544fe09c3544685057a7279c7882411df9cab505c574e916cc83b81dcf016a9da13832b0b32251a959b62e835b6b5b2a90df6c1b2d2c5c6068396c9b0d59239f5d452b3715372fe670ced8081100573ca220093828b5458637ac4982a23cf0e783e2f2a9dce7a51fac82c3cc0e6e8912e1450c1c078578591429cc641521395ae658f7c536c4fb22011b6e5164953adb807f458e917a3a9e6549c42a9cfa30381c888514521243e7045bd691212747cbc86521007ad5c7bccf791b48c3cc4d72601c2b5b8a215aba360e45d892def749dcf2aff6f9b47a0907131b14921a1c81dc3c65fb7c91e25495a2b8a5d847fc90c3ad41a6f3fc567873324988adb04677aadca84b4c489168a44c801dffacb57b754fde8568d513569404743eb88afa60b27da5124aa10c97268423b586b178b89e5b755c6845a7581e90f381766c3497a4617f7a1c601a87fdbc26eb01733bd0bf71b180c6c2217ae8641e358dd3f305ffa36fa381776729a666118141882574480fcb9974ff488d135a5f62aa1c81e36f5328781ac3510b8132eed9b4928024091a23ab802e4f150f49b0599ed2261dc82c2cb43ea2258fe1167308e83f4aba160ccb4c6715a300e1aeff3367bd0a77d25622d064763b91cd90588727f2407931611b08a22960574e23c3ec35742e369e790cad37a8630fb91c1302845c8a3673079039111b93d494672a1b19e74f04c13aea7486f5e4ab2047cbf64820d99c890b74969bb235d7b436c4d48351452598a64b35f58ab0db968d297d649b39cbb578e3586fdf55b37d2512093a269ac9770cf044583863a3e1121123761bbb6c739b480f8920856885965053dd21bce7574cb26676952a16bd89bd8d618810cc87e496a0629283dd0222fe2a4903f2b08ce898308aa9e0458305818ed61ab61fd360454652ab67bfadb8197ec4c0c1abc6caa2996f455fb2a51e9ebccf6b832465a80d93c91ff3002ac5f4c85bf3b8417086a3a551aa226e774390f8594dcae1a1211725695979f368c4e69863b0a6c6719c4ce3bb65982b8ba1026cbdd42028c9a36d7119d3fc6e871a47e25c61aa759d254a33a24a37133b130af28a87e598e0375222e18e394b64d1db9a951c197af7578d556711b9408d588cc1f3a67078c508f653d5c22a70b35ecd0842d2b8233c7b5c086c80e6007fa7ea493dc84ba948b6c1390470000258ac319399b15634b248553cd4e9b61a20b8b1bbb967bc52cbc75d0ed759a94817db5146a5e0c1a9949246163d32bc42cd538be8316dbfe3661a00a61598aa7fd80bc39115f884a1540221f4c619c5813952678c74c58715f07d8352cffdccb341eb82a3b8ad6871208d096a6ed1678a1b586f38abf3363dcb3135da1a3e794a3bd8b43ea3538b39ea720a2a8fea381a99ca064666011a366765a95588041cbdd8bcf401a014f0b728b65620b362bfd9b24505918735a5759c29f5fb67a11b7547825b03c957bef56518902ac8eb74633a63277721c72bce4e536d18e585f5dc611a326fdfca9a7c8580a8d0b46c56c55b7a74359a0ef98c16af3577d255abfc5c33b6341fcc0032226590b1d6cb5ff7850e7ac4f2f002c51060683010631aa10a042b9f5904d9c776f3272c85c63ca4b670a6228c0fc043e9d5a396631ca4367e34b00d98f1c4f7b9810b656af7782c4b13274d7c03a87404121a23a2cc17a032c1ca8cc3eb89390be7017da162db52899063989bbca823704feaa18bcecab41ba091c31136d46b30079d18b26639e64a1ee7247938567be89c3fbeec99037d6516f99621bcf8e055c149cc88135a2f6225039a5f9371ce44faf9956d17fdee66e25ad2ca1100e4912eee10aa277a5bc25505fcbcaf9a017c9aa66bedf10ecc5907154ba75d +ciphertext = 242c22e2d09da430d54c79aa5d8076a53aabe94abefb8705795d69e38bd6cd1739a144cc219959287a11396284040a19d55f67e7e9e99a762713fe35f60ce45653563f89438a779e9711951dc9e75a3bb1112921a4ce2339b2bf5ba8c632c8ecbc7de7725aa86feb94ed14b4252ade07b4d96c78b3b522c93b19903219d655b1312f6f5dabf8a1d520a77c1b1d02585e02bd42794a9cca57f3bbd76fa3f2f3ec8105ed9afb05b53c9ff6f4568daaf646218c45b9bd307c32a4b54b6d898091dcc9bcabe5e95ffd3de8c7fb31708a5365fa907c7ef3ce20edb4d246af4c63142341d5e5ff02548debd621b14e7268d3706cf4c0ce99aae8b8c59fa6cf8e6143b357aadadfc9ea6c546b1b7d7378e029564e1ea40d07b0bbb5ef6e7def3204520fe5cf8a40baad86e441228701101a8081f93df930d02593cd87b4bd61d563209532801b900956a495531de2d695970cebac5e7b9d69e0b1a57084605481f30cecc87c254e493c37b27620179dc7a9a93a2d51be73017dad2af8ce7455378120e78d4f89db22d07417da03bddf983daea03622898ba17e855519c7d6a8de1e914b5f284e847c1cade5397135a1564fd7ae275d4e55a5517f91c1f87ffe185df58eb5e5cd52ad9df9352d45c64b8566a264d1ee640b9dd4266dd761e5fd25d942f240bc2aab7d590fe5cf027e2c9ba1ce54c057f8c1f1b217bb72ccdb7579a3ef24b686f7229d0a70d40f7a06d07eb431c717a7c5e99fb295246be3dda6b9a7cfb7b5dcc1217c6a855d4bf4957f8bc860c2cd87bbfb9ca887fbefc51e2e782af7af4b2c5dcbeb44846e5d26da7630568109c2f7a73815b198f9487087911c49fefed8c82c3e2d020278b46e787203dac107fade8efc568c2b2ee54a54effa056144e4fd3c0dd88fa80441033db8cec6f92dd168901d1bf1a9540624b6b73b9b1903821eb9df8e3b66829cf379bd1f81fff3e2410b8378ced54132f5e94646c6b7e92112608d732beac24e008498e1e711fbd32a2ff2bdcfbe27e4dca687e394e6dc0bebfb04d1c5b5e53e9125a4864a33315858ef1d5cdef9be47be877e45c81dc87e0dd6e47182eb08320efebb8702223b4c1855ccfbefc621201f2f3429945b30e30a31a1fc46b6c6e0c8caa0abb0b42e2c5847043d7a3bb0755c960e416a53b450fcee1496fa552b4c9f66f7e0f6ff73dc927289c97669e653e95aac16b42cca23884069b8cf2f8cfde31076fac5ea8e30b4d0acde34afe6e2f82dabebc1afa6f44e83a8c159f4d28d322f140aa06a322d83e6215e61045862284a93f71608bc775e8578187dffe0fa362c15351db4023a7e50809cae6e9bd898cb0931e6ef692b782075b578b3987cc34d89eda1d881b121cb3109fd903bbef7e0bfbb3ada02cb70222cddd01a0aab7321fcc268c877f3f8f64596e005d861d4f72a3981f5c240a7d6f0af47e5efca07adb754e0484c84335cf596b0ed0cc050cf06f74b984057890c2b96211afc0d79a3880770ac64f63fbc2eb6f399a958c10e722780e752 +expected_result = pass +expected_shared_secret = 14d0e7b2969494c5c0ec85597130dd28fdfd5bf6d7970206276425ba9221f9bb + +comment = message all 0xff +private_key = ff3a74a3d765a93bc5e713beaa747473d4383e4853c2d96bd3fc814336816782aed2e40434960d52dc365758924564b4ba97b682463bbf1c8129265b3fac96d572845bac8eba3a94103967a5765c5e97004bbb2e7a097f28ccc4bfb06157d36c4cb76d8e042907982f76837467e00ab9b67ecba6b0b9bcb26cc53130a09eafc94fa7fc45eb27a16fe05fe868a1bd3c38784a8d0fa433d3b769471a6a317288198014250023b131c590e2cf2714aae0328394389b3fd18888f3187ba6580368378c3689cc3b48d690a2a227c742996cdf6296f86c12e0921a7051801af5421026cca1d4815e8cbd585b9b50d1caa2d2473c788ac9808d5e308833133551591f09b9221cb930fe1a029e6176e3b266e098026e0c5d4ad47a9d5c447f4c777d74098c6c408b30302a44762d406b41e73d3b16483ec3690d4b87af691db32bb9eeb8b2e8b85a865757207c85b2c33ccd5b3c88b0712766bc94229d3925befab5a4780ccbdad42ba5b336de7cae6c1a9901041201b1c3b4b115c6d22abc735018b571bb382d2bf60c0fd7cb6ab69b97d1c135fc0d24ba1093161aa599c06de209493b1be5703d9170c01565a148eca44c1c6722276548a686351c349737704b906d1f353ec64c2dd0e212b887012a227c0c38a6bd15953c640eb5dbaab6b1acc561bb3e6a4a635345f911b9f3441749b386ee098380ca6c81685a6ed7c00c749818f71a8b0865128504c97a15e866259b15b6dfb724345241ba52ca08b2a500d36811780cf12ab55de2bd3140b1f0c399fa1a1dd863cc8a479cb6eb9396c59b393195d8b0a54b0c133412704ef7391bc085d68b08b84cb2dfb4b373e7accd74cd8c084db36a9f3eb02e665948101687157b20a3a5b2321b1007b702b0f30e8a324f57c9a5d9f65270e69d4c8a6c27719773469da8f21d5748b7b35c592488cf2950c7759a1ef5c65b8fc8c6b9076e8ccab62c9704c4a9b4f6f4a97991ccb9806f5286749e115c5064784dc1479759966bea17ee75337178cd28d4c5a15450247383bda6b5fae875009ab5c41922edc21484a57405bc18801361eab80cf88a368dc88197c061433b540a923a167c4c613217696455ed935c13ba7686566aeb91c96a0a4b23294391775a100640cd62bc711b99a7c010b4d3c62d68c4e7046b7c074870ca585352bb761324e4d96e2da8b73b455252ca09e0d791777310e63748f9db65636c6897239e27f04c9ab7a2ecb7553c0492a942a21b18169f732759e8a2e6f193f0e167941c7173443aceec8af52054a9725f4a4758ec7b1a6db0a1cc56a5bdccb8c2cbc58d38cc37274f07f2c3b2051b9423820ad8cbf7331ede66c69fc4a0ca796cc5c16b03462f01bb048bdc7bcd90bbaa8579ed0bc0f317b527f16cd55a72ec596dc7c903dd7794d3a3ab11932f8780ab623ac000196c5356a858ab9aa6f7a596a19d8a470e475a4b08d39d9cf370db74004123acc7c8900373649fe74547e6bab62bca6c82590765104a339707d08990733c0a689077db122ea56ac39475ba83870c41ac5daa1dcb1ca52c52984aa41aed879eb404851c60503613205ce8a7eec9cbc982cb0846455b187159384570256744c47c628b5ab6aa3a5d8caf8b143593ec05f0fb23c23c7f52abaee39c283960036cc60af6a4b26518c6cd1921e26869bfe59a15184f8d5c357187ced9eaa7078c3327f2cc72e3ba444367dc1643f4760f3d648f1302050c978fdff774f939170b4a20f2f24e43015067267b1a3c23a6766dd947cc8ce09e747b8fdda838f8f745e9f88b5ff61f6cdaccf2f598e3052d47bac47a085e1bbb1fa4315757f9cb1f909511a76b90c64f4036cd7477196a60be14996a0aa68e0a13cdfde34905208695607932eb8e16ab811dbc38e8f9337805a16499741bc282625c0baa0bb3b2fc5df5c6833b92c1fe2a29de38a671d9a65a916bd7f157505219ad1793452c2baabba5f70b28a0a90fbcd67ef558364dc73cef18cfa7e98641e3afce97880dc25d3938c719d40980a65840f0c2a9a4142d41231a398124848e1f780af87864a310210904a02ac326bbdc1b804c89d813af649c111d7c46512a1c06a146f2fa7ae1c96a714b4a7e473340f20c420501f214a1bb253efb73a0b1b665c0a874ff7664808c32ddd24a7db131ded7bfd5bb48ebe1cf3cdb9e5c650b8371c680f8ace1b47623d38d8c29039014ad6b73637f915ea06ca61892a063545924c1764f15470d1769d25b5cda9966c37227aad82c46baa70e915b613a4993589c58e07872c39a6dabb8f0bc19b18249f7f94322899848c1028f275004b371f2b06f820c7c15b64c4dac329eb616c99c3adba45ebc8901d3537cae59b191013a2758af35459dea8098fdf8701159941585c6f55ca1d333b0c537ce91a894edb07d2ec33febe586389688c4b122f12baa4ecc20a3b5029121c791b9477c945d196c504652b4c0672f10f7b0ffb5868300020ad347a34610afcc04de318df018aa2ae69b48e71746147e8320238f125391521a4d5331d3b7adf02788c1b3cffce3981f5a49c6ec21e017a895a801499155f0fca39ab5716ba558cd81a88b559805645762a8827d88beaca6144096a59b3118941416e9fbb8af754717ec061739b6b5f155ff877cbdea8ddef2afd8baa91f328cabe07d4ba513a4f21311f07423850ffc133c47b819e0a7b0e43ccbdc66be5c869e0f9babe4516b7ab2312df5a809d9b42437738f66926971b3ea9711c821758edb2e7de8bfd82aacea29b169f04deee69c267a8af2b88bc45315e42a4346bc9eb06bb476057f72c8b71596a0163162cbb1977382ce9fe80aeda9cd3b9a68cf0730dac652499c05f38571be097be44bc5cefc4663f11008f44cf2c2283d70578c154515a8565f07868818b6c1c41b191c74389993228483bb650d00d57274a9882b96277d21553476cfe7404ce2c866cf831f730bc8c3e22603ea9afad891d5e51d47389a41b7841de4534e26b70efa3fb1a4512e234704c89251a1cf0d193222429f01951cfad38f1b5367bb51257ae0b86426a2b6ba2bfcd87f45967eebf26047826d67b03337140f42e5b035d22c566b196907096158779feb59271b3eea80bf7ab4802161ca283c6a6d74b22431bf1790b835d23664946bb16022ea76235a001592791a7c492d0e31a601e18aafbc71b04176c6dbaa9cf1c861c0c8d0533a842492a90912efe48bd659c3aff3834905c204e3776251a8bbc4ba71c76160938146cfa4124dba3bc8f09464841d3afb6b7078a0876707e61250f7a83fbfb8ac54f0fe3c5b0b84e8f65ff70414c84957239e3c4cf1873bc2216b38e26ab1bf8eccc4f9f4b5e160e78c9fe8d6d03f9697b1706bb5c347148e96b3b172f94cc6a8db +ciphertext = 1d375fb71934de8e937ecb9f3b939296081909cadb550137d49a91651b982cf839746e1b46809a058201d699eabb726734acfb06c4417fb1505d2b5b77782b7e6e4914fbf6779bfeedb0cb281ece21f3c0257cc1a3ffa57231a04d33c81292a3f42acc637745921237b7ea0d2951e8a572ad048469a509628e79e40fd307e5c9a0e0ef3d737c34245704a7e4a5eada2a6112b61287afb6bb3e556e0d6fd5b41fef9c5e8a966745bda853df46299f13cb316bd2a4402aeb92304f6de1ee2cf714a58d31c2fa33b547a93d2fc7b87bc8ec99bafa34f9b127b2e32cd4be824fa628ee17689d618144fa7bd782f47dc63e12cc109674d27554c1b2ae405dba2f38153983baac80cec9f9f59e13b62f5014c64353cd6e16d047d662a079de67286fbd5eb047d8d80e8e155b89663d0b10997fcc54306c96f87c6bfbc38c61d5332a9b754f89793f244ca3c63cc3c4c856f20370694196ace2b5ce97d34658d5c6b365001b1b590c25260e3caee0a5fd9a9c840d69301023b885b7727ea780e50d73944d0ac277cfda42a6210d57925df5913a1369a17b21b6aae23f69c3926361d91155eb89bfe9b39a229cacf2c4e4fe8307640d30f1d17174c6e76ae1e22740524752965cba981e686f4a300438011e318c079af455e87d4a6e5c9da01be68f24e9626852495f38cf03d8f93ac491b00041aef546dca2e1a38b645d2f4f00146473e61d1150fc3bf48951da3b97ddffc38e5658842073f60eec1e12148a8cd60d2314c5b7c7d98268b24bd41498ba61d7ace3f596500e61ed27e2099b3d687622eaeecc1a7aaa862cf2604d15a6b04bf1336f39d1b5676d6e3eb67d653f734955957f18b6972f87ebf1dc14f277880f1c274bd029249183818b1321f130da50b85f5e2c89363dab1184ded2feed5d2dc29c9bed46ec7e46d5d508eddae181225bf686cf2892b2b1b359692402e0bdc224868313849fcf7b15d6c7475f8191f42c7f6cb3acb4d5b9858c5fd79133395be6c28b6172b7d5513b366ac293655489dee6e4f78d58f21c6b8afd3d4746f67e02993e76f48f7fc9dce1541e7d78688cb2b6b1badf2af7036441adb3741992c597365b06ff49ee206e29f380a98ec834e82fb11306b7113d5df273caf4ee1094716414fe47643c7c818ab17bcdef79ab8485e58ffb5bbdb98ac1da3e54503ad0e867f9fd4befc753f73aaf442028295be1a1a146da3de9b74aa1d13d5f1949b3af8fafd0e3ff5a4786a70501be1be7449d41cc25ba844389da42f27ab149b4d931f6b360373307c53782c292150667efffb953396f3c62c5c36a3557d207791cde06c5547ae66b1c49d445260a48113a7906e0cd7e8a1e0543c08b91e755cbd8416c04235768b226405daf93821cdf4126969be472405c245124b3ae45bd4d714bd38253fb71fd848d3725329e7361b43dabe7ce3430193788a84b86b40d78bfd835f6767566305b80e55e0d93574b1c2887b755e13a6b77a1a779d9f84bb7c507ffea68790f697f45a9c7daf225597ea353 +expected_result = pass +expected_shared_secret = 737ac6ead974f733d47ed88b8873c56bbb898b0314db75c0b5eedb0961afce30 + +comment = ciphertext secret and error zero +private_key = ff3a74a3d765a93bc5e713beaa747473d4383e4853c2d96bd3fc814336816782aed2e40434960d52dc365758924564b4ba97b682463bbf1c8129265b3fac96d572845bac8eba3a94103967a5765c5e97004bbb2e7a097f28ccc4bfb06157d36c4cb76d8e042907982f76837467e00ab9b67ecba6b0b9bcb26cc53130a09eafc94fa7fc45eb27a16fe05fe868a1bd3c38784a8d0fa433d3b769471a6a317288198014250023b131c590e2cf2714aae0328394389b3fd18888f3187ba6580368378c3689cc3b48d690a2a227c742996cdf6296f86c12e0921a7051801af5421026cca1d4815e8cbd585b9b50d1caa2d2473c788ac9808d5e308833133551591f09b9221cb930fe1a029e6176e3b266e098026e0c5d4ad47a9d5c447f4c777d74098c6c408b30302a44762d406b41e73d3b16483ec3690d4b87af691db32bb9eeb8b2e8b85a865757207c85b2c33ccd5b3c88b0712766bc94229d3925befab5a4780ccbdad42ba5b336de7cae6c1a9901041201b1c3b4b115c6d22abc735018b571bb382d2bf60c0fd7cb6ab69b97d1c135fc0d24ba1093161aa599c06de209493b1be5703d9170c01565a148eca44c1c6722276548a686351c349737704b906d1f353ec64c2dd0e212b887012a227c0c38a6bd15953c640eb5dbaab6b1acc561bb3e6a4a635345f911b9f3441749b386ee098380ca6c81685a6ed7c00c749818f71a8b0865128504c97a15e866259b15b6dfb724345241ba52ca08b2a500d36811780cf12ab55de2bd3140b1f0c399fa1a1dd863cc8a479cb6eb9396c59b393195d8b0a54b0c133412704ef7391bc085d68b08b84cb2dfb4b373e7accd74cd8c084db36a9f3eb02e665948101687157b20a3a5b2321b1007b702b0f30e8a324f57c9a5d9f65270e69d4c8a6c27719773469da8f21d5748b7b35c592488cf2950c7759a1ef5c65b8fc8c6b9076e8ccab62c9704c4a9b4f6f4a97991ccb9806f5286749e115c5064784dc1479759966bea17ee75337178cd28d4c5a15450247383bda6b5fae875009ab5c41922edc21484a57405bc18801361eab80cf88a368dc88197c061433b540a923a167c4c613217696455ed935c13ba7686566aeb91c96a0a4b23294391775a100640cd62bc711b99a7c010b4d3c62d68c4e7046b7c074870ca585352bb761324e4d96e2da8b73b455252ca09e0d791777310e63748f9db65636c6897239e27f04c9ab7a2ecb7553c0492a942a21b18169f732759e8a2e6f193f0e167941c7173443aceec8af52054a9725f4a4758ec7b1a6db0a1cc56a5bdccb8c2cbc58d38cc37274f07f2c3b2051b9423820ad8cbf7331ede66c69fc4a0ca796cc5c16b03462f01bb048bdc7bcd90bbaa8579ed0bc0f317b527f16cd55a72ec596dc7c903dd7794d3a3ab11932f8780ab623ac000196c5356a858ab9aa6f7a596a19d8a470e475a4b08d39d9cf370db74004123acc7c8900373649fe74547e6bab62bca6c82590765104a339707d08990733c0a689077db122ea56ac39475ba83870c41ac5daa1dcb1ca52c52984aa41aed879eb404851c60503613205ce8a7eec9cbc982cb0846455b187159384570256744c47c628b5ab6aa3a5d8caf8b143593ec05f0fb23c23c7f52abaee39c283960036cc60af6a4b26518c6cd1921e26869bfe59a15184f8d5c357187ced9eaa7078c3327f2cc72e3ba444367dc1643f4760f3d648f1302050c978fdff774f939170b4a20f2f24e43015067267b1a3c23a6766dd947cc8ce09e747b8fdda838f8f745e9f88b5ff61f6cdaccf2f598e3052d47bac47a085e1bbb1fa4315757f9cb1f909511a76b90c64f4036cd7477196a60be14996a0aa68e0a13cdfde34905208695607932eb8e16ab811dbc38e8f9337805a16499741bc282625c0baa0bb3b2fc5df5c6833b92c1fe2a29de38a671d9a65a916bd7f157505219ad1793452c2baabba5f70b28a0a90fbcd67ef558364dc73cef18cfa7e98641e3afce97880dc25d3938c719d40980a65840f0c2a9a4142d41231a398124848e1f780af87864a310210904a02ac326bbdc1b804c89d813af649c111d7c46512a1c06a146f2fa7ae1c96a714b4a7e473340f20c420501f214a1bb253efb73a0b1b665c0a874ff7664808c32ddd24a7db131ded7bfd5bb48ebe1cf3cdb9e5c650b8371c680f8ace1b47623d38d8c29039014ad6b73637f915ea06ca61892a063545924c1764f15470d1769d25b5cda9966c37227aad82c46baa70e915b613a4993589c58e07872c39a6dabb8f0bc19b18249f7f94322899848c1028f275004b371f2b06f820c7c15b64c4dac329eb616c99c3adba45ebc8901d3537cae59b191013a2758af35459dea8098fdf8701159941585c6f55ca1d333b0c537ce91a894edb07d2ec33febe586389688c4b122f12baa4ecc20a3b5029121c791b9477c945d196c504652b4c0672f10f7b0ffb5868300020ad347a34610afcc04de318df018aa2ae69b48e71746147e8320238f125391521a4d5331d3b7adf02788c1b3cffce3981f5a49c6ec21e017a895a801499155f0fca39ab5716ba558cd81a88b559805645762a8827d88beaca6144096a59b3118941416e9fbb8af754717ec061739b6b5f155ff877cbdea8ddef2afd8baa91f328cabe07d4ba513a4f21311f07423850ffc133c47b819e0a7b0e43ccbdc66be5c869e0f9babe4516b7ab2312df5a809d9b42437738f66926971b3ea9711c821758edb2e7de8bfd82aacea29b169f04deee69c267a8af2b88bc45315e42a4346bc9eb06bb476057f72c8b71596a0163162cbb1977382ce9fe80aeda9cd3b9a68cf0730dac652499c05f38571be097be44bc5cefc4663f11008f44cf2c2283d70578c154515a8565f07868818b6c1c41b191c74389993228483bb650d00d57274a9882b96277d21553476cfe7404ce2c866cf831f730bc8c3e22603ea9afad891d5e51d47389a41b7841de4534e26b70efa3fb1a4512e234704c89251a1cf0d193222429f01951cfad38f1b5367bb51257ae0b86426a2b6ba2bfcd87f45967eebf26047826d67b03337140f42e5b035d22c566b196907096158779feb59271b3eea80bf7ab4802161ca283c6a6d74b22431bf1790b835d23664946bb16022ea76235a001592791a7c492d0e31a601e18aafbc71b04176c6dbaa9cf1c861c0c8d0533a842492a90912efe48bd659c3aff3834905c204e3776251a8bbc4ba71c76160938146cfa4124dba3bc8f09464841d3afb6b7078a0876707e61250f7a83fbfb8ac54f0fe3c5b0b84e8f65ff70414c84957239e3c4cf1873bc2216b38e26ab1bf8eccc4f9f4b5e160e78c9fe8d6d03f9697b1706bb5c347148e96b3b172f94cc6a8db +ciphertext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008088808880888000808808808000088000000888000808888808808880008800088088800808808800000080808080088888880888000888080800000088000800008088880088808080008800888080088808808088008800888080880800080000808888808808808080088000880088888880008008888000080088088080 +expected_result = pass +expected_shared_secret = 309d56795b2a044fb483648e7f54d27bd98d02b2f8e5d6a51f49f2130c244218 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca1c63473a75acda757b3ac6ad26221ef4f671e01461ab865f59c26f22c61de17800336b18365a190e7a123a34193f375e9f9643ae99889eda085d5317d5887e6b2c8999c133e20c49b3294aa0e064dec63c7a00acc1c08fabfacc28203e616b5a06f02e66e87fe1789725e8538b405323b9233fa61771980626b98b014ccbb9573d57d85dff1b000b38502af474add3a32f1ac7c1ab8adf93350ef1939ea376226a37c9675fa33503fcb753a1c86ca8c10e10ac74658944af239b48b97ca2b85ca4034ca7d662c91237c63c6b35137fd0429562b5856fc11662d0777c111ad9c6c34bebbd61eb6b538378b0123033c11ae1f0715553ae62cb27f15ab26b46ce4e540d39679ad9613fc91a35ca1073497cba5c57cc2c77bc75e7281e518f7640ad48451ecc32bb26bb2512fb76c9f6c46dfb6dad9c7be4762cba596184f37259143983e906002b34acac2be801c837c53771b048dbbca14b6c33e9ea7886c3be529a488aaa4deb590fdc96aa62a68f67abb4073b2f0f13a874fa7065e3c16a8b549987c5f2733ac4bca74be87f2e14cdf7d8916d47b69652244552a7d74b846961333a5755ec1179eba27b598333a07aad70626429153b7609a131e63c6bc94c32e345b9b293345598ae20a6f6cb25ff143f68e28013793183b5c9bc8a9d289967ccf613ad510a63c94c2b6b32214a9248fa89f85949ee3cbe0ba3a778ac7b754498dc3a79a95519606171608840587040a70aa1331899bb1082802c2aeef31ca2a773ef27382c2a84eb04ca518a83af9b44028c56427013b7036e441c20acf86ae09a82b8fb6ab2a234853a7b3ea386558a0bdfcb4487455a95c30cbcd54a6df965c2830f37c41bfef65013671411db77b8d69f6d386fd254ad7e175ceed98cc1e16190965b97e7375ce1105a491875007030c01cefc43e7a45615b665e073b0ba41a8309fc7cd70a271e71a36530c80ea227a9b57645899003c60e97609aa0761e60e8aa1f414518006cf1c62ea53826d53981f2264bc6c24ae072a2699886b75912ecc880ad6939b6a40d539232fa155b0d101aa7791cf74a1fa459ab8c8cafbe2911289312ca990fba952cb0253b71a792a5d9c6bfb31219e898c7125197f7b7a90aac7d527f62bb5fa7e00e106961d1babcc582590989262f1a1463e44d839221717b49b28980ea8b81f5f2cc44252c771b47d5550e3d68a8f5599aec848347ca728eb6c93b717fd6dcb7d8e338a6543d3a434245a44c2191a550794783212f44a94e46a64117f0b98157015fb0c6fb7564847703674945ca3b272e14aaa3a02cb8eb7fe3445e45940315b4408c5b4400812b0b48925862cd5c27abd9a2a0c3656290b11f6a342ec589720135a47b555aba0b098b37539cd0a05e729165d82b82ca1988dbb5bae64c7cb44a3bb190fd701b7927257a0c564fd2762f0c999341600bf86ecac593f7320e4f77bf720a42399c3b36642885b5b53a527a7b9606de8703805a72a777b1bf3674de08419e3ab4e424678e42ac87c15ed6c49afff1c246fb6b80d1182f57b6360203bb6640291a0b9d067aad6b8e3465a84275b923ea4853f799a7d31766bc84b5a0230aa43b9a3153f509b0ad9c63b00b4f68c75e29a6cf40d7000000000000000000000000000000000000000000000000000000b80a908a7f6edcb4bb86f2a0ec5da99c374870127a29b670702bea6a13ae462811536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 515463ea5284839dc84869288f9c03f0e384e56fe04c60cd7af8bdf53057698a984c2ac336de2932d3d4ba3d2073b481a125bd6cfae82da6ded2b0e8fbf7f579dfe5d590a6c03a95b53df59baaf4f0dad94a7b821cbf9c1c809b5d089d38be1c30d455ef44fef503be587c4be0929e2cbd931d10f1a8027ef2d14e15a931f3881a2bd914adf3fc93f97ceeaa8a521762540307ce5a670313d828d5ac71680d4f46bb1ba551ed7fb47e4b82e6c6b4713228038d5011df91b07ea0fb98790924b4cb859bfaeb309ffea5c2cbbf3f12fac5a063e1fe7bbdb0de70683837b180a13e0cad655b6fcd1f5b635d3342dc84298269c1de8ce6b39452297fa6bffca90ca6045cf304c4691cd052148dfb0812162e7e000dc5c18c21209df9d9f0fe7dd8d0962cd0ac01402a7f8170265af8804747857d31aa7aea612900e9067ba8970e1a60ae3ab1105b1eff223c755c045b81de79659d001b7c45ce64dfd2dc16853276b50053988337ef88e4c70ef5861dbcb8a7d6d1b2a5fc5f044160be5694e12201fc57f0c8e3ed5e48c83c2815d78fc68a118918615b2ea0898eb7a33d446c449aa92c82131fb80267666d9e11425c9bb8e10f745828b72570194465c7b2eca785228244e08c06e0d8f20222221f5dec81fcb478945564e2e53ddb68dbae7c6b1540ca7f4087d2833a752d97a69cba3f604483a6eda26e8f5ec27f3ca84730237cf1bb30d70aee528eab3e4493c7f5787f5757ca6a3ab5c278c631584bdbcebfba318db0fcdaee34cfac4422b448f00006c97abf3175c379fcb16f5b150e398355212d8c60ecbfcb3503824565bf841743bce55fbb2606dce0b45a5e2c1fc9fa20c1847e9173de2d8dbbdba840b42b002cf5c0c1d34e709816806e525ca217e37cb2d23e3c268fc4b31608f89ceda1c78c7d3c6b23863f2c6b80747dea4fd11ddbbb8421728c4dbd97fecb9bb652150278a3a3dd388789d2edf85baeff8f6153317a9cc9b72af8f69f260ca96cf602e2831cdfbc14958bf62968e7c019d7c71f6ad55fb51cfd9adf82894e56c05f6b19304cc04d2906b935639f2e96b56768abe27199b5af84268ee89c97f42925bd3350aaf8832d1f7b2225515759ef64d2d75ab29039b549774a3ed7209e1e0e50656794b315ce2bfe35e20a33bf180ac724b9a47cb9198ce2174f6b9cff075f94ede24074f169f15a8eadb54d5cd8241efe8bdac98ce02706ab86c10089ea23470e048c0f9bab797c240b5c499f75ffef8ee6da533642301c897f66770fe1860a01e82449c4259f54be74a46d96ff5c78f0c07d43f66ab578a795a5f3fca06a1d3cfa16449a278da74a5eb6f0494ebee89d4ce6dff6c008e10953b9df95f0e2e7310d33239206598cf4a729e1466f3718534d914617d260298b45a5314d045516a15701c269ec948b681a4b3dba464878a193731e174ea8902873b7132eeebacfec09ccbce7f50835116ce5b0a9e10fbc7c76559ce0044ddc494a9224bc197c494510f2c44e43b037798c1613416f2240394f +expected_result = pass +expected_shared_secret = b177b87b89197809b36026136b06fc1d749dee4cd4881b4ecf113f28df2bd4ac + +comment = Rho leads to frequent rejection on matrix expansion +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc2597a577981e1c300ed316423494735483aed71b9f85903dfca56970907910317d72a309adc2cfb0f062d4cb215a1caf67f4543f499001ec9db4db066d9989b600223d3830bf1818809881efb057a7626ed7948f2dcbb9a1582d6f421e08571655916d3a99b14ca30145e3330b31086d5a039a89ade149c9f362cd03c1919b4abe4178713a8400c0d0a21f866cdeb55b1a4202c79a5a26874004eb8a2681742f5bb97ae578faa58e856a8d186a07826a54c1495503d9180073275f139bc1a3749daccec551a809981520aab0c19c3bb59571e9cc0942799f71b502475397e9508d673b14652b65644565a436bba2aa8fbc4802663608e97a2da50249f6187217e01d5f4812f889b958d2ae4af89b255836795049b87bc45ff47549532c00499964e046191c26bdcc8eff1553ff488124d709dae90df510204f234923dacebdb46e5efa933c693c00b4823e276b5d78af2b336309919168fa38a224415ee61a6f729958f5605d57b748a09993f8c809212393b381f1e7c139844dccc37273488562a28fa232b51b6b22de4c0b4c909a03231078f2cb05581cce12432d44a66ea24ddee28ccb2a20a31130822cc74112686599ced4320878826ca51a9e892a5be735260be64c11697fafea1cfe152eae96a4d3acbf21594af1b5507c417679e6bd85e169319931922631e8042c093a6269205b4e8121fad69ea1f4037282852afcb3ec477cf7d25343c59e94e74eea681502c6939c297367dc3502e21724a77f2535a70d383a24d29e872aca63d9cbebd9b737fb2d565968bfd2a27d44061aa88cee5869e3fc96e337033de554ba4229d9ac62743c509ff3cba9c25e7ce3913e9812a5b9ae281c1374e86f653b7d78216af6f233e47a5b9830c5e3c3b932d2604c45c7777898d9078bcea38138a170fba8b41012648983b6c6e1cdfea72ff838922fd55cf1e62688798b6d425d20f2ab12c75714e8b3ec0028441259ff5aa175184731d98d2e7215c87970141580e91cc6cc2561de55387e63346acb04a6f017c9d7cf7ee39b26dcb012fb59eda233efc411aaecb51a6037ed4ab3dc227a4a977100ed804aeab9f7f585c7f5b76f441ef3b2b5b96434a647012fa13c1fabc08d1b46cd8a05753b7f7bc345847151c4a40ffb19238c122e7ca6220ed8acee34129075aae84b3732bb23257b33892c80309b89a0f33b1d7a4102d55f81b1996c90c5258a880e2aa0e80700803b9a80952316e654cb6c2349a0c88117b5f60138a571250ab0cadf7294457646215ca866487e6b8590fa926c2b5c367d1a234714a733671fe6f8b966b9b96b4296692981bd19b519a4a951eabb0d40751d916f03b3223ae4b12851b0d1e7486543272e71097bbaafce2a82642252d650c82f38a4a40b9360d789e00a3a903b71b6b91bb4bc17a67b864312c4c030127de12552f97dd814ce03ec14ce737ce3539a8f71b369c8947a759d18dc2b76aa0edf820d512615e8a7a8dbeb4d7aa92e8faca354f7192f7a42257b92fdfc017de9016a969efea146d1516316e31ad40b5829c06fac16b2c6d425b0b5aa17623af5a26ee4e0587f6c67dbac006c236f0ca216eeebc201c107b2879a247a60b1a7be7094ac8ea62841cd0933ae00000000000000000000000000000000000000000000000000000041186490472ac37b8929cbe8238e5f6f3994006c05bf47d88f1a5b571caac8082e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = d8e28962213efbabc8a9e3efde9de2573855032cecc3be756c87151a368e15e8c734155213614c931c083fa04313898680f70839229ee7f34eefcf639bbd35f3c375e49aaecfcd3b0b506a1708f4d8c26a69a46483c5db50201db95c0de02f67fff0811b43d58cfa1f2a61838835ba909e87e58708b07ed43c69b1cf67655baac003b6dd004434d22bed1aa21796d3c9c1085a2c04ce5c03797023545a1cd0d6dcdec111b896a7b34b36c24be3bc890a65d3b1f9fb96fc56928d456b845ed5b526865d9d588df3a977cf7ad0277c5e02ffb8ab67360d0009279eae50e8b038d43390000c2805875e9978879288c827fc3fd49305d3ccfa9c7fdb63833b5765b21f70d52ccf2802644332f961029dbec5c0ab56ff9fc72dc3df3b97311ba4058eee91b0634459a59213df74385ecedd341fd0b7235b9d7e061746149ec12cb1c6fa8b28bf995672f1c7cd1c01b80d2be48493988f0a43bba9ba45b6098fa8ab08ff8941aa8ffb2b7fcc82b07afa401f02f562d6b4656eb0fe8a3f8c2e97e45372c35a8b97041e4d2bc92302bd4fab1bd989e16e5ba7c315a8a2441c0607368c116159b005fc18504f12c96d557857e35726f9a4bf2c0012453663cea4481f3b4efbbde568664c54c1be3e346a499ee98e06ce2534b5d9bbcfecb804b8f4ce6b876e1ee00c12ca97b90940334d6cc0fd4cd010e3d83c7c4ae91761d8f73d699d2086e7fd635a028b1ed094e50b633d153f71161094b9aa230cf1bc005a9b2591c4ed06ed9b1695479bc67c41b0f7f3e25cfab21f06c4dfc68fdef64ea5b86ba05fad5b8a5316593c9ff8a9f3636167cb3148e97af82869e42e1bb3f110ffd711478427796256d82a665ef33745ea2b949a4aa55ab56e86d2f5feee5f0b203ff6354399a0ebe00c36d09060e467b434db070e77e9a125ea82362dc76cde94202acc71b47777e6821dc477a466caf6ac724761a1ba63020393ff2c33b6c0e14edca3527e897e184509e48424526534c4f2ef34a91a28711c53675eb4cd3c0419c747e2e67ac03ca3015e651dae27bb559993b2f0d20f0179300e5e69580323534d1289117ad6ee3ba03e3cb5f6bae436b9ef634a8c7be8e8c5567c5576657d1820f83c6578385d7911de91585a28d1d4c681ec03cd69081b40bd5143387fd020a9dc5cbd5fce0e8baed3d16ad548435db9adbe14566052c2d8d93d0b24bcadae084ba69ec63735cf19a6d46d534efa4c65bca47ef83f94d9fedd42578f794549bd5331b9aa1a2fce0c6d83a6e392cd4695e13245f8c91f3e76b187c55ccfc0c0a6344a6c89fa6544a86f762df3c59da21964ba4aed245647c56817a600ea3ad3fcc3c104197e2bc7e09fb81d9f8fb7ef559514da710f8093989f51c5c6dfe18cd821917aac8c7e9bdd9c61296ea839b8a54e466e49454e212314f39d50dc762e6c4c5623a88ddd423536aa51007bf6c56e3697c3879fcc6f2a55f0246a032dbbb073a1048f91d0264845c405c5063852cb507e4c9f3646db75c99abfadb6cd50f7a1 +expected_result = pass +expected_shared_secret = 8a746f85a41b6c46e0ef358c9407c702c86fb907e85f86de98d6f7bf7d6e9866 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca5d4aa88217021609b2499381632883e6c690d720297f130a546b8c101487a31579bfa132c9b06aaf8b6583e633487752aa9fa26551650afe52d67d182bb035848e30696d1be1e56c687eb6387043e28e6a381b4536eb18dbfaaac8f6123ae066ed7568fc1fb580facb933875eea026d182329214cc62f75383d68bccc63788d228f88d17d3aab08f91c19ded4b19a876bc19984075a529dd267b823b7c83bade5e6a782013f8de263e992031e8a32252035e6d292f6d98e022c632d115ef2c60d53e47345e470aadc7816cb6c43f0ae1ee2bec3786b6b159b8d2a958ae567f364c70e4987f237a5d7dcada9066df63018ec4b21f0000f4674a4ca155e761c41c6a54490b3c64c42b2777cbdcc5cce8543a5f9a605e7aac50012c7c2088721d69910f9b3fe26013f45c68b7b04069b9d41555b5d7339c371389c95ca419b77d2c5c1a5b068846972ddab9cafd26308f790ee0a8e7d73ad4c12c4256b237a9659a6ca866197a2ccf39c005c47b4102ebd47607181795cc66a2b677ee68b02a5fa4be222c5f2a5b44436be13aa589044b574997c5f085ca099bfe8b2554ff981d2872a78d6a08840caf9a9051609c586409923a989ab4bc1521b8d23ba04f30a3df77378ce88abf81309de61646ae15e7bb62c8f300b5a7952c5d4881bcc2a81e64a6c612f7c6a9eb8007a2742b4bdc8bc0b5a0218479506c746396867b1a869038943147ccab4a9c735fb318a7b84efd56ed70b05e8a9cd05a650e2fb7ef5c48be6d39222082080b74aa7f4ab869b4e189710770cbbc5a70193597a0282a02445c5f5772750e505b968bf5c665ef2eb79c01a8e12948ddeb641fae4c4e8d7a88d13433611553292910e831d786b0dbf5cc13f77a881f82c98263a86174223184fa96a2c53f1b77c0c12c11c54cbc37776b568b4574b458494ee6b8e0c356a4195bacdf2b11876bfd3a84804a3001a37967b40855326c261d778cb544d346127eb7091821a5bf5eb3c6215b3c7933e05205754635cb4b15a89f827289c20844a6f7e4a817bb140057991858a6091157fde0717bd2428b50711443195f4a9b462eccb9c2325a092439452aaea85521556a17102223a65452c5b152c8b476db176cf76a6575188222215d32b5c08a80e80bb84e7007a350776165c1ba259a2eb06c5a3b36d27ba4b7530a104d2a18cd896dcbabc020a6de3f09bcf24a1e5e5772cec886f5102c71930dc00a07dc71f56fa905cf8acce66a717279ef7718fd9d40864474338c0729f4cae12d2b0bfa579f742c5de322225b0c633359108d8644c47b539d3b6f99cb8bcd42d39208fa5dbb87e600ac3cb1179a63936881748eb99a7bb8631d65dce2078edcc4abf0608575977ff4a805cd81b5679899d36227d1479d25a52072c07e7ac65148559ed558ccb164b9822b5f80575dceb5166121f4ef56c32950ba46217f0dcccd3f4ab8b42b4b0213adc08a5136a404f4532449915cdbcb3fba8ba3aaa7f32a63371f5c09ea1cf1094b205b2681b476375c481a5f336f38251d4bcb652c2a849daa65c827d5163359292b8e4b98a6e6c38fa592fd068197661282d457df84367f5f46815905203d635e9540811b66b990045e4e42532862012ae783c1d000000000000000000000000000000000000000000000000000000666980dcae61cd9d2602a64f618f15dea5431543375dbe5fc600d68e360d30d35ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 1ea478e56a462e1f366f167cd818372a44d1d0311631d74a6e2ba29a86357bd7e066489d32f4eedb2398e2baf12dc4e90188b81cbd961047889a81c4a2f1c040a4527fef9518029458d524cbdd897409255258a9da92edb0d9bbaac73705614171db771c68532750750a70af8acfdcba1ebd423858b01ce3ecc821f9359c043b37dafb9574c5f4abda2cea0d09c0fedd0cbf40041a613e4de883ec725de57a89a2d0a9ced380acd54bea2eeef2abf769f81d92b302911b4ce0d865b5636372543e218e52c5a1ef0872607e4422a6c10aa77022120ce4875e9b11273281044b5d200a61e3c29a69f177a6fe530399fbfdc4edd2f0aae57102e66a4c48e549afb78e503c90517b7d741abbc2dfea9681ab74bbbe5bab1f25bf4be19964548fe3048cc27be264ad196e837e2e0fdd8475e6909d0d464cfc8df600c1a71523582378d1d70224330c852aa2f70b9536f1768736e95ef8ba0b5f595b683ff8a0a2e691522784a38c44171250719ce54cda4216052df02d164034acd650cd47d465be69399b9a148a5fff2974b7b42beca2039ad52358626e2b8d808b6a52d8b7eae2fd92a7d5b019b018f473b712c2df01295ce33cdb56cead9402adb1f245682d29af706c270d16f63edef39a49e9346a2a647aa8e481e5f72ac87aa5348af2c655c074ecaa0394bf531d9ba5851ec692f577e09918e4013ba53d529dbddc98dc041cb5e11598474f34e5356877c4adcfeda2bc44872ab538b908521088e06a166b58424a462dcbf88ba92362f691ad015083d83aa686147e635842fd2dcf58faf92d94a104719dbf7e5ea19522d395eb4e1092bffabc6aa314de0549381b8ce4b416e102c3fac0adddb2094fd1eea9451d6c14295446606f9e65ddac902a1fcbe65fdda0c1cb5322af2805dbd33633e5d5ed3289bc133983920491728c9b851b46e04c7dbc6a2bd24bfd63d3f5236ca8b2fabd0ae30506c885deb0696317929f3c8aa27b6320ee241d434ec50f2d2423d7c958c6fbfd04b059b3e98214faceb96ed5e3b8fcccf169c7873fb87c1c236539cd1297cbc9f8c3e66408666a678d80ad6e29b85df490fa0e83686aa3261cfa5e123f3fc7dab946691524bef770da4952ce4702d1d854996d9c2e30f8bd88accb0ef4917f3d5f9aa7cc51e566b9f94a3fdddc7640a6bfa0c7b6bdbce57c7fd76102dac7de2761aa971c949020cf11981d55d5a283a1b9943b2692b3a280b6312e32ed52d4f50a38f366b91cec8167f6fe4769f1403ab0750671257194b62b856ee5459d095298001e381d36df7e2c1a5c10241ed4c278d3d477bcbc1973728d7934f9ecdb0ead0d26ee993ec91199bccca33fac5881ff093880b727e2226658ad44c4edfc74b0c3893cd281923724482e1897215d3cad17f1b27dcaba869971f7e24adde068943faa11b45f88cca96997291126523d7ae9f956908a0003e93b39d1b88dabe66ddc777629b8a6202bc0adb7e97f754b0546d5bfdd2a13ad7b316d199b10694de28503e77d6a514e376bea64 +expected_result = pass +expected_shared_secret = 144bfb50c676e6c8efda24b8f5c94e9305dd281e3a6493d877f3face684df1bf + +comment = Rho leads to frequent rejection on matrix expansion +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc52a278678a38ca0034edc7b238f66c60b9ac1f309147c4cc7c78c393ec196c5b04c7906cc476b6931c494d0e4b11187948019cb75b0abdba480d61b6a58f4b8d9158486a7b94c05521fd7a1d0e8ba9c5a9612a8351f1b82c6db939ec326f34c13ba5497d7632e076c363157b156a289486a0b8a1b01a7154059149093a59cbe69ab6d8a67673b808fd217fada63f92402261327f84cc85ab50cb93517f4f3697e7b7c684064bc474ee617363f11711e4a7d5a422f68834abdfc685385877444cfab3b42a5e7649e0893d953b0db408bad47a6d8d061b884551e8031d4d2c207c93ff984b71a46c8c6b8174f22604c4a6d2d1c125117a281d37c2e001bdd6c42c3e3b90ea3c4386a7add997018a7330b0c2745f075ec10441870a890722d003d252923ca79ec870291329795072ed804a8045a34651191e824810b4c70b8a00e2c1504ea929364bef4027597f12a5c392889295fd6526f3d36572470a6b48188602093aebb3feb5b54db342bcd70c7ac881da4874f1d058dc3db26fd736acf9377ac64803a4b37743c6ea55969e13579872a6237d374adc29b5eb11a1d9b3aabc0377f550555d367cc7bc0c1b960a877a80a391aada5486c620f58182090436a8e26ac140292e547031ffb16f33c2a3cd2277a50903ebc67a22997d599a0037bbbe73057ef3296c7d3271cb17b13cc844b2aca8cbb1329b4886472747c026f63a1c4131c97dd8253c2a05e9a414b78c3c4fa2a6003712512310ab9b19090d7cf127b29aaf59923db8f33150fe2c34b0ddb8d3989513fd7b4a10495c9d86927b2cb505863b7bb3640912a39d0903db082ee47c0e8a01ab22b256682bbf6bb69b4b2394fe7aeaa939f4b624906b0c1b67665e6560f82c55b6b188aa7762ddd224e9648cc7c2c2e08589f948cc3f2f0b09150879a47a0e8bc1782c5befd0734120069e83814e34c663f115802b220f5277798076863e54ad0496aaf55baf21b5dcf60aa6ca42ef46c3c30052d7b78acd9e40a7079aa437908495c2506549750704577695f70725ef3eb8e98d88683501b3ac08ca8e5b4364c8c68eb5c7e4c690db96ee7194e5cfab7db691a67914c3fc3c219c56e52081f9ccc592de13ee5e266df71a350a63f1a63aa4984b2f4319e3399b058b4b56528bd14191e0657a76476392e9a5d84d83e87a3009b800004f60f4b4ba8d0bb2beac7362e762b417824e1539a2c39be5db8013060c76cd6453e313bbfe87a350982dc04ad7da459dbfab6c3f52b5a779c33047ab4f9ca16238d0049200d394cf44b92caec54659221e2e6b6078ccebb35b6bc045aaa331c8f29b55f3654e51b0ab20c16eb331843d2ae43749f5632056e101cf2ba7bc2921647aa0875f099cb7ac083ea662ecb0be57c383554464ea40f1248802fb9a48ddb4ba409b6db621b5395720b215efe32c47bdac84c5aaaf05c61c4dc2781a87b00710202fabbb077cc93602df8868756334362d3564baaba98c6c80fa15da5b2c924b8c85c918fa0d18bea758fea9b750da0c37751370b4300a1b6a3d7da6566375155793a97269cf4f87172832aee156ac1f18fc1179003637b3aab85db0b7b4b152b4fba7f990964d56c2dbae99d070419690a7b4293c6f3450000000000000000000000000000000000000000000000000000000817dc205a979273e6bc58838c286506eeaa89ba33d4e1971291f3a4da3a37988bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = e60755df5f91c38cab8e8769ae6c40bac77397480afce10cb1bccb30c8b8729b1bcb2d6be360089e8edbaa14ecaf528c488704870a6b9b299fcdfd910431cfb7da36eb755ad9fecaa91754a28ef2461886a0fea6c757f8e5298e047d5b61ded088a8c04787d32650a9124ade453b9b233832d699e5a71403ac186aec624d25ae3f8154c9b7c1a3723847c9b6e9f97870e81a6fac4888629e3b81e7df3d8a56f911d1559ff6f5fc15eeedbab77b70231d9e4a640ba4e1fef23fbcd073ae4c1793ad824b5c30287f24c52522e6d315e2d90c7fdf692c795b7634c3d935c98012075e0d263e917aa5c9f05ea049e1a8e8009b65c26d53017cfe5d2ca2212a78a5039e12e2b0490c2238dd693978f1d75551539834a954dac8f745a1fa48218eff905a592d0548bd927a5104185934f16c8c46dfe581f6c6ceeec019c73d0a0c041dce578ec5919b9ccc7f5df84822c4f5e82c0e020c6a9c326fdd74626da86fffc3a1067d3081d3c8ab58b3613a9d0f3013eccf6b3e5bc34bef9da1672bfd11d9b51222d109e5d3c66244d9723a4d4e1be1520a15d58f966349fdeaeb587790e2a0d87647f2445b8673be9045940b01647964e3e611433fb126e5619f8cc96a7f2f6bcfaed300592389ff60d40315ab87fd91215249b911166e648708b3c71f412c2b06fdb3fec91d287dcabe7c33b96318381fcde852017cd911bfb0e9bd09fb481af1494ab51c9057d77cdec4d615207d7637c007d2f2515bf532b7402a496d0687a82cf6a603348501585fe9fa987b47e06393f377832f16a6e3bd2022e45a81174a12de22b2a5af4ec78a55c2ca1488c564af9becdbcf2f7b635d88dfa14caf10fbe1ae4fd89c4d57eb04b35b810529b3fe3aa10d202b14e0c2417b1c2cb2adc02474fb4bc74d813dfec562e17c43fcfc1a35df1008c6bcf73a71e67525c78da2b0c5480edac41f839f8f67bddcc14b92d5a04412327a9e1cd34d5c3f5ef6cd1a59af4526d05996fc049a39db14dafd81d96a8f1b80d77a4f330747dc0bcec5214992dbe7fda726e4d0413ddac4ad0f583018a378c844c56d9ea0329904945cfb4f55cd0e0f4ff2358eed74675791d74cb7ab3ece8eefc771106dc4bccc7525e3118b8fb13956125402b310596c5ad0eea3ac8ef75f8b63bbe11ccdf7aad66d05ec052ed9b54becc2fc7ae185c9c752209d29c76bc02d1d05b693e12e660f18a326cc42a4ef4b6dbde69f4c4676c4bfbfd1bf3dd75c262e2f5ae9b4db247d3e824d1d87151c40a7ab56ad5fe9deb8ab40137860e87fcc972e12f6eca84c284eda1b925a2dd4b36eeedac18f1052f280ba55ce11f55b0f45443b4943fb0fa7354068259667defec383e380768276f97af4a0bb7dd2ef1669e69345d08155a0ea23846dbb9397cbdd023d5dbfc4a544572e82f21ad601f31cb01def894978cdb210b3617e65493f898bd6492adf5acdfcde3474f6aff97a86497b9fb6bfdc51882d3d5a3a35c4c80ca1c21fa3031a3985c7a2e34eadaf1ab6182c1a471721ce2d +expected_result = pass +expected_shared_secret = e3f0f3e54c7a50d4047b6fafea1311637c76e6a426940afc55a432bb7a23956d + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00bb3c06376046b4f295572947b7fc5597b38596655f25f6603255aa19ea7f9fdc5c9efbc5b1343b9d214923121da4fab101076d9144b2881ab988092fa858a407db97248516981a9d4c336df1395c8920496f487c60d46a97368103bb9af9b62162ecca0c023b7bcb71086c1b1ba92efa1b0521b472539b0a87030b7477bdc4d980be20ba45c0aece03c49de971a6f9c8f7522c1a4a6df1225e836640966348a777bb325c4f4b972d484a74c1c743ba88b7d9a3305755992eb5723cc8280aea6ed64b827a0518e7b4cd2cf56bcd97023195a7aca9486ce2b50e35a967da1f8c39c9fcb895cd9895e116b6f58555ae82609fb703732452dd60274ed87adfe293b5a2be5554ba0c455836c98267e77ba6f5b5dd90134e126c703cc1648cc827754c9c2928073493332b6394511e1499c0818866fa0951f8c1400fc51cb9eb6cf37b4a3eb3959ed2af6995c480844291766a66d81713aa6351555068324f84262c9460cbe041598f519c8b387b442a6d6c873508ecccf6b2ae4e89bbd1306f962915a2d759e2e8184df59620d8bd60fb2464ba40188666aad85279423cea249db21b34525b55191375c2f19dfc811d3b77ae56b9366262834c2b1dd500ac17828bcd44c024e90e06e9a7a9607aeaac2c93d48236d114d352859d9a559b9b6e003cbb9a07c65d0a9f264288083609434ba7ab3a826a821bf2db0306a84f386252f7c56011b96fab3b3fe2ea43536a3cd39c2f11d1bc62e03365211e82e4b5287740aac771cd772575c17f0c712c6e1485e8f4cb8e11a89fc4a0296b567e835b6f18946cd3887b56bc4bca9327c52239ab34925c2440ac7cfe6644c9c8058f840143d782ec82793a234e9ce9a2d2f7c96085c6899436cb9c97ba4bc3187b2ed5e622c212ab557bb828e196e0336474e1231ae72f16233ac7f844abf5434d457aef124963c85c25b7414df98bbff69008c27b9f25ab2d9990faba0bd9c00f7d27944f718fbbc1446b3a0e98611af4c22e4ae958ee993f8abc59e3c41252b160de5407a498a0d4f90505da3e90a4b2f8697e99ac7e7c769250a5bc489a74b44cae15a59be7f5922705ad8deaa41d4cbbcde7919c3360e2892914640d19765edaf3203ec950035550072a53b379982b3a3d1d18763f9b1601854679965ba34b1b073809ba675e09997a8519510780b593638dea00cba3598855125ac71c91ad671bca1499037b7791f32fb82134319b1ec041475a238bb5c4ccf3524d613c8aaa096217b5afcd2c4803720b549c8916bcbfac990ada5509c9362488d66f80b2556964a856c06b746a6a27877c0a213bd501b939796ef0cac630705d44e66a1d3c2517f940bbfc711ea1c5dba3a491b61fe4649428c6007052517004416b0201f2440d467733d923277d54bafd729d84e2440270a259c14d88a4564fc9941152b591aa644fc93abf08371ac162b9e180c0fcb2783653e5137a9faa04ba137113697b11e419dbd708f18b2fb5f20409448f31906c2a557da57621ad4242524a8f9f754e199a2b62e87132a33af47166dc614dc7034935c4b21b7c102d71762239c03084bf0e381524a94b6c22a7e499baf0ab6c9bbc8573909c8e99ab09a44e6d3b017dec2cba8b60c13400000000000000000000000000000000000000000000000000000037d9447735ae18442d1b8db2c77e3cd72ae226b0fdbe34ce9a0b82d721e8517de42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = d388adf22faa385735ac4630979b0d692aab8fc502ac7f8a0e3561400f8d04a4447cc9ad1003d530ad2f7b5da076b02bf291aa837ba4212d43bfc514ee60a422c07471572340d7fd5fd127dd82283a4e0d145e294841124d0dfef27579119d8a9eda24bec0aedce586026d1107568831363fee0187f8a0bfaeb384bc9ec4282d03acc461e26c4b2826b15943d95d96ed7cb72c53665e19ef8b4641f6eef759a1d7fe860cf72c342b3d3e2fc784269460e0a1ba6c394a9c24db5a4c5f6ac523a155491d149806d73550b2b9f8f00074dd06ba24188a3bbb5f3370f398011899758365850054928429a7565ca5b9935f5e1b2600a779152dac16e78486a716a393cbb917f060c83a5a0cd56f1ce4de12bf088cd5e80e540ae97a2ce2b8ea35b3a7011116c7131aef928c23809b3ab4a464497d4be034543d5ff1112c6ea13242c4b60503607b9f4de544cb49c4580518e15ba51c12518312cd44dfcf39a4c544c71a84cfce3f70b789e4814ffb36c1e0767f15ffdc82ae5f0800bd8e2a973b8f30f34ffc792c9f7db5a91c2e0e02461ecaeaf2ae5d33e879f01475e102f85609acd1a8f0b1fc57739c331c25bf0caccba793b659d90483c220bd9cbf0691c5a4f11fa0c87fd630243a9f6e9d6082017dfc84b6ef1cb1fc793d14aad856fbbe051c724557eac7c8f123fd50c0c8368d48f153ab93da02b09fcbe5a91eaf3ffc9a7837b1e68170cd544057afff19163d3ff479b1d2be4f834a5b8ea082e2e37d9932936e5b3ead4ac83201a504ef4bbb6621349fb473aa38bd0370ee39105c5b635c1b149e263f5513867abab92c00c4019e6206600829f1b3ac1c849139cd4e04247801b2d126bfe94c6c019916247ea2fec03598aedc84197dcf7db900653fbb5236c52b640f1b489d79ccb4e4d062e77b6f9772218f64b02b3c29044c62279f11755791d8600758850cad537800e77d7727a63802e3a256031c94f3cd3f7cd20e10a781a29c2f699a3b4425ba4198d3e9fb3e5fcc726d99bc735ff16e2d1eaed171fe4ed00b0fccd81a8d08dd5d4a6c72bb8909ab98c35e0efaea3e9a4ed31ab0c6ddab06444150d36637077275796802b792354567f2af4dfe79bbc095f2bf801db578ce720e8e4fc9ff772d016bf400e5d330560aa5d91760f3dbfe7c0a175f7d0e730665ac079b4aa29f9b51a20784bee6020be8cd3862b3d992863d25a8215e1169f5eb4cfda064cbba34e1344009b461334490f7261c9a6a4457fcfe7b8536c59a8ee36703e8b439feafa9b4536119b863a91805706dbeb6e79a9aaa8d3c959acd75ed03cf0137546141fce29dc5723db5356661b62a5e2addc6cf479cbb4b6214e44b0674381fcf8d23bff22ab413701d8613cb03e140e85e6c00f75204a6fb1ed29ce15ec90cceaed7e216876b5e5b21b7e99da01f6c2c6318591e57e188548dc9a98e14a61c472d9726cbb09635bf99b32fbad21e4777804565d749b380924d7d5de3ec6be5b4b2cd2b784abc179b478c9237e111ce04f99706bd85c7 +expected_result = pass +expected_shared_secret = a8006ea55b49d054de26ec8780ee0928650ba04f33699616396fbd980d9bbd72 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b16971c5c222e297e1951c5424665e24b2f8c0a98fe5988a202b02db7021b8caf6f390469cb3a3a44b1bba8028572290ad3987c84380706046d3147f2a098f6c11912d204ca7830b49946da095d77e4b55fbc763df31a6731b9bfe871f8f383d3645a44b18e8b59bf1841c48da75a66a1322a70c186d7751853949a83af71494384221876695a35eb526b3431b4c02a00503d962c1e35898cfe9666b5b71aa88309266ac0cb7c50121707c06086e4d7aaa918ba75f2ac0502a43d985eaec44c081b7aac733c065b2af38807477501dfd6a84436bf9609b5ee21c78e2c5ea1e2053853b0ebb570fec357fbd227123683292c58d082b4990c7b8a9b8a15b1a72017844b572eded48d2f902621280cc4d0174e0a04c712b558184ab893bb70b39f7e92b5c3ac61c4e0a4070a78a6b0bed6170a0e07606fd15f0dbc553c64672ca3b8c30821d6973a5176aa2a0343fa15a75d26953b965d64d94b6e3c5873fc2ecd13199f9caee6672847a87dc7d31534870502c3a0b9493aaaa5441099b29a2c0078854e13f15e1da411cd086a12f587ccd03038c049e8ba7532db25d4a855a1f7696a0737c1fb5e2130a4f3ca0ae1a45429a44ee55604e31858db353241d620818a5b9698556833398878825f22a2f0b739d39c07242aa2d349002979929af37c74457683f940e503ab5e475035921abc92b5850b39f6d2052f811a869c11aac93fb6e063e7b495a958670e276e6e64bb63268bcd01064a782ba3443c4e0255e3db3e55ba7082438bc303c94146bc67270a12265eec0637761c47ef5c19fdd22d4685c335146998a4ab70e6b3a9f63c7f95257cb7a7ac216c480568056a825ba6b6a25b084a604349bc4fd668a0c6bccf84db88fbd504aad20b68b67ca7d7c9881b948af06ba3f172456b250850aa03580de5312bd85b9ff9e746fb26c8e3da128e2ca463bb010a6872bfe975947b9b00bbbae5e53cace8380d1c3b34e71b35517764635f1c29be58b9aeb4704b2bd58f81a7a20ed1a0a505a994b0a8e71a72431991541c9b39d4b7de179df2ba5dbc12af93f057358301d701c3fbf119d1f450ba9900c483546e3cb55716ab5f193dcbc6c175697d9403816b263bbb71930f55081d8c945db976ff8b130ef1164d6bc8d0d1b2244a08b5903587932bbdbb7d60a29ec8016c9cd30ec7b81b1bd527b59c063c134340d35495d89f3d46728159874b8cb8edeab232885d635c1e46f4653c70c95aeb0370da4529d319a812c9b9d210f8655222ab13dae5c0f9bc3b6b55a23edc15b132c937c0833beb8058529a1f2a880d7b198c947c65db8a0423848720248d7cc937346bf0e01996032106192c58131335fc52b6817c97250d71f613a0217fec98b713a08998b8932ce850097361f077683147740a8a18cb16367fc1cc8771bb50fa550c667fa28822ca407399634eb42a79250483663708819c55fae2c4cca04ebfbb7582bc84ce27c2796955d334af342589ab196b3d03ba7b58bb209017c69a95672138b526245137265948239476496a6100d9ec7092d931f8009bfff9a7dc22908074c3e41a8e6ffcc199fca488753321467850514ff99606b7a8b975c03b05e3c031a99da72bc953db617dc41d664cad9913000000000000000000000000000000000000000000000000000000dfcd8e31042a2b903abc95630619551d24aaa4eb3a69f40224dfb4ae4538a303c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 852e70f6d10dcba613c39fef87c4147fbe2af99288ad6c18b6e266dad0746ee662ad0926f4c0ebd669b27b893777a545d12744de0ee34da7b38568eb1809245f9a03547704e353ba537f35d5784c37ca5cbf3696975aee1ead6b376960131f6e73250307390b74a10645cb38c7c16a7bff98324f994e6e3a8d7a0c0ceac903e8be98892bab7d7691ca83233d61a31c2295a134682176787a40a263f9d8a97c9b262ad343f3823739bac811f95014f6403c0bd8a7fea4064454333e8eb63dfff6b3a9afe291217b0b0178c075cf04ee3a0895606c422e24b634237c1ee72784e14af8bfcc232ebdbcd2b493efd28c9a849bf47737e20948ae7a399907b0f2a5ac9ded63aee710a30f76327f3e1ad042dc12776fef148daa0acafed5598650eaf46dd53998e6c38ed318ce56bd35ed18f99a34fcb4f427b3de31f4fd0ce2bdce0f80248ff2370e08cc2eec3e6a71783aba779abf38a8bcdac9abb75d80625bb4420e2bca3cf4d8867bab62d6b884ae9e6f98099458158947e1169685b1a6f7d6f554bffab3dad8488e0a159232f3777cf85d9dd4399a89f1610943bb7279514e0fc3737ef8ef9ba12a4db6d11933db6f57c48b54db03470b0deb7dadbff48d75ccdf374f8bab3b7d3752c8dc4b513070fcd884d94e435e63b4b40c15abf109ccc5d9ab51c4d069685550baeacf37a6736daebad595f96e2f82c5c458a27e129af4dde2eac2a5768f5e4a4970a0bc68bc4d0d32fbc275d1aa988ea425838297722b826852735c4931b97e145be9c6b399bbf4e970c83e98bd5c1be7942c6419b0819e600015ea82ca0d55894b0ace32f24b2652424b85b0f86755f1f8db64138a704cb6ec6f3e2a4a5e708713398101e0cf8d6029ffccdddd03d8a8074792232622e00384ee5b9db3535d7ebb14713a32806861877ed3ad5b293980b68f0408eedbbeee9bf449698f0ecee6635f0a8905d378d083f80a482334d30443c139cf5a1e2ea7048cc4a1829ff36f9e0f674ca22d794c2d7e9dd3cea60318788e56b3e6670215b82acdd4c9534fcf5545eac516261dbe4bb2e7fc38face7c59668487507ac122d295ca90af4035760c9b89ec44f432e8977583ea2da6a21249f667fbbb5c4307bd3f2e47ddfc8aeacb54bc33d1365ca3b6f75c0b50917e2c84849f1898a3e1c76ea67b21143f39d4002026b0e2686908bb9fa502a88c7b5c747f57c13b9704452c1ceb14a5342e40cad9987bfb32c769f110d3d39cd41178e248d51fe7d7f1c55a5f64764814495cf92a4155640a4d3411a74597f4c8571dd0662ac2ccf0ec3a82750c0ba5c3745247b7f09b62dd9c6484a1e0a0199555078d3a750784c96be465053f3e024189cfa2875b3763971b48b5c8ecd155f879f494d9be7f4e27417a6fbb8843200eefceb4334341f8a5a0e98769cc977979b405fb0efccbf442008f7cfa18b28b48ab56682a91d8362b6b5df54db3dcdfa25d4740a13ad8dbe014b210ec14af156b34511896e64d08f37b2cf2a383466351270118846b6fe505 +expected_result = pass +expected_shared_secret = 8da6007bf6e536286b9f65fec6f014680d193306a55d37978cb56b245e256eb9 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe33170cc2bf4fcc4e0ec002da4250cd5320095843f29795b36b634ac922e3796ae428c894b1703332b83d9759027588f1ab2539180b75da984246a745ab595c46ce9852029995997ab27fa2b94e165025e7e7061f2cb35a907eb6ebb0e1d2a29e139f179078dbe13abf1787c3282fe45a1578e5752b6950e7428ff2693c6e6c4ad9b960f024a7e1f41783f7112489112af688b762819b222e1d6246717b730aa9b224ea64a1a45ace60257522505e69bd1b2235f8d71f8ba5b5ed425ffcdba742379a7e1c28af1c8b35994324051d7b46a6047b77762c158fd5977e57bd4f398d4f1a70175897de6c8a3ff6ae90373065233d7c4a0e5dcb8b0731914b37cbdd29148be2649f055df6bb82fb398a630a6c556c3fc442ad78e24bd1406a35d82c5f582610bbae17d118b3f0347bd84f7b8a6deaeba8c698c456502eff6203594966c1f7413a056064d09bdd273b0ce56e506c0cce2267df24a13d7a0cb5513273f37438b568c569681314c3b6db28e05478e075abfdd53cd9291614c2650dd58b40f66b10e3a5cd11ae650aac35821d5ff612d1662a3714962b3411e5996e3ca3b839a58898848ebfb869e9b214635109129c333e931b22d34c63c96a74c3745be124c153512c060ccc6a36d244139f106bcd78808db7cd0dbc3e5b452ec753a643107a5f946b8f319a0fd28bf86c08bd16cb0324c44a0ca5165174f4681b6fe85b21791bbe1b11874270069839213b5829aca7861ac642e4757437742898416e2988c3277f9ce35f82218e9eb72afec300b9e59bd1b10349994bcb34c9fd2b31ff7482ac4c75b693af46a581dd85cf33d21e600bbc2921ba49053cd5d28595799fe23541a7d6b4e4e6b59f761e0339157d5a272406be1a776b3eb2c3d33055626712b304c4e651996f26866dd8a99c607f0a044a4ed4c04eac8122114eb6f567e1133a7d385b4edc71d19655668a86cd64503f0bb1cfdc06d9d387e55296c4a76a71b78e64daa58440264a8a6e73d2bb8c028ec970c3fd7535bcd65110967cff563ee9c5777a465003fa7ad97230c2c76bfc41b5c9d26d9a7c3605905fcd99b36ad5c6ff585513f633b26617f144a3dc4c70cbb40b7c3b8d0331014fbbb7f3c59179d226dcd4758ccc3cab8679085103e8949ea10c796204ae993750104a2123ebb902aa8902b6241be505a9e3a6734191734bba77c969e92a9c0894367dec1f0d50ce5046ad6f3aabdb138f5746a737082bcf6b8d0777b4bce1a9a35b2e0d794ef713736b4966d1322594eb8e90a5af2b42c2d7874296401f4e6a66c088a73580362031c9b0119d22dc9e6b649ff220919d42167f5ab863603d474051e3c424a0f8516ec0652545c6bf0831cd8aaa992c120d2477f791ba1ff56ed2bbc2e39266cf618580b7b19aa94755869d7834a7d4a87e234c25c0e595cea31a8715bd76d3bf5e6badfc4a758d7bcb88b5a018228c234836a0c77bed231a64249a064402d5f0b66276113022b3bca4486efa97103560751b108a5a10579c73c1e06b0eb117ba5a635b459e2f3887734b83dceab3ce9a7dc758265471b795221958359ff3ea282bd2c099436fe3d3c5b2000cf0db36a63123e9c897249130d1d27bba527eea241d8c930ff80d000000000000000000000000000000000000000000000000000000535a9913e52f1282c372204cb9bacfdb259c053eea92cc8e75bdc797a5b16148d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = b931ab298f4492e30329ab86e3d92e6241f72c568f8a2744d493c2b02b8d5d41470f0d73ffc08deb1812a6f4143f97afee2682f6d4809a0ef3e97ac2ae4468a5d436c5549f751b440167f86cf238270eb8c2e3d3d9ac004fb9ef5245d32b4740fe79543c073b41c8a1773f11b41c04ea5eaa467758660c17a6b38cf19b151e9b6c68fc35708be261a9e7cc45d771853132a5d7059e3b6b9bc94755f451452f444377be5821aafcddb7e708fb80f31bf1a89e1691009e1e36b09d754870e24fdc640afb41ac6c4260b68dece256aa9467dfbd29a25ab901bd1dbaf2efc055263f06780a73fea14bafb12f14ea2b6516c97b1a9f56713554b218613510ed7637940272b502ef32c3f99718efa3fac323207da815c6c5d04823dd28f99049ec50fbc590f519d843e0cece45713e42ceffd48dc1b7a739124c698acffd4fcf1390351af06ac1212be3abc5f8a51369c57b0108fc593c5d7185686c6a27363416e53f1d578e7066456e6164c030328ac53c2ea6fbb6ff508be8c2f973d3a43476831c94a7e85de88b71fa77be26168f82ca3620d1024e2bf998340271a4e2df0654ef1b6c9d5a8d95ace50a5f5ca3d321a9286210a21ab97d64066390e287d85345d22f6b42d597c5ca8888c1f871e34a4d1d7e89380abc284afe3f1f7784d47f75c674354825791191b2cbf5607ad26931bc0bd05ad2113d5c93c9e0e71a8b6c69ae4df3383baf71877bd3274de23d68ae57d54e3679b40950c73fcd38c1b8ed7c58f887e5cbc74bd388f77b72875828667b143571f6d0b69cebdf828b49d6f4a6d9dbbdb2188e1b0b30eea6a5b9970962f00f8b8440dda64629988de710a3e086e6a220d27358272b680a91195115741c77ff04c0bed30a2c47422664669aee91d263a196ad48dc24bd386dd9df5724965f2af73bb7a406bf9d17f3485f140b52fdbb06b9153bd96cf0be8ed4c0024571f859c8492ed4d970e700e11360d4cd51b3cb29decc38944a895978824ee94ee6ccb6988337755c07491f43526db47e557636740b393d460b3434fa70833c490ff59aa62e0fdff9a0e664dea7425ee586c29c7648a3ce8ebe5b441f647596af140a87d9525643bd97707cd910e17cec76ed33f4dec0c5222ca182654c8b5ca12d5801ea4c26bc7ab9877d9f838d8455b59c5590f4c602887e219a12077f9639be7a6f5d227d64540f3636c46cbc1461e665f677b0183c5ce13f77d923b368d05030b04c16ceda5d511fd0db061ef3b626e50767cce8a5cc108486e941b7912d944a7a0e0acdf050eab2f600c242c250bcfdb93ab9218a4b495457dddb959e0a8f976bbe147674d5ee92ba71491812ed10fb7de3e607d6ae67344e0a611a6e82a1b66e0528598b30daf398c98d5370e6a1630b7d10d98b12a1470fff4c04a1859415595362e29c3245164a2f1124189c3c0e7b0c875c658fab040c5e0ab690193e3eb1951f24ef0f39bf51fdacd68b65b445266b758dea04de3b3d3137c9445351e9fb80f394b76f24383c49c747e9b15814 +expected_result = pass +expected_shared_secret = 46f591e3c6491c7e12d58a7d06ea5354bbb77337572b70d94e4badf7ce394e08 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960f8569c9dd09912b200bcb155e7f388139675afca87b0aab4e4e2535207b4d1123062772bc8aaa028597d15f02f1240b3a4aa96c1b344b0b892bd52b3856ccf6ae94028574f13c09418eb998f741c1607461bdb8cf4094c795acada2c015bc2b5f4da99bc85b6715b6bd57aba2d016220ba2db3a9ccf6524474e0c3cf0003376b2aec2b031cc4a224b66e139397e338a8a1ca0ad7c8a8356b09078588955157fee40e4ea1177f7c13261427eb047d14a826fbdba1cf607547a93a61c8a5ba200abcb676deba97fab023f5234b46c99cbbb38f27fb68b0a2b89937be4f61b3bad5446b74542b52048ec9310b1a2c30c25c569a2fba55be118472f6147dd65b171c654e8c3acc53637a2f409dd14b99ab1a772d755bf34a43fa745f7d2a55600a8873a5cf852b1f6356bcbc2a70d134471c7720918528b63270e729472d1093ef72629c521e49508a3e584f81250717f73909e36e231b0883d9c474ea0dd64400d26317fb8569106983b4bc3d0818987adb741d547fb15235811819493c1a92f665352a92495acb6981aa5fe83fbcf620045275017bb652ccce8b748eb9354bc374c131a74854f9a2bba3173b1c4004607a2c975e3ca635737a7f5bd35c8798174f6bc30473c5e700b42a96054de8237b1927f999351f370f1e241d89083ab9cb09a9e908fa82a0a3ec9f37375f30eac10e20ae566b4ebf811513825baa99c7a9265f73b2833808a52a755bb106afce71721e71c693f29b402b8e483000e1a6375ba0848881c817b47d3cf8a2d64a757eb80e02109a8e0a873eda7333e7847902a4f4c44e533a8a8039516549aa7f172579e063d73999eaf47c13d73749796dd022cfcc9522738127a1c984d9d3755c29bfc6b52c08297662e24ab77790c056101bb2916385bf418222d752408ad1843cf6bd80353a2068ca714c082ef86503064274f94065926fc59c107ec5594b365606b20bc010946f60c7516c4e59c33a527ca3229b2cc35459bcdabb9dd8170b1b319571b535d514f37b3de62a906a05bb90320b88b989d3204511a2151bf39425a1572c192d8be2b695f18dff4a7ba7206d4409c9e51c54f5797ff9055837d2459dc85233d3c95a597f7596580a83ca3cd6ced5278c24142f90b653280b54fba3159147cb08095422d4765112030f5a696a628d8a67b90d27762665274c338540d7a32894523bc53dbfa760146b32edb938461c14792216a4b94615615afb151604f31b518c37ccd502709325a2013aaf22ac49a67350067f405809addb023e9a13d6734ce5e71f802a147c191536eccde7a67295bc86322a7fb83308f40a5517b61a790a8fccc469dfd752a45416f352b6eab11f0623551b49a5ec2754a674c1847bcfce66c9f80946eb65a419c06747c2a037a492d11947afac79db877af9750a85652f6b06447216bd69418a86169614e27b3579a8b3b669f8eb8b84c252574c856d91b081043710d0abca178b215854f867c5b0da0266977fa1e75d29d560015755f64b867f011369ab7189a916207c99deeab286e635b4aa6521da156c310cf4a592926b33f49062c94129a9547ae24a7e0bfb6d4f67bfefaa68cce739f46815afe593e8ab3a63a90797c01aab7a5f0e73a2d589000000000000000000000000000000000000000000000000000000b7fed2a7dc9aff1d845fd0f7f86e39a5d5e66f376a9d68ffeff6cb718eac8503a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 87147134ba6c085c2b878dd751b77273438b4e9efb50696b22e725bca466abff4ba40a150b68401f043b73127177e579be1d727ad37ebb79b2f5d3ba038d4a8a6b74633f31bffb103290c0694beb9c4cefcf47fb2f33ffb3d8b6126665cee64c6eaf385a816167d149a328df0efd29c4bf324e4f3769f8d7dc784da38bedcd8a653a42b0738661d3799db5c9a8c65b88849d07b27c5c88032a3b090026fa2d818a4e26672fc81a97769e432b217df4c551243354131100947f91df1cb442200a08eded975c39b74da9c22dca588f8fe63cbbb6470e3b029eebfb5ecef2825e834fdcfa2337f55571506498dbf2c97fc02baecd0d14ddbbbb4bf48eae0de95d42cc8b364d6703574a0faf12f72df2482b78b005d800e31bf1492f4250254a0a48990505300d90baf577191d8cb6161a4b39d18c84515f26216af074d110bed4b2af846ae9b13fc485e55f9a72f7347efb147045f27c914a415fffa32ab9f8251a03fc7efef160da5dc25e5b5ff12fd5e999fb7e55c9014a9866e2018d09a4e5b3a3c1c833985e3bfe3cf484a6910248794e636822c40f6a7ba6cc35baafd7557e1000da487574bc7f252c9b82b19febc1455de0b9b79ad1f69931180b47367c8f621b46fc09d8a6d43d91078121956eb44ee1f1548f8d3513a300c626aabe660ae38fc0625ad42afbb5786694b747c65fa38292cd5127f20d8ef0039daeb8963d8639a17a64012357d1612910591faf05e842e23f14faa4b01cb657bb4a4cec7a11d35cc2dacd5556ae116a1dc53a82d1f9ce151a41dd05c953407669f86730f9ffb68478179306d56009f2e937e77995937ff72df576c552672893f1f4021d1be8511ed04d02278c9628b0ecd3182a32ffcd9e37ab0795cb161b50ecd0f97aaa90a9b4af816dcc21ec5f1f54e7170a4167dd2017325888732138e854aaf7e2eeaa964d974cfd3fb810386937e92ad92cb4fd0b730004918aa6eba5b64d1df55f9c2d0d4c2db8188918b7812a71592d4a0924fa67b62e3feeb78106e491cbb7ac9d456c3bcd747db26ebd3b822944bbacb1e742578b35b4d6d9f49efca4c929276ca6015739a0b4a369a7961babe2ac95b3df89214630218182aaff57be9268367282e4a040accded4cb93170cfd765535e26d2ffcc4e6eb6832ebe880497dbe5edc3c724b659727d5aa9b067719b6a9f02616504cd3eddf0d56e33766856b4542132560619866958f8aa54d434d302f9280208fcd3ff42bccfeb450d6ad4f0dad91208d357b2174fa67df22ea7b4b3176843bdd5e581654fef45c16017fee95b92e5a1f33cc6e3eb1db250e7c6485d368f8fe9e53f5c863edb436d7ea007af06570d3725f07213f24989a637d9481ee38e26a4713450d122849990892bb2f95abb6c402053a9d41bc8b9cc9281bc6a45e295997a1523942f125c3f899f9722397dd1678d3d30e43c20fb0f57ba95e6d825adb66ad7cd23c7a921709b921bf1bdf0c22838ccadc9866c61880de260f32aae94d6fb6e5310e72ef8d881c3d5aa08 +expected_result = pass +expected_shared_secret = 05c30333e58ef628d111f6aea0cd8eaefb393f4e1b9ea8ce21c16decc506a407 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3964af3214683995edbbcb52acd7830454cf669b608c3cda86752d97e95c16c99b258ae01735c94a7bcfb585f451d58a0673103b203e32f64dc94b301363cf1542202074458b6d6e8cd0076327718531ba40f2543a1a91b0fbbc76a93ba4c6685bba5560a9d6c6c42897fff8594ec665e311ab39edbc99580c35b35796b0c3b0d89b8658a1b140979ecd28e87f135b5b781374a766cc18f1fc03a7a3ac7f5fc0c639a2ffb43bbfe74c709b303abb1432614bb3388baf38980f18a141d502797674d76bc8159a8062c79146f24973d090bd70390961ba5ef62a5575abad1219e5bd2c3a063acca14702ee58a32a593c5236bbd4ba938a339108c8cabf2a08516408444584ecc4124991cba6219c7f031ece14288097ae7ca9fd370a52ed7835388403816bb1bac26d56809e9ea77a788c8d6bb215b0caeda1717884913754c42190cbf10387e56f92bf46209fe448312d930cd735770b6ba940cacd71a04d1692044a1930b0c11b701c851a26c2462b0451930180415de6a1addc504724042bb832faae8576f2316fd718657d7ba8c975f6584cc91c9cef5609a433b6cb1f08476363687944bc58c888a00925cdb862df89cf96b5a9e7948c53a51d02001e0a97bcf4735d99554bc86106f0970869a4470794e20051723f40ec64625ade826bbb9bdf962a0190c708c0946d96263ae580e0968b01d03c31d494bc002737d990bd0252662bc34337b1093b97d084baa73eab8636615a832b7df2a9c6196495ca7422ebc208d6048e16c2390c1c91325a30f9ba64b06911fe41b5ce35f62c1567029018d34775b6a0c8f70081e5c12d0c73dd6693b34e29c6c669fc485c6b5004fa06a7fc2d2c995bc15b477a1f7463d12016613b24332e4729f8784f9024c2b4c2e91a9055cda9347f7cc02f532c3e80620fbb124f0b8da57abc6e421606b2422dc450c5b97ba040d781a0ab4ba5cb7998aa5ab8a0681339dd4b8c1eb77ff830a4e865f36897899d003bab7395f5b580b78b0046014181c640341aa0a5920b1609245f140bc7a31fa942157569096495affa32248c4a67ff5456fd8189b5593412539173c6fc898118b2b98535401ccccc1fa7945eac36bd248cd081925c941937213263c81274bec5773abb1c4607373029c6fa59723b893fde7b77124929361467aeaa1a86278e6b3c47a68cbc28781ad199c68bc09f3538f2933aa011b800f9609f6887ca4fb3857f869c1ac3147a842359065b6a59d999465ebd4228735a5c7f984cc93928d4c7c44ec4d90d55d66709ef68827df87abcdf433f79342ad4152e405ae69f56689747ecbbc0b23d55c5f86b5a699a06df3573d8715c6e667bab949da615dc1f9620dd28d2eb1ae6674506ddb212b315b7c89b050e48fb76a4946b7572e6a187dcb4130c80f38328037e2ae7477bcfaa71efc3531b2438800744116b96a0f48a1e549a33d19b0a05c206baa07345ac3427578650a97ea1150ab66cacbe848d39c0c744612b4d0738075251f7bb508113126a6b0e93b67bef50e07843c271614a4dc8799bcbd633a1879195f570907c05310fc91ae2e6a7ef474c6cc1112653589b32393d1bb6d741c19d616b6a93c2adcea5762d35aa285702882463b1d5cb9de000000000000000000000000000000000000000000000000000000f81db56542740a79d6677b9acfa5a3841151471bedddc4d62cea3558b2ef18fc53f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 738318f855b7a4cf13603f7cb528da3e04dbf38e61b3947e9c98d96d4733e6a2096a06afd90b4ce3eebdad11c4635d9e1ae8e058908df28e936cd049100ce5b69a29f80ab7e827c3be492bd854d20f9b0788fd3c933f3827add6ddfceb81a95f116d48adbdd6f543bc312fd5fea9f1fff44f97ac89b1695ca27f6afdd4a01eb80182830f4e1fe457f1dd7ea64c496f49b4904e47be3919a0d90da460ce60c8a6d66bc8d3ff55a8a580899eed0597981b9118c7deebbb746d015c8e117814f9abd649d6616bc075239cd7301413c4815eb880f7162666f296e06e4df2349272058d8f13e7255707830e98acc340195c0f0b61080fa8aeee33f1ef7a02e3faad19f1ced92c3941751980f5dd3c33b933423ec450f16543f480b6c3773764cd09a469db5d4fda16c64a0b80105f796adcefea0cf17fb41887e29d56b86d35574aa8a04992160408b6c30bb6370ad3b2eb0b8d772ef1680f1160e4fd3a6431ae5eef86ba8a4550b9344e2155e7606f211e85160642e83a923c76989d5f131986ba424c2d007b22d3efb868fcbdcf0b78a41b59d34c9fb24d3d65b9fa3bb87e36601ce99ecce01cc44bc120e983aa0142e6a56a3a6a19ca75c73185d48bb6179f8dece198e59ab821dbb83c429336e81f90b562f3da63c3fc910a13b8bb04a8e53ec067377fc1f1db752e9b2caf3827870e01f5f632734658a2c69da353959e5f00574d595bcddc551bb728bc13267acb7cade43b21b244a54716ba3b765ae331fca979948ded2c7fcb9a773d6bbd4509536d29b730712dec068353fdcb9d267b5ef0f905f34823a21a1be3df2657a078e678f6eeb6e0ab1c65c034b329421bcbc8f505a58a78d250e1a003d13d928cd6d305842dd127cfc805b02280d6f6146446b551ccbbbac16a4f1316359e5c2b801a31f674ec5a48287d7818f7e8e56f53c77a0004d8cabb530f95a54477fe5ed63dd47bdbc3d3d26194d9a488a909fbd4a3ec97163c7b8fd0467c6bc20d1cfd03046200baf232f6f5a6798300b70c197f1f616d12cdd17691406636fb1094a2e3e4343beb84f9a67146921397ae9be4160c1c81886db504591122ae7c90f1131572e54152ee1a203f521405bb928af9441a63fcb5445c5e9b2afce13800750babfeb6fa88994a8330d8d51061642698f02380d853bf2a57a8eace6b1d52361820342d00bfffc2dbfbbc3c0a8699c5f80fae249dc1bac232383b6eeb243d9e960809fafa5bea564fd610ca7c399c4dbf5000e4386f4700a561450d02d92d8b5ccf428306a9e57eaff931b31a4ca17e4d6a179db2abe53452560649f5b8f1858c0f66bf64fcd440b6384dff5e62f8983d46d924d85a4b449543ef8d5e0c023353aefc8f552e186b84378a1c34375cc28d83a62b04addcd057f4d83b42926f811b2f9e0bdf9d59cc1f65dbed5835b60404c048b386a3d09e0e7700735fdcb124c4238e1874f99703a685645cbd5cc3506799984d0ead93cfdcb6507d0cd757d2c0f1e350b17a1258e65965c2c6c092b6d4663aa3 +expected_result = pass +expected_shared_secret = 10198ed9166d13a1ca423fe3b36244be9b94fe16deb306ad742f505ace69e1d3 + +comment = Rho leads to frequent rejection on matrix expansion +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d7493cab527e162b7b5b390723c83ffc170e3e153b16285676101d66999fab321e9577d9f284fc3531e50715e790a2714e404232640de9bb0a4649e344ba2c33977f20c4488463a0dc58c1f71055b353a749a54db7b9dd1321d1f2812ce8a90a503a1e0e36ce0ab91309424b896bca7d39575bb6129e0460282c76b3937313839ad8672d4a13ef0f9c738c3c473f38be4a84de989c745576ad6f3bf7933879f69b8d72b93aff64c3d29292a794db4a140029519b99abd78017e5d84c578369a71089ac7b93c97a114e74a62c98b0b7ad707e60b0332b82af5d346f8373c11c83bfe543d8fb10cb9f128f1509ac3e02ceef44e52070305853fab0831bb05bc4ab8b311a2867a051b2e43a8254c787fd437838160ff13b752255e52a466b8543865dc61a40681b1e74eb7504442e943f99b7a4a695119628dd8603f9ce29bb9ab9202cbc52b78bea806d0d2305b442943c3d812e2d2cf07f2c2df778c6d6794114189162c537a9540a0bb75660548ffc56b1a5598aadc5055067f87d545f87b5bb232ad6497bf5f68110d16530bf80380410b67a47b081587fa78acc0621e70624605456aefd9ae2849c715a89a00332779216a6a8b3418196e23e76f919c6d4476b4ca606fa212258bd520e9d9162b066ac4e12568b532d584cd091606eb9a2f91882daaa2815230bc21ac33e8a8408be21b13c1cf90ab1e6f753843f6b5fd3446f93a2072cb3a94d5090e870ff2d788a94c912837899c2b04598c0085409acd1767214c822cf3579637c8beb94ff9b6327ff47ef5618e70a5bdcc76c287551ee2ac24229507b0d87b779cc59be8cc4d30ae0e161ab62a05c7eaa9a209152f37c798a2b1c76b2265dbcf930b131ad88c65224c4a5a2d1712c2a631c2982bca5afa6029e52824920c3c7b3093988d998001bfa23d9b01c91b111cc0fb7accb88d34f34bb7829192d21923d15faa81267e284b7aa18df181a02932a56dc4662f19148d055a91f8a3d97407ab9257108b7447e24a24c12a65fb1331dc2d06f60561d7bac9c993797255340c6770025f776270742c88ee4a899609304d75b55dd2c303b97cff2871cca3bb9cc8400b930087571dbb4c73ea1460bfd34595650098f38548906c2a8154b4017626a6b8a1db4b2a221c010937fcc8c06d6c7132688e1f2bccc869ca8f881303a52bc6313149b6450de00728808143f438be904c8de5923d8a02482a3a201b050d4b1735867eb8e7bf11d5023668c37c867d156ccadb2c383e113dace4a090aa9c1cc530cd17a94fba6c6ef062eb357e3293b343b169c6e169209b0faf0bbd5e42c3b6c077b1728ebb2a1e44d431f7c34835d9b0021871aac86d0782448d08236d94c0f69a46090b6c5916339baa15222a0496600dbf012c20faab5c7b7613c85a5c759d178c6a9b1596d291ce6b975363e47331b16735db2fee1027ffd018d8f338d712b2a79729fd20392c837fe40b3bb0ec9f11fa566e426637149d9041088419575db0734d854d0a0c769550a8dfb80da3cb9f4a7ba9b4c84e45b3457007ba2f380d19098d4f915023ab00e0872dd6485e1b365802d0326bda7c75e7346b001cfdb5710d1746bfccb0946151abeb7122baa4b79c4f6cc10828771cc9160000000000000000000000000000000000000000000000000000000982bf7a037500daa285465a7b1fc2d22ac15a00c1fbbb2c84d7da1bcb2b7bc9e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = 37abc2d961d3bba2efa196b62a4f9acbcd14137a7253a9b30fadd1455c22014f3542558291c55a8a00cb44aabb2d0726210b887933dd24955282fb51d17d1838b6804186de8130529c251621677d8464131c99dc5de3879df80b5130df5409f0d75526357ceecb0be3bc1709ffd3df917e38680bc53017f934179ba3467674d8231f6513c64f4f06507a2e3d10a4f2e145d759a23897dcede141e5b13b235b274074eb976f84edda05d507b23f248dfc3ee139f4309ba099fcb250d7c4d0eb61ba359fec9ba74186c5956f118c90417931aefd5adbc179f58282a1885679f21d2ca69a30dadccd896b2e84b4497c347a17a9e3bfb9bd8804c3b3c7b689e1ca00d3d32e1efa17edd4c9c8a9c8f1ff06d991142c193489e1de0e4bce1e989491a0e1eb2447fdf301b5f72a31601a119315af7bb534a088707920f8ec8a951f22929f90e601e231b7e5b46e930d19298afc429fbc0a68a6227757b14fe547caeb56826e008786e5cb4d01feb8ffa890612127c17474a50671890c5ea51460973b3944b66295b917f0bbd0c188e37e6d85d3a2aaa1f8e0045a2d954fd6d22a36ea5f6283652feb40a694e5e46d1953de2e17a090d60fc16dfae7b0d0ab5bccb33ff90d13860be15cd4f1e4c12233a009537920f4b4738ef1e5d40c67e9aa6b07f921ed1100a1e6138c779062ffce429167c4f204fef3b6912f3b35eb44c9efbe164ce5c939027d8e9bf77ae311a6df1fdedb4b5fde5aff35dc94bf023048507371ecc567a1a7ffd9aec53e2301e2c8f9660890c61693fa638cb62d94fb436709c7e619248a8ddd71104d4b45f15c1878a847aeca848f7826e319856c09c4418b9ca0893b983734daac815a97985e4529cbc455855122f8754ced61b89d43df961bd6ffb1c6a7a74ca4a88bf7c2bbe9ff412b8f2a41294503425a3c39a64627a41d70499ae7cdee4fbc33f042e7cf4fa04d7f60452d6ed80076dac04c7fc2c8c9d79d7f7ac8f125b3b7b12dc36b6a50f9316ef24843594ff5d0f42e6bea4fd893d7f59d5d219f119cd682438a917c28166ceb2e96cb5d7e096889543fa145ca760827f9734171ca2c46f49f195e38784bdc6890d953b6edc4d04c4cc635b34847563edb6371e1cf168b47a506b324e66783890f5e21780a94f3d0a9d3021bd426a6e8c5c748661cb11ab4e4101db18f077bb973207634a674c7940863cb87481884a173aab7d5929b5a77127299868c4dc275669a1827a16788a0adaa52e85f52a349ebf4bd8f864d052e1b6978605a6d368dac7cdbdfb13f90ea6d2039e375928d8b9fdda278d896d847faa28a9a1723b16af26110922c76bad4154ce7807e5a8f7720b7b28ff4e097bcbc70bb8f7bf25a565d8a81b81f7569ab3e3d868abb474845bc2e6850ae4c3caa887524cb34950f8434baad75e7ce00808f1381d93d6f6f6d8d85c86b55678e5bb819dd1283485f4e1dab73819d8882e5149fec4e34357f881bdbd0345a6868e520c6c51bd9b355765cb129248cec784e7658e33f8929e0d4 +expected_result = pass +expected_shared_secret = 2bb1532ce907d285b2d2860eb9bb5070a41ae73585743b26b948cccd1731ce66 + +comment = Rho leads to matrix containing zeroes +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca0d849d09133648875d99c8a2d199343e2069be06914b183e36f76206920fbb9294e3f17787c4595ab553ffe18287896cf6452e149cad67b901767a6e37740624d12b4657072571b9ce524780e2374d1b381e211159eaa9e8f5ab21315e3ae48041f50eb75430018199290325406bb65eca0088fc5e0b72ae2522a1e65962afea8cdc2c1ecd1a8efdf38d12ca5d4bdb8ba4d50d5de96f25034707aca01a296e63033a58200f32079cb8cab973026934180857d054dd75371700ad89102434f2438a823048900ff4fbaca832065ad99fecd12a742c286c067a93ca6de6e85304572a4bc2729ee2b421a41316c0bd766087eb2a88d50cb182559da4492a0324afcfc519e0c1c83336913881cdc9504ead243878caa6783557eb26599fc56fa26c6209f31222b7bda6db9b50341f5741b6f029a00440bb1af6b4e07a46ba9626d2a3475fac7bfb2047a9b3139c225c36bccb085a3b60c51a6227230df260d8f47ae6598ae065395e5abb6d5478ee97a9eb1a369ad367b075642997513159a1bd426c19542c86da7de7d626c7828dff7c9a6b53006ce03cd54c4f709c231f70829593358ab2515bba53da61c71c9b5b1df2029fe3404a6a1b7bab3be1299577c86997e48d38a17242e75847a23a8ad5a7511bc87a0261a8ab0e07889a53323ccec92e497c930dd57e43f39fd495b5cc2268cadc2918cb8ca24aa28c110b84c5b2b075c2effb3d44b6351cec34503c94e8aa016ac837f504aff5f68def8c8e0324754736950f28bc4d38bb6115584fb681b1b05f8f8ca69f924d25ca3f7715c72fcc1706f83f8538ac14b79581e103cf385dd8962d012309ce7774c687ace4d8372d1ca7acb1cf8f27545c07b6204140737316cf8971b3448127434156c9a4d35352dec27dfa82bd5e72522517bed633a3686ccb64759396db9ba279a5e967c5284814058a2ad44b8b1e9a7786ec1cd7f63a7ef72bc1f5c35ceba1a0fb934a2a547c86a6e00a51e9f89ff8eb68e3a48e7ba03418072cf0fbcde0bb15a6ec0ae648c012203bd6d83e3dc917b7914ca31505e5aa62875aa96c4b4c5cbc5b368b18f68264cab71332a38680826895d339ca656d358a0d40db12ec43733e60a287ba3998e7aab76972ffdb3139b30abc0ab3a089a6223a04c92a9880b89daa915130fb21ef6127fbe74721677d129793fd035d6fa2a1f1719a710a5030abbb917bc659b57f166304a0474daed828e8145423a87abfb36822d8211d9508a6d53994eaa9053c1a69d03dfda68593b1b9ad2b3cc4591067658f8d62347e022205823942c0981ce6846bf02fa16a8b20f39e1a53caa21a8f8ab4667b00c040228b262724d7a95e1718af48ab870675a4ae537d364378560b4dfba04146381f4977647a333df3e718ced96d66051c3f5c2fadc67f29596c3687948f455c3b7b13e2789b518866968788758c2a172b0de0fb370722571be5259c76b06c101250a49b542375a97907d393328afba0dc21948d96861b5cc8059b5feaab36aed39a1180a2bb11ad797752edb36a5cc98ca13c4e90e48f91404212e9ccd4a76569d661735bc9709b0aaf7b068a09b598c96557ec2695755c53a7a70509d0294a55a1707e040b2a8564a623c5ab9094000000000000000000000000000000000000000000000000000000d4a83033492ea7388d0d03b115ff3bad6b0a7c4970d30342a3e5c3bf11253ab611536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 37fa90752936a8099c78fb7599926bdca1d3ee985af00c51add7e3ff7b282d26b1690f34cd3a8997ead23c2ccdceb07ec9df81ed6a8967b848c406340dfbfb9bfb223b6dc849ca5b1969f7aa519a011e33cf10e641fec3c0411d22508a18bfb316946ff41be61a16a75bff04d87c44f33bb3ff9faba915ef3e94ea4bdf1a6a296bfdaeb3dc50aea22c4ddf77b1b53b753f3c228876c6aaeeafbd5c59d748b5e596535995e075d5e47370e5b0b570408b1f8ca0bc0c6d60099c6a465c5e6600deeca2dffe0eec616d97d9eb534671251956505e1c546975c8f125ef2a50192d5106be103fa8b475a407a1a0452310e8b1d78c1147640e3873ecc21811678c276185f24e5c6742423a8778f5a2d74a3fb7ce6862c5481a079f7574864e23886658b2108891480a481b64fa372d5d628948c202a4232bc0f8bf80ce2eb4f90fa47b6ff1dd55a6c02a41f6a7c68ee7f83a2fa094789ea8bdfc70126de68a61b5f8ff5b92601f97ebf53b3e196fbd595dad44490722147737f54d9e69835a98d42ec10cf1524dff2a267156028a60bef51cda83abb1f5df8a5672aa336c02d6591aeee7a4313b4e6dc2e06404158a0714bef56df074cd290fa8a16daa8a1fc8f49ec7067be5bb5856f23afc6b2ff72a2a64c967c374a7917c3552ad54124633285b5f0cedb49795a20116b692b8ed2b49b0d421eef3c51cb99f7aba701b0387059f34f71b12d8517e7495eb0433b69340bce1c755449f1d08789ef7cf9d0bd528c262178af413d4f40cef52392b87d805a4d88677b1b8275640b066e46fdf1ff25264fb5f4eba7e9e1fc2965a27108bc32dfc4ce565b98577f0d1bfe37471d11c3afeece6a411b33ccee3692f32c22f077401135713e33f5f868ac1852120c170336581521834e762070b403f49e08e52ed0458866fa7df50d8d3b5fa8e33e931313aaeca6bafee1cbfb2743762314ce70fd9fca8fc34b402ee5a2ca330f60725d5b81a6d35e1c41f6d8c88939859e3f48c654dd8b9cbb4e9e0afb8aa3344f6abf18b6f5d011d8905e12f4be7e7d4081573649d157d4cce8b7b2c5e13875e0d2c7dc4bff5e9d436ae112338390acd59c7b7e5a086cd3b00817a1a377681a73531d4f1efc7ebaaf6d528e984d9609c81714efb89b3f0bab8505bcbcdc5535dcea227d3507d38cf72133c252f5b425cb800ab6198ef3b33391bd5043ec17293fa73eb8f3f972e64c5dddc851f50f5c48175117e533c87903f2d215a27c01f6050795109d200f5e39793554b35b2a339695bfc55d1d32a06336749c09f0ece1e197dadb485e2d544823e013cb84a11cf44ac7fb4f74dee147e4fb805059fe67fb1eb7daea7be1c5e7a050236ea8079a6cd1578715d8510a53c03a94ffde8a21507086d007145080e07aad2e7398cd98305536e6f3a0a67f83b16698232591337d0cb465bb13c3570df161e97f6e1deb3b6548aa7ff4a30d145f64f2571bd7f748f3044afc5a8d3e2f01113430ce83dd59b0a627ca759551a635a68838246af6c304ba843 +expected_result = pass +expected_shared_secret = 359de9eb5f1a17bf7215b7c1ab7cc320d7801f826f917755a79f413876973ef6 + +comment = Rho leads to matrix containing zeroes +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc40da241478b798a39e11830b402803ee9c4decdca918a7276f2168cce60092c29bba4cb8f532bb209367748599501572dceb9560ca00bc841e442a41e15b590cd63fa7921b344018f1a223e9e44ec933877c330d2b72531729ac91746e26c61381c80d98003265c306040c85fb95be547a46e3c01671401a42237da688795dc8c9acc86208c36911295ad22b05a2717d810076b63b632eb254491a414128377de53f941cc7ea1018bd83cf7e6a76d85211af63cf2ec856e636a9210b04a24abab1355478d132805802725345c43a981c2cc3fb0318db62531a045d2ef57680b547bfdb9d5d356464592f47c2360cd249e73a0f59fb470f4491a9e55d6fa9a982b97ee235adbbd8039beb9f07ac35ee5cc6243897f5c81bd9db5591c7225e90587279b35c5a1c075ca5b7106510559eec9ba2d2e7143c01afee598283403a6d7597a38b01bf1c02582035ba743e1aa20c49983779ca8279bbb53d5115534916184c5edc70ce4372bb25c48a2355c22a5b15e7563554e9a0e6f5afdb3aa3a1cc5b32b67ffc13756d65309dc95d561c91d45a1fe57a83f9c4ae8716bcd8708efceb851e4c3cb3acb4ebc7993d1056a485bacdb50694a81d12dc098d39a1f407468e215f6e055498d215f6f4bb8471121eacb2a324635a07864199a0199b0b6276a8a4e5b9ff0ab9ad13474ea6b2ca46b2c41027644a416771cafa07a1ac28519bbc0888f3878262c871b138aa109966040447484b3a999b7b4a75ad185475ac46ed92a373070e03a90f8e1ba97a91b5ace881377a51c24bb1fa85451cc94c72517f3d72024e7b421666cd3814066ccc5d70595efa756bc3760688123e9c3aceeb270a30a23261ab23e30c7f0785a360e8a0bbf5401450114f80580b03ae0b503419a25861331d58c11ec1c21d47ca9dcab60a56a5baee20417172a4535bb6de18b151bcb4159aab3fe69a31d5adf64c530726677db07dceda5d94a7427c189344027fe819c50f10ae70e550e154bc7e5a698c324096e9cd1e78053c6a05c7c11e9b2b532d19a87dc08dde0c73f0d3357f732c441462c8476e5dc5881d55465893438e60350175178213c0b1d8b503782d786b63c1e66cd3837bbc4c891a364b42130c1864c675097f65b6acab701de01124ded8aef4f70479eb996c5558cff287ce1826ec962bbf554abb282442a1bbcdc210ca389c50105eb253ae05c1477ff0523c85a294e084504616d7f75ce624925dc0c00b9c3f2f1363d2b05cbcf165f365390376b9d1817cd24560604c1512720b09d25a82f7179b74399fe46db356253a8320b393b068f064db6a353ada951411390171b47dc29bc4f05a2bf99aad4087ad54be6602bc7db23ae34b27d594b83e798f22fca1fdb56333374f892487e7289cfb01be4b8b03f0d9c2a589ab101494517264b6ba494cb0490a1871d301483a4c647e5c88be907c7c92abd813865606728bb95aa9058bba6cb3953b012cbc2af7a4770eacb6f2a7b9e8e94833e0592717be06517e9d33389b993a53833f9ca20699cc3dff64995ef914c05bbfe154951b7221fbc779740b86cf59ceb353233288911b1242c579c508149ed71052aba9bb79903e23c75258a445611c9deb185efb25524bd60000000000000000000000000000000000000000000000000000009c1b1fb64c47e73550adb98b72060f295b67b70d01eb99fe6c7c4922ee2362412e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = 06f9463d5e9d8718bd3f56e92a41b4147298b758e670e938ccf1b048a6facc0709e58ded8fe9a88a11ff81007e066c6038388b7fe0e5496c02edd8c28509f584b9d58604c7a01f3196f99d3bb5fe1e9a6d2ebb47b2d2e0da69071b0f4af22dcc830745229081c266780c1c5dec5af5b74b9a2355274ee0d0b0243ab75a5f59f09dfcc2bf305f5df0ba6fb24c01c9bfbc38749681dcd401ef1f38d2bfc29ae990835c48a80f56b0869e84f7524f7d469ad2c63aee4137130575cacc87dc8fada26c4b2195644b54db3ebfee1e4fc3f13ab744dabfa044ed7cd099ac836b8faa41e510d3995c129429e2f4c8b188b612ef32eed540915294be069d64c662bd301381a430123a6ac2dfcf2c6ea4eac8dc5b066d7cca6af8f399add96abb2154b9167f57fba21a145288ee90a4e47595738d7c32be27cb1b0e5e16cebbfcf5323bd0b719a641ca98bec4b148128e3fa11963070eecc2329efbe9bdfed16df4fed34cfd03e65a59e20bd3c7b8f012e88b8262473c7a36d00a381bf37c15ee6d709f9f4f0042080d4f67cb6f4777f92a2f0a4b07bff9e925a7d7ab581ce46f055f35c1963d283e4a210a59dad5dfc7a679cd828ad96382046816848b1789ffc84babaa60991082418286bd281947c7b664543af16b8ade454d3d8ae5b416f82cadcd7eefc5b135bd6ed577e8d85848419ea73c3e0ad7276b3ce8773e9881384b9d48ddb6eee9d9aba7dd2a3e0ac8972e301d9cdb0f25893c90e68f2d1ff8ff892c6b59bae088dfbdea3135e74501236e416a01c770bb3c77c3a634a29ee6d99a0f954171078c1eb44d76612d25d7e51fe3756df2c87482a709384825f52dce92884f8a3ea3ebbe219e0bb36327660b1b7c44583bdd924bb4ffd6baa933034e92a5feaa13b3bb8e8e4c0a54ce58f4a48ce0c8baa273e963d74538c55d2414891bcea9789764247e64897c25a8b154d2ef8d1356a77b8a5909c9a53d45d2e4d7362e96edbddf27bda011a439bfefcb09bd46bde933b5375bdcbabda95933f859c0c43cd60f21186439701b7ab4f19c8bcd63ab3adee01ff5c2c47867297297ff823c814bbba614e87898bd0bad020c6f51440037a687bbb96c558ddc0f2a250b836bbb36d88009a2575728eabbd15e3dd14b47c00586f371e8e7d964d2cb7c7acf1bdb0077ef2f79ad0c20e6134b54a8add35540cecb4a1db7bd8bec65467745c2dd4763d7c67d9a53826c42f67176354d472bca647540b404c0e84ab05e4d474dac551f0624ab099d24fefa1066f495e0bda8439291e4c18718ba9ee97c16c385309c0d9505e51ab5651470148223603cba76d767ac5131a13f097a537eeba099a18144692b718cfba31b748a72b69f03d8226bf5f8ed7b5ca93b40f7e64e5a56e6edf2829b61e96283518594414603e7acb8e5cbeee0a8e9026196afd72dd3448ede9819a89a580992060b1852af4e2d3451ff7518f18c75c4e4c453f2d7dba5cdd60f5f4686b5e2ef272ea958867501a3e29a9746bfb41f42d08ab860d862b6c0f4c0 +expected_result = pass +expected_shared_secret = 9cf796413560833a3c2e39edb3f4f4bbe551109a4c0b9a25c42777d7d89361c7 + +comment = Rho leads to matrix containing zeroes +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca513c4781290679e16c822f2246004c38ee6ab27fcc694e665ec690515542eee6350d4a13740b417d1b91883537b2bba248a61108a818d80c5c67b1c3265c124f9e56be2a13129121e030aced4585189d58978cc3750815688763bdb44a0ee46c678999081d42ca342b414cc00539b6d19645ed18ace96a46c2453af3af9b73ad649febba71e40802e3871cb3661c2c7c1480b9e15625fb61c322f0141268583f4c9b19950018c70a55ed500625cb207e9219d2c9cea134c6f32a606393e94923e3fa5729ad2264fc8667d140d232a3b68a93caa9098fe242f99305a0fcb3413ec8b22472e66754edbec064e89245301bbf48a8994d36b4093401943a427cb5388132d3543944e656ae51c72118821102322a8f7246368b5d9e4756fd45d5886477e476e641b10d0f196cb6638f6c30ac2e6ce57230d4036cb23d14e8ba30d66e92656090199f1652003af17393b1fa912df25b6fba7bb3fbb5037915e46c8217cc88142e14622f028fadba21455b00ca96b2d039663f0aa6d48b0b5b3672203b76330ca4a14434b877cf83a818e71b97b77a4eb99858542b316c809f1630f9bba7e00a265ef2b6b2aaa45611726e1ea7d96a50f5cab524b138288f74b8575256fd7504740a256e1bf34318733f6b7a53aa30536bf0e5079e5b0395189262027cbd497c350b1ad89f4aaf88b219de48801c7bf97486824a7b7bf723f516293f2f786a6989a35c192eb8b009fd37f950cc6e08592a1350c680952e92887b5759249cc70bf477277cc18a9e95da3579bc4bc42761c505504372eac4cee71b4d82c787356983380666b3718b288948372c11fc855b3950e633a70762490ca13c11c6b824478a293f5161c782c4ffa5fd0a64b5522c23979b2434ab52b783a37098ba2da100da063dd3191c29c12bab3927ca721263cb518924483091070981a902518df41ac1280bfc7ba2f2703cfe2f8cde65427818215fe57b68669ca97c977af38845433295e770c4bd4cc308cb203d823c84639cc9496d31424ea778b0f215430437deae7b8c6906bd4fcb589d251b637030f9607e9bba487fa0fbeb9545eaa8353c738a9f02b78e19774b84ab8144f20e39c62a16032d924658262c75b91e5a471ffb95ca40b5c1d388be8b55e09f4980a274ef5a5cdf5137c1afc0325913bb1ac608a210ae92220f4a47d8ec6806dc6b5efc67ccd677d5be615bed15cd76625ee4300f1e8aa9330952d49aed6b14c8550204d2c3c61828cbf36322fca4faa3190a6635e2f0809f45b5064929c14e0762d62a3c8839663fb8b9a135b715440d81836bf40a6cae8333d4496e4703b4ad50482e8ba9f5163838271bfb66d1fb462d51418e2792cc7370f7806d0ce7b7b4a66af2af770f5a253c46001bf82988a4c0c008b8bebe64bcbca680d3136e48bac4f030cb495095af7cc418b3acaf95bd6b636a4f92dec211c4b2b4e8bb90969681c61ac380c16ce7dd0aa3236957415b29144737c5b9124575872950a23c5315bd3b0ccf2a608e6a0d3659cd1053938cc1e68c131095cca20c4b2b358c65192b3d812cf73e820f89ab1c5b4c4c2270e7b465e2253c179d312bdf77f22252d3332cf685abeac1c4026f95e9b9b79c5a3842a49b4ac59000000000000000000000000000000000000000000000000000000fc068f82a15745766e3ec7df374ddf20df18b64e7ff18bd526fe226dfdb92d545ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = b812896d14f191fba331fe20ae245f968a421c46ae8e3360f380a9f0a00d50da4247b232f5181ea946b494e9d99f82e7fff27d8ccbeb6fa8dd5e12f12d2afb02004f2bf046f23115aa3f7e9e5bab06803c4df1d6a0bd935c882721d09a3b5c41050afe0ae3706fc83f87c49fcc22ca331fedf7787ab7ab0ac9f04fe405f21d3384b1f377332feebd65e11d7989f56cf7430ae8441072a4a8e9c8be24a4a1fcf380dbc0a8543d2159de861281493516d3fe7f0819da15d259aa2159c37d325c884217a03c83d8f4d5c1b9f2af4e734aca05ed1d3951d3bd5c021a4e81069678a210ee5f5c9404b52ffa495ebe6b05cd02cd84ab3f3795793e03d26e83a647921c2c970170c0ecdaca8d2e5c469b1a3309e46dcc9122623b6f41771131db303eadbd7b7df5c86bbd6ab0060df29c95a0c014da4939271a98c12ed92a91d8b3a37e2236ba269e7df73f7df2fe447a20bfc56e6b9249485cd71a9fc83af54946537872649949b49f3d98425453fce02defb6d09790322afe334c53ca802510a87f543264e5bbce4665564d23695a08161e28db4c90bb6bee38c00c5d3cc2e403e225afe39ed45ca3c23a35e64769486e4e38b122e3d1bd2bc8d1a38f689e5ccf26db07c8b7c14b19431686ef783382d02080b9221d2a15b41db02a63db7b5396e4b516d241ea0ba533c6f1c90b67d0e6bb2bee066015dd7c42f0226809fbd81a8a56630b93aecd63bec94c168142bc64f0086e02ddeafe7615192575e74e174cf7e2c4df95b55ae810d5cd5cc706605800a0417bbfbe3097890621721939e01e51f46dff10e0777bb93e0b87e8fb88c5100b47ea0c1f356fe669ab2ede1f6eab8a52b45815f9698e86baf38c35ee99f5d3613be4fde9febaa6c33f3a493a37eae52530b8ff0282671a01a13ab74b547c4bd7ae87666c20f857bc4fdd2eeb15a09722cf158083d7a31cc13dbc53e0fd2b2957f5032761e777474f17188835bd79090087ffc0ebc01af02e4d0e0be1d532eefee9ff92afff8cca34286cd6e9c03b2c41b2080484c725afc5aa3c76d4c807e8c5beadf261061c4df268b4d4e6e24ea68f2fa085153d37be084e9d69d2bc48c819f898ab482c0b80659ff473e8b186cd5304c62b4b3f3b714c628478b8a29cfc5be37773cdcc4558986d29578b5dd087ce0d989a70616d380c3c5f68410b3a7a0fd247b7a3d9c9dec0e8f13fb1fa1e6cc579e31a202afb994d6fb4e40e6377dd2ba3247e5150db44d4515d31296f00bd2ff2838d5070821396ffcfb424bdba4ba3e9bcd2e02fe85f5feaeb0106fd8270a47aca634101102c08dae778d40d070d1ff0542414d71a7dcacb25536b4462014e5093710ead409aa1ba2c21c1716cfc4f1091aa39b41c28ac9cd3293c00c853a267cab452473fac0c84bbfafb4e2754a1c1ba244fe1ba8fa356e78f89a94501e068126acf20ba176586adfc0c03535eb6fdb1ddd41c6272d0e8c49f039dfccd737c284351ce14b2f7e0d01639d502d519fa9cfab9e41632b79353ff861303508f +expected_result = pass +expected_shared_secret = ce303d3ea30cdad19af0a9f428943317278b22f4c7c229aaca25d0709b23e6e5 + +comment = Rho leads to matrix containing zeroes +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5b08c45bbdb5d4053b675fc7ffba8cab1f105c8095a0a209c4f16447198cda9d73c62bb98dbb3c86e8761978bb77a5c7a28f03f10d8558cab3c71d498429786280383f944b75c7139e533bcf7019fbf953dcc00c884446e8bc3ccf75b3dee9190526662b33527600296aab664ef58c5890111c4d1c04262ac22985181c80f3906cf11f38af489a75cf5596757a8ec56cb3d3a7c2594441113c427f7b43a019ce1bb1756a9223b8b15c3cb649e93497fb34ed17b7c4d185ea1e9a5a6dba569f1414aec8bacd1adb784c714a7b2b89989bab281eff81ed093373d5c6d3f36ac3952aec99ccacdb0634928668264bc70303fad4a746592778568570ff75585422bf3cb6a6960946432928a0b39e5bb017840c7c4d99b8b25a0c76349766b0d39f7076a839abf883252743731b53c3f650a32b0297e806addd02999d61086362322c840d8dbcd820ca008e5ac150b7932f081491415c1c3300e0976e7f9c14fc045be34983ca26b71690d216989a01b03b6930fff0964fdd98b2ac6bbc408d0731a501ec87a93e19096fa3161870bf7964ab5d6a5ba764ed8206815d83045b24db9a9483bb776dbc3ad85435d7cd449248c4058e3568bda4e41061ee5f0bfb0e29867491bf796140e8a2194572c23f75922c4ab0014c9ee5a98663ca78741a4b15335d14a3fc92a24b05b5233a43914b274ad531e94656309249f79fc93c13652933529e72690e1b8b7c6a21c756614307229135977fab1727a497617c695b9299d81358354c9962d231183d8512adc5f10e56a053610cb042cc4fc2e485099b973b320c090a4459f8dc279beb9568f840932c77d28ebafa40ca22bc60adc785449800c8fb71e80ba9a67c4383049b36fc89f0248a688298453e480ec525dd45803dac94ac380c468ac2c85015560965b7c7838e59a8f90cab718246dd4a0578fd41438e09716d3530a3272618b191c521887ca38aa8c994c93820f78673f5cc95ca93e3eb976946b8785ec3f12641d41f60db3085931aa365970190b93c37625332fe92e4532519d8825c46200e8b576592ca557794e370144d378a62e5c54cf6820f1671934db0b6c47ca8d302bf18a8b82152926853df7d255da51cc7a19657ed77377fa4eb8b2a929b46ff18910d1832b71842cffc3849a66107702ac7a86630769889fd90d8ea22788805876321ca2158ec7bc878c568822c0bfa03c10c9f5b5a8076357c6b934b75617a20606712b0e8cce40f4ced0d17defa628bab4751e56b3ad040be6e3264e6011fde7c4cebabee0701c6023c218d07b47ba4ec811b286ec3031f5254302be6b776666897b3062649252c5f7c1bb0dfab6b4f13155c91f318963109421a4a33306eb0b66da38fdbb541bbb3e2037c1a0d4493e0878aba23e7138bee255b3423009ecc8920a3a4b86932167b1affab27a8821598851bee698665a2130816b66b7e81842819ea1560a0c5292be2cc7d5428aaf3b7ef5002d5145aee9a82c9d44bdd0842adf54b38d9213e904052905adf3255828147fb64960c9167b17126d61b05007c759c938cd2086695e0636b25b69312a70235b6e201c23e2f9a9ad696716f53333d004fc663d5c0b0776f875ad988aa6c6230218cf6806353409000000000000000000000000000000000000000000000000000000c624c0376c3309778d9aafbd0bb50366caebf7b7b46b4e9aed69b929a277342e8bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 87099f26e8493f157e405f8cbaf679f5fb0aff16ff9e2c2fa8c263c6819287da7484cf93e0a6cca4d0a94d0f710081c0bfab292981dec83558b651abca873980d077e9febdfa82398896e88560e805948d84ea38cc77554e9421dba3a85ba24f3328ffeb4de0bfd1da900412a71903908e3b8cacf00ea86f21e4eb124167b3ec769a8a22498ec6cf26cd4b1470e95c37b3716462929ddd9e247d3f23b98b3efed529066532b8f6042ee8eb6ad00233329e0b634e300ec2932fd6631b1bf14d7e992f54b985b51cf1b05f5ce7d9f7458bb3b530fa3feb7ca1a72dbb8c4b01c0f03d8b45e550514fa4fba32705c95316960bf50d64e3f07c48bcdc31265f0fadb5f348799fe0364c93765e2bb4688704f3027e69689861dbbd65bba05f158fd329c5474386f9ad7afb65b297004664ebf3cb7ac1e8a34e33ba15ac0c92e7abedbfa96fe4c68ff6d7a4d1dadcf56824285883d74370e2840cefb887b7b934fec461c50781dfcae2bdcc9983e0b34c3be81a0dca5ff0ac834f5bf71b4e6135c79c27a525bda87c2c1c05e5e2addbca7c43e49ad11ea240cb09bd77d22e7e9d0ccc4d638feff6fe9bc04300202313197a9a53b99e67e96aa72ebe3200758c1f17b05c0b793dba17278f3e79563a532161190eb3a0724524b210f26038ccf08d55c0bf29b95917c0bf97df6872438b25d6d90091ada34b46ff2df784370c8bd3a523687902dd9a1d70f9aa9b1a06dcf4a1fdb740ac3a0c25c3840bba2e5c6cd1dbef9aca23d5f29ffc00cec2fd9dbcc187cd2d3c690f436e6265f8cc6857b3ddc1cc1415877d83d80337fc4c4e38808b9e05b14173497330077fe4c38699523491d4a3248e5dc4c401a3a29054c924c744f7514b7a84e91ca6cd2cdd5cb51c4ab4f2dd4aa0027b294b299896b558754264ab10b0c0306465ddd4e88f2e42b580801746452467558d3238d21a74ddefcbdcff5d79886b101c57c0d4d1bd4af284aef20f558928ae0768a07f397c5f9f7f334a446755a22549cd7fb1efb14bab48513e52c454e57c381518ff6d3d02278abc01bd0d54d53e77d361bef85c33efbbfb295bbe3aad332d5131e8cb5cd90a960bf2d429524b45abd686ef95882ffe6751da4f750a367fcdf0e807fc204834d6957ba8fbcc0e9e3d4922c45085aad54b08934e0d909b334d3952cd479931c75c5f4aa1ec286099bedbe5ec17123384e83dab7230ccf5fca4f085ff348197d837b752c2bab7f0fed29e6347624c51059a48dce7f4eebe03b5bf9b15b13ec85e8acdef861fbf93f17e377e950dbe9d6cc96ae83e94a3c5848dbc2ccf6090882f048a174bc42107cf9bb0df711551e2d550e74d2d416453be7fbdae5a24ceddc7dbec4329b4a67d187461ebcbd9845c5ba04967ee59da4bf822460053383935cf1bb1766a7ea5568f16ccf8400d9a73fc86a7570742d76d4f52d20ec80b8ce2a937d53fe88f60bd3deefe27642fc7cd7d79cbc59fbadef2ed189edb3239a948aae68bb2bccbd42c872dabd7a261625af4fd0b92c1 +expected_result = pass +expected_shared_secret = 53865f61850687872fbe708ccf896f7f24ea01283510faf76481abdb0cc17e89 + +comment = Rho leads to matrix containing zeroes +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba000674c3adf498654b7d8078c405881705953d58fb08954a73cbeb43d564894eb48e104763d35563358693f2f2442ba8a01c38af0d94be822a1bfb7560e75abff623401fa043d4f10f8cf688b20c56cd18867712688c992f18617331631527cb4c7b0a526aa488b5122553e332280ca64deb0c0ad36db2267b633b3f8bb8a83551000e1ac17f7b426813caed005892a7077c4bc02f703befabc0f6b324b1422ec290ca42f630bd441d1f119f1c633b2031cc759322a4d762265c5e642462c0b38ae5339747a62062e07aacf8aaae3725424c4f30f38e1c727f40e53788c68bbfbcccd8db7364388a46a366b53bae89f09d64c7c1955357e256586dd5cf508967cfc97b0b481267566b7eaa00dff67158f81cfd8a406dd8c0095c2c6e4c9e03a466ec79232885145ab0a321149879a25c77378dd1e231be71519122b4f1394e1998081f271840a245e1774012d508bcc0830c5901cfb7cbc178875fab73b4aca397d13da45b9e93342d4f5aa813048d46e0b56c8a9ad7194fcb6046da9b9d16d56da6399315c924f18c527437c9fb03ac3774ccb272614b0cc55968ad346187a5f1716a944fb3946783a6511a6997cd482ead064356f843bd6b6379f6c662c9c655705c6265c8702729c3bbc022a8828312bbc7c7b90c373448a59cb67ca2da3771882130043488eedb9c91b39917a1629918580381972c34a0e7abaf372527e1902088e1354c5353c900a0a16536435124a9e51369bb46d226170a064e91e85dd6d987956820b1446a6181535d3ac8a994341ca43b0cf06a83825a85a5ad192582554864561c5bb2915287a502c39b8b54abafce465abbe7092a83384fd35d91d5604c7a4c14395cd57713baac0d7f906ac9274a8bbb34074b3f96fa8fa23831ece3975f3011a815bc7a4c1a96849d386511e61a9ac187024eb50135aaaa0ae2347a804e55e4b3d3e3c678da9e5997419c836948370d1af0a1c1c15d70f4711e825244b1521345304af589877b64afc28ac625a237a3226e1873101345e9ebc060a255fe0862de4800097a89fbe07aac5c1cb983049c369c8f0924c8320df70ac9da023cba2b1e40757a3323833d12229ce607a63275f305c3b8bb830dcc9f63bb479969cc0cdc30afc75a8308cff8e59d5b2a20d46b200dbb7d80e011bb726e33c968e3ba8809771269a096e85260828c1fb0a719fc638442b2935ae4cf82a2c27bf471e48264ccf912d4f09910ac12c19077a8f52bf3b2c8fb4ac7ace2ace1250347c3beb2d89299673a6328c8483805be327079f8552af16117d12550042b7eb635cb0a8c0d370ab508a7789235fb81bd60b882c8909140eb487c5acb092c024a9c6c8556b832c36bd0dba31565b70c35c2ea4cbf7a1b42d2d7184d37b3bb180b9e1078a793b7fcb2bbc97bcd8bd7cb3c0758f398a482565d185abfa4310c3a84b77b9280e7a6222098aa627497fd13abc2130ae6d34ea6c626fec532f1eb4ca97266eb95a728434ea1987e7e666ad09c0f08c6c581dc733f962fd04780a7565355083b12a56a7c4ca774b3cbf4cb762949631d8bbccf7b48e2ea459343a6beb3a2c38b64990a01971579014b41a3a90c06eb3bf83c502388a5bfbb0c9be9beee4f3c26cc000000000000000000000000000000000000000000000000000000c4ee36b1f287cf80a73521ada9ad4a1b7879d18d9264224ffb630b088865f8b6e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = f557aae24c7a8527f8a1ee03310c78172826128ca814882e33e4af6612c938d174209b287ae8a53adeb6fa0aa25fe6d19f027367239cfb89bf0dde0f99497ef7d7477bd332264ba237ec0e1035440029fbb5064ddcf9bfbd136e92f1b35a0a2cba8405ba42b8ce36cd2a686bde2fe338a013c230b1f1a99113c01babef6881f471081c9b9fe25f28c0fbf828c243284e6be4c0feb138729ac4a6d6b2869493abdb39a08563b2bbabcdabc3b349f74708b714f7e11243d90a69f68585b21de1cf742ed7637fdb5248cb5fee5a3245136e85dd5042163f2417e58a634224db95d004a4e9665ce10dd120b80df855c5ca5e464875752a70857511a705be5f3edda976ce536a5a83d5173c194d0a9ecc24f83a6b6c12bf06521f9494dc56d3a85df270518bf930474d9fbc3c77b61a1799db7146d5865d3d71e84a64e52deda9e16cb73ca1babc487a5b653664278f6256954397300b150b9159e5ef19c71e45fdc1919fb99508606e180305f7bf11f9c772e49e7a0890cb5b0264749035c3725e3f6dc99710889f8501b71872ed3674557e5fbbed85f819fdd9f6d83f1c40a04afeb67452dc3a44c77a90bbe770ec918557923e61fa704b3c08012873a0c672e511241612de52cfcb8c8e129f3b81f3ee76d99bb42398eaad6a1028b0c618b6c0c2afc7713ccc226d4c853227cc6864dec677e39dea238d79066f427c2cf7e9597b8b5a0c59536ea78485511b3c804be288c57d894322dcc2ebaf11d2da207c71381dc654a7458cd22c34703e0b720163ced269283a7a3a50f5e31868ed996227f49d8f0e02e6eca130356cb125f948eeaa0aaa8c324401f5931298fb20fb0ca6cba46bb98b02575e7abd822838467ccbf1d80868ee866bdbed1f7d84eb1604abe5f88a39041a18d301967260f8589cadb4e35c39cd50fbbd6a3922234732f25231ddc0df32fd80289fa8ceaebb0d19ee014200b3bc9f896e1e2585a0f6ece96a9983cdebd5738fa4b10a90536d820ba5f91b3fccc8e77a8bd01a56721608d402e4171cd91a56ffdf9236fb75e7041903a327bb2f8c487fdac2e369a4895b5affd68bb2967c2bf4f46144e6bfa796731ffa338eb9acc96374f2db1429b5568e79cf9cc077e74b3e048894c3b0686f4f071203c2ac7dd94e029ad9b9d8ff680d8bd5de38491c43ae7917c18b4cc50cb9793dc7da034cae15b8740b519d8c673d276488b8bc9c3c6fd127a7e9bced8385f39538ae500d76283779a4de8c360a976bb237822abb96dbde0408f9f9ecaa639af81c941460ea2c19541ede082e0635fba083de29c5d460079d6ba038e961745a0837edf37f7b0548c65fc6f8eae8706e54056b6b2819b79231139da08c6f66a4455be50ad702f1469770e30ba9b108b84d77d30e0fd4a220a4f4bdb7d07878ec837553f4210385c760fb7f180c943a965df8b3118e3423e28f6172a2c9f9c268342e1a0cc63e158c51abfdd23efc929b8dc17274063ac8c3e4a9f1b3ac373f7f279257fdbdf044e14861f4ceb75bac6710 +expected_result = pass +expected_shared_secret = bf9eb969821d6b129da2e353e7ee8619859fa2e1480599b3546f305e56c7be7e + +comment = Rho leads to matrix containing zeroes +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b169780002535317ab0223bcad8c9d0c6876dd03beb06403e50606a33937515359663546cc0bdb16a4a9d6ccfa0315882739380c591e4b3302d807f76256f441b99acca228f17c904f88143840648971cf03735ae9ab070b6c4057c6865c88964748d8e1c5fe919037f3853abc58a3950cd307c39f8db6b9c6794d6d921da4b5ea23391d916b7f2bc8b50061eed220e901495c9744da194790cabb66a3b34eb020af87532a7967a5ab190f1898cd402c093e4c0a7967460d5b0ca0bad973ca86e533435536366370388178d28349aab06090ee40291263c16d26551a03fac734b0f17c2ecc693bae40475f7cf5edc778060186e5811a3dbac9d34b9f478c2b7e1c7654938cf8031e433ce38c47dd5e9aedabb6eac802123a82c6aeabaabd76a254c451460639fa646d87576ba154fe0b024eb114af1d2b17e245c442ac9a82bc948db520ce2c887d57f0621270b819aeea5422129372142ac87c1762e6b891af95a47912029d09118f97c5a67628dd2997c669523c542393b97f74c4974395a857bb9b47b39d22b00d5e946365a2dda868934e514b35954ead55a76d812cf619113719b322b72d6d94187ca4d3a26847437b2195a1a034b530ec0b8c7e1401be0308237094abc79fc9c92d79675f590347d7b706361556f2c00277289ba296aad73c9f3f654d1893062735869255c68357a97558f0af74a44879ccdf7122ba5bfc5d21d805430432abee64c7f271a930db3aaf5f78d8889b59e654c18ecc915db8df2eb7930426bf64b62088406c4b5948b984d29f149ee897c1bb8664a8617183a3c477994aee870d1089cc77079369200eb944a79f5aa8c5315da8a7571a6ced0850b2a71a9ba6221cf14be48935e12c8a4cb7630b1661c3504885a065ab5e3c1f78327c779122d772cf64c4b3a63aeb7b7b2c11cbb8ba98e5c340b8634bf743731f0942b8c333261a8b9e5d60c91a707d3e4035e30bef3bb6089e5017d154279b89303a2a10709bc8a44ae248827c477c7568013db462b34e8a8d7731340f7658486c3e83631e21938c4c560e00b521e76695d09844a0a35a6b758e711687debafc31532d2d6a41e512e3ca5bc88770fe49a794292c0437017082c5d11b8a6fb36401fc92aa5ca7cab8b550fab6a74119b5ffa8a14069f58f81231f2a646eab240fb56e0bab328c4637d3559c9b7351f4c7f68eac27618a874790f0ce75e7c32333bf534d0512fdc837d7fdcb49762cb3c8529b8538fa725476e0939394c9eedbb73ccaa0a8879b2c029b9dc350e911278720240ee262830c41440b89e18446f195c7fa50c8a94b02ceb5c93d2eb27f406b80e758da7f99eb320cb28b2aa6465b50c6c42b9a77390b521f3e2830f789a3882298c649722748edfa9c8ff2b7abbe61aeac3171cf16ec0997952323d11bc29fc1a76e022cf2a07300e3a87fbd47047c1504e8516c4e2358113b8ab8078d6466ca802ba3141287181777ac12618081892529a0d5879f4ccc979286ddd4c3112145dec7a711548214d62b92c238e82b4cf1cd6b78cd94d6490ccf69005d9ea13efb1cff0028f6c1543c501255495118d76137fa4c12331800c5250a71a4a8ec01a30bbbcda5a038c682f2b85b6885714f6ec2e27fd00000000000000000000000000000000000000000000000000000049f9b6cfa4b1a8cf67a3b1f225a621065805a3939f4ae4a6d1111906e9c6b7e8c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 7a47d5eee9259bcb9ff2d28b7ecb9b5cf70cc36298f0578b0b8fa211f51453fccfbefa32711bf6e83b796bb7927185afd4776069ced5de3731a1b4783db069092607bdceda88782b7c7bce5f77bce5bc70aa9edec73634c6d55b6c7e66a80a1628cc5a0ac5a83141bd060c5e790c6d1e2d604b948df39289825258a575d559e1c06090ca398332b5df350870abdbf17a5aff739c49c50bdc1f92df4555f4ac757f5e98e43b287873a6ee4f35970785b7e43213d5d49078504d0f2d376d590440eebce8e86cd12a5f1669ccf0be6e8eafa396ec1407be8a02198a287649865cd0b6c149403f6d4866bf117e2f9b5f3353ef662b64381acb92bff6208dea2c65f49868404a02b5286dfaff50472d24300497d8b673098a8ffa09a3633d91853491be3e925b18a6f81d757da0585c948afd41081c654853f3c7d6befd41ebafa1a2393bb1415e312d0930da60f010775d4f86076c19f2957da96a0ce4903b9ca5f7ef18d33c681a4252e58e2eac4a1d292ab9952b0339313cf5ede08f000b3bac1344fbd5a23ce63f810c993285816e42a2c13b35ee685863d691bc1dcf61ecc4b2ae54a2732873c065170609aa0654279cbf77f790056f337f45d9ef3be9b278565decd4f86574322da9d37e4e6afa7165cd2b5d1d96fd6a27570e1797ca8ec1b64db363ee5bda8d756ae024ae1061826d90ffb68440aef1aff662c801255906fb040cec10e4b34353193e3476612ca6467a19a2635ed3497cb565b8d765642a8cccbdfb2fabea1e2a64fdeff5ad9b8cebd9505872132286731bf566bb8caf5016ff4eeda1fc612593cf812d69b12dcdfe5ab34d03a8804feb9f79683f3ea44da7293ae812f68d6a21cb0b66bb610cedb2976531e6b174d8a1cb46dab41d87c3ccf4e23c5f0860f0cf118fa50cf8429d239d80d81311e090a2533f88c707a64ea25cbaadecf72eb202c647fc1bf3bb76cad5c05a305fa2e67b4ff8fefc82d9b1868aea7dd7aec33d60a4039c08f0f10aec4826d3e1b8e0b845082fbb95fbae30293a92d5ac73856a72ff52040b5f5844b61af07de922d65319b943cbfdbcaff62390f3b162e64956320aaea0e2abbbbfb9678e15ec9dde1509edb4643d997b25db8ffe372ac7845dbf2a0d703340cba5bdfd9225526f249561a16e21fb899a71293750b122fa22e23424aed5a72bbce45995050f6940a51e495931fcdbb289bcab11607eb21a18f35ba5fccf786f04d536c165d4d3f5055b661a31f43deb64575aff3c2b61556c20ed98939517179e86902083ffec6d42c6f744487cc4fda790e87a73829b8849990a4c3c0b5ab5c0ea8f0567729bab9f2ffb6f032403ecca6e4bacf608851dacc924ba6b8051bf48aeeec8c5ca87b56e3cf440521e72f569ec80e07a8683fe06f4a584e7faaeb2ce6c8031755648755c75475a2d83941d96b269dfe365cabdcbbf207e79e00075dc4259f96cc9fdb3429418072c93ab4f9322246b3db1f436e579d1f541306ce036a8effa25efe0fd0b2a208d340cfd70cb1506 +expected_result = pass +expected_shared_secret = 43e175ccf07fb358c9b4a6117c15c327b88d4d8b95a645fcf1ed096f0eaa17d2 + +comment = Rho leads to matrix containing zeroes +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe33176cebbc9157cd2d0228c6385f0d9aa0f99335c9cb777e96b597551a0a644a34d3a419b3ad5351876d93490598a90f31a3a2a227119b7cb397988c8971a0459b2c811ebc8a19a094457c118f6db50b7b1ba6de5aa85e316f71866d759cab439c71d90691f1d27da41779f2c3380c600196133f15938125583ac7650eedb0b069004073205b49943a4fc00ab5ec5e68ea5299b95b303b1cb08b687c0b533ef3a98a7b0c3b6419a6cb825874c4ca5688dc5cc5ba5c49448b479b84baba1344a29493fa3828e953b3ba64b087ac9f5b9a3f12cc6cf9942612606998207a852b35f42ab80f1ac8bada3f107b37cc6c1b8df40391b1afafe848a92853c9b32b9ecb758b88c8f76a9b5e866e8c359f3fa29019f439eb0c9b5d4b2a516877de0295fe7409dc79caa4da5f6a87a26f9265581cb6d141c3d0e597f385bc77f966ae1c01cf29cf0bc536ddb0a8d75c8c5db79e967c899b46bdedb9528f596de02c120fa2702f73b3756aac59a750ef97ae2a7213ee95797f2149af542b992405c9d79e085521d2e303c14146180904f41937cf4180edc666d70238030b4b6572af377693677a5762ea7775c34b9314c10489518525cdea77cfe8b24233dcb477e9cf48acce10911dc9517587b409742b06e3142ca7a54f36d6ba225bb933632ff06802779563fc43a231a11b42b91feba135d7229f1d29781eeb65d93537c58525c4e48b85083b3226937acb2c7bb3941f95664c254c18bb9f91f54f69263a1d590c64f51f0d8789cb60cc9682082bb399fd87279fe4039c9bc69202a309faa488e26a4e3a5d64ea4161b9a8bef9997346ba46da3414965c4ac84ebad1c2f067a3ec5a0866e4a5a26a7403bbbc447c3b13e9c282ea36307c83a91b25b8b565155146fb5a5146e01c21f4aaa3dc7082e93a2dd95e7364b6a97cad2b0bc27d0aa3f393195250118f9c635f41ce82cb1c8ac2158b3101e3f44132a271a545240938bb56d11520e2474678391d4abf7200b775b27dbe81970ccc517542222a67b693d151ecf5485c198838a2cea0060da6285c6f0321472710d62a78c42c9edf07518704157cc5669c3ac775635e09356304819d718abeb0603886c67d8c0c523691a22b987af137a18d20ba3af239de79cb85672d8ed6beb818c5b09baea6c456ae3a4a7481343aa890a94a15a6502399a0101da2448f55666aca18d0259d95838135097273ab117a60cecae8108dab28d6945cd0a30099645892737c3238974588bc9b4384615917e8ec0c10076b2249a42f1841252533376830f1c2bd85456f4e8577f7ec1bfc7a92165ca5a83b85ed4c0dd0652b0ccc9bf5fc6946f710b0bcc42c9529de51bd99166eb4030bd1c394cce0835dcc311cfb6e3c951643f5736045baf1c3a7f11603cc168b6a47ca7eb909c6d9806543380c603a09d435f7695e6b117b75538d92fb03fbd92d05c7461b113eb5dca813c43efd7835525a228005076b969e9446be37c707ae0025e54863fcd72462b6aed873850cbb92cdbb209246945df26c6412cc16214155e57bac92562c5c14e1da60f9e036172cbec09caee2d14242d16b1b1b9659a7705a59b23fd93e6eb23442825473c820df8342bc33177f39451149340964c3ccd20000000000000000000000000000000000000000000000000000002201b62fed0c7f34d9f72842d1c5e796bd86e451f91f03e9cc73d31f8d7cdb16d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = e4cc5f39086d1886cc8362e6210515fec1d8474263af5d7eb7b5ac9c1bfc65109de928c818728fc17548bee754bf8df9f972fc2f5943291e24d0911a1963bc3e4999b6de2add2e5c15b3100a83be4647f3fadba3d61022970ce43a6d0cf5a84b387b5d05847185cc862eb6b71b5a8ef9747a12e399866b3839e73f3a73e38877a1faf8b88c3283f22f6fc2dce6fe43118ff68ca6cb9e88471dcad4ab28c657e30462f64a34a108bec7e3b6eb988c6bdbdf4a300d476c170879ecd62ceed6b530575bcae1f23da95ae486b3322470523429052a3059eb75b699a9941a028da267b970eb0a8d444296e421abeaac7106f0a45dfcb30a69d5336ea98d999e65bfa6a2cf43bd302512f086f8441d92c11937b2773b1cf33b82076a64b8327bf2f94f7ec3e83037dc543bcc8bfed37e3a2ef05e009745cf504f2e261fe194c256292d86d935c7c971dc4c32653fe88fa2dd822fc37b644a3d5dfbe5a710551adc671f954beb44da64c06b9f5a0fb78c1d1b3f94dd2c0a41829fdef6395da7493d18423b52bac69b26b2773d0c4242d5172722780843911f864959c14c4bfbd83ae4c19602460428f9f111e43fdd3c64f9eed410da10348444e6af25f0f83970fb23f0f5515c68041ad694cb9ce9621dc504b564a4757dc4d8ead6db23a889fea5a7982fdf403e609f51758ad7bb78dc6b69a53e32b808fcfa44b547d7b23fdce81ae90070e8cad630ea8000d8f840af81c6feb308b8a5135db80c2963203e9a13d2c5b4926e68b8893113c309c3bb4cb48f06fb87313d414b9fac19fdaade98e1b396d789381b057a293de05fd96454f4394b122de31d72bde9b39a3c171c4e1a036d7d94b8e59506dd16aa28596513c3a0e6d2618fe8d39671c28f33630745b3e671c872a01035da1624c6516b57226aced46e63c0a5c6f791f188ddc8b0c4637695b1b711a92ee422225f5509d9a53e894c959438fdd81f692b930ffb29bbd9b7418c97ce03263877390f86bdf59b617622d181061e9f146c6c355c7d8c16924f99d9b135174935fbb63b09d06734e41eacdb7c55f561da81126487732cc6ae18a1d8df377f865fde5db3289f0a77359550ff31b7778724449db57483c59a94bdcfb7680476a9a5a38cdac1c1033be8c1f4e6689bc7551a7d01912bc00e804b6e9e6b4e84e096b9ba4f07f0d67a3baea5e2fda3224387e298a144c06d78f26948ee7c88c11c121b4ce69ff2912c93ee7cd96ce4faf7ed6412b3ac238c05c9378dff1051e3a48c16a3daa8597ee0ee83fc0b95e2346f5195a2d8af8df16c9608fee9c1fed1d5ba11f31513431d304a3382f18c9ffce39a7c637caddd67153c18ebec8138b7cfe9e08c9a7844e879424531f47444b1cb48bf2cb4c92756a1c03f1d37d1f6a2a22967e5a719aae38732dd5e37f795591ac91faec146131b354ec31fc0e0f80d02c79cb6f40f42f3ef1d0ec6ad1cb208fd6e56ace109c1e5a82079eb7b6a32d358963ea06f7234221e84b67c716d7e523b502de542fd468b130b9ce5ee +expected_result = pass +expected_shared_secret = eb7106b4bbabe9796e68f15931ea311dd171561dd000bba4a80cbb13c17e9709 + +comment = Rho leads to matrix containing zeroes +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d6296030fcbc7549ba7ccb22607740c4a4ae9c72a7c9d75f27120e6551a24baa69b07859abfc0a3f81ae50b410cb4b13f4d3174acc7a36b3cac768430678b86030a92506bc3a37bd721320f658bbd2798bf78135c8a29c5c3b7eabd292aa278a0f58620a89c8b502b3cf9b0ed7d3606f612651f28f5d39646b5b6a16cc57b4574b42fbc5dc6b15b92723ede862ee02cddfa891a7b243b4b8ccab0969ad050a35ba05a8d650c2b19a77f8c97b9c15386233cb543063645dcf1c976d79999b5b16e095724e872c9a799246e9c68388573db17fb137a936aa3629e68398851bab14cba8d1c0be8c213453863a470b6e4a640adab4c97375d72422c1e55d6c892fd117999c9b0a000b7a51064505b237055882c3733020fb6375e48d1a07454cc6b2a7c40bba61c10062a9c1957037310aa66a1d560a61d2e2362d912ca5953e8c3a33967b6121b9a888ba87c388bf1b80064b8b75fbd6afc7dbac45d45cb3d9410aa9c56ab369cb4b3ecbc43942d344a3a6785049b78329610a297512bc9a2920bca6aa08e44467572c2d93b513fa83c97b1a29c161c00bac6484659c67e74ead90095d19481fa476bce539459321aa258da0e2579b06cd91e88bdd297447db2f5b836d2c3613d25a8cd00331948a93cfb6bcf5e374f9f623f571b330ca63ce6210c7d229d27256ffa9a32911aeb77024ccaa5145ab493eb29a2e2a134f7bae4c39ab6a162bbac174ac12b1df51bfd02c159eab2dad955ad3a978f85449a9f7b253a74b4c81adbdfc3efd90ca2d7c8b63e574a09bbda6599f98761ff0c1b14ad429512a46e3c1392a800594f95cf3603a760cbcd6c7ba86ec1c9c74c232f31a56f8a3cfd29f05914ad5220bb4dc23900b55ae5607e00022fc0002dc363ed67c5aa49abeed31994e3440253b82dc937ec718273e25293c01305f4c2c47ba47a5558c17fa2f9640034eea6e2f2955189677eca2af91aabe48fc93ad497ed05208d8401d921a5aac231964fc169673289b270ceb9c745ba2b07dd402d3961c2653c27a697087a58a184a9d8b4a34e355063da16bacabaab34c0f6a35ca4500b7e7ec51af92480f726b034b6246295ea017ac5d7586d2b17d074c7ddb3cb5e9597c35692e405a900a535958fa713d0ab6c9466baab305e83597d167783e22b7099bb913d932672954724631225b6b7c1b717388746ed51050d26f4ab89c56e12697a9ae925c5d91194097da004b7925a90cbb849a2e8e250532fabf1c9bcbdb15a5f17395cb93c7e374461c254ca69c3567c01468aa02d3e445a1dcb194303cdc3c580ebabe6d95aae182621dc52e18055050274f024ac6a5180a49dc0fa5033f07295d00b70a5a93be6ac1a412c4217fd177a8c433f4b26cfb14303d42a705984a27c305e1f08da46213da399eb658c14eb03209e601e38887f2c5cb2aa4384a1790ed16a19032cfa3f368a9c1218abba6b0b606baf73d58b4c771baab5481ae971188a4a323352a2b0f0c3e45e808e88b2ab20942c14496abacb28c313f246b807ce73d7b09a612382ad295c74bda7ae1249dcfb534143acd4ac6a68f7573bf256a946395cfe4463e76bf8b0263559b9618a859f46bc3aba5ae34f903038a1df1e02603801be7c53f12a500000000000000000000000000000000000000000000000000000019d4dbdd018404448fd2208e2433d1344c4488d6553afc581dc2cbaa10459f8ba9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = f28a06a7b862171162d64f9df3702b7336c47af5e15b1ced699164ae57797974e7fb78276e883360e2b51016d72d69164becd785570d9906641b0650c34bd1c556013688dfd9f2858c1a2151465e5ab51aa40c595ef4909b9c0de1eb7d4ae92467721131e5ce21f7365788798d18682a8035e14d2e769ca10589531ec5243e077a60abfae9bd0c03d8ecd7c4717c90137515c764ae0540a99fb2bb4057342eadca362c1b540d97d59408b2131df36a950d0a257eea95796f9230d649961d1cee9bbd30d1b88bb3680075a4c5976efeb95211e184db3665c7e184a912bcbcd3ccaa249c722b89c35d7374256b5490bfce5a449c2ec93793f0426c4655ec82f5b4492d44cef93e55802eb64d3fefe0d3b450c9b72df7bd85997c6c6b94033102091d4829ba10ec59dd5ca88feb328c39748d26bf44c5b5310d814c4cd9a1291a041169b0ad0af9dad279dd80a5f465bdc74c5060c2b226dcc04f8d8c03cc38a4eb1437c8500c9707170bea771fa27343b0efeb485c0c2b0b5fdd2d0e9c450a05b9d7f554031125e336484d235643f429c015dadfe10d050734e2dec4b915c3350277ab2bfc38479dd3f773f6d54a397eb7825a398e415664ec884dcd6d958c5794d53ed9f8bc8d1de0e48a12ba149626bb1bda6710b48e1803347412298db17c224f8279dbcd311a4e67711fa0a8de2f7d4234ec25952a415c96f4d3a92e8b9dd6d37d726375145d0dc68afaa08701ad5af5a9a029cff366e01f6bfc1d63069d8c2b00f9db8f1794d714b36e6e783b6a2fcbed61d16eda97803602bb0211cbf5b8895c2a451407fa4937369f0deb8807759b16d81f215b69a257e207396df441eee6f8069a9637cac41aaf6155dfb45a7402596370faeb1ef9bf633aa5eb96a207cd3ade1765a597d4f277b6f7c33b36e816d2368a19af20df4bcddc15381f2d8f04e4650157ec4cc0943ee080d24bd771bb35c0f8269be961249ff8a5a315c1ec1ed4ffe5a4210b5455f6d367c2df5f0da09d20eba91c6dcf63b215b39dca326fbc4649d7862b56927b41db2217459c23a9a9b9e83d79fd6f34295f3853eee312bfd30ee31d02fe026eb56adb6135fd51a8c9da35c171dcf5c999b1ccd78de1b9574b029cc0a845b196330a3e32309d61294468cd40ac3d51011eec5e1af1e397c0f6d2355e4a5bf69391e7e90825c524d76c688bb8cf495d2dd70d316996d3b0fcc8d1008427413f0498e63d5001e4ec571bc0e68c37947782e48d71feaccadbd1d99888bb6c4f22e9eee0800c09ce8ddee3af45272b4d9a3ff372ff1a7fc3f5fff8fc2eb3cc909fe273eabe09983223dcbe0cdb6641b5c905be7bab920a21ae6f43beacac025fe07ebd3d5065d49dbd0ba5d603f2c534b6533049c62628bbf3002c0da4da81f1e0f4e957565d79c4b1896b6de04393629fb453512f1e1d39b1462ce7f693ab482224dd376b0602dd2fe0ac592d7d0fb92ec5657af2317255ae3f757b01aff57e112c61f53b850d41a0d2964121a33d15db32dab2ac7583136e +expected_result = pass +expected_shared_secret = a39c5a7a5e9f4aa4a81e5463048c7028d0a2df5491fa678d38161dbd3a08825b + +comment = Rho leads to matrix containing zeroes +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa39692a59b6806bf4af964b370a7a5c3b2681cac9561bc4f59c0f32151e25ac4b1c80452e7cf2544824ebbc8d33ba3ade7ab1a585a98a51cf8632a02295284f2acb78373b0078081a291477510e7f6569751cde2106f8a064a24ec6a921103b8e5b820410f15e51ec7a49de77799b16c58d0c350f83a5aa63a286220c9ae97c2455780d917b2a7d6738735be61964574805f848c1d0a689060e591d60c7f057c92896a71e5109c07c0aaddd3622b672109664fadc3304118afc71644c2b7844802529f38b9a2212301dc2d2e589e7577ca2454a7fb78bab8165ce4f94cf8f121eec4531afa5fa02251090caa9425aac327af64601fdbf19feba983b0f55a22616048c646cbf08091b315dea5637fc8aed7b4418e09a70dd90ae1004d8162b5d58c24eaf7cfb47b26ffd98c48870c583aa2a5a6b5385b51e5f46236081cf9317c662498cce911b1c736e02503650761fb528d33d6708a4bab573456c2f01a52a024996a80ae0311dd56aa532709be25ac0e9b7862205e300253bd31210974b44477c3d0c62ab02b1f7d8bc910e5ac0ff29af6c66f05c48edd4601edb547ece62f8c4944af201221886da1f36cfd937e98d6a8bb606507c5099a76bc91a38812b822da60afa0d1606cac59b267ad4f47782a882a8415b9cef663ca89240c474ea265adc9f71eab97cd8215c10a32cc45287ed53180e0982fc6aa3db2b0cef48640992a33365454761ac072f765e84a46504304d775929222a6fe7a3c790b48bcc255ff189b5391add20c4581e4c59d09744a56a1941734fd24a81a968322b33da31234cea9387d31a9e9374cc4203a608285de5996b62143aa9a4dfa5a2cb0066d2bc4be6885587a4408bb3103a24b2561729021458b77951c8b8564ef0a08add70c3b7a1afcd3b4d5d3be685ba1439aa66a2393531b86a707576da189ec3885f5756c851abe689024bdc2671d926ca511b7c3b41e03c79c2b3caba27bb31f5a3184e16055c8127ba7b0d87216f81318a0d88f1665996a6b47bc7808daeb799935ac67653c59e23178da6a7cf40f9ca22246ac56db9417e5062d487c1b9ae3664109a9329567bd8c577d8cc0ed65cf1b6887ec3836fd16bff20a7671cc37b0921129b410a5e22b01d3477da0230ee5018a571f7519610c4badf145c5c4f5a29357a17f245f24e3bec0d22937457c38955f0aaabfb4d80bccf57909892e120546868b9b556289cc5594c7cc083e808f66e20d9c855d4cc936db566a4ada6e46b680df8b91898a002d9494a30127855c4cb843a8080205fee96f101b9c06104191d0bf92273fb0cc6f089a202984c0ea1c46d1f3b037b7c9b557af96e89784d990a66a1634888dabe6058d03c8b857605621a0b031a52cf26385a55f72d36555b87c5f2a36fdd4a72820ae20e90025a077e82c20cc7a8ce4f64c12940976d34e49b1200bd2b11b94bc5fd379f88779133a2f6453797f5c34a7b916f4f3bdc8c10de83b08312ab49f34cbca4917311401c7581a3cc02cbfca9b1da3cccba54c1ef7992335b25e282ec7677698c8ce94a1846443b1ea9261ff688f467212977493b27a43aebb681450ad64f31e158a5cb98a9ed43554c807090c22a1f343605bdac089362c0e2bf23a830000000000000000000000000000000000000000000000000000009aca1ba802d896abf9daa0d84b46b63742699b4ebe792d40deb9e4eea6e5755453f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = cbfe4560b3b067abd9cc82c2c40676f02b730c5280fb13645666b719e7d9d5527e029f3d75a3024502b338be060364a41981db3c7f52c59426b43fa835fc2fccd92a26c903adb74de93c2dbdf590996ebf1a9e2003e77cc896e2afce50d15bedf3fbcb65675f125745fcb1804e25ef99b6f792578520e82e599c5e83a500428b191bd93798b73645ffd10c9beb3abf33535bf149a3471f85f55789e3f73b55425185449c60bdf62c01a8fb1936f50db5d436066824b378902a81c5edc3b74b3bac3c58eaf3a993b3b4c1f2a0027cd7156b7127412294214fc7aae635edf26f6e5f8034464abc05f4059de6cabc5e4a8fb83a8c25bc88e7e9bee1a8cf312434410ead60d1b482399422621006ab52127df15f7385d62480bb0fe494843775aba4049ef94cceb78e9dcd3318608d3fff2e75e29769cfd8df0e12a77ba6db5f54d69be74a2b03d62db822a8cad7f20ad4655bfd73c62064d23fe521d37daafcf143f693eab811d28da6d0929be3cdf61a56e487289c02151f11342756bd419553186ce79bb17d5d5754752bcb72349b65cd64b8fc6066656a9cedda0aa9a09f567cccc23e547cc9ad86f636233be7815dea220e29863d830d0ef9b0a13a62a56237e2c6f443e61410253957ce3b0f95dd422012e1b84d32ec17f534f56641e7fe92ed181d830b4d0f3245df6ad891c26bfa116d40460c497d8fbcb6def0ee530ff4422d132726751d724cd84f8dd19e286e0a4d891af0e4a913352b9afecfbaf0210077c5be9ee7f5546700754f7f0dd2c2600f113c747d2a706009a8838a7b2b958324842f8fe3933b8e522d63d772a3bd0d5186342a20ff3a5e7a5728fcbb3ec18d0c90e5fd2430359affbd9648d1ca2400a55a99586807bf18041fe7af6f51120ec366c99fd4994f20e540e31caa71d5f95e60a921cc62db1fe6f9219a7705edc1a7015e7ec126a22f7ff0c9bb4aa3a1126d83ce4987ebbda148fa5b3cc07bd7c78f26699486a3dc690920fd21d75fedc4b631841b634641594fbd98ce2d8376b179da29f925a31589e04c74c4fea00db64289e30ac9e58043955ccabd9515e0c2a88e6b50dabdec8b6f574a6c44f4a0ba4d00478396852263376574706e5f92220492782df64becc8149b24feaf808c85723b7911961051468d38bb94421a18364e2c158035172e9368810d2f68f64499b6b407bf775223a3f345223ea3c1c5f456f48983d994fe4da62d0eca318b130bc8ade488a900b7746633187bf12a598f6f144c55738d4831f0ff3802a6a8f742d7a9f64f95f2401194ffade9def6f73fdc67b386115c9d905719808f41e2035947cde0bbbb44d92e51258822bb4e4493a7a4b0ce64f8620b3c54078985a3dfd4cc2b3b5ec3fd870cd6ae095c39049ad69234966c5f1f70140f88c75f11f03fa25c3d673e5ddc14f79f567bdb29a2fff88e11660327559bd0d2511d21a8ff1957c0beaeb1a26f280b3f1146be891b39ce13010c77b775d11552e59dbfabbb64409553d3da222902d0ac1e78b21677ef +expected_result = pass +expected_shared_secret = aa50a536b37f28e5f80904269d0555a6172d717433bf9a680e75e98af3209a91 + +comment = Rho leads to matrix containing zeroes +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d749389f5b871bb5473b52efb4ba5b2a8317c7255790b7e96937f9c95466431a268b0bbb12aa639d418775a56d3595231262c6602be765498dfc0b5cd404a630cbf46e06cb235ca7064a8b7e2471fe34ec3db94c8ea14abf797d5259ea7236391c3b7ddd3c3aa1745cc6857dac8a42693274507985c32bf65535d6644463753c00e18ba859b86b654916c9b14be78a5d11a2fbcf9ba9225566b600b0edb3637a18319027aa494a9631c6958221703579d75b9cb09d21c34409a3d2b342c05bfa4b82b19444612395bafd8ce0bd772b303bdc37c1e57a26c6efca874fb244ce314f63b6635c7af1be1a3205498204505a80138bffa0e79b60f58675965578719813e31b352390ab04376b45344bd8efa65fea466e8c78d45680be0e1381ca5af4cb666749676b2eb1e02d003dee20f4298b720aa6895a80a17f242a983c97a43981122043d444a5af3066816c7a07c7c880b2b2b8958323711e5551c91268b1ecbaa3342418b322766334d5d4691e0111d56e48637c012bd04a9b06524c30752fb7834a2506db7ac7ead1b72cde45dc793cf875085f67a055f6cc0f7b703e29c578d0329dd2a01ff05ce9b1a5a8b993621611fc51356b5d4a55c4a6ca3b5046d7b9e305494c93177c2e78ed1bca1110c7221ccb07ef99b3aec74a8f083ee5a897d55515a5117b1c244c0898738636e577ca59d16cd1c44299d41c311a8728ff38bc476b1027426bea27795396e2bc24e0ca43e17cc8e63bab9463b42bb6812e7b840a9943ff11210aaf11568c85978816bae1457ff364923c846548b5908b2737514c625c8c11a0898924ba682b3c8c30437e8b23477d06d89d39f590c8e2561c698362e99224450217cd0a393ccf870a84159273083008345b2973e98d78089317f7993c299b7c64ed3309b5b6594a236bb8c1c67cac692a2a1746987ed6ca84d5a5a4003b1b1347a9846656a36034d7a148cc8157afa6c915a05a81b1d88568fc3f62b9996062bb99e43447bb22a5b29473a728c929d57b6ff774f5364c9f4145944b979bc549c1d5b0e9e676b2d493f799875762360ab9bb4b322484bb78fa399bcb889c08c94638d95518bb8742bb2a801233adab5bb95903f355126629aa87477b19d3135af8695f3da81df3559d510a7da3cc364939c8b507c99096630601d60999278b731824642c6a018c22c82a60bc9e0203e0b8139dff977c2a903b812a0a6c79c9bf21618b4ca7a836e20346f64483c277750d38b0a204baa8b258db85b3222a5cbbeb599af8ccb19c649ae048d97153b5a7c974738a08c1c653292496287682670cf30197142dcce7fac5694f58bb9e23c9b496f0a939636d6522129038e99179c8cc37697c83e908aee62a1fd266a613853fa12180407a222682b49bb41c9c23c55c63cc7d115da6cb53bc688fa178f632b0b9042631999b6de6165322a817ee3037bd33e6d6024174439119993e1776ccf6862e104019cf739ebe62e0dd10628dab37946c0f1e762ab4bb94fc993cffa89ba245d7e48055c43a8819c4701bcbf44044210c451fd4c5a82231676ac2941278ffd12c686bb21547a1e832a48cf991bca13433d4a55fb485f04546c8a3201dec55d1889942d1928250867ddbf1a9138000000000000000000000000000000000000000000000000000000d5caa2fdfd51a2788de89e6d3e77f6abb8f38693cb010deed4069f451284de44e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = 0802659cbd143028c3d5f499c51d88e361522a2a6c353f8bad088b1f0a6eb02f94458508a80aa98ec29952e405f754a77ea9cbc07ccc41ff66fff5c4664910a6363da480ea8f0de3e7bda007593199494e6be43c713178b791119adcd4fa712e077eb46b39d1bb073ba7f39b56885906fed63a0d6a1be4bfc2d512a17ae327fea8f1f8ddacc103fd8a1131908ac348dfd01372968ce3ed40ae90f747be9294f8e3c356f425dcc5002e9363189969f3316774acfe7982361e6f057a322d667032c5e1b235cb44a7e7be4cf46d3f6b59154ba303abd608e75e55214ac4993683dcfb5f4cf3d99b31b43a054325cb6fc3614b76ba18c6f40ca3a289c6ed338a5ede7677f6a57cc4d1c0ba121feb6cd170419a7c9b85c63233ede2db86d8a52018e2f00ca1ac31157154dbb539cb65090b2eb3a5ddf6195dcd25a2c3c8ada060d2a9fcf43bb1e67ac25dcbe67709f00abc94b9ffcf754fe742addb0b928df78122f0b86a2a3b7db85db4a9596f53048cb0bd2e849b97f99f1dc4deb86d4333a891f1e5e205637a31956cdf6442632618e97b8e2f71f0d97a88908925fd1f19956d34b67b258c49058c9a162626066731ac4c8272682c6816e7a513178ab4468772185d461ea5db42ceeff258be448ae8337f1c8ce44771bb79d6e7736949db9b68307388c7a28781a0b0180bece5e0f21d99309621d6ede5031cd791d591b7296f8fda67af0563598b463e19aed4576c369dac22c7e74ef6c1be036a74e9483bdf534cbfa78455a84568a7a2ec9a43b0be67ea16758cd60c999cd72a8b14dbe544bc142eae6ebe838091602535a127f7c1d6ddc92c07f5852158da2ccc90551edac0f043a951e5c47259001c8fe9ef8a9af5d4e40422dd8b0244468a5a9f0fc62e300f0b80069993cb0b5fd6555c5feb71a9e07fa121c82dca7d9df561b967436dadf5752e9cad9bf587a3e6c18d6fcdb00aa21e6698617ba0166b52f4406b7b184abf053a713e55e4b6d5148651fb29ce1297554a254df7ed1c97c2e30e6afb19289f1e8c94831211af2fcf6e3cdd67a04a65c19ceccf08e80f649b5120f6f6efa2af36c53884ab9a5fb5ce24971b9c907a130605bd996e6a7e4b8fa852d421c5cc46d05148957288a98ede63b556c96b6056496736b1f1832463e5ce4ca602eb3c2e86712cf4d8e44942554d930ebfa9eabaefe29358f23939948616c5ff831f162826732c25c319155808eeca9d7cc5e3325b01bffbecb7520a72b3b71e4c50d959f45b6a79789dce902ad29e3a66373bc1b40a821c6f0e6057c9427f30f3a7cad672542aba0142ac6b371fc3da667a5aaddfecd70986571b49bec52c59eaceac305dde821d248da99058e3a23df496fe51cdcb45501b02cf5338df7fe762990c2a6dcefb23dc1e5a257c14962501ab1e479881ffe5868e00074cb8fafe6477b16530854da6223153680571865a6ebc058e64c11f09236886c736592e73a41de2c093e88348631cf31de6440ae21bcbd045166d3af8539d77f2aa1b202056d23b +expected_result = pass +expected_shared_secret = 9f4a910d1fcff86f96149e88e28cddd95526ee64c491291e72a2719f97b2beb9 + +comment = Rho leads to non invertable matrix +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988ccca947895240c96489219f575bdf7b6305fe7ba4db674f8b57be7d17947b73ba481a51737962bd0ce801254d54bc9d6d5bb184609d844501eb81ad43007fd3513e7e6aabde15bfec8b74ef67be8e4b61b4358d4828914033d65f89915e6c27e5676c98423f0d2508c343e049cb8044a4a77666a3475a52a4c73f38acd49519486e511ee7b8797b35fa8301ba8fb793f6906304842604b5608fba93f3505a765ba5c329289fb4a69347501c686b5d126ddbc58f5b8c5bbf044a1a58926d77ee9a7bb0ffb69f1986cf10719b2379130872b8c6640ab856622eaa08b298adf98115e68615d9627f339c4f08ac67fa464ab5b4824ca3765e33a16f7706ab7c1deb31b262a3e14870ee4bc30a746171f3c998fc73663320ea3475564c25e9fd869f1e3b94ec15ea8f355e6944b874c469e96050b0ca62985912a4b87c4aa5434e4929430b06f220737cabcb771b6714497cb07b319e57165449bc7904201012fac808013836dde3555ff6462a77125a6a0c6f4aa0822006ba5357ffc494602d87866854ec8b646ef5a545430bbf155cb4e9c36ce2c42b6e48fc26296b2c1415cdc8d06c38ec4c37f9e16afd6fa232fa396832a26c7562fd55b80bea977fdb5b7a5f95e221401a932687e535b0213056297391d36b0cb320cb3358e1ff19a2d239a8f5a75cf40a5b4130ac2972c1a5b9e4fe799394c23196805459336deb36367b6b2c81cbbdc56840ee0058ed799c5c735df07a99043201c2427a4699f5ccacd3c86299e458f3783628258677126556c485406d0678d030afb082b88676745189800fd9d6267b557a3936e262baed80ce471997b0147b3556a8f74760e85391300ae4f84c494a09da042422f196dc0ac3a65687d33ba4219788037a14fc4087b585842290593dc853c68d70c410b98117249654c3332685de518a3beebb5469c4d2a624855124025544afad7a26f5234bba21b8e772c0a58572608857336a9ad070b6b01990fa4bf797902d0765c83604ee4767e11e4bf45ab7dbc9ab7efc180789070380badd67b96f0c90cb95a4152144956309cc0ea6771655ef11579dd703caa09c1e314493b758e8a12a8e7dc8336c29a2a9198873b2065caa6c8ec545c03827b39b210544668e9884353791348bc74032d4a7a00396744813baa1a83b0d1139ceb18c75f6cab6b13cb8722647a730f67219096b50375a105a5dbc960142648fca49aba468ad77a031334ae650ba879a859e80901a70fc2d80083c2b0786a589f1b65e0f83527b60d298b8b93a177901b78c61bc6ba296a342a412f1c48250340a0bb5e2b227b42451aead12b196540c9f001907a40bc68821b040607f918d9199693395d4f828de0502c8c601b2a787d15dabdbc764ad9022cbcc87fbc4a84c22840a39cc610905423a5c4211abe722b69ae78803fbc56b5f3671491495ea9a7b067541954650582a1a6358af04419c4d2acd16910a03a2c04a1ac3ac6138f162d61e6258c863427a8937b65c183734b533c4bf0e52c3c06cb5422c2bdd063e405d08bd7a82dc731c2e526a5d19156b19b68db05421c5d099334bba29da2d953164c6cb5c6860de4adbd60525dc96e1d261786d79f09819d680598a900c42c3042e336828a1700000000000000000000000000000000000000000000000000000001a391043e522eb6682ef71d7ce5fe4a7b6be5a0d5507ad3083378ef190a50a611536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 2a7190d8db048ee0963d59eeb251bed93d3223db4415e438d40fa06cfb65c5dbc9cdc219a8e007434870fa10c8d64f0aa3e5016c67378b670852af5615e23b612f08d0f83d26d4f48e108b6e6a639649d618245055270d7e6f47c48152ce42effa918f74118dfabf87a497a412a0cc464e99d2460e0dcf6a16b99e8f35224894defa85a02ac162e122a4389a7c85668781c6d682422bdff1edcb442a73982c4512111c54545fc8cb65d1fa2ee1ab685cd047aed9085af1144014810959fa49e7c08ef15bb7c97e8306e7a28404c9c26e21b053e9fb6ce86a76b13fc28df94f3719bd55dd281ad1b8289f8c53175838fc406a7d705c4a91a2a0053507fd7176c1efe28bbcac57f555504f5b2ad0a7e8e9d941fc80080f6615130284e428fa18740af5fdfbf848b4c772e38347ea7cad57a72cf02e41b114de1380238a6fdd35d20e1847e92c64a84039fc3564a7ff85ee6c4a7f5b05fc90f95cafe52747b34e3a9ae91b28c659f4941f2c9ad595700c31b0dedb53d6a2d4fead5d754637e89c4aa7175f17882aaf775d850287460e4971dc112c498000f4da174aa4f4f3f3202ea9e119cee357caf9c1fa9623fd1033df981c09a010dc44a71a7d43d55c328eaf205586b225ca998c066623993046eaf93d827a891f1e997fba4008db106e430ec7528286b2b2032d299acf11fd3f8fb57aa2cbb2642412546e09fe139b377ce8f6e1890be4a23f50de04b5c93b701a8679ea102f90f4766d603a164aeb7270ca85faba085f15eabbe1c89ff2edd4b50227503cb31c34f645323fd38c7bffec6a825621579b565339624b434abc090ccc4c1227bc63d4bc1a6e2535cb5b299ef03061f9bff77052fd23984d7d6f63d986cf310474feaf338791b158c542a361c9c222f4012d4981247f4cfcdc3a2cdbbeebf9aecfb97e29f9c328be170d5da3539b277d3f4295c6ed3712627b5176b7ad1d2aed1445ef2e47e46d251b74b906f6dc3c3d9f54968245845f2fcb33522659508bf54e6358dd3cc43c2e097b880371c6cae243b11f36f8c34ade6ff113da5ea0868c4f8a5d0eafa3fd5ac8f5bfe776f5f72791d654fd845d0ee6c9d28fd835dba5c367af22ef2232526bbef604c163417542bf6fb768ce2c29000ec626cd56acd6f3dbd18b5485b710e4456f2a01c25bc0af5aa330a5f9d45bdfe985710351c167556acbe0fd0b7bddbd3a86dcc7d7ad63130f33b651afc897a7fb2a724c205867c4dbc86d53e68b1679626c750fe5335853a3489821e52402d0b1ed47c69992179c663ecd914e77b0c94e870ba17929d53e567d444e592e580b23c160933fe3024a49fa8656236d3917192c44b0c5a30d79a121ff12411dd6b3d443a5490276dd379fa9e3227b1756981b1cc0ce44fbb939de802d16ef81bbb98ad6add920c42d908c72b7abfd6e946dc16598272be95c72a05658070a211801b6ba7b04248898272e6a348b26e93207185c2d57600493a313ad162561da704b75b52388d84b240993fb3a4900a2951bd380589fcb +expected_result = pass +expected_shared_secret = eb34705a8743c042134c4f17ed6fe334ee260a7e77223af5bf77788ddbe5cac6 + +comment = Rho leads to non invertable matrix +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc33e5bf55f1b014715eeb1340e17172a3414c573732bed83d3318b40e32a5f4fb064a8988dba93c5f1aa8249b1d0d0393ec765cae519961c109f607306b8322125b0eb6bc000a061b2222b58faa86fa706e27803b02b79aa4e9b26e37130cf14b903a70bf042f4d72c091297179f3a1567b1cd98bcc4be1c38a75139df8c422769289fa73562a8429e88dc60571e933b22d8a9471cb7bc11a6b74e0b62643574f91413e9913229584dc8936016cc5f5560a044488183a53822c77f5b26ff9f2c289e7c88795301e095efab2b84f90350524549c855dd9928dd735a0da461450a31ee2e3b285698b5049000b58344e393a33ec7b114acbb6c69ee40b62b986a7a70a6bda64ac03423517360df820cc2f5a0e279b30fc77a41b220d6ee3ccdd4802ca3447d5065dbcbccc0b3a79e932c1225acc8c02c906c49586037e6a16c5b6c64e6e6c338937ca94c77d9cdab427a258804768e739ba637725b7f98ec064b645e23710d50e1a563719b190d8127e8d8557165a7e61770008621b211c1ad9f004a97556d41511d2a8a290490a0f6b289d3c35cb8830f5f6c4d60b9cbda14b50677c210b6539229d44c7376159c4d4f4b7e1557e1a25a51f6456bbb983177599f7f1ced0b15c751b1046a1015b4acaf53c8e43c7ae7a14202a54a7e3037027fc5e8736a4d7d9145a56cf65b862f03b3a9848c8c2704295f328a6cc83cb17774cf20f9db1162fe604c77100ece175ac3a9f3f297c72b7a3efda073fb6397e0aa8fe60c9e5d26281699c911632d055434ef4792a87c96d17228611828c0282ac82abc3041fc902c09a1c918fe20a0506788a31cd01583847373db827b87b7c29c519ae2071185910b4f586be80488ee85a31c63857fe02a11bb270337b6b92a32103197f260b0929e289f9c9308056a7539394c0071df82591428bb8a2b734db430074f9749da3bcfc46163c3b5f31430e4556b91efc1f62aa912361209746909eca91b40ccc815c1274762b9c697cb7659dd200a29a641db2404b954a1c17994d5b3a49af157f7d645df88863f145734d7262cbf8a640d2b31e601124717c6f456db325b1b4b344bf3a922f624df598756f8a2c2acb0c4e62140ffa4cacf4c6e03828ec903acdecada6d0074b2364057584b3f0530bb587666a88d2e354ba68bee404227d7a963d8bab4c7545b95a984d117ab3f576fb1ba4e912b468889762009eeb83949d39613ae7054d9c76ea556ee4a8286bb489e4da9e4bda4db0714104da37fe1777adb632c57020164331bc29abeb356344081e3907c467657ea53a1111d45ee2f416f945396e6c63df328575808640ac5b1d5a711a5523cb7a18263224ae615840f9c448274409369b2d66b135e57648f07333fa326045681dd20cd9bac300c834ff582c1be9223f427bfb13731b27175c1028f55736ea50a7adbc819c742c22328363632f1917cf5c89441b841c3532693c3718a1fb693b28c103ca3ab9690502965f907b82cfdb4e0fa2884ba7ce8b0768ad36a32ff60b4db45edf64a5d02018836a8230c6a2f8a037b72261f4436b987066bbc90f65f2c940635cdbf1b4c5a853a1113c86010bb7b558f9a773cab0434399874e01afe167908045c34d3f452196000000000000000000000000000000000000000000000000000000794a6406d252e3b08bcb62b3bce496a88019d6769334ea4c56acad3af1c5da402e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = 0b52af120747b8cc02ce11b70f30e159c9f3028f0b44757f23deb9b62ec75c61d64dcc774729b5ed59c23cc809a88d075021e7799b50024bd9ebdd3ccf710f17dfa89423d20542a44a97ab3bda0bc0825f76f8f481a52e66c344c024d0350e4d28b49bed05dfa166d8a5ec175e43a2a535abc6dc4decc1cb9afd9f05634d5054fd7b4c17dac997a70798c5c712b276e56e2af4543f9b9e5ce362d2f5f7c2f5af150c9782af88ea561161a6e5892c6a7d22a367dd461971cd801e9c5f2e2fdfa70f39550d06157e66e0806143fa56d5a9667e038d0c818b2be48de10408c67c948ec5cd1c543fc92d76fe299af65f94edd82f0be2ab3cca31272592549699555dc08e1de7097e20b83fe3eced16446d90f79ab46ab702804cb3a0358c927b7d126799f52c47e613a2730680713e8056135a26bafdd8a9e38d8c30e628a090878037da0afd82b9fe89a601d3641b6514b0450e3792fbc60d3e78c7316301b2e3dad4422c85b4afb1d1af20de6938a1d8aa2625b637ebcec8754ab5b66aed8b13b669c81f986d158cdd9bc82db0eaff8c80895d9289e30f0595131bb9aa1e77fbba451c1988117e2ce8b4e3cfa6f0b5c00d894753a9c93d269d477b1c86fbfaafb1dc083c7ecf3c688b36b4107a2c800f17d14acaaf795fe9ff913f702d188a204a26a3c301e44a84c5e32e9c8efb7236943849dc442bba5552fb34dd7e7c486959fdc8df5d380b199a9d637c1d11091406b3e3d2ab587794eafef76f6302c1356813109acf1dbc7380f6eb082a2e5cd4e53f93dc277372230997a0858229f9ffec2691d39f748dcf1c911f8d49d281bb9299582e1dabcac1119a7bed289a1d5ca9b471542be7e5bae58d275061eed3ab92dca9e444061d641f3e128d9d44757b350bcf673de1165abf6e10f87d101562eb6585baea22583fd8193da19f15bd88ee614523305e2d996b04db09aa3ddb422c7b9dfe93237e3c85043469916763bd58132835795d4c6d01682fbd877d132589ff21de3e4882a927971ddab6e2b31a01f3c32ea60f506bab44f8ae74cbd33e551cd7d52791155f390b409f169f2fb2166719265c6d4fab72abdfaf530842ca86e6f2d6a04ff0c96335ea20564f6328f4a10caa1b9ae6a2873a966e2d2ad2819f3e398a493d878bfea76b4372d2b24b93edc9f1e2438ac6f3fcc1944ab99c3729c3526bf1069b866f7b630c5b6ba7e10696326bc0096aca3a6e526e484b8161716b7377f9c5ac7401a850374c3adc7057d0f783eed9c98a3004ccd529a5f0846bb6cecf98c55470a7b55d3c1be06cbe3a3fba17f118dfd68aecd0ba783cc7489b7ea3bb8fac98e70c1e8f047deefc3760dbcf6571305eb1cc3f88ae3fba08359217ba391c1990d33b89174a5e896d655aa36909a4fb65495651ce122870b5e870edbc4b0dc9d72dfdb873cb219d1d7b5143993c01ab6929baf37ae6de2d920eeb333eb55a0a32a1a9ed2d4f29f9dca34969b268a9f26aa6c0d8378aadb5f206beb4f607f308ab64a9b1669c87fb74a55f +expected_result = pass +expected_shared_secret = 4ef9b4bb13acabdc211c3e0860f1b2dbb4ad467478f8fee194ac57a869a4a8cd + +comment = Rho leads to non invertable matrix +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca5e1b4c439d04b5c35913283bdfad965fd4749a9eacd65d1182e83b448bc3d8f25b525d57db01394cd2b99fcbb6b3140c46c9685916cb4d572a78f59af75342188156fe6b991a7780ad5366104630700d585a6b93ef15a8025b8a32c57681ffa88c1850fca4b65928970549aa668477547b30afea83bd3cb6efa038e451688d6932d342336fa074565775680790404770a520b0845a7a09caa5ab20326c8db671541305ef9264e0074505804ca2b7bce041b69c20d0c67a50bb46e57cc920d4405e4960ed1b20a14fc8fde1626f7607a77cbb9e7835f1407b83ef53c66e3145d764cd297badba3c290957180f650844c31feba01ed2631cad26057fb610f302636500e3337b073e33b50fa647eda24425021c5c1c8eec6163ddbb6419aa3be57bffe37cca885b8456652f7c00ea65c78d2db431a28883577679485611a9cb77f95339436787f1369110203ecb1859fe49662bbae39b6bf736266e1670940780db319c969570c719499ef871e87ab61cf435114551295ea4fba96ca5939ace7a9b712635c09667a2ca87a241380edf030abb8290d1856b520aa75e52fcd3316ecc31a8c71136480c41e7c6074207be522155d66a70d73c913a62fc4f77202203c3fb58171706d55455adcf115314b71ae00745764877d44321df625916a5eb5a39bc915a7adb5c16835817ba9438d8772273038abfc29104909da051dc542719d19007a786189e2cc9ed9268486068a1a531c108659ba37383a9585440dff07116f4b5fe9b1a2dd73320b2051216009a498c2c64b59aa539244e487464475918075ee807ee8bc9bd413af46f80717f31365653b1173693f1c5992b45770c515323c74296a0ef3e8b52be344f1000f22971ac19233f25a4c0df631a2d2b14fb5cb85d6ba9c55a5dcf42be1f18f9be91134a64c57a723f02a13d2e4029d6baa6d0aac1dd5cd6d483c3b7bcfe7f69202d321d4423962a304dafb930cca0671eb6ce7a0754866827a94af22b26985e264af1278cf481193390a2e870b413884c3da9928caa8ea5595a4c4aa2d4a6f3a9956e87c87ce699f04640d2d699a4ff314abf653674b351c69367a7c6041b87aaf8a47ce07857244b71c16112db463dc3239c3908bbf715b86a2b7edec09080c1840a2687c4b57854238a2555d9d2469e798cfdbc6ca06470bbe3659e1949df3f8a6ae42822c8702271029689b4ae1573b66f5541177ac5e05118d4364f43c79d5d2cde2567811617b06965cae7491aff33d5fb4bc24fb8a69f4c0c651cd53084938a56e792c29d941abfd448a38830f9b482b26fc0f5f8a25a2c570c51a62e605cac0a0b19d3b3d5478bc879896a3e01d5e6a97a8cc876bc96ff3040a81c87afea285a35b3375d5b8f95665c1bc6896e46b09d4a5b13a48eda54cfb168a74349887a93ed9e5a1f40a5e37e2a97823a2aa7c5cb028a3e30b19d4b94857090a3e8276ffd45eac0240dde5a80f46ae14f184fbc29804726ca50462ee2583cb92953b22839a27aaac963013b13c1d1847130c96371202b8027f3df427b03119e5e57284f4751ee76cffe81f315932174560dcb211dfa13ee9d242dff22934550227ac0f59698bb700b97bcc95fec45cc65b12e25663059565330c000000000000000000000000000000000000000000000000000000b2024fa7dc204dc572e389002c78d0f96de9fd70568e31343cc05c95ff1aeb8a5ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = d421883017a28b1b0fb5cbd2e19168a0405633601a3ca939f5660877863828dcd366e6602ebc6b7410fdbdbb148fd9d9b5f803467e0bf26a4b3c84f2f90aed4f64d60ba2862eeecd9bda7f4ddd0c031c231f5727a9681845774573711afe23605c2aa64a89753f8aa0c4b51209c3117f111b82e70aa6c55826e12be53216d299b1ff18d2fc2c8c207131e462d614a92171bfd0855a2319ed6a4812d6385a3786a39b489405fded21cf7a9e5d581900c3f04a75be593d4ef5955fd7419813f65c3d672a8be0cf12b42f19d3775a489090cd8cbd07f2f5ea5d4895e15c53737f43dc934d2252873554ba8f50bbbc4a6964c746c34541eff210290c3b128129b2f8d7e033ea6c945d666c4baf45883fc724da572265bea46d6036f029a7d25b9adcb0e88f290c553378a940bd0425caf60374cfbc4dfc54879b95f7ae4331a8789c2086dc4ade9c580bb8eb2fd07f3170cc5306136d715600e05499fe6940aac16f82759065a153bdaf51335affd893c296bdfad1ba11fe4b10b49c2b2bb54444b613d6b5c4fcf458ccec4ae711f840c5bf7c75e4f808e5da7d112b735345d7b7cda8f6aa8489fda2790d096dcb9f8733c7f589ed047e9a56e4dc0c5adea121966be8a1215eda38db95efe2ffd6356209fabedcdf2ea4cad4b0b180ea2522d98cae0f09f793f037dbedd5f03d12db9016bfd79e07726cb575981da69f88a8aa5d104e90ea53ab57fe27b291bedc7acd5aa4449053a7ac8012fcf9899bfc423c0018e539321a986d4011f9beea70ca0e984026277290bd9373da79389341c90f1ea64de20a5415dfa16b7857df261e68d515c497dae0a6fb5b21224f0b2a3125dc3fee9395316d4f269154f528f5bf3ade728f8cb9d27147751304ad1239b955c911ef2f61f0c193365ed6305d4c0bd97c9b2f70e3f5f60fb9cda8128bd7cd6e6aeb1e7909881a6a35d34df4224b0db7631df1a497a0dd699a086aa8efaeef0e3cb582a71deabab97bfb77fcfc2067652311604d56ef3999c34b72793323607c59febf9b41816d03a4db06afd9c19444abf09e1126a5cb19842c9316718d3cfc48e52a0181521008cb90607a18548c6521520d887935c0d789942ed48e68c28905b267c9493e33004056ca159b823aa7e42d9b5104ccf165b0a8e8dc19a3db59b415049b1d82aab62bc6f2adfec2ae128c8b79c0c9d750ebd0517b6ed61f8345aea60c04968896da13f84224fd92d9c56862adb73c0d5c3ee8fff1c05a4586446f0a74ebf39898adec7f07a7ba97c138530403f2523d85931e406d476c8569e0877f73aa37cf41f0448dd2ebc89556e79bc9a081e7f34586cd7cf2f960ce8156a3e500e63fc9d652f9af37bcc36117449b06f67caccd7b9f94782d84791990497761d503d07fbb50e1891dad302f20b16bad86e1e31f7c03a9172a6f079e244314551ca5772d43ae75b4c3e44aa362f9a950c7007a7e3d9758f8ba2664add4e37cfbede8066068b449a100db9e35386da603f7abad9fc85d32090ddbff01052c1601 +expected_result = pass +expected_shared_secret = 96b7761b785b1423456e7b84f37464eac941840ce73cb0e5903dda9c4c43a296 + +comment = Rho leads to non invertable matrix +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5a58974c8174cf998b681737830ab9132c2b925ba0a9dd7573197a72997cfc9fcb9b7fb8f7f7b881b280e43b1719fca705a209516981c2e88a617625beba7acc5a2335aa57daebb02869339b907cdcd2c4aae01a57a58702fd0883732c9b334bdc6a9bd8340bd83d5b0cef4ab2da156ba283005111360695be97576dc880d2e2a32a9e666070666e4f46b14f2a52d7006c94803ddd872b02bb31ca08901c42834d95a79fab04d8c08bb2bbb0348261f8426cc16720fa188458a4224b92dbfa067c3b518cd74a639119555844df56c0cf9023259d97fb326c45067c18adab10a881fbd4354f348139613b8f5e911b969aad197cfbbf4c1e24616b8f0b87e4206e2c46201b99da006a3c8a704ffe6ae36e3a7c07373dca58e1aab2bb6cb62a3ea5a248450df074dee89511e837b66b409061abdca119d00047252668cab621d0ab82518c66d41d951af924cb6b0189f9654a4a7b58359bde2e5ad4ef729e3d35ce95a589b237f03d10604002debb248e80a93957830c2a06d483c9f062c59b7313cfff647a80834809a3f6198658f792ecf9cb679a53ed41519b5b91015005cebe8b343d16928b9480daa3b025c68c8e9cdb7276bd588c8af8296eaba9a6ff44ff257a4542077e70a73a959738a48c007544d7fab9e87d25b04a01d27a8473ce83a6f91b3c8c9cd0493c35aa01fb38613f5d1932ee81e8622ae09f30cf5394e6ecc849fa881a555a1c4a7931e91100b7b26797b643a3a5773648609b5013f565ec161b657c653de89266a34aa6d80b35450bcafda7fbf1c0aacd8647508bba9e9b2ae6675149a9e042b6378c76335857f0bdc2b2a93c2e23b6f89d743415b71371c9e61f4590254508da401b0d8789b66c6abf2bc31a8560f988586301f54d6123dd8a4e7a41e9246ce3cabb721db810ec54ce806be4b203b8ff6574b397f8e933d930c23f6a128f1c17f017c2c2b22bbf52b4741a8c2198b6a2aac6836c09a3dd1115074249e26180c850567c33fa55b9a23fa365cb8c425eb5523dab4243b3cfe3a7fa7e75aad3b206a32a11282774745bc96c566b05562a6696efc789fe8989a6fc218011c4cbf15b960401b4e4937c752aeda715ee0e39225494db1a0acd61c704a62bf903cb6219951fb568934f2bab9595895390eb5dc3ae6e32390a942875826b453b42bd32045c5cd917a01e283812ec0274de627c1061a8208c7ea0a4b5d71004c77419fd080e662051eb2692d7676c5f319f728169db707e4b9c538f9c7f3d823a53199fc9a9f27f8a183d62247529ad152cffae14bb2d33e15dc669df777ec06600723a7da656f7d4463f0694e46649fdfa1446306377541aaa7e3948b83b7b39522e0eccf544859f1459375db295a879f97755b40e514f6a22d90f20f22674cd071a5454275af02c461152f79b8a247f69a56aabd6a4275c9757ef708ba492892473ca461730bc069a5ed103eeeb21ab5d5b96e868f5b64bb5f18174710bed8108742c25f6fa5b598a81c8a509454d8b6b3744a0e85a64ed9c5855c3014853d4836565419adc67b6566968c2d82bc4bdc424737894f48c19f60079df447b82573c2d28ac4bb29c9272580776b43d21474e52e09ac2255b95e3b3c7ff02442dc47000000000000000000000000000000000000000000000000000000a3db11a0e8a06e78944c960e175fd62f4b32871e83ffe837b7f34ff75f9ebe588bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = 2363ea527c82054080a7e6dbfd16d3e96e07463bc44815397c970be5db84d68b72bce2772578c82f916b29fa0ad068e9c383bde469fefce18c63557db19ce93f1c302a9fa6d1d39faf7b4b5774b045f825ef9139cf113b531a12ce15c7c24393092eb886df18e295acfbcad1ad8edb5d20be0a412afa1857e722a20c2740d1a3ba0b101e7ce331933057f0b1cc19161344c87340f2b78510dd754395e6368e222bfd9413df061a3be812022ce2da08bc4de3bf6e657a3a80200e51f82fb098ba9770178dfded93c3772c4aa610648e7b5b330ea921c1547cae8d2a0621afbaeea92f43435bb40020776f529a7754e7f318f9968bb74057f371eb11013daee9cf8128046e492517b16ec8722d993b345fb0d0c7eb615d1e558acbb39f74e08572bd8ea2503a319767899889196a0a42f26e7434e359594a87f0fdd68149028bbe8bd26e3b912e95776884e83dcb3da50659c54c7f49832996faa3de449cb61715b81f75887529c7e8e98f39eaf3af683b5fbb150f7dea6da5867e0aa9b2ab42ba7ba42fcfdcb076690255d5ea8260c7b106738a63e887fc6993ad0bc93d1e6e9ef893981ae0540200ca393ecb5f7b90394dbf15bd33afdfa499199eb2c3ccd93a0e54fc2211b705640e87475c24e5524bfd5a80fa0ce6cf9db8d263cc203e52e6bc5891755331cff855b04c98fae0b416c61a8e38f669619a44b455752ddcc94fe1bb5608ace3029ffdf881e09c49cd7a1e397efd9f47c2c598c624cab914ead90bc50bbfc5c1aaf42362c48d4c2feb42f95057502f30a1a9d9baf49199d05c89db7cff332c24c7cdac1c3317bb884c4ab041580d3c50a68d3444ea0046850473ebc5bccbbac4f94de8dcd7453ee15e001242214cd26548bbbbb0681e4169223a7e0fead1299152476e9eb86f2a84c08d5308c61b9af960374f407e0d49af22d871a7fa048aa386fa83bdcda6bf1fd27996d597802595cb0d85360ad1717b9900b3f6d68ec680693de41eea73607de43668e55491b9e2670deac0ea38fc3218fb4797ec037b5c5075f7a65bb958a8eb551de7c0886f8d5056c1711cdf2c705be5d879d4dd45aeb3d514b09864333b6c8393fb37c4585018c8ed0d952df661c4808baf4ee3b2a93248e0ce1ba65b04d2ba5e520eb2520039f76c637749751e504acc792dde698b04a4b0b9e2f90c98ba8beda3c1a26c6941e509bed0d4b44809e27c982d1373f89a6a5cc60c3e4042f6182fe28d2d1a034f21ba4a007fad040aa2e0762adb6bbb92a218d3d18919714acc77ee1c281de78743337fe9a0d788d9993b91808f7aae1e88193f6fe8422c0876d225d724bbe5b3967f0fb2c2e4e2aa98fff8a8d82be444b840294f51fbe7972dc8b4cdb701b733b465002c1e49fbdede6f4137a2d4d12235f3f9e7726ca176e4229ebf382de8210a68280ad795199ff82740c5ace14acd100cd39c29a28bdc49a8ae8393c832416f52dcae1f3c24c5a9afa613f8d2df09eccfa1194f39d69cebaa778572f42b1d8537c9364cd165f05f +expected_result = pass +expected_shared_secret = e02c8542d46fcd5031c0efe0464fab43d07337181fbc4ab3d58bb7bda0cfd7bc + +comment = Rho leads to non invertable matrix +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba0082600ec863a0a0831fc05c3ce85c3ee9417f6c993412227e7be59aacf03cd9231c2e0aa9020c2d17510574e2a1e89a9905722a13b23d3e8561fe37b034916f0bf61aafa00bdfb1321f798a8b0c61062b9835f389c33b18169a156c11917d8949e9f1c8ca2bc0e3803674436f62798295982b6b3933b09378cb837c5ad440cda657c68c76806b96dfa865e0352bd5290b91a42fc74b1e47033942b07632093b5e717b9b90120ef389b8b2c4c7bb324807251b26c779327f4b776644a55e17e4a67c1a3ac2457636a057cb29329dd0b5d0f3295d128394259649e5b735ab80b3738495a170dc9880be07ad06c2a60cb7a5791295e9c03f4ab96fd287097df52942352cc31c9ff50683ade3c0a4015216b28b0b695b2cb62010aa19dfaac2ad2231dce54aeaf75197db12c291568d5a9a8147280cd956d9d67f7bac1296025801f36eeae79a2f71065f01759f68b30d521333baa96a998dd1946f90380174450692fcbc0e56a31fa238cce178a8b50477831f0b203da58943af694caed2cd3b2a6f58ab3ada92cc5a1860e0f9845f5639a1f555a7d1045d5a07b428b5f2db893dd3a80936759b73642aca1ec7b1535eaa36dd695707b89a9062ca107178673ab34d31cca4944642babd3e79045d4bce48c8b7d46c522291a6e81330f1071258219b4245cd5e381686cab8a9e10120e625516c1299c184066a3bf60a1dc8535398c43a8deb7546000ece3a429003982940bef6870be1585c58423f419a042c30289c80b6f5624458ca8da2713c564282aaba77670c73be5c7bf0e58d1948beea9a97750a06bfe472d721bfa1e54b23a35cd5672b4e84677179579a29723d5003e7a44a8e691cdb015f4ad123d13a8da615a3f52763d334a6a07258ff127e15ab23b0f29e3b4061914b8349056d45f06886051d6ed5a6974bc4d38a7282b837f18082759530c20689f838831a937b7ee74d4ec64b57693c72a778dbf73ebaac041c4b846f78585a81971289bd51a3359035ab12222a3af7bbed6a64a856601af10efd0b23e3d06df7d243b04ca8c07a0e2d0b883c997d74fac67957469189a1ac592b83669f2f638e0976c373fa354045799824bfcf9c45cd408343239ed168b8e25b831d2c200be6303e93103a14549ca30d9f8a0e4b976870801d6bb50d2ef8914371414bfaa56e724582d14879634bea15ac530983a996a31fc9578d88cb242b63057802e7bab2cf2981fc2a9aea2cb173b873e1569a73356cef7476b9fc3a0b18cd978011dcd8b6e0b3c0769069dd94a6f39c940f6a5764d8671208271820c444d1c2ade4043677b1a9d7cc04871981838284c85850d416b7d2825ae95f79bb95f6262bea8a37e240bb02d6ca8fb03ef2d221ee818454222c4d4b998cf586d3434024b304b6ca68b478c773955f2933921e882f15c3ae726547f9a019de89b8335ca3e7f74fadb8ade6c061106c335e85311dd3208724381e28cf3636ba7f784da2718e857467e70a6682e5891473002e176adb848a96b26641e89463b488c616ba0cd4206583804ef8ad9ce3668129157077922bf00999b711af0973ae169ce7f81157d298fe033a7d547cd5b617cfb908a8db40cce2022578006549c05c594a8b13ec66bf000000000000000000000000000000000000000000000000000000ee201edabcebc02a69a6e0bfa467e1541791f802226c10be95df3819959f493ae42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 4cbe8e1ceb4f29a5a28a605625ff03b2ab4a82f81154af1731b0b930c6bb04af7bff3d7c2058c5788b389cd258851b6d3a17b9667d12a8fa61ba7c98b573dbc9cedc3e03a8f53b96214a4e1dd1d38f321d7e3851531246fcc1a2a1f937a101eace805aff3877438dee254bb7bb8b7ef71f2a202d36f532f2bb37f236021662f7eb0473be940f1b63f74276ac8c8fc8e92f805119e240b1df416dbb599a1a6055eef456d7ddc920fdf2277c6b72ed23e3b4b77d604974e7c10290214ed8aa9d592c2f0acee64a5a06ae2d95cca227c23e48abec08b22d9ee7ad35b0fa799b4b5f4cc0effada3f23fbf30a50ebef37ef6f30f6aeba700c6b8d10bf3141dc87e8c118d13bf23c9fcc8aa7473d2748d7dcd88fe5c2311d69ea29c6f5beac3b0d47fb5563b3c57277ec69e6fc2b91342e79b70d976c4359c00e0d08733701690dedd6f93a2fc751fcb020407d9d53ac454fcc8e0204da5e9e5e5f48cd7f3d787a95cb37e01f9bf9ee87e174e4367a0ce9f4aaae125a631d55e13e3cef3e6913f3203b9239a9ab31f297b6aeb5e0044d05fe3f620d3494a95b19bac5c782321651443716ee815ddb9bde2fd4cd0f274feb208dcf50e3a8f68971b69e847e21b948394bae8be37dfd645006a27aae0c4301a0801adf533e5229c6af3d9f9196e38869f68f71ecf720e837062e13ff754c72d101ee202b023c105765db30e5c51c06679b8cd504b83525a3e4a277eae5b2e6d59156cbe11df8792c3563c74076f93357917a1855943db2d68d89dfd53041143014142361d1617aedb76b1d536ba5b3ec8bd008e8d6e709565e02fb4eaca108623468071c9efd3de94d0a380f7b84788c7d17a5ff7b158531cd2fdd72181dd98f2c03aa872cb429e6f2f5474f27f6533d0a24f8a78178f280d9232e3215d89978ed0e0e00cb9b90ae09132bf14d9e0bb23e3f6c1a2d3139d912fe0b2dad2adf2a4a06f392db783167a332db072790324f9fffeafb3efa8547186ff8c198fd47fe91f0c2d513a91cbf36dff2ee65234b9ec53412f44c32d3bd856478507d293761cf61b9f9ab82a1c54d9952124069865b94258d29a2752a3c518f2c8407e022e66577281aa704fe6628282896ce6b7e8d642c7193f6cba50e8ac0b2ef48992649dc8180632a4f9b393b6ec5c0ff2ef5e33d5550c445ae9e60ffdf7adaf9375d3111c9d896d8a4673cb25ec0d05d2c8564137998e43f7dd51f7b7a438d1c09e02e6caf1aeeec2819ee801992b3326d45739263b66d5d7e483c6fc00bcf69b969421844a0042038907be2e853d965f26f3f5d543230cbcfcd7a5f3ddcaea581869cbac5828be28c4bf58c45f539e6681091f9a5699c9cab2f17f0862cf65454513977854339a81aad65fa1a631a4ac1d9275bbf46b11d8b62c9417bb2f5c30502665ebae8784f281cddb3dc0ce1e76d61f8420aee5419242dd5e09949d18d3fa1a81307b51b6b8a30473076e8041f46847b91278ce78bba4e7bdb2b1aecc7d3e3bf6c01e61ff59d9e1e9eb7ff7393d9005dd6 +expected_result = pass +expected_shared_secret = e572300d1bb28e65f38527a8007b312961b7c6cb204572fa0c7f53531c6c98f6 + +comment = Rho leads to non invertable matrix +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697f8111cd446cb2c44753cf29cacd39a7c9cc96af28545c40a6cc64f5974810ae45a97380302375de7c95b44318815776f80397c4608cbc22086e9fc06fed87c6c780ead85a8d5a82f0fc2ac28366f229566cfdcbd0c65ab3c112b70a908a85660547719e8304d513912a215acd011918cba5423e9094ccca3ef073832c3b81863242c864a90f1bd9e6359d9c72dbed85e76a926f6a84cc4a4839e5266aa9020f445ae1062b3751a438fec3dd862a8d7831db1c84fdb9102872b2c55b28e6f00623e2a971eb4982842392c10bc3e786a5ef5be5a69903728196c028a0ae20fa5921773f35c296770c8cc63a48844022a32e6d928ef042e0537876d3b276ad42ee7585b8dd38cfb58492e28488b0488330b935ee8701bf05372abbf4bdb1ab7da67367ccd8df4469c13355992a036d0a0eef51045a9b40ddc04c492c784a945e99c2a8ca52b99734e3116caaf2330ff4195bc2776ff8644d4d510f1d7cea4682b1533b4c567a1f0d052ce387237b92fd14246adf34ab4455f97f579d3e746bd97313ce10e4a331bdc8a1974481289000b39baacf9c757dcc357b2ab4756309849881289d66f7692a084dbc9b92b671ef115b979b26a8873480977ee621faf6b6a506b2fc2570ec44a9d5eda9d46f2437749367eda6af411ab661162ce8809e2c6999cf26ba5a37fcfc009f60b7dd857bfec86a3fe095df844388c31ab44c26b090c4afe58052a80bb39e614eca3c07e7871811b19b45224e7db6cd077aa4dd366b6755623453fd29b42af2732db855e0e829a9b51714f362b083bacc9e68eaa8507b0127b40227b9de014dcbb93b8db567343c1c1807d5f81b64031c364210531008976aa1daa866579aab9a6e1baa049624487cabf044c0e576902373ab2c0ce00f22a0bb61b38f98f4bbb5bb4018f6ff8a815d4338447bd133a610ebb10365276b2d0a473281c64e8c3677741a1a0c360a8797a3a4dfa06ca5bf50658600de1175822e27f187b6cf7198b8427750246b8db6653e448a16b21ab2e343ed4d55287341155a7b1b9d92cfadc26e138c3e784c03bcb6e36a1acd0e0ae04d78cef528b9636ab4fbbbdec0b7ec5e3c94c808f90646b7f833867b654fd9415d4b971e67920432103d00928f0f3af9274bbac2c5a7bd7cb27d2b1318b840b899257065026a576931735600698e2d49b136c641e080e034544325780fd683ded1caa11052fd89b5d18869f8a8024d4657e4870ced241974d2c8f6194886b509bacd5ad2ecb8cb2850bf55200d2226602a640e8812eb26a4cc0a960979ccdadc5b31d98cc59283df09a6c2d5b7f6ab703a6305709d10cd968826c6a019a264210c699030804db419c5ba4460b25510cb43e16e36eba7b74449612eb73662c79ba481816598045f601be5da995f02229d5d130f6688a57585c959c69cab00e462512e6129afc9bbc5845c9714a3cf14a1061b46139c79e02849b6114b80a75828cc946a5f00096a4a43d065ddd5897f3756d0bd208b4f8685d2a165442c132a74f78da6370422d0b01b812c009da680ae91ca0fc56bdfa36a32a6308c8eb32ccd23ed3eac3c9a029186a73c8d63e8fc92a5dd42905198405c76a2ad92f9a21a2b62b11e8831b4062425c62000000000000000000000000000000000000000000000000000000c7251fbc2a67f5f93c6cc8351988b94fa564f61234b66064e5b41eaada415781c975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = fa75f5533fef3b994435bcbd3d2080030cf8b04d5773762f1ca6fbce54d86af4ec2f36fac7b3f249f4bc11cb376b23e70a7ebd39da39d9377ee63a7c02105ff9538d6752482378b4140266f13faf8c7ee695dad10b590b40ed5627ac417e8399dd398cd7413587f7d5c530801c6c3d7a33838cd42ab4d4d47d263f4e1366c539319faa0bbe179e069a4880f928f7f5107298b1bc2bf75e6f9d135cd9c96e8fd1483e3f9211bb73fbb5623b9ce1154cbe01797b4d69b9940c20d4fc5b1d1e103a9fde78aa11310e9ec3cf57bc2f41e3296c42991e03b19938e2c57efe6579c192b66077b4da4a7bffb383d23d7315ee81794f2c4f74c4349904190a73eeb1eebe03ea314f708f9f103b2862f8a4a05aa8aaef91818e6deba42b60a9957e5261e01f7c68efca04eb61fa7ff86996b69a2d7e293a6407004bebe90bb481daf560e446338ed6ba259e1d0910ceed2afc7dbb520629e8cd92f1759803bf0a598ae25254f054c4551009f9f331d24c9e443b3942ce662b28c5dd5a6f082ed5aa2725ac7a9e3abc6e57d9d8603052015944ee9d6d55198a5fa9d9fd953ab5afb63eed2e0e6d01983a8e2dc19708c404ce6a7092f2761b8dfad19e0d4dc657827756a99932c88643c6e3adb0d272b9cd877079754fcc2e60c5f222d7c751914621873edd16289370e246bf6e63ca7442b54f7d6198c99deb20e635367fb3c187063713d4a6059ce5623fd8203a73b62c2476605107a64efa177e435b5c7bf6b7c36627e1192a00d6d376612bef6560acfc270257ea0b561af6c2e4738207d60197dc1126c89ad7416e45af6022b227f9e1c4beedd248c8fff802675e21b15f06c3aec36400515c4bb9f4ad2e878ba4eba2658c66f4f38cdb2c73e71de1796290133857e90965bd334628eb83ac769cf63fa9a59298d089302cec86c2d10aa03c6d620a1e735176665435479ccae37a168a0827d7f4d8070d98065ad0bcde435c9e9e9d75e71ad0e40d061a2dbb2a3262e18704649a14310e545e8ce93be3b33fc442d437acaa3b5bda4f770f5eb60f56b0fbd0e9a4820f3c464cb900be522928d9a3a29573b07884e19da158b317fcdf047a2307d0066f16a3a4e389f0166650937ff1df8c4e637e24e2d50f4d2b731e7befab3b0c33ab81b4b031174a61be15d992315464f99d292696bb1536ddab0195a140beb68e72eddca6220d01d4fbc77ef3d743ac1dbe06450614d9255f13e60417624dde40a25515f19b52750c1fabcd7f128b472d80337c469cb8ff95bbd2875ed03efe8df9aeb677146002c138edb668a22c1e1b671cdf636a725de9bfa9c0e12035939c8136b8da4792eda4e82f29d33bf3f67954863eb993e51344ffc4d144d651219de292bef3f3763e2aa061264b11016b6bd4586f46215eee237b8b616a260071004e253c7e1424d01c4b71bf53e085f93c6917a028e6f5134e2c04bc8d9a371083180c3d95a709bf56f79dae2be4b1df4db2fa14b075ca14d0cc7875fee90f8ad2ef73fd4bbfa3422475bd9a7b8195 +expected_result = pass +expected_shared_secret = 0749d8808bf77c517e622f26abcf23f7c40144b37bab16c6605ef1c97636689c + +comment = Rho leads to non invertable matrix +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe3317a86b5b613c6c4c869dd552a711040a0a205a6a9b7ee5c7607825a76206b3db25aa6a0960da259ec279960a5a947106b51a299792707447856085a12397e60cbf91713a6c4bc56b03531081b0b38b0866718c53bea1220f3e5c3a59c74f10c765148c595becb9aaf0ccf2e429575889b462bd59678f860a5e501aa758674d22842cf65a3f8dbbaa7da061c54073a92cbed742163df301e3675c5ad96b26b12651fc9507b7361a8bc0cdc47e7f38c1ad80456ac3443bab147e86924ec112adfc9f1c1b81b478740b752d030537c817a727451668d9ba1fe092d5e116c20262b722b6f895b78e3622c00596ac8b5d4ec11b0413635e85637ecb9a87516cb8c46ef2aaa6fdab62860160c4b29e23f921ed3a381711540cfa5df115a700d40c38b99efb870c6ed14f2261b17ac21900a427528cbff423b0ecf29c2a901baa9c7ae3d438c145385c73b0961c4e9dd5cb48c2ba247a30b9691dd8fac963a5c46ea44de03274896c8f36e57f84dba494c473af0a64d97533b223a32f8078d933bc6db125c2e7a779e0676e09648cf6b85c2968b71146763b7082ca2fec33884d6704afa71f5723617f83737cebae33b95be2393cf1f104c093b4caf26548704490b4aff5d6175ee4c7a3c0718436bf996003039aaaeeb18e92e341938b7a71609082b18995aa042e628f18e8c6f67b67770597772259e0e7b1025c29ea809beb994483a6863d038f6b9bb814a5215d299ad0b0b577d70e7c946be6c93ee257c68b1653ded84761b3a6104814a265988bea5a6ae96951f1bef6f53f50aa78c1f655dec149706ccc561a846d9cac61a339c3c279a290829f972a1931ab5ddc4893f71127d1a96796a24152a5d56016bb5c9d483b9b4346a8550784a828a3b53573e61104b6392d0bb246b8116d8f78021bd012c322c8b0d8392677afb40b36e49c0211449a2bd841e44b72b25b11cd099bf4ca292af2722dd9ca2ad3c36f4377ee54986b737a6a0b87817384ae9964244b140689b2d2db0deaccbe9f63b182164b89c932bdb22e6127303044b91eb76572e19785747e6da01c20318bc8092a7dea7ecfcb638e0584a6e00ccf243e06c577b784704c3b448e22a2b2c9c1dc0224c7ca798567b1c5f3a7ba660af4028387f2c573a52a28a3449c26342f214923e3932f3bbac2819329b83a2e89b78d93afc3c134be3c5fb8c67617666c22c71c4cb99063898f65b41117893785f376d2330b3b5a2fa946374f8a1a2eca1645d255c2a28fc8d7734fa10c67979e5950a1b5e085e2d52763326f3dea8b783297d509333947b9a47a9ce9caa0fff56637a54ffa6a00ed942e0d382ac6c834a7e40859f58d3ae991a9e359e91530bdb75c5568330236149e71040dd9219f5c24cf35c4e6a670e0719b2e738969f509cc55bfb6ca08c68c28165bbc43598ebd9744a18820b5947f0b41a311846588187c0aa669843bc6f4620cd1c62f1aaa90f93b7537828b42f59c153b9ebcc9ae1168b2ee7b2f10c062bdd49259024f4fd51c8994acd60478cd3a00593c403a3279877801d3c88f65b7bd83b76fb54c49bdc8af3cb4b2717741bce1bad123cd062211e74782f4620e9130a9950423afdc98cf0519a643a265e4c6ba4142557d000000000000000000000000000000000000000000000000000000d79f3c29a80eb53b13433a57b98af3c8beae20850d72d14a2e8fc6758d059111d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 0d6a627804b6e54c49e39e098b20c978cfdda91acd2d5d883111b0fe855460e981f041682f419dee54cf5b7f923c2017b1012f0b3233d507ed065e96ba51f92f70a38aff0ce071110bb0513b22262aac6ffc1287c63c07f312ca2310293a56e85e429bcf3b8662426c086f388312513825888762fb3aa87a40653de37f48870ae16c19ec088bba8911e944b41a8cd595e2fbb680971981b5352a9032b28fd3bdd63ea4a72b5d999d6fad88e19aa84e5d60f173283f7597b682f4616bcf532ae1cd5e9e5e231c6bcb1c9d5fd0e50d54c53ec8a4f1162696aa72c02a6fc97e80686886b84899a7ad7a1ff6468031dc403dfabdcd793bc31a3036d5937f5af337f806001f4ee79dd889e72f5585636205a3a906c01588150d73571ffaffb9775970af6c98a17f1a6a6a0161de795ee20fdfae34fe40e4423012dcb1cb918144225716dc32c6d9d453a148f3a5999b6df6748a97429ab5b8c6007f2595b47fb52030ffaf99735f22657fa8e93f31238941436b76088a72dc6a133f96f0461eab8ad3361f59d4539090c2dd4b05ef665786de899af3582a8a41400b0421c6c646050171f6c2c8231e7fd295f855d2236f6b17f36cd998b47542ad2a73c1751883175a71ad2695b7b372b71ac8cbc2729ab1f4b76eeb8187777404ff81e46aa3a246cb0c9dd3b7fcc443f6a89df493b64e770aa8507253aebc041587b3b9e365688138518d2e84b635c045c9f7e50e62fedc9a42344bece5e21e05c52baee9da1e5fd50ed674aa83845343894439da9188a149b04d7110900fd3a6bd950be022cdf91e6bc896125a10e64ca3e55785aa5ee668e42f338abf50690c61cf19481b1162cfac86b4f8b8800e3c65e82e94e987e37986a3669e401f199021a98294018a602801c07b51faa641a34183ae5a101189887189f072943a712f74b3710a98ec0a992ae4ad1d4d56a508ea3d0762d1b004f399261f2fd836b97740f4d96e3a939ec8854b711ee358425943d218f92a7e07799215ea2e4e097448f7d75e79850560fff7695c4b3f1266f60c430b602db4cd75983e3e252c541f5d39cd15253441f76534cfa94017f1801797503b9d1518fe4857a27e79c842cd3909eca55ec46d9652ff448ae113134c7d24a506987875e9aa17841c9453ff951aee63372957333e8af8ad72ca7e8bff5e0372209fd0bf11881475d0900c643b42b911ed8da750f4d0afa53d13c749bedd5c69a006dfe44a736a44232de96075b6db454644ed3403bde16116a670d7e6c60e03e25a72711ba7b17e5b65bb8af376eb71df16f7d48af1a903bb6eeb599d8acd74d7990053b39d4c81887411927689e20b51006a582fa0c0416299c850e75a81fea3f4dd3d3985087fa7b5f163827c89c2737a86bbdfebc4240c166acd4fefdda881f76be78a079295033b10b5e2bbd9590e3354d86c2532e43b9d1ad7c66766d2faf2877eb0ad087fe52fa1ea1a0d5661872735badad7ee15754168059d5f527c6b188e6dcee930e09718f6551da8475df376ece9e890 +expected_result = pass +expected_shared_secret = 951e3d8eecad130865f9f89c27c36ea8d091b6f3c00e35969f92bfc4f91d657f + +comment = Rho leads to non invertable matrix +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960f486c7d6766d95f2b7296a07c8c7b767c1057548a18263a4366040c003c50084bddd31af425b261083ccaac26948ba1882739732bcc1e73685b52287148526bdfc47d8822d1d5853c9447b21f200592937b9229b471646beca2cca630502e167b7c861d03cbe302600c6e1806f6040cbe518e15c0eec4395ec1a47c44c8456830709a3be9d05cc5cb3266f616f9f8a7adf9b2a04bb623f801da0c8c0cb4b45c16282c412c24ab90c7471b554057b6c0623481a46a0aa53dc167c15ea8a723c81d9d56691b060bf00554548c34f1c603b17b705a72b2c3091ac134d192806635385a5ec9cd28a3bb56b83cd2b153e00b66eb58d8580a47e696aba9abd36b19b3cd47a0dc4ca2d6b7ef106a3b94b349c665b295433f4ab8711a01e2de8295d58b20eb2ca49c23d595c96c874a2749087dafc044c0b8bd5b340ffd12fec07640099753d4c993fc69d986210dbeb95bab40f6ca0096ea866ef216c6b2657600813052886452c130e7c925940564918a5266531af820d0e69c10471ab3b74585f2cbaa1b27274589fea64b2172b4020b4619b6953a9d56d022c7bf937650ee5608b15988b3377bbb617c4016c1ea3a7afcb9665d995eebc2b0ce76c38a0b6bdf9436ad78bb97852ffe8a618f3c82dc4afd81c99a9512777094b12564ce1a469cb49045a90aa3d2c20fdabbc5bb4940d30360f17a66d58b7a3ba7920c102ccf8b30f03621ef722776b2fba0164b3426d514104a6689286649862b7cbd84011008ba69c6148201b576a7b4b58a53035946a0af9646251b8c1cc7bc4c058ed8bbc53c91ef74cc06e1c32a211ac42570b7a7181f23552c762118a9c0f4862687a502c232b9d43224f5fab525f6186332969b246082c44cae7236e38865e4dbbcba87c12e90b2b970097c0e307dda00d7cb98574915a03d25384d4584611c837e19ca906a80868b382940d909091527b0bf261be5ac0a9ea151b8979ae46f2453b420d5b6b1fe02605fb8bba1e065bb9506e1be7c471a9b8083734a110aa6aeb8340338b14aa71189cca4ff01777e7a251b7a0cd1cba9a9a7b9ff3953fd9c87f5b043f719f692a9f4c7352a0756393e50f0592cac59bc21e198729f23b4500d0e620bd02222a88c5688ac02809315cce210db4169fdd1312c0dc85baa25f3d48ceab80754987553fcc7806827441b590cf9a8d5c590b2e00bdbc9b4ac3d2883f6cbf9e047407858b99ab6577a66b498b0f18628d16a389a5f5a20e1b0ffc228eef287a36968ed913b8fd74a34de23ede7743da2311fd10c46eeb84c38986bca7536ae8a3a42acbe5dcb3fe9432bdab1f3d1226a99148d01219f3e68f68d7a689e39d7502b6e13b665cf0235af1489bf4ce8619624eb4509c7639ec411fa223793b4cbbc990256b390fe23a2624977477428ec39835809343023c1dfefba3aef98e7aa15ae694861ad54e0c74a6d8122ab181c9d23397902c99b0dbaf78a463682294a2eacc1cd36c8fc1ad2e282a72fba0bc179520ba2b410acc977b9f2cdba3213175204568dc249571c20fee0874fec364eaf210ad31b6018c2d841269bdc95ce753cf6a765af4bb9deba17253985277f71d2563a585a7573d31c87b80913c0a38d3905a41de6fdc4700000000000000000000000000000000000000000000000000000097e7e324c2d12c3d0bdbda0ba8582b04e2ebf47f5ecee9b9173053949f6ede27a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 068bcf0833a0a08f1a1c9128e6575a62ed3f2e075c4444f2b4584b18e4af26b4e84f16b697141c2b000847dc2916b8718608465198935e67d873335d065b994e2946244d3d739b1d31ee6b8d54c5bb04fc9d7d6d22496a869e5331d5e293a712408207fabc35004b13d3ee3aca54200182249642c5e9de88bf5a489cdfe6330170c0b2cbae18f65043ee306db39d333344c37fa76ab05675568a5dc576290abac1d6f28f6ee1d800a3c638b91cd40cb02e531c88c0a3328a176f872386082f07b4a782f79d0b2cb2df14a62e3db5a30fc753f25db235588652c51b251685ffc1090ffff37671384482d4ad055f0d51a5f00c1c14e67824a29ff8910d9e9295f633b6e8dccaebb2da47cb628a246c6a443b87981453e4ec64e7d0df499f026977b039f73d5edb354bdb536896f35a5431ffed50861551f5e6114da8782d3e1530858e516fb623dc3c0bea0c8981bd3091af72555ea18ba409bfe2419a60d769999d82f7bf588be754496143ef980a3995daa51e370984e212f41681fcf6f1235871389fd3b52e76537b84af594f5405fdfab1d90c79a302c142f88affab1f4d524a139ca894cad46f270270f2d8024d06582492fd1502a65e7b70ba0941dd957808206ce00c6be60d8fedeaaa0149f17ff0b3b775fe59317e769024c91ec83a191cd72481e3d90361a4dbf59968a33a56ecde8aa618a8046e0c021c6954f983b489bba80d15decb9955e118899d98c1df865355f5b9ffd97c52c097474704088cd2dcc01f303ec675d87938d21cacba1fed2483e144bd6bdfaf5a9a233238313489e1aadb82a060390adbbedc55050ff86f967b4b7aefa563117556c4ca5ce9ec3db571b5d2c9f5fef63e731c86b0ef3d84239641fb082063ee3c3756006b306754124f9b964dfffe718c72b93999255fdb3c4eea7907a8bfb5936801e799d499269226df5d9d3232b5bd5dba5c2ad9b03826b961535044dba6640b7da63a9f639a834f7311e7d9ec4a1591d041de4f080416acce59b2f1fa4f4a7654368761bf1025a2de5f02cfbc2150685f3e457aea26ba25ad3b828f9dc07d33a55450a0f0c6fc3898dfdd7a43488ff012cca26828e5a1dc5a0d605c59afcca1cb0c76b3c20524eecca2ba2afc939204bf06adf3a5c0a809641cd83bc1c5991c9d16696a4e4e6462ede7953d2694ec9ce865523b1faa9ec4b8d5f737ab31bd929c45ad6292a6926e1c62c7d48cbdc6c6e30f289a539feeaf84cdaf23330c37c97de3ba6dae06b737e2a51faaf0363a961cec9aadb8c74779e242572fece99801eeacb7e972931da610b75a3ab2f7803b8f3b9460f1ad39385e9bd1fde1b46b676132f5590c6cefad5450de5c52087f7f5dc79ae1ea8491dfb8b2d205361eecd231f3af8d95a12da4ece84d6985325f4d948eccfd42fca19014e7af568175879101da556d615b3f4d81e0a4878bb32ae24eb4fa91334b214b379f6deeeeca45a89ac0d16d533707ea5e4b5e0c06be84656e5475c4257eeaa3353d4444cb88e499ce7f5a2cb2 +expected_result = pass +expected_shared_secret = 5a7f85e2ae8e79a1b178cfb5f38cdf9e240b9997584fe9c432fd63607139f08e + +comment = Rho leads to non invertable matrix +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa396029b98bddb329742ad26390f48a7c0f624c336e5b71727a4cc29c06e1a2968d864e131b79e5365dce048453ca51bd8718427a35c63ab784ac5476627ced945b656adc438a5294800b6b62f62320adf193b198998a845954a2488e0ca4154a442b0012d44b7b24fa5a6f03a8efb739ccac77b8b54cd235ac65773223f3709d0cb8195671f9ed7b324a11d920332d41c9ae0c0c30279721c80c3a2423cddac9311cbb39f7512d8859074558942504d9c087d9524bb21f5cad2826688e5bb86b91c1f120da1808a654348fd3ba11f3b20bc7612950c392dc27cf6a4aea8f47b841645d4860cba4b3a865c46c0f259af1a60c43141f548308088353617bf95427fa094389a3a6d2df6ccafc7384efa1cb0ba2ae5a2a8d89335d1eca833ea026f9a08c9e2586239aff1845fc5fb6472d0056770a0cae059d81812b8c679c502b3527ab21c9b142f89bc4092cca0a6c20bd1a22c29b773b2aca72ab0a9922d85a8bd676267e9d6452235c270698c5a7a13a1640e5d20c1abc844493ca3634c1ca0813e7f73532388c1e059c414c24bfef16654850f9673afecf630fff9c3aa0a56fab46eb5cb436f4ba94f046e5d57a2d1897680631128c42dca353861a7aceb79267a48b429539f51475414c66bc66a1e8155435df18ccc2993d5e93642354921e9b2205a6270e34b4622c9c69915ba80c9ff994263a11c46a95b8f5c43de1c5221b0745fd2ac0ad5696e5323935a688c906aa2050f89881d3d21605c9564997b66c6452e333cc33ca839db53c17192796e9213b0d7a2ed796e7b2842d9aac2398c3ad11abb5cd342eaa2c6468b70130a5b8b2aadfdf08a2c39732708842ec03d62f60c59b28b81f726f078a06df43faeac927d8c52d14664bde5200bb55cfb06478ffa9b62db67f07565a5673393a388ddca18b7d7978f338d93f37d24a38ef8786e3ed14109421e5884c18da611cb7b62d745323611ade1527fd841a4f3e7122bec4c81609be78b1e1aa274b06193a9291bfcd88ad0fcb90c69c2d4b4073f89a733729d3adc79ad93138b8116fc05b07d7ac6d1645e3a7ca15569b1fe923115133892279f2da7be3f96a3a4417d3b929fb4d842ac017368bb461dd4673da34583f71dd89963718a487db15dba89b26f57b5843804f4f77467936157a504bf106fffe93b82a5be0396161be988c415666b1a26823755274310b8c07d2db27b4e0a7f62747b37527b4b3c87c758603adc3b240a359639634480834de99a6efb12cee23625d563cf969adafba20feb785ba71a5278cbe18a112c673e3332575fe982c6fc853ba675a610357dd2275aa0c6ebf3b5a66a38d253b13b8a21170647c28a7397498d9473c463b7b4762939af5a8dac0066e9f14b8e7534c21342d4c7cf4b539d766a350d882b70c29bcde61f854aa75d427a84780220278716eb8ee1698fd5825cf206a0797552e2f18d3ad062d283719dd61d160681d685ac3004c0c9802d78ba41e8404436d8563de6174e911ebb16a4ffe945034932f335467b250bd95b1d80966aceba882f2858e2011f9be167e6e3c70b234da466a28f8140c9581a9755b5216882f0d43bb70751ffa702eebc7dbf12450cfa3b542777c35b96077cc1cc2c5fa7ab00000000000000000000000000000000000000000000000000000054a21826b02592023db2703799411b54bb21a140a3cb4772b53669afbee98aba53f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 9d12c628e857d6fd5a1932a879dcd28bff777cd6132e14fa17480771b09c7f325a9127f610aae2bacacf515132f848a943bd40e75b894d37b55018284ddc5899431636325a5e86a79222196fee72545b368cc998059b0d88587ccef6e6eb833d05e08123f9b18c13ce6d456f4995340e17a26a9c3eb97930dd207d5155fca9a160e5e8c3f8b7259637721391d9f0787a34af39b136f306400b4805befbbeac25eeb533678b6994fe71ff8691c85bb2cfaea77efbd0299415a4adbf6cff3f4e63cced78154525b5b3d21cc838a5c89f42a1f7c2e2847c8cdca0351c47c1a6fd3e0b20d2d24989b931e1bf6f9e3d015a1fd3deb195a959a44f87b168976b71ec5096a92c0708d96ce00930abd77f4dd101c64106671656f668a07934c89353ce8b27e76007c7d7aa159939210295ad05377625b6dff8744332b834382df6ea2254d523f415928831a46077488f925dea5bbbe4ce007852ea26353de810a78d79be4da1fa41546739b74ae5153d692b14693ede93e2e5248a9244a35a7b64acf95290d1547d6e4e1d63c653a0e52c83264d7349d209147c97c9971957336f036c7195aab3e80afb7189542c45194024e349ab7f62c9cb2983e238a8c76f4c5ad6dd07516d29fec6f38579abcabd1c04005c4106b22c45d27b7786575b15ba00be22d752d6dc7e689aeb21ba9980c63476e742b1f780e6f9e220ab09a5952126ab01a59277a52ba8159d3f25dac39df888ba0e920cea9cf8d40525f79f74766f62bfa2478afaee5240f30a106fde661789d15780bdfe17e15cc033e179735f1de3aa82089dbfcc9df71253bcbc99cec3c5cf163abdba2b8a37e8321666ebf0639e9b240a3fd1cdffd249b8e0f04228ba21b777b8cc76c1942656ae9ff36410564a9d776b82f1e61728e71fd88c1077fa74d08bc2d5cf59b82163e122bceb5b05f6bc493ee02b111af667fa67bd0f7464d8738d6e1b47b282e83f3d83b1ed5c32e1534407c6976e280fafca2dc950597dea6efc162139cfd2bdb5379ddaf6c2d2ce876801bf5dc8ace9bb766be0452105861e99534f84512ecb98ddaa2bd2938e371385deb1623a13900eb624f734cad7047790251bffe4af673e7caa5595138b8dcf15bbea0acfb745cf84e98053ed593fc1103e80fc4ccbdea7cd3049c43dc46a21d68bf194a101767570d6ecf7ce087dd34a526673b6b959a9dd83e809ffe8984d5d86fa9c23c0a47ef11359283ebae3a1c5e6cd9f61a73a2a875d0d8fa1a801d31826ffbe79179c9b32f1ecae0097350b44918242aadc9ecab9bbd1e889a113d9cf1454163317684e0a99318d66f6435e373eec3ad87789afb0f7dae49d2b03610b5db9788e2b3e0c96474baee4bfc166d3f5580c7654ed4b19c325503898b38eb24aa30e4496eceea05954780dd389939b87a4eaefaf86ce855d1d1708660add4c70d30f7d14262aec22a294987b2b850390b799c67ed354bedbb86bb8c1a69e38313d4d52ed2619b3c482f2e16153263b3e6b7863d8cff75fbe549ec30da553 +expected_result = pass +expected_shared_secret = 5e36034b55f986e8e39485c2de5de7f5bc816322c6f36ce00b8ef8d7513edecc + +comment = Rho leads to non invertable matrix +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d7493c30b1c077bcd1dd852cdb9736289bb441013f7132a86664c31990bf601cffb845d39a9a95f4b44e285c537cca542335e77b8ca7ac4037c56822d524f74b76f2a113693a63400334967f9a29008ad53f01921499e54e8c315b47788aacdaae2269957010f4652c48a19cea9b2a32406b4ab4128e150beb10e0811b2aed3c95c89639a0ba3ecb689a911acc463708b733d3b724c63b100f62c1863c2771cf7c6aa215e5848687546446c75a1b3d56d8f07b3a8f8bf79dcc360010fc833056d04a80132816a63122c591cae5a4c26ec119a7cccf7f74db33c8a83c379f8f3cc75e85a8016529157aeaeab503e7b9734c8801c309ac580b792433f46451c8bcc0fab6a9ce7b0a2110a933d62cc55f953a036b3bcd3a9078c01b16bb6f78c9f14aac2949617bd6c0a99f003ed2bca0a3690ad444d314a1c44f1638db6c31a3884823a92a28aa3eb498452895733d97aba3c3c7d26139843adea69b3730451fe75aa74f6a1dc87988012318cb172b37843bf1385bb400018416344a4c61ed9436e142d9a512d63693c46f47e2581a97349bbe6f463e5ec806f2bbe56025932eaae009591ec6260c83202b4574f6274414e998d2999371d39855d7b52544558a0da3456191950f96f0995313bd06ac4371207f606781870244b3994ac91a0030b9b26072e121322c7b3a7723527340606c9657007b70700739b278da9a14759024537aabff70bbad9bc513e5809677bb170d8886b2176b9999fcfd5c5e260475d315445d9a6a53b8c7e5919fbb6209d2112074243c16c783fdc571dc842eae4379378827721030cf601b92a5f06aa877b8070e0b3a44762786645cca13c8e5c84a5010290459a3637d7c240cb8b1cf0c58a649c1b33cbd0c62636707d321cc93960a42807a8a4fa9f7c889a4c6ba672b14206926849257bead619167c8cc7c466186821bbb8c67618c6c0d9064e71519902280534623bac0af20259304a46b0352f0b62707d7645b1ba5817e41079893b1ac00fb14480bce6bc19b337a05cc79e96ca15dc7686b33e2e85146224b96266c8164b4f17ba6c3070960ce26630fc454cb25b51e935c507afed34b029838822a0a77a24bf45e9b9047627dfec040e648738e05a62fbc972e4c1b4218300221ce3dbb3db904e82bab6f207743422b453f728084501ae7b96c26534913568edb18446c409613b3ee4f52af5b466c9ea7af349bdc5eccfe9a510f6fc24226687a9e19f6a925b8653209fe4a932588cd52bc41e48404e369394385d87a5b28b80b971836e3c8929547a6e002d5f26dc4417f0850c44ca3905708aa40556b426b6700d4e9126b8ac7081d291fd7569f0b08f789b8556864483ab668fb781db2837e73c20891928e1eb3d29f7a9a294641696a1fac1c4bd526e1fc73c78c01ceacc4a5b707262307f8aa28f61642d71d4aefd205a5bd414150188fd679636ba5fdb21740fe3738c5bca69ba72d1f0871244b0fd430605253499d351fc102280987956e287bfe40daa05a6d6179ddc75aebe5076f18a676ee71658283752ba79a2457fbb107c1f7b7540513df0119b40fa2342b64b2aeaa21c94905a5c68f222c84ea63e9c0b0afc55bc605a46a8179edcf8882ac203302879a33b000000000000000000000000000000000000000000000000000000b35abc5ac256d7f72e6a83cdf27e19e97e40639a6832eb08f3e534e831c385cbe366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = bb7e0dca6eca3ef57e945d921c2f80875556f7786d6bcca1312f86b3bea6d0f0a73f7d6036a7c38c62d4e356961ec6a28d8026a2d915d9721ef815147fc09ca65a3394aa5dc14c08d41cbe932337b9a531ddf68df20b6aea297194ac398f15919830e3ee6c20145c0aae7a2cd276ccad7b5c414212f0c0ae7106333868938a6a00da19377d996c7796d400606007dff30fe554a5fef86944d43ba047a00da5c2c2a1aad053aeafcc75a1e826a417b4c320e60a68e63dd7b54827f5b8b0063a00043f29ce8975d95bd418eb2ed29db0d9263c67fdcc153ba9b5a33279becb7ab193c2f257bd660fd7012712be3fdc2e52490ade145e8e030ba1ee5368791e6f3efe00deb34cb454cbf7fdae3a507261d9fce66ab58998ca19380187e3455d425977a8396cee3442935e24347aed45fba9b323a289f1b98691e35017ecfd7a423cd8d0149432a2063e0786c2f912e1134ebed188511c905a1a9890cd55d496e8441ccf637b4d660d93c7a46c3e17219167c3b4740878ae35766470b5eff3c6b1fc8c30e5c9645a94ebd48d2d40fbd4baf9d822deb26c089da84043340a564e6c311bca18c7a2c868831fbb866d89652556b53297b9c0040e98a692fa536af4c9a7aa09321ca27068ca66c665b1121ee4529cb3e6d899964de759ab915b0d2c571c5aa76cd64df4a4e55d9de59eca7b4379b30f8559db41e804a18b8771f594b9bee3de9ae98a003430aac58c141e6f0b7b1e5e08e27d1127b682882be055ba31e280dbace7878ae60426626ea4c5bc034a9206e27f578edd17fa6c33180b649bc7bd437b2c86ef4e0f4583071f99090b95db1e415d21ddd88a910b1fd10e3a04e391d947558a6619683ae070be04cab88300614839503f088e2f04cc4a7d091af9833a4f957cfdc574b1c994673ea14dce6ad89adebf5130d266c1440b3f544eea380ba245e21651f1f2aeb2b3d578000a87683dec69ccac18b0702d3d030077981076766e7e5f3ae1174eaf21bf03662c6bda5fd209da19ff6792c0bbc5d210851061dcdd2e4794d2c3c0c531e92a2c4a23556878d3e890b65289a6a02530bbd40ed66db3bb220aeb71fcc3c0b5d5b3afc71377746b22ce636dba028bc052c219783d468fac1d4eed555c1b4676705c8d27aa8a09c6fd8640a6f7b6790ff173ac39b5f3c709281df4274cccdc1e3b690ac0a77f7ece34cdf3216d2b6058baf5f649ff5036360dff99334ff06a366785c0404c584f623801190082fe5cdf88f9cf41032681e8fd6b84d127add01d4b2286af648b83fe69aa8d109c9320bd40621cf75adff8603e3da00be36f03ed7925f19b2e913d756e952a9402cd4fbffc0428cd7eebdd7fc7d3b4cde181b16b26811cd53d9f5d85d37c1670b957d4b3d04fd06567ac68d3f9dbdd45d182619180cf9292e86f42bcc213e94900e0c759e051bc0e30ffbdb91a2493913dc8b81ba4c3e8ba0e7277dc38dc91eb2b27823dac71b6f1c47e2a04136e2c0474fe070e2e4bf8e6fc98e73143ead3c5f778ce8a4efde4 +expected_result = pass +expected_shared_secret = 5b357f714a293b6724c0dc2e2c5509676782a9dddb050d88e6efa0a6d09d20b7 + +comment = Rho leads to a matrix with unusally large entries +private_key = 00208080e8b3938b09aab715a0b7a09314c3d2aa03e900528a209c655886bf0180a0775a1ee133e543c17d7c24407131f0b813a9287c5c9939d43ba2c1f064015c1babc910d1024bfb46a3fbb1ae13dc5d8bb4576787a592495786a53d4c172cbd3b2cac6a2f5ab68fcfeb2a67a997d809800615c043e4bcc0985de9d671e6e0c8b071a20264c457c13b1f4734f234142e86c23170821d068210b29358694d8ff27e89c59264a315b6591d97d90ede633b68fbc36ca96b823a4bc66144b541cc118b0d60a66c89124d9080ae30f44b9f4793cfac65ab8b8cd65ac81cd95de566ca2c19906a955a04047052a699e8a132e2e48aab916278c49ccd1ca0076b5254784a23f7a8c164229bdb9b46e1c7bd4c74639053cad5226c598918687fbc50323f086238366c4ad9172346626b54ce142053de67ce8867cf599587d0a47aff0a7fc113140c18c40bb31e2340822cac294aeb3a02652b424ac9f1008a592ccf70170246e689edeab03dc0249ba59fcc6477fb668038443bf9a743255310df11b4c90a97bd212a74d5142bc6461a135ce7376995372a1bf919e3db20f22c683f488395a95e31ab13aa707c59f22e85d892830bb550395633f6c87df28401865106b5cffb75729391767522ac236072250c6f4dda196a90bbdfa183113c5fe2e31ba1187b4f682399f3c6c0288977904ab445c0c1b9caca030aa639b35029657c1608e3a654cbc39f8f096414d278059a6f56c8c838b1879b00ceff668190213eb15184a57706bd8c9111667f52a656d161bcb5e7cb8ef5beb6756371ba4297397eb6d0c850aac1e01025001b71a874a25e3ac16450228dc33691b3112de319f69ac29f2a1cdf02a0cd77319931003910331a6268f42669f4a90e79bb820e5c98aa252dcbd056318a050ab71f5d60028fc41594688cea4a95b32529c39c582ae828016644faf4b7b1fa6fd9c305807c43dbba54d44273669bcf956c197ea3462a30be3aabb1a6654dc4a72bbae53982ebb986e249d9438d66b65fa15b723267ce1fc1200bc26656d7c4e1839e02927a96304460a34a9c0a22ccf15c7390afed4a612ef236f9d00c22d04cc1dc362c08afd0a16536985f69f6a15d6585c410ac7a39599c683b9e67a33ee299a5000c7e4acde611bd6c817b1aeb1373835a245b916620be6ce8093f88635cfb619a963c99785cc5c354e5d025f954071e380876408fc5ac7fbbeb4c532b1f1be67ebfacac4cf907be9485c6da8da380809ee102af0c98beebb088c13d29830e7fca4dab8c1e8cc87a3b4198c50686c82626c41414d50878f403c10ac905f39a901405b93366a575338ed7d66c0a27c9dbc4af2d217688dc3909db8878000af307a989234174363f3cc35c25a42d7361ccadeca25a484a01967be2a65bf4998d57943759528d54e498ab18514a5665b87c98339c3fc01baaa2953abc1aba78778b26d54bdb2ab69dd705d6953dea404adf8c82d29b932e144f48a2661dc2129e6a2a1bc5242552374a504e0d135e6cfc9fb91a492e443c608c6e5342361aa8205ac744ecf974b667a6528938b6085492298e97ea827d5a4274ca359a1811c71a574dc986f4262b2e29256c4b52c9a22c3f168988cccad7dab73b47cd1ca43c7e036d41c94f8f31a0de404fa38a1da0992933d752acc0407234883488a581e340bf5a8dd7112099259ebfdb0cb094c8d592485f25729e1844870a3d57d63fe9c1295fc2c4a374508f359a7e9b062348c6c807322f1a2dc887a20ff1b8e951b103698492504dd86babc01339f5b0c9bdb01b65514c8df3a61abb7941da84b8005648fa0e5b094e54e56a56e8c840371349820dc3f48ef0fa488f180f57b5c0ad663512467836d6765f6517ebd0172d886430357baec25c709b3abb9c01dda27e2ac7c17cac7511726a39050fe92399e14780e3288ae775612b2c4baaa032af561d0356c43175c6263c5d9cbc62f57194c9f76fb5293e86d9a95a641325013dee98067d513525eb5d2f7cb5783915d0917faee635bcdab95a61592fdb1de202c439dba37a235e3888134249044519732701111385b9c91c2fc96b039d6483c6d1bba2223cb0f612c3f7c6dc62bf64a04b349a0fab73290acbb15ce1cfaa15c68d896493e67dd9a518782b35fe141a4d70bf33e97a616c51193b711b04a40c9634bb62726f748572155667146d311016880c670067c653e9a8dc0bc32865adbf41ba99f19b2dd9ac7998bfc8679c689a05a5038042885742a68ef84c429984588995a6cee077c3a099caa7a5d3761cb4411d1dab8fe7258c75903ef515b6b0629ff659436ff687e6625d2080671e0cbe0cb624bf8b367e780452ea3713804e083aa6e0c7adc15618cf223b3587a364320d56c58be8f037f89cae0be209ded78cbae29ed73767ede6793f0051cd5692f63661a257ccd9d859a92ac08784070bfa7ede4577e7ab1ff6c7b159089b8dbcc5ba56357b2659a7a04c8748a86991b2b775c2015a4c12341ebb419e1244396c233c161495366104b8e29979e571c9614fe10c868db56cd934c5b2d04986a70be8dc25d61cb6f0054d5e4000ef72557b712658d962b1e673a07222d59bcbc4e8339bb5b37cc1c2bbd38780f8233843ad420782b4951c3321888fc3b488897c8bab046f79cc456bba9f666ba261284a1285bf1a9a9d274d9b87788c225c0ffa20388183f35817e5825d450a1eee881f94a5a129e688ce6664021356580190a3ec5ed220b8a5878068ec5cd485816f8c1ee05c3c23ec0d0aab7f73aac249142d8992678b38410d41be710a285d3b593a8245e514a870c3c348fa45f99aacc464b399ecc0cb3c306c273e5f4c671b806864120a88c07caa53a550d52c5641203a7927b40631e21344a9337da2d128dbbb5f97b68b8e57cfbb1a67ca7741c60c2533e49ece409b0492a2e81523e6b6ad655a6dd1870b5de3690de3369c898b557886c4877ad1d67a1583bc70502b32a44afb9b60f88838eae005e2703ca26355ddc479bdf1a93756af16b7789a3221fed9a4e468b710035060752e884c56034b768d0a7106a4bebde7622bb46b6649195301192c498bb555c653c42f6d84883be82e8fa56ea303caac534014b6bbf38a9f73283e5a40b36e36c9d8b1a9856aa7d9913b22c40cb103b74853c53c3ab4ce895388aca8584449fae927b16534f48b3aaf350030a8460c8572bcc527f1f62bf1c5a9bb8ccf3ee66f66dc19286782911a6765c72db77ac0e976a2bc114a1b110000000000000000000000000000000000000000000000000000006bb77bbab15f219641914e23e02624045beeb4d7f4608d5e52063d1ecdd8ac5f11536217ef54eccc82ada15ed86ba2003e177f270bb5aeee52f9436e31a379d2 +ciphertext = 1a2dd390e05984bfc0f55ef96da5050fd9bb03891d4d2ddea46c463aab28fdfaf63d4b2e0c9af992e4f1421efc26ae86c2b296f6851bbe2e898b8bdf4057e875d4a98469b7d2646edb86a5eb5259341e0d14986a8ccf93563bc6ac067f8ff6997c2e7bbd897f02e844f180769fec5af9d6fa017022cb0af622b6e4f7a69d73ab01d3d09067b118d51805e1b6413b7a9e0ef292a6fca18a8828912a2db675f0244cd63d9340aa3ca00dc5d70c915b0061664b1e1d64d3d4dced3ef739302f1063442569efed0dfbe8c019c27823a3aabd865a47600ff9e24f748302bfca1bb60faf4105889a548be9ecaf266d8f02d3aa4997202477a70ee71b6e79dd1609acb4dabab72a38448758d8debf55369c5d3e0870ca193018e0ae6d0ffa33b93e962598b43e89d5978a9d55a608b98ceae5e897363f8a9e253acf8af560c57e07c4c4bde807620b6deb76d581bf92b7f514509446f5c4e4d09430b1855e62854988302c931b9e624644a636ab8acaec56d7673b26852c692e8325fa1b6215f24ebfb388ad1022fedc0bef272c87e10dca97df1e63f1a0e9582daae0f49e30c6acd119f7c4eef59d47443f491df846431cfbd23900341086a304589f52de1d862c26af32095e922b92650c68facfc13892430d428f626fba00cf9501e1e4646e55f5304c806b5acafe100084d7635702139725561522632e7e3871effe883298a7264a411484cdef78f9e721c0e5f3937f2fb7d40bb91620e473f9b97adddea69b3ac682e8aea2513b985fbae268176c1bff90e401a31e729fe8b76d13b5c8c85ed833d9b076b5e11acecbf0e96edcf8ff562255124edbeb5b9117cf486f30d7883aa353b9e433a77ac6912cc8e5093c12385ad926be1d0893afc7e64fb9ec55d3285e01a3ca63f3c07b95399bb4411c3f820f53d8350d1979ee9cc6bbf2d7c92d0cb2fd0a1de910d92589cf1aac29992489bc179676c31ae768869398fda50ff14860a1b4dd3bb2e4ba8b2c87aef7ee00d375956a62dc1e5d548a59f209448e62c4b1221631d4776dd5192154d637217d31feea1c4cb3ef1903b8987f4c184cf3d6b5355ad53c7bd3e0ae5373d9971115698214a93e12b98489cdd75028cf22c1da41096daca95854b35d8bbf7d0d4ca2727aa511eeb6cec5352ed487bd3b00b261cbabcfa9f082ba7300610c6f92725d532a86e00b2ed1929a8be7a342c079835a2285569dca92a808049f170fba39d990884ef39ca511aaf9a713b8d78973b4f4a2fde7ca8b6adbdc5a70241fe3ea7d005b33e48cc9fe6ce5bc2bae0746827e548332adf83f8aa707e703fd688c494136d8dfa50961a9e5b69b542ed6ae0e70ae159df95dd9d4789e284a675fe048585214047f7f6819f7f011141d265de9fd4c04f4ed5dead63fa4c8938b2f42108d263d5394d164b3254294402cbeb48663cf1ab2c296d6ada107e8aa5b505da49af96e1cebc6b302faa148216d38b9e8130cc654974ce299172cb875742e62c32c063ffe7535db2726f65fc8f600d4dbb1a20f +expected_result = pass +expected_shared_secret = 54c35602dafe572b99aedb7069a59c4f7818c860b27a947347657ac1954d6454 + +comment = Rho leads to a matrix with unusally large entries +private_key = c5f6c739c640b093956cfb9d54272b3c704d3b364ff1c68510b875c8c29f30051b5f60b53f6341082252746b8d4eb52b3f77c818d42ac776ad393072d458a28b186da2b61cf64bc6d8b424afb49a3b2528d4863c876aac69b7c7fa95314dd36ab5f021ba8c575ca458c469409b71b31f3a8e371937405067951c084b6a832ab321642c82f33395b0701e5a677c3c783a47d7a6e474af454c1b31b174ce5285e90608e1932493e44bf48b921d6a58b1b86ec2a38b8ba2a1fe884c0fd608af3986270391d1a42843637d75194722d31bc81b2b507ccc0fdb309e59549a874d09239bec5a41c4e9bb48d6968152ac9d431cc3b290371296b8056ed56898b272b948e556926478291cb0eb1bac50b6718e98b74a1777e685b7b6d7cd6b22bb5846c69149b4e7b292a4153763b768cd5a67b65c3d059464ccc123ac086f9f41c3395a56ff3152fe149d76ac2fee2079653326bdd82dd6f66b6687a7fbe00d9832b09135756c5819b1f66dc44c7b32c2496f63cf077ab51b8626d0918030134b8384c565f0715167b21fab697e84c6838a71176748f12334078c27dda3133bd44abd69bf631badb5f2664f2857c033102ce8284e4b2beb9095cbb40587bbbf457054f4d11bf938af207c1cdc5217b0e9797bf9ac88f3943873c8b66883d2ba5ec7e6696d50a69ba55457853bc526819f1a6fe09973fbd19832312b554653b8441e5eb01884e94a355732e3da645eb849f520bb2bb4327d560612852152f8cba2f77db8d21922da08e60bb9e3b39b9b85bbeb9b1715982d292b8f1017cd3e60447278cc0257898575a0eab1408122bb3fba17b62a31902a567a0821d42086aa6417c259a1dbc93b25003fcdec9f6a5507b4b732a43c444c5825a05119cd089fb2e569f70b4d5e6919faf15d6eea641f5a2875763f42b3991f7c89fe473cc057c148ac58b6c88dce537da8632c10ac851f8916fb7b6ce89ba5053b8d95d29ea5d36c91981042c4aa1330aa098a6ab256ade08592a05c95021606adea0ab637824214009c2b915be450a1f7434ea2c7f562a4fe21139c2652ca8785af3208f4927abae698dd435e90e7474556af9b907f6d73c4ee64897dc74c6a876eba1b598e784b8094232dc62bf1119ef764bd1a3bb2d4fc7de069273a223abe5269a1403873087906db164b58435ef41d7d78b36087062419123c8b1d54da918f34920d3302ddaa300797b32c1c81b82798e421ab2589964334714a75cc84548031d5810fd87890a1932c98bad37c860bb15663cc0e91880af1947b8a26be9183b648b714f763b81652786682c210301852776aa673a1fde470afb56eb0b0114895638c609d8d55585d68c165f7aad64c1406a165788c3364667f0a3c65aa300fc4585e959abbc5e1b316aa108a1cbf703965a74475147a2d323b7295d185571000e43b9120b76fb0105ee7a385965026e8f8309d4badef88b433a59090f88bc4eb4ee2f6c1f0d880057b477e628bc35b023a4c9ab682822556afeb32b6c9088e35c107e2a43506c43a986a0420f5164167519c4029b47bc81e93c1ec149e6083b13589bd2a9c64fc6247ec323b8cb73cb9f9ccfb8bcf25617a87a3c2d8b5158ac8661dfc789e92cc47340db6d04313d3a689b357566b9743cace5d5b906a39249f1c2bcdf335f37aac2565932631ac318bbb7ca75db36ac198ac6b15a02173049721d10f7521a52f358f35f3719269a695a4b0fa03b32d8a209aa12a5d786d8dea4ba05498ba222eadd647dd5a397e655ed309883d76326231a6764a7ba4226567022d70fa20cc53a045cc5a1fc54abe0189a4a2b6bf8a969d61706944bc59c6add2992b6e562e9732973d32b97956203dbc523803ca0a462ae118633483cab85c645ee3ad51682c0596378dea5e93bc7ab652648cf1954745172a75c2bf6a3177a7841b089b6ee911149871a9d987c6d499b6e0c4d15c9b74685401b680d3e112d6d70bdad6a3f9954b0057335ca36823328ac4e124d55b9932d548f58b85a32844e9f0260d8a4339285ab46152bbc05a967c5f16072f16178687b0bc06b621f5a4a14ef86b9cf1bade0185c5c52b3f2c407479467e5516ab9a1128260317605d4db250e8f4b59bf28a6ac2606d280af28664b75092fdea1fe9374976722dff579728e121fc1944891c586625a880a7bd154aace3e919b841b1f5f8c0fb841d1eac1fb18002ece216d42cb401dc1681836c1198653456c9392944054200a3b95b986a396d443a306b66018b525fbbb042e662ec108f6b872749d3287440c12bd07d1061a524a01ad7342d74f8a4b76222c5a439eef4235d51c9494602f6624dee256ea7fc09ceba9877f9332bf195c43502ee43c75e78720c306c2fa47f4ef6b7d69038dbcb8272b334c98cb665b306c04252fad3559eda4b96c14bf50b78d4a9a37081a2d61cad33b3b9418bba25409fbf4a5bb3c775a43b39520b37b5b82191b4983398858bbb0c6c8031b9736a5f76cab0e647443cb6d983a5e0a6c27756cbf471baa17870015566db8c8a51aba969e976a1c6cb2be166f20680893950ddf09cf8e3827a2a884a7a65d61c7c70a522d17ac0939625fe63958741255b012712e76fa8da809a8cb447d730d4097bd3e86471019dc8897bfc82c3804a76a38919f7cb50ce79bc13ec4bdda215bda9789503aa822c71ad8107a35818a7cb055b303338e465933565b94950c11836e8e33ae8093b0aa0c5d5d555cbec5eb4190eecaa1525014e8a341e9400180937afeb126c278a5bc4713fe9c417c50c1e47c8756fbb6a6b265bdffb4c1456c5b7d7a895b6932dd9a55623341354549283ccfb36abb3068b2db7348bdb1172318357bac12422ab93a32b453bcc0faa4e8e595b05a145e614aded6bb77278bd78907b828b18a22aabea48bdd69cab061522a618cf39406f6c78cb983354384415d8b857cb451e01b24f489a3133070d775307fb61a0f6d56d1255c4d4e18c62e57d8422080cebc919b81e67c4304cdb560ab16d929413af650a53f870e8017e90096452ca3ea648ca644010d34bb79c5898b775b197189a55840f43371dd9cccb7b4a28a66309a515658f06acdddc47042acee250a37632b42af51adf1c0666902fe0acbfc8f59127753a40161de4ca07a5c8bec0d8ad3141487da4a842147b9de945e4962699033375548d680b88ae8354d6114efe284517778eb9b7957eecaf5b4165424a5f82f100d02b7d39968b98f69c2cea1a0b39394f49265b492ea8f4000000000000000000000000000000000000000000000000000000050f496e61849154f498d752102402b70d58f7e61615f724973e5ffa9065b18a2e8541047591efe1847559704339d0ddba611d0ff8017cdc84e61184715c93e2 +ciphertext = bc07d2caff561b4645e3878d1de0730a88c05f46348526829a396f05a0a00603f0e2fc79e13beaacbe903827c20d9d687f3fb4eb2a8e9335459fb21380b8bf3734518778d8cfae9524ead1427c6a2dc379ddd2e985e2977bb63e932ed59c83a8b9a593e2adba0cc5f106620fc8c6c4cba5106bfdb4105def0c1d7b6800327cacb964e1d4ebbddfaa15b279115a1d05754c0c8a715fc2fe5aa09af7b96d5a93e758458aa5af8cba03b942f4d3c0fbbc2a45d3f7af5818d67219a72f4f538883ee2d3e507e2dbf4f7748446443bb71bfbb4eff0f57d8154d29f5cb26cfb52c51b676e9b1ac08786d5f475cbbfb49697a748b7902a83da49d285a48c7e9cae74b66a30b02a353a287b40a66a0663e7a71adab7d03272f2ec32d47097d4c303396db3e7b7a947f467a70646777cda227d72310806107b5dc16cfb36918e88784524e3a46c30242a40811593aa8f72c742f885a9623534753b2bac5e29110a1a854646abe1c0337251e85987aa612f3a095409a5a632af14acd19491577223c278b18a9c3ffa7f72ae49b89df6dc45ebb2803ece96cfa94ef9ef5b24fbe686ff90d130d3ae953a4f9ee6581a346b0612f84cb6ccad4fe94a53602817d67c61a9604d288319f5933f4a97dcc6ffc36cf14db593fe27f873be712186a6695d949d4552dab37e36e2e0ced229ea9dccd6d3bae22f9fb888ef400b594ec08a15972e8d2478e50f11947b52bf384c731b0e50dcd4ba116abab8af3b880c54badb11d83b4266d3e5fc25c2c8dbbba12fee2fa5c2017987f31277a67ac702b8dbe110894a8c81011c7c662ce9ab96a2e25cf5056a3e202dbf6bd5bef2347537f7811637e932d13ce02283d48d032c284b6cfb84fd813b6c3421017a7527eafcd3fbc5d4324b5351b30abcf1b366f424a8a0b5edf6bc1f3e8702b03eff875687c6caebd7bc15f1118696cc63859e3aab75aa9acc58484da7f2bc9a120844e4830429c0eee2b2324890bde302bc93f661edd9c04e1183528482f9950654e8c267234245aa9482d94e90e00e929b65431f986e7bb34524cc41f4b4443646713c7abe6c4131a2d67f3bf42f0a7f2eddf82b5c08a94d99a0a7d14c1b0b375fc158b7d4276eab22efb438f0d0a9b30e9dc127026181e42643af8da0b24bd10a532069392724948ad722b25477b481006fc1fd030aa62b217e6695dd4c7ad34dbfb75aff1df5774b061a4ea8526e9bcdf9679405c0d2e40dca00c9e80840e832fd663596dc55f602d094253893405a02d4414f119d23c4544cf832888db5ae8494dd2e8ee357753515d929b8a37b5b45446ffac20fb204b5c937f6344c453ffa449fe839b4afe1da61301057338fe29df93aa962a7374a2ec181ffff9252c8af5c3f75ebee02fba58a76066df4c6acfd5d1c18390652eb2f469d35dd708e63a498c08c5241b2717333904ba0e6e0845dca8c9608f28bd1046805cf7b220498145b23cb18184a259458dd2fbaeb1c383005a0d289562b0a9daf7d1e320aa302fd3d9a02c65fa901d46d4 +expected_result = pass +expected_shared_secret = 7e1b4195e9cb70e6884d3d00f0b3f0a66b4d8c00ce112e1e79a1dd236ab62b26 + +comment = Rho leads to a matrix with unusally large entries +private_key = ea53a046a53b7e3298d588b38c403e67b5620c5c73a438ab7357660362ab3822b5e774a9dae973c83a96db79b550dc176f9b0182d37f12118bc96a4982249a352219a110704e4a0ddbe545e4f55cfc2c50d54cac33ecb6fcbb3ac2a7bd4e41282476797a3c24f4ac4f60c33da281cb1313035c9c804d755267894d867469dbfac7be52a34f55c0dc642354e52967b043a0e0167c806581b51519e04af675147578c79f492da3ac0748352c6e5c7ff462008cb42e9817155444b214c3b93ff3ae7d44b5c2b659627a833cc18ccfab4fe6d6513dfa67cec499cd7a0d052a5f9ba378bff75033e69ad053c04b74c8cd756c7cc0bd494129e069cfb4358324066415bc2a4d1cb8401867c9954aa8a33f929ca279696cd515bff0abcb6c8692aa9cc076861e2bf27ec360983f775e9f166964d0c43c380366f19d3f868a7e038752d30e389c0c057b6d93a9ae64746d5b3a146d31269b94c7a753412be68d09d820be6890e5db1ec3eab1acb14cee8a317ee7ba0eb6027f13a540b07c12cb1164bc7d295c16eef4c8d9773bd2d32ead764f58fa48abc2a5491bbe00e07965017ebf40c973343704112bc90849d219c70b028ff3769e720c4599098d172674358bcaa8947ba6b874e3d94e623122ffb3984a0b571632be1c540cc5da45ed1c57da1054abbc4456678249a2589544c3dfdb6330ab35416ca49c8046c9446150660b45e05b720722bf390e307445dd8a3e23253cbf633c8ccb098976a68e481ee86b86a32865d9caaf385842cdd071b0974e807710e2b44c598a4a36bb2af048b0fd30bb6c64a539513ed2a5a9c6cb16129cb88d6bc62389b4846a2a0afc532eeb0f055aa85ce7b43f8099cbf194e664c59e683e535ca809d40f72d4a3d5e287b5ca3880d4af1f1523b60c8f811a17b2881602ec0393d54988d63a1620a48ab25a5336b25ca25d5b21425ee54673062020f065693665c68399691748ed8c2b6ea47b89391e7dbcbb3e4bb8bc0972916aa0ee5b90292b23618c5e9a68bff8476fec1c7e382b1cddd45069263a507c44b97663a9c8b4bc690c89d25893c4caca0caa7633bc66f449bc06603fb747843b0a8ce11d46ca100b3243a8617904a2ae48db08ba24bacd5b946cc96b834491a246850c44a0f049bb3e099b3353b28c3889bd4520ce75749b745e65e6442d970e917362cafcc9cd1a6194d9ba41f29feab98320e10234c1b0fa367f7c3a420052a9ace9a0787bbc420832db814e8f86804fb74090146f899a624ee9739ed55c40b3716724b8a8164b8b976130d89e15dc24e2078f24a953b2781b7d36a12334356a6998870a0128ab5152a89ddc84aca3475f8cf849bd762ea7b23bd2d743a9d3a9a2c2ae4723b5c1a3b5349a2d4bd2907d89ab8fe80624838130697bb1d45f873a3416164f862630e96075fbc5192be26755eaa1f33026a1f201a05b6b57ccc83fe9c191b13016a921532c4558b44ff0a26c864c3102ca921c299b38199f7162938387c3598362e5f616756bb5aad68c68e0a34ce96684597712341f391ca6696538582ab0dbd532c7757b5b24b0413145395123f0c4668cd538782b0f65ecc30b687efa78183de47f53b73831210c513c54febca5ddabceea01649d9c6588d68c05e93cb6959fbe348468cb6e7f482d2b0507a097625325a7ff5740086bc203410414845a177c578698b313842dd2737d79806fdc8aa4ad8b91b514b6aab60885a49be68ba60d05891dd1cb47c1850b0105ec15a95c93136f22a170e346d2256a0cea672941335423cde35492967759b4317981c34fb0d759a2b08aeb411c362b2630c4b8ef342cf844206d7a5a3934bdfda95ba9fac912fb1844a0bb62041868ba0e3660a5551951b39880eac2959b5028eaa765492416ecf7a05102450eb20eb2a28be460972066b41ac87abcc28b38a7c92d91779e0c7cc8b42f107b48269521edf0c558a1b767536d295c3a7e60b9de6a8f299563be7c4d33d33940234af8c7764b181fb7b5af1dc88e4e830725533656520af7344e4ab40f6df34a90a898c672b854021d0631c1b1e9999d8176b22a5ce829a240642e19472e635a83c5086f87872f72a62e5fa038481a6861141227666f9203675db45a444c6310518d86a9221c9b6bedd753bb7914f7995e39031963ea056536a96c9b14598c95652091dba9210168467d7388b73770aa905052645eaa877c6f8a45acbb775d080521479314e214a5217835667dc2cc67dac17b0103b1049a03585b30631c6dac53b6d4056e5877786b295fe94c8804b57a027609bee938a8812666d12345e04c92469463443fad1c2188c951cfc6a06c3b8c3ad8856ef26a67b7841428a1f5b69a3fb82cad843a55645b78219d6de824701b0b1f192d4f816f45032b1cd5b465d33b3a9cb2fb04cb271a3cc74a8bf7ab6ac7a00e8ce6a0486c660680219c6ace0917b31595584f4756c9c5273ee36c37d25d5da146e57613edd34795b9cf61bbb7ebc441d575631215a87c4070159136348854c297cf3ca44fb2814448e30eb2c555aa2393bee966ceec0221a278f048aaa6d09b1d801aa0fb369ae4480f051329390af222712c61a59f98a31a03ba90c1a6c34c1c98c0be7bf59fd717ad9894786acb1cd081405c66a2e79a1fd77cad853761461c99218aca3cf4920703654fb9529c106f41a78b259294709bbc91679d0442bb383c28d64683ebdc7b94f4592c8ba2c1126c9dba9377040d3a124176fa33a3905cbb96764bc89a69480b74e38f558b422ef22e390bbc76e048c01129c97c26125bb2f86c4bcd274816265d8c41167223b0a22406d2a193ad3b1083b0cb75f9542e55b9aac02845f59618b5aa580b5b2bb44c192a906ce61b8c368278618d8ca8409fc02bb9b097acb208e3c2a9b651a316b70cafe6b9bdb32ad794b4f018b66ce55639e5558f5a3990475794bcaa06f17093d490fa583e6fd9596b40958359a30f813b940b1e1e4223d3857cfea691eeca944de845c2fb502e35a5f1a3750454593fe1c41662a3b3da407aa269c43167acc98f5f3c662d6177d3594d0cb800087c6a525c586d86c12e941b046625d90c8ec6dc8a5c546abb19a0b585aef39379db926691124265103bbb49cfc4e9100c803b4ef68a904273a6c899e48609bca003bcea9cf82203d52b5f9b65c409ba9503b3b16c7077465aae45d2cd4ada79ca43a9e99a124b7c9fa24a323f6c6bc18b81d9a6161191561f3776740b539479582a46bd913ad73e0900000000000000000000000000000000000000000000000000000009ff3bbc6c725ac014b798e2d5146532f55ca1f580b27b436aafd30679eb4bf35ea63afb095b03165e6f3b9488778fdd771036713df7b893ab8777554eb05f64 +ciphertext = 79efa2d537baa2b87a787317162d3dbcb40cb3c25f540ddb91aea6cea9870bbc5a5f86f8900b913fd4154bcfc7c8a463b9b66118c502ddad539186fcb079664f44a5363cc8d80d6a4c09f28cf8952157526cfef7bad2fc2cb69ff03ac39e37d47faab64cf54f63919303badeaab9e59df7040511ae335c5230e46e00a666b994d647d11cb032e7ee235b5e18b1894621ae93ee129823334580381b857cf0360196cb75180410f9fe7558d0e189502a5dbac5b4f0597cb3d1d201f89de26f7b4ec0d200a418a26cfb82cd4496c3ee22f6eb60f3ad2e1af981c238da13063d1746d65f77ce0ef30894468b687b31443c7acacfc3b3878fc9ec56878e7bd1a9f72ecb1706a4e5face0a83282cbc2bd15c89afbe3c97dfaf395a96ffbe1a3f75af03311afc69dbc01b11ffed2aeb8906505e910105806febc6e1298fbb5c0bf501232b888b7e8b285953d250b866a20cfdc7833a732966b3a03485ae2852d0a3fbeec6dfd0ec8015db5de69e55f091e956ab4392834c5128417105541b1145b27175fe35efbf3102277b35e42bd83aac25e25da6c55c28a03b9e2a8135871b4cc49fbfd5598c9eaa2482f249c0b6332a6999306be55921a3016499bc63a072a6e9eac894a3ec209177d07208d0d271c47f8065d0facd2e975011944f7884088768fdc053cf86f31f6d348222c06467fcf8ce0d404a2558e8cc422521a4e249549037d3e8a29e03a9a9bb511d9ffef4c5185a380d874732c9e862a6e8fa3fb72b213dab2ad0d91b047440b1d334660067566e6d2e14765d8fd0a45b9b8e8566419a6d7138e5a106c31b1278d50027d152bc8658d7045cb2297bb8382585b38be2d5fafaa7e8c867c74be013793874f181a9798193dee26fd5812eb469d1b842a969cda65d3440c67b00e6d1c3ae8630165499c1b4cf3153fb5731916ab779a2562ec62637d747d61342d832aed330e5cd794de900fa507d4b5fbdbc5f3ec1aa69d0319b3644d46d9502d435c1b5a329c0d3524611a145e3024595e91c2afd577a422d59d4d54a430f439534003be467b6f018736c4bebceaf7c83c799c2b7745ce7498dc84b9e455b96410dba1a0a5720fe703b7c0d859a42445eee7ca3353f294438a7d463fc3e98f4403f93b5fc4add88cc22db7bba150a2988639ba96cba8e2a0c980c9bf8cebdb5beb262d79e86cceb774750cd9a192ae93d85e60722ec6590beb7df8e4d036837c97dc05c7964dab00034683a576da5b51aa8a0622edc27975978c7daf1b942285572b09c170dd332a99bbf703d84becc6a96373fd1c0b355f063e4c2c6e59f5437802676000a819b9b99418df893b98a8e6ca22d95da2c151fb24a3a0e5944ac4ca6376e6c281b275589a3907c0473282967a121f1792d09a15e9d71e71e73f9f627ef0dd478061cf053af434b0663624c3bbafe0f37d7a32504e9c686f41bf48e287aaa8fadb73fece907f26a9576611ab2176a58e5c1f3e98ec0248a15774434c2a81c7a8f57f9950b83c0d3770d17c4e57582387d6f19bd +expected_result = pass +expected_shared_secret = 2522e72d308dc9d7d701e0b024af9e15627572f13573b27c406fa750df9636fd + +comment = Rho leads to a matrix with unusally large entries +private_key = a7d40e120206cecb9458a1464b96c447db086780708c7435e40bafe1ab8cf26caced91b888711b8b95414e080c2be24d7a622c2e0410fb9c795a25a50554abe8b9049f9890e29531cca88e4284a5bcec559f939061b003510c8a23991cf474ba6676b0599c86dcc0976f3b61cb624954d3914bf28e109193ef1b9efdacace8574dceda34905485e1a79d51c8ba06722150d8a243d69f671c18b1c2a77c990699b72ef5b1c4aaa121a8e5a6cc971178127024166f2593893bf3b9e0db273040b0821051cab28af5196b8937538a680b39251b08051502c2a3d5504f78b767dce91e2116280c3532e9426b93d8cae3e9abc5aa4832c6bfb02a71559bb689f82c22835fb314a5e6d44bc4085eb39ab41555103033a0f4b6aabfc5246c93c07840254989301f88776c06c9f808369e18445058b4d940783d57b7d7901b0d63a6e6512b31a63ce0704028d936462c18eb4bb78accc3dc56884d9837d8632a258c4e998cc536248aacc62f7b9b65191a28a27a1cf44a0d512875ad5112e034c0adbcc67edb84eb000bf3621e7c1c5cad1cbd06f848c5d8c3601b07463b5c0e33cd260a2ec99a972c47cda74229f6292221391f37d20903aa76eb6966195acac6373a41db78b8f7515a473ba04397c2e94a26a6acd8f2cccdc572d4b60e56880fd0295152e18bc79699feb1a0b6f6c7ee19545f4124eeda5755a85d79fc2dddd2848216576e9ab4d07b7ecf77a74937cc1605602c62003dd5abaf601b55ab0cdb37bb3110290f829a742c5607ab24a50000f3191f435427b5345ef884b91811bc44fc4c6de32bdb0a73edf80c8783a5a6b6a2d06657b16104cd62ad847206ec1b87729260e91b2afde6b0f13a87025c10bafa88e1fb1a66b98a5308a2c4f10874324179a2729df786627271ac5a945072beadf878035169c543c0b07acc49241b7feb406f524b71c787ed757a3d48c233bb75d97c42e03b9973cc680169520e400b00879cf2bc9119325586719f22e1b2de163184b2c43735b2c1a8654c92138b90c458421f681136e0d6c417b20a5f8c126d3672a4073942855b127a87ce96c7e34861923b3ea9bc9f0aa277746927f0777814862b0845c3bdc12309241f387cc6f4ba4a9688b947ec8b5603ce88ccac5c35756d0031ab4a5e32f6ca97184df2acb38f724fee64a6a688c69f6b913576af98ea2487db097d7c81dbc2a29a381b2345495160c348e8207e313929dc08412304f6a01c90f6889e23b7974bbd6f081f52dba8baa716b53769e6f71b962156cd44a3f50563efb3b65741aa26e42a3720ce737c7a7ad5c875663bfe36bde03b106647ba1ef098569bc10a0940cd300d58571dd354ca5ef714733bafa4308b3c4b7528862664a8656d16c9c3837355e39072db20af20025306390ef32931e793e33333cfd893c6227215027ab7ba9cc0212ebc749abbc62be483b3e2406a5ca10d7fc534166646473c27979053928aa5445c4c1c26cde40777aca39f5a64161c322135fa176d44b694341a0d3a05de662ef0e1aced53c4ea2762c1333da3f987fac65ea63a17b55c3f681c568d648966eccd095928f2e32af2fcb0674ba3a50350e282c99af149ab1b3f52d3b9f838b1aa8cc5e2c1184862562b91806efa62f1b72a8ec43e70663de1f66a59687ae0cc1d9de1ce69244fccb0841b4b1de2e964e29408094a1ac0a9b4daa836e94454ebb942c6e9ac66f39abae73f61a99834292ada3c824bb53c8e67912a07377da92e63087f8d947f59d94a842b7aa8832b2c3c1aa957577f55027e76c106f86946f036804671b0e0416cf62e70eb8194d88030e2b38585181c4ab1fd8165a821bd68dc8fb3b403016ba5fd129bb9d23182029c4a292433087632816c009a237a608e65cbae17d688a326bd6c1ab4634576fdab2322b983f29c3e63b31303cc386bc90641c84965572c49a91f4e8258764834f38ca7f869cddbb10674d4296e5205ad805ac48462d3b31a9e6067fc0a27470aa593b896c3c319357b9bdf0632bf0786fadb0ac242609462a06f82460ea75762a678fcb07c350649d13c24c9e33200c9ca0e9bb87dd2c8578c7c4e27b1b75681a0b6aec6a55e767c4e14820f2ea609a16b862d5695556b0937f53e0ae370086c8f771295b1a09f0003a07bf512c4272f7241752a6603f8f51ea9a088e5263a59eb0b13b87a1d2929c2c29557681f180261f46c294de4aeaf380ca5f79efa2c64ed3131272ba489494ddbea14c69c46fd6346a7ec9f72d89559435e139a67bc3240bca29b3774127dd85d53c20bef719724612c462bc598c54738c87a00a9cb8c4b44e4e7ad4573afd9324fcab820cbf2091fd83fea52adc1b82b3f6c86369aa358498197631a20d40c790c2ddc66b0871c1ef882305bd978055bb934467d3ffc0359c2b31748cb19f615a63262fdf695f555be1ac432126b08e4a97acc18b8606ab6adc5cbe4589389e1121d737ba2b3a84d02bfbaa669f3a06b1be13fafd42a1773c830749cad35456e956c0ee64a5fcc46f1763c3b0c0d3de5c296a28f61194ae72979add8c7ce710d4ee846af81cba3e18d5e459addea9fb565b010e9ceed5798155227dcab155984635d7539d68c9f0d30537ce8b573b6bef1170540d0c10528737d6a5b219b2d96e5709a721b40536ee3c416fcec0bdba013b0fc0e786c9765d312692a80a5c9a3d65a6662788d194722d63b4bdcaa700e4c3daeb911e4d45674c3720be35269a21c0717a4c3aa2f3e1ab4f20a885cac44228138ebb70bb4548dedf8678d2163c339c1a9c719c2f1a51748571358c1451b0ced7b90109c98591126fbe57e1c913b5a935eff14450a22c4a108108b99b6efcc9bfd8438b5024677144885f1886ba068a6191ae17b9ffac1087bc94badf510095baa7167a7fe245a89a2a627d2631706a15d5aa081d037a4101b217c1c45fa0d83dc790447121cd9a533592cf8ac424de8770b45307f0aab484467c4acaa82a5669f7621e8ca42ec0b9222766b52775173b288ff5b01d70a60a853aa44917b8cd09a4b666138e91a3206c97877c96d690957b58553018f55f168c1c51bd9a48ae762a65dc73f366c79e77c42e793750924bcc1472cd5e552e20868a42047593842619c2e0fd40a3c7bba9557bb5c71185430a0158b9b95d04fefa266005141ffb4ba5160a5eee1499c09b11c549bc88cc501dc94a0a5828ee8a776a2a4aba3bafd410cc8354216cc3a93a457e9847af39b898b04b60a0c661a72a2df2b000000000000000000000000000000000000000000000000000000da8d41b69d2601355a1e57206c862dee967af0224b3c5ccbbbb89be1bf12fc688bac5e523fc2f73973b46b1727891a6077329e10e94acd027c9dfa38ef4e21e4 +ciphertext = b0e578cabf9deab616e52934955f42eec74bde5ea98acb022c427e08232142dd08f9120eefe5f455c8f120e672cb68f3a146c3aa457b637d0901fe2b4cd45e8b208e06823b8aae09778cd00fff5bed5232d219a2c33645f2dc30593e591f697118a8472eadbce05c9fbbc5d4b717b880065173cc0854182555376dbbe39194e4204067358808c890e5fe96028921fca344e3500b615f2201a1c4e4d13dcc889cc9b1ac72429074c21a52f4c78ea2c467d65cd2c9ed682f21f31b27af4eb5cad33dd633185bf32e726fe6e57b03168803f693bd85f5a9f2c3ec6944e9ded2b8f3270a89139ce50ba6ded6bc6b0be8893f44aa5856acda60dc1c4c0834d45574ecb6183d6e59a183c0125ff45c718be2cf85b5ce6daae6e37336ea63856561f1bd4404df725d5ed9263038d1c623b2e1aeb35924b79de474407168834891af783fe5d83a631eb14d7cfa949d698ffa45e7d8c46ed4abf75cc666b78526c9b95ebb2920c77c56227eae6c893b57f9f463ff2ebc9acddb2f7ad543c5b2259047a4cc87ad05c08bbf02e8bb267bc490c4b67106fb598d42135c927fef3397f4c3f6838776787f23a9759dd3214075e79eb3929932becde84e82c257e4638a19e1e3312cfe09d4ac681d653d749c8fa6efa6dac35ad59399f1e233540fa354681ca55db90007039b7e504e2e4082aa3e4d672019741aa02a281454d4e1c73a1c7d0b5449c2e143ceaa3b18cb9a74a89f1ba74963dc5dd4155a356211277af3a267947700a2cfd84a605ab02d37bd6faa8a26b50f7b3d9bdc79913272c31dcc0f0183d05933a9f233504ddee2dd851529667ec5174a3d23bfca197538ebacda36bc29ca675384c0b3f45e4f67fb66d8dd4aa57b7da50ead391e6b663af173e7f4d46139f5d0f4cea84dd32e4e718967c6b93617271224f2fb3a1ca5febff5f26c4edc60e9acdd9e464ebb4571dced645814e1038a50515a7e06501adb2de19fec4119dec7548c41097964c3151226153ccac24abd1415579ba1c37c805a5827332d97ba90713829fb30b7b09b275d75bc10d4a26b33980a0ccd4b00844d9f379551bd0170ee895286526ea9625a72b6cb8decd9cf18e57262f8102a025025e8168465a65a7c7e4d5fc8742781acdc16171085d51dd5ec9f4f71f58cfaf4557a55d07e7c164ccf7eb427145c7f9a800e9bd9192ec0f74d19fc17d3881b1d55e8600aa55abf78fd1e226d9dd6e8da2bea15712f5f43325d4b9c083d6e37d35c043f2bc8c796ade072555263331bee7fffa54e2099135ea363575847abb770322376cbfd3f1b7980a1857c55fc82aa80bdcd701c7b7d66221f08492efb5438a04d041b485bcb61f6fd306e96cfe758d99ca1cee70b200eedee86145fe37ab7aafcfbb2df694361fe9923e754187c3277cc895c4a53732ee118c7b6156b55b30847a6e828b7069a5d4be623abff66ba87bff49294dd9b1f698ba445d610973d052a80691c9968e3179aa3eea5b0bccb3cf674c5cfe7d2c14d7b6daa7a4813abcd56ef930099 +expected_result = pass +expected_shared_secret = 1cffb3d6d9dd9cf90d79fb2c5c974818c5bd6f32ea4d44c302337c4cbea44334 + +comment = Rho leads to a matrix with unusally large entries +private_key = 610c36a286cca4815c657bc2f28b854aa8602890bd6ec2700d64b495b50d049c5963b8294752942d11c1d0182ba6704e54c003b828bc58b6ca3ee0823607c3c00bd0471b4df571c51db3003e4cbe6166c0caeb747f79573f5b8b80d12ca78bc1d3e01a318bac91fc863198afb70cb9256a330faa06639caa7ffcc1248b367bb6b0bd905ab0098b79b85ac5dc083ed43ed8b248dbb72e5ad962b3201c92b132b2961d9867b48208896c11afdd929be2792839674b18e4c1e99a7df714ab7ecb58570281ca80a92f148bc492797564682b560f1bfa42b2f7734047cfd6375d3dc05846da1d3511cb3c8221d38226f29ca52b07471a41764f86ac3418a96aab70fc8454d6823f8b7c6211d216d08c67eec474a3cbad8f3587e22670ae5a9938651f3b48011341b6140ba393621accdc3f606b080579197c48967f1c8d11026d8f90b0697869ea49cb9db086ef687227b2549ac689b564326a2280d8384698185afb25941ba0365b0c1939148ed6e1bf0ef5c764832178d47a01c3573aa268e168b740194a9b36ac2580a7bbe1625900befef3adc6fcb356100ddeac4393d388fe647c3d623d1e6a56a96073bec59f5fa39581245e31aa33cfb865bbc28e9f2498bad34a5bc65c517bb8cae19b6d1864fd7a0c48aabc78d0373a84c168f33ff13a9586aa349a185e3528003e804c8cacbccf0073da46567f7c3ee6a55eba856851234b4f3725e1bb3609e50cd4c9c96ff947c4b048dd7c64b3498d23c234e9bc45230b8b0c797946d0980dfc7bbc5773620b8330262ab6247fca5684c9fb8c2e692c3f654099a7a93d0aae62d24eb594544a81431f295bbca7b15dab7bcf728e3dc61f6354a459a120c371030f3b622569a78762b1cb08248a455e0f0847e1531d194acb0507bb53e9c0e13c8b2f45ab06362be3d9bb58ab6d90825a15211f81f4987000cf74355a28ba08443b3fd9d26b70039955773f9f840207f696d0e7a4989c4b38cb23df626e53b7ccf7c1bd96bc3f68c20ba180a482799d2cf975e0a39d5fe863df954665509b3eb63c257b8c9e39050bc4a739468e716cc289a79053453a28906d003535536439d418736a95763ae222c8870b66f1b5a9978c29d238658a3e773063dab55125e851983706c3ec68d7fb1d595b55292885f758a8df752fd3d97a8dfc33a228c896a44bc039ce1a2069810b1304d44522b1a5e43756cb843b5ef515d89c310f442f585259e5d460dcd578cc51ab49e63a7cdc2566d77e6959a7d24150cf0b413d335efa65385ae13b482b9b4db4ad2518b71704098d7481d2233e2ab201dcb4a1b3604149710de3cb247f29ce8ccb2ec062b014708f397482dae5936bec37663c849c9baa9d3cc88146b88cf970e574694af03fb78205e205435221b32e5513989047e62775f1ba5aa89a10c9d35cb566328eaa5748e9c5057446f96cc691d80208940cfea984df8817d4507aff0a0a96b8c6729329775c8d75935d7624cc0a06ab7a950f2b73ce4d90239706403c0651dda56544ea59bb06a99f00bd698a8c3f127fb4a3759317a05ac244a07342f9a47257e5649dec2c7050188ea669a97c137f707f4e5b4c57945f82c1b0b2040476d73acb54724cba00e8014b4f4687bb6670b1c2a29ba577100943d5b926cb396423663f710328a8b536403530eee05006e7a7cd679ea44c29146494f1775cddd3b43ce6a903283f7890979ee98842d5a76f93777297abffccc0b8faace8f362c081aa435c32a5c31773bc046e61921f1a5707579fe36067588a0f32e2cbf91aa3ca6b38a0e12ffdf8685874869028775fcb7d7fd7a1e37c611316515638a510a13e950960e6f39395e436821165e734837ed575ad510d4fba6c3ad67e039b71a9b6c2a7ac240ccb3742d65b4b1c50a6a1a496995da77921ce33624fc48135e88c59caa47b299605ac1c79009dabb2062e375547ec907590b9bec52c86a6b9e394ba5f02401e4545c462c5f320939075b516c4a5dd0aa5d879456449a115125369584a609a83df8685ed2ab45f038559dc6b0ea170b09680e7e747cc7246b6c182d9199941847d9c1168a84400da2a98215a9e96f6bc869035a8822b27d459cb52147d966e0c354b70ecbe46daa9034074019acdac30055d8a1a02741ed8e602e2cb3185ea44c9e61fab637188554c8b12cc5abb9073b35108f59f6832112ff23b00acb0936594c00c0534a8c4c11cae4787092bf497b60b4a44116156e8368c0c950f3677f6424690803ee92373ed5c13d84c355bf041edcc872965816d6723b344244d0a54f8ecb0f1703ac251293503baac445996a1c9bd6ab851eb52f042692a2b10e4b9b44dc9625973af03fba67a3a93ff849dbea64739f643bfb803ea8653c2b9ab9639614000994bf48a8024c4e61c8a07a5c79b19540084bc7664ad44122e46ca1fbd517c8e68aeb3d835e53846848742a9fc2a4058047969bc11a773e623462c7bac66a34c62db861ef64dedf23c0b7441f6b75b4e60b86fe309b1b7746d558987f6a92cb8513792360ef76cb6548f0813ae8dbac418c25a1d95b06c530d79c6751e7569a2027f8a5354de3a70752764fabc632f3a1bf2473e8aa2a5cf815b3856a89afc122d98ba3f74185a3b2c09049601e23ee226329f024ac2692adccb2018b22a592a450b4a5819b2a498738d29f7145e534e527c859f05ad96cb963314c58a5a6b050ac6ead9adc4782859e3383170cabe4871cfc17a30ea4ac55cb998e77e1a26662a255f99f4ac7b98723341b2c7134adcdcab12a473bfe001127bcb01f84df31384af06171776263085bed1aa3374da7136648608b569a88663d2122e84b4b946b35c1f24a836e924202b7c7828c15507b17f906bc0e4b28c230134d90655696edde11a32c7a70303aaae3363e2a6947b4bccefe9ce62953f92521029959096a8910e71c51b69a0615ac790341c0ac3a574a79d34c11b4a974ffd7cccb05995d4089f8186b545b80a166982cb53123ef644e82897c77889ef91bd8c5a4ed1a4a414389d77307d53487940fa32782061e8458e0c601c884321d121b48ec04bca78c60d39b0c4bc9291945ae18224ec73ab7a451b9cb511bae34a20e326a497cb6ce46b5848c289da630f497ea3975eda79489f18a405e91bde288379f291f538c1a1426cf1634bc033098bbc9958f7af6e408354314e7221c37c1610bf904cf9e7807ad327f0f316761939674867ec7223f06a245711b0d47832b1a699badc8e1217798c0d0000000000000000000000000000000000000000000000000000007420233153145d018d37197db4a72facb39b5779cfde51a1ffe665b09f338119e42ed33e0da5856106580e02aacd0aa1546d3df0571d17452d22f186d011981a +ciphertext = 3159aa52482f4262cee553f9eb6d853d091a507831f5ed1af37b9c55f217eb1e87e8b0dfb653932c27e9e9f2c4d45cf89e9cfe9ba0d5175be56b7fe3751a4255649cfabdf0cbd5a8704d58511acf6e0580eed572561fab262b24d39c3a430a4e54fca969394037df12fd8cd71b7b6ec3d8f7345b05d4c16c5871b686690cee9804012a3379bbcf720f405c3c83f59aa391cefd8b00a73b41147d42c8b7820b0e779c44e032209067349fa4cd35e83850ae37ee73f96fc6bc5b71ff9b0462604b4e07be60cc76903175b045b908c9b8e7e94c6bc7c48ffd49698873913f9132025e51614317d27a874e319d802923804d1ce1626420d5794bbbe5e077cbd7fa3d958fb2d9608a3d41f605908d21fc7f942e3152337115a28b661f76405620b056692bfcc066f370449628f8e31b7453e5b7b10702f7c195dfb779fb3253f86acbaf4444ba9ce01c9b043133a233030247f8fc44d5b8c9b024ee83c186a62ba9fa5a3e45389217884a478f238d6a9b8eaf3d87b7b4b4375d4d5226dfb80255faab42380365b5511567978be9726d21178eced7294463a348b1e976d800b1114fb8230115b28e51f628a31aa8cf2e3253a7dccaa37f975fa2b8d32a6b6147033cfcbde33ab8857e3a6af95e4cd0db62fc020f55c2d6c9204a05835e2cf878c66502f572016d95b30c45c2ef6048471ad0cb7fe14250dddcb4014c392c22fb1dce1adc8e02f416d3e9b417f41c1b4065b975de472d0e9fd5b3a012ee9bf6311345b4968f6f18262bfc2a38d56d911f9efb981813f77a8a8d6af0618e015b8b005e7ea957f89f140192c7442a645ea7012b5ea2ba9f8cd2fea2ad3e41c6a57582237d53444fceaa933d61eac36d03a2865bfb7f12fd8cf451edb5050a35a75c95dd328296dc32daf61622ce0cc457c5968414b634b3e12a0ce45bbd733e3982c087a037d89cc86d546007bd92eef33949d19dbd4daa18e59c7ea3572bf3155a9a46af527347f4f4dcc2be3cc285d65f2f86c681a137850431ce8d2f76e295e74bd0b3c88f1b68885522dadb99fe1c8e40d938c9610e466770d62c34e9393241907d9cd7bfa470cb8fc149306d9450a7a1887d03cddad3fcdeda1ea54d3f126bb29a1ac3d7c5a60ead90d74ccbf1a75b4289a74a49e0a7c4006ab76a83915ebd4a95a471525444dd2c3e748b1bd347774e2cf01f90f05a1672c58f4f563e4da083e95e0fadd4ba57acebcb45611a3923da1d0d73f5c9a55489fb0097e123694e413460252892a0c6317dcb56efa834f7a51db4a413976afcb30ab4dafbe737f43da11c1b08a2472cdff3995dd7d23382b866873624fedee76823d37ec230dee2107258993d5b802fadeb89c9469a33c66c91567ea92581e0c2c1eaa2e2a4696b024c7c6009687d07769438a8b2ba75a7bfb32841dab8acfb8cbd4d1e26c5eb68bc49bb394b178e6f89dde843f4e2c5353b04390c245a0bddd1aeaefb87528b719fe42b35ad2a89ef34826d9e23f95b1bd3c3b24f785985e10dcaf0eb33f5f71f5cbe55 +expected_result = pass +expected_shared_secret = fd9e333ac811ae8be12c052c65131e3a7a32ce82e39055012ea564e10acaa85e + +comment = Rho leads to a matrix with unusally large entries +private_key = cc389888219463a7a5f6c2ca3014accb3bc26f2318f593876de6a49822b6c1e694b7e5aa9140a0765b6334ec762c8bb018d28a99004081256159c836f4f800d0c9aa4a7136fcd89ba7cc1d6a32b23ed181b3fc118ecc60096a4ce8261ea2c0a6ca49baa28b75d1b40215367e6a33a1c177937bf43a70c3889f6aa239e20e499bc7a836694a0bc2912cc7cf211ba20c12d5ec312da2815ef20c8565712b22a927451271040cf4daa44d79705b97993584424e7b3224a5583e5b8eaf640e85015676517113f53a415220fde3638b9c0a38115e668545305ab298b9923bc16de5b9137b30a39a2c8b5fb75e4d1168593a8eb0e067bb9343f1a030e5228bf0b3a49169393cd14f73c2b8221b1267627d80b97d30544b02a4c7bf06099194b2d646596aa439d82a214e6cb9c5ea1ded727c8143755cf881415b6357661a90d5ae759475baa6076eb478a5826f86f9868afc47ac3a02a0e84579a25466a63d933b071213c886790c320416d9422d280745758779635ba6f848440b2489144866e8e018200cb8305b3060926d7e7213089a06d044176b053f3bfbcecac7840dd7844ec29eb17bb2caf321a5b17848c16a678552727a3d70c34f024164b3c4856b0a4ecbc78d345187c6e09f055273bb775078b43ecc534a40e66592b607b56b5f9304aeb048375ac71c30464e979a656f1728a7b700e3b33e5026bf40198b94455d2be37cd65867522b20bddb5ecb7a010191254b8a403f37c4577a613ea30678daab55508b16d6020f074504f928dddac1e8367faf6199715048c96a8fd6bb225715accdcb012cc856a76057b6b72b09a4aeff5b8ba278c54a750596e82bda45be19014e8ff52df181435ed9ac8c402147b539ffd984c291535b7bc8b26c5036352520730195fbaf40033fac450843e808b9ccbf03b40a9ed657f6ac4af8b65b4e389280633d79799e0226b28b356fc2e39f10a80452dc934caac7c3c521f0c5544e7821a403688f08378c3086d3ab8f7e4036ad516778da606204aed3ca1ae8c42e11038a64ec78a5fc5dcd0475429124b5d665e4acbeccca3a296a8e878b917b886ec7f029491c661bba684ac4229cd71373c829055b602db0518a481230345a34a709010a03e4b197273510a0a24465288c327c10c75434d9473208a7964db7792ea81c5fe0c4bd967c3f0c98765ba7d3faa4e6097f09e9bf10638fb900a764e4a0bdba2f19165bd69832681310a7a2585bf06322a3238dd26a4807af44faad999397d4aa14e76c2cad5326ce573d7ca04c03db769dd01a65583ecbbb991e7a31b59238f8741845f1adb5992607184dfa19a9e8840ed9e1622ab93031e2b448860d411a3d239277052cc8ea71046a0b1ada191a020c322d776c6655ae71964d86314a86a47b6a367b8ac5a4aec75677226de0c1864492c88fb70a53187cb76835d5477346646a9da97301156a3ffcc231f9a0da760dac142674e5cea882364dd74fab66901dbb7eaf037008c52073054cc2f94ec845444054058402515bd206d496bfa02c442c746ff3e662b899c34c40900902c4f8ca146458522c6a7af772b2df483f9d840fe07464b0c66fe1036c070c6f70278e9506342663b07529247b1697f6513e1ec8234bc145eba3446eec18b3826b2ae709792648e071a7c4627e4ac7716db5b1d6040ba7b8ac39b347ef721a99c879453846e1aa591b8495e19003df973580d4192cabb72ae2b1f498bae9b3cfffc8bbce09122cd1910a406574106810dc556894777f35316c992f3b902186dba411ca3462b927688c81f7269b7c2770de5aaf90c81f752a3ec77942729a68fcb38a62946c601c945249bf0e280b66764ba71a44134ba84df1400bebccc61456fdf3bf50aa85e8e60f491ac1c1317d831ba5db6601133883fda81115c67fe4691d9df01fd3732b336bbc3899cf067b9e3905294902ca5686480cc94eb4e98260408b4dd060cf4b5344380c89d564b31158ce098ce1e06b91446c4189c6a4d89aa7e81befa900b250a7060406e25725e09399963c5e3e04219d390e6c28983e335646485023312c4d5bcad9aa7ee683b935d71af1908703fa2c9d66c8b6c55049b3319d39c047b5824d04975a9034e8ca1a9e1a5b0bcb222c5b5c848818d14503c31270d4f8446d013d4ecbc250b72dc25934726b426afc85631ca1065ca6e957ba00f1176a6a45b68a5e93274423e642451129ce83b7de439963c0c4e5d8b25f3b74fc053151610b4263725fe51423e886bed19c534165b4cc90fbd67256839b9371290af9853c948251c768e157041ac91fe6649bd1b1855dc417624b8ca0d798b1947c720b3414db56f01500fba30207322ede05612bb6505818a9a68538c9eb98f2b0a83dd38b765891f0d01f1db768d2355fc6b7a47414527c92ba104637072a72a6c0ce74772664e68660c9c0c28347315b17273a6846a79904a04b90a60c5b15973630209d9460365529bb72524404b3d9cacc013b0a7355a7eb2172d317cd356a07e5a341bab7c33db5a48fca4b1600443df6bf441983cc05125f6aa94f114a8c3ccea3f9c498c1126c072f27e97555456114f6bb3244c4698c3f6091864274a16bd82aaf0711eb8c4fd86a11b35b3b8b0528cefc253d7906b6b05382e37428253ebda5b48b6a068354381b24348dec73c279010bd32e41431d139a021a398f0e5c7fc1a98863f069b9d42a96b029455670caa89e0b867781f73fb7549392124485cb032a008d63812f832cab899a8d5d24b403e76d17d6ccb56c729e15abb2e04e32928c9b8971be6a4c70b15bee620eef375489347df7c622d9a803a86c2a9ec5a7a0554ff763912bcb7f57eb8b8633cf6ef39556162eadf8c285b61a53f4837c8c9ef48c3a58b3b6c31b8227c98df0b9057d452df2c258da8a1de1b99449c0054c48a0bc61a2336323367077cee252d366661904b12ea6215b3ba55aab06f60a517704a4046312731325df563cbed805e2c7b2a5848fa1cb97e17a2f926664c2947a2fdb56ed1b3c5e084a680073669b2b9e888ee010410acba461910795958e7c0c98294865cc700315e86a5c54912dc2affc2469244912d8180eab244332a00b7536c4cab62345872dc31ca3c0d2078d07beda4431f278aeaf2482cde53afc56352a894dfe3948fc14956917a4dc836f54369eacd4af052b4aa6b60af5e86bc868be275abd1118a83e5acfdcd4c92a3c2e2b13cce7101a9d303339f0b2dd4a282499579b803ede0b26c75eb8af340000000000000000000000000000000000000000000000000000005781f74024912ac52aead1be2a87e042830737220659467bd06128a096343d5fc975767ff083234b2979bb109a24a27bca17d170abd8d9e6ad3c3ba19e306bce +ciphertext = 5ab063c95a541d1be3fa0744e0db7e0ece17b6b47cca0fa41d08e7969fe87de63f319f80b9a31ff01e203de6e518e62e6133edd108e5a3e08d3f8ae0556cfd36b399dc1ebf3b229bc5013d06d7550512280bad2b27657d3ca0679d9fc62f0bf875dd0b326008a89b4f29e97211ee7ec75108a9e4a320a34daed15fd7ad394a1747e4e35bbe4f1118703c330aea81bef3e3883fd41c3efc3423ab46b553c7587894ad64db57bb0fe4d289d54c8ba78d40683bdf6330ccecbacd3f7f41541f1f2b1a7626d3969df6586b4214c02f921451f6adc04f5e8de1e3beda82e4aebc5e06abb33f4cd8a3b3b5741617b6a385739133cf5b77dd5607a5c8721d5b51c6c0b6df551a5b440082093f49f31910a04e4226b9ae6f41383672e0694bc4075207034e39c40668aa3174cfc8a75fb1a474485e9aff01f3572a5c7e4914e7519344c8ce7b81377d8c2af66bebc558359601b21beb984c1f00564d46585b4bf02c958c6b348642be25119b12f34a6e5755588f649837ba53c0efaa4c6c95d109a4ce1f761c1dcecb84cce8376cb1c4e34ff932408ccd2d06f20c5397f6277bf9c3234b20cedd45afecb7e87793d85af15909546c6ee41987f36d85865c8c1e281e13d9575abb9a9f215c08d89420535f73643dc584707deb7d5275252e862393fb6493f9e126c651b7981f26af8daf978153fa4476d615183bf147629fe36de7cceaa670dab930ba8a684b0bee24b55961ea556123b34e29491704d2122e46bed0f6fd50601e13a5d46c907b915f3b8e695e0bbf474aab6e082d156e79e59572731b48338892f2268dcbb8fc21cfd537979278ceb210fe3efd052365fa249c97e8e596ae6225839e5b8b296770f3b42240b8727a0a730534d0f42f8c6ef148fc04e4285e1aecf060c3666fc17a1ff794f584b26b0b1c41f0fcca249935cd411a151932b09402016a99832850b3f56c4846145738f709f5e11e28a90d9137e4e43f03dd1ddb6565c67c2a138aca59e8aebcfa61984bc7ac13a60ddd2c1f0fa84fcf9264ad5049c888b9f555e024f0fa685474e083025da168e3b9c4ad91f074e7e711f84bb808604114e09d1ceb83b697cc0f045b5089b0bf7381ff2efc08e7316ddb7eb7be47a1d82cf533ea898e668f0da124d2e87fef2b558f877b50b13a08641c74e2726b19fa7c0f33ab213f403c328ea60d08c07155ca0c19bb75f7f6716de89e34c20f9d15ba8aebcb98e9b6461477f56f9c65ea7e8744a4d7306e216f806ea8f9f1dc45781c1adba44319031fb9e81c6d33bb317d959bc53a677270f13d96da19833965aea9a18172f6f975bc4d03036b1239e7c315ecacec35cc0f788be1220c0497844fe7c989fff5ef7fcdf89c261a0fed3915cbfae94b1fba22827daaaaa0f968f1ac71e9772aed587d607d5d3f57c1500b6e08760e0b971c1999d01553bf87f55fbad96ce61d0750d75180623543f40e5b0cee74bb429edbed1b4c2a3e1aab86c8dc7381afb0b9e7d4151a3f76b7dec4199b97304d7b3845788e19126e +expected_result = pass +expected_shared_secret = b4b4634ad37852e19175ccfb5eca50093291da8f76b86be7511379188bc20d92 + +comment = Rho leads to a matrix with unusally large entries +private_key = 078bc69561af0cc77acc291fcb063e1d7c82bdd7cc31d5b44d1aa746e261f2a592d4aa9165c2c3755aa457b886cdd55840767f4fa0b19e45410872cb1db3b8b5829c4ce9b2a8969330cb5bba2397119310fa072b7053b35fb135d04977b9ab4766c4c1ecd9695957473f10c679d71d2f6b57db2ab0726022bfeb10b61807d35447a141255bf5b3d0e3bbf5cc3ae74932d87268e172978d78b99daabcb16b44bd578f6dac130c2528fbc89ffa94b48e6785293023e2605a8533a5ac17c15f34b1e30501729a78d3b8ac6e4a329e1006e0c0735c737283856d7cc7663cdaa1610b1045b7423ca8ccb59ca6b1c482dc02ba117c17588809ef8506f09a7162720142e397c6ac0f8fdb02e4c1c557050af941ae8165ae01d9228f767ef1ac3d72f27cf9a2282a6c379a669d01cc0a6c560b21169557b88771008dad62641f435e0780234e86c1ead05f14c0ad68b6b1041492a166bc4a278b0d352129556d55f37ef8969b596c5e41f8597878c8c6c83de675019c022314215eac667a7b559146478a4a5634ff193f6b83673072643efa59c27650fec168ff17109577083bfa8493f38301528f27681405693345e523ea4398055606d4ccad9df967fe59428ca7502f046506756a6b9a78182383db4baf05014fbb20afaf148456126fa393abfc480edc92465d93aaa158c2a8493882b24c564b607cccb2c8f6cbb43abd722c74c2c63230946acc091c48b865cdb33edb712c670648b07c06691687685218ba48648fa3054ae7a6a663aca6aa4e66506516100c8f2caf9c0645f2554c10c480e798b9c96756e42cc8a7f626c2759d21555342548e0490420df3a8124b0566b1804933b68225359cf66caa599c55573b70d488d16185496216cc09090de382d570795efa569aa5bfa8f4a60665cd30d63bb36cc5ac050310ba9bbe4b3af2f9400296bd344cb72bb623c757366ef1369c968578eba52a092dfef34aadf552a63b1495a5b78168cf6e58b218a3ae64310d16734d5e72b2036bcc001ca07533085548809bf114a092225aec9cce6950a953773ee37ad3467bd5ea0b4cc4c6b0695a774781ce17004cd48e36116776db19565367c92a94488ccbf4ca3c3960524d1b13d6f77399ac625de5a2d09954cf867011f79bb4c3682cd40f133a9d67778a24d7cf1a5b71b7b81dfe335d0fc392a8b12b234950ab79cac94776ad1b713e99b0f394aedce739a15334f19042f4861e739c839ce07da145808260b159625b5a742258779440953c743c591659b9d982aa7da028c7eac4390b47b243ba23e8ae4fd9c98042a0c2d25a6688c9ec774cd7e95899fb7f081035b0c4217c2903688ca7e4466e66ac4e3ca938fd58b4d6bb732a36aa8e097fd75976d1200d61a5c988c12702698b1cfcbd93157d3d1c6e76d316b00b4e462588bbf3c480d8374df3cf66a16f9dd2ab721954e02a9f8eea4380c381da230f10c2c7dec02b057177e157cbd5304ab1d8160a323fd5892fe1649c2e270dbd3777035912dc0802f4d18a56356b52946f30c516838028f7f39cc22466ed277a5adb6864972e1063b1af0709dfd60136b16a3d6c863a68895677c488eb1d879a69a5341a695212066ab848609cbe3317b0abba905c1559715f25f720b7b745a52332355154e60577e598c754b6346b335b0195ac305268bae78bb4617807ca4666738ca81515bb041d43a4188003c52ac4ae4b3808d8c755d3e99d00537249d39d4cc02ed9f98ed4106895666c47538f79e30f5104adab1540a1fc58d1a857a1a4611257be37e0327491aa4b543aa6322ef7816a5c9a55eb3bc8604b15540b62c3405b861a84218211c20bc3d35a8a506b0153306fa98b9488a7841d85197c170f84c380098077e42cafdf1913df369f37f3291ec47289710c57f152b74572c23324f83618fd281f5e41976e77097a570a991b3bc623ad6331a1bb34673b1c328319758ed731ca2981b50a5a2cf8c66d31b10e88c95ffc27c3b6aabe8b207e6cb4373464b1b83f4a5a9806449bf7fb622360bf9f098b56729c5738191d57492b377ca8f989a87922a7368d724b07b7e36133620fa0735d60f5be8b51c19ed1655de5108681cb27273d511c643b7867516c2982a74f62e4cb759bb1f5f0808cc90e1baab60365722293bb07841803076504d00e6fbaae853749fc322e3458810ea41d832b35bf05a10e62a4ff8317b506b9af7216c445663c9061cc62914b0b72b5989d7d9c2b761c2fc5a28b5839bee5596c0de25c10a15776447e17770edb666249a2310962152059c5ed5738741a29e899072427891fb53606ab8b5dd06c005d239adb7bc368b10b74508c45c4aca726fe59c7729cc1ad617236e1b75c760e47815df33297c084429ca371c16c5761c9a23ebbcc2cb43ae9734ba9495d5a86a89e75aef50b9e73470d8d9974cf27a961c0cb2c180ff36140818b005f05afaabc86d8b8bf5c2a62f0632ebeca0c9c567514c9311ba6216fb13f1603c77656cced520d977ac75031044c8790d1b4c97dd38b2aa43dd8808a79e406f8e01503db8f7b51cc1e4265ee830461f41cec398251ea60d2c573ec59b4d28b09dc9446bb972f6d134e2e192e987153b39538e1f631bd81b2e65c2c5c68a96d1b78360889efa4c692b7cc374160e8dc485f47a676d77706e047d3e717386bb49cd942e4c05374b3a1cca148535a3ff1085102f4a7077b5f9c7b1a9ed651edb32691037f9388b672a662bc247beed215d51b414d3530c6b0631999663fd7c0e5da7e411c32c506476fd08a09d499ba3c27bbf6a804cc7e8be5c1f3f97d7aac085dbb3bd1076a69db89bc990efe59b00ca943ef8560642176e926af342b48e8002f6d1aa99b58cd013b03e0d285455786b54a4be3c581419730081361c04697b1b2c07df068621213c8ca6554b5982d5a1aaa113ed9343a56101aec68b838a37ef2c8a15d0504c672b278556b40c766c2066ac995caa32676da182545773881545cd58b71d3d7a02a209bc7407f420a830513b9d9d6c93c56571e42c8bf154afa060667a46d13cc542429c9d1a35be012cd3c9abc2bb7484fc89a4a83a20f7c2bb088793dab732ff370cbab614aa851fb77ce176b8f806c4f2e6068235b93d08c39e96badb37a457e8a790b2b8ef00b0b9e941592373fd2caa3ec3477c6c440d0daa755ac0ad2285754ac64b0852086112b0c9794f1657916fc173209a40425afc9b19946c529ca95154f24ca3cda5f9547c429836c377123c6ec0000000000000000000000000000000000000000000000000000006f8e54b993cf2cd10ba4e61693d9aad8943af37178908ab532712df5dec4b908d48790195fff2c19f221b7cd8637576cec18c29a4a51cd07c82eed4974c36e8c +ciphertext = 925fde875ae198cfea88c4eeb3a0091897e25a793672df1de3f24ab4fd3edb2cad0b07e698f35dc97bfd1d551fcace3282c8c3d8131857d96ee9986da7b79a02ddc6cfc9fb7f2b809a8e5511b1c1256dbab33e7606d8a5fc048b36f6ee53c7f556efadf94494595a549ca260ac9c45bf9962bf406610ca58dc286a9eeccc447a767b6db3ab009f5848558acea4503de747d72d43218babd6f68c091b4581f4e41f2e850047f5f543a02407e7331202b0eac7bed180061bb53f4dd3504ccbd3f298d96b43bbaf8f0c2545be54c59830e1f343ca88bb9c6812c66bfbb59a6d68298985767a73d34fa69b52cea98d95d8305f97c4d4fd643b56c60fe31e3c2ee7e938ac2e4a5da2297e670931c1dea5fcbe9cf118c62a76a461495f10f640fb416ff7bc2478c0e8a1356bb840345f3d43476bc4cd990eb7f7cde7ccb96452d055397ee402be2ce395a29a4f4061ec3d85b99f086341441022435b636028a1a04c5d787abe1c24a5a55653b7063b1cacdaee40ae0de77b4034b9ac0e860a90c8834b352c71e353c02b1f46b135fa68fa7a5c1c719896987d79f3174b8d0b0c28ed64cf9f2907924497e35bf519d519a9199a4dd68025992c6f466604bb2ec3d7b13eba76e4803fb73bb125b83413998ae86691a0b35c0054e1418898f435ab26cc12a12fd4dcfa9e80887af7ebb6c856a7fc010cfcaef9e1c5a4dc24a91a622fb7307521faff0b8e8e966b7b6ae849ccc75d31c8d700a3b6a9c3f646b2a88d1e9391c2ddc6c9ff15db961874c87dd94bf0165cfc8f719806539a8beb8e28350610461b1252872f0f3ac273b3366abd78d9fe8868dca1a5eecb683ab8b50ced8cf4a5ed3b721e0fe6b205fb191985ca745ff5dae0010493f8296b6586e1c96f7f23fcb4ac4dda15eab811107c977aa0a16439b06986a9027640cf7a01051934dfc758215d22c6f06866d5b871dfdb6ed240a73dfde43f7f89c0ce6909b54b0a633a25f7253c10906166f81ae91a1419028d6182c1f277dc7872b824c7a5a22bc7afc02afeaa9ba4c271ee68882397e6cec34a955cfc672f4e6f5ed870a35ebce97f34542cf0a162938c91922230ee3fe9ed9a166a790ccf450b80cb5f483c3c6ae5b2e52e907824b45e69e5ab38226cbd6519de995e1a62a910fd45ed189540e0b4058ff01edbc6ba4eebd58d55c0e33702de299eb53d6518254b8471f282779533eaaef90602e52373be8b519c56a2f6fac0953c0f84135715c5674e45d15804fb94d9e0525ab493aa625fbf73ebdf74f0a1246e1eb0e4e2e261b24ab81d8da6e1770634c747542450cf0a2af23507f8b6766a16dbb2e67b2c94859228b91eec6c59f5a271902b340320412ae947398ad102073f8b9b8c021f81f786622c3483e61f812aa76232e6f9453eae044c5e918e6e4e0e18a78efaf6cb36f7b75929d0036c44edf928d6efe1ddc87b96288c7c624655d302b98865978ed7bc779c800e6113a0484dd225aef29796c8ba300b3f48dd566fd877dfeb5d25f96da5d07e643c5d +expected_result = pass +expected_shared_secret = d4b9a0f77a52d4f8b9c95951257348d1931725c27eede694ecc09204a931daf7 + +comment = Rho leads to a matrix with unusally large entries +private_key = cc4a14e75a6b1bf87f11a240424645dee23657db9819ac274780c2d7d8ac64f2cb82530b40a078791a2ae70aba868253bdc3045b6254c4e29024894cd13723edc7461a37403609b48f79b8e8b1018981bca9f68031dcaf87528a6b065d8cb83c142ba20d68a728a3866ca88e6836cab209ab49bb234312916e432fa51152c763a62cc53da61480691b07a073be74aa6c2b88468bca8302a23d1d6405ddf4aec2f88ab055b18e2b1873862af6539ca83b1c270b6a563cbc7a220cdc8106e6e5595d63a26c0cb86ff11b48066721634b43b361b57a5b4ddb2967d232d34cb750026b362cbd20188260c6a856e9493ae09c462bc4c8663c7903112488b06b2a996dc6668e382e9cdc93e52a1a368b07d8388c9531afff0cc4c07ab423bac717dcc888e213e3a75d69a633f49745bab10f62592f59d53ef19b6a62f0b24216aaed9c91203b7ee65b9d097cc1e2676deeeb576ceb4fa4a867ab7310076a912a41292c658e8f75a98603612558352a5b7beb404fd2bb6de18c7ac838464b6399182536509624e1e25a7821b71edc57c35541cd115ec52c13a739c3de231ada741274272383cc78bc9869d37282f5980209543c92b76ddf99c3d45cb7409b5e44599b75412d8bd122460905c250a94dd4052c0b0a91c9a906aa3652180fba9212046b4f7ad14f7c304780d553f19487b8b7413de732ba1296b41a2d94983d4be93e540a4a4137a030629e97fa640c21ba5b7b5537a03a2a958ec3a888590a5c14a904dd74c83631264644cc6689a245f833530124f7d10e2596a8be227f270941faa75300bd731c145f781cce52247418595ef67c94a170676cda269e51c7ddbc63b6765b010aa061cc576696c84345c35c491d3e4626efc8b73dfcb481c11bbf8c79c6a3aa4e54c43a44141f5c35932486320567ce37adaf5241bfd8c44ec140d30823b58223b02742f3e2bf5864756d528ea36348c1c2293d8ca050b6307d71a20a036e0060697b58a0ada53eee5a6990a9cfe283436cd36a02dcb1a2b7200a267c3f133ea6423bc001baeca953515214e2766f066cae531212dd3551e22bbb1c705f21753ab60a70f364bf1949901d9a0415a36567614c1aba2dacf2c5435b4ee66193c5e461596719790aa792d5a09ac474343509ee36ca048751bd4b0c644b2b039b1320b2294df814b419c3ac55541be5cf4b93593aa4c099142de9e13699a40709d70070aba9227b6c14f216d434c9bc16112b8b4237f838340a5c317a618a91170709bae6a7c13cf96851f72a8761736c452df27758afa4b02fd55b3493b1bbf96dfc45ac743718978b7de8a017eca45dea633dbc417f856781c856c87516429127c6a3d335f162ace0982235ac79ba0ba68edbc1eafb9ed7a3597ca7a612a9bf3ef2b0d1d7c238e98714a434b8b08b35e3885e007501f9bc06e841921521d47999db3ac3937468a54b95b57a2bbe34aeb48ba57f0744021bc684456a8ed413b9192057eb77a5502dbc89c5964c0383b4c9034396da209279199ab5830abe9386b2e811c222a6ccb0cb23732a95676fd5c0376505943ef8bd67a95defe0af7cac395a743bdc3119b1a74771343bad21c53ec80cafd7548ae310293027d62960038c5d80656805b427d0b9167abb3697444af88a0f3eb48bf658be44f36b01233902291860215084ec7bb3e170e517c65c623ecf4a488f69923f9045ea18334d5c8ee847381b5a8903a6233796b1def36e46d343cd3547f4a757d82c262278432bd555fb5430e7f936affb453ac1a031c70cb1b3a8f3762dbe226461501d13d10052fb621be30b8ce63ce93591979863816397f0d198a6c534b55213d778ae7bb1a20ef1809ec37b08382c43e82b4a758458d7758d23a350538b3e524d27c9074d1cc4e3e1a17a6b06fd71178c5b18803b1c439b9e903a0d63018d2f765fa7426a0684793ea789c30435657b9aed58886cb8788e14426ea0295da18293024eb1a39eb99a20619a3e2db48a93eb90dbf42b84fbcec1f0b9571946b6f150ef5a672686a30e52be2d536bf3664550f60c99a89b81f3c911784d8a371ebea0b97ff50e2af68f822a72e9a76cf473bcc1cb81fe2a03051771b1c91f1e1a444ab6119c0a83b25a434fd598bc767315881aef9cb4d4c51ceadbb3b1a1142e0b87d5826b161233ce253d2adc9a00bd00e3cc21fff09abd919b54e09ba6b505601a358e50593dfa117eb2b8d7458745a25e7c7321cda0c432aa5bb41aab60eb3dc7e03ce4017b245809a534c3dfa49e97f4474689901e814a97fc0892ca04d0c00e3dfc836b36bbf74256e77525a031160fb3bf8ac31502c049d0a264140104c7488e36a46d23a76f4535b5902677cb98a5abec57b9357b0cb3b36b68349b273a2f8396e6c8594b4a32f0aa8a622378b3ca0426f44443942c02162907b2651ac2168fd1279b040192716bb584211df4ba36cb363b8c3adc39b410977ae3cac26c21470426837a43b821f65d8ee1950c87b4765a034aba1a35579f4148b8c2f39949812cf9d850d5e25be7713ce62ba31366737c03ad45f23e9b226d1835c5ab01c081063dc193630d72821cfa2a56d16108c40ffc483177d075b6a7a1bbf5cac7da0834d755acd10b9b9850a7c97d90a1061ce94efa4b0c0707339dbc7f160a45eeec022815a4494334254c08ade388c07c34e3a07e51ea60fdeb9b20b4b9afdc6c3c2b63e872aac9b2a90b798bc2dc8d585c69c1b33c1d51372c583e835b9ed561c218a2968c044051f8a969a7b2db6a7031d20cc9e024bbaab4385a3ae13ca264c25f6c5b4170b5c0da13044664a10f335ae9045bd6319abe139bb2b8b635bb06e2f48427e256a16a0f71f119230a9acfb19f0fe07c71828063f42a844a5c703aab9a844f689944ead511d8c97127d99429fc87ede190e0fa002261494076b7a10496dbe12919f585685733ae780eab3ac168287aae3842cfb637a94483f68170f6a3092d51b82ef10496a6374572a527aa7a7d1a99315953f625842ec0bc8851180b98cbe411453027c9b8a4a07fc3bbe32b897fc09e5e65a0457556a8b28e5b7c8b28db24e5431893953c912c195ca52db5d125c3f595f2ea75a63b6c83c8cbca257824ac60ce16bb5be02b30488974a22a66d37b19531e3cf17b59bb43d738cea25326dbd6355243ceff3caae98446927351ff623260472f8c7a715016ca5480af5cecc001c6b65f41221b16bfa61863e225709775b5e6393e4b71920c0c539c6bc5ec5c609466000000000000000000000000000000000000000000000000000000313af29c47d66acaecdafe1b91b95ddce43b0cd52be1d1a84428587728f01522a9e4a0d3487b6714e18bcc9d1daeb3127164328a19d5cf60822f3fd37a24bbed +ciphertext = 7c06bbeca8b58423e2ad420ec36064ed42c881e3655668f8865a2d643ecd1a4eecf915b6c64b37c98947f06c3ccc8e00bbd16017c246db88cc83f12c887aaad7db61b4d567c285841689169c3f928f1d178a0ddae50d8c46cfd95258667d6239c300595738defd2e806637ca46baa4c6c7b97f1a9b47d53cba9ffe074f88d104c4971d250d085b1800fcbd91584d8cc48e145fc81438290d74765e7ee8c1605e8048b37b9d22b050791fe008b9b84b7f23b0f49955e32c0eef78d7a3a0b2effe8b37d124e19d4cb6f6914204598a525239d9baa116e1c9c39c47f9f37f965941b2aef8519782c65f3ad3a6509d1e31e7efb67db21911e4edeb1f7e9c37b3f852c81d63a95e4775e3f2a8ff315a214680adf44d290e42ebab8ca95bf471140b9d7e03f5e9f97864289a0ae8c9a105e00409f714e413b69be366303b4a138ed51264ab0e5cca5f6dc9387c6608109e8859893efa3bc7384e9f418468b1078807dadb768e254094039d1b807d67353c8e0b5a03d28b8e41ffa0eb3ce0837a132144597908f7a059a097b79a1bac323757324e907b445d064e25c378d2069e7c5d671036871e4fe36705747635e40c6e835319e3ff81714cacc44515d671b703c5581dc76afca0b881f37c1ffc93f2e4afab1e8ac776ca883f3adf7f9ab99396f7e19541c26342a7d5618958523b81871326c357ad84ccc6d3574d97cbd875524e7b08a102263d80f318a48e510c22126568f76936c904c231700ad042d73137eec741c827a082de4a45d296745c55b8367719dd08b8295e38d8d3894b9f8e2f9b483b266e1fc71d6374353ca7d9ed1c6b73ab5a42f6abff7b2ba8fd484d1ae6928b5ea92ea3577be01dc1e88abcd0886eb771dca4d36e91c45bca4807c89736b7d6a927cf64b22c5f323077f5488f6044976f310b4b99f7d486335dcca60571157ac0e480a4dba79a826b4bac3dcb7327a33b16381eb41e1d39915e91a58750ceb71098ec7f1a2d7e44d4bab75bb7482eec277df206502c497eaa345109a145a4da6bed1900b680ad12fb028d33563bfb204ecf66e6ead587c5fe27f8a2eb0e27471925ea0f35eb9d5e53ef801eba3acaaa7790b105eb6128ace992668181c1d7cf203afdccdfefbac67dbd97cad05d499239df84e4cf7372117932c973957e5c70a8520f822be430758990296877df62069d818768513d14df0568be8e63e123bdde35036dcc69a98197f52dfbaae5e5e0cee4a48c67fdda605dad8a27651625c2b35e81dfcacd2a41a6d17f6d7067a67faf2479b3868673b248270f4a2d8ee26de9c787ce966ecf186c1401ad9d3bbf2c43b1d5de32bdd77f5433f4325427254a13985d733ab0863e62a4f3d484ab3f5d3b88f23049079143b058babffc8367cebdd9d2468d7af782979a3ef12841370da6ef2db03679e6bca0db72166c361adfbfc02234119abaf98d4fea8ddc6e8490c2fb5a1be4806a61bc7b36884cf4631cfd53138a23fdda11e597aed323748314282672473a1819ef2b9488f6744544ad +expected_result = pass +expected_shared_secret = c9d0cf3edb1172344364afec3615ba98477ce9316f92ca46ca5f42b73553a9f5 + +comment = Rho leads to a matrix with unusally large entries +private_key = cca22002e0b84e0c0fa98c902c2a30f0d9303a411db91a26576834d4f1645c181bba750c42ab6bcf401739f83fe2a4a3aa1a3f5917418003aed863875fc044dbc99c70b27758389fdd3cce51d5a13b21afe1219f0bab5dc3b15952591e6f80068b30870ed644de082476e7b32d3a531ff8631914c7a5c106a5acbf8672ab4a304afb71b1672cb281438f0fdb1db0f52948e8b0a1422ba10ac5e0a480e87bb844072e7a134dcce36f27274775fc6a8bc611b2a33cf85a4820e18b47b24188030fcaaba998d84a68424c07f4503abb553ec33b4be2af3557aae2797649da014dd0264d00ce74431e46f8969276b24b359c6750c5bc15a6318c2d06898ec5f473380a68302a91eb562fe4f10596012e5efa83f4c55a19912978a6583e4a884e36af1b9367e69ab0566c3cd8c34eaea615f49c094bcbc63d52a21d74c02462cb0bb7c77cbaa03df988b60cba880771a7c179315a9f6ebc6e9b8c90bbf17f737508b1691ef1952363e9499b5007a9c84838c2a149478e4be76c0368a8220b9a3ac68ef6560dba6b3f68257b6719551d83c38f73654fb392af0c1c2517851fc160c343cf826aca2c5614726c774c758e1abaa9ac04ae0742799060970909cbc2f78ca739c71bf6528f0695ea6175a4ac13555c3bcb9920bca3a37d363ba622666e54a4e779cad5059612792d610257a689975fd664dc5081d5ac4586c60e99b9a2a17ac612e5a794ca4dc097a71f72bce02b4907d69d801a22fd7b88f9e4ab284076037a0f6ac803bd7b243b835e51873919d3b77de041bbdb9c2917338f0c42a54ba6f5539d60e827387a9e7c156155d693b85701b53278139b29858785cb59788ed981d77556d27390285bc3f9408cbdc717895815d31641d0c31f2d911515f36743c40f4f3517432c620892149b518fecc80cd2d14c99730e0c940dec155930dcb5ef861b7c80b55c2223f7066b625c9fe5f0cb04f0bcb880119de142ce511affc01d483ac8db8b73e504b242315533d9c02cb64d15445fe32bb0c8e19383f82854981a9ea465b05c77cfd66d97a2b262bb37398cb4654a0fc8146c00b7608f061a216b9becec17f686b93d88309a7ac04c2447030b41ebc6a95fc52466d36dfd461bb046172f3b83fd10bf79c281202a60aed8467748a986100b97742c8d70c8de523c1d700489c391096c1b92654064cb7e35d7b25f29818ff39fa523c88bd69b8cf41689a414288c492f2a83f7b34a4d95770e6144b7731057c73a077a471e7b378fa48464c426ce5a6566e7c862131ebd5a1b3df013641a878fd702d167ae3f369361666514d98f325679c22aaddb56406e148e744960ee1395866acbe095542a6836571959a80238d037260fa053a52cbbc2cbc035e78fa9c306ebcb61ce33422584009271835ac3845524794f18bd7e1b4c034832fe68ba24a162815404f65c0af0944c9789b1d92767268c801a0444fff50399b3a192131e965523bbc2c75c286c96450c3f0733458bad7831205b1b4841a617626b4bee232cd1f220edf53b59bc213a055d956591fc3518a1974582f79a66dc8892ba71ccf7a5fae1c01841428525c32dd2b433445118559cb5447e3c851a0cb498cf99c2d359999fa3967dd722a23522b0d8cb522a67d63a75af305c05f3659bc496f1c47e410582a0e58bbba80751bb2f5ab71414051627f46a78f9708e3139f8950b999378df4709a08b9b511982ab1b2cc4d51d177578ef263c8e12752f914733023d9e8068d4fc1aac34106fa72197f6b4e4bb26ab29ab64d7c848f98ef5557ec2b35edea70b67c084193921d8cb52e132a24372be7046aa2af66696007e2e0830df1c7b4396bcc8f27aca46932c463b49db0ed88882f3a45901a4b96ee3b74e78afb8dbae7bc653be895179f208c27c6ecd60c26e54152aecbc13bb5ece39840574c56fb39fd2385c76d62c59a41b3311702d5a99e366467b6c4f6c252a95db32e5096e61d1ba872924d358b346dc099a485c3df72a94e437a82a6cd778888995c473c203e091309ba42511950c19db3acbc5987259bea952b5a549839f197d7bf64ca0772cc1dc89572a0e04690fe651a79ffb3dc07388c30c06711c6b25572bbc83ba868a379d54c6439754bcd67c9b0364ab3790967a062948084ab33a80ac5971fa99830aa7d1e9263e7087af67ab6a83ab34f405dbd72b3fe46e9f2114e26cc6643b6d3adb9de63090394213e72b64ecbb2242266139579ea9cab2e51868ef82ababaac38e7ca0b9554d665365dd8b0b58f3020cc9218b866955f54d9f7b9af9634ab995a0b5e234fcc78cd1594e1cb8a845ca0cdbc82e3fbb35414c53423b76875ab267a702d51710149061e7655a0168695053aa61b990fa9439883640e7600345033ca90678925b1d632962deaa0ef5642b870610be3387eda90cf608254dc2b000c06632331680e12e9b277597d07633a31f6445318ac7b9cc1b087cb58bddd30a07ea6e1b1429950b7e7efb1a6b88b037c92cf987c904268ce39cba4bd3c163f5a8bdb9698488152a18b02bc98a83fb6c28a55a018b48979660ad5b42281b8745a4bdcb02cabd16735ab1523916adcb031e34ccbf4c50bf61bb7d562804d4104d3f6ac183f447e6608acb0bc40a34ada4897e9a91c542571877931864b612cec01c88010cbe039d42540835422f5900c944c7025ba3365543536d093a68c27abe1175bc227faa590f8fb8ca9ab1a87366574422379fd8659fe5bb5ec76e179666adebcedc7b54f1aa9388b2907a4ba5c48441ad90499c64a57768631d4a961d88976c816adb897da7715a100c75099cc122f3b1df183385673a3bbc98cbb0ccb0b090b3517993815e3f6b26b984bdda32c11947b2fa5411004c2c41f2a646036b86bba618e72be7f97ec6369af5ca2ab2dc9493d9078a0c8598841385205177c80a3be42a31d1166b02cd1dd2871148033c794242962e8645ae2e4867a3e5c74f71a1d978379ad45f7fa5c70066cbfc4cbfbe05cf23612b2dea551cc52dd90a8468ec771ff071371544e96400e288a82e9c9eefe807d6f4903ac567741abeaec9707533b38dd8c4366bb33cf86f77272478e43a2d8061293332c8d805a4516238d5ad1934a9683655674aa6b6d91610d4c82e966d74c41dfe7ac18e993c22d59b2d286a0b5272cd44988510b9b342405757a25731729e934c58c601f5c311a244a24dbcc772088a20dac4c8410167304fda18445f6c6126b9645d4042d6033419d246968848e1f5000000000000000000000000000000000000000000000000000000ed43f6cfc5464d2f56a817a3dc74b5ab404164947d8c0792f6bc9bc00bb4d20253f53a49ff45b0ae588d417a63a599670cd391c5e9885c972593d09350bd7523 +ciphertext = 83ea5ed982570cd981b7430de924469d4e2faba68e03261a74f5114ab8c448376cfcd1b9cb3e72bb031bf0fefe772bc40888abc6acffc1d335d46d267acde2cb89cf1b3c67a139796d6a5763805d5edcebb81070b44ffe021b6c2b3c6c3d5dfb6d9e546930223ab0139990c6c5d6257520fe394a3aa30c6a71d47f415ac86b68eb8c83b131a3c5cbf051971fef5ef3bda355d3868e71ed8a0e2c6de8a759bc0c9e760277cc2c04c783d29d1ad3d3385accb85cc88c39bc8348f84dd8c714c5feda50b0770414a333136d6678be6ccbc5df488bafdcade883fbb310c99cc648493aed72680fe1e43c0cf523d3dd06417d29dd97c98ce53089505d36a476c0ae6d89b165c3ff6b2c62ba954fb81ac5782ae648a6802bc057c64fabd3726559ba79de9c144aaa525f6a840ed55abf21b37231c6c4cbb0110fdbcd0004f6f4974ec644c33a8aea34ef4a0a146f7502650c3def5a313d2f309cb428880502d3bdf39196a99bee296f9231d87972efd1159d3cf59bea05f0d0373a0e218ee5e0528e1ac7132440980d1153b9423bb2e099d05fbc8241ec1f316bf0add575a69982f546e99c64457c12ac83951ad46a5f024f6a61c91b7d3853ba1fa41d5a95f6ca811610ba3f32addf011ea4091ef217cdd126ec5e45cc40ec6f1292602b16c02718419646370e5b2c7c55c1128fc5d6c767cc75248b79e2379d40f91a8617e8a3db43c42cabb5cd39a7a7969147f30344c4b03de7034b12d8a1c3639697c97c4483e4191ca0fa81d8659f40e31b899b4ef4610644b1314ab2ef14b8dd8dc0082826fe65dc17211572cb14fa376f1b1784a00033c8dcddc44d6a1128a200eea668b6516ba42585cbb2e2be2a42148120013d0a9378ed7c185071fa8fdc09102164c63a665fd09c08d34104c9abb64e394b2e2a00dd834f7c7f5de16f6c02906ae37acc923dd76e530c78f2143396bfc371d14e6c48bec072b6b4e18eeae967456beb3f897a06eae17de174cf09be1435e691350632c0b1eac69dd66549c1d980fb147fa295ca6f21b5dc398e63a7c4263c75b55c85b4f38fbd7cc0fad84aba90dda1f2c9ca88d88905602096162486dba1ed0a8caa6b897c99e25934152a35fd0d476de09fb211abf36565af3744f3fb737247f5d8f172fbf438ed04422a6b3e17bdfe2cb0f09a1d57f1f1a113a768697f23d61ab288f15abc760feb0f5c5d4d5c0b1c891d3dad6089a3b7e54516b8f9755d38430312cf17b21efeeecbfd2719b62480225b9b3ee8940b1f1784ed5630d152635a1233acdd16e5489a9a15eafa7bec99aff25b18d9cac1e726c9e424773a7083f213cea53dcd310b0037aecbde1d584657f32cf548a6872c6f5a1a3a70d4db29ee3773291c94b00b5a596e1691f7752e246ca0960561cd233ec7d5f54496d34ba65b359a856315f02d16c990cdf3db2051b17bf283fed1b808ac79a9ce8250c806896bf75f2cfe76465c09360aba4c9688acea341fe755363abe41c0cba3ebad00c6c7bcc3f7ce091f87079f60094b92 +expected_result = pass +expected_shared_secret = 4bb6a6b27596869efae3d411c69c593afff99b1a703ee1f4ff3e0e7e9756e75b + +comment = Rho leads to a matrix with unusally large entries +private_key = 16997ff80976d1506b23c012e387ac6ca0a792f7481ac3c9775317ee3ca5267bc7180ca884d28bad6b5a05b045f33a9b975c6c98908d670550b874ca70a77424e48bf097256434b9d9b96c8b8149f02ba5bde9b813eb2b60f20da4440b4cfb05716bbfd86255a1e82941d2816caa7253e7368a4bbf4bf546f40b1bafc65bb994c34f7337e82818021797a431cfc664699bc22b92561fe3d1cd6306b89a36380920abbb466477549d1bf14364221c10f51fc3f7240de4c99b3bb3eeb9ac1fe12bb7c97888e8386da4a341a0be8f78a7b7c49f2184376c3c3784289a6bd9b6a03a110c228f72939b86c7a87dab3e093c0ade693a0e5331c48b761b070476f55cc45ba1dda14dfde01a011776143a4d29d48b47b0c6cd2111bf18360a7438f384a28d772177f648773b961a86637c946d7981a6b9f571a4c29aad07220fe081f1f18700f3c99ef28e76819f8d7c4c43d754cea21180c43357f3430bcbce1fe8952c691cfe9a7483026386a479eee4025a838df5c563b9f5a1882a2d7209a68d231ee82260a7eb4fc157936deab52618cba32772fa1440fb675220f4610d749a5b3b142f31b404d94d2bd816cc4773ec83aa1445a37b361e52b10960827e94171dce3c12cec80a1ec65aa6f117fe937673a78cd7767dadd3cebe0217f13c903ca25d6a681116b206acb46949b18f671a63fd2581a6c0978738460cc51df3711dc1215dcf75525d30559ab6bc52e16fa513753454888189348f045aee8a32e98cb2dfd708e7d42818115e5c61711a0c43e85a13657aadc24b5b30a04a43cb97bafa433204c18536337758c0db6154d4fac670fa3af148b52f24aa731c31f98464ca9bc975e97fd665710ee2c56b024fb8d7c7f4a20cc9d510f8eac38f96129c97b17c890417a21465d05abca02754ac3614e964f1a24393d05ccf5cb9500852cc9231656ca899f3538df30984475209f84ae8b99983e844b06ba4cd8a9640a513cee439ae13ad57d3846aea4fa165b68c6c03c05c835bcc5a63d45cc5568aef94ae7798bf29aa7f38e275c902236e63872a274e4776cf1928c492036166d04eed9ca64aa16ebb4b11fc3ba802c6b249e4b53f90112b587d36c6bfb0733a2ee3003419026a10a4c54c2be294b2031a48fe895c2c9920b3772f127338a865a82c3262dabac113c235d433b90d401f5557bb1bc68359020f75742c2008c2bc8862416910f53772a55376ef05a5eca853eb1ba5ef841f243b8d98b11e94483ad7e72fd7360a3641159e481ca50971a6e8aee73a0d4f24b25430ccc0997c631308fe2aaefcf79af5d2045932043d95933919b21ef87865b8550742a513d67af756c5958465f582983a777e9032ac43164e552358861a0ebc458e55865fc3545fd01b0e7565877ed3229f8267369c319abbb017a87ca662c635519ff418682af39ba387aa38ec37396b4d6ab505219314f4448d0f572f4330cf33fa1369872649c922bcd228c294b3213a216e59752072b8e026700ea63061855be3d6037c0cabe0c21f5be948ee4b18dd935ad358a5885a0331db2e496995bd47c3ff2b679e0abafc02804b6117271a2b00e33bc06250fb30ae2036716d30a50aa07e45f244e1f0100d749359b479b444b510d9b6d89b7001b237f4a34c57509f69208c7e6b956144bedc8b2d19b12c1baa725dd106f5418ed943370050808ed2636fa634add059541a7a8c7976b0990e59c20c00343d1c37bc3ab587e312991bb88a74227651b340346c58bbb174ac18c204f37445681bc5905354d834f86016d0921219fb467d829daf24901815666d664b8c4aae307485cb95885b7cb9125a14d4d988d3a42c0816ba7ef14de9b622e08871988b8c02d857626b65065551d5bcc81112384f979cd8d2b9ecb55c6afaa700e92e3ecbb285c01112a19cbdb90b8af135b235914c901e2314902a43c939d065481128f83ac801dc2fa69c912f2b69189736d72414df12646680c9c858a9afaa28b994531960b0f2b82fc6b9c6f10706930786ab5c6b0da61ae813cdb7387c27324499b111c6ca5767056070e608cf421af52cb45a842da82560dd86acf45a7e70245e0b535f7559a9fceb9369c44032c09302438cb4670925c7a831d52f083a7919e575be844d9e6a009957c15e6c5f84f050cc4801561876f9f483ded505b3c77a4a97788358801f012b59d716fed55975f8abd3464420d849d89c16dd2a95c372cf631a93a8897ddda2a038070adc2a97b5538778c0215cea399deb8279b2ade6c5ab84bbc8c6e181c091b7002a4d5f395bb60c817e03966b63ba76e88fb05b79d126ab0975c995b5bb2ae6550af78d80b96af40c9514f945d72b0c9602412242c81b60b2df97999fbbaec0404056195879535041231803aa7cf064b5fdfc8b86344d65eb30e52cc0d5b86947b8051ea93008d789914493b58abbd5395b657560f5823c387574db554118d06b26ba14b9660b4b390f8b828ba8a852870cba24a114a68094cf0168b721af8f0998e599b5db2135a3e9360b5754dd49155eea830f0035c2c116dbc9039cf69034c505ed998f8460a170eb5f09786d902664c8135ad77101d0b802248b6f3165a847b5c989131d7ee3135cbcb48b3cabfd100074c00f2e7bc85d4c84bec8980a6920e6f318a4bc805900b548fc7d98316c1b3c3b49f6c5d90595ff7a7b56465385620544aa3f39114e53581e851849726023d953b5df56b87be98854b253a39297f060449fc1c02725c3442a4ed8624f7f6abf3854cf04166b24c3b5a38358bae933ee4777df09720415314b152efc0b175b664c0c0a3521cac1817314d1e69fe03b351fe211c4c44639622a73a4547ef52d46b033aa52a79182baf49a8808fb259c048a04cc03f8a1038e9112eb30965c797f90c277b3549df4f757526351bd1a100767b4bcfa7489c17cb181b707986b9af85e766aa1f99b08aa2a7bc8a385d294277cb00d705b4ce2583e61c16be2b18445d051d7f0cee51703db3162bdd328cf0b0b24a424bd830c6574091088ab746a291c737e8cd595d1b51f9646c7813a8991f89c168489d1a3b61a82466d98ac9de55b4d5aa020243e638328fedbc93d341e1fdc7eb861bba3783a57c86a7184aaa7d5051b7018f3f18b40b69fd7780ae9609194db70123801729c561e973dff3a7ea5ba9045b24e5fe5bc63ea858c687184a8276612c80ab600cc37699583b9ffa8c5a1b7934f3c12873522dd1c4f976b73121bb79766803d247de1dff18807000000000000000000000000000000000000000000000000000000c69860913068eb936405db039e82a2f7fec48a8ea570bd538dc9741a6aaadb02e366c059f5f26e6dfba8db203c5b27beca8fedd3de2664f6bd5c3e2ac9fb3891 +ciphertext = d4e89c9a1b36b648551ac2180f2f59158514568358f66a6fadd88492a0e1c122d1d7806287eecbcc8e8e6a463dc1c909f13842f734b9eb5bf690291c9d5b7836de8f4a28b8242c21131c53ebda4002b329a1951f469168ce0199f0a1d2edcdf3e6566f9e638e5a1095025cdb591aeaed8bb115ca3a1f1e9a8e911b2b9d3838608a27e50018e9a99e65b04adab67a75db892676c28ff41f118286f0ad2f5b650baf9441470db659e262e64cbebb4e808b1e7cfde0ff5c1ffbe1336beb42155fd9cb1cef90f306f5aa2f121b30b4d6091b19f37243cc15df2a0a16c4b5f70ffba99456f535af0eb0df80771150ff28c7925da7293878699c00f5136c340d1d06460b0ca7223f37ca553be904ebb7a7f41daa8288aa244202247eb8c35b7bc6d1dc8b95c220319532dfed22dc5d0f2f77a4bba0f5ee599420a94c446d89e3e8532117bd8ed0f7d9cb1f0a58a92bbf30a9d7c16d5ebffe16f39f682c18a8fc2ec0a551370c0e3ea706259f52333f5e86a83fb60b9ee3776f08e3f85ae4ee66be8c653cbe25e316e6ad33415a13e5139f53480625f09f593a598d6fd864729362efc3d09f5b171b0eff76cf860c8fd80583bfcae3bd7535e0270d622c2c09886bf9fddff6dfd045fea3259d26f17500b6b1e0b5068dc06a510da4809fabd615221f672f6d1d220c22dc080c9dbd7544ccb3369deccb76287c77e1a2af0afe133cd19325e6a77a8bf96fae6dc0381bb303815df4de480a9f3f97f1baab7774d7d5d9eda6c5927692fa2277934b0ebd30b4e7785f0c61a44357f49adac4430fdff3af956904b789c2dc9bcf87eb4cf93c48256ae13e90a1bcd713f77446593837b81baa6fd7050455d69a16b429018390a47e6e881467b57a2cfb043ce5a8cb114c4bd916ffe353579b599994efae24ced2dcf1a2923a0d0d8e771e7c230d887e596b80e01d84c908ec9fe81270f12e2f9ba2d783b1200fdb106e9d340c21667b722564a0cb4603dbc2193d3b455e06cf8c1d8fdf3e7ebe16a47f0181407f66c214379a5f336545818782835f6be2e9ad89f180ae0747067cdaff1f3b9386debdf3f057cd02f6eb00ecd656838e2ee5bdb99d6260c0447707d747bb6ff33ed65c2b3e22074ff25a7a0933be3e9b51de95d99e02ed4204f5ed8a6ff864e2f04266c9392c6feada8805ad44dffd5abe8d4262ddf6d2b1b4099367927b0bc075cf1d1d802f2d10b6d31d7f8c48b043340cae34b5b7c2f1e9b5043a0c2a977c51ff038171f8c81f04b284b2ee262befb6a54bdec146b84dfa116542bd13123ea79e4a660e44f3d23a0ce35ae4eb7b45611f87ae836081742d3cae6c65a0f93514bfe118cbbe7011e2a9502b197ac4bf31fe17016e184657b8dcdd62a223d1bd88b98aa0bc200ca91e123fa956b3d804b2c0ea139f934124f8d0c3f4412d8effc554f8364b0f351a789cae775b241cd6aa6d15251cbd28f0f85fd4f2a48fb467444f2f759ab6048d33c27832cccf9cc45fffaaa17a6f5e4b766f861529cb1a0641b6d3854c11 +expected_result = pass +expected_shared_secret = fc501515ab8bf04e3cdbc78c032524d6b9ac385122bd2324b11a2ba812158fe6 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/encaps1024draft b/libcrux-kem/tests/kats/wycheproof_early/encaps1024draft new file mode 100644 index 000000000..4f957582e --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/encaps1024draft @@ -0,0 +1,1841 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = d22302cbd3399facc630991fc8f28bdb4354762541527678bcf61f65c241146c426d23b9bfaa6b7df18c97f20c1b6125bf874b1d89475852c448215db0eb7737f91480e8cebd9a0871574f5ab62d9020175ec6927ca0b54c09818e42cf92a383172422c7dc1831d63b0c295de75159db8034e9e07f7b0b910c3c1e5fb66b3dc523f1fa6eb4910cb89a6c17562c83ab4c18d0cd7e0796592a372aa409b1c557347ccacdc4644a119064d06dd474929d1c6fb4d686e5491ce4bc89a30bb4b8c41bce5157dfc1360823b1ab618c14b10f98c25067398ea7018c278a4b3df31334d603b2044ef187cd9bc6ce42725bd962c264983e9e18155a8b9c47143d70460a26a56fe7658c1f150348c6087ef758ad167887860a007a5fc37358d43b5ebee820acea474f0ac07b76802866199c61231d5c747c93774d2c1e0c1c67e6c81b82752173e125baf39b4fd19a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a13322899af659cf1b3558c1b5001154b625809ed89aeebb89e6ea7d67f723d045ab05715c42355da6a5c8dd39c8abe3037751a01ed1c7374919f3121b5a52c53d1487316769f80721deeaaad3c90f76e7ae9e12ba92b32b5fd457e3c752c2650dfb885771cb77ac3c785a8c562e6a1c63c2a55ea47cf8b90eb8225c123c346452566235b2f31823a33521e087937a345d8d663eeaa05658917bbaa008c2e335f8850a90a326d0e66432f44ceb8289e4ecb2d12958e984072ecacb88e1348ff0b55654acba5b54971cbaeba88ec4b91a94c37192fa982becb9f3da421603b61a51bc8e36cbd053851c77b1b926b17a272aa9023246b02b3ed47f66a00bd5684823634e7ce58cf8f306e35b1e5322824d904801f0a2fa7c2bc9c252b0a56b7ba2ab0f636021745a70a9a43e2b0a8d615970b65309624b5184bcc30b911679aedd76025fe3908fd67897b0cf4be5a6f5413d7dd98564b23e42a93e4aa8821cd45054c643edc1158db6b3deb13fb5a51ebd1a8a78b87225a7338e101104c4a220d9bdedd48c85a1c2dae781a80c40e13b87eac73a764201c9b760ccfb1ae392699c7039d27c39362b27b8fc6f07a8a3d4410f1547c48a9997f62c61074452ef1515f8a649ebca9437205a4e8a61606b41daf6834d671f4d852c0c9c4096611648c6a3170678b1537cc1828d93580c9e5849a9653175acb753f2be7437be45f6c603e485f2ec301bb42b6c37c225d7495a584ae231890ab5c8c35c268cf4bbb0213c096019319561a8a6947637aa40d006b415bb2cfa2237e0890b6a3bc134abf8f6585e108d15940f91f4bf5b0c818055b21dea6e63b553988c47f4b94e7cf800a493b4734705edc56a4b6021c629500675876804cf0b951f038a5c7fe58e89774ef2992fd7c63099d352a7d21560b788b405709861817e59a96b3a3a83cba803b16934331071905bbec6532900155d8ac88cb32e4e21a3bd3a03fdec325a51cd2773964e6784fcf1853737aa64eb67564727272661abf84313a57a44b123c65509cfb7a6f6641cdcc3b57fe628c7b8192db44ffbf5796a8613b1fa126f6076883c783dc24e2a4464c40b3a41ca70ae87620866cf4fcb2bd204bf5c283812ba056ac0c345e379c4ba24d750901279bb2f3a16f612bfadb35703332c7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377bc200e4d315a30a6bcc3256f9734d06e9779caa5442a9a16069081377c76e75154368072dc446ed6c8b8e622a21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543546284eda2a26b47f05b735bcdb1202220076dc8b4e4b9f853533c8f6c7ff38817ba49712835785f17f14ca01d0c1c1e98810fe0b36e5b427157b9418449cedd641a4293c85c32700102acec22ebad98ed160a5f027bd4cda57f1f3720a12c134654dd5e73f829676495390d0e7929d6034e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7a0021535a6e25e437d49a780698be22ac9953949f571b85a685725f8207a2b0ae849b601ab91b159b3df4a154c2041e776070afc42969322380917c97510799f3149131477e16663d3174c7c1caea788535c6c005a64f2868631b31b66e205fd38c1d84542d0f1b578f58c9bf5a0faeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = pass +expected_ciphertext = b15696acabf3f5c71c09605df350f98ef9897474f241c7f7d16f7a69604358508458916d2c8552c704cb6e0da4305a11720a2b59a6d8190fc3e389e6551e7c59578fe2b05d7591bab326d894e23656c6b5fe4b7abd6505a8c26d1df8b44a0ed53affff9a585fce86da3b3ff22b1fdae2f6d255c26535f61694d50471f1d84d17673e481f4e824c82810ce8f2ecc9bb3f5f07bf1430e7bfd99fb98f3d2f941edf642d7b9e73bc1595a04cd949fa766468489f402f92325f6d9ec5d696e0fac2c6a37983a6451384ce9d9de448f15874e530943e8e0fe29960587a89b8052c9d0e6b0ea5dbb734d2a9c05cbb6d0c79f4a57db5afded6a7df0ecf47b7a31deaf37dfa1dc89722a47b40b4a50c7a2f32e8ab3da973aa683c0a698294ca3a045483175d87786b47f78ab0295b8267edfeeda442c351a38e95cf43b08342c67d0bc5dd5974f6c5c003ea31b5804a311c29eba17bdb547a629ec83974043bd03a37d0ec7ff39de1dfb8e632a86b26021e753e7dc731bc4ed7e7fece78b07dff5e8775b2223e19dfb3a06a1865ed4f08a84544492504f2962e005fde5de6e4ff48994d4ff811ce31e3909803c3534c1c6c6ddc9e1a43c845e7e7e2a1081186bede4b5bcf1b80b13d218a4ab446f479e38c1de4a594e0f20cdc23a9ea58778cb2fb104f1dc91ba5c17e74004c430aab1a3d1679daeb5082e517af6a4e28f564441b73235d084a5831cbb394cecd997fe08b1b4aa995bdd9726c04615859fffd1c9906fb2d0401ed6f591e13c6e79ec5e862079e6dfd3ca688fa5ac7f8d27907530549ac71fdeb5f869d2a9b235a0e54b3b866021d6b5c98d1c6c0c00489995e3c3496b69c76338ac422c9f94158ed5cf9cc6be93846034d4ba533a3422c29d675405ae853b8497dc912f4a83500c89db76bcdd7046d9832fa3d2bf3d02465ebb4168035118f087ddd47643d2db71f47419aed973ec4384866d45e1df216eda5bf6133f84a328c1129621ec1501fc46fe3eda460680b397a42a4368eb3dc88451b2b616eec5f1ec05e5bd2084b4945d20ea8630d81492c78cf06a78ec508a0c5713b486021643266a60d99744678e598b152cf1829897af720c18eb6893d8b1f81c8bbc55c8047391a9051a6d0d65471891ac2dfd8ac984aa7aff3974492b751fdc5dea1396886e8c94b9448e1ee633f6c2143552eb849c6d7e72b6a7c8121461544515e346d69973111c924acda06470b5df2320e06b8f1aff413f9e888436c31378025be66726a0ba559177b1137c431cce1a6fb00de36c6afce92f11bc75a885fbbd9b108e6ead43fee47da311230f922bab93a7677711e97ea4129802c5dff20d0d9db97f882c63379fc27d08a6fecc288cc06e257654b388e5018801ff19bac2c9487a5f47e073101dd37b10d43c935119b6f70eddf9ba5149ed64e8c129d978cbf2c1a306f83a6347bfc445e8fd645ab0e4b2a939328cb55a7951a3a938a06aed24ef32562149c8b7f2dadd75d2db3782b64f4cb1f56a0945277c9c5e1605a0c0eb65d7fe3421c90874bb9ccb945ea74c997eca73c94059b77c7c3f08dd6e5e494e3f23399f2fce056e9f130feb6cecbb3e8dece49e5673757515742094ac382563857b5d412d7191cdc5de0681c72c5daf833beedcd88e40123a617d2bd0d7595916a6894b9263b6eb91e2380154e0cfc52784258cf7320c4f02ead0b4471ea0dd0abeb5e63628f4836a23db269cee09e46f35b9de87ecb0422ad8ec6cb60b717eec21216f0b791c852a9f8a4c26167d7350e17fa3ec745b46311a671cb8d7f14885ff01bab0ef469d0850fe807e70d36a4b736b2c32c676258ae7d553dcab8ade6368aa23179778add214dd9154f510f50e5560c65fcec35e87882530edc65bee66b25a535da2146e14f8390bcf579c337bad974575d5f09a8768883f9393a144171feb3fc663eeef138b21bd557abbbad2c0224341fabfb6c6fdea6f3c265e5d8af169a964a7a86a1a0e222dd6371382079f838234aea8ff6e2b894e04a9a34cfacab81b0704b14d7d109949c68644c015bc2f26a9c294287ecf152d846f914c0745ceb7ec3d36ad9d723c15f89e2d8fe2c18e11180d0709d7002a50f87d1c73dbb616fd8de30339d83da5a8ed50321cc12f94dff84d9e544f17ec34a60eb414b2878cc1a05c264a066ddd37f0c504f0e6ccd0f311eb5212de32e9d655125e4f4 +expected_shared_secret = 63a1039074f01f2651213ad9350d6561cb03a60400e74118bb4464d87b9db205 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 05d918331371de92c27a1a5ece876015a959e96aaf3b1a60e9e77e46d51d9d85aba374263bbc65ad78b2d5a53cb909682aa0bf37d49d172bb46a0271d30716cea8aa095992dbb1132e81265a29435ef2c51daa9f27fabf3a799813e67efca087ac12247b64cc0ba15a5486245dec1648cbc7aaf40805115d78f6687c47c553d050f1e6821b368f98da22f4aa7d738a81b298a81bc43e16c8ce1490147ca83d2dd98bb918300a26cb431c99a952471b84bf6118a4d5c0a898532cd277bb4443cd7b6924c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7d31921a66403c587c165bfdd341011d19ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fba176f9bb8dc7716cac344684334c5704d5a54c932535739948acc61bd67b581f75a2169a89a11076274b10563141722c9aa9a34bb28a69ad677292be84455b24559cbbc0f347e7b36a45555a8336b8adfa07e599633f5d1bb6adcaf86ac9e7885039a3c1d308996ab6c966f017f8297009c9b4b573b70da8921a0c256a9a03c0cd6a4f72c6edb5630b1219c4a3c30d1f1586cd936e3437684ac60efa62d0a345fbc4881b24372b5692c101195c66c3ad647ca04d37f91f813a7a6795b371a574565e14779772372cc4a79c40308eb1233ed643808e939f27571c72b2f719023e048c4d15c71b3e116482c413a816c6d3a3877f862559b4afaf04df9c62d02cb364aa2adc64078b8bcbefe043bd6f32ff62b9555fab5c1009cfc102b9b4b88b8a93b66e3a65a62b184bb5406dcae7b3ab6047754bd215251ebaf102356ba688095a8c9eb1a9d8771cf60e864b7b4a5588843922b6d4a7445476997a6e5620a528510439b02a4b0de9c147bb14433db144fc9ab4b4128f7291a637b7e609a7de058a3b58a17501c833be09143244cc7e2490eb01cd292454523ce413a6e8cbb67a464aef43912b4559651258b9b812989093540dc8d202c652c71cca1eac46eab3f9ec199eae025b153348a600b0e373b7cf2620f5560a3c64c15ec85b5e81c0bcc4840466c63cb124ca45994babc31f12486f3712d22b1f649a07b192a2451cfb079ba179c2b857c41c4f8842a916e06f9c6a07cc6a4d2821401a65060688713ced4bb72c08241aad91b50bc1b968bcf3bda76a8e1b20060975e8803dd7b762d9a49b988568cc575a6d34bca13a0ef701b823296ff114efec9031d79a20f6c640d4519a1906183099926d44e88703db7636e19394b2f65abe9a8712c868697b46871d830bbc09ae02487e8d59537c3841d5b080f503aea769b0335493b84b94c4a498b1a6e6acb578201bcbae6baf0e960aa975d3f14b5179051d933c4109361f03461f265274f72416df79d1187b6822a0c38177a02b4afdd635324eb6737c11a631784916452c700d09aac42ea2634abc68bd3f41a2ca679546414df2314d57c2b318bcb98d7b46fe1b5a7e3af1b2047d193883cfbc6e7d29049fc9c97b344736a0a48082b0a145aa8776125558df656718af59964d42f0704318db88d1e91b840690b96669c8851bdbeb6043f04c017b59b289bbf550a94d0aca4aff18ca84630a99b82711a661e8b202b976e65f53b5db52b255a88692852e06bba321b4de782b5d951ab02eb27098813c98b0f7cccb778b08704a068b4d48afb30274c0759fc5bb86fa59fe61688296846b2481e18a05fb9c02931570596ec436f570c187159b25c1f6341163b79670f62334c6b9a7139044a8bbd2b5183e0f82d3b6666735a94478784aa6168d0d3272876b5476b64f7932f3aa4151ca9b604bc7fd5d1395c3708908015b0d2c8cf04858eb23238458f70f964687bb2137a0c75c06a868c3490166cf2bc3afe9b3746e40c231b3638a3558974bfb0603cf4c28c21003dfe87b3eb959dfa715b78ecb71bf404cdb2b675160138a46501569918cb7deeb0489a72a4799a1a4ac625d5c6021f51c357895ccbf26fb5aa372343bb1c516ceea47683e5a4d094a3d5188270811751fb1e19d68ef637227e491cc6387760eb5a810b387f596aa20741c4627b1c13a303d160423bce1e422d929c06f067adb7d96112f1607d3c7e43e7aa09ea248526c6881901852123f1b734a8c1891261bae6e7a23dd5296858b6f7813196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = pass +expected_ciphertext = e0f53f918f1b56e14a62744fef0e1f7a5a257ffd32d0657c3090cf56234d18b278df87a8c7d06693fc38ec3d913b77a7f21dcd876225f50b2775694f5446f6e9bf9f4f3fbba8c6f1bbe1ce5aea4f27a83338d7b8a89ae41842ef990b4d9fecf78bada42a9a61f192f08d7a34a9519a2e945213b34b4cd227ee9246e253a9d2edbbfcfe2f723ab3477e3d78e73b607ecc0b644a0bd15d6559ffad87d7bc49c92cb5e606bd8f7a634a105c15051486c58e1ebc0f21b68939c998eef4346a5d3b134279bd9fdfc5a2ef2507d0491718164ce3c8e03ea769475f3a419f01ea5b2469084d8ee605d6e4d2b346dd0e35904b40933a5ab3b3c6789c9c83bbb00cf2e328ebdf0f52ee1e5462f2399d68a798ca7b04951af96aeca32135a6572dd16360b9d9124e43f0b285197f31ca4454e22ba28963efd6cb22fd23b709c509c39ef20ff7a771ed8d53c2f130ec64a02ff0ea11fc456a42f703977e26e143d8e07d25147554081c0716ff78187484b4a4331ecea813f6851531a942552a342c4eebbe85697927d90734d83e2851a87defdabbaa247f1eb12ac2f6d6fc375bbe89abfe37c477eb47cf9d00084fb97d89ba8ee77fb9e16f459591d8e230840fceec0b653d06e01de59916061aaaa72ad3240c421494af68491d4bb2dd7934564b1c08964e22438ae9779bb72f22c120eddc24676e811afe4a38b9fddafc3787e9c43bd83bbff3cbc8872a94c3c84fc0aa2b6d561349bb5cad6ce202b0dfd6e9b65b54678332820b075e659909855c24be66aba5169650439014a5334520f74a6ecb117e247b37b5c44f92a3a2e030ff60dec5b0fef6389587d623c00a016ceccd0ff7081b1346da1af19b587d39f79fbb8c5584c6c8d1f776ce8de828fd6aaf0b7bbe7074acf01a3595b4bb8bf272fdbee1556c03db2ede1713b7f4a08ec16bb99d1e3cf17afe9426f3adae028d6f057be233a0ebf6dead93f1ebb4548f8c7da7cd0c5b9c131193545d164e51785c09e1fb8314cb874d5b8b408bb7aa47d74091d6ff60a237cc9b2e7a04a6982da853277bc59fe26f314dd63531e8675f28296d1b1903c360c09b38af11d065056a38f7d7f84d77503caf4197944e322f8b5e32b6fa856e05b850a77bf21d2d1875ffd970e325ebafca515e11732b117168ee814e7064eb005a1d90e1591c9fdf9fca1299f47c137c0a57c06cfb1172482b35aa6b7d30804f5b8ed71123b0c8bb49c1ac3e4548cb7e9e30f7fffb07a2278533908713a28833b9a5469e119082d705467ba1a0e626e607dffb03ce500f2be1398fc072f67c673d44b6f079d8005955e965dff4d8af1f36ac30eb20b91c9b5663fb1fc858e61c73dbb6bcffd2e8028b237129bc2ca003c3cda79e7d885787877bb5aaa25c91386331549c553d680bf2e9bd47ef502ecba1326b6bbdf6b75583e5d7b7f81ef037c8bc431df0bfb7509024ce05b21abfd25b4aa7a68eeeb0075a0aa85f6051e8a0f93832f1b049bc5a9dd44eee20032a76af3c475052bde457046d6c64004ef10e54b501a8407a0201dead9334209e0be7251c405594087178d8ba6ea13cfc36ff083159ed5ecfd0c72e99f3ece3660fe269efe32b55108ba712c43fc6d7bcabde4875b416c99035afa95efe1ccb2a1934efec2b15a70cf5fbb5b9465e88b339e4f95b2ddc3eca8b6e55a453345daa5ec70c05c69ca36def7d9024806f7849487338b4f86ed5fdfb3d5ce83ff868d88fa0b7f09370a1963b9cda1efbbdb7e14d5e1b46b3ff008a01970180570030f6b18f689b5e2de0d552fd596c81e0b2a7569d701576f86a5b84bd3c7633777a57d1f6ef39bcc8dcc777063b1035f95713e072a920a8a86f5327914eab7d1e13f35a1459423c1225acf6c658e68ca156abec8620f2c055c125d9140442d63d95406b389f3ccad86535ddf7e9b8b4f5fc61b406d97ba20c6b550117e166fc7e4b26555139154ace7157964e0be9b3a0df7dd6332b927ee3428809cfd35b7e72cf8cef5306e4533749c38296ee19d0bd9a36c2fe56fe3f0d6b7c31f28cce14ff407b8c944b5986e7439a9a2cb73e2f7b20c3b0a32d844b7bc529304d21fdaf56a00282909ea72d44116f61367a2d2f2ad888bac956b80ea070677edc04572f547b3e9debc96e2f983e0fafde0974d6241b28a75efda0441d60dcb90592f238b77c429e973480000952a3c4fdf6d2f2df2f6b99 +expected_shared_secret = 856d56ee09279a13f9abdca14ecbe8ca9968495f09a0758b6d1c8376099365eb + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = 042b035f126c4fca9e059972fe92c9f4b3755648b5b2b7784d55a62e9b101a7a059cdc2f3f4b8888fc3a56cbb1447673a406c78e9a045df1be84da17ee2350b64c0d3bb63965328d16b3c446214c58731ce3c405d3d251ac560d0d9108e3bbb268c6931fc49d7b454594444dae401b2fa3011bf3c697e67ad9c1540ea945ace6c98d49321dbc36447858d783bca93ca67132800672513e577d14607cc046af9bcb4896f2bb39a0208405b3734505b239967ec72f8e8b0c2bf06228bacf834029dd123c83fa3f8f83892b504c1a11b809a9acc494c5e5c79c18401a41a6af6632c11266ae5821b3dc7c263e1b5e33a1a7bf172d6d142c79782e20ea38d6e791ad3b86517681ce389620562bdba89898679ea0c748d90a963e738a3e9968f3648e984c99f0e04c952309111396d112523959b9baccc43df715dc94ba3253332ed27cccf56f5812200e8c7e2a11ae02087e0fdc4389e98eb0ba5693cbb79680a6124074d3c998d911ae4e142296c0ca245719467402124574f8d271624315359c7842c761bd6057b92b4640a1703200cedcacbfe0e475f7316ccea74b74257e37c63035f04a880910bc042802332ee8b3c3612290c45793cfc5581b92236b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab999031d470aa948665aef9974df5a2fdd93bccb74762a0b7c2fab58430942f900de1c835c8b9cd42d521e54c434fc240add0b23ca1aaab0581ed9a593487b95a16353c0c7adabb285c85105a667af674344c3666da142049413973051268d94cea41c3cc9682b791ae17f0696df29f7f559375965f817a8d9a3297639017f5624f9df1b259412f89a8c88a361940ec9c3045c4a78364e1e06fa95500f5ec0704a365f4698b2f26a7ee348806b74e1579c2a466ccea209e515302493443f8ba9e32d04e03a7557380c7bfc83f191b84093c98aed14286f762d3b5513f996481d5445c7a7c931c1b9b52bd86e0b3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7e40b93b5108861576b3594966c40860f74cc58b9bacf51a5db6ab2d4ca43d964ffd831130b21457a08af7d8060f847e3695b8a7e8c9858a70d521908ce1c38c0713469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af944165dc9597392a6fc2068297d11c39d8648f550a7d157ec4b64c631a7ba7b94c6cd7083e21b149b484817a6f93e011a8e76931da4921e08aa604756c0bb63f897afdb8c6112a4ce21b2cc1935dc6b38b6c4473e2b0639266386ca988456ac843a1084c220b74f72b18199ab17aadf0960f50db4dfc7bb3454a9b29e74b09c410362cb8a5516e0546a3b09356b520a303e284569b2df6d263ead36ce75c82f6d141bf7c3e5b87b3eec630fa7a65a4c58676181916cc23e0c6a0339827571930bb65089376ba4bf60f4ca71d7090614f468732e60989298384a93849031a989488e144be739a78e1c49cac60af115c55a6501f010c100dfabbb462b1b3b6469c8b0d8b91061bea5da74a28d17cba84f04d2232076cc91c8bb21fbd558426f99b00e13525e37c23520698e0310c8a53c6b36192d82837ba0d3ee27b059b3e8fa1a315b64ca5159de3d9be0fa0352b511d1a803c79668479a1c3561a8ee6f7aca9ab4c861554a5b81b5e6115c952b3239595b9782fee01b869380ff09cbb5784811966b864d0414249b7dd0b53a762155170990911192e37c6c7263be626084118266bf7271356bb66d35aea64c5ea913db432c3caf989b0ec702139504fea41fcc782808bbf26d3b12a962d2b1a142c755fd1acbb802ac9b93713ee71af9d4430f240c7fcab059cb435a8373633417e79106a274882f5d40a4bd732c1e8202e41131497721792ac464b3b26a6456a9374a5520054e50cdb06a32b3973aa948a37e4798544020a7ace817749cdaaab1c7713b467a77593c034c20de0a9c71c712d6529820a5b3bb4e76202080a5e5c7ca86bb78c392a39aa37a91b4e75b3c5f2e56211358cd5aa2781ebc548e21e5351209b7a7d871a782da1306883a4b6b070a06b97639a3ca3273d1218a8000b7e85d6011000ad018527a25059c2ca252e5726629b0800b85ffe02745e9199a705d0cf4879719a53d33a95b2cccb52c1c9655419543aa146241b98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = pass +expected_ciphertext = 56211694d62ff252a094b42aea2280838c673cf1dfaaf01971185b9a4b9cf6a313d0fa2a54b11469be2f0534e3e77c13a9af9504477becb0a49d54abbf3ee8572873fbf5c9ce30b9a4c9c5f7d145993bfb146400254335f4cd8099cce4b426ae51937c95a6465846552ec9a321df8434836961a8358909ad50a976ad4ed1d699c516166ea8861d0240692f47d876a618a4ac4868d6abc7843fd371f8437dd3fb66d914006226f4a528cd96100570a18bcbcd3435ac73a7c9a05855a878be5bf6f6d3d279843cbacf6fa788c4ef800b18747e10205698d294c42e32e7e325821da1acf774dbd7ef1e10e1b143a0be35259937ba479f2b16d708d511fe3bdefb290312996a78a106d11c5d060b61d99c59b35d62d402d8b36f04ce5776c53bda2b5e274f3ed41b82ea51a48eaf990f31453fbc12772fe780f53168ca3f25931c8b4a7746fd7777112dde693624acdce62eb21a0d1d3fb1208f4f1a7b8e13a6980bd621997a73ebd1ab38e5249d58e4a3f5162163a2d992a28239b2e3961e50d741187e0383ca185f1850c77cd6ac5121d2c5a740ae2882695f46ce169a7ada95c5e48e9299b2e9f0333b9985d24ba875799fdcb7b7e784903ee3b4f1e2f2b01f8058bdde42b958bf2e0fb36c5d933c1ea6871af0a9d3f37b9f23cc6533a66a5e543ccfaec7d6fa4a8b8ab76ae0d283df21d3c2ed3526ea0907a331c4363916faf394db5c6ac6b1e53721a0e4ffe2b15803cec8ef4cb29d288551fe1b493f89ad2f15474559177a7f919998f4c3d11a5741f1ad4c1a3ee3b4f27be7217918d70a0f43c4f5a409e41d90b5435e50a24ea28776d6bfef07ce60cedfbda357d828283c50162880dca807cbe8e37c50e5925c282defd6ac28110b40b51e951d4943f53a085ad3d040a061b5212e35d7eeb25be82a6d787bc86d5aab30f797f932166f46f6b41798695a188c92ed86f5a5e934c002497d824194beffa9fb82cb6e53a275cf7171f32e5ec91755b1f083773f970ce7b7b79d9af71c970f816b990e046ef30186356567fc3e4f1fecd8e4f50e8bb77f2615e6fbbc40b30d3dc596825c26a7b91787eee1ae8c019f636bbb65fdf32df8da0883449c20f6c02d8562de5d6544c55ff8826a1ecb976e28695403ac0c89a2f009d0532fcc6ca5780b423740c9f9ea896a5659e633ee04fa914b3a2e2092ef48ef13f685046bc6b354c1b26314420354ea3c07eb63b64e4e102bcb43782864e0f0ef991ef21366acf36db469c4eb23ace9b8d9de933ca5459bbb4cf1f31a64b4246e4bbaf2bfee841c4684e005a27503f56bfd8ca08251bc870caafc7f79c3b206f7b7fe5e989417608c24262832e359ab429b9d73b7357dcdbc57aa03c3572e2d7bd67c58f6c8a1546be3d815395fd4ab50a626b6f3b57dbcf40858382f93ebc9d8db4cd34275affb174d8bceb504ac81fc5741e082322fd32d9f08e05936b00e035c0582d310c586e03615efd9998da8ba8820bd7c7ade8fb918118af7fbc4d40f4e5739891e294d392b1d4e97aacc170b8378debdd5cb75ef2a60a61685e3f83469a8ae3185f057478363da5a1956807131fecb86f68f0884c2a746ee5fe4153b8b9477c56b412a4a82ba01da89c7bc25b8b047e7c78edc83f36220d2d91055f967339bf024cf168397991d58215543fb26fd5da4097c00d1c0a0807759a550ae4139c5015269d11fe013ae15cf60fe5cb2261f4413458f9e03b1d53d874cc2ba54a21b2b91fe81d2338da088e23f190a02ffd62de52d0e618011ad8e0c83426bf590158c16894350ab9f9e1db42d3bf455ade601caf40e38f2d2fac40094b74f99210d3d671c7b801aff1023c6b76453bcbacef25d164ed3109c7640e4bc8574088189930226adb6ec7ef902bcf0ac9df59e55c0c04b568408aaee63c181b3a5725c3a4fcc9003fcedd69ee93f7f1505a488ed929fb5e7706502ab1f518a3caa77de38cf42e50e958c79d0bc93aa2de53a1c16d683d14ece2b5fbe22f583034b2e463e46bdc0d31c850d6c5497d5464a0ce78942e20f4b3deeeb2adfe210d0a2873575448a6b58cec75268f83775beea3bc1c73e80ed529c99056b0824c1cfd7636571a972178295de1d7415ed14e64f361764f44bd3f0396db4972f146ac0779441d73d7a5905e890dd22619a3fcce078ba66b2dc8b63a79ddc9ae148974844d84f04bb509fb79c73fceac5 +expected_shared_secret = c33a4432cc441b7683605c29afdecc81922cf234e02be8c2fbc4e2a7a3b4b078 + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = aea72a5c370048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f58987730d4becc9de18019e5142f94984fd0a6d84a8930bec6d96d413bbe97b14138e95e05cb05345c86b96aec66babab7cb8a2ad8f774086918795c39e95ea3e40384edfb1ad3aeb931419c1219286390b9cd2154348ba19ceb280c537353b701976236414f21939968190892001d10f8ea83ca16803d2ac4cc5a96cdee3a424c935b673732b312aa1d722f303bbd5175ed83087cf856c15364958b678e74b3618cabf82ca58befa00c6462b3c963edb4a4b509792f890b228c7ca68082a8f38c388839190942fe3ba6224c4c58fec51ecd52d044400f8eac86cfa6904aa99f47712ff29c3f73b02d2127f1c687a00e2c48bc032cad5b261b94fa44649c5b459fcd18d4014c34a3978f6ca6b9d667e5d93b87feab5c6f36472492b1dfc74cc9430d1818c0cc90dc947b01d33cb0c086849f81b570a407e5248a3527ab58074ee52313e678fd5876dce81860b4b06f22768e3e26a3ad450da516224e06bfee2235f8631f2f7697e3638d3911bea2bb486667336e4072c061180a886e45144fb266643ab524ab95baed92c1324045c7768465cc177a6543376be40e132e702318ba52eb10837f0bbbc64e10b5079a24564bb950915701a06bad9cf1f0662c63bcc1ba31985149c2cf79befb710528b3f3a1406869872be1c59bc011294ca50837852f6567f6cba9b5ed028bda8aa4ff26af2a4ae90eb03c65a7f03c61baa3008480b8a006c29d6a2b52e2278659ac2faa877422a3e0809736b576564d800f5287c5a73c27a9c1e1748b159dbcbe9f566cfb05fe76419c84321b8fb772597262d2b48f9c43bfd2a110bcc93aae57531c68bb222ccff36b2e8466fcceb237bdbc336e855755b25eb4784ade55cd54b644f6404b549a2103b31a0433363337ee7e520db9a8929f607368a090fc77aff437020109001b40de05035394a7032524cd8395916bc2fe12a7b9fa2a4ff93000cfb3077c23105ac40ed0162d8fa6e22a37f9670a4c686a93e556ad82509db3aa2074a47bd9605184a9a1f82bcdd033116e046ce58a9e639c8b506cb5c17129b3079fa96cb625115ea887c11a7aa7484c03ecb793a07adadcc25e2e876fc31766ef11379738a8bbacfd46c5d53f7091e6ab6108356d8ebcb45e6ba20d36d10b1aed4c2701f6b9924bcaba7934919c2a64d340c8e9a42a98001e75b09d902714bc47252b9b15c2a08f2345b78b97077bc989c662560e94f551c3aa7834830761dbee93d343a4089c8775ec85091dc1cccf91bdf30620cc3b92c6a25cf147385d1c60a5886cfb6bee5f30bde74c579689251199ea26a15a9388cca30ad565a83ce397e07a8665b0a9286d223402059a8238137306fdbbbc2f6e4c6707534559acfb4628f803250ed8c4ecf846d8aabca027b9471e4308d727987a49fdb68a11869adf57a6f786043243608810a6353c36cffd18e1ce8bf25512a04378e8dd7a01b5c2b563902288624c25c06ea881fea70390a039b82e162f61ba6c484bd09b703a4812535427a8843b41c405c7ca0abb8e17ef4c82589945e9bec2bbf348da0219160e50c54d965aaaa4a628079eea53898778331649a8851732618bf307491fefccc7074ca2a7a56f04309e39272b74a30e526a6db5c3ffac70ce46363fe596ad5c377c7f2464dba68d42851f6f70d4b8a0b0cd52d75c48a9cd31ed8f270b36b69244237f9da28e6b0512676145677b418309d1b491cd9cc1defd06cdf9c182ef4b33610b257d68ce0b12a3f024ae0f0113ad538ece90b4a3b85bdd99c495b0fad7780fa1804953041f643183bd7083c5969255406f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d80a0b153c8b8147676a212e6ed13687941132010a83457ca155888946c8bd8506e6301f1bb78cd9a0c4ecb73eafcb2fb7b02171885b6968ab52b89109bb2941e10683f30591c322261155d0dc7b0b1821eeb75abef6023ed67e16e0ba40c78109b45cd03bbe2c800fe4b19db4a960b3d11a45392c6b088cc6cc5d8de1275f035357d3a847313eda8c1c0a65c27a743a000063ac6a89754818ef7991469a39f39536a7b70964b33d25f01b7ad9cc4fea6546f82c3648751e2b41ac410e764255782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = pass +expected_ciphertext = 0bad1ae220239a1b88ed57737a4743fef2e3eb585e518ecb49bb8ad073973c6ba1a7b98d7d834c3e92c0d5851600556670c6e279f23ff0e8b257b9e0b8539130d0d01a06874347450c0e6c6c7e975ca591d8b5aaa01ecf5614295df5e767ba67b7033d4cd6c9a76c86ba83b4b47497b06e01896186521eae106485a71a2291c72956d9ece08c24e7f37c0b1feef1009a5aafcf53cc08cf19b74bbcef8e739606e6c3341d5af3206da79ccb7e1a107f5bb757d79be789531c57cc149ef6b8a4139f20c3338361aaa083f8e30331f603b6537a682bb395072503b583f4250692a406eead714f5e24be6b2f8508c4f98b349140bc6f5d9388f0153b4732beeb17a535fdc623774e6a70fde45b0485c3b186b287017f9b5e977a95671b681e949c258920a6cb4afd41af14f0baf5a199840a06253b221d78cbf3673741162ce5577854afad9380d09a984d9f3ad0c06fb5947195f78bbff51c9d2161279b4aba7bf711cd7b5f1ebb65e422421648ebde84e115f596e2158d995e48e2c21012089d6065aada81ad4d2faa0e655311fd72430651c61d4a40c77d74ce4509a22fc64856f060bb6cc1d6c546f81e8abb1748185b4feebd65001abb73e9802e389511cfa1c598f4713ed5f22aced8812f972a438612975b55cf59f2f9670c92e2985562f745ae2f9af9a40968daf4112a4a2bd18e1e13a0142393f743d19ca3511cf121aac9998e9978bec2a90977c6dc251a3191074c8fcfb547a1bfa1ed1341956d0c9e376d7a709c6526fc59f4546195670c8b36a39d8df3d8674cd9f3b78c1ec2683602d7aca3726967d20fe7154cd76c6c76b122cd98ea962b0aa5cf9c451c5fccbc77414bbaeda28f3ff3a5111f4b81aae471c12ee833b4173594f46da79410714f57c89bf32aace0493d8e1d7f982c9d07bb930cc65b542ee87b4b1eda9a8f5d173ef7966d0827f100d3f6017a96945dfd6f677a71d765fd10082e0fe82749a89950c8c46fd047e310066cd8b9bd0bc75e2f7a9afc416344fd8a584d85e1b531eaa5e6c36a521311d7faf1bd31db5497662d393ab4dabab9e74e52db1b490dd42a63cc9a439d1daa854d0f30c3c2ddb9d76495e5bd2cb51466b32010299d3e0d28724ecf1666bc07a22cbf73c816a2a3f5dcd84eccbfffc3bd16a168e90c008dc094c693c157cd9dfec2adeef804df20db85f6a5c2804ef1d85721514607d2fcbd988fd83a0166964259e9999ae991e00609e6f341f5001e5fd2c696e15d64432f8e27309080565b323beaf3bb9af047021d9900ef3a7c2ba113f48efd0efae554cec4464b9edd0f73bef2994582245381133173249beaeef4fe0e3c6abf3cc0d3f709fb93693b10de18f8094989044cb19080f64e42ae17997f724004a02f760c8627c5f408d8f46ba2e61e8ab1976205266b490e57e645abc6182351de1a7618c6fe8d80ba20e82a95efab6f2ca36fc3de204cf2d63515e497d0b06945fab49c72276d292de92d299af0e746286dbec3115213f6b33f73bb79fe55f49cdcc3b04af90fe4f38ee135fd1e3cce74a03f7f542129c766532732d154c879dd363c52da83c5a8d1ad0dca006f594f187650f8ed9b22dbba51f64c9bd52436aa6d49939e5e53c24934f474e320693d7a8236b8d46483ea9339378a2a2e0ca251e5fcb37a23b36ddc495c7974b7a648137642e3e3c38471244ee65e64843a70cd13501abb2727290a7de50086be6085a98d50144f5557b9725ffe2d968d264437d61354ce9b516c914358a398c314e3bc1b259fbd2aa47bd0dcfc7e384e7c95f01c9884c2db55e2e07d75d3aa1f8d1ca96de506d32503cbca39ba42a76839e3d716eabba954cf255333638751ed5d9ac8af41073abb018480262c53d1562abf58b2163e7045579428c71b6cfb9210c10777abaf40b6135a71c8fc6f9242a818599d03093fa5fb1cff0e0a43a732444cb2fe0be143b2146d9059b57a20136b4fefa558308562594f2bc49e3fc953367741a11af45c5d4fbab3c02def5c67cebc8f210ae208aaf0e2ecbddd50449b03c8c1912ceb6d1d2af72c86d22e0fc81b58818249be4c1d9f711e034e5f23dadb673931c0ab0acda5f569ad8354bb330b11744c09393a54979deb52ab6626177dd32c49f03d08f0a56187babf6eb750c8f1ec3ff0acdb820c112087d2fb17f466f7cd7cc7b96ee22d8e3039b634456618f2537d911c +expected_shared_secret = 7c14fb353ba421705de44f2a12ddc5ad9b11e30e7b0e163cebebe2da79a7293f + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = 041a9057ebcd8df95cd5eabae5e776ba758d8ef9c8702406afeb9d82d91c06e8a27df57be2d2cec9893e9c0a678ec02e94c21181993cfd22c19a7620d9cc494394b2218a81f9cbc743047160b0a551b6c802e44d09e52ea613c5f60940d77c3aad232f9df0561f159ffc0c88ac9c2f1109a9d89ac87b4a756352289d241b8bd694a1e140f255163f7888ad1314e6208082c0bbdd72220fca50d57c65c3b05d701b567550316c440c6f90ba50a46ad9662f99c61ad6601a4a26874e30ca1cb97998a13e68683a28996933ba186f469dc903b0c46a348a1c307ab9a9a4d427730920ae296d725bc045d2807ce2cb325cbd5f6cc216a0c0bcda1e321c5b17565ed0028d68554c892a9755643a69cb721fe6296acb64b93966a1743ed298b5e348817d62a93c453318db713e95cc53f8bef7d6a5dc2a7001473851324ca0db3052448da3136347008ad8d8b6b95a62e8a48073d2634a58525dd663da939948d49da9b12b1d758bb6f328d0f42a38837675e487403148729c4ffaa2ccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63feb255360c4796bbc99d95461b30502b42ce4e6aa92120b61a283927184931fb6c98727cf4163284732d62216b653c633659045549a40bb0c7c0a64adeb841596516bcf97e6ca33892ca8fe6ebb45e58313fda81d164193bd711ab5b65e7f2611b4b558f3c03294336043884e8b92390d11903035ed46289925447d3ab1a53802376cb2ae1960e4a7a13d0d05a58c89f5d0499be72acb9fb7dc5468afd332f483b1dac2370a14326b52467a205638fd603d835a628ab940a0463eb93814237415397b5a8b062b915c3f4278ed1db16ed13b03002c158700852837657b94a4b5ac43da32a7179a4c1a4303350652693844949029aab4222ac62de266240fb48bec4bded28213d945c3626aba1856c5e702589738fb5574380b74071dbb401696deb422b9de3699a0949e20522a3782e20a6aa2c364868ca41e7202ce8ec8bbc2165a09019a898bd4615741dcb73fdac5fc7c35503a937eefc08cf88570ed41163bb7f2e9315f0249d2bf5cb93b74627041bfb79c2b26754c6f38f8b802f28d7a775aa7cb082cb5755a195d66371fbccd1678478c462ca1896b201098d66b3991b2e73c299674bc645d2737111cfdfe89b416a7da8ca182164bd708119297283de6a1ce84cbfce07c683783402539f88b6b071213732b7594052bda614c95860b57bd5ad5ed10d8139348ad549bb573e3549320e521c0aa3919eb0978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ef030c94b2e93ea67a081af3413aa6ad1c41091364e558cd561674340430bc490a52728cc188cd1281c7aac45223a341eb60c8eab4959701aef2120c891b5ce115bf8aa17cee2a980c6895ec5061ab49dfea7431d755015117a5f0a0f200921c4547abba8bf13b5cb7987b0250c2885a0507094795f7274af995647b5b6e559275115cd55cbcdc9b988073b2ea214551752baf467432904ae95182514e39b3b418a49c410e4832d5377b95227b3091b5f782aa431a1962d6a907d3c2371161d71a9640b177a488a1fcbe57f108900e8e08292f4cf97460893004f5f88222d059b162207ad739650537bcb8b813490ca702555f134406e9c04cd54bb85a7689a1316cdf3c401d9c49b22816f47ce750aac7455a222490940f030f108086262479b8489fa00a12d09cfb5d4b6a4176fa0f62b1288c46af76340d81eddec842a548be29a3994c53a7e631baeaca3a0f8afc4412b6d51426d496d2a04bf29934f17e668421899c6690853876434e87f8f10ab52e61ff35b54227ac0fb7313d2f1c308405e5d767541c8c3bb4664c594a257ba30fbe34bd182790045bc1bb377f9d54ea8db52a945642075b0df8b2e6ac87e71177a4860157f83829bf7003558b7f35a1690920d494b4391396dd61a7f221991a1c6856f7b1ae5147422742aa0ea005fc1549cc034b9c11267e00fc32c2b3cd172975397a3647a41b1c69f9bb663835db97314468540973c339ab0cb36a19b2ea807fa788402d48dae0ac01285a8c5f3725fa674d0418bfff98f6c64c2fe21a4c6a7cae7b014277413781b7c3da207badc70aaac10e684c42940705b8ac37ee7c0a101bb3b9bc233845ef75908a83108a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = pass +expected_ciphertext = 20be7822cd6adaadab8ca2416907a677ec5a50e6a8e4b3449c5e097306024a43f0e3f9f225861d4d9606860ae79c17849b4548057817d0b706c7c1551137086edff26dafa6ea695901a8f0c1e80ac82d499f6e7fadb20bc1ce9889c7758f63358a47897efb315a60df56651c4fbb5ef563fa783e32735f005a24be4643f4ada0844712b36711ce5696828fa70feb1cece8ac2521637f118eb9893ee2a58ac8f6b8d417aff015f06324e7f36dbd901312a62b33beec72ffdf22ef3cd416823379d2a3f7fb76bd010078fd0e3273b79ede7b6fa9151d5fb3ba6d7227b373b2e05d3e13f36e9dbc747448f8b59b51e5e39ccd0919c2168da6c31b909d1b3579713478be503f3139c4d451b7efe17c5481a9a0b9acd6a68c7c94a3085f3c5f41ba436e0f6da69ee3fc1575602235e932cb618f6b41d52d756d37847229ed09290cf11e54c8535cc3c141f3f0e0954ff66cb74602afb44f811b32f5b1c827a3c087d0bfd775a4d15e5f967220324260cdfba577f4fa3b560242595d242f5783fef0bf9cc217851638dc265e42f575b67576f65ba33797b678e4f767af10cdaacd7fa09342976572ac926ddc9158836d4724adc577220ed75d1242b9b5df6c13594f29c0f2366fde1981a00e253a17b2b74291453910fe097fa1139f8ab3a0905e4097443b2643de6e80bbd7613f43b36846a65fde36d934482ac6d706757601b1e5afff7e5d2019e1d1525b982fc75f97ee31896678fe45f5f9b7619bedc611d59929508e34b0178dcf93634d6cc82f6b4857d6f161399d34932d869fb850efa819cc1859f24694665decf61bfeb4a82d499823928485e4c30568433eb3f9f916fc1ad9be0d3f5257a742e85fac12ad0f2cccb770e072ee55da1ba419be9f5c6078713e535f60dd875c9834d21a2d853dccf798ae6da06334bbbc3feef8702d0f08afb0a783cbe6a64df220a1ed012d4af7448485985ff0a9e7db204be96e04e1de7eae947e9873eede07e85daf9e4c41a45338f1517e4f5f7e8fd8956609cd49b4672ebb965089ae3dba3572a45ead681a5f9ac64f7515a4719d2cbf0ea5ec6c1ca7b3e464b1deb0194ecaf02a48731caf698cf4d626fb5790f754888dd7c2b3444b3e8e6a1af286069e805d787a5f8e28bdaa567205262f6e0a8c7f80d7e9dd1cf1927576b23284eebe841116b20cad132f0b1f8609cc8a8873c85dea2000f632655f1c311953e44bea148ded0e02e5b2ba61609538c04576b0c199b3af0643ebc92c740c4e0a501b97a0034db8ec623684d0c08a1c03e41356efc6be36046a5944fccda633383c19bd19af053b051b283e8da490d31a79cf6c2a3924201b9c8975b215b368a1ecec59b0c957c2c4b112d0ce662768759fa16d7e1cda01d507514c8493bfab36565335b7f33e59baa99b9e28f722e8fab080b8ae5352883e5cc576aed084a94b6a7fd93d1325cf05a179e6ad015ac119b409d207c6974db16c2d6115316bc6e3e924c0cab592f35daf15c29e76bcaacf7a294df4bd4b47733277029c393ec3aa81dbc7cdfe3d5e86e41a67f62d3e59e8ad66cbdffbf159ff57caf059ed46859d4354405ee79918a0390fc5a779e3496c12064fc5161289d77d2330f101a2f457105654f421791dfe61afd83bc628a47cd5ae579c0fbee3bd6f158bd1997255083ba658df1663988be5239605593551886470d7dbe1f28f2bdd65cffd8511c3ba0d6a06ac6aaf3d785216f19568ba67c3986857aef636eaa696c5e50fa9109f6128e456d8af149aa469e02a95c17c7eb11211b186d7d52d7d306e50d076b5d5446edba2d531e6868b9d519760303bd5ee4ddb7674b7607625205f329552a6b1dccc79d7cc6afc6d3f71dd226b2b1ddefd6223eac169640eaaf5662ec6eb50533e9f3e6d8b550379161eb4e9f0ea0cab074b5a44a5ce0b5393748c7da5769d892bf88f04a58e50851f148b45a095b20c85e6fb475cb126022b55d12c020dc3ec336828a8300173c977b251c848262b66892d6f25010e56e323f1ff8bc59a613661005b6f73303e1c7f56b8e8c6e42e8d43b63ba1d01f5fc5a490c47f3016a5987f9f2c808902818a092bb5bb940786043ce7d4d9a73a225e041038bf68a8fb41ad2ca7f1031656e2b3073d03497997604fd3494b5ff1c0cd212d0a9704212627de2b7d8c4f0084924c28226235cb949f6851439077b8371fe4fdaed8 +expected_shared_secret = 35d2a2ab0e91d365a3e2e99bbe3f5121f2eeb528305cc7730f679e10ec1c9b8a + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 7bd4ae7ac89ccf0180b971854b229829c15ed8119f77ea8c7a80a4b7290b92a4bd7ed21e3b317e15d2ae5593ae3b3413d4552b767b5c264a2e31c28164e18c424a00b013389663ca580ba5b94a5e3c3a9234f15de0f4aab90a240b55b6cf6c4bf5d29ba93480014023f25c66813996f674cad2f72c34882bc441a851413560f54df40146fe9c634ce98a8a659b38d71cbdf934d29bb4c469c660190fccb1820cc365490a8a79228b79d95c3850c536f7ced9ebaa92c159e5f9a28c9562beb95d9fa000371a2670e5b066d16e5af730c59a03b8d2364eb048df031618d09e8c07781957b3d06c6ad4534149fa65f8c513733b8b095b6badec8d0ec0cff1618f5b754e71f50f3f7c9a209acbff1505a7a40621b0aa817a9f7c6a1caa1441af16606376c845c473b89bc8cbf95460192632098bfbec366b1914d9216b16a19c8cb45204379a782c203614b37fe411dca18c20cc033cd6510b649c09431afe167826576e19d425026b02f628c92e389d884a8e5975c3a3a252e0443239305e30bc6e73d33fd3b0cc63a8484721157a491535ec1918a99584808e75c26de2535227a7120bf97b64f320743338c642bdc9d02b45a29903f22ef3e789e29c4119acb125347749f373c3f4156a2ba0bdaa51fdab2185bab69801055c1743e7f7541198cd6935598cd00ab2a051667ab0fc67b9751aa6cb76b38b51754d66296d8abea1e6268d410c68412424c780bf8198a9bbb1227771114baad6a63977163fd432131f96168131cbcb536b8d223d521583e9b31e025abdec005a6ec66396d94b17436609e6205f1610a805cb39240bf3d19f81b20cfb94cef7c10bc7b3110b2231c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63165c07a81e15d8a5313552728bc5c2b7ecbc3e35975a9bc5c341a7d6967757bb7c67eb279f7b34c33f95dfa49185f908686a55cba343af19635d07b3a23d6442d15cfe58c04ab586930029d072704b546a4af3aa9cdfa148018954a857b3c8992d1c567e3b20ec300ac438b53ec808ad0753cb8026703c1892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71387c09ae312e00368ed4198fd23884f1bba5651ccb94488166943b2972ac73615a21e32ea83b9b23596aefec1785329238e210fa1528243ab9fcfb974a6316e26217d278596d188c43684d8c349d91cb43d301c961e4b51b51b202c58ddaa10425412f13228d16fc0c75e2b8eba686fe5172768378f16785247b9c6e1ccd9929a8d17a829566b640f0744bf565ea512402707e78aaa6809b75c5154dcf70bdea1cc05902bed4bacc3a6c3518d2a605cb96e3cbc5209239f4994df6b503d5f16e04562ed689a2130334ffe99b093a5cbe2282321551e943ba7c988561d332663ac4e8b367427133cd216240f659d1542e54e4ac32c42da7c39c0b5c105ddb872a9b617bf386d7259661c2823522198802be252747381053ceac84c5f827339c90812615eeda92dd38c2e1db2268a3929087480f393643d17cdec6cd059c2b810b464646a26427cee030b311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b42099de3c6d252467c0525131128b18508aac196a8b45c013519d52950a16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f5a16a98857d7f57945f05925b45a55209895b7ccd7a9831d93ccffe55a8ee0c63cc57a10a0c8f905542856594bb41359fa9f5c312ae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3c9222c020280f77b9b731514d2ba49b1b0b0e6533684fc5ef2665c25840426563ec3a2aa0a01812186021d40c4f3519da9799feac06afbf04cd390c0a52a0b687a5ef0877f053c319fa51ce7e53aad0313ba3b6a7ba5892a50cead19356d8068d1a93681833ed4b8c975e99d969aafe1a6a5c2326c4e290d65eaae1323125238303719c545202178ba17eeaa1504f13cd96838b7560c1a35b1257a1672c599b1b993a55ca982a1ae29b6664998469f171865562ee027c4644234f7e3b14621c811caab7498b204a55c8b302033219d6b2b9bf7939e9fe4523aa9cc9a41a1ce11c18fd6bb9bcaa8970534a7106199b76975ea8af98233f031a371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = pass +expected_ciphertext = 3a0a5b632ed69517af9feeedba86c25ebe6a1a73c852db53637c6616ea2a1e77c02d3330758a95e34454346f64f88782b959407df9286028dbdad2ceeeafed8863a1d10b200b32eef145eed3ce167440f908efd4a905008cdc275a3afc61c4e124978f7bcec7bc7a045bd514154ccb0332de24fb83e37237d6e24e76a7a9ec7461397a536985a1cc2ff710f659a3bbe89fd4d3927473ecc8a11186b4457ab2a68083acfc75f7442a315d8b0b2b034f89a39b29fbc96956dbdb5651a3f349cc598b2f11bcb8762f9106f3c50db6b74fba67d67c47f12f4b82d3f6a424c38fc71ee1d82db9dc83536d54233b3ed286b996451fadd4fba2545a3d0f08e35c733a6ba865417607545c0840deb556f5c6381971d9ec96531514ae7d957b11b99a22c795172e7a948be60376dde244e9f00a5e9faa5e2870f39dbc39b863f5841020e30cc908b9d762dfbfdb84c5477dd2cd5fb920611531ef17325bd1e5b284a931c29db3ad9a544f7ebad407396af4ac31834960499c637e7a0dad0800742d14f2d62a0565746ddbbc099f2f357c674a68afa3f9cd157e254f80c24225268d6ce9338ed1b60372de9d90f5b787255aa9c9db05f424e2d8552ae24f603c54455aada7b7e41f2b46c1c6c0746191cb6a86575859aed9170787831345e890057966b5e39fe827000b4f571075475b2a157281896d1c897e52b900bca93d0806e6f41fed04340d8c12b5e5aca961135bec95a87c2221389f4e4f728438201b37bf817c69ef070f0d6f683d3a5ae5a2b1c4ad2af523e04a5df0414de537c5501eb94d954f1203ad96c1744011e027da4db58ce64808809464b48d483cf37406affe1b1ab8a883fa30bd44d8b12a4091f00e2ee789b1657209025b1dc11ab20a5aac601cd053a6eaeaddc522907464a8b7f447e98a23863ea694e7d675f59850dcc1a2303b9c60a44a9093c6e6ef3f8e57c1c43d237630eeef60d8c4de2c1ed17c05762e9ac388682f8bc22d296cde5e301ae53f0a3537f3a1559e1e9ee1ffc56f6de4df77ea50ddb98b03060b342ffcb49411d332eebc366a8cb577523b487845294071cf84a7eb9aa4ee5ab9712a2949b45729a813e35a3669726bc8c470c51b42afa1bb7e85cbb7cc784d50d0736cc605acf9b7ec8ca31e681816424abfb1fdc64a0d2b55045edbd7eaa51c790d8073bd29701e378d131b51abd1a23ec799e7fb94a451ba63c3dadd061e9e6edd3de92f279238cb125dd57237c560a81e5f3788fa70e1ba3497985bbfb8ebded19f93d658e8cd70a47edd4adabbe33bcf1c8a95785901b7e5fea98637cb4d71e59133d64c16fb2f1cab7342878035b6cf25d312997dac69120faaae39fa8ad10c5354cbf0120e894a6f97de6e091c3ee9366ec2e13c6800a197eaebac9a75a515b9f0a23f20bfc704675b473858dd7e812125029dd3c91f2d86ef19b5d536f9fe345e6e38995eeeb0aa8adabf0fc2647f71f4d742cedc71f52a85f42a6cc65da3ea7e05c0d40be45a61c0c81a4e994c185bbdcec33bf81100c113dbdb8956db9a75b629bd3bdb72412c0c321b8406264ea50cc65c4a938e29f3dbb2cf910ccb3a7a1374ceac6c412233889f3189e093c6d11b92c01ca94506aff55e09cceca978aa14cb7fe511effdd33f2a296b482f5a34683f9e1c64168908dfe7626e2f8fc9dbc535bb353e8833e9a1c8ed51a4fce122b2c7fdb129a960ea642c3bdf4d03efc2a2397bdf19aeb17ceb6220c7031e0a5159173de6d8b7cb106654b37d669527934623f64d2bbacd617b708e6d1770deb3443f27deaa55c3e0659a37be0ce8d4cd87771f8d6a59e19858f0b674a2b7abf263f2d4e821cc72581e5a07f72b5295cec2e45f1c97ab33d174ca160328b0c968f69d2f08a1d4e37e6a3f36ac18d0ca50175ec38cd38d546815a2911571556fb7ccfbfe9b1473ff91c833314b773e8ead462227132979924a20010fe3b702023777b79fb0f3d413f2e3a97e85dddd1289c76a1d31fa131d0b75d74665336270833516ace2a5774f10018ea505ab947a896bed114ba5483b69ebc9cf3a70a5501451d9138bdb63e2dda78b1e1fe4a78ac7f204a5c0d40d6f38c17162d0825e0b358ed116717ede8b9b8c79694930b5b6d22d661ea42a22c9ac8f99937a77a22d88a4d55fd69ba328e3e96fa3b9e43b95ec0f732df91e245ebc0ae0de65f1f1129cab5aa56137 +expected_shared_secret = 8084cfff3d54b7680e737ed71c37e449f1f9d74bf6735696c46910b13d42d1f1 + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = 202275f93924ffe79141ea0abf85a4c970c45e0acfb20c426cf545caeb594907a23be6cdcd38486ef2cc1234054fa47c50c629657c91e71103c029539e632089461effb67a0f8cbe74b91793ab033bd89a2a0a68ef390ac90669aec42530c785ec3a0dab424c8184bb051780b4e80838539c81a5097d42cb854cbf324a26f3cc65024a6404cc2a335378fd10adc8e10cb99c323ddc55e70b32a06cbfab829e53aa059163c46339b7fa1090244a358dc647d4b1783b59383a0988ace605ad979f655038aa422981ababaa0c2f28899a352572f4f6515d62649cf88591ab7da91ca2c0e44aefd16ed3f174cbd0bedb7736363c609eba4655b2a31ba20f05e412282b28e15125eb212596e0c54181028cec9b106849ac366f62e8c1c5ec9502f01ecfc1749fa3bd7b251b2a09c731c468dc2988f69649fa9b46e9d244df903ac9004f09cb1dbcc9c69b33ab9e928fd2072cfed1186f9799ee3c2ccc2b68a3d662c7fb4438240d6e0b70ce98478e6c28294047400b9088eb4aae3a5a076979af8ab4234164b0846a9904ade949742d7402c8516ccbfb1d30581a288c9d1c69360a2b06b21541382ac9b4101b96d4952e89725258cf7fd33ac4f522d12b6f65b884f33a0a4d1b0e41d660d0861beca59164f8760d3274d6643ef7d13043d63a4cec67961c808cd64b9728872f74412b8867a2e25cc58174653b2a1a0ac0a24316f4c14281a0a739bab2de26ba73c4921c50b909d188e8b3c4db1274491c792028515930ad45e667c9e6870d204554556bfff44d09f95fe9dcb7370320bc6740f3053ec5b7396db400ac671b01f33dbae59838741b59e4c7f076a92ce92c5213adadc47c8f50bcd4756de7642799d5477967339e01455e6898d2194a7aa724338946b7db70608c0337e305ac876f3d87c6ad857162e491e469bf62c26285f9b817858b149358cb67248a298cb21771f1504f4997965ea38036d274ad72849164262fb58f46cc96ffd75f23b4a0c990a9d59160e4365b07909f7874a22ef1362035312f43b6272bc47eec6ce9c0b4418b60c5022502485bd92730ee75a9bb4a8c81a03ad4b292f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe274c268a11afd003beabb50d12b8550eb3008ddbca593c7bbdf6768fb561ac452d32c77d74352310e4322ee53b9ba879d511368b445df20aa17a7ac8f205a302f75f3c679557f2a37de221cde6c8f7248e73ec25de603afbc5baf1b076dc3b304550c198b6b49159c12490bd964b661e6ac0eeb2b09a78941675a2132527d0016d89ea6b3cec5d19f1818e4501134947a547957a195807774a8c40a9c50833790aba5628c2eec2148dd0430294b331235d4246770c293046a237f03487993043573a71f250090aeb01dcecae4b878633c59b5403abb02151d8048dad408473d63cdd018d3d295a46ab556c8aca53495683976b2186c6c818b852005d20964cdbcb6061a50910b9c429ba9f10a06f4e053c9e1c4cbeaac35949c8f23c3e890234ca990b2bc890d43c2a4051aa058a402b7caf4a3925f52c95c6b6c7d26b4e3d43b21d7b0fff3b37e5d33e391b5e617785f52128c581969e094d82d062a8631a76b093703626d8708c5f310abc1951ee8984bf858a7b582038a6a624f5921257764890b73cc9af94e5aa82d831f341486aac17cf29ac351483f7f26c80111f6715634ab69ca71a6893b13bbf50cf58c16b29d6b7c9b58fb3c0b9295a6320210f1db8193bb8a57889a28ce3b196f32cef048a4d60466e3857c07847e3883c1b7bab89224c94fabb3fdb921ee3c7fb716ae8c520d547b1ac49cbad256ef43015fbd722b8b31d6db24937338e6614402d9272ed014710fc5b0a7105e6659de2513101b22c81dba972fabbf23756b5d524d41a15b6d682a1894e8439b6946c64d10732ac603992353f03e61c1a136011b52c624b0943a3464ee92b8a7b970ab5ba9713205e4a22b6a12e063c35e8c65470b32f9e29255d9847de80cae1091fa536213078bba0181fa33bad7f3003d2065b8d997a7207b595994e816a1979ac5174137ead82bd88295f2cbc77e01c0fc9119ffcf25d8f2044a16aca9ca052bf917746109320dc076e1895399741ee690702b477a2d07242e03dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = pass +expected_ciphertext = 5f87f10c9a250dd54145314983d0bdf99d7c5ad004b950ee81798763ce02525da39e2fc6c3b09dc64287954539c76011a7a087e9e387ed105a17f478b1dd601026ef979241e53fed94ad15c9996fbfd8863c2f2c2ac100529acb319a0be562e28ffad82ca952774ac27f6cc8532ff3dab15c6dcee9c1a670f0228fdeaf5563ce7c9c053ca328891cd49e494ed4ab9642707c67222753c82e7255c1778fe549bbb334d4e2015a6ad18d4c6552f7be3b545797a233fbd1a8b57771cc1433f298b758c43354f0a6a63e399d958dd8abe0bc4a6badecece4f7652f1a3789739b20d777b7e606751bad09a18d5fb17383b677feb6c99a3b7e55791af134b2942e67c6ed6b39acc417080cea35a9f70ab9745fc329986fb1f5e155695307748b258346a6b71fb46be707f975c91115688d944a2274044661bb803e4ab5b0cd428a080fb023e826acdfd70bf66482a1cf18d020079b65314c5070b9394efcfe0dfae0ead326d0124d1d8b80cfc3a75ff7def710f7a0b758981dc0a385854a2556cf9cfb1194efa38eaeaf80617398c3208eefc0ad72393f6a5ed527806d4b8221e96d73f80ed1a421aa308dc4bb9c0c928757e9915c08b0d21de69918953c9c7bd0c71b36deb4d5939d798fbfca60b30249d8c97ba3c4c38d57f31fdbcde15427abe36204e34ff1e1690f3ee87a7ba5094a2f45940dc2403cab349808fbdacabccf6f4afadd798bf1ed09d5b39458a0d6e279b08e5d046bbc2f08e3ff4dc97f4f78e02b069745c69606f9fed93913c3b7c4c744722edfb9ab431b05d8c2e3e3ba677326b0dc70f07c5a519a01eb18c8df7e4441dd86c1f704ca6aa5c073101ea2c64f36620c5d692fa60ce347ab1c466f565142cf19d09926aced32dc5f1127d2baf35a718eba32c9666e38b3496a1294f28d3ceae78293cb82c0b7755b26cbacdbaef00b32460f0e1fc898a724448657bc658d6a847241f20f14fec5a7b8a9d7c7b5491d2e05cccc0c9ba11e501e51ade82e4582db34ced28171e68da79c7e008d5a99757b9cc1e9c99fdf6f919dd120435e9023b6d431566291329037f802ba51ced6dee11e10c762723db6a1063e01ca2222d604b78b2dee4f653a2e6e2d572c2cb934c019a5c12e608bf39414db933fe7e7d2822f0e4dd9604cff7326ed0bbac843e186ab1826dd3a76ee6e82138ced21b9cfd11d4da585634328fbf16930eb70e66ba11d2b893c63430bcf3d0e629d27f7b78478da35a61e81bea0d4089dea702fff9db2b9b7600c1080c566411128f9416e61a0b09828cf01054693e4624b1a3ee03589f5729e6c8a73fd2104eda181ddffde4daea2187df8f1d9843123d906cc847326012a1b6a465b0da9aec135b5ecbbf3378e22c5d2b2f9266f8f0537506fe45397d97721f7952543a105b232a5bf705bda55d390d80e8809194f7d3bbaa39ce2ab2c27bfad073c5801317e11a44c809c23126f1ebc6f3765a331f44c0fc1fb31e315fa4471cbd2e21c0937ba67c71e801239035da9484060f78cbd38ca11efe0bbe9bfd5a7ab7117c4b49004bef93f9b37ec78013064c6d5aba18ac380cc27c02cf90f6745d01f4f9fad5f1ff3e26d01ba8ec7325e06ec6171422147f4f52def5f074462ba28dc0f4997ee46adcab9dc62a50ee400f1ed5c2ea22dd25eb92f8557ccd1b5bb0ebf01a9561e551398eb4a9296c96b1e715aa1e223d18797de63f6f38a049e1e424f295d0a966789aac7d1b487dc51fe612fc210b768cf09dab2e0bf095fe3b420d31c7889bdaf046152bd0c268bef13f14107a448c144f75b3d4aeb366da3dd67f98766be43735d5d93c48e59d51cbd0fd2f6356d791f0b82198615a2ca0a1468a3c497da5a694f73eb90beceda55b34aa410a564c3596cb5621cca2f16f5043f20635b602bea75fba43e3e950cff76598a3cca481773b09edf9fe224c3ed588256dd49eee5dc1abee4cf6fa83f33bea1e8116ef235e8e540fc99224c9a781f62f16c73f7399d13fd9c44a19bd747e73eea512e2bbc87c8f8ead1eccd3f7888f67d60cc5dd8c601fe39bc6ce85279e63fb738499a08912e5895f98d25af90c8f0396e6f9f0221854caf8156ce2f231b38adba6e9ae1c1afec44649e859227526aca8f4139fd45e105f5a1492613ccaddb59f9b918c799d3b38e1b3ccfe50e10ee01dfd7ded945a40d76ca4643df86289511138cdfc8fe0141 +expected_shared_secret = 3e94b68a80291e957f9dd0a15b112ad75bfa07951ccb36c2de610e6755a4a0d6 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = d5ba702b276804716279e61c4b3a599005270578414141c09d070d9302cbb10aac8b8483f11b1044cb83efb8315ff38feccb09d1775e1e29c59b1759d894ccafbc147b228debb52e83d2584552bd15b9b18f02ba12c6669ef94190126f6fe364d106a9d4762522f25a0298cb5e40cd6b89045f275456e8bc32e2c11835b31e6aa628e50e28a9a18226c73343479d0ac61e5a81c6a38c0506477e58001b6890155c3a71f21e1df151660c376cc61d90d93331801b31dba89b6853c2630d33578551399164db647665ad52f912831a956b8ab283f91c10209b0b055ba765cc75587df545b670ea13c6b917393666bd6a9e07a21ac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837b02600c03c9f8f1481414a241766df430a6dec7936db2374eba1dddcaa58c8a2984094c57349a78102a48e48c450ca7135a057eb2858a6176e67316ad21122c44643fd42cded7caa55a628a503366077058b286aea157e540c598822c3736aaba5298a41765fb949190977456e1b5c1810db1301342104b9526a82459a0f78b9a7e74808a49243a0902d8c6485f887ce62697a72474a1fab0d1342d5ab7a8d9ea38d3b129661c2ceac177d63a59d5b62be8a11379a51055b36ef78817b677ac30f05bd38c700cda17d52b02e8b19f09354ae074b4365ab379667744363b9d4ba17c061ef955631f1ca916a74cddf05160b82994c49688d71612676bb0d95f6fc58d92970fb71c3c2a250b4161b32b3405abd605d0a94ae017bb28801ea54588bbf0b9caa8cb5920bb02730454085871469cbccbbb26911d934680afda6ede5b29b0e4a0f9b15d13392647ec9ab1922943c88dca974af1c95d01866e906221c901319e2bb4db5807d3b22ebc077834c29aa555226903a4b53c7b5d29c226144095e03a4886a18a26b99f389a71c41849f10fafe816d213be109ab7ed104114678d16242547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fac2d2405bef464cc60c58efc595da6c1ada9200d8eb1631f119e99b38970db26be02333be37e661c2bcb483dd1156a7e016dbe39af9ba9a7a6fa8173033bf4283e5160b1b2d4914f453bcf3406304859205118c6056243209c87a76a7c3259258786e6c64b0405bb8ae22e33b1617bc9815bf57b182748cbc6c4e8cac9a9a22965e560fac66beee32f7b8248c241cb3213194221c704bc821185041ae5510689a8d7c4ce5a6c3720e9c845116d2b3b9de703937bf500c9249fd3b2b134998ca657562b19857f6acf575264eb1b0b27d50049542d3f87041ddb755cfb340fd122e4c46663a7b556921b41b50713d71cb20a7888955689fa4e43172f134b1a2b628119c22c391408b16092cd6c8fcd6cad8ef34e129c6d5fb8881725a3b8180a14ccb625a65ae7c59f8b7888afb126f2d8ae8457a273c453cfe69726d951b3a241df583af9995dcbd73223884560258459d0bca1e794c94214276547d3d740a8608c33662eda195f4e26b90d86955c2b4c8470592d1c075bba0fb49b6732b2954fe76d0dc3b3e840865fdac146f03ba0f336f0397c6fd450770a2bfa5837f46096d3c673c562c9ce79b5e978c2a40450ed36b43210386a769de3a9063b93455b694c5cb3837e865ae61b82aa96661e57c41e405d260bc7ac84cc0e1c7515c47c320c61723177f0f57f599958dec24a3f81ab7f1b759c61487a243ff13790de540bbd1b90af233d8658b2805152183bb220e1ce017795ba97753e9c06620a85d4e28591aa6c1f440240e9c22a9acbdb568a98eb745ef435805cc00c2722b0822c1a88b8b80cd05ad2a69c6a356889c2389ac128c49d627a1f3c844ec85b82a405a2e1834cb753b415e32629b7397713aac7c70ef01a7bb3db86ae13b4ed51cc77e2a90de08c77d6938b903e05913477d1c38c98a80dd034caa3746018bc32034b27602732bb0a9cca9dabdb795c6bbe181576e69413c419674b646386b62c0eb8251572a630b087851892bbf726fca0b7dd8a170f19100d6087c191ab56f066a3f61f973c47fc62c331287dec02518039b32e7c320376b0fd82788e2a8ef38b1dd977889c2712ad258d4feb5f7426a4ed147e742b0995a97c2ad876e1860aac6ccaa82287edc68267362ea53ba9d0d91549a448fbb43e3f90802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = pass +expected_ciphertext = 8859218dac402d756e7a282c88c77ff1c320193e436eeefeb6ed478ceea116b288467862926d741ad4b1074423ea57f8f1d6a7b751e34f88947d5c80476fcbb5385b8dbbd21ba11a69e646dbc24038abde3e8ac75ff1ae80097010ccbc99dcbc7d220ca8f1b5580e9585a0c193439b6de6d9d33379c24be96072ebad553105a3041c501483a34b2e27d81a3ea479b18df3d813db7c08d949cef6ef74daf1a96e2c2fc3a92f1d865e352f39e7a28c55c81acf68d41552c4ce3079ab0f797ee464eb213097cf08565bb689a4759d3dce560c460c2ea3d0bdcbff0998be2594f0cdcf25098d70776f6460e4f42a17575821565481e3570becbd44e9402b3db722bb2fd9bc6ff99270e5b6ac636346ac846e1e24f58d4f7d86691abee15e29f143ab5247100dbe772271acc19d263d737937ddd4408b6989364f9605c626a1ce9a5155dfa2719b0235a1d6fb3c9eb231f4144a114b26620574d29fb558d3b6b8e5bd07cf0a86905ab3846e56b7bf778279fec9768d6747014400b2b6641292ad225d18b23329f126c3e0e018c109760cfd5643f1b213144fec5d69e73ecd2f3d0209537473b92b35f69eebd7ad649fa435669da9ccfbac5f6d56cae98c92d2ff71cd08e4f7f2223290c9a2fa06ca83438e0ee184df2316b1b626c2104c68d778cf971a3504b38ff77d8d784e75d04e792ef0b54e5b933ee027d5e0015326be8618e35675949874ce976d39bd39080f8c9d03842e7dfe17e630df0379baf004735009b86b631d87f263ac14b0c018da9de19b24ba1b455cb71a4d4e88003ba9ff5b26d02e9592c55afc7761d98cff35df75665067af96f7dcd71587701a31295498c81886c38dc7e4ddc8077f5636ccca01040cdd9b80352cb638626c7a183a8e268f60830e24af051179b2c71fa9c41b61bd3a9e822ff619434e4a3b582c6e7dbfaa886622083a1af2e8c6e2c69762009d846563b82ec926a4852ba381e6abdd8e9fc0d29ec6b337bc71ae6cd3dcf9d10baf3d5dbc44c1ff54993b736e6fe3bf683e68a2634a77f8fd2297bd02366c5dbbcb80af4696b2ef13a6a841d6684b3fc127d9dc242c20d3d305db264555892e2ea0f9aea511c1308ecd6a4df93f1e8cb66e02f8c5a8ab94457bb656693c068f706b6205b729258b69561cca577ea435106487ba79e394a039a80d7f1f8f1bb16018aa28d0e1558ca9b9a52d7ba3465d93cc4fe1565b24b8a179ef08315e474bedf202657c52e552c6892aed26403a7b22c45e657ebe229f5fe6603462369ef07e82ec7f3c74db76de728fa92d9f73b7b141b4069eb3e8a4be72da94b84edd23c4a4682d2398f16722f17cb28ef635983a8f60276e5f2070c2da3525eed47449671663d5c5bc06e298d1b1ca5f409a336292be5c666ea295ed55f1bab1e9b59216875bb7abd34e2dd18d503f22ab66d402ce9393ae077028327d80973b4b11b1afd6975b55e41e331b127ef2f0b8626c5e0f2c83067309e15551fc5a76b2e353a702ac80391f84ce87d07ff77a4b7c528137de655d951d1b991da763a3a1116135c29707e74f29ac2b8d1682c1ea01cbaffcacab644654d9ee7485d41dabfa19aeaafc1f2b3c650c5b065c9f8a9c84d786c99d633607e3493da11790b853c37538fef57246dfd0605cde145e25d3b3d13441f2f3c6ea5005526e7c7a514547ab9bdfc40e46b017ce4f47aa417101b6acde4f8bc7891fe9b63b505d9d259ea0346253531638e35f5e992a7c662e96b296c91dabe688aa0061872ec39889451d1f8e237bf7cab21a1ff87503ef9d8e84b6cfb7e88661e38f4ba121135d2d9433e46d51a6b1c82ba8827cdc1c79b56692b03b3761092b983906beca37a675c22b2f11dae846880dc90b91efc690b1819743c4952fe9fa494a3cc6db7b056e04cc2b0859a869900d90a38f2556a09b7c0b5e8188e5415547f8ffccd7cf2b815e6117a2a1a5525a6a385d1444bbea0fdf4b889d3d71690e04df0a19e3e2128aee9634638da69bcb1f432e2fae59dcb23106250516aadfcb71a8a6dd3a7de9a298e581a7a0bcf2a7f12e1a31c3e0f806cf4836d1f6f93fb0805a433c7b311dadc784d4db480dd755386ba4c2e80e9c37d77350719429f5b6755681ab3932e8afcdb61198c95b46400e3eb893b2ffaaa5171fb4c94dbe7780777447239c956c7689ce17fca998e1e1ab4bde954f63c757f523487397 +expected_shared_secret = 900649130f9c28082eab5ce3d128593eeaae89667d7fa4da23fcdfc1573995fa + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 707206a4b96ff9ac116a585f4394c4e83574bd16364b02bcc4c89dab6231e5ca7550517a335536b08665a136b47cf76ef816b037e91c3aec389b2411f3b397c70847a3f178509357db63a5d5caa882b2079644af11f01d18d9b79fc92744850a7e8b1c39e479c57b887e854cad028d17c84f5dd90dbb2042fdfc82db061afc7245c458b05f934d08849bef6bbd90349c4bac3ce44c1a51c622734265051787f7509a30d9ccf98250b42cc8e75c6d62a5a53944484578b262850e06b8717508c75d702783781290f64a412bc3f741312ecb795d15c17d198334816582209606210b73865fe79662943552b69b11bd141637b054a64497cea157e9156da70891da159c3e138f86c87e27376eab0204f8ec1edcf49ba47b1521870e46171d18268d277c1467b3be6c8c6895461166fc2c3f597fa6478348f640e44530f966c3008902c8625b46cc6120eb2d82506b01e45a9ed7a19f1c0df13c0346aab1f2cab8e01032b1f303147b5ea7e149b4bc19772408cb923e06614c9b1cb76e0b1d2eb1c4d1f6bd8294b280cb9ebae45cf0943c03b239677b7ea7c71265b04ca7c1580578768deb1cf10a2898143ef9d1c5d614b76a8322331a09c48422fd8b1c822384ae1886ff108e930692263965e949319ab94ee1b6763e460a0812780428aee4d446a61254722c9308c512711ab175312e39467aa21bcf454b8289803d85f33400d659dd8369dde71be20907651bae89d861def131ff805f56557cad430d22cb84a4aa65ae68c3f278b5816b86bdf57188240f60b54a8606b74cda0c47323639a578eda52575a32efe03b349b6938d763dbf4c44f13a0f92f75fc091658c60a32691a52c78569f322521799c91aa2cb550c9a683b061647cde186ea2ba57a8a1ca929420ef1895f2193cc6944a26e2688e611ec0124269f8c9e18c4032b731db827fe2930d3479528da2c2acd56a8182231b501b05c6383b070190782225d732f84273eb9655b2a4c5d04256a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd750bfbc28696808f52b13b09e43ff5cc098bb2a80b4c8f6a3c8a805cc6c69b7b02ec4f67651c65268431057fc7d1cadd8c4ba4965d67db44ab0c54926723a0842546fb0799e71483169ad17b60f9353777765157bc7e25d02ebcf9198c70a53bfc0fc7d51a42e260f7c5222a519937a48492ba079df30adaf127db4ccff100112e155501b3719a2a209983358771b05b38ceea677be4a4b086132c12f4594f427400f6ba5af4a07673464118cacd99a8ae5501ab22a235173412479cd759139d18900ce6ad44e0ca5ac230caeb82b6a98da48b318b620ef7093f06f20b5a0b4b95d986aada54891a00314094ca9478b790825a368f2f092d2978195ef2c52b64602929837d0b3efa65a61991ab61d8cd87f618cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a43272d8ff943261c5bda7a4f1092c9a6b7481f05bc3ff05ca5f1cd0b2bceb936233e0952f3380c4b7a1612c5628d5a6a05f837597c94ac061658c53f3da8ccae56adfa5a8156638be426cbee2025860c105da76b0e953c69957e649c5bf7151c77160a1d2ac9c541a80ab20c1b866c4fea987e30790b64b8aa5b12bf3429f47585ddc8780b9a6e1e7a3c030226ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf47186107219df88962b302010b755e002cce9d87781e4b717825fadc62a1a95589694581a18a188143d22f1bbf8769b3da59813fb963a78adb8d82b6155b02889371df684e3060134e738c682a03da9c62d2922c06425ffe8c2e18346e6f5296b7c4722e065d984cd17c8590b202865761162e6576a403e2806bcf618101fd5155702364f6920c45470bc9b1180b259c65bb552253406697e2371224a80045295a0e9b06899d06bf2b5824c9b2e6ca144647b01f45a811102afc4c7682e4b7ff8bb4464987757752942ac106389c847ab4dacc14c22b40cbed29d1e81c89704c21ea25747114f7b910ae8715b55671fdca0545007266f08851dc22446436e15827a1e834f270b38e5ec60222b1724c6054af281747739178c49ee04ce0fd39d5e7cc65644ae9a60303aa54a28a7c0ec4ac2ce7149fb8932ee26b67c2bce886a5fc9f321f5b06a03fa01d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = pass +expected_ciphertext = 2043ec62ebe64855ce8a3c4dd252b9c6c7c7102b4a57b402a09f458f187cda36de17f2ba0f0702a7a49620d0a125036156a808953dabae6773b7085a9cc7df2487ce4d447828837c2647d01de3e84970a90c57ddec48def3e04281b88a6b45fdafc08172f024c563090691878a744ee6f372e798f06ee94b05933b58ae1147ccec96dfc76a6a9bff0fa662f5cc5a322292308300695fb8d4cb53912e7b4dca893970150ba93e6e3f1b6d8929c1a4da3748a6d3757c3e55e7a7f452af71ccccf0c5cfd4391f93d9ef0c415b164a3b205073d6633f07177ff9f533a40aafa084e05698b59207e2218d7003064b96d18f23ac12ca34fd6c652699340477b94f41ecb0480cfd1a71a550020a11485583a01bbd0ca04f29ce34fbba650f93c2098e7f0a925054949e9d31995ae05dceb5762f0fe32b2999e6e5a61d5ffc184cfa143e701d01b64744558e58926ea0ae3e8990a73008fa4ce137ecc722efcec77be0f9de7725544a9bbefb03af345a73b511cc0663f4d5980c97646dbc02abbf3553c9d4aa690026fbca616b7b290d3d67eec14dacc9566d7d0753098b76b0d7326018e8213a68eb5a129fcba227372468e04c2912b2e30391fe87abc25b9faea185117ee9fa4ba0efe0b4f01187919f45acc11b8c9c6f6323bab07beab92550a6cd62336a428052dbc55271687de791dd52ae20573302dbdd0e65750e931e19e56a612ebd3bf86cd95eb7dc5a25bb96ac2e0a374233ba0be71dcffbfd32fa861f05ea470bd8da19bef702925f31a9181b319c1c1c027139c643765b2fa9611adaebc723d06436f4923f2523780c0ac798d4a32f3e1a0269d23655238d38c24e597d20164b431f3645b792a809b508c0ab84363990efd5f7f0cfdef164de6801999fe9cea0293fad6d9e1a49b6fd03bc14d25e363754fb7f6352265b61817f65d7fd43d75eb5e50eba144d7c6f68b52724e3dd3a7ca118bdedc1f7e26bf722fb6f2fe962d1c2b03f8ac82f07a08b6c108d724e197ed65d0e5540bb0529b0cb1407fbf6e712bddd2744b54b1564b5aa789c65b9997f27257cc81affb85164bfd2b60aea2c4d31b71bb8a5f02cd0d1ae3909bd8f5d3fbf2177eba1492709e4f6c53af4619ac450a778bf416a66fe7b6327083434ede9bdc9a1ff624707cea766b53886f290b40999e342296439df4f1b8ce20832361dcdbd6429deaf3115186cc4677ed01da35e65001b53c711d8e8e83d12f41c8676fe0a3de5232ba0256f08ce3d80b500f5b88c9474ade0ee08d160946ce76e8320f8b2ee35e71b6af0f7361813d3b42cfe88cd79bb3864aa74747a579e7143a013acf903269d4a740b58f6390e804c51d87c0266afbc992e80b27a5ba512026091deab587f93ee9f73fb6dd7959b0422728183cbe14dbfe146a6dfe8553ad3ff708b411e2a2bdc6abd6500564e847b8fb447560d9d77bc402c8b131a2110ce92d936dade0f4cb59259b06cb021b681fb4db0cce6a7f8eb43aa9d569407bcd3e241b7b7047b2c91224610fb6acbc50306fb75f696bf8ca92cfc8e7f2bd5b9c5095f52a08acbb5939a206e392048e3946f10cf4f22a9c9365f9e475e09eb95e42b547fa06f6be566ea796fae62818c4627fcda9de3f1a49cd29b6ee2f538e5e92ef719a631a0ff80502698846f2a6454a5f8b34dcff2a19b924e49a71f57fa62819f1fcea60be197e7635802d5b2cfe3ba8d9a11eec184ece5d501da8525ae45ad2a2a23e4d7999bfacc24a8bdedf78b8619d0f13add32e8d078b3cea727d993004f5b51f978eb86c8b649f4890534e182eaf9040b26b788446e2736c07bdd707cc04f1756db88eef70b1122cbb96bc88c78b0c84c1fd11e7fdf546e5756119888e44d9e95609a0dd74fcd17708cc8bd4970d7a335c00d54430986be57cea04ac1d991a779b46249a061ea30300ac5dfcafa484f2f4e184c4389e3115bb4f7a36787f920d85bcbe3fbbf1450e61d6faa050b91a3374d2f5bc3c12f79e58a0c155ec89548812ebbc27dcb8f6ca73de92b216e5ecdcf6df67dd086c7f171d7d70af96e2db706e669ae153e62aec486f53e30115538832f8668ce478cfc75b5e5bfa43402f1c59db5c88012b56c7ea59f404f5dc5f438b06232160ad1619c23f81474a0bccc4ebb9c6b32a0297ac14be4af396ba9048231ef7de50bab59a300637517159fae0478351b333d6d7ed8676784 +expected_shared_secret = 084aafffcc38ac80dfc02548df07f6e7809eb0644385abce0fc569821a907011 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 83306092965daaf95fae22ab9782be28474bab8785f6030f9b360a861c741619619a74a96fd30cb6334b6fe379c9404f95c5571b2143657c956e031f2a5a03733aa24a73224f89106f7514a8db8515bb9c7fb4179b9b410b7197dd849c3a869c687705c692842aa8bdff5169cf0937a0d669bbf54c92651449252245476b4ea5126041b5721002ff129272fcb76952791b635b8bbc6867f051935508aea7bbcd722c693990e3e8078b1629d21c09e1b417795445fbb857e8fb4f0a1aa6f761657584165d38ce815307e6d778cd63a283e081a5372b0ef040b889cf8041cc324145a571031f5c218ca816354c2c41817f196272976c2ff6115f5257cd13b373bd2a757dab65d1e1863ca4b7ce559c73ca919198ba574a9ee64047b85a6afaecc043327e0800cb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a6fc2ef7d2c4d175c2c8bc812d5b3d54695027a91baf657a60d4befe7562bdf620bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b602b02cd036a24c23816c96deb45c2a8cc7d623bc31e8811468a7c2b85c209b27364c4956b6c30c8094af8401a233c5e4d348980491ad24b04dc2706b502a9c8390ba3f611344c44bf50241cfcaadb7851685c73603b429eac840c6b9a7ada53416470f13311c2218017681204e33a588981f66a02b4e97f1cb8ab61e6a7fe45232b5545a3a35eecf43e67a4c29948206088b062b81875b632c1767789563bc947a59305afc91ac53387925b4b3c7ba24d84ab126d3b88e852433dd0ca40892d3429962be6cbeaa85a3abc46a27b525a562670c801f5f0566a7558197600439a2b98b16009f87147c55f99fb109515b125963f7240b12a4535cfa22ab53a3c5eb8c2500ca5ef9b2d26d93115480863843656c59a85b4a40cf8059d063cd2e7115d862015d059d3577cc1803e6450b811ecce3cc83e039520d6b23ef8576bd342094ff2a908f42f4ad88e483229f4ab41db2107e48aaf1b32a275425492b7bb423632e42a6c31e320528327713a86b4e83e929b217c69b34ec3afce8628c23a6747666735360b7e70bffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c4756421ac51ec963493c2d72791cfa2c69b58bd5463c544a3ca679b43ddd13ae979bcb158744d45639586959d6ac5784c074d0ca20f326696b607a206895d495f61525793a839a5631cd94bb7e39b609db1caaa3144387c46a22b2ed393060a679bcb13a7c781aa7be1a9d4d3a58a9831f15372825a08d4e41d0e3371e9f796ef0ca50e128afbb5b83ca78ad7ba50276ca2244b3452d02d803b0e8854181ed57f04aab2bfbb1a48cb949f570eeb550a9352c3887a2c37341d8881beff0acd11a8714665a05274613fb168faf6c151277ce03b9f711034e642425aea6e37f536c27ab4c859a64b96baecfa10abe982fab01e82a48538c12f2f615abb815f7fbc46d20378c77626fd4447fc088a7cf626180b2443226c0d560d028b54f884825290cb5ffabc1e152626e62816069a8f9965d89a09b9a19b9c8734a2f71808733a49f30bae54659c375de1a1181b478e08fb7ad85983d7809a4c7bbf67721beb9447191a63a10c2cc709a2d9489dba469ad9c035664aaad90bb8b7846152218635816ec4b1b39ad3b1e37201fd468a134445e183bcc3430cb2a9015a10b0369c079e60a42d387675dbb292985dbcd4b954c75b56a1152942ad9ecb12c8074c1998710826b4b1044a1c368d4808d081d7be1658193c1c0f46739ef1043f1ee38e90ea989db0c9d6d8568eaaccf1e986e4f3b39b596f4bc11e32fa03e10418dbf464f435680dccb76e0bce29005950ea7762e0a86fa4cd5e8819f3c95ff713b006155438d9211350c317589a5c599619530b664070f3715bd3947427476124f328b850603533a651a38c4119c2da956383c0090bf31a378474992636eb10b079b319c821b4ba9336f413929850550c9271f547344e682780eb9d2dc84b742b49eab256b6d8149a904ba0293a0a40731b98751a71371059b84d323970a385408807bda11497c42478bca048b1c50ed3681aa8044e8884458085b4834e313825b3951e8b743a765a166bc1a133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = pass +expected_ciphertext = 405a96bfd02c25f66daea1440e632c84fd0e021f62a71ef46f1806de1ebbeed0ce4eaca6c0c5792677a2ae3ef3e66f36536f3fd37b4a2840fb36901020d47095e73b0023d1ab420ad313b36e5d4628c99cbde76099ae1282a3434a7ff38bd5de115cfec4a56362dd68c7ac5818348b1aa3a595b724388388f3622f7ca0133fb235e6c82a28c1f4f49f45e654d3c455298a18c21dae8eeb5c2887cc258899395bf55d3e2bd75a74eac7ce9a01d806f4f5d3556d2725a10cbe44545fc0915aebf08ca5ab934ab247670ba701ae17063afb56f753987118ddfffb4337b5dd48a8cafc6b692115b9d8af156217c5f1440934491203607da68f9a90c5843264e893d8a872dc2c95c3d9fa93c8c05fce5022b39fa763c996a30897689147ff2b2a0379dc6318193d5ea90093d83abc3f51df9a263a3a7895c83c30720ae773ccb4e2e805e2f87c559d274401602642d7b992bbf63e6035d347d8d6300b345205bb0d6cbaa2bc61326f7be2afd0bc2238621b75e69b3292fa42e79980642eb4e17f77c5a797e7eff2fbe73c1cae2e5b5bbc548207fd7af48e443f259b6727b2f0297b62389bfca4c44aa3020e583efa081a71dc29ed739d30d48aee2474685625bb241e0bdadeed100931e65d6dedc94a54e6df203e702520234230b738edea749fd0a8cf9b2e2e0e13ab3dbdce8cce21b290bf0bf42493b10c1545775b3d1bab14ffb6aa26d5b1a0db66511ee75e57422c4eddaedb9b5c74d49376cbc6b9a1d6a6d1bc4854cef00a43bd4bb52a8d3fa6444064a11393dc1398a2c5af503cb97041f6de40ab849b5cf71887be298218821fd6aed1775bd27fee8a532e94ecd80733ea2099d84afda3fd65bd084a6d7ffcd4433a993af0551d580922bb0a8d3d23f9032d29450a2a34cc8eb123b95d9fe4bcd8ba7d4bd9eeea98279f02851d268aaa3de64db561acfa717657e905ec1ff6a31d1857976397ef4ffee04440e523f7cd75cdffc64fdae8bab29ab5eb0fa8f6de7cd5bfa072c1b4a63486238713e9e06e9a73a554232d5d6ab3e09652ea4434778180bc2427e7a544c90bc510f90f227ba29f6279f033a90b9063da5a596eba9acf7e627aef79eea6fd39075ed8112c7261587d941ae6cba3a19bb05492e11339d333622cf2396a3d41b3053752208766ed434c7649a1e3d348bf5857a48c0a7cea8e155d30a046169d10988ed0ccf09556ec47cfa37589a4b677c6d1e27d9742ad401cc98184328a395a70342234fcc219b5c0424dc61aa73db27177fe4f7f56d1dfef7c62f726c5b508f64d68ccd8c732fc06ce1fdb864c3f5401eda20576835d82d5b24b7e2013d8c5ccf1aa5f401566be406f7639ac38bf2c7f2389cbb966f6d1f5a493d6b5507d04e8515ccc0cc5410977816bb0310ae5d7e08ea3ae1166b230e0d3482b7a7af0761cde220694e2662bfdd29ddecce7bb8d912d9352458112a26ecbab3ecc647ed695e82e2c312b16c58665bf394410f4c5f0c422c39b6567b6805668e04712b3fe49289f3e40995bdc7f0e74b1c23ca1688a05c06688f45f4a65e945f06136cbc139469784428426e1f616f4e6016bf652fe155bd40341270e343503419d726481128ff7a263d70f0026f6f11c443be9f6d3ecc808c61369e8113c0fa0fdf49c92b9361c2667c7a9afdf8ba46feb32e7b78bea54898ea55bfe5c95b8d73641f53d5416c0f7bc38dd4281f3e09af70c9a7739b257d55edc7c7ac17bcfaeac7f21cc93807215f96996c1186d1f23e25040456332ed86d9613b91b689e5b20024f279608974d65d8419228d3bdcd70285d6a21305d23b1fb7ca4ed7e95b63eb3c63cd7670e25b8a0680b03642ffaddb65d5edc8a2fda9f164c2f2e5e3d8aa903f9488573c824ef049048770409c8e6091dd07885ba404cab3d07a8f6019866984641e4019f5266d11c4ab7432645aadb519b46dc8727bc0d33fef2f5f58fd32f1183171d797edf314923c027fc98e91ed652a57137fdd7c75167d51d150fa91a897805c4a28c15b6704b3ae1fa199ea42dfc6cf99ce3e91501db463151987c60690ac7f71644ad36c91d2c5162b6cf40119980e2093065afde74d46d4dbe83facf91b3104731a689cb8d539ccf042aa32cf47c2b085a37d1458fe2e8ff9adc78c88b17512dcd71bb6d6955436663373e66550674f567284cddc9926e6e53b16ed4d93c60c36c0718c155e +expected_shared_secret = a7fd777a337219e1d0ad2cdb47fa18f4685ac343bc537dba6c97326340ab3ebb + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = 6cb55b5e77c06784a223b9cd2d59478b608d2e79b1dd02803a272b54f2ac66498ab1f621abcc61afe10141eaa935897f89208acf9b3593aa90fc9081b8993d48a84aed0252d7f28dd48571f1b318f2d22ad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9c211f8e959f0d75b1e11486f197368188c8eeba30a0865711e046f9483d3e953a55802299f02968a35374e6a2b9251af66790b73c200f74b5fae2c6c4ec024feb61db55c28d2a99a67436bf5879835bb42fac07b9399ddcc01a6d5739c2c4c4ab217a3e28a06e6ab367354195c5080f334e0674397556047fb02d195736db39abf7c61e02c11e9da5b1c4829039f159ac3baaf5e47a2e6c2a17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd492bb4dcbabef3c20f83412a6940b78053e26227fbf7608f2b6233ce17db500641b295e9d4a468486818a9375e074b1de9124cd44c05fb975889192666a38ebb79f0e80a21d1c0358f24eb4167dc1bb2cc4fc076bc634e37421e0a5054490b6f45695e59cbd4e7947204c62cf0b61c2422f39b2a1abe24229e456cf9b374c8a17c85664f5c02b575a640074354e385e36a5b0d373bff3105cdd110cf0ca235f3bb18a051b4894c26b6c6b8a4a9d185a6be6127a1f172fa4e75971552ea357c891210cdedc7a0f3278e930a0529b056820c7dd699a436b80017354d106698401b6092a049eda3a07674d65956943b96c9191340046148aa8c6837acdbca06fce4a341d526d437657388ba7b7632085a921e447024c5b5ab9198b7b7a6b8380b4daacaa6b17bb508365c34b8145aa3b2f5b11722345d80554919489e49433bb558a3c332eb12b1a36746e5a531eb2a6afaa1532183550defacebf4c6bfdb0a035faad062b1cb2276505da77dd99935b1a3bb762666de6506d3cabcaf8b5dc876fbfe55feaf4acc4a628e0347a66f424ca2095e2a3605075786f9b728b5905ac09113e217e663a91f3430dd6d4244bd2cd50b69968d95bf9b07c0f352912e28fa9f0600943a0ea1578955b314ec1bcf13bb4cff6c1793b11cb1b08bd55bd850136e539cdcba0c8f8b1a1aeb183dfda8b64718bb1d8707889c74d92737ca3619e42b7d971783219882b14c671c5005c352540cb5621c6409366adfae73b79957539f15bba26166f181a407b5e7bbc14c54119588b630b782621eabe39567032d76716b9684e217895d82e0ce9473cda40e0065c2d91a846d7cf9e86b934381a36f130336c7eb7913d0aa466737c8aa34453e4c0c21d098906e0229afb13b96b6e717a02089a19d479826c585e1f8695f9586b696c805f0533970ac5dae753903044ce0cb180276c4caaccb71169080474b3003e0296271fd891c1a788a264482de92b47549bd2867a8024bd65287f80b25dc18771f8f697d8a830559b544dbbcc8c656db07ab70174855192362dac79783357b199b090840dd5d474227bb8502528cc5659fa1b1575c7798052393866a48a006ab2572d7b8635e71448b1d48f0175baf92bbf98e12660f6730845164fc42aab8480871c3b2f844cabac957f62aba397abd4aa1319e7adef132aa7f55abed6143efc5483e2c32b1aabfaf3161bb24c19e50e95673fe6668617111a38525fa76cc314f891c9520b88d7b82f5c415b7310d20b5935849ce2d138aa162bee6a5822c52c5704b1f1b6838dc88ecf0b3acf5a5868f2576a58730fc7b986361dee901f5e050841ab06364c72029b259a754f74a95b32179bdb35888b0872c844443faac6f9f67aee9055e4f909b3d424d6167725e960185738df3a30930b4d74dbae5a07463126b9c6ba257ab8cc893758759b4d24f75cf2f745bc6337e366218716bb4c5b8d7f0291488c8e20990faec84cad2616653104d621b3662838c0d2a27e4a3b85b25f22ec350469582e75408ed36141033043e459fd7b0087077aac13058519ba1c210f68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661e007a8484540363321a08975f024353d72a1b08252173c874e515e543ca12959235537cc4f314f7c81015d462e2182130c24d3f572de234441ce52e48aa67cd8b2941508edc9c421ed797b52343c6c792e4e8a4001936ad81108e4080fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = pass +expected_ciphertext = 64ce20892558f065ab2cb0e35bc0ab93b0549b77f257c05d6a21ef7277194c7aeef035a169e76c0400afcccee0e3025ab1f64ae4f6b23e7fdd77bff46158f505e55d5e153c68ab964e2e9d45ad06c96735ac0eb148d757b0a06fe10d1ab334083ab123e72b863998931997160f7d5d92081dbfe1f7b25830b0e70eecd49b2f3b43543ac221c981733f4797167704312fe150aabe2e981dacd7e1906b239de9fb2fbad87306cf6aa70286a787b240cded1d15b499654f80b9bf492b09c34fa7d39b1c7335def5100c78aabca92c3cc6626ebd4d7969a164bb9badf607cc0bd6e6d7a72415902040189dff9bfe6fc9df1bdcafcac77cdfa26fe099a61a3f6febd887cfc6f3a80ae3af13955f4459dda9613927b4a7efabaa9eb76a8747b6da218022f6aea23deda7997953a0b0e6c810799a673cb0fab21d9949519e8727d601b3bb0da61eee486e94fd666ea29f690f5b30a76fde6e906d9ae3835dec164e08a184d6437479ee2f52304710617ee7e27944991c62240dbc0b9a4f534af0c8f6829a6d3a55b5cae6db8fb8207ebc183f509f66ecb63059f1e2db1c56adca32b9a90d8e0aca443610d7ecad93561689093191da6457c6610347a8154e40d7420546a4b9dc89cb804e03f4e3ba1665680e801c61c6bcd08976bbff1680038b6b47a6bb00563df5ae9b82b406a2351452472236fc4fa85e04999ca25145416a7e63fced57bceb621158beb7192ae5b227bbb7e0392bf30199cb345382f63ef22c0253eae4cc33594870cd778b8eb65cda23f170b40d50acf9f97b31b784b4014560146a3769ffff748b29e05f39f89351afaef01daaafe7f98197eb47664523af79aa03a9cc7ac2bac603df9a258fd34b8329d4711d40cc6fd39ea90b6c0a6bc18b822997bbf1b00e9e87497ec154bd7b13300ae14a1aec21014f407701bbb7bc6f9520f08d05a30b1a75f057ce1c7af26fff07b55c9ae255c4f9cd9a5d92bd234283d158a272f68dc8387cdf7c81218045f241bb83d8fbddd2302a8d7e344af462086dade8c8e6b4584cf5b3b693ce317f23ac1d0a24b237eb07b00fa8fd4a5bd4680e89f5e011182b4200971ca09dff2e49b72fdda8134c0ce80d3c50fa274c7ac74c3ca8e2033bcbc836604471d9f11b0da84472d69474f03f62deaf8537686382c39a5b7a03cb64a948f325733fac7ac62511a1546eeb9b40fc34c0704f8e79ef639871072167fb3a11741ac8b57cf1101b66c20ebfc4223492005389ee9f782841315171754e5d8cc0d82823f2a8af73b415734c2505540858a17600d045d9becef38c6b015667fd6f98096094e2b55c820627fa56abf03cbdb374e86d8b4a4c11d66dfc9d1f65b3a127f489c56f1fe6b493b077d70ebde29b47a406f33d589547dc11c678994c33d9d96d5ef706bebb836657a00a16c9b0d65fc176d5bdd0bbea6030039d53fdaaef3881d805ba72a23e8bbd24401133ee085049e6c0b7c74d2531f171e4b86190b4ce31307eb474d5976fd0ec2d0dbb6d522c5d2b2ba7012ccf2b33248809b1669cae4d16c7a64dd354141d386e7bf63465cf13086fd13639146688c3972f41b8f1e071bf949cf3a94e909c452f741fd98a280cc9df4bdeaff30e43efcefded41db01de9bf30d934e746d76acbaa91bff2f08b20e8a24639e1eee0338664d224bbdb8feb10398c3d8bd90ef9a664cfdcf8e005ba51862268aa6947c58dc45530b201c4ae650c765bf5655661292d05d96e635de51e8b8b7ceabbe7c20c5e6acd44238568cfc127625461ec7c22ab034d847432cbfafd973460a373d7d588b0dd8c2dd960aaadea186d999aef4a87bfd58dc03c00836a9b7b3bd52597b6cfebde4dd523066b8a3ebc7ebc38f6742990dd30aa0d963577a5c160efe3ff8f30158dc2d4c5a2a83c6a701f45e5579510891fff52f059b27a3281cd9a3022b8e9784f2d1b75487deb48db743c4eacafa4f6d59b7b5a211470f559272545fcbeeab53358ddf209b5f8a846493373985a5b1a265f65465deccdd1702d0d3348243f6dcd57680979c442ae494e90ccf0855b9445768e2a6dfcda0e70be6896715e6445d3bfa242c1221e0672e734eb717c8e0f7978d62ee59145a87ff5a36d2d1552e01e89a9e67ed30df6984607b4b46c457ad13eccdbbe88e0fc9c12722737abc9916ee07b088e5dc7cbf7758f87e6bfe83ede7b9cb3dc256fff5c9 +expected_shared_secret = 17672805d3953f1f374dc8671137dabb0136de43700fea82a2ca23292bd0d562 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = 8045b8693056995a847dac15ff49b59a1b9aeb2188c46214fb86a8ff8138c5e8b63d6c29447bb60a56210ba594a3027f4d7667edd310b678523e87830a469e5a758024fcce5a7741a7368c790cbd86204f6ae2a71c2a6a0ce80d14f26e53c175318cca9fdc5fc0a110f6834e1a32986cbaa0f0283376b25276b304dd4c9debf7ccd4c98bb1e605abd84bf824a61f5218671b17918432b32359feda8cbf822c62e86061ebcaec22af3ddc83b45252166a55fa2b3942e346a688cff13272a092c22c5c156ae0b63214bc7919aa90847f9de579c6eacab9690c6281685f4184736092d7b365c2d0aa977b0999635cfb0c44a8193377205a49033fff2133853a4559ba895f0b5b36f2cced166f7dc4aa6d064e6223a114580b58128dcb30b5c8da30b97a497300061c9cb9c7eca6924b6c6b19469645a443851e59248a3759164c02a8a86a9d1e86c51907074c7003e1e0764ea650c9aa9f1ed14831363e56104d4126bf09207d5544c5696a69daf7a748ec7be4b2cdb3c628d5a302f1a82eeefaacf731c5ce3bb6a26a80e7414044087487648e62f9c5d9e29cebc8b5bf111995616b8677778a8cc6b55618a26c6ba74753a2d943fcfb838b6a14935a38cb96906fe2008d2ac8622b50ca4a79035a403946180fe69844020bcc093bdba58d1496ae7dc5741ff16b5b5185a86277ab65c92551b48180972ba55580cb8cd274bc58a83041c7c0349191cf7c9be0a24f23e81e9892c2e0fa979fb4aeb3648ac64534e6c3823ed28cb24569e0931506396140b72f059818bd483d70c8132bc38ad19b995cd9859bbb06342ccab0180e8471c77ebcce2cd9a09d32c7de1443f6c588ac2308612b3b3cc51c670c935a91b973063a31703047a630ec03375831a3357940d2285ec8363bee2b8626656669b36875875f32592e9fd5c1e48879e58746dae41a9e8043ad3975de6c0f59f6588376682c770bd2cc3e427ba50070a3d1572fc7a61f08773d60bc1dbcfb087d726372d23bf89647ce6792f1a12fb87298fff567e6ba833423c43bb157b507009d46c8bed6704e5b23e5c431206bc3d6ca5665db9051d882be08b714950054a6c0a341bf953c4936830a74db1e7236c5cc3b49ffb6230c02978b63020ff75e26f375621b26730aab7ed79dd7facf6bc7a038b779bfbc43866123ea910c4620363a8b885c7017741a22c35506fad12fa5e2360c55aa99528db32709b41c79e7a1730be27ade379ec986239cbc98c3e2bb818b3c33c29ce1b6cff56a58f97c0968e83156a5617a579e13fa208c840591ab630d942ff415479c8343230a9f150b39b1e8259a839eaa370b9a083f50a8992c2b90321549a15b482b752c65c11dbd5b302e630293d2463a47cc54a02c6b7784ebe8c6b487b185898887f1590ed21c1c757d248cb712b7449f712082b7591b34604af799f9b5ce2aab6ce9464528418b01b1abd3e4598ca45022809a708460eb72bcb708c5bb8c272ea187e0158778760b7ca864b0fa51347b4d7130a2ecf4140a8988b94498db660229f78852fc149dd9c5692c41123a6f1310743c892f761345d2f685e5f3a924e620d7122cfadb4f8fbcc95f5a65b31728624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a340100ad8384a2955462bd703237d331eb7742349876eab4c2c933133d3c833d185f129c5804aa1453b0947da3cf3bd44051f70de00b3cb28396c180b501e70157c22486f8a82282652bb21fc23c3bc123b6c3d6acdf079906b149ae2b52efdaaf3d9b0ecaa92ca9d8694bf07d4229835f3a0a21253877e1a39b4699039041abc8c0b3f6aec29bb22e847131670c0e7b5abeb2455a246d03b6066114552476a18c23b013a812d65a15d021c117f926607c076892499056c1bf058c52ca1703a0812678b4485b82814bb6960a86c3454b99b731cfe15ca5ec005f866b28235036e632b89cbd9aa4a6e70ac944ab82661134ec2ba3b871272864a85ef61f86f51337651eef063fc6f07a39d3ba7aaba5d7357506c550bed913788947a1863a25209cd01200272517adca5f1087c984e11f13404d046c5537711c56577adefaced330230a42cea4e13d0e899394f120ec34c2a6054e5d2ac90696115515345aa2125dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = pass +expected_ciphertext = 65c9109d7c2eeeaa5ec2b4dae6fafac6f7e17093449f00a5319966bb022c49765023c6097d90f47d6e58b96c0c17d319a88c2819de8dd91cdef8817e354ca37a3e10853dbdd3231a2516df2dfd1f55e256ccf81e624c5c19c2df81e6311d02271fbd27de2f579014a06d2dfe32fc26cc5a45bd7575ccb8898e780aeb20d5c01145f1480c95a079fc6767523ff69f6858b2d56bfdbd3695d8a2101bf65cbbb28e347b2b528f2f01d630a035ad2802d087a676930c9ed741de8b0157423880998e655e20b6f4325b3f9e7fe36d1cca269f49412400f0ed498b9a7e699a968e41326f7c813cca95ee5b2bd5f5242de87609fb3d2e62ceb776486e7826e45b5ca6feee3114bdcf705c1979b96ff382c1f92be175e60b37e7885d18635b06183807d5f3ae5d3c9cb3df01aad1487bc93bbbc10d078fcddbe8a0ace94414d7af8a3cf0ee579b3782bfe8cf6b7f377f8170bf7fb8e7fdbd96a075b804140a65d034ee675fc3e156a12e261b50882875ad073e071295daa7743a9d581ab9096f679ed9f2cd7e36da05f435ddca26c0136676775a3f30ed0c800e51b7ae9dbbcd25d3fb9d6676a972a25fd7c4ca91859b175c98a933d84d1797427ea8c0aa1beef033a2a35a145d9dd59f7e29953c5bbfe6865bfebb558ffc747b52ff7b5f2e83d65dff3423328449d27fda0fce912a0b6ba78e2b66c9db821bd322b5081cddbeaac16f7ef2e41fd6b86e4490a2bc04fb697e09b3c543495fefcd999e6442a56ab49ee9fdde910a768d4f0bc51d797dd730f98de9edce163f685c0363e73ec6d235acbbd9e168b6152b0eb50b7276306c7efd42845b11cfa11de76163efc774e5c6ab2a44a6d117c7b80b2b14ecf1b1af7f8a09f3d23407cadf256061df3fa9d940ee92f3a80921f76f0f14d3e3e4b0a943bf6d6834d9d75d0c4ac931e59a98d4e53456bfe77a8f12637bab2e4db63fa8b47f9f26cf65c5421caf208e74dcdb98f1242320d900133a91769a5c9824a83a0e60cf78dbb8fec10dd1366c1a7bf75412da8072651e36ca8d0aaf464c3d4473cd396cd82207b20e2f5cd07b3cd1ae1a62d9ba86bc1cb81459975ee94ce5c1fae71d39fd2540d631cf6cdae1c60a3ce10b8732f9366a553333323a9a01c56a5a91267fdb6b3abd68f73377c2d10cafe7ab4af06b66c77dc30428105413a62ddd505b043b03e491520bd526e00ac068a64f115716f36f008d475b441a849617cf44c8e758726987ca48be6dc5f41f95933ac9f6a4b1a8e26092340108643003f0fc243ca8900e8cfc1b8a1910e2c75384d3653d3a47c619495837399e7668884138497c598b8fabbc5d406a00a8b89be59c44bcd8ad090be3c15efb1ae2f7417182fee2e68d0ccb865d81b23a4d5f2f54f4e91d89bb42a451f95d3f85dcada8d651147ea53b086175b52748f96ef432cb3b34e14a84139915cea2d3af6a33d2c9ef3e3004c516a2aa16be6dc5f1d07be3d5ceb3ff37c24d1d2c0edd91b9b29cb04b40311582d473d71e52bc707e9b0d497a3d6d6d96efae0f9b556358eb0b465a86f9cc10a37e5ef129ae64776ad2374649b388524825761a56d32e360124af0e2c63de5fc6719fcb13f9a664400b137c842d5b5c7776dc7adc6661567e8d62183a16f45840493d8a4b5eae39c3ecd40d60d2b0d015ae2b59dd6ac298ef11fa1c4477d2cfae2765182ed4a8625f3daab15f51712c3b9c2a33e8f09957807f419cc531e018dab3e7aba6348f1563eaf7c6bee397a813849a58f4eda0648727ef3d3594a171181a9153cf8eb02676cbe6f70b63eb998454edddb2ec074849720ede5a8f13d4c9f8e2f1ee6d95e87603e00731fce896f6bae80d5b01386427fc5602bf81d64b4ae3194a040af00b0038be7e8719b24b71aa884304cb1fcdd691ec6e5e4d07efcf683847e4b46946a7aa200d7c9fe5ecebc1f95182ad4c5ce44a5d0d92b8e511e5e9d2c0a74e2c5e9beff56e856a34905f20d0d97364b33596f7efacfeaf0c8f34fe76d9463fe972027a2157a0e6c2f4278f48227558ba3869acb0b06b724f08429e60cd52e2c7bd6db139f1b3200db659eda1b9d21329d8171e07049b7efbda98afbc49b53f51042b987b1afb8e99b8ee89500fd52e7d9db1dcb3ab5efbb5df6e084daa70e202fae574c0267a8b72b1ea174f0132ccf7abaf31cda71b4ebe9171a822bc2d3b44c739a24d51e85446a4 +expected_shared_secret = 8813fdb7bcec5369e6238322be653d920ba26e0aa63a3c3b4e4218c48c1d6dfb + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 6db66dca0819602701895a6e3a2071623403b78438977211d33331312c8715e34929757ad52815c65806ea8b222ac2a5b4b718411732d6a0137c5c7ca8e285c02634130950e1143160f6a34cd64dee440b1b3b8d64458c78492095517892c5a169eb7ae87733aef3b16a5133788ace5fe57cb41ac0e5b13c403441d374aab997500533744714a84dd56ce547a10c782d6071bdcbdcbfba391dd44926022b9098e61d079b2198c4c4201295964aca9d703013341313a50a9b124427209bbb248aaf96ab9efc9028cb9a298838465984647aa1e2f4087c74ae23f2606194447e403ee45198e29c12aef2ccb0c4b07c98a02987068b4a4f14a778be34c362204ed4b31788e3b7d2e54d74e07a215c7eefbc3067f9c67e625bb43b9ce25179f58a113bd2cbbaf85c34ba8fe26a331e0b0610893e0947495cbb1e287047da04527cca1ac68a2ce1742d8c855576941b4d627f0d326a7e543497f09fe1fa536e997828c19977b0b82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e79501817d8894004c5586c78c1a54808c37d40fbe3171f6e950e287850ed19d975446fdcb1b0cac2d4a611d832acf1c20a28c164201638110e0997fb36b2d24c6b349c390d4a13e06aa95c40e878830827a440985870a4b6288f82dcbd9ae23175462fa054d2a9c6f6210a1a7cabb9a6ee8e37ff144043ec0123c2c0c4125ab48775529a86462c34c00b128a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a716a27b1576561f681e346ccb74a07b71938676c25eee2a83ead225afc408cbf085a4a342ddc2b058c6a138a94a819c737b6baf4a4493c38a52c1452a302535dee813f1dac31e09402cf720a3b16751451df057bf1b7519c8a62e1be69e339910e6024c59c13fbac116d6a6578ae40765f78a7147b5dcf93f4eea1436b559ae373888042c63c0a52cdb2777e8699afc229d575ccdf802c59c15bf3b6f028494594b53d2f3cce339229b3a03eaeb164f325686590f79dac06f482254838e5af209cdc31f9a5bb893961c5576c445a02034088e89140ec2b28cafcac58ad352d0ab34d0659332d9266db85bf57bccb67814bc74c107c41dc2f30e6330b17b4b710cd7ab0b1c01d9f82d3fa0216e51198d723f1e52314e850220052309a383e63b774370713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a85603fdd8b392a616f55c3783c28b5308a4b0a5c1c757b677c475c60516a65f656b4868cdec6bfa723c66e52931b738e18cc518cab93a7c942e7db127d239c11580c21c71031f20079e9506ec57119688e0df98e4045b77e87728496c2060c93f4819ad2a79ed10501498891828080f4841a8af6602e100981124f6a16c26f3380e4d3635fd3cb77cb6c8eac22ba212a804917b922218066241e848e3ba589569a5a6420019370ca04bc196e88cf2f428595f1912fe9670b9ac97c487ee2e7a77a621ab3b9b2e4c23c5d4c8657277951b55aae576524769ca5b83b37d84868367d7e9323d9ca4cb7071c352ac3da2b3ac58525a152a00ec268f85ab6559027ead8abaaa370751c64f51473b02126d7b3be27812bb008c45797c1b4b05b5cbb8c2dca419f85be36bc390ef5c4d3670c8ef7c00b59a44c65ad11d68c5af4b2b675cf40c002a1b7844fc9a6c32886c74a1892a2514cb930e4387904d1970168181f7b43c020a8071969b868a5b44729b8d04b3ea9716269cc005808bad63d0b063f21c23ad1377e80bb07d608786d849d79eaae94813435d602214075bde7bad770b28b380bd0d7139a7780588c01c8eb6622f1a874968c874b120ff81c988c5684f3c9ba677add2c23400283d6d325d8289473f557eb1c2977f04e95fba614ba7613720c704905f7a73a2834996a4232a8ac278a444fe5f7a9148b57124580b7b03df89ba646aa4233611da9b5327d61b6b1aa351d25988e0c25e6e2563168c005666ea90852183231ef5ba371935c4c0abe6b61c0a1da756ef390c120621af2ae243089f84551185616779c90ace0593b815dc5d8b2d5726a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa4a001c002374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33921c307c05f69f90cab5602a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = pass +expected_ciphertext = 13372ccab4d0d1364dd7d76cf4213269ff8332b39b15dcc8be813a16f36135139d49589788872472ca4629003ddc721a02d27eef1f842b2da4da148b9b83bdaa5f0f8ee1eed71391454394ec62f2fa18805cc78524db523debc3d9206871bed38b6d6e69dd74dacf6ba07889ad3d2d8cb1ee731b16120468ed3be436b8362e56ce66d1f1b9ce8b42323dc302ef37f732b9067d80b6e6b4be3acd2f4751234a5410d18c5972d32abf25c4922515005a89e03d310b8a76139fceeddaef9b37998412fa7ef24817861e6f210c1ffb2780f23de28f2de52205aeb9a64138dda4aa0edc91dd890c41e1e814939124efda4cd4a344cf1f3f046507822a726ac44acde42feedcc89e159571b2cd4450c370650fbae1b0a55aaeabb70e31300605b9ad5575ad05a2df9bf440f123dd1b4b2dad93da1dd0c7a2b7f03baa74b14c1b94e63fcc8cc3f173ff50f72570c5b3a65ab4520e3fe80b9479195f1c733a3e9059fb4186013ba9f64ba006ccdd270747f5e355b4a455a7197146bcb42604f7917503b86e818197fa78ce268e288fe3ab3a7d8678a01cc2dce86e77ce7bf49514867ac9cca6d722d374a9f0afbb51fea1c4f120c339160faa1f40103b3f84f69d8945d72d91ae9054c18f70d33676ef0f3c759973e25cd30c26fd3b823690b127f95a0b7d3999ec16ac645c181b264178bc7f11f64127800335890c31d7412a314ecd3d361d9ceb85d77494c20e465ef7c36a227bfb9104436fe95cb0050ea548ea22252394eee01c8ce8da5eaf4ccafc647b7ce956f1eb7b28c28cb05663aa5171412288679ba2d44d7de75a625667bfa865a3dd0f20cb92837dc383df5bb060fdb2f9457f1f8af77497d408da49d4510357f43ab7985ae03ff73bac3e9d2b2c2f3ff9190d5e928ec75a2fc0e2019c07ec2b4ca40da2fc16f7ccf3ff66cb06327ed9d2c73751e7ac34c062cfff2f6a98eae4e8e4f989dbaf648a7a23e5a9f336a5ef87dfc4b044384467eb7f63368daec721a1cc13ffca44b4a4bdc5c429b7e0466bd9d19ac0104879a629d124760427202c9cb325be4a7624593136254ffd5847e8f4cabdb2161178aedd4ff9a9e9622de100cab8523f75f885479965a7c4e8578c2bbc6d5db343d1e9e4b7b7b9006e8e63f8e636012dc66fbeadfdf1b94a4c4a58e61527e06fde7994a3a9edd9792af3352ed453307d8a5cdbd47cb2d7de1e78e13876ac46e7110418d3cdafaddca4e63b297dbdf79dec136fdd9cd66b2ffe04fdd541ba022493faf56b8c238e630e07274b0d2e7dba457ac1d2043f8181ecc8655c785105bd8635ef4b070774c21ed8fd1daa129b7bbb34c25b8aff031aa08635b69f021c5188e539b881eff8191b985c83d7d4465f99f9b6dbafe322c9b0359cc7d769ce3fe7e0df2c8de02e4676b5811908d2d29a270f8a7b33f70b270f5507c4398e7446dfea9331675ef9c32c73d5305492b8b3b5fa8b1e77d7ad3e2f566f0b17a7f2522ec38b28fb71b3fc9d2f0b6bb6adf50a0f779da14d43c387323b623160589970ee0fa10dc662d1aaf71632eed47064d523f04eb115d90f74a048529cf2e02143a788dc95e0d802cdc35a00952ce377954ab3b61b7fc2e03247576f2707569f50457df76e3b73cb20fa6d5b2fb716769154d4da9038d8f0dda0d93534dc42ef05de2c7815dcc97e0bf8e15acbb31c7fbc1063889e03a312d03c8d188c6423adbb20b6d49ed25cb0aff5452411914c61261f533ae1d8fe887b08db689f7e46e76176226fa75e41d9a4b700bae0ad7e7d1b7e2ea90c339ab143db4408bf00c79e506ef2adef8ff6d95a1800f725770be6d3438f46593e78920c4730859969c789d9068d830ec761a7c4d43b3e282c552993b232ec0f4251d5be3d9a743c4586439e7db125827a916a15fbf94eecc4af09eb109a7e27a45068458b02b475297de3f99521f3bc0a4c0eb5b5fb92fcc94bc520837168642017688a5aca19342dc342d624a02a30af36300fbe163f015e3e0c46d2af22cedcf9d98f350b40355ec0ef816652975b314800f3b0ecd2fead11d315700808f5aea0963088b008d048381336d7492999a5d29a36bd4d9d0e57c7bf870cdb9b75da48911a900c018cc5fb3f262c09cbd6032ee778c704500f2c6f88b20a6baa927eeb373cf490e3eda483dd0101dd2260d77e32d9e6088dc906b5a61fc4e2c22c8c37a82effb5b4c6 +expected_shared_secret = b00167b499d5130ef82a91f83d1f1563185de735e74f89afea0b45ae1b90cea8 + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 3746054cc692001b531bc5a46a5cb02c910bf24519198c1a2f2023a4367e9d2ab4cf5887c756299efba70d9008fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9c9f228475e0a454639892d992503abfea8b82908a087761bec6ab7d60c1892f41bf1f99c6ed256b64c78c93a316b31272d6f236371ab2ab77123eb732ab303a5e89485f702f528a38e1920f12ea72bba8868c855e305425d84a5edd11918b4cbbe5c0001a5637bf8c022128b81de80509ea72a0f66ad870257e529a31cbaa39183f006a0fafac0fcd7781f1033257d766f78b4c4a9b10c5b8208a40368b393a39e7762467463b29a7baf4307285b898aa0bae485a63e739ba5a7a080215f4221217fb43177635aae61f218850a1d924052a9c0626a7f11646076176215152b5508db2c52da7477b7e2b0659b999148a214a12b9a3e770998b1a26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa94368429f763991911681c1ebce5ac515bd5663308361e2b068332763752047ee14ab31b914e2d28457395cf61c69ecf3834d305af9ca18decc6ed39ccf69a79c379044ced7440a248963c269b6b58a049a8077e0a0981639d581a8c38a16f4296af798cd2556889e9697ba8156714166f10a57c970c6131386d9154894d495deeca298e33de4b09a94dacc2cca1d816708fa1b1b5e0a7e8046143fda893f0b3eb2b60ca7a02878729768fc82d8b06a05f647916a9cb84b69ce532edb5a7ec4eccda5a5a4fe8c52ebec6584e6c0465529f57699706cb9a497c2e96757af06783a4aa6a00087079803a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401abc1b8d0c8eddf679a8ac0fde11917376a7063339f2c2507ac02ccc512c7a75b00de0701124ce3057a8c28687b2576c640bd0ea5422a534aa4bac9fde1735f35112c98528298218a1f051d54231f7ac5c4353be2205c3b6518df442775b9771ad19ba9252698bb6cda102cac759a5a0734cf07791a38c7ca940a86b584457559e7b933ac5750c4c43785ef61f5c121f8f4175570c7ccf864c4bb7c49c606ebdf7950e49433a841643f78273e117780a5e1e4cbf3e0016b45994c1821686d41133bb353dba0fb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb0e0baa50199d80050dae3266f228134a4c67ffc5241a757e0dc2485a64d4907934eea5fe503653311c4ef24bf09fc3f0388c88ed9cf965ca8a109297be60893559a0f3696e77b38d677a7e9f4c788d67046c28281c8a7f71ab250e77ad87b4f64237077d1a63b753a21b088c5149af5d40b928401e4c407e71b6896b840d8f717e627532f3cc604e64b84204730c8330ea35228580b4b886518e9670d6100826560f9623045291ebad1ae5fe6840c30cbe69ac54e62bad8010c98c513956534beb356cc6555c1c4225b7862c4651e55c4452448063b4c04e105b63daaa90f9a6b0769b161a32f49fb64010a91e0b4410d86b7bd4c91f421ceb091a88ed9ac5e01c81527886897a8e6697c7571ad95b818f942a5692459f9979ac7a8078883aa8a445a5af84b1b86c4c79a224a5c8f3a889eee0c768af29fd75a506ae75f9d578c26c8645bc8a8bf0441b6da2bb27b6baab43031047c6b826fc98766a1661be0626cd2c37864eb23f4240e5fb601dd645ffdd9898396273d3000d5486cdb67866751378350068a8439944ca11f9a5e7959ad43bc1f5cc8c741a220bee733aed2a41edc34fbcbc890a718f608794802bed150a0398b0a836a68cc0b58dd705353a41f28883cacb94c797b8cf8d23cad9bb9a18c53b372c50aaac124fcc07b310907988f38164f46d70305a381e4a1673145b0bfd8ab91a02c28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c45057dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c6a1c7e1589e98cc995a4a2b21288057fcca694c0c00e7ae05d861b90a520eb34002732a2812368931a18243ac62f34cd7027fd80436d0454aed978115034407e30dc19813c5100c3e13a26c3283d4a72e254ac3f7e637d9435281180dd6fb35f0433788d470b6216b310a63d5e11b373a073dc8098d3950819937e7f66ff954caae52b3bb86c80b5680851170140a1e59ba0b23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = pass +expected_ciphertext = 65cd11c5fbfa837e85464c0dfcdac9724a25db17ea1f8631400187559d743cd8d29a811b0c159d777d234d3cf33a19b15bc8841e5434e28b752b865c3d1cd4f7ae70fe84d3f4dede9c515dbd7843cba1d29025a30070d3a1b841cd2cf1d76c4bdf6bc2d24d218959d180cfeba7a31c81e495baf9a1b313c2608b79452b2344e4c6f1960c530262085a5c9053456aed77daf70502a345c6bb3c147f8143f916f99754bb1ef31c4167bbf63c68b54ffe5fe459dc9679d080065e3b73a7b02f8bc1d1b996cb0069a36f9f04dc5aa3d00633c38b06404eea9a4af2f6144bb47c009a01df11accd962c20165a3ac6c27e5cf50691a58c45d68be6f5732df8e07e7bdbb2f58ecf171baf808dfbe151c00b576856e0ea7c292095c5000c9b77e21b7937953a38af0f53e7f4c65a70edd1396dab54df2967eeb7e02cc548597a6ffbd829dd72a2d18e7888cb0e3ec9049182301c1e6be6bb43f4130bb57b61138bc82720afafd061b3ad2c00896e7405e4063790a75d96e7b3c1fdc475388d488f4690e0c584a33efd2692f2f90c974b4a2498b847953e2f72c1aa2354d04c2fe61b561e29b7d37f164734bfbe96b0af480f4189b67c4889f1913497b55547a1b01a1b0adb944f75ca30145ddd8120bd7f09f7e36e479af5f50befce9bd15ade52d4b329854c62837cc0e64af3e908b9b47e61595f2f25ce78207d2331c183188d27b8e8f29661cd70216f491b886ff2afb018611176649c9488e6aee19fe6147a3c92e95fc1983ef5482d295e61ca2c8f4644447d0b918b443f3e6efa04e5651edc750a529cf33eea818242b45802773ab7e74840cfea962970ada0a2f906227f3733a72ead1295f78c0161cc91c448c9e150c565d022d194a7296911113ab1a550806edc6f1689be96da4cb11245f0c0fa93797a6d6dbe992e0e695209d010b3a728b0a647fa5990e78eff5aeb75870aecbd0e14cbad1b054c9fbaa5b86a00dc933789db11df313c39fa0e7b32e281173e5eb13be31e5c349709093c9125030e7e066ac38eb3d89e23833a08a66f7c0eb230d01ac83f792840db7de17adc7dcb828765f67e20ad5e4ead3d6f76302aa9a5b321d68971e07a1801f98544d6e1d5a68f8801872d099faac4c561e35d2b48036528a8a04c2033b4e2b018f1242bc6f8af436648730564629302cc5cbf1bd2214dc8b3e38a79aea4b67a52af232f23d0ee6f60b318736276986dbf567baef9c168c9331773cb1c32aa22dee8882d557f79da61171634a5a4e806939c3eb1d575712b3674f503e9199c6b1b630d20296fecfe4573ad43a266b8cabc22ebfb40717d781d4dee61591aafbe0a042c919a1804953d4b8c1a6cc5f8be7ed45bb1ee6f75671f102248d4dc63ad0e6098de0b4f3fc31bfb3164ab3701e51681993bf1a4bd78064b3fda30deb7d70c7ab35e64bd82f91da3b06688ca4a20d0b19849b72d2c342702a077e015ee10b277d5e1230b91c22d41085650549c9eec529f34caaae7de76bccc960bcb5b5c7e6156c6069e4b27a949ff8c9a1aaac2ee7625aa3f19568b14e883d3273311927ebc09dda978e1595b7f392ec8f896fc8c8f90ebe8dea1cbd54e8d061479656edd13dd69467a3adec9426f1e8adba7c80055a961d5f795d26268efbe41dd91f7ad4181bd6e6269bb348149654e2e12c94f5400f1f8b33de35db8a08dcd10b5e50e10def51cc062157effc7fdf2f1bc45cfbf600df322a7d711918468e3edea2ce05716dcd996e292de09a910962f64056fec1e8fd041dc26efd6e08b62fc943a84c6e8578eac778685515be6e24b07a204626acd3b43dcf2b95cfb41b366f1f283c1233c4c54d14024425a351cc057f07b861dbe48512e6e34b136484eb43fddb97778cdda81c4e294d740c6a2b124c1be3ec67c266be133506d35ec2a68e89d1eb4d16ca04066eab2978dc14171e8fb0d5591421b6852d4c2986057beaa96bd5e7b3ada56e3932b29bd1d4ddc4199a793faa47a7634029ebe81ce082efdca2761cc1c5a00d2a779e8b1548de89acf26787e7129ba62c445324249dfdedc6c6639d665eebc2c5cb475c89f8fda7ef4e88786d24ead0589567e82f0841bfe3e483b1af4fe488a5e8f42766f765e210ebee1b2380d082573aa423b3a5f41d46b61231fd9e1f7501a7b8cd2a56aa9d9e272df94d630630ee36fb35f1d968e2602e6cf16e4e38ea80529 +expected_shared_secret = c55179382eb5d4bbd91e45f4b3dcc5d1022110aa209c002600fe0d55a5b3333d + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = 8f57212b9b824d071bdbc45143b4663ada61ea72608ea85b82b49075d3adebaa7d01bc9cd916728ce121c1fcba51e42732d76575607d3e574c654043d717afb96532da23924fc124b01026a8f8b859f4bcd1aca153133905904c3be8361200abc6e7ad42f236a0826c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f18042f2075e0a8c58a5c244e14119f5b6d5538385089400e23bc1c106b2cdb59f287c538f32917c202fb682b9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74096e0423db52e7c0099963c5147c2cdc7101b0d01cceb8ac64937186c23b0da108f58f5271e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af97c05041b0494ec11daa36facf034210383acf9089d371aeaea975c489211184d55db561c272cba9881acb88159c74bf9671147490fb7a4cbcde1689ee7cd777b3f83c54850e8082e884a7c3b3333d7cdc6318d5347b0160a4b67e46a24d756105c09ea0043b66a74f98599129b52eda51971b60b6c65867b3545139990aff9c088b7b114c03d10972bc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d6a1315c63136139ca954a86302ca788c27b4f82c57ea35bd7c31d5d543cad66bc4ec9b93df67d2b019e56e372fdd7808f4453ebfa3092676224670f79ec579307052832bb4f2150da4c06e8069855573378377c44a9508410cc62c60ad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f6152bb2845a3de24807102a274d2b33f84392648c6f64ac85d304a4c024d88c0a13f0874231cc6d2bc8d7c99c0530087f61856c000180e78939148212d2b065df99fa51a0e768995a8f3bd71ca82a1792afc7c05f8b07db30aa18dd25180b73d175382158a1c3d5135fdc40f2068c17ed11d32022caeb404c68418e7ba2f352a510cc203179366249385a2db3639809795cab6ac0c11450220d96356bc6b45ea943c5028771eb8c58097966b4821bd1504ba1a1836251047c8468089c58ac851999b7ba017267c3a6e20c5223fe5a41a52044bd5103f5b1d31fb9b0105ccba387cca72b6ff1bb27119005d6a29a6200de9dc2c19d85be067793ed476b0324c24f10a8d106b55c63bb346b9ddf44b9a5a5349b766132824cc955214315267d69f82093642b9c2360c2b57993b1ff2c52d8118d62375ac851f5eb181a24badfc165668e7a36817cf80f5873f87a6dbc3cd42c0b2bee57f0e06c93a9807b0bc32de588808ea0037db50b3bc14bf98affd4400dc9566ed8022a4c7c34fc4369987904b362b1d04cf3451914e5909ef750dbc56af138529a601a261932efd626510a528643693ee79284cc3987e3694cac828ba3964e637925b201e270744fd41190b3b1c088a79f31581b0641917dc161b000fb4a8281f6a6b7b1392949acd277b9901637c3454a058589299c48b3401a2e0f788744081cba76b5ec378bb83789f63962ae2af1175176ff353c1cb3632bc0e206194f4b7367779146df4acb6d89652b946a9b9c2b61c0553360616f90e97fcb190c43faa544891745ca9b97950384de8534626914ffcda63ad302c9f001a361ba7a94066c9d8b1f30111faba3728fb143bd788aaf04491951d541078aa1069741352fdf8c032964717ea1791472a2069cf43da46a40046c61c79cf4a7d1e093526d75b444a08b0ca984f2869026a4432244d662951df52ba655ac54c502e83e8587e21c4757166b78244da2b5364d3299981859cc61a67d02b32b19c8ab31b78146690690096d606befbad0ee628103712f0f81e5fb4bb22e65e9ad1410504ca75d29386f73b53b0be140a5b548a48b05313de873e18b030d6f691322a2409f4603c7bc24c103111fba7dd5acb3f019e7cc22bc3f6b1e6acca131364d0fa0694866e2322281cd229c16aa82116ce6fd0187d4034db33c2b3840db1f42c5df49825fa7c6bd62c31a625616270565a2fe3f4bb50c58597f70e6124c2f46a83c3fcb62ac65a5a66557b22ae31c7813243a1f0c4b905a31a40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a0825ea860af29b81586b25832356c1f976370496b6fe7493e482e0dd9483e51372b093d37f29b9d1a83c209bd98a363df8a3ae430ba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = pass +expected_ciphertext = 7a15ca405767bb90d0d9760073d0b132c61cab11bc4e0c7128cfe36a2c66f31aed86f7b1564eb5ada3a2dc244077f8b225dc3c11c14f01dadbd4a596f6331a1f35cabf199b357b635a9032a852a7b06c9ca27b77ab000780ddf16e2ab81ee06e41dff4282aa32848ee66deceb75e40f3cf72456f53ecb11f47ca808c05c9415fa6f07f24e6c87f2cdf2609e24df56c2875d62b12272cf673ec4e44db21893f1abee86fcd6a12d8bc34e80ebdba35ae88b8e48735058dcb1a0f7c423076fb16f33032e70acdda71af0fc5e7b0619f52e9f93d7471edc8e7b804964284943dad6cc162d1c8baa62d892450698e329c04b9bb6280a96a390121a6ddc339d6ee06e747f30f9610fff22fad8979a54d07678c245d00729ff1c5ce7ea1b553be1e4156d9a420a8b65b2888f9dd032d3dcbda9e0bd1c7a2454ac3a95ac3ae8384e062dd6875d3326a648e605e65f7302a9788ae8433d8c80ae86cbe77fb759ced8ffb6d62131e5a4568f15f2b0df40753d63fc20b99ff476a5fcc686b99a636c70a610980c3e403681369a41a952b49e0b7b0d3cf0fa14275a6427249de642f61a1062ecfb10bc59c2bbdca073ff786bbd35c98701a534cfbfa06f633ee19c3d9fa51080423da63915e34e8f6bd65a6d0dd54c627c01848681010aa5226890d707ef21b687b6bcd50a36c06f8d506b8bdfbdc47f2d21f4ff3b5f37b3bc99c7f7eb05f5853ec4ad4e9d7ed1ac8ea161806041698c2ababf591c41d5033c312df31c6ccfa0941aa307cc2614fab7a17555addbd6ddf5d3db269bf21f8a83e8160282033234cac43a6ac3b9e645343accdd7a0905c54ea2a9cca750e0d8edf10586134e9c63c61271067df91327e064c1f9dbab405149c116c8e5b31087513d2939e3756274bfe284222b17bb99a4ffa1d9c092d1ed2206f5c227ccd7feff9790da2b33a012d975097de5451b1bd2ebd1472437a58f52c5f581d44f97bede74476b810cb9b0ea47c190d147427ceee3d98b4355843d0e1239ad7a94c8cbf42e6c6cd0dc4d6b6177e32afb339abf2661860889c8d31b9fd984f75513d39f9b7e8da462b5ea7941440cdbde94ede2b6c50e53c9c83fab96736e82655c3dcac4fb5b1308dbccb81e869f9661dc68c7239fd2993e81c58ea5a203b31087862b0e9a5ae1abeb8dac43e66ecbf56c5734cd5e37cb5f9b8992ba3d36f89b3cac8960b092f5212c8cc54e1c842557860356e1ee6e3be44c5794bab7f291d2fd31de9e3177d218ae60e2a20291cf74c7244792b4bb33b471f0591da492c99f7deeb708e8cb29a187134f288938339f10d71c936805f39f1b0ff4d6562b4c7d8c4460ab6667570a4f806baed968f34455779efa411a7232983f8a9ebeac7a6b413b714f2b53386f8fe29d7a7d9a93f1264496c84df8c571508bdde65b31f82eb279ef312309694a8a98435e8ecdefe0256e55a85ce0b866f35d846db6aa786203bd1676436e9c398a1277dea0cabe668b9e92567bf5e9df2d99b0229dabd1dcf7908c858691b8b6241b4140d2488817a811004845648b7cfc9aab7ea513069a4a5c45830a286e8c0d922a5f0f181285b25d6263df9f5962b4f67f1fa1765afffd9e9f4204889bed16a4569c79a68147e8cf8e9162361f645c670d7b3cd0321ec6acaef224c7c11cb04ae086d34e11bcbbf01746f06b863615e3fd57a32274cb7781ef4eb7dc5ac4a7285d64c2bca6d5d5529c1781d3c43ccda706655c0252bfd7d49c1580e14bb558c91fbfd789cbc7e7f84baca72e0d42cb89034e8806e456436c6d893a7411dfc5820f9490b3a0390d696446bd6bffc3247acccd917e2a9246e3710b5c28c30bd0aa89724adea98886363443a81e702313f4df4cabbebccbc6b03aa6f15a2280ba828c6197443eccb034c6f6658662e56a102e38d0ed4d6e02efaec6e0fbf4daaaef3ac1dc7aedd17fdc1bbed4949891632e3938226f8ff8639915d5cce755ae463bc869d1fd519fb29b67743df797e20e034f800e598de4ad567f399f3e0714be08fbd55f038624fd9324361e793582dae656b2c9ad77a72b53231ebd8812c2f2d9ec5128f50da504e02ba2e4fb507d61c9ca805cbbd1a8ffd20367336735b8622209968d538f12c3102092062d8b9598953f3f4549f10656eec731cf4c26ba9f31c690bcb4fa2cd1583226c584fa5f1ce14626f1f8166cb84814b68528b9745955c +expected_shared_secret = 91c0a23c78351e8f8de8e38c5a10e41e5290ef96266f93839169c05842820e41 + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = eba27cb3f055c38ccb7a5a78348cc39e6039a1126d369495687342f9b7c7c88a5f0d1c2b15e68366532f17d6ca8fd85d8e9249ede8c5ce6572d816657d5755236ac059125743772ea7ea7f42785b48f62974a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33921384aa9737af3a3e2d881224629a76c50712ba306b60fc88b85da88b716a41509a95876355fdd49a2eb7130600abd277810301062b0b9be3c97343e345e8fe25f6b58cb16c90a36830452547f4f658110f0745329406dc8a698a71449888e2554c5b039076f67397a94cd13e4b9f9558bb0464a39074fb6e556494032b5433d3df005ce4a1145f0448af07a089447cee578c2ab5d090a2b9ceaab2b472420a56caaa04387d7969fd51a1923c14959834b905617c61a68645aa51150f0079ea64bb16a8a8fbf701c9f5ca74a1803519792ab169976f886cecc709aa90c408720fed90b58d006f2f50d23c4bac1432176a47627f6090a788403042efd5a7d1a22c793aa8dd9a91e381acb0b5625e0fc203fe0b4c7e816eafb87cd774a5053036afab5b293c23598932ed3658f8453b958c1846c61c4190386343435b04c14ea3597f84a22f70124cb293781accb8ba008425149643e52cc124969929721486b42ac9b592eb1c15c4f8c6bbf901b8dd419c17c38d68bcb9d519e16021e62b211c6ea00e5622486e41f81f6ab58c49ba5729c91b2396f7bc9cf8462af8b06d1c28b0cca2faeda8b829943f64456bd214b7ae57061a325bb9c097b656217d65b36f575d39c11f971157abba074ecc1ba302d5318085e13aed84ac8d16652361b67a02c41aab82d10fc339c53b3e096aec1e1276a572ce1a5700c034014884392cc6eb4f9ad80a52b711053e2245537e76acee36f530610b8ccc4caf241a0f3c1f8195cad80c69b644c45f68ba7c448431705b3e9bb84568c895b56351a09bdd8ab2763054384c116e272f5d0a7f1f158e5f68ed0f47f625ca3732729e53a87d223c1ca807d277b726d0c7ee938667ff1c4af519ab7e1446a077b6045995d3001ff289014e43c7ab738f422aeea3269c878b3a7d979aab698c4b57462339703386cb4d0bb0598272349b04230c6b6708c894bb409755dd4e09fb8a84e6ee678c896992e845908b963fbc407589acdec414546a92b1da98c294b23a53ca79a27859ba787a7689202833b87893fde1b230b936916bb038316b025a5b1039a775b055d6b26797482672f02985e39c88911a4540327e3680c574150b74331ec63076d645743c677abc255d0b11d9489a35d65448a2c1bde4228b4d0ca03441d90b57d5c16b6bc6562b4d22e61e167861cb62efb1a43f008877a2895e95b4e0428086c7c34c146f5fc2c9babcdb0f74c76680a62a5c8a82348e7b396b7d95bca26169ffb90125b765d104ecba32d3291a38079567a599644cbb4d36549f26615fd31a6232688bd1694d6c72cbf04c91638ac4e7c1d8be2cdbab51fae70093af3272b885e56f62bfd925b02d099602110914a50d3431f10a803608806d9257bde17123e939df7e1951883ca93e1820e852f2b511218152011012b8adb46d9c400ef099ad3e412eea953f7eb7e627a762de88e7af6ae0b832190b91950aa40713521e0f54955f2039213c16a604b29cb6dba67b89947bcd81b22700569efb06548944decd13bd133877e44ae8480c46b6b547d72bb1ffa0f88fc3b13e2a48e5b490301d00df251e5691d36295a16dacef03c7974341ec3289ffd87434854062ed9475e758b6c297acc679730e291cbb52562cb9408b07bd70215aed0a1034c6fccbccec88b72e44944ab79592e659865f019280b8723c578096220ce5a0930dab0075bbf09b952c217b4ad8b707b8106f9f5180eb514176aaedcc3bbe0a9bf876895ffb1565d61b01f0a3f2d9391c56b6e6a9363d434b1338456313472ad730cd9374c8d81788fac62d68694df05bb88a6613ee14d13cb6e18f69b372c2944a7a76d3a16157686ab6250a98b42d50b15aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce132814b26c0fb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d5d286d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781ede06a48c1383938a9f242264aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = pass +expected_ciphertext = 57cbb1d2d65c141407b9576f9bca609316fc572f2d2cc947cd51b7767d46825c16d3df8b3552d9f04dcc0c946ff2413271393542b55f0399350d04e78f8b89c4bb1009042eae994fc42ab5950197dce9b7d33232f28b787b781be3ed876f7403c1aea44f281388d2aeb7ae9ab2a66797e0bbcf9d9475fc0b1df08dfec18a199f4f1591e347a290a1bed55b3ccd4e02713874bf240dc39daf1d871410b9e0b13301097a8b5f34c38df8739f5c36f587400ee712aea03640050cb0451d3ceef2dc252bcafcbb29b5e8d6fdfc9e54ac34af80f03bc660424317d07def719b8c7d3bcc73eb55be669109603df65238354ad81f6077d24fa8e8cb863048b43d1d7888c7f4b75587f91432192a570fd7d78b0a6b081ee51c4561e00e67a0b9c59fd5851b9783d16237f038de6d9a48f04d7eb5a705a479d5c9b8c15bf50509e1c8ab2d75a3c1374ad0163eec68f3edc973ea23bc0eea94e0e4055b30fb39ab6ae80d4b745eefac8fe1d8521be3acf3b18563e1c3e58cf719ca2abc170554732b4513e4195a46fe211482a066d9d24929a15a0b3368c99aaf2fa08206e4969531171fbd669cea343bff8176235988e799f2636a8ad5679064ede2447d3dfcef86ecd8183d5e307ecc39caf2cae06ce08ec7e68ad4a865373f630dec35c1348192acbe7f03d6f3409fdd6e90c6e93c8cbc1e72c1eb929222aa8976aae747712c336a2faa21496500781f43810c94e0b9103b3989943e77c5e9c0b47d86c0b13a3bf3ed76a7f280c491d8633631edcc64d0f0ab05bb3bd420a001675d3d8dbba207db055c87bb703d54485a4eab992c9a9f33679def6ca8e3f6e43218e175520054de072a971ce6d053e0d71ce4f5c3d013a986b7b534d2d1d6b77df2326e82ddc8fdd4b529d586e64c1f08ab916e84e169e2e7cb3e86bb2db3a70913f629a509c601ed34202c51d1233fa7083184da3f9c198c182a114688d51fff6950dd0210ebce437f16db5c71fc99a7a7ffbbce8e9daee1f01704b5ddac15aae9bd9ba22c9acd7e456d3ba4506f14410673c3cba52f1cea52856ee3aed64ab2333a08fdf84702de5ce353146eb79a8e2f213dbfdada91fb94ac2fc7e744572d43d310c978e7b35430e10f8fb069bb7973e1dd4fa55073dc00aa0e871d9cab4e258ef4507fb3a6ebb4bd3d7b881ed82e9962aaa37895669b2dacba11386be59b90952a0dbf323b8f9b14d86b89c22066f6396e5df81ae195e2b99fb5ff3dd3b216650a011bf55df026ce1c6bda80f740838c50608e6c0a80a75be65b64b4a4a8b0879625dbcec514b5fdcc6739573b03e1cf99f7abf9cc73b04f9c7a632343699257e15c836b65e1d3a402758a6af62073df90166d091f9c22214f137fb401ba00d9c072f1feeb88321549cb40d5b97d4ab9d76e3dcbe924b87714a05d43dbfd22d0b6710023af4a4e7239b4aae8d0268ce441ffc1556553e6fb694267867d5d3edca2fb720e383e4172944918c06c1a7b7e3ac57c667652556b3f59f076ec6eb26bb7d99f6c934317906cbd84b78564db3bab0f4461bb3b9f4eca7ae19d4e4fe85cfac56827aead0f748e68ec0cf2f3b2fc764a01743ceef75e64855e03f4708f7c0f72d68dabfac742706cfdf057ccf36e3220956a5d2b85ee8b46ddba4eedfcf447186ed3c85b5086cb8093eabc3e874239f3c017441a35dde66c71c984d131ccdda6a037a0f44c75d4c993045acbb2e4a1d7ea8604fb6c898fd9c5842fe6feadd2c21aee9956143ce4536477a550169ab36b382a65928474c3d545c44ba6b6b9faf2706f15e6380cad7d1a1617aa59b834f6e88dbf6153c28449fdb7739b8eb5b150a4149b0521098b112dbf1ff35d5aa034820ea3d427c48cf4d57cfe2a90dcc81e01d81a392772c1ac307b3f9c0d08304414dd1789748e6eb258bde4727b7c9f2c5de553fcd4210300bf6cbc4306e0e43ea222f4df44639bd9d905acdf5b44192f4b5fc48e371dda612bd8a242b0d344387f7617eab7992de8db81440ccbb68c54b08d1c8004bcc9f4c970d5199384351edba8d86683aef89f60f053b6a5aee7fcc64b30d79414da116cfa251c4e7e94f3e621e2ae92b08888e07e3c2264ce732a1052422f3c3d9d313f148110e81eb8929403a36f3817ed62e86e7ebb83e364933d8c34cd3ae1788e446a17c4c80699a3498b8ead65e27b6ff2f7f794f92333bc06f0abe657 +expected_shared_secret = ffd93f9141d4b2abf600c1c258ee78e0f752513bb002677221060cca3ff1e5a6 + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = ea9213f8fb3af02330f61ab15d3a31cbf57898f016b419430d790f4ba8a594e2ccb6483e46e5474518ccd033543065cbe6a5755e97790c4109a5cb18b124992d885493e03a262c3da395b46a069b9154c81294a7dd59bd092b69aca326220475fc792aeb639ccfa62cb9c549d28736a944af91119ad865c8e13700ce9482ab6b89fa7794f9d273bab516d142455a78675e21a8e74cb13876c82c738a55a4649304cb8f9cb2dce220c1bc06ddb0c5291595bd5867fd105236a91d3d61b25950c4d991625d3aa711a2449d118a51a88a1c4c17ca680c3ca950d141a220a0271a2b0593db333c1ccbe6a1380e465fe60404055bbfc511895861a32433a7037a00cac8197ac11528011e4eca80bbd921f2bb8162c0580fb94207c89471da649ee7cffa4293c4b6baddcb88efca19ab6c6e71f54814b8a2eff67ed476088dc30727aa0a47b81f9390bdfb93c3a8281ef3b92be88b130fa739023aca492549d42103663b97d7318c01e0660696984aa5c5bb1019024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785a41a25703627f0a51bfa82344723c0ba43184a77556b8cb107232f480488cb24f8bf324be8116fb49c8c329bbaf00c9ac7751a39a222217979a83301c0528b87992b87cbd5c576c806b4e8c383d5fb025ce83104fc5abc9d235ea374588505018c167a78902adf24f33ac22811c612cc09b4ab1240fa18359134cf4f657fb5c96bc544f83b8b02620b5564694284452d8d0467716bf41504dbd6574f5ba2879b674e9ec858700213df91f5f9b18686669c9365d2f2cb9def360eda91272b876cc75a022724c7caa7e003cbd0b8bcb5b8656fa7255f0c8be4bf2398e3106e47ba27a934896370d52e0cffd9263cc85b6266018fd6303371969e7b78d326c9fc2c9a5b1c32e68e218ad278a8d5ca5629210ba342148e45217d594958bc0eb6a13b5910af6f616e290472ce203a7f76f1aeb4651f00397fa537fb419ef2ca0f28834ec0ac07b11bb22b3a1a1b1cfb4679586f720bf6151662303f6fa774ca020fc03cdcac3b74c319c5b23ceed4c24ebc48f067735cd5a02f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f6082965579be60a0812d34361695ee6282998219366628ed9575203d6652fb127074cbaebd2c1b25c520468a4abab0b550503cdd33851ecae8bb27726396a15a63dc26078368aa5a7c1b075e781fd231ec27cac42eb9e507a82751b7c8cb7b3547b0a1a58c82cb99da9cb926e311b5a9a1d682bb8da2c40fb679ae4c15ea0360a39eb6fd10719ae253aac91132938579d3616dff29ea1d33640e3b71cf2652e85c786873e1457762d230e99b81db1a99dd0a8ce052849e1f8a5ee050eb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02907032337720dda9b9f8174fc20afb4439a21fb979af288f7b7101b104e2c7a9002b353dc1c80bfb00797455640b603b65c4cdc89254014079fb33217a15c31f6262c1430002aa148ca251aa15981947d27951f24030f9abc3e49370a94d803094881f3017a8be248e2c9515822439ae537776949641513c99c695625134348172b76b8ed929d1063b05ac774d83a3a6b0482eba52b2f07bd17021e0fc4b7651347f4b95e72f0a6d676158ca191a5c9975b1bb5b5218093eb9716e350e2d340ace90956c05b5d874dd60a7c9716894f551dc5986e378c830af8ce327a027741431d48714223c83f7b1dca94ca5e99814e1311c69481f38ba87fac128ea30c19b2baab1a2383113e5d282bbf0c4175a69fb4db66fe4421bbb26b990203929b3a58a85245bacede19159d1ab21537cd7861191d15185cd5b4f07a2559110cb42bc0cba54cff480750b56933666cc470b2504895a1213db43c5c176590c9d97ac7279d6dc55ccc7b1d4d82bb33f240b4c635a936beb5d71f787c396371c088d65f7b2a395071a4e6c381a1708ec05a6e55959845b456794055864c566d445ad9091834b77a30228caec6a0829bc243a9330b42010d62149d672373812dd014873bc79f627b25b1ecc782384e0dc8accffbae88c0415f6cc03e7640895c744f4707e130a9c9ac6cbcb70729db69ea7c6d8c8a9e94c1438c96289b41419af6ab083219f8a88753ca8b6ff168d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = pass +expected_ciphertext = fcb50c168f3358b2232b2f566c1da4da98f6a5b62e228456823fcf38ccb848e3e29d856e87621f63a33287c2e48fb861dad773a832f9d80d677e3d6c4f93e2d46bba6d8523135daabc358ec800144fa4b22e64843c1844dcbac3cab2128094434e628282f04eb18e1694096d0e19e3924045cb1a4a7805d879eb4a66f201809d1ef6a5523237b361739de7f5ca4e8a4e026128712eb591d422831ab93410d5a0aad8a86be6e8051ebd4119fa2c57a74a0f5fe71453bd80cd1e779df5d2fbc380a035ffb50baabdec86302e32c18dd2dfece9670f02edc07328033e4bc543e1306097cfc121ae9172d39681464c124093dd853cbed8138b891b9baef4633251610a95005fc6065cf747c964369269871bd4aaeb147fba8410b9c2d3366fefaa6a23c850b6d5270bf95a9d1a0bff4023d0c1593ec0e178429c120d16c88092c846d5607d1e831c7cfc084971720c9eefe55af3efb2cf53c8611f71cb4e25bab3c3970aa4e1d5f71ab263508d3922f4c188fc2dd1430e968ec49cf18a73e0080f29b1228a735ee1c9eb404eeb345996fe6e18d4bb466dd324f51817a612502d9c269a53a0a03de09707f772dfff58204ea9056ef052413bbc2e5bb771c9228f1e6d6d0e317cc254f2196821233165b38cf1ed26a407a8d5550db26e210a79d153084d2c22dfdae1d19ecb815075e8b82db4377b037155171eb02a88dd8ae4e876f13199655b66904ae4f60bbde98388a64261866404feef743f1246c7cbfebc6430af76dd70fb2b4212306846c3b8e9e2513f5f9601ae4bd8e3b892d98cda10fbcf55264ddf3ea834a8bf0a770c71cc8111061fc693fc3bb42b8d098ac54582b4dfc0ba6a3c58aecee800323ba806feb47068bf23747b35f557e74f7fbaf554ffd81b1af5420b2a4ffa23f56f1c361a02b16cf87e196d1e581be1158aa0973102519663df840f1a1ab7d9a553246d2249b0d418008ac2666481716f9a4dccd25a3cb38bc4a87cf9260cc9705229a7195c7165033414715abc58f1cd74046f06045559fe3083ca8a461240811d5aa75ab314ca9cc44d4aa86f792da4e020d3a9fdf18626162bd9ed2bca008b2d136f2df5a9b00deeeb7e292773cac02cd69d07a03aa2236f86938052f22c643119a072952b8ddf88d83c727b33c7ab3a4e536e96b48fbf3d2511689754c2aebb50f6c7a3c8b2d64c630712b33f1fdf17e4a5a523de991c2419d0607d8d2975e503122de717aeb5782342cecfebf801492315e2660a00d222a3d275b7f17ef07ef6161e7262bcd9476b1e963ef6199bdea3613a19851d375fdba192563ae0c17cb30f7d0b9672eca4fd300f49a176d1852d976b94785c1ae13a0a3dfed4e08377247ea088e01fdcec464bc125eaf7a57bfd25fee500252491a952aa8adbd53188bcbcea3e53e1c22e95b731e8053ad8c25f1512ee943fb1e5b744bfe620f03ff709b93715bad814a5b32ecc8da867fdeff6fcde7dc131633c530ce98e552bc5a7566bc46705e565e33560a37112c451c6305a601e4f21b4293d773df5fa417f2af26b002cb88d50748334e2157fb0be868022163f332469b0abb2fd47c8f0b36de48662f0af98fb33d2b6d6dcd6b49d75372e9a5dc37e894fc946d21046bfbe1c30447b39b07a05692ed580c8be056929dde993baae59869f35db1c6cb9477834d8b5885ea4d9389ca3ed96dd2e9a32c824c167d80c3efa57de8805430e6ddce94e086c27c67081ea4efb12edb1e596d3e6464a7ca37e34ae9635cf3892d1a523ccbe6dfe9697cedfe50a0892d084ba31076be21632de72a70136e537f57716218d6c45ba3db7caa0719454741913a40998125fa5ab84a6b86bb3b02ee1847e2a8a76e8497aa092c4165701f894be5cf024329c17fd166dda767e6a8bce10834e6c24087ab22daf5bb17ba0a58fdcf989e829f158b817bfdb3d281a0220b51716a53da3a84da6af40d64f45939f0072f007b451461fedaf3582e0c42ba16a7222dea115df07775d5662b51442595a26311abe6805c45db04fe9cd449e187a2e6438b4ed9518a4c9a8b21ed4431d4068e3fe2ec34573d0713ee9320e43ec320119cc967b38941dc794f9460cc300b91f7b831e72a4dc34f607caa68f68b535995b9bbcf51ef0656787128a0242748f6a976af65bb431b6dc45dc99196c2877d2f56bb392533badb4d1eec1dce07e4f5a07b59e319f88 +expected_shared_secret = 550b4e8c00bb5ece74059879fd14f5a0a89073d8a54f8bf1597f1ebf198a61fc + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = f1564b86096399f0415e5b757e7a6f9ba5120dd8a938e06c7ad8581fecb46b60afbbb444ea375e53837827f80de1e3753a4aa255a4917f1c8af87923f8397c9750cbc7e5864049315e718aa2732b6bf7be35694468f55b45449934715e460c6eaf734f96a1adf87609f8551dca87a94f0217e4e507c2b637f368ccec681f36d6cdd469be9d0bc7828c1bf13a2d28b8093b59a174d271ae9736b6397a4b8c9e4ed085a705a4987bc56dc172caf58e543bb9d151b259e735ca851dbb685d5158596d61a411e7c542a240c4900bceeb6e6aa7acc7db5dbf60c178813051574dcdfaa38d6b8eb595712c8b758f7827a981944f550597d120e926486e623ecd029e92825ebae4b6d049011fa7216dd81c005b376bf6b1171654b5a3ba932bc98111b8213343b9e18c9e7479611606961b476adab27e457225351e2981a4e65b6a7f0b02078505d7d3b7dd671c1bb79610dac7c92518a8b851ea5c3115f5cadad3cb24923baa686542e83482b725474381409a4016e54066c32420e99349d0c5a32ccb0b010983b96f8c657018ac0014a34020888317a13c8296a5fda3937ebc61f2d1022b2b00e7a6341bdc70d1a11b9eb10673c07e612363e6f0413095561dc15c313138efe56c67877c51f216476ab182a233f34801205a9087ba56a938900a0cced6e16462a5bf746ab679aacebed1b1b62b78a1e2aeaaa336f5286a84fa76e1fab798749d8eaa1e71c48ef6a08977235ec54179cebcc349863a9e40b61d68c1ddda72d60b061f0c42e6c179c0228d8722ae90d022d9747ccf9326e4e27bc87257c24892043aba248c1ccb8405a66712779444ee39bf91292b9f926d1c99c65a7941bc7c1378f682f390b855d88273e56fc1067088232f679c5544a03b64cb2a8d9b8319d254c3b19aa6184b1db0529bb9750df0cc6cf5a39b7139383876f633763cd07feb86393f6053a25b043e6b736b0309e7743103f0262133a4b701028db889fedb88b0f5a49d77938c33a5af559468a91e6184bb9ee9bd71d060c6f0b2a2413bba67493fb9a12e7b8c4f35497ec192b4086b4741402e46c97dd85f12d79a9b915160c788bc552a00c8ab88b50506363ff3eab9f84b5aca7460c882015ec08b3b4155621558effa01b4e1c3ffc310a2405dd4d4561e8bce8af738cf65279fd56571bb2a76faa6b1ba9b0b9c7c8e8c9349d504952c8883a4bea1c2c7f0528840119bbff2b2887310a7f1030bcbb0b8002402c2c782c183853658fb374de5ac9bacc24dad86b088daac4b62640fbc5eb9990e089b1f49e95bf3471edfa0521fe910c0da89a1193d2acc253c9aa8ed15bb4bcb16d3c14d262895d594693825ac0ca0567acc11c94a6c27438d6a5403a320b2c4c47400a9817a2296be402dc688957c7494600870e84cbaa433076b201cc64b3a3a51311f7c5a3ab206fa37c0a1c98048271648b5a5384c119dd73ea44370358182c713ab2e399655a171670a5295773d2c36b6e4b934599656c7808f13044084a82666742eb6b605dd2751de5872df234694a84397aaaf3b894e0a7507c3a354dc3409ccba4cb16b5387406bf7d005a17352c4d331b7801596f031a7a15044e1bcc00c4a920a1ff7cc1b904847977261ede038c5c51841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c45c2471ee52019b952bf716a1bb4059549a8c0bba67519ad4f10cfee06bb34496f38f9491c172f2be413da1b0a7de20dcbc1aff4103e546c8fcbb20bdca475c9161dcea2aa3ad534fdf042b2776b04477b14f2c705c85b3a7c5ac3803b3548b132c6af8e90ba88ba49981729a8621f30c2aa0dab04b49bb28abc92d9cc8311faa8dab45d545611a36b86549760cbeb4ad464199a35811a63cfa00a8a1bfc202ba75d73560eadd235c2490c8e514ca29b30ddb0996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553035201e48c406382a842256162b067f887729e298436485f10236f67f96d263c9d0835171dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99393c1c35cba50014163c84977edc8f02ebc9b5ec5045c6b1091ba794303e8bb52c7b8238a635c23d3c13d9e918d29025474098419aada6720c70da55905c197c1114c60054fcc651ab6aa9876430d4d530ec7a7a734189a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = pass +expected_ciphertext = b2407a93eab248e03dd8b32b67d192b562144cfc3f6c221a1d79bf545efc25a585332391ea28202105a03af661b765c19b832b48f15b7d94ca69f8f60db0754811c749005ea0af732bb6e2ba28d81c6142b02dc19733a0ac36b775bd617e801ec4f2b2a4efa3779a76ad443f6b3ff9a362a7c08493d33462aad8776c4471bbb79824842b4757a1d884b457fad025bcc3bf29dc5aa61d922f78b128a627d5dd6c84986f2bcd22182c9de1eb77b0b2f7aa81207aa26ea0406bae3a9ad686ededf3fdf43e13eb6086a9e308bd108e05150d66ee98d04e1b549998a148ee54821aa2908ac5b10baea34b2407158313aa3a9dccb1acf1bc5e57292becf2844869e6f83a7b4871078cbe2b8760f0e5ce95fe02e2b2bb71640cc7a8ec7a23fe0d674279e52e4b860136cd359c5d07c2917c1c9ab1a30bd27d0611cc19f5ee7fcbb0b460e98d1ee4f4f69abdac6fc1c10fb43cac153d6585195d0268433430b343e78f7482403cb341d250f741f34508e343d43f233a87127fd6f13272e12a2b73eb390fd0c9500f5d36a5f8caa8e9ea69e13506b2b10d0c3c0c58fbcdad28dc83d806e656925b365c598860f72bf087345731ae2165eb46c0a5d44ac43c9f1745f8c2feb805afccf9b1ad24cad13639b7938097d9314ccb948aa45a8479904dac754fa3f1a24327252724492acc9c3d1b4ef4d4ed1d379495dcd3df5e3e5b8fc4739282622fd2b73c0b459259f9151c33395269713a78b5bb8285b75f33c35edc6857103c2ff5f9148e18faaa8a09b2eeeb2fa73b8ffe180777c69c8f4401cc59478936b279ebfa6432f02c01e01328e36650fb2f54b75a2ea0434ee460ac451bc828dae2681ba390d304c0ff083cc107f9d941279d1cb34a1fd13c7ea98ba108856d4aa22d6552563b05b55742a03b815c8dc04ec503a86a79c20385b472cae9e04e1d288532629048cd844184984fb1538867c14d7006fb11baf5c9630e739210494f6f4b0aaa20ed6adf3111ce159c6ff6d70862824881d29ff6e990bdd18c4caae9189d7fc4c7a32bf0edeb435279fe0b38c1d7f2ab231970a1cdf0364767dc92e730b6d757242d0addcda7e4ac1da31ea5a722be4687ca79637246a6ab01ddc699627939799e4889d078f268b100ac98f3ab248f7ea7e1a2f1cf92f9b107efa0aabc8deb3be2e108d99b5f113eb0430065bbd6c681b3ac9b28808ca224ce44399efc9791e7432ec64848b92ea2406d6dbd8ec60387a0cca37c9789d293efd841ad0c19b0253dc8f27185983219344c0e895b42741995f75e7ed74036024875acd12d1877f658a4cc4d2199bbc7a70c9bd61607ad1aa708a94bbd6132b7063ca77ffcc9ac433426112e960eb210e914f03d8f57c1e014045d9bf9c25cdc399e401c40d23d47e40f5c478a864cafcc3a27d39c927d9b6ae4cbad079bc984343ae0071f1a9123ba2335a02b49d1a51137164d3f8f92b9493d8b64e312f7774543906d5c5f6c545e4ecfc67ced611b01fc2c85fc33dd9eb3c287d196eb9464660c95a3a67cf8bbb3e0d72542836c53c6ed82b4cc0de8efc7689243b5b690bed176634abd962fef5a42df66b87a2ed6eabbdb94dca2298392acb3a1bfdbb6e254f10debaff731ad7990ef1e6702295b4240b625dce707cb27b86a5cfe4407ccb8c27c8deb14a6def5a187ffe1ad23450542775f87e0438ed4dad3eba330bc7d54503a531c668674d52dcc73485f25f9ab79c1ce33ae6b464a719a7bbde4865ac2e5a10dc2fd18b09dd19da0cfc7c46c4b2b7a99de777062e9298d5bd31238a381f8c565a93c5a105cefe6c76354e8231ca91d4b75505367af0b1b7a7a424208bbdf8c468be7c97dd1512e927945c4b3a4f594214b8140d7b1a7566fa0d9514d1b828da6beef5fbdbb1f09a1b759b4ce2ee18a474edd188b889c5a9af2cfa1ceebdbdd83dd5738480954fb4d19afdfa3b31dcd2a85315d6707899889188ef3a392ea331534536f7158950f5cfb79e90a4688bbb3d13adf46ab60e7d996cbdeff1b424eebbf41d35e92eb710b4f92fee4ca8791479c9bdbf8468ece24868c1c875c1e2c76f3ca24d582e93be11e00a7e58377d9b395ce9ba710746fe9eb78ca29de5bf92fa5703fd36d98711a9863b7aa40c0e95d488b6ec72680abaaa17e13b8fbe7dc30888ce5acbee633370ab5546612f4602a4d9242c91714024a98c1c3663d4cdbaa +expected_shared_secret = e5b98a3c32a5563c49df725e661a9f44a20390cf83a9779ecf5e7d9f5aff0143 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = 14b0961b350facf720ae691dfc4a847b143d9c9a2d2e7a35b6e33dd78b761125bd8c4b1d6994cb8e01186dfabe6270a51cd85b8b39678af4c337bcb4fbbbc0fc260d48aa801f86538eccbd3787a12a09b42e18afa2e8c77bdc11b13b5a8404cdd7b2ce364046ae059a4c950e1e4638ccabc8157b97a238a6fcba379bc6afda874335956d2325376fe1ce4405bee3e37ef818b9826743266c078c01c36fd62b1d17adf33467d9c1ca9f2ca28a2867bf7a8084daaed0a19d2d40a0979198135c229720205763401045879ed65b09825012e626a24118cee00216930d44a9bca32bc74a6683a8d1bae1701b189bcd8feba2da42cc3b572151e7243712789b2801043196bd8c15d972cf7674771dc55e74931fc0a55c434497a517c99ca3276d262ffd83cf66d87600d097b1ab5dd8dca86de94080da8c2aea980b3a1115b847786aa96b94ac818148e3e4c7fec633cbc6bd3104ccb216074a5b2a8c757a455ab38e1333435c3c30d94d8e922e8e77c0260b6128865bc37b82c7a6a276040edadcac335a10b569a2cc53a93b6729728b84b74b01d502b830330000aa1ccc9c4d7e7a74ed218d47ca60016411d7369248a261d6b6240d5b15d2fa5b3229373484c8d23bc8e78830062959d0504c92c0bac310967ec40af0c2902f82742efa78f57b70bcf54a73aa2aa93b0fb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad107711aa1729ccf857a14b0002f61575365f3ad9c18b947bbe9b3e31a7571a918728479710d64dabd569873461e12a9dc1103ba28028e001c8d5a79d24d30756cbb4a3ac9e48435ba09286ae89ac3c841e8909a4d94226a822c90b5a40f239cb0e8b98e86b5b06e20dd3764e42e8c8095052b1f66b76f164b3b867a98cb299e0995d44b5febc7a1f2c0cb2d0cd4f3ac5f9d5444797941666afd319a3c6713ed1e31338a41a6e2b548208cff5671a6fc7ab5df260c2d8a703a67eafa381c9d576c6c2b1177b6a66d951bd3c426fa79cc7b552ece197c92856b2c7064605079404a3b5d8b49afb9c87ea48e0811a61e81e2f101ca25a6a599947341040e381a52cec894dc9b6ad25b79dc903c35c450201071dba35ef8c11e17a1ae5ec7e13468c148a5946d928ed0321d717640e5a5767942ef2275e05e395321052e3e5059af77fb04271c2e511f450be168aba09d3b9eee1288ed1baef69ced005797982316e2c731f9581cd455300f35a6e1a5872552ac6eb68ccacaf636cc713516c275823e4a1a30a722f8c46a8932550db624dbb8b6e0bb51c3d54089fcc2042f38f5cb5988e56a1f42a65d5d788e2551f60487490b57904127433f685ad4bc53d6213cdf52d6b0991ae37882d37b5dc084e5a49bef660a4e8d03e24ac93e58bc05f8a759895074e156c09e73e6782c00a6cc80cd04829d270c7848d89bb2c321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a08314b29c81e31b63a008a51d283bc217adefe37d2d9b15c7257cf62a68751c2942c531bb55abfa321c581822c90c243d94b598fbb958e5950fd4c8b1f1cd06bacc30828fbf73a83f7387ca252e4f9805419c02d63189ee7b4661b5c1bd398ec82cc8da173ede64a38b3c1ed53a64db130564d2a54600bac8017d46507b3d56208975a70351a558d5774b249f7d634e6f21102310b6bf8c1544e217c68768400c3d721ba5c0f77b9d20795c8059145956ac7b7728222853a3c325d070a9eb256775c727118eb9cb7134748ccfd09f32c930881826d8e20af48b2e1ba10efc67ce0ee7730093a7305403eec951f59044a5f7317cb85caaaa2e2b5b90ab2b805a808c1be755f9a4c342a96e8ae83cc4394d73890f13bba0d35c45393730e4118d5345006ae62d38445666cbb7c25823c59a9d62e08bb8c7cd22b331be153af7c359091081fac67d96384100f44951422e83599763ab739fbb8ba2a064a41cbe1679a1c613815e9a51d5d6251ee73431cbad479cadeb64ac94f92a38d0798a4b6d3ef7233572b68d2a12d125a6d4e27939f341a4810f0c07bfaf993f8a74bf8e9710e7b29389ec3dfc498a4ff1839a1268db8b70e82670e689b5b3e333908b6e8b4a78fec249e798bf57b7ce985a42a5269435c81ba441230ea52319550476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = pass +expected_ciphertext = c1a2cadd831afadab4b54857c7e1eab27eb6c7538d5d78622985384a68ff6d1bc4e8a792306ca33d26f5b26064703cad77063ffb3e55f9e1490397b7419c5906069f2551c993b0b7c913af47ed040735f45ea5a179a29bed28bd9bbd06ef9de5f8bba3cdd1470f533f69cbcf5cc473307862a5185ee4bdd08863032f6c38659980c11b05150311ce50e5dbec0e779142930d87b3ab966156f7f003c3ed6180a08be3bb52f9ea2e11008beae0502fd3c76d44b19cf1c1dceb7b076756485d446142ddd0ce1c6e5006ecd91214a6b735b2691ec0641625dd8d530f97ff0cc5134d59d17fcf612048af71e8f9544eff4e81281e100607f520bb7c7c6ccdbcf2bf68b1b406cffc7ecbc8d41e965d433314ab1e68df9620f5eb90a5eb73f00fb516185c8493d9b98cafbd6267c3f1ff25d5e03c41d0a862b37faa8fc3efd0fe2a979c7d2b4ef86e5f9e93ed1bf31f237db36bef649a4257e893e14ebdf6d1407488a2a80818a450316691641358438fef5e094b2469e0ebe4fb9bf4f503ac5b161ccab279d9535cea2e239475354019dff1a3c2274dc6d94eb9182de07e12d00ba1fee95ee31203d35536281279d9f7d0929fe5c7679ad8131c0036f5a7a9813c78186594d5ec9b2a0c1f8e5cb531c822cd2f4ba099991b910f95405c964bcd3779e23211148ed68cfba4851ed5fa80d601488c2a0611bb5a8ac49912a5fa6f250d360404ff5f3421504442fea844b90b9cf9f2269d210b33b72d31d2f163b3399477fa2c04a6d4ac0b57d9e7a964c3eb96155de04361c4fb6819a9c5c9073f47cbba4039779af6635ce90e8d5f5635e4391709bb13a57c5887bde69b34de173d14f52a70a9ea53e8ccf659a3c4af4b867a9127d0d84644259413fddb18875302bd9a99e195760724b3e06f6f17ffa1fb13b90cac5aab72abc5b1999bcc8004f6f9a29fe8dabcfeb6083c1e5c87d7eca5b9595d5d725889858c173a13ee943ca2666475aa7b90e043ede6792e56ffae6081e6fdcd10100440dbe8a3b3f7ebf6f531074e870d7c57b92621c02d8892e8b1c29880b822e6ca8904ac37efbe11995dc3865a5e443805f4429a972f1cd6cb8bacdd119f6fb2fe891939e4ffc4014f3bb5a083f6fa26b8b6c17b064f5f19fad8e4260ef2ee8d0f1c2b20a01aa53b245521a84b2ea891af2fb004ea5625c5b59ab515aa162fb0c512bd61fa485016906fafa77bd86c6cc46fe96448a8208ac5146ad32b14e3cb0b41209e9702276ddac1e5a261b9d1ee756d55d9eeacbba104c93f80f36f1adf279fc6cd73744421298ae6b7a5fe33e025fe3c83c72d21fa86fc6c2f1366582bddad8544f886ab61a8233877a342a033c8c16fc49aa721f5a9de13b139cbe37a1ae746df5dbd6963a844bb729f051ca000d101aee39d85177a3c708577c4743fcb250915006a7324024cbffd4342d7f4364851845723f16b5d87ff778f814fb1913996dfd1dd32364b2f9a4f025bdd5dde20251324f2edc9fd385d3f84ae4f071f866157d218ff48814ddf81100c59a018239365b22e267195363aa3548299a0aff4dc9febd6e5e9f59b24fb7767710591ffddfdc56f48dd07678152bd22440d6ae864bfd46da4299c1bdd22c5d87814982e9cc451c0bcafdc686c0424a84b012d75f27f7687195e8c934f7a6233fbd06a519c045d13eefbab26b414098bb384b5858d122f9235da4f21cd980b4ec1399f15643132ad31531134720ef8c0268a325b23d8d0c2a3c875e7bd817037013aab674e29efb2af86c3185b8eedb4fa1c89e5fd89fadcfd43a37f3e2517e978c522d4bec552fe22adf37c3df8aff7fc611e00494bb36bdd24fd4c508f30c097d6de9cc3f786b3f17db1ac06715ccab38b8825628b677aec1ad3ed8533eea31db6ca47fd6fab9f0f0a3c668b402b9099618f388a326746a4dcdde06d3f51f1106e805b6b0177c8883ece5530a52275c44c1ef25860053b6dfea49287c9ac4c94db1298cc1c782bdd5781bc62bc49490bbe130a60dc47779e8fa16b66b61a56577186e6395418c73a0d44ad453c1c96949818db8d2145d4f5e9621037f06093c3f932d3c5060835813c5682a3ca81c3513f3533673881de9973442818ea1a2407b67ab76b3472d54a99fc35c9dfc1bd50fe38ac3970d73aec2582220a658c71be9424d0f37ca2ac17674298651160b0f839ef7dc42db08692183b5fa10b +expected_shared_secret = 169929e655f214d7ddca31eae7ecd2e01d9ee0601fd4a2c3a59eb701ed9522ab + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = 8eb8491c75171340b7774793b7912bb4186a7e3837e33414af6aa211061f3831c4f4b16b753228e998a721385d7b14211d8a7096c54ac3101dda7668013cc1555163f822b1cc144e240c284dc87b5075a813872511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e39298872552f8bc4b0df1632255588ee99b4bd373a21c665574bcd3fbb35690237a6cc691f80523390485447be94b76fc219e7d75c6649ccbeb00271fdc1d666351f396c08eac20ecfa784d45bd4d64847ea126d9f0a23a3b1727396f299951f95a68efe55c5d4c792e136148aa35d0663d64f2c040586e44b6cdf60c54e0c08f365001513694e27569a3d6c6ed2538937a7afaa0bc2ceb6b18914ac77c65922ac49e47c74447b889a39344db09dcf1bd73ec5c48263c214a1e946b2cb806668a32b83c0c97ad547989836a53f1025348ac068a69357c7f46c69f963c5634908b9963bdea79689b9679223824faaa920439356c10786a646472372be8729c4f2ba1e2897728cbab136757ac5a75242608d6d10e20aa6446a4800eeb621ea822c1a61eb7c5b84e764d83452f60e5bbe79b275c4a4445715d21ecae5a569073475a74ba62383137974bc071c27cceb5bdcb1991d393784ea8b28f259b118089b4b77f9b68ab0ca953ff8257a3938482313f4c5963c4b101eb0321d608c2f3127cf451764e15636eeba98021c963f359d2c44a9e92357f2853821ba0c8105c488b242d9c02ae637b2002ce644132069a8babe23d4e9a056fa0b8be8095113b86e6b5c748706924f6aec490a46dd398444499b95289f13a84868188fcebb861a004254068f6d9b4b83aa81c9b5433c70868ab5364a80d870b841a216506663aae569b025c5cc43b2e5a6821fc300eb6574d0088bbfb7483959892703666da17797dba514a489376b19707a144b6f80423073efc608347ba2e639b0c8f2a52ac959592b0b0c1a5b4fba61483f225344051dcfc4ec124a9d10cc2c557339325c699f091319853ef7a445b4064d8e66895f8c0bc887786f5240b72c319fc0b55933b5864063d14c5f732472c71340ea26bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa110e2cfa9ea61287716f199af376b106fb097760b3f11237fced41eb95b798f2787b3039f9c213ca5699aabfb03af86adf5d52d6aaa1ea952bc04725a22b2a28f4006cac30e265c793018145573cd1c715a69d704217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbecbf25804a210daac80612972acf605e91303a2d59b1ac84ee217872bab85cddba9c6d1381e312b4c574097d95b8afb595bd91c46fc0df0a761f596569f99b7bc6505e922a1f90c045493cdfb9a3c650224bdcc26ca199849128945ca5f97e230d601283aba102a26818932004bb114879139ebd637ea035c20c3ae176b70999c3ffcb7951742c73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab4d07bd6921cbd95c18ac60e7ed35aaa352e143aa1fc49630cfc8a09845cffe260ad953b71074e42f08e265b7473db4d178c269f317ac035cc1124540a4a47886b6e5b04418a760777e73aacf8930f08c2ff10815559c1e04672bf4b851233011d7b3a84155d76279f9778a72ac9803d36506824a34524c835222224545deae1aaaf193b778751889957d5082a9e9a34e6e44840cb7ddd712ce9313c5033590e9ab54c25852aa8b2f09252bed793bf6b972b593ca9317ba278937a607c6b9b8f79069fbe452fddf01622465006373e2f661e366a90ad1483fdf76e04c388d61646f0162195d36966d75dcc89a3d96b2f98c79d9e0babd9816aa2084611ebb558735c076576e102b3857c1eb2876d53c5777f146876e55020641072010e7a1b773d357d81b52b4071b9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e768295192ac02bbc0acb70de25a27b724ae7d3121b1a4a869034e70f279c3914d882422e1785709599df782bae64316aca97d42846a52d03eaf423e813cbb3fc26c0e1134ddfaaa3275226f6416d9788ba2026c78e2bb1850c681825774213628a23494db886aa29892ec194791a84c73b36fd5cbb2b4bdd3d664ab10246cbc9bbdc97d8ea5528ca41924e240e544a747071caca25b05051587173c9fc851edf10fd0171c69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = pass +expected_ciphertext = 570b448d4f9e17ac98bf61e3947f0006e0530ed08513ffcc4a272c08f665e408e75ddac360496d3fb2d18820817c42db871efb3a0219503ca91feb86d681d331df81b488f55e1d8f2a0b8c81e7ee6f49817db829131227e2b3fc7f776e4857ffa2ff4c6b349563c4a478bbf4078a01c2e4ff8d6b55f8dbfd787cdb94b1dcc9139399cf0d91657678d74599426057f8f05dde9b5a4e2366362c6fc0ba11140e8962f2ccda15133b8acea41ad23e155579c43062ead9fcbf512e4af35882a359a9a3a2520e192ece2f253c79ff16b51dc8b0d835f10db442700b1914bed638aae549be39a8a7f6e165bc8992b253848e36924943abab0d416569126b478965fb1601f0b5bccf17a58b8b934494fa39d4f98dac08c0d500a67ea8bedc71fcdc55bbd05724c89df1a6e4f8ee235c17ec1e3c13d742aa58bace2cad2f905740ad852d1b2ec0b891ea9cbaf446668a1aba50b162368c4289278a7bb681deb4ecb093d31db7d1f9388deea21d9771bcf7d0a22716fe1b3088c5c8c812416d428c14c79865746f67182c4ea08dbb89f739814e80b373a518a8f1552bce620aac42ee35d70d8571969315ded3a2208aab7f719fa46d01b73d92ca1fcd7d34105651a7084a5c62892aa322cebdad8c69a200ae9287772a83b9d33e7e059549de6a45b08319bfde2bdc5f80594e18d8a3351ff0f1adc88859f796eedbf58cb2e5603494ae61cd23028a21e00ff0a58b3fb4715dbd56bde04e90232d421678dc3c4e0eec2b2abd451f3826987c302731e3181764c2dc413e2eda47a51965e7810d7569a66ea1f41d494ae02834081cbc46b854517125dff564ce5e4bf9c849190c3fd986ce05a09c8f1c746e557be72a7626dbe01a964a136a2f529454284ff615065c853b591960e71c293e376ee1aa16081251007b95f5d02d92715d4cf6cc07174f94d8b6b02ddbe02a0b0ef15e32a6d008f1335115632f1dbd70502bf0c0bdb9639a79b37db9177cd0336a46ad841c951b11a2ce05bbd7a85a6e7932b629cffd002e93033701c5449eadf68e722470de90615b33ef965d3b04f163b2783d38a96cbf2d4abec8e628f8b4c1fa11ba849941fd7b663e38675e88d5f9d130527d62509c6e488d463c5a0e522156d08e93ddd50ded499295e5c5803aee6e33b0f51754a5c2154fa6d806d6645a003ab09bf716472fa935ae260a23c19563c8f749705f68b987b8d8e323bb3fef9b7028740730df332740d6632d6149703d4cb74940d05b7588805e2c501d1f7e2d16ef5d0f41adf1ee368b3b678b282f592a4b8f02881861279a0f347ebe24b3a8c656545aeb38c16cf0f37ab103bdcb4d81b621cca4b461c8020cecd65ba79de82600230338b8bde69d5d4d3c79c6094535f5afb70736f2267227be333236ad70b4dc4ca92f99e0fcbdc7d53b79b94e8ad9a80f06feb965c0164e2a254503a66eb52bc8115e95a2f9975edfbcf0f8ca8942c5b4b74a90d4b64e9cf6de899d6397be16962175b0e0bf790de9baf06b9257cbfd8bd47dfc75ac68d6096b121b7519ca7b615a7ecbbad61c5894632c719c01e3d325c71fe097fefebfe9a734ee844ffe847ef7c85a3478978e4274b402f612515021d30e5a940dec1af24f52cdd7c22ed40a439f47aaefc6f77bdf124ea4a8e5a6d1a708195ecabddfedd7447eb82774cf231958b11fb6d152a560c78238c94b383c069805a93d6abe39533a26a7f2c44b0fc46e552a1f104f4c4a7e0273e5354500d797285659bbb9faa3cec81cc9ed64ab954ae6ca8c18bfb1655ae14c682059f637ed6b6355940f224a3b01a60cd28f03378d3268b9fb3dd335911569308fdb9267e3e5e1399218e2d691620948833741fb3480114f8a2cdd738d3d313644dd11e9930835f5e84a42aa2aed8ba4b852c56724a0986c319458ebd36d97b80ef8cf15571374bfc0524773f40e69d38cb56744099863c2c2da9d85092a343f60b27c725891b8492e0a85e5755c1241f27a93aeb48699543abb24585512628e70921de558bb1bc88c5616153d949acc31a7d3280f2dad7fd800504431d7e24b6491499f0e67c947cfbc362dc2fd4a16367e53319738b39f169c6f04e464c014800307eed443f83ed044b308ecd34433d29d012bc09632472563103c09c1920a5d5b5837baf5da6737a95ad26d7cf5c16d7525d6e7b3c1fd41e383827034df3550af31add3e8795c +expected_shared_secret = be36ca6f5e0d3da0b5c144ebccd725900a06782fae7b2707ce7c5cb6818c8991 + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 85e9a58ffc4aacb3c476327b705515c6f1980b53b3654720296742b3a793258138d86728f4846ff1030f6f604d092847f011cd59165b9dcb400a8723ab79bd137566d709a5a7f62cc7a7948331920f75530c915b1bb086e422145dd74ea1b557f68b511ff8a1ec0a39845c0aa94c2bc05922e3cc52c7f59eabcac2d36b5535eb0d7737768d6322023a2ed2fb0128c2724442c794d794f302b89fe8b1a3e8326253362fc44bce193fe7725d1864acb29bcaf2c0bab9423dc593733bd99c077534cdda88f4bc2fd846b810ba71d2139fe1f50ace7821fcc5c9ad7c20baa4a430b8085441cdabf16251f8b686359c755981ec4c8fc834cf7f019e599051afa87584f2c41ce13aa9babab5aa20204974a10bc36d4aa1c7706a3838b8dfccb1fe16038d78aa78eb3594998a20c72337405e2f36683a01b87199764b533077688a9a755c2c38632cfa4c2047663e860a2998937703ba0f1780ff367918eb208b917cbd340b69577806e282401767c258b38b0c6b21a057f42b59a6dcb2eab48063116fd2b1ab64c0a864326e8683cb63e053fc03a5f6d6b58f0820f500ab1d78504dd80991e68fa6f91658fbc64c594d32a507be17b465684df8e65bd5745fa8d6512d382785ecb9b207746686aab683b0cfac43d07a0113317cc895a513776611b981f05bbf7e1bbf867923992441176135b394c6dedc8d64ea47971994cfb46bb7692f47e1b372994f3ef19a282799ca530ac7b82fca207537865ee0f4c73b0a0a84e1b2d2b058175780a287ba9a435a0fdc24fdf48ef579b55ce1b55531019060193fc5cbf013a8bf521c1f459afb125c78d2377722824736ce01901a16a54652d064e9058f918b5552936dbc77136b009b2108862f962244597386a2b078c6b46308436144b75b9926133a46ce1c44ca7b5f52a678463191d51953a516a1c937101fd236c962a8dcbb671bb1be92035910eb0b40d8672317aaabcb04bd8b716f104c3eb49c1e5bcba7e17d15861671950056e5278b845afd6cbcce9b2119d86fa1fa067f1c69bfcc7e693020cce979869588337aadd7d6ac7ac3ac67a3034a035a12750dc30c99c8692b9cd74ee2918a23248a3a6875e25bbce8c6902cfc81ae878fa4ba1df57523d3013fa79a9ab08894004042cfc00b0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b04034791ce31490459733ff1c7752864389ce3bcb826608f966342147d6a3626c4ab842480b571a9487bd8785c37a7ed10c8cada99aad1a19b144accc2be8a17be87111093189efc951d08799b5dc46e46e571b370b74e881326da687ea02e1088c400067ee3d885c0db3fbcb336416c74398132090971e2aa1fa9f6ca7ad186bd4c139be57665595337687742b1aec0da12922783c6aba7fed24d18d142392b26b3650731c07a15a987455986252b8234123e3a4a54c08b599f1948d1383183992e2cd17d3312cd9b3cb4149ac98ebc054f17cc516c67d8b26517316143c6640eab5134f41d6987c25454ca62070c985b2e0eeb24e05870667627ce5282f95635be4034d90232e997c18409b1d4991b7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54b9328cc492842238ccb6b652da6c037ac6afdae2be4b894dd66a70b5840f20fc18bbaac111486b9558137269732f2924ee050242329c0d1583bf890847b30d5921198814420b60475ce0047d973269424c54bc9e3b4c94633c1418db9a03a62f6cc224c59074809b9e023a5aca5757d3a789062bc3067698a5f216fb2c7355609a99aacb81b99087a087ed64cbc462301754931048999a2b9b0e06c9f251bc41b39092201ca3a727b5e498e4db782dd53846c7635ac12f6e89c30480bac297188338a58f338d6b7075003278cce876bbe18cdb00326e44745a4009209b04fa53ca742438336ac4f9cc337b1636898170a1d97c58661415dba67935162636a87f01bb87b66865d415360220edf89d0514663dd73a951070f68653b9c2b637259a395c500565b6b5a05b3f6555fb249946c9904ab40256d63b1d6c2344f80dbaa5b1be7b10299a7ddad03781983f8eccace5c85f3c3bb3a9d61c040141757a2e881c33a9784e48293374ca497cb59e12c07a4b6b420d3094400b24cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = pass +expected_ciphertext = 1c0150bd0c1a224e1de7d1c477f59517a9b46c570cacd48f189be2ee6ca1df6e5db2b93284f1100b3ddd47edbc5d29a8ce6e27e45d6bb7a58b4b0680b3fd9356b59d667bd9818a640735b7590fe7a99f1513d1c4637c6b5bc8e8128ca3101fbb5c71c6c50bdb475aa67f9c7e269580f41cbc0ab7dad00b9e36799827f13fd6e9f094f1e1c0ebf256cd5a56e60132796a05a4f7c2d2e6eadd842eb313933620e37108ea7c796e2ba2478d0d78ccdc66a09d14b7724f906bf4d57c919503faa5897eb33b0942366c3bdb45c3f9cef5e24454d66772778636f5261039abed24164fc831b7f0f4188b0bd392b2da8626c27d5c64c9167f86e9c20dd25b0b7315438607d7b66c27c3008bff089ae46a0b0aefaa71de7d0be42aff014179b998f6ddcba8e22294a33a535a6fb7719683af3fba951fa49351b641bdee63dd5b20d49e62f0f004a57220cd2701a6e489273dd5d1a37b35c5c6a2b86017655f0dbe5018319ce462a37aa9b6a068ccd5835261d33c195d6d98346b3dd49c14e70911a1ed705bb9d82c47f3bd2aaa5918b080ce8217dee1059c2bf0b81be3d1ad8969e1a15365f1803d56da5c60e6d227591547e1b7dfd60bb9cb3b32edbf8e7cebccbdd1c0964c88cf0ab5708b1670836fca72d4c457dde2a7d664bec8861b773805929b4e382256a615fcf693ba29e85f0fbd683b6d0a0a4af98e781ee946d430ddce6cfd62f23ff3d24af0e7c1e763b6f99233c8c80917a0e2b7afdedbd1cce32a1a8c959d47aaf7d1f92ea8559e0ecd2629cbf84844183484e46f386d4aaca70e276b1b4cb8703a6bb049c04120d129ce0b2de3914b3f50815b75ea850a54e14f8d9c8a8276a6ab50a2516f4b9487d2b91ef0234a269f78a8087568dc8f6b4320c7702370c6fb134ebc62f90328970d17b600688333a448e8cee00c998c23916f0f6063745639d330d496707caa9417d47a6731f4108b29ce419831a8d16783805841519b25a4c61d9696d4619dad0cc1ad3ec4e09b672ac2d68232ac9c768d5c0aa75de10031ae9e6a62d29e376afe2bf765213da0b4555e1b8969ba3eb37855cbd5251ad39f75601ff3dfe2bdb94f30f7ae51441bf8f39a32a3c1f173e3058068d8e83c0d1b3cc7835186d65f8383decfe3f11d9a4ed646e5b727ce18daedf4265f0dab11946a926a181b249cefd8aac2cd72f0c249108fdb3cca073b66ea1fd51cdd18e1175165ee41c3b51c8660495997442e74c782c95c464475ed6d7a3925fd15a6a0a623a93df1d57f4ce760de84c24e5ee00dba9f7df5a043fd6b2510c84b9653c278a5f8572583d4dc979a82a13517f1eebc4a00b3d7d4ff0f6b351bece612613dc4113c63786a995f27c13d0a9f997300bf5627e69428f2cda6771372b4f5a4108b282a5eac59422d9e25dee919d16524b9517d0a0ddc6732ccbf5c37b8dc372e0c295408e1592fa532f7fecb9c2ba2287e9825570c58322f5d8cfbcb708b504aac591e965948330c5fed5f5f9ca20f8c2ba1d813d4458b0d69e63e47ffc0ed13ce35b0ea48f2be3c1eae7721af145e451d1d7411f72fd237362500ba3f0d9b6c00762c58d37a5304f463e645418f83b0beec4a4fcbf03a6ea2306cd527268584173120e24f326e475abd09c78742c45b92eda33c239af4d635f2104510176cda3cf531b0bdc7e30b946b1349b123e03243fc1d19072ccfd3cb64fe0c25460be6bd4b2417cfa6292186e4eb8b9ecf7b534609539b29ad9c7b64e78f682822a03a16f5cdcba6b66a113fb8d4f092dd9136cafd896d2f2a87eaa0b351319ccb496edb346f885e3023ce6e1383d2009097b00a191b08ce3f317df080dff716554b4d5a91777cd3f41ce42c83b5c70a100f13c12e66bbce5a9164635020a4b0135d1ba08b45868f1cbaea1a5fc67acf36225bb09ae64e5a14b6fc827618cea4a805a2e7c30d9e20fff347370290b182a26440634c8941d67ddd7811f193684b330d961d0a336023bce514dfc912d6b7606d667f9bb17d055984f00ec2cfd675bf6fcb32f0be073d274e9d56aa3076d0c92bd8078220a2402dcd1dc51e10536e2e7fdcbff960ab06650634a1185d336bb9498213a144efeea84e9d8674b517753176075d48536dff17defcdc6e6a73386f30e77b5e8de17c0ccdb10bfe0868c50839575d5f7a33ac45d4a638ccd2260eaed4362ad7f63cd8967f3a91ed17393273 +expected_shared_secret = 9769b7f3571089f1a086606f3545dcd094097befd492e3c9889f9a97c7b181a4 + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = 16e63cac8b2dd05a60cc593000322c9c566b472b375e8484843aac71e74bf0315af59a8a4f6104a43159e198716e239247204753f629c5202c7812c9ae2351d88b4256e7a82b42b15e54412e0130d5e25388240fc05b253e7b0c94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e67766301b386b088f71922ca370916319d8f099f263caac7d7c0f81959c4b13a0da0b5c269760036a552016f8b591f6b37177cfac940f706c975a59da7c04fc7210ae32508c28204ea204073c73b474d74b54cec08bd14361b144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613c917393761efe2c2e4dc73d4998a1cfd6a2ff278b6f68b1f108151b857ee913b3568171bdf1502953b81fb085650bd027c4b66a8276319201ac328604100ca4f684f2fc65f220cac1db9c434a218814a14cb630b5b18410e11c37c92b31600e37c8bf12c895b1f315f0da01cab250881966d3c8256f5513cfd68e383bb8ae248e27f3b479f7a82da2aa564b121586bade1ab522776b49a02a16e3a798acb005d70d3ff24a8ca3458a826788aa09889293e4d862572907111071f0d58d679a0c620155ffca45bf03a1778941d41776ea11cf3ee899912c703d50c8e88ac447b2bb0a0cc3bfd83ef3261ca592915bfcad6cd26409472e4be62ebfd65f003c59d39b7f9f710f6a76a1e8291c834323f145aa3b8a9e2e4c2e98621074c49fd0716d3d61a2787a0598e8096ae05fcd7aa4250a7ac4a5314c842b8dc8b563c6b8f626763d865c141474c72c1439ba7012661985a061ced9679ac94983957dc99c4bd4061ea43c893bb707c0f633787c1b11d8622dc08c47954ea907ac1513aa3c4420dc48366e4045c79cbfc3b52415324e8c6669e52c2c16b1722ddc7d521558180781898a2e681a55693398ba712712b9c515d72255453a3c4212bb7b3692b3998d1bc6781ca28fea483c276a92c219a62797a88702b2587005208512aab304799a99acaacedb1699993150b41aa3291423bccb6dfa31a7b42be4997581b9aa54716cd5d62cb1b9bea0e8165eab6a6300242bb5a711f36e9a43b12e24492ab95218e084e1d2976a222024263e4c87cb93cc4fe556812096686ac72152f1a8a12b93c6530d08c99b9be3634dab9c93d27f2a4099304b4c61a4bf0fd9cb28803d0824c5058a515dc69c81228687376865852fe9daa07e45a889e650e0c58fc2cb71846b5296e76d71105e87ab2714b2b82e06342218822642acea28700486709c43b2fc421eeda5070ccc8ad1367cf2834e88eb8ff8d2059f455c2da34843418cd3449497b753c92826c3174e5e304437c04c7f518fa2eab149762c916b1c6a676a8d5b3bff02b8ea9a366f1706be888fbc40285d6cbb924249ce963646595573b5a5d0079fb9b0275ff031797899ae0bccb3ecc32eb48ba3769bd5e56667cc02723c773ba00924a961102225f2b88ecef333302077c2c761f48991755a83e09b7c3406bc8784031754bbab6b49c361c93f5ab9778b39b9cb66501b63d8859af0a00bbed32947b92f49961c5fc38bafc9b0a763802c9709fad39f040c6736a4c45a110a08822e26d93bc6ccb566a687ddb786f5d31378505f5d575746c3cbfff55899c933f0052e1155b776b9201f0272bcf67c3fd26868bcc42b2b9361562bec56ce1991ac7347b6bd500065e990b257bf20e1537988a560dc21aa652e3bc8650d80870a1a4190014fd1c43229043bc1068a5fa074fb5087581a932ddb5923730ba05216895ba1e67947c71aad452861371a542325607a7752b8485c48fa9ce930793130996bc63d1b162517c34449f5263077a41f576150d8b062718e493242f57041f2da6f271c0c5ba3a00a8c8faa0aa9fd61073dd70adb7991df8a143e797a9cf6b0cf257ceb347dff45cbf6db25d5928074b3a6ed918fd35895bc7b93682897c0d322d46755962928f3390664499a14dcc025b1c0780858db32826679a923e20ff56755a26604a2c8606fd7087218232cdc3b488423fa9328f9eca8eaca9fb4311777592157b46e4476c885581f6ca524ad1cbf663a0591a7679e515de5b65cea3a0971c9139019735d421a25f7126a9bb66f67c177f3873bc5a8a7c06026913a631b1b370aaa17019a7cdcbc22a24f9e38a69637928788bed0560a235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = pass +expected_ciphertext = fcf8147328a10f617dbd830a270d85e99322d550c48b8b7a79be3e8de132b1fd8a515f39b21a5ca46e319741a4425ac4f9dfc85ae47964fb68516cc9dd34a110a304d5a318a4f76166165766d108ec79440341f9424612975360eeda65bd7d2472331d430c9da35a17fc3b416fbe537469c6bd4de4a64478459e3df90971373421f6b53751cd482cb2b570b64c7db457b31d2505952345ddceb27f186bab6e06ddd164a4e3be2b0612cd4e8a7ab6efe050f1bde501185cdc6c7bafb33ea8630138e96cac4eebd50a32214cae082cbb9ef7ce1da7e5021c9691a6149a76d4584d154161e391e7a25108fc850a6bc26edda0cc107c4d810407a3fb9d1e364ee07172eef29d83bfe895d7c18b1f4486bfb5170bcf3f46ac0e478834e6cad1ae51447038cc8fe396cdc10c111593816bc3f08e103b93fb406ee9f24c4be1f24878f5da0c358ea14c321d4c7e6bfee0190f2afb4250c1803db72bff2f0fbb085fdcfe1df32e559e5be30fb1a9cadc7c4f34b40562cde97fe6a67681ae2c6c2a88d91e6c4feb7d30311d0ee0875babdb871322d9aa7d5e0c3bc50cae1c9809f3018961ac9b983a14857fe0d6ddf71506f592f9f6b465956d3ee2f4fb3cfa043b24b87e31514967c0c8d8d7c8256003d172e7393ee5a74b8113c53643b88a203cf30fb7be3f617696f3720711cf03f242269155162ba1a71644a2376b71eb50d98251c4e7a6ef953ac5d4e1d1ef41d146e31b82da436b41269b2521d56545d168ac1ee559a8fd3226a598fb1b383ba6bc61a14b2397e29352baa7c60b29daf8b3749e05d7d75703069411081350339727f283558d71ebf53b421e585e93c252f65338812b08ee74b7189576e44fb7f0d11d71eed724d41bbf373ca1d663955b7b7ef19198b5734909a582af72054848c366a9a519bafb8a532d28c6dc9ae2fa2aa98eaaab0d61eed5d888b4472a4c39f5128cda5f0ad11154a302ae70080e56c58d8dd94f7c2199694c91b1fdc087a9b78be41d4496a7895af00397bf5f1174a76eace20e6d243e7354b5ff570799297e9785522123c29884e97c1dcc303be462c7b6d6b1fe059d67dd90d0d3c410a54e155b24dfe25aaac5c1dff0f68c8401c02c76efc9bb9773876a845092443250cce94691d1244687ae5cea0f9fe1595c0d83fecbbf5febd6f7d18bf5b9b2b6ad4e606d67ae2c0a6ba994ecc35f1dc012fa21bb94d3f604f045124550e5b6b7710416087b19cfc7992e30376278ef39857414e8320499c958f7b8d20724cfa30d1e89fdbfbfb2fe132fbda5ebdc3712b96bdca5e9db036015ce27c44e960c2a78039f2fa9cff6e1663505e424d467352a734db0a2e0b61448e6c3428afac5094e7fb3d15c5c18763d18e68bb853b33084cd85c562fe2a989a0ca81c86e05b06972aca21491d64328621d3542a1b929624c6b703ab9294b9bb972396133c1f1f496332c7605099d092133ac127e0d0651f7f3568aacd520e56ff0a729c8d86ed7f78a18ae093edd0fc49fec84d34703cc8e6c1b12873988312918016946c9a35a3c8ec14203e617f4da8c798d01582134bebe3e8b629bf14baf518f9b5c170d5d3ba53910a10ae00dca87f5b0fe03a7b577b633a93e19323dcf68861b207a5acc69820caf616dca99de0b0c7d9a9dbd33dfee0faf482f11fb466650ab246157174b815a88547add371bd64f4ea6b5d1cef3a187a3ac09003e148e49f707ba4e365111860ea1901513cba013163a6a5e820bdff516c78bf8efd69c5407d5cb8db21b92788c21442eaa01bc459399dc89446b802591c30ca8799140c7c50907c1a2dbaafffab98bbab1d2ad387ab786f7630cefa20de4c7b576655410236c56b1078ebf8f658a3c0d64b7f08fd113631ef012ab95b2d7a280b8a58a1fa57358bc4db04a372c8484f13dc6a5dc1e510777214bb6eaebaa3bc6dc5babf00ad9b4c3fde76e7170b48fe93cda3b5ed09d16e43befefd436a6a790d2ee696422377fe27ffe0e2d978870929c809bd3c3185bba158eb9a2178a8ec139a1531dcc2b171d067cdf197919232e4216aa160a086b395f0016abbc74fd1a9a37dffbdf83f7e460bb86fe9a6f21a31ba32a9d137add40874811709db42932156c5a1270a056e654701fa1ef5cd9b000f710d3983639ee7097ab9893e955797968b1141a0ab7c22412fb4bf4aa2f425c8f1e38364b952eab9df825f62 +expected_shared_secret = 7a190640b245b6b4de7ac38fa6d4c50e935c0062c2089c926e4e8c31f233fbba + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 8b2755c2e64d1fd9b79f5a2c7072419b955ee69a6f453b862528bc78905bcbb44ed989b5e71b9126a6a920e67a074b2960d6a3ab50128fd9ce39137b03a66968616f134bc485770e87f01304a17c70d9adbd4159d67b888862b0b6052d9e8496084ba93d197766d10f6477679ca90fefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c398341a4810c6698351f7cc4fa59c2b0a86418145743d2b850cd47f32502e00d96b0a67cb3ababf62785b11a04de252813efa36bb83001ea322490a7dc5c54f32274b01fa71d40717ff917b81fc899e28adc5c4a0c41742c7d043195cbf8393a84206ca1e87032c553b68776f9153b4e2e0a445d2937fdca7539b8a2dc497a1f338802c073e891a3f834505a82a39f54544a49921e348934a028b7c54f11b26ed1a9cc2db7c58ecae2586168b120a2cf4487a6b34b8015e64816af26b864b7b30b19022d5038f89431056153dd03169a31a18c5f6649f6b638d4c249b712bb9563e4adab4f3e83c5bd05e2617b4530161b5264ee996abd5905e025820c7e1b1bc05188adc559fd0a0177473d816a166025bb4402d7e98b7f148ad42f72920d24e024a4d7a8a9dade92ae250bea3c519ab515fa2581b1f88c4caf62d59050e4ab1512c14b581d7c012645f89a0722ad2a1c2f2639b2b11051059549417d8f3ca8ae80fc241adede55999222b05b7b7101885cdc149be41cf9d2b9137e3bd0054ca89818e84811bc21944dd19bb2c1a54251992f2a51ba93a452c290272850225e9b2489324972cb6982c338f55192b4b87c2c91cc985ac9151c638aa741a476f25b3853afb4b106830d882a1e8a26b1b1305cd045e112a7e7a723ba9b801c48358e3004ba12b347d28a571f8a6c05b7c81fb3ef2e324b1819df549abfb871e25053d3e4676c9088d277688d9f85db7fba99fc62306c0414654509a086d0247aeb60a9924a2ba77f76d669c1880c302e67b1e1e638e4f74628ba73e0c565bf7766ea68206fc779f9c55b1b48c350dd095a5566fe1a611ee9507e729142b384306527c7928a7c09a74e7c03925e87d71c45896444522a63bb6b78615003d5cf37ca7e55e82888c17f171aeb440952328ebfb9eca10396b2044ce7275ee2709e917cee9425ea4c8a95b163876a2159907003355323d56b62e243cfdc714102a345af05f4e1052f9673ef57abd43e802744316642c26809a9f07805ead090a676204cfba52f4f04715e5788a08754d23b7c5db0d7d72ad20dab9ad776d52d1954a99407eabc44174237b127c4670aee6689100ab4e9e003a4157b69151431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb783115803170c1f8b2c84d0dbb801473084aa130d5c9c99eac4e00c2355a04556a26247a73b4a7121fd2cca08168d2399a1a45b685a921b9c0aa339390068348a3a8cb55653987c691e9c86cd67c385cd580892a01d160c9e86a65bcf63a50777b353b948e70061d03154e5ea518bc687a4a6b6c83372c0d16932accfcb13525457979218041af9ba2e012f82d79fc245356aa98b11f186fd2c538cb5159cf9562b5a5344cc1c44b3703a50850358c6ab4a5fcf830bcd2b1a0c932059f2c5a43b932e32a2fe9ab9f2f3b1ace7a3c1290cce509a5aba7d50a172fe51c65bb142b54ca6113baaacd44f3eb76aaff63a474a74614a0793cbbd7a1c822292bd75b2cd9d7b579fa995b9561a2ccccc1de89e861832522412753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dab154f96a4062751e79c4aed5a1c6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dfe021c47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc18a0b6591760576c819716560159908903a32111daa1339d8a8c66081894a52465f542b011bb607177d6af34d88ea80d7247ccbc269ad67a15df94f42a22bc1a525abc7480257694e9918597a8aabd1b537b163d6dca6dfb77fdba61949e3c15015b567fb88b509b43d4665abb834263a47c5a6007e2807b267aa50e8af44452b01a62b3034ba54ba910b018c629266e26514263820fcb3390dc117f9878c0ac4b3ff899d83d922184c42990088bcb03ba65993ca46c18bf1583f5599ad549801e934b8990fbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = pass +expected_ciphertext = c105196ffe91f8ab509666645cf70a83220648cdc8d4565d622dcaa2cfd6f10168a7c22d7cd28d5f65024947fe9f98d01f7dde433c8610c768c73bc584c35061c283085d68581e3270eb0171bd0b736649b079c2db7fd076bca7cfb6a186b88cdb9d9899abcf9a0bda849769a045686cc751e48cfa006baf9799c50c143fe643e66ecd041552d3d8518290b5a968604c1a9ce404b6d768be6496184de90241412ac4d284880d5360349fe12a33bc6ac9e697924a13eded8ff49c0d295d22f89d07a2ddfa2f0c7f83e8f59ed5573a747120be3ff44fa616eca090776245d10d6c8126b035247abce9b79c737f0119498acaa2b796f57e37bdcfb2885d8cd9681367d386c5ee8b0e6e8d9010b6fcdab4736282034d4bf3a0df5636fd541055444f69a84c593df54ef98daa5f6dc3a372139f5735d5cad090b5e79e2fff17509d3892dc339788d8fd3d408392f00031b117eca35d5be3173e053f52f25c649add017b2962f0551960cbd959453fe679de209e54593938390765cf0982abde7c6cfd2a32623aa534209d7a90f4170b64e78a8580ee1ca84e5b64115c7b9fcb294ab14561ec36f27d6a5cd87772e072637483ed4be1825de437e8cc321f2dea21a15d5adb668596ecc4832e3d5a5414583a2562aee3fc6ada088988d31b5b9e7534f6d4a9ae91125bce9a69db45209f7f76d0a21a659e35b839dacd367e9998eedfae7c2221b32a315872e1e4b00cedb20872e19edac6ea11f6202034fde554934a1a36378baf39b1c598e2666fcff60880a6993ea8214b0af7bfb08339eb643edc706dfd95d5366ee6fa8b02983e4c1afb0f434902ac07e50024c45b21c9d585a92ac046f928ea53588a54dde77de6859e571bc6869fcda8a2a5253c6332fa276ae247a72b7bf76cb459f6d7af5847be8ed0f26c3bfcdc48699db4b20d016bbd6ed416af20a82cc2277c97d65e27cfc6b0601eb5c29235902ac129eaa82f12d9cc2a6bd917e125cbe7957bffff7edde73bcb674dd6df6613bdb11c8139948c7fb10ca79e7c812d1e5a4ac7348c33e825096573ef00b63604ebbd007d3ad5b6b4477ccc992ab7fa53d6d62c2390ed9f836396e0816e2ab26fd308ea2adbd3b08456331d595fda53c7439210ea3b0f6ed5bb5ffdc258c1c30f4ed8e261b4edb9d2f0a94f9263b6caa34e48fea279484d0e88e392f1b7055d3eff14eed541f02c742be56bb9e7f3ffe8439ff997de9037a8d239b042bae74a3331b1ac2a8b7d463485f80fa051c6f4078c7d4835213e4210d6c41e401aa82fe2fb90378d4b975af6011cfc4c3210b24e7666f469fcec5bbeddd42ee79ec8ee731ec96acc9f45f72ac19559a3d30f0a2fcc786ae3c717f813ed5264a39d0bbd8d2fa0f438693a5a2805d3a86129bde0da616a66764fb9acf86587026fbd236ae438ef6da440524be4adab42527924721b6dd00a19c5c8c2fc42f2a5536d6e2b962a671c06b2559b9e2101497df277384b0785c87b5a8ccb08b8b8b732bcf7a9a88220a54684726f1680f51e710860eb2de2b9a6ed30b3299047a3be82b62a9267dfe9c535278bece20dec0783147ac65bd695796aceb61b9aea1f40d2592bcdb50b3ad97f3712566d6285be09411e36f1a4d7f10ed14b52e31da1d09f1cd3d1a2f9f3016440ec725b11f15c5b619a53267b50c04bfa8e3c5dca1cb9e326791d02f3a4f44aed832a2796dc5fad97a85b718f6a2fdde7ba7db3a9d2e4c5f6f6aa1c01ca3269e022eae8867e28bfc54947e05e9614bd0b41a54cff3f40aede9a3a497688ee5a08345f705e05ef0429c3fb272b0f3fc2b4e65dd3f4bcbf278730240e665ea696c119b38f8839a9e03d7aa70ad7dc382bbcd96f8325a8e52bec023888a0a99c0b11d4cd3305f09f1b4dd0efb552696c0240c5f7ee90571d01f460eac11e03ae3654d8745222911db99a222a2fde74ad001a699038451a832bd8dfc2bddd62891a685b519254b611bfc5e6100e70a02ae0382a45a8ab5a99e3046584655f45cae8fa2a0dcd66cdcd022e764fe318adec9d482057bb0fe373090bfb712c979662a2f23245e2d94ce730a0578e2f01c34cdebd096d0b83d583e52a934ce2c90d52f8371a2ce7e96eaca80e6fa7e7b41a28bbe2b109cdb70493698b493be344c961f82b74266096dc06df7e5c04fcf213bc9ef98d006325430318236ecb1b691963da4f0fcedc34c6 +expected_shared_secret = 5de71ca6710d2d588f53059a15e3a266eab4ed2230502b597f088014fbe9b659 + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = a7823bf24c9fed4588355033f5b22ace43a30478209a8965d587c91428b92fe034a1714535cc458c5146aa8b8c7b2c047ac76fb3d306174cc370873e25ec207dea86d8430a7ed130701c671697185c385dfe0410d91799ee546b4d6347ddc146947a9a5692c64445ac60a9259a7596ee8421eef78bac115dc95067e002aa89b814dfb1498ae7829517c8ab587afef52d4f4068eb21686e4416d93c51efc2ae6eb1cb1304228728769f08a4bb64893231c4be107a6de473afe6a1a3969b610a87fe2bbde35c31d1530b05aaae1afb69c07b6c6d4753b16588413aa588726f80cabafed3323f412abd2579096a44c30991eba87bb4d667bbab5e848a0bb178441aec4d00477310ec4e33677925985e1aa7b9965a103cf14fdb004a60406994e0a2fa5a5df0465cbb11a54298cfb109488564aea65b5eaef171716719916a4615d3ad708c8a825874b7cb671a5b61f5c3c9b9325ff964046cebc4991343b0eb199b9099f04c97e28aaaf0bacdeb4a007f956530c712ecd49017d73c8e498fab650608106174c7141a7373e27b3d11c2b06455b4f1c1471f8a0bc73c4299c47eadb75fa75210cd813798d84aea44a1303c95ec02cf4602a496a86ba364babeb7603195c7cad66d75b46d763094fb0b2760b048af1262954b5bf5833cbebc2ada183bc207290f094b6e9c2ba622914604aeba35237d17606d1b76330172f74a06821b07d8348979070b31ea32166568c261c91df097e41cc1ae4bcbd3e1525f179f8acb232bd056a5e18eca475f40e0cefea85d664bb87918339f407831c27da3ea42da34be7be4beed4c8a5ca805cb209d51a826d32c2125e204f5c87944372c3c1952d5f8b1873c1c6899b85748448116b3aa85156df381371763aab6c8b801b19ccaa1f87c4097c3c351c62ef1c697763915eec69389671081562e76701d805b2a62692b6f3a17fc163339f49edd205e65ac81fee42eb689726a960711e1b2ab7c15e385717946c27c86116b635873324bf2fa21a5c194492571ab5a7afa1427aed8245164a23f2518a4f4016bb9af0c14a16ab67675767d5a165948261f4df2bf1ad7cbd259cd31944cb7880920dcb227d62b17cba049388b340173221559f0b70baa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab32142888d6c070357b6e8500c43182240863b002bad191bc0e189c0a0f481afe268dd9abf93938d572cac462c710b67507a913936739e83407412db51ee778570692006a3399e12beed2c2bef5a43bf356a27d1222f267b2d6ca313315905b7550c7c150827c8eef97803159d86127029388fb3b733a6f1b83b638dc08778ae53bdb4751ede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e98952f410e774b520413a847046149e1a36339c8807cae45144180a2bb7445626f1b2bed9c0d9fdb5620450b69fbb972f6beccc9cd12591b22957f94f47ad7022acec4233cf86e25631b8e975eef2348776207b56acfcfc5b1e43c3e64591fa4129077c4028c7b5c54734945a7bc986a4f4719867f219978115aeaa06929812506a40426f43a899892de243da4e9940db29ccd421fde03c80c79ba1c1a1b163170abf21cc32130c19ba2c9f30d95b78d560344971ca8fc9cb899b082fa21aef5110b32dcb13a369364d44f3aea0c4e7c49f22cc0a3c07b0c134e9ca3bdff78283592050f8c99f0e467ed39cc32a9cff97cbebc90aff850a1b1a20837e02d516033ec9cb4337a1168e013587bc4db0a7a4cb52c3496c0371c1699520d05c68d81885920812af1841eeb8570783aa6cc0088d67ba2f7acb19370b1a9e2066528bf38830e9c72c3021b6e49640805979bbf662404236bfb74717659268d4129943120aeec2132c5a205b7b3a6b8bc6c944fbb035315c24666f1ae53451b52b9b850f15e0c71a086391741cba130d07b96faa70971a2d974bd6219a2339098356ba3b573a33b2837d3d186a26559b0d2325ab88ba9e0cccba484a14b2f73c54204c3111e846249a9cbbbeb8e7d1b448f353ff7a35d1600a6c8e87c06f653930bc1c3796fc0e8001a3cce3a37745382467f614af24c832757390cd0566f0c443c7c5539c72927ea1394005ce4b8bc223905639b1c7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = pass +expected_ciphertext = 929c5e294db4575a4c6c5ce5dad5b9280b0f44731782f874dff9c4df0c016422c8659d96f48bb8deb6cc2c083a6878004e4afb27400fc86b71e78ae91d14deea3bf125bd81f2e5490474119e3412d5da97b3cb6ee74e6a0665fc018145ddee19ccf3634855ca2992da96881d8cb457bfcd8050f6ac71849448d5a384e2ccde4e154cf6ffde159b34c6f9a04bf7f674787b3d561dd7a44493c5fc9b6968fef5e7cd4e39fcb6e325a491316469e1d8ceff045a6b1e750011b7b37498f46fe15bdb375681111a38a58155fd6a1ad37be5c58a5d33fee1d4f896a152097170abbdd766690792f3b8a5664e8ba9f271002fb4d59f005ae5a03853cd813ee3183f6ff32bb482d3615ea5af3314cacef1352f20e4416ae01b6f03627182736eec2e1a9cd092fc52b2d31df7bd8313e83b2c8a4e8e425841000083d83c8f07fc0a5f2a332deb838a31f1a1422e9083b690350410493e6964b69a01b1d8540eed1b590d7a63f29d32d3207b69e019aeb61bda5da0b6ed2fcd9791dbf2a8d6225e875870b60ef08047789b2586bd67a6974672c8e659c1f14b784d0458a599497ea78a9349096da0da59a66d9bdb798b4ba3f85c6536ffb1b1ff750ab24cc2d6c0d476f908671528fd1818d42fd172a110b668266c66b3ef2a9323ce5d26ab6b0981b1dd0f3a3f07a88c7ea2eca259d9fe4033af8134aebc6a0dc0e634c1728586d41eaf842bcc7ac403e57dccc5019535cb8e50e56e43902286cc58f10b83763c663c116f97e04ad0a67f873e05271a1554f4d10f7422bb4bdc5b1a0d49ad74bf1749683834ca7f4379dadfdac9a0a111fc908812988ecde205951a4a427f47b32fcf49fe9b6cdd14ea7428a463ecd4a22ba68cd05c8beb4480d4b7aa9a7eaf1f6aad0148b81a426269c8e8d1593a73bb6e802046987109dcc5af778f84744ebd3c7fce555f6b5d685cbc64d77c6518c19b5981cab55f81cdf2fe247303369794b15aa0b10e0d6b2c67e52c43725389776b8d666445da486e133b4131377cdf60cb4a7813b4f45f53bb576b9a35d56ab8587243b2c128796908e60beeff98cc0e10845a8d5311876a828d6862ade7087861b223e2bcf6796e2d19dfc5a6441b99eb7f267052e91282488637de81b3c033c1f5ecde939048f45c178d191c3dbd8e9e7ad0d597816a8bfd63f80971fb7f8cf77556d599db8fb02426dcbd3d982977bf7a4e22598c83880a45b2aa72fd8047d2c765d03efec2a09103688c8208ad9df23ebaf584e30c9f0695d76adeccd0ecf6058bf1bfb812e44e7f5d50851fecaaa0cd9a9321079d07668563fd85d6eb0556671723280944b003739e204f51f0c07ffaaf7af28dc9fa28076b15f5092a38762504710ddc78139bda1128541d2ceb29ce4a58a7176c624180dfbf257fc7cc685e35060dd1ddccd85a16caae2528a3bce60297fe68472544d1df6e6eb1453dbf0fbcb3449db5da8791761d8daae8fa4b0b82c695c11c8d57141b8453da367af090aa242afbe8fa1696db5ae73286eb5c72a5164237bb48a081a709437f4900c944d8655acffcb7554b151a7bfd5f430ab57c83b4954593b52ab8cb8affc466316de89aaaf6bc54729f5e6d6de1745325af0bf392e77988121a7a695489775bf8db0a4268612262ed68d8dba026c41a00d359288895b24b71d663ed815aaebb3ff62329a6973d3f7f79dc7ada4349c9308bfd91c9192545e05daca09454821bcbb2769adc6dc09526e9499f97d944126a9dc6a1a20f01599dcd2387bb130607bb3e84558ee7d781e4b591ae83af6ede35e91ab07e05dd3c1973d522399aa42a9034deb5de2b156e0b7aed374cf47a526d9e8751544f15564834f165d10dc24e0f56323ab373df8f021934dbe9838b8b55078823461f74e9ec52a3e38c31e578c84a5f21add911b18dabfcb060656d2da5e124511786616a67655f98d6f09394140928c0aca59b798af0528c046bcf21928f910c688adbff35d80c59d97c7cb352ea823e922f00eabb309d711b3b143afafd64fb600a5de7a0958b3e590ffb6c20aea00cbbe2e52cea27fa5d34a63012dfea9b38d1ae6585b2cfe3a63c9161793a12513293a3c7985e33c4081d6a4e740f501b3dfd54a86ff0498f0ea8ffa3be90e86f21d93f31706a794126d9b2b46231bb26e1102e8b6fa31f529cb23e6d131f0dea516e231e2d669562843b87e3563e5eff17 +expected_shared_secret = 42ffbb3ae86b744b00f36a01f9cb34e8a08916f455c9ea0e5e6ce81bb5042cae + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 6bb90f94c8b62859c31e146647948785b225ce860769fc51df7c4310984254f927b1c200834876b23a635869c90df39bbe36094bf6b4835750a6f3788bbb7a3140a7f85b1c5cc8bdb386a0f15297ca9c6462b21df7c11845788c130313c642ba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fc913ef440addb37107e3032476aadb55cc0cd93e317a8ce2439f2464278884915c54b97e882dc44817488994c0109adad13c5102847bec7730a57227158c4ad1b51afb66d5c01bb6d2cbd1a7083fa6b049912f736824ad40a1acb22f2cfc9c3d145545bb6494d0159c40c12bc84e8d22bb8e1a76c237020949698175b21410cd4c7bb567c52b08fa6253a50e4f1573abb18f74abb9837cce85545f8992c9cfab66f800525841948b18b7ef3a2b0961c4c7e8902acaccfc865b45a5209fd5a4db705f94122fc69196e3b56139173b32ec9063c4151b2819bf9c7b5d7626b01cc420c86d1070428d4a774177035269a46ada8ec0e02230fc6b066c57dbb875a8f294e66166f3d7b95edc3ab66b15d7b55dac16182c13b371d82c42b85313c65da7eba0920914acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c284f1589af30d00dd6893e70d571700b9a07baa6083b2c50ec4eb95e2236402f7b50c87a9305a8b5eb25664d74d4337af268b48bd1855574405ea6237bc057e191cc6743742dd5a66373b110d380bf7c03039296f56ca700ae07d1a826965d55d86c19902762e75f10cef33664f099f8440634b2299a474bb8af328a3e011bca75db90b90c52c1699c1bdcec31565e411fd1c6ad2d08eba8c50b66a57cf10a98e2335327b011a4c3e11f58415b6c38f1821a69671fc2481920c896b389cc5783c5fd3b7d974ce03375142815e86e13ed4e052b1e009a25a2097c02f3eb337c3c85551ba14e1c22036916cb993612c809bec807da4e25cd8094c36720d376982650a986396504893bb0d82389886942ed1aab5bacf3957aa8d191dc56c4049a0714d89bc3af9680ee602e154b5e1c35f1c0440eeb0ccab22103945623fc201939aa71f99ba8c409bff83276f84879e590d9a448e1f052188285de9668260282e8ecc630c15ab164271ace0c954f13944fa9f4eb3a848f11ce7f0a439ba07a469720d4506ecf6cfa241136b469c12e48f137601f39a5adacc54b094127d2c27fe38aa461c76003b9ecdcccaaa2b16d1e9a164122a0b1a1fb751bfefab4a1640a792d2381a74aae77084a4e3cc33275eaa595733fc4a99d43be88803244b449ac71da53b2cf30043c929811c9a558a165da241afaa8c45b07c27876c8ff77b721b21022c958323b41ffb606c656519875b8bc6e897854c08ec10611b954c693568070528824b509f83a3e6c505b6e3203afa863bca408403c0ae86a374c1613917bc06b94dda73a8e0c98cf54a60cea727cf1334b324343b2c47df4a843e467989e4160e1611c1558928717d794290cc3911eb70200f51152d04871ca46d2753836791ba98aaabf697adc925a827cb7f3ad01069f5748778b5946c78ef9688e16a5326577ad5a5773db939d2631b04545c530c9b99141f4d213158d213163bca141c7949f24958b9aa67089488a732189ca923301143a1728a6707a6e8aa5bfc4d05b6cd1971290114542386231cf04c2c80cb28e50026c66763a570d173612f142ef1ebc6cc9a82f7fc10b7104b7ed6b30c95c5a63a5e1e52450c1c26ca11613b2b3ceed10968e85c0a9539c28242f1b9a083c0109036c6aa9349f201648ef14d67094af9715422885c7d69627702943bf0955d90496dbb0c0f2b3137b89c62903af74b2783b11748bb6df46403b69701e1d9a1e8a63f01cb969fe9ce00d7b539159e75372dff7a85ba660aa8471ade291fc782403f16bc2bf1c4d1a138a0160cf44246fcea7666276318940624a32b4af5b15f8b4da5a05557bc819db8884825b8c2770d6636a16a296daec0752e961cc4d11d61826d883a61f74203006a83380a0f9e5280fc1b831567136d178a906363bb801411e069b461027a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a5401916b35e996e1336cf13249d0cc33ecf610f9811c27aab55c52944298c3a13158c38501813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = pass +expected_ciphertext = 32321e07f03c470e7f512459b81f4f73ee87272c832c9d6c1aa1bb4f1ee06e7bb26edffbdd4a2895892183cd155487b1a3b8da76c38def6dff27c8d28f5c6c59e4c8ccebe41b55766b1f7cbc269e029c11036263536a0132d116d3d8868ece468e6eea88a30abcf98e5bf9b0a933264b79265de1f986cff311956bcc2b7c4288239c14a7ab629dfd754318159c49380ad43faa6fc26501612ab3d5403291d312de1e183909754bb0bd4fb3c1905e2fdcc6ab9f05b984cd093605e7fa082836a7cef37fd745dba9c2d1b381a139d31e5ef4fa2d19d0a37b732cf5b2d40104f37e35f57fda0763df9ac35b81ccdd6b5ae33c85e70be21935adc0e84e46bbcb1f1c06ec60e2ef862f442cf401d57453d3052153c917bedbffe7c00d82e8f502b22e2eac53b97742f9f03f0157e3b00a997bfe577fc58db3b84114ae7f29e2148661cd3136043a7a194953f45a7735685643d1d4e54373a2c9146db06ecb8db86e210ec22218bb8e70634f558720d6299de1f5b74b0935c97d9b5bcad726964766a42a18b6918bd9dbb290e65f28298b3d37c46e58239263bfc8558f4949d882d91ec4e553235bf18cb8c056db5565b7aa4e7e2c3b8267188fb5f3ae0c5e7b68494a17a17f51c7e4e7153954fd77067021ba82eeac97e54d5398ed4a0462118b9ff429e1fb3ea12f915b4105c2c089e6db8111e5acb42942ca67687748e24f1b4460dfa8457e0346fc54d5bfddae4e2dceb761d1bf33787d37c25ffd5d5c21338f388f5676560636d30e71da73fd7595843cb1d6e3b117e471efad1da518b4bb02feddcaff136cda7b640e259c8d9cf915f53e3d63643884d85daf87a5956ba7e3cf5b56588aa16dea2a1aa839deb8e1f10b404721f29f3163cdcd68f599ce325906d3d1f5bfbdd0e7b251faa8a3eb64396570bdb58d6f7d7a2129c0f3e45b3d876b3fde7a70dfe5b0b80f75c03f4f710e37f820937f8c2ca9ecc0f0b0b4256d754e24a5d1c544fde6a22a0b2eb69eab48808d940c09fedb315dfaa7a2f476df90b952bc8e799a2952168fc704b1e3603e5f84702d81a0bdf87695f971cb7629df72dae408f95635c1910314d9f973f52ab00c190e03e9a11cb93456186c41fc56ffc6e8005476a4c9377a08f406b0b116250ff4b29006ecea251e7b52d49a51dab8709267bdcd6241f487fc4ea2a75388d4ac15543ba1dcf99675dd03b5dd8ae49e28ae1b200b277e2075e169baae3217c62a2c8579f9588caf53eba32c62351dae4d963a750f8f3882dd97eaa7115d802c197a24232efb77eb499d25ccda398cf7111c59e137cb0125b2799ea89f60b6eb55acd3cd2dc95ff5eabf114fcde7b734aaaba78f4a8b6db55cb97dfbdba70fa9df336563406f0866177b71c411d96303a6176ed0387a9744de6c1e34f67682a9ee2bf0c619b79b02db5129f31afd2a09a74c4fee27874171517e4a33afdd8810e72cac1915c7a701236059b9d78588ffc27ad078c9aedcb6872518c5aa0538e9751219bddd322ad0e5586d16765de15c19a2d3c56304085b390932c8e75d1f24aeffb7ecee790c87047010fce2ed157366634324ac2579617f478715929afb1696ba2e965fc7a19fe956cf5a7faf163bfb662533a6f1dbb2d3a81259155349b8c7b861c6771210dfe361c2543e7380e4b16250099651175152c86d6e3d697dfb92d6d4654ee0e5dce5f835d3d9881fcd85313f431d3cf6e13a615371bddeb17abcec3e44952405a8150ade995597dfd190c8ace3d580fc01d928e584ad40f41da93e7e583c70f69f9adddec54a9fd7d03177632f7cc818bbbdcd048f7937393d159ae0d55ed3226c94a7fcdaf71c2cef76772fa3f0874081f4b9ac27e3a9da00968814f9c38407a77b03778731a69468ccb83fa20c0458a4fc4951282e6d5da2b9134064547ff41546e7db0bc81fe24e1af6e4bc4720636f6c956bf96bea23b2627ad7f09f3285b9d93111c381ba9ee649c503ba794105d8471e9340218c55bf16c63b845cb6501050ac0eceb2ffe24f725e6a04d5a3acb0e0d98d6256a769762215441875e03fb7e09d46cde7bcb05c2d7faffae7fb6749e480c17f68638c3aedf8573c284a0ef9701402dc956ee859f5aa2fb704d234c6294c14b7bb98f8d5b1b202a898b245fe9e9339ee1418146f2ddd5436f707ff461304910ac55364729dc52218bdfca3dd084b1435a341a464 +expected_shared_secret = 90ca5a797490eb35c3cc24af19fca6dc71d41aa58d68e0061c1bdb8481e691d7 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = 9532712120555db81fdb599de13109277a48d20b0b16db7c6fa73622acc63ab1036c9c07a48c73dcc4111e10c919d09b3a48b96be05e56d809efb66ea3bc97fc360b85533c4ad1a9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6582274b7559be1362ddcb91e5c857b0e836349d4023d461b1b24cc873c56e6404149026cdeea16affb5fd715766617b9a5058776b74b72075e25002131baa50ca093bfc909b6102e8e5ba2c748bdc5ebca2be715b2800abe643ed542a8f4c055a0c7122854af8460016ca079bb701db46b2b17d0013dba7d24685fb46966ce53b3842cc66c8baca0934efad619459888945759b3842e26a914c835bec4410fabd4c98350717ffc143b2ccac4e72b64d195fe1147fac6171ba8b213eb5724039d889620c70a55ff0145caa543bbba3f732ccae4b0846200ae7ac6c84396224474568c058fd4785347f077da03acf744005ac1cc02f93f2130386aa2b62275722e11589c625044335779d8bae917a632652536337db7c78272241b4710210cc7954b6622bfe1653f4788450900d3dc9bcad010f9429615d24c9a4bc80a2c078f5b6e3c6847af5b0791c27fc99950e77676aea63413a3b259051cf6a83f0f9c5952462ab315af64b978bc4154be10702d5b266ac524ca2b5570199ca7ec91064c0247b08e01a8ae7f194db11b88d584237b507e44b411d5c5112dd22c7acc8d6f3513cc8caa63342284e6bbb16b2f63b9acc9cab050a19fecb758ec455414992aec45bd453639564a0c2bd164c1604d035380b0c2350f530770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe542054094a450a8c9f7a686b7565a3036ba7126288ad157bdf172c5e772ce052689d2495d00159a920b68a86fc905364c20027f90171845347366053d8c718a444a1e60133fb954adb3a47a7242b8100a8f9784181a4e7e479ced14190a282feb98008c09ae2b124a8743a4230910dd612cc75bc0068a4d866ca871a48b071cced3336d5c01ca3b819fdb2c22acb71b2fc2cf61c95b6cc164cab078472658e5d19eeceb823a373b4097b4e83b0d86e9a50488c1a35418c497250bc90aadab70ad35a16facac83093570399e8f615933f48e7fe8c04e517736732d6792c59e400a228a7cf4896af6c6c4d2f3acf279c861c83100b2868cfb42bc75052b26b6920591c78aab2de99c2ac0971dc90c19b6072f388ffe054166d95a785b8eeb141a9eb0482ee6b57c896d8805a33756005978a98f3817ae53b09ab4bad0011218382269f062b9895697514f9ad872a49392166c72c380a86c711d1f00c9641a6a03083a3755a482ab70cc213cf6f1bf7699164998a96a8258e819652ecb01f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341a62631f0410bdc0fda9ba4710a21c8934d6132ac21bb4a9292b16f787dfc58ace7d69efaa67c3a5405b98a9a07b276bedb636c18a668a1c36acb7170ac82253a85d1524ed79bbef4f046649b9f6a31b924196c6f72b12f108b6d95af9b373e34489155da84b8a810cf005caffb8b28504739590fd6b2a5247a5139b39236a2a496a93717854b162584bc57044f510656906ddae771bc029a0473a481eb2bb95397fb903a36a2042a4327c8c54bea769c419cc5efb83e84692513936f8f8775a1b114c13a4318d522194b8f1f7b05a8408348b3ca877b0a59f34dda1169a8c12d716ab9f558ace0b72750c1b4b9f11be405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbd407d36457c291b4027a6ebed8003658619fc4cd617898e8ca2e77a505cbc70f20aace50f301bc16c398d30473619326e261e2713375a68d83cc719a381284216d1cd011445010a2d24379b8024c30ad70841eba93cb65621260f41125c8cc03fa2894e84bdcb06b4120371a610ade828beee4b3495b4e97e25ed28bbd50223ef0c6b5a6c53470d22abd74c26af08cd44ca194815bed9c58a1775cd0431b41553454cc892088bbaa51b26d37c25a1000a7f8c54abcb1f5c0c3c61c7f6d36bc45320a886280fe2ccc24c704a376294ac15d70f1a300a8ab1dac505f3b2281439b3f93c4d4f62f5883bc00d9589f5a89e3413f425248a8f7c011f616d65b857d2353c0d28bc574c1f2522c2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = pass +expected_ciphertext = 8fadae443a93690d09a1783148006e46cbc537e90bc4201d319101de05c33bd3a917a7442f35b4f1c56acb4dd73dbd6be0d8a5cd47f0017a60eba182642e661b03bd988febc9ef27a96ebc1dda94853649786fa3707507154d4c3d6f07a0c0d059d0eb18a55467deb1f0a1ef776053b9856e7e4d6a432ee2b9717422445175c17aa576d0c3b26e715bfc654ea33835ed61fcc7e25f39e2009eab6dee957ca0f953141d1ccc9f6e887b512dee3f289139947d19fb3c035fcbe639a9ae1dda60ca47f45b033ac4dca01480654769e903771983322b756be853467cdb7ff2d8014fccee50e588af4e7cb79776242d036776b18df0ada02884d034e5af3829bf58eda38c280927c29e030dce8a4d8505205c059f9c054453d918685254ba0063c883b49c9623477e4b3ec0de7669b20b8357d8d1f6dc48479bbc1c35a661bdffe1f0bf6cf7e1abb5c78714db3bdb5d86ffd20c33806be106301eb53144a6ca2523a13997dc60e2cbc751acc36dc58b2a4cef33c5230e2d0a05b23d0705cfe0c4e638e7856887d866772abdc9ffe8950cc5a41365dc88085a9a9e51e340c8e4fa8388123e7442f17f9a647c40c90f7438026cc0fc18fa97bae1bb63fe49d745e1c219ae9ddde737a543afc8e38559ba8d65846041030b38e8a3b427b60fba15d87e15f477b355d5326d87066607ebeaa701c9a8d97884d68495211042e12d8cf7695b5c9baf136b064471c20602566257abdb5c77891bfd2e8f473f88eb8b5db0a70b9c4d338971cda283d50fa8dc0683068bdeccee3e0563b2c270e4d4e5bebe41c1fe84d6f8cc7673de8c70c2b18a4890be8255dfffa5866a5a039b38f2aa01984cd87f245a18fa16658b2efde81014e08a1452003ee5ce7530f61c0289c837315e593f64d75665c0c0a73d292a9efa16ceaec82854a58c9daa439b1ebc9681324a7e20ca86926236976a1ba362d33f7487a4f3d468f6b3f80e2ab541102f1368ad1da3a16fb3cc636df1cffad9ec70719cc395a7159542d64b7725a982ac5240b054ace33f4394dfd35480aa9ff5c8120407764ce390f0e8f8cb77ec0176f4ef6c9e64f2906d4841ce8d46192421778a3181f723722d6dbbf232e1ac9f2fbfb38a8169811782e267ee85f9b6cbe78ee9f75c224866fb318f271884cf1496724dde18bce61fb941c8d3fb21b160779671b0f14cad845aabe334c8ec30852cdd05d172d12a8d86d8e33c6067af227bbb3512de73145a1dc0d0e81a330131aec815f842233fc332605eb5576ca1b77a93bf02b0e94546bf7e887e996b1fc1522a8741f30d4d5456bb3d3de2efcd1648c41da7d73bfdea433fa60b2fb95084b1ef23c750416d5fdf3452b68eded81b4ecc636e9f4a973b0777e8fe15a62ca6399a41e9e92508297ac0c4d9be7e904481da8c1981f44322bcc987cc68703c27948badd76a5313ce40816612bc0f6c51399d810b62faaead5eebc32d9c9598a91efb8484a2ba009361de1318cb0f02796e827975cf0fe7137de63c2746c05e1d01fe2403b6fddb9615a9be91245a416532ce48f059a3053fcb6b9b6700a5f3ad6d6b88101eab3ab2c5d38250ed818cab52d152d4786502a48ca27269979f375948f0b1ab51fb6d9eb743364c683d3cf6af6423de3b3dc22fd45e2e561e122aa7ad2af8f65f5ce7d6b2877135e05a8eb233fdf6d2dde8430a59bb7665013ceca35121ce7015ecdc747b3a89fb60ebf7c05c587dea7c476e9295721ec45733605d6c94ea1ce7fa8e90dab6f8ab5457c90ee8afcdf25d901ebb34223c5db40e7768fcfdb3e85d3abda964b474bb432f0afef11c2ba80b381c6d6c009afad4b1601058617f0b24e76f6e3c36424f8c7f96fb9aaa80213e05caf90dba0e7c5a2361c1a54ab20adb6b5dcd8631c6b7540cb64fafa0ceeef7e4d8dd799aeea9225fdcfdd920360957c193fe1191e5f5901f04c7829bc50f35d8c5e2072c85d96b9a94605d7a1cd392a424054921fe9b0004dca6ae83214e3e4db55f839221b78cddc1eb8d5f5a2702cf6923f886850838a2f5e2fcf2a0afffc11cb42abcfb62baa4e42a47cf2290f824044affa377e0c2a58e325127fc2d0be21ad503b2efa5acd18856be477b62814efc047797fe15c6324d3b7afbff35062a8207f9de600ee3393bebf451a9dcd9eb51455ee5eb43bd1ad34ca52a7e63c9b43d3bc144906ca33992c33b18a07f +expected_shared_secret = bd58345e9e19483cde256be650975b954e167bd8b0a9036a95c98ebf037e87ec + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = 3c614fd2510dbcdcade2f57004cc995db29139a713ec106607f815db318f03d2caf4a294caaccf34914106d463fe118bd0b65021f086f1f9a8f34a42e197525859767d89b0eb29cf54a93e76f13bf43344bab7578ce167796976e5c7a2626b76ca2222cb358904386a5485c67fd58f7027543185c71ba82cdeb93b619455cef931560452d7650b25617c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5960a08a6d8992a23aa5840c97adf727e698c990684d0c19ac71bb816ae30e71351c3300b2edc22601b6bb7545a87869b9712997aa5c3ce6080afa8333e6159c1de61333f4742e5c49e887a8a4ccae2df6c7e218a509124d151a711da99a11d7b5841752c498521c3c4699113dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b592327d0242ac68ba6d01369257c56427928aa5b0534200ff8a4a7263f9f955598a0980ee67337442df706360faa20dd6941195036831186dde104c5e6cd79a84afd6917c1122070ac6cfb120c7f22276afb4d51f52d0ef2bd4322164f938f66269703ca1db984bcbe337c710142d024ac0d7502579b1b804bcaa5fb551274ca547301fe6597cdb0754ba6af7d74bca789c6a7460ab599cb14825fffe28683267001e32ec6f7802826c3d5091f8c520ca52c51e1e2b649222bffe45d9d373f8224b9e3e973a852a0d6acafd22561aa1376e9842ab292a61c21308e209d3ea353d77a8d835a46e9315ee19bbafec09ed462269de56b36f6791f771922b49a51b3870ad0a0a2f3aa0122ab02648ece97c96ed24b9e99b6ac2c964cf356e4a39c21d0274eec6fcc8893e7cb425c68c8e99a89d22647a5522ffcbc46184ac181d556616503aefbad90966d2806b6bf26903b18b1bf5a89167a10d47cb4a6f101fb09473710559f39b3046bc7a55331e8da418bb34089793c2a7606112011e89318267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd85f815c9c15b36077e9971b4ecf7546c4486ab074e511b729ecc835c175b8304038550aec0c6c22eb76f866444859293d21b4743e0202a3b6db7d2342585a5c098ca66822f86f01a6a9c080b414144220c44054801c36199432870f8b39b08831c8623972b1ae3442d0fe409b47a5c22e67738008a71ecbb8016ce110794b1d313460650ceebaccaa637f9625429538dd1e00ae8930211063f3265ce4b7c6ece835faba9236cb228ed003cb22cc8b3c5811bd9c276944d929c5c67b26b8648be93a89396c2949e26866ed4121c3849bc6c15adf8942fd4ce8f12b5dd83cea1322ed4c0bd2bf9b591fb01a7dc49387c04e7c1416abbaadc2c183072ca13c31f8e964c2a9b56912571fbc07878584f7926a9cf13c0f4c114c59b1b44a94014c2963c596471f7771cd383c235aec594b61eeb17266a5ebbc4828805169d1a2e468448e73a1e3c919ce3f738d2e1242c0895b59c27e12cbeb10c591a54108a7b730d2b902185b9a8da9d2ae01807466c456c4eefab336c13c6e137b6cce922b1113e1cc862c8883eb69acb0667a68fc58fc5d6584af926b25159f4700c110c43bcdac03714714ad4c07afc4d54200cf0184e5e8a6e5df1ae6d13c9f9401ce38c6144d3b87dea304625cb8aaa6ea0695fbbb775c6d0b7f79a6fdc4c53c9ab072d027da097a0d69ac77a9cab23941aa160bf36d95b10167364a0c866e44be2930199a00972936275cb9f3340812d70968a95428b3000b21c68a237961b99a2c7f62c9988675f01b1604910b0d8942b21c49e676532603ddebc39876c8479603f9360a9538679c4a83dc1c33947b5c01a5c659d30187db308bd999d68e30c79e40b631bcb8725b72a414e3be0300e4c7a30f56abeb9588fe0292dfc23c4c994ca20726cebcce5942a3b376bda76a965179f56e66a2bf94ca35090af041607c18545472db1e71af96570538796418737b048859e676480727e71e3534510998402ad13d54284b76d6eb04715934fa6f05cadd2a6cd6683d981cb5f6a884d04ccb008657f990545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdb304558423f4a47961e230c9091f0519c15de10275da4757d40edf70ce729a5986724e8701101c208e4e3bcd4341098d8b07708a2c81eb6044b82ca3868a4752cf42f2596c7ba678723931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = pass +expected_ciphertext = 39325b915a27e67b4e189cd75ab85f09f90259a816b188c86bb83ea12072787ce1d920bf265a004055f378b980baca30a3e3d5583cfee57837793a58dec88478f9be1884c5b820bdf63511dec3ea3f502463230f410f3da014d1f1b2074573c4a981ce5d1407ef42efe250464e60992e361b1d8aa52a7ac920a43092ea68645bd7a859c15c5da7411fa82aac79b94eb0c7b0d20cb7d3457522165f2cc4c7e3702723b74b683851a7b22a2197b49993065bde97775240dae26f2c128bb9795312fe9c7b912521168cf6eb620aee6f4ccfaca57ca71726a20126cd8df821194242fb044ffb32c2ebfcee78401386ada4f9339d504d26c536d388c981537569056fb4d54742228e5363439656ba7f5f5b7a949ae60a73891d98b0c18b5b9d265504f7ffcd4b4443c7b40a927ed0a8db13ba7dc6a1f6f65d95f2930652f9b8e03bb81deb4205e2633d4d38073397574fcaf47132a9dc686246433867968fc3c0564f590e7becf5e77ac4feca88b73bb55fc1c7b88fe0f3cfaac080ea06ff8a58d52b7ab22c344ebd3de5690ac58a12b17afe32ee420241486b70a4941004a4122906d7644e3f1da0f5b2c0cf94a8ae411ca0a49431d3d4a9e0af53ba7d899d6084cbe3087bff51886232cbc64b184707fc968f1e0f412057f5c35c18a4edf3d8c374256c154019203bc8d0191393b216c08143ec31d236c6c8cc599edfe6c3280dab9e46e5bd87f5d39a1dd3c153050fd8f43605cfa0a13d62eda8e70abff019be852f7e179d78832997a39c5f9d64d15387ed5df9d2744703860deac9d71edd8b0557c77cd40566e3a4d750c1e81cef0d6605c61159e02583a103140dd5d1ed28e8b5195499b283c4fefeb59658b176245b6308c21c64703cf5125283b5062557ee3edce4b42fc47e1e5d502682160b02d4010b4d731c15300eb78caa8c59bc7479339450647280b6414a812478f8309637135a5e95147f113f57701c8882f389164c748bfb561d0e088efdd7402748aa56c8faae61cf0c73c2a0ba7a2c9cc91e190fab3c45c1e414cd5f3a67626cc1e217422ea31f374e26cf5f38e003777bcd85d699ec6072b74c796bba303e72a996830e08503cdc6c572d6e756ebdf9c75a6dc09446d104a186e2c1de5d123a4931d13f90a9d7947979ea2087c5bfa83af27057cf2d28c932ee2ef4cac3cb330cfcfd9467ec056f4a9cf1bd376ee99ff213709139bb3694505452247cba750e70cf0783f51485e9596778907800928baff28fe3d7a078f0acdaa2cb531568ff4ea55aede535d6655eada18dba94da7ac9f3dda16a4e26780bb69ef34322b763d96cfb4366e68effd984ddd2bcf88211fa25525e94dfc7340476a4a95d356984d58f7e909072068fbb955495b8a749a9da1d770c4864156c24c54a10bb95839bd990405a477314459abeee6880bb30e8ab6f7eac5e0c074d053af6746277eb9aeebdde930e39a91673e62d85b21f64816127435de3bb02571788fdd575b7398961d2bb30a7625695fe3ed468a78aaf58e9eb841739b1e4d557d9895753acc6fc18c1ddb13ed1497a2f9da1a7bffa8ede51036cd094d720604db03a58c85af1ab9c078e92d8eedc226f4e423554147fa6602e48d0e4698cd0fa6bc45113bd7fe8848345a4e6d0bfb0124af9efc748bed49a34455c6b4b18d02dd2e719e486c20d7f183629c4814d01eebb337deb5debcdf058ea815ab556fd478f2d44f099c9a66b043b00795639f92782ca1de0c4da31b2a3ddfb1b20dec2333ff9d2722f88d7aba5de0c6414fd3e6f9612d26bbb9e70ee8dda869d11e253ba7def491c60824217bcf6ae74b9db4fe986b9aca5e66d8e4252500728dc55d34e551ec3f3aed46813c7785674b56da68ead15d9b0d353fe167e5665f4d7b331f9a535718c3f15f31d647564669bfa8735d88ba234bbcf79e048f1edfc0dca2fb5a6860293d4497ac5409fab8c026ce8ac1f77e6235a20fc910d9ef5a99a2e115807ad70af2d50eda409475813531b5464966bfef31e145dfd341693e7bf2ad51d6d1c492b67bba82b120bae325003434d01b23ceaead993823d4032b6bfe8e6134480063b48483cbd8a80abb90d7f073128f9742a4a4762c8247325c7dbfd96d8f952f8db139212c15ae1525a8611289cb8875a4f06b626def6eca35956547a7e4b097781d6c041c7e232a83da13121f6ba642e038553c986fbe6 +expected_shared_secret = 53d22dbfb623f5282ac68ff607b69b9ce559ec3b70aae668c684d90dcbbca13d + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = a2685786391d97d3b6fec35d89553e3dc1289051a39501a814cc5efe04bda7d7ae7531ae70706277f71055ac32fa25abd26ac6ea6975d5a91618476d62e311a9fa3db53582462467b19a7a7f025a3b20a3b5e183eff249c855bdb3719d5934c3be5b64576b71ce525bb2874641a09c036bcab46684e6280b5806b74c4192d0a55a54a6329ee7715c88ac3f1112bf49b7cd642553b152a45366fc925a4f34c2f97646c51511c0c9899161914654c052a06c6311022023954c28bbcc22b4641bc327aa37f494383639aa3f8a4153127f28ba56837a198b604ddac05f82cb4c11834aa19637804c6643125c9465ac03516334679f36175b35c0c4da90797e7a0cc36173eb07b8c541ab501151d9331666267adfa60315305be5345c46f628746025e7959dbefa1fc0593ac94ace87fb515a03b00bc84b66507ed2c6ae4d931fd28186c396582a56a63cc35af5ea02e980ae2dd21badb02699d69e857334b1e96a5086bddd7152bbfb2c49a411085a94321a43e1491f0f0067b06688a5ab8d0aa17a9448004f25c1c5322b8d7b6563977fad0c70e7bb961ce84cc685aed34b25f0d30ec53a7a5ed943f6ea3dfc917b01985c609c995f765baa071b3749c89346805550ba19d958c535627e606b2f0c2706632fa466504c267dc7805e60a0680ecc158d6b4f75ebaa030292ed12cceab06d5c878cddca919050cc386386f5c8b3679b254959a06ebba5520646e65250ce8b7cca03227d1b43f49c9e9297269eeb64409712fb868cc47b406d9425868b6a304aa46e472acb0197a071ab9d1622861916cf31afc12466a4022a3a635ec89433635bb0afe2c5f73670ba532714803b1ed473608c5e00c1ad9fc90c91281d5e081692d85dbff0acaf5579e2b1b6c5c1b61c3579cd13a7c8011cf5c19709366bc9676cbb8b2271c784672200e6a0254bfcc9b6387d42993e275ab2da100301b11f7e4881cc5774d2f849e3d3ce63639ccf303a7f7914287079c6066525a4870b974d3da72a9290b96c6846eabbcbac2b730849a9b014100adb9c66d0b5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebbb136907a02eb5a351c94607fda4eb44458c9cb8b50da190e307fcd63885463523086036c5655e8e2621d4516a39084fa5b4f9744a921f497eee3a46eda05a4f1481ac5b4b819a66753b5b75a95640b0cfa07aa8a2033a8f51cc526cd1be8cee5677a78f18af9608da3a565bbe1a79c58691a45ade1aac936f15eb238bb4879af7da68ce2a106031a322c198527b94984a16d9b4a55bcb59e9eb4b2068182cc9b17a8cb2b8a776206b59258a2c9a19243c9925fb5d135604712baf09e2cdcbc6ed11fdd530d83a901f06c166130b912a53c075178195662d9212e4219c63271485ffcc9aaa6222c9aa2c4e64f5d686bd4874aadb456ed086ebdf151eea4be6bf57e2cca56edb04c0e68aa4deb1580d005d9da4fc1943c85f75208d0ba3b517f89a82a2fd8bb96ac07836391b2dc3b6b0533f0d91e170986cd245fa2a90d6a345679377b767086a1173dea82969fe3bfaa643af8f98b97a8432afa1a8c748ee7055630812bd2d80be782a726743627e707f7ba069931c9929b37a9b0b04bc23405e5b890700dbc419bbc635c12c390e0a8618ea01f2abc84eccca4b9f576664237355a40b7e931195b606c6759848c33a002b74b4706266aa93fdc2054d95e7ec30f1ef53f4730af8a31a757a55a9fc69765f67ce7ac0413dbbb12980028baa2ab2a378a55a283a6c5b73837f8462259c2aeaeb36c7be5447ea22a85a561e2477742c61dafebc969ea66ff992455db36b6029d863a8b896057251b8adc659f294707cc643a91f3aebd594b2d1c3c1168b474e011e7a280e316890d467b77732e48c7bb0216381ac8bbbf6a7d61b90c9266a33ec7744099b2e4d464f1a11e1d38883de5c89371585a2247c4b80110566817808e52dba03061848fd6338cf03992c1ab83f68a13e75c6565868dd419815a19983aa8d5c4123109a34fdcad5fbc3c37c87d1d4a6b1366906a97099df940b2564f00e37760786ef28c7896c09d04c0cd24820596e538ee3876b548667cb26dfb6073eaa5631b92c4bd05320c923b53552384d4afaa047a2241416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = pass +expected_ciphertext = 3bdda88aaf866064ceda7b317ae51b6746073e9fbeb38608155b75cfdb558f0e5f5c162c48cce778dbdfbdbca7b2e51681a59bb262238de3d4bbb812f7b0a58aac58dfe2adc4fb07a9f22809aeca5fb7c0d9c6f6a0d776990c71325a176e86e5326c599508e1cc4fe1e6cd62d991fd591111dbb553fef6f44cd11c122405b92c4eb814c91d9ab28cc49cc43570fd2cf1948b558209e74da1d221b3a4fef04b22dd4c0b200d7df252e1083e4418758e92017bf4e59be135b84a6ce14402d0731850115ddfe15af373ed3edc382393c38cbe579d28ef9dc7d9dc7a9514a4f84b7add3fe6a65d80e8ee9e084fae2eba4a3f26223fa94a1ab237d158da8b10c2109801be34d4b4de815996928c9bdfecffa52a432d054dd3efc775f264c682f27e309f6b45832f1797d393c77811564f5df892f82617b333ba5f1101817a8ca9937a64ad9044a28072f748ed94046b7d5d3e415e5958cca81c86f104faf5b85392f48579a082b8398029f82f17314cbb4a5c2b6316b5ddd9b2fa1520ef0619b3ba69b16d2143d5b46e829d3ab62d72c370345433446e98965c04011c3dd4b4d1079d868aa7c6f7a3b977b8201c5df17cf9783374199c2d629055dd03a3829e1e79ff41183a97c8ad42d283086015359015da9e0173ffa99d33f73bc1b62990124b3b6fc1f0d2eb45733079d25fcfeac076c648c7500ae14b4d15f4511825eed307a0da06e8ef7a294985b02ea50eb7c763782a712887ffc6bfac2ef3f1ee6e16ea92d70cda1f63a298cc9cd882db26b4870fca0c47d167f78d470cee95e03c76a589ad3d620fce2bae40857b24708cc5d7e3a62d2630870793d38643ab2011c2299e6b5dcf9ec0cb1270e8b276219a2b3cf7ce28a877fdd8cf6e758de1e49b13afa9096ab6a43b5fab52b12aba0aaae8e2afff23cbe63c2c1488f5213c7eeb46d9df443343c810e6d2645cbafc71ad920f13563a03345fed0335f838cf109a66feafd887c3410605f65f074511cb3e80eb456d344dcd4f79531802f64db35b3608fc5cbff5614eab43afb77326d7e0caa693b5969102562bb138fcabb89ca44c47c3ab42ebbec653aedd2f45d9e12a841dba293e5c4483509774d5daab33dc4f132a5c4dbdaa19af73c16137c16010996248d889280e5e1afb1a5c962f73fb797b8abcfaf505cf8e21699d2b80d310fbd3b053c1a25ab5ca288f49a6c4b672d6f3b83973681f51cd94bf8052fa6e5ccaaede64c2253bdec403c35e1f772b0c9ae00d99b35489904716cbcbb9a7dcb19b30bc3d236e8997ed3a49b6621046e1fe0681b89d3dd3208c519a4d2ec95d4493c465c3f4788e7cfe21ec561aa5a026b6846593b8eef6dcab4c04e5f34333a56c0dd65cc6c151900552f0332caf8961c89532838a61db0d5a2d129644ce64853baa0b390f3818f43df5333ed6c5c035844b8e1ad8c13f68727ed0e64e39df6520fa5852380fe063641847089ccf1ac32dec22b905b00793eb542e391eb3daa3919443be7379ccd59ba76892b27d8d47cd5ccfc6bbeb184c937e58662f0658b135a84ff45e98c14ee6f4f5f078778c93587dbdf00690db36428b49f83e0c16420a0b7444cb407e2e52c3718cf06803d3ace50e4f1cafd22c2b5d50bb4d13895bf8bb33e45d0017e142640ebafa5240e3768463dab2fcb76b34303c9f76a683e755f1ca001f5cfbd41a2ea3763213c298227ab6f6d64858ef688e1040bb6e4d621fed4b9a6aa7510feaeb79c970007aa29b1eae1f459a1b381ccd01a8ed09e5fcd8a3a63555a2dcbcacae0eab716803da8e2e018aa5a56120cdc85258588481a6db2fa8ac9d88dfd21f8ceb85c9ca22bff56147b8cf31dccb8720ee81f7ebab1306237992652a8674a15b969e61f1a9582f989b5bfbb98c46de614d429efa46cb1752fff04e91ecdbcbc5aee7b53938ff6d10bd8bc0b54fcdf09cee0ead24daae0288bced7fbc60a5cb8a249f0057d1a25143f408cd2782b6ba96e39c9529effb0eadc7b3f9cc3ff46c576e001b38fabe06ac3032b970caf1fd581f28d965b70a82ea3bb02108b003a856e7bddcbe3283c33fef8241c7b0bc2fc5738ea5e9d251b731ab2553e752ab656ef624572b77b03725241d6374b67719ef076d13f332a80fe5b0391ec95d2390ae70983e7fd3304d5b408d5c9f8c00f41b6ab9fc6889683342aea39ce80b33e5223073c3ee9b875f8888 +expected_shared_secret = cdca5387453ba0f0fe9f126702ada05c3612388b70185b6c2e69dbf98c2803ec + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = 1a7c33d6425e068141b06c2ea57a010851a3b30ad021f6c0aa896e81f13f02d341faaba798a73a96d0b66b00bad5119a8d44797a1218b18224657573c9c556f5bc096f057f72fb749fe41fb9d290e76801b3712faadc58a1d3a8aaabbb996277d6902707a21ee099b5906854d2d45de78c1f134293d3dcced2296c5dd6b1469ac91c2508008951c7fc23eccb9a97f23501b21a625107a9c56ec39b724189ca111a935c3b58f262a29ff577f8459c74d9147dcb8eeb8689ee35aa131369cb805362289ae5973eff1420a8abacb650a1683104d2d82acbb28e54205404d68292f99c9c222bba8045769b73b890c33512c04af0cd86273234e31e94349a322aa13254484c3b99a2ac01f6ca00a77ba7b78711c73249eac054d34a1b0718814f407fd9d62a5d48212fb3afe5518e3a671bcf2cadcf4c8acb972603f960f194a4214cc8c9941fb31a6093a34c102ac18c26ba171a048d39860eec35e890149b9bbf510a4ff2270c72a507cd4a0500ba593841974c419a7ee37859a76f02463cb8303489e61ff21492afd03124368ae02c794642b7fe758f76219128ac75f19c41ab01adfa1a51b027c16e5b15279587e4f4a929f34ad51b06a060058521af6e4a24d54920a7e60c4174baec0b5fc4b498b23711c92bbba383556ea6169f558f5ad29443012c5b82524cec7ec43a448fe57d88c4ba220b56ebc2bf90a2471bc735e88c2e73a8771d669a1d76566ee80b78410d7cc02407091f4b6ac97cf2afbe67a02e445eb51389b8233080d42e74e20650a514f995395f8b23ece04e2a5930294b37c79aac8782ae62dc0d7fb60fff5c8d54e29fdda87562250a70038355a70d6bc0c3720726f0586acdc727d993988032cffcd5a9b909857be58c3b6a7c10041976a472d2bb7d3a0932a6c0cec9b68126b98b40d4041f5439f395cf6ea5213d39c69ac91b85696b009084e662aae8053df014720b5759c5f81b91f296bc4103c7dbbbb6248f87e8543e8a660bd6bbb9f81ad5721d7f36cfc776acbc8635e1910e4191730aa68e5e177d2d2234a645768d26cc069254daf0c94a09414a36a3d19ca05a5475378254ddb0890cab0e686438461a1d499aba23eb3dc2b61aa6a46c4afa2a262c6f09979f01fa1a98f62b8098be6416c6ca5b3f8ee79e28c07cbe2855bb64c88f67947a495e87f03361080cfa3c2aeb2791671729248b488278c72e85ba2dac1dd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb97e0274975323a7b20d27937f0c785152209060b05088243636039808c555ce29fd18a449a9a188afba922650f17102fb0a28381ec046164358e344fa250c05df6be895a5a0566b409f893e9d99cea7b3d71eac7a4d0081d951eb755cd39215c60c1a21de05217692bef3b8b4104608d198ab11c4c30941789919830cba4e7431dc127ac770957257c19eb80595ab9bb9d4a0ac266b7a37b94bc517139c904595c327f5c1430ac7d7e33bee0ba9c7bd7b266e290c3645821542f0e0a920fdb72707544a6d10c8a4c5a46148c2458b6c5ab06d42c2d7db03ceb0c00ca37303c67bae0038e0a373d539b918737116ed029a4d78a71d74f770ca53c9b4ecd19bfb172299c55a0cac83fcdc8c74400c5be76907679b48e0ac041987f96754588b83722b49159f92b41b82e6625a6108a957c34b2d0e30d536218acdc56a093ba9940c075362c1028c6ba42a775864bbbbabca70a5b7da5cf05821a9a81ad022784202362e587bce2a5b090530be4c51ef77a887af373637326f436c891304b72867dced161c2f0342f23aa15d69fa887652081a9c42b0669a689c5fa77649bab20eac8a16a51759ccd0f86c06c610a88162291e6cc1d911a88fa26e7ea4a23a224582807f20a8f1e2202a92495b6393036a25d4cd97fc72a741e006b7e919358f6ba3c5ab136823ceb955382bb6fe3f61b6228467f3c6f5de79531f11fe4f268b7f50f662c85a49b36a7213ae958a14e9bc45d0105ad13c591aaa7f1663301aaac45427da3c6a8873ba78e7c7473d41bd79534df8145d1749f94cc9c82377cb388129d0692f839942830c5814a8fca410e4cc754f7315fddc20fc1d588ac4c3cfe9c40277b3f6173809dc063f6813852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = pass +expected_ciphertext = b9fe4bd50912df5228e9eae3f7d3cb113b2b3b80ea792ab437b9018fdefc174659f06d6d3ba49321e01685676d1306c2314f28aec295a9f136ec94b05dc6f333c886e02da664f0aad7877e84070f9e1ee2885c490630b69ca33a37e91b60f3a494242abd1cf1ff456315187279a08711c3f2c4a8b6718a031c2d1bce161bbec45ad8074996572d4bb2ca26197db8770243a0c6bc24e5c91504cee5618df95637f7cf913e062c12ce872c0ed43a38d4cd5f6389156ff1aef15e65287970f5963feb0e902f28f3e3ceee9cfde1140892dc69dd07b460dd8f3a9b41b34ffaada9a7ba82530cd5adc749d751d017c5e2a1a6802d955186ed07581cfff31825b5b5811542ff31ef774884d429249e4c0b66a9a35191922f302716d9cdb94bbf24692f23321a56e0797290fab5322b9156c7dc2e6e0fd9f20e320af281d7eb54f90e87b92ca5d9d7406bce4beb674db62b100a51340e93d5b47b533f66c68c2333dccb0e450ccfe02370ed5c4a377cefa3c2a69a0e48dd077e1b61d0a7af38349d0959d27510edb313ffa05a84d575f372e56f3e701dcbfc86214f5f66e7abd7a2c036e22e2521b6a0667ab623f160ded4d96f387b1a764758ab122b171c8b274e6294a6bab4cad72533e4356f3b578c05b0c5a7ee6e587d03b4c6e96f0b6e8c9c641144defa321600ba98ceee7ca29c1467d81a761438ae918f4161ae418969f2f30f8603f051b59ff636d6448be7fe4220caf2eec15dc671dc4e1d64eeac4b824f11536ae6fff0d66b49415da59dda35cbf2288dc6d5650b3685d02b81d12af0bb9ac5b1b34992c127b5062cd5a714a133583b3d9af35d4e6055b214f387485c59f8610d9ff7e9a548442229fa18f5b2e78dc2322c20023d886f32cb63a5cebd0f33c9877b3f7f19b8de870375ee386d2947a0c28b4f1e37e3cb39b5a9c9f3faae7c711bbd7432bc0ecb7b64dcc2203e8378be2b50a85333c6d2f14d89436ab3b7125e1e9392d6ee5f22a5789a49c7cea3731b513fa29e0879db8211c705d1f43a9f26559a95b30835bd26bd251fb9dc8259aab2f342f269773ba66317136f600e26bc39910f6a91858cd0afe36e5d7b54ff75a281d261deae9acd30e2882b0abd5513065aa58b5ca117d956967249154df5b8d5e2b2d458ae611014f633468981241731afe24d342dfbbf06419cf1e3129f5606336835c9501d67cf335bf5330a348b66d2470f68bd547d3a8aa7e7a4d560bbe20bf0be13babfd64c6277a772fc71eb085a26d4cdf9a0338c0640094b3c0b838d554a092b996d0eab4d6b27874a6b5b43f546f77eb93675e9abbf1daa2f4bbf76ea490148a261cf726ceeb3d9c586c92171124bfe6c5d33a6a0b7f95b09513d833fb9f47a0bf1dc822b38fb36c2e81967cd8d99266d8e62019ba0849c1d70340521025e6235012fb671b87a442ca3050c6b96283f1869854b5127ba4d8cffd336a866b9d4a6725404ca8acba96accadfc3d7b464398b67eea20b3721c769eb3a9127968dd0250e0e39f533482c306bea024c3ef0a840cdd50bc3dd57cb4c7770bb8a9e27f53b84d843a72224de499b641a2fc18b45acfd84c940ab189c3dbceccfc48f228038b095aadeecee2f805b1fb248a12c9d7ceeae2052a08c90565833dab3682511a057c420e7541f595e098b7c2724cd3bfb8979cf8d730a9c60e8a58a29ab64c414476d4c4496d393e6950e839bd9e8009f02b6c69538a0d35e619f321ca87f205aa2e5e417f7a6e55db244250e7ce3e5e4a9720156531b1d61526a712e8416fbc20a4ee2e7bbc97425dfbb4eb94bb9a0ff3f25f515dd017c4bb44550fa43aea7fd035e096d4e0056966b07fb4e2f4f40c612b5d25ab8c5bbc6d22f47d53a4964252de54bb4c973adb8cf4f0a6f2ce8d136109098ae90126d34460abd6ba895952e795b3bd5ddd4753179b21d6a54626c47d8abd4bf780177963961de0f915d0452c1a06febe965cac1d5ed0ad59ad52599a213d563defb30a4298b2d7f89e28208d141458739c719c18c9fab830f42c47ece180d458f4def3c878d7c9f16349a1a1ee157d4fc4bb005eaf1452c475c1e206ef7ffd87bc31a0b3b0486aa4e2b7129b9f69ff9f0252050a5a6cc1b1677f4544b640b911da9fc7c5b70077ba8cfadc0ed4558bf536608af410285d3da540899fe63139ad733f9d5d63d2c7730ca74f0051747d9ad4a8007a +expected_shared_secret = b15db77dc79f2d64e13445c4dfa997afb191e0bb2bbf6a210a5d64263b2408f5 + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = 0fb39b1e4b0c22871afffa785df48224d887a73cb9b9a68aa2a768b3ab087bd9cbf6253378885113bc6168d631121a5fad30cc822133161b0c39c0a2b30c5c33383555b415c6fb0588d16b3b890894026bb507d080f93e13327707a54725a3a859661e49184025f66f2eabc07c5072a21275440c9d520c9d0570cd4bf8752dfb37ca066ae450a3e5e6694b9581f6195b4b580fbf55b9f933c6f9867af36786fc8c24ca71b47127aa08798f99b113c1c661483a6ad196028b7752d9d4732622934a5b05c8b5095789999796039928b453e480f008a4bba7a49aa65462d71672450b56c441d2440fd4e151c9d0518d10534f24c1a355a5fe3aa1c4365493c7ad66f254300c373ac264b3339f3af02e2736b8023a270a20babe69cc15d494803bb515ec54719619bacac9ac2a58a4e67fe303ad9565b33c8472335710e0544c4a96bebdd98454058413db3bfc2958803a5963c725a4ca074ec9383dda1e892ac9e2210a60d19d5e4b3471f9519adb6bcb79c16742c07e933767ea4b20134ba8329c0c026da0e8a5e12770c8ba4ea7361bae91af0f953b47032da6640f202a8468a096bbe92cb8b02cd524b38a7a4c69d5b9818c8b88da78a7f2236746217a75a1f6e2805533a17996b7f972939a23c75c9023b715a714ac346f8102c2f8a04733495a4b456f179372202477e60b60ba210365274a393d999390628c7f63d2aa2b05cef68776db9150c39b6eca9ab32da9c6753208d74a2e7911af644a028d2c5a68494ea3da6b08a5b67d11090c587f580800e04c942445bfec357e33388a0bc328808624e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b350cb557bab3f87a05b22edb886812935402915e5ea51f41b70dea48aa2aab4f9f247d3f637efba51120a258cab867be231e67675ff29c83bf982e7b15b766a84cd9369ac28c29af664f5c7a7553ec9a0c3285caf26ce0b9c84d504ead34617f303f6d0ca807a7c0da1388f7407bc03c3111c8c87ee158e68b53ce8c668e8343b2303bcab6a4d98857c7070bb103c47c60cf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c38f028203357eb2a37967a60a95a1dd22b15f3d723f812890ffa105f1b9b2a238914f39975c1c0f49244e4db7728e15329f2ba8eca4cbe7b76029c9a6f721c72e27149807ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b37007fcf8486c6c5d0ffb3abed3cd8be0b87d1b2c80ab2d3e40949f94236e727b92e83a9ff0b40100b200b6519be545e893b60d09b881c2681d335f9f501b0910572645060bb8a141e910e6aa582f652ebaa79bf2f77b373459ce87c474213ef0257295abc192c05bf31ca3eb061648455fbf82710f8777636c229ef49c6986cba9816d11d636186b62d2b06212932e9e727954530182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968243289e1cc8460130c034b45660b3668863d719aa9c8e11df72084ae53c3b4d85a7860c42b2482c9a050b1065dda241b43ec996e368c6c7bcbab69a433040e56bcbd4f167a9d71c5d336234ba4a5e47a956459b4c0477b4780769530cb6c9b4a2cb6aa27423f76a58f89753196d8cd99107ec04741be761696c642cf6443bb72c5dbd336967c336672aeef98af9b203ee6f4096531034f890b1dd0862a0737777278167a2aead708533206b3624b906c57e4abc42bf61364e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f501104b9240cbc2c87b0531f6e008b38f1287be901af59a45ea19de5b2c4ce78ba4eb1abf4284ce0ea22f18c2a26f428bba481e54a1745702a8af06cab649bb5c7aed2342413157a811a35b162b6f444cf2ddb22a24bce8e2925d83313d0b760017b65b8867419c7a1f57cc785b26bbed63ec79b83feb60674e2497b87be24aa1f899ca59d6391c1f2ad9aa90806fb1c97dcbfe5b9934ba169386759532b1117115e77884623c84cfee522bc0735e1f34eaf4b452530418f652e6f15cc3cd88a52e98078424d486cccd38272a0819887d85811e6bf8dc3689a3112b1b86d77d2bd91a53d123a11b6eb4ce3a8471c35126c017053c8a8f46054bc9c92752631ab8a9100b04f79e14c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = pass +expected_ciphertext = de22f336102bed90db56dcf3c81080592ffed51e0d542b585cc15890ef83d4b2137d9a2c2c9d3b7a5008f13c9d9eaca44a97774491e0ec09f5fcc60f20ba8e727de47eb93bcc9c62c412c3f816015d39d052ce030da88e95975285220762837bd725eb1a5dc89986d74de1315a7f52d8bc763eea041d441c2629714560ab6505e7538a444291b61350e5898ba0d08cd82b2f7a15cb0c7961efd3e195a050619e6af964b2b27f55632474d257c7f00bc360a11187eef5fe21eef35b00964bf760693f179d9c086a21899b2f9c840dce611b4cc27ea2b1822efe7ee9ab30c822cbe90e37f7fec7b4dfb50ed0c6dc187fa3a9343e6c0fa0b6e6c6ac80d92e995999cdd5eaff5aac21dcfb45d195ac9d4e1c53696346a762d8a013550a882ef8f56b0894c3ee66a3ae4d0ba94f1c6eb276880172272ee958f44378ba23c461a7d79f5984364e1663ec4d403efabfc9dbb617c7c350ba5de146316b45b5f4bf06dbd3f6cb4ce48dae4025920cbf638cced37d9e7df698d1736ddcef51ea6dd0fbd9431aece193199a3911faa4f4585b88ae0a68f3d59f68766cff57dcc8cfc2b5da676af40555125c8b99ce911b41d1d44ac4b09aa5ef235f1c72e10c134ad457fb735db7202496807000fe76ca7221c72255d82fd538290d092fc518eaf0dc63d4079aab51fcd2306501decabad9d54b2b6313fe4d1e8585d55eb52523ca1451fa5151bc378637bb129e59cf8fa7192048672824a90d7e53b324df2d1cced582e003df5de8a51c1c7e14c63a83c2fd17a65c92d3be640751decba18aed1a47483c602b5f9a136c2a47c39837a84d3cd4e30e2d38b7599f62b2218a0ecff2159904d27d8cea620d873d00a96714699936ed0d1b3307c8b987d199de13622d51fc3342ab58c025ffb19cf90b42981cc86174bf6bebc8777f6c66da5b2ac85c778c6e47bb7bd60be9e17a7d7a3377143c36c876a15d115ed1f26353ee1bdfaa870dcffabb7a9ef8fe01067f93a681314e1ec0c8683e237433053d89879042f28bc41e7963d7b24076c40125aa65ff080a41d52b4059b6f01bd6b5583be37ddca124ecb8d7d68446acd30c2cfa9e696ff1ab4c0b16c86d4dc391e5c081d8b982e14c8ef163688591fdafe9554e45d286378a8ab2240ee550241efd0cb058edd0b4c861ffa751d0b69335f57a4bcd180a5119a3b76286179e04ac93ccfc1aa36d0b83320f9dce518802f5e7f4bf29a79ba3671bdb130ec01132b9fa24a2e8ab5058a7f790813ed175fe183c7c5393594488fffa734fbb154041bb569ccc2b81a5926f522ed4fafa4eb35643fa2c2abcb1e6559da7938714cdeced33b0ca4197f00b6b0cf9bce07e4138a1563e78959ad985776ef5af16bd0119f20635f6e6706a116d82a4bf1ea8dab7d3c47fa5699db9b4b006d4a2411f64645937df678e4acddb1caa089b1b0dd497da2fd4e2cb7eee47be2bd595b1dfb1f3fa0032200db31d7b49d7cb5b738e61e3e8824543548802342ffaadd4d21af36f65640bb1b42f2cac9063d05b334470f996fb13d0195ca47c675004eeffbe95aac706b27ad74d1e741e4a12ded0b4b1ffba5c09d3d9a3dab9a21e55fed670cd408c30516812e1729db8b5262e2fecfd91df70392733ea049d18aea68a02086d76f62b5427d07c40100ac75f766f4e2eaa32fcc7ff27d7fc9a526835ea0bb1a5483c1429e1e4ce370287173fcb0ceb8209c2496581d4e2ed15034723ee57ebc6a1f211a6fcb35e56f9348c2b83ddec9a008364da2b9ec95024a8f9be28f551509728d65b1ca1e77d36e9e1ff47f5a98eb569bd7deccc3263cddf76e2ca2b2019334fc06db81e82a3174aa8930eec28339ca30e5cb6529ffea5d0a1737083d9df4253baab48bbb8523afaff1f7c3ab8b071248cd888e65e92c89799a7e27464024c2f7d94755234001dd8749e913e91fab6ae3a3de7244126edb48ab1a85a21d3c19e55d54d468911c46438900844a6a50a9f28992b43b8283a02276c8dd4a6266f476ac7537afc03b6264f9bf39b8f9a922c85a890cedb11aa22344a7e17a7da87d156c26bc309c24fc3174899f9e283172048bffc8b1f1e1aecc2ca1976cbf83d482fa3cd4c511b73e3c45a66eed5db3fc1c9ad2ddbfc63324dd2a4a6350e02614d2cfa96429f6d7b703f4452d372fa53bb8304527b3edbef7c13cc91d44793a4e87ec7a034f657c6548526 +expected_shared_secret = 8ca9424860c35214636855849bb039cdcb4c722c5b81ce18ac1a1090034dafc1 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 319442d0786cba94aa139895eba98bff419a6b42644b68c5ce534b0f705225f4a7b28cbaf879b30fb633fdc2aa70c54639f180e76b927ca4622f086601a62afff5335ffbbbcb52075ab7681a55625e01cb31248e17708b7d728905b64976409d49583272fb6208e06ed7539fc4f87b1f0b821de4155b79531546824bb4a13e09cadf66b7889c6baa9679df6187690c9fea246226a7a405b997c322b4ab041d7fc0b24ab54400813a29c87204ea29414a7c80ac65d374998494b914467f44241251402adfa34616b021caf86b2adc690267a41c40b763c11506b658132c59c0e887888a2d5a8658bbe403758c84cf86611026a5bf802ae4e5031771c42d047ef42021a7c59c2c0a6e3f10b9adf716bba29d824b271d787379021ec44b4b39c3493bd980bfcbba73e5772e259ccdac1f062a887cf25887c30817da33ac19c2527239e7f6b434f0affd278130b1a480348aef2998924c684e3ca8f49694dfe149152b332128061c659cf2c5861ca003d1e8bf33dc06b197abfe2862362a9a15fb35f6009481d2a79eb18826581abcba4bbba6846238c5edf5b30d6830437714addb5f6751a7f6d79558148c0db07a7b2a784dc78c8176a2a36b4dbb7855602742ec2624d6c6c589c515b5224ebf92cd70b954c5190e4212a0542857a16cbffe060f56140e4f3b2e03b86ab0c8cdee1a3e2e95cb43c852c40b6cce660fe61bc7631a849ea28e6c93203bd55c4c4928d6ca777023264d2b2f96f99f3bc9b23d51ceadc713572542eb00b77ce79b2f0ac533198a60f03939ea1502e09807b5a7c19ba98396167b116c88e889b022195b016c58125de60708890793bc582717253b6608b0933b0b0d160c42bc3efb602e899555265189dc376b15c04cf5348753344f0e8349b4ea29a6b85110f81c247029ffe93ec5891194963bd9aca2ef5a3e912c255e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d4331ad5a30da5a57636e75f4900285b927289e7ba510216e73189b6d76db21c600e8c26488449041529700539c42195624bbdf1c19eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a645862416fbc92df042baba25ff1381f3c09b79e2c89410625462018ed38a8480afac4a313da239ba44090a7aa296c304dae24030db60bd376ecb7779f2f2414d144e624a9b0d2bc181268229ac1f92929d61c15250730d58b75e663a2a175b4b98a906c3871f1f9a46f0e842c7b48238722124e7c2882b7831576a03b1ca105333e4b004bf286e45d3a9188757faac58e8d995e7101129fc560c9021ba159d748619204b7963f957e7410592028f97d297e2a8042bb8b342f1cf1af6a843a1598b1a0e851cbe6452842762109eac773cf58fbcd5845545485eb47be86bb51522273bb7782223b855c221de3c3ce3290c3fb4c9dee73e23c06994fcb437a93ab885230ce5521f8224521a6ce6c5ac8f682353ec78f22cb133c1c48aca73a461aa128b96590b2b508832f9a04a1099b7775101fc349b6a686b9cc3c7954567f1c605ce1543a6e967857a19678b5e6a3b996fea65336794d36c3045a0ac514962c79a6b03342b2ef826b4e4a2aa4b8e2d66ac920557915058c551b82bc0134dc489d55742b59c143b88ac8903cf6ca8aec2c784c1dc15e3b46ea8d7bcd43ba3161564b6510459f7956949128d6373c1ea8b41b92396d124b3b978325b1d21c290b76a1504a01adb164b3a6cb9bf5422a6b571f209a4f18c31c3a647d8e3cfd335067c75308026c40c5ba20dca0317cc6954341758274330f35df38abb5f1b59806a831979bc985576ae6a8df2608d6305ae2f7406f347cff1415de856b859d8306271c716495ec273a2c96355e195326883c4f024943f54c35f0003e70c9dd5c412f6c260f18a6adf1435150abdf28084cdb13685881aab0c710fec5272417731a65eb9360684e170f6c7a13310686471b0e91b2002b789a5a465128043ce6b7c29bb5dba20200dfc69d242823e477e34e146c828022d78c37b8c8fea50294586cda2f728d9b10d0cb58e1b091b68dcca95e6ad22416e1c9a7b0a75047c72309a284426fa98b3c905f1491a44d1338e0cad6bf2ac3c845005c268eda736b1c997a64438323501b6ac5628455694573afd782ccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = pass +expected_ciphertext = 4f1b2fe882e53704f5883b1b8613c9d4a17f72b1500612c398b4715a1d43ad79c00f69c66e8c7afdac439207f66d163d40bfbfd7d96ee8ba5fa98b009d1dc306453eb1cecdca7eeed84a08fd29ae9d9b9d47f76f5428abc46b9ed9845b2685cec51559f0496bb1b0161b024633f05bf6ffd3455ca80f750aabd5c0d2bc3ed18d95b605c404d61074021f7c11ae279027ff48dbb89403f5eea50924a99a5f5a2ecba792b55842416a2dc21512ec75d7b8ae8f4c865b8ded35ff017658a57edceb87ddd9ca4b7df56aec4bd8ea02ca467e52c506273974f130b1e55f7250dd21c7c42f237753f5ec7f533c41b27206b3771189c85fe9d0184072a8d0b81e6f98fb8b4b4de9de9427c1fe368ad0e85c8acbd3c31ec17c3a071ca06a3bfb5df86b20d2eb3bc3f5adbd452d11e604f76395301f8e7b7ad5e884ac90ca7ecdd65363790b9b0e72616ae60d1b7153a891eb95de5ba6a4ba6789a03e20f1ce0be511d7c7c394202324ae0fc429d7a3dc27ac35cef64c01ee6fdde76c0ba59b03fafb57ed3ff38c26bfc095ea62cfaaa9e8dcb22bd26e779c0231e3332fbc0e5b24f06e63c74525bc14a6c4bfd72f6d8ee252fca1d8264e7a2f60079a3aa68a6ee11ab35a9c80e0203c01d62913edc91d3228107c95f2fb147612d974e6811c5fa307cb6617f0ddc5ac910577beff3fde9a7d082db41fe52f105cf338173717a73661da1e850c607c1e9aa9734d6ca90ef855879dbe535f9b144678eb7a78fd1a7d7e49f174782bc17925258a84d8fac64f74e58005d5a1931e9ebe55f2e9e4790b7d7a0b5d5bd687477c279e15dfba7eb38a928fec671a1f3cf5316458162f92c2df26bca3d98dd5d806e22d5fbf61d84e7b6e9a06e6edf5b01868f09bb13f921cbd8c70d1a6257f96e3b147802a5e995c20873f4d8c99ec7ba76d1885130a5df0deafe0461dbaa7d398286f18bc5abfd2fe03daae5ad101f16af01dc22a64b6b1210b55fd3269309d4bbea97d136db04ff04bf3095c053122ae29959bc3f157dcffad37fa6a6146cfec799f225bb576927bb6a291b9e52dfeeb6180f61d61567a764a3427c105f53c615d18b5b5a3f29943aa9226f890247560c6b14d830de714e041237e2b515ee275caab6383e8deb5bd417073ea524a49e485282f58aaac69999b63ba5436d5632311be74981f58bdc1b0f87b2474b1876a10e5d1add2a3b11c1202c439964ae85589c881d7c81899d1dc2efd50fad84e729a5ab4e6342a6749f44f277e52f83fda0411142c0eca549c5dcd85da7838a64eecb0e06f4a199637beae0ea839eb151d35a36d8902c357f02f61c1ee52387de35605509564ffe882df8193cfc15ec582564a4c824c069be5faae6d5ca3e4a91b242bebc52c6c6d98d8154472599a0e7c8cd9aeadb17b8dfe0b3a8562487d1f47cf87d4c4c4001199c7d192307c9a44dca16f7a4c8ff29b639f1be6839b48a51c3148304c15e68cbbb6225d9c3139544307a59120ce7e3c4451486b445baf6a31003a81bff820bea80cf66593919864452e9739d3e33fb354def95268c0f377bf49bb319457db78b1c73465b4cd8915b7453f39fe15c95c981a831d6b45032d05b2a14ef8787dde3ad7aa8eb0b37195465451c672d4c0a0d87905fec449600082b85638884488570932d28e7bac4086b787137dcde64676aadb80dd440e0953b67b7f5a369984a8cb473af2ae567b1c1aad0a2dce06fea6345155c084880a96e093f8e394c6d16c9eeafae80d1ff2d8f94f6ee77de3ed56e9146292113949f31f4f60a6483bd5c4b51d507d1c01d7ab7eafcccc0ae64409587e2fb2866cdfe94c3dcb047faa437c7fa7036351f59849fb4fb98cab19feab17ea32d3e8a7b1b0ec93be3d73040bc090931c6b40bc5e8b64e6768944306186f1d309ec0a950ded03a887373e201c0498ea5ee4d03adc2f0c00fcaf4fb487b1a4965667d263ec958a02edaa992e7bc5421044c44374db93eb1e7e0db56d79bfd97eb676c3c17fd652b4daa788ed71b3d96cf774b3fb4d5bf5ca2da108695abbbab29657e6cbe7c100198d076d8030282e63758cdbe521b60b8651c7ea370b5dedab33c659b60d9634e19dd20b5f387d9764284e28e35efbb7c419efe1bbad9a7bba3a36c8fea83c050da25334e5f3fa8140dcff62d89abf966cf9420f5d1b309566a797904c2923ad126793d65a1eedae40ef +expected_shared_secret = b056e2904d66c51dc817acf961f141c2de7d201ca8e52d19564d0fb4e1310aa9 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 8ba428266b1dbf30553a10aa6c5118f85ab9daec1c521639b686bfc4b198c511939a039982cc774aa074d391bc5137419a22892005114f3132f22497ebc5316e190013325b2c0c1f23ac61ebf6875640c7f56c78df4937c883bc9da38d1f709a6df68026d8af0ba51f1f2c5ff0806cac1a396a7272a4065660906658a25c570c7067d1972417142b0b6bc244b8e52b1b7a4b915832486f8a7486230cc63a981b195431448671e71c38527effb2768ce1574baa6a23226563794e714c1c7f75c05fc4b2630a47ae24b2a1d3141516941d61a58b609808612064881347b4765e892438eaaf1c538e0baca4e6e1bb38821633a385b7c1cd285b6edef2739a675110387e6ec747016a6a1007c87949368d31cb7a63a50e210ce168c825b86695223fc1b8789bdc89545a3394f9c1bd943094546f640b0b129c4e78a9ca0b8107bb18923ce669da26268d57c7eee01f15d0454cb1cb7af05f2e787833bcc4d4996312c82714043907b30a8d250ece8aade970cbe463494e759f463131c12b636503c747f64249d2687b3301387620307503d9562e5a033d86eb23546b83b0f70937fc6b70db7c1d519fe1ca0b93137a41d89843a635fb5c389d420558746be267440e8aa996124ff97b163eb828fe492e96a367ee7c22e2f4031c44688935b0e6439776e34c2c525a31664386a5b6040116d487846f538e0da71fb17a750d4b0b8f4c37ba859810a8aa15b573eb029c8f7052124bcefbc48dc60743e7a455a0c4cfb7c57847c50afb1b5725d735d013441f7b1b43d93840cc4373dbaaa71035ae110955d9cb60ba5b5de5999b082335ebc1d3d5b6a6681e2e4714423b50d30aac28a4006869a85941247f0a8f8da236421b761315b6adacc513f5ae525373cc57482dfb15286546d106925adbc71f4cc1bd33641cf63035b7c02669ced392b0b8c70e776a768f859c04e3b1c1f05d9a909025f075bc0021b091b0bd29ae7e7c787a0a570cb99f9337986d714595023b53147913b72f7df50b6421319825304af61ee75765f44581eb0378ecc979f81950437ba7603b751dbcaf1261a17346cdf645a65cea895320211089a07101bf617b731e38a8114335e3267169d060a9c09e7e829d0168a21bc580087554a17688cd742ef7e4a2510779b666a2b613bf81d8060e06385398babcf2ce1ae7abd2e66ac06142a2f73598ca2a1ff769923a0aabcc22268710c0a2143b96269bbace0f69a25142bb9f1a0c05266003f7a69ab405dcbb3360290ba355c8c6f5b1035697865cbecf8a20209019ea08b6416c86a098af524a2dcb9b7d16253960670ea96897b406c5680b14de691fa5305405f35048865e549c3847b3bf01856a15a25dac28c5afcb6be3e8adaf3689a0e5bb056b000a1308ac643ccd94c28711acc4653b52cc87c7d6bde2dbac47678ddf7101484379de232cae6975b4ec02d6a043ae14a53632ab428666fcd98b9f702432018e783ba3c7d32079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4baf2a4083a91e3d58e89270ef4560669d555fb0444737c6dae111cd1e18f55f1780ca0bb8e7c1ac3e7168d0c9e4a515ca4f11c49c967bd78149af3abc3e692c4659b30851eb86ab41d575021fb146d60069d242569d111e510b731724e6eb456c5428754db8903f31b365c7aa9976c13210438b50ea3e778e5a60e25f85c42bb10b24b72bc820300c91547582fee167eff958894e4898c198a4f652f871c9b03234f98e7a237778c679b757db3225394a356991b2810cc6ca5c7ab888dc9e59529f3498ec40efc47051c03c75225187da36d3daa9f3f0977da80a14a13a990ab20dd415c2036003ffab31b7aa534ec7cddc40a9877ad6cc61d07b7b1d8b71db1d1a2b71923337532e464853357400aca0f6a883ed84b56e77b755594b7bef178115b18c68175dc2c390d462ab641ba14d80b1d36cf290c6afa532d8d7091da94703cfb7334d667f0e3150b60ae8bfcb56dd40e3a58bd4d09a5a3e8a167841118a51490a126d6b85ee90a7f3d5432f59635b1d5587821818afb74ce42569751512c9840f364b6370cb318c1677a304be1a2938234b56bd2632f768a93750158e844df96c720007228c2829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = pass +expected_ciphertext = 8bfde9f50edc17447a32142caa59ccd778ad4fac7180926a6851c4236c118ca5a1af677ff00112e34a515791a02058ac7a784408a93e2e475a13d42ece94315e4495ee134aacc0e657de7864bc4f0aebbd4707e4b18000a10c94ce75ea91cfa9fdd629c29ff02a3b35c08b69f1600c094df1f87f8cb6714611c61559ca83ff20048fd2fb43bbffbb9c996302cd08fc36c56bc7da84b85a98b4a6fa7f4a4d1ebe4bb89a2f2944fe681743015f1b6c78f93221d08ad12d1220774d737df2ae3791bcbca602b724c27f57c90802b6ce86b374c582247f0ddca21f9c23f97192058869a433cf31ac318231e6c664645d66e18b0dd0fb548a3b85186699f43f9f4a2a15c9517e3ae66585922f844f09cbed5be15786f15061e4b5781934df2b317ebc9425872269ff5dd42bda30f3aa232f788eb78138d09b83e0609a5a0d3a1b22a37409ed21489545638194a81972f4667a4e1ebb517dcbfb607043b9a8658bd41a960301ad29c3c94797d2f0598f42394f57b40aab2bdd3aa0b156967a03d597359c187dd715e5d8290895f3f47273027b1f81fb3dcf992331ace69ead7d83502e569015d11533d704a5813cc88f74d39ee7d2ae492593c7d69d29899ed23ae6b5a7d2dc4c28dd8c6971a52cd6692b03409f1328738bfb1c1a8304229f46b02c1bb70aa23f0f9a6087bcc0c948ba291e63f56b306cd48e8a45352ec1f4e1125be5dca924231d8e8b6a7ba1d14d44d7b43eff0e6ce8c86061a27b84ee8a018d4accd3f2ac03f36f5b466e5f914f7eeda28f65d13a7ac5ea6718b4687875ebda9d67c9eb4634834f6bf4a145d9dedc96a3b118b026bd44b473e8839f86405982f33c70b21fae5e2824af14d610da2ce00cdb72f15f2ba3bbdbec777fa17c83a7293da0be926ef828e7e15c71efb579e72ed088a7408bd4034cb02511a44f6352cb44c7800279ae408c05ba7c9de63a5d16668e956771d580d5c4cc637ebdaa4d92c75fd3fda04c09882949ac85dc0356f210a538bc666c75a89c067cbc5ee5f7542712805be7147103acb203c8f99a5fcfb8ef874b6dd815e8b74e508a1fee87020d1a68b28358153d7b344918b5691ccc46d614b7606c2aefeeb623c4f367b7450a9fc6cb3ceb45139996d39e7afafc80c39ede56777f0e6c9bfae67a89db0aa2abb0a7d4cc24b6ca6e5da624c9f3a01cfb5e7039d5064245fad0c2273f7a33694b5be46adfae5afb1c05b93d7477e22cb2128b3312cf5c878953f8d4c4750e183849da2dab24c222a8173e6c1dec334532bd65bc0557fe85894abaef701cb660173dc1a02c64538b48bcb5f9d9ca5acbc53202faaf96f1d8281bc55788f72e64b99482fcb17c6315a9e48b661adeeecfe7339bcb709d70248e7daccaf9faef94bf769d26c4ecb231426c131fdf3ad9b744580508ed04b26508727def4e0e2003c0737bcfe26eafda4d8f261ab1dced0c88d08966b5a573e5efef88e1d332e1994c57783f189b16f99926035764db0f7d704300cf6ef23881abaa531a9902b03a3689207a80dc3f496e38e4a1560e6b0e71a93ff595e5c595e7e2cdf8e41e0a26dd24f850d6633f5ae45e0a694406e28b8fba10b7db3b710980de3f35f2aafaca276f59d7c3953d3dcdd82090fd988485a3373a7747884fc7e0dcb4c81018982fd3680a492aa40e1380f212c09e41ffe1a8952e6af7a9025bd2c3f385207f65c13b73ff15b062f0707c0c66baea4647019a0a16e24c21854e8d207dc99f3e58468f954a797cc672cbe2f3c898d0bc894fbb642ba3929232a00013570aa97b219e582058a3f4df92feab5c2ce14b2887a3bdfa4c63c93d7b476dadfc7e61aa156c523a87d7b1b38c99ea84ed417ccde7d1a5bde2524c118c9e3a491538e5b979529bd5e3d370e9208823aa0dd4f814e133553921945386b2a8d6c8847a94ecb8313bd51978c7ca65f7d52a0d8a1deba338b3aa9bf31755f68e19f11b7c19ea4f8c02fdc6974187c35d5f442aaa91a88f2b0b8a19febe41ce52898e616e5a016995419b7e1aae8e48794e5e245d0ef013e737ba64bd487f06ffd25536588cdde82bf10c26c1154e96b4f8bd83696f5d41e00bc6cd8d6073a1d98884c0e411d11e33e8a3f76a061562c1040a79127741b614b0a68d391c8d843df2e44136eec02186fe637cda6fe2c3abf3d821e9409ec5f4c17f76c8d4da5131ece03c095af052ace7 +expected_shared_secret = 663bcd21601942f0ce47640325c9efcfc3eb3b022f0cfaed168893b1b6e5dcfc + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = 3db4bcf2f3231e1aa3e81c7336e49c4d760454729e9a47c4550062afd77d971228863c24f1881d589c111b38a7e3f08788298e5cb26ccfe7a71b171fc504b86d4526a2c0a3e0251710a21fdd68047612cf215a46f1cb3d5376cdba14829ff67f7d4704f199ac398777c8ac0ed24c4f00715c976b0ef18a83dd177367078b43003c10e588dfb9c7c99c5164bc14755114d5138715721eb3022cf2d016f97011f37502c44a397aea0a7818546c831f2073a4697aa878d00c4b7ab8312233cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078293e11e43981f00a25988f076e20a7d69e25fbdf7030e8404ebe35f530a8cc5793cf3eb1aed34b3ea742f4fe853fc8b7aa77a2b17669a116c49a0a114770b14801a62868839ab199e3c02c810cb6e0489820f25c524969a57172811089c5c81659f6859a1e5197ca36a33da0e2ec00cd035b23973448d12b251793da4bc9039b11c4312cf3db1abdea0657467885191334fdc8f590973b201addd09cdbb545fe66a0aacf679f0b89d7914268084888d358b767a8475e85da48590f0809e0ccb2c7d286f12fb8c6fba2f1b16cafc97a0b9863b107826c197a7a6bb0bcec280c526ce18058e2d47bf92e7bc0d4031d4c8c8c8f57bd880c8b12c556d750eef27ac96fc47f37c2c26468a8d27b2bdab5483f241aad905c3a76fd82308d2938bf7a070e6dc56e100b99dba0e46f2729a52a365d732965875b020b82ab23de8f8807442ca89b31fcc76162961564060a119002b116a510b0c2e1f301c55992bc48519ec5a1abd49a4e9da97bba98bb4774c0e6b939ac720cc22b2df733bcb128c7d4165cce67710719c1c978cc49257ff741ea1c3b5a6479c4935447987bd61d99c1d80c833f671f6a44be835a8d8d733adf4af4dccba087c4b8681a8b49a863bc21887a0b1d50b05ae1513dbda0960bb156be96a1321b553f21aa0e14295d00b81096e1c557ad6c949bec43817a836f09b0ad0803ca072b488a1627ad2c017013492a955fc829df7d800c99b1ce02b1d35a68d3269cb322b4d66ca9ccd279fc738c4c3910a8a4a479bcba7b1a6ca8745505b80236b63244d54942305c3c0f89bb4e771a5b09dbb072d20417f469b47cb8b64380b1a99b6a83cd111a881af60ea3ae5a314dff60841592f46a39beb80234ea507b1c9233b898a33208d8c936294738cba7287c5ba7f2ab0b7b63a0d475ca3d6486858cc0de5580e95c56c635825bdac834c71337916055d1c9490e7977982945941b8ff196ba5c23f92553f9a1b962a56ac9498b69ce0c9393621f7a662c6074c9e93b44d099a0003390748547e10052506ac88dbc1d3523a16b0825b4656552383ecf067b2a423bd0aae22ec0971e52963241403438c3c254724e1565ee569b0d357b416bf3d770a729a277caba335519724b2098a107f3f4c1aa1f49796208e739304852c949debc717dc8430f23987d60f0a0a3fd5f97aae412907227fd2da078f1a1bf46c0b66e596839632b121c5eec37694809861541b223619850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcc805a0f4655c61a8564c3577273d198184a2b4443a11aa05931dd1827c0720214eb2798af1a83678808913c9c6dc57eea4c1f2f469bca44aa8a8082cd4082464a9e6ac0a86da0d1e0021dbd3196b726ad9b43dff34cda455c7a51ca343f1af8ce2c580c581e4ecb1517cb36959114a481a0e73718f07a8eacb71a7c2beb2654fea5a7e01a6c02f183686b89ca0c775d0605e17225a655a544838a60f252412fa5baf353d2d264c4e4c2cd31bb4f3075410c220632b3d605c7431479f5694870cb1b1724c0363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d6252c8733cb40627485df64a4e872cbc574134c319cf1464a6b69a6318038896111fb69d306a6c47a393069b0f27911255e0306bc4ca2e93ae71336daa3a8bc0517eff101989f9c19bda6751724e1bf816d4cc7397cb5a57a14c471aa511e42f18e4937001977d063a4ee855f326811ec26c8662b5825a95780a3d031948d53337a45679f5c328573c109e5944b68c0b4d2b466fc48f921328d6fc74705491077987e6cc936e2bb69b534ea97acf85e60f2522a55c115cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = pass +expected_ciphertext = 9fd78c1122ebd395da508c0a171cd52d0bfa8af3e954152bd5f835dd9158052e9e65522850ba3bcfddfd2c204a48edcd3d4f5f3c6d7052933baf66b707006b0909a57638a99023926d0a4d8fb5f5a81cea061fa3914fce87d3f12c31633d1432e7c0f95480ef51aecdd02344acabdd33f7b258240aabd85c5a52537f1ad6adde693d08c2dd6633a194b83614f1962664e8b31b11ac70a4a710304866f7809d9ec1b60a64a20c0ec9c383186506bdb44cd5ae5ccaf2dc0643b6e23e5c2104bbfd4b83d22ccd88274f5678e416219bcb667fb749b9a936aa32fc64d50bb86c624678d283a7f93f57050c7b0cbeb695bc3c7a15c843ed99bcd0f9f74c99e3ac7239283571aa442f981b0c9a9a34869de8e707f1640003717ff0c4894e70d7bf3df2e017380e3c39e01d19c042121ffbd9519b4f4a8eb6114f2927c715bcba66129af881214dbeb83436908640dd4f56137a8ebc14239a3fd227869cfb998696a57a10ba9169c346670a6d503d751b6afe396edf421a11fb6316a0aa1285b6933bfc18077a125e2d1b12e841584c0aab9ae055123918fe18d74cb375c819b02d0fdf1507c2f3fa19e872a7c7d7e7eb4a919c3f5d55e08721339580342e3c1bd6de5cee43774c0760f58c1fd307ec6d6e84eb9f98dab5c3d39910c57fee65411e366b4a665f58c258c34f1d6bcbcc5a9729f19cda362576f8d1f61003c1bec90093e1703ac84900df5c304aee2e847efde6be48a85a491f7134fa6cb485264ce1d6dac67ed21a94ec4f50e1f13d9906d959448218d0ced49bc32623f0d078115101803fc528bf3860e5f82552000140efddd8a644e4a7b102ba4b9951b2334372b665820d6f4515c1e7e89b3de28241a69eae8c5bf9d86a4c3c31384820debc75b6e3bfacb54f4489e5b542303cfe7f068d30792edaec52ec931987a51ff6c61dc551aa29a387bd6fa0a6cce23d65eef6302b9e99e20be127ca7241c80ab3da3c73b328052e73a04a66eb9623077130394a08db2ae8e0566f44ea5e5294a5b03197c5e4202e93cc20406777b35d20114f814d0506f02af5aa36103b9f6f7507b4d261fa76680d8d43cd88ef7bd3c397a3a2af42422ae0565dcfdb223891511f2f1f0fe7d5f4181b72598edfbdd4e7b032ad715db6ebee82a678d89a44d9888a4d6a71cd8fcf6ab5fcfef50f392d1c3c5b2fb3a9a57118c9f3897287cc973030921dfb70421f4bd93f540b045da90e8e75b319a66c3dc08a8b8f75ef2ae4a0d5ec62313b3aa9ccb7400ba7a3c9d38e25f43f48838d9bdee604b0501862d6ed0a05ba9b16bc4d24e759fdc8b72f47d7cd807dcf917bdf979135d153ed612a1388a91f4d3817cd051877466523e67c79dab62237c501c9b14e7493290b2a19da5bbf399ea734948418c9202fe61deb9b229467ab88910613d2ed46ab72b74cb40d56afab6b8559fddeab6083d9d339dd766815915e9d0bfe6dd729ada70d0082db06b44ce7d9b8e2e95ff40dbfcdb7f96e48ed5e61386a3b9f98c27de7486f88912d34256ad3d69827213c734a8c3bc062dc666a6a425e3d2ec9e29614c08f37603bbcfa8a2e69e696f111edd85d36684ae58eaa006b212e31f8bf850bd2113b97264428cecc74f65502988c8c2909643d3a9c5d0af5a24924a0950a0e0e9fc48708bc87967a5c53deb73089e31bc90880a929245e2408c9ff102a09fee0f8ab1f6814b3758540f1516a789856a8c0551f9fd909640ac45c6f262dc9ce47508f2a711a9ee24252e8010c0637a29d52d6310822aeb7908ba4094ad81ed06e37e0362ec9a8cbb17902f21e3e9c1bc7398cddbfd7a88fa36aaf869279ac05e6903bde6269c642c22e5185c444998d4575342088dbad818e6ebcf51b1eff795784f0264ff4426b47033b76c1f3f86e6120b2bc2a0fdf14fff4757b6b25587d1dc95783f83b18bdf3481ff15870df6aa8ffee072e2df4aae4f3ff7eeb84476e0e83959d6675b81712160d640f57b2424c6ba169f858015be5688e295be442a6a555ea578bbc345a51c049c01c1e0fbab96fb946f7464af0ab2de717ad066d6a4d8ee3ab9a60d0647edfd741c6802fdad1f3a8c277f269f6901dd9a7145e2720d4c9456e81f463ce52f53d23bf0e7de5d90e54a16038d8d8009465da7dfee322b2f87e8de9053116010b1873d43c5db1638b857eb2338d8b4d2803a2830fd370e640b4b5046b0c +expected_shared_secret = cad5816f1b2057a410cf917f52040aad9cdef2122ce59211ccef77c4a7c23a6b + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 24d25e62d57365c8c611f96ba675aae5a14164b5171d74146d792d6203ba384ca81ec71ed87b8ba40023ed8bc6ac54406263ca3d97c5bdc20d9e2cca82b0aa54586863d95d3ed0075cc897f6726caa441896e86e03711a3d109f5bc311e81a5194363f8bf735ac9a2caceb7ec4826f8af2b303c3914e9b7c3c5337432ca626970761900b44cc92630ac8469a6bd9d2b46d88c225223dfc405d6f1447f9878610d021cf3762c235c414025239ab3827ab5a4699c82e37b1a27b460f0264f4089a98e41c924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad0873935718bce46b2f19864e06486a4f5c8d689adec32a2e7c6b57071be67017fe25b8f52ca525f99be536a4c1468b5f9f418025450048692f961ab8feb5075b543e04a0564c26c58a72ec6433b623a2d5a086c85347e45ea7b99d03ab50664149414c3f81d219a5b5e732c0a52c060e90e64e14873c02167a21a67da6a0b945781341cb7c65aa2dc481b0998de5c8d893a548f055f8fe420f173b949862a5549b0ac1908f202ae0bec6b19c0b3e5178f4e40485ca33a93947522c1aa6c188ac2fc4cff214b995b1bd69229d01a8d3d2045af723a1de559abf78c09928d71aca3c0016038340ae715058c95cd33ca85709b2134f78b86a84ae764ae94b994acf1354e42126638b57ad207bad29f1e60471acb5b650332b4656ccc808c15ebb8df203ff0821bea62aa67967bfdd09535e7088ca98e3795aa1167be9126348a946507c08243a969b2f9238fd29f0370356288cb1708024ba7a9cd58a12d306d4f4579893c8a04a10c1872b6a602c155f70a8ba6987fd28dc842b9f60b4052890a4482a351533b4752061e30957f8a16b6f8502a1b4d8f91b56b71470ee2cef40648533bb1d9179b3e335e051115b817aa30b3707b64121179318593b0460bcf6e57a65e045d00353605d60a0705468c6b8e4db422c31476c8a0b54ec166ba59b75f9834633c0052757dc437005f653ed4c19ceb7c774eaa75ba0068f2a997a79a98bee42abf9a3b7597394d4907e430737f860454407b8fbb2da0a054c2a4c737c8724c02684a070da34388fe9927be4259859849ea9cb6ef5990eae176efa10154556ce5650cf264bd11780055b5931bd6c5f51816d135996757b386b76a03893efea95ef964b402079cad080b67098b2c092f1e9768782a8e3daccd82741cdc5c8575796d08e3180b34b4ce227e7593ae9264417e7b53daea2987a01fdd42150a4262441475370c1357a575288571996527c95a9fd62c3bf54a8c8ec0a335c3a31b934002443d07f27240860e8ea76c821a71e67132c9a5a1d4d3b5f29cc9a9924081fa3c33f4a11285458954042337701c392998da8ee556a544f0b49c9c2b83b58dd8d165e6751318363400d61652d7170ca44b3033bbb20b45072708e6453b1708b5b8206419e050d7c8843e0bcc227b9d6b426a9f693945d69ee98558bbe133fc6427a8f73981786f42dc03fb23621952ca8ae03810648b8cbab5c1d2816fd1c231e10f7eeaac9a798c2c3a4cbac428c6971851320191d3195fe4419ab69fe913280d0763a906c33c4a9d311c74d9459ee85a6599061f09376a14803e1ddc67d8328bef1c7f673b62bbc234b20a29802ca9c19c89b9b6628a6bac7ae29897b1136a0b8c28b0441bd00a9144c85c9897a48902d176b9b03a454f36885db61b5915811d60c170f74abf894bcde1a088195fda3043be6080b8b98dd48168c12a68d0b74242472ddff790608170c271a4bb19907288854cf1c4cd744d1eba1201fb643b805c7c7c1f6cc9437038bcaf6616f9a6a214785f5fe71071e4564d0070a401b457023685a65d63fc525bda14b26c1f5381885b24786a939669261b769068c3f97eee28aed3fc68d3b08d6a6b77ee2449030c0190c016394b0d9c8085bd550d12f5110e647b9a1549e8f67f5fd0580fb39358114aa668bfa3a202c0369ddbf5518d80aed20c403aa3cc7148119cba54ce1667c2654d9b5a833d5a552808ae72629a2da12498319a30113b314c870e8752e442af5ed67bf1481f071921191b2b21964fae23b33df528a22090e4bc6ec2911810e02e65758397b48d1906013cc0cc0c2c73944b45bef04c2781acf467336a107ff7cb12e6305ed85342d2355b047862be56057cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = pass +expected_ciphertext = ba3071a54dfaa0906f8ee42795eda8e49faad17e7ddc5667c5e4a10375bd75fcd52c555e82694b6562b862bf9eafa16c02fda81ccb4ee96e2ecf9f13528eb95e2dabb90876dc9018d48f137bb93182d83ce6290673264c46c6357dbd792d361ebc0aee118bc7596b58af225090d063950325f098f616016e259cb6056ccffd05c4ed8272866c555456d51d6e30052b8e920ba02975733cffcb02c1697668e518942d12485340b0696775c8f1ff7302f4025faedea28e39924f9006e5faad919a292e01a8b4255575d3b9f523283e474505ee0c34e8abf992808cbb23e64d44f5d62593200eb4afc6a6a5de98112b6dcd3cea483b741f82105bd56d6c21f6e4b4112b3767fefa5b67e42ec38963eab8108f5b31116be611708cc3e320d308aa8859c1eed3320012b800f38226f9617cfcd3e3f444c4b633fa4454722cbae119d03cd4b6d2fb8cfb0ba51c74f9e0859a6747c2241b9794b5991affe54209393858e85dbf0504d8215de1be359c63cbab55134c610d81ec0446b62e86e7f3a205ea621104f4681960e39f0b22492d62cc765ad9c72f1dc820752b2f4a23cb0518c7c299115d2c8ce14d799366715ab518283b31232d3806a81fb994b839673ecd987c7d95208e2d87a8c78b32adf938a2b99888a26f45ad655e4eefb8b3342d3862f00eaf129d0d660d5af10c2b30dfe64f87a4ee4450ca155ef2129095beac466a35269cfca6fb17ae3edc9959f3af90d1487e58cc1d62633ce0b2ad3e482a9005aeac77542cd14f3581300a2ad1aee5b3a99e4570dde81df5fe60675a8acd7c950ec15dd94c96f96cdff33e155427fa7d87bf47c2ceee2e4619f4163322c1140b1c0d3786bb065886dce73a16c4787692a0c974dda5ccee7741af8febd8a4a150d3e7e99663ad59b9482e064ea3c64382b1c7aa2fe8e9d3d763a33f2a89494c1552cdecf44461efe20b61167ca83c0e5fc890e58ee5c549b37db205e4368dac61bcf8c687eb32329865230cac0eadb9c41d998a34e3490015e275828a386d1e9fdf14273b94b0346aa6fb91e0ab3d64ceed7f2abf2bc5fc5d016a0a8a87d10e723aaa90d9b0b37d99483560be5fac144a4376d83925d312a065a9669e27ea4715d58c15564cfc50b8209120fe2db562f0b43119b378ddc5bd4fbad0fae538e279a998320131bc5d033177183977a637f9b0a590fedeaa6d70ca065969115f0f5523e22523164562339ed91e6b5e8cd3f480121f1d0a85c57e894d30176a8ee2eaa1069c5c7f6c2cf116780b59be89120dc9ce50afb6b85fa4737bb0bb2195b5a5db44b8eb0793281df1a64b89751fd0b8a06021ef95f01de2c8b5abbfd0f2202f63501cf019582ff1a60bd0b99cc78e355a9d5b5adc3e32a05c0503afc2f015bc6280117385c837a6dbf184949d179369d431a26d869b65d6ef0401246f8609393739e9435e9bfb6f48586d8b2a0debc0822332d97537e7b332eba4a61db9a093d844652c8cb8a32cb44f723aa07aa10551320e84ebe81f3e7d251bf40b7fefedfdfc0c7e5327206b51e34b6ec5c958c44b88c3ad6fa552d882baf129db0c34d5f57431f525275d72a1ee47725e0f3bfaec864d6812f270e58671e0f5bf3795db9c9d8d77d04d6025eaf2468ae90307a701ec72623feac4d0a7f91470a2da29058a3bfb18e60dbb5d8249172a495b31708058117a5b24c9130a0451f573d273faed048d4191b2dd2a8341d57933ba404200fd5aacb7ea7c3310ec54fe7764178d507ca302c773f53855296d094029e9f06e47ebe01d74604b8aa70c574f77ccac4e80f862144933b303627ff8effa189938c28263b64f57cf0e0810feb90b3eb94177735fc5a531d71257fe4fbec3a1f218316b35d1f5b7f8129e0c361ccd7180472aa07c91ac6b4b00c4e8fe91da9c4321b1824f7f7a87b059f02ef8b05a40b8e3c21d7834cc7f58180a4bbe8a03da4bc99bd37b2ce542ab0fe850e67f9afc9f00f41a0d38c75d345ffd28515f9a442b33b05f0eac1d0cf710540af1be81e7481dca72647d810dd7c9b851f8264ea21080d8eb5315ef5ef75f7d85e0b2fdf895883d9a285324ef7dcadce365ddbc0eb0e10bd25bbf34109cafc32d88384834e60249ffdbaaf72ecf6d02bd539d6734465eb5a176123155d743933dab89963f7ae1ea01ee9db1b7f038cb0cf7f9059e20a0acecfc357e4ebf3f016ede1019cf95 +expected_shared_secret = e8f4dd3d2bb2c2f110bd410b2c37beee6d3bc7c7c4dc477c358234c54bbbd4ca + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = c6100d6d7952085257f692ad9173888f28bdae384635b2057a8183ca07853de05f72437d6872575ff4c0efb06259e397cda6a87a178498c9aac54b046a8219d98c48f113319984995f68b1affb863ff97dd8d14cace2921bc192e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e731e0a68940ee5b8307460b402651457ad1a7883d0165c8cab4d88f565008155ac009776500f3779530958c3003c7603c900e50148088b9420b78eac241dc0aa11454195a03998388ac747fc465dc140e9193a9294abb90b8022b493e069ae430ab3fc9307fc89358d3a88fb054e9836cefbe45c44569b285b01ec892d5ce8288ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc06a08f521b6063066788841964696a31547c851b578fd02434526c7e641fb9721cd390984bb121518a88633658c7c7c6b0830cb6800b2368cbe703cec33a4bdf319b49909b590a8bbc6542a108bf5927c49dbaa2c5c5009e002e242ba210a64f18b8542be1cb92a8293c56586b568b489ca697d6c4f819c399590472e8b9de9573a1d2934b86bf2d2b6f92ec8489430e0a681fee0a22bc3a705396ce6a74c1d5d3a91aa253da718757c875a1442fef4241f95b516d27220973c25e29b1d335846db494db4cac3a0b76388304b4252ac2362ff032a8b5c3322f6a0e5658799f1193ec69bf15c77e5ff2a3a2925690496af4320ec688450058b5727a0e66f98270267b3f49270e310714f353dd4b74410a9a0e778a1e030461113cfb05a142001cf39721215026cf84b1c0e706dcfc4d9ea80514061463a16e069750c026ad26ecca10f5830b2b756d515ef1c64d6d2c5e73818998aa9230d19d35842400c4568f62397eb0a42cf86c857c3ab009c8c831257d246b456996bc1bcc378a44bd88a0fc3469b0da0d22410218941431a12f37831653342f12206c56c4b3bf980a5017114b3112a6100b06a2a62104c48ce8639d1830e785cb3dab23f398691b48458d2acce79511ad276643476bd6c33d8d1c40fab1b81a96a7dfe36115e49a07f8c72240b9b3f24a2739b963609b0c2705f928c6ba7c2fcc0c164be46fdee5baa5730cd7a55e1221cd73305bff9b8ae5c126b8621bd6116c17286974002c88785c745bc32f0b86dba92e072a395e91acf7257ac5ec5ee88a7095acc39ad023a904b72c0ac845a318d18c7c72a0c4387cb470c8ba438498c5514398c70967b46109e18505543a98d51a3753bf3c657aef7264a91c2253f801641c609628a7f13a246d5aa13f3a4d1da22221ccba20091c6284452f376b32cc2d27d3869137a3fcfb06b7c93f70f3a20d84741b8a186d78af94c204bc0b6da175175bd819479485db23bf6eb2cbbb62a088f2bda7cb470c26b281e29e0f29a111688cc2e7cd61985eb39287546967ad991eccb99a6dd4b111861755964a77e3a7d2c5b9dc966e6f51bd53d72f9775a624f344fdf4bb3a9822d26b6db6b11efb527a2138c45f27c5e8a834ebc780e1e8210a9a7a4b7c3fc63b1757a22b8cab57bc07aa27a228cd30411ef407bc276ace8c05498cb641366b4ea0caf8101198b35a51d502a1c1894eeb700a832d70e627ac0b7a57543769991f007176cefb10c6e74a987c1d9b9750db5230317298a800b508d41c942b48c36035915c0504646726ab767a5059d39996a3e310ccbc610d878f9b7503b08822bc1541a359c807526d27a7abc1d78e3c0c3f67f0609c699e44ca8ce2c7a78e70042be21f4c569e9d0494a6e8c2f0592ba5060b365b57d1b03916e27fce04c42205803af0b213e27b21245e480b6330bc8533888e72e9bb2148059ac42ba2ba2550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de4898181422a34b9a239508878a0682eb2466a44a59542b268d31989f049f433a7a0225d556770f4391dfdf4432133a0d888436afc531f4584abc40022c36314757e79538cd1c67da58a049cd10baab7a7fa38293ca84403291372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc7e1c2e62a2616838d5d13674b832694975cf1396deb11a1cb5a1bcfda55ba86583884aa9593399a047f00e703cd458ad157333c349c46021b7ae1970bc2927f094c77970a7c9bacfb0a6e02108036f809c9ac23877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = pass +expected_ciphertext = c15dea8dc9b3e3c3f0f882baa4492c72701aec1c38c15825bd31c70ea9190b9f8dac474cffecc40a279208bd639ef51489b1de937e444a4efbcbdc4fa7672f5485f1f3155e913ef6e79de719e74c08cb86ae841cec022278cba60e42bdbb2c36db4f558d8d0755987773d960901daaf8ab6de00dab4a3d3f0b89871a1ebb51713c2c4e094ca0ecdfa1c4ce541b2eaa57b13c2c73bfd3062ebc9e313c9183d90f621f978b0e984d025ca549ef3a493e663daa6608ffaf322b5e073e0b0a432926755b8b2953ffb7072d1a9d007d84666f732cae69d58c3c5fc133e513f2ebc54f04ccf95e8dcc87f0448bde13e581c6ea196fe22b1fe2a3f036153f7d4adbfe39061d5a4f6cd33bda8a2d68f491cd4a287366c7f25a586940a23b08f893d24cd62335130e210c02b1f4185b7c0788e23117715e9ada8a65bf90251321c8bd7d335723977606aade969c34f346ecbb3680b4d27af6b6c718dcd434a61ddefa5d27b24e786633928e13e226f1d63c98c408110f6cadd667b5f4a7893fa9c0e037c0d54a138d106801ed57c059519a774193e09ceaf35f21f6e562bd93ac9c4b2f85391be1ef215d8a95350abb2aa05fa90407677cdc4b53bbf70086ccc8aefe333c82ddfb52f2ffc3b5b2484e1c7b51597f3e915beafa963dfa604643dac74ed40afc4d57161a050e70e9ec5bd460e919d8b385ba68e0ee842391aaa355edfa8b930bae45bc818dabe3935c40cd6ddfaa068897a5454319702e8e94b1e86176939e9dd6a6034600a9347d00a5b561060f2fb1fd89b7cd459ab76d8583171d95e74122dd9a1e8d9942dff9febe0b30af1c799d27db896abb738c06074781b192bcfc468bbc267021522bd2637cddfc937251dc0c61c8f61e6f7acc1c2d25bd2688a54d81a1bbcaa224cf818119ab78e1e8870bbdb21396e4f3c300d63037867a8c9fa61577e0ec11edc7126f0355d8c104a5aebe42defa7c9fed646a4708c4de81ceae2bd23ebdb4362293c442675f754716475256be312734579837973b7d6a7beebc5db3f08322e76d4d8e3824842a930c1db7595505b824c24209c994881dec2d81db4fdbb6267cee4c42722c15817a0770f8c84b2825dfa882a41eeb123e4719facaa0a4c1dbc0fcffea49eff0d478426e3ba5e6f6ab077d0aeb03d66c275fcd86e4c0fb4c3561834ad83cdb9663a77e10609cbe92d2e3289fb3fe0ebaf208bef6ff9021a95f86edfa20e8af937ecd483c60c5aa0bd948d93fe13dc6dc6f1f4740c0ea16918ba739bfd5294c8081d3c4e5fd2aea8674744738c9f5f221474f4500d3638ab4ddd06710ecb1cc4a8aa7fc52427352d68cbf723dcf8f5a3a9948c9e3cc37bfde685fe73407813753ac60b6e129ce3f432332cd2d1eb3caeb6e050698f90e82d76987e3588cd76245de5f0e7ae7856e760c39b3a6035c2a25f568f496ffca9ca83701db810f494968d550e3fc686b6388c808657c75ae01f41927b4149962c1b9b383b26705b8b54201aa2091e7c33d6aca433a36be9810eee0fa2bb8b5d0624c0d7bbd0403f4a0fa5444afce8d7df30a18aafedaa3397fcf02f2867b3d3895719b03e237c0105e5a5b4b6e31b10610383a5660dc630fa5633ea95e2e3eb0e92820087f5493c434d152ee5a781bd50a4f6bb2eb2c3c3b146cef5528031af3dfac925193ea62d5ba10a2ee26b600703b72592269c67c6a244cd7605a419b16f6e65035fab65db94ba1589801f831d27fe91371c6f8df759d0dc96012137a3348498c9f9e167de687ebad6b0213761965247379bb12e703c4dcd8c429aa35bf2abdc7dcf13c33c4da813dfa6732e8fe2edce3136be82e4e58ca2d620a599e925327cae64a38174a581b5a8c5c1e526c24f0ef70282271120b8edf6fd0ba1b31190c8a81128ac4c634072417f347c966ddb3b9393386fe80b15245b236a66c8310c82acc3ec9ff85b33282540a40522256188af8ce3a4f961555354421eb0cae489dfac24a4073d5853901819ee24f2b2bcde412d48656e6b517ce5a247385b598c293aa1baa8e6073b9344025392ccf33f14c7379732a3e421a5994b619bf2ce5c3988541d9588ad4d4fd00d1024308be3573e6be351c43350eb29f5a1cebb834dbe1e7d92dbc95743f3298c2c1f5474a10d73b5c7b097eedf174909b4102a194662e38474359ff4bd36f9f6d3797a1e0c6624139c47c30ad263769c9 +expected_shared_secret = 249855eb724db68f7367385c45a3206fa19c521644f8841b7a73f536ca47c26c + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 49548733578aa80987b45a404d892f45f83fe6260b4521181484a7ab65aed79a53f2e495ad444066d1108d14c4fa74847fda990a783fdb923734860238a94b8634217de964ea35a3d4c651a15c719301a2cad86352257c2ca1a87f329092e18c5c782ace76ba239c6001143f87a0406da9437d7b19144386b9687023a34a46814eae040c71673aca3993acc03879c9af60ca0e4eab9205b7ab65c33ff1295100d349f84694abe062672135865494ecf58db2912a3af380c228b78d329634f359008871769696bb357d552c3e9fc17d8b636e1b905303bb2a5b6a6f07f478d4229daac38ecf47c205371705b72092f7a438d01267783e24370080362c659796d7443354d92dfb9bca5ba5355e5c3608bb3d9b312fc7ac435b81cc1a6ba84a74283763a520381e9e3c998dfba80d8383d416495b42b7b6ca3e91789c8191b894350f52b6b7a3e38a45f50f39497794e0971650c446551d7d304c87515bb415773c10bf08cc20506c0f515428e8b9037c42a837469de6a3a37c695b602407a46b7796593623a9c840accb5a6b1175a30f62c8b9461c444eb73bf1e22418347af3d92742175bbfb41474156745eb0dcbc4077eeaad6c13c314d3188d3c9bf2f73784c0cd1a215c4623a8bbb19997d82be2b1719346190f054a1ad92819d9b812028633469c3661238fc66cab7c05bc5468a132c9b3a50ea5a4a8ea04800c97c3b391115725011e597312b7a0440ac2da794859776ca73b550d666a8f058477a1a0c9621ff6184f415114d35514909719234c166734b5535b863afbcbc5a2264a86b0642a41763b6d6da15447bc930f925415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da37862790a282b8db833ae37bc5a6940a8b95926f1f468853b288c9a4c7c128bcb56c7a218c3fc725ad1b89c829799b0a8a1f3718fb489b83b900f1cc9b1ee16369f18b207d022a35224330582bc4848e4634f3490c12c756246dc9f3cc27550057a1863ccb91a4b891820bc882c0e6024e1bb037677092c633f2cf68b96b666e1034339ca3e43f6ae7fdb22f9fc7649e559e5d22a07075bde79a82e62b5a5258a0e685a2cd1bc8566cdb4a19d5c581236f0cb4e7aad6f561ca9f6850d30a6fa0c1eca230a06e11cd6f26194f56f40bbcdc99bb4c1f32c851bbb7af48f19d813f89b01d9477861e128631b9b4d72c4c7ccbe59462a4519a8a34a44dd84586c4a542aeb6e1338b6836297a59283af07ccecec01ce074d8469c93f509f09f7230c092c63f2245ac2137a4349078a473d81cb3f87cbdf843645500b932bc326a85fa91095e4513e9dac02d92a69f5acc4200bb1dc0270b013b1f2372bc75aa609e291f0385bbe9376953cccb3f99971dc9747cb913760506fb051ed186454255fcd642aff73c32743158d467b0ad012aaa439c9335b4ee23a426cad3ddbc4ab882076c2bbe83321fb684825b032059838e3d43da29852309b1a7c15c08a5669a3ba2200b34b7f325a5f47b479aa49984060ace979e9db6bb68466973a3e0030c0bcfc4e6c6c13f734b1731ca956f89341d37b1cd5c40bec802a98c674869c04571993e461446b2e2a68ba71915bbefc2d40dc8756b9ad9bab639ff6985e03b5a861785981a7b1449594d584bc1cc4ef7a4333e5453944c61d0145a5b6c999900df26299ccea5cc1d36fbb80c1a5e9c619a4347669377d541519ca47f06884b1984408d43b4133bdcc488bddc599c4057b14a027d051420a5c17cc1671f18a2128b58e9b7a5e233a6ed2da288130b51e47038c9aa2751556ba24b284515af73a81a6881d665426d1d27a8a763fb3b2caa19bc310a9c10024b7d722606c3b6f19c8935b744e28333df8b9480a0083eb588380e6a12d777862e5c7d3e1874e8b1405a5787e92accdc798a873539c133502569e6de7a29c7025289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960750209ee517629ca2280bcb7df35793bf233fa074185a04894ac515b8985ddb5acab68ab379a639c49216a8ba4f9b125947150a907385e9729a7d621a5a9bf8c4a1234e6ce4411923c18ca0e925cb372c59220a502390e4c740571f71eea1083887a5797f5631f614f4e91184811892c6086b0f5bb6fc322afa31653509c8e11a8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = pass +expected_ciphertext = a9bd39228fd0d5f72c71828ec1a4eb1d77b2171f65bb4e14c300c72db4510fd4d1aca62ef2260a8a014b3c7212101eb18b0fc78ec307f37e18bc0fbdf09328bc407960f5c850459a20fe17a9ac953874e4b19f75ec9c97287a4658f3bfa60917e20b17df6e662649f665d0b2da3b362acd21bfa020987f9918be06917c1ebae5fb91f445bf7dd1a5d25bbd488c9dd814fdc28972b069240f7c78073d551c6c07dc6dd643af417c00c4a23109083e9d82f68dfb49bf84a92f9d9fc948928ba7720b3ae0a9cb0a327460872a0cbe1086249712c0f3198a37bb1a438683a298980cdee25fd99ca87980551c8fa1d18d57c1658402d0ad8eabb57148f1f8c64f37fcfe613f191a0ff957aed38d7b873675847d4b885b2dcc3fe28d41c48caa7069eb650ab9a2ffa33cbf6f43072d6609dc4d2cb192a43b53fd67c0e549b65f5a0360aa6246ca44db675d77b7fd9ec15bcd1dceb6da84d7ee855ddb7dca7891c44055e4788009416b198f5a82f290533565c18f4889b77cbe66054edfc31efd33a639b539d0814be5b5756c5c06ab84be4df37cda9eae6aac88397134b3e97c0eb64639c29377aa216fb535ada2d86d7d441724b2298e6c76a41fc56250cab16477100ca437276d021c21215452db5215d749c568e9fe92f69a27e79797c95e421be93ae2497971ea1b318e71e706e66f293187502b2c788fdaa9dedddb8f24a7e767df6b4e8734a7cd988d33e52d149bdee4eb7578912624e2aa2d7206178ebc414fef841aaddc77e78a499341995a26e1166b288ee5adfd5b31813692cf0cdd365919fb11b3e566e6cf1003f1f7eafb9326ad6264383fbf698a66ac2ff656fed3c568f1e63b114a4549a30b633435a2f1b6b74b7ebbec9a9add304f6cc55c2976165990ad993c9bb7a86e90e9a3219b64e7ae8c73eed25ce1aef76afa9b7a5f58caccc904bbae8a51af94edff0353799ad64cbd70ac8a371090b7879ea360fe156c46d859dad7d89b1a444d647b6f93d17009562764a32c47924762c99b4f4c53990f7589f3a5d19a5010c3aac375c7b2faf5d1b9eebd6b0234a785db84baf242a99e409205a20c5a76822be5a364f89531195adc7fa4a10aa1beed267181c706371dfd4331e6638bbe762d7ca7a2e0123eca1a32041bbe27ac63cd8a87acaa09f96d6c399e1b06435a0cd80c0c1dda988891413a6a77f50c20e10d301541a989c2a7003aee10864b01019ec21a5b7b03a454b46e2297eed7d8436980a7bd16af924de74e9d12a49f895f8ac759a343103cbbb63f904bb9ac01ac6686c1f80b1f5ce3e1f7d991ada16b2f9a884ea44ee87f6de7b78ed45d77cbc93cdf98b668727b518b8865e9edd9e28f385c44ddd63ff1fbd123b3d6e16da6250172bcfb2d1bd5aff50c8f465fbe3797ae387f2cb003214773f9f162ba2a50aa285d101ead34f85c586bb0df460872bcb969db24821b64f94e6cd0d9d498b821e5d5ae5fb9efd604e3f15d0bc879e634ae325481fd9a401d895812add6b0614c87a28956feda8937944c61fe76c9f0733dc2b5878e7ebf95728c4eac151b80ed0b338167d528e435885d73cbbda79a3f9c0e3d074dbbca283b8a91445b9add3b7b0197e29cd4b52a69c6841df1fb2e6c4a10639d693cdd9db1aef487747825224757b08b9ff3e66d76c2bc1075c40241f5ef6cca4a2fbd5bf161ea978e8cf9943b8970af717deec6a16a835ed3c0e6106c82213d0a3c724c40ebbc4c7041f4e658ecfb5d9a97029b8f1fce55760be4a2eacff5d037e28102848095b942b0c1607bc8b9fd788e0194b3014803a974c5c69d315f2f8f889711eedd47c301b50f3c6d4f41794a01e0b9be3630b0dbb3999882439426c567a15585cdb869bfc4e8922599857789eb86d4df864722c85e0a1e16e544668aedf839576690e002b79dc6f8362827f55a7c9066f69978c1c0e927b740ce3a8b93551d816dea0d7604f00629aa8a3bad8449842b61aa8707401e24a34573a0540bf6ac645cbe5857b141fb559b89405964dc99779b3ba347f605fbb940e4c72f4557761ed73d3565043a38b1d136511708420cefc09a625ecae3b9631e858d22d3d355d055b9cca76df3085b15c8a0d80fea0519a67480a2d8182efbf49d957331954e372602b42a3ae09ea33f9bce9f40ef3e9b3ad6b6ec50880f78ae8a04de4175cac0d509dac33040889ba1ebc108f206 +expected_shared_secret = f1be516b31ed89cb70bcf428a2ba2c22b3919f8a9824a59b875ff1e697095ae2 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = 08aa6ac1e96fd9ea9bf4595a7cd565d91416b583be0c3355ef18b9b4bc1ea59135d3701eed6bb0b66bb320572189525bf4804a8d75a5f973393cf53ebed81a1f2ca339016e35617e77b58a38e15d417043e6174888ea4408cc8583d196042317f3c9571e6347424c032dd459ecb873d7f9312fe891a0a81261136690363b816a3b538923e56741cccbc86d477c629a1713e99a4be8aae2b3516e863ef232755fa0025e40a664b714bb5c8b2a42568d824246d069ba2469ca370c1417a6a632978dd39503e433ac8566708c21ab04924d257e8002804e92147db57a8d39168c709563e7604674ae830c176914ca2ed38b9e793515231b7e15b5dbac4027daafb276099c0036f81621f7dbac5d24c5067023dc6b219881cdb9f290bb9454adb45a45eb1b975b1094aab8b2a9afe05a8240476753ba802c15495c5034f9348ec8c732724c9703e9a08220854a29598cf42b6777a19eb462c4907f0a7b5a3e991a5d7c4d8a70a78ed5cd35dacf9e98c19c596ccc1c4710ec9b029700acc002a1c661c13ba1c25a1d853a851054546c33b1f4032e1f089e9c4c8af9a99c3c72ae4077272c3a37839b817b55a31ba99b66580766fa2180c35a50462c0b98adc38c6ac1d72a7396b28e36cb6a601cdf7c9857f5413d380a1d031bb5801890182518ec414dd78a8ef86edfc0a1f10572205b5593623c41d873da21aa60e3870348032497b367bb50dc6176d415ba54f8809b4155462ac6d34593fbf57fc7d5bf64c10af1ba368d52afc8e2ca3ff8467528c625b26709122c6b1b34648247849338a24005aa9100a790b054640ed59383eccb6415f7a15f2aca63cac12609113d843aea83814691072ab8292b7c5db1d973aa6c7b2bd1a4aeb4bb1d58ca7da26b2e0296211042488c0dabc511308791d7a8ae725c922ef374acc53d76ba5a12fb2a5bb94c309824ee119c87a62f5786996800af28d11e59a83de0504413351651d0209e98b76513747d087333702cff8463db4c353557632c8c46c3667623e012e5d7937f6b004bb549960c5760d15d08d1a4e85c288a2044d1362aba2962d2b078b7854f997abf6072c390342536a8ae8f62385a5770d4752db9f979fa09037bcbae54d4583e17c4be538100349a379502dc69c283638ecda028ba0cb1d21426334c4789715cb39c79cf408c2d1720afc8986de03627b28efb773ee612630b2ca1a0a81239b6020e1380ac69be3cf3742014c52f9b22a118aae7092efe8c93705c0a7a1a8849c0216f776695840bb0a168d5b991e4ca78af08255646000fd16373831f8ed490724019aa15c57307bf06011392859167d0ca6fe88feedb49878c7bb0609aeb604429710db83b1fa592c7a5e911ce795e093a9602875700306d38234e2a70bfad422df30380986533bcec5d8c119bdf3b99e1596a05a123e2d3acca83031ff778c2181f75d268d6aa98520c969306cc80863789724c0ec5552eca57c3d84fa141c69e07b39d9518bcb52049ea04145c34ad355cdf65cf6c1014f511b9c6bb9281fa243000781a99301c06b77ed606c0fa1eb5987e76aa5bb346cc85c85aca114cd0a51c06448c1eab496299515d7a1598940c33c8bc58db4486867158a09080b97674cc9a9f7a176fd5034c139b19a50d4355011e2b65d47ab642c84812c74dc16a83fedc38873145ff3143564c4aacf969f34ba743a14595bb0b5000c30b47662a7b4eabc0980aeca368573550c3148811386ee589a88a53cbc6be1ab2755e58441b6c87e83baba58b63bfd097f0d4922ea7c0aff97143666d912199fc4307a3bc086ab13d6a6481f411bf780b10f5e04a41f27f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9630c2c0dc6bf3987789bb59195f416f8661e6f5395839c68a0d85d13d0ccff807956a28124e47b5b3c9f3aeb9537c3403671c03d28a09610c89c8c6c69d9733b320382a84a6cc2b9407743cc66611e84999d11356115060e6c2c5f9610fa820d18b355b64890b0a88fe784a39ac0c9e539732d79a36832492439944b643436b84d4bc870b5c21a5e224e321a5e7a6931e628342ed4616fb4b1997cb12fe6be06b20e7794437512be498aca2c532c3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = pass +expected_ciphertext = ea8abbfdb194d0c3034901ff96488866e79fb029a7765138a85feedccc7429ed2881a8193fb0b83b49adac508b6d4da1c816fcb4ca95c9c65f4cb761c7d0fe050f60c295a554930abd90ec1fcc151332849b488c9c506a3a704a1cbd74c56726dbf1d1da97d058382b158803a25aaf6229930cacda8e990d6b6b917c222667ee8d1580680f87dee5816de3d2af2b874bb5ecaff31673ee28a02b58c59761651fb776d8f8ed8534e9607de88ec36fd3ec9c041f4e2ea1918ae57a7cf676f381a27e9047e940fe6875647dbb6453740809aa067818d8b8f1e1df6bbd2cf8f2b1e3cbc7499466cc41ace193eda019729e4cb451643790f30f5fd05887ebe9e4250bb47005133b3392fe282bf569a6c69c96815a34fa9af0db7ba1cc8786f7f8ae095463601783907932ad5fc2e626b72217189b93fc390556f06232b9a5ec5760f4069b15ebc878c3050360103faa7355e81ea267094e9064fc550e0337462bc20bc511c044065dfd8f1b014945bcd9be4953b4d4b99ffc633947b0b19b3feacab69cfbb261d6ef365f9802e7be7528d718aa353b05a49b1ce782f8370852ec7589980d0e2dce9d90d76010ffa317bf50b49ff31ab4f4828de281d75c3644e63f383a91ccd3a2cbed9df8fffc533c8f380c80e6352da9a36527938f227395f38d1db181481c65e3fba3ff787e463b241323b05132da8c648b4c8e257b8770f5235120d1a47ba2e68fb5a7e3b96770c57cf8b4f7f86f568cc0b7715d584ddc7bbfdc2b7ed559b2ea88e44ef2c2af0c4e5c0686f37769474b4c714bbab23f12ad0f232777d528c2ee89be7cce992cabfa8aac02336f327c2275b63ef927b010bf29ee1ea7b54476c8a064cb928c3096fe722f93408426231ce9f59f8984caddb27e25bf2179307e666503de33dd6296e312c2e92a3f05af31e81e5ffd1719298401dd2b3f104dcdfbfc31f06cafd0841bd319e50434a7457363947e6ac60955fc8cf2f02bd518b3af0ad77bb6f0da7bcda27ff22d8203d5b3bac070375332cb42d6ef895e4c48b47737b607ed9c1f86de6f2c251683708c193297c353b9a2348daf4d35f4c56a9b87c70f6d32ab17b15f62efab893eca7d269c5505f229b360c604230fedecdd732c0fde78f5d7dc6b8f61655e7eacf9351cfe79ec3a6880f84fd5d09037562c7c30bde8b7db5e672f4210111dd773e27a346412c9a32ca6bbd992b5b7dbe0eefeec512d8a1ec547a8a429c0033f59999eadb257e671be8852095b487e3ce21dcc41aef7efe8c520c52d6aad34451feaa77da8a18546be3d5bd3a24a15c5a0efe090d11798ee1c378b181bfa78b9c79f9509ee94420b5383c51e1f21ef30f95c109dcc534febab2eddb8438da19360f1a5a9ad80e3bb4bdadb8f68d23db60ad9a948b17682ac706e30f64eaca334331f6e9f665ebca0bee9b3fe153437a6356cda49db7b30fdb23b55e0b52ca1b54a115a179309f4763e70c7edfe6fa8cb28d3ff9259397005d4ff4d23915e5698df64c19ad60f24163a4d0c03f682bbae2864e5a446a5ad9bd4cadb8c7e02e8ed83e646ddfba1aceb34eba2bdb6ce854e1aa40b7e75d5a365e774e1639e3230b9f6a4b25493798ee0116365687c13b8be2041c37d81007c66085625143a0b4776483dcd25f4cbfcd42894963241760c1d66371c21413273d8a3ddeaab5e9ab5e00cede4547a3442065b057a7011576a52e4f1c5411d432e94a516532e881a28f3519211e58c25acf0200c8a55f272fb190bdb8af0bcfc4a6867870d4d06494e6105ec386b970dd0cd942853fd98505c4c36676a1d3a986aaef6401c7d31aad6e425ad2047ea3964cb065e714e35891ab5ef5103744d43ed6c4f2f0f563ca3295f7d9bd58a3a2765dfa4a04a055b6ed1a610682139ad91def5a5e5545e526b690d49356b5b9c565501e1576e3873780ca61ecd2b6ecd89f9fd3384b18b0d5f90742f4cefb0516013151c77490fbb2621ef28bba3bd0ff6252d363c224bc27a5384c700005fa94d93ab17b5733dfe45b60fa9bea0168c617e15e37f99b538a9d4b03403913c385a963f2eeb46058709b285aa383b73b004cb89e5e735afeab81bd40d80b7ffd84df84a1bd414762f8312b44f1ffb2004194b9c34f3708059eeaa9c09cf67a98d7a3a35e87b9e18af7afa188c9eecb0a1d5e048b514cb446d6a4bc30e96ff244f07dca9f290699a650c +expected_shared_secret = 6ec4f71386c0f0c16294e4d76966c69c512d4e5e00a6e05c5aa544e542454225 + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = a936ad0edb0ae5a6b9a66bab5538cab0ac6e0430bebd798c474ba1ec345ea6d3ba9fa0377d46606e70c86dd1be281a9f46fbc0d890c607dc009f46b459958989852b5582566cd30d02317cd4e0b84e6b1917e692e45c9beae45bc8e8bf6a65587f206a67d93a4872c571200bbde620e2639659302068088bb2d8bddf33c98ef34541b4c2a22897815b809b060f86200aaea90376234860a66e9e8843bb52ca7033010e47c41d573fd9ba40c4faad88026eca797e80396a2ed5586f8109a44bcac355117a7a3f72950030cc506482aa0ce39369bb350fb07b1388981c89400ab5a632c172d159c6f0e126bec96e17c0c18c615be5110818e0cfc2900f76d706aec990021aad6eca787b453991a896f4622537051e3e4a11a0954995525b8f2b11583a3a3e594400ac97b82a4b5da822891910c721ab0bbb9942f2ba777a0c5d8c532393934b391fe5669850bab01740905b684aaa96be0cf50df463406b91a28149174b555c742c3f78569bf294681ca09a336531edb94bf30459893cb2de348330fc56a7304ae2f7cc33d13b7966751414420dd089a48a6036c1cd7c5608727b52612864b63694005590859aadd91b068b053453d1c6f9287c58aa042073087f7959fa932284231b39aa991c0523be599ce85b1f0fb52d465156c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eab32960332860e2a25b7a25e86d0a7aab0226e877f0488877d941fc0a0541461b8a4744de6456df6c5ae6c621a969a02f9c943f68a48809328a0ba3892d7af2fe169ee41554f0ac1a3836e151760c8472f60b77e274948ecb6748c404a74005bde6c5849401fe2d667748b9f3c19a41d659474b0b4a6829d848a898b93080c66aae85b3660d392f34a6ee9c6b10df567dce1892f4932b6babe31e0a50f8217985c6537188b817b3311c25e8c63ca265b568ba9cfdd451e6fd517e18317fb99c8204abfdc937134e845cfe00018e097022997653a8d5be32cfb07b34836c242b74ef9d30ba0d7ad8c2b2944c766c025804eab23a05b6fe6b85d331904c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2e70e1a63815c760da8195bfd431a9fd88443e26dde85c5b08091cb19349cfc73ba195923a38ab6a044d1c9cbe498195c1b5a27a2b07b627c141cac61d391ff1b88c9893327447d32234705d42f10374b77c86d83d71e3711893188310c45c51a5473003d8566d87fde99c67b962f6b4750d7851d3b6201a2faae68fcb1011404b252bcdb341e68702c8dd6a237813e049c42aac05977637cd3c81103e1973f6b45b8b0b56f69afffc9cb5e97bae9b6c5809abaf47b5b0b20471bd77ec7455e1dc25fbfaa7018e58133a44678083c06e06334452890a35240526225a33736a042b1595da8452c2eba086acc1a6cba45beccbdfa23acb2f01cbeb75ff179cb39242ceac33eb2889c4784cb970938ad336da5dc013aaa2973043372cb99657297e7ca05702992b578a65c00c867b43eaca93e975695f7625aa8240c0e5827e1636d72ec4a0480408f911ef631b48a1c4462665b230550924b23481bade7b43a1d76cbe6791e33874182f955313cbe69bab35aa59cd1b133fc326ba571713a1c4dbe2a662b514021bc7bae44343f39138444173dd7944c6291c50973ff0b9c0aacad9409881ac232306354d5362537b507e2ab84b4a0a3b5b9819e62c3b6dc1fcbba0224b48da7114dd4fa3103069caba17c09b7bbef8b94b6e15f58321b708c9c23a40288708ccec56f3fa2bcc7397101fb9e54fcb7e7e816f149356570a006f69779fa6e30b1310e6bc6d983599eb81c202c5e887659f5e7836fb7a72eb80474116c6659c24dfc4c38dc2e8d6a0787a3b6c170a23ba53865a53849f4c3f25b2363e582bdf079793bcb832878b0f7268f658b72b3417135684393a4b1f40322ba7fb147416ff0b58d3b62a7343a6c51b4c8f6894f0b05e33476ba24c61c276652048b009ccc1a768e48cac707a42f4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2ed2429d547b4da5176a7b621a38681ccb3e72d98f1f9926b1b30325d6cbd3862c7d044dc16b8a25dc59c2a53e295040d7627f744bcdafeb522cf8ca6eaca400106b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = pass +expected_ciphertext = f513d8cc0665dd76133ac4e7ea22b5056763fc59a9afaaf2b4f583c9ff4347a2b3dc968d66775ce0f71b8895e79f4925f984d20349967c0259734e87e2b2dd59f86a89c2dd4a7a16cd8c67c2ea4c0e863c0b6043a73651f0a7a927399ae7bd4a31cfd904c2293cda2f28cc16a3a3d0311e044b55c8a6a89e147833cc06b5ce9f9f8f745e8ed3e3499079d480c81546ea970ff389eb49e29bdc46f852732ed9cbba2cd47105d6b52c812d91492fa750556e73ed832c194b9bddab98e76e8d939b95984397da789125212bab18dea5ae3c22cdf029f9c0250cb12015f380b33ba45482bb10ebf412d10633d74f7e7a7f63d162ca1c51c14d8799ae2234b2396f38732ad355b7a173a7cbc229cb9d252f7fd6c5d09ab41d20395e5887cf586c63a21d76a4e3e00413bf0af8ac22378f6d87067a3090dcfd60d242719f8d7bce6a281af3c29685c453354eb4721c2ea92b5937742f0c68d2d2ca30fb459153e7a371a7515130c20ca816ecadcbc4ff4969c033c81e52d9249588e854f063a79d6aa181e31ff1cd8eaec38119cf051e84351a3b8570b43dc6d921ebbdcba47f30a7a237e3a74de67b5d59a7f06c8b6fb13e810a9895c9e4bebccd649793ace6f226f3fb9f04c39aeecc9a7f0c5a8d82d862954d7aafd945702464640ba5c16c4df0f1b9122f9dc6942bf9ab261d7b65139557e8dcad44ef29b5a96557c07a311dda243b4c9fed3344ca0b647617eef8d7fdd3942982958d599da0fa786b40b5830fb5e05e32a0d6bfa3141905d4a1b99b8dce6d0bf53212b72454817239dc1d4b8431d4a2acb087fafdb68a326ae4c28f372db791a9c654a079a1d915a25e2dfa117af68d9e0a8f624a298a390e688cc4e8356dd52fe42569f796daab5610c7b2ac4bc7e1e3801c91a49d420e661b9432d930a10dd1eaa04d283e05b3ec41f821cc56f9bfb1eae60338ba0eab94f02d4dd043eef6d6c651b4efc3fb3fd48ef2c420087719e68a790e1d5a7e60fc292a0be640993327a68e5d3423c6df76c51bdc3a787eb23b11a49067f66d2cda3bc4d0fe7c7235b75f00872647581b75afb0b2555e85b8455a0298580e4f0f5b20c57503f2bc541549ba7c72b9d24f28e4ae3f9e0930bda648a243f5c4f473f87d3777333c7571c4981c081992fce9755daed0a97fc4261ed48af7bd55dbc7172a296488acc6ba32db0c3e277c7785e9e78d79509add74de0d15131ea9d1a31817db156e275cbf3334b48c39c8a27387549a92ef80aed8a830cde142ef9109d0c7db8da348697915d91e0bf0a819657c1521ede55af68dd1bc7aca0e7c0feb04d34b89b93df3e591e508ac7f0e3cb4ac98e28d207f2a105a4779ad594af98ca35f1d4b9f2f6babca73ab0f33f4a3011e81d6d74d183cd9eb33bdd7683eeae9efd5f15d0a847db8464ce2d0510da5d8664c9e688a58016e9203f7a3e02eef0c19204fb083f20cfbfb574a3d7b5af99b4f698f0c6248a1c2b1d8989b792abdbb4cc14d04432d56b63f99711e234c3c8fbf26a61769e8f0a251635f0e8faf0eb99a0c2965f1b4ba9804d4090cc5adf1a8c5f9bbd1e7ff0065296dc99a9e6dbf5a4e0dce4b5538b0f1c48f02d0d66a77c3a0c1bcc87b1353a83214218d0be833f3caf5abb13000682b1148623c1cea256c1dc7becfe14b698cea823e58378e1ca704878da44c7a4364a8652cad214df0f6e7be10423f308ec0422000f911bc7c5038eca2d155876da42da83ab23b732251049c007d4f7e1ef7bb35aeb43dc3c730b8d70a9e2e04e5ab0cb1c31d5dccd158b1977208404f8405a6f7a0f48c29768897519f21a8bef1d0da7bf4512d34730bf4cd1fa80afb5034d662a6ac860ae39819d82c6bc7886358a15ff8183f6f3f76f601a1286ae7367e82cb7d4a5a7d814248bac54ad36e6624532536c0f9932fd88a5c79b5615bf42ceeda21129ebdd38297149e59df243500f6453b4886acb80ce1c9ef44ae7a54c8a6e8d4da7b9c34c2ecfe206b6a0537e63749ddeadb645fa1f937c9f7d19acc9119462cd7be43fdfb5efb350c9f59cbc12995d1428edeb0ea90582d985ed0381dc586dc5216fbb5bee11cf8547499f0783c318417a8f7ee101b3f01d99d489876ca4e094f8cab6f6158daacfc9f21e830e798d1e7fd91329f59344ed126df11862b8a355d1b7b567e5676d09e9a9e3dcba5f42e7989a761c26e2b391a8470 +expected_shared_secret = 464274dd39f2862a97833631ac446642b3c3dd6467c7d2404aaa46a8f5f65b3f + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 6461a7a463b8e40c03739a6b5fd196655871adb3c82ad10fb2b2b538e61e1b664fbaf761f09b4d5e358b518088b3206e1295bfd0461a2ff8553b40cb92e36f0f928af9fc7ef54c358d88280697ac3d5548029c3faf882ae2da732e0c47934b9c98232c40b84a344421e708226ca6524c062302765bf4d593e2d75d3a783f1dd7328767315dda868e685eabc18fdaec2ca8b037fdc3607629cc3ecc8e848c771b94c6a20a28e3003778ba68b923b711060bb6152554707d7e4c135ae8663d87643ec4921c6a5c20ac69e67b0b795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e7b03189abf9b4a91eb782fed97bc3a6314d0ccb528b313d165b2910859de867d7d6290bbc85185b0201561af34b9656a00b2ec32323b26a04888786f81007362814bcc82862a7280a5cee73a330e6c2e01fc9afe2741b12166949532c884ce8bf2281aa4b860756463bb49bd1524b8ccc6ecb6051ada819865b8bbe1bb01141b77fa3ff5713f95baac10866303939c07483b6bfc500d61b7ad494382c643e87508e410c30fe96b37960ad4e707421944b13b31d6686745c52ef6ca4fff3074f19c1695038367b1218e8b08d8e6180870b0fe5b5511e3b4641b6fa44156c561aa2aa9a1e163aacf73c24d84bb764004b3b329ddcb0f15716e17c51c6c432ba1407c0d063b0cf2c073763a790cd0312abe6d26b0d75390492a88772763fcf67e1bf28e1a01c0a5714bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5e80acca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f052450875a8997c335ae85d5b790377301f5a094a5b43b515206067e36fe51ab9af296583d47450a34a302844b0526a4ef891d01c287602453126557a876c583c2a06561a88f9651e39929d0b43fccba48595925c01adc0677200c39c64e44505aa58a9b5c88311c094dc3aa5314f167247b501798c4a0d5d9a04b77c6552369542e96172573e727890fa3b2e3551286113221fe92f81c481c125bfa7a6199ef8c0eeaa0a5b8973c9a33807a464fd4a50eb294741c5a8fd998171872c0fd44ec86112e19a707dec768f7245dd2a6f60a554490947e5152dc3eb9d9e7151ff7188127b5313757431d3a41c673e203c7e8e9963d0ab1276b5c1114c38ec8cc0ba0a94918cbccdcc7dc5366704415cd2ab9a7fe55ed49498b8b7105fb312f4a153e394a019749a23dcc180236468a47d96d47be66a0cdfd16a2dd15aef826041192b8028b1ea782fbf0a2cd5fab19011b219099f8e87c74cc69841f4a927e181e98ac6b3db7846ec38c0ba8aa9f50ba7a423a474060ef165299b12786bc8c05a384ef129b0f6c06c1047e582c02a54aa8713422bb6b9a6a4195fe6843d7c639916943b5793107cb8e63365dab357cc02a9f1b33e8da29f25f9839d862285864ba790bf965292470965e0a9c1d1f65b72139908d791a4d89e489a983279a703a0c34222786e123b45c793c925b1a146c006f15fb4a1c85e181f8b1c6983e1a1d7210c12091d83439ac8a15d965a386be47145bb946162cb8869b359654121092d81947ccb5717e805478a7c0ea924692b361ccb730f3180c8f79041f8d366757528b0828b7ff9531c76690c37cd8072ccb1c36a195a84197a8797446273d686aea96fefc153f1710d98229abf35b6e6127f2e5a5c9e88a33a85a1006a1383988e3c72692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f0362c1f84954408ba3c9284442b59c1a4904128c0bbb50b2e34c98b819a1d6793de75697cd814ee162ae3dacc0d50bade8b835c3f27126731d2721ab61802f544967df987b5b0b02efbc95847a5f06113737e55ca4db20c4400580b5c241016b50db710d7555d8f67cca13b2d86103d3870d5713b217d03b3984334a6ca272d43911ec23db3b5c15139efcd510a95c96d68a70d2988adbd048122678ac8a051282bb4fb47d6d5819a3a9866571cf53b78ed80a76ffecc971b221bfb917bc69018dc0177468357292495d98a022634ea7b0b1f517734ee40d0e927919221ce9eabfa05596a801a342b87267ac9047129995630271c1c2f02a4d1af2217b65c05609b8745306b6a90f86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = pass +expected_ciphertext = da9300af63d3c10ab2a839f3a2e3375613529a345f92182ec42f0212a041d741c6b0963202359ab3e443104a935086117a43bec2bea7ebb7e5f6151c39d2cef855c2f725ca7d4f4d1ffda1752f834636baf6ad31f4245077683ee725316bceae73a44012afa9e923e851a93a74f32d94c47617bb7cfd1f659d81b1c0e8ad2f3c5fa54eef5aaa1b763c573a2d1298055ee6623f31694078cd0a4ce9cd047e2a591377437741296c28773d4d711d7ee8fd4e5b376199d42d86482dcf9fc84af2354b858ff6ef1cc3692ca1e0ddacc17ce13c739544002cf8748dc3ce62418941533da39cde819215927fdf87c4e5f9da167d03dd8a1bf91c89b007cd0434b045ab4f09dbeabee5cb93aa90d59da49c1347d5e9464c6a07c1546f734852f486f9b06cecabc380bc09ff888ee90c4093eefd9354658a26270c0c4f5ec4a489fe6fcdc55f872e9f6443cba943636eebfc49c801a2434a16ae0edbab19c3da71fab90f2a48452532a914ef0034837cd1bc08d9ae64ca3110822aab9daa043658f666f38a913042db83b1a842e463cf9dd42277be70b240b2c4563bddda5d629913815c6c7fde5bac736151cc3a39c773a55190de33d233ada200850c3cda654a37adeb5b643c8daa3e39ba68edfee6ef904b1dde292fa197899bd5455bedff84bd504b48ba00beef905a1cf8bd512c79b847d5dc4489f1a3c0e1394a7edbf4468e8d1747d1fa9a877b4a06580e3126349312d28865c81d59a375311e081497f9fcb6f9ba2530a71ab2903c52cc7707c6269d3ef67918ffbef0aadbe002d60999a41c8634d5ac8e84b4bbe5292fbe735b58ee3bf8ebda070b58a5a699984eb1a5e15c35b49a3ac58d23cf8e472ee49a2b26ad0ad3fce13c18efd85e9fcd455fea61d135c2083b792b503f43f729b27b02d30864e60a8702b749e91c3493872a15d173844cf30cc9eeef4e2dfcaa7e8c30cbf5a72c871201a3394715ab2b0940ace5eb1eea0ec4f4f4e3db9537e4f47c48d48f0247ae78844c575443abd1d00cb5367586f512bbd25fd252a893edb265867f9ad24d70009f9a9449ac0198de1c496ad303d2905daa97b57cfe044cd2fe94a1e8f8460ccfda24b119d6190d80cbf5955148b1d24204029fe471b23df9f0d67b8ce5b67e7a3ab2b843cc07ddee4503d3df4f3ed5ee841f50101043ff92b446d7e3f651c607e22fc306c52d8e49e924ec0c3bc3023a54f6298da4a4cc311ce3ae5b771630a203eaf010e8dde0c302da59ea4b23f60d03aa8d64f16f188e21598c4e50381eed5ef49baa947cc025c7fb508efa602c09dbc7e991ed31f48cd9121ec4699d2f3f0fc259254221f9d40360a15513b292408e04a0d33b77eb517c2438439a9890326a6ba84f126d58a007f7ca0063bb1373a441f8ee3356cf281e2eb75b941818ff5371973aaddd6a4545b11744352a8a02fbec9f9c2f73854430ecbbc6b86936b63cc3e9cb3f5d8e608888005212e5664c14180d6cc1c86041f7c0b3d6434b1a11055c75e3a0c528ddfcd9b7dc81c07180ddb888acb09b338c1d4c905b5b2586581c0f21793b8c788d57c67a9345b3a66b80fe6d3231cd5e4bdf7a50a54dcbf3088fd41a081e8d9d77d580aa8a068fda445cc272e37eb6192fe4b0cee1edcc4e450aad693845c2645f26576320a82a4a2ff4b67eda5a25a401c50a8ed9a932fd2c114b3329a98fbf2ad9a9cce4f2042668eb406aa07c95b0c30c07c67f7442d67921b177c1da33d6d6118e80a1cbcd9352facd70b730a755c15e8ffbcb24caa8bdc2012a0224dacbc024aee430160cbfa260f631aba1271756d528319e699198617669856bbef5943931bc23b5a60e34b05e95139ded9d7b69f7d195cc762bfffe968b5fabb4782d4032707957da5e324d7e300fb1be97ed226c4bb2e518efe1eb8f828fc7b0851be18c8be61ca1f095ae567cef8ad9f5d280a33979d33cecc7a09fb2e9d628d91d498574b46379c9f441de209ddb44402479c2d5dda5fd4cee0b41ef34ff3e1f937f7a1ebc683192b9265a7a92c805f3bae38b5dca4bce307df1423a394f54072ce533f918cadf3a8161634b05746dde1b85918debf842c71c84f43c5643bcc25843940761d7ab0061118c88febfa6bb6f859e74b7c338c58b0ab741f5206fc9bab9692d30f39996571e2007ad0967d676a8b128d9f6bb90f80662f3046a46dded36ba9584c853 +expected_shared_secret = 99dd968e1f5c94c6c4d92e7eee393c802d8ea4a34d39de2048eebfb21a0a4b9c + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = cc40bee26ac378d8b540992eed54b23676827aeb4bd44857c2c21d55d72d0db795b0b6c8bc9077aeb59b71588abfe926f7ca57d305141012a41eb063f5281018563eab7252c34aa832a4bc27dacffb008e6d255cd547a0ebab65f410035550297c50b1a637cdef9172b6d4ab96ac598ad7622c34c3b98890c77cb9a5a08e3411a235da946c92a81d7bc57998175531b203e21e3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2991def527fe6c838d3e1221bb7a48cf7a247895dc77328a07b8c342c731d24ca8a83b9cdd7a47025467aa81bbb0878ae5c8e6fc0ade2f88c68a328fa132a4b5a0298ac19f46098a451870993015360093bd7b0ebe3929a028333312361e07a7dac8c90b50019e73893f78d097028fc5714362c41dd42c4dd71cfbea58e5aa96d82b03f5ef65d572957ede919e094a70aeab998a55ae4b2988890c88ffa1095273b132550068337586284976a30b0c538474a25ec076960d1bee0620a2a875fc53054d28042674b1f51b7877629a1fa815e2ef578afe936dfe5c7cfe6472ae7c264809a3a1285f6a156448246e4e832c75439cef074f62bb4ab5a4bebf24a129c046b0cb215552d126c32ea74088a2a7da6bcbc380354a00642ddf9810ca8c0df8296c55c057df32a4aa14f45192846e31c38919185e2c77cfa199b2003b80a5d6a867cc6764fa4b907646cb923e39bff6a14f335392363890cf66a10026e7de62d09daa31a50a5458515dee1ac7e092dc19ca6ff506dddf67aeb26ba4d720a92310fb942581f69024ba975598c97c41a6112c812aa6a21258060badb32dde0a5eaaa4fec6983776b1348c06a7877bb1b44223cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a277625298f403114a018b8b78af433a15a69de14158657ba05855bce24402243746de13728b4c4359409a282b994f3053777a72e6c30686eb0e4746b88ab57fc9f2558a1a0820c59c2cfc801b97b0206833d4c389e415330ab87ff870c90f86218c3b2c058b97b1e595f87703f6d34118965cc88423e3bb4e182210c225902fe3229e4559ae8a231b34395989c732f54be1b90b3f846adcfb5a36089f1b057c70931921fb36207966666413c8998c509a6268a6bcc1271ead333060d9753820a0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040ab2773976ea3e6876590c152c897d59543fb576e6ba22f9b312995f9969c91cb9098aa2046ac4bc69a38ab5c7a206eed57514de7821e64aa6626299c99b2a7299dfe933ba386a19ee01cd7a24db661356a19a68f68018a6847f56c0247346e294158c36c3da5e51af8604c3ff26014648f310977ccf8bfb36316be8321c71a4e1745237f964b5df9b67f8699454a810fac4fc83493aa2a7e4af61728759a12a769fb751d0d2125413cc0d4e0b5aabbb63b8c8ac5d385a95094e0650d16009da134c36a7c8a59ba90260b9af69542add7a72922c8dbd2b9e1dcbf39e6b19a4815d1544d31547f9c336baa44c835805c1a03610c0ca2b33bc44557583da206ccdb50f1c7309de949996ac72fd9803ec5bb7a151fd8f0b4e78008e35c102a33a9412b40e4b7a247864277bac3c1409006a75596d0cebc52621e91a7af791672e29861533e765257beb06fabe44c20f0a44a288c42d22851433c2be639404aba3e6b356c4671906a375894954849431f71717dbc1a26b19258db8096138cf83894182c88c6d9a56d718f489040667184ad175ca0b02ecdb1b5fd0a2b785197bc696a68471c9b486d7596657318bfd1f46aa29414c436c0f69252ce96bc09837cb4325903bb15d81b3f5c62cbb8dbaced7421b4361a8c196601b002f79877158c97bbc80072ecbc8b69557a4c60c8e90d23427dc7ba806ba6234189bd874c30ec696710c53540f74bf61b2a777606721952f930358b55c183db4f1ea17a761a0cfa14c55ed47cfba737bc75725c3471aa8b563050bd424512df66b0684948d068b94765adacdc5a24e18035c5164c54ca64171143a023a7a07ad8b5ce3aa095c7307eadd6499d89cceffb00f635334a3c91785009fa6a93c1211854882e99b7a32306bcf053551bf99f99c8a458106a55ec98a0c06c7c58583ed757956a89533c6c7b2867b8d3a5fef526e13abe818919fb03a7f9f0cfa9025fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = pass +expected_ciphertext = 5c55a11405874e124d98ffff57d1de80e558b530fca5f3b32e5a1dd9ee519ec1076b7a094d98a00689d20c2f9d02f2366331ecf9a38724c9535f5f28756c1ad9fa29b326deaaa3124b20e5c5431346405b624b45ac9b9d307b07d85239fc0babde057cfe3b149ddb91db18809727ace779d5c282677fce653180c032d650e5de3cf70f190723d3effe7ac29def3fdd3c6f24b92bc574eea5fd3bec978d94bb4415e0cc952cd66f09bbd66d625845f9a854b2008709dd1bf5a1df212c35e3b646dd3f4e79559ed2612dfcff7c7ec48e8be3acc1117e1cfc928249231d6c3e1e032e5422eedb5c4473147fffac7a9f536e6242a0fb768c61abfdccbe15e84f1127752ed12d2fdec88546cc3225db71edb9fd49ffda8470b08ba0673deef35f2c6f85ffcccc8333a4a4853979dfebac91f41af523f285b21bb23fa098b1687ff38bb40d92fb29520220b9a9e146cc8ba13cdb4820180caad1855973a0b589158b16b62e01148b4769f66424e66799e5e7bf50915e04fad2b709963a3e514c3273aaaa4616735b07672f44ad93a46d2d68efcbd63663f6dca1656385fa9c80e1d7937eea2a6a957ea5f60816578e90f356deb8aff0977c9a949e27af55231de9d61b6071b73b9f75d33c2e7c3840263b51919a6716c91d3b1f5ded6a6aef9d5ee539ce176020392148bcc920866eb5628a2afb4be07e61d21dcbed1d13d4cdccd25042b3ffe919f06ccc7334b78d86f157d5241af54897e89b7bb3b9fe1e27f6bf48df6e4cf9548f55214722bd6cc8bb13b158e1cfdba4441f469b9d1f0d22c3c57608be47315e2c907004a075a135e84d72e66d2c5a951ce5fe0092d717955b169f204242fb05d7c2c6a5c273f3471cfc2b1179a71a9034071668927d8ddde3e1f7a3741844b277880e9fa9c4338ebb147d2ed8de148736f4385d981190e2dfe70af1f4412478facb105a0280a2106b3a0bab252edc4e09382cefbdf79178f29c4beada55a936da110cca63e9ca18a4a5024b0225b4f4e30b47b494839b4b9905960d18f2b9fea9df5bd807f1f53b5488e487c7ca8339194d2c6733a07cdc8c226160c63ad4bf54c0ba2e9b7db082130dfa0ccc95563b9d25ebf54a2afb0b9fcbb3137e881ecec27ab78dcea4eb25b333c5ddc6b6ead196e948add01be8950cdfdc12caa7d741a9138dbefa1d09a5ca0ebb309fb7ade75eb07526b59061c12419fb309cc55f0f0fc5325dfeb42cd91585dcc189d07b3a1f460f907feb69f073d50086e650230f55498dc4f3a34867d7f91a64ec760289c209598f9a27ea49b841d7cb5be8a4f3373b3150911d3c09e53f54fead8b7d734c66f6175ff87d582f4394cb1984de474f365eb8ac8c9fdf3cc0c406de7b780c7bed74652d36077bae4e899b26603bc24718671422938e50fc5c6d7e5ab55f010ddd9d9e637a8de4d88de35a40deffb060636736a956bec000977729365385b758be15a3e86b7f5b175e00ec39399e5e2e227dc4129adc4f4a04dd0e80b74057d0ee4bf3c716ca87954fb0d16d55cd6d8080a9510c185d0a62f2a9b09a7978513ca0336c66c34ce7c8e3cab8f8c91f85e90796f7f71bafd636dacc005b38b9f8b3b81e21051660fd5fad3781f1d4df1753a658a4c22a9c89c1471bbef06052413034b25a5ff7f42a09e808ea68449a17e7ef8d0e8f99ec528931528f35db90d7b46c2cce8fa40928beac45d09685044a9d84ac56659fe0fb9cd889ffd1596585af2dcbabde87a97745acfeedd94022edfa18fed63e0e3f757ee1f8db7cf25ebe5f238ba9682de4faa5912f1c9c292e12ab59c45f01aaacf8b3ec3a461b13e723b160c69ff98c5352f00eba151d43930339eb52d0487d801a34e5cff52a824a5965061aafb77a58dbaaddcb18f6b403471f5c9819acdd4716b86bf167131ed5aee53311cb77d3fc4f1ace517ff7f2c430f0b912541fe35c3a8bfa15dba69e8ddda522b46b5cc0a74981ab2dc2a63755d6e1a17780d0cb003eb938e5a1b49b2116eb32abef130f86b0ef2166abb38e88106762dbe781a55baab6e2d6d4a406abd997d54529cc2ddecd0d4c283c8e2558b2c79cbcd9c03f08c9e3a0803083bf6cc50b5ad358214723a67da6ea2ec99f5869e01040459df692d1011c3ea53a215fa2d15d11611187bd16d07a9e9a6de9b5f8d30ecf08d503943e374fbe19530ff3b44c42e43b755bfc809a58b4 +expected_shared_secret = 0642533fe87a2913a37847843f7336a0e4c47f778afe5cc95433948a76ee7ecb + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = 5993b3dc543a4939519f942b982aa75743861387558fd01f3066af48080751346618e25c2501979f70cbd722528c713e9bf1b891043de54424f7022e45cc287b7a8138c842f1bcbad18795a382439c5c470a91309fcb8149039d0435b9b80a0773778111134c104cc5e7bbc455fc0f4d157f2afb40972c41fe85622825b5ac48c0e357cc2d953140015bef5cae1cd2bf7519398b610c9b191fa34767ee67880fd9ab6d5782350b176d3a7c318714f8208f71c80a1b189bf10827b763acf096b49cc5c0b2a21c268a6c69500ce889785825438890a6e7e399ede411d83a53bbf81fc0b0b472692db25b69396337b2724f1425aee7296fb29a399a16a13ce748995806cc5c64ac87783af77bc05329ba849a086304ebab9edfc5435b55503c2a6f9b996d75359e963077f4a88ee2e259a6b97635a3bc8670b9fbb94af2fa3046b51bee299bae327f1519ca170a1aa443ca323c1d336952a3d2342d481b10b4752e34c2f03866ee8c8508a77a4721c387054cd241bd54b8be0bba7be18616d3b649a452123e347f8f52c0c5ba2d9fe7560ad88f2bb77622212dff7474b2c250b0341d9ce6ae52dcbac5d3b99807af81744498031477b6178d4552d3e813483c3c6c4a73dd111e7874b7659b29db53946538cf3b51bd53d63dca591d16043469310c512cabc763b208a19099fba9f82b445c05bddea259a0156940e3099d97928c8079bb7846b566b4770c904b75b430151b3198bcce1830b9b8cd5381a1b255a880e49865297a801291f491201684c658d288ec63b8e6d423c4c9091f9552926253876629266969acd09a8c896ddac6bee964832bc0952b98a95ee54422da547ad9174503093835c74693047d782829f06327d11b6a646ae2e8703c3a6bfe9516e71915e7294a2d5a4ec8406792b55692c5591af95d3e7376f6ccc58caa2ff787a126193175162e6a084159e957d85383a0502bbbe091da6a62a7ec4441453306f74c40c483abe092a36a5876a60e1893c8c4fb3dbc946d781873d49cbad7ba431ee820f6e0246b5548f045ad65b0670c341d3edc40f331b59740ab0d167e02fa36cb23b10467084a63b9f1facabc9c86e6511f8cc6928de03913001927ec47e6b001264c9629343e10f945e4f9065e3985e8b4b3536b1aaac91a02a7b701c961a939388f57b310c4652d7649d604a0a7006686c5c0f467486e5248dc24be13f411fd524a6efb276bd75875d5cf7a18482dea41b4579f168486c3d87545b415ec495f37185b6762b754194f3f415f82628ed9884b658465ffec83f5213ec15264c454cb4cb46106c21bd8031d11fbceb50b7d897aa771748cc2e5a23fe99fa91347fa90c642b5410c2c4382b0a498f479aa94011959328eeb48e8222c5ca82930f5a4d40a7460a827c756c28e99a88440b0ca206241f4472c06ca74d48a5f565b8a85803e214f9a6cc92ab2b80bd16c0c5725a9c7bfc6067109600d8142a8bf681ee32b3d2bcba3ea21aefe0655fbe06c0c0c6b303c6b2efaa6e8e6b29fbb86cfd13c6e143d7b104ec625a6ab2c782bb88d4929ccf7528aee89947ecc33e5187bde373c21f2ad26252163a48bdfeb74841987e797048b506c8fa6c60f431294ab03ae304e1e64a1489a05976355f44b6bdbac7b81d2b003729f9ceab9190165677c81644a5820d8a158da62ce19657e947170472e67d87fc5c526b2db8fca728ef881198ff809b80bbb3c1652fb9a51c42aa89ce96844721a9da7274d52050b106c7505497629962b747e117c2970948fa1e6bbef069cf4da83314083f57455d9b031639202351bbc4631b080f936a1e017810632bcc19b41ac0fc7939d5bc6562b074eed4267b9f6a6d110ae51f2b6d9b39f46061031573c5a10c2f23b6879338889e05efdd4424820cd98298b59dbb720a101e8e62887303d5efb4ea99288199b54a3caa85476876d969b2ffa0b72754e85d3979c17155d784e3ed0a2874cbb9890b4bcf6334c8855f7ac45159a18e4f29ff5d8a5e5f34142c01e3fc53a2d07cc7f6c582718c434c062383bb60d4c54dd07a06d2642c8ca4920d5b7fa723f6f2540eaab1385eaa17b4339b8b3cd08f60e5727045fa947bec4c6e766b850f86b80d2b559507137234cd9856b7310aef4f50034ebbd5336c026530b5ff525c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = pass +expected_ciphertext = a5f7dc2067f18ae678977fa4f0138e96fefc96c1c9079b1b5ae3debab2464eb38b217d051cb15d87851322abf0e9256620d58f3d62084faf29daec595cc4eb768299e4c83f283fab2c58dc0a4b77c3672e14103e9721975bfd6138a0aca1ba792fd7f93699cd0c2196fb185ffbc8e5ace4e6192c1e431b78c88c21186f1c74747c4ef88ed223b9ceaa7785b94096e769ff0ebd5133e099a2cced0f21ebf34deb02ff3463a53f43590713cfcce43c8260eb6efaa0ec1eb3c1f1403f6d2be47d0695be1c8897e32787e7df4ca49f1544798ad874ffa44f2f98000106e9386bfbd874a700e5d95001b2bd45f7aa3bb343c80c79b7bb508a93fc6c077af870cde24fdabb1bd4fb34b68c8cefdc4198ab60f5abcd7d80ebb2fdbbe3f99448ed48840e7ba62c87d783f8f20c356b017c31e92be43dcd833fb885d51a94623aa24c732c7c81267a67341bd33ae8ab8940eebf9d5e704709400619e72989d4a67b8b48656143d47c5db50f415c0b726f7b8f5280b7a099f7b2fad0a48e82f0d00926f39f63671a212598a2b1d6cdaa9c693eb64d568739b2c8f2d875a519d7772c1af1438e130e2d232fb8b1ed25aafedb8adaa0ca5cf8a97b1cb6a16b93816b5db9698f8d984168c5926a8a7da376890d1b99e0d7d1692045c57cc1da67109c9e9a31983254c1c816f8129fde3fbe54fd4a2f589d5b7c1d9e53ff5e0204889b1598a4954eaf8e161ce562899b05994a614b66679544170b458f3bbfcefb6cc34c6b153f334329929fe96bc5b1534b786aaddc0d7528341f4ca557b7082c1677b04460e4461eee5b7433e4c426f7af796abe8a15a2ad4570f9a9b81c59f372c99033bfff6c74de930473d49dc126ba2bd5b271b8763d0bd5201b101bf10100f3e70d9bbe865c7d1cde804ba9b9811444b4219ceea6c395866ddbd4f715a471bfe79eeb5446964692bbf41a617937926b0637ef5fb0c1f21676ee2a3ba4e685c6246bfe206dbffad10f1461006eed4e7f3b7d7eb66e63e21ab02a2748b4f6819810fdc086e3df15cb2a77ba2c52699ac58731ac9464022fe124d55491999b3b6953b8e8ca6f0a822c3a16a90dae90d66cc6efd9bade18edbda4a22c49ede2616abdf7daae20e95778c22c1c9733d898d017af3e48b271c4b0b89b72a7faa262c898dfb81b417208489e14957ab999507df5e8de9400903bd2d20e401695295c9923c8965db1df1f6891a2c9468a24e078065ccef077a81c93fd1f5455c8c1b17d9e9b76404cdced260650d3f89d21e861da69cf60504f6434f19136a45c238ed0a69c85d01618bf2987d1f0e7d86ff0d950a249dae581275ad7ff76b3f2fe170bf5cbd3b77a729ca3c12a66ad6e6ce1e58f1f7d83025211898797ee20ba367b31f82ad1257362fb04dff88b128304a9a5e4efdff3187836cc7fbc9962c32fa9115e7250b42a48bd54e99576243e981e77a5461e81bed22fbbdffac5a5d4e054492b663071a6a6b2bdffe2e8af8c2c91a93cd67e39e5709d583b1345fbe04a7be14b444557e78201b9ae095f14e67f43829548a5d587d5fe032261c437d2bef3fdc533564bef450dde56948b94d603f86f49831f66556ac89b76ecb19287a74e74064c8534e021d9f62ccf84a9ed3a309d3931faf673aa04dcd2c06bcef92d07ddf3e840d10fddbce6454b25f684fa80317aec6390da75ea9bd5b33d729908f6efdb150d4d7f74e7a1f63750987183c8a2b47bf5f1256c14d3a49682dce5ce1b6875f3e87a5597d82cea0ec4accf0c152a04c6f337f934b8febb4d00e266dab16d2b352f27e40b055ef5e672d7466ff11c024bfcfe659a2a621ec9afe1a1e1de1473c3a7c6ccdd79db9ab384cadfb0e63efb855e79c1deee4630664462a24e12f3d954da6ac191747b16e18fd1caee0333fb013a680e5971b8678fad6a44e4232669b4787a47254f9a97004de7942a5d640bdcb69b04c6bf28d420b3ba1fdab6f9dd824c47255e6f2217f06080fad4bc1d210e125ac3330f2b748498960a9d12a770619f716a5a9b2041c3141c6e93fccfc7095d5569748666db7795e0c235ca25e68093d2ed8b1ce8c88d5898aa69711467b43f8990289156825d533633cfe67ac8bfab5b5e1604f1ecbbf303fa48f638adda11a5998e26023f639efd3ec34775ca4468b71e703ac664189821eac927d64d9333b58ad6dfaaebc8f8126d447dc2e5e6a74c +expected_shared_secret = a226b83601ae0e6f76f9f08b0a2f6eb30a3afaa39ecf5c5671e988a354fde9a7 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 3c3830f0332f31f89ec458368a31cd2466203c2b510cd773d66c92cf2c95d7700d82b54faafc8931300f48563aa4cc976ad602d31c4b4b6c96c6f527a637231f1b94cc38767a608f44922a3f391b9e6c5f78a87bbf6cc19849ae619a2d84533441727e79e241efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ab71ce07276a78546859e21ba695953c8521a07bc8b4264bf1d3403eb8cbced71753b6619a4309599c4ecd32826e6609d7d09f976c02dd4143db7ccf9ff09365910757268f49141445b689a6dc0706c92fdd8382c63010f7a026abf217ce572256360a9a4ab2b7acb235f6929b8661dfd5bc4041813e657c95ca1a36535e97d6a56c7022dca5cbf8d121f24ab6df3002fd4b619b03ce2c4b57ab65732721901448b9c0136b1c72145b2b101fe1bb555ab2c0482caf3a1cedc926a007858e7a4ed9dc120eaa7e945275c4a847146c88a468ae23ec173ca76494732792d9a952178d83790b725ca63fe13ff7c5cf5096b3828b463aaa0ee913c390359c9e4346cdc063b8517dc5830a24e578f2053f33e5999fac5603ab62ea785080bc39e0aa206c98c560597d219746737015a5668ba4f0b06f45a7385c753a854c4d818f78466b5b9421fb84b0bad8b5b0cc3104ba8b9531b9033c52fe7c718ae81a3b06ced360a879d9cb3f73b8d6c09781462e6d7c13377006d95406329777e2651ef2803c69e984d4e719764ccc1307a64a1633e7516b2c5380c443a9bea049c91cbaa7bc385b989d1453676ecac1c2123f05e83ac0295c6e36ae6f0364ce5b35348037b7379bd2248af8fba3acc293479b24cd0a2b0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2940761e48e665461bf30c2e9702ac726ad1aa7cda90c5655b9904ac1699921ac4a3a1981b566c6015016ac84e7964f64c0b5eaf69fd5460b9a17686952951ef9a04a55926bd482e669bc6b731aad4465f9901337a0544f27ace61841a5c2b0efdb2e4b897bcbf1c032142b73f70cc0f7b509d6847f61ba4e209269acced24a0721ca6d9e634167622928b65447a5aab30765efb7c977a56020b56abfb82449614df3fbc118369e8aab020cf989015696140b6a5c960db2fcb5be3c41091a6729c62547db67307ace42760689c32c2388310d1269915470286433c5624fefe684a12957d90c8b61fb334bc56cfeccb229f01f0312a11449310e432e75037ba429adb4507fb74a293823364f81b756673adbdc063d030fbec029569c8db185a0ee8011000cc7b2118a046483fd975d9a0122fb0596aa8a6d9b99ce7303b1c8a4342696001167a742fb9374d4a20a8377e8a6495e21ca6eb106b2c680a48ca6c138673ed09897f4c731412ec536759a773a1e3aab3b335301eb2501a5cb48c33a1e026e4bb25e2f867271e48cd48a029039519b296cea8b04953bcf41b515429237e696503e9283ca4165355585be315f20266438523d41543194aa6aa476bb2c229f2f12648a179e46c1696581607b4585c5341359aab5c5f0b2ca96177010c892f8299042a880b9c281483ebf0a96ecd9cac2f13bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b09178f2883e8c6397c74352aa32a49468adf650441a73a2a0e7489fd7a42a9421c8366ec7b5a0ba8b0fe721190f825bf5ca839fcb22f425738e92b68608078316af96526965331d16a41052f2154faa17fa843a5e2278cd122aee688924e57029a8902a03186bc562f99b2e72b9cf8e578bf28c2f5a86b47b4555d50a1512ebc131280964165f139b7a8860120ca684cec34cec402552eb3b9063b7d8266735cb1be8a0b253c67710d80d5d1b128e38085d40cdc7e2cbf4b8c9e1861d2f41a79e1b49aca0668e4b9312003986045415b194f0f583811b181fc15f8cb5788bf14762095bab613f51f4351bf00f669102bd349b70c40549b75ecbe16394a3062c5316bcc4a1ff57cdc976950618c7d103248f4c4cc2087bca854fdf6840ae98238c26656615143f0538c960888f32bcabe935732b6a5c24372b438449812e4f125b07b836b1e076f7e629fd3578132c70776635c5fc0d4b435ce2e301703c20ec130a25657eb394013924bb88090b1599373c5b7624d59d2f2c3b2d71a308a25092d5b0eb6ba81c5b0c650104b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = pass +expected_ciphertext = a368cc5426a57b2426b82207a847039cd8d56199b28a9b5184b5868528d3774eceb24ef6d69a936fa15534ac8eeb16c279c3190c59dcdb808b62edcdf9301b36ef634e14a8433800b1be9d04c6cd781c9000aaa74f8b063561146b8c11b75af02fe5f4eeb852d5f53842ddf4f18ac33e317b5d3a7d4524f5037246df16d15c0c211f37a8bd1e6b35b6eb5153e740d85cdb248b78852253f2c156d405648668c700f7bd3ab1c7670fe8fcbc6eee04745abdd4320fa883d6535b7366336410823ead993a2a994e48553935a17ca6889be18bc2905194e365cec1cd1d75f309aa05f3ec3445c53ffac6361f8873cc1ab1d5ad2c44b72be01a86b828d5f9acd26eac49160fe941f263a82286574508debb2ff9cf8cc10e85dd4ce479c96a79f3915e085726334e4dc636a705175ee770fc9b463e34a2ccb04ac598608370c38936e36b6635e98fbc5fe9972a212d8ffdb93bf5c26092ca7ce699c4beef08b2c0d9fcad9985dbe35a95839420ff1fac408c914dfac719b6e329fe872d5b657907d056fe5eee7fc9f302e3d6bd23bf965dd7c5fc5943134e55459ff271166c3a15685c49961b0a7b7d5ae61b5fe6bba79a59de07c6e04c9541cfdf84c01685226c3c1b3f8de17747b9d44498593f2aca4d38597b766133d20b95ea15ed087bfef1612793c75f32169a3f366aa34a671ec2701a5b3eafeb687d60f3a4a022253444bf9e8fe98283c54e3e080925b26df9665c6e35618d29379745890f7fcb4ff6e66c45f1c1412888564b036ff10ba9650b4bc98f23a60eb1e17cc57841ccd44bb8db168fd2b0e52a384df522556d5d3cdb3d3f23d6c876fd8e627aa3644bca0ce0a49f982b69109f42163ae61293356bc5154c1dc5092bb50843583f72f8e9c8c5cca5d2343f5c3fe4f58debf45579a302c070b141033510a9605786e376704dbc6c6a748c844c41f2338cfc3d84aa1f7ed352dc47eb0a512357220714ffaa503647840a1105dd68c964efd899678319bb3375c8eb9047ff3d2eb98b1ad8ef50e55fe41fed5f2ef1b534e7dda5ff5e988f86e83a70ea5a8a99f822e2fe53500a87ac4705ed512f560498b17459e0e0e6114fb3e370ad38f0fde6a6e247a8ea81c6797b428f022113a0bbe97296165e151e40524268bd6729f969c2e988ee92cdd98ff945f9159e61603c10a39b107c1684069faf0516ccdebc4628510afd381b99f686610741a3931253ac2fdbd1f043e0b46919f420cdb188ed3c3bb11515532f2d029d8920545f8cfdf93a9a186b90afb9ee501d7af8eee89e7814efda71c02bceda251342f52bb115d3d4d4b6aa4a9a1957eb2c9229574644144a247107763294555c3a259f8ef07c73381b547b47d871f5d73ea0e2311fb29136a8f20d13a1d4968d0ee96d91d3b25d45a10f18acfcd5b30c45c779c1208e7a04b5d6cd6001a5fc900273e9553858ad746dd3256feadce32a5468f6de7126ff6df864c530107c6654d10b07c8338eab64d5c0e9747139820ff591e964e332ea357574509da4d7709ce2f163e999aad5c99687ee61881d6d8a7634aa5eb5d0130986517517ff45e764fc8ca00fb5b5f76fa2f89c011a5c5fb8e27f5e97bae00472338b1ee7e053f2529b3ae4d360ec408748cb81849958cea3926e934ca60c6c322bc7758c3f3de8dc6324a5157064ed137ed373c4bd2caa10c19c4d5db5741001ea2f20a7373524c0e31b126579db7a5e441444506a776768532433f7f6ae4ea1f708148a372b4ec0fb52e453c675c028201e4d3cd5cf0f815a9372d82528eeaa106ae2ccd0d9471215be33e5a45cbf58993b81e6360310b6476640940b1cdc8e79c65aaa5aeb906c3dac8e0a14f54a656aa138ce3bc2e3567ad6ce64f07e1dafa43bd022eef3e4972340e298835fb81618c3dadf88eb994373ee3e84107f8eb448dc31a4d33249cf3f02b2f42d810d89fd67355ca260cc1bc1c8c0d8103b94b9c67b705aab41facdca2819b8f591ef79dedb0905a44c2435ee41e488e538149ef3fa9cc44881620cdfecaf1583f186c5c229df8e62de3d414b30dd700a6fff2d4a013ce8b0ca52d7c0da2f24d21f65038a7cd11a90513c4812b1154891f898f8ab3a4d666d00fe98d8cf351b12580e36055f5f31d2a048b41fd0445cabf9f6f367361fc4a1706b7aea67dad68688af01cd1fedc893ffbfc6efd3b3acf38545538e0a4c0a155c30 +expected_shared_secret = 3040e7e4eeb844c1385a78dc3c8a6375880ce8fab92827460de1825a4915c3b6 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = a99ba278867903f11dce73ce433c475e3b7e0b3c65921b3c842b142e139fe1d15efe13b7bc3625177282f4a92ff5363027901e2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703ca521be85af4651c52ab82006c95fde5779c10ca73866911a4c48088742b8b2243f629fbea924b7d8968bfa6200361a9c344a45466de00b7bf0e5b78dabb1bac3278144a94b27193b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49944d161a9290b4ff328e4fcb2427292a01367c713806b37cf92649009c09416a915b84c23efdc41d7e7859dc81276042357663c0bb68282cb71d891177148a17c315b7cdaa9aff35b4a4369e83453097b88d61395da62431f19a7c8427a2cb15eefd30b810bb74342a306b1bf26a0490af566f5a17885baa8f4a60e1c9432cd02a15915cbc8d574cfb23399ca1d93b95bb1e7a68a798a9b9a6d4dc92bf1bb84ba1109db395dc4b59f1931087e4524a090ccd037be1be6237a6483ae1a21b859bedc7a5a57a46fc02b13f5a446f4997b310b14c734160c7a19a36507876cb4c0cb2bef3bbc5d26281f15ca5d7654de307b20f9b3ebe90dfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358db0784a9c7dc25cb6f6236ad96784759277f660c49130a8ed9377f85394ca90e1d59467ef98eb555956755aa51127a26f498f3a6a2d2f972357b0b40c1254f143042199bb380ad86a04c1a8a1c4fc68166606152c5950ca8b0b3b86d99167727f623927963770a1423a5cbc9629f248409183cb5a0d99e22c915991c7ec3e5288400add0c355a3f94e7a4962a513b05af268e31c7d1c4b3fe0f0b8be500812bcb66ffa0fcfe66928dc86d769ca1f4095ea3124c5e1c7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c1703a0b7b86a691935824299062c5bf927fd5573e413552a7731453171c945748e9943429da1c00588742c8c2acbace1ec1a290e3830006610d21b945647180075194db0170426087112764bc23718bac96281ced834396cc8d4d003d3246641577bd11a59a765001215760d8122eef819f2d1416f998c7a8a080718a11774072f3a563a0581b92e5aa24ec05ec9004d578438313913b176e783c01e4d313648123b9db69d9e7c648d2cbfd42587ef1a2dae065fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9cf818b938843f78ac68ef8349f37468e81c06044ad9a051585c34d33d76cb8ecab0c0886cfea5c725b3013c048db0b7efe3792c6777a0b8413481aa0ce5b58228479f90c941517631319415dd52eadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f5903163a9f45d681f0c637a5f53f7ec0cd30c270e3b78ee4d575a3040b71c30106c6831dab1f2c8515fa8a6c5477c311e7023d779365466228aa3d1fc2b819b51e0771c989720946aa19e6b28a463577214c58bd35237c33573a75a11cc1b5dd8595420cb87f9063bb7247d88789f40198a0395c001877cc35a5a5171e3360781bc3588930827339c24233747d9b5d96f6a31712cfd71cb962b7a1974c3ed85c05a525a21aac83af06c68136cc9bb8b7d74216da468d78f80153bb0cd2b2316dc975ed6c09b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df8117d8312093bb3363d02c72f727f3371c2c8491dd611ab24765fa2665f612517d1d66882056903a67fd4173575166255609a54a3245d74b46c075c04b702ac4bc88e71b757907091c228b0182e10305b7c1cab0df3447a93219df5390a0302f99a0ae8bc51108c7c3397590f4b241165414952840303606e6c1b98755264b01280a8caeeec25c0818840d494bc436279a939d96c6f9160a01233afbd576f46359b2c75097bf15c37047f31a186b7bacbf23aabe9b7ab649938b08687a4b1734a834d3fa62a8a7a180cca4fd0a74c32a76db42009daca9ad0c3a6f8a06699630f56a6c793927d155b229269b1e3c94e0d23be1ee3121e4b638216c5b722ba3aa3129dd49bf1f93e78d16d1e820485527564405df9fc6574b7809a8bc289a02ea0e455a3a7813c195921194756558a6d481ff86a0de4dc39a347ca01562454f589f953837a256cb2ba49f200a7d1b22ef801109e2a45e28c57e201354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = pass +expected_ciphertext = 2bb76b2b172b91454827ee5680a5d60d98d45f08c3d4b549edb5deb2a20970567ca6ec9b2c634d436eb162a1d19d64f397dcbc8aac9867cd71586f70a336add2d101201a6872f943a49f13e6994c61bf51830e361605495e42c54968e7eb2d5e99df9f3e997c72644e10086ae5f1b424c6db7aaafa7f84d741ab9a23959e111f749696cffcaa7091c00ef5f8b66fdfad2b47a029249816c59155c3695ddfac0837fbb794cbaaf4961e00973173baa56522f65f6cbe7c7a17172f6af28a5169002a1fba98e763b74df20e7d0d0fb73c01ef35bd12ff9bd9bf6c3074cc571fdedc187cbd9a9b7b02b57e81f4dc62e0cda4fe8e942121eac58a64f561f8a4532bebe68879f551e5dfe9f60e7beb44531432d0593f41545740a860fbcc36ebaa22a490575c8d8356c1678853172d8ca769cf6791431a1ce3f1c46673a7a4d3fb534ad97d11e79a0023bc90c74dc392bf240a675acc777ce4452749d6faf47618a3394529868e2093de715b67d0bd441df6a47315e6323a091967c647cddd53ee4f96b17bcb20de94145176838934926746e267db99703cc5c259becd0c31eb8bfc6e303564712ea222f51045b1ef629eaedd8a9795fac4b33e554f6f0a223992eb7b77d095fb5df37a5ae525201f67583fc94537fd22238ca6383fdef8ee29766a5435b6cbe75676dbedafda4b2515b569e5f3dd3480665f66b834d6ba52d3102665dd9eee38a6c50c81ee0d779f6b5868e5430686cd0ab6d0a292293aa780e196a1a31bbb3a8091ec414f4714533f117eb0a58d021b136a01b5eb83d7e9c8837d4a395d2ad10c0c06788b358bc8adf8c3d7363e7b59f757e6251fe08d87a7331be195836a16a742725f68fdd7f841d92cf03961b58957b3f533627d8cecea3cf66650a6d903e6fe35e26f5de9ccfc163ed973756c2e54e2fcb06b53a45d2a6db06aff3babffc02ef9cd1a509219262889dd8e0e8dd69f27e92a8131b02822fc6798e0317ef68e2a081c9a7cddf207d23e27b1c629868801ccfd3931370a87334d404b5ce1cafba023555fabcd66867f211ad534c00dba25014af836022d153920b6dffeb1259ad53f94b9ca9e21e31c21903b5b957d74aaa84ac4a55d172759331b5a2bfcf25a0bb4a43cd45fd7e734c8c0a965356f70b106c33a4a53229ac8df8322f4e7066aa00be77e9c0a88fe3917b2e09c092e30140fcfd6f215fbbb57e1951ded774d91774fff041c247d56f7444777d3031b7c2a849026bf132dc40d7fb4a2895872a296a3b5018e28ececa5645719866cca58a7a960d6aca25fa3baa95d411c3123b5be1bf279ad8503d7b508d1768baff17a412a43db832b589a9045b3dd859104eb9a83e03f70acae016347fc85638fb35c66409be9a02350d2078fba28f7db1c233d3ed0fceb923e6f587e72f22239a0ab1c7a17774cf18660cbce046551227a4937ca1ab825c26a9ee4075c4178c6beec79b779c2466ac7702bea20be1b167ee52e24ba642c3b16855d02e40345cca41fb38f4e06cb11da2aa4564f12c5c6acca2a41a83e0d37f9c12ea52eb82f5ee91bae268a1ee60b5dbc239ec33905e0d52170e90f2fc0121aeaa59c971a4f91fdbe92d248074ab271aa790e63f97d8b9289df1a7b5aaf8c9b942ef43d2ee3e5a6cb938a0353c326f439dabc4902a095fe2caa4b105ebd8b0c208f0342f17dfe818136f0f627dfabad97f23ab33df3a37cbbb664a0458665c795cbd0da8854c3e66532e1af1d20bb4a21bb0d25e8bea9db9572df1ace3b6bbfec6c9c20d688dda913a0bb1eb7435915964696f760127039f83de95f4569105785109bacf9936c6eefa6979fe67e026e353d0221e36d1676dffafafd3d9cb51af0ed05ff3d1cde08388199cf2defb58698c6f2555b6f587dd4efb83b10a0737b82ce8027cc8b83dc5405e5a75a65266d7e8b2e6b35a49af0eb41e0b435617d2b4ac75a0ca56ef26f6bf771ab0d971fe5caa9be849af1d0326272bfd238a41bfcdc14eaf67832fbb293b19a4b1752ca1e27bd9e79e0607d5217f980a865fd436b0ce35c3225e3a04e578d04c9dfd82d5f203b4d113ee19b0d097c41747908fbc4dd16304b56139e5705f2574e00af4ac6bed23be79919f068f6f1c68e9f1ac4d2ec6fa6d89036b46f9511088239a3c125d7a96a7c8f06339e73e9d358169a56c2099936f4fdc7c963afca70586c1151c547bbd299 +expected_shared_secret = d990008c5eceab7097524d6755c663ba04599eda80560d59088b21cd73243462 + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = f44a0e9b691f0a718f02246fc688a248e3c2f387a55c463f0d976af9a2399cd4845c22516e0b3c882625aa609b64195c90925afdeb2901075565db2562b11d2c07c8d0d94122462c25a794da3639879a409256018f7418af91608b63ab222069e31c2ac0233e8f73ba8be2b0ac0463c9bc79cb048ae517295e8a01d2e16437088d20168f135c4d63b41021060a557003bcc935c6c97b3859176807b5637659f1b5bc4b488d4e5657e9f7b37c320b5df12bf31330ad27a7f205907d6614949bc97f3c1e94f21dd235606602a5c13254f43ac1bca2a6269bc5e6a96c31e30c972067a6030665ca7b05a700c53c560860a11371505457196cb33152b10f9b99518d4ca6433724a93219db1bc834499a019c02665c650c7c0d22724bdc0bb852c9523d1a9e5b06570a6610bd1175a74b869cca729e8c17ed5101d43c814fb18838f840884a4159bac515f7b5a637b703385e5f7115cd187e2964be55828a33656ef0384896525d4511aa2fc40046729f54acc768353b8001201bf508b5904e3603abe5b426dfb77f213c54b443b7d5ca6998291b56c379ad5216056198bf5617e58977a0490c308bb5a6873ab980a1364b1d25f0b01c3acf3221528c942fdc83a9a9a60d819c015fe06d2c684194c56a98c286b2122ea3fb9b18d003cf91453fd09940f7722999af0645b67179bb11b35a4cc56c2fc1c581f168f1918983ea00693471f6e33144c642dc5a4c28b01ef514449213a4e4749f0b2c40e6e06052d6870dac120cfc54aba5143d8ba4fdfb946af9c90f99ca2eb158f001003517b9aa7a1306973deb713671a16ba714245ba96723e3453718a3bca2ae2c1b4d0265102ed901b3a1b6b6ec639a8900eaf67b5e500876137122a5284cf52de9881352770a9d20af5aa59c71189694590c549831021aa911948e550765f8897671621e5d3771f1263f87220c0f0b28804726c112a7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d4d0021633c9744440f0f9a309d1467cca4d67a917198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62006d29fdcb62526714cad2ca04fbc28983b54b6b037436917da15608759abbc316e8359a26c55e7df179a74c39269c02caea7e61ca571dc771e7679e611b9eda31bef53b11e3524ea3f600fdab967fc8a23b0b73407738955b20b76c75b971c4c1105b9c5a3557d57af4db036454a22093a570f0bb10038bb3a46a0c92866c707c28a91b9e6172314408dcd3b051f363775842274988340165887a027bfb629847b9271a5f66c15c286537c76c31f62b45e2995f0aa30dfcaa6bf2883d1deca9b7b2029515c564d3b970143c29956ceff588e99b8025a2343efa5233361bb2332afea2499656203cb712ac8cae4ce1489df2bd9223c3c65737c101c0dc5c2bfd83444a29c64d8812cd69a68f004d2596033e903d744abcb688ae65b0371d711b187b62e6c755f2f947d828446fb45f30c42da615b3c5f682f2157e940691ba674571573647c09225748416529653845a6944859dc3c62e7c0a9da78a4ea492f57386ec31b0c8730206e5adbbb0253113a173e20313610fbf696803718a0d393e7ce4165e004a450825d8935f7738aa7c6a1226640f3cf40ffa6644dae2280043c501635550bc76e8348d133a55cd73001fa3197c1a071bf30a1ff907813aa8b8986449918c08164817720f30e44828010aa6a11a378261e8b141d52779f73927d7f505dd99c7a43a2db1197ba33a2950c280549564733706009185a493b59bba67bd511e4dc55a4f458d9b1003b90a30aa87874fd83707f1cfaf11a4b9088bd41c8d69bcb77853b396c15e24948722943f0e28c4e896c56f7c9d3974144d43a4765392bdb0c2ef5bc72b27b11ff57d03a8214de0520dfcb3093b5ac72003c615c04f64693f68c0d17cbc34f8cb1ea068d681c917315836005dcb423c0695ad19a06801847e947b045e7b78c9728cd321579ea31e5d7633b121884ef65095354dfe63891945983d54cea2583ae4b64f54065cb5631272e1149c151ed0715e93a30c38c85c59415acf73ce76d9453697a3625a607a205204b307dc3c92cb140f1a75c671e916fcda070567b42a2aa12a2499e26293da440b664bb8337b6d5497471b002435c8b40872ab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = pass +expected_ciphertext = dccb4033246369cc996695589256e3fa1fe2702fbd5e0509fd02024cee12ee5507a2896d4d0aa03158ef904cae32b231b420c576d0db77d2e9a655b3ed9e26961036849742263244171a48c32015678f8830f08b904943256769255b0bfa71d5c9a727c617fcf7c3d029f2c090db9e53471c6934c94f0149b6e81c128b118235cacbc0d1ea91b79e9223eaa95248befab41078c39a3efdc033fa80fdbefbd4b72ffbfecd8a271f992afe5008ded37b98053449016d4c8c28ac834e63abe341e2602ad3873e5b543e8a4b53f6d824307d5baac7313a3f42e2dfe476dc2abf2b7230b4a71e04949bd08d77b420668ac0e78647be06552eb03ea83c56db72e4b0b41a2e1ed176ec7429d510516c6056a8c2dc35e017d8a9a71e2c0be30abf65994feb4a4ec45b4fee8377616aba107b8350cdf2ba10a1d01db9b9bb789753785ceae2bff11d0adf44b17e64beee6a233695d34ccad2fb1c4e36b5ce20185aef568216998d16c3cddd2e9e251800e4f1bfc9033e2baf0d2a594006e59341054a07be0968cea55839536e240b7a56c9e1ca5a6fbfd0bb23962a7e721bde72c25cec3ee610e0fa2c7ea175a355f7646363aebe34f6ce18d0267aec0cf27d91bfbd6b34a98d6167751fb98f0047b5d0a43943b90f19c0d459e78b46b568c5752361d3394ac4bc7c9ead6af89611786a99f26b64534f0f4157c4fb737a1787214d8044cfa0442815c5203adbe8d1888ad78eb9a1a29e98164a41226d356e48cd43cdadd19b3053d2c507ca4257a4c914552fe4f2ecaadf7313925a1da260498b3d430d6c960d3e8c1dd31dc0f583a6f2a013018ab04dc52fa00a80ada1022b818f313d9388b73edef561027c6981c7bdf98edf623571d3a37cb4f09a829316eff704335962160e333ee52fbb0dc67c8cf6ddf7e84f576e68e2ff6049d8d3341856abad05ad6223112a7e8056d679c5eeced4eb96821d040d283bfcca64fe5398b0d3b718731112862b681fec18af5368dab3f3dcf0cdc0a2311b25627db2aea98633c36c9e822c4b38602cbde7ab727b404f382fdd9a4052c7b57f4627d62a3920daa4f6edc5ff59cfec7ebee4eaaf0d3e89642a7de253084041ac44262ebf5e11ea9ed394d0ea16f326dba11b5759e69cc9e9acb0f963bc3703fedefaee9f7440cd6200cbab88f447e1c6475ec5dfb2debe34dd3c77bad7802cea500ec48952bb6e18b4e4f83a0fc3a5c59f7a06167996e9bd353586066f594b8a4d90fb027298b843e10b008ff66edb74aca345e475f1cf49b1106b9592f1f7263b713acf9e3a9a1c024ff44126166dd59977bd565902dae1ae0a788c1157343e045b0af00ab61fcbfc814e667039ddea20714a2fb49ad94b5dfd84da628d3f1119c440b6de841f0adadf874863ea4accb2fc0deb9de1dd18e3bfe372b92f0d72a9f61778c0daa54c0f6580ee0db7de48c09427190f3735051f06c83ec6a0425aaed68ac49a8e3725fed6bb1777f6beab59417f398ca66975cefce96b5775bbec006246dc8ecea177eabf074accd9b6661da939e55873cec5797bfdf579d38e80a7a2b5a3ee826ad69429a0d432d0b35fb0a51f84d418bb8b769a32deabd8b70c40d8c99b95a3ee7f5ff0bc243f76c6bbfed2fb72a4e5642bca96b0959601f3e7e4c029c0b04213fbb3582668b6e4561933aa1beb3ec12ad139af94b5f688b9c2da98ff4eaae3de57b0e2ca894114b969b8d2ca26e7af503db776635098b90039919d9b136124786aa1d123f1b9cc93afb6e4fb8ceef7e1fc18f6dc804f7a4b28432a689f98e67a123e177cb4a6b0178c3dc0c62ab19f93f624c2bf14ba6dc1702aa547e4bfc713ab95a40c9d8722044511ac4020c70a6f435f5566d08614ba112fc4ff8c2e5e1d13046a5a03a15ee834bc92cd63f0078fadf9aab21cc3f41eea633bd7f866b4701bd2da73674c8d3de6138035edeb47f5086f764c92679e62f0eca34c873e6317081705e69fe45331fcc807f4faef5f75f0dc054054e5e1aaf05f848f0d43ad9f456bd3ebfa809108aa1114f34b47e7fa34483982689cea633c541a243dd48b109922fc1277aacfa681d99c4879cfa4aa783272136c555be0be3149566a2ea5e11f994133220efbd7795f4975a7cebded59afbe539250099b2d78a11bfbaa136229abc4abab7cfc6b25a89b8b9bac53f1b5c4ffeee2b22641122e9c89f57b03d03e25 +expected_shared_secret = bd50423b4ef27559d67532abbfad2a3a388e3dbf4d7b6488c2b48f19cee07ad4 + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = b7572f8bd73104745eac83154707cf81c85377ba36b111c9504a180f01c880d08b55c3008a9594e75b3f026a103724064393351dfa7eb5ab9a1c774a59c47b31437011816abba42b75780c1ea8769a7bbd1ba60e686c726f2aa6c9101614c213a8147cabf658d5505aacb288f065bd31c5b7494b377ef1ab72925fe513c49ccc130cc542aa34abd31b5d99cb8f6e2b9a1c5417a4ac9c91011627e6353cb6529ac19697d05d076bb197790431f9ce62a31fb8154797583692ec9abf67b678e0c204a822e228b09bbb7b4cb3a5df788b0930841aba9e4f7c1212150c87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa500245acb15b7dbccf9a013326c2b0336b66c101aa499159a7c875eb6cebe292d266821bc193ced74b04e61845aa5b1ddc953699cbb7743cd76d930bff38efd943c34b01a8d973a81247d966825d1a9b3b2fbc5769c9d5ba883fc357946d54f3cc3090ee48eb2fa80b4d86dee07c57c215f07dc23aaf8c4aaf2c9e03ca2daa433fd9c584bf582793919449925f27786b6dc2de9c5cc08220feb501fb7e2900c243b1c357c8fc814cf87b233b70ce6f0938b56698c160ca893afa877bba49c0a8f606e30761d9dd14be7a40f8db95496865c2441a47aeba1ca7458256aa5a910948d4c920d32712c55cd8546809704c1760c8f8ed991d8ca570cab3441782b6e4035d82c24105397cfaa8ad86a385327873a228bb0c02801a50340b70e5483709ef03de0483bf08b940c4aab7a61c24e9947875c8e2b930dc208ace4752da4d0253ebb2bfb333a1ec9bdec73283d435c4d061df6b0692df903c6481179e07adaab8d69277958458f6ff5c6e4c92804ea47bc8a03bdd707c1a78d912467a83575fe74aa25c043feea0be5899210d7c8bc8b669fec5840f5b1782a5a9d947e78301eeff9b12635c9b15176499a3593362fe5a946fc98c7083bb185c2087b58b6d7caa3599427259a72c6f89fedf61f7e111c04f008053cbefca2ca13a06d09d9494cf29f82c5b93bfacac8d705e35874d0297aa15c7fb181878b32459cb09d6d489671e7700e4731e783c73c86b5b8731ae765a639b20f8c69844559b0763b5cfab7396c1aa09ce238227c29ba34a48891a39cfb37f1226cdb35517d354d422000c3709b7cf53bb9807e2ae7321b38bb29c327e5eb3d02036b1a4c61a2a66a3e91af4288875719496003988b488d84535cb66a4a1f1ac69952817fc13ffadaaff145780aa02ac41cbebfcc9d798cc4d9a090a4212f0fda861b8760ceba5f334c1a54d52567c2b51628455c85517f67baae5c694293c29a684984ac3e711501d5219fa8279bceda4d8aebcf17babe31fbbffe6c297dd27cd894be83b416ee182306d65d2a962f64811ad1faa4ce72a6cbb1c5d22a1c4a2c1eca36b38618afd0a928c4db55b991428ad72a40679ec7521a170929cf10a41cf63bf0dbb5f1316a23d2acce5c7c34c67f6b2450f36556bd987b525a009c77ac7e23355de3aacad177ab7538eb7b25d613a3e9c11c79e59fd9ea263c0178d47885c7384b492909fbc63ac0b2a4ae455dd3446b395c0bd001765f31c79649c53453252e02b98af51f23f8b2f5f2c8d3eba71ce67a95170237b7a408235429826637f8cbecb11a4dc351fd0134a0cc7869983a02a50ff3958e445a9dd35023900b7a3c41ccb66a54628741adba17da89cef8d83e8f66893bccb50918b6cfa1480b051dd0153fdf5a0561c2c782dca0a02861b87a8aeb304927716884905e1e0a004f3a119b3293fb0850cbba7581f1363598c1384ab228d8720b4c6124e2ad1a9774d7a16880542d30dab2f0796fe5536402bc10326c7577971c496083e0c24541e07c813a01989013ab9580abcc038284588294b743086357d50b01e93d841c6a7b929d32291e47d2419b464c3c692847f7706865a29335a4ff50c536991fcb790d0de50f68914d1ca5b438bc0a43393510fbcf15a895d5d546850c0fb1d970517819e841cc42dc279e8b398a563c174c57876605e1212be53ab714486588f96b8599262d67bbce891b90308959524355338355598b233aa89e4679749207f3ba1086ccccf836c7e3528989d0848b947487781a2b025955b2c748c700b479216c3caddcf63564392d6515767b771a21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = pass +expected_ciphertext = c688351c04b40d541e7da6b46d4d64ca90ae56db02257e9e64834e004827bee1b5b54c18e45c2ea9f379775f2280097b9b992547d209e01191328318d06aa7f34050ec2064da3f29e2c5e326c5aaf08f10bb8831cb81ad6640e5873cdee26f61311429a0c6432a1d2aae2c1bb40e2ecb57820c0634f242220c931ff3cbc13836cfad3517e39300f4c0f98eb3a533d4f35c5c98e14cb2c8d3ab3ea556fc9a03b09abfe1dd52199f33bf176324aa13f0c9fe138af8c84f889b547bc74539482f7f80245537573bdfba12c0fbd0ccc739fcf40e8f84f7f6b796af05b746ea4f33eb7977be3eab48722c195b1d4ef2b56112fb30d9f7ad31d31c8e7640c4ddeeada3ce4c7b6698d3e9b880a682d3d14317c04013ddc620d919dad419013e4813ca81ca9c2f3006d859f19689549ef64f2967e80295dc834bcb0c23bad006210ea8c38843de7983bb9c1e6735f853cbc559f121dd5ba19d4f7d98ac125d8efa03b858466827c6db2a2f0bd27740623341a691af087e416dac30a2e6d782c4c43e4a6993fd4222a8e2958c40d285ee743a9b32a82d1918b2eb216d6175ea69643d2843a32148b931b1d93a793165b282e29c2020ac05e2b0fa9d8ca9f76f5790cca5083ee17001f7f43fbc5f8429dc86f4849b1ca16ba588092fadd39b93d92e4d42aed9397acdbdb99e12f701231cb14800eaf02c948b93362e4d88c01f57e4ccff0d641fb2a209e706727d236cb089bf1de19e64ff0eae24a89a8661caf94e74310b1665e108a0317824b8de8a1a6978007bbc61971ec7c742a588b704f357ea8c22007b8b60feab7d9d78d6a5a89265d263f4468da1def7f165188ea05b9fbcd80431e21659e52870ca7865ade7d1f7d0a70373875c07ac1a23c0ac995f7d1ba610d0ed559083fcc437e1896ac73918b0c1dc290fe648eb84d9a8315e01709a80a559a7a54b4884472f0f785aafea6a69cfef57d460910a22bd1bcfe05e4e19ce109203e4711605fd982f32ac8152525b43cf9ad8a9500e7c90116cfd8e59fcdfd9aec7978ba333ffce54e2c4c6b145aa3fa905212df5e3e0e03339ae6c5b1130672fc0d3a98d4e2ee2d7550ffa0d360f77de309798d64dd805b3f4887d3b3810b44529c0b5fa39d7de88a772e6f9228755cd3bc05e5eb3acbb2f7c445e763fa463c54bc9681dc51585f2fb6203381c466f89f38108ba3c779e0794217f5154ab3534ed0627367cf8e7a8a6f76d3521b632b661429845f7b173b5f3e3232cc391eb8de1b0cca409a717222d2045124f9dbec51c7ac8177ff637dab056a0c649c5bef3f9460d2a4047c62fc1546eb291d2c968246533df79185cb9e26136651c5166d37e531a35aaa41f6c7edb7bf5f1092695c270693723fde78b2f36d79a109b225589c97db8db07343a6aa2fe2a43f2034ae315cbff869880a53aecddd9e31eb62dddb73a615a1dcf163e51423eab895311b303170aaa3658fd8eb6be92c3a377f197b00ec83e50ca8a0081a5280908547f9d373d7e1d54361bb7cb8a2d08ea054024b25b47365550fd9c9df1ae1bd2349990b776e350b3f371fb466813faa6b6b4e8d005d790cc69c77d7cfcad983aff636edb9fe06ffa0079059fab7d0e30b90c88779fbe65b203460b7455a08867c8840ff5cff27fdb33f8b81591503cdb3b0d1c61bf76be02b3259892f20393a1cedba43d7ff6b6a83c648ac6751c3f8e759223cbc1959400f09eef430d179ab0ab40840300afb19ef43d685a525b9ff44c49a5cc3ffad91b6a64049298e6b2322891162c21448f416484c45573d306153d7cde42251e79b15f03ec742cc62eff79b0af9ad84fa1621a083b97e51805c310483380661972e141eaf12032dcfff1991a38df720bfd3a2fc185f6edf150e873fc33cec05f8e6fcee6b7f2c62af3672844ed45b8237495d6b7be6feffdfa65e61cea2c70b9b4bc1716bac1d4ff28f80e9a3dfa7cdd559b3bd0322db1f5954b3fa0a25e7b5f4dbfed9ca6c7a917b596f323300863fcdef1102224942ead7e79646e67294cb3922609cd19d1f2e067df2f5a0a4317c7c50888af3417f55b5183b7331c85ab82293c5ec4a43d412dd6ad0bef34041e0bdb4ee9d6cec778441a7a088e368c7ddbb21456f7e4b2c16ac001b8ebe83981d9881b5f2fefe910ef66866dda7eeef28c474b66b72f3662d8063e770f073d03f4a88bceb10eb195f3c59128 +expected_shared_secret = 38e3d97b0547e648b2b722c4844f59ed43dcc4b40fa7dcfe6184c2fe62ab3530 + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = e7c99be7540833828e457c66edec8e201b07d8068bdf671086d6af0beb628685790487707b66be4c7341c654a8119774e8b262b2f34944898e42752149039356c1348eda779b526da7ac838551855a4a8af5780c5567295dd16011e3177e267948ba7643174391a34c5597b7af774256329f211518e1a67b2f35898e610f49500c2b4647297723004ab77f9b538524a9b96b1e5fca8f224c2e24701bb726735b408323784e9afaafde570b2f4c2bba88bb54808ee73aae69ba352612268e9b4460f004af4998a6c484474c0d04111f2d1091d31443ee2447be719e8f4c3a49e918eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523ae006853b5e09706259605e72e78ad6fa602bfbc7bfbb0d2d78b5155b3d2017c9086803be862ef501196ebc2af13b2b0569473e9620fab2c85fc23874ac14b59c0f082029b553184b01c76d856858475914f025df1914c16a209dc90a306914c3371a6cf68473a431b2886a8cd40a5302834a73359e001658b90725e02e63c27403fc0e1953b11ee6a6415815d2b2bda0b13e54511c96b801da22b5ae94b68dea940ea4787f3a1506e290696c3535b8ce73351a6e48bed272af5e456904aa03094210494c90b280c2942682dcacbec8c644e9a36d326816a42b23b96b751afb7b951a87d8e94db48932aa14bf73e92b06b85f7afb4387e949645c5838622ef7bb2fee0175914b3c931b25f80a010568a179a21727f52ce578aab6da1a88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e18fa294b7b8055e6acfac6242d671855f29979609b821566acbb381dfab0cff8bd47204fec023ef281226b63a7d0397091a9844e23b28f57a0dd205a520a48a3e517276977388b575522c5b78627c4253bd38840a7889fa75a7bacd10b8f27a3e13bc20aba3ddaeb88ae62b2930338cdda41e0770b4d2092da100aeda2b5f5600718d69b032a45bd677b8732965b82908b877f5f77446e4aa132d46044067b21090404d21d01231264651b38832137da53caba0865957f5af7ac4d640fef96702f853bb4a70767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5c81471539c42144b4cab5d8d53285f8c415cd8cfe2d30295d00dcb47b4ffd90282f6b582a57bd3f13eb41b088ba624575b355f8c7fc0f34f1e924fe7d653692c4f44e1c64f9cb145fbae9e789c029421793a4c43856469298b4ec648b21babc0167c04d90a3a8c554df46b80b407dfca54d5f68e2dca4e98a92ff38b427115c26aa33161503a83143714234fed912829bcb924d69049a1c958e6a3088cab51f956c87862e776320e78457cf31c20957158bb377460bfbf93a44c079e1f1bcb7b4268a0cb1cb8151512dc632252700cf06c988b2a3b254ac6422c73432ccb143819105897575c8672b7b0464e61a6a8891bccfbeb51f96120107cce8e950802b2c04650a1f264aba721541897538278bbac29b73f811940a47249035b04c0023084bf57806d51da03605c0ab0e6a6b65cab53cb26425666dd1b597418864211c6bec492d4577bc127369af391f8ec72c53302df5013c2c7c62d364b35508219749f131b7e2792cb206a9abe2c21a565bf05c1a7f8995c89549aa3120ffd83cc7a8b8a95bac3e7eaba48b57f55829f05bb265cbbb8b0b7983f7618f2511b3fe3ce9a0b735f2c1acd189f9115a1f1933ce19a8535958cba82464ed9829bc9a0c1405266f697d54128cb31cbd5b95c72740fe16219997210512a7343130e7dd00556948abc6c0dbd215e9db44a2d80c5606b930c6c8b949081bb453461a21026943929d3bdd3c942f8951aaff04276d2186cc052b6f67e84d5aa6be0c67ad74aace945ddd7c4b75248a0854593e8b27e971895b58c08e8107214afea3aa1b41a17ca121fb8308eea899e8cf04f7e884cd40746f2106a86164489ccc20f526154e613c565a282d5742f4953e963c42e878ab4d6668cb9c15f8629f537cdaa078db33191ee281a46ebc2a3036639e5cb1b201384b222af46873e1c946438125f060afd4734e21794a8da3d7b266c4125b60c9c480091874ae9c242f550898a30281380fa352c0d4466295a24653181e0e292ae099abec3275f8a89f22c983c8a0875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = pass +expected_ciphertext = 2929caddd4f0363b2578c242f3e6b4978d19f155c3de70cda974496e367811fbc606beac5c6462d68141dc06dd9a3e7fd30a4019c010f43b1830e197aa31df52362d0b969ea4d2abca78b3d2f9dd6ab72b5963b2bd469d4118337fe5792f49e424ff43c31dda4449ecf3988be6ec3e353ad357191264a54145eb5643730da691a4334d3895299bd3f18960ec2ae9a28f05f231e8935ebc4a9ed71752030f40b849ed7d5b81c64171ec4422793fd0a23e85283d59e8b0dd5931436bc37ad82594ef3f73d2c0e64e7c2f7e0cdd14a8ca835f8d2d0cd30b726a0d66f529c0236069f0b8e87cb2e022cb255157a77bdb49fadd8836010f301208d3a70d8b64a7df70d4a15b1ea9e3f15f91de9b934d3e4b17088037d282bfe89a2eb54fa17b1857d977286e238f1928ff0c2d200fd6122b2c85b80e75543d9814ffd2a90f4d7bd51bef826f8063ba56e1ac902ad4499d9025fec564f2f87c4fec9db6617b64dad6f35a8b552f7da029d5699fcf6c477201e36fb39b9f9cc40a5e44366ea7d894f579eff17a061f3d2861b38b21a25177fe658627b7a11e136e490810c9aaa3ce43a7700e7a30a014bbb13362657b479fc26b447b554db4de68dfb9e4912327a6f1c475497a5638ac334c5fd8b8a2c5a6d27e7f9c7e9e6dd53d5935811a20a24a46c6cd16912e6917946f5b59c47afae99d02c93778e755b6292c5bef16ed8fdbcd0ec0f8f27e2a4958ad98b4f4f78a21f6f4f96cf51d97fe0566ac95f01cba045685838f7db03d30ad856c4ecf5f1480e2fb60e55af50b8ca917e66e3b84cffa0dc50f620512d9139701be43810caaaf0c762ddb843fccbfb9205787ffcae3cde855013c5ecd5f64b68006ce2fa6dfdc416ab81328a478f2298e144cfc12f763daf2715652b22c1c20d7d1365f6d29cdae850364e32395960efb4d0064e96ccce5c4b089a3aa56ebc5d18595071b594024d392a536790f3dd1cdc0caa5f8367a5639c7586b09d3b1da545bda09422c9243d6f21b3a023ad806a0ef688d2df93d9f7aa05752356a90375b1a101b52ec1db9c196ab7532c44a1690f15fbfd2606a646592d44c647df10524167244a0b1623abb9f26fb068bcf72b42d09be0496c326d37ffedacc15265f7204d5892984c235e54cc4f3c0af4b412cdd51961fb30f4172965a54c2142e93d06e6486a61d748d138c71329990960c4d5b07d05d1f795b91b938f2f5f2e1b13f601be67bcc226ec1e595b4fa8ccc8dfc0f380454f1df747fe796fb6c26bdbec6ccb15d2fc5034f539bf2f843fc43a36405542ea6cd388a2b3d18c67308d6bc9bb379fa29dec50142db422ca575dff40fe21625dbc35bb3696f24099a920c6ad21dbe033bd851298edce552d73e0b77c81d7ee67b792150caa688a16d5a933545340025c60e95911002190327e62ba892eed528a5a4a4178a13fca93f203a54b53c5958a5dcb067e108b7b8ba1bfcffbb2412d0b86c6012a7792eee413443a372c09d4ecf3bc0c751911c33de3f003ca1645c4de0341192c6c5bc402f49fae10a7eaf3126260eb76c1c92f4629204c7bd70e7f26c8d6b3119fde18fb09d327b79bcc7b687dc352574b224977f1ec61c0dd0a6bf6cd527f24948a92ba5a61fd458450f045ddb8c86f3e925f5afe9302a5086bc0f09f759f8b59baa5f6cbffa93b5eb570fa0c5aa400e4164904940e94884824b28f2bbc7b4e79bf9b6e9002ebc9e017da0c49248065f37718ed74f9fb32ffba07266d599a989602b55d8a700a2108708de10f227a82d874be5f8b1489496970b6dd2a45df290227728e833be6f51bea9e22d186bcee723bd71d562b100da63164fbd38476a3aa305610ca3f3f96bac26a41cf884fc6b201602c7efa5097cf59a06707d7dd86ae4210016df94a2c9a59601a1b6d87db3b8d3da59d56032165c7499b6581548e8d69fb898acdbb28adfacf9604d47ad382d8b4b655cbf76c26f856ff28693b3c725f047bbb2fe72df9c38f58d8cee3435eb7beadf4450af322e3d837cce09d80f2c9e932d795d00a43c8359cac4f9d3e2b80d63144bed2559c9b733220c9ced94fea87409c42c7f5a6f2c8fe35e0389c195fe5c13a18aab1dbb97284a45d0bf87d7d004c264f8f687e93526a0b64632d6730a76d1869aa02ececcda1eeb1d05688782fb86c909b7ec128c081088992a7d6bb73f06644b9c8d6d12a6f88917ad29 +expected_shared_secret = cca4f1d172212f8c23eb5da77144640d821d2671f66f0b3015d0b46e274e193c + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = cf76c08745bcb7cb2c3478823c977ba1f3565d880d8e731337d798fd273bee2a03416cb6d11774e0b7c177e23a619509e04c334e486f97a963035c2952fa286c8108a3fa6857c080076143185603ef480c7ea135c76497ac2a4ea1c65c535385bb233c54b0326d415d2b01cb0fa60b969bcfd5578920a06659291b59e5100441b0e535b46294680627646c052d13404e486713fc460727f50677e48e64275e4e2b33da225686d920941277caea4d8f4a7c7b96b151b36836a76671c9010cc7546ed301866a694104169540a8620415037654a55ab132d56590663c21c267b94a2f1a162bd61808512c2e7c671247142c3cc54622697edb50514895276efcc21bb02d45c79a4549a501e79859361457047aba280f91c13556d06095a13ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a482afe97b508304b6140ca9da2c33f26522d51363662a0c437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fd927c2e3207cc77cc127790ff2634cc2220ad001e39ec393c5c5b5598193d628417b7bf5f903e9274c2a1a38f72db99e4c2aecd8b5b5b445d3d259057b2b3ac1b3a0657c2dffb6c75c93b20ec3358180f9c124fdac8a64d2b73ce6819bc1005602151f7e4c804bc89a81797ca8313650910c7b2a36ad2a690e3af7a99cb2bb09cb1eaca0891bc69d989cb7220faa3626342cd33438877799835c2782413a9f1ca29861752f294b7e3c2a3980618d0540a5cf00c01943db920bb4693436d3b7436593e7b9a83cd21cbdc692956cb3f7a17c41f46af94bb15059b8661349248235adf68b69d9944f2f30f93173ffda657c9d722d0521c12b2790e230afb49496a930c46a62a4d8c26601a4e783b73c2a465722401769365719681c5086d8a7bbcfff451e58b2cf32b363c501e978971d8c5ac6f41b458693c711765c7fc1ad7319f3481a68bc456eedc04fca898b0b3ab59a14b7fa1c148b6b792352e7ccb1456a86a5a0377ff98c08ac0bc4c997b0370baa76950bd0874f9478e6b8150770c4ef2885e88d119126492c09b8e93110616406e6bc7ab46ccb0b47587c0da1c54828f98941dae515d279308302b672ba10ffa0749395269f5c5a03581799eb3b60fd53355b3690efc291c3b77aec797fd09b1cccc8d5bdb8b4dbc18857c28ecf86ba3a654b8a351d0174df4ea4d7f4159656010f051462a3c4988e28e74c39cddb557566b7c757874d9061fa5f85693ca2124822891a4a0afb000a3887522326dbdf4a54e851cc775405938bdbbd39370c01ba010b8b3785e3880a54470546b617ad86bc984a70de844a510e6a14e241f18c765fd04c2006c6781ec90c9e16881b7bc4557945d68a4543a5f16968b39f38e8f5aa7699171d8567e35da662087aecea63aec3094bb4c88f08432b86780237218afc22ec78c96322a81b8060719fb6742c290ecd8664fd378a95341f3c326d992b3b7417c5f543249d57475b3b526b93307664217b8837c1c48ee6322df891cbf6943fdd445f2da71f8ac449c718e8412cbe0bc2efbe601ad08af68b48f7d2677dbe05914d9b1629b6cfb69a9f43a05b6fa560143a45f21405b25983115b537315964b3525117158013a434785fa13b30331148f028a2e3e299c9969fbba917cc27b851823630bbb930ab2336b59d1e0060e74230d6a0399087ace16894d1e4236f3b9b708645a3b27378a86c960bb038080f93e66bd1bcc3e57739591c386c45846cecbfc90ab3fd506ec50c0d0ec9a2422cbacacac17f62472b4ac6ccc645d48b0283a6c62136a60d62354a983d4ceb74eddbaae57711bd958614f054336a38630535f0dcbdaf918e5dfac711093974d2987dc1109ce7bf7429cfddda9e1826172114254ce0bc526ab358e359c35cba02e720c4611dc17122b8bb02702a962db3470e32620d62291ad8c9db86615e9ab48df3aefda4003f815a1157640e765afb2527b2c532011ca07e321673c721c3f32a2613394f68b687a042724c0207cc3b87675ab51a60b4f12d312a0fb5443cd0518b1f9788fef9a36752291647c234d49daf4a6a4bf420e990307f676271a47cfdc68182500a93c914ea348dbd544b3163780a2c2373282e319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = pass +expected_ciphertext = e5f3a007c0d3a9ba2786ba555a8c3f419bdf9df35908e4690b22a7ce095253c994778662f9b1cc0c358f8118e13cd4eba3108b886bb5a97b33b6887c80d2cd131a774fe781433ddc0b9dd679689546546b1c013bd7d8904a8bfe85933bb1488c37d4ef74b9541084f835cbe9a4fd7387ea213369e2d862ed7a5f2b294d2cc77d644a63c9d05847178dd0ce695519a92a0451d6239fcbaa76a24ce6b32624c9e3814f7da3d29087a44fef74c9b88eec2ce7f46690c9243221a235dc929a1ce9e446544427fdee71f1ef91827e181924c3d8f70273605351682cf4dd81088d4fb259c86dc3b4548ec57412a2ebd8fa5db3be5795402ab5588823ec62ec2df6d4bf0282ecc973dd8ffce0c8ec62f53b69cdbfc98fea226824eb43bdbcdadea7581ea102896cc57e5cd279a01796e023eeabf45d7b7813b2eb92b5054cbc2833942bc4d3066fa41d5dd6e9ff78dee4ae7f12ad6840148d2123544ec23c2dc3518f0b8b2ae13031a11dfd91b9f145093faf6affda150674412e4765e8bf21edd066e3205ad01b2f1686e8b7269fb41d793835f331bf2b71e6a53c35bfdc267a68461fd4a006947e0883824762e32bf1c1f93b4f98f5e154e32aec66307509ea72f2f9249b6c27cd7962032ecb7502c53791cf79a680b70ec248fe491ad71e75ae89913c88d5807d00eedd55d4ee077041ffe686e82a6f8d0c726e8b0da57b8e23382e8262912c7f2ded964bf4872f71011d39b887ffdf17f86cc6e7cf90cef123bda28e234e6dc0980bea57b733aeff0fc8c5d740a44cc421ac0d0e55478664908d74005ca6ece53dc69449de276ad52bafba85b03ad44c07c5210a1d8fd0f95f7a0cc9c88fbc9f838ed57926256aba7432e75de13fdd99ea43d034d12ca369640b5097a878b483c1ae1195de6fdbbbccb6a15c7cc8207e6405493aeb238c0d39fb544135a3796e52d91470eef480bf4f8f2a0b03a4625cf87960260b4b7c491cf446ac4f757892e47dd85b2eae90bb9b03eda843dd2f9993baf08b7f9142af62bc432ca8a3f3b2e85b08715d25ab36c4500250e8b1e041e3798abac3914646e276ee9828280dd9542d8e5aa28b80b3966b139da0ebdf6260410401f02863a22986ce2cf1be953ba68eca4be543b840ca0bcfb492907628d66afe24a2376f6c886ff9f8ab09abadfa112c5a4b92365c57d615a17e41249d757a787ceef452b5ee386c773685a2b723749cf9dfee7c97f1f0e524427039522fd0481594d777f03f7d11da3c001f822bbdd33c95a096f8ab09eca4b588ff9a68435cabb2b2cc1f39ac5e146474505bd893f94e2b603e8caa82cdfeb15873cb12ff87c387c476e96960cc182f569ffcc418900e6eb9db6d90df3df01cecbcd1f6d2c6605cf343cdb814b78a513161cb074c5b164b8c0248123a68c7ad12769dbd290a9fff6b2035715934aa78582ace98f10190dddffe8cab28f97ac7cbeb02c9c854a7900a3d3b5a94c12f00d4074d4016b02abfd517e4621aa16360d05a38a4fb6f22f0fbfde41fd0c7ac0d7583900c51cdb62be446792f051b5f1c768cb91f829876315566c607b3d944043d723bb985669f157b5c7d5baff47e9973ffe89a1364d0bd8e2db2e6814afdd612e5965ada830cbfe22ac43da7c9e49aa54f9da4f88e8c0df1fb6dd2ea3a92db1069f344f6530c472c400006bf2bb137cd601c686a9684207a828de1c5f401667e1a83832501c4def21805da23c5d63355be52f7a55d1951218aed1aa23303298d81db3453c9c8502942137f57067697f67179b8b33d9bd7a98ebcf63bcf6f925abf063c2efb4d29fad0914a24aeb9ab16e0b8aa03bde1ad7299105b12e9f222186a3f52f8344c8fbecb8a410328f99ed5ddf3afbe2bf2f5aa8c4d3b3a593e7c3769863a6943981824c8d9da5d46f1ff2836c765f641e3bec4079b1bc3a4bd3792658a987faf9dec7b3728e33d2f28ac93d1060f6376c8571d8334db81489dbd09dfeb57f9917294bb7b482f430d090da5046e4e7d0e1610dd4e0181687e6fe2c8d8369ae2f3a88b02f4b435a70de1ab2b2f8c1f17990d623e2ea489a63aa21037230ae37919f1561c0212be8d5ed87e1a1c58ac5503ccf40b8229ce8be8e542985e3bbc9875249fcab3588bf7fd6b84825f744888224706e1d14737ab7e162cfc40eb65b8701a09b38e9a8dbdc8602675980f7ebec5538ce3bf92e8c299 +expected_shared_secret = dd7816a8a015b2001258e665dc0e576ae19b10dba9704be9c484e4c8ba645522 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 2e225b33d590a3bc60ff331f856884594944a1055f1ac6bbd5f7bbe0c7b5363c984d408b493b92bca2a9395b7dd9a46c17b632976324206179bf05406e629f86875573d05b0599b561dc5ee8f54a73690b5c3b414fcb7aade872a9489a5530025b442c94052d5e892cb47b7c7585547a72a9e3a3cda629aef1876c96c479063c49e94b952cf819af8b3bc39995d4563337bbcd419c17c4f5696a6002cbc6b760e344a7fc49c2d0c0ed52b54f16041e5c4ecf2426442b9d59ec05872190a80b4f341312f91b7737cc77696acc5e0323e02100563519ad3002fb95b0591aa126a70ecb708143c7a502c53a77a82ae915b25be77c68006f4ccb0252463dd668537c24bf4b0039cac4a4e6b3c19ad37301b595c504909d8a4b8af71c0fc2c905e26b5317703b3195712070b0d5677bd5101c4baf9186582a8b70d163ab01c6151177b7c83b6cca2bbf62f6abef41c6ad6764cd8392819a85cad945ebd210b9c08f1333a393b144a4782e683ca2c73c5875f20debe3ab59c8393f7caf4328a57618197450097d250e9a77266d15cbd7b3867dc49c0e83c7717513bda8235e8b89fde06cef1413ee0a0e42c814b4da9d0b0c5961f73e90c57c1dc614de43c396118979cba7144316607bb82e5451e9475c0cc4127c58a69fc47e6f02a3fbaa03949a9760573b2bd3c6606325c56a23cf4aadd8024bf9d1020332cba28c7fee610d45674e17281e047822138b04df69ce9e11aa644c47fffc688ba4b6c91b01e2747d2765b7d9579485a37e7090aeae19ae2773cb4cc17b998c9d25955a33a0a9c47117fba45f02611f1fb59d415a93aee26a2e4726e50c457c692766d55477546785f76a2ab7c5ab983a90771834da4016a755a2040ee3f6a24145cd2f827729bc74b17bc92032548b663f50b307ac511c47e24e4ac4957e552c4662915074373d83b34f468bd66091b984692dd32669332b0527b0a0bb3df41556aee9693eaacf97047516b6aa455311cf97135b697e7e9a2e147756e8fb0b657b41a6352fe6a17f4b031efe17926b7757fa74831257ce2442066c624bdb106d3330b99d730e7eac1d1528348156352e266475204c6e13b5dc06b2596097c1da6bb2d31e139c34f732a70bc09afd6a8e9700bb20fc78e3fb15eba8b2eca7bda0508b1d8c0c9393557e62836117219fc2201c79346949c53d8414c7e673106234e98cc1508c81317450670ca7de957bfeaab0e6780fbd755eeb08a441f983e3c81468a7bfcbb152bf6a581a901564f2cc6ac13423c32dad054e02e6509725bf13605f646922bcf84fcb4b456c7ca25457415c7275ba54ae8c4717157a299fa18b49fa6be7460f8427516649440d4c0dd42814b8c4692d71b7b6c0049473472e002a53392d183b4ab70b6582557f8ed067eebc00b670b517433466ec6b2f967ec1720b8c68c41d2923fae5c4285c63b03a8416926b93496dd57b6e241b14f2576e7b9a28076b2dcb8c2f475152a5fa7ec98c952a263cfc221282d57bf329a0dad122046a75399507574289a18226afa90ce4d7235ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fc817899375f890470238004cc7520be51feb8291cb8bc336813dd14a7bb24b2b8b8b425a969c4e410ac4876787f67ecb61409885518e0533884c613f70a22997b0b8cb1e2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db8614024778225b92d5826e1bcca780400e79b42e0fa3baacc5825bfc0f45cbc485d69c024ca504a975ada9a5a822cc0c11cb3fbabc64d07db6133a7e91223c3658725686ceab91eb74060bd039cf1488376660225b42db441ddbd437d5193bfe777b35513ac8d85e6da433faec55fe969fd3865eb9045589b09769a41c963596ce70238cf7b407b096ea546fd5f141ddd54ec001b76cf634871240d9f82f77f5153e84a6a5c41a3cd908e962c5b8898ebd4287fb2c97a0710b448c4ec93cc5ef1719c91b92ae77b35cf2628396160f0bc3263003e2e89243f073726a657b2386173115b778cfc842c67a4b71d5276a934aa94d92b452286a35913b0262af2a4007642a0b04f76ce58a31bc776d6f1b8966180e2ef026763a87519a10b8049d799a8a3d038d5be31eccd5676550482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = pass +expected_ciphertext = 463d031123a2c978da1db90cce3787e657d434302d270680b17d83fc6a1d20f1ccd4187b401d849074362291c6428345717be577b5c466eb9de098fba1a8ec2983c82782d40c59d5aa38fe1c32c7d65f46733337dff0b10733925b6adb40f63e015b7d7648889dd504a5199814deecfb8f27c1d7adae37835a7e18717d1f0d990250e128e6de30796f0f5a70ffa5860ecc7dbce1456928af33cca30c8c6e66ff88d0f9fe07fdef98ac16875f05bcbfba2357744e405fc991cf4f79dd6a1e7ac820acbafcd3b6b08a0dbe6e6b25d462f4fed17fa26d682d456fe45bfb9bde018b207ade36fcdccfa00964a50d2933f5086fa51f8fd1d22880cc0e17b3050f69168c123e9622993213904a599fba68bebc1921bde537e30d179636fcc951a28b8e6ddac3876fd6b6b2be3cc6f63719899e2b0c0c241e9ac94853ad7a8378e12070f63a4a1d0f122043bdfeb1e98216cb31f26f6525cbb9fe2b2ff536c8bf5f6768f273cf507f5806605d086fd383f3eca5e20b0daa69d1c048ac30ac3d5327f166ef453d2f2ad3533d6ab83482a32a34fd2795131702e94358cdec743d702c64f40c1606a43c4a95c80d8a60636dd2be5ef48f2e58c8ea1d173ab2e64107703d827604fd276feaa32455d97301698abd9773438c8e1a22da3199a6699df6788b97e09a2ff174e78f6cb939c82a667fa28d647fab7c3177e21f1a25bb45f33a94f370ed15098ec34beab6e551b848773a2c01e5f47d32c997ddf41b7158fa768664f63294f1815dcafe8adc38c2835862c95b66bcc0397a79b950e48ad39df432458660e21120804d88ac56511a02e458d4ad0c9e280b58fbc595a651a27ba978535f740d5e3bea8249fa6325808472ed85fb5919784a826a402db695c24c8656a5b3e57f7f71cfe96fe42226edd6351e94df63022c466370c005846604e5d1d2e65d55cb3aa22bfe9c52fcb7cb8ec03190ac558be4f5c0c93dc3fea8348d211587cfa21d6592523c62f345327f881b911531ef970912608b86a56a7cdb6c7f2341f77c9e7dd83e83f554b68147fcb69ba149f37aa9ee5a13f9f4faa8205f16c74ed1ab56d94f7e7b8cbd287d5c0ab805e35ff9770b1dc6f8fb4a3b99ff24895af6d6aa664f5c52112481400046b3d76c0de2e7a59e46ead9cb6f36a4511a98e9bb85198503e4c9a6c154362bcbe153153d206988bc1d93610889d8c9a66f762bcc2e12755716ae22efd15933e11666da92ba74efcc1ecb234f265b895770c2d81c891a8baeaa573b433ca1472b1a99a186255d71576c2a11dcf82aad1bdbdbe76b685555de1e0c16f4f8f920085a08989462fdb055c66204d94f4c09cc10a9c98b367af509cff5c9bc175ca47213fb121b833114c9ff45ff85f3e9322c8a30feeb24ea684b744fc941e5eca51604632e31cda5ec04366d0df787aa8f8be1451bf783ab0bf582d0c04b05beb11e970a93c798fe8db58bfa28bc5659dffd605dd05155132f95b21ba865002b101a4143bc372a1c008ffb04bd06f38cdf9bf07eb3c1b0c45cc4f09b0db38b44f342b9adca8f2282c8c71a4ff8dbd47e6ace1444fa17e35fe3dabcaa9c2c3b9768b167fd0f0268bf14007e3cc06cb37dc422f9c0f3f5fbbfc55674bfb61413cd59a382f2a8195f4795031f0852ac2236851570c0254dfc90a8244fa25bd9ed40efaa27997dd9860e61a222268efd31aa09767a73d03f056b92207625c0962f9f8b2c58c1b6a9333f031f0e52a16971b6b016083b752d75af96b12b1eb4a31dc2e58fc60811616422ae613195beec540dfb85fa62c4c0a81203b2335fe4ef0054e18dc516d9ba15961d1b62474bb1c7322aa34ac9c24f79d62ab4b2590557db827e1066ec14c57a3a8ce650e1288f3d58461b29eab4748e6319b128d3059f3bef0978d74e7e4f5f666007731b16579ed28eb50e0b0c189f5e0e2347750378ca5fe08b04843c9d74de307b67e7862936e351afb4b8913f64f4226479ab763b8b1991945f4a87b7d7fe302000a365531655c8ef5719b4a97934e3ab8d9f55b459ee1c1914b31c4dd26e7c553bd62829cd2f1f678025514100a328f24947ab0b66020d10800678cf9f5944a7bf5496f3deeebb663377f140cb64f3057be389524934efaf66d81bd415f053d51221fda178857f1cba2b1c21cedfd18f30aac3cf48a721716747579c31e6d6c45a2e69c8427b05121cb3b190 +expected_shared_secret = e911f73a4c23637a2708739bd5ef842ccc57d32993f30d6ee1f88acf5093ebcc + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 6806cbedb0c2c364c98989815ee9081d132427943a0adb0da7197cc7430757f3868c49c045d39c8c085665d13bed825fd7cac7fc6933adf438a4cb6849b91a1c737d394c5e08649d88e9274009c4375a4fad4b164851540e43ac603ab6f488628fd7272bc1981ba03121c3a22e587ef30a793ba097d160025ec1b629a348fb8b854b54139d5b6af09a7515ac4ba457c8289108c7c316c069a8e454a8d1084504c2a4e03c0a321681d168933e0062bfe1635de39ec8c9aa2a5a48983c1bc34798fc64114c18ae77f13408f753da60cb892c52f811c8382b3c455c4c0f08248bf7278b9b4b927580a3e50930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c22529ec61343537944ac07cc5a1ae713ca8fcba73daa688c9ca369e8b8d99fb812489482a727d40c7aaa6290f5032ab8fb5b09ae4985d7558b8c55b9f0accb3781b9b2405f11c05e99cb3723922d0da4963e68487631722c0cc643b3920b8c2ac34b54e77c1fc748c96c186b3a5439fa2b3b2e1a75b16357e2210da4b3fb620407c4cb78f18178f2b6c4706b619f18dc0863c72794434978d20933fc79193894041183660f0437a2e309eee87bf538a2b8c7672833820805bc2cbda61e8f04b7839b1493372759aaed528980e02726eba914491b7317099215135175c41986858fa31cfb689a865375e8547932899867b987167115031f5b4dd263f0341395e1176bff3a69fc9b9c020ac8515af5e665a15f48a3cba1c4a96390ad7795f7695e654279802c46275bab1e32fb7111619c55c8787cc01140f0fc03fcaf4b6df9877e0f24971f06749bb343e1a5faafb66a75b4888a1c63f593bbf3906c324083f737a39247ca110279a677736e77eefd3b08f645100e249461657da00b365a58beeb48de3f96b6797850119145975388ab4c9025215dd4b0a0ec066c8a7a593fc0a1ca921c3c54659d40fdfaaa4f63a6b0d55a761e9a57843617ad6963087396a0187bdf593d98009ba825d056bab8e3b6ad5eb31b3f195a2c9b7cf9281c176b58346cdc24c580f23131213a08c4cc1c776c146893e8cd44983bc01494793028225f2161f916b888c923c8c30c43c41c1a2d12f18a4918216771cb992ff1abdbb33aa5f363e6cc044a0d68e6b36785951566e4a666af6cf9d3222fa17566966c734a364ce14933da00305930b47dc1e977b88e328296461c302c35f3e432e5d01243685c176e1b6876b03e341ce0a1c52ef32966d67004cb4abad9cc8a534b728db8c32811f7e71556beb656d773759f04a71f43413805c1334385e396e8b128225929977f41cf776450460707e0c247980ac42c69cb641af3cb36724d5705af745965181312a91aa000b42b82670a9aea43ac26a5cb3ebfbbdafd4225535255609c3a7d04332e6c816fb68e5ac05daf42c95c78f6db76213a083b3237b4665b9ede88c1bf53b4473005d4627bee21cf225bd35eb728932543956ca142b4f3614816d891895b14f0d28ba36d298d6713809180621d1b12ebabcf032aac6691b22cb9013d8a8dfd70ba1281a77f237f9318b43d043f193cf9e1004cda26f532ababca3528c69200624b613fba988bccc73288b7996c2de008f22755ade918784f7ae2f69ace6e08e0cc528e3bcc85403967da02cf1463c77976555460bba2824af0923f2dc4336ab44d54ca0658417f8fb5755f397fca11e07759c5ba86accac1e30523349168ef3740f59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d38752c435cce3cb9b176086019113ad638cf3426970de0013624313ff57ac82b1feb24195028b1b65bbcbd5c4ef3a60116125b3580743cca16ca9abe8fdc1ec1ca2e4d717a0eaca0fbcabf74034b74391d8d9668198a14e5491ec817701733be7ab11635e4a1e6910f3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b675a1660b7c22dd1947bb24f1ebc8b22b1ad1b81600b545f74ca076e468513c0a483466089dc1cd7090c4c5623b02b7824d2ba1894c4e200222bf867911c89d3264b5a081d7441a2f3729cfe4106a780237e179839323f97c04979887c4c223f23a81af875a33cf28cbf75722ab92308c320d32625ec326734a532333c8b1ab4767bcb682850750620c402878103056cfab5417354bd395084f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = pass +expected_ciphertext = 316f5978cb537a9ccef934d373cd244ec8b40bf72cba7e9aab5339dd2848b9007ba227f0e42a302e364d9ee9e6761ca09cdf5a1bcbee86baa24bc97e1cdc69c5e061cfd73c5d3446edae20513a9ec8314efae2dea09bcc268cb601e581d7dbb33dde376b56143921b5318086f4757ec70b9d33fb17d87807a7b54e2a077c3edeaa48900194049ac60e34776b975c07478bea0e76861e5bc6dbdb2a316d266c6d40889ea61e8d2d50754d6c112929cee6e1a9d20eeaed6148db31f4267d7da4f1747f468f4210dcffdd367f84ad35234b8b6252d950b7cf74379a3062baff3d20ef5fbfa48c3a9845d7f5371129b64f6adb9db6a69e3a89846fb24370629c589dc8501d98e18daac7054bef4b0d485fd35de5fbfd63f1c160ec2af53d8eb073be350c79dadc148f2b9f52829245b97ab3c86697bb1f9bff723eb633f366a015797180347c7fc1791bba66f1e05decff7d61f3f3ea00078d804ac4fe84458551649cc9426fed3eb8dc0db5acf85be11732a9afda217d21855c988ae6355c6e91f9a617175cdf3b5170bd34360e14f5fb7d00daed753b98b26f835344ddfd1d4b0aa04fb01d9f9ab108bd308b4d7c4d0978a83683e474726bb59508817e268dcd101125acbdc7f059be0b079747f3d22fd4d5c16b634939fffc1d7ea050c0452207671c0572d9228ad933f35d3896ee86eebafadf4ee549d608e3fe895af052df25fd75365bf8641f8e3ef581d2a4e4dccf06d56a045f1dd6e166942a998cfe234871b2b536eec90f95b5a55f5fb00547f34dd872e38f71b35d2eb339d78e17bdfd3799ee7f93a72ec83bfb2d4d2bfbcf080475d720676b26c5c4b9b30c98515133f8b3b7eddb64bea2d52671fd6ebff4773c24deeb8c20e5d8f09f1de74e12fe4e152221dca1d45207234e07d1711eef6f32f0f36f4c24cb0d724101d07e3d5c6a416b321af7442a6cbd1ce330915f57daa07fd7097ed0f4e5d87b57e288be359df4780c949a034449e9a9929edaefd094df3021dcc7d93b4cdf50e7fe524148a92bba0f0630d59f49c8c7ae39092013d14d5b942b4367a58694eecd3c614db59e498aae3cf84e373d324e9e893bf626797336f20b037c601693a3a697bd272476c7cb97c7fe6435925908e4894f48b02cdf6039200b1000a8c088cbf6b82767ca21bf46646d416a6686fd81ba82dffa963db5fdb88f23ed1b5850ec4193049426baf442980fdf1a60394d51e2c84f9a6c8cc940242eb625044ec03eac9e7242f6dca673447b81240dd019f23d379e52cbd2482e90ad254dd8e6e9814ac58f5ae9b16a126528bc912f6259b01d9f01ba1708909bd7e0ebeae96f27c6049035547b84cdf06d36add6f7c95cbaeb020c213111eb2fc0cc9defa65be9450179d2d07eb8c1e77bec3022511e22906a694bc28ab8e517b72e0808ac3ebab7d348093cea98199c2706415a60574cb6fb93aee68a2e63db550413dceba0fa85136f8a10db18f824844baaa6240ba4235f41822683669901673e8bc56d2b35a8435c64925a0281c1bd18c2d9c093430855f24f4a1b841588dacd5c061350622e536bbd7446de9df4be0944d3d29e9962614575adca136ce7c93e32d4f32e531d84757301c1a327d3641ee62bb79ee8f192577b11812be02a69e4f5d9f7c6d9ae5c536800d60bc5a6713c62ba25ff1ed00a7888f4e2186ea8d56b63ad057b112a9c325920192dff790f6114dea911e535de9e2dad805e4240135ca0199b96ea56584d76f4ad9d241b811baf547457161523840e7666601d39793339e4534b79ce8d0c66063220293faecc9925e38e6c9c29f47852d0f7193f00b07481dd2aacd0d0e7999eb6f7ae1e09578eea1370514132c2eb609a4f1a88a5800406d0fa5e8a125d1644af66715a8f5c078536908c1f6603a6d8b0d966f0d7ed73bf0ef507a385cd4c163d415d2c461ae0a2029f409dfd527348eed54c1a048adb3890693b427b6c6e037c1db7a2a44ff566da90a0633893b5e671bc63ac5e1c4f6888eb7199ce93e4a4c9d317f5d0b0ad678ef87695f4d545e995d384701673f1dc6c5451ec468ac0c9c18054c6835a54485bae1f252ba4d8e29b5e20b53f109d6e792637ad38c9e6093c4b34d20a9d23b82cfe978b49a5aacce3150649fb14ab9519f745a5d649a4b05e3f63a3103d1c655e2143b37cf17500815808e06e70f2f798a517f95ccc0cf60d +expected_shared_secret = 572994fb967815fe8bf36cf41560dc69aeba8e32b13e1d25128585dbb0e71068 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = 2e5317c2017a6ce707b079cb56a06e388b924e96254d26c853733b50520224bc51798578c4c53bc92552e8a42a07136992213a6763056a025106255f57e4670a6a4262445aa745a916a9b629ea64ac757186d136fe301c6226992129b493d0c2d635b5187cc2359cbbf235a90eb24f7feb5137e4157ee0822b0cc1761c18c25b18f757392863c24a13ce6dc84e3c28aafe018acc1b338a27746acb22f687af1e693df043625c63805ad42b9a368f13f19014b456c78236fff57c7de2b96e7a2223d00d9eb8973ab04c67f3b03e8cc1cecc7912033999101b37ec643605c0d70c1161a6cebc512380851f6a834de7631bbf47adea0bc17a6478f122c8be309804d2995541558d688b9e080c22bb3494f43c1b1a0c874bb4d5246688a2be22159a56151ac2e6385b1384d0c635ecc94b80bb8276f435a64883ecf51c43f066d481cdb5a21485380ca2874a38b39a691c12d983cdfee9530212439d154df71106e2854222454c20736f6daa41e9c949941205d84a7b5730b95cd3251c186dd97b1d4ec329521bbdb3394c819a984f87a7b3992d1d578b5e57ccc3ca151992395cc6695ecca7ab67806f2c2c0ef46a6bc02c2bfa17a8ec41caf87f48a146f2345b7a185baa1379880b00d0044f90e2a148186cbf474bab0330b8f029c72802f1b1698ab158e5c81343d34cb10255dbd1b9b6265d4c4a3b1905a650c29acf22ab6929a0d95357bc76983a201727b1a0f7c8464de2bc0da3a48a81b338a1855a759f764639d9e7306341a96b9aa52994bdad71ca3eba0cd695a701a0ca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d282b73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1ca0454a33bdee7aa80a2ac17fc709167843167208837594eb8a47ae1a38ce819c4ba7dc4521df532c0a6eaa5ccfc37e1f76e6ed20a1715139d9a41e2fb46cd5c0b3bea25f60a120222aa06e15504e4188116ade33507a26b927d10bed839577d2641b9550e1e921932185467b8c2856a430ed28275daa37b166e025073fa513a0c852091555b0e19a2c8e858c1584e229c6bd2bab500ec032abb4b8028b90e3b24feaa3fe2f826efb574a786c3bcba9829e49ba6318b2b24cca031c636c863f224619df40949b08ffee535a25c7187a92fb522376cb30d4fdc7ea9368594cc53921c857f7a1d9e9528a9cb817e423d25f791b4cb1e95e7b3e6dc406c83c9140385173073f7ac23d69c6aafaa6cf82862fe05a409521174328539b6a907f34d553aa77980c9f4959c329c563d8c03920b98563c5f13a0231eec58876210a5a78f1b43c1fb8b4490d18c16687065939535363ab88397e51760ac356c69f7b25458183a10a0310363f31c5c16f1898d06701824565a615ffc232f33513fae22b6bafa22177b142ff88190a207b4eb5edd4bab67185ab0c9b8acac2b37ac2108ab09f96461a3f079c3c018c6c058d2809f1346889e17cc488cb645c698ad3730084415647728c2116e013767b37bb513000feb359b84105bef19cc7dda7abcecafcbba381bb0727c8554bbac2d42c18bef471fce337e2fb99d69a9a54fb14a1bc6856dd56a020317c4a57e315cbbc371cd673a0b0919209f2361990068f0570b530b0678e01032ac6f95c2021651a1159b0b221545134c500d857c7ba0aab92cab5b5298c1b7b8ad588d0d53860f0563ad9c309a12a82b14486a10b79d7b6d38bbb03d9bb49db4c90610bcde5c383c418088f51eda6a99e386af8e1802d84b6d7f236104c2526d577adeaa8dd1c468d812cbdce44b04d64ad2938fc6495fc0a84e62e506ea548a8f5930c032b59e54aa54598f9653a118c5c83dd07f1b73061c02195436b6a66301bdc21953eba0e0e351e01605d9919956968601549abd9ccc9d284b3943c666cb8bf8c2112f52a5c733691fc2003c5b6eb8589d9594b8c92c4c4c6abc2e5b2bb67078f81849e5b6760cb1391b9c5a57f8705ea61f2cc475f1f3a45a2a0b12bb976b2874cbfb4f7266b6e1e20e6c2c490bab8daa779f0109be1a662c985016c483a71e636156186471a9ae452bb973ec28bc135133e9744cec8b330c0752451c6944b7a304a250595d86b394c6762d104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = pass +expected_ciphertext = d19c2f2cae13eb960f72953444d3c7b1400caf6ebc1f85f017b9e3ea75db21b9ab3b3fea55d9dab5931d5aa0f8ca4059cc5b34a84f735f8002dfc802bddf8d1ba392cd6f26d28ededdd92664d844a2cef31c7f2f5e212bd83d77b6e82c4792dc7270d41cca4a85a2cc649bec1e68b6c7dc4e4cdab1b3ebdbcdf5faf833f644df51d0475216e779589deb3bfba63601ee3474fee332ba1e2558f6fef6ec429cc3dd24b8ceb379d6451b7cfeb2e95d256522ac6521e79ca0a46070c5953d7a023f8e37342681536683535b7602ee52a7c0f510537fb807478d9c2ffa301fe7ccdfe2004a7e9d71edec7cbc630716d4c7013569b2d24e836c7018b1c8501ca3e9e2ac04022dd196d2d186e6167a227d528fab261b7a7f7abcc4346114cf13be6623724d92338675c3502434c1efd2c0d9fa11276a9d189f3e8c0778a9794c587488d0d20527e7c4045b1f49e0d59716c99e567de1a64ca26776d6fa783648c2863ad0e44274a96aed5a740b62684ad5095f33037b3b38932f37ac74d3bcde134a16a13a1b02c655cc91492ae9dfc3c4246d892e2a6dc8fee0edea910185e11d79e723be15b3334ace0d63db94e9d950163861ffccf4aac4993e0ae569d92163597e334ef1ea3884613f88e1722099ac84186e8d9e436160d6a7030f88f9634a2c20798c4a6af86d252f9e7f2c85dbf5f041feb022935cc987d9e065b726ce3bb4cf9ce8faed27181d430569729854a34e798274f558236c8f6f99e5dba5cb97b3ac10b74738ce2b91c62770a7aeadaa9e6c0e15c5e41a1151e774509f026013c7d6bb21ea0710a6b3beab18dd44ad6893c6dad807093632cd6d6bededed816fd8c7555c41976588198191c808996e1450561f330283752eebd51100b4e74e3c7d151e134645f6d1fdbe52a01d5d61fb0ae7ca1fcceb72c87534ecbebe172423f4293e9a6a98ea79182895f8b8e98cc111685b18cd99cb4211feb54a96a8a834aa583b24f371b4f8b5517add7d24945f54c1465b5121f7f6960fb210bf4561c8f3b662f2e0d511e27e62dc546c16ee91a8dc7003482c721b0a9dab43bac4a28b5ed285f32552ceb0611401d8b0ee444b0b2896b1766f8a26eae7d9d68aebca3e8004ff9e4fce24962abfd3d9e37fdccdb0f3e848b7759987efbd40d8657fa6736bf7fd831d975d527ef66ee7a6b8da173d5256923fdf22da29cbcfa321d6f52a17f9a1edc6ea7258af7a580e553888ef10f9803ffd32fec3d5089762ce75e2ba2bb14eeba9027f4a47f5caf1baf3e94b23ee6755cc4cf80bb2f4013dc4f71f0a493717288d8ed173d91742f4817be4c4e0c73e9d2a68b809d959f0fa491fe67dfbe345a4640e05fac0dfbeae1f885bce354b99b82897379f22e41a82b3f54244b489bb7341fb3524c6500a6ba916e6582f0e0b7ca715114bea90f0d4aa5e14f1f545e4347dd467ee5ad718d57dcdc0d2427e26e2890070493730dc1ae3711061e56c2fd7fdc7389d65c75378e902bfc8fd9599edced15bbe6d9895ef676f6e09fa935e3479af8c8e05e322199436a1ef8eb8ab51497bc7556db97de8fcdbf1517ebb87bdf6c694ffa93e25d1d30e113fe8e1a1f9cc6e395deaff5d043848fcd8990ef54134a30654c9b28b38b863ee6cb238d4ca8c9cc5a0af2ae9586b88fa99055a46c11185780a95ce967eb0f9f1bac11ca753a3762b248f8aa4ce55e47ff54d70e26f8fdc99ab055e3398394e89ee1c3df549838c64de1cfb93708453b0bc82312b7e3e07f386357fd92625929728a188d5bfe19d45b1878c1a61bbdd48cabd9010c3025fcb217af29a56a442b46be34760655d8748aac19959427c2df6fffa1af7229abed19307c99f0824303b75e34eeb011b10fa21dcc4022c8bdc75aaa41d3b4f4a79dedd5e0d8ad330e46ee3177fb2bf0481a7a61315e0395fbcb5a5d77e0e21748ed6f77bf845178a52aca547a5c3d6e24628819c27c023222bb47e6a1b0d53e06d020823706a4c89602d81d3161e9d14b33184324a684f0f6fafec91031300ebd8c8cf51b953374dddd064101f3c0922ba1e711afe1418c0bb7967ec7b5601396d88d134f5503073684ab44a02069d9684d70c62b0a235a141daaab741c1e5b8fe70e3c15fc71cf74d019d9fd0bfc38443bbdd75424f7308c75e1f2857716b3a6faa62fa940808c590bdf241c13b3a639bcd2971d34949cd95ecf21a54 +expected_shared_secret = 92c63dee4666bfb34fe3095f65cd458654df578f6eac0ec75f5235e5da6a926a + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = e4783db3d78351b11b00e292ab5425ab7110a6847a7fba29c24241999ac07fa77b461841c12519e9388635513837dca2a51434bb03bc43e89e9b73362cfc5f05007428c6c96271674a574f64d51cb5793454590fe9d42728c5c51858b2c5554b143acce2e1a9a4238cc9b88b12670e884b743168c967574f1ed1b700c50ce9f84d32ab1cd1e85a3a31a324770ec851a2de70805497a27148cb66249f8ba7796c02cfd462823dc9020f997114ea758511b5daa832fb6b4d05e10fd9f53d0837a5eddc05add9aaf668b87af55516b63a82bc64146b21290763f46b00a6ec3cfd71c702a28719fcce1f1a2b7d124a4ec8703d63865964036a27274c806ea1ab9067e5bb6d1766faf4b58ed05cca5c6688a86a5f9216ca7187423cb9d453825404448cb7290a5bae8848c41ba4cad130894cb385f68916d3a5ab6eb045522ba80c1154671617afa25e15734c5e5051f1e3173562899873ba90d670d644ae4192351b108f8511c89dc2c1633516b0a850a0345d46465bd058999ed227c8cb8f02625f4f0570a72a77fb1171aa577eb0239bcc2cbd00c82ed1baa91992ae4283be56094be2bb4c9f0623fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf30b0900716416a152be54946aebbd7ab8cc2cf535321a57cda44cd34060f86ca496830a16652a88d069802c59f902cf08d91afca82bb5b3aae6b4af650a3d7f5a0cebc8ce63a2a7c7e07c5a0cc9b18ab56698087dc65b2a014b8e00af240397d8c00c7454380df1497293327b81cec6e43154e97b93d9695d21c807f621576835e5b79f42d777230c8dffd72cf41a05fbe51765280bc6d3928c1166a6838e33a40b81826be34685203c7041599c14a84d3df2a044540957141545b465f03579167cadd8a93d83a03f7911406bf613562bb6a9863e80d886709978cdb75037b36a60f073ffba561fd87f6fac17d04b3233f797e091221114c78e794b9a9073bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372767060ec6951809848ef7cffae9aadea314d57780599cc3e55a8b0b04810e5b3a2cd9cae6d729e4d994c4d296f2b07dfc97596f8aa4636c70863ca52020b1c21c074838a4ac0360f88154c8e8ad820c3778275b966a3568b36b3f44a50a019a8d588849cb39dd813d5ca8905460bcebf94efad35a3a2ca588eb4fdf999e778b24c41259f198c20b219aa6c1715090000f4407a7217ff5645f8483a408facfe24b368d9042eca9bc803b9d0712b21ee36047016e5559b5d9bb6e046a63ba32a9537380ea73a22b662ee892a62af4b2710a2920a36f1740bb55b36700426287329e4f3b63acc77d6f6a94411a2612316da5b612882605a930a000c18dfb6331f9005427d63bd5c66bb0b4c496b6071cfcc8df3c4b350bb252d920b9ab3f73392b3a6682eb222c0fb065977b93c8d133fc07249f6a0a47d19fd8702f6c618d2c170dba4c65317c1d0bb188a09c9c4e97212ff004d9477fc36c1a25f3c725a7982146c4f3d20b0b07356fc8bd18289f860bb8834078d7d4813da9bcc2d3746f0b9387600088f277f9f747a9862be9a851cae219257b190c91c17c910dd8315a107967fc619c20093ddd6532b6a096838b1be3263f314c42a8f4b8b71586dfa279550ca54d87a1bd46b8d9c75861080294e9a084f3970d217610299aa8fc5814611a40bc01d8d60ab7878ec5c0460b916dcc183f826888d0a03a89dc3e27569b2a7a461ad847af7286af11a7c7a07ed8c3aa76b209d98c7aa72a5c3049be14f723c2062fca960c28925e6521534f855f3fec4054f3224851137ad18c4ef959e47c8134c86356f09b82606a69116b5d572a7c40a6a300b689721d37e80148821aa74902c0c30331664a65976c29e80034c00447245fef8a3a3dac44824b210a3b04f3b7af5a824632fcc5ebb45948ec3cb971607ee94ffca362ca60cd6e895c9aa0ce699570bcc4cab9832638c2269dd9b43f880d4f507768e4986d85814929afe4801008103900230956193e7262a0af2a6036f4cb85c581a5d1256cf78c1657598bf1c45f3048f3fcb0a37ab971d30f7f124e7662b171a5070bb14a750b26af9b020a929fd7b2b244d5945e58b5bb64b2f60b7296491d0ac31bc6a046c7aa3a1738b8563c234d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = pass +expected_ciphertext = 3568dfe1f0c59088f8abb35ad3875213a2a65519db7396b940f13f3c3128a64ef475f74df976eed5054329271bcf76017d4c1b4d12d1c1ca8ab36d82f7af859e14782b3e871c84bad4326870ea4a9987859130c77b1c2ce061deafd94eb6946cf39910fdc0a64bd9ab44e87c1abeb8fbd846575b0c50bae3f3d1b11eda8e3d285e7486e93ba8a0344b3f62036eb6b52106da8db4f4f960a3e358585d6b58521aa54785b64a6af668252827ebe8a7ded2f29ff588679149798c8546eb0ef95c47690127ae999f0b4473cf62d555f2c7f3d14e4415c4cba34d907dbeaa246f1c73b9afe7f4d7fb5ffcbe89180c6766a6cbc4392a2a381665cf49b0ec0aa445bb41dd0663c42259382e9c7955370935c166e951989dec85eaf907f4256a0e34f18db5928701f1735b5b2490b9cfcc3435bff0e3f30f0decd7d406e64a45e81d2244ce6c75d77ad56acc575086633f9e8852ba3c31555769ad954b8c5d168a877b3f32d2421f354b0ca88a75216c0885d9d39f69bf56473ee3c032f04479a45c3a5819835ebd3883b729ca72806ffb8c80e8f4249cb5e8e4e5b9d9ec154ead07be9e0d7af859b1269a82beb09fb815da5ed6f3f7b5d1a5aecbb26c5eeccfa52f81e9dd4a0df5f981b510174eeeca9be4ef422f823126ea6ffc490858997c2860a53f3a58a315c9df5b8fd6f5ec89a21c158e7328a236ef733aa13329e8947beb7c5e921ec2b3a750d5410f4512e25a657024c2ca66224736b41af8cdab22616909f607ed5b29e02c34681c7db9f0b1c981b458f56127e96e12534b0b2cf3733af454e9fbaa5214a3be33ab7d054a7af96587d7df35d1c161cda7bee9e0dde3b4dbdcafa49c5444937719dc7b77174fa1b41d795b436f77eba0173812d2dc5a1eabc50ee12532db8941a79c16f2b70dc8a6a9465bd7d05fa0259ed29163cf7227ec0ab57fa41d7c61ea1b170ff8ca0df789b079bde45b2289e686c1436a05e6b21c1ed8bb64c99af660f255a7b232ac662186bdeb5582ec186e327d5e895467dd14d5b45b518c5c80854257e0185d028f699e9c52bcbdea89c8816866f1b4b311c60664b63a90bedacd1d5b62521d1743e54f4d0518f81c221aaef93777d1e769ee10c7085b01274e3f4c890c93085fba1d7d26bb24a26c22dce7e0a3a4309604ea8630b728a53a24c998b6be599fef3f2f02b85ac645fc3afb0db2622f3afad432015f2f5ab114beeb9aff0289cd712ec00813bff8aba8b6f3a3f72c1e574a09271058c97bafab3bc6c7f7046add6534ed76882362f8b56492fdadd1e445af0958e368ef01dcd62a89bb22cd030024c1a69c2ca27e186815fbfa71cac29f1a536518ebe6524512f15a1d2c8f6540d6f7ed415eded2468e49710f97c85a58f3c8027b76d69d27a4bd5d004353a6bfcf05f694350ffa21531cbec13536f2ce843aca02f94609561a4e94aa019d2a60fb501a44b05db67a3f3a4989c361a8e196fc68ad318c2ebdf3a7a101d3ad3273c692210f01788f7cd8a2eeb9a5a6ae82f25f7d8713593a25f377dda51548e8ed46a1ba233b44160f77d0fd6aeac8c45d9c2a4f5845284adcd7fa389eaeebb85e28bccdb548d4135be9955568fcc22059fa98f81c7fdeb695242d08815e9b33adc7cff5c0d6fdd2a492ce921c44cee72da15d195b3e5508651bcfda255d029c2d9ff11de9500c0544c21b86c4c57ba3bda90d6afc8074cf5c218565c5b64f40f6e114720b586ec1b77bce3784b500a7717f0a8d5fe4c59d8297428aa905c8e42ea2e5ba54744a9af35f63955058288afcbd5ac75dd8a2fbe417c5fbc2a48c27f79757de22593f032c9052f9975cf873717d4fa74be7245f59c1166d573677781ad6591ed35d235740532ed21a41c617383079567183ef5a42b32c28460b16e44e129a99bb640acb1f374d3974f6094afb00e3ed232c261bc05598e50e03619f66861d0bc961bacf4ffa6bd61318b8447bfe8a9e4d97fefd7f99628fe16a8f388cef1a7a32200f0f186cccb8230f40c08880fe6d9f1d6fb19ba46550b5b6e340e95d0945b0b7915edb9ecb89d93a367db3f5f7314f134c4e5a618140f0414e44ebb94897330f17a5e689c103583e260ba4e356524aa6f7f7e6e461b8ea45643528fc9019a69fa664cbe90e5369fc74e2ff2e78266ccedcc532d7e16c4f97267b59a520845aee5f1978257cd7581d9963a153a45fae +expected_shared_secret = 0e2179fc3d310aca496244699b05da9b7bbb7891ed41b675e5dd48355a586360 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 44bb41c301705ee232e0a6bdc2e4c6bc55958859a5afd2b82f502e88a746a20179fcd60fe0276affa12828129543471c7c620fbab41db49173ae4a144eca173b23899a99785a25148e6c92e6b5b3222ca7eb3bcddf6508c4b19a039143b9d87aafc77ae80627cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861d950256484802a7b479b67a803fba87d916d0918bde0973ba3f2c0228c0dedd302c6fbc9366c4eb708234592cae1f3c58499cd177621731738f0d8573b53018ce88676ecaace719063910aa3d08b13a2ca2e64afabd52a309b2e0a849f3537109518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98aac23f489b85a9b18245649e8ec3bb8397c4125864d8695752e942437b315b7286675279df55cde5d20aefab94b1015030c40de0735472e02aec59027c8caf0074b0fff4bfa12267a3a5bc6a380632436041cac792330a4ed585379114b641bac7ccaa534a3863b52390d2173e4474299c8e1a2571bfe215c71b1d23c14368926a2d0944a1f20bbc536c84b7c8218b3937946cb227134e35c36f81c73d6433d4492cbe9bb1631787376115f6f9c3e5b76e83812494719b60231dcc4182c3e8a3e21122106b9036c62755531b6c5572cda5647746b9fe64286d395cfb759caf4136466937b70146cb99010af4088aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cb907022bcc72617cfb7bcce57988ca4c3d60e94d12c34588f173473a5d0929b5bcb09cd8f91534e7bea694576638889fb29c2074058900587fd8889c89593cb5186fba07bc103f4196a7063ba5c4229170f8830e254862457adeca7219f73f201130719b39e0b84845709f2cac7adfb60b26658ea9137a940b1ad8ca7966dc1c0e540eff9999822b5e69f58133902ad3704345914e17a30a96d6a879e320ccdb91f9f7c68f683c00532449f5420e8444e4c01df8b203e38327e566130c164d91bb14bec93b6eb4419a22c744fa9d92e861ae7bb13862288030551aa43bc4f809817675290a2413e71c9d29578df619be496061f7307248ba88d9a322648f969a2fbe005d9f895264887898cc0a8b35cfd0ab7afc594c9771536677571b9188d3b5411ae450a5a75e6dfacd813ca905b13f0a52153d0793c908b2d641b00c3a483293399d0b1579e28f240393e13c86e0121f1dba46fbfc9a5d062c1ef670e01c4b6b7a809470ad15f725b80849a0ac6f5370c1c96a309ff964dd1a9db2016b189a61311cc82dd652328596d6a2aab35a8020094ff7438064a7801a050090a18e9e4c2b33c14cd1f97b518ac9f4eb9a1156c816e6ce01d6053481b57b1787bb925faf531fdcba1be23570dccac4312c148e7833162c6219835ce3da23b1d149e434928f810577c37d0340b6bbb45945d789f6cca8fd5226a3c066595399ee696fbe2025701669454a83e3162535d51b11216affa7bf5c62a62d696d4532954791ab088ba84208a7dfe76b33861ba6d6b51dd322005700b38c8e4973c934e12c374c3c86c099fb42b2dad468a8701417e2b5e902b674b759a0f8366a3c00be49b43c39a016288a1282c9673c1204a73fe2b45e90aa2732a46abf8496cab31c52066052684d078c1926d374da041bee98939b4a597b2166451801cf89cac513a3d0890c3163150a54734b7960bf5701f837af59e9a4c631ca49768829ecc6d23122be873234d825209400c883cb47db7b60b1b1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342a4198366a8bdaccdab8349f9b9aef229ce46d4818bf188338aab48420b9abc13eeb990ea41ccca136fe6a3c3827bb40c33c1c749620db32dbd773043302b8b2b52de82910ba96ee430283fd51f17c38bd1734b4aa353345777ffac17797683ad603cde78c51dc45403e97514015fee950215b7366d76b29980c79ef727622919b59931e9a78ff6977d9e49c8da013a2920827a21988a713e8a378c3db9c90b8a2703e2961b246a5d867dd98692cb60093d617fd9493edee2820bb081b2b1c3c9e6941817b408255a0cd09eb8aa43c7d298954b2a92250aac1864d1086fd7338ade31a36f756425303a51bc1ac7f920a69273aa11b7f077000f9ba015035dfb96159d28282bd9960290b9fc51a79be9888d737329801428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = pass +expected_ciphertext = 8b5c5386694f22a31fe63768feec7eff7e73d01ad097adf11a44c36d84945968a6b59a167c808493407f5b31a0430e037538c9b12e5d52d653d6643dd3cd73a8aa48ef5ab20e2bb92cc79ca14a8bea99af098b29cd2507d06e0ee99140c7e88c7e79f7ffa90218bb356e648d034570cd834dc37d1d08d4ea82f88a502538a0243b280dfc2ad395a04823fb6183588f48d64ea0f81309fcdaa426d7e98eb2f60c15892218a5b804686bb842e975b561c977ad67f7c91d9ac8f6d103a18e2ceee42221ff5bcfda988521f43fc777a34eac5eb3a581ba69d03eebbb9ede81472c2a436b842bf899886e8058ecc84dead1e563ba6fe889a7e0b25ad5ff5b0077c7910322e0d0e8626bd636bb84aa0e7221958d66ea01f7423d7f61fb90d0c69922436fb6ff66e83390dad9e005bd882895cd5850a9ec8e7b64de89dc4fd244482806a8db6fde17013cbbb3a16703a3705b02ab690a88e1ad194ab6fd52d9d5218ae5454c05b8f03c40bc9a8f24a60f3b4b603bbfc251bd3cb7524d626378f0d260d67c027a52e16e0e5927d486a875a04e8a5c6abdec139e020c117b99f901c44a98ff9186e4ff14701b3efb455d223c108969675811f70e69d91d5b3286084161698b9b19562beb24737e9b998ddb9898d457defff2017d9e5e6c08145c3c766a5e1cc7a353b169570404dac2738716ff7ab0c2e56f05689b139a0f99119912e36ed1126702a7d5c52417740167fc481b402ec4acbcf97e45113126c6a9373e962669e570535ff0055f2cb51d1f978a60cd5403467edefb883fde3963bb77fbbcec128b62b429758cdde0f24262b5603edee30d8676e2fe5a234c83c6ad76fb84b3e8ed583a7eef115b9cb882f62e9f03306b400c51513f66e893b09fb01737476820770b62ead2d5bcffab7b85b71516144e20ec097bae7a732102580ce71b6bc05f1216615361224637c5e1005230aed6b17624c7b22943901aee4102846e0e9cda4b92fd41fc7f95e043dabc3fa1c4f860ed6a31236b1b33e60213782e8eb1ba3329a898d8cbd961d688735639a4705d5fe48f2682a5e58ff8a3524ed26e305d1830b9f231391527820f39a0abcdfd6e0ad41de8888e4e08bf777d8bed2a069aa66be30de2a210be0c30d1cfd25860b187e84c3cd71cf0a0dd59042dbfd52d299b4205c515997855432b79586520d60470589d1bfeb77256b3c65d95a14b8a64abc13c6d9318fada9f4d8045fcc04ec8da30a8d5bde9a14d1e8de93e9d9ffe64a77ca55d0d0473fd8ac11d3523a6f42d01df097d3093d9a7dfacfce4b49f03db78cbf0d587f1783f3a7b57a6ef7a45d7f47757591401d92899625b8944e60349bd0df5692e448607273ae7d56b864ccefdab75366c8435385f6f9feaf08bc3db55e4a2c18ab236e01f272ed11dd0ba70259f67bf369e6fd4972910a2c84c7b052deacf75d7b495238900b3c891bc46a95c82e3ee2a36f7a6e42658aba552994d1f6fb80c1f5b2e0b7ae01605e8ea55ff1b6ed14b4de413e501d8d9dc1d23e456e8c17228881ed90c3ce76d51f9f4dc74ea863e83ed32e47bf3df0b598fd7c5e10121a8cbce0b4bd89908384e2ab7cabfcb61ba4a2b06a524c318a739b13746e0110b50a56a583c0ddd133a8177b2a43f9000b3cf83afdce5617910539cb1c980651ecbfa2b2f1e1f4e4f97055775a5f439d861ba4694d8dee0f36220789b902fb2b4ea86280e0c7bcd638d43a6cc399c7c164fa5c75f1d547147589cb02b2bb6fef44c8927c0d26f0bfa8c6d5d341da0860f6cc4f9cd1ab4ff9225f71411e3a3b30280b3883e1e72dd29351196426f9a7aa2c0790c8d091d4aaa30b16e5262dab1de3d8cbaa951e003ae4ace9fb9c383030db4cdc6347863bdb2a4beb1ee0eaf1a276871b4a9f03f7ffb82f18edaf1b240f0e9e872247529c6c2a60a02a90526609b460944e52484e47c38b2b876854b8a95875c0e057902df9eb500bd113819d73b20055553bf893ad2af55a6c107aec3609571fd7fdb05fd1a65a206f6799e0560775865aa3eab49fafa60aaae6fae87ecc06c18d5499b71ad27789634baba61854282e2f0f7d06f8d4295c7419119e49a2753b7013ceed3f4f44b008d41c543cf47418d5ac2769253b636327d3970c0c1963f2f279c2415b03418a1a44968662d8663f7b8e4ce66036171a3ee37c476a239490892f2968d19309a460694a3 +expected_shared_secret = 573a8fd5e5935badcf974c50cc36e191f0ae2c1458fb00d4117e675424d4e37d + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = c6e762e6e2c322cb783f069a7e5594cd26a0914b3104b87318d0489a63ab263c88d561a4c8fb9a77c72ec2b917f685333c61989a4b3995d74589300688d2512943ae79335dbfb0c52cd14b16c085d510918696087d2ac47437c0294b8626a65f1e373d19a0107de053219a22bd0907ba19b4e7326f765989ea61174151356f04585cb89ba8d05a99808283b550c8a3816eba213362b5cec5773e152d14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43ea22074bf46f252a125d3740066509c48ccc347abdaf436153911dafd114555964c49ba9e2605213dc8a71a05e37b305f922a4e9a3b31e973e19b161bc4295d290535dbb8b6b359855d811614c14a408c34926be2700418139998e356acd5b85281b61b0c78733b0aee5a1ca99b56737c669d535b276c5546aa72673c5344fcc7923f69a0ada7096d75e81e32e0a8644ad73a4e7d19b3be97ea3d773be842597761818275cbb8aaca1206fa41686613986ddf37949842ba1741e812217593815c82ca7b583513938931b0bc829aa55d85a32b6822013244f2a3bce15791620e6cbc96b8555d0c77705c7cf996292cb5592e490d6243bfadac9dad7270a125e14faa8f8b321cc6c9e3b2407000340702a4c97a0189febc47e5baf51cc060af7cbf48642d46911e0889eace6bff53ca189a1036ba94912582b0f8b679a3b6ebdb31b7bba4f9c4c349052c4b9352d45e68463c865ab331884982c05f3a1fd78081d946a71d984887041a0e894f6995501233363027a3b7c321dc4a21d8463c9369abec4826f0906039a1a83cb59cac584d7c6426c91767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444dd52b236d4cd2c26cfe39c1cc8321cf7156867b37f85188abea7a040400dbf4830ed1835b2d47a6b8991451a7889020ead45451f46623002b31839c556a22382130b7689cc92cab281b164dd237357a195f4688f8f385f8f45a32432bc238a0c7f78324bd5b9e73aace5391d60f28ddef61e4e2c493c136b74229edda96c22f70f54435c6240747d963e576b2aeab0bff2009ba0f34b65c2a35b72477f36c914d048545c513ad61f964829a78bcccec39d2db38496a209afd760f1a51654d3125dd42c3ee13353f93e0114469c2abdf879050cd9466b4606241158a60b35ffe1a8956815419b9fe843913d22b93c7283805ba3098a52bc16bfd9b27c29155a22c99eda56530a69964466065ccaa447b13c4c8115adcc6285d947aaea1378a76e163556c18459b1ac905abc9b39e21e12486a5e56a228395093b150fd550feafab094602672860e5c74240ac705f25903e70667968435a4dc3e24dbc77e9806ee94436ce00b11bac776b46bd85a94634c1a3bf91e53781f03318aed41011a390f48e5b7e2866d11783c7b959882821fd4745a2fb3bf1e87756008ba1103a508a584a3290a4aa4783f10a9e62a73f11a0d18f9b8e3a608a58317f3d3909a5a622bbbb09b52350a7a681e2a63f02504aec572328155f67100b6331f38835fd56361fee46b903ccb020a2998d651bd2cc022f1b4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f43259025724ac0a05e9de54257859858685cd602bdedc01047fb903416a2e2d770aabcce2460903feb40274354b2e705111124887b331cba10673c0d2aca027a2c6ccb95c701568c20346ec747a29de09ff6311fc172910e41031b95330e240ebee2026048047e03c6de9a293f501604d3c7ce57a715db0aa91a6151230731e02f467477d04a5aad9b2b8176a1f056c3140bb1454cc7ffe380cf97139f4800fc4b740a22520a3b2a8730caf5e7580352b936ab9eafe3cbebaa87fdc771b0d704e455b8153c4b6cdc780ec415ac7326be810c63669a7f30a138a187108880b5ab97265a2158f542c37828c80b4bffb474ac27c6513bc54f0897ccd9948dd3c78f60c4cae733aca6caf41b9ca8052f25e58e78526ac8eb30afa960a04a322c582e5ebb286accc225a187a074877c21329856343c587e7ab6b09c3427091655f34127e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860ca17a63d0b154c9941d9c219c0a7c982114fc0c85483639a0f047a217a148346fc844c44f37270e775c5ca414ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = pass +expected_ciphertext = a4793adf41c5e21b686b9de3d72cec8129fd8a2e5a0fccb6ff7e2f06e82d8f3aadc526d701e51262e5d06883621cb5574e2e450a20fc47f20f7f6355dfce304028976c5fa57b63fc63e6ccfed59124d0a582c43419e433f415152162e7e4e08589b042524ebefe95166a55785ea189fc09b4bcac859274ce8c6d01ac52924874c8862dc1bb3ddbeb1fd480a1866567717956b26c55b29aacc0de9df4cc97065657092ccfd5c3854bbaa5282f217e1453deb8c62ee5a2babb288be4984cc32a86ec68a46eed9e8a97c369eb1a571105c2d63d52e7ca4921e6dfd4d3755d24965969c1789990608371e7c3a50d25aec8ccd9a43b681f4ced65d76640a668a4cdf7722b3e875a486ea72ee2e93c1d8b2cfe374e57dbdb28c95c9e9a5c64dbaf4b1c7132c3ebf3a951e013c94f653e8b1cd1f9a520fe7224a5b27e267d21662faf8c4b23043ed8b184bd02749654a25accb8580455c8e2af7274f9d2893863e49cd7cb7efe28a9edb4fec5d5acaca155aaf9deeca15d63cf50ddabc55dcf0c24748fed074447599572b51b1d6ab9b282ed9f53b5b77083b45d1f4b8eb0cbf8c29c0ae281ed97d9e9bd8a322cf48bfe70e7c091aba044b99d03336d015108831b5a7b6f5f2f4617097ea14895bc7bddcd5aa236eda01bdddbcd527d1d28de96df5aacb6103d214eb7fab3a3edb9e53847c8944716fdfde2365dd96a7e5e7f87f7566e52113cb584d17b849c35d6c99f0b5e2a2e48e618e57629c7531ee9fd098dcabb8920b97830e611563fd56b852c9693f0d3bbe5ba879ec4895d5b9e58cdca0bedaf1f9a635b2c73d8472f473f904c5bde372278d88d96fca6945995157bce76f8c290ea58164c0aeafe262c2627eb44d2915a9822742f3d1ff1a6c114ef3d5c04c827be4c8ee387223cbc0848e5bd8c59d869143ac4a58d0fac8763fcfdaf3b68f5edf1ddce50ef6d5d556babe89ed42fa2fc6e9d09307342d819550ded95155001a9882c69c38aba8478c1f7c9f1d85f1c69f062a835da33fa93c304905f9bcc0a8b5d01f8e67b0feccf3dddf490d7cfa46bb851c7e3cd1ff72b045102677b400cf9e3829263ff03943bd1767caeace23f387eb4ead7d27c73a703792279f9ebadb385162e2bae31759fbc735821d547da0f090ce88b12dee49fe9118dbb908b26ba68057ecfbacc84e705e15d4a734892e2546951cccfa05dff012e0b76a4b25aa648e78ac29b99db10773bc0dfa84aae26fcda78e906099111f3550b32aed526883a07977578606c78a15315969ce3dbc4cd2529421386d2e20001652af4aeaabc9085b26164f8a1b61a396be51fe6718f98e2ce4a67c5f36fe46cbb3c2e06f763a15d1525068b5b3dd7911f237e04fc00b461907c3b494f7400f6ab50db133d61f816127406ef28a61ff82903eaaae490646a2fd35da87812cb24abef28d381f319bae58ce8ae3696c30eb3db47e68c6e10c12a98039a3c2bdf4176a3a072fa5b020c30ff3e0ffcf51831a25c85523ab881cac1bb7f1ef2f18b1a7aaca6724cf60564e3aed54e5cc5b54259606a71d41a561f73605327d8429ff1da22f80c6f518e505f9b020cd1cb899b69e09054db0e7ca12c8ddb7e64ec2c02dc4b9dba1095487efe828f04f6eaa4009232a4f53db88b0f3335e3277a6c86b814829d920f409467503603639e7d02ed75dcb0647d0110722f94d7cbdcb34625bdd16683e00907c8b43e8297f937ab953fd0c22edc47419829210563dd5658ff0968b7c5261b09470a73c15f960dd12a92459f4fa737b63bc6ffc85c6bafb7bceaa947c564a3a30f0e540de9422918ce198f643666086772efa12f74917c269dd6acffdabcb6a71927a693120dcbbeae2a2023d1bfee1948b2d85bac9d3911b4f3e23900ac9b3624397521481a0a19502419f48ed2bd98ce979230787bb3bee28cca07b3a6cf8b1e37b11843d5fa41ffa77940ab9c90d61592319f728f3ef0f7ebb83c6f0cdfce9a55218b513d855e76599f1863451d64345258247a812e61d8aa5ed86358a95bff574a2a2c69c719104a04ed896921c4529154b0659de5e611ea81928f2fe57c02c98aad4c2932f9d435157ad26110eeac754b94d671e7eedda2163dea0e78eda73b2f776f69bf0da1c3a01a7f30979b7f8d4a2dc091af08904f123e04590014b9df8f6f724dd2832ca55c8b623dd435a2ecba4ad72119fcb42c2d6570 +expected_shared_secret = c8d5e0dd64b4f3c6450fd24ed2918887d3ea2806479d3fcd5a19894f4fe401ea + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 4eb491efdb1988b9794aba1c0d42326e9a797c67181995999a1053b3a1ae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f263916041ba9ebf2b86e21b127c5951d7709fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4d50fba956ab9b881ef55a6459199c2987162774f573599ee0b6b001cba6bb5302df24ea0622d3fe2a7db12a063d528baea6dec8a97bf12a61249010eb7056ec5a9573c77b848a6c6fc13c070450919054c05be006a40368094775032efdb98e087991d76a703924528ec05ee50bc56d206895552cbf4999c6a7617ea35652c8d5cf22590bb9fcf62aa0e055805279400b2c9522cabe1853e06e6965b517cd04538d7f083e27b95c29b073ae13cac42beb549337491b88c877af8910bf8659fb2f309442460ee93a0344ca83c58c1840c95ea482c81380bae24c01c763b2bb05b369bbf074c8e96ac2b5b73920ae07318057a643640fd58c691209b08c9b5cbe972adf001e8c00fe853631341c8a634cc52c77754790a6540ce9585290aa243231332d7ec3161b096ced68d80208c362707ed892921634b4de6679e08a10f55c72043348bc512ad39c07dd41a88d3c8c06769b6c080b9a24080684aea9637527a099bd53af1505eaf0272a1f537593669e6ca1d5135ae9d77b737b77a475b61023777eef22477b663d5848ba7d8859042713bf7353dc46c2e3b9e75788b3813b4844c0a233019529809487531a820a079fc2a43da0874c332695a79aaf3c6d5997bfbd27783064c1c055b82b3be463b5b54eb8c2e42772cd56318c6658e0b90cc31596b3880033338e6e41e9d1187e3732b75f50ed961501a030d221370a61788fc8b164625939e7b19d076b45b51c555d063433709dbab05746641410cb34ae53e3652a0ade7ae5dca29f0e22048668abe03869914117b6cc18617946c73a20b49826748981367090e8b72b8181ab696b878c79bd16683b2ca698e1489daa23b54eb017f4000d481b268e2c7c02a75fb608217bcb1290746f7251d010a581df15ebdba8c5d379441d22e591c4be3c9cd9af05956674f558c2387518bebc02dc3c2971bd264143271ce28b1f419be088922e6644e939738b846cb651267a913936d80b2f4e8987b5c48c37672a222037fa1529a764be14a87939b6c72b7730ffc4db926836c71a56112724a88c9f55aab44638a4c9186717246666b28e1003ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed16b0a526c019e7399d1996f44755fbfd86a79d19fbe3957ee97a08d668adee16b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd2c0b398383378ab973c9647db074921531a9441fb53a94e229b7c7ba8f2ec9a1e830b9826bcf1d353d91abb56b89c33fd37ee6130757d08a1699929808c881f9907556af18a95938a1bcec20191ba5a9ae32b769e3c56d4cc6baf9c9152359609a9e8dd6aa9ccb12b35c9db5605bd8868474e65257f785b429c1869bbdf6e118024c906a951195dc4361aa95d4c53ca418a7b6926cbf539ec1f242dcb3b96e47bbe6cb0cd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091c701ab73271cd86765e760f0a58beb61b0e2d12bc7511d04b98e8fdb5412f618964367e2cb694af203ab805889e0936c55bf8553b2b006093c72015d8629b494a04e3b51cf18347e7a025064a488b42c0328cea0c57dc14763a74368e36159c72b232c8424fa01b5be63014fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc4529a00c1ab9f67e84de76500f59c7088b1b9dca9ca9f0309b5f12eb4d55f3d734e086a843a39b29de99162a062b1e6874281221ea3314d784572bab031a3732010a50c0ac8150691b621687b6020a5b347817a3899f141bd6454ee1b25e0b130bed368c5f905c1637c036c22f65ca761270a9e8bcc18dabdd78bab5c48a3ddb82a01c646c9dbcccf972b9f0ac4edabcea3088586e8ca08f7177ad3cefd578f9fe6ca08c99167c65e4c6193251288785720ad110f58f81f4b938dfd813b76887cab48bf0cfaae5a8a16f3b110e130be7313411d517e6febb2e0ac004d44380b8ab62e874538d005d4f744918a250e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = pass +expected_ciphertext = 609d810d89c03c441dfbb03f5bcdea6edf70d1a067da94f6ed3e9ba09e5ed29dbe118daa609aa4e7d5123cf423003aa0c9e4e9e1e181fd5d8511e4c2781bb2d1edfec62f31ecb486e349849bc9529aaaef620e1ac497b54d315ce29e1b0244ca97a1fe8053eea30542115b1f8a9337f4f0219e5a1d4012b44c3ccac837ef90e92fe9f33f5e968d6bb35b4c8cd608b3d15cbf2e262da93343368a4a3d91108976175688243a9596b62d1d6d7617c31335dcdfaafbc1d9f3928a8d19aee6442e6e04c0b72f119a596f203c0118d307164e8896f19c903f968f5bb3970f71c63dd91e712b9e53e90d796e6fc5cfa7ba75a3f0c3ef415272d9f71b328112cde8e5fbdb1e0ee8813387dbddc2d8a6a8949381f6d5d19cd4d111fcc78cc82134c204265c0260a3443142a6fbda728d2b6ba19eb1f8c87e468749048c9452c25b89f4c065861ecc87b91b5f26c72bd7300254b44c6968edd020539f3d7bd3c4af5bf80e85b6b12387c95d0f587f31357dba76f89c84db06647cf5e9b1950074ae86ec225f2783fc06b5543301d257e821c9b2f0aefc322fecd5e8294ffc4fff3a626f0a455d8f906971ef6077704a3b0c9275e7fa3e66cd3bc4aebe6ba87e545e42bfd9663d9050ad6528a27f6072b39f2616b1610b937f888884fb11a1bef83e44f0e7c3fe5f0377d0415cdaa58e9662dc92333b5d0361a048dc913dc4b603aa1f6ec4b71e677964c5b2359a3eaf6d457e168e1f7c4f5d6f2e96177bd0ab814a038f6ea5a06de663597e6738c026b581a7b4ebecde74f7b84a8bc01c18275b4a4347d9902b84a0280ac7b202317c0831d72129d98e112b6a01bb1396a3d724142ba67352642f840502e6bcdf7a3c3d84d1389628cd5072341e83e58d3f3b2ed7aa04822904ae8eb7aa119c375a57fd3d41f88c94ed420379b47bfd987e23721779368b76fd92e32c05b835f724e20deeeec9e984d4ce9bfd52d61b63dfd73d24e51d6005d63cc8ca34257d84dbd88ff6a97232cfa190f6c7a66b13155ce7a341da5958382af189e3b45a8e884698a7ba4f5345bba4a19460649ee5844734bff46e0114bda1265786bbc8b3c968e32a68373079d3ec5079d2faba3f31b903656d0bae43b855076cbe4e9c597f31dd77a981b8965ec13b453b345dcd665f571a76aa7a8769c2e0ecbb3b7911b3ff0ec8b563be40ed24aac61a794716f950eeac5054568e614335caa170e5045b06ac08da24807cb2cac132576529510041757188a8a2136ef544c75838f7a9852b45242526d1cc1dcba9d375ce332a14719506386cd09a972a11c6f40e31f5bb794feb9b36696087f271707fe6e6f580090775478428aa05a7986fb3bb2f23aca96b34a95d2c7947fe1bedddb527df4f816f6d726aeacfde3ecfb23b05b3f94911adca76e4776269746341daa40ff0f8c26fb8310907cc086a1a3d99b647edb2effa7c59d0f3eb615600a56d3b3c5458df518086f8146a7c8755bd1072038d859bca37b9ac9fd99215beeee2f59237ff2280663c406aca9c7ed87763a9dd618f734a452b9e9438ca40df7b22ea30f32bd1eec2ea006c55fc594b3b7643b46fde5e8776d6a31f1ada8ea45778cd3c39b1bfca7bf7ac1eddfb6430a2d86d5499b84cacb1669973fb82e0edbd39b0fa19909ea012b5d2f17f37b5cddf98a529b205339d58289731526aa11be9339eda449c3e60f229b7ef356c2bea00f0d8a89617acd6ce419dddb5f12c9744c85cd17c1cee5caf69a3e456c274f911706bc6f503418ae97fa8dabfa6a228c82378c1a56ad6e1e225cd73fac1230bc58a365252d6a86462410b2b72be47204d23af3ac8e2b014a28f77aaaed3bad6228ada26d8109c23101e3eb30dd93f219c00102e285d29dc10aad691b860784fd1caaba34f4255b27f746c8fb2b94a34f41dad71dd1c5e18e4b2c3c5fedd3bdad66653a649a3aceac9468de6c08099c70c7d6743e2ee329c50f8bffe17245a1d4dc9079635a3bf0d5035b6be5cf014a713fa578bd631e9a6198fc90159cb9d89aaf7f96afbc1130dc98143db98c58117c7c2e4db218f426cd959ebfe63f40af4d059beb8f715eb4a1e0f5a8981e63991cea7f87b07b29fefff046f38dbf22d53f3a2ca510f3d2d5636779228b5636b9458ce0e79e60a6422e6dea3b6f51bca95dee3a3de8fe877474897bb365c4d14c3b905befe7cea7cbff9dcf25b8c +expected_shared_secret = f0691ad2fe875e3f0993f25452c70f0c40891b998deb6a7f7aa3c0bacc59bfce + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = 8c06203871ae8b0a2c3bfa4695c43050870392401315764ff65c9ef0db06b03b5b5582b57e1a7ec6ba4ad832a04e31268a853aaa2227f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f26d0769aec141c0686f750c1f17784cae142b942648655bc8a0acb8247462713a2183223dfb093a737306e94386d878eb8babe7ca066fcda152a0a81a792afc9ec32369101516122782100b24b02d5b8693a712f4711176b348e2aeba7314a3a17d0ce11315412e54a6508937a393897b01d361b1fe9b0b7cce01806a62d12470ad5650606883872a55030827b5bfa8a05fba19c9207f113c99fe5985eb70e88325e5cf35eea9605317579f15b161f55a81b694b0a79b8210b2c77524383aacd1936ad36b43f66fb6b5e668205396b40b3889da25e21fa985bbc6af4980d9fda368507a7659785363c6537f067eeb596f5337640e7b3b1877804f21c14d76d69d01b67a941e76cbbcc3765aefb0a74565470e7320605a0cc009c60e57c9e765d2f835dbbd91482d43b86858bf82161e1c3586290acaba2964f3a9b83352cf40aa26442634ef069e2932a470a59aff725b862b880e7a75fd705ee50624ca368e8c39c27ea0588c8983a453bca30897a5785cce2335ef8cd48217eee4485abd47a0769a0ac99089bea59c4481b18d27c15d92e915285dc62197f4804ea3b3e79bbcbf57671dedb8678f1264b420bfe191f21e489675b7f1479a390d0c8fe2a801f4cbad2f90138259904705f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fca06dcc3b3cd617a3f433174053885f785193c8a70432ac83c37b60cb1ca407f22c7b577f4acea879a8ae700985028aea3475426a3f071cc5162233e793aaf9936dc625a292b84d185ba31f964a4003c3a96701c6ca96305205b5071c3a6540d76c14e969a8061146940907ef20b857245c6f202b8978a23a6c84ceb3de596c10bdabb2732008c6a224de0ad219b9987099f1cea007d1466ab0719e396618014787ca6b1a2680e96a85c949486105bc4357a93a3109422e52a44bccb0c8c1aaca7931973560a82c65d253c02b2171688648a2c9f93f0a26ba58061c8cf64b54f2930a2a4c064cceaa6d34c76ba200c382a1fd1b70119304f278a87a77837856c68a119ca692b8c39782a16ac11cb6c4d9bc7acf335aeeae65f01a50d4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd440c449b8bdd15a3de54a3c1a17a444cb469e0c1cfa347b5173fe6f4749658984ca0530483a86b773471799b9bd53faf04d0a3c07515a3b915964aee1010333127b3aa72ad964f38ea89a4c561e36143eae3003a19cb4de14fe88bc5b4c236ebd1930474718ae654f43277255b1f508721ca318d2d5255db804166d94cf305bcfc6c91465b18f3aa4a64b624bbf395a10967861ccc3d13a17706511c8946ff31954962b9dc68aab370baca922b4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2b526eb4131e48546ee449d8eb7b709e296c028c6d085a3d614b8856a6d076cce23ca4ebc192ecf14954ba06415280275ca743587492e76a5ab5593e9d15b10f829dcf73a94e040d8a25aa29616ac8a88cbb148e1c727b608305841b8f3c63e967843c9a50c43c3366293868f1b1acba037d95b64dd088e07d42f2d218b18eb7eda5a2506cab773444f2383a5e40940e4f26033c336e3c7b5d7d2bbecdb39180c87127781111b318fc4ab8c50926c932a122aa79766a48abab6707710c66030668540cb5c8d87272dac2683ada81dd20aacc3c01df6056cbd23735dda391332c773934e361a1b6e247711a843644226adaab77089a831e37d571517dca952a58c0835705b03187b77e6ac91d426ab21b997905fb658c6b7510ff5e45e446204fe935a7612a364414014483cf1bc844a6935ce351d1e090313a776253386a01073a416b47a943712c0b7afd130fe833041716530c4af95928ebc541961558a707320a5fbbb3c113e8b3c88b0c3b359c13ee24172c8b649b67c645e07400cebc486383d8ea2afdde8c104e69dab368f092ab3b3b85fb70c3036fa5925301430d17603902b1373258b206b814bcef5a2588981339cb725a5f38a079935f6a27578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = pass +expected_ciphertext = 8a8fc2dfe41f13693c76063bf85b294dcc5af350562458d60a351a5928019ce73d03bbda5798bcbc45ecf04170b4410963babb74230972491fa66480de29f461a97fafe6506905d447f426d7b32e24e71da2abbb27dd73f2eaaa73eb40314cf15f6892f43993793c36bab7bcdc4e3da3276d3073fe3deb01cd15fd8d1470e7181fcaebb5f57239a6fd9bc5ab0ff7623d7c601a3b45eb01162ceb7aed1242766c7ab7c0662c59b6bbbb3cc4f4c061e2c8f6dd305deeb66860eebf38f45509b335707349696c8a694b270b68dbc23bb8d60a00f515f70ec312f06ee0dddd7a4b05608f9e0a1e80e8336104736b1a38a01e311bbd09ed5ed1d885a18917c4891d55e050bd4d85619013190efbc88d9e6b09d1a5a8a1d81e9259b5ba2d2cb549f8722561ff0e6367067149ca18963c0e55adb6bca560e60d1947e60eab78441f8ef7a1137eabc54d4dc9e96ccf97868a3242ea9a063ce5b5b252d286eb4fc80c8503af57455760f5a44e55342df303ded8be48c039d617a7b88ccaa5b4d5ca22474501ceccb97e5c7ece676cabcab5e46de64ea9b5390ee916eb2cc756dea0021d14076e8024fd3006b7e231903a90f53b46730577a48d35ec3a37ca3b974944b7fe89de8216f774fc628c0f4c61fc4b90162278d37a1e7287f9181635631538c918ee9863b3224b6a9431e57640b777f7531ede094a6a2e386faf6ecb5a6933c1645d95ff4cf5fbacd89cf586d328b8219fd7097fe5777e7f0ac995d477867211de7648c353afe888878a8e461069e10a7c67b3eb295ba0f64535a8b7b0b98f71603475446a041eca8820ff5c9b920ccd397a732432c6a052d2557fef2f9556f4029da850ad7b8cf24e9ec42b00169631f839819c2b135b9796bf8bb107475745197b7c6c449ca662370db8f5f6ce94917ad9c16f36b10660945e27981916b497d074551f9d60a2a43b04cd2ca94de6e1f31a7924fab79c513579d6ef24c3decb978883ef99b349cb647766d4ca40302443bc0be7b7249819fd5b025ad7decf8f531efb47f3eefdf900cdf8fc2798e244da56853a22264d725f5918d197711ebeb084156202d795effc7f769022eb6c62bbe51fff8d636a813cceec56f1495121fc6f3d295af840189b56b8a5b9a7abebc6acee6319d6c2ffbc68e9803573a8046290d1c9f969900a129caf952d8efbc0c7613d11b956181f1b3ac3882c561125af9eba69ea4aafb613258c413faf12302135816ec7626415418ff1053555b5dc26f8f4777a5a8e536f740f041a8fc9a9cffd8bb2932d11a3a5be865671faf54f54060901b00238a0e193a94c9ece9dabeb902e834c8b5f457ab1739059b7366b8b4ccb83b3365aa85df3961e7cf2ff37fbf44a2ea0919f7c4d9d7ff9fa817ce33eb4b15f6f1a6b630c37f6ada9e7bdbe98c49ba7d5a706aa948ec1521f64efedb6066d10bc2033e926e892dae1cb9902b8f1de72016bb02d7faac33d4e62d1200a2c72a24d5acefcd2ed4af194080f587b70a0e68e6a5dcd676d92371f0fa810fd0560d69a802d4078edc9a086d87380ba4adebb29f6a4b1765f7fd7228ab5acba0b8a0a0263c47b9d8e6e01f9f8e4d9442ed720c41879ad8d9eb76e8d41ee2b9ce6d7575395dbdf8e01d9083a59b19eb7bbc34593dba21dec635d197546427f4b0b771458710fe4407b9ed53c5061b584d0c371ccb1e18d6e32b87b496d1834825c311d06fa8eee65e396252e0a17130a9c7e3b69831860bbe0920e6adc2005c8916d1776ae8f9d41d8ab0ea4a0d4573494be6df4c7c60764e8d0218a59a7ed2e6b98e46d6e6cb2fc273ffb1759632af9d23d8255783db57470cd85b133c174e922fe73b696c537ccc69da7b8fede851f904b6720ed90929e463d1ff6d6a0038829a82a99defb0cfe0f2d2fcfbaa9fd7141443d12689c6a5dd400aa493f3bd6d14f0471c157d63e125495204ab788dea1b24d824e08c3b62a8be038c0129b136e1697aae78c5c83d94abe07971538eafe93f48cc73e53f0f887fdf4c80fcf786c45bad0d09f4b70d06d7fb811c51ee0569af07f4e92779572882eaa75f5605eda9573eab68944cd5fb664299118109eadbd912f28d981a149b2fc6bab1b03a0ba4cc87f4ede29d56be67859c27404a622f60f7f3632f9746be3b76dfafe4a2858d1eec3ec15fbf3dcac42a97bec2341368e33eb8eea5e7b6571d0aa3accecca45 +expected_shared_secret = bec215c6bb33e83574319c839db1ca6793931d35a7239bf4ad3c4a493fe5c5ea + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = c17c04d8c082f06a8d497768755ca932d2663637b2641c34a379ad8faa55c15246fc5a13a3963d4d36a1a1e06bb811c736e10301d96181207f65e992a66b7b3d1921c7f7247f34bf3951cadbaca9e346bde27887b61ab58fbbb3cd25466b3684b48223b24c34c6f1ce5aec8513717cbe5a0059352e4ac62eeb157a0ef76936c16db808572cf93adcf5bb44b1935d43abfca1b06d375f4d5a4d2a40392023a86e05796565abaa806d9ba0273e543ab03809c4fbc74fe4156bb2b60c76be49c7a1d5d45410627a85026a58152e2833b445a087a4f011befb1e03b7102ea4b17d6b5c4e3791f9c2babcf2471d86c720d412342529728cb560828c7286035e612698632cc054079ad2b53517b4c953969d8bafbdd0c09845191ab426c23a8b469b601c8751b02a4af32b670e6592f2e5b943924853e551bd80c5e717405eb2480da7a6ffab19660cbb5956546bc64def60b800c252d76c96d2fb3d22736143b144953a410653334c8967a367284e2197f5864c5e811721a49c29ca0e43e9aff5a7264381bdd5c4af51c51b66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7ed026efeb5b271324bc71bd73d09d923182fb7739405159d51ab7e51a0765c56d98d50fda35546bd762c21204f5661a72aa3a731a0520409c62154cf54243a32914a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6b917d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b1551d4ff31d11435a97a61c0f4430757c70a4d73402d94338765c8f708502774d36ac34cf85af4683ab5b36c61b04064705c68b578f7dfc4b9886140d28335e78c3b5ac7ed5bbc3dd6ab0a76a97858257c519cb57f0c949c2818c43962cc24695c5b3a6242908f20e14239930a9b8fee51bf5e62822f42095f37299316479c9371bcb567cd5cc138828ba5036799714dec18047c84aea562d67e375ce697536443ae087a5787a8de6314a30e81aea1312f3fa12bed1ce1fba8e637009bb7998d41a6654d70b2f9436f6737c9d118de76ccd885b4b0f3751990b93138a70acc047e4416fb2e21bf2359ab022696e67b6ac6b8045f3c826b81b76c4589a687e42d909ee5473512a71b6369d22877ab0f91a7cc2c01533635d896b6bd293f85962f05a2bf14315e42582188bb09f2c3cc86632f636adde80817c0681a3c8c313a65ad918cb12582ad1d76ab42643efa7ae8d94a4721b1f4bf77e8e47af68642112ab9629e0a2e3316d6185668ba373db4708add91ed47a5044eba47c346b7d230d4b324b30c6193184b493d111fd8362812b5fd1e19d4978672c505bdf9a2f888469faa040a4b3c5648929abaa66ec435d3173519b882ddd7474b1210368711c301961f4855a49f75656d356930c79ae11983a32a17d4757ce42a2d9e26f6a77475c12056a5378abf7c7cf097a7fb23badc4ae929a5d1eb46af442956a370d7f9a635926859e6099d2b121a807c107cc15ab18ae4634834c22144f689e92000829a4a9793ca767e43d707bcb2e0118e810b32f14007231721a5a1f1621991b556b70389bc8652b56d824e070a5f9552de88b14df346d43b460807662263769ddc268a78cbf4c155e46484c8e02087aa6493ce73b845289e9499d0dfc1b156621683521dad7176de52bc294770ca02ee08899b79673f562c5ec68157c758d4726cecb986c1355444d96402bdc20a620128ad3c9407a64537ca855f820c7166800839e32b5a0b9404ec4f375c68336c2c098ebaba5d1865a99a8b45993533b0651ef97477660c48ef40ea7261bcf9c43bfcc740a0605765c5cd84cc5640c92e533a2ec923a1512ba57d11924542f53329598598a0717aa91986901046db1c763f25098103b208933085b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3cabc04b7f7ca57072216c859e73183288c8fae0a71b98a2366a99f276c0b68688759e6b34d51a0f5fca2c52585894a5ee52253d6f963ebd1283431b6d681065426a19157a6384b27bbb0495cb8a4f42c5649f185601b4a19511841e775868c0ef0e010a8147a743285ea16a6f01323a9acb46c1418418c0b94793617db9fcc1039b0060c167052b3766e9452b65f4789d9123e5e299c0e440986013226b63db7c78109622eeb8880c351c6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = pass +expected_ciphertext = cfa709be046d7a5089bc89acbe7cf9c0d995018315a1da69f28fa50534d3a66033bd7f3ba72dc7cf4a59c5af2004c5c84847f4ba0703bbeb0838b566072697cbc4f83519dcc80d4dc57af1d4287303f0e1eeecfb571dceb8960be0db46e84feb6418af8d5232751d46ea9e807464c5c046457c90a2c966fca923a849b247b0e597b04984ca27719fc8de2e7a88884c7bfd904211c691318fba488f0167c3ce3fb3f09a576e0e615d9c4025fabcd87f2fc381937bf5e5767c929b489957c4c902aed8ffa04a4151ef4f7b1fc24892b8417fa768c5c4caf89c1d7a4e2c0281aee2deaf5eb36f1a5151102246957f2d5b5a0f84490a7da013a4ba455337300376be4745a212e190a8319486dba5a491798ff284c7559d5ef4c22f11149688eaed6cd5b03e64982e928349a85a8b10e9c0e8d919877964faf74bccd45c9b8358dc06904642496d5b1723f44871beb9d22c20fe44f4f522e69cb69a8c2a4d02c813add14c7f3a9b813654343a091b59df148fa2331730e2b1bd620f8c4d2d7cf5cf2f179b4e7536e79673f75f26fb97f641dc11697ffa3470e7a51f2595d25534d0d8fc2951e566b825bde2a2fa95ce89160a245c779aecbe727c37124d7b4047f7a33143d89c36bc1a8d6f81ce89c11dcba1eefbf5d9cf516e96a4cb1fceb8c32b2783130d4744066a39a0e0c4f1a63fbc1da236a9b477b6a3602da150e02f0b904524ee76e427546e0b4c784f16eef19d2b36779db24b87878b8bfcd17244a30d6028b8aa0e2311d48efae841d37e4ffa0f7d3f2b68a81dc91ca5d4414a3c368be4e05b10bb932c2f7a5fd656ddc67e51e7b3b719f9ea25e3ac18ee56c53e00647c57a8f7b7a9ebe219ac62e0ead2c51e6f0b8e96803dbcdd1c45a7f8fca47b72fcd948c12d1e2a54e2c89f9d3f8fc9d5869e354693229a1a2f01bb36f4ccac457acc170f89fc02727c11aa053c2bdb810d8f4806caf8228b0bf6024fbf16b4c7ba3335a2e1b900db84b612f3f1ab4cb94ec7f9123468b282c02502901258b00e7bec13b8cb7548ac4eea609aa2bcfebb88e362ecd6bd971ff280ebe52dad8eccd2ffc148b7a39c572635fec41b1d4ed932701384c749874f6a53bd975901e17a1a8d371f105a0f7c61980e872e8c9b653b47031dfc70b255cacae5753e479f4ea2a6f7760af10a5c3c98c4bca1b9c3bc255a65d10a5a9d2094bd7ca335d43ae0cc5f9e2b401089fd05dd71fda89a860190924f47f79b22dcb5a9014824cac41cdd1b3ddce29aea4501bf061b95a0deec5f11cd2651091154b9ac5cd594f259727a277b24b5e5f560c63c21fded496ea84f4c808787ec84190ea23aeaa651d2cfb728dce2200b7239eeb48e2efde5d21077ce14afa47f3da8669cdda62ced1ea7fa0d200854a70c5b016b7258ed36216601d716937feb112c4b9f90527caedb744be654e3485bbb0854458722271f6bac03689c5792e0e2903f1985b27aaf8d0fcf32f10a18112978daac5b4b94e6ade015a23e0873a2dd18faa90606486d8d8884c2d4ec96ae81d895d39e40df7563c625b3b2a2d9bfba74f049e5a6fb237988782eeffd223805904f9e90b7cf65bce60f3a85d635c85156c4f7797cc9373b37e21f45f99624932c1073a2c7af131b6476e1acef410900bb9228ebb6fea2f2a912a2a8fceb80d2c5cfd6455ae7c6ea1b8c41a27eac6e83c565f9ec5096d505b0500ecd51873adc56186f9d16c8ca63d852d65b766d41dc433a63528b2809890f085cef8f6df26bf378b90d60fb01cf27c4bfd7401e2b923de0987fa04580169243c4509175f7798b901cac5a1818a43e4e70846c6d9de333b730b875cfd7b756237b87ce7f1b50414064ca6be999620d90a056f0f7587bb9403256b33751b0ce948e294fd4d7bc1c852a3386614e20e9e9257d318b065668a4893494038979593db9e5b9497ea660e073c0b1627c3bdee1b81824e6e814718974ec3b45a693fd1c10069a7087eea71482c47ccb01a2e017235c78edf0bf9258e534b1e47b1ab84cc120f83b8c8fe3b56964b28f9ffc9b654869e4ccd65329749db82334eca6e83d330480120a1c3d41d20181ae60001c6d5bf9037805fd5cb45d5daa5407fbfca5ec89a02cdd7ce5f0a86b7ad9b7f0966bba8975d291c06080d3d648466601d4af6e03435b45da8158bbee2271ce4d092f59515f40bb58d081abe51ab8fda4404b +expected_shared_secret = 18a505a0543800a93ab6e2fc1d866e22337fc8387d32541008ff82a73ce7dd31 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 56054ad4251def874aa0051ea234b544d7a0dfa60b1d5bb60b8bc95220c6cc96ab6ed53eea9c7cd1715e9c29291a361b04f205cb094ff888642827aa19c64893685ffc004b6ed9516f6638b9bbac94404f91c29a4d5ac6a9615179798cf6c486333a7641846cb49c6b78425aea240cd5f98ffaa826aa3b7b643a0c5f4c3ab4c21ea9081e9439445c98277b9a507bbcbb82d31aced3c378b017f7d62270749bc1901ee53c72953576125574dea727080a659bca4f007b6cf7c9cb2d0254ba9a293290c493654d25e7ac0cd88a6101b12622ba2627000de87d88e4990ccb9cf4a08918d044c2d52cf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348ae706f400a28f0b1c9f8a40d8be14fecc0b2f282ca8f5c499f2a3d16bb7501003d22965b7e33826d343f72a501e0b219bf868b3e47bd4fbcba0d6635421189c17c32479aa5fb0abc84549f878490bfcac6934a6393a0a14874a878d65aacfa3678704919240d31e9911fb703dd339684d5ae6090bd3478578f7a60d1d72da9d70eca9266b19c79115322e626ba64d52d26c9a655f1325aa63881e8800e16382a46865ac2cf015abe3a420ecef1290e5a2836500176d7b6d54868ae3a977cc26a40a2c20ec3b346c0a4b81549d274a7bc6b446d6a42512c55b9823d745402a630065297973b99b569952aa9a66b440430d980bf4944cd66513220f13964a30e86f738a0eb1aec491908d2c07a35591a384d0e560af91c1f7910b2d3f61e69234375b9b6cc017891eca65b83332df15773baa489862494435538db956d9c09660499d7e343c7d68fe082997b73b69705b9498ac9cd989efce26f4aa2b3d5e7b445e4132185a4e734175ee4b5b7cab33e42ca33096755473d774c758b3ab1b7687d62351c3c5251653953701c81e2cb2667c885e75c814f375eb946adef027f78036b28f4151f1c799fc1556de38bfb2ba996db3e3e70b79be2614b073cbd150c04313013ab88c477297ee615fba0a9e00a50ee3b0f66498ba09acf338b7342b8670c31428f4a52ccf9b4b6dc98667ba43792863661738e63653c34b9147b60ebb21ce89291891bb814096d662806d1d012481b922b9c2fefe9a66b919823970be95bb12c6619498228bec78db0739a5b1c93654a2aad73851355a0485a52c3896c3527964e88727c3805eec01a65cca1fec8466aa44bbac56e53895251892b6355c5e39953f680683ff72e0968867b536c11a33470f8ac74870d996557981711e5d0abc65c671f423ee4b67771055952b54df8934f0b6980779abe207c4f8ce1cf17bbbd90b24d1ff875109366a4270202036a0796146cc8ba70712f98b042b301c5143a6143e01b79b2af3a944100eba87da1725743c370d85894892469c00a95f3866726138c2099b9b6c47ce9b9630222c7656623260d8500b4d7752b6779af5b5b858016057f545175f61477476e3a02aca3d1485e0882b305c9f956908da84ebd8083ed26b8b2b8b50a347a4cda722bdc6ffc2b9043491da64b0fd0a39b7f1550186a0038e07598d6887e6c8c2800288b1c9a45a66233049d77d912b1fb50fc119b0b7455c8d90a3edcb046f2064d401c8f108b833caaae5573a10b9fd1775ab90226d8a32088ac614e9b20737c88dda963d0e77c7c592179b4030881987421a886ac7a422c98b6d51c53d8c1027c84881491994cc84e9b1185b3425758bbb1e305a1103ff6989c633a5697a97e5dcb94e7191d9a47330ecc60acf85083559d507a77f7033965a0859fd6306d27c0ed2b35e7b3444d957a52010ac49a8851952f6061ad551b7c74814606510a0bd19d9ee7998310c74ef507902cc71103134a411f90da122fe72fd14448dea00932977c0f27628f092da3ac07d901c2c3613d22d48ad6376ac1d008c7d19a31623ebc616e4fc3887d68c033bc3ec0e5840d415f6fd2c15355c223da1c45289315cc945aa39ae7498767eb3a6692b2a0ca6e7bc73a5d97644703aba392b5d386849f91bcc7f5691f295a267ac0c1fb84e5e31c94ab020e351ae410840e4198e417b8f397aa33f88114030b07d5c702c6ab64bb7df7276f593ab3d133232c919dbd06b6df756258b25c7132bf03c62077084ce937ce829b0172810b92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = pass +expected_ciphertext = 9d9882a27b742d5b881f0d90337a252784a2b4cdf03ea7d09f4fd8826f3bf67daef9c48e0620cfe84925520467c308de3699719b08e551d463ee7d2bb5d1379fcafd75912c5b64008703fb7eed7303e195f476143b3a6723c14ce95af85df17462f123325a2ba206a680edcfe4c5d1ba1f7d6849b59d1a95561f12cece6f7b39dc6b1e9f9f42e56e9544ebd21f82b0254eb66de5210b9ef3bf00bd90a19f26462f4750c5d67ba46fe11e03cf2490963ed6e7f3646ed23898d1e87683e0252e253c3c3c2d767f66c0005ef9fc05eb66a8984725310e03de86edd931a74f7b0fc31b34a1019fa8c25eb5c9d20e4847d8fd3914547e2d9e6e58d2ec10d0d3ef5f6a00622568148bc0d61157d3e04108625c0a00330fb1911f6631a1336730caba6d3fe420e364c6048abdc83998b28c43e168b61c32e23f0df46bc980a915ca09e8425d9bbc201af25f2bdaee38b49123bf71560c32c0b033e1568aea57462c31fc37879314674382aca847be3d60514124700b07b0e86ae457cbde316629347b56307f2d627d6a28b5c4b1056d9f1f677d1658cb4c04f4f4e7afcf514c84d7ee8d0671ef7f502579435c100cbd96af496bd2637f8368f0013ce974ac519a32970ca0225053eb8b62ea4de0c37d443241e537903777d476f6f5055db5fec5c867e334d2c95be5aac9eda6e7309f9b96059174a73bb0d623d583d7fc47741410d6edcfa0068cbc60ada07c34539a6c00970f86e571fd2535704dc96a9067a902c0087020ebdb815dec49ff645543fb593e66a697297db587835920a519dfe468a0c397f52b7973a26e6705d88346c9937d022a9dd2f2f661aa609a6ca388ecf101a52125a63a1c031fba8f9833db93cb6e18e9aaf77055af81c9bb66fccd5c6cded6c0f191a6ca576c3960f2fe3b8bac77a8683e7fe27e7018852ddfced60d09ea52313517e2844ea2b034beae96560a3ea184145c6c30737020b0aa9f0a82c6a09abd789c9e29606fa1b92ed9b535bad8d8b19b760edad4fb755e56e6ee48fe7e955a176ef4954e619f93ccdf800f6931179df4879d397d9286933d61f377262a732caada2ce3bace41738cb2b939a73b0e16a6bb6563a7204fe8cd1583935fe6f6eaeac1aec99ba155005057de028a6f18a91ddbea4f3aa1eeb52842715b8196463fb082e523e3bcc21622f087dceb6dbcd9a13dab218c88826a79cfdfbd76147de5ed1337a851690e6e3b5ba8c994d172692d4ac72e432c0a0d50e2cbd59d11c193b169a6754d66e8d855b89b0157bbddf8faedb0192b2faa665981ef8c767312bcd8b2414f0774383949db885e68a79ad88191ded52bc0eb175b987ce5b0997703e31c3f69bdd7dec2aa3b813784bbec923550b8bc3ee8267190b539203aa07c1000d7f0e1f5fae0d1d0e5b93df78d2877b6c94a2acb676441e65c709ede336575ded7aa9189997468b5c79f12f43aa3eafea5c502b40196ba8ef8126bc24c2911a1afcc531da7c9692ac38f57efc844d44a038dafffac41cfeea24e24c16c475ed6f84972bd89d22d6b23d9e19fdd500f8263e7333eefc061ba764d74a7ba016b7afe7f5b7be45e01d3b6edcdb6ee47f7cef19935f53094cbe532d614cf203241707b361366400886be6d0667f6d601fc675518844549a64de3dd9fd44e553726953527f84e92c726e73c4fd6cac3db7b526b05648600507e599c13ca541767cbd172211547f73793ffcf09c6a7688a694c8431bec47b6169a6a08b124157aaa0bb6640d8d6bf8bbcf8683c652fb270af94ea472fcda30f004ecdf13875f6144701cf768a7fc950f6ea1dd4880fcb538fee5b80160ba89c8f015611ed40b6f08675d03c37dafc1ee0b682b3de7729ada805c4f3c2231f81b023ad5dba9396361835c8b93d094c85c7bf87ac063e4ea3de7567cb767440e0d9c9fb14bcbb3bc8ccf3217811b5c8fa1fdcea680bd555547dafe2544c3874a0555ad8540096d1f5013a663bf4dd1b549ab28c4f6fcb01b854167b8be45fb0460e3339c286b0103179f25bf260be3d911668259ffbf0c062e69f6c2035fada24aacb86222db54b38df9ca621c45e0afaae0c5d89fdae9ffd2f1b4bc0a23ad088e7b6a63c962aebdceb8b1897a277a4853a5285992c3b9b7ebc72a98e787f4ef5b443c58b81c3510db13a3e7c3f5a05112a9ca4ab5eb0b077aa664cf9c119c4f76cbdbc9cc7726d61 +expected_shared_secret = f155d993eadba79e6c2376daeb7f935d39286b10615ab42c5803d43f15960a66 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = f72bbedf8059fa51188fe16e54b22f88a59ed8a92d72188f1b687222500dbe642699493dc08c97b6a13e640b51f2173cc8a417be58077803627a7c9bb2a7b96e9596e3d96c74f03926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789e02664ee7552ce5b4c3e16af4299c775a4dc322ab9ee16d65a1298294adef821e94a5119e713175b69f03f941f7c56f565439f1e24f663987d65b00bf899495d5c2f178812ee73387a1627f98029344928e5c9100c50f87cb6f99b27e3ec7635c6b132e0b81229807e4d9903a2c5ab8985ddef435fc8462f67a6c01d2188d731412262392acb98fc49e4cbca7acf522a8d385dff01fd02c4be4b878bff659aac05a8fbbcc1565a53cc36af88b41a1a3a18b04c728b1b66a7698be968db6f0bb00f1665088cdd4e3464e34261e72748705b5b7ea5e4c02289365a56739a4ee34a5dbd5509ec297c12a26ed1116929a8eb4793248bb78a1c21d981733ec874eccd2c9b4bb530c4b6b10e136e764af55059da3da93b79076aea089818210bd076e2a8a49a5032405a857baf295e7868bd82c958c90474bc4403e62b85201061b7bb6ac533e96870ad0d7b9f8e6a835e6c6cb4c8437489448a273e576b91ae8062e411593b4c541098185198e49c0790db516adbc2852a220725a5d50d47333ac058325b61325840634140bfb7af0110b34fb408749998df156668634b775965f05aef99713d1f5bdfc5302337b1c041448f5b09af8c5560076ae90ea3d2dbc39bcbc8e9ad26981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc49199c2c35e35d6107ac61744df910c021591d6df53e4358487f26b4d4060958095fe464ca2703394d885625806106ea31173017f4f0594550bab828993d55628aca5955f61f4e4b316a8aa9971c65813949a16828b5792ad841772aa1b85314527ebc2e6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485b8064fc585ab8c2af6212441a763540f7af3d8a8620c6cf40ba81a914ca28a8265248673d731432ec9c70e083be49816098494e6994b385b509397198e2a50c76a8949c25ecc9849ed45d59c966444313d5f0419abc929b8ba51a2a49589978a0e29c680c07b9cab2be0035a06c18d561b9b0e862a2957d5d41a0a63c4be99c1d50f76ce57862b4f61cb42591f17ab1e85c1ca2dac3f746940c001d64d81dd0889629d60727d5a5fd8ab7549b439d66a30316883da6455dc023e6e702fb4742a82a101f60cd8f3a29d3d88c7e418c3d30803a541d6ce1aedfa540371c846c672753a858b39b5880d69b8d525c6d57522bb6530cd7a4edb7730cf720541454cab59595e8a5d6302249300a6fc2180eb31ba43398a2a18adca92af2a686c20454fa8a1864d73c0b91167b6b4730c2b67c55b425e92c663465b7f7a1d2163f7d7a8a08a962fa0149cf2ba8c4066cae7c0a22a989ddea22a5311ee5d895eea9a5416739f810ad5ac901471a72aa78956b5183b194b26c361219401aefdc49b6ab481be838f85290a0d96060d68e5fc71358a924b95225070c6283b401296698310bce2f1b7c8a531e84f625585429ad3394fc04bcd8a200834cbb9c9b9a8c83601fdcaca281a93f47c6e32c133414ce71f32e60fc52b4c07a1402c3932056fc3323ea2241a6484e6a074676996e5962867a61cdffe8811764953004cc9c3697e78ab5d156cb952b1c53ec674781792ac831d6e20b5b29c3b064520fd5968bb351a401646ae3267522c234a8404b02529da182b473051bea4b971b170d03aa378877fa47bb60f1c1e3519110121bd58b17ae373be2d21fc6d7ab2ee2085f4a194fa7717ec83f6c144e256807aa921c32b843aeda0a5cf85773b77efc579a677816cc998970911152d091f21733dd1c0fab31808f2a3a64fa783efc2e4a252b56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277961e67e555cd6c7c4a630fdd897cf61c9c5779594974088a2b415806b520503ebb416481e87a062582a479b3e05b9413aa2c7af59c5a9c5034722f43032f0d6428f8425f4cda38876ac45ba2137fbc56209823b05abbc00aa9e6a307bb164fe0413311f22be44244aee55268da3135ea5996f7cc3f51856610ca68310dfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = pass +expected_ciphertext = d461713522c86d1f49f313c57c953ea6c90095c374b53608846b6c9592d574034ae4e08e082094bc82509f773b0b23980c27b18788cbbcad4cb03f292f7dc1b40dbb9f9aac870da48878f7ed31f551e9e0d1bbef739bd15f4f4d4b1ba219764ddc5031399f3b1cc3c40afe779ed6dbe177e47ff0696c76379db79749e608abdb4d8d7570bf26fc7a290061744e2b907b3e356dd503f6f52efc5a216ec851f4f88f65694556716e675a6480d7358de0d1fb3eab5fe13c803dfdfb8932938d1e2814d58bae2eff46bdc2d0032dc31b80fafdc9ecc6ace570da8458b3638bdf79c7f6fa398ba6d9777ace4404e2403f3410d23c79cdf84d32dbc30e255aa6a91062527de340208c0181d5592a8f8942cf07a80dbb1f14a3f800454dc80abcb555878bb1560cfe843f4fb5ce7d56770d4f7a4f36d20ffdbc6626eacb77bb74edd5e8d1d2b6021efb1ce39a41a4ed8f330eaf10c0186454919cf8184241b42b398d8d47208d3ede12d6568ac878398a3144ed985b5637ea55d498ac3de56339ccd50077c6ab899dd34b2020d8f8387938f8486ac586214b024b54b85aa1b1a60bf73bc07a24af056075cf89f5a985349a573a718e66593f470a48484c1f22aead53fcf5fdeb98fd4d3f3627b6be715b367c1549c7724afc6deedfdc825399b5fce1d72ea61b9dc65ddbf385d477bb253ce75f935a4f56f68c6990a3f20239746ea8e7834ec5372932893c3e4fe93f29d28a312354dfbe94167a4dbd80497f0fad7040e6ed69e93c9f04d254d3a3ba3ed743159142c82b99601cee295cc53d9bc48ee8828d1d9ea0f4c0956df9d3945e13ec9a311da1b5c7c6b190dc5d289e6a7b6e924457fac478647d71c9f916ea94365022b3a3e7e0f126bb47395f8311f9367d041a97395fc4825c89538a5fed9bb7d655bbbaf9d92cb8ef37b6ec71f20f0086b9d86d54766e409db6ca94bc3f8f025d5f613002e892238370bbbfefa16f25f7eb6be517c8e2870a2a708fa2aaf6b4f829bde2358aa374bb3557f796626739512e7d6498ed9dc6d4883f2bafc671bce7ba13ed3d0760efe85d465649b4cf641c70acaf845bfba0b0187ae02e68de2f5077140719163f2385b9e17175613f3c740ba8036ff871f1c48504a8c78b4396024325d2e4e062aa900f4a756b5339768d9f6884d3ffd96008454ec582ae8885e2af1fd9b732bcb6d6d4c4a790eb6bcac1b8b6af66650c345516d9b1dceca4841cd7792ca5271ddd4210eefd69e2e47230576e522120f4d768f5f0a3a9db569dd03cc7cf79420d0d414cd2e80569a578cb3ae3c73abec90daa76c5099c2168051a2dadac047b53c53775b99cdc06aeac711e6edf4ec694b4fcf82351a1f4272e460214cc44324cb94d2b63e1c8fbeacff3c7aa7c96aaea387979e802cec66846b697660aff05e09825022b91c94a842e1a6db46672ba9a27af6efd816aee4eedddfc2301bdcd5e359c13eb23e4a3100f3b9f5686c8b24ca570047ea2a8a3999d34615183f48c121ca1e4f8e0ed3bf554d7512fa532ee23dca8c532a6f23520723dfb97c5dec7d00f4e4ecd40a7c9943bf9f5c9f3a544cd9a837f41f346933eeb1d327effc39967ea4e3f35804e4ff10bd298bdf0e3782a64de00725a09aa20c24832f57ac680ab62b0d0bff68764486d0cda4fb56142430df0f123d02f83a70a2ab2abcc1582b8653137784435dfa80283bd8d29accbee3d57192be70ccb4c5e3fcf3fdf5c5dc127352176fcf7c1b614a87ceb0d9ff861d653b798381b87b96ca02fdff075d454d6e95c99edb7d66b89e423274c23abe0b21dcad3cdaa3a7371c1cd6a88cc9694107d5aa3a05431a2df1383f255801b2d7af9f6c3f6023f479fca87fba98e5730f4bc40f0da2c9019dcbef396d3a35ad092311b7368dfc9495e1eff80622eb8f6047213b53e72a712fd3bcd15971cdb61e1ce06f10d0929e7c6d61f8d8a280c27d86d4a9c129d8181befe173197e21d9cf702a04b5cd334f4d698d18d89e48aca65f7b2f459fd0aa9979113a9bc7e7e13ac721b00a1fc55ad7deb81b7aed345d3fd3cecb8434e7a279ed8b255352b142747d365b2fab7b44e0bb6c00bb258d7500ec7c2f9b2e152549f0f90d9aef6707146a662874dfa7c7004140e4b927e820e896847b34e555e98cf49976012b59d027978aab4c1bbc6f3eadb044eed3cb3496429ea295e3d4062ecfb19 +expected_shared_secret = 4cc8728603d51b14fca46ebaf01e6b6347ee9c71d192591ee857c206d131886d + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = b48117f3ab234a4bc2e6b80b05f97f10a508b9ab08c0650fe66185f146b0ef5993629b3f7fb646dc248e0690b77557971f02bafef88a9864c28e885562ea7b54dc217c5521146122aef78cb893a99c1c9621a6b51a43117016a7f2231f2380764dd81162a4433d6ca171062704294030d5a3bb9859a983c6b7f009f130444303932f141f506896fbec852a8a6934e72ad8c038319c58abea4c73319df541ce4086a90976356d001cf6479437b64dbb318f7db813d5034840e23910ec67519c93e9648ebd1b70edc3ac24c983ecc4003cf5b130eb251a6199814c715eb54fcc8ba9cd638a294bc2015c8cd7d28736226863a286dd4c0878345d3885cc4b2acc0ae08a277cc23e397dee84ad6ec2b4d73c520910b4eb4ba447071de01311754060195a37eb701045103b59a94d59131faa1b0a99741bf8b186f44c6f66f76695eca6932647e408966f7ac4b0b8af15f1c4fbe27a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be945113013d02197ba78b0f5f8008ac89b28ad829e5fc2516dbced3192242e074cde7c8e2b11ed1192b25db395f09bfdcec8b1a8671975b692c84714ba3049a636494996143212c54058deb770ba709ceb7659868998d6560c8f4386629331f7fe77dc5f5390443865d1215833c78ff2a6e24e3655ce799f62c3b5f24529c051c28347c3c792fdf8700ec3b6559f8bf6646352d2013bcd704bc2b26c0b8a231acafc7675d0e8a0459770f11d04aa0fa79d6062178ea4beed06057444c4b4a76712201937212de48941f868ff3184a9a700756a59e1297a71c3912cdd40e6f883295d0a62904a4be9350edb4483ee6bd20201d253997d983cacc0a4730a4255824ba9e4b7ca7908ce84a2562ba6db8e38b860671e2654f2c9b669ee9646d683e9f907733423d4b139bbda51e785a86a97103d8e14d645064b6e02a3ac6bd56abbad5cb09f1968fd70a84018692c2866af2b85ef8031b7693444cd1a9ca668bffdc9889053980a88bbbe59c883acad0f00dd7ba954c487b585910a10c95f571c245f0b415261fe348714c288220ea84d8bc524e438f43f29a9d42a8ba8138dfcc264182ae8cd7927d0cd0f5da7c2a321914e84f716836e53025e2ca75c8e34b04092752f1b77e9cb872e742aee71dfe2c1ece8c9fe82bcf56131ee0774076cba525934e21ca0387e43d53624caaacc88af2a59e234e24e262a1201582437656f97cfad4a087c622de1563d2a16758875b03ab514291c7d3ebac7e44304c32712af58b079031993ca79e35146723bcbffc96f16c6ab7975151961f1c3c3fff9a9ec5940da90a99bb2cce3f376cc4d9a417fa715892411b649dea698678936c35123e5ee8ad4cfb2a85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8db9a2e14f49581f106ab14779278a6aaa303ceb5ca7c246b5ac13162a9273a9ac00c745fe6f01598575e5348670bb82d8cd04a11a7753fa7729c89196be39ce7d543e24ab509684256e82825277da24b84d8f95517b55c2a301864b9a13ab809cb0ac7ff3047e58b9091c5b55dd0c23cb1964d8b58dfb80aeca479eef16f43ea66e185b6fc263e081458086585b8150b8239a531936e926ba339b79f18461851982ddb2a3069b235b8f15e8d74aed3571cb4a55067e385f3b53549fc4cf02079b8a41626a0aa52c5647ca634a37588402ca812f870abb94e09c2bf31bbb865dbc2a3f197bd7c679ec436f21684d7773de6cc551d370d75cc6217bc8db75431159aa5308570b173c7e90b6b09c16267b0169677610f57580640a536301d6b6b7c58525b6f853a5aa73a05c766f631c0f1c82f6ae54eac6659f2a37fc364b266cb0fbf8601dc5651daa87d79fa1852d950f29441982a71bdbb74d260c6b75630e3e80643676c4d59960a445b86d5508dba0c41f1516f44aa309a799ca626d4ca8b7fc5cd54c623acc96f15841c85cb1265f5ba3f6754b178a281e8106a23b04744ba248c703f0279cfa055dc3c70b8c68e48dcc84cea9d725b4ba5b628d9ac62899a460c157752366c00aac16e281ffe1233e217202fba0e2bb3cc5c170e1e373fda503a1d75af9e7a57ce113706d833ae662429e2774fdc686dec4a6268093743b718d3cafe703d2c27bf7b902dd1482ff611cedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = pass +expected_ciphertext = 26b32c1f885f84ee7c603a079aa9b9bfd88cf4a140edbd1c9a76c458c5917e2901dd306f4489539b6512578750a3d1efd7f70c011fcaa9697754039de332d69f39ec075b7fa37380db35e1a549fd188b163aa3927d4f0c222965aaf3d004c89a6765e818edc975a4bd286a44d88d4d2376d89d2ea01ccb0a3aa4645e2058e9e8b059690ce511c0aa292615053f5f5089c8f0b91fd2bc3dd683e1482b0b49dec07c10911c4ae79caded9284fc9a9d3b9126ad0508da57fe10e4c3e0f85052b524ea4b8bc9474256a5e08015d1b23433fde585e29eae84561d2d513efa3dd09a01fe6078e920686e8123fcc0352780bcaefbd7a26e51f85397f99398f27d56a9853c2253d5d057b378009598f57745e9cd9bfad63e3a93cc00946993ebb2ab3856c3a17309a116cd5cf3a94fd18ed35286175036ae66ed022643fe2775b469dc3912d004362f03f1ed6d218880ed206d8024d66bb72246c1b27095bc31d9299acf030dcb8a58f7f71c4c2e1e34a3464458eb516e4c2fa2d819795b12d2c92a56dae7e9e47d16aba8eb6e6c9e044c89a7b18a111464cfa28a634842193f5d6c1a63bb39035630af6d3141b72312273e4aa3b338db926863c98970dd8bc8b936572484c0f3fa52d0cfa3b360e7c57169fffa35fb1bdca24ea32a55b229454d0b57b3088a9b9943c74b5204b86036d36e05da8a6a5a313034205a192aea5c60879a721f9338c10280b9b407d6fab7214e903a3039f59057d7381667127283eac4ae8de0e71a9b6c36037536ecfd0970dad44f51db9b3bdc961ae8ac451f8521cab090541278006549aad938ffd10f522ad149cc952c6e8c119b026672c6564453afe3de708cae3bc07276388e1ca4846c85310a66056146ac055f212be32f5730390375140427d54c781caec84cc85f7fbde7383354aea94d327bc830005f1eb6654b31586660409c237e00bb5a1a740cfe64db97b3211e776576e2e534223357513c8838978a8688ddbc16d9d3f2f8c3d21f32751c26b652ab107ff601a313c9488a336aff6474bd18edbaabf79ecfc6b8f6796d921d75fecbd736001b99cb7324571e7cef3ea13b8e5fa7b609e4df8a8a58b1ec2f1cfb9b5b413456f9b54f36edacd482efd94a7b2b48a64aeea7802a40823335ca5134a07e219a509e96c9f00b521b13ef4e2742bcffb02595daacbc1e1d43b5a8bd6ea35f0a70be84ec944e13ae16aa0a055c46afa180a0e3cf4326143b60a1bcca06045ebd3ca8425b3b13846796f855125c5bd93849480203a915f2221d097cfc1d6cb7d9948265af503b96f53e2c9b41e9a1e95900a882384f819afa1058b1d891f173daaf941fc341f984e77f483f04fffb6dd4cee50b93a289e6fbaf71d2bc36db6692199a47844544cfd3af2d6f9b5be58f9713e6af5c4fd20267fb68f6daf81173cc6d8bb24a46cb201e038610893f9e18170a0514114dfe0f41244283b485f7d1cacd88d3da4f8126b5f95dcccd17e8d90a6ba381bcbc933963efbcfb40ba83a16465e528bf59c2981997327a4f75d33d997e8e38d0429ec0fa9e5e450237b15238fb0c8ea272f684baa71af738d72e412c8ae3a933d709a6f647123d68d6cad188a914aa18ec760224791e1730d5feebd3ff69074498bec4b53fa3d9ce23dbf26f65bfbccce5ed8649f88d659885d0598d980dfe27494f924447340a7718f399c0c676d8a5740def7fe7ca5737e4e9c71f6a0e222c2978ad4ba5c5d5d5f6f5966c08cfab026b0a6091bdf3f5cc3bd77e5c2d91e200bce93bbaeab412d5dd40dfa7db74ea453ec06fa3c0299eefabf6fd9b3b57ee799e6406a266680f98e1d6a8d06ca968cd90a7e5fed2463f6f0a712df964192733915398391fa5590afba1adf5b5ebb8e7a90eef89bf67a19cfc4eb061214244b82672a2033ec48ddfd385211e5dc780014e4be422ea8af9db275f973bec8c8b40b3dd95fc58b200d79765845d297e3fcf15062b0915123aa279bfce802da4b166366f890a4acdd5b066391990d66a2f98b0cde158d144d61e4115caeeb84192bc98e27a832ce3165b0c25a58b8b78be5c3c32278b971abf5b6390e78f30d5638816499e926a6171b45814e17bf73af0acada513cf88b55be51a72148dc8abf01a3763f8f427509795339d80de25d57733b7e7248b6619078c731bfd8d91df790eb4c068676ef21ba472c2b1fe29edf6010c126d59 +expected_shared_secret = fe5dab115160a7200005216d7e6e7dd8527f9c2eec34f60c6710ee21f7f91730 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 6daccb26429b4e18c04591cef2a49a51f34aa224a4f7e0bdbb1950b5b9bd633a1ceda3c94da93cfce38aa962a45a135a45105c6e2548db96698d581f42ebbb7c4aac8da6805024bbb2b0c45806015db249b4e10f92536495670bbeb0402d0c1be9b01e47a2a77d29cf03647fac3730878c7bddb724f7d8539e31274e20334949a92063634d6c1c0b5a1999460e25259fa91737d2b9a6457588d41041d8d1786ef80ec2951cd0c84bdc57108f02a7aa5297174c7be5a6157693c07a38242f85b79d16260ab37786e67d7d9a77c953b81a2a4b9e01697bf7a714fca3d9904795671d4b99b5ee83765a532624b4004fc6044c1840a4d07d45240251d32fbf922ec329542471037dac809f477fb6ba5b198683443c683cc8494bd1b7bbac7ddfd39f45a10c77433b868c981b7aafbbb2c8f2bc8a6e3134eed7bddd54b9fd1a38dda8a2ad60b4111b10571928c7b55721c527150668a1da383b8606f4e1575ce164dcc911af678a33973c807a159bdc12811b003d68b8edcb12de1614707b555a853290870b5e5b48d7774a9d69a116d13808961164cc0cc38325f49c463e41c043f120af24239c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4554a2ede21cad465be2e3001fc9c955a3b6dca4612d0763299aa8334b28830e996ffb13f7195598c55a704ec9539bcb9a44704c77cc1e9c2a7cd371d46c02a409215333acb076bcb2355acb6c5bec8cb2640c86882342ae3938059a99ae7a281d2b6ade8073d1a90459c04a5db7547b681b007ab996e1a7fd6a030c7b34332854e036b8e99d0369bdaa123a86ab931776e437271a2219af7a4c7b8b78aac0365c78d1de15fae8c4c397c7b6eaa4d02b06f8da7145fab7948b786a78639a4e80299e3c12e5b3847f508c5189d0c735f5841a7f5b34fc7e194f4f20f348475c1d4a3f4e8111c9cc6eb06214c43838b41ccbb6524da5715e5a2644bfaba69b0cbb54935db0379b52668e2b8b84ef5600ef76686bb0651f7c43c1c120e20af9de18aada655d48b375b4a23d21c51e1c3ce9e0131b61c345112b5ca302ca9e183443495da4b309ac898e02c4f70fc7359a57d25778457e70bca8a1c7b444208b00e24da7e0ff89c19190675ab24b605295ba862eb732e4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e08c172467c80ea05262831660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6225b1fee03cfdb599bb024416ca980c8181faf51b421b86f92147e12d04caf335a87fa1dbdb2b0e66c0795cb5f65130adf3bc8ee3bcdff9223cd74ca9c4a8544208b31cbc7a05b21392b0ee03b9abcca42cef8b5448482d8d8013ac221ae01436cab30e1c126f6f80af46baeb4a828f54735b5513c8f11228ec2af7d854d84e3688799ce24c8454e326fd0f52fae773ca5d408568551de89cb85265115092b960ab9792ab8612c012231921b6c697bac6bf53174ac50a6ea2ab3f48b532af51a6f6939d1ba14b694c149b5503f3320f438b731a59b4c22810d1196ed4a90eef2968d1ccd92327b37866abac1c24cf0c2b2228d0e41a3a1ec6a4227a36218b6437b5023e22d43f04b712c2c6665bd2deb160aa95199146618cc1ebefca7691248acb7c549cb66cdd59f5c4c0470205791c742fcaab677f966f746721f58846d1ab2fbc11b6f2978ddd282730402deb863ca1a7e224cccaa2b34f788987520c9da9c0c328cad6dfb46a920bf8ce22f4d265426cbafb31023b7e748252561cd678bb10218d4e5cda45488c4b2c1b2cc73c5c163da9467f02b5ceb4a5ecd136a2b518470719114d1c310a688e46bb80dc38dca1a092d36a3edd7c4c6d37074692e266a0f5fb0501e9791f3f90cdd93386c05c93896b950c7681f0abf8a044ab1227b68210c169b6057528315ca5fab7ab2c9dc7743d8943c997801a01eb2d9a195d2c6a8710fefac2e60702b68523667650e6616cc0b7b5bc50809d1d45e1673be8dc435b7355b0a26728205ae8713be0372cca8169521e574fbd18c37ea3cb6f02aa5c82a5834819254077e1670047997863a5ec7692bc26cacfd8c346290564fb27a50816f2d592277f56167027fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196e92ed698157064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = pass +expected_ciphertext = 371298b6907604100b71c9f7170de670bcf388e150f71f83432c040261d09762bbb54b2bb3a9f050e683cbd1965f6421749149efab2ee69368087c9a52b3ae69d9da590f741303cca4fe69d66da0b7b5f1f523c55c6d0ea735abb53ff3055db3475559defc033277a06df8f8190839bf47cf0ba7b5aa80a2d1c81a69b04fc693ad12d694db986232cc539bc1f396dd1c306d9f183cecb93b7da0751dc691881c6f4ad9e02a692dbba4ee7cdbd21c8b62b0c35a41674f3b433304691978ab587eea993919cffddd25ec216e6b84c11d618682beb75d679cedbb58d480e803b2e1ee24228c9165ab864ef495407f99b475cdfbcd0deb672c8945c67ea53c6a53c7a2be2da425a38619d9220f7625abd46318123ddfe2b1fa9b59c0adff0c7aeedee850135a26cc09e9755f05f27f42fedcbe8e1478e9ce945efca92efda7eb28b175995a6f7d7ea75b3527e46d9c9d65d1d76bbcaec4aca8a8a10480b1f3161357082e7e42284d307255c5e479c9e530f6dd1c36279e29c47ec67d65d5ec8b5cdab5a3a53a1007bbee8e285c8440bf938725e34e0486369bf603d0c1fcc59fe6dd2b88ad5381a1e6c683049bcaee96152c00552505919951500f61160b5ab2550cb00fbb9a545e397bb31cb1843312cab077c54e408aebc25b0b14e945724deeeda339fa681fcf6a6129f709bf150b492d155aa06e2bb5120d58821794a4ff564282cc2f10574e246eb6531facc1d1bf4efa3b149fc773ec6997dabb4c726d81b357a152e722f3d9c1559f92fef95ddebb7367d650fb3010aa100413e7a38ae91e4af4d9620a63674e0f6eda1fffa7cf3364cfddb3fe2813ebce0aab63bf6d6fc68637ea5e2a142c6ae2a27142f7b52fb3814013ee607c06521ad3af0fd979bd4a75a174277fc818adccd7ab80055b54305911822d926d7bef7cb0f1367280d01170f4e874b53a1bfbd20bfa546d78e1440879875f957fd31bad69739e2b1f742a5fe58d37654079e59e0680247f1080a24adc1400388d146023899eef694df0c3e03c37b2f9c0be7807572df6980574cbeb7431eb9e9f42397ae5d14dab4bb8507ac9612772910ab44eb8c9239e680220dde1c420d45f87d94d5d9b80f76a9e15f083631a82a2093b75652e51d5d4129bd5e33220eca0e7650e6e195351a4cf062fafc1ef03af4571f281d46b992262e759c696e6ed5c8b2810699a920b0d1e9810d7635c8b0cdeb4cae1dc4c4284b41c542e66902decb4a60ebba7197462385cb8aa9130ba9d54b1a3ee32037f2c09f6ee7e8cb94e73100dabc5e2466dc41e5e29f075a64422ecfc954e2e589c79a1d4697ee8a2b18f9303ceb6e2a66dc734ef402756bae927c4bdc9150d1132693e5dae94e9610e0ec18d9aaf6e7c28551b3f6334af72a97b84e09a126b2b5d967cd5d53548280b60f0a88f90cb740291fc29799c8bd0ea74bbf1db1bc5ba93350093cc2ddae74721f90447160d49d01190306ed6ecf7efd2260d7a361daa91090f34e4fa5dc9933d2ec66468655845165596f84db142f31ad71caec5a98cebfc2b6e8549b6fa7c235ac832b7b71543b7f7c594d631c9402f86a4a4a8e17896846e1300a8a1c6e3ffabb5a25ab471194c0b393c1558e8d55a10723b6288996e8c37ee262f9a2a87d97b8ec521e23e784468e98b78059f2f19c26e96249998836127384f8383672e9836416d2539de6c1501b937d0c5a2ac7b5c78463d97b032829aeddafdcdec97e5da3f95b76e9c7eb3777c3a926612d442ce3f11beb8456c200fcd098c989e09d8b2b576fb06498e1a265d604776643e10aa24aefe62391d967efd62831be65cb38c0ebf9517cc7e8bfaf11e3b7404fb03414dd1acef354acce23d32fb0c26c275a0780c74ee20127d87f7e315b0cda02e55a44168a88e6a1785caaa2e0b8ab65754d1205ea69aaa252a4c4202bf50e8ba7bebaa50a08c9e41e1046092bb3d52cca244eb6ef9ac534c1893067811ec97a17b9cc63a9f0a1f99324415f782c0e70b16885c5605f137505e4d41870fabf9523cf32935eb480c29fb65f3a23e06db00c5a7c5286bc6e249dbc6cd6efbc275cdd6c7a8320d182b7a9113bf6eb837b924b3580be35d05d81a09fc4211f3a713da32663f7478b6e1d6f6c7c20ce32b6aa3d517f20fbfa56f9b7c99ac376b198adf68bc754ae8d08bdb81ea9672e8eb40943fec88f81526199b641f +expected_shared_secret = ba33ea19873105ed9690d40426b2cd24073c822eb86120a4fe8617b5201f9494 + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = a8102cf7e4cef04582be990060177980606196d12ea824ca65d485783a32e42a4e20d41806e8ae1c51544c63c3156a42bd8abe55e36be37c6be6a51eacf02274eabb03f64c4ddba2a6806cce943cf338b09f50c5123c4083446802456ce85248daac7e5d9637a541c755b03300b43c4da96164c6c42c3910d36522e34895055c43847459451b8022d39a2c287ffb85c8459c31c2d183f98c684a959b2cd0a224cbb38713c4034a6668e14cac3c8f9d1b95ee6251f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ee51c62d244502a3a044f4c95fdb42a7fa0300d079ceaaab0f5720a1ba852fe7148d4a1642d1330942c81b27882c631c3ca3758f56b7718475404ba20cb8b436bcc1116690380507d02c63e62ac58f551072cca75a761f237b5abff58b2016242fb910f24baaeaa47dbf010600881ffd228aaef714c65b496795bce329819418c26321b5c73cb603d15ffa162901f386e9e815940bb5703477a996b313b50ba05a1d41ab65f233abbec534c106224c792a3dc14688332a8313408510386253c7eb076711ec35f6f929c301422192b3f611b36b97aff38a94b00764e9d89f38072ccd6b978e1a31e391cdb2cb3f9e344ba947a73db91891b944de4935d48a5663f85c94ba6ed8a3026c278d645b7b593702733865f12a3ceda3be2787a1efc2a2fc2211f405c3ad1c8c46257059e6cb43f36ccfe6231b730040849233d03b7e90076a7792f865467b6548e541bfaf5b7c3e6059cb426cd263494c641bdbc7616aa8348c6335d42719c0e79ae52931a119856c168897d48dcb44242c505c535698a35cbaa9f80a8145927af6653d31977e827625e3ba18ab7af3621df248434c2cc5e9324f34c60e1ff1253b4904b1952bb7e16dd979c03541a6be9bca09632120aaad6c457942b0077ff01b6808af3fb82d390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399e2255e030833485bc69c5c94cc48bbfe7bae3754bb49a2fc1a15db012be519ac8802a5cd005a6adc31abe237d9c2924134235db04b78c96876b084d41c62aca10008237a6f0c12600fd134ac59808418fde238aae358e34c1153842a31cb030bd97ab2cab83f74164358a1a077591c356162d53970ad65e21a994123c4000277d72ccbd0d712026217de9054fe9b38c61fa2c80871ba83a88bc98105e693a15f2213eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7a90a770717b14b40673591e986a1dbac4a87b111ad2854899808de206e6a768770e84023931bd4d996238430859a6f7628964e4465e5db7a9f5a0a77272ffa95a9ae759d47e1885ae6a4e3e78493a25153387f008a74ece68a67a8224e19209f20770bf4c8cb15cc39dc4147549c8cc599b760700db4591b284905562afe554658a07ff22c8645e29006d331bf09936085c4e7c345e2993a7332c9b40124d375c40e266a251002eb03b5dab50760972b7e9785dd585df7c6488ce9218c0171db28a99ff7a557c34936780fe9aa78bb395885085e0243887ffb27030393d925cdeb2a2cc3365ea95b5bcbe4b0bac9bb32e1a90b009de0f6be8ebb3e684514d2425f3f1688f54056f41c8e364b5e89859478349c793a70982818c28a245f690057095b320b2773206a3a856445290ea1636f5029bce3d8baeef0a73f912e110570817bc66d9b8dfab95da8b270898b6e30f28418ac5233a954f05009c2bbac3cfbabd0db906188abe7b72cce5001496360758cb477dc2ec02a590621c93b9067ed346378c419ab634d95267def3148a594be088bc349ec9669e4bba474c4aca165e664986c34a0dfc5c5c4781a61063f10f2c175693b5b5cb7c9b74442050f5d9421e6900cefe35bd942b49e469787471f43b35ef0c86340235525d50904263b2cc052757b01b75414027c9d02db50b4e47e5cb19f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5bb1a9788565de9455be321b50a39105a33e60a9533b506581d03459696192c08626009e723b228df1cac15c645db16faf697a7df68d71a56cf263639aa0185ed25bae84551c60205fe6b98d9328da3604d8d1c70d84c9ad68cbf266baeb8c6b3b9716ee50a8fb5a25bb6a32f0f971369601f9552a52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = pass +expected_ciphertext = a5ead95b44ab725154827549ed041a9da95427c827a9d4ee7e8e37f7001a5ba417aee761a6cab26edb9c8d86e6c275a176f3ce635fba2e97e428df214c03ce4d6a59e60cd257fad420513f55ffe6fde38515d00b7f21d55cecd78b1731d33aa39bff3f007350aa5c380c137027c91e9e2f5fe009db047d0a78b95515c04407573dad32d4a788c27cf0740fe5647f5ac2ea1e23440fcb86705a71d38a746c8d80de67a84836a656a3e02fc1a81db65f52b4b55024b433a400cfb43d7474133db3796ec75403f2d38bf626a6bdab7f8ca89b2d2b2684345c972adbf851be5f594ea88d993577a7f409762b65eeae0a752673ecf43565ba57cd2fd76984fca7eaaf4847dacaec3ea6528fbe7a2cf236c48d76ed2861e66f9c9df3057349a465575052158deb91d63c48c0e58abf2c4d58cdf7902acd8d54869e1f8f46d322a9b1db170ff139a3bb09e75b44fc8fa284dcfb5a959331e110fafeb5973cbe4e8fe525c08cf1ad29a6c1f2c4b7004a9eb6b66c7b64d2f375b1fd8c72588abf25018493d47a5aefa0d93dcf36ecf336a5025c404d9afb0b8032bbd6e407390e917c7baa28f74119cf4a77a9b5ae1f41f108b42c9e16dd907534143b68ca49673c54eeeb496a9dc21f4be1070e4bd966d853353a8a075fc17d5939d9609a83dbdefbb4a5c710829e26a1b1c5ffb62edf0aaf4a789f78429f4050dda21d4ddd6a7e1a3494605f371a1bf6d3624c8cfe29ee961b41ccb6a01ddd0aa668e3535b686cd1f515d64e4892d61531502018ce3f4c1a8d5a08e272ee5ba785281c3c15ddfe5b58f05913cfe14a471ea01a961793e09db9b5114cfa5243d68f05be26aaf01149767ae46bd854d565124503d77daee7b4626fe130a9d9bcb8efdf495893e3b62cd84e484ba4ba5fbffa19df0c915b13e38fd0a41649251d392322cd6e22a2db1c9106de2c8196761272b9329cd6353cb8221e00ffd91a9f06455658334f66945e4b24f1cf30664c123257dffa874750416af0aa43b0f0ce2c7c40710f6471bf21376a0e6bab6af20fa02ae95a8359993eba2f349b62e8f8857423f46054eee46656c8e12aedc754b03d485ee98f0b7edad160aa052887850103de3b5cb4ab8189907baac915541e76e7734f53a69c420ea95fae22ed569bbb7d28311a52e1e43efd9dff98606979e82fb19d4d7b5b60d5a626c401d71fa18fef6eea32312d05aca694d54a6c2c55f907e25928e16bbe38ccf0b37a3ec0ae1593d69c60dd880a61fd803856580d9cc0c8e3f89c98d17a43f74e3695927bfb8d539fa4b79eb0576148da4dbb295277c8cd71b94ea21b9614367c466f03e795890cdc5d2a75ae57cda441589c88aff28fe60ac7d0acc0db4411846ca14097a736bb475baadfb334aa669e9e3dcd2fac3ccb8490a97f5a5cf8a627b296da204971224c299cee3d46591d57c7973f2f561bf5ad97039ae97ae03557e6caf2b7edd6977fca67dc70c60fa962382ed707075df43082cd593a01e89b14d08f1e9669a06934803eae0463deabf008251216684caf84913891ea636353d50e6f86f15408bedc97a88a8033524d7a3599db638efc49488456937af09f020c8f30e0d6c7f0fad55238fd38fe57c2e42944a4265707003b884028a8fad01ddf93aba1eb07f3ba0ae0c9b53fb56498c203d4013418065f589e2aa2a18bd02fc92d19bc1e38d72f449fa37fe3da189e953a9f9e28e1eedbe481bddb8f2bac2d6e6acee07e0e79818da2c8b961210a72a6365e5c679cdc2896a36a0f66c121a9657ce84bcc070a3f5cf06a843b59842b17eeb1e2c84f0d387b05782dd4c5613a6dd5024cd79d1429f2520fd626916304a0d9ca3a09a7638a45331fe6e6b6089bf07dac78f005c7227f2abb68d4048628143e90b31ce66901b0d0790bf0837cf773a3fbfe53d13a3b0d2420286ab7f7579f4f85f0e4cce62db423eedfbf6ea89f22c4271c566997303281d3a6b633685d5bcb5ba91ab476dd277a99574e39e45da3a7e42f490ef0d606403b940e87ac4aff2a6b09d8b18675d3a23c1cd05745e36bfeaa7e559d076a4839926fdfba3fa7287f6b278491f469393ac9973e154aa413af39f0b39274137081fadae69707d39134a54e0be1f51272b141d97d6c5e902f7a752982913e17da9b2e8648a298987cf1d03ecc3a9f4bee827731156fc1a38b6cbe7b3ed7cd06ee5bb9e7ee98f909a5 +expected_shared_secret = 2baf80269b225c66a8c35c6f835f15bd6949ae2814cd8c405a0aed313a637701 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = 9f711edcc2ab20e136f9412f7151bcf330987bcc5332408392075a25c27e3747c65b5206a91483eb501b48cb5e07d501579b5093255d5e565cf5ca6247064ddaeb7e909a190da61348365c1c508820208ba282b5d48199d7a947ce9946f633bae9d24eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc7419d9c67af522a744a506e73ccc5afc2cf27663e813bab0c82c6c64023fd4cbb5b74d6d5bada2a33ea3f407cf5239fdf56bcbb455f39b9d69813662281947659534f9443f84266937c1000d8cccc430d5f9821126b9b28226d8a8c1d7a247e2d0cfce23c52c3a2c92fbbc45a86394500f7d984c9103bb77030b41b6c885b1ca1c8b1107878069d2bcc23b52a38651c8090f3cfb023826cb84089809e9abdf107e0b261a8ccb3cb8e10434acc40312ae18b93b89323c3a7676d0827beae3b4e7407827579efe5750c47a322bf76851a762caf62cc64370742ac715f182c4e6a77f47c5f23644f42010fc029c49c538c9b821c7761c1d2c27d7096c9f66ac8801660beb39cfd23e531603c7145d61668a612b3406d16feeb67bc5578bb972147fbc5e3f14059f55c8941177cf24910d1c94f1380f2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecda81133a299fbca37b4a69ad509ba44403ae3e5b2cf4277c8d22b68fc61f5e105dbd8c31f99609ea2770058352b81836b473ebe95c9cea90aeb682ca81b3e70508bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d3270406e5b4589f5401261b790cb02219636ad9c65ea5c48ce79c2cf4758db9bbb55e003e0c64f9b025ddaf1a341f8c2f26593adb9af185915c0489c77f1038abb9802ec812885af603267b7457210f5a00c917039b1b8e1bcbdb8b8b3ca9418d27ca6e96644f7090322993797a54bcb13cf59428d24d499c6f631e8694c50389496c6454fc34aec2677ebe05a0d61cb7ac553e2017c93d7183f06cf461331073786712a2566230f191c8169a1bba3a968a44a3fde764a0b5724e74615f3cc0f819616bbb21055d85f0fc40c667048fec26fe98b901b67a2923c57e17ccd2ed20f8c3731f10b58b7e9234c4151f6f4174fe6216f5aabfcd3b634122896a156bcc0ce93f41a8a25cd825334b53269881a682d8447975b45e839b8fc54b53f8c70a5aa9c786113ffa708ddd5070b841b58d25820fb6e4d8121ccd016b9601dbbfa4116e1aa9f904dfb5ac2b4d607f43a3961161e02092b9233c75b7020d5ab4bd7e3abc3b679c6d003a6a072f0038983677f606ab976474d8616a5dad0c15ebc10986b9be9f19df7c740fd1198adcc019d43766a847f05fb5cd7c16a6215a0dc251c894ac585a5b530e2611c839e98786fc5d1c1b0817da7c20dfafbc67f62bbc872cfdc153d83f328814abdb5f7babdcbb125298127a83bdfc503d6a8a2359136225b2bbd9baa2a11050774924b8662bcfc608848840cdba8f5d72fa3876ea79784e4784860047915c8922c96bd8f625d56729b96d88c3dba9eb3aa308a7940e90147c9110770f712cfc81224f36fa61c1225ca7a653c5ab8d0b4327c014ec580b9b347d0403c235b25cd88c992582d44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f6fa1f9e8c34d46a391e80bdd48691a930b3b0dace1b6b4b90b948794c14ec7b767ea6b2161702f9f5cf7336badbd2cd5bbc114f7b84d73a24e0049c03f83fc60b618ee23bfc5a286751970bc37b47432f982101e8fcc3ce01089d5898a46baca7265f05e4027ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedce0373a39b545738371499e3b7c88d20179434082ca235bdfa7701624a09b20bc65a10dac15c6c14268fc73be9d7a2f6556044c49a2006403848a726e767d2713be1dd04828da143df7860a9253566c9932fa54c9561ef5a26d990c308cb8a65ec8ced7181371a517c16a28ee9989f9d5acd50c8ba7085e95c03de98c978999c37195356dfb2e1da0768647c2e4ca6ae1d6bda251103ed17482cb0ce78ba17c69848475835a0c2e9d08b27bb220185a7ca40713aaa70068f75140c37d259150e6b4581670a6f8423a5979645309b7b0ebb0e911a68e46c48b150552f3093d425761196378863c431605ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = pass +expected_ciphertext = 187eba72434adcc60ef030ebf26c2b60cb370bbb217f1dfe1f662002df875aee461d371fac4ecd85cd34e406a2354d521ef4f24ea61231626a8f856596c2560a50a8bfa277e92228053b535f2fd7e88b8ba7fac2032f508face47ea7a8028d5adb5c200ac93dcaa8a26f521cec0e26ac0c32c0244044e71c1db0be8fcd9be389aa6a3b9bb51facea9f4a0d6d94359b2a04326d78f8fdb4e03cfa813e5a27ae1ec5a14779e3878b75a670990616d89a3e3e1460c6ee8c8cdf3c5971d3d372be837eee1252b5428e7ce752a0af05b34c1c40c9f8798f704466b53d83eb2be8233b041cf6c316c93b225d207ae6b3e9494900be4996cee6dae35d39f5a6bbf230bb5d99cc22c9901187e49221183935a5f4b696e449e925c87c9774a3ce2d0d189655beed14a4a33466f35b79b12449188b4f8c9e20d48ec98a1754231488ab6631e08617732857696df0924a362e6c88731e95aa9e8fc995744db8dc276fc8f6bb92a4b213700f795c8f888fe478bcf609e4e02db5330f3a29a2163c950e800c1e6c98cb86e3432c298529d7c678476a31f3936f35ae32a0e7ceadf56c38ed0af6aa6677c3d422dae5d259aff44de8e841736490dcbf8f2e5aabfa4b07ff71842c1187b9df78864e6ce527f6f5235279d69938e4b76fe68dd5e9f5bb87fc05cb87fc2bb8305718db18d2ad6034029853c6291877c6c8356a45e320698d342b327100e975ca9cd4b76b3486b800662e35f3acf57b375d253cb6e4e7e64779f00fc7ddb6b20693cc733e42110015f390223d168f59e000b75f9296d38649ee1eed28ee32e779d2a17b5a908e6d8855380896fa30932ae5996cb0761ab1a253e51fab1f564cda8d47b111510db92c3b8aa28cc406ad5a58283c3d36ce9d35bf85ff74c653f9926e3d9ab35692f202922481b7523c6c7d060d72d13dfed44e4374e6d95ce4a70d5e44169a80d8cb1de32d5cae2145cd90e96940fc5da4b3a0d14ecfeb654693f7ffdd202624c25d99aa254c45ff1b7ecdd6d0aeb786b8840fcd07c8aa9cd28dc15edb8be3cf5f8dded47ec3efed3df3e92ab87cb42d724235366339b4aa6f749af6e79ab606c8bc30f3903d9938fcad6c9f27586c3fb8d80428dd32683e0ea23b492bca855165c1e1ec9c812b4b7497956422da355539867392ce79c914f239408e763a7534331aa59428536e0cfdbbf81601d4af3aec59c4979f13c0c7c9856481d707a71d1a211b087f9c213ee9cb276ac05ee4a8938d8e9cf3267401221bb43ef369f7f3ae287bf99261b28f5b4377cf53be63a5da6e797dea2898f64d8ea52dc69b5de4c092639f168a4e24f202195afcd09cd9d7b9c1a5badd8024b2ae433781ea798bb422756fa17e5d1e4d3c08ef89e1194eadac34334ca6f6f1a69a79126353af5090cb605867bbbbc40d3f0b48e6c2a6aae40495d85c2fe9313fcc3d73b4ee0bef24cd3234c7562606144eefe5752ed1c9b8c81a25a8f0d20ce7bf4e282c934bce0c03cb095d1c54e13b85182886000c955db44b8d608eb22a5ff726645f28a1292aa32202a1be9d519c01b7232457cb32e633e8d14c3e90a51382610e569d72af874f3c557a944c2f1d3f172d0e9580431bb5cbe99b9fa564f6ebde1bcc3de195470bba8d50cb8d8a254522a32754a64d579ef292136cd80394e5a4aaf1690f2d42f9bad551e1443e120bb0c913719f5e7df94e95e227a9b5e0370a12629d37f12308c73e4eb5aee6c0b793df2f803e22d51d21a2b9078d3bf899d68f53326ce9a1d319ea9048d662bca4f455b1b7491dfcfaec3428916d635d8463dba2fc5e0833444ded908da99f2eccfab6d8c1666904ce96e57da3371b651e22a7cee4e123d362ff68db36283a19960b4ac3538cac26e7fe95f2209b66dcf934f087d5c73623a4eeabc118389cc12b993c2dc7d24e15af7e786bcba1ff7c505274027170055964ffbf60a1b929f773911eb36489e31d4c5107cb6cb4820a382b4d558d8f5deed70fd4b2468a2972fe14741b13b7b082152848d8b04c56cceca6c9a6f9917c6678d114db15d153911c622149a5319afafed2629b96734a58823a153c0e0761975751a291287a41e50238a065fee87a9b4751013afc304b4ffa822d3bb5c55cfef33a1223199cbf251c38e0ed11acd32b6f742d549d150aaff8688f28c66a803c41af1c52142b92c8a1ee40ac404a8f2cf45e548e5624 +expected_shared_secret = 07318e8edf0ca8f30f49fa906ec814e40ec52922f2c0ace243386ef2bf650000 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = f3fa06111b74ab835cc8479a8ebab78552ab3a3ac845a332bd1200c0635d3ad6768a4773aa803ebc08a0d7f772ff78ae9c90b5dd1b50e86724fc89110c128bda8209f0173e4d23210910bb05832b32017c182915308563c938695a0a8c49e6108c972587b04e6c916d5ac10ab425c15b370b0a4273d33530245048e62222d6211caab6a25332651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6fe701c23885e2141df14b4933c70040a295144a74a440487741116175addee87e656136a455bc9d1c5d611a22157aa3dd288b4ffa1d79668bf152bcb71108dc5916a223a703d376f3877406081c45a08470e4ae5679b34d2b4381335d8d5120282a656f121a861777d597a3b8910a67749855dba05f36831bd101ebbb427c92bd62f9c7f1a99a47c94e9dcba438835f3e053011f180f501c82611a64ec79e8b3563816a3fbffc5e033a114b8c94c9fb3391e0bbb8d4a33be98b219500f53b782fb2482fa9089b46b6f32555ba583370622771d02c6142647e6b87ddd382428552e58b80a66255394ab3815aa014c31878b74e7121b9f6d084edba988b43104910677aa62a1b27035de440b055146d15c466ea340b4658a41a885fe206c382923fd079f988b831a99d42241cc8637a647216eef18497298509832f8ce55235771e408a4bca646284771a0ae66ecdc2bb9d696d799c3cfad47a5a8b49575618bdac931d00c718049760f880831092fe3acd56d517377b00b156accc3ca6957ab22529673a59bfe87846c5431ef6b9c6c3201841da1451b881b2e26e44ac71e8858eeaa55aabd45281b56345222453440f7e427ebaf90bcd23c75e1cc96776ccdbf92766c778ad3b0a43a82463d09d79b90919eb76084438413573eafa0a60d26bd45ba0f75824c5808112406950d1ac5b226b9332709d1374b61957bb20ad7c33576bb68d265c7ddaaa12788c9e015a96009c0f99521e98e5c0cb38089d2101ef8700fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794257a277a983ce87c29c18f8535b07960bf20a3014974883529ba033a9604370a926778689937c774e74a3aea922f5fb717a7b73631c2e1f8c33f499674e584dc7f48e3efab83512c0f723ad981452003840215912e3d0abe816a58af87e1cea37daec759da34e24033c1842b2dc0a6909991b9e205178596c812a0cbaa48efb3586b5b6963fd445140bcfab6b4390832de8e27851b10619e699836a692bf44ceb23cd1f6938222b4b83f4a25a0c0c9ff397195bcf5dca633952aaf0321b121518f887c5ae945821f9b1150bc1d2401a7547ca3386bc33232cc58c6370508542994ca6cb098b01033c0c97ff468bc1c726a992181882ca810115fd2755ec18ce0f88cd37fb61580c039ab121ce95af498bbf4eea277eb780d3e0a0959a388d6a290fe58a64829184b763d3636b0551a90e5a9723b26f2c4869ff14ba806153d6ec32ad4c42d27161bf051be85303d9167245684bdb3198673c668e579a72136b6d252225b49f25746298532990352b90d82f6e324fb5877176555a078b82ac10bc8ea63a2b9067f13026584abfbc473909d50c58e9bc47bb99308298e6e90b3671adf643742e669a93e2a90b26723af4cf6bb64446619bdee7b5088369fbd737af0c4ae367313c699f384205c14c13c38599604390c7c911a5781bc2511208679510dc0d0dec26ec46718c748b59418bc353b7618195b77992858c06ff15a9077a37ace35101554e8a3932a9a9138a800bd3484b1b977d53f50a0443538aa5516780a094e6306e7842ee6a753c412d2a89c23eecb2b26a6ac90b3e890466a557394b520a07cb671ae9cd2c43621bf55a99a98392b9cfea6373d4b136dafa78c6e93ba7573b429b50be5949a254714c720721699290a510581b6af396879703aaf4a9781268446ba96a072009ffea0250c793237744e36bb0d3d752e1a6caa346a2f9d1695d49aa1aa2535c6449e8f4abf85079c0b99b91ac2e91613de6368c430a886eb15b192805e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c4d1a15b5c335af4091acc5bd189176b477938ebc700042cdbcb7385e10c3121b179660eb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = pass +expected_ciphertext = 847fb7979787cf06edd5ca8187896c920f8b275668939297c3bcd2e23dceb07ad7c62fa6accfd6be9a70fc1af69c82cdb4c6dbfc9b598ab08ab9e5a4d0c5c741c8f9f3896dd05f1c61246e517d1e88bd90e6eceb7ef563fe92cf8c17f2413dc19d9eddb96d57f7003b595b51242080b2d6a5abd04bac0e1e8075f983c452e16b8dcc5c3360fabb9fa5fd3671b50d3f7230c65a46b0e04c43278b2495fc45866afa27e387a967e985195037b4db1ff57f11882ef5db34452e587529e7f3b93ed113b0b82cbb9cafef86f90530f21649e22aac11f062dab01a5fe8c8fbeea23d9a7f4ef172387a6b08bf281f708cdcb060f84a2054eb3a996c35e30d6f87b88f76158413b3c01e50ff7284888e6b2600f77a3c08df381799fbb62c187dd81e570b2b14a730b55738da957aa140499c0b2e3b96aba03d2306819347b0e0c3feb1b28183edaa603a60cdc3a4c009f2c0fbf001f783b54734785479e3a95b4003eb0c57afb24c1c212be1ef92d1e9855c10c4e0f7773b3b069ca0de87c103ad4eb68257e64ee16e657f711159e22d5f9894c2b22abb8c8979d297dce205c20963307a151d2a2e1014f97edf1eb0ae530f26cccf31bc3376ba1d5485e3cd47360dbab0b7e1a9497ad6cb8edf1b7a37bd9d15431b5ed36b1328964f2f8de3ee109ed9b1ad2b5411d1c71733862793054726c0f733fb7447e59760174e059aa4c3ca6683e6eea278ed52d36d13c4af8b7a9574cefbda22104e93942f147eeb77daf30ebbe3b90543f562a549c830a5e0cfe91c1841b6668570caf37e274f8fe49f29c0eda1bc3d074231b4c0cac1816bdd8e9e32b714fcbe40b853415f8df08a4e859a65bda61dcd173c2ed6eeb080d4c77e45ad553f1211f478163e9a548eb9b275c695a00971498b248eb3c56fa28ba886193a49d135bb85909357b8363dfa9a5e420a48fcddc95449fd1d2ffb712060033d4ddcdba89b2a9cb1dc4cea293fa6d46480f7b916b91b8563b17f9bd0161512766ab6d8f1e70acce3af223fa0217a843e7bca4a9bdbb86a440837d6766d9900f292124f93b71133ee6e6091e5e9b3f4aacd3ae9e5743f3d41e851001788b87680f07b80259ae213abce3d119b191e6877988a2dbf56027a39dfd3b00cb38dfa13b7663781673e745de54af5c3b3b0dfee94c8688606df28f6af8909e04a3fedb7afd7c19e27ae2b0e7b7edaeb59a292880bd08c74ec2a07fe47c9c6070ad98099d655f263960f9c0a06ac78570409c391a26ede69da5976af32c16c156a733a1c59045b85840f5cd01ad3e708b8925d5f46ea49c51845f832e389aff2db412e9272e6606a7c1a7e69237a25bc552759b3fd0eae62e59ff8ae8891cabdcc8678ef2a0326514bea8a50928261f7e27033de9afdce4eeeeb5352c9f37d6a00d96b272588a3390ad5645d4f9a497d4e24649e2d84f92bec532ee95595b9c3d64e96408c9292da2049264b595db45ddf8d252eebff55a24a1f8fcf9c8a4b8525ac2b129b396da03d3dbabfa7ad085c3f3ae03d74154bc63aa631e84721242773f384959869c36efb99e19e25f1343f3e4d5ccaa3b59b12aba72571db26315991ea6c1dc626bf9ccfd03ab89412435c1e1ec283aa6da8677655380e55d29670a0df9e5aac18bda35cb807c4bfaa6bd3e3324c1852e6847b4c15f2ff8473427ff475057c75ce75b49004568c61c7b891c8bb2d7ed9d7914a5990252bd34836bce00a63fe5b3b06d6a0173554fc5aa11650ad1cfc84ffc1bf2435a8cd0959f0a13a3a38f239ac9e847d858b18840bc9a3471303a7aa77cc375719de84f832cecd0885057306705cf928a7d78db8d03c8702e55c44f6debb0ab613ea31e8498e9afe9c3f51b7ffaa5ff34419323d4bef3eb4f120464a64287ce75f5fe18cf6cf596a197540ad31bf5c157758d9c513631f3d5db093995fc89c67f6623f48d9fe23de28f8bc2f590c3ed5b9899aa397fcda3214ddd30b413a047f9765c7b0606e21ad56bfbc5cf330355671e28df4eda19b7ca89cf6ea84da9ad0f8ed6d41c59d42331828916af76f13453265673a8a7f03cbee6e70894bb6b17cc01efc9ad0d45ea6a6a73d420d097ef5b87cf580d179b573f15790665816530a9a78a8200bdda59b73d38dc1de856e5ea100d51d46cedccb3b2fb60c043dd7c9b0973f9e6ed2169f0ece4dad007978997fecf33d9037abcd7d622ee0 +expected_shared_secret = 38b5d71f3a64feb2cd41d6b7a4ac5440707770dc4c472c3ed141165fb7e8818f + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 5987636a96b26372851e703a9bd36d85e966fda580cc79af69772c2a9a7042363a3e3c116dc7711ed06fbf956dd06266329002630508b7d1ca73cbc853e62b23a02bff7404ebe390fcf58bd57262cf1044aa22225fb36446d44e1b8171aa67c415f96db0e109afa31fd00631bfa23f3b6c9c02b20dc3dc1ba6f30e6f20c9ec7471cef6996350bb87d43690c059065cacf697c63b6bc98c881d3ca56f07c34a5b0b10cab263bb75399d162db389206939b15df58448837e0d443b8df132c65bac83d2166c780132875fad888a1c53aea51661c135cea6956c2a4b87a53baefe726fdf09687f6cade7bc9ef5bc25dbdca95a0acc47e0caef22159af5b499fb6e8643c70803ba40a5938a422433053bdec4b729744b565066962046c5d2bd14f14bf0b4030be99a8a198b80b99ec939791bfc8572942e98d47b00814c6a85c39ae7323cebbf353439f3961f0abb687b4c18dd06b706db4350fc4a2e868229272f499709eb1450c2995d9b809e77e676b628aab0212475e602831a367d3948cdfb0d43eb0865eac55c516069893d09f24a8176a3beca0c6065abca0a3a2b3053da2a3bca6a7088f39d9bc8b1e685b67612413aa3b2ba4673b301cd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a8f134fd1cb590819a65190af53355a6483b6a9909bef36c76836c77168c679757ef404a8528cd569911d036c751d4ba4cb1c34b695caf487866cb1de5554196682d32285490a75fb5d18d3b40539adc4d9ad71452016a6fc7156b34014117bc0dc45eb319a1f85b642f7ca7a12164bc7a1feb9114a7c5ba8d7456cc08a883ac86100272b710b225e49de711115b418946f503586076411c6ca3ec11a5244774a27baacc543556582781b273bccab4326b4140b5643c86d310331bfb859f80062ad27e38ea1724dc4b7c3498a8601c11f25c99001db2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8ac2ce68b6b8b2e51fad7939979593f8f19e19b2c18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01a8065c6756e6ecb64de11fed0acefdd45fc50c1f51b045d8e096a9e77f10dc8e8349b5da9723a1829e2ee3cc0379942fc47841b81df7a94ec7f40bfc2b737d9725486316c2ec3e2b516dbf7cb4936217cd4b23e4422122854791a2cb136a1236677a4e42504ae43bfc93259441bc0d676f8932a757c087f806b59e6380197b37719a2fba88b64ca54fc69ac8e2b79df7154403249441d103f931a25283bcded4c8b51a7995655d49611ddb2ac406b28ab2a80342f51bb8126afd65412b06d0596622e5722465b846a52b47fc6b5842f12acd602ef9c74065d5940d2462f7d99d39ea5f62b46f9fe297f1c01f5183c73c3ccb63c564dbc4c1c60877960202d9369b750129d91060d1708f057811e68c47c4b68781c102f2765e093c94f6c43b784679c4257287680825fc5116cc04b489add5a009a3e65b09644d5a9a9745d249314c4693f017a6d5b054d07fde34cbde568ea6fb9bb56c8c5023142cd19eb2b3b0c6b8bdeedac8b78909b1bb1894b382e6fca4fcd63390cabfb4d516fb18526bb45a0f9a6aed971050788cdd044248839d954594259b562317cb163273b12b453638b70be1085e51c5ac0b6cdd15c218103e92c53750f107ada702d8725548ccc663947c3dd959811842b62b13f9a24b1b4a18f5691dc4cc331c362747f1654e1b785ad1c07443aea2f6006bd670d7128a8373c68aa36ffc59797ab3994bea35ce894466f0c64c061b5d48b9a18c5544dc0820479722795d77c85f161b865dba01a70cc9c00c15167aa35bf0a147147a81d540346489dc58926c975333cc3d286b4c529a2e3e6aa6d2225016a7126dcb46669c72c453bd745632e772bd2da7c1ca87318276ad21ebbb6c419ee2eaa46a733e3934c0ae933950da8fd2eccedf2919d7e8a6812897780275adf78e6dc21757c7a0a489cd8cd95126a569af7c67bf317b146743b0d32a6762103a13698120cf7d07b72be91177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516c5115c724af7cf05049a012c8e601e8b5237e1aa5652cc5e4e1a6d0504331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = pass +expected_ciphertext = 8c37340c59cfd8a543f9b76adfa38a34ceb4001269edb19d3acadfafb41bb5aa7c1b734e46de5046954fcc6188dc046bab996c1900dbdeafb72d1f8a3c4f51f6d118755cbccbc597f525cb827657dfb2ce3489b53e2a5ea10f73bbf1531770483ddd4083164e64620ab483ebed4a0b49e7b282dc0ddfd8fe3904d7c3d168112c7bdf0694a44be82782a024a105c11bd8a1401bbb5d0f97b23026d88449ab41d5ad616d647ba7b31228e3edc05c529a0cb081a5c1d8f12d4a6f0a6ee2ae3271982a5ee9ba9e06c0d931067b13fda615d30168c29add7a3dedd4ba1069bc58a56e66eb04f21cd3caa5b3e7655ba88d19f2a8060d2ab31b1cd73eb31a428bc421c8d27cb9c03bc9f866b6250488f73bb5ec1a9851c3607316c9ae0b47b39f2729af9fce32f8e1cef63bc167862365c8f18f36a559f6b91ee35d827135018c9a0dcd7431778996ebe3a4fd009c0f4d8e94c6d8089960d5c16f152d84139989836c86d1c4267322325a93025912dbfe11042d5cdd2e01ca8468f3dd86f29a7f33de0746a5c53eadf5d4c85a9de76e2b8ae4e4175bec7145803e5d6d57625fcc23186d1df1ff08c646dc416fed539b91443702331b8b46a1ff6e33573f474eecece71cfbea722f0be68fb6c99d815f626eb15eeacae5333dbe5479c29fb82b1e4b59350c5123a373b5f581085f3e388539f76864184596bc37424aff1ff26feda8833966286234e6f81a759a47f2b79aec8de967c4527f12ba414d887e19bfa224c99def53b9f66f44b695b5d24230e2440e0bba3114f6553c85df67c850632cdee289df39185af65b65be5e25f4bd27feb4d0c619b54a38aa8c5d665500d6243dac963407b7b667d492b497ca639ebe0471364473eb95886288b1663afc1dda99927674fcf7ffeba9dce8f76f0900f64957948373eed776996786d3d91d42dc1c7552d82ed2f0777d0d231736e4f05c24785ab0b40dc3fbedd959948a515be53cdaf1fa044033561721ac7a3f930ddadb812e6051e067d8e0883d2421ca6564802d02abdcf4ebaa9f94eb6f59f56306be7f265d4f676c58a72e78427258d4d011329708763d7b2f2aaa69de494d389eef0025d09015c4061e558ba2137b8051aa037694cedf59380fe62e0c5c8cbc0d80b2d72d7ee1d61ce81d5305ca9d35bdbdebd159136284eac79117dd4065e80f0a72ae43236caf71ce09c61cbd9023042e6eb8499b6463d409bb94b2886fc8d59b7765321485ef64f8fb4455fd0c1f14597e9b90a62f38123888fbdf6e1d4dfe730c769d1521db0e29bcba50d4fb447417c4c2b838f5984af13edba3d9b5b547177629749461fde7fb5b3fd72837445c8779588bb88ed67a44a253449d6e20f2dce29e484b19d1b1bd4aae5466c212b84a626ea97a9d6a9787da5c5eda1f41c34cabb8cabc4d05484391f6140129a260f96133f2118782e242409532e4d48931c3120903b2a6cd728a22accfdf2ffd81d1defc60ae9bb8f60caeefe7fe12dcefe951b5362b1d068f7af1c4e3c7d37046f7bfa8c10fa1f21f18101b57a77b7d76df2a6630697d2c6dd772453b2b7fd0833ba67369de9c6eca2bf94d8fe31997ca6cee22ca2874bbc87ebf3fb0edeaa88fe262c355b5aa21b6bc8a42ab18a48bc5c30efe96fa75769f4a2d2fcbb872b6ed8f616b1b05f53c4072812dee5f09d33a38fa51cbf08239dd806806421ed0118f411fe38f9d4256b2b110101aa7bacf01e0079af5a8b60d8aa1a179a6189120a00678e29255eeb4c77f2d8453d73accc226fa0dca7ba6b00aa8a27dc2647dd8f163cdf8c6de93251c1ff97396fcf80ee7cb0fb249192760baddaee22b2d8ba73a38cd71da3b78ea2b107d6e85c2f637faec470377e064a61670437d8ab58be9937bbfac5c060f365b2200e637bfcec0844de7621f2c438727048005fef0b4c08a99e86397c7de530cd4014b055b8b66013477e8d0f0b009aad118448e233ec2b8b6beb3bfcf9e60bdcd541c910e8d8bb72b56c0946c95ecb9167174bfa90cbf2b03a0d7b6250e4793694cb48a8d299780aac15e40ab66d4d18dcd634dcb0e09894ad42c5cee716cef46fcc1be68d52342be20c43c98af395636b0c5f33d261d16a921adad7a0b88dbe8650b5a6ebb6c18be5a4615087817fd96bf0d0c96d74f9e7f3e06a2b3d5e2843159e26b90ca7b5995f62ba2b6ca3819b61e34a70129d9b3a1b5de +expected_shared_secret = 368a5e417f4fc728f5080e8fe206ca7558909f6537f1012a58b2d9d45b7c6a8e + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = 3c2199c59446aa08c7646c1f567ac35c18b82cb24ab1c51f2ce8a79ba51f432672ccf12c23a5750e9c9a6818b628a49a812377587323b1e63d8f21a9dfc76095827cfe352667c16e888b1a621736c28c8acea052f8c4618591b36650a63cf00b904120ce716fcfb40db52347b12486442267bea46c1b778a98268481155c53a72c5731ac2ee36fb72c61b60273d1419ab8e82611921c99dbcd4e209d2af64a08ac27bcd21fb7b9373f8a84241a1bad24c8dc11203b3554ac802dcd18104dc8833a4b60edb07f9135b452209b65229bef0ba922cc60e32954096794b7248f94b134143b0ab3a8c2288a6065e7adf5049e918b3447ac156bd462a204a6d8d680761b9e70d8796fa149dbd45509b6169bc34ea8b876d30c7a2e51943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397db06693c20cd7caa079576834a0991761c79fb660843778229b2af530276c345ef8c420ee395455ab47df46609b0bd34e2aa7f35af596750c71c4aa2754afdc48481a018f2499fae61584eca38f331c571bcbf73ac01b349953081908979499f2bcd6939b81a5199fb5838324928372aa2efb6c8da025873318c08117fcf47302fe99a31b923ba947871c6ad7168246341ae1c567f8706b88f240473a646173a58d559cb5d3865f2072d99b78cb7d63617fc05dd16391830cc22e2ccdec55c46f84262f59d1718c473626f55c8022849935b3a32f55180dd7b67cf496c999189d177cceeda613721718b0a2e74e0301e667ae8aa36d83298b2983054a3824d64097e380585c4288be24e5e711f09e72d31d29164fb34ec7068987241266587a367b067284f3595663f927255c66bc7c79e5575744500792e8236288a432b092597069182c28667c51b76c4a422dc8a023127b58979290043cc79011205cc7e61aed141bcb4c090a6405263e3c9d613a5d1b5b7e0a8c5915611fef213eb4a9891d49f303967ec3ac40ee145e8724e8ae90c6eab8edf970fddb459b66b654c8c1fe039ce07ebb50e441bbe386ac39473b9a6a26f0ba3799155bf047ed33a56eda493c26b6bfa912cd56623b18254d84c3e8e34a23b3948d4579d1dc301706c835d879787cc5964334e52875836e4b105fb9abb613bb3ac9a65ba8f39470e3aa20bdb1741f1f78d527555e10caac4e17f57e89a520514716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df76281d4515e4229547d235be6b6925063cc3832e08d192b6193d6c02a0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fcf819403ca08684a418c04e6e6397cad03b77b2bf3624b89d176f87c82508c9cb13d60b9b3194ff52a7b58413088b2964b2b92b94463f2cbd92444a888154410990c2d5c018916b5f7059c2087cdae1bf06942d05d997bbcb289bfb0725db84f6e23c96da5c64595e96969097b8b9a28c5adbe36093203f01039a0ada6e63a21d22794405940142e0c959bc624619b964dc6b60a1cd31dc99c4342d1ed67c534570a658361376378e82896f216e57c21159967212481845c112fe0a3b1b4b888ce4c22b3c73fb87084d645359a23d7929704738af9ee7abaeac15cd8c6d87295f849341bdf68b24a85621f397fcd31a209b3089151bd44c9d90092ebd2844fe173392a8836876ccd9d97cad570bfb55523cc7763502acc4d337e8634f97647f4a0996514264b0a3c6681022b739a66a98b92cd0577cf1906bf72cfdb23605169d0ef37ab96baa1aac1322149bf682025c3bb7adcc79c1a9c8fb52c3d4b529fda48997bb71d18a3d4fd201000c4648b634778b7a5ff190a27c1e631381b777ac0e858db4033509c66bf1bba3a5828fb7f578e8fa51c7c87bfca883ea96a968d78bf312983e6ba51bd05617c90a1677159ddb6d4ffb62b8642e56eca75cba3f9d810102037b2c57c7502a60831b15b49c87b7a14fceb228d2f0b82e1a5cb632b8d3070560977b24d591e7cc0c07017a09104d2ee24e6dc2c3af1231af922d62629c32481bfbe309d5a0cb4b61c2eccc7e9bf05fad1a7fcfc3635192c90d76668fc91a297cba04621dfefa729996bd118a308491b59c16cb7077456b0b48da4757f23b90253ca5a2c1aea9a524e08293d77022f66b5707aa4f30f6b099332cdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = pass +expected_ciphertext = 492ddd4ed467d0e58e5e369c7fc26bdc88d83193f7e8cac9bef9348f3eaebf7b621de26c223fb6d9a0906bfe41bea0489292f6f9ecfb668712d2b13b7581529e77bbe52c7484ef70307bf56f5c1eebd6ff89a501e67fc0434ea4410ecc496a534a4e930965ba6827b45624eb6155678aee08fa5ad5a8c28f4d00becd89f0caa1463a029138eeb409e3ee86fce90a53500d04ece098620e7dbc6ed6ba67626c22948078113599f0a6ffeccde84f9570a3744566aa5541048fe51bba811d2f2fc0cf6681dc19c854b7e115b02962339cce2bfecb378c5a38cc4cdbe150fee1364746da4950927b1a48957f7c3dfcc836eff46505d61502bfb5d15e4b88f335e8cb9136294b6a9cec1ddf86d0974e6fec6d1768b27915604b1c73b65f019c8521ead40fc262f87319cbda47dddd387d6663dc06e6eb730bc06508d33cfe7f19d0cb8a25cadfcc96dd330ebe536c8c01838006aceadefddddb9da6cafbf1e2c3788edf391ef0a044d2c30a18458de6bd9fa993500333526b171148b48e5dec630313469c2f95138669f6b7c51e68bf67d4b95faf4b53f62ad0d1e38eab35af79fe7b3dcda2829046e20f2176e3003a3ec9ee87c351285eeb0980affe05e4d4404c8c122e1d9d3280e3af34d98d153cb0ddc25b88f16b3632d46dc187a0514b10262060a59867ce8fe781ca067958ddad2aadc69006eb980bab6a1fb515dab615edc771e5486ea24edc602c4526c785d0040026bf193d80e68e49b9c00cb00dccf3b3d9fcf59856fcd3c077b1b62abcc2f4b5a173b0716f833c34e1d5f33fe11010a02d56ec905b475212e01cb7cbfd47cd389222d7865ca484ff9bc6beacfe18dd9543e1cc7ec5e925e77ab33b5fee26c62943f8e95cb5551c21990ab63b33ca50ee4e2c4159ca4fbb5953ce7101a172d1a6b51a92cb7d80708625897f09c71ac2dd8491b0f40d3b287b3e2ad547557b21e47531d4029cdce70b580411ef0a5107491e8fe60d01b44d9849fef9c4e07a21110913ee320fe001102b986241fc6e914052e833271c6fd9921be7d794745af164e3a9851d3396f4544142b5c6f560d5f68c2b5c7dbe71eda07a4c4072c2f33636b36f457546ab81de8329661a008d94bccfceaafdf421c8c46a00fe0e9ebf20a335661cdf6d3ca61b8e3994f1f442f9598b93aca6fec36e524437a903a9fe356cd34b3d37809f93c702799066ee40df443492d934c8ccbf961f5b9a2522a139194f0e2f6b6e3b2ae2bf7df843b13a66a9e4786851d3996fe808ffe7196cf729d093a115fd8776c411c87a7aab196d1dd83abe6483d1e5edbefb09f40a24acd610a4937f41aacb9f50d4b2e122ed9ccdb0d62dc278dfc710620a291281f5738439a4b3af19d5264e3c3bc69be681349bb4aa03617a3299e433ed6e2c66f7dd2896910b65d365c9c157a49f703cd64a20c40f05f11dce7621e16ae9ce148f1463cd695bc0387a378bf659f6ccb8594e9a5d3f38b5e68739306198f5cfcaec603de5f2ef125b16bb2e8804e0df41c98dffc1e4c5949524c491eb882790474b98dc348e1d4b0414a30631500c85ee203852db7ae58892c7aea3415ddd854001b07a0c3fee2ea7414b4a7bad71ca71b4451b7257a04ce9e0be5f416e4bfb69abab2f717b1bbd795ff53346ad025933fc88cb3753685206fc1eaff473c2637dd3b9ee29998902f0456fdfdaf6d267499d1bc3e3cade385509bbd86c03af612f1e9d458cf134aab214d44774b591e3f8f32160bc8800fb83976235253cf0e3f21ac0cdb92fe209071077809ec7486edd35dba646a00205b91144441aab1dfb3b457b10ae14098c6154fb19e9f3ff083b2d199f272920e704718674c2ad1fa73507ac78e305c2a4f122bf13b9e9fb002ac128dab41cd10d123ee4f2b690e9083d66aa048e66dab4ef5c0bcb9583bead7e56542b172b21a03147de98de4e3c5292926cd96ff6a2740474d0d7d08dc8d2a42b34e9ea00f4e6188ec714158fa367ec7aba30af44b992cfa68018619a670f72bfc9363cc892e331fb05b4d54da38a3ee44556b3a848ae6f65c8f506171c3843f5943b0910116896a63c780a9678b4424a7527fbf2cb445f60d839b9b2f46878af32a7faed6ada4416377c8146468501cc2599bb20e674370d2ea13ab8754959d826706400091706ac63cc068871c98a8d3e9c29e18c150741fe5254d78b4c3558fcd8b8 +expected_shared_secret = 7d36e561b501a687939aa880285d32cd6d8b66e2e65b2a076d5aa516cb5b2e6c + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 5651279153af42d2940a191c57e30e0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd4e0794d55bb26379871fa7692fc7fb61c8f0565916db30861a2a61b346986697690d16185753395060b229326681b16cd5b8069fb5498aac4ac9023adc380aaea764fd8625f765f5d73a1189a7524a6bdd1209a8a23bbc5d96c54b89b9f256d20f396b6f61e47e0989ac04cfb267b175a8b38395dc3e976feeba1967ace1c491733cb3b005580fbf666ff6093597cc59362cf60d074f6d33c3be33bd02bb0d3460abd45889cba06129ab11fe978d4749a675c32e2e9bb2d6816ce198bc5e67bd6069666c6b1ef780765664ef650c9847566e02c116f5318d1fb240a167a89b2381cb4cd7ad60eda125bfad338bfd668a008a9f9354999949ce5fc09aa21025a83cdb2c7cfdcbb3e03e0212d58b78e00ad85ca97e3f64a82e79d26053da439862eaabf9bba6a11f225ce27be4cb2ac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd8306370672f20f315474836509c93ea814c9c77a4366325d13c52b0d5a231d79ddf765e774c9c60f6a2f7b1377630be03149a31d7112e61b32296234678bebbe05bcc4857453858b06680399c699fd23a9f96b95f5978437b5d453704c32317beaa45222133d6cb8a5e984633081170c154d68674896911ce5014a9054c37901411ba72f77474b5591e0e1477705a3e1b535d4ed3b3c1d043de517b23035239a39694005c00ca332d9b5c98a16034550d4a92169966882bcb28f01171e276bb36f98dc3dca74058462f2caa4d5a9e60991f848b6c519c45332b18232b900d9787dc78a685360336b685d5301315923f8df99d34b8267932496ae4981a2cc94739cf075343de4231736b42d9866b0ce7030be42aca98309021b24a1a518dd0107c2b03a75552c169b605635323d9cfee4c607c656724b48f523a1ebee51393e1538dca234d864066f7417b1b67968a2c03f9b85255148a9409bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f63c1646e015d64066402a2a8f36b7c96e0a50ea13c220103194bb188c6947e533b1a173cdaf225eec27720a61bb3017205e98258fb470641633d955d14589bc566c9fce9590b6141f9c662baa60ceac1a7b0e518e370c27da21e2a098d62433f2fc336340851e2e536e0b2ae8c2b2b58057b5d30a8fab602c48ccfada926455549ee4c15f2369f58742d5fa85415990faab1b76eeaba47d05a0c35653b36192a6b108046bca55443fa075f072270e836293ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccab92446a09c8be6653f9398b4d5540e8544d56d5c88dd20ea99344b747304f56b2aa725f1a858eb7bbae293b891ca61c2d5942204455cb726c29a23231eacfac678dbd002ea8395203172b35a448ed3944bb07bd2e11b9fb52caca2213dd482159821ef5d9a98d09147e272d3a9b84023172d0d1ade55662b02a9574c13a5d5b79575c25c9d46bc5c766e4768836f787cc6a771a772518e7c5a2f4716e007900db8abc8a630916a268b080cf12ac427a02c474ad28caa73a5793bb0a7593913debfc4cd353ab92bb23d78a2822527e58f52f4d5a70b2f05eb0e6231dc43e5fb7c27bf6870181709f1b0ef4175753687a66261f32773dcc520c752ca7ad6344155bc63f000e1c18be1d154476a4a639d2ae5e36bbc157a7c7f8291b6506f12aa8003784927284fe1b1a4fb70aba9a39d0775dfa293f9a29a4fa3712fda54c41e45c6696aca509d09e42618164c34f78b5b385750ea93d39abbbac58640ce09e5a5245a37847c78765d731596bb10123f51793ea5d97c0321fb5810a22af50406e53806569c53750153ca7b49dddea12baf4ade371b4c7d05e29369a5d1c71ee1ba62db26c74b456cf30832018cfca235b32174c031c53b4c653ee205c632218ce05676f2878930334c2c284d7e3b73683cce303694e68bc7f95b0d186acf5101d95fb6ce55acda6743c7512638e42978af9037272a1a5e23e3632059ee1a3367ca9bacb27930700d19327a0c6ac9fb57d3e41bedcdcc47efc18653c2c5cd78200ac77b066b018d137facac920790bc9e593cc243761cab947818e8ad7ae6701601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = pass +expected_ciphertext = 698d515fcb3a6cae5c7489af712c4417864c849109264cde1dbffbe903630ba3fe59f0201fadbcd93708918530542cbf035b3f6e863476d736a80f413550e52998bc8f525d9d18d1cace1087b7a06e5c2257aa7fd93d6050f8da704e2694b73d17cbf356f974e415eb55e9f445e12f2fe78e69000879bb91a281f7a6062fa4994cb8c6096bb28da068b1e611340c5d0c2f12fbd20fad155361c019dcfbd101e478008a500d7492655c9baa4f04af597cc67e49705ae03b670ca112e2eb718cdf7399be05eee4e8fc14fb100b5ce1c024c8df11db2ca992b0560826e81cc5a18079d1a45e84648616d284fdad7a6fad5bfd59659d967208ec7e2a9fec243790401f85e0e7d147abfa0e585edf00e4a4341ffbd923038f2d43db27b0ce197f24302ce668743490068edf8dfe829786187f95a92a97bbb652135138945d279814ca80f2b7534f6c4009e1e806a4908712bded1b98d2caac89f1691a0f0a3e8072860705196b73292c9caa1994cd72ba5c721b01d9d94e0bed202084577bad20fb3d7f090a1dd156571964131ea5af05a12af20c39de5f8d4157e564e0653b3e0aa5c6fd8fa1bfe72e70b163eba1faad62164c4f05d7cb1caa1d1d9b973de2c10e439ca4c4cedc8dbed545de21722f0c0dcfb17f8d3e3abb197e7456c804ed7d6350eda067f2904ed9037f2d8cab1b53bffcaf42f20b05677a9cea30be46618c75e5c0b943be4c03e613f9676b5b49384ecfb9603bb0087129610df0530d83c742aa5dd4bdf93d18a816f02984c0e7a1014a03822f69b99c48fb63c578b17bcf190af9e1b6531fb739d1e5e67722c8956e0452f2d6bd4a2ef2c9007ec2c9d32ec193540c67911731b97e101e37f3dd3e6e5e5ac0e12ecdbd154d47fa0a55cbdef4cf77e2d95125910f95352717c33c8b62672f03f04cc60b0052b23f42ada97ca43a614bd1cc1aeed6978a841420236ce6b768937175ca9e95795ebffabba193397affa7328e14d8028252feb88f923d8e3ebe84e9e435d7c273425ddcda52740db716cb319de921a2330b7fec204a562386a72e36c8d01f3814a37e5cf0e1270ab565fbb4154193c1b35093448fa215de9ad83454db5a442c68077b0928bf3b10e1e5ea220fc655d31e47307bfd09cfefb9f6a469502390452af9dd459719f51fba3c3cfd40895b27495f8d4d8ba7351be43c908b8d6f71d060f3410abb5b8d34592ce663893cd6d6cfe31fa16dc93d156248cbf320ff7bc6f5167589e1688a7ca2474822fd408d29b5c637c82ae85098accc55e1439b96180d0b0e03c5766c880233741541ce1330f84ce1969ba735e22a20578265751e76fdac1cf15e7fd64e838131f69132079a12a104e330728a3951c18b4a1b45ecaf81368983fc31da091c708c910b608cff0798abba8812c07af6af07d274f046fb0a4fbf74a20467c6059a9a43474e7587c27e009b74ef4720fc9773748042dce5e17f3c1b0bd203e629f28611776530858e34493779604f1cabd13aed8b20ce2023425ccfe9bf1be4e38ec0c650b9ac6b804ccedcd0713a895f673bccba4c7cb06dc3e6c70a92da9986bfadf9ac0efa5685c45594edf0e40cdcd369f5ce2a845b4a43d27ec464ee8790a27e669f793c8bcad4fc9b8aef359ff16492bf65ed42edcfb3d81f38eeda496c50c118ac5450fd4bc7b5339c9664b32492ad9c5e94502f9c032f06640ebadcf5d345b5460d07e3f415d5982e073c36a5fa497d904d574cd571c0dbbac1fa0649166c04e70a9bf061ecf15b63befb0ceb7a62465c3bc27087fa3c61ea7f8f005f667727e9ac51b37f915439cc1ccb017dcd2e99e48506429060d3ee8f3db5db83301a1bcda31d05f68b95236ad1ddd47204564d3d9999aa3e46eacd30073d4bee95faa12a91a744e75720365f951e1292d891f94dd86c1ae951ec261b1164a796a316f026f5fd6b07d3d8984dbf82cad3b4ab0e3c3eea8fa7975765b35452d6d08e7e875e7af3870a4cf4e5b14cccb6292f859169ccbd43f915da362e7efecd46c61c65916ca1a39e2c0c9447e924dca74be8d0eb36b5f3be4028ebeb1e7f72c982054b6807f77d64c25689ff1b70098f1ce980f211c61d5b297ca7736325d0b8eed6ff2844dd954f7cb26b9be8c2ce00a73c876915a1fdd3094f0d85797a8df245a31624b484b270e4f39920943c6920714e86c5b6d3c32eb6dd6ead82d44584 +expected_shared_secret = 6be99cc08c8bf10372f7d5c27bc3ecd17ade8afb967aad41a1b33c0ff848a1be + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = b7fa152b25c460c63c4d18ad733422163c0e26ba99530074269c212f2697f2073bcac61e4e603b18b575bf696d7feb8724400848f05e91186052b05ac7828127802fbd1672b3fb45ff418374d61f1aca1c1b93af018cb60f006d04418088216844b29f9b64bd46710657ca30a054bb1bb0161a857edab220813170d1cb96f3d82365317cfee94eb1a8ba6bf82af10acbe3626c7284b622b314d72469ebc76d3ad8cceaa93e08793490ea0a73408a1cdbb066b67d1351af5a6c477d2b90b68a3982b70d32346cbdb15ef09736b28c23cbe03d18998270013509f13c7eb95d5a03895301cf2d0cbece1908b3c28e73e676304b0c98f7932bc246107ac07b27090c2779ea2b8c987b084d86bcc40496a1c44c751438af5951acf276b25414d4e37aafa3a1fa5b8fb0fa11be21bc76b7816aa3a1df142446aac524a6a41aa3411e00609f297e698026f852094e2a2e5e9146f812c283529e16256050204ad3b03f04e35af7d36799605903e8c3e2663f9e89791aa8cbf1b8047f2a159dd909d01a3eb3f081a930b26b6b3c32b7172b77bbaaf1ad51401c645b63828842ea7b7803f9699740cac72b56f434ab7e1c09b4ac5368dc559d603c5aa471cd673bac5abf0f858dbc672e16f819149094f2b144d008c06ba0c36ab2a61053629f994fc233a38576a7821229e79685c2147b7b15156493c1eaa2c087134f1222758b00b3cc10804561b24974742c2aa016e23cb19c868244c65371b6bbf31d5603b46e58bebf638fb7924ef4181d02f6a1da6321a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533d62b8d31889e6679251560d0fbb4f768501aebaffcb116a23422f48ccd89e0c645a11b0f80ad2c77a2f30b8cf415084e5c9f655824eca8be8835a81a6c9832e09c3c596417657657a9c85a13a54d3c0d2c427a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9c92ab3ca1a8c47c89d1a742cbf4352b762a60226cbbbcb28272856b2bb3f176ab32955c96a0274723a508730aa94730f998ce0e04ce1e67726412233e8b96c31481bd017c67f1aea09a3e96f897b70b969cf405ba7424a0e8aea4b45c6206752c075e2bd3b3abc53f99f2842a459a55118a10f87d8f0c2caf4180ec741738d6a04efa30f9b3b9af587c33297bebf8778b960596bc3095439ef3448c11871d228a0dc24718f6c59c8c73234a641c47917b27b46cda986a1857315911673ba0468641757ec5ae71c860de0b5ebf05cf6889a170743a27350b19e406a77427421a54f1c163862a43c6ec1260d45139b7419b0538ae31a0ac78584b3264cca519ec35acd94c1ae5b436eaf82fecfac8681224fa810fb0a95581528ae300081efabd7e599517c21f469208f4daa500b9225560b9381707440082675293dba332ca00c4cf746f46041b78d219eda4bbbd32cf07e37e20e15c25f8a96b5706fcc71f620abbf052a572d73b24c5445715c77187a1baa883a714329d619a10cc2c9c84b2c4c098f0e42c4c00a77c44845b45003b7c1bc587a3f6c10d34269430765da39550e2b78fd7b97cd9128a5d8653b7aa05164101a9285a9c1a77a8b255d1b8533a1315a82bcf7e6620c4224ce830b83844bb16560d6ef98819e0ab4523acc16961229a0b0847410b19647ca7836345b275609d5d12bcdfa5163b0c4caaf2a0f05993ed16b89dc14d33a60b56a0a298e453a4883c7b6c7bd2186718da1a29895b2c066bc6a2896947431fb224ab31b11f204f8047bd5e421d92b78357694d8959991e56b6a123373c00463bc259f78a3c2e7b3526331323e9af2bb55726795fd904160c302242b1bd7d65103da1395d82aa5f662e4edbc812479b0b79ae15f25a07363080d887fe8a0df37b51b5ab7c3e878d21086ca0e1cc47d877194cad6e384a81403adf05c430d22d47516acdbc946498a281611bb9f73ac3424f6cac3146faae1611103ca4008fa95a8ebca35ae114ffe14921a855f5049447643c391588444217a510ae31b82b5c159c928ba434890aee2c7268724bbc29cfd152b05d73198e7b62b43b9b03e081cd0a1ea7395246cc890735268f189f21c143e5f5cec76692e6d937faac7af3abc5480464f8b077c9352b14a22dc65514caf392d1ec6c81d96c33175f5832ab3bc19c54229f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = pass +expected_ciphertext = 02367918fa87d1732fa29e978c06713a66cfa5e50a7ed5644a3da67a89651567ecffc9bb1f79e1bf0f30091bf08256384f45f32e420a8a45bda4305bb231ae0f5ad834ee9ebb6f77b5ec136671eacb9054b02314866433f3c8bcf74a6be5dff9c968b9c167cbed7b843de055b7a7ac6fd2772eb79d66a34d08c9e811fb5d860d1d41c3195d02a731f0c5a0887547f980e7f02d5f90295f3916cfda43ddb1d66d66e486b5c6e27701cb1b749a1f30a7eca93e812dd462cc998e368f3d951d04fb09dd4eb78b43766d5c68abb4ef48d8d67bfcd404ff8b717dae7f2bb9a15912dc6d6670213af09db6aeccce8fe6b9943422c919222461001e5a068cbc250b9b3a67be2db1bdc169057719ad03b9f687bac14f406400f39cf8e6bd05465e632ca5f1e176af32d089746b31d9a95485b6ec3e360d6fca07ee469ece642fba8c325b81c6b70c71d5e2c8e4b8a35749c463e87d99e6746022e88eee7f0c27258bfd2ecde268c37625eb6c44c40a89ded03bbce4c055d21f727efe0a6bd1bbe15ac2a011ebee84cb8f18c6932d7fd687018f23532e0942af1422b634478de271a852ec157f9b5547641bd52123cb12453c4f14498fa423d797768b58d311818d68aee9282f8bbe43e010ab36e7132400838ff27266cddd2ca36b7acc576c1874556ef291b05a0d61cec2e56d9f1881907c3885e2133a999c064677ad323608645b7a5f8aeecbcec9086fd644e02b03c0dad7c2407dcc935a640a4bef943ca2b0caf4aab51d958a6b0ddc1f557e43089ccd669650b5e3039c9c100fb604c0d1cff6651b193b98fa04735223128ce84e1f6ea5010d9deee37af5d4a1884e2483c2c7019521e2e38179ed008530e339b26fecfdbb271fd4b8f5211130a7846e753ca108c15a938ae3cdaa85b82e2318a85d26f2849c6312a0649b2751d175c68c9021a839a70e11d947f5d4576ec6e5a1ef9ac9467e323bf751b60e0adde97b9bcc54668f6f579608e81491d9ea45129d83186e14a533c825cd01d8480e4bff0ac9a5b4f8171a6aa5acfa09b8518500e42b30d27f9f79e1f131391ef5477099534c28e1a80e3f50d1019fa671179765cc8d3e40a4572b27447f37dfc5950321c20512fcba0de91baf9eec84c914572334e3fbbe13f96455477110ff515a01aa51cd94039966f6930a90b80795d9ebd4a5fb9ab59ec285112d8bcf9a4d4b2cd3892cfa7231875319f00d36a5b274da937cc2744b8651565d3018a5ceb5286f814ecc734a3e2d86832f531482d3cfcaa850e573f6311b05d58a86cb38feec0d357acdc1de40cd909322568d72bb78b72091f99197b341e6274fc7834c7830a7e981957f030e8df6cd94994564352273a3d054b1ea8b4c8139e677490fd95ebe56544d2c6ddf83bf99ee3cd2edebcc1b068ab2d4cff003a8ee54532fab9bad522d0180d0a4908969af1086b749b892d0872f86068e06b414f4e4a68fbec43ee1cb97fc288590f9451cfc0863c7ba58007a6e773fd54c2d5e5a7f324a272bcf8668a399a51660839442674385c6192f1c805c7b3331a0328349c7e786c30fbf436fa209bd79e7beae00bc01cf2db5c4b54372c70503e32b3b473b44b0e71e480672641dc03427cf4f31f047542f2cf9cbb9c7e011d6e73a112a16d1be72a31191d0fa7aa8246995a1128750bb1e0a27384590a71c1db3eae7720989f09e1c085aca876b75185e562f33dd26fd4a0e41495bd24e7e7c40f5a0d013b403da4b75f212db1c8fc9d93ccd9b9f6dc6f9cf48ce83784e21e622a62eacda50ef89c11fdbf7522d11532ec6e0fc7ef0c8fcf97c859be5fb79080aa9a980c787b65e37b2c29820978632289d026fedf0ac6cd0f7f3774cf36cfe60b6f86bc87a339c2c8b32e372165959177395208942d1c37289ce83e3dd3c5cb29a600f49479daa034bb728d076fffd4c5507edb4c5d4e1c67412042952611c3cea42478081ae3fc011ec89c964d22db22be0f369b15880a18a703aa9072b6b4c041d35393c953b3237e8c7f86e1f650640b1a03863281b28350a21e7969fd6f374c9560c36a62c708c8d1986d511cf89dd38bea10df48824b037b513d3ec44cc89b1939671ac0b3e0159a703f4a6ebb3ca7c5f48ea8d3080d337fbc9491b4accb5ea5f64897ddc966cfe585abdd47022afab5dbe39e7cd6e36443e98f108059c29b3f1fdf83e53a186b53f608869ba31 +expected_shared_secret = f6fec6f62257d9a7041f119fff60f734c928e945fe131bf70338f273c0614ae9 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = d3539de5422f470189bd6c462361c8105549370a09e8ccc407908a4e433813f73e3ae465cf99af30105e6e4456b899777236466f05bd36a05494b347457439cc9ac66557580ef049071c7922f3770b4220063139a607c8019b52708976d184949cd88714f18130f0a6c91ca38680863eb9be2542a4b27a629dec949e552d8b3c86883211ec341b637555c70a8fa503412a771853d32cf1a5939fd7b6eb012b26e414b14710a4639096025a95fb8cb581358379330999cb6b93527ceb079b134021c19c9122640f90c11c234f808ccbe17b3e031b1a7a94654f82289e2755ae38b9fcd477afe576bad2218ce692b51205f61a59e644808c011c0ee0ac36a050a4c158edc9c770444d310097235890f2d630f85c0ded24443462906fb84d7cac3e7c1777d08a57a689302e99a3d9302faa4c0dec854d4872579365bdd1645706c744fa5a167b563accd8097e8c626ae63c8280663a382c11ba8f6c1b95ff1161c3b5679ec6c661c2b8081c1c39f6c732dc97bbdbbacb133006a7c94de933aa19156811a224829769637a54b9512d8a4e82071af50a66ab52301241bc5206bab6bc0b29776a4b630e59e72988c4c7fd83912499175a2a3d3a2270edf3a2977049bac7524cd69691f59442db348243881e04b8e9f1adb4a436555c52f2f729c345ab278011cde73521172e8fbb5509746ae871cf0e72416c2482a280c348862b313c9686d37ff0d73a1e216ffcd936d2941fb5bc77a9b0b771354fed30ca16121514541b5124386b835c22540ee2f9b5970c1508e41dee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfbd05acf507686d53257c372dc8279e89669284c76294aa3098462efda8c743b0b7305bde0693d98048412907b2d2b27892397b9f3cd31dbaf9446598dc886a4e1bf0f9c39e9faa3aca90ae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd1150cbdfa3609708e4de5365013c819fbade55636f2a311d7a2b2ef7b250632774ff22ef2e76029569346266e70bbc82ec09533f8caf60c4356d1023b4b4532f7c1e5da18f4582d40b8861166885f52c0db58357e7579c7516f9da7046d3092303219f327ab52a28cb6a246b5016fa6894599d9725fc3c2af262b53a4592f881f2a195d5ae75bcd36c30d6b7646424c219302c4e5794057782e7034eec6c488395710c8211ef954f9f7434265590862b2219045b1336af22889abbb4639ba0758e28f2378cd1b1a4225b4171c53691a9cc5986a6c3ff51ff53b4ffe3c4eb8585006c8667bc17b3a28c67439ac5f3c08a6e93a926aaf515c24f8a7c3e3b2ab2f5183def46f8ac996e400acc320b49254042ac43c7cb160ff32ca605438d7124b5a727099f48008d60ea2e63f5bf9b81e3183e1647251017e82827620070c96a32fe122632c4aae1590623ac191bac113e9c3676ee645fb762b0ff982e416ca2aa343f607a70405720e9c42ffd815be984042b37d5f76646db400da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca541169058521c28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceebf916a882b66752a7a6e96dce612ef5754c392207b5b1c69d362134aab5513ca757aab9cfc94db5302510101a73b7cfeaf7a0f1d259893c76d9111652a4ac02348c285b94f16c671fe953e1bb0ca222a3ad751096a1a05bb2789c0c14da099e75477ed038849dbb19de489fab582910bc70a3a80c6f76152d494fa067186958191a5101051b6d55449dc5a4434925ca9f610ba498a24b232ac6aa08cf477a99f5a223067aa4c91a7749b834c90d6e247653c6b6db65c5efa72f3cd9cce1510437268cf92753db242742e042def3019f85188db7573a43830abab80d4c176ad551c5c5216870276160aa61b92863c1725083a56df800735c5428b28adc49b75da02bf120996be7ccf9e20d43dba59b6900bb50456d6589cb2c0209e51258336034566ae1bccfc1fb314afab759b00e103c0a7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d63661ad0651d0f3286d3f055d1a307aa7371ae1a74f1a68d57a7438e4b5107bc0dcd8c4de5736adfe3170f8a1f01535a3772229da4386b4acc072c1611b53c899352b5ab5b39bb9cd4ec72e622c946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = pass +expected_ciphertext = 2a70bae622394c84f44a5b2e1118aa28f3583729e7e606575297aed9041b31dbd14dd2e8ce797923821c525a9b9ad87a39e411c20f4b4a98066e149c3baeea96d67d3ab839a7479b4bba6fc0b3e6da970b38fc057552665d129d26c4c3c1b8c4e7785c09822cdabefdf7a4f8fdd955aa35ead1e414d452c080b64d793a9f658e307339a18fd1881848c4b0a92fe4ec4b1c397b32f2c8ad5bef07d9bdb1f1366185f2065b497a8357167e9e91de6cb9cbea36737a1e3fdef09367a6c95fe23144017ccc6eb5b9981ab6a936fec5a2496584a196872a5e1c4acc1a50a8ab3dd714006a7314ca2250c1b2411c7b8cd552d99731eb84b321e421909c1e7ab9d1a61b1af37b9472edef61c6848305a8b6bbc0958677e1c0bb79122d2994c72616b4df68376924c1484e9ee20c65be4446776ab72b0422ca4f3cf5bec0c9c550de418edce654051221383923030c022b476cc3d95bec28fefa128350843ef7cc6a442cd76ba6fda38bb25a909ede689290887b73ec02ce5d1bb4253526fd4f7930ad4ce36f09f0257e6286cc4bffad656c9826a2cad7797c17bbce5c552442db8fafb01935b973076dab3e271835740d59c8663b44f1cbb3772f2fcd5197c52418bc4be1b928f68008e5671a753d335b202779a4e5ab3f8276422ed23fdc249a5c0923f6dc1d4d72ad6cdf270bf19539ac9001d3acea44a90a7d556bbddaf2aefcebe3e73a09d7882e74933e23b15b7d00a71b8ba1f77f32ccdb4950ce9b914d75e7184ef6fee73d9201e69c2acf0104b05b18e6b7068761992d333e51af8d7685246000f63fc5221679aa58e8f375b1c420b136e4cfe5aea6dab98f81892ad11181482378faec81805438ed4ca497b7c02bccd5320bcdeb94413f3a88a457890b7ae6b4879c091eaf8709112dc39a14ef0123040cecdd8a50a2538fd6cb1890b23300521b0fcef1150b1e53d8ce256e0b89f51ee6940aa6f9c4d3ee6aa2ba413747662ac01b35ca6b976df28147e1c4ad7b7b958f0ba86e092d71a100ec0060e9a5744127520f4995d6d0caa87786e2d44cb0d77789646c4a76c1f470fc4d18eed0cf365278025ac73f971b441011bf76dec7521aed395255cac3f03583b0d37fc206eef2370f8a13986c98660443a10a8cc56d7b905a46ec6cdddece9aecedbddfabf86362c3a2a4eea97d990e8938167eec639f90f7135c98cdff4fcba60176ea48bb15db19b8d6ed38edd8a7789ca9502c80f6fa1bd08707fe9b51f8110593c8203e305949ac9672f342151832fc890b86961ba408f1d82c051f7ca3e585d8dee88a429d44de29d93ee55a4bd9fd674ba1ad67534f0de5f9aa9c828b8128ba2f0b74724689264119cc8ce9a0431810a09422ac44904f6ca01e12fb0a10a39bd657dbe2045433822bc60f64960b83ab813720c120eaf14c76a58d04c2402785aa1833d885ead1dbc594cd0d110faf736f70852f76df0d1c877062bdf012c818b01b70a3b73dd3fb9634c724a137570c25a006b6a9eddb3ff7b91635bd5b734785c47a1c24092eb5bc480510784d8841da2d86087c2edea18e51c75af631c71a7130c40a999caf5c6235aa52accba8d650a282dc75a89d83e5402556020acd43141a07ac36bf8b754ae3a2b7e64565d361944555cab87ff26ae58a2cb7f3b29555df9cf983d290d448982e9a044073468484108012eb0a5e3e68b17271ea99706c5dc8b3dc364cc3eea2313b88ca5b7389be2c8a174e7a405a64a6655a67b7b4ea81a5e767244a5a63d45222ec03b0c3cc451599de35dd3167d5e0080d7bbeb0fa6077e6f5c4143fc083bd8dc4b029274fb87ce5eb13a79daf68d55c5bc2966ed34d13fb45a729d1483a186dd8061733ed71c6f6d7ae76607ecdbbc80b16520b08aca914f3fc5585fc8b0645efcecae66ff36dbf2ea87f9ebdbb591e56fcaeae56bf25d11448f5736fcdfdce09568b6ff335aa886c6256e518f39edf134f03f4a73876a43628f2b1697c04e4249684b6e6ae3f706dd1f7ad0c62ffd7e9eb7a12824a3b1854dea79050d5e647956f6e3a3e2871fac0f78d219cb40cd11bea041566c1cdbe9bbca5c4ee57115637380c9b82bcf938abe19af0a1a93b272e3892ed9d38a12eca97089720d05c3ca17fddba22d1432aaf02d63a7f804c7d2ba373b643faafa7c249a7a6078d95e770ffe1515cfafe746b0d649d28cbd54680bdcf468960 +expected_shared_secret = 9c56f6d91af6741ac13f241f8c960433c0ed4adcc86130877ecc1dbc10573bc5 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = c675bab636ac40ecb18567a8e6fbc63a52327520bb770a5d64349817a13cd365c96741726aa9107e9a4c04796dbe92061697131e728104c9c6ada26ebfc51632898564d89b2919438ca1308c53387604c162a424afaa2af9ab0c42b50cc50b3318a15738057c2f1806017a7bac76ba523acc1c66111d45c253ab299463cfce584ece769707a6b35d6114a8b92939a16d27a7be7f72b660f0b851e4950c20b33c074d307c8fc9b51454e41a96a8ac76cc30a568b4bc442177e7748e4b0f7d31201569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2bf23a19a5740fc9b9bf18859efc79f9e9178bb542823a4fef94be8ca589abf740d7880380e78853708cb9220e5d0ace428c58a543acffd8333d2831857c3784090e3696a3b011683899ae31b40513e9589467a3cf2891439871a1b240fea31f2fb89956d9966ca204a598050beb2c36f9a6851820c87a5262a9cff23b1e7bdcc9d060484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ec103864b75ab25a013d7c183955884bd01c4f58cd410344396358bd6901a94228275c79a289b385c788884b2bd3371d0852b0ac4a24107a87f1da0e6fbbbbd0a25c9cb14b7f25b7432c8148a0c91f8c7616c7bee7119a8f9aa4da5291a820922ea68f2bd62c4300cab4d10a73db255b1aa33d523d774aba41fc5f26326220c8b3575520788c0476bb3462f73c61016c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a93001a8c4c539f576c735068661c02026bb22ce5932bcab118827107a784ce94c2c89444a7b03a2386772d89106b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f502042c388292394a4940c0470458726b76f39037e10821fb56b3e4f38c752f4278b8b1fc332a48da56cae9c56bd03343659b4abc262fee6855875ac2b8aabe02a352919ba6363c6e75a8358d3297386240aa80f0aa33b1a79cae3c9ce40f87520ac713bfc2dc9da6c5b2bab6443383279bc9f3433e4080c7bd5bf22306e4fba2a8ff0a1f7978bc6a7bb809664783c36ac81445d4964c8ec6e9616384c60636f6ac08aa1c23d182fe70034ff2390442190f8c2cd68c9892bb0a6fb29c5e3480697145b150675992137c5a16c507c96180a3129417d9e30815e30b90d05835b890cec789e3ec8ab7dec509919cfd670241250822c539fa2ca8d9d619e22f050744727bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb569147804112a0046e2149903fb5ae0e56a4ec2b44397973441394175bb675c3198800e1bc56185ca7076345ac1623ac0ac1f10f099fcf971feacb965482a2bfc585bf30647d90f7ba27cd76891ef5b3ef84b988f2a407f5552be77559d026e385627baea2debf3ae73e3cd1461b1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526cc2fdc6c7a39da80278182347a3330fa332e071d8f31321bf32f4507b16e328fa7892758f2948a1a951506222833c0bb68140495a7a5e942c6b17e674733ce754eab747e96d2a077e7024df77388b6bdb807744db74612a8c72011be7d8b0949c75cd1b6107c2422e30c1e577b3515556a10c1ba712aca7f6988b3873705257cee724acf431ca0f9961db020ebc784e4f27c6fbc062857015db28d64004cb41bb7ea3b5657e6b65200b3959c642b213dda13a1b25377c4a47c43dc2dccf3607aa02ca28a4067095f541b359e21b39004590ebba6d6db8fa461a1343b824d1373f872343e8bb605729b674c66f7e5c76b536539f06f919213cc14756ffacd5789a46e7c8ad789ba0f6237998487c1912e86b087c9388d3a6a9c18d505fbba2f7aa6168508b1c8702a2fc167f2202ac21ba862917f6d78971aa7296ce1306d2a1f2f06b8a3a214ed45765f6a05a7445cdea385ce7922e8006b549319cb38904f38a6f932304037c4fceb9647fb7ff9e9aff5dcc951aa3e4bf50c296b71259650b5047c94ea2696837e26aa1d18938851198928db1ea22758c6cac0906a995a022998a7a942626c2cec7a5fe83948d74509c61915819425120d9e6580c0a3776ad41a95b52b2e867b6d7242ccf281a241a88049058d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = pass +expected_ciphertext = 93b854ae8690e56ce1149ad776eb9b8b29ba124398429b24cdaad3596c9d2889d1166d4604443441b5a77a71cf4ad72651365263f38ec232de2bd664bdc01ba969a557c8eeb6888b4b1272035f34532290967a0ed6ddf04ef083e6e525279120bd02a8da8515ed4b420c9dfeabc5bd0d73da26b8afe062ab3a5279f1069ade2d6284c8df2cee06855eb4b94e03b5ae91a5ec345300f3750ffd02ae558e9ca00ec2bd11066ba7827d26063146f1d1b246cd3c1342b51e2e98e0a06faae93b462046b1e29c0b9b525a229395889bad0dfe46b6a6d3aef00786447a5dfa1b2f1a0fa8cfefade49bc28b76207790ea62a8c2f9dcd37a6884e5109288f6196fa83486bf89b5fc82875c3ca187440e4a53d6b0746be742410d5e4d9a91df391499482db0ce46048667f30d5902e4399a8815d52d4295321e53e68480ab1bc24c3a281544e0d68ffda5ffa7b0d770a6faac834815819558507fff7704d84d5f694385d5a480aee1a0396c31764356d7a034eada7e816d3b86f44f6d1bfa95a876939bdb77c100c9d06f2fa29a8a4c67b61ecefece063376bfdac2bfcfc9ac94778a87ede84dd299e685862a6ee3e435917a25dc763d6ce9b4fc19e415b3dda2f90d9d1e559d146f6a3d822e21f90d2bd6a4c196c7080703a54391f61ca2140ccea20cd143692845b20a78ad5a4b0403f373ad9085e5b3abb2776b684a4f9bd3dd78a1835cf257b106b6682f4d86ad0627ed0a3e69222c9809f2740ce3aa16c4fb39486d399520a529791c1fa90e069da5ec030f726093a527e51455060499f38ebcd797449cf3ad21186a1de8d63cd9fb3db22a8823292a262347fc6b5f9264a8b907237dad3da30079d64375e48208aca9f2a5953a4763a2006f4070b796ae75e7052557d682f04e7f6ba51454c19364697c279eef3c421c4d478e4f8c654ebf9d1bc2f4aacdc19b9f71f87e3ca7c2147813e64243e515a180286f23d4f3032b8b31aa35dbeb1922bafd81f72ddc3a78745eca243bb56df728d5ce2556b985217ed7862ddcc915b9fa6fcf42992923a14447b8c4f11781df1f88798e8b5b170b4c2fa86a758208ed7f46d13ec64a2e9bbe0edb79993e845b418aa402333179c476ab9f22cbaadc31d318fd6de048807676d8aa8dbb7615300b871e84757e1a69498d0a26872aaf537b1423fcca7aa9ee79da9f5111d1e239dc8944212b05216c62a18fc3bc7707313aa8a4c05877f09c8f167195d8edd787ee4447f57ff08f470b33c4bda786e4457d43f50df69ba500905f4b69d1f0e8b98ff1db00d8d0ee4a40958bd4b0df837fa44abb3e2fa236f1fa05bec38f1c6d9467eba4e2067decd56a11bf275e07fe74db3a79642ee2a0b2d658c34748b6bc54e2bf6814407f500e5517b1e162c2ecda4201eb544bcbc816f39246b0bd63f100332b4b78d3c3c262a5610da4ffd95f4da34d9f76d967888beee5857c1c7a44ce001a782c1e41587271b11e68c1e6bd84487275c7d89bda052b67c567d7545899460701242d70a998c2ec9db6be579bee739bd755b9f7b94988173958ea9943131a0292aa6db7fce96c361f9b4d82b84402f67693dcb166ae5e8eb7e1ccf88c755fdc071ff0acff6d74190b424c7c2ee899bbe904d1a367bb284e5df91b1c9ce68513d3d5d2940a261d8e0c3d86872a02f4b7f3e37af66508df837326feb6da4355d5158db2f96f52663f437b20b851f9db9d11f8ecfbf9e5bc429526edc29a7d9e0fc32106db843f75313cb5299021d193d4e0ebdad08be7f8d4ceca944a3b90f670a51ec5fbaa6c3b811514243945dae6223cba1650bad5443f19683c387674e23195ec1422367b7df591667d7aca7836efccaffd4c4d01ecdf8eb2e49ef55e256dafaf56d0c193373d33c4ab9af7aa564b92cd1dc7168b4aa58252aef2b35db657b97c84b0a7af5a158de9047368749e653571246899a9900c53bf8a8160143e052006471446f6c26cd6ccaf3bd92121654c19a8279ac459a36de93114bcf7bb3db544d3e1a17f60a998f6647ed0ecdc687161bc5481c7314d761a08d01e7a91fb4dfaaac857c0bda1a55dfa861d332822676cfe751bb60ea2e29febc238a96eb2f014c524bd8d5f4ddc21ced5a68f1d5f658821c85520d749d5fe7c1cdbb97c761bda8546a47507719a1e62fe1a25d24147bb2bd90bf23d3b68649c852b24dc99e7f2a1776ead4fb011 +expected_shared_secret = 021b7e80dfd1258695b61aac785b0134ed6e9864d3cdf5ebd4b3ffdd9a5bbf06 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = 10089c89021be2da6c17ea926bf636c042c59a1b79941c248dd3079f623095437766139de109c3346147d1f8a069b2316ed2606ca1454e364e9c43a80b0bae79f005e0ec3e006d1adab7bf69fa5b098166aa9520de263e25a36436d3a9783b96a763c9321727eb65a7207b51d526c6182c1d51372316cc0ddd946077a81f6487b34d68b59841ce41e779885027912c5d6271adeaccc07ddba319700694f927a374b794584de181b890f651043a1b391a7956477b436307dc8b0d0467bc05206074d17f560160774a8477509bf5a936811bb9acc179834a9d1106af0438148d076e4c3a7c70d7231dd475f06778eca68e40210859b092915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91c82028eb18d99556abec2cf3aab979d125c137b75586b4d419758ff68229870869be755950100f9c2bf6d706cb9bbc5289489df8acf49046ea3d27fe7f0cf0e148286970010151a11b879f9035351ab10a536b6a3144a806b8fac1389f58b0395fc7ab90436b440bc9e66ae3c73a5e8e5ad59662286fa9a03e62c5eb100c9b63dccc74793080ce967b7d162438a492ca2815f56950d02aab7f12254d75c499840c5d662c0c10185b4ba3f84a91b37745d1ebac3a2440dd899619706756ad70468e1515d4c0a765942dd5a84af8a894cab90a724a95481285a160102eaa39591ad4e2c871a160be835012705598ee166bf2622bae3acaab37d4fda18997212b831b9b043082ef2b7b86423bdc15d2be82687c35e12c85fce726f340634c1107df0f50f3253764fe4cf0d294d27f28674f94ad16b7d03f91fa62a42ba154e35496e9b2aa884ab27b5332514c377f78a2fb5e7ad85d643ee94763095b2f2616bf87439c22a26c46287125bc7bac3aab30b1aeacccd25532b326983a37a623f0a2df3d7cb732124f89c37ec1881f2c5993667339d825b68908cc7923d02c55e7f967d3d3b8d01ac87128b85c465b285d60869290a78b40d48d9c39e92c298b313eab8a8b1607b6da8c22967ada0294696988d5d251ea0565c84571914156feb5820e5ea145f411f5ff64b587a99b88cb08ff4270cc89573d901cdd5624c0a2c3a654b99a0bf602acfdd15c06d69077aea18e73ca0c2e650751a68b659a568c2742b626d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1e12041e056ba02bce42d9ca15f5a241db89e2510469762690d270d1e16cfcb92f715975f68b44e75bcb98e521a5c2be1e4a2e5ef07bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fbd00ee503966c8118a1993910c6ad99511da8216431b26aa7b09a5f304201acba84670714c410e21a2d4517a0a1f139304a6fe9c63371f65d43b095b16040af3ccc487840cc41a63bbb6e2dc49731013ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef33b176f31104a3185dfa62404dc4a771877fb94656d15c43142bbda1417a7c69996681a0c69b2d7395e694c4ade0a5886d28f207722855a30273c91e2c19a2b40b62a554f1ef9c282b51015504c4b84714a99a3ef33504429976c2c036a9782b0f2be79924d98700d6c066015b10c03db90844b7d4ffc14b49ccd5680b1c1d9c15ca935404737093c20a05461c45abcb81c6a19b3a0abc168356882b8ec3549836faaf354d3b60d1a5290a883ab1e19b9493c26113b3d03b8c3fec053bbd14b4be12c80ac412b6bc1328a4fa5f1a3f46bc4bc685c7da98533422aa2a8c9822237f62c969ce064ea0402cc656a88c39ddf221e3d6a52ecd38f160a3f71c281a02a24beebbb1c6c9025dcc51447a7f5679fb0e382854a29d8088b5fa11c59c439eef92f869c4fc8b66ac7656c385c0983b07aa98a71abd2b576212fbbd14b96b19559a6cfe5dc1f3549436a4263bd9b8a185740b4eb16e09184dfbb07ffb7266c275438e13208e4a2888b63fcca6cd8b5abbc14769bd61a74f34627b896f1e85c03202f4d58932c183d7cb4a5548cc540a32aa9c558e9889e10d706a809aca75218740bb6c39761bcb0bb0c76725eb80bd5a46d074864dda334359b4d4dbc7c8da2b413dc20a1201ae9e7acb49c905145307ccc92fba03c02045c9632564b68cdc1e9527b239c1f9a7f72358949b2ac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = pass +expected_ciphertext = 40d176c0e576da5380547cd5e1cfdac9329cbe7dc473025481d612401a1f28901dc2856fbbf214385cd2a655d9ae8773f2dab66e1416881fb8d11db2d6a93ff00701db7bf4c28328debef84c4134698deb97339a66d5e046068bf25105c1fcacc439bca718e9a1bc570d075252121cd388834f074a27f2e4a01fb131b278599c9305357ff2f1efdbdbe37564b324b9646903ea90836f2e2ed93e91bf0b9d045ff2f119c0cfcd69366cceded4cb040a656d203b04e689736373a9a4a3062999c3999484aa11bd24f87f588423e98c0f34c0c522f4eb58fdca72a4e108678fb3116ecd60c5cd6c38936e02729241e4da1553005dd9c6b192338c9894b14aaa57c9196c28b2cef0e909cd02d6d7d5348dd409136cdf9fb9edc128f38c9491aa3b2bf75659f225c639d1e7ec179339a142188db6ee3d251965ff232ae26a1a9af7a19063c4c37fd60bb4c3f76890588a54d321e3d21f0c5c879418ce6cd3b1ddfbf83992b3b860c8756be4db101a395d9025e7aa7fbbad94ea3bc4dfdb5628ffabc684f90e9037b57f97c8730a4a8ff8353feb31ae5f3536f9a64c2cec9e25b666351f4462248c2f84b0cf89c2b2238fea1a658bd903445525f227a849f41f58f7deb9125aa3c1bcec584a17f45998e3a5c1df02d064ed19b8d3c455e2f244fd0e683fcf9a929681fe880aedd218cc3079bbab5f1731c58da5a00c78c512da63b4f2fc527c0aa7963df97f3d461a0129c7d76e20b7516d1b83eb388079d497cfe5834e30a6e336c8c45b214b360a089f4a63473ec691555276a5d1eb62e07b06ce36474bdb7ddf21a5caeac5ecddf648a7e6a862bac72d0cbc69f1e9361829b1657cf0379b05bb1630a1ea67a1a3f1079dc729c8eaefc5d77895e2746deb079e56982f9cabb21e225459c7d2ae76b112e14a0db49a55ca1c353eebe6947511f8509d1b99a86ad8f38f58107f8605b47e287397b97205d215ad9ee840a95a2c6da24b9f4305bd734759f5bc6bb006253fbba9d6695da96d77b1c6c5d2e6e7228ac9c83dbe16a095feb2895d2142251985e9d38c0ad583a80c99d453d2eab117e10cb3a91a621936569976c69e452075465f3fa7ba041c112944186a6e9f0862597ca2cfb443f6f55d2c8d4a622780c4ad9e9cdb909756cd702e51d8a4d96b08d62aa2579a9b8d20228db525667659f4ce676c590e6a86a4d8a457e9994377df22f9ac3d4336495b7fafa0e06d58673d70971ff3ff8c436cf17e839b26087b01544070cb8490c2a88c2d2e01fabe854d58aa3fc066e5a036acae3a7bf9d2c02104719314e97eab17d95dc4421e002bd15f4dc0f1860c7ba32f0188a9d333f1e9b5092e1c01f952ed02fa3a8fa18d3113d4f7fb1b58626cd2008da96b45f7cf00a22d4acdb1234661687bffa52491e25bccaca2d00d21b0148e13f3259f956fdbdccb7fb16d0780d9fcc0bbfb39e00dcffce4bfd9d916314b5d159880bc791d3836c7cc0fbd461375e35bcf259908a40da82d6f3d1a0f2e26fe78e4ec4882be39c2a2d97aa9e63d2ad6b98e56fa1e593a844f2d8907b0996d7aeecc4f87809c7730a3b6a21eb9f0a4f7f31d7af2d71462c8dd97079a686e7abeeb5912a9068d766af158d7c38d80706a439308af945feb81936571983d6947ce5891b32ef7f3a9d71e4cc2ac133d004d5ded7a0cc29303aa207a233d9ea745afbf718138ccf8a15d5fa39c6a2070a53c92221cd0cbf6b878dcaf7268a68fade731da0574998728ea63477ee99320ed00a8f239b8f4e85f7ff6c7266cf9a3ccd14cd6b9cb616e6195afef1d38f8f2d0d9779c4188e60485ff8f24d8a7a10accefb99b3d6ac7ffeee11ba0fd40190c672b84434eeea7e9a56047a3d0b983b0f834b8a7af34de7cd853d0282508bfcd0b52964d3020f27d3d137a1c3c31a281e5a4045c9da040188d5c59c96eb855f92afd4fe53fb546406c063df50e13643cc49d12c86d33d936c8818a3c84acc10b677850d3a6150089281c92cafe51024a03b4ae6071f2db11de2be9ad3068bd94ddf1d42782f318124967087f486c0514560e68abbe5dd2d7ad0a65fe9b4ca3dc00c97ba2d5874596337a466eb6593feab2029fdc0f3a665bc93807a80fb83a62e635e380810ca78677bcc399b360ea0e7ec0c89be6efb84e3a6e104db94f715bbe80da3cf4151bed37cf1c3586c2b478ef2c536e15f7ee74fc2e1016 +expected_shared_secret = 2c876ef4c2bd6464c5e4274d5360e210ff389325c1da4bda5495294d7cd126be + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = f2810baed633638b1737b5ab13fcb47e181e6cb86c69301b77b85e2c64305f1584e370934a02aafdd27c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab9599544ff08a4a13643e181db6c752a8a5c948d010e8743ecc064ea034444f3a2b207bc3a0606600358907708bc87016261a61b1547bcc8421c009778ee31598d47a48d3a99e9a24ce230b9568cbf4bb61d9a0aa512b282e2506a51b0fe92507bb7cb044e93ca230b6d9f97cfcf31b9055c9775419684aab2609a1e11b2b354223c9761f7d6b5b02a16f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824c115c69510666308330901208d02f1a6057a0f5481af4956ea5281c956735d28e49173031b688a30289d385a7718c2c21c300d7ac3fc81bbfc6747c60f4cdb9c037c458c50dd1605ba167806a6fc32c759f2942dd81962ad657b51942b3fc8d925b9db72b1fd2b303c05043638a3217d1856d8b243018b0d8679db5c3364a85b78c913793e87855b382b3456d3d7c1c2b82bdb94c6e96732c6f455e4e631fd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be1b09430f2ce72482d6a8673a8d511a8a1c506a2cf4facaa9e489d6a3a5322410464d590d0f52b957b28937b543bd5a01f07261afc810d41bc815469e145862a3238bb194da838c642b817db611e18c08325502778922197e73aaa2c030869ca3ab06b22827feb4465ae60975a61255a405db1f112a2087218619bc9dc064035774306b14d4b6003949181301253034323f55bd0818097193d449a3ccd1315ee375c7efb833d03a87a881cb5dab7e0d045b6b80505cc18d8e9be1f1a7740d4981e31339503b1a2b22061d484d9368b8a5193d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e470999e90627014b34a7a8b168010ddb76f994783b5f41ebd60697198262cf42efc13128a45024386c78851c709389262d10d65c4784eb10c2cb13d9fe819cb4c6dc0c34da8c22b69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbe917b37292630518b093b98d39c6fe0138257467f93c76118ca748556003c05810e7cbe83c60f8791a72494889289716790242199262e44b356a98e38429733f07e4d2329da534fe8d4998872429793a6c4d14919d3adbda51c60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f11471d84064732b11d62d40633d67affe2bd75315c54321d3f515078b1cac4e1ba9fd529db1b92a47202c0e768b271826787bd6098a8854460d5da5d5744944887cbb1840125e2825393b64644b8c0b6cd9536be03d6c3e7e6ceb13b1901f1cec3456903f5b15e9994ed1207ff52915ff2460c098ef820a1e885c2ff231896a3c1dcd5ce49910b30927597d988808721cdb68f98914266919dcc46125278774d4c1861466a8197c4214493fad00f83808290dc6064a388633b0ffd2b1fdd84a6c3fc3576345d1a654f3b129fd6c2a6b95b46d235a9a7f44a6f9558af20a451a69c6f5c119712cc5ed91f91b946678520e7165ab4cc367d1ab985692f85e68a3b05c738319e0d7107f2f89710f32c7c047019f6cf29854bcda6b319288944e9907975083e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b964101aac6a016725c3903e5caa639614650c0e052673721b113f48d5cda5cce6b8a7449ba5308ab9f1c25c4c4335e2c4a3be318c99787fdd98f7b592d942617b4346fcc402df7a41043b0bd87c318757bb3878b60421ac5b2234863d2888984898d198d002035dc123091532371e444204ab05c8a9db00c4756135998369eb181882ab3c0c3d17189267f03d64af8b2c3addc90e32b3f44c43864615af5001b45c9677f59b8ce680edcec5088dc17865a790f593ab49bbe5327718a4b0a4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de04100878518c722d321740f4c4035a813a5b1c9cf081679e957b795a2771485874e5bf75f57b11f8ad9fe3b1d2d72a1bda04bb1517296193763776fae451b6615a8e9c788a5c8d65173bb9307b2cf9c863029553f56717b355843ab1dfe72cef8c46d6a8367ab70f83db71c4c410960a7b6221ae2ab64a17441f4b50adfa971f25c719dc8705926c6bad712cef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = pass +expected_ciphertext = 9dfa36f0d0157ec8952c2199d3b6fbf75e162d7abd5f697424597a9e6e272cae38c8353a8c98e4e318cb3ea35e45dc7dc65a964b13a318af75adede184d692b684270655c2fc3413d03d53dbe243e626e0f427b55c1b71aece27c08f5804e4d7608be6b6172d0d89dcfcde114381ea824091a43fcd55b2da0bc59a3aa7430a5f564884c71db9fbfd37892314e8ecf1f71057a94ac68580b82e9d8b5d957016ec3ee640eacfc497146fab1deef7e50100a4173b91db6b41c069e9e32e207a5664b4530a9fd17e8d2a0443b8b39d4615705b89ccdcf552e272db8216e9c5a04bd5da18fe4e5e574a6d8271be679638ede14e0926f0efb549edf47c23667310bde6c8f7b573022a1114dda342f8c043165e4d78d6b9b62a47629785acd03aa5a0b37d4f1ca00d9b3e1c7f32a30ba5f3fe80d339d80aaf508be370c9639753f45afcd7449d443f617c7285e6cf2ae9f5090423e47b3abfcd9feb78b58a6186a4bcacb67f5993e8d0aae8ff8d1745e44d769310d85ed5309a8a87a406200d55876f782adce8af5bccc071a520bf5728d21428776f3a03c6341323ffca12815be6434106a26e692a2f46e4cee37cbf4b28fc006d4386c3196330fd0a1dc02b8d6bb6eec71eec766f2e8862b5d91a20bfc6c2d133613eed0e39b228ffd73eae3330b71865e0afdd9596774cae2783c0e85375f5073675dc65f93b71478875f29f4644095ad735cf6c82a2fc10f5e4d2717d2de098d28ee335ec858eef9a39e64194cd07ecf7b818d5b6988b687cb7f1bc46b94e38a8035b9cbfc97c4bfffb0cfa03aa5beaf56a2a21edf2a73a7a8a49d7c72ff3c11ee42f92ac7bf769fc513de67c4095826535a2a520fdc2eab29f71fd7735e8bab1979c4068848d9bfcc2418d4b40e9122422c2edee659dd60b99721907cdba4e388140b886a7a814ede3590e7557d16310caa4209a0b6cec282c31b69371f5e088eaeb20f395dd1c2798b32bfd8739539f9a7cb74b8c926bfe01d563aa54506d4e8c0daa27a7ee7b5411c9295a814334b7aab656d96d05cb9150707ae678933b76afd957e6bb39655f24267ea364fa561d2f435c12882b191b295470501ad8c8db036fb92df81c6dd9ea9a61907eb587be79ccae152935d6865a86be4697ccdee31d890cd8d0f651f0aebbebd8e6840a2a609534cf295ab7838d705cd57acb0d7cfe30aa6fd4b48eee85974fc9123d5c085bb668c7bac8ff77899daf404c01ce991d14a2f23094e14c4540d5b0e60a541f4a0b50be31bf5039979c84277e2e34c7f07afcd9521510abef0fc8e3d5211e8edf03568f4439712e6653fddc949e0b4c5cef165dd5fb749128d5f1b0cdc0868dd49ab1d24d140bce4e1b73533141cc4a8419b0b0f4b27d1090dfeceb95cf13f8ff024c9d089128f313039f0ea12161656251b0710260b7893720059262c24797117f618a9a05a027cedffbde83a93bba0437204f3af49e831b2b1bacc3c17ce407d0f1935534dd341f45f502a6374b6225c89b3a096edfcd533d6e0dd8dceb2ba7a7132edf13b1a5c1f2f5b0b23ef49de8e9754485c59cf0aa3fb3ab5b473461d11baf3be9d0187ed7175b135c706535af6348f5dad15582fec850bc48724c7c4a0ca080ee98f502c23c2816caf7fc9a4950f0da7320b027831f856d8aa170e1de03f8994fbcff4bf1bc507acfe95196784b2421af9de36cfa6125e75392aa050a8235e2dd72c484e61c47bde72e20c23e3e70e9db972b54f7b5b16b2a610926bba71886b8ae046b371b096fe266840b644774991d279a2fe4d4a965f3e9e9934247077c787e54803979b0bc494b56b3b081523605d3d09be6a01037c2150e40e46f4865fa839ee58887176c3feea6dd4188e58224894ac2ac38d78adc2ff6d911b417d799f3638ae8ec6c3252045889b6c0d3004d2dffd71b1a1d49490aa92456b35fe08589e596052c845f63dc3622364c0fb1de74a2906cffa39c5b1029189aa6c3c0814edaebd4ae01355753e1fbf211ead32be62c906f2f1d8d894cbed74efb72e40b0971774837ebe05eb27bdc19a5825ea0b50b47df97058c4ad78670380db8101efdc3df6b372b1a6aedb47baa29abecf11e0be25ccc4a42505b7a70827eb74948ebb4b5be65ce07501288862d98ddc0c977c8e9ef0848f49ac26e0774707fd696035ad5fd14e5b68b420d7191212a7748e032fbeb5b98cec320 +expected_shared_secret = 909b047e7f0fac27df2787ae406fdd66893a98d98e38a9f5b67bb5c8431a77c4 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = fb70ab80405c4c59421f913a78e89f67767e71fa51431061746a74746b1fd544065788a7f880b9c81c007e6091e6118f3acc518bb06579b45ad1374404284b0f1c370c53062cb79a08015b4086626d3083ee7b427b24613947588f7149777a3fb5919c73d5a23ef5445f24aba79b94bfba774f71c84f929978c44e07a84bb9139b32fb97d4b20e363a2098838c6a3c51ad244b540b90020c5a0ce2b135918db1e9093a0cc43ab210d28a7889da51d88c7b3d1452d7879f34a130bb263f51429086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e56881b94376638f507e95809862b0897744d3d8658e33c89a7791b93acb17ddc91ccc5b71b01b9bca81a7485c5e4428538a3ba7f124d24864149b26d0f246e9aca34c76103d676cd7a54abae1c895c37b1784476180601a67a5d04996d195363c61864caf95e7d3b2f4ed68ca2db09d9d34f86d5666aecaa468587fe5a3c56434ff4815c61094c831699c5f1be9301299e3016b4cc602bb62a4f1c2f1af247b4fb92d4a10430e29f0a71c02df70e48e0ab79c0a31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114e62417d9bb054110d3284b3285110b7069fcc58e2e13cb50daaa0fc082b7c87eaf13063c6a966b4cc24334a7e6fb8c3131461756a35f2b9842811f233a6a7127a33b7cc559b477b491c0155949f9952ac9631c32451b3872967955c1235b61af676429c94e9034405be47ac5873c9dc33ed94828c9429dd7cc29d076871222893f207b0f3a8086d77c3d7792ba25ba8db46a554b161a30cca878ad6397974acb3812767a95a01f73ca80f1d83006e9460d2348c047ad60f2841db1bae58952142aa3491cc7dde58debbaa27621c7caf299f4325ee978caab6ccd4bd7510f318b20e98d26a94ee99c935629394e6b80a5614891a75b45d81eda8a6cf8d8b43d62ad9399369023c4d677ce75f14f84b05d01b7b021e15e459bc5c82cc9c4158ba32c5d50708ad9f620297333a4d899cc7a90c28740039b351345bc7b971aaaf39d97326553740238e569d4870bb09c66af75b532778b9b0a631d362d13d61567212e6ab523fd4c3ebd5839e4aa1421db5e06e33bec836876d8a8624c22fa56c43d4060a9e52f1c905ea8714d8436569d050c7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dc5242c5a58f0c8caedcac7c5256d8f3b40bf57b055616c24569a51c5bd712279827bb00d274d767156173c7ecb8766202376e9a7227517bc4488c029b9b6b2642858344bd14c8837ac908690312ff5a6de7bcb88f2cffd40a9fc666800f9ac54fac76ff5a42ff83b9d49233c841607aa348e2a5dcbc572d2a482f78b2cdf3ca4bbd22148c925276b6072d777d53081311a286f37ab14ba2000ad4cb82769dc889de981c969f732eda2717cc405cc276fc965ca2bcc80054c557c1343847bc6054157a5276432917501f88bef0b44521c0d5fa168dd89c9e34aca4df0a348e53eb5c939650a240879c0911a8e1ce371d7ea45e6f90b8db0520b115f826085ec25a108309466c11920984534c99dfbc7467af31d5f941784586bcc0347412c48d0927a4b95a22d98b49a1a20cc72272f09bb63aa194e4450c3bc2351ca6d2043a68ec30c705cc856b00f5054a66d3140bfbb47425a67eddbc4204944a1e379e1516e45216e12d06b2d522398a125728822ced62dacb220c845a444594b3b6977eea89e256878e52c766a86a3fd04437b4165242553fc747b80952769c10547804b80c1a6d85a29620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d7452a3e2c6a1f87c4efe1234bb9971a1026292c22c94449b7c8a2cb117b8175c7416284742120c11378c03256e4d2b80d502bc5ddc1d4e3c022bea80140307a3a214ba51c807db26f2536829a62400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34bb128bc0556fdc40ea9eb0b73193396d51c1bd533c4910b358969ba135f862b64dbda9608dc7665fc61ccd645f8926d1835adc34386cea20ffe3283f900a4ffb693a223755a50c4771379307242e4548ed4dcba4574410d409a4838233499a337859c64c6941d477f70bcb5a653bf571602e5224e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = pass +expected_ciphertext = 3f57ac87afe43d83fe09b407027bd7dea796a49fa78c01a16b064651ec669319f587597eeb52ea0c3139f2e478bcd671a12c09a419757140d489247281c02b0f39255fed4c1fb81c79497551541b22f23729bee988944c8b4771add0c0af47f9769502fdef1769bd4a280747b2f70022adff6d4cd868679441edadf0e5a9409b09b7ec9bbff46c69cb4ac3ae080830a9d98815950079aa0f889678c2befbe96ded187534fed04b6896fb5360537a8f714f3860c9716cc69bb4d5e30a43a2603c4dfca86ed7326d75f8252c90694b0f4562df8a6506dfb1990eedc5af4418694638ff90c9a8f9289831c3bdc7e352778d9057b467f0bb8d085ffa261ebf964720742939d80de8ad8d9608d93c124b2211a68c66e5803f3a29f4b0d2402716fb7f12a0b2d8b85f7bfe42fb0544714099d1745c7ec78a260fa8a9bb381b75a8a7df330268eded6ce8018a24fc8164be2fd923ea0816635cc0db8d00156cc1d3fd728346580fb99b36aed774209e9e19634e55e645948eb640be29c69076b8ac9f112864887d4bdc55a11650fd9723bc80b9c5e4e853ee34ad3780799cd4d1ff9766a1a70ec6ce7a214a2dde93473cb0bcbd59073be1f3943f2bb9cd79b3f422713f465a15db53c0dcc0ec3ca78bd27d491bc231fe03316041538194c9f6f3196ac721b8f432c0059cbdc53aea19025644b002b2d64f64923c0a09366454e54953edddb8ef2adaa6d6e02c99aa1fff571465f1f4c1ec6ff3839d46a27b99989438373469141fdb9481b8ec1d02c2919fd38779765efdc65de7d6754ff1ff3573d9739f5d7db2e7d831632704c96d8aff25af26f34d6d902dfb07d54aaaf3ae0a5a15e95fd69bea419fd487218048cc065dc8fd3ee69cc6ccb9f2222860247f8ebf7d1801c340dd412bc6629041571f8899fb0aeddc76a26dd091e6769dc129aaaf57f1bb12e38a8b0378f27eba1a360d5a9e50a279f32bfe036f36ab0a33f1fc22a18129a3ac0e45e3377eeb59836fe23fa0c74615d4c5bf6ac894125019c8f801d5f9a44dc00d1c4e6f29a92d3daa5d1b47415cc0df26a19007f179392caf4bbd6700a8e9229a858931e0f1314a705973d865140c583ed0b63a2ec8bcec92d5506470f8fb43ce902934280e24b32a1b365d984d9ea92dd2da2c91a21be2db4351107f1340a199370d5c431ac2681ca5ad88f2634b73fd96fc56dd69ae5c59c6eea3c4597fde8ae96c162a82497bbd35cbd3d51ed3fd09fdffa5e13cfd3798390f149302becbf108beb59a7ad4f21dda52c2fc5488b3cae185aad32372704616db7040e707f0aa801cdaf221ce94b3097acbc5bf11733be5db7211bf88d6f337dde4825b41d8b8c3797ea7b31de659e1b6dc33f1576e8ec6c7cc27a4b2e572df14715169fd2683560924ae674501da9aea875c177743a98767539681bbc043bd99a3ab8b78189460c0e2b4b2d2aa88f7187192f9be33afa5170db91b4a0b80ec1128ed5c1b25fb1ce6c9e41cc662cef6751c1d3a506441252b7ff5fbc886e4e573cfbc4b76c76514a64443371f7dbf959edb577a9d9b241f9d6422887f6bdaacb340add18fcccff5a89c7ba3b62d931a02d4bfc40a38e8964628d576f06819e04d2fb199d5d80ad0f618677e47c700477d74f65edbe882b4be41e25476a6ec9ece34324cea745b6561ea2d3c104e34a8830298736c8b654be3e3716d1c9235d3c6acaff4ac1ea87f9da0d07d09b179156666bb2e01973f3ffe0ef25d2920dda4e55b28d94ee46ce88b89a56c1067f4785b8f1369af3836a01542384661d54ffbed84ffae0c4e4bd1b6f1bafa08c97e0074ee93c6955012c611b3ac6b6b4abbffde55212c194400f1dd28df59a279dbb95c1a9f05d1400e1e357422a2ed4513e9bc97696f0ad239877e1523fca75196fae41c46af4df83cd30558dd5c45c0776ccfb7bd1813e97c26dd5775e3e223c0e09ba27d4dfd6108a2b730657d8bd41e7fc1f119531d5104c580ba6a015c5847110e181fba3ceb6b19c50bfd12aab3cd2e73d36e13089f274379fbe07a9c8e93cf5156faea35e50fdf008c8be6c9f7f502191f7898ca41baff0f61e1a561473e48b59e4dfffbe817ffbe3899ad97b8c4bc91d4f0daf68e3630bf7ee35fd95fdd5ed6f20e0fed9e38168722a581928e1bb4aaf406080ead269382c9b8c4901756f1869a2053d245d729a8d19e8a90fbb2aa2ce4 +expected_shared_secret = dff8310ce364ba5686b9d42a17922b8d5e9259a176e38d39687a5269455939f7 + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = 52dc3121b31062ca9d2d7599b62b942c221868e9030e52b016bb30bba71109ec9cf44930d76757d16452623010828925c340a8c2a7772fb71a09e1cd8cb73fe5c1a8428219b9f14eab47ccb13703ab2aac1bab159fc57b1ed434b5a00d5221c05ee77faebb4a05ea04d9c6abccdc5764e876305025e57b9e25473dbebab8bc207148f720f224b1a4887da3604e23321f17167b01d546b5074cb27bb5b6a365b91232ee7cb7f47102902285fef001e4914499da9e31eb1376e110b3bb06fbb350a054bd79e84113021bd1a1637be1a7d3057679b41f20fabf3d764c158457e7a967cd4440d4eb2c2d09808296c1d666784698115a83ce0840467449080e038b81f1c7743c7f71861d0a150c5867bb71db4ccf5c5a92955cd33812d3590b7b999708b38d6867b979650a73a63cc9fb9bf87653c5396ab8730e38201d3d493443369a7b424fc895cbfd96271445849c38ba8c9a969cbb70626698f12223e450c58cf5a384fc784914072ed92338f11693bcc2c48c201390144bd52584260a15bb48401baeef381affc95ac96033816c3414d03ee70ca8c947c7b9ba2052393d3ee9856cd52708ac02294c4cc58461b379a8b3b5c85396b4e90b678c9817c34b2ed2fc9e8bf346ebea1e6987b81e32b6fde7947a1772230257c0b1c564427b0951a451c11c6f2a7c27b6391c2b0581d19bad322038989c3540084132bdcd6368682927524149a4620326c7b968f6090ebca4b7da889b48723ad977bb76369d3b07873b5bead9cb08766702b90d16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7d0084f324bc15a0347ff2264bea0c88711364ea0dae46763a02c3a90b1655eb7d74a59d3687738f1c8b26e0929920089237a196d64a3ea58facd259c4d72e17721efb36c6aaa1572ea88d1171134fa331c43125eac801d1eaa9ef426efb2cbd6718a4be981ebd2375b73c91b7248ef21c6bf6b29a4c385ee899007e44a50af44ff7a4a973d933889241aeb90358f84943917441c7840d0348526b25ec3a15558562f107cf33540823788075931711c5133f8516bef21c8425088435405275b970c457abb73f696612b253221112a34376c3133164a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb3690ba32476f701c7af32575cbac0beeec43bcd8b54fe2c026d6c4b4fa150111bc58a8119c083a1a755e0e0c57be5c0929f64946015f8ac80c07a249eb68afff3388f205353327b484cbbfdf6236222867bdab6bb2fb4fda4260fa1b47bd47b43490cb11a9c3aca191dcab94080bbe8e394cb988ad474c122964739f05b5964070ddaa7a4bf2227e96498f7205e17b77d926695c3508f1105e4774126f014b61194436042c3c155e4a5134dc95583c189aba2bb29268c44e2b6b6d52b70198a4e193c0b4587ab18a0166c51365b05949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a048717b60c22d5b2a6cdfc4158d5747925731aa85bc66ec37d3384ffc7910ec5b4d2cb5442e25ac411112dd4b983b68a90bc57ddb122d73372794214e4e64a07ae676da990239498257149c299a193fa1cdeb371cc354bcde26c3238bae59230f4ccbc4614708fdc39ca5d916d80873908204b70391788cac2a346a1ac72a92673532bc9286455d7eb405c830beaca707fb865aa1d41315628ccec14d431434fff6350e518f3ea8422b44cea3b6b39910ba6b5265e8d18452f7119384244228a983c3aeb0b139a96830ae90b9c2e569fa885406c1270f1654cf69a34c2375f2bb537f39a61935af753cb6ef139317105c9f4b3dea094093d667396552b2b9562cfc0e9ea43c54f99430931f10bbcc0c81270ae352cbdc29658188e67a3de915469ae4263667665385381a352b48176539f59d4e2b19737309efe6c40a1a4d3f52a7fe47089ed22fb3b3c24531865beb47f823221c690b60586928ec5cb9505ac6b9c764b62b63273165f70e76034614ec354b38786feb660704a5de79b1d3399da5c8b1e0416af49c22d7a6982a338471cc88b18258f2f3b55bf51bebdcc53a7829e4c875f18127c7b5473f0252bfe4735c59388b305f3f106803c27c6bc3c51d38070f1561eac805070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = pass +expected_ciphertext = d8b74a1e62c0230105fabee0fe5352ab849ef211480ca818b64eecd888685317bc56a0c6bf0bc53df14f5af71bb0cfdf146ca07b11be69b9fe13743c2dfa2f5c2df130da68045ab3598e9c7cc0510f2f8d363c5624f62ba60344019436150dac29a7ffa21802a8a341847d99bc10cf989f71f2de3aafa7f20d49bd37d14b6d9aa90e09418de03ee3944aad45322fae41cd0acadfedb73597ff0d2cdfb86fa3ebfe8e13d8a5158cdedd760d144676e2b7a7f9fef5862b6466f8c421d4efcdd5f93c8ff86d4f42dde6fa0857973061f4ae50342af9d8f625481d7a0c191f3744d138cd7a11fd1b39059d6ef5c4d04864e97f96561e4e54797d2735db1e79419ef1c1aceebd7e0d8f126a54c9dbccffa70ecd2ad5a5c926af4371e2d3192393c549190747fc6f5aabbf12727c772227ee77576cb07ac9e5d058535222351a5d2a4a3fae8d7d30eba922fc75a89209511ce945a6cc55475afd954be547a0dd6063220ac58e188655402e5bfaeddc3b800cd6a4488da839892deb75504e84f550bed98047a84a57e597e8b6e1585e96c7b54e5c8427251a2c30b4b5790a976755cfd4e32968066fb4bd324f50ba744d8cbe9fb96c08c07663d37d08991bd36156701d60e7ad3f7281bc209b0ec79dec9b480a38500db888630b105de2143f8648618cbea5558f311e231944c5903ab4f61113fb95b80ea1d0f870ae521549fb4d201c70389079396e56e7bb2822241dfd9742738c62e30e2019d1ebcda1d720725c936b20837ee40774b702b8a851c8ce68f571e8e1420d05400c2016d4764b33efee8dee011726fb090449c8982d5b8f80a861f1befe0e553b3a9914cfab46ec458fc72bcf3ef2a6864e52308ae4754b7d7547b6d2bb16d8be6121b1af44284949624fda63d9573e56070e4b2a06ff84b4d009670e6270d307ee32a339d7255986c7885cc28a9af64c4231c3d85a8e1cd3c48d4cfee7424bed108b3ce5e962f5d29ba50a60c7da9e8583401d7a88d53f647aa4a0c48b2eb1b468ebcb1a2cc7903768e7d6e359114f3babe93c0070e26388ecf5d3d6bda5d8c0f3f57a58e26bf8b2667bad861b5d5d120c63271e4c0e6ffd0d6beb442126b1af8f5a97143d0051a48dd727ac65aeae019667d773b5f533fbc23e2dbe20f838b03a43e2ba0f60674e0b2798be3f375f2c6f6106d8566264f82924865ca6db0f5a5b3ccfc8836872eaf443020b1402ed8575db8458489c2e39d06fc3f071ea6578713c4ffd345669948b62fbe1ac4e747a68086a5c1c0d3bdf464d82715eeb6573178dce7c53ce94c340cd753f062425fa5431a670ec5af19434f0ca6f18638219a2edd4a6c1186261fffb0575e426a6587efc48d88ffe01e675d526ba18e49d794765bcc55dbade1ae3443ee61c9869ba7d5fcb21ae42162f37a047fa8ef2ccea32d1bc1f6d08c7a21bf443ba6550c04aa61b4277efcc78534bde2a0abc6633e304bfc39e6a19385708d0e08f245b77363bddd153087a6443fea3b2c586bbb7e2920e29e0b988d66d0f6b0325d058adac1a0f377dc4ed8d73a18580cbb133fdd00fafab4ba16d011d086eb5653e3aa9f3ebe53f88824b4c027587129ad990b0a78308bd101e191cf49174219bd0ede582af30e4242059e79d90058b01f693d56208771dd5cfad387bf3fd085053403a6a337d16456fe1344de38a830e9921bc1d66de1119a9926cb047d4adbb9d4a80158d17404538c5f7284f2469d6251352dcf693fae17b89613f37549a5612fbfe5366149794f5e334fd95ea233b87302960b67b0b3bfc41596c247135d4f95decd2bd82e92cc7f92f27186916ed9c6b26aaeaef313ef75aa2b5ffb10d509e276db55497dafafe9ab5ef4c57050f4270bc467ca004e1d5aeed5b8fe80168c4004b7c0826ca878ddb79d8ff337194b2602d90c89c63311268bf37e717f9faf7a0cf1fed7b42f922b32b010166e0998f1d07a207c41d2fede3df9f200ddc0e9bb59a95af738e0824893d8e2faeeabc45f8de103caee88df2a99d4b9f8e2ec6d45e8c74aced33438bc771b267c4eed7a1a1f5309ddc877591380ec9e6008a6b2e2d0fcf11ee580728d05a66f02c59589a59cf716bff1ab161cfdf9de7694ddff3343f0cdfbea1547d59ff0baf541edf2fcc3675133c9718531138203d22af6c0db87a395cb76188b5907e72a5fe03a7333bd64baba11812efbb23d60c +expected_shared_secret = faa9833781a7a41691f236feefa0c743bc141f458ecbba98eac4a51ee1ca001c + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = f1b45961c6216fc930a8760d4b79afe948166ce6222b16acc847ab4bd9540cb68872c9095aa7619b88414e313051b7abc0248eaf745c7bea31b01b29c5105fd698119ae0186e7c89aeec141027b19a5ac3e1c419dee19825f518d46879f43c8720e23f8916abad006b3bca9600932a67938015964b25b75d95788278d0af8be577ef5cb1fe61cfadec5500ad17de196a1f95187106649ea4227ac9a96091617d673f32454fe68442f0509faf86a06d4c421746310341257f48c51c961342372954e8373796a089721cc646b6c27b2d7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331aa082d1b66d708304ab884ec6c7e9ca98d7edb489fb2ad522a2b0881997662205a38a35ed77d8af15b70346fb825a25b0962f0a8befd5c602550925ac9454b6a4c02db9ae9a569dffc568d70a1bfc95c108b03f16c799310a4aefb74ded63c3ad4791ce3ad8cdab1df854adc814b2a1164e551a36cf87daf367f8767b122d4c2ce30632f22341b5458eab4cd2e9547f83b2d50ac57d8c30ecbf5387db6049a61768ef21123936664a46b4a2cadbe1b7a5ff752dec141f38aa5b0b85546b77f67d32d40f6a588e63ef136013f0ba4e2889714c309835bc0d8e858863a29622a843cc49dd2b85e66214c0b2695dec22d3c4a0f6544940ac77eb8a1c415aabe7797bb4e8079cf74943c5190a549a78038883ec62093a70ee6022df193a4fd7ba17714af692923b650b94f5b854d07139b240c29361ae9a2cf34fa4f1f6c2924850471d6338206a1b8c806697589b5d8a2ab860f4d1614426452038983dfe2ca14ac40170aad48809c99f68e5197a0f02a78b481062413cd8779c59ea9864bd9c68e8705f4179405d5a5ffb2273051bc1366a26312895345b81e780fd1683ec8e3261e1291723978a5e3350ffb6e1a7923b363162eb14247684d01cb3f48b7abeb2154a2751061327ea5c3839fa0a0db315b7ca60b0a7c5903309589e8812f5301dda14e98c92c028c1bb57c1b23f1b90ee5bcdb448229fa6ef147c56862babd6aabe7eb142e9a671de69786010720eca14ef6ba53d71e5ba885d50bb325707865b564e0018d89f27f8fd2678be207ef830b3a6457166b031a307cea082b8260937ed83f20646e50bc022f81cc6738b16f16954d983cc7a38d365462a564c8d4417c29ec50daf373f0c8134d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f8810cf0be61ab3d678757131ff93b5ba9a9efc54aac9fb279991370742af6be65145ca215ef35dbf512f13f88873f87b17f3c4d9e475f90a02d270ae72734029710522b93762d404691910a3e79686f6aef2118446d23955da68a477bafbf278822276b3882feb3112f2a47ec753510fa97bd5e4111ec67a66909fa3557d637c3686a214a81a6c9e983039d5cbd2b1853ebc7697a8c0ab34342fd3561d8b3ddb0575eb62c0f509079a5c5a3eea1b23417d70eaa585aa36ac24993c6cb463d63fb6129583e7908dcc4c6e55ba3cf30eee2842696777989b90ac577bdcac111ee344ad1478dcfa7bd15911d0e745a523a64dbc28f03c336dbc9a86c146c8f842478a172706cdef994d87c562d3b39911441e6570397f503da1f07c0c6045c3e863c7f3bcd41b787c8016058b81fc7b3375e9185696813a589c75995ede730d39715e66a370c127121235cb7785a42bab8a091872650062a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b85342b350477688a0fc2c5905216a7eff70bc742723d34a3daa13b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066083b2805846267cb3c989926d72fa18abd97cc0531a8747ca42d0b35c89478ffa2d3f769b1b2c0961ec877e704212115df3e171eeea463877b2f911878a15310b6042c1624f6232867578a842cbb477202395f51c3c129385993023325ee405975e062c705a63951b080bd4b98e3388c74cb6c4d9ab3d66a5e543481f300c2f8a1a17e7cadc83195ab4c840756db9fc11c39196bd34071e1ac098ab332354bb23d5a376ca35862070c933875ce21dd7383a41ab9abfe2ac96170c22c5133e07089940c03ff80ee80aa18b33bcf8061fd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ec711a0e259e3548f38022a5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = pass +expected_ciphertext = 668488b1742ab2b5efcb1ecb1abade0ccd75ab2f924a22d86911697d54145df559b4233de2c6174aaf9b4a28a4cdc61e2e0e45525c5faa7acbf6c1010ad2d278de2a93cd2274d0da5f0d6228f79386aa7768b9bb390aaeb3960f4ad68c8a40c56f547c94b1ba4f23646833721faca288c9cb7cf024d0ca2ad9b1c038abd3fb33d8315eff7b6a449d00f23c1614fc34b561cdf4bb49e18a4a7f0c551c61fd9ae12e8e26d06179de6b17253d162db35631fa96723f5e7d333dd283d66c68f974916c5c9e9860d5b0abe0fb8c445a00cddbecde8e97f621e2a8879dcbfda62352d658bfadb048d0e283fe5a571ba409a77bbd1fe24abb54ba232b33d24524d9f06128c08d179218738814f0c5b694244280eeb08d16059e85749a7217c289d528fbe06aefb681aa49e53dc1ecf487377e936851cae7be021046b64e11309d8b42a7681b851890143097758f5c5579ff4a1790eb3db4707731e5c2c46e87d5d4403fcce998936b8710fbaad0ba1525bc0bebeb8ff8dbf066e0a3bdd26e73aa9a19319d3b1e227ee33be3688108906441f306fd580608fc0e9904e99c8f518cea697bdba243ff762da3aeb7181b1b8c36dc8d0dd4df6043ebd9e8d6cb03a6a0355dcd88b134e3230c9d590cb2828ef4015a93cd6a6248730591f467b7c16d0cb3ed65000d568f4a4fb3b72a84b9d104dfa3b0d1c75c81adf89320545940394301a7176201a95a2d5502df6c79299921b2db70b2c0a6421f6fd4ea80346f8b6d8aecff68fd3dd9f4cf9a84bc9f50b7407036d003b6b470d57bc9910b4dfebca165f4c7bdd93c8f389c58b4522013e891c50bb8e34c57820e775ad7d2f5c824e6b7ff090d9662077df5d90a378b7fad220687198fb71c554b02b046690798d0665a53f6d7443716d11be803b317daf0c32c081ca0db1b71530b70ce3d1a6d4b59a435e2d423711abb3866c85efa62d170addaa29499d59a4ff5363d3d628bae1ccc279c8c373c49cbb73190558334bb9de513b31291efdfbe824accc8f09ec5cfcf43356d2dccb747a1983ca42e2bac83201491b2bd360d60d38ac8fc9ffbae86c2a5549acd88848104cbfd2647eb32073f8a30089535b6fc2e52f078192e3f5418e3ad3ccf8180568e7fb0f5187811f1f3b5e53bbf5c0e9890e0ca9c288ebb33f52f1cfd83747895f58ecb635a0cf7d671ed298b7d32ba470e6bd0e25f123486eaa8bb304ce20a2ac813c7d40e2e18000a5f59fff0eacd85107ba78f6186744114485f1af0ec6d986335c086335f045791aba91a99d76d3ec48d5eb4d8baeb9ab91e20862d00d170770d2486e39e3d9db208784e9aaf773993b4611934f3097a58bf6362f3f9555f93e5fa8526d3a0acc9840c2748a2729ba37254f16e8efdb82b3c216cec275e2243e7059a391854f5c4dcbacb109fd2c6ce10195c1ce02a8add8664ff46f326fe9eb38930b0d15b5c5e51f25b3d4e608c9a69c80520b4939d7e9faf21b44f01972e994b8c503507f2f6e848bee6df7e6492cf480828cfd724bfaeb26ef089ae29651f3194d21658cc4bc03dfcdfdd5af8c1a717b8dd3897f8d28db9768b853b5b3cf44a059042ca1d12544cacd0d91ad0d6a5afb82af18cdf21b697565390c8a1d043728e5309bf3be5eb71445f3f354fa5791e3e96e7b19fec2f824389f1882a1aabdfe62798cf48e7e2c58838383f99030bc0b1765a3779f764ed57eceecf2f32a985e48edf1dae22ac52b3b6e16ca870254f4a00ed3ec232bb7d77ca2be0f30a834567deb806e1d95b43021aaa5f0092ab91318518788083a1f96dcf22d387dc7dc35d9974c85d9f636b46c684cb668681caaf7de23dec177add2af7ef4c20084b847248aee6249a6e820815125dd40e141dd130a5260191628e44db1481b8a5949587c91f4aecc37b46c3b97fade84d2e6c6448520de16895406db62bec81aa6a92d99e5a611096128dcfcb2f996710b3ee1fdc34b51b6fdaa1a888c3a52c2d2d048555f358cf2f65d3c3537207b76e9bb11c336fc4a2dfea1ab36b4f429f2230515d485e5ee47a6a85d7eb238ae0877dc523882055a6deb0042eff47997b8aad4acb0e99c627187c6692b15825ad3b55da9e4af3d5c5a1d6900b16821c72873e027665ff2a5d9c2a550a89e389a9781163a3e3e559a90584c4de86403f58d8cf181be224fcc6098d28de413ea774a6b166e6c3d82ee9184aea +expected_shared_secret = 0f47139a8b007c4ba77c91ee885435dfcd38d38c0aa4f57fc147f08b4751aa44 + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = 09167020156648552c8dc941c1cc6424693025e263aef87f3e0b7147d0b8164077dd580f8c5b8f8ce10d77b217adfab3c65a2e6a04a662bcacc640b0eee6b08dc32c661751c0c8bddffc2e0bb78691a68e7eba25457a42aa0c3b15e17787619824e02edc7804161a3e7fb092e897506b8333aee03fd8b11c943853f1a9a44f5927309abde1321d60f73e41538cb9f83e3fa004011a94a200cc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29ba2274d759906a9043f2575f850f1152542585b9feba4368598c883c65120048b7c85e1a361adb0941e6479370f01604d4bbe85ba4683bae545b3772755765073899b00b0de9a6d810137ba8a91aab33ebc21c34274f3c995fe4ca8aaab926e7ba0d83175100fb261272137fdac3ec38ac299a25d2d9c514937e4386a06831ac39e21fc6e702a50476493754a37261c7187cab94922ae12f2b032228934782c056aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c6717905456d55016360d789a1f5ac166b1508d6100b0ce914216ca0476566ec33417ac234597a45c8a519b40842e5ee66b8b69269be2848053c50b38c258e38ad3104e9a1a50e9872dae129c38a367418c84f0cb5acedcae229291c3f6aeca507007042f609734dac77fa01c1735245d06f64aefec7736e077d5ac9d8767346250c7dca28105477b18c681fd779123e93788624007bc729ab13352f9915d062df3367d1acc58ed8478a9e6216a826977b770819796f24cad7db1538cc41c03a8192f2323c68a9f28fb0145cb543832639158cb098b7693c615b820ba01a3838cf805b9972ceec7689e9bac7831701d543e87a880fe91b59743888aac439d1222a5fc33f5068844fc3ae421cfe80c50db3031584a21b4330ce1a7c014b11eb3526ee4dc740ca7179a428dac27c128421167665f809959a5494c6e3a53f9d74f6e85ba7442cf68d999ce2a891da7cb6903ade2f576f858a5f731c259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a3896917ebd7c2e8c521bac1c612f0aaba462e48a30ba3d37a28507a16e20658f34ccd3905db5ab94d6333b1390e7a93906eb0c59932840cf55227f19a2c8728a7d385189057144b462a2338df6151e02bbc53d35412e4235d7045e47154e4b910a47ca8ee678595bb690a6b4459b23fbac0b51b055402a9a83f29691ae02a500c9c6352658fd1816a7a9e3f593ffda6939820530793382ba38aa851433585a39c68c7026461f9e0000b365ff2b67a93eb83437b5207061961233013a41cf7d1ce8f86c6b8159a65cb979161410d24b1b20a1ada82b72d127e941846e9d16d16f3b9a63b9e678057a20aacb88238ed9ca1c722307e2c2f3540afb2b78ed999981ff6a0a0e15f3c3ccadc9b242b886d12f29ad6113d63c8268c56913458ad31a04f6130845a1942fe68b9384c3fd2f62fe034c8e6ba23bb6799163553291ba2376775c4a67914f78bb75026df18aac6c8c9e6e77351dbcf8b97106d7ba0df874b1ee2bc508222794543ea60b3dc95093f288220f83b6a6b456f2a3bba809af288ac08b44ba9411bccb5ba61961817e20b7cdb6efdc4563a6b4b4888058f08ab01d702fb015f20c9202af713de66c1cf133bcde0277f84a5c1876b7adb21fc5a82555474b70443bc59355e3932d20c14887c25e9517c69d807c30a842cf50549da1620ea315e5a20549b59106a6e1fe56d6c4657d6f69891a7449a57239de5137e8c3efc2994bb0b2bd8cc49edbb3661820da27199414a33d804acbb1a80da68ce288c0974b0b1a8f038fd1819bd8090fb022fd648331699724b66059d148d6445acbcb9b910ab14cd0482972858b56541596b5b809aadf81657796c544c02b9a6eb9160bb0cc6445708d71051a89a88830c03c71903892860b950fe66495f992829dc783691876a06a1ff983965d67f2207a60643a6cbb59be857408d802b86f054d5137ee8e6a02d2603e29b4e970a9ca5f49e64e39f70fa5912488c98d28daedc20da06c811a38aafb0064e9ab2f3628587f7a099036a0ec71d70b04ad0e26919146b4006b15221ac78ea0599325b9de25c81506a786949deb23bae43c27c60b79f73635dd64b35002ce5d40f9808ae6a51cc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = pass +expected_ciphertext = d49c2b7a2106705cc9c8c1a257b88f7b647f7aed1bb62b27aa4213178b6f39ff9e94185502826a0c36eb5033cc4cb6ac0f94ce65ba99b40743876a3478661c824ba2c86db3a7af824c0c0e771a94b181c80656fdb2b200587791262bc89bd2892837037132dd9b07fa19d14e4c5fc19302b26430bf8701e847fea6bb5c10e3c8305f90c9ae4eed53dcb4d557234b06bee720481124252a4ab77cc61347aa38136342c28d662fa1e9f52483e30337240dd14dcde53f9dde843a77aa38887d8e4dfcddac3a1ca2b713167f9b64fd76964c5bb1b6800f9d2e904f3b4a573357fc16f2ce32eaf54306e850091d34f3f9762420e56f37788d081a3ff997af2407d2d48d86401777bf63a4bd51cbe8f6072ac5a799c9b174130b2fb0efd787dfedcad6bcaa7a77854da9565c0e3ff941061db8e166e26fdf9f0ed78c40644af0e5cefb146e5257fa1d410462abd301703a89222325cf45c9198227331608feb7758b15bc3c1860b94f80e14013e3a313f83560b8c0929e7ac731c06aa4b29adbafd18123557bcfd363f595950636180ab6bd6076f64f3d8cdc2de61a69e6932b78f1fd400e1be742ceca9c85a088e459ed8bc3cc2da9a50b2ea8a968f6bcd9b1f292961f07d96773ddd2b48479f8896c5a6ce6d1e6c856c7705f5f66c513f004c5cbe844785e6c0518e47465aafa1268062ec079107b63802e02df1c7f00001c5e06e0406d9cfc3b264964d458bb3589605a6b15bcac15605c882d42b37dfbe7a3fcad0de74627727551788d1d4c1bf27d139f86883db8384ae53dea68ed93a83380174824c08db979a773ee6648db9ac2cbde415c8aba0f66fd7a2611e0a107a9d86c06479568c462eb9dcff7f0dc0155ce7620526ab937f04061c52324e9cedb8a39626f57c19ea40441177ffa949184c05eea0b013e2b5bcf36a1c8800287136960cf328e63eb51a77c64d9d1351753c76a92095f04ab8eb7a4a105b7776cda7b9c5dc5eb9ae8fa2bc069b745110b04486ab6f6af90b8654f134fbd3c4bc06f02e8620bf4a452cf3b39f96ba95246006acd9009c14d430d28ccc3634604624f7b4a04c14ed0ac41a8f12a9e8fb004988a76926de95ffb7e03de5e977f356d13d4fc7b4a0e73eb65e48124cb5b035a4e3ff30a84c1ec565a441eb5b6bb0f3cc7bd1d51703e3761d19c7e1b1149d8d67daf17805e9e7276edda6532d2afcfac2eaa9707750d7568e4c2b8bd5f31b4c1f5adef0abc447589dc8cf3c3c78cbef3df957bf9f87020106cc927990b93625a91858d7a1c1fb2c7127f11d8109154d42673744ddc3846c4450e698fcfde63f9260b7ebdfcf920b0f841fb17100dc9e6f7c654825be2e8fc7e4f8afb32a79e8e85c57109563809086a23e7e4b82e09a89afe2f963334482019aac0c5d52180c9bfa0db8bc5d3120ee0560581cad04369d2593c10ceb449eb9459770753c7e6829179e11912247d93e98db06197c7d44450035b0a2b46dfd8624949bb98b4ee93f7ff1152baac80d8a30971af84f4b8677c06c2486fe85d6f82c092976f5a15178c3f4d7caf1ad0b8c98bf58f400e8a673e49f9584378ee71fe72740424ea9275631d16e84009c3d3f64e131362bdaa49b9d025ba149e0bf770a76566533f28f060624399773a0bb34e380e99680b698a320e6965c724ee3dc2654d3cc520f752886ddac9951dc921808f9d83f466e77e3c4ed05dcaac7888947569c720f756586244340ec5d79710d80a8d3220c7b95cd3a2c649aef066e204197e4161fc7bfd76cd92ebe5e0fb75984711e38c51449fbab7e68d6e3f3c0fca0414d19ee4f83d5b9b61f53dd0d8cf65a8ef701435d9c0a1001451564a7f67eab8e2c66a84c849dc50e8d099ea1a55deb34ed42f8a9b385b51b714f45402bc9a0c77f6c2c321d31bb5e28b3d26bed1e76355f0b96ccc71db5d4eeed4ef059771f988aae855c363d6f9fa8c2e9118ae3bc33120e1e7fe672ae06dd7f109ae3fab3586122c6093c35b4dbfaab4c25c34364272d047d4a9b39a16958a764a00ca0426a9945dafb5fa44fc288f8d24dab2817bd6933235148d93904946ea753421939c6e6cfa42db032b37efa8fa124053b50f7ab54e292a7474c86ed599539a583bae64084eabf0daf4b8c1388e57f3fb831a633a118881548b6df15056f72109c1d5d78b25b81c7e3ef51325e2f49cfeea570af8a1f69f1ccb9288 +expected_shared_secret = 182d34d0e83216d26a9d13301fe75a3aeb15ab145433965996255120cc9a5f86 + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = 50672c2e47609ecb47db696d4fe16e54341c0a510ca0293c25f69d027a4b7ccb08c184a68dbb0e8822393ab7b05ef08c4610a0b84c8c4cd5b783e71327d925959782b6c106b08436861a8fb2c1ce2f239f19a73b84966698c52e3c380a7da81b54ab76e62929e6743c88b05457868fff3074f8f085dbb05816c8b4803a7398f1c0f2cb3765e84672b24fa32838f7199a8f738b89334dc6f391125569b12a670cd37caaf00ac919aa4b92bd4da706973681b696b33871441daca919216760b41f5000a7bf782ac33491382b1c423734016cc8ee4b80e6e25be4720ed05439b9dac5fd240193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f2902da9c4a641fc36a1289640a371ab965b25383b7f017834fb4c3c3477910288f8b305031a7b97b69f3eb48780d3558c7c741171815b169e4e9a62a261460ff2caa333150aa2698d243ec55abad0329cf8fca935094c6795489c902303fcca7f257c7d072eaed4a31c9146311b21b09b38326aae0d914c55ab756d7b0cd761510dd12572b912ec79b61fa230e4eb9dd052b29b775d891b7025bc89c0dcaa0a18855988c215c74f06b36976101c0f697cf8db4c0fe25f1c016cd11154f5a5cebdcc4add13b31a63336ae621f2257837b16ff0f6c07eba6fe5b058a42122aa88629014256017bbef582e123365ae37063fa97277b2063d3860d3920beca27638f02807fa3bac4ac08614ad1590bdc6c855f4d3b292982838923251a348cb48753ef773570ab00768341670c21dc7a356931e5b8ab51e8b2615f5689e607953f685aeb6b999815b2cc66c24f65d2ec64e4ee88d4cd830da4c61e15a033e37182731b5b0b506def921bdc19a85624630ba9102226f6c2467c9eb21483bcfc96a22d8493f9ef8b7276378ffc16c3a996f5cf6755d924716524dc85c39d22a8254e74244229c975b467ac94568312333eb578a197f4530ab74514fa174855904c7fd09b2003c3b94bb41c4559b45c00f7a73935ed15a39e47bcd46497141942c3b669642060533ce5ddb0cb4c1369dec82b8d7239637b615a086d4aa87630439d712a55556cdb911734a23779d7c5ddc628d0f326b5502a79da80fcfb3aa8e607fd5c25b8f2768515618538a990df66fe57c5c3b3a354655ae4fc098bcd7a382301d0b721a1e74795ac23ffb8c5493e14c0793cf03063794cb0d340a018461ad89e17ea89b7b88382b9a288bc4b13180db6ee6224fd929b628049c20c1c830504e09651147417b552b6ec810c744210532bb011a93baf28c20512558bc1c4c4a07565779b7fcb260839506e0e0224099c5751a93d6141f90816ea8da87cd1105715a67d0b969d8b748a46831ead199eb4c28b634a82d8b988d2a6d5c797943000d2546957eda9b1573bf534b552f225253d768706c8ad4c42e2688b40965c0dee151be4b7625d92e79fa40fa7c00093148125c65e841cdb86aa90a02099e2c6c4c0bbc95f14fd0734872f2a6d6b3c9b3d0285b7ccbb5b715e913245c14a5aa146f003788d4a76df1037195da2e939cc08f56c3c25405d7d1851249496d33421e5bc386645ff3a8367c3bcfd0542c8962ce146720012087693c60e3a47de4570887473bf9b68c22699afc314afd801a0cda51fe4340e4e34ef18c07a9c7a40190908ac323068c95d59bb04bfc11ac930f99d082d547c99a807c8d112d82f1b81125b41f57a243006b772673efd286b4d24684d2b046b53d7d26b6bbb862d64c42e0e909e813391d6a8289647e91660dc5891479c43769d9608c10763e5a35acb9ab7552a08d167abc9b02d3798115d4c0b6b0782c77bfaea4bc27835b4ae525bb052f6dc04d65074e00207213d612e746a44cb5bb55311c0d4a43d2eb3c2003cf3eb895fda1001bd55484992a384561152779df9534b933244654b2c37b3caa368319235a1da431d958a4dec38da311412606adc0d26022f8a822e4913b8b5e97b6c2525636b586c8b3c62ab4dc73539a028fec33a5704bf95183847361a8143d1c22495ea4a229b4214fc22334b857344c721ac2190b554f7a30479bdbc8854c0f0219b4002a0685119aec442242d15cdde0983f8c9ef2b3aee24ca7ed917b90407d5ad86906c0c865149060b36db1cb1a22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = pass +expected_ciphertext = 0efe44715790e522dd7c57674b14433a78f6ff40d93cb8418bb4eaceefcd5b2f9db4ac2556602b9c21fa8f12123e3784fa5e47cb2b1e59a1df68ab72bb04c1561b9b002081068df5f142a6157afd480835b0231e575b5ef4a06a9502cdd90d0df551482f563a47e435aefef9fa79dd8948cd34751bf8a6dd83db7e70bd00c2f89433a4ce9c3148d160d170c5c720567f7f7c4ec572aed3647744738722b1a7d5a657c031c65b4424c2677527e0eaf5e71ece38d307d5db72d03d2447b2be57b073652ca4a01a0733ec2bb127c6001365ad553b18ac2b0f5f70ee9ff6440cadfa07f1ad4f4e9561e113cdccad1c925855c78502e38b6e6be1af5b08a9ee18dce358fa089032772b0d864f7ec014e4c130cfde4c7b4c36246b14775d4f500e135b2c2126f3a4c971a9d0c26e1221d18c9841bfc5a2159b3918c7445ee24b4124e3eb8b73d96df478fa5e35e8a7c5e8d2823cc1e70e320dcb5b3c1d35f3ce40aaf700b9fad25b289241b2e259c69fa81ba095d2427d686186aa953d91ed8f3d2f5b3fe248ab7b51680192255e09b1d26fcaa9737889c8e21081549ab1bd98e1951674821135f95e84136621bbd6bf40501d71d02e6dcb278aecfd9dbdec9ed6f2e076e61888e63e9c2d4e89f22f2bd6a7c483ecdab4b1630105359bb5da97dbe0cb65c444a90299c4425f2d655a5d6762ddc671d87303ba65e06fab850f391295b041e583c59386d132091e8ed0407e89c97d4c061d87b5df0c2c3a127729c5c1538ccce52dcf845cd1015fdf457e39f3986c2d987384af25823fe56450e348a8035c68c05006c07b6d1f6ae6bde926a84255e769a6fe84a5f5de7a6d7be100bd68048ac892cbec2e16068d1216d0928e34f42420e90cc88c9b0bcd80124676f38da8f5a1cb0ca49fa252bf51584ff49c5b631772d38a2d266f1a383fe97c716dd3959bdd4f3341746dd90c09a07dfad70ce8a3247ff2d22fda1922a8fbc13a776f80fcc119b363de7434f0c44d92dd9de68d1be0fe59f9e288eea89be67be109dffbbf3963c11a36c2d1b25dd186f924a1ddb43338670b52765658837d6ded97d5299081741fe5311371945da0c8d50c3c30b79d111ec1eb1d42643c43a3bee2cb78fd6b682688252556b3e1ec7bdc3903d8f1bc8a4bc243e543043257d5ea5d8db320ae4b5511e51e53d1cffc863e20bffc306159f74cb3d674ab3008fbeded6bc8247911cf4407482aa4c9fce44c8646b79487335f906fb0280731d56cd25979326f941a9eaf669df8177a9c4eb9451aa52d96be299d7cf819d20ca35698affd625abcbc433816f0059a28586b034ed15e151c177df47a69719420df9359bf1534db883d910f31f38c2d048ef84a4bbb13d6dd5b943de1509ba15f2b2bccaf13bd1327dd3e972e8a32a29fbceed5c6ed947f470bc73f0b8937e5de4e32be391061f353f3294ff53c64b18a5f198b72fa9c0c86ab49011838537f8fdd8e651e2b56f9c14eb18d6492736454f322894412331ca0b236b7f84071fc4ca7183335c848036f8898f1a9c9b3df0498f25e41ba498bfcc398d2724c671fb5949558d67716b3b853bd6921e14e3dfe5dc495f0635b28c5ceaec62395f68fedd6946cfb3e723be0d45f7338e0977f1990003701a7c6dec5e470bf5861c7bdedd2c7cf2555cb7a19e606085e1d6a651976d4047ffd181f45c36f047a7378a7c2f7610a4a756bf8f4530a221e9fbee0c70ec490d30b4ae209acca94a8241bfea5c84e2dab5765ca9f9d0d72d99788e60b9e5030b92b930ca94d45225a572fbc7d2f8ae0b27c2b334bd528eeab4e6ea0bb32238939b7850907631577982dba433ca4a717540e54bf56282040e8cc8c59aefe7800a792e2b575d3e413c6e8513f42531187a943e4a64b429b2fe196972f6ea484b6cb84b7bd8908e660dde36931f6013aea9c5ed1b9300369e32c43201db1972075fdf49f6afb94ba8fc81097f2bf4212bef0a1bb559e139b434af763e201b13e938a3c7e30b8515cdbd9720340a53686b02b0b841cb6279415615789cb10bec3b92fc60335e5d05ef77abc905af3c02b31984cff768051ab2b6eb0d286516af882eb89aac29b856d46f2735b57869cf0cac9bce18a1f535fc5f219cb339ae357ad1bb8128abb0b8dbafde98c49316b43c7fd26ca723a4764e3767e6caef79f1bcee92a877d59e1618d099f29f1482be21f9c7a +expected_shared_secret = 62a14f68d726235fc16e0ac57ad4ae0eb3fc029abb18567a4ee574b44924693b + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = 25879df1312d41f14b53ea0fcb973ead32cdf833463ef73eed9a0ce2d09faff9ce3a06030b3021cf4360f3e4cf93528bdbe69d0655171ba7b6d93cc220a10d37e828e54629c6239ee13c0a73e58f0ab6632e764a840753393b206c180b3c333275db3f05516fde08803f7bcc10589f8f54793f732cbfe82658033694e6aa74823b92cb616433072d405e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb56292bb1d796bebb5c400f30098591447191a7ce6a3b2cc3fc7ab7b5c6ca02c6808be45671012867812c2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd6734736907dd3a9e60e4637e2ab768e9558339921d8c1a8218926815cacca840224052d574164a4661afd903d4516e43e3984b31554e5b666a9cbd332a9e6c63036d34189616cdb3d100331bba659649ef0abb86502fa994b941f9a354231110b8080db75c69ec6ffcba48642b0ef54479dd7995f7f9ba92f8b473cc7e31d04948648af330aa09996e868c75bc3949bc3bc8e5923df68b5dd78bafd3318ae4fa6224b8a7dc9814f7b35839b05cb709cb1cf2c1e80aa879c58b29677cda375a5e4229bc8431d48bb08af0bc27f982a6723e60b00df6e607665b7a4b4cb35e5162ba3698b7140ae7a25a3ea76db07626afc773854038b3d13654b7cf0a1a8e75959e5ea0797ef4a64538c19f0028dcb5cdb5803815467e57aca68fe00c3352602897aa88021203a4b970ebcca77846e5c01adb22859e41cdbfa8a7be9b932aa2c6d391379a035455d84282d5ab90d5b6de056f211cc6af61c1d5b643f8d299c249c055964c56906f88778a4600bd054850a9d92557ab2c33dca2eb2857b9617018ab08f25493b265b10ce74889d8cafec53f7b6805bfd637a6b6ade8a65d7f885c3af645cf08bae250753eac8e2b734a75976ac9eb8d2633a980285ec33b154c1551162c81f0254d2eb55a7db13f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d0609e5b36b8b7e097d40ccaccf496f3f00fb957162445025ed62592fb61d41a28b16a1f3a3cc83b1b173e9599e5c49a41b93169dbc4fd006a93bb233ef73df88116e091b17a06125f651f52d501dc86a856a96a43601c46f32b1fd6900a6513f7d298851b443242c62b34236c7495881cc3fa592ebd4397d5422f3c40ca62980188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3caeb0a980d13de0f3129e151c0813b259d53efa07681048888dbc082adc4dd324a028d48fe728701398ce20425bcc9b410687363ad771218285617a39f3c7bfbb2a6c006125d6fa6df88898f7b236f7581a8a077038a06394782ce7862185f4ce98ac06c25b611da7701a80329228391da903607793bc8a2189a123c177af9d987ae9d1c6d2d01bc5910f56514532d582ca092939119444b3b736abc0fb5140e14c723b1c6abc2034929a7edd48ce3d469b16b09cbba5008728baabd54d15f427d2eb5e890a5a13224038328fcb227baf6a7ea3b82aac5844d809ad86b6adca537c2c0b4e0d659606f835129905a6760cfd68b5697b9a8ec00159450205cbcfc0f8c9fb8898f135298ee99a154977fae7bae16ab9325231178a764c1b10b5c427598490cd9539b69b1848980d09768c435233f52376371b7971d861c8612ecd160655e83ba1e60a553b4905d35efa1bbf58318d78353da822241a354b439b2449a2825d43212be80483c167e6c5b50883412571cd2ac3c1b5aa1ec9c232e6b9b5a2091e189b3ab0b323ff13654bc60ed42857755902d063619ab98fd8790d05d85bef1ab23a09a9c241a3cdea620b6c338eb582dbdca9a6ac40fef7615091445a93b8fc2001e09816ffd54f7870b5ce6a4fbd46c3f42b8e63619b7675716bb65eab17299b57c45c834226dcc6c1f98593782c9733a078db34a137c5422cc1dd87a614c1604972559937102ae60337d997caa06b0f33c43b093af04595e5ab48a7a0966ff318a735024f004d6f1893b48b74b42135c43425c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a230cdc1249b09833be95c5f46bc5905b73a82206bd6658464659293691eb58551973121a42385ae81ac9ea2eb6419a915441f41946e504a6b9d5716e909bdc49337909282c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = pass +expected_ciphertext = 76a8aaf524ed637534be4d3ac319a56d11f27da6220746b43136c9222548c8015f12394c5222412b1806c7cad8b4940658d1519bc2f4c6880798992cb3334e607fcaa0344328bedee7091854ed2fe4332abed021d113833f6a63048a74ed630779914cf1a54a90f95e3d32b3a8fbb2f7242f7b55a688778c10fdfce2e74a3adce25266a9017aa799a79c5861fd63a03ea009985961bbb7d0458fc6a2cf56a64a8741ea85cd56501f6fb2762243c788fbe46fc963526d7060787f111159ea1145c107696491c3c838a8b0e3fc9b820a349962416c4756969ebb82279596b43a152bb8a96d880f6f187e5b8a6a2bd2b987f82401516c0b199ddcc49e7d609b2cb4fa8656b3189efd325b04c3b6c7b257d2e56087cab0fc74230dc7c440550879d221e066ad553dc84f3b77c25c1601f67aae9f2740e5040efb324fe3b86e6e9c558c9ab9ec0b22fd838a92da19ac3598324297c98a5461c9ef76a3f92f6c83b99cb842585ae68adbdc1cb99111ed0c19393f65c2b01f6a504755a671e40b0c336396aa8111acf71dbbca1e3ca4f901634a88ccfdc88eb790d15e66f1441fd4cbafa6f04841a809c3cbf26677f422a15c2d93d361530dd6a22391660e8c6619655fcdcff7c82192cde31070fde0ab9a027388ef188b13449d44b7ec9f684404f38d9b58fee9c1ac8703fb5a88f09b63b2e3ff4d5c6c7968c5de612453e42e490426bc8259b040c7c942bbf63a68c440ef7cee3687da84ffcbac763fc67946d4438c0ef229eb2433d848bdc469295be7b09d5b1daba8576f2502261361b4d9d206912d29d6f7d6b52f2872b71e5a0c6aebba71f89b603c81f1a5241a901b21ce2e88f44982aa3612ddbfb54ccc5536a5ad82f9ae5519bf4b2b90530e0887609577145df92481bd786e09352d6b3e5c856378324beee6fefbfd62ebd43de27666d17c9f2b668f20937b75276bde8d2763077662dda3d09cbeba14cf05e138cb8386011a7b506c08d12ccf4781172431b6dc70aa723fd80e3cb87ee0fad2b2211ae0b046753a7e7eae4dda7bb689104f5264bbe2fd1d99206e8004e8f658f3807d6939759eb85cadce7272723675d1c41cb7e5476a15f238f7a59cff42a7bd39d4374f9a74d63cdace08d74f12739ca73aa8ec8da29832611a891f7ba94877c493326024a8cf0bd83c8e29bfa48df9ce2c227387ed730046bd9c30fd3bac87d0cdd03c5f516ba20a07221d5a2290d7fbccb7fa9ce69d228fe52393c3ad9e0db134ca5cc085ba08ed902cd1e17319936791b8b0281fc1b219e8fef1a4b0e7e7328a7612a99f392ea5495a8a850e4059ff6d99984cfa95996e52a6e7809692f807963f591ce1543ca2ec33ed51dc457f7494fb7b641aa65447a9423cbeee9acde902ae6e8587f9690a67fad158905ad6eb4b86c435ac36914e0ba75d8039caf6ff4d5b9fb718145f95e173a0f074df2efa88804201f928be5b7772d5aa3ce8e48e4474a872a7a602f5e8743f8fdc1757240c1f180a24529b1cdc4d57a23afa8557119351df6f08e64ed1e84498c34a2dfdacd75de045a9ce6510e93fa4ed22735a16a7e2d1f4fe7bc0a22512dbe45ae055666214b6a61b495fcea2ac2380dd7849fbeb227583edbbe2939f63e141fca36b0e2a03c08927ed4c72631f8b35ec8ffb5ee7d3c5b3411af5d4f8b5a713709b53d8685d6930033af0eddfcfd20c3c85978432b8c1efb116945b0cd2998005b346b516602dfc17fb5b7d148512f8f074405292d3211d2d7eeadd046232b1056a8e8455e4c74dd990402b7164c511f8099dcf4acc56ff320762baa4ab6b0641384b153d94f119328f2bbd09731643700f9c2702eb83831154f1df082fc872230360d3819214a629af48be4ae80cae16465e4e0970c37bb432feda83bce8c1d89d772cf8b1fc2d5315cfb62b9f264c34fef2635cb1da048e22207bc84e5d81980efedc994c184efbd9fcc05120cdf8046cf15a3f27181872376f4c3e5868cb96518a0b0676f16ef277fa153b9e05688bd8db52496ef64a8af467ed46813108037482816d581f7624619e9d77c1c43dcb5a0579d2958d427d020e098a4e8714ada6c77428f0746d6cdd0e5a55aaba012cb8880b1e8af0fc7a8bd79e332c26c6742538ec997cc9775003198b0dfd2da89870c20e136f380d76d90aa2ec27f8cfd12a58c233b748fc4cc8cf1ccd58d5cd428a8395eccc +expected_shared_secret = 4ceda11055991ce1e5d910a240981e39a6a903b20ea6ae6a21d9d56d0935efa8 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = 32a8b2861c097612cdb6f437e844b131e016f3299c31185123951b2901c5fb8296762292d6b37f5bdb67000d91974c77adda0e8601a03432c648848e38e45d8b9a45d8263e64d603e0f50d3f438acc29ccbe54bf6cdb0500b50344a96837828bc568cebaf055f070737f4771c8b4cb87230afbe824d6312ed22ca5e2d4c5dc354d44935ca64aabc5a64186e51697b9444a50569861404bd7a9b76898a3626edbfac8a806751d328bc393b83525514c56b7727110f802cc41bb9c43666b25e26987cc813fb7193954a0258c61b4e13f2da32ce3f1c030bc0081060a7e091929cbb729584a888a06610489f3312bd576666fa09013f4a191b498b9637df5ac5610103de4734c7e82c99062c34063b01fe2210d0bba1a15406836275aa119042b5072e77523a655f41316b3dc31f39840446886af337d2ea0c532999635786d9a6948164c361877891ad903a0c725289c4c02f81ed3452858d93489a07ea071847c38780c86c6de1c22f1db704a2249c6a96695ab22b9868d639ca4a8346ae0845aa8ba151e14941bf447b2701cb715456cb91b927c63f829c562628e01f88499a60aa69a0f3ef410ebb2698889711891b008c0b11a98c47e291b763039e5a214d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a654d0b13d23b8ac2869b4062ba3a27af9f4468a216789b92bdcc8ac7ff2b86b134606a693a1915c55421e8260a872f57a73047f496442d7b1cf44830a8cc01b27b54f495cb984e732c4a40f99a17c5f469f311b6bff9c582f888910da60e6211c788c2ff2ac489f1163826b672e6abfefd917184b3f66d72deaf652e6a596ebf5248a2809c3187c4a3834f220c28f55b589e161479882aac21407e56d4c541282b1b330a7681db50bf30463168733faa52cecb1a8c2d51724b7afe1976e42ab7fefb1c234da45aafb803e80c972559694548ee98ba2c818010ca940f41429a8222b8739c872b1afca093faab792c3e965e7b0bd8850be2498286ed9b8c9a6987577b98ec4a7835cae03b28ae9130ac40c5af971738e423f7f905a223a6c27752bfaf4c495874d0a984187631f50b8aa87ea806e78a1c18c78040548443587486171a11288d4d2a7d19b809ec8c5116575f3c47a1b419529112417a15cda9a0fab5b7968a0937b4c443dfa3d0cc893d4bab60bda28da5a7a7fe6394f6b1dbb207b5abb9b0157a029063ededa1d0f162bc536cda44b598396772e4a3173ab4a22cb91e4b165a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee7923c64baaefcb99bf37195ea6b657d442097289db24568d970ce526c11f507cd7bdc3facc879893c33d35b734fb9928f82867c5266dc1199ee679ac2c337c35c435f90c8ebd0aa29e22a169bc36d605d5a2cb1eb914534f5b3d89a769d806dd87b0d32c63d0225cac6aa1b8c3b7d9258ca68cb8086b673322716389876d85c71d2f5bd3d081d812ab37d026a34324135e5988fea7833973d3b25ad2b8777f3f8691b5671d05b266b61c272076ed0d23604ec7a670c634a7074e889c030026a1b29c4b025c59d43029be2c2a2665dc2f1423c063e1b78b79b550db2281c3bc88dced5345882b30ddc400a62bd35c52bfb063213947b89a91df0fc0f34f53555853a8724a9d15a00b285abfdb39e97b5aaafb429042aaec4d21303f1217a3c0ac7d249a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d650bebc225fcbc132936c9741b496d1c95d8318b6b9b9a71c071f7af5547f895fc4e313e3a262d31695b9471dd8f50f6e227c7774260d60ad56ac7608430f1c370cb917adc3b7717b484b52158740740366a42d9f010c333611e0d29523b04618895cd91a21629146bf1870ed2584ee8c0a728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba0b0687d39094e034399973e2d09116b225f2d41a86b61936743806e41a242b63aa19532f19c5fcf0204329537e996a08bf52acf80c39ce1938fb581543cc77146cd34a5223af8bffe735fb327c888208b5dd648d41ca209f976f6f226f853545a525f3dfb258c8074ef9a442c639a38459fd906a8982a69e29608da98b4c4a59eb6ec04382cc584e663f5751f6aa0486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = pass +expected_ciphertext = aae6b8e3eb42edf187f787864affaa3e657383ed66e1d6c71386437f74b297ff2cb4884f17c32ab05efa09d27f3a3bf26076f79be7dde0f24f2f2c9229a8f10033f15ab8424bbd1c11e19202ed71af921842a338325c8997e1b9ba892ab8eb4c060dc28ee5ac28a047054d3ef96514d75aab341618ef99abaaedc22071c25728e1e19ba78298df96e51010f32ed5fce1bea80fa7b1bce6ab21a8cf80c478fd9f83222d29199ac57177aa549442a620687ed3e0f349c1930c7b5f3308b9b99ee8dce261d3e430b5e224ddd31d810c28247a2ceac2d858db34353cf7edda521bb7d50468feb2dbf07c4ae5f31d6b686905269321a7a7ed721a0d943779494be59440c0d1d8c288a6ea1ba07b44cdedfd9b98ff60648cca5b0000b11c1a1a7a005e5ad5cada8a1411c998c96d583757e8d2c50986165e1e9cd1b73c1432a79a25809de5843360eb9064775cec0a8578cced7ff6e5c7a9c653533e1f302b778c9933d6385857c0a5069c176d174a2b9ab7adb7deecfad589e67926806fbf567b834fe907193733d2e00a084331ec185bad1c85fd6b132f3a469ecd97c0d88ad87d0f864738100517f8aa407009d6fe14e597ce9fbe6963573105f1648e7cd42532b70fa0f499ceffc9fc7a3ce33136cad449bf81785a0f7002cf724710269dac94348be7a722eaf9b51b0b81e9f6d9ff3fc7e4b2a5bff66f35692c1badd5c9c7c3bf3444e188ea589ee69ce5c3e397bf29abeb71f7bd2df6aec7b3f60aceba3be1edd3c222f1aa2c6c415926383eac51a9e15b98478f12b7c69e4e372b0d443a90ea5f374797566acb58b84732ed7321f1c91f4383301da30fbdb44ab7b967d72f502ccfb46d81dc5746fcae3f6de14cc63601c87eca9dc7a9b9a406ae604d30e38536d7271c9d1b2512a8e1d0fc9cd9ac0ed24ba41cbb7cac9b099dd9d9a0b85b41363e19795e868b49f05557d0b49650f0c950a046c57917915f3a238bf49f5859f5e35087bc656987fc4600e6db90e3cc2e9cd4cf97df005c5f517635b92412d43477f3c633e51797d084d6286c5cac768d22a6229a8905b51157e536edbbc6b4477066463e44e21a31b8b9888168a460b1f80d57252bf8c145535a162270cfbfee98009a0f4d6e8ddb953c468ad14f7855fcc73d593f572e1796243d029559b26067de9db571b8d9090d49342aad33c23a5c83dc2205256fc1efbfac5b78fc39de344b1fb600001deaa75856cbb22d9555a381906c598e44a8e43d869972c243a444c559342d3ef6a9448576bf7e9429d407465c3513d2525510ffaea7923f066bb16d105573351ac0289975debc39bd43a49758b003919db44313910ceafc4e5196cb664b8e751b82110c14e5cd268ccdd393da65c25a6af61f1c509cdfed0df06bac8aba62c8fbbd69a45ce0f4c79203b543deb8d98b4a3e74d0f8c0b71056963faeb0e33ffecba17936196153fd11cb2bf121b6a80aaaa21e16cdbb4a70e1c1c6b2b3d4d1d9a5568733be1ee64ab7a95fdffd8d3ddf944692b1f3c092fe65e67ab40a58ecedd6e869b0be37bb69c93e8459f338af18a043fbe9b34217b2c0756b08ca505a5e513a2a07b12ef71821c1cfee1c4e61bdefb849f57aa9bb9743f06310780ea951bf2824575a7cab3d0edb7da713d68cf3eb3f9b3483a5a5321f07d3fd6918e258838f0f921080ae13601e123f854fabc15d7ee2cc33dcfb07b0f1236f6f7157306ac2b59a00136a2e1d8af72676eb959650ca42e46ffadbc1401928138bd65b45bc3e67ea59ede671bab9cd3eb856389303f2f34903c22309afed76ff0ecb9d2ca6b6251eb9bd2cd7a17dfe5b50f8acb1f3f99f3001282623bdebf20a91a4944538460b15d2c5896e8dad33cd1c9f5a0e2f567d564eabed3b6e577a2b03b8695e238d9a08ea06fc48e5a906947880cc343b6b2189886a7b88db45012815881631dcddf43ac5862283ecc8b798c4ee4c7aa56bb7dcb158bd1ec7a0c38f2df1524282939a58472f056d58dc38f7588386aa04940394fddd34ae12f3aadd564a55f8a5d7fd4bef9ad78c57f83e70cdcf284dabfa8122f10e95739586154a0e8916c80059d76df5f5b25a745af49d6cd52974fcaf65c938af7d8da7a14fca12530a1ec7b7bcc5083b4a7ac2508e8a368df0fb7b47c678414842d4e4b4b94dd4ba6c4cd7db0f5dbee9943f5b89fadd73a0ace826f58d2d6ba5b57795 +expected_shared_secret = 8d8257f05a4e76ad11783f7f6850c4f1c34017bf5ab47f89eae202132ada42ff + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = e0f7b1cab23a3379caf84ab285e12ebdb602f431a82e0b098ea1a1f18b18411989cb1b035d0726865712f5cc1e6b51674887b0e00c2eb067731dc8419e64b816955b407a1a813666d73b53d7955639a877a961b4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a391bc55b30dccf33dc1a93b9b784c7c3429ce8684e1910800739839bcb926374932a7241267835caa9131818ef9aa4ef5c1a3e2f03bfc83076d8a827c082f0d0c2ff89a8fc2e62a96396dd411259d26c7b9c84bd38c557fa45103f3b793097ef6b775f050033109ac7c606e2cb05497c9c596639a63171f5e70775de9c545b919b9e199f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a203825297864ef536cf578c277b6541083168d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b7a018e3e5cc8c581198e2b4b372002eb756bc7a65a4d67c86ab022f549bb97904e035173ae9c1073a9d23a315d054cf0e3ba27d401bb04569065256be9447a06caedd97871b52624f43916d475c7539bbbbfab35c0864c8c77b12242797323bb12935bf5a08c2ea4d446305a7345de980a03067513f6402e14b29e7287e30194dd76856ed80c55bd65849c1135d398994007b1f14a452e36bbe7283ca7b3ed1b67d0fc3667387c9b3c3cd8314515cd2c4e51b96a8d43a1c755c65740ba9830f65356290953b9dbb03600b18f4681f6f039379f26d40f2c8cab57378b66aa245197cea225eb9b712c95c4bba470b07bc6c458aad71bce067b0991036f5f54636248c516c88eae013232c0191257cd0a6322704c9a6d005fc80c6c6ba0636e701bc5847c091045bab969ab85f5644a5f8f43858c94b276201a7e77aa5c413c57b40726302559762ec40178199526ae63279fb510c8917ab40c1b1bb15dddb6d1c2b22520780f222c15ab2a16bfa28753a61a949aaea6abc3e3083a467110334a959fa582261561d3c8fa671ad34b8b7ff2b682020651935cab1b227d75261e3c98930961457a955275734d9f41c61069e1a5569d38a1a1ca1876e481d94851e62918fbd550e45fbb79a7130643bc1fea1c722675398498c6874ab1a7997008a166c9146882c37e4eb64c3e306d2b2b4c1409a81da2122a5360430774fa56c5a3520a7e870aafb55773124d93b17451c01c7e21be33a9de7a500fef26c7117c13599024ebab75ba9710c5465a089375b2a751f5c3eba8151bda4182ff3280826c3190b9b11b89bf9d151c4a939510007378895f916bbb8e107031459e27c9ee698a269425ebf5a484812271ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd82c10c997ace9e09f77cb9fc4f8c13b25a8a12c52c7729f22a3290140c7ad0480c00a175db293cea64d422baf4bd306c5d446d48b062f751f47891a8fa82b9786148c364e4dd85507c07a9b4448e57c2795554b3cf53d5d14ad3179669862123840a7aeb57240d69ecadbb48521c196dca4705671b1e566fe59b08cb963f417abd01a1915a33367508cfa9c89413b7709eb48e9bc2e809a56b027b6dd3a513a2428466c29b6ac802f9a83536ba1adfb96270c57a0743c12733525311e8fd04e12c52f15468e84c6af54d8bae8214c152c56082465b79a6cead444aa767571cb1351e4cc05a8a75057c5745abb125a5382cb8a3ea2170c104ca21cb5da000002b7231a8a0a23e50d173485c7d1cda9e8c1da913161e34fe0a986ed5c1183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d21f170569165ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93b506a8554738e522e11bb3b7976f9ab17ce8a190b0cc810258972a10283c21b9fa36384ae0be5556aa252a59c1aa7617b480729c0272576dfb0c6108db290a0cafb8588f6db8b933970ebca0933c9382acab4dc0c75c4e9a469ad60c86d7474440b870e7958b600b6a3b48cb13c938652198c183347358cccb4d45ab3a4fd7c7730470c2218726157f89facc31b6449fd6b4666081572ca291ba6e3657165b053c6a239876ca5eaa0bc659b0b1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc5d006ca6586818664ea6108bf0080966ba83c77aed8fb2066c94458e70a90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = pass +expected_ciphertext = 722ee373d0ab7b12bfdc068bde1e6e3e25205e049621e8715b003682dbe090de85e0277a44abd1ef864542e911768d2ab3e948e72a24190d55becca0b3475960528494ad8f1990486d1cd627dd9015096b7141650267bb5448be49261cbc0cdb5139db934566e5ec5c4930e9412f2070fc1b4d960435797f21f4c72a44af123bab47134010217ac3a6b754873a1509d76f8412a69eb76e44b958f40cf00ebfd63a81fc72aa8408ecf238425009cd4abe2f71f18b99c4149c5575f758623c843cb965b827f71e0d086ee564ed710a6d7c747d11ca6448415846b8607b2feb8919c635d57d7e8ff5c3fc483fa28eb2b70874ca6e0ce4254c20b3b77893fae5149adfd7da1d04e5eb7ff0434dcefbe2abd245c9b01dbb710e86e69b649e68bd15fd7c9cea94630958b8a275c1d9062b311155406d7fbf1f9ad2060ab91bd9c0e73a3309d2485bc98b18b0516925671dd40102fced9412598b2519cc18580401b68f6ea472302fec5a0b532781a6ef538dfecee2b3834ea9ce02c57f82fa473b50dae41f38bda763d833c60a5e89bf630975c40fc91ffc02faedbd982f3c092c6e48e90b614163fbfd0b5621de436e3468eacd08d40228302f89d9228384bc4e7d0e5b4c4b2e9d6f8625280566a3ac8cb62203ef53efc2ae725aa46e9dc9330e6c0a021b89ece4af9baaa21cda48fa6e67c95e51a8786cbc4f9b7e1fe1bf6f7658d24a41ef2996de5de80c4df7d7aeb58bb1281a491956f4fdf360a713d10665cf36fe20c33262eb965eb6a806b793504f78e11a71d56c76d95cfce2d9e80801f02cbcee3156fc30965d62029867fb34ecc9990b523ad71ba540261261f02bc3f23cf9a7441a6f6ab3622de48bbc3027b04680896828bbdc0d630b78c294e25ebf872cb08fde4a313cdeac0b4155bcfff2b7f7ac98db3fb802e503b7280e24faf198193b3fe4f329c2128adf30a86dd4c0bf3a976af1d9e1119021380abae173ba04282f27819b484d243c6a5b3f90b638501a179672b0527ef810219617d062471e70871af275182414ae2925d41e2e95e4dcd49a5a1be726602e01003b845cce7e361dde2587d56120b33d57f5511bc523bce5d4ba0f99a9671d2b212d19d9ded87a861bbe7dbf765e947bfe6116d03dd459b00be91269f9f5ef1d4998f626456776cc973fe2650f87c4e37d96612eeddc25a68830c7b409d0e922e9b7c179670c60b7925ad59467d5a2e0da1f3a58a17f7b198b659bb93d16386a768438028b380eadc3b4cc6d36c0d7b216747a96d53af8fb0beafe9c1e3ce618d8288069ab4c893e7f8dc96a49de28e75d21c33c9a00afb5a2f96c1e414e621d46b51fc5e2eda325738966f07ea5a77402f575987480653fc0e8894ceca37d0c6f47ff1a69a70bd97716705e44befb7cd1d0c7e64563c3432bfed478d05c532e0469a9ae5ee03a56b656140f33c5c4ae2d79f2a681b7998c2237b9fde7ac0368106d3af4530bac3041b2405a8f21cb16af4264ba44f442260bca4a771633f169bc7c41051b1485a748e58a0ff618903e63fdd4bfa210ce52c7401976bfc02d0ea0c1d934c76993d07a0cd6c02e1cc93f59defed680bd7fc13d644bb474fbabcf2fa83e5eb77c98607298342b53b08a4818322b193591a95f2bb22da1c7bb5719d62ed4929c4d6a74cf7ee21e75ff9c2d10e6142f2698140d0297a7b1456ae60128ba3b497decda8733414ecca7ecf067916a50b648ddbe1092bb19ef4e0861e32eec2434e3645b9d280c2868cbfed38f5764c653af765b767c84f12e37d333dde99ba9ed448dc547757d9977543daaae2a3ff2fa246ab5ab80b6bc27a957a8587f3d176f9f2342794a0acd6c1d9a958b25e99cc870951d8428427c83a90b408e6353482445095311e5427f65b3f135a27b30707a7f1483e38819ee5a94ab3cf8dcc8b7eaee1d8dcba7a75d9625c7341b26c4561aba5a02f4860076bfe11d79803b2c52887d7aa6f556365422786adf9a9629fbb3bc6f3371cc04b21c03aa9779f6f56a8cb00e3160b4f88eeb293e7510df18ee120f65437feb23fc11831fb0da1ecd8632b9d863f8027e07ee4655305046396cc2f610bf5892a8eb55e1805a1af56518fc3bb2c0ada610e2fb1b79ccd5e3c29163c263156ea6a25a56dd34e4ccc7530bc7b53b18f2e100040b8252ac8d3e4afa057bd9a655fbb97d2fa890ae04c676a8c64b20 +expected_shared_secret = 08a60196adf66426b4e7b90be90160e196944d012cc34a524e1e73ca125ba407 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = 2c12be5e04521dc3892ad41cbbd769aa8b79cc9801866c87f7194d89fa56329100f63788904c7511533ecc5b8e7fe45659bbceaba74402605a84f195925a71e3153827a5b417e0b994ac6355071ad98b1328f919d6f8c30ec7ad3366683aa3472132c801e59176711e2b20c251281311a6041ae71f96b9ab225a35e6273b5878ba6e362bb1ac896a557078495d1ed08264984357498d119706b7f4bb42a8700eac4e80164e19c2263a425f4fd18f39c2b3e6d70904e7481a14030b40bebc26be4930a05b4236436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b1261355bf296be8726b04a066138c714b229028b2dc5e5233cec7abe672a0f67572ee2a0b84b6f231a37bdab5006a9ca184cbb82948c46b6882df10a6bc12a8e637d3d437023b99197c207acc2157c43396be138ea06adc0bab4aa2aca95d5989cb6b9f1987a58d52b0b460956452f6c00d08a188030bcaff3e9ce91ab88dea04547baaff1d64bfe3c2f5050a398cccef166a6fd82151738b227c04288e8bbde4c45aa285af2767d17b4a66529a06291757cb52ea67865afa5390a02d0e93226eb200a03fc0e83203e08390af0875f2331b8076259d9378dc77877652747774b85064b878b816cb30c6341c4529fd112b1857d2c2c104a57c52e6c7ed5274873e43303238d19f21447cb45ce568e3ca4863be289e5917e38b4ae2ca117ae7a45b29c345e8a463cda4264877964033025b5a77e8824b928bd2305421b810732a1a2a96225cef965e46369cdf15e0b6129b5aa061cb88688fc0e0da00d71612a56085be7d24f88b4c2e6b7125a58c253c8272b04a0df60485147b85bc566fd34ce78a95a235916729778e4b521ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629e712b8e3ceeba7b32ec4a4b9e115576a6f74495a7210c68af925c7ca5f0818390ec408757170c8090c4ec78fc312a1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7b52e32bc1799b649497b4542970a50ec5a412594d50234cac594efd1b415b777ca759ec6c51197177dd183307313a3ea9b7976879b85703bb81aba1ae3727e962c0ac0ba7f60cf0cd6c8e863a0c6f395b41935ffe6b56d7026a0655d2176be3cd9537c227cf79243e09a5d04783ed170af46ecc670b16a47803ffac59744ac514d84aa544350510706aa408b91e1bbf4387d13e05feea35263446bc7d32648c8131d1b53d8da5ae774634b85bc77742128bb984ce4341d1b05cff711ee33aff31b849c66791fd5259721bccfc8a1836cc95c39540652a305c410e61a980ea5b720c472683811c7c596b635072fe7589c1700d72bc2a84106a296636107454a7a47c66a1234a3a3abd91cc7b049738b6ab7d70f450c64daaacf2cf9148c1806e2308f9c883875ab36fa20593559cef890006eaac701db9d80a762c448ad14c4b8dcd22c2a4b26ff23912e30c1c4f0467762b39689bb9ecca9ae56bc20c1347c6b4657d780d0a6c0abe904c9fb8b7769c550a11dbf54be2f2b4fe895b74002ce859228eedb676fdc15fc52c5a0679399205cb0b964e8e3576dab64f21741009082b04a9a4881c91be1ce9a68291087619b8922524222b1385454f59d355231f75071cde1cc1f96b45425932406380fa54653f521c5a178eae6aadab4bddba968fa037a94688643961fbceb633cf95c253668187784b09a7270993f6f12c96ef91cec254ccda64bb71582f20227dac5bdfcd535de1324520731747cb81cb96f13633da59318119150a002a2417ab8963b51f4fcb4c3b34ca9964fd5d94e57b23acbbacfc1267641da2083e55f5ca34695c7a45a283b15365ab9dab4118cb230ea06eb4a2fbf952f1342710ed07a2cf16e3145490a2a3a9ff308e0555e0015029e65aae08024b2637da6b0bee9797536004f9c54a782fab6ee67a8847143529c8564c37845f2c281664366205f51e8b577b19daa25162f291e21cc498a5599a48c439457a2c98cafe7e600718b282c45c58f04306aeb59e5d6ad6f3a3140903c6b8636eb2800c554c4753a3c981914d4c6c6914b56fdc26132fb281e944f27b4abb3eb937cc49707e89eeda1694dec921b6a6d9c238681dc2f844096af3bb25d61bb81d557478904b87511b5c2acc402a9164807909376b800b8ac970648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = pass +expected_ciphertext = 5aeac6657f61806a19b78e1501024ef9a194d5fecdf8a988f44c34a3c1f15d6801fc28fc2dd6776fa41ef415eadfbf8e5e870dc878234c74c09d62bb147c513b37a5767f3a976b4326510c958f532b22b9a7cc76f6c27638dbb47852692b64c8a87c2e74cf4d34b96e3feb0bdd497d1a371f8e4e94b72b6fec30769c07755cbe6ab243ea2b214880893e4b0d22cddf124d171f80b612520f314a225b9916f19bac96bdb88736c868e27590603be0873a1fb84a3f92ab8952206fef3221d795f5e905f61cdbc7edb33e06238cfcac6b1815b0637cfd16be6918474f2f63f47d908afbed7876f3d4bba22385098cdd729a568b2fabd51ae77cfada8849220513467f5dd720071ae404bce9324f3874e0b96d0ec919a4d0bdf51d71eb2cddc8a821f4c61d08cdb8fbd1a59775d1bee663fb8e702799192366a1b3c214f49207b49634731890e8d05712fc94cd63cfaa04f4e8580c5df6724d7e01d48675340b614115f94ef42336c84c08b13530cfb115093e16ca9474b2fe57a36345aa171217cb7cd811909f85abab99291ef90b31a697ddcbef02d6c1ca1c7bbf68bd1770c15b13b973a60b0a5db4ac5ea51abbf8dcd916abfa4426db43b0d45e763cd4f1430cdb7837b0a8856f8049324ae97f3bd1a7b6779c36e7c633a6bf99fe5ab377d0d4a30b0446978319e9407b265253200c98521750abf27324cf621a98ed9499e97b16418417c4570907e06404d117e89dbd3656d5cf8becd4effd19161f137fc45ff2adf02baf4ccd47cec32dc2092b0ee8c9dbb0cfe76f5e1e44bee72d644a3bc9112ba8c8faae23fe16a64d35e5edd741ccedc75975c8df8e370a3178541b3214999c15d5f2a4848585d31dec9d19e404e7810f2cc0172763b6c746fc7d75d6f1eb0d480d16ef597c1e9df50364591c09935a5274bdb7b5d0386f6cc6da6f50f2aa562ccb6368cfaf92c8ce1330b7f6e9a6d343bead20e5f9d9abeac428a63200c42127f163a30d1ebafff7ff582bd81e21355f95f9256687abe3fcd2fbb09fde72d079a955c9bfd09e31ab7827d2991834df205c3d696db33fd766e8ecba56a1c61d49295df83d4e2520313ef9330f07a3ceb51f3a2d06b36aca88bc2b6511d2730160f0a15528568507e367581936851db00ab92715b42f04df99884800adfe2692bf40c1aa82ff825d4a17675b7ef736cb705bb11524a0cef22b26029abd3fe0325940230a310a6bdb9ed6c6d2ca9910a2742cc7fc7538573d1f5737def3bb60608a44a1d57c1d5893ec14deed990a89215b721d0a6bef09ae51053cde3989e249bcc4490493ce55c1b623daa5deecce769fc3b1821b34d870bfd87869d55dd9c63db65d52c6ae6351a1f4b4c8b36e5e7d97fc6643b8011985d8ecb62c42d459d55186cc76785de1301e41c71f4c78add1cc9ff9bf578563fbb42c1c5b1385c32bd5c2fcb2605a9da5a403140370fb9b9d0673c3cfe22cff7dde0d203ab79ae5f01df3718940dc1a3744d14ef6434cf78aed1188fa8db485504a12a15ec609375188b7e95bd70294f91facb04a806ff935a2a51835c0e4f702ff92e01a0419088e01a321cfbee5c8352373b2ed195a3e89bd600d99d2d91c5377d938c014b98e11a8f3455f851c4dfce5b92eab76065fcee3aa10efb57b8fed365795b436ab8b38037c75551fd5b8924eac14d401d3158d0a24474ebba1c8bb84dd6a8c3618765a93e559142128fd549cc5af8f1e6b63798efbf9ebfdbc740ff683fba2f398abea3375b58f37987da855e5baa68d6596dea4901eba5bdc8eeb7e5aa28b8a8de187350ee35674b674023d493da86d1b6799cf662033f93499bf00ed13072bd7a67f4f7dbef7204ce31e6246e29abd790ae1d4d211e72f636ceca98a502aed3463c47f6d6f69e4347c9d6838f4cace94a318a0ec87c118086b79d2893614c3e5daffe2984d19dc25ef69e4c3b49e346c43147e040ec6aeab8a1121716e081887ce86ab39f543e69d662c83f967549abf6c222842d006c53b3854f808481852d34c25e2a73c6f988f6bbf75bba6f4fa099822deaa1cd933c005cc324685bf5e214298f09c2f6f74c80f628e4aef97622174065852e5b2134f4d3614cb78498c2aad54ea8ea563cef0cd786e30f94f86c404b5f8042797a67e5111f7050266129806f5bcf73b8aef3f29e26bea6ea9260d0efde9c35fccc9f761d8809a9de1d1eb +expected_shared_secret = 13f3b79bb1e5d20ed95c7165a610e122b5de6cb02444cc66e0f1f9ec44c27485 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 88b1b22e1b2cb01b18957737b65a63dbacc6828418150978215b85703586c1060740d56b50b40f806a7d2b83890d2996cdda967654506e096a9e59b69378152f4b8b2c1050a9e2bc9e20b513813db6f6b42701ba8ba3a03e80362c7904f240a49625435c00d040648262b44d881882de55cb3bc1968f5b3fe78bbec040a50972237800c378eb9ca8735f5502ac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c88509dc25276fac066199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8d514be837e0de28079e22b3f6c9991504c73bc2603161f8836a8814095ac527e0969c00dea613de63b05033b303c5937815b02ebc3466b5bf287265852665afa4d3dc7622650a0ca7438d896404e5b2a09220315bbbd5be37ae3a61953473e2be9b39cd71c072a97db3aa7546a9ebfc651500633a30919fe41a435cb5dd9b247192b233b676d2432132bd4cce04c30af99344e20aeb8e9b6545b4e9c9bb211e5add2071911dcbfdec072cfb76fd6366a74aa66c1831e1b6ac6def02d703bc9a9011480032e0b1a8e668cc3bbb46510b993958a455b25c025f19677f1c03828335b85868dc99c81d3b75d0042c3735cfc063b68630c00680dcbf561fe07ba4202b1045a2eaca9033ddbc2f3e620cff6158c904666927d61d4702c84aab51c60a748acb573704a5b422057ac3933233dcc6c6609cef96993ca951f89e10b68217d4a59839f261fac87375a38314f4b7ccaf5321a305ff7137e4207a9db03ac08370dd903a634b8951fd6c93bec205434ae6fc066eb18a4a1102297abb8cba62980340b2d643be20c067db031aa886282b03dff2870ffc455cf78a1657aa19e958df64b21cd9467a1306ad40195db3a9398c86c5e4111cc40816a860909ea742f8b14cb2309860b5d300253fe6149b236aa8ff44dc8d79b852888a9b2988644af45c030f5a69e93a44bdb454d79c36f2a1b13db7b395cd7b7da192dac99b4d5560fcbd96312483511bc8d9e738bbd4cb5e708cc0a02056a292180d06d0b0983a2748dbabaa88ad144aa1028edda8dea7704908440dd9a272feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abda504aefb2389322af5df12cfd399cd19b52cd8850510c37e6c087ac060e468c97fa97857e78712c17696ffbcda6f13248733cc03c4f08b92000590d79d74f1ad2336b9368572230ee472cc3d28a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c444929376021b7fa06f5acc940f2984b118164ab204ef2ba59de476e0ba22169888e64717e8635e7a30be99441814b5141a658bbe25641d3557f07b33d3027ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b162ae5fb9693607bc2fb279ba5b3bd19408ac8ca13e8c80f2139bf410e3065a0be22800c0305966832899753d342694ce56483a45f0d56848484cd1b9c949c192658e14e7c6abbaa51cb45441af9e46bac064376509d533718678a614c1b9e99796c0d4c8ac6ab134c4aa79a1c22692183c9f2af94836a52930680c974355104a05c0cd3a5c34d6a7b524b1dffe1459754066ab41a0b7315f302955ba23fd2b4588bb58048e981b0cb1df247874699021368277127912848cd65229c59617a7783542b289456337dd572c8e703ab1f22af68c962c9387e92d754027619b7f9accf233a10ac294ee15c3928934ee0b342f39f3ac5299ca681f5c569a2d87429bc7b4c492a9a09a48e17534e7a74023c0601e92bb13ab2f6918a44066e58433c2cd811ec5a144867c666b390841712d0659528fc76fc2ca17d3656b4b0673f682bd37980897b02d3608ecbb27b76ac848d55658f2606fb761154b0c516d0787909a59b35bb73e43988ca7459c22da04cb91c784f47e39152293679b41d13ea4908836735c3a28768509b2c6dc3d220c3db729437bea79727ae8156e2798ab7e9abef81437de27e752188dd22913e477230549f564a353fe17d513a72adf132eb0b0f3905cace01b05a073498c56221a4b9941a0223d4abadc87f83b6aa153920ae58cedb7aa5d4ebb6f4b34570079d6d1354afd1c30efb1aea9c25eeb07cb56417c134cd45441ed49182651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = pass +expected_ciphertext = f5ed4fc705e7731ad1463d9b3c1c634c6bf644df4f86f08d4aaf6a499f4643dae0acb11d08eb4f160489ade20211e0d1a32aaeada615cb99d309fa94a71f007172b3dd870c5682b88b81839063913eadf10ebd5f57206e6c2cd99a1d84607f54b2ba7f5d3db7ab8f63c97318819b078881b2926bd446bf7fa02728704250d34dc5471f72b5a9078faafc68d230f966134d683f3cb951130898c994851865aee64dff49a6844d28032ece637eb184c80c51385968f137acd1ad6bb68ebe96ff5d24886dd21f16294ec5bf3f9cb61a2d6fde85a2ee354890cce77fbbcc06df6e8341567e6548aefb2b111e66308ba49ae0a8152201e1543982449a22adc6867569fd2c562ab5ec6864b606910e373eadd2b5a19b01fdeb7f707c0a9626cc410b8f8a0062aa15ed499db23684dc1fdeb0d2ede15adaefa91487e54a92248761b09b689af2b2e3a9713533bfade1cbefad1a499e0e6246586f235dfec390e5001b4ee8d3916bd8384d3045fbdecee43378d3d4146f0583cca1302179ed3addce22955e8719e817c67a95b790b744864c8a6508fc24b262540112ca7b1a84f17ae26c61ea395e04346a0d32e21d35a5a2ba3e71ce4de4eee6391de568deda7364c5dd27ba6fd497e1555d469d6f87d3cf656cc6c16dedcb44a6aa4e7070ba0dc1045fbbdd8f45d3d2cfc8b3b73689c971260ea54a537754a08a7a2eb55bcbf7a02c7371e6e2a7d5ffa27088256a52b89d9c172b1601ecb98106f67e661adbde97e78f47129ee326aa8b25423c7cb4a57c60bbaebf204a3c520db9b9b5cd751b2f9c8a44d4151fdc5a0ee211c1c4a6cb5ba9331758276d87d57ea19829fbb67380794f6be412c4e3acd696dc305346f2ac01e1b6c42eb3f58dfde482162d8e5cd8fba4da08612b8f4ce2c870750f4205872bc46127d4dd564aab830844887c52c8bab93b54d31e2994582635172837bf1000bcbfc394879f9a00dca4134ae99677a81cb0801c9daba7c7a59e625086f6636e66624b4eed2d3bf32ae568f17cba3f3bd2b4b11796cfb71f7e562f9a02bb53bf7c1460f9cd9a72dae6c72bdde5edadcb231b876b233bf77920bb1b2835fb9449bedd6ee791c985136a2918329b92253b4307444f1aa7afe4a89d5f932330147b678d4092f26b9f094c1abccf00ce618a63afac2a02cb73fbac415aa961860031ce4eecf9e53f8a4daa8ca65af9955eef5c1a9168eb28c19ba1cf14aae597dcdf9476747a15cebec9e239f7c4b54a4b8e11885cf625818b827cd83bc054c2f54aacc33efbd2ae54d04514813954211879f9b20bc5438b7bbe951d30c7a0cbf52d5ce43dd6a485b97699121e64d4c7e7a378ecf72837150e8aecc67831130d05d052a06ecf065f3e24391d751e7623ceedc3f661e9798dbc252f2dca40057bea43807fe57afed578298771133d75e50562b947f1bd5f2c40445770688cd930ebdf9878b2f5924e0cf6cca6083b29bdd05ac25555244867db9bebd1c7b65af1e66d4a4d8b325203867214fded74a430415b1112efa11bf57b4a8d03dabd88d7a472a0677eed4956dfd6620267f2651d5209e07da56f538c64786267e701fbe1e57ac2f0985678fffc6a5e7b0272b27b457b25b93566e3ed346ceb3f8fdf005c3d33e0417b70d5d77250899a7e69a40afc8e332c3b315805c3fac44167d28ca64cb3f6df6c389818ad9a481492f271e14535d6085492ba4797c4cba39909fe1c501b56e5ad29a44c6c6ecbaf0b6383f4ad160ef563ca6a3fe6b22e880545ab934f416cd6659596b8283ee4c2a9406d012670f5a66ad44f5cc577c5c0ea98d70920926bca9c9b43eb908d0e25b96553836442d9fb789d977c677c6cd166f891ca95938f45732dbfa6d7296372f7a06ce5ad83bdf50ee6a9eacb3cf3d861ad34785ff5a0612dec617ebb27aa496ff379dc20f9bc5d6a59d38a5c922fafad0d9d3a7f6801a160c4123ef8716723f5fb9b8498fa1193a24d5107b0c5f13b2c527718aa413da53d9bac0b70c483835921bea069c5e1d9854e2db40c2427d21cc0f84a4dfa0c94db628c37012f23f637f2ef5e2fc0c11357891bd4574d42d9558b7515baa4667d32b497e3b9b5a20234c91f895ca8c2e71081fa6cb834aab7770fe35501c52395eb984a2a2d0ab8a608354812e425d93b6b92134eb877bfaf2b671be892a485ae94d67e9cad8a615dcb679efa56d902 +expected_shared_secret = fcf4227a487e719499f86e44ff74a5339870e4238c20731e0c85f00229f2a1b4 + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = b3f044ae2026d8b17f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749a52c8bfa2327db1a0258829bf7bbe4f59b1a6d8b8d3954db41bb4a20b0d660c21d6202759601630854ee75cc29454ab1a3469bffa989076301132aadec892978b3e15082bf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b507f31bc1495ce2d5943466996a0691d80405cc21b060568f55a18fec917106d7277793089e147d759988569820e0254ee7896e9797612c655e71371178a14b37b3a2c2b18bdb952a5295bdd4385c190b3d61136f128ba74c2c57612708f900c144093ae460c86c7a2f0b1903fd9a889dd7874f6543a2e112219869819c35c055813a394333ac6c9c860ad7505f8aa241046a984403b798e3211469cd1d8a57455702b2816f0b2b3ec60b273b102559099528d306ff23be250b50226b497b60b7540813f5b0c4a11732a6b9583a21b3dd2028e79a82ea0144ef34c32e4392a11241748351046b9454a50e9f90739d12a96a928e75806f24004b4a926f0e8769f90a921c4323d7fb7cc74c2e33248c30b774b795cea60c47ec52a01ae84247e53243542ebd8abc24a183e2d72247628269e108a5e93f11a45ca9561e8fabbf85aa61c6bacc2493aa93a38bb72421e8913fcc635ea0f2ae17ba41e43c5af3c83382f0667b6113591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc7c224dfe3bef7e0afdebb5f91b2532bb867ab3c08cfdb6a64ba1876285bf6463b9a241512919c9b72669ed252faa0aeefbb963076592f9884b5e60e42c2008efc08bcd1cc2bf31025c386cdf99b49283d6d7b0a24693618d2a2fac3b7acc60ec970b6d357b199fb6af3039eb6601bd57506cf8292d3181eff61cd380c525086962b58bfe53c3c0844431347a2f2112776818fa3ec2937b4b3b21c52be816637c38a68aa5373858e16c18134093311292814101cc2940b7f61953cf5971fb5ccae59ada4373dbf9c149869a0833bcb97d9bc68d6581cfb803264599a9cb1cab10a15178f6cb23ddce70d060b0ecc7a0feefa35b6db9800567417775e1df95ebd32a4e67616381b48595933f301408e2cc1951a095994428ea01883b4a8a8d780cf960d69a18425258eaf63ab2f2752aa411856b78dfd60c2da74c35f517718c3b117a98e968a72c3150105ca44fb02b14c439abb81adf5a94e2e5b7a8971848c4a9156e1445f41cbbe2c7c18785baaaac24bb87936ebcc8ef6ca4a951d1de8c2e6c5658034c1fde4b75dd1a176824298a669b0c4355aac3e201380c42cca5060192d06606e8430e135c50997579cd756da40336541a781e6702c0041c696270b65a92d531e964a1e953555628929f7fb59a7c2a5cfbb90b4f04b129cc011f7aba0942247908b22267df9333e8c762143c4b68909694de674ca14c7538604a7741fbd9004d861a04f63b74106729c6759718125cbdc40ffcc60c4aa30c7da001e30c889276d48b1329ac033d5365d76c85893da0e15590bcc064f0803cad5e80355fa56974ac577db713862545aa43747f9456b822e74e56e3a825e0f6259a3551565215dcaf4c9ce568c25d9c9c7471806210969146bb64c7af9a03ec276ab4ab10e8dc227ab491473f09718c4a046e84889d7c40f0bd0878675deea6c8e071b0e819f77147631939c035a8f9a4644b3dc35c3dc328c1c0cc6cc537af884d7c6000dba9e1e3062c2d43a30eba1873409422a5f664174d2f536e8420634558f4d427d3b8b48b96845b0f1847208c374f31d419988e9434a9f626da5258c00654b6789122de71788d6b259a29eabf83a42621b1bcc1924a79d3fb59ae6475ae6714296ba1528f30a66c2597ed308a3973a501cae96e1779813195805b12b0b008090acafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b1829428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3db0273551877522faef812d452b6444c4ecf3b9a9670810354b5bd57ba43aa5c4f271a03b2800f5290650a08ae83061f331489265b2f2a3ab1f4b3159103773b7806157e26ec1892e2c3d121a601777834b52939a658531646e713222943a0decb5b82baa4bac41f1cb2aeb3076a1a20a382698ce3919ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = pass +expected_ciphertext = d2ab81360e842785725a281e35958b2dc839bd1ddc19656a44364e7f2f094965f0d9516f525af183cda454a7eab8920adbdb00c96c5e4e8245e6de3630f0a2bf64bed8a1cfccd7455b29228a390ab8b9bda1b3a8bb5251f87d9fb461a197e06944979f4aa1008fa95f56b27d0caf87e7f77ad94fca71e26841383d391a168c300333b472263e90ae0110eac83e2b70ca139064d50264270ebb8c7daa18bfa3ce3e2f0d2b96777f04fced16c69602189da5250782a5f48f6a76c3bab6273addb195a10005d5d190f2204d20272c1fbb372224976b6e538c26acc90cb2905a528b7213ca54cb66cfe431dfb88000b42733488d89cb698beb53f262a1abe632a1d66b62e223bd7ec342ae362ea3b4cc322c152d90042c843d966997d18582cc2f828808b3015079bbf88e0ecfc1dc8a2a3f227573b31a78725cbc6a791669200ddde4e4c9c48752283bba0f1e243561e71f7ffa06fa837f3c70d78ba19d58c7c43816a89436acc77eea80390215ccc60312dea12f3d16280a33dbef2bc464341ff884dd332d00a2cecd1740d0a2847ac705766544eb7fe2e1b08bace10c083fa76e3543573af1a45230fa6c12b80e1b84f8340b16261a54e5dd612e825280cad56df2e9ee1a387c0b8bf846db737dd16ee5f929e5b5b2166e33c7a5b18732b7fa4985d1b772f69968202134d0c95d95be357a507625e97bf27a06d2301df39987f6641d32709fd228976f53624abcefee139128a173d7c2700cb912792f13ce697352b5bbf7dce8b1609bbe07ba32640ad08d8594a9cc82ad39e1fe414ffadbe5abee04e2a451e068ce4abf4dab9912377a31f222a420a56a50bac6098dc5aac5dcaed90fe65c894c95ee3e49955258af83493028ed855369dd119bb55cdb6c446f1026c9dd09186e35e813d57c671fd421cadb74c66d8dfb9f3c7b32de3af2dd5416487908dc13dcd39fee455e3a05235e3fc03a3a4076f5353fa4859908f8f0a63c6016b3f10a739175ad03cc4efba63a58381007fe1cfc6b7cc824e7befffd3a1566cd1c90325c73734c12cc308757304387db88d42fd0ae6b9933a9f3a8a4e95e74627995fbc77285cbaf944a2f5a5afd5cd722c7e5f462a0508de04dba5f728b87f28549fed395f892b250877099925bfe4b36129c74c8c6b81186549e1906c7fe9c2218dfb7c0932e31cad35e7ca2f7c0edb2fa97aa344d515c9d87d4a9cc6cf3ccd9aadcc8f9febb5cea1e263ab7e0228c974b6f726e6d4168ad170d167b893a1ea0b9f1090bc14bc6529a809b66c4726f6d50767831b3ef5f46f069530e12136406051833f729f0c7ad573e58897f7a24e1ff52e47ce2ce7f4467f6dcb98fff612d118665d99c54c92dc6a923631b5d919e44732a0b4662f2f09435098051d4e1dca6dd4e5032b58be812c736884ac2940425766465814c70ac36fa116aa4f1e9a5f8ea491688f39fe9a2acde2760018dc91f385cf181b3002172140fe7ff2bdf57ae92f0db586c9752145d2ed5af52604bbe4b62d12f17cae51a8db3cab56a1214b89fe1d55295e61ba2104c3208f11eec0c0b563e45dfa0bd029d92da71b923ed607c16392dc2c28f3e0dc58e2e54270ff0a11cfd106307839b992e6fd77dbe7b0527984c907fb670ba8f24eade12010f22941d6da98857549e6c17affd9d8c19b766060508811c65705a06208c8af5397f679931392975124653053ba92a66efe27be764acaefdae358b2228f9b56ae2e399aa3f808fb5d0de5edd3b9e7133c2468f732a59f7064d7ae615f1468051943eca7284a3bff8efb5812e6e1bd4ac2271a089b79fd5c613401eda4baea70a390feaffe0183985e108c1aa8e4f177faa9df5c941de63244a84282ff8dd7ad47611889ecb2d85f2ac009f4c11b7d56420827e008b502a3c138274050c37c27d3539d751159df30dc979d8aa4f52422d9960ea0013e4e53f474f05f360f9dfd9d689017bbb935536d72bd0bb4766649909ae713f5b47acacf3b688785c3abd48f334985a42bcdafdeea8809cbdc2c5223c7474645e015b956c60e0c61482d5c13550794ba19bdfaae821f75747e71672e596610ff807255e93086d68f90746fddc239d4a03da2f69f2dc484fdc5b0ab3e2da27f64ed0f137af649fa013ef667366a61b2378f5d8112dc289b31ef7c995cf137652156c9b2d42c2fe7ddb3a24f6b6395442876754cdf32bba6561 +expected_shared_secret = 3f8cf35d0ba76d75dec611e5fb059db5197862b7e5cc6b116a730734932441f3 + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = c3c489ddc6bd144a0458168e5b5686e92625325a8418565eb6fa0fb7619773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7bb2578e2a42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c4801107d0326eb24c7fd4612bd91275eca20f057c27e10b92e0b27c07a4d621751ef66307ce584708a5a58661838b56e2b2670ead04a9df7cf09bb8c83842dcfe4cfab4a83e75773e57b908feb46bf44013744bfb1d3cf98d34237b29207961d5d5cb43d6a49b17601743c86640ab9cd4a1786448c89e12adf884147e2cf091b66da57883cf36363611e04005be8376fe99c28fbc50092a034fb39abdcc97c6ae0565df82d4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7df119e86b92c407cccf98581bc62ba89228432a4922ee5c47be661dfb543ef26306f5301169a31b054cda1449cc2faaebd04c2b5823f58997defc48f6db37300b0c1c475a866b035639a5bdc4669cde9297d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6b31b8c529b84cb42dd8e2a48fb240c6b703c787590ecaa1f74044b5e295122c0a81c3a71322a2f4c9a33ea67d341a4426d60169acbdf19827759c144a271078582a33541bfa9367b757baef6890cff95d32d68f6c90338a20298b000e9144112dc22f4bb3117a6abf83b86b2b3b9cc244330b97392dfa3202ec7746d081f0a036360abad9d7028ab5bbde47403ca1a7c68a2c1679212ba707663ca412692049d45017f4993beaad79a990bfbb416d3072af8749f7f251dd51ba3c8b80cf34cc21ec923ee2a52ec3c981602c94d668bdc108154429508296805c156f05ae7908310fc176ba241cd35275b4c89e52786665e5798ca71a5eea5a721b51de6a78060a58f1a24da91666fdec925231c8c9f53d2fd270920092f29515dce0a8a2c6ca1e68bda6ea24b29424e22523a7d41773252e044356650aa5aa467b3cdb72be7700d268572d620279ca0668ab514243599de939a85990bc7cb640019bf8271efb7b1d32487b2e912e4f0267fbf197f1e3c4de63ad7455bbb2204db4c5995641892330c5b5140dcf0a8009d135a92352e97584c1f294e9548af9ec348e7408b448b85d234f6ed614834706a0c978ad9a08cc814953b8bbf2bcbd87071b597343629b3745d212111b7230ac9275c037d5e747afe60cbb9b439b06beaf537d6cc80bc1d1ca3db49f53c4a935a0226f37a85b058f32e307cbca9b7c62ba581b351ff5cafb198494d5abc4406e30932355754ab2a38232561319b0081b266b1fc714567305e0b27d3d6cb8457baf9242c598ac29520432fba3c3968c8e81078989380085178489eacb2c10c452079b1c33634df13d82b81da91ac85e43815f262c133075cffab454f50ad6c35410b295a5357e95fbb8a1d80964a40184a19618d2c0b7e13ab5828b60d461e10b41e3274363687cfc5849fe6badfa11821a31c2f724735ca1c4cb365b16ac43cbb24ec865a6dee75b7a6815500072065aaaf7b9af31214ad30ab984c57515a94a67b7391a37044cc22c9976851b19cd975a2c3be0539b213b9032928722029ac59231c90945a9bad4d39ebe623c08da1421d90fcd990bf8f8807b18c99a3799de3068a09912bcda3f5cab1089caa3eccc831f64bef79c538127b152f97946a264f4085c50299601043860d95832d15ed6f06051d12386559acfc5934cf4110827476b32af4498819e3ca252f28b48a96195f0a7c8e01a81d00c9063acc0954337d360b514906504ccce6a54bab7a3624130630a5f93c97af1c1a981b50eab54937251b9e1388842847ec6f4296870b51866c04458152fe3844cd879f335a7a1fc0b04094d2692cbb2f84f4a02b500d38fce69145dac4d0e4339d7978ef6e651c6110154046050b52bf29751c0778bd5e0409a1a2145bc87b1554b5ee209ed03ce01c251f4f39a67e09f2629a8024896c6c59f2e9a2e26523273e337b2b80760db1025f5b21931a82673be930ab5358381241acf46879650c208ce840b48041997500c8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c3a2b61f85f0b10ba790512d6422900db29d542ad96d8b6c0d954205a0d2c74810ec4469bf2b902811e5f5778a4190961853c777514319cab0cc90cc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = pass +expected_ciphertext = 32f41efca0bab79755ed200aab047a395fce9fabebd21c174b6894f49d4b576fa778917cff6d1507904fada5b3234d17c15d8d2ca1e2af38061283c2c110513958f0a1f416b37866fa0d1d7b386197d02552f50e43934034af43f2db61b3c57401cda202fc6b13376b6b94270f6d28d9a45e367a7fb6a3fbb35411c66992fd3a3e80193b4ce81ed09c985cc5713cd39eabc1832e180a5363a486d3a3cb32b56a515c0ef81221e8252076d85212415d0d8bb62e4e981fc092dd3dffbb241d3443df4fc9e65aec0db1397e4b2300c94db9b25a514b1efd8b309cde4c84564f7efce1033c76cf2f83b1d7e27378701167e4199086c7d5590879850c2c114a6a8367ad045da19e04e0f5b5caa127ea3ce1555abf5b55bb88ec58a20ace7ef8e3e627a847056776588f1f5356580d155b960a839731cd6fabd9dcf944b07f08818720b1bb8b77697bd55d255cffd0ba71c241de4013a5c8d8eb90336a64a99794a9da0bcd8bfdf7549c5a6539ffdd821e18870d4497aae172f0c16b10908c4f49304317567d43e3c567ebe91407541c90f6030520343797f54b96839dbd9b54c5fe6db4a33146e42ea74863034cb78ffd3f35871cf66c791079a77a05c7119fe94c068768c431772ebcfeaa41d71a95f581243c42e1a3c7f5390efbaae0d16e35caecfa8f854313df32a2fabf90fa756a3eb2ece0e8e2cde0bf47f85fff1f3927ce15cf096298271dfdcf2822cde284ee563602da0fca82cd90b03ce8744a52a82f42e8ae6bf477dccfa4f0e3949165c7e8b0328a78d12cf8e9dc96a852fbb4005642c48d70d7360150d5ea284b77e30ae24b8142e1bf89ceaa3ef32eb877721f3d6504ce0c3663cfacd1b74ec92817b2b0d90aaea3ec36f7aea7f1fbfa39fb83fce7411918c3c07fa8d4579277bdf5f06648252cf5b9cdbf979fc139534a508667f075aeffe2b12f0f818ceca7c684151c5777beb7e5ebf9bf2bcb4b06483f6f91ea2841bfd5107a6c12d5d808b31ee9c324a62b8c274e224f7b87059b2d71659900af62596c40c36e1f44092345dcf36cce43cce1310130e1cd4663fd29bc3e6092ad68b351733f6e5157da3d3a2b62d0cabe290c2118311589b11fad11b7d74c15ac5d074d67464f2b1e9e901b7486f7f600d6e45a4a0a6fbb9423b0f7b68cd71b388a0227cd855ed6903373c8f269dc16ad7b02c8605351099036bfa842e6417e114ee3be6991e338f7b66e767348a41fdb174da68ff22135bf267db0d509fc9b8a98335709c7e0d9c6ccb69d9e701d7bf7263e08defc4debe3b09a6f10835fdecf0dff446ec5cc9e949450fe55fcb5d323957b5da26db9797663e9cc0f605797258b3e1d3f5a700eea83eabe1b2c2990d1b6a26ea97361f853c1a250d6e5bc8f5db9da7766722094d9f2699e975de35be0469d98c1274a3dfcdf97f5a3e861e6894736a7c6d85236689ede2c87243059a9494c536ea4cdb08645298ed55b982aad590a739420949b203723684267b16ec9939aac3c2159a32372700adbd4c6e14fc1b0823087c518ce3647b30e9ee9d4038667c5776512b1ad1529cf17f0a70d9da127ecb0f536f668b6ff2476f2f1e204a0dfaa4b83d2b35eb677c588710670df1da6753a3d6e1bc86c89b528ee6365ed85dc0db991b4e5594e74388a1bd1a05770ca93a0e78d96a2431c47371446f04701750369bff390a4dd366e63d4a1b536dde21810d1cd27368e431b4c94096175b41b2e3f3374377de490b31c1b8f36d0485461454a51e88eff8c5e323787b8e5b1a69016d31e4d341280397f9ba87651d9f341eaa1b37aef6130f34484cc1673c4f0ffec892e859de2b4aa0f03be218cce765e34257430e5a8e99a51beb25bbbf5c6ab7a8801aee3533322e06cc282c1ff735db37ede240f47377067424cf56a75a98ae77d47fa1b1e95b6146d730a7e7510182da193b4ae3aedd82a8943494cdc92bc7a069855000e2acbe6018d3d0669c16614d0ab413e43f1062a6be89965f497ffed2a0825d4d455b6fac1120b1b2999af343a672c7a702253436c7adea48087ae99be9cb9cc877ccdf0b21cbeb3b3a5b2897766daf7617cd52088ba160148f9ef21ade71db2faf1535f0bc276ca34b2e62392767e8f8a48f9104b6ce4bdb38fd9a273cd36d15b27f1a9c7f5fa9018917d62c6ea3c9e103a95619dbfff5ea1b38801ed1711777ca7abb7450c0b +expected_shared_secret = d48544c1ac452c0b821e080e02c9c83e95252fb033617ce270f58e2974679fc6 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = d3bcbe7ec12d1af108849a2cea79be2da250f029382498919d670022f38be928a341b9783e164567aa87a9055fca176ab4870a2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463d51504bd6b62a44b0c0251afac229ea8359da303066531ee34451fcf796544125f933cd52f9b2a5e72e1a42a45ac9a80730376076cd57a289d5d97e4e1c5826757943471fa4ac0b7dcb737bf95f92f2b94f844b2b26297b2a44dd9013767b8b2cc7c1c8c83583e78f12e60050ea0e45e3453ea86166b70c21b0310059c58e684ade01b18f93440b0292dcacb6c9e3488e235f219c91914302d1495134e9c2b2a3acb6f4357c740aebb4534448bc482a07ace3b2211bc6cbfaa95ba4171f955ff915a1d5b13cf07184bbb230ce99c8a13264d3b98c0ab0986d62ca8e22286ec90029623d0f033bd4c13a26f08120f76aba45a904d01266520206e6a76697254b7120296820d0a0a29f662fb623c34eb282852832c044565860200222524b42cd2c8676cce763e28555b8e86a2c710b47d40a788513d140a41a65bea5cb054b73ca98c3061a39c6276a96269cca4597897c37b25f672c0f3766be5065a05b19b4cccb1a6771421b5cfdb7094c89c48c20cafe814d98d41bb5733aca166e044810704b1f9d632ed279275c802640d2bf754a99367b4a5fc959c8f309aa028ce21057fdd943de716e3f66b76660011ae354ec9475b4452932859d2dac38a853cb1edb09e04a367e02a92e89794a0c4ad866c65f3b4657492d0b575215e7926bf455686393ae7c507b9c8b9062c89b2310725baddeeb8a3079a7301b5be5f463f826ccbc8719e017550734812f1b18da724b99641e5406244a28aad89920731b387b934d02667e86b2051d35ad6820909924551430177f934650b61eae840d952b9f1f8b7e22ac6d6b005013439a01698644b2caf2b205044846d84075b715835a18c5df409f686a78dc675aee4944ecc806339b5cc8d8bc64d24bebf75a74207e60a37787c59c5e6875f61238fb43745e58bf3d2168c844b7c24c4ea2822f3abca76163a40a219d2798a2e1a8c606520c5a622653348a63980e61f52654b385575697d56c86abc5536ad67264a7c3813c1a1eb21442b1c0ff129f93810685a359fb13167e59b2df26c6068b641738b6ab82357c95c0cac43a21f867e005c96e1a4dd240975264606cf8ce8ff7bf0984770a282c969253189cb70cd3440a92c56319c9387733af98cfc8892f0e6736c6b44a0b952934071737a24a3400257e3c1690ec9f76726a327521afea4259d87eb6978d4c77afafb1b9be81cc4ce1197592bc26908c469863aacb89b13b231fcc9669b8accb2a4a61f641ca173dbd2a1494519b77acb0dedc284f068e5ff73bfa9109c1fcbf34b15f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f4319997fe1bdceb9513c2ab34691292bb961ddd202398b99c8f1aeeed7302262359be5b1e53689103246a473549b8274a1753721c621a0f468a6a9080a007287731bb8d99360689fe616c707a9c0c04c919b05a5add406a7d1aaf9d675922439e4224300b18e5d2966a6104cbc5a43786584ec877198dc8317753c6f0109a11c3808a50693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d4f05e20c2cf9102593ce45770da720531cbc50552f1b097a5a96bf291895ad9c0fcbc6a462068eb2ca7f65217f0678d0e25c447161cbd9029ec24845c5c1b2b7832ae41172efb8fabe6543ae3bbde44a0b9f926b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6c8117091523209ca8dd342e3bbc0e8cca579c603daea4e11b06bcdd5be898b825452a28d15261bf9abe00a7eca0474ac4c92b0938aa2a00854f3a665ea56169b3c572187ec88945d6c9637b4a8f91249b8614e9647760eb68d2c08c21f390e36370cf30ca0bf0b5c48f7287c822026e30850754b51682a0ec016f4fa0773b642d4c5481502bc9f023ddffb199fd241f3c977a9522de7f61eef4b0ad3166515697ec9ec5ea87796dc6a24da4939e8b5af7fb191f861abd3850e4ecb1f8b819ddfe605ed6a113ae4075ba67414b4690f59b2a6121928eb21c4d5cbbb4551d2c00fde22b537522663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = pass +expected_ciphertext = 13061f9c915937c0e1ec0a9573d1e5cfec9b9db980f404000206aecf2f2092abecdcf46a82a342db12ea41d20a231e64182fbf8799220966d5d5906546ea40a2d9a5d431f67784ff2c041a70cf20b03ec219387419a5d5b85e0df0b816bbc36204f9f2a9578ab785135a65c0d07c5d5cdbcea40c8cd91d552418ea8d3c0ae467701dcc82ccb1b25c96eb14112a09fb693d0077228b36ebbd49e791a00c87e4cf76844b13caed08488239aaf586a13df492c9d0d9ffeacd66441568cdf84c7a86ab83c38441ac585c6a71fdd79ac0de031d18ab0ef1f133fab18521c5a439c9f338c4e7493290e98c7352c0708e6b576a05fb0def5b757ed0a51346c2472911029bdc595fc1afdcac39d3d6db818ef8a7713013b7db2eed84d1de37258c541397d7ed5c37b63563736f2d0924704e02c3d457deccb3d68964e6e91ae519199291c4fcf73a6a3bfd87321937cd8955ae5ac14ae12638781cdb20a12b199cdda764378839dd778a1efd6dcfefa2607d7479ed80918a067f6cb198d20883b876c57756accdbb13095b848411b5339b121530f9237dce7a210146608513accb3f377a753a90dab9c9559fbbcb214b3f13f01db9d578370d47a484f60424a33cd0edbe460b5f399dd64f6759a8db56013f2292aae64f7372c89e8fcd186c17cc18ad490b78115904bf8e13648ac764dde042ef51b082928a1db8ee45d344a70dc01055d38ceb21d81edbcdea93ec2046bcebdb07ce89a672afff73b97e76415d1c2b8502653cadf4e0604fb62f6a448e0fbc6355c1d97a8f16852c7b164b3b77c7d8ae594b40300ae124ea63e398b1982695810c949c316654f8861269e79ae7043e3c79c81337663d1f36c8d62925fdce17782ebd5250ed6479a2ed3a8619b46937d7a01864a7bfcaf5eab26806613208c1117dd4fdbb2832d941d292d20d5b96ddbb1317f06a64671857cf4b9fc78d5593108db79db32cd14da3454fe3cedbdc44545bf72ac79d5ab6e1c95eed4ac2ae27c379c9e9e763b263d30ba070b3bcee5d1479a1af464f344f59c1e9a187dd28a722ff5f31738a1b45f63bb82c119c4934eb30b47deb53d77c18d9592f98c90454ff03489889d65b551dd06154a5edf007d876b28cc8b2713afd7d952d53dc13d46677a3c846a4568fed5a1685112d20f8905e333bcb2d962ae0abf9f2868acdae7b7f6e3132ba9193ebab674437e0bf85e37811473bf07113d7120577c956d484f2d5e828db5cbb3949998f16b2a0cd91323f709fe8e7255dda601dcc3a4a41750e622f9712f4583f325a7c4e4977aad6406884210789c0a6c891165f67c55eabf3d2a1bebdee598ead19754fcaefae0f5f656caa3446455e04c95403867657bbaf6c0044383c6af8b1041d322799940debf0b110f6ca7828a53a7aa6bd0d7a31192be03120c61543c51459d2a86737f0d1fc4d195bfb14d80039dbc2317b5223283cb282696cd88d08e3d1db6c310337f225e9fd3c1dc76eae923f19bfba306755115029e26a9240fc722998d89cccc7bb176d72bdeec70756aae129a7b9e2d6f4a83ec497cc0a6fa1f27aed10f5b90eb58be3deb3662f60bb2dbb704379d45eb57f76cdf88189eb67bfd072ad751d48d3c5b7162379464da0249bb39b50b58c479888d7826fada02cedf7a0be759b5348d0ee76a7c95f697fa52a887aee6cb0f7e80934d938ae8b0a017891f1e3aaaa24360e08c80706a28208e5ddb1c53ea748adfb05aaff3febc468c9aca5aee9047c3a63151d4e1b8f97957092b2453f3e777c42fa218b31db17accf707482aa9f93b3bfdde8c7427437d21201f3de3bbf703a98d694f50e75a4be82e1b9ac2626c384065e40ff1a6d43f194efa0633dbf91b531241686be479efee669f96d10434c33129e7010eef00e4f97f05619b502f180c1619f8286f07a6c978676b4026e8cb62b42f564d34f5509abdf230f6bf3b84ba44acb9f496d2409680dcb4343b36663fc7b9384f0d021a92d4cb1ac48ac62f31132d0a12ba9d63378474ca52cc3c70f08bf46efcc24b0da6b476c427b19e2c51802c93d34f33d6d70979bc8b485a8c932fd015803e0540fab60ddadba357e2b156d22e84f261b26f6f77050c97389531a6d66a17d0e9e2e0fdfcc7c3e6209634911ac774727eae38a716a978a8005c8be1c1c6717369aeab55dabb98b0f6d701e5df14c489597ee687855db833219 +expected_shared_secret = 6b8f4cbb3c4fda3c067d7ba48bf24e24258ca7e26bfaf918b784d01ae74ec57c + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 60c80e77b5c6ccfab6f463a63c069276c9321d8c961802a956f0b8f41307a73b5b4ea33828d1bab555c02616115f890ae7b1c5e6061a484825a448452bb26fb9b13d9bc002e6798d54238125477bc01babe0ec7753fc8c8c959916f16206a7ca31c7b121724e05bb5d71c648fea759a5d2b58a257e728230c2ea779ec4c55f2319cbf9cffeeb1f285a9fb0d4a391386ce69bbb6e37a548246d1061494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e53a2766642992881a2f1c8b7454586cb3822c125af4d70b15ccc546843100b1443e365cf31680656879f00e640692b94361286104c79af9c1cb2b98f01e3b9480c5b0af0988dc7bebb33bb3ad87cdbe09828a25f17fb323bd17a11ab961c236eeab89cd7c3030f4b437c09aec5f461afe64e1939c93081b44c8440f7b070fe982c16ccbc99fb0a8332739b641b326cc689c51c7ee33003a277c41c2a05676620eb9806ea6f53c2060f13a75ff67b7d1b4229443ecc4023c84293f3cc58c60a1bc00a3d1ad31aa88aa6d2923643585d39e16e5c8bc5e650a578d60584bc24c2fa2aad7b2cd9c99ffee6033353b60f506b95927dad7ab997868119b5976f561007b51aca6b36b08b03ae40a9dcdc19ffb776304bbe7d3aca167753634969cc57c48704a19a22416d2cb658e75ac2d428aaf9a13e6693e4d94df1f2a6559a4fdd16354c77129d32bdc3fa136e180d66842fd2a9540c63ae7412acb67b788936066af5b7fc44409a77a27017c9b883b705caa371b831c7195abc01530a97728708661d343cbca7ab7268b36294b2efd96f87a298092684b02569ab5911f4825826362414fa2f2b955f6a318bfeb18b12d058e4926ca973248d162164acb5b7a8a7641c9557a8a0fab208ac2744810397cc049ef46756e4d14a884745e73454e1d675c3743a5dc2546c424735813ab05353cf65b604ea3e44d8828c7a3ac9851848090b0639934d9b19ca7630844003a944238876966a62a87218714a4b3f89638a064846fc4163d03341840091d75b25dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae58012f2c3938c40cfe1281aa439486d5791e745892eb36905cb142a5c718f456b74ab213f4ac50cc000cfac943c60c3de626080b525c52051ea231f18dc126eb1c6fb76232d5722cee0c9e458c09a38c35ad64959bc64ff252358a5cb1b07384288b457ab15651935a99072f12336e14882a2d0b6f918933ca0574b49b214ba4018ca4b1373cc0f007b683a9a44f842610106de16cf202bcf0896c9506855bb4849beb06289b72041c75512e152183242a5162678d10d870aa888e218ae969c13b024729c7acd818971e598e495902ce92d29c73d355bc44eb544ac760c0cd58ad8157ff242963ae3cab5bc37b9c78ede033c210c59e20245fdcb51f7ca9588359e2264118ce4057dd7c6ade4bffbcbcba5f9433314cbea9309a0d86a15bb6f753abdc47149f6bb0eb339734aa1638fcc633244559a08af3c4b15e6bc8cdc63398165acb51925c7141cea32773fe5b0a64075d66c653e750cf42866255a9bf7d4b66c488f774193ce9b35ce52a164bbcc41f7b6779a9b35127ba7087a4b673096bba4048410778b18270674af334bb92475ce2787bf9a08b587a6d48845e44c6e04a254425ccb59b5972fb3a57cdb02f5100d45b43b76140c6047bc5ee59fb6e012660138d7c107285a2d461b20f1d49e1c206ffb28be65e26154a64df73358dbb49b77258fc45a15b9a80144099be67b76fd60b7e01518074b766211132e157efd507b5970c862d5cb870751da46ae460416eed595a74724152ba84229905880cb682cbe477995437125fcc23677c25fde14533c6aac694206aec917162b4efb61a1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d7872a694881916016c1af8abe353cd1ae2263cf417c013cf46212b3d5720af335d40b646a794ae602b5345300e30f4812e295f3cf07c2117cef1c591cb9a350ffcb718c64b0d76165e9a719ffb75f46b861f968eead3373c3cbcd6a983c9270fee433b2970b6f0947b8ce46fcad6518d5042d109ba53d324b9f657182bb110961e96a8b34c5a4b808840de8b71d0d87a510944a9973df9a900d9a6c272a61bee2200b4c80aa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = pass +expected_ciphertext = 67f0df1e6668d5a7bc8163a41d22f232639aca9455710213efffeabb29dd83664c4b50d538eda46647c9c16aaaa70b38270eea8b9c03b39344549b46997f519eb1b453047bd5c07bb496da5e22944d63dfb98c8923d9cefeb98f301f4a1ebb116e827ab354d3c5d64df0a46fc19cf47d7377e092f020f4d50399bec12f86a1207078d68e6ad4141d38f28ae3b78c0882d8661d87c8b1f681cc49dbf4ea9b46201de47048799ca96bb1759a242ccfaaf3088a4b462df9ef13c9e087ed63c2c89d12a130f3446bd42825fdb07e49de847968d72084dbcd79afb01f1db4f06829e822308dc51b47f85bfc90be5ef1056cf7889ea7d85952a881e6ac6f5453b83d731631c0ff615f2a45fc7f4e9493614afcf2dbe9f2f3d7f4dd706dd220bb3ac8c15ece45b3669fe962833f21477281abcd372dc2a1fba3e3867b382e9ccb47d39706a46ee2b04865d4f1339ad30a719ed0179c73a433b726093d9b77a0b63102bcc49fbb1b34a2be964f5b4c23f7b02d5f73aab5fee8fc25221cea8e4dfd4280a14c4f9ff4688a924ab533f9aa4b5bfbdb84d4a7e8d4ed59e0ca81e95b8c6f655c9e46a17f2e9159c261a39b32d3305fe64938c6610e93e1fc5c18790179e40c6559553a4cdb5b93f61cd9a4cfddffd81191c7a48800f4dd67228d13d2ef61b0652cefbb1ed9b6f0d1994cf08fccdaa4513652e1f6665efc38b621e2dfe238a6cf7c2dc88413e376be6eeab6b0b19545c6f41fdb7bd8abf3cab612344009f35592a5757678594f8626124a039bc16da995bed5129f4c10b1a2b490f62e1521fd47077903b87d10b69c1cccb654ecb9bab4930796bc45506cd0ca8304f313e9d43d84bd485544fe068f3f18e4f480f6ef0346f6e0f465c90bdaca8144d5261a1ff817bbc139f094f8c486167d7bf582f0929f9dfcd8577e0fbaa4b058ae158e7dd90f57269c30e73c18073ba8c21abd7785d522d9c0a6367d37d8d9808b84f05cfdbd79fc8eb1e28a42ce2a2a9d547995c541033517da3a7a8cc0efcd1cfecdf389469167d2ab323d337751828c87d6aa4631049b10d3159f662ecfaba93c3d890d058b1023cf415eb03e0886e86826fc6aea973cf32fe7efb5e39a5ce40101e0cd8e70ce92787aa9b4e0387f6765638f046b1d7fed2b4ed3c8fb0947965bd1dbba5aacd8d9d3a6fdc3e600372f404ea5013f75dab1cfc25436bc7cec331b0e462d84fd60129de1767ee0d4664682105b504e09c79dc4122d364baa14d464b8da59dfb3afa71f380c77feaa6e14045dea85a8e58a6e354498719f488c6a42ce369d25be4fe6d081b8a0ea3625ac59c41c388749de1994656990743277ffe6f19d938387970f3d9004e12799fb85a6bdbd206eec14b3ee6afc5b10622c8d99b642bb08ccf840197a77cb6d3af99d36feb114f2e619996a00ab57b9f44d56cad1c8cdb2584d9019114e635041cc65bdf6917795cf117eefa49d667f9788cfb83ec2f2eb1cf5921937c0e65ca4c2b254090834a8fe9f80960964ce84c0589e4de68c214f982091ab163574e8c1b005c655fc993f552b02c0576ba8be57c79ca9692dfce5a2cb72e3114ea9c7d4b21f94bb54cb4ed54e798a95cb7898fa62f0f594133254522b1e0c2b6a45a391f63483d66fabd227983ff3b178b74ceefd9cf41d1acca4c20dc1cedba9cdfbfab63d73a49e077f464137b5727b7aaf91521a66cfa4696f786f5463fd872e923fa180dd4827be09abead47e532583d465dca6937544d93e131b6f33924bbf402f853704b7fee75c9865f4ea022d1487c8c690c5a864f45ddb378001f31076b3c89be009f27e01a6582ed3bf8f8ff5d753ac7398691c6679dc4e663bb6fbe02b2ed06a91a8f95b940754818dc8c16f74333f67771e78134243599b76a6dc5e4c4028de18b6bae67f8ca8a4d799da73721310274b1566d79f5e3f9b04ad3724ca0ec8a6767f4e65dec7394a000f5320945a530317b87161405ce3817f647a99faa6d231035c4e2d252c3d49ac827d435c774f245c801daa956c6627208290fe57d7b97c913885fe0fba2d396139a1a56775b8cf7bc9bc02ea6acbb62561da17457d455d72c44edfae372dc3219100601181ed4e00c7ef58b16f0ada67033b83e73769b303061f68871eda434540beb6aa0dae4d44b4dcb1f677846111e7c939b67e72858f9b20798ac159669c85c279cdd11963f0986b86 +expected_shared_secret = aa9878a81dd8165350b880c4af6a2adb9e50a48b9e0709f069c02184d3785181 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 9d9171d1fc6308f0c7b2015fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff140f77a87e44960e6fc73cf170991bc57fde0c406e432253a2aee4b0beb4d26e0194601fa576cd89a5bca45e690833592b874d3b3cf303475f1140a0fab6129296c51b4a5b30650b8c26b5e67100837d011c2aa7881bfed806f308bf2f99118565cc85323410abc6e34520b818b49b6369dca3a1ac2776f75142b84c76a43223fe2b7f78544191ab4f0b9316c3b4495514118c63c1f9691ed6ec30670945da0a92052a7d2d11c4e0f8be14b867d4708f6fb4569b6081ba685c78e2c835e0bc29bb416db14cfdf3c98e8a4aa7161859e2cf74277a4c4731224c0649a01abcf92ea723784ffc290775282c256d433a64b705899398aca7e084ab6958c801b27fe8b39ff4bfbb1aac410421c50aa911706790d3c350b6126cf9242e33a359e21e4b72561f1368c3d2265b710bf0d6acee3a5286f51dbf16c471327612ebafcbcc5e22a5b5196a06336968976a9308c075816727997b7d52e34b648b8bdbf229aa4925b3e5167dd1caf619bf0d620540f29f6e77091c4b430e708d01ec9e2e0ca44e766c7643084af17722488f4786a720ec6dc4765e0f558a7a9c449f04333476262d65c4ba175a0e2bb29b524f8465a73436bdf6494578020a425149f3cc0c9b474d5eea98ab529aa1c97a84b54c064c8902153703618e5b99122d4402681a9c72258137b94091382888b4636ca983c79a944a4ba0169a730f7401d58196dc193742fc4d20eca71ad359987086aba19ffb05c0e09a0a8581844774b12beb3692e055df16b67706902d625590037997a3beb105931afa84b5fa389fe2b2bb2b5f521169f18b012d17a5ad203e2508958954b8fda5956bda2126503f34c571457056b333c9dd265bd9d4a9ea601620454bf020120d5a0e99f837cce92e20865dd7870a1ae12f1da8b369c814fcf63a9fd830c4827f6b151449879c4ba9691e68a02aeb89f362a9bd57909c3ac1e064780fa1c74ba21daa4b6684bb64eb108987b18be7683924e3202d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e51222c4df502c8415089255e8a095efaa822b892b2a0a17a146216282991833338553c8bb4947d892923010711084a19435b5c3f6a6af7f89457ac8a5ea4679fa2921692c8af459ad8cb22ec187dffc3425d88b6396cb7fb627f5fc718752658a5fc92539668c7327b90b26572fa8bfcf705f11422382079e2333af6b51e65310751343764bcaf5a981a260109986b5c29d2691f4a981d391175a21e16a13dd2501f5a256bb86169c63ba737296a5bacc65781b8ce07b4b8f28b173b42f802baf5f235bc06c9d752351980a72b52250269ad66a098fc9b68ad57c698a014b9d1c278f3559b361e3b8ba2d690c5380765de0b2d0e3c63792c7f9c8122b297bb8cb8381d6780505c253399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa5529fd8cb5215893bec6a64201629031b16a8957623b0619b33c6b90c78f4e21f8ffb94d1a6648d330d91096bc87093417b1ba6e14eef17ccf3923a84328b5b60adca0c4348d9198262b27fe56eff73566bb5123d7ca987a26fe9a00d41a2405fe31af48baa3a5249e4c6a638985669d576dc7c9ba575380e959ef93c2dc5dc15ca87cf3f98675eaa87eb5a51cc3450b946b810d05d94a815376868c5d9594fd02891637ff517a6597a1272b7c9933c544793ad167b1537b478ee3a20c8b874f5fc95aa46851fb1610453583b23c280838573770609344f14c4cc1da33720b3257a53a8e58c1c0ee500a3e4781a2cafea727ff3b86ccbeb9fb63b0f215ab297ecb1485589766ca828332942eb9c4037bd76aa1fd24160febb8dc499c486a6125c137b77597317f06323c901ecb7b17b75180c71c6b1646751f2522f1a7d13cb7dbe0ab46385aa94b84acb565f32470fe75b7f9c876287f2ad5b0b52e4b5aac9a43eb17b207943ace482b46123652f7460cc64427710603a8307ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc37591bc1a926d57c0ddb5b52024ac3861785b6134ad8c067c5e9a47ea96f57b40426697e12846bfde94af1b27ae4305edb932b79ab745abcc265b8c7a37063ddbcc972c26864269ee557785690ae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = pass +expected_ciphertext = c4285bb585926557c351391f42e7b83e54b65b3f0b324cb0e7ea76ca221109ece200cee8184c5b603ceb8bc5af9ffe39bc281953379516e808dc913990e3bd0561c868cfa85e4922bd862021c97a437cf2c33c64703c7c7e637e000601e061261bbd710f3032c129dd435a306de39a48ac1ad1d751429f7ddf3c166e646324a01441a855ca73d5be1f80749414bf383b0f9cc8359a8c254333f9a84b9527c2984d0c920f17fada4d49f003b64a9331e542fb2e846eeffd59127bccf394c463124ba68b43d7f7daa9a9157c72081fafffedef56afe344e1ddaa5f9af8ac7fc52730d49daaa0bb710972337eef7df81fdda22781afd9a1849f4a58b194febb65c6803d072f4b1bddc29f3bdc5a536dcc7096a37a14596c3f6435d8793a5c0c7ddd45a17a9aac7da2f1f742eb23e52736ed7f19a082741b46e635625c0e270c0ec06d60534bb7334b57b6ebcfdeb0ea6078a775d23d6937d601d44f3b3ee5140356616fd2eb904a76e5ff7cd98d70281e87d70c108f71a61a914c224f421d86db3db59bb51a0b766d79258134c0fec752c29075b4dcf5d5980c8dc9a618defacfb44cf5bc4ef1d691bf3ecd77cbdaf34be16322737932cc105ec490024e45c4d8f558b45f8d6965554d62ef1cb9ee69687f2a6184c54f22d23e2944ff140b83b967081ea995a7fd99b155e9d75961dcfbb4f04bfd42727e0cd66abf9b6f97f7b2adb0fed4032208b62eb3af3aeda3b3560f50bb29097c57ce059f786480cafb27eb51e1ee87f82b12e4ad4929b184e73673ed1ff8a58ea812099fb1c6af044021d0ec5921a25fc7f6c0dfb7ac01ba481cfa14ced4ae4a74af863b1d255543fb80ad53a67a04333670550fba396eda43812f7512c2a72e69d3599dbc247893429824f88b5c9acfa3d6c789ef487a530af12dc10f90cb95511020df2e402ee5fcd9d5acf7a2bbada0cb523a4b6c6a659a5ac38df531bc83ba54c5c1c3d9c4bc88df83261df4e048b14751847dbaa1ed6d3820cc6c4af84bb857a02db6c7db734a3d067076802620e76d7e60a0c7459061bce780b844ffdafafdf7877b1775f53cd9a44e2446fe96a9a9dfd3d1476b32dc07f1ba8a767c0398f7552f0ab5f23a77982e35290ad2e85caf6ccbe5396b3fa02c01a62572260c555fad2b21637193c266cdcefc22f7dd3469cec1647c9d5969f2863f4feb9ba753c8f91f35d94aa6a0f188ae11bcbaa872347adf646eeeaa9e67ebf44689e29f00fdfb7b71a60a5df52a3154c14f67f7893e6fdbf8035d919163b898d71c0610fddef4e7ec1d4e10357a2c6464e81c3e1eb2b7861c47f8f5770685c781167c96e03e82fe0871917a92d65d281803adae1eff3e8d43f0acfa0faf6853fa32c507990cf811e9a26886ce4c4662d38331a91623348129a8042d7bd92aa194e4543584f6d19fb302f408117e49b4ee623d3971bfb61b96ccdfb9ced039f300ed0eb75a2a8a5f22cf2cae4c9ce8a0d5b74a12fa08824744f3417e74fe1871917aae250f4544e7199820498a42a38f9656ece553229c75d8014c4d09257c5982a6bece62e102c99b24702cd5da41e8cab445ed69e96f811467d2bafe55fa6ab14031606ef8192de2cb71aead3a51cbba7b6ea2b69863a12884b94d2e1e7953aa5632b6ecc3d6aa5893c0f501c67f1e1b92e794a11167e4814071aa227cc66fb817568f84ddfd7bd94552545fd84030effe4c42b9bc0699574279f6c38146055123ad5e70ebed2116b625610dd0baa82487ccd85db7a69543cf0ebbcc87c0b96074d31697b16ee31d9237df7d0d7d9e7d0fa9f5a5ff615735da5fc38da1f5a1a854d98b3d4bdf0a0afb924ccf66039f9f8629efd571efe59cc467a322a3b71a1240398abc7164be61df0dd9a99adf7759ad1380d4782fd6987224130a50064119b16b551c3773fe11843f61b979ca171174ecd7e9885d64648f9288269ac2523fde655411c4e0fba8d123e70e2bd195a0f2c98946c6ee4f37be5dfc44cc002119d6d5aa21b9cd9a2f54acbb5fdcb3d050901f037ea9ac27a32f7f090df665362b59407aeaeb7a80c9e84e5e5939d9e105901862206becf2326db1005509177aa92e8dfee8302758edd739d829046192d0037ad9de1c6924a91e0048e8a4465c9342d7f07c5b7286887b19b775c5facc4b1cd6fedfd9c8bcc3d46a263f1156df776065481b3f9bb004a888c80d5b38 +expected_shared_secret = 5a23296c84df3d660e7c2a973c4e6bddad3fd814e158028ff92b234cffb1afa4 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = b2197fb4a3ab3d470a0ac937d1b37a3aa5b4f6a69bff4c57a8306ab886243ee6b34e8922f9b416faaca70a850d9aa008b382383470c0bb971027cb329cc91a9d89bd46b64e26b30dd01069bb8c99ec91895769bb93661b429a0a2c6ba5ebea62cc6b6923b27d9b99b8fe2a01db93a6fe6362d530093d4167ef35626438a949ac2f77772b1ffa65f0c771a2c18cebb2b9a3366f42782353b07961d485b7b70020a36c5375152f558f3e028fbba53405f58918541afd0b89e4092b0ec372ce48c4222a6b33a192d380a1a133272a6b2a66816f33e410ee02362f6bbbe44976dfaa4bdb99bfe9897894c254e5a51728858ed386980c52064ea3a1a837b5ba02ba34fa6de770b001b9a9fcc90fda64359f37b85f203c0ff5cf1e7c4681e990a11183d158269267722441048911b41be8b63dc139859973eb4578c929b730b1cc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ed91e02930c790bbbd6f411bcba06769b779e125ae3788d5b3844a3a7b4ddf8bf3e53274c29ae25f4573a459fc2093caecc197e050075262c7fe590b9a90dbfec86a2546e800ba726d344c0c667445b35872059365626c4b9af412b701e00392171b1f8922129123f05f3696f47c405739e0460590a52ae7c875f0a088b0e4924ef3711b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfb42645f3809dcb623dd48936c0440daf036f12ba9f3573623360ff00ab58604106fd820bba7a9e9b09b7c022262330627302e0852b70c020432235b11d750bb5a700b123dce093e25c993035cc1c3237743bcaaa3620a33b16dadbc93555c13ab0781463a82df942b58930cdde7aa1f256cb7860d0704a7d82182cd494bd803684c4cb4bc278655f31eb439c9aacc78ce21967ea07e1a6b99e7f8253229754c7a97fc6411549641018cbddbe2cd0fbb12f35c0791031735d4ab51c62e2336025f0b327bc82d92dc91dfe544db159319215c40666b86917bd2a889de8647ad658c16b9a3e1d21532011fd40b5c548534f9151f39dba83cc3170db022d488662a0223c750a1d4e048cf9157bdcb0c75185e774ac10be2b0fecaa021613cac50461a380f419a9fdf075787fba921a6a9f3ba49d78892771994fff11a57fb27dfa895d4c2a58820798a7b0bcc096b2f591a4c53bff56b054f059e21330c308a2ab9e403e5b6b7ec7574640812464710b508043ffc3b5d2092ac45b39d0c743ef1873286a6779c15669b854549a156b77d42da9cb39b868c70a037d9737746b6f1b91733c41c610977a5f66b98a167d9a15e4f8750ebf00876783bf23b9e023793b6c54ad3a3c2d33ab3eb0a2a7ccb9cf3f187bd8b358564bd9948810f91b9dc426588c51432c83a4d704677f2918f6670e611a410014838e9be4c12415cd64ca1ab5dc5f81ee8610adc6c29f5da8224093d350aa4b7988303411b1a55a240ab4ad7900a4f3718a58901371623dfcb7515db485d1736068a1549714402649b1cc322ed093eec5022113384b8e40ebd9ab8654393c013c99380be30e16d565170d2f20d12859e795c2eb28c8900910e3b294302d420193b540f826b48663f726304cc936fddfa8fec5304d2100c45d3a0b9308fd032b535780dd6fb7649410867e610dafc425202316718ab0104552393084ce56e2a36a5eac1b0cd9899e3fc2816f94b59cb76c22742f736afd60b9615130caae76f905cbc1414c8274b11b713cd049803796a8ba121a95e946be67418a205759a3a285aa69ff254bc2b39ae75021227c6c48a377f9e2267b3725666e6480920949c413a1e805a52f159fd216938d0ac4743ba060b7fd8ac2071c7022c66680d80af15736c5a3500826c1448e601058ba38c278df84a6e65357adf6735f114bc17011eb9bc48698893acb932bf6aa9d9f845de9c4e4d4a1c93a1c9bce1023181746b7559ba6370fef77671769cbb53b2d6f123cb800f26ca8b6dabc7c24560d29561d8c0581391329e73209551ba29a579cf40c6bf792b0801b1d24204c20139cac32beac739e2269440c02990568ef2a9cdd3756923a100d97c42d45b71b0432176238c8c69af81755b194a2aedd65c1c4118a320c4ac672e78ba69fd80828b7094227bcbade5536f95b440fc9b953b4e0729bd185ca617560546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = pass +expected_ciphertext = 674ac342e1ab9008ecab115b7d3f1e4038762a8b454c6c50e1a38b996005113d6e860beb5e26e9b5a26f588ecc4b4413be6f713a1ddcbb503eb2df7fd53c02840199651d55647ceedd1fef4d011065bf9e015b12ad88498b17af47f46013de7f54a24114909119c0a50b9a03b947dc88ff948dc0bea2c9d68f1f63380697d8ecc0f77362055566f20fde0f9f45e2c026aff1603d3ce51394d5b35248a542f2134d222cc152a363c1f23f74e47b4d99c5ebe5119f0d1577f870d2130931c78a0fa81fb2b6d30c79bc0e00feed1a785ad2b6a00dee79a0563cdb0ee084bb016ed5160a0ea71384b4984a184d842aa6d11125ed10036d2773bcb97cf16013e31f1c86faf5e02ebebd6a7e8ed2aee8a48acfaf0f3712145f33884e78060515523c4a36919c97885810c6914c531a81e5050b3c00aaac6257c340efbd2bc6faceb77187ed1f3618fd868d790ac779f7774238ccda3d29831dcbbd07c99511a4b6c684fd295739a1095949ebfc335c871990ca1f080cb433e73e650f5e35e2f1dd3d6d82474a19472d0a356d7e896823fb396d3690d73136148117f80a335113c39f1896ff38a5f9ec7c177e4d0a65ea69d43d1ba4c39b07a27653925953a187ac65bee722136d9a8b2bc5c5eb9fcdfbbca6004f1a24d83bf5209adcf0d058557188d862908001e90037d1f5c56b695159ed833a4ef1b094194027a00e4b5ac9499c740c3091e39e710828345581e2184f6da0e037a3fbfc47fcb5bd19ff9869aa6989fdcbdb1af2f88e81a8e0ffd2c9ce75bf1dec0f3a04a2ec61cd302530f30b055aa6d3894d7e65012c4a80c65ab856a6205914da7aaeb14b045afdf9c100cb3e17442381f73a6bc78fec09e69730f6d9538b617ee64408b446aeef30b39a33249d8262affb1f8ab4e914423b0bf2740331eaad94330b0334110f6e55695795c55df52a44610e2c45cd7e55cc55209752dd929bcef57c2380759747a500c0d2fdf9ce9090ce30a8b73567bd05e730f624d16cee1172ee80ecb299f35946190cfbfc6ab2d5dadb90e61035f03b50e3e77750f87ff88caf8759b5c03492b1d12a2b36059d50bc8a410d1793ac223f497b0a389078a43e9ab37ceb8859617b62635d037f05992a026b438bf21739d6a28157fb401272cded6682786b6e7d13753158aeb2461cfbcb5f164d5585f167a438aa18a3a1197665fc3e0ded017c96a05ec20c6646ef7784ab63a3bb699a55df6a29e9e7c7ae8c98b143d547b9684ac2045d4c6e40d39d0cc53e96654f44e1f9bf0054b5f9b7e61ba26fbef4f6aad23079ea348b8bc73153fbe9a5107024c2aa2bb8cabc255347b02111674a5d652a0fd98ba53c5d779edf04e16d78965b63a5c9350d26bc9521d6b5d83e8ca4cb589e4a569ca2f8496e40fd706b804e5787d7727e6de44ece54717870538175ad1baf32bc91d586de5270c68bc7ea3860654dc25036abfd40d2c752d9ea5f230adc4484e85fa6b8eff4623e7c9c1e5f9a2f7bdab3f26a410938515e1e77e7a889471c4cce8acec08cab2c6011e15c3e8cb18ab975c140a68f6dee94d06cbc632b4e548cbc074b4b3ae9a6bce86b2445e474090005143c773f15f018a6485e9e78cd328565fe23b438d978f49762094cb4da91ad0660c6d6a3aba3ca4ba134c165c23b50c72735b714c9cea13f03d85c237d295367cd6b545f2276191548457eaf5b118e4cf90086dab9297259b9fc02e53eaefd1a9d442d1498595ec00e4e8d3f76965c0c4cabbd3e37b196c7991c7bd3676f8d4b146e08299f94189b57d095e819d3070da10366042e12c169538beb1b7e64dc542d7dca602d12949df421923dcd764d4d1ba9c5e077e6cc9be88e9211bbcffe2bfc8a91a5492c590c22617b8e9a7c5b34c2b2dd65eb8c713e5b2913a6794e479d86af019abac8f933b189843add7d24b2b1e904f0ebf789cd694fd38dab5c39d71afb783e6b8556f402696221aef748df46f17baedb58bba11413a42f93c417c76fcdef3be20cffc91bf991302c07259b4f6be4707a44dd7582aadaf6245648629a7c31c9d3f39c73b3f498d49229164dfcafa8086f1eb3d3f383343de6d0a6e82fc20c6d6a1bc4e489427829b83241e9f3a02382fcec52fbe610ae89089ccd4065e1112c8acd41802bb80019e9f4465877efc5e13a22bb08df929013cbef970cff94b4b1c479d162383a37e1cadb1fec00 +expected_shared_secret = d790ec546719fb05125841bda9dd361e162ca4241e2b489a0f948b612309b649 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = dd9521e55c85d1ab71750942bae014469040333767dbe4ac80e4b3d6751f27fbb0eb0418406111c9e77c39977315526bbe1c8e06150a0384ca618001b08554c472464ae8b4b9eb679a790bf0e311ffc20b9a28a2edd52c4cb51bb739712419a116b1c0de65217ac429b091bbf94cc9e24886ffb623889028490976074888ca731ae4f9a9e0e4099f149372390bd2b78516044067201da469c7950bc9c681423b9a45b579160430add2b34d3dec2ce84270fbc019847c017d098bc4224bc9c99ecef95947e358f0f85def6837c5361fce2145faeca7ade0a612138c8cb26bfb534c2087c8dba4ce1f841e704652a093af188c55ab221123540a1007190453163a573d166617f452b9b2c7b9638b0201292dcfca46f4b9c95c1c8a47f44c19380a061b51942636c3bc8950f01186878004db1eb6a3b2ad5410c3484aea11a8d38881de278124c4c2b592b61bd87aef623de1b5b8b2d016a2d985976062758849362b2631a8a08404651305484a3b2dabda9982566822002ba1e83ba8b04c7be77d4086207e5b8310fc28812584129a4c03e938e950cfd43c3023a8774b42c9338ba497e853ba684c24aa03ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc659656715d0ffb8287b86cc0964d3e1b77e7d83afa733789709714eacd47b8bede99aaba2480002c0fb9136e397790bce939086ba75467340780cc31491e82172803a57129b3cfa3957bb70b114cfa99568428c540b187b98da9eaa20f3a7771d80146ac21b8908260c2cf79383031fb99ced3be7c86168549b8e2d2474e96bfe28158d91a16d5230b2f7b27d645c3b2096659a60c78a602457b0ef8553bff9508175b5e10e08326139aef678703d39693215d5d821811bb0868e483c646a4dbf0958978352b919c1354071c42bd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa3572bda92c2f9872bd19276cf66c31ac6cfed109bb36b77378c5d9a747637f1950cf36c5b22130eb018b607b74a270e0b733f12e426a2eb02fd3713f72c682d87cb6752a6a3037816b9a1278151c662529b54c52655b76c534e09cba4ccdb85289528b8f0201081cb05066515a3cfcca9031f386d6f4a411df397e526b754a0cfbdcc7968a03ffc7349f32036aa4b15123a6ce8d47f87516c717651d56cc7e2147cff3261ec76c045a32beb047760295e79f8c501c46b099bb7b508cbba9b099f612e595b41d32a946e0bcf26a0c5664b70971853b7965725d52bb371a03f456be855aa495a2e3d9925f6a7c3b98695b5e179e64c17410bacf2035e4fd3b938c98db2526804c79322230ba8455dbefa40caaba9757380944193063335b6721225f40702ebc418022fc2590d00f918765ac41cc6b40d39b45291af80f721069c7f73096b7b0a202749c70ce672f246209c637375e75a1ec03102940e8c17566b7c2ad43167f48a56c55c6b38d289d5675b9b224b7155905c814e175052a7e67685392448003d8e2815ba9810d8930051b615558cacd704202ad50f52890500e8be5cdc91ddfcb61948788a9cc2167a0021566a863b875361153b1a57e0c62f8cb11d3b3840f570b922e4a88151aec22baaf7559f724549b892575430383473b9183214104006dbfa356e2c31ba283f778776b43530a857c8126780e29c0316c64ddb1a947d747a8ed831135a8146936090fb59192b32b50327218125814b2863f2473b708338390ac2e507715136c8786fdcd1c10e2b0d63d2ceb6a4b0d8db6f8af354bdd1bfc6c71afb627686761d97b761fc0aca584539117ca416078c784972f67caadfe67f38eb1996e749e2f11a3c47c389d5c3f1f52d33f14a094cce5557154001ae2d17a2896ab4d0744e9dd4bbdedabf34d38c1c81812a3cbe4a065a0d6ca0cf3a9f5ff0268162a5b3d872b6782cab9149c52c2726079396b01866e00a20bc82208009f625323df535f1658a1ea29b933368992a89efa0ba586381d845099c35a299a467cce67af2d5b066d9891462114569a2261acf20cb64cf3819d0e0a4c20a153cfb5efc9c45501aa26adc5b26553b520a04c4388d665b098fe52b5aec48154a2ab5053279256ba4e6975f4764c77a5fac85275fec08d62534353b17764177037bae5f010266767164b307d4d375c85549edd3261c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = pass +expected_ciphertext = 2555f9bc4a695e0925a3689286aecff9dd94a6d9d5f865cdb52f33218b314f382a4b99b7b49b941bee78f844e1e55f28397a25dc7524209030e4e6946f3529c89eefe3f6bbf9614cc6ce16c49a79120e9e22742e814738fb25832919de2fd8f5b3afca0df5a96e78ebec279941f1729223e9bbe0bb67e1e3d7a6f64e63029f3ff8e90d6581981f6546cb9e3aaf49ab04c25fde5db04ad5436bf6b06409e735a87c9b002c69a03bd65536c9e8c88b68db3f6d8cb706d97dfed7851885d081ee8e069734065f2b8f796bcd814c3fa751eb3d781bfd5cdceedc12519fc1881f655208b315cd69f1b0066ee51f90c61d86ac47112793834de1ccd2bde5f6bd561855b59de7e0ab44823fa6890641d3408b723ee6be06c800dc55a710b3e9e45c6b9d29e6a6920d588bfda65754d1cf71ab87892319a196e7bbb531830a5d9f7ef3c625b8f5c64eefcadcc5bcba8d6f143832ed55214e717fe58132e412b5baa0f663982d6a01372938d24394e6c3e6ffc2b3c7bd61b76934871707cf1dbc128da0b47a80bd48fe193226e6e6d72a6a48eed3c0414a9c3ca00f7862bd802f035a60d90e29962f9faf780e2e4c110a42e7b94c1fd6d9e95edeb6e5434f473a695f211016c25dfcce088844eac0acefde73482b8a979550e4a050ec096d5e309489333bf4e618a198bcd6988578638b9dae6d996842bb42b1f34cbc398dec9ee4584169aac8929efe472abb1dd6cd6d6e69f17e7a9fea7370db9574b2e008d65392d79197e6b8e7c073b75c6621828b9166888bd4073f2ae59e0db24654695633329d4115a00e0a5549afb82ca19b2d013d83330b510451d76aca0a9eb51e7a9ace34f732cb128167d0d677b0b93e6551233969a08fc1799d68908a05b10494a2e98d783aedff4e6c32be3a5c83a04b0f751308015494d2fe5ce2d555a6399254eb53bcbc07b444e647fd3a1b89b9648d9c8fb64feaf0df3cc5c3ac3b6c5a7aedb1890e5882b20f3ed54d79e072b957a3802b2637d0841f88e6cb82145495e80a76557d938acb35087d2845a3d21be902da3f4fb184428f723b0655bc530f9356cb1ee3486c25ed268a0ac20514b6af2a62b8b6d045d329791523c6c2a7825feb97adbac629b2e94fe92941faa3593b809febd42906d109a6904441f56ec7f7cdce7f8aeeac3efad95ebb1336f656d0ced4e2acd737c27b3190d2a872ce59511cfa22d001b19267d727b91a43e8523e8c9b277566e03b2876da5c1177127bd1968dfff5b42ad817b1555dc5b8f4dbfc43e6abc775982cccf8421fe2dfa4f04153f5e7a34556946274a786a57f80a41180e7de70c2717f81715593b2492047407e2cea8e16bc32d2ca6038dcd78133c0cc6a3a339876deae7e4e48ce6f3adf352dfd415028e4048ddfc8fcaf745d8bede397691a4561952d990709af7ad591b9ed819b9a62af7d53a19bbf6cbb9bf2ec59ba49ca9d62b618f39884a7f9d20018157ffed0b41d1ad5416b929721daecec07031d7d65be2ebf4c06e9ff66c25ba99014d87db604600a6ecf113849929c442191421f388ebd1fbd5b8a3ce2d5df4e06a9a1df07dbb6ea4564980aa9c642019736ff5e290790d1ed79acfbc9b57c0bd5301e0e7a65378cab5e7ed6b74d8ce680f32592fa19ce77b38d7b02a90aaa0420f28164ba5b88d5a331487d02b9329dce23120a7cb93933d1cd7760bf581f036e2898ed25f2f441b7b81ab09d921f7f8b86a3611cd4f30cd5e505f85325ff8c14561d5f13ebbcfb6d6559726488aad10b15d3473193f7fee98f121e4a957dec525de7713af418cf578218ae8f57c655626b737930de46d83ca55dcd8fb7ef1972b3168f153a16ded056cb6d24b9d3e2eb37ee9185d5b3e407fc38f35e72c71ea407959bafb783465810ed4042b678becb92dedba9b78435dc4b3d575093796fbcfb6905a68be1f8cbe8f112158c9ec77a44b33ecc9d34550cf642e3110ff7943dba9491ecb7539972b91b092fdb1de8e96fa3d6200bffb3964c969e655251f90c4fe3cc247de08b8188031458e0a02f4795531700f8e40c895f8be3baf309e8a80b67b5ff081ce03eba0ba8d30a283429f94dc650f0b78a7b782fae499d12bf848bc2414f981d68594f82cc28d1ab3b9b0e4ec42485fe190fda4d9c019dd66e8c8f303bf9ced811db77a5ca20e8d323d76800325f8fe1251260bb1590d7882fe3e397d1 +expected_shared_secret = 10086d1a59c41f84a089c239fcd8f8eea3b22c7796f9c1f9b1867b709cb77704 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = 0ba19153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d3c11f376b1f1cd8776b6280cfb52559b6b3bf4716e9b49997911bf8da16c4147a2cc9bb379ac5195a320783213f62156c127257a469a428834d384b1ed48a8a576b240c1c55b84d61e248df45a52199143fb141b39c29631216a32b8dfb876df873456c14178c4360b8215c71e219c08c915a9ac02304c958c1bf7e65b3742bac539059eec85fb6cb608975b401c83b490094a6d1714876727ea34cd27b7385d7575ff49931820fd5dc33f3881554c25dc41a65834115e1c899ef8a080fc6c53b81b3804508fe4c1fe6904960d96f8c1576614474c9191c99fa3a201a4143b09ae0f3432bd13a3442ce80ec3ca3c94bf2b45fc398165318bd8d2683148315d1969b70840af5b42d5779c844c48cfc0488ec65b414837a965c65902c21a2c48a590ccf9fb9c6f9e45913aa0577d2acbbb29b5357cbb6b16fe6ba9abae44645ca68573b5fe325670f2c4b5378c040171ec3a25229b1c3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3e80fedd62beeec1abd53a45a7c33ed4117f415b77a43a0d7ba4ae2031e3c57c945b9abc3b5b3b7915784eace07e7caacf256cd27b28c2924b01302c9432e5f3a2a75009d03e36fcf7089fce58ce57492443323ab494c07146db2ab8e3263955eb373031c22da591ec5cc3ce0155f69fc43c8484a9e332e2dd433a888190b05747e0971005b8026409ab874cd65f533a51a40a668900ec109de60749250890ce91290a43078e3ac85502b4f34518886578c26353a6577fc51510ddcbf4ffb6b501662dfd1001d6354b47b0528dbbc0d6a18b58c605a91957c27ba354232751810202a891aa83efae7957ac2883605375778369589597a8b4f23f325acd8683c4b1dc3103002e1c588039e08a7c3c92137510391b3f75b99810f5c932a80a7b5d8164d999c131828a59a939d90a8caed47c205681973a38074243a787866588399a199c8bd74c8b6546168e255ca13b23d0775eeb727e3cac8b4305893185517274c4a4abbed709f2b986bc02592d1dc38cde048e5f63f15086f11031348a7a68e044cbe1075f1eac3c330477fa5124c832c2c880e29da691007a82b79611ee04b64280e51d201aea5b00a633e59dc0c20d72742a925d4cb19661ca864bb79a029c7100911dcda5fa1b36392d3432c187ddc51190c563d4c180dc87976a142962023301acc29ab63853813185b6390fd84b7d395514bea0b35b22d9dc19277ab7d0d602725a9ca3af87df9f96db8bc6a3f27891f9283bd6a4c4966cd26d3c96c2b4d808a2cd435abe4173ead728a200a43f8e21907020d6c19293eb02785571a399a81b8205485c54ac19bb298c8941dc06ed7796a39ea2c84d755a0e90b53f86ebff130c6008f2dd69af0017bee0c6e13a0bb2bd73b02431bd211a5fffab76f96c080482055837a6295209cb2a62505b846005ca5a482709411b5b94bc3781a557b2efd85b575621cab87aaad6844034c4a1ddb43d70687d968bfce441e7054a9c9905c114b9791e65bb23aa0cf22ad7e005bcb38b24deb2e7741853ee7085a93250ef7624be270bedca3d322842b477a507c3ddfe3325d893cfc432f07c15a1422128b5703d92812b87915e86a8f8de97f163caf5f695ef9994ac4d7932fb9629de72a988194ba13c996c2252968708e6468687b1a91063de718331027a54aea679861b1b6b6930f8947af72a1b30895f225a7bbf7cd7e8a857b6216115c8e98689b89c7686d282c44407c44eb64d3795d51665bd538c33a7915b5f7773ff20b6d289d2425a2ea4a14e8e2a349a78c76f8760082a1f8315b4dc41109a05c6053484a1b381cd8412df92ebed7c489ea3db9915a23e07c37f7c805e448a5f08a89a860b96c4bc7a10d4c30522cc900291a8504e72f4ca5229135827626c138173f73f123fe013f3612a27df9965dd78c6f1a2c3577c7cf866e70190c8a249a6ac6c1eb45ab61f9a021470135292d6ba6c26455cf0876c9633b4afc24779c908b5619ce1df7464e096aefe51b5f43be40b556e2c5c41503857f8a6b4adb2a5d8a67cb668930889d68295736027b5b1a4b3cf44a05101f1bd4b365b8c54117c6027460e14ba516724361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = pass +expected_ciphertext = 05d9eb9cf3edf93f6793bf5ed101bd3980b34678bf212b1cc444f2f0ac437e62c732b29deefdb3e75279d2e90deb57912831648792e7a4cc586a44e48005c8f1a0146d7b7f21300950c11d4162b9a20d21ddf22a795885f8e511d62c8337321d9a9b4c3c90196dca3342241f6a8622df9b138daf7fdce9bc9e795474e1f0fce08df25b7e88e1530f0b0ed1d5dee54ff93088355b32eba417101febc633c17aaa5d5e121ebe634834e64cecb4ea34cefb21ec8ef095af4d0afbfedd1eee96c9bac511d2ba607eb82fa5086dcace03a92bd84ac9c135edcaf68c935063c2d23f70a1bbd3a7095b4bb9389b74aab81a9ef4f48ef33ee5a6c0b6c94a52e6d8c2abdba8edd93017f9074fa6a9eed1993e34670bc0a5571adb497a80b48559f2d535c9072661c6ef2aa1620d93e00b9a75032b6585441d872ab950424f251ee65bd56803a71f8a167b9111498e2e936f1cd460e6b6cefa57a409210af828454c35199d3e307661ca760f5fa366a9d9307c9106ae358f7a3d52c23892b2a9b30c284a62615aa47ae6112c7ad6b630af9cf039e128223037c73f4e26e82a0fe4471ca332426709210b2a6d30ec5257bd86d8c80b2ec71a4e1801a63815528d6bd4c145c9c860b7daf7e0545be68efceb423de334b4dec869124844cfd94769d112bd6ce527b178d6d26a454cc2feeb128a38b94e217305ed5f93979728fd7168c8d1102cba2cb9d864666d109b649cb41bd04546023bfb87ea825bd6120d800156bcdd2c163c24258241a64cc4953a53cbeb8c2ee92195897e16af995172f743ffbf05664e60f22fa48f86fc7f33876c883c1d19f097f7693f0f1e3031789e400d6a6a93770b0aa343ad104d24907f5a6f508922433222321c0a2d2ca88acc24bea23cb290228ab6ca8be81576cec9fc80572d3dff7b714ac0996333d052787b73e3bde6e78afa3327b4049b0ffb31686456dc7875efe63dd7f2c64d4ad8795bc993630ad0cfcbd976e4e2d7d7d22f09127f4c5fc60b52907076be9f88efa8337124ce0ed05923f557b3221d288b71c8c201735661d19856bc973ea273a3e7f1079c604c91352251c512dfef663503b6b43f3d6ede5126306acd88ea27e288f8826e14b5a77804d36712d0fe3ba38ddbc6d3afb0b40e0a9a493ff38bb105c33d73359625db2443e7d8f50823998b5428ad14f67a509127e7b89b7703baaf17e581d293c0140ab760431a1a4826a673b5c70bc6bf030ddbc47b6c05f9888d3bf72e866ea07f97739ddf24d855d7a1742d42ec23c3fdbf646f3f6d1bdce61e5fb6d117acec891e03a4f7949e04f1175635511a35e718a7eb65df43307318607b7da11f0cf493ea7052ce585457c1700855faa2a5ce5f0e7fe0babe6f8183989ffc81d28026904d6dafa5a8f21f438e707871efc796daab9ec2a5f5f5e00480798d9d0461ea51a11dc6cbd88c2a0c0dde6fa97641b7f7c6b6f7562ef6a0f01f32cc1ac9e6ca352394ea1b38500c2d5e4e62a929789d6f061c2c0ce579ec0d5a3639af83b26499057a1a94f47acad835443ca6544fe9986059b96bd646403a504bc5dd1d09087ea76f49ae005333ec1231406c79077c1d33dfcc5b2c9ca0d0cedeee31fbdb4a63d7a3229a720567dc99560c33ed3296d00ae19bd736af5194923700d8e23a64480ea385373931f4504411f94028fcf177b203cf2fb32cd1a2822f37e1dc139dc985c93c4c4690545e51dc01edb733ac4148bebfbdbf3764eea61cf3925952f9a43bc4a4b342be1fde9118d935f88c8a1bf843e759a04a0c6cfe1c4518bf12849ddfbaafc94e7692c7ecac9348edb99a5ebd3006e97eff99dbb6b51579294fb03cbb2d8a50fe233724c00dc00d29e001da7b0aacd73fed9380d73453d929c6781869dcd13bf616d34940fed90fd493cff48bc7d1a07a70632a8aa7c5f65b12e8149e845ed3b62f6fd5c23ca8de0b7f2b02e1f12bfbb039c90eb202f1d624ffd94389e9e6f4665d4b1e7d3652645e06060d140c3c92e2768b82c137e1ee0ffe88699774546d38a4060fe455a564cf4575ffd6900de3c839e33500f6cc9b91982fc21d5ee24edc6b17b4d3ccbd6974a05e646d9e61e9417f6e37a00b917f08fc49f235cd2eef6b2d3b48baf58ac63d12000e9a3e518791b16a7c1140846ef8c79595c5b81b8a06d12338d9416499bf5870f5e4d8126499ad46c5bbdb29bfd34865 +expected_shared_secret = 82ad68065774eabcd6e78c027286ca7c7120987c4984e56f52abeb1ccc7a273b + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = 29d5526cbb30aa578643b133a0254d6e22c33ee80564e7424f0842b113636010c566eb59f9923a021b2a19c08bfae521e44324eb5bc9873846141ca7da45be4f8619b334a7cf52093b2177f4a71ae211081a096071f958277555709b2f459685ff22849a86375e157258d24563b8028a728c5eb0bef79495c1c53979880930539227c188c2027681236439085b41763d6378a4ea0254a7416473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c2716053bb54dbf1bc22f32e6d88c2a1947bb599a878b84f29021ead84a763eba7b9f3422466836bb6ad029543041115d638552cc2017a84ad4cf687daaba75b0c0a73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c2325a3ac19f9a5b0327b80f220b9122583f5d908cc21c97083227b568c47e58a2a7843d2141411b08f9cf61deb4a9edf41617fe26bf9c519d0cc80cd292585dc4ce5a90339216a6f876206732af6dac9b2720025b31e17ec47dff321b06107993a414f1509839886bc526f8051c4380c3faf4b64d7e3c9f9a76e9d440a67499322b37c4af9b26b2814a2b8b699ac0adcb25835d038b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53df10c578562a91b55ca04ae8530c6aba9c16cbb0684385704c15d302c1ad4857d0d1657dd85c536cc76f228641899188b9222f2b208d34222276a3c91628772c6245433a0ffd16b0812299283ac8d5a36b868b9fab4189aa64a0b90b606e695fa542b8c7c3ff0f0a46d5b00da78236d518d34756a2f32075480a4c15b7c27cc8e4a93180e6b5859120a24db2daec61a479cb039d4b9e6041e816c96862c2b1d616748444b4febcf7a129e6e7817950c77a3fac386fa787eba4157b720fc26629842a145759cc8fb652811a8a3cacc29571463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b304c0426ec26fdb17ca8fa5496d794778c49b4f74a58240bdd39c2fd6628011837451cc4389a43f3bb20959928b77394651e4c2cdc44cb9499def6b366d15550b41ac89707e57b271aad6113ef7a9b1575c69e35e4d75bcb0333e89c091603b7ea5973a277672a1c504cc2c45022906106b97d4fc01e98a876be91d88f4c908b892b5cab99fa878dd1b3b1688976c148bd0450216656028d9c2fcc3bddab2ce6541810cb84f4af414eeb863b7c7452bb79a96e790cca35bdf05b4c3b059801b2bee373da6a0c3df79c986e71a6788712fc50aea51044c2b82b3d201ac7a1245c96767f0cece2b4af175329a4973696c5deea91075a6b8ee2c347d15c89448cb48d22126d82732c1293288ac60bb3bc3ca1e208ba71054399fa4a5d1db7389379600c128b0ec1803b88de90369903799cf5ca0c5ea0b012b691b0a50b9011aa412509d1abf24e252e9d2cbb315361977770ed77310c1705e46b06a5c1c35fb5e5c9a8066d2750b388855e982bceab6b5e8018181b66717142cbc3729b13e2b34205fb06724ec13c3c2977e346e50a79498f94756069693989b77432f8b5ac8d2b06f2e227c4728288e91bcd6cac439b068e2017ce1c808c74098ec2c099d81b9dc6ab7e780c0c1669806e3cf34a1c1d5d002aa1c9301670fc4e45b64c59481d1cf6446468806683f57b3bc25b032aa40d2c188c5a2a7d47b41b4753d5f7a3b22bb70643942d6c35317f05e6acbb4f6794b1b0c3bd47893a7f9cbbb61c608068054b385a9578303111972e8888c6427afe099a1a07fb3879b821b25fd1699ad001f51b27acc5b2926ab2caeaa9341e1a627493f44f561eea57745a0764a840963024ff6c070ad95b285a74527fc3da894c06f7bb5de61a012547f87c1517b9aa5575a1ac9a30d858c912ba096cff4a24085c750aab463f8b956fb837ee300470452c6431d128b27472b5cbab268924acedeab3e7b02b2b201a44e99654910cdc8d5206496637e88929a1ba4436272f6b5ce41533450663f7a1a9144b5400d727fe6342c6cac6e2c3312015b571585303967422ed8c5d4b75e4f203bf2f86cf0370aa9324c47246a27d9076559c906ecbbecbb20e020cd9b6328857832ad8400666b943f8418f57408251b91ce341a2f63601dc751c0b301729caad8425f717250d5a249b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = pass +expected_ciphertext = 09b1f5d93b3554c6875326ff48f961225be029df22af93494a7edbd421193783fc0383f36c53e1d66ad64a1a6c58a52d1bbaa59f537e552ff276b1d328957b9f8a8d4e48c7b25c6e96e80ff1219f44d2d65e88b0fc84ddc1413fb4f56c018cf479e1c87916cfa69125c5ee99827bdb6b6a1f7ac80dc50830adc747a4fd99eb2603129b04c94ef1e431a9298c414e5aa87bc32831ce7c575f5f86a4f90650b99130147aaf75fbf1814871c983fb8676bbeea5ecd14562fc4b202e5de7cabbe52d40f436af9ac5b568c2d43e222f6bf19e6318d713d7a18eaaa3ed4c7ce5bb551a77dcacb90b68b3092f4de8f186dcdd80f224d0b9bdc2f7b85b0adb755eb56be6437a6fd4acae76a1ad77d97fc88e685d2890eede3fc7173e4a691d922d0823ac842af1cecda68acdcef39a0899e6cb94bde18fe70d7e511923e252570be75c238212022f747f7602579cef67a6f6d3f3b183b8dbfb9bbb39dcb3ee6ae24f32917fee81477b92bd0d6f69d6e7c97b9c5f83030e8331be2280a8a0a4f296b08bc62eb2581e1e1bfa9d5392d2e9290a396fa998da07cef57f42cf866f8d7ffe951e67b7701baecc00eec0de205d90b3115bb31c1da493d02662fb33dcb65dcd680cb548433fe9e0a67ec0b352a903390d5c2742d306276fd8f6fc3ae32bd2496a3f0693f178a528ee1c2df6701425caa647d0e0651809ba3cccf3e6db5418b15d1b4daaca4f111b675bd5acb277ce5cf2d84c5a2aae8222805fdc618df58be7133b685fa6094f7fa7c3edaeb0b7686a18590a086b3e7ed03b64e339de49cd79dae5f92e7fce2e7d71b1de3869a99bfbce25bef3a0b6482a9f9c6da8d228989bcb5f1dfdaf2ec6395a0d8b8979425f5395b1af29c992cb4ccf566ba7c0afbffaacfda474eb47e198e684db188096151ff776bee71275912e2b278933479a94cd77d70cf48d3a822362f3a12bdb95822b7728e7f48ad0af5fe375614c6e3cfcaa095df949fac1d1fb23220426a830b3674e2a48ee4c675f4bbaf1318d2e1f1b39b526b31af3e5f2d66a2c6c15d097e41ea68bcc5ea6a8da0edfe3fc37e0dce13f19217f5a901daf60a436aca6447780786300400eb0c82330aac637d7166e912246ef9ffed4dd1f55dc682ced90e4ba9d4ee1ac273f02115c4159ff14ea315ba0a5ba3c0d2b485dc931fa029bd567b96a4ca62ce17e6fff9a996b1c8052b76df2efd9b637ec1cbda1270e9d46c545d8ae274c831eeddb441f1f8b1c8b4af28996eba72e0b0d3507da9a923a6039be36ef41531d126d8498f83d5bc1df879cbda4a73da1ecd71914635ab28ba4a6ec32d6bbcc0c5d86ebddfff550837d253b7bbd40a824b8c2634adb9c4ae412189149d00a3e77c6a95d09ff7885af4dfd15d2c78cd616bf156e06d9ddf26442a2dae42e24a0fbb868c483dc5c4e896c1a3540ac8aa66935f8738e27e01c62f3af2362d0c27be70fb53dc09c1099d87d33e0c483f6e99d62bb5e7c9a1d12b54a1833569aa229f2224d5e95306abb2219497476da6872942195be95e9b2e95c92fd3c2d30035cffacb7f343d73b4cea396c2dbece97f10917838be58801ca6b3baa721e6db1c0cd71fadda0990572d8fc5c97d2facd4b365d8bc8c3c6104631e269c261d0e48167fa5b6bf884e41a00f855eb35fd1b5f17b21dbdb8cd9ae8d1c501b67379102c53fec015f19e6556629f3f385c8403cccd84c7cdf1133c65605051cbe67593a79701d09d714509bddc1f71e0a9863f456c865e824e041d5c7e4e411584c87d5c82ff9f6906d908a223e023e760fae53adf4267b6241c15d957d309aece790eb523326799d659603958886fb0795dab13fb0cb0212b84cedecfe4ae88a6e3cc9a4b9d503994609aca48f60a124120296065a7de2dc4985793c24cf6a849e708ff44236e0c83d831fa4ac8fce9b25947f8432fb1da499cbaae74a9003443350970e31c17b5efd6f317016a6a7a07894e13b8cf136f3d0f711acec26023be6ab981f12efcfe77438ebc093887c2536fc8a383164e7baa329c129ccd1935c9c0ca4a2a6267ab01e7afac3ab47c106d7b610563a5d822920ab3d3437fab93f3ac3ff1dff13d84f955df9a71776c54f0a86530f67ef1f9f4c954d90d5fd7ce1fabbdc218529089b29c43f116257799679916dd03081f3c931ccb214b1f56004d115afe31c39be017ed6fe7d1b95feb8f6e7323 +expected_shared_secret = 2d56c88020d399532bada6516f9a1acc28a565cf252bafd40043879bcd6de1cd + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = 5fc836b5e569623b3a02227b1c21a206e83a9c5b3ce1594eb9099174fb34e5b5c333e510ac2668a704548f02b47af007c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95930a65c2344510a450b9c59c24326c16cdb447231a026304bbcc9823c3a218989ef2352d445ca22b6b03186407d7973b4117c2914555acb33b4764515c4a37108306447f9eb200f8572c8467a089b824769b7df39967289a93b7f55e1a8447f862c1528c3dc4684daa9632417622c950b617e1a074b3b7ffbc23576a63857c1f386a0ff2a151652961137237ea346e691c4dabb45562653e26a806c6031368c17421747ffdd4725c02b40fc59737a75ba713311230cfea4c1be8a7c3aba9b589b6180dd701c4e704d69a0684a33adf1802eec804f44c2923aa8a577c34a4a678dd2446b7546af0021df00a431241509f6117cd32177da708a2d8472f8270e96a4bd21091f5d28b13fca8f7e2abfb57a9e4a522d95896b5811686e5b23d4577ace10eefdb9e1fd84cc51918d592857526c83f51c60d4210d92a425d7340a50423eea17b8be67325a33539ba09bb734eca0a4c365170448a126721484cf947933cc984cc7662da79d65601c3729881e9b4390a99b0ea62fea97eab9619d71b7bc282622ff0cdd0e72a3c8acb7449153df92e672c5c61b40e04854b0b523398a2634b727dae3657ed985b550849d51a04f3318892f7a4a2b73c8c301e2cb5aa60e5438d8962d8a36857f08c075948095c86de6bc34e35c8caa04772bab591e0137c4aca7c34598c65102e80ac0d677511b854a8829c08ea7766eb04c6047612aa83c17ac38a545a2863161ba3bf6a8005e9fb560597162ef1299d621b62c8a7b8c08e3a693faf0607081c6da8523805999e8b97056b5385834726bd7995bf6217c5e70863036b81c297eca1995ac48b6b7ab0ea85c3667370fabbca8d4c2d758a80bbf07839cb85d9428af1eac0d7c083567a85d13515ff399be3f5931d992c953a664eb8974a434270b47d3e635618eacd0989a15eb065348c34a19442db928d1e8b2b28a0858ed7ae8a5bc38087cc85515a344b4cbf529d7560590b3bb56de5331945c0c0b21d5bc8751d9120182c7348305edc765787ac9b784ac4bcea454e6a4c89132e6cd0a477f3bf43da356b66a8bd0980146b5d5137262b0062541960c0b19123a549ddf31d1c188171238259fb661e17363e12c57bd873c643222d014a2ae15cf6112c7fab407fc12b32c12ac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c699619d01b19919263102f5ef2a0c110752d3b34fd489b7a328638210307c6cdacfc6ada87190a98b0d008644b91aef65618507a7f59b89e7eb36998d26befc4b723741e0c35cf73e8041cf51af9832ba43b8e95e368974c1dd61ab65e24a87820cfae295d0ceb8bd6109b85174c80869716a6016ac8190df173ab61c4d3c4c37ae11593ac9a09c210b663bfefab5eebc30deb27cd25a8511bb2ae87851643b50d1b4ca5bbc66d49aa409aab9e7f3402ffda93abb53acd45bcc9978200e94cd4d617235b52d9297d4cd374b998698d82948dac3dd780c9336532c499c479756d50e9048432ce0156cbbd9c85f5ca06ab57b62981494622a74807cd881a58ea10a6e5c885fad611727441dfd52834d58b6408c7d06209bbb224a5d01eef9b491d13226684baa5a1a771971dd112ac668108963bb1864aa8ab7913917c980f3ac1c435457684ab758569247c98286b2cbc78263f1cb88478a931130b496b12f7428087162b6d525a8216061a3859a7a470cb9b88bb0c8b1e21ce4977a73fa5798cc814ccd1aa84370fa408a83e73be1e12511a59486c49c6afc1367b85231f47cb34c1a8f9a963cdeac7fa6076eb8a657e647466fc82663884d7c70eacc760db1b0be0b30779c98396aa3f2004976c8493ab90ae60996056668c8c2cb9065b6a2580a986d9853c071a02343b8903c0184991e2a71298269a17f64bbe1b6b51d0b299703a04a22e17c33b29634dd1766be40357f33a000a52597a3b5e4852473d886e06db52b7605df5fa4e0d5a0f291b5421e2c1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818db252cec8cb627455d9f792d7047cbe98b74eb26c6971be56b7219df092e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = pass +expected_ciphertext = 2c4b08525d8eb581cf9dbe8f86cf3137f7ed83947ac6d197a6f6554344eca19217a703e8770b41a1b1eebc8c22153a14a84d9c729821d7e39371a3ad5e0f276c97ba04311b98c31f7a618d7731ca511078584ddd84ebcca03d033048fbd532952c9011f44ec8a4dcfe1d22d09745459747cd7795f8e908ba3f9cdef9bea90398c100b173082249d99c88d2a0866ad714d1c30704f0821bb1098b3b4a77363d7437de00ab99f5d2d2af2e2cf8f2fbdf957283df191cdbf955ccdbe360dddc9a1507e40a0c6ee21e4f78bb8a13bb3bd8a1e5abfb07dc9ab71297f8fa045017028c25987b33b7224dd2cf40d934aa8176316784203e59e77434e1b705c580038c4b417867d5aaf5578f581da5656f639a4055c9a599fbf85f52af8776da6e2b49ddb24ade772026b84cf3fb75a2dd45fd94abb3561dad486e995be3f5ba49d0ad65246612e121860ca05710fe4549a401d370c1a67c58f9a19ed302d7446184e3eb712609584ded6419f020d537717e0b8be66b0ff6ff7bf6db9dc2da68c05d2a7bee7f52f108f9d0caadccf05181ec347fb7d581c3deca1623a1d9bc7e5654bddd5c114ff9588043ae286cd2b3879c2d613603796d07b351c821492a5f9efb7ea90f2d02cf57db9db167ec4b016da3867e805e7222ce2de3f2a7b27c750a2a936f1b8f8dab3e574679469c6f15e891344e8b30c6e7350831acecf4157cda632f66085e2f9ba6f1b4004e72c29c97fb16c1f986ac051a490c83a65e36c2f8858f0aaf8952ef8a18a1a83985c0536b1304a3648d216ec3326c3770e1729ba0231ba622c0c1420cca16f2eb1593db56b688ea5133d75af1bca6ddae050b82233c634d607238eb61c5e6a45956b4250cd460447e3a326a9821f2be6bf099f1d34d4c42e8c6889bde923a52ea32703830e7e92d2381a46b5bc62ef1cd38f0707e2a115b3dd7b098544fe16fbae58155ba301c89758218de4ed80113477c3e27d11f6b66b5dbe77e7ffee9999fd08070a58d357de3362ba47d9d974216fd2686a0a6d7b32de1795b62e90f9cc09348033462bb342fc68d703d0a9308dd4961de35ad20d0c2fcbde1e15ddca139c134657625abc2668db40fd555ffa76cba4d34d574de6384864fa14e541f2f54d2cc54824446296063ba060a2a87a1809dcc4281f213b5bd1ecf56c90aae7aca811558343a01e28d980f5108c14bf411b4e278d4c861341e51faf804b67e4dd8bddef46e5f06b18b01930f53615f7a8bcaa5f5e1bad9c9bbe5c095c3de0cd4a351066e11e58a40fc7cbea308f540becf55c4db86618b7821db519d7d64078c6e875e4edbfc49156e1defc0a7910cb0d7804e2cc651add9e9478f3a91eade16b683545362947633b620c078cd8deb7483aa8e9497ad64565863f360b95cd0463fa24b04e6aebeacaaeaee335b0bf18d36da9782f4e22804b7e00b132c0dc9669fb8aaff619c824b84c4ba727975bd3d6c39f9240243a8a9f85113689f871ae9ffdf7b0f5d186844c80517e05a59a30ef7c781ac3a5a48155dcc514970f92bdc370d7b8a2a89a4926e68116a1951fee233f4aa28f60867b15bb12e470c82154d8225b7f637028a785dd08aafef14ce8e7085d8b83575f65768a8e5538018efbf627aa38bccb5ebd61c3ca8e8652598af4b45b2bd0d4a6124977bfdac2659eb23248caac6c86c9a364698e20c2d455e34dbddb2f073c9dabdbc21fda0a987341b926b3902f055048365d8685509b868bc510f57dfd0d775a041acc0e013a9e7c43113bf16f801de8cb6783c8da303bb63decb4312903a22e87174847d33c7d88b8f6733088e0b4cb4de9299d641e7cc9a18e7907b6c9c0361fca64598b8844a08f1a8d04d0293ca131cda0fc5b66301b1488a49f2df5382e2f4bee501cb92d5e40fb8416a1970c9be2af98560c22ba517fc21ba01ba3d9320228aa851f5287e86b322219e80d16877289f80d7a4e4afd163d2bb59634a04a1a8817922a06ff73a97044a02edce8b9d42df44795b903b86fb0ca5a77ab055c8da28a9f6fce33e570f4c4210f22ccaa68bb10a2b1b077372b9875864bd2d8f396184010f52397fa17b0b26423851b0dd63f3befbe3c66769252066d2c712040f6fb95e71295147a5a643be1850203e1d02465b83e18362c7138890c309f246c9c42d19f3dc300a88cbb9d92b461ee7c228d353858dedbd83c001f918a4c5b397 +expected_shared_secret = 44052d0cc62801e0d9717c65ddcb560246cd901f104b4252eeaef903f7c26af2 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 3d8a9e39ba19ea979ab2c504335c03da056801f4c782d95dc2e163a043cf2db760edb7772c50cf5a62bda4742d2ea296b121094ab5cbf017755c74b6465137a1d32f4ceabdbf34a7471b45b166ad05ec69238b030c31485695a9cd615db68c83e457222d85960ffa8ba6c8cb5721acbca1a7b09b155a555f406a660c325c6166233c0500a0475931b27481a015ae521c7050ac2f605f032899ec655f0b662d7b65a3b21680d1b53ff554987a99258dda8cc711a18ad8917f838cf0a16d4f663bffb33ae9e3afe97b1bc5f9b1a53052f8907145440664bcb5570a368044151b0045515b94b7b8073615b2889a280e59940131ba50b016e0b8c6df2b34c29023e0773a06431397a68580c47610b50e025b0fbf374c40c1ba82a11b69fa9b6e522d4bac7fbe737a18085056bb7f7caa2c4c3bc5b6401f06b102a3b5673c7c8f1cb269438618f9717640c76a4f058ab864348f068691f95996072354532f3a3b6ad0e1448880cac03b6e2a84717158339c063147db0c586032b7d10a69e17c1b62c1ae5344483676bfe8928d637aacc4b613f24d7e2a46de3449f17b0062fb209cd9631160ce38a95361889b167cae272cb23f85bf34e14c789472974a176c567756c1c0ebd9905cea70cb88a55c68b476f877c605390ee1274c07cb95939c9babc97ec51df82a9b7d0908ddc3434208911142ca9b8620694bb3aa9accd1bc236a9a89547a26e44816ce3846f980c893b29e6e6c99580c2d0a905643f556f592ab03228cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77d40182bb2524a87e1cb511e9d591f06b91a71594dce26ca8b20450b899e22c679aa7abf5b178b1637f998502f7c7b4a03974a840c9dd041c43017d8f7927f94989f2a16a1f7cc9b09908da388a68b13f39fba43a391d75c76148444954063d9163b6ab1509b03863dfd62d94b59e849cb545dc7ba58502f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2c40797fc29955960dbe618cc5d21eb9ea720d77c3f8b3c680974fd8c474f9d588285609abd4166a45cbab974ae884c7061c6f129a1de7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb3f263bf774623a37bcdda056ce232b2b2b4f2e22f6eba975c933191812c9ae55d6b7c6c76c10983b02462e220bb90c946573e3e2bb87540034f870fc69b538780090c3b89c18645569b124c03680dfc10cd3050b33c16740c54916c5ed1604ec092793d097b94b4ca3474b6d90382d5cb21e8bc8488451af2492310b7239d9a46f8c868890c7b531834b2bbaaca7ac34651b941d32477193cde0a3347323b77ca97b997c429a2544a1590aa8252d6e0832e128262284908ab785543bce3e6aa43d4005b469eda56cb28b45c44329cf7f79cdebabc3a9c6558997e04f980c562c852a103fb40ae24e26a8bc8bf014690b9085f6e7bb947f2ce93550327a61900aa954cfcaaee412aee44cad3958555d18b59a0835c015cebc77242052f13a780bedacfcb9998df665a1ea24887b570f36198836c6c57a95de6349d031b2b33a3b6d52292ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c6890c094b625a5b747b2280fd300455739af8d97fdc39cf741128c03283f0ba09fbe19a24598e143b5a856a5b41334839a6188e769f78aa24673b3f69c51ae2c5ae98bab4b0254ce8c85204e6ae38b80a2f24c162427a66b09debdc8235e96d25e96132617dff682cd03896290832e3d7b5959331c7025868803a0c292ae4068f1ae8152221a4607bb9e4f94a5b98701e027a8ad0913b0bbd0ba551b00b0eebe302e5450681878992a616aef08a6c16175a5c22317ccc48200bc7452414080adf9216989669a560caa70320938c812ad12278588965525538921e5920580516156fd563fc732e37e5591e000b4ed9b93211579d21cde3a951395a21289576aa5c0b0c87bf36acc28c0ab51fc86da8cb00d23c40459088a1506d8a2168f94a365fa56ebd751a51c84342931a5d569793569f8fa21168ac2df9820ca3134704c533a399219ee79f4571b1152c95333c135e442d5c5984e55516f958ca38927773a2aa526b89b79522348c1244220dfa84c6778466d2a287a774141b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = pass +expected_ciphertext = 1ea5056618b2ebc32b56af994ccf662bebc5cbd0d03462802395fc56b48ac8dfb8ebec2e00a9bc3430c9e542c6953ccc18de1a47f6982de199bc5e0fd01570c3d5b1e66a294d97ba4c42e3ef500cdca834c35e19f437c64a8300f9a9081c02475cb2e5929b25d9c4108d3b23755d1395c1894be55d6471ed29559d2fec0271cd4d970741a77942721261b67ec50bed1e2e0869df8889932f0df5549604b1bdc152f0252baa17f81a05eb24c6544c538d4a346f990033f1786e90bf9219dd04e32f963a2333e1431456c77e55bf56c6cd0f115867697681db95259ac3331c9cbb5e60f514d802334917dacf5e736c739344a0fc3df794fcf773a4c2c3ef80c0971e63e05ac9dae9795af309858ed01d2da97797f09c5fe68b4859938e12622e685525bd4291dafb20e02a01a45f5b963e281990b091e7ee7949f3eb2245a31e6fd3c9de6163e752f676da020dedf22ab2e325d21470c13342fb72d21423bfa1457b0fa7c1b27ce04c5f49477d2d66cb5369eae5695643c84a233e2634c61bdbcc7ba0cd928210554f7aa0166def4207fc7555a0fff3c8a91dfcc9c5a2a3edffbc46d0a45af2ba4624458ab2d2a8785a7367f7d12b4f4db39357d25e64ad17cf1c97d0addf78b0d0c2c4d5b61077e1688650c9aa9d59f2f3de73395052a538cf713a4cf5d4f5d8b74c78403baae3352d0fbfc1990d7789ff039ab951416b649ffd35e4ff1d30a5ac5a119f442011742f12ca39153359d21a47c27b0f6e4497e7627cfe578031206bec2985b976be266a29982dd47cdfee81cec48e545b9a2290d5244f6d23ca942f06f2f5b410f52122a4c9980f43ea1d3a4e753874ab9e003a918832ed60767251a24ae76e05a07a2672541129709ed5f5856903cc261072fcab148e5afaca434d18aec3cda47866da2d59a0352f7a6dfebb0a4f1a5d4d62aed28490f02e3eaf1fb13020f2420b06bd4073a30ae47838c58e20e4e047d52316983b5bc6f478866740fab85ca2f731bffd4afe9ad305321e9a2d58ad70b62fe5b2ceff5c3387a94a67b33137db6e8ec4233f14db67a49ab2631978322325bab6fee732df98b148e258891ed365481b53404f8bbf8257e3f6c0433e36a57761671753f7d0e9106325e7756b3c21fc339bd5115c9787348408a96e96d776e1cebeb0bb547cdaf7f11f3203fcfa1d431874b31ddc6594aa62bdf58f1bd7bb1a2c79033bd1a2ce5e9f03e6b2985c73a5ec3d570f906f3534329bd8f593e72d7470515b2c813094b3942d6367b173dbc87b9bfea5c66d026334d413c20a50561811c064d540538e8dacda28104f34ad6f9f71fa848b8029e3642db710abf3d9747ce271a2c3221c5fdb13454e9d325d865037492a4fa5e84861cea263a3c087e030214cb076280e68eda408fea07f13eb8f40e6c01380bbb2578723b54222fa488ade248fbc237511d7369b814df3dacada41845434f6cd8bf8733c51d19a65e08359432140d2aa6cb227e9848f5ddae201c7301eebcf8c97eaf1f9d98ec70cfd4bc1eeeb30968cf906a8a8447eae658a5db0eef30372deb6faf96a2878232650179cad594c165621f2fc8c250dd1036b4e34a2361ec6a14ae69b7ae4ea909d53f21600768dce5e954cd770dc9430a5cf7799fde0023f8b526ed13eb0a4b55b90fd30e11b5d4087725496f9f435904ee3ce44de3ed718689cf252f062b782035879627b752624ff076a920270c9508eed81471a4bb58769d1fb0cfb5c71f276b2badf29fe78410927e5f754c10a3020ad82d5182b9fde9fc440d4dc437fec7ab11d54db36ef73073204254ea1e9eb2e0b94bb3f4684ce9360d37404f91a490c7afb8bc7fc80b2a1997f78f90d22778c252a9fc3778b9a47d5178403f33324f684b872cbfd36f900d0d45684194a080ae04e8fa8b7ff1dbea5a3c8bb3784540ea1d3bccb94e9820541b88bd4c7bd4fc8fc130381d7bfe45a721a3e93c0d4a996ad39d4788302a731c8ed43e635c5423c44e7ceab90d3fc177bf3e70d814434324cc8809aad09a73d1360b92270c643c14846f4d19efd1c3d70b6cbbe8caba8a898764fe107ff49e26cd1ef419d943dd68503ea0f74d82ccece18213dc346c239cf0511fa7a3a267cd55414ba4abd277643f30890f20b0f855ad28e0431f99195db57799f2b2f66b798b2f46b4394a7a4d2e2ce0941be0ffbb23954ba041e27d0597c20fb +expected_shared_secret = 2e95f47543ff640e6384d65cede004c4fc47e9e2f05649e694c18c7faf975987 + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = 355a23b704c6448bae0a62c2473c1dac43425852245faa8514b54c2ed51305047e5b44618f166cc329172668306984151c31cf04a9864267a1ebe30faa133fdfc040adc3cfa49a3c0f4ca85d7a52a72b71f217278fa787a2e3047922bd339176cbd5049d498708d65f2beb4ff3e544f973a4b9e19e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd39e1630db0b5fd819dc4002297a205898108050c9365014351f38c017564d6798a16382b6f34907a4850a0183b27243ec4123ce3b00cc682c1cb8a9d97845f5d24b5fc35c7e088cbed62910c4050ea6b76c88c87f9577941f6a5b3f2b614c94224c26a36a841c3b40469d2c0cfc366ddac23c8c2bfc401ad78c758a6cc1684d1ad400bad5d88417503ccf169481fa437e4a8cf78b907890cbbc1ab9f46178ee2dc6dbcc1604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11df700044a79a809112516a88c2c662965a2da9b996ff92d951337b4b9c11e7947b14212a6f3cf19d2c5d86cab5267a1c8065ec045517dc9be0783194bd846dffc50eb723eadf08ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a0128d52a34e27610d9a902d4151105409be06a11fd3f73c88b79c9ee630a98105556b777a5bc680a803f5a7b603f16643ab0a9ef7161861b3ecb5636a9529a24a59f17a389b61aff5e633b863065f37789a538f8353b80ad75b4ee876a6ca363b6679680115f4b9857bc88b845510027a0e9014621dda9a31e12222522557f8c86d29a499f0547e35a99d81b1a02147dfa3c45beb8a3026a23fd20297d20e33503cd49002a9fc7ff8200ae433b921bc93cf10209a05242788908f71bae849518ba305eef84597f654754a7808d81f2cb62bbb282911a0c5636cad75b53b454a5a923a5fc8e956c9cc527bc04b846b596c9b222a953db76485c6486907f898f6835a6f315ae20b57d3e56953170ea586658b9178c638c9c22c941097838af0123a601d0d4108b2ebb53b46233408ccbad9597633440ec1aff61743f0371ce62ca1977aaea8d98900f0016e5a9248661fbe5c1a4d261c5426a12715af037a5ffdb38b8dfbc11ee3b4edf289c3ab3995959078091e888ac0107467bfda6f3d35516ba7404a4733c8ca4adb010f7399ac5f14c2cf992fa812cf72f2c79750cf52e648dbb8c3b14698bb517166bc1f663594eb9a6c476c58bc103ea7f03f37205c5c355a2633b9ccaa829e3366fea63932550617aa96d267cdf4b98cfe3334aa0a5c7600ce6ab6aaafe7cfcce4bbbe2756b7cb10d6d6cc8c71b32a04cc652c01e2b62a73497dbd9a46eaccc382c5903fb405d950462ee6c87d2631ff97adb38939c4f284489bb9d1072821c108886842f5c1b402aa2e49d37aaae13b7c14b5a748c2dbc45bbe5bc2abbb929b613767a720ba572ca63c2080c4547c9024d2f451f25973f064941e814e3ec74b4c1770542b0782c67580b7a695c2ab29c95da2c18e4563a24101b11084586cf9a42ed62a2bd1570fc175f4d5bf50f8c4a196aea1953199143efb5183b3a905510623efa47c4a52522787723af5b5d05b86d15126ec6ba2201120b5a527324a9895f62959e24aa6f8c95d9001e7757fa5b3a80085bc48bb0d34388c0f6cb647b0a7cb992519922a730865a4032b51708fb6602b08d144336b7c7b65730d8677399436ff5711eee7b935d67054982472b96ccfe7279f1a673bd61757f7b951a5bc9c4b7e52c11a09f350737120e0923f8c1a2989f19a6faa06105391b39b266d9c768c658d56fb59f57020e0d17feaec496f729a810821fce59cebdc24e8b7cd3b869144225ca4b5a5c72432738ba5b939c64cf338021181765891469aa7af34a628950165a1328cc4c2b6874498a8205c675214137e47080624e250521ca34e394e829206df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332ac168abca2597ba39320653e8338303552b419c84ecc014ca3006b50a6f74b8ac57378f8a06006841f972b703a2b0daae868698b778bf6984dbc7bab537b29ec5462463295ca1581e2a60f5c169b494d0b7793af3313fee3742d84c1d20b6b47877320e25aac270e3739b34063b62fc171ec6a6ba7b62faa650496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = pass +expected_ciphertext = a9a4803dadbdd25f9c157360a733e6473bf476fcd8e9c07c7ef8da14841e8844307bbb0517766268f74bcfb218dd420a98d35ddd0a8040f32301fbaa6fa68a1c01872da756d7359ff2ede53620cb5b180a6905c8836cf621851ccdc3a7490c3b130750e41f5f3f2045a6ade86678776744a7c0c858f0dad0f1b986dc3d64a6606a51bd6598e0eaaac34ad31f888bab22dd334e1394a62ed4e4dec4479af116a8c211a2b4a1399e27966f4ce8419551fc1d79148d0263aa287890ddf3cfcdb409b5a38857417fd8a5ea2e27a1b276200b4e42df603e29887b6cd99fd56074e031d7073bf529cad46c715bf8939da99d13d1cbc1bd740a58a08e381b3b95dc2c269e7d2ee040bc7a6d06589102a2a9a6366307aa429a20cab4b8cdfdf12b9255a23ce45903b0f79b66abf29f3dacbe7fabe5b70432f7474433733868cbc222fb9609c264bd5738627ccef8f529590cdf74ec496e781e9167c91b38d11f2cf12296fc404d49c69db03037f080108b6a68f629ae9a392e041ad4c1d1c5c98707c1a586a624e1586c7f9a57cc291d29a09c5efede7bad2e376fd865cddf0c10ee8f8da54edfa28ad29977f4333e9b1ed6f30086551a718a57dbdc39363f95bcb9dc6c5acdc7b92751edcce0688598b29b1ff7d0b0402cca62e764712e355edd9a02c690d3a7b3e125d8cb322c791ba39fc98b4ce39827ebc6a32414941dcd060d729f6044c88d7fd34917813cd01922fde7bb410046881178e1f2e62fcc9c8d851d91d6fb68c49366dd0abed8fac5db78c4146ffb33b46755a458c0a4b20c3b70ddc7135bb882db104c8ae7b4999771f0b7289c8c78f2c09918be11ce9a39a1e70a29716ec439001fab42e0cfe7b7ca2a65163a617865cddcabf3efd2061dc7fe0015d1ec66c7d7b700d9f296168f2aceef7014d2fc27af8a7228808ac6958aadbcefd617bff5b055be0aab337a984967b1f6070a106424d0f8c7ef56e80302886de677c155fb5327a6163f0ab4f4fee6046b4302331a6b1b7c311eddfd0b5585f8eeae32c33e639767cfcf772f70091b8c559b7821eba9e8020563017c4103e40e2277a441c8a5bff7ac7cd4389e9092d3d47205f563fcd1d7fe94e576bd8051c525ee446dcf66846648839fc9f0a32c426a3814bb399bb83e81b044d0369cfa3a5639f184751cefc6afbb4773625ddf90d5b16ae0c2b0e1c515ed23ea478c27e1c3419e0f14fcc6702fb730f82e298d16cd24c9c2fd0b91d28868e50c3002550a8609772247c5dce89c4bfaa547fa0019f254c9afd4f9d5869efff5ae805bcdef07168580c5c9a64232e2d3e6eaa81df52e8c42aad842df32bdfefb109b33f3324fedacf21d5026439839b8667ce7c2853d8d3d8b463c7861a46e802a0ad1d4b5080c491290e661b04a4870432fb6a695014018512f3edb80d5474fcfe8070b7bb851e0fc2312f44aa1c6d7e243872f1934ddf29bc7f4e180fcf160665fc776cc970d3754abcdfe9429b5ee03b02ade73c3d7ef9125a34b03fe38986167d6eb3363970a99065d5e996d33026e0da1ae583609ae1bdbd50b97b0e33f5708548fd869c120a5841711a81a131022b2a1783e89d2bf6a877719cb8cff6920a1c159ee550f126bdcbe39ccd65d238fd8070531152fee56c5d483e06655db20524ce167f21a0126facde0023d3711dd6b86495d9893d8d083f4cc9ba12906b770eb564a67aca0f62b11aa773de85afe12c13a77e5603249af0c16e97a02122d0ec0f8c3d052510a352a610cd5cc1bfccf18c9c0326c0e48bcce9e05383d9e18b1002cd8607c920835cc4ea5145849e8e2dce0e8f8240e9a10080f52687706ae62baa42d6220ab96ccd229ceb924873a0030a5f0e7bfdb09015d94a5ce039adaa6d2a447806feffd4dc79bdb9aef5c483c6a6450b83d385a4e09ff84a6d11a1fd9b1634dd5d849cb3019e888824bb9317471a96590ed4de34b4334561869291ef471411c47967e362532b92feb72d551893f4d592ca70dab56d0b742fb754d91b049a571fa85fba31f6f86b9b5fdf750398b72a9dd5af31eaddb80960b69cd1b5b4350c591386994354814e8cc38f0c172be358d54b37bb0bfda5048cfe7498f12af04ee886578c867b2268ae289e7fe91433f5c2038ccbcd94ceb184cf4306a2b187d2ede87c9b41095db2d7e883107757d73c1d486d4447b3377da7432a37cc686b7e423 +expected_shared_secret = 42f1442e384b4e747794c944f4df154cde33cdff32bf35c2c5234919762030ca + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = a3637b6eda83bb2281b6320527e3b22bc08b5aa644402cb674059135d9c928bc4598019722b8af0b647dd3f02d553bc457bc763883288dbc461e775909745317f67017d3ab5ac283d0462167dca55e7452438529dd715f8af6438edb470b816546d078db0ab2588bb56b2c0e06741cfa28c997a128370c1d72221147f0218784633b45207a3b43fbbbb0d0cac41fe70213475e61058cf21797564b0db1a2095cf367b9561ac2681ab8b6ce7d240b5d277169c31eb99a4b68b92b3ed1ce6333b404e8807b32a0b03080664cb9f0987d2ef56308707b46b14f5667b2ace438701cadd7b4026cc5886bb7c0160a9684d5220d422497a9162d84c2500c0bc4d8bf20a904dedabdc56a92f153770aa95244220bbcbbba66aa89823289a2335898f01789e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f020779f6b6cca633e33fac08c51330ee0bf70e8a6ae4a7df0f2be54b10c6e418426c69c212a33b6b897b31630c6928cc4865606ca1f7ce192411c8d4812645c0655e23553b13c6c7c073e0ac92f35465a1b8a505de879998bae71608af9e943b4caa34f248f6dc679d93033b51c53315aae72d843884c83a0a711d009414c215badc32a5f74cfb3179d6ef26818d7c79393b8bc8b8d212092f2250101560cef4abd4132cb31996b85432bf437037d73516927300528763472c0d5cab08294154001c3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd60fa1823e32935515f90234b7613ad5ea3734a6c0a9422a97dc7042a0434a684083e8bbb40d2c4ebc08496a7261eaa269175c2a8a0aef21474dd4837b6b1c7bc112d67a1c175b2634737b43e5475d5ec9a75827f02091dfdaa20fd43cf59922479a671363737ab1cc307225bb4118d1a714ddbc08b770283061762bc098415e1923ecb3e3c92216d30694fb869b514a314db3fe8da5fd4930ed0979011d8b1fc723ab617b6de420482e8b9fe2a3874b788f0416dcd20704c20285247784477385a1cb219313b700284097acbb90976b94a5fd8984bb6b7121bb020e589804281bedcd78c1cf0aa7ab136c7e7afc206983887beb2372784a2c388a18b1dfc5e077703c8eb7f8a966def46225c8b3fd0f85d6e3a328c8c1bcb0b55d0341cdc866e1b040e09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf04421056915cc0d79830eb972c01bd3756270975bd63e224d0f58307ec2986699d5f536ee6c21f5de6844da70b797c8ef5b9a473624c50647d171682f30a2f3fd7c670595243d59487cab8d0a7727d40350f9bb7d984ba82d8cf39e817c8984c17892295e09ff674a684272cc710bffb263bebf1be44665c85530d13f891026790c2c1590ab6159cc22b5ec76057371bba107ffbf402631297c2c59bd05634ba628a7bea14f3985d2b5260fbc64664bc9ee308694f8bb3c4ba1f4ee43dc4eb4beac095b74820a2787aeef612c0c48afd0b20ebec9417b12c7aa50f4fc86558d36fc764c5b69bb4bfab3526d533de0c2e2bc1cdd4b897c9f990e8987bbaf147a0c4428ab68ca077a2a2d3af76261a1f371fdd503f6d9517a8bb0d53499d65208baae23c77580becd252d006bf27bc11b87c19789384f063538448b98188b0dca07328265f4c4b68de438d8420874625bcd12912078056c7db367a1598bf200f39d2a90e12c8dbe7ae4b780c8f5662c78916af1a270db365ca9097a37525ae347961b13b9b72c68dfb7ad7517dfb318d5385b7343a63f5026bee90177ff212bd6b639bb15d7949680ea38336891653d2c5aec083a8873362ea5e6fb4b0b1e19e48c1b90235796ba570aa0a3b1ea6c483d3079c71cd153b246993b86b506e477625b3b939fd9616451b90da9348b87c0201e087a5592a208ac9ab7ca6712758ecf4cf1af163ca3a369e82b46d941b15a42d31f8775e6332387036cc1bb31c5505d52b1a0753098d40b4999a74e4743a73e539d9e7a9514aa5671042a68ba6ef785234622f7440241a55a71f018a09ebab25f7913691bf787b781ef818c8238cfe5cbff3f8895a19c24085337fe10ec7b326da82283f03240a02aaf2658e04f7626da155a9fa8117eb3cf3f36d1e48baa2f68d158a0123691872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = pass +expected_ciphertext = 325d59b9061200e6d70e4323079618de528e667137a0ad81daf0888da37e09a44e25e2f6365b5aacb05f592ffe22abca9633af8e9e8ee20232a4d6fdecd730588047e1acdcd3f745ffef9ac0a4a7e13e3e5f7954c7f794d0d6f278cd162ba2dbdb0a246a046881c4c196db83d33511759c536a44273d5d4c303cc2877805914bc4c24932721784e01290f53699e15630ef12a77daff98d5c2cc94be874076ff6ebf7b264aaaf706ccc733a71106338232140c671c4a11fc0f07bba9ecadd304b65ff0443ab6fc0b36f4273d27fc43c22be51ccbc0273f7f3aee1381f42c48258aab1b77406a972d530504d6e644bc8e79b4c0418ef2440155edae167dd14e3844bcf0d6dfe3c41533ccf705074a00e1af366797ce6c6cb1d6fb61b89fe62583eb8b946ffc50615522c720b28f14fe52bc6e2960fdcd9734056b1a9156a8d8c8b1338379aa61e00b83fdf85013750ae75749c2ade870400e1b744029d4d542ec00ae4b13e36bb4bf5cd4d7f772fee9b58a90f254117a03c99d9e058b1f4b3b768e1e98c27877c40f239b793f4c0900c79d151e0facc116027ca656cb7da34cd29665c7e49fcd7cf53fd654cf07d7e0d40b53695814f0f907438620cda0f081c478f3bf23045931975f65214eeb16bbd0434f9909608b8263bfe87e85bb2af88bb6ce2f6672e68693251c60de5bec2e801f46d1bd1a4ad1263159911dde676c2233f65f39e099cfb65653cfb31f4921bd4ca729ef5cd5aee4642af2d3cddeaa4356fbeda7fc41a87cd86ac107eb72d9ced1bef7f92acf4c7b6dfab6205e185bf2146bce3ccce9a1ed814f6258ac33ecc63f9402298750b85e1e9d2b8070baa24c06b9143445db7a81e9bf9ccbd6f4f84b07afd389947da350495a6b924c49bab542a1456cd3fe8725ad51e4f2769ff78eb5a7a729fe8cf79209ee526d472fee75750a3db23278ad532c245014dd45477bd216a10558f7428c923fe0b7281300214578e8649b16fbf597e40f6293bd8ea7db33dd9ed18c8b3acfbd03850fdfeec3581d3a36f31bfd024c2199186e2b8f550df3fcf0b3f97d3de9d0765ca0e1bc25b60a774486b5e16d6f38dbd0bb5a54178c48fff479feecdf42fcb3967b6b2c55c1a3102817c7cb8db08d86533b41432811b84f861629862b9901641101f0af0af26420af7c4987143a24f349bacea254dd755cdef1effe559413a9938d9453b067c3f2c0dc6e9b0cc5bf9a9aa8c6021f39d49879e0576075c7eedd1f04dc618d869e8fb7b9deadbedd1ce48de13c1dc2bf893ee360104a09d7915ce6f150d0ec95d1e68e40a84ba5ddc6e9257a603dfb3fa048f47afdb48bef0a4789945666764e9650827fb9e2328665c2305dafdb20ef9800aaecd55ffcaeeba651284a1213514ed615c2dc252e5271a52f3033417e0dc9619c3948f110b234c08c8fe0481040d6359f17f5fb2eceb23dcb7c01c697e7c4067538f04c167b9a2edaced56eb2151479a48fe90843470d2e38fe2d0ce331d27717c5b5c6e98dcc840072b4fbb9d4feba36ea1285d30ff6101d78063abcfb0bfb623cd67e023208a6eddc2a9496f2127a9bfd41bf5f40cb7ff729598bb8bf40361d7d84097478b8ec2813328ad9f20593f1f41e2af4812aaa53e2cb2e61ba4d1563e87d817b27b2d827dfca0f2b6e86bdbdaf536641ccc1f3cca2b026f3a17aecef844e658159f626a04b301e8e40329ab3291993c673da1baa8eab89813e47362e39177f7b8f98f65f049734b66f6b2bc4672dcb2b1e36512ecaaf83a8a97377ed8a085b5aace382f3c269f6f96b382a7c06ab2669d5024d308cdf1ddbfc7f8819977b98854ae29012f9bbf684b7ec5041ddfbfc44a6981cad002d1a6e7887e35c23ac62768fe472d286fbc5bb023bfe4aef65dc227e797200e3bc6c016c088d3f0e59a563e668af5a06640b92138d7996fcd19d9d184c3346601e64dfca4174259ca1698fb80ec9f6f082bc2b03e400b3d81d4f14e1f4744c86fde5454186d51e2ceee89d40e8520314f576699bbec6939208614ad821425552a1d9ee5e63bfa7f98f16d2046cf64b261eb09617d40ab211e5f8078faaa32a064bb0e7e4d1567f8ba8c1fe97a7caaed134d6fd0bc6635256e312e423d78b6abf69d01ffc778612d0d61553d9ea634f272c56ded2c119cfdd198acaa00896ff01fb14488cae64da87805f5a9abdef3ca09f35e5d +expected_shared_secret = a50a07f6b01ee4429848806031637c8ef8da23f253874124452e3771ef98b6e0 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = 5fec35aec29b1ce3387af3327d49734cacb798c955b329bc90122ce43c3cd1fbb939518c68d1b044e0ce31863d2eec9607410f0a6b74d40a6f93e7a88442aa0111008d38661241afaf6a2101dca37e83aa4e8747ce884cc1c29725a19510c7688ffa569cebb45dd87fa7772bdd6b6f26e48c5ec93a1d66a2519c571c1b0979e28a82eb9faf136feb21152ed15502521176c9ce3e2ac3f3dc78fc620e151badeb9b400da2029f1b1c2fa70bc8ca232cbb69b0f98a39543b03f67c1544402f518cf5477d6c4baf11f8bf44bb1208ec96082bc260e52d2ebc17c003a7816a5d940cb0bd7329912c4239b2910d27cfd2a48c77501e0586a2b88c99c1da29d0167a88abc35adb5a79c76c89f4c814ba410d9b2da6994c5a78c701ca91f42348454261f6f7a23ec89428630c5a88c9e309d08e8b7e9b353aede6c952e36973a23e9aeb8edd83b256d913b9b64e392936d538a9ab250175544a70796202154350696c9056695d9c0ff730c27ea71f1562a04eac9c7d8b38d551c447362dbb1277e6408a09855d1292956c72b39e802a19573c620a74f996492fa15322bab6342a8f90a747c3a40af020a2afda4d37620100351f3a5086818260592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b701a2c5909034a748b9891cb5e430836036cf686d8be47e2cd5559e500ee617ab436306614c4f026c6e57021da6f3356ea54e924799ed6827a1f311c0a340280ac21b110ea33809ce3744ac4539e4e912f4a99066c26d3f047ac87ccdc55529e710517ff042a893848d5acb44191c6057a4659427a7c2345e9005135bb3856733320ca4c031c3b86aa83cda29f40467d5306dc0142132f1a844466abc1b28d94b4d1b98ad5ff80886b38d2a15505e8cc24d9b3273039c2babaf8380568a1136610ba3ce49add830785a1780eb67b6dd628f718ca7f1bcca357a1531999d96556515cb680e153c98281de817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a4007f1069e6378e7f0b4ae2b890dc84294627a10039d7a46b3c705493c6471b3cc9ca2535fb8cb19798b7d4d562ea33869383b28ff7b9462124070a1c17cd4b2bf4a622e054a1cc29bb177048a62ba8fe66fba75cca14048da8a41c2e3a13da8ab593c14d0b295b1b587aff8778823ad2ce3644de2b236bc144aa4c5c2dc697ae3c681ac10b5f53ca1d84334a7908c48bb7f5c93388186860c781bc483b1975219d24677487161b15407e52faf51919beb32b6c3bb1fe993eb15a4af84a64aba7d794252fae6785b1054c24aa6b249840b08b3fd47a275d1a0930b2ca6e8b0d4b498628418af01aec4c049eff55a576123c1e58dafc5b00c2373adb7cd62120b9a69541084100fe44776d3078d66b143b7536888c4128a2a637c66d270c0be49c99f1241a951c413409d16cc653715b88e869216ea42ff505ed71c550848a98315c84550ce83bcc750e4cdb8084f882a29a5a0cb6048b5cea41b9b8c2fb3c949fb928770e411ded9902774b529320f768445349a310c727f2012678f44967f37b0a7cc3d4af05fb285a82ca568e88c87168b14a84b90bc6297bce393aec894d7b464852bbc55f3c85f447980c904bf067f9cf55c756a6967b95bc4a08427a8c9d3aa6ea8913bf47a823f0050de189c7aab2dbb040129f40b5a885caf20281e39c178a79729072ad360876ed670c192912095a01e19af47f11c30a44af6165ecf290f885998b9cb4ffcb1b7d71c7a4c21c0acfc8f9a942b7bb266c49a528a28732f65b4038bb7dc2670ef20cde470bd142a836bea52dc4460c0e01d1ef06e7e7775e9a888cdb8c2e6a6078ba3126572886bb091a14735158b4aeff26a852b6b400698434c61031540fea976b523627e1c11f5e14c5d5c878c607afad79e425b62d5a56530bb6bf889581045cc4839857ea16bd9775aad3609d5287aae66c60f916df54c88e8f291d8019c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9147016c9cb2018305de8321f4d0c158fa2452347c78a376f399780e59a5a4e1c8bb793fa14cac662732805146d2ea5cd67196257362922a81e2177ae5289f2bca3d6b2b0168a263c642cf8e2a3ce8577151aba48b828fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = pass +expected_ciphertext = b12a9afb3a11faa33332ad6a1a156f0c2995d887cc15685d22430657b4c21dc248d54202bdb64d8a769ae9e170d6b3bed186910e4d7cd93da5b1d5a9c1dea5b7c904e4de43434d68ded70c20f56e277578a02e778bd7e3a9b54435144727722bbe5f48c68132c8ca71daee35006992e3fcb18f69dc7dc8bfdd1395603e81fb6e005ad8bb59904e92936f5591bfe301d2f74a51200e85735d453eb0fb0cdda582a8a03fc2e4d767bfaa7cf2a35864ad498cb466154d59e52dddea1d109e7457f223c554e6a07b3e36a8964b06191cc10a2aa3c865198b782dae79cc56b906121c7b0e196b1aa68b8812d82ff20f94de0681ef8bbe1807a7769a6f187a93f2ae2f8789cbe6503c29c18f52a3caa7749831fe27ac2f7ebf202e51b6e69daae1d1ddb94700efbac3758e3f35713d354d2fb8c2542f07e0547b5859794a34eacb931cae689791f44b0da435bae4088067b78b645aedc9a8a9250eff90de440924864bcb9df4c9b0e8c24773fc35a565cac3566bb4edc7fcfd6c1e127d321a0093c298d09f7e45cd14278a9654eb9a09292a073a825ef776853d191f1be5c742539a3ce6fe1593924918a85c19e420a8ecbbc1a41e06e6bb90b7fa65da2a1a2115786017674262ad9ef7af059fd5564415b24196f4bdcc74b192a027700de533fafb1eba5b106d78a15251058e6cfba6902cb07eaf5fad4116bd00d3c423bdf80da84c4307f959381d20ee956cebc112659e2e8afd1e5011e33821f54b5aad23889b01dfcdda799dd1ecec8ddc86e76f517584bde598af55ef21bd1d3cc8bb0bb7e130c02c9bbedf6d7fa415619778c3d9d6d415e02fb426f1b72a2dfec6d7f236829db3931201f9e843a45baead9b6dac19012c607593ec4cbf1c7f8b45a22cdc39b0e7b509741383c6a6d33ba789b3abae9c9e9a1f7a40578615a1334b5524f36230a09b25e89354f8260f5fdf22352162e87022526912debc4b6ed3d11287e0ea36fd44bc1076ae889b89ab1a40c471cd2e3fccef126486275fb51cb88b5b405f1f209c8a5bf1b87ee928b32191663f13a3bc29ade704bfb35945cecae149f3d33c5aa73ccaad926af794bae7224d40546d0d81cff42ad2b04804969e4a3e7d7314f830a818ec6253df06bebb888cb919c057cfba392c2239821bf2cfc6e8404c709cfc39a910ed224c9509ce391a059d3d4734ad580cf11e85177acf9d7560f2703c3ab59ab4399812b558699e62774cb52093983358041cf43123dbf493cee7095957c6fe7fefbc44efdd82b20bfb73a7432b764e23f617680047a79521451460488a2388dac0cf4244beac2c36dcbbf4132fa8aee7f546387ce8ad7263541f4cec45ab382392c9a22c8e288186b2b65e4fb809454aed6ab014a76d040f41b95b55ea76e2573faaa7436f676f2576a8c97af4d577cfa64c29e5c5fdbf951c2dfb0a4b54d416abe48fdf7722a7734cf67b3bd55e3393aff2ab0ccbeb678f83e6f93a19396435d1c19cda0037a0f1d2feeadc1a5082d16faa03ac90101cbc19c8586c8ab1abcc6bc55a1756870b52d5e120944e1c06a81c0941107a2fe75dbb7dd29db5be0c97acacd75e77a4bbf488333ad6b6f31b29397348f31c2ec4e6163d0eb836bbc654f5769966c80b10e7f432c5b5716bf963536afa379509d733a2b2b1816f2b9747fd8df5f645909f455719d18c882276eed15f3965fc98520a9deb12ebb33427457780335314427135fd77c57f22122ff980ea747bd9031403872dcbc9131e7bc13c6de77fc97449a08f73cc34fd795b575537258b9817d08d8185f9b62b8ff16cc84941e7cc7bde8d34149a81cc15c02942aa029552469003e0051e792c70c1ca784a3cd9f7be1baf79b1d7858301d3d32b6a51f363934e576843f4c86a913053d382026267390375e4f5059b0634ca08a8792c8943dd4ea558743dd579e5e4176c53a9ea43e864713ee282c2c5cfb009a426aaa9eb1e984144465895b8ee159e819fd1eff43c2d4c7417631a8d52c3c8735a2c9f2ac4bd03f406a2a2bfc6bf5d11e63d066a220a075bd3dffdb6fd1a712f2429be1ead3edf9199bcc55d63a69f9ab0738b3aae75e72c7a165a474d8a5f7e77f5d6c028b27d5843fb4dc4b4f740e446f597889db3411bbf83de759c473a11c6bbf2f3a2c506981defbd52fca4ece20039653e7dea7e8c7d690a179cc3dd72b1bbbf7efc32e41a108c +expected_shared_secret = c299f650b03170f5cdef5da81e52c2a094b11aaf58426e8c41e06a26c7d5ccc1 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = bc859f23d76da58b31d2677f9de1841e50c263257b04d84419c3892d590b286088e35b9ed4a57257ab09286934a0e63326876eacb60fce3b9642019560a5646f522fbdf34dbfc8599829105222193903c97101a8dd4806788a8ecc223eac5206a8706f38aaa4dfc87181ab07e37bc3106590fe18996e5b88fda7af242aa56e42cac7113392317604cc89e1f067896755ead0cbfa201775329d2c8804f485cf61cabfe35a33cfbba7d2426ad2f59a98625315633b0424ab2f2326fa8488fa92895ee08edbf32f6e318dd22a5719d3c4782bc1787873e93773b310ca9b036680ba69acd75036952a330abbedfc5477545ae7b09b6f3467a900083d4677c6b5c0dcdb9886f26b1c9b6e180b8f5020ae1a68b9ecc3a154a084a365a9035841700966cca311c09b13fdeb4da6517c9c3a9c3cd9c336607a53f1972856b161b2878c5689e8ea7124cb768fb48efd92489a1bb3660422bcf72ccbbcbf0d7383ef47586863870620c025d6b65cd5c861234194448a021417cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466b528b2fa2eafc943b861c78666a94e1091efe4ae69010f0a139cd9984be6f23a237cbc1345a53fb0489fec34ceba3874f631f4a34598a7bee966225e2b251ada212b9365bfa2613bc4b2e0962493c0c461361fe555ad61bc6dd54b844114781fd37291b7c3e7090cea1a20c86b3637011493332925f503b4ac6fb625ca41601995869443da8d82b81412012dcfe22eba66072a9cbf65f34294b4c85ffabcac3358fd6193c8dc1706c05e123b10445baa34c6616863807551bd33546ed39112f49c371ad31c82ea6db593a173884d005a0a5184417d5a16ec87225bac3728530ea21913b6b05283a4c078950ca84b73e417cd1878b1ac9388241c3e006d5c0b1148db78b319293707d92210622cce348e5c0572ecd7718bec7f6c644680bb2a6bba55d412776303b8b5cc2603356a7f685095da747a3480dae39537780188e264efb88bdb8c82cfaab5586b3629410bdf2274e8e2b76673c700c45fdef297778cb8dbc4bcec24c349170b39f96a5e3c6ee7d1c8da58357398a5f0202743339aa7eb74e0a5b8542909c29a8337e6083e3663df918c6a85246769b01403bb24c25c27dc8a4841166a86698eec30f049a80f786f6fa29cc8f7414517429f4aa76421cc8cab09874bae0f9999f0a846fa742d8d087bcd929d42e89f994ba2d421058b429e24c753436b908833c2b4365047da4825eba955e9c5de3a02c11c3c8e214416f2a8efe6b3ad033bc9acb992d77d8d340c69cb97cd59c7a5b127c6b46a51267b2471031166815c105914590c2aebaee9a9286d7c7d10b42c80077ddab4ba9baac51fd2512b481d1b1713ad4136b1a4a375959710a156fdeccce7a2c7dbf2ce57a9520b7c9509075bee4c5f4e3a2b45a748bfe210c88ba484556299511c10f762c162bd0114433dd1913f628540571c04f79490c30ade20434341b59e2bc66f489058d0aa2f14575942299783caf2e7b40d2a7bc10a150a6b0b1fa2a8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c95b25066a85d1896123db2297a75fdaa015a60942ec7266f8d00511a1603fcb2e6d533e3fc7c126d2753b9704ed2c5608a226cff698a8fa53f9746eeab1c51796be3c013c44f0ad8ec2037e75369877c4d63a1fba7ac534f4b6852068ab973e1d9b96be70cc21659971c90aa7793e51a517f3108a2ff24fd3541cbb89b75786a546b346ddc92ab5eb93227057f0fb76e1554c0cf19bf0d08e33fb1abcfb71c1a0779a91a42af586cb27a9304a75e9604211640be36739fde51f2d9107fec20fbce665a45a1aeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf50c153e941158f2202de5857b834e3e553f7945398bcc70ee00cce8ec15296b2364393085f2821d36ce6f04b0b336bba762c387c69280bb4fff179eef54b925d99176167f4f916e2bfcb945a1bab4e5398a03c17c79992848bdefac5fae4667d37c75bae231d424381c39722fba787765b3005699b7b08d2785805d476679e29372b619e3568eb263c2aad8c891ca561271cb5868b5971445e1cc2e2f1a11e44c0a798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = pass +expected_ciphertext = f56e4e9f97a517a6d815580f3e72df4cbacee30faf8faeaf23852cf0798f27cb47d37785f82e0d8c4a6daeaaa6c0d04e3d9a9b9e2b40051ad3993d91fbad0626b36cd313479bbe79c7437a198851d12d349dc858078f89d1f15d6ccb3650c5d25b4e40eb72e0494f74adbcb6825f03b5d6cea726aea0107b340481a6daf20fb8b3e09e2000021a15d6b94549903fc5f4eb67252816d1aa31cf725eec0834073331e6c3202a64fe85763b3725c5b05c3340285072f4c67201d95959751afebd2e205d17a47a17e885682e9e592e37c92d0cad63fa0f12cf11639dd2c0bb6ae9d5f9900f23735647a31f99686fc203d653043ec715404564dcab8715eefa2ad8f28accaef47f5ca4198ebec2bd683bc9d8034e30a5e1047a77ce74096af3fbf984f50e8b945626357731a785e60b2445ad9ab260a20c44a6e81e9312532d4717f5e313042e365ed24f17bb9376de8a6338510af1ec6e06e6ecebd885e05a11c6c0fc11c25d7ed738eada6b6c8d2dcdc21058343f99da448931c8f2d637e2b7e39a8d571fb12ec0251c45996f86dfde41470f20ac3b6d580c78bc1a4dd65570bec1ab75422a17fe9cc16cd341065cf1a523979c6d05b97c605a4c000ea60ca9a642744b9415b4be3e77572a1eb0a002e47f843b0695133936e24825223a4ea6dd849cee7c8ea1aa1238bc4468b97336f18836c147d8cd62a4411987e7b9534dbd7184e5f638fdbc5469849b0ab8a09db0e2a4bdd0a3a019c47d5fa611dbcce91b76be7d91edead166861927ea965eeadbb7a3243b5b2e2ac53721d2e2d0010c8121291030f9cc7e53eb4ca673417af2f3c51ece935f8f78181695fd30261e33cda52d04d35135725e079e15198a9135e2f5666a47daf596e245e12e8cefbaa20fa93395159773fe71e59ed19f0a628ba116acef70a5bb2134a2e67ed415523a910ea571ddb9f2b8daa42282ac3f8e12ecfa62b62ba53cd56a38ba7474764f01af809ae1fd1b7715f1f76233b4edd9b84c90b3e97026ee72b065f8138c9ddd6718dcede648913886fe030954138ff322db57d06c16f1059b58c79ee2a7d6e98ab42a6bd3a98d8946405c6b694ba25b73139cf69fad46ad5a3fc28eb19e14515a5745b5a9a6512873d14c9b6626436ec28547ec3df16506ea7b0c9815b689f4ebc82ba6db7a0274d884f518917e2e03afd2bde2ca7fd0c2b0ddf5ed6de2249a239363e5337c4cbd31bebdd145add37dadb67fc0b22c96aedf2b6782082d4bcd5c48572541917c9ac3288b11e83c68b73420a88eb249cb3e82fdf3ec3669bfd1dd8d9a6a2467a58ffc050940305d0a91ea386f75a29336bc1490b6d90b76cc8986cbac84d474a2a6a512e2221597b60886390a37c7ae96bfc94e4168628eb29c7690432c24714b7b81d54f68b18daf9f5ad9f371b29d8792c7b2e11f23e87a053fb48c1b5945925cac1289cccce8f65eff481be54bd17ed2b470cd0e711be202dfcadcafd269fcbb94159170c2aa9377f6cc80081d7f23725eac0697f3e235d9c5d24485fd1170f3609469f0247c946f2e080a3f44d5a90e9220c531a73eab0d454366e303c6d46e44adc7fd700cb54e057280d1c799e8bf6e80b957d3d32ab48c1efa62247e161e540c1d977c70b591b77e4a2f1ddf6651b6f8158faf6967a7521dfdf3d2ff6e2970c389a1ed25d146320c3ddf12408c5bb012ece7012e6c86f518cbe13a857c10060d458fa5f05323bedbe06a295f7a115110f50566397af07d3950f820764633e5cfc0eed57f8deff0ff3ff91e06f1d049eb25dc3c0c73f6f811e3470e33bc3632d1365af3882ee090f7a259780290e07c6fd52de4c197b77b37a2b9c7b845d28420dc295f774e54e0ca647fca8080f17cd94a4590459f5e3bacf84d6bd5848707c45f120a0d7a612adfdfa33f1a969068580549cf83df5f64ce9c989cab89237f62deda5a1ee7fb4f8045a375a51ff9cfcb843759e444c35667bc649661fd613175b560bb5731584ed1421107b8795a2fe5e4ad86b4c3c50b06b540fb6602e6b443c210435172b9eca236992f4971ab3c5dcc965d89a03af1f5ea8c56dd7a361183db4ea502a6d11b960cc283d4b4e50ab1fd9cbe04b12cdec1543eac9a70d127152046d680bc82eda8df796e173c06802887cc3107cdc397c5de20869fcc0dd25bc9c5353734f0847e8994fb58e5f7b7d356922a7c647d72433f +expected_shared_secret = 5e1ac468279cfe354c4d0df6ead070071b19c9707338158ff7dc133684afe2ba + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = de90503d536a810bc927784aac5b15feda774ed1b0550b7a7e656817866881a2a4ef682462e75391298f75f2061c70141aa682d50787162a6dcd853971665c9609bbd90ab833367a44a0286d860c04057c8ed7797712affa2557e2db46b546390f3163f05316aa8a12a7d49c4fe03337cb9a7218739ddb184c1304530667b9b54441015b9f8501f902bc2f3000a4855e68d7350e83728765057959662504331d5026c8d52088593d0acc1f39e74a7fa59b959967073bb14de163d73308c276ac0e6bc26e1c165b873e46972b72fc214544317c31556a76c09588c45e4762a1b43c7ea2a9dd238ac6e39e9cebaa1945544fd8702d7066d329c89656499e6c8264ca1be481ac792c5a52188e8a954c06a96e13604e2ec0242c78bdc7763359a47c2c5c4f7762819504740c043b2a5bc8db00cc4aa9a8c6354df515ba7d7039f0268637430067b81284f866bdda366a8c25c3808af025561f24bbf8671305ba3aed330898f18b854c501549aa9a1c68dcf1071af689f3c4a46b19709cf02bbcb07f65b44e9f9385c94c4385d88f8b502ca9e19a246498646bcfa1308f8a6c45638a0df58668f55a3d30440453c36875b0aa1b5967e617a296d284c4e2828b64b83fb176156ba7fe864007414c3eb247c4063acdd61b4e5c42b9147044b6916fa9be1d25ba71a035d766bf4c1c336b836b512a23549bbc53e1a8fada8246b41cf93604bc9b792868734fa755b06a7821e688ce17c9a00c7f9fd724dd494b070b9d4fb0a2963ccf41777f86ba3b318a1ea543913d5a653f073b34c64980e02cbe17cdba5a286443677a152b0da21ee54991f34b758b87a3cb690858f29a003031e8a99964f3a904023404ca51d730957f34a0beb402169a6bf7163963d87d9c6159b8e342cd8738c945b832b698655071286338b67b372a067305e5299043c884b4ac6f624d06f1167003cd5659b68f36bccde8b37c817db27870dd196135b21849843835ec1efed74af31a3bfc6cc33a988322622e2841799635084aaba1eca13b61ba765466b05c742279067c5a1a1355737c84199932660b15e1c124f5718e86a8953a0ea5182299a8a4c4a82f91aa901f40a64c2c1457864f0beb17f5b6733fdb8fa9a04d9ed1480dbb2ebe1b8a37917ed30257ceb062d4b3caac11cc1283542b6a711a737c64981afa7cc0dff00c7019ae2169bad10a6f60f094020b7b422b006135b65110076da0ac1e9b8f354a46200b3d58113953197e7a942671e3ca61c17f4256737dc71b12291eae2626ec136b6898047427525290a62380b2b246ad86ab59b12499c77936f816cdf15c5873147e37a71a2993aa11042cc83ca7b7656ff35429795a9ba01075d670a464b33e368b70ce7b484e864efa8b890892b8648461a61b75bd7455979325755292576878d0f94728fc2433c1c04ad8b52e55c93f36c564630c7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b59807f51fce23361e2abdb21a0803f4af1dfc8b55a594e746b241ab0bba37b285666de8431bd3e28c7d6b64e7e1377364c75c1a1b6b8147d91074cd862ded548788d825bde070ede391b0a794fef56231f36b7c451d25db6419e761e700b080db345c613226d38895d55889b10754b9706c33144805325c3295359ca2ab758dd321154ce457b9734ebe32c02546a7556b599733c036060631d5b4ff6c57a1b6c5065b80a691cbf3c604dcf49d914853c87b6758a58d56e406c04230548954242aa799e0532acbbdb9d9a50dc2bab0c91b0268bd2f0427717bc5b9456895c1660cab6c312549a8f15df9c7957b1a9f3c00a7487a812d429bb8f232b559a5daf57c27a96a99327a39f5b1ec95b4161316f1a27ab2470a162231a93761ccc64689d430d4872acf18a4ef71c0b6ebb3d552b2bf4abb43d70576c9a67c3647d5919be77a0af046bc6580bf05b109a66256a21ba44c45c516212aeadb7594fc6ca17bc436102ef3d99722fb3bbb0bb39c9a1c14085ccff8b57140488270c165a8abe44333999a383c83bf1bdc6cf63258908abe715bb383c385fc26635283af0853b3e533cc6cc95591c08fcff360fc6b506b861444b3b328045270b001a481662bc847fd15924f5744e359c18514a909ca163fecc8a1521c1b2955ab7917e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = pass +expected_ciphertext = 21e84fec2d39d07af40f870aea929d72eb835afc17ad37b589a40011f9f22507a8dbcae3db12c7c78f04b3224499df5a5e2fbf4457329d4f58d8031dadc47cd256e1818c77a2ff57b79bc7da942e255c29db6b6261a8f1e83469aa1ea312be5131e6e48b8af523061b4d160921c4270054f62daf17ed5d927e71c11093410bc29f0c8ae9c85b2883ba6a6c02e3cc029de0adfd661572aa5bba2b4387d071695a26ee60e74c17d935f9fdb94d90474168fb8c301dccb02d63bd00fe2e4fcced4be6d0cda9f73086a3ff95cf208b47cb28ea7d8d76a0797363d3f8a15805d414612d9a2e8e3ee010445b9dc062ffb6515482151d9b0bda80270174db7012f4dc55c3753933f3be1ab8f8e4456df8976d217b32d5158a96c641627a9f6dd1f5ee063aa12d1c50f76fa1038138bbc06211e9111b23ba6bbdc8307e7106d5a0fd9306cd7474c72a0fef226d20a5f0386ff7b7f2b92f6f5489e17a49b5c322cc4593ab4f105f9fda8adaa4c14eda1a4290a58852abd3e9c2bab221c43687d7d7636fd0c6131c52aae1491c71c63ca6879a234e59ec2955bf2ff4dd94785c5ef566e61b93bb23a13126adf488215f1ba44a7c7b4505ddfac3137fff5f0101db710ab15b7b5b89c76b83ddb22e33e4f3e412c4bd4e495ed2f456a43ca478b7f89c966d4b5c49040eab34ac3dbbbae5ffdc1a695985d31a7339dea863370f26d29c127c210615adfc18a759c515952070383bf6168bf0f5b3c013ce9dbaae270723ace4fdd89118c4f648551c01c07616336c4d6db0334b6f069e12d0a1c2c79134aad08c0fcc9f2eed1479627172e9cdeb0caeecf35a219fee07c9ce9dab2c1d70ca16944fc72a04ceda778db35ef540a57bfdff481c434f59086767762bd956f8c46cbf30c0cef79638ee82fa9da2cfb1f1f6f1dd148b498b59282a6dce929e4fb3b9b1b5fa9e441558133647a58dc95d37c5d497dfe55ed9a14df84601d74b8b15708b329b54d42ddd2e1354bb237b67d63483ce89fc9471dbdb031cda50532e0ba0de9ad761c9fa6996952f63b0b7d38f45e1f73e714ca2b19bf130defeaa3f83d0bafc815121c66b2c52e35d2e71c54533ec758ee7cde243c8b38d7d401bd8ee5b904192b9ee7856cdcccf8eff4aa2621ef12176cdbabb49c279f16a602c670350e3927d466e75939c15f597073e406d2fa871651f13048f575d44f679ad68f058d058eaa5725481c6d4f0c60946d9d79586ab9ac2a042adbc58cb71a9d6768367751ad564c65fa822a8d3a4c4799df3c7fbd5712670377a0396487fe854c4e0cf3e68df8dbcfe6771d0dcc7af77ad8a44904e192593930de973df753f94e6b92733484101a51dc0e1f6517c97a52b8e6605b494dab7b2822f413e5e64323e5e2da4a7be54083d972e5d884211d29ed9325a2676b48b5546e7843e26252d45b35e159ba58f8c6fe75b7087bcee9b5342ec1d060bae57fe60563d1d40b10ce5cd53c3dcde3b95e8181e0d204e8bba231b7bae36740c4ceed081dc5e2d98014b172f89bacae436700aae42d9898e0a7958cfa2adad1aa8a3f60389441ed635e246f101c91465183178c6478c27705b200a92d4532a0e333dca8c1a2dcc7f1177a74515bd3d901278753ae3cd852a486c79c8849ea3e59dada0d006284b320ebda341120aee768104d540993b073d5cf679b24b6c656c2b8df632690736bc8076b6012463ddf5e54746de4ff9c2c3d903e53d80626c396d722b7117b0c993fb03d4c3e9b0acc038d2803c9af5a75015a349e1bd878a5699f2062efe387b9c28acd3565b5012d147d46808d5f6a147ad09a39d4ac8cc75ddbe2f0579117101e39979707d4d3a7eaa832d8820a13c438931057e6c48e433dd0b89097561a66742c3b8145e450a6f377c5aa62455b79f444a1394a453612eb04161b450a80f58a7e8c3dbc66294b75a28b8e951b955cff641d107f83b385be1394dad6c4c7678094fcb83ece7d55f9c69decce45243d3acf86831fd694c3cda038ed84f0b14e724754dd43885e4dc1beaad8a45afd5963006cdf47d2948d4bed48244f65856c2504ce77a38e7b3b13a9b169b800c729cd957a5bc290116bedad6d844498a3a1314c2f63544200ed7de137a6126fd6f75b828d113e4fad9d7c102034e531ce9b881336a66c05d3b0c7cdbf3afad7632799a00391c693017e49d749e038d2b99858fb2f894f9 +expected_shared_secret = 7841501410e4158cf04f92b9d65d0cec732984ea66809130aeb594156829dd39 + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = a0eb8fea64c6c0da5d9a16254d897856a1486c8b2f773c18bab3cd4f80c83dac6dc9796100886d14b4085bb2265bd9c2f021034ef1083d58afd447ca55526d2691781d409649e88f43ca4e9b4aaf9bd9588ae52d126692b181817abb5291f660adf3a0044a0c527b233327c0f9db047c9415c806414bb0758dfab9a7d3c28484578b6084b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db333168c32033375a0321a287e133a9aca8eab024a85761ad4776b03a95130d0178f93684a2c0a519501ee5b85c4c3278e8b4e7b2b461cd4602a7918767b315cbcb885410ceb025f1342c2388637eb69ab0fc21568b1178ef3669a1b9e4fc30eadf5be70143ecdf543f1cc88e05a109920a5f3b4aabc0b8197783e8a16b1e06bc5e7089cc447186830a1d5bcc8bb31a6e91b691a65721791b0334495cd014c134617a3318a7906069e0574d83c8a44326db67ccf94a0a735942de923b5a6d55b087b4390e975e6b3aae4606abd3500fd54837ff875c54bcb7b5739ddc0adab741e57946ac0948ccef5ca791a46c669c552b97ec35633a141b92de18b0dba46ddc64431920938a927c255ab78fcbfc9653e1c0b8a0f42489674c0f79c30cf8a5073a06fbfaa888e914d53a3b6a86418f5ec6dd5a6b56973bdd9744d0ef326ab49291ba1b1a9f1a68da542fd944b3b88c6c364752fa6233d27a792e6a040f1824120ae9afa707d7206966a4ea361681627cb346572619c9a7d539db7469e60177e98674398ea296fc3005800c5da17a80ea06ad23a265ab7293401cdfe3460921596a7c228c883b0e1e48365fb02eb50950de3af481439dfb98447f3406c81161e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99c820e1f258825988d4827b5b1506a0129648101bd18823b2f2c2a142387f1a067a295175f5922eeb1de320711f0b729971bc7647889ee86cb5f44363a992369120dc837dd474baffd381253680f00675fb380bf96a89e282ae67c32b94ab48e35029145748eaa76037a98788c45dde75085d9c5523a7309804745f626f89362f7ba94738c5b9ba0b11bf560e855356e8cac1195cbb2921bfdad80db6b3bd9916a7c6cca281914f4fa5ad26d00e6f6acae0db49ae970755d16b2069b1a7ec0d7b879af301a9bf5519683bb3a59b066b62c8d150a316508b8c2c62a7f20fae59b3ccb0cc5e21055c7a638e11242c39855545b0a880484fb555f0fa4bb059ab05457bed820eee0767470628f81a321f113a8158a1ad1367f11802f71b90a8b4a1cc3c16552c11064ac01402b8b4b695d19ba74991673a963537b2ab14333633e04b0859472ecac568c87700a5076c8c265a3b0662c4250ae5cb53771cddcc2473f7bcc52ca97ba018beb6be5ba5420f7b2882f3acffbca13193c71eb60d167c1d9b256f4706a19204a017204ad28b6a0f607d61a97cb578cfc9633ba9d6ab84367cad900e5ce147ac935af727724af3ac8f0c86ec70034ea7c7f5330889b402f6b7be7bb6c7751411120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb311b338dc8a8e5b10c08b3ae26c945d680f4ad35dc07639c581301ca981be25075363b8d3a6b2165c99c0b61c298a502123c40e1cc223b21efabc1c34576e206456cc082cd4048fbb576e720bb967f5b58763342c98ae883cb24ca32e06398c56eb6a7b697df092926a8c76dc160f0c577ab476303647bad3b6951949acc2a69e793807a77c7ef163a25c842723d85665b121dc8622772caca988c5e8281d2e7055657100d31688b09104d0470d8953b82ea4c6afe50bb96b68f5524ac3a5a92cd26f26b142e37920ad36111226c763e3ce29c9c1235c8ea40995eb867ea8e844ed819c10f62172c52558667f4121bcac1815ee2806d863c22f10a20e74425f6c22b1900b520a5041b0a7f5842ad0fc0e19c893d7e42b1ecac89d9a989d8c45dedc5621565e2e788147c42ec4dc6a8ca22d4a1904787ac8b75232bb13aca7e30825e865bde0ce8ef1c7e2172d759873db265638fbacf7763b80fb4161417559a32c2d6cce4834be3316181ea4c5cd29687a498953998783057df991300f224324b207b723607961622f20377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = pass +expected_ciphertext = 8a7fc61cbd793349e4eca40c4b0363c8cd6bbda7d91b3bc947253052a8aedce5fd3fcd3267834afcf8bc65bf4fd5ae665e83718fb3853b692854fe073d4495a10c94443fa5b96d5ed4c576c3a7c35019e090b8f4dd290125c120b6725272d3e5715537abb68b1c9383b9848561af1e407fe05be8559386d5fea2609b87cbead19c2088b4a01988bfce6457e63acc7446de77e6b95d4de8c23482a54227f418eb0c7ce1549aab9872eaa1ed31d23275e3ced1086ee360f586c6e0f0ef6747338a11b3a547891198ac06731eeed8991690f69f826065f2bb33d0b90f8c95c54d3208c2ed01339e07616539729b427deabe41e942cd9482ac82989e04eb5892b434c12ec598be216e71bfd74a77250ea0760330a77f292c137e3a6188c26856aecbd86b9dd9900a194041f6665f3b2c5a567e67f403ec8d25718c94b442092521e872238916d56a22145081d3f7f279b31edb7817492fb542ab081b8e3803275882441aa79d0bc50438b1598661836a30ee401285ac14637711657102da457accb446d5e477a82c277fe6a89fe1392ef3ad1438cbf8495466217c9551adbaaeed2d5303660f6d3cb7366e11261b8f5cbaa5908622d3744c76e4f4d758317c38b93560446758b3370c3336457e8d0ed04fbd335884d48815cf6f5a61a1b4228864ca33b9772d5a11186464de82959adc9fedaba313161198782bd30cc85f3b452a1aabe85051aa9a476e57cd277ba5fb1ea30fa93fad105d25d25f0a852fae45591eeecc8eb4d60f49080735a0088540ee2b0a240b071e2543692d0577e79cb0eb20d78e9564969dbf5d0dbd57f733d945ca1e315f83eacc17bb2f9618730357cb009b61b040a9ae14c50cbd0a34f508640bb77947160cc18efe07e19fced266bd0b1512c2054d21bc9ec59a53cf80d9e83cc5a096c28d6473ecfedf997466d9e875a9968c06183ad74715de5f1106b66411df25333e4b74f9609a1d4d220c6feaeb2ef6349892b1abdb8564af4c7b3dc8b4b3901609721919b6612944d8e4ea7da00e46274dee2b926b05646f873c0c79d1a6fad3dc7e7c2a3bdbe3ae25a305d30fe8052c539076a5e8d4bf801a9fa9185886ed87059402a45cd540540e7f65f2b395e36a9778970807d8765a0eefd75def212d5c0f48e392c52bf4ba5b5add4765c900ca9e397f74f6581ef76a105f2237afbc356d3b4888efbd42038f3ec212ab7db92d8932f968e3ad44954b7ae0ca07b1c52f7a2658cba0f1cfd0ddc653a47d6f78866b03f2fc7dd45552aa9ecec792edd5ff572d7ac1618800262515b55d88bc777b6bfa7da44d1e72f659078ccbd434c8a8b1b79806b922f45fed511f8365c9c17aed6e54c8a2d820203b7f3ff248b406826c36009cb020fdd7d6487d5e305df9d3cf5fbfa51071476a080a30cfbf1bd245255fb852eb96f63093ecf42e2092a8c5f18f5d23a8ad5462a81330050654cd253948f5bf400d25dea8512f7ab19c7f4c9a1a15e8152c410014c0390618cb7573f62fa998f1e1262b0e52a31e16c397a3b1a2f33ebd56a82c0539bd0dec4850124b32976fd013b3f313052eaf8e7dcb33a88d59a4b3c9af50386812117a403902ddb66d2370261ed5200903c093bf31cc1fea44f0b9c9312e7ceb47bf2ea05dd2b0c30df2b6d1d0490a92d387584ab4e4a5957372579ac66bc8a75e55d28980fed47ff66ee53893c6065bb04dceb6955fed293502d174f7f702a18d1c34a1aeebf3259eefc6c87e7325199d14e249c3b5c5be857200209565f4b37db58f16a658388a8403df95bf9bbeb91ea5fa1eeb62e18fae11d30c002f90ca42c8b189d60b559aef8f2dfb0749a9c80ac32ba227acd8c9fda46f09c7ae9b56fbbd463ecce9df6daa3907e539ed001dc62ca0c472edceb824ed76b4a4c66b1dac16fb6cdc7fd6c9661f2f3b816a4ea63bfe8507e2e2a83eaec35cb739092a1717189d029b8d96d7631dd4899a1acad50f03bcd167ee77c513a8d99cfe696370001ece57d7fc9be5ac26131ed30aaae8a661f8b574b63cc443549d0d49525093fa7eb4c1cf6a818868a6773139e02ccc0175b8f50b4560eee4a57828cc3e41bba85d02ca8a6fd344b7cc0307961ce2f669f49bb7cc5faf609297d36066e88f265527b391f40a477ee6ef8abb8859050275c013018eef80cb875f4790478657fab67547619c21b131080082c3d31793ce4474c1 +expected_shared_secret = 6b3fe0dd082bf384c3e08497d380516e78ca778de627c112d02dc8c393334d11 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = 935770f4970a8e4b7b83c12a1e44c3eb360b42e77bd4435fb6f65cc14b894c387d0445af3f28cc2434138a07a667e5ac6bbba72dc3b7eaf788d8621dde4034a430c2de165b313733e2daacead1a014fb09d5b834411b8325728eb325b12310992012a7c4e05dba5017a59ba9777a9b3d5a681f79252e1c15ff8593bef7cd3c059153435bee16cd2b8433ef80bb21cbad40c6b945d7b6ddac39d0d0b558c7a42d9bcc701aadea5707f77498d5527e4f0b0bee834946302191d06f46116a77b884479a75a585a0c2105343584aeef31bd8a7aabbf669a2b2518f3805be390159b974ce43c83ef68b72024a42a942d8a03ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cb50fffc35c6a8b95172a0416130af7560ef1020ccf09c400101705ec1305ac95ca03143d22c93d72bd07e83afca94ec379142bea095c754533d802183a9b3cf2796ee2988184076d6c2235f39d250b080750762a0a31ffd26130700f6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc371c1de16bf2ba57359d060328a8cc01b948ed14197286ad0e8acef142dac64b4fe260cf066886c8ca9292ba2b3315a2d719c53b7acbb5125bbeb8d3df4caafb08ac54b8aa2816d3b44630623101f3b69e15c32c8e6912d61cdb2602734b206863c9b488431d72000e59c36e031471bd693e238314bc282dd8b4702d334e5985a8e89045f40652300a9dfeacf0c922e5b631f00c434085c5dac53bb4637c624c80dcd59a2205c8c5717554c114999e79b7ef020b7961f007541d009350bcc427aaccec0b0c9e3656214255689b24ae3cc874ff7c0574b09f0d8223e4c19cfb381a8c72f7324ad9e600669204b2590bd9ff6a589d26e0f2bbe575c39cb304ed5c8b692a17b65a7a27623144e7248eeebc4ac80239de04e8b3928e750a0bd44c30315647b5a6bf3e5955971c9f62b44ee01221ef93fa76843be32408563c111447541d98263212cab014e7897afbca8618a27b56bb9725aa1b711315e30aa445537bf02a201e5362e6b6b82f52506cf8c1e82f7912612b6e9126b7e725b30451d2001b76cb575ebc847db9b2a048277202b1434f9c936da846a6773dfe4193d019c7a7601fca114737559df7aac095849692831156a13a9060510e05bb9f48a01506a08f63ca5cb4b032962b6d484e8cb742b0709023b9926562bc83c72c047833e27760d6a8a8c559a096600254909db3668b0e2c8bbab67413827a2c808bf6c2662553b4d9166a152931f30031fb15822c12462b714276c743b2691e69321946cad96f9bd71982f47970fce751b013630f5aa90334c657d286f94d325333b64c6bc9955e859f8c51c1961400388bb9de91fbf4bafe8853b1ce98e9f1076af1406458b00ccf021da408575e126d850a3a1d51f31069194d65c4df88b94d8b43a4b6ee651654d6bc72b8c283c49093eb3b1dadc9bd329b11862542da3b770657318f13fe4b07b1d22482c0410652a3b52c2216f3028fa47c3e5934c3540b644a282729196ca366e1064bf5e57ae739229e3f092c3cc91e8e833c4e314b6cb91e6873f35cc4ad2b60281c862b9d0ca89aa0966713ca0e973a766cf303aa1082266923cba1ce7a91964440d43878fd359583c6de0f5c6c86424a1096d5bdbb843990f0b8285681bba7ae82008a56f992267133b7bd1a55f0fb37f84d6b2609cbc49c968925069aab3498ff7c986f522b0f2a1512a8cb5a6bebbe62f28901f2c5073896381255912fc482e9ef57132ea5f5f61b36a5a17366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8aad129ccd6c796b2883ff989650c04af16b339ec34912226f586286a553db3362c5e1056a369b22c1467cdd4a633b03585f82116510127aaa1459b2dfe049e6f191dd7cb4d0a8ac5df064e64b9021440357c4562302bb0ed0a6aa94ba1dd55a50829a574007608bc61508a0f17d41dc3bbcb8e91c4dee25d2ea4700d905348026046450ad0c2768ad72eb0b770d45a7416c041160170b8511da2958f44c9b06060183bb37967282062e0a93eb5bb4b2b15a4152c6f19b730b724f94aab64b60b7ef5080b251ae0290746c249b1a76c96825653a89914b1ce70982d3cd437837854c6d28f871999073b1c2024088f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = pass +expected_ciphertext = 3608928ece690b321f3a7a09d0f3f9795cc9f17bbf2b0f389000daa3d4448250e868c9b5f439e2ed83c5123052390c46db9e7df41ce8b36a94fe4bac780d0a7f1f706fb291dd73ef22db1a261645a5fd6908af766afc8dcb8f4d231ce30a4f75095b0755bcc19937f59faa625a4e9082039263fa6995bc698480e0d574fb91d9ad226b2238ae6c90db35b4bc7c3b0a86246fb9bedebb99fd61eb308ddb984dc816aecb312ad8109b48873b240e804e12f874784de2bacea6a0ce6c7badf8447fc92687968a7feeac5a52c9e4c5994eec2b9f5aa1a02e77c5bded0a722f6f03ad50fb9af7dbd3c947d51c88265eeec8eb8cda85cb4e435b42f6bc6449198c0a167c8854e53be601903455b2e70caf40efdcc0f01fa094f1f131c5a4a8a43adda77e6a2ab30d757d27c6945520e61d0d586a4f942469fe16a4040d9cb35738745c6bb7f0fea1177148efe651c305d357cf9fbb60b28e7aeb0f86d401df1c6f274fed52e5201c6ef1fa44a49d8a83247d9e427032cd36dea141a5a9034c9ff43fe78ed18ded60c3c5182ddd7b750a2136d1bfc9f023ac2e035f68bb294b9230ad79ffb08dd7e560c3895bc29d3dfebc5dde309611a1971866932ae205384fd0b928694f1ed3142016cfd22fee072803ccb2f9a0b4f72c52fc27f9670b0aa2a2998cfaf447f1fa17043195e2f00e85d4a9438e5a43ae167d423f4005236726bb696eec9f5ca106af893f41d9e417b487051c78271574e5671e6b4354c6ea984dad8ed2dd1ac638848a12f016a5e643877bf7db0669fa23002484ea4893b12e647fc17679fbc09e3eccf840b17734024ba032ec16bfefecb4e2cd8b015fdb324b96ad167cbbf4f2fbcfcbe920acbb7ff5a9824620c7449192bd44e768eb51fd59304b7be0e031e03294931e71a845c23086de8984dc9ea6c62068e0887037b51545bf0f361c0eceb66d8ce759255a35e44a74f7eb568f4c952c86cd5fc210376af979dc7dda5463d97fa4eab46a6d5df4dbeac5a00ac488cf62d0a354d953438e87425592c850006cb5d9ba10629c5e14dc8de4d0f32c0668899c061dd485c4c02ed9a150443133f0aaac359e6fb7df8357a21d4e6da958a1ed73ac4f424fabb29d49ded136d4a9d7f42ee86e34b167841199333523d0fbb53726ee4239fa0f6213e6ba9ae3edffa2e914a802a245cba75b01e0d450e041a5cb1504c426f0d36bcc0d590af2e9dc5f68ea7e2f13ecf0a266b97f6cc986bda423068cf3da5b44c16483ed6a37843eaad3e23f0c8aa8671c75e8fd17ff4836e16fdb70ba9722403844a51a81d10c7b399a9e9ef9022017c93cdbbe742f1380707469eb5c513acccdf27eb2bb84b0ba66593df3540e4b3321a70338b6829bbacc2d1cca888870080c0bdd9d9a0276f6cd25e60d833ac3ab5e656432410f765f7404e4fc98b16b68e2fdd39359b3fc4c0340b57e5e34fe820459b1caf7d0a19cb132aa14ff4fd77a75ec858c7f6aa9b3fe51e6f5b32c136e84fd4c2c2a1a0174f5e478a347abc1c53fcc50373d71bda547bcda2fefd2b3d1341a0cedafac274783d749d7c4a1f1fd5d0a0e8755ccd4790e766d5c807122788a9c041af93e2c6d503ad043c36dcbd4dad5ae503115e8afc84fdcce5961518e7c117ef1da56934d1b95320672c9ac0c9db215db08ba4337a173871d3fb2934cd9ae40152086ac86188d461f4a37a07abe99ad20956c82f7f67a9f036ca4212ffd3d1aa013d3f99fa2de6eb1372c983c44cfdf0e1138962410d821d2a32e57a37f6db98f357f0b1477dc8a1256eb6a1af5bf0c91835baa033a9612d74f59cfe33c340d35cac871e0c60c0ddd0cd8d2a6b7681fa86ac0efd32ad17ecbbe4bce8550984fb0b7a74ed6da5e3ba27f3f08c97baa276d4b3d9382e9086bc3031cf95ee7c6da42f2fcf025f067aaabe938956857404c57cf4cc39fe57107a79dd1fdb9c3cdccfd74f5c0e90459e4e68f33a986453202936042be7b7b69ec3cdec4ef4f258d91200d222680a8443467d7ffd58c25cf4990d93b157debd343e23c3e6ca3fe612c52cf6705f409dcf5ec499d6d6bb9fa406a8b9500767ae4b4779b99eeaa75de3ab4a99cd02df8fefd7090bd825a70e292e337f2933ddd2c6498e00ec5e928fc7eb788e68479651203160f29af2b9d27d32ad50a63ac30b1ef4a6fa5120f077874ff23d009f6fdc39403e630de4fe8a6e9 +expected_shared_secret = cb15c306ba8d5f4f8b723db93bfbcfd4fa02ef32ed8e39c2aeb706a463d9a40f + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 5064909f424a15515fbf534b4f660b09e9146c40ac273822eb116ac60782dc519805c41f39a306d7e21d0fc2264b8bb6637b113144b0d459ba833965d3a39c51355416f672b25811f5f2ce8cec777ba322ce506823d6005d1147600808ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7efc25874d5190b893039493204f67e11560e49412b484781c571324f76218976a1633bc4ca3c0a6d8211c6c0171e0993baf46406f8b85fa0c7f0551b74ab81d642c634ea74b269837e2588228a8645764a2b9a7bc2a802682b22c24c2a55439d14d12e620363271a4468fcacfa8ba686f1bdbfc70ca9c0961f9a488b7962b8c718b9e7a33d8b5306e6a05616c2a1484aa044200038624f65b8a92ba4739c714ac71fb8f12af92c5cc06c2bb59367c5c471bbe6099d1b19c9bb1aa168c071dbc6e01c5c72fa33171c52b78c1deb32134dd8af5d147bdea32dd6c52450c112bc5a0d9e03b06d807173304972a9866ae4bf6b053d98680858671ce1f252293972c42c4bf6ec2ba9f11be4325c34f89e7d500dd749ae3c845f7d56815f11a2fb07b9e3f88cacb51e2ed258cf5bb981b089cba18f902c14e04503302ca929319645154cfa878cfc777f2093a00916a617b6086d973208883ace08270eb16be4ec404eb2951bb1ac825840bee09eba19a90b5316ab79c3ac062c07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f28a15e49863a2139dec116d99374236c8a7169053fa716756299ed16125d699c39357133fa49fe0db960a8cbc0adb979239b64a7b3a702878fc1610868790abf3968873ae5dc19020b28f1405cca1b0800ef236e020aed6157892161b54bb3d14a4c64fa1ab949648020ca86064b17fe8b3f7d915c72a68e2b46f16267b7598bc112537b7681ea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccc51f9a5357fd4b92ce4906183c0031727c7a966bf0c485a9312f7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c33fc2033c04294a91323f1602a6da351f0a6e478264e0e4a6adda77dd6a2535a748daa074af31af028509f2c27f15f00e60e72f7a7032dfb99d50c88814167a838758c2685243839d8ac19e76133b40dac70e49b33ff83299862c3496999dfa90470b7bb17bcd14019b093b5787abada26700a83377ae57173fe528d6dc35efe846d95933d68144ea3aca554ca0e873baa6bb926d70a09306621b3705942b4e0d60cbf200c10c3c4d5f7c8c75899aeaea40cec8928ae25baa2c7f139392221cc7042c05baf58371010492bc2125d27a9bb01a28a3855c98b894d4165689af39c0a26a6b920874728d475daa731940457b24199d11841d5bc369962c1cf3920b6af974b3150189919959c3b4e556c56fb22e5597b64506575f6799dd86cb0669651a1c017c8a74e5f63cc60b9047b21dee777df6010bd6a614f9a63c72074b7909137cb7155fea72bedb7428e0b197246af69121e97923f861af31f10249e11795a180c0c6c056d58d848a62370278308c4cc2b466a8d7231456c06e4b9f1faa65a8f0113f99238c52ae3c3a24600c4e943947c8c653c946bbf6b4cee89646aa23afc7b22f0d45464337a90a7c22cbdb4449b24d5bf3c070778773b92055206ca895105e264c9757918f6bb76bfc93de826c61c77b6a51b135915235271faad3cf608c0033b2581fc522965257eef576ebf7379a173b1b269e27648189696b30346d5202b560784777f88aca2c9f900344eef8aa0cb4a86ed6335be29b91248780674bbadb5b11f967a663c2f9129b73ec584c50aaae9771d258272198261f362d93830880e4b60e4b142b3822816501c89b5011681a5ec2ba2b03cf9eb1886c33c1c72cb6061b10638931e5f1461f413e5766a7becc59a052a0e221c6419752258955dce743131890bab88b8dcc5738eb6f409c1c0d888de1d0c5a7bb03e80171c2b41dfd411f74b5165804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca4e296f0d975f2f5731d822627c1964ec1bb1ac7452bf0c5c0735d6f75304efa4410e4cd20557b574cad1674395436203db728a58b8e0b95183c10653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = pass +expected_ciphertext = 682f51001e8e82ff56040975149cf749e276aa9d891bb063ad5000f7d00b94c2e63ce6c5acb8d4406149a32d8b8c793ca5d89942dc66d641c6d92c543b593ccd4fb4c420eed148f58962715f57c2e530a70f03e3e2fb3e1939cbfa94f525a9871ccf482d6d0a9ce9817a1f8f9d3b6ab339b64e0121d6b788b2a2691ccb640be2b327229c68dd9f1f2d185a55416e7de882dcb5198b22391af6f3233a3d252303020d01e92d9148a1ca9128c5c2585fa5e62e8ddb1be592313fbe5c0bc33a9e15374aea856c7023935f6fa0772ff8df39a3d0c9bfe4362ef49d2a6bc176935116cab82ee4645f26421874420aa9452c987d50430be35131e368e759be4244ce6135b6f21df91a541fffcd5851ef54bea5381f76d16cd8fe0721b6eea13c03e45d123f5ce83c3734894c50456d85ab7aa305b1f86eeba6822511b59c34e990030e45d7b02f47dcb2cc51361a931a9c5a40a49dd506b5bba74bc4748ccca631b748b96e999e16152254ec3c0f5074f15c29a172916b2aa50da95176544c80dee47c4d3ab06fd814f22e79c91ffcab2535ef4a21bf353ac06a71e5ba365d2eed87b1c3b53d9dc5c760485e665630c2e8d16f86921babfde251f06b7a6ccbe8f2a4e9438e122a04e277564dfb258400bc842f83eaeed123c5e39f15e9b66d7ea24edf862ef846fa4df20751fc167771c7a16b71a57787352de96f0c45b3b39e7b91dfa4349c7dc5b4c65992598c2edbbaba461a6e07be6c6cf90ffef1dee70857babf44979c2c9bc62dbf5a2c5d212da4f6b421414e8be50a2c240b3eb7f3bfe84f355bcb21818e067396956f62c5907edbf859517a49ef693e21e426f73785bf502aaf2e43e35664438b65d0a71bb1c95f0173cb9d086c61b71eca4ea5e5bfbac4a9145157b6f445990d45758bb886dadd7136f4049b1131346c2e883c766d3951cde3ae60cfb736ef668f314e58e21c8341039f8e34fc815782657cbfac346bc6e1f2e7119d7cfbf0fc31987cc38eebad9d91e466590686bbf8068be39d64375077c1ef599dbc64c8de64e308d0599660804ae4ccb22dd216c1abcf3a2218af6e5d8f07fbf52f2a1e9ddcc467029cba6578996e1e794a83f143757c0412c993d8e8fe3f51c9df30e5bd579c7fa0a2ce6c58d47334851fb07c07be272366c9ad90d19b9126f49a70670a4358faf8d75e727d2cc4ee203923f234954c65c94206ee6d803a5a5f4f87f75e2b509d75a6dd8066b7a7d9d6f075fb7003103c86a4c5a93ff2e9585ad1a39d6ac9710c515485e9666877f0d4d2e11bd322c8e124fdca5a800944102a877f83fd42d23d10c0068f3a9c29fd8ac3cd6fa59a148b08bc211397f4d597d39ba2488c93faddaf25930bc5787339702e668312dc1a333fdf09d29f9bfe60ed68a7e86d62531eb08b61149c54287c547476e8b169c20f53e79e7ed680a78adb122f31004d228cc6dfdbb24ef3513abb24c81b2632a1950ff700f422a06fc0b975a2fc4a727f89cbd420dee046f08a7554b34df4d40ad940f14f3ba9affb9dfebc244b964427a95a11b69f9bcff4f4fa382ee648853afd194c3e0e5fdd8ff06d87d4b4905e57b4afc937901e5dce596a085d5e547adda8aa5a57b9e182939c2183b18a44e899707ef3442139bec8eaae2ad5f8ffcebfa0a66952419d8a14c9469fe5f26ad06a830aa1ddc8eabb55ddbeb5df35ef2aa37155ce6b390bacabe1f796e0619f813bb7c9f2a433bc121a7ec4b063e18b6ecd2ddc504028c068b5a3f0a227c645ea0dcda03ce2415ff68582178d0c1281bb5f0d9d01396876900c483b465f4ed9efb4f43790eb88d6cfa2bbdd1189c9d0df02c7f8062166ec2a47b365990474fd90d559b387774cd21ebe3f7e5709e98d41852ed027e6df5caffb12f0c34164507f787524f61107409c01133b4f06c6aad5f581632a5ef4d7c802e4124a196be7e983e5306ac1a230b5fb140c07adc56a38b873068025ef0cbc86d95af8c220f83402dd8c8144e6d6fbc8a01654da62c44680955ba175ef3e6ebdff1d458172eddaea322d0eac20f215a937eac3ff36292ec4658ab0f48516741910e6d7295f39849c76a88849d4648a1e6d9fdf60734e43f777cb98f2db5d5406bdd3fee73488581001f4f5e48a2d7f7cebe408ed3c9be66ce69d4b58cdda8a384dfbb4bf3ec60c9d2612d9a741ba2135d4140d8d0b3ae1a5c0be0ea82459 +expected_shared_secret = 8dc8bc55a907bcbad27aafbba2cbd957c30794e3770d0984a6323b641e5fe53d + +comment = Public key not reduced +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = d233d2cbd3399facc630a9efc9ff8bdb4354762541527678bc06f066cf41146c426d23b9bfaa6b7efe8c980fdd1c7ef5bf874b1d8947595fc4492e5db0eb773709e580e8cebdaad871574f5ac6fd913de75ec6927dadb54c09818f4fcf92a3831734f2c7ece831d63b0c295de85e59dc8d34eaed7f7b0b910c4cee5fb66b3dd5f3f1fa6eb5aedcb89a6c1766fc83ab4c19ddcd7e0796592a372ab4d9b1c557347ccacdc4644b1e9065dd6dd474929d1c6fb4d686e559ece4bc89a30bb4b8d4ebcf5e57e0ce360823b1ac6e8c15cedf99cf5067398ea80e8c278a4b3d03e434e6d3b2044ef187cd9bc6ce437f5bda6fc264983e9e28e55a8b9c47143d7056da26a56fe7658c1f25d348d6d87ef758ad16788796da007a5fc37358d43b5ebef8f0acea474f0ac07b76802876e99d7ef31d5c747c93774d3cee0c1c67e6d8eb8285f174fef5baf39b50de9a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a1342f899af659cf1b3559ceb5011e54b625809ed89aeebb89e6ea7d6707f4d045ab067e5c42355da6a5c8dd39c8abf3d3785ea01fdec73759e9f42feb5b5fc53d1487316769f817f1deeaaad3d9df76e7ae9f1fba92c3fb5fd457e3c752c275ddfb885771cb77ac3c785a8c562e7aec64cfa55ea47cf8c9deb92f5c123c34655f566235b2f328f3a345f1e087937a345d8d663eebad56599e7bbbbdd8c2e335f895da90b3f6d0e66432f44cec8f89e4ecb2d12958e994d72ecacb89ee3490fdb55654acba5b54971cbaeba88ec4c9ea94c37192fa982becb9f3da421603b61b5ebc8e36cbd053851c77b1b926b17a37faaa0f3247cdfb3ed47f67bddbd5684823634e7ce58cf803d7e36bee542f824e9d4802fda2fa8cfbcacf52b0a56b7cafab0f636021745a70a9a43e3bda8e6e5970b6530a6f4b5184bcc30b911679aedd86d25fe3908fd67898bdcf4be5a6f64e3d7dd98565bf3e42a93e4aa8821cd45054c643eedee58db6b3dfbe3fb5b5eebd1a8a78b87225a7338f2de104c4a220d9bdedd48c86aec2dae781a80c40e13b87eac73a775fd1c9b760cc0bebe49f699d7d39d27c39363bf7b8fc6f07a8a3d55edf1547c48a9997f62c61074452ef25e5f8a649ebca94382d5a4e8a61606b41daf6834d77ef4d95fc0c9c40977ee648c6a3170678b1537cc28f8d9368dc9e5849a9653175acb754ffbe7437be45f6c603e485f2ec301bc4fb6c37c225d7495a584ae33e890ab5c8c36cf68cf4bbb12e3c0a7de9319561a8a6947637aa41edd6b415bb2c0af338ed890b6a3bc134abf8f6585f1d8d15a4df91f4bf5b0c818055b21dea6e63b553988c47f4b94e7c08d1a493b47357d5edc56a4c7df1c629500675876804cf0ba5ef038a5c7fe58e89774ef2a9ffd7c63099d352a8efe560b788b40570996e817e59a96b3a3a83cba804be693443e0729d5bbec6532a1de55d8ac88cc3fe4f2ea3bd4ad3fdec325b5ecd2773964e6784fdfe853737aa64eb675657f7272661abf84313a57a45cef3c665d9cfb7a6f674ecdcc3b57ff6f8c7c8e92db44ffbf5796a96e3b10ae3706d76883c783ecf4e2a4464c40b3a41ca70ae87620866cf4fdbfbd204bf5c283812cad56bcdc345e379c4caf4d85d901279bb2f4ae6f71fbfadb3570343fc7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377cdfd0e4e3e5a30a6bcd3f56f9734d06e9779caa5442a9a16079d81377c76e85e54378d72dc446ed6c8b8f7ffa21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543556f84eeafa26b47f05b735bcebe2033fd076dc8b4e4b9f853533c8f6c7ff38817ba49712835786fe7f14dad1d1cec1e998e0fe0b36e5c4f7157b9418449cedd641a4293c85d3f7012dfacfdffebad98ed26da5f027bd4cda57f1f3720b1fc134654dd5e73f829676495390d0e7929e6d34e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7b1df1535a6e25e437d49a780698be22ac9953949f571b85a68572609fd7a3bdae849b601ac9eb159b3df5ae54c214ee786d70afd4f96a4ff3819e7c986ed79903e5923e477e16663e3e74c8cecaea788535c6c005a64f2868631c3eb66f2d5fd39ced8464fd0f1b578f58c9bf6adfaeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 05e9e8331371df9fc27a1a5ece876015a959e96aaf3b1a60e9e77e46e5ed9d85aba384f63bbc65ad78b2d5a53cb909682badbf37d49d172bb46b0f71d317e6cea8aa095992dccee32f9ef65a29435fffc51daa9f27fabf3a799813e67efdad87ad2ff47b64cc0cae5a5496f45dfce648cbc7aa04d9061e5d78f6687c47c554dd50f1e6821b368f98eaf2f4aa7d738a81b298a81bc43e16c8ce15ade47ca83d2dd98bb918300a26cb431c99aa5f471b84bf6118a4d6cda89863fcd277bb4443cd7b79f4c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7e3e921a66403c587c165bfdd44e012de9ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fcae76f9bb8dc87e6cac344684334c67d4d5a54c932535739948acd6ebd67b581f76af169a89a11076275ced56324e722c9aa9a34bb28a69ad687f92be84456bf4559cbbc0f347e7b36a45555a8336b8ae0ad7e599633f6debb6adcaf86ac9e7895d39a4ced308996ab6c96700e7f82a7d09c9b4b573b70da99f1a1cf56aaad3c0cd6a4f72c6edb5630b22e9c4a3c30d2fe586cd936e3437684ac60efb6fd0a345fbc4881b24372b579fc111e95c66c3ad647ca04d37f9108e4a7a6795b47ea574565e14779772372cc4a79c413d8ec1f33ed643808e939f27571c73bff72adf3e048c4d15c71b4fee6482c413b8e6c6d3a3877f862559b4afbfd4df9d6fd02cb364bafadc74d78b8bcbefe043bd6f32ff62b9555fab5c20d9cfd2dfb9b4b88b8a93b66e3a65b6fb184bb5406dcae7b3ab6047754be2e5251ebaf102356ba688095a8c9eb1a9d887ecf60e864b7b4a5588843922b6d4a7445476997a6e5620b5f8510439b02a4b0deace47cbe4433ebe44fc9ab4c5ef8f739ea637b7e609a7de058a3b59ae7501c833ced9143244cc8ef490fcdecd39f454523ce413a6e8cbb67a464aef449e2b4559651258b9c9ef989093540dc8d202c652d7ecca1eac46eab3f9fce99ebfdf5b153348b7ddb0e373b7dff620f5560a3c64c15ec85b5f8ec0bcc4840466c63dbe24ca45994babc320ef586f3712e2fb1f649a07b29fa255ecfb079ba17acfb857c41c4f8842b9e6e06f9c6a07cc6a5df82150ea6516d688713ced4bb72c18f41aae9eb50cceb968bcf3bda76a9eeb2016d975e98d3dd7b762d9a49b988568cc575a6d34bca13a0f08deb833f96001f4efed9d31d79a20f6c640d55e9a29d6183099926d44e897d3db7636e19394b2f65abe9a8712c868697b46871d830bccd9ae02487e8d59537c3841d6bd8105d3aea769b0335493b84b94c4a498b1a6e6acb57830ebcbae6baf0e960aa975d3f14b5189d51d933c4109361f03461f275f7507f416df79d1187b6823adc38177a02b4afdd635324eb6738deea631784916452c80dd09aac42ea2634abc68bd304eb2ca6795474e4df33e4d58cfb318bcb98d7b470eeb5a7e3af1c2d47d193883cfbc6e8df9049fc9c97b344737ada4818fb0a145aa8776125558df656718af59964e4ff0704318db88d1f9eb84079db96669c895ebdbec6d43f04c017b59b289bbf550a94d0aca4b0fe8ca84630a99b82711a661e9bf02b976e65f53b5dc5fb255a88692852e06bba321b4de88fb5da5eab02fbf70998e3c99bdf7cccb779bd8705ad68b4d48afc4df74c0759fc5bb86fa59fe61688296846b258ee19ad5fbaddf93167d596ec436f67dc197e59b26cef645ee63b7967106f334c6b9a7149d44a8bbd2c5e83e008fe3b6666735a94478784ab6e68d0e3f72876b5476b64f7a3ff3ab4e51ca9b604bc7fd6de395c47d8919de5b1dfc8cf04858fbf3238458f70f964687bb2138adc76cd6a868c3490166cf2bc3afe9b3746f4dc231b3638a3558974bfb16d3cf5cf8c220d3dfe87b3eb959dfb7e5b78ecb71b04d5cebfb67526d138a46501569918cb7defbd489b7fa479aaea4ad6f5d5d6d2205ec357895cccff6fb5aa372343bb1d5e6ceea47683e5a4d094a3d51882719ee7510bef19d68ef647f27e59ecc6387760eb5a810b387f596aa20741c56f7b1c13a304de60423bce1f5ffd92acd6f067adb7d96113fe607d3c7e43e7aa09faf48526c68829d1863ef3f1b734a9ce89136ebae6e7a23de5f96858b6f88e3196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = 043bd3601f6c4fca9e059972ff9fc9f4b3755648b5b2b7784d55a62eabe01a8ad59cecff3f4b8888fc3a56cbb1447673a406c78eaad45efebe84eae7ee2350b65cdd3bb639663f8d16b3c4472e4c5883ece3d4d5d4df51ac66dd0eaed8e3bbb268c6931fc49d7b454594444daf5deb2fb3d11bf3c697e67adace540ea945ace6c98d49321dbc36447858d783bca93ca6723f80077f513e577d156d7cc046af9bcb4897ffbb3abdf08405b37355d5b239967ed7ff8e9bdc2cfd6228bacf845df9de1f3c83fa3f8f83892c5d4c1b1eb809a9acc494c5e5c79c195dea41a6af673fc11266ae592eb3dc8cf63e1b5e34aea7bf27fd6d24fc7988fe20ea38d6e791ad3b86517681ce38962066fbdba89898679ea0c748d90a963e738a3e9968f3648e984c99f1ed4c9533d9111396d21f523959b9baccc43d07e6dc94ba3253332fdf7cccf56f592ff00e8c7e2b1eae02087e0fdc4389e98eb0ba5693cbb7978da6134d74d3c998da1eae4e24f297cdca2467e94684d2124574f9df716253e5359c7842c761be6d57b92b4641ae70330dcedcacbfe0e475f83e6ccea74b74257e37c63036fd4a8819e0bc14f80243fee8b3c3622f90c45793cfc5581caff36b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab9a9d31d57daa948665aef9974df5a2fdd93bccb74763adb7c2fab5853d9430addde1c835c8b9cd42e5f1e54c4350cf40aeddb23daeaaab0581ed9a593487b95a16353c0c7adacbf85c95e05a667af674344c3666da24f04a4e397315e268d94ceb4ec3cc9682b89eae18fd696eff9f7f559375965f817a8d9b3f9764ade7f66f4f9efeb25a5eff89a8c88a46e940ec9c3045c4a78364e2ed6fa965d0f5fcd704a365f4698b2f26a7ee348806b74e1579c2a466cceb2d9e5163d2493443f8ba9e33dd4e03a755748dc7bfc83f191b84093c98afde4286f762d3b5513f996481d5445c7a7c932ceb9c5fbd87edb3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7f4db93c6ed8861576b3594966d4d860f74cc58b9bac05eb5db6ab2d4ca43d964ffd93e131cfe458ad8af7e8d60f847e3695b8a7e8c9858a70d62e908deec38c17e3469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af954e65dc9597392a6fc2068298eeec39d8648f65da7d157ec4b64c631a7ba7b94c6ce7d83f2eb149b484817a6f94fde1a8e76931da4922ed8aa604756c0bb63f897afdb8c6112a4ce22bfcc1935dc6b38b6c4473e3bd639266386ca988456ac844bed84d3fdb7407fc18199ab17aadf0a6df50db4dfc7bb3454a9b29e74b09d4e0362cb8a65e6e0546a3b09356b62da304ef8456abfdf7df63ead36ce75c82f7de41bf7c3e5b87b3eec630fa7a65a4c5867628e916dcf3e0c6a033a8f7571930bb75d89376ba4b06e04cb7ed719d614f468732f6d989298384a9384913ea989488e144be739a78e1c49cad6daf115c55a76def011ce00dfabbb56fb1b3b6469c9bdd8caed61bea5da75af8d17cba85fd4d234fd76cd9ec8ccfefbd558426f99b01ee3525e37c246fd699ed310c8a53c6b36192e8f837cadd3fef7b059b3e90aea315b64ca5159de3d9be10ad352c6eed1b8d3c7966847aaec3561a8ee6f7aca9ab4c861554a5c8eb5f7ee5ca5fb3239595b988ffef0eb86948dff09cbb5784811966b865dd414249b7dd0b53a87fe5527d990a2ee92e37c6c7263be636d84128f66b07f81356bb66d35aea64c5eb9e3db53fc3caf989b0ec702139504fea41fcc782808bbf26d3b12aa6fd2b2ae42c755fd1acbb802ac9b947e3ef7eaf9d4430f34dc7fcbbd59cb435a83736344e7e7a1d6a274882f5e4da4bd732c1f8f02f5ee3149772189fac464b3b26a6456a9374a66fd054f5dcdb06a32b3973aa948a37e4798554d20a7ace817749cdaaab1c87e3b467a77593c035dfdde0a9c71d8efd6529820a5b3bb4e7620218da5e5c7ca86bb78c49fa39aa37a91b4e75b3c5f2e56211358cd5baf781ebc549ffee546ef09b7a7d871a782eae306883a4b7bd70a06b97639a3ca3273d1218a8000b7e85e6d1110dad0195f7a35d59c2daf52e67f662abd800b85fff0f745f9e99a705d0cf4879719a53d33a95b2cccb53cec96564e9543aa14634eb98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = aeb7fa5c47d048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f5898783dd4becc9de28d19f5e42f94984fd0a6d84a8930bec6d96e4e3bbe97b14138e96ed5cb05345c86b96aec66babab7cb9afad8f7740879e8795c39e95ea3e40384ee0bead3aeb931419c1229f86390b9cd2154348cae9cfbf80c537353c8de9762364150fea3996819099f002eedf8ea83ca178d3d2ac4cc5a96cdee3a424c935b673732c4efaa1e7f2f303bbd5175ed93d87cf856c15364958b678e74b3618cabf82ca58be0ad1c656fb3c963edb4a4b509792f99db228c7ca6818fa8f38c388839190a4ffe3ba6224c4c58fec51ece5fd0454d0f8eac86cfa6904aa99f487e2ff29c3f74bd2d31f7f1c687a01efc48ccd32cad5b261b94fa44649c5b459fdde8d4014c34a3978f6ca6b9d667e5d93b87feab5c6f3647259fb1dfc74cc9430d28e8c0cd9ddc947b01d33cb0c08684908ec570a407f5f48a45f7ab68d74ef5f313e678fd5876dcf8e860b5bd6f22768e4ef6a3ad450db5e6225ed6bfffff35f8631f2f7697e3638d4aeebea2bb486667336f4d72c16e180a886e55e44fb266643ab524ab95baee9fc1334d45c7768465cc177a6543376be41ee32e80f318bb5feb10837f0bbbc65fedb5079a24564bb9519e5702ad6bad9cf1f0662c63bcc1bb3e985149c2cf79befc7e0528b3f3a24d6869872be1c59bd1ee294ca50837852f6567f6cba9b5fedf8bda8aa50ff6af2a4ae90fbd3c65a7f03d6ebab4dd8480b8a007cf9d7afb52f2f78659ac2faa877422a3e0809736b576564e8d0f5287c5a73c27aacee1748b159dbcbe9f566d0bd5fe774e9c853f1b8fb7725a7f62d2b48f9c43bfd3ae10bcc93aae57531c68bb32fccff36b2e8466fccfbf37bdbc336e855756bf5eb4784ade55cd54b644f74d4b549a2103b31a0433363337ee7f5f0db9a892906d8369ad90fc77aff4370211d9001c4dde15d35394a70335f4cd8395916ccffe12a7ba0afa4ffa3d00cfb3078cf3105ac40ee0e62d8fa6e22a37f977da4c686a93e556ad835d9db3aa2074a47bda6d5184a9a208fbcdd033117ed46ce58a9e639c8b506cb5c27e29c3d79fa96cb636ee5ea887c11a7aa7484c03ecb793a07adaddcf5e2e876fd3e766f0ee479738a8bbacfd46c5d5307da1e6ab6108356d8ebcb45e6ba20d36d11beaed5cf701f6b9924bcaba793491acfa64d44dc8e9a42aa9dd1e76bd9da0f714bc47252b9b15c3ad8f2345b78b97077bc989c76f560e94f551c3aa783483086edbee93d343a4089c8775ec85091ececcc09ece03d620cc3b92c7af5cf147386dec60a5886cfb6bee503dcde74c579689251199ea27ae5a9388ccb3dad565a83ce397e07a8665b0a9287eff3412d59a82381383d6fdbbbc2f6e4c6707534559acfb56f8f813f50ed8c4ecf846d8aabca027b9471e4308e7f7987a49fdb68a11869adf57a6f796d432446d8810a6353c36c00df8e1ce8bf266efa04378e8dd7a01b6cfb5649d22896f4c26cd6ea98efeb7d390a039b83ee62f61ba6c484bd09c7d3a59ef5364f7a8843b41d4d5c7dadabb9ee7ef4d8f589945e9bfcfbbf348da12e9160f5dc54d965aaaa4a638d79eea53898778331649a895e732618bf307491fefccc7074ca2a7a56f053d9e49f72b74a30e526a6db5c3ffad7dce46363fe596ad5c377c8ff464dba68d42851f607de4b9adb0ce5fd75c48a9ce3eed9ff70b36b69254f37f9eaf8e7bd512686e45677b4193d9d1b59ecd9dcedf0dd6cdface82ef4b3371db257d68ce1cefa400f4ae10de23ad538ecf9db4a3b85bdd99c496bdfad7780fa28d4963d41f653e83be7d83c59692564d6f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d81adb153c8b8147676b3efe6fde3687a4e1331eda83457ca155888946c8bd95d6e74def1bb78cdaadc4ecb73eafdbffb8cdf171885b6968ab52b89109cbf942fed68303d691d3f2271e55d0dc7b0b28f1eeb75abe06d33ed67e17edba40c78109b45cd03bbe2d9ddfe5be9db4a960b4eeea4549fc6b088cc6cc5d8efef75f035357d3a8483e3eda9cec0a65c27a743a010d63ac6a897558e8ef7991469a39f39536a7c7d964b33d260dec7ad9cc4fea654608fd3648751e2b41ad5ede774f55782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = 041a9057ebcd8df95cd5eabae5e776ba758d8ef9c87034d6afeb9d82e9ec06e8a27df57be3dfcec9893e9c0a678fddfe95dfe181993cfe2fc19a86f0d9cc494394b2218a81f9cbc743047161bda551b6c802e44d09f5fea613c5f60940d77c3aad33ff9efd561f159ffc0c88acacff1109a9d89ac87b4a75646ff89d34eb8bd694a2ee40f265e63f7888ad23e4e72d8083cdbbde8ff20fca50d57c65c4bd5d701b56765d316c54dc709dba50a46ad976ff99d6ead77dea4a26874f3dca1cb97999ae3e68683a28996933cae86f469dc903b0c46a348a1c307ab9a9a4e4f77319f0ae296d725bc046df807defcb325cbd5f6cc217adc0bceaee321c5b17565ed10f8d68554c892a9755643a69cb721ff6f96acb64b93966a1743ed298b5e348817e6fa93c453318db713e95cc53f8bef7d6a5dc2a70014738523f4ca0db3052448da31363480d8ad8d8b6b95a62e8a48074df634a58525dd663da939948d49daacefb1d758bb603f9d004fb38837675e487413e48729c4ffbafccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63ffbf55360c4796bbc99d95461c3d502c4fce4e6aa9222db61a283927184931fb6c997f7cf416328483fd632e6b653c633669d45549a40cbdc7c0a64adeb8415975e6bcf97e6ca33892ca8fe6ebb45e58313fda81d174e93be7e1ab5b65e8ff611b4b558f4cd3294336043884e8c9f391eee903035ed56f89925447d3bbea549df376dbfae1a6de4a8ae3d1dd5a58c89f5d0499bf7facb9fb7dc5468afd43ff484bedac2370a153f6b52467a205638fe6d3d835a628ab940a0463eb93814237415397b5a9bd62b915c3f4278ed1ebe6ed13b0310fc1598dd852837657b94a4b5ac43db3fa7179a4c1a430345d652693844959d29aab4222ac62de266240fb48bec4bded38f13d945c3626aba1856c5f8df589738fb5574380b74071dbb401696dec5ffb9de3699a0949e215f2a388fe20a6aa2c364868ca41e83dfce8ec8bbd2e65a1ade9a898bd4615741dcb73fdac5fc7c35503a937ee0cd9cf88570ee4e163bb7f2ea3e5f0249d2bf5cb93b7462714ebfb79c2b26754c6f38f8c9dff28d7a775aa7cb18fcb5755a195d66371fbccd1678478c462ca1896b31ed98d66b3992bfe74cf99674bc646df73721ecfdfe89b416a7da8dae82164bd719ee92a7f83de7aece84cbfce07c683783402539f88b6b0722e3732b759415fbda614c9596db57bd5ad5feedd8139348ad549bb573e3549320f6fec0aa3919fbd978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ffd30c95bfe93ea67a18eaf3413aa6bdec4119e364e558cd66e67444d430bc490a537f8cc188cd138ec7aac45223a341ec6dc8eab495a8deaf03ef0c99eb5cf1e5bf8bae7cfefa980c6895ed5d61ab49dfea7431d7550161e7a5f1adf2019f1c4547abba8bf13b5cb7987b0251cf886ad50709479607f74af995647b5b6e569f75115cd55cbcdc9b988074bfea21455185fbaf467432904ae9528f514e39b3c4e8a49d4e0e493fd5377b95227b3091b5f782aa432ae962d6a907d4cf37126ed71a9640b177a489aefcbe57f1099d0e9ed8292f4cf9756d8940d4f5f98f22d059b173fd7ad739650537bcb8b81359dca702555f134406eacd4cd54bb85a7689a23e6cdf3c401d9c49c2f816f47ce750aac7455a22259d941fd30f118d8636f479b8489fb0da12d09cfb5d4b6a4176fa006fc1288c46af76340e8eeddec842a548be29a3994c53a7e73ebaeaca3a0f8afc55efb6e5e426d496d2a04bf29934f17e668421899c679d853876434e87f901dab52f6eff35b54227ac0fb83e3d3fec3094d5e5d767541c8c3bb4664c594a257ba30fbe34bd28f790045bc1bb377f9d54ea8db52a945642075b0df9bfe6ac87e71177a497de57f83829b07d13558b7f36ae691afdd494b4391396dd61a7f221991a1c6856f8beae514742284faa0fad060ce549dcd34badee268fddfc33cfb3dde72975397a3647a42bec69f9bb663835db983e4468540973c339bbdcb37ae9b2eb8d7fa788402d48dae0ac01285a8c5f3725fa674d14e8bfff98f6c64c2ff2ea4c6a7cae8cde42784e3781b7c3ebfd7badc70aabce0e684c42a4d705b8ac37ee7c0a20ebb3b9bc233845ef769d8a94ed8a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 7bd4ae7ac89cd00e80ba7e854c2f982ace5ed91e9f77ea8c7b8da4b739db92a4bd7fefee3c3e7e16dfae5593ae3b44e3d465fb767b5c265afe32cf8165ee8c425ad0b013389663ca580ba5b94a5e3c3a9235fe5de0f4aab91af40b55b6cf6c4bf6df9ba93480025df3f25c66813996f674cad207fd3498fbc54ea8524e3560f54df50e46fe9c634ce98a8a659b38e7ecbdf934d29bb4c469c66029dfcdbe820cc365490a8a7a2f8b79d95c395dc536f7ced9ebaa93ce59e5f9a28c9562beb95da0bdd0372af670e5b067de6e5af730c5aad3b9df364fbd48df13e619dd9e8c07781957b3d06c6ad4534149fa65f8d5e3733b8b095b6badec8d0fcdcff26e8f5b754e7105e03f7c9a209acbff25d5a7b4d622bdaa817a9f7c7aecaa1441af16606376c845c473b89bc8cbf9546029f632098bfbec366b29e4da2e6b17ae9c8cb45204379a783cf03614b37ff4e1ddae8c20dcd33cd6510b649c0953eafe167826576e19e4f5027bd2f628c92e389d884a8e5975c3a4af52e044323a3d5e30bc6e73d33fd4bdcc63a848483ee57a59e535fce918a995858d8e76cf6de2535227b7e20bf97b6403f1743338c74fbdcaedfb46af99040ffff3e789e29c4119acb125347749f373c304e66a2ba0bdaa51fdbbf185bab6991ed55c1743e7f7541198cd6935598deddab3ad51667ab0fc67b9751aa6cb76b38c5e754d76f96d8abea1f6f68e5edc695ef424c780c08e98a9bbb1227771114baad6a63977163fd54fe31fa6e6823ecbcb536b8e2f3d521583e9c3ee025abded0d5a6ec66396d94b17436609f6f05f26e0a805cb3934dbf4de9f82cfdcfb94cef8dedbc7c3e10c2f31c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63166cd7a82ee5d8a63e35537f8bc6cfb7ecbc3e35975a9bc5c341a7d6967757bb7c67fbf79f7b34c33f95dfa59e8609d8686a55cba343af19635d07b3a23d6442d15cfe59cd4ab5869310f9d0737d4b546a4af3aa9cd0ae58018954a857b3c8992d1c567e4cfdec40dac438b53ed8d8ad0753cb90f6704ce892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71388cd9af4efe00368ed4198fd23884f1bba5651ccb94488166943b2a7fac746e5a21f3fea83b9b23596aeffce7863f9239ffe0fa25f8243ab9fcfb974a73e6e37fe7d278596d188c43684d8c349d91cb43d40ec961e4b51c5eb202c58ddbbed4265eff142f8d160cdd76efb8eba686ff5e72768378f16785247b9c6e1ccd9929a8d17a829566b641fd744bf565eb6ef4037d7e78aaa6809b75c5154dd07dbdea1cc05a0fbed4bacc3a6c3519dfa605cb96e3cbc5219f39f4994df6c5d3d6fe6e0466fed689a2130334ffe99b093a5cbf2f82321551e943ba7c988561d332663ac4e8b367437e33ce2e6240f659d164fe54e4ac32d4fda7c39c0b6ce05ddb872a9b617bf386d7259662cf82363fe9890fbe252747391d53ceac84c508f8339c908136e5eeda92dd38c2e1ebf268a3929087480f393644de7cdec6cd05acfb810b464646a26427cee13db311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b52d99de3c6d252467c15f51321f8b195d8aac196a8b45c0145e9d52a5da16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f6ae6a98857d7f57946fd5925b45a562d9895b7ccd7a9831d93ccffe55a8fedc63cc57a11adc8f905542856594bc4e359fa9f5d4efae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3ca3ffc030f80f77b9b7325e4d2ba49b2bdb0e6533684fc5ef2665c2594d426563ec4afaa0b0e812196d21e4dc4f45e9da9799febcd6afcfd4cd49dc0a53adb687a5ef0877f053c319fb5ece7e53aad13e3ba3b6a7ba5892b5dcead19356e8d68d1a93681833ed4b8c975e99d969aafe1a6a5c33f6c4e39dd65eaae1333e25238303719c5463df178cae7eebae505fe3cd96838b766dc1a35b1258ae672c599b1b993a55ca983aeae29b6664998469f27e86566fee027c4654f34f7e3b1472ec811caab7498b204a55c8c4df0342e9d6b2b9bf7939e9fe4523aa9cc9b4ea1cf1ec18fd6bb9bcaa8970534a81d6199b76975ea8afa8f33f13ea371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = 212f75f949f4ffe79141fadabf85a4ca7dc45e0acfb20c426cf545caeb594907a23be6cdcd38486fffcc1244d54fa47c50d6f9657c91e82ed3c029539e73f08956eeffb67a0f8cbe74c9e793bbd33bd89a2a0a68ef49dac90669aed4f530c785ec4addac4f4c8184bb051780b4f8d838539c81b5d97e4fcb854cbf325af6f3cc65024a6404dcfa335378fe1dadc9fedcb99c323ddc55e70b32a06cbfac8f9e53bad59163c46339b7fb1d90244a358dc647d5be783b59383a0988acf6d5ad979f665d38ab5ff981ababaa1cff28899a352572f4f6515e6f649cf88591ab7da91ca2c0e44af0de6ed4fe74ccddbedb7736363c609eba4656bfa31cbfdf05f4e2283bf8e26ef5ec3ef597edc5429ed28cec9b106849ac366f62e8c1c5ec95030defd0ce749fa3bd7b35eb2a09c731c468dc2988f69649fa9b46eadf44e09d3aca0d4f09dbedbcc9c69b33ab9f9f8fd217fcffeee86f9799ee4cfccc2b68a3d662c7fb443834dd6e0b70ce98478e7cf82a4d47400b9088eb4aae3a5a076979af8ab4244e64b0846a9904ade949742d84d2c95e6ccb0bee3068ea288c9d1c69360a3bd6b21541382ac9b52deb96d4952e89725258cf7fd33ac405f3d12b6f65b884f34ada4d2bde41d660d096ebeca59164f8760e3f74d6643ef8de3043d63a4cec67961c808cd64b9728872f74412b8867a3ef5cc68e74654bfa1a0ac0a253e6f5ce4282ada739bab2de26ba73c4921d5db90ade88e8b3c4dc1f74491c792028515a3dad45e667c9e6870e2d4554556bfff44d09f95fe9dcb73713f0bc6740f3053ec5b7396dc4d0ac77eb01f33dbae5983884eb59e4c7f076a92cf9fc5213adadc47c905dbcd4756de774f799d5477967339f0e455e6898d2194a7ab7f4338946b7db70609cd337f3d5ac876f3d87c6ad857162e491e469bf63cf6285f9b817858b149358cb77f48a298cb21771f25d4f4997965ea38037df74ae7f849174f62fb58f46cc96ffd75f23b4a0ca9da9d69e60e4365b089d9f7874a22ffe362035312f43b6272bc47eec6ceacdb4418b60c61ff502485bd92730ee75a9bb4a8c82ad3ad5bf92f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe275cf68b1eafd003beabc5dd12b8550ec3d08ddbca593c7bbdf6768fb561ac55fd32c77d7445f310e4322ee53b9ba879d61e368b445df20aa17a7ac8f205a302f75f3c679558ffa37efff1cde6c8f7248e73fcf5df6d3afbc5baf2bd76dc3b30465dc198b6b49159c1259dbd964b661e6ac0efbfb09a78941675a21335f7d10e6d89ea6b3cec5d1afe818e55d1134947a547957a195807774a8d4da9c50833790aba5628c2efdfe48edd430294b331235d4246770c293047af37f034879a3d43573a71f36dd90afbd1dcecae4b878633c59b5403abb12e51d8048dae4d8473d63cde0e8d3d295a46ab556c8aca53495683976b2186c6c818b8530d5d20964cdbcb6061b5d910b9c429ba9f11ad6f4e053c9e1c4cbeaac35949c8f23c3e8a0f34caa9db2bc890d44cfa415eaa058a402b7caf4a49f5f52c95c6b6c7d26b4e3d43b21d8bdfff3b37e5d33e391b5e617785f63ef8c68e969e094d83dd62a873ea77bd937046f6d97d8c604edabc1951ee8984bf858a7b68f038a6a624f592125776499db73cc9af94e5aa82d831f44e486abce7cf29ac351483f8ff6c812eef6715634ab69ca71a6894be3bc05dcf59ce6b29d6b7c9b58fb4cdb9295a63213edf1dc8e93bb8a57889a28ce3b19603fdef048a4e6d466e3857c07847e3883c1b7bab8a2f4c94fabb3fdb921ee3c7fc7e6ae8d5f0d547b1ac49cbad256ef54de5fbe7f2b8c3ed6ebf4937338e6614402e9f72ee0e4710fc5b0b8ed5e6659de35e3102cffc81dba972fabbf23756b5e5f4d42ae5b6d682a1894e8439b6946c64d10732ad6d3992353f03f6ec1a136011c5fc625bd943a3464ef9fb8a7b970ab5ba9723f05e5af2b7befe063c35e8c65470c3ff9e39f55d9847df8dcae119efa546f13078bba028efa33bad804dd3d2065b8d997a7207b595994e817ae979ac5174137eae8fbd88295f2cbc77e02cdfca1e9ffdff5d902d44a16aca9dad52c09e77471d9320ecd76e1895399741ee79d702b477a3dd7243ed3dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = d5ba702b2768057e6279f6ec4b3a599015f7057841424ec09d17dd940fcbb10aac8b8483f12be044cb83efb8315ff38fecdbd9d1775e1e29c59b1759d894ccafcce47c2f8debc5fe84df58465fbd15b9b1900fba12c6669ef941911f6f6fe364d106a9d486f523ff5a0298cb5f4dcd6b99d45f275456e8bc33efc11835b31e6aa628f5de28a9a18226c73343479d0ac61e5a81c6a38c0506477e68d01b6890155c3a720fef1efe51660c376cd6ed90d933329deb31dba89b6853c273dd33578551399164db647665ad5209e3831a956b8ab28309ed112d9b0b055ba765cc75587df545b670fae3c6c9e7393666bd6a9e08bfeac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837c0f600c03c9f9fe481414a241766df53da6dec7936ebf374ecaedddcaa58c9af984094c57349a792dfa48e48c450ca7136ad57fbf858b6e76e683e6ae3ee22c44643fe4fcded7caa55a628b5d3366077059bf86afae57e64dc5999ffc3736aabb5f98a41765fb949190977457eeb5c29eddb24de3431d4b9526a82459a0f78b9a7e74808a59f43a19d2d8c6485f887ce62697a72474a1fab0d144fd5ab7a8d9ea38d4cef9662cfcebce77d63a59d5c6fbe9bee379b5e055b36ef798e7b677ac31fd5bd38c700ceae7d53bd2e9be9f09354ae074b4365ab379667744363b9d4ba17c16eef955631f1ca916a74cdefd5160c8f994c49688e7e612676bb0d95f6fc58d92a7dfb71c3c2a35db426eb32b44d5abe6d5d0a94ae017bb299deea54588bcfdb9caa8cb5a2dbb0283d454085871469cbccbbb27aeed934680afda6ede6bf9b0e4a0fabe5d1349f647ec9ab2aff943c88dca974af1c95d01866e917ff1ca0e319e2bb4db68d7d4cffebc077835cf9aa565f26903a4b53c7b5d29c226144096ed3a4886a18a26b99f389a71d4e84a0ee0aff8e6d213be109ab7ee1d4114678d1634f547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fbcfd2405bef464cc60c58efc595da7ceadaa3ddd8fbe63201e9e99b38970ebf6bf0f333be37e662cfbcb483dd1156a7f0e6dbe39af9ba9a7a6fa8173033bf4283e526db1b2d4914f453bcf44d6304859216ee8c60562442d9c87a76a7d3f59258786e6c64b0405bb8bfffe34be617bc9815bf57b182748cbc6c4e8cac9aabff965e560fac66beef3ff7c8f48c34ecb3223e9432ec704bc821195d41ae5510689a8d7c4ce5a6c3720e9c8461e6d2b3b9de703937b05d1c9249fd4bfb134998ca657562b19857f6acf585f64eb2bdb27e5d04964fd3f97d41ddb755cfb3410eef2e4c46663a7b557afeb41c5d713e7ecb20a7888955689fa4e4327ff135bea2c6f811adffc3924d8b26d92cd6c8fcd6cad8ef34e129c6d5fb8881725a3b828da14ccb625a65ae7c59f8b7888b0cef6f2d8ae8457a273c453cfe69726d951b4af41df583af9995dcbd7322388456025845addbca1e794ca5fe4276547d3d740a96d8c3376feda195f4e26b90d86955c2b4c857d592d2cd75bcadfb49b6733bf954fe76d0dc3b3e94d865fdac147fd3ba0f336f0397c6fd450771afbfa5837f56d96d3c673c66fc9ce79b5e978c2a40450ed36b4331d386a769de3b9d63b93455b694c5cb3837e865ae61b82aa96661e57c41f4d5d260bc7ac84cc0e1c7515c47c320c61733e77f0f57f599958dfcf4a408eab7f1b759d6e487a243ff13790de64dbbd1b90af233d8658b2815e52183bb221eece017795ba97753eacd6620a85d5ef8591aa6c1f54d240e9c22a9acbdb568a98eb745ef435805cc00c37f2b19ffc1a88b8b80cd05bdfa69c6a356889c2389ac128c49d628aef3c844ec85b82a405a2e1834cb753b415f3f629b7397713aac7d7def01a7bb3db86ae13b4ee5ecc78efa90eed8c77d6938c9d3e069e3478dec38c98a80edd34caa3746018bc32034b287df732cbda9cca9dabdb795c6bbe181576e6a4e3c419674b646386c6fc0ec8f5167fa631bd87851892bb07f7fdadb7dd9ae70f29e00e6d87c29eab57fd66a306f0973c47fd6fc331287ded0f518039b32e7c320376b0fe8f788e2a8ef39bedd977889c37e2ad258d4feb5f7426a4ed147e743bd995a97c2ad876e196daac6ccaa92f87edc6826746fea53ba9d0e9e549a448fbb43e409d802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 718fd6a4b96ff9bce16a585f4394c4e83574bd16364c0fbcc4c89dac6f31e5ca75515e7a335536b08665a136b47cf76ef816b037f9ec3aec389b34e1f3b397c70847a4fe78509357db63a5d5caa883cfd79644af120dee18d9b79fd9f74495da7e9bec39e479c57b887e854cae0f8d17c84f5de9ddbc2d42fdfc82db16eafd7f45c458b05f934d08849bef6bbd90349c4bac3ce45cea51d6f2744f65051787f85d9a30d9ccfa8f50b42cc8e75c6d62a5a53944484578b26295de06b8717508c75e8df78388e290f64a412bc3f84e312ecb795d15c17d1983358e65832d96073edb73865fe79662943552b6abe1bd24e638bd54a64497cfae57e9156da70891da159c3e138f86c87e27376eac1fd4f8fceedcf49ba48be52197de4627ed18268d278ce467b3be6c8c689556e1660cfd3f597fa6478348f640e44530f966c30099d2c96f5b46cc6120fbfd835d6b01e45a9ed7a19f2cddf14cd346aab1f2cab8e11d32b103d4147b5ea8ee49b4cce97734d8cc9f3e076e4c9b1cb76e1bed2fbec4d1f6bd8294b280cb9ebae45cf0943c04bf39677b7ea7d7e266bd4ca8ce580578768dfbecf11af898143efadec5d614b76a93f2332ad9c494f2fd9bec822384ae1886001e8e930692263965e949319ab94ee1b6763e56da091f780428aee4d446a71f54722c9308d5e2711ab1764efe39467aa21bcf454b828a8d3d85f33400d659dd8369ddf7ebe219d7651bae89d861dffe31008e5f56557cad53dd22cb84a4aa65ae68c3f278b5816b86bdf5718834df60b54a8606b74ceadc483f3639a578edb5f575b3fefe03b349b6938d763dbf4c44f14adf92f75fc19e658d6da3279ea52c7856a04ff521799c91bafcb65dc9a683b061647cde186ea2ba57a9aeca92a4f0ef1895f2193cc6944a27ef688f7eeec11f4269f8c9e18c4032b731dc8f7fe2a3dd3479528eafc2acd56a829ff31c6deb05c6383b17d19088f225d732f94f73eb9655b2a4c5d14f56a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd85dbfccf86978d8f53be3b09e43ff5dcd98cbfa80b4c8f6a3c8a805cc6c69b7b02ec4f6775ec65268431057fc8decadd8c4ba4965d67db44ab0c549277f3a094f5460bd899f7e483169ad17b60f9353777765157bc7e26edfebc09ea8d7da53b0ce0c7e5ea43ef60f7d5f22b5e9937a48492cad79d03dbdb0ef8db4ccff21de12e155501b3719a3af0998335887eb05b38ceea677be4a4b08623fc12f459504f7400f6ba5af4a07673464118cacd99a8ae65d1ac2fa235173412479cd769e39d18900ce6ad45edca5bcf30caeb82b6a98da48b318c7fdef7093f070fdc5a0b4b95d986aada54892ad0324d94ca9478b89d825a368f2f19fd2988e95fffc52b64602929837d0b3efa65a61a9eab61d8cd8706e9cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a4337fd8ff943261c5bda7a4f119fc9a6b7481f05bc40fd5ca6fecd0b2bceb946f33e0952f348dc4b8ae612c5628d5a6a05f837597c94ac16e658c53f3da8ccae56adfa5a8156638be426cbef3df5861ce05da76b0e953c69957e649c5bf725ec7726da1d2ac9c64ea80bcfdc1b866c4fea987f3d790b64b8aa6be2bf44f9f47585ddc8780b9a6e1e7a3c041ff6ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf57e86118fe9df88962c4df010b755e10fcce9d87781e4b7188f5fadd6fa1a95589694581a18a188143d23febbf8769b3da59813fb963a78adb8e8fb6155b02889371df684e316d134e738c78fa03da9c62d39f2c074f5ffe8c2e18346e605fa6b7c4723ed65d984cd17c8590c3df86586e162e6576b4d3e2806bcf628e01fe5e5580f364f79f0c45470bcabe181bf59c65bb552253406697e248ef24b9dd45295a0eabd689add6bf2b5824cabfe6dae44648bd1f45a81120fafc4c7682e4b7ff8bb446498775785f942bce06389c847ab4dadce4c22c4dcbfdf9d1f8ec89704c21faf57481e4f7caedae97e5b5577efddad545017f66f08851edff446436e168f7a1e834f270b38e5ec60223be724d6d54bff81747739178c49ee04ce0fd39d5e7cc65644ae9b6d303aa54a28a7c0ec4ac2cf7e49fb8932ee26b67c2bce886a5fc903f2f6bd6a030ad2d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 843d6092965daaf95faf2fab988fbe28474bab8785f613df9b46da861c741619619a74a96fe3dcb6334b6fe379ca4d4f95c5571c2e43657c956e13ef2a6ad3733aa24a83f24f99e06f85e4a8db8515bb9c7fc4e79b9b410c7e97dd849c3a869c6887d5c79f842aa8bd005f69cf0937a0d669bbf54c9275e44935f245476b4eb5e2614eb5732dd2ff129272fcb76a5f791b635b8bbc6868fd519365d8aea7bbce8ffc693990e3f8d78b26f9d22cd9e1c4e7795445fbb857e8fb4f0a1aa6f86e657594e65d38ce8163d7e6d778cd63a284ed81a547fb0ffd40b889cf814ecc334e45a68ed31f6cf18cb8e6355cfc428e7f1a6f72977cfff71e5f5257cd13b373bd2a757dab65d2ee863ca4b7ce559c73ca919198ba574a9ee74d47b85a6afaecc0443f7e090dcb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a60cfff8dfc4d175c2c8bc812d5b3d54695027b9ebaf657a60d4befe7562bd06f1bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b603bd2cd036a25cf3816c96deb45c2a8cc7d623bc31e98e1468a7c2b85c20abf7364c4956b6c30c8094af95dea233c5e4d34898059ead25bd4dc37d6b60fa9c849dba306e2344c44c06df41cfcaadb7851685c73603b429eac840c6b9a7ada53416470f143e1c32e801778e204e33a588981f67ad2b4e97f1cb8ab61e6a7fe55f32b5545a3a35eecf43e67a4c29958f06088b062c8e875b632c1767789563bc947a59305afc91ac53387925b4b3c7caf4d84bbe26d3b88e95f433eddca4099fd3429962be6cbeaa85a3abc46a27b525a66f670d8d1f6fd566a75581986d043aafb99be6009f87147c55f990be19515b125963f734db12a4535d0bffab53a3c5eb8c2500ca5efabfd26d9311558d863843656c59a85b4a40c08d69d063cd2f7e15d96f016dd59d3577cc28d3e655db811ecce3cc83e03a5f0d7bf3ef8576bd45fd950ffa908f42f4ad88e494ff9f4ab41dc3ed7e48aaf1c3fa2764f5492b7bb423632e42a6c31f3f05293f7713a86b4e83e92abf17c69b34ec3afce96f8c23a674766673546db7f7dbffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c475652eac51ec963493c2d72791d0afc69b58bd5463c544a3ca679b43dede3ae979bcb158744d45639586959d6ac5785cd74d0ca2103f6696c6d7a206895d495f625f5793a839a573ecd94bb7e39b609ebecaab3e44387c46a23bfed3a3d60a679bcb13a7c88eaa7ceea9d4d3a58a9831f15372826ad8d4f4ed0e3371e9f796ef0ca50f1f8afbb5b83ca78ad7ba50276ca2244b3453edfd804bde8864e81ed57f04aab2bfcbea48cb949f67deeb65da945fc3888afc3744ed898ebeff0acd11a8714665a052746140be68faf6c151277ce03b9f721d34e74f425aea6e37f536c27ab4c859a64b96baec0ae1abe982fbcdee82a48539deff306e5abc8e5f7fbc46d20378c786f6fd4447fc088a7c06f7181bf4442f6c0d66dd028b54f88482539dcb5ffabc1e25f626f6f816069a8f9965d8aad9baae9b9c8734a207e908733a4903dcae54659c375de2bee81b478e08fb7ad85983d88d9a4c7bbf688febeb9447191a63a11cfcc709a2d9489dba469adacd35664aaad90bb8b78461532e86368e6ec5beb39ad3b1e48fd1fd468a134445e183bcc353dcb2b9d15b1db036acd79f6da42d387675dbb292985dbcd4b954c75b57bee52a4fad9edbe2c8074c1998710826b4b1044a1c368d4808d081d7be1668e93c2cdf46739ef1043f1ee38e90ea989ebdc9d6d8568eaaccf1e986e4f3b39b596f4cdeee320ad4e114e8dbf464f435680dccb76e0bce2a0d5950ea7763eda86fa4cd5e98e9f3c95ff713b006155438e9f1145dc317589a5c59961963db674d70f47e5bd394742747612403f9b95d603533a651a38c4119c2da956384ddd90b03eb378474992636ec1db079c3e9c92eb4ba9336f41392995d550d9f71f547344e78f780eb9d2dc84b742b49ebbf56b6e8e49b9d4ba0293a0b4d731b98751b7e371059b84e3f3970a3854098d7bebee497d4f478bca049bec50ed3681ab8d44e8884468d85b4834e3148f5b3a5ee8b743a766ae66ccea133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = 6cb55b5e77c06784a223b9cd2d59478c6d8d2e79b1de0f803a37fb55ffac66498ab106f2abcc61b0fed141eaa935897f8a2d8acf9b3593aa90fd9d81b8993d48a84aee0f52d8ff8dd48571f1c3e8f3effad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9d3eef8e959f0d75b1e11486f197368188c8eeba30a0865712ed46f9483d3e953a569df29a0dfa68a35374e6a2b935eaf66790b74cf00f74b5fbefc6c4fcd24feb61db55c28d2a99a67436bf5879835bb42fbcd7b9399dddddea6d5739c2c4c4ac2e7a3e28a06e6ab367354195d5d80f334e0674397566d480cdfd195736db39abf7d6ee03deee9da5b1c58f903afe59ac3baaf5e47a2e7cfa17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd59fbb4dcbabef4cf0f844e2a6a4db78053e272f7fbf86d8f2c6f33dee7db60d641b295e9d4a468486818a9375e074b1dfaef4cd44c05fb975899e92666a38ebb79f0f8da21d2cd359ff4eb4167dc1cbfcc40cd86bc634e384f1e0b5d5459db6f45695e59cbd4e7947204c62cf0b61c35fff3abfa1acef4229e456cf9b374c9ae7c85664f6ddfb575a640074354e385e36a5b0d373bff41d5cde2edcf0daf35f3bb18a15eb4894c26b6c6b8a4a9d185a6be71f7a1f27ffa4e7597165fea357c8923edcdedc7a103f78ea3da052abd5692dc7dd699a436b80017354d10669850eb6093ad49eda3a07674d65956943b96c929e340056e48aa8c6837acdbdad6fce4a341e5f6d437657388ba7b773f085b9f1e457d24c5b5ab9198b7b7a6b848db4daacaa6b17bb508365c34b8145aa3b2f6be1722345d80554919489e49433bb558a3c43feb13bea36746e5a63eeb2a6afaa1532183550defacebf4c6bfebda035faad063becb2276505da77dd99935b1a3bb86f666de6506d3cabcaf8b5dc876fbfe55feaf4acc4b6f8e0347a6604f5cb2d95e2a3605075786f9b728b69d5ac19e13f2e7e663a91f353ddd6e4f44cdfcd50b69968d95bfabd7c0f45f913ef8faafd600943a0ea1578955b314fcebcf13bb4cff6c1794be1cb2bd8bd55bd860e36e539cdccadc8f9bea1afbe83dfda8b657e8bb1d8707889c74e9f737ca3619f4fb7da7e783219882b14c671d5d05c45f540cb5621c6409366adfae73b7995753afe5bba36e66f28ea407b5e7bcce4c65ee9588b630b88f621eabe39567032d76716b9684f2e7895e8fe0ce9473cda40e0065c2e9ea846d7cf9e86b93448ea37fe30336c7eb89e3d0aa466737c8aa34453e5cdc21d098907fdf29a0be4b96b6e718ad208aae9d479826c585e1f8695f9586b696c805f0533970ac5dae753913d44ce0cb180276c4caaccb81e69080474b40d3e02a6f71fd891c1a788a264482df9fb47549bd2867a8024bd65287f81bf5dc18771f8f697d8a830559b544dbbcc8c656db07ab7017485529f362dac79783357b199b09094ddd5d474227bb85035f8cc5659fa2be575c779815f393866a48b0d6ab267fd7b8635e71448b1d48f0175baf92bbf99fef660f6730855e64fd4faab8480871c3b2f844cabac95806faba397abd4bae319e7adef23faa7f55abee6e43efc5484efc32b1aabfa03e71cbf4c19f5de95673fe66686182eea395f5fa76cc314f891ca6fdb88d7b82f5c415b83e0d20b5935849ce3de38aa26fbee6a5822d5fc5704b1f1b6838dc88ecf0b3acf5a5869ff576a58730fc7b98646edefadef5e15d841bbd6364c7202abf59a754f74a95b32179bdb35888b0872c844443faac6f9f67aef9d55e409dab3e4f4d6167725e960185738df3a30930b4d74dbae5a07463126b9c6caf57ab8cc893758759b4d24f75cf2f745bc6337e376f18716bb4c5b8d800f91488c8e20a9dfaec84cad36e6664ed4d72eb3662838c1dfa27e4a3b86bf5f22ec350469582e75408ed36141033043e459fd8bd087077aac23d58519ba1d3edf68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661f0d7a8484540363321a0897600f4353e7fa1b18f52173c874f5e5e543ca12959235537cc403e5f7d8e015d462e228f131cf4d3f67fde234441cf5fe48aa67cd9bf9425d8edc9c421ed797b52343c6c792e4e8a4001936ae9ee08f4d80fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = 8045b86a3d56995a847dbce5ff49b59a1b9aec2e88c57fe4fb86a8008f38c5e8b63d7cf9447bb60a66f10ba594a40f7f4d7667ede3e0b678523e87830a469e5a758024fcce5a7741a7368c790cbd872d4f6befa71c2a6a0cf8dd15ff6e54ce75318cca9fdc5fc1bee0f6834e1b3f986cbaa0f0283377bf5276c3d4dd4c9debf7ccd4c98bb1f6d5abd84bf824a6206fe8672be7918432b32359feda8cc09ffc62e86061ebcaed2faf3ddc83b55f52166a55fa2b3942e346a688cff23f72a19fc22c6ce56bedb63214bc7919aa90847f9de579c6eacab979dc638e68604e84746d92d7b365c3ddaa978bd999635cfb0c44a81933782d5a49033f002f33853a4559ba895f0b5b37ffcced166f7dc4aa6d064e6223a11468db591f8dcc3db5c8da30b97a49741dd61c9cb9c7eca6924b6c6b19469645a44395ee59248a3769e64d0fa8a86a9d1e86c51917d74d8dd3e2ed764ea650c9aa9f1fde4831363e571d4d4126bf0a2d7d5544c5696a69daf7a748ec7be5bfcdb3d6f8d5b3d2f1b8feeefaacf83ec5ce3bb6a26a80e84e4044087487648e62f9c5daef9cebc8b5c02ee9966e6b8677778a8cc6b566e8a26c6ba74753a2d943fcfb838b7ae4935a38cb969070ffd08d2ac8622b50ca4a79035a403956e80fe698451fdbcc093bdba58d1496ae7dc57420fe6b5c5e85a96f77ab65c9265eb4828d972ba55580cb8cd274bc58a83041c7c0359e91cf7c9be1af4f23f8ee999fc2e0fa979fb4aeb3648ac64534e6c3823fdf8cb24569e0a3e506396140c7ff05a8e8bd483d70d8e32bc38ad19b995cd9859bcbd6342ccab028de857ec77ebcce2cd9a09e3fc7de1443f6c588ac33d8612b3b3cd5ec670c935b9eb973063a327d3047a630ec0337593ea3357940d2285ec8363bee2b8626656669b36875875f3269fe9fd5c1e48879e58746daf4ea9f8d43ad3975de7cdf59f6588376682c87dbd2cc3e427ba5017da3d167ffc7b6ef08773d60ccedbc0bd97e7f6373df3bf89647ce6792f2beffb97f98fff567e6ba833423c43cbe57b517d09d46c8bed6704e6bf3e5c431206bc3d6ca5665db9051d882be08b714a5d054a6c0a44ebf953c493693da74ebee7236c5cc3b49ffc6f30d0f978b73d20ff75e26f375622bf6730aab7ed79dd7facf6bc7a038b779bfbc43877ef3ebaedc472d363a8b885d8de7742af2c365d6fbeeffa6ef360c55aa9a5f8db337d9b41c79e8ae730cef7ade379ec996f39cbc98c4efbb818b3c34cf9ce1b6cff56a58f98cd968e83156a5617a579e130af18c94d591ab630da4fff415479c8343230a9f150b39b1f8f59a839eaa47db9a083f50a8992c2b90321549a15b482b85fc66deedbd5b302e73d294df463a47cc55bdfc6b7784ebe8c6b487b185898888fe590fefec1c757d248cb712b744a08ef082b7591b34604af799f9b5ce2aab6ce94645294e8b02beabd3e4598ca450238d9a708460ec7fbcb708c5bb9cf72fae87e015877886db7ca864b0fa51347b4d723da2ec04e50a8988b94498db76d229f788520ce59dd9c5692c41123a6f141d743c99ff761345d2f685e5f3a924f6f0d82ffcfadb4f8fbcc95f5a65b327f8624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a34020dad8384a2955462be7d3237d331eb7742349876eab4c2c943e33d3c833d185f129c5804bae454bd947da3cf3bd4405107dee00b3cb28396c28db501f7d158dff486f8a8238f652ccfefc23c3bc123b6c3d6acdf079907be49ae2b52efdaaf3dabdecab9fca9d8694cfd7d4229835f4ada21253878eea39b4699049d41abc8c0b3f6aec29bb22e84713177dc0e7b5abfbf455a246d03c6d66114552476a18c23b013b8e2d66ae5d12ec11709f7608cd7699f499056c1bf058c52dae704ad812678b4485b82814bb6960a86c3454b99b731d0ee5ca5fcd05f866b28235036e632b89cbd9aa4a6e70ac944ab82671e34ec2ba3b98ef72864a85e06f08605e43775eeef063fc7fd7a39d3ba7aaba5d7357506c550bee9e3788947a1863a262d9cd12fd02735e7adca5f1087c985feef144d4d046c55388eec56577adefaced44df30b4fcea5ee3d0e8993950ef1ec34c2a6054e5d2ac906a6e15515345bbfe25dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 6db66dca18e96037d1895a6e3b2d716244d3b78438988fe1d33331312c8715e34929757ad538e5c668d6ea9bf22bcfa5b4c7e8411732d7bde37c5c7ca9ef85c02634130950e1143160f6a34cd64dee54db1b3b8d64458c7859f0965e7892c5a169eb7ae87733aef3b16b5e33788ace5fe57cb41ac0e6be3c403441d374aab997500533744714a84dd56ce547a10c88fd617ebdcbdcbfba49edd459f6022b9098f6ed07abf198c4c4211f95964aca9e7d301344e313b5da9c1f44282d9bbb248aaf96ab9efc9028cb9a298838465984647aa1e204d97c74ae24ff606194447f4d3ee55e98e2ace2afffccb0c4b07c98a02997d68b4a4f14a778be34c3632d4ed4c3e788e3b7d2e54d75ed7a215c7eefbc3067f9c67f6f5bb43b9ce35e79f59ae13cdfcbbaf85c34ba8fe26a331e1bd610893e0947495ccbee297d47da04527cdaeac69afce184fd8c855576a4eb4e6f7f0e3f6a7e543498fd9fe1fa536e997829ce9978bdb82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e795028e7d88a4d04c5586c79cea558d8c37e4dfbf3e71f6e950e287850fde9d975446fddbeb0cbcfd4b7eed832acf1d2da28c164201638111ed997fb36b2d24c6b349c390d4a13e06aa95d4de878830827a440985870a4b628808fecbd9ae231754620ad64d2a9c707fe0a1a7cabb9a6ee8e37ff154d43fdde23c3cdc4125ab48775529a86462c34c01cef8a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a717af7b1576561f78ee346ccb75ad7b71938677cf5eee2a83ebeff5afd4d8ccfd85a4a342decfb058c6a138a94a819c737b6baf4a4493c38a52c155fa302535def8e3f1dac31e09402c07f1a4be675155edf057bf1b85e9c8b6fe1be69e33a9e0e70f4c5ace3fbbdee6d6a6578af4d765f78a7147b5dcf93f4efae436b559ae37388814fc64cda52cebf777e8699a0cf39d575ccd08d3c5ace5bf3b6f028494594b53d2f3cce349f29b4ad3eafbe6503f568669df79dac06f58f254838e5b0fdacdd3ef9a5bb893a6ec5576c446bdf034088e8924dec3bf8cafcac58ad352d0ab34d0659332e9f66db85bf57bccb688e4bc74c107d4edc203df643db17b4b710cd7ab0b2cd1d908fe40bdf16f6ee98e7f3f1f5f314e95d22015f309a383e63b77447d713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a866d3fdd8b392b6e6f55c3783c28b5308a4b0a6cec757b677c475c615e6a65f656b4868cdec6bfa723c66f5f931b738e18cc518cab93a7c942e7ebe27d239c1168dc21d7e0320fd179e9506ec57119688e0df98e4045b77e87728496c2060c93f58e9ad2a79ed115d1498891838d80f494ea8af6602f2dd9821f4f6a16c26f3380e4d3635fd3cb77cb6c8ebcf2bb3efa8059e7ba3ff18076f41e848e3ba589569a5a653dd1947dca04cce96e88cf304f8596fe912fe9670b9ac97c487ee2e7a77b7feab3b9b2e5cf3c5d4c8657277951b55aae576524769ca5b83b37d84868367d7ea3f3d9ca4cb717ec352ac3da2b3ac595f5a25fa00fcf68f85ab656adf7ead8abaaa370751c64f51473b13ef6d7b3be289efbb008c45797c1b5bd5b5cbb8c2dca419f85be36bc390ef5c4d377dc8ef7c00b59a44c65ad11d68c5af4b2b675cf41ddd2a1b7844fc9a6c32886c75ae893af514cb930e4387905de970178e81f7b43c12da8071969b868a5b457f9b9dd4b3ea9716269cc0068d8bad63d0b063f22cf3ad1377e80cbd7d608786d849d79eaae958e3435e6d2224d75bde7bad87db28b48dbd0e7e39a7780589cd1c8eb6623fea874968c875be20f08ed988c5684f3c9ba677add3cf3410f83d6e3f5d8289473f557eb2cf978fd4e95fba614ba76148fdc7059d5f7a73a2834996b4f32a8bcf78a444fe5f7a9148b57124580b8bd3df89ba646aa42347eeda9b5327e6eb6b1aa351d25988e1cf5e7ef563168c005666ea90852193f31ef5ba371935c4c0abe6c6ec0a1da756ef390c22d621bffae253d89f845511866e6779c90aded593c8e5dc5d8b2d67f6a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa5bdd1c10f374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33a2ec308cd5f6909ddab66d2a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 3756d54cc692001b531bc5a46a5cb02daedbf255e9199cea303df3a4367e9d2ab4cf5887c766f99efba70eadd8fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9ca02f8476eda454639892d992503abfea8b82909ad8786ebec6ab7d61ce89304ebf1f99c6ed256b64c78c93b3e6b41f72d7ff36371ab2ab87e23eb732ac3d3a5e8948608dff528a38e2afdf12ea72bba8868c855e3064f5d84a5ede1e918b4cbbe6ddd01a5637bf9cd22128b81df8d509ea72a0f66ad98df57f5f9a31cbaa39183f007adfafbcdfcd7781f1033257d766f78b4c4aabe0c5c8f08b4d368b393a39e7762467463b29a7baf4307285b898badbae485a63e739ba5a7a091fe5f53fe217fb43177635aaf6ef218850a1e9f4052a9c0626a7f11646086e76225e52b65d8db2d5fda7477b7e3bd659b999149af14b1fb9a3e770999bea26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa943694f9f763991911681c1ebce5ad5e5bd5663308361e3bd68332763762d47ee14ab31c9e4e3df8457395cf61c69ecf3834e3d5af9dae8decc6ed39ccf69a79c389d44ced7440a248964cf69b6b58a049a8078eda0981639d68ea8c39ae6f4296af798cd2556889e9697bb8e56724e66f10a57ca7dc6131386d9154894d495deeca298e33de5bd9a94dacc2cdaed8177d8fa2beb5e0a7e8056e43fda893f0b3eb2c6dca8bdf8797f9768fc82d9bd6a05f647916a9cb84b69ce63fedb5a7ec4eccda5a5a4fe8c52ebec6584e6c04665f9f57699706cb9a497c2e96757af06783a4aa6a10d8707a8d3a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401acceb8d0c8eddf679a8bcdfdf1e917376a7063339f3cf507bddfccd6efc7a75b00eed701124ce3057a8c28687b2576c640bd0ea64f2a534aa4bac9fde1735f46ee2c995f82a9fe8a2fd51d64f31f7ac5c4353be2205c3b75e8df54f775b9771ad19ba935f698bb6cda20fcac759a5a0734cf07791a38c7caa4da86b584457559e7b933ac585dc4c43785e06f05d2fef904e75570c7ccf864c4bb7c49d6d6ebdf7950e49433a94e643f78274fee7780a5e1e4cbf3f1de6b45994c29fe686e4e133bb353dcadfb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb1edbaa60e99d90d50daf3f6702f8134a4c67ffc5241a757e0ecf485a64d4907934eea5fe50365341ec4ef24bf09fc3f0388c88ed9cf965ca8a119f97bf6d893559a0f3696e77b38d677a7e9f4c788d67047cf8281c8a7f71ab250e77ad87b4f64237078dea63b753a22bd88c5149af5e4db9294d1e4d4d7e71b6896b840d807e8e627532f3cc604e64b852d4730c8330ea3522868db4b886518e9670e7ed0826560fa6f304539eebbdeae5fe6840d3dcbe69ac54f6fbad91edc98d5e3956534beb356cc6555c1d4f25b7862c475ee55c4452458d63b5cd4e105b63daaa90f9a6b0769b161b3ff49fb64010a91e0b4410d86b7bd4c91f52eceb19ea88ed9ac5f0ec81527886897a8e6697c767ead95c8e8fa4fa5692459f9979ac7b8d78883aa8a445a5af84b1b86c4c7aaf24a5c8f3a889eee0c768bff9fd75a506ae75f9d578c26c8645bc8a8bf0441b6eafbb27b6baab43031047c6c8f6fc98766a176ebe16f6cd2c37864fbf3f434de5fc6d1dd645ffdd98983a6f73e4dd0d5486cdb6786685e37846dd68a8439944ca11f9a5e7959ad43ccef5cc8c742bff0bee733afdfa41edc34fbcbc890b7e8f60879490fbed25da0399bda836a68cc0b58de7d5353b4ef28883cacb94c797b8cf9df3cad9bb9a18c53b47fc50aaac124fcc07c4ed907988f38164f46e7d305a381e5ae673145b0bfd8ab92bdfc28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c55d57dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c7aec7e1589e98cc995a5afb21288057fcca695cdc00e7ae05d861b90a520eb3400283fa291f368a3ea18243ac62f34cd80f7fd80436d0454aed978115034407f3ddc1a8e3c62ddc3e13a26d3f83d4b7fe254ac3f7e637d943528128ddd6fb35f0433788d470b72e6b310a63d6feeb374ad73dd8d98d3950819937e7f66ff954caaf5fb3bb86c80b5680861e70141aee59cadb23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = 8f67f12b9b824d17ebdbc45143b4663ada61eb7f608ea85b82b49075d3adebaa7d01bc9cd916728dfef1c1fcba51f4f732d765766d7d3e574c664d43d717afb96532da239250def4b12df6a8f8b859f4bcd1aca1531339069d4c3be836130dabc6e7ad43ff36a18f6c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f28d4302d75e0a8c58a6cf44e24e19f5b6d5538385089400e23bc1d1d6b2cdb59f287c53803fa18dfd2fb78fb9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74097ed423dc5fe7d0d99963c5148cfcdc82deb0e0ecceb8ac64947e86c23b0db1d8f5805f81e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af98cd5042bd494fce1daa36fadfd34210383ac09d99d47eaeaea975c489211184d55db561c37fcba9881acb88159c74bf977e14759dfb7a4cbceee689ee7cd777b3f83c54850f8d82e884a7c3b3333d7cdc73e8d5347b0160a4b67e46a24d756106cd9eb0d43b66a74f98599129b52edb5e971c6db6c65867b3545139990aff9c088b7b115cd3d10a7fbc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d7ae315c73e36139ca954a86302ca789cf7b508fc57ea35bd7d3ed5d543cad66bc4ec9b93df67d2c0e9e56e372fdd7808f4453ebfa309267622477df79ec579317d5293fbb502e50da5cd6e8069855573378377c44a950851dcc62d6dad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f625fbb2845a3de2480720fa275dfb33f84392648c6f64ac85e3d4a4d0f4d89cda13f0874231cc6d2bc8d7c99c0540d87f61856c11de80e78939158f12d3bd65df99fa52ade768995a8f3bd71ca82a189fafc8cd5f9bd7db30aa18edf5180b73d175382159aec3e5e35fdd4df2068c17feeed331ffcaec4d4c694e8e7caff352a510ddfd3179366249385a2db363a8d9795cab6ac1ce1461ff0d96356bc6b45ea943c5028771eb8c58097966b58f1bd25d4ba2ae83635e047c8468089c58ac851999b7ba027f67c3a6e20d5f23fe5a41b6fd44be5e03f6bed31fb9b0105ccba387ccb7fb6ff1bb27129d05d7af9a73ddde9ecfc19d85be067793ed476b13f4c250edb8e1d6b55c63bb346b9ddf44b9a5a5349b7661338f4cc9552153e5267d69f82093642b9c2361cfb57993b20ffc52e9ee8d62375ac95ef5fbe81a24badfc165668e7a36817cf80f5873f87a6dbc3cd43cdb2bee57f0e06c93aa8d7b0bc32de588808fad037db50b3cce4bf98affd54d0dc9566ee9df2a4c7c34fc4369987904b46fb1d04cf355e914e69d9ef85ddbc56af1395f9a70ea261a3fefe6f6510b5f8643693ee89f84cc3987e3694cad8f8ba3964e637925c3dee270744fe5ee90b4bec088a79f31581b074e917ece61c1ddfb4b8f81f6a6b7b1392949acd277b9901637c3454a058589299c48b350ea2e0f788754d81cba76b5ec378bb83789f63962befaf1185e76ff353c1cb3632ccde216e94f4b7367789e46df4acb6d89652b946a9b9c2b62cd55346d61609df97fcb190c43faa544891745ca9b97950384de85346279e4ffcda63ae4dfca01dea361ba7aa4d66c9d8b1f41ee1faba37280be53bd788abfd4491a5ed551d78ab1d69741352fdf8c032964717fae79157fa2069cf43da46a50d46c61c79cf4a7d1e093526d75b445ad8b0ca984f2869026a4432244d662951e05fba655ac54d6dfe83e8587f2ec4767e66b88f44da2b5364e3f99a8e859cd6ea68edfb33be9c8ac3eb7814669079d096e6d6befbad0ef6f81047e2f008ef5fb4bb22e65e9bde410504ca76df9386f73b54bdbe140a5b548a48b063e3de873e19bd30d6f691323af409f4603c7bc24d1d3111fba7dd5acb400e9e7ddffbc3f6b1e6acca131364d00ad794866e243ff81deff9c16aa82116ce70ede87e4d34db33c2b394ddb104fd5df49825fa7c6be6fc31b6f5626f70566affe3f4bb50c5859707df6124c2f46a83c3fcb62ac65a5a66557c2fae31c7813243a1f0c4b905b3ea40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a18f5ea96daf29c8e587bf5832356c1f976370496b6fe7493e58fe0dd9483f5e372b093d38ff9b9d1a83c209bd98a363df8a3ae53dba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = ecaf7cb4fd55c38ccb7a5a78348cc39f6d39a21f6d369495687342f9b7c7c88a5f0d2cfb15e6836663ff17d6ca8fd85d8f9f49ede8c5ce6572d816657d5755236ac05a1f574387fea7ea7f42785b4806fa74a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33a2e384aa9737af3a3e2d8812256f9a76c50712ba306c6dfc88b85da88b716b4e509a95876355fdd49a2ec7e30600abd2788e0311d62b0b9be3c97343e345e90ef5f6b58cb16d9da3693d452547f4f658111fd745329406dc8a698b7e449888e2554c5b049d76f67397a94cd13e4b9f9558bb0464a39074fb6e5564a4d32b5433d3e0dd6ce5ae146fd448bfd7a089447cee578c2ab5d091afb9ceaab2b57f420a56cabad4387d7969fe5ea1923c14959834c9d5617d6ea68645aa61e50f0079ea64bb16a8a8fc08dec9f5ca74a28d3519792ab169976f886cecc709ab9dc4097f0fee9db59edd6f205de23c4bac153f176a4762706da0a78840314fefd5a7d1b2fc793aa8dd9b9ee381acb0b66f5e00cf140edb4c7f8e6eafb87cd774a5063d36afab5b293c23598932ed3658f8453b958c1846c61c429d386343436bd4c14ea3597f84a2207d224dbf9388eaccb8ba0094f5149643e52dce2496992982e486c4fac9b69feb2ce5c4f8c6bc0adeb8de4e9c17c38d68bcb9e5e9e171fee63cfe1c6fad0e67ff486f4ef81f6ab58c49ba67f9c92bf396f7bc9cf8462af9bd6d2cf8b0cdaffaeda8b829943f64456be2e4b7ae57061b3f5bbacd97b656217d65b36f575d3ace1fa8ee57abba074ecc1bb4dfd5328d85e13aed84ac8d16652361b67a02c41aac8fd10fc339c53b3e096aec2fef76a67fce1a5700c034014884392cc6eb4f9ad80b5fb721d53e2245537e76acee36f5316e0b8ccc4cbff41a0f3c1f8195cae8dc69b644c45f68ba7c4484327d5b3e9bb84568c895b56352ad9bdd8ab2773d54384c117ef72f6dda7f2fe58e5f68ed0f47f625ca37337f9e53a87d223c1cb8d7d277b726d0c7ee9386680fec4b05e9ab8ee446a077b6045995e4dd1ff289014e43c7ab738f52faeeb3f69c878b3a7d979aab698c4b57462339703386cb5ddbb05a8f72349b0433dc6b77d8c894bb409755dd5ed9fb8a84e6ee678c896992e845908b963fbd4d7589acded4e4546b9fb1da98c295bf3a53ca79a27859ba787a7689202833b87893fde2bf30b936916cbd38316b025a5b1039a775b055d6b2679758f67300f985e39c88a1ea45413f7e378dc584e50b74331ec73d76d645743c677accf55d1ceed9489a35d65448a3cebdf5ff8b5ddca0354ed90b57d5c16b6bc6562b5effe62ee67861cb62e0beb440dd9878af895e95b4e14f8086c7c35ce46f50cfd9babcdb0f74c7678da62a5c8a82348e7b396b7d95bca36e69ffb90125b765e1d4ecbb3fd339ea38079567a599644cbb4d36549f276e5fe3ea6232688bd1694d6d7fcbf04c91638ac4e8ced8cefcdbac5efaf8dd93a03f82b885e5606fcfe9f5b03dd99613ee0914a50d353ef10b8d36098d6d9257bde27e23e939df8ee951883ca94ee820e95ff2c6ee21825f0121efb8adb46d9d4d0ef099ad3f4e2eea953f7eb7e627a762de88e7af6ae0b93f190c9e950aa407145f1e0f549560fd49213c16b6d4b29cb6dba67b89947bcd82bf2700569f0bd6548944dedde3bd133877e44ae858dc46b6b547e7fbb1f0ae088fc3b14efa48e5b49040ed00eff51e579ed36295a16dacef03c797444eec3289ffd87434864d62ed9475e758b6c297acc679731ef91cbc5f562cb9409bd7bd81fe5afdda1034c6fccbccec88b72e44944ab79592e6598660dea280b8723c5780a7ff0ce6ad930dab0075bbf09b952c217b4ad8b707c9ed6f905e90ec5e4176aaedcc3bbe0a9bf87689500bf565e6eb01f0a3f2d9391c56b6e6a9363d434b1338456313472ad83dcd9374c8e8e788fac62d68694df05bb88a6613fee4d13cb6e18f69b373cf944a7a76d4ae6157686ac6f50a98b42d51be5aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce1338e4b27cdfb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d6df86d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781eeed6a49ce383938a9f35ff64aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = ebafe3f8fb3af02330f61ab15d3a31cbf578990de7b419430d89df4ba8a595efccb6483e46e5474518ccd033543065cbe6a5755e97790d5ed9a5dbe8b124992d885494ed3a262c3da395b46a069b9154c81294a7dd59bd092b69acb3f6220475fc89faeb639ccfb6fcb9c549d28736a944af921e9ad865c8e147d0ce9482ab6b89fa7794fadf73bac5e6d24f455a78675f2ea8e74cb13876c82c738a55a4649304cb8f9cb2ddfff0c1ccd6debdc5291595bd5867fe1d5236b9ed3e6eb25a5dc4da9e625d3aa712af449e1e8a51a88a1c5ce7ca78dc3ca950d24ea221bdf71a3bd593db333c1ccbe7ae380e465fe614d4055bbfc61e89596ea32433a7038ad0cad8e97bdee5291eee4eca80bbe9f1f2bb8163cd580fb94207c89471da649ee7cffb4f93c4b6baddcb88efdae9ab6c6e71f54814b8a2eff67ed486d88dd3d727bada47c8ef949dbdfb93c3a838eef3c9fbe89be30fa739023aca492549d53ed3663b97d83e8c02ed660696984aa5c5bc2de9024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785b4ea25703627f0a51bfb8f3457f3c0ba43184a77556b8cb117f32f58d488dbf4f8b03f5bf9ee6fb49c8c329bbb00dc9ac7751a3aaf22217979a83301c15f8b87992b87cbd5c576c806b4e8c383d60cdf5ce93e04fc5abcadf35ea3745895d5019ce67a799d2aeff4f33bcf2811c612dcd9b4bcef410ae8359134cf4f657fb5c96bc544f83b8b0272db5564694284452d9dd467716bf425d4dbd6574f5caf879b674e9ec85881df13d09f05fabe8686669c9365d2f2cb9def360edb9e272b876cc75a0237f4c7caa7e003cbd0b8bcb5b8656fb7f55f0c8be4cff398f4ed6e47ba27a93489647dd53edcffe9f63cc85b6277de8fd73d3371969e7b78d326c9fc2c9a5b1d3fe69ffe8ad278a8d5ca563afe0ba44f148e45217d594958bc0eb7ae3b6aedaf606e7e39d472dffd3a7f76f1aeb46520dd497fa537fc4e9ef2ca0f28834ec0ac07c1ebb22b3a1a2becfb467958607f1c06e516633d3f6fa774dbdf0fc03cdcac3b74d3e9c5b23ceed5cf4ebc48f067735cd6ad2f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f618f965579be61ad812d34361695ee638f9992e93676f8ed9575203d66530cef7074cbaecdfc1b25c520468a4abbbdb5515d3cdd33851ecae8cbf7726396a15a63dc36d78368aa5a8ceb075e781fd33eec27cac42eb9e507a82751b7c8cb7b3548bda1a58c82cb99da9cb926f4eeb5aaaed682bb8da2c40fb679ae5ce5ea046da39eb6fd117e9ae253aadaee32938579d46e6e0ff9ea1d33640e3b71dff652e85c786873e1457762d33de99c8edb1a99dd0a8ce052849e1f8a5ee15deb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02917d32337720dda9ba08e74fd2dafb4439a21fb979bff88f7c7e01c1d4e2c7a9002b353dc1c80c0cdd797455640c6d3b65c4cdc99f54024d79fb33218ae5c3106f72c1430002aa148daf51bae5981947d27a5ef2413df9abc3e4947da94e8d3094881f40e7a8cef48e2c951592f439ae5377769496425e3c99c695635e34358e72b76b8ee9f9d1063b05ac774d83a3a6b0482ebb5fb2f07bd181fee0fc4b7651347f4b95e73fda6d686e58dae91a5c9975b1bb5b62e8093eb9716e350e2d340acf9d957cd5b5d874dd60a7c9716894f65edc5986e378c830af8ce328ad2784e431d48714223c83f8bedca94ca5e99814e23e1c69481f38ba87fbce28eb3dc1abfbaab2af3841e3e5d38fbbf0c4175a69fb4db66fe54f1bcbf6b9a1fd3929b3a58a85245bacede29e59d1ab21537cd797ee91d25e85cd5b4f08af55a2edcb42bc0cba54cff58d750b56933666cc57db2504895a22e3db43c5c176590c9d97ac7279d6dc55ccc8bed4e8fbb34ff40b4c635a936beb5e7ef787c39647ec088d65f7b2a39517ea4e6c381a27d8ec05a6e55959845b4567a4d55864c566d445ad919e834b77a312f8caec6a0829bc243a9330c5fd10e7fe49d77f3749efdd014873bc79f628bf5b1ecc782384e0dc8accffbae89cd415f6cc03e7640895c744f57d7e23da9c9ac6cbcc7d729db69ea7c6d8c8a9e95ce438ca6f89c4e419af6ab094fe9f8a88753ca8b70fe68d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = f1564b8609639afd415e5b757e7a6f9bb5e20dd8a939ed6c7ad8581fecb46c6dafbbb444ea375e5383782708dee1e3753a4aa255a4917f1c8af889f3f8397c985dcbc7e5864049315f7e8aa283fb6bf7be35694468f55b454499357e5e460c6eaf734f97aeadf886d9f865edca87a9501fe7e4f5d7c2b637f368ccec78ef36d6cdd469be9d0bc7829cebf14afd28c8d93b59a175df71ae9736b6397a4b8c9e4fdd85a705a4987bc56ece72caf58e543bb9d25eb259e735ca95edbb685d5158596e6ea411e7c543af40c5addbceeb6e6aa7acc7db5dc06dc1798e3051574dcdfaa38d6b8eb595712c8b758f88f7aa8e944f65d598eef0e926486f6f3ece0f9e938f5ebae4b6d059d11fb7f16de8ec005b376bf6b1171654b5a3ba932bc9821eb8213343baee8c9e74796126d6961b476adab27e45722545ee2a8ea4e65b6a7f1bd20795d5d7d3b7dd77ec1bb79610dac7c935e8a8b851ea5c3115f5cadad3cb259f3baa686542e83482c7f5474381409a4016e54066d3f420e9934addc5a32ccb0c1ed983b96f8c657018bcd014a34020888318ae3c8296a5fda3937ebc61f3eed22b3bd0e7a6341bdc70d2beeb9fced674cd7e612363e7fd413095561ece5c323e38efe56c67877c520fe7476ab183af33f358d1205a9087ba56a938900a0cced7ee6462a5bf746ab679aacebfdeb1b62b78a2efaeaaa336f5286a84fa76e1fab798749d8ebaee71c48ef7ad8977235ec64e79cebcc349863a9f4db61d68c1ddda72d61bd61f0c42e7ce79c12f8d882fae91edf2d9747ccfa3f6e5ef7bc97f57c24892043aba249ceccb94d5a677e2779444ee39bf9139fba09f6d1c99c65a7941bc8ce378f682f49db855d88273e56fc106708833ff679c5545ad3b64dbfa8d9b831adf54c4be9aa6184b1ebd529bb9750efdcc6cf5a39c7e39383876f633763ddd7feb8639406d53a26bd43e6b736b13d9e77431040df72133a4b81ed28db889fedb88b0f5a49d77938c33a5af559468b9ee6184bb9ee9bd72dd60c7fdb2a34e3bba67493fb9a12e7b8c4f35497fce92b4086b484e402e46c97dd85f12d79a9c9e5160c788bc65fa00c8ab88c5d506363ff3eab9f84b5aca7460c99fd15fcd8b3c4e55621558ef0ad2b5eec3ffd3e0a34d5dd4d4561e8bce8af738cf75f79fd56571cbfa76faa6b1ba9b0b9c7c8e8c9349e5d4952c8883a4bea2cfc7f15f88411e9bc0ffb28883e0a80ed40bcbb0b91df403cfc783ce83853658fb374de5ac9badcf4dad86b088daac4c6f640fbc5eb9a9de08abef49e95bf357eee0ad521ff9e0c0da89a1193d2adcf53c9aa8ed15bb4bdbe6d4ce4d262895d594693825ac0dad567adce1c94a6c27438d6a64d3a42db2c4c47400a9817b2f96bf5dfdc688957c7494600870e84cbaa443d76c3decc64b3a3b5e311f7c5a3bcfd6fa37c0a1c9804837e648b5a5385ce19dd73ea44370368e82c713ab2e399656ae71670a5295773d2c36b6e4b934599656c88d8f13044084b8f66684feb6c6d5dd2751de5872df234694a84397aaaf3b894e0a85d7c3a354dc44d9ccba4cb16b53884d6bf8edd5a17352c4d331b89de597fd31a8ae5045eebcc00c4a921aeff7dceb904847987f61eeed38c5d5e841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c46cf471ef5f019b952c07e6a1bc4d59549a8c0bba67519ad501dcfee06bb34496f38f9491c27ff2bf4e3da2bda7effddccceaff51d3e546c8fcccfdbdca475c926edcfafaa3ad534fefd42b2776b04477b15ffc705c85b3a7c5ac48d3b3548b132c6af8f9dba88ba499827f9a97fef31cfaa0dbbd4b49bb28abc92d9cc8311faa8dab45d5466e1a36b86549760cbeb4ad474e99a35811a63cfa00a8a1b0cf12ba75d7366deaedf35c259dc8f5e4ca29b30debd996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553046fd1e48c40648fa842256163bd67f887729e298436485f10236f67f96d263c9d0845e71dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99394cec35cba50024e63c84977edc8f02ebc9b5ec5045c6b1091ba7953d3e8bc5fc7c8f38a635c23d4ce3d9f9e8d3adf5484d98419aada78fdc70da55906ce97d2ee4c70d54fcc651ab6aa9876430d4d530ec7a7a744e89a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = 15bd961b45dfac07f1ae79edfc4a847b143d9caafd2e7a35b6e33dd78b761125bd8c5bed6994cb8f1ee86dfabe637da51cd85b8b39678af4c337bcb4fbbbc0fc36dd48aa801f86538eccbd3787a12a09b42e18afa2e8c77bece1b13b5a8404cdd8bfce374d46ae059a4ca5de1e4638ccabc8157b97a238a6fcba379bc6afda874335956d23253770eece4405bee3e37ef818b9826743267cd78d0ec36fe6fb1d17adf33467daceca9f2ca28a2867bf7a8084daaed1ae9d2e4da0989e98136cf2983df05763401045879ed65b0a8f5012f6f6a35ee8cffdd216a3dd44a9bca32bc74a6683a9debae28deb189bcd8feba2db4fcc3b67f151f7f4381f789b38d1053e96bd9ce5da7fcf7674771dc55e74a3efc0a55c434497a517c99cb3f76d36fffd83cf66d87601dd97b1ab5dd8dca86de94080da8c2aea980b4ae115b847786aa96b94ac828e48e3e4c7fec633cbc6bd3104ccb226d74a6bfa8c757a455ab38e1333435c3c30d94d8faffe8e77c0260b6128865bc37b82c7a6a27614dedadcac336ae0b569a2cc53a93b77f9728b84b75bd1d60fb83043d000baeccc9c4d7e7a74ee2e8d47ca600174e1d7369249af61d6c6f40d6be5d2fa5b3229373484c8d23bc8e78830062959d15d4c93cdbac41d967ed4daf1cf90308f742efa78f57b70bcf54a73bafaa94bdfb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad1087e1aa27f9ccf857a15bd00206e675365f3ad9c18b947bbe9b3e31a7571b9e8728479710d64dabd569873461e12a9dc21d3ba39df8e10ec8d5a79d24e3d756cbb4a3ac9e48435ba19f86ae89ac3c94ee8909a4da5ff6a92fc90b5a40f239cb0e8b98e86b5b07ffddd3764e42e8c80a5d52b1f66b77fe64b3b867a98cb29aed995d44b5febc7a1f3cdcb3ddcd4f3ac5f9d5444797941666afd319a3c77e3ed1f3e338b4ea6e2b548208cff577ea6fc7ab5eff60c2d8a703a67eafa381c9d576c7cfb1177b6a66d951bd3c426fa79cc7b552edee97c92856b2d7d64615d79404a3b5d8b49afb9c87ea48e19eea61f8ee302deca25a6a599947351d40e48ea52cec894dc9b6ad25b79dd9d3c35c45031ed71dba35ef9ce1e18aeae5ec7e13468c148a5946e9f8ed13f1d717640e5a5767a4fef2275e05e395331d52e3f5d59af77fb14f71c2f5e1f55dbe168aba09d3b9effef88fdebaef69ced005797a8f316e2c731f9581cd455300f35a6e1a587265fac6eb68ccacaf636cc7145e6c2768f3e5aea30b8fff8c46a8932550dc6f4dbb8b6e0bc5ec3d64d89fdcf042f38f5cb5988e56a1f42a65d5d788e265ef60487490b579051f7433f685ad4bc53e7fe3cd05fe6b0991ae37882d37b5dc084e5a49bef76da4e9dd3e24ac93e58bc05f8a7598a5d74e156c09e73e688fc00a6cc80ddd482adf70c7848d89cbfc321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a093e4b29c81e31b63a008a51d283bc217adefe37d2dabe5c7257cf62a68752cf942c531bb55abfb4fec5828f2c91cf43d94b598fbb958e5950fd4c8b2fecd06bacc318f8fbf73a83f7387ca35fe4fa8d541acd2d73e89ee7b4661b5c1bd398ec82cc8da173ede64a38b4ceed53a64db23d565dfa5470dbac90e7d475d7b3d66f08975a7045ea558d5774b249f7d634e703ee0241db6bf9ce545ffe7c68768400c3d721ba5c0f77b9e2d795d8d59145956ac7b77293ff853a3c326dd70a9fbf56775c7281e8eb9cb7134748cd0dd9f32c9308828f6d9ffdaf49bfe1cbedefc67ce0ee7730093a73064d3eec951f69d44a5f7317cb85caabafe2b5b90ab2b805b8d8c1be755f9a4c342a96e8ae83cc4394d7399df13bba0d35c45393730e51e8d5355d06af6fd38445666cbb7c268f3c59a9d63ed8bb8c7cd22b331be153af7c3590a1d81fac67d96384100f449525ffe83599763ab739fbb8ba3ad64a41cbe1679a1c613815e9a51d5e6f51ee73431cbad479cadeb64ac9409fb39dd798a4b6d3e07f4367fb68d3ae2d125a6d5ef7939f341a59edf0c07bfaf993f8a74bf8ea7e0e8bf9389ec3dfc498a50fe839b1f68db8b70e82670e689b5b3e333908b6e8b4a78ffcf49e798bf57b7ce985a42a5269435d8eba55ef30eb5f31965d476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = 8eb8491c85e7144db7774793b8aefbb4186a7e3837e344e4af6aa21116ef393ec4f5be6b764ff8e998a721385d7b24f11d8a7096c54ac42dedda7668013cc1565e63f92fb1cc144e241cf84dc87b5075a81397f511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e49f98872552f8bc4b0efe632255588ee99b4bd373a21c665574bcd3fbb357adf37a6cc69108d62349d485447be94b76fd2e9e7d75c6649ccbec1df71feced666351f396c08ebcf0ecfa784d45bd4d64847fbef6dafda23a4be727396f299951f95a68efe55c5d4c792e136148aa35d0663d65ffc040586e44b6cdf60c54e1cd8f376dd1513694e27569a3d6c6ed2538937a7afbadbc2ceb6b199e4ac77c65922ac49e47c74447b889a39344ebd9ddfebd73ec5c48263c215aee947bfcb806668b3fb83c0c97ad547989836a540ed35348ac068a69357c7f46c69f963c56359d8b9963bdea79689b96792248f4faaa920439356d1d786a64647247fbe97f9c4f2ba1e2897728cbab136757ac5a752436d8d7eede20aa6446a4800eeb621eb8f2c1b6eeb7c5b84e764d8355ff60e5bbe7abf75c4a44467e5d21ecae5a569073475a74ba62393e37974bc072cf7cceb5bdcb1991d393784ea8b28f259b128d89b4b77f9b68ab0ca953ff8257a39384833e3f4c5963c5ced1eb13f1d608c2f41f7cf55e764e15636eeba9812ec963f359d2c44a9f9f357f2853821ba0c91d5c489bf42dacd2ae637b210fce654e32069a8bacef3d4eaad570adb8bf8d95113b86e6b5c7497d6924f6aec59da46dd398444499ba5f89f13a84878e88fcebb862bdd4264d68f6d9b4b83aa81c9b5433d7d868ab5364b8dd870b841b2e6506663aae569b025c5cc44bfe5a78f1fd4ddeb6574d0088bbfb7483959892703666da17797dba514a489377be9708ae44b608d523073efd6d8347cafe63abdc8f2a52ac959593bdb0c1a5b4fbb6e4840ff6354d51dcfc4ec124a9d10cc2c557339325c69afd91319853ef7a445c4d64d8e66895f8c0bc88778605f50c7fc3190cdc55933b5874d63d14c5f83f472d7e340faf6bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa111efcfa9ea612887e6f199af377be070bd97760b3f11237fcee4eeb95b798f2787b3039f9d2e3ca5699aab0bd4af86adf5e5fd6abaeeaa5fbc057f5a23bfa2905dd6cad3de265c793028e45573cd1d7e5a69e7d4217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbeccff5805bfe0daac80612972ac06d6e923d3a2d59b1ac84ee217872bab85cddba9c7de381f4efb4c574097d95b8afb595be9ec460cdef0a761f596569f99b7bc75d5ea2fa1f91cd45493cdfb9a3c661ff4bddcf6ca19984a1f8945ca5f98ef30d71ef83acae02a26818a4fd04ccee4889e39ebd637ea035c20c3ae176b70999c3ffcb795184fc73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab5dd7bd7afecbd95c18ad6de7ed35aaa45fe143aa1fc49630cfc8a09845cffe260ad953b71074e43fd8e265b7473db4d179cf6a03e7ac035cc1124540a4a47886b6e5b04418a86d777e73aacf8930f08c2001e815559c1e04672bf4b851243d11d7b3a84155d76279f9778a72ac9803d36506824a34524c8363ff224545debeeaaaf193b778751889957d518fa9e9a34e6e44840cb7dde8efcea3e3c5033590e9ab54c25852aa8b2f19f52bed793bf6b972b593caa3e7ba278937b6d7c6b9b8f79069fbe55ffde0de722465006373e2f76ee366a90ad1483fdf76e04c388d61646f026f195d36966d75dcc89a3d97bff98c79d9e0babda8e6aa2084611ebb558735c076576e20fb3858ceeb2876d53c5777f146876e5502074e0731ede7a1b773d357d81c5fb417eb9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e778f9529fac02bbc0acc7dde26af7b724ae7e4ef1b1a4a869034e71ff79c49e4d8834f2e1785709599df88fbae653e6aca97d42846a53dd3eb04f3e813cbb40cf6c0f1e34ddfaaa3285f26f74e6d9788ba30f6c79efbb195dc6828f57752e3629af3494db886baf9892fce9489ea84c73b36fd5cbb2b4bdd3d664ac2df46cbc9bbdc97d8ea5528cb4e925ef40e544a74717ecadaf5b0515e587173c9fc851ee0ee0d027ec69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 85e9a58ffc4aacb3c4773f7b7065e5c7fe980b53b36557f0296742b3a793268e38d877f8f4846ff113df706d4d092847f11ecd59165b9dcb400a97f3ab79bd137566d709a5a706fdc7a794843e920f75530d9e5b1cbd86e53fe45dd74ea1b557f68b511ff8a1ec0a39846cdaa95cfbc069f2e3cc52c7f59eabcac2d36b5535fbdd7737768d73f2024afed20bd229cf72454fc794d794f40fb89fe8b1a3e8326253362fc44bce193fe87f5d1864acb29bcaf3cdbaba4f3dc593733bd99c077534cdda88f4ccffd846b810ba71d2139fe105dbce88f1fcc5c9ad8cf0baa4a430c8d8554ecdacfe6251f8b686359c755981ec4c8fc834cf800e9e5a9d51afa87585ffc41dee3aa9babab5baf0204974a10bc36d4aa1c87d6a3838b8dfccb1fe26d38d78aa78eb3594998a20d7f3384d5e2f36683b0eb87199764b533077688a9a755c2c38632cfa4c2047663e96da2998937703ba0f1780ff367918fbf08c9e7cbd44db69577807ef82401767c258b38b0c6b22ad57f42b59a6dcb2eab480641e6fd3beab65cda8653f6e8683cb64ed53fc03a5f6d6b58f18f0f60dab1d78504de8d991e68fa609e758fbc64c594d32b5d7be17b465684df8e65bd5745fa8d6512d48f785ecb9b207746686aab683b0cfac43d08ad1143e7cc895a513776611b981f05bbf7e1bbf8689f3992441186e35b394c6dedc8d64ea47971994cfb46bb779ff48eeb372994f3ffe9a282799ca63dac7c8ffcb2d7537865ee0f4c73b1ada85eeb2d3bd58175780a287ba9a435a0fecf4fdf48ef579b55deeb5564ed1917de93fc5cbf013a8c06fec1f459afc1f5c79df37782f824736ce02adea16a54653dd64e9058f918b5552936dbc87e36c0d9b2108862fa6f244597387afb078c6b46308436144b75ba9f6133a46ce1c44ca7b5f52a678473e91d51953a516a1c947e020df36ca6fa8dcbb671cbebe92035910fbdb40d8672317aaabdbd4bd8b71701d4c3eb49c1e5bcba8ee7d1596e671a5d056f5f78b845afd6cbcceabf119d86fa10ad77f1c69bfcc7e6a4df0cce979869588337aadd7d6ac7ac3ac67b3d34a035a1285ddc30c99c879fb9cd74ee39e8a23248a3a6875e25bbce8c6902cfc81ae878fa4caedf585f3d40e3fa79a9ab08894014d42d0dddb0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b14d3489ece3159d459733ff1c7752864389ce3bcb826608f966342147d6a46f6c4ab84258db571a9487bd8785c37a7ee1dc8cada99abdea19b144acdcfbe8a17be882ee093189efca5ed08799b5dc46e46e571b47db74e98e326da687fbdfe1088c400067ee3d885c0db3fbcb336416c743a8e32090971e2baefa9f6ca7bde86bd5ce39be57665595337687743beaec0eae2922783c6aba7ffdf4d19de42393bf6b375d732cd7a15a987455986252b82351f3e3a4a54c08b599f1948d1383183a9fe2dde7d341fcd9b3cb4149ac98eccd54f17cc516c67d9bf65183e6143c6640eab513404ee6987c25454ca6217dc986bfe0efbf4e058706686f7cf5f82f95635bf4d34da0f32e997c18409b1d4a9eb7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54ba3f8cc59f842238ccb6b652da7cd37ac6afdbefbe4b894dd66a70b594df200ce9bbaac111486b9568e37269732f39f4ee15d2433f9c0d1583bf99d847c3dd5a3ee98814420c6d475dfdd47d97326a4f4c54bc9e3b4c94634ce418db9a03b6ff6ddff4c69d74809b9e023a5aca5757d3a789062bc3067698a60fe7fb2c73566d9a99aacb81b99088ad87ed64cbc56f301754931048999a2b9b0e06c9f35ebc41b390933deca3b7f7b5e498e4db782dd53846c7635bdeff6e89c3058dbac2a7e88338a58f338d6c7d75013f78cce876bcee8cdc0d326e44745b5dd920abd4fa53ca742438336ac4f9cc337b16368a8e70a1d97c5876e415dba67945e62636a8800ebb87b66865e4e5371ff0edf89d0514663dd73a961d70f68653bacfb637259a395c500565b6b6ad5b3f6555fb249946c9904ac4d256d63b1d7cf34408debaa5b1be8be0299a7ddbdd3781983f8eccace5c85f3c3bb3a9e6ec050e41758afe881c33a9784e48293374ca497cb59e13cd7a4b6b420e3d94401bf4cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = 16e63cac9bfdd05a60cc5930014ffc9c566b472b375e8484843aac71e74bf13e5af59a8a507ed4a53e59e198716e2392482d475306fac63dfc791fc9ae2351d88b4256e7a82c4fb15e54412f0e30d6ef538834dfc06bf53e8bdc94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e6776640eb387bd88f729f2ca47d9173e9d8f099f263caac7d7c0f81959c5be3a0eadb5c269760036a5530e6f8b69ef6b47e77cfac94007d7c975a59da7c04fd7f10af3f509cf8204faf04073c73b474d74b54cec08bd1446eb144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613d9e739386eefe3cfe4dc73d4998a1cfd6a2ff278b6f68b1f118e51b857ee913b3578e71befe502953b820bd85650bd027c4b66b8f7632afd1ad3f86052ddca4f684f2fc65f32dcac1db9c435af18814a14cb630b6be8411feec37d9fb327dde37c8bf12c895b103e6f0ead1cbbf50881966d3d8f56f65e3cfd68e383bb8ae248e27f3b479f7a82eafaa565be21586bade1ab522776b4abdfa16e3a798acb005e7dd40ff4a8ca3458b8f6788bad9899f93e4d8625739d7121d71f0d58d67aadc630e55ffca45bf03a1778941d41776eb1ecf3ee899912c703e5dc8e88ac448bfbb0a0cc3bfd83ef336eca69f915bfcad6ddf640957fe4bf6febfd65f003c59d39b7fa08edf6a76a1e839ec8353f3f145aa3b8a9e2e5cfe997fe074c49fd17e6d3e6ea2788ad598f8d96bed5fcd7aa4250a7ac4a5314c94fb8dc8b563c6b8f626763d865c141474c73ce439ba701276e986ad61ced9679ac94983957dc99c4bd416eea43c893bc7d7c0f633788ceb11d8622ecd8c47954ea907ac1513aa3c54f0dc48366f4d45c79cbfc3c5f4163f4e8c6669e53cfc17be722ddc7d521558180781899afe681a55693398bb8ef712b9c515e7f255453a3d5fe2bb7b3692b3998d1bc6781ca28fea483c276a93dfe9a62797a897d2b25870062d8512aab304799a99acaaceebe699993150c4eaa339e423bccb6dfa31a7c4fbe4997581b9aa557e6cd5e6fcb1b9bea0f8e65eab6a641df42bb5a711f36e9a43b12e24492ab95219ed84e2df976b3ff024263e4c87cb93cc4fe556812096686ad7f153fea8a12b93c663dd08c99b9be3634dab9c94df7f2b4d99304b4c61a4bf0fd9cb298d3d0824c5058a515dc69c822f868737686595ffe9daa07e45a889e650e0c58fc2cb71846b5296e76d721d5e87bbf715bfb82e0634221882274facea28700486709c43b2fd5feeedb5d70ccc8ad1367cf2834e88eb8ff9efd59f455c2da348444e8cd3449497b753c938f6c3174e5f3d4438cd4c805e8fa2eab14986fc917bec6a676a8d5b3bff02b8ea9a366f27d6be888fbd5df85d6cbb934f49ce963646595573b5a5d0079fbacdf760fd31797899ae0bccb3ecc32eb48ba3769bd5e56667dcd2723c773cbdd924a961113ff5f2b88ecef333312d77c2c761f48991755a83e09b7c3406bc8794d31754bbab6b49c46ec93f5ab9778b39b9cb66501b63d8859af1bddbbee3f947c9ff49a6ec5fc38bafc9b0a763802ca7d9fad39f040c6736a4c45b2eda099ffe26d93bc6ccb566a687ddb786f5e3e3795d5f5d575746c3cbfff55899c933f015fe1155b776c9f0200f72bcf67c40df6868bcc42b2b936166fbec56ce1a9eac7347b6be6dd065e990b257bf21ee537988a560ecf1aa75fe3bc8650e8d870a1a41910e4fd1c43229043bc1068a60ad74fc5d87581a932ddb592383dba16fe6895ba1e67947c71aad452861371a542325607a7752b8485c48fa9cea3d79323d996bc63d1b26f517c3444905f73077a41f576150d8b0637e8e4a3f42f67d41f2da6f272cdc5ba3a00a8c8faa0aa9fe7ed73de7dadb7991df9ae43e797a9cf6b0cf257ceb347dff45cbf6ebf5d69f8074b3a6ee9e8fd35895bc7b93682897c0e3f2d467559639f8f349d664499a14dcc026bec0780858dc3f826679a924ffdff56755a276d4a2c8606fe7d87228f32cdc3b4894f3faa3f8f9eca8eaca9fb54ee77769f157b46e4476c88568ef6cb5f4ad1cbf664ad591a7679f5e5de5b65cea4ad971d9e39019735e5fea2507e36a9bb66f67c177f3873bc5a8a8cd60279e3a632beb370aaa180e9a7cdcbc23af4f9e38a69637928788bed066da235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 8b2755c2e64d1fd9b79f6afc717f419b955ee69a6f453b862528bc799d5bcbb44ed989b5e71b9126a6a920e67a075bf960d6a3ac6de28fd9ce39137b03a669696e6f134bc48587de880de405ae7c70d9adbe4e59d67b88896fb0b615fd9e8496084ba93d197767eedf6477679cb9dfefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c39844ea491dc6698351f7cc4fa5acfb0a86418145743d2b850cd47f336dfe00d96b0a67cb3ababf62785b12ad4de35f813efa36bb93d01eb3f2490a7dc5c54f32274b01fa71d417e7009f7b81fc899e28adc5c4a0c41742c8dd43195cbf8393a84206ca1e97d32c553b68776f9153b4e3eda446df937fdca7539b8a2dc497a1f338803cd73e99ea3f834505b8fa39f54544a49921e348935ad28b7c54f12bf6ed1a9cc2db7c58ecae2596e68c2fda2cf4487a6b34b90e5e658e6af26b864b7b30b2adf2d5038f8953e056153dd13e69a32ae8c5f6649f6b638d5cf49c8efbb9563e4adab4f3e83c5cdd5e2617b4540e61b5264ee996abd69d5e0268f0c8eeb1bc15e88adc55a0dda0177473d816a1670f5bb55dfd7e98b7f148ad4207fa21df4e024a4d7a8a9dadf9fae35dbea3d5e9ac5e5fa268eb1f88c4ca06fe5915de4bbe512c14b581d7c012645f8aad722bdfa1c3ff639b3be1061d5954a4e7d8f3ca8af8dfc34eadede5599a3ffb05b7b7101885cece49bf4ecf9d2b9137e3bd0054ca8a8e8e859eebc21944dd19bb2c1a54251992f2b5eba93a452c39d27295d225e9b248a3f4972cb6982c338f65e92b4b87c2d9ecc985ac925ec638aa741a476f25b3853afb4b106830d98fa1e9af6b1b23d5cd045e112a7e7b7f3ba9c8d1c48358e40d4ba12b347d28a571f8a6c05b7c81fb3ef2f3f4b28e9df549abfb97ee25053d3e4676c9088d277688d9f85db7fba99fd6f307cd414654509a086d0247aeb60a9925afba77f76d66ace880d3d2e68bee1e638e4f74628ba73e0c565bf7766ea79fd6fc779f9c55b1b48c350edd95a5566fe1b6e1eea5d7e739e42b3843075f7c7928a7c09a74e8cd3925e87d71c45896444522a63bb6b786160d3d5cf37ca7e55e82888c18fe71aeb4409533f8ebfb9ecb1d396c2d44cf7f75ee37d9e917ceea4f5ea4c8a95b163877bfe59917d03355323d56b62e243cfdd7e4102a345bfd5f4f1d52f9673ef57abd43f8d27453e6643cf6809a9f088d5ead19da687fd4cfba52f5fd4715e5788a08754d23b7c5ebdd7e7fad20dab9ad776d53de954a99407eabc44184f37c1f7c477daee6689100ab4e9f0d3a4157b6925e431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb7831168d3171cef8b2c84d0dbb801473084bae30d5c9c99eac4e01cf356ad4557af6247a73b4b8ef1fd2cca08168d2399a1a45b685bafeb9c0aa33949d068348a3a8cb55653987c79ee9c86cd67c385cd68d893bded160c9e86a65bcf63a50777b353b948e80d61d13e54e5ea518bc687a4a6b6c83372c1de6932accfcb13525457979228d41af9ba2f1eff82d79fc245356aa98b12fe86fd2c538cc5e59cf9562b5a5344dcec44b3703b5d850358c6ab4a5fcf93dbcd3bea0ca3f05affc5a43b932f3fa2fe9ab9f2f3b1ace7a3c139dccf5d9a5aba7d51ae72ff5ec65cbe42b54ca6113baaacd44f3eb76aaff63a474a74615ad793cbbd7a1c82239fbd76bfcd9d7b579fa995b966ea2ccccc1de89e8618325234e2753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dbbe54f96a406285ee79c4aed6aec6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dff1fec47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc19adb669e760576c81a7e65601599099d3a332eedaa1339d8a8c6618e894b5f465f64fb011bb607177d6af34d88ea80d7247ccccf69ad67a15df94f43bffbc1b5f5abc7480257694ea9e8597a8aacdeb538be63d6dca6dfb77fdbb6e949e3c15015b567fb88b509b43d4665abb834263a47c5b6d07e38d7b267aa50e8af4455fb01b6fb3034ba54ba910c0e8c639f66e275e42648f0fcb3390edee7f9878c0ac4b3ff899d83e9f2184c429a0d88bdbd3ba65993ca46c18cfe583f5599ad549801e934b8a9dfbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = a88f3bf24c9fed4588365d33f6cfface43a30488f09a8965d587c91428b930ed34a27e4535cc458d5e46aa8b8c7b3cd47ac76fb3e3d6174cc370873e25fcf07dea86d853da7fde30701c6716a7e85c385dfe14e0d91799ee546b4d6347dece46947a9a579fc64445ac60b9f59a7596ee94f1eef78bad1e5dca5d67e10faa89c8e4e0be498ae7829517c8ab587afe05fe504d68ec2e686e54e6d93c51f0cfae6fbecb1314f28728769f08a4bb6489333ec4bf1d7a6de473afe6a1a3969b610a87fe2bbde35c31d163db05aaae1afb69c07b6c6d4753b16588413aa5897f6f80cabafed332405efabd2579096a44c30991eba87bb4d667bbab5e849adbb178441aec4d00477310ec4e33677925985e1aa7b9966ae03dfe4fdc0d4a614d6995eda2fa5a5df0465cbc1ea54298cfb109488564aea65b5eaffe717177e9916a4615d3ad708c8a825874b7cb671a5b61f5c3c9ba3f5ff974d46cebc4991343b0fbe99c9d99f04c97e28aaaf0bacdeb5ad07f956530d7e2ecd49017d73c8e498fab75d6091d6174d7e41a7373e27b3d12cfb06455b4f2ce471f9adbc73c4299c47eadb75fa86fe0ce8e3798d84aea44a1303c95ed0fcf470fa496a86ba364babeb7603195c7cad66d75b46d773d94fb1bf761bd48b01f62954b5bf5833cbeccfada183bc217f90f094b6eacfba72f914604aeba45f37d17606d1b76340e72f75ad6822bd7d834897917db31ea32166568c36ec91efd97e41cc1ae4bcbd4ee525f179f8adbf32cdd56a6ee8eca475f41edcefea85d664bb8791833a04d7832cf7da3ea42da34be7be4beed4c8a5cb8d5cc2d9d51b8f6d33cf126ffd4f5c8794447fc3c1952d5f8b1874cec6899b85748448116b3aa95e56df381371763aab6c8b90eb19ccaa1f87c4097c3c351d6fef1c6977649e5eec6938977e08166fe778ded806bfa6279fb6f4ae7fc163339f49ede2d5e65ac81fef4feb689726aa6d712eeb2ab8ce5e385717946c27c96e16b6358743f4bf20af2a6ce94492571ab5a7afa24f7aee8f45164a23f35e8a404d26bb9af0c14a16ab67675767d5a16594836ef4effbf1ad7cbd259cd31944cb798d920dcb227e6fb17cba049388b350e73221559f0c7dbaa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab3224f888d7cd70357b6e96ddc4328f240863b002bad191bc0e189c0a0f481b0ef68dd9abf93938d572cac462c710b67507b9e3936739e844d7412db51ee77857079f006a3399f1fbeed3cfbef5a43bf356a28eef22f267b2d6ca3143e5905b7550c8ce50827c8eef97803159d871f7029388fb3b733a7feb83b638dc08778ae53bdb485eede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e9895305ede774b520413a84704614aeea36339c8807cae45144181afbb7445626f2bfbedacdd9fdb562055db69fbb972f6beccc9cd1269eb22957f94f47ad81ffaced4f33cf86e2573eb8e975eef2348787fd7b56acfcfc5b1e43c3e6469efa51f9077d4d28c7b5c54734945a7bc986a4f471986802e99791e5aebad692a9ef506b4d426f43a899892de243da4e9940ebf9cce5fefde03c80c79ba1c2aeb173e70ac0fedc42e30c19ba2c903de95b78d560344971ca8fc9cb89abd82fb2eaef62edb32dcb13a369364d44f3afadc4e7c49f22cc0a4cd7b0c134e9ca3bdff88f836afd50f8c99f0e467ed39cc32a9cff97cbebd9daff95da1b2bfd838fdfd526d33ec9cb4338ae169fde3587bc4db0a7a4cc5fc3496c0372ce69a6fdd05c68d818859219efaf194eeeb8570783aa6cd0d88d67ba2f7acb1947db1aaffd66528bf3893de9d7fc3021b6e4974d805979bbf76f404236bfb74717669f68e5ef9954ef0aefcf132c5a205b7b3a6b8bc6c944fbb035316cf4667feae5355eb52b9b851fe5e0d7ea08649e741cba131dd7b96faa70a7ea2d974bd6219a2349d98356ba3b573a33b2837d4de86a26559b1df325ab88baaedcccba484a15bff73c54204d3e11e846249a9cbbbeb8e7d1b448f353ff7a35d170da6c8e87c06f653930bc1c3796fc0f8d01a3cce3a3774548f46806e4af24c832757390ddd566f0c443c7c5539d7f927fae3950d5ce4b8bc2249d563abec7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 6bc9df94c8b62859c31e146647948786cff5ce96d769fc51df7c431098425409f8b2dfd0834876b23a635869c90df39bbe46d94bf6b4835750a6f3788bbb7a324da7f86bec5cc8bdb386a0f25f97ca9c6463cfedf8dee845788c1313e3c74fba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fd9e3ef54daddb37107f3d32476aadb55cc0cd93e317a8ce2439f2474f78884915c54b97e98fdc458e7488994c11d9adbde3c520f847bec7730a57227158c4bdeb51afb66d6ddebb7dfcbd1b7d83fa6b04aaeff7378f4ae4da1adcfff2cfc9c3d145545bb6495ede59d4dc12bc84e8e2fbb8e1a76c247d20949698175b2151dcd4c7bb567d5fb08fa6253b5de4f1573acbe8f74abb9837cce85545f8a9fc9cfab66f90d52594e948b18b7ef4afb0a6ec4c7e8902acaccfc865b45b5f09fd5a4dc7d5f952fffc79e96e3b56139173b32ec9063d4e51b38e9bf9c7b5d86f6b01cc420c86d117d428d4a774187d35269a46ada8ec1fdf230fc6b066c57dbb875a9ff94e76e66f3d7b95edc3ab67be5d7b55dac26e82c13b371e8fc42b85313c65da7eba09219e4acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c285fe589a03de00dd6893f7dd5727d0baad7bab6d83b2d5dec4eb95e2236402f7b50c87a9305a8b5fbf5664d74d4337af268b48bd18555754d5eb6f37bc057e191cc6743742dd5a66374be10d48dbf8cd3039296f56ca700bed7d1b8f6965d55d87ce990286fe760eddef33664f099f854d634c2f99a474bb8a03f9a4fde1bca75db90b90c53ce69acebdced3e565f4e1fd1c6ad3dd8eba8c50b66a57d01da98e2335328bd11a4c3e11f58415b6c38f28f1a69671fc2481920c896b389cc5783c5fd3b7d974ce033751438e5e87ee3ed5ed52b2fdd9a26af098ddff3eb337c3c85551cae4e2dff0379e6cb993612d8d9bed8d7da5ef5cd8094c378fdd376982650a986396504893bb0e8f389886942fdeaab5bacf3957aa8d29edc56c404aad714d89bc3af9680ef6d2e154b5e1c35f1c0440efbdccac3fe039456240dfd1939aa71f99ba8d4d9bff93f76f84879e69dd9a448e1f15f188285de966826038fe8ecc630c15ab174f71adedc955fe3944fa9f4eb3a8490eede8fda439cad7a469720d55d6ecf6cfa35ee36b469c12e48f1386d1f39a5adacc54b0a4e27d3cf7fe38aa461c76003b9ecdcccaaa3be6d1e9a1652ffa0b2aefb85ebfefab4a174da793df381a74aae87d84a4e3cc33275eaa595733fc4a99d43be898d3244b449ad7eda54bfcf40d43c929811c9a558a165da34eafaa8c45b08cf7876c8ff77b721c3ed22c958323c4effc6d6c6575e9875b8bc6e897855cd8ed1d611b954c6935680715f8824b509f83a3e6d5d5b6f3f03afa863bca408403c0ae86a375ce613917bc06b94dda73a8e0c98cf54a60ceb7f7cf1334b324343b2c47df4a843e467989f4e60e26e1c15589297e7d7a4f90cc49e1ec8df0106ee52d04871ca46d275383689eba98aaabf697adc925a827cb7f3bede069f5748778b5946c78ef9688e16a5326577ad5a5773db939d273eb04545c530c9b9924ef4e2e3159efe3163bca141c794aff4958b9aa67089488a732189ca9244de144ae728a77d7a6e8aa5bfc4d05b6cd1a8ef90114542396f31dfd4c2d8dcb28f5d026c66763a570d173612f24fef1ebc6cc9a82f70ce1b81d4b7ed6b30c95c5a63a5e1f5f450c2cf6cb1e613b2b3cefeed968e85c0a9539c38f42f1b9a084dde09036c6aa9349f30e648ffe4d67094afa7e5422885c7d6962780f943cfd955e9d496dcbdc0f2b3137b89c639d3af75bf784cee748bb6df474d3b6a7d1e1d9a1e8a63f01cb969fe9ce00d7b539159e7547fdff7a85ba76daa857eade39efc88f403f16bc2cfec4d2ae38a026dcf54f46fcea7666276318a4d624b3fb4af5b15f8b4da6ad5557bc819db8884825b8c287dd6636a16a296dafcd752ea6ecc5eeed628f6d883a61f85fd3006a83381adf9f5f80fc1b831577e36d178a906363bc9de412ed69b57ed27a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a54029e6b35e996e1336cf23f49d0cc33ec06e1fa9eec27aab55d5f944298c3a23e58c395d1813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = 963f71222d555dc8efdb599de24ed9277a48d21bdb16db7c6fa73622acc63bced36cacd7a48c73dcd4e11f1dc91add9b3a48b96ced5e56e8d9efb66ea3bc97fc46db85533c4bdea9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6592f74b7559be146fddcc9ee5c857b0e836349e4d23d56eb1b24cc873c56e74d414a0f6cdefae6affb5fd715766617b9a5058776b74b72075e261df131baa50dad93bfd9d9b72dfe8e5ba2c748bdc5ebca2bf7e5b39ddabe643ed64fa8f5cd55a0d7e22854af857dd16dad79bc8dedb47bfb18edd13dba7d24685fb46966ce53b3842cc66c8baca0934efae6e9459888945759b394fe26b9e4c835bec55edfabd4c9845d717f0ce53b2ccac4f7fb65de95ff1e47fad6e71ba8b213eb5724039d88a6f0c70a55000f45caa543bbba3f732ccae5bd84630dae7ac6c843a6f24474568c058fd4785348fd77da03acf754d05bcecc02f93f223d386bafb62275722f1e589d6f5044335779d8bae917a63275f536337db7c7827234eb482df10cc7954b76f2c0ee653f47884519d0d3dc9bcbede0fa4f9616df4c9a4bc80a3cd78f5b6e3c6847af6bd792cf7fc99950e77676aea63413a3b25915ecf6a83f0f9c595256fab315af64b978bd4e54bf1d702d6bf66ad5f4ca2b5570199ca7ec91065cd248bd8e01a8ae7f194db11b88d594f37c5d7e44c4e1d5d5e12eeffc7acc8d6f45e3cc8caa6344f284e6bbb17bff63b9acc9cab051ae9fecb758ec455414a9faec45bd453639565adc2cde64c26d4d035380b1cf350f63d770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe65fd54094a450a8c9f7a686b7565a3036ba7136f88bde57befe72c5e772ce15f68adf495e1de59bafdb68a86fc905364d3dd280ade71845347376d53d8c718a444a1f7de33fb954adb3a47b7f42b92dda8f9784181a4e7e479ced24e90a38ffeba8d08c09ae2c1f4a8743a42319e0de7efcc75bc0068a4d866ca871a48b071cced3336d5d0eca3c8e9fdb3cf2acc7eb30cfcf61c95b6dce64cbbd78472658e6de9eeceb823a373b4097b4e84bdd86e9a50488c1a364e8c4a7f50bd9daadab70ad35a16facac83093570399e906e5933f48e7fe8c04f5e773683fd689fc59f5dda228a7cf4896af6c6c4d2f3acf279c861c83101bf868cfb42bc85d52b26b6920591c78aab2de99c2bcd971dd9dc19c6d72f388ffe054166d95a785b8eeb24ea9fbd482ee6b57c896d8805a33766d05978a98f48e7ae53b09ab4bad11ee21848f26afd62b98956985e4f9ad872a49392166c72c48da86d8eed200dc9641a6a03083a3755a482ab70cd2e3cf7febf76a9e64998a96b8f58e819652edbd1f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341b6f632fd410becdfda9ba4711af1c8934d623fac21bb4a939fb16f787dfc58ace7d69efaa67c3a64d5b98a9a08bf76bedb636c18a669aec36acb7170ac82253a85d25f4ed79bbef5fd46649b9f6b3eb924196c707fb1301d8b6d95af9b373e34489155da84b8b8e0d00d5caffb8b295d473969dfd7bfa5247a5139b39237afa496a93717854b162584bc67d4506ed6579d6ddae771bd0f9a0473a481fbfbb95397fc9d3a37bfd42a53f7c8c54bea769c419cc5efb83e8479f513936f8f8775a2cee4c13a4318e5f2194b8f1f8bd5a94d8348b3ca878bda59f34ddb1e69a9defd716ab9f558ace0c7f751ceb4ba0eece405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbe4d7d36457c39eb4027a6ebee8d03658619fc4cd617898e8dafe77b5d5cbd7df20aace5003d2bc16c398e3d4746e9327ef61e37e3375a68d83cc719a48e2852e6d1dede1456de0a3df4379c8d24d3dad7094eeba93cb667fe26004e225c8cc030af994e84bddbd6b422d371b7edadf8f8beee4b3495b4e98ef5ed28bbd512f3ef0c6b5a6c53471effabd74c26bfd8cd44ca1958e5bed9c58a1775cd053eb41553454cc892088bbab5eb26d37c25b2dd0a7f8c54abcb1f6cdc3c61c7f6d36bc464fda896f80fe2ccc24d7d4a386f94bce5d71fea300a8ab1dac505f4bf281439b3f93c4d4f62f5883bc00d9589f5a89e44e3f435f48a8f7c01106e7d65b857d2353c1df8bc574c1f36ffc2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = 3d6e4fd36eddbcdcade2f57004cc995ebf9139b7e3ed1d660708e6dc3e8f04dfcaf5af94caaccf359e4106d463ff1e8bd0b65022fd86f1f9a8f34a42e197525859767d89b0eb29cf54a93e77fe3bf43344bab7578dee67796976e5c7a2626b76cb3ff2cb358904386a5485c67fd58f7027543185c71bb8fcdeb93b619455cef931560452d775db266e7c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5961ad8a6d8992a23aa5840c97ad07f8e698c990684d0c19ac71bb816af3de7145ec340db2eedff601b6bb7545a87869b9712997aa5c3ce618dafa8333e6159c1df6e333f4742e5c49e887a8a4ccae2df6c7e218a50a1f4d151a711da99a11d7b5841752c498521c3c469a1e3dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b69f328edf42ac68ba7ede369257c574f7928aa5b0544f00ff8a4a7263f9f955599ad980ee6733754fdf706360fbaf0dd69411a5d36841e86defed4c5e6cd79a84afd79e7c22ff070ac6cfc2fdc803ff76afb4d5105fe0fffbd443fe64f938f66269703daedb984bcbe337c720e42d024ac0d85d257abeb804bcaa5fb551274ca5483d1fe6597cebd754ba6af7d74bca789c6a756dab599cb158f5fffe28683267001f3fec6f7802826c3d519ef8d6fdca52c51e2efb64a3ffbffe45d9d373f8224b9e3e973a95fa0d6acafd22561aa1376e994fab39fa61d2e308f2d9d3ea353d77a8d835a46ea3e5ee19bbaffcd9ed57ff69de56b36f6791f87e922b49a51b3870bdda0a2f3aa022fab02648ece97c96fdf4b9e99b6ac2c964cf356e4a39c22edf74eec6fcc8893e7cb425c68c8e99a89d22647a66ffffcbc46184ac181d5566175d3aefbad90966d2806b6bf26903b18b1bf5a89168ae0d47cb4a70ed2fb0947381d559f39b3046bc7a55331e8da418bb34089793c2a86d6123de1e8a3e8267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd8508e6cace5b36077e9a7eb4ecf7546c4486ab074e511b729ecc835c175b8314d3865daec0c6c22eb76f866444869f93d21b4744fdf02a3b6db8df342585a5c098ca679fff870deb6aacd80c4e41453fdc44054801c3619953f870f8b39b08831c96f3973beae354fd0ff4d9b47a5c22e677390d8a71ecbb8016ce110794b1e3e3460650ceebaccaa637fa6f5429538dd2fddae8a3d211063f3265ce4b7c6ece835fabb9f36dcff8ee0d3cb22cc8b3c5811bd9c276944d929c5c68bf6b8648be93a89397cf949e26866ee4e21c3849bc7ce5adf8942fd4ce901fb5dd83cea24ffed5cdbd2bf9b5910bd2a7dc49388cd4e8ce416abbaadc3ce8317fca13d3ef8e964c2a9b56912571fccd7878584f7926a9cf13c0f5dee4c5abeb44a94015cf963c596471f7771cd383c235aec594b61efbe7266a5ebbc4828815e69d2afe468448e74aee3d9e9ce3f738d3fef42c0895b5acf7e12cbeb10c591a64e08a7b730d2b902185b9a8da9d2bfde807466c456c4eefab336c13c6e137b6ccf9f2b21e3e1cc862c8883eb69acb0667a68fc58fc5d6584a09f7b35e59f58ddc110c43bcdac03714714ad4c07afc4d553ddcf0184e5e8a6e5efeae6d13c9fa5dece38c6144d3b87dea304625cb8aaa6ea0695fbbb775c7ddb7f79a6fdc4c53c9bbd72e0f7da097a0d69ac77a9cab23a4eaa26dbf36d95b10167365adc866e44be2a3d19abdd972936275cb9f344d812e7d968a95428c4dd0b21c68a237961b99a2c706fd998867600eb16059e0b0d8942c2ec49e6765336d3ddebc39876c847a6d3f946da9538679c4a83dc1c33947b5c01a5c659e4de87dc3d8bd999d68f3dc79f4db631bcb8725b72b4e4e3ced300e4c7a30f56abeb95890fdf92d0cf4c4c994cb2d726cebcce5a4fa3b376bda76a965179f56e66a2bf94ca45d90af14e608ce854557fdb1f7eaf96570538796418737b048859e6764817f7e71e353461d99850fad13d54284b76d6fbd4715934fa7fd5caedfa6cd6683da8ecb5f6a884d04ccb008657fa9d545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdc3d45594f3f4a47962ef30c919ef0519c15efed275da4757e4dee07dce729a59877f4e881ee01d2d8e4e3bcd445ed98d9bd7709afc81eb6044c8fca3868a485fcf43ff596c7ba6797f3931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = a268578649ed97d3b6fec35d89553e3edef8915ea3960ea814cc5efe04bda7d7ae763eae717d627707e155ac32fa25abd26ac6ea6975d5b9e618476d62f3e1a9fa3db53582462467b19a7a800f5a3c2da3b6ee83f0ff49c855bdb47e9d5934c3be5b64576b71cf5f5bb2874642ad9c036bcab46684e638db5806b74d4e92d0a55a54a6329ee7715c88ac402ee2bf49b7cd74f554be52a45366fd9f5a4f34c2f97646c525e1c0c989926e914654c053ad6c642ed22023954c28bbcd2fb4641bc327aa37f494383639aa3f8a41541f7f28ba56838ae98c6d4ddbcd5f82cb4c11834aa19637804c66441f5c9465ac045e6334679f36175b36cdc4db9d797e8adcc46e73eb07b8c64eab511e51d943e666267adfb6d3163d5be5345c4606f9757df5e7959dbe0af0c0593ac94ace87fb515a03b00bc84b675d7ed2c6ae4da3efd38e86c396582a56a63cc35af5fad2ea8dae2eefebaecdf699d69e857334b1e96a5086bdde7e52bb0bfd49b4e1085a94321a43e159ef100d67b06688a5ab8d0bae7a9458d04f25c1c64ffb8d7b6563977fad0c70e7bb961ce84cc685aed35bf5f0e3dec53a7a5ed943f6ea3dfd9e7b01985c609c995f765baa17eb3749c8934680565dba19d958c535627f6d6b2f1cf70673ffa466504c267dc88d5e61ad680edce58d6b4f75ebaa040f92ee1fccebbd6d5c878cddca91915dcc386386f5c8b367abf54959a06ebba5520646e75f50ce8b7cca13f27d1b43f49c9e92a7f69eeb6440a7e2fb868cc47b406da4f5868b6a304aa46e57facc0e97a17eab9d26f28629e6d03eafc12466a51ffa3a635ec89433635bb0b0efc5f73670ba63f7158d3b1ed473608c5e01cead9fd9dc9138ed5e18e692d85dc0fdacaf5579e3beb6c6ceb61c3579cd13a7c91eecf6ce9709366bc9676cbb9bf271c784683fd0e7bdf54bfcc9b6387d42993e275ab2db2dd302ceef7e4881cc5774d2f849e3d3ce63639cd03d3a7f89e4297d79c6066525a4870b974d3db7fa939db96c6846eabbcbac2b730849a9b024e00adb9c67ddb5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebcbe36908ad2eb5a351c94607fda4eb44458c9cb8b50eae90f3d7fcd63885463523096d36c5655e9ef621d55e6a49d84fa5b4f9744a921f497eee3a46eead5a5fe481ac5b4b819a66753b5b75a95641bdcfa07aa8b2d33a805edc526cd1be8cee5677a79fe8afa6d8da3a565bceea79c58691a45ade1aac937fe5eb238bb4879af7da68ce3bed6031a322c198527b94985ae6d9b4a55bcb59e9eb4b2078e82ccabe7a8dbfb8a776206b59259afc9a29f43ca9f5fb6de356057e2bbfd9e2cdcbc6feeefdd63dd83b9d1f07ce6623db912a53c085e78195662da3efe4219c6337e485ffcc9aab6f22c9aa2c4e64f5d686bd4874aadb456ed086ebefe51eea4be6bf57e2cca56eebd4c0e68aa4dfbe581edd5d9da4fc1943c85f75209ddba3c5e7f89b8fa2fd8bb96bcd7836391b2dc3b6b0533f0e9ee170986cd245fa2b9dd6a345679377b777d86a1173deb8f969fe3bfaa643af8f98b97a8432a0aeb8c748ee70556319efbd2e8dbe88fa726743627f7d7f7cad69a3ec9929b37aabdb04ccf3405e5b8918dddbd4e9bbc635c12c390e0a8618fbdef2abc84eccca4b9f576674f37355a40b7e931195b606c6759848c33a10fb74b57d6266aa93fecf054d95e7ed3df1ef53f483daf8b3ea757a55a9fc69765f67ce7bcd413dbbb12a8d028baa2ab2a378a55a283a6c5b73837f856f25acfaeaeb36c7be5447fbffa85a561e2477742d6edafebc969ea66ffa9f455db36b70f9d863a8b8a6d57251b8adc659f2957d7cc643a91f3aebd594b2d1c3c1168b475fde1e8af80e316890d467b7783fe48c7bb0216381ac8bbbf6a7d61c9dc9266a33ec7744099b2e4d464f2beee1d38883de5c8947e585b2f47c4c8d1105668188d8e52dba0316e848fd6338dfd3993ceab83f68a13e75c6565868de4e9816ae9983aa8d5d4e23109a34fdcad5fbc3c37c87d1d4a6b1366906aa7d99df940b2564f00e37760786ef28c7897cd9d05cdcd259fd596e538ee3876b548667dbf6dfc6d73eaa5631c9fc4bd05320d9f3b5365f384d4afaa047a234e416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = 1a7c33d74f5e078e41b07cfea58ad1095ea3b30ad021f6c0aa896e82fe3f02d341faaba798a73a97ddb66c0dbad61e9a8d44797b2fe8b29ff4657573c9c556f5ccd96f057f72fb749ff4efbadf90e778d1b48effaadc58a1d3a8aaabbb9a6f77d7adf708bfeee099b5906854d2d45de79cef144f93d3dcced2296c5dd6b1469ac91c35d8008951c70cf4eccb9a98ff3502cfea636ed7a9c56ec39b724189ca111a935c3b58f36fa29ff577f8459c74e9e47dcb8eeb8689ee35aa131369cc8d5362289ae5973eff24f0a8abacb75da1694ed4d2e8faccbf8e552d5404d68292f99c9d3ffbbb8d45769b73b99dc3361fc04bfdcd86273234f3ee94349a322aa13254484c3b99a2bcd1f6dad0a77ba7b797e1c83f49ebcd54d35aeb071881504d7fd9e6fa5d58f12fb3afe65e8e3a77ebcf2cadcf4c8acba7f603f960f194a4214cc8c9a4efb31a6093a34c102ac18c26ba172ad48d39860eec35e9ade49b9bbf510a4ff237dc72b5d7cd5ad500ba59394e974d4e9a7ee37859a76f02463cb93d3489f6eff21492b0dd3124368ae02c79474fb7fe758f772e9128ac75f19c41ac0eadfa1a51b027c16e6be5279587e4f4a929f34ad52bd6a17dd5862eaf6e5af4d559f0a7f6dc4174baec0b5fc4b498b247e1c92bbba383556eb6e69f558f5bdf94441efc5c8f524cec7ec43a448fe57d88c4ba220b56eccfbf91af471bc735e89cfe73a8771d669a1d76566ef8db795edd7dddf40719ef4b6ac97dffafbe67a02e445eb51389b8233080e4fe75ffd650b5e4f995395f9bf3eded4e2a5930294b37c79aac888fae62ecdd7fc6dfff5c8d55ef9fdda8756235da70038355b7dd6ccdc37217f6f0586acdd7f7d99398813fcffcd5a9b909857be58c3b6a7c1014e976a472d2bb7d3a0932a7cdcec9b68126b98b40e4d41f5439f395cf6eb5f13d39c69ad9eb85696b019d84e76faae8053df014720b5759c508ec92ff96bd5ed3c7dbbbb6248f87e8543e8a660bd6bbb908ebd68fed7f36cfc776acbc8635e2aede429e730aa68e5e177d2e2f34a645768d26cc079f54dbfdc94a09414a36a3d19ca05a5475388f54debd890cbbde686438462aed499aba23eb3dc2c6eaa6a46c4a0afb262c6f09979f010aeb9806fc8098be6416c6ca5b3f8ee79e29cd7cbe2855bb64c88f67947a495e88fd336118dcfa4cfaeb27916727f9248b488278c72e85ba2dbcedd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb98fdf74975323a8bf0d27937f0c785163fd9061bd5098f43646d39808c555def9fd18a449aaae88afba92275df182dffb1af8381fcd46164358e344fa35dc05df6be895a5a0566b409f893e9d99cea7b3d71eac7a5edd81da5eeb755cd3a2e5c61cea21eed521779fbef3b8b4104608d198ab11c4c30a4e78a9e9830cba4e753edc127ac770957258ce9ec8d595ab9bb9d5adac266b7a37b94bd5e7139d9d4595c327f6ce430ac7d7e33bee0ba9c7bd7b267ef90c364582164ff0e0a920fdb72707544a7eedc8a4c5a46148c2458b6c5bbd6d43cfd7ebd3ceb1cd0ca37303c67bae0038e0a373d539b918747e16fedf9a4d78a71d74f770ca53c9b4ecd19bfb28ff99c55a0cac83fcdc8c7450dc5be76907679b48e0ac041987f96754588b83722b4915909fc41c8fe6625a6108a957c34b2d0f3dd547fe8acdc56a093ba9a4dc07546fc1028c6bb4fa775864bbbbabca70a5b7da5cf069fea9b8ead022784202362e587bce2a5b09063dbe4d5eef77a887af3736383f6f436c8923d4b72867dcfde61c3fd342f23aa15d69fa88765218ea9c43bd669a689c5fa77649bab20eac8a16a51759ccd0f86c06d7eda8826f291e6cc1eaeea880af7e7ea4a24bff45838d7f20a8f1f3fd2a92495b6393037af5d4cd97fc72a741f0d6b7f9e9358f6ba3c5ab1378f3ceb955382bb6fe306ec6228467f3c6f5de795320ef0e5ff68b705e0662c85a49b36a82e3ae958a14e9bc45e1ed5ad13c591aaa7f1663301aaac464f7da3c6a8873ba78e7c7473e4ebd79534e08e45d1749f94cc9c82377cb398e29d0692f83994293dc5814a8fcb5ede4cc754f83e5fdedfdfc1d588ac4c3cfe9c40277b3f6173809ecd63f78e3852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = 0fb39b1e5bdc2297eafffa785df48224d887a73cb9b9a68aa2a768b3bbd87bd9cbf6253378885113bc6168d631121a5fae3dcc832e33162bdc3acda2b30c5c33383555c4e5c60bd689de6b3b99d8950f6bb507d080f93e143f7707a54725a3a85976ee49184025f66f2eabc07d5d72a31f75440c9d520c9d067dcd4bf8752dfb37ca066ae55da3e5e6694b9581f6195b4b68dfbf55b9f933c6f9867af36786fc9cf4cb7eb47127aa08798f9acee3c1c661483a6ad1a6d28b7752d9d473272f934a6bd5c8c5d957899997a6d39928b453e480f008a4bba7a49aa65462e7e67255db56c441d254dfd5ee51cadd518e1d534f24c1a355a5fe3aa1c4365493c7ad67ff54300c373bcf64b3339f3b0dff2736b8024af70b2dbabe69cc15d494803bb515ec5471a6e9bacac9ac2a58a4e67fe303ad9565b33c84723367e0e0544c4a96bebdd98454058413db3bfc2958803a5963d7f5a4dad74ec9383deaee892ac9e33eda61de9d5e4b3471f9519adb6bcb79c1684fc07e933767ea4b20134ba93f9c0d0f6da0e8a5e12770c8ba4ea746ebaf9eaf0f953b4713fda674df202a8469ad96bbf9fcb9cdfcd524b38a7a4c69d5b9818c8b88da78a80ff46756f17a75a1f7ef805533a17996b7fa7f939a23c75dadf3b715a714ac34709ed2c2f8a04733495a4b456f1793733df477f6db60caf10375f74a393d999390628c7f64dfaa2b05cef68776dc9e50c39b6eca9ab32da9c6764fd8d75afe7a1eaf645ad28d2c5a68494ea3da6b08a5b67e2ed90c587f5818d0e04c942445bfec357e33388a0bd3f88096f4e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b45dcb557bab3f87a06cffedb8868129354039e5e5eb5ef41c7ddea48aa2aab4f9f247d3f637efbb5e121af58cab867be33ee67675ff29c83bfa8fe7b15b766a84cd9369ac29cf9af664f5c7a7553ec9a0d3f85cbff6ce0b9c84e5d4ead3461803d3f6d0ca807a7c0da1388f84d7bc03c3111c8c87fee58e68b53ce8c668e8343b33d3bcab6a4d98857c717dbb103c47d6dcf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c390df9203357eb2a37967a60a96aedd23be5f3e7f3f91f890f0ae15f1b9b2a238914f39976cec0f59f44e4db7729ee532affba8eca4cbe7b76029c9a708fec73ef714a8d7ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b48dd7fcf8486c6c5d0ffb3abed3cd8cedb87d2bfc80bbfd3f4d949fa4f36f7f7b92e83aa0fdb4020db200b6519be545e893b60d09b882cf681d335fa06deb0a1d572655d60bb8a141f9e0e6aa582f75febaa79bf2f77b373459ce87c4752e3ef0257295abc193cd5bf31ca3eb16e648455fc08f710f8777637cf29ef49c6986cbaa8e6d11d636186b62d3bd6212a3fe9f7f795463d182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968253f89e1cc846023dc034b45660b3668863d719aa9c9feedf82d84ae53c3b4d85a796dc42b2482caad50b1065dda34eb43ec996e368c6c7bcbab69a43314de56bcbd4f167a9e7ec5d346f34ba4a5e47a956459b4c0477b488d76963dcb6c9b4a2cb6aa284f3f76a58f89753196d8cd9a1d7ec04741be86e696c642cf6443bc7fc5dbd336967c33677faeef98af9c2d3ee604da664ed34f99db1edd862a0737787f78168afaeae7d8544fd6b46f4b906c57e4abc42b06e464e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f512ed4b934dcbc2c87b063ef6f0d8b390ef97bf9d1af59a45fae9de6bfc4ce78ba4fbeabf4284ce0faf2f19cfa2604f9bba481e55ae7468dfa8bfd6cab649bb5c7aed244f413157a811a35b26fb6f444cf2debf2a24bce8e39f5d843e3d0b760017b65b8867419c7a1f57cc786bf6bbed63ec79b83fec6d675ef497b87be24baef899ca59d6391c2ffad9ab9d8060bed97dcbfe5b9934cae69386759533be1181e5e77884623c84cfef5f2bc0735e1f34eaf4b45263d418f75fe6f15cc3cd88a52e980794f4d486cccd48f72a18e9887d85811e6bf8dc3689b4ee2b1b86d78dfbd91a53d124ae1b6eb4ce3a8471c45e26d0e7053c8a8f56d54bc9c92752631ab8a9101bd4f7aee4c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 319442d0786cba94aa139895eba98b004f9a6c4f644b68c5ce534b107d5225f4a7b28cbaf879b30fb633fecfaa70c5463afe80e76b927ca4622f086601b6fafff5335ffbbbcc6fd75ab7681a55625f0ecb31248e187d8b7e7f8905b649774d9d49583272fb6209ed6ed7539fc4f87b1f0b821df4e55b79531546824bb4a13e09cadf66b7889c6baa9679e06e87690c9fea246226a7a405b997c42fb4ab14ed80cdb24ab544018e3a29c87204faf9414a7c80ac65d374998494b914467f4434e2525dfadfa34617cdf1caf86b2adc690267a41d4db764dee506b658132c59c0e887889afd5a8658bbf4d3758c84cf86611026a5c09dfae4f5d3187ec42d047ef53df1a7c59c2c0a6e401db9ad07e7bcaf9d825bf71d78737a1feec44b4b39c3493bd980bfcbba73e5772e259ccdbcef062a887dff5887d3d817da33ac19c2537f39e7f6b435fdaffd278131bea480348aef2998924c684e3ca8f49694e0ee49152b332138d61c659cf2c5861dbdd3d1e8bf33ecd6b197abfe2862362a9a15fb35f70d9482dfa79fbe882668eabcba4bbba6846238c5edf5b30d68304387e4addb5f685ea7f6d79558148c0ebd7a7b2a784dc78c8176a2a36b4dbb7855602742ec36f4d6c6c589d5e5b62f4ec09fcd70b954c529de431fa0542857a16cbffe16df5624de4f4bfe03b86ab0c8cdee1a3e2e95cb43c852c40b6cce76dfe61bc7631a849faf8e6ca3f03bd55c4c59f8d6ca777033f64d3bff96f99f3bc9b23e5eceadd7e3572542ec0db77ce79b2f0ac533198a61fd3939fae503ed9807b5a7c19ba983a6e67c1e6c88e889b13fe95c0e6c591f5de617d8890793bc68f717253b6608b0934bdb0d26dc42bc3efc7dfe899555275e89dc376b16cd4cf5348753344f0e8349b4faf9a6b8511008ed258df9ffe93ec599e194963bd9aca2ef5a3e913cf55e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d443ead5b3dda5a57636e75f4a1df85c9f7289e7ba521fe6e83e89b6d76db21c600e9cf64884490425f9700539c52e95624bbdf2ce9eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a64596f416fbc92efd42bacaf5ff1381f4cd9b7aefc8951d62557fd18ed38a858dafac4a313eaf39ba54d90a7aa296d3d4dbef4030db60bd376ecb7779f3ff414d144e624a9b0d2bc181268229bcef939f9d62ce525083dd58b75e664afa175b4b98b9d6c397ef1f9a46f0e842c7b482398ff124e7c2882b7831576a04beca105333e5cdd4bf286e45d3a9188757faac58e8d995e82de129fc560dadf1ba159d7496e9204b7963f957e85ed5930f8f98df97e2b8d42bb8b343fecf1af6a844ae598b2ade851cbe655f84287fe09eac773cf58fbcd5845545485eb47be86bb5163ff73bb7782223b856dff1de3c3ce339dc3fb4c9dee73e24cd6994fcb437a93ab895f30ce552209ff4521a6ce6c5ac8f78f353ec78f22cb134cec48aca73a56eaa128b96591bfb508832faad4a1099b7786ed1fc349b6a686b9cc3c7954567f1d6d5ce1543a6e967858ae9678b5e6a3b996fea65336794d36c3046adac514962c79a6b0344fb2e08f7b4e4a2aa4b8e2d66ac920557925d58c65eb82cdde34dc489d55742b5ace43b88ac8903cf6ca8aec2c784c1ece5e3b46ea8d7bcd43ba3161564b76ed459f7956959e28d6373c1ea8b41c9f397eef4b3b978326bed22cf90b77ae505bdeadb164b3a6cb9bf64f2a6b571f209a4f18c31c3a647d8e3cfd345d67c75308026c40c5ba20ddad317cc695444e758274330f35df38abb5f1b59806a831979bc985576ae6a8df36d8d6305ae2f84d6f347cff24e5de856b859d830637ec716495ec273a2c96355e195326883c4f024943f54c3601dd3e70c9dd5d4e2f7cf60f18a6adf1435150abdf38d84cebe368598eaab0c710fec52734e7731a65eb946d685ee70f6c7a1341d68657eb0e92bf002b789a5a465138d43ce6b7c29bb5dbb3df00dfc69d34f823e477e35ee46c838d22d78c37b8c8feb6df94586cda207f9dacedd0cb58e1b19eb68dcca95e6ad234e6e1c9a7b0a85d47d7f309a284426fa98b3d9d5f159ea45de338e0cad6cffac3c845006cf68eda736b1c997a644383245d1b6ac5628455694573afd88fccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 8bb4f8267bedc03d553b1daa6d6ee8f85ab9dafcec521639b686bfc5be98c61e939a039982cc774bad74d49ebc5137419b2f892015e1503e32f22497ebc5316e29d0143f5b2c1cef23ac61ebf687574dc7f56c78df4937c883bc9da38d207d9a6df68026d8af0bb5ef1f2c5ff18d6cac1a396b7f72a40656619d6659af5c570c7068de972427e42b0b6bc244b8e53beb7a4b91593f486f8a748633dcc63a981b195431448671f7ec395f7effb2768dee574baa6a242f6563794e715cec7f75c05fc4b2630a47ae24b2a1e3e41516941e6ea58c6d98097ef06498e347b4765e99f438eaaf1c538e0baca4e7eebb399fe633a385b8cecd285b6edfff739a675110387e6ec747016a6a1007c87949368e3ecb7a63a50f3edce168c825b866962f3fc1b8789bdc89545a3394f9c1bd943094546f641bdb129c4e78a9ca0c9ed7bb18923ce669da36f68d57c7effdef16dd454dbecb7bfd5f2e787833bcc4d4996312d8f714043907c3da8d35dece8aadea7dcbe463494e759f473e31c12b636503c747f6424adf687b43d13886f03085d3d966fe5a033d86fbf3546b83b007da37fc6b70db7c1e5e9fe1dadb93137a41d89843a635fb5c389e5fd558746be267440e8aa9971f4ff98be63ec8f8fe59fe96a367ee8cf2e204d41c44688935b0e6439776e34c2d5f5a31664386a5b6051ee6d487846f538e0db7efb17a750d5bdb8f4c37ba859810a8aa15b573ec0f9c907d52124bcefbc48dc60743e7a455a0c4cfb7c57847d5dafb1b5725d735d013441f8beb43d93840cc4373dbaaa81d35af2ed955d9cb60ba5b5de5999b18f335ebc1d3d5b6a678ee2e57e4423b50d30aac28b4d06869a85a5ef47f0a8f8eaf36421b761315b6adacc513f5ae525373cc57482d0be6286546d106925adbc71f4cc1bd33641cf63035b7c02669ced49fb0b8d7de776a768f859c04e3b1c2fd5d9b9d9026fd75bd1df1b19eb0bd29ae7e7c787a0a570cb99f9337986e7e45960f3b53147913c7ff7d05dc652e319825304a06efe75765f44581eb0378ecc979f81950437ba7603b751dbcaf136ea17346cdf645a65cea89543df11089a0720ebf617b731e38a8114335e326716add60aacd9e7f8f9d0168a21bc580087554a17688cd84fef7e4a2510779b666a2b613bf81e8d60e06385398babdffce1ae7abd2e66ac16e42a2f73598dafa1ff769924adaabdcf22697e0c1bfe43ba6f69bbace0f69a2524fbb9f2adc05266003f7a69ac4d5dcbb336039dba355c8c6f5b1035697865cbecf9af021ade9ea08b6416c86a098af525afdcb9b7d1625396077dea96897b406c5681be4de79efa63d5405f35048865e549c3847b3bf01856a16af5dac28c5afcb6be3e8adaf3689a0e5bb057bd00a23d8ac643ccd94c2881eacc4653b52cc87c7d6bde2dbac47678de08ed1484379de33fcae6975b4fcd2d7ad43ae14a5373fab428666fcd98ba08df4330e8e783ba3c7e3f079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4bbffa4083a91e3d58e8937def466d669d555fb0444737c6daf2eecd2ee8f56fe780dadbb8e8ceac3f7e68d0c9e4b5e5ca50eed49c967bd88e49af3abc3e692c4659b3095eeb86ab41d5750210be56e7dd69d34f56aeee1e61db7327f4e6eb456c64f8754db890303ec365c7aa9976c143ed438c5dea3e778e5b6de25f85c42cbe0b24b72bd9fd300d9e54768ffee167eff958894e4898c198a4f75ff871c9b03234f98e7a237778c679b757dc3f25394a356a9eb291dcc6ca5c7ab888dc9e59529f3498ed4defc57d51c03c75235e87da36d3daa9f3f0977db8da14a13a990bbf0de4e5c2046d03ffab31b7aa534ec7cddd4da9877ad6cd6ed07b7b1d8c7edb2dea2b729f3337532e464853357400adadf6a883ed84b56e77b755594b7bffe78116be8c78e75dc2c390d56fab74eba14e8db1d36cf290c6afa63fd8e7d91da94703cfb7334d667f0f3e50c6dae8bfcb56de4de3a58bd4d09a5a3e8a16794e118b5e491bef6d6b85ee90a7f3d5432f59635b1d558792e818afb74cf4f56985e512c9840f364b6370cb319ce677b3d4be2af938234b56cdf632f768a9385d158e844df96c7210d7229cf829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = 3db4bcf203f41e1aa3e81c7336e49c4d86d4557f9e9a47c4560d62afd77d982ff8864cf4f198ed58ace11b38a7e4fd8788298e5dbf6ccfe7a71b27efc504b86d55f6a3cda3e035e711bfefdd78d4771fcf215a46f1cb3d5376cdba14829ff67f7d57d4f199ac398777c8bcded24c4f017e5c977bdef18a83dd177367078b440d3c10e588dfb9c7c99c5164cce4766ee4d51387168feeb41ffcf3ede6fa8de1f385d2c44a397afada7818546c93ef2073a4697aa879eddc4b7ab8322f33cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078294feee43a8ef01af5989fd76e20a7d6aef5fbd07d40e94d4ebe35f530a8cc5793cf3fbeaed34b3ea84ff4fe853fc8b7aa78afb17669a116c49a1bee4771be4801a62868839ab199e3d0fc810cb6e0489820f25c524969a5727f811089c5d8e659f6859a1f5e97ca36a33eade2fdddcd035b23973448e1fb251793da4bc903aceec441fcf3ebeabdfad65746788529e334fdc8f590973b30eaddd09cdbb545fe67adaacf679f0b89d7924f68084888d358b767a8475e85da48590f18d9e0cdbfc7d286f12fb8c6fcaff1b16cafc97a0b9863b1088f6c197a7a6cbdbcfcf80c526ce18058e2d47bf92e7bc0e4d31d4c8c8c8f57bd98dc8b12c556d85deef27ac96fc47f38cfc26468a8d27b2bdab5484ff41aae9d5c3a76fd833d8d2938bf8ad70e6dc56e20db99dcade47ff729b5fa365d732965875b12db82bbf3de8f880754fca89c3efcc86e62a6e56416da11a1dfb116a510b1cfe204dec55a9fbc495e9ec6aeabd49a4e9da97bba98bb4774c0e6b939ad7f0cd2fb2df733bcc1f8c7e4e65cce677117e9c1c978cc59f57ff84eea1c3b5a6479c4935447987bd61d99c1e8dc833f671f6a44be835a8d8d733adf4af4dccba087c4b878ea8b49a863cdfe888adb1d51bd5ae25e3dbead960cbe56be96a142eb5540feba1ee4296eddb81096e1c557ad6c949bec43817a836f0abdad18d3ca17fb489ae627bdfc0180e3492a955fd8f9df7e8d0c9abece03bed35a68d3269cb322b4d66ca9ccd279fc738c4c4aeda8a4a479bcba7b1a6ca8745505c9df36b73f44d54942305c3c0f89bb4e771a6bd9dbb17fd214e7f469b47cb8b64381bea99b6a83deee1a98eaf60ea3ae5b3e4df06d94169ff46a39bec9df34eb5d7b1d9f33b898a342d8d8c936294738cbb7f87c5ba7f2bbdb7b64add475ca3d6486858dcdde568de95c56c6368f5bdac834d7e337926d55d1c9490e7977a8f945a4eb8ff196ba6cf3f92553f9a1b962a56ac9498b69dedc93946f1f7a662c6074c9e93b44d099a0003390748547f2dd52506ac88dbc1d45f3a17bd825b4656552383edfd67b2b4f3bd0aae22fcd971f5f96334e403438c3c254725ee565ee569b0d357b416bf3d87da72aaf77caba3365e9725cfd98b1d7f3f5ceaa1f497972d8e73a3d4852c949debc717dc8431ff3987e6df0a0a3fd5f97aaf5ef9082f7fd2ead78f2aebf47cdb66e596839632b22ec5eec376958d986164eb2246e9850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcd8d5a0f4655d6ea8564c3577273d1a8e84a2b4443b1eaa05a3edd28f7c083df14fbf798bfea83678808913c9c6dc57eea4c1f2f469bca44aa8b8d82ce4d82464a9e6bcda86eadd1f1df1dbe3e96c7f6ad9b43dff34cda455c7a51ca344feaf8defc580c581e4ecb1517cb36969e14a58ea0e73718f07a8eacb71a8cfbeb2654fea5a7e01a6c02f183686b89ca0c775d16d5e182f5a655a544838a60f35f412fa5baf353d2d264c4e5cfcd31bb4f3075411dff0632b3d605c7431479f5694870dbeb1725cd363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d635fc8733cb40627485df64a4e97fcbc574134d3e9cf1464a6b69a6328d388a6e11fb69d306a6c47a39306abdf28aee256ed306bc4ca2e93ae71336daa3a8bc15e7e002ee989f9c19bda67527f4e1b08e7d4cc7397cb5a58ae4c471aa511f4ff18e493710e977d063a4ee855f326811fcf6c876fb5825a95780a3d031948d53337a45679f5d3f8574ce09e5944b69cdb4d2b466fc48f9223f8d6fc74705491077987e6cc936e2bb69b534ea97acf85f6df262fa55d1e5cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 25df5e62d57365c8c611f96ba675aae6ae4164c5e71d84e46d89fd6203ba384ca81ed7eed87b8ba51df3ed8bc6ac54406263ca3d97c5bedfdd9e2cca83bdaa54586863d95d3fedd75cc897f77f6caa54e896e86e048eea3e1d9f5bd3e1e81a5194363f8bf735acaafcaceb7ec58f6f8bffb303c3914e9b7c3c5337432ca626a7d762addb44cc92630ac8469a6bdadfb46d88c2262f3dfd4d5d6f1447f9878611edf1cf3762c235c4150f5239ab3827ab5a4699c82e37b1a27b46100f64f4089a98f4ec924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad08739367e8bce46b2f19864e06486a4f5c8d689aded3fa2e7c6b5717ebe680e7fe25b8f52ca525f99be536a4c1468b5f904e9025450048692fa6eab8feb5075b543e05ad565cf6c58b7fec6433b624afd5a086c85347e45ea7b9add3ab5066414a4e4c308ee219a5b5e83fc0b5fc060f9de65ee4874ddf168bfea67da6a0b94578144ecb7c65aa2dc481b0998de5c8d893a548f055f8ff4f0f173b94996fa5549b0ac29d8f30fae0bec6b1acdb3e5178f4f4d485ca33a93947523ceaa6c188ac2fc4c002f4b996bebd7aff9d01a8d3e2d45b07f3a1de559abf78c0a9f8d71aca3c10e603844dae725d58c95cd33ca8570abf134f78b86a84ae764ae94b994adfe354f5fe26638b57befd7bbdf9f1f6d471acb5b650332b4656ccd8d8c15ebb8e02d3ff19febeb6faa67967bfedd9535f7d88ca98e3795aa1167be9126348a946508cd8243a969b209f490df9f047d356288cb1718d24ba7a9cd58a12e3d6d4f4579893c8a05bedc197fb6a70fc15507db8ba69880df8dc94fb9f60b405299da458fa351533b486fd61f3d957f9ae6b6f8502a1b4d909eb56c7e470fefcef40648533bb1d9179b3e335e062ee5b817aa30b3707b74e21179318593b0460bcf6e57a65e045d00353605e6da0705468c6b8e4dc4f2c31476c9adb54fce66ba59b75f9834634cd052757dc447d05f653ed5ce9ceb7c774eaa75bb0d68f2a997a79a98bef4fabf9a3b7597394d59d7e53d737f96d4554d7b8fcbfda1ad54c2a4c737c8724d0f684a17dda34388fea9f7bf4f59859849ea9cb6ef5990ebee76f0bed154556ce575dcf264bd1188d055b5931bd6c5f528e6d135996757b386b76a03893efea95ef964b402079cad18db67098b2c19ff1e9768782a8e3daccd8284ecdc5c8575796d08f3e80b34b4cf2f7e7593ae9264417e7b53dafaf988bdefde5fe50b4f62441475371ce357a5752885719975f7c95a9fd62c3bf54a8c8fcda335c3a31b934002443d08ff724096de8ea76c821a71e77e32c9a5a1d4d3b5f29cc9aa9f4081fa3c33f4a11285458964d42337701c49f998da8ee556a545fdb49cacfb83b58dd9de65e685e318363400e6e652e7e70ca44b3033bbb20b450737d8e6453b1708b5b92d641aed50d7c8843e0bcc227b9d6c4f6a9f693945d69ee98558bcee33fc74f7a8f73981786f42ecd3fb23621a5fca8bed3810648b8cbab5c2df8170dec232fedf7eeaac9a798c2c3a4cbad4f8c6a7e8524fd191e3e95fe4419ab69fe923f80d0763a906c33c4a9d311c74d9459ee85a659916ef09376a158d3e1ddc67d93f8bef1c7f673b62bccf34b21af9802ca9c19c89b9b6628a6bac7bef9898cee36a0b8c29bd441cedda9144c85c9897a499d2d176b9b03a454f36885dc6eb5915811e6dc170f74abf894bceeea088195fdb3d43bf6d80b8b98dd58e68c12a68d0b7424257fddff790618e70c37ea4bb19907288854dfec4cd744d1ecae201fb643c8d5c7c8cef6cc9437038bcaf76e6f9a6a214785f5ff7e071e4564e0d70a50eb4580f3685a65d63fc525beae4b27cef548e885b24786a93966936eb779d68c3f97eee28aed3fc68d4bd8d6a6b77ee2449031cd191dde6395bdd9d8d85bd65dd1205e20e647b9a1549e8f67f60dd580fb393591e4aa668bfa4bfd2c0369ddbf5518e8daed20c403aa3cc7158e19cba54ce1667c2654d9b5a833d5a552808ae736f9a2ebef4993e9a311e3b314c870e8752e54faf5ed67bf158ef0729f1192bfb21964fae23b33d05f9a32d90e4bc6ec3aee811fdfe65758397b48d1916d13dcdcc0c2c73944b45bffd4c288eacf467336b1d7ff7dbe2e73d5ed85342d2355b047862be66d57cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = c72ddd6d7952095f57f79fad9173888f28bdae384636cfd57b8e83ca07853eed5f72437d697f575ff4c0f0bd6259e397cda6a87a178498c9aac55bd46b9fe9d98c48f113319984995f68b1affb863ff97dd9de4cadef921cce92e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e83ee0a68940ee5b8307460b50f651457ad1a7883d0165c8cab4d88f565018e55ad0d97776ddf3779530958c3003c7603d9d0e60e48088b9420b78eac34edc0bae1464e95a03998388ac747fc465ece40e9193a9294abb90b8022b493e069ae430ab3fca3d7fc89358d3a88fb054e9836cefbe45c44569b286bd1ec99fd5cf8f88ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc07ad8f521b606306678894e964696a31547c851b5790edf4355f6c7e74efba8fecd49d984ccef1518a88633658c7c7c6b093dcb79ddb2368cbe703cec33a4be03e9b4a9d9b590a8bbc6542a108bf5927c49dbaa2c5d5d09f1dfe242ba210a64f18b8542ceecb92b8f93c56586b568b489ca697d6c4f819c39969d472e8b9de9573a2df934b86bf2d2b6f92ec848953de0a78efee1af2bc3a705396ce6a74c1d5d3a91baf53db7e8757c875a154fff04f41f95b516d37f20973c25e29b1d335846db494db4cac3a0b763893d4b435fac246fff13fa8b5c3322f7ade565879a01e93ec69bf15c77e60ffa3a39f5690496af54fdec688450058b5728ade66f98270267b3f59f70f4ed714f353dd4b74410a9a0e778a1e13d4621e3cfb05a1431decf3a7f1226df6cf84b1c0f7d6dcfc4d9eb8d51416e464ae6e069750c026ad26ecca10f5830b2b756e5e5ef1c64d6d2c5e748e8998aa9231de9d3594f400c456906f397fbda42cf86c857c3ab009c8c94ef57d246b456996bc1bcc378a44bd88a0fc3469b0eadd235ed218a4e432beff3793e65344ff132d6c56c4b3bfa8da5027e14c4ee2a72ddb07afa62104c48ce8639d1830e785cb3dbbf3f398691b48458d2acce7a5e1ad276643476bd6c33d8d1c40fbbeb81a96a7dfe36115e49a07f8c7234db9b4ff4a2739b9646d9b0c37d5f928c6ba8cffcc1ce64be46fdee5baa583dcd7a55e132ecd743d5bff9b8ae6def6b97febd71e6c172869751dfc88785c745bc32f0b86dbb9fe072a395f9eacf7257ac5ec5ee88a7095acc39bedf3a904b72c0ac845b3e8d18c7c73adc4387cb470c8ba438498c65e4398d7d967b4610aee8505543a98e5ea3753bf3c657af07f64a92cf25308d2641c609628a7f14af46d5aa13f3a4d1ebff221ccba2019ec6284452f376b32dcfd27d3869137a3fc0bd7b7c93f70f3a20d84741b9ae86d78af95dfd4bc0b6da185e75be8e9479485db23bf6fbfcbbc6fa089ffbda7cb470c26b282ef9e0f29a111688cc2e7cd61985eb49f87546967ada9eeccb99a6dd4b11196e755964a77e3a7d2c5b9dc966e705ebd53e7ff9775a624f344fdf4bb3aa8f2d26b6db7ceeefc5f7a2138c45f27c5e8a834ebc780e1f8f10a9a7a4b7c3fc64be758bffb8cab57bc07aa28bff8ce3d411e04d8bc276ace9cd5498cb641366b4fadcaf92de198b35a51e5d2a2ce894eeb700a93fd70f6f7ac0b7a57543769a9ef017e76ce0be1c6e74a988ced9b9750dc5f30327f98a90db508e4ec942b48c46d35916cd504646726ab767b5d59d39996a3f3e0ccbc610d878f9b85d3b098f2bc1541a359c8085f6d27a7abc1d78e3c0c3f68fd609c699e44ca8ce2c7a78f8dd42cffef4c569e9d0494a6e8c2f069fba516db365b57d2bd3917ef7fce04c42205803bfdb214ef7b21245e480b6330bc8533888e72e9bb2158d59ad4fba2caf550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de48981825ffa34b9a23a5d8879ad682fbf466a44a5964fb268e3e98afd49f433a7a12f5d556770f449edfdf4432133a0d888436afc531f4584abd4d022c36314757e79538cd1c67da59ad49deedbaab7a7fa48f93ca8440339e372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc8eec2e63af616838d5d13674b93f694975cf1396dec1ea1cb6aebcfda55ba86583884aa9593399a047f00f7d3cd458ad157333c349c471feb7bee970ccf927f094c77a7da7c9bacfb0a6e031d803608dac9bcf3877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 49548733578aa80987b45a404d99ff45f83fe636db463ee81484a7ab65aed79a53f2e495ad444067eee08d14c4fa74847fda990a783fdc9f373496d238a94b8644f17de964ea35a3d4c651a15c71940ea2cad86352257c2daea8803f9093ee8c5c88face76ba239c6001143f88ad406da9437d8be9144386b9687023a34a478e4eae14dc71673aca3993adcd3879c9af60dade4eab9205b7ab65c33ff1295100d349f84694aced62682e35865494ecf58db3aefa3af380c228b78e3f9634f359008871769696bb357d552c3ea0ce7d8b636e1c9d5303cbfa5b6a6f07f478d52f9daac38ecf47c20547e705c7f092f7a439ede267783e2447d08046fc659796d7443354e9fdfb9bca5ba5355e5c3608bb3d9c4effc7ac435c8ecc1a6ba84a84f83763a52048ee9e3c998dfba80d8383d416495c4fb7b6ca3e91789c829eb89445df52b6b7a3e38a4505e039497795ed97175dc44665ed7e3d4c885e5bb415773d1dbf08dcf0507cdf5164f8e8c9d37d4fa837469de6a3a37c695b6034d7a46b7796593623a9c840accb5a7be175b3df62c8b9461c444eb73bf2fff418347af3e9f742175bbfc4e474156745fbddcbd4d77eeaad6c13c314e3e88d3c9bf2f73785cdcd1b2e5c4623a8bcbe9997e8fbe3be719356e90f054a1ae9f819d9b8130f8633469c377ef38fc66cab8cd5bc5468a23fc9b3b5dea5a4a8ea04800c97c3b4aee15735d11e597312b7a0440ac2da794859776ca73b550d666a8f058478aea0ca7feff6184f426ee4d365e490a7e9235ce66734b5535b863afbcbc6bff64a86b0642a41763b6d6eae5447bc93109f5415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da3786289da282b8db833ae37bc5a6a4da8b969f6f1f468854bf88c9a4c7d1f8bcb56c7a218c3fd7f5ad1b89c829799b0a8a1f47e8fb489b83caddf1cc9b1ee16369f18b208edf2a46ff4330582bc4848e4634f359dc12c756246dc9f3dcf7550057a1863ccb91a4b8928f0bc98fc0f7df4e1cbd37687d92c633f2cf68b96b666e1034339ca3e43f6ae7febf2f9fc7649e559e6effa07075bde79a82f6fb5a5258a0e685a2ddebc8566cdb5ae9d5c68e237fdcb4e7aad6f66eca9f6850e3da6fa1ceeca33da07feecd7ff6194f56f40bbcdc99bb4c103fd851bbb7af48f19e8e3f8abd1d9477862fef8631b9b4e7fc4c7ccbe5956fa4519a8a34a44dd84586c4a542aeb6e1338b6846f97a69f83af07ccecfcd1ce074d8469c9405d9f0907f40c19fc640ff55bdfe37a4349078a473e8ecb3f87cbdf8436466ddb932bc326a85faa1d95e55e3e9dbcd2d92a69f5acc4200bb1dd0f70b013b1f247fbc75aa60aef91f0385bbe9376953cccb3f99971dc9747cb91386d5070bd51ed186454255fcd74faff73c32753e58d467b0bede2aaa439c9335b4fef3a426cad3ddbc4ab98f077cfbbe843f1fb684826bd32059838e3d43da2985230abea7c15c08a5669a3caf200b34b803f5a5f47b479aa49994d60ace979e9db6bb68466973a3e013dc0bcfc4e6c7ce3f734b1731ca956f89341d37b1cd5c40bec802a98c674869c0467e993e461447bfe2a68ba729e5bbe0cfe40dc8756b9ad9bab639ff6985e03b5a96e785a8ea7b1449594d584bc1cc4ef7a4333e5453944c61e0e45a5b6c99aadddf36f99ccea5cc1d36fbc8dc1a5e9c619a4347669377d64e519ca47f06884b1984408d43b4133bdcc488bddc599c4057b15bdf7d15e420a6ce7cc1671f19af128b58e9b7a5e233a6ed2eaf8823db51e57d38c9aa2751556ba24b2855e5af73a81a698ed6664f6d2df7a8a763fb4bfcaa19bc310a9c10024b7d82f606c3b6f19c8935b744e28333df8b9480b0d83eb588380e6a12d777862e5c7d4ee874e9be405a5787f9faccdc798a873539c133502569e6de7a29d8df5289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960761fd9ef5e7629daf280bcb7df35793cff33fa074186ad4894ac515b8985ddb5acab68ab379a639c59f16a8ba4facef5957e50a907385ea7f9a7e6f1a5a9bf8c5ae234e6ce451e923c18ca0f9f5cb47fc5932da50249de4c84d57107efeb1d83887a5797f563206e4f4faee8491e892d6d86b0f5bb6fd3f2afb3e6545d9c8f1ea8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = 08aa6ac1e96fd9ea9bf4595a7cd565d924e6b583be0c3355ef18b9b4cceea69e35d48deeed6bb0b66bb32067f18a5f5bf58d4a8d75a5f973393cf53ebee8ea1f2ca33a0e6e366e7e77b58a39ee5d427d43e6174888ea4408cc8584de960433e7f3c9571e6347425cd32dd459ecb873d7f9312fe891a0b8e261136690363b816a3b5399f3e56741cccbc86d477c62aae713e99a4be8aae2b3516e863ef33f7560bdd25f4da664c7e4bb5c8b2b4f568e8f4247dd69ba2469ca47dc1417a6a73f978dd39503e433ac8566709cf1ab04924d257e810f804fafe47db57a8d49e68d7d9563e7604674ae831ce76914ca2ed38b9e79351533eb7e15b5dbac4027daafb286d99d0d36f826f1f7dbac5d24c5078df3dc7bf1998ecdbaff90bb9454adb45a45fbeb976be094aab8b2a9afe05a8240476753ba802c15495d5d34f9348ec8c732724c9703e9a0832d854a29598c04fc6777a19eb462c59d7f0a7b5a3ea9ea5d7c4d8b7da78ed5cd35dacf9e98c19c596ccc1c4710ec9b02a7d0adddd2a1c661c13ba1c26aed853a851054546c33b1f413fe1f089e9c4c8af9a99c3d7fae4087f72c3a37839b817b55a31ba99b6668d7660af280c35a5056fc0b98adc38c6ac1e7fa7396b28e36cb6b7decdf7c9857f5413d48da1d13ebb69de89028f518ec414dd78a8ef86ee0cda1f10572205b55946f3c41d873db2eaa60e3870358d32497b367bb50dd6e76d415ba54f8809c4e55462ac6d34593fbf57fc7d5bf65dedaf1ba368e5fafc9efca3ff8467528c626bf670a2ffc6b1b34658f47849338a35dd5abaed0a89db05474ded59383eccb6415f7a15f2aca63cac12619e13d843aea838147aed72ac8f92b7c5db1d973aa6c7b2cdea4aeb4bb1d58ca7eaf6b2f0f96221d42489cddabd5e1308791d7a8ae725c922ef374acc53d76ba5a120bfb5bb94c30a8f4ef1e9c87b6ff578699690daf29eeee59a83de15d441345e652edf09e98b76513747d0873348dfcff8463db4c353557632c8c46c3667624fde2e5d7937f7bd04bb549960c5761de5d09dea4e86cf88b2d44d146faba2962d3bd78b7854f997abf617fc39044f536a8ae906f385a5770d485fdb9f979fa19d37bcbae54d4583e17c4be538100349a37a5d2dc69c283638ecebdf8ba0cb1d224f6334c478a7e5cb39c79d04d8c2d27f0afc8986eed3628bf8efb773ee71f630b2ca1a0b8e239c6d20e1380ac69be3cf3742014c52fabf2a118aae719fefe8c93706cda7a1a884addf16f77669594dbb1ae68d5b991e4ca78af18f55656d010de637393ef8ed490735de9aa15c57307bf071ee392859168ddca6fe88feedb49878c7bb16d9aec6d442a8eddb84befa69fc7a5f9e1ce795e093a96028757013d6d38234e2b7dbfae5ffdf30380986533bcec5d8d1e9bdf3b99e1596a06bef3e2d3acca93d31ff778c228ef76df68d6aa98520c969306cc8086378a7f4c0ec5552eca57c3d84fa24ec69e07b39da5e8bcc5f049fad4145c34ad355cdf65cf6d2de4f61eb9c6bb92810af5310d781a99301c06b77ee6d6c00aefb5987e76aa5bb346cc85c85acb1e4cd0b5ec06448c1eab496299515d8ae598a4dc33c8bc58db4486867159ad9080b97674cc9a9f8ae76fe5d34c139b19b5dd4365d11e2b65d47ab642c84812c74dc16a83fedc38883e45003f43564c4aacf969f34ba744ae4595cbdb510dc30b47662a7b4eaccd980aeca368573550d3e4891e386ee589a88a53cbc6be1bbf755e58441b6c87e83baba58b63c0dd97f0d4922ea7c0aff97143666d922e99fc53d7a3ccd86bbe3d6a6481f51ebf781be0f6ed4a42ff7f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9631cfc0dc6bf3987789bb5919504e7f876ee6f5395839c68a0d85d14ddcc008e7957af8124e47b5b3c9f3aeb9537c340377ec03d28a0971dc89c8c6c69d9733c4fd382a84a6dcfb9407743cc66611e84999e1e356125d60e7cfc5fa6e0fb9fdd18b355b64890b0a88fe784a39bcdc9e539732d79a3693f492439944b643436b84d4bc870b6dfea5f2f4e321a5e7a6931e628342ed4616fb4b1997cb12fe6be07cfde779443761fbe498aca2c63fc3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = a936ad0eebdae5a6b9a66bab5538cab0ac6e053dbebd798c474ba1ec345ea6d3baa0ad377d46606f7dc86edebe281a9f46fbc0d99dc607ecd09f46b45995898995fb568f566ce3dd033e7cd5edb84e7be917e692e45c9beae45bc8e8bf6a6558802d6a67d93a497fc5723ddbbdf6f0e263965a4df068088bb2d8bddf33c98ef34541b4c2a22897815b809b16df873ddaaeb9d376234860a66e9e8843bc5fca7043d10e47c41d573fd9ba40c4faad890f6eca797e80396a2ed558709ed9a44bcac365e17a7a3f72a5d030cc50658faa0ce39369bb3510bd7b1388981c89400ab5a633ce72d159c6f1fef6bec96e18cdc18d6e5be62ed819edcfc3addf76e7d6aec990021aad6eca787b453991a896f57ff53715ee3e5ae1a09549965f5b8f3be1583a3a3e594400ac97b82a4b5db8f28929e0c82eab0bbb9943ffba778adc5d8c532393934b49efe5669850bab0184d905b684aaa96be0c05def463406c9ea28159e74b555c742c3f78569bf294681dad9a336531edb94bf30459893cb2de348330fc56a83d4ae2f7cc34de3b7966751414420edd89a48a6037cecd7c66d8727b52612864b63694005590859aadd92bd68b053454dec6f9287c58bad42083d87f7959faa3f28433eb39aa991c15f3be599ce86bef0fc5fd475e56c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eac3f96043f860e3af5b8af5e87dda7abcdf26e877f0488877da4efc1ad54156eb8a4744de6456df6c5ae6d7fea96aad2f9c943f68a4880a3f8a0ba3892d7af30ee69ef4e554f0ac1a3836e151760c857ff60b77e274948ecb6748d4d4a750d5bde6c584a5defe2d667748b9f3c19a41d659475bdb4a78f9d848a898ba3d80c66aae85b3660d392f34a6ee9c6b10df567ddee892f4932b6babe32eda5109fe7985c6537188b817b3312cf5e8c63ca265b568ba9cfdd55ee6fe5e7e193e7fb99c8204abfdc937134e845d0fdd019ed97022997653a8d5bf3fcfb07b34836c242b74ef9e3dba0d7ad8c3bf944c766c025804ebbf3a05b6fe6b85d3329d4c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2f7de1a63815c86dda8195bfd53ea9fd88444ef6dde85c5b18d91cb19349cfc73ba195923a38ab7ad44d1c9cbe4a8e95c1b5a28afb07c6f7c141cac61d391ff1b88c9893327447d32234705e4ff10374b77c86d83e7ee381e893188310c45c51a5473003d8566d87fde99c67ba6ff6b4750d795ed3c7fd1a2faae68fcb10124d4b35fbcdb44ee698dfc8dd6a2388e3e049c42abcd5977637cd3d8e104ee973f6b45b9bdb56f69afffc9cb5e97bae9b6c5809abaf47b5b0c2d471bd77ec7455e1ecf5fbfaa7018e58133a44678083c07ed633455f890a352415f6225a33737ad42b1595da855fc2ecad86adcea6cba45beccbdfa23acb30dedbeb75ff179cb3934fceac33eb2889c4784cb970938ad336da5ecd13abaf973043372cb99667f97e7dad5702992b578a65d0dc867b43eaca93e975695f86f5aa834dc0e68f7e1636d72ec4a058d4090aeeef73eb48a1c4462665b230550925bf3481bade7b43a1d76cbe689ee33874182f955313cbe69bab35aa59cd2be33fd3f6ba67e713a1c4dbe2a662c5e4021bc7bae44343f49e38454e73dd7944d6f91c50973ff0b9c0aacad9409881bcf32306354d546f537c5d7e2ab84b5ada3b5b9819f6fc3b6ecefcbcad224b48da81e4dd4fa3103069cacae7c09b7bbef8b94b7ee5f594feb708c9c23b4d2897d8ccec56f40afbcc7397101fb9e54fcb7e7f8e6f14935667da006f69779fa6e31be310e6bc6d983599ec8ec202c5e887659f5e7836fb7a72ec8d4751e6c6659c24dfc4c38ecfe8d7ad787a3b6c27da23ba53865a53849f4c3f26bf363e582befd79793bcb832878b007f78f658b72b3417135684393a4b104d422ba7fb1474170fdb58d3b62a7343a6d5eb4c8f6894f1bd5e33476ba24c61c276652048b009ccc1a768e48cac707b4ff4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2fdf429d547b4db5e76a7b621a38681ccb3e72d98f1fa9f6b1c3d325d6cbd396fc7d044dc16b8a25dc59c2a53e2a5d40d86f7f744bcdafeb522cf8ca6eaca4011d6b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 656ea7a463b8e41cd3739a6b60de96655871adb3c82beedfb3bfb538f6ee1b664fbaf761f09b4d5e358b528d88b42d6e1295bfd056ea2ff8553c4dcb92e36f109f8af9fc7ef54c358d98f80697ac3d5548029c3faf98fae2da732e0c47934b9c9833fc40b84a3454f1e718f26ca6524c16f302765bf4d593e2d75d3a783f1dd7328767315dda868e685eacce8fdafcfca9bd37fdc3607629cc3ecc8e848c771b94c6a21af8e40d3778ba68b923b71116dbb625f5557d7d7e5ce35ae8663d87643ec4921c6a5c20ac69e68bdb795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e8bd3189abf9b4a91eb88ffed97bc3a73e4d0ccb528c3e3d165b2910859de867d7e6f90bbc85186cdf0166eaf34b9656b0db2ed3f323b26a0488878709ed0746f814bcc82862a7280a5cee73a330e7cfe01fc9afe2741b22e66949532c884ce8c0ff91aa4b860756463bb49bd25f4b8ccc6ecc6d51ada819865b8bceebb0124eb77fa3ff67e3f95baac10866303939c07483b6bfc500e6eb7ad494382c643e885d8e51dc30fe96b37a6dad4f7d7421944b13b31d6686745d5fef6ca4f003e74f1ace695038368cef18e9bd8d8f6e8097db0fe5b5511e3b4641b6fa54e56c66eaa2aa9a1e163aacf73c24d84bb775dd4b3c3f9dddbdf167e6e17d5ec6c53fba24d7c0d063b0dffc073763a790cd0312abe6d26b0d75390492a88772763fcf67e1cff8e1b0ec0a67e4bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5f8dacca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f15f450875a8997c335ae85d5b89d3784def5a094a5b43b5162d6067e36fe51ab9af296583d47450a34a302844b15f6a4ef891d02cf8770f453126557a876c584cfa0666ea88f9651e39929d0b43fccba48595925d0eadc0677200c39c64e44505aa58a9b5c8841ec094dc3aa63e4f177f47b60e798c5add5daad4b77c6552369542e96172573e727890fa4bfe366ef86123f21ff9ff81c481c125bfa7b6e99ef8c0eebada5b8973c9a33807a464fd4a50eb294741c5a8fd99817197fc0fd44ec97ee2e19a707dec76907f45dd2a6f60a554490947e525fdc3eb9d9f7e51007f88127b5313757431d3a41c673e203c7e8e9963d0bbe276b5c1114c38ec8cc0ba0a94918cbccdcc7dc53667054e5cd2ab9a7fe55ed49498b8c7e05fc3e2f5ae53e394a019749a23dcc180236468a47d96d47be67adce0de6a2ede5af08f604129fb8028b1ea88ffbf1afcd5fab1911eb219099f8e87c74cc69841f4a928ee81e98ac6b3db7846ec38c0ba8aa905dca7b4f3a484d60ffe6529abe2786bc8c05a384f0efab0f6c06d1d47e68fc02a54aa8713422bb6b9a6b4e95fe6843d7c639916943b5793107cb8e63365dab357cd0fa9f1b33e8eaf9f25f9839d96f285864ba89dbf975f92470965e0a9c1d1f65b72139908d791a4d89e489a983279a704adc3432f786f1f3b45c793c925b1a146c007fe5fb5aec85e28ef8b1c6984eea1d83edc1219ed83439ac9ae5d965a386be47145bb94626fcb8869b35965412119fd81947ccb67e7e805478a8cdea924692b46eccb83df328dc8f89d41f8d3667585f8b18f8b7ff9531c76690c37cd817fccb1c36a195a84197a8797446273d686aea96ff0ce53f28edd992f9abf35b6e71f7f2e5a5c9e88a33a85a1007ae383988e3d7f692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f046fc1f84954408ba3c9284442b59c1a59d4129cdbbc5db2e34c98b819a1d6793de75697ce8e4ee26fae3dacc0d50bade8b835c4ff712683ed282eab629dff544967df987b5b1bd2efbc95847a5f071e3737e55ca4ebf0c55dd580b5c2420e6b50db710d7555d8f67cca13b2d97ed3d397dd5713b218dd3b3984334a6ca272d43911fcf3db3b5c15139efce5e0a95c96d68a70d2988adcdd48122678ac9ad5138fbb4fb47d6d68e9a3a986667ecf53b78ed80a76ffecc972cff1bfc9e7bc79d18edde7746835739f495d98a022634ea8bdb1f517734ef4dd0f9f791a3fece9eabfa05596a90ea342b87267ac90481f999573d272cec2f02a4d1b0ff27b65c05609b87463d6b6b9df86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = cd4dbee26ac378d8b540a9feed54b23676827aeb4bd44857c3dfed55e7fd0db795b0b6c8bd9d77aeb59b71588abff9f6f7ca57d315e4111fa41fbd63f538e018563eac7f52c34aa832a4bc27dacffc0d8e6d255cd547a0ebab65f52dd3566df97d5db1a637cdf09e72b6d4ab96ac598ad7622c34c3b98890c77cb9a6ad8e351ea235da946d9fa81d7bc579a8e7563eb204ffee3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2a9edf05f7fe6c838d4fef21bb7a48cf7a247895dc783f8a07b8c342c731d24ca8a83b9cdd7a47025467ab8ebbb0878ae5c8e70cdade2f88c68b3f8fa23fa4b6ad298bce9f56d98a55e8709a3d1547dd93bd7b0ebe3929b0f83344ef362ed7a7dac8c90c5d019e73893f78d0a8df8fc67e4362c41de4fc4de7ecfbea58e5aa96d83bd3f5ef65d572957edf9e9e094a70aeab998a55ae5bf98899dc88f0ae195273b132550068337596f84976a30b0c538475af5ec076961debee17fda2a875fc63d54d38d42675bef51b7877629a1fb8e5e2ef578afe936dfe5c7cfe6472ae7c2658d9a3b1f85f7ae56458f46e4e832c75439cffd74f62bb4ab5a4becff4a12acd46b0cb21565fd126c32ea84d88a2a7da6bcbc380354a00642ddf9810ca8c0e08f96c56cd57d03fb4bae4f4529f846f3ec399e9186efc77c0aea9c3dd3b80a5d6a867cc6764fa4c9d7646cb923e39bff7ae4f335392363890cf66a110f6e7df6fd09daa31b5da54595e5dfeeac7e19fdc19ca6005e6dddf67aeb26ba4e8fda934edfba4f581f79d24ba975598c97c41a6112d8e2aa7af1268d60badb32deeda5eaaa4fec6983777be349cd6a7877bb1b54f23cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a2786f529804d4115ad18b8b78af433a15a69de24e58657ba05855bce254d2243746de13728b4c435a4d9a282b99503d53777a72e6d3d686fbde4746b88ab57fcaff558a2ad820c59c2cfc801b97b0206833d4c389e415330ab87ff97dc90f96f18c4bfc058b97b1e595f887d3f6d34118965cc894f3e3bb4e193fe0c225902ff3f29e4559ae9af31b34395989c732f54be1c9db3f846adcfb5a36089f1b057c70a3e921fb362079666674e3c8998c509a6268a6bcc137eead333060d975392da0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040bbf773976ea3e687669dc152c897d59543fb576e6cbfff9c4ef995f9969d9ecb9098aa2046ac4bc69a38ab5c7b2d6eed57514de7821e64aa6636f99c99b2a7299dfe933ba386a19ffdecd8af4db76e356a19a68f78d18a6847f57cd247346e2a4e58c36c3da5f5eaf96d4c40ff6014648f310977ccf8bfb373e6be93f1c71a4e1755f37f964b5df9b67f8699454a810fac4fc83493aa2a7e4a06e828759a12a769fb85ed0e3ef5413cc0d5edb5aabbb63b8c8ac5d385aa5d94e075dd170d9da134c36a7c8a59ba90260b9af69542add7a72a2fc8dcdfb9e1dcbf39e6b19a58e5d1544d31547f9c336baa44c8368d5c1a03610c0ca2b33bc44557583ebfd6ccdb50f1c7309de949996ac72fd9803ec5bb7a25efd9fdb4e89dd8e36ce02a33a9412b40e4b7a247864277bac3c24d9006a75597ddcebd5f621f9ea7af89e673ef9861533e775f57bfbd6fabe44c21fda44a288c43eff851433c2be639404aba3e6b356c4671906a37589495484943207e717dccea27be9258db8096138cf83894182c88c6d9a56e7e8f499d40677e84ad175ca1cdfecebeb5fd1afb795e97bc696a6857ec9b486d7596657318bfd1f46aa2a4e4c436c0f79f52ce96bc09837cb53f5903cbe5d81b3f5d6fcbb8dbaced84f1b446ea8c196602cdd2f79877158c97bbd8d072ecbc8b69557a4c60c8f9dd244f7dc7ba806bb6f34189bd874c30ec696710c53540f74bf62bfa7786d6721952fa3d358b55c183db4f1fae7a762adcfa14c55ed47cfba737bc75725c3471aa8b56315dbd4255e2df66b0684948d068b94765adacdc5a25ee8035d5e64c54ca6427e144bdf3a8ad7ad8b5ce3bad95c83d7eadd6499d89ccef0bd1f635334a3c91796dd9fa6a93c23ee85498fe99b7a32306bcf053551bf99f99c8a4591d6a55ec98a1cd6c7c58583ed757956a89533c6c7b2867b8d3a5fe05f7e13abe8199e9fb03a7fafdcfaa0f5fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = 5993b3dc543a4939519fa4fb982aa757438613875590edef3066af4818d751346619ef5c260e97a07dcbd82f528d7e3e9cfeb891043de554f4f81ffe45dcf87b7a8138c842f1bcbad18795a48f439c5c470b9e309fcb8149039d0435b9b81ad773778111134c104cc5e7bbc4550ce04d157f2afb40972c41fe85622825b5ac48c0e357cc2d9531410e5bef5cae1ddfbf7519398c7edc9b29efa34767ee67880fd9ab6d5782351be76d3a7c3197e4f92d8f71d8da1b189bf118f7b763acf096b49cc5c0b3bfec268a6c6a6ddce88978582543899da6e7e399edf4e1d83a53bb08f0c1bdb47279fdb25b69396337b37f4f1425aee7296fb29a399a16a13ce7489968d6cc5c64ac87783af77bc063f9ba849a0873d4ebab9edfc5435b55503c2a6f9b996d75359e973d77f4a88ee3ef59a6b97635a3bc877db9fbb94af2fa3046c5ebee299baf3f7f1519ca171aeaa443ca324ced336952a4df342d58eb10b4752e34c2f03866ee8c8508a77a482ec387054cd34ebd54b8be0bba7be196e6d3b649a56fe23e347f905fc0c5cafd9fe7560ad88f2bb776233efdff7474b3cf50b044ed9ce6ae52dcbac5d3b99807af8174449813e477c6e78d4552d3f8e3483c3c6c4a73de2eee7874b765abf9db53946538cf3c5ebd53d63dca69ed1604346a4edc512cabc763b209ae9099fba9f82b445c05bddfaf59a0156940f3d99d97928d8d79bb7846b566b4770c904b75b43025eb3198bcce1830b9b8cd548ea1b255a880e49865297a811f91f5aef01684c659df88ec63b8e6e4f3c4d9d91f9552936f538776f9266969addd9a8c896ddac6bee964832ccd952b98a95ee54422da547ae9e74513d93835c746a3d47d88f82afd6328eeeb6a646ae2e8703c3a6bfea5e6e729e5e7294a2d5a4ec94d6792b55692c5591af95d3e7376f6ccc58cbafff787a12619317526fe6a084159e957d85383a16dfbbced91da6a62a7ec4441453306f74c40c483aced92a36a5876b6de1893c8c4fb3dbc946d781873d49cbad7ba431ef8f0f7fdf46b5548f045ad66bd670c44ed3edc40f43eb5984dab0d167e02fa36cb23b10477d84a63b9f1facabc9c86e76eef8cc6928eed39141de927ec47e7cdd1264c9629343e10f945e409d75e3985e8b4b3537beaaad9ea02a7b701c961a939388f57b310c4652d7649d604a0a80d6686c5c0f467486f5f48dc24be1304e2fe5f4a6e0bf86bd75875d5cf7a18482dea41b4579f168486c3d87545c4e5ec495f37185b686fb754194f404e5f836f8ed9884b658465ffec83f62e3ec25f64c454cb4cb46107dfebd813ed11fbceb50b7d897aa771748cc2e5a23fe99fa91347fb9dc642b5410c2c4383bda498f479aaa4d11959328eeb48e93ffc5cb8f930f5a4d40a7460b8f7c756c28e99a8854db0cb2d6241f4472c06ca74d48a5f565b8a85803f2e4f9a6cc92bbfb80cde6c0c67f5a9c7bfc606710a7ddd824fa8bf78eee32b3d2bcba3eb2eaefe0655fced6c0c0c6b303c6b2efaa6e8e6b29fbb86d0de3c6e143d7c1d4ec625a6ab2c782bb88d4929ccf85f8aee89947ecc33e5187bde373c22ffad2635f163a48bdfeb74841987e7a7d48c5d6c8fa6c60f53e294bbd3af3d4e1e64a148aad5976355f44b6bdbac7b82dfb0047f9f9ceab91a0e65677c81644a5820d8a158da62ce19657e94717057fe67d87fc5d5f6b2db8fcb7f8ef99ee98f08dab80bbb3c1652fb9a51c42aa89ce968458fea9db7f74e6fd50c1d6c7505497629962b747e118cf970948fa1e6bbef069cf4da83324d83f57455dabd3164afd2351bbc473eb080f936a2fde7810632bdce9b41bcdfc7939d5bc6562b074eee4f67b9f6a6d21dae52ffb6d9b39f4616e031573c5b1dc2f23b687933888aed5efdd442492dcd98298b59dbb721bed1e8f6f8883d3d5efb4eaa9f88199b54a3caa85476876d969b2f0adc72754e85d3979c27e55d784e3fdda2874cbb999db4bcf6334c8855f7ac4515aae8e5ff9ff5d8a5e5f34143ddee3fc53a2d07cc7f6c582718c435cd62383bb60d4c54dd07a06d2642c8ca4920d5b7fb7f3f6f2540eabbe385eaa17b4339b8b3cd0806df5737d45fa947bec4c6e766b850f86b81dfb55a5d7137234cd9856b741daef405d134ebbd5336c02663db5f05f6c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 3c3830f043ff31f89ec458368b3ecd2476f03c2b510cd773d66c92cf2c95d88ddd82b54faafc89324ddf48563aa4cc976ae6d2d31c4b4b6c96c605f8a647f31f1b94cc38767b6d8f45affa3f49eb9e6c5f78a87bbf6cc19849ae61aafd845334427f7e7aef41efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ac7ece07276a7854685affeba695953c95f1a07bc8b4264bf1d3403eb8cbcee7e753b6619a53d9599c4ece3f826e76d9d8dd9f977cd2de4e43db7ccfa0fd9366aed757268f4924e445b689a6ecd706d9ffdd8382c74de0f8bdf6ac0fe8ce67f25646da9a4ab2b7acb235f6929b8661dfd5bc414e813e657c95daea36535e97d6a56d8df2dca5cbf9eef1f24ab6e04dd2fd4b619b03ce2c4b57ab6573282e901448b9c0136b1d8fe45b3be020eebb555ab2c058fcaf4aecedd9f6a007858e7a4ed9ece20eaa7e955f75c4a847146c88a468ae23fce73ca7649483f792d9a952178d8389db725ca640ee3ff7c5cf5096b3828b463abadee913c390359c9e4346cecd63b95e7dc593da24e578f2053f33e5999fac5603ab62ea785080bc39e0baf06c98c560597d219746748de5a5668ba5fdb06f45a7385c753a854c4e8e8f78466b5ba4f1fb84b0bad8b5b0cc3104ba8b963eb9033c52fe7c718af8ea3b06ced46da879d9cb3f73b8d7cd978156fe6d8ce3388dd6d964d6329777e275eef38d3c69e984d4f7e9764ccc1307a64a1633e85e6b2c5380c443a9bfad49c91cbaa7bc385b989d1453676ecac1c31f3f05e83ac0295c6e36ae6f0364ce5b35358d37b7379bd2248af8fba3adcf9347abf4cd1afb0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2a4d761e48e665461c03dc2ea8dfac726ad1aa7cda90c5655b9904bce699a2eac4a4ae981b566c70e5016ac84e7964f65cdb5eaf69fd556db9a17686a5f951ef9a04a55926bd482e669bc6b83eaad4465faade338ad544f27ace61841a6cfb0efebfe4b897bccfec03224fb7307ddc0f7b509d684806eba4f2d9269acced25ad721ca6d9e6341687ff928b65447a5aab30765efb7c977a56020b56abfc8f44a6e4df3fbc118369e8abbd20cf989015696140b6a5ca6ddb2fcb5be3c41091a6729d6f547db67307ace4286d689d3fc2388310e1f69915470286433c66f4fefe684a12957d90c8b61fb334bc56cfeccb22a0df0041fa11449310e53fe75037ba429adb55d7fb75af9382336508eb756673adbecd63d13dfbfddf9569c8db185a0ef9de1000cc7b31e8a046483fd975d9b1ef2fb0596aa8a6d9b99ce7303b1c8a43426a6d01167a742fb9374d4a20a8377e8a6495f2eca6fced6b2c680a48ca6c138673fdd9897f4c7325efec536759a773a1e3aab3b335301fbf501a5cb48c33a1f0f6e4cbf5e2f867271e48cd49ad29039519b296cea9bd4953bcf41c5e5439f37e696503f9f83cb4e65355585bf3e5f202664395f3d41543194aa6aa476bb2d2f9f301f648a179e47ce69668e607b4585c544e359aab5c6fdb2caa6e7711dc89208fa914fa880b9c281483ebf0a96ecd9cac3fe3bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b19e78f2883e8c6397c74352ab3fa49468adf75d441a73a2a0e7489fd7a42aa4f1c8366ec7b5a0ba9bdfe83ee9108f5bf5ca839fdbf2f425738f9fb68618d78316af975f696543ed16b4e0530fe64fbae7fa843a5f2f78ce2ffaee688924e57029a8902a13e86bc562f9abfe72b9cf8e578bf29cff5a86b47b4555d51ae512ebc13138d964165f139b7a897de20ca684cec34ced5df552eb3b9063b7d8266735dbebe9adb253c67710e8dd5d2be28e48d85e4dcdc8efcbf4b8c9e196ed304ea79e1b49adad668e4b93130d3986045416be94f0f583812be820ce5f8cb5788cfe4762095bac6e3f51f4351c0de067aed2bd349b70d4d549b75eccee6394b3d62c63e6bcc4a1ff57cdc976950618c7d113f48f4c4cc2087bca854fdf6840aea8f38c26656625e43f0538ca6d88903fbcabe935732b6a5c24372b43844a9efe501f5b07b836b2ed76f7f6f9fd3578132c70776635c50cde4b435ce2f3d1704cf0ec23da25657eb3a4d13924bb8819db1599373c5b7624d59d2f2c3b2e7ea309af5092d5b0eb6ba81c6bdc661ed4b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = a99ba2788679040eeece73ce433c475e3b7e0b3c65921b3c843be42e139fe2de5efe13b7bc46f5187f82f4b9fff5363028adee2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703cb5f1be85af475ec52ac8f006c95fde5779c10ca73866911a4c48088742b9cff4406f9fbeb9f4b7d8968bfa620046ea9c344a45466de00b7bf0e5b78dabb1bad3f78144a94b37e93b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49945de61a939db4f03f9e4fcb2437f92a01367c713806b37cf9264900acd9416b9e5b85cf3efdc41d7e7859dd8e27614f357663c0bb68282cb71d9aee77148a17d3e5b7cdaa9aff35b4a4369e83453097b88d61395db6f431f19a7c94f7a2dbe5eefe3db810bb7444fa307bebf27ad490af566f6ae7885baa8f4b6de1c9432ce0fa15915cbc8d574d0bf3399daed93b95bb1e7a68a798a9b9a6d4dd9fbf1bb84bb2ed9db395dc4b59f1a4ed87e55f4a19dccd037be1bf6f37a6483ae2af1b859bedc7a5a57a46fc03be3f5a446f4997b311be4c744e60c8ae9a375d7876cb4c0dbfbef3bbc5d36f81f15ca5d7654df3d7b20f9b3ebf9ddfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358ebd784a9c7dc25cb706f36ad96784769f77f76dc4923da8ed9377f85394cb9de1d59467ef98eb555956755aa521f7a26f498f3a6a2d2f972358bdb41def54f143042199bb48dad87ad4c1a9aec4fc681676d6152c5950ca8b0b3b86d9916772706f4927963771ae423a5cbca6f9f2494d9183cb5a0d99e22d9e5991c7ec3f5f8850dadd0c355a3f94e7a4962a513b05bff68e31c7d1c4b3fe1fdb8bf6dd812bcb66f0ae0cfe66928dc86d769ca204d95eb4ef4c6eec7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c27d3a0b7b86a79e935834f9916fc5c09f7fd5573e413552a783e45327ec945748e9943429eaec00588742c8c2acbace1fcea290e3830006610e2eb945647180075194ebd1714f60882ef764ccf3718bac9638eced834396cc8d4e0d3d3246641577bd11a59a776dd1215760d92ffef08e9f2d24e6f998c7a9ad80719ae1784d72f3a563a068eb92e5aa24fcd5edadd4d578438313913b176e784cd1e4e3e3659ef3b9db69d9e7c649dfcbfe4f587ffea2dbed65fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9d08e8b938843f78ac68ef8349f37468f8ec06044ad9a15e585c34d33d76cb8ecab0c0886cfea5c725b3014cd48db0b7efe3792c6777a0b94e3481aa0ce5b58228479f90c941517631319415de5feadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f69d3163a9f45d681f0c637a5f53f7fcdcd31cf70e3b78ee4d575a314db71d3d106c6831dbbef2c95e5fa8a6c5477c311f7d23d779365466228aa3d20cfb819c5ee087ec98a8fd946bae9e7bf8a463577214c58bd45f37c33573a75a11dceb5dd8595420cb8809d63bc7f47d88789f50e98a0395c001877cc35a5a527ee346d781bc3588a3d827339c24233747d9b5d96f6a3181fcfd71cb962b7a1974c3ed86cd5a525a21aac83af06c68136cc9bb8b7d85fe6da468d7808d253cbdcd3bf316dc975ed7cd9b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df91e7d842fd93bb3363e0fc7307f7f347ec2c859edd71eab24765fa2665f6135e7d1d66882056903a67fd41735751662566d9a54b3f45d74b46c075c04c7d2ac4bc88f7eb7589d7092dff8b028fe113d5b7c1cab0df3447aa3f19df5390a13d2f9aadae8bc51108c7c3397590f5bf41165414a5f840303606e7ceb98755265cde280a8caeefcf5c18e8840d494bc436279a939d96c6f926da01233afbd576f46359b2c85d97cfe5c37047f32ae86b7bacbf23aabe9b7ab649938b08687a5be734a834d3fb6fa8a8ae80cca4fd0a74c32a76db53dd9daca9ad0c3a6f9ad669973df56a6c7949f7d156bf29269b1e3c94e0d23be1ef3e21e4b638216c5b82fba3ab3e29dd49bf1f93e79de6d1f9fd4865f75654d5df9fc6574b7809a8bc28abdfea0e455a3a7813c195921194756558a6d58eff87adde4dc39a347ca0166f454f589f953837a256cb2ba49f30da7d2cffef91ee09e2a45e28c57e30e354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = f45ade9b79ef0b7e8f02246fc688a248e3c2f387a55c463f0d976afaaf399cd4845d2f516e0b3c8836f5ab6d9b64195c919f5afdfbf901075565ebf563ceed2c07c8d0d9412256fc25a794da3639879a409266d18f84e8b09e608b63ab232d69e32cfac0233e8f73ba8cefb0ac0463c9bc79cb048ae527f95e9ad1d3ee6437088d20168f135c4d63c4e02116da568dd3bcc935c6c97b3869e76807b5637659f1b5bc4b488d4e5657e9f7b37d4fdb5e0efcf31330ad27a7f205907d76e4949bc97f4cee950feed23560670fa5c23f54f43ac1bdafa6269bc5e6a96c31f3dc982d67a613d665ca7b05b7d0c53c56096da1147e505467e96cb33153cedf9b99518d4ca64347f4aa4fe9db1bc834499a01acd2665c650c8cdd237f4bdc0bb852c9523d1a9e5b06570a76e0be1e75a74b869cca729e9ce7ee6ed1d43c8150be8838f840884a4159bac515f7b5a637b703385e608ee5cd187e2964be568f8a33656ef03848975f5d461eaa2fd4d0477f9f54acc768353b811ef01b05d9b69d4e3603abe5c4f6dfb77f213c54b443b7d5ca699839eb56c379ae6fe6066e98bf66e7e58977a059dc308bb5a6873aba8da1365bed26fdb01c3acf332e528ca4ffdc83a9a9b6dd81acd160ed6d2c684194c56a99cf86b32ffea3fb9b19edd3d09e4540dd9940f7722999af0645b67179bb11b35a4cc56c30cec582fe68f29e8983fad0693471f6e33144c642dc5a4c29cdeef514449213a4e4749f0b2c40e7ed6052d6870dbce20cfc54abb5e43d8ba4fdfb946af9c90f99ca2fbe58f11ed03517b9aa8ae306973dec7e3672ae6ba724f45ba96723e3453718a3bdafae2c1b4d0275e02ee9d1b4aeb6b6ec639a99d0eaf67b5f6dd876137122b5f84c05fee998e35287da9e2daf5aa59c7118969469dc549831021aa911948e550765f88976727fee5d3771f1263f883fdc0f1bf88057f6c21fa7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d5edd21633c9744440f0f9a30ade467cca4d67b9e7198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62007df9fdcb625277e4cbdfca04fbc28983b54b7bd37436917eae5608759abbd3e6e8359a26c55e7efe79a74c3926acd2caea7e61ca571dc771e7679e611b9edb3ebef54be1e45f4ea306d1fdab967fc8a23b0b73407738956bf0b76c75ba7ec4c21d5b9c5a3557d57af4ebd36454a22093a571fdbb10038bb3a46a0d9f866d7d7c28b9eb9f6e723154d8dcd3b051f363775842274988350e65888ad27bfb629847b9271a5f67ce5c286537c76c31f62b45e2995f0ab3ddfcaa6bf2883d1deca9b8cfd29515c564d3b970143c29956ceff588e99b8026af343efa523346ebb243faffaf499666f03cc7e2ac8cae4dee489effbd9223c3c65737c20ec0dc6cfbfd83444a29c64d98e2cd69a6900d4d25a6d33f9d3d744abcb688ae66bd371e8eeb187b62e6c755f2f947d828446fb45f30d4fda615b3c5f682f2157e940691ba674571573648cd92257484175f9653845a6944859dc3c62e8cda9da78a4ea492f57386ed3eb0c883d206e5adbccdf53113a174ffd3147edfbf6968047e8a0d393e7cf4e65f0d4a4518f5d8935f7738aa7c7ae22674df3c04e0fa6644dbfff80043c501635550bc76e8348d133a55cd83d01fb3e97c2ad71b03db1f09d8813aa8b898644a9e8c081648188fdf30e448291edaa7beea388f61e9be41d52779f749f7d705d6dd99c7a44afdb1197ba34af951cf805495647347d6019e85a493b59bba67be6eee4dc55a4f458d9c2dd3b90a30aa87874fd83708fecfb01ea4b9088bd41c8d69bcb77853b397ce5e24948722943f0e28c4e896c56f7c9d3984e44d43a4765392bebdc2ef5bc72b27b11ff57d03b8f14eed520dfcb3093b5ac83dd3c615c04f64693f68c0d17cbc34f8cb1fad68d78ec9183e58370d5dcc4f3c0695ad1aad6801847e948bd45e7b78ca7f8cd42e579eb3ee5d7633b22e884ef65095354dfe63891945983d54cea2583ae4b64f54065cb573e273fee49c25eed17e5e93b3dc38c85c5a4e5acf73ce76d9453697a3625a607b2d5204c3d7dc3c92cb24df1a75c671f9e6fcead70567b42a2aa12a2499e36f93da54db664bb8337b6d5497471c1df435c8b4097fab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = b767ff8bd73104745eac93e54707cf81c85377ba36b21ec9505ae8100ec881dd8b55d3d08a9594e75b3f027ae03734d64393351dfa7eb5ab9a1c774a59c47b314370128e6abbb4fb7588dc1ea8769a7bbd1bb6de686c726f2aa6ca2de615dfe3a8147cabf658d65d5aadbf88f065bd31c5b7494b377ffeab739f5fe513c49cdce30cc542aa34abd31b5d99cb8f6e2b9a1c64e7a4ac9c921ee627e6353cb6529bce9698dd5d076bb19789d431f9ce62b3efb8154797583692ec9abf67b679edc204b8f2e228b09bbb7b4cb3a5df788b0a3d841aba9e4f8ce21225dc87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa61df45adbe5b7dbccfabde3327cfb0336b66d2deaa4a9e59a7c875eb6cebe39fd2678f1bc193ced74b04f6e845aa5b1ddc953699cbb7743cd76d930bff38efd943c35cdea8d973a81247d9678f5d1a9b3b2fbc5769c9d5ba883fc357946d54f3cd3d90ee48eb2fa80b4d86dee07c57d2e5f07ecf3aaf8c4abffc9e03ca2daa433fd9c584bf5827949e944a9f5f27786b6ecfde9c5cc093fdfec6defb8ef900c243b1c357c8fd8e4cf87b233c7dce7fd938b56698c26dca893afa877bba4acda906d6e3086ed9ede4be7b4df8db95496865c254ea47aeba1ca7458256aa5aa1d948d4c920e3f712c55cd8546809704c1760c8f8ed991d8ca570cab344188fb6f4d35d83cf4105397cfaa8ad86a385327873b2f8bb1ddf801b5d340c7de5483709ffd3de0483bf08b940c4aab7b6ec24e9947875c8e2ba3ddc208ace485fda5edf53ecbfbfb333a1ec9bdec83f83d435c4d16edf7bd692d09d4c658e17aed7adaab8d69277958458f6ff5c6e4d9f804ea47bc9ad3bde7d7c1a78d912467a83575fe74aa26cd43fefadbe5899210d7c8bc8b669fec5840f5b1782a5a9d947e794deeeff9b12635c9b25e76499a359346ffe5a946fc98c7083bb186dfd87b58b6d7caa359a4f7259a72c6f89fed06f07f2eec050dd9053cbefdafca14ad6d09d9494dff9f82c5b93bfacac8e7d5e35874d0297aa15c7fb28e878c3f459dbd9d6d489671e7700e4731e783c73c86b5b883eae765a63acfdf8c69844559b0763b5cfab7396c1aa09def38228cf9ba34a4899ea39cfb37f22f6cdb35517d354d433dd0c47d9b7cf53bba8d7e2ae7321b38bb29d3f7e5eb3d02036b1a4c61a2a66a3f9eaf4288875719496003988b488d84535cb66a4a1f1ac69a5f8180ce3ffadaaff145780bbdfac41cbebfcc9d798cc4daad90a53eff0fda861b8760ceba5f335cea54e5f568cfb51628455c85517f67baae5c694293c29a684984ac3e7125d1d62e9fa8279bceda4d8aebcf17babe31fbbffe7cf97edf7cd894be83c4e6ee28f306d65d2aa6ff659eead1faa4cf7fa6ccbec5d23aec4a3ceeca36b38618afd0b9f8c4db55ba9e428ae7fa40679ec86fea1719f9d01da41cf63bf0dbb5f23e6a24dfacce5c7c34c67f6b2450f36556bd987b526ad09c77ac7e23355de3aacbde77ab7538eb8bf5d613a3eadeec79e59fd9faf63d0e78d47885c7384b4939d9fbc63ac1bfa4ae455dd3446b396cdbd10e76603ec79649c53463f52f0fb98a05f023f8b2f6ffc8d3eba71ce67a9527d237b7a40823542a8f6637f8cbedceea4dc351fe0e34a0cc7869983a02b5dff3958e445a9dd46df3900b7a3d4eccb66a54628741adcae7da89cef8d83e8f66893bccb50918b6d0ae480b15edd0153fdf6ad562cfc782dca0a02861b87a8aec3d49287e68859d5e1e1ad04f4ae19c3f93fb0850cbba7582fe363598c1384ab228d8720b4c6125efad1a9774d8ae688064fd30dab2f0796fe5536402cce0326c7577a7ec4a6d83e1cf4542ed7c814ad199ade3ab9580abdcd38284588294b743086357e5db01e93d841c6a7c9f9d3239ee48df419b464c3c79f847f7706865a29335a4005ec536a9efcb89dd0df5df699e4d1ca5b438ccda43393510fbcf15a895d5d546851cdfb1d9705188e9e94ecc42ecf79e8b398a563c174c578776d5e23efbe53ab714486588f96b85a9f62d67bbce99eb913d895a5f4355338355598b233aa89e467975afd7f3cae086ccccf836c7e45f898add848b94748788ea2c0f5956bfc748d7d0b489f16c3caddcf6356449fd6515767b87ea21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = e7c99be764d8348f8e457c66edec8e202bd7d8068bdf77e086d6af0beb628685790487707b66be4c7341c654a8119774e9bf62b2f34944898e4285f149039357ce348eda779c5f6da7ac83865e855a4a8af588dc5577f95ede6011f3e77e267948ba7643174391a34c5597b7af7742573f9f2125e8e1a67b2f35898f7edf4a6ddc2b46472987f3004ab77f9b538524a9b97bee5fca8f225cfe258debb726735c4d8323784e9afaafde67db2f5cfbba88bb558d8ee73aae69ba35272ff68e9b44610dd5af4998a6c484475cdd052eef2e1d91d31443ee2447bf7e9e8f4c3a49f9e8eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523bfdd6853b5e0a7d625a6d5e72e78ad6fa602bfbc7bfcbdd2d78b5155b3d2017c90878d3be96fef61ee96eccfaf14bfb0569473ea6f0fbbfc860cf3874bce4b5acdf093df9b563e84c0ec76d8568584759150df6df29e4c17af09dd9da3079e4c347ea6cf68473a431b2886a8ce4da540f834a73359f1de658c9d726fdfe64cf74030cdf1953b11ee6a64168e5d3bfbda1be3e556eec96c8d1db2fb5ae94b68dea940ea4787f4ae507ef90696c3535b8ce7345ea6e48bed37faf5e456904bad30a5fe0494c90b38dc2942682dcacbec8c644e9a36d3278e6a43bf3b96b751afb7b951a87d8e94db48932aa14bf73f9fb06b85f7afb4387e949645c58397ffef7cbffef0e75914b3c932bf5f81ad10568a17abfe72705fde578aab6eaea88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e180afa4b7b8055e6acfad6f42d77e856ff997a6d9b821566acbb381dfab0cff8bd482d4fed0f3ef39ef26b63a7d0397091a9844e23b28f57a0de2d5a520a48a3f5e7276977388b57562fc5b796f7c4253bd38840a7889fa75a7badeedb8f27a3e13bc20aba3ddaeb88af6fb2930338cdda41e087db4e2d92db2ddaeeafb5f67dd718d69b032a45bd677b883f965c8f908b877f5f77446e4aa132d46044067b2119d405efed0133e26475eb3893f137da53cacad865957f5af7ac4d74dfef96702f853bb4b7d767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5d8e471539c42144b4cab5d8d63f85f8c415cd8cfe2e3d296edddcb47b4ffe9d282f6b582a57bd4fe3eb42bd88bb6f4575b355f8c7fc0f34f1f9f4fe7d653692c4f45eec64f9cb145fbae9e789c02a4f1793a4c43856469298b4ec648b21babc0167c04e9da3a8c554df46b80c4d7dfca54d5f68e2dca4e98b9fff38b427115c26aa331625d3a83143714234feeaef829bcb924d6904aaec958e6a3088cab51f956c87862e776320e78457c03ed20957158bb37756dbfbf93a44c079e1f1bcb7c4f68a0dbecb825e512dc63235f700dfd6c989bfa3b254ac75ffc7353fccb14381a1d5897575c877fb7b0464e61a6a8891bccfbeb51fa7ef0107cce8ea5d803bfc0475da1f264aba82e541897538278bbac29b7409ee940a47249035b05ddd23084bf588d6d51ead3606cdab0e6a6b65cab53dbf6425666dd1b59741886431ec6bec492d4577bc127369af391f8ec72c543d2e06de3c2c7c62d364b365d8219749f131b7e289fcb206a9abe3cf1a565bf06cea7f8995c89549aa42fdffd83cc7a8b8a95bac3e7eaba48b57f568f9f05cbf65cbbb8b0b7983f86e8f36eeb3fe3ce9a0b735f3ceacd189f9115a1f1933ce19a8535958cbb8f464ed9829bc9a0c24d5266f697d65ef8cc3ecbd5b95c7284dfe27fe99a8fe0512a734323de7eedd556948abc7cddbe2e5e9db44a2e8dc5606b930c6c8b959d81bb453462bfe026943929d3bdd3c942f8a5eab0fd4277efe86dcd52b6f67e84d5aa6cedc67ad74aace945ddd7c4b85f48a0854593e8b27ea7e895b58c08f8e07214afea3aa1b42ae7cb2fefb93d8eea899e8dfd4f7e884cd40746f31d6a86164489ccc2105f6154f6e3c565a282d5742f4953e963c42e878ab4d6668cb9c15f96f9f537cdaa078db43e91ee38ea46ebc2a3036639e5cb1c3de385cff2af46873e1c946448e25f16dafd4734e21794a8da3d7b266c4125b60c9c48019e874ae9c242f550898a30281380fa45fc0d4466296af4663e81e1ef92ae099abed3f75f8a89f22c983c9ad875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = cf76c08745bcb7dbfc3478823c977ba1f3565d98dd8e83e337d798fd273bee3ad3416cb6d11774e0b7c178ef3a61a5d9e04c334e486f97a963036cf9520af96d9ed8a3fa6858cd80086e431866d3ef58dc7fae35c76497ac2a4ea1c65c535385bb233c55bd326e4e5d2c0ecb0fb6db969bcfd5578921ad665939eb59f5e0054eb0e535b46294680627646c15fd144d4e4877e3fc56d72705d777e48e64275e4e2b33db2f5686e9f0951f77caea4d8f4a7c7b96b151b36836a76671d9d10cc7546ee3d1866a694114e6964da86214e5037654a55ab132d56590663c22cf67b95aff1a26fbd628d8513cfe7c77e24724fc3cc54622697edc5d5148a5f76efcc21ccdfd45c79a4549a501e7985946e457047aba38df92ce3557dd6096ae3ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a58fafe97b508304b6140ca9da2c33f275f2d51363663adc437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fe9f7c2f4fd7cc77cc127790ff2634cd3ff0ae1dee39ec393c5c5b55a8e93e6f8417b7bf609d3e9274c2a1a38f72db99e5cfaecd8b5b5b445d3d259058bfb3ac1b3a0657c2dffb6c75c93b20ec335828df9d1f4fdac8a64d2b73ce78e9bd2dd5612e51f7e4c804bc89a81797ca93e36519e0c8bfa36bdfa690e3af7a99cb2cbd9cb1eaca099ebc69d989cc8ff0faa362644fcd33438877799836cf782413a9f1daf9861752f294b7e4cfa39816e8d064da5d0ddd01943dba2dbb4693436d3b7436593e7b9a83ce2ecbdc79f956cb3f7a17c41f46af94cbe5059b8661349248235adf68b69d9944f203e093173ffda657c9e7f2d16fec13bf790e33dafb49496aa3dc46b6fa4d9cf6601a4e783b73c2a4657234d1769365719681c5086d8a7bbcfff451e59bfcf32b363d6dee978971d8c5ac704eb458693c711765c70cebd83e9f358ea68bc456eeecd4fca898b0b3ab5aae4b80aec148b6b79245fe7cdbe456a86a5a0377ff98c08bcdbc4c997b047dbaa76950bd0874f9478e6c8e50770c4ef2885e89eee9126492c09b8e942ed6174d6e6bc7ab46ccb0b47587c0eaec558f8f98a4edaf5e5d27a3d8302b672cbedffa07493a5f69f5c5a0368e799eb3b60fd53355b3690e0cfa1c3b77aec797fd09b1cccc8d5bdb8b4dcce8858cf8ecf86ba3a654b8a351d0174df4ea4d804e59667de0f15e462a3c4989ef8e74c39cddb557566b7c757874d916efa5f85693daf1259ff891a4a0b0cdd0a38875233f6dbdf4a54e95ecc775405938bdbbd39371ddeba11db8b3785e398da5457d546c6e7ad86bc984b7dde844a510e6a14e34ef18c765fd04c2006c6781ec90caee6881b7bc4557945d68a4543a5f16968b39f38e8f5aa76a9e71d8567e35da662087aecea63aed3d94bb4c88f08432b86780248fe8b0dffec78c96322a81b816d719fb6743cf90ecd8664fd378a95341f3d3f6da9fb3b84e7c5f543249d57475b3b526b93307664217b8837c1c48ee73f2df99ecbf6943fdd445f2da71f8ac449d7e8e851fcbe0ccfefbf6d1ad08af68b48f7d2677dced5914d9b1629b6cfb69a9f44ad5b6fa560143a4602e405b25983115b5383e5964b3525127e58013a434785fa13b30341e48f028a2e4ef99c9969fbbb9e7cc27b8528f3630bbb930bbf336b59d1f0d60e84f30d7ad399087ace16894d1f4f36f3b9b708645a4bf7378a86c960bb03818df93e66bd1bcc3e57739591c386c45846cecbfc90ab3fe5d6ec51cdd0ec9a2422cbacacac1806f472b4ac6ccc645d49bd283a6c62136a60e6f354a983d4ceb74eddbaae587e1bd958615fd54336a38630535f0dcbdb09e8e5dfac711093975df987edee09ce7bf7429cfddda9e1836e72124f54dedbc526ab358e359c35cba02f7f0c57eedc28ef2b8cbd2702a962db3470f3f620e7ff91ad8c9db86615e9ab48df3aefdb4d0408e5a1157640e765afb35f7b2c532011ca07f4fe673d7f1c303fb2613394f68b688ad42725cd207cc3b87675ab51a60b50efe313adfb5443cd15e8b1f9788fef9a3686ff91647c234d49daf4a6a4b04f1ea9d307f676271a47cfdc681836dda93d9e4ea348dbd544b3163780a3cf37338fe319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 2f2f5b33d590a3bc60ff43ef856884594944a1055f1ac6bbd5f7bbe0c7b5363c984e4d8b493b92bdafa9395b7dd9a46c17b6329773f4216e79bf05406f6f9f86875574dd5b0599b561dc5ee8f54a7379db5c3b414fcb7aade872a9489a564dd25b54fc9415fd5e99fcb47b7c7585547b7fa9e3a3cda629aef1876c96c479063c49e94b952c08eaaf8b3bc39995d4563337bbcd41ace7c4f5696b7dd2cbc6b760e344a7fc49c3ddc0ee5fb54f26d41e5c4ecf34f6442b9d59fcd5882e90a80b4f3423e2f91b7737cc77696acc5e13f3e13ed05645e9ae4dd2fb95b0591aa126b7decc7d8143c7a502c53a77b8fae915b25be77c690d6f4cdbd252463dd668537c24bf4c0d39cac4a4e6b3c19ad37301b595c504909d8a4b8a07ed10cfc906ef6b5317703c3e95722d70b0d5677be5e01c4baf9186582a8b70d163ab01d6e51177b7c83b6cca2bbf62f6abf04ec6ad6764cd8392819a85cad945ecefe0bacd8f1333a394be44a488fe683ca2c73c58760fdeebe3ab59c8393f7caf4328a57628e9756dd97d35de9a87f66d15cbd7b3867dc49c0e83c77185e3bdb8f35e8b89feed6cef24e3ee1ade42d8e4b4da9d0b0c5961f73e90c57c1dd6e4de43c3971e8979cba71453e6607bb82e5451e9475c0cd4e27c58a69fc47e700fa3fbbad3949a9760573b2bd3c66073f5c57af3cf4aadd90f4bfaeed2043fcba28c7fef7edd45674e1738ee0488f2139bd4df69ce9f1eaa644c47fffc688ba4b6c92bd1e2747d2765b7d9579485a37e719daeae19ae2773cb4dce7b998c9d25955a34ada9c58ee7fba45f037eef1fb59d415a93afef6a2e57f6e50c457c79f766d55477546785f76a2ab7c5ab983a9087e834da4016a755a214dee3f6a24145cd308f7729bc74b17bc9213f548b663f50c3d7ad6eec48ef4e4ac4957e65fc476f915074373d83b34f468bd76d91b984692de3f66943fb0527b0a0bb3df41556aee9693eaacf97047516b6aa4563e1cfa7e35b697e7eaafe147756e80bdc657b41a645ffe7ae7f4b13eefe17926b7757fa74831257ce255fd66d6f4bdc1d6d343db99d83de7ebced1528348156352e2664762d4c6e13b5dc06b25a6d97c1da6bb2e3ee139c34f83fa70ccd9afd6a8e980dbb20fc78e30be6eba8b2eca7bda15d8b1d9cdc9393557f6f836127f1a0dff01c79346949c53d94e4c7e673116f34e98cc1508c81317450670ca7de957bfeaab0e688dfbd755eeb08a441f983e3d8e468a7bfccbe52bf6a581bade565ffcc6bce3423d3fdad054e02e6509725bf146d5f6479f2bcf84fcb4b456c7ca25457415d7f75ba54ae8c57e7158af9a0ae8b49fa6be756df8427516649440d5cddd438e4b8c4692e7eb7b7ddd49473472f1dfa5349fd183b4ab70b6582557f8fdd67eeccd0b77db517433466ec6b2f967ec28fdb8c68c41d39f3fae5c4285c63b03a84179f6b93496dd57b6e242be4f2576e7baaf8077bfdcb9cff485e52a5fa7ec98c952a263cfd3fe282d57bf329a0dbeef2046a7539a5d7584f89a29ff6afb9dce4e7f35ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fd8e7899375f99d470248d04cc7520bf5efec8f91cb8bc3378e3dd14a7bb25bfb8b8b425a969c4f5edac4876787f67ecc6e409885518e0533884c61407da22997b0b8dbee2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db96e4024778225b92d68f6e1bcca7815dde79c4fe0fa3baacc5825b0ce045cbc485d69c024ca504a975ada9a5a92fcc0d1ecb3fbabc65dd7db6133a7faef23c3658725686ceab91eb84d60cdd39cf1488376660225b42db54eddbd437d5193bfe777b365e3ac8d85e6da433faec55fe969fd3865eb904558abd9769b4ec963596cf8df38cf7b408bd96ea546fd6fe41ddd54ec10eb76cf634881f40d9f82f7705e63e84a6a5d4ea3ce9d8ea6fc5b8898ebe4f87fb2c97a18edb448c4ec93cc5ef27e9c91b92ae77b35dff6283a6e60f0bc3274dd3e2e89244fd73726a657b2386184ee5b778cfc94fc67a4b71d5276a934aa94e9fb452286a369e3b036faf2b5dd7643adb04f76ce58a31bc776d6f1b896628de2f0df7763a8751aae0b8049d799a8a3d038d5bf3eeccd567665d482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 6806cbeebdc2c364c98989815ef9d81d23f427943a0aebdda7197cc753d757f3868c49c045d39c8c085666de3bee8f5fd7cac7fc6933adf438a4cb6849c9ea1c737d394c5e08649d88f9f74009c4375a4fad5be6495e540e43ac603ab6f488628fe7f72cce981cad3121c3a22e587ef30a793cad97d27dd25fceb629a348fb8b854b64e39d5b6af09a7515ac4ba457c829aed8c7d3e6c069a8e454a8d1084505cfa4e04cda321681d168933f0d62c0ee635de39ec8c9aa2a5a48984cebc34798fc74e14c18ae78fe3408f753db6dcb892c52f91ec8382b3c455c4c0f18f48b07f88b9b4b927580a3f5d930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c235f9ed6e343537944bcd7cc6aeae713ca8fcba73daa688c9ca369e8b8d99fb812489482b7f7d40c7aaa639df513fab8fb5b09ae4985d7558b8c55b9f0accb388eb9b34d5f12cd5e99cb37249f2d0da4963e6848773e723cdcc643b3920b8c2ac34b54e77c1fc748c97ce86b3a543a0afb3b3eea75b16357f3fe0da4b3fb72d407c4cb78f28e78f2b6c4706b61afe8dc0863c72794434978d20933fc89e938a4d41183660f0437a2f3d9eee87bf539afb8c76728348f0805bc2cbda61e9fd4b7839b1493372759aaed528980f0f726eba91459eb7327d99225e35175c41986858fb3ecfb689a865375e8547932899867b9871681e5031f5b4dd263f044e395f1e76bff3a69fc9b9c12dac8515af5e665a15f48a3ccaec4a96390ad7795f7695e664f7990fc46275bab1f3ffb82ee619c55c8787cc0124df10cd3fcaf4b6df9877e1ff4972fd6749bb343e1a5faafb66a75b4889aec63f593bbf49d6c334d83f737a39247ca22df79a677736e77eefd3b08f645101ef49461657db0db365a58beeb48de3f96b6797850129e45975388ab4c9036fe5dd5bda0fcd66c8a7a5930cdb1cb9f1c3c54659e4dfdfaaa4f63a6b0d55a761e9a57843617ad6963087396b0e87bdf593da9dd9bb8f5d056bab8e3b6ad5eb31b4fe95a2c9b7d09f81c176b58346cdc24c580f33e31213a08c4cc1c776c146893e8cd44983ccd1494793039ff5f226ef916b888d9f3c8d3dc43d4ec1a3eeff18a4918216771cb992ff1abdbb33aa5f363e6dcd44a0d68e6b36785a5e566e4a666af6cf9e4ff2fa17566966c734a364ce14933ebdd305a3db47ecee977b88e338f9656ec302c35f3e53fe5e1ef43685c177eeb6877bd3e44ece0a1c52f03f966d77d04cb4abad9cc8a534b728db8c339eef7f7e556beb656d77375afd4a71f434148d5c1334385e396e8c1f82269f997704edf77645056d707e1cf47a8dac42c69cb74eaf3cb36724d5705af745975e81312a91ab1ddb42c8f670a9aea43ac26a5cb3ebfbbdafe4f25545f55609c3a8dd4332e6c816fb68e5bcd5da04fd95c78f6db76214ad83b3237b4665b9ede88c1bf53b4483d05d56f7bfffecf225bd35eb728a3f543956ca142b4f3614816d99e896be4f0d28ba37df98d77e380928d622deb12ebabcf13faac679eb22cb9013d8a8dfe7dba138ea78ff37fa3e8b44dd43f193cf9f2dd4ceaf6f532ababca3528c79f00624b613fba988bccc73288b7996c2df0d8f22755adf9e8784f7ae2f69ace7ed8e0cd5f8e3bcc85403967ebdfcf1463c7797655556dbba38f4af19f3f2dc4336ab44d54ca06594e7f8fb5755f397fdbeee07759c5ba86accbcee315f3349168ef384df59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d3885fc435cce3cb9b17608601a1e3ad638cf3426970efdd13624313ff57ac83befeb34e95028b1b65bbcbd5c4ef3b6d1171f5b368d743cdae6ca9abe8feceec1dafe4e7e7a0eaca0fbcabf74034b7449ed8d9668199ae4e559eec817701733be7bcee635e4a1e7aedf3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b676ae660b7c22ede947cbf4f1ebc8b23bead1c8e600b545f74dad76e468514cda483466089ececd719dc4c66f3b02b7825dfba1894c4e31df22bf867911c89d3264b5a18ed754ea2f47f9cff5ed6a89df37e17983a3f3f98cd4979887c4d2f3f23b8eaf875a33dff8cbf75722ac9f308d3f0d336f5ed3f6734a532333c8b1ab4767bcb68295d75072dc402878103056cfab5417354bd3a5d84f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = 2e63e7c30e7a6cf7d7b079cb57ad6e388b924ea6f54d26c853733b516fd224bc51798578c4c53bc92552e8b4fa071369932e3a6773d56b0f5106255f57e4670a6a4262445aa745a916a9b629ea64ac757187de36ff4dec6226992129b494ddc2d635b5187cc2359cbbf235a90fbf4f7feb5137f4e57fed822b0cc1762ce8c26be8f757392863c24a13ce6dc84e3c28aaff0e8acc1b338a27746adbf2f687af1e693df043625c63805ae4fb9a368f14fe9014b456c88f36fff57c7eefb96e8af224eddd9eb8973bbd4c67f3b03e8cc1cecc791203399a2deb37ec643605c0d71ce161a6cebd6ef38095ef6a834de773ebbf47adea0bc17a6478f22fc8bf3d9805df99564e558d688b9e18dc22bb3494f43c1b2adc874bb4d5246689afbe22159a5625eac2e6385b1384d0c635ecc94b80bb8276f435a64883ec05ed44fd66d58ecdb6bfe48548dca2874a38b39a692ce2d983cdfee953031f439d154df82ed6e2854222454c20736f6daa41e9c949952fd5d84a7b583db95ce3f51c186dd98bed4ed3f9521bbdb3394c819a984f87a7b3a9fd1d578b5e57ccc3dae51a9f395cc6695ecca7ab67806f3cfc0ef46a6cddfc2b0ae8a8ec41caf87f49ae46f2345b7a185baa1379881bd0d0044f91efa148186cbf474bab0330b90dfac738d2f2be698bbe58e5d8e343d34cb20f55dcdeb9b6265d4c4a3b1905a651cf9ad02fab6929a0d95357bc76983b3de728bea0f7c8464eefbc0da3a48b8eb339ae855a759f764639d9e730644ea96b9aa52994bdae7eca3ecadcd695a702adca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d38fb73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1dad454a33bdee7aa81afac17fc709167843177f08837594eb8a47beea38cf8e9c4ba7dc56fedf63fc0a6eaa5ccfc37e1f76e6fefda1725e39d9a41e2fb46cd6cdb3bfaf5f61ae2032faa07ee5504f4e88116ade345d7a26b927e1dbed839577d2641b965de1fafe932185467b8c2856a430fdf8275daa37b166e035d73fb5e3a0c95f091555b0e19a2c8e858c1584e229c6bd2bab500fcd32abb4b8028b90e4bf4feaa3fe208f7efb574a786c3bcba9829e49ba73e8b2b24cca13ec636c863f224619d04da4abd8ffee535a25c7187b9ffb62f376cc3dd4fdc7ea9368594cc53921c857f8aed9ea5f8a9cb817f4f3d25f791b4dbee95e7b3e6dc406c83c9140385183d73f7bcf3d69c6aafaa6cf82862fe05a40a6fe1753f8539b6a907f34d553aa77a8dc9f4959c329c563d9cd3920b98563c5f14bdf31eec58887fe0a5a78f1b43c1fb8b4491de8c16687065939535363ab88397e51760ac356c69f7b25468e83b1da0310363f31c5c17fe898d06701824565b6e5ffc33ff345e3faf2fb6ba0af3178be42ff88191bfd7b4eb5edd4bab67185ab0c9b8acbcfb37bcf108bbd9f96461a4fd79c4dde8c7cd58d38d9f1346889e17cc488cb645c698ad37300854e56487f8c31e6e013767b37bb5141ddfeb359b851d5bef19cc7dda7abcecafcbba381cbd727c8554bbbcfd43ce8bef57efce337e2fb99d69a9a550be4a1bc6856dd56a0213e7c4a57e315cbbc47ecd674adb0929f09f23619a0d68f067db531bd679fde032ac6f96dfd2175ea115abdb221545134c500d857c7cadaab92cab5c5f98c1b7b8ad588d0d53860f0563ad9c309b1fa82b14486b1db79d7b6d38bbb03d9bb49db4c9071dbcde5c383d4e808805efda6a99e386af8e28d2d84b6d7f236105cf526d577adeaa8dd1c468d91fcbdce44b04d64ad2938fc6495fc0a84e62f5d6ea548a8f5930c13fb59e54aa54598f9653a118c5c83edd7f1b83d61d1fe95436b6a673d1bedfe953eba0e0e351e026d5da9e9956968601549abd9ccc9d284b3943c666cb8bf9dfe1305fa5c7336920dfd03c5b6eb8589d9594b8c92c4c4c6abc2e6bfbb77d78f81849e5b6760dbe391b9c5a57f8705eb6ef2cc475f1f3a45a3adb12bb976b2874cbfb4f7266b6e2ffde6c2c490bab8daa779f0109be1a76fc996de6c483a71e636156186471a9ae452bb973fcf8bc135133e9744cec8b331cd75255ec6944b7a304a250595d86b394c686fd104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = e4783db3d78352ceeb01ef92ab64f5ac8ee0a6847a7fcaf9c34f41999ac07fa77b461841c135e9e93886365e3837dca2a51434bb03bc43e89e9b73362cfc5f060d7428c6c9637e674a574f64e5ecb579345469dfe9e4f728c5c51858b2c5554b143acce3eea9a4238cc9b88b1277de884b743168c967574f1fdeb700d5dce9f84d32bbecd1e85a3b3ea32487dec95ea2df7d805497a27148cb66249f8ba7796d0fcfd56f823dd9d20f997114ea75861eb5daa832fb6b4d06fedfd9f53d0837a5edecd5add9aaf668b87af55516b63a82bc64147bf1290763f47bd0a6ec3cfe7ec703af8719fcce1f2afb7e1f4a4ec8703d63865974d36a37f74d8d6ea1ab9067e5bb6d1766faf4b58fdd5cca5c6688a86a60afe6cb7e87423cb9d453825404448cc7f90a5bae8848c41ba4cad23d894cb385f699e6d3a5ab6fbd45522ba80d1e546726e7b0af5e15734c5f5d51f1f3e7366f899873ba90d670d644ae429f351c1d8f861ec89ecfc16345e6b0a850a0345d46465bd058999feff7c8cb8f036f5f4f0570a72a77fc1e71aa577eb0239bcc2cbd00d8fed1baa91a9fae4283be56094be2bb4c9f16f3fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf31bd9017e6417ae52be54946aebbd7ab8cc2cf535321a57cda44cd44d60f86ca49693da1675fa89dd69802c59fa0fcf08e9eafcb8fbb5b3aae6b4af650a3d7f6adcebc8ce64afa7c8ed7c5a0cc9b18ab566a8d87dc65b2b0e4b8f0daf240397d9dddc7454380efe497293327c8ecec6e43154e97b93d9695e2ec80706f2576835e5b79f42d777230c8dffe7fcf42ad5fbf5e76538dbc6d3928d1e66a6838e33b4db828f6be34685203c7041599c14a84d3effa04464d95724e545b465f03579167cadd8a93d84ad3f7a1e406b06e4562bb6a9863e80d886709978cdb75037b36a61fd73ffba561fd87f6fbce7d04b3233f797e1aef21114c78e794b9b9d73bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372777d60ec6951809848ef7cffae9aadeb3e4d57780599cc3e55a8b0b04810e5b3a2cd9cae6e7f9e4d994c5df96f3bd7dfc97596f8aa4636c70863ca5212db1c22cd74838a4ac0360f98e54c8e8ad820c3778275b966a3568b36b3f44a50b0e9a8d588849cb39de8e3d5ca890556dbcebf94efad35a3a2ca588eb4fdf999e779bf4c51f59f198c20c2e9aa7ce7151add00f54d7a82e7ff5645f8483a408facfe24b368e9d42eca9bc803b9d081fb21ee360480e6e5559b5d9bb6e046a63bb3fa9537380ea73a22b76fee99fa62af4b2711af920a36f184dbb55b367014f62883f9e4f3b63acc77d6f6a94412af6133e6da5c6e28836d5aa3da001ce8dfb6331fa0d5427d63bd5c66bb0b4c496c6d71cfcc8df3c4b350bb252e9f0b9ab3f7349fb3a6682ec3ffc10bd65977b93c9de33fc17f49f7ada48de9fd98dff6d6e8d2c27ddba4c65318ced0cbe88a09c9c4ea7f1300dd5d9477fc37cea25f3c725a7982146c4f4efdb0b07356fc8bd18289f860bb8844d78d7d4813da9bcc2d3746f0b93887dd089ff77f9f747a996fbe9a851cbffe9258be90d9ec17daeddd93e5a107967fd6e9c20093ddd6532b7ad96839bebe3263f314c42a8f4b8b71586e0af79550ca54d87a1bd46b8d9c7586118d294e9a084f3970e2e7610299aa8fc58157eea40ccd1d8e6dab7878ec6cd460c9e6dcc183f826888d1ad3a89dc3e27569b2a7a461ad847b07f86b01ea7c8ad7ed8c3aa77cfd9d98c7aa72a5c3049be1407f4c216ffcaa6dc299f5e662e534f855f3fec405403f3496ee37bde8c4ef959e47c8134c86357fd9b836d6a6a1e6b5d67fa7d4da6a40db68a8fed37f8d1499feaa759d2c0d3d331664a65976c29f8d035ddd447245fef8a3a3dac44825bf10a4bd4f3b7af5b8f4632fcc5ebb45948ec3cba7e607ee94ffca362cb6dcd6e895c9badce699570bcc4cab993f639dff69dd9b43f98dd505d7768e4986d85814929afe59de0091d390033d956193e736fa0af2a6036f4cb85c581a6eef56cf78c1657598cfec4603d48f3fcb0a37ab971e3df801f4e776fb171b5d70cbe4a751bf6afabd20b9f9fd8bfb244d5945e58b5bb64b2f60b729659ed0ad3ebc7ad46c7aa3a1738b8564cf34d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 44bb41c40e705fef32e0a6bdc2e4c6bc55958859a5b0dfb8306dfe88a746a30e79fce6dfe0276a00bff8291f954357ec7d7fdfbac4edb59e73ae5ae44edae73b23899a99785a35e48e6c92e6b5b3222ca7eb3bcddf75d8c5be9a049e43b9d87aafc77ae816f7cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861da6df56484802a7b479b67a803fba87e9e6d0918bde0973ba4ffc0229cddede3d2c6fbc9366c4eb718f3469fcae1f3c58499cd1786f1731738f0d8573b63d18ce88676ecaacf7e9064aedaa4dd8b14afca2e64afabe5fa30abfe0a849f3547e09518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98abcf3f489b85aabe8245649e8ec3bb8397c4125864d8695752e942437b315c7f86685f79df55cde6efdaefab94b20e5030d4dde0735473fdfaec69d27c8caf0074b0fff4bfa22f67a3a5bc6a48d632436041cac79243da4ed58538aee4b74ebac7ccaa534a3863c5f391efe73e4474299c8e1a2571c0ffe5c72bed24ce43699f6a2d0944a20fdcbc536c84b7c8218b3937946cb237e34e35c3708ec73d6433d459fcbe9bb1631787387ee5f6f9c3e5b76e849ef4957e9b6033edcd4e82c3e8a3e32ef2106b9036d6f75563eb6c5572cda5647746b9fe74f86d395cfb759cb04e36466937b80e46cba9d10a04d98aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cc9d7022bcc736e7cfb7bcce57988ca4c3d60e94d12c34589fe73473a5d0929b5bdbd9cd809e634e7bea69457663888a0bf9c2084d58a0d587fd8889c89593cc5e86fcad7bd1d3f4196a7063ba5c52f9170f8830e254862457adeca7219f73f211e30719b39e0b848467d9f2cac7adfc6db26658ea9137a941bead8ca7966ecec0e64deff9999822b5e69f58134adfad47d43469e4e17b3da96d6a879f3f0ccdb91f9f7c68f683c0063f449f5420e8444e5ddedf9cfd3e393f7e576e30c164d91cbe4bec93b6eb4419b2fc744fa9d92e861ae7bb1397ff8813d551aa43bc408da817675291af413f7ec9d29578d06eabe496061f7307248ba88d9a322648f96aaffbf0d5d9f895264887898dcda8b35cfd0ab7afc594c987e536677571c9e88d3b5411ae450a5a75e6dfacd813ca906be3f0b6fe53d0793c908b2d74eb00c3a483293399d1be57aef8f240393e13c86e12fef1dba46fbfc9a5d16fc1ef670e01c4b6b7a80957dad1507f6b80849a0ac6f547dc1c96a309ff964dd1a9db30e6b189a61311cc82dd652328596d7afaab35a8020094ff7438064a7801a15d091ae8e9e5cfb34ce4cd1f97b518ac9f4eb9a1156c816e6ce01e6d5358eb57b1787bc9f5faf63efdccaebe23570dccac4313ce48e7833162c6219835ce3eaf3b2de49e43492909ed577c37d044db6bbb45945d789f6cca8fe6ff6a4cd66595399ee696fbf3df5701669454a83e326f535e5eb122e6affa7bf5d6fa62d696d463f95489eab088ba84208a7dfe76b3396eba6d6b51de3f20067d0b38c8e4973c935fefc374c3c87cd99fc4fb2dad468a98de418efb5ea0fb674b759a0f8366a4cd0be49b43c39a016288a138fc9674ce204a73fe2b45e90baf732a46abf8496cac3ec52066052684d079ce926d374da14ebee98939b4a597c2e664528d1cf89cac513a3d099dc3173e50a54734b7960bf67d1f837af59e9a4c73eca49768829ecc6d34ef2be873234e8f520a4d0c883cb47db7b61beb1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342b4e98366a8bdaccdab8349f9b9aef229ce46d4818cfe88338aab495fdb9acce3eeb990eb4eccca136fe6a3c3827bb40c33c1c749620dc3fdbd7730444dfb8b2b52df8f910ba96ee54df83fe5ef17c38bd1734b4aa353345777ffbce7797683ae6d3cde78c51dc45403e975150e5feea5d215b7366d76b29a8dc79e07f86239e9b59931e9a78ff6977d9e49c8db0e3a2a2d827b2e988b7e3e8a378c3db9c90b9af704ef961b246a5d867dd98692cc7dd93e6e7fd9493edfef820cbd81b3bec3c9e6941817b408255a0ddd9eb8aa43c8df98955bfa9235daac1864d1086fd7338adf3ea36f7564263d3a51cceac709f1a79f73ab1eb7f087d00f9ba015035dfba6e59d38f82bd996039db9fd5ea79be9888d73732a9de428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = c6e762e7efc322cb783f069a7e5594cd26a0914b3104b87319dd489a63ab263c88d66ea4c8fb9a77d7fec2c9e7f685333d6e989a4b3995d7458a4dd689df512943ae79335dc0bdc52dde4b17cd85d61d9186a6d87d2ac47437c0294b8626a65f1e373d1abde07eed5321aaf2bd19d7ba19b4e83f6f765989eb7ee7425e356f04585cb89ba9dd5a9a8d8283b550c8a3816ecaf1346fb5cec5773e25fd14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43eb3fd74bf46f253ae25d37400675d9c48ccc347abdaf436154aeedb0eee4555964c49ba9e36d5213dc8a72ad5e37c3d5fa2fa4e9a3b31e973e1abe61bd4f95d39d535dbb8b6b359855e8e1615ce4a408c34926be280d418139998e356acd5b85281b61b0c78734bdaee6aeca99b56737c669d535b276c5546ab7f673c5344fcc7923f69a0ada7096d75e81f3fe0a8644ad73a4e8de9b3be97ea3d773be94f59786e818275cbb8aaca22d6fa41686613986ddf3794994fba184ee823fe75948e5c82ca7b583513938931b0bc829aa55d85a32b79ff013244f2a3bce1589e620e6cbc96b8556ddc77705c7cf996292cb5592e490d6243bfadac9dae7f70b1f5e14faa8f8c3f1cc6c9e3b34d7000340702a4c98bde89febc47e5baf51dcd60af7cbf48642d479e1e0889eace6bff53ca18abed36ba9491268fb0f8b679a3b6ebdc3eb7bba4f9c4c34915fc4b945fd45e68463c865ab43e884a8fc05f3a1fd88d81d946a71d984897d41a0e894f69955012333640f7a3b7c321dc4a21d8463c9369abec4826f19d603aaea83cb59cac584d7c6426d9e767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444de5fb236d4cd2c26cfe3acecc94fecf7156867b37f85188abea7a0415dddbf4830ed1835b2d47a6b8991451a788a1fdead45451f4662310fb31839c557bff38223db7689cc92cab282be64dd237358ae95f4688f8f385f8f45a3253fbc239adc7f78324bd5b9e73aace549ed61ff8dde06ef4e2c493c136b752f9edda96c2207e054435c634d747d963e577bfaebbdbff30d9ba0f34b66cfa35c7f477f36c915dd48545c513ae6ef9658f9a78bcccec39d2db38497bfd9afd760f1b5e654e3e25de4fc3fee3353f93e0114469c2abdf889d50cd9466b56d6251e58a60b3500efa89578e5419b9fe843913e2fb93d7f83805ba3098a52bc16bfdabf7c29155a22c99eda56530a69964476d65ccaa448be3c4d9ee5adcc6285d947aafae378a76e163556c18459b1ac905abc9b3affee12486a5e56a228395094be50fd65dfeafab0957df67296de5c84f40ad7d5f269d3e70667968435a4dc3e24dbc77ea8d6ee94436dfddb11bac776b46bd85a94635cea3b09ef5388ef043e8aee5ed11a49df48e5b7e2866d11783c7b9598839fefd4745a2fb3bf1e87756008ba1103a508a584a339da4aa478401da9e62a73f12add18f9b8e3b6d8a593e7f3d3909a5a622bbbb09c5f350a7a681e2a63f035d4aec572338e55f78ed0b643ef38835fd56361fee46b903ccb021af998d651bd2cc023feb4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f432590267f4ac1ad5e9de54257859858685cd70fbdeedde047fb903416a2e2d770aabcce256d903feb40274354b2f7d5122ef4887b331ccae0674cdd2adad27a2c6ccb95c701568c20346ec747a29eed9ff74eefc27f910f5ed31b95330e34debfffd26058d47e03c6deaaf9406de604d3c7ce57a715ebdaa91a615133d732fdff467477d04a5aadabfb8176a1f056c3140bb1454cc7ffe380cfa7e39f58d0fc4b740b2f520a4bfa883dcaf5e758045fb936ab9eafe3cbebaa87fdc771b0e7d4e455b8153c4b6cdc780ed4e5ac83f6bf9edc63669a803da139ae87108880b5ab97266af158f542c388f8c80b4bffb474ac27c6513bc54f0897ccd9948dd3c7906dc4cae733aca6caf41b9ca815ff25e58e795f6ac8eb30afa960a04a322c68fe5ecbf86accc226ae87a074877d2e329856343c587e7ab6b09c44f7091655f45ef7e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860dae7a64ddb154c9941dacf19c0a7c993ee4fc0c85483639a1fd47a217a148346fc844c44f47f70e775c5cb4e4ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 4eb491efebe988b9794acaec0e4f326e9a797c77e81995999b1d53b4aeae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f2649e6041ba9ecffb86f2eb127c5951d87d9fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4e5dfba956ab9b881ef55a6469e99c2987162774f573599ee0b6b001cba6bb5302eff4ea17ffd40efa7dc1fa063e5f8baea6dec8a97c01fa61259d10ec7d56ec5a9573c77b848a6c60ce4c17d450929d54c05be006a40378d94785d32efdb98e087991d76a7049f4528fcd5ef5dbc57efd6895552cbf4999c6a7617ea35652c8d5d0ff690bb9fd06faa0e055805279401bfc9522cabe1853e06e6965c5e7cd04538d8fd83e27b95c2abd73bee3cad4fbeb54933759eb88c877af9aedbf8659fb203da442460ee93a0344ca83c58c1840c95ea58fc8148dbae24c01c763b2cbd5b369bbf074c8e96bcfb5b73920bed7318057a643640fd58c6922d9b08c9b5cbe972ae0dd2e9dddfe85363144ec8a634cc52c7775489da664dce9595f90baf43231332d7ec3162bd96ced68d812d8c3637d7ed99f921634b4de6679e08a10f55c72043348bd5e2ad39c07de4ea88d3c8c06769b7cd80baaf4080684aea9637528ad99bd53af25d5eb00f72a1f537593669e6daed5135ae9d77b737b77a475b61023777ef0ff577b663d5848ba7d885914f713bf7353dc46c2e3b9e75788b3813b4845cda244de952a8d9487531a92da0790cfb43ead874c332695a79aaf3c6d5997bfcdf7783064c1c055b82b3be463b5b54eb8c2f4f772cd56318c6658e0b90cd3e596b3880033338e6f4ee9e1e87e383fb7505dfda6e501a13dd221370a61788fc9be64625939e8be9d076b45c5ec556dd634347d9dbbbd5746641410cb34ae53e375fa0ade7ae5ddaf9f1fff048668abe03869924e17b6cc18617946c73a20b49826748981377d90e8b72b828eab696b878c79bd16683b2ca698e1489dbaf3b54fbd1805dd0d58eb269efc7c02a75fc6d8217bcb1290746f735ed010a581efe5ebdba8c5d379442effe591c4be3c9cd9bfd5956674f559cf3885e8becddfdc4cf971cdf64153f71ce28b1f419be0899f2e6644e939738b846cb661f67a913936e8db2f4e8987b5c48c37672a33fd380ae529a764be14a87939b6c72b7730ffc4db926836d7ea5621f724a88c9f55aab44638a4d9e86727f46667bf8e20d3ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed17bda527cd19e7399d1996f44755fbfd86a7ade9fbe3957ee97a08d668adfee6b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd3cdb398383378ab973c9647ebd74921531a954efb53a94e229b7c7ba8f2ec9a1e93db9826bcf1d353d91abb56b89c33fd37ee623d758dd8a1699929808c881f9907556af18a95939aebced3de91ba5a9af3fb769e3c56d4cc6baf9c9152359609a9e8dd6aa9cdbe2b35c9db66d5bd8868474e65257f785b429c1869bbdf7fee8024c906aa5e195dc4361aa95d4c53ca418a7b79f6cbf539ec2ff42dcb3b96e47bbe6dbdcd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091d7d1ab83f71cd86765e760f0a58bec6eb0e3eefbc86eed04b98e8fdb541206e9964367e2cb694b0fd4ac8d588aed936c55bf8553b2b016d93d8fd15d96f9b494a04e3b51cf18347e8ad25064a488c4fc0328cea0c57dc14763a74368e46e59c73bf32c94f4fb0eb5be73d14fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc452aad0c1ab9f67e84de775d0f59c7089beb9dca9ca9f13d9b60effb4d55f3d734e086a843a39b29de99163ad62b1e687439ef21ea3314d784572bab031a373211da50c0ac8150691b72e687c7df0a5b347817a389afe41bd6454ee2bf5e1be30bed368c509d6c1637c037cf2f65ca76137da9e8bcc18dabdd78bab5c48a3ddc8fa01c646c9dbcccfa7fb9f0ac4edabcea3088586e8ca0807e87ad3cefd578f9fe6ca08c99167c65e4d6e93261f887867f0ae2edf5808f04b938dfe8e3b76887cab48bf0cfaae5a9ae6f4cee0e23dbe7313411e5e7e6febb2e0bcd04d44380b8ab62e874539edd5d4f744919af50e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = 8c16f0397eae8b1afc3bfa4695c4305097d3935de315764ff65c9ef0ebd6b03b5b568fb57e1a7ec6ba4ad93fa04f4ef68a853aab3ff7f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f27dd769afce41c0686f85dc1f17784cbee42ba4f648655bc8a0acb8247462713a2194ff3e0bd93a737306e94386d878eb8babe7dad66fceae52a0a81a89fafc9ec3237aed1527ef2793ed0b25bd2d5b8693b8eff482ee76b348e2aeba7314a3a18ddce123e5412e54a6508937a393898cded362befeabdb7cdfde806b6fd1257dad575d606883872a550318f7b5bfa8a05fba19dafd7f113c99fe5985ec7de893f5e5cf35eeaa6d5317579f16be61f55a81b694b0a79b8211bfc785f4383aacd1936ad36b43f66fb6b5e668205396b40b3889eaf5e21fa985bbc6af4a8dd9fda368507a7659785363c6538fd67eeb596f5337640e7b3b18778050fed14d76d6aedeb67a941e76cbbcc3765ae0bdb74565470e7320605a0cd0d9c60e57c9e765d2f835dbbe9e482d43b86858bf92e61e1c358639dacacaf964f3a9b8345fcf40aa2654f634ffd69e2a3fa470a59af07f6b96fb880e7a75fe7d5ef5d624ca368e8c39c27fad588c8983a453bcb3d897a5785cdef335ef8cd492e7eee4485abd47a0769a0aca9d89bea59c458eb19df7c15e9fe925f85dd7fe97f58d4ea3b3e79bbcbf57671dedb86790ef74c5fdbfe29ef21e489675b7f1479a391ddc8fe2a801f4cbad209d2382599057d5f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fdad6dcc3b3ce6e7a3f433174053885f785193c8a7053fac83c37b60cb1cb4d7f22c7b577f4acea879a8af7d0996df8aea3475426a3f17ecc527ff33e793aaf9936dd6f5a292b84d185ba31f964a50d3c3a96701c6ca96315f05c5d71c3a6540d76c14e969a817ee46a4d907f0fdc867f45c70fd3b8978a23a6c84ceb3de596c10bdabb284fd08c7af24eedad219b9987099f1cfad07d1466ab17e9e396618014787ca6b1a278de96a85c949486105bc4357a93a41d9422f5fa44bccb0c9ceaaca7931973560b8fc65d253c03cfe71688648a2c9f94fda26ba58061c8cf64b54f2a3da2a5cd64cceaa6d34c76bb3ddc383aefd1c7d11a3d4f278a87a77837856c68a119ca692b8c3988fa16bce1cb6c4d9bc7acf335aeeae65f01b5dd4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd54dc449b8bdd15a3de54a3c2ae7a444cb46aedc1cfa347b5173fe6f4749658984dad530483a86b773471799b9bd53faf04d0a4cd7515a3b915964aef2de0344ef7b3aa72ad964f38ea89a4c561e46e43eaf3d03a19cb4eee4fe88bc5b5cf36ecde930474718ae654f53f77256bef5097f1cb3e8d2e5f55dc8d4166d94cf305bcfc6c91466be8f3aa4a64c6f4bbf395a10967861ccc3d13a17706511c8946003f954a6fb9dc68aab47dbacbaffb4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2c5f6ec4e31e48546ee449d8eb7b70aef96c028c6d085a3d614b8856a6d076cce23ca4ebc29fecf14954cad641538d275ca743587492e76a5ab5593eade5b1008fadcf73a95ed40d9af5aa2a6e6ac8a88ccbe48e1d7f7b60830594eb8f3c63e967843c9b5dc43c3366293868f2beaccad37d95b64dd088e07e4ff2e2e8b18eb7eda6af506cab773444f2383a5e40940e5ff6033c336e3c7b5d8dfbbecdb39180c87127781111b318fc4ab8d5d926ca3fa122aa79766a48abab67087e0c76d30668540cb5c8d8737fdac2683adb8edd20aacc4ddedf6056cbd23735dda39143fc773934e362aeb6e247711a843655ff6adaab77089a831e37d5725e7dca952a59cd8367d5b03187b77e6ac91e4f6ac2eb9989d5fb658c6b86edff5e45e457fd4fe935a771fa3654e4014483cf1bc844a6935ce45ed1e19d313a776253386a11d73a416b47a943713cdb7b0de30fe8330427e6530c4af969f8ebc64e961558a7083f0a5fbbb3d1e3e8b3c88b0c3b35ace3ee34e72c8b649b67c645e07400cebc486383d8fafafdde8c104e69dab368f092ab3b3b85fb70c3036fa59264de431de7604adfb1383f58c2d6b814bcef6af588a8e339cc7f5a5f38a079935f7af7578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = c18cd4d9cd82f06a8d497768755ca933df663637b2641c34a379ad8faa55c25f46fc6ae3a3963d4d36a1a2ed6bb91ec737fed301d961822d7f65e992a66b7b3d29f1c707f57f34bf3a5ecadbaca9e346bde27887b61ab58fbbb3cd25466b3684b59ff3b24c34c7fece5aec85147e7cbe6ad05945fe4ad6feeb157a0ef76937ce6db808572cf93adcf5bb45be935d43abfdaeb06d375f4d5a4d2b4d392023a86e05796565abab8d6d9cbdf73e543ab048d9c4fbc74ff4e56cbfb60c76be49c7a1d5d454116f7a860f6a5825fe2833b446ad87a50de2be0bef03c7e02ea4b17d6b5c4e3791facfbabdff471d86c720e4e23435f9728cb5618f8c7296d35f7ef69873fcc064d79bdfb53517b4c953969d8bafbeddc09855e91ac4f6c23a8b469b601c8751b02a4af32b670e6592f2e5b9449f4853e551be8dc5e717405fbf480da7a6ffbbe9660cbb5956546bc64df06db801cf52d76c96d2fb3d22736144be44953a410653334c8967a377f84f2e97f5864c5f9ee721a49c29dade43e9aff5b7f6448ebdd5c4af51d5eb66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7fedf6efeb5b2723f4bd7ebd74dd9d933e82fb7739415e59d51ab7e52ad765c56d98e5dfda35546bd762c32fd4f576ea72aa3a732ad5214d9c62154cf64f43a339e4a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6c9e7d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b165ed4f03ee11435a97b6ec0f4430757c70a4d73402d94338765c907d8502774d36ac34cf85af4683ab5b36c61b14d64705c68b578f7dfc4b9896e40d28335e78c3b5ac7ed5bbc3dd6ab0a76a97868f57c519cb58fdc94acf818c43962dcf4695c5b3a634f9090fdf14239930a9b8fef5ebf5f6f82204f195f3729a3e6479c9371bcb567cd5cc1398f8bb5d3679a7e4dfce8047c84aea66fd67e375ce697536443ae087a5787a8de73e4a30f8eaea23e2f30ae3bfdece1fba8e648dd9bb7998d41a6654e7db2f9436f6737c9e1e8de76ccd885b4b0f3751990b93138a70adcd47e54e6fb3ffebf2359ab12f696e67b6ac6b8045f3c826c8eb76c4589a687e42e9d9ee5473512a71b6369d22877ab009eb7dcfc01533635d896b6cdf93f85962f06afbf153e5e42582188bb09f2c3cc86632f636addf8d817c0681a3c8c313a65ad918cb1268fad1d76ab42643efa7ae8d94a4722bef4bf77e8e47af6874f112ab962aeda2e43e6d6185668ba373db57d8ade9eed47a5044eba47c346b7d33dd4c3f4b30d6e93184b494eee1fd8362812b5fd2ee9d4978672d5d5bdfaaff888469fbad40a4b3c56499f9abaa66ec435d3173519b98fddd7474b23ed3698eec301961f4855a49f75656d356930c79af1e983b3fa17d4757cf4fa2daef6f6a77475d2fd56a5378abf7c7cf097a80bf3badc4ae929a5d1eb46af54f956a47dd7f9a635926859f6d99d3cef1a807c107dce5ab18ae4634834d3fe44f689e931dd829a4a9793ca767e43d707bcb2f1ee8e91db32f24d0733e721a6aef172e991b556b70389bc875fb56e8f4e17da5f965fde89be4df346d43b460807662263769decf68a78cbf4c155e46484c8f1fd87aa6493ce73b855f89e9499d0d0cec1576f16845f1dae7e76df5fbc294770dbdfee08899b79673f66fc5ec78e57c758d4726cecb986c1355444d96402becf0a73de28ad3c9407a64537ca85508f1c7166800839e32b5a0ba4d4ec4f375c68336c3cd98ebaba5d1865a99a8b45993533b0651ef9747776dc48e04dfa736ebcf9c43bfcc740a16d5765c5cd84cc5640c92e533a2ed9f3a161fba58eee92464ff543f9598598a0717aa91986901046db1c763f35d98104bf08943d85b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3caccd4b7f7ca5717f216c859e83e83288c8fae0a71b99af366a99f277cdb68688759e6b34e5ea0f5fca2c52585894a5ee62f53d6f963eceef8353eb6d79ed65426a19157a6385bf7bcbd495cb8a4f42c564afe85601b4a1a6ee841e775869cdef1fde0a8147a753f85ea16a6f023f3a9acb46c24e8419cdb94793617db9fcd1d39b016dc177d52b3766e955fb65f4789da1f3e5e299c0e54d9870e3226b63db7c7810a7ffeeb8880c45ec6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 56054ad435edef874aa015eea234b544d7a0dfb6db1d5bb60b8bc9532dc6cc96ab6ed53eea9c7cd27e5e9c39f91a46eb050fd6cb094ff888642827aa19c64893685ffd0d4b6ed9516f6638b9bbac954d4f92cf9a4d5ac6aa6e5179798cf6c486333a7641846cb49c6b794f5aea34dcd5f98ffab8f6aa3b7b644adc5f4c3ab5dfeea918ee9439445ca8f77b9a507bbcbb82e3eaced3c379cde7f7e6f270749bc2adeee53c72953576125574deb7f7080a659bca4f007b6cf7c9cb2e0f54baaaf9339dc493654d25e7ac0cd88a620eb1272fba2637d00de87d88e4990ccb9cf5ad8919dd44c2e5fcf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348af7d6f401af8f1bec9f8b4dd8cee4fedcdb2f38fca8f5c499f2a3d16bb75020d3d22965b7e33826d343f72b5d1e1cfe9bf868b3e47bd4fbcba0d6635431e89c17c32479aa5fb0abc84549f878490bfcac6934a6394ada14874a878d65aacfa36797d491934dd31e9911fc7d3dd339684d5ae619dbd3478578f7a60d1e7fda9e7decb9f66b19c791163f2e626ba64e5fd26c9a656fe325aa63881e8800e16382a46865bcfcf015abe3b5fdecf0efa0e6af8376dd176d7b6d54868ae3a977dcf6a41afc20ec3b347cda4b81549d274a7bc6b446d6a42512c55ba8f3d7464d2a74dd65297973b99b569a5faa9a66b440430da8dbf4944cd675e3221fe3964b3de86f738a0fbeaec59e909dfc07a35591a384d0e66daf92cef7a1db2d306ef69234375b9b6cd0e7891eca65b83332efe5773baa48996f494435538db956dacd9660499d7e343c7d68fe18f997b73b69705b9498ac9cd989efdef6f4bafb3d5e7b445f4e32185a4e744e75ee4b5b7cab33f4fca33096755473d774c758b3ab1b7687d6245ec3d5f51653953701c81e2dbf667c885e75c814f375eb946adf00f7f78036b2804e61f1c79a0ce556de38bfb2ba996db3e3f7db79cef614b073cbd25dc053e3013ab88c487f97ef6e5fcada9e00a50ee4bdf66498ba09acf338b7342b8670d3e428f4a52ccf9b4b6dc98667ba4389f86376e738e63653c34b9147b60eccfece99f91891bb814096d6638d6d2ede2481b922bacffefe9a66c9e9823a7dbe95bb12c76e94a9ff8bec78db0739a5b1c93655afaad73851355a0485a52c3896c3527964e88727c48d5efddea65cca1fec8466aa44bbac56e5389525199fb6355c5e39953f78d683f07ff0968867b536c11a33470f8ac7497dd9965579827e1e6ddabc65c67204f3ee4b67771055952b54df8934f0b6980779abe207c4f8deecf17bbbd91bf4d1ff875109366a437d202036a07a6e46cc8ba718eff99bd42b40ec5143a6144fdeb7abfaf3a944100eba87eae725743c370d8589499f46addda95f3866736e38d2d99b9b6c47ce9b9641ff2c765662336dd860db4d785fb6779af5b5b858026d57f54517506e577476e3b0faca4de485e0882b305c9f956908da84ebe8d83ed26b8b2b8b50a347a4cda722bdc6ffc2b904359eda65bdfd0a39b7f1550187ad039ed7598d6887e6c8c291df88b1c9a45a66233049d77e9e2b1fb50fd1e9b0b7455c8e9da3edcb0470fd74e5dec901d8b833caaae5573a10b9fd1775aba1ff6d8b3f088ac614eabf0737c88dda963d0e77c7c69f179c4d3098e98752ea886ac7a422c98b6e5ec53d8c1027c84881491994cc84eabe185b3425758bbb1f3d5a21d3ff6989c633a5697a97e5dcb94e729ed9a47330ecc60acf85083559d507a77f7033966ad859fd6306d27c0ed2b35e7b3444d957a531edac49a8851a5ff616ead551b7c758e46076eda0cde9d9ee799841dc74e05d8902cc71113e34b5eef90eae22ff7ffd14448dfbdd932977c0f27628f19fda3bcd7da0ec2c46e3d22d48ad6376ac2edd8c8de9a326f3ebd6e6e4fc3887d68c033bc3ec0e5840e4e5f70dfc15355c223eaec45289315cc945aa39ae7498767eb3a679fb2a0ca6e7bc73a5d97644703aba49fb5d38684a09ebcc7f5691f295a267ac0c1fb84e5f3ec94bbd20e45eae51d840f4e98e417b8f397aa33f8811413db07d5c702c6ab64bb7df7276f593ab3d143f32d9e9dbd06b6df756259bf5c723fbf03d6f077084ce937ce82abd1739edb92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = f72bbee08d59fb6ee890ee6e55cfff88a59ed8b9fd72188f1b6872236dddbe74f699493dc08c97b7ae3e640b51f2173cc8b4e7be68d77803627a7c9bb2a7b96e9596e3d96c75fd3926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789f0f664ee7552ce5b4c4ee6af4299c775a4dc42fab9fee6d66bef98294adf09fee94b5e19f7e3175b69f03f941f7c56f565439f2ef4f663987d66bd0bf899495d5c2f178812ee73388ae627fa8d29344928e5c9100d5df87cb6f9abf7e3ec7635c7be32e0b8122a8d7e4d9903a2c5ab8985ddef435fc8462f67a6c02efe88d83e41236f392acb98fc49e4cbca7ac05f3a8d385e00df0d02c4be4b878bff659abcd5a8fbbcc1565a53cc36af88b41a1a3a18b04c729beb66a7698be968db7fdbb01fe665088cdd4e3464e44f61f7f748705b5b7ea5e4d1ff89365a56739a4ee34a5dbd5509fcf97c13af6ee2ee6929a8eb4793248bb78a2dfed981733ec874ecddfc9b4bb530c4b6b11ee36e764af55059da3da93b89d76afad89829fe0bd076e2a8a49a513f405a857bbff95e7868bd82c958d9d474bc4403f6fb8531ed61b7bb6ac533e9697dad0d7b9f8e6a835e6c6cb4c8437489449af73e576b91af8d62f5ee593b4c541098185198e4acd790dc5e6adccf853bff0725a5d50d47333bcd58325b61325840644e40bfb7af12edb34fb408749998efe56668634b775965f05aef9a7e3d1f5bdfc63d2338bec041448f6bd9af8c5560076ae90ea3d2dbc39bcbc8e9bdf6981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc4919acfc35e35d6107ac61744dfa1dc02169ed6df53e4358487f26b4d416d958095fe464ca2703394d8856268d6106ea31184de7f5fd59465dbab828993d55628aca595506f04e4b316a8aa9971c65813949a178f8b589fad94e772baeb85314527eccfe6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485c8d64fc585ab9cfaf631f441a763540f7af3d8a8620c6cf40ba81a914ca28b8f65248673d83e432ec9c71ed83be49816098494e6994b385b509397199efa50c76a894acf5ecc9849ed45d59c9664453e3d6fd419abc929b8ba51a2a49589978a1ef9c681cd7b9cab2bf0d35a07ce8d66eb9b0e862a2957d5e4ea0a63c4be9aced50f76ce57862b406edb42591f17ab1e86ceca2dac3f746940d1ded64e8edd0889629e6d727d5a5fd8ab7549b439d66a30316883da6455eddf3e6f7d2fb4742a83ae0206dcd8f4af9d3d88c7f4e8c3e3d803a64ed6deeaedfa540371c846c77f753a858b39b5880d69b8e5f5c6d57522bb6530cd7a4edb7730c07f1541454cab59595e8a5d74df24a4dda70dfe80ec3eba43398a3ae8adcb9faf2a686c20454fa9ae864d73c0caee67b6b4731cfb67c55b425f9fc663465b7f7a1d2163f7d7a8a08a962fb0e49cf2ba8c4066cae8cda22a989ddfaf2a64eeee5d895eea9a5416739f91dad5ad9d1471a72aa78956c5e83b194b26c46e21a5deaefdc49b6ab481be838f95f90a0d96060d68e5fd7e358b9f4ba6ff5070c6283c4d1296698310bce2f1b7c8a63ee8406f65864f9ad3394fc04bcd9bfd0834cbb9c9b9a8c83601fdcaca38ea93f47c6e33ce33414ce7103ff60fc52b5cd7a150fc3942d56fc43f3eb2f41a6484e6a074676996e5a6f867b6ecdffe8811764953004cc9c3697e78ab5d156cb953bec53ec67488e792ac831d7ffdb5b29c3b064520fd5968bb351a50e646af3f6762fc234a8404c0f529eae82b483d51bea4b972be70d03aa378877fa47bb61fec1e45e91112febd59be7ae373be3efefc6d7ab2fffd85f5ae94fa7717ec83f6c144e2578d7abafec32b843aeeada5cf85773b77efc579a6788e6cc998971aee153dd91f21733dd2cdfac3e808f2a3a64fa783e0cff4a35fb56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277a6ee67e555cd6c7c4a73dfdd897cf61c9c5779594984d88a2b415806b5215d3ebc4e6481e87a062582a479b3e05b9413bafc7af59c5a9c50358fff4313ff0d74f8f94f5f4cda38876ac45cbfe37fbc5620a8f3b05abbc00aa9e6b3d7bb164fe14e33120ffce54f44aee55268da3135ea5996f7cc405e85671dca694eddfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = b59ee7f3bbf34a4bc2e6c8db05f97f10b5d8b9bbd8c075dfe76e85f146b0ef5993629b3f7fb646dc248e079db7755797200fbafef88a9864c28e885562ea7b54ecf17c65f1157ef2aef78cb893a99c1c9621a6b51a53e17016a7f233ef248d764de8e162a4433d6ca17116f704294030d5a3bb9859a983c6b80ddaf23d444303932f24ef506896fbec852a8a6934f7fad9cd38319c58abea4c743e9df64ece4086a90976356e1decf6479437b64dbc3e8f7dc8e3d5034841ef3910ec67519c93e9648ebd1b70edc3ac24c983ecd4d03cf5b130fbf51b6e99814c715eb54fcc8ba9cd638a294bc2015c8cd8df87372f6864af86dd5cd878345d3885cc4b2acc0bed8a277cc23e397dee84ad6fcfb4d73c520a1db4eb4ba44717ede023e1764d60195a37ec8de0461d3b59a94d5923efaa2bda9984ebf9be86f44c6f66f76695eca6932647e408966f7ac4b0b8af16fec4fcef7a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be9451140e3d02197ba79bdf609dd8ac89b28ae8f9e50cf616dbced329f243ed74cde7c8e3ceeed129fb25db395f09bfdcec8b1a8671975b692c84714bb3d49a6364949961443efc54058deb87dba709ceb7659868998d666dc8f438662943ef7fe77dc5f5390443865e2fe5833c78ff2a6e24e3655ce799f62c3b5f24529c15ec28347c3c89ffdf97d0ec3b6559f8bf6646352e3de3bce7d4bc3bf6c0b8a231acafc7675d0e9ad45987df12dd4aa0fa79d616f178ea4befdd6057444c4b4a76723fd1948fe2de48941f868ff3184a9b8dd756a59e1297a71c49e2cde4de6f883296dda62904a4be9350edb4483ee6bd213ded253997d983cacc0a4730b4f55824ba9e4b7ca89d8ce85af562ba6db8e38b860671e2654f2c9b669ee9646d683ea09d77344f3d4b139bbdb5ee785a86aa8ed3d9ee4d655d64b7fdfa3ac6bd56abbad5dbd9f1968fd70a84018692c2866af2b85ef813eb7693444ddea9ca668bffdc9889053980a88bbbe59c883acad10dded7ba954c487b5869e0a10c95f67ec246fdb41536efe348714c288220ea84d8bc524e438f44ff9a9e4fa8bb8e38dfdcf6428fae8cd7927d0cd0f5da7c2b4fe914e84f716836e64df5e2ca75c8e34b0419f753feb77e9cb872e742aef7edfe3ceece8c9fe82bcf5623eee0774076cba525934e21dad387e43d546f4caaacc88bffa59e234e25ef62a23de582437656f97cfad4a087d6f2de1563d3ae6758875b03ab51439ec7d3ebac7e44304d3f712af58b089d31993ca79e45e46723bcbffc96f16c6ab7975151a6ef1c3c3fff9a9ec5a4dda90a99bb2cce3f376cc4d9a417fa71599f411b649dea698678936c361f3e5ee8ad4c0bfb85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8dbaafe14f495820ed7ab14779278a6aab3d3ceb5ca7c246b5bce3162b9f73a9ac00c745fe70de698575e5348670bc8fd8ddd4a11a7753fa7729c99e96be39ce7d543e24ab509684256f8f825277da24b84d8f95517b55c2b4de864b9a13ac8d9cb0ac7003e47e58b9091c5b55eddc23dbe964d8b58dfc8daeca479effe6f43ea66e185b6fc263e081458086585b825db8239a531936e926ba339b79f1856e851a8fddb2a306abf35b9fe5e8d74aed367ecb4a55067e385f3b53549fc4cf12d79b8b4e627adaa52c5647ca634a37588402ca812f870abb94e0acfbf31bbb865dbc2a4fe97bd7c679ec436f21684d7773de6cc551d47dd75cc6217bc8db75431159aa5308570b173c7e90b6b0ace6268cde69677610f5758074da5374ded6b6b7c595f5b6f853a5aa73a05c766f73ec0f1d8ff6ae54eac6659f2a37fc364b266dbdfbf96d1dc5651daa87d790ae952d950f29441982a71bdbb74d36dc6b75630e3f8d643676c4d59960a445b86d5508dcadc42fe516f44aa309a799cb6f6d4ca8b7fc5cd54d6f3acc96f1594ec85dbe265f5ba3f6754b178a281f8e06a23b04744ba248c70400f79d0ad55dc3c70b8c68e48dcc84cea9d725b4ba5c6f8d9ac62899a460c157752366c00aac16e38efff1f33e227f02fcade2bb3cc5c27de1e373fdb5d3a1d75af9e7a57cf1e3706d833ae76f42aef774fdc686dec4a6278d93743b718d3caff7d3d2c27bf7cadfdd158fff71ecedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 6daccb274f9b4e18c0469ecef2a49a51f34aa224a4f8edbdbb1950b5b9bd634aeceda3c94da93cfce38aaa6fa45a135a461d5c6e2548db96698d68ef42ebbb7c4aac8da6805024bbb3bdc45816d15ebf49b5fedf9253649577dbbfbd402d1cebeacdee48afa77d29cf03647fac3730878c7bddc7f4f7d8539f4ef74f2d334949a92063634d7cec0b6ae99956de25259fa91737d2b9a6457588d51d41d9de786e08dfc2a5ecd0c84bdc67e0900fa7ab5f97174c7be5b6e57693c07a48f42f85b79d26f60ab37786e67d7d9a77c953b81a2a4b9f0e697bf7a714fca3da9d479577ed4b99b5ee83765a63f624c4d04fd6d44c1840a5dd7d4534d251e3ffc0affec32954258ed37dac809f477fb6ba5b198683443c683cc8494cdeb7bbac7ddfd39f46bedc77433b868c981b7aafbcbfc8f2bc8a6f3e34eed7bddd54b9fd1a38dda8a2ae6db4112be05729f8c7b55721d5f7150668a1da383b96d6f5ee575dee64dcd9e1af678a33973c808ae59bece2812bd03d68b8eddbe2de26e4707b555a85329097db5e5b48d7774a9d69a117de3808a6e164dcdcc393f5f49c463f4ec0440ef1af34f39c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4555afedf2ecad465be2f4dd1fc9c955a3b6dca56e2d0763299aa8335bf8830e99600bf3f7195598c55a704ec9539bcb9a457d4c77cc1eacfa7cd47ed47ddfa41afe5333acb076bcb2355acb6c5bec8dbf640c8688244fae3938059a99ae8af81d2b6ade8073d1b9d459c04a5db7547b78eb007ab996e1a7fd7ad30c7b34332854e036b8e9add369bdaa123a86aba3e776e437272bff19af7a4c7b8b78abcd365c78d1eee5fae8c4c397c7b6eaa4d03bd6f8db7e45fab7948b786a78639a4f8d299e3c12e5b384705d9c5189d0c735f594ea7f5b34fc8ee94f50fe0348475c1d4a3f4f8e11c9cc6eb16f14c43838c4eccbb75f4da67e5e6af644bfaba6abdcbb54935db0379b52668e2b8b84ef5600ef76686cbd651f7c43c2ce20f2daf9eee8aada655d48b375b5af3d21c51e1c3ce9f0e31b61c34521fb5cb4dfcaaee83443495da4b309ac898e02c4f70fc7359a57d25778457f7dbca9aec7b444209cdde24da7e0ff89c1929d675bbf4b615f95ba862eb83fe4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e09ce72467c80ea15f6293e660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6226befee03cfdb599bb024416ca980c828efb05eb421b86f92147e13dd4caf335a870aeebebfb0e67cd795cb5f6523dadf3bc8ee3bcdffa2f3cd74ca9c4a85452d8b31cbc7a06bf1393bdee03b9abcca42cef8b5448482d8e8d13bdff1af0e436cab30e2def6f608dbf46baeb4b8f8f54735b65e3c902ef28fcfaf7d854d84e3688799ce24c8454f3f6fd0f52fae773ca5e4d8568551de89cb8526511519fb960ab9792ab8613cd1233e921b6c697bac6bf63e74ad5da6ea2ab3f48b532a05eb6f6939d1cae4b694c149b5503f43f0f438b731a59b4d2f810e1e96ed4a90efff968d1ccd933f7b37866abbcec24dfdc2b32f8d0f4ea3a1ec6a4227a36218b6437b5024fffd44fd4b713cfc6665bd2dfbe60aa95199146618dceebefca76a1f48acb7c549cb66cdd59f5c5cd4712d5791c742fcaab677f966f746721f58846d1ab2fcdeeb6f2978dedf827314d2deb863ca1a7e224cccaa2b34f78898762dc9daacdc328cad6dfb46aa2dbf8dffff4d265426cbafb42df3b7e748252561cd678bb21fe8d4e5cda45488c5bfc1b2cc73c6ce63da9467f02b5ceb4a5ecd136a2c5e84717e9115dec310a688e46bb80dc38dca2ad92d36a3edd7c4c6d3707479fe267adf60bd501e9791f309dddd93386c05c93896b950c7681f0abf8a044ab22f7b693edc169b60585f8315ca5fab7ab2c9dc7743d8943c997802bdeeb2d9a196dfc6a98edfefbcfe618dfb695f366775de6616cc0b7b5bc518d9d1d45e1673be8dc435b7355b0a26728205ae8713be047fcca8169521e574fcde8c37ea3cb70dfba5d8fa5834819264d77e1670047997863a5ec779fbc26cacfd8c34639d5650bf7a518e6f2d69f277f561680f7fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196f9fed6a8e57064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = a92dfcf7e4cef04582bea9d0601779816d6197eefea824ca65d485783a32e42a4e20e4e806e8ae1d5e544c63c3156a42bd8abe55e36be37c6be6b5eead0df374eabb03f64c4ddba2a78d6cce943cf338b0a05dc5123c4083446802456ce95f48daac7e5d9637a64ec756bd3300b43c4da96164c6c42c49e0d375f2e34895055c43847459451b8022d39a2c287ffb85c8459c31c3de83f98c684a959b2ddda224cbb38713c4034a6669ee4cac3c8f9d1b95ef6f51f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ef5ec62d244502a3a044f4c95fdb42a70ad401dd79ceaaab0f67f0a1ba852ff7e48d5ae643de330a4fc81b27882c73ec3ca3758f56b7718475404ba20cb8b436bcc11166903815d7d02c63e62ac58f65e072cca75a86ef237b5abff58b2026f42fc9e0f24baaeaa47dc01ed60098effe2f8aae07e5c65b496795bce329819418c2642eb5c73cb604de5ffa26f901f386e9f8e5940bb5703477a996b313c5dba06aed41ab65f233abbec534c116f24c89fa3ece468843fa831340861d386253c7eb076711ec35f609fac40e42229fb3f71eb36b97aff38a94b00764e9d89f3817fccd6b978e1a31e49ecdb2cb3f9e344ba947a73dc9e891b944de4935d48a5663f85c94ba6ed8b3d26c278d645b7b5947d2733865f12a3ceda3be2787a1f0cfa2fd3fe1f405c3ad1c8c46257059e6cb43f36ccff6f31b83d040849234dd3b7fadd76a7792f865467b6548e64ebfaf5b7c3f6d59cc4f6cd263494c74ebdbc7616aa8348c6335d437e9c0e79ae52931a119856c168897d48dcb54f42d5d5c535698a35cbaa908db8145927af6653e3e977f8f7625e3ba18ab7af47fedf248434c2cc5ea3f4f34d6de200ef63b59d4b1a5fbb8ee6dd979c0364ea6be9bca0973f120aaad6c457943cdd7800dec6808af3fc8fd390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399f2f55e13d833485bc69c5c94cc48bbfe7bae3754bb4aaffc2ae5db11fbe519ac8802a5cd005a6add3eabe237d9c39f4144f35db04b78c96876b084d41d6facb2dd08237a6f1def6000de44ac598094e8fde238aae358e35dee5394fa31dbd30bd97ab2cab83f84e64359aea077591c366e62d53970ad65e21a994123c4000277d72ccbd0e8ef0272e7de9054fe9b38c610afd8097eba83a88bca8e05e693a160ff23eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7b9da7717e7b14b40673591e986a1dbac4a88cee1ad285489a8d8df2d6e6a768770e84023a3ebd4d996238430859a6f7628964e4465e5db7a9f6ada7737fffa95a9ae759d48ee885ae6a4e3e78494af5153387f008a74ece68a67b8f24e29f0a02d770bf4c8cb15cc39dc4147549c8cc599b86d700db4591b28490566fafe554659ad7ff22c8646ef9006d331bf09936085c4e7c345e2993a743fc9b51ef4d375c40e266a262dd2eb03b5dac5d760a7fb7e9785dd585df7c6488cf9f18d0e71db28a99ff7a557c3493688dfe9aa78bb395885085e0243887f0bf8030393d925cdeb3afcc3365ea95b5bcbe4b0bac9bb33eea90c0d9de0f6be8ebb3e6855e4d34f5f3f1688f64d56f41c8e364b5e89859478349c793a709838e8c29af45f79d057095b321bf7742d6a3a85644539dea1636f5029bce3d8baeffda740aefe110570817bc66d9b8dfab95da9bf70898b6e31ff8418ac5233a954f16dd9c2bbac3cfbabd0db906188abe7c7fccf6dd1496360758cb477ecfec02a59072ec93c9d67ed346378d4e9ab634d95267df03e48a594be088bc349ec9669e4bba474c4adae65e664986c34a0dfc5c5c488ea61063f11ffc175693b5b5cb7c9b7444215df5da4f1e7addcefe35bda4fb49e46978757ef43b35ef0c86340235525e5d904263b2dcd52758bd1b764e4027c9d02db50b4e47e5dbe9f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5cbea9788565de9455bf4feb50a39105a33e60a9533c5d6582dd3459696193cd86270d9e724bf28efecac15c645ebe6faf697a7df68d71a56cf263639bbde85fdf5bae84551d7df05fe6b98da3f8da46d4d9dec70d84c9ad68cbf266baeb8c6b3ba7e6ef5da8fb6af5bb6a32f0f97136a6d1f965fa52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = a08eeeddcfab21ee36fa5eff725ebcf43d987bcc53334d8392075a26cf7e3747c65c6fd6a91483ec6deb48cb5e07e5d1579b5093255d5e565cf5ca6247064ddaeb7e90aae90db6e348365c1d5d88212d8ba38fb5d58e99d7a947ce9946f633baeadf4eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc84e9d9c67af62fa744b5d6e73ccc5a0cfdf27663e813bab0d8fc6c74d23fd4cbb5b74d6d5bada2a33ea304d8d05f39fdf56bcbb455f39b9d6a8e366238e947659534f9443f94f66937c1000d8cccc430d5f9821126b9b39ff6d8a8c1d8af47e3ddcfce23c52c4afc92fbbc45a863956ddf7d984c9103bb7713db41b6c886beca1c9be10787806adfbcc23b52a38651c819df3c0bd33826cb84089809e9abe01d7e0b36ea8ccb3cb9fed434acc4041fae18b93b8a3f3c3a7676d18f7beae3b4e84d7827579efe5750c47a322bf76851a762ca06fdc64370742ac716fe82c4e6a77f47c5f23644f53de0fd0f9c49c538c9c8f1c786ec1d3cf7d7096c9f66ac890e660beb39d0df3e5326d3c7145d61668a612b3407de6feeb67bc5578bba8fe47fbc5e3f24d59f55c8951e77cf24910d1c94f148df2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecdb8e134af99fbca37b4a69ad509ba454d3ae3e5b2d04f77c9effb68fc61f6fed5dbd8c31f99609faf770058352c8e836b473ebe95c9ceb9daeb78fca81b3e715d8bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d337d406e5b4589f540136eb790dbd2219636ad9c65ea5c48ce79c2cf4758db9bbb56fdd3e0c64f9c0f5ddbfea341f8c2f26593adb9af1869e5c0489c780ed48abb9802ec812885af613f67b7457210f5a00d9e703abeb8e1bcbdb8b8b3caa4e8d27ca6e96644f719d322993797a54bcb13cf5a4f8d24d499c6f631e8694c50389496c6454fc34aec2677eced5a0e6ecb7ac553e30e7c93e7e83f06cf461331073786713af56633df191c816aaebba3a968a44a3fde764a0b67f4e756e5f3dcdf81a6e6bccfe055d85f0fd4dc677d48ffcf6fe98b901b67a2923c57e17ccd2fefdf8c3731f10b58b7f9f34d4e51f604e84ff6f16f5aabfcd3b6352ff897ae56bdcdce9304eb8a25cd825334b63f69881a682d8447975b45e839b8fc54b53f8c70a5aa9c797ee3ffb7d8dde5d70b94eb59df5820fb6e4e9ef1cdede6ba7dedbbfa4117eeaaa09d4dfb5ac2b4e6d7f43a396126ee0219fb9233c75c8df0d5ab4bd7e3abc3b679c7edd3a7ad72f0038983677f606ab976474d8616a5dbddc15ecce0986b9beafe9df7c740fe1e98addcd19d43766a847f05fb5cd8ce6a6215a0dc35ec894ac585a5b531ef611c839e98786fc6dec1b18e7da8dfddfafbc6806fbbc97fcfdc153d8303f9814abdb5f7babdcbb125298127a83bdfd5d3d6a8a2369e36226bfbbd9baa2b2ed50774924b8662bcfc608848840cdba8f5e7ffa3876ea79784e4784860047915c8922c96bd906f5d577f9b96d88c3dba9eb3aa308a7940ea0e47ca2ed77007e3cfd8e224f36fa62ce225ca7a653c5ab9ddb4328cd14ec580b9b347d14d3c236bf5cd88c99268fd44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f60af09e8c34d46a391f8dbdd48691aa3db3b0dace1b6b4b90b948795ce4ec7b767ea6b21627d2f9f5cf7336badcdfcd5bcce14f7b84d74af4e0049c03f83fc60b618fef3bfc6af8685e970bc37b4753ff993ed1e8fcc3cf1ed89d5898a46baca7265f05f4d27ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedded373a39b545738371499e3b7c88d30e79444d82ca235bdfa7701624a09c2dbc66beddac15c6c24f68fc73be9d8aff6566d44c49a20074d3848a726e767d2713be1edd4828eae43df7860b9f53566c9932fa54c966eef6af6d990c308cb8a65ec8ced728e371b5e7c17af8ee9989f9d5acd50c8ba7085e96cd3de98c978999c37195356d0bff1ead768647c2e4ca6ae1d6bda36ee03fde7482dbdce78ba17c69848475835a1cfe9d08b27ccff0185a7ca417e3aab7d068f75140c37d269e50e6b458177da6f94f3a5979645309b7b0ebb0ea1ea68e46c48b25d55203da3e4f5761196378863c4326d5ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = f30ad7111b74ab835cc8479a8ebab7865fab3a3ac845a332be2fd0c0635d3ad6768a4773ab8d3ebc08a0d7f772ff78ae9d9db5dd1b50e877f4fc99e10d1f8bdb9fd9f0173e4d33f10a1dbb0593fb330e7c1839e5308563c938695a0a8c49f6e08ca7f588bd4e6d9e6d5bdedab425c15b47db0b4f73d33530255d48e73ff2d73eecaab6a2543f651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6ff7d1c23885e224edf14b4933d7d041af95144a74a54d48785ee16175addee87e666e36a455bc9d1c5d612af2157aa3dd288b4f0aee79668bf25fbcb82ed8dc69e6a223a703d376f387740618ec46ad8470e4ae5679b34d2b4381335d8e6ef0282a65702fea861777d597a3b9aeda67749855dba05f36831ceed1ebbb427d9fbd62f9c7f1a99a47c94e9dcba438835f3e053012fe80f60ec8271ea64ec79e8b3563816a3fbffc5e034ae14b8c94c9fb3392edbbb8d4a33be98b21a5d0f53b7830bf482fb9d89b46b6f32555ba5833717ff772edfc624f647e6b87ddd382428552e58b80a76f55394ab3815aa014d3e878b74e722eb9f7dd84edba988b53e04a1d677ab6fa1b37d35de440b065e46d15c466ea340b4658a41a8860ffd6c48f9240dd79f988b831a99d4234ecc8637a658fe6effe849729850993ff8ce5523587ee408a4bca64628487ea0ae66ececfbb9d696d799c3cfad47a5a8b495766e8bdac931e0dc718049760f880841d92fe3acd56e5e7378bd0b156accc3ca6957ab22529673a59bfe87846c553eef6b9c6c43de841eae451b881b3ef6e44ac71e8858eeaa55aabd45281b563463ff45354df7f4f7eba09dccd23c75e1cc96776ccdb09f866c778ad4bda43b8f464dd9d79c9d919eb76084438413573ea0adb61df6bd45ba0f768f4c68d81134d6951deac5c2f6b943f709d1374b61957bc2dad7c33576bb68d265c7ddabae2788c9e015a9600acdf9a6fee98e5c0cb48d89e3ed1ef97d0fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794258af77a983ce88cf9c18f8535b07960c0fdb3014974883529cad33aa6d4370b9f6778689937c774e74a3aeb9f2f5fb717a7b73632cfe1f8c33f499674e584dc7f48e3efab8361fc0f723ad9814520038402169e2e4ddabe816a58af87e1cea37daec759da34e24033c194fb2dc0a6909a9eb9f2d5178596c813adcbaa48efb3586b5b6963fd445140bcfab6b439093fde9ef7852ced619e699836a692bf44ceb23cd1f6938222b4b83f4a25a1cdc9ff397195bcf5dca633a5faaf14feb1225e8f887c5ae945821f9b1150bc1d35dea7547ca3386bc3333fcc58c63715d8542994ca6dbd98c1ed33c0c97ff468bc1d7f6aaafe8198fca821ee5fd2755ec18ce0f88cd37fb61581cd39bcef1ce95af498bbf4efaf77eb780d4eda0959a388d7af90fe58a658f9184b763d3636b065ea90e5a9724bf6f2c4869ff14ba816e53d6ec32ad4c42d37e61bf15ebe863d3d9167245684bdc3e98673c668e579a72136b6d35f225b49f2574629863f99045fb90e8ff6f3f4fb5877176555a078b82ad1dbc8ea63a2c9d67f24df6584abfbc473909e5dc58e9bc47bb99318f98e6f9db377eadf643742e669a94efa90b26723af4cf6bb644476e9bdee7b5088369fbd737af0c4ae367313c699f395fd5c15ce3c38599604390c7d9e1a588ebc36ee208679510ecdd0dfcf6ec46718c748b5a4e8bc353b7628e95b77992859cd6ff15a9077a37ace35101554e8a3932a9b9e38b9ddbd3484b1b977d5305db0443538aa551688da094e6306e7842ee6a753d5efd2a89c23eecb2b26a6ac90b3e890466a557394c6fda07cb671ae9cd2c43621bf55a99a98392b9cfea6373d5be36dafa78c6e93ba7573b429b50be5949a254714d8fd721699290b5e0581b6af396879703aaf4a9781268446ba96a083dd9fffad250c793237744e36bb0d3d752e1a6caa346a2fade695d49aa1baf535c6449e8f4abf95d79c0b99b91bcfe926e3de6368c430a886fbe5b1938d5e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c5dea15b5c335a04da1acc5bd199e76b477938ebc70014fcdbcb7386fedc322eb17976deb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 5987636a96b2647f851f7d3a9bd36d85e966fda580cc79af6987fc2a9a7042363a3e4ce16dc7711fdd6fbf956dd16f6633add26315d8b8deca73cbc853f6fb24bdfbff84d4ebe390fcf58bd67f62d01d44ab3ff25fb36446d44e1c8e71aa67c415f96db1fed9afb3efd00631c0af3f3b6c9c03cfddc3eceba603df702dc9ec7471cef699645dbb87d43691cd59065cacf697c63b6bc98c98ed3ca56f07c34a5b1be0cbbf63bb75399d26fdb399f06939b15df58448837e0d443b8efe32c65bac84efe66c88d132875fad888a1c53aea51661c135cea6956c2a4b87a53baeff7f6fdf09687f6cade7bc9ef5ccf5dbdca95a0acc48edcaf03fe59af5b499fb6e8643c70803ba40a5938b5ff433053bdec4b729744b575d66972d46c6dfbd15fe4bf0c4d30be99a8a198b80b99ec939791bfc8572a4fe98d47b018e4c6a85c39ae7323cebbf353439f3a6ef0abb687b5ce8dd06b706db4350fc4a2e86822937ff49a7d9eb1450c2995d9c8d9e77e676b628aab13ef475f6d2831a367d3948cd0bde43fbd865eac55d5e6069893d0aff4a8176a3bedadc6065abca0a3a2c3d53da2a3bca6a7088f39d9bc8b1e685b6771f413aa3b2ba4673b40ecd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a9fe34fd1cb5918e9a6529daf53355a6483b6aa9d9bef36c76836c77168c679757f04d4a8528cd56a9e1d036c751d4ba4dbec34b695caf487866dbede555419678fd32285490a75fb6de8d3c4d539adc4d9ae7e4530e6a6fd7e56b44d14117bc0dc45eb319a1f85b642f7ca7a22e64bc8aefecaee4a7c5ba8d7456cc08a883ac86110f72b81db225e49de82ee15c4e894605d4596d76411c6ca3fce1a5244775af7baacc54355658288eb273bccab53f6b424db5643c86d41d331bfb85a09dd62bdf7e38fae724dc4b7c3498a97dec12ff5c9a1dedb2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8bcfce68b6b8b2f5efad7939979593f9fe9e1abfc18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01b8d65c6756e6ecb64efeefed0acefdd45fc51cef52bd45d9ed96a9e77f10dc8e8349b5daa7f3a28f9e2ee3cc0379942fc47841c8edf7a94ec704dcfc2b737da7f54873e6c2ec3e2c5e6dbf7cb4947fe7cd5bf3e55ff122854792afcb137ae236677a4f4f504ae43bfca3f5954ebc0d676f8a3fa758cd87f806b59e6380197b3771aaffba88b64ca54fc69ac8e2b79df7154403249442eed3fa3ea25283bcded4c8b51a7995655d4a7eeddb2ac407bf8ab2b8d34205ecb91f6afd65412b06d05976f2e68ff465b846a52b47fc6b58430efbce7dfef9c74065d5940d2462f7d99d39ea5f62b46fa0ef97f2ddef5183c73c3ccb63c564dbc4c1c60877971fd2d9369b761ef9da1d60d27d8f0588e1e68c47c4b68782ded2f2765e093c94f6c43b784679c425728778d825fc5116dcd4b489add6bdd9a3e65b09644d5a9a9746df49314c46940de8a6d5b055dd7fde34cbde568ea6fb9bb56c8c5033e42dde9eb2b3b0c6b8bdeedac8b799d9b1cbe894b382e6fca4fcd63390cabfb4e5e6fb18526bb45a0f9a6aeda7e050788cdd044248839d954594259b562317cb173f73b12b453638b70cfed85f5ec5ac0b6cdd15c2191d3e92c537510ed8adb7d2d97f5548ccc663947c3dd959811842b63be3faaf4b1b5ae8f579edc4cc331c46f748fe654e1b785bdec07443aea206d16bd670d81f8a8373c68aa36ffc59797ab3994bea35ce894467fdc64c16eb5d48b9a18c5544ecd820479722795d77c85f161b865dcad1a70cc9c01ce5167aa35cfda147147a81d540346489dc58926c975333cc3d286b4c52aafe3e6aa6d32f5016b7e26dcb46669c72c453bd745632e87fbd2da7c1ca87318276ad21ebbb6d4e9ee2eaa46a733e3934c0ae933950da8fd2eccedf39e9d7e8a6812897790f75adf78e6edfe757c7a0a489cd8cd95126a569af7c67c03e7b146743b0e3fa687fe03a1369822dcf7d07b72bf9e177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516d6ee5c724af7dfd504abde2c8f6d1e8c5f37e1aa5652cc5e5eea6d15d4331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = 3d2e99c59446aa08c7647cef567ac35c18b82dbf4ab1d5ef2ce8a79bb5ef432672cd0efd23a5750e9c9a6818b628a49a8123775883f3b1e63d902ea9dfc760968f7cfe45f668ce6e889bea621736c28c8acfad52f8c461869eb3675da63d0ddc915ef0cf7e6fcfc4ddb52347b12486452f67bea46c1b778a98268481155c53b7fc583eac2ee36fb72c61b70f73d24e9ab8f8f612afec99dbcd4f2d9d2af64a08bcf7bdefefb7b9373f8a84242aebad24c8dd2ef03b3554ad9dfdcd28e04dc8833a4b60eebd7f9135b4532d9b662f9bef0ba922cc60e32954096794b7248f95be34144bdab3a8c2288a6065e7adf5049e918b3447bce56bd462a204a6d8d680761b9e70d87970ae49dbd45509c6e69bc34ea8b876d30c7a2f5e943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397ebd6694cf0cd7caa079576835ad99186ec79fb660843778229b2af63d276c345ef8c420ee395455ab47df4660abdbd35efaa7f35af596750c71c4aa2754afdc48482bde8f2499faf6e584eca38f43ec571bcbf73bcd1b34995318e908979499f2bcd6939b81b5e99fb58383259f8372aa2efb6c8db0f58743e8c091e7fcf47302fe99a31c9f3ba947871c6ad7178f4644eae1c567f8706b88f34d473a646173a58d559cb5d3865f217fd99b78cb7d636170cd6dd1639193dcc23efccdec55c46f84262f59d1718c4746f6f55d8d22849935b3a32f65e80dd7b67cf496c9a9e89d177cceeda61382e718b1afe75ed301e667ae8aa36d93f98b2983054a3824d74d97e48d585d4f88cef4e5f8eef09f7fd32df9164fb34ed7d68997f41266587a367b067284f359566409f7255c66bc7c79e557574460d792f8f36288a432b19f597069183cf8667d5eb76c4a422dc8a034ef7b589792a0d43cc89d11205cc7f6eaed24ebcb5cd90a74d5263e3c9d613a5d1b5b7e0a8c59166e1ff0fe4eb4a9891d49f303967ec3ac40fee45e97f4e8af9dc6eab8edfa7dfddb459b66b654c9cefe039ce07ebb50e54ebbe386ac39473b9a6a26f0ba37a9e55bf047ed33a56eda493c26b6bfbaefcd576f3b28f54d84c3e8e34a23b3948d4579d1dd3d1706c835d879787cc5964334e52875836e4b105fb9abc6e3bb3ac9a65ba8f3957de3bbfdbdb1741f1f78d527555e10caac5ee7f57e89a5215e4716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df86f81d55e5e52f9548df35be6b6925063cc393fe09de92b6193d6d0fa0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fc08ea403ca08684a419cd4e6e6397cbdd3b78bfbf3624b89d176f87d8f508c9cb13e6db9c3e94ff52a7b594e3089bf965bfb92b94463f2cbd92444a898e54410990c2d5c0199e6b607d59c2087cdbeebf06a4fd05d997bbdbf89b0bd825db84f7ef3c96da5c64595e96969097b8b9a28c5adbe360942d3f01039a0ada6e64bfed22794405a4d143edc959bc624619b964dc6b61aecd31dc99c444fd1ed67c534570a658361376378f8f89702e6e58dfe15996721258e846dee2fe0a3b1b4b888ce4c22b3c73fb97d84d64535aaf3d7929704738af9ee7abaebce5cd8c6d87295f849341bdf68b24a85621f397fce3ea209b308925ebd44c9d9019febd2844fe173392a8836876ccd9d97cad67dbfb55523cc776360facc4d337e8634f97647f4a0996524f64b0a3c6692df2b739a66a98b92ddd577dfe906b07fdfebf3605169d0ef37ab96baa1abce322149bf79fd25c3bb7adcc79c1a9c8fc5fc3d4c5f9fda48997bb71d18a3d50efd1000c4648b634778b7a60fe90a28cee631381b777ac0e858db4033509c66bf1bba3a68f8fb7f578e8fa51c7c87bfca883ea96a968d78bf41f983e6ba51cdd5617d9da1687e59ddb6d4ffb62b874fe56eca75cba3f9e9ed102037b2c57c7502a60832be5b49c87b8ae4fcfcff8d3fdb82e1a5cb73fb8d317d560977b24d591e7dcdc080e7a0a1d4d2fef4e6ecfc3b01f31b0affd636f9c3258ebfbf3d9d6adcb4c6ec2eccc7e9cfd5fad1a7fcfc363529fc90d76668fd9ea297cba057fedfefa729996bd118a30859eb59c16cb7077456b0b48da4757f23b90253ca5a3ceaea9b5f4e18f93d88df2f66b5707aa4f30f6b09943fcdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 576ef79153af43df940a29ec57f3de0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd5ed794d55bb26379871fa7692fc7fb61c8f0565916dc3d862afa61b346986697691de618575339516db22a3f6682be6cd5b8069fb5498aac4adadf3adc380aaea764fd8625f765f5d73a1189a7524a6bdd22d9a8a23bbc5d96c54b89b9f256d20f396b606ef48ed989bcd4cfb267b175a8b38395dc3e976feeba1967ace1c59e733cb3b005580fbf666006e93597cc5946fcf61dd74f6d33c3be33bd02bb0d356dabd45889ccad6129ab11fe978d4749a675c32e2e9bb2d78e6ce198bc5e67bd6069666c6b1ef88d765664ef75dc9847566e03ce16f63e8d10bf50a167a8abf381cb4cd7ae6dedb1f5bfad338bfd668a008a9f9354999949ce50cdaab3ed25a83cdb2c7cfdcbb3e04fdf12d58b78f0dad85ca97e3f64a82e79d26053da439862eaabf9bba6a120ff6ce27be4dbfac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd93d637077ff2003e6474836509c93eb8e4c9c77a43673f5d13c52b0d5a231d79ddf765e774c9c60f6a2f8be37773dbe03149a31e7e12f6eb322a6f34678bebced5bcc4857453858b06680399c69a0df3a9f96b95f5978437b5d4547d4c333e7beaa45232e33d6cb8a5e98463318e171ce54d686748979e1cf6de4a9054c38ade411ba72f77474b569ee0e1477705a3e1b535d4ed3b3c2dd43df5e7b23035239a396950d5c00ca332d9b5c99ae603465dd4bafe69966882bdbf8f11e71e276bb36f98dc3dca74058462f2caa4d5a9e60a9ef848b6c519c45333be8232b900d9787dc78a68546d336b685d64de3169f3f8df99d34c8f67a3f496ae4981a2cc94739cf075343df4f31736b42d9866b0cf7d30bf4faca9830912eb24a1a518eede07c3bd3a75552c169b605635323d9cfee4c607c656724b48f524aeebef5e394ee538ddaf34d864066f7417b1b67969afc03f9b85265e48aa4d9bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f64ce646f0e5d64066403afa8f36b7c97eda50fae3c231ed3194bb188c6947e533b1a173cdb0ff6efcf7720b6ebb40e7205e98258fb47074e633d955d14589bc566c9fce9590c6e41f9c662bab6dcebcea7b0f5e8e47dc27ebfee2a098d62433f2fc336340851e2e536e1bfae8c3bfb58057b5e3da8fac6d2c48ccfadb9f6455549ee5ce5f2369f5884fd5fa85415a9dfabbeb76eeaba48dd5a0c35653b46e92a7be08046bca55443fa075f082f70e846f93ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccac9f446a09c8be6653f9398b4d5540e8544d56d5c88eefdea99344b747304f56b2ab7f5f1a858eb7bbae293b891cb6ec2d5942204455cc7f6c2aaf3231eacfac678dbe1dfea839520327fb35a448ed3944bb07bd2f1eb9fc5fcacb3fe3dd58f15a9feef5d9a98d19e47e37fd3a9b84033e72d1deade55662b02a9575ce3a5d5b79576cf5c9d46bc5c766e4768836f787cc6a771a87f518e7c5a2f4716f0d7900db8abc8a630916a269bd80d01fac428ad2c474ad28caa73a5793bb0a75949e3debfc4cd353ab92cbf3d79af8235f7e58f52f4d5a70b3fd5eb0f6f31dc43e5fb7c27bf687028e709f2bdef4175753687a6636ef32773dcd6fdc752ca7ad6344155bc6401dde1c18be1d154476a4a63adfae5e36bbc157a7c708fa1b75d6f12aa8003784937f84fe2bea4fc7daba9a39d0775dfa293f9a29a4fa47e2fda54c41e45c6696aca509d09f4f618164c34f78b5b385750ea93d39abbbac58640ded9e5b5f45a37847c78765d83e596cced12305e893ea5d98cd321fb5810b2faf514d6e548d6569c53750153ca7b49dddfae2baf4ade47eb4c8dd5e29369a5d1c71ee1ba62ebf6c74b456d03d832018cfca235b32174c031c53b4c653ef2d5c643fe8ce05676f2878930334c3cf84d7e3b73683cce303694e68bc7f95b0d186acf62ded95fb6ce55acda6743c761f638f4f978a09d4737fa1a6ef3e374fd59feea3367ca9badbf79317d0d1a3f7a0c6ac9fb57d3f4ebedcdcc47e0ce9654cfc5cd78200ac77b066b019de37facac92089dbc9e593cc243761cab9488e8e8ad7ae680e601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = b70ae62b25c460c63c4d18ad7344f2164cde26ba99540d7426acf12f2697f2073bcad6ee4f6d3b18b575bf696d7feb87255dd849fd5e91186053bd5ac88f81289dffbd1672b3fb45004f8374e6ef1adaec1b93af018cb6100d6d054e80892e6845bf9f9b64bd478ed657ca30a054bb1ccde61a857edbcff0823e70d1cb96f3e8f3663e7cfee94eb1a8ba6b08fbf10acbe46f6c7284b622c3e4d72469ebc76d3ad8cceaa93e08793490fada744d8a1cdbb066b67d145eaf5a6c477d2b90b68a3982c7dd32346cbebe5ef09736b29cf3cced3d189982710e350afe3c7eb95d5a0389540ecf2d0cbece29d8b4cf8e73e676305bdc98f7932ccf46107ac07b37d90c2779ea2b8c988bd84d86bcc40496a1c44c751438af5951adff76b264e4d4e37aafa3a1fa5b8fb00ae2bf2ebc76b7816aa3a1df24f446aac524a6a41aa3411f0d609f297e6a9df6f96fd94e3afe5f9e46f91fc2845f9e162560512d4ad4bd3f04e35af7d3679a6d5903e8c3e2663f9e89791aa8cbf1c8d47f3ae59de9d9d01a3eb4fd81aa3db26b6b3c32c7e72b77bbabfead525dec645b63828842ea7b7803f969984dcac72b56f434ab7e2cd9b4ac5368dc559e6d3c5aa471cd673bac5abf0f858dbc77fe1608ea159d94f3be44d008c06cadc36bbfa61053629f994fc233a38576a7832ff9e79685c2147b7b25e56493c1ebafc087134f132f758c0db3cd1d80466eb24974742c2aa017ef3cb19c868244c6547eb6bb03ee5603b46e58bebf638fb89f4ef428ed02f6a1da73f1a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533e6fb8e3e889e6679251560d0fbb4f768501aebaffdcee6a244f2f48ccd8aedc646beeb108dad2c77a2f30b8cf425d84e5c9f6568f4eca8be8835a81a6c9833ed9c3c596417657657a9c85a13a54d4cdd2d4f7a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9d9fab3daea8c47c89d1a742cbf4352b86fa612f6cbbbcb2837f856b2bb3f176ab32955c97bdf74723a50883daa94730f998ce0e04ce1e6772652ff33e8b96c31481be0e7c68feaea09a3e96f897b70b969c04d6ba84f4a0e8aea4b45c6206752c075e2bd3b3abc53f9aff842a459a561e8a10f87d8f1cfcb04e80ec84e738d6a04efa30f9b3b9af587c33297bebf8778ba6d596bc3095439ef3448c1197ed229addc257e8f6c59c8c83f34a74ec489e7b27b46cda986a1857315a1e673cad46874e757ec5ae71c860de0b5ebf05cf6889a170743a2745db19f4d6a784f7421a54f2ce63862a43c6fce260d45139b7419b0538af3ea0ac78584c3f64ccb5e9ec35acd95ceae5b436eaf82fecfac8692ff4fb9edfb0a955825f8ae41dd81efabd7e599518dfef47afd8f4daa500c9f2566db93827d7450d82685f93dba332cb0dc4cf746f4614eb79efe9eda4bbbe3fcf07e37e21ee5c25f8a96b67d6fcd7ef620abbf15fa572d73b24c5445715c77187a1baa883a714329e6e9a10dcfc9c84b2c5cd98f0f4fc4d0da77c44845b55d03b8cebc587a3f7dedd34269430765da39550e2b78fd7b97cda1f8a5d8653b7bad5175ed1a9285a9c1a77a9bf55d1b8533a23e5a82bcf7e76f0c52f4ce93db83844bb1666dd6ef9881aedab4523acc1696122aadb0847410b19647ca7836345b2766d9d5e1fbcdfb5e63b0c4cabffa0f05993ed16b89ece4d33b6db57ada298e453a4883c7b6c7bd2186718eaea29895b2c066bc7af8969474320cff4ac3eb1202d4f8047bd5f5fed92b78357694d8959991e56b6a123373d0d463ccf59f78a3c2e7b352643e323e9af2bb55726795fd914e60d4df243bebd7d75e03eae395e8faa5f76fe4edbc812479b0b79ae16ff5a07363080d887fe9addf37b51b5ab7c3e878d21086ca1eecc47d877194cad6e384a824d3adf05c431effd485e6acdbc946498a2827eebb9f73ac44f4f6cac3146faae172ee03cb4d08fa95a8ebca35bfee400ef4921a855f5049447643c391588455fe7a61dae31c8fb5c159c928ba43499daee2c72697f4bbc29cfd25fb05d83e98e7b62b43b9b04ed81cd1aeea7395246cc890745f68f189f22ce43e5f5cec76692e6d937faac7af3abc5480464f9bd77c945fb15bffdc665e4caf392d1ec6c81d96c33175f593fab3cce9c552f9f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = d3539de65fff480e89bd6c46246ec8105549371ad9e8ccc4089d8a4e433813f73e3ae465cf99af311d5e6e4456b899777236466f05bd37ad5494b347457439cc9ac66557580ffd49071c7922f3770c5ff0073e39a607c8019b52708976d184949cd88715fe8131fda6c91ca3878d863eb9be264fa4b27a629dec949e65fd8b3c86894fe1ec44eb637555c70a8fa503412a87e853e3fcf1a5939fd7b6ec1efb26f4e4b157e0a46390970f5a95fb8cb68e358379330999cb6b93527cfbd79b134022ce9c922f64109dc11c234f808ccbe17b3e032bea7a9465509ff89e2755ae38b9fcd477afe576bbeff18ce692b62fd5f61a59e644808d1eec0fedac37ad50a5ce58edc9c770444d320d97235890f2d630f86cdded2444356f906fb84d7cac3e7c1777d08a57a689302e99a3da4dffaa5cddec854d497f579365bdd1645706c744fa6ae67b563acce8d97e8c626ae63c838d663a48fc11ba8f6c1b95001f61c3b5679ec6c662cfb8082cec39f6c732dc97bbdbbacb133006a7c94de933aa29e5691ea2258f9769637a54b9512d8a4e8217eaf50a66ac5f30134ebc5206bab6ccdb29776a4b73de59f7f988c4c7fd839124a9e75a2a3d3b2f70edf3a2987d49bac7524cd69691f59442db348243881e04b8eafeadb4a436555c52f207fac345ab289de1cde7352127fe8fbb5509746ae97ecf0f7f416c2482a38dc34896fb313c9686d37ff0d73a1f2e6ffcd936d2a4efb5bc77aabdb771354fee3dca172fe51464eb5124386b835c2264dee2f9b5971ce508f4edee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfcdd5ad05d7686d53257c372dd8f79e89669284c76294aa3098462efda8c744bdb7305bde0693d980484139d7b2d3bf7892397b9f3cd31dbaf9446598dc886a5eebf0f9c39e9faa3acb9dae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd125dcbdfa360a7d8e4de5365013c819fbade55636f2b3e1d8afb2ef8bf5073f77500ffff2e76029569346266e70bbc82fcd9533f8caf60c4357eed23b4b4532f7c1e5eae8f468fd40b886116688605fc0db58357e7579c85e6f9db7d46e3d92314fe9f327ab53af8cb7af46b60e6fa6894599d9725fc3c2af36fb53a4592f98ef2a195d5ae75bcd36c30d6b76474f4c21a3d2c4e5794057782f7d34eec6c488395710d8f11ef954f9f743426559096fb2229d45b1336af22889abbb4639cad759ef8f2378cd1b1a4225c4e71c53691a9cc5986a6c3f05f0f53b4ffe3c4eb8585006c8667cce7b3a28c67439ac5f4cd8a6e93a926aaf516cf4f8a7c3e4bfab305e83def46f8ac996e50dacc42db49264d42ac43c7dbe60ff32ca605438d81f4b5b7f7099f48008e6dea2e63f5bf9b81f3e83e16472520e7e838f762017dc96b3ffe22f632c4aae169d623bce91bbdee3e9c3676ee645fb86fb0ff982e416ca2aa343f607a70405720e9c42ffe8e5be984042b37d5f76646dc4d0da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca5411690596fec28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceeb09e7a98fb6685fa7a6e96dcf7efef5754c3a3fd7b6bec69d46f134aab5513ca757aab9cfc94db64df5112dea73b7cfeaf7a0f2df59893c76da2ee652a4ac02348c285b94f16c671fe953e1cbdca32fa3ad85e097aea05cbf789c1ce4da099e75477ed038849dcbe9de489fab68f910bc70a3b8dc6f86e52d494fa077e86968e91b6ed1051b6d55449dc5a4434925caa07edba498a24b33fac6bad8cf477a99f5a223067aa4d9ea7749b834d9dd6e247653c6b6db65c5efb7ff3cd9cce26ed437268cf92753db34f743ed42de03d29f95e88db7573a43830abab80d5ce76ad551c5d5f1698df7626daa61c9f864ce725083a56d08d1735c5429bf8adc49b75ebdfbf22d996be7ccfaffdd43dba59b79d0bc5d456d6589cb3cd209f5e258336034566ae1bccfc1fb314afab75acdde104cda7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d6376ead075ed103f86d4fd55d1b3d7aa7371ae1a74f1a68d57a7438e4b5107ccddcd8c4de5736adff3e70f9aef01535a388ff29da4386b4acc073ce611b53c899352b5ab5b39bb9cd4ec72e72fc946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = c675bab636ac40ecb18567a8e6fbc63b5f32762dbb770a5d64349818ae3cd365c9684e726ab9e07e9a4c04796dbfafd616a7e31f7f8104c9c6aeaf6ebfd5e632898564d89b2919438dae308c53387604c162b4f4afbafaf9bbdc42c5dcc50b3319ae5738057c2f28d6017a7bac76ba523acc1c76e11d45c253bbf99463cfce584ece769707a6b35e7ee4a8c9f93aae6d27a7be807fb661fdb851e4950d2db33c074d307c8fc9c5e454f4ea96a8ac76cc30a568b4bc54f177e7748e5bdf7e4ef01569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2cff3a19a5740fc9b9bf18859efc79f9f9e78bb542823a4fef94be8ca589abf740d798d380e788547d8cba3fde5d0ace428c58a543acffd8333d2831857c378419de3696a3b11e683899ae31c4d513e9589467a3cf2891439871a2bf40feb3ef2fb89956d9966dbfd4a5a8d50bfbfc36f9a68528f0c87a5262a9cff24bee7bdcc9d16d484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ed1d3864b75ab26ad13d8ce83955884cedec4f58cd410344396358bd79d1aa5ff8275c79a289b385c788885bfbd347ed095fb0ac5af4107a87f1eade6fbbbbd1af5c9dbe4b7f25b7432c8149adc91f8c7616c7bee81e9a8f9aa4db5f91a92d922ea68f2be6fc440dcab5eeda73ebf55b1aa33e5f3d774aba41fc5f273f6220c8b35765f0789cd476bb3462f73c620e6c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a9310ea8c4c539f576c735068662ddf026cbf2ce5932bcbbe18837e07a784ce95cfc89444a7b03a2386772d9aed6b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f512d42c398f92394a4941cd470458726b76f39037e119fefb56b3e4f38c75204f88b9befc43fa48da56cae9c56bd03343659b4accf62fee6855875ac2b8aabe02a352919ba6363c6e75a8358e3f97396f40ab8df0aa33b1a79cae3c9ce40f87520ac713b0cfec9da6c5b2bab6443383279bc9f3433e418dc7bd5bf233d6e4fcafa90fda1f7978bc6a7bb809664783c36ad8e445d4964c8ec6e9616384d6d636f6ac08baec23d28ffe80d34ff2390452e90f9cfcd68c9892cbda6fb29c5e358d697145b1506759a2e37c6ae6c507c96180a312a4e7d9f3d815f3db90d05835b99dcec789e3ec8ab7dec509919cfd78df4135d822c539fa2ca8d9e6e9e23fd507457f7bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb579e47814e12b0d46e2149903fb5ae0e56a4fcfb4439797354e394175bb675c31999dde1bc56185ca7076345ac26f3ac0bcef11fd99fcf971feacb96558fa2bfc585b03d747e9df7caf7cd76891ef5b3ef84b988f2a407f5552be77559e0f6e3866f7bafafdebf3ae73e3cd156eb1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526dcffdc6c7a39da80288e82347a3330fa332e17ed903e321bf32f4507b16f3f8fa799f759ff948a1a951516f22833c0bb78e40495a7a5e942c7be7e674733ce754eab747e97dfa077f7d24df77388b6bdb807744db74612a8c7211ebe7d9bd949c75cd1c6e07c34f2e31cee577b3515556a11ceba712aca7f6988b3873705257cef7f4acf53eca0f9961ecdf0ebc784e5ff7c6fccd62867d15ebf8d650d4cb41bb7ea3b5657e6b6530db3959c642c2e3dda13a1b25377c4a47c43ecfdccf3607bbdfca28a4067095f541b359f2eb39004590ebba6d6db8fa56ea1343b824d1373f97f343e8bb6067f9b674c66f7e5c76b53653afd6f92afe3cc14756ffacd5789a46e7c8ad789ba106f37998487c2aefe87bd87c9388d3a6a9c18e5d5fbcaff7ab6e68508b1c98dfa30ce67f33dfac21ba8639e7f6d78971ab7f96dee306d3aef2f06b8a4bfe4ed45765f7ad5a7445cdea385ce89f2e90d6b54a3e9cb38904f38a6fa3f304037c4fceb9647fb7ff9e9aff5dcc951aa3e4b05dd296b71259650b5047c94faf696837e26baed18938851198928ebeea22758c6cac0906a995b1ff998a7a9436f6c2cec7a5fe83948d74509d6e9168e94262fdd9e6580c0a3776ae4ea95c5fb2e867b6e7f42cdff81a34ea88059d58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = 10089c8a1febe2da6c17ea926bf636c14fc59a1b79942cf48de3d7a06f3095437766139de109c3356e47d1f8a06abf316fdf606dae454e364e9c43a80b0bae7a0dd6e0ec3e007deadab7bf69fa5b0a8e66aaa5f0de263e25a36436d3a9783b96a763c93227f7eb65a7207b51d526c6183ced5147f316dcdddd946077b8ef6487b34d68b5994ece41e779896df7912c5d637eadeaccc07ddba31a8dd69409f8a374b794584de28eb890f651044aeb391a7956477b4373d7dc9bdd0467bc062d6075de7f570e60774a84785d9bf5a936811bb9adce79834a9d1106af0448e48d076e4c3a7c70e7f31dd475f06778eca68e413ed85abd92915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91d9fd28fbe8d99556abfcfcf3aab979e1f5c137b75586b4d419758ff78f2997d869be755961ed0facfbf6e7d6cb9bbc5289489df8acf49046ea4df7fe8fdcf0e148286a7d01025ea11b879f9035351bbe0a536b6a3144a806b8fac1389f59bd395fc7ab90436b54dbc9e66ae3c73a5e8e5ad5976f286fa9a03f6fc5fced0c9b63dccc7479318dce967b7d26f438a59fca38e5f56a5dd02aab7f22f54d75c49994dc5d76fc0c20e85b4ba3f84b9eb37745d1ebac3a254ddd899619706756ae7d469ee515d5cda765942dd5a84af8a894cab90a724a9559ef85a26d102eaa3969ead4e2c871a26dbe845d12705598fee66bf36f2bae3acaab37d4feae89a8fe2b93eb9b053d82fffb7b874f3bece5d2bf8f687c35e12c85fcf7f6f340634c21d7df005e03253764fe4cf0d294d28ff8674f94ad16b7d0309f0a62a42ba154e35496e9b2aa884bbf7b543f514c377f79affb5e7ad85d643ee94763095b2f36e6bf87439c23af6c56f87125bc7bac3aab31beaeacccd2563fb326983a37a623f1afdf3d7cb743ef4f89c37ec1881f2c5993667339e8f5b699d8cc89f3d02c55e7f967d3d3b8d01ac87128b85c465b285e6d86939da78c4dd48d9c39f9fc298c3e3eab8a8b26d7b6da8c22967ada0294696988d5d35eea0565c8467e914156feb68f0e5fae4605eef5ff64b587a99b88cb08f04f80cc89573e9d1cdd5624c1afc3a654b9aadbf602acfdd15c06d79d77afae8e73ca0c2e650751a68b659a569cf742c6f6d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1f2fd41e056ba02bce42d9ca15f5a241db89e36ed46986f691df70d2ee6cfcc9ff715975f68b44e75bcb98f5f1a6cfbe1e5afe5ffd7bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fceddee503966d9ee8a1993910c6ad9a6eeda92e6432bf6aa8bd9a603d4201acba8477d714d4e0e22afd4517a0a2fe39304a6fe9c63371f65d44bd95b26d40af3ccc487840cd4ea63bbb6e2dc497320e3ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef34be7704ee04b3e85dfb6f404dc4a771877fb94656d15c4324fbbda24e7a7c6999678ea0c69b2d7395e694c4ade0a5887df8f2087f2855a30273c91e3ce9a2c4db62a554f1ef9c282c5e0165d4c4b84714a99a3ef33504429976c3cd36a9782b1ffbe7a9f4d998ddd6c066016cedc03db90844b7d4f0ce5b49ccd578db1c1d9c15ca935404737094cf0a05461c45abcb81c6a19b3a0acce68356882b8ec3549836faaf354d3c6dd1b5f90a883ab1e19b9494cf6113b3d03b8c3ffcd53bcde4b4cfefc80ac412b6bc1328a4fa6fea3f46bc4bc685c7da985345ffaa2a8c9832f37f62c969ded64ea14d2cc656a88c39de03fee3d6a52ecd38f160a3f72cf81a03af4beebbb1c6c9025dcc51447a7f5679fb0e382855af9d8088b60beec59c439eef92f869c4fc8b66ac7656c386cd984bd7aa98a71acdfb5773effbcde4b97be9559a6cfe5ecef3549436b4f63bd9b8a185740b4fbe6e19e84dfcbd7ffc7f66c275439ee3208e4a2888b63fcca6cd8b5abbc14769be6ea74f34627b896f1e85c043dff4d58932c183d7cb4a5548cc540b3faa9c558e9889e10e7d6a809aca86fe8740bb6c39761bdbdbb0c76725ec8dbd5a46d074864dda334359b4d4dbc7c8eafb413ecf0a23deae9e7acb49c905145307ccc92fcad3c02045c973f564b68cdc1e9527b239c1f9a7f7235894abfac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = f39edbaed633639be737b5ab13fcb47e28ee6cb86c6a4deb77b85e2c64305f1584e47d934b0faafedf7c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab95995450fd8a4a13643e28edb6c752a8a5c949ede0e8743ecc064ea034444f4afb207bc3a16d66003589087d8bc98de6261a61b1547bcc94f1c009778ef3e598d47a48d3a99eaaf4ce33db9568cbf4bb61daadaa513bf82e35d6a52bdfe935d7bb7cb044e93ca33db6d9f97cfc03ec9055c97764e9684aab2609a1e12bfb365ff3c986ef7d6b5b03ae6f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824d1e5c6a6ed6673d8331ade209edff1b6d57a0f5481af4956eb5f81c956736df8e49173031b688a40f89d385a7719cfc21d3d0d7ac3fc81bbfc6747c60f4cdbacd37c458c50ede605cae67806a6fc32c759f2942de8e962ad657b51942b3fc8d925b9db73befd2c3d3c15d43638a3218de856d9bf43018b0d8679db5c3364a85b78d9e3793e87855b382b3456d3d8cec2c8fbdb94c6e9683fc6f455e4e73efd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be2bd9431ffce7258fd6a8673a8e5e1a9aec507afcf4facaa9e489d6a3a53235ed464d590d005fc958bf8937b543bd5a01f17f61afc810e4ebc815469e145862b3f38bb194da838c642c8e7dc7eee19cd83266df779aff197e73aaa3cd30869ca3bbd6b238f7feb4465af6d975b7ef55b4d5db20ee3a20872196e9bc9ecd64035774306b14d4b60039491824de253034323f55bd18e8097193d449a3ccd23e5ee375c7efb833d03a87a98ecb5dab7e1dd45b6c8d505dce8d8e9be1f1a7740d4981f3e339503b1a3cff061d484d9368b8b5e93d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e57d999f9d627014b34a7a8b179de0ddb76f994783b504efbe6d6971a8f62c04fffc23e28a55d24386c7895ec709389263eedd65c4784fcedc2dbe3d9ff8e9cb4c6dc0c34da9dffb69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbf9e7b3739f6315e8b093b98d39c6fe0138257467f93c76118ca748566d03c05810e7cbe83d6df889ea724948892897168adf421a9f62e44b356a98e394f9734fd7e4d33f9da534fe8d499897f429793a6c5de4919d3adbdb5ec60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f1157ed84064733ceed62e4d633d67affe2bd763e5c554fed405e5079becac5eeba9fe5f9db1b92a58fd2c0e768b37e826787bd6098a8854460d5da5d5744944887cbb194d126ef825393b64644b8c0b6cd9536be03d6c3e7e6ceb14be902fecec3456903f5b15e9994ee2fd7ff529160ff460c098ef92da1e885c2ff33e896a3c1dcd5ce4aaedb319f7597d9888097f1cdb68f999e42679e9dcc56e25278774d5ce861466a8197c4214493fbeddf848d8290dc6064a388634bdffd3befdd84a6c3fc3576345d1a654f3c1f9fd7cfa6b95b46d235a9a7f44a6f9558b02da451a69c6f6ce1981fcc5ee9ef91b9466795f0e7165ab4cc367d1ab98579ff85e68a3b05c7393e9e0e8ed7f2f8971003fd7c047019f6cf29854bcda6b319288944e9907985d83e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b96420eaac7bde6725c3903e5caa63961475dc0e15f67382eb113f48d5cda5cce6b8a7449ba5308ab9f2cf5c4c4335e2c4a3bf3e8c99787fdd98f7b69fd9436e7b4346fcd5dfdf7b4e044bdbd87d3e8757bb3878b60421ac5b2234864df888984898d198d012d35dd1f309163f371e444204ab05c8a9db00c4756135998369eb28e882ab3c0c4de7189267f03d64af9bfc3addc90e32b3f44c438656e5af61deb45c9677f59b8ce78dedcec5088ece7865a790f593ab49bbe5327718a5bda4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de14e00878518d8ffd321740f4d4d35b8e3a5b1c9cf18e679e957b796af771485874e5bf75f57b11f8ad9fe3b1d2e7fa1bead4bb25e72a6e93763776fae451b76e5a8e9c788a5c8d65173bba3d7b2cf9c8640f9553f56717b355843ab1dff7fcef8c46d6a8367ac7df83db71c4d4e0960a7b632eae2ab64a1754ef4c5dadfaa7ef25d7e9dc97d5926c6bae8efcef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = fc7dab814d5c4c5942209e3a78e89f67767e71fa51441d61746a74747befd554d65788a7f98db9c82cd07f6d91e71e8f3acc518cbd6579b45ad1374404284b0f1c370c63d62cb79a090e5b4086626e3d83ee7b427b2461394758907e49777a3fb69e9c73d5a23ef5445f24aba79b94bfba77507ec8509f9978c44e07a84bb9139b32fb97d5cfde364af098838c6a3c51ad244b540b90020c5a0defb1369e8db1f9d93a0cc43bcfe0d28a7889da51d88c7b3d1452d7879f35ae30bb263f524f9086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e5698eb9437663805d8e968d9863bd897744d3d8658e33c89a789eb93acb17ddc91ccc5b71c0eb9bcb8ea7485c5e54f8538a3ba801f4d2486414abf6d0f246e9aca34c87ed3d676cd7a54abae1c895c37b17844761816d1a67a5d04996d195363c61864caf95e7d4bff4ed68ca2ebd9d9d34f86d5666aecaa468587fe5a3c56434ff58e5c61094c831699c6febe941ef99f4de6b4cc602bc6fa4f2cff1bff47b4fb92d5bed431ef9f0b7ec02d07df49edab7acda31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114f6f417d9bb065ee0d3284b3295e10c7d69fcc58e2e13cb50daaa10cd82b7c87eaf23d63c6a966b4cc24334a7e6fb8c323e461756a35f2b98439eef233a6a7127a33b7cc559b477b59ec0155949f9a5fac973ec3255eb397f967955c1235b61af676429c94e9034405be47ac5873c9dc33ed958f8ca4f9dd7dcf9d07687132f89402d7b0f3a8086d77c3d7792ba25ba8db46a555be61b3dcca878ad6397974acb3812767a96bdef73ca80f1d83006e9460d2348c047ad61ff841ebebae58952142aa3491cc7dde58debbaa2772ec7cbff99f53f5ee978caab6ccd4bd751103e8b20e98d26a94ee99c935629394e6b80a66e4891a75b45e8eeda8a6cf8d8b43e6fad9399369023c4d677ce76fe4f85bd5d01b7b022ee5e459bc5c82cc9c4158ba32c5d517d8ad906f1297333a4d899cc7a90c28740039b351345bc7ba7eaaaf39d983f655384d238e569d497dbb09c66af75b532778b9b0a631d46fd13e6e5683efe6ac5f3fd4c3ebd5839e4bae421db5e06e33bec836876d8a8625cf2fa56c43e4d60a9f5ff1d9d5ea97e4d8436569d15dc7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dd5f42c5a58f0c8caedcac7c5256d8f3b40bf57b0566e6c24569a51c5bd722f79827bb00d274d777e56173c7ecb8766202376e9b7f27517bc4488c029b9b6b274f858344bd14c8837ac90879d312ff5a6de7bcb89ffcffe4da9fc666800f9ac54fac76ff5a42ff83b9d59f33c94e607aa348e2a5dcbc572d2a482f79bfcdf3ca4bceff148d9f5276b6072d777d63d81312af86f37ab14caf000ad4cb82769dc889dea8ec969f732eeaf717cd4d5cc276fc965ca2bcc80054c557c1343847bc6064e57a52764339e7501f88bef0b44522cdd60ae68dd89c9e34aca4efda348e53eb5c939651af40879c0911a8e1ce371d7ea45e609dc8ebd520c1e5f836d85ec25a1093d9467dee920984534c99dfbc7467a03ee5fa4e784586bcc0347412c48d19f7a4b95a22d98b49a2af0cd8ff72f09bb63bae94e4450c3ccf351ca6d2043a68ed3dc705cc857cddf5054a66e3e40bfbb47425a67eddbc4204944a1e379e25e6e462e6e13dd6b2e6ff399bef57298f2cee6fdadcff0c845a444594b3b6977eea89e256878e52c766a86a3fd04437c4e65242553fc747b80a5f76aded5488d4b81cea6d86af9620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d755fa3e2c6a1f87c4eff1f34bb9971a20f6293dffc94449b7c9afcb117b8175c74162847432fdc11378c03256e4d2b80d60fbc5deced4e4cd22bea801413d7a4bfe4bb5ec807ebf6f2536829b6f400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34ccef8bc0556fdd4dea9fbdb73193396e5ec1bd533c5aedb358969ba135f862b64dbda9608dc7665fc61ccd645f99f6d1835adc34386cfbfdfff3f83fa0da4ffb693a223755b5dc4771379317f42e4548ed4dcba4574410e4d9a4848f33499a337859c64c6941d477f70bcb5a653bf5726d2e62f4e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = 52dc3121c3e062ca9d2d7599b62b942d3fe868f9d30f5fb016bb30bbb7e109ec9cf44930d76757d16452634de08299f5c44da8c2a7772fc7ea0aeecd8cb73fe6cea8439fe9bafe4eab47ccb147d3ab2aac1bbbe59fc57b1ed434b6bddd532ec05ee77faebb4a05fad4d9c6abccdc5764e876316df5e57b9e25473dbebab8bd2d714807f1f224b1a4887da46d4e244fef17167b01d546b5074cb27bb5b6a365ba1f32ee7cb7f58ed2912f85ff0dd2e59e4499da9e31fbe377fee0b3cbd6fbb350a054bd79e841141febd2ae637ceea7d3057679c4ef20fabf3d764c158457e7a967cd4440d4fbfc2d09808296c1d6667846a8e15a83ce094d467459d80e038b82fec7743c7f7196ed0a25dc5867bb71db4ccf5c5a92955cd348e2d369db7b999708b38d6867b97975da73a63cc9fb9bf87653c5396ab883de393ded3d493443369a7c4f4fc895cbfda6f71445849c38ba8c9a969cbb70626698f23ff3e55dc58cf5a384fc784924d72ee9f3390ee793bcc2c49cf014ade44be5f58436da15bb48401baeef48eaffc95aca6d33816c3415dd3ee70ca8c947c7b9caf052393d3ee9856ce5f708bcd2294c4cc58461b379a8b3b5c85396b4e90b678ca8e7c35bfed2fc9e8bf346ebfaee6987b81f3fb6fde7947a1772240f57c1bec5654f7b0a5ea452deec6f2a7c27b6391c3bd582de9bae4ff038989c365dd8423fbdcd63686839f7534e49a57fd326c7b96806da0ebca4b7da889b48723ad977bb76369d4bd7873b5bead9cb08766702c9dd16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7e0d84f324bc16ad34800ff74bfadc898ee364faddae46763b0fc3a91be655eb7d74a59d3687738f1c8b27ed929a3dd89237a196d64a3ea58faddf59c4e7fe188feefb36c6abae572ea88d128ee34fa331c54ef5ead8d1d1eaa9f04f6efb2cbd6718a4bea8eebd2375b73c91b7248ef21c6bf7bf9a4c385ee8a9d07e44a50af44ff7a4a973d933899f41aec9d358f849449e7441c7840d0348527bf5ec4ae5558562f107cf3364d823788075a3e711d5e33f95e6bf0fed8435d88435405275b970c457abb73f6976e2b263f2121fa34376c3143e64a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb379dba32476f701c7af32575cbbcdbeeec43bcd8b550efc026d6c4b40ae6021ebc58b8e19c083a1a755e0e0c57be6cd929f649470e5f8ad8dc08af49eb68afff3388f205353327b484cbbfe06f36222867bdab6bb2fb4fdb4f60fa1b47bd47b4359dcb11a9c3adae91dcab94080bbe8e394cb988ad475ce22964739f05b5974d70ddaa7a4c0ff37e9649908fd5e17b77d926695c45d8f21d5e4784e2700e4b6119443614fc3c155e4b5e34dc95583c189aba2bb29268c44e2b6b6e5fb70198a4e193c0b4587ab19ad166d5e366bd5949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a0497e7b61dffd5b2a6cdfd4e58d5747925731aa85bc66ec37d3384ffc89e0ec5b4d2cb5442e25ac422ee2dd4b983b68a90bc57ddc2ffd7347f7952e4e4e64a07ae676daa9d239498257149c29aae940aecdeb47ecc354bcde26c3238bae5933df4ccbc46157d8fdc39ca5e9e6d80873919fd4b70391788cac2a346a1ad7fa92673532bc9286455d7ec4d5c93dbeacb7d7fb865aa1e4e3166f8ccfce4d431434fff6350f5e8f3ea8422b44cea3b6b39a1dba6c5f65e9de845207e29394f44228a983c3aeb1be39a96830af9db9c2e569fa885407def70f1654cf69a34c2375f2bb537f39a61935af753cb6ef1393181d5c9f4b3dea094093d667396552b2b9562c0cdf9ea43c54f99430a3ef10bbcc0d9ef70ae352cbecf9668e88e67a3de915469af4f63667665385381a45fb48176539f59d4e3be97383d9efe6c40a1a4d405fa7fe57d89fefffb3b3c2463e865beb47f833f21c79db60586928ec5cba5d5ac6b9c764c6fb6327316507df76034614ec354b38786feb660704a5de79b1d3399da5c8b1e14e6af4acf2d7a6982a338471cc88b28f58f2f3b55b05ecebdcc53a88f9e4c875f29ef7c7b547400f52bfe4735c59388c3d5f401d6804cf7c6bc3c51d48d70f1561ead8d5070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = f1b45961d6f16fc930a886dd4b79afe958e66cf6f22b16acc847ab4bd9540cb68872d9d95aa7619b88414f3e3051b7abc0248eaf745c7bea31b02bf9c61d5fd6a8e19bfde86e7c89aefce41027b19a5ac3e1d4e9dfee982505e9d46879f43c8721ef3f8916abae0d6b3bca9600a3fa67938015964b25b75d95788279ddaf8be577ef5cb1ff6ecfadec5500bde7de196a1fa5e87106649eb4f27ac9a9619e617d673f32454fe68442f15d9faf86a06d4c42174631045ef57f48c51ca6e34247f954e8373796a08a8fecc646b6c28bfd7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331bad82d1b66d708304ab884ec6c7e9ca98d7edb48a0bfad523afb098e99777ff05a38a35ed77d8bfe5b70346fb825a25b0962f0a8befd5c60265d925ac9454b6a4c02db9ae9a569dffc568e7da1bfc95c109bd3f16c79941da4aefb74ded63c3ad4791ce3ad8cdab1df854add8e4b2b1e64e65ea36cf87daf367f8767b122d4c2cf3d63302f341b5458eab4cd2e9547f84bfd50ac57d8d3decbf5387dc6d49b6e768f0fe223936664a46b4a2cadbe1b7a5ff752dfce41f38aa5b0b85546b77f67e3fd40f6a588e63ef146d13f0ba4e2889714d3d9835bc0d8e858864af9622a843cc49dd2b85e672e4c0b2695dfdffd3c5adf6544940ac77eb9aec415aabe7797bb4f8d79cf74943d5e90a549a78038883ed6f093b7dee71ffdf193a4fd7ba17714af6939f3b75db94f5b854d17e39b34dc2946eaeaafcf34fa4f1f7cf92495d471d6338206a1b8d8d6697589b5d8a2ab96df4d26e4426452038983e0efca14ac40170aad498d9c99f68e5197a0f02a78b59ed62413cd8779c59ea9864bd9c68e97d5f4179405d5a5ffc2f7315ebc1366a2641f895345b81e88dfd1683ec8f3f61f1f91723978a5e3350ffb6e1a89f3b373e62fbe4247684d01cb3f48b7abec2e54a285e0623f7ea5c383a0ada0dc3e5b7cb6db0a7c59043d9589e8812f63d1deae4e98d9fc029cebb58ceb24feb90ee5bcdb448229fa6ef147c5696fbabd6aabe7fbe42e9a671de697871ed720eca14ef6ba53e7ee5ba885d50bb3267d7865b564e10e8d8aff7f90df678cffd7ef93db3a6457167bd31b3d7cea18fb836d937ed83f20646e50ccd2308ecc6738b16f16954d983cc7a38d365462a564c8d54e7c29ec50daf373f0d8e34d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f891dcf0bf6eab3d678767e31ff93b5ba9a9efc54aac90bf89a9e37084faf6be65145daf15ef35dc06eff13f88873f87b17f3c4d9e475f91ad2d37dae7273402a8ed522b93762e4d46929e0a3e79686f6aef31e8447df3955da68a477bafcff78832f76b398ffec4ee2f2a47ec753510fa97bd5f4e11ec67a679d9fa3557d637c3687bfe4a81a6c9e983039d5cbd3be853ebc7697a8c0ab34342fd3561d8b3ddb0575ec6fc0f519d79a5c5a3efaeb244e7d70eaa585aa36ac24993c6cb463d63fb71f9583e7908dcc4c6e55ba3c03dfee2842696777989b90ac577bdcbce11ee344ad1478dcfa7bd169e1d0e745a523a64dccf8f03c336dbc9a87ce46c8f842479ae72706cdef994d87c562d3b3991154ee667d39805d3da2fd7c0d6d45c3e863c7f3bcd41b787d9de6058b81fc7b3375f9e85696813a589c75995ede83dd3a7e5e66a370c137e21235cb7785a42bab8a091872660d62a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b8544fb350477689adfc2c5905216a7ef07dcc84f723d34a3dbae3b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066084bf805856f67cb3c98a9f6d720ae9abd97cc063ea8747ca43ddb35c89478f0afe3f769b1b3cd961ec877f7d42131e5df4ee71eeea463877b2fa1e878a15310c6d42c26f4f633f867578a842cbb4783df39505ed3d1f93859930243f5ee405975e16fc705a63952bd80bd4b98e3388c74cb6c4d9ab3d66a5e54348204ddc2f9aea17e7cadc93e95ab4c840756db90ce2c49e96bd44d71e1ac098ab332354bb23d5a376ca35872d70c933875dffedd7383a41ab9ac0efac9627dc22d5e33e17d89a4dc03f08dfe80aa18b33bcf816efd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ed7e1a1ef59e3548f391ffa5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = 0916702015664865fc8dc941c1cc6424693026ef63aef87f3e0b7148ddb8174d77dd68df8c5b8f8dfedd78cfe7adfab3c66afe6a04a662bcacc74db0eee6b08dd3fc661751c0c8bddf0cff0bb78691a68e7ecaf5457a42aa0c3b16ee77886e9825fdfedc88d4161a3e80bd92e897506b8333afed3fd9ceec943853f1a9a44f69f7309abde24fed60f73e41538cb9f83e40bdd4011a94a30dcc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29caf274d759906a9044ff575f95df125f542585b9feba4368598c883c65130d48b7c85e1a46eadb0941e64793710de704d4bbe85ba4683bae545b377275576507389acddb0de9a6d92de37ba8a91aab33ecdfec34274f3c995fe4ca8aaac9f6e7cadd831751000bf7138fe37fdac3ec38ac29aaf5d2d9c514937e4386a0693eac3affefc6f7d2a50476493754a47f61c7187cab94922bfeff2b13f228934783cd56aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c67189d5456d5501646dd78aaef5bce66b25d8d620db0cf9e4216dad476566ec344e7ac234597a45c8b5e9b4094fe5ee66b8b79f69cef848053c50b38c258e38ad41d4e9a1a50e997fdaf1f9c38a367418c84f0cb5acedcae239f91c3f6aecb5d700714ff609734dac77fa02ce735245d06f64aefec7737ed77d5ac9d876734635dc7ddaf8105477b18c681fd779123e937896f4007bc729bbe3352f9915d16fdf3367d1acc58ed8478a9f6f16b8f6977b770819796f24cad7ebe538cd4ec03b8e92f33f3c68a9f280bd245cb54393f639158cb098b7693d6e5b92dba01a3838c08d6b9a7fceec7689e9bac793e701d543e87a880ff9eb59743888aac439e2ff2a5fc33f5068844fc3ae52ecfe80c50dc3d31585af1b443dce1a7c015ceeeb45f6ee4dc740cb7e79b4f8dac27c1295fe167665f809959a5494c6e3a53f9d74f6e85ba754fcf68d999ce2a891da7cb6903ade2f576f858a5f83ec259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a38979e7ebd7c2e8d5f1bbcec613fdaaba56fe48b3dba3d37a295d7a17ffd658f34ccd49d5db5ab94d6333b149de7a93906fbdc59a3f840cf55228fe9a2c97f8a7d385199d57144b462a2338e06e51e02bbc53d35412f4f35e7d45e57e54e4c9e0a47ca8ee678595bb690a6b445abf3fbbcdb51b055402a9a83f29691bfdfa500c9c645f6590de816a7a9e3f593ffda693992d530793382ba38aa95e433585a39c68c7026461fafdd00b365ff2b67a93eb83437b520716e961233013b4ecf8dece8f86c6b8159a65cb97926e410d24b1b21aeadb8fb72e1f7e941846eade6d16f3b9a63b9e688d57a20aacb98f38ed9ca1c82f307e3cff364dafb2b78ed999981ff6a0a1ee5f3c3ccadcabf42b886d13ff9ad71e3d63d8f68c56913458ad32ad4f623d845a1942fe68b9384c3fd2f62fe034c8e6caf3bb6799163553291ba2376775c4a67914f78bb86df6df18aac6c8c9e6e77351dbcf8ba7e06d7ba0df874b1fefbc519ff2794543eb6db3dca5d93f288220f83b6a6b456f2a3bbb8d9af288ac08b44baa5eebccb5ba61a6e818ffdb7cdb6efdc4563a6b4b4898d58f08ab01e7d2fc0e5f20d9f02a07e4de66c1cf133bcefdf77f84a5c1876b7aebf1fc5a82555474b70443bc59355e3932d21ce4888cf5ea5e7c69e8d7c30a842c05d649eae620ea315e6af0549b59106a6e1fe56d6c4657d6f69891a7449a67f39df5e37e8c3efc2994bb1bfbd8cc49edbb36629fdda37e99414a33d804acbb1a80da68ce289cd975bdb1a9fd38fd28e9be8d90fc1fffd648331699724b76d59d148d6445acbcb9b910bbe4cd0482972858b56541596b5b809aadf81657796c544d0fb9a6eb9160cbdcc6445708e7e051a89a8893dc03d7e90399f860b950fe66495fa9f829dc78379e876a06a1ff983965d67f2207a60643a6cbb59be857408e9dfb87fd54d5137ee8e6a02d36d3e29b4e970a9ca5f49e64e39f70fa5912488c99df8daeecf0da06c811a38ab0cdd64e9ab2f46f8587f7a099036a0ed7ed71bd4ad1ef6919146b4006b1532eac78fad59a3f5b9eef5c825d6a786949dfbf3bae43c27d6db79f73635dd64b361dfce5e4df9808ae6b5ecc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = 5077fc2e47609ecb47db696d50ee6e5444ec0b6edca0293c25f69d027a4b7cdbd8c184a68dcbde892f393ab7b05ffd8c471da0b84c8c4cd5b783f7e327e9f5959782b7ded6b08436861a8fb3cece2f239f19a73b84966698d5fe3c48da7db8eb54ab76e639f9e6743c89bd5457868f003e74f9fd85dcbd5816c8b4803a7399fec0f2cb3765e84673bf4fa32838f7199a8f738b89334dc6f391125569b12a670cd37cab0ddbc919aa4c9fbd4db7d6973681b696b3397e441daca91a2e6760c4ef510da7bf88fac33491383bec423734016cc8ee4b80e7ef5be58fded05439b9dac5fd34d193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f3adfda9c4a641fc36a1289640a371ab965b25383b800e7834fb4c3c3477920f88f8c3d5031a7b97b69f3eb48780d3558c7c74127e815b169e4e9a62a36e4610ffcaa343e50baf698d243ec55abad13f9cf8fca935094c6795489dadf303fcca7f257c7d17feaed4a31d9e46312bf1b09b38326aae0e9e4c55ab756d8bdcd86e510eeef572c9e2ec79b620af30e4eb9dd15fb29b775d891b7025bc89c0dcaa0a18855988c215c74f06b369772dec0f697cf8db4c10ef5f1d0e6cd21e54f5a5cebdcc4add13b31a63336af6f1f2257838be6ff0f6c07eba6fe6bd58a53ef2aa88629024f56017bbef68fe123365ae47d63fa97278cfd63d3860d4afdbedaf76390df907fa3bac4ac08614ad169dbdc6c855f4d3b292a8f8399f3251a348cb48753ef773570ab0076834177dc21dc7a356a3ee5b8ab51e9bf615f5689f6d7953f685aeb6b99a8e5b2cc66c24f65d2ec64e4ee88d4cd830da4c61e16ad33e47e8283eb5b0c5d6de09f2bece9a866f4630ba91032f6f6c2467c9fbf1483bcfc97af2d8493f9ef8b727637800cf6c3a996f5cf6755e9f47175f4dc85c39d22a8254e742452f9c975b467ac945694ef333eb578a197f463dab755e4fa174855904c7fd09b2003c3b94bb41c4559b46dddf7a73935fde5a39e47bcd4649724e942c3b66975fd60533ce5debdcb5ce369dec82b8e7f39637b616ad86d4aa87630439d81fa55556cdba1e734a23779d7c5ddd6f8d103f6b560fa79db8dfcfb3aa8f6d7fd6cf5b8f27685166e8538a990df66fe57c5c3b3a354655ae50cd98bcd7a3834ded0c8fea1e74795bcf3ffb8c5494ee4c0793cf03063794dbdd341ad1856ead8aee7ea89b7b8848fb9a288bc5be3180db6ee72f4fd929b628049c21cec8315d4e0975e1484e7b552b6ec91dc7453ed532cbd11a93baf29cf0512558bc1c4c4a07565779b7fdbf6083a5d6e1fdf24099c5751a93d624ef918e6ea8da87ce2ed5715a67d0b969d8b748a46831ebde99eb5cf8b634a82d8b988d2a6d5c7979441ddd2546957eda9b1573bf534b55302f5253d768706c8ad4d4fe2688b40965c0dfee51be4b7625e9fe79fa40fa8cd00a3e48125c65e94ecdb86aa90b1fd99e2c6c4c0bbc96fe4fd0734873ffa6d6b3c9b4edf85b7ccbb5c7e5e923f45c14a5aa146f003788d4a76df1037195eafe939cc08f56c3c264d5d8de851249496d33421e5bc386645ff3a8367c3bcfd064fc8a6fce1477f0022d87693c60e3a47de467d887473bf9b68c22699afd3e4afe9dea0cda51fe4340e4e34ef19cd7a9c7a4029d908ad3f3068c95d59bb04b0ce2aca3df9add82d547c99b8d7c8e2efd83feb81125b41f57a2440d6b772673f0df86b5df4685dfb046b53d7d26b6bbb862d64c42e0f9d9e813391d6a8289647e9176ddc599e479c43769d9608d1d763e5a35acb9ab765fa08d167abcabd2d3798115d4c0b7bd782c77bfaea4bc27835b4af5f5bb15ff6ecd4d65074e012d7213e6e2e746a44cb5bb564eec0d4a43d2eb3c2003cf3eb895febed01bd55484a9fa384561152779df9534b943f44654b2c37b3caa368319235a1da431d958a4dec38da41e412606adc1df6022f8a822e4913b8b5e97b6c2525636b586c8b3d6fab4dc7353aad28fec33a67d4bfa5e83847361a8143d1d2f495ea4a229c4f150dff334b857344c721bdfe90b554f7b3d479bdbc8855cdf0219b4003ad6861e9aec54f243de5cdeed983f8c9ef2b3aee24ca7ee9e7b914d7d5ad86907cdc865149060b36db1dbea22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = 25879df24efd42fe4b53fadfcb973eae3fcdf833463ef73eedaadce3dd9faff9ce3a16d30c4df1cf4360f3e4cf945f8bdbe69d0665e71ba7b6d93cc221bedd37f8f8e556f9c6239ee14cda73e58f0ab6632e764a840753394bf06c28db3c333275db3f065e6fde08803f7bcc10589f8f54793f83fcbff8f658033694e6aa758f3b92cb616443d72e4d5e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb5639fbb1d796bebb5c40003d19869e44729ea7ce6a3b2cc3fc7ab7b5c6ca02c78d8be4567111f86791fc2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd67347379d7dd3a9e60e4637e2ab768e9558339921d9cea8218926815cacca840234d52d584e64a4661afe9d3d55e6e43e3984c3e554e5b666a9cbd332a9e6c73d36d44e89616cdb4eed0331bba659649ef0abb876dffa994b941f9a35433e110c8d80db75c69ec6ffcba48643bdef54479dd7995f7f9ba92f8b473cc7e32dd4948648af43daa09996e868c75bc3949bc3bc8e69f3df68b5dd78bafd43e8ae4fa6224b8a7dca8e4f7b3583abd5cb709cb1dffc1e80aa879c58b29677cda375a5f5ff9bc8431d48bb08bfdbc27f982a77f3e61cdddf6f6d7665b7a4b4cb35f5e62ba3698b724dae8af5a3ea76db086f6afc773864d38b4de3654b7cf0a1a8e75959e5fad797ef4a64538c1a01df8dcb5cdb68d3815467e57aca690fddc345f602897aa891fe203a4b970ebcca77846e6ddeadc2f859f4ecdbfa8a7be9b932bafc6d49e379a035455d84282d5ab90d5b6de056f211cc6b06ec1d5b643f9df99c249c055964c579d6f88778a470dbd054850a9e9f557bbfc33dca2eb2857ba6e7018bbd8f25493b265b10ce74889d8cafec53f7b78d5bfd637a6b6ade8a65d7f885c3af645cf08bae35d753eac8e2b734a75976ac9eb8d2633a980285ec34be54c1551162c81f0254d2eb55a7ebe3f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d16d9e5b36b8b8ed97d40ccaccf496f40de0b967e62455d25ee6f592fb61d42af8b17aef3a3cc83b2be73e9599e5c49a41b93169dbc4fe0d6a93cbf33ef73df99ee6e19eb17a16e25f75ef52e5d1dc86a856a96a447dec4603fc1fd6900a75e3f8df98851b44334fc62b44f36c7495881cc3fa69febd4397d65fff3d4dca62a8d188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3cafbda981de3de003e39e25ec0813b259d53efa07681048888dccd82adc4dd324a028d48fe728701398ce214f5bcc9b410687363ad771228f85617a39f3c7bfbb2a6c017ef5d6fa6df88898f8bf36f768ea8a077039ad639488fce796f185f4ce98bcd6c25b611da7701b8d329228391db9d3607793bc9af18abef3c177af9d987aeadec6d3edebc6aedf575e4532d582ca19f93a1e9444b3b736abc0fc5e40e14c723b1c6abd2d34929a7edd48ce3d469b17bd9cbbb5d08728baabd54d1504f8d2eb5e890a5a142f40393f8fcc2f7baf6a7ea3c8faac5844d809ad86b6adca537c2c0b4e0d659606f83512a9d5a686dcfd68b5697b9a8fddd15955d205cbcfc0f8c9fb8898f145f98ee99a154977fae7bae16ab9335f31178a764c2be0b5d4f7598490cd9539b6abe848a8dd09768c445f33f52376371b7971d861c97efecd26d655e83ba1f6da553b4905d35efa1bbf593e8d78353da93ff41a354b43abf44aaf825d53f12bf8d484ce67e6c5b5088341267ecd2ac3c1b5baeecacf32e6b9b5a219ee189b3ab0c3f3ff13654bd6ded428577569d2d063619ab98fd889dd05d85bef1ab23a09a9c34ea3cdea620b6c338eb582dbdca9a6ac40fef761519e445a93b8fd3dd1e0a8e6ffd54f797db5ce6a4fbd46c3f42b8e646e9b7675716bb65eab27f99b57c45c834226dcc6c1f9859388fc9733a078db34a137c5422cc1dd87a615ce604a7f559947e02af6d337d997cbad6b0f33c43b093af04595e5ab48a8ad966f03e9a745d2500d4d6f1893b48b74b52e35c444f5c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a33dcdd1f49b09833be95c5f46bc5905b73a93fd6bd6658464659293691eb58551983e21b4f385af8eac9fafeb74e9a915441f41946e504a6b9d5716f9d9bdc49337919f82c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = 32a8b2862cd9771fcdb6f437e844b132fde6f3299c31185123a5eb2a0ec5fc8f96772f92d6b37f5bdb67000d91974c77adeade870ea0353fc648848e38e45d8b9a45d8263e64e6d3e005de3f438acc29ccbe54bf6cebd500c5d344a968388f8bc568cebbfd55f17d737f4771c8b4cb8733dafbf8f4d74efed22ca5e2d4c5dc354d44935ca64aabc5a64186f5e697b9444b5d56996e404bd7a9b76898a46f6edbfac8a806751e3f8bc393b83525514c56b7738ee0f90fcc41bb9c43666b26ef6987cc813fc7e93954a0258c61b5ee3f2db3fce4fec030ccd08116da7e19e929cbb729584a889ad6610489f44efbd5766670ad9013f4a191b498b9637df5ac56111d3de4734c7f8fc9916fc34063b020fff10d0bba1a15406846f75bbee9042b5072e77523a655f423e6b3dc31f39840446886af337d2fadc532999635786d9a6948164c361877891ae9d3a0d7f5289c4c0208efd355f858d9348aad7ea17e847c38780c86c6de2cf2f1db704b2f49c6a96695bbf2b9868d639ca4a8346ae0845aa8cae51e14941bf447b38decb715456cc9eb927c63f829c5636f8e01f88499b6daa6aadf3e04e1ecbf69888971199eb009cdb11a98c47e39eb773d39e6bfe4d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a655ddb13d23b8ac2869b416fba4af7af9f4468b2e6789c9fbdcc8ac80ffb86b134606a693a29e5c565fee836da872f57a73047f496442d8becf4493da8dddeb27b54f495cb984e732c4b4df9aae7c5f469f311b6bff9c582f888910da60e73eec789cfff2ac48a01e63826b672e6abfefe9e7184b3f66e7fdeaf652e6a596eb05f58a38d9c3187c4a3834f32dc28f55b58aee61479882abdfe407e56d4c64e283beb330a7681dc5dbf30463168733fab5fcedbea8c2e5e724b7afe1976e42ab7ff0bec234da45aafb803f8dc972559694548ee98ba2c828d10ca940f424f9a93ffb8739c873beafca093faab792c3e965e8bdbd895dbe24a8f86ed9b8c9a6987577b98ec4a7835cae04bf8ae923dac40c5afa7e738f4f3f809d5a223a6c2785fbfaf4c495874d0a98418773ef50b8aa87ea806e78a1c18c78040548443587496e71a21f88d5dfa7d19b809ec8c5116575f3c47a1c4e952a2ef418ae5cdaaadfab5b7969ad937b4c443dfa3d0cc893d4bab60beaf8da5a7a7fe6394f7bedbc2d7b5abb9b0157a029063edeeaed0f26fbc536cda44b598396772e4a3173ab4a22cb91e5be65a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee89f3c64baaefcb99bf47e95ea6b657d54f097289db24568da7dce527ce1f507cd7bdc3facc879893c33d35b734fb992908f867d5f66dd1e99ee679ac2c337c35c43609dc8ecddaa2afffa169bc36e6d5d5a2cb1ec9e4534f5b3d89a769e8d6dd88bdd32c63d0225cac6baeb8c3b7d9258ca68cb8086b6733237e6389876d85c71d2f5bd3d18ed812ab37e0f6a353f4135e5988fea7833973d3b25ad2b8777f3f8691b5671d06bf66c6ec272076ed1df3604ec7a670c634b7d74e889c0310f6a1b29c4b025c59d53d29cefc2a2665dc3fe423c063e1b78b79b65ddb238ec3bc88dced534598fb30ddc400b6fbd35d5fbfb063213947b89b9edf00ce034f53555853a8724a9d16ad0b285abfdb39e97b5aaafc4f9042aaec5efe3040ef27a4cdac8df49a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d75dbebd2f5fccce32936c9741b496d1c95d8318b6b9b9a71c17ef7af5547f895fc4f3e3e4af62d31695b957edd805e06f2f7c7784f60e6dad56ac760853df1c47dcb917adc3b7717b484b5215874084d366b4fda01edc3346e1e1df9524bd4618895cd92af1639e46bf1870ed2584ee9cda728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba1bd687d49d94e034399973e2d19e16c2f5f2e4ea86c6e936743806f4ea242b63aa19532f19c5fd01fd4329537e996a08b05fbd08dc39dee938fb581543cc77146cd34b5f23af8bffe735fb327c8892d8b5dd648d41ca209f976f70ff7f853545b5f5f3d0bf68d8d74ef9a442c639a38459fd906a8982a69e2a6d8da98b4c4a59eb6fcd4382cc584e663f585ef6bad486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = e0f7b1cbbf3a3379caf84ab286fefebdc6d2f53ea82e1bd98faea1f19be8411989cb2bd35d17f68667e2f5dcee6c5e674887b0e01cfeb067731dc8419e64b816955b408aea813666d73b53d7955639a877aa6eb4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a49ebc55c3ddccf33dc1a93b9b784c7c44f9ce8684e2aed800739839bcb926374932b7f41267835caa91328e8ef9aa4ef6cea3e3fd3bfc93d76d8a827c18ff0d1cfff89a8fc2f6fa96396dd52ef59d26c7b9c84bd38c557fa45103f3b793097ef6b775f16dd33109ac7d6d6e2dbd5497c9c596639a6327ef5f7d775de9c545c9e9baee99f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a2048f5297864ef536cf579cf77b6541093e68d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b8bde8e3e5cc8c68e199efb4b48fd02eb756bc7a65a4d67c86bbd22f549bb989d4e045e73ae9c1073a9d23b3e5d054cf0e3ba27e5debb04569075f56be9447a06caedd97871c5f624f43916d475c7539bbbbfab35c0864c8c77b1234f7983f3bb12935bf6ad8c2ea4d4473d5a7345dea8da03067513f74d2e15bf9e7287e30194dd76856ee8dc55bd6584adee35d3989950d7b1f14a452e36bbf7f83ca7b3ed1b67d0fc3667387c9b3c3cd8314515ddfc4e51b96a8d43a1c755c6584dba993df65356290953b9dcbd3601be8f478ef6f03937aff6d41ffc8cab57378b66aa255e97cfaf25eb9b712c95c4bba470b07bc6c458aae7ebce067b09a1d36f5f54636248c516c88ebfde3233cd191257cd0a6322704c9a7edd5fd8dc6c6cad636f7d1bc5847c1aed45bab969ab85f5644a5f8f43858c94b287fd1a7e77aa5d4e3c57b407273d2559762ed5de78199526ae63279fb510c99e7ac4dc1b1cbe5dddb6d1c3bf2520780f32fc15bbfa16b0af9753a61a949aaea6abc3f3d83a477e10334a959fa58236e561d3c8fa77ead34b8b7ff2b68212d651935cab2cff7d85f61e3c98930a6e457a955275734d904ed61069e1a5569d39aea1dae876e58ed9495ee639e8fbd65de45fbb79b7e30643bc1ffaec722675398498c6874ab1a7997009ae66d9e46882c37e4eb64c3f3d6d3bfb4c24d9a81eaf122a536053d774fa56c5a45f0a7e870aafb55784ef4d94be7452cd1c8ffebe33a9de7b5d0ffff6c7117c135a9d24ebab75ba9710c5465a089375b2a751f5c3ebb8e51bdb4e82f03f90826c3190b9b11b89bfade51c4a939521dd7378895f916bbb9fed7031459e27c9ee698a26a4f5ebf5a48492ff71ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd83ce0c997aceaed9f77cb9fc4f8c13b25a8a12c52c87f9f22b3f9024dc7ad0480c01ae75ebf93cea64d422baf4be3d6c5d446d49bd62f85ef4799ea8fb8fb9796e48c364e4dd85508cd7a9b4448e58cf795554b3cf53d5d14ad317966997fe2394da7aeb57240d69ecadbb4862ec196dca4705671b1e566fe59b08cb963f417abd02ae915a333685d8cfa9c89413b7709eb48e9ccfe809a56b027b6dd3a513a34f8467cf9b6ac802f9a83536ba1adfb96270c57a0743c127335264eee90dd4e12d5ff15468e84c6af54d8bae92e4c152c56082465b79a6cead444aa767571dbe351e4cc05a8a75057c5745abb125a5382cb8a3fbfe70d1d4ca21cb5db1dd002c7f31a9ada23f5dd173485c8decda9e8c1db9e3161e34fe0a986ed6ce183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d22fe70579e65ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93c5d6a8554738f5f2e11bb3b7976f9bbe7ce9ae90b0cc810258972b2df83d2eb9fa36384bedbe5556aa252a59c1aa7617b48072acd272576dfb0c6108ebf90a0cafb8588f6db8b933a7debdad933c9382acab4dc0c75c4e9a469ae6dc86d747454db870e7958c7ddb6a3b48cb13c93875f199ce83347358cccb4d45ab3a4fd7c7730470c32e8726157f89facc31b6449fd6b4676d81572ca291ba6e3667e65b053c6a239876ca5eaa0bc65abdb1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc6edd6ca6586818664eb7ed8c00d80966ba83c77aed80bf166c94458f7da90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = 2d1fbe5e04521dc3892ae4ecbbd769aa8b79cca8d1866c87f7194d89fa5633aed0f63788904c7511533ecc5b8e7fe45659bbceaba744036d5a85fe95925a71e3153827a5b418edb994ac635517ead99be32809ead6f8c30ec7ad3366683aa347223fc801e591778eee2c2dc25138e311b6d41af7ef96b9ab225a35e6273b5878ba6e46fbb1ac896a557078495d1fdd8264984357498d11a7d6b7f4bb42a8700eac4e80164e1adff63b4f5f50de8f3acfb3e6e7d904e7481a24d30c4dbebc26be4a3da05c4f36436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b136e355cff96be97f6b05ad66138c715cff9029bfdc5f5f33cec7abe77fa0f67572fefa0b84b6f231a37bdab5006a9ca184cbb82948c46b6882e0edb6cdefa8e637d3d437023b99198dfd7addfe57c43396cee38ea06adc0bab4aa2aca95d5989cb6b9f1987a58e5fb0b56d95655ff6d0dd08a188030bcaff3e9ce91ab88dfad4547baaff1d64bfe4cff515da398cccef166a6fe9fe51738b228cd4288e8bbde4c45aa285af2767d17b4a66529a0639e757cc5fea67865afa5390b0fd0ea4ff6ec3dda030cdf842d3e0849daf0875f243eb8086f59d9378dc77877652747774b85064b878c8e6cb30c6341c452a0eee2b1857d2c3ce04a57c52e6c7ed5274873e43303238d1a0fe547cb45ce568e3ca4863cef89e69e7e38b4ae2dbee7ae7a45b29c345e8a463cda4264877964033025b5a77e98f4b928bd2305421c9ed733aea2aa7ff5cef965e46369cefe5e0c7ef9b5bad61cb886880cdf0ebddd727efa56085be8df4f88b4c2e6c7e25a58c253d8f72b04a0e06d485147b85bc566fd34ce78a95a2369e6729778e4c5f1ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629f7e2b8e3ceeba7b32ec4a4bafee5576a6f74495a731dc68a09f6c7ca5f0818390ed4d8767e70c819dc4ec78fc41fa1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7c5fe32cce799b649497b4542a7da50ec5a412594d60f34cac594f0deb415b777ca759ec6d5e197177dd183307313a3ea9b7976879b867d3bb81aba1ae3727ea6fc0bcdba806dcf0cd6c8e863a0c6f395b41935ffe6b56e8df6a0655d2176be3cd9537d2f7cf89f43e09a5d04783ed27daf46ecc671be6a488d3ffac59744ac514d84aa5443505117d6ab4d8b92eebbf4387d14ed5feea35263446bc7e3f648d8e31d1b53d8da5ae774634b85bc7784f128bb984ce4341d2bd5cf07e2ee33aff31b849c66791fe5f5982ebccfc8a1836cc95c3954075fa305d4e0e61a980ea5b720c4726848e1c7c596b645d72fe7589c27d0d72bc2a95ed6a296636107454a7a47c67ae234a3a3abe9ecc8bd49738b6ab7e7df450c64daaacf2c09e58c28d6e33d8f9c883875ab36fb2d593559cef9add06eaac701db9d80a762c448ad14c4b8ddeffc2a5bf6ff23912f3dc1c5fd46786fb39689bb9ecca9ae56bc21ce347c6b4657d780d0a6c0abf9d4c9fb8b7769c551beedbf54be2f2b4fe895b7410fce86aff8eedb676fece5fd5fc5a067939a2d5cb0b964e8e3576dab64f21741019d82b04a9a498ec91ceece9a78f91087619b99f2535ff2b1385454f59d365f31f85d71ceeecc1f96b45425932406380fa5465305f2c6ae78eae6aadab4bddba968fa037a94688643a6efbceb633cf95c253668187784b09a7270993f701fc96e09edec254ccda64bb71582f31ff7dac5bdfcd535de23f4520731747cb81cb96f13633da5a3e8129e50a10fa2417ab8963b51f4fcb4c3b34ca9964fd5d94e58bf3acbbacfc1267641eaf083e55f5ca34695c7a45a283b15365ab9dab4118cb230fad6eb5affbfa5ff144f710fdd7a2dfe6e3145490a2a3a9f03d9e0555e0025d29e65aae19df4b2637da7bdbee97975370d4f9c54a782fab6ee67a8857e43529c8564c37846ffc2816643672d5f51e8b578be9daa35e62f39ee21cc498a5599a48c439457a2c98cafe7f6d0719bf82c45c58f04306aeb59e5d6ad6f3a31419d3c6b8636eb38d0c554c4753a3c9829e4d4c6c6914b56fecf61320bf91e944f27b4abb3eb937cc49707e89eeeae694dec921b6a6d9c238681ecff854d96af3bb25e6ebb81d5574799d4b885e1b6cfacc50fa91658d7909376b90db8aca7d648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 89beb22e2bfcb02be8957737b65a63dbacc68294e8150978215b85703586c116d740d56b50c4df806a7d2b83890d2996cdda967654506e096a9e59b69388e52f4b8b2d1d50aaefbc9f2db5148e3db6f6b4280eba8ba3a03f8d362c89d4f34da49625435d0dd040648262b44d881882de55cb3cce968f5b3fe78bbec14da50a8ff3790dc378eb9ca8735f560fac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c895d9dc35f76fbcd66199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8e5e4be837e0eef807afffb3f6c99925d4c73ccf60326ef8836a8824d95ad5f7e0969c00dea613de63b05033b303c59388e5b02ebc3466b5bf297f6595f665afa4d3dc762275da0ca7438d896404e6bfa0a3fd315bbbd5be37ae3b6e953473e2be9b39ce7ec072a97db3aa7546a9ebfc651500633a319e9ff4ea435cb5ddabf47193bf33b676d254fe32bd4cce04c30af99344f2daeb8e9b6545b4e9c9bb211e5add217e911dcbfdfcd72cfb76fd6366a74aa66c193ee1b6ac6df0dfe703bc9aa1ee48013fe0b1a8e668cc3bbb46510b993958a455b25c026fe9678fec03828335b85868dc99c81d3b75e0d42c3735cfc063b6873dc0078ddcbf561fe07ba430fb1046afeacb9d33ddbc2f3f6f0cf06e68d9d46679f7d61d4702c84aab51c60a748acb573704a5b422057ac3943f33dcc6c6609cef96993caa5ef8afedb692e7d4a59839f36efac87375a38314f4b7ccaf5321b3d5ff7137e4207a9db03ac0847ddd903a634b8951fd6c93bfcf05434ae70cd66eb18a4a22df297abb8cbb6f98044db2d643be21cd67ebd31aa886283bd3dff2870ffc455cf78a1657aa19e958df65bf1cd9467a23d6ad50e95db3a9398c86c5f5ee1cd4d816a96d909ea742f9be4cb33d9860b5d310f53ff6e49b236aa8ff44dc8d79b852888aabf988644af46cd30f5a69e93a44bdb454d79c36f2a2be3db7b395cd7b7da29fdac99b4d566dfcbd96312483511bc8d9e738bbd4cb5e708cc0b1fd56a39f181dd6d0b0983a2748dbabaa88bde44ab2df8edda8dea87d4908440ddaaf72feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abdb5d4af0bf38942faf5e0efdfd399cd19b52cd8850510c37e7cd87ac16de468c97fa97857e78712c17696ffbcda7fe3248733cc03c4f08c9f00069dd79d74f1bdf336b9368582f30ee57fcc4df8a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c4459f93771feb80ad6f5acc940f2984b128e64bcfd4ef2ba59de476e0caf2169888e657e7e8635e7b3dbe9954e814c5e41a658bbe25641d3557f07b33d40f7ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b26fae5fb96946d7bc20bf89ba5b3bd19408ac8ca13e8c8102e39c05ede3065a0bf2f800c13d5966832899753d44f694ce56483a45f0d56848484cd1b9c949c29f659ee4e7c6abbab5ecb4554eaf9e46bac0643775d9d5347e8678a614c1b9e99796c0d4c8ac6bbe34c4aa79a2cf26a2e83caffaf94836a52a3d680c974366ed4a06cdcd3a5c34d6a7b525bed00ef459764d66ac4ea0b83e5f40f955caf3fd2b4588bb58048e981b0dbedf2478746a9d21378f77127912848cd662f9c5a6e7a7783542b289456337dd67fc8e703ab202faf68c962c9387e92d7540286e9b7f9accf233a10bcf94fee5c3928934fedb342f39f3ad5f99ca681f5c569a2d87429bc7b4c59fa9a09a48e17534e7a74024cd601f9fbb13ab2f79e8a44066e58433c2ce8e1ec6ae44867c666b3908427e2d0659528fc76fc2ca17d3656b5bd673f78fbd37980898bd2d46d8eccbf7b76ac848d55658f36d6fb86e155bdc517dd787909a59b35bb73e43988ca745adffda04cb91c784f47e39152293679c4ed13ea4908836735c3a28768509b2c6dc4eff0c3db729437bea7a7f7af8e56e2798ab7e9abf08e437eef7e762e88de2f913e477230549f564a3540ee7d513a72aefe32eb1bdf3905cacf0eb05a073498c56221a4b9942ad223d4abadc87f83b6aa1549f0ae58cedb7aa5d4ebb6f4b34570079d6d1354b0dec30e0bebeaacf5efbd7cb574e7c134cd4554eed59e82651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = b4fd44af3df6d9be7f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749b5fc8c0af327ebea02598f9bf7bbe4f59b1a6d8b8d3954db41bb4a21bdd661cf1d73df75a7de630854ee75cc29454ab1a3469bffa98907630123faadec892978b3e1518fbf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b50703ecc1495ce2d5943466996a0691d814d5cd2eb060568f56ae8fed9e7106e7f777a3d89e147d75998856a8f0e0254ee7896e9797612c655e7147e179ae4b37b3a2c3be8bdba5fa5295bdd4385c190b3d61136f128ba74c2c576137d8fa0dc144093ae56dc86c8aff0b29d3fd9a889dd7874f6543a3fee2219869819c35c055813a394333ac6c9c96dad85d5f8baf41046a984403b798f3f11469cd1d8a574567d2b38e6f0b2b3ec61bf73c2df559099528e3d6ff23be250b50226b497c6db75418e3f6bdc4a11732a6b9583b2eb3de3df8e79a82eb0e44ef34c32e4392a21f41748351046b9454b5dea09d739e1fa96b9f8e768d6f250d4b4b9f6f0e8769f90a921c53f3d7fb7cc75cfe33248c30b774b795cea60c47ed5fa01ae84247e5324364febd8abc25ae83e2e7f2486f826afed8a5e93f11a45ca966ee8fabbf85aa61c6bacc2493aa93a38bb734f1e99e3fcc635ea1ffae17ba41e43c5af3c83383fd667c7ee3591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc8dff4dfe3bef8edafdebb5f92bf532bb867ab4cd8cfdb6a64cae876285bf6463b9a34e5139e9c9c7f669fdf52fbadaeefbb963076592f9884b5f6de43dfd08e0cd9bddecc2b03e125c386cdf99b49283d6d8bda24693619dfa2fac3b7acd6deca7db6d357b199fb6af3039eb77debd585d6d08f92d328ee006fcd380c525086962b58bfe53c3c0844431347a2f32ef7778e8fa3fcf937b4b3b21c52bf8e6637c38a68aa5373858e17ce813409331139f8152decc2a4db806e953cf5971fb5ccae59ada4373dbface49869a0833bcb97d9bc68d6581cfb803264599a9cb1cbceda15178f6dbf3ddcf7dd061bdecc8adfeefa35b6db9800567417775e1df95ebe3fa4e686e6381b48595933f40e408e2cc1952ad95994428fbde883b4a8a8d780cfa6dd6aae8425258eaf63ab2f2752ab5ee856b78dfe6dc2da74c3605e7718c3b117a98e968a72c325d105ca44fc0fb14c439abc8eadf5a94e2e5b7a8a7e848c4a9157ee44604ecbbe2c7c18785baaaac24bb87936ebcc8ef6ca4aa5ed1de8c2e6c5658034c1fde4b75edea1778f4298a669b0c4355aac3e201380c42cca517de92d06606e8430e135c50997579cd756db4d33664ea781e6702d0d41c6a6f70b65a92d63ee965aee9535556299f9f7fb59a8cfa5cfbb90b5fd4b129cc011f7aba0a4f2489d8b22267df9333e8c86f143c4b68909694de674ca14c75396d4a784efbeadd4d96ea04f63b74106729c6759729ef5cbdc40ffcc60c4aa30c7ead01f3dc889276d49be329bcd33d5365d76c85893eade1569dbcc064f0803cad5f8d355fa56974ac577db71396f545aa43747f9456c9ffe74e56e3b8f5e106f59a365e5662e5dcaf4c9ce568c25d9c9c757e8073ed969146bb64c7afaad3ec276ab4bcede8edff7ab59e474fd9718c4a046e84889d7c40f0bd0878675deea6c8e17eb0f8e9f77147631939c035a8f9a4644b3dc35c3dc328c2cdcc6cc537af884d7d6d00dba9e1f3d62c2d43a30eba18744d9422a5f674e74d2f536e95fd634558f4e4f7d3b8b48b96845b1fe847208c37403ee419988e9434aa06f6da5258c00654b6799e22df7e788d6b25aaf9eabf83a437feb1bdce924a79d3fb59ae6475ae77e4296cae52803db67cf597ee3d8a3973a501cae97ee779823e95805b12b1bd0819dacafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b28f9428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3ebd27365e8786fffae08e3d55fb6444c4ecf3b9a977d810354b5bd57ba43aa5c4f37ea04bf80105f90651ad8ae93d61f43e489265b2f2a3ab1f4b316aed3773b7806157e26fce893efc3d22ea601777834c5f939a658531646e723f22943a0decb5b82baa4bad4ef1dbfaeb3076a1b2da382698ce49e9ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = c3c489ddc6bd145ad458168e5b5686e936f5325a8418565eb60ae0b86e9773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7cbf579efa42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c491ee07d13f6eb24c7fd56e2beaef75edaf0f057c27f1db92e1bf7c07a4d621751ef66307ce584708a5a5876e838b56e2b2670ebdd4a9df7cf09bb8c8394fdcfe4cfab4a83e75773e57b908feb46bf54d13744bfb1d3cf98d34238bf9207a6ed5d5cb43d6a49b186d1743c86640ab9cd5ae786448c8afefadf884148efcf091b66da57883cf363647eee050d5be8376fe9acf8fbd5d093ad34fb39abdcc97c6bed565d08fe4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7e01e9e86c9fc407cccf98581bd6fba8a2f8432a4922ee5c47be661dfb543ef26306f63d1169a31b054cda1449cc2faaebd04c2b68f3f58997defc48f6db37301bdc1c475a867bd35639a5bdc4669cdf9f97d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6c3eb8c529b84cc4fdd9efa490bf40c6c7d3c787590ecaa1f84d44b6ef95123cda81c3a7142fa2f4c9a33ea67d341a4426e6d169acbdf1a8f775ace44a37e07868fa3364ebfa9367b757baef6890cff95d32d68f6d9d338b3df98c1dde9154e12edfff4bc3e17a6abf83b86b2b3b9cc244330b97392dfa3202ec7747dd81f1ad36360abad9e7d28ab5bbde47403daea7c69afc1689f12bb7d7663ca41279f049d45017f4993beaad79a990bfbb416e3d72af8749f8ff51de5eba3c8b80cf34cc21ec923fefa52ec3c9827dfc94d668beded81554f9518f96806ce56f05ae79083110ce76ba34ecd45f75b4c89e52786665e5798cb7ea5eea5a721b51de6a78060a58f2af4da91666fdec92533ec8c9f53d30df70930d92f2a5e5ddeda8a2c6ca1e68bda6faf4b2a4f4e235f3a7e4e77335fe044356650aa5aa467b3cdb72be87d0d268572e7fd279dad668ab514243599de939a85990bc7cb6410e9bf837eefb8bed32487b2faefe500f67fcfe97f1e3c4de63ad7455bbb32d4db4c599574e89243dc5b524ddcf0a800ade35a92352e97584c2ff94e9548af9ec348e84d8b448b85d234f6ee6e48357d6a0c978adaad8cd8e4953b8bbf2bcbd8717eb597343629b3746efe2111b7230ac9276cd37d5e747aff6dcbb9b439b06beaf537d6cd8dbc2deca3db49f53c4a936bdf26f37a85b058f32f3d7cbca9b7d6fba581b351ff5cafb198494d5abc54d6e30a3f355754ab2a3823266e31acdd81b266b1fd7e45683d5e1bf7d3d6cb8457baf934fc598bcf9520432fba3c3968c8e8107898948d085178489eacb2d1dc452079b1c33634efe3d82c8eda91ac85e43815f36fc143d75cffab45405dbd6c35411bf95a5357e95fbb8a1e8d964b4d185ae9619dfc0b8ee3ab68f8b60d461e10b41e3274363687cfc5849fe6badfb1e821b3ec2f724735daec4cb365b16ac43ccbf4ec865a6dee75b7a78e5510d72065aaaf7b9af322e4ad30ab984c57515a94a67b7391a47d44ddffc9976851b19cd976afc3ced539c2e3b913f92883fd29ac59231d9d945a9bad4d39ebf6f3c08eae421e9dfcda9dbf8f8807b18c99a3799df3d68a0a9e2bcda3f5cbbe089caa3eccc831f64bef79c538127b152f97947af64f4085c50299601043860d95833de5ed7fd6052eef386559acfc5934c04e20827476c3faf4498819e3ca253ff8b48a96196fda7c9fdea82eddc9063acc0954337d360b514906504ccce6a54bab7a3634e30630a5f93c97af2cea981c5deab5493735eb9e1388842847ec604fa697db51866c04468e52fe3844cd879f335a7a10cdc04094d279fcbb2f84f4b0fb500d38fce79e45dac4d0e4339d7978ef6e651c72ed154046050c5fbf29751c0778bd6ed409a2af145bc87b1554b5fffd9ed03ce02cf51f4f39a68ed9f2629a8024896c6c59f2eaafe275f3273e337b2c8d760ebe025f5b21a3ea82673be930ab5358381241acf46879651dfd8ce94db4814e9986ddc8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c4afb61f85f0c1dba7915e2d75ff900ebf9d64fad96d8b6c0d954206add2c74810ec4469cffb9039eee5f5778a429d961853c7785e4319cab0cd9dcc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = d3bcbe7fdefd1b0ed984aafcea79be2eaf50f029382498919d77d022f38be928a341b9783e164567aa87a9055fca176ab497da2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463e5e504bd6b62a44b0c035eafbdff9ea8359db3d306663eee34451fcf796555ef5f933cd52f9b2a5f7fe1b4fa45ac9a8083d376076cd58af89d5d97e4e1c582675794357efa4bcdb7dcb737bf95f93ffb94f844b2b36f97b2a44deade3767b8b2cc7c1c8c83583e78f12f6d050fade45e3453ea86166c7dc22bd310059c58e684adf0eb18f93440c0f92dcacb6c9e3488e235f219c919153d2d1495134e9c2b2a3acb6f4357c84daebb4534448bc483ad7ace3b2211bc6cbfaa95bb4e71f955ff915a1d6be3cf17e84bcbf30ce99c8a23f64d3b98c0bbd986e6fca8f3ff86ed9d02a6f3d0f033bd5ce3a27fd8120f76aba45a905ede2676fd206e6a766a7f54c8ef02978f0d1ada29f76ffb623c34fbf82852832c04456597df0032f524c4fcd2c8676cce763e28555b8e86a2d8edb47e4da7895e3d24da41a65bea5dbd54b73ca98d3d61a39c6276a96269cca4597897c37b25f77fc0f3766bf5d65a06be9b4cccb1a6771421b5cfdc7d94c89c48d2dcaff8e4d98e4ebb5733aca166e0458e0705bef9d73fed289f75d9df641dfbf754a99367b4a5fc959c803daab0f8ce31d57fdd943df7e6e3f66b7677dd11ae354ec9475b455f932859d2dac38a853cb1eebd9e04a367f0fa92e89794a0c4ad866c65f3b465759fd0b575215e7926bf455686393ae7c507b9c8b916fc89b33e0725baddeeb8a3079a7301b5be5f463f826ccbc97e9e017550734812f2be8db7f4b9974ee5416f44a28aad8a9f0731b387b934d02667e87cfd51d35ad692d90992455154de77f934650c6eeae94dd952b9f1f8b7e22ac6d6c0d5013439a01698645bfcaf3cfd5044846d94d75b715835a18c5e04d9f686a78dc675aee4944ecd8d6339b5cc8d8bc65df4bebf75a752d7e60a37787c59c5e6875f71f38fb43745e58bf3e2e68c844b7c24c4ea39fff3abca76163a40b2e9d2798a2e1a8c6076fdc5b7ff653348a63a8de6105f754b385575697d56c86abc5536ad67264a7c3814cea1fcfe443bec0ff129f949ed685a359fb23e67e59b2df26c6068b641738b6ac8f357c95c0cac43a21f867e005c96e1a4dd34d975264606cf8ce8ff7bf0984770a38fc979f53189cb70cd3440b9fc56319c9387733af98cfc899ff0e6736c6b44a0ba5f93417e738af4a351df57e4ce690ec9f777f6a3285f1afea4259d87eb6978d4c77afb0beb9bf8ecc4dfee9769fbc279d8c469863aacb89b14bf31fcc9669b8accb2a4a61f641ca173dbd3ae4955e9b77acb0deecf84f068e5ff73bfbaed9c1fcbf35be5f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f43199980eebdceb9513c2ab347aef92bb961deefd2398b99c9feaeeed730236f359be5b1e53689113f46a473549c8f74a1753721d6f1a0f468a6b9d80b0d728783ebb8d99360689fe616c707a9c0c04c919b05a5ade4d6a8deaaf9d675922439e52f4301be8e5d2966a71d4cbc5a43786584ec877198dc8317753c701ed9a11c3808b5d693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d5fd5e21cfcf920f593ce45770da72063ecbc50552f2bd97a5a96bf39e895ad9c0fcbc6a472d68eb2ca7f76fe7f0678d0e25c44726ecbeadf9ec24845c6ceb2b7832af5ee72efb8fabe6543ae3bbde44a0b909f7b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6d8e1719e523209ca8dd342e3bbc0e8cca579d6d3daea4e12bd6bcdd5be898b82555fa28d25f61bf9abe00a7eca0474ac4c92b0938aa3bdd854f3a665ea56169b3c582e87ec88945d6c9637b4a8fa1f49b96e4e9647760eb68d2c08c21f49de3647dcf30ca0bf0b5c4807f97d9ff026f3d850754b5178fa0fdde6f40ad873b642d4c548160fbca00f3ddf0beaa0df41f3c977aa6ffde706efef5bdad3166515697ec9ec5ea87796dc7af4da4939e8b5af80be91f96eabd395de4edbef8c8e9ddff6d5ed7ae13af4d75ba67414b4690f59b2a72fe928fbf1c4d5cbbb4551d3dddfdf2fb5386ff663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 60d8de77b5c6ccfab6f463a63c069276c9321d8c96190fa957fdb8f423d7a73b5b4ea33829debab555c02626e15f99dae8bec5e616ea4858f5a448452cbf6fbabe3d9cddd2e6798d54238125477bc01babe0ec7753fc8c8c959917fe6206a7ca31c7b1227f4e05bb5d71c648fea759a6dfb58a257e738f30c2ea779ec4c55f33e9cbf9cffefbef285a9fb0d4a391386ce69bbb6e37a548246d116e494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e54af76674f99298ea2f1c8b7454586cb48f2c125af4e7db15ccc546853e00b1443e365cf3178d656879f00e640692b94371f86104c79afacecb2b98f01e3b9480c5b0bfd988dc7bebb33bb3ad87cdced9829af5f17fb323cde7a11ab961c236eeab89cd7d3d30f4b437c09aec5f461afe64e1939c9318eb44c8440f8bd70fea8fc16ccbc990bdb843f739b74eb326cc689d5ec7ee33004af77c42cfa05676620eb9806ea6f54dfd60f13a75ff67b7d1b4229443ecd5df3c94f93f3cc58c61aebc00a3d1ae3eaa88aa6d39f3643585d3aee6e5c8bc5e75da578e6d584ccf4c20afbad8bfcd9c99ffef6d33353b6105d6b969f7dad7ab997868119b5976f66e007c5eaca6b36b09bd3af4da9dcece9ffb776304bbe7d3aca167753634969cc57c48704a19b2f416d2cb658e75ac2e4f8aaf9a13e6693e4d94df2ffa6559a4fdd16354c87e29e3fbdc30ae46e28dd6694ffd2a9540c63ae751facb67b788946d66af5b7fc44409a77a27017c9b883b705caa371b831c7195abd0e530a97728708661d343cbca7ab7268b36294b2efd96f88af98092684b02569ab69e1f58f582646f414fa2f2b955f6b3e8bffbe8b13dd58e59f6ca983f48d26f164acb5b7a8a7641c9557a8a0fbcfd8ac2744810397cc049ef46756e5de4a884745e73454e1d675c3743a5ecf546d4f47368e3ab05353cf65b604ea3e44d8828c7a3ac995e84819db0639934dabe9ca7630855dd3a954f38876966b6fa87218714a4b3f89638a064846fd4e63d03341850d91d76bf5dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae69de2f2c3938d4dcfe138eaa439486d5791e745892eb36905dbe42a5c718f456b74bbf13f4ac50dddd0cfac943d6dc3df6f6080c5f5c62d51ea33ef18ece26fbec6fb86f32d67f2cfedc9e458c09a38c35ad64959bc64ff35f358a5cb1b07384288b457bbe5651935aa9d72f12336e14882a3ddb6f918933dad574b49b214ba4018ca4b1373cc100d7b683a9a44f842621ed6de16cf202bcf0896c9506855bb4849bfbd6289c7f041c75513ee52193f42a526f679eedd870aa889ffe8ae969c14cdf4729c7ace8e8971e598e495902cf9fd29c73d355bc44eb544ac86dc0cd58ad8157ff34f963ae3cab5bc37b9c78ede033c210c59e30f45fdcb51f7ca9588359e2274e18cf4d57dd7c6ade4bffbcbcba5f9433314cbeaa3d9a0d86a15bb6f753abdc57e49f6cbdeb339734bae638fcc633244559a08af3c5be5e6bc8cdc63398165acb529f5c724eceb3f773fe5b0a74d75d66c653e85dcf42866255a9bf7d4b66c488f784e93ce9b35cf5fa164bbcc41f7b6779a9b361f7ba7087a4b673096bba40494e0779be8270674af334bb92475ce2787bfaad8b587a6d48845e44c6e05af54425ccb59b5972fb3a57cebd2f62ddd45b43b7624dc6047bc5ee59fb7fde2670e38d8ded7286afd462bf0f1d49e1d2d6ffb28be66ef6154a64df73358dbb49b77258fc46ae5b9b8d144099be67b76fe6db7e025e8074b76632ee32e157efe5d7b5a7dc862d5cb870751da46ae4614e6eed595a757f4152ba8422990598dcb682cbe477995448ef5fdcf3678cf5fde14533c6aac6a5fd6aed9e7162b4efc6ea1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d797fa69498e9170e6c1af8abe353cd1bfff63c04e8c013cf473efb3d67f0af335d40b646a794ae602b53464dde30f4812e295f3dfd7c2117cef1c591cb9a350ffcb718c64b0d86e65e9a719ffb75f46b861f968eead3373c3cbcd6a983c937dfee433b2a7db6f0947b8ce46fcad6518e5d42d109ba53e3f4b9f657182bb110a6ee96a8b34c5a4b808840de8b71d0d87a510944a9973df9b9d0d9a6c272b6ebef3fd0b4d8daa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 9e9e71d1fc6309fdc7b30e5fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff24df77a87e44a6de6fc73cf27d991bc57fde0c406e53f254afaee5bdbeb5df6e0194601fa576cd89a5bca45e690833592b874d3b3cf30347601e40a0fab6139f96c51b4a5c3d650b9cf6b5e67100837d012cfaa798ebfee8d6f308bf2fa9e18565cc863f3410abc6e355f0b818b49b6369dca3a1ac2776f85e42b84c76a54ff3fe2b7f78544191ab4f0ba3e6c3b4495524e18c63c1f979eed6ec30670945da0a92052a7d2e1ec4e0f8be14b867d57d8f6fb4569c6d81ba685c79efc836edbc29bb416ebe4cfdf3c98e8a4aa726e85aefcf74277a4c4731225cd64abdeabc09ffa723784f0cfa0785f82c256d433a64b705899398aca8ed84ab6958c90eb27fe8b39ff4bfbb1aac4114f1c50aa9127d6790d3c350c6e26c09f52e33a35affee4c7f561f1368c4eff65c8edbf0d6acee3a528605eebf16c4723f7612ebafcbcc5e22a5b5197ad6336968976a9309cd758177f7997b7d52e34b648b8bdc0ffaaa59f5b3f5e67edecaf619bf0e7fd541ff9f6e87d91c4b430f7d8d01ec9e2e0ca44e766c7653d84bfe7722488f4786a720ec6dc4765e0f558a7a9c449f04333486f62d65c4ba175a0e2bb29c5f4f8465a73436bdf64945791fda435e49f3dcdc9b474d5eea98ac5f9aa1c97a84b54c064c89021537046e8e5ba9e22d54d2681a9c72258137b9409148f888b4636ca983c79a944a4ba0169a730f84d1d68e96dc193742fc4d20eca71ad359997d86acae9ffb05c0e0aada868e844774b12beb3693ed55df16b67706902e6f5590037997a3beb105931afa84b5fa38a0efb2bb2b5f531e69f19bd12d17a5ae2d3e2508958954b8fda5956beaf1275d3f34c571467d56b333c9dd265bd9d4a9eb7de620454bf13de20d6ade99f837ccf9fe20865dd797da1bfeff1da8b369d8e4fcf63a9fd830c58f7f6b25e449879c4ba9691e68a02aeb89f46fa9bd57909c3ac1e0647810aec74cbfedaa4b6684bb64ec1d8988be8be7683924f3f02d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e523ffc4d05d3c94e5089255e8a095efab8f2b99fb2a1ae7a157fe6282991833338553c8bb4947d8939f30117e1085ae9435b5c3f6a6af7f89457ac8a5ea467a0af92179fc8af459ad8dbf2ec187dffc3425d88b6396cb7fc6f7f5fd7e8752658a5fc92539668c83f7b91bf6572fa8bfc07d6f124f2392d79e2333af6c5ee664ed751343764bcaf5aa8ea271ed9986b5c2adf691f4a981d49e176bfee17ae3dd36def5a256bb96e69c63ba737296a5bacc6588eb8ce07b4b9ff8b173b42f90fbaf6ff35bc06c9d85f351a8da72c6ff50269ad67ad98fc9b68ad57c699bde4badec278f3559b46ee3b8ba2d79dc5380765de1bfd0e3c63792c7f9d9ef2b297bb8cb8381d6780506cf53399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa65f9fd8cb5215893bec6a642026f9032be6a8957624bd619b33c6b90c78f5ffef8ffb94d1a6648d43dd91096bc97d93418beba7ee4eef17ccf49f3a853f8b5c6dadca0c4348e9e9836fb27fe56eff73566bc5e23d7ca988af6feabddd42af405ff3eaf48baa3b5f49e4c6a638985669d576dc7c9ba575380e959ef94cfdc5ece5ca87cf3f98675eaa87eb5a51cc3450b946b811dd5d94b8e5376868c5d95950edf891637ff517a6598ae272b7c9933c544793ad168be537b478ee4af0c8b874f5fc95aa468520be610453583b23c28083857387d609344f14c4cc1da33720c3f57a53a8e59cec0ef5d0a3e4781a2cafeb7f7ff3b86ccbeb9fb64bdf215ab297ecb1485589766ca82843f942eb9c4037bd76baefd34e60febb8dc499c486b6e25c137b77597318fd6323d9d1ecb7b17b85e80d7ec6b1646752ff522f1a7d13cb7dbe0ab46385aa94b84acb565f3257dfe75b7f9c876288ffad5b0b52e4b5aac9a43eb18bf07943ace58fb46123652f7460cc6442781d603a93d7ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc3769ebc1b9f6d58cdddb5b52024ac3861785b6134ad9cd67c5e9a47ea96f57c4d426697e12846bfde94af2bf7ae53d5edba3fb79ab745abcc265b8c7a47d63ddbcc973cf6864269ee55778579dae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = b2197fb4a3ab3d57da0ac937d1b37a3aa5b4f6a69bff4c57a93d6ab896f43ee6b34e99f2f9c4e6faaca70a95dd9bbdd8b48f38357dc0bba7e027cb329cd9ea9d89bd46b64e26c3ddd11d69bb8c99ed9e895769bb9376eb42aada2c6ba5ebea62cc6b6924bf7d9b99b8fe3ad1db93a6fe6362d64dd93e4e67ef35626438a949bcff7787fb1ffa65f0c771a3ce8cecbfb9a3366f4288f354bd7961d485b7c7d020a36c5385e52f558f3f0f8fbba53405f5891864eafd0b89e419fb0ec372ce48c4222a6b34ae92d48da1a143f72a7bfa678e6f33f4e0ef0f362f6bbbe44976dfaa4bdb99bfe9897895cf54e5b5e728858ed386980d6fd64ea3a1a837b5bb0fba34fa6de87db001b9a9fcd9dfda64359f37b8602d3c0ff5cf1e7c4681e990a21e83d168f6926772255ed48a1eb41be8b63ece39859973eb4578c929b731becc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ee9ee02a3dc790bbbd604e2bccad6769b779f1f5ae3788d5b3844a3a7b4ddf8bf3e63f74c29ae25f4573a459fc2093caedce97e15d07536fc7fe590b9b9ddbfec86a2546e800ba726d344c0c667445b35882d593666f6c4b9af412b701f0d39227eb1f9aff12a1f3f05f3696f47c405739e056d590b5fae7c875f0a088b0e59f4ef47e1b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfc4f645f48d9dcc6f3dd48936c0440dbfd36f12ba9f357362346dff00ab58614e06fe8f0bba7a9eabd9b7d1ff26243d6284dfe095fb70d1fd432235b11d750bb5a700c1f3dce093e25c993035cc1c3237743bcaaa47fda34be6dadbc93556ce3ab0781463a82dfa4fb58a3dcdde7aa1f256cb796dd0704a7d92e82cd494bd803684c4cb4bc27865503efb439c9aacc78cf2e967fad7e1a6b99e708f63229754c7a97fc74e1549641018cbddcefcd0fcbe2f36cd79113e735d4ab51d6fe2346d25f0b327bd8fd92dc91dfe544db15931a2e5c40666b879e7bd2a889de8647ad658c16b9a3e2efe5331eefd40b5c548534f925ef39dba83cd3e70ecdf2d488662b1ff3c85da1d5ed48d09e57bddbdc75185e774ac10cefb0fecaa0226e3cad5d461a48df419a9fdf075787fba921a6a9f3ba49d78892771994000feb570bf8dfa895d5cfa5892d798a8bdbcc096b2f69ea4c53bff57bd54f059e2143dc309afab9f4d3e5b6b7ec75746418e24657e0b518d43ffc3b5e2d92ac45b39d0c743ffe873286a677ace5669b854549a156b77d42da9cb39b868d7da037d9737746b6f1c9e733d4ec610977a5f66b99ae67daae5e4f8750ec0dd976783bf23b9e023793b6c54ad3a3c2d33ab3eb1afa7ccb9cf4fe87bd8b358564bd994881109eb9dd4f6588d5e432c83a4e7d4678ff918f6670e71ea4110e4838e9be4d1f415cd64ca1ab5dc508efe97edadc7cf9f5da8224093d350aa4b79883045eeb1a55a240ab4ad8adda4f47e8a599d13726f3dfcb7515db485d1736069ae54a7e4402649b1cd3f2ed093eed6df2113384b8f4debd9ab8654393c013c9948dbe31ee6d575e70d30fde12859e796cfeb28c8901aede3b294302e4f0193b54108f6b48663f7273d4cc936fddfa8fec63d4d32ddc45d3a0ba3d8fd13fb53588ddd6fb764a5ed867f6e0dafc42530f316718ab01045523a3d84ce56e2a36a5ebceb0cd9899e30cf916f94b59cb76c22742f736afd60b961523dcaae76f905cbc1414c8275be1b713cd04a8d3796a8ba22ea95e946be684e8a205759a4af85aa69ff254bc2b39ae761fe227c6c48a377f9f2f67b47f5666e6480a2d949d4e3a1f8d5a53fe59fe2e6939ddac4743ba060b7fd8bcf071d7d22c66680e8daf15736c5a45d0827ce448f6d1058ba38c278df84a6e65357adf6735f114bc181eeeb9bc48698893acb932bf6aa9d9f845de9c4e4d5aec94aec9bdfed2328e746b7559ba6370fef77671769cbb53b2d70ef4cc9ddf26ca8b6dabc7c24560d29561d9cd58149e329e83f0965eba29a579d04dc6bf89fb090eb1d35fd4c30e39cad3fbeac739e2269441ddf990568ef2a9cdd3756924bed0d97c42d45b71b053f176238c8c69af81755b195afaedd65c1d5ee8a42dc4ac77fe78ba69fe8d828c7d94227bcbade5536f95b440fc9b953b4e0729bd185ca61766d546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = dda5f1e55c85d1ab71750942bbfde4479d40333767dbe4ac80e4b3d685ef27fbb0eb14e8417ee1c9e77c399773165f6bbe1c8e0625da0384ca629dd1b08554c57f464ae8b4b9eb679a89dbf0f3e1ffd2db9a28a2ede5fc4cc5ebb739712419a117bec0de75f17ad4f9b19ebbf94cc9e24886ffc6f389adf8490976074888ca83eae4f9a9e0f4d99f14937249dbd2b785160440683deda469c7950bc9c78e423b9a45b589e6053dadd2b34d3dfcfce94f70fcdde9848cd17d098bc52f4bc9c99ecef95947e358f0f85def6837c546efcf2e45faeca7aeeda612138c8dbf6bfb534c2087c8dba4ce1f94ee704652a093af188c55ac3fe12364da1017e90463e63a573d1676e7f55fb9b2c7b9639bd20139fdcfca46f4b9c95c1c8a47f44c1948da061b51942636c3bc89510de286878004ebeeb6a3b2ad64e0c3484aeb1ea8d38881de278124c4c2b69fb61bd87af06f3de1b5b8b3ede6a2d985986d62758849363bf631a8a08404651305484a4bfdabda99825668231dfba1e83ba9bd4c7be77d4096f07e5b83100cf9812584129a4c03e938ea5dcfd43c3023a8774c4fc9338ba497e853ba684c24bad3ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc6596577e5d0ffb8287b86cc0964d3e1b77e7d83afa73378a7d9714eacd47b8bede99aaba2480003cdfb9136e397790bce939086ba7546734088dcc3159ee8227f803a57129b3cfa3957bb71be14cfa995694f8c64db187b98da9eaa20f3a7771e8d146bcf1b99d8261cfcf79383031fb99ced3be7c96e68549b8e3df474e96bfe38e58d92ae6d533db2f8bf7d645c3b2096659b6dc78b6d2458bdef8553bffa5d8175b5e11ed8326139aef678703d396942e5d5e9fe811cbd868e483c646a4dcfd958978352c9e9c1364d71d4fbd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa367fbdb9fc2f997fbd29f76cf66c31ac6cfee1d9bb36b77378c5d9a747638fe950cf36c5c3fe30fcde8b607b74a37de0b733f12f4f6a2fbd2fd47e3f72c682d87cb685fa6a3037816b9a1288e51c76f529b54c52655b76c534e09cba4ccdb8528a5f8b90df1118ecb05066515a3cfccb9d31f386d6f4a411df397e526b755adcfbdcc7969ad3ffc7349f42d36aa5be5123a6ce8d47f885e6c717651d56cc7e2147cff3261ec76c045b3fbeb047760295e79f8c501c46b099bb7b508cbbaabd9a07efe595b41d32a946e0bcf27adc5664b70971853b7965725e5fbb47ea03f456be855aa496afe3da9f5f6a7c3b98695b6ee79e65ce7410bacf2035e4fd3b938c98db35f6804c7932233dba8455dbefa40caaba9757380954e93063335b78fe22504d802ebc4191fffc269dd0009e9765ac41cc6b40d39b4539eaf8007f2069c7f73096b7b1af02749c70ce672f256f09c637375e75a1fcd3102a4de8c17566b8cfad53e67f48a56c55c6b39df89d5675b9c2f4b7155905d8e4e185d52a7e6768549f4490d3d8e38e5baa8e0d8a3d051c6e5558cacd714f02ae5df5299d500e8be5cdc91ddfcb61948788a9cc2168ad021566a863b87547ee53b1a57e0d6ff8dceed3b3840f67db922e4a8825eaec22baaf7559f724549b99f57553d383473b9194fe4115dd6dbfa356e2c31ba283f778776b43530a857c8126780e2acd316c64ddb1a947d747a8ed831135a8146936090fb59192b32b513f7229ef5815bf864ff473c7d833849dac2f5d7725e36c8786fdddec10e3bdd64dfceb6a4b0d8db6f8af354bedebfc6d7eafc6f768686ed97b761fc0aca584539117ca416078c784972f67caadfe67f38fbe996e749e30eeb3c47c389d5c3f105fe34fe4a094cce5567e5410eae2d17a2896ab4d0744e9dd4bbdedabf34d38c1d8e812a3cbe4a065a0d6ca0cf3a9f600df7826fa5b3d872b688fcac9e49c53cf726079397cde867fdda20bc82219dd9f625323df535f1658a1faf9b933368992a89f0adba586381d855d99c35a299a467cce67af2d5b066d989157fe14569a2261acf20cb64cf48e9d1eda4c21ae53cfb5efc9c45501aa26adc5b26553b521ad4c4388d666bd98ff5fb5aec48155afab5053279256ba4e6975f4764c77a5fac95f75ffcd8d62534354be7774e77037bae601ed266767164c3d7d4d375c85549ede3f61c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = 0cae9153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d4deef377bef1cd8776c6f80cfc5f559b6b3bf57e6e9b49998aeebf8eae6c4147a2cc9bb379ac5195a320793f1407fe56d1f7257a469a428834d384b1ed48a8a576b241cec55b84d62ef48df45a521a9e440be41b3acf9642fe6a32b8dfb876df873456c24e78c4360b92e5c72ffe9c08c915a9ac02304c959cebf7e65b3742bac549d59eec85fb6cb608975b401c83b4a0d94a7de714876727ea34cd27b7385d7575ff499329fdfd5dc33f398e555cf5dc41a65845ee5e1c899ef9ad80fc6c53c8eb38055d8fe5cefe79d4960d96f8c1576614474c929ec99fa3a201a4144bd9ae0f3432cde3a354fce80ec3ca3c94bf2b45fc3a8e65318bd8d26831493e5d1969b7094daf5c4fd5779c844c48cfc0488ec65b414837a965c65903cf1a2c48a590ccf9fb9c6f9e45913bad578dfacbcbf9b5357cbb7be6fe6ba9abae44645ca68573b5fe325670f2c4b5378c04027eec4af522abec3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3f8dfede6fbeefceabd53a45a7c33ee5ee7f415b77a43a0d7ba4ae213ee3c57c945b9abc3b5b3b89e5784eace07e7caadff56cd27b28c39f4b023d2c953fe5f4afa760d9d03e36fd07d89fce58ce574924443f3ab494c07146db2ab8e3263955eb373032cf2da69eec5cc3ce0155f69fc43c8484a9e43fe2dd433a898e90b05747e0971005b80274d9ab874cd65f533a51a40a668900fded9df6d74935d890cf9e290a43078e3ac866dfb4f34518886578c26353a6577fd5e510ddcbf4ffb6b501662e0eed01d6354b48bd528dbbc0d7ae8b58c605b9e957c27ba364f327528e0202a891aa83efae7957bcf883605375778369589597a8b4f2303f6acd8683c5bedc41d3003eec588039e08a7c3ca2e37510391b3f75b9a9edf5ca3fa80a7b5d8164d99ace31828a59a939d90a8caed47c20578e973a38074243a787866588399a199c8bd74c8b6546169ef55ca13b23d0775eec7f7e3cac8b53d5893185517274c4a4abbee7d9f2b986bc02592d1dc38ceed48e5f63f15086f1113e348a7a68e044cbf1d75f1eac3c43d477fb5e24c93fc2c98de29da691007a82b79611fed4b6438de52efd1aea5b00a633e59ecdc20e7f742b9f5d4dbe9661ca864bb79a029c71019e1dcda5fa1b36392d3432c187ddd6ee90c563d4c28ddc87976a24f962023301adcf9ab63853823e85b6390fd84b7d395514bfadb36cffd9ece9277ab7d0e7df725a9ca3af87df9f96db8bc6a3f2789209f83bd6a4c4966cd26d3c96c2b4d809afcd435abe4173eae7f8a200a43f9ffe9081fdd6c29f93fcdf78567ea399a81b92d5485c54ac19bb298c8941ecd6ed7796a39fafc84d755a0f9db53f86ec0fe30c70d8f2dd69af10e7bee0c6e14adbb2bd73b0253ebd31ea5fffab76f96c08058f055837a62a5f09dbfa62505b8470d5ca5a48270a4e1b5b94bc388ea558bfefd85b5767fecab87aaad6844034c4a1ddb43d70687d968bfce54ee7054a9ca9d5c114b9791e65bb23aa0d02fad7f0d5bcb38b24dfbfe784e853ef7d85aa3f50ef7624cef70bedca3d42f842b477a507c3ddfe3325d893cfc53ff08ce5a153fe28b67d3d938e2b889e5e86a8f8de97f163caf5f695ef9994ac4d7932fb9629df7fa998e94ba13c997dff52968708e6468688bea91063de718331027a54aea67996eb1b6b6930f8947b07fa1b30895f225a7bbf7cd7e8a857c7fe6115c8e98689b89c7686d38fc454d7c44eb64d3795d51665bd538c33a89e5b5f777400fdc6d289d2425a2ea5ae4e9efa349a78c76f876018fa1f93e5b4dd4e10aad5c6053484a1b381cd8412d09ffbed7c489ea3dba9e5a24ed7c37f7c805e448a6fd8a89a860b96c4bc8bedd4d3d522cd9d0291a8504f7ff4cb5f29135827626c138173f740ef4ff0e3f371fa27df9965dd78c6f2afc3577c7cf866e7029dc8a249a6ac6c1eb45ab61f9a02157d13539fd6ba6c26455cf0876c9633b4afc24779d9d8b5619ce1df7464e096aeff5eb5f43be40b556e2c5c41503857f8a6b4aebfa5d8a67cb668930889d682957370f7b5b1a4b3cf44a062def1bd4b365b8c54117c6027460e14ba5177f4361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = 29d5526cbb30aa578644be33a0254d6f2fc33ef8d564e7424f0842b11363611dc566eb59fa9f3a022bfa1acd8bfaf5f1e453f4eb5bc9873846141ca7da45be4f96e9b334a7d06fd93c2e77f4b7eae32ed81a096071f95827755570abff459685ff22849a86375e157259df4563c8d28b7f8c5fbdbef79495c1c5397998d930539228ce88c30f7681236439085b41763d6378a4eb0f54a84e6473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c37e6053bb54dcfebc2203ff6d88c2a1947bb599a878b84f2a1feead84a763eba7b9f3422466836bb6ad029543052ee5d638552ddfd17a84ad4cf687daaba75b1cda73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c33f5a3bce9f9a5b0327b80f32db9122583f5e9d8cd2ec97093f27b568c47e58a2a7843d224e412bd8f9c06eeeb4a9ee04e6180ef6bf9d5e9d0cc80cd39f585dc4ce5b9d33a2e6a6f87620683faf6dac9b38fd025c3ee17ec47df03f2b17ed7993a414f25d9839886bd5f6f815ec4380c3faf4b64d7e3c9f9a76e9d54da67499322b37c4af9b26b38e4a2b8b699bcdaddbf5836dd38b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53e0edd578562a91b55ca04ae863dc6aba9c16ccbd684385705ce5d303cead4857d0d1657dd85c536cc76f2286418a9e88caff2f3cfd8d45ff2276a3c926f8772d6f45433a000df6b092ff99283ac8d5a36b868b9fac4e89aa64a0c9db606e695fa64fb8c7c3ff1fda46d6bd0da88f36e5e8d34756a304fd7558da4c15b7c27cc8e4aa3e80e6b585a2fda24ebfdaed6ea479cb039d4b9e614ee816c96863cfb1e6e6748444b4febcf7b1f9e6e88e7950c77a3fac386fa787eba4157c7f0fc2662994fa145759cc8fb65291ea8a3cacc2967e463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b305cd426fcf6fdb17ca8fa5496d794778c49b4f74a5834dbdd3acffd76f8011837451cc4389a43f3ccfd95a9f8b77394651e4c2cdc44cb9499def6b366d15550c4eac8a7d7e58bf71aae6e13ef7a9b1575c69e35e4d75bcb0333e8acd91603b7ea5973a277672a1d5d4cc2c450239d6106b97d40cd2e98a876bf9ed88f4c908b892b5cab99fa878dd1b3b1688976c148bd055d216656028d9c2fcc3bddbbfce664e810cb84f4a04e5eeb863b7c7452bb79a96e790cca35bdf05b4c4bd59802bfbee373da7adc3df79c986f7ea6788712fd5daeb6ed44c2b82b4efd1ac8ae245c96768fdcece2b4af175329a4973696c5deeb9e075a6b8ee2c347d15c89448cb49eff126e8f733def93288ac60bb3bc3daee208ba71054399fa4a5d1db7389379601def8b0fce803b88de90369903799cf5ca0c5fadb012b691b0a50ba1eeaa51f509d1abf25ef52eadfcbb315361977770ed77311ce705e46b06a6cec35fb5e5c9a8067df750b388855e982bceab6b5f8d1828eb66727e42cbc372abe3e2b44f060bd6724fce3c4cf977e346e50a79498f94756069693989b7753ff8b5ac8d3bd6f2f2f7c4738f88f9ebcd6cac43abd68e30e7ce1d8d8c84d98ec3cd99e8eb9dc6ab7e88dc0c1669806e3cf35aec1d6edd2aa1c930177dfc4e45b64c59482decf6446468806683f57b3bc25b032aa40d3ce88c6afa7d47b41b4753d5f7a3b22bb70643942d6c35318fd5e6acbb4f6794b1b0c3bd47893a7f9cbbc6ec608068054b385a95783042ee972e8888c74f7b0ed99a2ad7fb3879b822bf5fd1699ae1def52bf7acc6bf926bbfcaeaa9342eea627493f44f561eea57746ad764a94d9640f4ff7cd70ad95b285a74527fc3da894c06f7bb5df6ea012547f88ce517b9aa5576aeac9b3dd858c912cad96cff4a24085c750aab463f8b956fb837ef3d0470452c653ed129bf7472b5cbbbf68924acedeab3e7c0fb2b30ea44e99654a1dcdc8e5f06496637e88929a1ba4446f72f6b5ce41533450663f7a1a9144b5400e7f7fe644fc6cac6e2c43e2015b571585303967422ed8c5d4b75e502d3bf2f86cf047daaa3f4c47246a27e9d76559c906ecbbeccbf0e12dcd9b73f8857832ad94d0666b943f94e8f584d8251b91ce44ea2f63601dc751c0c3d1729caad94f5f727f50d6af49b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = 5fc836b5e569623b3a032f7b1d2ea206e83a9c5b3ce1594eb9099174fb34e5b5c333f5e0ac2668a70454900fb47b0dd8c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95a3da66cf34461da450b9c59c24326c16cdb457f31b0f6304bbcc9823c3a218989fff352d445ca22b6b03186407d7973c5ee7c39e4555acb33b4764515c4a381d8306447f9fcfd0f867fc8467a089c8f4769b7df39967289a93b7f55e1a8447f96fc1528c3dc4684daa96324186f2ca5db618eea074b3b7ffccf3576a63858cef387adff3ae51652961147f37ea346e691c4dabb45562653e26b8d6c613e369ce7421747ffdd4725d0fb40fc59737a75ba71331133dcfea5cebe8a7c3aba9b589c6e80de7d1c4f7d4d6aad684a33adf28d2eed8d4f45cf923aa8a577c34a4a678dd2446b7546af11fedf00a43134e50a07ee7ce4fe77db7d8a2d847308f70e96a4bd31d91f6df8b13fca8f8efabfb57a9e4b5f2d95896b69ee686e5b23d4577adfedeefdb9e1fd84cc529e8d69f857526c8405ec60e5fe0d92a425d7340a514f3efae7b8be67325a33539cad9bb734eca0a4c375e70449ae2682e484cf947933cc984cc7662da79d666d1c47f9881e9b4390a99b0ea62fea97eaba6e9d71b7bc38f6230fdcdd0f7fa3c8acb7459e53d09ff672c5c61c4de04854b0c5f3399af634c7f7dae3657ed985b550849d52ad4f43e8892f7a4a2b73c8d4dee2cb5aa60e5438d8962d8a36858fd8c075948095c86de6bc34e35c8cbad4772bab592fde37c4aca7c34598c75e02f8dac0d677511b854a98f9c08ea7766fbd4c6047612aa83c17ac38a545a2873e61ba3bf6b9dd5e9fb5605a7e62f0efa9e7feb62c8a7b9cd8e3a693faf16d7081c6da95f3805999e8ba7d56b53858357f6bd7995c07fe7c5f7d863036b82cf97edae995ac48b6b7ab0ea85c3667370fabbca8d5cfd758a80bcfd7839cb85da4f8af1eac0d8cd83567a85d145e5ff399be3f5931da9fc953a664eb8974a434270b47d3e635618eacd0989a15fbd65348c34a19442dc9f8d1e9bfb29ad858ed7ae8a5bc38087cc865e5a344b4cc05f9d766d590b3bb56de5331945c0c1cfed5bc8751eaef0182c73493d5edc765787ac9b784ac4bcea454e6a4c8923fe6ddda477f3bf43da356b66a8bd0980146b5d5147f62c0d62541960c1be9123a549dd03ee1c188171238259fb661e17363f1fc57bd873c653f22e0e4a2bee5cf72efc7fab4080defb33defac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c69961aedeb1a9e92642dff5fffa0c21d752d3b34fd489b7b3f86393ed307c6cdacfc6ada97e90a98b0d008644c9eaef666e8507a7f59b89e7eb36999df6befc4b72384ee0c35cf73f8d41c05ebf993fba43b8e95e368975cedd61ab65e24a8792dcfae295d0ceb8bd71d9b85174c80869716b6d16ad8e90efe73ac6ec4d3c4c37bfee593ac9a0adfe0b663bfefab5eebd3ddeb27cd25a8511cbfae8795e643c5dd1b4ca5bbc66d49aa409aab9e7f44d2ffda93abb53acd45bcc9978200e94cd4e6e7235b52d9297d4cd374b998698e8f948dac3dd88dc9336532c499c479756d50f9d4853fce0156cbbd9c85f5dad6ab57b62a8e49472fa74807cd881a58eb1da6e5c885fae6e1727441dfe5f834d58b6408c7d17fd9bccff4a6edeeef9b491d23f26684baa6aea771a7edd21fac679ed8963bb1864aa8ab89e3917c980f3ac1c435457684ab758569247c98287bfcbc88f63f1cb88478a93123db497be2f84f808726fb6e5f5a8226d61a3859a7a470cb9b88bb0c8b1f2ece4977a73fa5798cd8e4cddeaa8447dfa408a83e73be1f1f511a59486c49c6b0ce367b95f31f47cb35cea8f9a963cdeac7fb6d76eb8a657e647466fc82663884d7d7deacc760db2bdbe0c3d779c98396aa3f2004976c8493ac9dae60996056668c8c2cb9065b6a268da986d9853c17ea02343b8903c0184991e2b7e298269a17f64bbe1b6b52ddb29a7d3a05bffe17c33b29634dd1766be40357f34ad00b5f597a3b5e495f473d886e06db52b86d5df5fa4e0d6adf291b5422efc1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818ebf52cec8cb627455d9f792d7047cbe98b74fbf6c6a7ebe56c7f19efd92e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 3d8a9e39cae9ea979ab2d5d4336cd3da056801f4c782d95dc3ee63a043cf2db760edb7772d5dcf5b6fbda484fd2faf96b23ed94ab5cbf017755c74b6475e37a1e3ff4ceabdbf34a7471b45b166ad05ec69239bd30d3e485695a9ce6e5db68c83e467f22d85960ffa8ba6c8cb582eacbdaea7b0abe55a555f406a660d3f5c6176f33c15d0a0475932bf7482bde5af6fec715dac306d5f032899ec655f0b76fd7b65a3b21680d1b53ff554987aa9f58dda8cc81ea18ad8917f838cf1ae6d4f663bffb33ae9e3afe98bebc5f9b1a63d52f99d714554d664bcb5570a368054e51c0d45515b94b7c8d73615b288aaf80e5994023eba51cde6e0b8c6df2b34c3adf3e0773a0653e397a68580c47610c5de026bdfbf374c41ceba83beeb69fa9b6f6ffd4bac7fbe737a18085056bb7f7cbafc4c3bc5b75def07ced2a3b5673c7c8f1dbf694396e8fa7e7640c76a4f058ab864348f068691f9599617f35463ff3a3b6ad1ee44898dcac03b6e2a84717158339c063147ebdc596d32b8eeda6aee7c1c6fc1ae5344483676bfe8928d637aacc4b614ff4d7e2a46de3449f18bd0620bf19cd963126dce38a95361889b167cae272cb23f85bf35ee4c789472975ae76c567757cec0ebd9905cea70cb88a55c68b476f877c605390ffef74c07cb95939c9babc97ed5edf82a9b7d19d8ddc343420891124fca9b96f0694bb3aa9accd1ccf36a9a89548af6e458e6ce3846fa8dc894bf9e6e6c99581cfd0b9d5643f556f69fab042f8cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77e4d182cbf524a87e1cc5e1e9d591f06b91a71594ddef6ca9cfd450b899e22c679aa7abf6be78b1637f9995d2f7c7b4a03974a94dc9dd14ec440e7d8f89f7f94989f3ae6a1f7cc9b0a9d8da388a69be3f39fba43a49ed75c76148444954063d9163b6ab25d9b03863dfe6fd94b59e849cb545dc7ba595d2f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2d4d7980cf9955a6ddbf6e8cc6efeeb9ea720d77c3f8b3c680974fd8c474f9d5882866d9abe4e66a45cbab974ae884c7061c6f12aaede7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb4ff63bf774623a37bcdead56def32b3bfb4f3ffff6eba975c9331929efc9ae55d6b7c6c77ded984cdf463fff0bc9dc946573e3e2bb8765dd34f97dfc69b53889dd90c3b89c1864556abe24c03680d0ce1ce3d50b34ce6740c54916c5ed26d4ec19f793d097b94b4ca3474b6d90382d5dbf1e8bc848855eaf259f310c7f39d9a46f8c868890c7b531834b2bbaaca7ac3475eb941e3f477193cde0a33483f3b77ca97b997c42aaf544a1590ab8f52d7ed832f1f8262284908ab785543bce3e6aa43e4d05b469eda56cb28b45c453f9cf7f79cdebabc3a9c6558997e04f980c66fc853bed3fc4dae25ef6a8bc8bf014690b9085f6e7bb948ffce9365d327b6e900aa954cfcaaef5efaee44cad3958556de8b5aad835d0e5cebc7724215ff13a780bedacfcb9998df665a1faf4887b570f46e98836c6c57a95de6349d032bfb33a3b6d62f92ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c699dc094b625a5b747c2f80fe4dd455739af8d97fdc39cf752ef8c13f83f0cad9fcee9a24598e143b5a856a5b41334839b6e88e769f78baf4673b3f69d5eae2c5ae98bab4b0254ce8c85204e6ae38c8da2f24c1634f7a67bd9debdc8235e96d25e961336e7dff78fcd03896290832e3d7b5959331c80f58698d3a0c39fae4068f1af8e5232ea4607bb9e4f94a5b98701f0f7a8bdd913b0bbd0ba551b01bdeebf3d2e555d681878992b6e6affd8a6c26e75a6cf2317ccc493ddbc755f41418dae0afe6989669a66dcaa713f0938c812beef2785889665f5539afee5a2d580526e56fd563fc83fe37e5591f1ddb4ed9b9331e579e2ecde3a951396af1289576aa6cdb0c87bf36acc28c0ab51fc86da8dbd0d23c40469d88a25d6d8b2e68f94a365fa56ebd85ea51c84342a3ea5d569793569f90bfe168bcfdfa9fdca3134704c533a3a9f19ee79f467eb1152c95334ce35e54fd5c5984e565e6f958ca399f7774afaa526b89b7a5f2349ce2453fddfa84c6778466d3af87a784e41b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = 356af3b704c6448bae0b6fc2474cedac4342596ff45faa8514b54c2ee5e305047e5b44618f166cc339e72668306994e51d3ecf04a9864267a1ebf3dfaa133fe0cd40adc3cfa49a3c0f4ca85d7a52a72b71f227f78fa787a2f3d47a2fbd349e76cbe5d49d498708d65f2beb4ff3e544f973a4baee9e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd3aee630ebdb5fe8e9dc51df298bfd58a9ed8050c93660e4351f38c017564d6798a1648fb6f34907a4850a0183b27243ec51f3ce4cddcc78fc1cb8a9d97845f5d24b5fc35c7e088cbee6f910d4d50ea6b76c88c87f9577941f6a5b4ffb614c94225cf6a36a841c3c4d46adfc0cfc366ddbcf3c9cfbfc50ead78c758a6dce685dead400bad5d88417503ccf169481fa437e4a8cf78c9d7890cbbc1ab9f46178ee2dc6dbdce604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11d07d1044a79a819e12516a88c2c662965a2da9b996f09fe951337b4b9c11e7947b25fe2a6f3cf1adfc5d86cab5267a1c8065ec045517dc9be0793e94bd846dffc50ec7f3eaefd8ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a11f8d52a34e287edd9badfd426ee05409be07beefd3f73c88b79c9ee630aa9ed5556b777a5bc680b8d3f5a7b604fe6643bbda9e07e7196eb3ecb5636aa5f9a24a59f17a389c6eaff5e633b873d65f37789a538f8353b80ad75b4ee876a6ca363b6679691ee5f4b9857bc88b8465e0028ade9014621dda9a32fef2236ff557f8c86d29a49afd547e35a99e8eb1a12e47dfa3c45beb8a3026a240efd298efde345d3cd5add2a9fc7ff93ddae433b921bc93d02df09a15f4278890907ebae849518bb3d5eef84597f654754a7808e8ef2cc6fbbb38f912adc5636cad75b53b454a5a923a5fc8e956c9cc527ccd4b846b596cabf22a953db76485c6486907f898f6835a703e5ae20b57d3e5695327dea586658c9e78c638c9c22c941097838b0de33b7ded0e5ed8b2ebb53b56f33408ccbad9597633440fceaff61743f047ece62ca1977aaea8d989010dd26e5a924876efbe6cea4d36ec5426a12715af037a5ffdb38b8dfbc11ee3b4eeff89c3ab399595907819ee888ac0107467bfda6f3d35516ba7404a4733c8ca4adc1edf7399ac5f14c2cfa9ffa91fcf73ffc7985dcf52e648dbb8c3b14698bc5e7166ccef663594eb9a6c476c58bd1d3ea8fd3f382d5c5c355a2633b9ccaa829e3366fea6393265d617aa96d267cdf4b98cfe3334aa0a5c770dce6ab6aaafe7cfcce4bbbe2756b7dbe0d6d6cc8d7eb32a04cc653cd1e2c6fa73497dbd9a46eaccc382c5903fc4d5da5d462ee6c87d2631ff97adb38939c5ff84489bb9d117f822ded8886842f6ceb402bafe49d37aabee3b7c14b5a748c2dbc45bbe5bc2abbb929c6e3767b7f0ba67fca64cf080c4547dadf4d2f451f25973f064941f8e4e3ec74b4c1770543bd782c67580b7a696cfab29c95da3ce8e4563a2420eb11084586cf9a42ee6fa2cde5710ce75f4d5bf50f8c4a196aea1953199143efc5e83b3b9d55116f3efa47c4b5f522787723af5b5d05b86d26ef6ec6ba2212ef0b5b5f7324a989506fa5aef4aa6f8c95eadd1e7757fa5b3a80085bc48cbdd34388c0f6cb648bda7cba9f51aaffa730865a413fb527d8fb77dfb09de44336b7c7b65730d8677399436ff67e1eee7b935d67054a8f472b96ccff7f79f1a673be6e757f7b951a5bc9c4b7e53deea09f350748ef0e19f3f8c2af98afe9a6fbad6105391b3abf66d9c768c658d56fb59f68df0e1de7feaec49707f9a8118f1fce59cebecf4e8b7cd3b8691452f5ca4b5a5c72432738ba5b939c64cf338031e81765891469aa7af34a628a5d166ae328cc4c2b6874498b8f05c675214137e4718d625ef50521ca34e394e83afd6df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332bce68abca2597ba3942d653e8338303552b419c84edcd14cb3d06c5da6f74b8ac57378f9ad600694ef972b703a3bddaae868698b778bf6984dbc7bab537b29ec5462463295dae582efa60f6ce69b494d0b7793af43e3fee3742d84c1d20b6b47877321ef5aac37de3739b34063b630ce71ec6a6ba7c6ffaa75d496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = a3637b6eda83bc2f81b74fd527e3b22ccd8b5aa644402cb674059135d9c928bc45990e9722b8af0b647dd40dfe553bc457bc763893f88dbc461e775909745317f67017d3ab5bcf83d056f167dca55e74524395f9de7e5f8af6438edb470c8e6547dd78db0ab2588bb56b3cde0684ecfa28c998bef8371ced733fe1480df28784633b55f07a3b43fbbbb0d0cac41ff7d213475e61058cf21797565bddb2bfd95cf367b966eac278eab8b6ce7d34db5d277169d3eeb99a4b68c9fb3fdece6333b404e8807c3fa0b13d80664cb9f0987d2ef563097d7b47be4f5667b2ace438701cadd7c4d26cc5886bb7c0160a9684e5f20e5ff497b9e62d84c2501cdbc4d8bf20b9d4dedabdc56a92f153770aa952453fdbbcbbba66aa89833f89a23358990de889e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f12d779f6b6cca633e33fac08d5e330fedbf70e8a6ae4a7df1ffbe55cedc6f4e8426c69c212a33b6b897b31630c79f8cc4865606daef7dee92411c8d491f645c0655e23553b13c6c7c073e0ad9ff35465a1b8a505de879998bae726d8af9e943b4caa34f248f6dc679da3d33b51c53315aae72d843884c83a0b7e1d009414d2e5badd3fa5f74cfb3179d6fff6818d7c79393b8bc8b8d222d92f235d10166dcef4abd423fcb31996b8553fbf447d37d7351692730052876357fc0d5cab082a4e5410ec3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd600ae923f3f9365e5f90234b7613ad5ea3734a7cda952fa97dd7d42a0434a694d83e8bbb41dfc4eccd8496b7f61ebaf69175c2a9adaef21474dd4837b7bec7bd2efd68aec176bf634737b43e5475d5ec9a768f7f0219edfdbaf0fd43cf5aaff479a671363737ab1cc3082f5bb51e8d1b7e4ddccd8b780f83061762bc098416ee923ecb3e3daff16e3d694fb869b514a314db3fe8da5fd4a3ded0979011d8b1fd7f3ab617b6df5fd482e8b9fe2a3874b788f14e6dce2d704d3df85247784477385a1cb21a3e3b710f84097acbb90976b94a5fd8984bb6c7e21ccdf0e58980438ebedcd78c1dfdaa7bbe36c7e7afc206983887beb247f785afc389ae8b1dfc5e0787d3c8eb7f8a966def56f25c8b3fd0f85d6e3a328c9cebcb0b55d044ecdc866e1b14de09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf055fe0579e5cc0d79830eb972d0ebd3766f70975bd64fff4d0f58307fcf986699d5f536ee7dfef5de6844db7db797c8ef5b9a4746f4c50647d171682f31aff3fd7c670595243d59487cab8d0a7727e4d350f9bb7d984ba82d8cf39f8e7c8984c1799f296ed9ff674a68437fcc81dbffb263becfebe44665c8563dd13f891026790c3ce590ac6e59ddffb5ec7605747ebbb1d7ffb04d3641f97c2c59bd05634bb6f8a7bfae4f3985d2c5f60fbc64664bc9ee308694f8bb3c4caef4ee43dc4eb4bebcd95b758f0a2787aee06e3c0c48afd1bf0ebec9418cefc7ab5df4fc86558d36fc764c5b69bb4bfab3526d533de1cfe2ccecdd4b897c9f990e8987bbbfe47a0c4428ab68ca077a2a2d3af7636ea1f47efde5d3f6da5e7a8cbdd53499d662d8babef3c7768dbeddf52d006bf27cce1b88ce9789384f063538448b98188b0ddad7328265f4c4b68de438d852d874625bcd139e2088d56c7db367a1598c03ddf3adfa90f1fc8dbe7ae4b88dc8f5662c799e6af2af70db365cb9d97a385f5ae347962be3b9c7fc68dfb7ad85e7dfc3e8d5385b7343a63f60f6befade7800fe3bd6b639cbe5d7949680ea3833699e654dfc5afcd83a8873362ea5e6fb4b0b2ee9e49ceb90235796ba570aa0a3b1ea6c483e3d79d7ecd154bf46993b86c5d6e4786f5b3b939fda6e6451b90da9348b88cd202ed87a569fa208ac9ab7ca6712758ecf4cf1bfe63ca3a369f8fb46da4eb15b4fd31f8775e6332397d36cc1bb31c65d5d53bea0763d98e4db4999a74e4743a73e539d9e7a9514aa5681d42a68ba6ef7852357fff755df41a55a7200e8a09ebab25f791379ebf787b781e08e9c8238cfe5cbff3f8895a19c240853380fedec7c3f6db9ff83f13f40b0faaf2658e04f7626eae55a9fa8117eb3cf3f36d1e48baa2f68d159ad12379e872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = 5fec35afcf9b1ce3387af3327d49734cacb798c955b329bc912ffce43c3cd1fbb93a5e8c69deb045edce31863d2eec96085edf0a6b74d40a6f93e7a8854faa022ed08d3866134eafaf7af101dca37e83aa4e8747ce884cc2cf9726ae9510c7688ffa569cebb45dd87fa787fbdd6b6f26e48c5ec93a1d66a2519c571c2bd97aef8a82eb9faf136fec3ee52fde55036fe176c9ce3e2ac3f3dc78fd7fde151badeb9b400ebfd29f2bec2fb7dbc8daf32cbb69b0f98a39543b03f67c154440305e8cf5477d6c4baf11f8bf44cbe208ec96082bc260f5fd2ecce7c003a7816a5d940cb0bd83f9912c423abf910d27cfd2a48c786dee0586a2b88c99c1eaf9d0167a88abc35adb5a79c76c89f4c814ba410dabfda6994c5a78c701ca91f42348464f61f6f7a23ec8942873dc5a88c9e309d08e8b7e9b353aede6c952e36974af3e9aeb8edd83b256e9e3b9b64e392936d538a9ab35d175544a70796202154350696c9056695dacdff83dc27eb7ef166fa04eac9c7d8b38d65ec44746fdbc1f77e74d8a09855d139f956d7fb39f9dfa19573c620a74f9964930ae5322bab6342a8f90a747c3b4daf12da2afda4d387fd10045ef3b5d86828f60592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b80ea2c69d9034a748b999ecb5e430846d36cf686d8be47e2cd5559f6ddee617ab4373d6614c4f026c6e581feda6f3356ea54e924799ed78f7a103e2c0a340280ac21c2edea348d9ce3744ac4539e4f9e2f4a99067cf6d3f047ac87ccdc565f9e81d5180fd42a893848d5acb4429ec6057a465a4f7a8cf345fadd5135bb3856733320ca4c13ec3b86aa83ceaf9f40467d63d6dc024f133fea844466abc2bf8d94b4d1b98ad5f08d986b38d2a15505e8cc24d9b3273039c2babaf848d568b1e36610ba3ce49add93d785a1780eb67b6de6f8f718ca7f1bcca358ae531999d96556515cb680e153c9838ede817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a40080ed79e6378e8fdb4ae2b890dc842956f7a10039d7a46b3c705493c6471b3cc9ca2535fb8dbe9798b7d4d66fea33869384bf8ff7b94631f4071aec17cd4b2bf4a622e054a1dcf9bb187d48b6fba8fe66fba75cca24d48da8a41c2e3a13da8ab594ce4d1bf95b1b587aff8778823ad2ce3644eefb236cce44aa4c5c2dc697ae3c681bce0b5f53ca1d84334a7908c48bb7f5c93398e86860c781bc483b197521adf4677487162be5407f5ffb05e919beb32b6c3bb1fe993eb15a4af84a64aba7d7a4f52fae6785c1d54c24aa6b249840b08b3fd47a276dea0931bfca6e8b0d4b4986294e8b00eaec5cd49eff55a587ef3c1e58dafc5b00c2373adb7cd632fdb9a69541094e00fe44776e3d78d66b143b7536888c4129afa637c66d37dc0be49c9a01f41aa5ec4144d9d16cc653715b88e869216ea42005e5ed71c550848a98315c8465dce83bcc750e4cdb8084f883af9a6adcb6048b5ceb4eb9b9cffb3c949fc9f8770f4e1ded9902774b52a4fdf768445349a310d7f7f211f678f44967f37b0a7cc3d4bfd5fb285a82ca568e88c87169be4a84b90bd6f97bce393aec894d7b464852bbc55f3c85f447980d9d4bf067f9cf55c756a6967b95bc5ad8427a8c9d3aa6ea99e3bf47a82400d50de189c7abbfdbb14d12904dc5a885cb03df81e39c178a7972917fad46d876ed670c29f912095a01e19af480eed30a44af6165ecf39df885998b9cb4ffdbeb7d71c7a4d2ec0acfc8f9aa4fb7cbf66c49a528a28732f65b4038bb7dc2670f02dcde57dbd142a836bea52dc4460c1fded1ffd6e7e7775e9a888cdb8c2e6b6d78bb3e2667f886cbd91a14735158b4af0ff6a852b6b400698434c61031540fea976b523627e2ce1f6ee4c5d5c878d6d7afad79e425b62d5a56530bb6bf889581045cc4839857fae6bd9775aad46d9d5287aae66c6109e6df54c88e9ff91d90e9c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9157d16c9cb20193d5de93f1f5ddc1580af552347c78a376f399780e59a5a5eec8bb793fa14cac662732815e46d2ea5cd77e96257362922a81e2177ae5289f2bca3d6b3bd169af63c74fcf8e2a3ce8577151aba48c8f8fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = bc859f23d76da58b31d2677f9eee841f5dc263257b04d84419c3892d69db296d88e35b9ed4a57257bbd9286934a0e63326876eacc6dfce3b96430e9560a564706fffbdf34dbfc8599839e0533fe93903c9720ea8dd58d6788a8ecd2f3ead6fd6a97d6f38aaa4dfc87181bbd7e37bc3106590fe18996e5b88fda7af242aa56f4fcac81e33933e7604cc89e2fd67896755ebddcbfb3de7763f9d2c98d4f485cf61cabfe35a33cfbba7d34f6ad2f59a996f5315633b0424ab2f33f6fa8488fb9f895fed8edbf32f6f3e8dd22a5719d3c4782bc1787873e93773b41dca9b036680ba69acd75036a5fa330abbedfc5477545ae8bd9b6f3467aa1dd83d4677c6b5c0dcdb9887ff6b1c9b6e180b8f512dae1a68b9ecc3a155ad84a365a9035841700966ccb3e1c0abe3fdeb4da75e7c9c3a9c3cd9c3376d7a54fe972856b162bf878c5689e8ea7124cb768fb48efe9f489a1bb36614f2bc07fdcbbcbf0d7383ef4758686387072dc025d6b65cd5c861234194448a0224e7cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466c5f8b20affafc943b96ec78666a94f1d91efe4ae6a1edf0a139cd9984be7ff3a237cbc1345a540bd489fec34ceba3874f631f4a34598a7bee976f25e3bf51aeaf12b9365c0af613bc4b2e0a6f494cdc46146efe555ad61bc6dd54b844114781fd37291b7c3e719dcea2af0c86b36381ee49343f92505d4b4ac6fb625ca427de995869443da8d82c8e4131efdd0fffeba76d72a9cbf65f34294b4c85ffabcac3358fe6e93c8ece707cd5e124be0445baa34c661686380765ebd33546ed4aee2f49c371ae3ec82ea6db593a173884d006ada5184417d6ae6ec97f25bac372863dea229e3b7bd5283a4c078a5dca84b73e417cd1878b1ac9388241c3e006d5c0c1e48db78b319293707e9f2117ffcce348e5c0572ecd7718bec7f6c644680cbfa6bba55d51f776303b8b5dcf603356a7f685095da747a3480dae3953788d189ef64efb88bdb8c82cfaab5586b362a5edbe02f74e9efb76673c700c45fdfff97778cb8dbc4bcec24c34927db39f96a5e3c6ee8dec8da58357398a5f13df743339aa7eb74e0a5b85439d9c29a8337f6d83e3663e09e8c6a95f46769b01403bb25cf5c27dc8a495ee66a86698eec30f049a80f786f70af9cc8f7414517429f4aa7652ecc8cbbd9874bae0f9999f0a846fa84fd8d087bce9f9d42e89f994ba2d53ed58c4f9e24c753436b908833c2b4365047da4825eba955e9c5de4ad2c11c3c8f2e4417ffa8efe6b3ad033bc9acb992d77d8d44dc69cb97cd59c7a6cef7c6b46a51267b258ed31166815d1d591469dc2aebaee9b9f86d7c7d10c4fc80077ddab4ba9baac520df512b58ed1b27e3ae4e36b1a4a375959711ae56fdeccce8afc7dcffce57a9520b7c9509075bee4c5f4e4afb45a748c0ffe0c88ba48455629a6eec10f762c26fbd0114433ede91406f854067ec04f79490d3dadf2d43444eb59e2bc66f489059ddaa2f14575a5ff99783caf2e7b40d2a7bc11ae50a7bdb20afa8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c96bf5066a85d1896123ebf297a75fdbbde5a60942ed7f66f9edd512ae603fdbfe6d533e3fc7c127df753ba7d4ed2c5609bff6cff698a8fa53f9746eebbec51796be3d0e3c45fdad8fdfd37e75369877c4d64aefba7ac534f4b6862d68ab973e1d9b96bf7dcc21659971d9daa7793e51b5e7f41d8a30ff4fd364ecbb89b75786a546b346ddd9fab5eb93237d57f0fb76e1554c0dfe9bf1dd8e330bebbcfb71c2ad779b9ea42af586cb27a9304a75ea6d421174dbe36739fdf5ef2eaed7ffdfdfbce665a46aeaeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf51ce53ea4e1590ff12de5857b834e3e553f7945398bcc70ef0dcce8fce5297bf364393086ff821d36ce6f04b0b336bba86fc387c69280bb4fff179eef54b925d99176167f509e6e2bfcb946aebab4e5398a03c17c79992848bdefac5fae4667d37c75bbef31d424381c39722fba787765b3005699b8bd8d2785805d47667aef9372c6e9e3568eb263c2aad8c891ca56137ecb5868b5971445e1dcfe2f2ae1e45cda798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = df9d503d536a810bc927784aac6be5feda774fdeb0550b7a7e656817866882afa4ef78f462e75391298f760fd71d8de41aa682d50787162a6dcd853971665c9609bbd90ab833367a45bdf86d96dc04057c8ed779781faffa2557e2db46b54639103e63f063e6aa9ae2a7d49c50ed3337cb9a7218739debe84c23d4530667b9b544420e5b9f95d1fa0fbc304dd0a4855e68d7350e83728775d57959662504331e6df6c8e5f088593d0adcef39e74a7fa59b959967073bb14eee63d743d8c276ac0e6bc26e2ce65b873e46a7fb720cf24544317d3e556a76c09588c45e4762a1b43c7fafa9dd238ac6e39e9cebaa1945544fd8702e7d66d329c89656499e6c8264daebe58eac792c5a52188e8a954c06a96e146d4e2fddf42c78bdc7763359a47c2c5c4f786f819504740c043b2a5bc8dc0dcc4aa9a8c6354df515ba7e7d39f026863753d067c8e284f866bdda366a9cf5c48d8af025561f24bbf877e305ba3aed43d899fe8b854c501549aa9a1c68dd0ed81af689f3c4a46b19709d0dfcbdbd7f65b44e9f9385c94c4385d88f8c6dfcaaee9a246498646bcfa23d8f8a6c45639addf58668f55a3d3054d453c36876bdaa1b5967e617a297df84c5ef828b64b840be76156ba7fe8640084e4c3fbf47c4063acde6eb4e5c42b9147044b6916fa9be1d25ba72ad35d766bf4c1c336b836b513af3549bbc54eea8fada8246c4ecf946d4bc9b792868734fa755b06a7821e688ce17c9a00c7f9fe7f4dd494b070b9d50bda2963ccf41777f86ba3b319aeea543913d5a653f073b34c64981fdfcbe17cdba6af86443677a25fb0ebfeee54991f34b758b87a3cb79d859ff9a013d31e8a99964f3a9050f3404ca51d83d957f34a0bec4d2169a6bf7163963d87d9d6e59b8e342cd8738c945b832b698665d71286338b67b372a067305f5f99043c884b4ac706f4d070ee77003cd5659b68f36bccde8b37d8e7db27870dd196136cfe849843835fceefed74af31a3bfc6cc33a9883237ffe294e799645d84aaba1edae3b61ba765466b05c84f279067c5a2ae355737c8419993276db16eec124f5718e86a8954adea528f299a8a4c4b8ff91aa90204da64c3ce457864f0bfbe7f5b6733fdb8faaad4d9fde480dcbfebe1b8a389e7ed40f57cfbd62d4b3caad1ecc1283542b6a711a737c64a8eafa7cc0e00ddd7019ae2169bad10a6f61fd94020b7b423bd06135b6522dd76eadac1e9b8f354a46200b3d591e3953197e7aa4f671e3ca62ce7f4256737dd7eb1239eeae36f6ec136b68a8d4742752539da6248db2b246ad86ab59b12499c77936f816cdf15c5873147e37b7ea2993aa1114fcc83ca7b7656ff364f9795a9ba11d75d77da464b33e368b70ce7b484e864efa8b89099fb8648461a61b75bd745597a3f5765f92576878d0f947280cf534cec04ad8b52e55c93f36c56473dc7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b5980705f0ce23361e2abdb22ad803f4af1dfc8b55a594e746b241bbdbba37b285666de853ebd4ef8c7d6b64e8ee377364c75c2aeb6c8e47da1d74cd96fded548788e8f5beed70ede391b0a794fef56231f36b7c55ed25db6419e761e80db080db345d6e3226d38895d5588aced754b9706c43e44805325d3f95359ca2ab758dd43ee54ce457b9734ebf3fc02546a7556b599733c03616d631d5b4ff6c57a1b6c5065b80a79ecbf3d6d4dcf49d914853c87b6758a58d56f4d6c14f30548954242aa79aed532acbbdb9d9a50ecfbab0d9eb0268bd2f14f7717bc5b9456896ce660cab6c312549a9fe5df9c7957b1a9f3d0da7487a812e4f9bb9ff32b559a5daf57c27a96a9a3f7a39f5b1ec95b41623e6f2af7ab257da172f31a93761ccc64689d430d497facf18a4f07ec0b6ebb3d65fb2bf4abb43e7d576c9a67c3647d69e9be78adaf046bc668dbf06ced9a76f56a21ba44c45c5173efaeadb7594fc6ca17bc4372dfef3d99722fb3bbb0bb39caaec14085ccff8b5724d48837dc165a8abe44333999a383c83bf1bdc6cf73f58908abe715bb383c385fc26635283af0853b3e533cc6cc95592cd8fcff360fc6b506b96e444b3b328045271cdd1a58e662bc847fd15924f5744e359c18514a909dae63fecc8a26fec1b2955ab89e7e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = a0eb8fea64c6c0da5d9a26f54d897857ae486c9bff774ce8bab3cd508dc83dac6dc9796100886d14c4d85ccff65bd9c2f13ed34f0ed93d58afd447ca565f6d279e781e4d9649e88f43ca4e9b4aaf9bd9588af5fd126692b28e817abb5291f660adf3a0045adc528bf33327c0f9ebd47ca4e5c806414cbd758dfab9a7d3c28484578c6d84b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db343e68d4fd33375a0322af87e133a9aca8eac0f4a8586ead4776b03a95131ede78f93684a3cda51a5d1ee5b85c4d3f78e8b4e7b2b461cd4602a89e8767b315cbcb8865edcec0f5f144fc2388637eb69ab10dfe569cee78ef3669a1b9e4fd3deadf5be70143ecdf543f1cc88e06ae09a2da5f3b4aabc0b8197783e8a16b1e06bc5e7089cc457e8693da1d5bcc8bc3ea6e91b691a6572189eb0334495ce0e4c1356e7a43e8a7916d69e0574d83c8a453f6db67ccf95ada735a4fde923b5a6d55b087b4390e975e6b3aae56d6abd45d0fd54837ff875c54bcb7b5739decdadab84ee57946ac0948ccef5ca791a46c669c552b97ec35633a24eb92eee8b0dba46ddc64432afd938b9f7c255ab78fcbfc9653e1c0b8a104f489674c0f79c30cf8a5074ad6fbfaa888f9e4d53a3b6a874e8f5ec6dd5a6b56973bdd9744d0e03f7ab59f91caeb1aafea68da542fd944b3b88c6c364752fb6f33d27a792e6a041fe82422dae9afa707e8fd6966a4ea46e681627cb346572619c9a7d539db7469e60177e98674398faf96fd3d0590dc5da17a80fad6ad24af65ac7f9350ecdfe3460921596a8dff8c883b0e1e483650bd3ec5d950de3af481439dfb98447f3406d9ee61e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99d8f0e2ff58825988d58f7b5b25d6a11f96492debd198f3b3ffc2a24f387f2ad67a295175f5922efbede42d711f0b729a7ebc7647889ee86cb5f44363a99237aef0dc837dd474baffd381253680f00675fb48dbf96a89e38fae67d3fb94ab48e46df9145748eaa76037a98788c45dde85d85d9c5523a730980474606f6f8946ff7ba94738c5b9ba1be1bf66de855356e8cac1195cbb2a2ebfdae8ddb6b3bd9916a7c6cca2829e4f4fa5ad27edde6f6acae0db49aea7d756de6b2069b1a7fcdd7b879af40ea9bf65e9683bb3a5abd66c6fc8d25da3175d8b8c2c62a80fe0ae59b3cdbdcc5f3ed55c7a638f2ef42c39855545b0a98d484fb555f0fa4bb059ab05457bee9fdeee07674716f8f81a32201e3a8158a1ad1367f128d2f71b90a8b4a1cc4ce6553ce1064ac0150fb8b4b695d19ba74a9e673a963538bfab14333634ed4b0859472ecac568c87700b5d76c9cf65a4bd662d4f50ae5cb5387ecdddcf473f7bcc52ca97cbde8beb6be5ba5420f8bf882f3acffbca13193c71ec6dd168ced9b256f4706a19204a0182d4ad28b6a106d7d61a97cb578cfc9633ba9d6ab84367caeadde5dee47ac935af727724af3ac8f0c86ed8dd34ea7c7f543d889c4d2f6b7be7bb6c77524e1120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb41eb338dc8a8e6be0c08b3ae26c945d78df4ad35dc07639c68e301ca981be35d75363b8d3a6b2165c99c0c6ec298a502123c40e1cc224cfeefaccec34576e206456cc18fcd4048fbb576e720bb967f5b58763342c98ae883cb24cb3fe06398c56eb6a7b697df19f926a8c76dc26df0c577ab476303647bad3b6951949acc2a69e7948d7a77c7ef163a25c94f723d85666cef1dc96f2772caca988c5e838ed2f7d55668ed0d31688b1aed4d057dd8953b82ea4c6aff5dbb96b68f65f4ac3a5a92ddf6f27be42e389f0ad46e11226c763e3ce29c9c1235c8ea40995eb867ea8e844ee8e9c1006f272d5f558667f422ebcac28e5ee38d6d863c2301da20e74425f7cf2b2addb520a5042bda7f594fad00cdf19c893d7f4fb1ecac89d9a989d8c45dedc5621565e2e788147d4fec4dc6a8dbffd4a29d4787ac8b85f32bb13aca7f3d825e865beedce8ffec7e227fd759873db265638fbacf7763b80fb41624e7559b3fc2d6cce4834be3326e81ea4c5cd29687a498953998783057dfa9e30102f4325cfd7b723607a6e62302d377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = 935770f4a7da8e4b7b84defa1e44c3eb46db42e77bd4435fb6f65cc14b894c387d0445af3f28cc2444e38a07a667e5ac6bbba72dc3b7eaf788d97feddf4d34a53dc2de165b313733e2daacebdea0140bdad5b834411b83267f8eb325b1241d99211fa7c5ed5dbb6de7a59ba9777a9b3d5a681f89f52e2ce5ff8593bef7cd3c059153435bee16cd2b8433f08dbb21cbad40c6b945d7b6ddac39d1ddb558c7a42d9bcc701aadea67d7f77498d65f7e4f1bdbee8349474df192dd6f471e6a77b884479a75a585a0c31d5343584aee03ecd8a7aabbf669a3bf518f48d5be49d159b974ce43c83ef68b730f4a42a942d9ad3ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cc5dfffc35c6a8b95173ad41623daf766def21fdccf09c4012de705fce305ac95ca13e43e2fc93e7fbd07e83afca94ec389e42bfad95c754533e8d2183a9b3dff796fef988194d76d7cf235f39d251bd8085d762a0a31ffd261318ddf6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc47ec1de16bf2ba5735add60328a8cc01b948fde4197286ad0e8acef24fdac64b4fe36dcf066886c8ca9292ba2b43e5a2e7e9c53b7acbc6ef5bbeb8d3df4cab0bd8ac54b8aa38e6d3b44630633e01f3b69e15c32c8e6912e6ecdb37df735cfd6863c9b488431d83dd0e59c36e13e471bd693e238314ccf82dd8b4702d334e5985a8e99d4604d65240da9dfeacf0daffe5b73ef00c434085c5dac53bb4637c624d8ddcd59a2205c8c5717554d1e4999e79b7f0df1b7a6ef007541d009350bcc427aaccec1bdc9e365621425568abf4ae3cc874ff7c0575bd9f0e8f23e5ce9cfb381a8d7ff7324ad9f7dd66a2d4b269dbd9ff6a58adf6e0f2bbe575c39cc3d4ed5c8b693ae7b65a7a27633e44f7f48eeebc4ad9df39eed4e8b49f8e85da0bd44c30315647b5a6bf3e5955a7ec9f62b44ef1ef21ef93fa76843bf3f408563c111447541d982643efcac0e4e7897afbca8618a27b56bb9725baeb7123e5e30aa445537bf03bfd1e546fe6b6b82f535d6cf9cee82f791271fb6ea1f6b7f7f5b3055ed210eb76cb575ebc847dbabfa058f77203be434f9c936da846a6773dff4e93e0e9c7a86d1fdbee4737559df7aac095849692831157ae3a916d511ed5bb9f48a025d6a08f63ca5cb4b032962b6d484e8cb742b17d9023b992666fbc83c72c047833e27760d6a8a8c559a0976d02559d9db3668b1efc8bbab674148f7a2d8d8bf7cf662553b4e9e66a25f93204dd320be5823def462c7e4276c743b2691e6a3f1946cad96f9bd71a8ff47a7dfce85eb013630f5aa90334c657d286f94e3f5333b64c6bc9955e859f8d5ec1a6e400388bb9df9efbf4bafe8853b1ce98ea01d76af24d6459bd0cd0df2db4d8576fef6d95da3a1e5ef31069194d65c4df88b94d8b43a4b6ee75e654d6bc72b9cf83c59d93eb3b1dadc9bd329b1196f542da3b770657319fe3fe5bd7b1e2f482c14e0652a3b53dff1704df8fa47c3e5934c364db645af82739e96ca366e1064bf5e57ae74aff9e4fd92c3cc91e8e833c4f3e4b6cb91e6873f35cc4ad2c6d281c862baddca89bad9677e3ca0e973a766cf303aa1092f66923cba1ce7a91964440d43878fd359583c6de0f5c6c874f4a1096d5bdbb843a9df0c8f85681bba7af8f008a56f9a2f67133b7bd1a55f0fb37f84d6b2609cbc49c968935d69aab3498ff7c98605f3b1ffa1512a8cb5a6bebbf6ff29adef2d5d738963812569e2fc58fe9ef57132ea5f606eb36a6ae7366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8abeef9ccd6c797bf883ff989651cd4af16b339ec34923ff6f596f86a553db346fc5f1d56a369b22c1467cdd4a634bd358508f2176ed127aaa145abfdfe049e6f29edd7cb4d0a8ac5df064e64c9d2154d357c4562302bb0ed0a6aa94ba1dd55a50829a5750d7608bc61509adf17e4edc3bbcb8f9ec4dfef5d2ea4700e9d53490f604655dad1cf768ae7feb0b770d45a7417cd41170e70b96eeda2958f44c9b0617de83bb3796738f063eda93eb5bb4b3be5a425fc6f19b730c7f4f94aab64c6db7e05d90b35eae039d747cf49b1a76c978f5653a89915bece70a8fd3cd437837854c7df8f871999074bec2034d88f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 506490a04f4a165e5fbf534b4f76db09f9e46d4dac2748f2ec1e6ac60782dd5e9805d4ef39b3d6d8ffed10dff64b8bb6638be13144b0d459ba833965d3a39c51355416f672b268e1f6ffce8cec777bb3f2cf5d6823e6d05e1e476018d8ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7f0cf5874e5e90b893039493204f67e1166de4a5efb484781c67e324f86f18976a1633bc4ca4cda6e9fe1c7dde71e0993baf46406f8b860adc7f065eb74ab81d74fc634ea74b269837e2588228a8645764a2b9a7bc2b8d2683bf2c25cfa55439d15eefe620363271a4468fcacfa8ba687febdbfd7dcaacd961f9a488b7962b8d7e8b9e7a33d8b5306e6a05616c2a1484aa054f00038624f65b8a92ba4739c714ad7efb90efbf92c5cc07cfbb59367c5c471bbf6d99d2be9c9cbeaa168c071dbc6e01c5c72fa33171c52b79cedec4fe34dd8af5d147bdeb3fdd6d5f451dee2bc6add9e03b06e8d71743d4972a9866ae4bf6b053d9878d85877ece2ff52293972c42c4bf6fcfbaa0eece53f5c34f89e7e6dddd749ae3c845f7d5681601ea2fb07b9e3f88cacc5ee2fdf58cf5bb982bd89ccae8f903ce4e055d3302ca92a3e9645154cfa878cfc777f2093a00916a617c6d86d973208883ace18f70fbe6be4ec404fbf951cbeac825840bfed9eba19a90b63e6ab79c3ac16fc07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f29ae5e49863a2139ded1e6d99374236c8a7179d53fb7e6756299ed27ef5d699c39367e33fa49fe0db960a8cbc0adb979239b64a7b3a702878fc26e0868790abf3968873ae5ece9021bf8f1405cca2bd800fff36e12daed615789226eb54bb3d14a4c650aeab949648020ca86064b17fe8b3f7e9e5c72a68e2b46f16267b7598bc112537b778eea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccd5ef9a5357fd4b92ce59d6184cd0327f7c7a966bf0c485aa4eff7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c340dfd33c14f94b9e323f26d2a6da351f0a6e488f64e0e4a6adda77dd7af535a748dbad74b03eaf0295d9f3cf7f160ddf60f7ff7b7d32dfb99d50c88814167a838758c2685243839d8bce9e76133b40dac70e49b33ff8329996fc3496999dfa90470b7bb17bcd150e9b093b5787abada277d0a83377ae67e73ff5f8d6dc35efe846d95933d78e44ea3aca554ca0e873baa6bb926e7da09306621b47d5942b4e0e6dcbf30dc10c3c4d5f7c8c75899aeaea40cec8928bef5baa2c7f139392221cc7043cd5baf583721ed492ccf126df7a9ccdea28a3855c98b894e4e65689af3acda26a6b920874728d475daa83e940457b24199d1194ed5bc369963cecf4afdb6af974b325d18a9e9959c3b4e556c570cffe5597b64506575f6799dd86cb0669651a2cd17c8a74e5f63cc60b9048cfedee777df71edbd6b6e4f9a63c72074b7919e37cc7e55fea72bedb7429edb197246af7aef1e989f3f96eaf320ed34afee796ae80c0c6c056d58d848a62380f78308c4cc2b466a8e7f31456c06e4b9f1faa65a90de23fa9f38d5fae3c4af4600c4e943947c8c653c946bbf6b4cee89646aa23afc8cfff0d45464337a90a8cf2cbdb444abf4d5bf3c070778773c9f0562d6ca8a5e05e264c9757918f6bb76bfc93df8f6c61c77b6b5eb1369e523537efaad3cf609cd034bf581fd5f2975f57eef576ebf7379a173b1b269e27648189696b30346d530fb560784777f88aca2c9f900344eef8aa0cb4a86ed6335cef9b91248780674bbadb5b11f967a663c2fa1f9b73ec584d5daaae9771d268f721a8f61f46fd9393d880e4b60e5be42b48f28175d1c89b501178ea5fcfba2b03cf9fbe886c33c1c72cb6062be0638931e6fe46204e3e5766a7becc59a15fa0e32ec6419752258955dce743131890bab88b8dcc5738eb6f40acec0d888de2ddc5a7cbd3e90e71c2c4edfe5eef74c5e65804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca5ef96f0d975f2f5731e9ff628ce964fcebb1ac7452cfdc5c0735d6f75304efa4410e4cd20557b574cad1674395446f03dc7f8a58b8e0ba5e83d1d653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = e7aa41194214caa340115002a25d547f794ea33200dc8a9ee0fd033e181ac23a +public_key = cd081862b08b1374a434d4651ed493bca64ae33aa679678d595990e1773d3fe50749dc6d91d01407534fd0e0918ac634f5500f7979985ae49881b98bddd466fbc157844620c1f7c9b85bb954d3cc5bc5b925d300e0769045326a1a8709642c2391f060707231b8328e83584c36458f13137b68c67cb44281a70222ffa564465c9e9bf26cb375bc5fb84375865a3390a3bb37ad88f17025e95abcc91b00db8ca1d7002cd4a80328294b734b009bc2d5972f9fda524081463fc1b87f357684a605ad3009e4ac24a8508a52259c78854671aac789e7867ab1b55858320fb531e61838cb489eaae703e40bce9414a410e85a270a908294a943e176f1621b49f661200975564b1adfa76ba1ec1f8edcc81e20b9a70ccf441c3115f2b00dfb99d9d505e8278dfd09a27eab87e614cdf9327bdbeaa203c5262eb79aed09a732b8af3f1c76dc2658e2853fedb0c8b44bbf00763d26dc4c3fa78ec3a93e546818a19bbdc03b77622777aee9bb69f676b0b912e74931dc036a74195ef9e179c34b8c8eb461e37b7df202929f57456cd602fdfa618ec718bc481f437758d982090cf8a8dc8122a948bd326c190349c580913d804c408c8c314275ca4b3a74489625727cca371a3d98 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 08a1233ae8451c8d300783fb93056849f6bf554252a4c35a517d4bb0ac28846a +public_key = 3697ef47868e5200ec555be6c13be1f824b20b4ca32140ab85261fa257be11c280432b533b1ca9048575b152e5494d787605190556df028856473b517c63dd5213ef7ba07b7659a3fc0438f403cec4cb08769e4b497c8d78477d25b6a16a8f8d047d2fbb3cbc345307eb4ae5215ef14c42e26064c4b5765da77ab1bc6d452a7470792d12a7157113cc49931375a85522363f00fd7882f8391d105755b225dcfa50cec1c7e3505c4f6692a8638f95306d5d5630b7dc40f370c8a8b4724a29af26c85a2b92154400863c598813137415100c6c5c6f5b185b25137899fa18efbc9a715bbbfb355fc9b6b769b01962f19528e84de7251c217240afaca67c68a32fb60eab3139efb078d3a4b575356491645eafd655ce2a0613b0c1394c2b40e517abd9adaf156ee7b7c52a0471464184d4d2ac755263ccf24e328085ca6427d499caeedb0f21605a9f105c93405295b6a97a44b3cf984ce8312df1016ee47920ed55618794af817bb689a58c18c2ad3d1ac3830145826610e5801a8b0a7d383535d1795966a8a76441985dbb3c6f6273ad886a7a028aea94cf59b1547ae7c39d925145c10aff91b4695c42f027b73430942dba605a1576e77c7bc339a2d8aa5e78c11294609231704a5198b859e9077125b97cfa33fa1794185244f8f89f5a69508d583108243e81a96968da58f038cefd506a81742c4113bfb443586426bd27d082ca979922d95d2b47759247c6b19c20f71575b0fc1826b1bc0881064961135ba9536271851764390c4008830686c0260bd527c68d2023576cc9678a348d053b9bb0c3e92619355345e0d998adc8c091b3950dc596f8160fdac8c8afc439ca1524da68a46210ac150c9680886c7b904fb16ac731244fcfb928dfd4cc4d283d74830f595840d38030bd3573f6c62f18273ec94a5ac17c6490f17ba4cc9099f9caf9a49bd09224c3b20c4b0b1f3645614828cf773c4b3d879e2f975950f14b75b9753544cf01a7cf694312d6221c41f85381b7a2b885a44739584037a053d6033ad1a3e8b430fbb9b5555748e3022abbb8344976b3b4501341c84074c88b94ebcf241c3df5e65eaa790005314cd1da729e9c21153a03705158d93347188a299f20bdea847102a84d01d2016d34998b82b679fc35d4f0043762abf35c68c080c10846a351f650785409a9462a4b2020ca583c831723d43470c8f465f4ba3dbb78a67693457c223a40152c9057894ad63acd0950274453196945280036d1020ea9968c92f00ceea80a8081248e3a4b1b86ab83813ca698269b1ab402857a0cda2ea4686d246a1f4c3972398b0af98a89275a86f2f37033bc8e5364b75b8b39c8c45b14fc0238408d4fe4bd52f37d60fb8c51ab41c14b4dffec817c5812a9ca85cc50a5d5e5b70d86b5cad058bd0260e3bc4014fb41cd06455cc35046990e10812a24792f7e740a7b98a928e96757dc9b7f720b197c16a0e8c11c3cc54df235e7256807e84fe03ba4393b6d16484e9d2389f58168a8ec17d9f23c95a43cb0da21aa1958652011baba439a651bbd2c1c12aa879e1a08cf4c6b3f39393f5482d055186716cacf0846ee1272f09f20ec988f11dd41b23e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 9504db1b73df385fe1325b11ccd3323052f0c861aecd077f1128a6a70c96b530 +public_key = d52cbc9d566e9be256a08213350c5fd8403c609c238daa4d710776d281940e762981c576817c4b4a137e6b6bc0be06badc2116aa40a52e282837cc6826fc5397b2b37f24983699cdeb6315443bc003c2cabe2967161862101658fbb31b6530b5c5c4633cb89f5be7b980b0184552180028a1dc3635cc7ba186667b14db99735b76086389e0fb3ec942c96f191dce50bbfffa68cb4378aa6b8e88036f469ac042060fe2e0bfb900261fa78440396e2c90759ae3b346aaaba95122068a8054366c1774ae5156bfaff6933c8c03b5e911ee318ccac2c2f344bbe48607d0d665858145e55909cb7658d12391773c7551ab0283b9a9afd07cf99795074a47d03a6998ca4913c97909057662f634d01b2337c109c73928606075d69955bf99cef3d448cd641f53259f7e12698610babf1c51da87331f56b80b851c6a818f46cabcb6f3826e353f97c806 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 985a506de024e2a8eb662da102bc835ce2ba861c6cf4add4c9f09a4fb826368c +public_key = 99699c47b7a9a11e88d788cb2a509e6099b3a6528e5865c5ca78465b8899e7158c8c2b02728e4cc60c73606d4e2182430a46627c38a8b2bd51e81be4003d17ac3e801898af9ccde34321de0bc5cc46beb6805c03bc63f3b7001ca496440a2b51850bb2d4119d7bc98be9b24d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = da47de23ea8d972b4212f0f58a0fe6fd47654c86bb490a8b4976e9c14f4b6ccc +public_key = f1b48ea13516f0bce0f05ed70942ec438628b13de6a9a34b02881751537d1595a89c48a61236cfd6661e962b30c3afb212a9b62a01aee98cefa0ae468206abbdd776deabe5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 3cd670e828af82544d1877fc27218314a90f6d52b8676fe2a1e6aa2c5ae5ad2e +public_key = cfe56d4b360b9cca754d6abc4c78126d793d6a726b1428449e031aff591b0fbc45deecb10652be53c4abb4391cd62a2eeae06486 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 37093904498ae4743d282481daea6c1ca3178c2f1d626696273b34323d8d837c +public_key = 91aa43b598a900235422cf8c9ac8d448a25269c7f507c34dd21849816a0a70a503e62ae46b44dcf24542891d8b033ec907ab6cb4606a333c4d441519fc3a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 71d027342e3fd6d3d6fbcd3c8e00e29ea5fce9664fa7c58b615f5128b67e061f +public_key = 1bb026ca22f7677ecd886cc920a578619d1d7683f5544f69db2120097a9c04939bf9afe8f38dba7a9677f09ed35a1a423187966bafc9b201ce6c5834e437493b9bc1b38b633c4dff2b26aa0962dc50 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = d1bd79ea1afb6b51ecda5fcf663a6ef8074bab232ec352866bd122b8ffa75adc +public_key = 14eb50b5105954c3104d24a27f4ca35aaa136b7c0f3854 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 259b39143face8dee2cb8255366b221caf7fd595b3da4d86c63c9d47583aaa95 +public_key = 3a43034e5d325b788a06ba631fd3ba33cf56b4ab64b06273b26a647779925f8d3050241a91c6ccb20759a051533063f51a5b22a52be2551f071a39d88d7f28933cf91eaa56753c31c8c907789e4624e1708a921477a6b079faba8f30e8cd594166962a3120a62d154a6466aa3cae8cbf59ec9f31c55c50f1891b99ab1dcace46dab79c35a3e3966995c87dbb361e39a6ba56559350d10cc1655af01518e3bc6d334cbae9a5485830a7871556687c889f973d52640d75627f23681ea5fef9c6a94fbdb832e52c20d01759ad7dc0ce564f30 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 2fa93d1de7c718780a4344565540fb38cc33692b6feda37e5ed8e17a50637b97 +public_key = 1f962cac337e91aa2330c41bb34c8079a5c7d21655a53539b96b52192389788147a6b3921821c986494410b19e4a2997c374bc4d8ab248963865dc84b3d2b5902b0223007be1d88a89868921c31e2a3750f8b3a62372899318384506aa82b6af9e1b151c4721a679ac9f424cf359a605d7893c37b04ef7c196a70487380bcefb049036870bc91c10e897a18a99f286cc66ac7b13d79472eb04297b02a6d01965ca9a58059f299742b40a0a98c8327443649d9825c5bca111c8c1c5857f4f636e8d32ac08c27694ec430eea20a02581e6b073081c5e4ff2205e22559dd18bc8cb9b0778180740cef50a31d9d1b86cc679dd4702bf142457d392e0863b74f0b9463374bc03192bcb0724dc60e29c61361b06933c3f16d99b3ff27c77aa1d0435ce65cb391a8ab104458e43b201cdd52fdf294f75aaa3b9f12018354d39b548487b65e61a4b606bacd7574e18a59f788ab65347124d5398bf777b277aa6cb40480ab212ed66b1dc272fd35baa0a13ab168a3c6663170ae7300758921e848c84ab680c71ad8fc6819e4c68cdc41f7005c8f8750f76eb3496118401cc89523865cce9a1131b5124690c5a03ce7821844a5cc8c57b91c3b477ece61a6c2b59d63648e0b1c9a0740760b30c1d64b942a46cb1fa452ebc5fb59841b8918c27235a3abb7f79678ee41c534e2a6dc25c178fc9b52028be5e77bd3747bf093b0664ecc88da38af6b78416f7016c8a75b5f5664077c72b42b953886a21470a00879d45bb9c66a809577a8329b9acf039791db2c640b238e00966235392316ac6055750f07c8ec0f71f0dd877f14659c1590db2825e6b49a3eeb2aad78982b963c555f09125447b898c8c3fa58f338b9af0306f9dd70619951a04bb81b3759290f28c18712b4fc35a65ec2297d11a60527c62c102fc30c246a62a71242138973a39d65f2d05af671633a4a3a4ba034afa226976ab764da96682f9aed2b66482a749e3ac887244208c709373a15ed54579ec933b99c80ac3c4197e419112bc9d280a038ffa7707084203662eafc162c7b2811b843025e3c4a6fc1e94f4980351c42078cbea194ef29981a3e46ca2c1c5276bba7463cd13b415a5045819e1a1e6a3c5c3483829ec23f98a424b469ae9ec1c0ec67e2c27cc75745e0104a70791487ab7373868c1a87ba2eab23537735f4546161b5baac13a327749c5ac82a0fde5b02985b3e7bb1218c2559931017e179ece2c42f5420816e22d84473f15325f24a110eb2528f5bb87137cb7f65b59fe3000e13a51f1741a6e790f93a358c89177d2689e82a1800fc57528f8a5aab20022c73abc4095599a1271a5812069bac4236ae73c3a4749b3dc403e575ab4cf694843100124432825824e0bc903a970a04b5880cc27978508c7362670547c0cf7257ab37b139648335455b874b233711537fdd30b80f57898b264027286fb7176ab506ef35b1d090259bc6aa296d3a7603180cdfa69431438387b6b6ab9571d8843034594135b0c49c9c60a11c1db4aa57ffa9f1c0a2c1bf58370d7153e742bb32534acbbc9f1b97a26485d35215a844818bc154872073eca438480f88c67d333e90090fbc19d78e5b913871ebf9737eff6221083584f56288a80c5dac7b8c7d4149eb1ad3fe944601a5dd1db864065753eac9891e4627cdb1f6da279cb340674900abccc23578a3a7de29977303fe1505d59013cf3025544f519e7b51b4eb08521e4ab02c2bd8ee28522809bc3172ff88700cfe6c815d74ca336920344c908fc7a23b9445dbc774f36393e8c1c81b26c86843e96256e9cb35400b2128587a000673228b1594cbbc524aa76c8185675c4601455902ef64eaf7c3d03e7b6ce8584ff84595d55220c5c639a87a0f087afdd307abb071c8d2129ea1762533b2b5081559432c0a52449875726e51b5cf2fcb5ca39b03931c7f8f71f618b7d7c1246228abe6df956b1d996fc1833f0a15abe4c88a071b5afec8f9ca389f7039bf89920b9d68b52b78ead68b0c646440e347f5e6b0048c4c7d658b46bdb0ec05592b490c5fd92b46a63ae4ec20d3ddb65ebc75a13a3916c6c57da248e06921d0dd313ddaa840854870534c602e083afec3b227930d3641e1998223f6266a97138f689898d97bc316982a61b735cc3bacf277644b46fadb0c049bac408588ce01e17f5791e50d62574fa3a4efaf76a1e2bff01d7b06a1ea842d1b63e3cba5e50638d145c0f36fb0adaa242c663a98e1fdac1766dda3f3d0233 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 3d36c670e23059028db121737c0ba77baa3090d7ac3af5239220a6ee6489ad85 +public_key = af1c4552f3b2a9d9b3db4aa9ed072165b8af38f8af5297b57ffc59e3f58cbf22a03229708db1972f15a59fe696e2195c07fa8d0742c4e3b3a7b1a56d2d6a582a4747cf679341d005e0c628af77278174297ab98eaa3cb157d3cb94d4bd17ba6a55ba903ca811218c09309a04b942936bc01253e5a9dedc224fe8c90d2b6c7f09b8c4d72922e32e3a7a4f58ecb3a3b75f23c9651fd78fe2744aa634805487086eb6b59a37163d158ecb04b7e936c7de4540a068be94e3849740bab31389392974878a9093672b7d8479004ab10fbc459d93c1a2031b4a2b677a4437b137c2d67829bc9ccb8918ca97fac81793adaab412a80309bc153c2bd45302a99a234330ce4604cb9cca9ae249a461036622893d48cb48c514328599a05cbbc12771aa83041f3c1854037e4c206dc922408354cc0ed5c5423c52b5471937388a81464fa66483300416d6531b8a229152d02387c5b0402010027b6531aa0f12d54a065c15f847789ab9b7ca00908340b8bc1792d8f78308e19cf73b0d3b4ab7651c032cab04a45666148c0ac5416ae5d14c875a6ccbc66fb8daac0bf09206492985f4cf721ccea7616109332fc503979a2a1ec0c72b9f9bc8c283aede7b7bea2c8d313c8485f126ee99688f78bc523c25d150b88f546d35784b0926320692187db06b16822e3516b5ba015a3c337ddc9657f162a9d6e3a956a4a68e2013c1706589963e001b47db90624d742ccd26508b5b924016bd8cc3252b7179a37927a3456f0a296d32ec10e3ab6838ec0430ac6da31867b8898f7901adb4284972d4ad1588cbfa29b7eafb5659430722a0213c7c165c95658d6ca34bb4cb6d528a53e757da2c55297378a9d96a82097f9064159e1a5c7c654947325adab994ad478abd7abd53209ca6868a28f32e0d1874fec99bd23468723684bcc2cff360426677a5cab2a799e8b234d32864931a6a3cc767e33babe80f4aaa8f91a267f44a345eb0cf46d38e8c30b5e296716ff3c0fb399988a700cc45a3bba65d6f6cbbcfd295d217a4d4aaba95c637d476a2cad60a6e0cbae0fb1c14c4ba34303adc06056ca1477633072df854d79a89ac3a3ff120c5bc3c29e26b8c32b17729d6143f102f42553009f0af0fc16c09a611728c563a4777fdb98bec55a15e119e0c314af09301bd522c6441c3148534d48a2415c740f4c20aac396d747b817804bcdbb6939410b4cca58f1792a9bf65301616c8d70891a4c55999166358629034270ccd556ae2678eeba1a854b5125de973073596a7b927f2298ceac1855379146350a343fc4863b3304fb8a153f00db84874f69140a8b48376779a84433d44ec4e490099f3e64f0c4149b4d049ff536e859161460372f4639ab3c5225e0452bc569562664c4dcb52f845602014050b13a71eb50989629b14ac3a23e4a4e27482a23c1aed794f1be7c2c42177eca0b935207909f237fff9c38f59587425cc60282be157b6f2828d7ab9091e550a048514b94a423531c2f84260cd23485cf0c87c62c5425190e918312918881e686cc5d46c1188cb6c260e8d6aa38428ac09a7a179210d75f24e4b96804cd49be4c031b27310bbb4904e2a3c40620e89b5c6e1c932a77334bdd86dbdc8a42fcc4bb5a1a82ab55438b56229e4cd95428912414678b85365d66f94446945d29f04729ffc936a26055e40babad676add68297cb420af62752524ac0f2fc13e1a9a1a3885afd379390e102c1a5519c7407e7179a05669ca4aa00596c5f6c3134618b77ac6025e3b9a63aa943143abacc989ad4c749bf8c94e5e18c53180491338afa102f02f0710eda83a20715f53b65b68b93d9e26fcc465654d45df4b1496974a6132520f8155e1e97680388c09a027c1ad02be1ea4fbeab245bf983aef0868c4535b38aa8f414081918711183279f11c7180a3c86934f86767d775c265dcac709e84059da4992691f3d5870b2b116221c1d7a6c1070524d1a7bb432a71754f68381b4356fc6cf478013c71854ec022a52a62bb0136db305567f263aec40ab171aa371c540221a671f7010ed673e131c45c6d989a283b2da7645820305d45740a650c03e48b27f5b4404c14c6c0058828a0e8027b48c5c00f0f76ad7c67cbb73cf5cf24649e4622e7310af35cfe45070065ca66df82864508702d97d0e043d41b62651cd692a043706e2231784ce30140579347cf04ce15704bc58b0460de5af43cb95e16f32b200498e02e16db3ba2e434de9510b0b520ab7e7041a2e61b513b0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 82901f10858d3c07a19dc72d8768398c85e93b246d24c5378201c3a43bd4b356 +public_key = de578c79e54b6a93356b14151ef20e44f29841ca3312515dbc85644bbb7845f17bf14529522039bc641e3274b936f016beb689e1112ad54bc80f6c621e3c4f7d702f4ca7262fe4bb2a996cc6fc590b46a6076414f47ba5724b1eedb45986a4a258468fbecaa6f5406580311358957c6f1864a5b5027a9a7e184c97dd605055253da79862dae61f3eb51f509c28de536125e22194d02901279f136350af890ad0a9b2b8e8992a98c96d78b00e36a98b9824b35590aa068319abb0272051b210be04608fed4b00de1c3f96667e7262a4569871b3f4988b90b1a1646d9c16065a8c1498374b430a68a020181a355d4e6b18b1c17cb9c39f1498ae368975c3c43a31ebca480c923d270c207a121aec807207184fa39e0c43c8d9d494dacca399ab01df9b3506d8aeef374eb8e01f0186c2a85161e2bb221f09134fc690114825b99539d54b22d4c6926486bcfb4c1e78448ebd4a8f6fa04b3a7178081b3969d24214e1966513bb2075a4231959417a164f386779172833386503f0b963d8648dd138fc208c3ac611f19b8139d6b70aac5c42c11726508fb5b61141a99a73e0cf22554c4fc66add1779a02612ee1583de157aaa2204d3e90a7a1719611793939c31d33391ff1837cc0bb2df5080bba10834453fc6a41523daa21ea5a6cd73878e343225d534bc2b54fe0c1aa6859fe8f5bf80eca239a030f9bc12b7b23fdf905e61294c2440c8d2918215b1c4823b55052181abdaabbc225feab60ee326a2f4079b2fd1c6336027138660bb68279d3625929142958880c5e362503889b01345e4b49af6f034a8fa79663299ad094ddae57a74d9b82b958b3f029572d94f75b90b092571c61766ceb49d755bcb6241be35eb07fb375a17f66f4a2226dda7a0d5e5258b58350cb53eab008bd1185195e06ac1c4ccf5ac249c0cced342b73c723c38c4926f7b9765a23323c22eaad29d6e91147f122db7d8a0b3f477ca798aa35b7283164bebda41bada8ca671c12bb107ad206975f0ce4909bff3f01de7e46a0fe67140234b362a9fdfd55ad4c49a3639c210d0227149bf0fd71b9aa2a42ac36fa30560b834a1546b7f3ef5a965c49cddba0b4c7307c6698b27e8217a7abfdab7a05c825500196499ab2ee596022d384f393ccde8892a636c5e541b1459306b7fc65a2df5bf5a0329264cb104924145e8168d207e3cb1ca3506129ab35dc5838e0b5b618d8bb7ebe487da808dfd875d81097fe3e323ccf32079a558a0855b5e40225f3443d14a46c84464137894cb08c59b4b1256f3a867ba2717487020aa0e63ba95eafcbbfaa20cdee8a903aac578a34dfe5a83dc65081f1b5f81258fdc59bc28c21c9d55444bacb71d2c717e69513014036c10a501b2a2382a5c6943841f5828d8b812b1b27d58a06b085c26c4b57c88fca7f6b70eb9554b01b7c7abe629afd93cbc245ca7d1752fe710e03bb72fa794d53931fa762851d6876677cd757c22c7c649ef38459c655f87030bd2da62890b5b7eb370b329cb87477a472a8b21349ad8e0ab0226b312553fb1e3a65a9814c7f4930363cae0a39fb9794f763212304b3e44e507f424b195aa4cfd7925a0435404c62d4ad8bedbd31a81ecc9d35ac551356c1d9c5636a2cf54b42418d06f968aa4535c779c0b67dd6b4492866cf61c83dca62ace4bcd6406a8d5e48e06e2077155c74f34a7ebb6ca9ce3971e977360bc1ff8611c48038fb64bbaace648dd34358ea4b597b86037e97c603715e28434ed1635f4c06e0ed0053fb0996c0433c50b0d8d76887a14aea51b28fa0185d43439a77783c603a84c1042cbe022f3b2902d88960ad0a9329c83e1f401a7f3a88b07ac39ec6883f2092e9b486218b87537090bd3464c982834c38f78b79aad612749475ac9143d454bb2c4314fe1879fe4482949545859ccb5961b7849337147972aa841117bbc72a6b227c967ada24c18fc25697fa2b42fa64fb547561087225bbb637be65f92f3a436167b1e98adfed33d7dd83e98509c8cb07174ac1b9b075811f9c4b89225b37824d195c37b550ae6995efeda0acfeb041825106af01888497cee11c727b3aaf3492d9e016c5d704a20a2b985d41bddf5c9e9eccfaa690770a0a6172019ac317413989b5301cf2f189b7cf89de527b9f0d63c6214bc5cbba81886581e37bef066a3abb098cdb0a4eaee93efd2c89f36666d4bc665d4ed5b7866e892d06ed431bfabeb668d6726 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 2a5cd1c9cafa6f458df60e27bc5fdb21432f31d5e3fd9872c91c5024b83a4ad1 +public_key = 89122dfce6590d10c272b07871883d53580a604c99ed108155b4118e3247ae78653c80a19d7387086c16a7787c20d1c3b3356d6e0597ae8b765b47c34471a4eaf850acc11b8c25a2b2038159c553c6708b34ea71981a20f2e5030f91bf4ca26d32fcc2a903939ef8c893ea59472c9c98a26d644b3d25781fc4957b7d3cca768240b1b585d77bb6ecf4ce8f070e47291b6b743d633a8aa2eacfe5937b9d860c04e546766b53be6a6d88497bd89232b7818aed060e6da7aad17b1fb7642dea1b2ee4ea29186202a170c5a5b60ee6437d01a19621ea9aca1482568ca5687793d5e949fff38cf5b9772ba977c1ac5fbea743c31a90d8b954e2804a5b62009c5690eee692d73ac266321a5a8bae415c23ad85018dcc60f269ba645a6175129d947956ff130f1fd101e4a5bb30c36e08066f28e7c1b67c87e34775f2197656685d36b810fafb78ed581e4dd74179c46178301cbec3704e3ca468fca1deacae7a02b554c49b947609f0571c387376462495645066f9080e98e8bf51a4cb36d96465b7c30cf9ad5f3c1bd9429e51f1094916502cd5c33ed5412fb085d9b017f5d0807e37081ec13011db2535e845c974181bf0982a76a68b5c4ccf81798a689a4755b312f21989d4ab5344121135c6a56b52b8813afffb0c6b90bd6e465cea4a924d811510229e47ea98d5c8587d3a349f207883e4769e2b0174086e49d43846b93f14aa83469c2d94f71a52b62cd2184efff964931042a63ac6b7a40255083220e12e3de78faa0a5833e64124751862c2026e5035ca08903c030dece29b9c7206eea00d916411475abb52695ab1b74d285a92dca8070566258d644c2e0a2fb47470e2d8c60b8b5e07573931ac115b526d332110596325a5831557ea7b11165bcd50796043852da660c65299169253d5209aab6501c7015a17c5112aa2847f93720e8963c66a9648446ac0e050ce7546a741c89b42be4e23cb3d2c5a3d6c8fa7a52d4d722a806629f2a4c2ae6396677744c3173ef19b7081ab41eba04e5136b042743c5f34ba041b46c4959dda1b8ddd1627eb2a29e63081e5206355951b4f9b8eae70814ceb074cf4cc00b594edb0b5271536f5a1631f3ba2eccc988b4aa522b41898f422eed4bf4f5b6880c51dc1234f2643b95f22a152d80ea1ac0e39c2901e0931bc158194f62ae3342d158160dd3b5700915948e30fdd34388b3b3e0863b58195617dca23d6c10fff888797044e3c2434bdd338bea228773761d6f98221e802e819983ed348fde9cde8d12a4b30cf7d6473f3bc6564a69c5725715315452c06cd7de7a1306ab0c32809c6c798f5e95922f1a596912af1da3af7555b4ec533bf963972b167036614f321953346b6c897afbe9c6fe4492e3da10b96c11e75ba752150b0e3dc8d44956adeb4cc02eca2f3a425c088145c39c29ab2b85dc0a089c08b05571153921560b495c991c085734e9b88213e1a4b1e32b7466867ac8c493c320ab092afcaa6236975041ac34a679945acc6b15da85993e08928b597cc032173d152b4145c2f43bc4ca7222541208aba12b17bcdedbc09138613095a36de82607c1b74259709a14806626a34180392a69634413550248a93606290dc2613fbd2bd96b744e7e886c817393ec2773bc41783582bb65b8b72d5ceba7348b99783d1e99a0f04aea15372c62408132244a383871993a13933c47b069e6c978eca7a3490bcbe0ea1b0992a1372fa0ffd63969245bd17e8274642745aa12267778ab9b87937f35b6d534aca81488b3a965b6929d069000d8483abe24dfef3a7e51a400a058c9ba74975c789485cbffda59ea1d0a49318400e882c377517cd46c013207a66d9838fca071de31acfb9af6030b812635c454b81821bb305f2169bebbabe350f1c97021d29287bb066f2a270f714ad58325f2d45b15eacb78b7c2fdea16084628ced211bf1d2756d73bae318920372222d2a4e7aac532daa90217657d1b4181272267056c7771233b6d00d99e4aa1a18afecf3a169735c91ab95bf257c454ba04f668ff66aabca2528e724cb0ff4994ef1af8602ac24f7396a77888b28378a4285f111823a7873fa657075249506fb1b4e2c72aee311d797b8bf62ace83060deba0a725a403fb53c845995e7d30fd59531e4a88d339a1492c63560056d81a38214cdaa95637cd0c2a14017938be4e14598a9ca644ea1051ca2082d9cf2cf7d679025c351c192d27e6cd58f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = ce3eb23bad9f43d6b1a9763e5c7705346f514ba7bbd5f541ed0df44cbd91184e +public_key = 11dbb438e18b88f5a97a79a4e42508fff53dbca0a281a9449c06924943b43a010c48c3268c37cc8b599a39da0c6c664e4529a136c5bac9bb1476b65eb381c82394bd0f48a817d85f490605c12b371b9cce20ba802f888eae7cce7a942185f88f62318945f0a18f5843ee208a54e184f71b6192842113b89b0a4a242879afedd14ede6779b2f6b1bd52af71f21b8930bcf4e146b23940c1871973b57f7f826898c7198b76c1683176aeb88a63d41686c5345be56f6c3ba6c90893fff8715fd57b8ba45959e062f734bb1b2a7cd4c67325fb4d3bbcba68380c3d5413ce09cc995b3d80e26f1987b58e0cb77bac331fd63ea126bfa5882d7a490ff89458b88018353779c2641a21311496982058f5250b344be1088d70fb1057467e464b79a2d06babd29b1fc39529279b2df18212d89ff1cc5bd32918fa39ad57828c1724a3aac6cd15a0c75e633e12505e209a7e6a902e2d5835fba992213b8ca15a2086d376d524733ae66eb5e17cd3088128c460e7f301f51000b0d7a49d3741299786c42c0f34d12ef4e9c30a9cbd81211370b4466de87ee97a901993aedf31c2fea5c8a0b119b8c22d57f95a77595c2fd5828d1073812231361b625a376dbce692fb4383b3f08b9af1b510634ded39315768c7456b7a2c354f90151722a07b8a830da9136db845a45dd37c66a06b413599c727b4f685a379989b7ef1a402b76781d6156b792af603713a5225cdea0dbe842bab0c237ee7c0f62c40451125b2859cbf64a5114a4fe31a28a1aba150837f1b227c227cb6ac0a1489880c73c376dd118a8ad0249b6601c4b04ee873b664e774bab213321143c7e7b5d4802f1afcc39c043f59028930e17175709ca93271767b5b71999ccb8bc35a424f9b436c7aa3322c764ddf27b768868758b740fcc1a83c416c0a9742f193ab9e61316ed967f5d83cd00cb9b30b8d8cd976410a91376938a14b1e42f6302732581e3c5d3523a257d92e9f5a4fd433600fd7215a064538138068dc0101bb24f0792e3ce72c6a6698a5571841368b95b7918fdb7a67988f37249f51db044a206c894c136795869fc69572d0c4b605be3ad4313ed2291b921bf8d8ad5bbccedbd8cde6d752f9f898c6b81e4c70313cd627bfec0af54756d58651f83a17af00c548c311cefb0395dbaf8419775dcb2238542bbc793079c85d425b7b10aab9a226486677749a65b60f34397d8766b10978a6b47dec697cca6b10c0e8b1eda03db446ae921b49e4f610d57b6bd0c9b25ac4165fd3c14708012fd58aed8131de1656bd5a0ea6dba44aa078ea09bd2be79e936c030727601434c8101c8206bb7d5be523d6229a8d6590e25281c6dcc7951093b4021d79966c3bf5132df79394d9bb8c840a0ca73b58b219d8692473e5a59c52b01ed783e41746bf0268c4136ad53775ecbba90667835e8b1ed1974387c7ce89d9570960205995c87e68b66fe308204c380596353ef5c5d8db4ea346538e7a4eabd2360b17388cd97cf0d54c2c9859f1fa93ec485db5985c5e8a130d54b477b15daef7b3b46995fb23c9a4769a2fb531e4b05668f5a3447141dc3cc85ca55580596731c02d5f56b756c461bb5a50e95cb5f3c02c28104bbb99933d744a611059e8aca9598c3bb705a40589a26812a197827a913aa9a6019d14f605ef9201c07493325680f9b295e6e436b6894f616c0d9a1b5786b3bb058b6b12765f2c5c6a9f82cfb1a5c43c9469d0b44a6bfb187c9c9a1d4a7903479afd827dcc5b6ca3ba89c3670e9c7955f6b0880931a32255caef986829023d8aa6267f32c687b0310e7c59cd443ea644c90ab15fe8564d64f55af66774169277db69c897c298797703c6a3843ea080d3d6c7bd78498839c873658b63acc1f19485c48864e0eb53ef8ba5612104fc732d7fbab0960a4b5f0811444c7f37d170c0f0babbc022e3011910677c35446320408ae302ceb5dbbe9a67b05bd059471811bef91712f11b69333dad60514643b540bb1679149dceea9fec2c96937ca9f5252aa3829f6eb961ef0aba11861090080985007042a93450e532736b906eda93563c0b50b49b21e2647688bef5d9c237274688a9a9faf36c5a67112e453b6bc295e2b732276528b26b68e0f2c7895b0e40547233b1bd9e112356d3973cb814191acc47b313cc758b1af24ffb364b98f69b3558d3b600be9c743e03878b328f52c6789e45245f3cccf1abcd3141fbc6231f72340dc485238e1d64a88abdef +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = ed9a8144063ee3508cce3e15c1d2c830322f875b2c4903d87b3619cdea6f2bf9 +public_key = 3dab4310e9abd0d06c4e55023e3180ccd73f02899aa1921cf695690a23ba010a414b4c3e12e242b217ce6c34276c321ed43080c8d8710129507c878a37a61b5da0a944d02ff10a5ba6047611e5858986cce5924359100b10b5279814a651e1161dd297a989b0dda17475501834a165f34a34a8251521ea45d414c642fc46790a878046103f3c99233102df24cca0e072055b6a57b841c8556e99004e40ec334af96bad048349d643b2b86031ca505944825b81cbf1e42dab66112cb508b8764031d61c79c9abdfbc168bf4c946a44ced570f8ef92105cb089fea63cbb7b3bc240e80c54238f000d4c19b80dc13a3e1b6b569767fcc439717aaa477726741953e30ab8b875ed172b1afcbc6415a5bcbdbc1019821546a63611c3d8fe26224b79c0fbb058e6332288832fc0c8045176746a5ab2e23448636a2cc35ad026b9a1d187a3758ba39b1019eb164bf0cbf351b8a0fdaa33e7c9115d82e3d14ae1196aab3286a5ab68642bca09bea1a1c06adf9d10592301d8c1a057901218bfb68e988c3d619b40ea48ad396bb831b685f335f03059ee70baa59fb9058234bc95398778277a8e3a683d549e4007dbd327d1aa898cc2b51fee658ed3392b43438f34a065aa19f57b2cd5ddc6017529ed74292d4e07583289d09ea754a3c2414623b89f727c759979890cce9ab4856428a0d7239cfe76c4009afdb61b30915a03a9597f5f58a84f5addc896852119cd7031d7f54adb3725f7985696b9a50a1275d47b6047af81d40c67537a4aa4edb23c40b495d8793d9b1baece2cf67d691f2277e531989cc645d64054de7acacbf37348ce921ae12c92459730c667b9ad4161c445b295ba7ad0707fb844281682e265882fef32b994162040139b50c2f940742f1ea774e60c718802bbc180120e378e762cfdbd0cd4df94a24829c4c9a5c6a99bbade797876bcccec878c2b0ca59d450412cc12079579119167e699da4a470a5a375025569165261ab67437de244af00c36d0834ccb19926c6a25b658c666984b47389c8023418fa0145b0c6f593c41ae25e63bc7c8a7354fdd73bdb681373166a1c757166f4850f95306f0084fc375b2322c069dcaec98124a876cb9f393e56124c41b97cc72bcf1764218c943a3cfba906a9bbd01c19b5ac7595f84a6ca1a83500b90e84952fc59d942749f87c6ccf93c87c170550ba3425487ddf2cab521274365b6939e543d5ca49c99309a1cbcc60e62e4cebbad181cd1c624e005286b26aad87f48e2448129ad2613b4ac8cfa41fdf6722d73c9858d1ae4eb38a46c6840e3b1346f2aa4c0735759a1b8b804b60f5b70e9b0928c41cbc981f729972a85629d179529312b9ac8692349494098083a2f70e6a9c12dc7668e9f431f3d63bca8819c2ab2631556b2226a97f40486106008fc86aec09b797e60b02e31abe889508d39d954187eb4b9471f5bedc5931568009a400823fac368ae30008ac5f79a207b6b0c0503225ffd42682ebc357c9b0f30819e3c24018f39f3d1084162837d83a1e637c5bcef65aa05952474635a76639f665a4242579f3295a850015c0d5c4c03ba202da45060277f30018f374659b5bb3800443223485a958761b63368b7b258019481b47c40823aef61a81959cc8cb43196307910983bb057059140bbb2e624e508499701baae4180aedacb8b63445289024fa43cf0f7a174a770bb6e371d6a5ac6820948334949785bd3fa3c36d81bafe050018cc09018aaf48ea746b8b880f13726ad12c07d1bf75d91f53f9988193b783659808f919541b1800e94ae7a4aa80e94d54a0a96ac29059db2ca051c4ec2c8c700b36db3a6b3d5ac16ab83ca2186a2326be2d54a53349124e3b6859a48cba597aeb86312800155c23c523952bf9a38e1c83adee847331fa96ede47e7bb01216e3af4b35ba23abcf7f46b4c3c28587c008e0fac1a508927ee73052776042dcbd34ac03cfd53aa5e626e7a718acf24a29436e3f546896b4385ca8c71d306823dc03de703455b0b37894c4b69a4957d0af1568a6a0615431d644bcf7bcd182aa36643f12c21331dbc3394b1e48e74d99acc4dd22a43fe071b5445617f61638a41091e6b2b4429d25a2183171380e729a71103f9350358855a8910771cac5787bf7b3d3e798c62ba44d3b435d707529c82b378eafcd1fd7cecf8aba170ccb45d56d24586541130c73aeba3982d6f92dc61ce261b76cefda7d471120868f838fdc2c76bf95dd63592996a6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 8eaaa8c0471e0cd24bb68c344b2c7eef19414c9b4eeff7ef1da55834d3ee0aae +public_key = 44803cfb87c774538a07451473b80bc31aadda955ddc5b2d61b061937847305c455669cf6b48260845446da319482acbbd23858951516cb1100ae606bec81ccb5675c783c5ca3a6726d844c90b9cf3f6b495902c9bb29165eb32f8ca8e2537827e854972555eb8bc5a5a207a98a30febe62c82418242e45c0855c8dc391022da8de2db69910a97a60c145c703a1f27b2c90662b81298af7c5098d14a102a164f3765097c6bd489cd45413b5d53170c93cc21fb8f95919857a0735a14904bd93efa6aafad45c2c2043a47b96a08d314b3a86646a68633d76b97510bce926146536f5a54ce73d2c979665255d346e67488b73c24622c159b3abf88ac73bb38cae3e186cbb5c14c214c347b473a442c85f23e69917aaf5abfe9273bcb3264ed738041dc5dcebb83678622765ba5d895746f5149a9b09d48873e6f293ecdacbdb79238d7c1b7f02676dd41613f0195fbc84b717a18cf5a495be540fe12a4d3e91fd0f27cab1a5eb5795acb99648321378b8abb97b57346aa10a495197ac82fa0fb88491463760c621ad26034d948cff720adecbc5687a255eb50aa172b463701b6b398d5f52f0a317c7c7cacf3964773aa021cfb22d8c70d2978697329238c0a7696c6514602222540b964b262a1a860c2480c8fb27eb8c9c06d672dd0a583f165c093e58a8ef2253ea8357aac1d25c0604c822f3669a46c927bebb846ef8b78c9b1a05907514ee1c9d4127f00441c5ef67361533124d37866eccc9cbabf5579cadc5099f28353c80c6f479354bdf69313845207620ccc6045c8aa350ec125e7e86a23e437597291e3a273bdc2bc71a589a7ac6a86f23056613097b5abfd6a0253b61a3d5928e50937c46ba5157c818518550f2c4557ab2359f66400390fdd40a927c88830c6566bd9b58a82a5f2abc0506ab378034c8eaa777715ad16049b4d814066645c415cb9ad7ab2c17339f075afe1e048dea8abcb30c11328c95166239be3411fb1aa57dc2525167a848790813a9abfa47db6467a8ee27ed0874882fc8186f9a9bbf36185d19a58231fe21236223b4490910f4bf33f5b48b331c522e2333b733092dbe35dcc11c898cc2bd9b93e479b07dec79ba3123da0a875d4b2204f8484419c69faa20fba798940061e28856ee88b11b4366c975c6bc00bb9a1bc8621c902624b6dd9691f05dc42fa12b45f186b721aa654cb84cd1b5a15892059a3abc5377dcc6c4fce9b2fbe1ac8f685a16a5b22e2e438590212944a5ad70b6146aa12c0e2cc8bbca17526ad57f057ac872bec49a06cb706a0cb2580d78db5514231d9cde0d68b431861a8784562c90224c5a0506b45fb793e6aa13f35db835db429763a532145652c2969e32238a926cbcd3c5d0f94722e9cc56af5b18c8990d1514e7ffb42ae30cba757b927617517e8369e760ebc90a5584bc4cfb867c2b191c684489c7b3c4c220cb6f898c8f9c1fab09508f616ee5699340862e0d3be6c741f13b22ffaeab38a9373be2193db953e9be010b7c89db711cd0baa58fc480c32b75a0c3108a8f6aac374289c76044a00ca6955805e58cf7e7a4856d479e8392ac8737826057bd97a6cfaf35fa45b15822284c8f6a4030618f6c40021e336ab79945d08ce3cf2874cc0abf776126fd57a8ba95d31da29513ca9892382e243cd98c2ae695c77b058ac77b515f0834307e538c77a9e2b596953635e31c9a9f94a115a2b62ab227a49d06fba36c4be3879bc665d23305ddaf01404539b3da62a6a6a01f82c5ec636c98c898a8ef37e1a9aba50ca02b489aa8e347221182c3b2c064496565fb462571b186f4249d6477d24ba81503c731ee9bee5c2b364775445c4486b45b7faf324d92289181b31d0d83c14cb600d8358f982ac9532368f14365047679388be8e675b65924a54c1bdd466369fac803ecca49907c9f1a5804018c8ce02362721a35a48710045aad63b0ecec0cd618a0a9cc6016c4bcb21c5983b51390e4c8ac189064fa013f1cb1d92a5046369a0701667786947f0eabac0e7cc92742dba03c255db7df6612d821b9cd68b9c17b092d21c9659c5c01f403a40f94913577603c1bd9059012fcb19f48b6a1e008a57e1a00ac9b4d18306f98b9cc8957bc51788499a2ae2218dde92821c7659f6f204cf812b7f91835f7b55b81601479142cc5a2f8ba4f30dcedebaab60853a154e3dd1b615a178ca268681c2b33b5a21767df9ec93ca88ab6407912ddf5cd3d8df99a42c3680cce4866e389ac8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = efa2efe68712d67a330db585df6f768611084f03b68d1542b909e1a40c1c42b5 +public_key = dae155d0598b8f3c6317fb4cd7683bc23577b0d856e15b4d1a9b4fb3582631057e3fe2395ac7a57bfb51b1b725b54ccfe71c5c7023af6f476ad8006499fa67bba360f2b499032842534698119a9804ba955154ae84f70248c43e69d180adb968e473b04eb76b8bc035d75c745f794727152770e1736441c307f8b41432ad1c6c8612f2bc8dd507ca627156360e85208203708fb852942e298bc1bb852f00374ac1249a2503c75c0dc8a8c1ba645310707a5b9906ac66647ec107d3b7953fe64c9bc7821c2cb412319ee472bb91787967b36a138ac8fe183dcab027d3d139c32aa5add0cec53a93c1236000caa956f0b9adba6a20608c2384216481743491c6dafac13ff512d032a9d06022ac4b0f166c488ef5a415690453d8414bb31121698677f8006ea745ae9a0a40b7ac297a4ec2a58306a2353482160487a74b529185255bbf7bab6e09513ae591f8377c51182a2a44a8a66240c1e480d5078ee23ca8d5567365608919d41ed5346005872d3171c654921b1de52e1ccc9c24a56700a249afd8bd7634c4d4db57d9d07a997c7c81eaadc4d65e4ea98f24fa27c9913d63d87e57d037d0d45d7320cecb10870244aa108836e41449f164b66dbacf44d94f7ce107279ca6ab109148297611369960e78b004a0627027040076e0f479537770b0096244746807397256830605391409f69c8f3e9810d245acad84c9ec49ccac028bdc4226ee8833df5674b176ff22996a0a4516e77c8f77399df019f6b6ccad1b69f4052ad40ec644271a269023e7f2cb9b6577022b3c5c09733d862a4eeb94b9baac8390c8ec6b66634fa5eb18c52a35ccc22c4cd86682f3edc387caab3057c8d4ce41b51e26848b14b87c722c723bccf0191cb66b4dca72a61d23312091570d3072043992da633ed90558cb83b36842fdf5b4d40847865771c9d6b9652aa3ea5c3bd1e19b757a3a73f49ba1ad963caf6aab3e7c3f5d02ad9d830f7333fec5326077c7e06945b496a765dd505288c9e3a4a7a50052ff11c5501997182a0311c4c3ab8714d89aa4fcedc4737dc81f93923104986718561aa2b0216f8420583cdb7176877846a000096d985b59b46aefa6cb8d37b2dbed7bdb768b4ab171c35d74e638726c0d51a6ce26891fbb8cb707a9ff5298ae192aa492617d36c879a49e1157290aaceab0c8c5175456130811541a821d28876629ce42b291e3ab2dba03af571914e96936d71557cc90b671119cc192913c00c3bc58376117f5c472a2af763d159527ba05ad4ba8a02f41faa8677ce093fcc8493b4da3966c5b436d0ae3090b5a3d9bba1d6aff20a91bc257f65e35b6da574fcb09571c631a0d1822236beac66899c6972a8b50bbf3183c3181b7fd7c741b573e738945e40c4d77083b7ac3431d09ba6242900aab3eb35a09af210c5d69e1f63bd695041d64809255a5c8395b1bd84c587ec0710cc7f4763c40b012822b702711b5443a55cc1645d98b0a4800b3fd9127035e981341a644da2711ca24384f1bb34623ac71c1eb8b69c59e99cfe0b3415e932e3d41d02c8be85f28d5e84c72a2b52b45b6826c668532181e0aa8762899ec77a7ed66ca3cf1329c118307a96b70994444d745914f412c676697971b2534827067710cecb8f96c5982d0c870096850c32b94cb078b2b7721c979b2674bc44f168cd701c2c7648f3581405020a74c417b4f112710a49334a5776162a746b8ce30ac85679ba8b0041f04017df21a9cc434fb1395be4e58b6664c389d479546471e4715d1e3204687a225d2aab5263776f38319526a171f012bad155764057deb9c86f5c548c065070156c03429e68b555f4e322ab851cf74b9bfd81617aa6bcd329428d97351495affad1865422baec99384f7a437283b7aca956c1226f8ae0abbbb8a397614a3f467b8dd71db522391a286aa61b91a6da0e0b09c0db7b93c7464c84659f16c5826d42bf74d785c1925100695c4b999f3fb50f0f3968000650c6752b2e306d0e4921802b744a13cd768337046749fb6bc358825b116821589430dac11b2bf99062422df29154a6e592ea5c72b5113a55e37d93dcac46f4cfd9eb7b7451901d1553039a449f6a9f36dcbf4eb3c6c8da7c253915ad37b68dd296b6fb0f52856fd272a262c3cfb97841710b02d81948887b7fbb26422acabfe649c26a005254b0545014675f243b2e1351b8780eb3de8f36fb9a93096e780e6cffeb8874c8df8e83b1877a1057890146f0b8b3ece187 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = ced2e5ffc24a8ace3bb2108739af5b8b5d426a4bdf3a79276b673d9c61e1fd13 +public_key = e3222b41c2c8e110638999c3ed12188a4ab043930de473bce6254f0c88575849c2bc050749500ae472448a278242e8910df620b323571cb9426109b2e8fb593e3aa34681ccbdf7c8e365606e8398489a5fb3823ed8f8bc1930c5b62917c524b4a66266852aad1d189bc0b6608837cd43068e262832a5aac036561ba65b0c0294ae31004a8e011a4525a7c3d748f9d9c35ad1c3c97ac1a282c96adba099381239e8a649b43a0eb0b83f93057c7a95c4000558eaa7f129b88c3c7039343356ab6874706aeb031eae227a608775805539b0ea13f477bca2b4646b6828ee4b630a6a0159244e11a7be28c5944a4242699c91e2fb857bf52d463b7ac1505aca570f827c784933a62dcb061d4300114c48e0846fc6c2ac795506c5226255a1af8ed874d0a8a4683606b25711b095af5508bb1b3b20a75700a649865b4c0fca3c95994b7863ba0b226ca170589cb46b56593701dc53cac6695618b4cd6dc1b9a437ad5047438d7243b558c04f3449c5608ae785220b46831c501cd88231a0635789716c84291a28b092f76812f441807f623c29da9b0556c47827896954611449383ec5cfc2f29050b693abb06982f7304eb924f0d181e2271242225e368915d7860fc5c02918daa408eb7c9021733ff05135c09448056295bbaf781215bf791d2517a20e9006a94b56300037e39c4698225ce3824d7078747a7b294059141022629016caf6d382482844de956f7ea798f8e65e1b8bb1ef3986e1028b8f6bbbd490cd349c0c3adb783209586a4a162eb80a401371a0248200caae4170c7a553630844ad4519074f525565959fc9e173be1157cf6054d6f5bf2af35a246153ecbc0a829805c4c75f58a5005e0106de6904b7158d15c69fd2621c81970d33141c8cec43bc067c5f95a1263cc00237ce1a7057277787411754525b1b5cb22b5696049c3a949df688bfa66b5f0a4d5b49cb521b06e660053373cba6e11e3a01417f39217c052a62b60bac56ca102866b1189494b78f27c0ab66bc9a30f70569dcb4dc400ab4854236293ccebc8895160cf8095dd57897459652845502f7d58319e31dc794ad20e00f8e3339c4d0c9a9f6917a30a01955227ae535ab132bea4134508c4182e72e15581c090097e05698d271c408b05405f3a395d51b4c17ac3232adeae0a1f65b2d1541127edc031e671626b2658cc6ad2fa351f1e0b63e4a926d43ab16b54b74682bf761ccc04026632523550376080a78c77ba6096356eb541f5fe22f71e72f0e9a315ab99d7c5242e65928ef6087bf14c02928a13b419722fca97dd01004e718ca8aa5cd1a4a176615e1dc38038aafcd5a91daeba3da059d723a17dc8a2078acb6bb8093bedb1a52b1483a962d37c72e3866a27f404babe167007d53f2155bbb37a60391ae7c7c7733826381542f033aa28e184af3ab809a0b4da6bbae686067f4d9181415200c9ac7053aa9d1304852f19622c38e57b39ce860661ceb2ddfa60ebaf466f0cc9ebb0b6f3164495972519ac8a44691b1d05b7dfd526efacba204f9b823b263df2113664a27b274b5219a2d64e85c52e55e418ca3da186b4df40f5927c5f9e162c942242abb17e968c81f19bd78320777eba18b128541853965410d868074fb978c7289414480028ec7292bd3acf667a9b61375695004a87c951901c083014f10cb9860d7664ff850f7666f9e643aef8b73e89acce2f662b2372188f20de9d591772a7525ab4eb2621ab9a229a6a676941cb94d5c240c87cb8f70b2546c4eeb3438eff260c5fa5dd11b40d902ac401418244789c10098cf58cdfdea0c75265175605a8dd9865f3049f4f6967080590647148862b00ec32218a90b6d62a59587120a4c9342e970b6c3a73a8c19d44581c1f90e16e0036b9333e9437db35b0a0d177e2b64158a77084f27cd4d1211f6883ef53953122a2335f46cbdb03ebf7924d23473e6485430c8823ea7bd2ef235a21c8986139f0c5698100859710b9fdf6143b8b07b7d562187255810356bbbc58a84f6c08c203015a7811448b518b8a5cbd27ed0ac4464f917b3e211ec6133df412d7ac47882650498a783304066676532de618fa8d4afa7a4026e298d4e39bb86125dd1f77da9099b790994b8c4178b9c12426029556a2b3fb0208a384627f229c3ab0dae215740994d3b84c51dc1d36824660ca442e06a5014f665461de7badc369c5d6ac8ffa84ff0e696346de2a041b16ae7429807ab162ff0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = d823bb23a3760eb90b032a46aa51eca400d1332b1c0edea0f9b513bb9ae91214 +public_key = 1d599854673135c84a95d8488f3871e1274d603141d9e54a839228e7492a05f9a0c8a7311d987098bbb48d8074720a2a5b136ecdcc66ff527d0be9c6658b1b6ef0a46c26c9fc89a545b533b471c457d2a5c441c52b03595792c8b75ab55542331e374f6c7ba6e1c5a96b33306d6b1c0dcac7637519cb016f2630306c93ca413b08d19a58af2a2586535e9ce2cba8e7b0640358e2873d97773f144809112a7134897fea440fed541872eb95f871c9eb9b808f235ca5d9415abb41380688aa646bec5ac0d3e838857168c4f891e8163e96456460551194ccbc687524936bc7d85b482571477914344ef5ac070ccd55f13e357929a1faba3d73bb1930603e761349934028d02781a0acb8e39b0cda449d950abb1bb86000069a8a92ba9575fc8abd6298ac405a790f89094ff7035885caa67acd4475b62e068d9ee4b7cac95297e994ebc68a41d5ad7d4c34c77a9446db7199c1b1346a98d650b41e68c6af0c07b9359d817a33702380a0cccf23ab877b71a0b9041118b594286c76186222bfa43f429a7ef2c35772f06ad102782f491391868519278a0da9c3c1b7c6569241d414757c920d7ad6a534863a775b24b2c23709e95f17d8185c3c1493f3323fb2c6c5399e55e14c5fd767bcc41e6a150421aa5882011a9fd1b7a8046bde789e20f38b4e9c16d3f33ca54749a9b21606e859b59402b47920fae93429cc40e1e61276946471c2c27bd98d4f1451a887b3420c8a2a927e5be9564afa18e75c516cb0743e876e1af1cb57a94469cca4e627574cc01a6f3630fcb6ba4c50892f075696e00f5a434155b2908164b10b224961f2c879210b28f2714930c030f080ea9503f7674680c782ce00b13d8b478d494c87722412f491aba7c5af4a0f9ceac6d4a8c025c93c71e9073852baf87ac08cb7aa98e857383171622b2563d686cfdb1475006db8e7943e3b842f784d5f768c013c3491654a39acb828d8366529b3ec793e53fa7cd143aad7907d8d531ffb648ced280063677f8b82250b6a865c3069dba84821c32706995158dab6507334dcf11b4c8c4082884a2ba808c82cba6d4c1480fc5061b56024462d56a3cd9596c468a01fa5ec2773a6285446844981714028006736791047c6367a4e3e72bc10b6a69d65bc75c9051f11a7e8ab2932677b459b3c3a442115c2377e46372c4b89467511d37a3f316681b62b2504902c75259a53d8277746ba89030f6eb88f0de334d804217f273ecf29c0f297310b920dfdc46689a74e37a4789a356e01f920a5a7bf037596fd895b98bc747489b3eb666601a9141d09c262b581abeb47b889a53b951cdb4a161a293fffbb6af4273b20dc5a6e77901a6a0712221105422e676a68ee0b95234206a31a5f847c281cf139bab5990c8c0e9b05442fc9cf7cba2b738239cafc2987532083e9c7c6cb057adbbb45862e0f1198f269b2b457c989679358ba9754e5632f359770b906e31606bff5bd9b0bcc0559107e5032d062b48121146456974da9a171a42b25e2ca36b776e521ae5335242f855ec235098b778a2a457760d84e4ba6c87ca93f6f491641bb30c1249a6214ae514bc8e6f08221ab8c7af87bf98916630bb89bb5c8bbb15a3ab72471496908412345dbb72989cf8316078ec78f30180947d83a9bda21b6213cf81a1bade20d563189e214047ae7303041695f4c012df70f5c877a54cc7aeeb577e0d225bb529c24b72a7f1b93114c10b7c785fa0278a798cc15752bd2c54a697a07a825be6dea607f32432478817de1a65eb96b8a972791cc40add18ca8c9bd25cb8bef9694d01c5325393923fb9491d42edb852a74aca84ab4858c22801b2a9ee5c5b712e0a11ab44efb32bab0953a165b93aaacc41196b791fa557b383418e56ef066c74577cedfa9c7f1d2807548b0734797b1973af587a054c3b91d05ca77d35448a1afc8529d29862fbbf74d55ba943f920e2f50886bc5906893c2762b0feda0c3f1a6b792ab1a6e742ab1817da28bc70189031da25755c7cc5fb6384722572b403ad189a296f902d06578f0a9cd3cd650fed7a355d325c1f49f19b3001e5242fb3965fd2b55ccd1c70d182532ca652599bf50a64dd7ba6b338267a779cc40008e3d1ca6994675017cbfaf267e47317a6c6cbf466209ba5a5c9d55402e2aa942e97ed34ab2e803047b85ceaa07f1ead1748e0d7bd9c23866aeb8f44adadb5e48f001a20f66df626a690254bbd5211f3de88424 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Zero secret and error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 30a0fa10e8c0f94f9e11093a8416c0c21c8d76f192b2c5bb48149a874efa1dd6ae457ab33900dfa4e04b117396c5b8cfacda8d01bec1eb08e83c11280b885b8d883344df96cc32edd098b05d3ee2a30081fcea4cb7f6bfa4658a0f3cd3299be05ed2ffaa90d6791469d383bb2f07d61e25d5739de0652980a072fb5803c361d81413004161390926457e7384a6d7c37a7b0b6ee33fe95b6078b3bf085a1b080ca03ed6d7729750117d41880c8ef0e402bc15bd81b3cf4272cb84db3f48682968f683ef7bd5c07fa0f85b6787e83b9c6d9e665befc7d0843a0b911893c9699d99c36c8a95f1f61edfce6803eef39fb2d555503809289877a78ddd41b7f271b8d8ca6f01bb6a2262cc6b459488677c67fc2035c47fd20e33bdd9a81d279fb7f1ff9b5b8d3e000c02c68d590e637fbfc899c9fdc7a10fe7348e2bcf4f1f731ced7f5741175ea484c85f8304c37f1949980a0ec0101935f7ca9bbdbbb4fdbeed3a56238344419655dcd2dc0bf0a2abdd81fabfe56440f44c615992d1c1b9478334c199c40d4b62494be60d0d18a2cb1515060d884fd39e4856cc2c8b4030b46a00c33804d3d2d9b6408ab6a258d4ba55c52f9eb7c864f2511899d28b91fe9c1e328d867f404f7dc523c89ea66dbf934f2d231b63d5b4329a8f09a336554da77bd22c506823a69341af85a0561015c84cd1a52391ecbad57667a2a0a99cc7bd0e6a18dcaacab1b6c7f9173fc1b7bf247bd8e2564f74fa9d0e6a8a7cfcc5597e27d06962ef3f78d182e21a7eaf77c8f783f916b170ca79e3f1032f2ebfee0b9676806fb5ad881a6db806bfff8bb077bd1e0e988de526469e3ed6970254781bf0d3f1729958bf73f59da6b7ece2e7e3b7c3b558bb63825111422d7320086a34e459c9681bad81cc89db23a376bd620588eb381839a5f819dd826b13c060b48488cc857298b614dfe1e61b8684efc110fdaf72fe0c79d0d1d4de979a75a5f58a783fc074a1b0f3e5251cac2b0a798a31bf9b8e5c2f84ddcf2ba8a7d81878aae9c53ad2bdefa5cab9c2f1637ffb2299af62f382e4dc843c0e6c989c6a983d86675531e3b297ebc8254250f052addf07df3ea7a104bea20052cb7037e68b52bdf205cc8b77bb90c6fe671182fab394eb62bf39733db9fc1a18f307a788038d3a58a18e6661a74b4a2e55c24d42cb2824856138c1898630e059087837409612cfc8a7635a1e6c985506711c737ea7aeee42851c9edfce69500b34d15357b14867fcafd459e2de311b826d8c3819eff5ec2f16c6f6c59bfdbb4d9c63997c1e0b461170326cca23cda09f0c0f978ff75800ee67916d521b87ac96e09d8230a9df27626420d17842aac5e20aad404c07e1c1bb32f4fae720bda3ebb8652c5ac9259e9bde7b0430176ed477977116cdf18948d2e117be3a5bc996ea9738c4709b2ff9f625d34128801d696f6b5d0730ed935907b170d9b1d0099a4a221e7c488aa1b341a212a12bfb44f89f13fd33af275816b2c8a56b8a2ba19893efab7809efbe92453d339046e6cf08fd6104d8a487b385975eee673955e059bb997ebdad498bf4c2825355e5d4732e78d4d9288c247a5c4d2e53d5d1d6dcdfb19a82a610614abfaf61e982f9d17bc10221c3ea5033679407b7cfe22fcbbf9e1a7e8900b29b9cca73a8d3461586f78733dde42d12e9bf39d14735dd4c1382b3613c9bcb057feabaf0e90de42c9c16fe87c704c0b03cf324b4316653a9c1257affe86d5bba7f17d4973ac798e5a4ecbd6227b2da17f4eaa462faaaf6cf17adaa4b3564c0a012422480cf3bdac498dc9750a486ff54662135f72e23addecba2b49d85a254259dfbf2579a1be48a93a3a31045046936bdd268c2aa54cee82c4148ad281bccb8bf3677e3ede6dde20ffd2b61836fcd80e106c92d72a35b57d4ea17366f92743ac36b77339077882491a1288c8744a435cdcf21dce1eb4196e076b269d2652152500aa9bc2b1238e910400820801040002184000000010000400801840042080000100008018000020821041000002184104208000400420001800040002084004200008010420821001000002100004000200410400021040042082180100008010410400000801002080000000008008410000020040002080084104008000010020801001040000000104008210410020820040040000180100200008410400021800042000184 +expected_shared_secret = c5aa00b1b6e55e6aeecc23499baced296d8576f3674ba6a9da68bb14101194ce + +comment = Zero error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 2a2b8a9b681139477ce641c0e766a4573c65fdd08b74038ac64021fa53ab9e2801743c9cf730b0609985059bc12ac92c61d86ee425b5811c6e4b144f0ba3599d7bcc83ccc4462c0aa17c7dc9d55598aca3a48b6ab4479eb4f4584796c64d2c74c360a34c901f08d00d4e4cc7e70c7b816bb0fbd323ce96416102580ae89095d4cb5ae93cd9b105d1065402a4a2681255d0821a21953ff851c23648a849ba27b267c0e70558d54146031482653116570a0fb6e7a63fd5b0ea9212a920c43467740642cfcb53130cb77a2a3bc678572235920191973075fcc1e769480895bc7cfa3c4c8068c3907c8da657e656bd8572a54f80847683639991952ad7b978e49d0022c17adb021030c54ed691e7b0b738c0b7078442651b979c46b0786b45ae446f73b56ce1b64042f5b27bc470efaa8ace21afff35487aeaa8d635bc607908e3f00236c74017dc0b515863ae690984f56c5156a70fe97f72e913ba74a7d04cae8b14364e2baea90695b5e36344107835ccc4335552f228c32e861f21357bb345663a1b9d70ac37ad9b4a937c304fd887048b8364744536a443540b7b5e572522a8c969b8a45068622982ad161c5ca1b69f9084657bcbc36025a82cd416beb15f037c045371617a81bc9bda545628804e4cb0b9ab7a6bc959ed6616465323f9b861521cb493da674c579b6799584af793459a2d1513345e67c06c1b268930c6d4dc0cc56c93e7f01bbafc589e178491f6206f9c89816622b8d5c19795c7c3404b54404629933fb6bcc03f99ad2155c332eb4181da3d07c35c048920f35a7bac1b465545018b899a5248b53f354cbbe01a004602dfac254efb3bb42130f55520921a712b20cd250bbb0d7949db4a05f5a64797417158241ca40c49dc83186cc236be4774e51856da828a5143588d32cf17c7a8d44aaa7be6aa96c794773b656a622609ac22b7b302dc88ce0d317c8a18877db8168621485edb278a0561d7abbbe33560b2eac30cb6b05f850418e1293d8566b5c370cadc2b80c10c9a84a47bc217bd645df4d627d9b28bc898701d87a07560918ba0a657589660972a7d636df533c58c02cdf960a6083c5a1452ab54673dffd2769dd8b95fc761b152181e2484be9c5e7412a994b81478a863e32489ad294cd7f60e2648a42f8890c740220cf4564725b290355cb86834b08182b54ccad880a4fe3617d0e04dd651334c00ab396c42829a45e149b3bf584f25e1aa674293e132a2a75b5e5ee4c6977a2b1df64220683326fa3a7b3888e42a51f712c944f9cd5aa6cd992c7f60b0858a638862b178080c5ccbe45ab9e07b35d37c34397cd2c6280226402784c04bb6c1d8492d5c021969108c13c7b2d1e605711a71256a3216557687f69a8ce38e8e3c74c12798e7547653418ac2b41133b3172a734d3c632930e2638750cab4d0883261598df19f1ebcb5c1baac516a4167f3c14e271d6348bc92ec1da704996bf9c53177855028335b834bd0340123a67632598afe146298177668c967fc4461ae3237a38a1be079a460a7a5d7d6cab0345ba945708d604b2a037198aa7209a9356270010cfb96f663b35601c92dfcb202d027e753a662e060ddd90360bbb38f4301111c509d624abc4752ae1898cc5732a518061c4ba4aba3ab5b9a66d9e8a679ca31136aa709e14cd35a129e693436990836c0648aeb5815e34a91e0ca3ad6838e859b2169b6e482492ed42bf2026b0508b733e437f1c6cdee0654c73b98b740474e2b9a19d08878855564893059904623711c42b62e34733e583424a9d25fec3b20b6345b28801d3db830cd503aabaa5120a040ab31513af89fbd0b8e11034abe120be9f99756bb26a9952615527ba4a1c0cc562cf565635fba5d2894b846b19907aca15e1979136c79b737821ed74839584de5b7493121c7cea71e6b744e42fa278690a6c9f434c0d51e28f5ad045c6d88969bc1e7b68b1b13a1d1a01e0a913e187eb861023a8268061692c7db71cc1272b63094e4c28163ac636fdb5a9422757744032b329e0891232a60cf1d5b71b2090bed7807a2d09ca1192541290ce65605e4197951e87c85ab3a41aa7e76d4b9e4d691c3d54aa27595a86a218b396fdd99642515bd4dc38dd7861b17e30eaac2c3e139381e2ba17056b7a7a07f7c9626f716c454e66c0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 8702ea652463d333c0695063d67f213d9e150f2e3aebe2d2bc992677e4492bb95fb116e17e8c5caf5067ce0c9c2d8c81369ec85fb7dcfb0ba32dc924a67eee3f92e13251bf1ffef5b1e3f98f25f7a8446a0305296e097e51bd157e97d476258ab146f7160413416a86f4b2a860971c1169d3b01a82201929cf2dd258c693e2becc839ceeb97c9b570e26a54cc1915ef8f17c47fa0b1d0b6bc9f25379514fd234425d02ef22cbc151fc2cbdf4549bef807afa1ec7e5caece5a8f4b62f2b388c210357c998e61fb205dc975c8fb5814345671bb8a614f911bd4de6eefb458a74d95093ca17549940c65101d62bfddfd4aae3c9a7adee294ad409ef778b1c25811cca3ece5928dfd6f3bd8a4da41a81b7973d5df2b1c25d0610ccd9b61e477785908d70b23a6ca9ec11a9c63ef6f52b624d66243925d2f5c2f90538540304bd3a11c76344c2aa90a12d8aedd1c6517732a15948fd3bb6a2e736b33bf68e816f19905b1a96156e2431da5525147d35d6b903708add85dd102658ab1972aa19cee456b7ba1c7847cd6b4f132068833a70cebc4b23a63771f4afe8f2aeb077572c76132033b2575c1dcfd12521d1249a5e38a8ad06979601f18e156518157a7c8e6526b957f657f8489e2224cfb73b2d1736837507fecddddac860a587122a98a08c137108e5fe9f9b2feef6b52e712e3493f66c98ea9cfa08aec95b27220f5b219689216b8e0aba6ee8a7e758730108652776d100680e800d6613aee85f831c3d92fea5123136d204f8983a7aaaca63d812234da3ff596ccd4970467f24217565b6069b6bebf58ed984a2f0476cde2319aaa792e46eb6b84f4c3c20ca27183f1e3e2be347b5d1250a666a81c5936b8d0f569db64aec4c2bb1099e6c5aa6b726a1617026c2c8eb5e72925d030759677863cae4f09018377636b69f2aad335200934ad4bd622fee2780b11bf1373000491724b37fe82d8d26a869bfb4d003dc0f85961dec623dbac4c55e7a9c439eb91ea01960d3103b7c0aa052e81acdaf1286620229f5a2973e8b0a72eb423cf068fac5c26190bc90afc16938eedbb5ddb3c9b5bdc8a595ac12f9c80dcb9abefda4268b8d74c7462104f105cf3437bd2cbd337dc5d71b552936e9df0e47eaed472f1162e2bb1b94ca19d449f7d1fcaf0e737a07075352aa6a45318981f9e67a6b23c2d03b3655147fb0d2b07462d64277b6cd11f4ffe969929a20774a885831ca24abddf752cc6133f8211edb3b5229218c9a61fb3683be29c7a2beab256efed36c6537614c77089ce44a6402a07c54cbcc105c4c1d7f35d2390ea2248fea06f472ed018548b1377738e62c081345659121a3948afd758c3fc764291c17f1274f6025c802f42ef00c6d692311c27035d7ed2ffd32d82671aa31429ba471b605993770e093a9ae706d523accf9684fb12a7b6e6da228e9e781a8c28f6cb6da9a6876f0e5dfe2fea4b6da856dc981ad8323dadb1768aee416471b87819d3685564ffb3bfb3ef1dc93289416b540f3a2f46f29bbdf9fe05155ed8d12adf5f85f372999b113d780e3034715f6e143c256cb2c50e86b044cb5449d09576e776520f8206ec7f9deeba0db6a4a131f0fc99e8bc794ed12e45bfdc9ad5e40a7f6825ce57f3f396f20afd968574b6ad34f3c150dd65ee11b7e0e396067e7d3931b493089ac078a812fdb2e6a56b04058a53d0c8fa9d0e6497cd89b0f35abaa09b3c8cfe7c89caa9325bac5440e971bc0ddaccc7390456b7ae38e51862522193e90d0d6452d19c2501edeb37567a0c6a9f9aa9b6dab2058bd08b3ed4f90e823ec4fc4c003e137004e0bda32bb843defc50ac4d0e6c21e1c8456963db80c3798319336723f4cad669696cc3ba07c98f986a9b7559bada4540b10fc50ea11d4eabb00baa323f4a8f4b93bed5561aa3dd36a0c8c9f56a684b65f08c7e725f60bab7f786b26921f9a638f7046fcd25ca266a4cdf774f29fd683d97750b7a9f551e99b04b3e6345f831cff027bae6919beab52eedcd93a2295f54cf4b14b010500d18493f99439a6f528212681d240adf2cc4556daf03ed57e19689f09f29a06b618fbe8428bbce371514c8b15cd9c34da0009fb854a8299b7d02f1c8b0350628c901427274f6e5c7f34c2097a56e0251eb14e5ea5d5ac0b12c778476d1eb4a85513387ecad05510f64bf10d1325a91f670ff6fed9c4a8421ac98c0d06 +expected_shared_secret = 4aff47d4682e6b414067b3020720ed442d0e2fb4a2b15c38df29723b8bab7b85 + +comment = Zero secret +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 76da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af6268b734e27627797582803cfe6006230901d074c72fd0755e011d676a8e69d41459c31fa5aa5de74814d0eccb67d6151dfab3d83927623242d78367f20249ee924c2b582d9d775a1cec0155a64f058aa6741867c7e491f6b53f1f8267832b7a6a8494dd249680a5b147579503425a55914580810673d507a2b0cf003cad1ca3809f6a06706ba72034ab8e79340d6232eef9815e761f6343a3bae63004c57bfe876b8d4a6a8b1550db541b359aa0f192a3fc2937078875ef55aaedc2115201c721db56b170239582cdb5c72ac4c7c94508210ab0bfbd1ac7cdf891fb370522ebb8a087709b3803069843dcd8bb4ce28663019cb470413e78097d933b44621b1f3a0930839807a13325900d0536a8f280225afaafd1d76c0e7aad8fa3af38884440d5b3a9f56922720d6854979b835c4ff69af290aa94d662fef6be4c46760b200333992f4df215425296f8d50876a94753024dd176991ea8a4b4256fa25a7ad7429303172bc7c06382316a61c0b2746252d2d7b1f501b2f9d6457e09955e29540a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = f0e103c8bf553c2dd0a1043aa1c6eda544ac9ebefb081b1724be5cc4bf4167e8f59c53e11c2d2005310f3ac9e470759f8297971fbe8c08e7edcf5501164ded5e40e0cc9883ce1a8a574579cc7f675780e1f130ebfd2a83fc6fb276da2e6baaaa80b9b27cd19268ed6db19ed2e5f8467e831e5b19d6afd169ca9789c58b887214fe589a0fa5ecbcd88866dd2f574c39813b4bca5de8ee9577af32ca11bc6e17ca841d7c565a630c145855dc974b9584ca24c9979f46516440c2f5d35f148283cbd41db73bfddffb5a36420cb3c0d15e81f1d6e0c5e99b4693a7c83a51ecf91d7833cfea740e2e53f294c767bae0982a46532c35737fb5a23fcdd46d530b7b0cad6127a66ad052ee518006c6024bc2b2944d9b7536d47287dedf8a1bf6dfcd8373444a379fd1756d1189ea101e7c26f579b32525973eec803b074764b13d96d60f68a279e34c04f3e43bec799fb0fcd25da9eb14c4ae21d10a1dd7cea23b2ed5724f3ffa5d37766a34bb9d3aa8330a923a41925a7aaf071593ba163913aeba546c75d889750492ac376acf12e841cfc53f28a82a1ce65d29289a57218731c0b7ff814ce4ea7cdc087bab5cd2d57f0f1a45d9ad7096323edb3ef3558649f8aa2fe49a146244991f1d0cbf2c2e74e50038d6c47d80479e04f6cac03e667dad2c8865d6c8cef96cab4d3361e3def6e0b45a2dc81a4993e05177f2fcf013d992a943cb0b11b6a75861bfc8ad534065aa832915b254fddffa898c69c24514ee452ee1f7d8e052bcf3f6f598fa69db0ce6b3397994cd1f139e665d87ddc69ff6a4b7368ec4e5d026fbb16c44a62a33c2644a93128cb76397516dc88f664261bd09409b2d0187cb73e3744854ced4d6cb1099c56fb325dc93232ba353e421c3e318669f821df71c6d8bc68cacd45958442575b9960b0d903406c2d6c8577bb1a3ca8e24f47c7bcd2fd6a4ab83a3caa554c6695b286b115df21699a78269b25ad7013978daa30290d541f3060b01e9c3fa0d703322700227d84101c9d50dbddd00c92f57154ec9cff10a3dbfe6c2d4b5a0e0099dbc9b4883dbe2d1ad748fa6b5136d8759b9ed314d330a8822ecd74df76cb605087875150b205ecc1b73023bc185b8bb44c8c3c32d76948bde1249730aaa1f52e11754b2037d2cbad433c9beba44b6c8cf19b15e688360dd2cb7d9832926ae72b5533cda8ef08a0f92c5c1c5c287caa02b79eeb8073492e46cc4183fa2d4623a36e0a968ccc6ac29ee9ee3582182c261c7c0960f163b290f2ef893da422ad03fcf3926942570c186e7a90bba86ff792472911cb04bf72a8067190d4d87331d52d4505618c60de95142db27f784c012e209addd58bbcda062c590296be66722e175ac6536c58bd10a68b6d75513c78853d4d1f796bf477cf380c7f533f741460c9c5c2d1ad851db4b761b9c5eab3fd9d291e7921039150f8d2b81f86f1f997214660ef4cc63eca4b6c76bb5742fa9920d6e2db3480ae82380fcfb8caf51abe21094736f58cd7e6706b5d10c4b33f021bce59d288bb41faace2411a0ac5c766fc7d87c5d6a4f0cf2fe16cce09dc7ddf8d968366ac293ddbe9c0c709a4c0b28eaf2e23b4212c1191112fb9a316aea3334ff9f4645245420006c406724cd7f254a46097daf669c2b137560a25432030a6c7d6f4732594f21a277b610b870222b4ff561a6401f10b35cc5045020cad9479bb449322d37df22c9522c8b7c5c0c4897b1175f0dd40038a477c46e10f10f4289a81477a07b8ea223007e25f5b871d246e585083240c56c3d80d4425ff7821f17acc96121ca9ca50b95ea46ef8116734d015ce88021c620b57fe83b5022ebd980856d5102e4e80d7b176bb79209809cc32a7d246df9df5b0375bac96547962c413f516f4f0c24c8921d148f0a168ed5e0434b72538b9e5cdbc00b7e7984c243872fe44baba62b917a3f0601b81cb1e6cd89de2f38d0fafc2eade0b00a573d59d290586f1040082080104000218c000000010000400801840042080000100008c18700020821041000002184104208c003004600018020400020840042100080304208210011000021f8004000200410400021041fc207618010000801041040004080f0010800f8000008c083300000200ce001080084104008000030020801f80f40000000104008210410020820040044000180100200008410400061880042004184 +expected_shared_secret = 71a637ef1645d00719e56ef39217bb4d8b2cbc71db826affc2529589830148cb + +comment = Rho leads to frequent rejection on matrix expansion +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 1ef7040c4b37bda74af8a45652510df4d67b7c618279d2844b10815913914c392a4119911d2b40da79b882534a6daa1b3b8679eeca4ef2b57bd48507b994a950b98865103cbda9b6fd38ac82b64859863864ea023fa6990f0898a8d3ba8a947fe859934ab06ad545133f57a3c692c19058a07fdab3f0daba0bb7846ef3222ad4bf62d995a7bc4801e5114b5c131130c58f76bb858abd1303003461442d64762cd5ce3421b52f492ed5660a4d632af3d24b9b5a1af291323429896fda2e21494e5630502aacc91bacc2902880c99890f259c1b9fa01e7a716a0a3a0707581acc347622369a4e610a1336047f3429ec16e7cc97607a11ff59473b5191e04586c1b32cf82da6816e47c72d7344e84a0d6cc42099781e5837eb6ba878e489172c41b4e2c3d0370874c0bb939c485a05851cf351652f82f1ba0a50fb235a6f10f98655cf2cbbf1c21acf999ad24f77ebed4297425b59072ccd1b6aa6467874eb014b3c911a0a9430cc86cca1aba84cbc709824a5f3abdf7f927d8f9a8c5d6cb955661fc7bafdec7cffd720fedf95353b01743613faff9b4c94c80472894c2322f641240b0d60549e4a405e9a20c0b794151a63a598e26eb021e1717723bbba58302096b563ea4217a8863350a7a729b0c1f8486a8faa7379a41515103f59b773be06a6b3b01ebdc67cff93147279f861114f97c3b9e7abebda5a51ed4518c6a20e679cf2a48b8bb354095b3ba14d07f3a61c18964cfad11b6b814b50c07bd2c6aa38c6c4b20d47778aa5c82fc575bf02b8967ac79fb9c1354bb1df83af95a839015c32f8b4387795038720c53f1780c6a5a42d828ea42264e55594732419e450afe13ba956581465a686a1659bdb21bb2083424d19fb0682687ab005f1111c4a43205db0633d301665c635dc016ba2762360474e728362ba46b52b54475140fbdbbc491ec5141e7947ba42053c4b63dd1032d8b8d3fa2c593322e5509c01a1584759892a910581fe6bc16b935a5931627b67e77247df0d3c77b94190920aea31c093a1a9146f75e51f07d45a607c7f4c38a5a23a3198cbaea7baabac8e70721b80596c015285f20ce45c9bc86d67a1942c139c9acac70bcfb7a1f0b993c7d145b4a03be0a86ba201647d7831c6d960420fb517ae68f3dcab3c5651f49d221037283aa4711bc3973ecdcb7c030c24b084ccb850f91d35e78e381970a948e376d4bd7b670086542a61be4c670aab7257fc58dad24a3afa727dff967cab9088587385ca15209c18e06b68ab8c66db7d680fe40677f8a0d6edb9d34b4b1901ba729338a7bb90f98ccc61676934d8b87d7ba15170017e9247a6445236512aaf23a6ccc629e2a2a7d748b0a67b2c64cb61aa549b7befbaef6ba45e0b6c3a72270de5497f6ea95059238d0d28aebf1cb4f209c24c8b83f19368c495ee05638f45b7002c12a23013f24721501d6aaa6c337af9185d8b733464229a8aab8eeb50f8fc5b4d9880897d3128387aae8ba6e2c116a63b5434be0503b77903f98a7efa5b919c4a86f39671a477c4569acaa07b316d8402a1580df17736056acb05379cbc1228aebb671f7ceb2a977e4f04ba363538c4c28f5a585d712453556b4cc74894740b73c5882bab36f96c27dca7caa815331ad4425cbc732ee3a56db445dec2cb7b3c5444e95bf796b3e69999867307af7c716aabca5854a2118eb78e92c9e1da4209ae0c7d61a0920e58f50f62aa4321d541a8ce7d74f456abf09b293f7da5d1549ab0d34044a624cd51c5ff3774101fc4e77cc76a0f3a1224c3ca2d42f92ac6a23862dc2539dadcb396dfc41e73996497879d8c396c3657c379acfac04a652fc4c32aac57e0368ef606bab471e52495369d7c616d3a3d01b668c7a0f0c305efea09a2d01b602c4a2ee47027b0c5f18994c3e369c7b985832a48372fa6af929605b0c1806539a0dbb2b1eaa674ab8720b9381688b18e5136330e303f0b4a9d6b5138a07cc372431c8958260c91c655551b35538860acac1f047905cbec0623bf9c33968583355822dd563af7b71a39113b3024074f865ba8073b412672eececcf8af0669413655c318bc5684e7a655e370840c59666ed8a6884c05060072fd2c0bde6f39c22c1348200855a66aac2155cc13233538aae893abbc3cb4bd2c87ca6f78c49691829a6cf40d7000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 3c14f18e865f367b72dddbccd6c535fc2945bab3799b9edf5dd5da57f28a74aec23c5113f792f0a92e096f9c7af548e96c6a4157de843eaa0a0089e25b8f85ff44187a662845fb8cab374c143f4f96c6482ce7cb7cbf8f27e06dc50e0783568652043c45767295f860e63093d53213c808692d0bdfd10392bab65bac43979fbc5aaf04c824df2383154bdc30362c28d0fdc353f4f18bec2620a906426f744d717f04cf108aa91c82028ae847bdd5e66eea3ec0e719cd1a3f0d36965a8e2a1a03bf4233edfc4b5cfc7fdd8ec969037b3f02404e3bc3933ee3c2e910d86476d9b7667772ac75ea46e181e95b9a3157c3420ccffb064de3ffb32c1c855040eac8cbc15c9ae7ca1aef4c442eb54c3e574c9155474e93a14a5295f66e9ff6292dea202b9bb4738d7280128057586e0a9635459119df84bbfb083f0545d4d8387ce9a502f2c3addf0a7968fad11284277478dea0b29c96b364ea62ae83825011f1ccc6cd7a58026a4250e76696b836bc06f83e74e528d216f474dee938e78534fe21423cea6f843a70096f83e144208700d156261c091782fe8787b32848ab55390e1968370203e59a9a53b1c48a6a449a55ae997d5f222712f4f674991e8a4cbb62b67479b56933c290f701483d2dff855797323f19c06e692940fa32c9c2964f700b4147e23dba5313ac247ee26ca05d147e469b6e870651878328c79fe28158e29a6c41ec48356de5c2374c2d7ca435330264fba31bd9c1c85be3afcd456b3345a669577c996062026108891b8cdd099d91e3c662fcd1a2f28abf1567b519ffeb46e9580ad17a5b13c9c52c544fad1648495b77394232ebaf7e26c57fedc43bffd6021fa165e526627a80761207ea3ef172e8a26bd65bf51ae6ab9071c61c17b19d02e66ed12fdb851adccfb9ce73ea98839f96ce0eb6e1bdcceb752d7c5ac5d6c4bf6c56258048a21208fa289dd517511a5849899ac33d50e1e94fddbcca5987324230ecaf242497be400d80541101793f8fa5bd896bccec92e425bc63500305d69a226a165d070545fc2277a9faf16c5b004aa8c7e8c3147890cd2ab0847afffd4026ca76cc6b5d6c9aefec6fb1b21794e37c56aaece2cee1881ce64c9941f904c6e0143f0332c5b0b9ef7fa394070b73a62b2f811ad53524fbf9a038f185daa3546715acfd63c95594a7f18924c3da980d8996885b04cf7944477b2b9b1d939e81d14f84b129f76046a6d78482ff8debf21315f412c234cb776f529829e07ddd89806e343112d82ae23b90657ebadbb1fb7999c868b52f907b7f8aa131dd334a5332b4b2d8fa664e18edbd89b4596e34eb631cec9e81dfb44fded66b9f236add78150415c3feea074e34b43284765274defae58471f27a889c641069b436ecaeace548b03e95cbea4a424611b79c0a26502808b8e35a1b285163db948692afb29d94367eb43ae5df88467e4cbfa92f0f4b5388a975026c5cf0ad2b8d10c53f3eb5d6d94e5082302e8780e5a7dbe4eeb7061c02f4a46d6611f6599fdf2121bafb38789cc789f2e1730ba6be17caf12d5deed32f731126b3a75f33b86498e1c739db09c3fa2a97fd77a16ce0d6947e5c69120e1490b75cecf695390255938c9f884cb0248082b36ba19580130dbd292b34bed650c4eeadcdf15685ed27b6c23edf7d218bf7d98dfb3018fd7e14e68242554250886dcb6a0496220f8b4c4aed6c87dbdcf62b47bd8c07f6347773937e0bd0680e7e0d62720947ce2a2bdead1919ea3859bb01e341b814dd13615711afb12320cd914dbc97f6767c5d0d69f0e38b46e4bf3b132466bcd89ba1ae98144874c28bf476702975d3afc17fe4bb1dec671b85111e5f1e359c15d6b0421935e26a5d4eac269b64d122f9419a9fa0fd5d239fb20fa31192ba2acfac52c92cf5f339aa80c3e5a2a4ece0b077d5114df54349cc8f2b6daff625d347f5fa60a37913a1402bbf9790eed6ae5b67b87e076479ed1abb258d6a7e91ba07786d819ee869f5ac216341535995799e492911a9b077be49ab3538d3a52fe14e19b6a0d6af2a7df2cb1e5904a3941b079489f574e066f6c565828d2a312573fb6e90ea67a7747c8b55b1f117482c77022b38ccee1a397d82f272166b66af0ab67b631b2dc891e2ce4404e6446563489077873674ef477e9da7d37926489ef60b5a028e8b6ddc871bf5c224be846b9299f02b82c8dbead01d +expected_shared_secret = deafeb0bf0d0634e5acaa34966e58df8b9bb63b376e3409db49b4b117643fdc9 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 32f393adec83a1bc0379bc0fc42015610c1e8fec7878cbaf623959a22008ebc81ccd02b0847a7318b414f1ac47ab2b0dd88049c1047e4331767f3847bef0750ac4623696bed9c2162d2b84e0b4b606180a6d2b6dbb5190bc3c6a51780de86071ce2a0f05758e199983ffe8349c036d6667870296c76930b34260af449b2a6795b4fbeb3309f017e9f820c145716a91569057a22b44bc38b368fbe221e1f92d0d5430913580f534b8373aa760d47a0ebb6bcda55b5cb62797b819cd185ea798a1b9e21391381173d2a416eb98db74895085ce31c868f52a2f7654b3779a0a324126c1b3aeb73c073deb19e7925126aac8d87bb09ca69b68dc4fb17bafe16a4315677d57d0c36e9479fb03a30609b7456aa8e8b76c97100728c46ac8f39588f7062c1b27fbd12f4c9bcf95f24f1a698da0e78ff1f4481691068ca7070d341dd519c63815a2fe3286155c741e20a3bd8c89ee6bb069bb89b7aa1b1c4b4ac85699ca2c786d8305cf1c4527979442fb4f3823c7dc887abaf866fd1b20a9933707c23036e653ed99476c242c791744cba152f45040f6bc3414a13dd8670327d50e446a22b07a42bc056a95c94d911356e276cc95d585aeb25f061b87da78550805af57414cec34083be60f6e7b0ddd1a9c60f5725681bb70db9390014df9dbc5e022b4c24563efbc2b32604aa41225d9993f924cceea9c0196a8065237cb47035142b0693d090e6ef48ce85aa33b57c9bbd4c1dcf4b8314162e0f9b44e01732d6cb7876559096620e974cdfc263adfa1c8d94ab6080cbd42fc1a585009662640eed3353117017e754db4cc0901f3c18e6452667312386b8bc27c32cdd9c11c14403d390f80f121c02500a1d03942c0aaf56a83f3f062ebc708003d7deac3a47f33ce9463381b19818cb97c8d61c320da588105651f5496b2d38615a5929e50234a54393814311b52b678ea8b50e3ac47c30ab2f99998a481602b4aa701384ed347878b85b8bc108eb90bda44423e620613e223ea6a03708493b7013be2b926daf33fe3d81fbd9795a885accd8b4ce3ba33ea57bf04530afae5643bbb4b22981ff5b097e68c5615b70b4213b3feb020e968734ed33b6ed87cbf5468c5f055a1dacdbb9b19d2a057a6fc371d389ff6084fecfcab2f0bb66d0931ce29afd098ccc4020af50275fd5600f3b31c063174cf5a63363752cf5612f121bcf549993132c71dc5c4835c396f2436a70092244c82b5497209b779786b3a399237e0a7237e550e0d784f1258c540ea91bb99c915f052fc8164b6c1b88058242f7b13a98cbbe1646274105f330ad0377ac65e6acf89987979d44bcff381620335ef93b9f7698527f2c55a39a4858812e9cc8c99aba640c7915bb1475ae172bbd2251fb2695b842d27f688e1e23f607905bd347c83db7376706f68ccb72c94519e426840b412944c7181f72f98a56c0c5ba302ec728b31a43d6418984c47dc0276bc3cb6c2817e658ba9acfaaa1017659d10beeee7a399e6049dc62f5795558c082f273949d9f82cab2c3977359f510394720cb9815c240ed64ad4f4c4b27057da3abc1486942d01c5852658a267ac18e886c410031bd9aff0950165b53e53cb28b21172b1866d2dd16f9cb59c9bfc8aac8606bfbc2a0861a9c7f62d3d41074e56a73615085b9053fd2ca533470c06970c4c6a097d0b4661c2b001e9bad5238392b811a1276ed0a65493080e94b7813d9baa3c05c9f7820f77e4af8891170a6ab302e23287932b82364fbf5abdb4f2716e5b74705b0756eb6e3b1ab9f96707ffa05d3afb29dff48a004b86bcc784ea003727a49c072cb3cc6cbc4473c40965b5f76670d8cc1a9fd3c4982662b8fc2d9e982debac25d891217dd24f798346b2ec770c427f49ba4452a1c8d49b9089e751931bccb07557db36bbc13225590cc94586058c3c1ba406633e650f703a44aef3c305f652a4f4c785b02eeb40cab763731a7c20d062125a24b2bc58ae6c4a0aa4e4c5a330cfff7a46bac4ca58a33127a8bea7d5598b29c49366cd11cb4d60d71c0d08cad7145216a8878d6c346a32a948b52300c8448d55a532877daffa805320bba26a9f6197a08f71b4f9210cdd9c3416263f5b921191084b87236649a02e9f0a20f09004bee065485088430924326353ad90077ff0a10fd3c077111e909e000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = bf6a1a4a5905e3b6bf5d5fff91790e56f6152e31289585d4209cc364cfda745e4da6ab9baf213a75f7f6ae50b4570298035dd17a7108ccb8a5f511a0377562eb37eedc3426e5ceeb793eeceeb5f3ca4935c68d352c6b1ae2bff892c04de562dc2197cec88133bd7384679a1c7cdf80a43aec446e60c8690c50207e54d1d6771bd41ca54654b835cec7bab1efdd6c0417d06cd74ee851c4b0cbff894dd245ea33bfe28adffbd0ec8cf6b34148c6a8126b988f83f5517125b998859abfbf4e9eec1afba438faf25238657d0b9a370df6445dd9527e85502ceffb25e13fe6cd8108475f56252a148ca7d11dff8e83c760a239da62f994dfe5a4d409feba83005402252491e87b5d585168dbe6c4f9b257bbdf7797526a208dd05687e2d8176655848e9f171d6fa63791b02e6508a58f70f461c5de34ca3713c1c0b0b280db1d493ee5103e768ae38482a38692425f05d91b496b47743f28a12d34cf26a7ce164bea186549cd4eb1e0e9558902aa1b63fe90b3b5a1ae952676d37395e64c873f042022c7c9fffe06e875a7828af940e0c4bd0ecff75d8154be5bb5d3dca963f35b0d5d45020c4e793c4f895983a71a1f48d8a6a03cd58f570f56eb3affe3514f89e46dc9a91cc466da782e976aaee83773a481788cf872ce552fc56399fbc8f802303a5e8a0215fa3822d21393d268a15e617edbb9de328ad2d92633fbac21f5efee93588b8f8789aee93019e61602374bf84e004174aec2a98939d3fa29462db61e3cc1acf68606802fe312336e72ecf9faa23177235d7fb3b00b5c8639ef16af505f42943c3c3b8bf0b1118ee78dc8143fc74d178b4db2e4eed82cb21930e67d5fe265e2c095aba86991fd378f5bee637e0a6e283440d57b11cd6e44dbc55e06a574fe959d946b54619091a4a0ea394e5d00c707bb11595773241b23731cc741bbe253369555934daacb06492991e8e5238344e75c7b3b6d85cff5683a75995216228922bbc0e5932bdde90486569d60decd6dda4cb4e8961a1beb45e8e0dda5fe91c2ac9e709f4585f4ccb56d89979767cabfe7ad88094bc975388840c55c8379ead9374b5b368ac51fa7ea08fed2519209ba78dba663a6c2d352bb9aea6bd24131178c52d4a0e161496c758fb8a451001292b56f69180c18aa5afd1a6c0bc1c141aa68fbb9b74a75f893036f3ee4b65eac6a9a67694d8473db851fe78d0ed544e2927c9cdaa0e8187389cc0a15612b1ac53c59ca1deac4cfd6a3944b7df446a0121dc81fa7ada3660e27f6c2f65311f9e2e9a1f97545a8b3c6e226ce547a3d9d283cf37338c07e2f426e7017a6a513fd104b88cb8b9a92cef6a1aee3f12f258a5d059318830a6d842563134e896d577adcd229548396e5b1d3a1bf80b49c064cbc20f22eac0a2f3da972c580a92b293d99b820888ac9b3c50f0c16ca80147e5e73694da824b0e1e1cfc771773727744822e933d2631b1376bdd88f37d124bb6776b83c5918ec63c48c8b339b62d1e487cefccbc8e9f3276d1c29f448c5c37b33a2442f096286e64b90dee751a6de0f50197805a6db4bf77a845df7770dd34a44ad0344caf560c77e7edc655604a4d42e591842022d64c1ae605c749479ba401a31867b4a11b978ad690b4c2a7cb6d0ea262e15ddae9025b522312e08bbad67038b4c2e272bacd18ecc2317410901ed69b6b9f03a6d5575efe5a9c08463ccee314a522fb24163630f888c9eef18539e5a088e80f4604612515dff0e0bce97e9788d70d148431e8eb9cd49f52a42e21e36c392dab9aa3f3c80e6e8f812d18be435a1b073f9c346856446dc5144f5e6776704342cc877b6bbbdb01cae23a579f5238241988a9ddf5cc7f2bf64265b465fe34d911c10265cf7d2208e526d51467de5fc1dff6228d771b643f4e31ac9edd95929eb89c98a3849a34a8672660f8464c42d6566d5ced7639c2f2165d505c7eefe844649a605a3622e60569676a41cd7db48ac0fc624c1cdfbd8e1f07ec14519023b068dd1e58e720d53e61560b1d00f7a1b0f59c20139874c4d0c35004b5477cf5b3880a95864eed75de14c8be43a52cd46d6e4e510058e58d80096a243e191471abdf0f2ed4d7d61ec97ca4b7d2658294a15cbd40414ff3e185a809522ace539bcb806881019930bdab728fa2f2d773f7997db7aae3927500a4a9b9508d199fc622bf62f445fb0c0df9e50e34a833c0a +expected_shared_secret = 5a9c3568ee557530a57078310ff6452b09049f55f30df0704f9607674971e033 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 80d67fba099be5882ff1e53ff300bbde74cafa260a124624df72a7f73449b253525e75b658656556422e26352900a0b1ab258dacb5cc3ca0ae9da2826f15b8aec76676920168492ad2b9b56714b3881103634c1cf299403864cfbbda1546d1031e022ed172960171bf94894dd48331f5973bb509d068a32a60f56377b911f5226fc77ab27ba0295ecc70275a0b311284eab09825c14ec7826779039f3319877fe39d8f938068b9916fc60a7359737a918286b2c943801713b78a8d14a558994fccb48ca20065a013318f099917bc930d0ccfc54b6aa0a7791af5c0443c96c17a5a59666f73c395139268024a49bc7285aa7634ce461814592e74081c04a99c84a2205420a5a9777a24b11717011d897c2ceb02cdb79b94d26862df47cd793645b6288f4e7a1f5d18a1bf732dae8850f289307ab82ed5ca025c1553b5d40c6a776946016016ab5913845958904b53fbce279979dc36a0c6b2c483864b33178998e090d0e01d263c84daabca5258027f57bbb99c00d817749b14bfe4902ccb65258d50559d6678206ba44f3c0160dac0434a1e2d25bc16b407b0209b1b08122c68b75a6a4f22e50387f13a3f590ddbca358fc60e8802a25b31bc4ff327c1da127b20132f0036df997b0c7a1d43f8758b4330452ba985c9241b1879c0995247569bd1a1c927b52bf318695e73102e892f9588a527c68196b625ae412b4fb35ebc3c147a4c3860348a414875b60233f8061c38000401452957fc7223303930e653051535e647943b1a50d324108189955e589d837b1ad3fb331ca7b0993c0d5275b2f9254fbdc87ecdc8b28378553719b1de9297bb65abe703294d11aa41f7a5832a7247c100002b2c3afca68bc729f0f2432ecca03b83b6c748cbdc457e1906ae03f25ac5e37ab0880cade4c8aa6904862484e985a88f54c0ac75712ca9706d9c6e130376a14549a1a7a9d2bb155e797c98a22076e00343a55f1d488941a6527e808a65f3b79a73b46c3523f71455c0bb33d26690bf657900d549988cb96069cec0822b1127cd9456c975cccc86486ea3686f46e0ac92b35ff2cb881106c1803823df12163d004ebaa45919dc7a2c304868885badfc4baa43bc386500b1f8acbb0734183b674b338cba409684f993d8a6068d466d4ac82dd5e42f336badb7c78aa41ab2d0eabc90d9a6ce033f1dd9755939a8854498c7415af65b52934246ba521fac2780b0e1586e351dd6266e93ba9e3955c753841373dc89504c7361081034f02e18311fb2297fdbf79d004ba49cc916836209965c6ddc2c4a55b667eb1c08d405b01bc6204250159fd55485d29c48da37dba05a6cec2f856943f383a6a5ea09c947c4c7ca849881aa6f407a1e86be6954b221acaede360ecae49ca9222284695f93480ec710365c68847e7b839aa81d84c6bca8c7a71127a750e078cde65bdc649b17a0a928c8cac51a9e5a40608f21b3254b3e38f81aedf4c69bd49aeecc32089634450c42999357d432a82a0b96a789c3001c7b9a5b55501a7f360616ba7a648648866228bea7520fdb11c70d549fb958c673825f98923469fac9af62c702bab67f29815b331a136b34b29bc54302bf7f35721e722a01cb7a327b078f590864841926214a3f068fddfb8cb196c7a8d8c78358488723bf508a27729085ec4c9bb7337834212b2ab082ee1339a8c64e267517db35ca687826d4b62d40b60aff89c720ac62fa2c3091eb87c3eb1f33272585a6c91d8c669b1a69c9211c098105a0c58960137b3563cb16da942cc90e47c95bb0f9895af845024692bdd99e87269c15f82468454791c7682c8962bb8b85430bb6ff067df8bccd78a476779b075876350b3668fce84af7e5b6a90911f973144740046aa7bab4a1bf2e6961540990d159ac6884c85b28309336ba18ec9e2455cda24a1c25246375dabb21f0c252b4319452719c84756d730a33a90502b4749d36a2ed80b755a931148c8074065487504b5a7c2db6f648adf92d8c8258d2689f921123ae5495feb095b5c4981a860df6478340bac21b700601d324c9d0a1951353fabaa885f00b3622b59d31cfa2eb524b3a5f33e520c6074382ac30cd9636f9c3693f17595a4942f2bbb5b168649fc35a3ad63d11179e64c0a7cb258692087f665620dd0125e5a8901eb8468cd2007020d53b72000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 516f535f15a891e51513c4f47d87634dadaee540c8d5c4970f199679cd8faf38eab3c2369df56d5b31722036fada3011eaaafdf4f83acb5141e2054095ba0f31ad2b89532ce8a55908c9349fa23ee04b551853012e712538f02c7c6cb9bf3ca670b8a3319aabaa5f857586bf1cfba6226144b9b40bb90a706635c1a4d252b8f3bdbb3eaceee7c0dda061b9da7a3166c1464f970dadfd92cdf2f6589dd8c07db7d8e7071978c7cfc432e668eda06826facab576af7213713abb2c3538291f9d09e59f956b6f2946d67815956d3b9a492bc2bb1a2942e869245ffed653be70f0e39ff06ac55d7f8282b331404bfaa3ba7213c17f7939238f7f00931e39fb5e97bae2d4f392f59ccdcec0881d75da5933c31f20d66b60c9383d36aa12b1a975fae04bf808f6ba0099a838382b844df1bcf1366e96c462e2219ae96c3d25d10792c775a2d488b27026e17dad61745fdfd44772116092743bc74ac5bd519dfa22a39f90f4bf38160daa52caaf71778f1c2030c8715674c2aa7191c988b6a5ecb02bb68126816db952393e8c52e91249f14e920003a6f803b09543342360857b2de0b227feb86187bff55245d6ea004d54527ecc6196155d0a32fb1f97908c2e61ee1528ba98d039096eaf8d4bff977f05a9a0b53436b55d2b9322cf1b0f6891b0573d44eff7515f5005f0a12b7066180436c24bde5ddb183652b1f41245f812981fe0e97ccbcde1c2f3ef7423d1bb5e744c05ff49dce1af51392851a716834b4f059fe179f1cd31860ed8ecdcf440f62333c86a6cb7c21409fe20afafb972cc3ef584cb76b85208c56c676f21eb27bb490263fafaa2e23e8f3379023df3250678d0287badd7cf425c04632c1b688ec438dc6b3963a26e69e093fba5ed940e672bc8ae109bc78dff824a04b90dcd5a5a453fecf60c33596b4a89bf683e1ee5a3cadcb0a6c1371cf21ff75335f16d94b67c0b774c38c592a498a9d7ace89c5cccd998a339c84d3ad90e2fc96c0d1d4caa6cba13c5a11a9e04936f3610e16b36c2c37bbfb73517ac10ed3bafd6b9424c2dae97600458553a243e124c85ce66b414129f3f08cd48b33af0a633befa2515a5b7eff8b6ba70710538926d05ba1fe341426278efb17b2b3769069cae9c051168b5e5deb437550e1eb7c0bf88c2514fd51d8d511b7ec90c233b846a103c0fc516e8dd0805c5a2b0880b9a5e293e0511926802b252b7781332fd73be09f02a7ef234cd1cb1effe32cdd7e3a37c8668884cb8e6cc10033f42786c3ceae1754dd4b7b9e69fbc8273e27f977b0e1c3b320d2dde5f9edbc751b742ab24cfd776a67f3a5d52409911d1fc1dfdc1d35771f5ad35d19c36401b2688118efaf1c71f333528ec6140dd2196946d69c6f1b6f53428904dafa316bd4a28ab7fbc9380928abece9ad7ff6c6a9c26fc581550900b7e6e4db71118da5d5db5c504d0d45b310abf0057523d573f868aa04a99be48cc694e194737a1502c2a379ad39ee8d6448867aa2c970c84f00c446236ab4908d791d304f69089968ec5412a807501f5a11ddb06bfa598ac07ec27776415da98efc38326973d6908c1b8cacb95cf2a04811ca39bf1ffce699e4c6d8bd35e51e4e02b89a3545391354a8f4d46beaf9864794524bd6c975b15ae0dceb2c4623096d75bd1ac8991880b3cddeced70fd3b27af44b2d36147c2e0d34048e4f30de879618e7208529d30122fcb179f754d2745169afea6e91d5538d67c54648faf2b61ee1e75154db58d17160dc5a5a36fab0a8dc86e421c4d99f963e6822802adc7b261357bf34fb4ef076d1d617e3ace0b8936139b52bf6ad4ad26205dc206756ca54c972bf932d4d0646df0eaae7a7bd2962b26df4aa54f4e9cc353896163c8b48355c7df687941949ed03b3434102708f881cd9a114163fba2263e29f992eacc807c2a96dae2cfa5701122f8426feaaf2d739802b29f1d70cd6a46d1a8e15bbda052c2ea8d1f41d4a5d856c44ebf9c7fa22005eebb61c0f0012e4e36b2ac1926db6938790e1319b9bd66de5ba35674bbf22317731a8133eb3c45cde4f328275592472ede408060462ce06623926426e5c2fdcbf725d5bac2b34e0c887e668e0be3c1cc7ffb97dd030295f8739c9813bb429c4ad0d381bf8958d76780beca5b9f559deb25905c618fabdd3bba6a80085b2e5b048a93ee2673447a70a58a09f06a30298ee8d4170fcd +expected_shared_secret = 2b5d1e7837bc6877b4bad1c4b7e04276d96f318dd248017846f71328d85e2eda + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 74187555c00026e85418aa30f84bc81607376ac9c2e64a98a4c024c7165610027967228cf5f85dc88ccf5df023a8cc0e76723c97b99934766caaa3bfae25afacd39eaae56cf36023c6e368cbf38f27a268ca24845c48a85f2198a6c1744c73c62c830c34b8248b52b62f847c3ef87b6458235fd25cbe2abe57aa62709452ca6412c0932c3a10bce9181628631db6a7b525d1c7e5231e33f65470a31371023444926a19f80a67495a9fd1043efb44adf3789c576577f5ae6d136b3268606fdabe081509fe1c4c05077a6805b22eea9f965666e82866a47444721a3e7647250ccbc69df06b3e3c3895c30f6d275ab624913173952d630aa72240bc4b979ee55ce8505f42f1b7ae797f53f4b23616a00df2153fe89c94391a35074946764275e064abaa01487830839616df9485423029b470401cf010fea769d6f237cb00bc2e8c13f6c49f740c9544aa6519e93dd824ca395076c184b2b2078e4a51622401be47f089d2668260b1b8817052d0c407a76009a0b61abb0a0b3c481d86d4c4fe19b910d1b34fd4408098ae5a599e7eaa04321c44da53297f788d9c2a0707f8788780343a80cfe6119bccba711424cd8c453649870280568347ab5bed10b57222c213e55c703ba7f154939898c89e43643635ce47534f770c44dc839f295b1361a9a6bfd494baa2b8a3264bddd204f1f063887192a0f1849e2b0b3fb6293c2cabf6fab1aada5ab9c35a6ecab7b4c605d6178b26203ea82a76a9fbb7d95c8cf0230dc2cc57128493d0b47324d333ace21d3b3750ce6584cf193a0aaa25f8f865d93495598109d5b07450bc9c590905e9a19934e28bb5bbb149f2b68965056b989338240d1fc52e87446d3ad6617927cdbd268249b785695311458909c62a724db618fc28114a904053ca89d127150d930d583ac664ec1ba08949a027bc86c403d0865b9d3781b0d4a034067fc558033760672639697d649f8bc4cd2a90ccf2435fcbd98b3dec0367f02889991aff7709bb0503a2c732c3869b4f969a75f797f32a323d546a5c47ae6e3292872ba85414c7cfb28078d67afbc42894a92172ec2270974a259680f659a03147661ce4ce94d608b62a660c0099ee1460b71b4c091110ad6ac5e5c5978ec04a203686f1385573663956e8c77a5c29ef06235b671ecff82e49d68f8e0054409c68858954d25162f0177fb08b29f5d9afcd4cc512d8b0f42877a60197837717887849ee127d5f76871276b9a285307e96890fd3569c9ba5c58664cc20744c9609bfb859f72c85363a34a721bcfbf2b9c48c1ff8d813ca596430d62370f91b342516e650173c711196a50396e43b46d6661087c4adfb8639c0cb17183dae91b95e1832ac14554909390e087e3bc09e9ea5ad53670eb93c4fc653a6798428be514d6d00509ea1310ba84fe56b2eea2006817b31bf661dcaa3b26592898bba2ea0379aeaab254b9b62c4421a06254798b892272095a989513a2199c8d90afd753b574ca7f17c2c96334f32a703dfe4735bc2965db62a5c995e349bb1d6c63736874180b044dfec8c83527731781dc193b68c997b4f8637a7c86a8c38172e42cf4ea46dd43abed5b0b386508a00bb0203d6a8a0ab5edf228a85aa8f9152b48bf1bb92240c92059b531b4206abaf3478c41d0c1c054422a7fcc405f7bbf453cd9e133208e2475738a03e1ac2f18088cfcb51c8ba447514aa59fb54066c979de9c38c43cde0162f30023c3a1026a2a2a18cc6c0cfc390b7336548a06239d287b6709ba92869a8673448e142f74848bb38b1ded527b0a69370910fcffc53cb875b008d7505428ec11b3f93c7ba27664ea1099f6dbb3cc1ea7d84e1807f3b5cb1b2bac0053c8097094ea73aa033221c853f88672e3ea335a5499502037dbfa227aa458d5ea59d80fa4a2eb72fdf514f4fe22763d227c9a69a5769b63168c4b4fa9403e3a1ef54b39e6568479796c591afbbe1a911f92df63aaa698a2f5309a92617242999176239bc01b8ad26b02b6d7446d8067a52d40c424b99bd353de13a6defc9a92855763fbbce9f648715aab80342beaca6928a036c08361643f669365105fc6853db1a44ac0b574a842e58a74905c9c437fa375fb22d7b113ec4e91319926168516618139d8edb60574774bd808f88457609127617c85394c65f2e3d78ca47000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e831dc3e5f67734ce3520b52763f64d8f40199c8dd2e723441f9d9fe9b33a1ad8ec79fce3745bc53ddf45990ee1f86fe0191cd5515093eebf6357409891e4822b543373ff83f3c0f73b67bf1e15cbe8b95b0e3dbbb20f10fcad2bd05778ae106e8ab813a131469bbc6da7c2ac3b991c6e070fdc7781cce3cca56fb572ca822b8a52592d24141f089a4dbb842a4318a223b947aa7684be12273592e0d4b6fb65071f9292293a85eadee0cd22b6b893a683d504906923abf3b25e0e7024e7b499b281c965fdea72de1f02fcebf0bdbbf6e3ca02bd05089f79f641ad199300cecc03d88d41360cc895e77ffec06f835c5cba89e8e3d17906bad950b85542bcc551588c32f0376631f554cef3de448afccf8efeefbab031f1c95e569c8b90bda0038082185370403ec340ca345c7cfb1e82a2c5c47bbcfde132e798f53da8c33adabc610272e7ff2037a009e3d3df4f521e8c9b5f3ed7cf28bed5d25145926edc4ce783b11896be3ed184e3d9b92b29dae5510fbec4386e89bcfc033704d05ba91bc6bb09320bf017ad7c567f8eedc273f992fb6d6dbdc9fcebff8007088afd5c9eeb3b14b152185a01b8fb537530b7369b30ed437a280f71597d09b07c1477d8680ede31997c8b125267777437316c44c3b1a1251f608ebf5b37416b5a2914edda779653010685c0d391f888073bac0d4f9b197fa009bc0bcffbcdf0fe2335d6062edbe8f25f87abe8f75b80e9f9cb6709057271ed6690c9b6bc6044c218d65c88b8aba768350567374b66e0489803a9932f77008faee9a83402269803ca5c90592491c686bb25b627dc997a3a8c6db9e5233e02ddb4e5fafc182bf996f741f6f34933d7ced8eb86da62e2739f8a0b956ea7bd854b1c6328671adcb0e233ab192e6f77594a2a3a11dc534a21b5e49bfa45122e24d878c4614180b230836e95a9b3dc8ceb7c826e83a66bed645bdbdc0c4257cac60406306bdfa30a8b8f5a4480db8c75b68b31604cb3eae19b3893d3600932523d0c55a4ed3bf8f86404764187dd4214de1d9bdbdadc7c9fecf06a823d3b3ae16561b3b1890fe1b9689d92e478120e9c38262d312b3ae2eb3d773d946ec99f018a6963b261fa65de5887801882c64f5598003aa4dba947022112cb33febaf8b224fcd3ed10cd2f6b4396c966b5a9709e69c7b7eef4a926171762ad9707af6ee93d4c17b04af42fad670cb7099393d8182045a22e1a7bb8e02da5d4e1fe2bf8c8bdabf7f7e2a3e1fb5db003cf8078635dcbb3cd2b49cb3b8d84e6ed64944c2d75cd6f557deb1b51029df2320ddbdee99f41153cfd7ba46d44c63c90772c3d60531f60e7e761913dcabedd57bfeab2fd0d8bf7df560d8fe30763e7d45c22459991ef1583e6e937edaab7e9f1e8a68552336993460c3dfde7f3a3c5b8b44d6afd57f04d62feb97290b488286426c48c4c87fcaddef7c06a534b671698718fa326549ef5e8e724cb11c21f7b362b967caaafd8205a3eec0a52bcb0d6ed6a1d0c4f433cada99e021047536782581584ef2677b3f3bf75983630e70d57f90b13c369bd4103fd643953190a536b05ea60b47da77bd0f6fabd0ded8f608a08d807234b54830aca2fe82a181626a9b9a219246b039036d1cb04748a2f84094770a12de1411e4510f11b5d090e79d8185cd8718649d88000e6f9571bdf78623a85c42afda73e637bde0b5a5e73aa2ebe2cd0897ebc09ad6974d825a5540627b1cb0e7df03a73b91270ea6402927bc4698cc061cbbec9245024e0515bc27a52714e2189ff3a17caf5b3530b781f70786f074d5c01b5a108cf7d13c2363cc54c73ce71b4b33eb354dc377dab5807a7d05808833c270d5735fb1e75727f66d3ca1ba467545590f3c2fc1218d94bb264ae313930ff8485d616cfd5a64080837ca618344559b46ca89c8b29f83e9a2bb62db57cab70be4042e01f68ef54d3a915d0eb51f21ff89b729ba4d63c6b2fb1b14e5e397f13f0c277dd81705581de763d3a3b8e2115156b4766d40e8bdc0d68bf76e14233d8be21a68d881ca6f5a11a1ceb0393f73a9276eb78bbd740e4a94128e6f5eb00aa10974cf41c6a4cd22ead82816a402a50b306b5312ba196ea4df4c5386668079ccc95a75893b834415254b2feb5b25f0c7529d6954a3657fcef64a8eff497b95ffbbf20bf7023cc62f2119e2f06b3e5fd22b39feef1acec8bac4962bf52b90ed35 +expected_shared_secret = cce58b5d736b86aad09ef4782fe87a0a4555c7f0a4b190de6246cfb21308b103 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = fc2177e50618c73948527b9073c885ce0873dc47350eb3a421f59b4cf27438ca36d3f271b4467f61a2bfde259cd4a67674c4a1827a7e23e24e023b08aabac3c8855d4c737f0e73600f368a8614529aa4217f198e1eb69696f2bbb829835ffaa069f31b1c9c5100ca1ea6781b47c3bd788ac8a3831a56b08093fa64f70a1d3402b17b184e96dbae2b84aa75c2116dc1ba6183c6ce5a3cf1e1c65807245fa3211e9a49703498451916a8a04325bcbf34140539b89acb550565525f99aac5cff44d25c163d30aa6d9f36edd44a3b2c6ba5b54ad0b0b28a5e0991fb41b909067c1300fa6d174dea315f33434b6f79016b5be65d87333e606b2243ff524a01a754adc354ae2b444271a1ca5d4c0f06761300715ddf58cf16a41a83892ab379348b778d1a62cb4b806f03c3f219b8419c746b1b127f5cb8a853955626ba6a5130b19022845cbbb250759bea234592cb294fb7c97777855236659f48b59a21c99ec9130baad818536ff238b33234c718a45de873a69d693db31157a86c9a123b5ee11b715b90a409308efe93db1e3512b012435f26e260527681bb939216ff5409002dc4dd8ac83f41c745509a82036ac3ae524cff190e07998b2e93bac316932fc0a56f98f27a7189ed4449b875f97a2950366754d85a299a422e7b7405b629542007ba5c93e372ab3d6b2ca26db5a9107cddb34408d0b075e209239c2c52e041c2889a625b86282ab8232e10cb14c04ecea6037759f8a6057d4c2037527bae813982128205e535a855710e077cf4b3c94db0683d462365f40043a328cc0991b84e8066e44bc2cd020722157111a76970a521f85a24708565c38babc003b1f84739ff5c7896bb3b9515cea8074f2eb18592b2c9af9b67d4b3f831093bc49993cab27f4b8a47c4364c2855d9cb2cc7e5c7f9d6b70076057e3b989fd314e1c16161a4b1e83713c1fec8cf29a60271808c03814e7252c52c1440d933c363b9878b198ad3641c92c53e5d4bb240b03fb81086662041c03189e43c7afea6cc036a12af28b051792fca44dbec68839d3ce6de4340e88bb4289105e162e8021c169c81aa462866cf20eca2206f7745685abba5636897a8c8ba1292ec1106d623b0e2769244f702a3c295dae415602a2b313da54184aa3c32992bf3c7a846b30fb046c816ca123854481ca1a6d1076ba261f0f969003a37a83e822b668006aac6d5ea3be1f91c5f2300c53372668d3059ba8b8f6f020d2c5ae135811c395138f4a3c17f86f20f2bf704705f7b7acb1c617367bced496cb3ee5bb23e34eac352d60459704ab39b7b2b98bd2c7d5f809382331c3f29bef5aa25b18adcd821dc4d0854638be88fa55b1d00babf77ac42b6e256a1fc3030870a8c612dc2dcc686ffba99093b13889da8631a60b150946cf85188e15826f22866168600c3629494063f1a16ff5b90d6db24cb08c6b6d0257730970942ace54f0a0316b0518c1810c860b276b510424163e6826dffb02fa1572b96a857af935ac8423fb9179452cbea55c3fa490148793c42a0450dfc286ae68b782847eabc30e3652bd7d998324b6b87f7b308a947b1bc74683c02f73f2b130219529950bbfbb6b103645685c8461216e8d51bb2c1266b449657e63625af83743b584e325866ad14b0d5361975c01462739139c8ced3c356a21080d5649753a5ac4849c7ea42820d712490a174243cb744b75cad06f4231ad132321c6f91469024a29d7ab8dcac97a91aa8a08adf39638c1053082c3cc4e38adc7950e280c17ff4781600a95692a76f0c53456eb697d30a354f738cee78b5ab7ca72f99b8c224e44d3337851143c46907dd7cc6be50f6f3ac6f8d8537ff4bd12618b79881148a9791bfa77fd062d65c3a5e9f806770664a050570ca2858175867731c2e2e49ec3a88015b96498806ad52580dca82a37d34b39fb5401e45aa7f8ceaff25e6cf94b0db972d1c21f601041ab309cb7e757b2d65578b252585bb6c9456f35a89024306cba79886cb05af6cb230f56025d6c31c325bd64ac6cef327e66f6b4bb80aeee82043468914a7b0b5481ae7b954789836e59dab088b54467a85fc042a26d0581a1d6059bab0f5d0050a61ca1ef1c705f4bb9fee243b8452ab7ba022bd6a3838baacd8725e7b37bb09580e371813ab53ce7746c7ae67fe6cd89411d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 04825db8d0ffc522482a8464e01d1da34eb0984cee438850ca8e3b8fa37ccf842aa33ac29ccd52eca6f187be197907e7f84ef4bfccb1af2ca91e7fa3cc6cda0dd3df2efed4c3980d9fb011ed301a2117176d5a94c1d9983fde14e4f2e45f28932df2ef001341e57053462edbf03f4f6133918787ba1d62619eb818655091c7660dd4162a1caa675b125ba8461b137a55296b968d1851c96c455809c1d9151403e2530b18ac186ca769cce801f4cdfd181ce90515dc1cd8c1c66596248099de2ffb8ee5486d7674ef326338dd55b2fec7798e34f57351cfe5258a52a6723c147e9908d05132636795ca6f0bd682a10b100688e4d9f9d619e2e8de507caa684208bf8bf9e3b63d473b51ada0ec4424021181128f55595c2fcde65667e5221bd895eb9560944f7262ec89d9070c19b45393a69502a602d753b97e8fee4f1ba1762c21e87d04d3a86c3368b15043d36906472bbaf160130a31ee3ae005e1711d68e07b176349a50647da3746f42862d1dd394b75f4a4baa3061544477cbdd03a37e34a2c57992cbb022df33f4525ca3589b295967976d8f46c931c047b9912de175f2afffa428ef4e68f2594aa88ba839e9c278b23af1b0d1d7094ceeece58ad15d92524baf693c0aebec574c10d67596dc5d835880cc3c79263e5ea520e6d3dbb32ca894f6b37c07b7077e4f807b1f931fe37324d237be301f92798c1279b73e1f57de6825588f5a1eba171b85cde0e4b137c84967af4f12f26f340f0269868184c4b2e01648f68db166ebb134b67e135d3f510f16c450024968106fc8fdc6d49043a1206f89a8ebb7a59a69d354440ce2f6ee4617df5acd396e3739639094efbfd93ea89c436a776c910dae04317c3c9c9af5b265d8e8fc3934a5527125bbe8b72ea8f9c7ed3e760107b313e4855c799e8013a4f29dd69d7922cb76a5cbc6b2d3a6468d74ef015da8c9c3f3c47da81ed7f1491fbdd67c800aacab404e88df2c7fa383ad3d07a1139881db4e99cad396769148d143be6ec5832fe8574310b9b89644865bb206b1f75704dc883c3913ce8f4a3bb0c24dee01548727957d85e42139c16b5e9dec16df089bc07f7466ca38a421709e4cd86ad111d7ed7a317764d13ef73fa4e65722d955d97e8f37341bc511f9596f2c46c356e5366162ac33dd643011777fee6beb5e8b03ded3948e165db06fa89a1e576d1e52f7785b6fb1133ee82a283766cc81948879815e8fa05cf29c727b8820b39a4ad80ef57e919b71d83657331c8daf6cfb1cf7f883ad31fed93df35abb12ad6781b19c0f4223303d39957798d516d09dc00d8dc52fb60464e55b8db1ba5e23236873c1c4001bcea552f5f633ab42ff3124aa5d62592a9405dc1277e24a9fe610de9f3b2321774ef6b6dbd91f1030561ccd890a99df2a039264c74a3cc5bf97ce8572a4ac1a34745e55f9d31bdebddc04882fb27283d63cea4fbe6e5f5c660a8ab5a535c44c56c39664206e63b11ab9f7127579e9e7bf02ca8e249c2d21639f6e09c5e4b73ea45351d0841f87aca886cf4b171981289096858f59a0796d04d2b0e1dd8721ff246cf53f46b6d6fa2240907440319e0fadded6877a1cd9be7347a2b757a11e0563b6df98bb12c79c6fa60803bed991bae7524f7610e77026d5e75843ec50e684bbabd0b37b1c1e2b1b58c88022bc874e401828d20a013dd67f1e26a27b440b3a85292a65c39ef0ef17d26178fabbcc21a64e4b90daeec7a763402105f42a819fb9096da9a52fc3e918259fecf4aec6f54f167ffb795264ba7ca86e7f9ad67df0f79ba29a83534354a66b7c9c32dd386809e3245b3d7b4d353c3ccce2df45d30a37a9bb5d197d1ef74a31b0e9c9022298ef0fad317ea3990af27d9b2c80c1a123d773aacf759dca2042046014b7e228c963977cbf7ab81cfb7870e9d26049428b2eb88d1e4e1def593f087adc169e46a36869ee73ce1f5b3ce962636a75b1d14d1423fcae3332d2cd6ef6bff1b8cb7221c04b7a27e5dd7adda864826444c94f4247601004091548f8e3fe14db0e3cca9528e76e2db9d5686fdd51442f799e41d7f63f93a17628b65233e9882b82916e02a0f84e5b0592ab1b8719a0aac9428e2eab67c95738c82e4b0a2c1135bbbb9d243acf146b2ee88aa84ac00af15cada505528c1eeb3c7bb23dea16992c489febb1e242a67dbfb454c95b42740baf31df72eba9351e1c1 +expected_shared_secret = 536cdb35f0c8ba05ae954b77f6b04849704359e9e7cdc7ff879f4b70dde3fbd2 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = c06b2d1ac8bfd7d00164a4122e50441742702ae38c2d422f6d956a214375485443b11c3a1d705a03728ba53b9cfdea8c83550ef17b9779220885b993df38bd50d12933d3a4918c92813490aa5792659206569b7514a413db3506c28095ca4840f964312ea8862bdc932bea84fc19749c026d0e3c620de5942006b47083514f141f2fa81713bb95523ba5df235a78f52aca7a8b86256c64933baa18342c1a3de1d3a0697809f6762290b0474e205253bbc80064a8d60ab8844324e20c1b249624bdd5434efcb46f52a1d3881cbf0055c390a91b286bf0dc67a95a4acf40cd858427f805b057d85a5d121a7888626341a7e475a512476d8f15993f58918a22b92c23908bc528dca6c3239794b802335174b2e2246d579b5de3a17d7f1aadfe69906601730f4b6d6717ad98d6371628b062750459fc9cc1640b8a584a92d10d4adc136c8c7bfe76748a91af2d644ba95690a34114ea574495f967f4b951cb487f4369858f79c111e8671a250dc0c053d857b3d02566e2254df7c1be3d1651bdf29d96829a5f41c691f4c1e4d8a5dc5b4fc9dc772e4411c442bbcb767508b7585116232b8b4210bb01f7bb24f54820b29a494a07a4456b785b90b29fb89e265985133828e8819f3c8437449748c7cc7b5c40ad0fe193ed6b1f0b0ba71339adccc7020b9334107c32ef765da84564f8ca0efc213e91219a11c495a44b905acabf18720f8396c4dfaa78a5258e980c6011712188bcbf10d9cec3028bfc85a2be9b7fc879cb86175900a66df3128843c53ce2417be898073b362b98942bd52183fc0b54e5b84570d59cdb6282ceeb3ee9226c5a5806c4646056b4aed3a09dcf4821deaa9e2b7623b0193d2ffc25abcacdbd6a39615102818b9ffb6a6ca89911aaba7f1ab6cc1601bb056061fd4417161b9a1678be6f5558d2870af1d18219a031e685c66cb74ebe7a2f177b59038656ffc56801c839445c61035bc54ef2b2aa451ce494acb9574c8fb4a6e6399f07ecc2ad5054bb23cbad267a9ef4c350a2403c06bbce5bb71f2865d905624fc0c84868a3a7f52cbaf45f9ef27a9a0a3e83da93721464a910b9f0399fa1b856bee051ab84ad33113d7001af17926b70e758f8001a790968178c1b9e679e877591fd177384519da0c94157001bdb6b112a74241a447b4fb31126ac94e993711c4658f20b81a7526a55e9945f53878dd64a09a481023b385de41b763ca371a3cb5c927549b112fd73cbf2012a5b334f446962111907c4b04a0c06ad9c69b85a722be0a33860997ed58312bc0b1958c4a016650eed626661785ca1e8766efc09732a7c3f8044d18564e2dc8ad9c62563a01433d8145b13968835111073cb134a9b0dc80f195ab12732514cba1a66929065e3159c4a6e7d40b182f420ba56aa6d4446eb7bbf49db265cd22c189139b50b2ad4ba1fe8a130e4d9427cfabef8a946a51a5defe3642842365608b0af110116dc3bb1db7b2ab137c6c3a9c04253d60c72e696610dfb62ee841d7d427842b032a254c3647b0812f20175575ec1f1c0ea14824aa687c4c52f6d224c289862e015634a815dadfb1ec495c4cc968ad6e983c829490f1905b55a1d4a08b50d3114ef6cb4c780cab2ea702b8762c89492a29c452ee35e00c366a7e932a916977c7aaec8908219466864f8b0c5f8a3c46c745aa96550a710203055e90916b190872c186efa16172399240e0801b3166810360db1c7788a33be47062aa3310b57c1220b9001491512be0366bcc67ed80640fbfc7fa5199d261a3b9204cc085baf653635c77c80c39a080dd61b3b095c9ea24c8cd270a722bc16ec5011e2b6494b0560f8b126b943b0b56fd0f82be5fb615d724c74002f8aa85aa91cabe3d79e39753252b847843aaefcf56e08a919b7bb7bb5e404770a46e6bcaf4d278924f85a49a496aecb6ef2ab692590877f2710cb642f312231310926eaf8a96b4ac13224439decce0bc614e8050d698b015d318f284109e2103d1e877a4f43bda014291377172c6c8e1bd7c80aebb3ec3578cde5ac745335b6408d7cb5150e26bf95641441dc06d9454ce9e75bd6eb19b4a49c0b70adec9695c6a5366e69146aea0a6f27c53f19c4c718cd21d1601a8a1bd2c26f9b5aa984abc34c4bc9b0e212e1b84b2e41547883378681045145b341cd0933ae000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 8d6c45548a028fe38093d0ed1c1f89f921d823750a65a0f4b55eec20b6144a6632427f53b6a56e7419f89286e0b958d63d1b5ddc633edc0b08414794b6e80265b426bda64347c7e6e8071a7076823bcbc9c96ed247d85386dea5de7eb551fcc92d86f05c121d16fe669afa879faba422c460c1998d150fd0f2a27b9928b66c022f879f153f604d6372c173afa6e3bcb8b9792db362f0b3ca28c7cc4e128019cdeefaff98cf247f3db5a35b59027124d440fe7c3f523e36e48c343bd10acbb4faf3859e7012469779ecd010c6a94ec63021be2c22290ab1e4bc92dae6dccc71263172172a0c527dd379453e053050b79aba7100854473abeac7c0f7d29fb9f72059e5b64f83cf8a7be5c2524e0d87e7b9b1851851291534bddb128d69cb025416433d006c7ae4e1e9ba95ea63dc614a8677ab1472cd8ca7d9fde895a658e0fd4755dc340e46847265454d16e561ef12af68e4be6db09c58d91221cdaa5a2188fa05258b0089c1d66ac890d8c7b9149ee9e27bf16cf78a323c831c5f3cc063a2aa48f8306bdd296efd061305b1da2a696bd80fe90d2a873bc9384231a6edcfc6a83bbea524eab04af929d6d489ecf5480e67722f5e67ebf463d36a6b26131e9284e40083b90e0fba3db9e347b7470405cb4486ac1ecd87c4ae8893d65dd191466863d4d98226c6790cb8a176b53978e726b5494397d7a7e522ef31cd40e600f4156384a2e605be4be6be73b57aa1120b05700cf7bcfab4aaaa439cb152da52f4129b78c50f5d7994591b37fd444a907981d029298d590f4d7ac3bbde8d852e65d85a0402ef680f348146edcfca9886509e8017354daa6634a4880ddb3db205aa23b7f1934a35464105fe852911c7729fdd5ae11b8ffbd3e329c7781bf9a19e8a25d2f15787178cfa6addb4f6d739d611dac67d64f01647ccea0a02f2f03ab1dbf0e45c95dacca0395b3b2241a2a4ff3d82d8fb02218dce04d2e00ec60208a9835daed88c91b75a94d80a5c10054491d48574766c40d8b2aa96836f9965117310574168eb234ea516df470ec12ae167c4b618162b6b7d751b9e8f7ec84262c8a3d442577456023d2abaf2f8f666c7e7c2b230474597e344fad49eee580f429a65e40abad25eb45b3cd9df1cd42aca2693be05af75241638df4a8b400e2df9342c35f450b359c1b0cfb5190453863d412061361ac6fb7828044e55302bcc6134cfcfe6247034a65e7fb89da7ea05beb35a386950957aafd29c4d60770d6d150a3c97e50ab9e6430bec496b9255aa054383d1858956f86d600ca56f05db5546af09b81a3a9b473d9b8b5d83de010a6c4dd27bdc1e699e998cd2b2412c732d21908441e7e9d43b571da361108518223b1a3e8f7c9f36599e4f933c9208a0716487c89050b473a1d027b31044ebaa81f8e62f4766c3887fe15282e84dfe303ed273f96fc70b6f4402a5d97a59058d016f3f6e9dff119edec4654aeda2cc011cf005ba3d6cb562c23d8ab2aa1cc1bd362ecb80f3e0b2261ef518b77664f58e90747f273fb19386d3602164e1c126b754269a6b5da31f965c36023fb2eb454e6fe0ea83c83c2033b49cf54056119660369a499da230a4a6d528729809dce197ea36b27ae6324197ba3dedd5044069ecc9f5ea8a02ec29089dd9e991fb828b87f3c573a0bd7b9490f5437d18f98526b4fb66ccbf2f58bb8b27441fd5a8b54e23861115bddb1ef115075541d6187aa3083e156a61c4ba69613251e2c0800df9ebdde17ae7643c3d6032680ed73b44711570a8b269649b33360a92206b4c4ec4529287376d3b0596d9dc94a5a25a75596fb3efb449fdae50f3446592d9a0fea2e9c68de91e21a09f85a3889635927414d88a5f413578d2c2e79858ab9a2a75f9606eb8d3a4fb582429bc5527f5e56da5f0e24cb3afab72925b3a9cd2443304dcc1cd96d0c496ccfe6941f870c230bd3831e7d6c25ac1132cae6fd7d874192514e7f812630e0919aa735b5a7f8fb04fade34f1a478b3b2617f0fbb6aaa1392adca2102518b4518e40919ae5f7770be298c467de4663cccf5349ed38056ae429fe00d332447e12237394b8549fd8655b31db77bf72388e58369248e9682fd2b306178bb7bf4aa3bec18da1ec50f5004f6fc8a92f56b4b87ce71e6709a15bf5f1442ec7a0b55c70507d3ff42ce190eecb930a2191fe764ad8c3e1ed2118effa9d8806bb091b8557 +expected_shared_secret = 7fa8518febf294de03c48fd26404aa1736aee3eaf19d5a55311fc4d367d56447 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 4dd98b98b790d85379e8434858571ed2261eda1ac35943b4361abf24b92af0723874601a9dc98a6c872801c54e55981024887f9dca26f6531952055f0ea90ffa859e6c39aafdb8621ba078dcb4884de4bbbb0b96ef167d5332c00cf79f93d30807a44e60e68dcab05e3167315f5b71bd2844017b417af2ce61e2a2d2713b7945cf20a39a0cbc92a07348cfbca566d04fa6983c3e37b2bac33627abaa656c873da54a46399ae61117086b7798259a11315dcf411eb7b4a32f375596485dcac61494978e3ce6626b8194211bb134aa82d3b28997d25637f4a9bcf828f7a17d04bc15eeaa809d582297da9f5afccdad46b71983a5f40763d709c2d7038abbca9dffc530ef293a78a43aa2979f53d3a4ff184d2aac5cfe7ac114d378c7a4a46212a3c56c7443d5b4ed309d7d356e169270196159ab428b6dfc5441004fbc019de1f5aa0aeab64c850d1e9acc000a9628d849bdfc7d8a4b29664b65a66aa4ece6a72ad5136a7ab61f8c85eaf798ad7752b1c5908f931699c35fe2c19a7eac2c73f512e4a368e221381281c6f3688965d55969309ccda49bc38a558b605e38bb593c2bae94cca262b37408fcab7cbc29dd0466b7e7ab4a6013bcc7a3d9b87045f7609285aaaea16ccd1cafefa5a22b33043d47ccc0b0c9a0487691f93f92ec0c9ac47756e3cc91b3331866afcab93966c2a1d1490238c79c61d757e5c383a691b2a241c6c19bbd5c99655c4c632d95b9368688ed9294a4865c602c70b40ab6b1cc6c6b039206bc560c302394e46c428a82979b2288b30bcb813e6c35c35565b67bfc1dc4804ec8462d54709a4ce181d46abfd6554afce4204eaacee5092828321e1d3132d7d0b4f2444136117ba1dc843b440e2b644ce6b5cd1cea7ba6fbb1adbb0a4d9417cccb68add346446172ac0232727a6fba3cb59c38057b2b8be26b56d974483d31019fb33d94449226608adbf1b1571c34f5f920565b4a791b78836aa50687ba6ba49b4e280bf037b6901770db351af99bafa9dc0cab14b406561c101478b4b20d4f765d70f072f1d6676c43a8ee432426f2238d37c11a280adb094458fa6ebd2269da310438503e15b22da42a7a24566881d3cfd41bcefb34cff01328a16a01459259e5406451d831f9430ef7e94d4022714c007de3fc0fd637c16cd14489f178f54aaa72529816f3158c601027dba98093712b54aca5d33954077e3b856e4588432c510342e5c99e90995fe7604524a3d066196dd63e98a3b325d2a8669013c9b10cfed68b24b0973f0c286e59605bc3c0d34094ea667b780288e323b334463dd31c7c64b10f6479430406d04b4756fa685aa30a61bac24ed5451a63ca3299606491644e76c765b8ec2dac478192a685210a4af4397f7646309d17b1c1543346ccb884c28418858a5fc9866dc46f5bec91f2a73c02a1585e620b7f9045ced60827f58123274649048477c70f4b57ab8e8189ee8560ce4b84b2d57eac13270f00cac1e0a11a394ab4fbb0fc8890af29111cb87905c09c3d3170806a80063258a6625a24b230c502460f5c44a6c27457e43412a7671cd24911b23f38013ea1d7771f6b4ce483803778be0e5c447b457900133f4fb882d2b9224f2997a532360e573fa626543e856f6b8760107110cfa28815e71b0b1430f02bb857005193875caf86693c1a0748d3a4d3469be2eca0db34b10f692ec1b12d84453fc067cdbdea8bf59a2b00b083a34a5e3061327263be41ab8012e8283f1b86238a077cd02c79845fb71744a0b2306c29a541d6bf2467a483a03324d87cfd00135f8a9bc3aa97ccd68d0fe98bd7bc260976344cd9af0e6c911f3589a09695064769f5b92ee1165ee7f10031d5811274075ed14069d391b09b3b0fb80280767fd04b47e755a1eb3cc3bc9084db2b79e5b506a4022662909c135083b5a12a59c6328f6ca9856b0befb52e84624af1d81b52068ffb80c58b837134f49990632354799ee166461a916b170a5ea397c319b0a492f566257a3672101038a88be2e4ac5781bb829423ca2429b8238150743dcd43025da8121298b8557c410993828c316265bac2f6c2b0e3340ca5dc4c01045c14731d7525158ca89e35e21121256d08b8ad6c850aaff8ae7b97cb1e8683befab96678b6c0c564b2d41d92d24460d75461c91b42b62112ae783c1d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 182bc48cfb7ef59210e250816725e59be1f4175faec6003c718d88e5d802c96d95e024e9cae147f6cebb2fdf3a98b796a1cddbc680095fe1c4a3ee780b61dff0d5a208532a836a90c919b32e23ba0539fa28ad99c3200469258e444c55237ad4f25651ed888a9ba538c90a94f601d0db2a8e0ca91b655c7abf7a4c5e2578a6de7eeb68dc681dbfd4fb042c6c36dba421a81dfba5c2d8ed9649193905692db183a946dfb819ecfbbd94494c36331b1d65e6468c76b28e35af3b5fc6503b1a7407fef9c493d8f3b86ea00900c5928e857744ecae5d8b486f755b6ef655a1fed4261daf062b62352f88e8f41b4d3a656a5b8ce0b3c7d44ccf4f9e901c9a77b84240e6ac45d941cb2d9305e9e78ae39213e825381e2cab3abde4447b2742677fd271d0e53fb1b6eacb6eebc24cb44444a58488fb8e114f4a771e16e96c350518ac2eef03e1c116034e7a5f82dab805994b791af74c9af4e0e80cb1d543779ed0edd752294652869d83f43a26c9198b375b621d8ddb9897f9b2440505372aac898adcae00762e5d46f189903e1e3d21d5036a3eb74c1a833e377050dba79bc2fe909b1f4df99ee85265ba379b83ea67ee9b7386dab1ea2dbf2918c066fea055b7024f60e9e431619d2282cd207a06fe2d926f96f6d6d92906c71c5a9cd64451abb4e9d4eb4d02cd394740a0b6c3d43befd2c4edfa6539b1f7e165fcdfecb8e0a5e52744b050b5252df3fc3a39badff486164c1b238e315362bbc9de3e34d9e10f44931fcfb45c47d368d922c56695ae3bff0d809b620f28ae16916432f7627c2849ba943556fbac4bab79c8b939c12b78eba9ee62c256d378ee912b124f6f7c56be139b9a5b85f6b98aeec516d1086cbfe06dd54c4bb2910a28206554d312f907c7462f6791f07841d9bc88a96870719dd548197f3b92d22b8789656e41cdf629beab410d8a7a5c65453949256892392d9ea67730007cee5482f6beffbf49dfcbec6f76539474f34d9b803b759780dcea2ff8a307998ecaae255cb0bc464c4fc4a236d3989a82b6e86de2d1b9df441fef56524cba6cf996ccdbe18e7dc433a938fd0017a912c44177341a42cca0e2104094658b1a2822cb0d2bcddcf37770efd18e41c6d3c9eeefd57f7d350104b569cf270681f2656f8c561c901a17c5453ae0a8ee6bc7751d8ce737166d2978ee8f38c9ee07bc785dd59ca6956f850dac891e1ccb25989dd3d347a0194a1d44d8c8fe9418be7e0ee631a80798c2003bb4bd5bc76269fff164ccf95eeea8c0c2867bd5ed4838251768f910f9b58f21478509bec110926cb886ac03f6809de328311c7f66636b46fb04e2b54ba2b09cdd06c0b6ccf1f0d744f699f281e8aa1fbe90ea035924777adbfe3fd28d21935ac911be0c8de9e2393632d07f140ccccb46c4d625821b08f55335a95c2dffef96e1feb13091d257313eaae7d911e5e120f2192c29450e32a101738fb6a73104d9ec0a2f995b7b134f3f748efb82e012d63448bc417f54e3f354ebf584b26e4dbb85c75b28fd9ae25885170ad64113e8d5b47d54767ca184d579edd0b0bb30bfcd5d1e44838df5431235079163075ecbf30ba6d5ccb737e732aa16624abcb42f1c63f91862471c3d8a14697ab74a28b4d1c7a7426732e7d323c2518d82968d7237c76493fd3dd169614a756f7f931f29bdc89055688c142cd71dff82a33f4494e36a64fdfb377613c92d58644c5828997849e19ca5de4dfbfa1ad860644c60d794f0cacd1d8b059d9a126d56b41ac2f03d8c0cbdfe04573481b5d7cff7ce84d757b3544ac5162c600808a331fa671629a6d140c49f4685727f087202a8ca5186d2315d47270cd61ed96ef6eae844194dbd3eae320aee0338beb0d163fb668b22451b3d5a8fb2b4c961a9615a6b1bae6d257bc5baf216022f6d2bce09adf8001c9f8e9c9eaab2d9c5af0e81dab1ca14199646e854bc7b33419490b91c01914705f5b4d094f1b71c8557958f01430040eaf2e06f427135e439f780ce8184e64b339537ec933c8a896716738a0986491771d4d4e6e98d4d33e2633ef2b9dc3c0fd83dbdc48a2c8aa53c70aab81bfb13c0cf11f1d5adc9aee2b1301b6e3a7e644deefc7f1ca260bd26abe04797f7b87f32b792a68db6d7136ab6c4a29207ffbab0aceadf8dafb1c7cd28a484049e91bb900d01a10db39398f6943969f82c82788ee1568ab6adb1c6e2 +expected_shared_secret = cd7069783053ed075b29b8bb8f86ba6e723df5d0a8e813c585874f5b39ca2d0a + +comment = Rho leads to frequent rejection on matrix expansion +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 453578e606159c2c0c8d25857a72912297b678d44e0b328bf0d05a1b096d302c6edf39934ea185d1577207264f0ad6c098f6ae59759ad045726a03c0735080c6b1a7f39ba84c27b41ae555f3e93133620c81674a8d9b29501b8bc19ba9fbd375875843524194858a88a57ba69f719c11b534b5055ac821216d2a54be9771fae1bba5448e39a1c6ab667ea0fa6df038a1843675aa5ab1ea132f797490c3da86b0d58474db11417645e4cc68d0294839513b36db91bf3ab32b2aba77655c407240226bc0baecba66c40dc24469ee617f06f739d7d2249a5802f69285053c74c98cbfc134706e535a34fa03f0a697d3db3e3d2240958ca40ea9545369bed2d44e75592154967b71956d35031b8b425972544b63b8bec1743608c2ae16444eace5395689a02d0999b189065342166984a1799bbc00b7b1cfc33bc210433fe86464093d69b83e095b74d46b8786e71732c6088b4753933b77d40c32570879525b20b2b006febb8d0195a6eac5aa310a38b2fb1506d0bac2857e65ea29a210bdd3ca526d59a259f7cc6ac20c078aaefc8537a69516a8081a0e6313288cca716869ec4a47b7b1afa40a59f9f1b79a2307582a2537330dcaa4167cd848bd51725ef478fe98c6ab616f71a43f24f323f536c6fcf67fbd517ed2d61efa9acc8b9966d25848cb416df944a7f8f900c395884062ce1553518abb314b446a85a0a58f78b8d9a8cb7f027ec87470e9fa05cecc07328a6fd03b8960582e47e97272960802013be71974e83573a0fcce793160949826f376492e3c4bbc376f60ab1362273a918bca4fa64c13c290af3c59e7b0279f410a14d5b1d53c1123dc1e6515619da1405844b5047831e4e0c2c0eb890ed5660d7b98f01019cc98c513ba29ff89101479bec1f37e81f84b23d907728665dbe96f4c2469105c3f3261cc4972b030c58746258eb14494b39381c8c022b4010f6758a0ae85c10776ca67c8225ea9006d8798cc90ceecea408d896ba957291166a189619447ba3940379308fc303900a409b333c9c5cc54a8829a4b36241ca9bf319c2442093c1c22dc111b64e783511c7b38e7481977a56f5baf2ee28e15fc5f46a0a83a26b3edcabbd8602938b2c320f0a384228f1d1c86c0a41c2d238af906c79c5ba65e66a2e76626ff50bf3acbc24b5891e0f4370d764b6c503997b98c9c4656ef1c6ccc89a6794b5913d829e87194088b183bc64eb55c85342a3d12a08c0518a69b4c711348291df114c8da5adac6661197373aebb3ed6b8f9940a127527f43b0857d9c4888082802acb374824791d9c3684c2fa05cc965b9481f1cb1956b4cf3c84fd92083f371835c087371ab840d90b93bb3a0dee11307c66a22c6c18d86a3ffe89434d5322cb17666454482f06d608a8a0f1509562435b10bc3432331891c6c759b4a8517247bd8ae4f950f09638dc5206e39db7528e63d15cbb7484c2f68183dfb234cb393b193e134a470adda3a497d6049b4d712edb380b278b79a065f0bac8ceb654c0607a387a689713a5553755b6121012b614910543bad77c21ad8770cf78ac789c6124369a5766a65e89a8921520febb92fb85e561140a4eaabdaf4809052434ea4a9f5298c3eb4c8a7a98c4c5811b4519402c55102f6973cd13e503ba847874c76754ed8cb92b1ab398661367a3b21f2d0ba969347821cae1f475567700c8a0b911d45b3ee10cccd2544990a6a29d0140685a1de7696abfba58f1577cd84713dd947b9d14d83901c19436dee843021e75951e6474146b355422a80d6a67e4c4ad1fca2d8e607e28032a7d0ba4ef916989a47059922be992381691e0580b5b5192a210acf95285a9f156d14fb3ba7b8090a6946b2345123477e96c373814b26f12b40f0b302cac522f3c07763b82b53d36abf2c74dd29b8edf0c9bb5c749af9ad86542ae6c555930a7a95d31e9bd13ff6971ef6a62cedb4779dd008ff5b165d4b4c4e10ce512932ef890bbd5331f445ac68d045babc39f1f528d73210d0f526fd575af6e80945c92f95448972dab108089931e99958f28ac08567cad714a4c737e8a37629d64deb5c8dd8b313d10a662906bb8e958a60a7427cf2b0c226452463c1cb716bcd9b93d0ca0f3e2a12c5389e38983d11e7534d77525fc6aa32e4a91d552e3cc5049ee74ff2bb98ba8b60c134000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = f47ebf9c54267c3ca90048612dfd843904470288652f4177601e6db651ac45682f0885eca62d9c71a2526068d57bb05d65188f5265c5d8c6ea66eae04070de6be319e67e08ebd76c77261c7d6a684711166b62198a4b7f2cb77f5646af2f0bc24212b2c6155b1181b75d449930b97c7fa700f151e7f679b75692d4da04a47864b307ec54b1288550f4759b25a34df63dd1c8db38b9374c6a9964abd7e143df3083832e0ee46521a715c2f5c7770904715feed7c927eb1e424f5a27984be052d36bde159795e0f5c909c7f7f5fc5f71e4fcd09c1a24e377af273fb9f469c7374e769d49a71ee13faeed93253fd3346e0b695741870b8bfe1046572f9a64bf52dc535a2ef548f932c8cf574e456705bab088768336e5422c6827d18fa0aca54de0b788876c48010249db3e874b448032390f384fb67af94653bd1fcb64655cf467545c2939ad167e37951a39200ac7270c6d7101930c05d417e7407e8003cf428f8e0f4a516fddae3ad998843f73d96d97fa84d37829c0072b75f2ea0c61472a23cf99928511ac3ee0031c61af06b9849541c3e87fd7b11bb1fe7afd49e0a07f01e721dc975ba4440262b96c90f5f4a12fc2e2d0ca6b7969c24a81cbc8d87e3086339959c7af99b690240740709bbc09e41f318c977c5a9431a977decc1cc2808b529d40d8a823f8d2428da165dc21026b73dd9e60f48d1900807ffde3b903b667ed20f71e71790d2de970a13913c69d2dc72041152f44be8c78735ab1c7cc473bd598d7e0a671105e5e26da1492bf0031d7051698d46f36c3b389048bb9147518efb3bd57e85ff5fdb2b606c1504d15eab114fb7c144b35c60d5874b3a6adbe1193f38113fbb78416ad9ea7e896ae57b41881b91e54552e3e7d17891759802e0f49307880eb3dea4657059bb144929d484b6a573ef854b466225a3b7e33f09b4a7bcc04c7ed3bd8efc704812cdf33e450b1a497f99d6c5b7267f0ba5cb250d0e62cfe4d18ee03a11132c222877f3d3dc4a12d89b9bb805bf66629a2c14fde7c7baae60e7634a61e9207dd9ae6ed80da7869ab911e0c8e3ab90e3135de34f548a12ba5a20faec23212ec4014ab1b624f516cf95b1fe42aa33e136a524d8e1955ea964a738bc3d7fb66d92e3926653587f69d421657c1765707ab8e67ec50ba954907d03dd1a5ec5c5a78f044c9393b028417e2919664003a96c7ddf2aa997b5ef1e1f3d9f333380ccad84df867c22eaa6fc2fa3defe362cbd6d068166935c67d6b498c853fec2ec699203f0c1b5ac93d4e1369d8b9776fd86d8de47d8cb813538d613742c6de64e854b9230e427f0a2982d69563bbf7237c9a88b06e67a73baedafd7f7043c9ac7bf3b2d3ff2f9961d62fc0d6a0196ad15b0cbc2f34b1cfcb1b77164a8f8fae684bca6507a1cec731820c920bab97327908736fd552ccfe0f1d075cf15b58970cc41e9f86f28702f4bff59b88f2e478ce69a2f8746673e25cc38971713d018f7b4dde544b05d02921a6ea43ec5992bc3e9b2585cceebfa3adf5503f0d8c2b63de7230221f0e53d61dea4f9e153e3e2db14498a5be638b3177c14d4bd9ae54ddf24aeca14bf1a5a146ee880e181cc8eae9e61e514905fb80f5fa812ffde64918727f2c00541f7ad40d8f2bd2e58b28e1bc21f075eb185af9186a4875f99738a095066f5d2c3b13dceb5935c48b1946d7c45536a122ac99638262eec4cb395cacd6458f6a2970fe400df59d890a3b7dc63cdac7a8f74e4546354c830d45e18f1acc03da15f01dde2bf31669e8d4479921196c826338c18afbb553bf5ef3ad5492dc7e0d4530590a5a09a17629d50dcc941b6a31df1aca559ff490a197e912cd01a4e6385e25513237ae611328b07ffacf6760be6465a00cde8cb8ed630b27cf36cecafe59e9a32c68d28dcb853d346ce4ae872b97abdf85ad6aaf05694eec608cd38799f9106d0f48fea705c0abbf8421418d4a511230c73340461f3a0de4f69b141d00569f61403303542da36953c26def5b2b322e70a101d5fb53aa9b9ff1a940056212e30eac32d3b7cc161ff70e74c0c4a73bf2cc722cfb9c30fd1c90276a8383dd2fc625e1c8d728e16306019ab61066f25ebb9bcbda68322fcbece63328501581e71fc71b7e31e0b57d2c4280100838c439e48d6358c370a9ca5301953d9b4d00e806ee3a4d0fbdbbc0da4ad72833aed64390e03a818bc307 +expected_shared_secret = 19a85075ee44b34ff0b11d12655036af401478f0e66d354ec9d17a6c197a69c3 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = f4c42b57b1625ba25249b9697b09985dcb92d155c4a7db3b2e77464ef901af38b930e0b5fb67cd7a4cad52ab9297b383dbfb7e7cb32bf674b24f92c6f13ba50afb2164173282031b584828f8fc835a094bb4631193258f8bb1aea8949a7cb4abd1279ae3373ac36108eb290b1bbb205bf81f907873de0466179787394a48c72bc100192d8a0a46f76aa35a2c4ba8430ff976caa5d2888b7bc054bc07ec8a0374a5276dc01c34918b37795369b66493ac0e3c1362a4f3217d240ad438b7472172474a377b715eb0702e3b1652c3e35873904ee3b139896245c0a05133e873b5183d5ce54b758075478874cbcb00aec3a5f82c03f6ca9783ba3f7a6a1c05a41b0fd30f24f8c47309950282b7aa9ca84dfa20c8a9c5b9b3665ea59b2bf035159a20eab110a862c4112cb697c923311387b99a15066c569c300772eb44eed03e25903e88a84cc5f3b6b982086563a36f21b3f9c434f3200b0b9b5852a2aa75eb54426049c264b73891a28d9412b9c3bc5b87cdfa6b07242a4c1aba32b229b374071d4aa33580b52dc09093d9c40d95801246561cc70136c389ae1667bb0ff600fb82321c509121694c4298c67b36a21264201ea1c97aaa757e5c975195067416964a3a250151337bd489a4e943c03bce82a7b447b134f25940b345166c5b498b6431c159c829434067562f7a331b051854b32b7000c42a122974beccb36016459c61a97517c80c763964c64f6f72cfe69bb2c87c63bf610dce640702e99affc20d1ce934cf1c70683090367673c7422e57389394e7c2aecc13b23733076c6a50631c69106792492a6dfcbc7963998d219f5be767b180568b76658573410ed41796a9affdbcb5a9991ae48572f1d2a78da29a6eb85cbc50329e24c56b41a4b9b313a85abdab851886fb45f643b6774c7792b89dabca1d54b1c728b38dbba6887b028d51715e131cac8ca22eded549b54c39733309efdc2b5a5b3e45968afd13392c29a519328c57e259e7aab48d730175d61479b044fa019cf86681ffb7a43770c7b3e22efe3aa45c61246c368e920b8183b7446475c32f739ae4774c4430c5265a3aae3104629c31218c7b424c3ca25a4e9bc8cb5067a38ea4cd6f704c5cf895bb676489e8995d15954422495e82caf1484fa64264173c5bbe8138b6132cf45b8f6c1b2a99d42fadf494f90730ca9286fc9aab08f3b006622a9837149f30275bcca354136d876a728634c6ccf48be4034bb937bce815b291d9236da83700b494082900d435151ca37258d39c816704f8bc1373aa2f6f1a916e21c983fc590473072ea0039630b016b963fb8bc95f21959538854e9c5fad4212d80ab30eca4661d1aa6184a8d7a872ca6682a85773c6ea9006a64ba1b44205facee36c93b962cd01d700ac7a088c7c43fcf8bd07d413a0022fb43883f9351ac675508cd89c50f06eeda01830c42a864515fc88c9693026e785ba2a163dbc819541a61d98a64e95e62937795290440769c1049592499ea0726c18b943040fc9d533ed38655d05264cb0531d23bec531c6726c9dcc132e34704752ba240b4c4ee506bc15150932c9038e164aa22925152c52cd59ad3c68bf6ac9789c01b7a87b8a5314354f36038a3b2bde93cb73b596f830bf84f024458641504cc450d510791c43b9db3ce60127f081c8d7f61840eb75522590ef57391c3a4189771ac293770aeac4ea031707d6c38a2334d44817db05cfa54aaa5540c3334291145970903160f85cb814905b493bb995ab3ac79bb62e3cbda3d4a0cd388517547cb3b5a6c2ba9ca5646473dba10104a2bac7b4a8f79cede97d48a94d0080ad5782819d8c4b19f8860b711285ab3082784420863487863e182a09d30c8dd8198a8876829f1c336e583d27e4a06b091c4627022da33f06a201cdf43120e1a6b396bf26324d32c73cdf531488650b3b899c1ada8bccaac08c3c6617649233501839628e53c1ac7ae51ec19b1468039ae88140feacc9027c5f9370985a0932422c0b24b849be7a9bc497cbd3d317f48c50009a676161901494a52045afe3b6c516b18d31aabcfb27b2024505f758c91f441b8139889bc6ae3440208f34508df8a25bb4b3fed3929da0572a5a804b086ceb74020894b534bccbdf485fa769aac8e9577e477caed5b029c86b4682a7e74cba8c930ff80d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6d12517b654513bfc072c7567a03257db9f6b093bb84737dd5cb2861952e1936bc84892a5b7c5f70c5349b4af1ab9e8b65a2107232f26100b4ed9fa413bf04bd9cf7598763fa3c40b7a2b2593a4bd51167a64d6228dc5bd20d0cd431cdccba3dd5b97a56b12b422f666fb817c1a5fdf9d1fdf8d69640826aa94ad87bccaf8bbe4f1772efa2604d14006b45836addb7f2935697c445b4fa69452e74290115a623e8758803000e0f4261ec8d3a68f4e82df31c8da1a59d74aa956a4227ef6b59b430345e4aabd96fb0c336b9be15ec550cd964bc15f2de060b2144648d71e7ceec4881bffab6540591f3837f935b4ab48c3241c95edbe3b7be6de17f62b6a141048b6663d6316ed3c1e8320f3ec5b818eb890985225a33eecae76a813f08b9deed452d34546b8f806f8ea57e6315ed7e305c420d037c2fd2359022a92dd3b0645e00551207f578158f2d853f41f09680fb226b08344af892ae470b1f281b58b2129b302f2da1b8292bc851b0f274365ac410ee178594fca317d55df1a63491b92d8d1c5be3b2814c40ce082702b9f6a6e6eb9807325aac5ad656523e69732feed01e4a085372b72c604a201730f785059709a6be4589f8e523d254abf8004bdb615d6b45dae3e7609b94be0878532e1dc124e92b24b677276c66d62fa6f097a3a3ba029c56cd7b3af092abc02ae18ace1109e47beaf478a84f34ac8bec69e67f71e9e8713b2e04460de25503c8355f26bbd9a84e8f136c15e93d17c8da50e0ef1f529283a574f81de5ec885b3e114f4b26a5ce46c6d94540981c8e8c38fa5d6a2dc1a78d4655a255a915903e88bee5f30bbe9e730d9d47084500cfc4a5cf5979696508cbb3a20ad11870b0871ba7c579846e67c5d504edb07bb742f58684c7af5b247c5b1459fcf04fbd3f1b2f7caf32a73325244d1febc8bb93488e73679e1171208597d50bff5f2a0b1b0e38004f93facc8daef9865d35a779ed93f4e9e65413733b01e2c4aa7f649ad4774a92422b47b1610fc003fb25b62ccae811e8bdd91fbc65c1b2505a8226ee96e275ac3de93bf8539ab14ebb5f3eaa536a96ef7042a4158af84c80e7b5f161172ad08438fe518d32411c9e9fb2213515617f418477ea1b69d767ebfbbd99fc7ff164da7a43f0f1804f7e928531283445ea517a9e1e715bda558807d2df4a636dc5a0cc59353a33b4179a0c431802b11f676d46fb3a7700b08558c409ae96af58ada7af081d42d6d0db42371baf3d12078f61b88bd09cb9e37f51e512d8ed1f44eed6113600f705f7514f5d14a91b1089d7b441ff4166f728ebd4072bc77530bb85ae0c6b0233d47f9d474466d7b5d852c20f6c5ff936efb6842fd94a4618ed11086ad6ca4dbf9bd6eabff8c230421c486a3c68b440f2e9a28c580cd438ab8da399f8ec2e7e0a38aa95ba39acc9ca8bc928479779c0165cbcbe292690015ae10db2edb418fbb148925eab905a3093bef13fefdb1774bdcfa7b907caa321a5b9fd149240a0ceff340ad906fe103f6bb111eaa53761cdd971dd61d463ae503e96df8c457e71065a86ea58fc345d73646f5c9261701a7264f119c29faa19322af0097a3f889cd40f0eb7884c2b2716342634a640f6c6388a68822cf38d93f159f67048baa8cfbcf5ab5f8b45d8786206a7ba497fc935d2be5644fe5d90e551fae7ae2bc0f237dd03352f511f61bf873b33d4974e1936260536ca88e0dfed5bb80700b3300f781439530b4569084297e38deb96976b66922a11fe56e5a14a5bb01654f485e1f87bd204433dd15871e7b9f4ebce48775e117f29cdab877d65d601c2657b407c26b33778491ebe4944056efc8bf547fa7bf534b56c363d4a165210feea4888078320636e50b08c46168953db0caec119f38188666dff40c056b1f70b4cd956ee8db8309c406563ac9d4353b36f51ebd760670250c556d9f0f2556aa153c0b8416b26fd723429ab0357e32725b2ef106b3bda98afba709692ba91a2ae2708d9d67a79cf615f8304cb4301e8120ea00f1372e429d873b0c7161beadf87fc12f06269784aecc7f6545345753a5a55799269c9276125633252501f0d313ca9f8e06e4e2777e6ef21e78efc716992ecd979fd3ba00b4c3115b194f3b84f515fbb0b4f31b279f3e776273715c05aa9adbed7e12b6f2522a397cc6acc96b25dc115835ee824a22a21319fdc4514f87b4c5d48bc7e83c2 +expected_shared_secret = feaca519e19182ed57d07e8661103ba82976d8a079ae871951bc678c73a81379 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 6f87a12c4aa441f688b2c0cd16a89e315b3553a16179db0e01d01e19bc1574c75a13987b2600ba2ca68cba5c1d0ea69ac5fcae7862ab218b1a94b22030b40f0b3b16bee7c6d6e58700e150d7217bd7721afa7702023786f365a43a60226068c5ef3323c8f85488e77c106a243e96ba538264749539f5874d55929b72a695ebc3366589b04880721180258eaa095a950ea13319c0302245d86219b79a1dc61caa658fff790f99d2c3f25c11eb34aef2e66234e2116274ce54e5ae335260fe3ca3e0673128d064a39c82a3a9ce3be0a2c501aaa53175478b847f9cb17ceba19e120144534dc1a9b38afc864913a8dad5a7ba6bc9ada898c60b63deac87092275685820131001911b98af683248b50f1e2650bd299c9628678ae542e3e7a526620d1f78aaff445ba75b47d0ea0af4a3a3e7447851377f40c248053a88f5706dc119712a5001b8f035436c7d9eb1269b845156e60c5a714026cb330eda7f4ff1980fca10f5b87666d5600f468b11d81140b27498a10715147167fba6c8c58680824b21e97bc982b61aa43f2dc4866641b9bf6200e7a8afc3c1b3c70226e2a320c603797330c952050c90508a4b36580fb5c83e7c9be912891e7849db960f83b134543a3ea1c40d7f0029118a855a926f8b6a2777172ad5452fd0a38753a94bf3f6023fd631c3e9a49be1194df4c7fee149698a2cd7b54c5fb33b306ca72b6b7b4280cc5db4c452bb8abe365a3d16c5c02122be27bff2f1623294bb6217c201714e9868b991229df1569d7dbc9ad957379bd58a41c990fde349d50a3a2102637b18be9f4b10cfec0fd3fa2cf4868bac98a268891d9bb208f489c1163a16c4d68a13156ff31a0129839a6ba4436ff735ad69161d551cd0933a25728360a7668f166516a69ace60b8283878cb22394fe8beaf153632999d60554725c041f5b089dc205d4a3759a7044caa82c78bf50d63fb3d72172622f71c31fa66460882a603d02b798470b24409b019a6f4b85f571c5122b872997aa4c389fea1195ac349014660e619888a50142ebb173f95011a716f1b031a7b860d1986a3c43a65bf5654dc8376d2dbc8d25ab90d139a18167fb73b758331ca69274a2d340e59bb6091975407b4039bfa9e2a4480ddfbbc8b26c0d1457f39a38f1b8626186c469b48007fe0cd2472a3b4369d425518988741507912bdb12901fc19c49932cb1b1558862291a63ad878cb6afc2dd57a1593e80e720a0766a031cea2528daa3fa866543fb5a2ed8a1c111593db955c36143ea38a43d73024de9446ca2c69923ba88d2c5b4444cdd94a3c380156dbb0346a02271237cc488c89d050035db74022c7c924921abfd86f71646221ea2c61b123224a1b34fc5f02c6849678313fd86a7da11f3ee681ae5560ad42cb3a86bfaae100478b0677d23dacdc9005b17af54515863159f6072937ac882212cdb3e82f3f811737b81928b605a6142a9195211fb73142c96e2cd309b22a8191166e33d39dc5a26148179521a4ce69d4c55988966ee2b278bc2564c62007e75da8b1ae169595a9dc58dbf47da2e0c192a915a59765abc62e375588d8ea3b72850bd0c584614305218c729628a663399dcbca2d30fcbb6e99921f5c22d1e06f6dd99442a27c1342afdd2705041acf8df78bc4e835d8e400cb6419c52148f676354421c5e7268c84501fe82b851bd87bae738ef5c67032c746356010ac03caec13b212060890a38ebd28285c990021a76cf3a417d538167b782b65a56cefcc2ec6015ddfa7ad8f2876a9b3bc0d9649827abc33d7ab21d5b20e4a84577311ac7b381741c8238955e630795c7a3072d23dccf4ac689a781fd783fea7592d0a629449b44142b56f440ed00b19bbb976234439da01238640890353b8e14b7a0d964819101110da435c9b68e73b033c78b1efeb9d44e27acb225fa1e07bb56299d54a779cd5379b7c02fad52f3c1a2cefea9636d850c6e05ddc14b4bea669505a94fff87acb2ba0321541b2d78d2c58abe48b62d4d828c8ac0f881baadec1bb30d347772729a73390bdb85f0e1c9b93123f7e44a541740c5d0598015c1433c96eaf97b5e0d39c27e60b9ba6cbcf8a2dbbab8259e44d006da65869c75b711939cb38a3ea83dd3c8ae97b4e272a07403c40d127956e969f8ff3bedeeb23c406a20e73a2d589000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 16160deb06f8324dca1eb3093b3fc501dad316edb4d5f8b2ec591eff7b65a048b3333532ebd3d961e363157ebbcac231aead8e255abb462fba12955310c6c925b530ad2f4a761d2efa5a3b9a8aaf1929d3630a6244e9ee1ff5839198fc9b4ef47e450d4026b5044120c13eeba48e8fd9fcbb02523814c44874ad950a83bfc21b1ec778c1d5b5efa0f2a9e028b13622fc0c2c08d7acfdc45788e0805aaff92b51532139416982f0fc9931f3fb12ebcda2f72bd9048621208a4a91d42b56f7d810e89bf6e4e7d5171c82f09402d2906b692bdae3088df4b686b9c1925143e07212e13f4a3732f84bdde9074ebf3a549f0d90aa152671d88d88af39364d33e8e14cd0c71e979c045002c3c40f897bbff857f1dd82141c719ac5cdcbc944f6d38978e8f39ab0ea2dd9e8d19e6cc95e0bfab01f8bb1f8330e6241c3a937c70c40280cff3bb6a34b5b247fa970e50361447bc5b163143091f766387d15033cbaf8b9cd208a2548f42f00dee7ab81838ec03aff5d4ac446a55100934866163e3f53931e1f4b86ddc021f39f2305f59c95d336bd070d089526af38416e61cc73f94baefadc73794da7a7c9eb06b1cacef4b37626ef7d1dd381952ef67d8a2959021ca85f4f904f912187294acce58fe364f57e113e1bb4cbfd2913095ba6039677046645cf84e4069bf5f4c0996539eb1d036cd4c8f8e1c2c8e0d775f11d0eab393d9474220186fc3459db73bb864716418cbb90f55abbf9ac57096f566702bdfc668314d98ba91677bf74d91547c7b5302c725b890b4f3f2a8b95f65521a9199a4bb429b31e7537733dee03f7f2f135dfe88e38d1c301ed65a3d5788dd593531c639eecd3b947dc557253b993321d76a61ad4ea37ef2bc43b5d410c7837aa3b706a28051d3c1ade2216cfcd719ceb9ea9aab4d373d535a13da4c9c27c5612b38badaf16ae3a584cb7c057f1c2f4a24a477cfa4a1d834b3ea4f9254ac3f89223bb1c8b9eb514460028ac47b0b38d0b4dec9aa4c2b4ab16e66780ae8589860006ad4ab72bd42cbe4275942f8476928046134b89922b39e3e527dc48f7f5433620dae3ac140747053789149cc1434053923ace9f5205dd3d1d7057dff6b316535fdf508bb91b4eec6503db29bebfef73302300822fc4ec4e39f5a5813bed54837468c739e43a421b2d6478f12ea5a5f37e26bbfdd57ccb11900bbc3054687edfe96f88b59af5856e87e90e594b5555c03add6fdc0b62ff3c48577b3a9ac720a3bba2d10958d79651c3d5e7db9bd701e072a25799197e615f4f4258b7c0cc7982b8ea89033304a0c2c23eaa24d26b56f84d82b139f990698906209ef8df440144941b435c891f6a2ea0276df6f9e9fd36ba636284574d49eae6c09e82e4c0a147bbdb2a636392bb1671862f8c8ffc0929e4f59da3dc02d7461777ba48acbd062c933e1a61857124bed102865fb4a8bcda191894ce19953aa6f922a351702c570cca0e6d95cc4757ca61fc76507b82481ab538f418ad6b225abafb0fb824d0b8f1baa9597e5e095d5deb5a70d7390e1ec308e2e3a15a62ce03a73ee6a827e50d68b173a7e1ca2133c26f2a0b922b06c72383410b75c8911203a7c00a2920ea891c0940d33939e0d5098b42cc31d6bb6c0dd8c03e8aa2465aa01597ceb533acb3059763273ec053c5fe1b72f9db066a1a5fe216004b1d8577849b6d5cac89101ec453bbfd8d571fc08087d0353c0413b02fb8956522fa871db4f4d734e0677339cac50199d070d8f592b66503be23ff44104d5e02ea81f17234cdf33db122b5f5540432610b4700ddc6183d4528288d692f119bfaa81a33e89ecef970b514355bfb0f4bee9800c8227217db2514ba6396106bf603296b17b3b5e9c6512694de41c99c1959398800fd9f0c0cd0975a2df0c477b45d2f433fa28ff3c7bcc6c543428490e9c2f6169edf583775595f265f969dc11d5f1679a8cdda1738e64e2d250dc8b769b08742002f22106d7f752cdfb1af97e4236cf11589f82816b065ca8d1b159f49c9ea06a7b5153cffc0d703a94ed67dd58859311b72b4f032ab50d4b10556ab415c8a6b2bdffe62deb01c654af6f8c1f29a4b91d9cb1c6663485965c0acad445cade15282833c0ba20e821fc443945eb783d4d22b0283522e59ac6b8fce4b00f5a7837bb7943417288442c286f2c869f99cf41c9b91e70307d2424b4b831f0cb78729c7 +expected_shared_secret = a2b9e1dc08b711d8744a6533f3c9ad42097526e8e7bdd375b95ada3e20af11d9 + +comment = Rho leads to matrix containing zeroes +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = a1626b61157361758af813446a455edf8346004c8f1d8882c6833b7d6bcbd86abe3e448006f0598a288c813790256b0c5f0332e06ba2f7f61fa405752f509550f86a18bb5483800a7329486f310228e9b467353957291eefc5ba630715ca177ec73602b1cbaa4956b37f1c6cc8714702b882686bbb8d1a19bffabf06068f72563437d37b33b38c476366404a4a6d17232e437c7bd4b56656b80eb7180e29613dbb4dc4b45f9d6909b07bc479126a4ed1b60d276962c060f725406a6641a29c7b87d17e29209c5473a595f93f6f0b6c4473afe95b2d0cf13710b12e4cc094f71b8f6c3cada16370fa4037cf721d56f1c5efdbaf1c395fa77175abe6c9fdf3a1a0b88f608580c1024dc319cea9836cb3f70e0d7101117a3d8e8841a92990d30cae17b676287795dd9c0a451450b7b75017881a210175af8a6ed69900070192df3195d27756c303bc82bb93a19bb805820177a07c75c5c1c04a8e61566ae62a357d6016e313181a260d678cb646a3cac063caac952ad4830deaa1b2bc4161b7c23c31356442e2c851ba64f1e99abdaa55b3b9a2fab0c172a3b9b26918c0f6933ab74fafc700255a59f3871628d291ff56b8f9241587f5a8681aae851b73b0a26363f2263035a271e883c5fc8bcc653c910924c202b103b4131325273e6246579939dfca8c6e78bc47e686841b629c93cd7dd16339d5b40cd8b34a289de9394c40d63409cc97b87860ce54c647929d2fc84850443a42a74a5dd67cd14b715c7535b28b01dbb3c0c3793b438b6e56f60347bc4220e695459c402c94aca43b9382a47091b0569601ccd7a74b75b868b035a39b9617a10953e468558d5850acc0a7d83532c9a6c5929ca3c9bb8fa16775457c2d9b320dda73bea9d2047a0c8f62f78f5e52ad9188a851860d1015c15f89395cd86822faae4fd2354610a608b36607247956e68bd4c252d7d68a4d58c3107465748a31de880be3230ac6714a33b4c62dbc711f5c0af44a36e6ec7ae6eab7ab954dc1f420a569b53966141df1566c73290a530d4174c198e5c5f427838f1884a2108c85688a16436270002207d58e75412de7255a1544c7d8b43f60bb2b93f45bacd80f2900cb324ac271c98a95f3917008ac3940853c13a516140fdd0064f646aad67b5bf1b966b68a6c795b2f6742a9d68228f86a60cc210aba894ed84859d990c10cba5671161caeb59c497c1b2ac52df6913a819168f8b8343654120a459ce5846a6fa777e82702fc8987368c05a503b57ef7304f862c55b9848a461af1e4383537154da27866a8ca4ab4af01ea4c30dcc59ecc0c9215a141996ecfe34aea6542b3b8c917c98ef574b1ed006977fc7b755b87c6eab128f6bd4b089359aa74eef351302335561303d26c24fb327319b8974c165e77277db30035c84a36534495ca260f7f76bd96396dfca983c89a8b99735486a78d34c9580b691108f63846183659854fe8f1168cfb9d1f5a05ac8106743bb74c1b72cbfc0e8ef6be184751fa449795bb1d0b7ca37dfa8f3979bbbc09a13d4c47163a69b04cc013795d41b0033549c3d84b00c01b1a9d7104a9d37751d08cf0e8132eea86b2462f37d660df4a3a095910b5ca2ca0da78163bb79a181e76dc619283b6cc670ccf2b1f3862c57e69c2b5cc293b87578b190710533bd4fba426f3389848919619c5b41cc5244a368adc40ea2647e4413dc9114e22749684923fddf2192036b83cb870eefb9afaac2961e3869ff0554077caf6d1aea720ccc59734c0a5465b7768170b323ab8c65a2a82f1267db4555565833d9f19ca10400d513bacb055c956c622cd7c0e5c54b33073be531c6586802cc11b75e8b0542f80b99639021d89caea41644029a81084129ffa66a66238c65c0f5562bd74b861293549a1c7cb70b6b3ce25286558a43f318d24052a196639c8b247bae6c59cd27d0768492b6b6ddd2011134cb9d9964ead020fe8da84a1f910aae304a9c3756112331e62ad8650544b5111a0977325c6c9ba242271ecb0c1a3c753543413685e46a31312c68bf9175a8b110a6816b6aec9562b8322b0d932f9692b1f29c6e3424d45686272f00f22db854fb8157594ca7c7b018b01c1f1a23028a4663c6b258af445f83c97f652954d619d7c68bf5e10046e7079f44b05b9c74591988f328443c1df349052000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1b5fa7222ee14e61e4532b01189d576a2f0c0019705a424c3a68c27da592c2ad20802204e58a40e5c4b88b34410e000dedfeb719c7541cea51bd176de9fce964a96006c7ac87219b0114d171d89a261a2c08220ebe532c48ce9db09c791824b7373e1237e82a6ed491d71dc997baed4622b5d4e87e5124267a3b87cdef166d6d1109e2258f5deca3390e750f92bec1795f84f33ed51e071cec46baf3704afbd37be4603bb4fae6795589228be43598b1b055cd696377481e6e4c5b0e9ca39358312a27fc1526814d2acfa9f4a2a4820294dbd422715ad3957cc3b30cbf97a4453d9d6e2b340b8a6822963b19b5213cd9707420cbe5183ebf969d9a1d7c02ad9b02e7c0f8e15903891a506ac9182b424e4025c56b8f8adddece1c62a9593c1a1b83e01239f3582b3e97fb55a639b29bd7501c7008801dfb67716540cd9fe51ab5340f6277a57eba60f3fa755b141eca72b5cd33d1f51f32c32f15459a60dcc0cde1ec97cd3574a70fb835a8080ae180b76c6894c01dbc81429ab00fe1840b4ff75887efa840fc89f3baa828bf860c6c394577edd9490f14d9bb25adf5fe7c81f2e1d5ba110e3271ebef0d42a158aa51afe9343036d86273dfcc01a414d2c89a05576545466c1d2e5f238ad901d2b1d042476c71f8a3889202b25a8b73bab3209d168812f2d495849ba309ad8a51195c32a8f9bb35287a2c2d3d75976748d3660db6c398d88fd84693c83312823f886d839dfc7e56d93ccef2c8b8b64045347870489c3a7e95383429dc78978038649742755304daf1289c74eafe56675cf8d7aba5b737c4d8476748d31b2c02fb8851bf719fc36bc45a42dec0a36c0d9b0cc12a8baad50b539ee36db0052942c1a59081f0463a57792e954f609bc14316f674877eca906f3bbd25607a4c076c9fd0e85eec2a02a767478745c563fce06833144074de383ef1c50d1a135d51fbc499267b2f224fddb0c8d392fea01764e38eddf6ead2ae01f30cce05fd7d62543e3dcce21c76524c52afb252eac36e10d8f9aeb3ddd450fe18bce8034e154d4b0c5d5639bf745e2c8e5435c9ba7db121a780be2df8ca2fc98d41348f2830fc5e182e5c88dff7c88429762b0459ca7977d977b14cce7c84ba39c8cd012a3b15f4695338cb3d6ed991ebd20c853328bd81e037f75e82d85695d56e10973c88b33c88d70b321818e62ed15f697c3eb949d1d70e91fb8cfc3cfaba12dd57beb2ec6a2ee80cff28e54ca18e1686b2674156bbe57a9a8a1152b3298c56174550818fff9beea0c2d6ce74785a0cac87c7ce8a11c0a8eebb5070ad79332e15961bf2413a793beb17ddcf0cf805de33ba04b48ec1e3abc05b7c81aa3277f39d40a1509232be61fa8dd5428300d60efa05329162b46fe3f6973ea3adfc6c11440240099a3d65dbc1fb0996fb75677bca40dc764caeba053106f74f2222482ef6f7617ab0ea0f97bcabfcaa8442657419eba2970aa5031245760b0047ddb8868997edb5a5b443277d00f8af3ef9b024ec3e0ef2ec199685d44ab4e06cddbe4dfabbf336488fb82f64edb55d8f7e52f9b21b2f984507170bd4b8881566ce5308401b6a06e06f2217f1160f5550555527b71774b47e619a83d2c129beb5601ab34810fbd16f7cbe6597de399e4bdac009c6d5e891b4e1b776ad16192437ee0b3d98f528a6e65d17797debdf367a202a9cd017332f6e36c4a6a83481bb859ca6613e0d2b34dfbbae2c583e4936dac99f45956b966452a9c68bf1dc3a326d6d38a6a6da2b6975fbecbde9cde0cd6af3e1cc8a0efc7cfab8d4ec0b74288bc319df5c4754c77c5071a68056f9019aa1d51d6ed28a99d7fe9125d04df0d7839810f2d6f129ca61d117169b0f272af6eaf080924c42c52acd3f28abad80c8bf0d2fdb79ec2e22c6967c044432f381eef520d0f99916fcaa184c81e820d894f9c668261d78daa3a62d11f6a82a2a803166b98cb4568f4cf8845fa78322fd07b0692790a80889e0f54c042b61737aa721b62c8b1f1cb5f01b6d41861b1c614d2f42ab82fd0c878f2212271429383de3496757158b50c451542751ecc49b7b7d3bdf697d66b042e47c33cdcb9a084c275fba27a94c349565532da680efd1caf40a4dda1014279d4b6a530206bd90bea3c14c1039b570e351b13da4a1af2612fe67c3ea4ce4c623fc4026005384addb19be959dcc24857de3af02d5652f9770 +expected_shared_secret = decadad640367b73f7c6a9e5d1f9e6dd576350f841e9d8eabd8d525fa8b0e1d6 + +comment = Rho leads to matrix containing zeroes +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = b69847be058806d916fa0a458891821a0099f3618274091336ea37fca742ffa5bf85a845bc772ec2abc4c9b05aa7e51e8291aeef2a05cc185aa2f438d56026fa0ab0a0e8ce682294bb41238d358dcc1016bcb97ea4e01918a516cfd658ae753f4e7756f08b247edb899ac8b2b11862cbf92a5966b68e4cc6fdf66f0f14a135753ae0f5472a3614a46715fdc7cf69bb465c66ca82e65bd263c5bbbcada701844104ca821a6b5a914301948bc20987229c81d2128754122c1cd3c43e2b4b6aa880d0c203cd9490b7796c02109c2875ae7bd284dec49ecd22949539a2f7c792d351bff0c26f8721a86e1948e08a0fcb2135ff7ba42e352ad3c3a4d1930a26034ee75b355cb299f2dc375f7462f3801c1a636a87d71fd0e528191c8b1d6c4a1aca21edb82825056f8623975c54b1aab806ec623ee50c3c9f954b29212662b7530793c4e3308fb5610429519ab35906834923b053b595f19d6be33c5ba4624dc72fc5488a98e0c7cc9835a161ba97e72bd08485b2c59fe2e56cf1c5a091f389f555c7049c9a74b57af3b1af1263c7720880e5d9c3270b338488279a27c9acc04409d612aa8b195dc5c15bca57a4d24d8d10ce661509054a23c0a0b7839c7ca0f77b0524721b06a8f92570aa62091de06d06783562ec9a0a795100c28fdaa06928dc6a9fd106ff05c2c4d4c3d193898661a4a39583eaa9b62cc282c04c872e145b42058de4467e3f22cdf293723299565d452219c3740bb65bab60387a3321bb2b5ebe585e85e4a2a5882c72919caadc9b46495d100081c88964c87521ac22127e891e1b9709954326b45cb35f5778420b08773b926bb79173130d43aa2c586689effb567fd165334b82ae4c6c98f93b64d99a44815877f5476583ce363196d0257ea472a9bd630f2fa64585b9ccfa1a2012822f6a004cd5959d5793adfdbbc5596887b5088bfc5c5af9aa35e5b9205686069c55aa7437026e75ac370bbd40421df7c21350da1a5b13b651159db592bde2078e2d8cc374d6833cc91bdfcc1f19d9676e060f2baca39cda1dee758ccd096545e21fe2cc082c00374d593968fa8eebdc309698020a29910f3910a1679129791c02f94cdd8aafc8c007c96411835280e148c4109743c8d168ea645ade7c23b5bc26d4bb083d0a4833f87e6d5b218dd73b76810216f9658a9547dad241d408bdca43cf792bc2a6438df858ba77d01c34c54ee9a31c83e472d5f945fa504f054443851a9c0d59734f175795a86ee2847d7981654d89633f47a420b5bf65920b9810c5512a4d8e19aebbcb13ed0a87980891799650a88b8dd4eb7985506a581110439a0f5afc8e998a7477e8c4b54872b9479b36f2378a4cc97b3208be2457326988e4a13b02812616d5add646cf0f5a8f5458b8960839f93581db651ccc5238df417b4ec6a445127e29e44563a7b49eb403c10a6edb624395c58738762009a073d1949149ac8e69e8014478a6701cbe140411d2f1b95376afac6988737a1b9278a2ee5b7fa4c1cd89b69f56f2686bbb59a54c676eb357a0602e8f8a8a914c745703bb7542c313461d1075beda6cb685832fea735d0c573fe744c16bb52b8e7a7c8d049ae34891ef0ba338614f300033969403ab4677f2179c8224bb2031b8e891a8d0806819abce1356cb2c906fa2a17d4f3c4ed0b8cca831376f67487847475a5b27206a18dec19d29f6a8d49737e7b14f2034209b0497474a3b0e94b6ba190d2793c945cb7866b3959f7b2721537b77a45ba6a259c0153889141a1f9171e4503a503802b4e856f90433063b37ff00b4fc3347b99539efe3cf29b515dd7b700b37871d926f699499d6699831e18cafc00619b35e58555a40034c22bb430fa23854c81ebe12823b92c0bb05b2eef1cef35a75ba6564db9122ec125952260149cbb8e524391aa92b82d13de624c0368a9df175c5ba9b99703b5bd1b918eacb53d78c86b362729a01c2ce905c4d5120e690911255be11b39dae9b8a9b60191790b59ac5421473237508ab327811ebe955e8acb15ae72019426573e314cd775f4041658e85b3261c3f04c32d04e58b3393a81c7b4f6b2542b2e27b042027f9a0b40947a919fc80e87a8182508d2b4264fdc9ce9786ae8ad3cb041274b9fcc575291d74c3b95afc31acc280297841fd5549083120a2fe78991e000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = a9560cc3bd566af9beeb59a300ddad8de5a70be9cbec8777b625f9df541f3b7e3432edbbae58624ca393a7c8466654ad4e616f302946f2b4e848aad0b16d6ea8d19faeff99df0577f422b17638ae8fc1c23b90de0d3b0aab0e7f77d81d4411af93fe1fb038fcbe8b5dca3aab65b63b767360ff8d314dfd9adc924dd5315a591946d7e3bb9a8d7605d4168255e2c0eb5e5fa2483505cc5e7e25203728ff51504c580ed157bbb7ea59702fff5f39c67334332d5ee17ae551449ad402b9d299d7519a9d60efa56a1bc39c1a3e12936ad533457fabbaeb5f4016c39deeb95bde3d8b62db69aefe698e9ad4597762589f20771171623c3fae08176cc6b9904fdcdcba42b1ce7ac5a4403ba3f38542160bd235f2b1a9d2c8735e86ee7af2e749508252a34a4c36bfc82573b856ad0408a95b7fbbfee254191f744e0f36d698dbdb0e9905e2a5e4efebe76dd2af71578e5dd28974f393afaa581e755030a137ff7a912648e6c1c9cad9a11c2fb22a028cbecb24909ecd07a53b5094d035664ed822561daeb8bc09c3be6f351dbff20f0bd69c6dbd8495460e55710e2e26ca39a1a90f05bb44e74cc0fd932296443a39b968717b5d7bba52b4313005a7e917a7eef4561e340e42c9d4730a8ea2500db48da0aa4c8086a038c00a5698b1675b398cbdc8223bf2ab069503e574873ed015338cdfabd2c4c8b349c6889732dc737501f9f4804c67d693722f3723fdfa21130fe621e1e091dd6dd63cee53f643f105ec486fcd4bfcafa03bf7662b2b31f0b428ba30636e2672b4114c381e2ceb631ee4b59604a656de5b13f556ac60747f00362ec577381cb6263c7511d1b4b6b5d55dfda1861bd8ce2437e47fe8661ce3af193a8ecd2e3fb249a7b82c9ca905f38f3072b25262b50ab205d7c210ac62783f332254ecbb013e0ad36ec963d62e69e085aa6356e1d2027b6831cc7ead70301bed933823d1fa5d157573d9828700668593dcc60e1c8adb12f14d61496d90d38b9be0fc78654762c4cb32ec66fba75063f1d8f7e83a3e78c33a5fab61c80e73af520b6d013daeb5d48b0308a5c30f86aa19e64743d1bca73ad7336b7cf2b9a309e3d86ab39882bb6d3f4c2c2533fa3a4c650463d3992ad0ea1732b2371b62d4c8c98dade19edd0eb1462c830e67ff7413d890d30d2437deb5abbab57d24411fcf49a2cdf997263721f1a36fd7e32ef383c3ba460a983c61b2463279330f24b75abf6d2ca977727696f336220192a827d13d74d833d038647dc6720769cb316ed38e9e60ad35b00f21eb4c9076b16c79f8f3bbbed9fcbcf1f0bd70a4745a697f3a7497996953604f29e4ef850cb96735153fa3f2416229cbb4c36e85ef8f68a607d77c48f4a14e00a080c62bc2094dab53d39c7a75403f35c9f58aeb25b075c9258c2fb23afe18cea496ec56b3f17cad7eff23bfde253eac130494c0715e5dbf5a565bab2998d8d0dfcdd278b863a2776e1c97c8deade022f3cbc190517d0ea91d0e8b224e3eb802795f730fc90284b86c265ff0d9b7a5de627859be4c7c8288d22c19a638fc80836aa30b948617b3d4f086f337443db0eb6f1dde7e854525ce5028d3fa8d45bdec7aea94fd2c4586ede8a23cee74e42024c8875df7c2d22a10dad2ab7c677242bb80d21a52ba9fa299c046111838c5a0555f8d11880d35e6434bd66433dd9500febab247e9c220b2d97d523199e99597d0e83ad6c11846c42fd04b2831b4688b4b338519037e90b68055c4d10722d933b0c90197979be263b884e7ff11d527b532fb17e1f8ea94e0a177308c6e626d6deb681b2083f9960b6d9845069b6bce1512a001a8ed694b16a191023cde941a525b94f225b55d12ec40bf92db4c04c957798be6eec2c1f377be77499739f48c9561e83a01c49012f134b5eada3d662e02127ddddc7569c07499fff9f8f341adf25ce79bc46315c4dc08b65ddec14275df0c38ced826ec2e21e3acac3ba78860bf829b5775da4ec61ed0dafd17b79b671629c0f10a497ddc3734586e8c6689d087ebbd63c9ca5d2edf349469ebcc31e81c2d6d58f2c2ddef32b4b9986bb64ef8816986758a616ca4c4155d126d357f0571b172fbe6b7308e357436945bbbdc70c831f60243dd96a7c617d040a6276e4d9ce07c880cd4feca2537127eb0eecc6febd22c3c92a3110eb4c4080e88923e56bea4e5fcb76c450442b89a5cbc230f +expected_shared_secret = d31df13dfb22d68333814c817ad444cfef6378fcba2edc372ac44ace59e4e9d7 + +comment = Rho leads to matrix containing zeroes +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 424b6ee6089ef75bae678c685b685315456ec584a93ab25f67427be85bba701c0566544f8133952936a203923e07d5aadea1130d906daaa1a4d9939ce1e147cd874ca0f777f9023d156070f8998a9607940d15af47a4919c52b831748af51b41712077bb4836d383a33d802c80a133a388bcf0f3cfac305a7fcc3199ea880d271242a3a6adfbaa5a894ceab055a6594436818ce10bc8113c8ce0613fca2533088a9f35c4a161e0035d690e48b4677273ace7d2c70e378047e7b9b7c49b729a612f5abc7551756aa91239cb16aec08e2ee53659954cfe1a5ba8b47f36c47d6ea2885b8332baa61b71a9bccdca58e2f0cd25e9b40d38867f69574f98ceb03c3d18b9b6d5c2ace4a8b1bdea7e5e678f1662932c267f117005be498dda33b97b0c520b1375c75829d8e7cf268524f74656d033bb986977296b4997fca693281896681022dc138fb24d9fa5270626b1dc4375a72c42955529922cb683c225cc76ad1b25c3082b9d2c47491bfc8b83767d274b0473fa753b16b117546b8a755e94b6b6f7048079985632b33664aa50eb072b47a338ec12b3501b3413e6c94488546f2bb142d851fab8260665aa88a75856d1ac719341ba190e941b8d6bf53f76b968fedc28d0a524d7e366efd50c8929cd9362cf4ad9366713c2dcd4b91c45b6fe654fcb87a6674c2f3c9447cc546aa645a04cc3b57d8b1265d91028c3756d216bd671560e29467805a2ddfacfa651a2fe32731ddc74ccdc243ce97ebb7b2ffc7056b334a0fe7813cf5825997690b91073b7f9563749b8eaf46cd8b93161c21543592c21855f577290b9a6616e2c80134a3713f04e6c2cacfafb3daf78b9ab671337931ef7eb58a48a73a96b6739850f2af60ca0917e301610c5731b032ca6cd77554b7a7d7783c26b2cb43ff1c1fc3716fcec4455e516d164c561776a03c77275d52d1ff426d76240b8b5a47c498fe836736a09cba0b32983387f595593800a4e37b3764f054bab91731c748021818e4d149db358ce8b2ca2af45c6e070ab06fbb3a3485698bb955681b95e8932aa30b9d8242bff3618120038b3ec776dc3b635963ab24b8e5f9761162737b04a59fb38ba1b3685b3512133e25e7810c4cb26a25be67b314924728528dbdcc87ec53cade88b1e55c7a9ea43b647655c697331db555e7881e240cce208ab189265db243cc97508889a2fa201a0d1066c5d2a7370eb8137d04fe035c8510b9f21e6bd152872ce6c7cdbba87ec85341c9c23bbea14f9caaccf56cd41c60931a1970867a38fca93fe6a789f5b1cf99ab23fbba5abbbc881aa154df05e9dfb5c92679cb56b0f156c3b67e918de09c5eaf4288885c91fa5366f0854e320451e14a48261cba3cc671ab590ccea69693a25ba90accdb715241754f2f5adb67a6e6491703c0b803d8c55f6364cf64c3f117206013ca309f5c7b4b40774f98ee7738f70b5b9bb19737855bae9958f6b24b22d643753515f79b884c223cb9a734c634306ba20cffa79a5c5fa46e1501aac245523e2b1e42a44a953964727b13fa01b65eaac6188a1c9ab974c613cb5971bc8680e90181b3ae927b3b325a22389c204470e4c6a97e404437858910c61897cad27f00e2f7556639635e3775f7ea351921051684cc6ac224df9ea98bde524863683175447d25aaed72c68b15955dd1639dd978318a8347316690c24bea1d3c64f031aaa2a3b48593a7593b2047a8c29c317c9766bea878cfe5ab947f12d5fdbaa267a18ffe966ce629c25ac16b68aca3ca000e5081faf0b07c7b914dac266dd08109ad52408c0cc06524ed424638d1b7d3175bd977b982b26450b7b3111625d2f64a6055a59168c9ad1cc13773a8f4a2c79d92c08de3567387a2bcfac1186960d3c939f2a601bfa96bf9416022385b2d1aa2dfd570fe54cbf4cfa325bf4a87e734b2bc4ab576387c63590ec3171b41a5b621109ff0a7617030e02962224903d40c5c396413d8793c2d2044949659a92b4480e8123a8738f3cc12e45504dbd40a3a497623e70600378bb32d66dbce08eaa28303e896aa887186ef9107b023b69c49c0ff802fc504431ca0aae2008fbf39c268cce17f1a75dd8c880a34467963cc2ab4d60d78e96dbbc5e5611d955658de04b13d5ce6cd3af9e2bb3caca8e6a088afc7ba31f951b920318ee4f3c26cc000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = cb24ab9d59fb286f3ecd5908e34b4e5860bbd08ac3939825156f619e0c005de948e8698deb7a34462c5fb7730ef3ddc05b017b58edd91e6fd6d4df125128d20ff619e3e593364eee7e532f3d962108b31f77216f71bc9d5163acedbdfa48f94f2f587bd5c16e11b5480237e88f1260f7c2fb25d044d5108d199e1bae51f8f14dc5614b75996ecc3d067ad3cc6b294ad60fb9fa21750c7bfb53874c2ee99f73a494d0df220f054a845f2fbf85d1a5727c087a65436433b73013b9a6f26f08c1ab443ebffaa03a7f8f185f33b07b99400f6b03ab985711fb4ea97d058a8e9a948101359b610a6d428a3d10594aea5ad602bd83b05ef6b6aaa2f56b655dffd3db5ad2ba51d8d3138d355f2550f29b40bfecbc43f1a3dc7448640b5b3006b87a23f6b71554d8a54fe0d4db52732e8260c915407286bb3074d2dc56e4cc50bb14313a4117e78e29d83c3b5dbd93ede35d2a47b46a0ed51fe72cc7b86f96a3d9367949abcddbd9988639f8a8555534e23fad9f35fb132396a13f3abed73fed757363207043a84bf5fa6cc2bd862ca46dfb9a124fc0a2958a09f1f35fdb5095bf48b859255cf49eea771f10ee78ee460599342bd76ecc8ea35077c4adfc3e05c37abe4b45cc00ab74247ce6568b0395ec681de4f96af9fe4f053d08ab465ae580bf2e4bb54884bc90c75758a6c9fdff87fe56990cd3d0aa691f97e03d46b5e25bb6a8d2acdd458bdd60aa803f4a2e7652cd9901a385525eb1f2c619fc2ac3bfc655a40102e0721cb842bd1516894e31d972adf9570365c2d3acd23e998c9aa620bbd0f98b07cfc103389df202660a9a66e819e8ad4872cac9d11667ba07e49d0095b1470d793b0520d492b4524521f470c1ad11a917545c3e90c0d09c57153b9f01021dd9af03ca73f0d833a0f7d6d8cfc132c95bdf9713b055acd993f8070095cde23f5782bf1502268ebbbe18e0a2c2579f4277d2487173fdc03f787e960b351c0b0c8b676e6a9a1b2cbb8b88ed59ca6fa351141711349e70f13175f5e1e6c40b495c283f7f10eecd35fe77330b52b1dd5c198c1ab5aa82547b822b59f2eb18d3f70c2fe6d78a5eb960abaae74fc69c573948212efb77b7b58ac24f23e39ed35a0c52f00885c24bfda0336ae6ad827b83a0520710d9a039bbd2c9653d8b3ec38133f06c4bccd714087f5291a37b1ccbb4fa71aa04b6ddda1cfa0e4af9d531c053b4d3b4546894693e32feff3de7df191517c89d34bb3bfa4215d98f5c72bcccfecb97144f1abf05fdb21e2a4017e9423019a26eb70022c74d49926654e986781d9acea4d8008dabd068ded76190b76a6dea78e2aa33b33e5c68b43946c0f83cd3c162dc23392d47e6dff8ae4dc9ba44ede5ed59d6bd399110c513e52a71bed8073d3b791aba2dd34ae5fe07bc9f0b8efd5a275b10477773ed26687be2df6afca51aaadf3df873b7b87b221ed25e053de30b529aa920b14ea96d955ed4452bcc4f40389a9b8dbd8bf25bc02a99d0c1fa92e8d1f39013210268f766c5d9a8f080756791e2b9ecb7c81b10ff643262da8e63870b6e910c26e10c20643ee740bdb73c3ecdae5bfbec98940ae2cd3936c8dceab8c6156840463786e20770d7c2b89546a41b7bf5dc1a441dd8089d03b69942f3ae9823a29aaead42fe77763fe0b51803cfff169b5303594823ee70e56b4aa0d8d77a7a39181169d4c9910280edc3aa6841e54427b962846df3fc73b71ef19cd6f24b74f88740347ffed1c6b299ca9aabe8f17c9425da19518f490ce73b1418a41d7f5d60a14f74a51dfbe6170b4df1c908af859392a4df8e27168a35091c20b2a3ecab2e0713e26f97d7d571dbb2931db0d36997cba78a929f06480326a8ded29b0bf1199b654cf6cee8e982ce057a55ecd2be458bc8f55156be7db5a39dd5b5e62c0b178c0b500d79bbca5330cd21c4e213bfcb2584e2fde2e7f19629710776affb99fb442dfd517d49305d1980069447b09fdb411e3ff2df0fd2e76b35ed65b6abd6771e6e05977ae1a86145a24ccf8b8ea28758921a0f202cbdb629254059ea8f9b5f6f4cb4f69853e7de7cffe70c05c5588ff5e77755852b6782f2565644e6489f62318a7e2a29370f5ea90c6628bfff320d948f715ea88958974a0ff700b08b3712100e73ba7d134f107c304ee0c00c65dca2853e739ff2842beed8e5df18fb4bb3e7edd7ab8d7d6fc0f2afd92f5d15 +expected_shared_secret = 751052356086210d8df27a08a945497eab163ac925b059000c89b6e82b2c6bef + +comment = Rho leads to matrix containing zeroes +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 52f8b3b253b655f962e9475e8cf792f5f99b5c4b440a166e0d18c79de23173d690cfb697f1d072f269b94a78bfd6196ceb655354c31f356806ab5c42bcb9030c6c61e3c3a023327fe813362bb69ed9e783b086a94581c41cc49c03489ed53b585febabaa951bcb642674b74a4ce35db92894c6db484ad10b0dd84b3e1b9f88960f4d7a9b36e580473692930a83a5233dd07a027c8cab7b4165c860cae41b950d970831105902b90805d066da6552b839607880a1bbac123145375115c647d10671e84b85f94206d534cf44bf59416f01994b8b125a0e098a842c4ad6ea108fe5bcdea005a1e3985f656e34c431d456cdf9f624a7d221c2c242cae4c9720a048c760cd2927591db67c951905c67bb42900c44f67b99e508d5b38839a0b31443ac8c241ff7b9ca0a06ad744813eb37142939248c7163262216a4438b7f3aa5eb1c9ae329c0d0bc63b2665d90b17e7a27308449bdce8a861fc08c982266ec83c9aa1422135a9e9be99c0a098df9a5568960aa2c727a18c15e7713c289e502bfa9170788c6a2d01711fc9b4177a491226c4d6a05b03baeec202b98e3af0c7612d474c6b7b912cbb38990f29fa5f15fb12c4a5c417bfe30a8ad88aad5395287376fb3b18b234199273625fc23c79a775586d87dd9466f1cb816466807e5079a270954e8fc8851738dc316369f8344bd1019f6b6624bd50f0cca851eb57c48b126aaa3a97d8044d3800bf344c4579361e3096ca29506b4b125143b2d625c21bf0a001aba2e17aa6075d8177d55324a08cca923339bf5c7c00b5717e7007cc94b61f3207dea1e3bf24b79a09ef07a37c4476e47f79a674693fe00b78d372b6ca76614ec604a86b64106cb61d4324e99873b241a56e063960b5fce306640bac5d46c88c85678c508452a806de60966006663845692129123d2846fff3225529475f51521e3f027d537877797b511043497706f3bc3b77ab6823a112597567e6b4848acea62fb09181fcc556beb8216c76ca6782e2d1234bb8521ec40a0f6d511bf8774d335b9a764a89aea93cc9b21ad62635c1b8fb6a4a4130572e41bc13ec627ea2c631d33a81ab1b6c77078c564957b39b0f9f04cc91b1b9ed89240b03a1c787347505fe4675af30a09d6ba13074431fdd045c44b4754e5682e7c5d49492e0ff2bc7585b631f3cedf98bf774427df7ac847954a139545d3643b1aaac31b49571cb7ac65554356d8aa555a67faea89396aa810a9b1cc8312be7333003d8e1f854a7e35ca0d75b06c499b0ed2a35699114d287bca9571e93948bef4c32de6bbb952a5fee5ac42a14c4ada7ceb5c8bdaa873076b0f7ba4881bd2118ae67ea671482312a35c7c13b1d7af2c9291a8408c3ce985a6311a2c702cbf306c9a7b4eb3ba169992831899c6870a8fd3302079748a835b04791720cc4737c5b7684ff612abcb477c7032a88262a37845f2c46f9f0066d19238689b1b53dcaed0544c06755399da2ff4fb570b299290497937126672a41ee9fa594d40551246cebbca8ab1f5c30ad6bba9b0aff0f06b0dc060e6b58a70cabe5ebb464b3562f1a10990d12e5da525c43040d66461cc396ace7c90c0f1aba06c94dfe7426b922c91744310ebb4e33251f1c47e2a415b95a895666333aed434edcb69dc69a513194ee2013a19164d49a519e0cb3771247e65664dfbc69c46dbbb6ab2193bc5b56abc9034790ff43909e6563c42545bd6ca31045c2228dbb5601895cd397dfd73473b0609bd720f9475482697636df216beba0d1a85b396e6ccb3e41fb8d52b1341b08504bb00a5740a80228118adde4c7d0bfbbb0fe0b8b815bc07885e496324c9806f9d07762f123ddc558aeb387b9858b2117714886bcb2b18b182b6ad2f8a21acd50388959f3b70a258a025c80a0b89d6321f222913484990549fcb98c5c8c88c2832075be378410b70c9b9494a6c1a40e5aebc88ae3d186d0b3896d309710c17ab96c93e629166980325bdc946e022ab80c47f61e01421c780ff336d7ad11a3c28721b09a03a5337dfa6cbb76acdb1846b62225578d17fdf062839878196d1819abb7f09dca6a1d225e2e0bd89a5578730adc5d53d19623203e24597c1a2015accd07a6f83938810bcbf2dc94a99f5b47082336fd11a45ba478c750f3e638d064144818a17f1586d6806353409000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6fef277df2e04e66e489b1e04fa87580157cf1c84f0b3bd8137afd87cfb0d726e39d9706f177f605e9aaccf3a52e841e4c3c4b5d54935c5a9eacb0e6d8a2cf17ca416bf7ad3cea42c3533706c54779d62a0c8a44d0c0f920db72b7d072738ecc07fe16a8e257452e1197604054866dba1d12cf4745a2808a435bf31aa64db6af2dc4a3af697911adcf9022936fb5d40a9c553774f4a589192d98bf8289c09ea803807c448ee3e99c26799ac051a50ce5edcb57f3e13a13fa1af41befeeadb7c33e513ee8cd9364025ea0b4efc5ff8f095db6f0a9783acc57b2ed7573cde2ae2a8e7b211ec9eb6eeb34bd358d5cb009184c76bd7d1bdb4a920464d1da993787cd284ab05b8d5d3ca474847e64e1e728ac4ae3522cfa3a642eae5c47a94783700a2b758b2342d5dd261715db4f3156a5be96fe219dc8038f2d7afc74fb60e6cbcad3ddb6befd0625c4b2de1cc9039c9486c5c18aa8a796169a93cf8e626ac47e82b752f2e6537287580acfc1b6460bf5db3f71fb1a4f57e67e0d914587dfba55ee5bfbd5841bc04d041526a46053af4de2347fefb071465a7f9b00396b66c49efda179f13f07dfd0278464239436d8bd39dfd048329c89c2c8fcfa54c24ee67d124dd0b2f411772e480dc2a8b40a6792d0cae8ae9c6c883908a0d33e931053dab157d49e11e76ea3a9bde1c24eefff37379b265a52a4a26b507b5a4eed6f60a84595b1b747c96e8656e7759392924662fb43a40f8154b642dad2d8a0624b413a15545da8bc3dd5a5f8d304eaf23299d5a4574ffef0bd5b3d5977daceb80d67df682979abe36cd7d74c063a0b7214336c75c6d047f2bb52a0a5124658b9b53ac5a67a27b001aeed0c6dedadb3c818ca99e52b18dc0a9adba7f88eaf4bcd269132be2462be1a42ed102811b376276780e7a4b399f02e6c00605f1806987a6c1b3d4cc8f9cdb85b2c833702735ec6a61b9fd2c9ba220b108451d1fb8ddc5a07baa2537f71bd82f1f06d7f27e4a374336743c40466e11de367ad4a256e860e6e5f62a38cd2911bfce65b1b29274989dd1016ee6fae7790bdac6a3e1ee05fd4ea743c5609c3e4f1a65953421be132220b1792404d80d68db00ac5a94feb238325ffa44b376a9b6bb3a84928b065995cc7882673f1de566a78bb80b61beaacbe138a5a7e2cb5e3e276057520db7424405c69f719534983fac6ff483b884c932f6b72fd1878ec2ed1edf741159b973e5ae846fbf59ae1aca97fb855c72dfc5181b09a5a52a1f8012629218a8b00968a5c4ca733a07893cdb1ada1380db4b6f4f211996bf9fff20227f7d73aa552d8f9fbb6ed0d4dd278aab1214fce37dd76ad2ddb90e7ec49c4c4bfa61602988bde7f498d5feb0540cc0d6f2ae75018115695482a4264d513780a87bedf78e256f99ad0ad37f910215795fdfbb375d66ad20d1a731003a1ed52014b6183906fc6a0ee544f1b238563cb6eb407875714ba9d2fb48e667962b45127deb0180e317af9d2fefed19ee929b75c97088ba9cf525ad7264680d3a9fda47a6b5168a846a1bd63695f4b3342ffc828f8fd1d5614fb4adf9d64447984605a8846c094f813e991abfcf01c0ec330cff0aa9c8680d424196f173f63e2d0ae359e5e1968fdb6fc72721c23c239e88957f107eb296d7967701d4e9dcdddbc5962085616cb641c17c86d8f33d73bef887a160065f48f5d7b456153c4d2898f092f6a870c49ef615fd22833131b55fb46f73fb399b046248723cdd15d37c46e0460a81840dfec3879a49eef63e3b331cf53c8bc5b10570a7fa23e3228ffcc20cef18ebf8ced22dd37b50f79aea827dc37cee62a849110db97287b366afe64b4b9379586ebe34b313e260e84be654d83dd3fe4f31d622132c06875ddbc70629197f54b400a97180b81b2cc5aa430e3dc6ec4d9aa37dbf811ba2932aebbb9990f0048b4f04930e147b38f3f22c4f026b806d9dbdbfd69914346440d9b37e7ffdb8bec0761e49762f4f87485e2ba5beeaf306253b97cfca2637e7f7cfa175e5565e9df8741b94aa8d808515086a12606cf207878080b7cadbd318ad5667b50ebae48bc923b4b7a7c7f7145f7f223f2afb9536584caf2e8df28bf693c2d4d2ca71e38361f3db5108e28ba11aace9bfb85bd872be837916bb53ea66a22a605683cc112220f894a8dcb16098607ee5e2ae33b4b93dca707fe7f96f91defd1a6105022 +expected_shared_secret = cf115ea5c334c9374daa083543cd805b8070de6688c552b82b256628573d668d + +comment = Rho leads to matrix containing zeroes +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 5be7aeb3f7b944d964d1a7cf0e1a686e02b0b30195ee2bc6d5c78a8d73caa7726a8bf2cd62f33ec676a2a0c997541a386ebcb3a5d845c0a9b970f35ae0602a4282136a0cc832f34de426a08f05bb89f05c4f23a1d7bbbc81628040fba50077569d99cd7b5c7f19b4cd5ac618a4c489cc08cd55f567a203106be784f6824f276c5b4407cafc0836a69c8d90047803c598db03491110688029885ca112ba18026a339ba7e47a4dbc2386710e87fc74495935b6c408ee077138476b8fe10cab556bd1613bbe8ba72a345f157641873651b314534a7c4bf2979fcc062593c652441340e481a76df717b21061620c946e1250e781661bd10914556552ca3204d44d64972038a68a60358126305dfc2bad91289ea150162333bbe98874930abfb3b13922b2be9fe6bd40c9caba8b9412f85ef64348b6b46695184b212b9e35586df10375f0c0781b6245e2d8c580196a025022388a8b1422a847d388b1cc17f785772d5ccf342c01ac667ca866c49272af0127b8076570ab309fdd096b007843a2dc167837977b459000a8378fa4aaec320874804698524e4111bd1525be985a959ad3c8ee8373511726e88c71f2a839067c4a5a4235ac4a977c444b482087c612752ef0359d1041d3740ce4db971071c0947319a8a2c314dba1bfb118fd093f323c4e41d618f0cb73d6023e7380bd68b9351a825fdb952f13f48b64d99bda8701d040b6da27061ccb36f982611b851cf2e795f02161f58ccb973c6c3b0880915c31b7d59e3ab05d14d7697ba59245043bab406d0286b71f72006a51aba92c8f53e39333cbb273fb7814162c4d87244933ceef702d17db03eee50b48eca264026d19191800e47d1bbc7ef57a4fa0880338922f75484759e2a926391d1f993ace7756fd03c13002950c33cd4a882d90131d5ac4c436bbca02e22c608a3537d21971672b49963a1f867fde42c4b464b8b1e557be884862a68cfe361600f39d38886f8fd97479a0797ccc95c66289a489a66aa9955d1985d518b7c3dca884db56a6bc01d1d21818fc25f43a1b378286eeb18da2706393026dd8295e4e20a103ba97ec7618b119154543875f43bc08d76dd51730672321bce866ae2ac6a6450215439c9510174c90b58a416375e935092bb7469624337a5130c30e27905b0121678480b75d206888c706699b555084a6cf21237b102107bca8cfd4809e3513886b271c45cb162a189568ccf9389ec8017355db91ef79afb172cdc60929d071c6ef927f641a82937a146d85ba668701f14183a5136df8d6b27a87c215363016a21b8ed0bb27173d067349b170911c0607c065b173a429f244199db3affda480d7e3919ee616aba4165cf1040544739b3b2669817ad6f3335c96b731ccb2f0765552a71ab3a32e6509c7d53233b229bbff40c8898544a8a26db655275500bbb265acc4f8cfadecb77465c5c1989680fb37b554b9e5199c53759f27409df229034d9247fc965d453a206197cd840c42b495483faa1d62571b27190aac9c56bf5b992b8019ffac1366925d2b65230e2a88cb3c209ea13a1f273c9c512918637d5e40b92b9546970b341ac0c69a264b90a414a43270e442665b59608919cb8ee7234d113bf6d14c89a7a1a1f489420bcdcd96123349c65984aa9ff083a73c8294a282fecb16179c494ffb33506947c9b59e39990b9b516a3751aae6cb5499d196f6402f7c2a88459639e6c2105bd565380184b3e48691b11598b5473c02917558911afc73bada907ee1c124a1086a949fcd45c0f0c37df0863f45d70125d02ceada9c797a80b1692ce7e7c180079023826f0acb5c80a44a47f724b27b652c10bbe4f6258014a03dd7cd84ea2fe0ccb4c0744b76fb01f0f42d3c5862327c6d2980751f835a9dd741cab5042e685b52f45ae95cafb6229b044b4a3e056c242ac7a44587abe55f8de5b2fe0a9cb8f9aca9baab8b423a2b7c6afed694f275c5ae2157288751e95c2ee45c03935a45a130156a739906f104dd931a6498960fe27aa15a0679d1bc68c9850c930140b6a45bd2c2b5cac0a168aa644760f3c8af61b8bb184cb7dfb784e0f0c5ce739fd881c1856815cecba44a3c4214f7825ac44e77e97c8b8b32c405292d508d2f8709428a39e9b60016908b1ce6847f84b14b555250451be218c2bed841584b3627fd000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 3fbe35bddba843a88d1401fb50ebc9a3ba2b42cbc5795ef3f29f3c641287536a4999325b99f6b5e9c2a36f8127e2c09a7fc6140a9bd68300e40e6ffbfdf112e9a50a21d16a256dc2b9b94b2e45d249c40810a6978963b186d543e2154590b9007afcaf9d1791f4b0ad69283ce711467f001e8580693bc7a59928f7b1c228dec882e3a37f6f6ca83efa2a3c2b2aa919328a4b4174c00c9ab4af6d16de60859d3b4cce874366fa93c26457d029d20c186034ad8c4c30a51a2a5547e90456ea1d43ddd1b882681e58fb8e2db2c0ff36201e0becbe530be3cc8c6ebc80b9f7904e8a1009c1aa33fe35649ee91c558882f84c885183a6f226db7dca9af61babd423d2f749e98133744d5cdcb36b541a6486a43a5c39f92e0949c6204237ea64ac25faa8129af4a10f9aba6a0b647e1bc99b19187d3a2a941df726e7f8872e2e4064702ab7bda5756d7ec0afde524bad03e5f80a4bd76790a46bcd2556c31aef335daaa780c2533c1aa5fb2109a597326fa9a88be25f28c0b9577fef5521761802236e274c790891b4966030d08319894e6904745065e417e91d8f06722b159f21e4395143a875b2b6f48fc614fc06aab25f676c665ab98971fd28a7a9674ab15012517860b2a532fe543f50a4b467b2246efd85e32bee86dd067963edac95b2adda65a7255b7e83be377f2831c0e1a2cdf491bfc255bc417661a581ced672ff02e61c097e8103966b7ebd851a63d5d5b5266d2604bc350711df665fd82152a47c723cdd0d43b226145aae4462a233b2a8f91975c498d50a6f4f368e8501b709c0df403ae23b4f559cd57c2597f6e30b1f6047be7630b90f94f8b13b26421386b62ea16fbbfe926b7cc08aff6a216ce84b850d4b3fd2646824a3a95d26480aca8a36dfa1925578eeda4dba9bfd90fc72419c648223d259886d72e728d90cae21cf204f230c57d00be1444a891d4da82a9c9009db64c8fbfa922c205e2d51b50f4cca46ef3c19034be588d305b21d4b91dc2c806b12bfcefac96c6f5294d1d43c5c33365a0d5d21f5067c4b525e1fa20742502441b8d7595a309c7ef52f4bc96d3a4dc09e4480a67aa9ca10cbe640197bd824099448cb7a2cc6d8ed1a036c3dfed788fe64905a0d6b850002b932503eabcc1dab4695b33b48f0fbcddae3b8235333d29080ea2c1b58309c014b13dcdc2335dacffc003e98e2bb2259fef78ca1d136ee25805d9fb757a292175b0c9edd0452effb49cf3cd43aa50009e55a4919d2e1031e17ef2ca0d6d2eb660c159580b1ec821b0dc9af97603bc27611adab6fec6ddeb233ea4c5d068d1936f5e2d0632052512bfbba15e8601f5cb8534f543997d268146799abcde181ae13fe13d1b17a4785012e902f3bf43599b0e287ad3abfab70c2eb79a60d9c7c9e3856d5205b27272e16dfe157f36befeab28785309ff0c2743a36ee66b7b036c6df71c116fb4ba983f80b07817982e084700a24245f377eff62536645699e1ba3072caaffc45a7a3668c4ece26d7eeef7d7e32be0e218b89e88aabfb7a2979c0ba030ce36c47b6c0e4609315fe12b25f66f33de60cc9334a0198e00a81da412c9ad39a036e5e3f9d39b4a5b81543a7001caf176fb1964cbb1bbcdf7e096d762302baa502f0c172ae4f22bd92a969381ea476ff67ff3c96e9be48950b51fd01f3160b5156b66103b40d3274f041640e14d6579870a6bb51c5c27ef6a3f0f5260cb29982becda5fb21114533b5686df14885c36b07907e33b2462c17717f85a700d8c209fde740af48652663d4a67eb09f22322006a63a54fe50a9310cedd9d69b6ba52c1c991b8b43913d97cbe5150ba103951462140bbf02da88709af263eabd1a6db3a1036d2ed6bfb3b035c108b5df06a9b0e64f16891e11460e71707c6e0d5eff6796ae7d054a9026ae1a9daf1fd6e6f6ba780c852b7dd164711167f0fa71ede289aa7e77aab847e9b8852bca0be1e0b22201158f8ef8ed7615ef65f5bfdc3cf3b8dfe33d94a0b4976e621df81f699d0b7b61b3a1881698595a06a46fabbfa2d41ebbd7467fef258b6676fa8e89fab9103cb1505b9a4a2a532ca2c146dca4da88586ebe6b9116e7abf83f0042ba7a8393ce1d7f6ef50d443579eff34a4bd08642441f98ffa908a4adc4893a5a4cda1bd08e271a317950421be1af54ebce11f3928dba1d5c72897f896a9f11266062b5abfe3ca98be59a854 +expected_shared_secret = a0cd6965a9282d1db07120d6ca59cbc6939fc4c64c6f980db9ef85b07c047e95 + +comment = Rho leads to matrix containing zeroes +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 75a9865fd5889a51a706c80945812c122ca0ee71178b4ba808bb7a28ec91ddf13affcbce77c1111f692e50f8b6f54b2694266f10c5cf411096c36aba5a292335592d975036db69a823b5ba1d003b98acaa0f6929701653058627e444b63777b6047957bcb749c889b1426b34a10783507bc5e3fa7bd75abf62fc236edb83d65061c2a7671703758b04d0ec738e1841b8256b58ac448285f1cc0495928c78166ec0a5ab8471d8d59606e375935c0211535ee2a47f051b310de23a153451f39179105997841857f7e277918b682de60ea5d70419b0a2de9c6ad708091148514e94249d45c8cb60215996abce1c86c31a780246b0bb937f26313e6fe1ccc963952352c717d303254b5c373752be849c027cb6d3c616fb52375492a4848732756247397a238cb63a6d50b9317bb939fa594c881497f92f5783951e03a3b1496cdff20e22256319405d44c9553f91018197510db2956baaab22009ab153370b25a98ec2c2645661e748ac85976872a47d9716ae7f865ed112c4c522c1825213e68978f0c1654812868c00050c7acc412aabb4a9683ca9c673e129d018a05da0105060931dba7eaee888a2b233cc567d722a447dcb880a46c640592837891d6a4770a46c267f104811ba47b19031bec2a7510933295752d2b28de55326dc71c4caa543b70372938087843bb63d74953453057a3877d2343663c058e218412db1829ed9aaf8574681bb2ff9e217e7d44b2c260b90c18a1b20c5842225a66c9afce760956b118069a4a8ba057eb204e03a85ea1701b85c71fa6ab590345140f58280121c58b42fe74922a99b8c2be04dc76c1173016b7673bf870889ce6520ec537d356c9b55d7680324517ce3066d8551f84c7ba9d70fd9f3ce485b6d1e38b5cf055b38e2b83730ca439a14b7fb7a043a390fc652f74940ec2b906a41b5304140cb5b5412f996cddb40f8ab85b087a42e6ca00a275975495678890ea6a51b6d874235b48295495e951007142b703463c934d10cc88145886c5e7b6a04dfa9b435e27c6c729941802b9b682a6587907254c5b93694de13aec3d93043e4c095e4937e9506867266ddcc601ab9a2649822824aa12846563350caec702f1b493cfce645e2a0758bd5a9e29bc3c72ba74305577c10266099bf884477ef111c6982826ad7b658e8aae4ac69a2025fca407f6b5275ec6572b0a86a16a787a413cf919a39f65074273c54d8fc548b2abd1a7c9fff406c84191a8d4c2e9916b37e652e5e83c879942a559024fc9008e8d008dd39768116b50bf4c94031cdf45cc932210711a443b4d5b1b40875924576e864335f130f2f51348333c0b6538a7efabfc8075306669e7b47cfe5758f7387526e666e93d16777895201f555ca916c5907c80cb003f6b31daa94851d0199493242a2d4ac3ebace84d04b7663a7f922bc277562d984244ab894bebabc8d8b43110b4b1b0ac3f4858be1585a94c46b24252d3bda105521b0c625979b6b251726ce2848b327d36ce3e8502ebb9e67c102c3e6250bc605d71a93e96472c9370dcc3626bac07334954bbbf280c2e84dc2e61b7ebc0035897516d75cb6cb6994a06bde802d0bf986633c0ea0f3a4854059d3e251283bbc3a19ad83902938e2b976c10611b62441f7c8d147023fa88c1803a8f4b5a8915b3454a85e66345218f6c27dec0444d4bf28a024e8d82a86cc40edda2751db4bae70045af8a450c46b49ea7ea01b70424810a5187e2057aa7ca2a36ba56cc94917535c06a827a704d3088a344125215d0b5944e5a91830a663f8a8c4f8e20c6072759290946f153422a62cefb33ab80b037b145dc4f5c49426770c103fd91539b42b52ae74a6b50c50f60650142b39cf595eb520592c0a4be0c16d4f766c29eab0edc03a9b864c19102d08458b1b94292c1915a4f191f6674723285caf177e339c7c8ec7c6b0a502e96a74db0c5102eb519814acc3a6698be62f97e82bb57535ad82cc4a8b90c2c46827ac0adb013954e959364c28e51284252466be14c2141231caeb2bcd975492e500e6c518d22a2b5cd667700bbc741c155ec81481687e4dc98a6f5b5efb9188c028c01b2c94bf858852603ba35924e1ba3fe08c50020b7d142a8bea70aa5ef57eee5ab904b4a5d1b251e93ba6d9fb955fc33e5c961289ac040f2b4af6ec2e27fd000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d7e07ceb0c6e77b3c5adf2682470e7a7b874f6de85bf8a43a6b08a5c9a538058b8c3bdcea97479c5ba6d7aa64a243d739c22bed27507968dbc74427bca924f61d6fb5825c5f74592dc09eabc65508ed637b8908d058790bb97f05a1636f42714e7d829177b49c8b464d0491ee9f00412c38f0a67504499d119acd85a3df5835302ac2ada18cded22f36e7a97f18643c1181bc71fc636827f9b45639744b6dd5d121c2c5651faf11e7752be2a91488fc684419d394d13fb8d8b566a2f4e72f86f6ea22b45aad8f52e2a4e0b9e4b02e216a1c2d924dcd258f84430047c2a999c7b6548edf5ff36bb14ff79534dd18c89d187dbf261db5abe5e9a4a98af5d1d8633690a18ee5ba00b8b606fafa63c9b5a4e58fc32f32f6917436f8aecffa64f70bdfac2d9e5963f0c841a9a2a40bde295a7ee21d5f84f88ad2dfb60482f5224a1ca6f4d0bfc3ff133795478f8d58dfd086ad5bd93571070865723e0cc1171e8ae93c13d565194ef6cbd40f5930c88a2e433120a1b773a9dc93daf21ee0f201fdc24752693df11c0d86115b68e31f4edf4cc672c2c1c75f45e534107317c5e353dc575ece35ae6069993999c2fd5a0ad534682edf567e1c0a960013c7abb691dee608eb269825a71de35bb3441fc422e4604ee2635f73fd3fe18c59b04b30954f81d4e8b6e63a12287dabc50c26dea93a5aee7fc00815af233c9fd510a21be7c9c0fd7276c7edb2130545c9e732980a1402aa639dc713a540fcba2d7d0c2f7058cca6d503c1d2a062ea636e78cfced18a17914394b340f7cf3d5cfdec1caad629133939f0fa0d7eb093ca8bce074716e9b5a8fa39893e1841a14294506b921e34b7680ea79fbf88328dc55b56803411e54a172585e4d119c6b42e089744fdeb34d5c3e0da9a61ff73dc9d41d5483fb7fa90f31aaae4ee2e9068f00e2fa0ed7c37722963639160ec4aef8fc076c4224745310f3514ff50fb36611eeda4b14034c84ea774f3f864dc8d43656648c514ffbb59969b573af2daaf209ce7b99d6b2ea076acd3be5ade1832b8f074e6c721218b99d64c499a26c1b33f2b293900c9d8a5b0b6380610d49ff6a55c6fb9e06640db1e0181fc39a070fb1573acb86ec8cafc0239a913727f8b1f4f58bbdd522f9106afa5ece1be2fbd5259201783c0444a95a4d04aad6fbfc3c514a4c5959191a8baee6459bf086f31204d624d7a8821ee7da353dd95179eb6dfdf95ca7571830f7459f4ce6a5237f4fdfc13e2455a3e94996c2fd08136fd44dfb23d15e9bac5ea07c270f62402cda12df927bac95647d969591b7ec8deaaedfe34f8b4731e578b1b7ad8d0386885552934f6a8f00ef304128a369e78ec7100f9118f0ffe8ad237d2851eda280b3cd2b7f46d62ee0ed52487e951592606f8cd0a2f463781bf3fd1503218d4872a18ece06c18463c075418dd4bbc514ff4013b6a49b4f3676a1654c74552dee3faf897f3695db1d3b75e3336146b78371fbbd5fc135c63bbcbe019b5faf910ea1709c24c0819e34a54f03c27f87b040e07d0f418a04d1d1a9508b70d6f0b4315f37d0daaa0839405f4b781606801b4a5b0d3b2087965e194d513ca64c310ea65192da9179a483adcd1dcbb21f389b1a515160391c1becb9d7ac34f75386c9ba4ef487b4edaebca3545a40cd3bcff1362d5d27a38993eb843bdd2c7de9e81ee87bace1bb4ac6d88a524db65289cf69c9c7be3c1882a39b8fb038ebf531ccb1538985e51b9b494b113933b1b436427bd1dde4540ffe8ab7c4c426a384fe0d9a824ed21d645cff1afe2bab0511e6dd3b0554843931ed277e378d8fa56e8454b8318447712eab10c102588ebb12b481fe8a613bc1a5def7883d0681ed90ec5f3004d04020700848885f1b5fc542fa9085641a5ac2d8b42cc9ca6a484d8c0efe93850d6896dd7a2bb15e3b36b8edffcbb9810cdcf510344070a264d32166ec55ce3764822a8da2377d50749b415077112a1353327bbf38d89a0611cf7e95d0a1a5cc6173555d3b76c13456e7e042dbe22b1123f32528953d2969a966aa37affc93472fad39949ea8db080d58a4460d6bedf80ce4b83a8eb4fe3e29cf72da59d354055a364dbf013d4ad0133fea1c690d8b68e9eb3c01b7a14bf1bf619f8f5fe2d2b3001d3a14eb07e9fba744c4ea8e4700492070bb2792c8a753251eab737267840e4f8b65a8f533aaee2de1bc20a4a2 +expected_shared_secret = c6a7a9d970bbe63973359c7c72f190080a27a02b95abd0f588fc163eba9f82bf + +comment = Rho leads to matrix containing zeroes +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 54532140ab6140d7a6265c3c55223229f1520da71b88cbbaa7dc7b6f79cd6ea1062f9ca88c47b70fd5b78d5a38ea594de590b49ba0ac7b5cc2b324bfc4d26dec413467950eb7dac40f5a60f054662bb9607f8bca39fab368526ee9980498180afc1b6954cc242cb04aa8a01a37c16a805792872b2b1ec63bb4b6bec174cc28631c37953241399edae60e66074dfd9b019fe97e00ccbf5537baacfb6bed8b6d3d4cc9c3b54e006c70ec2269e5081e8bf17371757b9dd40a8f1a388d68226d46bbe0b661a2b4521d143b77e2cb2e567fce825ee9338c12f425466716e67508f7e4882229a85766079194834df17440d0a4533cbfe24b05b503c75dfc9dd4e7a067ec9901b504b5a08a9d340f9ea4b036b218ff6353d8732d08d74cbb4cc19d6123cc237e31768845c628ad754ad9f484f3c3c0587a1b9883b0abb2845fcb7a57b42493d60eb5793926acc86b1a21ffa1a790183e1ca56aac8256c98546c69523819790fd3764ea0670836078dc5105ffc04fa83c50d1e933682c54911348c8627cb6f776d6c79f4415ac0a91c46bdc68711c10b0e34770c4b2d39194f95b2215a9bd453828871789a45164e57215fd4096d9ec05054bc55e2a49206a69e4f998cfc68656840065d242ae067195a5c421db21db766b27c29fcfe530c5e311408328d1b69eb415bc4b30917f957c52c14bc1c01d3f0588dcd58565f500569c539fc67e1381ce86904bddb978467c24352032b975045747235c8932f42276e9a36ff89335d6a042699827fafa84ab12b17db956b0b55c38a1281f5a5f2d9c9104cc5af03a918a5b26fc5585f25cc8ab750c47684623dba4f609827abaa9ad668427b63e1b347f00957041b6b62509259a35542ecb99002c5d388c98e86b7697f41398a3a30aa69158171a63e3397526b6fa4c72008288bcc1c2f7d4572e449d228ba05646a946b512260b6eea7218e47642cada5a9561b867648e41c368b1796e2df7273a7208f26444871756e4d52fed089019fcb727189718f02122853c6ef21d6b3403e50c0cfd447229b3457d7cc63737c6b72c384c8ccd4fb451d82a1b49e88c90c7be28311c25e3be7160bbfc42865b9003d84c1734d44adc8b590465986089bd59f1503d888f7ac2064e03447896074a947487c2b08247328c933cc31a9d9ac828962cc0b7807554f661a7d64ac90009bce5bf00b19c579995df27401fe4bf0dcc459a8c2dac1c55e50bbf0e877abe5b658d128b7f434936e273268442e725116f946738d810119531637b65e14c9d3ef26fba358df92319598c092b936e368a3e0d8a53f438708eb47de814bc90f49c83c87a282640fc02a2f30b56f659717f6234b611b4465347bd990be4ca01e550524a164c6b97a2d64cba75c3aa35924e31d92f008b42c2f701b0d99addb39a045a8cf7ebb868822250db42408c0c0a60785c182231002b0bd9884fc89a0ad60af9699e5d0661b514291b824639517bbf267decf078e8c35dfab769845a2cac1ba4c0e513454151d942a8d4163ced994d166c144ba81b41b1b64b74220b34cd5185086a797b7738a4a6e48100ed5077c1cb4401ad5f173ae4d047da4b5977f3bed56c6c318bb2c11883aa3870b760bef4a71ebcec54b49430ef0b792ffa503947187cd382c49c130dd32797740f335703ddd9703ae163b069cc76d50aac06ab01710785fa5429f79d8cd0c6f4f8711e766796d054b8a99c7c800b4f5c4f75a329c147649a7485cb61c19c0a453a9774585856e65bc9b3d30a20094be3d2767fe0431ce85e21eb9b35d48ed5fb2c2b1c17b13a4c67b09431d7180dc04fe087c827b6a572c446dd5caf68f0b2a1d973fad4352f3a5b22ab45eae32d17a993b24200125720a1255f607a1bf79c3928230dd3443343694bf62b996c3273323997972076fa49c48f094d2e122382b36503e95729e41be8f19eb4d962828959eb56491115bbb5d279a110330b818cb4a139f2290c4771399bc041b5905531b76bf817cc283331e860ab5566b5e7023d3c6a28f0d7151d175dfb9c1c8cc01a45522d0ca6374b8718d04b77a03635ed23c4001145f586a4f252a10bccb3cde193fba4329867926ef0b1a47b8bc130431a563ca97bae83111d309167caf354cbec2e51977094bbc6cec068d339833ca9c7b649204345079274000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 21c66edfc81eada5da6f03b40842bc67acc6653a816c35c9279cc4b1e956c94cbeda12013dbcf99a31c8579eb911171bf6f02b95e9a75ebbd255f2bee1e78fbb1524cf32afb999b4f39e3084e15b6bd4f6aca7f8cc2228ae48362e3c069426b260e0c5efab5f260f7ace2f1d29d0d9344c56b0a2232c7ad3d0dc963dd6d6bb24d956c47f8ff0dd7c5ad88bfd888de6f81cfae46096dc35739adfba6521fee79b4d74c4e3673ef9d91d26278404af9afbf26a8d8663dd722653c993ef20fb8fcb22057539f0a756d20a4a53710b3076aa90cd7c9f6deb6cd5fdf50b320685a6fde64b3e0580edeb49b63fc0038433088deeacbdba4bde5e07a1952dad8a822e4659ef39c6e32cf5f674591b939cb17db95cd73a18f3d7b4e2305d890d3d8134e78550a06b16eb84d7214748a50297dc409e7b60638878cb6c051621277c47648dd6aae6829b23f5bd6df5925d435fb5a4eb852f2bff1701c68d451760f254ec59f7fe900839afc085adb69b6d640a98c10c49d24d75046b4fe7a945248df6be5331285c42c4d714fde6fbb83cb7cc2c435b5691abee38030da34cffd895cc8231a8b39940e55437bd2856e3adbf2e48807aec2c90452e02d51731eb5eabc223d9eb47fff0fd59480648ead1b14a380bc1a0433a14ca0d815cba125b21b00e54d60aa912ceb7f4976d2a69865377a5b884e259001626303a33c302e4878fdc75be458f1ae041213e85316836f2574394002d248159b74e127012085b3043ac53637ef55ad9941802446d5c165b336a1bdf83736358ef62efca6c3f82bf0ece3ef5a69c6817748091826fee0677995584995e2b73bcd7c185e1bc88c4fb9953f61fc8c3bf3127bb3787da572dd9d99950557120ca64a09a1855d651bb6aed9cf9f791fdcbf92a742bbafedad28112787482810ac3bf3c6c14755c9bd75ad285076e50a30a232c3f6f0d7c4efd1857c239b59552819524690f8b3b3d3ab415eb36418470565248bd10657ef4b46d2b42dd769e386275fbb4ca289fd095d33a86fcaf88cbf5a374e272221b2e771b2e7f5546dade7e11616a722d5ae62d87b9ef777039977d1448e84d385eef27ad070b39a96a610c238945b530f0b1e2ec2aaad1de6c669b60aa1afa4616659de42dcfd2b7437a5952c7601e803de19fdea2564765cdef8b10d300d4df126fd8be3b0e75dcc935352b0e942723bd302f7f74b434618941b02d7872b17be9814549e72326b6b098f7dc15b4dea4806f9c713523a6c9c4166e689fc09bce2e61eab4dfcd82d0ffc0bbac3c419b56a16739d68afbeeeeee17b561c8ed1d26c4abf375e8fbefafc9f9a039bb28e4146a2a6d7a80743c92ce938c3fedf05f2addea12a470379d152eaa1be0d997797d880cda4335d325c2a8b1f4d04afd1ce667ba24c6bb66cb361b0eb97034d6a26bf02a1fbcc8f02e865299ed5cad65dcb1a3fc71966bac09633955f4834b0d9b3222176013aeeb0030b2623bafa7c2011777a6236633a719ebd6c5aa6347c9c8545dc8110668fc5f4bcb9cf070e4da0d60933f8b064271a4b70dc03e813329e421b84ef778ad98b59dedad9b1ef3e1115343100604fcb7f95b1e448639a6a35d2c0a49eafaf18a19f5d6f3c528b6a9cc14f091b19bb57643eebe1deabedcd4a20faa1f308eb88132774091dfb4a7b17c012dc9521ba4d5a0023f284abad7570645aeb798dd23863a66d02c68a91b87ad060fe813dd9894f56511ba7b40436ee063fd67109209b3d6724e4b1dbdb445c02324474399bf144302b9bd49e73f1801304a68870ddeadbee49ba227f7edd5fd288a0b936a7ac25290aa1cc57a0b90120b8eb89bf423511564b764991750a5ecf42938e854b1e4b768c61ecc871ad4eccc18d3196e15ddf3afe4bfa59a01344289a8d19133ac3b63d4e700591a3ad63b3253f6e25705585c56fad7b965732de47fa92ecdca4f0914dc1d78caecd85b6f9a71d057493cbe9cf27fa0923f642dc94b917b7ac52184f75530951fb84d9bb189c879cd75c93895ea9a8f53ee91358351a68eb4af66a07bab5e838dba00ba447642eb3568dc472a89190a2e8204c715a0475353d177f32775b7626cc2f3430dc488a4175d1a574f7be8a7f3a5c89e6ee97a73a5797907ed8c239ac3d93e299e74d01af7651cf3cc2cc9d92000edb5b91f77abf3f5da6500e04ad76ad016371779740b9cf845581ef5 +expected_shared_secret = 784ac74e14797b27f5d98bed3d61d66a017ee9ee37a5b53038820b55b130a2af + +comment = Rho leads to matrix containing zeroes +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = fb0a389191c8b5857fae399094ca8c9af399152a87ba77181926b78f2b462c92b788ac988303cb8d2a9855497543fc09c7a49055554b9a9b6d868a31fd4922907275ca978fd0a6c3790a72b438c4203641fe2bc4f5f45f492c0abfc9267fc6660f2c4581e53d6f8b57b0d89b2cc29d97aa315fc7c9ae419f38f425c45271a29a9aa3f28f5162a92e317312f218adc92b3c46b8ab8a4c598a78da54107df7720b734f58d63064088766b06fef11a95e76b2b702b3eb0aadd0a23b66429572677304b024f34a0c07c4cc02d51186e406085a90a7352cf9ab502dcb65b24881c6a86d39c49c37f77a15b1b10bda2fba45b5c6c0025452bba0233040c11103084e95c8a51b7743fcd984594208deaa223278c12d191a060ba269eb0083c00b60daa0b8169188ec35c589652bc21da1c3c21ce5b7d6fc5eba8bbbe13216497884f09a1ef04b529805a80da578d8fb3724ecc9b861a3fb457fb47678c0809eb9e24da241900903a71ff446ec4baf09305b03ca1ea1034686f533813921d7137848e962e32563c9f80cf6f564f12999b25c4826699f06fba88234b1d51b77d5583af18868ff1c78a502b414c49319461749b91398832863821381fbcb62b589fd665b78e81297d34df7b44117464dcefc863f850ab12ab338c359ec9383e4957cdbb810e7d4c73c173c23f65ddd8bbd31305d868a496a63aea62014fe21c8ed2c80e8ba56f606a6412a9a34a98c3c0219cf054755b44515d805dbe4879c0347bad7c7cbbc08380aa297623cad5029634b025141b58169c8865c206cf7232c260cf88aa91855a581b750a1ac168fe960e5ca283a1245e0b31abdaa58031b3bd51ac295850772dc0b819cbb07c66e734597f6387ced79392594723cf39c67763e3a3c2c6a009853e510bbf91c4f4b5828a91328073683120919eca166095c7bb4bba5f13b43bc8b7a991ef855399c6019e5a7a83057982e43b099016537760956304479a4a73b57bb76153f58f51d47dc7706542b64e73e00513cd838bbc9800d6b90ca304b06a31bc493035cb1d116ae17c164f8c758f5c7be580997d155b2494e3701137ac69119e47a2f145eba891839f0baa084af96d916a9a64752d4b4586c0626836f549317e4b6bdcce1196a09761928a968a4b74b611960ea2eb34bb18a964c18fb10a15319fb9468134395fef8a40a1b144fc31aa536a473ec9f809c8fa1f74f90262fbeb0b1d980be7a2970563cac92565d6af60be699ae8e692c311692d8852c0fe0426624cd9a0a1a18961a1be613b4a9a03d275e4248809f0226179410fd190c858a41abf5446b2cc3fc1815e08149d5c81c924664e2455fabc46f108259073520446b98b697c36da1602ec8135bd053cc034ee5db4b7b58ae8b59256d93a80b69c6911b14fbb68527da6a3a29a8d1c61f4d7c21f0dab9a5b266c875610437365e2a2a4e38a2e1a8835cf7237fe1483ee01ead6aaf2fb072f9200514a9709d6b4ca51019e782aa590552fec8b5ebe40a0c99ba17c57a7a460abf5ac9a4869f11c7c1bfe8b8eb0b7618895acc88b91ce273df7353b3d083cd72501d0163abab80120a317e870c0a1751600162d633a4a4373fc988ced65b6501844da162c6a4132d8e690246898e3d2a6915ecb013661fbd763a624c8c7c1672f88347d6d28ff622427b669332aa34dc590b3244029912694721551727cc36725861959ddac230b5781ce2f9b5147bbd3b70a499c0bb34c955a1245e7cb16287f357f464aa11e44eb433b6745aad46551e90935be4c5b2ed211e818480e4b32c2af84c61aaa6c01a7e16a08761d80b221772d234c68c97a3355637e3535ffec5bad36b5214a22bed5331b5ccc55e48c4a2a76d0f68759442ca54075ae0accab8f3c9746b129a152343993bc7db74a7e027a523bad3b7cae347328d64180ad396897007a098a590d98a8fc5816aa5ba805035cbc24c685441d5c754efd879c327b56a7194b5391696f0167c0677c48bc8d3701447e052829b3de6c840ce0b7b8d95b5f46695b85037232a7356c296e854842be0a48a758d34fc0d7cc2808d7908667c77a2630ae8a52c06da9215653cf41799eeb5c517f65f6d26152a656d03a685109a955811bf05b6199be9ae97fa62ee2ac65a6354200856c6538646d47f9f974289f0ad6978cb5dea000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = bada76528c6a07c80d5f8363c32338250d6ea541cf8d1177bfecbc469dfb47c28ffc75e102b25b880bdf0c8e9977f41592b24b1ccabc2e2de5f38283aa30ac51fe3b4960ab8810ae05a823b52e76f267358a56124a54fe3f8cff35dc8ef24895c83e90773733dbbbda50df879fec084be456a1250980f4ef12c78ff2b59231a944d4c4449956c635d443c92845bc747854ec6e92b0d9339684326c5adc6a07737b27a6fe207639046dbc623f531217a7d6fee0f5c8d6397d05dadcf53e43823daa7a0afceb87b718dfb46e4818f11d2c935c628ff152a0361fde8458e76475682541919b517ddcaf0eddb918c16539a8a04f81ff07827a47b5d72c92b566f4d7afd4db362c855e75dff1c0bd83bb6543332218d33e8f9e6fd38d021f961ac98525371183dbcbbd4875861d5d9cc65da0550279b8055b4bd099109e193a32b862d14faaf1534e29a4d9963e2c71eeee21b0fdf66bcca905c691cad611e4b55329a9bf8aeb55a1445fa2f6ed7782a6b3450f6aa7aaad82dd5a552f5f3d333c49f1677fb34cedcf4243cae779143fa555690402302bc47bc8d386ef9969426cb5909dc7d180a02374614b2bb46fc61988984bcb91a307c40848f7c8fb058ef2712c2bb5aa42c1027cc85f22e3ea91e59ab33cd9bdcd80de2c8ba1879ffe9a79a17948c0a27e4dea267609e96e5c84195d5b0c41178f35266df867a7d32149dedf2beee8a3f7dfa9fd91865e2a1b9e738378304884979f667055f755444c73ee53c36c21c2c9638ec9c0eb4f761a9658a494cf2213b70e9c19e5ae51a3750a34f3c78487a7736623e57e320e63162fb6f41cbe19af57aac75506d59350488368b443269b98300652412bfcf66a37ee5911d9ab94e402abc78515e5e0abe59ce7396ee77c7dfd28382494f96defd6c2d00ddc19d40f256e8656c7eee808e01dda0e04d1e13f3bcb943339934fe9ef9dc3b4a6b2d89ef7f42f9ac7a9dd446715ea4b25d14d37894ec6ed5fb8ea97a101e2a6e324989dacfc10d0634198aa65d65cd7f4e8d60021f288124a4a33bf9cf4a8e3a44c8fd44f6ff7d4fd69c645b37c5860c1f86d87c16e05e16e3e8fc84d4948f19cc8e8cce3012d94b6ee94bae5ee701d585a9af4b48c70055988235861279bbfc1663299dd6ed22a61d2542bac802ea9b0857b5afabf44008a8fd2a46d5b5f6d27be8ae9b13e4522c609f8244bf9b3049a8b49ae60445db69d72be3fa1b5d7756ba8a1fede16dc223cbe27e2d36dcf275e3e42be48a7a4a9674b71a4483d6c6b8d2dab1eb7851e089fb94fd3b18a37243828fc1f40658024200b1284c82d9e5dbbff6974d68db1c4e95532441a4deab8c2904cd5bf210dc3ba1e35073ddeb346976904062ae052c6f5edd46bcbbbae8e4197fbf8a638576618d77aa80c8d83c2365426fedbcb2c5781e08138d700ee544d07267d392b081a281408e5dfdc303dc7940c61e64aec119e0a3b1a78f7c703896d2f1d53ce7fd13245ef67d57963cb4c9231aad8464d2ca36bfa42f282234461b4023a842220c838b1fe7157223d254e0405b81536cc06a3a9f8a6f175054d31b67223fb59ca0df92c84473291e87c9b74bc5207a7fdc966dfc36e503cde19ffe7b284430a865334968c2ad1c1fbdb2951d44d18c898a26ae480f31d55b97190481d48f395e34b4571e2fa5bf83ad9b16d185f34a5b55d65ed5679775f39e63085e67217849b98b54d251b128e5c232fb3fc355a87caa3ba457cb49ee1f0ba692c875079d1cea754f6ca91d28bba83392b420135423420cb680dbeb047c45f4f7bf998c9084900448e8bcfcfcfc87a81d2b586ed4c38931175442595ffb4088ae657e66636c07fb47bf2abd0e32b3d979b1f32c2b3516b9831a57136e4783dfc081dcf8e3666544f2e3f9af6d85b2588811f3335c1260092af225572ac7722ec3a3c00f987b4ded3d1a9d278cc6151ba936fa02d66ff76ea12913db49830283890ce5b87ecb6270d71418d9c213206db87b116eb58eab2530a1bb97ff7d57546d83b32e4b351e3da6c619670974722b6d006e3c288b3a6f684b1db98938bc864433506e67de883749a3c052165720a833dbc412556ea35c437a582588d94eab42f5f7cf9f841f839c7cad07017634e70940453213638d9efed5503def0076eac37c82ecb46b194bd22c6e7db7bff4d5d75e188518d6479fcd34dda34eb70252f +expected_shared_secret = fa3ccb03eda9e8299be919496cb2581d3127472eb062a8f2447241f6b4a66d02 + +comment = Rho leads to matrix containing zeroes +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 26c5792a30b2ce4856623898d79ba97c3076e54100eb7029df333b5190cb28a8207a557cf78cb88c11b241da951ea96dbeccc90029845c7c8071f584095923266964179910a64c835045922fd520535b35869a147616970424835e913ad8382faae3b756aa51d65306c6b6760cc3aaeb7958b531293e6a6daf0382db834fc7e16811643692ba162db4266e3b2af1dc9227aa7edb2a545b8785e425bbd982cbec02514924844da57e3740881ae68d9c104afc33a8c27782c658bbbff5ab1da73ae2ba267326ad3ad61183e792075033b448a36ab3bd8e8429f9cabd5e3a57f45464487871a02bca6752311d607701b89aac021649f37ccac9a455017495129a45a6b24f07726c0b633c7a333a2c589967c85e7376929205d6291a74335a89381a4b851bf758cfc069be95847da5d6258123bdbae08fe0b39d55c11044d1c8a6d70421333ebd91bec10b73532a6c00e090027b3480e796e69209bfea7f3945350747af2534234fb0801ce11c73b934391b0f7c6574d8c8c8086151f8817bb2082724c733d44837fc7c24355c463bdc0365b8a0a2b15f63ab15f42c6635a40c6d8a502d5000a6b7158a16cbca964363a4c7f9da5d51c2289d7342d885bcfca1123c324e36273fce5c4be83c343e84914ac382fff92869dc11fe80824de3b745e68f55bbc979a0759a35cd91a75a7c649bbf7999d8726134d75691dc7d25b23cb5d16f0d505e6e145f84a4644536827ff982b5b9326324132edb30e02a611aecb749685069baade2545d758aba6c5220bb244e08d01235faa1fd5a0cc4612139466d6ab26093a22c428252bf8491a6794728ecaf421286c2ac5f4117b16d145977c4232f8564fcc5996de99b71f896b5d828105c593fa43ebaa2cd74712d769814d490aa7e2140f942b6e86b734c32bc79187f6275b9da3bc621ab152c8a6148a9327a549727ba02a9a1465b3b9a32d7cf6984c610691061e9c8a55badc65503158bb637ca4c55775649caac535c345a443b27e88e3b0c435dc33aebd5087635be061a37f3a0715c37b0b351681614bae36460c5a34eb7e763af22955167b85542519700511c843e56476f0a977a5a720aef292e0ff94d726a958a63cca8665fc9a943d235a569da3e2a4b5964d457df1243771504fd26527b94aba0e8b547207861b8cfb79bc6abe3054184922d477840a4c221b420af50608a265eb508a651dacdbad403484b59ef9a819466c66c458d172622609065a424024811b26b61b74b8c0adb179d2dbb7cf4e336677132052b1b7a6c6eadf63a15b484a3240c7bb1c9e1160dd6832c727044c012936ea43eee4ba721c489d6b8a6fcc2bcd3c3ac8121455c845978364148bbc9498542ac093a4d1b7a6a666d0276adb218315afb4683d6956459833915862e18056f7c02f9a492388a1fc65c5211e7742cc656bf2a82cc727fe3516288986da5e4b74ed8abda8084aa90285a86a275f8a18fa99934e73f88f42aa6ea3428b6a9d936af53438e51423a9222b81ce7b27d7b015ff06ef98ac62843703b9828f4a0c71a603b591888df2339c8c5b8922a2ba8ea1a85a6163d5205824056176b2cb150bb544667635788338919c21578faf64ca0c980e5a554f1935410b36b5f29b110121c35424cf52cbceb53134f7569594b0677db53f97b570f842a1d27c3e0971343baa872bb2453799b1e5b433a2361d2f1931c185f13cbc0a0e1ab1fb310f4664d8a49289d15433742aa439483d8789a25c2ae77a3689a17807fd544ff4c7d022c42ec9049e683472b490bc7dc8c9766983e32a2620a611da65583479fdb7670d329c33d51af50dc3234e63bfc1306913c66c587b9e3a23143824e84227505b0b34a3399746554bc6037f87b84b0a7a41da3b366578fd6d79cc9a03d34a227e8095b9bca636ae01988dc2dd67722a5db934c7009f812a985598e7e309cd7015d24a5b36cab65e8f91c233474e1473fef76828f2b245231605d079b308a732553600b549314784690d5ab5830c36d824b68881d6a440696d3938f328bd755cb833a8af037a4bf8241c5d9aba41540a015aa0b110410a05e104881f5e41471e70029a9c42ed2aa4e3a5012a7aca6db06b7a847ae624ff7e941ee18bcfce68c58a8c47db56bcbf60701858e26943cffa53661c180a3ba0bfb25524bd6000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = ef250a35ec80dbfe58ffbc7f7f0a97ee1e77dbbb601ef38a8599fe1c50621a7fafb3c2f42b8dc17058d2c5cbf965d1dc6e45fe0f033b1e42326d024ec27eddd00f4af75ae389b6e2b95076862e11c63136698eaae4a9735ddad9613af997976cfae920dc0a08b9bdbcfe7fb168d5712c7d372fa29a656adeefb3cdf8775cbf38ae0134bc024dcbff32ff2575911a98bc19e7ba3b8fa7e5a1df85bbb4bda21427195206a07a1f8ca8b2550fbb9724df204be3cd5f3231da0211d79900cea59a6e394915d208eadba3feb264964e269bbcae99bf7d8caeefc00976687ed7ba1a693008aca00f0e9641293f75fff8e7169e6e149e6695003c544b946898f466a0cfe7a2ec2b531e771094787c75c05712b6b27e55f1fd3ee3bf4230c05059d83eaaa2ddbd4e9fbdc8fd4e694f17a5a634daaae4c125e1373e8103a1feb119a5a6bbbe7d722427182e867e6bf051653d28ba59f68d52271a29bd109b4b55bef30940bdffe931cca17e2add03a2e808c4c2b09cc4978cd89c078abbd1b3a0919421c0e86f1294f07f5c9ae8c6f66369702aece6f1a368dac179a64aac92d445c9a606103b48e2778237178e407de8d576e5931d123caba6f99bbe158ad4878c5dc78bce1c519f5690b12b5421607d5819d36c5bded5a23c46578e564b1c341e47953b80db58830ccbf40edfebd6bd92b99cda2c62c0d3117f5e84f9f7b8dd6871d045c4cb287e689e865a9d1d1f0b0feeab1ff86adcd1952261d94a994869d33cd083e28f158b918f22f0b8a1fc4cc79d800c38ed0d9f746c3b506e6ccd58224886083cee785b1b1ab19eba46e706e8e89abfa36ded66bb7a180250202dea8366b4695434c81f02e0ab5c4cd40451cf5242fe95af132191a89d653550cb76505cf5792efa6c8f074801ee54ae10a36d75160891fc2a670f1f7f1cd628645980376999d86aec88d3ab55a06d987ee62ab7feffee85f8dd7bb925e3a60c8b4c63dea64777e3dfd19eff0c42371820aa81e451b50e6183e762798270a20e94f11efa43ae958f283e05d20faea378d9e94f57c32c47755c400c4a6f17a94e28ccc0455726e309d1b65d920b185ec129088071f557cbaa3372c9bc56d16ad33fb592d8af9076920ede91e6ce659f76b6f8dee15b1ca5a5ef9e5b20e7a136db652c095c883a5cc638a79fe5dea351a485ca8ac83373dea459073528d138da4eb895cd201d88b8c1dafd0d344a430495632e82044b4bfa73237857b5bb2e260a6bb2c7583fb49826ec08cbdf60128677ff1f0c44aa55901b5b9c4eaa6defabd1f6633ecab01cc0a79229ebc22c7451d81846844d229fa74c0f9da3bbd8135630f2311341929c146e7221af95c8f569858f113f32773a8d3cd10f71bb962364279a023518daf7e9a53778c228dcbdab239917a4f963dd221b00a940dc1a1aab798820aba5005b7d80cc84c18e91b6087c7c966015cbb22c30ba409e5fd93d4bd843b35572a8a629e9e2713659ce0b893f1c995f1e61d502b50a62f166f2f3bbefbb534ac139580fd56acfbd232dc507065830377cfecd3bbb377b72450fb615c7971acf1548a2abc79fce191d1be1acc15a8102b50923a8e596537eafdae404d546a90e444e47e04aa6a7d529ce6c74710ea4f8140b3bf7fd8a468aa8b96445b413c9bb19d057bde4ceb98a537f736c9deebcdedfc58c9d5ebdbcdd975b762a20d6264016cfb8bcb57ffc4bad83a5b997ba6263ff34270c10eaf932f85f5cf10cc2ddeb3344ba5dd654eebd67008c3161e4c9f79680c375b2e8b031bbd1293e22323abea7bb04f9eae988c8a9a9d9e7f27cb1f87eeeb5151566e8d22db6389119d33cfae07f1bbaf14a48f0c082e325f2e8d397bcf3a676666e7c2edc85727da4729c1d15b4b820853ef49434372ec50c8d207ff252cefe875f5971a6b102b661d150a782e55019d9761728b752e208bd740fd148e9ed06d872ebfde0489315c46a62ebc6c0a5ff5cd57eadec362a2d8cf87492f557abce463e100e6df8981573e54358c3996209b8758dffea3847eccb6aeeb5c3c5471167e1aeaf6f9a660cd281ed06ff4fa11cc88e04b162e72222c4fac1081a9f991be6c4ca4b1ae02de3b514692b8c144ddf40720c1e1394b38c879c382861bb2285a28975c26a6c1fb4e542794a8e654faf918f79ebba577c5cedf72431ba7d18cdb0da6e90edc2cdb85175fffe80dbe7 +expected_shared_secret = cc0c70663e64be7264620b5682f2506f2084b66faf8e8d3916c8b77fafa924dd + +comment = Rho leads to matrix containing zeroes +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 2fb1b863185bc7a3bd95b15f041c8e3aab5b08d6c32cac121cf003161c05c64b1d90074090605731b5c6c465675ad846cd99cf3fa08f7aa45448fb2fc802529bd69e95d1a21e98242c66266290bfbbb2ba58fb320d660e297ac416b2b0d1c5968b53a95172450598ba30b96472d14522513caf0332c8eb8f846bba02870ac989594f9141d56813a68aa5cc43666202038c29621eb658911027663aa0155262cd86798079a257621ab73a8489fc531f41c1483582a1c92cbc6b329fd09913b1a6c5fa0b3f7116a9866290d4b321cb639f544b0db81a6177212b798f911b0786849b17259232ea74a9963a85d90aa8636a9f4746f7b8ce423a374039907591a54a503f9298b486e907f2d93d1a2868a1d47608a6aad83c1ce7d216dc0283ad56426d7b5cdfba794ffbc3654235501c960b8c9613eb6126d1929c55c1e7cb8cffb180e0d942e199b4bd51721465ba8de1cabb081f1f55218a86cbf6b7ae038421b5278f2d8086041480ea9898880a84ad25ba631b83e953598bc76ec9b36b92a76359fa1e44209139272fb0c9c5c5f0af6a0cac4d4529d18b8070e76b8b173085c12d84bb2bc4eab464a161f5ea69e0318d3719249d112cabf827ef4a4a7c813d384b62c02c608c0b49dfdbb6f34c4ca8db3dd19142e5c53e3d17010f931d0f9c8657551deeb53516149b459238657295cb5c66dd6466f9c1ab7b711ad985a93a46b94f2aa2030405f0b013e12bbd380a6ed98840c1f484ed5c5ef9401880f646f424c052f20278139fecc3a3dfeb7c3cf99979f8b8c6c77eb4d20d9deabcb0648fd07bce67738800a2415f3722595c4267f7a743f5562b1a26ac168602a84b6864bfdc770ebd792543455055a6055117cdbbb6cbec340b69493c7f0648ece7119b8bcadc3282e5a8b0a21b1898fb20781c298ccb750eab8bc9abb3330276639bafc2d9c00315c690593c67896b83d63356e81cd4624c4f39591cac40ac49425af7a5058a651eb4800094b0a32778ebc025910b0e69450cd0657c296c986fc9559b1c3d0a605754b266f0f28a8d5470155906331693e425896a7644d6f340b0ecb4cd2268b536b54a38431e69852d7c443ef97db319879d1b7147411db40a0d7ce7cd358463d8c5be972ba5add85b4f6a47b6e59b58312dc0500457a1a578c93ca9356354834599c41a2853c53d6739be379b9c669e7ff7460a29a2e5126e90902b22a29446b3275dec3d891852c3d3175d8bb3526466a662a163095b8c3587fac94dfb78cf1f3968ba9888f790cd8d7338b2c0b55c12a91a32381fb2427227aa66935cb0a07575c726ba16c92275370fb849aa548967a1077cd2801b858111761230544184883ce385541acb0033f0a5bfbc6779506f7f0063fd5b3136232302b46fbef8c94cf384fe50a97d24a67608bab6299d1de88189b612a43b897c612e9f44a0451588ce9c319b9107fa3c1188986869fa0fa43c248c91c4ba5ca3bbe31c3fe4a5c3147914234aca96b0a58c52288b174aaa5c9b156bff3ace0604aab391411204714ed067e03b38b6654dff57354a311653c40e70017df6b3bb2813a19bd2b128a5001a38a7698386e7f5ba1eac57e183034133cc83a152bbf0b321dc5a4cab8cad524eec35783e93956cd59e1755773f321ae6427b53c33cc91c920448bd7734b57672c9744164b22c9bd0c6258dcbc5fe22b947f6bce1b156967b65b1910c0c57b3076148a627a74f5a42342cca8d757cbf227adba4cb954a562ecc9557c45b76e83a88f9472ba8a4c6a0b670952f173c85e0d033ed74a48445670830c493c8c89b321b26a1c87db34707e5a21bc7644bfac385690fbbb63db72b2de6f684c68b494a461d62f19d0580bca25a878e5077e8617f69c446da1ca1ca81adbc8a6a4055b0bbd2138be99617c9463c873b7a0a8d13f8c228663730171c19462fdf02a164ccce14e53c8cf3baac96af911b328eea6e89d91bfdac72fbb1846e6b071bf7929d486363bb66cdc24e5fc93965e3ccc6f5ac2692087eeb884ed6206c924c0b1952da48a84d919805a7bbbdfc578dfc08020b0ef5e4a49d013a66ab449ed91c3f8390b2f2a7461123ee3b6cbf965e71b824c808ce142995fbfb6f9b0213b0b83c330281a26cac93f94f32c30bc22a13ea8337497b408a0ba3aabbb1c7c48225cc000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = b9cc6d4403baa088e562753c1a21c66f1e9ec19efde0365ee8e696bcf2d1e68ff6acde8394205be0269f2cb9bdb974660c8041dea23912b0a154dbd31792e2495b4cfdd1c772b12398b279ae755af3c525c700620e8a30d9bd54a062d8f64b029dfeea3d13ef53f820b71c911eada200b3f90d019a6430d382c187228cd85dd229ec0dc125b0643709486535907d69d11ecfa15b9be98674e3e49c25510b889052d0f53dc225def026fd7ea783093f16463ae4b4f0e1ddac026cd9e00db7b168fe0b9e3a87db01185ff52443ee1cd51a89ffdee88f476de7641b31e44446d8db73991a6b491017ccf55bcef6d6d2b6be1f69f789c545fe233e09da0d5137727b4e7b437c57a12dcfd26fdbe8ded090630ad6be805aba4c4230daedc645616cce15662491117feab609c89d61e0d7bdca2660d7f36dac259e4a100efc4130870f0c2bcf64137b43b7695a1a8790b365aa3ced0738c9e1d170860dfd3229145818ce8cc786e60b1d3b159fdb9dd8af4a2c8002b24c30be007233eb5fffce3ece5f8fef18286851f89b0d741cc2bcb4f8099e5d7c31034d7a3634eb7503b93fc9135c2774127ea1d30261037bb18061fa97fd44adb8fe69ba85e520f3930ce991d74ab849d0af667b6984b398e6b392648b0272045889df3f1f47a17361ef2afa15fc15acab23d4541519f0a8de6d9a82dc3daebcb242706dba34408e4fef0fb03ac7be98b331c9969e738e2e4b4ede9ce70f59ebebd3b9afa9224623aed04721688f8332b1a214c2c8f39f76ba631591f9fb162d867cca0c65041ab7d4ad9355210084813d8beec36783a2f0456074e35d43014d44d8254970f8e279b5e2d7762e7a51937f32b50eb140ad9ceb23bd8101e0e9edc34c579249bff46251139eb54ce0e533ea720c4bf3ff7a73793d83d94c4e2fb17745c18df2ef1109ab6561dc91669600d046dd1e9d6ee68b6fa5b16fb2bff887f4aff76e5bfa6f2352da18312080b62f09322211b54e7ac1a382ab2de1b6e2b2bc0bf15ed700415ef319405fc5946bbece863dcb0728ffbbebba11ca578293f0a1886f53460685e778abe01bf1df7d8babe44bd48b0cc6f69e1d4389e77049694221008b73a8da2761ed862d0127d8ba8f6e4f7d3057c3e32059ab1bb762038ffca50fcf2693d78127b2a65c335905e1fd6deaa5bbd14b350b8afe18c00cc0d4a4271401fe78cda6b89c6381e566c69bc5922bb6a43c10968d754703b5602c93e6f21b1b7432170ea5e62eb4e0c0abe6f6a3317b19e19b5763f8bfbf74f4a910e5d271062fa79fa9682baa5fd0b9db3a5f2a069fdd10aade60a618dffe2ffb2a89bab137cfb73e92a774f57606a30080cb1bdcba5dc6536e70b745161017639187a7a495e93fdc48bc24bc565f603484127ccf13f74130b8466973548b1157709c9d6ddf672efbee69a4223f164f8309cee7d9660a323f834bead26a7cf668fc3e033b68c7abf3ed0e4109ec9e263efd07b3b1bb0ab26899067971158d0cd9ff7f91eedea7c4b7e88728a1177087653bd6517d11c490d9dffefa52d4f09284921edc23b5230c109d3697c881121db8b85e1fb7c2b9cd2fb48db52f18a51374b7e4a6220e8a50d82809c6666b5ae854c2848bf5881cf834ee44171d26b0c0296477b4299b38af261f9ca6620b57fcf276ec790e47b778cadf00fede43d03e70d6518cfbd6581fcf84e81aeb3bba3bc7ab26e562b65e1599d4e8ee7a23992c5039d612855c90dba4c90cd3231d01ed150b8226a95cb87867a2358f11890914a2016c78ffbd31e7ddfb1dd97f2e0e01e3010d6633952d7c16c1755594868702215cd917b315a54f35f92f52bad10b3a7e54df657dd7e168eb8119b28507cac71867180e0914d39b8441b3c5c20ac22ffcb0ca2b201e4b350debd73a0c08b37fcd13a3957d96476d31d26153e7b4bfbb826f7ddd5b2a7d29183a579f05fb36d459026963ed9a694fbbd9b3ac3c5e2be41336b48ff5af60d9c6030dc13981585426d3a0a946b5008ff5cb3fbaae3bc491f536dd80e747f5df92270ba40502409d9b24307d775f4ef7c9c06dca69cb5dfb4d0fb890a816a7b50bebd1ae9e55ced79dc36bcfe04ab83fb2f94e10910f0086e0b5bcac717c5bc73f5e03f09ec94c3bfe05d732fcfe0d6baef66064cdb02b49eb5d938d2b9bb077b5426905865b170590f8ae3a50f823c9f56fd3b390fea9 +expected_shared_secret = 5772134d07e1befd82268588f722bcbc7c131d7bac8921fd55d7bf5201074bf3 + +comment = Rho leads to non invertable matrix +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 86d0a6739947e5cb25b2b10d9573429894601c1891ba3c78f2814e1273c8d2098f19172853b3b590487397692ecd3b6e37f58875b60167fc208e6b813e0b26e1b42b7af60a64aabfc156346c78a225738983a03253d679437504740b872128949d971c619031b51090f54abf0ba2cec479a671d43ddb33c430c8056fa37768f8551ffac4682cbc4755267f7736c3c97002356edd676e0f26c2c0f80bbb04c26a09bc337bcdeb68bf25d183dacc4d17cc68cb8b967b31692b2b6a035c69460bb202937d7ca92cd87651bd7804a1d24826c3be2232310db3cb08ba900ebc4f5bc4052dea72e272596f6373b97aab10e8b9ef713550d9cfd3610432b6710130ab394830bdd4129e0232263bcddccb1dcf9a4f023865f24bad1080c207e02af3b56f2eb1356ae45466a61905807a5156958782b02ee86f69dc3ae5e2b23b8a01e6e30471a7c85eb18216d751645a893ea169f661230d1887e77256a4944004b8415a3bb554e436ed2004f30a19c6099a573ba752f2527e59b00ff8943cc65caf4ac07721c702e05d5ab2970ae55ba7f8a1335aafd7542630f933dc7420cd054bbae009645231a1362c74252e649844f413ac83e544578903c310af5660cbf3e4c4e1b4917eb2a0a8bac4be184341629d0c9b3b1cf38b936828abc520a3c13333c0c2c1c35185028bf1f791fc24a1ba12c49b252ce82c16085623984368269b6dce933410f5b6bf61c13388bfdd87c0b547690d3cb2910b05707865f9ac3c1872a7cde62d2ca43fc391af8328bb5c853c1f1cc06c165394874405734746874a84b2261b5032bf586fe9939a0ccc980724759582669f646406097270e2cc1371b0b6d81e575b5170760004f593a0c377c59b1705bba52eac083cc597a2d03510e8a0bee8c5e39546f193cd8e4083a3683602cb1ddae257b1c1bfc409942d2abac0586e63f3721b4bb921e135759b1efff0306105a71275388ad69c75c5056fdb443e3c708a8a107ba0cae4955e2ae7a310d97a6063690e5c8ba84891e0a9c62eb983578ac0c6a56b710a2d63305d931293ed42887284904c3cc4e1418a9c77b8158916bd028f1272518c0917b7f4b457fb09a31b63bcc9278b529cc98c4351436e02e30b639562c14131f4e7903136157269235508a7aba15519f911fe061d9bdb7b63dc91539428bf1c72861305deb39ee8e226cff39e448a9cd7e50589f85430655d0d027405d991cf1c2aefa28d83d5c7ec8994cdf39ed49b5cef917c55f0136a1a9d8cb38715cc0785d5cf5f9c5db452798348c70c52b5fd89a7fab54b75d22c6958af84bacb21621694d492fb90b71c787e9fac0ac9e3c710739d67598b8dd6428bc2ae26218eedcc4d9015363f8acd9ff043d0f7105bc7c75eb9c376da757f1b9aa2378da73a7a6e4571eda670b8287f4a333412a9c94ca39bba9759bca1c2e4649bae51b1cc10913e0cafc8575629ac866a729674772a16660c1aa53a77f002e4136455da31ec28121a7577150cb3fa0ca2c0d8b6985543d7f90eabf2bf4b85a3efeac5d0b28f70e93dd08073a5529b41ba4e2c736fe3e0192794b00fba1d429498560b2eddb788ac274c06f43ba9da341fc52cb2f5755ce3c1af65027c143f106b587a1b6f18201d9c3b0f19e4b005076834d7830911c449aa913dc6a3ef31c208d014b41ca6ef1b12a796be561b006630c14c03504f87c600ddc20c6477b5b02c5bd337f56a9423f516812a594fd4b2e794442bc8057899aae012c320b64eccda7681274adb72101ec41f99d63648763158323c753b0acec97d96cac9dd35924ba1c0555b09a3ea95d513b138a444bee8608c7ac1e64240d15028cae552855c47beb0c9f6f10cb4a3b9f68c3552a301b6a8cfb9487c241964c4e167e2c1b158a6b1a7c303c0e38fa7e0c53b376b5ee5222cb574d72734e7e90b531aa4ec656160f5a23f6b3bb2e3c72a453f73ac96ebdb128dbb8442b5c7ea842fba805799c811afebaa4bda82b559c624322aabf5a3910a152d5b8402f33ca0176fa5600b8d358d6f5956fe6171cb841ccde5bc76a27550878b5e065364139cb891065467c630d8a8ec6a002626c25c8aa00bba4be3c2305f0b1b18e79dd1a8475d2001324c898c0a43075a7c06697c2ec6baa4d78258e60297081869503b7084aa73756b74776af98b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = a64e4169d49c70374a2c237a33ac42503c6ddc7239c53aed99ed033992435ad443153362ad3c9cbdb576fea6b87ae15bac3f70c457f5e84bd387f358dde9c5a904db99386d2f5cfdb29454c978a89083c9095b2a2ea1fbe220ed78cf34747528e7559c6b6f6eb168e878046afb0526bef2f966fc80a863ed6e138d6ef2272ff9dd49201d746f82db8122247a3921a058fa62a03f259284177d518538972fb8e3d83c4644c8ca3377801c719f55277894e1d2170719782c6b136b7612eace3f903cd5c5a98f001b2c8e351b0a3f24d48df4b3f639b749c3771d38dfb69c586c44477195853255fd8d36cdcb867c8d4033e5d48a9bae96ce2d839311a5620af3dc42d35126f222b9552e1c36ab21c461cbc7ecfc6eecab244cad16ed8b48cc056ae98b4a0b93c1db5b5976a40a4b5bf58ab01c2a32e045f3db5c5ac00d3d04718c796895a2690b126120222a786520de726b43fa40eaed49f7e86dbae56c7c1d782254277f438db81e56236535b36a1c02c54dfb3974d1ac1f6c814e2fb890fb3c1364d1544e87aef84e3ee3e47e6ee32160393f9610c5ab33ab9e1b49aee4bc8c91bdcf79fd831fb651dd80bd0cd9cc439c811b736337b5ac64d61e6eb1abda5dc67e694f2350a92422faeb7774755fb8bafd5c091b634d229ebae35e3bf93c6f1d79f54c7cb6cb249a589a6dad72a4551b32e1463dce1f50e636b60b70648b81ea9febcf79a3fc8ff35ccafedb3bfd48fccef6e6fa5bfcb44a2fda45ce7df150b9639a9615a936ba1c2fe0c6f2f660cc820b414da22a3dbf9e8139ab3a0c5c0946dbba66a02e2c5febc88d46e6f79d0e669e60fc8f6df1d346aa9caf90c16505886b48a0c6fb41883c93b6e8d307b97f1ae01e5e4af5b9be506dc4a8bea249f50141accce764e85e9121a7cd087b26f5d248113ac7b97517d575bb505fe6048df915fb5e0cf304d636d4767042c609ac823d9d2812b9cdf4207bfb3bd477ec047c1987162e250d2bb57791d1b84b4341bf55f0f93afd75abbc90cbb23e47dde24583d1acb6720e1722231f9b103b0a7d454182b6eec57eb1e4a64fe7c92133302c22d941a0b17e86adc350b47650cc7a1a953b78fb1a80aa44735b3623d2da25ed5691065a467ef15a3dda917d80c1d47f2542a0afc383e75b0e955ca530d61df1aac8da5f1ed8297a6b5fcf950f6cff8521a7096ec2391669742087139cb5665cdf525c7c8f157af19779156beb2fd39c34ac614d2b0a91d87b050f64aeaff74bd894d3a68c1a52da47a42ba04d06debc14d9d82e9bd94aeede4a35b6bee9732bae0f76e9d07f742a430441b9d8af5edfc290a6f30050841c5921084d7df1ecbf8b70637090cfa784d5214839977eba9ca94f3432f47bbc4d60c465edfc7a931e7f569da5e6b4dda05913f7fb67263cd939b15d7a8f7c0d15b2c9c50dfee128ab50821b3fb9b724b643a9464b0ca38d51c751d8d4fe5e378339c9f68d51a245fc0ae76ba14d9539a90e3174199f503231d7bbed22f977b37a34596cc8a3207b852d6b09e254d7aea868b29c6506881644f493eb41875d6c51218b7d79f7f1202c0ae747694403da054128aaab773e092c04a2c34f4a73fba19d99df3a81e4e60c1635f0b34b0a5fd7d0e5a5a236033fea303e819da88131223fee2064e5981d596d30ccd7b744e183bbbb58bbc7c84d4ca59cbe1f52e2739fac45fcd0a706a1123584167946169c3494ac911a02deeea2b487f5d57c4429210cf812f90eacadb7d51ac65a6dc49f9e51ac3b4650bda7966eec378df60e5c98723bcf7cd63d65a93569be54d17a54df9502f9b6b9f6deb46acc37da4451883f7ca49d4075d045296012b6f2584c972c087bf948fe7d9f0fb561dfd91c3e64f8190ba77202331e5988aa9d5df9499eee4119fadbe2b5530233d6873bac60c5da33f4f0de0262eea35b2041c3864731c3a3fcd9aadadd6eadfa55249dbb5a8b63d4c6f69ecfaa9dcdd293b7e85a3062b53e7350141ff7f6d622a1f4978ffbe22bad117aeaa425568cea246d0da900568c70a412fcca2fecd427d14d59ed0867b6905adff8cb33bbf33743378d4a2d0ccbf79e721d22d4c1a9921e296640639a5dcecd93a1ef94a06b25af0628a32647127c10c504f77ea6ecd31c2a035e8baf3fbb1434c59d28d25221c6d71cd063e3d6000130ba62163566e2f8ace8e2031a530787c4c9b25856 +expected_shared_secret = bb7c4b5d4fe3d2e310f176eda060f614672dd307e94766a8043b914e9f3e5c25 + +comment = Rho leads to non invertable matrix +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 8eb82cca6371fcf0392e359ee7d96badf47a3a46aca01aa9ee8816ed4939a8da1c7a6cc0c78a2c74dcc482aa9b0f27234d1a418b994fcdd4864ec208e423b97c98ad541878794770730c4e1662ac60a1140a6aa9fe425fcf9098cf9592725712fd995a952a73b0f8c4c312a1ba498d3bd9c742cb7f011216bc816e6cb13324c17a060361b01551692a7456a46c76c994ed067d102947f674b918e5c924c86a5e6172b0f1ad8e7336409cbe7b16afbc48aadfc4a77bc22ea467a2cdc9350313af150a9eea3775a78b45d743afbb33bf2ae2bebb19b800eb18e59a74d79197d8e36f74790645e77d2ec46a5df081bff73ecd31c0cbab6275710206fab518230aa749cd4f5099a304017e937a264010620b80f1d0c7244480736ccc623c8a2d7938de85411d7acb1ea00cc8298d85a5443ee058505b5aa3d88ffb3900567a31a9b25a3082035f5c037e571aa832672a74961e51290cfb0b55843229d11213d18feec5a35ff2160480887ff03c16c5a35e367fb6f5561ea266e973928e3b1304d13b3924be68855cebdc8bd0c3511503ab8e50c828b04ef2934c41207c725c8f1d589956e259a9f3120d6392851469b7fa49b8452389eb2de3497586ab043448c14a13310ab5b352a740bd486e31f0655dd472dc3b3208d06a79cb0dceca7c2efc8cee019c023232342810e3448b5d019859da0ee25526b81422f884438547386c3c38dd707e9ae18b27838556d2398b827dcbac8344c7cea904640f9608c82b4b86d27b3f4ca4882c6da694bc78bbaa08c900abb62379eb00f2ba692b167264802d47d74ab3671620194555b8249857996a25bf8b44892914cce1433685ab210f92253e00a355b96d6716af32e6629cb26771f57c4ea7cc80476d3af5a851f191f35ab646961780e35d6ff449e3b258b57375c8a43718f05262c274344c95ad251ae8619cc6714efa12ac9999b085390fb684c03028615063ae5f472962d49dbe7a65e248152bc73476026cab06733fb57182c9c539553b223b31adc966c8e41cb0e9847236c38ca67c13966c915a9b04088c72d15ad221950e65309a2bad8a58693168b5e7d7be403137f4130f8e911aed444c84e469f98228a55a2c2c22c0061861d866aacad343ba3590145424ae886b52c862cd0036eebb6fd1e33cdc957e2370ae8b42c2c7eab508540a72698810533bdd7a1739e88255e86c8752974986bf36d889fc172d9c434ef3d079697204b778117f1acb520c63462c07679347c4604c78f5acc99cc58c245490250c811bcec2d2184cac261263581769044a232dce38c6802c359e154119c4874fd95bcaa5a67eb4c8c3a5104f15962a725e5ac34e0dd363f5aa667a22268afc4c382a7968017331f4cafa6b76999640283ab672985a27dca0d39c4b7ab102fef1863b06b67d9bc01b8040e1156468960f1213b365d2ab2a877468851fb627b1ed7154c6b83e7f62ccd65ac410e8c97adcc6e37c3b5d7893efd6b2a0b995aaa9171391292aba405b051f5125c8978a15fc479a55ac296d7c278ce5a3724535c91209e1e90cb113423d27845c95aa1258afc49a43532ab873f2a6d967796421a8da73cb2acb14c3981bcab14d1c7647735b25de0ba346bb61acdb8be7f513ce561adea73d19c34d41d12499e8a843943bd21610e3749cddb25d0fe0959f8c0559f774d5ba347c30430684b7535302e4daa90535840cfc9263fb126d23cbe85a43404050eae4badd99a0a1c24e1a2b4df41c8a8593a6763b31a4642830e797541b3ffac28bd7b7a496053fb1e0b4002433dfd705251900a636b7cbe3858874bb9585715bbcbb74dc992f4a5636fa62c2a56989529f7de46bf10845e9e9c03d282261715c7b7c97b4786387411cfe36565c2159903959444c68a0726fbc5a13468714b92cc3f953966fc3bdc3cb1f606a5548e4bbabe2755c56a35664394fec77d9f0646ac5736903a537d29bc6e905bfb5650cea3a5ae0145605c0d81191fba11da630b5c6c866cd09681ff16950b495b9aa6843141236b079ec67cca7c554fba14e534bca50590c1bf40ad5403a1c12578337b55a684038d4046f2c8d4be864c2025cf182592871909e824c24815fe1e206e37001022ab475481c56464a1d258997887c49a052b43108f6b7b8b50271eba002c3d881b4025cdd3b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 2c2a21b05890062fab5c11d3d55b8e032fbb07ff61ba147998ad1a4d200fd8fb17defce7723b268150ba8ce7a4d9a3548538e2606377e91658440e10b048c8c4e42289a17f398a664986dbe522ba68f42b14f40f25be762aea2049c9444dfbddfe416c04ca7139471f185a441a515e0d08fa24991e9f02d37520749499266d2d5980f35356c86dab927c39d9276aa745f4f9d1cb33c386faaf84ab03a67e42fccc7eee3818254b7799bf445a491b1f4bc64de499ac4171def329cc94f0c4b0ffcd6ccf9b140c776993ce1a0241d8113c67d852c24a0e4e070ccdbada47e953cf65146087476d1b0dc53c039427f1ad7b466304a4f4b2757f661bae492960f667ac439e3d8d4595d7da06367e69015df630a7292b0dbfcbe2629808ca08e3ade11185ded915fb0f5c599417d2d2c9fe742db9535ce90e49d2e70cb83b29490de8db042530e16d3d35b488ab1693ab4d9642740394fcf6b34d74ed47a16cd2e6dfa80a94eb1261ee6391687ba0bd60ec124cb1c3785c2143b48b6ae5c2a109169a974599daf0c682e1bd74c7fe7b3b76fbd5347750755195f73af0a5ddc35c7415302f34f331fd976a84426c3f1b0bdbbd0fca925e7b2e9f78e77571c761f896ed51b66bd9d8d4dcdb5a8d28c382f322dca57bbf1bd6a4131f162f4d8c0983a0140a3bca10d947efd93774edb8b4d0cab98e83ca40a327d68c8cf5fe4b48583d04612bf65e61f00a4a56a63fadeb321a033ad5f7b65540d74ffd144495ccfdfcd4afa7739811590e4d7357a9f80732cd0ca6355c31eba16fc0671de573de5c73d43999477bf383e35387db6b9e236850cc5a286d5a93e9906b6c53bbb822a43a59a3b47676d30d4c8c4665d73fb275ca0dd493afb80aae9e503518ad8c7cd5486ac10ee2ed63913fa20c4e3ad6231b39ce07256f0e8ab72a8281db22ff9f8c2c655209ccddaccc1752f63b1967b218a872a36f84f5fa46064173f44f4a0133771abf6183923eb11b7676ef55726f62689b4695fa39130718c21145dbb8979566dcde5197bc3ed8381e4bdbbb881998a60a772811c50babd1f7811def20ce5fe1937a28ca433116d6c85d5e8046c7b7640ce5b7ce5e3c11e13c2afcf6c20a633abf9e4b3d6323b71acae281ba73d00d9da20292fd6e6042dcfe154f22b308e78ac3decac8afec89ff500534e6e789459b42358221b37e180d3e0aad911d35d381732682c2b5a50f29d41e7b21f7958ace59f56fc1ae6de40bc26a78ab022b5998c324340e95aa424677d2cfec90ec8785339d20859687272bdb581b29ed49a5463be54770a17ab25214806e9acdcd650d9007f4075659271c3b288c9a6a8a7e8291103d2b750c7c088637a733fbddc39cf0f0a9dd6d9dfa6102d12c5dedefd12ca43e43e807635993be1495c18be1c90f3a620074b86655c40b904c1bd97526d7b70364a2af22ae002844c6741ea35263f08d6be51a6f1c039b52dc08c89b45db2c4091c55b3ea13f28494dc0c131aefda9d3b111cbd1df48eb51f68db738d31e73b03799a57bbbff09a0018ee684b6502422edbb80022498ef6e26065bf5ac7e4992766fef1548bbe43ee1cf9335fdd154a6731cddb9d50165d28a62774f23a8f4cfb381a71e488cebb6eb4f23d97a6f6e3dadfd0ab3e146d0873738f1e3f9ac9f6ac38ad1566dd5d33e263cae86e9162bfaf0de296cbd8508ce6e1d553ec6d8915e69ecd0d460a9d839f66aca1481bb17938c25e6c1839ccfa09e5660452b4de60ba32d3492d2e321236fa62e00f56f9284c1cd2c994e503a69aafadf18e631f5d36890cacf5950364dc8d4f564352df1da0ef6d7749108c27d63f4de76e0805db07b70f35adc2be0cca552bf5211cff3cce4ed17fdbff7351577c14344fc4aea63a3e659d615f80388b2c7d1b75ee007138f76a42a82f8bd948a06cb6d8c2f9d0999063e5dee458e0d18b861c4e298c8a61bdc11d54a3c2a3b50da518bcc39db9252f4298c878d2882248cef7b7b600c455efc13bb3f0f0d16380c86272db86f988465611f208f7d1b3e2987bf60a432428a0fb810d29c1c7ab3ffab55819cd168454603c7292efc59fd7164ba2c53f9bfced9c3da9a4dc9a9f48def429489a5742147c79a3b7f2be6d20a2db79dc808e0f56a721c31b1df888bd19acd89b273f169984109b381a1e449778d768aca994bf8e9740b0dbfc1654e2a7c14e95fe5 +expected_shared_secret = fe71e2b85d231f4abf082d4f7ca86f042ba259b24a14a934d79cace53cc10b89 + +comment = Rho leads to non invertable matrix +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 480813ee095bdea49d18f360a690b145d96b0ac56ad8007ffecb7cd198a9f6178add5535e863471cd5198c565b62d912fd3a9040828ac9834ea753c0d77b5f23637e5891a92fe7508b672deaf212c2711137915249b50ed9bbc2f7e804536b382d3a29b6132337e68d363903aa84b08a989f2482c56418b59dd351c54b0b89ba5266d354b91b2fdbf26812b19c79a12224b723bf0b0e6967bb1413cd439789058091ef95c62852075e464f717ab84db9b28b23934f625f08d0a05541a5866343a04216dfe83ea37abac6e273ebf649f7e391df2829ad2aa45e634dfee00fb465bc2b7658b36556e7c813d2e4a92eac6c2b84c8b3ac8d13bc4dec0615199b63860ba29172bd8ee51080071553489e850b1d8026a898c0941ac62fcea1cc83bc02fcaa3b5e76938ff96c3c682fef30c320d3a325d633f16888613550c120b9631235281c6f531b19f8ac1958eb531d11a857843c02e37347c13d8a216c1456a9405111d7e00d0ec2bba81b0a4062908883a3f7e088ffa10118352646964be2ca3ba2f6a4843b836d538c042c693ba928fa1651521894a7f83311476faf50add5952aecf663686a07ac302d5ca15e16baab85230e077acc0ef4b36de2613a1c210fa7c7c37188f1685f067403d4babd15925c470b8559e8abd4db4cf965b845f22156515ce54643f9ec9645c53c5c830344f6c7c537c87f2b6c70938c58139fa6e2237b03aff94b48abb8441d8b0d4c108bd6f4114f98c22c412b0d559a25c0845a68bf6266b7b9e17d80dc6c3631ab0620c0582b0705cc686bd267e8309ad1e33ab0bba9fcb21b13e7c455887d07a83d34d836cec3907026911d799653ac0298fc1bcba7c941823fcc88bdb39541cf989bcf08a0468451bef079a627cd31855667e97e3eeca47e2839ae32bf112b71af0003a42523390bbddb71cb1531264113b990ca286f689a3c660496f68c5d68247677262eb36b7b26ce6807459d7c7dc5e4782964122bd96d1b5b8ed9105ad2e72050d874ca1b09b7bbaec0107c1abc025a557206446745ec8d462a83e6a53c5ec6c0b8133054745762b5b4bd142a1e2c2471a81ee35cbad7d6200924cc367c3a3c55032631418cb6a3124200209a782e2a0036ab9723f511fae105049579bf1051b9b41d388609cbb81dd1191b857699d04486e018779a4011471a241fa9401f9009c90a14ac6a5b691bca69c3c5df7b45a7e77267f1082f0418a8d14bcdc29bbf48758af83cc9331e3fb34a49a2570f75562d0bb7213c230a549498751b2cf0bee4561546907f2aa436f6060bd74c3b06a7812fcbc63523a451b90b4c7386cb5614a97a146637c38cfb77ee1316d0ab981b4874a9d263185908fbfb1aaf9b9939fa2d3d552bfd577de94264740ba291ca4c0f732263617dd8d7bdfbe80797c68932664e414c8ced3a48f5287dddb04655b76cac5ab725763264cbc95dbc2ad7976eb5508482389e6bebb358097c79f2b3f5f6a0249881fa6b932e6906816038f239992fa23e3f1814003c48cbe3542825ac45a00d1c104d76424fac824478471c0349cc7fe5ceeb21c5bcd1c262154fda607fa811aec08856b444544366a62a57860e71b742b61de0f129009924af08a92799213b933739a3a81e7a65002596da271bb19675c02302a0a2cb2d928318c365cef3b828a362166b9a6eda5bb7e610a5e22afdd390c6c5a0e6f955d1740e8fb41347a62abe59752ee6ab13f78b4a3c3fc0f70de4a46d276333d5b51f139cce889ab9e18643f9a18be7349a319913ec923233311d1473b37f39185d872a9547b1702cb096526a8596127411bd1e611d51816198b95bff68bac6538149163330814d4d34a84cf2c174c96b21787348c037ca48aed72b22ebb24afa3924dbe43a36f50f55f3bc5ef41125d400eaac4376daacd71398dee37e84fc007f93b245ab0842015cd26671ab840f74831954d9886e2513c8d752ba15943945109b601f051146824181f258417cb393e8761fed36c5fe36590a589ad52675a9b2c05a1565cf54453c7781d01709ac331e5fc454bf222d4f70517f80afe7d90038987df37990a0a42095a517979a0fbd994fac3a42568687b20c8d4857321edb8c320682638c55c4a352d2e843b52278f78953a617b08b271b4fec05109278ffa5b74856188cdb6e30e8000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = ad2de30126428ed97dc602f7d15fa00dbee9bdeace6b9fd7579ecd9c015fae9d9d752b0a56fdbc997528f554879ae42c40259eb4f0d289ad7898ce21b45d0f84981eba7a48df5be7b6c3b07675d5f4c241c04281781e80a9baaf183570f47eda8e535a39f8e8dc562b28c1cf2b24118d87f5c528ba93cd5f4757e23a2a9ded44295ee1e706444e62a94e04df3fe4d2e6e77f77ec87de4527f20f93c62939e08b0bea1a8862f01f7a884de4f77f7f32b6ea6fab67635699f2b19eac1d1c4902432e1f2851bb35fb1e3a1ab79bf2d2589d34eaa4294c4305090b12e3625ee42c8f2e6a6a0ff86eb4439b4fb3371ef04b61f5b7d75217ddd16dea7977ee763f07da3cc3eff2ecea8d4734b8cf67e4f95874fa14ae397854810ab1b593f7eaec2e87650b11079d5eba756ba7282f1bc735e9dda89ab226148552a0a6bf67436149a2d79e1212da11ef87da910ba69e1499314f3cf90fbb4c04730cea5fb1e5d35eb1f522e09590522d6294f212c223249f8f7ff82f3707875e66621235c464a7564df4e0a825311cd915e6ebb0834f6f8a709636ca137a32d405550d97f9dc1e8b970394003fddccaaa1e98185d3dd354f3f390a5e6ef9d293e45ceed7be1583c983eaa6f9489a994ace30441b252c375cd448ff4c7059f6db14d1c65d14c4a6b1696381144bfed51a55827db14584f54eac1073031d7b282fc5a48eca5b164429d9bbf46803cb079924c971aacb0bacf3e58637b813b15794029740f06fef8d80ab7013041f3b11e04df8c6737bbe842c8271d584e5c84fa01870c9ff001864176c967d8aa39d6f3585ab0b0959e37ac8e9cb06e3bea1083c2053cae238c6cf55e9b6052592ac075900eca92404af4a174a2cdb94e202c31807cb5bee36fa4e6e6f67ad4eb5d60a2edaa101408a8e16df3f3ca8cd6e2239b079d70b5dba53a42cc594d595160a3ffae9f16121383ba5b778397518095a4a92d26eadce6840acad84610db923b5583024a5fa682a3e224c5b081a75d9903a870642151329befb6c7f83d5ff8c0001303e7349fdedc44067f894023dbf61557394bae481cd25bb48ae7785db5457a90fb1644f16b9aec60baf5095d4182b10eb12f680b37b779619f59108b055c7e7d0e33f2ef4a8911ac876dead82cba65def0c3015274d14891d1f726f3397f0ddec9929189f7d5498b41799f6a4cb8289744a9ef7d9c620b28ef6cbe88188111a5ca0c5a320c47bf7c12fc1cec6a3dad012f073966ab62ef5fd71a7dd05d774c322c8163b18a6461fb321d77fb26ea2afcc9a7b30bacf3d6bdea1daf3312192632b9a5a5f3938d42f3e7b5b48b4b58d915fd8bc63eb5135e5a617a333a21839e47d7f61e6d206ad88332c1fb55b71369e63d76e9bbf8e7cccee4307db753533b61b7fa2edd1a2fd434ae1ef841c87f6250dfe40d8c045e47f9b93abedea1c4ffafbd0d61499652e3b636e0b6dc559bd3db9b764e4d46c35f2434f23ff3628e9b4c30a65d485d29a57f5a400aac8df42593b33833fd138408e63fcd8f4f1fbd189c05d651065473a88c9e259029f752848d07f80954af01e8cb70ba019e902260a612c24bd8af1e484b280449f335bce1a32878a0af01641bab8901ce362ddf2dc31a2ce8aad03e8931a427b07fa2688114feee300302d193b05db582ea6c1c68c7c4e405e72607dd4df28c905ee38f5dbb6b0eee1864712a1489c974764bf7e79d5520d2695025a04173049057b54c23a3d2b9e4367f6ffc7be4bb3642b7fcbc639614c3e479bf755c343bbb925c7e7336d567eb051479521319be75831191c8321a5a887611fd8353463f245f91c396fb0b5e495dde71b124c875dcae8fb4d597bb84f9045c17949692963aef558be7260973589ca0760fa7980c85498946f90c719adeda096e111ac8b3a215084af549f4d61f8253f4acae2894c7e880111c1bf01124bfcf829ecf809b67b08bfc3fd9c8afc04c330fd67df9a07f2b92f19b56bdd5c621b62ff1b55d7dd0ba5235e72d5e88014c16016178975c14d4b105909e547dfa6486043025e55bcea08dce175cc10bca8c56abbfa688984504f5176a12d975a99d49c30ddc265f1f251bde72ae16b36d9ec61640c4728415521872967a6521acd50faef7d198e78e33e0585a14280ecb2a9f8a75744491d90616ee35b34f50ddf9800dd80bb39fa9e7b523bb03760550ede1a90aaa775 +expected_shared_secret = 365bb81ed68c6ebaaa58a3633b096874485c19fccd8661cb2ba8c2634efd0fca + +comment = Rho leads to non invertable matrix +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 0231538782738a75b631f992d3d74842714f03c31164843609092942715aa4227254a57fa5325e39e2763ca679ce680c528b162d18a3b60c6485e4aff926895b4982a64c40b28484a32979d849b380ba867d355ad55a148f811625bc1427c917379239203cb59230460c880754234453779eb7032ffb3b98071546e3300a63f39cf4ec0dba9018c4470c63e920ee79c000f57fdbf504bdf709b70c82ccf3c7f351b2b35a9b94582f61455b8f24bd43f1148b91a123076562e53b23fac78dc4ac6d257b3e882842382b30437e5c208fc7dc15a0eb4948e902a8f13192d401887c4f01a4924248af31db0892ba9dddd6704b6c696870bb87257a0e357d0c908995b0789079c414a0424855c47dd73becca7b13b029afeab7a7860220e4cefb361edc19c961fc2b24d4311803727e5c0669aa5228e907f6394768e7a3af5068b1b7a0bba9a2aa195ae052233e92ba6382548dc201a5d1c9bcc70f1f50694f56277703138787b34f63b407125d402369eae548d12353220b50e36583d9b0b6b33b8f38a8b7c0f20a4c7561d6c80ddca37d2e709263a54b4abb4577800705f068f21b8a4b44cbf4e3c4dabb1e78865c1fea7064f6534b1c1e7d088dfb37c4b5d362f6d19d90db7b9804cc0b5b02a3f091cd073722c82d0113bb64ab2762411cfd91353a8838ff39c2b1da1fc41353d4f02a66dc28930b9aa96088489c6a83822664679457f9868a0ab58f34bc16cc6fc8672e1f35a21891246bb201dff207148b08f02c7bb707a150084b93c44c021ca3d56735744070d0b26d3958c87218accaa424ba20c3522a6e17b5b99a26650c410d6042cefe6493c660c954484a6fab528d034da0d5a92200ab2c36262f074ba54432dd7054d348ce54fbca9e88043d3b63f8193ce57b770f05079c3946f9c33c2c9285422756b3653b4a876618773de5c7b0f2b019dd7c23f39759cec53e95aa0b87609f0ac794632849e5bc76c1619be9688067d93cb87b1f51337f45bc9ae8386d7c98b88cb0b96c583b010656e7f017e972c812635115335af17c2c3518346407c94e25c628002652e2cb88fb0779427fad957d394999c0c369447b06c095381bc909d93a5e0e0c087d71965e296a489ca5a542a41a99529592167e2bc1dda7bda1c5026ea15cdb4bae4b7500f0b1aaac059f0ff8381897c4f3a144728a2ff12453feda091503bf603b16e406288dd89be4884e4f86baf722269475c874b1133de17ce1d51b694c7df5b9a87f19c2648170de3552c7990f68ca7e16a913b6697b5f848c6c2a92a9967d7bd180b74839e233389bd334c80c7772071d84460c509c092462cc1e4072f8a3297558784b68c7359c0adfac975ee4798d26c719e25c16e47850d11569866e3d610c0de0c68e2886e2675f7f59791f4568eb60583a28ac8ff2430bab6e5fc07f1637a59be1cb9b33c93b3ca98674492203a9e9514ef5da006854037b4b4c2a1ac6ea6587d208b505d206f04c7a8df119774657eb549992002bfa75b480fb576d3a0484d695f6fc56dde369154c5509f346c501c12a699354c14478ba95601239a2c48217219013fc51eaba658d4a5662e469b6547f74eb29c10c296d1172d1b0c75df4b2459cae31b33d7e9164025478c75586e25730550216c549ad05c3660459a2653397d60c27b342a5b51836fb1a33bb8bc9cd622af6632245e49c5b129307942eff7c3157b2180112843a61376dec7f6294029a441683a996fa538bcd07a35585558ee09123b7c3f6291ff04cbfb5d9a85607cb086bcd36f3c0a8854bd0f58cfcd5a1f4c51bcb41bf0138c8c7e29d7c43a1b4538f318532b8f30351967efc26a7a683967d770f3c21ad3dc85b7da94c64ec6e66d83f01490ad6ac3567c81b55941ed45a6ed4b2c87f473f900891b5c69d5092087559407cfb5e9c2aa18b491d6ec7424aec12675aa6230303521bab27303244ca2716e83b212783cab442c909c8760ac2d341a24df63315ea42726912fcbc0187d520d70022eb6872c8b1158a804ac86893ac7741e2118bf721c5225853a8e056c0d963dc0b2500147b0f632fbd27594656866167c5bb28994833ac2031bf4998597f6c1da7a0a3d70c3d3b01cfe6a87ab57419491140ae9c4eec0b4bd91a1946233f3cf88a1ae27acc03cb551294ae5ab7606431923b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 5afa8807bc581062978485432085e6af37c06780538bd96f798f641949ba3793cb496b51fc455413e47586d44e379daa9058a4bbd2e329e7083db3c99074287a3958682fe1c94c88d175296b78e880eeb27bdd5b550bad0577e9b24ea5f3148ad58ab81a1bd1b63a24c0ebd31f2198cbbb819eae7d30eb8ab49b08451b4eb4c16d1dbdbbc1da5933c284c2b1cf37d9d92af41ff4ebc78f4418c6b9077a4888a3b516fafdad71a517df1b8818c29accb9536f9b0998c3a973b91c87a57a04d48d5f8332a67720f92c8692e8b2eec3fd62dec973b815a18a33e721617110e636301b737ac3268252920c578e18c50b8517c34b38117fbcd282392c14a61dfd30b5e15e10f05fff96f15359a73b8c29ffc44233ae49856da73426bc84305f83e540ecce3eb1c386572fdf2bbc18163c2dff137c05754a43e50d5103c0d7b4cde47457d64dd2cf1b1edf208e225fccd89a47831a7aeb0d1ea313d2dcffcb730532fe151a2ff28c1dcd8212a10dfaa0a6668e3c66c67e20290b285411f9c9ca55c36369b11548048687282e6bd9abe13f4b621a2545d50f530544602626d524306a97be439004d670414bf69f07cde6d82576533fd01fc9e8d8d40eba682f88f228151d5a87097a8ae33ab845d523f709eab85835278d8c9ff1ba2fa639f61726267b033bdc355c5e4b844fce265936e7cc009a99caaa3c76c4d73ce84264b15d1eb3359ff7e8ea4752bf3cd2c9365ec3f5b8fade92e7c1768814b0566bf3a2633b0f8ddbae1da24af6b42bc80a28e9bc1b601ae1addb0d1ed1666fcc9bb3e9fa8ca2dcfa7bd53c96ff0732a00bb1fbafd01b239796d658437c5a42297c2ef395edcf90a521a2ac2a852d329c95e9c9dac1be1948777f794c8e5c5728d4ec2c95036bd7b8aa5a272add19f5c10fc8171fb027956cd3c9e1039795bf6514310d4c2dec7e363320e481a33179ba5930fb20fb351ba3f4c6b72985f12a43d133530a8122e4bf9774e62e064eacf8266803769fb991cce898cf03457241d2bd7f7d104ea07615d8be80f3c2e86b015be16a7e0d0015f69ce1841ebe279233d661209495a728dbc6949650168148227ac08f88a57f3b3b45b7f99552467076ddcddea388994b2d9e4ad91a384ef053b2f7b5f0815d23c3a5c1de5751173353f88b9b4d8f2cd6335f736a646e370ca66fb911525299a5ee382dd49c2b34b654ae7f5b4ac07ba6af9f3b903407eba86dcbda9113fcd00ec8edc4873ddfc54adede668df06968ce5f63335f3834d6172d40d0a7086c9d3e68dac3efd25bd08d4a72b0e19455696c45f1a8f5ae0356cc86e0712aaf8c32393161ba47e519c8fadc19db8f4db41651c1fa90b800172b41fcb88f8bf6843c0503a1451177303f5269e804a73b5ec0b45e46522fe1f939c2f1b4b0fb6568206524990809edfd450e9412e76498109b7b349379aebd5cd6cc9a3c57c7eab0f57ad011f2599ee74f75ba208a1cdfe7a52a67b9a1af206013d28d01f8b4a5680735c8c6adbc3af20063441d5c4a6a6395da2e97151e92da944494c639638d6c2f1d5849ade57c75138a462d3a97adaa4599db5cea3f03a89e4f6c02a874f09768c5c38cce9e8dbc7c4ec5fd6de36f7a06267199ade0e03a2b9c8fe1bb38e4aaea819d9bc2d9a2023372d264231bee7da2f6b853f3441348e9875aa784162c9def07ac747135f445b7645e713e3467856f35fb4179b01ebf0baaf840f4b56681a537afeaf1c9a6f86fe6a9ba6a3f4300d222b9811d4d61f03a8edd7d2a4c1554587bf1e82f97a25dd5b3fa145ca4d92660023734ba7242470b7d784284002e3e4ff3b1fa12a50c159cafc3446747f57c860c7d1755273f9ba906f8568a650a9dd4cc2a31502be833fbaea86bfd4c13a2bc8b713d68c6cd0d6b0ae7ef14dd58fc68c558cdd337318365289c7e5da57bb63422e431d86b5e7e47b71a3d2340c619f0598f5af80e97a0be519d38b03c826ba8f87fcc4b13f8827baa22c46598861351595f8274688919c972b884882026ab739692f9758d12e5597b8e3f5da9cb5a7d903bd8030dc468b2c4b66416dc56ff18c20c78f018d7102bdbbdc9189cba86f9eb1f57b6211f9569cd34737478f6946a2fc2f34da0573db8968690d9ed0dbb2cb6bffaab6d8b28eecd6220c067e1ae1c5e4c8eb2ba179dd4c56860f6f38f5ed3f0fcbf7e7e67f5c92bb9db439b4dffbc +expected_shared_secret = ad8e3f1d0b1d2640a6f879f697c81f353f8e5fe17d0d09bd5d21c068b0720147 + +comment = Rho leads to non invertable matrix +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 0bb7ab955a1d1ea4113173c05093259a84c8f055148d301f1c72c9eb2ac6e03b8ec47b955fa429b138ab9762705ef19cc3d4019947c53eb361b8a6798ef219ecd086464641a642660bc0086bf97691e81d178007731511bc632097e08453fa02e8a2cbe9e858a20835b8090f56119bbc000c69f0ce0fe49c4e80b41e040f3f3c84388c6eb5ccac37b19420139e19f88b0b99214d06ce660b844b0604b49222e46136539c7084260ad0786a9b790d76c5132068ad6d1763c0207392760de1631783d21c2459c8189c3099245de001aef30a5bea95609759141e8458c3e660aeea2a3f721d15302e46e1a92d213d1ed16168f71e9b21b5fbd62355fc8e696c71eab7cbeee9258dfa4c1b876583f56c6bf37f770aa7c3e317f50ab01a7bc9f7a31d8babb0c9d2083821343d6990e50a06a33985af449c29340b89a59192b37a2a7aa3fad830725aae61c52b5932a2d9eccc98612997a2b76cb70094e62f4c97279c2044eb5b624097c4f2d6a6232b526b582c9897a9ac734096d88639fc4adf548bc9f8905a4a4d13aca80e952aca037cf71151042429a6f30e3f67802055b217900f748844ddfc987623b27e21c869c16396a57da38938625b9298d66d1da767810860df4768f9c26cffd4b0fe4693cbeb321ea69243fc0e0da0948e5c9ad676c058826b9c263c4587b104350e29fbbc9dd91e876b40396a67fe874177dc5013a18c9c1195cf92436c03b0e06b86c7773b0ec37aadaa7bab6214bd296ee820b86d4026a5b13bb0d79df7497d1d27194f3450bf38b9ae7a18aae876de5b74fac93afd26750b9817df000b89c113ae700102fcaecbb2a0f52035c6753be93ccb6e51c6627ac06a121d55845199a69e9b8b14f4f878d7fa9d3bd901fef7b250ac713ea823eef11cfa041bee03abee508f45a828dee681c077c8bf89433ac4c58035a755b27b495678fb051282299f8658bcc5567429798407192e8ee59693853a37f54893974c4fe64bdffcb6d2c660f88c8f489c4ffe716e27d3a157a539a8a6c1c5045fa93b7ba5f0b426d628ab6a1efd92662f802d9287570dd962f44c4a8ff37825444031ac27e26669fa15a90733ac0352819722724419642875cb1a143b5b2a2dc8e31cb4aa171798181feb539ca8407e06120ebbb2aa5a3bcc4600ef64577ed0bf315a05bf4513e3739282732c94997ebf91ab6293b909d935de20a8939071168c10f1a2792b4911bb212914e5781e3ab5b0d1c7c1363bda387118a2b130e07bcf4768c0fbc43cda2d58f44fcce9910deac4b2d11cf89285b1a604b2d6b6832ab2449c35fab65b9f1b6a22872858dc8fa6923450975f55bc7099e355416768af41c657352eee743d51da6133231cdc5c2db54b59ba6b092b63362ee2bf3ffa10f1897b75e329040c31bb3b76440ccc0b6098930072a1a95c70d0b5bec7786c3ac69dca40ffc687efb75325a5b0f9b67b642007ced66b31745828aa89526006be500edc94c69d9351e9139d3d826a3da4177757b100460f0cf223c23680bc233de3ea7950d0b21a3949e3e278a3c058f9eb7751a2ca35e35f88f121646774960574dec686452732d2ab00c863ccda19698456a08de7b4e129a9f2fca3615001720406d3dc90e94665d501246e446cc6225ffe44c8dedc908d7b28fa1437c95323630cba8944c0cbdbc7f1729919795c5b52aa1974647c43297efb030a99a6b0d5a0a9d3679c20c28067786f580506318bfcdaa3417366cc9c93e34488dde73652a6b9ac562747da8109481260502fab5c1bc4636c9d6b555f96462e940cf0b58202d049aac1a3c87b5d950b6701846e948550bb8199831c461e7436a3713c77c0662ed009df341d5de0b697770f12082f04449fb2868a69c68ad14c941130967f0b06b2bc91c0b840c43c20e837147775853d3baf7094c51ec86051b1ac73753f032374e76cc5eed8a0be466c9fcc1ee9a80c04b566decc5a448753c2535fc9c0b3083716d5b049f89c9f191a807b933c2ab912b7127b4ba04c85386372f6bc5db69b972821d54867f440c4697220a12cb5769cb7495a37acf99fb0451f6ac7807087ae83a0b564924e84428cc94538fb0357a7e222f8606ef0404cd7e29d2a4ccdbb22a45f9a7a51499f9764a063788c070a93bc0766923297fe438c6fea2971b887fb4c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 20327e06aef57e606fc94d91141d35db28ab5fb1a7a1c0ea51eb1230a4d8b7b0439722c9b08528ac3c63e93c1f1932e2602e96bb51d8d34930df8198269997430826c455c1feaee04e96bc91c5d19d5ae236a2e90cc23cbb802d4075aa7ceba81689bdf1907ca524a7582f7f6945812fb8f0e07b0a6b5bf1a7e879f4cb725d8c2a11df68aab2447374c9721a13225e23ab561301d3e1627f9973a0e37f76a3b4c3f824fc26f249f8b4cbc9d9f5ad11b93a29167d6f6df17b47c1144c0ee807d296c49e36e78805decd1143ad46b29c310b9228c8d66639de571542806115d8e55143139f976095b88903831a5b40f12772a7aed5cce13ff46c97606abe1ae98f5d43ea40d48d8ae94e89851c4b39d4d426b8a1d5622d1bf03d56739a9f81eb4c62fe026dc51edb57874572d04eb5d3b43e4e17e8d1554444a98145e3bbf65c900a7f378e5d9cc71169e5fbd59259f7a57b1b4c608e863bb6dc0cbe45c402acd789cedfdd3200e2c4e9ca77054e391b457f011486bc58708c44166bac944ab915ffe993591341a5d07bc0b66ca063c5294c3de876d4a57b8a9651e9a5159b1e12b9005bc44e757cb141cc665a2a03158308e7203bcb43a5b913add9e7c1f2a33319bd25e8101e9bf21a4a58de0653b106f22249a05f43c61780f9574ec4180a0d05947b0107bfe5bf368e3b3f9c7a7e9bca0d848d7b76ca57bf0876be4a0a97995d00f7cb65ccdb708e992efac5f1ffb990e107c854c5f15b8540db4573cc52aedf1bf5e4350c4418be50c9664c4bcf113e8d78bfa116a287e5f174770e7f9cda3ee4f9cc4f3e2aaedf97f576e0e71282479ec1fd4801e222893ef7d34919872ab79315547bc687da4ab3fa5e8d330a4ebb79be2a2866788f0e24fd946b689998c5226c0c241d24e3c6dde149fac94311031377dadf8fb263b9d8e055824fff8fff07820fafae7aa9477e42fbf42ea1332eeb572c0070b48ddae20822b45d491c819756afb5fd6f9564d3f71c043229cd9588d0292aecaec74d537339ee37cb9d2d365ea41bac6a811c41b9946dc1963bb6302c6ec01627dde1c2024d5dc9f9978cb963dda825a3bbbdd75dbaf04ff70f8b905abb70bf4bb4db15467de1f37e7a22109395f7b9cc60861888c41c8efdff5942ac6758e8466029cb6378eb4b79ae5c47b8c13dd9176d64010c98ac111e9b9ea8391a1695a7597ad38c016d3d28d44a22847c551159ef9a473bdb98179efb294e85d7819e0a100fd2ef92a0ccaafa07e5320527dc798886a4e49911afeff40e45768f18fbcd79f6204f17bc19cfd6b86f0405e0dd55ce4ff9e092825f0d83cf3a7767c49106dc3b996d011535c316ec78433810173b1cc8e280a7e23d2bf2bb615f3ea576bc8ab9c7ff5cc7d79cd093cc031a58fc7d8b98e7dd127d67696ada28f14082a779398ea6c722331783e77b26a2a496d484ba8986c497d5a038542e192a82d1a1c5f02ed3afa81ebd6348c06a897567163377bfc9bcb41fc3b0a037565871ca9693b1023fb0aabf770571be26e847f9ef822681ecb407c467309b118c24243ce1b64b060d48ee545c094d66d032c9249f877a1b034e9072e5aa63d05a9ae2e7ae037b70b68e0851ad8d99f3a6b6edca98f24a4070f89c92b786db50802cc8bb5d7362e8a17de3a4137b01269d53368836ba7b7e9651f3073f32140a5c86d88ea06d8fb488e20d721a198d43fb530d83f9f67977997bd24af8bbd6469f377e8fe6d4021204869813e11407a310ae89381f05b30257c608d3b6c395428fbef8c5d28a4169c07885c3858de23196e2e3e67819e50fb0bf45734d1ee5e61520cbead2f716f58fb7695b00cc7de362a149eb34ce562b93806c78efb67a62c7abfc5f2a7722f48c496ef6d641a710fb5dbdc0db58398dd401828a6e5ea1387386e9d67fec705df55ab466e3498b1e7ae78fce4626e440117dc16a5d3b849a60a3b6e0030b483ee04c7513c0effee19e63ea7f148cb8f4de75c0ff450bccc5cb85a3187881f3b396e4cedc685894d5ce799320f01b7aff4788af6e90ce97165f3cf7e9eef7f8f86283a99de3864843c6177a8cdf90c50c77d1f81e11cb42da9fbd3b495e7528453844f315b18a3a0be78f3fe0801b1a8f89dfd5d7eae27a8eb608831eefe5cfd0ad9631dd8be45add9da2f73cdb57f062fe46be28462d09c5ee38feafef94269344d765203047b8 +expected_shared_secret = 957ed68960e9527bb32460505e0a8b69ac6dc0225501d87f46fa810d98f2e31c + +comment = Rho leads to non invertable matrix +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 9eca02981ac7be932e01087b615a60afe87ff8d93d807589e1d351a5033aea9b032ae80fdada8fc4ea6a72b82929339f23870e620b836634a0594906f5acabf563c97abc1da988aa4344bdedc707e4636d65ba034a7c2a29090e30f677439247f753ca9ff93303a52a9ffb605c7b8fc142b576f14226c2c20828a258bba28bc0b680e60f43c08417946b77d29ed1ea968aa3a268e54b71531e680c09f5b08c01500956a86edcc05633dcb13e173e28e8c983fa75207b537dc37c9356b8ebac5d401a28a6d937f9ac49c3fb267d9a0ad9386f9ad4397442b05f191314356b431892f590290e488f12bac3faf94ec0389ca3d88924671262845bc022ab0856242cdb5fcaec474565caea58395a34c709aa270955104493832d2805a8e05d62437df6993a0f6cbd35040580871aba994eac37955f73ac8b057060426eb068114dfcbf20441405a2322156a5fd491f24402f8b73ab88f2498b04148cc2835901604674867947c3fa24a2d821963ec5180cbc00bba371fa3879be800bf309c0ce9b6ae90c99bd4b9eed787a539c90b31cc4ac3bcd1d2bad5fea1abfd7383a7497483b089297722d27ca0b325bb09272e4ea1182da4a75cb0daf7a6647b15ff0e1cf4a55a061921e55d6c8b5131d88da828dc800eaf4216c283af147939f1cad02351ac8ba79515167d1d2b582292776c300230a9cdfda2ecda65c1456884a5aaf3ed23c8242a3577913cfda45e3bc2adec6aa281051d0d94ed0320397b7ac724b8679aa29a85b838ef9a3c53021b0946c9933a5c5669b65b789e349055404b134671ccd105b453066fcc9949927798670bb011bc76834c37f3b98d2f992fa493fc3850fc64a92c6c17be8ec3ec5c46c4cb415de2c1a7f42700e415825c4376998522bc05f7a61c77f47651dc8a4df012d1aaa85ca5899f67994303c5e870b38557c05eb2a09069397c638674cb868b028b96e4249d2d935abd80278d35fb9668ac0d9999df99a78da32eae376cef69546fc71e3e2975221c49ab03baf048e1823bb8199049443433eb6b42a32ced9f15a9f4a3503598a43582070fc7492d6c1a05ac47f4a8dd3802af68c4aacd778d7693ffbdcb3f5b77f81a1951cb43597f5bdce907671d43bd4f92f70fb7c2a9a09402cbf0b8798f662550e2413992a8419d6a98e709c2c2caf9fac14fbe558b0597979810d62854205530f9b558ca4488470a39c88a37a152b6572c2c57d337a4b7ab261520729132afd067e08035924a14f28d32f6a258dd59472b5db2c6cdc53b9d766dcc030bf54b62a100cd0dbc9b99760df12ccd1e61df0b624b593b004f6712a13aac6934ba8339fcaa64f5d45c05a2a6f970400020380c320adf23377c6f5691dc96cdcd4864cc8254c929c080232a01b1dd9e7808e076d6e729926e81ef57970447c46f6ab942b90505afbb98edc344c47a3510c358bc63b76ca0ade7589cbaa3800e9278eb16a691a54de7cbaedb384ad97bc04a7666c4bb10cfc6ea85855b1c4c18005cf4939130b3a4d55a954805616678671a6353d45bb23fe847dc992cfef322484f7b90b3a45180a214491505ba24572d596cb6a48dd21748b770ae5a8559b287c76c29f3c5636b4400175b8aab65b91bdb09d43db7cc5805673c5a3c509ce77184f4d5ac4f674c0a602363d984e2bd8336d7877b436b6c0a8b68084a7cab956d300c498a86d49965172a78972844f37b5ab703731451854d7558f8f307d74a967282bae40806597ea5984899b54d31d85d159ee245a85ba7181c5bb051c49f2391acf60cc7c211f88d11617bb4a62446c635cbc09165fc590926cc7c4b67acbdca1804abc519af0c7268c0a3ab92123f15ec9f148517162e6d2a1083919570834cdbb7d7c23556a1cc11a55760b0470e6466e595a43a25b27565524618a6f0853781808bc14a97257b6ad9ca5cae8c294fa26053dca2c5fb300e0982df766882d80b33af645688c7a57b5b1a27526184083af969aa4aa5f52d9874a09b8dfa21cf5376b8db101b2b218412a400e02aae7a186f3b226fc018701533ae10c37b3836bcb829c7137a6252c9fd73723ab7169667b8c8ed4401724b36c71c2c8e56dc3785379a55219e63b4f7159dea9225c8b51cb4c8e435c3e19b7413345b12fa3a0f3cc6146860acf104ebe31a52aeaba9a28000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = bc99921d5e80c1f9d343ff32fb4a40a3706f750c4f7b0ccd7656ab6111f1ab8dad341e30e9a18c570d4abc4195927cc24fbfc57b1467d82d2d0cc1b7a192d769190a29d0e0ff672d6771910ecc08b2e8559c8677cb8c5d2109c07c67c639db57d9f83e0e67e2347bfc266bbdaea1436afc2ffac8c753c33a8c464c2652fd6bdbb7b78de3c851d98c5903a26d253eec7af773f7060eeb34f721178f8f6b4fb48ed18e0a614be5b35d9059ff8f096796d1c750fbfde317cb9bc95b14a25fb919a9df07d19aafcd52dea0a9b37d3d4d5fad67bce77f25358bcf3f90c09d08ca0afe83501bdcbe63160b7c8fdd8afaa7ef023f6ddc2c966118602cbe64a5450f1cf3d62d7cba4cb2627ab954f65f628843fa661b55a9e3f0d8a1c710b068625985405b29ab4472a4161183795032966e27080a8c3042d616807b49a68f9df5a8f466845b0948b1ef85695a631bbc503f8113318ce81e436e4fa69749bf38fd1a598e6f15f0412519363b76a6559fe068946925da95d5d00707ba0da8bebe3121f859fcbafe80796109a067c4e1ecf970bdce85946830b783e9223dda9ebd84ca91ef9ef096e3174785db6d4aef47043476128313195cc9fb3c009c41a2b859046f9494d37e057dc0723b17d7c1ed99c9ccdfa0349229151b584081bf921cd7bdef7215125d5ac2d2764e1d0c5671845164a77bfc91be29a476da8bbd5bfea6d102890fcea3757d9b323d12aa050a4653a93f5a29f2cdfb30e7df5d36f8dac610dc401b0f6ec0f63a022865f10e119b68c017d083ae4dde05598e02cb22f2db9c69372e23cef10e92536e11fd69baf27e41b578864c7f1a552b739b3369e2fbfdc7a7b6c38a1961cd717c4c8a4ad0d3da4e147766ee94857d0914aa7d18879ec6c5ee0cf747094ef3d681699decb917280bb76874e90c5b70e8f2c3739a22874dedfa8d8b1c5ef0cb72e67a55165abe7c3513ff34286ab8dc690b95b914acde3f63bafeffc2a6672e280acad66e757bcdf9f6650dbf39035c2a0ba75c100aeebfb8d0763074b191e6d6ad86d50f945400568f61a4e8b400a41a336e1179934ca181798f159278146dbd5f6a49481be03dd9538539dda5cce2eb4c149f9f7ef0f1ef5488c4fae38fd49c07a07976ed93e57a8f978e7704a1b316e4dc3482e6eea6181ace8e6fcd37cea7357740b9ac7a3c6c4cc3b1b7f27f25ba500f7b430079ace631bdda634e421b457fb9a951616ad2a15e7fb7af4a9d05473d94bda20fa5b97cdb6bd54d028ec81b09757036bdca2eb2fae32a00a50b21cbf7b2c9e0206ec617870bd18e8e5c05c4d93ebb88f4376f0d4d8629f5e03acfc6c5903564a3fd45529ddf45448174d2b9a36dac4876e601a26b0830546d3232cca2c2a4a5f6f62fa9f9c6c8a88ba83417487c2f838dee3657f4501f46f99467a738ba552ccb69ce20fc576722a5736d30cd2d6f3fa2e6731db14f4db0ec60fa134d2cdaceca19aaed29ed3c9905e98031470e8f06e5a95e25ea98e712b16028fb0641fe92ddd6012b05d3a2910e885135ee75fb9de08ac97fba4b42886bfbfdbd9c831996ea58d3eaa0cd712602d65ff8798b80001a5deb51a4823216d85f8d79eb85bfcea1805571a048f0ebb6944b8b32988014601b161894f736ecbd4ca149b8ca8297f8bdb4d4467b776e96df55df1ff8c192d7632fba09959e18edb38256f13519ca331e61a11c43a1f83f0fc668a62a467d3aa5da3b2875fb0befdb947f57e90f9fd9330d6a8b691038afdee461737f4a1b21f3409c71a09f8e5a26f4b82e7995872c13b023e2afd497eb4c95b949594138d4c52edd4cb446974e26740327d9ce438d3c7ea4e786e74c9981fdbe6a8a63fbb814e17fdf517775ba6946f9e4f802e39d03c829b87a68abfcf25b6b5e20f2b6b2ce53d99eef19b44bff5f76f5a055897a9695d6f83e7c16cc395211a672639134f960f986c75fbdaa7355bbfc1f79da427ef0037d4ce4cc52e972c03886ea3e1e9e66ed98033ee579f951b46839d3546608820bbb1e4361144214c27907f000c5e7866eb2ab5c3902395845c5b3bf14186eafa490d74dac8f1be75904f56a385c102ab9413022ab6da58d2d170dbad5c2a7c935a9c0190bb730448fd3e50dcba8aaed162a4aca6d4d2ecd8c9879765f87d6630a204c05772ca873fd78a7bedd4b6217d3731c0c51998cdc630e5a256200395053d0 +expected_shared_secret = 713597a2ec9a4e0cbad958bc8e4929877ae01d034c78947399b9cb1a383ad7a7 + +comment = Rho leads to non invertable matrix +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 1582ac34c94dc4828091253944b84b01b12106432fc87321a15688d6114c5486aa6d90338d3260de15633028a9a2c501e3e7a88747a03bc4c41f748778fc06adfbb70dd01d706789c49b847b12a2e369341c7b5610f2336730cf1c1bb07df6c1e9a035c6da4f01ac38570256ea0bbe73832f2ef968635765e7b9c823fa326b57b1608c50cb552c5c4b6b509abf2ad9452b76660e69abf2f172a117359b40cb7e972790f4b9bc05b0e866474ce6c2e37a36d74b49d400ab37486e47597afe6a08cacac56a654b1c56cc2dbb944cb6ab12338444d15f0de20265b57f3f7331ce56b374d13d4c89213117a15ef15ed6356778a6a6579356378cabf268be41466fb82c20845bb5811a2ac3609f3d556002148dbda989d8668ed8c26563595da887c657c915bc83923b46034af134a6a71e09992182310b061840afe058556738526469f76b91ed6081bce143e5e223e9a425bd645689d37fc867006092a7305a44537b06c60b168d039751e6b015c7c7d652ce121289920bbb1fd30304124819121af20600c4f0b261ec014153604140a5b8a97ea49c6c065429e08781c7377b73d06eeb909e9222007a7436a8e8a28edb7ff9e78c76683234092b6c97b256f2942eb01bca52a5f192ce1b890bcf0052ee905d66bcbb7ff44462e5c2a92a58313807b884a719cb07a2d8a3a0f5c2bad57cfa692a3d01345807213a2b5cf6a1234278256965464b48bf96fb6d3d0980d2c89dc3171093e80b6fb7391f203fd0e77475b8c8b8e913abc7066b5cceedda8e97acbcf3c6a1b5a590ddb0265b2abd5df28c8d7cb1c6553049d65808a0021d671622f45a5e834ba8498f97a10a15f1c8882b8c28e31b1187207bf5b6577053c5f7af3839bb2997bdfd761154fbc683c68259eb2e2367b2832a0c26a53b6abb06968a05ccf236dd8aaf3422c427368400dab1683832b9c73af3f63827ea16c1bc832f115ff3d00eac20cd353687507cc6d8f97ba12941bcfc714c735b45aa33dd3451ec56c4bbd6c363b3b8f65097d6e0ce03b29fd5039fa0f2a8342514278aad9d4807c1b25fdf035596f8548ca85f2291207694b949b42b00fac43cc6394ab85c0a01c583717d900035463acafed05f6717057e577fc30a92567a080fd942816157146a70ef3427a71478f404c4f613266f95a552578af3b4a7bb8383b1f20a6e47157277a7277086b0c38dffcaa911a1725fd34b04d545cbd924adabba3ef705c6e44c885526dbbb55bfc8a772453397902ea9a2b279e379f65151fc3450a1f471355a97ac0abd0af32a4694cbac06c32069c41fb6af17d684aa05a84689565ec05292d61aa374044485a507ca3478973b11008bcae4cb0a2975c2a471db196dab32bd71397e87240043b1305362a62fa6843010a25fca317993660b705f2637988494b94aa9352510b0bdc352394ab627e5937892aea86ac0e7eb1c5a2b2eb403994df5bb8cf144f3043dfad619e0627c2e661b70d1c4bdb30401ccbba87c1e8e0c1a83802abb5910625344174b6813f89191d23b61f3aa4c458a1886233aa29d6473be06f0906b75b1f16b1e5ef34dcc88007cea76130a70f6d1aae5028ff71ba38e047f02fa1956e7439ce37d13ecb555635e3644cd8c51b53db31a8254b2698a76b96300f7a14847c9ac372820ab779498b15f965831965c158fc196f56aa9dd37b0972c834eb0705b266def50b62636546b96a87ff666b1d5aec3e52679d4ccdd5c9b0dd50a7d916bada24eb6bc0ad94b9ffc986a4899303fb95107a90313fcc3fc0374e0c53c8160567f577402515624d84b15a9b4f18625c7d732aed4c64ad4766945155657b93a81283172850ea5417bf877e5eb95d739079377913529657dca52c756779876954f864b7251a255dc58b723b5fdea551aa299ebb8af0bdc2f9ef1b78cb42401ba62fc1992c5ab95e6288b584bcca263912c25a72a69a3d895aafafb38904a7ea64983637773dac77f0752909161833d3185c5d2824319aed09b0d27eac30bf5ab3849cc9041c7c8bc92e0c0b3bd657e2074963f79a4ccc42ec823c8b0d302d85371c4e928e5cc9d11d0889834622041bc971ac40e00871b27cf052647fab656401782a0685a800850100526cef363fd550cc491225e4c4a0ee319afd39ff2e2b581f728cff590a5a60dd5e4000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 51256f7e688d03d9c716d923b01f95c6266ec20da79ba4dec7268f51319e8bf0b37db4c07ebca73a80a06c25458e7861dab9e675c67ca9ab940dabb117a7e2426a7a81be3dc6ceddd27f073c2daafdb9162b4409ba741c6f16ac6892d7d8b06972d39f22e38c6f2cbec7f0506a5f86c5fc708a1d9a36391019c6ed9281c986103b6099f87ac956b59cad12f69db134f05d9f8f641678da42b276e754a31a77db16b5e85110235c4a4dd8ad1f6be34527d01115b072b82e007abb4e8bfbef65919c4309b8417c4bcfab963ee1110614e57b85195359f48c5c471e24fe3609a5314b5854b695efe31aab0a07d29ec29a8030c2a7a005e3d7ce06a23bd240feeefe6320b7c994fec0134bcd88b2fb91ec37b0ad802e45003049024133f90ccf375abafc7e742542576b026f71dd8f00e8f790178de9912fa850d6c24830354c4927d711a3314bb389fd01341c270eb1cf2626bc19042955196358421c559a107d4274c9bfe232328e9571192f2209035c425224a240f6a9b3dde07b6fbd18eccbcd7b00a6904a801b0ee93011644d64d0c3d58c0f9699af2d4e7f9578aabeaddbf8257e41c2512a5e566577ebe94699e00953126ce91674a772108a433c82b05524c1ac742ae513087f69e67543b93f03f8bec5e5d8dff5251f4bb4d17e721fdd7b9f6c06121eb53bc06a730d482aeff1b09cb6824eb52838d85af90a685e4178e76441ffbe7aa6fcc3126fde29193aaa25cc850cc0e8df7c9699584fedc15ed5e0e7d49f89efb61ae381e3adefe8eae1c6d6f71ecdb418ea36a357f20ebb4faea2ec2826b756daf9a4655102064d036e745932fc63a0fcba1d0ffb99815d03dcaeb5c156f4229ae0b07375cc4d8a9cd22a583c16114aa613dc38ebdb8c06721d32a6293aea51dd7d31ed3a101ff727a938bc70d78f08e3847145c02f4f0f8635be2bdd8958c4265bb27fe915a9206e70e9cf9979f9b47823708102ac1cf12863ac7dad149134824d3f23a621446ad907549b082ab099815e1fff844959bda476ef642299652f2bc801a26b9d4e5c212cbc1c1f23f23aa334300cbb73bcb9d43344cc9b6bc2aeacbf90fafefcd483b791fc3e310643f910de193c788c702f359cf97ca07341dd6f088db0c435bb300f23d90ad23264f9c394d56bdccc23665ca8f802e2907d08e7c825dac31520282c1713701ca29a3175157d7060bb9244f4a54ce1ec2b736e73aed3ff4dfe979e89e241b578197a0a8f37f0d811f429b5b1246ac2205b657e7ea051890bd62ab11c34e1373e8e48d449ffe08dc36e978e4b0530411d9249cbd5e38182e9a7922ab0e51f7feed86201fffd39af6dba54d3129a7ec700145f819499d4bc2d95a47e09e3429a5803f0b2f35d9467671336e3289eeea89d233f9c2a3562e277a81af46d00417106b1d7257b1ebc20cbf7c09f8a5c4f035a314be27fed58571d77ed229662c946b233feebab9e14891fe6e8295c945502c114e6f2117de50fbf7c116e5e151b12aafa3432a2532f66301292ee764cd9dc76fe93dc395c110d400e8d337541e94ea1afda991ac7309de1149dc78ac843317fb95eef99e72df29a0a88f788eab75ea8ad1dd0c2b1d0ac644cf180d022ea8e0b7d7ca12f65d0c1647b2267b971ae1a7d45b3f5c6ae5b5c239bf3b59260005f24cca25a883245d714ffd87e357d987a49ed565ea729b0c9424aa4116eae2e8ebd62c69fe7efe6dee622d83d620ab2a53b24c82ba9aa0406a9be7139092cf97db8fb4c5647bc14e3b3890d482960c7e8b0422e4757feaf66426985d07a0cc39f51faf3269fbf2d8db382cc35f5845e7dd13df13455f4b3ffde636acd70c60e3f3a814173ae1167a69d7af59d61ef0bb800a371e79b60681c20882fe80fd3e6f5cc21b03b0b70686e8b62e5efa48f46b48e349f20b3f0b4212e8eb1d7b2120c0a0fb8f11852dbd144ad22c549914ae1aeeb990a317a6c942ddd07b023352cbd33209326a6ce4d751988a4c7ceb6e7f718df7e9edf6e2b2675429798b013d321da1f0e0c2f50b2db93d9d451209b4411dd6eae8b74a63342785dd492103e9ada05d797ee2027c9ed0837a0f4e9175b6b508cedfc44e00c944a771e40fe4de1e609965a08e2434a4ff5ea969a43274105b631375c4e3b38a7f40c26f4aa202771ae2a9179141ef005aa18a64d6e97ecc1270be6cbb9d5bcbed815b983ff8c2c99 +expected_shared_secret = f1b9f6c6304614a31639f9e63a019e699257c5e60ecd5cc9fc950355e0981772 + +comment = Rho leads to non invertable matrix +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 54c26e3a0776f2db61ae55ca140c1056156469333834633d88c59aa9207774343fb3c0bec2aa0c60f25a1761337e9c3823a3965028951e114003dc86e1cb701b3112ea048672e5be40c6b319d88d62731a02290ed9d7429b71afa05964a5f775b855a271759945532eee7a1e49c1518d0b3466d2c5513bc84a69a0770b8f506c5203336691a8189ff8672efc68163b895d7a77b4a50668ca1ebc4bb703756e15605ea9e9c7dbd398aed773040ab89639aa4d005638a839a1e47e113564a33889d72682794cc68304d0a21858def7c8e5d20cce503909bb2064b7775db64c8a87a9e3ec79580a4493a0a845db33afbac74880888dd3070dab2ace759f777c03d0194d23a3b655713932570fb3686eebe97747713050868f72f6537b1b1e80e0a84d24c4a9a888f5b7c3bfd9380362ab98806812d07403463c9438069eebc541e8a8afcb93a18285d0f1a319e2768cf1427123ab458a71f3a44002b93cb84b72856a6688b99be6f2c764f81af231c87b7bbb1f3002705ac905f9be3d4aa584b98927902261f2c8bca677a2a77e8821a1afbc2b227603a75c1bc98aaefcb22fca6908ca2a8b28c813702c64c8fcca8af5c29e3893a1d696e3609312e0286c47bfbd2a562692a8fa28b17865aca8a7b00bc1356c489c4a9c11781c5f465c7c547b1cc464b5e56a84fe104501399a5ddc47c8b3ab0914584bb54f3c7107dbf0a3b8404e35fa22f3474aaf6b24ab562d65654e3889723c201d68f0ca9074769c15613319beb2449b4c2cac246b4f4687b09205c239fa839314a1d90a71c0aa9c74423873b08904a263adf2101b02aa222c2d06e42819094a60fcceba022dd9f50dbf00a96a76528785830fe453d539c2f61b0c999cb90a2bbd3db831cccb813ff1a7a70ace99976bf4308e2894cb4232441c0a094dc78334e2be9e6a830eb9c6458887217a1e6a7cc679838ea84b41e5b45066b32c69731ecbcc4d73f68f964958fcfa6a64b8b05171be99a78c31340486174566f4bd108433dde695762328f0570fda1cb79d60c67b510b7b34b0c341ab8cf8bb70146e0cb2036799368ee78b330a9288625c366b0b0d9a1eadf917b2f7159f25c31d34b422ca5d70d93de8e31b7a6736677c93952807314a2e58b685fd926b4555146ba41bc4f223b42821bdb22a99527699a7c85eb52288a3a4c56296bf20c2be811830fa689633887b8512723c598d8b1f9e88671fe77d9ae923f1b85973eb6ccd7cb5ee15b34022ce5078ce171837472101bde6915c97150b3b712f05435cf975b24b51e2395ad667c7f38a8fb3abae833a939b1a86f4545b3b55119c10a19983b089276ed7ba25c910a726ea3ba02344d33cc666a280bdcc2f99e3991d2491861c3b295668cc0a5c465b1e00c2be482a57b9c4475b3c11d9850e6684768091480e4a1dd0d71e88c17456ca0049d209d1e1a92ba4331dfa7382e2852c98390d4393f4016a98d59ecbb829a0f4b7261b12ce796844458fd393ac69f050317b66f7208afef2113e682552e81d99b3bd8bd30648b1a0bb153864bb7293233230f0b164c1a60d834c2a4a41bca495b57c02113281cf484937745b4ee90a55662860306df33368d7f2390c2b600b0a0314d1741c1a1cfb0940b39070fc1001142a27ff752ba7fc83e296cf62bb76f8a3b06359705ef1759702ae9623b6d365344ba2578ff4c00a4cb48db88e9c5acc8cfc033210857abbcd6132140eb372b9c3c1b69c9fed366efb33b518f99c23d7bceca7cb6b427623286f14b55b6fac869e8a229bc342c96727917a94bf29549c145fe9d95d35e518aa5776ca3678460a49bcf22035d981a4217b6044af11c9710a26466be948f177820d26957573b1575a09c3a87a13552f16234db5152dd2fbc764c88525e3226e2b5ff5571890db75458363bd8791dbca67ae112858908a4ebb7d0d847ecb610541c0791ac73f2432775207a73544491b7a5c03199ce3010a05f764a09cb9afa27023f72d9bb0b3252673ab714b792a35a78b0cc1593f4c5582406b4d44f6c67fb06972fc7a30e937d8c7964359376d896e9d54c05eb6864e583539a348e6d3abc256ad6443013926831513896cb5636aa1062f95bdf5b0acdb49a72581b6d9369c02234ab3dc5e3b4419f27318ecc3c7dcc60ce888b787a3458c342cad1c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6d7218616fcb7c0a8a0ebbc738afeb35b63c00897f8557500d34dc984338ba4d4e9a4228063774f6b19d60e68d67f14a63a0777c4af4b9a0387c8165f368cfc8d603ed70f6df210e9f540cf9d240006bbabe17821d46700b8fc755c5074d4e558d80230b50c298b4a813f6652f6ac92427c168bfc6b63df821d1566b56dcbc48e96e6e9de8c011a3f94e8cb3b11e9928a125b2acdcc5323da857ffc0211dfaa59653a14b408635bf1d1a1ac1f614a6946c98d9ef55e8d5f6c66b980241a0f65c14e5e6fc1c116ae9af9961a7afe535332c5f922f49521672e84d5e28974f8df7e77e7e07e4931f827d94c7576dc16b6f8e0409d4eed15ca747112ea1c9c16602799dc37f31a438f7809db67ec184fbeaf917a72e8ce7d0b68c4eb69b3e4285f0dc3d5494b6ad0e6c9649b75f58808b8cc54258837eda14de7e2f900e8dce47e35df2b529409ab78952779a1006f81e32726d9a6d5a83e541ddb249054956c3a0ab4520b4315b8cae764e42c97af4876ece118e0392b6063a8b38c89dbf8c4e1f7de17aaffdcc9ae30bc71ab4b25b26e0a2526ecce67cae66c6eff9b9a11e8bcaffa5cfb21cd5c576275b5603a852aa08ff1382cb047b1bd6519a6fb1e505fa4fdd06338bc9567d78cf1deae827587006e220777b34fad307a61e955673bb539abeab976bfb545c3e002d5af5581819aa9c932bd2ae210ca29dbdeb33269439f1553f86d44287726d74690e279aebaa526653bc24ee5a94fe70a83c46378d4b2aea5f4da0ac4ce75aa7d21072746a7bd5a4aac231c977e9365488410ed78cc357c9cf36c71c8608b2e233e37ae1f169b15b9b5d5de5c225b60c3ea32eca29501da353218b593c6793829f38a852ee3c575e468734733f8d87f677b5e425a2f96553d554dc52a8ca96b1d711406e04b2d12c0f089ac1001b00e3ab5ca951091876813a1a7fcf4fae9859991f8abcf40bd2430326a0f0ee7582a19416bce4a95f486b146283641091135c7d71e89ae8f44daebd43c7d179be2db238ee7f7723ae782eb4d0da34d35dcb4b8831617f1c82b10dbc8682beb97d0c58d4fafc5fbb8720cfc7718df0883473867433bf7a851a225d60c9e76dd7a7efecd15534dd0e3d14d64f86c4d9a696c61dc520fb79c2c8cb081e72aee2119a3ef76c4f49e9616ef6a85f9b779f99177e0ef427d9a6ba6465f230e63d9700855065b4eeb5ef471698ead0dcf7a55fb1ea54073bdd1d67dea4de22469c317984f21fc421171fea81ac872c779c62bd4e4e8f1ba4faee4e701458a2e21222e9b45b3ba2789d1ddc34bd48f16ef6e4625b1a73aef185f62c73b79dfd40ae3d6d838484b3d9a6825a2a4b9870d87fac0a4b2c8af548b47766e3c92f7821484c406b74bc4b4b88c4d7ac536767fa72dbe413e5ee4ff8d4ca83cef9de71590e02d07d9e830ed7f315d542ccd1d0820374c19967f2ec7b73089a4438e5a94c6580d689bd9cc25bd900c275ce9aa450a5d13fa143e2ed6d2bffd5a1ed96e4c1073ed92f48d575cceadfcde1f0a82941dcf4daaa5399b3775469dc75f150ab41b446e2e3e17cb8c89b54be85dfdfaf1769d022332c3f819536ab3abd1d89f9de0b25399ef5872130255cb0572da109496b44c5abc4b8fc5ce2a9515ba12c38c4e6ee83f4d447badfbf5842757aab335b62c89665a1c42f829a40ca8c470bf79c65e29ab71358063594e21af5bfb2f6b53d2c55a2a1f05652ec8773b437d68ba897c035b781b266b90ae3addcd603febb3f0ad2afa0904cac6b9c04ecfc1547bbb0278c024dfea4c7ec8df54d24c4b7e9f614cd8ad0307cccbf298092ef27add01be5f4631d4e1d7afa0d8bc34d0dfd4922abaf5952062bf86916831d2864404d565ec557ba7753480ada5eecd37e21808cb7e92bdd34b7bdbcc0c93f39e9a4f515ba7bd6071c2b9c7d513b98802111c2ac67bf004f211e4daa201ab61bcf174dd83aa5d98ea1b55b19391ec50b299a56899f51cd476021fba5f5f997a0103049a71cb20da170d38bdec4964acff514b0c4fc77c90e8ae331099f6863b551bb980ae547fa41c12c31c324765bdb09f6d9eb734708b6c0eddba22154b3dce0acf3210ffa58fda8ff718f949da8eb7c7fa4a67775834c1fc9e74c5f7f765920f2647572e9158f6bac6e1240850decbc4772cbf54ac754af22d16ab0abcc3ed51bed9af0a936b82158c310ac457d5c +expected_shared_secret = f72431bd4d76ce666c68f35918a601983e117a666e5009b4802e904d0b32d9e1 + +comment = Rho leads to non invertable matrix +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = f4e8aa57f60972f4421bfa448cb92525f41ade71a35261551547b97eaac35ec9607a061483874b19714ca7f443abf4bd34d2729891383cc0a52006a4bffa743cd910d4927fbf792c20e07e9228b56247c2440a3eacc0c231ec949ee7809ae4aa00c46a56aba6db5218c588bc9285261b278b1efc62e52556b130a61659cf09648b57c79647b54ee9658913caa76eeb5c8a6b6eab8a7cf9f2707dd4195fb3939e91bdc5856372b5cd571983c9709c1d854ffa56cdaa34b3c2a51bd0d304570a591f45c2f1e4cc35fb5a00923d71a5acce485b210b39de54a8adf82fd8682fac45430ad513aca5022611038769b29c1a3f3ad751eaf5b058370927e36049d1b0970650db914249d7a2997446e1b746f47b5fe6057bd55801c8c0af94857776d0b60be8a66f46440ba766046a1e08948944525e6d078f1177a60fa3acc2832121c7a428d5cb3ce316a986118d006ad5aa7e54c4c5ab5492e894b484e594b14b8f65752da0239c6a0784e415bcdee96ca0546f81368d8899bf7c372789f62a3182bfc990c9da414e0ff346a4c1025ee1bbbfe99099fa29cb5b744d860e6630c132e521a65a2e00d1561c98afbd434be0f92da317c89926a87dd674afdc8baaf99661c9572ab800e14280b3b08f5df826dcc051a647b96009159ca26f5aa2ccb770b8636b432b564b4183a50ee32a80318c646c7b29d083c718c27ed989535861c385bbaa44b836dbbe49432f63b29bf66923dde69c6d742aa2fb28524abd22433ceb87a4eea71a4180a370305173a8a597aa00bb364bfc167461e33cf4e764d4437e5ea445b7334a31db333fc2b3754bbfa6bab6bec208d68274a4103d16f9069a9c9f6b0901c2281112bca50b475b4d6cb612ecaacf8827b55b6fa8c1821a8a9f602c66cb719c97337c4364450ec2a8ca6b01fcf2420e0b0d27c0bd82a721c74bbe62c5ceeeb906d555ca90fc12450bd0522ca52f4598f3701a50710fa2e53561562e8cfc58f4596cb9c8b8df540fff63359b24b1cfba7ad559a583b04626d03bca5247be964b457bc71e324ffdb758ebbc695b919517e045f6e1162c333c30526bdda31e5f4a6eacab3d97c27025f32e695703bbe7ccc18a87b8e347b7c678f2607e24c888b85454fc738ee0a74720ba03a7651d84c4223b32277b5231bdd1b4e61361a451420891c1a0dba6fc4508119237fe113aa087772659b64c122382bc9aec39bfd2b2a88b32199d38728ca98b259b85df75ca4ee5a671130ac11ccfe19a1fa34954387035c8721e2bec713e635290eaa70660b5b79660334a5d56544aeed1044d6a3f0b88a1c900cc362151a3e0b46cf5a64a5bc38578bad6d0c467028df742be58c3c4c0096c20ac9f5799aeff295f3939ce61a92148ea2313195525cb3da93b30698ab893964d23e72eba952f058c2f74a00081814497a0306a51aee0ac1cfef00b7accad91448f49c8530ecbca5c5cafd66b1b03515a5d6a0ff5a10eceb67493506c8a514b72babd2036674d1a493b598a2850342a52a163226f07568c846a4bf35c502255b9ef4c95c87aa6088226a8033af1f6bd93e642fa8a5ae1263de5e53de8b419ae066ac3d28f159613cc63a163a41b95589249f0747c6a179ac9830cb5c14bc88efa708100aa7a5d2c7fedf0c550a5097f764d948a9e4e821a4c64a125d9c54677848b806debfc2cc5b9c8187b52cff197341904cb21b9061acc7c12aafab320e2f468244852c3720a0ec554d1219561e954752495c423635b92975ce327c18c346b026753a60c5159a33c584a2d297a499a294ef9c1c8b5081f859443f53625d6113ba1a90db33d7b5a32fe399eb0e84e0804adb0e29f4f063892484110121fc6c618a0235a22014dad868ccc55875c37af10062fc8a029a0c458dd80578680757194a75c4350de14100c73c40b616becf89637508074baab38acc741139b31d70bf0568ed5302f3e356dffa01f6da50011313b78016134e4cc15e65206f1ba865180d3f7736076c682566defe87bd676bdd149c76c136d549049990b482860a36e321426e79ecdf4c9d4b0b4953073fd8472268929b8694f07bb7c20f2900db8055893607428b1586c65b4ec7e195a431249a9d1480400d0825c4a655e257ca20175ca47ce081938e724c138592946f344d9eba69db96899f5afc8ec000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = c22bae19c43331e5c52e16ee59188c1fff71f15af20de57409add7604fe7c7a9426ed876726ffeb416a2bc7c698584155935d02338aae28a12625d39b8410b232da09e83c1c5e4b12cdf2a6c540575f232d5e5bbabfc299b9e36f3cd658dc38873fb3d5e9b3c8c292e28b7367299a12dab435bf2eff2602643e13cfaaaf96be846785b3b712a1f7de9f3fc1c340f32d069ead5b68ae6adb183c5d7589bec7e2eb96715ed3f15a336c63b3955fd6329281d069a041a76e7d4bf6d758dab0f5eeb27e74a318c1dcb3a645155c62c5d7710bf019fb0667d88da8d41a226bd45e4b6015166631fcc9f559d405145d49291123baa069febc3b720c2edd2dfbc29145c6665b0a4bd75e95d8118ab1367175464fb7a9a6cdc0aa7818466721f44e6622b40fbbc18947652a1940f885d3977f9a177caa17634bcc528d71ea678b387284f9a33f549052c331ec81398dc9f15bc3f3eff791d31f80324e21e86317e1ceff20791c8c8bd590d8ad3f64b3efdf432efc0e374506697728c84711f84b0f1c1c386f8607a20cfe3177029824df54caff1c525f3b1f8780490439a53a3b0daec32289201c81e4358f8549bf9ddcf2b2991dbc54ee9bb3ec0f7344100ab900a48d0a350546953a52a42d108de591cda14cf5471fc38ca8babad6693b518fc8774f351bb29ea8da5e2eb05f3190a97cb819ef91927e6f1288872a8179a99b0c071c429c5dcc8250d5e9c5afa505666d8b95712605cf9fa557c6c26c574f8fede993ca03ecabaa144911468f8eb0549a5c0f9b7aeeb94ee26d097d6b7bb76360d4d5091feff29843f256507f4bd743a5d2a50cfb0d0d439197802a44f53e74bef67695bd08f242f51d842ecb3c24a05788c75315a54e1f7035b86171b3258dbf49427cc2b871b3664babdd7db14f4d9baae20171ca7798594819f5e2ffb31c2589c169dacfd15b4c890441f0f87a8e503c2135037eb62988aa1fa610c6ceea56ae48017b8a9ad2ff5a86bd1a9d17e5e9a82fee0fa21b7722535b2eeee10573f9dee78d7b6667484f09c8353e6099c09ffab08994d2a6a20344de0c359e8adf05732fd6862a978ad9614986a2ad87cbd87015b2925d6a23a9f02f27fc7507f852cb06539e00ac560461154005a9ac3dc5ffd521abf8d584a1df85cfd64922e0d1e9e4fc731b0728a50c02e184e404b3c5e4fb8fad63a460e45370211bf60e7737df85b373fbee014b11706c9d8b09b1433a96ce62c5c0c08c484cf8be95b7426fcf4878a4eb15e668786af45712c82849f9146a2ecc3380bb473a0d619dd0295401ff9d1f57f2fd5a84bff5fa6e1786466b60169c1ed7e4083cf1816e116e8d0bae7ad6bbfab7625a47eb6d20fc1fb2b91c84adc23c6c14cae79f4fc3f3ca90c3c15315720fbd15d1a70298cae1b6b03dff6a1afaec2018016616dd7c890066e1a36562e55773f8c5fd22ad1f4f1b2fae4e8ceef92c681fb40cc279edc2a834eecb1e49efed02766b9547bd679634940f247eec42b790afc45a77f5e4f6fafa9eb1323fa73fd40727ffb6998cc5c8ceed32252e5c26e57290f336f5831689d54b8797de208f0ca2c75bb6d7f9dbca88946c1192fcc99fbf906c592090d3cd183eccf714c52c39f63cce1044a7e15cd574aca2cc7d6a76a56e945f108d53c51fe67e8212abb7849e7df5ced062bab608b445ffd9422e608ce096791a1cfd3f2b2f61d4e5c800e33fa3a8a38114cfa02385833d435551f2cdd5fadd3afb949437f0c19d7566a5659770441c7dc09768782f574caf781855621099d7602a6eb1935317d25dfc813d12cdabc3897d0493b88ab2eda981c407e0bc4a62f6d18c96bc497c6c9bbb5401b77a77413f154fcd309eb6c4b711e41ea4ec1c7e2f4c503086be4d96394d5b420a813cdb5798b00831139eb57678b790a90aa731ecacaefcff840e0d721dddbe5cc1c3deb03620615f79760b92384fea781c8971820f9636d776bb2c32d596104fb30e0295769acfc39a3101db88a4b5b38a75e9ca10f4071660ae869063cccb409fe921dc1596a517391184894b45a561621eb7c1184f5e69051845eed47021da5073e078e0f872566cff985ed3b866f273b80ef57d88cc1e2f91b72c69b1c1a766b4f8db2e8ec653a618f046fda32cee1f06a6e8b5895b578b3989a4e86dcff4cda1d0b573ec52b0b53dcb1024ba58d10253330fe3fb7c19c6bf30d +expected_shared_secret = 0b6ec01df36ce91c82f78ed1b85ab731581e50597253c08745f0f2891a97f942 + +comment = Rho leads to non invertable matrix +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 1cfa5addb505d4b3155f44c292f958f02c32de979b3b042f85ac3354fa3190993040a01ad5450680026d7e17a0732a54c09329373009a1c3087e8c892ac0aac4793fff2b98cb96a3d0671f998749d716a78c4cb6738879d76307a3a35738a886606a236c92accbc09ac502c03b41ba0a768edf06a2c6162467581eba5083fce8488414068ba06158a9128ff5361ebc06fbd492d69c185d0b5568c1973bcc1604a4c0916a1c03aa9e82c98cb3f107ebf239ab50213db93136013dc11c44f2e55871c7bc34fc76a4383477410f73902f57d229e6851aa182880e767e1386082fc77f20c7a3fad8677f9ac611dc40494ca66917a6a227b9e6e71a325a3a4925640ae59c96d9bc33c919be595aea76a47bd64fc291948d51409d99008073b2f3356a040cb8a27706eb5ac08d8aa71c716f4f9420b5974078f235bca67f2c8161319824eeb892e56a3b7097068be52eea909805863057f1163b1bbfe98b1963e83e1edcc65e88411836a6735b50f8256d54dc11fceb52ea771930a3987a85b2a73a6e36fc946a3716277943aa935953141c167a8fba5545089345ce8a8682672ae718c87dd63511f81ef1185db0c173159928722202b0b161f5b3a1224766ea1264166c2bc83229fe273824014adb8c6630cc3fc8b19e4bbabf24bc9bc3c3adc5e3774c11a134eb1cf491550c9cac68ec89e281b88709ca688597679a2ed6f73160fcbb0b9cc696da6060864c2e0108cf225323129af8958cb5436604ac0e184a68d22110afc91384cc7735d546e6db898e163cdc62a3e8dc4c20652a947396d5973ff8f0b1141bb361530011604f8f85b911302064c69493529869c5284ecb64bbf00612b259b859717f89bad2bb71be41781fc011cd26c93c7028ea35389817bcfa09b727c66f86ec9497ec90dc0a89402611b71ca6a513cd4e568cb02a7f9ab84135f7c1b43aca898780d150636af51b8e78c754067f872438ac7a6270fa9ba3ac47dfd13de72202740ca297f284acd317282733f652ccfb805d628887b1ac6b22fc0ee4748995a685a151aef80cacfa6497f23156805269bc346eab122cc8a16883fb42ebc19dc2c81065a773444617d0fc0cd150c3afda64aac933823864197cc28a672893f926b562cfdfdb7fa62bcab40157f26b0dc0fc805de81719759c9af0abbb998559759b35a58daabb243fc2477caa289fd194c171be2ae5b66b84ca5c480be10887948aaf86149c5f47b137eb3d2a6ba5738c1ed6688ee6eb7a3c8bb022d19165964ffb2746c5e81b39ab7e6f5b3ad8c65b0bb3b7315484cfb62a96f76cdbd715beb261574bad950660f1f155d6a62d29449cafc43e9b0a4b7a747aa65a825b26282a164976d557fa8a135ee58e9cb1bc0e8bb38e7b931e528c7e6a2139b2061d605909375934fb3fd7273cdd7ab28d17b892102149f6cdfad1772f0b18ecfbb9c2583568551bfb33a1eb0cb91cd5609db35379f71a88e1035d875942d646783a8f11e4314d6c97934595165b23df05c1ab8bcf51783b81f435c4c74d652b44e077c7685908abe138755763974367f0ac2a63f5cac37039ad7919d3c98e88f89397a401d7ea1b06c08a717b582238191f17b9ecc1782976ba3737526e4bc152d86f3d4407549a079fb15dee5232f01a05300a72c073be6147053d712887fa909aa787c401b7b08c1e8395809876bd6d423c3e489e152696c12603f0d27ec9e4caed1bb9563a19547400efe30502d99430bb378ec397dab2a553330a34243839876b5ed532fd469a7df044ffe90354205303009cf7f252dd6b0aecba8da45a8c683413577c787ec8ace7d17a277561a7f271283895b380cd294974520556e072a7ada4024a2842e3f20c38cc5da139a1cc496fa583a1b1410a15038002f1a17352972347ca22215739d53b27e53dca17cbd2bc616a804d314373cfcc1d72c0736fcc3f041455443c443e72875f968d095b18a7f111c1ccbbc0c1a5d8485fb207223057b8d4b754076a919f96cab4db533e2c48dc134c190b478fe6635d053c476959ee4b7ff2754bb4e7c8b9675791d1a84845491902c7cc99a300d4a1196a9f43c816d7013794e1b3402622afd8ba997cb9aab2ca302b8f3af098dbc62d44bb3c9e35871554c6d30840ab3c7127a030e19b4c1e382228b5bf481b0759fbf1adff000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6e78c7085b62594c22b881c61e63674892e8b15be6b3137030cf91834ac0126295c6893f0c386b7670821cbbcafac5d4211cfad5c1f75deb8e7df047b950fa504c189fcef6806e16c7a447187a7877ff91d5aa1f89d9f4c2f8c726dd7cbc688e247c929117e01c8cf93e62440ac3f9affd27ecfd76d525dde13ec8b3a6686e25cea8e46fdb3a264b4e1692bcb1cbfbf6e750a1faf99d8864c1a9beabe0d436b7ec5566c92be999b165ff4f30d6ba43347c326edf4a41ecf2d35cb825bafe62184cfc28b30419f509b631f9affdca2b3b78771fdfb006f5b6cca6d0f5522308543b4a1fc65463d8b0ef14fb3fdc160178692d598e59d71110447fec3d02a58556bd1d17d212bd09d4dcda359fc4ee60dd2f0c73db72ee684a28b550f6b17e7dc8e2bd1867076222033023851676c0a55956e14f2c67874217e5349918243011ace52437a127c1a743a52c7c6fd8a0a007d5d020ec1bfb9f98b0ae36561eadbb5e23b7202d909c7d5fad270542c2e57dd0a54fe7179050b7ca81d72fc8c4f07f45fb2ac905e209a3ced970bcf5334daf441a0ea8f250d41be94cc33d96a42a067654f43047cc500214d0a54920f61728b6e95a014926f03faa1b27f6f5cb4397347dd0744c09ad92608ed7cbc0bae29092d6846fbe0fa14a38529e00c165a7ba098c16e532d43a8e4bff1490c45e0a33bc02738b4a1958cebeb39fd30ed7026b3a015863c2e4a2ca00635475678132e7fc114fc8e891711241942b787384ee22352b2811cfe1a22fb7e8f2e173df93e59cfc98a677a136ec29bbd47bc66070a7a8fa3a709aed2123ce55bf27ff2d23eb87b9762659d16ced5e24b7e825e0b4c2e8a6b6cd1596e4fafc06c9e90a8f0137ad182662f54288da8b590d42c6fbf9bb14cc8f23fff1abcc5885ecccb580d93846b2ebec01bd528547765fa2c231dc1b5ec3b3263617d136a102f6e02458444b158162b80e9acd39ce90db232582ecfd679029c6ed4d5a17f28b4ef2a120455b5933b51d3751728ad07e9d1ae3dc52d690d5838cbfc8c8d5bd7284dca1b753be3cc485aff60a120eff28891e902af0ec3358785a0ac87f99f18f268d73c05ba725de2cbc82d2918f1694c3f6c813d02f341c9f40a7c75bcc5984d5ecc1cc308eb16a9c1971d4f8e6a8d5ba59e855656543c0c7e5b7e49a360bc31c9411da0642bb815703bb64fb550f19fbb0bb993453ab8f15ca9ebddae7ef5acf2910f130f95fe1e4ca602f7e09d605a4dddacdd3cf5c2830a7bd1fafa1d63f7cf4ad511303ce42fb6348397df469a813c822527b933747f8f419177caad0787b63570cdb807a35a190a46f2150fd19c18db91c9435908d79449b23430c1d26a7354b6b9d1d21f31d160e767681580c770bb264dcc24567e88a8bc6512831fba35cf6aa4fcac1040b200df1c60b88a3d7e1550f0a27e8232dd88a9c751624198f811ddbf1c2a833c58b91bab501e7cfccb5374c21482808be44877ed51389234f3bda65c44ab5781da9ee3269a0cd4a3f13f50ec1445c859fc164774cac725a3b561bd63a97170823fdc07bd6ecb46bcfcd76384e7baa0ec3c1f4c89215e26b580962502a4c06aa26068c041ff1354ee9ec07da71b163901784ef525c65bd00c403a9445ade4b0bddfc30e04d278b4873dbd1f18f4587cedf870d958b16be02ecdf3a5cc435b49e0e56775521579530013aea6a081aed4a5774bf72918526eb290a5bc1ef3f0ed9440863c1133a70b1481d46b6f0adb352b3cd4e50bba138570b8e5617e3a10b6382970ace312b95d87f5e8a6baea10d2ea19546acb5fcbac0d20e964b7c0bd0d1825d3955971bd657c316710066d81ccc421c786f7d21df4e748b47111732f1851dc992322d5b50cfcb66321b46588b39184c503666435d620eb03a3535b9611e7aac801e9cf90ecf7671f70eeec6103d6e00a2ca5a6a8424e645d4fa89b058b5f77441437e40bba596d705ba522fae5fb1240d9f9e25c9bcae741b514b9ff33d0132db5f06a73964f05dce8b41a568413bd7f4fc78a4c7dbd2f5815f3dff8f25b2e82a508f5f2fb02087bd23927707bc729574777e01ed0c93557867956d8493c1cd9dc86ef3c1e48986be905101578c8e7a11ea96709929e5dbb1560bd4d9f9acb7957355e09fad7c97712e890234b335fd950e25cf59a4ccc6cd461e6ffbbc43026faa7dcc6df33a8bc5f1dae7e5 +expected_shared_secret = 8918cd0c3eabdb8267e24b79272ab6b67c9ea6418cab15e2e3070f6c747b4dc4 + +comment = Rho leads to a matrix with unusally large entries +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 9d76798256925e67ccd5ccac6d69a85343825b6a20793095e1a29d1b526e183611bad90cf6440bd3e79f847c6b912aa1919a9e7d9357b414cfccb206180067469b294b2c4233960a40e17800ab0ce483c40b653392488df837689fd72da0daae74575da747527b2a116984b2adccba04000ab72402f09c749341be42c79a5c8198488124fe750f66b82cf272826747c68a946d2629a48ce0a777b4a9673ba9c3a2a402305506f4b65b65b327e62de16c696bca3d0b8ca44013cc88d9444a83549af17a3f8270565359b168ca721027479a6e60a28f11b33d88da4faa084b576ba5bea09c2fa8a68c0aa8a309c96119aa52443bae570abbd942d193cc8ccab6e5643d0e362049f1ad00f98d173849afb1248ee2a67873950ec849e9b7042b94222b60bd50720b94d7317053cc86758cfc0bae9c9856c0c4411e74730fb65d8b7b838426123bf68b9804473469c6d8717dff450fcfa208b8f53e2cd8987919a5defbcda5a422ed82b495c67b46264106a613ec138097f05a2f2c5efc2076b9e2475ee162a5e7242cea1598088f8146bc8ea65909723fb7a60b1db157a4f43158457d2d157a1f980925a396401450b670728b2c7ca3aba3e7d4b4fd34b24caa87d45846bc2104e95a1d9a5676b734736fb00f7b3241160c2299b50e5517bd4faa859b79c8590c4322115a7c724f0767c056620bd006c01b5b87d80091bc483e5d341d14149095045d0648acabb46053e78c84045a9606bf82f6124fa9a8a9104ebaa734e3720eb6921553e353e66152f2e96adf34534a06aeeb677fc4f901bea148d28411f1f856b4d2cd261526e3a8139788796690413a50251dc1763703a42ee708f932cdeb9b7ecfb2c7d99002bb93cc248a133b9a4c8e910a045669ef5bc75113ce12f7963d665d6662246d383767f74317dbaaa3d0b855bb0274815442f0b66821cda6aab15672192d20c6aa8537432699ca8a22392a855323ad70f75979b56b392c29caf9c072885710c33967120aeef0bcfca1293df8181ce50dae21577701b1fa216dadf19fee4c35e0d435ffc83de3f92c2b276461b66398c75c98d92628b32a2ac3b571853c4a142bd5e81a8770c9d9359c91ac41aa2b4b063a9bcaf4592cb6626c213bc89c6eee3b75c59a21d6d748825b336f4052c6bb79f4ea13f51b672d1abb32887f1977505a75c13f0b66db14b56956050550ab0d85a814640dd3a36a825682c9cc6d6f13cf132780f5fcce87355007f9021ab5a5a3a69369c7876a5158654bc9f9400a1de60e71e34a370372f24cbc84166ee68b6433b6911a76bd78fa249e850bab6aa96ad820e0dcb438fbcfd9ea81f5f3c0d5d53653ba288815029202807aebb27402660e4b3cdb609bb7145dbc055fa146466b121e673359a8465073d99b63e799cafca95733938dfc2ad7d6007a36a8da027ad396618f1647b1287094737fe518b779f238b1ec0c9351b3c408b8f66b27f5262693826b24842a9153a9d205a7593665fc172c7c835354daaf90574686a8ca7fe5824ab94f29d6a5ac87cc40b999e5e7ade2744e1fe7048e38c804472579d93309986c28962b06e80d0952ab10d1cf1d945b99432ef5074dea9c6f4ed97959fc904e23a3834cc30de35f5350656d027a1e6620925a6840a337d14a82dd524c2077302fd6b72e97a959001d3d81768ccb7937f4aa07f00eef0aaeca877999e5598d30a81e920e2e8489970a31fdeb7d921474500835a01530e0177a44852cba38c3b0c297a0c5bc73db986d24cb0b323402d5355b543468f948976284dbcaa1c87c8b27cc62ce2b8306da3a5e08b0991403e7b0381adb0c897c7a994997a69ac1f5092f8edc480e77a82ae9bdedc724883b5eb3da56648979fd2337fb42aed861859aa6165a800d4c9b964e70195927359378073a84b80219613873a164324a04144c4a5b551937c23ac75e3a664a773966b512a01f3a7a60ec1ee06a068933a8ab0844511488f058b2c5bbc1c8dc07e32b267aeac8285543300bc66f8514ed6aac59cbb9be835b3ec68987a5cff5791643c60841da8c172c1ffc07110c77a43ab34621c474a60a385d153d79831922638740657030481146ca6843f6043cec1de4b0b307c52b288b98905b918bf3af0e698b4ea261db5895f7d02ea0fc59156090609764d09b4a7ed5000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 02c49972f757b82c1f5e7ff048b375cf05adac485075ca5a1eeadb615de1306d6712f0cfc452db395c57039fec57708d0a35b7bb238d1e4fd58301473cc4737d72ceab2b097d513ccd17a7f54d1fd145bc28aeaefd2157f2a8dbea391cffecfc2e1fb86c909b45e97a39b30ff59f176b2359a92cab56cf8d04ca42a08c70051c8d9405fa9aa2aaf5724d8b2a00528b7818671af4129c527bffa74702f02172bf51cb8e5b7c07438c785329807bd022fcb5aad5286642b1fbaf976af9816d3f0a3fdb79c2787f6abc1dd20fbb2995bc2a4b2408f5900c68a60f38f78037c3ddee01a3861433a7d9eeb5e7a41a56d2b2a11615d8ef8751d19cf7bc5e5e46b0944dfa61cee6dc16c490f5c7b62ebb6bd9bdca7dee23c3bf1529a4bf40977b307e945efb6451d4ae1c1aa507e30f653ef476c64610edb39201492434dcf36053f668b43746cda8fefd4316425c92f97e1900c62a91004405349c69497438aeecb876ab534220a4563138ceeb3d4edb0d70330ad031aa82dd62e19d17f62bf83dc3d4e2c3850d47efd50edbab06c9661d1ef274e856d8ae58564909625de2acf771334ffc3a3d7a0b1a382e8a17c1a1dc0f29401d9a3dd198a4ad70a740700301da40b468fc4232ae841489a1169170d5131d9b0a036149eedc23f2abba55883ffbfe4788c887e3248bc1de1b3677f286f1269d110d574d01199524d93263517afb76759bcc2728ac595b004508946618b55b0ca734431e85496f07e153f9707d876b6342cc99be864d9d603c645bb9731890d497d85d955e2d80e2e660c93968873eeca1a51157ceca558c0544040db61fb4ac4e20effdccdf950feb214971dde984cff17a75973b8d3a8cd27c92a8686fb93564def326e3cb617411892469be218d663a009c37e2d573b59beb4c5f62206f3a0df818608583e73d12366fcb1d685650d72ca4f533b928c0b4772ae645f0b0ad71bb8313a601723b8f90ffcc53dfcda9d092f8931ef168ca2f53d4600677833b9443fdc05db07f80c03bcf6e364fd4d85c89fab6a08cc9399b10afcb908cc4b6b6a3f6a4725bcf8de94e6515345e333a8324765ca69ddf9c61539d36c67e91ced0396ab2adc022ae9fa8e41d5a00168cd8c9ad0291f653af63e67b90ff2d448fdbb058702c551d323f5916ed90f6b87e354944e167887c5ea4b37703c8b0a94edf20d188ea989999deafe0a6de995434275b18d17a33b100032f2796749a385d972542dbc9989311068e84f3629bbb797f7c6f1057d99185009b5ac0d43d7b944b2e5f528cdb26ca14d995671e72eb725bf2de60289da1f06d78b137a79ebfb75425446c20b4310700053cf3ad58ce01cfb4d97325a27e5b5eda3cfe1009cdd186313ec3d16f005be47c8f38051cf2108b85ec43aa0d527b8d3bdae4e0a7a711c6fa69998bc26a9a8d2f7433f24f79c0dfc74a56083b42de7860b22c45f0c6e31422080c7a21c8d672fba60ce7652a90a3134f54594eb0fafe5a953e4f179ab06ea6b9795bc31a4f6a7f18bd5f1800a5263c48da4ad48ceca613fadea7741dff9d90f6400aa31519bef0b01e3312a5042ac35362df5e61c8e04eb52bf5bce0505ea7233b516321a08185fbdb9ff8434b4c6a88f880f594d100f46924a26f468c754d6af07f4868cbd7aff2caa53e5146df4afde9f7753484fa8be36baf89ebd4741b7260ff1ea398d59e503f5fd6c5c543ae1d318dc1894a48025c76e872fdc3026bf33a91b4618d1618554393eef6f7816b7de65c4bfbb55353cef9a53ad35340049ec65ad5af27db6fa597eae6499a3e5a192ed731915f6ffac811e35555ba5ffcb6628f812bf71a268620c161fe2a571921f5bceb4d0cdca776c7e52f68140845f455d247cad416c4de040bc37f5421e2b8bd6a049db84f0b3c807c3bb9d47cc7ac3ae9599ce82cebce8243306c0f3de6af1526475387c76751b7412a227571450599120570cf3cda19264136e0a93b4d25a160dee03d3d812dbf172618f58d09645becacb5c287b3b01ce4d1121272747648c50112c44728f66d86bd421390f2b36ed7e18b09a985a306ec52f240c0bc0957335483439f146b6c340f7e062a6059b1d47750c11cda575f8a2aea78ee09af0e06dbc2b2ac2b2bbef17fa108681dc90a7b970306522e521aa987e3ab6dfe2e1b3c6d9fa68897efc9e998afe55620cdbe9ddbbac8a0e22395d5628a +expected_shared_secret = 6e63c5ca8af98628c02c8f1d520615a1a2c4824d5d155a6e51d181e8eb44c7fa + +comment = Rho leads to a matrix with unusally large entries +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 452bab83196c047889f7eb13897b3d73db6ecf5c9687c3a97d5b3fca3071a29cb82902c7a4e673f56842129c4e27254d50c2a9741abedcd925a62796d9a98733262e45366a5d7b81cf7c9b3c42a6b2f70626d0adde9311239061dd893669404058da8d209ba6a6825e796c84e765b348414447246f57acad8c933dcaf752ef268bd6246f6b57377cf82607a522dd7028b572319263c9a9805aa6501ca4ec2a182a25cb751ad6f0a0a23955986155e0a1b0957bb9afb35320da2b20e29210b2605122791db13adb91a0fed0b36bca7d6f03b0ca6c8597b56a189c10ee887b4429b0cda99d83728aa6f57a03d182685b2266ac1f70645b123c0ddf352520332fb5ea06e716b010f82c62858c0408446afb0ffe23ae9241be953b3d05a9087f8738143c3c66b5b3c61ba1240b99c2f50b620038d775706aa58cb0f7094d52c755b992e008c2419b3b4bd85a41f65bf633136867caf5872d551340f377c06546495b8882e4e14df8a958a501161c547146fa2132160fce98c830a5b42784cfec7410bfe87f185657a29508bf339c7871ab9de91423d23e90ca2bdddbacf7f4af0f616e9626a3ed4a87b9b900b2412b0b5328104479d33046f54a06cd88a3d0c9780af5807e3517e0c72d45b17106a136e68a49521364e8661636f250fb679d3fb649a0491d349a6bcb49a4e06552ec60b33f947e37fa11b6742ca9119f0c6953f8175deac4576292165f42110c99467b008f53e25308e560fc845df84b28eff321687c45d6d09d96533f1d0078af998a9db59cc51b1ed4ec6c13695fd33a768af521bc9c39bbf6c27c6266ba271e5d8cb89982077f553b1dfb5341b5caccb856a7608cfee57ad3dcbd782ababf70c4f825cbe1279b304c2cf134beb0268655951cd76079b06410737cc10550c16cb9848612b6b7652d4ca9bb5be64f08236b69a097cbd10014e561469b7a68723160d91632d67f4908622876a29c59682579b34a298cd01597887c1b4d100ea724ba3fc8960356b499825c5223585024a478d34561a98d0c23930473ad6da637666b454c7882f0a98254f41caee03e03067b3a001f303c651489c1d00a825537c2412826a73959f085c5d6a836836582d938b9d999b591019219c906f6712fdb52b13bb8708d0c570a00bc40f1168b80b9c11a4e72430943c2544e2bb910ca5c4f0b245f4bccf0f0c3a284757bc6c535c6a205b34cddc15abcd92dcee9717b413568b461e2b9035756a312414e2644422112b49a3a23eed98e07884c80a6291df38d5bb039df15b7d89b5021d691f1a165eab9242b34146f6b223195bff19c6c6197a5e424c59572502f69c7a8b633534786e4d8c1e280680361b8ab5657b74336d72571bcd12af7089d4a23c09a167d0a3bcc540b8be036b24664bdb3a13b62c11eee93c4ff5bc0bcd92f186741eaf56a5f6111f161b9158bae9691b8c99cbae21c9534da07d11930b96751e3c29a804195a18781e016b6af45bd23e8297759a1d1487c6212add88675cc3b92de46c09b4315c9a0cf6a5a20e7fa9ed5d594aa95cfa3681e42a3543429b9ec551e1e74ba46b79234b8c69c0b5f9553aa12455edd971ac29199c04a40d702128cb77f63d50f11184d2d0b66befa6adf7c2bed427c82a632a81497c3831e38256784802fb7195e40b571c26a925de84f6366b3d9aa2ecbe57ac61283f5ea3648b652f0c742b9d7c2a8c00ab5b611fd36458ec71f1c49579f96c1a774a3b4179ea63b4fd1e3b172b39eed1bbbf0d27aabd1befa0232440b336b53230bd60b88da4c116ac47b971de59a214a0752e75888172386ab2ba525ea50492a59467a57713985475108501cce687bca50b6c8840b03bf2a5072e8585f33625a9a8c17160fd7d630ba54c2dce9bc0ab2cae4965ddb9110ad612c65c8203e7b462ff86ba28abedb808f70818f022413ed5a9a3b0ba6aa24685fa91d5938a69693862e31aef5054af2f9849d3b1d22e121fec251c8f358a0d320efb9299df6194cf6cc5cf0c11363114abb8069e57634ba173ae199b080c1d935558c16696c97a5f316a4b8565c20b266802c60d4272e49c2a5ff794bbc914240f81317558a8cc862d9783630d90d99f6a68738219c44b9ad5c07b7242e85d71f2a958398e25047f494e7f6acfe339f98cc2d65c114a537b1259e000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 841dcaa46434e75228b0bc10733771ae67fdcbef99433463b2aaf2da88a98e1bbc748e1d14239a3a91bd2b6752b83302265c58d36f176b15988a3cdcc0f65cd72eb5486913269eb31b42bd0ccec456b72ff18f3801a1ad44c3ae6eebfaca59f2ee8308bd6c4c05a7262a01f168662dd42153bcf885ca7e84adfbaf6429bfacfde0ba36426b17dec09cee0591eca54dce505b6f23d2b674fba0a9dffdf7e77ee007e7570b31c71723047c3e8a271d6876261fc1766e1e468bbaec2a42960c2f0a3ebb7dc5d5d6d75a24245a375d160bfafb01cfa2c08831b1ccc67bf9d05df3a14d8f4b170e145311a793a92b1d59602e45328e58c5842dfa6d7021e1c65a900e0b04a79b17edec62c5d1c2bb8679174b45da0cfa336f7a0973923b8812d7b2015e73c42e1219900cfc3cdc93824b55724acaff2158d38732c429883b4d461b74a858cd167ba9e47f8157834f2e758cfc1c8f0fc5e762d56ead723cac0759cfe5233473b9706be8d909c1bfb2cdecbe7eb15b74b181e8fb949aba6b82e2c7c1d40bfc43cdc758051d1ad428a43bc7708ea9b46ea3f202974abf44644c7614769c9fb39de6ba9fb3009cff125fae0ebf0ecf5c9dea4ef2b9a8f26fc5d27d875e068ce3d319f816000f1dd560d03cccf97c5485ce65a77a326ed0fb2ece5cd5a55661c7b41f4b08486770cdc510f03b2b85c73b95d0d77b0aa75f677682d0a383a6e69ece0d5bd62568f2f50dd64ce3cd9e51556043323729b165e4c6726dc77c78025faef0653e54c6474834b9e2b51c66bfc8fe90e6e48fa217add307120ee0c00e8ac8988e5765e66dd0dfd92c80a3b19eaefb46585f0078f5f2de0b9c83ee10996b27b7c64d0f7b4d3be78ae18030bcd792e83bbf99529d1e7917bc053846268ded779a622e83f5d2fcfb0c15bdb1a2621188037acb8999ccae846ab2664792b043903c3e6b59c2645ca44e2b19cb21122035f7f3b222bf382800df1d1d8926eada144f880ecc739bb5644986f0a3c1b7cabcf3c9cbc7938802274ba459c1b870ddc516b5ea871fa6bd87b8cc5e47541f1dab3b9fd63865bb514b85155c41780b6ae24a02a06804a319d3f8d81383e7c8167853f3e24b35e220c105dfe14c33441f928c6dcf63a606500539b602f3b3f547a49545fa43f3fa6bbbd6049d9769ae5ac0964d00d68409abac87369f9608f2d244935aefce11e009fdc9a94c4a803eff45f989affe68c4dabbb291de0e7251a82bd5e5d19bc165fafa25465066e23dd905dd456e0d02ec3cf229c330d404b5f214a37363bd997979fd171584a296cab6e37928940f6bde0d1ed593903d86524449ad42248572680f1b573ede4ae27237e56755485657a5f542577700680308cea4a0d249e48138743017078e668e9ee556c7ef5a83cca9f96ca22beb7e30e2df1a793c6e2f402f109770ce7763eeb057f65bc0fec1fde8ccbeef1441dc98d059d1589564debb2a993ce21031c67d4d8c61ec53160be67aee11ff4b901bfd7c91f6e1faf7aa525aa8d15c3212ebdf0e3a5adc57690d446fcc9435caa5b1ed174b96d4da42851545ce1764bcae48c5fa580802eec2d1b83e4307c1da0dbb2a0fa414d2db8d6335f898fec5e391d0d7c2098e35dcd68afa8adc29d5eee9a9cc6a517ed310897e69eb23ce83e5ef0535c0f64d4f8d62a962e8af80f47a7f76cf735ae4ab09db0b806a9c4b2fa9ee493d69e73af045e6a1eb07b5bbd3241ccce8b5196080c2953cbc50a2052126ad754dc971050150d7ad4b319fd85cec8c4be05b55ddcd5ec7e804083278495b1601792464202969dbe01488f876d1655e0a3f4879ba41712c9136ba0f99d4bbf3145f34bd6f4edad036e6db0ba2532e35c6c097820d1fb069f9d69c259fb17b94970f2cc8284e5fd80f4e6070b4389bcb49ca99f207d002e44f6f0c9046fd89c0ddb1d86b01007c02920acafdf28e49d3c209e3bca054b67398b6c6c2561004c129947d87d33390d28489855074a6777dbf72816f0e1bf9488009bb0a247784c8a9b8f13a163d86a614edda8d205058071c12845b21e82ead309ede45872c379417c536ba446272ffb63d924d0055a92c320739d364e3eafcea6d10ee09a58a70c6c9a88550327070d6de72034b8140976856895147e2a1ab4ad062c7d299228a50b605872e3d20daea3e918f2dda9f8182aed61c93b4a47c5796478e182ba54c87fe +expected_shared_secret = d0ffac51bd8b7e6192ac5954b26a5c64f4d0ea746b08d9f73602062aa8aaf7cd + +comment = Rho leads to a matrix with unusally large entries +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 04db6353d04f4a88b97b6aa5a6a42a101a535da323cae6c7dd757de67c24fc0c1dd894ba24c26c873172bf2c1ce63c56cb98189d60587cd76c2ff70cbea93a0d0767ff347a071333986226a8812677e2b5e18a15fc5b2d23bc03786b2faf8a9d2705bcb6276d2c140509f67a123a34a98bc879386b5a596b4fe77f0caa5145d766e05834658961a4aa3d5a90bf9da5a53ddac964e62216d0a6e39934f00c6ab988cfe6334a69480bfecbc7b100b621d471ab51725008a21f404142e489cc30cb1aec8dbf99038c8989ae8c477c198cefba1f3420951b660026c820fb406d19fb0878677cbb852bf5978d99d33f6fd7c3aad87585e68e5dd5a444a8369749ac03902b91000c0d986b26029005ac6daab8b0888a75b75bb667469525a70278945e2847cfcf242b420a10af98cdcab58417400b9d58b68f3670aec0ade93996a8e16d63337444d0b7de449f3ee63b30aabc9ac2b77d5bb13d672ce9db86770b9c21e11ca3f42c2117654c657da94c451c319e1139088d008179707eccd6a47d68677c692c9bc7790a6311dfc244d1c67eeb3420109404a86ba668e24c09b6308f3b09e546cb20db4117c74b4124946735ae70ec8147bb2e24784c3b4a24eec5ba8de3269054399a623f0050b5d0c10b5f5139b0786353504216850c85677bb596b2ac6a5fd4c224bf61ced0fb031411a887066d7a5455afeb8309058485386a023b6c58b5b967557a5b291698d488a131826b958df717caf472118d96a3b6882c1e95240909886895a0f5946aad1c690b7a904121688f5685ae775738307786c5a6915baee72b3d71103a96860afd696bc70b880c019e6dc77c38e33817db195ffc2f7cc37b4a6450a2e787d2e65c55748be376af57251974ccbd8b398858971eb5ac62f7156e9f2b43d6c54a51c40c55156971804e21869933771b3ef64d16e48ec5195018425d32b56dcce1844f33600bf366b9237f6ba451fef0816d17a00542433dd7312c474f2c1abe2e3a1a12b303f9d42891b12954473f6eb41ce2014bc083732e7a4a7808831ae478bf2865934437d4874b6e5132ee99c727798aac4b99c7494fb555a594d21bc99a014001b7d06612c2b3a8c7170e99e037a2d50f33e61156c519a1a15dc78a60afd1c2c159375ed570878c319db912c1745b90321ddaa48bfb80411197b2fa146315bcaeb292714ab7576d946b3927a280319395dcc4a0c431692c7848d10a36dbaf5d78af33f62c25e5c4fb009be83a5b93e054e587393c48ac1c65a524a0cb4e6637fdd90e43346fc9a45a720898d05b4d3743a0e2e40f4cc77237e8913ac0557db49eadd7cf00c3695379b06602c332f57da6409b3b888e7c06898fc4412444c677482003c73fdf07ba45ec968591c3445b14053a8077e664b9964956fba6faa50d680352a4c8378d208940722bda766910403970e3b50d863d28400512d7adfb372052f1cfd3b24ff4e46695533449dc232a14604a08b00da1ad81e31232412e72d180826b968513a2dcc724085a3ff0d5c3a7361f861a3e02b0308b897ed9d35b14a4159cf646336ab8c0e273a6915a14297abd937afeaa3f62005a001417d91699e4166740764cee25b91fc2c44753a3bcc2a8144174cea18546fc513028018aca8cff714d6eea7515db543a192d8695b1923642228394dfb428cf167201bcbd1e217ed1e2391c616db739b09c9a0996c5bab53bb5e1bb3aa547937dfc49223897034bcfedd55599e15641bbcd1b0072e11ca24ce7a828776fd0c94bce2738eaf13075aa7340d51b30fa0caf857f1c5b7808048917e7490ab0739147b7cf229953a633f080ac80c495f5b03355bcca47a94b60e95d72a29147f2b677c6a106f905f5349933b0b7600358fb009bace2c229246aaa51a95842cee212c11a205711125c4ea14d68a833c2892e8bd265bfab3e7b16cc2d34adeac46aa6e92598d45d972577fd76a9a7b954ad1bba6ed63132a375aa29b9eaa42366e2aa8da0374a19b16389a1b36c025168584a91a4328071de904ff9162a06a8bb9b9030f4571b1166133bd11f9fb9a2214c3f838a0a6106359e778fa7f504c6e719ed9c2ac66479eb1b662c8571d7e398f80941bf2ca0b8791bfb51693fa95894f25f2ba53882e450eaeb0b3ca706a936bf22f6056588144c1c3219f0eab96c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 8106cd6746bff4925c2620882d571c50b36b066a5ea43fa6528351d97dda7dff1d9e9ee6ddc640ddb88851844c388727c918152c41c814be39f274183e116432a61f9a7c1885f07bf118e4ba631598fa9b1e01e72a68ec43dba62235587c9b9dd1c8e806174ad612a2ffd477e8d0edc2ebaf4036393283b55144b9c83cbb31d1674565abf29a56980dc4a3803a389a20dbf78c78a907a5d651649c27c9771ef436c189d1922564397f5b5594d7efa951ba7d05962df80c49c1f73029c3d7899852d8a1fe03d1245a228028cf713f4403abc64a9093d782cd1a6dfe12a79098e07f40904ad146dbbdfa919058149b051bea097a60aa0373cf9c0803e8da99c03a6b83813f99adea8c87e6da09013947cbbbde8edc3b7ca29f3180882cb11bec706f4048a20c5938560ea83380be5cd75f48d77bf3360fc131509317dd72b9340bab91fc6bf7ce099bfa58d6c5a413fd2801a15ce7ac6f6f2c0447cba39987a37695468cd0fdc982631d9b0354205194323e74d41c54e0a026c4e67467b5595aae7c8346d1bc5538ad0acdd56fcda32f95dd7830b65b2d98c05355a3ad9c84cb43c23ef9845250888ecb6f992da17f769a13bb7bfd621571f98b42a9aaf19d0626d7d59355d9730371b29a3868b97afd7013142866e0b2f1c54841de47c47775940c58475c96a4881bc69c6de346e05f55cab15d497392fbefd2309a834c733eb3ec8df4ae65ccaf690af492e39d0b5c91d09b39966b31b47ddf6751b481966f19758dbbc373debf284640015cb197e53120e0a36ab02203e0992f35b4c8347021f8c4663c996597a466b416cf271e04a20045639635b904b63250817c29451dd2ada5f3011500f705c2f0982d236ee1cd02944e35cfc6704f0e8fa30d8d2d595340b4245d3f3d5246d368062b53f06ad365dbf12c0fe7f492690fbf3389d234e76a618e63f785af41b2f4af70be0bf0a917df6a5f34683d931604c6df9288cb9e38b8d8396ab2e21a1c9a54f4dca2a4985c3c4aaf20af5e6fdd126860df422a894dff4a857f2a8aa54c4bebb70d44a4ad15d47497be7e0b7487003ecd6f92cec84bf4c459eb5f480dc20bb6db735cfaade1ce33782aaffa6a39e4f2ce9e7df44347b91d75bbe71b824d6302608dedab325d00163cb9e0a274ce49717bd6ddf4b9c02fb6986a8f765ed565f48c10dc90f39b93aba1a69a832e41f2b0dc2113fee500c99471ab67e3ab5a1cccc0f92273739eae4747de461ca3ce6161b558577b56af9e695a978970473dc671efcddda2bbd8d15fa6eb8ec0ec9f479bd9b8d3dd4865460846733856fd57664760bbd5ed354696ce6c8b44c6ebbcb07920cb6c3cf769c005503add472c7374b8875d714d25c74e2d4390ea455e00208763f56e475b630a30875bafc70f87f541bfd0a28839d441ce567db3be7a20e2773f08ae73f9686b95623fcfa7b1b3052d64448756f9a7481b1d9c6022898e79afd4c2290a9ed2e0658c6178826ce94e0ab460798a88cc54558c51239bbcc5347d59ac87fb6580f84aae6492e1ca700093438889fd50eb7028153e8b4675fd272667fa022b17029808b88df427ac048d8b410f60a56ac39220f8b509ca93c34c7dd62934f62a7e29aa3b0918299fd5c56b3c3158775a3b3d5c78aaf2f656257fdaaaa5b7daf83294b5fc48d08922ea6f5487d647c30b1c11a30d2b1690958fd90107a0d6cc689441a36d04039bea83c447e79b04bdbcbab04427949855aa1a32790075438ca6ae6f7897581b4489ea1dbc4c025fa1ebe698959a8145e8f11aa1cb6f742d1be789cba73fdea457eb0abf1e814c931922f451a7d59514c3e2526b1378be1ba8ce317ec3fe2e3d983edb346874f5251d197ea02c7b16fef2b7ba8cd3b0179b1f935d4aa4d463bda2d5dadd6ba96c0ad630f1eff86e34dee3f2eafb9cc5f5ed13dac2149a583e2af8db3a789c39f751e645acb58743646c6f65bb12564b8f26697e80b8d9636b0833d71433a0465dd501eb313158275608390568c7130ae5f998d3819ad7f3855d26ddc9f4ec07a36d191450dd6502a28665eaf8235a3f10b90aba654c70974038cdc9b3335d9b865da8a07be70d53f6a5edc7c4a5f4b5220c8e7fc01f5740360db072a4f8d7e80246dced5c75ad642ef1b41841f43e6e422f4f9131c1b3f505197f18571b057ed1cf2dab2f37dcb88082f8d8291d13eb7abdbb14 +expected_shared_secret = ab923efab9857dba5a68f9198c4318f54a42aec38d194133eb7f5dc172478e79 + +comment = Rho leads to a matrix with unusally large entries +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 61e61727c66c5cdab43ea53041e25b36b56a323a12f70c99eea25fb4d387c1aa2d871244021a45ab27a0709583e0c8652db31167da21ca46b84002ab009a8659656876a037e844b6c027545cc66d783713a79b1bb5021e7a2c5deaa900e595503cb1bfc394cf65707c78a97ee522be49c2c08de89336b4b50270ce189bc81fb6a464a853262791c748714aea70e79a6967e62566492157b4bff737804b014c69f41eedeb07e47cac957b4ca937cf4c907189606a9187c700a7b6756c5694b285ea6171625038f1c729a7897e5cf853aae66104fa1e6c66b86b643b1e37838f85bea35132a4176afefb2e6254433af76d5eb455b11a0624fcb63f7310b0c9b171d62134fcc361c2a58b12b2c53530fb658b83107e76006e43ca74d9093fe0ec4127f5866c306b791b5d033cc834652e6ba485efc76b5289304b3c774e88ce0173012e0203eda7a71eea170517114ef93f739501c6f9c9a4d56b77494f82c06753a996f33721a56a003167bc773c44d685a2aa45b61744058a1a097a14299d7a5257e27f8efa796776249878854f458d7e4b70db914e888567e5aa9cf238ac4187bd783570daa77c3a9854c11c80bee12374267da446cb1a3b5177c112a3945a92596093f77c3ea9bc2f95452b89879bb6c0028b653cb6c804d2680da39cb99233067c7b9124a27c4c6558a641718588709ac86d5c57ac7a1f1aac68c9c027cd2c0433a139f17b2972a5a81fc8763ad92391e818a8b77c43fa7e71930ab5934d58301c723825f9079ee9ebcc8096a1c4eaabfb5b73f070b43c3112af289c09d908fb8a2ab48786db29c2dfa82a16c6c8a8b34f83583a6fe3a630b639631742adc422a71798974727e2a80b139872df5420c60954a453633bb99dd40098be6952930cb35cda52a33c4728eb31fc7048ee5176ce947b194885395163af5aa5f2f53fe8c9246bf6143d199d2a797dd62b0fe67042fd455acebaaab2bb61ff778ffdac5edaf8778879c5517911a468a583286bb4d11a7f852ce921cec823647226c96110063d02a2708364e585c5ddb3914a27123a8c6ac89c6f98260009f172f644b10a27201a73812de28eb9f04cd0e4a19080001d082189b7b85c788e02324b2f4b07dcd4aa298b44b0f49efca0b9c0811b57729ec7ab7f0a6a7bd14c220394a2609832a26b3b8c29139af994a5c96bdcf13d8fe21c225b5e5f5aa2e0c7a21ec3a8017c885ab5a694aaad999c6ed14b77dba90fc666c0ef88336d79b3093719df8179e25bb59301a67548cf74122954e34fc5e94fc70b931a3669314605d609cf06f25f74f76fddc056cfa4654094b724636f49fbc3964a5ccd79580cc8a15eb07eb4061d528a32de192413d388b051660d43507c49720ec67ae41461b5ac87cbf91dcf42af4d38680f450acb9c6cec903807153b71613f02900117ccaa11e2cbd2885187a49089b63c3f1106fd5a3070a38b25c9757bb9b40c80c6fc4611334c4463e1aca784af6bc38584a72ca4db482361314fa1b18da660f440ab6c9167a4c18afe6395cbdc5320fca49aea990e12ad6863a0725863dc1009de81abf3d56ed4c70258096f6647cd3c5b1033512a742984af1a08617aa63e1b754ec93e77eb1f379532cebb7d4421a58bd133b9ec264ffb252bb8b546961e2f602aa45c5c20756f51c0ac29983ed95036758b05f6d90aaadc464e914004ea81eb74162d8a1e4bf986120c1e9d13cebc774677577f86c10addfba2b9486f9123458fb20e73c32c8a36a60f457074ba640309a7c9b744413a5622f43ef3785da0b77739e00f1268b50e04056b0c2071f8ab5451cc0d2861310806a4f180867310b03c0fd0d9781b3315c0da53d30b5a84f27962326084b4cf8e88a2087b420a9299c34a517c088e12ab2f54f35bc4542b85d455f6e9307c949cfd617dee8153a46c99fdaa1c00795296e9816e557369e34bb25b1555199dbe0a089cf83cfe019e5d013c6507294ce27e51ca5e805b894c13655ae6a0f9da6051706d46dacc69ec3898fc58ddd5c75e82345fd8137cb606a7707b4d3bb801f77b615527705399c8448f95d3c292662957e48bae0004acb52e55385f0cac2a9c76c471e2654968113c98be84c89e0a49040ef23751521558e677e32089a6969beb0897f74a52aefa2a087c454ef26efd08a555d6000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = c60d4aa71649960bedcfd1ba225807739b82f912425f50d32153167826926e51f8ed961b5439fcc7a3804d55ff46d5b873e13a0c8ee7606fbb21c5e121fb8e60377ec46ead034bea9c44a685e7a588875e5bc2dff98e5529cff460ef5fd1ede8d4cf2b02e9a537887028150d0d79ee6a0ef2f0d5507c42ad1d788a75899d0b7243f7179af88cd6b7fa41849f1f49f782eb0bb727a9b0fd51ebe3f05ae80fe7259aac42c8b0a70b7b74da297c03dc1f06c44edf72773958e5a0d38aa91c35e71b27155e875f3378ad6a2d064d6d7cd56689b1a42dc4a26ce2cfc8012e147940980403bb6bc164f3a0f9055867efd0bdd3ff4c36ad8165aaba00c8365d217d4bf208312f3ce9fbd7bde30d6e4d3f1a98b0a20f947d03b45f3a25ad481fd1dc271a0cafdcc04f02d314ce3da2e1aeb00c7d3a88ea3ea2783b75e16768f0aa122db015492b0ac9bab3d3f85fe6d8e32cfd66fab8e3138402f690bfd3a5fcf09ca27cfaffca96181b8a906a67d93303069ff91c2e3e6cb26c5608bb04e05ddeab18ad3ff916bded7e9e27c99492b7525f95e02833ae827c48b1f4ef06b77633a66ef85520768b64641c5b1b3bf319c390006a026b3a77331c530aa5a86d0e329d4c7bd729992e3c574876ad9a29d79b09018e850e2e63d51f75861af33e6acbdabb722d41312294a9b302aba8e3f04ab1f04688e373f86e3753d84070bda2feabf6b94617cccae0fd427f90f43d3b686fd772292fe1c93f355fffd2683eb8dbdf171b69bb6a5c929b7109744f542a21539e04151ac7e46f5d4b8b151981d4860a366d3500c3422a2bb5c24fced0221e1b84b9e5b587e9bcb87220dd92c127be67a396ac18cfd3470e715ebd320fa07097122f696ff81923e4c2d3c0310bb8b70690dabee4e17efe6d871b32eeaeebb448f7d65fd60e7a3f32cd07e61948be330179dfdab4d748d01694d64edabfa95647a21ceafd5261cca24a0548a135ca1f7c262952bee7a291857062d3546dea97cd745050121c82a73ec9c0095847e0563229ec36046ee1564ef3747b49812eb2bd015025f077b56d63500bfe523689a6be7b886fd8aebbff18cfb6e4ca18c2d0dcbdcff8fb7a9e852f81ffb39245abc6ebb9f58a28beb15942cfd5f797dc867f7a855a3e6ecbdd9a8123ecdc30c7240d44dffcbdca05bb17d524a791ea32d60c65dcb6ae3ae3b724ae7da36b88d3563a63f4c059fc83c97ad79602cd7701749f92c02bd65f505f407b64ab3f8417d3de5631804eeae565af62d7fbf95bfe25126aa2494368bab7afabc23825d6cb03151222bec05b09a3fabd5937b7a0ff17246564e163d049e0724456576f250045d13d99aa07a5f298cd76ac73f69c3547ec9a344998dea3448a96480ece462922f76f1fab68d030796bcf570298013001414ee238a8ac4d7047514ebd5c3e55e051846403acbd3d7a581c1d53084eef20edce56c2f50443440ad0fc77a955c1e5c4d610cb45f43435b1a66bcec638ce88126ad88bd1b0d10cc5aa23789d5c8f4d9c63cf796e1ee6f7fb309855f332a648c731775edbcb4968592f1f633a3fc74bc5fbfe9c0e74d8379fc56f869e63d8db3b9ffa92e9b470e668e10acc1c7606839f2ec0abd02629007e3b1300e558e5afd136f949eb1e6ae56b5a8c21d15ec4b62b22af89618501c1af9992a3f002242288fe01140e2476ff900afe32685afac7baee893bcfaa54c1bcae65b2c9db04b1e17dec3821145daa041150f3282a500ca46c535ee47ec02b1a1639713354bc4ff7217ec169a63bbf26a26b2c712b02c76b56a8ed0535e3ee1c3f118f2a68f9c699ed8702f3eb30328118922b15b8399a3fca410dae21e7d762e6e45c8de7ff023a75211e42d1acf1d8f506223cb281fb9615b2de1848ad674236e768a0f315041daab6f491195453081535f9235f6d215e5750226ae7eef4df26469cea1d0541e7932ad917fb360f4a9d5601126b1c76bdd1696e6d59749635b844c9d416a12d0eff4c4a9e7f40860b047ffad7bce7439ef0fef50cccbdcc848b02f66bf67f2d3cd795242896c5f2cff82864b1d1f00974c9142d0b0ef2a8d00289238e822d352a924c689ab15e6e5b201ee7ebca1253b9964a04efb4d7af21c6ecdc03365b4275d72502523d562209a316a88163ca33ea279702309f8c2373514d459a5298ce6999571072852d996fa8421fa594069645f034d3 +expected_shared_secret = a6ac9ae3077504c8a7b1e5558a0fb1e7d60cd2bc3e59d615e68d5165e4903d07 + +comment = Rho leads to a matrix with unusally large entries +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 6328240b1a7286c71c5cc17284fb5058410381c74456c1ae3ad93735b6c7d0e13621c924a67a44937039df4b4da608ab49978109f077c961c2e6d02cb0f429fb04bf7b32afd9e0748a50162bf49ab17602717b25800ca3c762145636adeeec6543c43dd20a2a194211030971f16139ab86a22fe07664b425e47240ee1101cd171bd681a681804d38bc4cd562b7675a1a4fb113ab476fb7e67009c8ad5edcb053e77e99d10a348851f266919d29204f5bbe27e8672ed92e7777aae4141a8e81a39cd83a30005127289092929a41b42db3ea2c3b9b4e14a02a45906e871b5ed4c5067180aa97a6967642a5ea52639f27665a78aa24511ec6bb8ec7c3ca2fd34fafd5b5397c75c8144894b56d61e57ef77725ed8909afc703c6cb858fa1c600556babf3cf4fbc089595606f450753c727b42c7e8a8c470ae99e40e518d73684f2810e1ccb187441873fe14cce8628efb360083029fad17c1a9809daa08df859a0626365e0f1ba97ab9bb0d09e3b2632812152ec6361cdc65307f916b1782eee7873c2313089f3bd0c5ba938b80f1b43c7fc6c3f801444a34ab9c167629076442b1cb34c9b02941368c6377098a7618ae352d7cb1ed9419d56158f9222c644f58c3efa5209317a165434b86350c1a94d21fbb065854534120e665bb73266b6a392a60fda82b096701cb100aff65b44a40a4d8c83f8c63621f44a6de22f9b4817a2772085a95597c309b6423b9710cf72720598064717b52a336a0d3d9b6092e9a445a3c507e37ea9ca126b1b8f4f702d55959faa7b80322045508b2025ba64575049738699e2e1a42630c80615724dca7e98acb40f6415f6907e3649962c451f31164e88601cc2c37a65c636b6c146cdc24e5ce6976bc3457277a588118712cbabd8dc273fd0c8c3835fdeb500fe035116f6beaf437354c39e9152c3c9999f5f98281096a0f1cbafbef24e87bbce8f88377a0a3541eb128e31a0d77c247dd32180b97bf6f8bb2f611e7a7927f7ca25706cbc7b52598b4865ed8b520aa53e6199a96a0bc79a09002e07bcdf78473b273028b34e7a7c9f71ac38bd6327ea4c9acba59a07b59433908a3b8a4cc5a01d704773621b4c750389e8557498747ebb3b8b41b99105756205b2b578f668de8c293ef989a934cd1c80b18d700f7666986fc445854c9a6bbb8c9ae050c6316bafda5e98aba4ca0b92e3c3a43c504e214193b43c9c9ccacdf4ba85a57c6da6d1a8b310c4f0b7390c7001e8004beb92bf55cc8eaf37ae07738a090018e843288a965d4e8bbbf9a18730106c52758367361f558272f3887762ea91c35a23a708394b8a3b505098f7ab8ba505bbd1763a0339084f3ccdb2e68ce8b032bc217d51110c6cca10f277142a844ce5e7c8800b5bc857613deb0e5e59b4acc72f0fa1bdb0f016ace9b02a43a49e83c207e8ab82e98fa1144a47809a5dbc5be622b1bb364e8000cfa2c203f247706b3b3dc520bb308a62bd893c3bd890102bcdfa1b6ea91cb5f86758d5339396184b2ad4b36d6c875675261658615e55c85839cb10ac8c789959cc675a976c4b88146179d38820344f319b1621248577294d4550a33e723d65f11f3f654f11f206a7b4c4b909a4b1490f41d68752aa4af2723ba9c092d371c0e2459c9361230cea1772ac0990b6626a9914b20769c51b2df3996639fab765164a7b61280049ba14d55a98537e85ca0d8259b14ea4151c787d49c9b2d291c9e2b005c13a3d93a88840f9a19d30c346b14b413c150818850bb8585ef0263b515a74e79032b3c561ea543d652076a38fb4f769318378510a8e277334c148bbf38868d74ab56adb16f75a6c4ecbca6e1ba200874567fa5d1bb42527f123faa69bf2c45e4e79022799a717c21260e3585d6a86b7582a1f166dee7015abe11b42a961d60750e2e40ffc82588448b515bb4afe246c875297ef87740a775fcbe0bd902c67b9830c6d318523e422b0060bcc5a5a5f7b267f5b53e111c7121b86a6025a0fc2716fc11025c857ae1926fa7066ab527045d8244c75bf13a1a3c6688811d35ad23c1435b4cd536c6f14f78bb5d34b4bb34548a375b93234c63645d7ab59580567f9517604837fa6f98b2b4911d9946a54d0ad2cf0747b4081b904a2d6f953c70065b0c4b698e556daa27cee3b40070326f43c3d93a7cfc649000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = b0ea35919c0560ba7caf9fb6352b36bba962cd45d3d2b7f6bd97ebb2a3ba6df22e018390330f75cb4eaef8c9ee9bde4a1f25110dadf363df31f3f8702a3c14d5d2da303bbaf0fb199384a2702f7089fcc63acfb29d5e53571102566866898055258241e5ec4f1a325175cf3a64a84ec50b4e8e511ec24dfdaf0ca79911b1d84b5a0872fb1618edf364ea06d7287c6ac39e842c56d6630ef38f4c812a8d1fcad73f2d4ecf8f7033c1f5ab982c5b6b8c5545237c4a3ba8d5ece30dc93d1d4f4e89d3bba0b8149ee5c2df793c8779d45de92630b292714582387e60769209ea7d00e2f1173f8817567f52fe53d908d11e8e77375e7d2f73f44a01ee3c87c8f4163c579c40ce70dbc006ad2426667650c35d80ced3df0f3f626fb52f57d874625d414aeaa658a220a4ee6350900dd7b1b9e165661b41cd0c96c3b665d789a297f6b7b4f261e6dda3f6b027ed8a308f1168627f71656bb0ad456ed2b197c672d88ea6bd61fde6dc3df7e4d8b505afcaa35fc1d9b5df57b69679811ab5b738d62a5800555fe282dd4d06d5ab25a3847b4f22725a2360d8b47c69458b55f485a1ee75918cefbac2b4945c20a7356d1b7c69f1c047ba355496e21eaa2123b5b545e86c23d4cf27011e68611290161366d6c12b340292113d3973efb312b1474807f8cf735b76bb3a722aeaca7b865530fba177f9016d1ad1a7bd86da6f657c32d6662e57cc691f5acad0faf4f21027fd761ae23456b599333c9af918166927c6253dabe508c7d931d50cc824c589881b39087e02b52276b9d4252c08199dd4943d72b4fc14e603c9e901d0038da715973b0d168b13edc26b20e2649f37d27c9cacc7a8508ab340a1c3ed8d26099171bfaebd39b0b9fedb3c195a381b55c13365139063e5525400127cc963d9659c964ef3415b31c3a2a923ed3b96ffd327d6eb4929ce1d0d26232b46da119e5e38e71a2dc97bb953567bb5dde9c2d19bbd208c85b135bdc885121b5f7195904d2a9141bf5222e98f95ead571db8fe2df9a93501b8fb9a06a3ce0338a37920fc4268e26e71f94cc218d6fad6c2cfdbf0a5855b186ccdf10f66f01f884f22503c530b3c5ecd96d9b55651b1eeb3af62cb7a4cf4cd185d98afd1b942e8f7eff849ce843e113e82c3a875fb996161e0d0185aa99e21e7c99c9636cedf0dc9aeb55a37eb1f744841f5d8fb3eeb5eef76039a40a5c643957cc81dba3fe556234acc512efa07f3a140ef28a93ed9cdd2088456e3bfad0e8377e69fbb3dc67f3864ab36f8f8422837e067c20787b80d77a30995e5d78f84804cd7c897d0ffa5fe1e7b92f17575d94512b6a4b5888a3cfa6e03be3a50b8797f43a87477982fb241f24af59f13acf60ecc4c11e558b1a4feb81f69acd5a67f56bd698888c9f00430dd8f8309629f7c29e96d2951fcd8b521265c368e13e22fefa30bdecd51407387c77259e64a62e5d705d3d46be5b6f710ad86e844e509a3c5c1dce0efe4b1427bcbe56758432301a14d8b882a70cb5c587e1636ecf96c61998bec7a9b6b98eab92be2e30b30174c87bb8bd66d13282dc4d1b67757435807a90a0b268a9f760054c219bef6c8811476a56a14994c760e21a1b786efda3fcda5acd859967b9874eb049a9690b0acd97c907c1ec6b1bc9790b1fa6c8f15518b9c18b3f0cf672d26496be193602d909efc2562bf72e83a3d8244eea1942c6b6708f006963ed1005615abfdb57cff11b985134ef3ca90116a7ae35299d1627fc05cd40cb32a83c9f9e19570ab0b4e079ae34402641e47e1f0bb20b63e551dc7c090421bb1916e970b33a6cee4be985f28ea66cbcbaa21279b45a4d3927eff26dd1d171f18ba8c5e78644d6027e7ace96ab62bc862d8cd69bdc9c07a4d8d66ce2a08601783e6d40665fdc637aa813a447361ccd9d843bfa05f5e88f1f74a4d6fd1bdeddb1c50523d731cf6cb4686018e8518525a83c2aab2fc5ff97ea1562c7cc7347482c96675b0b249f99428d68f180d6590c67025e41c80468a3edcf147368f3612456e9d73bc4d6e0a70364036f75cb6657ea99c8fa365c165d7fc912bc583f0f4e57ba0f531544282e21dc42e00f00fc59273d272a711748bf62760377e5c30c1776542936a10fdfa8acca0b4b5e5c9cabf461ed5caa9124c59a4e867859401c158080970ada9cf76ab49e250411a61ec5e83c781c269b75ed1c193bf8134d7b0dea +expected_shared_secret = be6aaee5bf0744e7ca1ca0e545171f3075aba9b4d10a71ae00848c8398e3c52c + +comment = Rho leads to a matrix with unusally large entries +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 2b1a5060745e8525bc617900d53b414dc995772543cc58a6bb7c4868f8999509428a3244db4081ac6b3f3c685865814c318032a678ce19866754c0774b31cc47a6a8e3cc90d6a15e54c7370c0360c38409b126c06d4b06b7d652318cc810c774f0e66e7e547305d03109030fded56940d472ee123438551d6885922ee91889f97ae31954703952f4a3951e8003ca2836fce071e382373c36a27b947ec8766bcafb1a3105aa2b082802b9bca0e4c50b80cf9a4033b44ba4b8a2cd6d480a315b08e7774d68f8ca8778894bebc2ab431d63c931e61c5366699b65ea448c127b82ea493034616fc1b6be01243bc84dc92bcb50aa4c7a417f1b5268e93b35ced9cd6263227c849dc8b107b10120f9f690706cb0ddec8fe2b20a26da422604c9135c58f0b06aa5180ccb55adcce07e51f885998398c4f16162c33b89bb37a09b84dd0a9d0e8c90a71c2851e33b3e9cc5531a76f81992344161a837608872355d57111df72412e58c5ff85b97ab2016b41487f56a9fbb48d2e498c2e12d3972c677caae5e439c598b67520a7ff6ac9c2424482988153b145d6b40973a1582b90a5bb76716c9878dee223046f746f08323ac3a5390a6148d767c3054524b7247c26c9339c0642632710b8a4fe0502dcbc32c35ec2e1e22510ea4abc7c74980ab25f9fa58caf4a70eec2d22c1957f162f5f1c5e5ad0a0fda4c342885081d3070d773cc972928eaab2ed604503257bfe448ef2a9c9c933055e633a339792d24a44769b95123c1f9588c8759a469c049a75bcad2e6087559c8afa5b6415a8825567aa44f63ce5b49ba4fabaea311918b804c7fa2d1742945f39bc9e8256b537128a9735a0939a1150c10418551723154cf4c027a5355e1751a9866bf558672fc68324438f12d83551ea49b358cf873772ae7853b53c9627ec75479c746a116c5e66b20ce0478c490946a0af4a3a3138534c2c94a44bca955e84513f548840b929f4b4ae51d53d52225a21b320d0d8b075358b019720c325814303170b627fd6856a149214eb192659d21001d5ba6953288e5a62d141ad5ff31c413418f332947f1441b8663f95b1a8ea35576e725a83177126719889651e8f20a8fc2392cdf55976651f1c177c5d8bb035993b0f2ca020a8b22b27080c4161cb86abda574deb0c858d14ab4261b1b8718ac12c56db9071a5acb00c4b1fcc9b9880917f53cc12bdfc77103a45ce8a2f4875c7e3711b659b967c5c26497c6e2903198f36b01c56ac5d054672d6914498643ae6b5bdc2447300737883306e4250ec445b543bb06b6113db5369da2b02dde3a11b2c080732979676040ddb2941956068557e65e0c4ae9c2834671f9ff65c246b31dbfb82720c8f014aa35d343b8eb762219b0eb802637574724595ac1c92b85e9a416089a2366ac9002d01af606ee9b21868e72ba96c6d5adb51f97c778cb8653e30a253b333ae5bb600a2b064cc387b38bbc0379c77dc45f7fc45fd060c60bcac60bbc794d18a5a8ab680a0ae202c97c3f153d07058017bc0b74458959c2a358b6c3733c60374a2ad540c75785ec95cb0bc125df1e8359af2bff55026d18348d0eca6672a87671925a8568060c09913993fc6f89e2523023544938a573ad208761e3ba85354cec6d999ee1c5f909bb973e0780c84101cd3cb42319b0d5614b9d103be8477ee9713cf943e038a04259c0958376c1013445731b0a5224402845499f30449f0800de86b614718bbe333b4b8245fc1a8e0c43eadd61f11f532ddb7551686cb8b054b2e90a19c889ccf68394cd501fb92a7211b9b599b2a2b637dd4246a7b8a5f713acfdeba03fb513f998177dd8cb216aa12c27ac3a5b84491738e5a745cbe7a3b5006bae6a08b0cd79a2b27af3da8ab021893e7727192e28787a052df8b434abb0f3a5866368991aba8ae3c891a0870327c3967eac16e8bd725bde990ef882bd6e5663d50b7adf75048d3202b39b44606ba1ac33fbb7a866a59a8c70988705974ec413abf660d5e98b6d9c60454a8825874953d778ac527578769aede871242b04561ea2d6e5c8aa04ba44228125bdb4beb90ca152705716cadd283ca2fd83ed9087ac5b2c7cba9334fe936c69586e3399fa46a174170aa8db62bd7095736012b49111e73bbcbbc89391bf70af7bc3581777c54d74ac2fd37b453000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1feb4f1d63f08052045012a21c33c2951b16c4b5ec02c00093d54ded6f94309e44d558787273bf593ac4bd77a56fe4dc30a54eb68a2f473c31c239ba18c9ca489cd50611fcd3be42f6f5069facdbcb7166a64ba7c06ba953142e5914ce20ec69038895c9860e69ce6cc3dac6c1b28d30fe83487d40591995f091d4ea116ad2675e32bb83325b7f379449dcded935027120d01ee43b2208deba910ca7ee635c5b928e5f6167307c813c8e7034096878a2915ed2d20898d8412ae61a72378a4eaee2f227ad5467d04ab884340cbfde2400cbdbca7e07a2f14016fa9e403a2b0ed27ad1dbb3cc492f584a6b5a7525baa628303039f69cf1c1e4db920ef7882de21eda5d2bad76231c88a061fbb2829fe93149c69204e2e783009beb4188fb876a6f869eb11b1c32c2ef15f9aef62f699f9692a502a4d87e5a497097ca73f8fddacbc03dd40a53abf267f749f9ac0f7b4ce9417a0f5eafa91fef75441ff7c887dc2eab2336fd257d4cda373121af864d4707fd20965e063fae456f0bef8f587bb385f8e5c96592c9b7d6c284197ca1706e1961dadf16a2264f74be425ce117a95dc9466474c856adb20931cc920177dc3f8c93d2bb3ad5f7c5517f0b7d141b87a8c287207e64158934766c8845ff0a480da124716b11d0e257206f68f2d4334e8e260895ab83e218e032a35f8d792be7b413b2679f8044e1c0ff67c474ef4c9b7e0dfd3d9bc4252fa81922cb146417dcadae7d7a7ee96e13bd480c96a4314f31fea83eef588bbf1435528c51eaf05cee2f193c3fc234d695ba32546ec77a16b1ea8047498125f2bf78dc9510812be57fe0ec77bfb3e28f42a4d15c2a2f0b54aae023ada92395cf384a1524a24e36ee2e69128fd2ab78b5af77d28c2e9ccd6c706315d46887db0c0c4f28666da7437489e3b245a19fcee97f187327a5806d35889e63940b19249d627165727f66f50aee62dd9496d6493c1f01ed0091e985048c2aa85a3b25a4f90f6e9f9cf67d6961ca246d763d3437ad64e7bc5c58b10117a66c40be088c58a27be4bc1360d114e61d002e271c4806b872f5ef7127217d5af6092e4aedf8b5c40198f266f9e10c560d4873668d58c912ec7ec18d27249f5be604a82d50421d436a3230780419bdefd10f049f404184b3530361c5c0644c3205c32fd451f6c6919487aefb12a75c821cfddeaa14c2abe20db3ac57ae0ee8ac4567db2d1e2d0920fa036351e8bcadbc14ab73d0868df6ab06e675ee193722f93f64a5344bd70593c23647152a81acb4d1a08b62b5f0b2669210d5d7845248d95fe9ccd796d73e34af955d1c94edcd2bba91be211cacb0884a90eab8a0125130ae65318f5419810f4df129c8504def662df4879e2a8df02d881e9990148065942c0d52865425f3239c4a4af51eeb85e1baeaf647e794b9fc04ea16eb328b8b1d0550e5dad8bf6248782b530735f8f5da40cf21241a2d62951cc9e894a339491f64b78d436c635eccb855d3a1f7d64f63f23023620408df6b3d190e7965d219a0cabc0933f7d50d9854e4d4aa7a5cf67b37e0475241a5af8e5000d117ebcea40b526c5a669dea1760d7fc30519148649fb00ca434f2cd84862a2755a99531854cdc847b7d5af3ede653ad6959f49c921d4a8675f7f3f51416c39e026488c297d844a8429caab43671093cc3ebf8730a18bae06f10ff8047cafb8d80edd7630c95d008cefca78f2b08ccb330d36eb33b18cf47bfbbcd0e2f81daa87160f421603d10409b8eab53f1561623f5167dafccda4f9a4e6504a0b5e67ab5dcfae98672f4cf62e4f152d09f2c64dd81e3476839aef8538a86f3b616ce55adf1dfe9451ca48acbe210c32ea1cc574730b37d4747b580c66820caf475858b4b6ad0eb7c06ed56b8f16f83595ee3466bdb8aaba3bbf35a177fd6645610b9dc238571e81b27b94757c9004a4c512cbad25730bc6f85255ffdcd052447766219e667095d4058e5f0045e16c0fcae1aed8dcb7c25fbcaf29a71a8abf72c398a61b1a57bec4b11a8c746bcce3ef0f82b9b2bd702d92a7fabc1efe0065e662270e1ab664cb1197f00983f1d265ff738f63b93d5d95aa4ddef2ea3f473440ce7ca1558b28fd68ee09c7b97e9d4c2052fb1dd657ecf09a2f664de0902f23bacab5d64bd449a0ddab34d4c0695c67ff5f6e11044a0db15d2d19a9ce2aeb818f0ecaf8c1522276521b0193f76e2 +expected_shared_secret = ff81d45deb69b6890f147710945d1b750cf17e876cd4e694158efcaf4fa2cb15 + +comment = Rho leads to a matrix with unusally large entries +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 101738f8f11e10897f9b1b16cc7c57ddfb3e4f6b01ad6239982baa07c56c05827e838c1b4bc99f9cc40608e74ed2d123757aca9d8030a0857ee2676db47bbcb1e10badb32508b87aac4c066fc747ad09a52177b378fc1446ea5aefcc30b0d744d2240e5e94c6f12254945223aa93abd8e71fe926a4fafa2a49273d618a0a5921cbde9c6f9648c6c12bad96d080e39ba128464d8f496b7cb020ebb03fbb2850a7118a7edb1bdc438565ca33850c1b1bfa6be29b88bcbcbb3e6675924550a7427035f60000841603c2b4c9f22040f9205c9386cd1b457046b4fb1521e4fcc47c1a0e7fe072bda26946762167d8bddba8c6d04470a2705fc05a6b00c4cc54409499a4859c4148b2a7596c8c7b2e597f0912742794495491117fec96486035f270363fb88511f756238ac9faf98251ecc06e1495337529b209031c0008e4250f550c3d476352ab82c8ef41c4b8203caab3b81335613016cb71b6a1f2c9b71158526cda75d9057c7597099789782b05164d338593b0a9b5ec85e0e6263c6a54d5a06ab4caa6c8db5b40e099f0ec7c00628373c3189e6c129b76827d160783f183ee14151b3b92e72bc4c65a06296a88b9f75948a18d50f53381f59360a19daba36939c3af104362d725c62f51b72ba1c8526c0be6a36930e19de18c2b1e470136cb7f92d246dc45992879b3762c92da6b97c10a552ff7a8b56788985814d2f9c5cd316dde3b2c7329b42f7492917c9174552219719575196844144a04a0b6718158cefc7833a421016b5193a5b965eb7b689698d14a41c03a408f8713aa46a077eac06a6106796c64b67117acd1bc0220125f4408222159503864eaa8824626c5651959d0f4c250c0002ec513c0817a47927ed99467c1eb6091f91773495d70084a7c344f41e0967925734ad846d360bc2a73c96f754b065112f1f472fcfb331eb8a286bc69cc1486d58b2d4932086f40c90ec601035c3016985962da0ca3571f5f36791a466861527a1ea52dc5a6254303971ce841d165985e2c02ec5b6a92278106117fcb377ad2c6c48bb24899a519626c74da9a3b026623417156aeebadabd418a0a8bc0bec5b43316ba7d7c4145016ca515ae19932a50819ce609b9ee9997c29a9af03a05ae9aaa89aa03b4ac5ca887b7b05a14d283a42da27ed7187369b0108165ef403550c99cad5c3cf7e28bef8a83ac8867341b331c9c02176520e0555af9b8047b3753e1928c849a13900545ba7a5c16bb9b6c689102aeb73eac0c5aa093a1f92810472c29642cd2a549a32bb9029961f6c4a20876ba8f4ab5212539f543c9d247355a300467b5a0a9d130613549d17a185fd045495f06820684c86aaa18a89317ea34eb0923d5600146497729fca9a66e9a544a55c1aa6841c556cdfe7ac0959635281c54e044c025c5b466442f15655474928c617a646c7178bf5b679062ceada6c6d702c22d339e0d3a9563a252e36287fc7975725bbc1a68122f4579a34c9c84318b13a76254c6be35a1ac3b26a8c2b373c6378cc20a7de414924a38ae7e8423fa1a66367a14b198f9980aeef068f346b208aecb13d827b3b5ac088878548171451109ce1535eb0a18ed1c1c677f9ca7f60501e1986ac19764849633c408d476540d6290738633a2e711eddc883ecb5111ce01bdbaa3df0f381facb31389249e261786f79aab0a80992b9a74002c9a7432fe88243f4276599389ce8119b846a75dcaa8eb300a7cfe266bbcb3742bc1e4dca77b986be341a03a75644dda25805bc50818a05a8495fb351c0709a5c37a07759dc0c3a253a3c56740aa8095d402bc65554880c2919dc6375451be6186d18da30c2f35ee4f1abfdbc594ea6ac5799c1d9912fb173044ad995d675751294489be7674d84181f4aaeacd9951dd0be79b919e585560d0b090b750f2f667e2ea21e283577e3aa4f6b11ad2560212f8309fad233ef87c6fa37480217a7b3933147daa29d2642cd582a3ac96ce5026135d5376a586f4604a8d511bcf5d09dd3e895fc3cb7d90a2535a1c31da1b1df5562e1b2a86a116212ab10a6328d2b80921c3c04ca9a4a9424bcc3a75e649ab34481561eb0a0920b71c245c1789770df5a7fc9136d4b573b227614dee4b23276af4b6c3537bcca67b59afa0119e668c910060e04e7c94a1a7fe0e191fe22cc727d12dc6d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d4952da07911c8ceb643e6b3254f7fcc22242a88df735c9aa9a91fc692f32544b7f30fefed3311dc8a927930c50b17577573f858b778294929b123b180498c22c1ddc92a11cda9c0da3cf300664feda28bff6f1873a682451d24e2c2a5991fa8aa29718a43c2b379ebc7387fad5dc9e3681d233641d1b805b167ae52631b3b6ebb0aaaa6507d4a87a808a1c3b62c97da49c02dfa2c729693de194a1bb1643fff14e0fd8d3749ad33936e8b4f8f6f3106c08a8098c6b903d1cb70c2636571253564fb7dbe54b96b1f999749d0c81c698934756b455bc6ec918ec267b5e54a0a812c62de971d8ccd93e4c1d6752afe3d5308c5257abed2b1c01d0489bc1d5fb5b2f4b199cfec784b2bf92dc85904cf78a9a6c0fc3a9c5c1640f905fb8fee2e08b3c0d5fa029062a5d41c82c512ab0645e7a1d728e7fdbcd95ec59d121fe876b1e6d624dba73cf68f35b23bfff7a435a5afc81947587b60d588c54ba0c999242830e568c3269bc96e001a99edb6ccef086abec634d0febbbaf72d872eae8c5606e86d9bbe279395c5370647f245351ae41358cc26f5447c37f959396dbb03e484c80dfcfdf93701e849e081232e85eb15e034b5421dc63c62190ea54a83ae06c89f395f7cef8eaa41517345a3a0aae4705529d3c2c13f71418817287c860f062c6d0c5ee918c50e613164dfd241533dd08928fc695f3b3c45cd75c740f76f6a896cceaafc9afd64deb69db89cdbd589fd6987b1f5da8b5b9115d675d3ab6cabcd0f793f00418c97b673fa31b851c1209140f76492359f3580c0e4de09d2a3efb2b3dd4afd4abde0e97180b7b24a45063f07f82771991fd2da92e12de7a868e6e84dca6a318dd8ef3a1ae6420d63051306d0582b058b7a96f25766aa0d863059483e9c7a17748a268e896f0d02173606e4381b639b480fbf0b3541a7c1790e66810e064cdc9d4e176cadf3d64ac27648467cd0b8643ad1255347cb6b086788f6c4dcfb3363cfef54c3ba5c13562ce884b53b09e6f149a60e1fbb35b65261406ec04f4146b2de7c61c2fdcf0f714981308774af933b710d1d4f315feefa97a581a98dd083a4d31749e5d0af2ccc2109cb739f8bfe85e4e7844dc3907959ff3c04ab9edebf3317f354c5e0aabe4de2e0711ee771b8dd70a3008eb9936f8b6924ec0dc9897a801e00f6738ec7f31cef0db9608d2c3d3683e97befb02f0ecff93068a46e57c97201608756dc45ca8bad93e0f562f5d74790c87d4ffaa67613b89c22339115d7499a2fd038bc4533e46bfb5eef28b06b8fe9a3182c6a8b18286edd1b57adeb55bacebf7c842d527ff5024c0ffabbf78eeb956a5127555894ca8459d99df31fc0fd1e1c5f7050d2cfb427dbb2f67530e049e23f8310b88c39d25dacbd6c7dccb9e382b0b471980d54974adcdb082825a9d6325cbaf90030a58193d5ef0a4e1e8fc885f04329253408b4de1d25acd097ff10e0afb4ff344063edde277e49b18996cfa57a7617b395a54731052a95a3cced450d38a31f19811ba278c60097aa1e3c91e87c57486b23ccb07d687c48fbaef4e814f9500b1e6f679a749614c86197239936be1f7ad2290b9a421c4f2fdbd4178a75cbb9cb1f7eddaad9d369f79c0e383fc9ccbbfd5e4cb93b211c477cac2786395e92385a4c0815d0ff6849e961395eba07c86e698d5f62466492efdbc326ff7c955840ed2877919d1cf95cdf5f557ad069363caa905c97471c85c5d0e65cea1ca90df82a0f8ef5660f68191c1aa19a180d18ef4a7b0dde8250ff3ff0a97dd4d65c3faf1e3a426f6c4b64f1f2d65ce9c5e5921ac20197a00f2331e810acf4f6b71878f1b785a28970d844ab4b6d1a604824db09f15e96bb711389114a4680b1c8b19be73aa5b039116c7a7cb7d2c2b026f5847afd6d2ac804f4ca24554f5ab27db900a159579efd23d78cf5542a038744cd6bdd64a3b59d233b878b383bc0ef38a0a2a8ab60869b64634df1cfdf3b53a367d3bfbbfb741badc819cb01823a8e8e16f6b4a35c380f99cd45af0edabf9de4fe2e5b0e6c34f7dce2c8d9a4be2b2b8951c27080aa965ae3afc422ddbefe0da8f766c8c63823050d1ba055e42352d305385ab932f99c0309dfa8d6362ec1c07e33909ac63200787f5963653db6ba2994cf308c9763a153b6ba824fb8ee94bd6a38f2a12047f7e0b01d090aaa41b4acce8396c18aece73cce364a7e6d9d +expected_shared_secret = bd452a700448a4542a31dcddcd0bf285610aca6570d8bc85e20e163a13db5663 + +comment = Rho leads to a matrix with unusally large entries +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = f6036a8efa3d74327dac2417e6fb05e2f1c178023b70214296c3ce65151248533f43a4b50826b181bcb51fbc54279397a6e50113635faca0cf7439be90867a4c548a9af0704da13d12c7549ebcbe5b279afc266fd83b9c4222b717b86fd4724cd0a35238abc2c3390695ab975bd38e0681b67bf86f36cc91af700277998ad3d700e6419105dbc952144561137711a0acaad546e76c66ab5722bae1cc110abdff7044b662beb6acac276317a7799f7ec6bc1282c87cb284006b3e74c361e5c6c8b899ad122880a1219102404fad458170f8aa3576750a9682c830c7c8796daef63042f3607c5c059ff98b7a093ebda2947b861f497202510a6a2cdbad3d7ba3b8da61f02671be3410549aaa9c3140635334f6b4385cf4105ce791db08b73f3ccebac9ad93f1c7abf6289721568d601c2cf5ae2e4690ae0c77b66134f3e1c33bf82771491da4d228ebbb7077312babb47e1262009457a3caf60f0e47145e29a3ec3b37a67b9b418625142937278c50344c05a0a606fe43c229749415064556a55dac28321be77a256637fe2b8dedbcbb02a29ae505c641b004f970b051e028d047cd152477db673875148b71434a80221166698c3cc589374634c06110320b0f249a3ec4856ffeb478979533be7a333eb144550939b00164b6b1b545905612dc24775ac2e4bbb531c6763f934121a8a8d804951b05c8f9c9237046245b422272288e333970f7469a78d543132055c8781ee308382398a7bff70f62b7357bb8093624a3ebe3169e957f3a33019fb0296ea1cebbb484e87b04eec76a3e29cb38b451816a8feba195dfe79e820591d7e73c50139e2beb847ef43e42ecad64b533ee3857dcb35413066c7eb19e8c1bcc42c9959c13ccc4bab6ac81b44346261ebc74af482e34f855e08916e0c1bf33861fb6d706c3a5c03bc62c6d97cba4174b2441a32ce47db7b8703452bc4693be69a4c539c6a6b744211598cb644209e84a711a05b9116574c7a222bf459305f10a68d4c48eb72ea16526ff7619e8391032685e244693ec24b30a257511e00ada5a69b6cb75c2983d53157fbd708fa1e54057757bfe6067d242cee6492a51098913a6b2bf888ccb280dd3cc48c6a95ceaa5a844338cf4985978929e9ed153819b97dbb944e18c0d7530a09cd420aa7ac5f5910325d02368c602d531289db188d30c6fba407f32c41e80133cea869b52e8091f701c3d7a7d4b317e9b0291f05a652165695130c6cb783b18ab1ffeba0f72d2c21cd9844f8ac2826267081a4315927d9ab6123fdb0193f723a3cc3738794f735b1a145b83189b71c597bd8248ba511b9463b9262c80790a09167720473fb77b1da2af8632ad793c10d1916868b99d2d23a06875769d7151c9a524aad51eb4f20bc58b4c572cab2642769fe444362533a04c7350b3c5eb418785e13e05b5459ca2c856b1b4e1b266e9677a27d29f6dca61a2776c92dc9290c04d77d7bc7cfaa8a31a581a623cd1c046a488080ffa8c13f66f4d262aba53cfcad64313c5c2fd838f88e903fd3c7da0942fbb3c84f4581457252e8248a75e185d4b5b64e0634b2ec5c5a088a6251c9c8c76837c95c066a565f9fcaf0cc76a79e1a20fb05a5bc1bcdef32deae76105c581319bad317b7991d062ba1761cf1accc2b969ece35274d7b6a3c8c79142c43b14772ad96fe2f296eca5c9aa4b68cf14c584792b1e4ba1132aab4de7788dd642e307a6b2476caaca69a1f7a3946404a440764e4446c20c216da5965c88bb9e09c165b93845c68a5674105884c46c601d35737649815de052cabbb31b39f95531286e08e64772213280ba64b6467d03ec43c5911854498656a831a366cbc256813d451153a3610e6979671ba7bb7ba41dc832a81885589974f8ebc2e57a1709eab2ae9931a09bc97d486839d6a16b29b7de642aaf1861c31b6ebe82891896b4e75b2360a776678aab892b81c5e2175eb588885b980ca02e9ae7bde1dc6346a13a5964c4391b4a3cc776d9311f0a9706c2c04584d05b58624906417eabc95738407ba197b2a14c6e4655396575b585f7c2a8b262cfc7c7d6f3a1fcbbb4356195b502ca7b278133614379176f3f4aaa49a040c7672cfada79ed5a2400dab4d050560d8a30c3e57ec6411988e941622c64b934833f9225daf42885a5b1f7909d65b5000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 021a27d9ee3c76b205152ced9c68003eedb09245954d50316a14a3e1d877bd9d6480d479265cf7a693e77b8761f11a09c1c30d2fa5f50497ae6a4d2afa3e61b0b7fb4b3504024763ac6c10fc2e6bc77dda7fd837ce115b84b1d0c749e8e4a961d3e7de1bf6b36741be282f9df710b46410df07191c3207dd9e74e8c4d43e3c75607966a1894e86caa95cba51a9c3289b00ad0fe59c034099b822654caec138a1b06635d1de59fd469ca3e928deb7873cc3dc2fe03aa4b5729f91b940f01ce83ae5aedac13d0a961cd9420584346346955780974ef21ccbe3208cb019f050fac0b80076b48ac6c0f3c2aa2dc3a13b914ce5343c7a140186728bb335a47515d361466c2d78f3fc6250f13a4d4fe6c8a587512700fd5272c9de73eb698045708e18b86d6b6692e3afa1b73e5ed55614dce4b8e71ba9dab03a246b1469c617f5bbf3e502632b060c7c17145ba7df290ec310661480de58a56cdab7a2e5a8e298746eb1b7b8703c5c650456c567056451e209148059a59af315540e448c0c6a7f48df9e22f373aca8be4df3bc9bda80e94a92634a612afdbfced39194e124c07748328698cc21f39de459b4cb08c6c73e80fcb6d0d86adbea470a207b0575f180ddc0d658d7ae66b2166cdecdee265a02e56bc4880797f0fe09c081788f5bb507db2406f37a2743a3c22ee0caa51ab62ceccaeaa9e189ae412f8dece857b0faaf61f81f2bd968d0f6c9048fca287f74d954e48ecf05806a695d06bfc66ed8b5297899dd4b3942424cec559c33ef0da1ca083e7eea98585f89003ae0ba98fb3f51becb80094ba0091f97b3a32c635a12308851e070f4a94502be51fc6f4e11bb7803cfbee43135c82bdd3bc82d58383636eee387d2c13c1866982d7c4f15f0be3bf5f87c8fa5d43daba703c73135ff3aafe4cec43abf9c1bcd16e56d6df85fc38dca4d09245677ed75b585722a9b20fd5ffe9d0436b3fb592ca6982ec2b96a8af589296b0b0ffcae14ec9027d4815bb9b933470a357d0afe5aba5010eb0d93a0fab2c28f84d7091e607505ecada258a551238a2ff68621bdf5ee1246c27d6e8673f1b785f7abc9b88310e3c1ca5e266f2c974d1c88a31e27a102330f924fb3713adccfd09c4415c1773c8da37e4e18ef274b00d462970873b54ad108f588c8bee6a7b4cce157109aa04ba0daefc9b5119b3ff9f70d4728574cb9f57573f41760248a8a8cdbbf7492083cfbf585c844f03ee2e08da4a08d04717b6244b63bbf80d0f4f0477f94de7ae6b2883388ba05b27ffe8a497541f012f16bd9ec50f64cd0d14e1a6c2be8c77ffd39d1d19ef402b46c0c41718ac406acb1b71fc044b1f93a4fe98fa8a0bbf09caf9dcfcbd8e8ecba42e4bbac9bb5de40f089b86ef71003b92a3fe385bfe603b098185d05f43819f8686b4f4e14a75463f2026baa66789edc52610ca8d3d5b11f10672c70c80effd7ba0352b2079de6910221ed21c487a7367cff076e84e1cd3ec625065d7a9b8ce4eed9d91c8a72b16a4a50d96b8a00921695a00167b53471e79aa445c656fc0d41da64d836ac21a34be767c514d1571e500fcea435d1a1d59a6d07140ee4d1a4014cfa8a6f0be9c334ebdea053c842a06124dfd165232c1a2ce63babadd8a56fd78ffbed64b63bac3b49e5af81c746253bcfdfd045deec785e0e272ef8c7151bcefdad6fa2bea962d621abd97f9b5cbf1eab792139d16b51e1f732326a5e02926817ed0bc4c6c4680e42e7d5847d6e0195c402e59290ce8a8f040a70980eac1a0bcd3867ddc0f2de9b204514011491c8dd63a371d331b2edb870e76e7ec5b27146a0097b969a6b157d00f66ce53b71598b71869063b9a29b23f3623837385571962ac29ac868301e2ec0643bf639b074c8a28f0a66acbd0ad77e5c86d01cabd8fddd77a4fce6185768566a6d98e679986aaf9978c49189a2ef1a218977f4d2c34c5027188d816cc918061ad13421be77fb910ee5aef5e159fb74169d7763b446e523470409c4fc4e76aa6d98f120013d4af284bb0a8e9eecff71b8544f9d3815062173ad6d4e9c4727cd6395bd3da54237501c73390cc5c48683d780efec478d2a15a40a5ffa3455f52c092993859fc8ff9c1ebb308ed03b5b88f6de341c3be3ddc96f695d68c1562b85806e162f1b07c5f10a1213f8d85f6b7d92e06d664cda2ddba47b93e2922d30c3bb110405fc7dd9213812 +expected_shared_secret = 8d99392e447dbb7f7eefd329325bd71d1d984cfb01fd609c3283a84fdd0f0138 + +comment = Rho leads to a matrix with unusally large entries +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 2970cafb137f0e7c060db72de03a46d8a860b0cb2a45b462e5530eb566bcddda2315a633ae5054957cb74df537c30777a547b0c6e486787c74c3d242ee34158b212f4fe4107885b2d3da2224803e73bb282cdc8ca0365eb70751c3263531b31dae5a29561316003b2d781790cdc2ca09b65ed19995765263f06c8a1f3378d46c19b1b46a43932952a37e4c828e99f95404075b013b7471070422fc65f9c9965a1c0cd0141472fc7004f6319b548c19929f792ca0d588208ba4628cf2bbf7377ddac05a058308b7fb92cf55584a381204523a460310bba06a88d4b69cf62fe2a71097461a8c3b5eb212337887a34fcb278c59931f28a0000227d9cb9b1b3753dafa63e893c9783764bd01b7f668b83cea1e7fd94913a405babb301ffb6b57b2845cb7cd929c0acc7540e1bcb196679380822c7bb67f732a3c9ca778b60451fb03755ba151e6b0bacd1129df5174ebca123805beb8e91b840b70643713272ccbcc2b80008a46b3a818ccfa6ece2c3364f373fc8c10ef4b4c95955052f99202362bc3020cc2528486784784095fbe10b4a44732a2c6c0b2b50d199a93c544a00980baa2f5cbcc6a3456eab71c2798d04c9a85827b8b654c962b7e4125cfc0f82a59632462d656b9b96188cc89373a6165c287bc890d5ed9500ed08ec1f2822d718bb94525ce81cb48b4999e288b5c90bb7e3647ab26a7f5479199f9198fc950948605b9aa0c8d0b133851abe4d77aed7455b70410b54a00bdaa166f0b4712e3916a70846840c8f3f9c80c8a95c912bfef188782974eb372795d96cccfb6c9209cc2cbec64bcd064e238608ea46f841ac02d6aba8ba9bb251a381777b50570a5c79257a964190e56aba3b27c708803a2e6909a6920f546c509a7524d138a9c2c839f34a6a814b10ba4642b7214e447844d553532804154b36f688715b203cd576274445c98abc60192f603d970c988b42d6cc250b4349f2d91b50c123875c608c932a7f85bae2cd54b6de80be13914f2606cdd9b03ed83219ae5623748972a657e0ccc41579b745b3abf6b04b50b945f2f2963504bae804a261254ceedb767e252c64908abeb94669a94cf511b992c475d99939095ab9b19f74f75d30efd58beec598352108e1ca648b5f31bc7071c86aa97c5fcb60bba8884a3c72414916bf68a277a82b78857de531611ab7c7a111a632a64704458dac97dee2442b4b05a378baa74f34154bc8c191591eb2196a4d3174c3848b5f02f2351211f605b2608c9fd8a101b658599b87c65a3c2c7a266c02b3b8beab84feb0071c25a50b23ec8acb1daa290cca2ad6fbc8280c5cadac42993c083a25338150231cd134548661d645c678bcbc0e7815da41a14e8eb123c482e2831a1ab0399ce02cfa1a39a41c714bd8c9206d6c8c922043a235cae2bb6dd1ac430e22947444ded7447e00a51c13308365aaaf4da9dec03495c73295aa9259d4529eafb67dce58b374066796983f06c91d034226aa75afed116c886927e135564e4000cd86016346b56d9864c7abc6211a72cdbcd32fa869cab01f1da8f6bcb84cf1441781c6baa263ea684cf96a1277e2459ea07c6071b06093985b047b791ab6e6593be230099308a79376bbbcd71492a4a4de83a4d70c290aa05b74a8c80fdfb9293317d10e07615acc85d762ae35b187c55060c912d9a2a09e995afeadb874a5526cef75fa4701e9e0a5c082b92ed3b8887f0bcca362b492369881373ab878d00054027c4cef0c07cae57b30fc51e744653316591b5845c0a47492378764769cf3846b263ca6e086835cf0197b5025b2a960097e57597327f28d4b2fbc6bb241863a2c96d3242a031171042fb40afe8a75cc2976903a603b96019f4c7420b77625470b62287e03239e5008c1297888f5322937457b9467e52937996157e50764537ca495ac75fbff53dc1e8cb77002aa7988604b0829976c8e49649f7446495a7548227ce61d963da3bbd2705a8dfc73f091c20e72b77f6640a14aaa30134a1b3fa7083a50cbc720bc9a802a4208568e2a2ab065db245628ef2a138ca1d71fb3f66d6a8aee513f1c80b64a0bf38f01f4979a975054dfca823c4165aeb1876a7a81fd6920974b516d6b3a1aa71776a264a32447240855b84ba0fa1d35f07a8c11361040da933c4c44e88417b585c1a1605c68ce4000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6899d650581d8ddd73d6e7095d24e2962ac573877204768c66a78047649ffd373d4e0cac20e0b98675e6f50962871c33957b5a7ba2af2ab800ad728c2d0e70877cc3f459ba53d432d45f4c9ff4c951c35f14185e01a1fbd735fc3ed84063b579e69c230f41af67c9cd7481fea81ed64bf248c63f56f81115ad8255a172fc99d87d8fdd6db00ee407618c7877a2486b6fac3b8eb7bea62c24bb5c5655e47388f2108ac36d5e55c5511d72bbba65706ffdf297cd0788b4c34ead564e86e78c605359b6b344380a4ec73a4f64b7866a2eaf36a494c76adba39158a3d1d3b41973cad055780ce211982fee596ba61e5e5f7e44cdd8b1d6f866c708d20403760b9fd4abf31a0573afa130aab5bf7493b2365ef5437b7824366fb3ec967016e2da547eb61276be7c5509c2bd5e16d8812c034f6b4c5a7f5f489137385ad5697c4312042303a5d7f62e398bf5fcc758ec1475e7ba671c656911bcc32ddedfdb07252ecd0eeea696046e3fc9e564b2ffca11562191c4a1e4b31d9494961fb66ad44f24c4b0d8d7422df106663600ba380baf53007b6146c923412228936d7324a87050e62b185bf3700959e262fc64bc4f2b55402d57c63539c57272240f4725ea23d389b17d6af64e864ce3429c9c0514c9b384d79b830a9c6fe12f8781755d53b8af9bf81e4784d9780ba6ba0ae36f89a99289307481bb3955075057648129349f1e0ce4e750be53372f82c92230127280f0f393150c89715a43eaac8abf538a031155661b489b066e915505d59ba40cc0b5a4b8de7e731533fd06dda44e65f22b7931c4b8e34a72331d32798aee1c16d81e06eeef892e7858ed2e9c27d21a3030567e40a369e21c925a26712e1ad6344474bf8e9539027040eb4b0cf65b627623ddf81253c6cf002f837673d2389cd296f9abfcd38a36c6976b03432c9100c7ce9bc862d2c98a6dc2f931f62e471369bbfab644f8ae37deb65784e6f5414bf88cba9e6836d3fa3c0ab7ceddd81d31e94c612224270fe79048688b6d8d46acc7d656a647888a469fdfb6ef8c8daf78a2270c5058e9b87d2fc0e4f8a098c1cebf96e06ff1edb382e545387b2314b2f7d4a669dff20122a0165c285258a39e2a1d27c5eac3d79ce0cdc64dff98a8633882db588a34b93a1403f6a739bd056cd2d6531af36a2701acf47617024cd1cd4b9b60a02cdfcc6f34e4693eba3bfb32780c573b4482a5f6bf109c7ee51792252dc119a5e41a4ea8f25557b64e500a83a6d8a839c456775a9ccb906a733391605bc487bbd6ea7272325df31cce2093649fa8a379f4977801240ea2be8b1e6a5ac95ba613bb2798bfd1cedfc34c39e1c43cc094f8bff34607f8419bc3ef2fc0c37075dc49280656304d2f642c5ffe86d5cdea4fe96cc8b4451954e5d898f6cdf7e7ec5af447dbda66a254b964df9e8dd565d46cdf04dd2d19ea1c7400925be2105e45343baa9855c5236dd70e042d0153c904d30fe45d087b0f0863ec603ad74baf1836b18c91d98455f3e6477936dba7379a6072744be6d4c64bca89ac3334ba727e0763f0ea52faff3daa52de9fad1f27e566e7a6e85914a02bdec5f7a8509f80a616f6ed66848d4ce8920757fb7611ee7c70366ce847fcb62a94452dd2523daa21c759f36cd31337afe1a5c8e8ce8799c6f03873f58bac3649e0d0fe6adea0199ef6eed64dd1e2fe0bc606b97ec8ed1e0b567baec2816273b7280ac91b05fb25e7467e934bf79025f5b4060a813c221291cb307f7783d5877987124ecab1d9d8c8e36c10608871a92e8878220f593cbd4ba61c35d2805500cdc0b145cd6ad2cd614481edbc913733e3a5104b0006dd26e871df58f32047701b2420d93bdc2d0a2474f7d9927e7f196993d9792e30cdff67ae89bc6a27236a6f0ce0439d4b04788765943c2be5c9fbc0f139135ded84ce79d876eeb37f30371194c8eba42659c185a10c8941f9fe9fcc722183ba7e22a7885a66d8cd10f214f4534171e0836d86368cd04d87737923da8801166afb398bb345b5bee89eb512cbae07f192aa50a932a5d92e909e65443f4004fca49de5eb19abedbf57d066d134e096e7c63defe4430f8e1886bdd3cfb8077f7196584398589ced5670c7be91d715a20f51603db8ef35724805eb1c270cf16b282ce7c79111e4577a0a1a27a435c070d6b3e89dce1bdb53826fe9a05d86e586ecd950d27247ceec6d +expected_shared_secret = 71e358b21b3b98d915b70e9b877e94159aabe9df32737c71c50c2f99d7a074e3 + +comment = Rho leads to a matrix with unusally large entries +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 46e77cf311b99822a8fde459d7d01210db0ce68054199939e8156f8f7c33adf5bd5f2c54c6bc70054a5b8e305d526c1322e49f57c47264091e39eb0c72a596ad5575434c4de07c0bbac32f7ed30a0930221bba0aa75140b0c97a6e1775e1211740c23390f0094d144632169e4a0c2534479b85546a7fa65694610b2fc19488a5833aa7bd0ecbc6dee36997a900fad18b1c13b7cd381b1ca598038c2a4e40ac374615ffab46b3cc992df777eb0781aec573783b75cb426283ea01bdcbbdf8f8b30ce92f46cc7d4ce407bacbab2bfa27fd7792f43ac0ba74b58b332bb915be649a573eb22c12b6037b4a8cc109cb4495a337e42ac82c48dac2099684bd01700b7da007dd8039bd6b09900776cc783ca114358ada02cf5443c9bc6c181a6c86daa79371bf6e6c5cb68b7255d592796bb7b38c5f8c655b2e480cec127a2dd4aae4b23c44d4367de78e74797b64b0ce07a36e73613ddee8a61c5c32f865119f1a60b44ab5a28374af3324e68604bfb33962fc1f06d661119c0a081c45dea91190c4cad6b6253ce560d4e7855a64c58bc950bac88ce61b76691a93be4b81c202768c984ba2d9122cab4880942c40d87022b91c5ad817dcb5037b835dffd916a2b35c09f782ecb72cf63239b6c33bd73c0efd115357b283bd6512c1eb3ede4730284328a86021fa805ddc55c96c1caa3832857cacbeb5353453638ee70669c4dcb6a10c723b18c71dfc44fb5600c0f8cbb35c6d0b075335f6bec7ba1306766591575b5d2b4eba76a84e326b1475b5ece6c3ccea5e555616d38c03fe630c3ce56d3ad73858539d1718b915fa703996ce39745831b3c93e4829cc5677e5a79d3b1794f81816dcc2c5babc859b0966c76c23a4e66f1031634c93b8a51550d7850d5407b4e2d00ddfb5862c1c570b778042986f66ec940c5039dddba773c9a6a3c10e370714d0a4a43300a7b06b01aea6b6a4b5c17e7482d59bb9e1fb16897cc0340c5b65b9239d973c06d41f6e7b9f351a22b8eba6ac1148d91bb4f8959395e6a6ab996fc79bc8f0f7309be14fdb65bfb0287771908244033a3975ce2ec096abb9c15fb40d33a074fa2c84bdf7b1ee94746c42044be55484a179ec5c7edfecce56f9845f29c7c535282759c2d0a2546a13bf56dccc6d4463376a46ed05ba7f54577f26c78e2aaefb0928c36820db23a999e4b399b9b4fc864444d665e58ab24577533aca26acc5c512970c3a84bdd6fa7c7fca6c60eb73a1ab79db779c208c61a2f5311a694dcb7ba37ef7c7db92587d4a77fe3665036531d12c1adcd29cd2ab733e1b2d3ca56a2c7c9f7e3b96d6355b73c4bc4061ce276308b449cc0660b0f9c30fa4a62005f836e182a77e0b74d2b86e3bb6a63fb58d362b9496025bc5485a086808d3779ee28038d1939c5e39b645db160059a04e1b8e0e532686f29d34467fedb02236f3bb0b699c68726961f49824d277c8495c9d804a61f5320e61bc57a85bef199700d18a69e25331c41646abc434e6033d4abb30f114c35377365c51f5173769c315edf076e58710449763af61cc316b5a3e75346bba705db322cc683d5258a249a22524db0e88059a423c9b55d173eca88ed47cc4711a2ae295b846fb113834ab688bc2a42435258b9b1be648c5889230dc153273903e06aa2590ba5d77a63a16853d304933157288e03af785bbce36067c296a18cca79a18aefa33855683becd7b19b3890de40a24d6d389460a4a66378da2b82980e61ff0b144bfd64d0ce294e9816b9105c20c2076ddaa1026c68e50982cf79ba879f630d4eb8df663390307902207950b8b9db571c306a033272ac8976133a641c585d43e730a4969d752072bc6f180180e0ca0fd9c27d7845be15cbdbdd44c7c525fd70b5479c18a24800833c9338a5635034704db0443307c616209ab2172a0bc42c239d87ced11779625315ec168c3716ae62a209ed7096ecb83d7939593e519fff06e99a6a09122c5bf20c5bdc09af2402a3a605318d68c2b31a284b33b1719a4b6c7a5fbe4500ce23f7d858456f47d135a8256c9b40f52c37d07c728da600f127738c027d131b19b0070cbf9322d1865fa515471d461d17c424626b305d68e34838d5d7a35fb91816b65a1f9403771fc3a8f22403ca8616f89995b52425d618a63a789a0dcbb9ac196bd6612fb69000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 09ada15058fa9bf500eddb096fcd572a056beffdfce251252d0e9a8ae0300272e289f4f8868c1f4909b0502fba470989aefee80303e817862fb74080dbd7e872c05bd63162ada055a9f5dc88e9504ac344a517e613113f670c16415e2ebf5ecec2056620d4fd9b905a14a92d4a6af2d34a4aeb21ed9a98d498c25155559fc1b3046a5ea8c519bf320a8e2c0ebfe02cf28bfacb9a6a04c54130d93f1aa33af643d2620060bf578f525b1ece5464114e56c5d21692cb5243f763129a44deb9835f4851cbef64e0f97cc4ffb322c2f3863b26526153db89dca3f55d6727252de17c2021d3da9c1f9e3521f03844a066b047b318baa867c3201a1943c3a8245182f1d3a36b5e4beead76120470b2ef02b85ba13a1dcede19b5e4a7adf09d13e4f873fc5756a37f1ff240f6554683098437a9c374721088c0e0a390c435d8196d94ce94d988510fca6ead810a5da834f86f7bec0e41d83d35d1acae4205dc00a7a9b05779d41c893371bd000e308f70badf03e2f9066540fe2ad85f312db74fb48d054061c869f80bbf9f2c6c28fa691eaf8df27c7e13e076d8a793d7ef70d6cbb3afb059ba176888f569e73426765e4b866148729151dcd89753a68a2e1b76be36559dea6c7e4f8aac70a417698ac9d546f228ea36b01622cfb4405563a43e75c6baf2c626ff14b098ee33b1e9200d7b7fcd2cde35198b3332a3292f32bd1959132fa1510d8f1a43956b1d93820fb9dd88aa04597f65f86166033abd9ffdf9ce1ad4d8ad60d05f298c11f2816a0d375a9f8095aff0725905f508d20b11dd59b7145a101810ee140f86644827f31c64b2a7401048a8a5654934d6e5eb41d43a4957db61f341f5a214d2d09d4fa6fd2cf709264c4a755aeb0aa171a8286e94a354425d795780049f097b3c20ddb6cac39a78f8205f11c4744972263c1a495ab1fd563524f9822deb74a70df9ef5486ccf54e737fba48e3ee8d1c69ecd1c843fc38f4986f8fecfa42be99b056f24a2156a14d10998b4edb501f7edcb9df12bf1f235068b2961455f3513facfaac92d7d5093f00af6834d3e33c5f0271feb31edfa94bb3dcbd1221fe29095d6832f5a5155951dee6ba7a379f73854cf10ef5ad39b1730bb01e315a3c642321a52f4ea7efbd4519ba2192d974d445d6894feb9356a4c4b7512a0b1973568a04d7a45d7a4b0c73cc9df8147a2d0e31d2729c6091bd7a1c1985649795f2cb3b40f4df43e3bd7069683a737347bbca94239bd1e20badcbb702aefb93391c852108708db4949579eb495ada6840755a40fde96a009ed6acb54e98e0f4a084924ef15b25a917d497d25d9032a895a6ecae037af1d6e9f36ba56efc69fb893506a311f1f80b746c8ba0b8e08cb6c980c476a5982ce622e8d7394ddb0f6ba2c6dba68b7c5cd8aff2454dfc92362e82594123d9c200609d2372a7ce4df6e1b7ffa68df7b681c1d5174b3de4eec7d6f1321b13fbf4986b0c73ec6b9583229798801aae096bc5f972e1b3b07b0a40e1280070b2977d6e31aa8f4894d6dbc967a4d0b29c736ab33db11c172d9b771ffe84a8a803306a1b59d7fddf4975e6aef83375299d97d364a7629cf69ed856c689b09dde89fce7ff9e273bb72e768fd7d671d6591c6497f3da0eaee46feb58783f9d0495a62eaeca8e054038efbff4cc599529a9443b9496d1b0734eaa278121ce64d2a59c352b0ade0ffa907846a0ae8bdf02426f270293f1fc40f2b645089d621c18d11fac3d073afa27f20925039258e9d5530137f848d8e3e56f970d523544485cecd847dbc7fd8033f89c04a542f23a12e8e4bac7b9ecd76be797d8195b8f6f4e57b1b779ef41f03739175f1ac5e336fac71cab07f7dc760e4de2a3296c5acdb01dc5096f3f2de463980ab26e6d84b8a0754578de9b0a022281d6d1ae1a4ee40b781f49ed605a387b5176d685d1a29d3581eee4b1bcb050c2567e4f997330105e67f128c28577eee5ba1d170365cb81dafd7b218c8ad0207bcf00a38ea63ea404e3482a110fe16d0ddc8700e185670fc1df89ccc8a712df0c4f69c4db77390f72bb12dd627ba0159afa309e17e3538c313716f7d03a07998f941a7d4b8280975b2c353495747d1e115b770951ce5c924a8adc73eba6bf4146aec3dd27f828266fc3e1fc23f3b5c501404ec19c8030ad8b07d26aff71aef4bd7228728442325c5b880120e1c4492c1166cb27 +expected_shared_secret = a2334b0bf4b86c60c4bd971e673427352bf08c60e7730fcd94edb8c34339028c + diff --git a/libcrux-kem/tests/kats/wycheproof_early/encaps512draft b/libcrux-kem/tests/kats/wycheproof_early/encaps512draft new file mode 100644 index 000000000..58660b616 --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/encaps512draft @@ -0,0 +1,1841 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = 115ace0e64677cbb7dcfc93c16d3a305f67615a488d711aa56698c5663ab7ac9ce66d547c0595f98a43f4650bbe08c364d976789117d34f6ae51ac063cb55c6ca32558227dfef807d19c30de414424097f6aa236a1053b4a07a76be372a5c6b6002791ebe0afdaf54e1ca237ff545ba68343e745c04ad1639dbc590346b6b9569b56dbbfe53151913066e5c85527dc9468110a136a411497c227dcb8c9b25570b7a0e42aada6709f23208f5d496ebab7843f6483bf0c0c73a40296ec2c6440001394c99ca173d5c775b7f415d02a5a26a07407918587c41169f2b7178755acc27fc8b19c4c4b3fcd41053f2c74c8a10a8321241b2802432875ae808b9ef1365c7b8a52902f1317ba2fb0269f47930672107b4726fef64547394d3320c8f120b3c2f4725b0305fab88cc7981fcb09a76a1cbf7f179f43bb0a4c8b0590857f1e69708466c7f8607391e7bc5268bfd3d7a1dffcb4eca2a1c9b597593013d5fc4202ec2b74e57ab76bbcf3632bbaf97cdc418a6f16392838ca9bf45ddf023777b7561833c105190f94f302c59b531900bbc816361faa5b3380ca3a893104ca7388b185671b3e5fe3790e9a626ec46d9b0b33c7a419af7b32b6859894f575d82ac5456b5490a7af8fe61046360589ecba7244236f4123116b6174aa179249a49195b356c72fc6641f0251812eaa98570b046699070e0819dc2713f469137dfc6a3d7b92b298995ee780369153ac366b06d7249cd09e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf598159a7792cb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4932612ec915e4ca346a9bce5dd60417c6b2a89b1cc435643f875bdc5a7e5b3481cf919ea09172febc46d4fc3fb0cb9591704ee2dbb61844b2f3314a06bb6c6d34005e485ce667bdc7d098586928d2d91340f00419ea401351a240a0b041058befb0c2fd32645b7a2df8f5cbfd873327c978d7b351a28088438837024c52b9c295cd713646fb5d6c0ccfb470734ac2b2bc8123c2c13df6938e92455a862639feb8a64b85163e32707e037b38d8ac3922b45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = pass +expected_ciphertext = 7549998d469e2e479002305b09b44dbadbc2457ffd3125f6d31b0f27b803d581071c1dc6181196fe76df78de20dda609cf1b7cb7a352c4dd9c2cfc18801f036fe40f8f7e6f3dd73f387130be387b1713418f83d93dc7f8074a032455c46f857c6b6b35429c790065420d742252ee53f53f6e64a9b78a49bc29b8ce84831a01c3429e346960dc559526d97853c36631b4773285fafe8e3ca4255a8723ae4f02ddd85a4781b9f4186d67a83b5d9eddc3ae7cd4096c33f4d97fe02030ecb6a1a8ad9b19d3eb32f1b8f271b30353e9e19dd183f06b54c3cb02ef166282752aa11c8158e48bbc6830171ca7ddb75a35e46c35321abe6a742032c772a16b3d1cddfc6f2801e2b817302dbc94f333c0cb91e1cebd5ec61e49fa5a14aaa393755fc3e6f4b8c5c4fa4baa07a08c4f3394626358a15e690ee1e4829b111c17241aee37d5c832f4847688fe5b5d1b19e8e04d9d1937001987f3b4b83549c3e530e4119d164b20ef9d3a72f74c044a974591228b41e680ec5640a97234c2c6017c95e91be2bd498547d57a5222b8162a3546656d59980d51af595bf5f23a632f6d8544b81074aed34c0352ba560deafb07441a55a9376342e50a0ec2537228255a4b5d03c92957f4ea3507b4baadce53ccdfb7364ffc1817b58c50ef28e322e1b945e0eb9b1233975c30a5545368682714bf502b61e1d0457a9753e10de0f1bf35ec3a3f470a3c69ccb04d2d98fab3a0b6729a9875e1db533c96b41e3d98628a6f8cf668406c5f038e6b7b242fdf86a7f1e697aeb136114167b13f89f231bcec7a4166b39eab4a3709237822050c49c92595a237f2eb483b9e1dd6124bed5eb9b7b5121296376b7d2014a77560ca65833d8beb4d6ae68efd7a11acc7de87d82be1ad573ae9f6f0766fd786387d1a8c12d1c8a296b4f72634f70577688848e576851f13be48df335d4acd89793a6c6c0655fc39bc9e1e27b4a500f708cd4a9f2ec672ba5bf8ad23998d4c0c958f290f2a6c4e6cd8c0cdc85f5716ec98a4c8995d378cc6e2a1e8b82800ddf03b3226a2e7817771e509b4955ee2bed4217bdf0630b5840f2524ab +expected_shared_secret = c608777086ed9ffdf92cd4f1c999aedd0b42e5e8ef6732f4111246481e260463 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 2c421ad4a7848cdc4b73987cf2f85e660c65e468346672ab09ea8b106b2ed51246271bc9d21672f6aa0b3a9b24c8f64722842f2e24cb2a47aac689a5c57318663bc98756c199160f3a39c2148c574c23836dd060d1ac8a06794edd5aa068ac19e42ccaab951051756350c31d584a517fc9bb303276215580fda99551e82449d8675f29c45ab6354107cc94509ee55aa5db3a813adb8b04005200aba8f91b58a2d3b2b7d82c6461363353038099b7a0e981a85c75e0e422c572c506071df54bb7b715b9f4a42da1e89694a06475545d97a09ea36374f2c8ba40a5cc17eb1ad308ae862a26e38b2ffc11b7abe3b58509b21649b86aab9e0d1abb601604c4152257a6691a964657ba0d1f561402545b782960e547a4dab7b71aa95c67e64caf568c3b3144fb29022cb0bf01b895e3327d019b591ca282d22105da99b58be42bae7185e0b56cbd0c56ead56b5dd34e9bc1859b927ed78c4ee1340960256a0b63cf4e1cc9e84a53a48b2f70c3c89e83a0005d65019a8419b5166469999a453418cb94295462d9256ccddb3fcf8365cf0235f1d547498714a8b09553182fba093f447a220146182a3acf062a118b22ca49756505978f21db629799cad72ac5d17b2bfa52a6ea15672537899a313a4f0b7df3f8639906bd0163735dec5923a038fb7b5856570e279275c3093998338cb595c9a6b712c06c526166a725b9098ea02ea10c5d7cbb86b935703f122dedb05233202968b59825f41f2c17ba76ac661fa69a7998c5fc6c2fb68a7820576b1fda2c73daa29cc21dcdca47adaa1b3b5258c1575fc9270712f3b8842978be50a18da45159b99272162891cb8a63cacfbc30bae0a4364c8a6537e1b40e825c4a311488b133956690e494443ab44793d3717582701fac5486da4ffaf02c058ba688fb88deb3c94e7445cfa89a79ca5f4b991abce25cd6b74afbe9c63dfa0f40180b242ab52c1a455c0664f7357c048b27e05ca46b8605e6843c66fbc2a6a29be135c39565a916acadbbf2aa2656125b603bc88c9d710399a84850840169be61bd4ef3687777075f0c7870b61903a26e6391a88b114e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = pass +expected_ciphertext = 4e2c094b4f5e09e17f2c05a8931715dff6d0a395bc9ee327e019b3683bac51f148cc0ff627613a7905a8ed870dd1aeeb7ab9e9055c860e92469e5f6233396e37700af8c4dd1a745acda15142b178f88af9376014d1153c9359562be9e5f87c25c08961e7fbdd00d7d9caa1134f18585a8b887a6364b92495379e6645f6164925064cc8882d42933520aaeb27cccaa919a9796054738ea4f815f70a56192c80faece06005aa0909d8bb58924ed2cc91284f76e33620a1d1914ac0208f1b95fbdd98e34b924c8699b9a0bc9cf686c75ce50e05873d2a95ce6cf5da1e5cc92e7a73ff2caad08dfec1cb84e8ddd6cabb0aca78c42261ceaa6669c917c7bc0b24d6c96cbb2d2519738a50f6a3e233c04a6243111c7fe5fe617770a89e86efa3ac5f510c0c5a8a568364edb478cb43ac0b318893e9a07982d4564cfa70cd95fa10191d9d3c1df1814df49d1353fef8daa5f7130f8b63b633b7afcc3d39256d281993c013a2743ac9f8b5a727248e9336f6d7922133d4caa79e311a64799814cbe22a8c3c9ab8f70f09926c83dc97fecb39aceaa421dd08fb17c72dfb84b7c7fe309bf65214af7d800d7f290f649e5b7e7d3bbbc60cbc89b03882cebdada415c22ece89194d67b663e4d3129646b3ca5ef8310da467b6cce1db6c3016415575315e6601fb7023143ade3ab421f3f7abcc62641d058bc6b25d5a4f719bc218122831ffed894fc5159ea86ae60dcdf69b0fe5a4a2bc6da7eccd007e7167c939c8b0b730ac37e9917fd9bdbb125e6708daf97f6e5273e533abfcf478d8aa22c16724bc7c7bd7c8bbdc01f6610f1527832c3a82b76fd44a2f516cd7c0c650e6736353244c733f9d23b06dc25222c0b100a65464196429760e27b596ea2498b44bbeb9652c32cb960a5c501311188d001dcbe04963739d3653dec28f948f5639e0153690f75567ecdaa21d4a113f077c8372a17f89c08552850317975911307a148edcd4baa130ba91cfae96c2db73d4b46446341a442cb44d47181f3bfd17336b9d0d71d63c825dc606609bc583a59564dc98ec68c908e754ca04989cd7a1dbcf10f3348c1e +expected_shared_secret = 9401f92689a452b5e58c35cf06690596faa4ec0937a04493a359b59ab3b0fdee + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = 59720c3d802726470d1c567b5908698650360db82700e7b9dd26013b6a8184316df3c59194fc96a0821a95c666ec5b130262006442cef64428794672b43bc1eeba20de01bc70c15835952164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789de2153b3f64411534cfad0adbf8bc0aa51bdaf396e5746517c5547b3112fe08188da54932b9b458458c55f146feaa9620e7bb6ce21648af047e0027c3553813aa81574f26483e93a5ab3642aa1332bc34f86328e5f80b272aa8971d175ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31a9b27d3b17f63fa0e0da16a3e54bc85da61a0119a95201fa51906d6e2257b2cbd7235abe8b80e80947cecb5ce87f9af68442e8b6336c68ab0b170a67cc14f5e5377c4cb5930705775e522ca466dfebb1aa800b452262a01966ff624ce79561b3a40258be53512d01b749c25ec903923ea58e6677e02b0430e996000c637d002ba09dac9e717ac64b634688b558d598e4017cbd46a160c621dbb2b961638b08a488fe8d814aca37165a43ddd4b3908d84246794678823e794c9191332f344077ffaa50dbd2a6e0692addd353588b3e87e31f3ae4030b2371eeb1cad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4ab1f87235e1f114cb93c3150e25277459c43a6aabe39af63eac248d19f21b17ab5a2ac14169b01563dc818552ceab71eec2c2422c3e5f703b84bcfb457707a0b3edc80c0efa324d407d077cab9b416b3a97713b89c6d65c2584ca652e6c4416bb44d3e7478eb21ce1a555456b94271689828560eaf4394bed93a86d48ec082a7be576b75d00ec418228bf93c7037a49339352828af07f3729bfa739b00d04b5502b9d6054ba525d724a0df8506d9ea56d750072868cfcf07716af003a02c45d4991f4503bf5ac86024857acae4ce24850def0632a6dca9756c5c8a459341c69e93e154858b7c917592bb91c23ab622d3f84b9c81445e5a1e59262bfbf025286bbbb5d03eaa794445f7839f3ab51bf5ac48c978f0310128817d27e658d9f468f77c4c69da09dd8526539c2598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = pass +expected_ciphertext = f58035a4c7772f07420775b5ea7701f30a67a905e93b0131287c8c80727b2ee674004421dd48098281580c8872e3ecda197617d1cae78a4e9c648e64a811f2c11427ac3daa918a67141df332a7ef030cfb2a7f8db782f564010077a5091fed691b8d60a940e1dbf6d11326f13251e0b4cd0a44db1a3958bcc0860a87e430ef1b6d16ab6436ad5a3d79e9f20fedbc75baddafca29be9a308844047e26bae5846e00222aef148fe6e71009ab6c2c5c064f129123fd437f30953182aa76a5d91b1edcf579c59887466afa1589855752bda4e642bc99e61e18546e5324b50a8e012394d93b4c65b0c2f284fbbf1ffacd96e41737bec86540e86e98dfeb9266495d944db588f091d21fe0ec3d3432bf1b4ba4682690bb9b1124a0b9cc2212fcca7701d4cd75f5b91d5644b6746ea6e971b130d554be196e51d979e2f7cf5fd613f4d4a1b689a0028bd5f42f772b3bd1eb6fedece5cbe09bdf6e7d4fc01067c71ccf7ec6679c024764753a7e801a93b1dbb3d82cdb35588551a4365b0a1878ba8a3d4d7ce4f94bc03da0a30ba53873426fbb73d871a94af67fb7bf585d1af2d393a5bf33e063d2aa37fda97dbea3f87c7190944662b0758339ae937b7e60aab7c8350d1d7052dec7734878dfab0e57a84b65f03dcc2bf5bc4874a435962d7f1d41b46531e24b6dc01411e77b6d07a6e962661af91fdfac2c10aa0151aa7f6f47af162c21ba79fbd72f176b81ef412ee9784b8833a3bf76d4075333a2d36c22e8f999cb96aae94221f98c9feecb9843dd8a561a3d09a88e9f514441662e5f1d66a986d07272b4ce1b7575d7c3b0c4542904751307fff429fdfb38e82f004ffd8a3f23fa8c05fe59097f88ba0764a78d749621b5ed51d7c03352b574a1c85a19f3af0ed5916d15ac826caea0ab3d3bd81832246315c76cc0f434be5f517f07c92eb8613b5a736ae66649c4a5a53912e1115232f72927a076109db03aefa247bdb1f00a7d5915c3b6362799d7033cd0f86a43c727e4a293916fd0c2c98a66e92adbe40d562b5dec0dc61578a9c8c10ff30ce8f1dd24633d7db16ca2888d896dd1d1c13375 +expected_shared_secret = f2c689c7a8180baf27a4573d3e6154d4f2bff7b3f34d44576e777e2ac1249e8c + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = e5dc61cc732b09e221ad8840d101040c4428a798704db118c037476701a79ae30f9b7265038abcd0933d1100492a6b2fbaa7c0d6c22704571520f35e322a4bef080fcb4c83bc62c432f75f6ef22b2b1722351343cbe4460b25b4bc806bac542576ca42f30c7ddef6082199a4edc2237e5271eeb024e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4e0168ccba259bc99b9f4c54cc2a8c1489415c422f70249235235f81404c3601079a3c8095214ae03c86bb4a1487a00710dca3dbac8a89d045de4768e56329ec6709a9208df6d3af6f8c7ddd6284f144120e1449bfccc6cea22bc3917c90f6591062525804054553a46a226093383f12b8529d306ca2fa03f3371de8641463a353513a593d601f91937c3197cd535768f78aa4ec11c4f59267b5fa47b0b2312ae97b77aa1c3631b7033cb17b5a592c89091d0a2062f8c7299a2bd7f77832899b1a84ae67a3c11e87b17a0050523b9a9bb87db0152cbee582b9d821937a2770d07d6e2113832c1456662ab38475a1527fd23287e45822c5d0c19875cc4c60c9ede44722552013b6ad7ee4b860ec2ff8337789832002026d7b54676b44667961654902912e3116402824a64cc67655018803ab2c06540123166d78b87be63997692efc099e4bd72d734b1e9dd6344df12070773b06c5c1ff3b32417546ea5416c204917f104a3e603bf1f09fefc3184fa43f06200423c3026b3a2374186df33344cde1ccde212ebf626410907fda57a9538b165b3911e016438c4b3f0e485b3ca3001ef03466a8749d1488e24685fc1cc89e012758473601b572acab4db6a93edaa6aadbca7924c23115769db3a4185aebcd09a9b045b3437dab3336b47a6bc23370a53a5e327b6654091f9a435451cc26b41ecbc129ae109475793c3977b532c6a8cb3317d3270bbc6bbfbcfa1c2ab2c41908520184000e3b62dbc3005839200b486d6b89b1719505f6fc4a3b7a41ce4a4677b64688284ec18915f17133f81c4f73c13e14632873652554685debb7b987c66d01b9049f6b2e44960022e7916b61a55c12c4f5e099ca059e3f98704ad5ca1d2676496c21782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = pass +expected_ciphertext = b7fb6e4809a80d079c30383d7428c7b85b84c3725dfa7d4119f5fb21c713207015500d2588003c3db2f2a1c6a771ac4d948565d51e9405afdaa8ae5d93e268a604932041bf8c6e8a69767706a55f0805b2e5d9d9bd3e35c594241bbba3805be580f63186320a8061ece24ad66e5f557de610e321cae9509e31196462d633fe03b0ce992664c223074ee5459c6937aa8632e5311860348b914564234c60640b4c8eb34496e1546bf16393893b065c1b58ea733fd8115f97620131aa216890d8c5b5146f99bb6004d76f846431666bc23a3aa3a6aa6863a82ed11291b1284b4ea014acd1ebbc31c9446c042a1678148b0edd54aa5de979be1c463b6d6c2c86a5b669db2d09c7f6942c795529110144b6d5885e2bd035f82f5115fc8e5c0703bf23403def796e03e6f1a372e25038da584210b1a07cf2ee20e266a7ded2198a76a624d1e0f01c6430dc24e99d2efda1b0fbc9cf964cf31f4eb27f819523180788308729ed77cf2b4960f1855cbdf7f5b15b10ef06e9c18c07d8364f1286aa74ea3497a73467b20b3ac49d6eefa4d70a83245538d7d644f158d0331d10238e929d28fb12a60d76f536e929f128968d401ae554381ca24e8a1e89c5e480a5f79f7be672b7b11590f68a4c319c295962907f4dd309cae63cb00f046082dbe60d768205f69577abfad67139310721025ecca91d77b890a02aac012eac4e87f1a6a3c68f026541123b22d82231c295d387ca7ba7bcb620887a94429a0b8c8194d9ecb533a86c1b178f29d1080f05033257304a5ded43f4c1968b4bde413757b06b565f79f124bace778f08b523ece29a84516c7eff38f56bf89b99fb0e2f6b6e075b44651d146195c6710229fd57c8054c073ce48224778b317aedfaa85ce534370252bb537efa267d5745bb049bc2d53abe121cb4a5290ed77c8974f4c491e93c1b4c5e9183a114cf32ca5e3e8549a00e68fc4dc595f9e5dbfc8be5f2f94c693f87c66203e6ec345f96286f3a0a19d6fc58298ab987203be622df26fb417b00e28be76e57661d27ce69ce2e25df76a82d74bf6c0a5815c90b0c3c166b6f43251ca0a1c0 +expected_shared_secret = 1dac4f6f8d96ffd931f67b03cee8c4e4bcb42eb8bbda5cb702dadde8340d1524 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = 6f70c439f9cda8e34b944822c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b393269fd3478d1836f80a9cf51b03fe697846c44abe549aa16a25819e38c9ca1262ac103f4417cde8138f84050c0bba5ffb5090c81bcff1bbdcd67739bb60d236215b8ecb5c9002dbf41b36ed335dc4778153761472421d2043f06a8a83422ae6fd0680b860cfb589a3f5b85ebdb94b3f21d24f374949563e8a35eef8c70507c47dccb241dfb53be08b129a283367b48894c090b523e6ae0637fb4894707812ea9b528f54395d0bea3bb3a6772881061c28b8c24ade167633c30935a6c4f29a68fa298bd0c0bc1729c330953fdc5bd6c92595d576e4d6cb45a4a213aa299512c304fa2a3f6b1cd8d545150965bca39703efc502608bcd1e42da21cb129400dba7a9a053a6cc17066d9d98899d7c4aa3cab66b1c13d58251eb196959a6a250ba45023b9e6a6a8d192c0eb548e69d20c68f0bac8ec682b366926d62e878123e198add1d31abe91a02a5cb6fdf6a40255bc3355809fc8ab529a00b0d451dce9a657e961b4787829132a7192139532195bbcbb0fdcada2c515e3a83cf2485fb5a28f648981ddec7a80470540c71d53c29aab8009d9067c703643c1062165e3745d3ccc4e5249efc87b9f73afa08b1915065dac1c4c68422f89589526188ceaa19f64f0cad4781327e85665b5c59e8c3797f72642897db4515da47b994b2c6d3e41949363262dd721573021aa3373aa22758fcc22dbac46806c9005001c92aa9b05d0c789dcced4d427ae762f4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a4e194aff46422fb57fe4b2b2de18a060627c3f19b984aa7b738bff9336f80171f8236a3e95372975650d6b28398865f206a1bc81c346ee76999b8b889c83551f42495000eb9f5aa3ac16b9247091469815cf4533eab9be2ca283b962ab0031892999b55822eec5503d7201f446b21ec3319813a4f7b70b68a438c6147c182c48ded8c5fca18b2c7322fc3e4341eb46bb130464a7868c5d3ce5b1bb479e69bbdf20dfc59380099ccfb06789fa1183c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = pass +expected_ciphertext = e756a73da5006a8722c6b9dc0cf22c88ea6e0675a120dc5106da63743538ce258cc7f2d76aba306cc29a842af082da2ee435af8a36c664f7215ebded56b65778a236d449c2a7127efb4f76b9013680ce3c1f79e3c354c82df0d117302bfac8de889b469cfbc395efccfacc213873cd741cf32d9892d24a671d68c5d78f45f958d77922a25e43ffb8c3d88d1d3a622cc6cc0df3385340689c1dd5b2c28984ad881cd123ba1c3a11d8b20603b5e3a9b6a629b700834e450f267bc706a40835d4872b2b639382195ac0556ab110b68d5994b2b43dfd89c7aeb87ff4bcfcca24fa249d80328935aacc3376377c26fda978d7ee12135afb76e5c4354aee066c0f8eaf53b7497cc2695130fe5e03099b66649a51d7bc772e0c24f1c7a29d0e1a4239e15006e02a330e1e831ba5f0fe864ec8ea2e4149d7361d73ff8c29c4e1555bec5cf7fb7b12382f6df0d4b20901a161bab4c1bfe78405ffc286d3084b9d53a8313f9181df118909cd7fe43058a4e8d95354a6cc31a4955330bd1a8fcd88b65ebd8e3ffb4719387943b9c16fb9c7514a81c15cb9b79c2f48c4b47724933b1192689ca71d662c6c3155b504f5e7e0309bceac043b085d5a2db8736a5ea680518a698c78d03cc2757418f88f8aa4b8901da6555778fd4e82e299af2464bdb1ce8b3b47b4339795edce833463df3446834c15e11214d36f8fb0f9ac4038240c1c618d21063065144680c34b30994029633af967046729ee3490d583307d2324b7e6288bd944f45accd0464f9761079fb0db5f7217f9574b3e4c6a1d356a6333c1939846ba676ed361475b53bd04358510b4ab69da5abc2ad4c55b09d8547169891cab8e96e48127e6c303f2ef3ac1af2f4f30812a47fb4d424ec34a690bdc4e9288c56a747b029bcb6aa81f9494b7e280172b2101c537ffcf8ba2755498c268fee4b4fc1d3392a9bfbb016a987afe70f0fcc4476e440a5ac9aa2e935d89660ecaa98b368a3aa06c5b745c380bc95f854c367fb32b7cd7c84c75c25314bde0353d1323d6550ffd23d3a4bbd8023a029e8513d013b0d5f9f0fdd7091442d6217f17f72f52 +expected_shared_secret = 01adaecc8cd981e7f00187622defc0cbb8934464ca4675d86bc7d9b69148c85f + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 4870419a0b91a8b97bea251b03c51630381aa802b51353721697c4bd2891f37698ac51942d44c931f205ac15bf35708806a118dc32b51655070cb196246b6a63db0c57d727d9aa812c676880e3532a435e191935a6db1e1b110cd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb78090ca1043ea8ebcaa3b73c768892832c357b0cc48e875f849149ffe63a21a169798b00cfac58eb666c9ab68729dcb60cac6dee1497a64533989c0a68b151f8865db5f421eae77292155f12944322e579d8f61c20ea53b34cc7553b6a97db6c3df847b8aab6b993c4af02c44d2c0ff555ba6c68132cc6b9c4766acd030c33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e10561965e45551398a9632169d6a53da1314a9b4533f4c223fcc46ab0730a8b463c537c2d5ab8c9956c542d6119f76b82afa13ffe637e09297b2e6565277079081c574b05d50ac2bc8e9538d0105f828b539d47f3a9a293b4b9b834b2cab741674b8c61f28a778b736b699bb989705890951c30747896508421068dccc0f990611ebd800c942be5c886a59b008e6fcc86956aba6863bd9558417a37579b7139efb5bc47b1ad598464f287a3d8c56d748c6ae794f31842fc3aca9c5c05fb5f76c5f740d2d7908e01a173b75a35b8a70cd645e66e8a6d290919f227ef5e5bea2816b31829cd291b136520fb1a2825ee01dcbba7ae9a10c60a297d39c7b40f53d02d602627879fe6b4c00ed426a0b065429acab34be641c356be26a7c5012b9643fef007577f79dc99459152c13e64618b9f9b3be0b551dd33df8cb7d890c48ea83b68c42a327ba25fafb5ed65c31f4e6b639230aa989b1ae7a2c5ff3224b33883955890e5c7aa691463e58977c31445fba5c408047d227aeee6bc90697545ce0885c3abea2ec9668359e59282c22a0920ec76a282c545a80896f5a4705c02adedbb0f8dcba46f36c112b578e7b4c236899d81259706c3d99b0adc3ec44e58171a5e21c052767b7692800854132624ff438b03cca42473622a6db189be32c7e906a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = pass +expected_ciphertext = 329030cccae3479b35d7c0ddf09909c9e95e499c46a4843a29b28ec0990ff257f419ea1adeb11186f273df00d61e84d66cfb5b09110d3636bce91e7f7cb9b480dd22cb6034f85c1600a764d510dec4e10daf714bc3eca661c2e1f53b266e63e9c4e92d8d7d34cbadcda42760c02803136037a02d996855764eb55b2713f3cd3ac9c70d59886cf05382478d58816d37f1b13dc0cb5ab6c43071667ecab8d10f5b220ed4ea0775c6f93000a57b80d881a00085d86396119d832fbbe6dae1fd8cae651c2fc5c25c4461edca02c50553b98a21b219b50ee7ac4945c5b6b203ef3d42d243fc789585d009e9035cf5f12322ce47cd04bb5179c065ba7291f46dfec925327f1692b63ba33a2f40666ca546597d335221060afc6729312a7985d3953855efecb6340e1966520e0af12bf88d8bcd413682a74a0bbee5bee9930d4d2d79d194cf9bf72d17995eda7a6ef970335f646693169d904193b35c723cfd2df1f650e54d5321df3847c892ba6b699b4567ecf3e83c4ed2b9fef04a3f544a3dc6fc0eacf6b3f7164b0e482b610e79c2b1bbaaf42df68d4de0a94750d0a4bcf39dc6a60202b7a23eeeddf155e348d4b96d2d23aef6ce8037a4611b5a0cce68b6afd284f137b5041b483d7d2cdd40863553eb99378b53565b364a3e27f88e60a950b2d6099b100b495fedcb094268874db1e341f8b17417570f33c2aa05270b5539b9a72261ffd9948fe243a7faa213144e12429c47c19bdad12ea0113a43ec269e0a0740f3a1c79c5af692359b23ff9fa7e256d32fa4782b6f7722bd0e45e1c7fe1e4fb9e6c3f5b916bf8ec2f52847cfa2eb1e5c5993815261927f2eaf914c24c4d279fec6e2ec7c5bddd79785f225a22f0261c99185bfc0348e7f6b6032e68780d3b939b8a9ac7c44ad8806528f9b5d3b905aa5033e7ff01660439d5b897e9a53036005bd8bbefda602d9ad7d4b8aa68593515a7411b5e965fa265b19df9c8c295e7461d7e8c5768758a806575e55710d157d5235fd5e7789f260a1f02b682416f9bf6869bf076a5a229b2f3445d52e959a03db3b8d859632cf3879c79c8cd6ca6a8f +expected_shared_secret = 6f13bdb1452d9e672c8fedaf9450c436e5fa77e8d58ce83300b8e539f20e9dfa + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = e29100ec15605818b877d7399d4c70c4e3b362a3268fbb7e41d494048740ea222bc38b5ebd3cc8d049a2551a731ef31684247f30fca3f03c0a7d7245d0e81c25359f245b9523040fd2d24ac3941a213b561b974ce45156d268a0d6c5b555e251e18b31b7753c2826bf6654453b81a11478836d08c6a803ae48e0892e927960118d456232025c3f516a99e4818627760c88f3b8813b57e9ebcb37fa391fa1c7c8bbbc358b40db908b526a85ac86a03848820879314ca86a2c326f5eb69e7ff6c5a0c3779c20214581bb5f4973fbf54353fc448b0b2f00fd746f303473717ff829218b22bb23eaa132e31cce576efa0a53015c3788c82ee55a69051a62b6293aaa9a4398d61d25dc679964c33c6028448b92acb7ac1115c50dd3b064818cb0224209193797ea3df48b6ffdd8228d148514ab0c11b1840b3843a7472876231b3bd91822e8469a5095acf5b2bb5b138425b2d60c1e018951951917630b8da2372aa239bc88d5a086b0b6aed50618ab25000abadc6684266939d4468ef5c651ff69b11b928355170fba871a59eca1f7073689516d17ac6298d2520e8328f3cbaf8de33969ab089d6a046bb979c3365b2dd2704c359c04797384c5c7f28c342227b045e40e88d4bb5c792381e639c86a12885596144b1a6cea01ef9794122466e3bb779e2b0ccf9048f50557d536621d280b02547234700e442b6278d2b0cef240946c542292c904ba31a6a38cb9328874f824fca0504238bc090bbb78e60b2eec76c900bb6010240b839d433c4968833715121a884b362fd8c8eaf90a241b66d7522b6908c43890cea4ec80ca232be3ac573bac2428192087b43cd15891585339a6123475209af6c132be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca662742950f431c93a391618c2a410834c2231a92c3d91c471803f22543ce530a17bc924fc326aee4537a5b43fb655e00e46185e809996b87e27c6361fa7b53da5ab393cb56b1b9676155f2e57092566590642bb090571c6a92f60c55b339618389415c259705fc858ab71aa50021c1191359576c8390a70e703f32ec26419602cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = pass +expected_ciphertext = 47e5904f3f55db748f9537a2a365dce063afee46eb5da5469f1e53d601a8883f8d4f751845cbbe9fc664c498350a73b80272d1a56b3089976525f58b2c5d69b7521ba45acee718267c463dc53589ac3b0df5d3d0e32a9bccbfd11571952c64db6e1c6ba8058f95df6b472955ccabe149decb08f8afefd1a3c698b4ef5801c368f83e54f1db222c3c5b51a8fe98819c89d0742e4d9f22df5354e11eaf3abe6b47f436bcda3c3184aa995f3aa44fda6c60f10d82170bd6947015302c51978c0012140d99cbae6b05e63d74ba035a58496ac54a6757dd5c3431b7e0117d1da3b30d8d61ac0b1f1fe0ffca95a0ea6f2934693e1980e6e46c6ad4cb17ee6bb4840d5d2a9e4e18e68fee480c1575f41a865385eb017c7d1e01c9c5ab263585b88642e936fa6600c3e4f6692b68167aa8b357c543e479ae92b47bd037688b017800a07974b01970c4ec61775a52f6828d2a093fc71f5b921f03e8692f512ae3a3c23af1eda49e6799947e4b4f83fe509a476efd5bd8f411c5a349a848d81a011387e3bae39df806fdd847ce885d0a8bf16030363d66e96f6a98e1bce87becf2a86ee6608fba434e8e44ff32aef118a17e5ed6eed801dc057b6f6905c5fc5695e099b229de0a0c30f6ce0b5ff358d9fd329cca06c412a4a94e5e91dfe076d38b7a5ab73b229a94418692fc234e93de64f7489174f8e29c0599a1431d8280830b33c396c591944e030e3ec4ff2090cd901c05b5fd1ca29d95e31515e15500935c2d06ebbdcf655dd9ef555fa2a95ad8ae6f3a7b6d60b0587e92e4b1a812ebce6c8f9f5e5f5e02badcdc5a9e2785dc9eda60c26b687ba214a663cb45feb42555af941b1a565da858a6034c8f2ae5e8fa272585a82e7ecdfc993b2793ceb51e458a8acea14edce88927fac5aa03ec8dbb575625c1773af81ce52ffc7285b3f5f8aea31ae908936e0dca950a383652f3e914048a86cc6473d4701c09150c8de47065d06830dd05579b2fc6849643b50d2d23338e973dc825d1b0c55acce3ea0499e9add6233ba80a134af4d24fbb98bf2e3ea7eba53efaf3af0fa5856d3a5c4b2c3d44af2695 +expected_shared_secret = c81a637f63a802a5d2b336dd960175176b2b838ffb6de5adc501bef984fed26d + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = c51bc84c04b516a56479711aae6b9efdc04afb251a0c121b249a03cfd27d8c435892c88c0db5291de3999db794ef43a14ef966c97c02764bbcc6786500cda603062e54b0444e52835c67b5bb524f52e670553c24cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e32207c8a255dd72a3de5ab401e540359575689233e1693f477b8c8e027629b1b2815b27b9b557f8123950b307a9d91e1dc2278a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c862a74730f16a223bb97af8d82331b7421172723473ca0f3e24ba744b2bd561900c45df2f3bd53ca25df405a93ca4ad222989a58136c9403ab5428b908ca82ba0436ea046f548f9c00aefbb27f497a15ab108f39f2829cd38d9db01c05e717df09d0a96b1b24c8a6e5e5354787429e559d61c853c1354f60dc4ae522141beb5f3ad27388363a392275ea8b7d08b68ac583713b714b9cc79bd9cb265d91666242429ac62fa6991c2501638772552ea54652b4496bf790efb876288bbd6cd4500a344f0ff17264f73d0a1a10e4d63b06884f8a5c3562bc8617ba4f33ca14e3b40fd8117bf547b5910107f5863e7ab3c3ebd98522f81923dbb55eb43af41a1af1047b68b940bbba364ff69dc57c60c6cb88d4dc43d84c00b0437dfbd913ed15a3bb84c542137acf1205f4826fe82bbbb701bc00a23115ba718ba5c80ca301aa970d303a0a9e5b64adc04aa8c8c12b39513989a8a27a578309661dc31a5de69bfbb11308fa2ac4d701be266cfe14a03e961fcb6132e7678d5fd06fd1a74262837b8b7228bd297a9685a98f217976b527b1dc0662d6238c8c4f05aa29b3cc182b78a7f29172bb2a8b50fb861624cee1c19f4f0739cbb157d8f60090fc847765209aa4b9b782127f400ef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec48c2ee05996e0535dbab9309d365687a4b61d8a746696182df7126b5b8c5fb27cba016975d4648b006f2b9c2345ab61fa68c7ce7901cc09538fb6349a391403802a26316bf15ccaa90686142ccf5e709cd4b6380088a18c42826330a454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = pass +expected_ciphertext = b878da0ca229e1586aaa9e5f0a266d610839eb54c963f659ea670d747a2c7435019b1d3c938f730d41fb9ed03fc028d22cdc011a307c92a73adc45a1bac2439a4d53b936873c83b5bd882e3205e55a7a57f89fc1f4f89f38685d7eb80ada1d3036cd3d1529c49957c6b9f4620389b53f0715ce427c86971b42203849b1183e46b58d5944286e1d0f3196a82a07b4d5cb5362e1a474db1cb98bffc0a45cbd896db14bf7978400be5d1e10d21607478afd45a2bb2f73b598e979d1164341b2c7ef4fd869f40bb6bbf47ff6793f265740f3305a77d13589afb6b7d1d3899f37e04301c449db9f1edd102db8f10ab6dccc8982618a218ec2d9d9cefa071b48aa97cb46a398bc6d1ff9436e8e633c0d3edbf37076a1ae760bac41ed59589737704ad1b051e8d6fd61b963c4af3670b90bde431bee2fa17554ed30d3c01543d602668587dd7c743b1789b15fbd09d15c9ab329edec2d774d7b0ff42b0dd913b4318b3e3ba98101a9eee73b05003cd10ec8ac71b82fe1709a2a678276a235cec6ade3b88a287277f50311a8b8bfecc43bfb01acf64d0eb8cbdfed46009c12ed423292a35023277d7f0388f0efd4e95cd465d92e70cfd7478ad1e0c95d3594ae0e63a4da325d37cb409dfa120b810367d4a92b4fa0444150ab6bce154301bb0cd5528fc575d4b63be3eb35c2b8b4ed8b96d9ec53375f684e7a96829d04a5941562d7c44391d0d857f3265e383eae277c3b3c78fffd31b0de4703a3e31e620bb712bc7537343561fef00e18ec93733da1446cfa3bb297eab64c6554ce1009a46cdab4f01674f9810958d5ba58ba7641afbffef089d80462861bf59b73f43fd20eecab234a506d7a59baef6ecb40ae50ef7ab23db5b2b88d1253ccdfffafebc1bbcbc7e6dd3ac45ee2bb7de893d3b701aba45d80c20aa828b1ff9ce975bc1f25dca609ab2f1952a253c878bd031640763ed9eac99b539b2038d47f59c80d05a8921cbd7e33b373d030335294debbe616d7a3bbcba14c8d92a898b74d7737c284aa5e0354c5b5d6551da0efe99c00c7a7cb0ae56548b6fd36216efbe3b57523b023739e2eec +expected_shared_secret = 3031994f1365446186b4a4d6190ac89f928f6706d08c6316d6f522cd7605adfd + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 2fd9251f7b8fb16c6878bb20829260c588bc80195ff8db59ea449209c2476da061db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa6c02b3e531ac550a25db8783c995e2716b143c8a1309572fe47049a65742c632755a7d26e5a3344309e0c14ee313b0a8d214811b64d7351258e80ed9720863368dcc1851a358668dab3f0cc77f074aae24d71e0b71cab858b29e6a06190177f9dc39051b460d338363a9b7f6c691ab17865c4735bf42a72a655155b5106c165085b1c504d6b75187a44ed198c98aa26aa15327c5b35f6b3852a58fa7613337094129367e0660a62fc28e613c762d857f99f057b4e208e39181c63a8a91723352b8c4a4e04c0c02b78ac82e13c3542634484cfc8ce738b31a3062d2579f8394cd0947157443bc9774089689094a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba819b0aceb923918112e22b5591ba032b2a0d4f8301f2567b266473f3f1101a7c9ab95c94dce238db18166cb0c8f558167df937377a2096eb99408a32e3759a88a4cf04cb57923a1b9ae7140281a3cfd6763bd92e0fb91a24e87f1c56471eb334526053db394d39f956a8e45c6ff39cd57303c0ac920af3a480329dc19c43df67c05d889fb778a0208298938ac423534b025a04b141b1eb7017c9d053b7463ee870bb17899abb19c99193b670a23672b0ce15f97f71092cc121a0fc75a4ad292ff4a4c9c78bc24c764d7d4b9e1230bb46e02ee7a66357f25716c386b91193fc5a85cf63a748072478f23b0fd432944a5cc25a7dac2297b1234744a918e7565636c674e4aa4d2c957c7aa55da692324935a4c3749a08956028675ef5b9ba3ee5111dd73f1dac282523cb4a89bfb7973a50d30085e70818ea596c7c4ae332adffc300a5d691836690228b2fc6600c5a3a363e357c66a53a0fec851cd94b29b066305365b6a78fcbe57dbb40c8d02ccb5f541d11d24ce8eba582104bb4da4b9e099e822933b6b74080f8b743b59d94f094cde7c45422317e358adc6877613b7ec0a6ce8b702a1a32b285f475af3769d8a1148b5324c6429ceacc5980b902ef043f00d42484a10ad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = pass +expected_ciphertext = 63cf7c70a32a271417982c440aa26959410a79a7e7644ee15cd5af5edc1ecfaa6eb8c539391a486b9a7c64f8edc3f93c4f565c91e2d72c1445c6ca66498993ede26c303e61234552fc5eb14db62cb4cd5e0f66cd72ce07c89006e846d3cfbac98a52c4c4edc769a81864a63ba93f3a6dcc75f21bf4f14527e2e527fcf9649c75bda5edc21e4d13e8c254393c9095e6b80bc09eabc6e088f842ef5a8db89fcb885efcf2033555bbfba69b0713719aabb1fdabc0ca3e368b37a6aca44a4c08565797787f1d7d42aa4d66049514e8a9caae3d6113fab46e033c02665a0a80523b72d59aee48e6b8fc6ebe4d15c3d702817797c1f27c557dbc90f817d59ec2bc1d9680481b8954b5d4703dfcd8c3970b26bbe25d111c678bb5e9210a48741eb7189deb094fbf3f7fbe81c0d9e2e8df169d6221beea1c9db502fac210b7555dbe981def1f393ee57520b75eb25b73ac3cf8577255be45b2e3e065bf4c2adec044d5bd264d82bf3b3630b6130562c7bf0a569058278fbe74ec000d0d45ffcef441cd18357d91e1ad38a7838496dff864d4f8d89abfff9fe654c1f7876c6479f32bd6e6f6abf88e0d9d696933a1c5224689b7db0aa4e300be8a1c8f9b004aefcb3cee44a163404ffa3a3532b007b6b1d135df6cdd80b055b56c1faeac0441731049eb37f2774bd3a4b9d8796759a54fe9f29a956eaa16ea90d78c330c63a4f266b0a1ef06aabcb6d378be79c050eaa83f23fb2afd2ba24c82a331726694ac5fcc24de2b67260664fdf889f930fd4f2a7170f7da1ef4048c108e2ee2853535eee70616d16386ac516f083d585a01568c921a0c830fb01d524815669ba6f268e1f760683daf0a909339b512d8e6a9aa1082f35678c243a3e503154d574182e6df68304e80ece25d3f6cbd01d84fbc6abc62fe7e536ee645c5fe13231921e80c72056c748d2e34774d9b129c1146aee3bdc75295887244f016f501b37239c27ba2a5507c91e0819ae15260589848b7bf5ccdd258ae0d9ac2e36952238925bac564610e4a5a6f35ff57502c7afdc6a790ba151ba41ea0f6c2dfd60f09230af146174c3d9031 +expected_shared_secret = 61419eeacf26714b028d2f7e1e3769ae2f181a7e9311f3312911ead00486bcd5 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 4e2008000d3e22d76ae0046db986b85ad166052648993355c2262dc8e3477e83bc9a843476da24444b3936db182c608bd044a76ff88cb3c2b4b4f44f35932d0bb3cd8b834ad6e23eb9d9825d4378cc40a94d007fc5d97392eacb9dc770bc2569ee1b92cbf0aa2abcbe1e8a1e10ab1244e14dee474ef3e4531e330eadf71db2a36b32e152a88b5d90b8212b45b69c483cf261ad54564a76fb0b2b0c2589037a294772ef8c0b00666c2cd18cf54bb3b9b910094a69fab10df29620a890bb07e16cd8b55cbb40c074e0aa256253f7159c07aab0a26a9104b73b2942143e9622e07c055f687a5e1c2bc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db19c2fb151ae1d4082103046032603d8716726539dce01c940a78423b37661128f88e74ce04411ae307048c82de6a2af26996b28f91e32c21722554e2c51c422bb2ff5e3a35a0468b3aa02dca384b0ca793d1b524b7c24acaa889175a171b2522a07969249596ada9e76d17395c49648740fc0127beeec0bcad5c98852c3314111d149a0221168af2ccc65c6961ce3690d64ce1554a137b373319c56dcb5152a19059e0128ca872ca6f100d4509f196c7ad4fc65ee6accac6b80a9e8315c7619870b3623d38d2778c788c62d291a32b1ea078bc5a4e5e2bcd34c97e5a6301574c7854a8fefd62ab6657e4eb9371e09b8df2b1a45370ed45214cee3b86a1417c234081047b5c84009bb10351932c3a3078b7cea137ad22b665cac0bc0c6a032778ac437f139970c377b4d651b0e284d48040402685dc3ab6d5d206aab39c361789818ca7b3e4c8cfe2c4719e054a85b383eab160139c377896fe0217d46b98f3d0ac2a44cbddd003344974f30f3b9733579c506659272c1755c9346cb31153cbe133328283637ba5b4d3a906a3ad75d519786c54143101b77b7053977cbca1175a0ac076dfa3c0595b0473495738da76ba0d4a2333452d88c82750c94e745852a1118bf7a03b6f1b448298e8a2b246b166e18760dd5c468a4187b80fab8ccd078837b8223769b2489420f456140e2b911290eb4e780dde03e1a699b38b95edbb1cd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = pass +expected_ciphertext = fc4177ca4d90f14447dc8a12e6f8e99e5a76ca88a72108397e804739ad896343801e46355836c2929f3a27cedaed8ce0c4f3b4def76c5812b9336bff95564389438b2ec957d2e9dd55edc9fbd24bbef43dea449123f62e1426397b83cfdb15160eea28bf52311c04961f36f96a3ac142163147d162f9725269193ed174bc771eadaf471347c8e9e7ca5810cde01c83650041af602853c079965bc7bdb674501a00bce0a81ca1cd05726e5f1fe0f0d066e15d9753ece5676d764a1b3e8266d6aa97785b7938f459506c8d71d067152f4fd79d8db6da8322e2aae4a06dcce8569e39bd955325fe780143dac613fd6147b062a8bd567d93a3d73e4f4949699a114484e758e4a29371587a08c0b188db4c9d661fe1afaa5b05260d42e9229f9f973fd96fb8407cf3a77b7e96ff29952a16673c5ff7d5721a52cdd0881ff6ae5c335cfba27362387da9c350450f63154c7676a8fd68759a3fdc4e73a4062792cce00d631c2bbd81f93e25fbbcd5d3282d54df1cc0dbb8fffa2d4727fd8ff612cb711536403c5ca9d20f2d69715248e5ed3d1bfabf721d52517118735f6bafe8bf17bec04a7da805d10e81b3564c871ec16b14975f44a27921d2b7cc41aca148fa9ada39d7bff1b369b3851930b41ec81160866dbbb6863ccd4873c9d23ec01348ba88c56088f072aa39b9aec760dc1d49acd14c4837cfe6daabe6fef2f64aa6f1915e5eff15a3e31637cb840aaf949d3d996faa4d789fd1f141001d450d22acba46de7a0a62ba2fd25353707126a2fea4fd55b310e63d94b8fa801deaf178adc5c749c52b39df05ec38efbe4b9b9c75e411d4118b87d74d3355546698052420101ff6c0492fc425d621b899f83fab4dc5307de45196e6d297976fd5ec9d2627981d90c77afa7537cba9abcadb9824d28c5c3e8507d4950764015966b7168c888237ac323ab9bacaace0aa324be9bb41f8b17433b6697eab07bf42d1ef045d8310bd8727f2979c26fde7ba93273df44df31432d5458a434d40e80830f9e5acbb6b898b7e5842a38c56754632fdaa7e5cf00f7bfb5149a17702ead4aee8da72abbf423b +expected_shared_secret = 3871c9637cbea04a2ccd3b62c9399b0a7277a31caba8a8f015d59b0fed845bb1 + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = 478771e2f15c94962e6200501bb90320cb6a0eabc78fa97f2d69c5a7a00b81db6b2a77a2b99cb1b0598af4bc5da77623fb5a2d3d1709afe65521c5324df95e40d6c20189a4cf80162737801c48c1d4b253a7741dae446162d6a2457574969105e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9c615b63311756d79efa6957766a5de25b89af140a096ca145988e6582bdf1b590c8689a366b9b4e2877c2b5c5a33320d3d532e3958465c9586f604f4f800952eb5f96d73b6287bcead21f7b8863088728ff160d1ab7b3ca594ecee60a8b741903e4892f6154d6356bc308bacb17067772580af8a1cf5157ccdb86aa642b7da9a6a583508d18773b307b2b0ca3a1cc89ff531e0df13948c288fa4aa6d3001c592879649c72450202e39c5f837051db1314be4a25a13a6a00537c20ab5acdc6be15562b1027056bbcb63d6c8227683480b6bdb83c5a74f31b0d1ab84d129d4a883e2cf48ac96ac9aee856a331a5b8a0504a461daef078d3d916f962a9f9a82fe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a3701982fcccc93353b0387df0671abd2140dc9555b8d98251924fb77570aad8737b12533ea4bee7326761e86986273bbbd447e47119b3eca4b7f565de6c0ef8494048a08967cc17ca4231c433864cc961f6193774494aac460f23d978f4267aad92b66678b560dc50c5e797bfd407b5b89b83aa1023a3046d098d939b3974c6626fdb5d4df84b7a3a6d63727ae028560fd79995e6c310cc8b6f33a3f441aba1ba3f44714975b3c3c299aeea9a714058ac74f1334e8c011a748485289af49542df7c2ab7830a3f519c41612f3066b24d594322913e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcc9924dfbb3b052622a15bcf0dc7911d148028c8a8cb574334010e222abf06fba5ce5022da143e5985c7cf277e5db727f6b07f2d8034e033a25b0b1aa9d180f4d403b7072f87c694a5962be49938783613fce30e8bfc204800bcb45c5faba48968c95199297626eac6f4c1099c903a24ab54251c353016418ca774c52294a001c2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = pass +expected_ciphertext = ddfc5b0084ba9e5ca50279df6bc37a9c2390c2762ecbf49be1e050f52bf52c56b6b1aed384ed56bcd8a340f880568a8b16f19e61e355e084bdb5f88631afd27264f1782e05a77c39a2e6e761ca50d093c6666fed23607a62293f3d4b73272c9c7c6ca1457572d8643dadcd420c62d94212aad6db3d5742bacf266569ac74783febf0de88106490251b53aae3a809eae2cfda87bccbbcb99d15c4d4b59f91e926818fef5827241c97b5b70820c701507ff9b7409ce1057f0f78eaa743807a1003fcf20847b63ef101754fcd280ded48ee34da0affb3b8d53d5754875cb10fe38cfae39761348d9bf94b8b6031dde2f04955b27cebc5c934f3377964f64114b92157849be5ae0d88c9fc5130950738e802918caadedd661e807a12b4961f9b58ff7992856aff40af139fe660455f4e7781bfd51cc0391b4b865191cc946cd5f9db076bedee9b04ed9258616847f3b3ffb64dac4c786fa0d069f600ce60d2b0efd796a09bca4e2e0b7d4599adec6771e31113b534e36ceb20c351525ba0d2296e0eedec74e3c6d622a3b823c6e5f39710997ed4cdb3097421d6033ac3907485032d84624bc89cab9507bf824b9396137962018bce76e1741e45a27cb842fd74020198ae5733d1362b43d6fef638422cac4d825f897037eb796426c63d17fc29d2c0dc3666c51c98d4a9c54799f06dfdbd437e389c0022001525d4b2e237da73b95ce62fd9dd06856ad96fd04229ae243b4cbc10cbdccc9d620b51ddd022cb0135dad1d671541ed0c74aee1280a97cba74ce3079e9364bcc9ac1b459e141d5b1f5945943a2f8df962221d263fd985f3e25b01d8f9e93d32cbbb0216dd0a1dc44dbfaac43b1c49b3a942f1e68b73dc4f92ed6a3e3802183d2c386519830876728cf959cc1c7a058cfc7df27f3567f664488b84734ce660461565ba5c4fd0b5e7cb111f0ec33ea8c99626e7821b4991fa9a48d2c0223c740131600e288908059dcce70ed14f1970328e09bb32f2eb16fe729c4e850063a5b987702097d8be6d4e91193700caff28bc6e3c73ba6e8a5e5779f8e82067456b2b3c1ccaa2521f9535ce401 +expected_shared_secret = 3775b12681d854b7ff2eec05cd4ac2db91bf06f3c14db2eb35287129a960ab03 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = 707a4731f46a6d2c59e27c013d7834f126719c302c7af3609bd0457173850bac49581557700cc0dcf034aff6b36c2a53a5e8580db101e0f718898cc8cf216fbbe1bc78c8984130c2ea921d872224572ac3dfd0ad0ca32a1075c9c2a97c41635ac9dc7aa2d014dc460115c93fc427c155726830b9cadcd8523c8722c3e4639d83c5898054fc68ca8588c55d89640e5cba32fc3f5cb283f2f9032f2c8dcf3847ee1b67ca698292a99348d194df068db0d46d992aa59a83c08b24017ca1048f77532f22039f92bea7139f1dbba914b10dd27abcd6912a8fdab2ac5c68646ab880554b5512459efac549950270e825e39670f06288a97a5e36a31e61a5257a0534e06c1418593b7e844f6381bf1ff5916be88c697c6a6c1c0b42ca1daba6300106784f125e7fc80a37f08a6889771461ad90938894a54914e2cf759c60b3dca1b86abecad16efed660e4422cae131f827b14b2bc4a7552073ab069365bcec3d3a41b22323fa827ad50793b3186c6a0a7e3b007c892868f18bd62105e220517c0db3057f77a3be29f8e2276a49416737c9990216c2eea6fffa7b4bdc6603aa400cb5675aa5a78458a498056511ad42b8550aecdc4940ab1c1739c33fd07bafbb287ae595fcaca6ea4bc3fa708ad3ff8abb4126d6aa9a4d9572b74cc5567b55412e901ca0c4d5eeb4c9683131522917f0a7eaf56b20d1177b448878b657700ad885cc0134a249970e1ce1ca779196215d104117c3c884c9196f33627d6712a3fc234fe171db342a24577a55c5c68e3a2350e41c14c701b1b01a39d2850b69274b2ca3a20ea2cb444294ea73042939a5a1a9a905856876b0b0e3492b6a328b40a949f1865f54558aa6263789093dea2ae2e8631e2ca5cd2662583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89d51669947f1ab44f9aba94bb239264a0c6ccaa64c0e2b3fe6212924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c4471a36aecaf3868b4b8f034a756020864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d80f31bd314cfc85416b2b2a1973714ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = pass +expected_ciphertext = 086277a8a542fd9b516d003d08eb96ad496fcbbc9e55b05eae42c95787402727d46c5e9f916bf992687844a4dc5d82e71401a36822009b0601a9fd396891a6c15c89c638afba7594b8e2ca0b8f26775ade14a1037d868ddc2fd71107932a112772e4c6a83913ccaeafdc4fd809bec26bf3e6e7d7a69be522d9f4e8a265417e36ccb5afcf25387f35fdbcd6170c4d31fa070122e7cdd8dd90fbeb9219db9742191f3bf4c68c95a20bb1d33e2efd99eb2873e98b9fbc6369b9c12ee49c39ea1408bbbba3bc498830a5bae84c72cd18034c27d99e1fd40a5a514b0423355d474b2cd0b7e97a7dfed1ec618524eb2836ed0883f4ed5d2e3a202d1cd2e5a27c6e59d4fa1c79bbfb2c0c4c74c9d515a4960eb468a6ed5519e1ae993ddc86aef51bb20639d063aa99e9e7265996ccfaa700b46c6871f1d40367efe07cf5383b97f14a1e408bbcf7f77aa19d1a5b004956ca61d29bd8d30a1419d2d831fe039ac0d750843c1348c7ce4d222dc4be92d6ff20ccb7cbe28d225575b9b7c1e26127fa6d367225b7a491f34313f73b76300ae25a4b3abf7ea7bcf692bb488daef093a1c91e4159ce21559495cc2bb730e1a9efbfdf7f26c1d2bc55c5d89dcf74e0310f2de14a1499282f9b32f373fb1214074685bbe5a256a083e8c06b221a0d16a9e31b38ae7733ad9644e70fafb18391486e1cb7cf9810fcfa276045863cc5e45bb2e9ea49dd7659fe26be983f6b984dd9c0163a2efcff698fbaa172a180452b21aca550e93a20e049de89a284ecc30eb45068652717f143bf61b5e7a10c35001431470d0966445cd9c118135b29a7aa442809e40ad21d7e52b040a0086e6c99cc65f18cac115fe47834d45521ca6e54f0cab4200ea72319f9c916ba9fd39ef1c404c34c2ae14b2c7f407e099ae8056f4faba6d0b95250cdcc8d7d55d417a8b666fe2b7190c7b192dce117866e8b5c75a07d387455cd195e8963032afab2672d818332c81910eff521a0e1a4415ef86241b14273566afaa97b3e877e0c47589e831bf4783c78b07062b4d523702666fd8f2f7ff509560f1d43cc5fc63b9753e3059878e16d +expected_shared_secret = 87662dcdee8b176e2dc60d079be188f63501274bde0829f3595c99d1e564c2d0 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 8f31aa78a9043268c7e25b0c43469ed0a535bb9a8d4ecc65c3cbb32bf2361838a8358b2edc1a1ea2fb66cae5070a30080a84a9ff81b3b020ab1df4548e510f03b13cecd4aa32f380172ca85cc8962acb7a51619632b53bf828a7ccec1b65c72fa0f814cd2c101690b769e452e34993b0a33978c19da61b0061f24661f20ea6a566b1d7aeacda859e52cbf32aacbd1b7e1e66b138d2cc613a26996b6ec8d89c63a34a44abcb70772083140fd6519eef107f91983f2e4557a7e21c62179674031b9e7c2edd845188c12b4745b7a68308e1e19a86968a4ca001268132e493a79595989e7b55a9f2ba83ac40c89cc752a97d6d6b6982e1033298445384c5fd04ccc06692cee0007a8481316bc02a724491e469ed7a2f1b809715da8cd130a2cf4c200b168ff33181430cbb5af152c0510e46b9aa8d83060648c2ecfb74840c5110004c25d9164e1a3dd9e181216901b1169a9ae3a760d1ab96c7bfe405c657a2cc1e62c65d99aef490892e96bd6ac08d9421975af70b16d3a12f898528130f30ba4b9b513bf42b2f5be08264a985b2ca61998a2a30030e3bd51200ccb3d0f66d08a677f6236bb951150e29531ec278f3d013bfd0afa81c009d0c78537c62557b7c5c930614e14d9600a9e8ac38f44761460666d4701782390552693b83736e3e340d5671ce0c5128cc991a984630f1f3349fd80e7756abed753226b456c2968efde96de0a924b926ab75bccec5e69b24a42aa34c110d75ab27495c5d4cab88b1afd49a2fe5c02acf3578fa4664934a1049fa7d89f666e2dc77165498ef61c575b4156ff7c2d7aba435870999d62ae36a6cebc66d04ac54bf4cae14c0ae89aabe90f3c397ebcfe69aae0618475e5512d5534f85f711a20a9699c620181acd1162b06e990096f7799f836771a05e56c99d3402599e713fd0b44be0db130ac3079c583bc0ca266a548da0895c1a3c3d1c28385537465df75b055106a215309309820813b3b8f7895d53611061bf796b47ce1019e3aa09a013764ea8ae0573ca62818acd346fe3012319db7d351c073d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = pass +expected_ciphertext = 8e88de0e5b03a5b2356db29ecc828f4ab4dbad32607b6ff0d052eb16aad666d0e1865bc841b8159af2ee85a5bef94f89548f5a3fadd8f7b6c84fa4597f7b2f01ca125beb86d6cd34fa5cb141127831ad2c98e08431102cd332fe1fd9843ebda0fccdd5c116d3367b08229fcd397e7ff2bf7fe4013975c306415b77656a733088648e93ce6813c314b7d001824ae7a5be1c3bfa58453a5f9d9e13782b36db6e3d2489b1349feea7d960f53cd8248d22ab4827bd7fc5d9ebc972939148ef7d94fdab15d89c1fb6a0e6d5f706377dc1538ac6a45566893b5f9aef83f1d24f6fc0ef170b2e33fc712f02ddb6c39e9c4bb0f4543a14b3fa5436b6a6027b6287c3e0e6bf5cea841649eb652297da5772937cfc2f98c8d3b053318cf9218f4ca4c7cdcdddf35d6673a7daabea5a087ad0c78322f86e140f030a0d6b7c745dc632ac5c158074db2da6b4015af685ccf27d8ef7da7e9404f2a885e39ace3ec7f23d8fb02104d8ba46804756dd69520d65b0e9bb0fc1241774e36f76434179047533d5f57eacd067ee85b20263df354006a01ae38e0498b9565614a35fcbadf2f29775c4e6db4f9eb329e9e7e04457ab78af06fb8a60d5914525ec051338cc877b445605a0d8e28d19b16512cc06509253071d6b2d74e328c20e2eafd17e9b8724f51b105f433ebb269a7d94f2750e9cdecd4122bcabbb9636b4a5fd9326f2fb3cea6bbaf0f78deb4f2b33f32278ad75a9c77d84b97865e09595d1acaec269c3a2bbfaefe9dc220083344fb65090e982e49307d525b796f30d27dd3a7a04388167489c9d26bab2589a27f3627b5f97a7e96f56748c75aa60bdaadcd1de91c0db8e7ee5b754c22ad491b7a3c218858506f8e959def527cac09b9208741aef20f1f8ef2dfaa7ca9e7c43c27a526872395a808449ee447cc7c71bd0fa941f86063ac84e6549eeaf90b0cd60b6bc1d932356442a26c07431b490cf53a95d309ffaccd68e3d47e6b9bc2f4be8313adf1ccf2b8fe6fb5eca852de15bfa513c3407ea996f887ec9b744e5e9a0a6a140f6cc7a82141b40a10d094a45268c8ac52af072170f7e2e5c03 +expected_shared_secret = c5676cf0cc81871d677bd7f5982e6493aa3ea4dffbb30dbaf59e90e4977d2f12 + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 6693535cba8a70d2410f72cf1b69ca2951579da03b23e997146bb3519c521ff325f9f1a1c1d506cf42079f694f0340abda4806719b8df468a53a92b5bb2629ad0b54799103c0c17936565e30d9272f44a657f190cb92887d4612a517a35e87b24fd314dbe32d99c7758e5458038140f1ca660eb8c1e813822f52865f6671cad74ff478514f87afbc4187c0c12a4f388a63613d592c1dce237d13a01ee6db54013590dd91078b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5b9d044a3950377c2ce8a010c9f59ab7e27aadc49baf10521d7b11d3ed707ca2b377912c131484c5e94cacaf88595c711599c081808681c6609227648033011fed686c9a2121e724346426108a5c514306717224f5928063549b268d87ddd91a79ccbc42f884f39d097e6246266173a79c68896235619928faa907d93226db05157319456dd06564f364e8ab68aa1fca43bc419425160a6960ffef152ffb85f24358d2bf3c375888fe8f7245225a27bd710efba2ff73901c1f080f6064c44ec982716b0fc7a88aa41532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe930915d7751fc7b1094d4757fb0baf1aba40d0d443f60cae0d5b19bc4c705567a602402d18c546ad9b8cac337ccf4a0c1a23467e75ca55090ab4435446b9737902a73c69cc86d050a8c11fa928257c5774d3f74547016995633f7c564dd4c962f9865fe78347d8d0a5eb449f6a046bfd6028fb1185ffc86e722239cd3bb19fcc117c34658f00b10914989cc24545e615fa824742a1814d7642ddd21e2a89194d13270835799e23ce97f25ca7bb82bf096358916d73c73259853c37d814425b37e9c67f5630b408785290934a70448132c653afec782a478920a085c46823b960ad795674b937053543b80b98c52fa29961380a8360034674852d151a8c1393fd0c97a0b94695b8adc652ad1d3c69764387e75b1038921fd53171fd43657fba4c919411161004b4db2e079541af110e166ccdf2b77a8709028b18a96e015f13fa6142c63e71f73236d227e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = pass +expected_ciphertext = f9381d44768a327c751ad39b14ac7ac1d1f215a959bb34d8e1f008911d7c66ca6e9a8657c6443eb4141a46a52ecbf354812128354b697394d97eb5a7477485a676a0fd500ae629b3817ed80920f3cd1a8c4de779d29c2c814136c4cba979d95f2368e015b2480b55de69e5e3d4e58583809cfaa228c7f0a07fb3ecd9c3380cc3adecdec3f7d502f20baae95a4d3a5e13b2719cacf76b2fa992489164e4f9abfd3ad91c795efe5783a336e988995b12f05f8c9a8f199fdbb7790a80eef844114b8f4eb4c2788e25750cb103baf4e02a4d75d1e28e9e39849d2177a008cbfd14ddc4aac135203938e4c058b5864cdec6f4630f698e4982e25100a7de03a7a165b36c20b25a2406db953670785493ac8556e2930bc0005d179fb1cc274eecac96e64768729870bdb0af25a2bf01025222c48d91feb647108e624d075c8f83d762f3ec7097f84479d6f6b052ef975ae641ebd7844b4c525dd05ca9b4fb1f4cc18846935ddd74826a3745e34f3bf0d74f13fe0b497aa98fdaa59b94b60132537a943444cfe213900227ad73c8578030d9c6efa96e863480c3cd2cbf1976134c8b6309b996c18ad1fc84f4a98c5f3db36204c7b178557b0e5c99b0403e4d6e2dac218c925572d8bf7bf33e463fb2c88d24deb81342f9a19172b2f34fc9c86f4e81dc298e35199329806062b916760fe4cc9695d0993d31b1e8fefc67ad4e423dacf63695c13a0388e0601e34052d6acf7bcf7a7f2adb76402c324cb7ac3173ee51ff41f14b9d95fe71e6afa49fde9ddb9ef2b308c3a546c04c345dc0fd2fd8badf779e57490e6e8b25c678c5f1b001044d5d7637f629301843519b4196ea99c9151abc30943b13ea9d9c8ea8f5bd15008c8fd36bbf9845ffd90fb5d8954ea8edb10e53ebf78546397edf86d354adb3fcd3941569ae52d86e07223f2731b6f104edc3fe83c9eb17f1ab4bca27ec1601d45ac2c464f573aeb142846c28dd7f734965a8688b8d2334080634d344cc07bf7767c3d2dcc3e0b72d3e4901f5d3bdb490f1fa8a399e3e53eb3e487452072133613e6c1a0d932b5942c4512e019ada64d3dba28b +expected_shared_secret = c5b03a417c10715a53f3a1efc044a81e266b40a1b16c87aa1f754146ac39b80e + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = 3883135665ac3d6b0e710204689c2616487bf51295c5010347b4663b914bef02791a147c20574f1dbc7065e7b2a930236a99304b6529e95b9eadea48fa5490fcb8c59e6b5fbfe5522bc057e3f9aab8e7aca680cd620310a26bb4309a2f2c4c56226114f8ab63de71b74971197d6a52308910188b603ac8523493a751a1cdfd441259b03f5d140f862cad7a794307aa31cfc4624f2a740552266b22240e631638c2c17492adede14997d95e4890002110ce40fa83f416a2ed06806cfcc49bc9a1599512db09362aa01650f7cf56290d2e85424812cbc009afd5520da63b30dd814e25bb1f974b7f3f77c38c638e1943beeba234736a029342a13aac8d21da0747f41b217159869bbda51885ea9b0a99abac1b740ebf40cadc78a6fbe93076e214031264275c3d56486efdc00e9f1ab1d3bc98963c908ad13268d9b068cc2ad5c36f68a11281da7b2c325509383e71d098c22a1de3c3065f1082087338b3ab021b0a3fb2b5cbd1b29f7b3b7d897c8c874b9d71d34dd60bb686b99c82750527704a53c737b157a6c98a148ad0727d13cf770b038e9a275e568b19cc2bad360c958c54900c59b4bb69b8341362ac7fb589ca96f563de54a46d3c02c475788351c5ffccbda1998a87d7a27301095ac8577cb84c0a4a244cd8c544f4bc7b68cf02a99d9af90bbb42a1ce63740ea784e665882c6aa1ae151501e560ebe9116fa9cdfd749153b7310e1583feebc2856384923200a811b2c0f71c23076de6590a89b6b6114316eaf80c90480c1ec1c131990637765fb17c2b0cb1ca1c03a3461bc2c8534b35493b3dd3c8d7b6816d8127d192a6f7d79e805283e3e882e8120aad321bb6a197fc60cf443ace984510bc59c8ba832699c8b145bacbc090965ed08785f72d24f4b9ba70c41ea79c91591b2295cc5903b29e04bcf3566c9b7c001ada05744605f1845f3e13bf9f22744659b2913b2489b073b6f01765c756aa494a41e44b599719ef5968853c0896425085d75cbaf73abe304025ca6006858ee7c1c9cf0067b576c168651e3fdc9b9d978cb1c62354094faca0a4adb426c157166f08034cd4025a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = pass +expected_ciphertext = c09c79e80d5fd851248fadb02c75d28926a95c17103cfdb6c190b9c97b77f128dcbed92b368b8610d7644d947f834fedbc5f53a1a40a421870229aa8807ea8e407a099b9eb10727fc7856eb275f18c153abfc89aa426592d159952cc6c4ccdd6b45e1f80de249a42728da33aca44b5868bc7bef745da90e297cdc7156be96de11ea7e699b24e62711e20d19f3b7cfdca8a2e1f09284fc3725973a0f60afe3eb0928bac1ff71b87985af10c522d381a381a54c8c33e3f8f639048391ee7a49806e68e327c5451e5435643f6260f5120260019b4240211929ccc9f243ff78e6b2c5ac80c0ba4d0ce6f2f8b43a44da5056c12e42aa920a819e0bd485e24db4ce6046a4477381bc71085f3fc45c1c0dd95dcbbdccabf7b17315efa3409646911ce8eacddca65b569ddd37005688c70d8f3d2478c7cb223bdfcbc33b98e88a92a7411075a225521ed126c3d708e5b4f4dae946931be4d33b9b6c1dcf0f06b74a71b3e4c7e776df38263b9cd3cc766dcc1bca5ab2c80af0b29277fceee8104afc8d45a68b84b014e7fe301646b0dcc1464bbc09c316b1b3731d85bf1df830b201456d4b7dd7f09809855d98854fd04602417ecf0603290ee6dd9d000e4dedec2c2f169fe46fec554c95d49f17713cb0e9023b2028f2a1f483ff3249d2627a41183f8c09072b3b35792565fef60f784b432266d8d6862b637a2d1d3417b2d4473c0d6311a9814471b28392c742148835350f07c4bff215e1c953b4915e39cc2836ba217adeeb9de4e5fec5c41fa292b0d8c09013d7e9aa61ff33d6e5dd50982b09c0aaafc07dbb7a24ad575659b036097c6a1cdb0783e4a8f33cbe999c188d07824aa0411d989dd9e9d490d9fb0b554a990da565df181a53459ded33a53f8a80484e91a136e02534e80a05c8fbe2d14b606ba681989f436ca2de0b75015fe2e461188ee8fc1623916349f37dd8199a50ea89e134f999de57dd76249a3476bd9f2bc8ce2dc898c7528f8e4ce77f21e84bdcf3e68dc751a660f72123f1658dfbad7627ae64c2d39e6b09a63de0f5e2423d7bcb520ec9c128d86a6e01cb712f524cd7b16d1 +expected_shared_secret = 38daf9348e4d89149e4968131370ce3d38a4028727fb85d27f87a95b341340fd + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = e7752afb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afba81681b834d55864f8e240a69067ba1384f9279576110a0809b34c81aa350cae66c535d5f24315fcb30b3469e59c45f44915d9a010e834071a60b4e29001674326e8b556943246365c87d9133a7e68a6f57b63f5b72a94d2545dd682143ca0ec892ca3376ddb188a83b3ca5d31899c5b8a0ce014ddc1bec2988171d7bbec2742feb77e286306d53b687f9c04c45a4eedd1c4dc593067086f1728724c282dc8b94978a67bacda824e6a259e12c44340159510526b6630df44bd4eca50c62b77fba073de86c167e9974316962c6805dffca9f5d4a413cc04da0b4a9bbc3db7eb825d7b1f3f942870c559f900bd0082c13dbb59d68b8b7b84906b4c5e86ac94da520b54a5bea0f51fdd12cf53e90ab317117e320afb377cca024d91685a2371612724208fd02a2240b32349893544535ec21655d398914bc53589b5a6a920dba6b76b125c32611c9db77827132a00651f6bc3394eba975bc40e87c34a696a8ebca0cd356517b4b16f53c99feb517337a8231286a0ece32a9208bf90daac845cabb86c8d61d498543c4ad2325cc82a75a11a9751c6a0d1a7015f74ae1e32485b26372366cc97f42ea0840e20bb54800028e537cbe867aee64a1ed4453d27768a55815557e71a3857012e33172b3a6abc6729b207559899043185919883c9e6f74d1c5414e5728d18785ccaaccb753b61a6518ef57b4546c5261ed80d6262ace4d72f423b15f60312a9352e19e0887e7a131e590cf24b499dfa53ac3c5123240469350e097524263cad98a50e46739bd342bcf5d454df2a82004ac7ca8c23a7b406fd396239f74ab0686141d3ce9aa85efafabe79c1bbe2883efc6b18a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637e0259e485203077a2658a73871b70e28358c94143e78802596a4124b75a2376718b548d8eea706a4a256b297271a2a0afda68030504e5c35f7f4cab2a667897774fdde85e5ae01fec059111a1b1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c817505418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = pass +expected_ciphertext = a1a2955d5ab07eb09594fc40e3f42f6b9b9972f432df202e36c9d06ae6a5e866e3a8311a128f7d6e2478aeedeb19d43cd3b66d21a4896900bffc09445dd07b6eb7ff69c3e4b44111b8176323952489eb1989a5ace34b7af22b90f2b70b71541ddc796f90e4db332fb5a879564bafa9af37b8f3c12f5212a12a1d960a5d67079691ec1617a3a491ed17cd7d7735b4eeba90424de5187672751b3738223af79c70231f12897e2b6fb924dac07174498737ebfac17af295a56f26ccefb75b34ea5a14f17dcdc8ef9ebea5e6d966c8203310898ecd3955a85bcd1b66c64624dc7f83e487c2209f810f026a9230ea8e0cb577db040fe22e5e94120d40484d6baaf90f000972b1d304dea1f0ab2e964c1d46e28a879ab5aa67d4e4434b787d5b04cfee49e913e793ecd38deed4f234fbab2e984787cc3976cf59b0cff5692c53ff83ea0cbe67e392dc31b906593fd82fc34ce1e26393679fa3a2a53a98760ca751334fee40170b90572a77cbbffe7520809dfd35f3d5a336b2c6ab06bea4ebb15a0b06782da865de8a7b7e7d0b4c533bc8d5808e563db58c3937a783ebb0a89c5b20eaca2b8383b3ad8bf8f69566a017a2e8b49eb25571dadd14e799606f6da308d5d3b951f86536cb50aa0ac17c0b846163dd580144513610754f5f2fdde7cf67fe73e75d763699c4e77c6f5be7eec75af73c1a6bb4bd48bf54855ef6d2ddb82b9a3ccf51341f3a8dd946635b96f2e3f2745f948eadaef103cd69ce5c7c0cd87d9b97356aa7e4788333664222c36d5b1e295aaf26a407a6ee0b80b17c8a9d242afb71340ee78bd13657d915ff8f7bdd0d938d6a09d879af23d4f39c8582f5a0cc6a0cfd6256b53ab0896a03904c9a7cf724f98442e37dd5b28c06bbf0d3b9bfbec38283479f54178c04c3183ab8d1ad2bcb745650bb0f27bdf073a732f6a3e97fe98aee80b50bea056dea21395982641278454327301b79e05aaa6e3667cf4da8b396ff499bbfb3f9e6e338c42a2969992bfc8a3755160a93a73457b0a50b2c8d3cadfd52cf2bda2897a98c9bff35c442ae37bd6c4a4044955b4d9f57a4386c4dd240 +expected_shared_secret = 60bc23845c0b116208c0ea02849cea3d8025a7220337c617c4bd304aedcdc1af + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = 4a20774e234119411edbb3515e4c00a4987d491c37b3890db4ab249d28aef2c0cee1768c52b70cee7966b31c58ec975ef8b96dd2e156544a88a9772bfc834d422599b117968b648172b2ace7633ede1624b0a4cd031779040128c0e94332b03a798579206873b5583ca9c6be34632fddcc223a76c415e262ec8831fe32225ab2b484758728182eb45c851118cfc5086974403f6b161028534bc0390dc7d7902493440134c784b30289833652e96c58d12867cccd61713b51345c21c865976c0857808422f78de8b95472627cf6b895dd4065c68156bcd16e65494da75ac2e04668e0548e9658cb55d89bc8f98333e030a4720027aba862fb6f3b006f6be711b10b6d5e30b892708f42c49006357da4f637e8b3210e49817a9026b7403d64d861dc65955d75028e596fa68c97edf133d0997d84f342caab0f52db4b1330af6ca57b8b2423275255dc605fb9111907b648834c37ad812a300a715e231dba4551066051d31b82b6c3be14928c9cb78179e16ec0088cec140d3d6842776b30df33a11154a04ea7a6ade981b8c2995a37bd16734f98e95e1f753425f15c1a9b69ac4bb27a9bbff4f1845a734baa620595a66c97b64b43eb2c54f43e506cb8a7b759fb063f7c957155db10fc194171acbbe5eb47e024730a76c04d4525baeac5bef681bc3159bf0821c5b448e3a2c6bcaa55efa55e84e5084d257a0f7a97c322c8c1848fadc7a2f3db817816758220a5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b365132ebe95dc25a9ac3a1838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1d81755877c83b6511e10ce4d52440bd94c246579711150a33c62f42192e90a178f676ddb34a05401a151a4c167391d199211644238e8500bfb94adda266e23c0cc5f422a5c0719cc1a870e768c5fa95eba105e904a9875fcc58ff39375b72f84f12672386b690710b6b96c4aa17816a6a3fcf68e7b724ef4982c05799cb7a502b08b9ecde916b3e47636835c500360f24843c265b1d282a34f04ba6246b6ade8abbdfa13681542e77b17d398088b6243b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = pass +expected_ciphertext = 611c29905b1384fabbfe2241469d171ae5469bf944110ef6a79c5e06e36540300649545d479c143ebe97252515c9e3ecc003f03550b35ea31f9ccbc371aabb2702c7efb4e538b451446db1e85d9c7e2f7486a93a72f86fec574a94ca1e822c49ed6b9b06c4f9340c14ed887452c2681feb3674726b29d6ea6bc46f2c6de226076d154190525eb6ccddca62cc2b1ba3e5d1232e5f1117038f6d1d4b61fe754b5b5de5c55457108d37e27b2205686f0332e196974722f7904bf3eb1415fdc89bf92f8094f16ba89911276bcc33705556a4098d0bd66dc1a668f459cf4a7299f49b2df5d1cb248ba17fa613b810c21f864d1e9ea7e78d474a101a813e0825ee47440de187418943ce495cd84da8d5aebe3a347a156c03928fe6c4c0bdd23fcaf0f675fbe2d72e08ca6781730609eb298e346046953b1f915d98bf5bdfa582b1ffe5f200d54b2086f783e69f969cea706ac47501b37457ee208cb678cc12bc4328a21522b91d849d3128e6932bf7f1cbbe494e5c918c97dec505ddee8de0ea977c7822c1525b4335f1db864ce2071b50303a264f8aad6f1965638c97ccebc85fee2b3497401ff6fc02e6b3c4b97560c9df4b2c8601081991d7bac94149e2caff5d2552db4da90380f5e1fc06e85d55634a5570781b752331e39dc86da264fa7d7b627664f110b41f3ba7c702e104a3e0661660b8ea1f7a681af65be2c03f13a2b2e10674b55176a8c4ccf51523eee02f99581c48cc522886826e69b142702218772c25c082c381806d348835c28829eb81930dd527a3d7f8199e0bbd841822668c75bbf44afb9d3ac2219fba4f66e8ab1f40848b89011e417e5df41de43cd2446fbc7537b396e82aebdb03849f19b27f54d2b472b4c4a3517e777440b5870edd45f5f29d830e4368bec78623f0fedef49e49e32d1be375f0f7b0cc152d8d8a75edcd67f31e1959155e5e6ade4caf7494c6465917962707a1231ccbfc9571d5338cd30c0ae7f7ab40ecc9e1f11cfad4e1c98398476666528dd04130a978895a37db9669a0dcdd6426ebaf8c8f24cfa3699b275fca7c1e624c816708d4c0be6df7d8a5 +expected_shared_secret = 2eb03b010e291fca1bb6ed09d22d50b9c7bec93c556f1f273e57048c9c56bb3c + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = 6c10a1acf866163b55706133db1c41474a3ef0d4c7f131637d32b4803ac902fb5246c858a7426f9145cec60047473666a5e9c37b8ca4b5c1161dc5479341876aea6c515b564d68650b9822c6a817b5938f3809a784010278751d539b75ec07ba09aa34b08178ce5cb5bf70c99df201018b55e21c8a51b9a70be2997ac10b8a783cd9c54e69cb8b8a360d0dbcb9d6210933a5b7c5853af4b22364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a45181be8181ca2515d1394e7ef46ab68a1e93351a6da3684c8272c3e41547eb9e2e397a18f982e95730529c2affb88fef731978388791cb053906a57241cf99525fc87cae12e7360bb2a68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee3b231bc28bfe1534a24e15dbeb43fdb40238443a29d3685f3180d65658aea5b96078ba150623ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f19b1cd92177c4c2019789765790adb3d63c59719a292069922c5ab4b6b9ec2523ac919081764019282b16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e74e10196ec67de372878345213754af4d2affff085c970b6fd7ca06bfa60dbe526114bb854480d519a09bf5b6831f4b2238b99428538ff27c66777a49b4108fe3ccb4ad486f54a01e514266fd96a61fc2757facd39e071a0896e93036db4b110c8d78b586aafa5f182e1d05e17446f6158cd34427624a488fb4650c8883190f1b60374b0e8418a12866aa8000a7b2ca387b4b792c3719ae883a030150a668cdeeb6e8e59ad3e420361361a5a149c85880e245888192560052b490248b91a29adc0708344280b0b153bcbc0b575593245718b0180216d9a3847a186f312c169f42853820e862b90a4429f5d927a340589e193a5bfaa46f5350145ba2e6cd2727fc2545ee5bd74d4a38e181e527a80e2288444d860e7400b3ae3827a24042596124ad345e43a03ca310d37522dd962b71e8b3b1e3b29972934bf00015b6380617c8958303494d03366b6a51e7ccf6d3abdfb242ffb8367fe3a1d44ba87bda4587a9427dac62d280a0cb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = pass +expected_ciphertext = 7a7a1d8bbe39d2b6835bb8b12574366cdb528f4f642dbc4b07509a753fb71c25357604a06cee0863b279ba50379adf586e20bddc3f925008d1acfca6c0a77172de26a4098808669ff9dc4b2782fc9b5b1a331af04db5499e91f9ed855eb87a177748f9822a686f2bdb5864ce400879d5babe9282c28e175fee97973feadc09625bcf040ac94fdd59835d4a6da91dd5fcd403a5ae336105e36177534c8bd5adb7aae4081f19de5bc251f87a5424b5ec92c13832a68effce05af6d9cfab72d8bd36390f874c551ac5486c632f2d9c19bb12124b2fab29dd4103f0a27227f0c007d73125a3c392029ef290e7649b5d52766b9204ad2e80256426728fc58484441b58e08b769eafe5e5a60e055eb340c6b026c1f567169fab3b33df4b635943db3f4dd97c3f35642ab82740e98ee138d6da37dd01cc55b33993a1a70650d98cdf6b2798b9311a7a5094d442191911b16cbf00595e0cc1bca40d53dcf3540d5d07402275e552c57d04d7a6cfcfacd57010fb4c617a171c4bea0bf726d7f10168512bcf0dd4056ef513aa31416164ce130b8e041556e548e961ca5cecd42c80eeaf0297612c4a71d6c42e11607783e7e44a99cbdc9ff3dba5ec0b1b975c296b09da8e326d1e4d6207cda1dc8677c5659aa6db0ebde94b720bcb7f7b7b46e31b233dcdcd527326625f14debf1d7a7a8a35fcc5868eee21b00f8039af84642772b605a2b72e0d2133b4d7c4915d8e461c67c6e10b94a8c0f7ac81ee47a81eedfb660d28509acbc21dfa08435f61197cfe0fe4b73d2d0025d69fc57787f4b669bc559915157fe394557bffba9df7bd462791d8fc054ec2bf72cb597898b0e2a56a9b24ae93db062ceb59851ec2ae301e51eec0a5f60cdfb575762f227cbfa8a143e6b1ecfeed0682f4f2958b5749b1dac33483832ba37bf50d2ed6b31af31b608794b365cd7015c592c782a965f76f73dde41f4b345b74de4ec9f837b88f53d444eb038ee587d33daf46235787f21c8f3b257024fec18dd26cbb72af837dc30c92a76150dd41a3871a188b9894c01aacf1c302e7972d4d39bd4ce473c3171edee2c707e4b +expected_shared_secret = be892649db60b2ce07ef18c4a709714933542ab94ee3250cea6e7c6f5eee5d5f + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = 608a70da01862dd25b9717bcce38ac41045d44876aade7c1ed6a2aa638994db7011fd42b3d474b08f87b4b2a3b83ea94b4a21d214bc2c974a078b22598a7cd7895942ac29d876b9723f32fc3bb696b467bea64b176c1219732af5e21ab49b49fdb0bcf9152600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d380130aff7a0ba20a75f8a04238294a4191ebc900d255ba923056464f6621d2b96c493c2e5379a95d16f4b5a72e5c5ba3840517a28ab3d8a8c3b8c63e882ae37f4215a74bf62c54bcb65159f9ccd88e07933d4936f12c2ff174f84a1a93e1a9163d0cce3290324355c1d6b21ed458e2f5883a8806b2d65a5f85b3bc103a692c94333331671f54629e89b1be35c25746130d7a9b939cbe017170fec7d5675b3bba33e4e086d4c6625580536d0c28ab5e073e5f37cad826173cb422f60bc11208fd0023395603d8d047fa57cabacb428d2f361a13321bc20827d5566dba65bbd827a2f952a065ca19fc208f4617e0bc9bb97e82f4322413d7317c14866bc72242134c38a7774d1580485fa4e3905122ea993b03b12a1f6323ab778fce157e3450eb02357a71c3caf9571fb83718748b2adc18296f570b05c4a77502062841ad216389b3b3b71c0aaca94a7051b0b523504209566bc153b3206b822779a98f59842442cd2b5246c674105b450f8e385d1585e651c934c4312d3208f7740a6f8a47e3393221c40747e452e1b0b7918b64d6c018a130416fd32c20ff641ddf25bec731f9bc9a36da09c1f5a058440b920694b2e9437bf23c1bc80835447a33f40a8dcbca09a14cc83d44b20da529b303d74932cd2761d27f5027fd01f93e907bd0538898078f57395ee2972642097944c19ccbcb4cfbaa79289ae31a230c67218b3c7075ff32563089a1e65aab279c3e4d9c07deba0f72a796f601382385568275c8aa6b26a8caffbb09e44409d1c404b6fd957a967a17c83cdbcab30d299a623d4b0da14a1971a09bc83a59f56a05bc6727d91572bac8fe834105616b5ef3c3e0cc2998f5006efb3673f4471b6e9005957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = pass +expected_ciphertext = 7732839346a2622b81e6f6393906e2b65189bff14adfb40da9805938d2f55f9199775973a056c5ce0657a05b0a536e07e01bc9d44d662d08431e8ca1ce895bfc2d7431d6b301ca1e4c1da5332c52eb4c31c6a4954d0d421b7d43ca0b80348b6a7cfd20cb3d68af3a9bb1b850b7f74ecdf9d315504e20449b4eaff80f72d5019b5f0143133e3e44e0536d8f141f4648a43092475014a7d6081ffbbf6a6f13f5bb04ce6a2171cafaed5f945e3f167d8d79db5bffee110c267f24ca57c0d76cfdaec5a63a3c812988ece57da484fd646019f609b1b1574d858ff2909712c8c80f14a4a2f3b0daaed6930a450309cef3dade546faf53af8c2527d796ec430335fda2f83daf0722b5bb5edbc0c80234f549e10c306e20a0fd578d02c862073467e9e9e6e9f3c03062a447c7f3b8d2bfe2d7de50c3207176edb6ac36129d10d66eaa553ab94b9317d77bccf9b290c4c44f00a9f764c7ca051b04fb14448a9347515cf0ffd3dfa35e7dac0ea32b6f26f6a34e4763698cc45360dd7037f531bd9020dc5ab4ea337320443e002f40f54d0c90070a9e65007944a40bda666409b318d4d09a1d2b50d8f71004d03cc2ec7afbd4b5319ccbe3b92732d9389e27866465075019f3d986781d5c846c14e5f81c595b2a5e680acc0e82166452bec3bc4a1e4ea0b6acc7db2a6a051505e7508dd5b61bbf8a8652e36446f4025b105cce2cc3a880539757d0e7086226df342b4107f451164bf4e230da1c8fb9d8260c6383e9615856328f4593c3620accc0cda5f70ce070aa7928c1065e1dd5d44ad08905a50b59691559e0f2015add5468bc5be41ffe9b5f3eaae5e865a33dc2b08bfe09ed59a71d49ef3b57e96635cccdca8f7aedc1b7f1584dcc287b23b5e61c48ca7f4c1d0c329cb65c6019cc3f4ab37f79d2c8de8a1229c9357913c20a8e7d2a99dddb0da67e5278757c39821980fca495c213017e1acfef18c8e4128bdc0b7bbbb7100891428ec50bd867a0efbc7e91634731998cbc8e37086f321c32f2b90146999f97caf5226debe2a4e0a670980325bf48293561f8ad6f974484dbf856ff2e3c7d1a30aa +expected_shared_secret = 75556d5854c44805ca5c4bb927c837ff635feaae939220592d89caf74592a0be + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = 055323ba95c83ac687a58a7f92701e7c388a4dcbcc611aaf6399522960a44d316b77734f025218e3c2b201b0816cbacd5b9b303297b0361b23d531a77dc965ee89694288460844259a735cf0c4c0add2457c5724fdfa1ef4546e5ef7c2363760ad478aa7806df9e35f0e46ca8dd643c36c6c9ee3b564181893b1b3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f5631102aad2b901d5a7675d541dcfe35e92239776a81e758c1c54e00d380232d5849102117d54144a20247017148584c1038a9329b9ca5c1dd337c1f758f558628c6962eaf49abab214279138db549c04f87bf243bcab3757f75b95c1f08685f20cde8c6d1a353fbdb3abc0599948ebc82e2434aca485d191287bca1678d2ca75497d73296177009bd384a9a5d0ac8b6102760261852b63d0520fe82b9307d1ae2b8c38bc1054c0295f7ae2321dfc82417849a3bba7467232830c35c08038ce2c4562b7a89171864e566121f6278a0b777e02bc50029718709af63a7014d8b9f79627f61b457a25c202a6cdd6f9a59fcc3cda84a1a43620b1394fa65841162638342a24671a6a71e092a7a19866ab7519e723d6ecb836998af8724efcd2941a5bc225f9acf8468b5c68a781b664e3614fee782c20e80cc8f27d1f455397509c86067979d7407b1bb536408c654c624adc0cc126bd3ea29c33f897e168c9c715887474cf1479450b80659f816a7e1999a8f2008cc9cc732a35c8d3b290988dfa31a80fbc1a18a58263c7bf18dc0498260e66fcc6b991b4e91ace50240e7a2a4563460d016314c404b269fa9a8d1b0c074545feb288208b790de67dc3c787a12b0041c52f80ec9f6a96733d874e986a3e06b72cc4b2ad2460b7aa2141f3b186525aa6b6d2901d46ae2f5c7a195c55a48934b4478974370a982414d9a160a8c45aba043dc597a2d2a4acec6708a3ba881c925c215a8063fb80f0114a94c63a1971249368b772a662ac38856c79c7b726884cf5a014527da479c1d7747b4d74cf33f30612b70d1e0c2faea53ea1164bf9733935d51542ba3a47b099fc82cb8ec391a1361c19484f1bd52dc2315e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = pass +expected_ciphertext = 9a9b4571820f9c5f47b07bdb1c67abb85c73355083931db78f6325c2704ca2d94938b4254ee3b0f7a854dc5d538ad0acc2d8377a53e660a8c4d21401609c78402fd6b54da88709c291fdb782b71606aba066ccde8a916ecd03c4bd8a2742cb2c73947b2d1e27cd5a11b8e775ce9be45ea145a5b1f30c3f9f1186d070c898e2a8b685926d390aae1649bcdc5ab20793c1d6b6baa9f53e8a62780b65cd7c7df3ce7dfdea8efe17522a23b916a58c34999dceae36aba7e048be1d3bcdd1237ace16b56370c3ba759776b1a11648cb0f903343fd2b4b8f023e85c07bc4a27ff53e9d98c6ce95c867e267f80f93d5bd8aefd0606b37a8d2f6f7f1f4658157fa24419add7037bc7b9218386dfb29142e80c4b8b8e4a85c068061b84e869296a4b1ed7e4390b29d7defb0123e466e2ec2efdc79d47b134834e6fbbe1b48c8121604fca5115ccae3bd7b2e56171e47797074489da8595c995fc55bff27dbb6f6f9ad0a068ccf7369e58e47a02d89b68903f9b05e7c65fbc77eb9f85d00257a09b8bf5ef6a07e4f5c1cc2634c37b822f96dba4481522b9244666281168702e7cba9824ce6f9e04deb7250beeccd74db0fb7331748e0b766c398912c42f226cae3bbbe19e37b17ea3fef017e4bbeabf53313eff762dce9879966ac17b8854e95f8cf7bf007fb13743532deb9ed840b96cbf15f15d83f0f6642808dd917a6eeaafc205caf9e4d4fa6097fb91703a11efb675c9210c75ae4767022c220709af702fb162dc901e0803dc5b3357e88fe7c72b67e53f01393faa1fc25269c874766690aee0e523a2c7c6fdccf17f288f517f3870d1b3a9c02fea5892535b97f55da5efd615b74dcc86b2f077c0f0e2b4e43b043332bc7195af2a2375e55c062fff5edafac0e62a334b24fcc6e5667bd256605ebec5c162cbde1e40c652b4dacd864d144641b3034eff93d75fa59a8681d5e4ee1d582c1fbedceee28839f3ef1fb79d4eb7af134c4984e86d8389dfa7a21690667ca1e6ee44bd66e6c3ffd94e84347d6cc233e33210d737c37f5188d8c9c33d7a41d76c0a60862e0ccc87b787e574634e3b130bc20 +expected_shared_secret = 469d60c303b10f517a932d9fc090e61802003e9cba3630224f2c43a4727230e1 + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 7f010097591e75470eb931b90d0a7bb708c1b5e97fca41b6161ab4c1cc9ab3cca4ef8804c76c45c44c4bfba29d978014e36195cfcb04ce7487994261638a779fc540b6d0286849b7cf51b8b648ad792bb225b42b637693f967c21758cdaa71134cc68d8bd7198b2a971071373f772f7044b912775652d1b78a9c18c7f00a86526b134aa656801b507714ab6a37fc57051df46a4ffc2899411eb6083df07a9e59c2c55d626d0bd04425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e0a1f9d9416e2b2ca22cb20f8f4ce3080aded2262d885780c9c4f171685b466a5db14bface3cfbd979895586a5f1a2bbb7626e567075c004b92301bb60b0e3208882329cb7de807a38656f98abd1a326ded150401035c816b9e7e677a29849caa7227d57b7969541e11f601526a15631c75f6e9be24d54773f906f394643ae31161898530344c07693c4edc042ae805b92157b6637722146f16f49297370a074962edca884a2cb091568e70e3a57ef2aff79b17ba6226b396a5702673704b01d7959c180513e0ab03a421425274ca53774557a8ba060817b62b8abb20596eaa16810513885435486bbb5fb83c7a9969ac593881173377b1b79ef4b7f20b0b6ea325826667fba3c4e31227cd858578bb771c27abed688844b95a4906c290596ec7b14dca4a60cf8bce7d12545833803351a0266384ddc2673048aa660b9a8db520d37ca59ea19cc6f19eb9e63d6e842076b397f5027ffee9672e91ba1bb50f0ce37410c686e9952d86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637e227c963029e7935814fa0b11c4b0e695aafbc75dc2e90d8c63740c8875601008b8959ff214b513d42056f78457b45e47285440306d15e3607a130a4d6b2bc0904c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382624c07c4f26fb449a412c37b73037131c81af9084eabc16b50956ed9daaee0f4153da0c959c40f78366867e11378d2bccae21762b543d8b2ce2d7ca79cb7ae2d06544982728a7a2ce39ab54df83521312d942c26f618ae5491bea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = pass +expected_ciphertext = 3e361e9dcb35f7146321e7af1daca34ec0152cceb5775c9247c23eadf5b47059f1443b2231db821d0d66a1cc778842afb8175adb495fc6549044fb548fff25018c18bcf791ffc75c7a3ee1d5939fc226f3e992c8dce24c07642c28aae6dd8cf449085567b97d6687bc5227ff71e12630a8e1710211409b118a6973b485ba8bd7c8f9fafa7184d87d15fffb78bfb00f5cf7e3eba803ea7826f928102a57b197564f48b2e4aa47c020be5e1f389a56958c13e55062270e7988af908fafcd13d4f122ab6f99b3badf31d2c0d15f0bfd23b68b5db9ef1e278ef25521b2ff6716e7c2a45416f02e9e7b2c0ba1fe0b4cab08e0c89b3e69b384522a203c4e905a8917727be79b1991e80a372c38a9ae6a8026f60fae6f262a8277941c718e7d4dcc679cc6cc16555a5555c8385ab2845859f5281d42ca6dcb5121f18bc37de2e04d8c2f238edc456a94ad42ad9ef62c1e0bd1a0df361a59d2a26bd5cacedf7b9a0bb1844ec2aa12f81f693125c149058e5212cb1f2fd6787f3f7d228ae8f87fcc2a8777b39983563c40855dfd6fd8de65f17021c7f553eaafc49a526b8c1bc8ede4bcc4ca4f722e95ce80a192f3e52fc89874f6f0f4fb0f8a396a299c77ee476f2584b41222b42cb0f7a60ba335b65bbdc2c31e80e2fbbac369f2f97380c06c3bab9ab44db05353fee5a8a757718f3093fb1f431046508c2978dffbccb51a0ad9b82a72b793e524fffde51dab47b58a71e1b54d833a31e5a805a80a8404a0e18a60811a9a814da8f16c3f7ddf850cb9a98f5efbb3f26e3370e0b9c9f07bf696afbf35aea332c6879455c48f7a9aa9e44838fc7f4f997b0076e66e263b2dcbcc1cc4a884641b919dc7d502361bfb7cbaece1e944ca5cda40f3d0c1601c5a2514891590c6de08121695e2293a11d70f316b8b3b19059b782a87976163d687221d494de8f66c3f753b460f29abe5e56420118d464c33a955f41836988bdb067a5ba07926fd34d1886dca61324476a3e7c685b16886d077ec7192331b98b850723cd3c10fe294cfcb5e5e05039c5c1ec4ff2d8d0cc437b3c2e64a15cc867a7d6380567b5cf5 +expected_shared_secret = b545dc066355b91cef05e65107fa11070c455209c55573cc549cd053c8e4155a + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = 412ac5007438690416fad3acf0bbb1642132613200006b4a502975fee79d2b7aaa8ae2745e16c0a666c8a3a24a990cc4646c8bd9e6744d6245fad4b2acc58b0001a7a351b61debc0cdf85b5b5a188d040d0994027f8131d9706aab35763e4aa232554cebd44886a70a7a846e67c3842e96a3df7233112271ba001105e2a35b5689378c108ef44f8ff858435b7fa1b1376f4c5276a4002732b81974c79ad23143d8134fbbb2426c9baf566b777803a354c5afe8a1b840ca5819a3d612752d047207181bb6c049f70656c22589d1fb5d5b9506f432b52dc933d0e816b180681d7743aca5259f92b8b2309286b680d174b267c5bb01e38224763a26db0b36520477591b0707b09e97ac78fa71e43154afd39266217067fb6271fb4c16c71e277a0ade710562ec287b7493e4fb453c098e5d991fda9abf9e9a29e7b28e0cabb4be5c8a3f490265f5cc93a0b3a52881ad806f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6c7053a48a5168934f0f2341bd263648291078554692815e1b69b1fa97031af13901c4a90546396af914f1dc6d09f58c4af89474ec34614535a6dac8d0301f67339baa610cd5d9c2ac832c54a55175567a5565c478cc5fde74bf2614c6815152e83a615de8ca9ed465a05507b9218ad6f7b9b2799e2ae040084287c19573ad0200c8e683d138ad4e8804eba5729aa81c1e1a9ad034a352c156e9ab635e849f65a37ecba8c0009843016266d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b461cdeb83b637196d757999523097a00920d0677ad5c23906a3fc9054f1a3176d5759d39a03e591bc10a7cc7e05397af2c0f60e84de24318423c0470b82acbe97f3a9889c2f45418ca28fdb092ac703a6a9bafdf6b0d05182dbf9a55dd3397de5a9b0d7c4950653652c035addb2ed3abbce4e755d2519e881266d28524c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c7811966b7e202395d4a46d81b0b3c2d3950fca0cdd208cf462b688919b79366381a11a6e195cf234cbf10724d4c3b9bdfb0816160215bc6d5102689a21af235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = pass +expected_ciphertext = e1160ba40116fcb1db2135f7820ef78e5023cdbe18b2afc353d0e3c5a98cc7321e542834d83302a0184bfa1a51d1a9b349fd79a8ff843a2135977c50e31e62f4df200df07cd7d40da1c7aa3d7c53b3daf5faf39908af436aa4263f5eb995999961f2d33515219a1b20808039ac45babd25a0d652a13f29f0f86a50352de672935f1d90502a67458955eaf044d1ba388fe89e32671aa122ba382c8a605cf4301fed0065808b03ca94da42c2b074c790cccd18d1b0070873281277bef252b920102af4ae96f464b0c5ed1642322faf0a829a0d86839fcd9bac2db2857e2bd098d3d9efba9a87ea4baab180969c785886b20591dd0bb5083445c068b25cbfdc4ea472097fbc45964866545a54598575d0d61c57d1adf4156f87bdf9069d54ea0381627ee4987af624e3889de5db635bc2c40afb3e83259093e8d952e921d553ddf14b712bb63eb25c6e9673abe27a73d37f33563e55b353631f0f15cba393f7d2e0112063c76dd1da61bf6ea976cdbbcfae79236c28a06ae5453781d4f74d9756fcf021c4e26320d1ca9bbc435522271ddcfb9e2a3b84b2f309286f5936594f52fa8e3e4d4559953239172e7045e5eed928cd1832def8f5ffe577b78526f09e7077fed5a03f0b9f1fb5f56dc51b72eac7bcb2454610b384c974591021a6a2f78fa81436c3c8dc208181d5483f4491319021f3686e51ae5da60276ef5af30c53704ab3025469809d319509f052cc1c4c85c899480f7792d1b9802d1b386175d3aec998ed3aca1e265fb0481aac45b5f58a6f9841d6594295af4c98bd81bb912de6fb5e52ab71202c8280ff34bf4d1a7203d224601b9c7474f6c4b77f549676258109d277162614167382153a462f3bcf1c6437e24a1d02ea67cc7233147300d8ad361775112258bb8b0321ef1c98f694e1e3f86e1833c8d9726280afcc31aa802590421a544beec646706e8d66257f1047d3d98217c42b077815fd8c80d867662327f98fb7d59c3a3a56a8d2e934f963f40ff1e78871a8d059a744152e72e082f061b6a4ac657861af3e152be2107b942ac4e840c7d26e9183c9f8590104c4b3c962 +expected_shared_secret = 2c42bc4a172c928bc6ec7480785d63f7281a9e5acfd3f94335d6d7fe5fb9c5d4 + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 54342021507ce3543789ba78abe30d6241382c6292e084319a4aba75374c0f6617bb0a92ebb52e66d790b9106553d5c2931a9534801d37551d9e7a854b9733be2b0dc6b86390886a6330b159f96dd3339ca12a206c3278603a123ac0c1e8a982933b0b29b5671a291ae67c08c7945e71891eeef048dab9370a72865c0b47c2c5b90d134132bcc48d4bb6994b2d6e1567409467bb21868bf17eb4c23184fa9eda3bb6e2187d7e9b7d503a47ab1c2d0837ba25a108805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8a612402091349e0cc0d142e9e763adee2af2d998e8e686fcd76c03b069a558605f572b359fc4bc7b0346d11c1e6f9ad71d1399eb992b9e54268ea8ec5e9af804290a19732cdca883b5062fe1a878b1696eaa0340f071e2c9206d39284d6b2499bf0a7faf99f5f8a6b77499419dcbdeb6725e776a0335286234a84474c54f952b6ae075af4729a277381a94414e8e6ae2a9bcd2e01517b99b299f3aae1ac965c086e59bc6d32a02a26b911be148c7e48385777b841d917c34c8842c9c90ea431b2f8cd71a78a15f185f77cce76959ec1748c44e5aefb140e752c97c5aaab8e936e84b5c89b3080480a4b8be81fb46b12049c6bd67c74fb9095fd95c971a2c813f08b55d9c867aa61783896707a36fcfb175a64013b071447469e768a7a1ac43fb77649802522ff880e59b322f85b919b2424650914d529ac7a147586279f1206338a67c02109194eb493d4b9ce33bab709c333a91079a542bf0d717f1c875d54f11d7fe72abc346000452fbb9178b7c87fc437129797cf38467296889d3e225dca6068583921c9767050f51246900af6689227e709c91727bf41483915b93b3225454979c0ca7b3a2c63a0521a5679caf5c26d5944186f43463aa419b4a660f2414a535b9236868c2c091616fa6522bb859fa61503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1d700ac825c501c986ed28bedac0604b40a0b4f8990597681390b2656857ac712d7d4ab4ce85673fa69c404b0b5410a531f0a6258336d2bb639f9230c16c9a85e363f9c355f8f00fdf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = pass +expected_ciphertext = 689eab66cd05a44bbf065669766cc8b611ffc6f75f205ccf55a56218d4f9da959eb545f8c47260052b1c2047ba745c6b083d12acb0c482f0adba085e3aa1a536515dca67b8335b06951388dfc6313686eaa664a67d04a0ff60ed3c620b609b4039296304ea987174ca705a5189eab8b53477e3a53a621ba08a2590791514a86ab550aaa853a8e46f60b5ab159c65fe6eeff861dcf102d1b2f71f1862592ed0280ba4f3ac61f0e51525dae128cb664404e702c0fa543e047c55df151853f995a3b99b92bc5bdb77cd3bcbc63e509fdd0c7ec40dacfb878f4e84c4aa9154ced81e814c668834bc4067c11ed28a80a35a478cb72f13c2ce1d70ecf4827d00e3cee83d5dd0ff0b43489a2b7e5ee069b3c4f48ea4fd774f66cebcf5914156cd251ea48c3ad841b5c5531640cb4762c4dfd33bc1f1c3377797a93cdd5b07343a01865cf6953ec2c33c7e2c95044c5a95d1ea8ca2c6bf039c07bb91f64527ec5be6fab765bdfaec1066a95246d95a3a936ffef8f08523152e46ccfabc515b036fc8179481e8a3097b99168825b055e4a916ca8d839a3fa98fac30b1077f4dcc73cae3626e827d17cc50c84545ef759b40e084678aa13b6f7d58cb212c002c837a04cb00573c1d4795795e93e8dcacf317f378ca4f01847f93d5d5e09f880bde0840e471f38570d947f842c683fc851527988dec19024ed1d109c2dfb9220e1c80877174e50eda8f24a513b1fcf730d528064272b7a1c8fa7443a4e996b51a54a0fb90ae336a5085ad6d1310e285bd58011a50dc829d6826fdac4cfaf70508e261c8e85c56942b021c248f1cea0e4edb5548959f7c0d08c1ef04964f5e2bea6a195bddeecc418cf4be8ae7b37a86f4021161962c46ec2b5cff3857423ad8378e21eab4bc4f43be3b8ced7ed1d9a1adb19a0953eaa9f961898bfda24e6ee007ffa4214d00c661a96efd43faf78f2d2cda966839007fcae6c9ae5cf6df4e98460da6ffec2ae929e5ae47e3388d7008fb390118bdfadf37d1f72312279410d47b4f19cd7b607c7de9c3409514c37d137ae5dea9d137d2a85b19f0de7d8ed9f93f10b8497402 +expected_shared_secret = 230a69c53e2192eed6c9b876d6b228fb666b19448e0a2ef8601910d624bc173f + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = 3fec7c38a86bfa490bbb6b001c129707b1b765416401290a94dc8e2cab1503dc4cbb2a51bda96c5828397d406386353a75157b09f1776ed5347f3a32fe6b2599827f83ebacba251dedb3c3e514b7add849ac5c40e49b1297634fdb8a6c0d9748a8fc9e98778668bc4446c1444b104db4da7ae5fb5db088cd34017ea6926dd2128e9b39419cb13ef8511705844d4efcca1219453f987cd5d0b532c6b958b202938a90ce9016792035577a4b59ecbe063a8a158b92e89aad62ea507520bab2596ef18778590708dcc62bec78a74715ac69bab4521949e8c0bf914b5304a7384ad25e79c3244e581033841ee8628ad68842f320584068cdfd91467c1051d1a8ae77e4b418343743f0a64635ac313cb722f61d0a672645413e5e92853f06aab35a067eabbf6774a291945e9157255af4008a123a25778d57308328a983c0dc8b4f21c7dd34721db734967a706ffa75e0b052f67c36168ab46c485b1190a6ffb60f4eb739c232b2eef630a00469bd011bc1eacaa9ca60c613039439cfd4ecbef6d7523926ad88b8581e619b02a182b76993b26b3784799a7a314b38bb6a17529650c7a0a556c3dabb0fc44ab8eabc2af522207e90c7c7e113fb7220cac24f45dac26d1605a70c16d1f58b6f766c8d07c56f582c88f6402fcab763f996b164047daaa7cf5048eb51297c50c44d95a664583579f18639772325ca12fae19205742e72803fa4b9991517442be7cab72996ebc50018963f89a5af785c354f7a94241051c80bcd0d9c7f8b09ccad58c0ba22820e859c9a261c6d41a6c310b310a480d0c8950fe1383727b0863ab758b2c551bc99cbaa90f0365961f7727f639183fc652bc4a2782081dc69571b298affc7af09c349124601602bac8c79afeda8531423642ed20075a9b176a75d422740c0c20fa87aad22eccb98d4bfbbf52e7b590aceb660e3982ed3f3cd328cbb6103af5be626b5036ec8460ba1fb8df516b315e1267ba1bc5770402082bd1100ba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620ddb15151b9c67a9c57aa678e7e83b3ab4196b682f20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = pass +expected_ciphertext = 8b51eb12e555fb46bf0e48c750b6d71a284850a56cd5af3922e92839761b1c085f2d9fbc83226098fdf6affdce428bdf900c8d89c03ab6c389558b3d5ba4075edf430243005829b960f7a87c862af0ac59e689900372e2388af25eb4f9756ac42d72222d4a0b0c351e7da086b4acfea8f4b1081d5b6ab7c8c5b37ce6e7615be7592489432dc253610c1d7896aa3a5e4d7399d82101a1e46677b4edaba777308a8cd9f1525341c9c19d1fb9347cbd98b207c5515d34995f4f2df14f2ae5212088806ee7ca587fc0d7b5a7412347a1cc41572aaafba04043dd593e7a957288c2192f08afd808b74d3fb89ad06a5e3a25d2c182c411a1c2c7fb3f2ecfa07b2c6de5319b9e309f4c3abfa2660b6f59e8db4815e9703eac99469eb78243d92b933f01a24e84443fe52cab14f7ae1febfb0e48ef7930983853dbd9d27f3ed7492fd9c53f20df28b5a327876f75ab1793be950aa007a6a87b8e79a58c6fff43a7c69901021c2bf124a4d22632a68b607f730695f36b014ef094f798091b3abb4da059dad519a80dba1b5afd3d601e4e00d258c6f4be3dd887c547c79f2e5917eacf44db086400e49fa6ccd86b8da13c34e267bfe5d5d247e37eaffbd960627875bd338d9c221b0f930afdddc811097b9c63dd5dc2d661f76954fe4ccc8b86eff95c5fefe71a2854c5b36b706711530a6ffd07e7777eb6bfc53f8ccbf3efd2a24f16bab09934bee06843dd4dced6d4a66bdbd651109193160c9cd363635ebd4079906a499670bfd09e0b360d0c6058be1ae86e305771c118dfaf9e128cf64b8422320b51ed1674bf5f4fe73b0d3072fa7669581a1ca9835564e3ac05621c1a652ee69d695f28d4fba47b2430867e2812b41ff7c3b3545857f01c12f07f6b243894be53b2f409cfe00d5b705727f6bb5973cc9a3f2bf6162a8cbd9d90fccc83f133b3fa15c1b49054147d9f691743ba4902c03eab57374ceb7f23bbefb436f2d5c659f3908071b65cea4b8f744d77ae9cac24df472bf55cf6a5f892d4daa048e1182e61b214cbe2746dcf12c24a64d36d3e01e90f595bd146555368928960db5e161cf4ce +expected_shared_secret = 327c548d7df90d813f3b3c92e908c4c55fe4c7277f91b6fa2271c0f149dfb273 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 5ca83cb627b7477480002c1ac0ab41865cb5ad306b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda5835f8189a8f1829d09a379c059f3833e7af4593f6b5736f782215c72f8a30e60262dd776116ffb50746bbeb7565fd1a585dacc7c644c15f6647a25330e6e1301844652ccfb90d4d266e3544fdd7733b89b2326f0378d214b615ca423495cea4965fb586c00dc7243d423c1819be8b97a416293467a77ebb87bf724632657348f2a7b34aa256d0826fbe905267076c92262282291ea620b262355d067c6b882a64acb8aa6892cec15b3d66086a665054c40058c7a4714165a431a8c5021102cfb8168e4b80dd8b0c8d72cc8a07c064b83b5f1800b42aad50664cbe1b671d9373ff700cec873eb8a352081bf3fd9c9aec277cbd21eb8a4a2ec126f378b3b60004426a66f167154145b28770ba7b700b538863907961cf2271daab2118f2c40ac4989ab20a056b40c99a769b25c7a38d7b76a164964fb24a27880d7abc72e324a88a25466657c352486b9b17d4c13957d4b8ad26640c3a6223ad44be71535c3c258de440fb2a69f53e22103597aa8778127e971bb074b4dd704441c1bdb38274058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc5478475821b0fc7528d932874c47df5108f3e06106e18adde5a4e50d134c3648424630c42a20c0178bab98a67714c80922a3ddf431dc1a83a9a0c3087a45731177a22928551cca0e90bc229b95589259b9824a679a5a144c0cebd690620c12df2ab56c3a633ff6a1af01357b87108c4d56e6b694c41e153334b034d568f3880744059a214e80d3f477d67a332d44ba4cee7ab25d157b61416a81024dfc92f3650aa3e9c6f89a7629f347f91ec54b13997eda15bda0412df111529497284b312de5b4b0cc70bf0d2b643e5c2385133749243b678a026b415489c31d0b902f4dcc96981accc8abc5b08b9fadc35022b2cf5888d417b4a0a188d0a305d9ec820eaa4bb89c085f3655c0a2ab3962b069bb0a1ac6932c748cdc611b1949abe4a57b7af0c934c8c0696ba6f39c32f4e6874798bafeb70827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = pass +expected_ciphertext = ffdfa5a0634e6dc6fbb03b34adddf3d909f04934883900e2322421fc88cbfde7c0b09abc772e4157bc04f15e0378e360c19ef33e7e05111136ad4d8c31de02694255b97bb83bb05a1015965b642d141a08d425141d4e870607b349257636bcb6a9a36e02751587595e40675deeb87a641c6a5a52cb60c1aac0717cf53f56c3f8bba3a1934021be629aed1cd07b55d5f4de711f7dd92e2ace7d2245f4fc15610d5383ffa40efd0e39b3e561329589d3e51f851ebcd218400f842c757cdd097f2cfc3c3c646459197745a47592b668feea0213863cffea5d2f0247b50359ea2ed2cc3191ec2e8b7c9ea9880fec929591c17d6a265d898090d752deb4aeb54edb85ecab0d4a5667b38dfa2dbf72837ec641188f33d236d9e54107d6f9c3aa56ec02ddb8fce07dd2e815b893e98d606e87959a34b09d184002d6643645021af942000296df0e15f277b20fd4f17f67b40732be99da749939052a6418d336698c95ac022e9268089d8f15dca44c21e50f789e895f6fba634fe07ebe733f67c320c7f20637a223500acdd080d889b783cdfb3efe600e420b0356d27898af7e4dafe5d84846f3e92fb365a14f254c2eaceb397bfb742cd22d2a114c6c702e2554b3930ad0719f6d07fc843f2e3ab2af7d7a22351ed0adecd8c4e5b3977f9f788e4b5a6dda8836e42c7c9c2a34f6f62079eb9f01513eb43c78a86a55af18d8fe5cb5df964c91dc1908f66e53900ae6e522b6c1b5329e4c285c28e8d76a478fa28576cf42252aa2cca95bd1187ffcae126c2b082441ee7555ccf13a4c665ee8990f2903a6c1a4377049dde70e391271aaa33d0642c160cbe18aae29988778f6af11ad497de92902dafbf5d2a672b2ecbea57dea1df787b048ffaf0eb195eef3cf9c2a06e6fd24d0e791e51affe06207775223d91f5b2c58e3c719ddeb217edd837ce27529f956bd33c874c7e0bc2b5f2d191887aafc62f02f1227e716a37498998fec0b9972f834c71acb00857a6ebefa33018c01fafee9d947241253fa24e3ae8a13149ab23edc8ef45245b48fd5029c3bfea79043f3ca64fcae32e5ef7463bc7b0a4d26 +expected_shared_secret = 0d95796efa11ef2b4f05d0cd9e1d8db26f3e5839fbba7cd84e00d468decc088c + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = 1e0315240833d0f09adee4bbb29459f947897c4b882780c339019161e80b4699924a5c945c1a97c8eba4af258700126747a2800f81092649523dbc47ced32938a783461aa1bf6500f66b6e8307aabe7c4005209826a98a2904becd2853fbcabfc8c24489380bb4f7a1dba07473388508792ae1e7ca257b5c15c3771c92b9d07bc0b83c7e3371177985cb61b7bcd0083fea2075ddd321ce490a483a897cf6955384002be3016f6b9e2ddc5b8d5cb7c4f728e7966e13c04b310b7286021a5551a8b7e8472d969703f54ee4e1b1ae18cf1f6454e360c7ae481ec2b3b72d4049a74514eddb57f71b81b4405dbde79e05a1787dc2b19cf72a0a93b249b15fcc061e700c5325a40b880527f33b78eaf7370fdbb8eeb38e6c1585a12c160cdc7a43a7c45ea0b9bf18c5b5256b2fa2a25c1c29289a72f09560d54662af2c359dd87d9c599288541e36bc7313a4893abcb4ac8269c2829330d26b46cb666c821f49808c79eabc046b110c75a67ca59db9035b7061cdec3486a9b152856c360e021e3c25b4036259044347af18cbe495369dd5ba76ba917fb37d2314cf73607fb0c845463693060ab67785c1c6ba8efc581d21ec2a856ca54170190e61c8ad2c91b2a08791c1cd3ce29b080b342183cb5355b08d4a153c8a9b32bc4469d5557ab6ccc4a41d1f9b6efa405549e30022f64f62e665ab8934a617a4cab60567cb62dde7bd81fb69ee60a603c9138eea88d6823cfb3b6c0448c7d244ca70f5991618c3ff504734c98268f5770fec449ae6b4c47b563b9795a9d58f00b11206f4a26e6460af0531e1c07c54f1a61a86624a64a77019642082cd2cd8464e029e94085a8ab0352710c9f41c23ab47a53f2236387a381648036cb12f3f231624862f36084e1ed6b58309a03c50838a970ea14b76ca064756512b12e0acc6d4a548e63213c746877b4054c41ac3eb6eba4ca759223641613533c2382d53352fea4663d5a121759e97849e7166a50f139f04b2bf9609ab5dc238af2c0dd59ab31c6214c288b21b9b33a5c04845c6283ad0bc16285684d1cef0b11e8b324ab3d2616b71020993959815207b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = pass +expected_ciphertext = db7aae4d860aef5c9e6245e9d5536306065b0057d059c04494d80ac44d0c4e9f6788bb65c10735c22734929fe2d73ad97ca026ec83cfce550fbf3680ca63787e4a48866e162c620b3e2484292368f07bdf5abe38a0c2f548249c01feb4fdefb38d9e921fd87d5d91d3044ddfc2457fa5a81a975783ef8ff36e6bd0e450cf016693d4add665d91a476b01448899b959abb4698a22a79c1799443547327de7069f3ca56cdb964dcf245f302d63e5918ffb7fd31d5677396099b4d5b19b8e5491024947414cd58c682522b84ba8a03e506cff6c5391ea8a3aff70302d4f048fba296810cbd692948efb8377eca49ac6a47b15be7b26383d30824883474fa60ffea5bdcde813218182ee6ac82e0cd8b990fe449ee6ca3b42cb74654cb7f5a6d7bbcea81d0e8b01fd9fefb66e91ab7c5cdbb78a24063468e091b0c50f99880a7cf4a26a275f824e9a23287eadfbd4a425e7f6839a6e6033df2461cada26f9088da492648315dc3404bad8311f85589c59c193c6f1f0a8daaba797c0fcb9824f75a37a01c489d38df6a5962a80c0d4799f557503c3d64c6e5c763c3d9a132341893fcafb8d8ded3cb0bbb4f502d315b17446998c739968e5e1aae4ea917f0bd5750015d94122415ad932872e4123fe026e169578c95876efc592cc822122feaae5f1bb3aa1c665f95c5841e68e3556e1c8d85664b3e1da330eeb6e48dcfc4aa5d5499b246815da8067bd48fa69df4919de2248a77e5790c4813de37ba955b29ddc72cf90fc7daa869aa0fc530e76e6e4b95f71a3d3a1d6f36d416913f48dcd041b3a74252161b343f640463a1ae78b4905a66e71cf70ec285a947e1ea724d4a56347e793160d794df98c367f8a0ed44baa1cd63edaf7d7506806f384e73f438fceda2b88a76ae7dbd49334ccb189c1d95f758366628dde9d872aa8b70d6fba50e120bf08f3c9d276ac5d84a547bf9c16b7667e4277b6ba56ab75a5136c2d17bf3d6b568e050a63b0457fb168f0e6f375eb8b94b907101af14bbbd80321cc74456c9f7cc87a4e21e003c22a1c1e72abd47d484356b2c1fa20c3c7d1be232ae7bd5cbfc2 +expected_shared_secret = cc047c6cad36dd056b84e6b9a4fb6b1b349d593e104ba94a67b107b291ca4633 + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = a2ccb58d9b00887179c1e007e9624913b9924878c5db1c9e46faaaba1a2944304ed64cbe6b96c3d61b83c404c498f1ba7eeb8000c8381de471a50957b64a94c4d42005831f4b4380899b5b848c307fc49654438ea062719b20796bc39b72c34fbd717bff95c687eb1ea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b360b3de0055742563a1db2782072fcfa86945f83f8e028f80e08825782b05960005f37992fcc126b9c942a7b2c7a230c30824325228c971335fc3609878509d302c8f1cb7ee3b4a9e58013e2377c1104cddb2cf9f969794f715cc805157ab62b9b52d7e273c2f6b74f8e142b8473ea9aab2ba3cb0e1791831b56dc7d6ac7a41482bf347a63ba6cc072201e19949e7baead45a49922bea808b0ae8000aa1794b4a92056a51ddfa0e90ac818940b57408b9282c0835b2be2aaa417ed6be7328926ebab1bffaa0c2360e60b905834a9db8390bc48026f1136d48c42587693ddc15556e4472daa04d8ffbce175bac214b28b73c0f4ca2a521820f7206ce7daa7491050937d5c3608b024a97993ad0156c9cbdfca0997893a7e412bc5d6b8956385e00d7cb61696a3e94a98230c4295394079ac7b1818f1c4601301850735690abea3ef9aaad82b16b30ec4f7612364fda0f78557249aa1302d94fb9792acd5914693729531ca3bcbc42b9b2bddc768803d2611f01b8589809f15506ab5c21ce5bb9404306026b74b1685706d09163a74ecc51684757a02a9b5fcf21a59c17c894135dbaa37e89229a90130aac7cba14513de24611fa77063f4aceb30a92d3f75c4dabcc5ea3280edbb0297b7b2b842cff286e442834624936a8461752693c335916210c3d6c1c54f9ec4ed60076b281534cd497ec113aab73027d918d6fca080ec48b70c9b6cc57ac527276ff4ba3aea74270c230ab058a135995d39438e5f52649b17be2e5ba1890bfb484805c82a912e9046eb9c2b563ba9fb48bdc9b95bb9276f3d906cca8c89439c8659ba84d672e283890c468cb33877aaff06af640a9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = pass +expected_ciphertext = ca97e3afc9e4c923849b77753c240917a39b0c474cdbb1c0d41b9367b3adb4ece5e93ec993d12590298d3b978d2b934723fefe4424f84227b825b1f42e1058d9edfa9fde207392d3216949b0f6088beb7c48ad234d6110e71d02dd44abd2a4d02c7b6f899cce3a5291fcb997967f1a4e3ae433e06a18287b8f9bd441912cf1f7b2c2657eb409931eb1266c5869e284bb886c69de61bdfb468dbff4884d4356acb301ad704e2c6c3db8cc58b3c50315f95e52b7b460117a6fb301c86dd5633bd11cb5a3cc8873703e9caf40cf81b51151e924567a74c9005a33bfefcdfb3247c9454fe4b2ead383f414f747731448e76938ea83674162cabb5e50a7230b03aa795ea7fa76a9d09bbef1fe34ced18398343f3ae07b3f41ee4011f02f112814ccec044d141ccac71996fd42a625be32417319031fcc1b9ea402b76ebcc9289e887aef0bed9f18d732455bfd5ba0feedabdd31bc752782b47a930234e967fae43d7502ed1273c1582fddd81e20d618605f3c72d196b3e1b0d78d4191557d457f1452687d7f5790b3b4acd0b689ed5414b747b7452a17b07202677a5557efc2b346c5c66f5cd57de02c21e55aa0664e14f105d417cc4b4915b5dc00c12838f5d4d593b121f0f40e7a5939ec83f6722b5e0a48740d2d801b8c1fcc7a9f6bbfbebd470573cd5911730efe9a0a6e5fa66f401ddb8fc2c5bbea98f02914a6d0c55751f83d2945a09293e6f07c7483588cbe64e8d948b6c263f34ad8e8352534f97db7fed06704a6647015f6b8cd1c7e7a8a9eeb582da8de50336b7c3f18c8c75bfc1494cb5c296490262de97e3ef100aa559545d8182b0b4d619b7274298b7820e75df66a47074f9f4e40b835af1dc11b9ead78ba8c3339b98a29c64670895016d1a6cb294348bafcd380b292d7e9d28eb6bc83b6af0118fccb8e6bf2a14c1ad6fa666dbefdc3b5658761ccc6e960f7d08a9600d140a71b8ab47ea85ccbaf180a9b3fc478146c3435557adfe33af31faaffa7967a7dc888f72cc00b67fae7d9a3baac1a70a849d557a4790e1f64a2eefcb1b86baefeef4452527cf1368cb3db04c4d0ab14 +expected_shared_secret = 2faf2dd50be618b025cd2b53365221f5258e175e4a445cf053c66b3d3a998c8a + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = 05192fbd776ea2338c7aa35efcc6a7d3281c50e1521186b785d020868b5052a10288321f363986f6dc5d28033d8e0553d9768241734561416fb1f8cbf623ccb3b74263492cc0d3c086b448073804e3a1aa93d5b1a22b9e02360297791c700a1ddb6880b9413840a828c06c4b5c69a4ae68a8069431f35b9174020e61758ee5eb6e337888bd563e1ff6c05cf568738c2683c50ba4713cab600c55b362f2a3a0907159a30a97054bab56655c273897d168cd41519a3db96c0128803342058e385c802aa7dcb60544921584821b491a4aff9155d2118bc9357bf6e78faee87606941a82129e6a401c15f41ab886b0c262a662c27e7deac9192cce0740ac47481744ca938b901cf83771946c6edec63cb99b1817f5ad4c4285e1ab6c0186463c3318a5a923cddac59a7991bf4279a1324671153def59af647aa7cd454d532a4ace3c01e040789d867d8230095df9c5ae64b1f470660a753cc56aaee948228e7b31e5d50217bc034f351fc1264512b58c6a206b5f844f881c0c833bc78df4c936c49247374590146763404441a4377a105431663394ca183f22789eb9bb96d73a0211b5db155a304584b3fc56ec2c7edf7235ac284021c5771d760edd4abd556800f61c65a263306ea81dac64321fd869e1a369a8594d9b219c26e754e1334269e4aac5fb0424d9c3faea7c0b384006ac250796a8d919ae8cf88d63f848b31c0269a58ffff9ce6f436ed877c33ee72efb5695f9e9c422dab87c6b92f3aaa3333688f5241cc996052f7a27387b6d8cca70fd1273b6473d0501b4155719dbbc464747702de4b45d3c4f0e3a8fb4826752f3bfbaa08f97804f021acdc37887f69060afbc3bebf3818bd064c4fc04cc35658c60be55dab57aa810c98ca49b790871f1a5bcf235192646c8e7b84a24185bc6c4b679586e6c9002e0767aa47b8b23905ce0bceee95f84a1a529185a72a80a95d30bdd74b4a664a0c0864ef0a557938c8e02b92a5de767a27c14d4b4269e22b1e70a869767b1486513809b1b6ad0acf683963da5248296cf1c71295529c9889546b7519212742e86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = pass +expected_ciphertext = 15d65ce4761f9b6294605daa078df2844415581b516941f7e0324ee9b9da5e209977921e082d18663bcffad0ef1bd0ef4e3de0f929865083d2644abb88a9adc869a65d6feff6a71161b6e5339795cea275ad40909bf7c5a443294a854c63c98924e1f41b0b1936b8ef3747b5c5345cb4fc84422f7058d3f2faaafd18597c9667a3563604f732d3610daae54d9a015aa0c8b86f6cef4476afb389d0b0c0584df617f60c64204ce0fea4732d7465a8e56f5e734785f71b5076521abbf6adaf2a91a064d3f1e0e0cdbe4366435fc4eed4a63be380febbb2865040919abcf06707e18830db6338790f2930b7d941365349d93606796a2eb85a83abafc4b1fbf610f948f0f941be153e0bc91938dd4fd9277bd2db0f53550f2925af336e037266ddd6975cb14fe752a468a5188509dfe54384715556f24d0db3d8d56d13011c58429473df2fc305c03d2a92088e7936946170d6c35d9c7d4139686919af847e2e4073e981644af3889df5cbe922c96a8627b15645d1908678a561d9ce0c7fdd2c1c4f9a02c22461301bce73ae43dc2456cad2bbfc0b45b8a73dab6bf0e59a29c362af6c89f3972b55791472d446f52f7b6b905708fbfd3a5cd59366876f6f94d59cd1e9a009acbc3369123eb11722acfb0c586e9844d397f9e55448834318e051dc69db03a58fac094a641717f3d12eda91354397bd8892a99abd8b241bd4ae09f0d84f8cdf23db8992576596533b3859113bcba8dc9f904f4455aa041877cfedcd950853d672f4d5fb041f30ae623b4a5a1b03f584e115a36f3b94924bbba2bc5a9f4510111c1b2bee8610b578bbcedff2f1e34c7f10026dde18bbca59645dcc586170d3e0c18d33a008263cac232f96a12da8c41a811b8ff8dc3fe13cae77718c079f929b20907c78afe647baa5b1d6690be1379bf03f27bf605053d371a660eeb7bd2c4ac84220df35737baf07a81cc1c1e2d7a3cfba06da738956ffe77c3d456b6116cd048f2d7d2f491a285ee367a3c36bcd1b57cf0469611e91a0cb0b59b7ca6983c74486e77a65d3cd35901a1097104e32d3a8bcfe812cbc41dcf48369aee4 +expected_shared_secret = cd890d2eee7f747441ca9448c7192bcc274e8b0c3c80005cb6fdb4691186d85d + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = df624bf2996f55293fe31b0704145a4a92534116109e3c0b8f904db4dc70f4ac96c1572248640d73dbb88db3861d108d368b30086cbc72ab177e1bc48431afdf3208df342ddf802787e385d5344e02c49192d105ac0c78c95253ab90cefd870fde5c5315821ddbe82cc1c267bb797492409603c8536640285d396a53c61632e227ae209622725e4cdc5768e96bf3f42e81b6afe853c7fc8381b4aa6070f2371e00619d685973dac323a1513200ac6826b6bfeb9c053508160700ef6238efc37bd5ac12ed744714b45db77ca4fb998745a6012ee042142cc29f9161c72c86f7cb7e834749e647a30a078de01311d908add39b062018bbc81c96b74aa702d4a40e7a596a9720b08496d2f3a990337a1a4396c291c390e1c4cd685dc9a635e7c69f7ca82eebe24356200268c118410706983a49134c2d96365fba38b992967de41ba6a91640857c020ed955a1228e5a44c91eac6a3a6710457baa88d4bf072c32d458b333345f9f6cba68e9a4086516f0641bb311c72d72ca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74b60886a19df5ab7d2f2a8390e44491901dc2b58d327453ae306530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4b81709da8191e2a2201c9e6fb973f7142622fc95d9876d4cd893a8f27db619515b476a1560949db5a893a675e0259e98625f46aa41fb0a4436410591470025305a01fac275d8cae99a5e06561c94e01262c8b878081852d86ad4270bee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912a50c08d17254788b0264933215c74c9ca4de4262ef880571078ec2695f80277e934208c8cac7528205ab523ac08cb8d29a314242606677a8b18616f9a3ae1b4856537831cca23447718edbb056f8f9b746f14d3b466a1c4419c3c155df08960047524a7b39ec3c5778837f0ecb8f49d03204ba6a41710b07f8589667c769b26a66472ab8217c19f2b3037929f8364c09821e80bb1b5b1c2d0078692fb01a9448cd60a59db56cb96b5694fc7b7abb48a23b8a12ff327a5419342577c19d30b0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = pass +expected_ciphertext = 583d94dd417b8f213c5ed3218bcada4238e632f9705b422680163c81c972f35d447bee75f03b29c364001f44b20f7a18ca86c369df7ce42253e26875c878e4fad2621a033df9635cc8858bbe773608962bcf1215841bcde2eaa7ade1de9fe76810b3487803485b5afba5c4efba4c5ebed878be42b46cacabcfad286ae5c94efad920ab525d5f391f7b0389fe9e24a30c94a0408f6af2fd2ccc0a36c7282a6068616bab9f05ab72c23c25fb5e513a694d0cc1e7a590d2a4e4c2970dd7aa8b48a0042779e1be2415e3f711550e2f02144869c3e57bb3653044736f40fa5c990b1a075c58d30d98e3af49424c7fd72768e029b04f06c4aa7f78426ef953c910cde469c6a9da510f32de2543710a54efcabf758ea0bb53815a6cfaf0cd64feb643de1a60d95969c20673785bfef17a84297afc872779c9a8ef94c63a6d388adf7e02b8cca1be32aae50e6af16cac23aa3aac347e2ee2c43f241191c87cc45abdb535505f66c2a329751d81496ab9f5e9c1baa949f414168957d39808277e6053dffa3d1c705fec93a5110740eba84dd5dce5c8c619be9fdbb1809932ab141b6d7c8bb22322256f25ef6da180701c9d09215dd4da7e755316a0ec3de523e9191352baeb100e0f42a60d495e00e7341eea2cf819f2f42ae1b12e469821d8bdd7f88c820e0372f86af8d89df5d43dd63ae36bcbc0a42e897b2643ded9312143ba5a0c01076274b216737073fbcaf52d9bf8df7440a428242d126c22b00a407dc5e5ace18f18dbb73fdfd4ea7fc4838f7e4d019a58d76b0990ab47ca380551f25a2deb87147ad5880b802a9dc39d614adc2dc6bf35a426ef3a7e1e54c956b061b266b574eb900a1559c8aee07797f9a084b94c1302ef963692fb365168fe0086695cf7aef879e7b5e78d48901213f4794ef8a732fbb5ad836c6b057ca07362886b8b6abff739700ef7e7d6adf53fc2be6f621cc457bf744694f5f7c320a066d0df27e556c695c4433d480a559cea09a5d5d3c34cad6e35e4cae6c7740eee1c09d5d8fe3cb8bc9ccb80b0f2189fbd39454e0f9493932506028cddb42b41fdfdf958f1983f +expected_shared_secret = e7942359dfb015d5022b790b5e777a93a5963260ae352567d3fb7e27b2ef0bab + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = 65a217f49001f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e0a1688182f35446c1e972a2f923c66d2c15bd0534d0b2f418c50e0d81bf309a002c100c55040c6e6b5433a5d47d2bdcbe84823c939c3f76a681982075c90c4c712d1399a0d82c6cf713e5fb28d0ee6368cd4a708508de1530ee89cc53e8b7df748b91ae45bf2a849748a3a54695b3453975082a39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680aff2a80c4c1a07647fc5e8b87b59c8bf97c235f0a56ce2a1b7608d6445b907f4b261dc55cca76a85dc8400895b4a4c03e7e65675f5479fb4cb535240fecc628c180337635af6ac6366c8a778d84980ba659f8482785b5b6fbb1a265a99012a41d5d13cfe07c7bd82cddcc98449d0a2663a468fe9591b0450707a95538bb1c22393f7813e68719a2c11ad8e311402885a54588bfc47c9fab18218bc49c87397be532c0127302089ceaa97102bb2cb219901ebabc69ad1764bb6cb5e7553810b923be76796406994587bd8a0c4216662651b2e8787bfb6b15b98e26481559cd3002c2a03bf0d53467de01bde0bac05e968ae266678bc6945c182d1d66018cc7762ecbb10012208c3cbf3d7671a98388a30b990a4674a8b7c6f958eab221d3e58579e521922abc0b0879b825c9d64791671fc6fe752bf49f87b606580d62c8a17d85a927976daa50ee54a0d186c6c48f61f6955b8afaa1fbc805a53e22ff192161d2850093816d7235d134623d3d4bf20479aef39699426642ac1c084ac43d8657559f817ebb31901f2ac308421a0ea975a4023221080b786049c89a6c451ac076a80e87192d8d8b19a6083b689b128f90afe044d16663fd2ba1ed717c17d5c06ced28446c88f30dc8d89db3d5c531f6d6b63d5d535ffe2671a625d97254223f68e89279198296db0c0917dc338b1b5b33e60210457970aa2c2caca854b07937ae6cca428b8c4dc96029c57ec309ae6e306b077aa1d8baf3df17110207b73d056550aa7ef171b4eab2e8f7990429141c7c518299733b734cfff884aaad95e55b4a65776256d5540a057baa7450574f1266a3091d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = pass +expected_ciphertext = 6e4059a833118a1b89450531c1c5a9523539a64deb37910815554057f870927dde17a903e3a41ca3a2ba75372a78584ef2cc03fe630ea5f77586e76876ea1f48a1b2478198de60933beebf57158c64de5ba3cd14cbbe35c368561d686cb264544569659cabd15db5b2448ff3231508df4ea379e84f83ac166b94343d3de5c0709d243bd507478fcf330aca5c795571b21320c042719765032621a37c38116c4ec7b0772067f7c0d54d49c9a2e50d42f96a348c034d5fd11011f1748a7b479dc5bea123a3f0d7495c5a5ef948512c3c61e53bd7d087d8c2d8a94575ab04974fe8e9d77bfd593ee0c0feec1f9f74f3ed6a5cf57880ab5699a460d3c19183744eda429010451c0c7a95d721f3ce32f36f2ab850a425c0936b909db7d709a7375cd6759204774d724febf578915417486dfa7fd654b31fe26f90c8d5d49a3199fcff707a5e39e2bd41518a0ce39724a541e142b2019295c70ec0911289116124480a178f1b0527d4eb6040dc862916b454b20104fc7d497b9e751a3832bccfce92e8ace8421988f9a177e4598f19df8348b187aee744ec623294c7efa0ba1684c100265c179e183fae81829621e062d7ceae2cb6891e1485d7f445f72e68846274e5befb9807b8f1c3461912e1f1f6986896015e7ec54c12f7c56f76de4c30aca932d9368023e929c338d504ef7c8c8110adfa29651508477b2c1e1b49eba441333342ff8322b632b5eb067cdda030ab061a5144edf85e0992ee48ea8c4a820367aabc482aeb184348fceea8d183cd029bff843f2aab52bb08092b55b06506cccf5c00530076b027475f6db5c12fbc171bebce17a6e1708f19924d1e06e192f48d36f8b87067121a6f0312750de6175b0f70c70ecc6c1651b237db6a520201a61c17874db3d4dc023e4138342498813bd08470cd834877bf1e92557f5d50f9b050539e6a3163b00c53c5340844643da03ab3884fa84de493e6754ee573bd49640d72aa1561ac29f4c6011824917dfc8b89bd4f8045939b5fb07cf6b06cfca0e9634d895a6bcddd6327c89e73f7c390f562ae5187fa72aea4ec737f3cf0969923d374 +expected_shared_secret = 5d7b6ecaadbae69fbaa9e004634ea609df6ec80801bbe73671f4e52169cc9683 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 6e1b8a3ba66274e66d3990a19fd84badcb9816036919f23c61077d12d85eb2058bb4b3369a040c5e61573d70c590669f0d394135e30570dab863488a66c1744a165c2e31144ada7b351083890a3d10077f2e556d0271134fd78d570a2fed451572d4197dd90fa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a3c154728080f0e4b910310ce1c948007990df2108b4544354f92a1fa6685ac203c11a58eebb3523b47349fc2ccd19b33c522ddc60cb97671ad011c150a29b51249158d5a131d3583196c828912e7b15572db019904a548e0967c91a684f4965bb3b3e8c008bf8531f98286c005b27a01b7ab2c13ea2c50133c3431db1c66a0b83bb92302fd7948938b4e87c7ad2f430c6516872474185d804c3b8ca891b95f5d0893cf20b90635c84aa260a48aa7b9b3c14130d77e3994e952cf52843069a42a5c285db221d4f492e152c03a51270a35738f51aca012560f84a238da294f2a17bb36bcadac68baa40b110d78966f6bc77b8930bd708a74704549560fc59769399793c26253e67bf4acb629138c277f7826cc00bbdd61dd3b97c2f8277696387196950e1e53b3cf40164c32162416308761e72756c2dac0af7945dce06571a5bafc1968d25a6628b766bc99a5d43c219161ba16a20c5b2075a62d18710dab472550edd2229f8428717b58ddfaa67025c3e0ad97657b20d3be467db6752747961713971d5cbbe287937c12872d305a128f05a53e56b43292c7ce2c2a360381a8610f1a0cef2cba93359c06b3c74e9fb4165f187376a55fff7ab9fe872c9121008579a877099581458713a0683a9425d6072c6b813048649a9f5caa4c606c1ca2f79299feb0ac1b277cebdd82a2396a02b272b4ad196d457838a262be3918dd3db84d7d821ff3aca89450478e8c10997628f9ab23fdb0077997a8ed5b26773377f7a466a69ab4e10b2d93899c66c900fc585391805aee1677695cdbe264158816755f69515d1c3d76046d18c18e07300fff2bf6776cc7ee87000815ca4e83967bc37d366b9ccf74870a678cef2b13a7636d1d311dfd5a37aeb14a3c51c9087b00a2911caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = pass +expected_ciphertext = 5ead2d871610c05553a64024ab82356e63260499ea33a44c47580c7d2fe200565a8ed1ec0f320f855a37b5e2bdf47015c18eff5356a9e172b47dd0adba7a263d73e013f1fe8919b9696b2f5be8bf3ebe97c3f348337892914434a2ed9250ea8c7c90b126cdb2f87d323a98f160c3fd829c086862e77225919f1bf1177cdd51df07906ccb277293163dee1cae366f625de9c534d798809515e0c53a34c3e961784c9b5b552f7d323be6f97e9d532ebd26a4e3169922ffbf39fe12d0e8f409ebe1b8fbf1a8489e32017e00cfab878f2418b1556415179b1377418b53f25c7bf4ad8d38ff83b4c476fc88e6736d4a5fcfa39921d1de65631542238abeab7302695c9776830766a73d0f815b03d832a10b2f2a76bb674b242684d158c658e0684268850b874cf0db2f774b5e6fced825fd369219284890ef92b0ce3bf649d1d897810ac8d17417dd54df3c884824b13a2b256fc363515a103aad47d3085ee1f52a71d4372ab3eff8cde8da2fa74d15af1a84a0eaa052a9fab407aec1f0060ec2bcd1eafa30f9b61c97ab1ab67e948f406d490c977221774198d084fbc626d190d45da4f2952f3191851f51cc0837f8f3274ff34deca842f32bc3fbd54790fc2451a1e8bc7579f631717e97c06be8d61ffbdf7d92bfbfbf52fb93690b5ce1ad3b13b6cd2843b31015597156741d0a15985910218f5912d88338f00ef7e21d42be8b188349e952dc9f1f0f3969806a962a1aed65c8ed0374f4e5d5ea53c99b753924882f072398585c79265c37ef4f19d59125e5639430b072e0b349ffa6911e8d1df2c44202f3aa24445e58296a50fd6c775026ee6b6cf820c26429808242dca5617b125b2ba693c3fbdd672739c7c620624428557ea4d0dea046aa554f1529ab014448a9b1b27207d6590944f5d83fd6cf71a1f8448879b200f764f47bda6f1b785b2976dff1a503e8a6c3e558062455bf3ab98139d2eb429a97da61357c7ca657ca14b681c88fbbf7ae541f493e7fa89eaa30d703cbbb86384f9c96d87848504bd8bd36d708a224b71cda1266b2fe7f68ae5115af37b1e59ae02167a2cd3e82a9c5 +expected_shared_secret = 547666f6c72c97a8f06fbd7cda4279165dc82489aba2119416e0dc46795bc464 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 8cc33e478b0946e4646e934c7bfaac517294c2a75357f1028b8c32e1314cd097471f15b35707a28951bfdc88590d464750a6c7b5b62c4218bf9c152e30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1ffc00e93475ac669be33808079b2b5e230f838a8b003d77b97672844639f8b7042ae6343f681fb1f77f3c11970ce715b8033ce11c9089c9b79e9470b9b64f4feba92067988297be29413c609a3e245866dc0079ac61a61ba1c90542ce965750f2b57a02d19f59719af9191e62a1b64579bc6bc5b1b353a050d913eb8117c525b8e2a417743c9eb8e589776b885c465e4d02a51ed7072d69c8912ab6493bba5fd186836623dd635d8121ac8b97772b671d76d983c513a45e4068c6636f6f1c1b21647ed762a3fb31615e781134075dd3969366527922868605459a6202428c3b94497978429b7e1bd2384e1154bce5396f71ac49aca4c426cacd1c66c0a19918104e1e6ac72018bfb18019b9dcc75a020c14e35b3e7759487b089a45aab9773125f61455465c19a062ec90954429adca61a62d20114127312dd52903604f943ba8f3e0583341844500ccd7e06403a95328e02bd3ea6bf3b721c2049360930602611f5e9a06a795a4b1a8b8d8fa7845a12d1dd44d9d67971ad0ad0b3280b9f996d3770890582af9757360e7208c8b9766c8c673db52c22cb6e167191d11900df3b2190230f01437bdd8145ce232a1737eecab8b2ca1489d427ac74426dcd39e12a8b510a0b6eae269aa4a0f46724045792a27d7cc343459914a490a170ba0c27e1405639da5141673b8e9606cce509d353abef9b7c96c2249dad3320cd189060662c11069b36b1c75e561fc3a20631862a9b531c41683c30b7879e0c03c49b8e26c7bb59a2bf16950cb7c5eb326481a9161691859932c430e66c1d998a1be066648c569698285695c08d004586408360bb8954f195cc5198fbbe3c16a32c72ea0b577914f5590bf189833b9d38f27433d406a88876ba754d86f4d9bace1665f42092129995fdb3b790a89a2f1fcce9c2048b986c8bf16b5cfb5b4f3d21f4ae84b5057c1ad5922bf15209eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = pass +expected_ciphertext = 3de423a447032c7491d31a02eff8be53b289e2e744f301b962ff2781fabf8d90df9f04874361f7fa7b3046de234606ab863f9bd2a63a4074846126b9de7fe2ea6ef048b9d5d3f79398d6aab2f308347291cb8749fb4b642bbb7b4008801c6d1a513ce97de8d674595f19fd4a0335509af86909990001f256bf72baf0c650d8338629d0819e558e7e2499118013ec2337ed91f71495183956e3b8727300b0a1317e9b277357bc761600aee930671e8475fec90fc6a978a2b83cb1e0546955cbe21c14c9ea83631989a52f42f823f955f3bcbaa3d62b72ce441dd6c7f666aaa1020838f7268b98f392bcacc9c7a97e629f9af67cc7bbf2b8df9225c835a5e177766d8bfe67205a90261360963809dcae2d9c847097d0b6a69f0e251814656d84add3d9d7bf54322eea86818526439b4f719721baa2c0568f9a60c7401789b96320140581f18eb326c42ddc63043a7f0c2f8988d7e87c4d85b20db82638e36117d019dc3768260cfd25501b22a3e9fe68085842d9ebe1c10b29d3e67200440e76cd014ecab987c7b587b939d63eca26f45156b88f22fb6e8ab60984a6d2687f9d835c981c86ab34f429bdfa617935e558bd717aac6855239f8c4bf550169acaab015efe104e3cd0c64642af9ef019a01ccd0cd4015317569cac48675370332e385a1a6ba218ded34e2d674e39af443bd79ebf8109af1ad9b06f3126c88bb0513caabe06495b6a618abbe3cf06daac2a629586c1e59380f682d181e92f6d2c025c29bbd9b63e867b5d899ea2843dd6b66342e023508e7cf667dca6ccffd4a2e79a4b30274a82bed3998a4a207782e39a5aa8728b5a226297945b2e8c3171d892a051f18f219e8b6af979e93664c886b925ba158834d82a75db6e4a330d77c8d92a7ac0b67c6cd71c94356c51a63f5d1c812410c3b45aba6466b9fe5043bd84ff80fe3d5cddaf52febf32bf2ec79f66bf1f7682c4371188ba89bf599561bd454d7322681a88988ff8dbe44ad08d420fe7251cfcc0623395f09203c6e3de22a429a51e0d89b9a20447e60ee8392810862f49775405f41dc919145dae208eac80486410 +expected_shared_secret = 88c80381cde3db2c1d40aedf8cf923b79b18cf76efe0e46edc3e25e17c7cd8c6 + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = a764b9e7abb0be68520a095bca8946289731b5d068114acb1209507e9b20831bcdb2b2b6610c0031f89f6d408003ba57398b5d4bda4479134350994a8190cc1ec6b8ea0905cd38772789c9873a4cb6606e6a591410125786d7140778975c472077e42416d3223d69ac98320de4a1bb45761f04178fb63c92c71b24ff8056844455a45a37969b4231123483b341ff6652e7666ede163e9b614313012fcfdaca544b99cf922de994cf6de08799586bc5810c5c1c54882b935c52046921963865c0b82b5466e29eae6a62fb1792f4e1035308aa5ae81aaa524533ea7a000d7a128cb83bd0587138c73d66b17c585f7037be9c0089e6572f2f68c5ba09a532326419b3c19346267d8887dab82fb0176062f4c6e6707ec2ab7448215e895908d82cceaed528ba75114c7609e0b6b4e27b9b14bb8adaf0413d354f00d33409d5a185d1b95c58b7a86caf903c1de1ab16aa2054c13849edd469899780c34b8c423a27483abcf4c53b4bf2210f602aee904d2dd879054b69247b05f3b86f00a1113dfa29d47bb006a2b1fe8a540021541f412d307433ce71362f639fe39912fc0a6ae4a33ab4b07cedd1813d0009b784bdbb209a58d66ede34bbfb939c09abc80d6c71c550953494c99881a1f874791031a8ee2bc7760cbf75d82bee11668be002255b7a0309527d63bd3707a692bc3d3c927e0a406e852a7215c1850dc9aa9b17af5dc71fe9c57dd5dacb26f95478613c878b7694d74be742c282991dae15267cac6d2bd0b2d2c469bf391efd470a19d59a6db65710ac98905520c863927ec80bbee88513d70d009370d6b04af5ea49e6263d034228644307fb407c4617b8b7977c8f2c8bdab888940c2b1e157193830def0804d58b8f380316f60a3c26e27581d03351237cbf85ce4252c92c19c7a842201826cf698a074044b9b8132236ab6852718e09e033e009a1e8dbaa6ce98a81fa6371407fc2619e5aaccb94f1c8fa18236570abdbc217a0489be14aaecaba1c631b76c5a996d4bb842bbcce6798255d7365fed744865267da794cfa97ba6c7927474647a6c952a68954369297e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = pass +expected_ciphertext = 4e9dd9f50c039ff75f9b9340310a43a920849cf1e23cd46548010b2fd4ed0752687f956f9bffb4099d03366ab92117a49183512bdc028a781a1ecae340de7c87e6d8efd1eb994d91db17e15e52eb1160b287e5de0bd4aabc140d0b30910358846f520c6944f1a0ba6a57b23724218805d6dab6f0e828b3bf6090ef05d0eb7b93d18eccf19f2571ab467643107bcd2db2276ceb90df30df458e946c82fb960367e0b0a86838a4b155e0d5026e19bf43cef7826aa67302fcabc38899ff6226894aa4730a3a54886d7541e1d7c994cc31e097b3e32f7a1b3cd4c8d349088efb1bcbd60f029429bb686c1a01bfa80e53c6fedf2c462dc573d1f6ee97047a3f0c53ce4c6efd2c7980d8923e70e0b00eca1ee09408affd0b06d9aff7df0e0f81aabb1f1ea477ef2758738bf7cbd6a97cd52f543028b00f16c50b87ffe53d17de0590e6fef5f1ceb223a96ef5afd4bda3e699d28e3cefd84ae069d4a6e652124749ce3e0e3244c97f9844904a26ce6170b37427b4df556b36f31d63f83e400fe28d7a0a018c9ab23ad45802c8fcda36b2f22ca60c5ad3577255b98698412dd5c0e0fca267ebfd0875dba2ae286aec6d955cbb104f80837966a600ca019200e00380689c6cdae7f58fbba574e0a5f26fbaf302ec310c1a53488e2592b2b8d8077c3daaddefd9c73faa2de7f1c2be2896c3635846146df679216332050a3f6564f8861863a336970005312cf06c14c81ef3d9a8b9e53adc27662f25cf014bcf02dfd121a0d98cf7c7a988523f5b98c336dceaef7ff831c0c329d479a7fef21ebf1a6ee39ce801315a38e3722b970968799d72f9446aa0ca103c0d59466e9224e6d55227796bf641139b119d1e616bd811a6744b8f489e146e18f8ac6b18c44b6960aa2a4a0d63a38b107fae88840df3e2439bfee676ee690066d157556e763852a6d6f6ef9028aea80c356a5b4c615ff59ff04b9a06ee788cb3584d096719374da82131ab0960e7d2018ac0b14dd0c89e77a11b5d3df3d5a4a8a9c4da834060cda8130fd4a69ed6bde96209e88eb531578ad9a1ae9580fbd5f05354d1f569388d3427f789 +expected_shared_secret = ccda9f28bb09dc0017a1df8e1796a3489c66afd2c3898a39027c843cf022b790 + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 5722c4c5abc6ba118828263017d56e8fc3871b503a8517a0e3b8bd8192746e211a1a09923b761b20695f6a3ca01eb62e7f6b5302f54b8de33fe02b8fcf9c16e7c552977735139877c95bc69bc704fe94c0333115d7ea091fb41c146c07f487961c83b1b18225e91449c961769a7bb434a93da88531a75c207044a46623acb8342d59d1455dc434e2d2bfa5c30b9807789856b76d3a4c65d642fe65827eb7040290c21f2228e40251680aa7aa106a4e150d3226b030407d293929c20bb1afba5187b1c4a300749a323168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439c30850b68f20d860ba262c992c99c2bc37eee195d2e945c1d6336c990a77e9af68eb8932eb3325e362db5a77980274aa3b699be212db904e49e326fd445e48354b1609c0942735dc6480c53bca3c8857fcd90965f61d4de0509891272d31a51f3528fb17acaf669efc1032a4240f097118697842d79239b16313a6f74aba689aac94936a35a21331961397029a823d443244f49a445527b039ec8547c35e83fc2d076225d72b7634fabe64a103283434de705bba284fd2241a7e161435c896e899579caa2cba03c53ef74ba3cb30adb80b94bc407159a5d3b35f85b3ba3491c85b4379cf6472310335dcb0cff3006bbb5c8c37e3a1b758518d4c740ab5358cf8ab6cd92542a79a97dc4498734c8c9c36baaab29472a9cb633ce5d30039bb53b03978c51402fea962b70506642b5f6242345746abc312b6625a96443111a2c78d674a755554266c5089e23c9b63ea4b255890f577bc5a442066a2c448771629b542d2981093e49961f8a87a93c068e25167483872d378c2445f398796970c92b4b42aaaa65771382b53d8c79a0258cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d61a0614f1436e3623a77d38abcbb780059521ac7148c088a89b916a0103f477a15a68489d5f63cd7c84132aab6bc63a5dd30b8f27c835a738f1f619efb31509cc9205a4716b64a3cac7725b79c8c2d304ff4a60b328013fe6cb99d94496b363d03c1a278532780fca35473a000291d8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = pass +expected_ciphertext = 04770373466d1566c3feba571a52b23b743a851c40c59610cc7a6851bca9b83e69bda93360e0d900da2b5ffc34607b1d26bc75cfd8e2d5cb0fa77303b50ee9b0eb4bb55e262a937bc69fbf0a1c800a3d52cab542c63810e496122c11d8e2d2415221522ca95359638c57786f184d093d61e5a3f31bdad6a86aa7084b565a93d059216cb7901cd4705e3f14400e5d5e40a18140c032cdcd64691985bb9bf09ee6c9693a95a345cb405f792c2bd73f3adc17b004ee475cc5721aca4af6030c7fe9185998bcf0972bd6b5a940132c360604ac04ffa25104f9333feef6eb11a13b7c46f67332becb386f58db8714708653653044f40d01cf561997c98789570a9d882c77b5f8db73c366ff5207985326c92c12d8f02de5382f80e9be096206c5d9dad8c68c2d0a6a13dd4174cfc96b34d5fdda384a5e2eecbd4124af20e0a72a042596ba0d02eb199df52d087ae8bf18eb484d6d3b3994d9fc63185b7a5d3be0196c91c9b92957045eaa0192b95ea263d106028dbeba6f42d8465901eaa4ff42768c314deed73737d4a1eb21b511cf17626b92a75914140d820465320be487dd7d6be1399ea1576102b41531c2603173764931c98fdfc3a498f57d977f9e13339951d7f59406d532a46e4c76f185a17b3b3746d887db5341d5619b435543892ba2e68712b583fba2793c217fbf9e417616f4ab924f86d616cbc5d9ab0c303be54bbf0a080ce3f4549e94f55997e528318d9502d6af2cbc09c13227a39284166f258be87783d5c2f593fe956b16c24ba17728586b3cfb8632a057d683ed9cfbe8f19bf7fdea7d73b5fa3297ccdd538c9cf207efdd45a70758184fb8a43d0761e83141e0db44367529e3ac59dcc76d6c13bda70f56635d26a993f04eaba5e351ed12bf736f52608591fc2315cef1f618d31bf15361401045b38d66db05e700ee41ea1f17de9e1855bf965dc4e6a12eed15afe2ad30fee124db9a64eb3abc2c5057fe95e0ce5111042230f825179a751f65c8bfd6f6e3f04fb77dc98d62f75c72db05388f2d2b9b0cb63245cc0f29418736591b72ba1554ef99f5bd8a56fc5eaaff5f27 +expected_shared_secret = caea7e78e6f80e126a9f41ddc0ae5946a80cdf617635934b22c9097c5090ce59 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = 44d99657b40036ba1462e34b668715c8ca2a84b4c5b7e81d11e4acd7c6ae77a7a7e6193b5c8143a45b997dd291d3b08840cc4765b8b4f8c7caa7158f2b939cd273362c9302af3c59b2a08dd545ad119c0522fc60aee902f6a6b49778ba17a97a47b2018e14336cc1cbdf49b90698551059bca80506a4c8533d791bdaaaaa638571398ac85256740aaa5bf4bb35da6b3b6f514a7e364935e769137a300e9811355a9097492ce020aabbc0cfd8398792651f82b887b0d13c3e9c5632029a1670b3f8c8437b09a8cfd6b8482bad74347144661b0cf297fef2bf91ac607ec7b77ed308ac430abe56c69b668cd6201f329875f6454aeb73540e3c0f0816cd7f2b372daab8b3ec1718d362f97c5a05b35964707b4a7558ea1276fa837e4d90be1b19ae05cc7b948a32d1018f14844e1cc3b79fd631d8166d1fc072e538429ab1b09f8a0ac879143f514ed31931878191a0c203b5e69b30d40734904c1bd9ceead909136593b9c51402e5cf0917c3c9541cdfd95fa66018784ac144c610b4182a69a08cbd43cecbb8baeecca48de3ca5d21ce58a69a96ac65778cc9a5dacd663a632e63b1a4e71b012846f0c6c26b728902f64baeeb6718163cba1ac63447cad9d63eeae21855776dee780d1b6443753235f4330edc889094241930c27fac186f46428a60180d239008fcab21ad162f903a7a0984489f8a9d10840f2171734536b67a329174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9cc129e4bce6a519947d17caadc8f3caa6a5b10bf98a526ee0653af3b214b652dce4b3ff3d2c1ca4b3b2f751e3af095d4128b57c46c8a89a1de5b805ffb20d0300e6ae5c57f562fdf493562e1bb5ac0bdd35b8395889f6c7037ed636e56c1aa661289052952ebf386150bb03eda1616478a1dc43f50fb1edbb63968945e05d09d1d320b335433b701caef733a47bcb0e62bcec0e68cd6da26dde55c53d5a289284a7e6b1c239a092c0841c6e7a8292041a04b842bfc8f2430a632d55568a58282018d55876bc8e90bd1686b61d7ceba6b500ce628dce8a5dcd13cf76c81ffa1afe352c6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = pass +expected_ciphertext = 942678a054e276d2543728786e8254fecdbd37a6724521ef40252f1aa2de44973537ce77b212460e448798f197ce133d934f49e18c6a5647b4f846f41ac82045f37bcb1f0e62253c757d251ad3a138b012f7ec3fd7c88f22f8c723a553e371a37131f5ac50183ac462a03fba3b22bd9a0af9ff2eac360670c3991b63fcdbca7a3334817e13b05ab842879e682568d14b2080874aaaa07b77dad8f55703d6d78d49d0e293f59f58b0b8fbe2f29f46f33544687a8c66a2d30f66c0766efc4753ed53a816d04786b36562c001cc39b88e9c4ec4c86d3b09b1ab9a927f22254117777bf8d7236c47c35d0acf8f63f34468a6abfe8c213085e8cffe758065a9bf378a2b1e3fe30fb8c6cf35aad2a8743c53fcb067683d1f67b73a8b48d1cfaaf03755d55b7c3fea0e2617138c333834db6e48fa68332185de4d8a164832f51ccdea2ae602e9c04cdfaa5acbf14739367ad9788559424dde2c9ce5d9b2a1b63de89ad33afa0da0336ab877f2ea73c2f05582889a3fc60fb8fdeb3a5caf023d362e9756a9416b24f8b740e44277c717da14cf0b2c4084c3875b473729f5981928ed839c7d36e51f0b91f345d08b3c9ee1fbf88d638a40695c378cf3b75368b09c1a5ba13a3aace3a4b41774d20a6b766b2be0b086854b965b14a75704a6e0dfe6035c5bee41b89c1b6bcfe23696305ef9d1585678fb1456f3ca44d937cbc4ea7c2ecde196ea2912eed17113b510b63ab32d415ad08e2e0239b986ad9828f0c04993605ff677b17e8ab5925be654999135d33a627d79f108eb5d6be3704b032c1ab1df3de825795bafced52859a5b1a4e64c9bf783abd20a09d320541ae120caea755b793f0b112efdae0c47532f1182ac59f6243ce6b4330aab60c704a8649a24aff47aa1a651b338c6cc87b2d81fa75506202579d59e057ecda1d2efc5c8a4f1f29083dd3b85e7fac6b56dfae8a0e19fee07b3e54da6835cc290ecfc734b5fb9903403aeee16eaf8f61ee317394d39b91a4e3208c1fc50c4d8ea66a71bbbf5cd24e7ead5617bb905ab96cfb02f363b92891044f9ecbf2ea00e833bcd560b9e3dd095bf +expected_shared_secret = 431bba421ea89647d815a16f440d47f1604b67d9a2d33f2dcd21dae7e65bd5ce + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 945762aa4b7684d18022bb247f593d00f4956c728f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcc3269622355b436610412cfd92458cc5703fe2b01cb3a395927be19c8067a793bca615cea3c2ea55cf10c0cbdd94577331939e6b7332d849ac501750411223d143dc953d648152005a323df711009b81614a657487abd5476bd5d71827ca1b5ba45e9c268c6f826e9263adfd716cdb842d4f31b2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f0590b41661b3936950009c1423153c96351db064a794cb345e3c46abb00b061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345c524ba1a1345d052ae176bf16370dfbdbbeb906996eb41fad306a9153c0e8d98128a82231d73a878a8117529f8ff85be6cca6166cc5b0503134ab298c066c62260df091a15f598311815f3503965695586ba134847b3ada551b62072d03d468360150d0b17ceaf0a1496070778c7a75593acbab2baa4c888bb99d9ebaa34f8b02c27ac7ace0a15ca73905d9582b8137a223bca48b42ebf28d4360b01cd25d644a6f7e831e155928e971627c3c52a9b015e5d8a86a790ff785c653ca920151ab662c3fcbb18af3b9ca27f6c0cae82161eb940fd45555d71fa801bdcf418c5e9879fb33b675d5a27e5b45a4e2a20916c83a1bcedaabc0ac0666b4a2b403f05daea6906e773ee9eb3ff9441c06f86634f01d1c93788a08b76b15be95b296d407a9ea500d89b191c1c68b7d85763d1c2d2633277af163596a7ec257bdaae2a510b8282976bf25936a6e380a778939ee2b44bb1054669a2c5c06c77e712bf2a5b6aa405a1408b5fd2573ef231e2169c165727ee1a19b4c6343f2038537da304909c1cf81862e9676f1e26d7f48748488cd9ab64bbe3167b442719a304500d8c72128cbea470942289fc35c1fe32ccc07361bb1591e43e5a4f9076b7d416e5d2325fe0413a0a88984b048292758fcd080b5f5378d6c508927cfea478be3f68015b12cc1b05b47791ce7ca8c1a98cffea637807931a863b2cba011c8d8c35db81bbac79c5d05171be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = pass +expected_ciphertext = c2f9eac5b635499b944781e09115b12f434ce57cf24b2443d96d071090bc3c4375b9f427a1dbd55c3a0b7540799b311b1d7d64dafeadfd6c7e0418aa9ad342acf67aa6643c29edfabca90cefe4e7e73ed8aa7c73527b84fb149ae33ca1aa10c800add234cdfc458b8c7e98a3465d3290ab4d6b2c6c32a037de59b2261002f940d0150441d5316814b315a394ed4b22f9a8f05e323827e537e13a22739eb9a79ba72162d6858d791cb27429efa0794cc9b918d8a91b282ad9ab35a064ee1a064146a7b3737a31d24aaf2523c0cd4804e5215c4dcb008bbfb4a092013058460336b1db62cc1f7f5e66b7ab7e07a217bb8e2fe7d98adef0358e2abea21daa6d2951bd407cbe012c4c65f0103d9dfd76dbb2ae263b32200734e7217d5cb875f9f470283b777eab38d78e3afcf1b04a1b895986d409a11a7366262a4febdbc2c4009a0e19a311945f9eddb564f0c3b7a68fc0b3a874e45f5bdb30e0aa988143c389a8c8e83cd7028a79194628515c5c521f9b995051aa72a5f6952b6bd087a5e3b3094969e7e64038c895773702582ee8f4827a2ad5567c422ae0d2e155a6ff28c20a24edefad54f358b11a621b010a87beb347c49e8ef7f19c780396f0f13e4603b2920b5ed63d0d2e082bb8fe9d454deb9c9db4e481f8a5591512237c81a6f1ae56b63ce4b6e05c2c46a08ee685986a241431c84180896fb9336b3c62e2b9ec3e27d1d46d6cf28cf21b78fea500de3f77ab2b839abd4a2b1a71947795a0ec31053f4953a31e1759ad3428e6c3b3245b8c49054e237eb22840d0d4a26f540d1efa572cdc19d10f2f2425a05f0dd7f05db66667f9a784228134d50b509237e9422c2bc37b4e8701891028457b084e8e9e89e303d79b456625cedc9b227d693544dc1d26ccd1bb36ff51ae8ec6ce934a8d99c3d6c40e631e730bb993db83ed79fb1c1246a244da68dc093727f586dfc3e39373ad513ca0c1b29ceab5054e3657143c183727c8f06df9ae9059f3a8ad75d2517da7e8ab52e01eb486efc8e14bbd22eb9ccb92b5e839fd893fc74e257a85f56bbb8251144e6d9fb10e79e5e26362838e2d +expected_shared_secret = cc0a7809cf6787a4587e090249709f694b709ec8475a42b4705bd1ba312c098e + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = 00d6638044335765803648b2c7583d29185714c06345c8002f97a0b35641a2457c1f843d3ff637faa04dad093733811f2b143257c37b2f75bbe8a81b107443d071be7ff5c8a89548cdc1b11e20c41e1a6c5ddc57d7e72c8e17a5cd82a60b6c8136bc3b526187fc8774f9c316d9b7c2a9b41f676ab6f53b7e436194dc2cbd8ea324e8701d5dd171b4c20054c87970258fdf259f575a71145b1421667a16812933d645bccc8af72266d55184b1375bdcb15d87b5c1a9b4c0e4f34526194754358de8d655104241d2a30c6021c9d3e727d933147385b3f416b2418924e3369df7652debd6a3b0c457fc28cd88355bb1702d802c0e39773896ecb120a75c171069838888b5cb788990a349b44d5e85712ca91ac8a20e2f03a3c119ccccd37dc783175485be3dca1515723ff2aa14d77a216eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824a7072511b1709a4221b7526da8602cbf11dedc601ba492fde8a5d3bc27c458bb1b994432a61a7a4e333608207fdd700ecb8781887a6fe02702df120f30bab2b30c28cec7d86447371c6a5e99a1c171b64827229527c48b8e343005a58818bc8b9b9be2125aae9ca2d640701b5b204ded33d2cda34ae77134eda9fc2db12b5b12742fb4b4b8a22d8d75cb1f83df409ccdd486303202637a99cc613035ef54257a27ade904e88c13c91e42e841107be386c7ad228459298e01a1cd4151d64064666dbc954e921a408975ab6814752045324a3a9f41f322153e2dc1c8255a5e63280fc2210c52176a4c93cdc9693bfdc73156aa319582e8cd092a0e28a1a8148c13a14fbbc745f5644439905119b44405a27ce9ca446872927e06ebeb11c8fb39ed407042bb2308b90379566a18a32b7ecdb6f832c392bf205edeab45bf0110af1aac076c417923f80ca059f34101d87234b7a288374b2ca0a88950bc722a01ee4e7be48a81fe732998f536ceee8540323ae08f49217ea880de4431bfb74cc80cab0b89f327a28eb9ba932b523907164dc82c961343088002d10f02ac2647a3a532d5cd796abe16115724d37122431a57b1e9b2071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = pass +expected_ciphertext = 0f7175b0a6290fc998515f4604b69ecfcbc7c13d74d59e83ad8adf658736ffc9abf4eb7346bcfc7b038943b37fd1cb8dbb0390e0f42f1940d7ab3d1aa09ef8a4a424eaa75e92b8390f07c1b6bb7f8be764d39955d56d9465aecf075019620d042bcd89a8b957a938cbc9f550170aba5a0b60abbf6ac60a923076a08743564f06a3660d94c27c14870ffd744b788510c12484e2c21840bdb1144197fe29b6923460d6248721f95ad1542c43dd3155d9c8ea37f1419f93f615aa3baf4875c3a4e079c0c83deb91167d9e639c42838ebf72356c021181820675084a90d12e4cec6ffda46a1af2fb5305a925f66222dc9188e8954c510c7f45bd0392243d33d26b41d9db25b3766090a23db02736a6fd5edd84727a7817ea433dd6d3c787f4d928855beffca3c6ef6cb62991b68a27eadb3f6f556856142ec0561d116ee36292f6b03b00ca0d45ec4b95a2f2707e05219d06502e9ffd92e3d2d617c9e4a02d16a1ffebfe80a00f855c4547559f504428e6e0c69383adf03bbb4e2e9aa61c6082147320231bb09075942b1d73812647d3b8fdcb388b9b3088c4e596d72e6abcf6b38420fe7fb10d924287b21561ffdaed70aa8cecd73ba7acc084309106542dfc9ceaf1f180bed5ddc88bc3fcafa30b748eba8050f8c462cb430fa810248dcb2c3cce1902a40fd0143db9527ae34715d2ce124f2186f1c785fcdd67a4977c471ff5063d184453f9f2e4a07548a989bf3d7cdb21ebe5f8f1d701020b71278e6f5e0018e4478228a268860924f856d7677c8cf76e5b3bac29fecc9d1ae363c0abee737149b965962f7135a31f82f2ffe84d69ecd94ccf111e0c8e019da5c2761d9852649b783ba9c9fde2364a0e8e21f14d6f42586e1f08d235731ce0dc19619c2840488c570d528b953b412354d2c43b37d66ffaaedc48d908f3d2db276265118c1a1982eb024956294d97226561952f6704064705569b5c4bc96d15b3e84ec3046d379e4ab044e90d68d94b6c0e1434ebd3616dba4067085410aba01ac424b3f3ac81c9b9d399d069935d75157fb469abe37331a49ecf86d76d723f551dc57dea9921 +expected_shared_secret = cf21da86b3e09c38ce5799637b1492a1a268dbf0ac716499c68bac11a774f41c + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = d9f893e986491d219b6070ae339c3114e1a64d6c61353411ba2008ea358749866018c802d3dcb05b0c5329a691f57303c0d724fb2a1121d264374aab2eb209412941f7e39eaedabadba71494863f79e34eda632c1da77ebca6283311310f4918c69c6c5036a47aecb3b2433e8991b8d0bab01626034be96f31a41d98c1a2d3354f47e87b9053033b82a6a8f6b167e827cb1c11ebf4758af8c70fa98dc1f35b353c54b5552a0f37257367bc43e263e8a23284b0982ce8a6951a4ae5924d74e3481a4bc141f0a85e90c06e97ae64183c0f469dbdcb081de093ddfbaf9d4318a24615f8a38d1477132aa5c322934d5e92c89acb29aa85292c7971e61c89ab484e69976a57c2181ed5450260c05fd957163c0269e9a3aae27114a5395e398cbc198f65b46bc2108150b40493532d63a35f1882583fd16d5de1bf0a7a9c82d9717bac5e31a15baec1afcd94a352c01dcd73ad51852d618490ee5993dc617e0526556304095657274a738bd4620e80280c828c17d31892fd174a4fd8302d705cf738126c352899026d8795c9afec77f39c87f1567120e70d9211b73daa813497397c0abdbeb7124f942df311067a0ac03fd3c3e8641f202765026b7fc5511754481bc8f227e362cbbce579037c4ccac5564c015318e598cfcb538f1558a1b55e4bb61c372caf23c2a1eba52e7acc5a05f129a469bed6688788c2c68c72b75ca413b7496f3c2505eed19bb2962d82436c16c29db904b76ce5626da57bebd05bfe838725052d1103202e563de581151bba7d46e1cfafd50389a730c9a3c56d88030bd397a9d54af0e763249cad1cb0427580853b3572e705bee6f1bb1f4232f6ec2aec3059d777209dfb32710b9fbef71203f5a1eb11507ecb98e5e4cd384124531490e48a0bcd39be19e21c424c726dbc1900ebbc1bf155256a03a89b3d0537b4e00988447ca3c02a65aaa2ad5be40825d207fa683b9d915a6a5a1e8fe20b0cba4ea14378fb759e1a064ad93b6e5ad712be3551c9d4a4b0819eb7420a4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = pass +expected_ciphertext = 5474f5beeed244e5f164e61c630737d0428d8da9a6e8b55216d9b4f346d34eec261c465a58a9a51d0699934786671e3d52ac72eaf85a346d295f2a4b9e4757edf889b8424e485643de3f2aa5cd93a3b7c1a5378c1132eb4d0ef096fd33fcc6255aff0aaf219ad8b36e9f0c201964a28affa693201c54bf75f0b9b3a9f636a86a19560857153a3ba7bdbd0bbdc034666828e26d090c324e343d5968ca97fefc86a5e905b0135a2463ea25dc67a5b200a50b13f850a5b00eaa424bbf0abb2a627322134d90be38edf7f505b9abb4d49ec7fe8e28599d7c3c75d8a7026a3210187a4cf6e3b4f1374f18bf2cf1d624986c34c4a959bccb3d44b0af3ee25a3bea6b2cc288aeab479a33c62cdd7f0207e7345b2e790a2f2ba25ba5bcdfa1127a397d8cb3ed5d5cb75f3c8554289e91ab9a3d944e365cf97449b26305b58f120b01999633cb39f7653d0afec9cab3da916f773d6d218c0e184fbd24642ceeb73cdf5c68e3b065667eb6785d98dffb150a7c5c96a903e8b86fde7e9284737bc33863ed0881e79c0b98ff9ee93ca54a7fc5937460f1b20d0ae8216c1ca4a5ab2c04906e2164a4a9e344f6d4c82c8dabfa4226540e33b27cbac44715af571d4c48f2d8b24f62a593adeb4d57a49360edec07cb3cffa0cafcc79ec1d89c93544b85a103bd508b264fe59b8047f21da862b2af375fb4029986b58ef79740bc4fe3777ee9f0a680818870a1a7e3b38ba7982028d85e24c37ca2cfe7e92b4a1a705a1eed968390ef12cfa14d6a96a11ca17b26ca83372dafc217149b40377d41668845ef7d14f90d5ddde801c2ce862a7f014e0767aff25819f3e7003b9f274fbb3b42709824138a081606d8900d77cb575ab1d923898af507305bd9f34d21c553443b518f21e562e0bc35e62dfd11dd7cd42116204feed69bf6b6a64117183e5c2b08fc689cdb3a2e6d30a4482de2bf2da1c6bd0dae710fe191892189dcb78394281f57b742fde61bfaf975c00e125399480345b0358644d94e01a5e0f1b88816f630b817a2ce30ead5bd892fc905974975f84205e2a79c9fa02d25cb62b1485487c6a2100f0d +expected_shared_secret = b56f557eb758ae10d22b5d65847cd811475b96f5a46b0ed3bc2f1b9b371fef0f + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 87b3281828644ffa865c43bf25ca3ee561118497bb2c1a04c50b89ecb6b8f173ac78c0380153b55d551492a95f8013b28d38710ee7b0b3f75cb0307e22f1986b65c9a890bdc7846e71b926eefc4814b255a428cb4de94313da24a17973e5d679ab44057e664217a54f6b16219be642fcd16b35952f0d2a37f37692b34c3639e9400a15c245986134aaa3e0219b98383cfa7223acc31b5a05060bc1523d32c01239c9df8338d8fb2f998634bf71187b3c458d155b01dcbc20a7558d6196b7e0b0fff5c856077853206dde97268da274fadb80ac727555e156ef640c2582c4358aa8cb78a55275393de19792ca0f6f030e2495cf1d169e3b327a2cc17fb87bac4fb92f603c93658c2135322b58a4bbdcc95e56f66104807637d4232fa3868af473355860f9850ea5b61391a8c20537ad23367097b1911efa5f74767ce9b1516936a11327623d371e8d64a753785d09f09157697a48902d4121673e2b904aa94d845a5f17e90bbb60b81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e91822857f40fe1f2c818700d26b882e58a3efde1793ac428d9fa8a94f62ba9fb16ab867a146cc1c7c0a0d45a32dd074a4ba52232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097380d17a6f6369a5dc55616950918b245be7a1a3656ff4075acd957e1df062218bc84887b74da635d9011bc02824603007e9cc594387771ab84f7bd065c741185fac84096aaddebca179355dc365516efa4873e70159e28c714a4e1149befb0a18ad6098d5115419dc4779400f8259c7cadabd41a7a270e5c91a616e5cd0b05976979967baf943b592917befaca4d6827a4a545fdf584b8a48b6fdacb1de775bd259b083693947a31d91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a3d235b870896a558a5fb2ccd7d13885969d2037bee23b3db1025be64b3a5feb95da076019b65685186a445bb2387aad029b9df7f1bc5081a7423c267978c295f2653c785293d65406004806db9f98a8a7d12ba7b87b8032e0cbe218413da907641593ee627831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = pass +expected_ciphertext = 45ead8f635b0a55577e4ab9ad95a454cf7f790bc4bf6ad467a959271156c623fbf3d28189956f4e954bae7058d892d7112934ce536f5d39c69cec5b4f8969d470e63d11c929271782d53969c5b3bc9a21b6fe9c711aedbeb37e4a054303fcd14c88f1d9686077564b164ad0f226a75166b1d9f565d0ba003ae3457c9fe7184ecc97fef220c0ccb52eb174f91e79be2af19d97a30b5af8ec0e6fbbe9b96545612fbc60a83a0c484d4385c222f8e126bc6339412059efc649995de93f891782f39e15374bc40c912cab6745ca8cf2ea0571ec5b4d64527ba97f5c1de81bd4de11fa3d5ecd703d2fcfe3cc073f24d6c40d58c6ca482ccbfff2aa86f430c60e155c8497508b54be5ece269197f50a71ec6713a59bd3c8c224a072cbe5c556332e561e8ff3c1dfb96b09239803f4a637409ea35e7020a83c5530f8b8722efcb6cc3e57837a4b98c6ba10b855673b8d271e0e5f08f178f18777fce80a667e2030fdff1c5fcfb0bf566d06022a980df4a8de2e91f8b4bab58628a70b1be0fcace47c9580bc866e9641265bf1ebe8be9fba7ffd4eafbd62e68f81c1067a4e75ccf6ef5cdd8f18fa8e54ba051ae976b5ed66c4662c9e5e0017c8eea63d82b1dd3a8d7f0224497a4ab7acfb3ea2dc6e2d8048b69082fb9edba6c5e3fcb2f43c25d6077d7dbd5d4da018f0cd1a5d612cb9d139dff309d445eb2c3364b50e98ecb9c96c23bfcbbaec80c6306e0453d7f470302eaf456aeea78a8cf25a9eba87a30900630d53cd9fff2413e7da06eeb119c67270117ed8de87f0c9b9ba2e8652a838d036e5fd815b5f502372b60769223faa504d3f4add01472332d01cf6d95518a8a2cd93b6fdb4e4eda53fdb554c3d91ee4c4bec7bff23f4a9cba2f2723b79f8dc71b521576e6f6111ad0c3d50bf00f9dd1040f4028d9b3a92cb4816360c055918d40529045c68f31090b9f2d92c7586232241cdd4e6fbd492de375fce0da6eb1072228342bc5402bfd63b517f69f62dc7ec0c6c90dcff4676bd95030659077899e5dcc0d9a4c53ad7c1d14cedfc0b25c0d537dda3252aad4d453e1b8b4ac56a10e9a816b92 +expected_shared_secret = aec1264f12ddd2ee8e51b71d703ca5c2718dbd79858240635f9b076c749a5ffb + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = ddec85c013cc70746f2b268d16f48db17616367981940214020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fb715428542f5e49b6d5c762ceb26c2520863bf025421a29f854bb52b3a5decb8a5bb7ad23101a254b89fdd95afce255eac087651a588e8caa2d5512cad48c9041a7c6f06dffd86341e62935a6ae0d4907cb3a6e4e223cb754c15e2c88d4e13cede42a636724568a1f4507adc8d0bdafc91178d260c262224ec8a176ea573e69c057c491d1234e4f39a2f6c4283a40c70223539697890cc5cd935ab8fea89a0ac513cb12c83bf6be1de55788f8a434001b7233cd3fe859c3eb3ab0d15067422a5fe1acc2286f59b75111672a3ea24515f9157835ba868a6219d2a10e72703ed6b066c036d118bef4598d76d08010967305199e3f46cdfc41ae1565bace1c52bcc89628a84f8b74252566917d440718a48226b4bb2f29c0e7743fc2fc5a3252b93053c0bd1285abf907601b93c83399b104b8b2c06ecb1cacf37059016683d2d08376111f4ed13a3204701271abded98bbcf5141b12b9455687e66abff877aafd507d01395e7da932a2e386947b015e3896d2a38214443d169b565fe8cda1c305fa668ad7d57987ba95a4e8a8e047a6039159f9c94b6e896679c325d2298a2896b256f528ee7b114d0101adc255c893530bec9d1ad397c6776ef185487e6140f2749af802cc1ed60069585d316959b2bca22e224adac5b54d0655c0939f3e29c864d087fafab871a29ad82c5533b40f67d672a16581c3d05aaeab3cdb0636c938c575c611095504fd200b61293ae1ab3c8895b6eaa64d26617afc82c6821a5b1ae4830c526777f1b9d6bb271c48128098925d607d507c9c7382cd2267c4ed7c6e4320372dd88bd5a9a50737663998934b70017386784867c5b9b11aac66c1ac3bb1793cc02df88e54a41a3db8603af791af157665b88b0b9a075f5a805223754a2005c81ac211967a43d7bf625069d098058df21abab95ca1e57d2d6583cff926eab06aa139a3da3b9bca10c9de93ba6c6346e76a88a8e1288deb6832603b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = pass +expected_ciphertext = 2b3aa8988eb65bb1d5c86a3e8163033c7e0f3f9d924e64d260986b74f9a66675ed4fe8c786ddd11eeca0118eb7634501d8a85747d1f8a6b0e2c5c7379bf8ccb6ed35bea047f69c1a09280d0895695c08e6c2fa800d1ff2959ff66a9d425adbcdea825f7bdcfe74cd05b28d4c5f58eb66f825c93e63d998892c52604d14ca32b9f8dfadce0777fbb0d580fecc137476e85500bd909c79a94bcd8b54525dd3e7e4bef4addd1816a873e52a259a42097cdc95b7447fa53a5d0244ef610cb540dc745f78043cbaae20e02262476a21e1319ea75663ebec5960ea56834432a7cbb77ae51d60e3b339e37b2503f78fb14a6b8acef650e27807090c42908ebfddeadc1dd9b27ff1d471f6945b1176bf7260632a5ec6fadaaba637a1e43759cfcb48e5286b164839511020a4c22982b840a7fdec615f7df56bf468b3da925eb05ca7b71ebf67d4a8f07e71f6735f5f03de4e00e3f58b4aa745f421584f59d41a4e5da32980c3d5c58ac9eb22909ea6fe22fe16ce01e0cf5babbcb86719312ed8df46db9ac480cf3408a6f11c45f71a0913596749ebce97edffb095ed16191b9ad1914ea56a3f0ee7d2a2b7e12aade6f6399b9e273c4775544c5fe559485259af1f601f7d9cfffe9d89145aa0567155c1c2f75c83eae156d560aa6fc28e4a309a04d1d723f15b922580adbd4a790d56a0baf32c8d2443ba4358bdee22426a78ebe7580879c3ffe565dbd5b5f1e9a987f37129a255cffeac0d8c1edc65f5c6e1498a0ed9a59c2a9416f2ba0a395a338a4057149665a4c3f0754bb4abade8cb80c3ee101046d05f279624736853693ee9f86b2c237fe2a6efba216949e99a0bc4bc0302c08ebc39437333d536129dbf56b2592e681f10c61fb14a1e50111966e2990080bb6abd9d54abbb442252cf5194d6c907a394378e6998fddc4839caa0ac137cc8233f6ba92fe82dfb1de8a4b1866eab8cc360ccea3ab0493b6bef2c0cf267cbae519c0cc48a40e86a27f400d0629abe01615261ff55643772d990325108ad9142e13d64ef5295c88e00923dc9e4b535f97e6d4862a78ba80517509c05e729215573a7 +expected_shared_secret = 6514a3b97760070116c64014c5695df60d0345b29ada92fe24b672586f5bf06e + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = f839cd5b3685e864c874197e1bf074d30c41bfe01fb82085c8f5c43a26343aaa9184a095beeb6e01753dc7da7482f2199dd798d17660c5ccbad047978bf0a62d3b9ddcd92487f9103f00adc8fc9ca566a9331790bf93a1599cb3daa229f5ba8d2e33a8c7451130e17c9d4c91ba2cb187495c9a9a9916700e4f8551a4f8793a6c7e85327012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8b51fef740b0abb7ef3bbc8dc00599f711b47a4c858798a76494ed5f01796c43688339db7c40d06cc7d205b5a6aa3278f561cfda647f8961da7966efd47b433650ca5405770f5742b919c81356d0dd2a87b21bb9dda76d0b330891952c81c5d84761476063b452a6503f7565d406fb60b56cc14a9734a297283b2601536fcea5a67c42ead903d22b672d4828a93e2a321fac920771c1d038ab40075771a9f0ee97929c69143808578d114c5366fd0b7abda8a7ed521bded7bc6e231057988c362c5befee06895f89b2637c2866bcbba39b152651d5bd912344a9b68145e2ac69adb853d06f513e108105f65622ee25750595a4bf983aaf45921454e70a06ca392a78eec70fd5685b83a0532f4aecc8a09c2468fb2037f73fba689b82f590891bc087cca35772596410969569060a5d5ea0ae34b0be06ca8df188cc458cbff21615b1a4e0259925cb3012105aa50b494b35a45d4e9312038866dd4131fc4578674273e182d7a1a1bd049076d70aeee016a6c1c520d2bc404eb4fb28918f1990024d579175082ea9795f0616e584b2c7f93ab33944401c7bf7ee64040a3336ca5906e89cf406512539c8579f078d957a2f4b625f90561be79bb59244b0537a41fa0202072aa760a0e34e94fa751a49d68602d97c807b9992dd637c652563f7317084946703171db7262f71737518c52082966f96cc386e30bb6f89d02b93f8db8b9713580c7c62c06963a18681a1fa54a20d774e40c0abb98a6da5a148377a264d0cb705710f3f708955b16e8eb22754b26522519ba833fcc3000db88030546298b610451b50a247885e6321fbec37b2572a246e181dcf97b3003727141194337a108a2280d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = pass +expected_ciphertext = 29d525077b2e5a2be67d74f27b2bf8045773ccb65e871518dc134d6236a14f0ad4f22301b3f9857f08eaafbdf3aeb67b19cb6229fbeda1c6da308c1db7df054d94051b1707404da9da700ca4afcba759b2fa27db62794ab19220a9148abc2a2232b16bad89b9af0996a672bb5cc218262a088da32884d1db98490b1fc57efdd6540c06f43e90edccdec19cad00de68622676e68f40b72bf179e900d0734ccd0411ab3a0ae82ae5961b63931b1aa2ba42298b4fecf9b3022da59928c7a2e2c450f94cf1b25f9c7da70102da7be1a1e07858a56f4db2a15b2e878b80f8b3c4b71b6841d96e7e46123f771dacab0c529758856fb6ffa288a037294987344e9a984767885a413a65839be8e5571a3562ac42076ac70c27d4d65ae047b9951e63ff890e3474e309fa24b9f281f8e250fa0d24c193d9e8c865039c6d3c3e9ea18ad2157ce17293784ecbf5948b7a0612c04bf05431eda24516f9ec56e13b6727cb3321a2b9dd456e5e92adba02900590e083c55eb8710d19c7133caaf0dad8f563b61913c2dd3d3dc9244a113537d61f97f7ef7a0554bbaf2011442026a84e4cb81a3d39b144fb91c736e55e1742feb117979da0fca764440ede26797987c2e43d6d7c06c26b3f347e58e90bc37e36402ca8e003581283a1c63e96bf9a37db9279dfba5e8e839c1c2f72015ad781133c436d95f9722e033d83f46ee5a0714e64d959620a386e8ca52894bc54879d672e870662e284451005db72601b71e95ef64c9c36526f1f9da5ffe1fe9376f9c6a53210e557c6454f22ad4b2bf7d90c92f6847181717df0bc270287543ac3ac69c16776c65336869015c2d912dc101589b068ad7e7dcc7957a839c652046f73e85348c4b842cd074a33e8b5b2caf2d3440f650c29241873c2a86e3b7910add04e4dc38c0c0fa7f0adcd4a4d5738441ecf7879827c14cc71e781f28d505238e3223182ddf194f05f06888092e8e964603f9923d82ce9b10218c618613b2470dde0dc11bbd36251db27b5ceca9aa0eed3bb8878ec119525ebbfc4c83c0c7185bb309ddfff96f36caf7701a1c0c3d32c1552300c6f48 +expected_shared_secret = 52344e5e173fc6088c9dc555cc90d8e5de19bdfa0d657ad8de1a3c24ea679bb3 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 1ea1cd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856560e0688f75c96b524fd60bbfb40c18533b11d3f6b24069c5303cbe3e6558f376b71da5161c6310ae651eb0c9a8dfaa2c265b85478c59a7b3519cf95176768d048018e8a24be09bc99f6a459f9cca9600aa8625bec4a76959d157371b2abf19130a6540f2f69821aa161da542861955ddfb729a95841845635bd208ab5a7b85527c01f811a98aafade122ebe57cbc89c5ab551c6645bb40b36026b0b10b40b7e645cb571b664faa9d06270a1902549c507b33a568da51a1a7322b53b95b92158dcad6b85e07adf6042f843a06318b7fdaca35867910b0db0e09d03ae54c22b580c33594b85361788dd12764729b54f92b74dca45a973872b00412da2d83eb12d8c51627c4be48955d8eb67b54eb1879479803b30479b59c578c175448525c514b9e685b3ce751b035836b229012709c679c1bb710b947a27ccf07261d639314c2b1d52a77de2c9c2230761ff5254714af940ab4af7ba85c627a1a633a994752df4125ada5c86a60709f37970d771e96f01eae2b322780c3b2ec01fe086be76710f51cb4690a58be890854b7b03dc04c6f632eb56caebc393bcc70410375457af17b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa240ceb7936fb90c0673877d0635777f8c2a9a5b03d8b731e9a0fda08187b44037653bf44dba3f29074995ab3be5a59e3073e52938561fa9496b3ae0031ae0bb27a7dd67424c39f250b5f9c2512e507878438cc8b086030cc588d0c2dbcb1024167715b52130ce969785b4210da26b8a6a18606597829bb40fbbec83ccdf76913685c48817111bfc216699a9966b94590e80a0d45307c36499c006d37a83a46e12bb9fb0712961db7f33d49d633a98b7a36a3b2ad5402ca190da1766071473fb21529221559526a2e5bc5944009cf2d47075d0961721989f8800307c91e04883ceb97308ce6c03a7cc39cdcbe8723822561132b6705f54345ae1480b9fa11184c999aa8a1efd17944027e1969267973cc3456c54140b57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = pass +expected_ciphertext = 56dd54d42839f333f0a3f8626c6c1c9280110f73f8f164502bd6767bb05d63f3e8eacf81cd3fb3e6313544485c56f5d51053efea6795836680b030ceae61ac68261e606006f89e2801c8f13e092eaa6fd9d4c3eaf87c6f4d101378b0d5f23f935413abaf6c2ec9335444290f877472a33e46534dee227b0eb35adcd01d37fc524d558cf713e511f51aae290ff87077aa8a0ab9cdd0222f3a8e0f6a9ae55d8bb8f16c28115c8fec4ad18955da20c21b08a90dbcce7121ef87c5120e843590f98c3ca2005f9d6b0cc3ed8ccc303b26b79bcdc3e9277423c43761798bd884d7cf3fbf96e67bfa1f65fa07b01d5c06be5d13e5d784658193d1640a0299d62964f156d56ec7cfa0d83b553db4bf6d00de896ee643f44cefd9b01a186634a5210dab6448239efafcf0f905ccc66637ee7c7dbf017610de0e2abd25f91c592ac83531ac0bbf77709463652a7ac98f32b67c0fd6e328975ce02110c8c5d87c0eb91292efd55a597e1c76ef8c87ba517431e486d7e3667c33e621add7e36821dae9d3b5ed22d764b48f8104166379f90e246f97f55b479760a4aa5f9ad703cc3994c7a94ffb1eafe91f5f1dfdcebc5a5dde8314067d1465d424b995e4616efc1afe1960df8709ff33845f6be36ddd9bc66db2c40274bb14ed42ad096d2da00a91cefe4648ea391952bc8d7ae080438fc04221f6de6ab6f1de94f01a91aa9abd8111f3f4036ae47e97316e736f7c6a8190d36284a8255cae43febdcbe558ac088a93aafb6bda5a8098347ac38271e4dadef96397b2f0d54cc0fa1fce77b24f7f9e4927e07bc3535ef779a3e8c693e678b6714ce1b124bef5606210919ae50f1204f82029dc267710329d7a4d8681f2c41c70f287c812fc1960b021733a287f828150bf40acdf723e958c3cb3f3554850dee43d24332740e6573f4779e88900d56422e83b3341985ce10470eb6eae2d5f53ae79d2f77e32da37725e2515ed7b1030dc5f36bd13d8874b0e8f0d07d2d3b8035ff8bbff0abfa7dcc3c042acc1350c643d48598cbe7d5075078d9022e1629b5b88984fef4c05b522e644f59731b399378f6486ad +expected_shared_secret = ce80f65731c8fac072f7153bbdc425f76189d01bacee8462060c62dfeddfaf64 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = a1f21b5f97535710a214345eabd39b1fea121ca7c866981a22d06c547017d6e16aeb14a105ba22ff5b2304e10c948c0c4a376b9e5c2425920ff94953cc831ad45b3f81056b6f321d4c063f8323b0e23813a5a0873fd71d93f9af8059900c973327a048802a2585f29f9f81714a869047b0cc0f07ae4a9b5d398469c9832a7dfbb79fec3fb99c5f9910183a5651c2077f62817ff62c80c0f3ba5b89a19c8280f62b0162a87cbb2c39d98445fe49072103a63782c09e7bc3bebbb21901b081729b7db37379017453f090e5c672a1fa195c49601735c0cdf7338e0521ec0946ad2784eb1a5e138c21c8c04244d2c8e7e0a43c7551505aad3d85c9d640885ea8004fcba8e64c9da72c0ec19197732156278c3ad64282bf9590934a2806680f4e8aa14a8b030519ccf3896abc085566bc5757a467359018c79b57c149338ac2680c249b94fbadb134be1a911deb09add46ab710f930c4c24eb4298c0a05a1af583059b7724d7abb6702bb6680ce2fd3bfc73203d2a563f6d0b8ca54b0886998a449b70e256f22f7a3837263929b22e4a6c97d4141c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320b426749cc971c6735ac769c2072ee88407998399308a1a81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec325295000157857b664b548fdf9bf3924b508570b1a003cdb5158b4e61a8cc0054ecc9b42491bdb9115b8492848f0b6b236b963571ba882279ca3b6dc2532a481cd24375d8f9a199d955824a48916502beedc12c138998a14cd75190b9dcb65c5b20af7fb254b97bc412bc338a6c0b1873802884475636af09a1f222ccba2363c0b873555360325e18b2be4c33edc29e6b874eb74bb12511ab0364245f058ac90561d144ad230ba7882c893d9a73c4a03f82c5accc04031507971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13eca217b01647db07c8726418251703cfb653bc72e3a32192e489d334c53b91136d5b9794c96a8d3519467571a83e0b754b655c85a818d51014a15b03564b665a80df21264c5ab8ec8902be351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = pass +expected_ciphertext = 393a912358f736691b8e1bbfabd7a3ef373929bcd5413ec74e948c14fb4f6c03eb9b1e58430f90165cc5af167ff8b6a3f8da9d6e1d61e15e3a1d1797c53c4ec8888f06ff4f09d6037b22877092fb93f67f58c085f1dda1707a51ee4eba60291c59f027dac77bf8a70d630d8caef7a16016e7ab3865b6543ed7b413c2f2e031976a47fa9b9e4a65c8417ff7e454ff798941e5f34c57de545d5316d220d2f0f3a863c386a8632926cd5aec6e22c3743bf328cea18d0787f3fba86ed2ed70159df31db98e3e0a7cfbf604f90ed7efb99a92e8126d4fc965e67d9b4a054b130fa3db3f0ed0a98294c40d7ca6b2fe5e69046d4ce1f6ae5d55670cc1456e847ed2d7026c2d8604ed66cf146d7cc48c867d7fe1874c86ebb51c4945e2e149e7d13e0827616f502694b639378165aca5172718dac2187806556917b98bce68b91f9259fb62af2254e14e3b94af2ac7a3b8ed2f598154ef987332f82995cdf04e03768a38701ee44cbed47700091ec13150d56f72a284ab02862262a79fda8c6530ee1d4bd0487bc1dfbf27f54f51228cba703a88607c7bedd776bbac31a9457c92e6e16e44a7cda858d8f3237360885f2b68932acbc1c56e4d8b702dfde44a3b3909b825fa01e8724197862d4b15495a90dcdb1872f4e16ea0ff6496b7b57e5138bfd3170fff042410557f694257cc69e54793fce228c95523a9b7905932b4f4147c342ec54df67afa00b4aa44cc3564cb07faef73c025dde8808c7bc785c4859c6060ad33932d62a73a629863c7f821e234cfea7b3dbb166cbb7a10278311733e47b2b3de8ce818b9ba370b12eb2732ce0f824f1845d859a06fddee009b012b2bf7571e74f283dc419a5adb2f69a7867de48eee208835ff63bef8ec0b5b3cd4177f3f97bd68d770b28199815e3f2257cbf6b594c09636d2e069448450e0f492646b9a6c6efb0b206f12b5d93e0a09641d35b936f1563af0c1074c20d3c1c535ea0ade45c48f73b766b4937ea6a1e329aba02770141e6706eddcb5c639a8103810b29ee5a8167b4d45637ff6a77b6cc1aea1995703c9a498ccf81c893038a074244c3ad4 +expected_shared_secret = 3b23a3cfe57897fa9cb691ee9805739f40d2bf22930ca9ee48ebb7163cd66bb0 + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = 7ebcc6700b95f778cec6f514b10c58e323ab7f013904345308601ecf1707f8350b9f29cb39b261580c3dd2651f96e28f89ab9c1ad86cf77cb3db7aa8a05c007d0a1a93a0a83e85be418a7f141078581a5e60c25e4564691e11b5f16171564a1214d8be06c15f6281324997a98f6572adfb62612c6623d4c9cb24bcf0d896af9a16bfe000354a41f9720c53f1574f97c6e8a49886484830d5822751c6e4c94df54aba2ba767b2b3199148bf8a0a89c620866f1ba52c46687af31abc6a7b4fea9e5d6c70a5570f3d6a6113674c92173b6af4902f614f1d508b3b456c406522d986c31aacc3653098b0985ef1879b204261bba81752425d7cd549121983ffb30b17e181d2b8b4dc049f248b55a25b561aa54507141914e580684395e332225089bd29a934ce114f60936d9ab50f568362fcac1153620791d318dc735253085c8c164719b6c0b426c136a311d704d009f226fbd340ece426a25274da929bf5a206b1520bd114c754db2dab0b8a881c03aa569091f40ec3e38422c3b8d4b2c77373853e57068a591663446b17f676bbfb941abc0e1afcb01d939b426a551417acc95988d712600383063dfc5a6be917c3e4041ea5496ab68855b6caa6c92b463692ef2390ce797969715141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e163144d56a191e29c66eb75f86d6baa9e2320b43463b300000083c49a88b6338c374341cd83c1c15266fdb266e1e0933086c7358d82770aa652b7842b2b9b6f9165613d4a27298c0125a2609885d29715f9cb854cf6a0c308b36697cb1f5b530c7625694487252872c70ac1ada8b4959c681f64c46c5ccc2b3972b6188909a1955d99b65b0b80aec1770f60421cda11d7822621ab46fbba61cd0dc6df4082609105839d80ba850c0a8342be5a70d999386167ca06a485368276b4f7340cdc0a9b3010c3fc3726da1ad68043c1665b1aa4413231455078cc898d938d2c5663b1c200fc87a3b2c2b5c5b0c507c1b7f12ba711680951ac8ad9c7e430345f2f6ad3eb9317b044103a82bb03949eaf288b2377b66f629268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = pass +expected_ciphertext = 68f8faa185e730d2c069f2c19a319cdcc138ee9bba414fdcad84200063554fa1a49e182b572800af2afd4d0ff9354aa4d5520db148e31c2ba8e543964e07b2fedaf011dc760820dfd9b76b40883a69c9524a9091864c1b2bb79f568d9ad312760480f7c33b1068d89e5264b2735498afebae7ed11b7bb5474ff5bb87923ace45ef4ea7aaf65f0e383acf89c795c417434d21cd7b92ef27685871a0145fdbdfdbdc93089f999099dc060f78ca73056851aed35372119dade9b52039af2388dc3e39e612bd0a70a022a3ae486f11d39632a302a02ad0faeebedf8db52e2737b94145984d0c3866599247b65e566ec2c7cbbd18f3ab2464b75ecc9c0f0fe195e1775fc33ace93fa322060e968954045cb3dea4021ecb89df8fa965095ed8476e3e64052d2e5a72ce5fdaa36ac07a79aefa9f2ab44b31c11d9972263e9a1f04ca95b7d66ee19f97535737f50cbd379ad17e9880abb5c340ddaaa0c26e4ea60a1810dc83ad1804931294751c98d48293364bb3fb8780717e9363ec84fa3e7bc7a21849fdeca93674b2bb90cd88eed2c89b4b989d70fcf49df184fb07b158c9c3cc9e663d20f1d0a5ba555a09fa9359e18d0653be2bc2cfebbbc69aea1c64e8e0bc9b8f0cbb70d60881f86e4340278fa0b116fd36f18d40b4bb12455ea0bb1b4de65f8eedb5ffe7f206e50349ffd501708d452f9d487a9dc6474bc15f59da9a5324b465ff6c2c863184b023d79f02ad257c097f7af07f944a2f4b8ab01076f4ac40230d373538826a63e7d8b451e93e792cc5506aea14581fe1a69d5bb9e96b585967f78500e7bd9b023fc0816de2979dbfeb1d160939570296830e32bb9ea54abb7dc8c0807eb22bf2c2ee4e6b96e1f06352628e64318e5fc0a4c466df465cfe0ffba056a648f4e183dc37820b57ca7f2dac512e87c1bdbbf8b8cb8ce72d9e183a26f957203d3b91729bd1984203ff64ff6ccb5ce1acc1187e8df4435400cbc7c3723f4efe3d876c5e6748052e5af72cff11e07dd7c5e058ca40d289f4d919986015add25ac4d1dbc559bd6fda9af76e1bd7c744777cd5f5a7d7792aec92e0d406377 +expected_shared_secret = 272ecae17c3d107a8b008f60c8844ac01e09b8bee17eb4972f5f71774af2d54c + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = 1a986b25b24c36a66d747b761bb2c2a09415fed46551c6a26ab62819aa605a84c9d164b5146c6996f3a33475aa76d055ffb45617f256e22028426b71ea1404cecc96aa815f5cc804d83bba5d417caf64731906b8cdfcbfbaca0e7e0c924cd19475a88668c59f24b7b0aee4a63b936942ba263bf4533dd29e7f51760ba638702ccf6472305e5a0d404732e0a220b269affe711db0a8c2db11c2573b7c3a83b673d37ecd8a725553be79755b803cb866a90e12a4bf7d8275fc7ca07cd20ced0ac9a45c54953220d5caa8210bcb3e43289ba03c6c3a982b5b2d4b73853b1b7548f7aacbb0a4ec2bc676c55dd594aaf630ceeee7a58f076348a09fbb5b335c43535be99d552298acb1bffb30c9adf1c5fd221417874898132c00b83cb367bd79f734fa1c56cb63a8652ca5a12226961131b14018139937c20c82ae6964e0f4bf06f30cac7382bf2341829236ef27119663c1bb34819da72cf71b3faf01460b9a20440947452b52ca4bb9c4eb9cefb8c1a308b2dcb20dd88270bc71b9e95a2c96306ca17c769d301e01021775238fdc6235f89939b47774b5fb5293d2cf4875a698d33827ea2146b4c3aad66f2c918d9e638874dcc883a2399df38120b8baeb9a52b45c6d0cb2a3c766336d0ba7fbe55ca5eb203e26337d29438641bfb3a29d50500947064e65f7319854b6756b2e40c75b755ab983b52e72f9c5cb293e2aa34cf2b23ef9868278c531bf395434fb347f29c079395f70f62342fccbe37cc7fd4ba1eb49699ed30dfec751157003f8bc438381813d0c555183524ba8a248f531495210a6947ed6963da96c85af7bcb1fd8161a07c707019b67f373c4692c27279e67b677c2c4cd42b33c4662b012ba8a59b19391c25aa846814395119d65b585c39e738359a24bb0d31b266a81471ce25270d0715cac1c473c10270039489aaa70b5cf093ac930a91e9ba356d6a76fbbe8903781924487ca4cea7a67558e55011ccd4190c6ac0d8642357441545b477e0538b31230b07b17595e55340ab681fe860b21b9b893408656f920e8a5599fe94dea1b8ddc7a6eac61cc0457299c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = pass +expected_ciphertext = 762d2b975d7e97164aad923f4551dbbb99cfc44c146af6e270b3288086ce9b768dd9fd07d746a8f076d496729b50b44f972cbb53987762f76e1025741f203efbde6b0c2dee48d4aa224df0ed8ea7ffd70e80cbf50a4dfb099ee701fee01cfe50904e2f1cba82e7ef507777f0ac2d21d1a285cf8de33d59fded7793fc05b7e3ec3176b005e0e9ffa689596c04770848d7efc999007b762d824cade5b9789ecd06d1c73e7309a45805cd167516940dacffacfc9d049c4656ed397c3c5c53606cc927b5442f6ddda90c8dd89a68cefa6796d6ac5c08bd2d337720bdea8a25f0fb656c6d548a326483d6d669b1dbef7f33c26355f34b5b19b0915f7ace782168fe0a112bd4c2cf770660a421771772a53dce19635a4676d430819095b2b29f1d33d742e4d9a6b57bf8f32810bbd8c0890219fcb3c73178264f2984c74f5ba6ccdaad83804ead9ee123e86c394adae7665bc2b962cb8ea82a73b03aec1fb90c45c7d0adfff1acd946ccaeff9ae907b33d01a900b9c98ffe78f22417ccb06e8e735db8d1a9a4b055ba12b4032c19875fbb9efb074d3fd67a2701b34976ef595c8ba84b82af167ff718d14a144cb5dd593a5114d18c3cb8c2f552511def9c6c6d9baccf9cfced749ed26d675aee42deaa64dd3de0985d6eb87da959f55a55151d9b35e6125d0d297b5c70942463bee80d8fd918ce36dedf8a5f7dcdda38af8cf7e227d545b8237a690fdcb78d0fc19d42e872faedbe9b959c23fe484ab831ade77b64d488ab803b9ff82725ea57880248eb27596f9e12b33cb5ce5396158f74a3f0d83af6a8032ca0898b9e436d3e8b3406b5aa6e9de8959e2f215fe4fe444bfc56a97292eca756138556a5b4f074533b484062b0324df72ee28609b69d4992babfb15fb595fb59425f82040f0718a9d2b36154230ac7583079cbf90b52921cb882eadc643b5e601cee1d3629be8bbb5a068cd97a93d30a768a8ef0ad644eede70506c92ed70d6d5d7cf89dc642ca06a3ae69ee0e40f496bec30dae4120bed2e21d89405c062d029270f4fbc85075551858fd6ee48c62738a748593b1685b922becf11b +expected_shared_secret = eb456d8919c7e96c4e18d7a0ae27d47996e4f94c46c60b4649b327903acdc0c0 + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = b0141c2b68b888e674a38351470a3c831923aa3c3e40a2127a28c1a8818d42e4a48c036191681bcf982c0f13a79d643af1fa13eb32444d1577e0c1795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755a8199ec36c2c128c68fa5b5854348d55a1798054ab98a5203dcbcc5121300b15026c8b4d1aa329b804b13e61faaf672f0a304db82cb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b15211950b5551f0722a9b6a7ec554567b2c975af35b6b88041c01a1f182a50853998cc395c1081e0d755d0fbcaf69f85df21567a0a24474571d2f98ba93f37a0f5941fb8204b0933cf3cb20a706a06359cbba272c0df68647318774939d18528b8818ae682743071795d512b29c794cc8a6c0e4b827c1148ebe2a0e72fc50a3f71df0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58cc229d9623983564da34cb71a729abdccc3cf70bcd7d20aeb82c9d306464e132a6b9989c8561d90824f6796420e8b8c08a0bb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943181b16f747b7d04a7f6996983c494b0d527879366c3a4a6872a79c8c3aaa13f11695d36065d7843acbb04014539992ad369024f56636166990c23c661f34a584c12ba06a16aa582c887015cf96b293757a041b53ec695cb520960d959d96f57bd6da44e40024f5e04a3a135a1f112ecdd57ffe459bb22c84008d5a2ee831823b42102017f14a71b1329bddc07ef7bb02e8ba40bfc64362bc369e490675dc68a9c0b54a91b43386cc7a4800c9f60f2a562253904c71924fc7a9257b94aa9f78c6853a85d09ab7b07101b58309424420c744076c446e7e873c67d67a40cc3993d48c1a81495e54a5fb1200d497080bf21b33211e919730dad71c2a1a75ddc983853cab3cb55a3fdc0d778bccb2c42037098956307899123f7c5b7cbcf107fe1788e55c67fa65968f57bd85b53a29005c6a2c2c30ecccbf09904218390fc17f4b07aa2d350e9953705da8bec6b4048e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = pass +expected_ciphertext = 27579d6741c227497fb204ca6f32e119fa6b84377a1171b00f000527e5ce0ad46ae7c20b14b7aa32a048bfe7e491a500853568ce87fadd3a3266d389bc517a99b491329435e0b05d5b2697884528badc7cd42b91a76676a828cda05c94a497815a9f24b6d6073b1568e7ec22fbb51464ce0e78a4cb7115910f9f9c4eaac8a6cc514b4f473a5c7af3199b1296bbda4f71bf10e9001a88e4c91969859ea72340c4c1aa62d58586a9d4c03f946644407d8273dac810d9c032a890196aae72f549b0ad8bb4e15e1d8b07fe2369e104dccd4de63080466051dfdc76407ce6bf2dca8fef785fe60af4513d3f2d7753727b151fd03e9494153ea4e04c6593efd5d162b978d960499c5454cdc3da160454f6bbb64161661921607d07a716db783cc4b2c034e3f95c0ea7886a875c4f4904e29aba83095689da0519e3e9bb1d5d7edbc5ba20e266453573f9a4275f9fee4a85baf8bcedf1eaaa1abcd57169f97339100a784ce74bdb4e448dcc5d6d4566f646ffc8b03180ad0ad8afa1adb11553434293e1af8532bc87b8a7fcea9278eedfe4f92083e1b88a16ae23339cacf95b0727dc0a848739933b150d5eca063d9b6df4acdd3b70dba42c22be1ff37ded54ee50f439327d1b8e67e8a611036a5139ee2b97b3d57f28c1e0f68b976a1de23e181f68553872a5bffea7d7cce6001494b20ac48e9f645ffe5cdfb1edb93f36b33b91629eda556fc121571f6f72f86183adcfb8ba497d3b1e9f9055f0324b9128e37b2828cf99a80e4ff4155eed0a86bfc2da7250966783ef4aa91c38f2821a58f49ed947db17494c98dc32e33733223399f6cde4da72370ed8587917efcf0251c1f51099201159457e44ace6a7dbcd3ab57fc9aaf9a7eb0f3bbfede4b2e6d257fb6c7fc9ffb9ffe4b7e13cf3dd9855b233d781cb0064a00896986afe00889c40c33295c704f4a0808c44e32ee5da7701290fa5352fae93f79995ef6f89d5e061e4428aa73b10e9c4cd82c70b713d009b9847eac80e6f510e629858f2eb00f1d7eefe460cbeb4f10a7c6c508201f6bd916cb52080cb149953540e97b1b5d2365a783ce3d4 +expected_shared_secret = 3f92ab2eb867d4e2e658917fe95b19042cd768dbbcd895e83b7bfda621fc428b + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = 2fa2cee53ab17754381f14708ccbbd3a19ca2017a1637b08f2e9344ef76d5fd0ad937b027ae58787045b9da90acd172d29c02f2ea83b378690d6e694eebc39dfbbb12e13331503bccfa62b6058792c2642b365a9fc687661464768221a80d529dfd9abcb15813a4a6aa012010ec6a008419a6c8238f068671dd1b3bb3b10ba023aea01a90513518d5c6582329ae43c07a6929c3ce1740aabc291e440f909362c7c8651a64e0eb84d82448e9439351650318293010d718e8762c71dbb6cd0385c5be0c37709924bac6b6783c82431527996523ecc9bb462a1eeb0cb6276c344eac257bb4c4ab0124d6b1b7cf7473c050e9cb9762e856786ab1b5a9bcf69fc90318b3352e0481aab1b97279c088b397b419cc4cba756451e67628f535642b2d0cf71644e6a3b6f9b5409fbeb284356812d613ed338cc28babcdd4b6753f4bce7a7c54b077a5f162e96665a3299b938ca48ac0ccc7710bea5384fc4948dc1b56a1c7272bc4a3fdf53706dec2385db3767c4261e98c49164683cfb420c33cf7ed68cffea4f43e41da5ac727e87a981877e4ff12329e91ecd524790c1ab38784d89258562bcb5841ba8f0f17ab17236634a7019a520f48695ede951fe9042eba78e048791896844025a37575b2be610635ad358d0ac7ea3bb93ca4c8dbf6b566d00654f1541919650c4a88c9a19b4444a5cc7fb4ff087552fe1a288a15bb0941f71f4568ad3bd01c1991110bd2f755a9c7806ffa005803733e2e639e2da05b3fc71dd7a42e834190e4872841215454b294bf32a48c096d4476609e792a4e5465d5750aaea38d9eaba07fbb05d10950ce23256727850d97e16397e9376674c37be4fe3187c2842c797ace9475b1b42c10910270d917ab6cc42a573c51339c04c56a6b0150868a9a330620d886a5e2103248043b44e005a7344742ffab697f086526691b073aa70914b391c3cc31a83ff81a11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb07323c74a7892e5b3ed631370a65cfd4b1a4212348e54506648ccf0732a36c9b9cab979ac6c4c16b9ad0138860a392bf49490068807fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = pass +expected_ciphertext = 8db4f31b77a098ca2872b02e77df4b56649e19c41cea2e1768b444fe945613d7879febb57bbb20858f50c1a6b6e46da00969fed6e088d740b90d1cbbbfeaa04d1cbd6842a7461c05517136fd5d76bda7d246b5efe5474ea9e6789ee935991f11d17970610c211404e576d8a976ebfbf87196b0a9076eb11d02d0e7f9b8a7bd603733adecb2f16343902d3e477e1eeb6bca301799166a19dc61328f903fd7d132cd07b28bf5715ded3d073626dd69eb14db57036b176e6dff87726cd5ed04ac02f53b49107c560658191925c39a030dbc6d7e9777ff2b6d9710938f455fcf486d5abe02dbc628c1ead2d20e7b1b96f7e7f140ad331318da534708573e84d8c2190e309c68e7d89f62c986e9feb4c23575535276704ade52623074b53dd967bc40b23efa52d2caad7174b9eb16bdf3c5a396ddd494e6c4361ea12b74930cbcbbfe961410e753caee1b36e5dd9b210d6768abd092a419abd917bd5471702f678e882a848d4f9350b435c8e9217959a0e88fff18ff2b0ae6493c6ca3c2a58daf37e770c844cb210256beef3c7efe5d45c98e1b9d16e0fc334752b717fbf1f90e50123d050fcd5df3d719527b78268214ec6c2faf45beaf6707303d18d4b139891fd3bfb632b8ed27e39bb5243fda10c0e093309d22a63939b0fb266525d7fa76fb3727a325977f348262051f9dac4a0bd0169454e2eabdd5e62e2947b29e9ec6ca1389963ef104a995929df72051d7e29902fb4c92efcf2dbb03596279e775b30601cef58d875d07fec568c86ae0d2743093535ebe1d2485da2dfa010626af3ce158ad4f31f48c3735e59aac57d3d5697e842165388836f85301eff17ca0be02cc4d766a5543bbdc3b686b1498a4897747a8aa75546ab90aa6ed033d2e599a897693380056485c7f79d721236bb006f751f1080971d2968bdd380b93a56c852197d737331d0bec9b571c35031c68ed9a40d0481f331192e55ea1fc3f6252055dfaaa010ca17b3cd06d0e2a67873695695c714e57dc1cadf3a58b75dc6cb471303bd2c78284d6115b3b37cedcb7441d10d29187a6f15e26fa13a54314b3c0e44fe608 +expected_shared_secret = 5890e86b38f7fb11708a63f5e98ad65d10db5916e6669e1b0161142e6d30d017 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 8529117dcb33b7d246d122ab27cb961b63bbc579c27f644213e6825aa1a0d4b44918784e1954b469f106d6464da8db4de1eb8cab31317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f5a1443629def269cf7b98235569c1b396fa9164e2e0336cc8babadb160b082ba8edb209a426b25c435c35c0bc9b15af0d541d0ea5514ea354b828eb3772ba1ab1c81768a1e286ce2a01d1b900dd1ea9fc6d685f1095efc105b71571ae967bd9f9a02028729bbcb53c6a74b37950ef023b334241d2555845e882de3636cdfd45a76e1265f6937130016f8e1710b748959a8add626cb79b65de177c06ba2cd8dd759d86baf1d9b85f4da3b2ea9049ef9545b72cc0a6a736d5581c57a1d7d966f88c578dae60438292cb3ac26909baac0ec8d74471d511bc7e928b67913c17e4cc26818b2f301299da3910458be4bab41d3137cae0189225890ae91a364dbb683288b8d59b6619bb786dcc98a51910fac5c65e05b3c75a4185b99e00acf009535adc07c269aabec98adb1195ab0b5a623d448fa454e90c2a6be925ac912b086b31616337661d0a6ea7154e937a39d1a60a4b7923f4b2e88438386ec879196cc47d9179d382546168a36865246f07b86e48f3629c5b1bb99c62098d800cf2654acc6fb8057d25cd2d48c2cb71ef0e917bf106f99b35df1830d62226a1f7220be6c1afb229982067439934bd27b56171ac3cde09e2c1b3dcbda08c386355f328dc9d01827ea271a43651bba49a5a66f01966cca037fcf02aa074a7059d69de85961c9120e6d89349ada3af4d41175a6267aacc9637b8cf4d513a8f6b3ebcc9319c25064b337c0e90a88193e79a9810d2ba9b0eb089e437f473b9f5dc4b8eb95b24e1b85c5d0267da39bdf35831c1263fe923a2dc7bd54a5210e38203422a6dde30ff9c59325d36e99973e3e991b4284c06f673751bbc8c99b04c4990610dc2906b27369b72187aa2a13791cdcd47bfb37a19e149a32f8cadd638ac0e071771c9dfc58253a864c0e15cca60514f545cbe161030af806872ca2d0c67f54e04b4ca55f41a54b1de405a22ba275a1b919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = pass +expected_ciphertext = 0d815ea0442fdb719a6b4405d510615c107546c0bde2ddba35109d2ed7eb3383162cb686055c8abf2f2c28c1496c01f88dbb89a1e09dc3a92a618d6a039741e5f979ef5dcec8f1e34835662f0d263a5320084f4798da555d9e3478d75400ea55b90b44ca66c57feb23c7b7e057cbd3ff380587c7c6432e3d2edf1b82dd3cfa8a49b989d0346ae7963e4b6a67c3b85bd3f207561e3d3493929d9614b9892814e5bf988d3d6566404590442dcb7e9e1e738f9002e279f640c9a62f092c7b01d6ef86ab0f45e502553f013abee01a1f6fca018bb04698c78dac494c6f545246647ee370973430d0e59eb8ec9b8e98af04fec8dc4ccb4824cafd1dfc45ae9dc53cc869ee426dd4cd20e0e0b554af5eaca43361d85d50e02465db2b4633d6ce241e08859848ea555e3c84a1196076a091d262bc353cfc28899abe749d57d4b674c10b6826f01c6bb33468329b7954ab05482971635a388374758edc6baf439f7ad489809bb72f729c4890e43654c527906e26076f590b34f19d48e6ab9faa7a6560d187638d2f7dbee6f0cea42dd885b7d6b1be159a208d5537b447b64f870f087b40002068b149a1aa6e25e173298cdf8e2d6db7ebeac3e5ce590bfbfebc19c2bf6d2a2d4253e90fa9b7d8797b9063a92c4ea8cf2e6141817535f5e21055ee4ee3b2f166f9f69d1cfba707d2849bf5d4dabf6bbf1529ad2e98dc74ccd1a65c93ea176d214f212aad00fc1aa9f832569c065a569dc69cef444470f0c6dcc4b310b31fae45e3ffce97e06dbda75fd156df65257beca07cbada601fb5d1d3ccc5df0fccd6b54aa40b06ec064532cbc1897064e1f0c7ff182decff960e88cee4834b5fe3ee4824fea981b47e7793da73ac710972e019665eef1ae92266225f24b01bc008a45d3561a1aeeed40870cefc8a430c5c97e461adb7869cca48835ade731d783be18d12da0beb78190ebe334aa4f8bd790be4638f3f3839d94adaac268efb7d312a9cedc9897868fef597e5b145659708fc53728f0b57969e2d11e7c5b524eb30938a101a31b1febabdcafde3761adff7d9a40a6c29337e3f1dd0d1b1d298cf40 +expected_shared_secret = 3b09c4579ad60b17eba6029141a6d9765e1abae72ec32f1b329a5e2af761a087 + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 27dc0b5977446a8a2769da6dfa5aa672b16fb8b63a7961433811b6f0a973935587f60c8bb78326448a89bb291a32f1406282c3f8772a4e2b43ec8209fe907d1ddc8d47584a822b6684da85a4c54906320a9169118b1c6eaa058dd3233f13922e249932f65ac9f3932253c4c1e5ac9595d5a10ca6cff03403b641ce79252ea2b999365c2c8ae62b4f369c45eace0d35255dd4703d06ae06f22c25b50d312726e6165a968587a206a7ff789c40f1a195076dd3340f0dd8c6b3049be76b2168ba6aced5cb794516432585bc5a5deaf09bc5eb3306f7633c82bdac28bc27cc1924312462e48e6fb087d3a6b61a4a21e1a8917fe4b2c0c13570d26e8830a0e1923e649a756a5216844a368efa096d65a2c4c3102f80841a4211960070e1ccbe6538be5c7cc09469c76a37089a163aeefba6d340cc18ca86599a7eae767ffea39403792853834423920f2e026e2bcb6a40167e1fe504df7908d1bb7fc8c36a68dbbd30e611742bb9ac65334ed34dab7a8258141e0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e27075c73339d38b4441c7a4ec79e1e6a60c88729a26b8a94739c3b807141713650920d6be7c628551cb3169b3de62afbb746323400411b4039c16bdd4c7ebeb039db0cb8e3d1af20470e5a5b154a7040fa650f69dccbfd44119e4371d527822770557158573943683b32a80ea50241eabc322862cdd9924a00443813b6ef4a7b94fac2ba88542b4454ee27b54edb090bb688e7eb1a3fab22a11a065bbb52a66069aed1cdc3e78d36848a1f8b6bd15108a3846bfe14a51d89382d8332bb311f0b6909eed19d43182ea5044db4d43ef3a9173dcc669fe5a8a36abd300378d6342863cb2e9b4651aa8689991557e9636c92c87cef06848d500f2a3cb85c665f83e64eb54abadd777e10a23fbbb1818eac65d928b1f610851fb7433e255efe666daedc1e52e32a9f1a1d9aa4398253a644806073734c39441d511240798ba315599dac72cda9925e5a8a0183867cd442bee54b7a431253e9ba21f2098bb5350f6e048f19a51d90e7cfc408bb040859bbf59d80f8cb2702798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = pass +expected_ciphertext = af241b120f8d3acc502595ba14a0477c9783a0a442889e99e23b12fc258e9d2339660f7c44b315fcf3fac31d781648d96b4a55af9d3a7ac25386c6e121b29f40183f6195c2971cf50b3a6ace17eac55cb7f145caf9e42d7bfc50264b935f1bc1ed60c5caee8bdeca5a1087171279f0b26236f933cad6e807462d71d8b60ef5bd8a32966d5dbfecd033bf67104d79f7eb10dc4171b0d979c999512f854ff57ba0dbe822cf26b1c7edc4819516d683ea090153bfed9eefa1bf1401335f38751ce92afff775885ecf5c6bee8e58fffe4ea52ebf6bd77707eeddc86d67cf894dab1aa72d99fdad82b9f1b121abadf5bfe79a26317f71a5cbb24854909c60a815c10f26c867643f02439416010b6966c79ddea83bb472b23566381fa179ad727d76382d9370e1256e3d9147d33a646f3aa193818155d2048c892fd552c471e99e09b52a2a5f0bc4c20c9b9a09eed562c5ce6d35e387407db183d7f036f4ce3eadb86f5b8d7483dbccc8415035ad229b78a25f52e9d7ac254058d7aa4384a14f7a77f3fdf449156758ec3598faeba563028dfc5619c34cc814d7525b282747ad5c04d1a9738bb7f1a3a8072c8629ba15e97e9091c7d7e59805c58b165fe17750d21a304f68645ae799c8a059ea1b6e9b4030120501b12c52381d719fe2b5ddf5042ba6509d27e15a07178d476d94766347b2e800edd3e22f6dc37a3935c5624771eaf950c358303266cc4b3056bdb5094d096b66b98d7d3cff283b1c7ab23ef06b443f87af78180f081d9fdd74c8b3e911c611988beab0e7cb7f9ddd9e6233d1cfd4091c4319288714e57c3d851f2213fa41a60c8ffb32c4e9d530ec3a833364317230c4fd33f8ac4540f42f7da9ffeb72f8b2412636677159b1496365bfbfd28e76edcf961b287bc0bf464ab1edd8b0e0e46cec8eb96bd4f38c3b64b71c1206fe1359bf14d1e8c31d4c6227cef0b9964e1a94c183be6b4da3e755849a6299c21aa9995c59de988ad0bc8d519247ec4eb8bf2b0732843c48e45078f0f9fb4951e4e56d73e39c55a809ed0c048c6cdf4bf53318f04dd342b2ce699ca8d5e06988ceedeb +expected_shared_secret = f15864351fe8e878ad66b402f012668e8bdf21525f09d5bcf4a4dad656d2e480 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = bd413efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816eb0dbb4a0f5232b0c4b4ce98098441227f25ab91ec97319ff68a916910fd0ca1d5209c3420508b64acec450140165620d9bf8b8170ad328286e49fb049386658179986512fc07d47d49a1aa5bef5a4beb499a007065a79e164a1713804b108a95072ec9c6a1be395baeb09fd9a8e0a749049e405137a5c05c80715f9b30022183ddb127cbb1ba7556302d2b1063b798cf164f0f0bd40a202c13785009bad8769c3155b643f7a19f9509987bc2bccf41a3b9c1b9a844fcc537d8a8a28cce0641b16a0fd49969df2051a6b36b5b58741a0cfd49868bd136cbb4763a97660694539a2025649a7884a64761a1059cda78e07c5abeb297c9e61407ae00606cca7d26c0da8436c4343aa216c6b71375e4c9a0ecfda7697e149b72c025696aba086251826435c79c742058b644b7466b857cb5792c539709a59ab15aa296acc5bf5d30bce8b0b11b56d578837f922a7523927b8f0323bf79ce8c372c8655082901ff1630e0d27baf8acadaf284742e73ff5650a3ca80c47586a1d1664128a4518e83a0e4b13352b4ce5838cde93826f0ba92cd6027d0869bb5342ac1c11dad0938c5ab3a836a646e37cc2d42d3a9324ff0282a4d38fd9055bcaa715e8da77d08434f535465c9b880506831b33174b974d41e680000b5ba3835b457768b3936d3810557e72407d9a953111990c741104fa243a922da7b03d65d2b41438449bb0975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba39277797352d24eb2625645995a12c2e69a62f421b510225ff21b817878aa0031d0f70a68433b422a7360f69abce2bac840b57afda2144aa62949093f643a5cd209486b6cecea226d205ab14e76c17cc86345b0d119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b5420ebc19de137c2b4e55b749399c5386af0870250e853438321ee767012483d8b460239350c82f8700e3568dbf453fa275d5f612ec8fc6b6e37854e8131870862f8046881185c3903440008c4b3464cf43b6f5a80a47c473a6870137924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = pass +expected_ciphertext = f9ff711565761df5ed623814f675b97cb588d69773f3e1c81e9c146c5265a16be66107289d2aebc4f2da0e4c23a591d4eaf9d0966b4e50e431eb270343770a81e56eed0e592d07c3ba75703dc94d7b678348110ef444ec91f8cf5ac270c8e7e068b024999b5719b73002ec8ba9c92e577ea3073f27c0b823eef6879b332506957ce2a3c7df68e9817bb6a908ad241d8ee3a9695f551abfeedae4b9ebabd48d1b7a2cc960f030cced49ec11b9627b1875c582e0cd311d6269a3eb49bc638cccdf57d7712fbef189e770f8f7003a95fead9f12d0764058cdbe2fedf3f09b89dacb61082da216871f1a2cd37bb4c1b8ccba8d9683a20bb7f944bdcac0c98015abdcfd6c6e7d739f0ea39672889a8e4af3635cd7de8ef815bb3b309440586b07b9b77f40cab33c39042749a837c91882203b87f6d32845cffe3ae07edf9105782d823e674d8c81d61f113d32e4bba7725b97cd0ec3f6d1b92a41214776ae081aaa7079bb1c314b01deaf99984f268bd66c1bf6b33b6f570d35e750dee1d4896662a058e7b8cce7ee0f26930bb1ddd918430220f6084410e59b283df7c65b62e17549521b3edf319c747444385aec86fe4b9d676c1136d476692c124819577dde076a8312cff796d585e3ff3841f6678b5324b92fc695b4a83128f4bf49baa5db9a8318508a1150872a8a866a355f7d198308220cf30f5c70bce084f633675ba7c4c6bc971c9a64d5aac31241fc533a844e76706d17d19e2f2cfe81d5c8db420e4cea37ccd045f2bf5062b5456328125a294b5d955d756e2ec87f2fb81e72cad6ced5b6140f05d2a6cccf9891ba777180e681f9341f8d9a072ef67c5bd6612a080172a93e688c34f5d4c10cdafb98f38dcd93f74016881fb11b580002bc897350b017d64d5f54cff571d3b464d3291ae3de049d2eb533f16456d960265d541e1aba8ca41b0648358fa84651e3f77a981a4f36604d1eaa57e5095230e693f6fb83bf1ebe209db0a9d53abf435bd7e663d0e46eaf5f56de05d9483d0bf9838fb780f565800bfd1516c1a6b5137879621f54a755a6ee2ebbd9028417d686a4b64e3274e6 +expected_shared_secret = 1f1a7f0d0d86a52a6679c431c322263b185b0c90ce40db054928be438f38d47f + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = c7c3b4465b0efdac63724548ff25b73b9a0ba6b5004b82a614918e63400146f36aab60c8cdb51600fa1218e9c3d619168d1ca7d1b29a20b995dc254080108bde2836a53c05aae73f95d4997dd002c21c9e16711ddf2603a845a5ad8518a3d3cadfb57a5a994cfa262d51f06d3d1c857de85cdc934bdff1ab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4c3158a99482b7511ccd188b5ad42627a49240257b5bf500e382a577dc57fd84af49731b6a49224815a43d2c6bccf03ed1f09379918c882cbc5fe33303cc37621c21d9e5360b3c4029bc2c9f580c2519591f6ca703283f93e759dfeacfc63101f6a9bcdb30839b1288334562b608b32d211111a79c8c2c4b19a822d18646190051c65c0a42ea51c0009ac976a06c4b3c24ec1b47c117865287b836738473af07f2908935b5c0dbca76c44e48f5478f78aeac138885721e40b8ab84c2bf8c69c3d4ecad4df0ca07e89a6a245bdc46105dd21a9858a819310cfb239fa735186407a88105b3bf156f95f87d9b3b9db0da6bd67075c70384553b28ca89ac9131561b9c8d37a5aef7a4152f6aa0a7f54af2f3819d6ccf8a07d0f4c5310907403020a01e4bb94d4c7bd257ca0944a6aff6cfe00c9182d508ff329505c3cf85290427a2c06366907b2b292aeb2b13b954f211117504a18f37025860cead9717869c60fdea3e31e9845d439989839bbd7ab2222b13fa921133906868e6671659b18a1c0f62d8bbb7b69b0eb62967b85b21375742757ddb960cbfe450b9a415fd083aed8ac0cb05a3732b39453180c97ba6ce5c426392545e2b6d15683300ed697faabf21a2423409ba37a899c602b72a5a4ca1e3a7c4423c5cdc3765d0972f22cb9386bb347617720c6cf9e32964faadd4a625a1586985571d40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041b82479b23f18d51a77f1086098c3a9d2646fea3b822994ef730b97569d05aba38f880909fbc441815850e0beea12403d0024d95c6c1691584c6b548e0068ca7c7333ea8d07f12b615433da2a041572a46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = pass +expected_ciphertext = ed98e8a3d9b1fa0b2ea9c5ad2a02ffb131b2230df45df43f53b5cdfbc00dfbd6a8f8f7a9faf230d914ed687cf1a9439a5b3981a8e481f79612c506ad17cb8c5e45dea6151ae03814f377f3b3b293d1b9e70206da62bf076b0f7c21f737b00caaec99d012d1842f074ae4f407d2a5dc15a8acfa5ab60bb2cafb7220ea175031544b9c0e4dd2365770b3c8a703b4e5e2f989a2a93c36b38192c85e6836d5b13ad675da7717b4b5994391bd535249a4290042a39ba0c81182f43af051566e34ba7cce505c34f43be5ad99ef5ebcf49d6ca3f525cdb78ddb26615fe5ca02f12f5088af3268a06525e16873aee13ff8f3a2af0cf2472a00f9d5cc91733cfecd0e8f88d2d7d89dc4940a48aa6b905f7497f47718e44adf96721d61e7d3980d6fd72bdacfaec663c7a9473aa36dbc13372600605c9bb7a9e904b19ffcaf39c1324d8a1f2ca5e03a51b682a67559d64e5c505755a1190788ec9fa237cf58e1a98030a6051bfeb4c5731b45ea3297c12746d9131a1d750816c484c77134f5fcc87e36d58ba57e625e288299c194992ed2662a413320c4fcabdd8a0b66c3ac76f5b446387264727b40db09f84291da10ade352e3f3118f66135e2f2e465dfdfe808b13db86eba4e5ba6c035b860bd3e100b86d4cdcccaaca10415f9afed88d72a4ca80e77bfd4a452b93b5916a06bfa9a5489a0264a1d4201ea753b3824af7a71e0541a513cc9cd22da765e9b2d0c4b2ae0c8b7bda62a9e716e5bfc3233bb0294c218925ca7f2d7373eaceb74f3bee889cca5d661dc2f340cd09a8caa0ce74f62a65445419790b26ec978ec32f02f2693d53f29445cf705aac157cc9c946e2e0cbc8b73bb24adc9a3d4b05e5b4f9827b5cfdf8599e31db2f6b12e2df3934afa755dbf163c85ec6bc84533efd9f3ccd328624a96f624c52013455e660502386146c1f9aeef2f7e57c78bedbbc26df6b4f8aee493ccbbe03397e4990e147092b0534196901428a1ff2619490407f04479e28541ca2933b9ac8bf9241a72f5a37f74c3892479de914ec23afeaa5aefff061a18b3f3e1041ac602af40dfb786f528be6975f97fc +expected_shared_secret = aae9ca8c35deddcfd7dbaa7780fe31c102aa90cc594eb56edc782fdc4eb53b41 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 83fc2701341ac042ba3987b25411406b32a000a12e00f726799b88f2219ab42bc6d08b3396bb77e51a38808b5a00823d45fa46dc142077ac63dd25b5209b0b35c0a3bcc30537248f568018f1324141404c3a603f8bfb30f675710b33b1f986b78475a2d4b1a6c44b6277b881c8f69c7198657db21fb0a9887afc4c3af212d1751a1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6da906e98630ba611eba0b5d622670b33152c3d91311cab5fc052c0050097d0c9bf0a4729a58b216b92537f21948c865e471276918b712037569a079600b1eb611c8d0424f8903404b9338d4ca368c0a42df6a9b6be6692ba24232c68a82b22076b72c5a71b5cd603f52493beda57f12c660f241a6b772bcf007819acc094e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b242eff33c5263685afe47dfda38a8250cc54160e4c22bbcf9765fcdc1b34a94faa088d4927a6d8121ce556576ae682e5fb2761035981b442245c1d114285ca20b3af733c2d3a8121998bbf87734479505644b568301244e31bbdbac05b8c5d93121668ec64080287ea074f02323a91425c7362428c9637e61bae86d03238c96336081a86198e0f31c17a945e50e15634e23100c6499bf1b58a48813bfbc7ceb3322274329366267132a972553c6da19e13898b89277a33836371084a5297bae0298288fa68a27605a60b274620111d376227d157d066181714ccfd42a3d33882335565f9a0babd7154c5f12e67215567676193ea837ea188def143e98c7721dc539914c678e1876d334fb99627b848616190a9f5371251593381bc933bc47c1e5ba50429b1bf71ae7c11ab43273cde9538fe8b21b310c8da5a68d7828c60761f2178405ab96cc3d179e75837f7c69c0990c75dbc2718003862448eb3b03e6abb535ad733f5701699d543ff893003b3674ce997e0c6ab8b7b2bb834c4a437068c9271f55c2fa3abb4608cc88128b13eb17a2f45a7ea9b85fd3ca8cb70bd8c0578f7963ac76c3d39a44f2b87b1fdc24f15d32f2b38831d55722aea8642a7ccddf2011f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = pass +expected_ciphertext = c65bcdbbbe19ae33a1a009f022fb5f70673dbc955f18ab4346bae8a9439533fdfd0005a7627d4ff87768a8e478420852bae07d774dfa6c394d3b620c576bb24c3fabc712662cb14706658be7d40034a2d8f0ffc9d838e3af335da39feb0f66412fd83375f3a54990b78563ac4fc08ef20f0e7530346444b71569118bbdb8de85a54912a5cd82bb787f8b4dcd20b10c794ff9f8bff04470fbb576c02fa6d2f2997a9652b4785d772c6ab1fee81cca792a98433cb9a89498de87dfa403288f3c8d2b81ce486bc32c29d11a06dfe10cc6e3732cf9a3b1cba5dc3b820f6a5630b370abb0e4a97aff035685dcce014f68e5146fe0072af96ea57b10b162b0643668224ad8eefb26b29c0438358eadfdb23f30cba357d6dee149faf352adea4503043402326d84f83587eab1386a6ef65fea0612b33819b7175d5be443b9616551e2fc3198ec3c0f6337dd485bf0fcf25866b092a9991ee31e434e3a97e1fd8be7331115d330bbfd4423a432b3c196ae1652445c2b9ca578446883809c9437a41eb29d07b0e1e008f7a192c72cebdcb8cc9baa465f4ea2cd2d2c8918d3d0389e12d847b0aa34839645bae0a0e01b09d8d546307d05747c061b950eb6bb5bc8040362c7b25c3bc320fe50d912456e5c2043400455c0185e8dc50c8f37d51f75a1c88e809c2298a75ff9fab24b43faa33c1406aa68aa81ad7c6c0b3d22b59e9c9c5d94aabc89921412f27a4b9437e64325fce3c716b3dee791e85245c37e9cbedd3eeac18eada39a0a8881777625978672e1b3f9688ce38fd36d79d428b400244275e6ef929016cc40fa6fad3181434d26a3230215fd4739d9b1a0db3f648dc3b1b95feaa927e80284a788e1fce01d0988d194091e3ee0d4381557c3932977cd969be70c88f4195780626c5f091f8f04cbbfdc08ffe16cbb83e7935abf3b3a999412c29b217516d75f93909e75a42bc635a7c25e6ec73b08690ab23d32acac2f917033bb0161daabfd966063f4963863a9ad87f7e7b3b114e1f31b9003ac0d033d5d990be4e2efaed2b9f6c4802c1762d7247df55f849f448935220322c0360dc0a6d41e +expected_shared_secret = 970fe36e57a253e88cc80c9da6867dd66fd8da1dc15c85a480a1a45eed708ff5 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = 8b49619f318f10025f45eb7f63d1875e49a296eb1ef5586a9ddac4a59bc96cb01e0af7655b052f9a08b861f0573b8a64295315b76c3b0a13cadfa47e02c61825226d3fcc25202a862e509d0ed99521b1c46c7064de830cf70497c934c7811733e9c70ec2916075ea425d3a0d03ea272bcb0f294aa32f1541df2bbcab251e9173701d8cc678009f0323677c2b0708a246408b4f37e95c170311bb15787e9b035ffb823db6cd02e4421f3690644cbd4a413bc7e696d7491a6ed4018091a9be8b149ad93c49f6424c218803b72c146cab9721ab22c347787090d9016199e65940e19d6902324d138561592a0901700dc54058a6ab298b3d62453865ac29bc815e65582f9b8bb6b5e44c12316de7169f4988c86f953a61a313e4a2734fcc24afc60f6d22491e97bc688c528ae661c9923d587bb11d512c835a9fbb314c39109c3ca2166127084d282979304265d8a78ef343bee9baa7038b9dc9517200c4a049613c936f80982efa61a3c0f18edfcca724a43c79ec2f03b99b656941d5cc040ba07c8d2668085a1e1d7a8e9448767e32c86315410f590b03b993f5c21665a7339db6386e923f7b50809d528772c27660615acd53a9753085e7b9c025b76b952518b5b11a778a880350aad71b2df3260633a570250805b4b0c8887268f1a572c86469e4a75194d50a6e89bd4b2a6d4d09698b880dff136def5b03e66726dcf26fd4911bf3502ea40b0ce71c2588a62dd378447c5477de819baf0795134001bd1250aec31f39a25c98c59938d97390a309ace0bde67b3d13cb46e89b3d7f8369fd539b639164f9825900b36895bcc60fb98bc0a28110f3a7af4070c6c72d63096946423ef49269176a529b5792e4e10deca940564906a29ca1b6e95352210992718248e664a65263a235b17293b6f4b45836166cc461ab04f91fd9e7ca24a891e44c2df9684b85a5845efa2003709b07a596f36aaf9224ceb70c98bacb06d0a1be3b0a926d9c537223097f420a0c1a1dcf360d87d0825a417382c40f297a989a7bb827ba5eca46395e4351aec09420405e9a919f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = pass +expected_ciphertext = d4aa69eed658bcd19e2ad7011f6820e9ea37f36088b98d07ecf74e89e7f6a10dc43404cddb33d50ecbda04455584e7f6eb69ac0642a0d5a55439ecc1737352e89c21110d625f32ac0df847f6ec4d6606447f1b98412b46afa316efda72540ecaf6f2cb867441f7210d5721f9324c1e39bc5121e0fa3c1cc154fa527c52758532edd7899ab00636962d0d26e82e848ecc03f93e42bc4ec42b24f12db20c02431839560f0bc7ffa4df5523b712a863907c60cf414d2724de0db4b6a8277e00204a56234ff642bb4f4f2a477a2365a016c4d844efde38f1c65179c66c6b8284f8cbc52b821b9c0b715496f6074e53dd453e94a6aa23fb0866742a77723eb7a2107ac6d80787b99a7cc3b29fa0d90620d9d740a78dafd17d75f05f611883ac767e28cde536f2288380817c3018df57cb471fc4b0ed461332045a7cd89cadc290fa0b2adc367a76fabb85010257bb8b2818ad02ea515f9d1a686e0140c7e597111220295afe0ed0dad1072fc13fa9435e2a05dbc607f71d4e30f3e818e6aa700f792f60337cf85055fceae614412baaddc9f96efa7674439b96570ac463b8ef0f4334ed50eb8bdcbb5b882629e79f2b70d9e3c9fbe7f77366582ec3f23854004f38c0ba02593492a45672e6a4e345070ac75bedde0cff3ba5dab3238b54727f2d7edd44e2bd2a57ca26535359ddabf207b0c94f67757a09787a7418f2c551af0b57c801f7d7009e116c18b01d6cd679e95b38df127a54dff0fb94349f97b54e0de458d0e22e6f246e038f0b477e8ed6fbd5d8304e7cda6e79deeec0626881c7eb727a68120c3d602279bef6d01b7db70f1a64e9cfcac523d8d7dfba8e8f90f67567164a146937570fccfb3af3a64420e11833a39b67b727e35f407976880d104f05246ceaebca29853b014356601ae0fdebbcfd84e02d75b35db6ed1757691f4ada0aecfc58b9f4d4f6aa919fe8e0ba568399c9ef1aa09c55dc93fef55e871445df705be8d0eb7ff1416cca413403f1900f2bbf46a84dc3588f25b567ba5699a8bdddd55b6deec519bc1f76cc01b368ad3db77758f7bc4ac6e2a33a9f280c8c65630d +expected_shared_secret = 8eb310431276a31c1913cfa2e2d6b0dedc8a208c7470251daebc5b1bb6ee78ec + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 5684bc32ba5b14f6999a9c794f0c6af04803fa57cd54278313e99327d579b217682b1b86dc02431c6aa125062367798f2c7b1ee7f907dfe42736cac924d169351853f15b944578c5543aa27b626ffe7b3114a11805d8a3fd464ec46b912ab89a3df2a561855fbcb3820f4c11fa7b5e3727612e685830f3aea6c9881bbb06eba102e3f53e6ec502a4ec98f9c1af0d564df79c8d7c403c4843cd6d05732000c6eeeb17cae7032fdcbc275949a8d0501ae182cad756808cace516b72696c618b319f56615bfd0472c76a5b3b4b6b2471e1955025139c5805c095867be34657c5af333c9111b01da84198a8d33655a37f6aa3f35b7e6f34b1e2b158987ccae22198ae605a9a86fb3985f189292785a14fe2a4de8e245a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578b21260625b7ba7339057a94435966df3033c647beaac74bc7014b01dc539445c77509bd481c525a226dd44966feb66684644f598c9493346c9071b16576978f477ea07862863191e02805fe4c54f4153749b222a001af7396a2314054548203bfe66080cc0ec95c2b86223ed936268fe418486a58afdb9fe8dacc49427597e4198ac4c8dd747aa56cc22e38c7f140988ee37dfbb251762868915b6ac205a006846d74e8734a930211941c4e5721ff281551605866db0f6bfbbc9fcb649b45249b9610e647c827cb983d61a6c9e717206135e40780f99495aa3c9c6b619e47b40521db992e5329c4d3c894342e2ab2808c630d9761ab13416c55fa1f1ee2b7c918bf78832b23bc4561f6cade041f4223067db18033eca02d243811132c5d98acb172bd825660e07007125b7428f7403bd2c19f522588d20413162253a95f3e54738ae8694b7a5bd13c7b0a41ada087a8cab72b6927b3ab614cd6a00a00e2545fc7ce547a2f3b320b9711167b694c75ea6494047a8b6c07df344dfa099482d322fed5792d1507b801424bf50fdd2088c0f18a9bf31aefa239faa50c01c8866d0389eca7a521cb9028f94aab585841c021dfe04a008a8d11d23d534105aafb413450a2ebe6918eab0e641bac2d000d7fab0ad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = pass +expected_ciphertext = 69d2888f5b3d14a0c34b0d3ab04e995e8882390703525db0f3279d967fcedba1ab9bf4f06258ee76bd502f3d72b19ff6e44b241f2191146e64d42483a194a68336fc5197ca6e5147f7e8fdffbe6eb0912518636fe61781af44f39afe4cea8a0546d2b38371025e046f0fe9fe3c243ca9a20245120184d0a1f3cc3ad1b2dabe348ef5478f0340a6fb2b5a80381383ff91a1d4f86896bc7e42204708b7edbe828d209680ba7e6db55f08e164c68d91fec9a0bae1bfaa8e04a1d8556d199642b10ca6fbdf080a026f0df6a88f30101a88ff7ffdd0a98ea95cf470c06056effeff255ad441362d90cf0e1c147649a3cc30495ba769ea88985e82ed0cba5fc1067a5969978d7d7113923e68bb8cacbdce937a7232f1b1cd470e3c9bd0f5307153da5ca5700584ddd5f828e7dfb2d6525a0fbe5dfbde36f282ee3cf1d094731e27fe50a2ce995555007a563d0798a61917cebea339ec32410f8db30fd4606bd93bf7c60b1130f5e6b90ae2d37c3dddb5af7bd23117dff1e550569e36d0e4ab0489489adc94903945534acfeac4a6a8c71f890929686133fcac2b01de93c048a7bcd85ee32483b89e77002718ea0f9cab8fad836bc851dd521ded3d6141373d0daa8b1b824bad5f9750e8f79192e38fa928f4d13f742d88f0f398d6b0efaf0d718b4f0eb20fb68deeaab87ffc9f5e4175aed2ec0b6ddcb0c2b368dcb6e473a6d54b01483e68566b172403e124401ab98e5f18af399221d462231da58ee3b4b57e453fc1e99002fe381f56c8ac2942099077bd32a01be4a89a294235f36545adee763102e6655ced957493c6b0bbf2050e832724df326c3301aa50c6e0c1677b9cda946da86b40f2d8cad42c17a4b7eec870947eb2d98b2f3b7cd3be1f4d4b0fe93c30595c2b0a186e01ce1cfd63307d047eb9c4821f599b50a40820d9fc31e489467a5055a2d60148d1158dcd96ae06a97be24834d683d9848c9139ec7a612c248f655e1e0defc3ec939690b4a8b967611f11d79771df29bfde86e0f3fcc25f0dbe61ba1215c8130cdd358cbafb0cf1d4e2326949d7d3b75762b79ecf50673efa794f78 +expected_shared_secret = 425a88aa4cbb6b6de122f1730aee536f1cdb8fc84751fc6eb2b42bcde5febcb1 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = 9a3aa452bbcdc82111a6eaa59b04ba8a78bb9474659cc944e7a883780815b899cc64219dfc583f0ce4103eb04ea7e60e2c627a91b28a32843cb395021ec544005326f12b53144ccea0096d8b186fba2ccbb9e4197a43406fec09f53abac00245ce1a239790ca622401df204a90b4a438d33391dbb10ce1aed56456f4238af548881d188f0976887eeb672cc91078474cc2c289de2459513ba16458aa5ff06ea2746d4293b7ec95078d9346d0197dc9a93b2c153abad1c62758cc2f57544f37cc9597691047acfce10be1246fa51b056ab87f24c38a0fe36813316191612e9cd7a26b745f4c51a1a164422b4502b073185a93725bdb606ad6850ca5a27f7c2e8002aa709517783232514309b3c280444c0706422652b170011122e0ca821b5117e530ce07282873ecaa7d751689657aefd5575a7ccb65515e1dbb647c31b1f8578120252aceca821df0416c6780b9f9988ab68c72c73538ca21687cb4654667d3e9bf8a0bc6263053766c8180b8079aa8c975d867b36b45bb709436265ffb0524a0b143095351c90541f8437e756a028be92910341db30b8a94290cf1f9042b6bbc99411b72176e7c5a830be2569b695e40e63122e574e061278a35c607ac8d491b60bd96917d81154e9a244dd014ee85ce9b0691c21c08cf2b7143b21ebbf71412b873828a66286cb2b4f11c73954aa64b1717769573aab29de4cece271cfc549f7f26aeb28360d22926cd16cb67f0798a1c1a03f706cb3b37ea250b75b1b881c36c86461597292561503e6f3405b19a3fc3a8c229d51b6a5391964a4c05db926ef13401250e4a8235f8ab4fc3039f61446f37c1c3fb01b626e725c8c5031db11093017a0bb5905fca5a2721c35ad2100a41567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a3751bbfa83e7237329a8c118b7b7af9816e0922661869a2e68c7deec83545915cb11570a4737542ec9ab52246e7b58c0df812e2672f86ab92c788257f69a0f62b8f7757489a182de8f626a4a91aad8a06f9013a9ba28d3eb6617a21c9070cc65e3551dffbb66ea449221c17efebc429c489fe107bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = pass +expected_ciphertext = 8d6e542a640d28fb329ce4bea19d28f101981c4370cf4174d9b2c8f48b98fd44ca9b5fa723b2bd20d383726158a5e5be76ef74af405fe5b58b3dbdb531f227baf0c6e11b395528cdefd0248dd9bfc1daea59f18bd6c5dc839d50af2a3261ce05aafea3991ebc7367b2e9076ed53f3b79062a874d209651c62858244483fe50cafc9b0184df4ec777c9d8bd2779edd813b8c30d786bc62ab0267ee8b99290d3694ce989097bcd4521a935df12204ff351204e213c0b8fd595aae93f7a92d87a8d6fbb172a3c15fada27c6a5b6ce95661045251ae753d455b68f18c5cf0e1b0623611d81c9b01c0ca687bb6b1a481efbd1fb7611c1fda52ed75892d6550d67e382339c9557308d60dfa6f266f448de5147300931d5b6bb2e1bd43339921275d8739db73987b86dee67d11a8ada02f38ec92af8221953bbf87bdc60911fbfc17a21e395451ae0a63198699463e9bd09e2c1e3b512bd6ed7c09672715856c8f64aaef3c01193c4e8b274a5e793927d73289f7267b98c1e87dab413c54467b8052114751fcc5da30244b2c5a9f02427c7b55e617553ddd8000ab7be2e716584dec63fd94c219f85fa6060f9650e6d504d9bd1cb62d7ae0568d41df889ffa731c5e1b58d08c5c2113d63ce3fad7ba7272753d1aa1b39a47c0e475faca105680e1067bce782537a93ab48e266c6cd0fdafdf40123be2587b8697e775a1597aac1845c9d7db1d4de92dbf7faf9355756d8ea5f637da8d0a56555497f40577fea03eeb7f36e203ff28aa536e4490f39016ec9bba62f7751c1608bfb10ddffe3c7ad3e94a2540fd3ec60ed516021c77dbceac7bd3734c0a85f7930c17aa4f022866347a803eeecec2a3680132e2d4e256c539c35a435c1b2766fad849edcfcdec82628dc9c2b9f4e38803236f3cc1ae5e0cd30062ee83c7b69ceb5867ca09eea75e4ddbcca0d003dc352240b4cd4327f6251e70f7e85521307af5fdf16a4d9b382b60e265e110f2bf02e7ee6c7d24c5ca777d33890b6e9935761351e8eac0ba9d8b79fb70e609d472ebed303e700fdd57959ea3448e7af0e1bb738a2a76fcaf0c248d0451d +expected_shared_secret = 457efc40f2e99aa599ac1ef92f9efbfc93d17fcd793837857f6a5c91a8dd7da2 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = cb0842b8b213052794e18787efe902d94c88c0986acffc72dac4505e4c36cc7b4990353e249112a8251e887aafa1ccc9c627948179a747b5cde3b0409d5158230b56ddc86cef9b241c044fb3d523fb909ce0065e260879690bcdf70c33c24303f81143624446fba37748f820cdd97e50d7a3bec058c404c458294eb812908dd87e4d652d51824518b3185425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444412b20a802c399bb56f461aa7631603b85c18a9bb7c83f6c825b9a421e59718b43d745c3667781f819b2014051bd51758524bac2dc9176cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3555b1950de9907289bdd8591f5994be7f920d25940baea14226cb6907aa5ec878ca37ea698c84819b62c2e13115de0ac334169f3107742f42a9b02912b74c39ccf5181ec5c0686c785e246c424143f5363900c7c22df505d1308f8483108f31003a126401950e2afca878443722b30246344ec2290fffa542d6598f14e803f9d91e5d050541fa2c52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b5491149e25746e262193965815570b9d353eb1ac9ea9875323a33fa4878b06054e3867ad9a302b6a43ff902453a92517c7055b2261c7ea04f3f6051c16aa727c169c421a0bcd036b2eac82adc3efde4bc28381589f36806189b780c327bf4b4b9b11dbe036557cc38898557a8a48693fa70984aad327078c1f851ef3409ce0348c16202385c22a70a0c0d54a7e727c0fd386845890df7687a6f65232a327d8b778eaf5a29f43787646c8eadba0a1a9b5c2a6473252aa6f12954bab410e4aa4108b48f618ba595159ea8737c7870ce4b0791706ac871111b39f71b0a394d0482c5d61c4d4d5b3ad0f5936002477763774cc2a06e7681d616b12cbb18c9e0681eb66a724123eafa52f63b2774829a373ac8211ca3a9369f128b2c810496c8a9b32d0813bfc2ced0904cf0bc24222b96ac4897a7f4686b5b2118780b656406cf42294579036dc995c42089648b63504b756b823d22c54d2fd7428bdcaf74113d6345c1eb505b843291a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = pass +expected_ciphertext = 4069de96aca28f486c6e7ddfba8d33cc5eeea96de1e2d8bf7eeca884b015b80bacf2fd1e302932c267fb4a2c4e2e906694ff356e758ad383ffc1a106496d3525a47d9a75ba0ffbea3fb4cffad4b0a490235386cca196e168ceae143d66145174f0caaaa02f392bbd2ee43d35cdd41bb30fbb4289288f9de182bb2a2d2d03daac88111bafd2a1414824f23591105f43985d92b87c5ef71891ff72c76ab9c820d48f8796a801bc616ab7ef6ceb88852e80be417443294b70c8d2b9f5d1134b230facde0bd5f5c0cf873160e1f24c9b65744b96770e9a767a76f1b6eb570e97d27f8607cc88b29f8f46e2e79957cb2f583b0977074a9e8688288763a152978a5c976a116fe56e06a108f7e894abbadbeb69c53e7fe653bdbe43f62d7e7d30ebc8835eb532969ca76eaee890564ab3d703556cf9c8ad316dd94b9a5433776697b7a2ccd2ef624f6f1fed1716c7a5615579f51611480d074783b3145e87e42d159f3b1b47e91f3f930871c080511b6e8c8693356e17a892c61957148d16f91984f9ec83b3926dbeff6dd1944a6af872864fad3558bbd8ebd1ff66bc13444162a09c13e4e4183bc6f73e9feb1bec63db3d69c5fe3a65e37ce099c7f314e4ce7b112ab290d97586a72e0f76c4327c3ba084348318b5157fa115ac82087f9e7344b37f54148a367c3230a357add9378e4034482c7f45d0fc0a6c3a84a29a3a31768c352881713afe9a69b82d5ca99c929f7aa9d9e1f391ccd3403bd86a2c842137015da6b0ef0e6473a3dc795d36ed13f36864ea81c83f3da6f0c553098498d9f53a3e41f528e89be041069c11c2c9fc2d7408d2bf133f5334e89536fb59a060d9204a8412b8e6b5832c6031a845c31ea89f6ce1193e2e2e1b3847a926a72e5f31cf3e710a592682a85533a42df66f2505d4736f6c6311f09f7d7fca6084d68035bc48d45e1a1a7e530e58019b991cff624b86378b4060d45db07b8325cb2beac2a3d7cf40b7fb3efa422cf838debfd52e8afe96ebcbee8ae190e157974ec434160b81c4deef7e12cdefe2160c6c6283357403355c2cfaf58650146a2ee703cde07e3f01 +expected_shared_secret = 99b58031465868d0617fa795e6be1c33a870a1e154a85a2bf61346f7c55f3b76 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 595aab2d5917eee9401f1b23be84c1e1843126763b2d98c83094610e55545e5478f7251d83282d889cbbc4fc2ae7e11e13874a1cac92000949f82b43ec516de9500f51469975f5b6d5a35de6002e1aa68f84879ad6024b8d913096e381e57776b8ebb2ef501e6a3464f3730e668a22fc8224764a3810aac4c4213e9584516041437bea1920321d4e53aeb3336dd677579f84362265a69090464d053447684ad3961adf10605d28ac5d0193c2f59c5304b14da328ec44cf51e83992fc6f69380e694679556b14add4801342cce20a8658b98846827fb2f440ee21061253c3207c9cc8961ca37c4b3d9c0ce74b36c176643e8ac5fc053a7622158e8aa1ae36824a5c6a70b07dcae4846f28321fd2bd6822293ff4c446654f5837856fb98be568405a822f36fb610301ad2f6027ce1391a8bc0c4fd964b7b807b3fc5b684aad79495f78f980524a808419c13bb1437596621d89cad5475fde6887b973ae08f4a9276c2600489d0d773bd18b0bab3016111c3ae1725742f424d31115be336a5e5b9c3020bd7a4b5cb587c593ebcf61981e3cc6b4b19baa868092ee71812a6791a6e02077c48ee4386120700a054290e0c6b792857659ac01d715b663a3cbf1530976cab2ad5b54e6463168085ad60c3713a41722887e83b406cd67a7ab77596f820013fc7dee7c5c87e776c3976706b3013dd45395653fc4a42f0ce85dd9d49c9f299e38480dc1742348306a51d79d6f8a4285c580ad7b66ce5348e44461eff13ddb4aab80f84948f94c856c03188746bef5c8479c9c9cd1092607822eb82c2679966b17c093643e45d28bcfb424239abc55a52a9209bdc3d70042204e69c1926132588a6759ec3776e8794483a6b2f84319c132508c804112865a3a7c804b496294314de47a8c03a71fbbebbcd9e28e5441c654c04cbda9b7345a73db10a462280eb727c2ec31931d592d333378a6d261aad3a90ebb4d1b23b92d7779a0ab56e8d0ba87aa5413a34c8a18cb1406a8696837d7f547acf97132a015f5a76087f292b80835e32a46d250aeae45999ef2669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = pass +expected_ciphertext = 8998abfcaf828a014622c23957c75e736cd62f555987abe26d3bde3a7ce51899da3d5c075297974eae1a19a544b3922fe4a64414304fb534168154c21b10c77fbdde6d458eb54632640cb6319204c033781af0aa0fd9a6cb236743158be39f6282eed6c27544583e060663ebfd3e4e8829481542ceec033950c77d6769913e3d3c35a5767f9be786cbfda254e60c99778ec2892e3c04f29f1a323eb0e3b4b62704e63b6b6317b79af26adc4bfc6f95006deed7d1bd640515b8b3ba4e523e8cbc0e5b8e28ccc13f88e228b188fe3591302b91308002a4c5e1f3f28620bd2897a1e1aedcf836050b7747684c544b62fa813901ee544b6325d74ca87fc716f8cdb3c5263324c01615c860933501d7cbd9807eb7acdc87d4f9af9653f74ae224cfd230680b04cc820ed8cded06dc1dd046b70f4d95503668e2e45bdea6e38c6a5848177b40e8ccaf565ae7d170b2f4f6b87728f95b9828e9852122a9fe1c901d90f0bfab159353792975b46777e9b4c9a85747f9b50a7bb71f2dd090a52b759ffa31619cca7bb791e748f0028f0e0230109e622cf3bf11ec615b4339ad806a8492eb67e00b1369e15f05895c475fb39cda68db0edad0d60b1dc2fba828742df7241dc9fc885aae84e053033db30ae3712a5b002c52feaef4a5a2b0f2313e0a932d83abc4181c334f223cd32e54368ea1fc65727fd7d67dac2c2df471e71e51de7a688407a3da7549b502a28b3ea288abe7242c4b88afcf6218cf535d8ec8eb0d4ad36786614d3192f714f2bd914440b6759c5451da3b2b3cd04ce723fa2e726e497733d044fdbd6865e05d54192b373a4c72f3ae7cf414d79fbf2c5d9155f8dd25da662ef2c70a18c3d304ae1930e08ea81e01fc2777f9d03ee4a380c23095e2027c4f648b1b84d112726bcf837ab10007bcda9b40c1b9903609c61985123143d509a8bc39aec6c16541e869e69e5a282e3155e37876f635ef010d05acba33e3e7b7e61b0a73fdd809f9c7e959dbb24ac7e32134f2b18ec212e0161f297c5d8a705223b3b70891056c8ac524498e0f8c7ed682fa20d713b3abe50dd9594a6e8c261c +expected_shared_secret = 387705c2ed600492a0b06f5587ae3c40be55e6d5592597e57cb8015de9e9271b + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = 14938a88ea6a5678c232e9542a42bdd4664fcaeb10c9b8b9c98c7a03a82e25da09a2349361570f46038b3902031128311f04c50824ae86421abb346bdeec824a085f46a51d86f5843c319da7470190d572668384c46149b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85bf822110b942e309d03674d78e49e19a8cffe729986e06c14f87bab772035908096d7382488a7e450b516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd34146e41b811350f8fd9a86b113dce4735bb149eb4e8c04735bdedc8119ef7a5f6abcd94f55acb7276bb3b6000b9a82831209820b89d25946b59a888285e1fc1904d4c1fd0f39625ec2d01360768f57158a5ae7a2193243b009297702d121e52237b4cf8cfe794560f270fa985c949e2c4ed748f2006159d4879492b4f8a14b8d90c9e540b1f993a5236704cc5740a1490461fb23f3540766d249394a144fc434a226b04a38c755de32dc6dbacb70177189c10d8e43e49649840083a93817342d4294f1ca04f9a9ac52846f388bcd784477d5405a6f36c9774bc80909bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b8764f3163a597910c9aa74fac696b0cafd657882004805d36a726ecba03171c7ae41e68d08e67cb7780d7ca135652137613b3dc58b4176eb8ecc9d0b71c5098679d0b2a9d7058c71cc0d64c7a22f37c63a29c4f007d8d62bd8e245069bac1f2d980c0651591e5a4477bc03b47488d08825d44892558009392c0edfac55a2c8fc83a01577192d1dc27efc76b27104e61f34cabd900784c1fefe7125db21d15a6a4fde7780a9a22a0b52bd6a8b7f2120266f9472fc12a02d17c5ec6938ad416201bc2fed6094bc17e86082659863f5ab07c07d20ab6c9b15312a444f0482f5a24f3a96230875ac1121cde130d6e221341d78a30902ff031122f40c6032661f56b605135464185236a91a8e161aa0bfa7a59bac682ba31b5030bfb178cc33cb877796ce20a6e873c921b2c26e63349dfc668f2d3550fe0a914178c9845b23af95b52f86576c71a23223f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = pass +expected_ciphertext = 35e3db34d76dd2648d1be8b7edfb0f2f42e478a21277a69ee89ef2fc115b1b49a7d510afa8a10f55f14f8ef4f9926e30b57946e95a1491414623e08bd6475688921a22a2caa5819751f85b0fc591f97a84741be0a8132d612c9cc8e4805f0683e0ac87879ede6d049e856297f9699efa64855c81a91593411f7630eaf99e53d3a189ecf8d5c72acfe4cc3f4134b65b572137f175d952ad539c10e87be71482c02e4200122a7be856363fb52434d46fc8d099b1fb42c2562a8b09d4c501831d12892c820e4f93472d368adf41b937312a3dca33fba0ae00b0056494d11a3c4a649eddf0d728b15bb68daad968613c36c4c15dddcbbbc91a1ec3cb1cae20e8753736425ce146ec3c7ee3dfe4969320e479c2c4496527b3183bd7f933a1baef9f352180e16c855d5bbb54fdc2eaa821f91feb6268bc6c1248a83f2c587d017c66cc15286908b4ddf32b3fd6552f93868ba01b91480c641929bbb305f900b8003b7561dcc4f7b55759ce84992eca6bfbcceea32da4d14cf6601bcf0a2dedd16e8c62f25dc8bdf3f313032aa0a365aeb148ad298342aff0d3aa1ecc6b35eb17078df36a0fde0b607d0063fa971fdf7551935e61c0a278721da1936a79e43fb1d0e9a03789817c3cc6cf1d1fca3722d433e73a5ad12d2525a3f4d4265018029247226a6862ca38af8b1bbcdc408f862076ffe17b003fabcebc049561305afd51bbff6d027e453b8a607ec57b2e75f2bd4a2111cf5b9cb6024a968bcf84a6a60ec48a98295d30b550aa0407294d0e28335e1d683fc4bfb1078f67bf2ab8539f066c02155f510a2434d34389a4fdee5f287ceee6e55ef5e9a13f1e7cdcb323d6d3bf1ba1c686f312cde818af6b0680d41e997df78b9a0a0a9622eb0f36e73a96114c7d7d42dcd2cfe078b872b4eade50742a2e1f35a3752805baef4071ee00a01fdf2eaa01de47a772d35093e2dbedc34f535764852a67d3624425fed334e1498bf8d8fe2daa712b4f8d075bd0e34227d8c8d060b223b83492c3b5d034730736764b6e01b696ac6386ee84519f729e042b9114dec609eafa705858355c425f92f50378cd +expected_shared_secret = 2a426534e3c23e28a237047aec83d24abcef8c7f77d85d8b27aedd7c50263010 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = 811637e2faaacf51518bd1668fcb964116b7732c71d6515f51b0a454d0359384a2ef7c5fd7ea6b47350c68fca28d6c35219a359e273fb5489e8f4200f830036c8c6046fb7269290686241fc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b2021bbb207832f7b17d187a749eca9cd8aad1fa0c2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956e821c0bb623f033c0b926303d77cf8c2284648059c9b73afc326b0ce96bc8190d41d849a9a7afd7091527804812a914adb475b1149f090642f1c8c98d6453cd531cad4b886df17975f91b3aeacc23358b13b54e40d8856058bad19088371c7d8d896b2ac4c8f3443b95099000a237d791ba0853a6c0e821b051472bbb1a95c7a480529683a7978373081f30af1a7a6c713557c38b0bc9b281a622c68d7912bee99ad6d1bd541182efc3bef160358c067a3363b6e03a5db440bf6ce2cd8cd09c03985a5dc44ad7219c41b860eb2a8b6b025da63978d0041d9231a4ffb28fe6a6cf918bc6fd59aa6f8260c373b645789b9e0ba4798b4b7d8b468e52b2aa20496ba9cba4e2ae6cf069c86b652fa7204d717a623829218c4b288035b551c6f614805257516276531a6cc9b6260b50576e149acd9fd4b324ba5a89ab60cbdb682a85aea36230eee9215e442aa22679def37947d4846fc7ad5ea3626c9c20d94378834a4f086a05bc8c252d22adcfd47ab0d63c886947ade8282f380730fa7b827374e617582a7a2fd4bbbe56ab7031a51871988ac823181966b6bae54e93fc63d2463cc3b103b745b367b70bd212b79363b2669ba062c75da3f2037c17a290281abc4952de641feb740c1cf2829f1b3ae798c3a128b76f4711121597dbb5755a2964bf886f1208cddd70b759797349e4a8bfa0779da984f43195b6bc24338ca7a4714458068b0193c6556c471ec7586268879582b64d26383a9489a6f525c923a9e553627c365bdcf32a4158452410357952479d84306c3abab55792bc1466beb85bd8917722289534c74559887b0d8250309562910a0a692b0da73439d5e87007a4b0c2ebcf3c124394975657fc07b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = pass +expected_ciphertext = 733ff770191463a961d8840170e9ad27fa6a5b4e41214e06581c7b2bbda563baf8d029585137f151f99c9fc4b16e4a6347a4f14bde29406f0b8aa277914bf030b7feb3066d09ecbd19605bbb5b97ba890d82f65aaf7af9ce8d346611d11ea2b1af944fd8c5145b7b83ecea24188b510a1c51f876b4910b266e0738919105261b9880ef5c47c984ffb077e754360834012805f346d31e4227ea9e85cf13a787e1207f0b3957c7260ea4fc0186baf4cdbfe650457cee20ea4d38d08f8d761c6bdf33efc6480c684b2f9dcc3902c7f6832d6d51985f571c55017a4e32574b194d9b7ed474d575885b99151fe9ba61fe0d501a0112c1357912fca6f608660a47a17299a12662205cf302fbc9fecea71811eaf38f748839d57e4e1f1943fe7ca6c61a5c6be1fb65d8cf00d6c3126c3fa354ef5965342408e1caa091920ed868f2bac94d4e2a449d98b9b404bd606e6e4529f4dc2d0c8886dc4074773b999afe8818de9f23886fb4913de65c081e2f3712854f038c57d7082198444b7139de2f310478ecaa9b8d1d552aee3fd7e00069c75324c61db2cddd493568fef6e91a4b44015d537739722fd452fd4e6e27dc6d1a3f12bd2281ccdfa0e7474ac89889b370de87037fb06d1bcb712f1e2ebdf238e00477384bf28ea7f410ea3c82764ffcca870c611122f92541569c79989037dd6143058e7c69ea7153a73f54fba2398018f93cedb0b4ede0744c2c68b3b6deac7e9e4dcbb217434b0b472618e102df9a06f5052157d5e6747d430f9d1e5b4a38da7f723f8f4b82125e1653d28912456083557e314a0a2b40e814fc90a1b25a0ef5ca45a5b7f7536548a0eaacf7a0bd6be28d0da8d7234492c7a79e75b2cfa25f69b36edf82e7f883c018157536cf5c331695c524aff16d0f8dabec19d53f0ad86c8f109b07955da0635c894cbb891727251839229e3b29bfea854a2c357aed142272aaf354c2325a3917722932d7122fa88e01256c236f0a517638c5c455e58797c3631f579f1b4fd8ad1c2719bc28031f8f72426add2c250764d9e623d586fcb28c17356edf6debd32ab0208ee19d980e8fd2 +expected_shared_secret = ffaf18d4fdb39a4aedc80c7985843f6b87a02e36c69dcb00f3cb01a619a77779 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 1ee3723f94a99b7abe01cb641c501f856398369804ab87a2e97191f6c918367c653ed9a2a2559a73db3f04a4ab05e1924d3a9af7392289a894057782ae7139b1e82bb32a228bc7bca367af59519e5ff9319aa987356c97ab724b9169302e0b2924307a46839a4872a57b00ad4f8b30265b5d6a3c95b31c248da1514ffa25d908915635732c1a7e2c938c4e528184ea2facc556eaec7171831aff013da5acca8c500038c55eb8521b14e0263cea2252986c9023c405b56aa85791bda25c73db65126967ac8669c197153c14275a574abf090d5e52821f51a479238360305cd7720fa3e239878635d92315b41b2374732216ac4eeb5650a4896b3747c752827407ca7046a315baa63d9717824cf51513639607cc752ed60e743b5f8ac54168497aae4aa3e4c8aa65b97bb03314501b8644608ff49aa197bc0fb427a13600bd8395c94d534b1fa96341f8cec2b218c1a5745275799e93767c44b128bbb0fcf59f1899593e9176f070cc541949b490bd20790584d3b54b369ac5f2a7eb24043155272534889be150f320019aa29b8585ccedf65ca73211ffd8a60f558b4482a1b0194202c16cab1699cbb9544b221c2cf84726608311416267d065d5a819bc05c54fb0c2406bbd4efac451090ce9dc93437312278ac7f7b88f0b69b80b7982f7989c47a18185d2437c1689d1378d01c14dea68b701378e62173fbad1ac05ac1fa904ad1a22895c52b89c8cb548a4cfe168846f996db569cd252281d62c675c298a62d1a38c019c5c08caa986672df818640a90002c12042c3cfa437887a4cb221b65b94a82d7102d07a16333177890ec100c2a8df22987d0019f65e64d5dbc544fdc3a3945a3a77a75099238d0774e9681ca16ca0e9c0554e0e401b401243bc75390b3b4bad59151128f8cc28c2d40bbfc89b890c64ecb65826f202912707f976a2f76463ccb803a945c946d282cddd40f5916c77e268dee390c7a823e5f3313ded9bdc39c2690f15834e44b2cb1335a01068955a3be7c635b7036a975ba7fb986295c3249916b3997c7f0e2845d24b9b264ca4d49a697d1abf3ca9ea6313f46c0cf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = pass +expected_ciphertext = d158917317071d0eff707cf8d3180bc90400198ea03f51a2aecd9352bc1bb1667293927639f77465ed33ef8165b603c35b03b898a2e251d775e77a864d8f842a2793d82e7f9a2bedb5e56046d3a9d5802b7e8580d00da950b709480931ef47ddcb0c16b2aca9f156eb8e1ddbc9ade097f6d6771fd77f44a1404289fe091990b81583784331dd372b27462623d810ec5a402e1ba975dcf833e7b9d13e56db1b048836baf7e62f02d97b1c17c9388a09644e8ace49be91530d8ed23327fc04b4d018cdfb6e78df8db7b978dfcc5629735e7ce98295257f29cd2c08262cc41f3fac96a438d71689484d772a638d5a685a93ea4d7a78372a53282e595b685d663c73929040627036439424d7a176266305ad6e381883562e98090508c139f234fa03b49dfe7c7e708a50c8c0f3426fb392513141856313ff3942d8b7265264846f0aa622c51ab6e5d1747aa930fd92ce17008c06a9bc6244259f666736b4e6a92c9a9460aef716aff767a1ab60d2f39c83b7126f15615adc2acfd109a5fe6e790b990994b1ea3c7e73a3d00cae090ce45a5ce26bf1b6b1bb659f0cd4174c934918df77bda5a227ad04a9f78203594f346754bd780b97467dcb6efa68ca43db645253948ac5ff4a0867a64a4d25322f2151561fc3c2f464a6d2c7780afd3fd45fc97b8fe6f21587e8d627d008433561119adf814683dcbc61f7d733ada0b06f00610492529bcabace21be9168e4a75672448398c924f0f74646cad64db5244d2ef05893a48369ec6185e0590ed71edaddcbcf57c0224e1f54b680eab6e624863d7d90bddbb38524c1b76234e4024bdfa0ae2abcf69c3d06e6c8c658dde6a8e7d67db96eb1a1b238add1be3675bd8d4fe320839ef2573e9edc8f7a3e25976bae5d3a4907e984e1ff007bf5f4bec8a14a614b3e7c7ace89eab3b8d98e4bcaedd40665299e479ef41a74a4d6e3407f7df225191fdb1153ac2a38220fc6eea430ca97cfef6bdf6ed34017e79293ed24552670ccbe37a1d340645331708b3c2f9bd21fdf5cc7dda112f49ab7379b2bd8cb05c9dedfb762bff2da3e9cc698611bd3ce1681cd +expected_shared_secret = 1b37c256820ae408a0005a1fe7461d54e53813e6e7ad58ca3dde46a53a44590c + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = 501a0171c94c8651b920fcae8eb447d9913047183cdb16374d9b7c6fabc86fdbbe5905805f50bee8c12612115ca16bac13160198873b4f999e4ba1c052767d7d5ccfb364c12a5a6c81232991b5100f21cf47c50c8566c32afc13f7b03fd9a2b09a807b198a4b2ce48d163b0398731c142ca7f13b3f95000fc1345ad1a50952d09c6fa42ba6b5119ca1061a64a5ec4b1323a5be3ecc97bb21383f6c559550ca985c53c4e78d0d660c6baa11527242e61780c52770cc3739edd2ae47c676753bca078266d565377d2aa5cf677945551eac12c61a0a95f6930a95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a48b016de4c331ea591bdd43a51a2109f02601569764b8999bf4cc987f25b3fca822f5771d941ab90a0083d6676a3d743e458381cc3971bacbe8c3a4871d51baa80a1c34462cd46ba338ba319dcaad92ba7e471658097335921728f96b1f06a7b84e8a74cdb635b904dc7a583c4a6208d894caa22265378aa24808ef605193fe186bd0565d2c32ff234b45e2726d0d7c939754592baa93297c28c6462bc0945ec2035e776b2e4526129443c1135cf16620ce8b12825321aefd92010283f6a034fe86474a6e18a62693600d012ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a85a1f69f7aa39fc98938b5bf0f8768c2020b97b1c06d1c3b8773f8d110280a76834fb9643b42fd3dc002e3602ec84b79cea4d9b9c173c58c5417531547539e1d61e7c6ccb5fe2152eca572c7738e2a872a711225e0922e1b219beac2b2f3ac82d68759d83a2998014142491404a6e51b88dd7a21a664a14d6f3043f67cb0a2a697d537f3357bb19a6865172653f183e396a78b7217dd0f18f1cabb936169f6d75498d9027e1c59c7ff8558ef138ed0236d20a23af399067d4ad57d36927bb88b4a0836ea06cfb941617db0efa049b6de6cce0f5cc122239d85391c56487c48b919764536fc11a6b3b3860d6baea255e48d007272a24cc32637665640ffc8c17e013a3e974d6a5aac78ace4a2c9a173240a9cc1c8e18ccf841b4b77793c6028ec75c5e4697a32b591652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = pass +expected_ciphertext = c7e28f99c5a07ef7f1c3a5189686dcf99618ea60d0f997ce8cecc5b31e6e817f3aa3502b4945bf769871c8c66f430369d0f7fd9fd6b1ae63a7cc1599e36b8ed2d8970e7e1be12b49d1ffab6aa01d9684b4de5a5f53915a44d454615b5bf52196b5042071075180ad8cfd09f08afb3b1810ed4aef9f9dd5b0437183c22b9b38f17a86a27677e7dc64dc2d5edbbff7a3f3c24e1ccca83e867d4b0c027e6a9a27048a6cb0b1e0f4d9ef9d18702e588b4fa3972aa61ddb24b75911838a420602d2934370b9c73e1b202648801c0eb654db3f75ba67b5b1b40901f679faee7e390080f81df9668f1824027aea2a43c2f1cd6fa9e4e394e8d766bc0e23172e4328704390d54e7a8e7cdaa3cb43397cf4e645e0714e77f5167f75d451483c1d9f97622320b1e9540b9d31512970f416ceb182a30d74fb9a147ee5674d83a0bc2612938e9d7d5a5be9f0e748ae73f94ae7fc8777a1b83f3b53da066adabc238359a5326f7b3079944e550a6e10e87d6aa3a01c5b5a51b4b5ab85f2adc1ca4fc9a1570f9bcc31f57eb521a71cd45a98beeefdced8f9390eb04fa812108e8a59fd3531eba0583f345b1c7cae7f8dec042ad22af364d9f228d594d1c29768205c0197c72db661013551469cfea09bdc4a4c6594c358fbb5c6b236f3ce65efeeaae38b0d78e26afc22087bf9ddbad098e5335de9bcc9258b1ba18a06301a3da939aa63a398ce8e15684909447d51b9d3e2a56b7bf9a4bc7e4e63d5824b58f1979297fc842a362cf9fc8a0b00db5cd6e3cf221e952b821e1f34112190cd623b8643d8d1c76b0299949c47ce4b09c8d2ee956d501b273f371467ebce9aae118c6bce59e65c498436ce4dcd9524351cbfe6aaea71fb2a52e5eeb54a094988960d9035e095d3377ad03fef8176f0a7c682f7794d7ce4d6a5be37e824d3874afa160b51896ab85ed779e7104577caa60250b0f2ede06413e42183e8a00101c8f0dfa2dab6c90e56e5b3a1a179eafc9df1591bd8ee593d0e24605b24aa7b7c13ad482bdf7b95b23e00e06f5274594e270b03a97170bc022004b850bc8daaca34a2c3598f07f3b98693 +expected_shared_secret = 12871c83c35db351c2c0b4afe0f0ce9fe1f21fdfbe8c18a485d5c1292faa531c + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = f17c93d23556b9361ab12a87de122ba9264dd889232ca7c301859aeb32611dcb01faaba8f794aa3c0b858ad75e82b51ef707b4266320a6a9ba4b3616896c14db18bcae601828fcaf9e895c571205070562208c45877780fd2a02b3c697634116efd504104709f75426476bac050ababd708f38fa075dd2661d9241f0c31d7b674285ba03cc34c05fb378ef68a3e6a03a1366b8b432186001c56b01169227ad4bb614dbc290e5a085b7b90478b5702edabc9c12544f9a2102501836ecba58763b10751e9db7a29590711ffb3ffc240500995e30318fdd141f6177c2673330fc558c1cab769f202b5aecae19d1479ad32b4e2c59834ab79464770ca619e88535f84c26e219790f24b1bbb17c2b1017464c1f1d102720f111bd2b95d9ab79f866c26c730103aa602fe5ae1710c4a1782caad0674129cdf8791d780095e5d8a659333149b0797472ac623a1a2ff2beec7306a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578e801c35a429e341af97b505df8a46a7055633718d57814bb6e2abb272c9efe0192c2b55ecc5cb8e389b8bc5992b037d1e72074bd361740aa8a86c63004c99ffe50224378d1c28431f599f4a701f3165c8f6030a1ba7590ed49d4300578985add03887d867a3e82b577574c398c56f21c34f6349b6bd072bcf8318e4a8244bec6f93fb84b6716846670945a33ffe53bcf4c82f8c52ae84faafb4b46bed2a9807d2569c90791c087f3af05b88b45345bc099e9ba4f3028c469a3b4f2a1ead50147b208f24b21c9c4582cdb8633a9a58d7820fdd0c761e70855259216e2a3eae25129b2b6808ec1611800d0fbb3ad6179480bc4391860547199ba04b3a97f72c8c4caa93379f559626f6a4a8da750e6ce0651794138c6b68d474bb70f41975b246de5953c5226606102f98a36b66994e2ec785fdc2377ed9c664a05edbfb694a2c5f87dac238841245733852da5427a0b105ea2612a06ee9019b6dd0c3fa034f61da229b5608751bc29bb13ccaba83832c8d37108be5943cfd2173eb8512d16aa1c7b3b7d5ea6491c379c1c66853732d7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = pass +expected_ciphertext = 990880ea7c2b60e73c47ec16e53b62aa6f69b7a63a927834b0adca183d1b8faf02fd4061cb625c7696f2800564d0c9d3c5ce34d34a90054ad4dcf273516e26ec7dd530e2dd83f880be16a432101156b0a211584ce4af6c5b5076e32bb80f2244b615758b6a5be01343dce5c978640ae2f216d0d96980d53b01366a45f066139d851bb6f5d2e22d3346234fe218be963fd593a66acf04c2b3180a01a32d1b440d5413a12a8d89b0a8cd2576cadbe34a73b5927661ff366d6c7d9b0c531cb84bc57029cb1aae06f1174c1de605f10bd043af86e930ec9741f8e1a18892da2378cadea297d2147d7a1ebad21e8567742230e64f5ceb52a1f5bb2576f7542bdc32ce64f5c9289f82f14086e3346fa0f7dc883dbe0515a02f9ecef57ca3338ae60e48f7433a88708e84fe588b68af0caac4f9191483446bb5db9c663bd212ba1f99714c20965d874ae06531f0843057e281ff330415c018aa8028f14a48d1293d2356020707b59829d545bf33ecc5c562ffe2435cd653c70a13def3eb7b1a98290ff8faeede0377072411263846565504b3fd9ce7af2f7dd21a51295c785a97cdca511d1cfad04e0357946c7fbdb5dacb74da3f72b2893b68057c440e19a829995cf19ae1c067b2692081e8abbca54b697fc900bd3fb5b004704e4e4e56be929bd857f2cab50898fa83c65c9a7d70da9cc409d82ccc6fec7bad59faf2ea233e09e3dfaa2cbb91e9a93d7d43000f1922373fe1f8c9428dbc96ca05db0452b58704029d4d8e6f4bc985a3679324f4b454833c9563c23589e8e4c49b357107c3ddb7991ec9f2963fe15c7b51fa9955407e8a0adfb347e0b1f30033c4299293915a11fa4b1a10bbce36f4671d46d5a7094ad05e15361f2e0e9b6b5435383766c4792851bf74ec3afe1d137a7bfcd4e52fc39e856d9dbef28604b160403f5f1c294755690584135bf1a65572d66bd82a8dbe5be91e43a9aa235abb48805067644aa991e4a68014a66002bc5ed3f41661220ee02dd61b4942fff76fd43ac5154197c798418421b2bdb60265986f4ea4064f44e8dbf2e1d39d97829c4cc4008fe82b153bac00 +expected_shared_secret = adf49431dcdeb29f729459cbf3c2b94151005c7b841eac921a71262d65dcff99 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = 623668ba98183ca92c9075804d082ad2d17769032e77c50484281428c00320848073a17bacd2c47ab391fb9472d395a6376b3f44aa625c36c95457cbec00641a1cc4e248ba7a7012904a73179a61c1524578f739f7a5998355276eacbcfe462f2a82776ccc04ddc089cd2407f4b757748089d10baad85a3819d52a6560970353abdaf08dde151555f92b6953c0b6c51a7cb882ec5c574c31619d8c824c605102bb8d836c68f29578432c8515c913189b650ada84a2b5795093b5edb2a6e0b13b38fa3db500c7bdfc8dc796c7f57a9b95cbafb8610780eb6787d36067f89831d98590b91d96144d7a4c0fb1c34455902d49e39fceac427d723b027709338628defc8a771a055cd8bb143108c9724cbad1729b99c8fc675d007b7c38ca20b14c04549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499170a109ae98e53b807ad277dadda57a4d13f2397c167ca0955e3148dfa1b502726c908bb283bb1b41b89e15780dcba45485ab771f19f1f0350b64a4ff983a5e68982523c1e936b9be3c38ad892b0a20b4d4ea2918498065d2431e7f950bb33c68b23167bb4693bb258610404788a37009a24823b81b95753bf09aea4a7b219cc8a9af4632d9c5e4790158071318e9119def243a30a7925f17233098d3c594f1571abaa0744f0e44714d0c8765559cc327e35fabe67066af141127ee7145546c89fd55a852712eb8c9c77bc649e847d229958e0d7a3947cc4284729209a704aa4640f0c73dd63c6e48651f62c33f2351f5d90bde888c3dc116827b16d8071a01fe02d1b4b485e9779217641f0a0af2434574ef92e180c116f44899afa647cea8403a831ecdcc04faab8faf3215d622dca40a95decb5a833206866068a6b49ee588151454eda821a35a5937a63c23ba0a0d8c5657d18777aa10492b1652ec2cdd22a7f800708beb1943ec347fab41219171fa46b7b58006f91ccba3b69cd7603645c9bb584282dbfb9ad584c4ec0c692a25795111a18709072be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca241ca7e50ad46000ad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = pass +expected_ciphertext = 4f215937409d6d013a250084ae82d22c2e96c529b486896b7e92039aa0fe6d9902eb0f0371b022a7a294ce0ea16e479825eaf645005f90c598dfb44ed713b9267f9ff7db6da752462333351a0ef2716a95103b1710eed9e14ba4771b831b89421bcf754eb368fe4c468b43a00f4b91a47d6e2ace48f79b2c034798f8d08757b665f3fe7d0fcb80fa3e76c226311742b0d7d89369166bb208ff705a4248aa1bcb4cf6258fb23d62de3d37b7a1d8d48a3e3419917bb6d54accfea58def098795ae76ebb421254e1d07f6a81a5833d6994ceb11216c66e61194604329e2ccb1889e0a7deb3577049b2fb54a97f1cf38f6d353371cf4e12c0e33c16f6eb9bcb0c88ec350a3b2f4d95172c0638ce580e08800633f3d24dc44ffdcfc93747846ef985c24b2b3f27ef2ca50c72b40297206fbc64f25b801e4ff22ca8198e00a8fbab61c390c9d9aa93c41a5f07f31efa7fc5d3e1ac75eee9aa2b5abb80412360a9df05c5113b64aee78836fb1da8e5e3a4b675250dae4f0a16f34736967408c6bfd0e73a02e3bf70cd27b7b3b0461fd3115de6749621822ee148dd3919de5141a4e5b2d3c61bd9424b4eb59c51d026c12fe983a0ee925d071dfa6f028bbf698e4d5a31e9ed71967f81c9f7967176f353550d6a5a0ceaded0336b9910e740ac439b66dc878b83bf63656fbb1a9ac95f00719295ad6900ca6fbea3c8745deb1ba64f4ddd34240c4bfc9da156a5fdb178bd7ac82d6dd8f8d091175ceb907ea7d07305745b67f1af18ddf260608d058ea034f90c88ec87cd29c5f3351df52f67d63d4d0d810691c16e3f2bdab6311ff03247070e717902f0dd1c3f19bb04aa9be71761359d27c3f62fc40f4435e6a805c4a7284031879289f500fff831963a7099ca13c9cb6068ee7760a6f0704b20810c3dabfb29df713d0dcb96e7e43c3c591b7911ef783559e5ead8895fbc6093c2aa63536c8dfdc77c776e10e425fba44138235db7235bd69ba92ab93aa9389bd814ceaac4bf171173f9b958ce7f10db1aaaea429f28ccc937dcc043b5c0e1eaf4ac5601a0eeec046db5c0abffea6134a27b928fe5464 +expected_shared_secret = 35e1521271e7ab9931b2c25d75f0f09a89b3f83a6bb62ceb99e8e00c5cf78afb + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 8843b50fbcc8bbe4aae3f4c1942926ddb8580ef06adc73a7f869842a3211bbf36172ac6972811c887b350b5189a376ad6e032234c0840dfa0a7dab2cce171e47e3945f2798380583e4e2b1d5188b18bbbab2564a0a06c174c577c91000e1dc3c79c1a7d54c38ffc21dc0e52e62a3c093a30c0986aad289b0c45841253c39a1a00b90712f4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a630a00a4585f6a5ba1c0ab2c16450e0a30ab06670465628d763b5b0326fff11d5306abd4886cb304a515389e3d9cc4664039bcb80509661ff19bb372a8c8e121c94f5103994b91448982bf1627b38741a8560adcb5101b68937673a2ed345a6fa76e10b2a014115eae9b4a7ab8ade144871fb2cef1b10309a6ab67b218671500c0fa5ece8952d2635061524be47a33e4fc06eb1409cc4c7bead4a0ba8007df2b0d475a4312f042cc6b75b3484b08099c208971a07a054b701c193cafb509120d89579e282b07fc6ce1bc55c10012ecf1399c910b827a4ddde8995848861a8caffed9a284b829de0bca22585024d4a2b5946c5385267e9052141a5e27ec2b75188195d7c693f8c64b4351f2bb3076d95db950905087bb14d87831618e9beb5583064fad4952eaac72f3a3079da32668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab6712c40b933d663ca9fcb3441c62477e3209795150c4da33c9fc13b0e421d23a9393a76728f55261b41c8dac98e48c24d91701fe6c719d8964318655a0f9bda8e1c876c04a1b729951f5111735b3558162c1e27e6a9c0ce0ba0953620d6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c098e07607648179121d2ab55b81ac018143724015aadd1b730c274a6ec281ef446a8468515519b1477492e5cb87e0962bd9216f9863bfafd025b0e00c58a709d200be9187b654fbc6f76b76092c1230526d051836ba580f90e368a4b201dccc9a3637c19799465e3685eaf51bba70610d88b6f08bc6179ca607241b62e54e94f97257838acee5a9375b347d9723466b6609330a071a3ff9d1acbeb4c41b0650616689005408bf8c292b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = pass +expected_ciphertext = 30344d0732fee736428a73d85200691631752da1285f83dbb6fe91e28e171734a23671d1f4ef6c3946bccf8a4e1125f7b3e7fe573b69a7a0b8d1087c4fb3b6b53962e0c3fc1ad0a90ed96ef38b56f1cacaa428b3306c190985425f6ac32d885472d536a638195356a8b800b16a5af5db8b52da23780ea4e91c8ade09d521efb66af3e5c2435b2f91a486aa44636ff831c043948249d2d302ba900981a6d01ee3d442753f078a2bed76b0d805eb6e5302386ae5867eb71d302d8e4ff8b0fb1fd50c748aa9a0a313cb5774c8652154cc818b6c6ec44adc1bed7f8d5face8306d3ee04aad9f5c5767b790c3d83d37d817daa057020a95ce974270274bb4861dd98b944056f178c5e77835af65823cc779c647242770097eb426d905e5033d8ad7dbd272aef4849801bdb8afe41fae1a45604f6cd89e38775f095262bc72edd6032bb24fbb76010c443233c8df3ec594d30f58413935198880b227d791e06cfca2578ba405941618af7a7ba604bf2787366349e96c498b82c7121478e68bc632f9a02cae8f964c9fb4b7a7c2d2b1f9e45584b505c41c1af3d0f9c46448391506616f97ae657c5cbef42d47d5ba6fd99ca0a430b3ed5567aff41885e542950fce7b7e6a11be1d4ccd0156bede44904ced82160a89c5efa6dc0c360ef0905f4d21f1e6cda38e8422c30e3bcf966d476518fea22628f7b6bc84fcabfb908e203d05c731a7c59e76edd7f47b6f6f1be60ec1cfed497e4c5fb1957a1c02bd64c8523cd2e1e807ec604180cced79f5189473557fb7272c0772391e4f8e4fcf7774c1ff455f2817ffb83a4988d6f8a8cda9ebace4064f5e55d1f258f1a579374e4f2105b5e400f5d03e3d2462bf8a2fd5c64c740448e7823798cabc220f00484379b75561f01f6c911e253f0bec715fd6165a299acb7de62390b754899b76b5085ab75286178895b927e21b08a9c7f96febb4dfba433913da7473145939715d881459ef850b89bcdbd5833268a1b6dadfadde90378ce71f92e462ff402a5205af2b0fd2503159d803d20424ca6b5f2864aca6ebcc1ed24e3265ac46364d60aeb0bbef62342c +expected_shared_secret = 715519f07b29bbecfc0776e35417558e3bc50c76b8da6fd4c99391b7bc7873cf + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = a9f0c2475a69f1e96c610badd664c99895021f497c13111930880c02d9c8ad7a1309085826b4116f9a9cd841981f766944137de5587323dccfbba28366f86ae7a7481c054b2dbab86823b77eecbe7d9088a9ca882eb7aba5aa23c27209df4760e70b4876b709bfd225b0ea9644fbac9de01df90648a25b5fa9a48228872ec2cbaa09880100bc24f1414102d92a5a206399295333485f00c111ad49c0fbeb5f4149477e46075377967c310fb5231b9d6204bc877c31c524bd76b5edf23fb9b091ffa3bc2ec64423b02f673505d5c69dfe472d8df62f9775852b901000d84e4237aab4f32226272766234dda706fba5962e816a98586bc2a5bcdc1db80bd9b18bbc3c82d01cb1b67369f32741d50ca57a45c45667d5e5428824463c8a651afd95e995a4b860043cae74e265aaed3320414989a346a63f0f0842e59972a91bba62559422705ac6422d66098747a85737abeb01c00b4b90311081a17c6403726ca39e27c8d426845fb624a956c39bbbb404a8ef5073e37078ef535b9eb581783eba401243b02d750f5034d4a366c197994189846dbd82712663a0fa0beef5847622a904b04983b519955b717025c01d9e5b928d4b860cb0fbff76fbbc22b4761a5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b090aed1c9478a68ce883cc9b8960e8755485099912dd509e9804e33e86a12a75b53d42f0c784c6a73732a471e44900d41ec9c4c0b006910202b1b2dbebb65b5d7471f189faf194e642887c5631271649662f4b235829644198bf8e965d9728778a65405c4417eeb7ee25502618ccb0a0a226945adb0d73ffbd2ca47a5580d0803a56b3c3bc66e877ccf05741e29501bad787d8b588f97c20c8255687ed3aa1631122c387456088d1209c4a5475f61d12c2b60b1776244512a08807c09e7c7aaa3935125f235f8e872bc4356a21379bdb84a25b132f4449561e96bbf8776fab1c681d42575a1bfc0dac357653996d41aac4a9341196da05c49ba84a4cea37c818ba0f0408c8c9335616410b1d479ca035656119236ea9d6979366163791648088fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = pass +expected_ciphertext = bd160d98b7f46bf964b76e201dbf59587476e0c3aea4209510772e34afc0790ea5f388fadc8e6bdf3510d4c2d1c3a00f3008866b239005beea93fc2c2f632bd6b30fd8ea0808e066778f310d4e0fa946b135feb33aa0a270e1bf3d2197891a4afac3fac4dafca110a08c120658113ec4caf8e5692b313f02726d8f5369790e0c3c10a7a4d852c8f3f6c7b1e064ae8ab171594cedb913cbc922cc7088aa99660b03905531adf3babed00fa57fcbbc4a9be2ef43ce6fffabb792a16f17cec3d09b16a6109c721057517b50195112a67296a14ab51ff7dd6645c07d1eed75b4ca6b61fb269cf3aa82b937c0ea39412f2900c56b9d7af897b255573c114d23e536880d8f432246b8563841d54b673fc0399dbecb010c535e722b1822de018928ca2657d40e6d934c20d833d8488b44944e2af6754c5bb2255576ad58388dd4051e29fa2e99c8dc289ab8c38162d2c0ed342a8050394c695b4b6c3aa81371ee37f47464337808eb02b8cc78e2f01ce983d43298fcb24ad3f19fb903cb582fefc9a0b966c429c99f1668fd9f56b56a40134da74dd505d6b16d812b1745b47f603c7dd8fd205612c6be07994ea7bc17842d601ab0d54b4983ab92ea8d2202dd69be38bdf0acb384e9555048da6ebad1b28888faa64d5d2104a833f18966cc4a3a30ce23ae37e7b19db70694a2f5198411894d6251b65e7dd3aaf22fd74c38fddf38f797fed4a6204c444fae952bacf6040696e6a0b9412e29779f74679cf4d44bdd9f2c2f154e2a093fa892f71fc65e9854ca64a225deacf54020af1bb62243540262d2cd8c3e74547608f82cd0af6cc1ca3329197958f9b0b64949fa57162afcfd5e087ef5c5e7b6916c316d6278fbeacb8b4cbc16566eaf17b569c8cd80e37afff1a7fb914431b25178e881cf1d0d66199d9080329694e03228457d5dc76e28f32cff849e5533baf254f08d15f223ae5c4c91b1bfbe28266ac99d8c0107d7c32b6df0b2397db2281b43cb609eb25c3f02ae6bf15b6d19ba0c56e878a07fe49ce56830a67b46b44441911c614ae9e491bcc0b99da7db92bb8d2ca38c65ae7a082add92 +expected_shared_secret = 5a4ba3737140bf227c0e618f74191b3de1c1b8e24b032036942de66a13ef5a91 + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 28376c399946f6089f4eaa70736726a20c6e2acc75ddc880fb015477d3ab44c36e047c4bedcba5e2d775628154eca695261b5825ba495f84c925f73c5e86b59fca1a535906c29b0546134469aa2fa9a273e987c50f2b5c1f0b52d79984246c653bcccab49c172a990a72d93ce02c2a9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f4715b977580345b13cb945ee374a980a3152e1690469c47f8310d02ca01dec8f1a149e6c1a1a4ff0496c18c8ebc67b79127195341b132947ba62a89871adc0c9b32d951acfe88334189aebf89991c9b73eb0b68e6c2aeaa1455aab124160179ebbcc40667ec7159d8991897cda76e31a8330793fdb035feffcc74e251993913c6aac99e5ecccf5f9289343989bab7640c9c2a9e2c622d0214cf9c696e803d9e119af0a90fba50199032dbf491fa5e260cce4b92b8c9892c8519ab23031d9c3c53c671a4008e8ba31b3d1bd4c9602f045b92e42040ffa00f441579b105562d507d6117a9f5b9fb6e50146ca47faa64165c84a3c9a77a70963e3a6a8a28b658998078cd91cd4599cbc21ca68d13395b907e395b581b490b3007af66cbbdb222d78973b7b69b37c77547669695c347deac03374c209fd163984f03f59a6ae8de53a169041c35c99a4c95f25a759ab6b2f0fda12e1744a85194ffa736be1d67d7977b32eb7ae6bc04220c8846f157aa7d05c12c02eb8d3053059ce8ecc34791953f00077a4e13c001a48c28500c025c4bcd11e5ff83ae9e31e0a6788ad70a71c1c0d5da418c6e6934fc959d70259b606c986c70348cb7cd11a46be201c474b819d8b54b538c78a06a9bcf905da7469d9c045686a3b38e345e64994cc0785fc12073ce961763074f4d2aaab6c059fb67c947889dde52c8ffa432c9171cd16133d337f10546d864b3cf3243b2f3097f3314976c183128aa1a11916e6365749910600e64d96b663b236c43339cf979c717c6b03056081d9ac4301722330e13cdb0a75de4a4099f7a615419c82e10c6eab027447a78303697d8089647263c0b39834986f8da41566dc254891bcf93014b4b33e2be203b4e2c67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = pass +expected_ciphertext = a04e02caf38c63d95694ea94d21ac94fb8439fbf40a4b4ad80642bdfb8cb31c619f2eeb2005a0f0b75c4e07cdc75fbc4f688bc66d1deb0c0c88b19f12d4b5489a04dc4fc98557f97f1181d08e88ecdc16d15462ce5a532c7c3ced03ea2c35e9c7d7b0f4ceca12c3915e252ed94d26e2595ba49444cd22ea89436dd6e77e7ab41c616776af6469266cb500ce53607d1c1c7d6c6900c98a2bfce54877eabafc3b40d09e6cde906d9c86f6e75e80e29c3630184eda59e5fbc7699a2f46135fafbb606dfd6b4375c57864737ecb1ee0acd6ada573d2315885e8dca584263253a07daa6f120bcb35c7dd366b207901aa978756d34c54a0737a0869fd0a0e1167bc4895670ab0cdfbff599d43a34ef1a9eaf8761f98fcf6cc46dab816793f6c4afa2f62f654db94f1eda6539ec7bf7b7173e2de335a32c458ba83098533eafc44093f4297fd1994b809a3e6db0820307eeb75a93012db0932a46229fe025f6fc2fb50b9888ba4f52e628f3a66025df605ac60ff58025972e45f75cd8828b7fd8d338617e3221dbe9f9cc4bab1ccbf2bc1ac0b7c603d15f6268956b18bbe3a9a3fbae369144cc89cdf02896e053ebad7ffd16096a8772dc9c5c1bf29b1a1e3f76d09cc2e5b4324e551a7d097c726c26dee259ca0de91676a20b577b12d02a127a81dcaf489ec1af1eafb246b5f36000f77f57989f4e187862ae403b0e6ebbba782988b3a1151f7d3bad63c4f217f51a351474ea782fa006134469d2d87459ab774eae21823e5fe6a3e400b2da3e42af4f2d47dedff032b11576729e9f6c8f7908b444e788575aff60bfe2c836d8b3db9ebe5cd01e50855ea26017eb9a0590668cc0f1d863961678f2b29e087b42df2a4067d711db59f78fb97b393db0abe343e151ffdde87a9a0d1f5d401e1994d0a37049285ec5eed3ac635163e3c4080104c76ab2f452f20cdb37785ce1ce5aa33f9ca4f599610c4afea560b0779cf0c3b1d0ead1fd8a6f352c6b1ed314d13a5e85abeba7987a0624a9e7a6e9e1c711c88cc2925c853cd14971e67a8977e67e649a975924f63c8784d9f3ee80ad4fc6e1541d38ee48 +expected_shared_secret = 87528a4a961de06d5856004eba20a44590a1bd88318fcd1ae1dbfbfd41f152b0 + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = 2972584323c917fc24681b6168eca204b8210bb3029e05cfb2e08d479b413d987152a0203f0ccafc45625647b57e3796ac904643c73e9cd26653600209a62bc6498de68223c990672470c2a2b77289f41f5e07ac7320500a7c30a9e99544f7837dab6e7b7b7652751457d96e23080432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b576a242131aca3cc9c08833304dba85c07c212951af1303e91206f4a54c45e9ccaa1e96fb07bc27707311aa2a1438a9ce7355dc5861592a4cdfaa13e66245ebe67610de4875b57181e118930e671b34104a38859d203ac064b417a30aa8d23af7c5c732f4c57e8359f0b698de6320e0940a4754904bae082ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ad9109146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ed52e2438b6132400f3bc06f00c71b6669f02735229b9b1a5b580cf271003b498a6c6826d553cc736a19a6cafe69058ae8717b91842d92bbdeda0670118116b719264465e61d86b975a843a5c62a056b9af8a7cd402a747a6b758da977b12214608cea52540dd390135e28e6160468c97b713826dbaf27aec20b34e07aad340351a64223068318113c5148861aaec535d15368a6b096b559f57b2842713c44d46bf001477ca0c92bb47c5c502b4e5f22e7aa087c26bbb36d9acb0712af2fc7c09e55f1fb71238e33d05d41d186790ad725afef46173134620656449917d3e52320c8542e5d725ece72390f637af286a8457165f5622608c0813da9c78e83334005732246091aa5877e7ae460c18ba856d030a856a749d2740689ef036fa936ff3e25dedc97a72f539b3a32f286a02b79472f28089a6b4b9b42134b6ab252f377e819c233a16be6361a59b4a9d52aa18c18263fec2602ea9b8e9164bca2946a31a892093af891a3369a01e169594d0e50fd5b3b144405ba1139a8d167564943530a26522f3216517144937cb5a14b98300a03d6bb2b8c13eb23355590cb5989a4e26f242ed7b977a36c65e768f21e9417f3180c304009394cef9bb74fe1306337b7100938260c68dfa7910df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = pass +expected_ciphertext = 707921441f685b510f6bb24a1dd8cc65cce11d5ec420667a9455c90991892b0a707ae2d3e1bfd2371927de187f9fe0af99a69916c5e43beee042bb17e88406e6d54de5775b92588124872ebd3ceab5ec658a593514a2c669ff597dec7c1a00c3988f258c6461be0c3bcee5a68328586325cfadb60b9f9ee4824a9b7393116f691b7bd39f86edac4aea70b27c66d6571b3f7d7ff867476b69d8f10158cb013b379d5ee02710948161359c5d0434aa6ca35b82c0d0c23597e7764edbaea53943832207f3f403c40af1afa2af4972cbc91b413a89c0d6ef9432b733cca2ba1f1f6825f74a8986c1224085a81dbecd755057983116241941ddf76b4130095d01787e047711c8cf246c03e1d8c69e5f212415261256d1e232d6711a7d7db344fdd7380f20433a30f60799f39ecedadecd457db4ede782c281dca56a65723af91e57eed98bb1c7d2e4d3f5743e6fb7d1c76dc1225ae2c052e48c14a371699658c66e1b7f074c5335b2b933f259ca993470554cea8c183abfbee8f7d03e16722d8fc82ced63d23f27c3197ee14d71317aed8af580721847ea01af787831e3519e9372254878af3891880ef159992966e5892f4908bfd341cd3d358931c7693bea197877eae3d6dce7c7b5697f504a0bbfe0778dbc8fc55672acf7ef4e061d66856eecd79e8a8e45053b47c42e991516d1a16c20787ee76d855038ef45d3ee412dcc91a68ab1c2c844eb0c1682cf828d9e8e083a1dd0f76e7769eb56e447f8ff9de176e111e76569afedeb62bd77e448cdd24f5199aee96e416a9f7d7497017bf9204cf11eed2d29be791e50b6eb2892ff8cf232db026faeb137dc69fff3889df9cef163268608df15a3fd5280651c6376502e693410d8464b45974b3e6e3d160a5034d13e50bca4a67a189cdfcf955c7f4e10abb54b95123292f33dec86f86735440a18c5b2079a941549e3289047c113247861562a58fb1aadebd01c6249be461fa05af00e22c6aa0d75d4ee41d0dd174c6ca05eeb4fd0b8a904978e632cd2c6d4771d04a4952b3fbff04e86e1de51f11e53e180f67c0faac071dbd42e93b044823aef +expected_shared_secret = 3652a13e36459a324958a2c45328fe4ca6163ba833400e643b0a6e51bbc594fe + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = 3a090559a1773744077304007ce9af65672c5f221ca99685b84abb134800f5616b734c184107c8c5892c437b8aa3d0882929b8dbe394c1680e33dc2c706c8db227c292fb0a89a8a29261bde4fc1dc12663e8ac502e473e58d6206a90602ed87675287ae301d0ae94ca923ac8672a031b5840de90121b72c58310cd924c12787428adb9b09ea0b8a2226b84e9b5cbc2930122b5027c70a694238f78c8381078393178c936b8de4c204b4a31f9f72bdde751cdd0b31b2c840752181d838ad37c637cfc7584f37686fb3a31020a81db35c5f7af49071470b9c468dccd7c258780cbaece579819d8c766e873b6468718f60da09539fb7a34de11a70c45ad71918925467d8807cf8788318fd010a6a57ac83473d332bb9f2411cffbc7eac87cb7c9b1fd456dcf74896422513ae691cac20d03172728b11d5ecb9b9c8b520bc628eb5724e1b415fb8b99b519c1700537c2a22a2fe52e45a748ad5b7f4366b33b5a2cd8192f9ea406e181b4ba47459aa08033498b6c1cab1fa0327df5afc5a87f0806c6b26159886b40b3c8b068a7208dd12a7c150a679cbadf3b27457883231a8c351c04640099efb363bc962262d9570ff8b425d206227175de94c5cc010d9a3277e2c0055d84475501877d608156868708d5c725357b9df9b47e4c9d7819c310900df9926c0ef230999aa2b420860a6b7fdd020fe0345e8d539c5c839c3c11a270f360e2f93fb61507fd86442379029737823bdc445f05a9ad3c7e29804068fa96035a95459509b53c426e9188a0f016e8857182119ae936656d60072549557891c4fe0278791b58e1d0bcc4b322ab249865650be6946f319c7f0bf58c72b819b79c1b78982b2e24a8b15a1c166cbd3feb06eda478fab90ce7b16935bc4880f78f7d2a80b5b41095a53f19f46ccdb84bfbba460d1c33eb923eb56024dd437cc256a610920a650bbcd3f54b8ed8b1b0814e6f4acf94617e2b68735210bd263597195a6b59864c21e371c1d947f6357a4e064fae992dae617500794af82a5911c15dac3416ffb21ba5815b79a79c30ba72b66bb5d8d2800e581579219b2f0688d87a1346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = pass +expected_ciphertext = 568cfddad6b6008a4eb850b6d5b35083bc298a468567658a73789915ad9f04631201c39bf6a2b4ebf403c67ce5f110cc92385f93be982591a806fb97a02bc0a7125242faf363a995f4ad0bd6a18fd0e01e832993665e7873473fdce1d4eaf2bc972ccd0debc6dbac91db1e35a12185f26455505095b47e6bc92eb110bd93dc609ed7b85172b6f81a565b77d7d83efd1c3ff7f7a0060ec9ff9cbae48b6a295dd37abc2bba98a94d3d5323e30cb1dfcd1031a5890e8b7545e11c79ec038521f053e6e071c0393b9800383dfd761df12217159f53d4530d26f0ddf8f2f160ddd012e66f733eaa3252e471c061a4b11f5f18576355b8a3c9cc4f8a513d3c7f6a4910fa7fa9351a0dd4bc6772df2ffd6606940d39dc04c46e22a4975c3e4dc2d468025d220d3db4eeb2937a5e5c7840fbfe1295ff9dc4083594bf697afcc8df13a8294f3bee2bc764bf6db52cb72bdf37d4b591c6fd63c93cef89e8cd5e4846f6808d85a00bb69dce35198c2970383f2bff0daf4ee5c807c6d2a3eb33ff61ab871c58932f548bbce5d12fec74ac14b70c948f6011618d067ee17ceab188cbece4543058ac13b16ec58564aaad49816f9a6f2b6f1f58ae891b22bfc37a40077b2f9a73292355edd718703690c48675837fe8caff5cb453e4e4a58dcfcec3aec9eadb0e1c2c9c486d4adeb5be3528e0084326e94a0c847a2e4b55ffb97be791d5ab6fd51f389aabaf637433679781b8874d602aeb40a239814236ebd501ca60c8b6366bcbdfccb9c8496ed05bfe75372d6d44cac9601644c47b93f21fe6087246bbb31f226eedb520833650a77c8232b0f5667bfd28548be72ce7b091ab562705f1e53b3ba27bafab531b490df1317e28b62be14e208f24e647504aec816d11990341920f6eb6a4efc399d1cd97bc20c1f7da4c188f0754ac38e6abd40828f9d719c9a8215207fce4f620a02c972bf0ac48bff55931f3a0ae02f0d4d080cc92afcaf634f39ba847bd4d148f712ed4825f43f06bce1ab6a7dab906c3b05c7573f0111dc8cd9e0754d7c3f00c936ad3eadc1d438a0d3a79aa367da7c68a29c38d0adbf261 +expected_shared_secret = c07d965e4a87e89e9fd5db44cdf225b20157a6842e2862ecb4f72d8aac933c2b + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = 1cc61043d28bba4a2b4ed1c19f1369c6d7578ada06533b0dd8ab5afbb3bdc5b601ff108031d017b3d89aa253c90c7a4a7e368d528773b62c6aa38046de9b6651cb1f5c353a1f2c99a3e7bbf1679357219417c10b5c1c60348c5c22424807903ea4e9c685aa5b53da5ff92034c7c15a51777d7a637529a274e767539bd68f2b0281a8e13c08210f17ea7168b210830b0d07bb61e22b2f87323c8debc3c97a399de71590a23806f1903ce109ab804c5657290407463ae5bbe24c7fa62230c83288eab45edbc28248d89890491b32ec4d214263557b053f0642f327c78d3565df61796376a6e04a1d068198125ca6826a4c34e65e30a7946deabddd3062178253847c37f92a9cd1a749f1d12fab1cbc0017b468426d8bcc26422cc85e97199420a9367000e7f52e17b4bd5dbb6400bc42182cced4c564ac160d2932ad801650cdf29ca854a0b2d8918a3a2320c5915c1b37e6b3b0f08280fde7c6f2543d2c27728dfc8eef776ba012860ed55906a3a28ca88d5550b540538272c01ea0f83b78465ab8f062df740da6d31ed95a53b5ab8301b79d8ec6a5fc503bb0a6b57ec99085da37b3262843017f9e572b15c7b8aec40ef66755a1ac91856a8d0c8a0b1572a676b8ac671908c210c82c5900abf4696e2c73ebf3ccc4b76df3f74b930977fd616d31f48248c578a8d63b14bb48fe5c259f9734760944ae78164ceb699b1623ee648330019d79b49b650a33b841622b0061a4b79331a03da78b1b70a3901f42159bb4bf7e1512fe8483eff80e3e241bd94aa8740862a3800313b0c160a1302122951b620255d6c8beb52c7aa2ca1fe1858bb60b6e6077a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6d0058bf5477d358b630b42daf131ecae24e7f33960841415585101de67d96e2349962685fab259c312d175326268c807e036836f75d43e61cc65274e42b37d874b2c989044dec8aef59a2663047d8f6a0eef1649d7150b20230cc279baaac5e2a30c84bb1bb6475bd2d4a201863ad207674f4dc25a3c07cf9fb25b1d83b9cd3942b50c423d0b31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = pass +expected_ciphertext = 357e8eb402ee123bafb911311cc4d2400ec533c40ffd581c4dd737bcadf9cc3ac06e694c774926de1840ff94b42fb313978f5000930f5e2b8ffa17785e28d9450aa02c8461ed2432bc73b6a9250547aaa1481e86f34d0a82c4b5ba0911414185b08ddccac3a66b175a122cfcf5c171a89ff088d35ff2ecd044ae7f99ca8eb4b446987a5ab6874737281ffbaeaeb84f868ab2a94e5c0f53c05844047845d33792752ca59ee9723cf3ce7ae02ded0ed4348211d1fa1af4d356f272ed65f3edd4698cebded1167089e7ee17277fe47b16ffd45ce9a7feaf0dc6fc983893648e2a2a6ab5d392b61859d657b3fff61b263f40e189f42940a381e34c20eecd8a1d3a347641bb386bd2b8bec1390a62c8d3c139411daf513b16389b85a8e3effcd5a4d54eb906a36603be4c68de357f5d59a9d8fd11248504928722178aec21c4e5b4a824c52a34e1ff067818eb064ae899b5dec021f53ad07bdde56caa10fd0e1ba32dae976eaa6907259c5ea1ff6270b5d8267d29fbface8dfe1848300e60097b1ecdff39ed0be6845a74d4d271dd74c5df7e513108b84658a5869165642bfa67852090de4bc47e4c9ac130b3eae354c191d108d9a0e9393c9a8925bfeb22d00a1d74819d08cbd16b4af03323d0311c507a350b0a48b0ecb6fde5076a0ab1d9a65aceac7e3a6674b9ab87201d6288c65fc1a15efabd9f6e6bfcd5ca40140a5dde99537026b2a293188a9b181f0f1ecc4b0bbdf46056133ea4eb884569827dc2ad25a298dbf9d701b2087c68badecb86c8cedbff6f4c2ee3f20f1b8b7aa1e0935654dec99fa31ef627d24a3a48095157d037d7716fc1ceccdc705786b7143c11272060b666a7b723aa290ec11e95381db116bde516b977f55c26f35892fa081f323d3e02238f42a3fdcbb7e429bdece8bd51c02ffa135baf406149a471599f24bfc7c7e26acb6489be9d40abafe94c2746f0ce1dd3dd05153aac61926e4d6fb3fd85fa019cad88d67b9b2a408bacea9712fe33951bf8f7735ac4935bfb8cc9750b209e993350581aeee54e544d383d350de3ae5fbbdfff030bf728a4f970ba25aac703 +expected_shared_secret = a502041eee317af1e9e6f9a9c12cc98415b358ff179d4d64ba5b7463a1f33b0d + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = 8ed95fa3d30d9fbc979dd7cd223a3694b874c8272103685e3bbbb8888117d53abc7667b4eb158a34953147354f6a5714aab10aac07299c3038fedc9b0d3553734401be62862ca82277f57f1e6225c5206a86e175ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae5b1b521c6af59c721ea23ee2ab0ea2e451a8831a82d098e924604d6b02e151bc43e761c2324368a643ea23bce9fcc7e2502285119343603a4cd5bd444798fdab21d5369f4c73477e3891aab51e1b11cc55b3ab67cbbfd5f141715a9ae4681cb0f0391abcbb48ac63c8a707677650aab59c09b43dfae8653d887a6c2c0664096e551929fc0a00167429ece069f0aa266c542d28db4a42250fbff86aeca6a709c9a25f384effc74c0c7b32b4a616ef2a140a8c96c8b56e61f32963505775658b6c81cb40c2b99e43bd8fb8a8459a73d8d083ac178225461e83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91a7250499891698553bcb9d0848abd391afd195cf39a6213a078161d7ad1aa5b28b1c442f6ab732fc14dfc085f2a6475d4bc8f897a7c1d3b3e0c1203aecc5d5a8287e34c6e3f2a920ec8065644a373453cfd796a58c03b7e241bff2986b3c6c6ce4064db18137862d716c54c154a7e294b218bb1df2d76f8f36847288c76ae21e1967719ac92aea8b8e50706ed8cb06492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4626f29fe843623a55c02b1a0250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad196098b1a1383ae99f2ba6384a1c39c69350fe22437c1c00a651aa0932a771e09e4efc1abb893639f1340ca76a8cbc4c605257e14969d83cac02d131dd4273ac467b6db186e9086548224a4a1526f769a90c93101e26a2c1112744844b0584343fc9b35320b841961fa55016c9cb271570bdfc501d68f9557a920db4920d15e2bea64a6aad743eeac97560bb024c70c099608e55d351fd1784673635aa1b26b9248528d069d031658eb2c559876a7fe6adca630e2f2589de2aba5fc24528a982e2e5ce88a73b80121789522f63602ff0340f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = pass +expected_ciphertext = 563633a1c79ba64bf677c7ed45613705e7036ad4df441656581c9e68855d25c7a5080070db9debe4e503fa6bf3642d89cb52d5780ec1fb4eaafca477d1e575ffc2d16a73d4a24ada0b16f4fc6fb4db8be6cf5cfd503525ff0840a12473f4a52fa6a9d123177063dfa959ed7f4d4a17d2ce765ce65e6001131bbbbeeabb17059b92bc08b341d9f83a81b29c7b112336e6dfc263590a58abb08face7a7052598b871229b7c5df6a35599a674f97ba24da3471461e609ac76df16fe2496f4bca906133b14b72932ec5b53aadf3d1e0b9c7ff4426ce55626a45e794f1948d935000801f862ed2e7b4e05cd978a360184a48f2e32d5d58f5ae39273f8a24849585f19f3448dea38aa445e37db97a35dd384d1c13689a30421404ba60933f0f3ab4e2e3792f5dcf35fd780f9a113f29b4059312fae64df783df2d4c92835674169cd81d8805a44a3e04b7eb38eb35373831bcece0c56d41c662a0085dab366f52d336230c403f3bbacf23136176058f80115e29fb5e1207622eb6b57a14705417f40fb7916ed6ee40697f67d61fb19f356a5e2f45f0e64d42e0272d112106c531bf4b28f3763f2416f386a2aea3b44e2b4d25951f3723d58d3b1b833c3e573849d55e80716edbb41bb2a0469f160ad070064338c4295b1026f116c155f12aa11cace93bc57d2ba955f19ceb1db3c047380fb77be6c289c35284ece26df6a6e8cdf31a0065bfbfbea7c6fe81348e126950537c44521c835773036f8a7fb2d6632025ac66229c8e687a35c1efe6c59effa7b724df25425ca46e56f95ac36c09eafc00903ee3b821bcef0716b6da4258c544d28478add62025dbc7841abce4291fe8d6c4b58b97ca89f80887078702f4e8f2c823a07386c82086bb72ac8576cf6abbdb61cd195f21f89c842fc0cf8d2564b8c17233a20a048f0266eb658f0aaece01f2677de0c505cf7f07960f174fb32914c25deb4a5287187ed72685a04c9133e4da01e3205dc60fb1ef8bd6ae856244c93049f9a5fe744155f997af16a389859fe98ccfdddb421046bae0f47d91c6392e9a8b0bff226a64dda4d42ad1a443b904fdea5 +expected_shared_secret = a354e870cd600e5a5951aad3491c31a80b0545c1662f830d7f0b6d144ed3733b + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = fb32553b02b45153901b5951ae055f75a270a6f1b4d37cbb975b979278aff301470513b66f58817e6a5b2ed17891f24a84950be275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb89267f12daea09828f143cd6c7c133a38ce82788a6bb88126956f30943169b2e4a18357e43262d6350b07651a6b2b2b227436405ecb5655e5892ab1a0ce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8fde25fd8aa691a95ccc7da9df35393213322f50a61ad4113c094cdaa568b1f43517692c4918c2590a221fbc0a313d2b4321b9e1a973492bb519c010ced1c590f0a61799832c15012e04550edc12414f4cb7c32ac3a1bace2f9250caca0d027bfe238344e278d6509796155386c1ca904c34727f0772c12b66c2016cd933053106fb4a308afc2619f8a3ec5843bc2c64af8d71f86b6836ac3941022a965bca96de03a5982a8bd7730141b4232610cacb6684db89eb1b55456aace6df449ad5b7964cb4a888148d472ae45196e8096a87b014fb5954719e82d8ec33c285323c7fb4dc2eb768259696b41c489ccb08d8665fef6a7a14ab69dc3a72690b5480c1ccb2cb70d3ac37e4b2e00ba7111905fc6d53f0519c44877c9cb1b54abf3106d90424c6a39dfcb6e6c3b80d96a1dbef922aa762d5433485822b1f28c8776305018023cb3328b9200728d082260ccb07b3241b7c86f90f91f18a582aaba4003f9b8c3a468818619a57a2ee0d636db09762e634400305e4495b49f927091773016c72196e29b2e20034c854608f54d1c7506a6b89f8d1201bf659a53f7c16dc671bc65089de9774ce4b52543a1882c12773bc7cf00b746c5b6ed5026f7e30bcb3cb60a091091c2ac85f816d377167801c47e951b18e239c005bb9612bb03262a6c21306749a60deca6b47b22fd7c7ed472aa3e8b9dca5150c4d3209ae02eb72783594b0c713509410a01de44245258790058ba90ca08cda4c45fa6867b038c7eb99d0b026320070b1a18ace2ca6fed80284d094b72881232144f6422a896d67505e40106958c81946a86e19f153712ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = pass +expected_ciphertext = 87e9105293d63aeb83d6098dcfdd4be921d9c030090d76a0cef0350413d732b37eebca334490269c3a40716330dcf1c2de212cdcba257dc1531b3d4ef6a56c089d0fb455d306a240c97c99931e9fabcb697fe2b407432ed599aa000859ae50fc5b9f29f055b1762494d53e3269d7dbb309c94d670ba486555c4d9085d9024f4708089d0a64d4d692e652aff36bf30c86e12cc1f8f568f694446d98977687d83c01ad8e38e8c5e09ed47b8c447f275e06027dbc37d3a5e727d8a79eb3b336d94581f5690fc78742463696a45d0fe4613660cf8f0d66c7c25eaa27833b9957b291de30d699cb6ee391019b7de12f942914f47362453540eae89ec96c048daa6c4d34db266141b8f41ff623cbdd8c0fd74d9c8af6d3dfa2125eced0699f2b060e88c955a479e054bf2dd7650328528d0090a636cd796824d84fa382ebe6c0001ebccf5e305442ddcaaea5264685ce3a25fedefc398c3b00edd5d99889ceac23d861589afd384c4f5674b9e0c41c6320c21cd23bb1395e2caf219ca29ad642d374e63e0d41633009debae245bc0f5aef56008fb7220f73e6871c5cd4cc8491700d7977e791f0e30aa7b48b64a03eab107c5a65801ec19c785d7d474471144f6d5610775e93790159ee2a8aed5821085e7ba742ed0a9b369a4551e5eebbc4c919fbba4f5bf1cacee8d6ca26463ea4a17ef34a592b2b111846def0180e9088c855c770889fbe1858906f2d03de0b5a1f2608639a10df35f27eec67d78a517f13e00f31133ef508968e63c456704cdf7069fba554892a6f993a5f3feaf4432b351f20d3d68892ce61d762fea4e2436844573336a528c79878db781422eecdd8e8c70e5e9c25284efda4d732d623f29d288552e18d170ebea121161844d7596d1df22d1f35ca58bcf25ff11211b4faa333932d032261870b0d2da27cd4d4fe1128859c98a5f6100750073c3d8d42459504ffe3a5fc199ca01afb218ebafd57b72ab27213e31086cae52bcc8a83c42b769f3f1a153ba3c6ccc9012354158b7d8ccca22c63db2648f9c1294d283ff91bdc5fcc877837936e5c86b53d53d38f8d8e220398ad +expected_shared_secret = cd98ddb938549cc7c4fe56cda7f3ef213f1aea49fed4fb81b940c7e894be1e54 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = d9f06a7e367399206aec69c5569ba3fe2816a0862539951ec9f32fc1a2b9ea199b877873f6b13546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1da2512163eeb5c5c3eb60c91890b5992aed81b9992ac238c7c2a7ec41fb4481508a525f10c4e10b448ee4a7ba149649c11a20190cc95c60eb727cf84ec66c24c008a0308f28171f9c74cc7023873b1848b3450e28377d8115bd17462eee419f1c69414611c659449376b88e23061886338126b8ae317123786ade2d6c839f227ec302132fb59f5d3a5e11010adc5bcda4b01a28bc02377a6f3f4a0033249073b18f553ab65b57fc3176e514794db93a941d620f3f19d1103a6f0a02b7cfa8c213347c6037b85817b27b22f47b8a513d606444736af884fde78a879cc77a4d7644ae360004bb8b072b74a1cc99fb32a68770a110432e4c06f08148ff54aa6a5d2ac1b3b8e461b9813c3a16dc0b200ca81d4e336a54341c8d157d1742a0c327b7c0c9390416b59843353443530a5b70b71bf3768873771155617637272b1cd057f1f01b59565228daa20a060970adb811c106491fb32fda5c6fb70415125b1ab6148062100ab78107b37aa064942acf56919216c6fc58732598f0dd82838d8881999b431586a315375444c6a27d14ff8aa3da9d1340d137b885c95f69862b63c2618e28a11211e3b64bd1a678f631494aba55d42d8116b6388e9ea04b51c9773083a207000e83332c727b4512806a2dbceb6b40c644a5294362770f1108c467f6c64b907b0bc142625ac621352d64b73948d88f281ed3a65a1d4bbf920c962e91496718531756026e71a5986990b5bb1f9eac8ba3571052c32d414a5ab07832ff3172fec8ffd1197028a9ee410203ba02e6aa6b9517ba8746317c69304b381bd6d23b3db6605bfb2762b556bcb502cd10a22c8b78b4d0a173cd56ec835aa874c485f733b5e4c0db08558f1cbb11f866544f10a8a5b5cd52053d8708c3bacab400c78a65436febc36e5894d05b163ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff3703bf5150d1a7004c1c84ce25229ce751f8d00340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = pass +expected_ciphertext = 34391cbe00a1c3943f10790070339a88ed045ca63f0981b0d45a19b1af0df59a50eeef36f8045b6d6b8961811e99cded515be35462c05dfd384cec024c42929be7ff8536c0195c8591975381a2edc28f661f36bb3eafdacce01f47adef03b0464e14b34f1cc92e8e75a835e6b7be8d2ac6f8f8e82bd102dc0019715886202e5adb89e11e8dd3df99a093c62f9a6f5a14488891471660460b5e709636b2f8407546b2f984a9735f86b4dea2e3b7355a998f9bbc468ac7891835904e2681e9e9a445f70ba687f3025dbd9173741aa0131b2a4e421bb09fd162fdecdfecfde16fd7066527e833225f048be68d7fbc4d1bcce4a7baa2a24d114aaa580165ee3dd7605b0568465cc157c0d4fad4cbc1d78dfb3ad9dc1789010677f207fb12a0d616ec68119638e504a8d437600ca01130581022efc11a12cea0904e22dffb824d72b4aa6037a14610956a5884634ff1df9e0ffcffefc7c74ac7c4a202c60d1f0e9db4e2e722e58562811b3876dc7d872c0596a47ca063dc816558207c2fa155410bff0c80969c2c46b4828b2e5b7d78807d88430c254c861cbbd8e49796aca284a2500598e7a6f2cc543d8bc81fac06727e8b4cd1165543dab46c7222a9d58f8d9c15a5969dd77d6090132b9cd05c079a40a0f24abce054e3ce7717704a381a75ef33f06da5f6fe6b63b033721e7aea6c59c39a4333f09dff6f45176c7dfc654478ccac1395811c9db19fa39775f304f618bae8044333db786249b573a73c0b812e7f9657c471d65cd55994b54a348174df87a2ad7d2d705121045dec4df7b59d391b044c1f03fb5840fb8a061911794ea2c9c410565d73c8b7eb6c7f88fd3aaa251619bc066cb511ae055e8d3620654d3fc9956347854cfd59f5363b93cb21584f626263e1a47726375b0fb2c672afb3c61b3e79ca73e279ef3522daaf157d9f82401e955f9e55c70dcde3f784690f2f100771bcb8f9ae307242f8b8a717c7baee42eeb8d890adfabb7d18c9c2ea8d136e9a66a5b6f2a4289729f25c051ef44882d48e9f5d18b6c6162867945f94cda3dd54784e12d4fb364a58f65c039cbcd4e563 +expected_shared_secret = e0d0d574b1287716bd7e0a44feea36ec28469bd36713fa8a53b0a104f322016f + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = ce04a546261fb88a14769a7ebe1ac627d4709ad47e84c44ac01ca4c40c0977a9c8c6871bd929b6e70a8c76a02342ecbfd8a90f1f31470a8708506160f961564db86466d049894437ab1a89dd41363eb597d3265d1f7b9a10c715d40a182e945c9666371431a5a54c6a80222362fa245d9aa10fc115642b3f28ab28bf05c254110a5f5ca553db719a16269d749bcc85388825201c8152c172806c9986f53509a2a3aef9a28e22e58cd1043e19e757b8179e40689c9762bf2138bc02453802869b8f53abb6bb088828726cfa51eea526ccabc971007a0d011315c996ddccc0fcf365f475c578517592c2c48117a63a2b6b854bc7a7a785a5dc4fe4c1b012d78cb3341f9cd826d1d2a13e13083e046de47711e4ba0a784aac886b25dedc2033895e48386e57234ef28590c9f542331a9ce6a0a2dff143b6f542bd752ac6a67a6b319ef15c7203119608a21b1374c5287348e54284dfb3b421b674f0fb3186080553b81f92e403a5eab01d564c9486622bb5233ae0bdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff437197215da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d600260c2e077c1558c8f2abee536999d951bb934cc974b55365495795a6418ac4a9f4491b4e60f992142487457e7359cb5b01e7e1ccc909ca00e6005b213c339c524b26a0b747c18a116026db16239492eb056b12ff700fc56ae35e97ec6d0b787c8aa02e4b828b41996f01d69fc9be7005d4dd89963298838e27c59b79c8de62e4a636bc3ab197326c8eff92c90e4958980a3382365fc65594219ce9d7070a6c3586466ccc031310825ba43ea933d416fb7a73d83f05ec222064f03b635091c25ec0a7aa99b9080844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da88a02883406f1b379e95792c68197d591cb9303b3d5bb2791550da44567d2115da0bb4d380849e1145140d9c6983819f7447332cb697aa2783be169db60249d3cb77d35845a380be3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = pass +expected_ciphertext = a479b93daebb4d9775a0fb160af4970387139b148c9c328c02e2f774947e1c239c4d179d5c4007a98f2ea22e77878d092e8f27bfcd7aa5e8db486225e579aec679b6e7ff7f2281f32c3805b720fb1410f6294dba996d2eb45dccd91e8225d11bcebd9b0bb21b0e26d8155d630fa6011fcbdacaaa0d60fd16e099158d13cb58a74989a5b981330cabcbde98ec2ff9171cedc2afaa3195f8d6f566b728b3a45610a56f145a5a3e2887826f2b79717454607248fd041b533bd58b0cd52b067b902a4aa0c751ad82899065989fb5612faaec8c27d2d3b3a426bc188ce7c0cb7b64efbcbff3135783315aa327f711f5c02b15e0d878bccc53f6140c4146d7342df087e77016165f0388f2c5892e48a31b03eb5883954294f8d487879b5be80316647e14be9998201ef3fff7a1a2f7feb3ea54cb031e4636358da41af23fee79821a6d3924dee3246f21663b1897a8af2feaed7d66e9791892a86dec4ba230a00082d94718de7ce3db14936aad70f6b90ceaf5529d62e017ee5f6440163d6b43c7f38bba1da3d2fbd573d4a00bcf2262700145dda11f112b46068a393ab392b8900c673fda1d7bc98f2a0904f65501c970785abd9481acf91f85185dcf1971093a26cfbf1084269b55e6a19db1b961f38d820cbb983b8800ae1a215bcd1627ce81c9403adb816019d1774514b25144a0eaa4af61e8ba88ae25393473ca7ba236637381574f46e59d8a210323aadad4bb89143cbc3e3cee36b22bd9de990d2732bdbe1a5119c0c8d8e3afb74d4b3ad171d5517d5450ec3e88f8b976e6134f996fe7ff849262cbd42ee8a77a5b0256d16ce517c3a47b8410e592d9d880ffa67822b1bea078f70042f691e9740653e62879553564052277eb90fd95396f68ce20ba3a3c0e50fb25f58d75f490d94d938659fb51d16d50fd9d01c296d0af891d157fdc0c30ae9a8affc1d86c545fb286e7ee89041fe9aa113fe6d286b38391d1b7f3f35cf0fa54f6ec4c62702bac3310051d32e16dfe9db3193dcd54b087b3dc052443cdd0c8f2c276a493d476adff6a8a0972081874b7970e9102ae5e3675abbf6bcdbb8c +expected_shared_secret = bd97eac1e35a06536e713a2ca5e71e35277b948172cafef0c35e1558efb61676 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = 4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df08181e5a7343291002915603d891099172597c173a88b41cd45c24e40601c6a5bd379113d876e06614087204cf43c3564980d9630e84b621d6415d0ce224d50bad07b52d58c6ae9ff108948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd6013eb33046060cbcaec21b13549e3df843e9e7b6cd731664808ad4a773237194e9d5a39217457478a6198203f9e6a90e9a8492f96fe28a72c9e2743a41caf07752f52b2ed4fc17efa95493a24c66c93bc6aa846572ab7fa0a808a16279382f87700d8f195e1781803880b07c925256100f7bf223087a85c4f3c88f861e60f92532d60f5cb2033b883cade25f8beb7312520fb3210b2230528644b1ee298161f453b5f32126310899c88ba50690ed925ab0537ebd594567e837471a84c6ea72787176f80c94894c870e69337d939691568edcab008850a6f3a53eb585c01af253d1c9434810555afabc430b7fe69324a3e775e6f2be3638b119a6429ff98d8eb1b5808720e467302798a8ccd8350d36bda8fab17a53bc0c851d91b7cf10c617a1c03bbcc63d93a38ea4653b80731442889ff8200c96b5c37263081dd400d5670959941764a61cde119662325339da81f926affe427e31c6883ce10f5e5705eff1cb209acff5644717e6c6928a41b6e7183590aa524744881aa427c17fe955b306c33447054ac729112568a4cb16806ccc008ffca87e4cc37c3bbcf8e50d3bf07e01132efbe0605a14ac32f6ae2802ca893139f62a64cef28b1720acb282173f2cb4b0f392f8077a325a6259a32455e57964e338a6a731c5aa29beebb0843730ffa93d6b234d51bb87a054968cd07f9c3a2ca79607a97079eba2481e590955e124fa7805e1f03499b7216b6a3a14b9c0c6bab99917a435b88c4314a290e70c7eec8a145037b6531b35b89655e90df5eb2fe53ab33b6c68583780a3b52bb92cc90c45a28cfa8add511ee03bb8bf528d4e94bdfc0cc510e732df4913116a7786e437ef523607126f047a17168824a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = pass +expected_ciphertext = 773cfcf14699299bc1818306cec522f63409f9a8bc405b2838155bee43c8e6dcaecd05ce4d6f93e666c601c81b14ad1d79680b7bad56575ad5abbee83d014b44cf7aefea7a4860977a2a4a05351215c569c59938018aae94a5dc231fb72cadc67dd86bad1ca008e129fd1059a7270128b4b40ddf72685c21eaa723f305b6b7435cf3292ccdec873b936b41fc17b48e4d3ca861f66952f7ecd90a66f54dae05816fb7e68990f44710bcb121053505e9ab9c42a324248bb1719c1739660b65b44465c1daa42dee4448b642a9a88cc26c94dbf5a988a861b34eca0b4fe15f28973d9c8eda76f3ce93e9d69663c6cd7c8a0a8adbb1cad5edf5b1b9b67a48c3bd994c76326aca2680cf9e350cf46e6e6b93149ce7a79525d29bd9ed969857a5e7927f511a1f5f343bf1bcda86f4e39ff3b8c7b2b8e2b2a2ab147595c025cde7deffd917dfe0022b1dedbc8f1fd2b0e45b02498a9026e81cfa79178e75ddf5d9cd60fe5af246854665464e2c7fa2aa33901f598b0358326af9eb2e0d5936e1925dba6e356ba103a6ead3524eccc8726746828184fa2f836104d48a990dd90fa72578b9845fe99a9f9470f9a46111242e3e36023196edf9f6c8d3249e4f9480be02938405c3688d54bb95eec7fec06c710a1979d3166c6d247a9edf892c4f96cbb57171d473a03f86f918194b644537f91570abec07fdd2145e9842b36ce82695bc2bf328ef9f85a2fac305ee54ff330ca9f3f7b949eb56e0c5b6b72006905bf4392494ad70f43ed6ca4610c894ed53107c7fe6dd4b9ce821a9fab03f404b7c88645fbdfb655cb4414dfb3d9bc94ed723258f9a76a567cf9a9b37bda6299ed02444da2ac43fe607972a530ed1c634565516c8f1b36d16945af1892ffea7351965827e5231eda57359ab76ec1bb84de0809a44c2f6c963072895d0301dcdf2e58c24fb9f1c7f81b51cd111df67bf9f51b4f41ca15fbcaa4d17335377ddc5dcc6a7a0b7d54a843292e4a8951a691da80586baab781586c5cee2ef0287ac613faf0eeadd32d5d641193f0ffbe787f936f6d879c89e2eb1a01fb6ee4df1719779505df2e755 +expected_shared_secret = 2ed540764a77b17c6b9608bf86d8d8703f80718044d52dc79cbc1838f91fdd7a + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = b6712164215d038aa3f9050a35732e408ac91a2635b4c6b502c698104c7e90a26bcd903a4b78c20218ae92d39bf634828a14b529983e92900ecb3778a1583deef38497a336063a31ef9460e8b240fba40ffd4b7b070a4650ec3cd698046c097189237a11a510f6941e6b73a79dd99ee4a8517d25650ff2c0e9b0ac238302ecfac7fd642df9830ffe8714ea8071fa097b39e57919462948a177858c89fbc8bbb2717eee7169b4256606c8abd1e9399df44f12fb8e4ba0b846ec7fe1d65582bbbdd0d494a8a25cc81667ae1964a525016d9ba5ef698c84472ae62cbf10293cb047082a58bdd321c616fcb7a79223e95c8834362da8e60d0feb36a5d1a1a6b6736200213ac3620a113a6d5436ef2064fc360805d2ae84d79d07376123fa1682f80a5e85c87992329d52125a9965d8b039784a3bb472a7f310057dac08e5f41fc1ac9e55f7532f2359c3063726a25599980597da9715117a5af15de88b516f8a41e4ab824ffa8e6ef16cdbcc1fe4f965eac97474a7b235dc0c73140ee7153a835c29289311e1c2a0616a2742c70e27d656ef9954c7643947bc32eb713d9ac392b982400ed275899a04f1b7356b02a54c37beb03215d9e1505380049f9b61b35a61c105980652037142a44c42252663799de7bafa6a042d439c893a37a87b1a792c1689924cc642ae09a299d456c6d36895571572f19c144bcc6eb0cb9aaea09289c8cb193cb9ac33823c11980c950d1106625755b280077f9f383f828824818956ed46755f7933f029a9363054ded02a42f5c56986c541e9ada77084b08b7eeaf4abb700839a59c18fc556a6d528e5326c0b4baec27285b0353e3a152f06fbac742a9606542ffbc14d0ec214757cb1a23aa810945aa8526d3cbbccd11b86ff12b553268abce55d7d723e496071a8bc3a8072ac653cca7c261feb53c95b569a44d52f3d61ae991c38828557caea637e6b130142291dd51ddef7163cf84be7a266e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4a622bd8540b044bb14384aab596147e813f9b1c94f75bac39a1aeb14a035d858892b7e900a2163828f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = pass +expected_ciphertext = 80f0e07ec92fba925668f52fee7721b4365ce4cd7cf90db7f482de3d8ed0d94b5e79af79026a67fd90a5430d7350b22563a2edc68e796a39c8cd76668ac93136022e933657960ef383100689e067090fce1e15c2fd3a8aa0383de02f585557f0495e53d3ce51e947a127eeab55cb4bfd18eebf7cff30d5eadd29cba4eccca850233dade0aeb8275cf60752fff0a94e1d9f8432c26162bffcd2736a553ee71db05823223f650357d2a2e8728fe050b6242a6fa737754067d629a1c5455ea67e5a8eb6ab907ea17d86ec216b00f40a61a0bbab989f6d1643c020301daac7de7a59e76cf54a8abf6773efbd4b6951acad6c367ca6e9411b8f8640c0fb42e23113b7e1a358ebfb80987f6c7a10a3d0bbe682c20df093489d610be2a3b5f231321053ead86f4e402398c650ccbd8264a5fc3c8e1c1e4bd671b442650210f86d0830f428560d5d535dc734e1c4c8497aae1bc09441c52f3704de83e77b4cba2e3895f6d9b5bce23e31dd2761e3ebccda624b5b86085f18f615696a52de50c56b1caaf188a3a78a623b2f172bfae390df31bc9d41d7ce1ca6111025f2506b54b1d1ddf103a35089b6c25f956963a01401da4a62a570db8f210c8a4e3c94faf34d7b6ba3b3fc66f4a436225549181b9e951dc7b297b8d7fc656a3e7bba2967963fdb6bce347f2cf7c3368d6ac4ab2d00198125fa92363290db13bd15d57a0154cf91e8577a73ddf83ef7006c0da7e52f3b49d14fbc4d7aede982c35587a859bd796c2d35a9225ccda6c6ac15f57f70d04bb079b0e46c7b27c1e05990b9162b52cf95cd3998652c788dda7ae35275446a4edb0385fb5019cad108eeda5e49a6928ecb7659c7d64a60c0f2ed7555cd721fedfd9ecdcaffb0c6e436e9e70521009c51240836a85d71021b2121e4fe1f40afa950b2c8631edd8e4cd0a26b8e298a97b8f042969370582fecb51c933f7cf6d4e5aa81aa1b1c427ed69753cda44ecb992c227de925050fda2196b4668012b81bed5def654a2f17be2b13e10f22aa101804026f2204d7000719ca13053c034fcf608efa2e83dd1fe15dfddce2a61bf954d78621e1 +expected_shared_secret = 1e5ba1b64fa8ad0494c96ba27e288ee2b479c24634285f8919e58e9b9c8be78b + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = b7665f3a5a380255617309ccf80a53dc03259fd252de0bb4865372fe22148ed6c5f6c111ac00b31460c5c8da7728dcc4c45093f6c38d78432542ec71be51526d588d46bb07ca388088a1c873219d74334070895c396a87ae390cbdf309e41a2fdde955cec2a29bf205e492747dcb39599a49902151aeac0852d6c042b4c0db99c3f3f94eb7db193bfaa7005709933899c04235941969baccb59418a41e603ec62679b2808f25c8565e6954335227e40040d8407147ba15b7a84405c6a6e72251236bb951e18a1f81b84d0126804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1eca19835b0bfdf637a5839c007cb5c5972111aa64bb0f84884d70375e352241bb0dc4acc5f170a7f7b7ed3308b95d975d5c933e5058df99c4e08878523bb98274488aa712529870ddf5211da039bf2e43eb6506f30b41a90c8922880bff2b1630c0048c22c4972690bc965c009e834bbf936581c9da72a70e2a4c2de0220cb4b88296c9716215007ecc9cbf9c1ac081d84d56adb884d2522584cbc5e61d3327bb2002b275683664487a3ca8f767e54e27e541a403754a45b9512368b0c0298bfdd2143ef9c16b49a282e14010591bef728001d0892b939c3fce379c2e96c2b41a9e5cab8c09cafce0c2a14d79137e3b86b25546c86228d008c792496ddcc9ebb01a664e62040d09fa798accce9033bf828d6058c27e79e434904b756afb332c9800312ed69c4cbbcc379b30b83fa4f71c15e86680b6e40b1f79601ae530e7cb8b7b7d536336468ae291d63360814b83ed574c98ff9afb2db8fe0e4561b98001ac783eea99b82d13de2fc5fd59a1e7cdc63e814b3275a0adf318fb2419c76545ccc70066b0abbca763a99901ae6412b43e26090418c09554bde64c1d3767b074901b5e61449e32532f98365b0bcb65cb3b63c03f1d023e495a0f96a258ffac4d3299896055838263ddc85bb3a071ac5c87cc8a4ce8467881f54047759b420d5809489cb2785aff1935835b845977bcf2b275fabe31222e8576e3578a7a56a26a31bd5510d12bc9aaa3a46fc87cf9d0706d20a126bbb446c24230fc82a780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = pass +expected_ciphertext = 8627be55377332874bb930cb309bfc6fd3b38946dcdb8f0ab382d2ab60bc2d0bb29df7b1bf3b3575718369ea8a29e923058894b16fa20d83ee3c0a9c31163ef9c90e33c500f46f1efdfb46e2eb2040f681debd4d93e63bd2d3c79b4d38fa1b78bcca1b5d407dd1c5f4360cb0007c3ac8b42a8dfbb982fa7dac033a8cc46c01e13fca6508c783060825e6775f0e404b95bab4d6e4c1411a0866f0c74d1af869d5ada4d9d6073b25fb5cf8f3a0a6889468a07f6a11359ce1ddf10e5d42a45fc608c2d93bb35aaf106d88508b6eefd66485b8c88012b0d3f421d391e9a7173aab441edce79cf884002b3fe7d1f45438b0a6ac966a390ad40543f7bf1bad961deee15de44b07b3b4a40204bdc8f0abe5143fd95bf8e46c0e5488a3d142300715e9c0b5e4d56756a6f65570d36e7373b8e692a161e06a08b94015f1e0acbfacf5418a36d575a93be8cf61e98fb1f9c0229b50af4da55471c1d4c4cdfe8f859f56a95aa5d4a129f5819549019372e803d8010d6d5f444eaac568580ac0ed2ba98078bd65ad41b6a14102c8e5862803593fa79ff47220f4dbdb25c1725d07a564495259664e14da79d975c1b4fb0a36b43ee1646269ab0ce962bbf970c2bc73d953f5e78e4a4f4ff58dd2616e30dd4a71620142d05ae617df9d38131a69664d62020a0d4edbc0b21dea93e4b567db882d07b28fd392e2c188c5a9792fa01e375ab8e02646aa1f4b24836d2690141f2568314543890b585c687f451365995627ef661e6d16c074b3f1ef2621a03746dc9d930bc9989e6c6044c8410b8ac62b63f3a217c9d0e42b6d7697cd79c7b126fbfe5137c17f47f8f3fc0c907fafebc3e851310052abc266a8cd0907f416935104cfc1db894cdf658a42acf6bad98e3aaa296e85abf8c1217fabae0fce40675e875903042f2439044388ec5528c8f58c0b5147a8cacc393a8da13a52df1a9565bed1fd40503d92955160b7c6cfdce6e5a146b34011e0e052c1a4f7528d1da9667310fc6d5183e003f24699e7d16185b3f2dd8176edb310feed5b70e3f0de4297335cde9bfefcd371d6cba0ea0a6a5e9c1afae5621b +expected_shared_secret = 96ba12c7f8a0d864ce1434b789c09753c2d1f7ade6a5a0e679ce2ea0b6d66c83 + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = b6a67cd98268afa159ba69953a085099ba56f4e4c74fdb6759791d1ad738cf320c3cf8c52d607a32059f1e8333b4021d855816496963baa6cb41842fa7ab7297a144758b84a27aa6dd507c097a6c7a19063f2b2baab0604aea5ca1c82dda790fa390c142b3709cb69675b8ba0f4990dc923aa525a316a0c7931aa5e5dab4a4e19f08f898ebe80258ba72127a92e3005611a72022d285bd279332817ed4f13a06a71f8f68a0be49a13eac34c773937da6218401c3fd55577572466a271a4bb10a7938919688629fd1c77b802b6358189e13a52330c4f836bbf41595df29499b42a5a6605ebcd6aaa89ca33580b5ee619d282702b4380b717532e0dcb6dbe3bb0c6431ad480821f0c184e7817616c110f2155a0536a4c65b21306fcb5c343fc38191b8b46dd7a3e27240fb85c365a33e18bc231127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddc52157daa998c392a255b37bea55f1c33a23ff4cdb70a3fd0e019ef82131bd92e5db8ce9230421a670c246695afb5bc33e8569ba69d2843957ee52204e435f85c6a713c3fd677cf7a54cac8d48975f1609cd68659643a1a10558f7397234b583e5665e3d30d1fa26d0788b21bba2ba23507123b89ca5a1f54cc5957737159e93070987613dbc7dbb2ad163909fd167d9e099d8c394a7161417141cec54a24f34310bbec13abbb05a3681c81d7034b8687c1d62abc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa8309812bf6459c26c5fda4abf0ba46544a9146e5247adf99f09622c74b8b90397503e211b9a23bbbeb3bfcec659c936987c87104814a312091fb443acfb87a0863564b9eb9191708ad370ba73d42f35b5ae9b97004793992d13b5bbf00b277a2de699ae41222f28d593f6d3385583bdc938334e724341883a8026cd2ae5205da3b44b9075b86c75fd203b0cb738b4f533efe6117b97105a275edb7b0a15aa1ffaf029f3e13145eb3c500440c0e30c426c093c420496d85ab46883b4b695f30952bba32134189589882f5c297da14236a073ac04579e4e7a70685916e53845c8430e2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = pass +expected_ciphertext = ff737aab09f925bef6da4cdfc9142d86960f28c3e383a5141c7034674610610731b31435b50e2bd894dfc12dece35422ac59ea17beb63f9ad72f6ad81244275e96d8b7c143bbad756e86d9b206df9eeed6a64818902489981ee9b508a227462e2f6dbc3909a91986a71c9e1b497a647492fde143cf9d6730513ae680875c79e747e6b243e70655f560545d1a60315f2a2856cbed6a13f4857fde587e1abf415de2d5c67b1f61496e3f98290e6ba086bc412351071cdcf3a9f5f12881df65dfcef2746a7e1986d9dd5efde2bfb3b70744827fde41f685f694a05413043b14df26205f50f2acdbe893307719819b24e66973dda7f4c948da11ceafc96a20ffae64a4eea610397c2fcfe41bbf8c2764b60745e1883985844b76cd5b664e4df2faf6d2602a987a76a1fdd832e01d830b2f972c2fe55a8daf3263dbf1f0bb1e8ae5adee4bc2fbda1d0413f593d6c330779c0c51249ab91ccc0d6afc6369214fe02b1504c3c34c873e7421918b347a2f0b166259a758f6607eddbdbf87167e57748197fdb63a5501e235ab4ee00939d2e9bd8dde8328b9edefa8c1faed64ef861e088257fdf67369f1ba575473a354a42e6b1855f48cb87bfcc798f21a7681015972f9afa79c48db278437d0b20402d14465fa7a6ed2d919c5fa2ceedc06806f52d3746ece0fecca84e8cf13f8adccd9289e08325ed33d2af1e85326e431ad4380490b07af223ad0ef8e6c4a95e9cafa0c1cb8d61c41c123b27a2ca8e267fb9c63fe371cd5b1177618b7e26441596615d9695e04c77fc87fc6774393ab5e612e5ffcbd54eabbb548c568068b6350b27c7d4c24469efdbfccbd2f8618e266e2072e7b1f8c4d7ebbb15e29293a1c2a5c26b8829411a5f861c2b5404b4c0968c535d42c2b5b0d7b14e30e2a595d780ecb1aedbedbc036e27ce80975fcb381a3b049f936c5026697822e407c7656369caeb7ed574c5a8da357caaa89380940f776cf6880eca251ab1e895870be9dbbe3aa3a6e11315e1cf7b82a4cb183c8b0fd3dd4d6b436a0b259fb8cdc2257cdbde82c358b174087b62aaad99f4a2744b0cff5a04885bc +expected_shared_secret = 07dfc04ebbb7ae537b594210a9180f647d3d385d1c1bb56abb8174111eb246df + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = feb55ffc9306f08b6202ea25968669d4597145180620da32b9b41576a297fb5010948a0516ec3428f1ce8012c664dc5c390663cceac966656cae6110d1a45d4360c420a69014709a70b71c0cf8cffb81958a687656859a8979a24c8c131d1b03e791bb81376db31562367880dc097f04c150a171445283cb4444701bf513887c917a310c87fa30dc3a49a23727e3824f5e2b821875ba8b5288a28b40abc8ba0d130953352f60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c569c2b7fdea81bde50c7b495f901c14b32779baf70c57d84d92aca4163637de873f0581b170e77f4ff840d0e56e13d367c74a23c453c847e208c85cc687066c09c6cb6c397df1232313d93a9ae45352e746c1645528a30d19f6ae36a56cd1116af5d11f6fab71d45544c121895f355657d982fa23554b6525a68a050b1454cd3acb4c32af315b19c9e6ae4a9a3791e6be07f64c1de5782ebc2e54f23782c64d74276f5f060e89c826c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b352b34b71958b0147517061a45c22b0316deb27ebc26b33efac3a1b29c4a301e48e00da82930d4959a13e763cb63035844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544aa3290dc0697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f7625cb0a1d3bf043e304144b559e969264053a53e542bab4e57dfeb53aff658db07c6213586315f57289e2bc66e49c35e28f9a5219c9f653a9f1314406a6cf9115adec8568309388e18fcc5bbe221c323829c91bec116ec1128cb39460c25876e32c08d1c409c581a9360d570ccfe323244f0ba84c19cdfeb6cc761a2e408a9d073511b90a2fb7178fb9cc096ce14a1ff14b6b6600ef99c47de431cbc7482da47d87540b3e72801f8a9b1c6c583ee73bb157a78c585b95c09a868a957709a5305c7424a28a8d731ace8759f5212566388a7fe50705b6045a945b69a52bfb4a61e4dc53f6230773f844ed90c571823c3094912c3a9ba25879d7f4135780596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = pass +expected_ciphertext = 97912e16eb69efecb5ddd7c2f69ad5fbc628db11c4eebe7bd01e3efa8ffd1f30d4a5e39dac57494c313415c2ddd7cfc5c210c146b4e5ff721eb75ca9e54e1a690d4dbf9bc9f84dfcf30b43bf5fd71baeaab172f82ae38dfb3f52fb614cda0d59349cdd43e3b203f79d67654905f08abe48685e7325ddd388c7a93c1dd255db54bfd230412b3f68165c054931f3112095a9fd707bf29b8b520271a722c897193bcd1d0839c47b277207b720c3fa000209b14e1f6c114f9a8c1ba778d0182942904754e0a469415b2e4a4c54090a7a5bed7a5eea3cbeb98841915e0e682583d2f995deb14b2d98994c6b0be50e6b8bf6b3626d63d0395f2486b53109f29aa865e9d299085a4b4176bd06ca74cc67694b89ad39afbc8ff4b97e25e302c3df27b457a5d4bd8346e985a5d01cbd16140c6d7cd8943893703fe46420cc67e89103098e32e18e332cf0bc6ce7322be1a61b271eaf87d99ea38dbfab0f05c8eb849c215d93e1469eb447a160f148aff8a560eeecea86f57d269ba7ad3735243aaf3936462369515e516d3e5cda5bddc5d857c6f005496755d6dba588fb467a1ec8284496509820b359e1dd1be5490e8bd0152e14e54732b561cd0f71a934f2a7920e6f212082f3963e04dba6a5cd01b5736d27c2a8b40b5196fa57f71e069663dd6c220bf7caada8ec9a057373d21748e8dab71e764632a17955cb585fdb1231369a537918194b207f742d004719a84dd9226110e43cd5d3f5ec8da31e86aff1abf4c2fa512e0712d1de759eecd9f3e7cd5b90b32cee8d4b19519204ec4c8b28b9529ae87fd52b43822c7158685600c2b45517ba266032d732bb32ac28e2ab5c1d856d7caeb48540e1e5fe3924e5d8d2fc146fe5f821bd92efcda1aa7533a48cf91355183107734f9a2c1a43c5e8c63fc106ef3c8609919c01aaba3fb65285288623d5fcef62821dc24d04c8c44b3219936f5e6e87f723875cef8be4d1821f08e58a1dc72c2cbb5eef4018b324d328356c508d49c8be9ddafe5335c74303735443e4b366d51cd145906dd8d73219bef3eca694b780cb8ae59f3cb3b6bff77e76d109b0b3 +expected_shared_secret = 81fdb9267988ad39ab57e2fc8d4c280e0000dac3471b0936083aec68b49fd92b + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = 9a620f09135fe651929f4b299df28fd9943ae75a983b544e62305fb6711e780519b0794d9af7b4acb2bff7c704418bc89c38a9e2b00ffd6854c6f41d38b204bfe220034213c066cb62f721e59521bb6bc039c19781fbb71a546aeef31b90783695c47ae2812523f84f0f462b60f3bf77f2020e793813109d25332e966231a462ccc596a48ccc22677a904e35035ea10ec572b15af3ae770abd79c72a1dfb3a988952c925b461f092dab51726e999bab44806199716f425e21441cd82919787c629c90b6b1975e7b0844ae52df6a5cc7d393ada542f78952be2b001979ca34563b390f712111a24fe33ab65265b70eca7eeca275a993ea2793b0b08adc56ba66d93ab1a65524bdb034a33a9e9f59b79f16aaf12c470a22105ea1e2ca042dde1ac61a982ed40102968437d216cc6387989d652bd59a4d88b625056b40550092a506cb4b0532380b35ddc4d34318e33a797c696c12fa540df4329268ba47c95368473c9a70b0a5b0a3360b73767f16d94e59c79b1c839b0af93f3cc57323b9b815b94f6889cba154fb0c6bfa11ab5fba4f10c83405629b9c177cad4307a7b0e72ca4f8c7ba5f292afad92c566abb319124205554fb538c6a5c630a32655ad56be818aaaadd546b1d04df1121ac167bc09274379f0719f3056febaa36aac0c926512d21530d5b9a8ba838f7a44656e868c915046ea818e19b06afcec6a14594e6a5574eef2a937731f24994ef7dab03e223c0fb0bef2a2661703baca090c50a20da05a64bd764f1f1b5ec5a6ccb7ac59e465146304c272453dcf897ac415a8895511f5d04c24080ce0a1c024815af6fa0f21c7cd0c702bfaf7991d915df9b7a57f513cbf0cbbe6e40854e42a603a6ea6524fb3f49c81d71c4ca27848f51a354bb35020008360201baa7fa2d64d269a598e3919b1076b89b0c894d8cd63924eba5b25a92b351a516c50686b2597828bdc894a08349cb0996b73b2fa0b98d0d39fd2c6952e1a60b69b1b8d41b5f6c002409c3bdd716c56586b7d440eaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80cd502aa28063835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = pass +expected_ciphertext = 145a28ed434adcd1539de7bb777f913e0abf3221b06b68ef080575ad4d159c7c6b2eb313314a5bc69b559d61ddea83986bbd47c8fdcfc95fe19f7e1ce5f177dadcbdc1adfd3c61386935f0fc9a0f5a2887f2f649787a9d764ce16f8cbf54650c67742c166b7a91a2629c9006014a934903b6caac51c8cbacba7edb8369d03a0013557f7fd1d212de89af8765c8bfd679d2c53a652071fb6d975d19d3fbab5b8ac46e778aa9d2b5a6e809923ae3a48826ce6970b0e7c3f6f2d76c12980596beafb127b3c026a21981391ca6e77d753fcd4ab4deba818f8ad7f928435c37a7a5ca4f5e77aa4331a5deb34b86f4e415c2a90963189560d260e850a7106f1b86701e3c03b16081f12f7c3fb6e6d2eb1a05fecb6e9f0df568ca3edb978795e20bf7cf1c430c242321a6dc86b16b0f05551e4e391d33032467e67781ea00e671d79803de7a4b0736e8b94443f677c275e76ec00c4322f879e62161e30b7d94c7c72f9122e6c3827f48190372390e5e447d9bc595c5152a72f719afbd8ada9d1797236f86e51d3acc36ba5f049150f715a53fca607bc49c65ce74550f675e8d4d4fdc0f09c3164fa48e1e29478d3150e34f0f0d5057235737c84681533fbe39265ae58b0ebf7d7a3d6e3aa1d89f020406b0a239a69f24d82ce84941a1cbca00f3e014b4a62f8dd1087439470b7a0754291c5fba3bcedbb023261894729c581c47680854fb23a59a174209ee8896b3ad2fb3f88107dbcbfcf33ce4b33f748ff202e9846ce2fa43017675b17663de364177c0e3d4295c9d88fa0af25789c8d99a87c72f00e650d8d1d7d48cda095df9c5d30b6a7dc42cf5d7cc439b38f30fcbc42749a4b5f20024df0b76f08646a9c48eb26f84c39c6b6af371f62a0d7dadef67af471b8bc2e985127c91db263fafa9715f8de54e5db1a6e28258ddee4e3a9079b80fb0ed6b69d2379fe190b3688de3daeb4f117520399dab1d9d1baed5d42fa50ad5c60997cdf463cbe4add8680d009e52a7c68585d1caef2d2c72b8c07add5c6feafe6636ccc9cd83e6876f3144bb80835303c4bf86679a3ea725bb4b91d1905cec1de6 +expected_shared_secret = 703958ce09d7d6a5bb09e88de8df95c8ee2598544d50193be50534947530fa37 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = bda121a1925eae9139af19594444a8953b824f4ba5ca44c07df745fe911f5071975a5b4952c48df7d431a821998fc84f064bbee538569565bd0db70087654203dbc0cc21bf4cba678d1a093ea8b295789d52fb25f4d78d6986a0157145d054afe73a90f25886780044d4b9a4e112259d4a83dce439739a171f5a0fab0736d6731988ca74a56580d3c11dc3b187cd688cf066710a1458a7431c7bd69fbfe67b3532386dda99b9a08368d887414423d6c90cb69736a6a021c70a4c7e33bf3169aebd7227f5fa7f11927b315a52ec3341af239cb88b8137b509c7699b0a8578a4425a0dd535eada924f872fcc719aa785a0e0045b03b24d0f5c1dc9b720a4717e0705cedb88bca8e29a76043a73a87c867223f487c6cd7598bfa4194fb584f4028150513f8692cf17aa5d1009756db4b794f3c7c3d40253991923f098cd7680887935729c4a40a23dc20227cf18c86137482b574c5ab880ebc10c312c5eaaf15870aa4b51e59f70c35d356b11fc6abe072a501bb61647694d6c02a731f13c32a27fa5314a5e641836e23bd6a28c2ae62ddd79039b9365b007110dc95760367ce6a8bc2a358d9ea04cfc302663caab8c710c9f199c2363c4627c14b6cb5c3d3a0d9a3281f07aa5d67029653b2c9afa1375e343c197cad3caadffc0076ce91df0e21436cb368d9c2ff2cba5691acf472b4df839785737842b378cf29567db475622319328dc5388aca633531272b2c164a4a98359b0e9813109640847a8605815a9dcf84531e09b6dda2d1163cc19824baf076f5ef39e67761622cb0bcefc7430c07ef8b8bc84ca8f57131974e5a39244407d376fce88c340030f33ca7c21e27f2cc06b443a12937b978e68a2465b70fe8917da84700365a68ae526316c61fea6b0e5a88813e5251f83ba394b0296475dc1c77878db73ee4671e62bb66d50604efc4a7a91b87de178a617931f9406ec952cecaa8274d095c91062c0e0004093b3e6b36c9db094cb16a34a33a5890a56e973a12af859a7a2557235c50335c6418751952c1e3b3bb8b6490faa78c81d84c724e979cc2b368963552f21518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = pass +expected_ciphertext = fe68e5f9034567e425a37f97d35037721e74eb7f12591f59c0832afb43e1f3aaf8a5e4e62f86e151a0fe07eb292fe20c6815704bd14f1ff389364cdc1233b74cd4ba240168c9de0ec2f2c2ace3b46c24de977672049595a50c79b8695707bbd72850fa345cecdd9f93d6ae416eaa79659bcb17b98a974e3aa7b03f557aef8e491354b8492abbbf2fe3f39b1fe6b1208e92dd9bd8b40b98968fefed5f9101601b79007519f994b35b300e88c7c05f397e411cb990c895d0bccc3a8779c41452aa1c15071d78526929e2aa3529b996039792b3bb4d9b109bffa00fa796d7fe6ae23d4b96dfd9a16e3d91cbc4860bcec6172208ef190f56ae8ca201da34316fa2f7ee46a16154658b6c6cce17f4917aa711e43253ab2cccaf35d49501a22ca1f482403bfd8ee3cf56b40e7c52a83de9bfce2d20a14f858f7c32379a42865ee73d33d3215f798daf4e47bbc69b5f6a49451526d58f074eb8c0238e25ddbcdd30c8aa841a94e6b0d2cfcd07ee5ac744fe13c00e0563f75f2a63af3130fc72d5681eceb45ace81c8690f43594ac1e9d2a087db9022eeec67f425663c3882dc769abceef4e0b24bc7a42c9fdbc52247b70a93aa9fcc6cb77725a5f7dbbb806fe072a5d2955b2d7fdc5338e9f15dd5b95149f8fad00048c745a56fa7feef3a630489b8e3ea4d8cf8b8f7cbbe2014ead57a3a080b59940f835ff68473aeed19ec1cc163ef8aa9fbfb7308e5cdc7a45d4fb79c2b3082f031df5081fb0f962eef0c1bb967edbdf9b4fbb4eb95e73b29a948f2fc4130942160b80b0a9e402eae296697b3236ad570b78fb1242c14b620be5b0108d275b045396c8e4561a2cb05cd8e9ff877a056731654c6c6a4cd732c8d730dbf06c0bbe494e9472df109286670efe8880f897523f3b16d15e6821bf85af2d8c01a8a361523ee30405b0d4de846fd8faec5907f95db62a3fb4dea2f05ea54bf60c70c0ba664a5a3b777f9091ffb86a8ac9b9e328768700e82b4e7ea5e0cd7640ce0f004ef4ce4a236224288eb9899aa780f6b56b9382c0de0f2a68a7f55bcfb7887726c1fbfed3d75acac91643983faf2062e +expected_shared_secret = c86d221cbc5ff6a994d9111acbfff23f7dc0cd934412b17d89f0f27e3cbd1a15 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 5581cfbb9262be71c820b270d635c0002bbc92e596f5cc0b5cfc114bb2267640308b495c33314b8d208015888159c02831a062d7967691c64b0764966762c2c28666cc1119b4bc8541f016945c200de76f6f5a83605ace8dca54585a5f115434d70094fd540aae769450aaa7af961cd96239d624082ae6a494a000950747188236a3b9b170a597cae821b6d74d7d00c42ad89a31b0383665b4daf70a95885530e315fd75888e76c1113c0b43f80b951a626c5c59706138567aa786ccb7966840c7acc5e70c029fb38f9bd3b9ecd9b11291c808b44803c06f2241afc703834a125474ac3a926a1e24a0856fc27ecab603f0a82c53f94dcd8797ee25ce4f1635e2b18706032191c7834651c1bdb21ea8630884aac48ef3287093a95f7291e9d3bafd94574a41823f2c7f5600c6bfe237e09158e848b59f1702e1b924d47cc64f7b24beb41c3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bda063a3545f0cc8284e40bfa4b99d2094727f8cf006957fcc432c058685072a5653434a92b9ab4211343f063fd44572a23829aa8b19e16a7121b1f2352813d492fd91c834eb5a8e5498cf7fc76874a3ef8b926c0d29f3062588163a24c5976bf48797b694fd9b964b1cbbdf62a23a941c99fc986710a0cf2530f11f84914a916c6f704d879ab4cd3aa51f7c078006eca60a1b53075ec71c11ce0b6d8f9769f9549c2d7a690dc07f79396bb2cbe2e0ca72436879b0c8878d0a9eb9387c5759b1591c5339662009d449184690d717a8a768f0ce3056e477a9dc822b5fa466c0a85b3a0256a61b3d0e433ccbb6a9254222fb779cce1273cccaf7c51760e260e2f566b487b8dded9049e037290d102e03019c8c0b2983687d37c880a17484337a66467abee2b5c8340534ec6017a660344083c7ec21a729c754f3cabd2218dc2f200f48a3b67a07b7d86b072e4553be45cb50a2b424c07719878d4a84ad2d33453b783ad117577f41d6ee58ce4326c4c893711d66c94d6aca65c980a545b5521026a42318cd72e7f7129c60b652ea49b2dc075833c3ac3e7cc094618f003b26421bd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = pass +expected_ciphertext = b58756de5763aa23238a6b3a58bfb99f3498dbade080b1be63bf73d881278678e0bfa122b632887c981aaf81476073f3b193b18c53d8b782c48e73a0cb17f96b623975020bc5b7df38e328c5424b43a25afb4746ed0d6faa3785c9e341600acd68d0ce2edfba1c82eec60ddccf6ff5b14019238329b1b8b0d76888268af21553813cb577edbdf5f74854f0047832e14cf53a403e881d16f2e81ed08233963c3d1fc0e4b4ad599bd5317780e50f4e0551e7b310ab09b06f774c2d7dcc1d531d91b5c0145ed06200c4fe7402609b53a0bbe0c4de58d8d73b86efdeccede513525a8b8dd8545a3d0601b5e9da7c3e4549630f4d856945bb5abe3e5ee920b9f728cba5f27de7bd7f3d6f8721e27e811ac7d9cd1924aa244de8c6e1febb0f8778373e5ec63f8cad7b4524ea16f7d9a1e4dc4dbc36e5742a6f69bb5ecd15f4f4fcb6829e2474caddcfb0fd8cf0a4f6538d919b1583d748d4acd1b80dc584b47e031f1ce445f7c31c10b260c7b68a9d8e1af8c08e630f0e51019a577659912e472ad6d635472a5caaa22f5df159170b33001521a2cea14c4806a213106cdb0378adb90132fc5258c3ffc760bdc17acc309e9a7f43f56e955a577235bb03e2dd4dd1d5082c4d62b5514f34adc25adfb76236a5a44a8ca2f8dcc9b7ad9b807ba078c60a9041009b213e6d0a2df02ef4d60578f9897829016bb5e3e10afda3376308383d067fecc9c677339f19dec358a01684cfe001e17583b36ab232f8136c9cd2b99c0b2d96f46da720ec745c080faba6c3eba4a0f9d54bba436729380c4e9542625f67f7fe19ef75dcfcf6cf4b4c0778892ab036af7e8572660a2a9a0728315ef4110ce8e493fa2a7c98d98f9a307e86a81cb2a3f96fb69999fb728ffcb9b7922e8bba33e283986a9caee1c8316922dbdb2d1ed483f8775b4d7cbfccab2957815e1807ca85d18d49d48bf5d50268d84f3eb127cb90c106299a577d54812db3f8f331cb21af7806bc00f22e5da3c54ad81ce9d2578b69c48134cb117b6cf8057cd5172cfaf44ae88bc6471bb7fc03e13defcdbadb5d559e16642b822d90be575aa090e3 +expected_shared_secret = c0146ba47b3d4178919879721f69ac896d6911d6e86de1e8f05797d467053222 + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = 6845671057a2e8e3b4c8a70e757c8b424552b1b79f18eb72a64334ffc70b2b07203ed0870f6630733c26daf928dec6bef96a92064a738b1bc57c10c965d1740b313e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fb72f0caba15c00595af1b0eff68479daa985e79a0c5734987a34847215be37729ba51bbb1311f6f0800a37670d3a2f55023e88a019fb068382902a5d94a8fca972dd291178e039f8d2ca22936896c68976ca2309838416108888f13916089556a277e6958352484f231703d120922d103d6b2badb528a2eac86e174186b3278d7f480ec2195006f36583cc91c1288894759807692f15c22b9fa61ab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0aa1f182357104230349a0c21930f5fc760b821a07aa38b021123b9160d49b2438eca5ec5aca812f96cd7574a0761cb17eb9b71236b19a88d6bcc7e4a0751af543a151417d55093f6530543c678e19c330c63c371f84ee2d07d5a76ac273703b8166e889286da5c5055961084265f2e5817879713d74186fdf56793ec6c8dbbb4dd75196aac4318aa4f773bcf462586566c3c6e980731e7b8273a21c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768ea5026b61aa1698279191b69c39b53183c2745a7c251f48d26812eb4764d9196a18af28d91c54035fc149112ba7eec9df4421121aa6132e7069072a59a8739535c9c76959f8138112d7348c9030b60038a66bac005e38be1449e3b961850c1853450b33d680cbc2a586ef37e323891deccb16bc52eab1b7a6fa13205d38963acc148435cfb72803d6054a18c0de3a217037a257e157a59f8a968d250aa1baf88935dc54272bb5950303ac68495956689238bd2b595d7cd42749ae1b38097ea7ff90600056b5ff674a4c02b26aca5cab4379f0864a24fb14f24e274ed640ae6d692adcb3fe2541b9851ba35893967d39531b0c163d5b7f131cda1976e405029614399b7ea6cad628ac5245ab7552fa4d2acb10aa7fe2a91081707c327cf88192d904287c47014a4c51766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = pass +expected_ciphertext = e6447c8c12903c678b9e1aed0f6c21cb820f7da79ad704d07098a1c6d2e8757478fb606d38d006fb6593f8ed5e5852288e9625a164abeee5458e88e8a1a1c0ef43442eb5cc22affda6c867bcfc605ad210b7330b7f8d3e8d9a364a9ada51298fc27d27a8bd87f8b6a7b8fe3c9f467a027783ce6f98d3de72425ecdb46c9ca8910fc01b0c20fac06989806f6b4630bac19c73218987d90b1e41a1e81a90a9d278db5b6ebe4f7bc8ce196708a47bb3c1a07f1b05c34cf9b47d07027063b6c01a0484e88726cb423905cc09de48227e190f2d7e6800495d40b5248edc51e5ad6abafb682e3f91de3667b5697d02165d0f9cd409af52512ef65c9f8eafcefc75a92647c16f89b52693c05be2c5f9a8f170ece0e0ed55fd21780c092e48c464e07adc505c38989e692add2e7cc1dbfdbb4b583c01640a25eaf1ad0fd3d241d83a641bd4b8d6585d18bddeba85407531abfb7245588346d8a31f59d115e764595231e66323fa6b6d713177e6740a9ecdfe540afc59a5c659b3cef3805acec9fd0ca03ca0f5c4e5c2c89eca46a02a0026880923a8273fc0a28fe8c9a06ced412174f245eb9942b9f08ebb7690833d24c594e3ab4ed24f405d68890dde20b6d2865f36d6ab4fda470b0e7d4a1ad0623f814a8ea61084e99197123678831e3f6881cdce20eb9176deeb2787f359b8af7e0d4cc85f9ef9dbfbad12247035ea1bcd4c4e75ccc0eba9393ce0152edb04a93a6c58989f5269d86b9f091bf2013c5fc8f2126144e3e1b260f13e54649c91a6ff9156a94ce499e753b0618aeafcc5c0e1867601b0c4e744779ea63ecf0dbb5f85781211e0486e0d1a9b1b0fc01750aa728c8caebe9e7fef5a3bc9bd6a930bfbd4c56996edd1bc329bcf2b5439055e4156404b5231ed8f30baab6ccd8d253616d5cb0cfc8abc9f72ab29788607cb8145f496c85a01902c8d22ffc5ddff075fee2569e1fef59ab5646a85cf925c899cad88159df336733f1147117522ff133974419e7c16a95406717672c538112b00ac0ec01c720fafd85ebcb898882988c9fbd9b5719ff5797002939efd139da7c1f11f35e3ad3a +expected_shared_secret = a33f72941e0947735925e5be668b3481e0cece75ef48ae6db0d66f0fb2ec428e + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = 781451ec9a7efaf8639ea457c023088684a91cf779fa465940e25955d47a2df9782838648350be44899b198a706c6b5763c2a170c8c5f87b2f9a7b6af7cb48efe386c28c7b0b19a808f24e3e2b6b212a3b8b9a19f6c47d484893ed89cfd3f678207630c3844e969c967eba8926461a58826eff42beae5339c620607a704f91f1b056fa06910746c7e002bc617ecc64add1090ff1d1afaac53a40487b83e9453e6728cf352415a930079abb7e5115bc0745290c706420853d080377e921b5723047c22cfa289d2df186b1908a7bf471e5877fe23b30028a34f3fb27e726b99ba827d347c62997314e39a0f4b2b1e9163f53654e056aaab4718609983bb674a47642a81b000ca7422d3e361af12461b8620064547dfb578959b18bd1b61014d20315a659a5ca65f9cb4ee214b0d123113e34310c56bbd99737f0305f6f3b49f688610a777edd4a3a482163e6cb2c64668fc3aa024d789219078b49471be7dc4395346e7f87c5b150c1e7e30b9d2a435e7c3a32f7c4d33622d7b73cdda989aed858fe4c7e9cb163f35679b84b01096a1e2c3897c290caa996ccb3943e22f789d3c5098aa1a6f117347e0725c358670d678c51a0a9d5f66aaa6923a895cc5fe5c9530b069397a0e4482438e713290c62a94771f7168212a7cda8e2139d573a9ab0137443180c213b78a1b5b291a0f1566316857a72a521c2b79c660792acfc0f5a788962a6ae74e87c48a8010dd6436672817a00b49862721702668ff29f1077a87a96cc27038e0a2752a0d196cb17babc25b2996054d61c68c691c93a6520a97392830a8f157940fa903e75f909bc9691b86391ebe3611e04c9e0678c189b7875d373f0b25b9fe0a9b063cdd4446ab9aa6b23e6ba6c324cac29736447529c76c3398218152607aa5488a5e7b243a0920984b06dfbcc410679ac035ff824768168c758689d0b326831f5c10220c10911540c5b7f9a3510d73cc1153a2fc2a84b8a08cfd7f863e6c93e05f05a39da58cfb57dce98cbf1b7ab960bb14a9b86dc611045d1730f3b82e5eba970018bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab922085c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = pass +expected_ciphertext = 9611839ef5c05fde9b32a92a2bee7ccb6f870070884523b365417e830648467cf9d9c34f5b544ec6c646448f4737db5c78f8d7b2d4009b4912bb68084862a75c090c9819b1d765eefc1574d45f9f9cbae90795947190c9c5acdd3dcaf3804519382b51b2e1d8228d46332be81dd7e211a5c94e88808c2d0398e5bab8f5d68a7dc81ce9cf7daceb7b2395234980dba509ae47bf660f7b9449a3d8213bc73d207d55b97a6253739522cba9490e9514127350519fd67dfbc87a8e008fef806d422a70f703b34c8426911c6cd33c691969b62fabd01716d069d6920acc51facc37d58a69e2a101cfd101b3091496b301b0ea8e881bb36e5fc125f45b7df174bd1450e603ba0f3b66e331585f1b033d9f73bcd4c3c556c88f8e363c47885fb4181bff08b56d8bf0f3e5695e791310ffc5445e91dd7a4ea60e7e9f1ec75c2b13c19310beeb4a30507cbe4bdc9b5e46cca1eefe6748b095a87317c19639934f6d73d55d0be243845aa7c5c56a1ce2d432a8647e6fe9b7cda920cb777c58382ce1fd6a3bafd73c56487e5ec00a5dc0556d6a0c87185ad2527a3efbc03ee3f752dbf491556b68bca5aba0a3dab531445fd682385e8d0d3f49e54fdaf41eb58e4c2287983d013ac3eec0e4d45dbaa93a6bfa6bd9579ebc5e2f9c49ee45ee402fa8702a6e734a2c68e414ec0ff0b69a1da9c6d9ed89e97efca55901b053155c2c9d5d2c83c8fb59d65535ed936ecec4d493fc67a6595178008e1d237de84667e120ccf9f30a2bf571a6c7188726026b14672d49c9afec1c20aa2e7e272d01c09c562102e196464c0fc67a2f4edfaea9dc82000d2469c8968696f7f8e9c89e4941e1f03a9d9bd7052a0cd4be306b5cff1c666cef6c69a150692ee408307ae315a8f72442f63a9ee1bf07f1aaeabf9d473cabd9261abb8cf93ea8c814684a05cc83d3e6008d25a1e4f03dffee7303c6e473d3f2084fd85ebf13c7ade84449244e6f4af792b139a3d7c89e66f2e4083b1ee1cc8d90c0579df3c9ae83635f9a3575289f0720789e04e9e51d4bc6f169ca8ddca8e1695edbe32db5fce382cf61c6c39a520f3fa102 +expected_shared_secret = 3d77b9b4ade74443fc573c393b82c0cfd2bc2769327f273c14e66eab9f8d9ebc + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = 1534105e4b3bf53b1e728b61cca6adea603ce85425d8f251b4173f288b2ba4e61a1ff409215046a381211a26b897479a5b1b3623362ae7d22410d9a11f72cad7c107e5659731a6c2e0e95c956386cd2527b29095820b6268dbaf16c0754b583e8288787c186de1f516b204705aa1ac8b80ce70b9100c92093c3a7b69ea8976f5c5dce45b391aa28f0640940166741876baf7b5b7c6878a87438db18ff45c7371016a27e572360c4b2fe4552af9a1a47cb82dc249f2c8bae4197de351a48cbc549e236eb895c487f27ec3e765101a2e68860c61e93022292ec7435df62a1012d78824960216c4ce18e060f1c4af2aba5e9ca9134732149d3a57f72521ec9a97d059515ad9c3add828c75c90f6300e5135cbc646af16866aca30b6bcf60fbd9c0d1a2ac95b999e0749a3f5b9a992e18a8257af35fc9f7e4bce74c87c7496cf2a7a16d966cad9d02260f630d2f1b011aca52f78b6f040759068c0f3f553a4fc0dc7c9a4c8c05ef6c9b026b3be38f0c02049b8c89c88ad01a861f2b1b142a961c62f246a4c19d2cf1849484f884119a823d793a5790420a8f74f97a220ab8b91d475717785c12abb83291b3fb32c7bfe836b7b61c03ec76f36d1c8ca01426c28471676302129116d2a5ea5d415bb13188cd720cb96939f21c7d1fa17a59589817011a48cc65ad90a7353232e8a3db9ac87d425771c7b5bd1968498819dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7d61ba11bc93007147ed613c72f756bc367280278f0076addf854e837b62c9458c34f138e576a99f8a4baf5b596d327149616dc1827d2ef5c828d4764193b4f39a4fcc027d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c5449225132b1c764e91cc686afded843dddb97213c28ed00a6e4e4b66c17074181cd26b15ec1f3c53a18bdd85a6dad68562e3b78180066b4c4c3401aa1f752685ebc8316d6bdb5291e0c39cfe778b8ce55564aa50acae94c4962cd942271ef257bf1993ab04904832a9538e0749c97790f26a09c2c81d95543b5d97667c25da1c7ada9e9780aec099fb096446c03fd1a0b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = pass +expected_ciphertext = 0393719568d07dae3cffd36ff67a93bba3017a81a0d5e83c07c24ba0727ec566987890acf4c49002bae7fcc834196e3b33f944ede0269fef2682e67db70757330e3ede1d8fca6deeacc178ab6b880a3751b1878c40415dd0aaeb1bd33a6cab3a7049a7a72613cb9c0a9957096b827bfd5ad607cf659a03c7cb6c34b2539ca0e195ab35b104d99745254c7863119ca7b03c32774f18542aa3a911bd00c8458ba9cdcfb3f0b6edcc5fa51371d58e82b3cbf40dabde56152b5d4868f82e1769874cb87be8cd62441011b280563bf2036e53b6e710d04e52ae5ee4bc617b60c25b6557537b64f3f671dceb90264aa4018a4d22d9e2dbb67af3b1f03932b93fc8fb78fe4103ee9463933b73a371fcdd66dc2012ce5df74254c440e5ee491b19a8bba884071bfbdd72cf865e4afb79cde00ec9a03b16dfdff64508e3fb5093379b5bcaf11f72148dbaacab35c7e78a9b811da318d109213e7fa5f296acf4f4d1d34278a3e9e9dcb50bad86c717cec38cd6285b743d3bddfa150c7b6f2c870e311ae8eba5edb4837c85da01d1c5f3e33b173dfee1b1c9e77649fde88fbc18a1f9bd7da55cbc96f549da361fd88455edc7e1c772d1d1ed5c7e74da4c9a4c9ecb980ae0ce3a6c4260263b09469cda3bd25242185c5763f982bb59fb2a964930e919e28682bb83a3b1916db2a80d18b1c04119f88969026e13ef30d29b4cea6a02cc29ac4c0e5d8b48155d95e46c7072a25f3a71949aadc4c8d87b0ab3f62c3ae94d963f78939e957762b72f4a77c08cbdc06c6bc82ad0434448b9450dbeb77824db25e70eb43832d06185353122197cbab1c07312d340ff04f3e53a6913fc7dc051274f9081e2c9e452735ef560c8587b09b06d44381a356c7b4d6cadb5cc83489433cc155e5ee9fcc5a3dce297cadccefce8c5e4d9ce70d5ea6e21a0c96a764d5765e7979369459067324291223a8e58c274966ce4d22a4d3df52416ee6486feb3b979ec6f8033f1411b1462b91ea200de02581c13edae24d377c3b1e0d9763c444e270e5f186068450f23765ff74ef284e40a75af0ef07120d16d888c5defa6560d8693 +expected_shared_secret = 812d6c4becfdd4a95f234e8fcae1d9b316266d1c519545bbb7fab8a19f3519e0 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 4098cfb36505dcb77ea88c2ab18a760aa67c49228b7e5bb524b5c4be081fb3d8b92cbc4b92ccb4a61a1b1c14521ba4a898d46ba44168dc5a47af9484aeb453c4fc56eab73b0cd0407f5124ccf6b21575805e311af65084e2b0100202a1a39a866ed038328b75bcc206b55a90d714a7175c446dc2091b057ca54c111a820e8a75ba0206715a3042dd0ba36d2cbbd72326532b58b02636cae1949175bc51dc2f46ec5736ea91023657cc65aaa7c22158d22d76a304f796cda7d377c0e79a4aa683f341b7d0321b623782cb189ee6eac197860e05a224fcf12f7cfa8208054a56039485b11c1d888f51c479507b8a85a57b51f5b824f3a9e41274cd188d2099765a004bcc64a86844993fa69c0f63190c347e5f015c6bc290b39cabedcc3be8515905a37fd746616faa036666a08d537aba7a645a501f1cf0c0c8d76d07a67f47514c4c49c854d0b8d3fb02fa34abffd46620e886e00700c7c34a2a9199c78c23f58278fd71c0369b3d0288b711ec5775c70334e984c686cd8e3a141f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31eb51329c8125e8079557a63a53a8a31f245db209cb7375272d9689cd94edd20be8a380f27ac993a9287111cab084c196f4a921b6270e43366ff94af4d4930097cc847769cf3b8016e024733233e9ae67f8f1aac07b450d2299eb1c7ca84c28990377ef1150ff12b14f99b9a1bb705d719321e384399d675b382beef53304074c518382d341578e96b8e123312112c2f4dba5dc5b7278ab251bb3c530bf104783819ea985363fa8b44201d4f1c5c46497ec64380fffc553239cab6f543453485b6044b7b5049f85323d0e8614a8b5c28b52633e72c64db6d0438aceae55b8c239c6b06bf660a146c1a0b132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613ee0520dab93b8c15e0a301f9aeccedd16aa71a9570f31c3cffa013b27a1ec259e738bbd69164f5cc002cba96c68a22b35597f41fba0cdcb81729ac1c4ec49507683fa304d00dd398515ad3e92c33ed440e3013daf434712704921123fbf628531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = pass +expected_ciphertext = f12f2ccb97aeeedb7dc3a81f0c525d2e7171c45ad0853a4bb6156bd163e09a5a27251dc51b0d6911195407f980b0d8d86b65a3045d52060bf1b7c1d76737e3e0e4e1a6604241d4f0ff6ec85396d250a2e61ee3f569fe231b8513986360d029e99023e8f59dda52629c589b60cd4900522512702e68f39ca61d1662fd0bb515f676c76efd31adbc5b488450f1ab845bebfb4fa53ef171f952f6c7de0264c49ace51fdac564ba48fd3967fd83f18e16d827b090b966511f6dbfc435d86532e4f2b25e2e31eee2b71e85dcb923bdca1ba0de1dd46ad8ae00a085ffe0392693329592dc8fb400eb03f3a5ff5d133916e8744a7ee4fb9dd7249764844b3608540a1918e267bfd0f8f6333d241ccae868ad3a8a5fbcbb3aec5fdd3b4bcb94d4dc945f1d02c141f3f07e747f4a481402c7ba2cfc0796d24682bb814b71983b6823671c0540db1fc64b1802dcba49346fbf1490b829972d330639a6026c75e9abbcacfb38bccf271f8e201fedd6974d2a170f6507c4020ee7a2d70aadd79340f1db2a64da4261ade72677a2365dca25c22226a70c1140f709cf3d931b9e347cbdf902996b99b031f3973efea8f17858dd81245d631050acb28df40cbdf7a159203dd8f7feebe936941ec73b342340f9a46af07fe5258cb05a70ec04a8bd7ce4b81c67befcbcb4a4eba394d7bf60804b6afbd4b716987b874d21c0cac713adc3db1ec9ee3925a4f48664068f5866f0017c8056cb59730ffac1db65e235df9cb8908376ed4e06e31fb4cef840f6503923abb60361a18ee52eb59ea32e35521c90a21e165c1235a8eeabfba3d8274364e1f5440413d5f64f5decdffbef85f7b269da98737b30e17e7f6d9ec3a2084d9152b4e2b2e91a1d1992adce1769ba0e10b2d79c4850e8baf6f14a40f7223b301d439eb1caa11fca5c43be5ddc83fd432d1acff9ac9934a0025384d8d8c23eb6491f7d0731a5cca075afe7900d028715bd8d1ee4c595fe15041f253e3569ea5814876b154c05c78b1d1189df03cad56241b49bd8ca4e9ca83e47de19657ea4b3a08725e4d45a1068bbea9463ed57c05a65e46d0a43b73 +expected_shared_secret = c8757f45a1e334ad99a0d2adf12e79ef2bcb96ea1876bc29a4ec5cd660923d82 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 68517fb17496bc71146b716e9c289410ca7ac5fc5f663abb1b7672f8115917c610dada39ae344dfe805568a0141b6103a9d07bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326043258a62211ebb3568d10b46b08864b637e94a38b132199001a5f34c5e8dfba0f853980f071d8125c12ca665e72673102c05d50b28f71696f90c274e74cf57cbc86be00177930fa0a1164a245d57b4b2fe6c4e0f740d87b8695da43a98e79b3b102efdb35253812336c1058e727e14c08444f24b1415312185b2afb6ccd9b5920781ac0b5a7a483125a1a2300974c429e7957de3a796a48996f1579982adeb538dbfb8867a855059622fa7394fcaccc507013c910c79558b1bd4b5bc696052005c8c413253e6617ee827bc31bc973bb0bca2d6ae0b17239c1210b4866f5802086460589c64963a83a3ef18b5277272030079b3c2015cc1544985c687a438e94145838a14648c5ef5bb46a0988f42e124397bcfa42a2dff898efb586b2c6aa86b75b0eba10b2aba678687822ed5ac8dbccd49966e2f1991e09260f547a4b0d02a6d9b31ed02bee1764f7a5085ebf51fd5862550e0a19d05a78a80276ca0414ffc07b109afbaa9ba78674b92c5b6df20a153051a3c2378b7d05882ea15ac2183a62b8efdc15a9063b041bc1ba601bd9c16c6156c6e4ad82c6be595152174d1527a6555b42086be9d05945a289ee90c91e525b8a69324aff21306f5375d0934b49677b1f288d1dac1d1918adfe3abf0e738c81b0087e22c1b23aed4d742c283ca5530a0960122cb2a79c0a2966c5780034297fb4c1569d2b73127bee4e53016b04188599bfc468df3b091cc0a62a0832137127eaadc7bb0176baa45788e994cb8983c7b08547d340092594cd0f05d3baaae475092c3499e73d16584daa3e3f31df226c30aa49e59313e5dc98a6eb16f40875fddeb735ea6cafc657db8692d28c35c69022ad1e53418c461dcf46d5a40046193ca8277b28ef606a9e152946b04591ccbb1b7271940105436644e275d6f4503b5a32fc9907bf5c98d7f90623b822feb0c033a1b90d87422453a0460087b81098c163c295079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = pass +expected_ciphertext = 7b901088572fd3d5646a8085fc48026ca4ae5d33ea65a51deb6ce1da3d23c4dd748b2ce6d24879e9beab75469b2c31784d5074e5d84e933bcc638445bc01603c6b6c916ef5b3fa0847dabe4c5d62659b40a3e80686b91d1bb274d371b5860c56d042a84a5e0bc2b110a847ec6f6374f8770b5bb2e7eec9310709c8607fc09d3074ddb08a48bce41de572f2745d652f9ac11fc7e4ad465a6b09934f3641e6ecf60b4474a18e176781279be819d7f3a0adcf19ecd22d48038b5f1090cc24ca9ccde889c55c599260d84d036bb7b83697d463c3d52ce6324f6c49ecf8d6f3cef3d179454e6ef23da5c09e80830182adcafc696860b7e461ae9b3a62bb55c78eed94c94f5dd01c42a5fabb04e90faffa1983e6fff3a402f84ec8b400092527a71d613f6c029f92367b67783434dfc83c5e10291983712b66518074780a7d8bc7555e2e8498cee12317d030691065c80a12ea4c2fad1575bf85c2d44b3d90448638db148eff07b07d3cb6fbfc46e0172b9a9aa8665ccd2c53e3de4249f2b3312be8632942c14476bfab2d40ea748c2754f36d10b4a4982a63c6c3618b98c963cdffb219088ae2bae9f4948c61ff8bd911389e8aebe635bc40468d802440c6e84a7e1af45ff0dbcef205bb7da3412f2729b4835c123bd09af81f4edb9931dcb15e3b542e812b0c5d5467a184fc8d858284ca37e3804dd86ecfbf414d18b5975cb0c9effea4fbfc53700cfb32da2a9d0603c35a635d02e16cc33644eb7a4af1370f1052afd81db54a13b65faba18a27a7fbc22c0cb2c6b6af2f1947f6dc3b53d1228b577151e676305c52a5b38156963565404f8b7d358519cbe9478450712b4022e4099a3ec59462fb256ea125a8337fc5e5dee4ca4b68615d8d29133b37d5946f0d022b4b84036e5057ae75fdb638cf8bf5257f11fd2cd55795471cb1a552ae0c533a04f8a00b343431a7fc360474c9b2b5a7e52dc3a0812082a38c235b1fbbc3d960e1149d7d1a816005cdc62d56d7c1ebcc55109e48342f56af97405e3c3805883460e8078510d4f2f7c9599f4dc804ec76311ec8fa6759df7e8a94054b04814825 +expected_shared_secret = be765dc236062da9d3fef68c645b9a8a5494c351d37790c1e7cd1089d97971b3 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = b130cd26fc457b8ccdc1a7ad81ac5db25945132a6c152b12a29c8149419543a6bab0b8af5dd272c5a7b19b82199e943c5a12280a22453ff36c7b698f40d092e651cbee12cfd3843c07da95fb5168a4f9ae4553b149ec3f0960199f6375499372247cc59f4719916b168f02574e1cbef360cc18c3ba41a3258df742d9f6b32c076f695a7da1479790d9a1809001747002d8f488cd54be71022e134a4e8a9aca21570351248a4daa454fb201b5e57d15b30994b374277b3861898734436c736a2fcf0a9214661551ba8530b6ca4f36a74f8933b3c2bd0fc89b78146871c8849b31acd0fa55726836f8a6a2a36a32d43b78f94810141c6b18b4bb6763290a289ad6363f08816c3bb3a2e519a1dfe276f6814b7f693958f4746ccb68cd320ae60c589ea94023c7adc3c680a5c17075d772b28bcd8d109397407b60c2a7ee00758d7c52630ab0f686b510969404cc1a9110338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed0a283f71912b69b40d6a1f84a56576a02b129409e2429d44a9b45858243279a5fdf07f00e6392c662de780a5b8f82ec6dc248347c9a02062ebb67eb33457e5d36f10fb99db0171ef0949d117be5034ccbdf951a46c7497166294727b59c4b63034435e41c75d70641f800f0d458b23736ecb76bec2702b152389ce91736890af06840cb8d9b8f375a33b03438e9236fa3a221f83186f77aa388c840e2b6b9328710a2092faa59eb8aa2d59769be77046cc334f9704c8b855a787373dbd77215f268946e5c8792aad13e645f292bc73487432897c50e817a1f15002f472e404298a785b26f441ced2b5c7235c7f3b4428d78a7d47cf4b83561ac38da9cc124eb40b44b48231c9078702510326095b2b3492b82ddce7a433e97c65878f8fea220459bf77a81b8f010ac66ca102fc14fe804680fa9678c41746211444d85aba5c57051422c69630acfc7b86a843a74127effc452035b41477ac3ea934008076f09796323cc9d1970864300e5c309f3d7a3419d25fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = pass +expected_ciphertext = 7bec5e9049219304153fbc35e29817fc3d6d454278f6e0bafb207f7911fc725982a15106817c7626e3925d992de0f1c50d158d3b37fad4ee20628a8d8aa4c8a12e47d2255da69699f6683c6c09e1ceca8e93f3a6b8fbaf9bbb42878931a55d7d2a90c8b48e815fc54ba065049970c9e4323627fc13c908f7c939805ff886b24a659ab7bb41b6f34589978b129d78a95f3272212eb3c51da7234a9e46d86d16fd8fd37ab7361be0fa74707541f635dbb9ad999d671e886f3c391fe4c5dbaf3df0c3562a5825c00357db49720cfe54ce633e10100c4df6fd0ab987abe2d83ea800cb750a812d7e202e2fcb0290bb0b9ca9400884a9107f540504778518b111310526a756c155f107b5f460b5822b61a15b601102f979e521d46823aaecb41500b9aa1d43c47c9fc312752a2e41ef6659d2c3f426e354ad932a0398138045904c53b90fd388d93ea2eab7bb6c0abd6ef5db66d2349351d10ce1eb8f48e4f4306254c44bd798766efc3bae38c4a70f6e0c72c78e76c990b6766b2b2ec349f3e86af0a15d8fcd0c78c6695852be0158e9270605372097054fbe92f5c347a5573dea1d135c43fda7871717149752cdde8daebdf3f901cb70acf4bee19a77b8f1f191beec686265699e939b5693e0c96b8f8537e26af0366f59e3cc86dfa4800de586222e4fe021f92e01d837383bcb66bd217608311a539725d260e96e31cfa76980af8397c0c64362e17b823170e483667453787f31eb4afbaba15e37d000c5677298e7055a09a3b4d0e8c918ae01b17786848b4029f802ac4dc7a5a68cbc020b1fa27aa4c2c48e3042761faf8735bb865e7c521ba2766c11989ee2c5b41ab4d072134f2fac550ecbeca827e664faba269ad09ecc163dd01243580d29e735f04a95dfd58d314853ec9133361033b4729ac1fc7217e13611c486e531ededfbc1c9f3923191dc456684fc09a8e3842ae6d09f42da68df8005ca7735c87c075275074bc98635730fa518c866c52083314b4c31eca355e58382e4d2ffcca578fe1cada896d046a48fac96aa341fa097716cb05c8a3cfa1bea7ebbd7ee2dbec57e0c71da59 +expected_shared_secret = e72888e8dc5fe30f0a9c01e2e4599a7046147a81da280c393a48bee1b43bbb5b + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = 320558ec426b57e36419124bb8516c6b4232728a1ec4f1a51dd01b932738d9b00c6a50cbefb657969b4dd318295b6278f73963da647156944423045978c50d3c078e6d0729e0219352028970272f34147900370d490c12fce9b22357bf72fb470e748d82b79859133d8db603ac7cb2672ca9c7226b6e99a7488a219966b7b897ab398002090b4900acb068a866c50c3867380ff5eb2e0c9c4eaf497adbeb79632b0c023474837709a3d7cdec9c2f782c9a3ec0c6ddfb37cb3321db6315f0b0ae23e7c6a4e291baa61e4fd26c98f36f69d75369f5af277124295158b2506a39eb43d1a16308b71f3bb5cc26897df2378837d9cfa1ac4745718fc3739f5535c35e07b461a8cd65da18a3809d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcb41d00bac933c3783f05c47ca28058558cc05690bae3c507fa8d5780227a61095f0171a6d826f714146c934b80e07672e6bd66432ad1479136c06dd1a29f00d18b26ab9f8fdb7e6021ce7c657948273268e6b65245101952c73d949c4d82c8144a3dbfa7a82784844d57b354b1598076258fe83a23987de29261b0a8761ae3167d035e96b78fecb9bb51055d86e46466708d79a8b732b686a23b7e36f9ce07ba6956cc46bba61ce934af8ba7738bec5de094010aec2885a8153bf71f002c9eda917f337bbc18da2324b45bc79127d21b1c12774c6fca6a5166c4f03440af4520cd09233d493461420e5ff81ba290cfd23001052a9dd3665121392224746064f00f5b1a4dc19528a7b95c524304aa21164a45c964a7320d2611c68498faf56cfc195373267b01591e6c0a8d1bc0007ed456a4e205c49495ff99b1b1754a9e429346536d16e015dbf7967e851974b19721e845008b76b2c47e7c3b04457c924693bfb6007c918c64cc28126665b01cd18b7a253bd0706d3c466eac224fa12bcfd60417afc1b865029b672663afb3ba51b6a2b20502de6c6bbdb33a0ac4765f967f8d685ef1200ae1d17cd5b47aca963f2ba5cc38059b6937916566a219ac32157728dfec1b9950687ff543169a96f648ad2501948316b55ed4c1e861661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = pass +expected_ciphertext = d142e18d4bde68a0ae2591fb29bbe402e1aaf696a66958a5893c12198e950572959be34051a5b1658856699711699b1ea084fd8256daa7670d089941d069d19a321f2fc93cc625a727f1e7e7364a1993a10a03bba6c7c1af4f2cec2b12a452ca1720029d758559f271e6fab4343f96129875dd486ce6c6f14d103284479bee0bcb5ee6921688cc3794bc731b9d0916198ec510de76fff04cc27425b141fbf75f7e12fdaf1aa8e6cd097eab34c1bcca571df37d7c21bc12db3992f74d301762f8df0353ca0dfb827e485cdd8bad1f4a4d0094e008f9363f6cb0c8f355a42b66821b4e1b50fdc237fc7dcedaef8949d7f0f4b287c2c61548f7ae9ea64b7e8f4231e48bd5e37615c9fc9e5847ec4141f4e017ca86fef3f1df6ccd9c4116b4c8203caaf93155d57e3a243c0fda8e817a62609ce9e3723c39e4bab122db3fca8b738e48577a323ebb23528e8d8b69ad9ed322a23e8c4b8b423d2cf6ddf59429751cfddc32ce28232aadac1fff70352b37f727017354c7458f35b8702f15e2936eba3413603ae0ec0c8a17dc39cd1794972001b36d58f0cc83889c51db6656e85a68c6d6d4f4066b91b72d595049991da088bb51d29ec2cd5433aca956143470322beae2e60fad818e27d6da11252edc1fe5cb11ed8f7d0dc857f948ef779c75550c265fd5119bf95101ecafbee7fe603aff7f84c6875c6a48879c581525e479d456d0866024560b215aa572ad31776b2ff9ff1aad59fc013b86acde4151a17234b4b114b90196d0502b3d01ef71d00d6e8db3cfee85f91d8be6b650327fefb86ef186d075d600c3240ec81fa333bef3a0917e0d5b8dfb617e9a1b813f55c4736c9266fc73955cf9fa3824a0d7195ac5b356cc4fd8c967518d5e0b025bec7b2b2a79578a50534b2cbdf0e4b85e9cd69232db99e2015d8d9b4af15aca02173e88564c0f1bfd5a532051ba20cec7d16fbfbb9d83f01f885e72cd50897e6605e540c93502bd634de0b0d9849eedea4c567cc8ae47e14def90ce5d7c0dc93082f1a2ce9773116cda4d59da564ce8fcd0e549e4c8d25efbafc4f0f07a6ed7ac2aaec1dc04d4 +expected_shared_secret = e3f13c77fa9eb329c218e1bd5823d6e07249fa1b455770ae57b2a00aa8c69c5d + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = 16d85b965a81b1f55647985ec3f58023574f49003f67d1847c44a40d48a2d3d86a0e66505037b1a9898be7010d98c686d496c646babf8f998833620e287b7464f8005bf4acb8839d93a311e99ca4f889b123b81f6e740b604cb86464837be291d1f4a919b07dbcb9589a228286ea1ff56554a818439a3c8f1753b459dc557ed135149553d7d82b1d8c0fcdacc3043729d6ec9511c6a3f279783a2a8457817df77ac945450732d148f8964b83c16e7319ac67acb7fc903501d466fcfa22ee13a7010615bb7a2edad26fdec633397516ce0c36d2288ef1fcbe2e1b459348cc6ea669d8810740b2b7581a9e1f62825d80c903e57d40732abbdb7736e8a1a1ea9a20d217d55b5355aab672e61ae0d183e660c182b846161147aa1426e34269636406cf142cfdf43982a076be1ac956e114c316a7d6921674f6cab0fa0c49c91e01ca7ff76b61d06c13701892e208390edc717447a2b01c8a2d855c7487c37a0043644b26fb3a446774baeef30d1a09a3ea9680f52449df85262437b14afc2b4ea62504f443af0752b97620ba8145b396ced5366dbc9447c010740614360401be32903f2680817542b356a7a6ff830e944b2af872779f34911d9b99b0a98f3198198d73922f5567aba3b8a55b2341fbac3a2a3dcfb46256885331417f4eb8c209c235921a440e8695032247600c885a82acbe34af41653a33200ff59794fd98840f94745a607931c1a8a4450e67cb23a99b46a4368b6060b4dbbb5a394820a16bb139baa15af551b40a6b01232cb99801cdd4387f23ad6dec96edea64b64a76fbfc35587508733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddc0216d226bed9b723cf846aee457b0ec23c59107caaa49a3c879b761350ed319a828507bc687561a87841e56f37f4b4f6f77e253988f38488ff2a1e9b07257268a209f9b31705bef791236ce9c193f2980ad38c5b9939189a618598ce90f435221214259c6555c7041e2a9a12bcad5b86cc04842d992834425a10a3411f5609af68a525290320cc1cb607974c6d19b662122245991efa06cc6f075e84f2b025018f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = pass +expected_ciphertext = dacd0804d8149dbd55daa5fb79bef7882172b99e1c7cc54be52017ce6dc3fb63582346fedec4d03341a5c26eae631ff62048ed50727c78bb5e1c3198d7397629d2d9bfe9c29d8c22661478b011f69d0aad3d0fe11535c1efe9c787fa88cc530cde42e6b69d4a767f753981e3dc150877851ebab89558d2cda3a9593da09b763cb196b3a1d6b0e94678af167ec61555e30877e31c70e4646238a518d8f590c89a10826e592bad0c1380fb795d44536ac1c0b42e9dbfb52726846b01c3e2e2d55b52f7a6ed8934f6841426d24c6629944749814a032eb3d9c2558cdf0eb990c1837959986a02feeee7f23c611fdcab8c0c422f4ae42c54a21ae3a1d36d25fa911bd48620f6e0d6609324faed384a866ef92eff8de2f672fb0af5ffaa3cdd2689c3eacdf9be6078822c66aef17a03b61b2cd9af1654250a199dd7920ea0eeced766745346ad8ead76164e46eed1df0074dff91054e79bfaefc3df98139ce4875d46b506003172fa69c7ab9d0bcea3452be59c56945323629fc0e6a34041b86a59a44460e5e175ed8fd34f9ee485937bad889ba5344aa9139536479650366380f1fcee5ca33902167bce90ad9bce466bda9c0a8dd04ebdf0dc67688853c2d4e5c6710e867d3eac14a62651be709053474264b65739f7fbc725dd2c9c94b8e7589ce515a741d8955b10f9d447d0cbe90fcbf67aef7d52488cef52f2422968a8c550ff4e85e552e3ee3c8c7467eca1a0b6494ed3b8bd0bc1faa5b8fcbb055c8986912976410d4c0b9e4a81116480207d5f550bbd78cd50e729f4c34a367cf88a5f892770f9d12633cb0faaa484ba2bb50a8f5e0bf99bf26c25b64a3165da9bd53da6cd616fd8209d0f87d80233b2480c1ec13ec8814c0779a4fafad00274ae3b51d058ed077aa3852c0f2b86709314f195c7d35f20eb7c3891199762af63473e40efdfa9012585fd6f19158022e60e5151ca5f091c7d5a28a28aaad00cd15ce6555e16b9ac455e15ce701c2750ead3f933e03317948a2782e44df993802f5da804e96ce48359ca590976765bdbd7c9a3731dd33fd9abbf40b0e9fc494a895fc40bf069 +expected_shared_secret = a8498502e012b5cd006e77fcbb9fab801dc3748a0da37587dcd41310fa945e09 + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = dd08cb516c78a4619895f576bc8b3367f99d50aa502f365a5ab881d18044150539084a918d43a002665f4dd155c6bb9363127412dc05df9c9c2df480937507210c8a1a419c9cbc840e54a0734c8a281bc5fa709a2312798c998b9cec0ea947c0e9fc128a51700a21be8841395a2552ffa4645dc67212117131db3b54989bbbd5569ac4cc7e43b4b6a012ed87757f46a8382ccf1c561868ca741e51a554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759ac091519aafa6a4367e19b376011adfd48d34521e47b10bf497714f6464388121f46a444ca791ab9b84741518ad082153b2944d61a9ab8689410a7424b653443a9089ab110dd83d91f07adad9ccb6bc05f4a34133248524f5347f2473ab0c18b2fb3da280a8364464cbcb1c62dc7505b6c2cd057de444ba218ba49eca1142281e971bbdf531cabe6b7cc6892ab7b304c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627bb09f7dc6609b18a3c92badfba6560574bfe70b4b3578f1778785754146aac9e2a890d368b7144e7b95e4516adbc2eccc82e81627935bc455d9397ff14828a8c0a84f5a876990d909c481cf0668f9787b9f87b7604b392443d4d16a0f201057d578cb7411532528c190523a06120dee1a291e55d0fe860821b9647d289158163b19748a1477fa31b3e7c048cb93287a3d7760caa0a0bc5c880d6723ae61f4fba744808aae2e3742016c81d371638b883447a1e3db611f241255bfaa48811397989382369ce7a59a3a17c559fa29ca4b7a6751526c1db169dcb7fe00a146f6033cb44207836c405a4aa1c1274c9206537c1b767c9948c533e836a2bc7373c10c7b149ec2cad5bb515186ed9865968801dfab0123e3ac729681754265e8c9a3e9745cb9a770b2aecb473631184832b086a7a2217ab2d553d54aa431567a52f25078c10ac6f206e1e198df76cc6f8828b337685fe84abc3151bc6817a98c5beb0db1b2a4a28a7580747b6330da24561c7ce37d8750952945ce7731983b62a1025f322b515e47442b05a01955b4ad8aa63856345151c8142718e7412ba20aad10624ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = pass +expected_ciphertext = 788ec4bb0436a01973f78f3dc40c682ecdb3aedf218663d3574e8bb16c15a8c80591f02dbc1ac351aedade075e310171390e991c4e53acadb3a88e2e0a1ef969197ccef2f7587c2710f48e60762bf8919f7047205a722c0313083d4fc2fde591b4326cc171c05f0050eb9fdbbaa2cf2d4c39d50dc20cb3ecd9062ccfa4b815da7c210371d8fbdd63c2d8054f4da1c8fd991e0ff0fcc55a3c84588ab7b4c4d43c6d00251d401783ccdb1735a0bad3d7d704698e3106da83148ca193a37d0661175a972d43076e085f14e0f59e43d808a99d405fd3d5058f679cebb6fc9a9046ca0d781cbbac8a21a80f4faa82c5f10c809958a6d5125f023b2eed70c337117ebf4a57e98e1e23aa33d302e07fb5a583457e3c02418079e12b9857a91814bf36c5cb5db7aa4ad1852f320868b273a3086fcc2356ac75c8c0f523985c6222c6916b4fb5bd5c550bc89011fed14ce52843a3d18c1c635bba2e22cd57fd70b51642621af48d4e9d83fcafd8530a614ec7c41412eaa2d8b96122194b134dec845b8aa2d0dc54637dffc528285ae31cd2d942510dbcd9079dac55fb5ceebccd795049585ace5b35ba34859f1fcc7335522d3fb3f85075cb7e9d83ed7acd82be9c899266a11ebce385f92bdacfa90214bbf84b20349230a6328f07b711c8d3a9b5ac946d046d3ec485cf57fd96911cc9a4708cf706aa8014f05a3adaa5cd0c6a7fefee494df5b7bde7d40d22470c078bce8f56ac7f1b2bc4bda00365c288a2d8eab84cc35f22efac50076484a57f9e2120ce7550d8c29db5338aa0b823f503dc34fd08e0b19c6bcd655acfb5b3724deaec23bcd7b89155982b0a62f88935e2bcdd47a2289f573b87a7f20c5f12043870344b028fd7197f67f6c403576dba74e482028440ea6f4ca78d81aac3ba453432170f21b2bd2026b837251e828a19a1ce1b4b301245d373336c89194730f5485e954bbc4f4540abf5521d9bedfe928714b6c8f3048ccec8a8b66e6311a46af387ce4da65df7120ba680bcdc6308cda175feb18d4d563a7b8a44d0712fcbd4beb1403c036cd7ccc0d2db0363cf885bf5e585a9ba2e +expected_shared_secret = 780b2d0ea585a6ea41dcf43197b9ca4648454e30a3057f0d47f6e79a2bbc365e + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = 57178f4476049b9483f4357ac027b219226fd5a9c2b9da1f45c9036d55411bb3c8f941b75a844baa7388ddb811abb4cb13d003aee4aeab466a592b77041bae4733b5f1cb6ce2765778b02455c5536a02a2dfa640248c6442398f48a5b8ac7b6e2630b2c1e872a3e752da777eb4607875e0c771f81ccd633961a5c9d5987dde31439dc131f536b083709f7f072dd75533f9c984f08c7fc952878f2b9720da006c3b60f5298ed3921205604fc6cb969aaa69c3f3a230b3865a84a555925c895c58fd19c3b98b7b2d2acb941a44b7e519c7d22aefcab1def18429713772285de2ca225b5489466322538bce1ed99e9dab3443e47a5ce5a9b284008865a4177666345237cb7b796b9582da027d7af4ad28f558e4d7426caa80c3a19400e286799caff5b4bfea5cc04631bf72684983ec67943bc955582575f399fa5c4bf125b65bfb3f2603458c2a1b23925193f6b322a30bf8a566c43032e722961a09386aa2459c249415cc675e27722fe83d53785e2d817391485c7a14c402879a84741b03a87818295dfce827926b34cf045385f26ea08923b7462c5fcb7348bc4a2c207c5d28ce8d71b77d998fda190c41db9ea45351e35c5a4ab51d42702856e8cb07839b89a22c851654ae0cabb3ca66fd0007942789b43061382079bf9b32d3c07d1d903089a78c542113cf086e7d1319fd37b282974db3c41b08e1899fca1ab7f6358ad204a0b937a9d91266da6ed5552baa2535c2ec0efaa9a606dbcc8ce013c1123aceb73809761b0b7523f8981416f819d0803453b58c2bd294ab55b3abd7873371831845a8f4449b798ca3d18a5a4f183b4b16c870f21d36f00d6552907c11c76c547b10c27913d9a39e6340b8d4775a919868689c19e6cc7659c5263529e3f840c0182db1698fb43663e4545b9695889924b5d27a41d014cf8150bb46a59ed6c3890e087b2cb043de68cc98288a1f2bbeebd4ad7bd0880f86cb7093407f393c6af5579adac1f5a35bf08c07a12810b8d28298383ae6a298398b022ad50be3408ca5d11adc6510d1e561eae2b62fe5968e2c826c99a7d9bcad1092a559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = pass +expected_ciphertext = b82636cef6a36673297a865d6378f217a3f674ec6ec49db5876a9152c39a09fbee8af20997b04b9613fda009ca49fd502361885f1042ce04ca01327401889f171b5ed396f5f9dd4e09c0ff03d8d4b4b53b1beb1ceb77f16548e21d7d0bb819578fdd9013d902f86ffcc95b3953e272582ea79ac71344417847d7f73389199118534c9965003c48e5a1068e620e50e204b71ef15c76d5b4d23a7accf642fbbb9a501b2e1e6322a4b9e7d0e59c4e866680745b92d930e4f881ec5aa56546951139c69fa11fb37bad4bd545461ace438ddca88b12df72b48430e116bc5c94de41dcb9d7e22902d1677cb02af69ac7e84d1486e4ef00fb9bb9fbc6a0eef3f538996fd0009e68cd74ae8ae461a222edfcbba2f57f3edc49ae381282eba30ae5ada18d44263064f2abdf6bbe9c4a455b48ea433b94a262609a2bf7c565120647c2b75a593a77bf558d0aa4a772a9b29691f4eb91485815463dd403950150727de1887e2db2ae1e842bef00865dccd68345e1b42dd6a8ade97a2e37c4552277efd99248231c2a5bfc9778cc86863614c2da8b742f4cca2870e354b7eb287090514890a9201b198b7a9f81c3cb90055fecea93b61e8d3fdbcd3029e750561405cd99630d4d7f609cb2c9c28d3caaf88536ad8e70c931bc0a98591c1430acfdd604564dcafe564d4323592d4678fb6abbd435b7bfbdbc6db413f5fe6fb5c8cc0ff7d05bbf79b940de596d493787ac99380fe94b3ec5c00cca2f9d75007d5500e3c6d158e4fdb0a8b5563547b2981cc4ddb001b58414df92df3970922f8c2498315615d67c9d7485654766cb86399a026752326ca77ed639db1dbbe86dc5ebb85b42b17f9073be257c92e60223e20cee2a329d1534502ac435452e70c8be71a90c0a154c4e61d610297b38a5820da37d4a5ebb54eedd0ff7ce4f02f98aa8acb58d2570f8f846b975edcc1c1f8f97a063f27c3384a1b581b57b28811bd2156f0b2a96080aa345e99af2d8815db7f3ad01fa1dc969cc60a358febf6d590bd3a9a83bea0c345ad8dd1e1c7b89b53efea31847e1b94afd65d261eaac1249d05c024509d561e2ef +expected_shared_secret = 7832b351d71984cb60e6e548e5b4edeedf9749f8b3bc96fd208b6bb557251de8 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 88b88ddb2517569570e3b33d93928c62ab5680c31939a085255311d039144ffa338bc7633516c32144ab0a85869d0809b7ac8d4e4b6e6df00cdf36600e4308f395c1a9821a47126623827c489ab73a68104caa3f75558e596811417c966fb38ea85b703fd13004db91e1eace232664c06a8e85a35346b56a83e89aeea01cf009a02223312397185d9c801aa5672d61a56ff22b34016b7b2b1c20b7b739ca5319206b1ac42fd991c2fd959f63471431035830e122dce7cbe1c416e5a69d5a766d7959b5817177e6b29b450a7ce080969a3603b738b23916265852c837104499c8658e8cab078bbbea91b4a9e2a5394aacd8f2bf0f94107509c69bcc9b7094512f6a4fe9411b3cd77200f63087e4b205f40d9d08a6d093208bc2311a299e7c722c55f50bf01a75bff5bcf95780a4496e00431e6978a6396c1232ac08f6db5a2ee3b5cba66c67b0c431b165fe83a62e0801a3e65f8ae30b0f2477892133bf9a1d03d4a68b96b726392908da8c554b32a5c59a839661e77c6fcbe9bfad441be0bb9767a2368d216d1e136ad5b334f775c296c1bd69930dec23a72dc30ea45636bcd242d5f38b91aa23fed98d7aea5d2d173d33c034311807c480981c141821a962c92951fdd77906817f63000b966311f584b31bbc4ac3469cca648beae1b4582697acf62a832a455f169e07860eaa4856240a1e48814cc7393a2c7552b29911915250ea677a7fe3561229421bdc31c56ab2cdf41fb16040b7f83e198a581fea0753ab8d388b677e693fea102fc5e99fefa215c178ac1a178e64c4227743a98f428b80f91bd1acccf8e4c80df483c5997438748155538edfe6445c7026f7cc1fbb8016260a0d86e19338d7255d84817929a026ac9c96bb215f125997e311f0807224d12322156bb4e320404bb6ed190bb4a1871ec9b274088b0d584a9d405f0ac08114391622f893d6cb8f9a11a9e19c803c4365656129514a49de618aca46b47317785be7493218a5d6f879f121bd1a852110c5145ef7585a0179fa1c1aca7c4b42109efef4886454807bf40a06064b88b740d0fcab975b5d3df74ac7bc20f4f8265f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = pass +expected_ciphertext = 0abfc41da2386424c0c4b6586a07f59f2c7d9ab3ec74d2de590a3ed71309afc09f7c559cd66b91a5ed6a433c631a7317c0fa6d86574266de0d2be9c7a3b5bb01899a1c7b2e5273c6087b3f0dc15cac701d839723bed0146321729e3e770359dd8366bf5c9ca0f31ed5870c44fcdb026a2088ea9ba4ae8746f339074ccbd32780b7b7c8ca777cd161b289822199aa83a6b3357a134821b283a34b714e065b298e8e636361ca3c151e799b733e7da84c1bee4344a23377c14d223ae859d98d8fa8289115c6f08929ecaed4c4433c5ab60fb7b52cabcffcb233cf37b9918f9f0e6286d2dcf266e8cf3342593de1231b2fe16cf189c00af0016191b8e9e1de850491816896c0b8845001088b3cebdacd5cb6a5b16fea748ccdd4dd39037828dcfd4d8b4e3727d452dd2c4f073fb4b61b780be277b79c439c5aee214305df980416f95c00697c1d5280dd142b8acf5c656c3bc4e2d3d180aef6fa133769e781553e32b6c36105caebcac9607818513d452c1850b862ab04452871d75e7e804aa14e555a5e18150109ff038ae73cdd10fab0eccc18670fe55318d10c514290b90e58125b6d07d9cccecc2f68b488637c2e26b795ead932972f7f7bbf2a377174beb7fa06c62b705b2622486eb7cb13e8b7f02b67db3a9748af941629106ffdfe38d89cf2e6db22bba2e6c77d3ebf639f6f2180e84f122de7d493789f7d55b46a8d75e0a33a7ea09552aaf53f82774e1fc4c9b058c84c8f344d5406c1a2ff8e31b730b88e6865deaff9279ebf60cda70e8a6a3d80077dc12bb6bc4c9ceae07b3f4c5abc3fcd67b3ce815d2e256731590d75821cacf4880506009ce73cbb407585a61d9e3bcf68c46ee96801b696732b76328657194baa4a043e14a7f2296d3d7530124fb2b3229443ccc019a33ec98c80c62f33156e04c2b9f52ffd092f6c8799fcdcd5e1c2c5d5a5fbae6fceff3f883469279296657233b8f173e15db42b0bfbfd1a843670a46467338c84c10456a9698f50618d02a1582f297158dbcbd20173fbd0d5d07b5e4b81712f3d7d1346cc5c42061bc9c1fdbd00746c662635c983f70c55df +expected_shared_secret = 468ee020867cb766cd0a9ce1bfe9e7dbb56ae66c131a4540f211837c1779e11f + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = 5900914fc65434ab614df28f12e7206f50784d52417763b09de06a433b1665ca88c8e303129901536b1c99d284f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb0108323f8224d5b6936a2a0ecfc0874d6139a9c300d2505a2d10d926b05cbe404e5e764a1b353bd5c34d86a1ee2230387857f97d0ca13382f2ffc8ffb23933803c52af449c29042c4ccc7d06a2c3272786be7cd4642588d90ba7599024428c055c2ad6232c02a83a27fa7150c1c503dc421410ac376056933d3305f76bdd399851e8952c110693b99ba35dc3a337b9bf6cbc370c6a69f593add08149d88606931b363a470b2e16b3f688ab1f1478b2b9255942b86718082a2663f7939e893a5dce006da504f38e98c4ccc36432a491ce18217932dee5070ea27779697274457bb6930b4cb34297eb39c01923cae32835aa7803722908e9b3c6b488a7f46676b1c4b4218720423a809116a41e59577c8c89afa582a8a8b2bda1009bc8b48e58d08a1b418f954460b8ebde004870bd0b7e082d3c7af5ddb4980c2acb9510a12352312991368295adc166bdf522ad76a59ffc974e4cb04ff8034896bc40a8ca508300e411732d8e729b78006d69482e1704ee70c4e8576c003964f6ce60bf7d5a2029c03a8b778b65556a70c617790c2541a9a8f37b23096401b984c99e7459dc38436d210e7186bc7f070ce1574a8c17298a82557612c19940cc1056b92b2b13a8a2f93e83d635190ac1c5e093891aa3cc6d9a98c5b30793fab0aec423b09ba6dbff15d5e8522f86aa877000ddf9752f17b082768929ad7ae1122c2da818db93c52a1d921c7ba26fb857d3ef1c11d925635f050b4a89a59262438a7a7eaf30fd5bacaf319ce957b42ba7a1de408346e393d231ccd545081ed338250661a65eb45d5c05c5ee73c99538a7bd4c65442a14759188037670746906b35484fd01b89526dbc94123975087402b558d3c611040c65a9a2cc4c38f4a871b1a764a170b85b5c12cca551e6e466c8889798fa0359149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a72241af2b01254922a708038e5c5658e2ba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = pass +expected_ciphertext = 19f22971bd65f0cebd5616ebeb36e3fd46e48411ce02feca526f85ac9f66bf1bef78727c27c5a9ebf272d4662263bab49ff27c1b80ca16166e35b3dc923bb3602002001bfe5d77e2150cd320c3ff1c266d2422b781446d626c252da9568ce0861ff8ba507ec0aea2a9eadb200312604e6627b2523f87d907c8e8d3a104da98b3b2d5761da9bbb0c31d8de239f0cf5c803c90f6eb487fd0751d5a364c51005873724a0e85c0938126378b256ce616a3ddc367bd4800d68a114dad7786a4b1357489e20f0510675f229a6136ec16b52646d9d29c91909c721ee41a58ca53a9e222f8d3807e24908d0b93b50732332506ce9d3bef5a0bc2eb640ec5073d6c0c090f83afdede0bb64421cdee403869c5c9a0a6a5332fc3e235d2ed0901a2b2e25b9c14e3beafda2fcacf6975d7696d8d77be066999092570e6571fa85615732e578a1dc194d286f6aa40d92172ccfdd27eedd88f7ca49cb4b47caf1b387ce71754e1aba4ec433c7e8a89b890dbefed95203d111a4d6670081726ba23bd83ae8a8f3293317b14676bf3b02332d7d702048d12654a44981fed2e8ff72582114e646fc17b4a25b078c7e5f1b43b377a2a01750281f1ab737488e2b7fe9591ee4e87331fd0f5075ee1e69f4e89f556e0d567bead916128bfb44013263e941bc0cd388db2003cdb07f686279da84cfe73bfc76e94097295f6e2560fa26529f196efac71774f7a7f061f4a36d28c6dbd7651d2bf1d088b40e5afb1a0f1fe18bb66a861592041d14b87cb2a07c63cfd8d2dad7ca3a6cb8a392f1fb964fe0ab7271c2c56aee3daadaa67410fd15e80a2c59c3b93dd911a849f8d1fc6dc541bc8fc9e5b469856850fcda9c5c8841f30b73af5c2d29f11302aa36f990935a66aea62a5f701eadb27f46c9960155b258324dd71b2e1c786768b56ad2c6501a3e5940b859972590f893abb0355cb629969b23d9cdb7e5d6233a523bf327d58bd4132ee81fa245cf3b87b65445f32e07e3fd0184e909289e694ff19ea46d49f2d939db5e01e5f32cc69d5f749415af8087133aca54d5a95ec148716a577db1d4984fe34375d9c4fd7 +expected_shared_secret = f04a17a3737285f2257a6374a0057776ea24bd731724851d12ac2e06e959fa26 + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = 3629b44f771560c15223c88cf70005d91365e13c0040a79377468104752a66c4aa268aaeca53817a449353d27c75387d2a14242331bb16ecb8e7810d76801bdd3122ef9c6407439e5de3cba26a91e6c314a9fc543ac7cb37fac5f4d24ada0067cf3c97bb195834b635c9b099992c3657d55573160e26874fcab1a8febba997e22843ab7a7adc3106897e2e9215351014b2dba6f68074770b5afcf4b5bc9abd72c97c03e703ef473ef58bc8ca8a6ff0fca028590e2a44a85013415b5c03f3a301ac06bf3d95691664c9d0c76d60015b0398aa44f778473c09746b50d770331c011aa51b1379530daf2ca17fc5bcaf06c59e792f0b117fa2755e1f371edbd17b584ab5b5a7c0c7ac0dd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b063160ec596b9fab9953124eeea8484ab8441a0b2a85b481858a2817e04c9e821a703bc9e55c28643a04e4b431acd7c9e54368e7e361b1f23041439f0d24760827971cd52328793e029b634e792c96fc437d396eb61a08422279e853bc2501bd6cdbccf16958bf4bc133438280e8b28f494a83f61f365646b22cb238eaa2554250aa27202743bfe6f4a26fb2234aa80bd7142caf7646a5874bbfb0900f7016ca225a7f016bc015c9401a87ff339def0bcc7e95197ff4be1728ce9fc4986b58bf933b2d2ac703ac0823ae701e3b5717f74583c5aa5156b744abe535a9dc1cd42873a44c3acc9080aee873fa975fe78547bad901c929c008bb6e9ba24af9d285e7c139a54c72ad525e92384d7d650fcc40686404a8c931410e3c92daf8ab090b5fe48c2435ec7a8f21295c2473eae893c6c46b5e35868a91c962d15b4565461f067ae0036cad3bcfb3b23182fca257e7516fa25e00056144768311144fbf526e43b0a9ef797eb07346d78165e71a8c426abf868a5c251caad2c4a038529211c6a3937098a48b7dfa9322d30723c460cf2eecb0c4b752cf310323caa7ef39779c7754574c6a06a2b9a0a45e35d3732d490541fa7ed66ac5d5b007fc1390b1591a0f19a4dd9c8fb0d91275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = pass +expected_ciphertext = eb778fc164763c5452bca98dc843c9b1455df5ba7de8e61394be3074ddba1bcc9c2884c1035c20eae1e7b346211defd9500f915f976a41e74e5848ea63295aa96cc9efc973f2c02a399ed0111938128986a449459d9789c5f3660dd530199cadefd7bfec96acffc2597f12ff6888ae840a17dde142ea6b2f0be4fea618ccff524b7367e1d630d04b3b5af2213d1d76511d0949ad48c99bea1a93407dc0177e5325643ab6c762fbfd6c3b8f0f357626411fc61d399df4c3e7c4a501c17732ce4c5c459a411fe61133a85b8db2f791bdee6a34b9a5abe59691635fc8848017ffbcef77fff7663fdf409e09b716c1a76c30fdc8f95f02e19a4794a21b626ff31aa458cb581e3b700c0d7797cf86774f7e97ed9291399b4847e5b8aeba723a333bc81921fd34df7349edd3bac264badfb0f4342237aaf7783d59fe60669a90a8a2e12b33a2fe7cdea19d41f5939313151889aca63c79fd9aefc857c4034a7f943c0eeab62455c086da18ecddb2504480d421f031a324556be7d93e7d052f5e349b0ff41eec2465e9b02203e0286c6181e12d0d13b3814903ff0d90d44d727533cd4fb696a7c3ddf7bd40d390a9435df5cc710dc5a94ee9f885fa421b1141362391558f6719e1b80af98901f0eb483c6e3c9bca40bf7a0adaf1db8fb96b41c1902729aa1330d4bb17358f3489a6671dbef7e3e60845d214568db16297f1d32cf6472e5667a82fde84a0bf899459e295f7e1653cc1117d22e67ec8d2580b8373170938f38108d5926449f2cf6228f2f1148e42a3d33f7b66c5fcf954274685c5d029b8d19efff7a6f2e3c3ca707252a2df047584c5049de06db510aa0f25f6c40da77c1a43b74e426e5fc685ebc6a2931d34befa497baeefc5f0c2a2c5ee08894db083ded15f78c47db0b3a0d91adc543f33199e827fd0f42ebedf2e9e14d5a43b6a4d04bb818d116b17665297c5fa9e08fde9beba81280bcc8ce8b760e766634a4cd680f0bb179c1fb9b607ab12335ef50ab4259a1a03aca82f6dda87bc14c31d54caa2b6cbce3baff3857e40d2e4af24563b81fedb9a829900519bb8f21b136ce454 +expected_shared_secret = fcfab6cb3daf0c64b4ce007499f097f6421e00905fd4daca7da7a29b9c8f6325 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = be37c2c02582a708d02feb86759511c62580d99a5121ca60d7002246176ee5534c1261b86e831297a95ed8aa7732b58f0975c4445bb00db116ef36cee951006ac2709551872a84ac9b6a2b97b7a4e15011335777687749e7ca1319683840c017a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59da62cad366cf25351525536dc58cb622ab259cb3a6707d0abb088ac242338424baed40c182b15a9144dcce03456281ed2b9006915297fdb96e9c34efb551369ca9cb0012ce2c9af9cf90f2f616468abbb89b7acb5d18ee17a022a98b1fe2c2e8b4b1a2d4b3054d19162a243d4f0837e697f548164caf878366b26772351d28a025b227bd1c135922a43fefb55e3c37231fb188a37a6053a8a0ca88502d82a56f716313a5861f001c28678b23c7f66828dbc492fce22cf1d300bb3c576a1c01f13b962dd1b1c2364900f4a0db48a14cd103a7a5b535da93df79371c832b3e188bd0845ca95044002fa0c4bc92932e95180772ddb860b80063799b614fae43901d7cff686c8a5d05cc5589df1c7841d0312ad4261c8d81ed48b4ac513a88df3071d047d3380465f4a3a4fa894f6757be0f99e124150852cb56a483cee8c4f3f052c7489956f167e529a9c3dfc8256f764c78a4b58596e6cd0ba1c2c0e5aba3dcf5c46a533647195a682092dbdf61fc497a25e8b9c8770bcbca6c154629596f41c19879626392be7715a36570985ba46db7670d257566844a228db612fe32386590322b4a864a6c537452a9de020d2727dd1a0b066b0cb9d7144033765db050c0c363e926107f06b94fa70813c3c8dca862b98a4197be6b9f230a4931b659608ba32936da1904713c043718a8ae08419d0e34b26c6675b45451b392ac717a0e8f5245f035f65cb842ea68c7b2425b2550f12732402d852f5b7305975b588427d3de1b48c9783b19c7b1e486a47414a76449c26f3ab37f275f80413ab159765797d5cc653f2b4542f4027c199752530b6f7b49477ac60791706a4f7610138c8b3614950c06072ac49b6a25b464374a4d2c31483b34f83792db87d868a167aa08f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = pass +expected_ciphertext = d8be709a35560530d75beb89fba0e856d8a76513ceef4b31f86f25a5b9486db6abc27703e7f6502b2dd79549034de3770a83b603f06fb08a818bf40b1da23d7b37ca011cd14df35a5efe7349787f39db24db56f0c2f38f0fc88c6af532a75c157126d8c3585dee3d9cf27d866216148fac12fa2297923ad63c80682e489e71f66e4969fd006b5e30300a7154553bf082a03e5a4ef6bf1d449ab53e75e953cd0acadd3bda97ea266307253917cede6649f2f6944ea8aac6dfc95d8dc4d7e2f4aec12db8845c10170ce01375ee6d6b094ed69461a68fc663355dbd2dedcb2f9bf74c458bff6529230b38644beffb017de9c2dd9b35a1f7ff9d053c1b00b00d7a29a143e7ab2fc4d78e0523d7f58046ea8977a4f91806a51e655c4f18e196ab30755aa5eee1d74bd5ba200cafe60c9f02a236f3ba016cda33e9f5a9361be028f3bec9bf3f560a009b26696533b119f64c0a58dfabee7a3ad2a0ea3595a338219686dd458f69528cc806c93170f5d8b503b29ac125f716c45422d114ffd25dbc180f3e358f8d83b5b7aa5ab6174e40d8235679aebeae5dae15b8852e0e0fdc2f10eb9834ce5a9675b738963120d319b23a550fde300be574cbaaf70a112f5706d5c6476c9ef3b98e3b4f547f3cc59be199126edadaeb831bb8cecaeeaf5d6a4013bf934adf5e2b07e9c5ca28c2ad6a7e2cf1207ef2a760e01a5d07b7bc0a532c0157e430127739a1ad0eaab81d804ac15fb884191537085846416cca4c4e8f1850e8adaa031402d336748224b873a66257408d4762f3228dae78f2a0a4650c5624116fa9aaef10b2be30df5f0d8f65ede7365675ad11b2ed7564dcfa20ef0588bf67988215ca9e604970ff8f1ab5eebc0cbd069620694f59e8e99eff4d788806384bb551486452e6e77bc3b8a0de74ad4be9f29ab7b1364508bba891fcc5b674f433e20ecd1557494ab23ab30392f418cff1f477e2553ea256a0728850dd23aa3665992a93d9bede891e0367c81dc646c2b47ffce6426aeaae2985f7c7768176ad6882e07b3922eb85ee9ef56f3b5b0529bc6836c1b6d54c52454bfa0000a7603a37 +expected_shared_secret = dbf4cd1f5cddf15322449ddfe147ae0605d0315ff9da6421069b47c3a67a65c4 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = 4611b241fabba8f6435b0b4889a9403e60524f820cd8d875926a2d68b33c3134c90e9230b43cc743921623eb484f7c65a741a8c30cbde4fc74a55305ef8588db967ce70b29049a8e5c821b484390a01761f4850bbc916af732afe9a211419944e6c7457207ccd12aac09c421bc0a4225f84727424b306549738b91eda3a818e994cbc763c176795c1286019183ca6b2e2d3c8ee925937c5a9ad62306694724e0b62b68369a204b0d0d1b74ad9ab5158356035045416a8eb48483f11ba52ecb1e77babb800bcd67245932a237f237410730114ba4241a295ace13ae201b776c29613fa04a82050bc4514e8c532a0848a75fac67177844bda15368f1756bd4804b28bb55bb2e6c610f5e0ab9df749857405dad47c8b16b8063533b1e1c57d4db06f8e6643216cc342b053e3861cb1c71f2f9b52518457056676064abcd0041f1011b1ad3cb297a96200a96d6a30d2960161008cc7d26c1c011a00f857739e223ebd536c61748a1a9c792dcc7351210c8dc6c3e122ad7d9407975a75c3286f0ac032e5a655637c5b6a043aa840905d9623a077489e8cafa1285ea271c25f12cceb3664e3975f0eb6b25a04f18e4537ebb3f27405398d34718304e2a7265268367312aba5c069b765361d907775b3041b391668da99968c198e116530143c781160b80fb5d4b473cb7f60bbad1b83a3c8a80d93ee4e61dd546c5e06a67dbb6c94fe82d7e1b963e744984b849864a22d535cba8408bdab3854be3694515af4a58a4c6c0204f110ade12c0811036f9171635c00af6a29652914ff0cc23e0e67e84072bb1b3a027591ba96959ef3373a3912e1d43ad63449ec2f47de225767b94417a0b918bd83abf4439ead3090ee872f6c0c5967564da6c4a3ad061db656f3b8caf970a690422b914c599fd606eb1a17a3a220a1d86b8ba7343e1048c1d4328aeb57214e077246b7421091821c6299a4b75fb1b9fa124c7f5b3b1f8938ce9dc7551d25898387f5a86bc9a1c49fc8a7c5902b8e2912405a592a8221816570362c43589aa9eef609b0207c9e1f3b564aa6be9a60aad4193001ac4f6756570d983c8982cb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = pass +expected_ciphertext = 40cfa27dd5ba61faf78b9609063100aefadb6b2463b41275c33e04ab0e0be914a35bf215aa967a443b5f8af56ca77d74ca47cda9fe03c0714b5788454390f9ad68d519e290782843d9306da1b20392937680ee9a44588cc627e9b44950fccd15f7e734cb9e2bd080c2da64f3df0ce8dc5ef8e293b6ffea9cca7880c396da0ab6c5b82964bc2e626f37a87437a7be4de0b6c34a06fd0760d107ce1a80f08710638d0ad39c838173cfff9e78244bfa1195d887db17815d74795ce3eab5223bb69790c7929199803374e06d68b8f7fcfde7889d4b9ae31e7f19e0b9c956ed8aebdd2109880f504a574aef28df60f5ec74f4a4b4d6b2db06b47c7ed34d2e7b900852e4b3afe9faa8ce60ec55d0449c943181930c27c4c36ffeaf2cf27fb82e1a25eee0a3c39c79a6cd508212771862f055cfb7a64db24e05252b7835a4c6b24dd6067a1c4a624e9466e98b47d584285837558180e4da269c914887d44525c8c25967a6482d4e54b16bb6b22cefb93dcd5cc01c3ee4ae711c47fee03b29a5876a2e434d998bdbccbc5449ea33be532ad0612913064192b44cfafdaf06ee277f8aa4c115eff6cb36ca026b3240e70355ad3b60ea29846f846d7240afa4af97b0f6c7bf6de0b2686875e868a434b28b75d95fcccb1f152c43c785135a7f3e8568e40c249e703ace9a809d005c4967cc6a46bbd305953d6957d94be02ecf83694afdf1b3e053b97d693641adb6e94a123bdf1cd3b1dbf5801aad3d79514702057e9f02fd8f36b988916798ff3b4e6a6bc8b196e067bc117f573563b08dbb94d5b88b0a7f8d69bb60741459bb59e34abc792d70ac51c6d6141340ffd927c703b207b8f66df8d68973e2cc6218cf5c793690f3df49fe6942d00191980ddad5cc9cd5f8c81abfdfb3ab7135f6bc8a86dca7d1a8d38a47631f8578801d8258430bab8c4b777035965814f04d62b43e54a93c064a7ab0c7a96697abd94a1e460d32582adf7479b20f83c6dffe9b45ad4587a13e8f5c315cd46200282951f87dd3447f664129b8a0f6922c5de259042b3d14ffb72e0aeaae45792f1a254cbd576bb6432f183c50 +expected_shared_secret = 3f4848a2de1cdd8a0403da22f609809a20c2cfc0ae619be0cac350897fead710 + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = 69a047a0a46968f3828fa4314fac3f911a71a10c866e7c035fe4cf00a92ba9471a735b808117722378a879702d59728d66f35d53c34bf5797c2ff9a2f55a0b2cc873d8063a8ce7914eec935f55174cbb542702b1e7736f50215f7a1277968c2d35c711653a8e4af95115c9ae33d0349d4a09504a10cd48c77b411cf079a497a5785e39830cc8a189b9bb56891249d976991b23a4a7a1aff34f3788b148166c40f381bc5704058339bde0c192d307515a6a8fc5747a1058e394cdb79c4142fa5ccf3780f254a10c671543b63bd7d192913480c77517512c0e49ec3fb8d03ffc793e7cc01125226fc4929c8c1c2aadf12b452746306c2a9c36392b23045888c2f4170b5eea07aed4515a819d7c5749b35380cefc976c87270a1237d6f4ac214548268a6da75928e0734eea7887aac0a2bf623e17852501556b03c662e4e9c42b914923b88d502714fe53373904b91598c8d7c6b022e5367a90173fa511005039d9ca5c3cb2bd5ed1404f7373654848ec436115339db37cb3549ba77237c243f25da96a4bb4a8b88e441693f6a80840b0ef7538f8fa9b71ca736d08bd3678c4ff8c480b115452c9c8fcd52529b1481e82236e5a311a204bb571a89b0a60738101b4617b033ba2df6c7967cb7b7f218aff886edaf2464b2a12bf244bab812731f46200ec6e94d24548650e1e1572e4a78157e2ca569c3b1472cd8fe98458c1a5ab8340f3a90e5a854ece60469698cf85d88739cc96adf7048cc584637a408acb79980a8dc119049135795245748683ac8f53b815e29ddcf5452a9504e0fa1de9840e4d489810c35a100687bac18e185bb53d499d266a8758c68782778b533bb9e5b16ea833309a0c8b3e640a2c417ad23b01e27220a7e9cf9bb91bd6eba10c08acff499295e0ac4f61b9e85ca75185af845c4f4330652ef024869ca7d3d33cc188a65cf17aa645b8d9b010f379198e31b7ae448082069b33ab6ff3a235ccac081814b6e063686707721f6006eabc91a4999915661427c85979b93ddfc14e24176e9c0359839a1c16f91afef473652480d4a2261abbb7fcb031de8993a57600220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = pass +expected_ciphertext = 76203306e49a9d478fa987d47cc93959ab932ce7d5ac52801a01a95e25d772d8cecd1f718c5878e90d9d4a4976a9e6dad07ef015104e81817839ec0ca9ceb6581d911fb08ac2f7a7fcbc200fe5a81d07e6ef7ecbc1aa057b1ba3790ce9694683b1b8b7baf0b0f254f34262ae33834920e510849fe7d931a9bf2f5d0a8fb8ac25e32ecd89d880506a2ce0d51293f849e8d452a8ed509b959ba571c758d93c8eb092367b5b5b5ea3afa27df10794aacece9932f79f1dbe77deef12f9bad1b38dfd479e8bb096731fbcfed2b2f47a06bc3d66807264a4a8c12428fe6da2879e08a5f885c3cf08c73fb130bcf98c0f4d0e1ab32c50c1ebef43a4d7ca59d2d400af238ce00b00f755eaf5e613b7f0f63f412177b8525551f12b32c44273dad7796171c0f962f4b23b03d5ad75782bceabaccee5dd37a3ec588b0583a59c761b83ea851cfdd3b43daa3fd8ecc04edecadd4635557df4acf2111118f5cd0979f106e615ed443b7a271be4be9971f3076abc49e4acc4cb36a4b203fdf49babf4b920b374053b023ade1ca376bac0923192257435e7c2c9712df08cc77ee199b0194af5ba14150fd22343488a02dfbc7cefb730199fe24e92191eb7c21ad5af0fb9cc54e041af6b64e5176829f9f4b67197eeb530054b8bd211b68eb79df559f2ecbf4bdfd675a5a8b2f4cd48b8aab8bc75fc16cf2e49ddb932ca9211981535078ab253cfbc514e11edbd5a32b85610ec462e15ec7f12db1cc32fdaf2b09ec96d1a8bc581d689f1a7b4fa02a4891a77d128cbe48609c40a2a88ae8305dd6cf091f2b50cba5762f946989951df8488a7647d79a59e27acbfeaedd07931caa3d05868371fe32378f025b987467c3e6f33290b33d57455248c5a57e1ecfb974c5b9e5fef8b0da09ecceaf9ff6e6c7ad04b8ac41efb59f6fbcba2bc0ac8acdb6f4972dc8308f2dd0b2a9626637bb4ab4593d8330b38464467fddc7cdc031bd17aad822241f5798c5640552b78055002f145075985ff5b42d72bff8c9addfdb55c18c03354ce7207d842e9f734db67a24876359f33338c5b68045c342b676770af0162d1292297 +expected_shared_secret = eed5b71764da1763a01184a1eb51dedb4eaa9dae7890b1c7dbc7e7132c30e737 + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = 8c9845bf1121a0172c991415a6456b7d708cf45a376e689e8c74b1dd589e2ba95d19192e47937b647c21bd9a518644113f44877aab626c40843b078e9a93be166c73772b290164c7ca1454f2b310c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae30b2267aa97bed49c5eac3a9b769c3a9aba51e882d0f5984cd7c39a2d1136fd627b3a204ca30a32efa02d51977eb2145e6c91717e0760f8949caf6b928a59f4d6b24221a291d008679b4b761178909c83d4c035de424c202117132010da0502b75e51705d07da603526fe46f50807af33593b0d59d4b28b31ac48ba7ba35793b194224a4f7577d4a7664e4311841b3908ba57292728a428a516d96c90511ac6b34673dc0127db223b7b27121a2aaee2822744b7f23969cf95b3960826c0ab4a100501bb601b6f2597339a408eea5360b9c6b752a03d648817654a35db7c5fde89357cb1e44a1b800d99e87872f95a17709f72a2a502d8f908cca15a22c14691e219b95b9c3fdcc3fe3c849efeb9cc0dc051f451fbad93ba360b2dc2370b400ce74058dff270757f20603176ef888cf2caabe2f8b337377368ba7aca7131bd6c8615e0017e2b21bd5b9b029085ac668803f66798ab060104ba4e930322b1452befb11c45112da8592fc0a74ccb8a75491120c1b0c1f0cb0a1abc7386948be2bac6bc92c60944ac8482e5a519b3ff36df7ea5e6f939b0c1b662342a08b6059658448b65b65c432b28fb66b92594d0d8938e5d3a0d6a99c7b3173a0796e02195e84b28da2b06fcd5672412420c916c77613b9c69039cf1c6594d90aad857dd319cc9bc9702fd452ad455d5329b14ab033a5910c08124338933f60993c3683433352cce6c484efb072f59b85a6b402d4652d910173caec2adeca708bdcad9d996b60a08f8c3131c571b5faf01a4b65565b18298ff8c6b3f68e77e768a1c0cc009315a4459b0b191c3584bbcd562861c20fc8e2c70944b7eec84c7e427f935b5731fb6e42d8b40b013951852413e94d5e01a04405319a7167b8e4cf638279331a6c3eda1dff9cac99e148bda370c2d00715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = pass +expected_ciphertext = 7b5be6d0d3b9759d1889322cdb13d7bcf5ce2516ffd803b9acb5435a563dfddb466e640266191317a893c8d2606cb4502e85b787459a018342d1876a554d468ace2bf0e6cbfffb25bfcc5c2855afbd2a799ae6a197b861ba70c521b59da2982ea8b90970ad2f53aa11355058ed95bb01d235e41228ea4e7432cb81b95d69ffb2f48fb868af1ab0dbf410e6774d4fad8d37ef62e83ab2ec1e69eeed8cf39e1392015786ab4c93f1b6e9ca8188ec5e295c0f83bd863bba439493623d05fb6a7afcf8c25ae4fb2027dd56aa0a62de157fecce232d986582f228f7a8f1effb88ff513d6b87f3911604cd4da1bba8beea7837c4c9146de3e21f2fcbaa018cbc372e72ddf0187269d8805a592d09e33ae558684c223d4ab4ef9d16dfb5f034ca235f977d20d035472a711b773ce9bc5cff177207ef81601cea5aa7085c505f92d0bada16db937621dd925659b6ea9f1c6d7e859b012a191d056f602bf263dc4824ff46fe658645dbe9cec11cce5c1e5632e13c3eb634f196e059e42dc19ec577fd5cae7a67a7d70a9bc4484aacfbb3935fbf401d8099935a8d746363dc397477e7831842cb4d22e301125424bc994ca6a62f0b3c6464e93f5a8e18cb71e923ccaee3b6fa1569bd8d046a5d4a5687dcc55fadb5f8023309a31f9825bebc117d6427d4f0e6f48d6f45fdb00228bc42f8b5066a430d38411817c0278d17be7e64cdfa7918580aa62c1ebb5860c36282d8c3e6c2b5b09f75de3ec92895f07944041bb139e8232aa0624639dcb882492c00d5323026e510c7c3058ae66738ca61398bc731a8605eb2ecc4768770af6c4b1f0ebe0f4d6cc8c18c9c961d1003ab867a42187003f2bef281d0c88ef70c4e1927f7b4ad837cb89de4485ff367d082c3a3957c76f8d99f3eb8d0bbade5a5e8ff5f7dfdcfb61dffec0eb24d607fa3a95a53419e9cdd205463365f16579a7451a2264e89bf11d531a34d20b5b0d478b9faeba16d399db32390ba2ffa27434ad6a0b1dccc7df88b6d3a805b45040e18528473ec6591eb0b8ba133b9b48b65233f11a91b43895fbf7c79f199715401f1fa69bfcdababd7 +expected_shared_secret = 4218fc9abb402e67ac946c7a7c6f9029108f67de469e1a9987d570f011b685c3 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = 5b5b3208a4c987ac02199a6c057376e2e11015c237bff18c63b730297052d7b9a6c7e15a3f02a9046c23e7d977111524afdb42fcf24526ca4f17ea597a26874e333f40e840fa3c9910c12ed9d86425421e7b585fec42326fd1618db61c9c7ca727e03fa772cc9cb241166cb40d3148b4889ffed89c8b0b772e807a157a6ad3b067c9f43c675c69890a71b996a323376777723cc6a4bd240c40deeb93b9a61bbc306177909e181636353a2f4b3b02f820a9f841a690b50a74f09eab73ac4b13689e267983241b3c9774c42701dabc8c3060381f60c591608431ea91f5743362eb86add70c93078349f4bf4b137d43e06c6258484c92c8457521d54915c96754673a4f981ca7c1a3c228a22ab44a4c1d207988d8a49925724c218efb34c1afd4b56dcc8815622d0e1c206991abb6e50a3e8299d9ea10a8b5c5611455378a5ac2b179c74501896102890171f95bb18d32ca7aa01eab0b272df4b77c6377e9397f8fdaaad0294b59c68607a073a2e021ab8b1ab1205cac74c4bbe21ba80b98225a33b0f18b45a8227c9b6e18f9c25f6b901137a7912ab148849228d2aa374a261073307127c6b09777fa9768c183067bc821f3d77e343874864288518ca21ebb2061828c0a60340e30ce80f60ef5523129f18bed579625e9419185019c8cce24162384cc6eeb7b5f9ef1725ab6034db7c7ef0580c9f0cd0a81c2236c46ec9a3225593e3b11939b9758556cadd3f9967de57f21db4c4af8541b4b813d67159afcc69dbb36d3dc470a829a5d771dd8468a21356d40c80f1c156008b3bff356962f84a48a041f4e4b29b7276111660851f7ced28ba0cbc24cc631942b92691e386bd81a28f66b8d4306bf89f36d0e015542479f3041cebeab2d8e95304795a31e6cae206b40189b4823359382393bae1057a62471c5a3a93cc874f96c294a6a4e00e6bbf8cc4cea280942d0c43729b2576076e73b3edef1be7317cadbb58db1a046b617800d5ca0e352b6d40a16303c596652a4a2209c5c72428de4b0d6b6821eaab1f6824cb35a04e067b5264359a9a6ce8b3a26259b613710a672d13d2690caaf62c5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = pass +expected_ciphertext = 19bfab9556d26ce097facb97e1c345495d755fa7df0892460974f99c2c103ba1049b9832918b874254f91d8fb7cfc11da9c7cd1d6bb50701371ea35019ff2a940912d019d2bb18821de100b1391d44abb1f72aeea18cd4f52e1401bdafc49adc65d73b02a5360b9ab00114035052d57ce16828c22bec6afb9331845210ee64a180a30bb684704d1c462e780aab4a55d6d746a68999e583de1a0b147ebac3bab7ba17faa6f58d355d041f0af83de1b4d9a244b83842a9003ab16a14360a97978d8940ec93abce842e8a1a3a172773b317fb8dc59472156665821090492e61a99d65f0da5e97a6a1a3156e2890e4fed146f4df81205974fa0196037b93f52bb1a3f85f02b92c11ddfbe479a30ed62691a82ca807eb35b0eeb8a0095211b44deebeaabe73e616db6bcabf52eb47546e1c6e20c2e14960f233378eb96e356cbb71154aa8d0e342877dcb00ff7f136a02aec66fddd1853a034f050c6155aa981ef2182e190a28dfc480d14b170189d105e565312578ef1a0024314bddf231af846affab5b289eb586db64f27ae9613d79f62c96927b57135d91c8f9c26c48cc81ffb6e39733c8285a2c93b6238fa1f9bedeb5b4368236d22a6e03bbeef92d2dde1d7df5352d892e360e2bf0f2e4c6dc86003c9f2bdbaf5a308a230d8e00e810297a46dbc6c52de5011b983b1adbb754cdbd33b5f1ce7e6b1e9d5424f7d393a53d8d90fd712632b160ea812a4558cdf0e6730932f021474b67586e60a80d97d8fadb44038916bcd5c1c54256cd7e3f61df56a7ba1f1d96c8ad9ef234819cbdfc66835139c57220026cc25fc83c6c31da656a0694dfc3a3a20895fade4d17c0da5033eab105b3a4b464aceb6b653d54ffeedb2b0a009a9e45dba33caae7fa6a4164ed135ed0163fa1179f48431690314d1c7dd342aad752184ac108611b096ec477a6c9333930aa521a3b81e2a0836f0f0dca27cdace35a6569abe904d14822255ab5124df8ca3e17856f12502740a3038cedfc286f81c5525b7830f1d153967f474d2199dfaa139681036d718e8a308ee8efae1dc3035284b80e9b015e1d3f73b9c178 +expected_shared_secret = 95a33968866dadc1fd8748768a99f6bb444e3d76a65ec5fee0c8a833978d4585 + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 45c83435071624067d69587335b97bf564929709c8825a004b028ae09c40980a07e8d4bd604527ee221e8bac67d34cbe762c26df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367d3153e460f497a209c495fca318862d6a57800865479a006012d82f7212b40284d310e01bcb11e122c1fd303e441807849a7ea47976a99abb7ccc4b674ad66f68eca195789b277d23c3d67bc418ca7c908b21e53984983ba0205e4689000ace97238b3699016fa95e7a3a59cec0be813638527562fa9bf10d715e7505f6e1c1433521a918a7df52760a0d8a9549569f10827c423cddff82aae01a90111395487b9c82b7b5a7978d789679e66b75087bfbff0569fc94e94f93531b721315926388431f2a36ae0f701bac254befb437c58641d4560c8738a98f30918945db0a6900ad2c2abfc3e0f4786a4555639d84dcdd031d8f0508d8c774d68298bcac4f42c6a7ff585af491fa7d7c3bbb41727699ebb315c437b210d42626ebc66c916af1f3515374314e4f40309ca7289c7bc51c301d8180edc792d4dd44c41b77bd47a972d8434a9f03bb3954236ec422be0c8e991a79af286b6a7c459a95ed44868ed8052f2db0f3741710228979507cff961564882b5ea19515ee00d657c7141e9b05f9a24136a2f915620b664404b5397cc7842748973d0716cc273b528d51383a63fc8a3c4a3b1a8bc965775d750add6996c929e29f41e42362a759baa76f5a3dc0552f1d83195960e45837901494a87f2a6dc3b5d8b73a9695c1229a0c9bddb0b2d99aa350c6cac657745c1308af354e10595f3682a34dc26d9d28e2e2c4634aca75e94384700c9c06b1bca348330ac1791fab1419099cf1288283bab03dca09ab3593cf3b12739cb44c0c04c6b93d1ea831df6bcb8807aa6aa8cbec64d749a9e47f851c47c6537e196f1fcc4d63b67d29a58e86b9a72a199cbb793c5084e5bab20bd02289b4aaa64e4c119488531e8a651a31750148e1742c5390bb9995c123f3056ad44c476468ded4b88a49130e35b4b00803dd24718674ca708e436d5c15ee1d95367c623512653c83b27b41cb308f8c2929b193b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = pass +expected_ciphertext = d9219659f8d5a0b8c4492b9023910a14eba618ee697528be1c1278effc029ef469b4beb1e081e4fdf32cac697d5da4a859830dc4d15e0e1f3298ef3ad9c4641be0ef901beec94242e894e62d3443c4975f219c83e2b69c087fea2e2309bdb3d64446875f065f18784ef9c2cc0d1989ad1b10a20fbbee5a992fa717a64ebd7fefbc94823f571f8185b4f8bb3886008aa295416877456edf06bace86c81cd01363e29727073a35662b950bbb829758d2ed5862dd8222ce466dd9d2c5139df83856e78b25f39734837938e03c71727080f5ad64b3471774d528f96dd354792607a5f3faee5a605c388ae6b7e26a76dc58926916cc58697634295c6b1f50f18c4492ea1e57519a9c46fd992156a70068c51531ac2a9bf2dba6be5f870b145826e468cfe30620b6c3d5eedd1a769bcae9f091b3b3decfd200d574d61773fa2a15346efee7c8aa7a48a68bdb79853e52cf8805fb19a01cd95490e7b6b53773dd45ea1f1ef2aba510992fb3e8f2fba356361d94fbb3ad30c5af6a26b236f4e07d95b619686334bac20b5838891716821f39dd454cb6409b1d124a11cae63cd67961f3e07f59dad6e161e7c6926311aae61f737c67f30efb7978ebd022d586245b8a2053d04e1a74266cf2c630399f47f239465201a37edca5acc7631f5750e0c7b34f0b27ab7f1d0d14caf48feb2274aeb676c49c10a6e3228fcc290b9cf3d38d2c7b1bd4b2573979a7805b8835fadc25455c5b878666d4e5f1ce4708b55e425d589191354fd665d1fae19fd1870f3067d5428b71ce2057cd29dfde70f51bdd12971ce9ad925efa35a737448d6a2dbd65571e35a6dce15327ef73e4e6e7f2410cfe0edf52fdd1a401d867e12d0ad058fe92b6e7d7f7e3e1131036604c3f64c85dd3fcc3d81d8a58fac4a7804fce5a0294771f86aed396a5f502f3a366ace4bbd48a31c7b19a9e120b127d9933c46cc7f9aecfe8385e775adf11f665b2b4678db5afa7d98ceb913000d9c3a2bb814f547cccb129caf9ced3202b0667a98fd18d33277b31272bb47683179fb15ddee809e90b23ca89a1015c273dadf6fa0d39f20373c763 +expected_shared_secret = c9423277519ab439fca3f5fab4c29c8123a55eaf37d94d70e27afffeec1b3b9b + +comment = Public key not reduced +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = 115ace0e64677cbb7dcfc93c16d3a305f67615a488d81eaa56698c5663ab7ac9ce66d547c0595f98a43f475dbbe08c364d97678a1e7d34f6ae51bcd63cb55c6cb3f5592f7dfe08d8d19c30df4e4424097f6baf36a1053b4a07a76be372a5c6b6002791ecedafdaf54e1daf37ff545ba68343e745c04bde639dbc590346b6b9569b56dbbfe63e51923d66e5c85527dc94692eda136a411497c227dcb8cabf5570b7a0e42aada77d9f242d8f5d496ebab7843f6483bf1cdc73b4d296fcfc655dd01394c99dae73d5c775b704e6d02a5a27ad74089e8587d4e16affb7178755adcf7fc9be9c4c4b3fce5ed53f2c74c9beda843ef41b38d2432875af8d8b9ffe365c7b8a53adff1317ba30cdf69f4793078fe07b57f6fef64547394d342dc8f22db3c2f4725b13d5fab88cc7a8efcb09a76a1cbf7f179f43cbda4c9bd590857f1e69708466c7f96d7391e7bc5268bfd3d7a1dffcb4edafa1c9b5975a4de3d5fc4202fcfb74e57ab76bbcf373fbbaf97cdd4e8a6f16392838ca9bf45de00f3777b7561833c10529df9403d3c59b531a0dbbc816361faa5b348dca3a893104ca7389be85671b3e5fe3790e9a626ec46d9b0b33c7b4e9af7b32b6859894f575d82ac5456b5490a7af8ff6e04646d589ecba7254f3705ef3116b6174bae79249a49195b356d7ffc674ef035e812eaa98571bd466a9d70e18e9dc37e3f479e37dfc6a3d7b92b298995ee780379e53ac366b06e7f49ddd9e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf5a8e59a789fcb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4a3f612ed9e5e4ca346a9bce5de6d417c6b2a8abecc435643f875bdc5a7e5b3481d09e9ea19e72febc46d4fc3fb0cb95927d4ee2dbb61844b2f43e4a06bb6c6d44d05e485ce667bdc8dd985879f8d2e9e3410dd519ea40145ea241adb041058bf0bdc2fe3f645b8afdf8f5cbfd873327c978d7b351a38d88438837024c52bacf95ce7e3646fb5d6c0ccfb57d734bcfb2bd9ef3c3ce3df6938e92455a862639feb8a64b95e63f3f707e037b38d8ac3a2fb45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 2d5fead4a7848cdc4b73987cf2f85e660c65e46834677fab09ea8b107bfed61f46271bc9d21672f6badb3aabf4c8f6472294ff2e24cb2a47aac689a5c583e8663bc98756c19926df3a39c2148c574c23836edd60d1ac8a06794edd5aa068bce9e42ccaaba5e051756350d3ed584a517fc9bb313f76215580fda99551f8f449d8675f29c45ab6354107cc955d9ee55aa5db3a813adb8b050d5200aba8f91b58a2d3b2b7e8fc656e363363d38099b7a0e981a85c75e0f4f2c67fc50617edf54bb7b715b9f4b4fda1e89695ad6475545d98ad9ea36374f2c8ba40a5cc17fbead308ae863af6e39bfffd1eb7abe3b58509b21649b86aab9e0d1abb6026d4c425f257a6691a964657cadd1f66e402545b782960e547a4dab7b71aa95c67e64caf568c3c3e44fb39d22dbdbf01b895e43f7d019b591daf82d33ed5da99b58bf4fbaf7e85e0b56cbd0c56ead56b5dd34e9cce859c9f7ed78c4ee144d960256a0b63cf4e1cc9e84a53a49bff70c3c89e83a0005d65019a8419c5e66469999a453418cb94295462d9256ccddb3fcf8365d00f35f1d5474997e4a9bd955328ffba093f448af20156e82a3acf063ae18c2fca49756505978f21db629799cad72ac5d18bfbfb5fa6ea15672537899b3e3a4f0b7df3f8639906bd0163735dec5924ad38fb7b585667de289f75c3093998338cb595c9a6c7e2c06c526166a725c9d98fbdfea10c5d7cbb86b93570402ffdeebd52343df968b5982504f02c17ba76ac661fa69a7998c5fc7cffb68a7820576b1feafc73daa29ddfedcdca47adbaeb3c5f58c1575fc937d712f3b8842978bf5da18da45159b9927226f891cb8a63cacfbd3dbae0a4364c8a6538eeb40f8f5c4b4ee489be33956690e494443ab44793d371768f701fac5486da4ffb0dfd058ba688fb88deb3c94e7445cfa89a79ca5f4ba9eabdef5cd6b74afbe9c63d0ae04028db242ab52c1a455c0664f7357c049bf7e05ca46b96d5e6843c66fbc2a7af9be135c39565a916acadbcffaa2666e25c6d3bc88c9d710399a84850850e69bf6ebd4ef3687787d75f0c7870c6e904af6e649ea88c1e4e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = 5a8fdc3e9df72657dd1c567b590869875d360dc8f700e7b9dd36d13b6a81853e6df3c59194fc96a19fea95c666ec6be3037fd0654fcef654f8794672b43bc1eecaf0df0ebc71ce5835a5f164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789df2e53b3f64411534cfbddadbf8bc0ab5ebdaf396e5746517c5547b42effe18e88da54932b9b458458c55f146feaa9620e7bb6cf2e648bfd47e10f7c3553813ab8e575ff6483e93a5ab3642bae332bc34f873f8e608db272aa8972de75ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31aabf7d4be7f630adf0eae6a3e54bc85da61a11e9a963defa529d6d7fff57b2cbd7235abe8c8de80947cecb5ce87f9af6854fe8b6336c68ab0b27da67dce4f5e5377c4cb59317d5775f5f2ca466dfecbeaa90db45236fa01966ff624ce7966eb3b5df58be53513edeb74acf5ed9d3923ea58e6677e03bd430e996000c637d10fba09dac9e717ac64b634688b558d598e4017cbd47ae60d7fedbb2b961638b08a488fe8e8e4aca37165a43ddd4b3908d842467946798f3e794c919143ff354d77ffaa50dcdfa6e079faddd353588b3e87f3ef3af4d30b2371efbecad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4bbef87235e201e4cb93c3151ef5277459c43a6aabe39af63eac249de9f22be7ab6afac14169b01563dc818552ceab71efcfc252fc3e507d4b84bcfb457707a0b3edd8dc0efb3f4d407d077cab9b416b3a987e3b89c6d66cf584ca652e6c4416bb44d3e7478ec2ece1a555456b9427168982866deaf4394bed93a86d48ec18fa7be576b76eddec428f28bf93c7037a49339352828af07f3729bfa739c0dd04b65d2b9e6d54bb5f5d724a0df95d6d9ea56d86dd72868cfcf07716b0dd4a02c45d4a9ef4503bf5ac86024857acae4ce2495ddef0632a6dca9756c5c8a459341c69e94ee54858b7c917592bc9ec23ac6f2d3f84b9d8e445e6aee5936fbfc0df6286bbbb6dd3eaa794445f7839f3ab51bf5ac48c978f14ed1298e7d27e658d9f468f77c4c69ead9dd95f653acf598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = e5dc61cc83fb0afff1ad8840d21ed40c54f8a798704ecee8c03747680ea79af3df9c7f65038abcd0933d120d492a7bffbaa7c0d7dff70467e520f35e322a4bef18dfcb4c83bd6fc432f75f6f0ffc2b27f2351343cbe4460b25b4bd8d6bac64f576ca42f30c7dde06d92199a4eedff37f5f71efcdf4e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4f0e68cccaf59bc99b9f4c54cc2a8c1489415d5fff70249235235f824d4c371ed79a3c80962e4ae03c86bb5ae488bdd710dca3dbac8a8add45de4768e573f9ec77d9aa2d8df6d3af6f8c7dde6f84f154e20e1449bfccc6cfbffbc49e7c90f659116f525814d54553a46b2f6093383f12b8529e3d6ca20ad4f347ede874e463a353513a593e7def91937c3197cd535768f78aa4ed1ec4f69f67b5fa47b1bf312ae97b77baec373eb7033cb17b5a592c99d91d1af062f8c729aafbd7f77832899b1a84ae67a3c11e87b17b0d50523b9a9bb87db025fcbee582b9e8f1938af771dd7d6f3ee3833ce45676fab38475a25f7fd33f87e468f2c6ddc19875cc4d6dc9ede4472265f013b6ad7ee4b860fcfff833778993f0030f6d7b54676b44667a6e654a0f912f4ee64038f4a64cc67665d18803ab2c06540133e66d78b87be6399779fefc099e4be7fd735bee9dd6344e0ef170773b06c5c1ff3b32417546ea64e6c20491801d4a3f6d3bf2fd9fefd3e84fa43f073dd423d3d26b4af374186df33344ceeeccdf3efec06f64119d7fda57a9539be65b49e1e016438c4b3f0e485b3cb3d01ffd3466a8749d1488e24685fc1cc89f1ef758473601b572acab4db6a93edaa6aadbca7925cf3115769db3b4e85aebcd09a9b045b3437dab3336b47a6ccf3370a53a5f3f7b6664d91f9a43555ecc26c4eeccdef9af1d9475793c3977b532c6a8cb43e7d337dbbc6bbfbc0aed2bbfc41908520194d00e3b62dbd3d05849f00b486d6b89b171a5d5f6fc4a3b7a41ce4a4677b64688284ec199e5f27e33f81c4f74ce3e1473f87375f554685debb7b987c66d01c9d49f7bfe44a6d022e7916c6ea55d1fc4f6ed99ca059e3f98704ad5ca1d2676497cf1782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = 707dc439f9cda8e34b9458f2c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b3a3f69fd3478d1836f80a9cf52bd3fe697846c44abe549aa17af5819e38c9dbef62bded3f54e7cdf8e38f94d50c0bba5ffc5d90d8ebcff1bbdcd67739bc6dd247fe5b8ecb5ca1dfdc04eb36ed335dc47781537614734f1d2043f06a8a8352fae70dd680b96dcfb589a3f5b85ebdb94b40fee24f374949563e8a35eef8c70507c47dcdbf41dfb53be08b12aaf83367b48895cd90c5f3e6bed637fb4894707812ea9b528f54396ddbea3bb3a687f88116ec28b9cf4aeee67633c30935a6c4f29a690af98bd1cdbc27f9c330953fdc5bd6d9f595d576e4d6cb45a5af13baf99512c3050afa3f7becd8d545150965bca39703efc502608bcd1f4fda21cb12a5dddba7a9a053a6cc27d66d9d98899d7c4aa3cab67bec13d68f51fbe96959a6a250ba45023b9e6a6a8d29fc0eb548e6aefdc69fdbac8ec682b366926e6fe889ef3e198add1e3eabf9ea02a5cb6fdf6a40255bc3355809fc8ab52aad0b0d451dce9a657e961b478782923fa72afe3964fe95bbcbb0fdcada2d5e5e3a83cf2485fb6af8f648981ddec7a8057d540d7ed54cf9aac9dd9d9067c703643c116f165e3745d3ccc4f5f49efc87b9f73afa09be915065dac1c4c695fff89589526188cebae9f65fdcad488e327e85665b5c59e8c379707f742897db55e5da47b994b2c6d3f4e949373f62de7f1584df1aa3373ab2f758fdcf2dbac46806c90061dec92aa9b06ddc789dcced4e4f7ae86ff4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a5ee94aff46422fb57fe5bfb2eee8a0616f7c4fe9b984aa7b738bff9336f8027ef8236a3e95372975650d7bf8398865f207aebc81c346ee76999b8b889c8355104f5961ddeb9f5aa3bce6b9257d91469815cf4533eab9be2daf83ba6fab013e892999b569ffeec65d3d83def447bf1ec43e9813a4f7c7db68a438c6147c182c48ded8c5fca18b2c84fffc3e4341eb46bb23d464a7868c5d3ce5b1bb479e69bbe0fdefc59380099ccfb0678a0bee83c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 497d419a0b91a8b97bea35eb03d5e63048eaa90fb51353721697c4bd2891f37698ad5e942d44c9320fd6ac15bf367d8807bee8dd3fb51665d70dbe96246b6a63ebdc57e7f7d9aa812c676880e3532a435e191935a6ebee1c2edcd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb7819dca1043ea8ebcaa3b73c768892832c357b0cc48e875f859e49ffe63a22ae69799bd0cfac58eb666c9ab68729dcb60cac6dee1497a6453398acda69be51f8865db504f2eae77292155f12944322e579d806ed20ea53b34cc7553b6a97db6c3df847b8aab6b993c4b00fc44d3cdff555ba6c78e32cc6b9c4766acd13dc33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e1066e965e45551398a974fe69d6a53da23e4a9b4533f5cf23fcc46ab0730a8b463c537c2d5ab8c9956c542e6e19f76b82a0ae4ffe637e19f97b2e6565287d7918ec575bd5d50bcfbc8e9538e1ed5f828b539d47f3aaaf93b4b9b835bfcab84e674b8c61f28a778b736b699bb98a7d5890951c307478975d8431d68dcdcdf9916e1ebe8d0ca4fbe5c886a5acdd8e6fcc86956aba6863bd9558417a37579c7e39efb5bc48bead598464f287a3d8c56d748c6ae794f3194ffc3aca9c6cd5fb5f76c5f84dd2d89d8e02ae73b75a35b8a70cd645e66e8a6d39d91a02f7ef5e5bea38e6b328f9cd39eb1376fdfb2af825ffdedcbba7aeabedc61af97d39c7b40f53d02e6d2627879fe6b4c00ed426a1bd65429acab34be641c356cef6a7d6de2b9643ff00d7577f79dc99459153ce3e656e8b9f9b3be0b551dd33df8cb7d890c48ea83b68d4fa327caf5fafb5ed65c31f4e6b63933daa989b1ae8afc5f03f34b33883955890e5c7aa79e463e58977d3e445fba5c418d47d227aeee6bc90697545ded885c3abea2ec9668359e5938fc23ad920ec76a282c545b8d896f5a4706ddfadedbb0f8dcba46f36c112b578e7b4c236899d91f59706c3d9abdadc3ec44e68e71a6ffec052767b779f8008541336f4ff438b03cca424746f2a6ebe89bf3fc7f9d6a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = e3aed0ec15605818b877d7399d4c70c4e3b362b3f68fbb7e41d494048740eb3ffbc38b5ebd3cc8d049a2551a731e03e784247f30fca3f04cda7e7f45d0f8ec25359f245b952314dfd3df4ac3a4ea213b561b974ce55e56d268a0d6c5b556ef51e18b31b7753c2826bf6654453c8ea11478836d08c6a803ae49ed892f9f79611e8d466f32025c3f516a99e58e862786dc88f3b8813b57e9ebcb37fa3920aec7c8bbbc358b40dc9d8b526a85ac86a03848820879314ca86a2d3f6f5eb69e7ff6c5a0c3779d3df1468ebb5f4973fbf54353fc448b1bff00fd74703d34747e7ff839f18c2fbb23eaa132f3ecce576efa0a53015c3788d8fee55a69051a62b6293aaa9a4398e6ed25dc679964c33d7df8448b92acb7ac1115c50dd3b0658e8cb12f4209193797ea3df48b6ffde8f28d148514bbdc12be840b3843a757f87633eb3be9e822e8469b5d95acf5b2bb6be38425b2d61cee0189519529e7630b8da247faa239bc88d5a087bdb6aee5d618bbf5000abadc6684266939d4468ef5c651ff69b11c9f835527dfba97ea59eca1f707368a5e6d17ac6299df520e93f8f3cbaf8de33969bbd89d7ad46bb979c3365b2edf704c359c04797384c5c7f28c342227b045f4de88d4bb5c89f381e639c87ae2885596145bea6cfad1ef9794122466e3bb779e3bdcd09d48f50557d536621d38db025472358dde442b6279dfb0cfff40946c54239fc904ba31a6a38cba3f887408f5fdad504238bc090bbb78f6db2eec76ca0dbb612df40b839d433c49688337162fea884b362fd8c8ea09db241b66d86ffb6908c4399dcea4ec80ca33fbe3ac573bbcf42829f087b43cd15891585339a71f34762d9af7ce32be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca76f742a5df431c93a49e618c2a410834c2231a92c3e9ec4728d3f22543ce63da17bc924fd3f6aee4537a5b43fb655e00e46185f8d9996b87e27c6361fa7b53da5ab393cb57beb9686e55f2e5709256659074fbb19d571c6a92f60c55b339618389415c259705fc858ac7eaa61df1c129e359576c849da70f7d3f32fcf641a6d2cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = c51bc84c04b516a5647a8eeaae6b9efecd4afb35ea0d2feb24aad3d0df7d8c435892c88c0dc5f91de3999db794ef43a14ef966c98cd2764bbcc6786500cda60316fe55bd444f5f835c67b5bc5f4f52e670554cf4cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e43fd7c9af55de7fa3de5ab401e540359575699f33e1693f477b8c8f0f762abeb2816bf7b9b557f91f3950c3d7a9e9ee1edff78a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c96fa7483df17bff3bb97af8e8f331b84f11737f3473ca0f4ef4ba744b2bd66e900c45df2f3bd53daf5e04d5a93ca4ad32f989a68e36ca4d3ab64f8b908ca82cad436fad46f548f9d0daefcbf7f498ae5ac1d8f3aff829cd38d9ecdec05f7e7df09d0a97beb24c8a6e5e5354787429e559d61c853c1354f60dc4ae63fe41beb5f3bdf7388363a3a2f75ea8b7d08b68ac583713c7e4b9cc79bd9dbf65e9e66634f429ad6ffa6a9ec260e63887f552ea54652b4496bf790efb876288bbd6cd4500a344f10fe7264f73d0a2ae0e4d63b06884f8a5c3562bc8617ba4f33dae4e3c4dfd91e7bf547b5921ed7f5863e7ab3c3ebd9852208ea23dbb55eb43af42aeaf1047b68b940bbba364ff69dc57c60c6cb88d4dc43d85cd0b0437dfbe9e3ed15a3bb84c542137ad02fd5f58f6fe82bbbb80ebc01af3115ba718ba5c80cb3d1aaa7dd304ada9e5b64aecd4aa8c8c12b39513989a8a27a578309661dd3ea5de69bfccee3080afbc4e7d1be266cfe14a03ea6efcc6e32e7678d60dd6fd1a74262837b8c8ff8bd297a9685a9902e7976c5f7b1ecd662e6f38c8c4f05baf9b3dce82b78a7f39e72bb2a8b50fb861624cee2ce9f4f0739ccbe57d806d190fc847775f09aa4b9b89fe2805ddef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec49cfee05996e0535dbab9309d365687a4b61d8a7466a6e82d07e36b5b8c60bf7cbb0e6975d4648c0d6f2bacf345ab61fa68c7ce89d1cc09538fb6349a49e4049dfa273e6bf15ccaa90686142ccf5f7d9cd4b6380088a18d4f82643da454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 2fe9f51f7b8fb16c6878cbf0839f60c588bc80195ff8db59ea44920acf476ead61db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa7cd2b3e531ac65da25db8783c995e37e6b143c8a1309572fe47049a65742c632755a7d26e5a33453d9e1ce4ee313b0a9efe4811b64d745e258f8deda8fd863368dcc1851a358668dab3f0cc77f074aae24e7ee0c7ecab858b29e7ad61a0e77f9dc39051b460d338363a9b7f6c691ab17865c4735c04fa72a655155c5e06c165086bec504d6b75187a44fde98c98aa26bae5327c5b35f6b3852a58fa86e3337094129367e076da630cf8e613c762d857f9afd57b5ffd8e49e81c63a8a927f3352b8c4a5ed4c0d0fb78ad8fe13c3542634484cfc8ce738b31b3d62d2579f8394cd0957e57443bc9784d89699d94a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba81abdacec9f3929ee2e22b5591cad32b3add4f93d1f2567b266473f40ee11a7c9ab95c94ddef38db28e66dbdc8f568e67df937378af096eb99408a32e3759a88a4cf04cb57924aeb9af7e4038ea3cfd6763be9fe0fc9ea24e87f1c56471eb334536d53db394d39f956a8e45c6ff39cd583d3c0ac920af3a4813f9dc19c43df67c05d889fb778a0218f98938ac423534b026ad4b24eb1ec8de7cadd53b7463ee97dbb17899abb19c99193b671af3673bdce15f97f7119fcc22ea0fc75a4ad39fff4a4c9c78bc24c764d7d4b9e133dbb47fdfee7a66358ff5716c386ba1e93fc5a85cf63a74817f479ff3b0fd432944a5cc25a7dad2f97b1234744b9e8e7565636c674e4aa4d2c957c7aa55da79f324935a4c3749a08956028675ef5b9ba3ef5e11dd73f1dbcf82523cb4a89bfb7973a50e3d085f7d818ea596c7c4ae43fadffd3d0a5d691836690229bffc77ddc5a3a363e357c66a53a0fec851cd94b2abd66305365b6a78fcbe57dbc4dc8d02ccb5f64ed12df4ce8eba5831d4bb4da4b9e099e822933b6b74080f8b743b59d95fd94cde7c4552f317e358adc6877613b7ec0a6ce8c8dfa1b3fb285f475af3769d9bee48b63f4c74f9ceacc5980c9d2ef043f00e4f485bedad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 4f3dd8000d3e22d76ae0046db986b85bde66052648993355c236fdc8e3477e83bc9a843476eaf4444b3936ebe82d6d8bd044a76ff88cb4cfb4b4f44f35a3fd0bb3cd8b834ad7ef3eb9d9825d4378cd4da94e0d7fc5d97392eacb9dc770bc2569ee1b92ccfdaa2abcbe1e9aee10bbe245ee4dee474ef3e4531e43dead07eeb2a36b33ee52a88b5d90c8f12b45b69c483cf36ead54564a760bdc2b1cf589037a294772ef9cdb00666c2dde8cf54bb3b9c9e0094a69fbceddf2a6f0a99dbb08ee6cd8b55cbc4dc075edaa266f53f7159c07aab0a26a9104b73b2a5fe43ea6f2e08cd55f687a5e2cfbc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db1acffb25eae1e4d82113d460336d3d97e6726539dcf0ec940a78423b376621f8f88e74ce054e1af3d7048d8fde7afaf26996b2809ef33dfe722554e2d5ec422cbfff5e3a35a0468b3bad2dca384b0ca793d1b524b8cf4acaa889175a172bf522a07969249596ada9e77de7395c4964884dfc11f7beefcdbcad5c9895fc3325ee1d149a0231e68af2ccc65c6961ce3690d64ce1554a137b373319c56dcc5e52a29d59f1ef8ca97fca70ed1d55d9f196c7ad4fc65ee6accac6b80a9e8315c86e9870b3623d38d2778c788d6fd291a32b1fad78bc5a4e6efbcd34c97e5a6301574c7854a8fefe6fab6657e4eb9371e09b8df3bea4547ded56fe4cee3b86a24e7c244d81047b5c95dd9bc1d351a3fc3a3078b7cfae37beffb665cac0ccdc6a13f778ac437f139970c377b4d75eb0e284d4814d402685dc3ab6d5e2d6aab39c361789818ca7b3e4c8cfe2c471aed54a85b383ebbe60139c377896fe12e7d46b98f3d0ac2a44cbdde0d3344974f30f3b9733579c50665937fc1755c9346cb31153cbe1343f8283637ba5b4d3b9d6a3ad75d519786c64e43101b77b7053977cbca1175a0ac076dfa4cd596bd473495738da76ba0d4a2333452d88c82750c94e745852b2ee8bf8ad3b7feb448298e8a3bf46b166e1886ddd5c468a4187b80fab8cddd78837b8223769b2489420f456141efb91139deb4e780deed3e1a699b38b95edcbecd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = 478771e3fe5c94a6fe630d501bc9d320cb6a0eabc78fa97f2d69c5a8bddb81db6b2a77a2b99cb1b0598af4bc5da786f3fb6afd3d27d9afe65521c5324df95e40d6c20189a4d09de62737801c48c1d5bf53a784edae446162d6a245757497aed5e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9d6e5b644ee756d79efa6957766a5de25b89af24da096ca145988e668fbdf1b590c8689a366b9b4e2877c2b5c5a343f0d3d532e3958465c958706d4f509dd952eb5f96d73b6287bcebefef7b88630897f8ff26dd1ab7b3ca594ecef6da8b84e903e489306e54d6356bc308bacb27d6787f580af8a1d05e57ccdb86aa74fb7da9a6a583508d18773c3d7b2b0ca3a1cc89ff63ee0efe3949cf88fa4aa6d41dec592879649c72461fd2e39c5f847d51db23e4be5af5a13a6a00537c20ab5acdc6be1566fb1037d56bbcb63d6c8227683480b6bdb83c5a7403ec0d1ab84e1f9d4a883e2cf48ac96ac9aee856a43ea5b9ad504a56edaffd78d3e9e6fa6fa9f9b8ffe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a48de982fcccc93353b0387df077eabe2e40dc9555b8d982529f4fb77570aad8737c1f533ea4bee83f6761e86986273bbbd447e58ee9b3eca4b7f565de7cdef8494049ad8967dce7cb4f31c433864cc961f6193774494aac56df23d978f4267aae9fb66678b560dc50c5e797bfe4d7b5b89b83bae023b3d46d098d939b3974c6626fdb5d4df84b7a3a6d647f7ae028560fd79995e6c310cc8b6f33a3f54eaba1ba3f457e4975b3c3c299aeea9a714058ac75fe334e9cd11a748485289af49542df8cfab793da405e9c427eff3066b24d5943239e3e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcca9f4dfbb3b0536f2a15bcf0dc7911d148028c8a8cb5743351ede222abf06fba5cf6df2da143e5985c7cf277e5dc7f7f7bd7f2e8d34e033a25b1beaaade80f4e4d3b717ff87c694a5a6fbe499387846e3fcf3de8b0cf1490dbcb45c5faba48968c95199297626eac6f5ded99d9d3a24ab54251c353016418ca774c62f94a10ec2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = 707a4731f46a6d2c59e28cd13d7834f126719d4dfc7af3609cdd457173850bac49581557700cc0ddfd34aff6b36c2a53a5e8580eced1e007e9898cc8d02e6fbceebc78c898423dc2ebafed883ff4572ac3e0ddad0cb3fa1075c9c2a97c41635ac9dc7aa3ede4dc56d115c93fc427c1567f6830b9cadcd8523c97f2c3e4639d83c58a8d54fc68ca8588c55d89640e5cba32fc3f5dbf83f209d42f2c8dcf3847ee1b67ca698292a99349de94df068db0d46d992aa59a83c08b34d17dbed48f7753303fd3a09fbea7139f1dbba915ceddd27abcd7aefa8fdab2ac5c68646ab880554b561f459efac549a5d270f8f5e39670f16f88a97a5e36b3ee61b5f57a0534e07ce418593b7e844f648ebf1ff5916be88c697c6a6c2cdb42daedaba630010678501f5e7fd8da38fd8a688977156ead90938894a54915efcf759c60b3dca1b86abecbde6efed660e55ffcae23ef828be4b2bc4a766fd73bbd69365bcec3d3a41c2f323fb8f7ae5d793c3e86c7ada7e4cdd7c99f868f18bd631d5e2215e7c0db3057f77a3cef9f8f2f76a4a4e6737c99912e6c2eea6fffa7b4bdc6603ab4d0cb5675aa5a78458a498056511ae4fb865daecdc4940bbec1739c33fd07bafcbf87ae595fcaca6ea4bc3fa708ad3ff8abb51f6d6aa9a4d967fb74cc5567b55412f9d1ca0c4d5eeb4c9693e3162f917f0a7eaf56b20e1e77b448878b657700ad885ddde34a249971eece1ca7791a7fe5d114e17c3c884d9e96f346f7d78efa40cf34fe27edb44fa24577a55c5c68e4af350f4ec14d8deb1c0ea39d2850b79f74b2ca3a20fafcb454f94ea73042939a5a1a9a905856877bdb0e3492b6b3f8b40a949f1865f54558ab6f63799d93dfafae2e8631e2ca5cd276f583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89e5e669947f1ab44f9aba94bb239265adc6ccaa64c1efb3ff7fe2924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c457ea36aecaf3868b4b9fd34a766d20864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d8003ecd314cfc864e6b3bfa19747e4ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 903eaa78b9d43268c7e26bdc43469ed0a535bb9a8d4ecc65c3cbb32cff361838a8359bfedc2aeea2fb66caf5d70b4dd80a84a9008fb3b12dab1df4548f6edf04be3cecd4aa32f380172ca85cc8962acb7a526e9632b53bf828a7ccfceb65d7ffa008e5cd3ce0179db769e452e34993b0a33979ce9da62bd062ff46620fdfa6a566b1d7aeacda859f5fcbf32aacbd1b7e1e66b139dfcc614af6996b6ec8d89c63a34a44abcb7087f08324dfd75e9ef01d7f91983f2e4557a8ffec6217967413eb9e8cfedd845189defb4745b7a693d8e2ee9a86968a4dbdd1278e32e493a79595989e7b55aaffba83ac40c89cc752a97d6d6b6983fed33298445384c5fd04ccc06692cffdd07a8481316bc02b7f4491e469ed8aff1c8d9715da8cd23da2cf5cf00b168ff43e81430cbb5bfe52c16ede46b9aa8d93d60648c2ecfb74840c51110d4c25e9e64e1a3ddaee812179d1b1169a9ae3a761deab96c7bfe405c658afcc1f6fc65d99aef59d892e96bd6bcd8d952e975a07dc16d3a12f89852823df30ba4b9c5e3bf43bff5ced8264a985b2ca61999afa3013de3be5e200ccb3d0f66d08a677f6236bba6ee50e29531fcf78f4ede3c0ddafa82cd09d0c78537c62557b7c5ca3d615ee4d970da9e8ac38f44761460666d58de78249d552693b83736e3e44dd577ece0d6ef8cca9ea984630f1f3349fe8de7756abed753226b456c2968efde96de0b9f4b926ab75bccec5e69b24b4faa35ce10d75ab27495c5d4cab89beafd4aaffe6ddfacf3578fa4664935ae049fa7d89f666e2dc77165498f06ec575c4e56ff7c2d7aba43597d999e6fae36a6cebc66d04ac54bf4cae15cdae89aabe90f3c397ebcfe69aae0618475e65e2d5534f8507e2a20a9699d6f0181acd126fb06ea9d096f7799f836772ad5e56c99d350f599f7e3fd0b44be0ebe30ad3d79c583bc0daf66a548da0895c1a3c3d1c28385537465df75b066ed6a215309309820813b3b8f7895d5361116ebf796b47cf2de9e3bad9a013764ea8ae0573ca638e8acd346fe41ef319db7d352cd73d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 6693535cba8a71df41107fcf1b69ca2a5e579ead3b23e997146bb3519c521f03f6fafea1c1e5d6d05fd79f694f044dabda58d6719b8df468a53b9fb5bb36f9ad0b547aaed3c1ce7936565e30e9f72f44a658fe90cc9f887d56e2a517a35e87b24fe3e4dbf3fd99c7758e5458048e40f1ca660eb8c1e81382305f865f6671cad74ff478514f87afbd4e87c1defa4f388a646e3d593cedce237d14bdeee6db54013590deaed78b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5badd44a3a5d378cfce8b1edc9f59ab7e27aadc49baf115f1d8ceed3ee7d7ca2b377a1fc131484c5e94cacaf88595d7e159acd81808681c76d9227648044de1fed686cabfe21f7f43474f6108a5c5153d67182f4f5938d63549b268d87dde9ea79ccbc42f884f3add97e6246266173a79c6889623561a9f8fab9d7d942f6db15e57319456dd06564f364e8ab68aa1fca43bd4e9435e60a6a6dffffe52ffb85f24358d2bf3c375888fe807f55225a27be7e0efcafff749d1c2fd80f6064c44ec982716b0fc7a88ab4e532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe9319e5d785efc8ced94d4757fb0baf1aba40d0d443f60cae0d6be9bc4c705567a6035dfd18c546ad9b8cac337ccf5adc1a23467e75ca5519dab4435446b9737a0fa73c69cc87dd50a9deefa938f57c5774d3f745480e6995633f7c564dd4c962f9865fe78347d9dda5eb449f6a046bfe7df8fc1e85ffc86e732f39cd3bb19fdce17c3465900db10914989dcf4545f6e5fb8f4743ae814d7642deefee2a99e94d23f70835799e23ce98ff5ca7bb82bf0963599e6d73c73259853c37e8e4425b37e9c67f573db408785290934a70448132c653afec782a478921ad85c478f3ba6dad795674b947d53543b80b98c530af996148da847dd34674852d25ea8c1393fd0c97a0b94695b8adc75fad1d3c69764387e76be039afefd63e71fd43657fba4c91a4e1172dd4b4ebfe079541b02ede166ccdf2b77a8719d28b18a96f0e5f13fa6142c63e71f73237eff7e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = 3893e35665ac3d7bde721fd468acf616487bf61f95c61ed347b4663c9e4bf00f791a147c20574f1dbc7065e7b2aa4df36a99304b75f9e95b9eadea48fa5490fcb8c59e6b5fbfe5522ccd57e3f9aab8e7aca78dcd6213e0a26bb430aaff2c4c56237ee4f8ab63df7eb74a8ee97d6a523099e0188b603ac8523493a752aecdfd54e25abd3f5d24df862cad7a794307aa31cfc4624f2a74066ff66c3ff40e73e639cfc1759fadeeee4997d95e49add0221dce40fa83f416a2ed06806cfcc49bc9a159a5e2db09362bbde650f7cf5639dd2e8542491fcbc009afd66fdda63b30de8e4e25cbef974b7f3f77c38c638e1943beecaf34737ad2944fa13aac8d21ead74704ec227e59869bbda51885eaabda99abac1b84dec04dcadc78a6fbe93077ffe4041f64275c3d56486efeddde9f1ab1d3bc98963c908bde3268d9b068dcfad5c36f69bee281da7b2d3f5509383e72dd98c23aede3d3d6601d82087338b3bbd21b0a3fb2b5cbd2bf9f7b3b7d897c8c874b9d71d34dd60bb686b99c8285d5287d4a53c737b157a6c99ae48bdd727d13cf771bd38eaaf75e568b19dcfbad46dc958c54900c59b4bb69b844e362ac7fb589ca96f563de54a46d4cd2c47578845ec5ffccbda1998a87d7a2741ed95ac8577cb84c0a5af44cd8c544f4bc7b68cf02a99d9a09dcbc4fa1ce63740ea784e665882c6aa1ae25e501e560ebf9e16fa9cdfd749153b7310e1583feebc2856384934fd0a91eb2c007ed23076de669da89b6b61153e6ea08dd9058dc1fcec131a9d637765fb18cfb0dbeca1c03a3461bc2c8534b35493b3dd3c8d7b6816e9ef7d29fa6f7d79e815f83e3e882e92fdaae4febb7ae97fd6dcf443ace9855e0bc59c8ba93f699c8b145bacbc19d965fdd878507fe24f4b9bb7dc41ea79c9169eb2295cc5903b29e04bcf3566c9b8cd01aead57456d5f1845f3e13bfa02f744659b2914bf48abd73b70de865c756aa494a41e44b59a7e9ef5968854cd8974f5085d75cbaf73abf3d4025ca6006858ee8cec9d00d67b576c16875ee3fdc9b9d978cb1d6f354094fadada4adc4f6c167e66f18d34ce4d25a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = e785fafb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afbb8e681b834d55864f9ef40a79d67ba1384f92795772eda0809b34d8eaa350cae66c535d6ff4315fcb30b3469e59c45f459e5dabde0e844d71b6db4e3add16753f6e8b556953f46365c87d9133a7e68a6f57b63f5c7fa95df545dd682143ca0ec99fca3376ddb188a83b3ca5e3e899c5b8a0dfde4decebec2988171d7bbec2742feb77e2873d6d53b687facd4c45a4eeedec4dc593067086f1728724c38fdc8b94978a67bacda824e7af59f1fc4445de5961d526b6630df44bd4eca50c62b77fcad73de86c167e9974316962c78d5dffca9f5d4a413dcd4da0b4a9bbc3db7eb825d8bef3fa4f870c559fa0dbd018fc13dbb59d68b8b7b84906b4c5e86ac94db6fdb54a5bea005f0de1fcf53f9dab327e17f4fdafb377ccb0f4d91685a247e612734f090edfa234db32349893544535fdfe655d398914bc53589b5a6b9f0dba6b76c1f5c337eec9db7782723fa0075ef6bc3394eba975bd4de87c34a696a8ebdadcd3575e7b5be6f53c99fec5e7337b8f31286a0ecf3fa9208bf90daac845cabb86c8d61d498543c4ad33f5cc82a75a11a9751c6a0d1b7d15f74ae1f3f485b26372366cc9704ffa094de20bb54811df8e537cbe867aee65aeed4453d27768a568e5557f7ea3867d12e43e72b3a6abc77f9b2075598a9d43185919883c9e6f74d1c64e4e67f8d18785ccaaccb753b61a75e8ef57b4546d5f61ee8dd636face4e7ff424be5f613e2a945fe1aed887e8ae31e69dcf24b499dfa53ac3c512334d46945de0985f4263cad98b5de46739bd44fbcf5d454df2a82004ac7ca9cf3a7c4d6fd396239f74ab0686141d3ce9aa85efafabe7acebbe2883efc7be8a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637f0f59e495f03077a2658a73871b70e28358ca4e43e798d2596a4124b75a2376718b548d8eea706a5af56b297272afa0afda680315d4e5c35f7f4cab2a667897774fdde85e5bfdefec059112aeb1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c8185d5418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = 4b2d774e23411a5eeedbb3515e5cd0a4987d491c37b399ddb4bbf49d28aef3cdcee1768c52c7dcee7966b31c58ec975ef8b96dd3ee56544a88a987fbfc834d422599b117968b648173bface7633ede26f4b0a4cd031779051ef8c0e94333bd3a798579206873b5583ca9c6be3473ffdddcf23a76c416ef62ec8831ff4ff25bbfb48475872828feb45c851118cfc50869754d3f6b26e028534bc049ddc7d7902493440134c784c3d289833652e96c59eef867cccd627e3b51345c21c865977cd8588d8422f78de8b954736f7cf6b895de4d65c78e56bdde6e65494da75ac2e04668e0548e9658cb55d89bc8f98334ed30a58fd027aba862fb6f3c0d6f6bf7e1b10b6d5f3db8937d8f42c49006357da4f637e8c3f10e49817badf6b84d3d64d861dc65955d85d28e596fa68c97eefe33d0997d84f342cabbdf52db4b143daf6ca57b8b34f3285f55dd6d5fba2ee907b648834c37ae9efa300a715e33edba4551076d51d31b82b6c3be159f8c9cb7817aee6ec0088cec24dd3d6842776b30df33a11154a04ea7a6ade981b9cf995a37bd16734f98e95e1f753426fe5c1a9b69ac4bb27a9bbff5fe845a734bab7fd595a66c97b64b43fbfc54f43e506cb8a7b759fb063f7c957155ebe0fc194171acbbe5eb47e024730a76c04d55f5baeac5bef681bd3e59bf18f1c5b448e4afc6bcaa55efa55e84f5d84d257a0f7a97c42fc8c1848fadc7a2f3db81781675832da5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b375e32ebe95dc25a9ac4ae838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1e8e755877c83b6511f1dce4e5f440bd94c246579721e50a33c62f52e92e91ae78f676ddb34a0550ea151a4c16749ed1aafe1654f38e96ddbfb94adda266e24cdcc605ffa5c17e9cc1a870e768c5fa95ebb1d5e904a9875fcc58ff39375c7ff850ef772386b6917e0b6b96c4bae7816a6a3fcf68e7c7f4ef4a8fc05799cb7b5d2b08b9ecdf9e6b3e47636835c500360f24843c265b1d38fa34f04ba6246b6ade8abbd0ae4681542e78be7d3a8d88c6f43b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = 6d1da1acf866163b55716e33db1c41474a3ef0d4c7f23e637e3fb4803ac902fb5246c858a84f6f9145cec70d47473666a5e9c37b8ca4b6dee61dc547944e876aea6c515b564d68650ba8f2c6b8e7b5938f3809a7851ed27885ed539b75ec07ba09aa34b18e78ce5cb5c07dc99e0fd2018b55e21c8a51b9a70cef997bdedb8a783cd9c54e69cb8b8a46dd0dbcb9d73ed933a5b7c5853af5cff364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a55e81bf8e81ca35e5d1394e7ef46ab69aee9345ea6da3684d8f72c3f4e547eb9e2e397a18f982e9573052acfaffb88fef83e978388791dbd53906a5734ecf9a5f5fc87cae12e7360cbfa68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee4bf31bc28bfe1534a25ee5dbeb43fdc5df38443a29d3685f328dd65658aea5b96078ba1516f3ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f1abecda2e77c5dfd1978976589dadb3d63c5a7e9a2a2d69922c5ab4b6b9ec35f3ad9e908176401938fb16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e75fed196ec67de47f878345213754af5dfaf00fe85ca7db6fd7ca06bfa60dbf5f6114bb85458dd51aad9bf5b6831f4b2238b99428538ff27c66777a49c5ed8fe3ccb4ad486f55ad1e524f66fd96a610cf857facd3aed71a0896e93036db5cee0c8d78b586aafa6fe82e2dd5e17446f6158cd354f7624a488fb4650c8883191feb60374b0e94e8a12866aa91dda7b2ca387b4b792c3719ae883a14de50a668cdeeb6e8e59ad3f5fd36146ea5a149c8598de245888192560052b490248b91a29adc17d834438db0b153bcccdb5755932467e8b029df16d9a3848ae86f41fc16904f9549fde862b90a54f9f5e9f7a340589e193a5bfaa46f545d145cafe6ddf7280cf545ee5bd74d4a38e28ee527a80e2288444d860e85ddb3ae3827a34d425a6e24ad345e44ad3cb4edd386ffdda6fb71e8b3b1e4bf9972934c01dd15b6380617c89593d3495dd3366b6a51e7ccf6d3abdfb34fffb8367fe4aed44ba87bda4587aa4f7dad6fd281adcb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = 608a70db0e862edf5b9717bcce38ac41045d44876aade7c1ed7afaa638994dc7d11fe4fb3d474b08f87b4b2a3b83ea94b5bfed214bc2c974a079cff598a7cd7895942bcf9d876b9723f32fc3bb696b467bea64b177def1983faf5f2eab49b49fdb0bcf925f600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d390e30aff7a0bb2da75f9ad4248f94a429eebdaddd255ba923056464f6621d2b96c493c2e5379a96de6f4b5a72e5c5ba394d517a28ab3d8a8c3b8c63e98fae3704f25a74bf62c54bcb75e59f9ccd89ed7933d493701fc2ff174f85aea93e1a9164ddcce339d324355c1d7bf1ed458e2f5883a98d6b2d65a5f85b3bc103a692c9433343e671f54629e89b1be35c25746130d7a9b939cbe027e70fec7d5675b3bba33e4e086d4c76f5580536d1cf8ab6ed73e5f37cae8f6173cb42306dbc122d8fd10f33966d3d8d047fa57cabacc4f8d2f361a143f1bd2d827d5566dba65bbe8f7a2fa5fa065ca1a0dfd8f56e7e0bc9bb97f8ff442f413d83e7c14866bd8ff42134c38a7774d168d485fa4e3915e22ea993b04be2a1f6323ab778fdee57e355deb02357a71c3caf9571fb83718748b2aece8296f570b05c4a786df06294ead216389b3b3b72cdaaca94a7052bdb5245d4209566bc153b3206b822779a98f5984254fcd2c5f46c674105b450f8e385d1585e651c934c53e2d42d8f784da6f8a47e33a3f21d4d747e55fe1b0b7918b64d6d0e8a1314e6fe3fc20ff641deff5bec83ef9bc9a36ead9c1f6ad5854db920694b2e9437bf23c1bd8d835447a3404da8dcbca09a14cc83d44b20da529c3d3d74a3fcd286ed2705d380edef93f9d7bd05388a8d78f57395ee2972652d97945ce9ccbcb4cfbaa79289ae32af30c78fe8b3d7d75f03f663089a1e65aab279c3e4d9c07deba0f72a79707de382385568275c8aa6b26a8caffcbd9e454d9d1d4d4b6fd957a967a17c83cdbcab30d299a623d4b0da14a1972ad9bc83a59f56a05bc6727e9e572bac8fe844e05616b5ef3c3e0dcf99906dd6efb3673f4471b6f9d05957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = 0563f3ba95c83ac687a58a7f938dee7c388a4dcbcc611aaf6399522a6da44e3e6b77734f036fe8e4cfb202bd816cbacd5b9b303297b0362bf3d63ea77dc965ee89694288460854f59a735cf0c4c0aedf457c67f4fd0aeff4546e5ef7c2363760ad478aa88d6df9e35f0e46ca8dd643c36c6c9ee3b56428e894beb3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f563120faad2c9d1d5a7675d64edcfe35e92239776b8ee759cec55fddd390f32d58491031e7d54144a20247017148585ded38aa3f9b9ca5c1dd337c1f758f558628c6962eaf49abbcfe4289e38db549c04f87bf243bcab3757f75b95c2fd86860fddde8c6d1a353fbdb3abc0599948ebc82e2434aca485d2aef87bdae679dfca75497d732961780d9bd384a9a6ddac8c7ed2770f61852b63d16fdfe82b9308deae2b8c38bd1d54c0295f7bef321dfc82417849a3bba7477f32830c35c18d38ce2c4562b7a8927e864e56612106f88a0b777f0fbc510f97197d9af63a7014d8b9f7a6f7f61b457a25c202a6cdd6f9a59fcc3cda84a1a446f0b1394fa65841162638343af4671a6a72ed92a8ae9866ab7519f7f3d6ecb836998af97f4efddf941a5bc225f9acf8468b5c68a781b664e46e4fee88fc20f8dcc9ff7d1f4553985d9c86067979d7407b1bb5374d8c654c624aecdcc126bd3faf9c33f897e168c9c715887474cf1479450c8d65a08e6a7e1999a90fd18cc9cc732a35c8d3b290988dfb3ea80fccea18a58263c7bf18ecd49836de66fcc6ba9eb4e91ace5034de7a2a456356dd0173e4c404b269fa9a8d2bdc074545ffbf88208b790de67dc3c787a13bd041d5ff80ec9f6a96733d874e986a3e06c7fcc5bfad256db7ab2e41f4be86525aa6b7df901d46ae2f5c7a195c55a48934b447897447da9834e4daae60a8c45aba043dc597a2d2a4acec77d8a3ba881d9f5c215a8063fb80f11e4a94c63a1a8ef49368b772a662ac38856c79c7b726884cf5a0155f7da479c1d7747b4d74cf3303d712c7dd1e1cffaea53ea1164bf9733935e5e542ba3a48bd99fd8fcb8ec391a146ec19484f1be5fdc33e5e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 801ed09769ee7557deba3eb90d0a7bb708c1b5e97fcb4eb6161ab4c1cc9ab3cca4ef98d4c76c45c44c4bfcaf9d989de4e46e95cfdbd4ce74879a4f61638a779fc540b7edf86849b7d05eb8b648ad792bb225c4fb637693f967c21758cdab8ee34cc68d8be7e98b2a97117e373f87ff7044b912775653deb78aace8c80ddb875f6b134aa6579deb5087e4ab6a37fc67d51df46a4f0cf99a5eeeb6083df07a9e5acfc55e6f6d0cdd4425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e1aef9da4e6e3bfca22dbf0f8f4ce318dadee2f62d885780c9c4f171685b466a5db14bface3cfbd979895586a5f2afbbb86f6e577d75d0d4b934debb61bde3208882329cb7df8d7a38656f98abd1b3f6ded25d401035c816b9e7e677a29849cab8ff7d57b796964ee1106d2527ae5631c75f6e9be24d5477309d7f394643af3e161898530344c07693c4eecd42af8d5ba2e57b6637722146f16f4929747da074962edca884a2cb091568e70e3a57fffaff7abe7bb7ff6b396a5702673705bd1d7959c1815e3e0bbd3a52e425274ca53774557a8ba0618e7b62b8abc2d596ebae68115e3885435486bbb5fb83c7a9969ac593881173378beb79ef4b7f21bdb6eb3f5826667fba3c4e42ff7cd858578bb771c27abed688844b95a4906c290596ec8be4dca4a60cf8bce7e1f54583380345ea0266384decf673048aa660b9a8dc5f0d37ca59fae9cc7fe9eb9e63d6e94f076b397f60f7ffee9672f9eba1bc5df0ce37410c686e9a5fd86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637f2f7c974df9e79358140adc11c4b0e695aafbc75dc2f9dd8c63740c8875612dd8b8959ff214b513e4f056f78457b45e472854413d6d15e3607a23da4d7bfbc19d4c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382625cd7c5ff6fb449a412c37b73037131d8eaf9084eacce6b50956ed9daaee004e63eadc959d4df78366868fee379dfbccbffe762b543d9bfce2d7ca79cb7ae2d06544a8f728a8afce39ab54df835224efd943cf6f618ae559ebea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = 412ac50074386914e6fad3acf0bbb1652e32624fd0006b4a502975fee79d2b7aaa8bef745e16c0a666c8a4af4a990cc4646c8bd9e6744e6f45fad4b2acc58b010ea7a45eb61debc0cdf85b5b6ae88d14dd09a4d2808e31da7d6aab35763e4aa232554cebd44886b7da7a846e67c3842e96a3e07f33122f71bb1de106efa35b5689379ce08ef44f8ff858435b7fa2be376f4c5276b4d0283fb81974c79bdf3143e8e34fbbb2426c9baf566b7788d3a354c5afe8a1b94dca5819a3d71f752d04720728ebb7cd49f70656c22589d1fb5d5ba5d6f53fb52dc933d0f8e6b28d681d7743acb5f5a09fb8b33d9286b680d174b267c5bb01e38224763a26ebdb376fd47769eb0707b09e97ac78fa71e53e54afd392672e7067fb6271fb4c16d7ee278adadf8ed562fcf87b7493e4fb453c098e5da9efda9abf9eaaf9e8bf8e0cabb4be5c8a3f59d265f5cc94adb3a52881ae8d6f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6d7d53a48a5168934f0f2341bd26364839e0785546938e5e1b69b1faa7d31bfe3901c4a90546396a09e5f1dc6d09f58c4af89474ec34614535a6dac8d14def67339bab7edcd5d9c2ac93fc54a55175567a5565c478cc5fde74bf2614c6825e52e83a615de8ca9ed465a065d7ba2e8ad6f7b9b2799e2bed40094f87c19573ae1fd0c8e683d138ad4e98d4eba5729ab8ec1e1a9ad034a353ce56e9ab635e849f65a37ecba8c0009843026f66d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b56ecdeb83b647e96d757999533d97b0d920d0677ad6cf3906a3fc9054f1b3e76d5759d3aad3e591bc10a7cc7e05397af3cdf60e84de253e8424cd470c8facbe97f3a9889c2f45418daf8febd92ad7d3a6a9bafdf7bdd0528fdbf9a55dd3397de5a9b0d7c4950653653cd35adebfed3abbce4e755d35e9e891f66d295f4c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c88e1966b7e202395d4a46d82bdb3c2d3950fdadcde2d8cf56fb6899e9b79366382beea6e195cf234cbf117f4d4c3b9bd0bd91626d215bc6d520f689b2eaf235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 5444f0225d7ce3543789ba78abf3dd634e382d6f92e084319a4aba75374c0f76e7bb0a92ebc5fe66d790ba1d6553d5c2931a95359ded3765ed9e7a854b9733be3bddc6b86390886a643db159f96dd3339ca13af06d3f78604ae23bcdc1e8a982934bdb29b5671a39eae68cd8c7945e7199eeeffd48dab9370b7f865c0b47c2c5b90d134132bcc48d4bb6995bfd6e1567409467bc2e868cfe7eb5cf3184fa9eda3bb6e2187d7e9b7d503a47ab2cfd0837ba26bed8805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8b7ef40219e34aedcc0d24fe9e763adfefaf2d998e8e686fcd76c03b069a5596d5f67fb359fc4bc8bd346e1ec1e6f9ad72de399eb992b9e54268ea8ec5e9af814f90a19732cdca883c5d62fe1a878b1696ebad340f17ee2dafd6d49f84d7bf499cfda7faf99f5f8a6b77499419dcbdeb77f5e776a0345f86234a84474c54fa5fb6ae075af57f9a277381a954e4e8e6ae2a9bcd2f0e517b99b299f3aae1ac965c086e59bc6d33bdfa26c9e1be148c7e48385777b841e9e7c34c8842c9c90ea431b2f8cd71a78a16fe85f77cce76959ec1748c44e5aefb24de752c97c5aaab8e936e84b5c89c3d80480a4b8bf8efb47be2049c6bd67c74fc9d95fd95c972afc814fd8b55d9c867aa61783896707a36fc0be85a74d13b17e447469e768a7a1ac43fb776498035f2ff98de59c3f2f85b919b34f46519e4d529ac7a147586279f1206338a67c02119e94eb493d4b9ce33bab709c333aa1d79a64fbf0e7e7f1c875d550eee7ff7fabc34600055ffbc9e78b7c87fc447e29797cf38467296889d3f2f5dcb6d685849f1c976705005e347addaf6689227f7d9c927f7c04e483915b93c4ff5454979c0ca7b3a2c63a16fea5679caf6cf6d5954e86f43463ab4e9b4a660f34e4a535b9236868c2c19e616fa6522bb859fb6e503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1e8ddac825c501c986ed28bedbcd604c4da0b4f899059768149db2656857ad8efd7d4ab4ce85673fa69c405bdb551da532fda6258336d2bb63a09f30c16c9a85e363f9c355f90de0df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = 3fec7c38a86bfa59dbbb7bd01d1f9708beb7664e640139da94dc8e2cbbe503dc4cbb2a51bda96c5828397e4d6386353a75157b0afe776ed5347f3a32fe7bf59a8f7f83ebacba35ededb3c3e514b7add849ac5c40e4abe297634fdb8a6c0d9748a8fc9e98778668bc4447ce444c1d4db4da7ae5fb5db088cd350e7ea79f6dd31f8e9b39419dbe3ef96ee705844d4efcca1219453f987cd6ddb532c6b959cfd2938a90cfade67a2d35577a4b59ecbe063a8a158b92e89aad62ea50762dbab2596ef187785917d8dcd6fbec78a74715ac69bab4521949e9cdbf914b5304a7384bdf5e79d3f44e68e03394eee96f8ad68842f42d584068cdfe9e467d1d51d1a8ae77e4b418343744fda64635ac313cb72206ee0a77f6464e3e5f9f853f06aab36ad67eabbf6774a291945e9167f55a04d18b1f3a25778d583d8328a983c0dc8b502ec7dd34721db734967a706ffa75e1bd52f67c36168ab46c485b129da6ffc6df4eb739c33fb2eef630a00469be1eebc1eacaa9ca60c623d39439cfd4ecbef6d7523926ad88b8581f6e9b03ae82b76993b26b3784799a7b3e4b38bb6a185f9650c7a0a556c3dacbdfc44ab8eaccfaf63ff07f9dc7c8fee3fc8ff0cbcf4f45dac26d26d5a71ce6d1f58b6f766c8d07c56f68fc88f6402fcab763f996b174d47daaa7d05d48ec6ef97d5dc44d95a66458357afe863987f325dae2fbee920584fe738d3fa4b9991517442be7cab72996ebd5d018963f89a5af785c354f7a94251d51c80bcd0d9c7f8b09ccad58c0bb2f820e859c9a36ec6e4ea6c41db310a480d0c89510ee383727b0863ab759bfc551bc99cbaa90f0365961f7727f639183fc652bc4a2792d81dc69571b298affc7af09c3491256d1602bac8c79afeda8531423642fefd075a9b176a75d422740c1dfdfa87aad22eccb98d4bfbb05ff7b69daceb660e3a8fed3f3cd328cbb6103af5bf6f6b5036ec856dba1fb8df516b316fef67caebc587d40218fbd120dba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620debe5151b9c67a9c57aa678e7e83b3ac4e96b78ff20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 5ca83cb627b7477480003ceac0ab41865cb5ae3d6b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda583608e89a9fe829d09a37acd59f3833e7af4593f6b5736f782215c72f8b3de6036fdd786e16ffb50746bbeb7565fd1a585dacc7c645ce5f6647a2543de6e23d1844652ccfb90d5df66e3544fdd7733b8abf327fd378e2e4b615ca423495cea4965fb586c00dc7243e4f3c28e9be8b97a426f93467a77ebb87bf724632657348f2a7b34baf56d18f6fbf9d5277d76ca2f62292f91eb7fdb262355d067c6b98fa64acb8aa699fcec15b3d76d86a675d54d5dd58c7a4714165a431a8c513ee02cfb8168e4b80dd8b0c8e7fcc9ad7c064b83b6fe800c4faad50664cceeb671d9373f07d1cec873eb8a35218ebf3fd9c9afcf77ccefeeb8a4a2ed1f6f378b3b610d4426a66f177e54146bf8770ba7b80db538863907a6ecf237edabcfe18f2c40ac4989ac2da056c4dc99a769b25c7a38d7b76a1649640bf5a27880d7abc72f3f4a89af5466657c352486babe7d4c13957d4b8ad26640c3b6f23ad44be71535c4cf58de54dfb2a69f54fff103597aa8778127e971bb074b4de7d4442cebdb48f74058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc54784769feb0fc7528da3f874c47df61d8f3e16e06e18adde5a4e51de34c364842473dc43bfdc0178bab98a67714c80922a3ddf53edc1a83a9a0c3087a45731177a239f8551cca0e90bc229b95589259b9824a679a5a145cdcebd79d621defdf2ab56c3a633ff7aeaf01357b98ed8c4d56e6b694c42ee53335bd34d568f398d744059a214f8dd3f477d67a332d44ba4cee7ab26de57b624e6a92df4dfd9ff375daa3e9c6f89a7629f347f91ec54b13997eeae5bda14e2e02ee529497284c3e2de5b4b0cd7dbf1dfb643e5c2395e33759f43b678a026c4e5489c31d0c9d2f4dcc96a8eaccc8abc5b08b9fadc35023bfcf5888d417b4a0a188d0b3d5d9ed8f0eaa4bb8acd85f3655c0a2ab3963bd69cbda1ac6932c748cdc71eb1949abe4a57b7af0c934c9cd696ba6f39d3ff4e6874798bafec7d827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = 1e13e5240833d1fd9adee4bbb29459f947897c4b88288dc33a0e9161f8db4699924a5c945c1a97c8eba4af2587011f6748af80109ed92649523dbc47cee3f938a783461aa1bf75d0f66b6e8307aabe7c40062d9826a98a2904becd2853fbcabfc9cf448948dbb4f7a1dcad747338850889fae1e7ca257b5c15c3771d9fb9d07bc0b83c7e348ee77985cb61b7bcd0083feb2d75dde3f1ce59da483a897cf6955394d02bf3d16f6b9e2ddc5b8d5cb7c407f9e7966e14cd4b310b72871fea565ea8b7e8472d969703f54ee5eeb1ae18cf1f6454e46dc7ae58eec2b3b72e4d49a755e4eddb57f71b81b54d5dbde79e06ae787ecfb19c07fb0a93b24abe5fcc16ee700c5325b4db8815f7f33b78eaf7370fdbb8eeb38e6c1585a13ce60cdc7a43a7c45fadb9bf18c5b5256b30afa25c2cf9289a72f09560d54662af2c359dd87d9c59928864ee36bc7313a4893abcb4ad8f69c38f9331df6b46cb666d9fef4a8d8c79eabc047be10c75a67ca59db9035b716ecdec3486aabe52856c360f1fee3c25b4046f59044347af18cbe495369dd5ba76ba917fb37d2314cf746d7fb0c845463693060ab67785c1c6ba8efc68ed21fcfa856ca5428de90f6ec8ad2c91b3ad8792cecd3def9b080b342183cb5355b08d5ae53c8a9b32bc4469d5557ab6ccc4b4ed1f9b6efb4d5549f3d022f64f62e665ab8934a617a4cac6d567cb62dde7bd81fb69ef6da603d9e38eea88d78f3cfb3b6c0448c7d244ca70f5991618c3005e4734c98268f5770fec449ae6b4c47b563b9795a9d58f01cee206f4a26e6460af0531e2cd7c55fea61a86624a64a7701964218fcd2cd8464f0f9e94085a8bbd35281dc9f42cf3ab47a5402f36387a381658d36dceff3f33e62496ff36084e1ed6b58309a03d5d838aa7dea14b76ca0647576efb13edacc6d4a548e63213c746877b4054d4eac3eb6eba4ca75a2f36426e3534cf382d53352fea4663d5a121759e97849e7166a50f139f05bfbf9609ab5ecf38af3cddd59ab31d7fe4c288b21b9b33a6cd4845d6f83bddbc16285685decef1ceee8c3f4ab4df616c8ed20993959825f07b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = a2ccb58dabd0897e79c2fdd7ea6f4913b9924878c5db1c9e46faaaba2af9453d4ed64cbe6b96c3d61b83c404c499feba7eeb8000c8381de471a50957b64a94c4e4f00593ef4b4380899b5b848c307fc49654438ea16f719c2d796bc39b72c34fbe7e7bff95c687fbeea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b46db3df0d55742563a1ebf78217ffcfa86945f83f8f0f8f81ed882588fb05a6d005f37992fcc126b9c942a7b2c8af30c318f4336ff8ca7e335fc3609878509e4dfc8f1cb7ee3b4a9e68d13e2377c21d4cdebfcf9f96979407e6cd8d5157ab62b9c5fd7e273c2f6b74f9ee42b8473ea9aab2ba3cb0e189e831b56dc7d6ac7b4e482bf347a63ba6cc17f202ee9949e7baead45a4aaffbeb8d8b0af8d00bae794b4a92056a51dd0adf90ac818a4db57408b9283cd836bfbe2aaa417ed6be7328926ebab1bffaa0c246de60c9d5834a9db849dbc59df6f1136d48d4f587693ddc15556e4472dbad4d8ffbce175bac215bf8b74cdf4dafa5229fdf7206ce7daa749115d937d5c3609bd24a97993bede56c9cbdfdad997893a7e51fbc5d6b8956385e00d7cb61696a3e94a9833dc4295394079ac7b28e8f1c56d1301850735690abea3ef9aaad83be6b30ec4f771f364feadf78557249bae302d94fb989facd69e46947f9531ca3bcbc42babfbddc768804df61200eb858a8d9f165d6ab6cf1ce5bb94053d6026b74b1685707dd9163a74ecd5e684757a02a9b5fd02ea59c17c894135dbaa37e8a2f9a9023daac7cba155e3de256e1fa87d63f4aceb30a92d3f75c4dabcc5eb3f80edbb0297b7b2b94fcff286e442834624936a856e752693c3369e6210c3d6c1c54f9ec4ed70d76b38e534cd497ed1e3aab83d27e9e8d6fdad80ec48b70c9b6cc57ac537f76ff4ba3aea74271cf30ab058a135995d39438e505f74abe7be2e5ba199dbfb484805d8fa912f9d46eb9c2b563ba9fb48bdc9b95bc9f76f3e9d6cca8c89439c8659ba84d77fe283890c468cb33877ab0fd6af74da9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = 0529ffbd776ea2338c7aa35efcc6a7d338ec51ee521186b786edf0868b5053bed2894fef363986f6dc5d28033d8e0553d97682417345624e6fb1f8cbf623ccb3b7426359fcc0d3c086b4480748d4e4aeaa93d5b1a22b9e0246d29789ec701aeddb6880ba4e3840b8f8c06c4b5c69a4ae68a8069431f35b91751fde61758ee5eb6e337888bd563e1ff6c05cf568739cf683d5dba57e3cac7ddc55b362f2a3a0917e59a30a97054bab56655c273897d168cd425e9a3db96c012880345fd58e385c802aa7dcc6d545afe5859feb491a4a009f55d31e8bc9357bf6e78faee87606a4ea831f9e6b5dec1504ebb886b0c36fa663cf7e7deac9192cce084dac4758e744ca938cadecf83771946c6edec63cb9abe817f5ad4d4f85e1ab6c0186463c43e8a5b9f3cddac59a7991c04f79a23f4671153def59af647aa7cd454d532a4ace4cd1e14d789d867d834dd95df9c5ae64b1f57d660a753cc56aaee958f28e7b31e5e5d217ccd34f45efc1264512b58c6b2d6b5f844f882cdc833bc78df4c936c492473745901467644d4441a4377b1d5431663394dae8402f789eb9bb96d73a031eb5db155a304584b3fc56ec2c7ee07f35ac284021c5771d86dedd4abd5578d0f61c65a263306eb8edac64321fd869e1a369a8594d9c2e9c26e754e1334269e4aac50bd524d9c3faea7c0b384006bcf50796a8d919ae8cf88d63f848b32cd269a58ffff9ce6f436ed877c33ef7fefb5695f9e9c422dab87c6b92f3aaa3333688f534ecc9a6d52f8af7387b6d8cca70fe1f73b6473d060eb41567e9dbbc464747702de4b45d3c4f0e3a8fb58f6752f3bfbbad8f988d4f021acdc37887f79d60afbc3bebf3818cdd64c40cd5cc35658d6dbe55dab57ab8e0c98ca49b89d872fea5bdff35192646c8e7b84a34e85bc6c4b679586e6c9003ed767aa47b8b23905dedbceee95f85aea529185a72b8da95e3dbdd74b4a664a0c0864ef0a557938c8e02c9fa5de767a28ce4d4c4f69f2fb1e70a869767b14875e380abeb6bddacf683963db5f48296cf1d8ef95529c9889546b85e921284fe86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = e06f4bf2996f55293fe32bd704145a4b9f534126e09e4cdb909d4db4dc70f4ac96c167f24874dd73dbb88db3861e1d8d368b30086cbc72bbe77e1bc4853eafe04fd8df44fde09df787e385d5344e02c49193eed5ac0c78ca5f53ac9dcefd97dfde5c53169feddbf8fcc2cf67bb7974934d9603c853675df85d396a53d6e633fff7af2d96237f5e4cdc5768e96bf304ff81b6afe853c7fc8381b4aa6071ff371f0d619d685973dac324ae51330dac6826b6bfeb9c0545d81617d0f06f38efc37bd5bce2ed744714b45db77ca4fb998745b6d12fed42142cc2a09e61c72c86f7cb7e834749e647a30a078de023e1d908add3abd62018bbc81c96b74aa702d4a40e7a596aa7f0b08496d2f3a990337a1a4396c39ec391eec4cd685dc9a635e7c69f7cb8feecef43573dd269dee84117d6983a49135cfd96365fba38b992967de41ba6a91640858cd20ed955a22f8e5a44c91eac6a3a77e0457baa88d4bf072c32d458b333345f9f6cba68e9a40875e6f074ebb41ec72e7fca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74c6d887ae9df5ab7d2f2a8390e44492adedc2b58d327453af3d6530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4c8e709da8192efa2201c9e6fb973f724f622fc95d9876d4cd893a9ff7db619515b476a166d949db5a893a675e0259e996f5f46aa41fb0a44375ed59157d0263d5a01fac275d8cae99a5e0666ec95fde262c8b87818e852d86ad437dbee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912b5dc09de7254788b0264933215c74c9ca4df4f62ef98d571078ec2695f80277e945fd8c8cac7539fd5ac5f3ac08cb8d29a31434f606677a8b196e6f9a3ae1b4856537831cdaf34487e8edcbd56f8f9b747fe4d3b466a1c54e9c4ce55df08960047524a7b39ec3c5778837f0ecb8f4add3204ba6a428edb07f8589667c76abf6a6657fab92e7c1affb30389f9f8364c0a9fee80cbeb5b2cfd00786930cdea9448cd60a59db56cb96b5694fc7b7abb48a23b9ae2ff327a5419342577c19e3db0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = 66bfe7f5add1f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e1ae68828ff35446c1ea7fa309f3c67dfc15cdd534d1bff418c50e0e8ebf309a003ded0c65d40c6e6b5433a5d48dfbdcbe84823c939c3f76a681982075c90c4d7e2d1399a0e8fc6d07e3e60bf8d0ee6368cd4a7095d8de163dee89cc53e8b7df748b91ae45bf2a849748a3a54695b345397518fa39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680b0ffa80c5cea07647fc5e8b87b59c8bf97c236fda56defa1b86d8d6445b907f4b261dc55cca76a85dc8400895b4a5cd3e7e65675f5479fb4cb545f40fecc628c28d337635af6ac6366c8a778d84980ba659f8482785b5b6fcbea265a99012a41d6de3cfe07c7be8fcddcc9844adda2663a468fe9591b0450707a95538bb1c22393f88e3e697e9a2d1ead8f4ee402885a54588bfc47c9fbbe8218bc49c87397be63fc0127302089ceaaa7e02cbfcb21a9d1ebabc69bde764bb6cb5e7553810b923be767974d6994587bd9adc4216662652bfe8787bfb7be5b99ef6481559cd41dfc2a03bf0d53467efdebde0bac05e968ae266678bc6946ce82d1d66018cc7762ecbb111ef208c3cbf3d7671a98388b3db990a4674a8b7c6f958eac3fed3e58579f6fe922abc0b0879b825c9d6489e671fc6fe85fbf49f87b606580d62c8a17d85a927976dab5dee55add186c6c4806f06955b8afbaefbd8d5a54fffff2afe61d28500948e6d7235d1356f3d3d4bf20479aef39699426642bcec084ac43d865755908e8ebc3e902ffac3094f1a0ea975b5df3231d80b796d49c89a6c55eac076a80e97e92d8d8b19b6d83b689b12809dbfe044d16663fd2caeed717c17d6cd6cfdf8446c88f30dc8d89db3d5c63ef6d6b63d5d535ffe2671b6f5d97254223f68e89279198296db1cd917dc338b1b5b33f7df10457970bafc2caca854b07937ae6cca428b8c4dc96029c57ed3d9ae6f3d6b077aa1d8baf3efe71112d7b74dd56550aa7ef27eb4ebbfe8f7990439e41c7d5e8299733b734cfff884aaad95e55b4a65786f56d5540a057baa755d5750ef76b3d91d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 6e1b8a3ba66274e66d3a9da19fd84badcb981603691aff3c61077d12d85eb2058bb4b3369a14dc5f6e573e7dc590669f0d394135f3d570dab863488a67ce744a165c2f4ee44ada7b361d83890a3d10077f2e556d038ee34fd78d571affed55e572e4e97de9dfa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a4ce54738d80f0e4b9114edce1c948007990e03ed8b454435409fb1fa6685bdfd3c11a58eebb3523b473490cfdcd19b33d6ffddd6dcb9777ead11ec151af9b51249158d5a131d3583196c829aefe7b15572ecde9904a548e0967c91a684f4965bb3b3e8d0d8bf863ef98286c006bf7a01b7ab3ce3ea2d5d133c3431ebec66a0b83bc9f302fd7948938b4e87c7ad2f430c75e6872474185e8d4c3b8ca891b95f6dd893d0fdc90635c84baf60a48aa7b9b3c1423dd77e3994ea5fcf52843069a42a6cf85dc3fed4f59fe153cd3a61f70a35738f51aca012560f85af38eaf94f3ae7bb36bcadac68bab4db110d78966f6bc77b8930be7d8a757d4549560fc59769399793c36f53e67bf4acb629138c277f7826ddddbbde6edd3b97c308f77696387196950e1e53b3c04d264d3f1634e630886ee72756c2dbcdaf7945dce06571a5bafc1968d25a6628b766bc99a5d44dfe9161ba16b2dc5b2075a63de8710dab47265dede3ff9f94f8717b58ddfaa67025c3e0ad97658cfdd3be467db6752747961713971d5cbbe287937c12872d305a129fd5a53e56b4339fc7defc2a46d381a96e0f2adcef2cba93359c06b3c74e9fb4166fe87376a55fff7ab9fe872ca2fe008579a887d99581458714ad683a9425e6d72c6c8e3048649a9f5caa4d6d6c1daff79299feb0ac1b277cebde8fa2396a02b37fb4bde96d457838a36fbe49e8dd3db84d7e8f1ff3aca8955d478e8c10997628f9ab23febd077997a8ed5b26773377f7a466a69ab4f1db2d93899c66c900fc5853928d5afee677695cdbe2641598e6755f69516dec3d86d46d19ce8e083d0fff2bf6776cc7ee870018e5ca4e83967bc37d366b9ccf74870a678cfffb13a7636d1e3e1dfd5a37afbe4a3d5ec9087b00a39e1caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 8cc33e479bd946e4646e934c7bfaac527f94c2a753580ed38b8c32e23e4cd097471f15b35707a28a5ebfdc88590d464750a6c7b5c6fc4218bf9c25fe30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1f0cd1e93475ac669be348d807abfb5e33df838a8b003d77b97672844639f8c7d42ae6343f78efb1f77f3d1e970cf7e5b8033ce11c9089c9b79e9470b9b64f4feba92067988297be2a4e3c609a3e245866dd0d79ad6ea61caec9064fce965750f2b57a03de9f5a7e9af929ee63aeb64579bc6bc5b1b353a050e9e3ec9ee7c525b8e2b4e7743c9eb8e589776b885c465e4e0fa51ee7d72d69c8912ab6493bba60de868376f3dd635d822eac8b97772b77ed76d983c513a45f4d68c6636f6f2ceb21647ed86fa3fc3e615e88e134075dd39693675f7922868605459a630f428c3b94497978429b7e1cdf384f1e54bce539707eac49aca4c426cacd1c66c1ae99191d4e1e6ac72018bfb29de9b9dcc75b1fdc14e35b3e7759488bd89a45aab977312506e555465c1aad62ed9d954429adcb6ea62e3de14127312de5f9046d4f943ba8f4ed58344e84460dccd8ed6403a95329fdfbd3ea6bf3c7f1c2049360a3d6037eef5eaad6a795a4b1a8b8d8fa7846befd1dd44d9d67971bddad0c3f80b9f996d387d89068faf9757360f7f08c8b9766c8c673db52c22cb6e177e91e1e900df3b21a0f30f01437bde8e45def32a1737eecab8b2dae489e4f7ac754f6dcd39e12a8b511adb6ebef69aa5adf477f404589fa27d7cc343459914a490a27dba1cf7e1405639db5e41673b8ea6d6ccf5d9d353abef9b7c96d2f49dad3320dde89060662c21d69b37bec75e561fc4af0631862a9b531c41683c30b787aedc03c49b8e26c7bb5aafbf16950cb7c5eb326481b9e61691859932c430e66c1d998a1be066648c5696a8f85696cd8d004586408360bb8954f195cc5198fbbe3c16b3fc72fadb5789e4f569dbf189833b9d38f27433d406a88876ba754d86f4d9bace1665f4219f129995fdb3b790a89a2f1fcce9d2d48b986c8bf16b5cfb5b4f4efef4ae84b5057c1ad69f2bf25f09eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = a764b9e7abb0be68520a095bca8946289731b6dd68114acb1209507eabf0831bcdb3bfb6611cd031f89f6e4d8003ba57398b5d4bda4479134350994a829dcc1ec6b8ea19d5cd38772789c9873a4cb76d6e6a69e4111f5786e7e40778975c57f077f4f416e3f23d69ac994fdde5aebb4586ef04178fb63c92c72bf4008e56844455a45a37969b42321f3483b341ff6652e7666ede163e9c6e43141effcfdaca544b99d0affde994cf6eed8799586bc69edc5c1c54882b935d6fd46a2e963865c0b82b5467ef9eae6a62fb1792f5fed35308aa5af8eaab5f4533ea7a000d7a128cb83cdd587138c73d66b17c585f7037be9d0d89e667ff2f68c5ba09a5333f6419b3c19356f67d8887dac8ffb0176062f4c6e77d7ec2ab74492e5e8969d8d82cceaee5f8ba85e14c86d9e0b6b4e27b9b14bb8adbfd413d354f00d33409d5a186deb95c58b7a86caf904cede1bbe6ab2d54c13849edd469899780c34b8c424af7483abcf4c53b4c0ff2107dfaef9d4d2dd879054b69248bd5f3b86f01bee13d0afad47bb007afb1fe8a54012e54205efd307433cf7e362f639fe3a9e2fc0a6ae4a33ab5bd7ceede813e1dd9b784bdbc2d9a58d66ede34bbfb939c09abc80d6c71c65d953494c9998ea1f87479113ea8ee2bc7760cbf75e8fbef1e668cfdd2255b7a0309527d63bd3707a692bc3d3d9f7e0b4d6e852a7216ce850dc9aa9b17af5dd7efe9c57dd5dacb26f954796e3c878b7694d74be84fc282a9edae25f67cac6d2cddb2d2c469bf49eefd57da19d59a6db65710ac989065f0c863927ed8dbbee88513e7dd009370d7bd4af5ea49e6263d045ff86453d7fc4d7c4617b8b7977c8f2c8bdab888941cfb1e15719393ddef18d4d58b8f3813e6f60a3c27ef7582dd3351237cbf85ce435fc92c19c7a95ff01826cf699ad74044b9b823f236ab68537e8e0aed33e009a1e8dbaa6ce98a81fa63724d7fc36e9e5aaccb95fec8fa28f3667dabdcdfe7a0489be14aaecacaec631b76c5a996d4bb842bbcce67a8f55d7365fed744875f67da794cfa97ba6c89f7474647a6c952a68954379f97e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 582fc4c5abc6bb1e8828263017d56e8fc3871c5d3a8517a0e3b8bd829f746f3eea1a09923b86eb20695f6a3ca01ec6fe7f6b5302f54b8de33fe02b8fcface6e7c552977735139877c95bc69bd7d4fe94c0344ee5d7fad91fc4ec147cd7f487961c83b1b29ff5e91449ca6e769a7bb434a93da88531a76cf07044a46623acb844fd5ade455dc434e3dfbfa5d3db9807789856b76d3a4c65d642fe65827ec7d4039dc2203ff8e50f51680aa7ab1d6a4e25dd3226b0314d7d2949f9c20bb1afba5188bec4a40d749b3f3168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439d3d850b68f20d860ba36fc992c99c2bc37efee95d2e945c1d6336ca9da77e9af68eb8932eb3325e362db5a77990f74aa3b699cffe2dc9d4e49f3f6fd445e48354b1609c0942735dc6480c53bca3c8857fce9d96506ee4eed5099aef72e3ea51f45f8fb17acaf669efd1d32a434df0a8ee8697842d89f39b173e3a6f74aba689aac94936a35a2143e9613a7d29b8f3d453f44f49a445527b039ec8547c35e830cfe087ff5d72b7634fabe65bed3283434df7d5bba284fd234ea7e26e435c896e899579cbafcba03c53ef74ba3cb30adc8db94bc407159a5d3b35f85b3ba359ec85b4379cf6472310335ddbdcff40d6bbb5c8c37e3a1b758518d4c740ab5358cf8ab6ce9f542a79a97dc4498734c8c9c36baaab2957fa9cb633ce5e3d039bb53b03978c524d2fea962b715d6642b5f634f345746abc41fb6625a96454ee1a2c78d674a755564f66d5d89e23c9b63ea4b255890f577bc5a54f067afc44887e629b542d2a8e093e49961f8a87a93c069ef5167483872d378c2445f398796970c92b4c4faaaa6577148fb53d8c79b0f58cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d62ad614f1436e46f3a77d38abcbb780059521ad7e48c088a89c9e6a11d3f478ae5a68489d5f63cd7c84132aab6bc63a5de3db8f27c835a738f206e9efc3e509cd9f05a57e6b64a3cac87f5b79c8c2e3d4ff4b6db339de3fe6cb99d94496b363d04cea27863f780fca35473a00039ed8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = 44d99657c4d036cae462e34b6697e5c8dafa84b4c5b7f8ed11e4acd7c6ae77a7a7e6193b5d8e43a45b997edf91d4bd8840cc4765b8b4f8c7caa7158f2b939cd273362ca3d2af3c59b3ad8dd545ad11acd522fc60aef9d2f6a6b49778ba17a97a48cfd18e14336dcecbdf49b90698551059bca815d6a4c8533d89ebdaaaaa638571398ac85256740aaa5bf4bb35da6b3b705e4a7e364935e769137a300ea8e1355a909759fce12daabccdcfd839879275ef82b887b1de3c3e9c56330f9a177db3f8c8437b09a8cfd6b8482bad7434714476eb0dff97ffffbf91ac607ec7b77ee3d8ac53dabe56c69b668cd73def329875f6454aeb73540e4cdf0816cd7f2b372daab8b3fce718d362f97c5a05b359657d7b4a7558eb1f76fa837e4e9dbe1b19ae05cc7b948a32d20e8f14844e1cc3b79fd631d8166d20cd72e538429bbeb09f9adac889e4405e4ed31931888e91a1dfd3b5e69b30e4d7359d4c1bd9ceeae9d9136593b9d5e402e5cf0917c3c964ecdfd95fa77de8784ac144d6e0b428fa6aad8cbd43cecbb8baeecca48de3ca5e2ece58a69a96ac65778cc9a5dacd663a632e63b1a4f7eb012846f0c6c26c7f8902f64baeeb6718163cba1ac63447cad9d63eebffe855776dee88dd1b6443763f35f443dedc88909434e931cf7fac186f474f8a6028dd24add8fcbbf1ad26ff903a7a0984489f8a9d1094df227e734536b67b3f9174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9dce29e4bce6b5e9948de7caadc8f3caa6a5c1dbf98b5f6ee0653af4bf14b75fdce4b3ff4dfc1ca4b3b2f85ee3bfd95d51f8b57c46c8a89a1de5b805f0bf1d14dde6ae5c57f66ffdf493563eebb5bcdbdd35b8395889f6d7d37ed636e57ceaa671f89052952ebf386150bb03eeae616478a1dc43f500befdbb63968945e06dd9d1e4fdb335433b80ecaef733a47bcb0e62bcec0e68cd6eaf6dde55c53d5a289284a7e7bec23aad92c0841c6e7a82a2d41a04b842bfc8f253da632d55568a582830e8d55876bc8f9dbd1686b61d7ceba6b500cf6f8dce8a5ddde3cf76c8100afafe45fc6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 945762aa4b7685de8022cbf47f593d00f4956d7f8f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcd3f6972f355b4366115efcfe9f458cc57040efb01cb3a3969f7be19c8067a793bcb6e5cea3c2ea55cf11cdcbdd9457743e939e6b7332d849ad6de7515ee224de43dc953d658e52005a323d07e2009b81614a657487abd5476bd5e7e827daeb5ba45e9c268c708f6e9263adfe7e6cdb94fd503eb2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f069db4176eb393695000ace423153c9645edb064a794cb345e3c46accddb061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345d5f4ba2ae345d15fae176bf1647ddfbdbbeb906996ec4efae3d6a9153c0e8d98128b8f231d73a878a81185f9f8ff85be6cca6166cc5b15d3134bbf98c066c6236ddf19ea15f5983128e5f3503965695586cae34847b3ada65eb6217fd03d468370e50d1be7cebfda14a6d70778c7a75593acbbbfbaa4c888bb99d9ebaa34f9bd2c27ac7adeda15ca73905d9582c8e37a223bca48b42ecff8d446db01ddf5d644a6f7e93ee1569f8ea7e627c3c52aacde5e5d8a86a89dff785c653ca92025eab662c3fccbe8af3b9ca27f6c0caf8f161eb940fd45555e7efa90ebdd04e8c5e9879fb33b675d5a27e5b45a5efa20916c83a1bcedaabc0ac0666b5afb404fd5daea6906e773ee9eb3ff954ec06f866350dee1c93788a08b76b15be96bf96d407a9eb6ddd8abe91c1c68b7d85763d2cfd2643f77bfe63596a7ec257bdabefa510c8f82976bf25936a6e48da778939ee2b44bc1d5466aafc5c06c77f8efbf2a5b6ab4d5a1408b5fd2573ef33ee2169c1667f7ee2ae9b4c6343f2038537da304909c1d08e862e9676f2ef6d7f48748488cd9ab64bbf3e67b54f719b3d4500d8c72128cbea57d942289fc36cefe32ccc0746ebb169ee43e5a4f9076b7e4e6e5d33f5fe14e3a0a88985bd48292758fddd80b5f5378d6c508927cfea478be3f68016cefcc2bd5b4789ece7ca8c1a98cffea637807931a863b2ccbde1c8d8c35dc8ebbac79c5d15e71be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = 00d6638044335765803648b2c7583d29185715cd6345d8d02f97a0b35641a2457c1f843d3ff637fbad4dad0937349eef2b143257c37b2f75bbe8b8eb107443d17ebe7ff5c8a89548ceceb11f2dc41e1a6c5ddc57d7f7fc8e17a5ce8fa60b6c8136bc3b536e87fc8774f9d3e6d9b7c2a9c4ef676ab6f53b7e446e94dc2cbd8eb3f4e98ded5ede71b5dfd054c87970258fdf259f575a71146be421667a179ef933d645bccc8af82f66d65e84b1375bddbe5d87b5c1a9b4c0e4f34526194754358de8d655114f41d2b3dc612ec9d3f7f7d943e47385b3f416b24199f4e3369df775fdebd6a3b0c457fc28cd88355bb28dfd803cde39773896ecb120a75c181d69838888b5cb788a9da349b44d5e85712cb9eac9bfde2f03a3c119ccccd37dc793e75485be3ddae5167f3ff2bae4d78af16eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824b7d72512be709b4f21b85f6da96d2cc0eeeedd6d1ba59ffde8a5d3ccf7c458bb1b994432b6ea7a4e333619fd7fde7d0ecb8781887a6ff0f702e0ef1f30bab2c3dc28cec7d86447371c6a5e9aaec171b64838ff9527c48b8e343005a58818bc8b9b9be2125aae9dafd6417d1b6cfd4ded33d2cda34ae87e34eda9fc2ebe2b6cef742fb4b4b9af2d8d75cb1f83df409ccdd4863043df637a99cc623d35ef54258af7adf9d4e89ce3c91f4fe852ed7be386c7beff8469f98e02aecd425ed64064666dbc954f9f1a408975ab681486fd45324a3a904f0332e53e2ecec8255a5e73f80fd3fe0c62e76a4c93cdc9693bfdc73156aa31968fe8ddd92a1ef8a1b8e48c14ae4fbbc745f564443a9d5119b44406af7ce9ca44697f928ed6ebfceec8fb39ed417d42cbf308c9d379566a18b3fb7ecdb6f832c392c0fd6edeab45c0de20bfeaac076c4189f3f80dad59f44e01d97f34b8af88374b2ca0a88950bc723bdeee4e7be48b8efe83f998f536ceee8540323ae08f49217ea880de4431bfb74cd8dcab0b89f328af8eb9ba932c5f3917e64dd8fc9613430891dfd110dfbc2647a3a63fd5cd796acee61167f4d382ff431a57b1eabf071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = d9f893e986491e2e9b617dae339c3115eea64d6c613544e1bb3dd8ea358749866018d8d2d3dcb05b0c5329a691f583d3c0e7f4fb3ae122df64374aab2fcfd9412941f7e39eaedabadbb7e494863f79e34eda73fc1da77ebcb6f8341e310f59e8c69c6c5036a47aecb3b2433e8a9eb8d0bab01636d34be96f31b4ed99cea2d3354f47e87b9063d33c8fa6a8f6b167f8f7cb2ce1ebf4758af8c70fa98dc1f35b353c54b565fa0f47f57367bc44ef63e9af3285bd982ce8a6951a4ae69f4d74e3481a4bc142fda85f9dc06e97ae64183c0f469dbddbd81eed93ddfbaf9d53e8a256e5f8a38d1487e32aa5c322934d5f9fc89adbf9aa95f92c7971e61c89ab484e69976a58dfe81ed545036dc05fd957164cd269e9a3abef7114a5395e398cbc198f65b46bc31d8150c4d49363fd63a35f198f5840de6d5eeebf0a7a9c82d9717bac5e32ae5bafceafcd94a353ddedcd73ad5195fd618490ee5993dd6e7e0526556314d95667f74a738bd57fde8038dc829ce7d31892fd174a4fd8302e7d5cf748e26c45f89a0f6d8795c9afec77f39c87f1567120f7dd931eb73daa813497397c0abdbec7e24fa4fdf42ed67a0ac03fd3c3e874ef202765026b7fc66ee75458ebc90ff8e46fcbbce579037c4ccac5564d0e5318e598cfcb538f1558a1b55e4bc6ec372caf24cfa1ebb5fe7acc5a060efaa469bed6688789cfc68d7fb75cb4e3b7496f3c35d5efde9bb2a6fd82436c17cf9db904b76ce5626da57becdd5bfe83872515fd1113f02e563de69ee51bba7d47eecfafe5d389a730c9a3c56d98d30bd397a9d54af0e763249cad1dbd42768d853b3572e705bee7febb204f32f6fcfaed3d59d787f09dfb32710b9fbe07e303f5a1ec1e507ecb98e5e4cd395ef4531490e49adbcd39be1affec424c726dcce900ebbc1cfe55257ad3a89b3d0537b4e00988447ca3c02a65abafad5bf4d826efd7fa683b9e9e5a6a6aee90ffdb0cba4ea14378fb759e1a064ad93b6e5ae7e2be3551c9d4a4b18e9eb85fda4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 87c3f81828644ffa865c43bf25ca3ee67ee18497bb2c2ad4c50b89ecb6b8f173ac79cd380153b55d65e492a95f8013b28d38710ee7b0b3f75cb13d7e23fe986b65c9a99dbdc7846e71c9f6eefc4815bf55a428cb4de94313eaf4a17973e5d679ab54d57e664217a54f6b26f19be642fdde6b35a5ff0d2a37f37692b34c3639e9400a15c245986134aaa3e12e9b98383cfb8ff3acd3eb5a15d60cce523e3fc01239c9df8338d8fb2f998634c08ee87b3c458d155b01dcbc20a7558e6e96b8edb0fff5c8560778542d6ddea7f68eaf74fadb80ad7f7556ee56ef74dc268fc4358aa8cb78a55275393eee9792dadf6f13de2495cf1d169e3c3f7a2dce7fb87bac4fc9ff603c93659cf1364ffb58a4bbdcc95e56f661058d7637e4f32fa3868af473355860f995dea5c6e391a8c20537ad23367098be911efa5f74767ceabe516936a11327623d47ee8d64a753785d0afd9157697a49adfd422e673e2b904aa94d845a5f17f9dbbc6db81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e929ff85704e0e2ffc8198ddd26b882e58a3efeee793ad4f8d9fa8a9406fca90be7ab867a146cc1c8cda0d45a32dd074a4bb5f232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097381de7a6f6369a5dc55616950919bf45be7a1a3656ff4075acd957e1efd62218bc84887b74da635da1eebc038f4614dd7e9cc594387771ab84f7cdd65c85ee85fac84096aaddebca179355dc365516efa4873f7d15aef8c714a4e1149befb1ae8ae6d98d61e5419dc477a5ddf8259c7cadabd41a7a270e5c91b6e6e5dddb05976979967baf943b5939e7befaca4d78f7a4a545fdf584b8a48b6fdacb1de775bd259b083693947b3ed91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a4df35b97d896a558a60bfccd8de3885969d2037bee23b3db20f5be64b3a5feb95da076019b65685186a445bb2387aad029b9df8febc518ea7424cf67978c296ff653c785293d654070d4806db9f98a8a7d12ba7b87b8033edcbe218413db9d7641593ef6f7831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = ddec85c013cc70746f2b268d16f48db186e6367981951fe4020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fc7e542864ff5e49b6d5c762cfbf6c262d863c0df6422af9f854bb52b3a5decb8a5bb7ad242dea254b89fdd95afdef55ebcd87651a588e8caa2d65e2cad48c914ea7c7fd6dffd86341f6f935a6ae0d59d7cb3a6e4f2f3cb754c15e2c88d5ee3cedf4fa6377f4569aef4507adc9ddbdafd9e179df60c37ff24ec8a176ea573e69c057c491d1234e4f39a2f6d4f83b4dc70223539697890cc5cd935ab8fea89a0ad5e3cc1fc83bf6be1de55788f8a4351deb7233cd3fe859c3eb3ab1de50685ffa60eeacc2286f59b7511177fa3faf451509e67835ba868a621adfa10f7f703ed6b067cd36d118bef4598d77dd8010967305199e3f46cdfd4eae1565bace1c52bcc89628a84f8b84f52566917d54d718a48226b4bb2f29c0e7743fc2fc5a335fb93053c0be1f85ab09d8601b93c83399b104b8b3cd6ecb1cacf47d59016683d3dd83772eef4fde3a320470137eabded98bbc05e51c1fb9455687e66abff877aafe5d7d01395e7da932a2e386948bd15e3896d2a38214443d169b565fe8cda1d3d5fa668ad7d57987ba95a4e8a8e047a6049e59f9c94b6e896679d3f5d2298a2896b25605f9ee8be14e1ed1aecf55c893530bec9d1ad397c6776ef185487f6e40f2749af90fcc1ee6d069585d316959b2bca22f2f4adac5b54d0655c0939f3e29c865dd87fafab872af9ad82c5533c4df67d672a16581c4dd5aaeab3cdb0636c938c575d6e10965d4fe3ddb61293ae1ab3c8895b6eaa64d276e7afd8fc6821a5b1ae4830d5f6778feb9d6cbf71c58e28098925e6d7d507c9c748fcd2267c4ed7c6e442d372dd88bd5a9a50737663998934c8dd17386784867c5baceeaac66c1ac3bb1793cc02df88e54b4ea3db8603af791af157665b88b0baad75f5a805223754b3dd5c81ac211967a43d7bf635d69d0a8d58e0febbab95ca1e57d2d6583cf09f7ebbd6aa139a3da3b9bcb1dc9de93ba6c6346e76a88a9fef88deb68336d3b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = f839cd5b3685e864c874197e1cfd74d30c41c0fdefb92d85c8f5c43a26343aaa9185ad95beeb6e01753dc7da74830fea9dd798d17660c5ccbad047978cfda62d3b9ddce9f48709e1400dadc8fc9ca566a9331790bf93a1599cb3dbbff9f5ba8d2e33a8c755e131ee7c9d4c91ba2cb187495c9a9a99178dde4f8551a4f8793a6c7e863f7012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8c5efef84db0abb7ef3bbc8dd0d59a08eeb47a4c858798a76494ed60de896c43688339db7d4dd06cc7d205b5a6ab3f78f66ecfda647f8a6eda7966efd47b43375dca64d5770f5742c9e9c81356d0edfa87c2ebb9dda76d0b330891952c81c5d8486e476063b452a6503f7565e4d6fb60b56cc14a9735af97283b2601536fcea5a67d4feae9d3d22b672d58f8a94efa321fac92087ec1d038ab50d75771a9f0ee97929c691448d8579eee4c5366fd0b7abda8a7ed62ebded7bc6e34ed57988c362c5beffed6895f89b2637c2866bcbba39b15275ed5be9e2344a9b68145e2ac69adb853d0605e4e118e05f65622fef5750595a4bf983aaf45921454e71ad6ca49fa78eec70fd5685b84ad532f4aecc9ad9c2468fb2037f73fba689c8ff590891bc087cca3577259641096956916da5d5fadae35bdbe06ca8df188cc458cb002f615b1a4e0259925cc3d12105aa50b494b35a45d4e9312038866de4e31fc4578684f73e28fd7a2aebd059d76e7daeef0e6a6c1c520d2bc404eb4fb299e8f1a9d024d579185d82ea9795f16e6e585bfc7f93ab33944401c7bf7ee64040a3336ca5906e89cf4075e2539c857afd78d957a2f4c6f5f90561be79bb59244b0537a420bdf0217faa761ade34e94fa85ea49d68602d97c807b9992dd637c75f563f83e7084946713e71dc7f62f71737518c52082966f96cc386f3dbb6f89d02b93f8db8b9713580c7d6fc06963a1878ea1fa54a20d774e41cdabb98a6da6ae48377a265ddcb7067e0f307d9956be6e8fbf2755bf65235e9ba833fcd4dd0db98d30556f98c7ed451c5da247885e74fefbec37b267fa247ee81dcf97b300372725ee94337a109bff80d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 1faecd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856561ed688f75c96c5f4fd60bbfb41ce8534be1d3f6b24069c5303cbe3e6558f376b71db5e61c73e0ae75eeb0c9a8dfbafc265b85478c59a7b3519cf95176768d059de8e9af4be09bc99f6a459f9cca970daa8625bec4a7695ade57372bfabf29e30a6540f2f69821bae61da542861955ddfb729a95841845635cefd8ab5a7b865f7c0108e2a98aafaefef2ebe57cbc89c5ab65ec6645bb40b36027bdb10c4db7e645cb571b664faa9d0637da1a0f549d5d7b33a568db5ea1a84ffb53b95b92158dcad6b85e07adf614ff844ad6318b7fdaca358689e0b0ebde0add3ae55cf2b68dc33594b8546e788eeef7657f9b5409fc74dca45a973873cdd412eafd83fbe2d8d5e627c4be48955d8eb67b54fbe879479803c3d479b59c579ce75448525d5e4b9e685b3ce751b035836c2f90137d9c67acebb81db948af7ccf17f61d639315cfb1d52a77de2c9c233d761f05f64714af940ab4af7ba85d6f7a1a633a994752e05ef5ada5c86b6d709f37970d87ee970defae2b32288dc3b2fcd1fe086be777e0f51cb4690a58be99d854b7b03ecd4c6f73feb56caebc393bcd7d410375457bfe7b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa34dceb7936fc9dc0673877d0635777f8c2a9a5b03d8b731eaadfda18e87b54d37653bf44dba3f39d74995ab3be5a59e3073e52938561fa9496b3ae013eae0cbf7a7dd67424c39f250b5f9c35e2e507878438cc8b086030cc588d1cfdbdced24167715c6fe30ce969785b4210eaf6b8a6a18606597829bb40fbbec83ccdf779e3685c48828ee1c0dfe6699a9966b94590f8da0d45307c36499d0d6d37a83a47fefbb90bd812a6edb7f33d49d633a98b7a36a3b2ad64d2ca29dda1766071473fb225f9221559527afe5bc5944009cf2d57d75d0961721989f99dd307d9ee04883ceb97308ce6c03a7cc39cdcbe872382267ee32b77d5f54345ae1480b90ae2184c999aa8a1f0de79450f7e1979f67973cc3456c5424db57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = a20fec5f9753581da214345eabd39b1ffae21ca7c866a8ea23dd6c558de7d7ee6aeb14a105caf2ff6bf305fedc949cdc4a376b9e6cf426afdff94953cc93ead45b3f81056b704fed4c063f8323b0e248e3a6ad873fe7ed93f9af8059900c973328ad48803af586ff9fa08e714a869048bdcc0f07ae4a9b5d398469c993fa7dfbb79fec3fb99c5f9a2de83a5651c2077f638e7ff62c80c0f3ba5b89a19d8f80f63bd162a87cbb2c39d98445fe59d72103a6388fc09e7bc3bebbb21a0eb0827f9b7db3737a0e7454fd90e5c672a10aea5c49601735c0cdf7338e15f1ec0946ad2784eb1a5e139cf1c9cd4245dfc8e8eda43c7551505aad3d85c9d74d885eb8d04fcba8e64c9da73cdec29e97742e56278c3ad74f82bf9590935af80678df4e8aa14a9bd30519ccf3896abc085566bc5757a46736ade8c79b57c149338bcf680c249b94fbadb134be1baeedeb09add46ab710f930c5cf4eb4298c0a05a1af583059b7724d7abb680fbb678dce2fd3bfc84fd3d2a563f7ddb8ca54b0886998a449b70e256f22f7a3847f6392abf2e4a6c97e4e41c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320c4f6749cc971c6735ac769c217fee894d7998399309aea81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec335f9511de57857b664b548fdf9bf3924b50867db1b0d3cdc5e58b4f6ea8dddd54ecc9b4259ebdcaee5b859f849fdb6b236b96367eba99ff79ca3b6dc2532a58ecd24375d8faae99d955824a489176dfbeeece2c138998a14cd7529db9dcb65c6cfdaf70bf64b97bc412bc338a6c0b1873802884475636af0aaef222ccba2363c0b87355546d326ee8b2be4c33eecf9e6b874eb74bb136eeab0364246fd58ad9d561d144ad33dba798fc893d9a73c5ad3f82c5acdcd40325d7971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13edaf17c0e647ebd7c872641835e703cfb653bd7fe3b4fe92e489d334c53ba1e36d5b9794c96a8d45e946767ea84edb754b655c85a818e6ed14a15b03564b665b8ddf31f64c5ab8ec9adfbe351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = 7ebcc6700b95f778cec605e5b10c58e323ab800e39043453097deecf27d7f845db9f29cb3abf61580c3dd275ef97ef8f89ab9c1ad86cf77cb3db7aa8a06cd07d1aea94ada83e85be418a7f151d78581a5e61cf5e4564691f1eb5f26e71565ae214d8be07ce5f638e324997a98f6572adfb62612c6623d4c9cb24bcf0d896afaae6c0fdd0354a41fa8fdc54fe574f97c6e8a49886484830d582285ec6e4c94df54aba2ba767b2c3e99148bf8a0a89c72d866f1ba52c46687a03ebbc6a7b4fea9e5d6c70a567df3d6a6113674c92173b6af490306e4f1e5d8b3b456c4075f2d986c31aacc3663d98b0985ef1879b214f61bbb8e7534f5d7cd549121983ffc3db18ee81d2b8b4dc049f248b55a25b561aa5450724e914e580684395e44ff25089bd29a934cf1e4f60936d9ac5df568362fcbce1547fd791e3e8dc735253085c8c164719b6c0b426c136b3e1d704d00a0ff7fbd340ecf4f6a35f74db9f9bf6bfd6b26fdbd114c754ebfdab0b8a882cd3aa56909104dfc3e38422c3b8d5bfc77373853e67d68a69e663446b17f676bbfb941accde1afcb01d939b426a551417acc95988d81f600393d63dfc5a6bf9e7c3f4d41ea5496ab68855b6caa6d9fb463692ef2390ce79796a7e5141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e173e44d57ae91e29c66eb75f86d6baaaef320b43463c4dd000083c49a88b6338c37444ecd84cec15266fdb266e1e0933086c7358e8f770aa652b7842b2b9b6f9165613d4a27298c0126af609885d2a7e5f9cb854cf7adc308b36697cb1f5b530c86f569448725297fc70bceada8b4959c681f64c46c5ccc2b3a7fb6188909a1955d99b65b0c8daec1770f614f1cebeed792f621ab46fbbb6ecd0dc6df418f60a1d5839e8dba95dc0a844fbe5b7dd999386167ca06a485368276b4f7340cecda9b41edc3fc3726eaead68043c1665b1aa54e3231455078cc898d938d2c5663b2cf00fc87a3b3cfb5c6bdc508ceb801fba711680951ac8ad9c7e430345f2f6ad3eb9317b044103b8fbb03949ebff88b2377b6606fa268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = 1a986b26bf4c36a66d747b761cbfc2a0a4e5fed46551c6a26ac6f819aa605a84c9d164b5146c6996f3a33475aa77dd55ffb45618ff56e33df8426b71ea24d4cecc96ab8e5f5cd8d4d83bba5e4e7caf64731906b8cdfcbfbadade7e0c924dde9475a88668c59f24b7b0aee4a63b936942caf63bf4533edf9e805e760ba638702ccf657f305e6add404732e1bff0b269afff8eedb0a8c2dc1ec2573b7c3a83b673d37ecd8a725553be79755b803cb866b9de12a4bf7e8f75fc7ca07defdced0ac9a45c54964ff0d5caa8210bcb3e53f89cad3c6c3a982b6bfd4b73853b1b7548f7aaccbda4ec2bc676c55dd594aaf73dceeee7a58f076349ad9fbb5b335c43535be99d562f98adbebffc3dc9aefec5fe3fe41787489823fc00b83cb367bd79f734fa1c56cb63a8652ca5a23ff6971e31b25de8139937c20c82ae6964e0f4bf0603ddac7382bf2341839f36ef37e19663c1bb34819db7fcf71b3fb00e460baaf0440947452b52ca4bb9c4eb9cefb8c1a308b2ddcfddd98f70bd7eb9e96afc973d6ca17c769e4dee021fe775238fdd6f35f89939b47774b5fb5294dfcf4875a698d33827faf146b4c3aad66f2d9e8d9e638874dcc884af399df38120b8baeb9a52b45c6d0dbfa3c766336d0ba7fbe55ca5fbf03e26337d2943874ebfb4af9d516dd947064e65f7319854b6757bfe40c75b755ab983c5fe72f9c5cb293e2aa34cf3bf3ef9868278c531bf395434fb347f29c079395f7006f442fccbe37cc7fd4ba1eb49699ee3ddfec751168dd3f8bc43848e813d0c555183524ba8a248f5314a6fe0a6947ed6963da96c85af7bcb1fe8e61a07c7080e9b67f373c479fc27279e67b677c2c4cd42b33c476fb012ba8a5abe9392cf5aa8468143a5e19d65b585c39e738359a24bb0d32bf66b8e471def5271dd715cbcec474ce0280d39489aaa70b5cf093ac930b9ee9ba356d6a76fbbe890388e924487ca4cea7a67558e561eecce4e90c6bcdd874f35754e545b477e0538b3133db07b17595e55340ab681fe96db21b9b8944d865609f1e8a5599fe94dea1b8ddc7a6ead6ecc0467f99c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = b024ec2b68b888e674a38351470a3c8329f3aa3c3e41bfe27a28c1a98e8d42e4a48c03619178ebcfa8fc0f13a79d643af10ae4ec3f444d1577e1ce795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755b8e99ec36c2c128c68fa5b5854348d56ae798054ab98a5203dcbcc62fe301be5026c8b4d1aa329c8d4b13f6efaaf672f0b3d4dc8fcb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b1531e950b5551f18ffa9b6a7ec554567b2c975af35b6b98d41d0ea1f28fa50853998cc395c118ee0d755d0fbcaf69f85df21567a1af447467ed2f98ba93f37a0f5941fc9fd4b0933cf3dbf0a706a06359cbba37fc0df686483e8774939d195f8b8818ae682743071795d61fb29c794cc8a6c0e4c8f7c1148ebe3ade72fc50a307eef0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58ddff9da6f3983564da34cb71b7f9abdccc3d07dbcd8efdaec8fc9d306464e23fa6b9989c866ed918f4f6796420e8b8c09adbb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943182be6f747b7d04a7f6996983c494b0e5f7879366c3a4a6872a79c8c3aaa140ee795d36065d7843acbb04014539a9fad37adf4f56636166990c23c661f34a585defba07ae6aa68fc898de5cf96b293757a041b53ec695cb62d960d959d96f57bd6da44e51df4f6ed4a3a135a202efecdd57ffe459bb22c84008d5a2ee831823b42113de7f14a71b23f9bdecd7ef7cbd2e8ba40bfc64362bc369e59d675dc68aacdb54b9eb43386cc7a58d0c906e02a66f2549d4c729f4fc7b9f57b94aa9f78c6853a85d09ab7b18ed1b593d94254f0c754d76c446e7e873c67d67a40cc3993d48c1b8e495e54a5fc2fd0d4a7d80c0fec343eee919730dae7ec2a1a75ddc983853cab3cb55a3fecdd778bccb2d4f0370989573d789a1f3f7c5b7cbd0ed8fe1788e55c67fa65968f57bd85b53a2a0d5c6a3cfc30ecccbf099042183910ce7f4b07aa2d45de9953705da8bec6c4d48e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = 30afcee53ab17754381f14708ccbbd3a19ca2017a1638bd8f2e9344ef76d60ddad938bd27ae58787045b9db9dacd27fd2addff2ea83b378690d6e694eebc39dfbbb12e13331503bccfb6fb6058792c2642b365a9fc6876614647693fea80e5f9dfd9abcb15813a4a6aa12fd10ec6a0094e9a6d8f38f068671edeb3bb4be0bb0f3aeb0ea90513518d5c65833f9ae44cd7a79f9c3dee740aabc291e440f909362c7c8651a64e0eb84d82448e943935175d3182a3d10e7e8e886fc71dbb6cd0385c5cedc37709924bac6b6783c8253e527996523ecc9bb56fa1efbdcb6276c344eac257bb4c4bcde24d7beb7cf7473c15de9cb9762e856786bbeb5a9bcf69fc90318b3353ed481abbeb97279c088b397c4e9cc4cba75655ee686f8f535642b3ddcf71644e6a3b6f9b64d9fbfbf84356812e6e3ed338cc28babcdd4b6753f4bce7a7c54b077a5f26fe96665a3299b938ca48ac0ccc781dbea5384fc4948dc1b56a1d7f72bc4a3fdf53706dfcf385db3767d4f61e98c49164683cfb420c33cf7ed68cffea4f43f4eda5ac727e87a981877e500ef429f9eece5f4791ceab38784d89258562bcb5841ba8f1fe7ab27f36634a7019b5f0f48695ede951ff9d42eba78e048791896844025a37576bfbe71d635ad358d0ac7ea3bb93ca4c8dbf6b566e0d654f1541919650c4a88c9a19b4444a5cc7fb4ff0875530eea289ae5bb0a4ef71f4568ad3bd02ce99121dbd2f755a9c88d600bed5803733e2e639e2ead5b3fc71dd7a42e844e90e4872852fe5455bf94b03fb49cd96d4476609e792a4e5465d5750aaea38d9eaba07fbb05e1d950def32577f7850d97e16397e9376674c37be4ff3e87c2842c797ace9475b1c4fc10a2df70e9e7ab6cc42a573c51339c04c56a6b025d868a9a3317fdd886a5e2113f48043b44f0d5a7344742ffab698fd86526691b073aa719e4b391c3cc31a83008fa11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb083f3c74a7892e5b3ed73e370a65cfd5bea431f348e54506648ccf083fa36c9b9cab979ac6c4c16b9ad0138860a49fbf494900698d7fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 8539e17dcb33b8df46d22fab27cb961b63bbc579c27f644213e6825baea0d4b44918784e1954b46a0ed7d6464da8db4de1eb8cac3e317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f6ae4446f9def269cf7b98235569c1b396fa9164e2e0336cc8babaebe60b18fba8eebf09b4f6b25c435c36cdbcabe5af0d541d0ea5514ea354c8f8eb387fba1bbec81768a1e286ce3bded1cadddd1ea9fc6d685f1095efd1d5b7167eae967bd9faad20297f9bbcb53c6a74b37a5def023b33434ed2555845e98fde3636cdfd45a77fef65f6937141de6f9ee710b748959a8add626cb79b65de177c06cafcd8dd759d86baf1d9b85f4da3b2eb9d49ef9545c7fcc0a6a736d5581c58aed7d966f88c578daf6d43839fcb3bcf6909baac0ec8d7457ed511bc7e928b67913c17e4cc26818b2f41ef99da3910458be4bab41d3137caf0e89225890af9ea364dbb683288b8d59b6619bb786dcc98b5e910fac5c66ed5b3c75a4185b99e00acf009535aecd7c269aabec98adb1195ab0b5a623d448fa454e91cfa6bf9f5aca1fb086c3e616337662dda6eb7e54e937a39d1a60a4b7923f5bfe88438386ec879196cc47e9e79d48f546168a36865247fd7b86e48f3629c5b1bb99c72d98d90dcf2654acc6fb8058df5cd2d48c2cc7eef0f9e7c01d6f99b35df193dd632f6a208ff0be7ceafc2f9982067439934bd27b56171ac3ceed9e2c1b3dcbead8c38635603f8dcaede827faf71a43651bba49a5a66f01966cca037fd00faa074a7059d69de85961ca2fde6d89349ada3af4e4e175b6f67aacc9637b8cf4e5e3a8f6b3ebcc931acf5064b337c0f9da88193e79a9810d2ba9b0fbd89e437f473b9f5dc4b8eb95b24e1b85c6edf67da39bdf35831d1f63ff9f3a2dc7bd54b5f10e48f0352fa6ddf3dff9c59325d36e99973e3ea9eb4284c06f673751bbc8c9abd4c4a9d610ecf907bf7369c7f187bafa1389ecdcd47bfb37a19e149a32f8cadd638ac1ed71771c9dfc68f53a864c0e15cca615e4f545cbe27ed30a08d7872ca2d0c67f55ed4b4ca55f41a54b1df4d5a22ba276aeb919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 27ecdb5977446a9af769da6dfa5aa673be6fb8b63a7a6e43391eb6f0a973935587f60c8bb793f6448a89bb39ea33fe40638fc3f887fa4e2b43ed9fd9ff9d7d1ddc8d47584a822b6684da85a4c549074fda9179e18b1c6eaa058dd3233f14affe249932f65ac9f3a3f253c4c1e5ac9595d5a10ca6cff044d3b74ece7935fea2b999366cfc8af6fb4f369c45eace0d45f55dd4703d06ae070ffd25c5dd3137f6e6165a968587a206a7ff789c41fea195076dd344df0dd8c6b3049be77bf168ba6aced5cb7955e6432585bc5a5debfd9bc5eb3306f7633d8fbdac28bc27dce9254ef462e48e70bd87d3a6b61a5af1e1a8917fe4b2c1ce3571df6e893da0e29f3e649a756b6fe6844a368e0ada6d65a2c4d3e0308d841b5fe1970d70e1ccbe6538be5c7cc09469c76a47d89a163aeefba6d44dcc18ca86599a7eae767ffea3940389f853834424afdf2f0f6e2bcb6a40167e1ff5d4df89d8d1bb7fc8c36a68dbbd30f6e1742bb9ac65334ed34dab7a825824ee0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e37d75c73339d38b4441c7a4ec79e1e6a60c897f9a26b8a94739c3c8d71427e3651afdd6be7c62865ecb3169b3df6fafbb7463244d0411b403ace6bdd4c7ebfbd39db0cb8e4deaf2057de5a6be54b7d40fa75df69dccbfd54e19e4371d52782287d557158573943683c3fa80eb5d241eabc322862cdd9924b0d443813b6ef4a7b94fac2ba88542b4454ee27b54eebd90bb688e7fbea3fbbf2a12ad65bbb52a76d69afdecdc3e78d36848a1f8b6bd26ed8a3846bfe14a51d89382d8332bc4eef0b79d9efde9d4328fea5044db4d43ef3b9e73dcc669fe5a8a36abd300378d644f863dbfe9b4651aa8689991557e9636c92c87cef06848e6ddf2a3cb85c665f83e64eb54abadd777e11af3fbcbe818eac65d928b1f71d851fb7433e255efe666daeecee52f3fa9f2aed9aa4398253a6458d6073734c3954ed521f40798ba315599dad7fcdaa9f5e5a9ad183867cd54fbee54b7a441f53e9caf1f2098bb545df6e048f19b5ed90e7cfc408bb040859bbf59d80f8cb280f798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = be4e3efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816fbddbb5adf533fb0c4b4ce980984422f7f25ab91ec97319ff68a9179e0fd0ca1d62d9c352d508b64acec55d140165620d9bf8c8e70ae3f8286e49fb049386668e799865130cd7d47d49a1aa5bef5a4beb499a007065a7aee64a27e3805ced8aa5d72ec9c6a1be395bafbd9fd9a8e0a749049f4d5137a5c05d8d715f9b3013fe83debe27ccbeba7556303dfb1063b798dfe64f1fdbd41bfd2c13785009bad8769c3155b643f8ae9fa5d9987ccfbcc04eb3baceb9a844fcc537d8a9af8cded641b16a0fd49969e0fd61a6b36b5b58742adcfd49868bd136cbb4763a97660694539a30f5649a7884a64761b1d59cda78e07c5abeb297c9f6e407bfdd606cca7d27cdda8436c4343aa216c6b71375e4caadecfda7698ee49b73cd25696aba096f51826435c79c742058b644b7466b857cb5792c539709a59ab15baf96acc5bf5e3dbce9bdb11b56d578837fa2fa75249f7b9fd323bf79ce8c372c8655083adeff173de0d27baf8acadaf284742e73ff575da3cb8dc47586a1d1664128a4518e83a0e5be3352b4ce5838cde93826f0ba92ce6d27d0869bb5342ac2ce1dbdd938c5ab3a836a646e37cc2e4fd3aa3f4ff0282a4d38fd9055bcab7e5e8da77d08434f535465c9b880506831b43e74b974d41e680000b5ba3835b457768b3936d391d557f7f407d9a95321e990c84e1040af53baffda8bd3d66dfb41438449cbd975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba3927779745fd24fbf625645996befc2e69a6305feb521ff5002fb817878aa013ed107da68433b422a7360f69abce2bac840b57afeaf144aa62959d93f643a5ce2d9486b6cecfbff6d205ab14e76c17cc86346bdd119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b64f0ecce9de137c2b4e55b749399c5386af097d250e8534393f1ee767012483d8b56d23945dc82f8700e3568dbf453fa275d607efec8fc6b6e37854f8e31870862f8046881185c3903440008c4b3464cf43b6f5b8da47c473a698de37924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = c7c3b4466bdefdac63724548ff25b73baadba6c5d04c8fa6159e8e645dd146f36aac6dc8cdc5e6000ae318e9c3d629e68d1ca7d2bf9a20b995dc2540811d8bde2836a54cd5aae73f95d4997eedd2c21c9e178eeddf36d3a845a5ad95e8a3d3cadfb57a5a994cfa36fd52fd6d3d1c857de85cdc934be0feab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4d3e58a99482b86eeccd188b5ae4f627a49240257b5b05d1e48fa577dc57fd84af4983eb6a59f24815a43d2c6bcdfd3ed2fd937a9e8c882cbc5fe33303cc37622cf1d9e5360b3c4029ccfc9f68dc2519591f6ca703283f93e759dfeacfc74ed1f6a9bcdc3d839c1f88334562b608b32e3ee111a79c8c2c4b19b8f2d186461a0d51c66cda42ea51c10d9ac976a06c4b3c24fceb48dee7875f87b836738473af08ff908935b5c0dbca76c44e48f5478f78aeac1388868fee40b8ab85cfbf8c69c3d4ecad4efdca07e89a6a245bdc56e05eefea9858a81a4edcfb239fa745e86407a88105b3bf156f95f87d9b3b9db0da6bd77d75c70384554bf8ca89ac923e561b9c8d37a5aef7b4e52f6aa0a7f54af2f3819d6ccf8a07d0f4c531090740312da01e4bb94d4c7bd257ca0944a6aff6cfe00c9182e5d8ff329505c3cf8539d428afc06366907b3bf92afbfb13b954f32ee17504a18f47d2596dceada7e7869c60fdea3e31e9845d439989839bbd7ab2223be3fbafe1349d6868e6671659b18a2cdf62d8bbb7b69b0ec6f967b85b21375742757ddba6dcbfe450b9b4e5fd083aed8ac0cb05a3732b39463e80c97ba6ce5c42649f545e2b6d15683300ed697faabf22af423409ba37a899c70fb72a5a4ca1e3a7c54f3c5cdc3766dd97302fcb9386bb3486e7720c6cf9f3f964faadd4b6f5a158698567ed40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041c8f47abf3f18e5ea780ed96098c3aadf646fea3b822994ef83db97569d05aba38f98d909fbc4428e5851edbeeb1f403e1df4d95c6c179e584c6b548f0d68ca7c7333ea8d080efc615433da3ad4167fa46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 830cf80144eac14fba3987b2551e406c3fa001befe0007f7799b88f32e9ab42bc6d08b3396bb77e51a38808b5a018f3d45fa46dc24f077ac63dd25b520abdb36cda3bcd3d537248f579de8f23f41424d4c3b6d3f8bfb30f675710b33b1f986b78475a2d5bea6c44b6277b881c8f69c7198657ecfefb0a9887afc4c3b0fe3d185ea1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6db9d6e98630bb7eeeba0b5d622670b43e52c3e9e311cab5fc15fc016dd97d0c9bf0a4729a58b216c9f5380fea48c865e58ef76918b71203756aad79601beeb71ec8d14f4f8903404b9338d4ca368c0a42df6a9b6be6692caf4232c68a83cff076c7fc5b7eb5ce6d3f52493beda57f12c660f34ea6b87fbcf007819adcd94e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b34feff33c5263685afe47dfda38a835dcc5426de4d2fbbcf9765fceceb34a94faa088d4927a6d92fece556576ae682e50bf861035981b442246ced124f85cb2db3af733c2d3a8121998bbf87734479505644b5694de244f3ebbdbac05b8c5d942fe668ec64090f87ea074f033f3a924f5c746f428c9637e61bae87dd3238c9633618ea86198e103ec17a945e51ee5635ef3100c6499cfeb58a48813bfbc7ceb3322274329376f6723fa972553c6eae9e13898b89277a33836371084a5297bae0298288fa68a286d5a61bf7473de11d376228de57d076e81714ccfe4fa3d33882335565faadbabe7e54c60eff682e5567676193ea837fae88dffe43e98c7721dc539914c679ee876d334fb9a6f7b84861629da9f547e251593381bc933bc47c1e5ba50429b1c07eae7d1eab43273cde9538fe9bf1b41dc8da5a68d88f8c6086ef2178405ab96cc4de79e75837f7c69c0a9dc75dccf7190d3862448eb4bd3e6abb535ad733f68de699d543ff893003b3674ce997e0c6ab8b8bfbb834c4a447d68d9f71f56cffa3abb4608cc88128b13fbe7a2f45a7ea9b85fd3ca8cc7dbd8c0578f7963ac76c3d39a44f2b87b1fecf4f15e3ff2b38831d55722aea8642a7ccde0fd21f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = 8b4961a03e8f110f5f45eb7f64de875e49a296fbeef5586a9ddac4a59bc96dcdee0af7655b15ff9a08b862fd573b8a642963e5b76c3b0a13cadfa47e02d6e8262f6d3fdcf5202a862f5d9d0ed99522bec46d7d64de93dcf70497c934c7811733e9d7dec39e6075ea425d4add03faf72bdbdf294aa32f1541df2bbcab35ee9173701d8cc6790d9f0323677c3bd709af46408b4f37e95c1713e1bb15787eabd35ffb823db6cd02e4421f3690644cbd4b4e3bc7e696d759ea6ee4d1819ea9be9be49ad93c49f6424d2e8803c7fc146cab982eab22c347797d90da0e6199e65941ee9d6a0f324d13856169fa0a0e700dc54058a6ab298b3d62453865bcf9bd8e5e6568ff9b8bb6b5e44c133e6de7169f4988c86f953a61b3e3e5af734fdcf4afd6df6e2f491e97bc688c528ae661ca9f3d587bb11e6efc835a9fbc3e4c3a1d9c3dbfe66137d84d38f97a3d4265d8a78ef343bee9baa7038b9dc951730dc4a049613c936f80a8fefb6ea3c1fe8edfcca724a43c79fcff03b99b656941d5dcd40cad7c8d2668086aee1d7a8e9448767f3fc86315410f69db03b993f6dfe665a7339db6386f9f3f7c5d809e5f8773cf76616e5acd53a9763d85e7b9c025b76b9535e8b6ceea778a88045daad72bfdf336d633a5702518d5b5bdc8897f68f1a572c86469e4a75194e5da6e89bd4b2a6d4d09698b98ddff136def6bd3e677f6ddff6fd5aeebf46dfea41bdce72cf588b6fdd378447c5477df8e9baf0795145dd1be1f50aed3ef3aaf5c98c59938d97390b3d9adedbde67b3d13cb46e89b3d7f8369fd539b649e64fa8f5900b36895bcc60fb98bc1af8110f3a7b04d70c6d7fd630969474f3ef59f69176a529b5792e5feddeca9405659d6a29ca1b6e953533ed9937e8248e664a75f63a235b17293b6f4b45836166cc56eab0409f0d9e7ca24a891e45cfdf9684b85a5845e0af1047d9b07a596f36aaf9224ceb70c98badbd6d1aebe3b0a926d9c537233d9805fda0c2aedcf46dd88dd825b4e7382d4df297a989a7bb827ba5eca46395e4351afcd94214d5e9b9e9f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 5684bc32ba5b14f6999a9c794f0c6af058d3fa57cd54278313e99327d579b217682b1b86dd0f431c6aa12516f367798f2c8beee709d8dff4f736cac925de69351853f15b944578c5543aa27c6f6ffe7b3115bee805d8a3fd464ec46b912ab89a3effa561855fbcb3820f5ce1fa7b5e3727612e685830f3aea6c9881bcbd6ecbed2e3f53e6ed5d2a4ec98faceaf0d564df79c8d7d4d3c4843cd6d0573210dc6eefbe7caf7d32fdcbc275949a9dd501bee82cad756808cace516b72696c618c3e9f576e5c0dd472c76a5b3b4b6b257ee1965d25139c5806cd95867be34657c5af333ca2eeb01da84198a8d33655a37f6aa3f35b7e6f34b1e3be58987ccaf3fe98af6d5a9a86fb3985f199f92786ae4fe2a4de9ef45a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578c3ef60625b7ba7339057a94435966e03d33c647beaac74bc80e4b01dc539445c77509bd481c525b2f6dd44966feb66684644f598c9493346c917eb16576978f477ea07862873e91e038d5fe4c54f415374acff2a10eaf7396a2324d54559fd3bfe66080dcdec96cfb872f3ed946f68ff4e8486a58afdb9fe8dacc4a4f7597f4e98ac4c8dd747aa56cc22e38c7f24d988ee37dfcbf51762868915b6ac205a006846d74e8734aa3d211a4ec4e67f1ff38e5526d5866ebdf6bfbbc9fcb649b55f49ba6e0e647c827cb983e6ea6c9f7e7216e35e40780f99495aa3c9c6c6e9e47c4d521db992e63f9c4d3c89444fe2bbf808c73dd986eab144e6c550af01fefb7c918bf7893fb23bc4561f6cade14ef4233d67ebe8033eca02d24381123fc5d98acb27fbd825660e18dd7125b7428f7403cdfc1a06ff589efd41326f253a95f3e54738ae8694b7a5bd13c7b0b4eada087a8cac7fb6927b3ac6e4cd7bdda01ef545fc7ce548aff3c4fdb982ee67b694c75ea6494047a8b7cd7df344dfa099482e3f2fed5792d25d7b90e424b05e0de2d88c1fe8a9b03ebf0af39fab5dc01c8866d0389eca7a521cb9028f94aab585842ddf1e0ed4a008a8d12df3d545ed5aafb41355da2ebe6918ebbde641bac2e1ddd7fbbdad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = 9a3aa452bbcdc93ee1a6eaa59b04ba8a78bb9474659cc944e7a8837818e5b899cc652e9dfc583f0cf4e03fbd4ea7f6de2d6f7a92bf8a32843cb3a5d21ec5440063f6f12b53144ccea0096d8b186fba2ccbb9f4e97a43406ffcd9f53abac10f45ce2af3989dca6234d1e02d4a90b4a438d33391dbb10deeaed56456f4238af548881d188f0976887eeb672cd9e078474cc3cf89de2459513ba16458aa60fd6ea2746d4293b7eca5d78d9346d0197dc9a93b2c153abbdec62758cc2f57544f37cc9597691047acfdfedbe1246fa52bd56ab87f24c38a0fe368143e61927efe9cd7a26b745f4d5ea1a164422b55d2b083e85a93725bdb606ad6850ca5a27f8cfe810faa70a5e7793f325153d9b4cf80445cd7075ff653be70022ef2e0ca821c6ee7e63dce0738f873ecaa7d85e689657aefd5575a7ccb665e5e1dbb647d3eb1f857812035faceca821efd416c6780b9f9988ab68c72c73538daf1687cb4654667d3e9bf8a0bc6273d53766c8180c8d79aa8c975d867b36b45bc7d9436265ffb15f4a1be43095351c90541f8437e757ad28bf9f91044edb30b8a9439dcf109d52b6bbc9a5eeb72176e7c5a830cef569b695e40e63122e574e17ef78a35c607ac8d491b60bd96917e9ee54eaaf44eede4ee85ce9b0691c22cd8cf2b7144cfeebb07e512b873828a66286cb2b50eed73954aa65be717769573aab29de4cece37ecfc549f7f26aeb28360d239f6cd16cb68fd798a2cea0307d7cb3b37ea35db76beb881c36c8656e59739f5625d3e6f44d5b19a3fc3a8c229e5eb6a5391964a4c05db926ffe340135de4b8f35f8ab4fc3039f61446f38cec3fc0eb626f7f5c8d5d31ecee0940e7a0bb5905fca5a282ec35befe00b4e567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a385ebbfa83e7237329a9ce18b7b7afa8e6e0a2f661869a2e68c7deec835469e5cb11570a4737542ec9ab62f46e7b58c0d08e3e277ff86ab92c798f57f69a0f62b8f7757489a28fde806f7a4b9eaad9ad6fa0e3a9caf8d3eb6617b2ec9070cc65e3551dffbb66ea449222ce7efebc429c489ff1d7bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = cb0842b9cfe3052794e18787eff9d2d94c88c0986acffc72dac4505e4c36cc7b4990353e25aee2a835ee887aafa1ccc9c627948179a747b5cde4bd409e5e58230b56ddc86cefabf41c044fb3e5f3fc9d9ce0065e260879690bcdf70c33c253d3f91e43624446fba3774808f1cdd97e50d7a3bfcd58c404c458294eb91f908dd87e4d75fd528f4518c3e85425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444413cfda802c399bb56f461aa76326d3b86ce8a9bb7c83f6c825b9a421e59718b43d745c366788ef81abf01415ebd51758524bac2dd9e76cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3556be950de9907289bdd869ef5994be80afdd25a4dbafae4226cb6907aa5ec878ca37ea698c84819c6fc2e24ee5de0ac334169f310774304fa9b039e2b74c39cc05e91ec5c0686c785e246c434e43f5363900c7c22d05d6d23d8f8493e0904ed03b1f6401a5de2afca878443722c3d246344ec239dfffa542d6598f14f8d3f9e9ee5d15d5410afd52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b559e14aef5747ef62193965815570b9d353eb1ac9ea9875323a33fa4878b16d54e3867ad9b3d2b6a43ffa0f453b9f517d7d55b236ec7fad4f406d51c16aa728ce69c52ea0bddd36b2eac82adc3efde4bc2848e589f36806189b780c327bf4b4baceedbe036557cc38898557a8a48693fa70984aad337d78c1f851ef44d9ce0348c27fd2386cf2a71adc0d54a7e727c0fd38684599ddf7687a6f75f32b3f7d8b778eaf6af9f43787646c8eadcada1a9b5c2a6473252aa6f12954bac4e0e4aa4108b48f618ba595159ea8737c797dce4b0791706ac8722eeb3907ec0a394d058fc5d61c4d4d5b3ad0f593610f477763774dcfa06e7681d616b12ccbe8caed681eb66a735ef3eafa52f64bf7758f9a373ac8211ca3a9369f129bfc810496c8a9b32d18e3c0cfced19d4cf0ccf4222b96ac4897a7f4686b6bf11888db6574d6d05ff94589d36dc995c52d89648b63504b756c8f3d22c54d2fd7428bdcaf751e3d6345c1ec5d5b853f91a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 595aab2d69e7eee9401f2bf3be84c1e1843126763b2d98c83094610e55545e5478f735ed8338fd889cbbc40cfbe8feee13874a1cac92000949f82b43ed5e6dea6ddf51469975f5b6d5a35de71dfe1aa68f84879ad70f4b8e9e3096e381e57776b8ebb2f06dee6a3464f383de669af2fd9ff4764a3810aac4c52e3e958451614e437bfae9214fed4e53aeb3336dd677579f84362265a6919d464d053447684ad3a6eae01d605d28ac5e0e93c2f59c5304b14db3f8ec44cf51e83992fc6f6948de694679557be4add480144fcce20a8658b988478f7fb2f440ef3ed61253c3207c9cc8a6eca37c4b3dacdce74b36c176643e8ac5fc053a773fe58e8aa1ae36824a5c6a71bd7dcae4846f283220dfbd693ff93ff4c446654f5837856fb98be568405b9fff36fb61040ead307df7ce1391a8ccdc4fd964b7c8d7b3fc5b684aad79495f78f980524a808419c13cbe437596621d89cad5475fde6887b973ae08f4a9277cf600489d0d773bd19bdbac4de6111c3ae27f574204f5d42ee5be336a5e5b9c312dbd7a4b5cb587c593ebcf61a8ee3cc6b4b19baa878d92ef7e812a6791a7fdf077c48ee43861218dda064f90e0c6b792857659bcd1d715b663a3cbf163d976cab2ad5b54e6463168085ad60c3713b4e722887e83c4d6cd67a7ab7759709fd013fc7dee7c5c87e776c3976706c3d13dd45395653fc4b4ff0ce85dd9d49c9f299e3858ddc184f3493d6a51d79d6f8a4285c580ad7b66ce5348e44461f0fe3ddb4aab80f84948f94c857cd3188746bef5c8479c9c9deed92607822ec8fc2679966b17c093643e46df8bcfc4f4239abc55b5fa9209bdc3e7d0432d4e6ace92623f588a6759ec3776e8794483a6b2f853e9c23f508d8d4112865a3a7c804b4962953e4de47a8c03b7efbbebbcdaef8e554ec655cd4cbda9b7345a73dc1da46238deb727c2ed3e931d69fd333378a7df61aad3a90ebb4d1b23b92d7779a0ab56e9ddba87aa5413a34c8a18cb1406a8696837d7f547acf97133bde5f5a76088ff92b80835e32a46d35daeae45999fff669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = 14938a88ea6a5678c232e9542b4fbdd4664fcafbe0c9b8b9c98c7a03b8fe25ead9a234936167df46038b3a1fd31128311f04c50824ae875feabb346bdeec824a085f46b5ed86f5843d3e9da757d190d572668384c56e49b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85b08f3110b942f3d9d03674d78e49e19a8cfff7f9987ed6c14f87bab87f0369d8096d7382488a7e55db516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd44e46f4eb81145df8fd9a86c1e3dce4735bb149eb4e8c04735bdedd8e19ef7a5f6abcd94f55acc7f76bb3b6000b9a8294ef0992db89d25946b59a888285e20ce904d5cefd0f39625fcfd0146d768f57158a5ae7b2e93244bd09297702e2fee52237b4cf8cfe794560f37dfa985c94aefc4ed748f2016e59d4879492b4f8a14b8d90c9e541bef993a52377d4cc584da159d4620bf3f364d766d249395ae44fc434a227bd4a38c755df3fdc6dbacb80e7718ace0d8e43e49649840083a948e7342e4f94f1ca04f9a9ac52846f388bcd784477d64d5a6f36c9774bc819d9bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b876503e63a597910c9aa74fac696b0cafd657882004805d36a726ecba0327ec7af4ee69dd8e67cb7780d7ca1356521386e3b3dc58b4176eb8ecc9d0c7ec5098679d1bfa9e7d58c71cc0d64c7a22f37c64af9c500d7d8e6fbd8e245069bac1f2d980c075e591e5a4477bc03b47488d08825d44892568d0949fc0edfac55a2c8fc84ad1587e92d1ecf7efc76b281d4e61f34cabe9d0785cefeff7e25ecfed15a6a4fde7780aaaf2a0c5fbd6a8b7f32fd266f94730defa03de7c5ec6938ae4e6201bc2fee6d94cce7e8618f659863f5bbd7c08efdab6c9b1541fa445fd482f6af4f3a96230875ac22fecde23dd6f3fe341d78a31adfff14ee2304dc6032661f56b605135464195f36b9ea8e26eaa0bfa7a59bac682ba31b513dbfb178cc33cb877796ce20a6e873c921b3cf6e63349dfc668f2d35510eda914178c9845b23af95b52f86576d7ea242f3f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = 811637e2faaad05e518cde668fcb964116b7732c71d75e5f52bda455dd359384a2ef7c5fd7ea6b4745dc68fca28d6c35219a359e273fb5489e905fd0f94dd36c8c6046fb726939d68634efc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b212ebbb207832f8be7d187a749eca9cd8aad20adc2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956f9fec0bc6f3f033c0b926303d77cf8d2f84658d59c9b73afd3f6b0ce96bc829dd41d849a9a7afd719e5288d4812b9e4adb475b1149f090642f1c8c98d6453cd63ecad4b886efe797509ec3aeacc23358b13b54e40d8856058bad29d88371c7d8d896b2ac4c8f3443b95099001af37d89eba0853a6c0f8f1b15e472bcbea95c7a4815f9683a7978383d8203daf1a7a6c713557c39bdbcabf81a72fc68d89e2bee99ad7debd551e82efc3bef26d358c067a3363b6e03a5db54dbf6defcd8ddd9c03985a5dc44ad82e9c41b860eb2a8b6c0f5da63978d014ed933ea4ffb28fe6a6cf918bc6fd59aa708f60c373b645789b9e0ba4798b4b7d8b468f5fb2ab2d496ba9cba5efae6dfd69c86b652fb7f04e7e7a6248f9218c4b298d35b65ec6f614805257516276531a6cc9b636db50576e149acd9fd4b324ba5a89ab60cbdb682a85aea46f30eef9f15e54faa22679def37947d4846fc7ad5ea3626cacf0d94378834a4f087ad5bc9cf52e2fadcfd47ab0d63c886947adf8f82f48d730fa7b827374e617582a8affd4bbbe56ab7031b5e871988ac833e81966b6bae54e93fc63d2463cc4ced3b745b367c7dbd31fb79363b2669ba062c75da40fd47c17a29038eabc4952de74efeb84dc1dff829f1b3ae798c3a128b76f57e1121597dbb5755a2964bf886f1208cdde7db759797349e4a8c0ad779da984f53e95b6ccf4338ca7a57e4458068b0193c6556c471ec758626887968fb64d26383a9489a605f6c923a9e553627c365bdc03fb415845251d357a5f479d84306c3abab55792bc1466beb85bd99e7722289534c74559887b0e8f50309562911ada693bdda73439d5e87007a4b0c2ebcf3d1f43949756570cd8b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 1ee3723f94a99b7abe01cb641d6def85639836a8d4ab87a2ea7e91f6d9e8367c653ed9a2a2559a73db3f04a4ab06ee924d3a9af749f289a894057782af7e39b1f8fbb33af28bc7bca367af5a5e9e5ff9319aa987356c97ac7f4b9169302e1bf9253d7a46839a497fa57c0dad4f8b30265b5d6a3c95b32cf48eae514f0af6d908915635732c1a7e2c938c4f5f8184faffacc556eaec717193ea000f3da5acca8d6dd038c55eb96feb15fdf63cfaf252986c9023c405b56aa85791beaf5c73db65126967ac8669c1a7e53c24f75a574abf19dd5f5f82205ea4792383613d5cd88fdfa4ef39878635d933e5b42bf37483f216ac4eeb5650a4896b3747c7538f7407ca7046b3e5baa63d9717824c05e613639607cc752ee6de743b5f8ac54168497aae4aa3e4c8aa65b97bb043e4501b86456d8ff49aa197ccdfb427a1370dbd8395c94d534b1fa96341f8cec3cfe8c1a5745275799e93767c44b128bbb0fcf59f1899593f9e76f17dcc541949b59dbd2089d584d3b54b369ac6ffa7eb34d43165f72534889cee50f43dd19baf9b8585ccedf65ca84fe1ffd8a60f558b458fa1b0194203ce6cab1699cbb9544c3fec2cf847276d83124e6268dd65d5b8e9bc05c550bdc2406bbd4efac45119dce9dc934383e2278ac7f7b88f0b69b80b7982f7989c48ae8186df437c1689d1378d02ce4dea68b701378e62173fbbdeac05bcefa904ad1b2f895d5fb89c8cb548a4cfe168846f996db569cd262f81d62c675c298a63dea38d0e9c5c08caa986672d08e9640a90003ce2042c3cfa437887a4cb221b65b94a82d82dfd08ae6333177890fce00c2a8df22987d10e9f65e64d5dbc544fdc3a3945a3a77a750a9f38d0774e978eca16dade9c0554e0f4d1b51ef43bc75390b3b4bad591521f8f8dcf8c2e4dbbfc89b890c64ecb6582703df9137d7f977aff76463ccc8d3a945c946d38fcdde4df5916c77e268dee49dc7b8f3e5f43e3ded9bdc3acf691fe5834e44b2dbe335b1ed68955a3be7c635c7d36a975ba7fb986295c324a9e6b3997c7f1ef845d24b9b264ca4d49a698deabf3ca9ea73e3f47cdcf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = 502ad171c94c875eb920fcae8eb447da9e3047183cdb16374d9b7c6fabc86fdbbe590580605dbee9def6131e5ca16bac1326d198873b4f999e4caec052767d7d5ccfb364c12a5a6c8133f991c5e0102ecf47d5dc8566c32a0ce4f8bd3fdaafb09b8d7b198a4b2ce48d164bd39883ec142ca7f13b3f961ddfc1345ad1b5d953dd9c6fb4fba6c5e19dbed61a64a5ec5be323a5be3ecc97bc2e383f6c55965dca985c53c4e78d0d76dc6bbae1537f42e61780c52770cc3739eedfae47c676753bca088f66d565377d2aa5cf67794565eead1fc61a0a95f6a3da95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a49cde6de4c331ea591bdd43a52bfe0a00f601569764b8999bf4cc988ff5b3fca822f5771da4eab91bdd83d6676a3d743e458381cc3971bacbe8c3a4871e5ebab8da1c34462cd46ba338ba319dcaad92ba7e57e658097335a2e728f96b1f06a7b84e8a74cdb635c9d4dc7a583c4b6f08d894cab3ff65378aa258d8ef615e940ee86bd0565d2d3fff234b45e37f6d0d7c939754592baa93297c28c6462bc0945ed2d35e776b2e55f6129443c1135cf177fdce9cef8264feaefe9f010283f6a034fe86474a7ee8a62693601ede2ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a86aef69f7aa39fc98938b5bf0f8768d3df0b98bec07dec3b8773f8e2ed280a76834fb9643c4ffd3ecd02e46d2ec84b79cea4d9bace73c58c5417531547539e1e6ee7c6ccb60ffe52eca572c7738e2a872a82ef25e19f2e2cfe9bebcfb2f3ac82d68759d83a29a9de4142491404a6e51b88dd8bfea665ae4d603d53f67cb0a2a697d537f3357bb19a686527f653f183e396a78b82e7dd1fe8f1cabb936169f6d75498eadf7e1c59c7ff8558ffe38ee0f36d21af3af399067d4ad57d36927bb88b5ad836fad6cfba4e617ebdefa049b6de6cce0f5cc132f39d85391c56487c48b9197645370deea6b3b3860d6baea255e49edd7273af4cd3f637665640ffc8c18fde3a3e974d6a5aac78ace4a2c9a183f40a9dcec8e18ccf94eb4b77793c70f8ec75c5e4697a32b69e652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = f17c93d23556b946eab12a87df2ffba9264dd899f32ca7c301859aec3f611ddbd1faaba8f794aa3c0b858ad75e82c5eef707b42673f0a6a9ba4b46e6897ce4db18bcaf7de828fcaf9e895c582fd5070562208c45877780fd3ad2b3c697645ee6efe5d41057d9f764f6476bac050ababe7d8f380ad85edf661e9f41f0d3ed7b674285cad3cc34c05fb378ef68a3e7ad3a1366b8b54fe8610ec56c1ee69227ad4bc6e4dccf90e6ad85b7c9d478b5702edabc9d1f544faaf1036de836ecba58763b1085ee9db7a2969d711ffb3ffc34d500995e313e8fdd24ef6177c2673330fc558c1cab76a03dfb5aecae1ade479ae3fb4e2c59834ab79464770cb6e9e88535f85cf6e219790f24b1bcbe7c2c2de7465cef1e2df7210ee2bd2b95d9ab79f866c26c83d103aa602fe5ae181dc4a188fcabdd674129cdf889ed790d95e5d8a65933314abd79757fac624aea30ffbeec83d6a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578f9dec35b4f9e44eaf97c5d5df8a46a70556347e8d588e4bb7efabb37fc9f0fde92c2b55ecc5cb8e389b8bc5992b037d1f8fd74bd361740aa8a86c63004c99fff5d224378d1c28431f599f4b8def3165c8f613da1ba7590ed49d440d578985add03887d867a3e82b577574c398c56f21c34f6349b6bd17fbcf93e8e4b8f44bec6f93fb84b77e684677d945a33ffe53bcf4d8ff8d5fae84faafb4b46bed2a9808df569d9d791c087f3bfd5b88b45345ccd99e9ba4f40f8c469a3b4f3aeeae6de47c2d8f25cfec9c4582cdb8633a9a58d89fdfdd0c761f7d855269f16e2a3eae35e29b2b6808fce6129ddd0fbb3ad6179480bc439196d547199ba04b3a9707fd8c4caa93379f55a6f6f6a4a8da85de6ded6517a4e38c6b68d474bb7004ea76bf46de5953c62f66072dff98a36b66994e2ec785fecf377ed9c665ad5edbfb694a2c5f87dac23894e245733852da5428adb105faf613ad6eea0e9b6eddc3fa034f61eaf29b66d8751bc29cbe3ccaba83832c8d381d8be5943cfe2e73eb95e2d16aa1c7b3b7d5ea6491c379c1c6685383fd7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = 623668baa8e83cb9fc9075804d18fad3de776913fe77d5d48438e429ddd320848074ae7baddfc47ab391fb9472d395a6376b3f44aa625c36c95457cbed0d641a1cc4e248ba7b8de2904a73179a61c25f4578f739f7a5998365f76eacbcfe56ff2b8f776cdcd4decd89cd34d7f4b757758d89d10baad85a3819e5fa666d970353abdbfd8dde25e55509fc6953c0b6d5ea7cb882ec5c574d3e619d8c824d6d5102bb8d836c68f29578432c8515d9e3189b650ada84a2b5795093b5eebfa6e1be3b38fa3db60dc7bdfc8dc796c7f57a9b95cbafb97ed780eb6787d36067f89831d98590c9ed96144d7a5cdfb1c34456adfd49e39fceac427e7f3b0287d93396f8defc8a772ad55cd8bb154ed8ca7f4cbbde729b99c8fc675d007b7c38daf0b15cd4549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499171ae09ae98e53c8d7ad277dadda57a5de3f2397c167dad955f3e48d0aec5037f6c908bb283bb1b41b89e15780dcba45485ab772fe9f1f0350b64a4ff983a5e68982524cee936b9be3c38ad99fb0a20b4d4faf9184a8d65d2431e7f950bb33c68b33e67bb4693cbf586114d4788a3700aaf4823b81b95753bf09aea4a7b219cc8a9af4632d9c5e48ade5817e318faee9dfff43a30a7926fe7233098d3c594f167eabaa0744f0e44715ddc8765559cd3f7e35fabe67066af25ee27ef7e45546c89fd55a8537e2eb8c9c77bc649e847d229958e0d7a3947cc42857f9209a704aa4640f0c73dd63c6e48651f62c33f245ef5e9dbde888c3dd1e6828be6d817ea020fdfd1b4b485e9779217641f1adaf2434574e09ff181ce16f44899afa647cea8403a831ecdcc04faab8fa03f25e7ffdcb4da95decb5a843f06876d68a6b49ee588151454edb9fea35a5937a63c23cada0d8c5657d18777bbed493be652fcfcdd22a7f8017d8bfbe943ec347fac4e21927efa46b7b590d6f91ccba3b69cd7603645c9bb58438fdbfb9ad584c4ec0c692a25795112ae8719d72be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca34eca7f5dad471ddad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 8843b50fbcc8bbe4aae3f4c19439f6ddb8580ffd6adc73a7f869842b4fe1bbf36172ac69739eec887b350c5e89a376ad6e13f235cd840d0adb7dbbfcce27ee47e3945f2798380583e5efb1d5188b18bbbab2564a0a06c174c577ca2dd0e1dc3c7acea7d54c38ffd2edc0f5fe62a3c093b3dc0986aad289b0c45841253c39a2bddb918eff4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a73da00a4585f6a5ba2cdab2c16450e0a30ab06670465628d763b5b13f6000fee5306abd4886cb304a515389e3d9cc4674d39bcc8d50976eff19bb372a8c8e22ec9506ed3994b91448982bf26f7b38741a866dadcc5e01b68937673a2ed345a6fa76e11bfa0151e5eae9b4a7ab8ade1448720bfcef2ced309a6ab68cfe86725d0c0fa5ece8952d26350625f4be47a33e40cd7eb24d9cc4c7bead4a0bb9dd7df3bdd475a4313fd42cc6b75b3484b08099c208971a08ad54c8dec193cafb519e20d89579e38fb07fc6ce1bc55c21de2edfe399daedb827a4ddde8995848861a8caffed9a284c8f9de0bca22585024d4a2b5946c5395f67f9d52141a5e27fcfb75188195d7c693f8c64b4351f2bb3076d95dba5d905087bb14d878326e8e9beb5583064fad4952eaac72f3b3d79db3f668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab681fc40b933d663ca9fcb3441d6f477f4fd97a5e50c4da33c90ce4b0f4f1d23a9393a76728f55261c4ec8dac98e49cf4d927d1fe6c719d8964318655a0f9bda9eec877cd4a1c7f995105e21735b3568e62c2ef7e6aacdce0cad9547fdd6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c099ed760764817a2fed2ab55b81bcd18143724015aadd1b730c274a6fcf81ef446a8468515519b1477492e5cb87e0a6fbda2e6f9863bfb0edf5b1fddc58b7d9d30dbe9187b654fbc6f76b76093ce2315f6d051836ba68df90e368a5cfd1dccc9a3637c19799465e3685ea05ecbb7d610d88b6f08bc6179ca60734eb62e54e94f97257838acee5a9375b347da7f3466b660943da071a3ffadeacbeb4c41b06506166890064d8bf9cf92b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = aafdc2475a69f1e96c610badd664c998a5d21f497c142ee93098dc02d9c8ad8ae309085826c4e16f9a9cd94e981f766944137de5587323dccfbcaf8366f86ae7a7481c054b2dbab86823b77eecbe7e9d88a9ca882eb7aba5baf3c38fd9df4760e70b4876c7d9c0eff5b0ea9644fbac9efdedf90648a25b5fa9a4822897fec2cbaa0998d100ccf4f24e4102e9fa5b2d6399295333485f01dee1ad49c0fbeb5f4149477e56d75377967d4edfb533eb9e7fd4bc877c31d5f4bd76b5eeff3fbabd91ffa3bc2ec64424cdff6745d5d5c69dfe57fd8df62f9775852cade000d84e4237aab403f32637f766234ddb7d6fba5962e816a98586bc2a5bcdc1db80bdabe8bbc3c82e0ecb1b6736a03f741e5dca57a45c45667d5e64f8824463c8a651afd95e995a4b870d43cae74e265aaed44fd414989a346a63f1fd842e59972b9ebba625594237d5ac74f2d76d98747a85737abeb02cd0b4c9d31118ea17c6403726ca3aef7c8e4f6845fb624a956c39bbbb404a8ef5073e37078ef535b9eb68e783eba401243b02d750f5034d4a366c197994189846dbe8f712663a10adbeef5847622a904b04983c5e9955c7e7026cd1d9e5b928d4b860dbdfbff76fbcdffb486ea5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b19daed1c9478a68ce883cc9b8a6de8755485099912de5d9ea8d4e33e86a12a75b53e4ff0c784c6a73732a57ee45addd41ec9c4c1bd06a2df02b2bfdbebb65b5d7471f189faf194e642887c573e271649662f4b2368f9644198bf8e965da7f8778a65405c4417eeb7ee265d2618ccb0a1af26945adb0d73ffcdfca47a5580d18d3a56b3c3bc66e877ccf0584ee2a6debad787d8b588f98dfdc8255687ed3aa174ee22c387456088d1209c4a5475f62eefc2c6db1786f44513ad8808cd9e7c7aaa3935126ff35f8e872bc4356a21379bdb84a26be32f4449561e96bbf8776fbbec681e4f576aebfc0dac357653996e4eaac4a9341196da05c49ba84a4cea37c818ba0f14d8c8c93356174e0b1d479ca0356571e9236ea9d6979366163791658d88fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 28376c399946f6089f4eaa707377f6a20c6e2acc75ddc880fc0e5477d3ab44c36e047c4bedcba5e2d775638e54eca695261b5825ba495f84c925f73c5e86b59fdaea5369d6c2abd546134469baffaaaf73e987c50f2b5c1f0b52d79984246c653bcccab4ace72aa9da72d93ce03cfa9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f57e5b977580345b13cb945ee374a980a3153ee690469c47f93e0d02ca01dec8f1a149e6c2aea50fd496c18c8ebc67b7a1f719544eb132947bb6fa8997eadc0c9b32da5eacfe88334189aebf89991c9b73fbdb68e7cfaebae455abbe2427de79ebbcc40667ec7159d8a9e897cda76e31a8330793fdb035feffcc74e35e9949e3c6aac99e5ecccf509f99343989bab7640c9c2aaefc623edf14cf9c696f8d3dafee9af0a90fbb5d19913fdbf59efa6ef60cce4b92b8c9892c8519bbf3031d9c3c53c671b5dd8e8ba31b4debd4ca6d2f045b92f5fd40f0ad1f54e579c1d5562e5d7d71e7a9f5b9fb6f5d146ca47faa64165c84a3c9a77a70963e3a6a8a28b6589a8d78ce9ecd4599cbd2eca69de3395c9d7e395b581b490b40d7af66cbbdc3ffd78973b7b69b37c77547669695c347debcd3375dfd9fd163985fd3f59a6ae8de53a179d41c35c99a4c95f25a759ab7bff0feae2e1744a85194ffa736be1d67d7977b32eb7ae6ccd4220c8846f157aa8dd5c13ddfeb8e3d53059ce8ecc34791953f10d77a5ee3c001a48c295d0c025c4bdeeee5ff83ae9f3ee0a6788ae7da71c2cdd5db4e8c6e6934fc959d80f59b606c986d7d348cb7cd11a46bf3dec474b819d8b54b538c78a06a9bc09d6da7469dacd45686a3b38e345e64994cc0785fd2fd73ce961773d74f5dfaaab7cd59fb67c947889ddf5fc8ffa432d9e71cd26e33d337f10546d864b3cf3243b303d97f43e4977ce83128aa1a129e6e636574aaed600e64d96b663b236c43339cf979c717c7bd3066d81d9ac43028ff331ee3cdb0a75de4a4099f7a6164e9c83fedc6ebbd27447a78303697e8d89657f63c0b39834986f8db4e566ecf5499ebcfa4de4b4b33e2cffd3b5efc67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = 2a7f584323c9170cf5681b6168eca204c8f10bc3d29e05cfb3ed8d479b413d987153bdf03f0ccafc45625647b57e3796ad9d4643c73e9ddf66547dd209b6fbc6498de79ff3ca9d67257dc2a2b7728904f05e07ac742d500a7c30a9e99544f7837dab6e7b7b765285e457d96e2318d432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b577af4223eaca3cc9c08833304dba85c07c212a5eaf23d3e922d6f4a54c45e9ccaa1e96fb07bc27707311bafa1438a9ce7355dc596e592a4cdfbae3e66245ebe67610de4875b67e81f1e8930e671b45ed4a38859d203ac064b417b3daa8d23af7c5c732f4c57e8359f0b698de74fde0a4da47559d4bbed82ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ada1d9146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ee5fe2438b61334d0f3ccd6f00c71b6669f02735229b9b1a5b580cf37e003b498a6c6826d553cc736a19a6cafe79d58ae97e7b91842d92bbdeead670128e16c7e9264465e61d86b975a843a5c62a056b9af8a7cd50fa747a6b758da977c2ff14608cea52540dd49d136ef8e626d468c97b7148f6dbbff7aed2db34e07aad44d351a74f23068318113c5148861aaec535d15368a7bd96b559f58bf842713c44d46bf001477ca0c92bb47c5c60fb4e60fff7bad87c26bbb36d9acb18efaf2fc7c09e55f1fc7e238e33d05e4ed186790ae7f5afef4617313462065644a9e7d3f5f320c8542e5e7f5ecf7f390f637af286a8467e65f66f2609cd813da9c78e833350d5732246091aa5877e7ae461ce8ba856d030a856a749d284d689ffd36fa936ff4ef5dedc97a72f539b3b3ff287ad2b79472f38d89a6b4b9b52e34b6bbf52f377e81acf33a16be646ea59b4a9d52bae8c28f63ffcf602ea9b8e9164bca2946a31a892093af891a336abdee169594d0f5dfd5b3b1454d5ba1139a8d167564943531af652203f26527e44937cb5a14b9840da03d6bb2b9ce3eb23355590cb5989a4e27ff42ed7b977a36c65e768f21e941803e80c314d09394cef9bb74fe23d6337b7100938260c68dfa89e0df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = 3a19d55aae773754d77314d07ce9af6577fc603feca99685b84abb1358d0f66e6b735ce84107c8c599fc437b8aa4dd882929b8dbe394c178de33ecfc706c8db227c2920bdb89a8a2936ebde40ceec12663e8ac502e473e58e6f06b9d602ed87675287ae40ed0ae94ca923ac8673ad31b5840dfade21c7fc5841dcd925ce27884f8adb9b09fadb8a32f6b84e9b5cccf93022fb5027c70a6a4f38f78c8391d783a3e78c936b8de5cf04b4a31f907fcdde751ceddb31b2c84086fe81d838ad37c637cfc7584f37686fb3a321fda81db35c5f7af4917e470b9c468dccd7c258780cbaece579819d8c766e873b646871806dea09539fb7a34df1ea70c45ad729e8925467d8807cf87883190ede0a6a57ac83473d43fbb9f34e1cffbc7eac87cb7c9b1fd456dcf7489652f513ae691cbdfdd0327f729ceed5ecb9b9c8b520bd6f8eb67f4e1c4e5fb8b99b519c1700537c3bffa2ff5fe45a748ad5b7f4366b33b6afcd829ff9eb4d6e28eb4ba47459bad8033498b6c1cab20ad327df5afc5a87f0806c6b36e59886b40b3c8b068b7f08eeefa7c25da679cbadf4bf7457883231a8c352cd4650d99efb363bca6f262d9570ff8b426efd6237e75de94c5cd1edd9b3f77e3ddd55d8447560e877e6d8156868708d5c725357b9df9b47e4c9d7819c311adddfa9f6c0fff30999aa2b52d860a6b7fde1fdfe0345e8d539c5c839c3d1ea270f360e2f93fb625d7fd86442389d29737823bdc445f05a9ad3c7e2a8d4068fa96035a9545a5d9b53c426f9e88a10de7e88571831e9ae936656e7dd7254955799ec4ff0f78791b58e2ddbcc4c3f2ab24986575dbe6946f319c7f0bf58c72c8e9b7aceb78a8fb2e24a8b16aec166cbd3ffbd6eda478fac9dce8be6935bc4880f78f7d2a80b5c4e095a53f19f46ccdb84bfbba460d1c33ec9f3eb67df4dd437cc256a611afda650bbcd3f54b8ed8b1b18e4e6f4acf956e7e2b6873531dbd263597195a6b59864c21e371c1d947f6357a4e064faea9fdaf6e7500794af82a5912ce5dac44e6ffc2eba68e5b79a79c30ba72b66bb5d9df800e68e57a2e9b2f0688d88ae346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = 1cd6e044df8bba5afb4fdec19f1369c6d7578aead6534bddd8ab5afbb3bdc5c6d1001e8032ede7b3d89aa253c90c7a4a7e368d528773b62c6aa48d46de9b6651dbef5c353a1f2c99a3e7bbf16793582e9418dedb5c1c60348c5c234f48089d3ea4e9c685aa5b53da5ffa2d34c8ce5a51777d7a63752aaf74e767539bd68f2c0f81a9ee3c093edf17ea7169cfe0831bdd07bb61e23bff883f3c8debc3c97a399df7e591af3807fe903dfed9ac8d4c5667f90407463ae5bbe24c7fa72f30c93f88eab45edccf8248d8989059eb32ec4d224f63558bd53f0642f327c78d3565e06e796376a6e05aed078e98125ca6826a4c34e65e30a7946deabdde3d62188f53847c37f92a9cd1a749f2eeffab1cbc0017b4694f6d8bdcf6422cc85ea7e9952da9378dd0e705ff17b4bd5dbb6400bc42182cced4c564ac26dd2a3fad801650ceff9ca854a0b2d8918a4af320c5915c1b37e6b3b0f18f80fde7c6f2543d2c27728dfc8eef776ba11f860ed55906a3a28ca88d565db540538273ddeea0f83b78465ab9fd62df84dda6e3eed95a53b5ab8301b79d8ec6a5fd5d3bb0a6b57ec99085da37b336f8440e7f9e67fb15c7b8aed4def66755a1ac91856a8d0c9adb167fa676b8ac6729d8c31dc82c69d0abf4696e2c73ebf3ccc4b76df3f74b930977fe6e6d31f48248c578a8d63b14bb48fe6cf59f9734760944ae88e64ceb699b26f3ee6483310e9d79b49b650a33b94e622c0d61a4b79332ad3da79beb70a390205fe59bb4bf7e25e2fe8483ef08df3e34ebd94aa8740862a49dd314bdc161ae30222f951c7fd255d6c8bec5fc7bafca20ee858bc6db6f6d77a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6e0d58bf5477d358b630c4fdaf23eecbef4e7f3396094e415595e01de67d97ef349a6f685fbbf59d4efd1763f6268c807e036836f75d43f6ecc75f74e42b37d874b2c999d44dec8aef59a2673d47d8f6a0effe649e7e50b30f30cc279baaac5e2b3dc84cbebb6475bd2d5af01863ad207674f4ecf5a4cd7cf90bf6b1d83b9cd3942c5dc424ddb31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = 8ed95fa3e3dd9fbc979dd7cd223a3694b874c837f103685e3bbbb8899ee7d53abc7667b4eb158a34953147354f6a67e4abcedaac17f99d3d38fedc9b0d35537354d1bf6f862cb8f277f57f1f7ff5c62d6a87ee75ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae6beb521c6af59c721faf3ee2bbdea2e451a893ea83dd98e924604d7bd2e25ebc43e761c33f4368a643ea23bce9fcc7e36df2861e93446d3a4cd5bd444798fdbbf1d5369f4c73477e3891aac5ee1c1ecc55b3ab67cbbfd6fe41715a9ae478ecb1fd391abcbb48ac63c8b7d7677650aab59c09b43dfae8653d887a6c3cd664096e5529f9fc1ad01684f9eded69f0baf66c64fd28db4a4235dfbff86aeca6a709c9a25f384effc74c0c7b32b4b6e6ef3ae40a8c96c8b56e6103fa645d5775658b6d8ecb41cfb99e43bd8fb8a8459a73d9dd83ac17822556ee83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91b7f50499891698553bcb9d0848abd49eafd195cf39b6f13a078161d7ad1aa5b28b1c442f6ab7320ce5e0cd85f2a6475d4bc8f897a7c1d3b3e1def03aecc5d5b8f87e34c6e4ffa920ec8065644a373453cfd796a59cd3b8ef41c0ff986b3c6c6cf4d64ebe813796fd716c54c154a7e294b218cbedf2d76f8f36847288c76bffee1967719ad9faea8b8e517d6ed8dbd6492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4627ff9fe843623a55c02b2ad250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad1a6d98b2ae383ae99f2ba6384a1c39c69350ff2f437c2cd0a75eaa0a3fa772ed9e4e0cebbb89363afe340ca76a8cbc4c615f57e14969d83cac03de31de4f73ac467b6ebe86e90865492f4a4a25f6f769a90ca3e01e26a2c22ef744844b0584343fc9b3542db841a6efa66de6c9dbf7167dbdfd6ded68f9557bafddb5afdd16efbea64a6aad743eeac97560cbd24d7dc09a6d8e55d351fd1784673635aa2bf6b9248529dd69d13e658fbfc559876a7fe6adca73de2f2589de2aba60cf4528a982e2e5ce88a73b812fe78a6fff647dfff044df4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = fc3f553c0fb45153901b5951ae055f76af70a7feb4d37cbb975b979278aff40e470513b66f58817e6a5b2fde7892ff4a84a5dbe275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb892680efeafad9829fe43cd6c7c133a38cf8f788a6bb8812695703d943169b2e5ae8357e43262d6350b07651a7bfb2c2f74374d5ecb5655e599fab2adce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8feef5fd8aa691a95ccc7da9df353932143f2f50a61ae5ee3c094cdaa568b1f4351779fc4919cf591bff1fccda314dfb4321b9e1a973492bb519d1edced1c590f0a61799832c26de2e04550eedef414f4cb7d3fac3a1bace209f60caca0d027bfe238344e278d6509796155386c1ca904c34728fd772d1fb66d3de6cd9330541d6fb4b3d8b0cf619f8a3ec5843bc2c64af8e7ef86b6836ac394112fa965bca96eed3a5a8fa8bd7730141b42337edcacb6684db89eb1b55456aace6df449ad5b7964cb4a898e48d57fae45196e8096a87c0e4fb5954719f8fd8ec33c2863f3c7fb4dc2eb768259696c4ec489ccb08d8665fef6a7a14ab69dc3a7279db5481ceccb2cb70d3ac37e5bfe00ba71129d5fc6d53f0519c44877c9cb1b54ab03e16e9d424c6a39dfcb6e6c3b80d97aedbe09f3aa86fd543348592fb1f28c87773d50190f3cb43f8b930d728d18f260ccb07c3f41b7c86f9009f018a582aaba4003f9b8c3a4688196e9a58afee0d636db09762e6344013d5e4495b4a09f7091773016d7f197ef9b2f3dd34c854608f54d1c85d6a6b89f8e2fd1bf659a53f7c16dc671bc75d89de9774ce4b52543a1883ce2773bc7d00db746c5b6ee6df6f7f3dbcb3cb60a19e092cfac8508e7d387e6790ec47ea5eb19ef39c005bb971fbb0336fa6d2e306749a60deca6b48bf2fd7c7ed57faa3e8b9dcb5e50c4e3f09bfdfeb72783595bdc7145d9411ad1de54f45258790058ba90dad8cda4c45fa6867b038c7eb99d0c0f632017db1a18ace2ca6fee9df84d094b7298e232144f652fa896d67505f4d106958c81946a87ee9f1547e2ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = dafd6a7e36739a2d6aec69c5569ba3fe38e6a096f539a5eec9f32fc2afb9ea199b877873f7be3546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1eaf512163eeb5c5c3ec6dc9199db5a9faed81b9992bcf38c8cfa7ed4efb458e508b5f5f10c4e10b448ee4a7ba149649d1ea2029dcc95d6deb727cf84ec66c25cd08a13d8f38e71f9c74cc80f3874be848b3450e28377d91e5bd17462eef4e9f1c694157eec659449376b88e33d61886338126b8ae327e23786ade2d6c83a0ff8ed4df132fb59f5d3a5e22de0adc5bcda5bd1a28bc02377a6f3f4a0043f49074be8f553ab65b57fc3176e514794db93a941e6f0f4fe9d1103a6f1bdfb7cfa8c213347c6037b868e7b28cfff47b8a513e6d6444736af884fde78a879cc77a4d7644ae360004bb8b17fb74a1cc99fc3fa6887da110432e5cd6f08148ff54aa6a6dfac1b3b8e461b9813c3a16ecdb200ca81d4e336a54341c9de57d184fa0d3f7b7c0c93914e6b59843353443530a5b70c7ebf376887388ee5561763737fb1cd057f200eb59575f28dbaf0a16d970adb811d1d6491fb32fda5c6fc7d415125b1ac6e48073ed0ab88e07b37aa064942acf5691a2e6c6fc58732598f0de8f838d8881999b431586a315375444c6a28de4ff8aa3daade340d137b885c95f69862b64cf619ef8a123eee3b64bd1a678f631494aba55d42e8e16b6388e9fad4b51c9773083a218dd0e83332c727b45138d6a2dbceb6c4dc644a529446f7710ee18c467f6c64b908bdbc1436f5ad7fe352d64b73948d89ff81ed3a65a1d4bbfa2dc962f9e4977e8531756026f7ea5986990b5bb1f9eac8ba3571052c32d414a5ab07832f03e82fec8ffe1e97028a9ee52df03cbdfe6aa6b9517ba87473e7c6a3d4b48ebd6d23b3db76d5c0bf762b556bcc6dfcd11af2c8b78b4d1ae73cd56ec835aa874c485f733b5e5cddb08558f1cbb11f8665450edb8a5b5cd62d53d97d8c3bacab400c78a65436febc36e5894d06be63ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff47d3c05e50d1b7d04c1c84ce35f29ce751f9edd340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = ce04a54636efb89ae4769a7ebe1ac627d4709ad47e84c44ac01ca4c41cd977a9c8c697ebd929b6e70a8c77bdf342ecbfd8b9df203e470a97d8516e60fa6e564db86467dd49894437ab1a89de4e363eb597d3265d1f7b9a10d7e5d41ae82e945c966637153ea5a54c6a813ff3620af55d9aa110dee5642b3f28bbf8bf05c2552eda5f5ca553db719a26f69d749bcc85388835f01d8e52c27f806c9986f545d9a2a3aefaaf8e22e58cd1043e19e757b8179e40689c986fbf2138bc02453802869b8f53abb6cbd88828726cfa51eeb5f6ccabc9720d7a0e1ee315c996ddccc0fcf365f475c5795e7593cfc48117a63a2b6b854bc7a7a785a5dc4fe5ceb012d78cb344ef9ce8f6d2dfa13e23d83e046de487e1e4cada784aac887bf5deecf033895e48386e57234ef28590c9f542331a9ce7ada2e0fe43b6f542bd85fac6a67a6c3e9ef15c72041e9609bfeb1374c5287348e64f84dfb3b421b674f0fb318618d553c8ef92f4d3a5eab01d564c9486622bc5f33bedbdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff4371a8fe5da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d610f60c3ed77c1558c8f2abee536999da5ebb934cc974b55365495795a6418ac4a9f4491b4f6df9a2e42487457e7359cb6cdee7e1ccc909ca00f7dd5b213c339d5f4b27adb748ce8a126d26ebe623959feb056b12f07d1fc56ae35e97ec7ddb787c8aa02e4b828c4e9970dee69fc9be80d5d4dd89963298839ef7c59b79c8df6fe4a636bc3bbe97326c8ef09fd90e4958a8da3382365fc65594219ce9e7d70a6c3586466ccc13e310825ba43ea933e4e6fb7a73d84fd5ec33fd64f03b63519ec25fcda7aa99b918d844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da89ad28844d6f1b379e95792c78e97d69ecb9303b3d5cbf79165dda44567d31e5da0bb4d380849e1145140d9c69848e9f7447332cb697baf783cee69dc7df49d3cb77d35845a48dbe3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = 4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df18e81e5a734339e0039e5603d8910a9e72598ce73a88b41cd45c24f4d601c6a5bd379113d876e076e4098fd4cf43c3564980d973de84c6f1d74e5d0dfff4d50bad07c5fd58c6aea00ed9948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd70e3eb43d46060cbcafdfeb13549e3df843e9e7b6cd83e6658d8ad4a773247e94e9d5a39217457478a61a9fd3f9e6a90e9a8492f96fe28a72caef743b4ecaf07752f53bfed40ce8efa95494af4c66c93bc6aa84667fab80ada809ae627948ff888ddd8f195e188e80398db07d9f52572ddf7c0ff4087a85c4f3c88f96ee6009f632e6df5dcfd33b883caeef5f8beb73136fdfb43edb233d528644b1ee298161f453b503f2274ed899c88ba50690ee9f5ab0537ebd594567e837471a84c6ea72797e76f80c94894c870e69337d939691568edcbbd0895da6f3a53eb585c01bff53d1c943491d555afabc430b7fe6a3f4a3e775e7ffbe3638b119a6429ff98d8fbeb58097f0e467302798a8ccd8350d36bda8fab17a53bc0c95ed91b7cf10d6e7a2cd3bbcc63d93a38ea4653b8083e442889ff93ddc96b5c37273d81de4d0d577d959a4e764b6ecdf1e96633f5339da81f926afff4f7e31c6883dfedf5e67d5f0fecb209acff5644717e6c6928a41b6f7e8369daa524744881aa428ce7fe955b306c33447054ac739e12568a4cb16806cdcd08ffca87e4cc37c3bbcf8f5dd3cfd7e0123fefced605a14ac32f6ae290fca8a3e39f62a64cfff8b182dacb39fe73f2cb4b0f392f8077a325a6259b3f455e57964e338a6a731c5baf9beebb0843730ffa93d6b234d51bb87a054968ddd7f9c4afca7a6d7aa7d79ecaf481e69d956fef4fa88d5e2fd3499c7f16b6a3a14b9c0c6bab99917a435b88c4314a290f7dc7eec8a155d37b663eb35b89655f9ddf5fbffe53ab33b6c68583780a3c5fbb92cc90c45a28cfa8ade6eeee03bb8c05f8d4e94bdfc0cc510e732df59e3116a7786e437f05f36081f6f048ae71698f4a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = b78ef1652e5d038aa3f915da3583fe408ac91a2635b4c6b502c698104c7e91af6bce9d3a4b78c20218ae92d39bf634828a14b529983e93addecb3778a1583deef38497a336063a31ef9460e9bf40fbb4dffd4b7b070a4650ec3cd6a8d46c097189237a11b5e0f6a4ee6b73a79dd99ee4a8517d256510ffc0eabdac2393d2ecfac7fd74fdf993dffe97e4eb8d71fa097b39e5791956f949ae77858c89fbc8bbb37e7eef7e69b4256606c8abd1e9399df44f12fb8e4cadb846ec7fe1d65582bbbdd0d494a9af5cc81667ae1964a535d16d9ba5ef698c8457fae62cbf10293cb057d82a58bdd42ec616fcb7a8aff3e95c883446fda8f6dd0feb36a6dea1a6b673631df13ac3620b1e3a6d5436f02d64fc46d806dfae84d79d073761230ae78208db5e85c87a9f329e6fe25a9965d9bd39784a3bb57fa7f42dd57dbcd8e504f0c1ac9e55f7532f2359c3063727af5599a8d597da97161e7a5bfe5de88b516f8a41e4ab824ffa8e6ffe6cdbdcefe4f965eac97474a7b235ecdc7324dee7153a836cf928a3e1e2cfa0617af742d7de27d656ef9954c7643947bc32ec7e3d9ac392ba8f400fdf7589aad4f1b7356c0fa54c37beb14fe5daee50549dd49f9b61b35a61c10598076fd3724fa44d5ff52663799de7bafa7ad42d439c893a37a88bea793ce68a9f4cc74fae0aaf99d456c6d36895571572f1ace44bcc6eb0cb9aafad9289c8cb193cb9ac33823d1e980ca5dd1106625755b280077f9f383f8298f4818956ed46755f7933f029a9373d54dfedfa42f5c56986c541e9ada87d84b08b7eeaf4abb80d839a59c18fc556a6e5f8e63f6c0b4baec37f85b0353e3a25ff06fbac742a960664fffcce4d0fdfe4757cb1a23aa810945aa95f6d3cbbccd11b86ff12b553268abce55d7e7f3e4a6d71a8bc3a817fac653cca7c36efeb53c95b569a44e5ff3e6eae991c38828557caea637e7be3025ff91de5edde07e73cf84be8af66e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4b6f2bd8540b044bb14384aab596147f8e3fabec94f75bac3aaeaeb14a035d858892b7e901af1648f8f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = b7665f3a5a380255617309ccf80a53dc13f5a0df52de0bb4865372ff3fe48ed6c5f7dee1ad0db3156dc5c8da7728dcc4c55d93f6c38d7853f542ec71bf5e526d588d46cbd7ca388089aec8742e9d74334070895c396a87ae49dcbd03dae42affdde955cfcfa29c0fd6e59f747dcb39599a49912e51aebcd852d6c042b4c0db99c3f3f94eb7ebe93bfaa70067d9933899c14f35941969baccb59418a41f6d3ec62679b38d8f25c8565e6954346ff7e50d40d94d7147cae5b7a84405c6a6e82f51236bb952ee8a208eb84e1ef6804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1edae9836bdbfdf637a5839c007cb5c5a8fe11aa64bb0f84884e7d375e352241bb0dc4acc5f27da7f7b7ed43d8b95d975d5c933e5058df99c4e08878523bb98274488ab8ef52997dde06fe1da039bf2e43eb75d6f30c4ea90c892298dbff3be630d0d48c22c497279dbc965c009e834bbf936581c9da72a70e2a4c2df1ff0cb4b88296c97172e5007ecc9cbf9c1ac18ed84d56adb884d262f584cbc5e61d3327ccfd02b275683664487a3ca8f767e55ef7e541a403754a45ba5e2369bdc0298bfde2e43eface6b4aaf82e24d1069ebef738d01d0892b939c3fce379c2e96c2c4ea9e5cab8c09cafce1cfa14d79137e3b86b25546c96f28e0d8c792496ddcc9ebc0ea664f6f041dd9fa798acccf9d33b08f9d6058c27e79e4359d4b756afb43fc98013e2ed69c4cbbcc379c3db83fa4f72ce5e8678db6f4db1f7a6d1ae63de7cb8b7b7d536336468ae39ed6346d814b83ed574c98ff9afb2db8fe0e4561ba8d01ac783eea99b83de3de2fc5fd5aaee7cdc63e814b3276adae03e8fb34e9c76545ccd8dd66b0abbca763a9aadeae75efb44ef60914e8c09554bde64c1d3767b0759d1b5f6e449f3f532f98366bdbcb65cb3b64cd3f2edf3e495a0f97af58ffac4d3299896055838263ddc85bb3a17eac5c87cc8a4ce8467881f64d47759b420d5809489cb2785aff1935835b845977bcf2b275fabf3e222e8576e3578a7a56a26b3ebd66edd12bc9aaa3a46fc87cf9d17d6d21ae26bbb446c34f30fd8fa780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = b6a67cda8f68b0ae59ba69953a085099ba56f4e4c74fdb675989ed1ad738d04fdc3cf8c52e6d7a32059f1e8333b51fed8568e6496963baa6cb4194ffa7ab7298ae44758b84a27aa6de5d7c097a6c7a29d63f3bfbabbd604aea5ca1d8fdda89dfa49dc142b3709cb69675b8ba0f4990dd9f3aa525a317adc7931aa5e5dab4a5ee9f08f898ebf8d258ba72127a92e40d5611b7f023df85bd2793338e7ed5fe3a06b7ef8f68a0be49a13eac34c773937db6f1850ec3fd5557767f466a37ea4cceda793891968862a0dec77c9dfb6368e89e13a5243dc4f836bbf41595df29499c4fa5a76d5ebcd6aaa89ca3368db5ef6e9d2837d2b448db717532e0dcb6dbe3bb0c6431ad58d822fdc184e7817616c1110fe65a0536a4c65b223d6fcb5c343fc38191b8b46dd7a3e37f40fb85c365a33e18ccf31127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddd6fe57daa998c49fa255b37bea55f1c33a23ff4cdb70a3fd1fde9f09fe31be9fe5db8ce933d421a77dc246695afb5bc33e8569ba69d2843957ef5f204e435f85c6a713c3fd677cf7a54cac8d48976fe609cd68659643a1b1d558f7397234b583e5665e3e3dd20af6d0788b21bcafba245d7123b89ca6aef54cc5957737159e93070987613dbc7dcbfad1649d9fd167d9e099d8c394a726e41724ecec55af4f353e0bbfce3abcbd5a378ec81e7d34b8687c1e6fabc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa830a8e2bf6459c26c5fda4abf0ba46544b9e46f5f47adf99f0a7ffc74b8b90397503f3eeb9a23bbbeb3bfcec659c936987c97e04814a31219efb443acfb87a0863564b9eb91927d8ad47dba73e4ff35b5ae9ba7d04793992d13b5bc0ddc278afde699ae423fff28d593f6d3385583bdc938334f7f4341883a8026cd2af5f05da3b44c9d75b86c75fe2d3b0cb738b4f533eff6e17ba7e05a275edb8bda15baeffb0dfaf4ee3145eb3c500440c0f3dc427cd93d5fd496d85ab46883b4b695f30952bbb3f13418958998ff5c297da24f36a073ac04579e4e7a706869e6e53845c853de2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = feb55ffca3d6f08b6202faf5968669d459714528d620da32b9c4e577af97fc6de0949ad516ec3429fece811fc664dc5c390663cceac966656caf7ee0d1a45d446dc420a690157d9a70c7ec0cf8cffc8e958a687656859a8979a24c9ce31d2bd3e89ebb81376db31562367880dc097f05ce50a27e445283cb4444701b05e4887c917b4edc87fa30dc3a49a247f7e48f4f5e2b821875ba8c5f88a28b40abc8ba0d23d95345ff60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c56acfb7fdea81bdf5dc7b495f902ce4b32779ba07dd57d84d92aca4163637de873f068eb170e77f4ff840d0e56e13d367c75af3c453c848ffd8c85cc687066c09c6cb6c397df133f313d93a9ae45352e746c1645528b3dd19f6ae36a56cd21e6af6eeef6fab71d45544c22e895f355657d982fa23554b75f5a69ad50b1454cd3acb4d3faf316be9c9e6ae4a9a3791e6be07f64c1de5782eccfe55ff3782c64d74276f5f16de89d8f6c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b45fb34c7e959cde47527d61a45c22b13e6dfbf7ebc26b33efac3a2bf9c4b4dee49fddda82930d4959a13e763cb73d35844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544ab3f90ecd697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f86f5cb1aed3cfd43e314e44b559e979f64053a53e64fbab4e57dfeb53aff658db07c6213586315f5728aefbc66e49c36ef8f9b6fe9c9f653aafe314406a6d0aee5adec85693d9389ee8fcc5bbe221c323829c91bfce16fdee28cb39461cf5876f3fc09dec409c581a946dd570ccfe333f44f0ba84c19cdfeb6cc762afe408a9d0745e1b91affb7178fb9dcd96dee4a20fe4b6b76d0ef99c47de431cbc7482da47d8764db3f7f801f8a9b1c6c583ee73bb157a78c585b96cd9a868a957709a5305c7425af8a8d83eace8759f63ef566388a7ff5d705c6d45a945b69b5fbfb4a61e4dc53f633d773f844ee9dc5728f3c3094912c3a9ba25879d704e4588d596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = 9b7fdf09135fe75e929f5bf99eff8fd9943ae75a983b544e633d5fb78eee7815e9b0794d9af7b4adbfbff7d7d4418bc89c38a9e3cddffd6854c604ee39cfd4c0fff0045fe3c066cb6207f2e5a5f1bb6bc03ace9781fbb71a546aee03ec90783695c47ae39ef523f84f0f56fb60f3bf780fd30e7938141d9d2543fe976f31a56fccc596a48cdcf2677a904e45d35fbedec67fb15af3ae770abd79d7fa1dfb3a988952c925b462fd92dac5e726e999bab4480619971604f6e21441ce8f919787c629d9db6b1975e8bd844af5fdf6a5cc7d393ada64ff78a5fbe3cdd1979ca34563b39007e3112af4fe33ab65265b70eca7eedaf75a993ea2793b0b08adc56ba66d93ab1a65524bebd34a33a9e9f59b7afe6ab01fc471bff105faee2dad42deeeac61a982ee5de02968437e2e6cc6387989d652bd59a4d88b625056b4066dd92b5d6cb5bd53248db35ddc4d353e8e33a797c696c12fa540df53f9268ba47c95368473c9a71bda5b0a3360b73768fe6d94e59c7abec83abdaf93f3cc583f3b9c8e5b94f6889ccae550bdc6c0beeab5fba4f10c834066f9bace77cad4307a8bde72ca4f8c7ba5f39fafae9fc566abb31a1f4205554fb538c6a5c630a32655ad56be818aaaadd546b2dd4df22feac167bc0927437afd71a03d56febaa36abcdc9275e2d21530d5b9a8ba838f7a44656e868c925d46eb8e8e1abd6afcec6a14594e6a5574efffa93783ef24994ef7dab03f2f3c10bdbef3af661703baca19dc51bfdda05a64bd764f1f1b5ec5a6ccb7ac59e475e46304c272453dcf897ac415a88965e1f6dd4c2418dce1aec0258e5af60ae021c7cd0d8dfbfaf7991e9e5df9b7a5805e3cbf0cbbe6f4d854f4fa603a6ea75f4fb3f49c81e7ec4daf784805eb354bb3513dd0847df01baa7fa2d64d269a598e49e9b1076b8abdc894d8cd649f4eba6bf5a92b351b5e6c50686b2597828bdc894a08349dbd996b73b2fa0b98d0d39fd2c6952e1a60b6abeb8e4eb5f7ddd2409c3bde7e6c56586b7d54deaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80ce5d2aa38d63835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = bebef1a29f5eaf9e39af19594444a8953b824f4ba5ca44c07df745ffaeef517e975a5b4952c48df7d431a92e998fc84f064bbee538569565bd0dc7d087654203dbc0cd2ebf4cba678d2ad93ea8b295789d520bf6f4d78d6986a0167e45d054afe73a90f25886790d44d4b9a4e22ff59d4a83dce43973aae71f6adfab0736d683e988ca74a56580d4deedc4be87cd688cf066710a1458a753ec7bd69fbfe67b363f386dda99baad8368d8874154f3d6d9dcb69736a7bdf1c70a4c7e33bf3169aebe8ff7f5fa7f129f7b315a52ec3341af239cb88b8137c5d9c7699b0a8578a54f5a0dd535eada924f97ffcd7e9aa785a0e0045b04bf4d0f6cedc9c7f0a57e7e0705cedb88bca9ef9a76043a73a87c878ff3f487c6cd7598bfb4e94fb584f50f81515e3f879fcf17aa5d1009756db4b794f3c7c3e4d253a9e924fd98cd7680887935729c4a41af3dc31ff7cf18c86137482b574c5ab880ecdedc312c5eabfe5870aa4b51e59f70c35d357be1fc6abe072a501bc6e647694d6d0fa732fe3c33af7fa63e4a5e74e837ef3bd7af8c2af6fddd89d39b9365b017e10dc95760367ce6a8bc2a358d9fad4cfd4df663caab8d8edc9f199c2363c4628ce4b6cb5c3d4add9b3f81f07aa5d78df9654bfc9a0ae475e343c197cad3caad00ded76cf9edf1ffe436cb368dacfff2cba5691acf472b4df839785737842b378cf29567db4756233e9328dc5388aca63363e273bfc164a4a98359b0ea8e310974d847a8605815a9dcf84532ed9b6deafd1163cc1a8f4baf076f5ef39e6786e622dbdbcefc7431cd7ef8b8bc84ca8f5723e974e5a39244407d376fce88c34013df33ca7c22ef7f2dcd6b444ae2937b978e68a2465b70fe99e7da84700365a68af5f6316c61fea6b0e5a88813f5f51f83ba395bd296475dc1c77878db73ee4671e62bb66e5d604efc4a7b9eb87eee78a617931fa4d6eca5fcecaa8275dd95ca1d62c1fdd04093b3e6b36c9ebd94cb16a34a33a5890a56e973a12af859a8af557235c50335c6418751953cee3b3bb8b659dfaa78c81d84c724e979cc2b36896355302e518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 568ecfbc9f62bf7ec821bf70d635c0002bbc92e596f5dcdb5c0ce24ccff6774d308b495c343e4b8e2d801588815addf832ad62d7967691c64b076496686fc2c28666cd2ee9b4bc85420de7946cf00de76f6f5a83605ace8dca54585a5f115434d80d94fd64daae769450aaa7afa6ecda6f39d634d82ae6a495bdd0950747198f36a3b9b170a597caf8f1b6d74d7e0dc42ad89a32bd383665b4da07db95885530f3e5fd75888e76c1114cdb4308dc951a626c5c59716e38567aa786ccb7966840c7acc5e71cd29fb38f9bd3b9ecd9b1139ec808b44804cd6f234eafc703834b1f5474ac3a927aee25ad8570cf7ecac6d3f0b8fc53f94dcd8797ee25ce4f1635e3be870613f191c783475ec1becfeea873d884aac48e03f97093a9607f91e9d3bafd94574b4e823f2c7f570dc6c0ef37e19e58e848b59f27d2e1c9f4d47cc64f8bf4bec4ec3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bead63a3545f0cc8284f4dbfa4b99d2094727f8cf006957fcc432c05868517fa5653434a92b9ab53ee344fd63fd44572a23829aa8b19e16a7122bef245f813d59ffd91c834eb5a8e5498cf7fc76874a3ef8c9f6c1df9f316f588163a24c5976bf48797b694fd9b964b1cbbdf63af3aa4ec99fc986711adcf263df11f84914b9e6c607d5d879ab4cd3aa51f7c0790d6ecb6da1b63d75ed7ec11dedb6d8f9769f9549c2d7a690ecd7f79396bb2cbe2e0ca72436879b0c8879dda9eb9387c5759b169ec5339662009d449184690e7e7a8a768f0cf3d56e477a9dd8f2b5fa466c0a85b4bdf56b6eb3d0e433ccbb6a9264f22fb779cdfef73cccaf7d5e760e36de2f566b487b8ddee9d49e037291eed2e14de9c9cdb2983687d37c880a17484337a66467abee2b5c844d534ed6d17a76d344083c7fdfea729c754f3cabd32e8dc30fd1f48a3b68ad7b7d86b072e4553be45cb51afb425cd7719878d4a84ad2d33453b783ae1e757704ee6ee58ce53f6c4c893711d66c94d6aca65c980a545b563ed26b4f318ce7fe808ef9c60b652ea49b2ecd75833c3ac3e7cc0956e8f003b2652ebd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = 6845671057a2e8e3b4c8b7de757c8b424552b1b79f18eb72a64334ffd7db2b17f03fdd870f6630734cf6da09f9dec6bef96a92064a738b1bc57d1dc966de740c3e3e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fc7ff0caba15d0d595bfeb0eff68479daa985e79a0c5734987a34858fe5be37729bb5ebbb23e1f7fd800a37670d4aff560f3e89bde9fb068383adfa5d94a8fca972dd39e179ed39f9dfca22936896c68976daf3098384171d8889fe3916089557af77e6958352484f2327d3d22d922e1d3d6b2badb528a2eac86e184e86b3278d7f58dec2195006f36583cc91c128889475980779ff16dffb9fb6eab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0baef182357114f3034aadc21a3df5fc760b92ea07aa38b032ef3b926dd4abf438eca5ec5aca812f96cd7574a086ecb17eb9b71236b19a88d6bcc7e4a0751af543a1524e7d65d93f663d543c678e19c330c63c371f84ee3dd7d5a76ac2747d3b8166e899f86da5c5055a6e084265f2e68e787a7e3d84e86fdf56793ec6c8dbbb4dd85e96aac4318aa4f773bcf462586566c3c6ea8d731e7b8274af1c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768eb6df6b61aa16a8f79191b69c39b53184cf745a7c251f48d279efeb4764d9196a18bff8d91c540350ce5921fba7eec9df55fe121aa6132f7d6917fa59a8739535c9c76959f8148e12d7348c913db60038a66bac005e38be1449e3ba6e851ce85355db33d78dcbc2a586ef37e323891deccb16bd5feab1b7a70ae3205d38963acc148435cfc7f803e6d54a19cdde4bfe7038af57e157a59f8a969df50aa1baf88935dc64f72bb5950303ac68495956699f38cdfb595d7cd42749ae1b38097ea7ff916d0056b5ff674a4c03bf6aca5cab4379f0864a250be4f25ef74ed74dae6d692adcb3fe264eb995eba35893967d39532bdc163d5b7f23ecda1976e416df9614399b7ea6cae6f8ac5245ab765ffa5dfacb10aa7fe2a910827d7c327cf8829fd914f87c58de4a4d5e766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = 781451ec9a7efaf8639ea457c033d88684a91cf779fa465941ef5955d47a2df978283864845dbe44899b198a706c6b5764cfa170c8c5f88bff9a7b6af7cb48efe386c28c7b0b19a809ff4e3e2b6b212a3b8baae9f6c47d484893ed89cfd3f678207630c3844e969c967eba892656ea598f6eff42beae5339c72d607b7d4f92feb0560ad7910746c8fdd2bd6e7ecc64add119dff2deafaac53a40487b83e9453e77f8cf45f415a930079abb7f6ee5bc0745290c70652d853d18d377f9f1b67f3048dffcfa289d2efe86b29d8a7bf471e5877fe23b30028a34f30bf8e726b99bb8f7d347c62997314e39a0f5bfb1e9163f53654e056aaab57e8609983bb674a4774fa81c1ddca85ffd3e46eaf12461b97fd064547dfb57895abe8bd1c6e015efd315a659a5ca65f9cb4ee214b0d133e13e34310c56bbd99737f13d5f6f3b49f688610a777edd4a3a492e63e6dbfc64668fc3bad24d789219078b4957ebe7dc4395346e7f87c5b25dc1e7f3db9d2a435e7c3a32f7c4d346f2d7b73cdda989aed858fe4c7e9dbe63f35679b85bd1097aee2c3897c39dcaa996ccb3943e22f789d3d5d98baea6f117347e17f5c358670d678c52ada9d5f66aaa79f3a895cc5fe5c9531bd69397a0e458f438f7e3290c62a94771f7168212a7cda9ffe39d573a9bcde37453e80d2e3b79aeb5b39ea0f1566316857a72b5f1c2b79c660792ac0ce05a788962a6ae74e87c48b8d10dd643677f817b0db4996f72180f6690ff9f1077a87a96cc27038e0a2752a1de96cb17babc25b29a6d54d61c68c79ec93a75f0a97392830a8f157940fb9d3e7509dabc9691b86391ebe3611e04c9e0678c189b7875d373f1bf5ba0eda9b063cdd4446ab9aa6b23e6ba6d3f4cac29736447529c76c33a9fe81536d7aa5488a5e7b244ad920984b06dfbcc410679ac035ff824768168c758689d0c3f6831f5c1032dc10a1e540c5b7f9a45e0d73cc1154affc2a84b8a08cfd7f863e6c93e06fd5a39da58cfb57dce98cbf1b7ab960bb14a9b86dd7ee046de730f3b82e5eba9710e8bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab932d85c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = 1544e05e4b3bf54bee728b61cca6adeb6d3ce864f5d9ff51b4173f289bfba4f6ea1f04da225d46a49ef11a26b897479a5b1b362346fae8eff410d9a1207fcad8ded7e5659731a6c2e0e95c956386cd35f7b39d95820b6268dbaf17cd754b583e8288787c186de105e7b204705baeac8c8dce70c9e00dafd93c3a7b69ea8976f5c5dce45b391aa28f0640950e66741876baf7b5b7c6878a87438ebe8ff45c73720e6a27e572360c4b2fe4552af9a1a47cb82ecf49f2c8bae4197de45ea48cbc549e236eb895c488ff7ec3e765102afe6896dc61e9302239fec7435df63ae012d78824a6d216c4ce19ed60f1c4af2aba5e9cb9e3484fe49d3a57f735f1ec9a97d059515ad9c3ade8f8c75c90f74dde5135cbc646af16866acb3db6bc06e0bdacdd1a2ac95b999e0749a3f5b9a993ee8a8257af35fc9f7e4bce74c87c7496cf2a8ae6d966cadaedf260f630d3feb011aca52f78b6f14d759068c0f3f553a40cdec7c9a4c9cd5ef6c9b026b3be39fdc02049b8c89c88ae0ea862ffb1b24fa961d6ff246a4c1adfcf1849484f884119b8f3d793a57914f0a8f74f98bff0ab8b91d475717785c12abb83291b3fb32c7bfe836b7c6ec03ec76f37dec8cb0e426c28471676302139e16d2a5ea5e4e5bb23e88ce7f0cb9693a02ec7d10ae8a59589828de1a48cc65ae9da7363f32e8a3db9ac87d425771c7b5bd19684998e9dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7e6eba11bc93017e47ee6e3c72f756bc367280278f0076addf854e837b62c9458c35fe38e576a99f8a4baf5b596e3f714a6e6dc28f7d2ef5c828d4764193b4f39a4fcd0f7d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c544a2f5133bec764f9ecc686afded843dddb97214cf8ee0da6e4e4b66c27d7428ecd27be5ec1f3c53a18bdd85a6dad68562e3b78190d66b4c4c3401aa1f85f685ebc8316d6bdb539ee0c39cfe778b8ce55564ab5dacae94c4a6fcd952f71ef257bf1993ab059d4832a9539ed749c97790f26a09c2c81d95543b5d97668cf5da1c7ada9e9780afcd9a0bd96447cd3fd2adb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 4098cfb375d5dcb77ea89cfab18a760aa67c4a2f8b7e5bb524b5c4be18efb3d8b92cbc4b92ccb4a62aeb1c14521ba4a898d46ba54e68dc5a47af9484aeb453c4fc56eab73b0ddd40806ef4ccf6b21575805f4eeaf75d84e3cde0030fa1a39a866fdd38328b75bddfd6b55a90d714a7175c446edfd91b057ca55ce11b9fde8a75ba0206715b3d42dd0ba36d2cbbd733f6532b58b02636cbee949175bc51ecff46ec5736ea91023657cc65aaa8dff159effd76b3d4f796cda7d377c0e79a4aa683f44eb7d14feb623782cb189ee6eac19796de06bff4fdfe2f7cfa8208054a56039486ceec1d888f51c479507b8a85a57b51f5b824f3a9e51f74cd188d2099765b0d4bcc64a86844993fa69c0f73e90c347e600e5c6ccf90b39cabedcc3be95e5905a37fd746616fbad36666a08d537aba7a645b6def1dfdc0c8d76d07a67f485e4c4c49c855ddb8d30bd3fa34abffd46620e886e017d0c7c34a2b9e99c79cf3f68f78fe7ec0369b3d0288b711ec5775d7d334e984c686cd8e4ae41f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31ec5e329d8e25f8d79557a63a53a8a32ff45dc2d9cb7375272d9689cd94ede2dbe8a48df27ac993b9f87111cab085ce96f4a921c6f70e43366ff94af4d4930097cc847769cf3c8d16f0f4733233e9ae67f8f1aac07b450d2299eb1c7ca85cf8990377ef125dff13be4f99b9a1bc7d5d719321e384399d675b48fbeef53304074c51848fd341578e96b8e1243e2113cff4dba5dc5c7f78bbf51bb3c530c0ed57848e9ea985363fa8b453ded4f1c5c46497ec64380fffc553239cab6f543453485b6044b7c5d49f863f3d0e8614a8b5c28c5f633f7fc64db6d0438aceae55b8c239c6b06bf661ae46c2adb132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613fed520dab93b9ce5e0b4def9aeccedd16aa71a957103ec3cf0ad23b27a1ec259e738bbd69164f5dddd2cba96c69bffb35597f41fba0cdcb81729ac1c4ec49507683fb3d4d00dd398515ad3f9fc33ed440e40e3daf4347137d49221f3fc06f8531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 695e7fb17496bd8ee46c7e6e9c289410ca7ac5fc5f663abb1b7672f91e5917d6e0dada39ae344dff8d5569bde41c7ed3aadd7bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326053f58b7ff11ebb3569eedb47bd8864b637e94a38b24fe9910ea5f34c5e8dfba0f853980f17ed8125c12ca665e72673103cd5d51bf8f71696f91cf74e74cf57cbc86cfdd177a3dfa1bee64a245d57b4b2fe6c4e0f84dd87b8695da43a98e79b3c2dfefdb352549ef337ded58f7f7e15cd8445ff4b1415312185b2afb6ccd9b592088eac0b5a7a494ef5a2af300974c429e7957de3a796a48997fe579a8fadeb538dbfb8867a85505a7fffa7394fcaccc5080e3c910c79559bebd4b5bc6a6d52005c8c423f53e76e7ee827bc31bc973cbdbca2d6ae0b27f39d2fe0b4866f591fd8656d589c64963a83a3ef18b5287f72040d79b4dfd15dce544985c687a438ea4e45839ae4648c5ef5bb46a0988f43fef4397bcfa43afdff898efb586b2c6aa86b75b0ecbedb2aba678687822ed5ac8dbccd49966e2f1991e19f60f547a4b1edfa6d9b31ee0fbee1764f7b5d85eb05f0d596f551eda19d05a78b9df76dad414f0cd8b109afbaa9ba78674b92c5b6e02da15315ea3c2378b8dd5882fae5ad2e83a62b8efece5a9063b041cceba70ebd9c16c6156c6e4ae8fc6be595162e74d25f7a6555b42086be9d05945a289ee90c91e525b8a6a3f4b00fe406f5375d0934b49677b2ff88d1dac1d29e8adfe3abf0e738c82bd088fffc1b23aed4d742c283ca563da0971ef2cb2a79c1af966c5780044f97fb5ce56adfb73127bee4e53017bd4188599bfc468df4bd91cc0a62a093f1381f7eaadc7bb0176baa45788e994cb8983c7b08547d44d092594cd1fd5d3baaae485d92c3499e74de6584daa3e303eef226c30aa49e5a3e3e5dc98a6fbe6f40875fddeb735ea6cafc657db879fd28c35c6a1ffad1e53418c461dcf46d5b5dd46193ca8277b28e06d7aaee52947bd4591ccbb1c7f71a5de05436644e275d6f55d3b5b3ffca9d7bf5c98d809d623c9fffeb1cd33a1b90d884f2454ad460087b81098c164cf95079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = b23dcd26fc457b8ccdc1a7ad81ac5db25945132a6c153be2a29c814a4e9543a6bab0b8af5edf72c5a7b19c9fe99e943c5b2ff80b2f453ff36c7b698f41dd92e75ecbef1fcfd3843c07da95fc5e68a4f9ae4553b149ec3f0a7de99f6375499372247cc59f57e9917be6900f574e1cbef46dcc18c3ba41b3f58df742d9f6b32c076f695a7da1479790d9a181add1758dd2d8f488cd54be721ffe134a4e8a9aca2167d351248a4daa4550cfd1b5e57d15c3d994b374277b3861898734436c737affcf0a921476e551ba8530b6ca4f36a74f8933b4cfbd0fc89b78146871c8849c3eacd0fa55726836f8a6a2a36a32d43b78f958e0141c6b18b4bb6773f90a289ad6363f098e6c3bb3a2e519a1e0ef76f78e4b7f693958f4746ccb68ce4fdae60c589ea94023c7adc3c680a6ce7075d772b28bcd8e1d93984d7b61cfa7ef0d758d7c52630ab0f686b510969404dcea921d338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed1af8407e912b69b40d7aef84a56577bdfb12a4d9e34f9d44a9b45868f43279a5fefd7f00e6392c76fde88da5b808ffc6ecf48347c9a12d62ebb67eb33457e5d36f10fb99dc0e71ef0949d117be5034ccbdf951a46c74971662957f7b59c4b63034435f4ec75e7d64209ddf0d458b23736ecb76bec38dfb152389cf9e73699daf0694dcb8d9b8f375a33b03438f9f36fa4af21f93e86f77aa388c840e2b6b9328710b2d92faa59eb8bafd59769be87d46cc334f9704c8b855a787373dbd87f15f268946e5c8792aad13e645f39fbc73487432897c50f8e7a2fe5002f472e414f98a785b26f441cfdfb5c7235c7f3b4428d78a7d47cf4b83561ac38da9dce24ec4db44b48231d9d7880f510336d95b2b3492c8fddce7a433e97c65878f8ffaf20459bf77b8eb901edac66ca1020ce5ff8d4680fa9678d4e7473ee444d85aba5c570524f2c69630acfc7b86a843a85ef7effc452035b41477ac3ea934018d76f09796323cc9d1a7d8654dde5d3d9f3d7a341adf5fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = 320558ed4f6b57e3641a1f4bb95e6c6c4f32729aeec5fea51eedeb932738dacddc6b5dcbefb657969b4dd328f95c6f78f73963da647156944423045978d5dd3c078e6d17f9e12e93530f897037ff3414790047dd491ce2fce9b22357bf72fb470e748d82b79859133d8dc6d3ac7cb2672ca9c82f6b6e99a7489af19966b7b897ab3a9dd2090b4900acb068a866c50c386748dff5fbfe0c9c4eaf497adbeb79633bdc0234748387d9a3d7cdecacff782c9a3fcdc6ddfb37cb43f1db73e5f1bdae23e7c6a5ef91bab6ee50df6c98f36f69d75369f5af288ef42a5e58b35d6a39eb43d2ae6308c7ef3bb5cc26897df2378837d9cfa1ac47467e8fc3739f5535c35e07b461a8cd65eae8a48d9d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcc4ed00bac933c3783f05c47daf8058558cc05690bae3c507fa8d589df27b7ed9600e71a6e8f6f724e46c934b81ed7672e6bd6653fad1479137cd6dd2af9f01de8b26ab9f8fdb7e612ece7c657948273268e6b65255e01a5fc73d949c4e8fc8144a3dbfa7a82784844d57b355be598086f58fe83a23987de39f61b0a8761af3e67d035e96b78fecb9bb51055d86e464677d8d79a8b732b686a23b7e36f9ce07ba6956cc46bbb6ece934af8ba7738bec5de0a4d10afcf885b8e53b07f0002c9edb9e7f337bbc18eaf324b45bc8aef7d22bec12774c6fca6a5166c4f03440af55f0cd19f33d4934625fde5f08eca39dcfd34dd1052a9dd366512149f2247460650de05b1a4dc1a5f8a7b95c5253d4ab3ee64a45c964a7320d36e1c68498faf56cfc195373267b0169ee6c0a8d1cddd07ed456a5ffd5c49495ff99b1b1754a9f4f9346536d17fde5dbf7967e95e975be9721e845008b76b2c47e7c4bd4457c924693bfb70d7c918c64cc38e26665b01dde8b7a253bd17d6d3c466ead2f4fa12bcfd614e7b0ceb8660f9b672663afb3ba51b6a2b215d2de6c6bbdb33a0ac4765f967f8d685ef23ddae2de7cd5b47aca963f2ba5cc38059b6937916566a219ac321587f8dffceb9a5d687ff543169a96f648ad260e948316b55ed4c1e96e661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = 16d85b965a81b1f55647985ec3f58023574f4a0d3f68de847c44a40d48a2d3d86a0e66505037b1a9898be81edd98c686d496c646babf8f9988347fde287b746408d15bf4acb8839d93b3e1e99ca4f889b123c8ef6e84db604cb86464837cef91d1f4a91abd7dbcb9589b2f8286faeff56554a818439a3c8f1753b459dc557fde35149553d7e8fb1d9cdfcdacc30447f9d6ec9511c6a3f279783a2a84588e7df77ac94555d733de48f8964b84ce6e7319ac67acb7fd9d3501d466fc0af3ee13a70116e5bb8afedbdf6fdec6333985e6ce0c36d2288ef1fcbe2e1b459348cc6ea669d99ed741bfb7581a9e206f825e8dc903e57d4083fabbdb7736e8a1a1ea9a21efe7d55b5355aab672f6eae1de83e76dc182b846171e47aa24f6e44f696374d6cf24fcfdf43983ad76be1ac957fee4c316a7d7afe674f6cab00add49d9ee01ca7ff76b61d07ce3701892e208390edc717447a2b01c8a2d855c7487c37b0d43645bf6fb3a446774baee03de1a09a3ea9680f52449df95f62437b14a0cfc4eb6f504f443af0752b986f0bb8e45b396ced5366dbc9447c11d74061436050ebe339d3f278d81764fb356a7a6ff93de945bfaf97f779f34911d9b99b0a98f31a8e98d73922f5567aba3b8a56bf341fbac3a2a3dcfb462568853324e7f4eb8c20acf35921a440e8695042f47600c885b8facbe34af41653a343ddff59794fd98840f94745b6d7932cea8a455de67dbf3a99b46a4368b616db4dbbb5a3958f0a16bb139baa15af551b40a6b0133fcb9a8d1cdd4387f23ad6dec96edea64b64a76fbfc355885d8733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddd1fe6d226bed9c7f3cf846aee457b0fcf3c5a1d7caaa49a3c879b761350ee3e9a8295d7bc687561a87841e56f37f4b4f6f77e253988f38488ff3aee9b17f57268a209f9b31705bef8aef36ce9c194ff980ad38c5b9939189a618598ce90f435232fe4259c6555d7d41e2a9a12bcad5b86cc0494fd992834426ae0a45eef5609af68b5f52913f0cc1cb607974c6d19b6632ff245a9eefa06cc6f075e85ffb0260e8f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = dd08cb516c78a56e9895f576bc8b3367f99d50aa502f365a5ab881d28d44150539084a918d43a002665f4ede55c6bb93641f7412ecd5df9c9c2df4809385d7210c8a1b4e9c9cbc840e54a0734c8a281bc5fb7d9a241f798c998b9cfcdea947c0e90ce38b5e700b2ebe894e395a2552ffa4645dc672131e7131db3b54989bbbd5569ac4cc7e43b4b7bde2ed87757f46a8382ccf1c66e868ca741f5ea554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759bcd91519aafa6a4367e19b3771eeadfd48d356fee48cedbf497714f6464399ef1f46a444ca791ab9b847425e8ad18f154bf944e6ea9ab8689410a7424b653443a9089bbe10dd83d92fd7adad9ccb6ccd5f4a34133248524f5347f2473ab1ce8b2fb3da38da8364464cbdbec62dc7505b6c2cd057de444ba218ba49edae14238ee971bbdf63ecabe6b7cc699fab7c3d4c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627cbd9f7dc660abe8a3d9fbadfba6560574bff7db4b3578f1778785764e46aac9e2a99dd368b7144e7b95e55e6adccfeccd8fe826f7935bc455d9397ff14828a9cda84f5a876a9dd909c481dfd668f9787b9f87b7604b392443d4d16a0f31ed57d578cb85ee5335f8c1915f3a17ef0dfeea291e55d0fe860821b9648df89168e63b19748a1477fa31b3e7c048cba3f87a3d7760cbada0bc5c880d6723af6ef4fba744808aae2e3742016c81d47e638b883448aee3dc6e1f35ef55bfaa4891e397989382369ce7a59a3a17c55a0af9ca4b7a67525f6c1ebe69dcb7fe01ae4706d33cb54f07836c405a4aa1d1f74ca2d6538ceb767c9948c533e837afbc7373c10c7b149fcfcad5bb515186ed98659699dedfbcde23e3ac72978e754265e8c9a3e9745cb9a87db2aecb47373e18493fb086a7a2217ab2d553d54aa431567a52f35d78d1dac702d6e1e198df76cc6f98f8b337685fe84abc325ebc78e7a98c5beb0ebeb2a5af8a768d747b6330eaf4561c7ce37d8750a5f945ce7731983b62b2df5f42fb515e47443bd5a01955b4ad8aa6385634525ec824f718e84e2bb2daad116f4ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = 57178f4486d49b9483f4357ac027b21a2f6fd5a9c2b9eaef45d9d36d55411bb3c8fa4eb75a844baa7388ddc8e1abb4cb14edd3aee4aeab466a592b77041bae4733b5f1cb6ce2765779cdf455c5536b0fa2dfa640248c6442398f48a5b8ac7b6e273db2c1e872a3e752da777eb56d7876edc77108edcd633961a5c9d5987ddf3e439ece31f536b0847d9f7f17fdd75533f9c984f08c7fca5f878f2b9720ead06c3b60f5298ed4afe2066d4fc6cb969aaa69c3f3a230b3865a84a5569f5c895c58fd19c3b98b7b2d2acb941a44b7f5e9c8effaefcab1dffe842a7e3772285de2daf25b54894673f2538bce1ed99e9dab3443e47a5ce5a9b294d08865a4177666355f37cb7b796b9582db0f7d7af4ad28f558e4d7426caa80c4ae9401ef86799caff5b4bfea5cc0473ebf72684983ec67943bc95568f575f399fa5c4bf125b65bfb3f2603458c3aeb249f5193f6b322b3dbf8a566c53d32e82f961a09386baf459c249415cc675e27722fe83d53785e2e8e7391485c7a14c402879a8484eb03a87818295dfcf8f7926b34cf045386ff6ea099f3b756fc5fcb7348bc4a2d2d7c5d28ce8e7eb77d998fda29dc41db9ea45351e35c5a4ac5ed438df856e8cb07839b8abffc851654ae0cabb3ca66fe1dd7942789b53d61392d79bf9b32d4cd7d1e9d3089a78c553ee3cf086e7d23e9fd37b282974db3d4eb09ee899fdaeab7f6358befd4a0b937a9e9e266da6ed565fbaa2535c2fcdefaa9a606dbcc8dfde3c21f3aceb7380986eb0b85f3f8a8e41608ead18d3453b58c2cdf94ab55b3abd787347e831845a8f4449b798ca3d18a5a4f183b4b16c8710fee370dde665f907d1ec76c547b11cf7913d9a39e6340b8d4775b9e9868689c19e6cc7659c52645f9e3f840c028fdb1698fb43663e4545b9695889924b5d27a41d014cf825dbb46a59ed6c3890e087b2dbd43de68cc98288a1f2bbeebd4ad7cdd880f86cb7093407f393c6af5579adac1f5a35bf09cd7a138e0b9df8298383ae7af98399bd22ae5dbe44d8ca6eeeadc75e0d1e561ebefb62fe5968e2c826c99a7d9bcad119fa559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 88b88ddb35e7569570e3b33d949f8c62ab5680d3e93aad852563e1d049e44ffa338bc7633516c32144ab0a85869d18d9b7ac8d4e4b6e6e0ddddf36600e53d8f395c1aa9fea481f66248f7c489ab73a78e04caa3f75558e5978e1417c966fb38ea85b7040de3004db91e1eace232664c06a8e85a35346b56a83e89aefbdecf009a022233123a7e85d9c801aa5672e6ea5700ffc350e6b7b3bec20b7b739ca531a2d6b1ad4ffda9ec2fd959f6357e431035831fef2dce7cbe1d4e6e5a69d5a766d7959b5827e77e7bf9b450a7ce18d969a46d3b738b23926f6595fc8381d4499c8658e8cab078bbbeb9eb4aaefa5394aacd9ffbf0fa4e07509c69bcc9b7094512f6a4fea5eeb3cd77200f63087e4b20504de9d08a6d0a3f08ccf311a299e7d8ffc5505dcf01a75bff5bcf95780a4496e0053ee6978a6397ce232bcd8f6db5a2ee3b5cba66c68bdc432be65fe83a62e18d1a3e65f8af3db0f24778a2e33bfaaed03d4a68b96b72649f908da8c554b32a5c59a839661e77c6fcbe9bfad54ebe0bb9768af368e2e6d1e136ad5b334f775c297cebd69a3ddec23a72dd3dea45636bddf42d5f38b91baf3fed98d7aea5d2d173d34cd343128d7c58d981c24e821a962c92951fdd779078e7f641ddb9673e1f584b31bbc4ac3469cca648bebeeb4582697ac06fb832a455f169e0796deaa4856241aee498e4cc7393a2c7552b2a9e1925f50ea677a7fe3561229421bdc31c56ab2cd04f0b26d40b7f83e198a581ffad753ab8d388b677e693feb2dffc5e99ff0bfe5c178ac1a178e64d4f27743a9904f8b8009ecd1acccf8e4c80df483c5997438748155538edfe6445d8df6f7dcefbc9de6261add87ee9338e7f55d84817929a026ac9c96cbf1601f5997f3e1f18d7225eef322156bb4f3f0404bb6ed29dbb5ae871ec9b274088b0d584a9e4d5f0bcd811449e622f893d6cb8f9b1ea9e19c803c4365667ef9514a49df6e8aca46b47317785be7493218a5d6f879f22ebd1a95f110d5e45ef7585b0e79fa2ceaca7c4b431d9efef4886454807b04db06064b88b740d0fcab975b5d3df74ac7ccf0f408f75f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = 5a0d914fc65434ab614eff8f12f7f0705d784e5f417763b09eed6a434be665ca88c8f3d312a9d1537bec9adf84f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb11d832308f34d5b6937afa0ec0cd974e6e39a9c300d35d5a3eedd927bd5cbf4d4e5e764a1b353bd5c34d87aeee233d387857f98ddca1348ff2ffc8ffb23933803c52af449c39d42c4ccc7d07afc337f786be7cd474f588e9dba75a9d24428c056cfad633fc02a83a27fb7e50c1c503dd4f1410ac376056933d3305f76bdd399851e8952c21d693b99ba35dc3a337b9bf6cbc370c6a69f593add18e49d88606a3eb363a470b3ee6b3f688ab2fe478b2b9255a4fb877e8083af663f7939e893a5ddfdd6db5d4f38e98c4ccc36432a491dee8217a3fdef5d70ea277796a7f74457bb6a3db4cb44f97eb39c029f3caf3f835aa780382f908e9b3c6b488a7f46676b1c4b4218720423a80a1e6a41e59577c8c89afa582a8a8b2beae009bc8b48e58d09aeb418f954460b8ebefdd4870bd0b8ed82d3c7af5ddb4981cfacba6eda1245f312a9e368295adc166be06ffad76a59ffc974e4dbd4008e34896bc40a8ca5094dde411732d8f7f9b89dd6d69482e27d4ee70c4e8576c003964f6cf6dbf7d5a202acd3a8b778b65556a70c61789dc2541a9a8f37b23096401b984c99e7459dc38437efe0e7186bc8fd70ce1574a9ce7298b8f5587efc19a4dcc1056b93bfb13a9aff93e83d645e90ac1c5e093891aa3cc6d9a98c5c3d793fbbdaed4f3b09ba6dc0fe5d5e95f2f86aa8781ddddf9752f18bd82768929ad7ae122fc2db8e8db93c52a1e9f1c7caf6fb857d3ffec11e9f5636fd50b4a89a5936f438a7a7ea03e0d5bacaf319ce957b42ba8aede408346e393d231ccd555d81ed33825076ea65eb45d6cd5c5ee73c99538a7bd4c6554fa14769e88037670746906b354850edeb8a5f6dbca4e23985d8750fb558d3c61114dc65a9a2cc4c38f4a871b1a764a27db85b6ce2cca551e6e466c88897980ad459149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a82f41af3bd12559f2a718d38e5c5659efba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = 3629b44f87e561ce5223c88cf81dd5d91365e14cd040a7937746810485fa66c4aa268aaeca53817a449354df7c75387d2a24f4243ebb16ecb8e89edd779debde4ef2ef9c6407439e5de3cba26a91e6d3e4a9fc543ac7cb37fac5f5df4adb0d67cf3c97bb195834b635cabd99992c3657d5557326de26874fcbbea8febba998fff843ab7a7adc3106897e2fafe5362de4b2dba6f78d74770b5afcf4b5bc9abd72c97c03f7d3ef473ef58bc8ca8a6ff0fca02869de2a44a85013415b6cd3f3b3d1ac06bf3d95691664c9d0c76d610e5b0398aa44f778474cd9746b50d87d331d1eeaa52be37963ddaf2ca17fc5bcaf06c59e89ff0c1e7fa2755e1f47eedcde7b584ab5b5a7c0c7bcddd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b073e60ec596b9fab99541f4eeea8484ab8441a1bfa85b481859af818ed4c9f9fea703bc9e56cf8644ad4e4b431acd7c9e54368e7e361b2ff3041439f0d24760827971ce5f328793e029b634e89fc96fc437d396eb62ad8432f79e853bc260ebd6cdbccf16958bf4bc133438280e8b28f494a8306f0365646b22cb238eaa2564f50aa37f02743bfe6f4a270cff34ab8dbd724fcaf7646a5874bc0bd90108de6cb2f5a800e6bc015c9401a87ff339def0bcc7ea5e97ff4be1728ce9fc4986b58bf934bfd2ad7d3ac18f3af8dee3b67e7f74583c5aa5156b744abe535a9ececd42873a44c3acd9d80aee873fa975fe78547bae9d1c929c008bb6e9caf4afadf85e8ce39a54c72ae5f5e92384d7d75dfcd4d686404a8ca3e410e3c92daf8ab090b5fe49cf435ec7a903ef95c2473eae893c6c46b5e35868b9ec963de5b4565461f067ae0036cad3bcfb4bf3182fca257e75170af5e00056144768311144fc05f6e44bda9ef797eb07346d88e65e71a8c426abf868a5c251caad2c4a0395f9211c6a3947d98a48b7dfaa3f2d317f3c56dcf2eecb0c4b752d04ed323caa7ef39779c7754574c6a07afb9a0a45e35d3732d59d541fa7ed66ac5d6cdd7fc1390b169ea0f19a4dd9c8fb0e9e275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = be37c2c02582a708d02feb8675a5e1c62580d99a5121ca60d81df246176ee5534c136eb86e93e297a95ed8aa7732b58f0975c4445bb00ecee6ef36ceea6ed06bcf70965e872a84ac9b7afb97b7a4e26de1335777687749e7dae319683841dde7a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59db6fcad366cf25351525536dc58cb622ab259cb3a6707d0acbd88ac34f3394f4baee4dc183be5a9144dcded345638eed2c9d06925f97fdb96e9c34efb65e369ca9cb11efce2c9af9c09e0306e6468abbb89b7acb6de8ee18ad22a98b1fe3cfe8b5bea2d4b3055de9163af43d5fd837e697f558e64caf878367bf6772351d29ad25c2f7bd2ce35922a43fefb55e3c372310be98a37a6053a8a0ca88502e8fa5607e7313a58620dd2c28678b23c7f678f8dbc59ffcf2fcf1e4ddbb3c576a2ddef13b962dd2bec2364900f5addb49ae4ce1d3a7a5b535da93df79371c93fb3e188bd0845ca950440020add4bd9f932e9518087fddb96db80063799c6e4fae43901d7cff686c8a6dd5cc5589df1c7841d13e2ae4f61c8e8eed48b4ac513a88d03d81d047d348d465f4a3a4fa894f6757be0f99e134e50852cb56a483cee8c4f3f15fc7489956f167e529a9c3dfc8256f764c78a4b58596e6dddba1c3cde5aba3dcf5c46a533647195a68219fdbd06f0c497a25e8b9c887dbcbca6c1556f959604ed1987962649fbe87e5a3667d985ba46db7670d257566844a228db612ff3f38669d322b4a864a6c53755fa9efdf0d37f7dd2adb067bdcb9e7e44033765db15dc0c363e937ed7f06b94fb7d813c3c8dca96fb98b4e97be6b9f33da4931b659608ba32936da29d4714cd43718a8ae094e9d0e34b26c6675b45451b49fac717a0e805f55f035f65cb842ea68c7b34f5b265df1283f402d852f5b7305975b5894f7d3eeeb48c9783b19c7b1e486a484e4a76449c26f3ab38ff75f814e3ab159765797d5cc653f2b454305df7c19975263db6f7b49477ac607927d6a4f7610138c8b46e4951cd6072ac49b7af5b464374a5dfc31483b34f83792db87d869ae67bad8f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = 471eb241fabba8f6435b0b4889a9403f6d52509fdcd8d875927afd68b33c3134c90f9f30b43cc744afe623eb484f7c65a84ea8c30cbde4fc74a563d5ef8588db967ce71bf9049a8e5d9feb484390a01761f495dbbd9e6af83fafeabfe1419944e6c7457207ccd12aac09d4f1bc0a4225f847284f4b306549738b91eda3a818e994cbc763c176795d1f86029e83ca7bfe2d3c8ee925937c5a9ad633d66957f4e0c6fb68369a205bdd0d1b74ad9ab5158356045d45416a8eb48483f11ba52edbee77babb800bcd67245933af37f23741084de14bb4f41a295ace13ae201b776c296140ad4a8215dbc55e4e8c63fa0848a75fac67177844beae5369fe756bd4804b28bb55cbfe6d7edf5e0ab9df7498584d5dad47c8b16b8063533b1e1c57d4ebd6f8e6643216cc343bd53e3861cb1c71f2f9b52518457056676064abce0d41f21eeb1ad3cb297a96200a96d6b3dd2a7de61008cc7d26c1c11ea00f85773afff3ebd536c61748a1a9c792dcc7362fe0c8dc6c3f2ffad7d9407975a75d3f86f0bcd32e5a655637c5b7ad43aa94d905d9623a077489e8cafb1f85ea37ec260efdceb3664e3975f0eb6b26ad4f18e4537ebb3f284d5398d347193d4e2b7f65268367312aba5c069b765361d907775c3d41b49e668da99969ce98e116530143c78126db80fb5d4b473cb706dcbbdeb83a3c8a80d93ee4f6edd546c5e06a67dbb6c94ff8fd7e1b963e744984b849865af2d535cba94d8bdab3854be3694515af4a58a4c7ddf0502edadf1fc0821d36f927e636dddaf7af96539e4ff0dcf3e0e67e8417fbb1b3a02769eba96959ef3373a4aefe1d43ad63449ec2f47de225767b94417a0b918bd83abf4439eae3d90ee872f7cdc5967564da6c4a3bdd61db656f3b8caf970a69052fb914c599fe6d6eb2ae7a3b3fda1d86b8ba7343e1048c1d53f8aeb57215ed77246b742119e821d6f99a4b75fb1b9fa124c7f5b3b1f8938ce9dc7552df5898387f5a86bc9a1c49fc8a7c5a0fb8e3aef405a592a93fe81667d362c43589aa9ef06d9b0207c9e1f3b564aa6be9b6daae4e93001ac4f6756570d983c8a8fcb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = 6aad47a0a46968f3828fa4314fac3f911a71a10c866e8cd35fe4cf00b9fba957ea735b808117722378a87a8dfd5a7f8d66f35d53c34bf5797c2ff9a2f56adb2cc873d8063a8ce7914eec935f65e74cbb54280fb1e7736f512e5f7b1f77969cfd35d7e1653a8e4af95115c9ae34dd349d5ad9505ae0cd48c77c5eecf079a497a5785e39830cc8a189b9bb5699e249d976992bf3a4a7a1aff34f3788b148166c40f381bc67d4058339beedc192e3d7515a6a8fc5747b1d58e394cdb79c4142fa5ccf3780f254a10c77e543b63bd8de92913480c785e7513cde49ec3fb9dd3ffc793e7ddde1262f6fc59f9c8c2cfaae0efc452746307cfa9c36392b33d45888c2f427db5efad7aed4515b8e9d7c5749b35380cefc976c97f70b1f37d6f4ac214548268a6da769f8e0734eea7887abcda2c06f3e1795f501556b03c662e4e9c42c9e4923b88d5037e4fe53373904b91598c8d7c6b022e5367bade73fb5e1015d39d9ca5c3dbfbd5fde404f7373654848ec436115339db37cb3549ba77237c244ff5da96a4bb4a8b88e54e693f6a8094db0ef7538f8fa9b71ca736d08bd3678c4ff8c480c1e5452c9c8fce5f52abe481f9ff36e5a311b2d4bb67ea89b0a60749ed1b56e7b033ba2df6c7967cb7b802e8aff886edbff464b3ae2bf244bac9ef731f46200ec6e95df454875de1e1572e4a78158efca569c3b157fcd8fe98459cea5ab8340f3b9de5a854ecf6d469698cf85d88739cc96ad07d58cc584637a408acb79980a8dc129d49135795245748683ac8f53b816ef9ddcf5452aa5d4e00aeee994de4d489810c35a100687bbce8e185bb53d499d266a8758c68782778b533bb9e6be6ea833309a0c8b3e74da2d4e7ad24bd1e38ff0a7e9cf9bc9ebd6eba10c08acff499296edac506eb9e85ca75185af845c4f443d652f0df5869ca7d3d33cc188a65dfe7aa645b8dacde0f389e98f3eb7ae448082069b33ab6ff4af35ccbcd81814b6e06368670772207dd6eabc91a499991576e427c85979b93de0ce4e24176e9c035983aaec1609ebfef473652480d5bff61abbb7fdbd31de8993a586d0220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = 8c9845c02ef1a027fc9924e5a6456b7e7d8cf45a376e689e8c74b1dd589e2ba95d1929fe47937b648cf1bd9a518654e13f44877aab626d4d843b078e9a93be166c73773bf90164c7ca1454f2c3e0c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae31cff67aa97bed49c5eac3a9b769c3a9aba51e98fd0f5984cd7c39a3eee36fe6f7b4bfd4cb3da32e0ad3d51977ec2e45e6d9e718ed760f8949caf6b928a59f4d7bf4222af91e0d8679b4b761178909c83d4c035de424c2031e71331edda16dfb75f5e706dd7da603526fe46f518d7af33593b0d59d4b28b31ac48ba7ba35794be94224a4f7577d4a7664e54ee841b3908ba572937f8a428a516d96c9061eac6b34673edde27ecff3b8bf7122afaaee38f2744b7f23969cf95b39618f6c0ab4a1016debb70eb6f2597339b4d8eea5360b9c6b753ad3d648817654a35db7c5fde89357dbee45aeb800d99e8797ff96ae770907fb2b6dfd909d8cca15a22c14691f2e9b95b9c3fdcc3fe3c849efeb9cc0ecd51f55efbad93ba46db2dc2370b50dce74058dff37d7580fd703176ef888cf2caabe2f8b337377368ba7aca723ebd6c8615f1de7e3cfebd5b9b029085ac668803f66798bbd60104ba4ea3d322b1452be0be2c56ee2da8592fc0a74ccb8a755aee20c2bdc1f0cb0a1abc7386948be2bac6bd9fc60944ac858fe5b5e9b3ff36df7ea5e6f939b0c1b66244fa08c6d59658448b65b65c53fb28fb66b92594d0d8938e5d3a0d6a99c7c3e73a0796e02195e85bf8da3bd6fcd56724134f0c916c77613b9c79d39cf1c6594e9daad857dd319cc9bc9702fd452ad455d5329b14bbd33a6aedc091f4338933f60993c368343345fcce6c484f0bd72f59b85a6c4d2d475fd920e73cafcfadeca708bdcad9d996b61ad8f8d3e31c67eb5fb0deb4b65565b28f98ff8c6b3f68e77e768a2cdcc00a3e5a4459b0b29ec3584bbcd66f862dfdfc9efc70944b7eec84c7f4f7f935b5731fb6e42d8b40c0e395195f413e94d5f0ea04405319b7e67b8e4cf648f79331a6c3eeaedff9cac9aee48bda370c3edd715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = 5b5b3208a4c987bcd2199a6c057376e3fee016cf37c0fe8c63b7302a7d52d7b9a6c8ee5a400fa9047cf3e7d9771125f4afdb42fdff4526ca4f17ea597a26874e333f40e840fa3c9911defed9d864265fee7b585fed4f3270de618dc6ec9c7ca728ed3fa87fcc9dbf41166cb40e3e48b4889ffed89c8b0b772f8d7a157a6ad4bd67c9f43c675c69890a71b996a3233767787f3cc6a4bd240c40deeb93b9b6ebbd3d61789d9e181636354aff4b4bd2f92da9f94ea690c5da75fd9eab73ac4b13689e26798334eb3c9774c437d1dabc8c316d38206dc5926d8431ea91f5743362eb86ade7dc93078349f4bf4b137d44ed6c6258484d9fc84585f1d559e5c96754673a4f981ca7c1a3c229bffab44a4c1e2d7988d8a49925724d2e8efb34c1afd4b56dcc88167ffd0e2cf06a9eabb6f5da3f8f99d9fae0a8b5c5611455378a5ac3be79c755d18a7ed28a0e71f95bb18e3fca7bbdeeab1bf72df4b77c6377e9397f8fdaaad0294b59c68608ad73a3fdf1ab9beab22d5cac74c4bcffeba80b98225a33b1fe8b45b8f27c9b6e18f9c25f6b901137a7912ab148849229dfaa375af61073307127c6b09777fa9768c193d67bd8f1f3d77e343874874f88518ca21ecbf0628f8c0b6d340f3dce8006dff65f312afe8bed579625e9419195d19c8cce2426f384cc6eeb7b5f9ffe725ac6d34db7c7ef0580cafdcd0b8ec2236c46ec9a3225593e3c1e939b9758556cadd3f9967de57f21db4c4af8541b4b813d77e59afcc69dbb36d3dc470b8f9a5d87edd8468a21356d40d8df1c156008b3bff356962f84a48a14ef4e5bf9b727611176d851f7ced28ba0cccf4cc73e942c9f691e386bd82af8f66b8d4306bf89f36d0f0e5542479f314ecebebbfd8e95304795a31e6cae206b40189b4823359382393baf1d57a62471c5a3a93cc874f97cf94a6a4e00e6bbf8cc4cea38d943ddc43729b2586d76e73b3edffebe7317cadbb58db2ad46b617800d5ca0e45fb6d41ae6303c59675fa4a32d9c5d7f428de4b0d6b6821eaab1f78f4cb36ad4e067b5264359a9a6ce8b4af6259b61381da673de3d279dcab06fc5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 45c8343517e624067d69587335b97bf564929709c8826ad04c0f8ae09c40981ad7e8d4bd6055f7ef3fee8bac67d34cbe763cf6df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367e3e53e56df498af09c495fcb3e8862d6a5790d865479a0071efd8207f22c5df84e4ede01bcb11f2ffc1fe3d3e54e807849a7ea47976a99abb7ccc4b674ad66f68eca19578abf77d23c3d67bc418ca7c909cfee53984983cad205e468910dacea7f38b3699016fa95e7a3a59cfcdbe813638527562fa9bf10e7e5e85d5f6e2ce4346fea918a7df52760a0d8a9549569f118f7c423cddf08fbaf0ea9021e395487b9c82b7b5a7978d789679e66b75087bfc0fd569fc94e94f93531c7f13169f6388431f2a36ae007d2bbcf54befb437c58641d4560c8738a9803da18945db0a6900bdfc2abfc3e0f4786a4555639d84dcedd31d9fd508d8c774d78f98bcac4f42c6a7ff585af59efa7d7c3bbc4e727699ebc3e5c438bf10e4f626ebc66c916af1f45e53753e4e404d409ca7289c7bc51d3d1d828dedc89fd4dd44c41b77bd47a972d8434aafd3bb3954236ec422cedc8ea9ea79bff86b6a7c459a95ed44868ee8d52f2ebdf384e710228979507cffa6e56498fb5ea19515ffddd657c7141e9b05faaf4137aff9166f0b664404b5397cc7842748973d17e6cc273b528e5e383a63fc8a3c4a4bea8bc965775d750add6996d9f9e2904ef4246fa759baa76f5a3dc0552f1d83195a6de45837901494a88ffa6dc3b5d8b73a9696ce22aadc9bdebdb2d99aa350c6cac657746ce308af354e10595f378fa34ecf6dadf8e2e2c4634aca75e9438480dc9c07bebca348330bce791fab1429d99d01f88283bab03dca09ab3593cf3b12739cb45cdc04c6b93d1ea831df6bcb98d7aa6aa8cbec64d749a9e47f851c47c6538ee96f1fcc4d63b67d29a58e86b9a73ae99cbb793c5084e5bbbf0be1ff89b4aaa64e4c119488531e8a651b3e750148e184fc5390bb9996ce2403d56ad44c476468ded4b88a59e30e35b4b018d3dd257e8674ca708e436d6ce5ee1d95367d6f3512653c84bf7b41cb308f8c292abe93b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 02d74bdad5ff6b845eba516fd267b773ae90837d67262ac6d9f90664bc11053b +public_key = b4972658e5844dd0734f91b3d6aa47b8676410c376e6118fee627dc4cc3fc0a6becd453e29030c86b1b74e469caf364135a7837eab72c4362b97dc666acaa61bfcb29c385ba4c79ff9e76138ab030439c4a2e6572dfcb671f82194ba8d438c4a9c5aa066563eca0102ea634bea5667feba5f0f7ab063f27985ebbf6d5176d615311a6752f7652e8aafce143bf75f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 6568e05a770193224909d8d8c972cfd88e13b2e98f1e32825e500e9ec1ecd4a2 +public_key = 5895a2cc3be6c5740445a0f643af112db00285394ca9472a988be816497a32d231c8d8378d58d109d941b511e708e5e60045eb08a43b85a4a6c725d8c7f4a472fd746f26f68ce7b78b726304be81624bc88cfb5790ff181aaeb7070a418bd135851126c370bb13d526717b3a66d651af7977ca756141d27bb54c08099ba45b2c7136228a9e817c5a7c10024e13a016a111908c79ad8aa00181bb2145be6718204d593bdeb11027643ca621a41b4c925580826f09b76ac186bc0c61a2f99887646ef6a786b899b279636aa1466f99bc74d7ba9178859774957b3b02a6a83138d0493cca8c1cb198bf47c3a036712d7405254933b774db5fc0a3b0ed556506d798effc8dda7a1c11ab5828a12480e108f83a234a97b402fb6f90111f8bd3cbeda827b4e5b37583b1dd89889ac148adc03a33da2346d616bf3062ea09ceb30921f0d7b87ee19a397c8b6f139d023b0a90a40fef7b7946c975e907610bdbb8d340355491 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = c6aabd06a84f8360a7c287be71e94b631754f25c749961016eeb046cb181096c +public_key = 3965cd93d09cbb1b59fe419212190ddfc02eae25af871bc28e689f93140204b43735418fd2833691177c9d452059a218 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 09e9acc8fa7ad8ef00c57ea97aa9f1ecd44fd9c6d430ae64d1c1882bb9908fca +public_key = 3d914395669cc394c0fb52a01fa0503c5a61c4ac5aa0fac494067f11d44f0247a278723ba9f95b3b938280d572159b26728848dfd217724c25a5dab5413c0c26c38751cb67ba856c2f46ae1e2467e7012b02f60af55b5290f5c1dba3610a5b523f566d2f7348a6a38663dca86f32338525c9543aacb310ba8bf82c3bd545e9f26991b030a425a511748150800b8b333a09395a3f3891956297136a263612c81155ba887c78405820fc8cb7f70c8d8242726845483630908aab80ea16a78c161a7cb64010b0b290c94774b51c7d5597ed633257db57abb2cce013cad6d136fc2a0e975a572230074fca7bb2e0c8107810b241 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = b71fc6e4f3b6fe6fcf6f1618b13f0b793aaad918fca4522d2d83ca7440629241 +public_key = b5ed032787271eec411cc9d09fbdcba373807977721ce0132f1bf11ccdd98db9f79789f6b338600547b21a4bc40e8829af182a741391bbb4919cde9659898610dff638d1660b18f41b290a01eca424b14ba966fb18bc7a58b11281b6206a2c2567dd7010af564bb8182517d6b272fa21fdd342553953acd77654b47d7b144558a808d12a1cf75798df7ba1cbd8a4ce08 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 3552cda54c17721cefacd8c386a0ea73f235ef75ae427e99026ea72f605163fd +public_key = 4c5a46450cc701db47a5656c52b53a5e97d47f7130b1ebd9a5f89511c8a1b00b580e99aa25671c8f58c469b9c4a717927e6fa55aae615dd9737da61b0e1357629e9807de7196519a64f2278113a0276ad6bf50cb7a0983901fa63e00699f20cba8e03b4498d1ab38e69a5615b1476a121f7b76dec5b0eb720b56836a58 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = b9eca4af4306c65fb548a20d22d5b2d2bfae6b3b0fbbc08f9ac4c351cd386c14 +public_key = 4c3fb7cb84ea70094978b98b1e573051dec4c712e216066b693a463b33eb909db5139982cada102a3cf36b8601c97f8cbc9b266bd6070a8060583c37ce46e5b5c979543a148ebf6c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = d8ea98422eeeeea770d511a321eacd3dbab41b78eee5c750a3a7559315819839 +public_key = 1458387da15015db0b7b27d6b156b43cc50381ce0761d77803d25a447858aac71614b0e946a656b08af164af3c4a83c12c3745bfe4418fff5cbc5496a164e1c7c654a5a8464932328ee60b962851868d77b697420686e091c4831037aa3ed10b66e121b1408b372939107716c819db246419bcc664345d2a5fbb549c1e06183bd64fad5c7f94bacfb04c05122a92260cbcb5f2bbbf370542990716c94cea81c715daa32e23832504509e29c513363254dc82fa467c6afbb7ae2b58c4f1accb734315a1728fc405c60ace92e00df5029fa484c3408a66be677e3cd619aaf17d8d233422232041b4bdf71ab0b9114a193834fec827bde4780b4b2722b8562bf783aca366bb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 4d14f0b1f817f5fdb0019a92adfa4126874bd973de9e2fd5be756f48f60f4d64 +public_key = 083335474d934465082c4b3fb8b9c2c182c4b244886a79e0bb00a0c60303d19e03c10a62b01c1da4925d39121f824c2bb1947082505671566567bf296aa334992174d710fb4055b7c57d0f291a8bd7032d063594a94d4a86b272e2330fd742cd05ab3f942686369cdba91aeb0b4f552a7e1a1ccfe8178e09570fad4417dc189bc9f18ae6c1618c639cf4db1e8112506c333f58c04045e0995c084523ba84d5f8a2f2f6253118b5ff6a7c0f55b16777bcd0740cb9183162f64b23d65023112cad9a7b75711782572a441048cc4a8322e046fd457884a265bd1136e7416ba287bbd16b3c513a66b4137517c02930b6ac4c46750d3920efe04fb859c034187211ec69d4a6aee26a4868a22760715ebffcc68161cc48fc9d02527cc8190145b411e3a81fcd0c78727490f8e39931685b7d9867e4fa713b31c573618bf799a0293776a69a6c72b39d4fe02bef5281341409d89044a5884b8b57a09f706eaf26c56634c7b29c32d1e26e4f20b83cb27e6f5c261ac8866aa98f8f24cdc170211d842fdfb118b0319b43c513c86a0435c1b219a46fd4a966da6bc3c5b90eddd570ec475c687c9d81e29a4f9b80af350c33a29b60d75e4e5b4a784c77563b68f381af10a05ffdf72cbbfc509592aace8836f0163da6c903953c145b2b164ce32f83d68ebfc52160e0221a7004d059a9f3b6a371d16f2cb318496a56b56bb8972b5037f3c27ce0b4c8e9c1ffa80da5d376 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 3826220d1655b1f72048497c7334e333060c68f05f9a3224d8c1dddad7785a89 +public_key = ce290213eb07676a790a1147bee017c913333a8b096be74c522b28be5d1a4b2015c22b1c8315819407515dc34ba4b9ec7b8b1a50329311f7f4043186af317422fe4708a5cb3fbf8240869072467865a423ab8804423c053f0a892bf1cc6eac1092bf360d7e14127afb7816d003a754247abb25ceb3b9e3e61a23c3488e041d8bb1aad92a80bee618d6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = f86a930e66a30ac0287193e503fa500d396c583ec5cad139b5e23f4f29729860 +public_key = 283c0a7dc3a43bf245969a063e5031e0632df0e181a20512b2077b56c84a06739af8586d7249b5138aa035b06539c86ba2e270e8d380aab5722ebb8cd0ac6f7429c3d8c566233a401fd217bf0ab629e11d575bb68b6a720f75652c181863871240109e0f188e94b447c0b0355b84672158553e2049fc6376abc6c57f308f6f1ac18f5c0bd3321d2fab676a708fb490af13b72cf7cbbb063113048b1add993bac9765610703ddb325041822cf7a27464155f87722c3f2af78f87dc886aead6907f854ccfb70b56bd0a981aa6c65c0a1f0760624588df3322211a89b62d6468aa845c3209d0739cacf17cca85b8e106c098b91b16aa77804a729f998c9b52c71c29647495c4f56b58d5c568bccd7acf8e6c6f5426dd93b6ba000d0808c1776916f4790a31b7bc0e77c629ba27867c3bf607a31b412559c3251e72706a3912d4b4840c2f309f1c9015ab1b06fc5302c81880d011004000dbf825786d143f1fbba9f406627f4af43fa497723c0f300332d4a2f0f760fede4bad2315b9dc8050a897fdbba949a1caceb7599d05358c74555d83540f3254015953ecb293f9bd4ca935a3938d97dfb94c03bd05a46b846c0787ece2b0bf8a791db21b9a9760162508b4e9b8b1780b3aad14ca573127eb5628b3218ee8759d3a61ce00c8c71f949c3e94914a3173fe9503665cbfef8580981087a17083578b32e0c4abb5a9805d3698706430c903fb9d13b95178dcf7361435a987bf6189aa6597b5416c5c9845a6ba92cf6196094560ae6705f822e40d873a73b204f581ec0b72caf33254334b1bafb35a5985aa4299e55db5a8e688a703aaac97a7de423b9fbdb140cab438a3abddfd185d88b03f2aa724b83830e7ba6247727f3943a29b361b6308f83e614fe7a1917ab8165b57163ba61fbb6bf54e60c9df71158f451eb4a8f16f36442bc6a5fd92ca1f9002770bbfea6147319bb49b12cfc1b56698c7693b02772a84d7fe05bda687e8ee335a93b0a7f373e669aafc1954e5847b07ad19f5b2784dde8900fac6395f32ae8c8a45d35c191437031b6783358adc8a174df052cac8bc12454b425f82c7a3773c1f4b970b4a4ec8b7a13f9c9e9cfa24d7affafba69b05b1c4aadb5128340233378928c25a0d777e8d207da8364d7d89fa6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 4f35e1c42022eb2bb82570f3c869b134e373dbc3e6577a1a433bbe2e4af2eb57 +public_key = 0e193eff585c49faa0adf468bca229ce23272d37760c0671f233a4b060cb167c3ccc00786b90219f97175da29b4d2216d75963e53766bcf96256a128f4225d161b98a839c34fda54037172d41ba135a7430d7398804832452b5b2806b60bc34cfb952dbbeb19c763192b2b34727679033b21329a1534b52c94a409de2b12308123cf45b962849e9a5a3799a903a7d07effa3977d3242e8008e6e502d74f90b36189f32d7440c32baf86c15cef3b5a8ca9a4166c731d2c139f0406f62b8fc019a940a33f7cb60cf673bf62a2350909f3e1b56f9f42a79485fd2fc1bf38005c1b90fc61b7cfa881c07805fcdd42566291987a7578aa95089330300e12daf1066425bc48110042116b156321c16ec6d8ffa062df6bc672052e4e30e996c4b8d339c49f4253ea31d3a61b66e372e27e16e530b3179154a94e5601f122881a00ecbc60bcb3a4c4760285a3b1d3958987cd6b0e4cab37f70a7fd08489183469f504c9faa4f7620b5bd95899ca7451ad482c11a4c9c255ed5aca033516678232db11b6085eacd6e12310c543bd6164e14007646749ef7864b037096b74448d9db7cb8b621463cad8dc279a1b82abe526356bb31a0194811c04c6ce0b87594bdf09876487791e078176a8a3ba0f8b0f22cb31b333920e967604a4e728a6524b9887ccc083882ad72c4330ce9abee3544aec88e40213aaab73a091c8ad310256854c2a2dbbb58ec60d349527d5bbfb1641c32f9673f76be575601ac48936180385243c6a49709cfea95b095443565328c543eca8a5fb9106bb8083742138a842a65ff655ea089985646a2d31975a63158a0352b304031650016d7346cb3778277212ee04c604be681fc075f3e0a903b08ca975a4eef155445283a96c1c9365c4badb41e52c9727234449ca189eb21693a41992637cbb3538308c27c9418710e8c13bf718d57e68b86d74b1a526f71ac2e25c99bfd743c2fcabcfa7370cfe67b045504fc328db7db0e2d3528a903820df29e1cdb7247bc691b916ae983454f2645a64c395c9bc6d0b2a016f73bf7e20291196ce7ba1fe8e3ab6e73583dc092e56c07c6aa316e5e3654129918f5b7e239333bf49a44ccc0283e7f8cf86964afbf9239c6f8175f45d6e2de378525f9509d69e1753076846c7395402cae698f8de4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = ff62fb332aefcc7e701b69e43dd0f9f94ed7c13949dae4bcf40a2d84286e1fef +public_key = 66cb0d84c37ea7c84b8aa590c035289ee71827da7c081a1265182a016ac85560636e950e83c5827f45615dbbb595c3b9ea875037768bcffc7ba76c11517c1ce7c2bd8459053f407413d4542bb29614202fefc41875802e4c42c8ca61a1ebe4286501619200be88913f4f5bbca7f4308590325bb087600603ffa6a0a74c32b3f5cc091b6b51986a01823f5f592e56231cbc1ccb99525a86308a5b43b43bc6cc26aa8a6572a26a691600e810790abdb989ade67c1685c42aaaacb2c349a8a1f8195d88a14191b5c7146611795cca82549eb231eef2ce04fb4433998a29257af4b08568a5877b7b39681c1316595a4d1b170f118e1e571f539125b5b933926800003c9eda6777152cb40486bead80108e78c9252576563b3c299549b8b9817008a9d3809006834fa45664c82166cbf285185097267399ba9ac53007b41bda7f417465c1b8440b4bae9f5c1a982376ef8874f3905a8e661f53f94069a9449201a649799a6b110d888933d616615c7a9fadf42179338ee796b337b065b29a995a93c5b0f3693169684ce431042077362c96b675bce296443f8c44728aad45f18b88935065c0741ba5312e063301972c55f94d168764d46c278187bcc4fcb4a14b8bae174a2e74943d7bad89ac28048a3bdbc46598cb2101528daa11c017acb3e30077c93739aba73c9cd073cd0706a22baf88105c64c59b86067aacda6bd8c1a6d5dbc55efca5ec793d9ce461aae944d6925c23d45e9df5a8faabce98d63fb33b6e09e015ae9470a0227ef0a3399de2cf595498d246381d306ff6474684839b378ba1a2ac29ff0394d61702415547f88a8fac1ace7bab5d8f7304b8760febc3bb0bb8aa5ae15b03c2835b3658b86a17032a149f8bb91790adf6b8b9d45b3ca0d3cd085b2ae6a10ce6d371f64b97abca44930aabbb78b528352a9ca62a98fc0c43253c7520b766620e11b657d2da7573d09fa1424e89e1708a191caa43b0f449c67c674632473622220e61a542dd746364a5188ba55da9391afc9281e1613ae68a3caa7125003b1f0543b14be7679ff393ff596013e25ac06a3dc92b672c1a7e0a39322a59a567456a7db1c824fa009a075e87af90eaa13889881558c7204f1ea3b0c2ac17 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = ebf8fcb10f967ffbf2a35c932aaec042952e106b4c306eaa37ce8bd9dbc65742 +public_key = b6c3cbdf5713ede5a1ed235670612fdfb630cb619eb3f0a886264255cac7b1d299a1bb4878f7c985e1792b628f2c08c6b491ac949a7702622e318b6f7ea6b99c5a05f2991f48964c5a14480ef42cb88b7be1790b889c4b6044b885a80429420e92794d19b9aaf66a5638c1362c2828320cc73c2b66b6e64fb733b4e68b526c5abad477721281a2459b7aff1511534b5bbde1c95d640447b134a37407705951ec3c5e7ef7a14f113cdd310c9f723e885a7bee514e44d7c43c6bc13e72aca9718546541c74ab76a41291d1587ca22c7362b07b6dc838070cb529201ba0cb4dd06acd76fc877d66c97e6188ec50b57dbc536624be08d7cca5683b18cca7ac563a76e413f1fa238e1b8bb6e1b1fca661e1cb671cfca30585bc827b0016b833fbf4335fe9b246b18916e75e4b32252c52a3fa43a0935545d31aae739811a8ca28e8f540ef7a5d119ca0211b785739b83ff5995769ca8be8a2ee24079d425c3b7b81c517c0ab4b6f11e026323cb34d5a74c141b981e707ad099b6a09028ee749916a772a04b03ed98700321bb80508cc110a434c37e002d0f1acc84999a3e2d42ee914ccd5a97caf628d443697e4eb02b1623411cab82b8ba0291ac7a58925b188a8148710e4356995199376e584839c336762bf05a38fc17696ac8b092626a1ddf125f7eb79a6959cad82a5c2cc9ac9ebafce9399ec8a8454c9ccb9fc081a20bbde32a071babf1c10aef5a24b0b264727252b485c6040aa7c38a03c51f62e4a53a814f56d18d5872ada426ad4501475a05486b9dbe8c2a09c5367341361e62f8777505171326abc7b7e285586225fd1d80191b2bc30495ee191760f88b266f19db8b14065847db81754dd1691ab0bb7abf945b4a75b304a170a49bcfafb5210d9813be45e6113af06a71a7feabcd18147d18648aa966ab94a1006c178f0b2c5735997f1d4502be1570a03a6fe1793dedcc4ef133f70e75875e2618d10a4a84555c8d23b70169ae3568b902b4830e9295c939e0b340b0fa2164e46354c331a49b70345eb5d639b1d6f37b9c70707abe850fbd03907685809cbbe8a54b381cca97558c0298e02cd1a2144644a5cc97b7270f68ca2868f22b38cb36316c7e03180109b5bf5e3b344d583831995000e543f9064af929fe037991b2ce4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 294a685e6699683d3b2dce3267ca40914dd078b47abcfd1ef39e3a3b629af9f4 +public_key = 1b07772da771c02948a202cf918b4cfdb335edf54a3ef20f2737b137450acb824082838dfadb2902882333f4015589abec26492229aaa818421df684a4e690f47a58adfa205f06c7c5b24003aa988509c7d2e01719343286dbc567fa353c441dc5fa040857c62aab5fddc8490cda2e0484a042b077326263e158b598e02ed6a9766a461cac19a25e080f20d6a136c05898d3536ec38b3fda9ced390d2ad68fb28c87ce06812137a54fe20bb8502dd34b9a8ed39a5875ba2c1b918b061640608903a4c7d48a4c434589959108d59bbeac6a3dec33c7a79371f31bbb1ea19a4350c1c7e5cbcd5447c3a3944ac32326748ffed5a586d0aeb5f17bb7939dd85082cbab7bab61b4c6ec3c08e1680ad98db01b1590799b81aa9b4e6669c05820b9e7b365479b385747a735ccb8b25ecaf6204c766eea6ab63d8c7e6f64b7657a72d17a318a9926f8299180b10b8e9ac863a61c42975a1eb25bf5a9188fe871ee3c6118b629dd37673260ae88c2710d43048c138b74a401b588542f0a8752f52532543a335967e3877991525d704ab95821a2bd12035ec028625b8013eba56ada4f43a37896b75685f5cbb3c0ad58548be33ac18edb21c8c95666a78f8e085c26e4cb3bf59ce005cb5d09398c700a5302980dd7139253992cf5c66785a1e727a3b1e9c2c9b84ed23c8d51544e02603f050bb2f5e25df358656275a021d91a99bb4ce1a48e92a94cca8391c33bc0bc38233ea69642ba0e12c123705c1678f0bc6e21cdd7a2af49d351125415df56817210071b976724040cbd77a47ca31629a1a49f6a3fb9e871ec269999d51b09d14888104ce63c77cacc973d40ae8222c80d521fd2f38fd862216bf46439884715a0cfe4c073f3d3bdc9a91e8824754c8933706a9b9c5573c105931e13c27442bcb9b971b3f7829da50ad1393c669b4439c183eaa956c4f79dd2256b21785d6bd650f37166bcb03cfc118b7bc43dd7085198998799696afec9a0e760c93019605e911bf6c1c946243fa3b29f65d39f74809689b97f773536a66b0c5192517c366b14405100974fa9a470b1aabff3412c7c1038baa86b23ba121576977e0ca1dfe78cf0600297a455bb9c52794811693e1be96e5bc82dc03c896e3077ec94bd170c4a53875b446efe6be4833f358bde914ce1e3dcf2df +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 94baa5fab54b1ee5b283e7dc4cb5029884b5176c5551ca3b05c8c88d450d8506 +public_key = 1e4ab2dca34d033a8e9cc2071e7487f6ec159f4065cef83b8cb011992bc5f995bc810081c2728ecc1a6062322792f84bc2394d6491aa7de82b3a99c1d82bc49eb9457bc87825d3a11b613068c13d38521b9c871d1a1b688995bf54cc28311b73aa900b4ee3c0562082e4e76cf94919dbfa2e454073b84ba7584317c00156a26274fd0125c49cb9718b52043c62691800f4ac1299554277d441c7ba6bb031297f95256aeac3095582ed89221a2c5e4a044b0c5c9c64d1c1aaaaa9363aa0de212acf3abbb0c897277c90b75987bd5c27270a6ca2473903e2bc86c12949f88696003120d7a394ec1d92cb21ab473752043f09309f36867b8b913a88889678a54f8964b53975763259a9f2c947d065bc4c164a492ca6d37c6d1c258026b46374bc073193162e450528a21117828ce288a98b3089a56a2fad2767617c7ef7465a72743881532280c37321184248912199abb4dd3002f28872e8944b28e221da7a8e76806df1a775e0c2aa224c46ed7a2f91fc30d3d865ef9b58df409759a61ff1abb9da71412d68379aa980b005942d94264492146487a3bee99bbe637e3fe2307fd41b84b9683b52817f32532d9941f494751a797ebec7199beba0a6f8abeea018a342a6725156e3023c02c324f8bc028fd0af207b931ccb2e04d0bd42a03c247990937267fac75b52da3512fbaa8bcb8921f916d13b1b2f1b637c13908b51037d1c0964a8a7554730c9710a4b42ac1480777c886b305cbbd5d685ea909ddeb68a8b1323e74665d89ba8bb563279f89aace64003e16f1ff4b589a789e334b52923640ea417e4f01e56b7190e6c68c9464c41d4780b55903903a04e124933a0a595f7a0d28405fd527ca8ca455af6b29236605b34463fc01d0324832101066f807c77541edd363ec4f664068a7a80e269b7c46edfb4566df1aa6c63642c147929a323983627d103a3a7523baa1663bae526a4651fd1e814a9d41bb5c7896c7a168b691549a10831582bbdfcb4e51a4ae3cb0680f9a940357c567a2c5f34bbd1574f318883d2eb0e5ff38439353f4b775461b52989a17bea8862f4e1386947542dd58a1e9cb06ee72a646e6ee888746fc0dc09ab35403a570a3374a399617772fab100842fa40205d0cfddbedf1d826362574ccc97dc5dfd6e5084bb86f5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 28b279f045cc8010e8b47d2bedc782a373a929e3f038a4366d34338fe10f3ba9 +public_key = b1ab619173cbe6358d0c87c8e790bc2bf9b7740acf1cf55638a6910eca6499276545773f7dac3008a9c6b45a92f0419ce6c6b446ac7702879fa6945b93a8374ffc1cbaa007a43a8aa1643dc5166dc52b8ce2b87dd10c0261921dcdc959a2660354ab3e893c18793aa3be85b45697c61cc30731b662c316a88bdabcf84509583cc308634afdf09255ec82f2c6190834a298303d05395724ab0a96b46e51d504def0b4fc6c02ba0935d1d4cfbb6c1d1a4caf0f3c61051595b991a814c421da534f46a986d6150df9b07a9df9b0fea027d76b15a578806ba85f5fa501622423dad1982eea191526430fe9952438a654d4723046369257c6929b993c59bdbce2512bd4046f97908d697120b3afbc2a1ce26a0e31d15808508ab92b4ff12cb1a438cefc1a344a00c367d35d7c0b96e2a074d79b4e73d177f2c46e82e7317f749902fa0a5803b5b4a7822a494fc497189ba7b4a6a17cb25618893c57a894c547fb2dae658e3693b41c7823644196e8481d78b825ccf5966e9519eb7ccf36a8c6de854b17aa62dac6bcb26567242c8af60403e1839c8e68794ae930318218cba02a6c843e6ad08d6e6bb07cab43d5805da33353ac651303983e8eb4cd62e67c6134c4986ba8288b63002128789c79fd3ab86aab026dd1ae77a41967b1b2015a4274cc33522938fd62872d024e18585429db9805e72fa3d3ad45fb8ab6a97dba024a51d66c32cc442df6c6de927add344783b19a3b846c86fc117a10225fc86dac137ba815481942b76a234c0dda8983856d8d8a863569cdbaf53b2dd08400fb458a626021c4b67124baccb92a0b64297c0a48dbe68bb95c7a54a38e752005e810124fa4598848be8242c0d1cb08e2525013922732ec45f300a56a982597c5a4c36cc99ef85737b5ab44ab81475b3f0164509df541cfa68c870cc17d81954d0b2dcc7abb1ab8a99cf07813d046a9a1b2ec071b9f63bb3a3358ec236f3b90862e4190fd769919f56c6d599c1fdbbbad4a58a758a7c63b2bc4b74642c9ca67707dfe1a58ebab939254c5d3f04775b08bb8c2a0f5159b457c4545e5c82c0ba0b63b293bf67a4d0186b0d72f4ee680b0f3fec79c89cf1c4eae7c78f3e59382fb5e98261bc9250fafc86bccce5579ec270aa064e583f64f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 74bbd6091ffb76db8fd01280201eb2f740a5a9623b8fb3f961c8388de6d1f7b0 +public_key = 8226684b754e2453cf58980dc5ac1ccb93084e3aad29299ad443933ee39577080820d94c084a8d2e4c7629f556c0190da6e0a739615e270146768cbbdb7a6e3516909691687231a5880a9e33dc2271d3b78e295d3497223597bb0da7b6f2f504d01884825ba5102b89ad8ab026484ea9841636a76445c4b12e9856b4fb153e9503a183bcedda7541e8863794a2ddbac0a694c732593298460b32042f31c74c98db902bc9cdcd1caaf42041a9403d299cbae4272c0b80774a8818ab9943725c8bf7900824f96cce9671b2b1b3c62a7914ebb8a9b88ce2a470ffea00feb82284308dbc8a627a19891450c6ef80bd4b0a06d6946268b3137653c3fa92332b04a5356aa2570ba32e716ffc38a58eca46dc623c49a1c443813f055bced8dc9262d4cae4b4a6a3ca39c8993b379427c27284e3e38af9d9878b59c313863807076201e1794ad136f8aa569dd61e6a339845bc1d597698787190ca2a84e916c37a7b635902795f663b2049274cf477738627bb956b5da73285b8c74c6a0365f986fdea3dfb94965914cd216a708162671953b0347ccfe73336e5836d499786f9c1808997a0abfc9ce565bcf9d7c4fbf19d0646bf9719c678dc505772c580a290de5bc0a78b7eff8274c2e81027c3521d68ba6c87c73728694501722cac89f7c5b5c1aa7a54305cb705216ff7976b681845336ac2893973c38ee88a093245c96898c52ae18c46407907e056e82144dffc84aed84d166c1eb3aa825ea185d68a9671030d53ea8867712964f9068d57b88b5aa33428695364964289c6080c8682995ffc06c05621a571c8c9bb1799b0bc082859beb7b7699a6bcb373c49a045c2864aa8f9e0b767878743ab29d5db4bdc80a7afa0c1b3432f075a08238366a2483d0ab564017c2126bc114d4b989055287097686f0ac7778c6e4eb9ab9b195fad60a9dc853660d1bd5e49a1c1e6343ea6028636c054970c56426a8f2a97387baa890244408b1e2249cd070c3b02696840c5790b655c7e78ac65543aaf837ebcc87ca7a00f05814d9acb30339acb05871ee44c78a2ab2623b90900d28f5f673fae1906abf99facc21e5396adeb536a3f048a4d1439f5e6077730b1076fb99a8e4818a409c3b3a7c9a1f2965722038f4c4963e4ceac0439 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 8e592b5e637978f0987f8749b39b1ff15e19a7843300efca84e505e05c4f96e1 +public_key = 4a1785720a3cfcc485c1b3c72dbb23dc6c1f48979dde6127d242b4b3c499033a3400569dd376b59b5210e75b701bd7b12e7926b114ab59793023e6a3e3991c60011470084f1f37c151350f14e54f71a91df114ca652690d80c3ed809b9fa391b53cb9676c86e826272ef626602e23384c485d73aafd48a436f5405d756aa8da06303112b28b17a0b03796d034e94a51827caca06e547ec621503030349333ea2cc6828612050c3a9cf2b6d6179a6942065fee959079200a7d4428855406ce8ccba2c5b0b1047c0dc22425537826a4fb83bb514b78babf105f3317348bc7ca27bbc4b5c58646b28ee1898ddb80f63fc4debb6c7027c37b557159ff49ff604606b1b38fb1c3c75881a46ba880fb448b4f0c215d8c162b7bbfaab31b9c984f02732bf367acdf2cd64871f8169bc13a16b875b2dbbec8b4da307ba1b3e8d24a1c45c9745a857424b3e2934540bb8006f528e28e7025315080d09c578785dcef6b05c73206eb3385282537fb3251c2a05afaa3e04b56055411951c7aef4aa441ac184e58413a6106a19a920db9b2046f7cc5e15b6a00a830259333424ad22b09e8c308dac4421b2d331d84a7dd508acc04363bf89803ef9174247c2ca3718c7b1230fa652e835911b7b87f9a336d9d09e4d40bd556abc6c2993aa0bcb89796a792ba1232c2f946b00090a9882656898b794540b65b937bda63273f04067bd698b8c01999bb57e8ed76a87473baae0aec6868496c9012c723ef0d2087ff901756b5cb6f34382e5c29c3a55d16b3943e9c640c17b53498751303a56380a16ec395ee0b5c5f577f2346f8cacb8b141918425ba0121c020538d8751afb1a386ddd51d5bf4b29684be7e93c258aa0ff6839a0172760f9c08fa15963883ca7206ae3f4ab8f4007086c2049c117f89b38cf8b3685bc86442293ff9db0719005b19907a932c42c0e7a3d39b00dce520456c2e6eaab56b6c0f1875046ea376ac0114afa21d30cb0e6bc1bb2fd3550bc02f9e200a70e024e3831dbb070b975b8d971c2662587d9674c33c5b507ee7b03b71a59ca87e3c278692d304601380e06128e2b75c57c9394a56e030085e83e9ab6c46154cd22e3a9b05fbeee5c2407430629d3853698a4fb196c21666 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 7e0bc974823544306a8bc489fe3448b67628f7e20650ec18b657f3ffb482309e +public_key = 51ca250c3b7c6a1ac5d5d907ad3b426a1a63fcdc0dbbb4834c9874091b9841d359ee1a36e513331a72b8a88cac779c29b238515fbb94e332c8e2957840957a2487912f4388b934717fd10e24344d43615d2511614a65c4a4e8a20bb0cb338bc3cab07a9a90c1c9a6aa6c918b23b2bcc09889dc2c5f28dbc401a538a787b665a04db099c15fd9a863aa6263d191c311102902c88ec700e94475fa84787c86979c6a1887d608d0a3763bf3ade1b79d1604c2ec805687b26fa4259aa2063a200a30a8f71d9c2153c8826e9de41a221b02ece1cd9e806ec5aab755fc7ab12a90be087f29a27290e72264b7a62f58cbb38c9d8b7585e8dccaa5688b7e7740f0e1c0eb4bc925d489c869a429f6632d1318e6a7239665beaa5c65a738a6c1eb993255c924fc1981492938dc20cd526561a5a694145fa9213338614dbce72b9b527c17ea352bd03a3a3922605aa94143bfb66a53e085965d597589d8839f3058b5122243e9256c116fa67031b3c520d4f10447676ab066678c84b9572a135f9a753f72726e710f3c345f1126979fe982d9a1bd7cfa9157534118069aa7c055b9959c21232043731c46a3407e62ad352c17e4e0ad79f79c8345332fb64be1c73d4d1818f449c358843c75a3a6efd46340ab8e1bd3bc440abd4e9b34e6528a919900aff7798a695eaca1a8b201a5516b6cc7075421ab5d4f2a5cc0954342127c353b5c2ae64982a935a0c0474c8a8f7d9760e8f1438bb5a426a65d7e657103612c35b733a48c3cbbdca103ba076b9928611961b53102c0bc02aac75a38f923d6e41c12b4c7b94422253ac8e633135727477a685ba4742e0d1b9a8f49113e668775e6b6a48b37ae70425ba8a5268a2c71755fbf369c2630c64f015f1a92974a67887b5446f00b1686350395f37d6111be174ac1acf97a5b6b40c181771b684156792576660609b1239ab91c03c31c4b47404345745038b4988b0bf3073ee8bb8158fb473c1baa256843ddea6debc618fac1c6a0578e8627ca6b43072a1cb383096e3a469315481b60216304b3c0dc3907d2002b45a6c333a0887fb6b6cb007dae95b35555cb800c960ec52f13ace4e4fb5b2e82debc55f952d087d1a5717d2d9873842f23640b467ed47fb6c3 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Zero secret and error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = b09dad6ca6c4e0c81dd499ac65414937b26e9ce474cd083f5762b3c84d3a808d6a126a606b181560be684976e83c606acddf25fb47ccae173dda515226bc3e1d79192209a31c9558740376bf3ef8fb076c8d6b24b55fc60ccc24afa091727a84d7aea11e75d70bcec713e2aefb75e5ad80c534726a55a122722473ac762d1f1b1b52030d6da4d6a4e162188d043625048455ac73eded5e0ff32e73831dbd860b6886d684e6893c011d33dbcc435643f29992353257d20697c053521de2779819c532cd842e87e1c1b8cf56e5b2243414b02cf6a9d8df116655352abad59e99dec0d81b1b3f65a821303498a65727508478c88002aaa8e4000e2b5f06303597f0cceab408bb0e1890cb9b0343e8b3cc0a829bcb66534844dde8351943b26cc84009f5363ac6bebfaa311d089beb528bdbe1290f431f6a63f3113176efeb171717f945c662b4dbe1ceb8f58e65a586c4bbb9cda1955f8b97b3c38fe97260c5f00a7e8d906e09b622a089a4e704d7a20460d4bc72aa719728235f7b188516c484dea081af29af275e2e05942a0ed3fcdd81e194b8e99110c4bfb57c8b26d82b81ed9b9cbe45a1a4b163dda9dc07b3f588c16a7a5c5ed6384392f0083f1f9c9f3ca75c0b82b624efa512610f4b5c41001a49d3dfae55d0d7f980cca6ebf85151724cc9e45ccf865c314a949fc12aff91f0ea4a4857fc8212f9231345115d40df1f7102ddf8c3d9776a5199c0d79b0d15049acd167073c631b0453af91422d711fe9616db5fdce9e695357c5d35010ac4ba91c7fc65ec15503af873f55cee8a23d04b30757ca75fdd4290d01f675f3d518dd4f572027f4098c705328dccaab1c47514504d5c6de37e8c69ddbc8df746e2c7cd1f43664d4297e2113aac8836c0be469d0888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_shared_secret = 37edbd09946139e6e20ef35ad82ff10c4cffa4be5da8433878f2fafebd29386a + +comment = Zero error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 76148b17115a1ac8afd33c70fb8435f421bc4c2966d30104f8da40ed531460905374c15890a8152db91e71d31d15a078dcb1aa75a0b1b66c482e1520dd789766164ed7864e6b777713391457ca0b29e2442ce51419fbbf715cbe168234fb84828f9c244ae0691b817d1799543343b6d1a61a8105bfc61a448682040f4b775d7355a40b3f447b2e70a54655fb539123156a983ed08b2163e22ae92b4071caa4043aa6430783abd59c541413599ac193d7cdb14275d7906e1c3758a5187ec97c5f2fb0924bc7ac339acf2bb94b831c0c9097055c389e00b15231e3cbce848db5015f2497a5fa8672db589790e71437155e9ad8ad10f4afadc98686090229accf35b43dfaf67e2bbc218da462c8846b890410d98a7760f27247c9b63c8795abeb826921a70939a56e58220624cdcd2b8c10ca5213ec3ee91c3b7a01a9cf2303ab346734d568eedca4ebf598ee97b81825acc80b79dd3a94bfc9c8a041ca9d303843635c917a8d30e4ac4966b86e80999435ba05c73c0621a04841267d5c3dd8c54785a6cba1ec7c3ffc8a8f8ace78899a9ed769e5db3582cb1c86c39f91f24b8ebb01336c5141e86ddb801084ca2ba5acacfeb88484e886127ab31c12776193af6f1574e82742164c0012d55405483d74d511c9d48a87972c73426a4bcb713cb646ef62039e441c459cb1a4b0b088b564e114ce2f25648b8bbe28f198ebdaa1bfd19e0af67f6ee868da759c3b593c104821a50500b3f87327f70714f846e0889a015345f38898390491f2ec5b8af52948ca06e6865787064f611ab31e4b28e1b08d263c0786cc22c0eaace75467272575d337285cd1816b126383604f0de86bf9a1c51a042f387692c6f07073327070f209af85b13529a51cf800c4735f0e3654643119e4705a3e9c3fcea876fee5af72b71351b9796c118bf1182bf2fc74e2354920c102777841ccab3f853b84308a61b0fc51c175577ecc2b01521014b3b82b4674bb9a08e8eb721c4c2b01fb0cd0f1697119c2c77364b53727b195b2b458299140064eb55882104178b5742046981752b03d92b36809b4bbf3c5c2dc18f0e98a0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 6e4c471c64360a6c0958d5cdfdccc3470956430d2cd8f3e17e28cb2bb247f45719418d0ea31b6228ac8bfaf7985abe5ea5378e591af91baa4a2a8f3d8938ba71d7655f5cce981d2692bd619dce31dc8b4507f025bb9401834f297b85225f889c631937799468fda9fb792bec3989069b572415c18909f6e8f8ae638865517f01f09eabba737d241e7567118e0210524e3aa8e10c77c4a2cf29ea5f8c71ecb41cf972dcbad721924e921ab26664fd7ff017b6acd754ead449a36e805e8112c6519a9f4d3bdfae97b678aa54eb853e47f91d6e902e4d49d9ab9e7d610f769abe6db27af9d29c025b03fc188e4f5070d899f41054fef7f0804c4176b7149205732212eb84d96b54836d622f58ad96e39d4cdcd204c1433750b06e19fbcc36a4402ec2f55fab4dd55c1397e432315c803e5e0c9ecbffdc85a6c97b26ca500e4a613ab4e32d96edb25e862531a6b5dcec1f3f19b350fb8bbe0607c1907155d3d377cbddfac363f32e0da897570529b8ff80ce8cb7b9ea8ee9f7831a48a516a4fdef72c9dc48a491f0cd093afb714c6bdb39def5acb2a35a6dfc5f2c87fc703257f822220f6200a5b3901db2ba6ba8bf99e12c526466ad326ca382ff72eb62a5566f591aea01e28fd0a8cf45fc79423f159479d786084a28da9c0d4a38e65b658f2cd3c099dc7a50e626c416b4e8f133028c1615d2236dde145e94cdfab0512fe32eae9cfe8bd5e9d20d98f2fcdcba65b98a746808a24422b6f77589e644f9201b1bd78d0288f61f78ab22657983b6645d5451b6097fc3a535fdfcba6476427e59e317d71721009b2e768b9f75a92b8b43da45c034cb8a8e38f3ab08d61e6f4ac37039f696d862aabe14c0313bf02a8c56b7f1d1b1de1ad9f3b565bdbf6bb772ca9d1aa1b952dff7a9a8005476e25acb6a4c74403f4aac27ce67a4d633dc765eecd8672c65b54909acdcd537751059acc4034af72d838914a572acd1c9644b2df52928ad72adb09a56fd739fafd7a56ecd64492386c9aa5f1d522db5139ee733e072da70ebe494c638325dfbbe83d7cedb0a9bc17bd665b8a10fa0ef45c11e16b8aa3e +expected_shared_secret = 07d4aa5b3eaeb9e27f534fc120c0f0f7789a40cbad1abf26c3de26172bfc28b9 + +comment = Zero secret +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 67330eca16535be262d62cbe2fda08427c7981d063a309308b516e6875a8a2e870a1309ff7abb9f9a907bb57428a457b48727817bb3bb3b7b459cb93d89a3e8f9a7841c9167f290433f35ee9a33da7a429a5aa448af12348c9c5d74687ed462222741ae664a8b21340c34184e7a5ab9b1a6c842854b7aa1d4d566daf2094b609b410750f4cdc81c0d338921b44247c2ef39a75fec62b81528e08b3202ddbaadfd25770b8bfa77947b75182a868288df703f2152e3faa0f93d80d383864ae87ccaf6c5eadc0623b75b14bf73e1cfc6d14171265d30f4ab46deb986f4f0192f6d82dfa9a252bb0664876a793db36d974b50186883b8932421c29b0a5060f82565a640b73655ea6bcaf6ffc46554652a33230dfba582b635179018aaa02cf49f2187472ae7dc57856f34fa6408998bc892b18484cc5a9e9c040d61a70acfb56e2a120a54ca86e073289ea3c9710c86ea61930e79d381418017090880c07aca1a9b39802a6b0c6e2db13de67bc52f47121539cb5089b27423eddd70395678d2738151e8c6238f4a0eda67364e98b87c1a40ec658fca57bc49a69eef23b4b562c921b5c061b715ecc2fb4f8c25be856ce116dd569ac54a47fb8a54f63bab85bf34a8f4364a3040cc9f681da698b77a26b05e529bb53a965fc7711450833252f2be17a8fd799e1416f8d80589da5462ab078d8aa87b348cb31153d1a097d54a32f354297d643af09e37b8ad272bda697ddc9c094f699ae2002b25178a321be679b7ba82b50442519367cc05f0241a5bb6400c21ef0a797f6948a3b924fd31380789cb177581b8f7c7db853243a9c7a9d933a8d13a017b6727a5b414304b15812414c39081f7103017ac7e5e6b042b96673e87ff37508295443c5f70c27b4bdf563b259f83b0bfc820d994e08bab7e80c287a913003249b7818a7640252a5b9cd52e38e25b2883a758ff7503bd29ac3ae3485bee2af98d13b5db7a147f405eef8865d14c598e7261a6318e2d31254424cf088c69688518127693e22188e8897bcd65f50580d5a7c309ba9cd309a2b3b201fe074027157769352b15026bdc07bc8c925c00a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 7ea4ba64f0b48b0517ccf03ce502b22b784682e50048c48a07077f6143ee4900589eb086f147e66b1ec4278092c4bccdee4228477f06d106d800fbbc08f9ece5de9a0299a7de50c14e63100ac6642718e5f35b347665440dc2f66d0677380940aed6840c9b7d429a88974f9a37da8e2684011e58fb607535d5077c7e4d7fef8e3683bdaa30c5b3755454a1a4fcf386b26a8d7f5735c7f344af5b8ff6f89ed54e0c64f1ad2ad886045cf8631bb03b49c50f4074dfdfffdfd3c1fa829b4a8ace4b343c82ca336c429ee427b6a0d59c1f5e0fddd9e0cd2dd7a0fac57565f30547ccf25a6882ef26f44def60acbf1e33c647bae8d4aa9b4e40b9b5cce8626a7665e7bbfab4c02e7d9361fb38e34e4eae23f944ed05a647f771fa068cfa6badea473324670314c8e7b05571378df2707032072c8d42922412e3fab0d4cdcd5f343ee53b7e70a1018dc4f818e3c9d81515ff3c8e57479401e6ea51da695c2f4474ab1fcec2679f780905ce95ebd25ec415a2757cc9b5a0644d0f5abecec155dfcb75f674cae39d4346a7787cc9c0e038a9d599edfccf764250d51d7e56a02d163f97bf60a4e746a74288648b08f0d1f8f0d400f7cb6b44f83fdaadc09146e09f49f347a3a6aa34d9d40f75bf9655a78d76b249d68242fc0da78e69e03d3db8c8a0b9846954128064763ba7d2aa36c2bb6082ea8aef0f0c9c4ce43c93e9c4a861a80009eabece5b7746de3fd7487e3c537d0f7c35cdbe1abea4f6df7714a759ec67e7087de168df199de01bf7eb0460a4e3d98bc3de4e475dce50f921ca53a90336e5c14fb39ee1144e8ed44602f6746924b107918f90cbec9c4eb6a9256380559940b698f184c29d8cfa9bfba5d2b33fe101ee45a662223aee1df9b8c88ed7e645b3e80888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_shared_secret = 5d754bda8026a2b0965398cd12fffc357c16a445e3e701403888a18a982cf189 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = bb46cb622988f1d70ebbdb760f498fece49012b73d71e49866ec780cc83005cc252da512e3c5b43997b29470c6827a729e6acced8a214832915bfb629b83a1f477c835c29ce0e175847a63a1a69870c4adc264663b896b0e7b984871c2c8802f7380cd3c754c8371c33ec82d2d7518ec2638326aca9e0a9bec2abf68ca70390bc2dd2aa691a502f9c0ba9a829ba89925b69a13a6ba5d2390117809887b51b7fcc6c5af31c464cc17e81221813a837562a15a0ac9c81c289689890ccb6635f15d23bbb4ec248a3ebc86bc9b283b5a3460d3a06ca326b519091095836eca075fd6392402955da84fe7538cc18763a91a2df2790039d464b7750250d9b93e774cc656bddcf3c17c7b8820db883e8331a0003de25825bd0176cb3c4051a384b687309421acd0bb8bd2ec6a422a5d6509958eb25a5bc1ba3ee43b5453c53ad7776021b19e2a5b1f553b36134cf3421951cc5645d74813565f3d8b6e83d3607ef5751d09ce8fba792865231d60c82cd78ccd26001ed1b3b0378c87131b0cd3a389b963cc01b8b4255a31522a4c83b8706a7c1981b555730804836a730b45cee7853f771869306896d8c94fd261d057b48a17327fd8634eb77823239f623ac3d4d38a1b1b0d36736aa7f28250912ff5a710ed4776be53c264d687a9a1bd3c0b99453742bc4554fba93841ea2fdae6214f49090a24b93cc287e1c322a1298bfeb21313fa4367b84d928c1d6c1923991341429b3d6a59c3d0721f474c753c3093809bc8894b63f747b2d34a219923467464698e595131e3606a5812ef08351ef931679bb5a36a6fe547a103401c7634a7790283f4db6d15bac3cf81389cc23b74302d7b61389198ca7241870fc351ef159b894c50f93cb24c945bbb70306f1a7a0c5063d642433f852b3ef6c227d2b49c9a4c72ab21aae567c9bc6d93817a6161c12d6200d6a08afc1325a7da9a3782b8191aa5d6f30751d01c6af308b2c06c92084e4086c4f3e306e9d5cd82fc151a700bb066c4f97191a46833b8ac55fce41200772450e826b8e5985d830610fb44f216aae0e889de6857db4a0d4b8479a1800f92fba629a6cf40d7000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 0373e3220dc1941e80274f0a09399217246a31b8c86d795898ded46c6e26ce70ca710c80bdcf59b03b2ac1eb66ca6ac9175de57a8fe5b570452413ab628fb9105c8ef8852ee2e012a6c4c1eb6a7fb4e03357c6264b3b9762f10d5be97c340c69218b6b24d61d0c3c411171f22554ac6ea09748cc8585e19c1dfdb6ad7a85f6e264cf9173d9770ee0f6f89391121deb2179bf4a0656575e9a826895d20483285d8b6848705c27762cb9e84bff2c46dc3f978760a68daa900f148c9b2a415e589cf43eb94a8c7a6727facd6c880c9b76dd0b842a9e44b60ec3247602c2e213663d9fdda2e8be79736d2c3ea81f4f875758c56c0af1c6786b3eb6f3710fd276eafce95e0126af288e9d2c12425bca463173bd1bc0b3179383093324e94d5227bcf7b2c37218936b9aecfc6203ad7b868849c56e973adc639b8c116350599891beffdf266c4a4399f970ef41dd15971cc7c385041ef75569aaa7c0acb8d91584bd179ea207febf5839d63c579ad3dd901f4e8b1be181357f01e6060b748002c11a91efa0fdafe81dab1997b761438f91a89187656b2a9be93705677e25c0f99c7660d6cea743dfdf94b3fe9c3755052fff1c2a1e73ee17ffa8ed511e7e8f4d4975f33f694120195eef6408c5ed0fda03ba5358018f0bbb7fe5de78bc7d529e1005620f33183a2cd5a0300f177d7e5bd68a828f97289e2ce23b5cfd5797fe16dc98a5144ea1d326c6d15d2a34c187c172e32e4eb4a039b07825d57d52f8340e8d0d56c02215b2e074e39ac6905d4141c85a2c18c8a63f52a295ed3991c65579f483d46b617148cc2f03db0a25d7a8a9f3874fceefb91b87179025041ddabb11de036f290998c4ea44cca99d36d128a4b1d256fb143d63601583e594fd2537be8079b130223150d8f20b8a325835f324767eba245f4404253b4dc1675476eb80673664d1d6787f83e29e58ba926a062167167ad282825991e217810106bb2373cf75e9766e7f2857cd18815bc3f27a12213fc6481e778a71549382bad377eee688a9895b4ecceb58dcdcf0d6e7b53565cb54e7075cabb8d90278f7c4c884b0ec97a259 +expected_shared_secret = 913c02c8ef9cb48a557ba63dd5cdf32125be245f769222bce624e5976d294eaf + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 7a4741cc16803424af39d20428f7c0d0d80e5461cc46e04bf2f70cdcd1799a2179798acf8d91790b21a634205b7bd75bdc76336251c512886573a053da25afc0002f75d67e4dfc3f0a040a9d4a5cf2b99c1a75805c0007658c58813cab07b62e0c9a05bc1c14f79852b12a89b2c17105c8a6a3ea71daea6a895084a6f2372c76971972bfbe730464285d8ae1cacc5a8f75709a9f343a68e0bc4e994c0a955c25074a27277972bc45bf82125468105d308bc0786ae39c77cb7971c053a1bdd74204eb4f74e876baec8e7ce2c8abba8d23253628f944b0f77534e56ca0884701291918d2af5cf678c7635b2f981e75ac2ba7f7906af87819b63906eb85d551a89bd79d9762664e2b2a81f52b64e907c869cd6f18b88d5b2ff4471d7dd6b4378aabe61337f108aed1f267b275af7746be9d899f126c1b4d096c09a113dd3b1785737e9a2b6040a53904439a95347bf845c45123b73ba22c9a988b19bac9b6c476621196ba0c674f91629aba905871c1dc87ac10ab8806dc65fd27a493d46d9db3ccfd567719280dd8c2a11f8414dd9c4d27064be7862938d3201bf10e5367248169b4e32a547dd44a51b8b9ebba078e05be937c35fac824a606b76d6176fb0037efea11b8625705f8046515b8813b786a7c6c0070a9a13171649c3a019c7db6cc365e49427c3c4ed06bccf12144d77b111a2561b31a0ce28408c54a895ff2b49fa76d88c9b97c0678b5c8a5e912447a3b303167bc473330a24a539c9780d19a3d530440c5344018497d545c48206268f3fc03f1631be9d6143bc77f47fa14b803cb23050c62b06bf699a6a93336f2d62e6ac2bbada62e2c552e98d87432a3561c28b9f5d5034f67723cb7509f06973874c0c889b531f4ae3aa23cee94668ad00b5a10902167b1d09cc702b08a65b21d4f7bbe7d87b549a2c0b58235f8a9b8d8f97a0ee8cf45570355763bf3422f4f6b8730f68fe0c8656a608906d4936b7924adcb6b4388541f061e994b0c03a6c7cf219d81b7abaf2b4b23d25a66f8adf4431413868e8df526b296ad928a0c8aa030e1558aba0139b52a8c139180c0d582bc06cf41cd0933ae000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1c11f6178a09f65f8ebef2e29b90343c48f646e3a0badf3893c067fd3977f40baaca92f107a1d604f1ec9af888b108420851f22893e252525cc7fc2468f860cf9279c8ded10dfb044e186790aa919c98a108003726154025851988118bee7e2de6bfadb77190ebfc2065ec6ed7693a7e97bb1ceedfb00841030fa5fd950fb9b2652c0668bae0b587aec5d1aa3829fc794546bd2b708ef850dff44adc77832251b6fb78c7fbd207c9180e3d691080fedc44eee5d9582600d855be0f3a49e330136fb2acb5ae5452fca54dabef3ed5c5254ae475217993c75d106c337966d0f702d1857259538c8ce89c3b0d615c500106ee665e2b3f1177ad5a076171ff7f3f9770a09c66595f55af51877124ac0c5e46b09d43e404344e4eef255a9fa146bed156433fc3e4830143b585001307c92f324111bf3a3c21cc035e1e698497c025f721e03f18c69a0f4c00d8d19821b120a0e3245c7a30076eda174c701861c62874ca60a1c5408ad5993ec77deb8c5b34be816d272f384a92c1ead0482e6e3a9646e113af5ebc546d90146a26c56c7a28d5a7fe9f6a2bcd90432469c11b91ef79217ecef2c3383b5f0c46bb1349d02c7fc8ccbd5a695ed2563722e6b4fd522018e6b801809b01dc50b77da143b89a7c075c28642624129aa1dfcde0391c296aea560bbf792115a73ff0ee1ca899341e10eb267ffb819941fffbb5d6ab3a878fe10c9dcccc595bb9644c95ae8b954b6529d786a9dbadfd0d8464f794020753fac1fc57a96405555ed458075dbb39414d3693523e3234f38a1b63e2c4ff1e26afb38bc42fc239af6f64248ba0c853d79717e70033120daa668c2736d3987ab33f297922a4738f9924d2508ae0d50111651987e13739916f58d8c7a5c18d9f7efa0a72190d7d8d8ba9e53bbc1102387e4271c7d320663f83c98b0c0530934fa1c13819e28e68c20b120137af463fb4540986b721f95b35923603f311ce991a7dd2b6cdf4593399a87ef9e72690726eb7def8ef0b5a811e952f54df1af4d13133eafb9b146653e8544fe664659032389b130ba8cd8242d9bd3b8d10d473657c6bc217e4 +expected_shared_secret = 4db7174b795d2f909c71406bc69437f5ce58cb0d0bea33a60b5102afd4f57d9a + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 640300d5eb36a0f86b0d002cd710aae4617b2b45ba0c24ae1cd508dfe9a810ab9870592545933879ba18d47a17bde4a407130f0ac43162894786705d1bdc1bedc58e5d78183481452dd46234c53342f1300908bbfe204a5bd3899ddabe4f687f77f135c6b12b81932983800ab58ab04a59512a51bc7e360bb880813ff69d2395bcefe13880129e4ec78770ec3ddab2386733345d7c159b74ad7b7b4022f2c9b4394eb632927a6153855a48f6e50759925e9b3c8840698ec8924ff1e179e5d784f19187392acbd404c092ca4d84074d3605c7532a3360113036261aebf8ce54fa53f7ab75e3d728e152a4c5ab7f63b63f8e3b93465574a39731446c9b0bcc134bbb115bd9a4b9bc9b86a87b7f5700f3abca23db70dd35342dba0a57495906da5166e49bf56cc86965371078ac92d5afed2a0c3cb9524c9101d0381607406ab227bb77c9142f42cf1b98b83f631dafb58fd7c77e7e7a44285acc679844aa67c394528874d5074c498111dc396e553565c3a80776c432971961d12bcf68204ab1bdc6872e1dcc865907605cb5b79700912e0b68ebf119334b09cf32c986dc729b031278b85cc04c53e15c5330881df74cbc9aca6792999c7e973d8e3805716b7092f9c91497144e424bc95639fcc19028fb73ca8a9947600ce512136ff69ae8728a6b6a562f923565f70e0b09965349a16d06abc731a1d6bb4ef77a887ffaae5278a8a4260c04829ce826cdd7d942fe0874615311ac9191c2f432e3f7861bea471ac4bf137917adc6c5b5062ac8a47896824832529cda569cdae653da857eaab54b2cb960bfb29184ca407f4145717c30ba030ce654aaf8c39e1aa806da7395b63778b7c7757e0c87b2ec3686f05ce4b66df0826223e714d7e83fbaa84ce704612cf7c1df783a704011b3f45024d505bcd268f40400de1c0553479e67407e7fc09ea3c96eb675164d163d0fb1736d1607a34a101f7015dd946ed1105f1bc8706efb2a71b1a2e231082aab392ab3ccde922c9a9411c2b6c997f18b91231ce4d8074ce10db559a092586f72ba7cf681c492501ff6961eca809ae98c38dd35c8dc1ac8664cad9913000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 09e690e7e8092aceabfe13640317de9c8401a9f5554bbd1273aea9b5ce9483d64f0dcb38a9749cc9501f193adf4e9413c6aac05e2ef1590863d3a97edd8054b5af31f0be6fea45294f77ea8f311caf06fe9c8d0f7c29831c44e06a2b2c6adddf33ad84f5eeaf2101dffdfaba727c94219fe4a4f64ba4e0af97c342bbdbb75b13dd470994c04af2961be13e772c626bfa2355897b9df1ac4a331726fa3fdd730e669549300d1a308944dfe64baae2f2074dfd57cadc7d5c9bdf72dcc368cd881733ca49107f93a7be5ea90cdb3bb2d037238e0500cbd414c362753c104ea6e51540c2b713d42334642ef1bf4bd1c1ae87037a846810ad6dd0d51625f935ca6333cb3ad2e7ba1cea35e17b34e427977838fe2088ca367f1b8b345fda94173e7605dff4c59b7b9a53435d62f718fd103b3b4c9605f4d57987f70f55c9b0b8e638f5947b7333657833f14313b5b1681da369f884eb76fb1017d9b6abd562c3dc9be60b7ad6fedc3e3a698e698900da80316631ce21961e63ea1453430cefa1106de70657bdf32962b9c7f9738794729692cc73a4b5f6cb5b1ec594c3975a234d0c5544fbbf70cdfe0c83a13b126e09bd86cb2394b1599a77a1dbdf84ac6224a3b3c0a68be739f4de221d69cf00880cc45b8d221b417be5b425482f8c7f7d990dc03d1e23fa48076da2886f9c5b7cb01d5238dd3013863916019db176c4c08512b0444703d588792870a2d497c7dc7a00f240f481101552182c8a8a5a476d4cd27fe1600c6167642fb1a336b4195cfc00acec31b5e23bef26b35dd43f981a0cbca38eaff690068d0167139a433be719a75495070c170d65d2e01db5840cc6abf26247e78ec66d89c783e40ba1ea9d9f5b4d551d97eab32c10a6d5b2ddc9da3c0e885aad5bf8f672cf3f9f0ce26be5afac4150062af63c2f532a2ffea069b546133259164b820c059a01b804861252746ca3722d5d9f5bc11057bdf939bc05ec4066cf2821bb02ce1fe987f15d28c69cec7c25c2be4c3d256821e0aee57c55ac1af279584ca23d5d15c967ec7f2478039894dddf52d89be149bf29324e5797c20c2312 +expected_shared_secret = 5d1262f1f1c664bb74f85c0087ca6fb4ad883ef8f777705751ea770de758b83f + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = a6cb65cc52c45a038bbc90cbd865502c1ba70a32265fe3714b89335a1a8cf73723ff95addb6176960a966aa2c4493c3917c25c579a143f42b7005b0b0b77c5d6d169288596abb3bd0b53349a8c96e4eac40d20c6af19bfb8221d82919540f36673f6684c4870ba748ecfd3aa7600b463d1098c8c484c4ba3efb5c08a284672f420fe36b7977a0fc72a801c709f64706b70e4a5df566563f75901172f901a5e9640b40927140b0b529ba8549e4a41420a06453021ef96b7d26b44b3749b244ca9021c60d6e62b96594e5c6b3aa53aa7aa03c4bc6abebaab575b455ff4447f57a6a24c862f8bb16182e9659a780ae0772398f5c917774e59b678add3288eb4a1f4f7335ef7b62a823137b78f2d646b87b5bdcfc304f3154b8e779a31c8bc90051f22333f497b79df8158b8a2232c5270dbb5781db44b9eaaaa76fbc4d02364e7c2963c36b8669a507a7c688e841eb1f1cd230477eafc983171a84c399206047ca7f13906325b54730fb3db1ace32c75bab10b3bb7ecfb9a5937cc38fdc660243842b56ca16707d39d35c8e85212ee1022ff35c632a3f60434008e780a0ccc7e3983649a1426549485575b2b9acc3f3877100caa80aacba1a2c9a01b9531f450fb5bc0d58b21890997441d0410be989d79c237566b6fe14af1c98a05a325fb6139a4fab4e7e406c461a5a3e614893979fdf4948b7906dbc8c67388c728c66c71464ab575a8a39e62222ec8f254545dac2a97fda3b11c815b83c25250636b9d27a11fc536b9aacc3930a58e58f2b777a1b56a1c857989036975cd435d5c05a4e363d7659918ddc78054350cb386477c11f17169d6d5a3c52a9308546ceaac00b92619e35908c4ce92f4d047118709e24421b34818f55196b7302810fc8a61f5ca1953b2a5907665a707ee338b0ba96b419659518ca4501762675835cd191989790adea4b556cd69a7e3c4b36da74dfd1cc02222c0fcb65138172a3538087f1168f6b00ca7974c90bbc5c186d9eac89b6b9046037be796669e0a00affa119cd8b5a4c03ad45035c218ccf282508f6935e75406099504a684cae51f933fd91274d341f28771cc916000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 898ad47f2ac4802f28b71e6b37850a2bc1afcf1e3e401682ca928c15e9d32f62f7f64d9895dfdaae399568e0394512b94bfa1a7ecd0e71968699fee3c6d7c286cd6d8f18cb87d0b47e43188634d10641014113c6236b44297d68ddb2723560b1cf29267e3e7e1f327594e812a4352c12b977a5c31cf46aa5e95ba252ca7bf65664598407bfed485cdc4d1becda99be53a72636b2a95b07ae44ca1d40674c003fe4d4d2774c9c0de9080fdd0f5ec0fbe80a1410ee7ebf079accbbea215c10bec32c333baaefcdb52efe0d8e3c5c1d65964d25a2da50527fe5f00c77c9f81da7cf7ddc692e5b719d7ac671e0699e5f756c512d5c7daa72975168e0f848e0c065dc04a59667893a6688386e66e922f201c41770f8497eec0628df132cf1460df20d3b8e631e1515395619563cc74520e499f6d20b27798187066e80e4919f039a143e8503aab89eaac1598956103b3579840ed2cdb7e64651e98791868a6c45339482db2bfb06fbc8cb0182d536ee84d684473169ebb977e973abc709ca155ff77d4894735719fe33074d472bdd8fd271badfaf4d245b621432708cf62175f3791bbd14a019061be42d399b6ed48933830a5f6a8ce1109f3ec41ec3e468746c697ccd12e8ede885f00ffed145d33e28901c41e86ebf2c8fe9bb34c653b7158d6f0390ea600f216dfb6104c59eaff3ecf18482d1aa75718239fcac957c3a358a6ea5a1818e147ce6f7862fafbbf3f157fd41a25af87cef36abcd28211fb27969ff6b0d500f507a1b9655e3a318eb7885372449d2b58cc1d09d8bf3139c8750e60142663b43b53567912100694e819ac81f7ddeb3cb746432474e91909192085125a67dcf739aaca9caed78f1242a5614874d189069406a57f2c1e3e8a8a4a1c78add7879d3886f676beaf30eddf8c00dab2d18d668d699eea17441b28ed25fd3b37e2aa1cb74332dc79a71a3616f308362ec4183fe8cc1b1fbf50b19e5514dd219a2c974666a9c803e3730308b4d7f0292ca11f3a3cc75b5ecde01e8a0d6a6563fc013a5e6a30a014378e81ae8112c0fddbed714573c554627916f6d96c66c81286c +expected_shared_secret = d9758b5956b4e2bef89ea1c68e6556989ac7fe00906aa943a0234d2bb743f7b9 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 87396ad2bc9c09883042fb3ead95bca9596a49eaa0546a42b1b29a712898fb4babf47b23ad4a6f3ae54386cc8b497c2ee9153b21e580669405d8924fd4c840e08820186446b91698f8f3ceafa1415747bb31eab6748c639c97c7a60990798b0a7f11ad86d2a480e9b17a1835759269c90b9b09004681333ac472ceb822b59a630cb11ac843925876935ca1803d5d245de0874beb12a3ff341eceab0959b22c4bb093dd88421fc12e8cf739d3f5be5669bbd240b4694acb72d1733d4624cc750450cac107599dbe011beefc6c63ca516169c6c741b211291313840430b647181253d70c4a289a6c19343cdee5983fe6a037622b137a4962ea9c6c3b5ef3d239fae089a623a66fc1b47c0a658d3a0c7e4ac7b4fbafbd8919d1e74c559209a62225a989cd536aabc439b02671cc75744b223744623098df5a3555c668fbd7618b3a826bb9685917c05230a0118756a6497ee60b00942a5e615559d7f81970273be9ab34d266555b2682906bc7ea538fd98353c38c8ec8c515ee172685c66f4cf264a65b4e36b9641009288f991b249673d20b908be66f7a2b99d15b3ce6d95de87515675537d4aa8d750b8b8d590b726833bc536eabcb97e27b7445a104bea31c213b9fa7e53064f760f0a681b9194f751a5684040b5622847cd93d2f82acbc5610b042999406089bc769813bb9f6d711dfd57d48ab283fb216ee4a24f95048d4ec25dc1a585b5619ab63cf21c51909e2b741753bd8557904f2164b6c09253bb42e83021e739d48c261ab0103ddf174101b5ae20a543a6929c53c1fdb780375c6c600f450adf169b68c3c63f933de63634b976259a69bc187cf10504fab97934c2880baa5c24c11054fb2897f40264bba56da448ecf94503467ca603ca079c2650d725f9fd8c187c71ebf72bdd5dc97447a3a0686741068b61da9a3d0c25e7c22aeb5115eebf0c1a68702ef89b61bb5c4daf491be498e1365c06475b373faa2bbfb36acdab672c74172f673bb763bc8eb83bc05209ea537fc7271e11142a4fa6715d79f7ab88b09e0c1c583772ea9584555c3d47b358953348ee2c646c6c3d7883f0e73a2d589000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 21605da6d4c4a592ff5164089e06426fa78b7a7cef93278ec2fd9a5cc462c9eaf46ee3725e2ec759eb8ead381c19159b46e63c9150f60c7299a789213b3ac32226f8e019c1043ddc190a02e6899f7162c876e7cc50b2004f21961b4b53f7c52323b6bed0a1201a4eccdb2811cf01adebf731abdcd827e4b2017874db9aad28f5a1fac0fff9b3ab0e1da9be06faf987a4bb3a3c1387699a2223a6b1046956e6243c577284a0aeba8e53a8dba690d2d295d83d1a79f00e552a91dd5f5dadadb9110e4321233364c6d343a87605b35473937afc0258249def33019b71c708265b8876918dbdaf1c64a3a7cfaa0ace08686c5994545bbdbc3293f37a8a8d48ac0157d271111b159624b11affd15d9230ef753188de1771636c562a355bc98d724b62e6b58994caa909152e0da518d95d7d58076eb7490012818cfcf68c247d4cc77ca3888e66cf9ded1bf10063e68c6b2dade61d4f2dab1a2bc6d7365507de38ee1d31c472e9a2abfd373c9e949d539518438b49f534eb14e9a53e4f6e47c1b2870991755015dde9fef3ab4f3b4621e82667a0a3034ac2c87e0a84448c5a61e13fafdd09fae27fabe3089b21ddb1a43fe786e4fceabc33ba8913bf1b72919a521839a6278aeb75497041e03ebcec51159b5c53d9253ef535b324e684fbc2a5239af7dbd54604c90846f53f4ec740dc66f30bd0a85f45c8838d4bcd00e7d6ba7cc45123b7192ae62ea81737edccf8a5c48d336ab5570eef19e1b16ac155c2baa880e9cb027b4728d08504411ade74c5e85820bfcffd14a941655f3b26a564d12ab412e943d56569c1265a965d7eaa45a0d4db00946fbc4cefa0dcc219317e369a652884c67ff61454f0c2633b9ea0501a6809caee9c58b23c6859fc5e16b83001049ec1a05b47325ee6ea145601707465d7ad3f71ab740977c859753ce14e2fea4417d780d3619bb60abec6cf4ef2649e5b4005292b856aa67b175b975ae1bfd8a3dbf99bc26a971dc58b64bd1157b2ff97669d85383e1216e129cc9da30f173d108353d27c415aefeee2fb1a848c1ab5480bf851ae6d7ba96819b3dc776902ee54c5 +expected_shared_secret = f00e6bb6cd845396ad031cf285ee86a4dcb919dc5d9e91f816b4471220dadef3 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = e74b379648cbbd02866ef74c932441672c5c8b511e13e284443abb225a81ddaaa18477c5301483c13c7a45943af0a1805dc361c4a58f12b4bfdff1ac55e64cb42b8d14e0babeb8b99f61b910848545668d9dc7bc8a475b5bf462b5b5c226925277465d1d036a2a485f0dfc04e147a35f568e1fc9cfda1b8b9eca052068283c9945fa9a2c7fe418327945909822a1cba4a41ba8f0b7cc26209b9c84b679981158a855f1e335cca815d33477a0c1affd546784b0c893f7074bea0b770a4f8843b109b774af9986c2ac29c67aa15b98abff9718f2fba27bdb24a48c9043005dc981bcac8790b837ab33a1a8975410a3f396499bc725eb7ce0a87408d9a235b072c669c6cc935f194a950298830501b922d09206faca932a2ff45700cd072dbb9acd7aa5c284e4b60f32561ad142c4e214e047a0663211054b22e57b68e4763209c8c427c767e41678795627ce719969c781e17445de9c1d33494a3b23c7b3447d6bd019303abe67559e31753caae015971a809f602a6bba2002097b553ab481844d4f8486db35970e1534abb2ccd8f52cbae78176182e4079a0d0ecc6425b117098007ad58acb306037b118f0bb27d7741fe3a89f9034b1399acdc464271ce3a9302b994b119d61fa25b3b368338a8f4f51a008399942b1cde51a36ac3c6549a2401116aef240cfbefb6885dc9dcfa86c9ea58124ea3a05150fd41bbb8700550ce2b06c36b368c402832a691445692f299e5da55ff52c42d10bced47275f15433e643212bc260a0084ccf02422359507abbbb91e57b14ac030c2814e45a654af541fd704cf95443c8e2ad149b562549bdde8ab96f032db92b6a37f473013155e228bfac7b6fe856b9783220e05ba1444638bb914af8156294333ecad852e384a0f534288fc05bff2a6efc76cd18479ad9729da9e394d52bc420794b9af127e1938a9f08a8efa35438cbaadec162ca269a601ab42d949f00e741612266c51b969e317657484e5a15891a4249168a7888a903084a2c88f56a66033b262bc6b07a28db0a9d7d4361ebe62c54a3a292cb768e668283b06418232d6bb80ec85034067253f61818650a000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6bbd4bbf9919ab06b10b5a372d405a88d94ae3405ca26eb6f72d1486cefebaff2dc9d6bc3dc4a01d957b093b8d4d546ec46928ff42fd8fcf64c3dd1021ecb1e75e7acf0ccfa2aebf555a3d23e292b035c3816165e320d9545aa70b728fea21f4c6b2c7fa1eda7fc3b7594ed2754f4e291050e9fb4543190874071f5782bb0aaf683d6f020771f325e2435aa1f6f80dc47810f29f3dd930e24bdb4682d618099ab95569a740b3a1ff35320394cb0d7cf844445691b076c4709605945a8f9ea1c598069b58bb02dc34124791494fb8b7afb393f7e6b22d67a7494d8c888d957012d0f3b2cb9038ec0d7d5c77211f7e224460d2936e85a3a202d9b3e0c04cb076256cd04d4230599a3a2cabc56094dab0a99e1b409db0d8651c96f755552bce554d1034c4243edc31f8215832092000d9570804438ea7c0b0a167aafd113241fdf358d460cbeef621b977444f3edd9539920ccd3ded9a9d6a6d221957320421c388af2ff50bd4a7c27b01f98fa3bbbf32c82ffadfa14cd71025e19952cfabe485b06cffe8703b33258bfc7914f69db35a30de07c7c1908fdb5377493e5b90be1f811e8a10d5ba6ac7ffa202001189dc81e8e758d6192441acea101dcdf471eb74face697a4664ee6199e62b646459c7945c423496b177eb5bf2341a535cef9380554c6b2a859e3a860495912df0791a1a5bf02774f4311d82ab8a9a1c6e7b12dd86735134ba23ec5a553d48eb5c4910e0f850393f7992a1dc5042a0abacc974b4e5b3f21b57c9150a86f5cd8da8ea2cfed830d485e1031be14c1c52e99293fd124703fad579635182704dd9448953b92528edc9173086efb7471fb24ba7df975077e1673e3fde8e3a8488d591cab627cb5a0c39af7d6a2e47138c6616c6d3cadd040aff04220265b5c16ca0283fec6bc0be62be986d85099d679ceb47c73d8a8d4266ce337e81aa6a5f3579ff17eafd4456dec37a88075fc87540898305b480801ed75fcbb7f8e7d15b742cafd0dd23c49a42a8b2216ed47d3a8ef21b31d02ea78c07c128144bc8c714018606e02f7792d4532224f556923b14f3abc644ed983e87 +expected_shared_secret = dbe5130e95de9cb4e77e62a396a2a623eb069c1a96ea1c2d7ad37861bd75ea73 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = a08c14015c75ee209f4e6c0e5ba98c5c1272e58646370bbe91c93fda07a3272510aa03afb1fa64d5828adad578a659b8c3916316e368273cb249c5b1f9296429733ea2c77534f79e48f73c9c052191b4b76e6c62c5bb94760ba0387b15097c5bf278ba0768c5c2254d6cd52cb45c8f5fa052696cc4d2275b63fcb7ae1690c24099f86646005b67a79a33993755a35b0c4e0227a8123e88a07fec19566afb8ef95b5f2f4a2bc515a29d99c28795ce7f2538557ccce1698fde928694969dd42397f6c5029e302ac86a4c44dcb3bc7391ca81ca07a5282f01291ab10fda6829cc96b4577107e05bb5afe729462aac67ebbb15d108b38a2da1e9bd0dd90e307347dbe7938309c9bd8974e815597e4985055b7b59706ca6e44b030627a4112817a620db6722769a461f7cac71d2558fc0a076f9837858b634b444776c654ca7436c5164788182f2ba48b59377489373dc364de66608dd1756db27cc1c1660444143ad352576676397b3465f462772015dbf6454120323b6fc64aabc239792ae0c054e5515be13370d4260820884b2c5430c314969d7b898fb4ace52875e2d86c83cc1cea182355e33030cba8d3f077dba818b86b48233f333b7e1b29570181ae68b21675cf93035cdea454e0a207746b71923306e67740ff58ffcc4a2d6605537ab37d3e8cfb6e36de3086ebb8c65042ccb4a2670d669b1850156d06a8ce0383315e05eb96c713d250e977a22cc0881cbb56f80121cc9d697902babdbb1b2974b0b57720ef9038c0892b751b48a54b7c6e9912e9b1b1ec36715bf6a98a6b88cdd81c907948ce36510e0f88c7a4a13fd04a1a78741a87153c2193e035310719203fef365b4ea765d4babfd056cd8ca8ad9b01602115635e2978a8559716b4b7bfc380ec8cbd3f228a5f997a931518de07b0a3058b66960b9f4bba05038fa619ff54053c6840897ec91edac5348849cb39ab55db9c4807168cb4c1147f503344457650701464a35299c94aaea4c8b3b4243fc9f05ea651582719c0cc4db14775227c0e966abff22b995c6aea3909a06c20349a2584f2513389625adb02587b730d8b2bc6d96874fa0000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = c824df951ff2d29f7c5dbeb8313c79d27dbcec886fe46554b405d26cc0866915dc795e1b1381609be4b1798922c7584486f1240a9de8d6cc8c2f7c4d4fe92785cf255878b4443fe05749c59e1ef7a00821b9ffe98498fd6521d0bda1e8d865e50a26858b7f52f5dcc3d15433f26cc27c56eebb718ed20c9302e96293d3f8fd9ac89e9e3c86121431d7e3aba78c5adc0814417a57a1e3e24bd220b2824477ada48fd1f96e41bf4262b7245cbb20a813992258628ea6dd762f2b64c2d596562205842c908ee0ae1b2ca8d260448239407f1534d7ef44ec1a0c28a1b8793fabcf7f58b0886c0e545aa1d6d5ae276ed7495889a78793c07b017b4adccf96406ed5e82514a462b01e4d378280ab2467ee6744c4605387571d8e61f6cb75dc4230861e2a9ef8f83b472c39756921e3c9d15cd6b4a1e4057ebdfb5957a91b3c7bf696fc8b26b54904fbb336dd4312dfe5173a5530a03218aed7d5a0488f18a7dc97e137e8254097095d17b1ddec75e1eea69143445cb49b6422029f5437754b34bcd9678eeed4ed05b78bd986f6811d0d7a8ac0a147aeb7c717f49f563032d6a93e0f690e8421e82739f22b8a9a5a37a2d984ef3719ac33991295b351a946cf5ad5cc4259343c914d7fda568f06055f78741768ba45cc3c1f69559bb2086ac1a871e9972adefa2d0fdf305623f1e05325305348048a92e875a7472538c7fa5b501866b482e3c2a9c78cc78b19347e246353b01865085971ecfccb5442c1372b4a054a4687a84c2adbb5261ba834a311b3f4c5f26b658842aec9173c3f6f9497ad2967180d0a43c01956bcc2599d46b7c72f95a4f86c330ce90dfb5ecad75e365da9476cb19148756b223b8a49622f0be648c42cf14df56420f76d7cea997119750707931ee7d4648d2030ed6dc70c9ab1860628dceea1c3ca2ff0d4b77f96cc0965cd4b61c68a3724cdcd13612f13298ca726b97a1b25a68d348942162d4dbbc3b8f6553fc1abeb19f701cf7a15aea7c4fa49e1786f7876a6a249ecde5cb18f0349ee686b23b8dc02dd7f81bd194ee1468904cefe534881a9589a4591f60bb4cd2943ac +expected_shared_secret = e9fa60655724cdba8f39d008fdf5f4039630208ea2d1b8592bac692ef1d66bac + +comment = Rho leads to frequent rejection on matrix expansion +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = dae0bea7f6a9ad8c4e5a65827c9413d2200f9ee2450a11b901b92f5d994dcc06b851fa02ae4397aa9653c22bbd64c17da68b7bbef40773b7908686b0cdb5165b090d4ab10996bb8a81819615406edcf933e905a7b1e2904f6480473b1f2f6a26df42981f91c7d85b95f9d09335ac7db3e75a4d0aba5867562cb2ae290c6cc1038b978a58fdd7a16c7167e99b3fd80c5135eb934cccb8e36278e7d73006d4b9cfa2448181aa0cd6afd9386768833a9d222b0575a76fb224950aadb990698133096cf33787d241b4264e4273cd5cb57345a59b8b3290f2bbc89e3a8da2959245f44799918bb6266794d6840dd1422c2a2fd7db4e4da875a87028630590e1a62e3699a2b6aaacc313935e9a836a35b3add49daf5c09adf435a1d293c08b159b3277c38a82f48154c10073e413bb59a996ff9a7bc06069206a51627403684ca1b91bab5b8785314cb1cbd190867836d7158d28985f90417a19e72f6504b51145bd2ba77234073018e8b2d58b0f0cb54d0b0b302a30473fa98cda4c0166d8aea407996ec86c1c153bf2591901517e63f1835f957da9b93f87ac64037cbf4e8c8a12a5069a190f4596b672ba30df0c2c9f7366175695ffe13d8b101d096341b1ca423af9920844b4add700a3fb0a4e6c90948401985b73bd7b395424a18ea90602659dd3d3904e9a2040c4200dd8894020276403800552144339a6ee8262756c31aa125bcc137ce0a41be92873ff83391a439f9d3b6ecf4bc642c0162cd377ff776d95d17f682141205115be702507ebb34afb4709b65820126e0cd1996442c777504ff85610d1ea8f072ca6bec2387a69cd8bd96c0173a4d3a11d73f24220b06d6037a5e0e6a82cfa1d5c0ac078d37265f09a3ff1544e3a4f58069c95761e73227937d24583cc1be0982c241647e983816423628c54bdb82146851a68825168afe1a282638242ab9087854939083175b75945e73c93d7651a02bacee8944a85bbd313505c8a8a6c86394fcc5e3b5367292805d453ad8f99586fa883a8e5b488f14d05b95ee40878538c5db7905ff4a94427701f322a713f2b8747a83e6fa622eba85e5374766b44000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e56d39b9ef43351ffb3c948450b3711b97491023125cf23836b9c1a9ff8195b7dcebb487cf2887ab8b42a60e482536839a771e9d2e9ab0f11ce5ff2d8892102feb73a98daf2322ea8ee2d60529ecfe3566ff1de818f60febb56e122f73b33d7b62a1e4a9cf709906237059426f0291b622ce45e486080b26c4b210e0bc25636dc6665f0d93d4e36600a3dee8d3da60545e4e1d58086b57c760057c9e08cafbdc43ebfecce102a965d6b8cf4ca2e7239d5e277ea18724c15514edfa390feeecf758c227be087aa59e22f3cdb0f2d6932bc3421af1e168b70e52cde5063012275ff406290c00a8d99eef619141ed4449491f1d0a16f6d05e39ffc92de2a184dc1a3146276377c4d2780b39a0c41f7e342415ebfd70d3bd25e86c024ca888ce0206e13b193194aeeeb0e20bf845be1409375dc9102d1bac4da34b1919a26b750b9314a56c338ec6adb6f22c1fa11c16fdfa63a791963204fedcaade790027c16d4e654feb89f8f0ebb9e5ec359acbb5173bf2efc6db76df3b57181b6a088e22bd42ca9ce22680dc6e52ed850da1a3f4c9adc29c74c4c0b6a7c1b09c2da1373178ddf731d6bbd537a0e74c9409ceffad4099641b80f3412dd90686868c8cedfffbf26be5932d7e708a08962e493d61cb9f0b065edb481e6f1bd0cc5cb46e8d70b0f98cc0971adbe833a40f1d81ed1cb9f6f9ac915884a9d98045763e1d121590269cc2016a8feef8c753704f5c7ee184484b77cede8a9ae92f446adde8b02c5d3b5a40922430b3cc728ffc214ad9d239028710fbba2da764fa3f0c01fef7df6aada040fa70456dcd68934b1837f36a3b3ff72ab66aae0973c86b508a2ad46edaee59a51c37e521234e303e41088baa8032c805c8813be285f1aa70ab16fd56e2366cb3884ee49320bb365a9394888edb0db117e775a76bce838ce8c73a9cb26340f6bea85f561c95ed8dd4fa51ecada76c8ab0d0a961dc4fbf0e778647bc6152912e0e2d82c22871343e901338336fea4cf780f60e3ebac1fbfcb9dbb78757c59327ad1e853eb26112b06a258f8effa9a46b07742d2c6519a07cdee75d0cba470f06 +expected_shared_secret = 02b43754fa1ae3ebf8986efca3a6ecfad8e0f32a779b3f42c88b6f339140b062 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 8f244766a14e42916725404f782693e232120dd9c7d52810bcf4c50bd4963da46570d85f3ca320ed980079e640c6802b94d7584d287de856b36c56aaed4135d8276435336d7a1bb9f94b86be9a0f36540e1c0aa9ef93af562c57581b7d8de8aac6343759ea04118c1a43629e3a6a0b0c470f52f7b5a3ecc49079ade9511456cc7513778434fc1e472c415e57c3841580fee24f2482cf0e381bda6b3ec4a6874c5a3b45737b30e96ab312997a45ce92115c0d9c0dd52b054456473a34aeb26c9c981a931b383867718558b887c08c16bd8899ce278154d04daf5817d39499d5e7501e69bb5e5c33cf7c08e5867b101909ee102e766460db12aef713b6dce264135596e422b2d89b61996cb089621a370896a61a06d36569d808a520751676098eaf153853667af01b3d8e852e80f4c8c09665306295436b9bf492b7805a9aa2f414bc00cf8a00418738922f146785a4795a8748d7f4c1bfd82a10a63dda9089caa6273e0518f656532be21393c3912d495a02b5c3ad94c685db282810853087613027b651c02b73d61a38c5a42766be8e16c5c254b6c7a45499493218510b202b141e516a3304933a06ce31741f43973734940626913225021b5c7b9e0ad9240385741f2bcfce3378dc43010ef8c558d3963538311eaa3c45a9ce4070a6ebc240a56ba8f8b3bd3ab42ea701b80584084bb7437e4369bf255d4e939520c3759b8b0968515b11551d585c27e3abb85478643f62b904515002e4842b455354e76b3dab6ac02188d4ea8f97455fadc43b4c079c6bd019f533aaec038374fc34d5d4bca89c1e59685afd74b4d7d370126886548501362bc71ecc63788707abd4a878823a33d788f84b3ec3f43dcb601fcc6c913efa10b1e072fd8a59d1fc159b8a0061b11e1cfb709cac9313ea4639120ebb402946b3554fc967ae480db1ab6cff796d41b84533dc73c7213db5412a526b513a259c9ec62b41ec307a623d461c0588489d3e7954228c916e97858fb8686b2a7d6e70c8a41833c8dc4e90b2c6a85556c923a764a81a0b8c0232f71c296a526a872fd1215b58c16f800578789077c44b3271ac340392000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 256ba1f234b35f903aa1532622e890454e1d8295b92038377c9c0fcad76c598d5c9f22ebf59a28b5259540a2b3f02d98f6ece8954677ccfcc1ca8d19f904ea4cded34a771d4a0cd8b02bf14b51062af035434662789c4e9b08982eb5a6c3f418ad4588d41e3eeb68e8c411d005ffa06e0919c9066413b6c54f65b2de9b4a9adef2f6ab45746cec985f5ae0a5a53a70bb2b120fd562eb90c9e9431f4d122a90ed2aefdb521d3a6d9754813ea02d4fa4849293c467497a08c2be7a40d4f8a1ece02127416a6f8410e545e723549b7cff46fe9ed40781bdd552067f0d8a127445a05549414244ce4f3c3d2331339c6049470ef70a5e40e7cc686ec634b8c6bf50def47497dafda76250701ae6d5fda6797106b668985bbd4e8d71c015127aff2f2810f1581aea1bd7e70eeb6763e1eae57e20903ef6a431ce354878ccf2330332c785b31e102623586541667e2ab6697f62656ca100f21ffd921b9cac1879f0365b6b402ca8908337e4f16636b31013deb2bfce8cd7d1cf1bab4759b31549db7eb163e552a7a5659970eec9b34ac410897c634885ba0d2374008a3ce74ae8792d86533208a51f822a03b6c0904a88702d55f42b30c0c5a30fbdaf9a1ec7a4c6355a1e384bc16e61bd6b432780ce79d9feff2ab546e260cad223f8d8cbd0a146a5095df37f2ab62b54bd37d62ec5ddca57fef7b7403b63a231347c10250476a96e1201e1b075fd4d2597e91e70ef0123f7c719d29762eb945a6b5d3abc0937c793799e806104fa0647e161e0a56969d71c25db43b4c6e299890e5e95f80311416fc953fff425d84d5accfd9357228560dfbf57b3a051e4446a7cd6df21c5b50eab10cea9cf4c1ca75a6ae145087de8f940522b8a731047a5ce1750bf617ee2313fa3a48631ce89e548d50d3b3f3e44053ab0d761f4c049b38be4ceef113e52da254d0412cf640eaabf6a43d619f6884ecbbae00032991035b111a19d9691979b16cc953b8df4142c3c05568f837f144a9c49da9e8efa52935eb44bc3a2a81151f6c006029c80ace3ef9b708747f3fda9907692d3e3c1ff144c0e3fda9f99b395fd24 +expected_shared_secret = ac258358b89112d41e8fa1ed255dbff7d7c46b14e2b3d176befb6d10b66a98fa + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = a8349f90a3956263772ada8bb1b32f083680796138112c7b2a15089b8b7f70d1af1f4412d20820b820ceb2bb4833b0c7cc2cb9e37309d810c45639137851252f8b9cb8abbe3ad74bff61a3e2771b3e2c459b11c0963492f9e9ab805a0869007797b0cd57fb2d73b2aea9436130e19a8079323376928bb0c26f679621444524a848ed71a1786671e23230467551253c5ff2d8c3c441b33f85a1c1d618574757aa607e98fc170d727318b5cd4c2a8d82e06334045176e736ca7727560406811c3ff3f556b9e55c426a5e32967e9050c8679728722596b1b280e90315fa299345e80ffa484a64321b9e67758f4a72531bcabbea81d528274c1b1bca21a539e42fdb1aa6acb079358888c3449d7a415a99b4a9b4325e03172cac247a232cbf9400c6bcfa4ad2150e6d3130a3882446b0282861b5fdab61668a9d726252c79057c6609381b3a39bd888c9526f2af73a1dfb8c76220037eb0ab88910046b565469adfb17395528bc54556abd867a7032a598786ff1a2b108f2498911703737ceded3bedc99bfb6d88c97ab55338b7a990c994ffc26b7a62901f8a6722b7799f246b113371ed61d9d706026514accca1d35a548b00badbfd1a4ae953023b4492615165b0ca501774dd5b4ccc776b31fd29aff0115e176181f606a3c179941963cfa0a065a4a37eebb3eea45290b917c582078f79ca05de21fe6ab7ad124c23ff027c6baaaad416e551705284b6229a176e3bb9ec92452659bab4ed42fa042c2e7908cdfc04f1904934507878cb453800a407754a5722862e2a4221746226b381a09d277a7776653e65a5f31be6139755719a33fb5be294b8227d87e02475853f59e894cc67983ba36ba0e917293f788b8d7155bce0c1c0293528dbc8339922994e8322cba0a2446686cca83dc600c5ff79530e9b8ce4002a28465dbbaa671b5bb02c2283a71306e83a1d8ac8f0a321425f52ae1e87227969c0ec41fbe5b58b0063e929b60e1e8818be35487d39bce68c55b91324a8789c94c1122b180a160bf3ad2ba76a7321df6c2fde1b20e401ffda0840812c3d59c2f3e88ceeaa0171b1040906362377699d980000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = cf388c22568418f011709ed954d76560a7bbffe29f5e734df76545886980387889a0e5c947df7b4431f788ade60203c4d22a3dfaf7909008c69508f33503b0bb12873c71f2f39e11d5ce7d9e9a8cdd22001c089c66757336c4d5840219cf021f27cf118d0354d88c2c2bc7c6d2894a1c41bcfd5a5abac5c17794c972411b30a280a9a3ebdda057b234eb26468a64d04d99ecd741c203993be49b2842a8866c5e85732d74d5a3b429f62eff9858e802aeed9d01c76d683c0f7b396d7436adefd2616033aecf9499a04d3f872fb3e740e9bdb201cde6494f1e2aa77107ed15d2928cd4446254627718760e2e3783333c59e8cf3c3d16ac494d9947af406e4ab0e44fe5fc608f6b69c88f8553d0f749273fa2c2029cec6e5d4a8a9d66e3c2cdda9cc440e0353edd1394c7c044e5765c888239671942d1eb6ead1745146b2cf81c4f196170796e7fb9bec44091397c29af7773347304d9ba51562c233174d2a2aae570c6184f77f85b819d28d7620fd62e1b91edd3ebd65766e3b2532acf887dc8f5c05a9b73b03e4bcbdae701c44b067a4b34079c0b06903261114e56df05b4468bfcdd0d41446336da83ea815c8ea4b9bb88a68bd817b629b2c10fe95f843a83b561db986bbc755737bb99bcdbb6eb45b8cf5891c92b07030a9e3f268551e144e4f1eb827a4c17cf674cc41763faf2a7a6425f7819e54f28f6cacaa060ee1c8979688199b89cb434d22e581788dfefd1c8e6e48ec9c870303a4a217b5be2dac4c93ab1460433f3b77cad66b8b2571f63bab6ed7dc4967e7bcfd5b2de801a1cb3c377d6668b67cfec133a7ed0c67c6acff96d6eefde10bc567e8538e9a31c92a81e4b8e78f4c2f9cd98a99ebe7bc762b251d0e234741888462268fc1efdc434dd96d7325f6b098c5da259b6f3db12d0d66132b69a2813b1f155430185ffc4738bf63478b087c50593de42fc2e637c0e97a0ecd61de9a73a6cc96872d75a61face7ea8c04a099a24d916086fc2fa78cc0b34eac07f831c1c73e1f1be3ba09a30ff5aa0ed6e7272f08ac1bdfaa93e3a1052ca59ed3f5aef40259ee42798e0313e98e3 +expected_shared_secret = f88bf7b9d9f65f61c7bbc53ce26d020b4b13cfec03a58edbb011060b32df9958 + +comment = Rho leads to matrix containing zeroes +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 55533942a315d6053fedc19de4f70c2cf7378e8b3ab28605d0f2c7e6f5892f4365e8eb087ec0c00d879ce1c87655e9b7b5292374f8bce4a75422d64d7efac0e8e62df4d952c972727d3c3199627d6d012e1c22a09a1498d423b2d9cc84fe168484b4c8f53198ba39322ae9c20f30601b59949b846708025fade360f8c98617bba23e777e51bb20f23c095bf06ce4b7aa9ce03c80a63f48e83fbe783f718355cdf67b019807eb129932e441db7a5210b85d92b370676685b66220e1cc5f084a55bf073d9562370cfc70250c4c9e2150eeb942b11c09450a42a7e708968786d359af48327693010a21f79106734f30f3220d38afc9b12fe316bd818c2cbeb3be1cf8af8aa119f6e5b939a561634875028ccca426382635273ee3c724d63db832cacf9acee749cd1bb101c5ebaf7688a37595a56f73125be4ab734b5c9b451dfe764f88d524bae85dad3c21573632c2043482fa19e80740275031f62804062535c1b691304696b305674cb9370fcb71c14b45b301ce8793c766f282071123babb74fd63ccadba777168bf2be438a96668d5e3be4304833233bebb282dc01085a906c0662676f41c1d8a5c1fc43b71979183c33b4a2f80b059d9be802647c987167dbc0a3e40067bd4793d093556c53f2684656d52af3e3109d61144cabc8cc124b5be20281db0c9f89b2b54a4933194162f1c62cd453f5bf26b42c85f572b2a961c23b5a1bdba638bb3268575b0cdeed6076a7931dd587df2eb06a73648c085843c94641ed2790b1ca64eda335a6a91b5311282f2a5e86282ef7986d667ce7c9c335dc733c890c0b7234253255876fba9b511a3989766427aacabb83f9bc9468f07323aba6c0588c6e1653db6c7c9b5eaa41d5262e367a2f3d47cfdb404027a1719f92f45735237a4c2e4215b47a59b605a35477887f80091f2a8a17a466251e12ff071a68a485171d5446b5b925fd4a12a7c70eda625933515c97c3cde8436ec461e77c247e29a4a4e114281313e7e86bcd5acc5201328418901f49bacb0b572e6bb5703e312b0eba18337bf34f9b09be2c77a403017c3a434071940eb1047fb8d23c5ab9094000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 20c17972698dddb68954c1d8e88216375343cf60923bba4f5597ff589f23091becf204bcc7146de96a87c151f1d8511f0de53d7f6847b28e8bf06b4fc25be02259160bb0c37b1217de8b751fece804e1a2f311de9aa66a1f6224d888c5157e81daeede2703f50ea7f0108fd1f13629d6d91226f2d099860ab37cc5a79c19e045ab3cf95b317fe2b071e82c1c6cdd830247a07435076f8b30296892f39418e84726ccb63fb8262f655d8e0d08c09842a84f5d09b851efaa6446d50fe45bf0bc60600874b5e6059669b7156d4fdc12a85d80341a0c721799b9214f2468893ad0d4d35b89470d1ff9740ab608e20d4c4e04359be51c7abeb7f5ceff8430236c43f3062e6f700964cb47a470b116cada012d0b79def0ff1650536e10b16cba0bdab69169a1d07a0db4a0dccc74710d3f9fbf8fa9342b3520f598203c6a4a21b88d70a8058d6a8cf33c4c4b70ee9636141ed168d45737f531f6a20c77acc0707951aa4bdc74993c011be7e15a0f93ef4d6b504114f76ec78e902e2ec40736790d9703d49ef2e9a338b66342676820e5e8379ebd16f74ffc1626c6bd8978ab5e6fd2bcfa048919ea762d3a774178477fd1a040fe7d5ce278116889309d0819712b5141b8666f8f51c8b1d2b65a3cdaf1df79caacf4a5845ecc3ea5404728afcbf5551ba692dafb0855154f6dd11237b617d9175b3ed2f9aa3a21c7bc8e69dde99019e35153051e2824c68d2cbd00910b3ed0a44a0912648715ee953602127619bcdc3f778d352978ae01a4be409b49e2ab7da6789c9ee977670adfa408a03c86137cf4175882c36506da106328236f24799d0bde55b75f76fc3bfd67e6bc1e678fc62738631b3df7187f2e8cc6d1717c998545c0e3c23d0ee7c04d0895fae02e23946a07be88bfc10a06087c637b4023ffabfa0a49a8520de75171f150a0b59822e56c210f90d121105c2248523357533ccfd62ee805c2890daaf8b60d17a4fff7ada26fee4725305dc48749a18ea305e94662ab10598cff1d2dec6f04e2a8faea3caa0899334a45700e1e694d0ac0aecf57facba6c47362bb1da6151ee27a601152d2 +expected_shared_secret = dd9d02b5461c15bb10613479ccab153855f7af2ffaf98cf6e3ad03c7f0ed0d20 + +comment = Rho leads to matrix containing zeroes +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 4c8a1121e2446fc9a9dce1641382a75d3a677f2b5a1b44931ad54c36fb75ce4b3e95988ee9ba8cca517c5b6c3da806b75cf2695853637c190585ab6921123deda4a9a659aeee590ff3969d885952205422adb189acc6aace7b3c4fc1ae9f2259e4e81df8926444aca0ba058f0af47c879371373b325ce4bd12753fd0b1021c2c5d51514809fc62b0c61771d824d6035b82b7ae9761c98b45cd6cf978ed852dd610b2a922ce2a134f7d52845d37204e1686fdb61e71068f95a06b15bc9b85c28190da27e0e5302ebb11032b5456c47fe3f9a86df68c9cc546a88bbd0abc3814e03a1752b8fa16523caccab7d4c256973f8bb7a1d860c5ba059ada0c80c88897f99a1530029568c64c8e051db3b083ec53094ef5c48c752e69093058969a5553c03aa755795882887c689ecc767d206971519ad9b1a60d8baee61863a729263d227f9066b2f4e99f4630a541e83d7a9059c060ca1371c162394cb13a1edd4c8d0e230dd56652afd32d571b972da2417da59942fba107a240972a5e63f75bd9c7cdeee61b216c41eb6898f775b957289da810cd41d0301ffc0a80454b166596cff76b8d883fdb0069cee2a95bf10568eb4cf2e744d229571e22c4302c153e5022059044cce93e2d8c9a046218a0e3730ea705f7a021705526bf83146cec2f2ae2cb46843eedcc4c90a59a07e753a8b60a60ba1d863bb3b6eb48174570ce6551d9cb3cd003317c663f1822bec20cae297c113043a891806eaa857d93a7520a4c16338255abdc7f2f95bd06e04af8084a9ed193eda00e76913773d41988b307729b9a15506782545d42ca63632226bbca0ab1f9218423c606a157283397deb0342f38428de8b94a5617bb22c83d38c8f40c5555396a52b84e7b0475f2aa58c42b2cd73a8b6cd7459940c9f1dc0b3a660460e20227d8b688699227ac592e63bfca6107c2e685c1cb5f74518bb14a8a67f35107d507f17529562690f6a06e7aba95fac03c51bc734e8526a3502d26ec5a13b8a8049152cf89901378194bfb5f0d24a133c8b92cfb8db9b033771658ff024302894cc898b28bf031fab3aab966900f446021c5a312b8000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = f676cc7108a3ab8cda5d18b82a372ef0e5b6fe9872bf9f5d04208bb504b149e58cf120e3aa5e6e8ac92956227506163ceb6d6b5457af3e9ef2357b150da229d8e9cd06bc463bf6b549c7719fbdf1f538d037d8abe252fa88d6ca8b8ea4540cde44c7a8d2644cffe86348a404af2e2e842ceb3f9cde158729b4a9694535e96a34c4ae7a41e8cc811f38cb3ec2961478c6f645e676ecd2e8ba6ec1b81a0d951d3853df6cd858a394971778e41049c9e8a6bab02e453aba4a583c4396613b37373564745f96b421a00c3ab2d4f48c2b591d4480f36bf1078c1cf8529d6021ce5d2ac9bbd41a813d347c85cfb64393b2ae0700384d74f023594ad9e30cc1337c89f523de3e69128d8f3d192654236cdab65377aea27bab287b7fa5ed51067ac569c0e3c7de658d5fee317ab76bd7ace11937299186d0ce733c05b64843fefbf33b609af37cd554b5951482d67004c5665f49fd2f247e21be1785d6b27a980b7ee0f75a840b49e1a829b37b9bc1e5ba57627b1dd23f939bb8f3056197c9017b9d47076f80b00116070b4c86aae4636e14794635d675a9bbf103f0085e67fa104884dcdf6f0284e7aad20e87964b39ef097e5c8490d766cb1f7e3439ea316900f23cf0dee1446af965b411fd70f7c6db2a1828d4f9cf793d766bba3c84610a20eac87da4d98d12bce9d4c539f7c329937475a729528e2eb11738039c35a1fc4f6c5c6e103be54e5b6133c6fd18c2144172a95ace73da024b371ea2fcab31bd428a143dc55af7913f63e548ffb709f55e3da9277b8e752aa38421d93b684ca1862828f2dc1f3d0b7b858c88259886f35f3120caa04c601fe25d8fa0c7466747955bb41371a93b88d1523f18076a968031f1baac78e40f9d54bc559d847fb7ce1f73fdbcf81761e2092e29879858b22b385cd4f3a5ecc910789ff8a55a119f90847dee220fd08e3a6a729fd375a1078658c2fd5dbf3ed12676168222886915de5bb41b723ddb902af7e8a892de7a87cb9341773ca113ba774d3a2f1ce31d70c61e3375420152ec6d08c85894382b0f771a4504f8a379f9c859547bf1416093305beac616 +expected_shared_secret = 75046ba6d8839f1b5939de533f2dd0c66ec58559c112c853cb8027be7cde6b76 + +comment = Rho leads to matrix containing zeroes +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 09dc2ba9e9320ed420fd4416a0072f3b73cf83c24e0523765214a4c94c992295baf7e5a87548347ea12be1c03f91445a6de0243ca0cee67680999a1e7b9b209a758420f48724230ad5a4c2b5a673f8a0ca6ca5cfc9a71f00d978a8c82c90a47a8ac0c8f40cc5bef2889f61278ef0a4ef1554f71497ff748a039bb0a3a92d6c67414394618909cd1c89319de4501d99cf1987307629519796c17402ba60da90cfb04618c5944801966a456a43c620f8a94175c33f1e456916d59c9fe7355aba11c66503251c436b633fa90c5b57477b36908ef44ca0fe8cbd40f0997ed27681845f6de1ae64d8a237b3c642d9a834b6034cc507a1c8a36246c1cdb42057e905ce27cbb59b5937107241a904959670471a44a79945f36269b06cbe36223b0e126f6c89b094cb5ad82a54eca4ac4b4a53b08b91a48829379b9e9e99572736a483b17c4cf100e0053844ac18cdd97c9a209c2e000492b34a35e527b91850a99299fb1104b240c87141767010932031ba8df15c6175357698820f56ab54d2093a5c217b1734a8f88e6dab2fb755b091fa07f4f16d5aa461679c365e59640fec05f096b29a02b3f94069f3962caba81d2218347b29c33bab5603594d8a089496d33d1a991649b4a03bf932a9f02eafcc005d34837de0b236cba834e3672bd2b19d47930949c9c62c6831c68a89b6b14f046bd09014dabbca628b0372a25261f30a1a931738578b51e8707254a7992c6ba06ba5b8c8a3f49b8c9a4550413845bdf545ef459c831899241443bd777a823908a8b55b956649023673c836cfaa61be51cb33299c02b2fc679a1acce0c32d5b0ca4f8473441b1c16f10872efc17956b95a198949a89a137e1064e973df40c776e89727feb28108352da4a19eb760bdee94945058006d70e88a1763b8661b228736b405811f56aedab0b43041271e86934650ead8c8543c977ee138f4eb3ccb6896cf7e71d681b599c0877da20c7ff49564c29a293fa453749253f9a2c9460ac1c359bc0c826197871268a12014a6f91c3586875b883a69063308f7722b4f3ea62b3073134c1760b9510a53cc2ba450510a4728b7d3bcc0e000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 44c20c571d0b1a531c1d01c35dfadec6b0766bd36a8cb3995ab01fc10acab18b999d7d4522927f8164f7e10c4faf5f37f28d1b72a8d0e36ee4a8f5034ae4f7dd16f7f425aa1daf7dc616ae76bfbc7df24c782c93887abf848a3c38fca619dc983156940611d4e6834acd47cefa92677bc9a3bc8a3739349c73247aa48c5393ceeab3f556d01331f5cf71ff106dd8f6e9d67babd0f5bac47404e5dd96cceda5d9efa58a7794662168a3e785306ae1e9f14818d55503940afc5416729f9ae99c304680f6f216e9a94c9f740223124a3249e1724679ab98b5350f9eac4c2f6ab697133f15dc716737c7a6c2b1f6fc41d890b0ebc9471404e4a533dc113e25fa7e6437a847cb49936c487716ea27792f88bc1affe8a9bdfa415ff489ef1266db8f554dadedb23e74f29e90688ca367e23c9ff6f6625d3d0497b3a6c319b889a56f496bfefe2b53b2b397fad8265396967758eb5eded1efd6115c1861e27c07cd700d48554b3edb5d76993ffed5ea3b9e014e85ee57c6bbd77195d65ea99328806653d8dc4dd3b9d7cbf614d2db04fe7203286c12a11b69f7b65c970c34ccf9cbbb4af9f06c2002baa04602fc1b6613392d46ae161cca228a4e535c523c66fc79441116ad5f2ce0c6d2f3594ec8805ef87247a7732136102abd01f9218c6bf816c07d7b755476808b27abf7ff8c36c4e04547ab8eb941d6b5337c6f3db79cc8ba3c627076b37fe8d916935fd395ec54e6985c9f3ac46f289b9647133f1382443ae911b056c86d0232cdfbf36f5b270099e4b79e8500c2f808036b5834efbc1b627e17bc9dc14517b1e19cdcebeb47b45a146248bb160ae913ff272eecc5613adcbfdb8a20c11c008a7f3fee95f0bff86adbc404f928421775582dfbe2fdfa3fa90d967897dff35c49d69b3f3d1f72bd41161f447f512aa5389ade703941da3782a6f879c3b3ebec28d0c80d4348879c58ce1c53d7a20395f5180221c7f8d4acd4f782d027de0325f799bc6a9f552b19154d18636657cf012d6b6b38bdf055cc5b1a31ced2ff446f8bb95eff4205d164a45e3e811ffbada32d0f973c8ac8e28909a5f3 +expected_shared_secret = 3909c469503925b00ee957476837e3d4139f2bab99c567ffdb50bc149e4560f5 + +comment = Rho leads to matrix containing zeroes +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 275aa91a11550b155bf1e529a89350d03088faa8168a4c0729001764735ac2f67dcd2b798b8b4ecf876b576b88391c42a25a75b5982021625662f68e7b261600fa6f20b7890c9347cab1c22c7b82227c6eb6c5b0f2f920e21353f87a013dc69c0f4b6d92d19df983931623291c639bfc4781cea5b12fa59d5af527f9c496ed22b408f507d8c62e39f493304aa9640b3155d96d0c0a048f6ca50ee162ec6c1698c37ec2f32dfe5b03472a8041e4802cbc2448c01cf80047489a04f6306b9775bc2d663757b50873a9cc9168454f292db99503955807d77a72e21c206505bcc7853f12a266b2e5b71b7195abe8007bf54c0876172fc939cfeba86b00babda12db24771cc86785d1a185924574f8695c9164968c2764bbc205967ce171978505b4c80e600d1fc4903d59fa20c4f39e5b71ca9b4933650acc12fa29a6ec95240ff2a8e1bc19f53268718b15bc07bb22c800e9ba66e5861c957a42933d5454e3818e343b091562e64b727e3ba20a3051b81605826a7534389a6ed6135ee590510b48b2e58bbe09348734820d708597bbba21de049398303029973c7b33980aa225b0a7ce4547968106bac3acc3008acd49547ec5529310324a4976f30c832596864df6a6b019b49ffc0185631a7e3f75dbfb05af4924a2d4259e3a8b23262c59b4c326a254eac18b455fb1c6c6c3ca1ecabfe4c6fe3124b46169a9e635250c21fba6292dcc85556d2c4e1796482fcb70271ae9809587de99bdddc62258a0777ba626110b2fca7174c1650e7453baa2b2a27c36212a5a7d0894a75b2a270e39448358aa0d129458b789e286587965e93c4c645b7536187644116c403921093767863f28fcbf6400d93aa96236c51c6980f105cbe1a4732d560130c8a3379a3f14653f4d803b3b7ca113672ec0784be05cab2b2a601687a7d8868e9b93ea4dc06b46b390c243c8ad04e29ea419d36b2f0b923bbc90fee82107a9621b26ccecb486a34f44d2f251f4aa9408cc914258b940327226b2c3d2ee98435983924c657e52a03c2732073c188acd2593b46877e02144a5959dbebcb05e4b185419713587ea42aa75109943377000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 925a0915526fe9a47858b182248e94be5578382fe4ac9749fb288d58350a6f70ab08d67ee8fa05f35f93cf9a9390d1409885135729dc047fe787c39c3e9360bd209664136a405a5dfb2a8da05eb4155e0d89a545ba25680a34ae9fc77447f7ccef118377e21336ee06495b9b12f52c0e160a4273535ae6b5e8636156d52f0b8e145a3ddf9e712e7245091e533cd66c99f550fe7f800492d8f5e94bdda722046f6ac6528314d1d8d910fad1adb9aa9353e0b02d5312242365d32fcf32d4cb91aad99eec0601ab5af11f17d130827f46ddfbf629f1421e00076be4296525c3e583a91caefe3b1e8a0fe478c0d46efe347fd98455c8d7147fd26e777790aad1b2235056d51573018590b00d158fcbd5a078707065f73b1ec0db2a60c737d4b39437565f1fc0445f193cc1312c9e845a7efdd4303794ba049fe8ff00a1858acc5f4f030429bb1114e8755ad94c5486a365de98610a6325db614c9ec75954e849df4310f36fe98547c8e43212a6437d8a3b5ac721f3acfa263ea842aa29e84684c154e6bac34b89983b2c4da699d9e2986decc490d80fc90cfba222cfda81fc95a9c572cf44ce317c8d624b44d02139fe8a7d68e2e6090d74effb6af254155da5732ba9e4561bbbb26a95d38feb45f9e1dbdc1710f86f02d9416897b9c0d4cec47a24497f87ae9ea392234a4938b1f751fdbf92a843ad4124243e0e784fbadb1f3afab71d148a393d77cd7e87f4279191702856da914287e5b4bff4944550995d47c875bc83c3b3b7fcbb16b202694f2b4b39a79abb134dc1c488f120b1f9f1fbf782332cd50e6edcbfb1cdcf8d6f6d59d055b463073066afd2b8686b405b852c0be8672da63714c11ac8499df5dcc5d12a349ab041ee42a9de11b4324d5d1311cda2065f469eac42fa14bb5add0d60e7c26e8056e26b5df1c9421382e9a157221e185630aadbc20bdcf41f948c7d866527e2ddb7368d7d139ee4329c522c8791526c1484dbcabd199da3583f1beed3b1fc6fed0f70ce4392a0cfb3b2af262a157a06295dfaf7cda5517f3b677ad46dc8a29a852d1857e5455a42e44acc57b831263b +expected_shared_secret = ef8a062fc7c8142a70fb1293c544678ecf8161560ceb65768639446e54c76413 + +comment = Rho leads to matrix containing zeroes +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = b2da7fdcb1c22f9290e94c5177d565e6b20860347581a174b5c7c483fa5163a568706bad37944aec0bad755310ad2673e5a15b951bc17b6c5a3345b0bce7af3651bb0d5514e8ea3a4752bc27b4caf0bc3792bc14e8f07ac752b50c13726bdb37f06271bb46a775a9285e3a6431e3be6c29b17eeabcdc95b77c41c9d1273c71d3b3bcf8091850683d1b5bd0c7af2211499750b03194b7684846a91cbec315be1064906b34511ca255a91561f1347d5b3bcf9914006c3694413b14428559ef5c4a6dc32f499b98ad5b60e58a6bedf29dbab685b0988e3f13b763cc84e20342e10b13ca87543b2254c76553b010167310a891cb4632ab1d7c3003393b48a7e7acd44212868997000859e9896178a8c7e8c73ac1166c22ca1ee9a216ce7856cec8bf46615cd7d61da541c1e2a921f9755b0971bf5b535969fc025df15f09e1c42ab5bdf4b76991e5437d5b64a265926941cf0e7956e492b4f5b08514d7bc30c05cf5bac145060052f77047e88c36e00909577dffca1538d83bc72060b88836e55b08b4083493653856784d18bc2d0656287770832896578b6c54e0b601fd53b3ab71301f707865f504e08893f213588b77907d1a6dae01922d6a2d2c72c21cb416ee09706e4972114703533bbd2714ca3b8bbc2c1a2be9f377fe176944065556da6e5a9957ed011014c014b7a63395f9964b45b30d6054e633b0035a0bc6c9827a518dd9980ea8ec72ec2a57feb06ccf8a166f282039e8090b8300ed510ddb35b024665ee96a089ae831b078c92f89ab3e7337a7768b2831915536704d2b1b4e6c8a55464c0879bf65928c70a15c74737bbf159ae4c557f3fc4034090f9eeaba91e83927d11dd444b2c9634499317630d93948f0678ad7cd9bbac8f72ca9b15546b4da3405bc6f0a12494878ca7d58c9d853b3c4b3b6424652193c85f52285d449911455ac7d1579cb3375cd733948d46f238b3f7e391c1ca1bc0a85a44858b029b05925c2ac3557598933957575bb8a8464ad1b88753cc5b40029f25c7fa9d5982a5b51d5cc5d0afa495207492e50482cf81a18a38027f64791d6cd6809c591f605505a9c27a5000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e61c2eb131cf65773d6d1724e9f8dfe1c4719ff2fc5f13c5d786965f40efa36e918079c591d03300efb6e5a92b50858e31aaebb73af5b00fdc9c55fb5f2abe77451d5bd08d6790ec05b70a62febc6855b32a11b22a0666a379fc6b6a7a861cc831acc4bc48d683b3d63c91440564ab71a73f2992f91026aeeffa6e7fd12971c8b83055c5ad05ad9a4638e519498519f5ba972207d9f3e70f5d180a78ea8ad4e7ee4a27a3d17c351b596a204bd67e33fb290cf7a766ee0564bb1b891b0ce21e9dc6cfbfdab0e3a20887acba928cfbefe279817608819548b5b0c73fdaf2c3d67aa21d9efded46b797107faba6479244017bb97e6f1d876d71309527027b9209ccd51940252a906a5892852961f0ce153da08bf6809a6141ba4581a3531e948073575b6ae4adb0f90c959221160725979a78b4165deaf5e1810b19b23dffa92c612401ca025a170058227f6f11f6913ba484f059ecb0a8bebd2f99e0b0defdc01ae3fbe1bc0d5e10010ff5b499e5cf5953f2b7488d63df51c876c2a9e3cd208a9e4d1c8c146df1051b7788e3c500b4868feec5d1ced4a97f916dccc355873986a1a67995eb898209a4b04d1007a5122ec98d9d6120c2c1380cf64723949ec3ba586e3ffd90f532e27f0f9a13d93094363fb65595644c4c05f862ba6b991aaf231882cd8c07665677994a39ca3f59cd66336b690f1f0eb50507377f8fe88091537f14b60d9f7004021a2f58b542ed39bc240b142aebf4407feff1d379915919b83a5cf8dc63b401fd05cd475294219758d7c0eda005390359b92aa403ed0feaf98780c4c2d20145967dfc26676a1dc998ece21cbfea9176c72117cec4eaa79d74207bcdc39cebbd53d6198e2a64731ddc14291889c37678f571a0297b041728dda829b0d2daa5db7d78fdc76e2d8fadc2d12249aad02a9548673a2478770812ef9a634f80384f0b21e9dea74e30bfffa64f9b62098b17217a59bb277f74a15525f719be859bcb8f282643e184978f44f006b05959ffe3978f9e2c011ae179ae4c3021ba9e07b000fcb439df5b1f460a34eed835b98e64f7f718692a43e28646885e +expected_shared_secret = b5a6cadf49f4200c81fe6389a7a59889614b10c64a221f961894b34feb87fccb + +comment = Rho leads to matrix containing zeroes +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 8faac9377487c5a12c1f3a8cb79325dea5768793b77bf2452eb693116404b289a456b61160697f867151004111fed55c534aab5a2584b6a16fd0e7a80a01137e92931807aeee17b9767a8d862914e899a3ac03670d7b41711a3d5f775e7d01258c584774002850087fd95039e456c059c27448c0066e6a0ca3c22279019ff1dc29803859992214b32b331d06120521929ad42e57504a74caa64f815355a0ccfceb229de85188c1207d03cab1224c350179e53a6e0e46389e06d0f1577a4dd572bd758f92453efcd2515311492b392f6cb1a89ba04b3685afdb97247c049f199a4700e44afeab1a36d553cc8b535925070b250c1720bd54f39d271156dec49dd6466fa6d98dd22b6fbef6a952e38043962dcb4a2bc96582b7314f59c8bdff43a4dd73623572caf0832c4cd9b9cef35e8c25bdfad66fe6932f37f8b493600fe1a954cef720e669951c1a087808840d460b5a4967b9175f31000ddaf216953011008621f2d9991a4973e32862ffa8cef7a6805ab478c1075c0d3b85fef04e8c345cf3d031ce21711279a4d2fa8dd6f984d1fb9d050785e0fa52e0e114d98a6ea5e320ebb7515ca1642ea1a6d8d119962801a23c05df24b1de20073e641eed63996eb55225093fcb21303944cb0a7b8e48490ab13661c443b1dbf0a95748c0dffc3950e91ec8b0640f208b79a6a2d5f03c38537bb571b2d0f93cec8c562a3511e7378fb4c72e6cba9e2f8c60fb160f59f33a537543ad50a2d1933a650ca66a7c5b343933536a3b98aabf42a6cbc24509b074719ebaae5a34b5d250cccd15bff3015d7f087a96710499339af5894a29f978d34c4e97116d182b1baafb829446ce542299fe65c52e032fc45510b36a512a27602fa447c010411537b17cfa59a81b33eeb476562c92a201116aaabeeda4591692b17a3b72e2cb33d03293e668777c04648d91c4b4b729328a230f53039a5518d2a723dd907e1af95365406d93b38c2d4069ae2bbf8c4b8f56262695e371f11a3fd9b46f8864723ae507368a813ec5af68bc8f6ca98c294b7df8e7bc9ddc83c1862e1d919130c12cd56821ff09275c85adfb25524bd6000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d0413e5b700b33eae7fb3f99ebc53ed20c0b645e839b1d2867378a9aecb2761fdbbe63316016a6f94f0745ae10aed7734390f0f88c112bddd0cd8ded64b97702ebe24836302343a2da87e5414220e24b453ceeec2f0c1015b68f8eea433d25401f2de7efdb50fe17e9651a7a13b329af5f4afcbb8056ee66698dbf42b56d2829dd8bb99803a73cd5aaa07ec0e09a01783d97c2bc8a6defd2b150f7c34afc62c823a5210e73ae7bb4ae84770fe33ebc80b49ea69ecf0cbb1d7514fcdcce1d74636df3d970dc81c7bc564daed20249096310dd4e5ce7b91e9d5abe046d228edecf4faeedce6a3c1c232da1b3ea3ba54e352b734b834d5e4fc7c5d0f7d57f752234c0b79ef3b2b29ad4d7a8ffdeaa75bf214c24cc01a92c789716799d8cec0c89317761afe0ccf1282836b2a29260bc9abf2a5f093e6d56a6c69a76ff50fff8dac59c0fda33815ed358b18dea26bfee7911b5f09f54d3ae3c49a9bbfe7ceb41c29072f2d7b5524d027e9c3448fb8c5c7d940b7ddc102df795b7ecd5370860ae3e91a6c5668ca8f54bbbc7256fcd88896730b962cdf395add42038d1c892658c8aa19b8735e9f96b90c7ee4dc93b622b1dd0029774f368ec583feb6ebbe83a6bea3561fdd6992ec6c828c3b0232391acd8041b41e12285ecea66c1589be393096a10fb023e7e6b14f81cf45cd22a95df8d5476e8f8aa6da2e69c4715a1b5f43e3c3ee45b112815f743531e228f7947087248f19fa4cbb2c54d42ac6bd4afa8396ce631cc65403c995f8f110b8e3c228cfd22a82e13cc5b314915ef19ee5fe4c66c8227336ba82591f2e8f9d0f0ade5b9b783c494a084bdb8861cf9990963c72ef48cfeae56257932d2f9242b7fac70a56e35cde75ccaa1ed1f5523c3982bbd54ab54819fdb1750df83523d0433dfd1c450dc9c1e2980e4a4bf4f3eb2ebc2f66c9195d6b2d1ba90f187acceb29c8fa7dbdbca949b69b2d532d36cf37133da291888ccec9a8f23846b0201f12b8da6c7017f78c43ed07b831a72c124a631eeb7c0ae5e630351c5d4eb5df98adf479a54b62760a32637433cb9b461fae6dd86034e7eee +expected_shared_secret = d48aca6a05bdb23e15d2fd645f4238aeac249a93d6a6dd6d6e9052d924c67e69 + +comment = Rho leads to matrix containing zeroes +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 5ec0a867129c83893eacb17cb75b0b2093ba42166fafc4986c88880783c32989b05c366b7601ceb493cbbd770debf879b69476452c3099c938bf8b45d6c454bff7976c96b0f295915da3b4b7799fcfdc545c3cceab238456eb75deb43e3a5a631d274d14889453f04a93e50b4045196605cee181cb40488bb1c8485aa0b506a51fc6983f5454173039003e4b8c56fb3a18802c6562907b109200cb1a95c10a82a735d4e940fd5195e2da59f69a66d618279dd60def2c80e28771a7d814e1c31d251c3c5dcc7cf64ba1a808bca1e7793bd6ba65a31c60dc1b9897b3917b5665b1698a009bbca6b3a94504d00c0f49078109326bd8a46ef11715de5a9925bc569c577af3515081182f6c4a9106b57589caaaabe54c3bc55f7328a9bf69b3e08a39d9e8cb5ba76f5d5092f7394fd04b008deb993d8b2a203547d9839cb719108f1cc581f561cdfa635ae76bd0fac0bada073de91c986c9e5f04218604a9b6543e931cae754a1f36b63ecde30502c9503ccc9d7a18cf80dba1e0aa1235b326a93922c7fb0fed269bf25a3d720327ad01c09222148a8b8adb1c5d54b8606083c3180b35a5d2c517770124580c32cb9d3c37b1a081438349a53c9c1de3e6a88b854eeac6796d2a6d2e9197a8f21cf1907b13094aff72607ba31b78ab5a3f43256b18a6d1227b65291fa0ca23a9684971f4aae688ae1ae5212cec0252d47fef21429192be0f291faf63880cc4b80d84349a7acdc18cc02798bf4150b54212be25e255f784b9e802033e3c2783243f63c87cb3e005568a77f4e537e8809b78111d701c1666449c38795fd1bb5341788af1a948e780a011004d90c78d4de5ce9625ba1964ccefd81917424b9caa3ca53cae27e933acc33c48593d8e731e2e28c62ac3a691828d1b965699417ece40bcd0b7b525ab0fe1e30034f489568a85709c3fe65a8cbcb4a42a1577d1c5bffdbb0486fac9c99600adac445df224e536a000d3ae463373db34cf42768d5a05b34d76927164b00ea29b511204dac92c7d0a3a36c3b050503912916fa9d69ed8c4a74396072bab6861f819e20b617721a74ce958006ab2f6ec2e27fd000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 7b63eb35e66f6f45586d1bd9d76c581952d352babc1df297aba656f1abfdcecec830dadf6006ae178f5a83ae34217dd955629ed59a04f1273b2fad258da48b3888747f05cc4017179f329efeeb591d7b2ec3cc9b510e3e9ab769e77dbc594050fc864bfdf33899d2594b651c2674cb52dd4b0ea7b0ef672bd5689868d0560ca059e1ca4b40e77d5f4bd17569645e349bee8666dd3c78d2680c08e1fb9684908513ca43544913536c593b8411e8726e9210159d0477474a66baf2239dd5dc7e390c2bb5b798c22a9e607ac7b4bedac90c4a414bde3e53428849f3a6ce0ce629d3854d26cf325fb2b8a67c1a896495d4091c95672c45b7ac10d053b540de99ef2f0666af51ada4634ad4707ed7ae593b1f03038e10b01efa66299cfaa9003c333203cda5d1cf95447f96bc41067706e189460c26b6471ada9b800449dad04115df8f9acfd68adf097b0318d32da248bc5d979885bea4e4516e5bc7e2313c7181a676780b9c2abf90dd69e478439813b2ce25a97011f9bc2dcca053fb139cf1c2ae2a7b98a3edd4f872d251eef7e3224a4470cd07dabf219303b7d8a2bbc8fd9aa8e2c1f6a474bad9a3214134cd425077b3c572435c2a36c8dee73ed60e90768efba107d1325b205c53fe8cf121a1ad55bc0956c8bc435dee7d60ca028b7d7b37bae0b1bbb7feaa5cd2d24ac3ec7f9003424468c9d6b784039822c62f2219a96ce629776fb55da80d66fa2dbf6b3b9cf791103c171086411a3be61e9ce2cd7e7c8e2fe7409b6a9d98a0609cb5bb1d5a85175a29ff68b98889efe42556adb997af34f7142d5fe83454dce13825abc0f59a622b2c32a35cda17441594f2774613e117fee88a2cf3470aa000cf9086a57fa3269c354b258872624894455de18d4e92d0156a374c1607466ead0044d30ceff854c5b7b734ba2892cd671c51c9b6ac5bdda9808f486be2ee0604bf9da931ac2be530016fd5917558347305cc0e49d1a1b5ab1fd7da126d1a72936da3730fb70101acd7f2f5cc40cd7f29e49fae66b6cd26a88074e6ef4c52bdd782dea6355bc9ca94bcd07679f555e8831e0e5c058c8ca3 +expected_shared_secret = 483cd507c824b8cc9b247bfdfeb2bc33a87af648ef328ad4855fcf93af9aa72a + +comment = Rho leads to matrix containing zeroes +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 9a2561f163735f149e6c3320173865ae2862c4204497c19bed7a6f06057ceb2b310bb20f06956bc9db330a6c034d30b2ac6a0094a0cfd7fc05808c3f588345fe70687fe9522622540ee79986539bed02bd9155caf48c62f5099fad44a96976334ea2b2a13992677a71fa8c437d188573b237ece8a129d387ae6a17f09517d599a36a4701ebe4b5254916d818c9e5db1ea6e6a9e472c8f7022807ebba4e80681cb9436da54daa5b611d80cffa4178022759e9632af74c5c5f4bc33e24b8767c2950e705e2183d97aa751086b5ad3649f11c8ce5615037b76de620a24e73b12b5cbfc74c1d036294bff9afb9f70be674a11d7a1ab0571112e329723649a43cc58293be8bfa42a1f6c1c568cbb771250aa46a988cbe93f408f2a117ee26a35939541da8504be197de36b0f17b1f2f0b7450687a0ccbce2fe80be97cb7e59ab3d84720977a15ab756952713a37a8b4f9734beeaa97c3e11496c6396b7a9a6a39ad2854ce57328681daa96322058b1b7f9647741e5345a955c735303812700ec97a2d0710a60ff89cef9053efacabeed5c58f958944953eee1a6d81540ef40b0f3b51c42d8258b259445d114c8749662be08adfc2bcad97191b888259b5a7a6cb0c4c4823f2c05a71c58b57c031f4b63eb4870409f10363169fea196cd1a36717f46cf883717aea530009205285b5635152c154ba7a0845c00202563b0c258516eee09c81b0ad9d05c96a7987de001792c14f280221d99063e9080edf14982ac6aff8f51955c3c3ac25481444b4c2123dd8c448fcb6a411823844801fb6d20ca650bd721464537473d79cb480e44ce7e0596c8633d4b39262ac5fbc3348edea1e4ffb02a41311fdf280ed251bef9b62b98b297112b1a8b09b21c51eccab81b6b81c746b76726b371e2b632f923dfa42bcdf7a9ba5b395552288329c99c02306e7f50db94b371aaac69ac092733b921adacc05f2b9638c7e71d1983d8c567738cfa0fb2be3fbae787cb8e7a016012c11529b410a44474054b7953babf455020f9a5e42f98619658fbe70c50a53018e0454f31a6dfc6c63b226801fe141c7410d40866eede2b90b00000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 2da50b6a160734993ab29c5049fd132864ba6a725ccaa46d0bcae2c795f38425862e56550948a6ac0201a93150b9c7418dde1b1295ebdc24e998d1795939a882d7527c36e2c789362b14a91a1d3cbe9b0111b18d70b3d6039dcd90c73d14b0fc9222e32e4d8d56b3c74f029b8f9ea27aa9b9f341b2e35384532e42a7a19693f20087cb4396f0e2fe177ad3806ac8c300710bd095f867de7cc92bc4d2febe7c4e2b84a65bbff9fb9a5d8894773ea449c9e378219a6122ab6e456969e3cf03348f89266bc65febe36fab1a7875cab8143411fbf6f27f731bee85418f7f71172ae58ab7c25995636f81762f77c1d693ce7c04e7d0e852c69a23783a16ccb9af36351440e3744418ab478e63f5773f124332440fa65137b2eec3f5ab36dfb7573bab80d972f45c6f324ea92f346c86356e31c8249e00a1771c61c85e7acffb2b0d96c6415d93941e0c06242da487525e2c318ff30eeed48d0757ff5057f52a2e9be730f5cb7a4698d4ee6b406129a6a577749d1827ef5321b208fe92eddc05239a4cf7037a9c89d2633faa6594785dc7f7447ae0928354ab9443a2f173d9e05cb8106ad4a0ed705e0dd90cf30d18a24fd6c1e669e5956458ffe8b85016fab36832c279560c45ef62a6e8b07d8455058cbbe734e1d519f32ad83ae76b0f39424f24287afd9dba2d5e17311e0c0f2ab0d35c762ed3f02ba2b9e9ff6228972e5b43598ae0666116e7180784595a8bdbf10c8e6340aa67860689fc246370f1ce5d61bea178a60c35850616360f016def374fca8f2f7b25de2311f609b76253736fe748ce098f4b25c3cb4f1307d1c6960f46533368cbdd8e00540f6a01e1c19f7724bd5d39089d3c97c31d99f693bfd680861d15a1ed8b2faeef3c2e0a895958d0fad228dd6b356bc202b207aaff77dd22e6e3a055fdf6abc5d9a028845fc0374a254bbe0cf0618a2441b7d2d03724dc8cdcf34379ce66a761f5425342ebf107157eeea69d26e6309b92b4e5f48a0c10e402574b8a616bf715aade0d2200ffc1afd1758e2779df4dd0c2846fcd13c83fa46c89460611dd30400642dfc18da2019a71361c +expected_shared_secret = a254f96b5d57129c97541005163da56f63ae0c63b559716fe001bb26271b1425 + +comment = Rho leads to matrix containing zeroes +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 749c7ef6c14b66c025bceb1ac63c8523c5b2ba742588716603246d258449adb11b57a09b54b32ed3f2656c138b16e8055aacbc1d5273c1cc4b3c5213b9f2a9422908efe51fc431b5e7f75a74f39a2ad310a827b743c1376a467061146b5db6149a897bd149b8c8b4978c430c739069349067b063a27024375d8aa5a8157941f586f1846b740ab4bbd2b5cb4243edaaaa802934cbe53202074a6346a599091772916d8d55624f8b16f74cb06d563f845b3b1a62b46bd0bfde75cd9480306d31ad1cda8f1a359f52f338b989c5eac3c1ec90b98124715ee68cd5dbcdbd995c533c175dba8bb3b429bf851e6feabb5114428ae2577197948372a267c57bfcfa1fb6e20ed68c62a266b68d875f41a394e972ba8d08205056722295c609149d363a18bf601cbcb81340270662d22ed3613342d6c7a5ac05a17b8951eb246c750d9fe2ac7e4423978a65a58855ef62094b571f2277b9162b44009331d2e4581676711253cf7fe5b9fed57c4425684a6abc858b2922f7c496f2b6f278a892872ae4f31f23394e77431e12fb6aebd20c460a915547bdd7640ddd6051499169603672b8b1b304b6ada2b3740c24afebd86572e3c8480c04dd43131537131d619079f95dce104eb9f1591d5a7ab1182c74169d083135ec094f56f858a38b0c6f147269a6008bfc11403b27bf66a7384b782668cffe08a4c3173e11056aa2d33d48072b08fb1b37d4964eb92b08dcad94e429b3ba27af65727948bc56e51019d826468b8dc31c8be29116f57b469e974494464f1f906e938bb2b8dba85dd4c3698128ee50c005fb3b3904cb88e313bef89152d4caca29b7ac860da3ac12be8a7dc8e3a259d1aae22a1965e55242f48f66c92e3a434855852db7a467171b5ffc91ac0a506fa50214a4898c60f5c057b32d30483162256285ba8a1a03214f5038d8b8b68b701c928b2f60fa84d64aa105d549c2302ed24b46a51aa676ac73423b431071386bd6bbee9732eee9c932965ceb756075733609eb99c873ca10c35a160b15b767099909a321f553623b2c1453489de3950aa04c574382d5023888e9898c80c5c3dc23508b28774b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 7a2556b83d6dfbec6d0c397b9025d4314eb6ca3efc9e954030737f2d72388b7e0eb94a5ba8a078945b6e23092a83e5062594c9606004658c91e8fe2f9ec87a66d99749b828611dfbdc0ccc4369a2f73aa9d5028594fb25c6f35fa3f0959fa7f361d3e60d3ac4ab29135db5fd944e402a2c070ac6c35033eba8d80fc0ab0aa5a0618e00da810a1bd858b15da0c1eee4ad80e0532febabc78e148ed1e7b1f705238615f3224ab36870b4066f60ca0d0b47b807aa34a763e7bbe51d015497f1ebbd3d24a777464e50c06b1820dcec10b2427837e4c73c05a6495fd4adfbd1d0b921e932e8dcb4bc2868bb19cf5fd00855503b8ac059b04ab583b2597bb6915181bdeb20b493d2b993e6816f0a4afc8931f713f274987153246c394133f6c51224ec5919372ea8925a3018ea111bec3602203c5928cb25b895c21678f7eff92cbec847a513652cfba4f2dbea6c9f302c25b6ad189366172ac177e73b5a79fbb9fc832d0257fc2c5059ec31f1f6bc27bd33c81f522107f9f59056b4b165cf4843383ca3923f3f4441400e19b5a232b74d59d2215b0b1f7f52f14797d80f9788b69586ef08bbb8864db10e91721964f0a41cd5af309e77e926deb44c8e7e4d97dc93d909c0ddef9e0b57e0c804690636dcfb9c69078b90ebc41f7d00851219619462ef2d073c8a7c6ea783885fd32399f332ab6274e0ea0e0127d4ad5c1d6a5c643d685d531760e12fc138dc3538293c41cdb23667af9208955a82b5151994ac911099cba768019ea70bc524c67d276d6c3aa21c96cbb63fbb83502f8191547afa6af0adb3fe610da54bf3c7bf863019ac965e5960543c9db210df3475a3402b4d078aff792aebc7f7d97ff01508d01d8a8bd7d4a28b5966c5b360d5967bd8179f0e184acfdbaa72122fa29bb9ab49db1676e5c8293d700149dc0051964c1a9ab9ebe2f1e581362ccf8d3c2f401ffec1a521148be65d1e509bae400721670f2b2aa067fee9f19f35687ac08b5f17789782cc19277d8e6cce0bf775f5a723ba5a68af7650b8bb3e05cd0ace1f10bfb03b3b9d4b1c7733cc5a51760cbae55e7cdae3e052 +expected_shared_secret = 0e34d0eec6ab70ad944b0c01940c5f13c83c14dae754e007fef6e5ddba5b314f + +comment = Rho leads to matrix containing zeroes +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 59f2104124373191150cd7242e627ef0fa82e7ea8583221d6d9cc958fc0824d5bdcd51605cd65112318ff5eacfbbb188467852d683180c6715a705cf298b0330e302bcfa0390e4734d41c44974a58e9a56c16327308714371a1df8a72201b84ec7912a609a70a477881fe802e62b2cebbabd668b3f55545529885f96f1494da6329a387945070f5cbc01ad6722b308562ad78388225f42804e88f4a8fc91347bb84aca827ca0959666a71c33843acfab82e469c953a9540a587a7dd661e873cbd5356dce8312f188a8632858ba919552e22de178bd9710990b3122c491531e142164e7936082036c8a1092e4498569afdb9a34bc1371ad92be6de0b49b67687f16acf1047d7e926c349b26025c3d2db2997d9562916c80c672a98b5b1769052519db383a5c2de4621bf4444e3c920f03d4181f277747a6075ce726b9e97f96338382c61365fb64711c5b3e0180a9416307d1ac7fd980059764067742ca9acf027442c71a7a208ac907483578c15ffc9a0678e29cbda6ad344894feb4a6b57bbc5ebc217308b18e178046d983bfdcc5a278061d415004d354182ccfb2eb0a17167e7fba7908903d8d3231f2c49c5e45be8de5a0c44b72151a28621a1ee055866ea497e65016ac104753066fd32978b7354562123491190a1b2700ee0575a5356cee89adf14996c9719df840189e558536e3ab8a3114be5294c083ce394a478e5cb63a1099923246f4a94aaca7cadce661ba90c98a98b79d4c1b460582da062d29ba5b7a0844c8f2267cb5053989350e228f2c489055b4b40c8503fd17039ea1be1443af54d4b292f9599bcc009327634a6a2ae0d6553604ceac4534569896fde76c31d667284264676b57fa8b2c9f10cacb1257b26c7dd27c6ccf96b70b5bccdb437326c39d453a83d05c407a5153a24a87446160486b07d4f6762aa19730086a98727083457eba0c14cf29c5483249974a85f6b112a0b31e580206c3c125a3f893f708afa0d146cf91007fd835116444b78731e1214a52856e50b31b8c929e9a146d1333655e09922784bb3e02068dba8861e4bb84b072176b29284759475205ddbf1a9138000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = f55fedc208dcb1c42948aeadf8e7806fac6ae3eccd1d194962b78e2e8f6baa837470bc53e74a6d742ad926800387a6e89f8057d5579485369880d9c0588f66b2e1aad76158b55f5deeffef944b911b6d3e28bb7fc86d2c7ca61a156b1e917ddd4b7273af89ed9520baed2ff60d6a4de0d2c568243c7b9bba5116635a2cde70d8caf1fb17b42cd013e0060422e64f7b68438c50f20c74762023fe544a842eae40a43108adc848d1895c46873d86f0935abe723eb7d2e43374b3370433bcd8ec0cdb4598a1c8149c1a14348abe397f7025b9859ffe64aa258d95e39b44822c09073179b5f54d530a3f6abf41106014c63e621c93b0b41d49f5dca8d4cf8eafd98e35388e2c807e4896bd71bc87eca94987981c6a055c9cdb3a25a5f24c5ec56c550effe30e16b1bc93dbe11cd1891e05bff43d337e34ba79452d6e6a15800f2084183d81d71bce6afbe5dd0e94e7fd9210f0a856f5369abb27804cf432bec0e96881ad8e448d5e4dc1e9f69f9f54f4073d02148ec0505d53acd337a664d6b7e57647b2e74380621c4d0e0755455296eecac9c801e7e416c485547ab2fe9df280a0847c0229ca2c5f0ac581c282d5f30140abd9d09c02ec9c9c6754694c870a4f606b625aeb6e849e827a821e3e1359206081579f13ea3b9362c695bfb6e7254a81f00e30ad61e9a0586ed242b72caec9deb6b4dbecc316e0e36d81a733af4d5052978f8a17d39c8bf3b43e02dd7fce53f8c1e977a6ffacd1228d1d93b8c01b756a0a60c1109a1062393cb7fe58d7001798a123cf5a3361e3dd2ac080160a2c01c5fc4af7636441eaf56a61a3955c27d4ee09654f1200a2ca0605ff53f8112366146c8d5c8b0f53fa04533063227bf7bca696fab752488f8a3088de07c9d2b36d6ed546b4f85873670d4e24eee31f446fe42e5a16eeb9daec4c57e6c2e0ab3724ddd2b07d84828ec7816b567e84db094ef9d518f1072221a3d3035c0ef9b61021693a713edfbc1d956522109f1bd7e9f86d15c5f24193196f08befc7db94ca566d0002b4f635ad1cb333531b214609b32751995376df32eae93d0da6d9663cb916d +expected_shared_secret = ca31bf45855855c6eb792343942c149c17fab10e25bbfa1a3ad916e1747fd8aa + +comment = Rho leads to non invertable matrix +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 1fbca0f5a93566588d65880f44d4c1ec8a16e5e508f7726107761cbf026b89c580a62abc82137d9b8b9edbf082980416c43444072c9008e2184b557dbc1a79598c5d2c95c2bd7c12aee084c150b90bfa832859c841b235eb377ebe533469660ecf784faf862c6b026feb36508130c3c09196a146423823a210b4250e2b3135f1686a4c65d3f878f6233a3d48264b3302858774be5b328fd801164b21fd3c7e547c65d83894580536ea919fe00609a8f018f5aace9534c3d98c2508841e448440750747d3e6ba2907928129843825b428f650e8917e26787883276ad1116ccbb551de12755a4b62dccc5ff6ac180672735e354dd1d018cad55bc997bb93ba31d74c49dc99cdbbe359d834a65eb65c044b2b77754cd380abb6442d67440adbca3716a36b321766c6f40051617e716a49475ba2995b73b7fa45d4878517c45358ec0510e849a181be28c2000b376783c238c6c80300d25e4e1724783c182a668f9164c8e31112c2723f88087576a4c58e4a8d345c88fa4674ab9a2c3c0ba849847a64cb00d4d3b512758ea9d3892cd014370940cfcc4fad27c4ca09a9cf9a2fecdc11eeb93d88361914762c95e844d80529f586259ca750d72269b9a28336668855460222bb27af073260297910f1250336169de469e93093596405123398c861cb081c6833a9af25911739e9c1ab1a2817548009ec8e6654521e8b6efa3abf96c9354b7002380ab76f251d7a0436d69345ad46cafbab6edaa66123f2389397af5226c99401291b9722ee634d286619319bb5ee1773f799bbe54b6ec04aa6dde72570e8983e244b8bb1a5b0ecae0ae23618fb307c322d21017a241808cea14c2ad2cd9a474a11a2ba15cb99e29464e724322763914b1cb3a2859e716292fac42367120cefc7a9e66a63ef891ebf21739286083e194baea6bc4f84932443adfcc37eef5452cab5c3e67425fd751189e87cdfc3220e041bc1b5399fb28c5da2093993c66b8c5736190446d698be94abad3a7ce14b11454a8b1f2421c2022a5cf00a3329582fccb104c46f99ecad91d1c6caa2845f4202ca5520ba32376f93bce1e8128518b5e578000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 3d2107ffffe42acc2b1d2efaf99ee30467058ed826f28da60d0559319ce694dbae930a13dc15160ae3fe83b1fd4fb012940af0cba980ef348208095e0806f2c9cdb8d692839fb938b4defe6e230e810cf16122eb214308905940b184d5d388c478f73baab6e72976e97d95956bc75743b628696e657bb1e4c2388fd67947bb6cc24d6240b61eeacfb9d08ca46264cd80e62ecb994a23b29daf74f0f86dfd4a4f8ea52de6332b2736876afa6b68dd1ac516b77495fa8b5e0bff2231b827b02d3eeac779d25d018e6dbdfa352ed798ff497bef3ec7a69f151ebc422abcb0b4ec2a30009227b686f266bf6e2c38077ef08c32faf5ea6c5479a06124d5802865db29f44d169c73b4a2efaa559d312d92c885d4b5f96e7e69dde7381641fbf2a65710f62d592356cccb335242f34f641100fe9862dee601e07b90eb026a7325b4b683cdb46aa8a2c47d2576a5664cfca8d3b23d43836669c926c5e7af08e9835f0d098dad742e0e0e3b811f408167ecf9658f59d659d1c379580293e4ae2a8140b4b2bcd09a9f15d2cc6c137910ffd493d7f192bf6c41f0746b3fb88656eb785bc3d1e2560b8a4def7271488727737ed9a6831cfdde5fb31089e1f04a0e7145fbbab824574d73e191d0f481fad0a6280cb3e94ecf346bfb43e5d87eefbaaf7a0f9c96711d5776776156ea9be4e57c72addb3a31d997225b858b9366c02bd648a12c45143c18307bfa72526d6330f1ca626516d8a789c8ec732e0c7f9f0787f978dff881ad3e9ce009e17d13f0f4f445cdcf2b91ac6f74e6b1cd196370d0913282721b149eb999136b2c82a8172fab828305fef2b446125f258ccda8c2594d134a065b50c03b630b789fa70d14fe143c4e69c0a8ea956da7d4c58b3ae10458c59c81761082f3a3ba38b5e2ddfd223aba80b0bf2bf1d9c4a5d97bf42dfd7756d15b63cced76c1af8964260c9b2785e479c2ff391f4817b6df85a4fc05a576534c1125c2ff27513e9730de228e81c9915504f42f81916e4d30ff3475026859ffe0a8b2f27b752bb4e04a3d1e24b3f3bed914bc2ef674cd23d03fa28270f64d5d11e8558f +expected_shared_secret = 07fdb98f4a61857eb91ebe130935bc346ef3bb731281ea97365b3c2d2836b47e + +comment = Rho leads to non invertable matrix +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = a425484dd07076e0993fcb9584c091ce561b3efb7b96e9c02c452d8146cfbec52a83765b1695815f82291b004f28f00b54c936f4a2034c4c861f33c2f31384ceda2c9c85709c072c8dd2ac2bd6ccbfc1bd6d09038196c2858b1d946a9aa9c7588a1642b20c865b52ab5673cf7d3b81eb22a3da7378e56327289a99a3dc301d90605708670b98702bf1c30c21cafd1cb505e46f70ab05c180789f5cc3a06b145937185c3904d88312764bc4a0e1a1f8740b4ec37f9f150fad8b0f102bc733e86cc65c35b220907785c7d530bf631c0a54028336ea30aed13273f95a01bb2e3105a97c06083d9b0c4309b8c6294764ec9184c7102494b2f50514bbfa79c72a11fd9c1e91757e630baa9f124e6aa33533930a07c4bd0c155969143c69392130909e9c859dda1102bc804816d67c268338c0d2be2f624c1e8314e057b31119a008da1bf075ae92e01ec18c7f9f0b99dcc39c9ee3b27bd10b4a987fef3ac23b7a9527607fc8e13d0b1a04f900422b6a6e1b3c44f6b7b4cbf18e18a6336e4651d34052b9eacee2f6be3cc818275137c5254c59d606e3e1c7f6f4083a922aa0bb2457d52ad7e3c120a741ede5858448bcbb70abd2539bb8767c23cca2bf20bd7af644be9476561ab048a92713ec99dc2924d1f445ae570e9d2b5bb0faae7f556842d51f47e62a23f36b043acf69403536c6528b32a83b703ea4341316a03b696c0331e8a0a7820c67b992e42390d1935b8c18722ab723b8674182a02c8119479372981c35bd83d3538e09a3e074243019217fca81256530ca7034262b55a752778242338a7c0fa5ecad8012129e13a4563861f27596257a7fba43ce460722f0d930ff90c252030198a9680bcb1632b0a244f705bc4324e2a73e1c4a61f014857975adcfa1506fb1abc76502b0799cd71348b6689c9048bc0e1511403099069aaccc19019f461ae672541a719c2da50317428000e242d17a9d313164ecdca705d6a2c808105cb10c15d49ea7e07936fbafdbc919e22993640174ebb30bcbf20a14981ec5c1cb328b14c7c93fce56b3fb343bc1cc368f3a63b16bac72e7b130facaeeb34e2d403c4434000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e0abda2b44a5e6713314a3ff62fcaf75d0542d7f5868463baf62fdc819356deec009c4fc113eacf2db89711bc9b38b30a7d368cef8fe5ff014034c277ac05d1233d0a82db47d3e55415c8b4824860092e796b280a1c805ad7b47b97c2fa35ce57d72f17f1f7cfa0d85531a342c1dee9e48307ba341f514ff8013435f62e04acc594a5ce5470b599ce20bc8ae729be759bf346a92ea55b39020bb2ebffcd2bd6c8dfa9f703416dc2dc422aab577b63cdcf44376c4f0d3257030bbc2c61cc20f0bf6ea0433f7f62afa68412790f471d03fec734332b04e49a7350323efe6634642794237578cf10b3e98efd822c6f014901ee96103f0fc508d9f04ddb14261833dc6f994e3d136a9fa9612725c9de812f9590931b67f0858594cb44628393e625d8c0d1136657743aac7a24157e6cfe0fd703cb42907ff6f6078d35048af75018810c73996c35d75900ce3b72870f58fd8d98cbd14a197c91fefda474abd857e641b8afe1904b1b6fc5c35460be2b640c71982dc7dd3543d85826349db597fe5e1523baca431b43979a24ab0478be960efea436e82a705dfb0850a41575e4e508bb8f78109e5432a255c026854d79ec85b6d0f2d4b6e8d5bb37d5f9ef73f8a2d2b50e7bd041684f6299051e68e60d11bd226401c9fb4e6c1959c108ebafeeab62f7012439aab9d4da8f0286e90b65cab2399d1f9615131cf1fba721a264db0f129c84160b8c6a416d36d3379e0bb02604d6c8a0690b32a046e53e7bbc35cc6c738c4fb021d514c8c933ce27cee04d83543ab444da4e959502d3134d811d7545ca6dcae7c606533d74bb767787a7b141252479f0c76e27d2f9c0c3b9d2bbb76ede717ddb158d7eef059502054f81f8dffa04592fb0bc64cea12b5b3fc517805d6b43cf07a36f018f714032791d933ec6e46b854b6b8535ce685ed5e58ab339d6e859e8689c75d28b3117d6f31a2c4a26571c73e49f5fa733353c5fb5ffa331f05db4dc73ffa4fc7154580722e407629c5931337e5645be9f00a180c406e486432b4ebef8f28a7626fe257519f781f206fa3d5b206a073dd8a2661f6e066c2d5a102 +expected_shared_secret = 24f2f27886dc91cd2b97ebd88151bc48d18ede15d133884cd55c65c4c1af4717 + +comment = Rho leads to non invertable matrix +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = e60b4b1f6b808429aea6f38875b2b5deb376880c321537939840905af7a93d982a5b701b6cd2a5dbea7393c2136fa9a0c9673175986ff071517ce0907ad7c017577063ac826af10e63d49a57b6bb2572a4ca014244e502a9217d22b1813d88c52a564866f0c906fcc21a95c5441a98f2920f06189c212a5effb02cd8440a0be12ce0bc1c8b5720f8e8952e5a823c2432dce607f9b9629fa0315720a951b87b46a028e2d5771114c2c2250c541b1955e01e1b927c89439eab75942f04b009a26a1c12616ec028429c7336173975628af8891aa37c5fc88520b5fb8fe4438bbd4b19110b9573215f27e9ba2c48931348288dd1008f400736719f058c4109c0c374bc3b1d8609f188866c608658f94205f6a478208319419d46441e0fc5cad0ac1d31cca7734b71ab968202834bfef945c2508a3aa5532ae74c962550cd05b15a0c4232246f01c06b0b1c76fe461743f359e5a97bbf5b6d7d110583e2a5b851036aa85731c2bc10502c5c760092a8202137cc656a0d36ac49c1470d854603ec357433808415b09f3018a429d11697b25cd4158c61102874ba8d552ca176d837cb5659d49704ce24823700a3558566871323046c1dbaa6aeaea44e24f4ac9adb6ba0ab30710919fe44a8f61ccc181c6317f17edc64ce5c6cbdce41755eac909c4567d14820d1ea0beffc68adfa37f1f30daa32aa1d993765f195b71298570c9150b2c5eb0687822469d339ade15b6053bb04ba4a67755c9c4a22ad88295149477e512bc45867b365d6556c608363abb53da080a01334d014caa36837fcd5bd95a6132d4abe81865ac3404ebcf57ab1e7bdcfc078ec459da67bb40cb669ed500e464b774ab1090bf4c0c09a848a2cb46ba85ffa339cfc43679f4c1768956a9359945e14836deb87d2b1ad3d6c171dc4803bc58c1488bbe8017b3028362f4b0899563475998657a279afdc57c3b9ca5d9b0b1b12b67bf2ba0b106652c344a583ca911a676ab7cabad6598244c379934a16e973a5e413c7907af84cab87d3a15845b9e18956c33c6b9836bfbfbb3c6b291cfc5a455be3b0ad17bea621a4d9ab495f4671ee78f4ac18000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 6cef85fb2ea1e95d3afa336db82db61082560458a43e6f7def896b307e6e06c48922c95b6729b7e2871b75acab3241b3599aa4d15698d6c424f1a4a2daaf9b1e1072e4fe025609443271d51c7a942ab72aae3002ccf911380e2b8b6b3c758704006efc7aca771a7a2909423bca6905d1379a3ff6a7e443ae2dbe5cf544b64049e88e7ae0c47249d7ed63f4258d2d62798f2eeb320df7cc448e678b6c00f91edcda89f3a9e2c7c86950d0768fdc410731711610c4f6962a036766f75991db266e8ad32d73c0db991ec8fda771cfcd0be5cc3cb46e90157158bfb4bd1303a2e4746a095d53572d86ecd74222a85928ded30072c6fabbddc8d205320a922049818934d3e5db9189ff458f6d5acc98ef72ec28dd684bb565a54735799cadaf8528992cb5d0065968a03dfa5ca721c9a00feb2c61f32490205ffec272b99b72c22475219058b76c91340734ab7ebf62efae0dc1c9d8660250d24a94663f22442f1539b64a90543280d52ec3a2e276525f9857cc11b70af128f94401b8bdcf2beca09cd9a156748d212a02a79e281682ea01d75b28facd1b66715782267bbf965117a3ab23609f9a05fb6d3106d57be96975e05693740b28316bb1872be7d8b2a0c9b723f8ac71a4f32db0736da5d57c4a50114d1dbae4814f0bc7450c6c78465bf4cf8b2a9e0a08e7f0250b82975efd82ea6c1319ffaacbfa1c09919c15a66a80bda481ba4f36a0a7d2b02b29aa6d8b4d21b0158a7b4984934c2179626e4d329c2b39c743be34e2dfe9bfa78487940516368bc79e48aff6eb2d02783c88b9f6780b8f1661501b49d8c2f23155ef0ae6dd02f3993c969c95e19c91c1f1153c445a6431307829c8088cd4f8d0d6ea69cbc44b915634b871c0b39d64efba6298d7448d4a654e14a522909efe25072f4fc518c3e694b948fb5f16b41c7c3b91243ba092a951e1cf5fdf1f6347372f9f374225469d552cbf345419b81e27d51ea505226c8aa85c603948c0f959f5ddf9511642dc8b959eb536b11787e604040aad4bbbd1167c9070af73bbb50709072cdeef66327d67fc299c8c903753b03bc69b03fa3e5a +expected_shared_secret = e00425c727c86b827edb8052218886f737696f82b3d3d958afd73f3715b9413e + +comment = Rho leads to non invertable matrix +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = a94479c2f250c42387c2bb90148844a47a4bab4740da5b20de8b50e18312978765a1385d853741c4bc33065b7a2d1c9926bc125e86694f2c9913bcc921a446f6f4a7d3b56dfc7152984a65088cba5fc93b8cd96166f43a47a5c126c8a8a11a90e0b38a140448e4464a61fa56157a1256540f8a3c1c3d538eead78f35e796ae60abca6bb15eec4e118005ecc631815189bcd9a69a1b9281f53a35f08e6b5095e598145e303077085725241815c41cba5b3dd55aabb86a8e8fe87cb6870a549702732c0b6440a8aba22cb93558aa8645d7515449c19fbe849e1e91aa6fb744a5119138d5684795086613c0f7a218d5369d3f7728c1f9a124f8c4f36b16db63b49a07c3f93926706863a6674632c4a90ed4857150919a5a89c7215910f71574ca27a6371b9f9165721095f425a0ad894dbb5535552675d9c93f49a574f7316107d967961ca2091b9639626ce4990e7da531fe91781c146c4851497213bf246768b65453e6566707c48381d25830bc8bb6782386e95056371d3df68573329c3e537a77fb8830456afc678d396a15a1457793c6042f33c7d69ca2a3b0a652916de6169233e7be052cc153c09c49f5b4d07c806ffcce1e8712904621caa345bef6ae3229422f526551708463693ec228a05b82ba8231c839847be5d4b9c9c19b61802f2c777ed5778822fc9d51b621222b5fc2a86094e29f782c4e7361c90d071dc0e14d0848172841c465877237938f53eb28319259e56290991b4e0404cdd426c3fcb2a1bb4935fa857fc13473b59985e9da90ea2b3ffb370cd3cc217e7bc3a4f64bed6832d53667eda80961b7bc2ccb5157e3448816251a474a80f824b957794099a74ff81ba39c264426c70e230e6b7c76b272b00598ccb4561d7075243b0351d32222f66a6f9db50a5e65026aaa2713d2549e67442bd482fa197f836166d99507541b6928b59c7d8a16cb6ba0b812690c9416154648b59b937b776d22163045bac48d698725f8b0dc1b11b2866ee9600cf6cb9cb99151678a87c3a1b08975b1a0718ddcab5aeb31a5a3815a090632b48329d106b36a671c61a2bf3b087ce5c17217f1418116000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 898fc0d2b7573dac9db353fd05267b4f1746996b4a4105c3a4cdd4cedf0c10014d26ee9301a38b9e4d1cd2368cbe357b3ba4c30a85cf2e96ecc046756862ef3a57d1154671bd90770be8e3d90ca391e3cf80b08bfc6ba129e4d1a74bc739cc11ddf11f79728a510c310f27525007154de9dbc7b3cf65bcc90206c2af08cacc78bb43d0884583c872543116afde34a43d2a20651bc9d5d7eeb08a2d0943e71437eacf147be648a4f39929e3c74ee5291ec8cf1327bce41d4cc3284edc113434bb259dd3a2c9d80804bdadfa266359a64eb6215cca836bf960897e796b117e70bf9881daedd2f5ab702b7536f5ea803a67aab344f209b270098c29e419b1636441eb3e9a921db1f3cb687d36e19af3f01240927ad160cd0ac0ae0efb45fd46cc8a043673b76232b2455163c5f3f6ebb43903ef7754bfe8dd58088a8baf3318efb9ed21153def55888e5335a46251bcaf282bacf138f3af7a4295d8448732c5549cc138db33037c41cabf92cec6636071fe0a62fbe269fb7b13d70004cf8c1e3b8c18a99861fef295b8776c1aa2496d2d9bea69b24d84fa6885c043240d98c90bf6203d92e78cc94047215a24d54f8361ae9aff03c70f72c25a88578d90dc7357f54ee15e54588d0630c84e1a13c4bf8492c78391970e80be6e29a4b7a9103539294685fb4df7716ca21d695873eb3661dafef54faae9049c08ccf9d3a94178f7016a5701930f8b604fc88ecd703e68688d7e83c2b5683e983ce7616f45da09312a74cfa6ac7cefa1721b877ad87c9664a556401cab3b9195e21499c6e7a41752fbcf5505d9b0d86769c49d420e646399230ba6625273ea02728c0999523170ef0d94ea29a7d03cf15cf1cb08b7b3ad6cfda0a510dca59fd445df0c706519edbd5949baedb73971a4338959d39b66a9a7c52e4d6abbf71c975ba77a28bbb8762a2823056c8113d927fba7ca31725690d78b6c88e771c6a90f66c581fa339e43ce18f92c1e011af8332fdf21f24b7320b18d6a8ac00a5f786595b002de716778f554f321291b5d175bd82ed0466b52d7bbac855725198cf9ce60739080770051de02 +expected_shared_secret = 32ca254e8c907952a1a17523d1a585613d7f40535fd5e1b0920153ec30bd77e1 + +comment = Rho leads to non invertable matrix +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 27b4235f044fd07c2fe1a63695e7399d01a373366d8c835c2874031b3ccf980ca026d215b7805880ca50a56b75486b5370bab08fdc09ed724a7e825a3263795c92b3ea389c1e8745334c7f47ca1ca622c6b840c6de4b01656633ffa537edf68ff3f1829d4b98ee59c654ec1dd2b8112eea2700ac92b05457e3714949f4476bc7584d6702653b28931a3b660a97f0c34f2b81475a3b4b2b121e44c85eb9415a94b10c7a533c33ca3aec249b7d4a2a3bfb501005c3bb70b9cea64da54563e86077e19a2eb2f74356aba1001a72b4d98bcf850ee422816ed99d1b154ca88ab740a20471d45c8ce1af24306e2d67254ab4ad3ac54c8fa96799496900742fc6062ca2d969c14c206bc2a1d1c6aa99a75cd4f18616d138e2b28812c38f85138e2c9a21a89855934b83f45b2484da4533125218314c08ca41e21250ca270bb962ae4869cbee927509b0ab6d7238194c0ffa48a33c3187e243017e7cad326445d876aec5ea95bfcc8ab3c4428ea470e73433fc4bc982b364db680503879c24290d15450fc7bc737323ba6f295a0ccb0707054f77c32b33381daad4236351a19b30a7cd0b75cf03c142528b7724555d7403c07a7fba0a55c7122ad7037b65ba90754c2d5bb3a56b91acb5c40fc6145f5ec98f882006ca982831e99badb698317428ff758559951b09e489bf34c70b901703b3a6e2a0894fcbc2c1286ed5669c6a53b35545bbc16a572c3256c0fca995b890fcb401cac41d91455ec4b294683aae5f0843ec994fe046767a112e0f0ab6c1f9716dd68cab92b449b326d3db37548507584259a705ce68003e3ed6cc56586343f4c6b3e4b6714a0bb27365bd0c1531584811a935dbfc477663c5bd6bb53c475a985cbc84d94728c8700f429a0d67136a27593b934133245bee569f74354c7f279d9fbab2e077369c26cb661270733a857403bda5fc5bc61149ea419ba2911d4542a223361f27e5cb2e5a6383146d3f16c945ca4ba23110c773854da8c59c783f32d404d8c4b761824e8ba74dc5952cdc3526b3a62d2a37624aa5c0f6a0a9001505dcb47fbea56ca3389e07d064c033cb0ba62e3789f8e20c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 0c0672109ad2986c89c1b456c35f2c7334e47f8af9f8710e70f9514ee15c0d0067970f042e2029ab269d6ef56f37d85c90b51b24e4e5fb88420c6257b3ec5efba9041bd6c435c1044c4c62f1ab4d06962b3ac45e0077bba067318fd3c7648eabb0a8a17a286e00b0d56bb056e1c5a7e475b192a01b82e647fe87f822954ebd500d1370e29d7bacfb0da4ede93a8539c508c819caca82f6ffbaedb3f512096b597401380dc0d22532c43f348389ce3ce5da6789f383c6d6057a56c8aa5ecc6cc3b1cb7b2fa1a7665911a407b2ee9f9ece9943510c0bc98f08d2294b4f49c9298a66c28593a8330019d3185331cdba4e876d49be06c0f394f613282b03b4fe4eabf2ee57e0cf6f40e31b7614302d4d06a06dfd55ee1d72e5cf1b58992b7239d6e97fb93134541f31124a7acb2e07948a8f55001c7a21899767b9cbd0ab722ffaac73459e768c7dbead24813f5beb65406a41a31faf63d58f36f119e9999612cd09d9b0c929a43d40481a08191c79fab6edfc7dba5e4e4d3c66db2a4232be62b748cddd4445fb38279a13da6e9841e27dde1ab4daafe22a5723e3c62be7bfc4bb4e5fcbc9bac9a5d1d2ba691c56fc7e52ba391c1bea5280af63623445a50c5717e5638b096c13597bcc7117a3a2113fce277047c463a31579d91ad46a0995d5e76065ec2a6ffa8783ff64f1dcc685e258ef28a0a3bd66708cf1da4b3587db7d4a8aed945b69c6dd0f49db376239188e47fad1ded3404c1539351f9407b8a7decce4f3a6c29e9499f2a50b1ba49daa4fe1ad5072af61a71744824c833b2dacf1ccd6ea4fe256f87cb9e21e89a2c55f7bca76150681f17ff1bc36dc153262d843b0fd54363ed5b7a1378e3a970d2a76244098492157fd29866717df359aa260dd5cbe4e8c2edc33adbea983bbffc522a5b0ff52be5f3670687ed69f328c3b8aefbed81938e82f7b2dcbd8acb44fa7f962a4b14f3a4b99ce26ff1aa66a81c004cdf5f75a8c7622d88473605a7ea1868b438a5cb64e8c5e63fcf8bdf659060d7e42965c41a3f506cd19bf35e2ae96439aacf076a4c3983b173e09e3b64aa37197b7d7a5 +expected_shared_secret = 74dc5b157e4e45c8a550b2eb28605412b2903b02d1bca02b8b44236815e9d5e5 + +comment = Rho leads to non invertable matrix +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 30717ac9d391f32c6e518a50e0fc5376e5109c0c6652384acddc3e10e230665930cb416d7daa5d4222a59941ce9ef87e325760f9b31eaec17c9cd984e6e98f237b47e6776f3a65baa645139ffb0b233a1c4ad0296aa46bb470332d429490552a1f68a6a769aa37d5a35ec65a6b9341a746b55694b1774279ae6b6edd0b690b041c27b1c36157a871ac5e1b44ceb08050e8f96089f481d3670c61d7901cb03ab0795e00db6f2260868249789aa69503c464cb1541d5a1b43cf8bea2a7c699984c7586317ce7064945cc9f41108d35055a687be910bd9c771b9cfc6a359b9211cc5557f2192267142be32cf37a784e855783cc092297c401b66f48d5bdf6b7c84309b62622312d819a6496a3a4f7b5fe8b914ee24256d7be258967197419084bab578826419a7351f327006726d4686226ebb1d74b151651977dea83a9e07f2dd18e88440f4baa6cbe9289b0f728755564f3914b4a4b24ae06305299b6d8e859620628f3436982949aef359f9597c6ea863964d865aaa6783a07c63374ba8bbcbecb9976f190baabc4ca14cb4b02e5ce1ad784c455b43916684cd7b35042c5c3eb026dd08dfff9a7a8fc9a2bac9d65b7aa0589c7fe036b7d8364fe898e76b798155b1690b21c0f5c0ddb83647ff28387b2c926670d49205625fb45a2177f438b5bcc2abac63b7d8992694b6b6417786ae5c8248fd993833b75d3353c92728612f02578472f5a373e1d797be7a8221efc9b89b12f5db18595ac7e86dc49dbdac352c388152a7272f486f8e88a47070485f5026766586eb0007ae84367ea17bdc868152c5ca9149b49fc14e60100aed892578b834e4a4346936caec5adb39b475e68566f7961a82ba99a591f5a0113a73b03456a050f24ccaf2b835981243cd61cf93318bd09277f4215d2c27c7108ce8a8882f28038799456371cce59db341d321ea57594f76376a20b02dd2334b7e479abf1b10560c6afc819e665b9dd538c0fe1cdcf238566bbc6628326e6d40f0bf92fbba52e07079dab4b9c9d90720f50982469bdae9414cf11506d5a125ccb3a508a127f1c31b771232d67a53a9928eeb3c872208ad067000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = fa64929b4a342999d14ee51ee3cd19d7a4bae89a5cb819fefaffa1063735fd08a371062152b2ebdea921ef7dfe98d92df7be6c7f3e2a997f097e020334d87fb898a99d442c7ed49bdcb82601612b2a160270ce1e78c045754661d9122ddccc7042d19d305021c2adf7c3eeb217c59e3373c4f72f21595f419b1fd993ed9336e577c6823e1d708e2afb5a779c7b3b036b514f3d4ed953022d6e5f1925fdb0024c519f333e60587fce463d21fa6ba972d8ea7d3334db09da0ca2207daaa6634074566f0ba0ce7c7453a86b8001e5b1205677759c0b90594e6e6a0c5852bd9a79053f84527eef9c6fef0367270351b9f8ccfcf10abfe4f08c566a452259cb6acde14d452ef31fad7ff4a4bf7391641fbbfaffa14f9cc0fa6905f0bf0948c69a0e224ad59f8b22d767ef96b73569817435a9129ec6288b3149a45a012c6501d86f8023c8d37cea7026643b61cb2badc74962727cd1164fd5c686af863f3a6e8ad998f4f0314b9438e6df155873cf10f0ddd06aa7992d36d2fbe81b44925a6af66fa773bdbc07cf557b0aa3763261bb19a3559d78e17010edd3e6b0f85e0422f6d75611a46baced3572f0748122528e98934c236d3d41551d23b8dd85a30550e63ff6c82a925c471af1a392b0371890e54f221816846fafe82eadd2ac54de28ac60803955a8ae74f9300faf17376f4ca763b006c35bf4117b60787aff77604cca7c881bd6159b74b1d2c129d5cc6f6e5e6e1f0ea1e2aede05cd4c0bf233b8090287f824164060de841b8801ca977a13c89802e1403224110b651283484974b9d16e9b522e0826d6a07a386791080e67deb1d3f067a33d9a62a35c7c4830ba62733c1c715b03436c9292f40189cbf7d84bb7d7eb6f89fbc17a361297c99fa5e9bc850b7b9c29ea587312083a4646ff7c384fc7f83a7e72841019ede902900c791446827498655611e15eadd9d7260733bb6026b1eea93f66574863c724fdf226bab44b59dc9b5a3791877185c58ead5cd0641c663440124d9ecff5bccfa3bb2c751db7fafa3d71b66d3474acd5d58d63dc49aee2f1bd4a5477704ba8dff36af33d4a8d +expected_shared_secret = 6a1ff0115043b87ddf83c59124f7a212cd9951a79764f186d113bbcd1d76cefc + +comment = Rho leads to non invertable matrix +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 8bb7254e662ff1cac748b233db944e3346a24fb5b7d4a242831cb3b6e543ce7301f1f74a78479999424952c79598db9e6f4c3598184d3e2925ea6aa57654a4b8306d6522b0e8515526a5caafe9aee40303e49b1225613ae6f8335d744f088c9aa514a1a52151ffcaa6602605090ba8514968c2402e43c7ab0c97bf696025c594284dc813dc604e4ddc19b7365f0d2a1b72c675873c9830122838abaff0133cac656b1555080769344bf5bacb12433459110c8ab6de24c47a70203b90c1699331b95094ff8a975b735c4e407fb4e4334ca144d7428887dc497d7192fcd6c6a3f9b8a365862318525e0a45ede5a711292767c4b6e945b4bd0cd0621c8ad5e2029f4886ca75bb98574d8a529380f75ebd9abb99d6c96ea329e58cbfc4b600d010bd5693265368a1cd8824b18b8a726ca92774639d01a9af2b43d0c606f746ada9e156bef761a2ca8e38b855b4f03566ca8546315b4b3a3c6ecb4765e7b7b262279f8b79d83127fc04aea85595e5f98b2b228fe26a1813f59cd9875b19126dadb6564af57c2a2594be2b01163a2c48392e3b41b626b0ad5b7203319094722a7e1c08595fa3709df919eef59937a8034c3b724e6973f28063a17109af86192e9585b7149ab4d36a44652295c15c1b60c11999a29a67bc1aaaa74cf14554db740a63c33a5a62869a84478606b169ad1ad2362b81105e736ea4b4ac39a092d7a0c3c6f35e7340b2d190af20a88395d751a0841ed4284432c897a6d11a7a493dfb6bb95f179d2e07b9e4fa945503be1129649a4249cff3caef0a825c06760ab907a02c10c8c43b14256ab1aa45849551f3a72249052452e8a550a9cbc4969ec8141850f64fa032a6255649888b52883116b0317b9be8765b7a30f8245c67543ccb1c8db811a730d063b3223a2bf4304ea1472216a561d5c44adbbb64d25867758340c09bf1d1396f47c9a6272ca660bdae8a667e06986cb73d2d429863c92799910c7c29cb4b0464e004a89d90641e085fd8b215e981454d46b8546a5244d4c6ec18c83715409dda64252b205c5461b0693ffdc6a5ac9b9e3db25ad322b66dbccb5288b519363f6982000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 406c170b05e8cfc0af69e4d84389b3e768edb4532f12da65590e9a9f45629100860f8fbf1545e4d85245e06074ca12414ce74c2571c2ec1d3aa12b2454ca6849ca75b1720afc50e90a9e17f9f9e09c17bfae84766978715c1955b5ee0a5117be7ab2c8a058490ff14f6b13f79737972e920b223e124432967dfeb849b2264e76136b02a7d3b82191d5c3758eb0792a21411a80c9480d77734617e59035fbd883707a5902718fcd4db226ea67ea4d200d105085019bff60249488aade301b92776b00bade4f17a81d3b17bd7431c73a27d24fcef7db267fd2dcbe67958e27b98ed4d326d0a04db1482194bb38f1f0603b68b16da739b25fdb30070ca0886b895e51184a24387b93041e336177e5a2a74097aa903aa1dabc2160a18b3b340283535999f7ab949a8a291cc9627eb537be4c513b5b38ac6199bbd60f3e22b900b8dcd3cbcd5af958d1bd4f8a177bcd790e02e5d5d0bfe5d2a85108c1358ec8fbdea5483fc6cd911b788d78ce045143ac29ce9a99b21d314f7e4ebce120afe64b6676c5c5000dd6c23e141bd615d69906bac419f748d28aaff60b3798c57e7c5831e075e91d6eb328e15c62e26bdf32199dd6f9860900ea051b92991b6e7f187dfae51ec7bdd3d486d0c8fb42bae7cc01225c481937325dc4a2db8ba11911529dd0af0e2af7b3f2a02ce00c6e26392e63e1f79666755039434eea8049a9d5328213d8d1b535fdb8dd332766f8f43719533e4c6f5ef514ef454c11d076e534586681d4a2ebb627bbd911aaa540f52f53fcd8e6442c137dfc8c26e5625817fbf0e43ca2fdf726ba61b2673815188665f3a58024baec2aff32214c0173226ac041842dc35bfeeb34517c260b259ed9184452791e62d7ea865f5e397f0b2de05b51ff0b6fe6db93ebd78cd75a38e1dd8d2c645f9278a377d343e70d7708c0c95341e15c80f54fd97558cc5d339a20a807b644ad9defe60a6cdb71fb82397e714cf37034295c024a25608ba503560b4f131cf2fb2eb0eb8b146b344f04ee8c35a71c6f98d1d07c15bb63b26ef26f5c9879222b82a65f4de1ab6ed9381ca701ebf890adc728 +expected_shared_secret = cc9b647a2d22aca68714069abf5a0fc381d407bab547b634fc5e0f904045ac41 + +comment = Rho leads to non invertable matrix +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 79f7495333aa1db44f5dd58c8cd7bb42d9521eebcf75e18ebfc69d42f0af5a0a0f1593ba58022245e03903e15034ba17a3468bfafc8e392b684ff0009cf3c385674117cc5844492839b7410b09a9659477fec8263d485e6dea01c2f93a68d08543896815661b216564da04750cb7b86cf540e18a08cd28310db755f81395709b3de9f6044ba009a8550f4a2792c2426b2f0836dc8b42128507f7d102fee97325c4105a2c4413a1417b40510011c8c60979226551dde63ff2d263b79455ea61c708827f33da78d99054d02581c42c4dbfc56cea7723718433865530163c30f6c4a31f7ab88356507063319dba3c10c62bfec7966ba65f71e8991d9b3ef0d705a3762a5bda7c1829baf8d947a360b3e902696a6a8adac80bc025957a639f102a31352aba5f560d2dd45512051fb7d7ce62094c86193b39131c9c7b949de5507ef96036063d77b7cc18e5971273a403f11c6c52534fc31c08aa1b9fe29a58db93d9550740568c3cac7371287d41c8bd51d51258f9316d733c39b27f5f68805d9b0df3d771a7639cb180057e082e17c72c7a575f3f46890793a10ebc2dbe608cb1464b46777aba8321c21b338b4a1fc8865dd577195b3457d436ac0f7ac0444950bc014e9c4ca4b8a5c55ba8599d60c765d19395818e48419cf7d41b048b15f6334dc7250244e705a6e19db5cb160ad9b5d2410db13aaa019988dd62759aab30c6c2c07d185b36e364ec6c2b06735d1d56753b692009721c728cb56115102f177f0b35a2920c1c67464e364a05f2447516f40980c464b206861dcc54a6e6cecf826e3677be04f8387c42cbf4d9ca50ea7fa826452e3c6d93f103e969cbcd60bc1f0a41b67541f75c1c605250491a16c100af86ba7ec503ad278558e61acce955532724a1abf78f38caa10f612e287876a988a35afc217e78a8721a3c4fd78216f48d1a5892b7090b01eca133d861058094d427ba784b30de1361c34a2544162aceab33d788b5a4070bcc3959d5d537e76cccf71432038305c359902889384a842db3a410522232690c2a3cd33bcdc58cc7b347d32b9498a689c5b47d91901a04032a885adc659c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d2ef2a34e53cb055a34453d5c3f42bcb3d3bfc7a57f62fa8fa4e0129545cabae97ca076213b9bd2af36837a2746a6607c9b5d3b7c2daa929b8e05069206eb0f326b10663d0c3ab4a83549c1e7ba0b816c78fc79845349a78f4a4ec206a7c00589f8a255ef05cf29285a9543d98dfec3eb348fc0811461e840b2802e7563c70ec128d0a30cbedc1d6882fefee3178ce816387f2989aeef6ef8fe779319c758b8e4740639df4f5fcf76dbf7d1fc9aa84712b59c05e8146b580ff5b28594b509abb31256d964eeb701282d3127b2ead3c9dd6db5791f3d3a919c06d764286987c646195d327a769e14430ef98ae3edfa2b177ce6b70a93f61f180f4ebd0a0c3bd0124c4bcff7d5d606e49cdb3ce1eb86a66f0d110c0f1f77d3b525ea3357c4d3daabe91fe76216a01eb2aa367f036c5337f2cb1ef6c902618dad672465a7095f9b2c3ebcff81820976d901e2800deef15dc9c61fe13916f5a54c9119860864be1baf35bd04bad899fc0617057ccc38b1a2e8eb8149fd50994418632a415f7fdb7f5014a591fe1f21925a27d01f1a45198cefaa30225cf105331cb8cf0102c9ff877b8cc4a74ec30514c6346e6ac514304a3f533f0604ea47e5353562193616624d593377cb445e13286b5ded2f2c786bdc2a1b66a1e02fbe16567aa83ce0e7d4c498074901cfc2eb4bf8e474b0dacc25d747cf99ad7b460af3762127638dcd1d51fe503ecae2c20c9265b16ba51ad1e8f953aad0a14f5b7dad9e9aef7e223467510deb83af133089e33fd225cf36d1a7a6ea930f61c06e7f6bb971dcd01bc8641d8a4204884204923c207e923df92a4027a42f4fe5ce6f6c619739b3ea085d1440098e7e989131de4ce60565f118f7ac588ed94e4821c3d2108f3ae07eb733e4d38a64a5b1e11a39c33d4988836c350288454408a62ddf81bd8f18a6a86378b4a6186e4d0a9dccd4dab530c6c8b66a838090e11a23367c52670e92b465306f4fdaa9111523f4bfd3aa0e776db962f9319b7ef19a67cca46d7ecf70acc01034613da030e087d3074d8a4b5dd44263ba320a7e2d444d8dba7420622e4fd607b41feca +expected_shared_secret = bc96e9498787ebb9ed9d598b415fd8d1d58156c25f615c6417e213f5a363f250 + +comment = Rho leads to non invertable matrix +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 38136aed33c38aa6a772543541825edfe0c47f6012bdb0a55bf780831a2283b628d205722b0932c6eb1243a07c7c051ebec77d2d486e9328849b0c77380c2a2084ab2c665fbee545815149d08863c0e2176836ceafbaa2ed93a163b2a1b53a40e481aaf4f8c3f1b2ad72f9494d8318f354af5819bf35f92efdc2b34831641672af71178d69629a84a6975df3aa9aa86bea805c5a885078cb81f444371df2a630372b14cb29faf62c523972d054047d9b97e40a6b6e852d5349066a1abc737967d3f296803262b0690322eca4afb7544a3321e53b614f66460b54c71e1baf2fdb981ba89b22786e8ce86285e4a6db0b85ba7681e290b41be59075f6cfcf61548ac9c29939882770501d0006e716067083c78a2c5a84db252601bd9a84917f985fbae38b0db9a5441064d62b69d350cd51ccb5876a5650c23bb40919ed058a940acba157118977928e30a2c07194ea6bca28aa5f71199823642e0ff83c41d6970c54ae098b44ff4397272a9290f1cb65a33a4fabad54f62cb43c9c221bb421a82f5ba832a7a00d803a64a00c10fcd159b797a161484c12ea3165608b37398bd83971229aa84be377e412c3ed45042ba49610044b815266b2b9852d8c79b0eaa52b1470a0280cfb00469df52bc8f234572c7f7f59a1cd92a45988cf91ecadb0e32960dac239ab1247113c7ad7385d666d4141c2a6587ee3570be2158a990c538501458b9264ac53398cb946c54b80d8380bdeb343dd2ba21a3c299503548fd3105f4c45785a6c52060363e1509b3832981ca38b120dd8b58fbf19a455a70ac6c1c97f51ae5ebb7c2dca9036805be089636a4267e34128cc28c5a882c9c05649a83c2efac3674ec97da204c64145b1cb1b4a5373a752358aadd15368294ceec4cf9722c0e4d66fd1a97060e696bc210d62335cd5366aadda3c1d5a7f57126fab8aa07ec2b316a45ecf90c001a90074578aa84b73a45c232cf1cc6b518a73430b3cb431c8d7c878920597398eadd4037e9ba13b40c1fdb26c35a4037c75a2d392470fa72eefa6c902ea03dc8a2366f73348b292ec65849c2178464011a8d7ba70013e4e802c6458000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 4a033a7cb40ad97a70223b8d6aa583f86f75ae5cb87500dc91b62a6f4b007069378c432446d9a1e00c9120667fa09f0202b040b16d1e9b033e2d0c92ae29c3e1324b207ff8a6aa3505c4ae20a5e1e75bd1ee71644bc7d4ede075faf41b1aa38b590991c014ce6d009a6270e9ffa50aedf535f83b17c041aa2c418024eadfcade2e0cd4471de72aba7faec8bb3dc277af6601223c3f505c52546538bd7dd3ee6e1ca6b05e92f4eab2162e0ec5237594869d214642dc7f8ce3acb9e00e4ecc9e7a238de6696dfd75a68bb80c5e1348788971093bf74bcaecf8db9d1e680879c0584cba6003198376245dee9772e939337d952ed8ae4cfafbd50dfd578fbdfd910c5e11b0a8e101454d401229709be9ca60bed47c3cd03dc0c0c35c54ef909626483db5e6e67a5a103fd7f6e2e37f59aaedb0975a9423bb3abc5524967fc55da4fa99167e5c870d05bb3c7d41957a1a8b8d3a440cc211f0bc3019184a572c3cec78b4485466b8f35bd7cc44b4280020ad17d5109819ceb393268c7fa2e70433393d2ececab723b3939d8842789bb47bee43ced41769ac6277e457d1d1c4dd455ff4c83f5f30bebe8925b085c5d4c595177192026f4345ee93a4c40586ff622166f7aa4367704f8fe67fd262cc38ff2ed12f94a5ce6291e9e93c7627c6b3d278212d66202a4347f90ff2ab880985af794b6b556d978d50c61782e0199a8aed609679546de271e8d6d5bc6e9492388860c8275de306981cb1b80936637a4d17cf10876c856dfd5c492201d1037b14edfde1c352837de64c9bec5626ff3b0665d1cec2d9c2e315442ec39d9948838a9ce641b998e7ddd498dcc06f591b272811698c664b909b4d3fb449bfa0e3b54a3ee044d33a0ced7ae9043a8c5b4378ff06da475a6b51d379e6edf689acb808e06df3f7236830e161f2342c748ed06f00e5f147b0bdd8349e330d4f5f6a9fe320ec8a3fa31d120f391343ae27981fb75177cbddb4b775b9a3e26c0b59bac8cec7756c6b7d0081307270060984c989cc9496314e7249a165cb86cb5fdd773fe3574333b851caf1e7a1505e8f357dbfda4f753a1ae4 +expected_shared_secret = 1bcc6224357590bc6f231ff2b85b0eaec225a0d51a02afb497d6af1f0ad31693 + +comment = Rho leads to non invertable matrix +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 600bbb767a033b3a6b70940b52f0739f96064b24b323ac83b698cd6f562493530b4de15c26e3902e1a4fc1b455bbf52c3ef16c07ea8917e94a07f64f1269a17b8c24e79714c4ec2613a928af8788f2889a6d3a1c39103f9da045e0b28c55fcb805d8c48cd6a47952b2df350e1904a334889e90dc79df9b55052a5926d5987fa6bbc4f8156d93ba7c3895d9a655a7e86f2318bde401604c28cc394a70ad466794cc69280695c40abc38436083c59d1ec3997ab6658f123e209b9d2c1a272855395cea6556f8bb44e8a4244917683598d5f2bd21230f4af0b5f8825a0f4b2ffcba0834311681eb9116d110d4c92670a2c444dcb599860fc7f38354eb22ebb5b1d55c02691410f76b41003c293cb436f5e71b2b2bbb104ab04983c167a57655cb64c5861c9b599d259bc406f18a8ffa61e4d9587b8ac009472fe32669f8b99ca1cc5e62a12d0902af096b9ac07145a98b5b7354070281c6b9c53105685690a2291f48c8b3065af6b98b79f1bdef6856b6e9c6df7464c18b3351441e5d3b2e1a487a1c9296a603852f05b490ac4ccd941dd046733508306201abee272dd90239d5f922d2c631009c75e674ba8c2399f0f9268db9a07e1024c744491db86936913ac02733e332226402760b87a0b6117e174c5c6eb640dea607b072c9b150107be5ca37e6bf642a5be4b663c059c8394c33f20c02e498aacb15aea3c16968dc0a8fca9dd2653bc49cbe3c376184387b3d966457a4ae9006357f0c3a23e2b200d6ad377452e37b0480ac6d9a7544cf359a6ca14deca422c4835551c2937500a2144ca7df247f0e0a17ade760784cc26f51c32e144bdbd135924b851104b74aea40aa0266bec063d759b5a2775fa6309c00a3914930526496bda04cc3424c983aa2aa0f0070b0f3625c512a43b3567f642343e0246d262bda42b0dac7bd9e540a776365f4877304f49775283b9ca691a5f8c0b8807299c52e1e149c286309ab568110b64442a553e3ea6b277b02b609bd425a58f3389b941573c681140b7499943733da3c981c75069a3aad306183c421c28a720d5a32b7cafa8a9ae7aac936484b56bdaf321b76a3000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = a2661ddfb82bee75831653b3783c20d7d2b2dcd1c37b471495c77c6388b29e53357098350d840ebb50b8233e185f540fe4cd9360974949abda32aed4cff401b08d513f3b928106e408561a359750cec108b52875db7f3efb88e0d13cdac15c9ca60294163ec46d82fdd89f650d30ff354d12d1bc7024b131d9e6f13092cec164742c4267eed81949b949d6ab04ce59f0d1938cbd97fe833f4db0ff429de47e161129bd0217907d9ca59066495b8980228ee129ed40cacc2573e322425ed11cd02e50f48b5208ad3dc1bbc43334806c270352a067022739043b9b11f3bd23687146b70ffcc7aa523065abd605509cf867195270ca355f9eff4b4bad0814cbb55b0e7b2a927a57b1711d621409ad8bc850d3b0b4627e38baf0a671b4350a6b697eb297bf523bed95f32a1e1bfd1db8dced27c6af290c7f7d648ad81f07d1a3ffa4acd8d08af8c494172f6b52d028b836e72dd3b9aee7f319c62cae8729ecc69f8fa5b4de68bc4452da20c442c0f09bb0e620f22cf71cb6f629d83dfc85ac6916acf62a2b96c11e2954791e953b31c992d12e838ff2adfc395b84f1e3482ddeef96b1ed04225be90abef29382da3a7cbf8610b09114788cf333daac7434808de454773689676772f5683e076145f50169fc8b63fac55d0ca26b5b54238ff349f2cb28f116ba83db2ba1c3d251ce68669ea1a5a0fa946e345c7fdb656e5472803804323107ec108aedb4ab585a5a3dbc3cda6262bb690b21e3f84bcf1af0a188194dae41508c2a9c721a4ee1f8f59d1c24f88e8f5c287bb5f774ed863f6caf612fb100523671c4ae9e12c7118969dcc5244a1fc5f5cb3edc76457b3d1c4383437e2fa4f70516852fece588d008d5a8747bba217fd19c6dc4cb417e6cf793e8c318689c4e1c7627762b0fd5103613dca5ce18bcf4767fe3e73f8dd9342049b33827f2270eac3cb423001a4f1be6deee114107478da8814d84cfadd93e68f919f0869831d427c8ca7839dd3742e934dd067438ecae87a7076f6c312b9861d640a3d2f4bbef7d86de1c10a4ff63f4c2bcb6cbb0ceb602dc2b88a8a674f4fc3541ce581b +expected_shared_secret = d8953400259db576f84162a3c0e9f4e9bb3a50d38518237fab6d284c2e72b557 + +comment = Rho leads to a matrix with unusally large entries +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = f8a212f2125fa33cb039a714173b5064558605a7bf4dec183bc837efb865191048f9915858024ec37c77ca301008a00c2e03d0b0e0a3d0c67359083433764225363411571d1ef847244c6e4b4b84deb9b902f07460416ff4bc8963e72e1e7748491a635cba3e18659c4dbc20fccb1ff703d0fc531cb54c4800841a10015a3eba0e02194ef7a7aeb1242d25958d168c2b0b83a0da2c3070275bb21420cf7b2273a0184b3776ec117dba1952171b4da13069e09469eda75cb93cb04aaac5a2a75dbd894606964397538c03d41a8c2902b1f26bf1d9acada3010f1593dcac41df4ba5ab0552feb20527570c73bb9087e13fd34ac26787112444bfb4216561585c754324032921fb1321d896b0e917c5906b94917b416179b9fd55324acc5215dc1e6d555627d8b82f611b4226060fe95f91352753c29c3cfc5f889393fb0175b4c4c32f1c78da420337f24fea7282165b10a2172f8aec884e8a7234a2c2239c57c5629511e6526a40730b9ca0f08080afd8274f26343a8a50d061818e4a2305393cce660be9b6c7cff03b3a7124b8ab9d71a69de42ac02e998d67360d1cbc912f308a9a346fc5d3ba7fec24f923a321b362dfb868a7f151759c5a552401d0e8332bd047d081b9cf2444f63879e2b38a84a3c307bc86d936902c31a15ab68424c64ab6e4244916ba70b189a9875c83504054977785e41c3b3434c8c8069196ba7cf6a78409b8da4aa3466943fab47dd01712b4ecb876a8a398d22fa5c9599bd5a4c57c2a8c288046046c79434e874a1050f4a525b83aecdbaa04ac0b9c546a16860b96d5c118777d630c0a4ed33cbac6876ec6b28277bdb7f44b43977116e72472e4482ba55d38457dfe4a6008f5a547288f31fc47646650bf291125955d37944a610a265af15d3182a439c4938e702662f5b288f69c0c68a273aab0998c0796d525b04533e72cae299a98b178066a4897da20c90572265d461afb747cdbe924b1865ce3e3150bb2b454da237ed8bc7a7abed1fab4b4729b05e3adc2297746509c1eb24a0c0191a1d09c9eca79f39267da99c80ec98bb615b05c4b9687ba9001c30d48051b4f63000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 4c9b8e26976d7e77089578159dd1276ae2c48a781f8bf78d7959ea9d2649057d9bce12e45c3b994aeed685dff6c4bf5339f7bb8e5e6457ad69addd3070036a4ab978abe88a5a12f427267630b2b6fadc841bc1e441163210c8b60616fc334c5a04cbc465d7cc9b5b1a65ba39746d5ace9ecc091d35cd38993010d8a9d6b995aa473dd77ae9c43b2438b0e1999ecbe99b2680f601871ed2dec989e53953ed1261b020f5e0cdcbac9cc52572bc89d45ca9fe1f98e1f4391ba7e469daebd4f8c9b0281f8c55ae52e4ab4231f9e5edf0dc43e2a2d19d5657744a22d5f7bafd1c2851046d8c9ec4c8bc40ac5f5c7758960a0a87a92ec6bb549025d4bfee9f0b7f9a23a672e96d2814159416fdc8adc83e8556c214fab533ad68a788887c1319c26917fb3cc79a411b73be203a1173e50bc8498d66a352db77fa819a95d07a49687d16ac29c43e20a1a0106cf471e9d9eab0526db47e46f9e318ab655fe44e343b0bcfcd2f2102957b32b072d14af78ee32463f5b1b8c85b10a57d4c9ccd3ab92792f496872a869a111dd764c145a7345c02ecc58cd923bd84ba75aeb418d72490f75e78e87d1f0fa0a451b746cb8c414e12e6c09178b84b10597bbd4617c1d33d33ac0738d9b492f8f597df5de861fea1ba878b45a89caadd1a35ecc6fc67aaefbbcaf61830e9fcfef59e6bbaea87d28d4e4827437553d66b3f58ee76e735b40debe83a92e2563a2b7951494674cbbd346026195a5bc5d82aefd0bdcbe66b6a475a3866d4c4c7523520a48836e3d28bff5024f7ec37702dbddeb0703ef5662df2f27a98b74fa3002a530de453b3436f012693b0fba03b66cbcb3b89ce2d99605c36d8f973b4dcd659a5fe7398c92d11d3277ef56cf986ddd57244d2c3cc67743fd35e8808008b5fe9259eecc4216e5f68fcfc042ccaaec6989e4a31848cc1f933d218e3223e51a8233e314f8e5c7053d4ca0db65c1067460888f27482709df6d114b3462ae9cc91613c619a48ad9ea3eadaa50033b0af1017262dd4443588dd6bf77475f3a510f417d9c7bc0103c96a2f2b26895fc0a06a94f271193dd0744d7687a8 +expected_shared_secret = a520c6a9bd8260b1a71efeb0d5878a388715811819e4a54382aa4107e37a094f + +comment = Rho leads to a matrix with unusally large entries +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 8c39b906f71f9b2565255717c4c1b874a8cfd7226269a74a26d9ca0faa218bf8290a461d86a002ed272674c690413a870fc28f98b2a639429136ea2db2927b341a6e9216c0fa447f7eac8a39c535e9690a2e8027b2627e79138f7ff9a1f71b951d4273eae0ad366202a164b011040a124c0ff8337bc8e74903461b2fa8847684036f3b91f8186c776b51c2a88a77473005f2729076491c00696275759fe2c421f18a39293e4dd6b4f783909d42459842855718c53228c339f28767f94f9dc17f600abd64389917802ffc0009aac74d3eb579c27626cfcbcdec17b182bb48d18a7b474a2f8b5484dc088da064aa45d4a81adc9df11327283b303ed697c75c77730953547a2286951b7991bfa0c397044b34adb4150b0556790764d833b81bf90ee7d3764e9842846c8228917fcb00cb87c39bc05a975d2b8f93530918b14b7387af554836441184e761caeed04d6a5432c8e918360b902b45adbf8b477c57447d36799d6986365b365e369d91e9189e1bc6b3a7975c348f9d40879869bb0a40a0fb8304879b61d5e06aa982b7d87bcc312aab46506c65ac4f91e7180b22b52a393032e29fac2a8a6841a4fa92c3c3233d2367396f57509f7c79719733c99898408b5d229b363dda598d6a924f9a319ac0c247830cc2b9b28d1501c9200d46e13c358a6a9cb07da7494ca9d297eca37ab9e44cdf2b0dc5a121466790ed5782b5ea3aee1734486bb2aef1246cfc9818991eadebc71b0ab4fce11ed7c48f20a6a1bee2b7aa4a0f7aa25a3ee61d844b298be06f24aca8e4464cb9a23379442c57511cad2a8db4c02a9189a1c048643372c9c1247053e245b5b2cf1d92b505d4b6f0d60b26aa16d71ab41202922df51c89d394cb42a905601fb3004b77963af10870993aaf5ce9513f8676d6358b7e77055b793c2b93971e0478d479b9e19198e7f63b7c375426a342756c966e49bd92061c099b7a114651b2dcabc779ce45bccb61d508335b4da5841af57346bd1539eae4853e931e6dc142d96babec750102cb5f8095a8abc82db5a1206953bb24bbb1146369a5e7c1bb78716987cacc75200fb3816581d21cb3000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e1b2fca92070d9cf0a781c557edc393c363dc1aaf7069908434012a43395a8aa06326245729610995d39a8bf075297a78c0b1e235393c848069d2ae75fc3205e343cee5529247bb609bac47422d63ff33a191f9bdc9b1e8e7f92d469e1426b0290094e231de8ddd2dc853e39489267528f136adaa42e47466b520cb079e7ce7ddeb96885ea7d3955655f635dd7fced48a1ed5b8ced12e3db55cc2b03c890801b53a817c4f29897d83481b60579813e4d39c8ebb3b195134e617cb08e15cf7e43389be5442ce5431bc3aed76c7a60040dca336a49066a91c682922637e51684da048c5415d1848d61c9197b15fec2d25f0d6ba0b35f2ec945d36d243a73e2b99b359e80efb365e07317d6524f41fb22c0308a4658d40e688dba11987a9f769512bbd51274c96106a5742c119326fd1d94b54e588f1bf5fee850006cd7b7d9c9cbdd09fc9e7e0c397431de35eafca81d91875978a2678841460805cfec9afb863f0ea8dce2a494c581933e4bbcfe5f452899c27b4f0c271a45e2b3ca074db853074ecebaeb80e5a14c420f2b58df10de25c60e44d0da99c5b2aded4640861a342057a20e058525e215d099caba6b48eefea85c48ad89d1c58afd58d08d9e55c2203a79d9b6e0c1d34f7fa90dc47b20e38d13aa9d714dd4429e36e7092c167651523450863e9fb9eedb1a3a927269954845d97f5f36f74f441af8b26dd93590367e6ce9fc46157bbb0df28b1e24443e608dee81a1d7480309224fa6ef28d495221e10c518027e66791b74cb96d71061d402667b53a5570d7eb520536109ff43a535d38a0362b60294d0459afb82159f930a76e3abf7b3585f3951ecd2792ae60caf9659489f424bbc43229fb40385ddecd99cd2245e87d6f0f9af1d3b93c0caffbe4b602f201735cf10bfd3aad6a82fd41f0d5b9144c1c34c4ec0b4ea7ec6b905d9fe514a0c4d106bad2c7f6ad62b9b17677c295cc448a37f888158fb828a43cedbf48e265f4173dbd1f81834ae04ffd9c67a97b6bcdc57acec9596c78a8eba951c7874bc787ff30ec0e5ce616f66253b15033c3795a9a42859d082fff0dd28a9c8 +expected_shared_secret = a358bf3ba7aeca1e2498e52a64cf84f555f6537f0bac7e56560a5ca8f965ee1d + +comment = Rho leads to a matrix with unusally large entries +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = a364bf972928df72b00c233d3ab1054fdc4a8420c8c468a18c5217106b3e609614304b892e1a9639d20b0db01f50eb8f66f3a52579059f0699d012cbc7a0c82a4b9d6090452bfa1cc1041524516ad78a4232e0864a57c49b0427c5999e1a45af002c571142180c91b909b971c33930bb43bcc95b1d21ab85a2a34ba4daa5be382434ab71c6b5011426a81b7587d25b2bd0f329cb24cb777502d7a0507204c06686a51d58257451cecc5a2d2c6b0fdee34f3948ce76cc1dba7b672dca4950019c38e1bcf7a9c5505acecc6b1cfad43129b2c09c3c8bb257443ce152fc8a059ab9afb6f015ef14ab1ff50a4cb60d64a02827578153525b059c0b1446acbcb29ca6957cd3468650cb8cfb59101ae9181c3609faa2897948a31d0092b2c5aa4b16b842b55e117228ed98bb5faa6c5f092c9db050760b10e24c5609786b8cba90fcd1838ff80a2f735ecc9398e291579f449823647d17411cdf5caf2617ab5d77760f6cb7230354b022a72bf49cb3a2c935232d873c5d8c901af429709704cb1fc0827cf40bcb0a8ec151211ac8070890512fa06c48d7c3e25855811bc88590872ff25f5c78c1734c845c18cbee0888b06232d853b1a38a310feb426ecc7b30bc805c998ae742b50d50bd77e6bbce76bd3f51c1f039b3ba892093a88c48e0668a68279202838265b80f2b7f3a33abfab4845f551289f7c4a5274b0e0b41645a6f630329fbe8b5a838c73f73c5dbf3aa0ad763df6a390a4910093abdfab96367809a55325f31871a23641702d10f3a2a652fc292086212345679293c534454aa9daa998ce4039d54221cd49fef5c3e6be6ae6a2b7797e3b36dd673a2941fa98abdec62b67783a618d47b95e7cb372b0844dc133ea174b8fc2fb2d53c8351416f813c7ca15d7d8c8e61c27f765638b163c3f2e172b0fb3c28204ff96c642452cce7a40a7bcb6ae31552d6d78305e3c08165657848865562b7f500c561e752fb154597947f18ec56a7057c2eb5bb99555c2c99b003b115d6214ce093bbb8d712f3e72fab70198e5abf0da17384f6737b3c602296726e316250f4ba15e41644c5b5de6572b168cc21da000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = ab50d831cf728c58f565ea56c5dddefdbfe9cecd1ec5e5ef7839b594886e58ad3d3d43e8504727507e9fd38a96b5e714967b4fcadf0b902447c6e9d2b857e5a43f7bd68a1f8ab524066f54345a9f1f84c0394474d416e37aabf5cef0b8cb3996d2f28606ab9fe89a263b4aba00a6663588e7af55535f148430f82dc4e3c8d14d469f29039e4cc04c6f431f67544a9902fcec03f72cde536c340a93d07dd0ae4183ecb0ad2a4e5ee6ddb1c476f3a7b4377f05c709461bcb2809eea320423ed00d08c24bb95b0f36dee221bd072c980f94700a8d01ea911392fa156b2a33cc85672a8515b1d0c6c350be5b1f83fe3ef38f7f7f6ca4781c3284fcf590c156df251f25761490017e4a317c187df97131a981d4106f0694fa08da8d72574e4334fab26d31ece0ad672a5fe0773ac7742123765115cc1d60edec1204c170b27974a902cd77183e51a7f229f5be88789543bd243749d6582e9992e9e9efb16c064adbe2578965194f561525049a2eb892ad45822169b9b5d5509f72dc6e8bf4f0ec1645a1820af7e77519eac617c5df3f3ce7b5a22f9c1ad1218d896aeeb0c9bd5d90030139582bcff4834f04592eb36b3e10907897881f241753b83b11c8a73d95d595af5b6d57c96e33801dafecb7bfe3606313500a8186067e28015183503e2d24dd99048b45371db8ea1801b331785fd0f144fe509a68e7b86d379e6ee554be31e800d547922195cf417746b9daad81585e57f86a9e8146a5be5e9c00c6c32d7d3599505c422a5e833d1ded11e231307019767b4690831f3a6baaf10797b4870dc46ff3f5d01ba14dbb88d5bb86e02755a29915e22ebfadeedaa85dd794b6c7dcf25e45b889a2b0bcc34ab6455106b97e801211031a0f19ee0107e810e9180c2916468a1f13e4831c429b543269ae0d60ec349991b04fe7756abd54160645911915779b843405f23016278d377c58b3cb5237553a35ec3859610eb3a6abaaf7b898c8a34fa18a0bffcb7a3039d0711fdcac329f796ec2f821b3809844282b5860af6686d2849ef4442aeeb2e4310469d3ed766e5d9d093d79e27210d995fa1903c8 +expected_shared_secret = 5e63eb447ffb9ec9858ad3ac5d6897e9ab3171798167e4abe876f3f0bd8e32bc + +comment = Rho leads to a matrix with unusally large entries +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 523b4e87152ebfa716533137cb8bb472202b29e2a6cc2a6ba8ec39c4c408da635ee84b714a833f60952531b51cf0820496362598241ce3f7578fe562db4bb6b23a8117443ca5a5bb369abd40c779c11898587798ed91baa682c030268246b0bb40b435f460be810a0cf9cb91c8d681f8c1997c07c3b31a1d404488baeb6640419b1acb3648580b2aa03b66c2415789cc06bcaf246c8fa15ba98f043a90bb6478cb257f399e3a765b4e704beaf6751df658d52c4b84389a81e042ace6491ea64e01a473a5e7614f495c1d6177a9d1906c9bc951a1b4ad46a7ecc93ad61205b319a4d3d620d377584f9322a059a55ad782f2db59f8f7841a4c4f8c08a811dc4993cc7b7685729155537028606162bd5a445362f8a82420ba8ed590370b460cf1adf4e1a9c4254eb26791677b56c1d1a9947c8b63e45ff43489d29a88796543759a2887478ac4e87806213bb5f51790832496d958cc1a318e8b793db5619fb107b5d20b5e52bf6ebaafffdabee37157fa821be3681dbee56646202268310ed413536e630e954103a3c6643c3285cfba200b665087831f21ea209e685c0bd71ec5a26730a0a01521610572afcd83014f6104ef56878809cce38579fa9b2702169efdd5c522fb42d9dac80ce834c115087f659575aa0a1d310339033e4ac95f773bc2779529ed65bfbf043132f2afb3eac67d0b1c7989ad08372f728994626ac98b2b385c5b2f3552115f97517775507f75532700cfbef635caa43286720345810764bab180f96e07f40e54fb75b1b9af43852d569133093763f211980786b97f910d04f26d77075002309441b63d4e864609e8afe213144651931c753c4c916fb8f871418c07fa4835b5d8b66e6c3bab45986c09346bc31fbf882ce1ccbd83cc7269269b6fb82e7a75b517540247206d6559bda183b589e726961a4610b081d2bc7f03858ca1515888b88236f62a241275b8472d4c5260cd04c690395beb853459b5762271c0bf676345d96ca0e798fb9a7fe901b107d078f5220306d9cc58f009cc84647d6a51ed3b148ec923049c14894797fecb44a4ab0cc5855c111c32e50c9c6d7ae8fa3a000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 5be0852d7859e0229710d1869411914a9d720f9210aef0031279cd456035248af7a387ece9993171206b497ac3b5eb868e7cfde58ec09a4e87dbbff0c101605f548fe27608b4dd46c890ab19824791c9be09e31781a1d1f106779c9ef577bd01054e7ebe250c0a6ef5f1ae8552d0c67f71f132097380de6d233d59db692d35f981cf200b91d2d8ecd026fafaec85d67810604ee2f5b42d190f26d763ea7deca62c89cceb3c46cdd295a34f59c54b3fe27c63f57cdd21f22720eacbb769b457a8e15628fa4fba818a5926c98b7a8b8d6c0a28d1eb4151c18e07e3de588dcde77422ab9a6afb30e0f2f3ca465aaacdf8e450b21b598bc8b62b8c95147697620e031758ab74730323144d45b31108461a3d10115855b9fe72201c2839e6dcc1a006c5966c7dcf5c1987efaf7158b3ac9a5fdbb7ab13990892762780beaabb55a97c35b5f3ae5bd5975f519eadde1c46e83e10db765372b83e5939e5f93f51eb085fb0af56d7a4a70e611411df560a13cc28e7670876b8a6d00407865dd33e9383cc81a227d15b63a2f9d02bdc719713c3c73851b8c7d921c1192a7262c4552ff13d6ba8be7e51f860a6e0af868f98043261b50c2d6f91da089f6c62901c702b4f9d664016ee71baa5b976ae8c6d02d6d30a8b3d41a4607b5bb7bc91fa9255d7e036575a96c6a61711c5eab4845c7b3f50f356f2e10d00ce0703ad9a42a7d7e32e2cbb665c26de8aa37bfc5e2a12474c5f76eb34710df1546b87b0278018d9da82a40aec21235f46028ef58a78fe6d1389f3c7cca0d964b5f1944cf874445d27a00379acb75547e8640e29f7c4186ba0b02a1e0bdebb7a5a0bb5aa237243861a1f09d56bd61ac2283b24dd61bc31d5aa2ed32f11cc78336db3fc5228ac91169250588ecd00032e6ab7b6503d67ff97764f763a9348f40f42afa21015ef11532a182c9bd45bcc80242bf8560b4c7e9dc8d2b858383036beb46cf0023c5d626354f200bf15cb6cbf595296a85419915b521901cd2089a41f6e66dc62477388b9135713dc89f29c7b41a425efab463bacb1835d34ea887dd28bceb6db2757a753c53808 +expected_shared_secret = 3eb059e6d6cf65d88a4b359f79253a8fba021f8b00df5e95d62d6ffcccfac92e + +comment = Rho leads to a matrix with unusally large entries +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = a82a342e7c5fd5ea38123a97a2e89534757babc220ec0b499b70ba5e4bb37e051124575cb28392825a3d750c6836696272f745309ca7fc54c403003ad4c724b9d4232d34454dd49f47ebb6637a1258fa899566148d54c36dd013d8615124d34abee4a9bf3a3a36f3b308b47e920759159269c3bc5658c37a64079b6848471a184dd9c032659b08bea7753f2683767cb6a44562af66356ec45e663266bab736651c38edf5ba5312240030badf358419e03363f4cd1be8cd33b89755014d40565c15407f2c763b350469f014866e215d4eb40078491f21801c9b9156f87c838613849f52c868c6717c63baaea727af13bb2a6cc7559b9fac995e7e743c14376c9964cd4b7035732424efb57329270ff61abef3076da40b7e797b4cd344a712c7898cc02fecc25ae1d5b4e104af5be64a055b29e1d2a8ddc79fa0b6146b4b5f8e0715fd0b8b87537331aa95cc07c3877137fc172202530e479cad45a2324fa395b8aacf80b92d6b2897bfe978fc7a1900459c4fdb40a2015f2ab9c9faca9837c94bc92a6bc66b906a439b8dbb5a7b6c141428a59a5671194a43859bac30f59dd7e7b83fe0a4647276568c2affa215ca80721decc8d684760d2c23bef6c9891a7266eac437893dddcc8b4c774ad1bb82f0f13688123f23170b15813e51c5b1806c99c00602912b2a99729e5b736dc80b45026bc7e08a2b97229370e2a590da79888b843db001f0225b429c22146b75c37705372b58cb6556810a4818842f321a46136809aa3bbf4bf4a7cc9322a16539cafb109a88891757544260543d25b737612cb8381baaa3a7cac3c564ac62f851077ca0c6e5e47990b9096d01998a9abd4da8cd1c7716ad34c2eda9aeb57aacf8d25816b083d6a18170294fc1fc281a56789edc21853807f3d93bc40743b9f403c9e9441b3b08df5758a16839eb3795ac9a5d051759b5e680a3aacd2b8b1c4fc13cbd267caee21654b1b9fc68ac544aa1e9421fabf075c510c1e7b98404191de64047854bc1e714c854c75faa248146930578123c538621e09c0a7e22757b730d1f6172c8a7adeed087a8b3a5be8b4a07698727512b80c8000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 7d6b0647a5e86d2f4016277a07c0f48186262312d4c5363b8b5e655aa6150e4c3d96b41fe22ed02520e8a236bd0e9c2c8c47ce54529ecef55854fb4e7b9aa34329f58a113771504c0d7c53107b87b6340d26f8ec893cdaea4e253cd6284d23fe7cbe357045f5311c4e74ed6e36ad5f8ce17afbf73d7e8742fd24d3f07b81e1aa8a2c1acd7789263163a637d96e287c5bc3086806296ed108fe6977b4d29e67a030360623835adedcda4bc333854d7a5c13f675a3205201d14e557422c36bd949d7bda0d626e35e066cdd30c2ea5d335857b09af66c07e4cdea6e44e4f67bfbd0563627c19b4a8d6e04b2d26cc9d0e221eeadc6840dc081d9b4e9526c7420fcd248fdfdbf51db7ee0bbb5455b338bd0913945246249b0953015d4aacccbfc1cacc75b6a1be47a588782b40cf65cab4a2071952b44f56217643a6e181e8bca950cf352a84d7118500da0a8df9d2ceda15becddaab696e2b56d164a1162acd09d545e7ff69288deeca25bfc508c15932ff95d3e8400cc66552905447231a3742f8aacb9dc1f4800c80425381896960a0753d8885188b627a7fb94255992a5974d82166d4e504e491b9339cb0759189bd7d52a5f1e75096fbc39c12f1a7f14cc9509b3d6fd494236f85aa6df4896425ccd5799285249a0e21a51de18cda835b69a9b5c3fed85794bea0342a0c984eba708dcc1842ce676999ad4c46e57ae7427bbbbfab6208cc9e5357f656dd5974dae8246ec958fe4a4e422736f3268fea7f413674a4e8135d0006c723c5545021c537121eac7b066a6d895f3c3c92c66fb9a2bf96129aa6ecb187eafcdb2020c4d1a32b204da9f178cbf5f727b3a70360cf737ee1fa6fef0bd18cac9e90755f56d44eb4514728d7869fc8fb8c762ce80537e38a1d6370ed4fd91be8ac31add922e419306ced9d81bfd8401ac9166faf3f0e07f179e30467526a75ae14e069f511014f5838d2ead5e8791481f5c76639c5cf58b9dc38c3458f75b5a87ea791ae0930b5ed0d90dcffd5236e55195c44a8100881891b93af6a8e88abf31d2a6e0547d22482337562b084a6ffdd3797b20ecf1228659 +expected_shared_secret = f2235105b63ed1151103544c9c96b98709816b2678806780d4116522ae82470b + +comment = Rho leads to a matrix with unusally large entries +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 38920633a7312d320c7323c81a39a0a271ac7cd18cf3f2b9a0617c13e84eb6b36a0a242bbe85c86aa5bc22f205f51c0ab36084b4c79efc220efa7301c4d14912e39a1db66b3aa67a4f721c7f988e90939bd55c7f99189367013f4dd0716d58637f5264dcc742cec65dc78273e4dca225b1987f50696648b6c3848450d69712f978f974c4192732c7c7bbeba18a0fe5b38b122cbbec27af82a6c7883265d42ae9d58feaabbba460cfa0cc414bac90f460916d20b632a717ef131c54445d3ba2a1ffe8b156d5a4e0cabde82cc7317cbc14f9a59de92385097ece54a6c1e86de59b8cedf1be838029168aaacf804ee099ce184825647b5e46b42d73a202ce1343efc64e5cac68d18493d26767e2452e0be05c0394242419cde9ec567b272e2b2cc63cc2c50a273231b26e8a665e6881187795410009c4fbc3193256c550f89e2bc4c728a851597628c64b3d93662c5f3687e3c151bccbb13d91a3a0452db4c0965cd1b59ab89fba033760ac0d270829b54ac4c844a6771a43bd39a99f3a0a27516158a52178608322371541da4eaf15bab4a4be25920cf562185eb3742ab033eea81ef77976e8b9ac71412ce968ae6e83bba7f23521727a4da4a54ed56219f8a2965c064b752a6292c737713ddf362b91797dda1b45fc6c5cb1c70dabc75da0292901321aa66c8f6a651d76f24ea022166947197c3383a90bcd73646efec6056d2771e34b931b255676b52278c64c55455431c137313149d948184e4a0e8ff4822f7995771ba32006c7b150cd77acb35795a336b860157c3861d78a57c39705331f2be3931120b031f54ba1521ee8d0153630926ed183a4c2a8b8fc5fbe420b084c14771b3d81d2cdabe2b64beb78f8c4795f45446a9b4b4768672bc9598bd62c802108c5e9932486582888cabb76a56d57262eb2a58ca1a0b7e521eca4bd12f65c0cb717736b7ba3382677fa1403926f1c9bcb20f4ac97e8baf51263f25c3af3d2b77f0253c7073f6184b6d50718e6fcb9ffdc57edfb46cc6658b77a77f2fa38f9ac9462ca0476d47c9c154d087695bad8ae367235dc870de808a4aa906afee167f039aa3ffb000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 50c85020f18e41a8a1cf467d921bf02ed861aec594810ee77f99b0613d4622739a3a1b6050c5fb2a44b9609668b1bf04fb39f2b91e176141e975ba5ab5a1aaefd790e9ae2db2cb853ea65851d0f88452cdf3987d439997dbc90287c2914efb54d6508e56880956e4f33f6bb3c84d6edb0085b3edd6134c531e0ce46ef8b1c3d2c504095e1de67f5b2593702dd4290af44f7a0487f7eb0e42214de1741573856ff5e63c9de9f66fb135e1be7b759f12641b48c70d2789d68dfda9d02f57a95060aea2957cafe442baf320a3813a4958200cb0c13f983ad13b910aa36aa623c219306fdf8263c9eef8c5d5a21e783d8e0aa02704395da563cf9590daf815178fd867a4e204c053ce2e73ac40cefd418ad0a8d34698507e275a57b784030dbc05d20095a9da9e0454364b12958f7ac8323dab15367a90472e38ae9845ae20e1cae296ac296c4cc001ade00ed9c2cec74bf17cca84e58a26031ac5c4a0d3bbb20c6d57735edec022eb313d3e2dd0325c89b0ccd6a4bc76e9a082c99eff5adc0dd9b5cde0036082d52be2480f5fbdf35079dffe83fc1f85fb03d2a2f4ec68825685ccc7a470b26373f43b9e7824b433a5010cf94a39226d7f4702625eaf9e2e67a2c745b3fe51c66464c395bff2ddfe831580d678f5ac75cd350f1d0b8a778cce43926dd006025f2efb9f6abe18060c00e78734d074b1f1a1f6bd424686ef98355857046879cfda8a8872e3934b858e39ffbaceb60fe828cb78fac861e12320b2eb9514dbb6b7ffb690c12919ef982482fb4d87b7ebc98c4d2d5c270c4b0337ee683fd0289064577a2bdc3d05b330ad7732bf1574c2dd0c449517a77ea29b0f519d75e607d32254ee949256cfc835a66a4c4dcb0297709b5a0773adc9b352cc084954e92989d7ed5c6ae73004ef682c4855ac3cd7c1e2a0b38457fdfaefc96937df19e6ab1eebe500d320e90c3694a69005f610a9f8dbb058e0603b0dcd80d8f4be623a6b19678aa556ac61f8f77affbdff2f2d6122de5da05255973029b0f824f939a27b84e58b53021255a3d81309255124a8f9d9d1923ae9c92f512d8649bb9faa +expected_shared_secret = 90e6702801a2634e103160e98754e1b2d96b057d277db4203abb8f52a2ded972 + +comment = Rho leads to a matrix with unusally large entries +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 74652b10690860f3228053844582a35bf46bac784f3161220cd86c1477bab6786f557b7033a8b2d17c30e403879ed87c74ac1b33276246555dd05a30e68495e14ac94844c1d9a350c703378cd92d8fd15cc97a95c45096f0da917353993d3a634cc32fa84428be02448645843c012bb648cb4ff690aee824f3cc18ce8426f28b889767b91e8b0aa25566ad06a44a2263e1d8ca7c315ee873ca0e85cba540751629b8f75c1b661c369424a51db3b15ad12daa501f0fb37ce9404fc8738bd0cbbf7d0405aac3c76014996641bc92a527952bc9f8d839a4f8152725088ea7780f7982c8cbc5509636ede17a315843f4d0220305c3f0c86fa573ccf26cbb83597e0a8320dbf61cccf073949a6851d3c41ce485e71465e232a752c4925ab6a55f309d77c20054a8789c98bd72c42d99093a5b894b6fb73af0d32475334929a08703ec84914404d65b3fd150bd07012854b43df16133ea560ecdb662fe630c910c3781dcbe4d4465e1d828411c8e965cbc046b0d8f87a3832a2adcf73f33e09b5754bd7db90e09900937d228bf0966b1e385d2c98aca792ad384240aa570a4826b4d95423ac49e84a02b5bfb299cf024bf133d7e7cb7ba20bc9ff7025a74ca6459697130a2f088472ffb3fe4e5c965d156e191ba76e7b47eb75038785a641129bef51a9517773842a324dc575171023b76c3b2570475b2a468ba49d1273bb0db29a22284e875bbf69b5d8d08a01a532316a010afe992724c6eb524250f72a76c131d7874b21367ccb294447c317ea3898a4c8bc5e20776d97b9b84946757067280fb4f546356656453e9079c3e8595345a804a641bcba4cfb2089235b29a7cd778c5c534cfb4c77e87ad13bbbc3be133f05656db82924198bd3de4a398944cb3313acb360004445f0dc7a5714868a02204a2668c7fa5023639699220bd85cc2bdf2164ac94084e389062652ea26cc7316c6b9b02b639bb630c6293cd45930f299180ec1549813c411133e9252e83eb22c899c7f4083ca3939c6acbb9d06943a55ab638e82505ab2b8d0487495b767c3c4c97777792179ab3e5a180506cae4b1ddd655e217d754855000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1b251f08fdc6eb19ddd0c8d5d5e2da90f71d12944ed19ff97c654376a8eed0936b0316cc3280dbde787ce827ca3b5fcff90a6ad6f99a6060f9e75b1ed6a73151035954efefbd9eab3eaf34e4c4b2ad85ff8a7707330bad673cd5d1af192dc83205473d9b29d817c8fa4630de8b7aea95fb8765429303a6b9105e834121af1cf47d388ad800b33a03f81c41c7bdd42e61a34df294e14623511a59768c8c9184dc0f61fca7433cce1bb7eaa49921d6c840bf607e5c12cc1dc9b93df5fb31494e1a4ea51d4c289641289ef01137d5a4edd272f48038903037dd58dbc9981d6427777037c376559ced6accceb8d6bea9451ef77c1b33238a7863b4467a9be4e54701b642584c3475d6379d5c875d0428c7c918e1ee3bde7e6659596ac6eb1afef9dc53d3020406ce66d52c486633e3f1ee359a6c68f77fb9df77e503b6de14e9e75535129dffe8c83187269b31cf5cbd1e83fd1a678de5d8a717dffcb1ed6fd1dc45b7bde30da96a9a6a4ba2135c51f77e7a2ad347f9af899cc91c45afb2037f55665d4fe185dbfa0af29edd12c984f9eb9ffa4498ac01ae6c9dc276e7369887f957d5ec185ddcb2294204a8abb1897b44466856225f7cd987183d87a4b04f54464586332faf53b85cfb37eb7bb95aa31748f6db76357e31354b866932c8bb5e0a1bb5fbe9a824018aee574722afe77e5ce3b9bc7c98c42d132c1a7419f438338047245ff478c2b91755e989f3c5bf653f94c15d1956a67022cb6122317c88b26b86ca91aaf1c10570df2572cc8f3dccfbb23a3f48d8f8355ee387c314dbde8d13ff26a00df51dc3ce52561ebfd9547adf7f0f249db13b509dd06ff1ede748a4b1a704cd9597279339158307e7304852a91e1a043ced0967a9e1359e65e4f5abd6bff0304a14a182d472c7ac5000b14d27206a9bb74388e95f8c5e6827d268c38722611308496aacf723921217ffc4978e4498b818ea010b9836f9b275ae71335bfc95328a8e02fd281b8d797c29ad6e6c84387f18f7d8345876c5f4e93d33f617c87db2036b2f55f9d46d9e4d55eebbe3657461a14e159dead4ed3dd21da8da4bd0 +expected_shared_secret = 4457f4dfec136705b3f85a0ed291390fe059fd12b007cecbe708efe7930631b5 + +comment = Rho leads to a matrix with unusally large entries +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 5667878d538c66726d8c174c4a41cc96713830c14bcc072f1af31cdaa7bee82a49a95cc664465b9c059ef7174e99ab696eab718dc78644a3119b81b1ca59bb17754dd91ab874b7038889239ac236f5990113d5495d7673f895216c6b5cc5b55a4e66ce4969504f089d9a5226d89a867061c110a6cb50e66189212d4fd873c0d8cce927941051ab228797cb8b8be5947ec258b7e9150660e7474c71cb73118c4b8a2f327775b9e64b53684a081710fc71b08d306a3e75b72ea0801940c9c225a6e801bb5f3115b9228086f582ef1784475a87cec793f19a729d544d7321222f3384a2d28ff303c62b1560c0c7be39d3adc385377fda9bced80a0780342528622b31371a7a2963ba6df80776409662e33a54ef12a2c459256622257a0a0c5422af4a512037091386b11cba375489766e045a4c23674b658614f9fc77ac0c4a17f84256b60df23a1da916245a0499841b12f0a32a65929988d42cdff22559182134d0c91b199714d73e1244445414801458ccf39040d9bb069f668209d0669eb0c43c5cafb7c34bf3441eac95ce42abc1e7ab3e1231ccf614b7f01119151a91bdc66a52d81134d151be429aea190b96b2cc0af59c6621206eb2955042581941b262288728a3339b1738024b4ce6802e7f984ac438a580267115bc3be0c0389ea00408d13a41c70017e506b0acbb79e64946b9080e835117b49a338ca6ea26bcff6468115bb087e772f690acbf3a4a591357bfc33198b247d116b0ec2003b1393a30f0c28a071278eb4a09bbcfb2bbaea7b7ae900471232c9de63c3f075b0727dca4022592c79793d79a92cf94bb59735bf0146bd8770690408a27645829d70038b16c835b4a775852bc699c5a566418d2368ad82c2d931a04eb39dd79c465b7c2d7ba39f27cacfb44c20d082f2b65b27660560442529604c281ec9f078c25adc15c2a2b9930a21d55c75aae5051d4309257e73def8b434bac47e18028e9e091b3c64b4402a6cdb37a4740a528fc42727025b782c29aa08e9fe22185620c53ca70ccac11f0a036ff0a9eaf7253bda1c01950172ebb77d374599d93b89d3a76eb7298c44816b4e1000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = c7eb8c4235458a2770e15aacd157db4c09ec8e22442d63513b0c4e519f393f14c9624f293a363fe0562bf5cac85b6b7f0e0e459a32715e72cf58df8893426b233694344872d51f97f7d08542e084f911e6e56f49661f00243420ab5df1b64fdc4cbce946ef58d97b2a44cba85dc3bb6cc90243996561e2ce1c490d01f2fb539925ccce4e81cd3b7f24e0c9ccb406d1715e10e524006d95ab3752562f39a299067bd5581431410e710c5898d52507cd0e9051604aa269f512d4a51efa5fb6d662901f7f5dbebbe8e1d48820c05eeab0b94f19cd28ce0082c42dbbad01ffdc38443890309fbdc22b16c4ee3461f8b4eab6dd36b51392c059debf48103eacad7638cc43c1d6ad333b8ab958f026e914a662db9af9dd1dbb20371f83a660f17e81d52290a449a572fe4de555e8021516b6c9d95725712b867556d474e3832cb24dfe3ad74417190f6346bb3e7115365c3d4bcaac876dc785da3422501e1c45706ff231df10be24e5f55d3d2da1508cb34200d017e562c20aad2d1833356a9f76966a679309dd8de635ef9d11d35eb862c4efe547a667bd6a1edd5f895f63912fca65d6ef897d550d698506cba198cdef1766eebe08c8ee29085ed92f75ed9141c6d2e188e76196971dca72f4d901e50c7daa88b343b7c5ddd3d78e446cf2ffd2ab84fe79ec9883078689d6c0d2ceec4023b7b921219e291a6560214b477e1644eedaf8a0ba89f3b0750d1df45f3627b7786d988cd862b50cdc93af2283e3aeff87ed7b7e258a76d0fcc3b86ce94a90d0e1a5192d01a9e450d1971548144e0537e4dc8523ea2abb9dad00765b0e402d9a558bf1b15bf42146246f930d241bb32bf6ad281126fed40c6a7caea50ee7302b739604d6fbf08919cec975b94eb4e54359bb0b7c1374b8563200b49fe6cb856b1111bd681f31ababbf18164ca4998b16c7649ef92a0a8a47fa89fa92256342a517b3fac6b59d89d7b91baf8d503ec6cb876e0011eed47dbb0ce4c9ce13a4135c10d280d7a67c151a2f9994429f44208ea54a14070b7834241555b35a706db557c42452df918c3d9aa2d412d8b8ef6d766e7d +expected_shared_secret = 2720f0bac612a277330b98b0a4633be90f0b0519c8190e387ffb8c602ba6b6e0 + +comment = Rho leads to a matrix with unusally large entries +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = cca86fca023c46d54cb8883eacc247d96cb06ef01b246b86c0711f0be3b218751adea46e7bc01555e21136a10cbe872de0540ebb09306cd71c5084612e733f14e0aa5ca67c79a7c30d047902957fc723694f24c66389735cf2cb69a09066b86b1b6c01a88b0a9efc17351a678d06b8987aa54a85a2f2e39ade850c5598898ffb88ee1320998c07619b94ed7cbb896b97c2cb51010c6b91cc54886b5135db4b368a61acb2b415e0b408a010b331c55a6907bc3cce8248aa19501e8ae98526940b26a67d70843fbfc06eb92a817c4a0fbf808839404eed8848e79983d2616ddb52974f21607f6a74bcac68c899534a951865123555150564488887877edf5b1bdd6949d76a6e28812d3a61b0b8160da3a49d67b889e884033419192b6435e79025bd7527e2ea1f6707bfe8683411e6b67a24c69b09297ac24b7348650f8537bf150781259c8e925028f0ace02627ab741aec9a2cf1c5cdaa963f0703184447019b68396ee6646417a600335a4544030cf93148a4b9f7128ff072adf2a71f33e8481a07353a51075030bb7a191be89855bafccdb79c0139260b8d5588a79927ff2a2f67b52e8840a138a95ed52aaf5b61125b60202c082e78598d328b607a9b067f26355df800b0e50e70844426680b69a0c52495c6f558a23fbba14e3b821f6abf80dbacefb53f8fcc613da12f0a352ea0d16a77108ca8b93dda7549612836fb65799cf7c02ed49d90a8baa6538db4c787079177d4c5a2b765c95ffbba6770710b30aa9e2c1be803962f07ca0ce8c8f9d3cf4956b7c736c103fa426dbc17d958a7a25ac70d092ed49483555886e78a3af6b363f41122acb472ebc854e8021ad22c93133cbe058b249c581be6b9c2f8c1173741809dcb748d5b85199a81b8287861d29b13237eff3b1a020bc49a6258c7745c237915d5738247c38d81d6c08bb5c74701660e012b822c3639eb79a5409505d454af748ed767b147940e9c00a2ef5057f8308dbbf060659708f8b1aa9e2778b3a62222f54b6c966048aac74dd514f5c663d0ec05adb99c4a9c5093893384648d21fc92831151accc7850a85b7cd9ada62082f802000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 51ffbe754500d132a6f0a749236c4ce530ac27606e6a9ddcb0e311f15f436aa79ad04c65d93ed41b39b1b179281aa42aa7100829e7d3c28e0906423e24611945737bca6d767c0e263f8e38698903eee5c197928cc958bf5aae01c6437836e393eb5c29ba869a6fd2374395e8848e75f279d650c10f6e4175ed2d05b73bb37f3d92026e3511dc7d48d8207e4fdc5fdbafdeffa402ccbfcb893f765674b35bde9073b3e508a9ecaecb51e8f0359d2ba50d65893bca9030261a7543f906478760d66e8d8da154b13e14cdc172405d83be4e0f3d24caaf1bffa5841b4c995d47d47c5a28e17ea38d5d036fa6af131926c529db5497082a57b0345d34226ed602a036b8137c470e741710cabaa4e82c35609d030a6d492a3d5b940ef20ee6439376838256f19cda424d7d3e45c8fc7f5d6a78bbbfa2cbcdc8a09efbb9600f26b8be281ee8382a355842e9791fefec1abbf4019e1d31db30b3313ba76c3a0791417739021a8048a98ceaf8bff65b494dd4b81b0d80f25c3f3c5265929d1d5b6fa3cceb46983dae0af05a4c9c2f0937e37eebc91d39ff6da03e080ee0afdca14c85938837e97b182e6ce1bb504fdb83e2ac5f109c2a66448a47c12f9a72498b83499eb7ddf9064146dade1683e814cd41393a64ea066c3bfad7f59d0620e1afef3093c677b1c8dedf8c81273bb581825991b6f282995084b43dfde8ed46187762fee9804463a0ec8c633b68fe0575fc414c85cb99148753a97e7331f10b57768ca3532c3e87d79848cbcc28126f540e3e0d4c18550a34f3dbe1884b4c70d0df97a80d32cbdcea569cc9f4f80b469e5a6bc5d562ee81e95a794dc1ee1c61d51516b4fa905806b4f0d49996e10ab9e226996122f065997c1b4887da7b19b002afad0455de6614a43c049a6df10f2a2549363a791721c95f1c4311babd5b1cf69c8d1cbbd95e8bf056f4424a0877303391a1c17f4e56d8ee0840bcb6ce832e449f9f1580f1485bd5b746cf18635dcc1e0ebc6f416511fa77f4988088781b40a77178ebb2c93b9f213c671c9727a81d1ac6afde0fd09d8618a5f157980e1e49ad44ec0e2686 +expected_shared_secret = dd5b87482f6e9fe2922cf3c75430986960650011b03b94d331edfa6d4b249f92 + +comment = Rho leads to a matrix with unusally large entries +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 22e762e6d77baca48b4e27c69245c908a95508f032a0e57f2cb82542e8c4629cc856318c12a402da979de1e1b85136c4a8e897124837add5aa7ee5c35104243f0b154294440d73cccd3a0aef77a548291501c5628322163139be5bb58b438ab9f1136095c1359eab171e783b7227ceab75703ab6b77b0c2621ab49e3c741a2260b0d86021146b88564c8d723cf4f0cb62a674a79ca013905abfa8884b4b37b32b20940c07e513b5c419897d2b33e2a85311df827e9272032a930d8f49a4cc2b80d6367d1ba456a25ab0f774646d0273855c9fb106cf5292042619a4ef2462ee88ae7e5764d36c3da25366d30840476845f82378465bef5b980110a1ce913bc1703121c036b0a6523214c91c337736497b806ec97a2c87756418c38e2803f4835cf632cb08ca8e2ec000b89095b80941dca287e3c703125356b9b2d06c135c6218548cb49c91863d00269738126a6ca44238c39ce48b5990b5aaeec611f768b3c2a544f6a502e69ca73ea2e91c73fbe147762b87dc4446a74723350f1b3feac73cc076216f50b26b7b2eff79edf2430dea28f96871247804155b65935c476c69173c0ba154d7519dae450bd0164e7ac79878712687aa100c71399675e1a4649df88c442c247964b6789ea1be66c7e0a91c9a6066308475432ba697c3a0af47680ab917f3da0311b976ce6b921b62b68a201986b801e03ba85a1a5a0ba567124a84c07c12878bbbda9b562c2a187771559d7aa7b4bda7aecb4c685126b1b343a658416608b6ae4e331b8bc84d4fcb6115204ba1c76f376bd6f5c1c7b9503817758e0a5955775823564cf2a078df488996e364136ca2a9a7b0c6ec1bf57082d60c56e3067b0eb100aee060d70e08201931405c089249487ab749b88290a2beb6632bc5f7390649c4a9be7441a49287f8e4c22c6bc03c5b788c7a0807f1b39b8e6514b8047925b459e2ccc11d1a1bdc29f928c5fbcd8b58f2b6e34b6091500c4dd4979f640c50df0390f2c0da32c1e8fb63f2fb3439ea2b35754559b0a7554e15d2dfc123763213a3b0b40b87362203172519a81b9351b07bcdcd56080fa07714a700658a25368000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = ac7ba64dac025d715e62ce9cc4b950a543bda498f9ec1746756aa80c5343fe95673f30c441d240c52834dd8312fbc7745261d61937945c7c581580a12a270b6baafd1df41f8e7e85e2045c7166f39336cbe3c9b51bbf3727de33d5442ceaa6dc479cbcfbd1423ec3974988990e6690940580f93a549f65081c9edcc38d437b775a88dd9899d4fe880975277a4dd2a3f91f4be393f1e259f52cfeabb8ca43a0c89854f2ebe52b2f34102b70194aa01aefbb14c06658ba9c134761df71387abe12bbdcc42f68a0e9389ae9fa8d0776c2a8b4866f0dd37836494f27c0651b2e1388bae97068e1407d4a408b1ffda1e2159c15fc22b6347f6e6b293bd88145c88d17fac0a17c71babca924c994576b0bb86c2e83678759f6e29180204e1c9e167934d459bd5eb3109c4ab027e86150fb0144764fc371c93ee3d2816354e670141065f6a11909a8652ae0b866ee2068cd6846e4a3c99a1de553e36a6d7a38724495dd0ca5d9a1714fbd63f9b11026b81b90bb41b65fbd40370162f0b7f41e11a64f5e188c8e380579556009fd18372010afa3d4e95d8df4dd3d8d86db67639869757ec9ce2339b0df95988bd57df993e027316471a9e037e2824439a524a2f377c6a6cc7336b2f672a78c7d7b26996cd445476b49eea2ffbb7060eaf3c2e5f1ff08a9add038645820ef8eaf436f949113bcbc0700883d5a331f45387b1e6a7e180021a269ff29d9f13133b05517a65b7fe32cad23cae9dc5698e0d23cacffa357faf659cfc8afd4c5417c9ecab5c44ae08d416d57904c1f60801a15fe47cdc727f03952940adbe55a222c19f458913143c3ebe91090df3cc57d31f8c57c1cc8bdeb79792f32eae17da2a08df08fc0acdc4ef12d0ef04dba38833d7116280cd2b19923cb2cc4a3343f3307af7af5d32f3ba62e8e7ed833363df1ed94b27c3b08d4efaf5b394bdeb417aac35c05fae6104b07f804761916d3bd0a8e546466ee22045f84da4d9029212df2ef8486c8480948c7cd49224ad5d553f17b30cbff4ddbf3d8d8d3222cb9043767c4ca794bf9bd85ecf3761325d8d1b83df43d40b6b695aa9d4a +expected_shared_secret = fe359fbf7609e7ac0206c4f8b273cd89e699c0f3824d86b2df5e24a6fb2172f5 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/encaps768draft b/libcrux-kem/tests/kats/wycheproof_early/encaps768draft new file mode 100644 index 000000000..95e6aa6af --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/encaps768draft @@ -0,0 +1,1841 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = a72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = pass +expected_ciphertext = a413be81047259202401ee35989d25a3856cd1c0260ce2391de323736b678f328005c821ad092180b4496f2129280f4f299404362b9d141948b6bb02acd5736559fc9039018c961dddd94ee559198471d4a049e547b5636cf8bbf7db1a90c72b870923dcd54b148c60c9c8ee604d30eebb6901e6df2596121826058d25029ae399c95f6aacbaafe34f118ddba7a69d7cd899b5f4d58d3df2a889b030ce9a7ea6446d41a60a175f127da94c276baa1edfb357d41b2857ad462c83d8ff00236d9bac59325e0c3bddcb37bfe0fda4e167fcf6aec149fe5f9f6393fc4715c6995d67f2b4ddb0c7678ee140bcfdd2365e8122ca92cbba1ac703357edf15210c6892669f1a2b88d792be7d9aa56c5e8df758abb4bbae83141d2759dfc4ea8f2cf00dd86a7312fbaea9cfe6d7fd3f13fc8cb75d252cb3ec7e7b37cd81d88f38ae593ede6f8a81d51183d7dc7f57abb21ce2c593db72f0bf779cccc82420f53c2fe364b1fd3cd2ec54b924a62afa4c3195578e48aa5f507e7928d7527d6577d3fca87e7b7b19a89f69f0018eeb36871baadfcc7094e344fb36481fb14a5c53c30867cf1c5c02cf6227f9aae8d8a12b24c5ac2b8eb912b87de8325409e440a47b5c74237179a6ce5558ee09101ca4e645e24bdc28778735abf98b0688f6289d503251582aab6e81ced0179829f7311731d0615d0a0d955978aafbf8aa440a5c85870c58b3e5c1ff9267f094b742f516e8e9759d0f88021d99a7fd65bbee801217276656d21f3734de0a5589b33fe996ecb99c0d8a52d54b39dcfe707fc11e35638a69d908ccb0edacfb2aa435e3beb981d3fdef59cade6f63cda056c526cdc55b87a3ef2638bcaeedf406711053a09d310699dc8e3d07acc10e1ea8ec8d51ab31c04ca88c2177a51193b418ccc4b2548ecda861598ffaa8b16eaf89d59c8403c39c8d94c428cf19180e1420287b455fb6e4e5bfbd383aef18ca99f810f6cea703be4b9bf0cb6f0c5383e83ed3a723a27d8e3991067656726925b20fb735b12752facf684e5c03dc5be7a63af4bd930754fdb5f749306c2cfa6e398925c346d9d572924b153b7673b7a5022140264fd5a0abe00b5d85c686f296fbc49dd3155ad2f748255506909b355c7060dded4dd2fa21c7bf681251e7d63289e15f85854a25b4fb085ef03a03cd050f4f5021d112f3291a9fd60ad01e0b5797e78d9b94befe9746d754e6ce41da34c57da3d7deda6b233082c4137614e964fff0e38472e36e495f54e2d2371a7581b694cb263ddf80bdd43f6383578b5e18244a69cac9cdabea3d05718f5c23b1d4ce6684457597d01284b38b9d3eb1eba4f5beff990bb749f096a30f1bde724ade3789de5ef183a60163e28f1584500984ca5153555c38c61649683a727921ffcce3007c267783bddbdb9de48880c4e8452dab29e7c4f8d1d5dfd303a908b1ce08be0b9fae98894dcb2692d0b32fa39da98bd4ff0ea10f0b438a4971a7fc47182fbe52d6de71fee3e824a39f19c27f51aec6d92bc7f8b8f071847bca +expected_shared_secret = 729fa06ac93c5efdfbf1272a96cef167a393947ab7dc2d11ed7de8ac3c947fa8 + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 6dd406b49b9ca035467fd26c6c0b824bea310f435fbe8bbbd3430b5c39889e6b117e994e2f08823a33789ff858b72715323c6204a241d9835ec0da85c5884a8a96210219099c8c383c182632280356c1b4f298405258a170e81624e861fc1082d31867a9037e3b90b0aeeaa064d27020da7ba79398fa92a963a8a294e7720bd4cd9ea213f08063079c4d55b094bebc4e979444f462b967972e61206fcc80337911b02c7396bc64405ffc0b77cccd2ebc121a734037cb90b77846b2359c30a451beb20a6d72c238284e5df2ad1cc1a33fd5a104965c86251a596360d541240a4828231a827a0168b6d8ac7e27328173886453a9c91498765c2bd9ea9f666bb4a1d60f992538a1a746df845574f99adad23b9744afa81c7fb79a32b175706454438f46b8985132b8e1cca10c2b0fa011eab2428b88cfef9378a5228e55d7463dfa5022c998abd6354118b5116b3bc1004f0008134b85a1cf2a9f409a10e14b6d06c26d8e355864c35bc71b60d5cac33a513efdf6b9bb83bc880983682c8fb8a81b6927ca52e93835956795488181a8cd82b1a50dd18a25f35e2643cdd76c282e7018bb99624f031418fbc8052c4179b43a5998be9a20cd2d8a883b313ec282598202add6471971c88cd9607d3a8052519930bc5bc71ca4652352b4d02620b8d983b9849ce8b8935f1a4decc3250de7b0cfcb49eb7b74e0b5792ae97633b092081c3c6bf58f1b242ca07610c3387098ac3f0f9043901c614590c4ebbc64ce1971e824694a999cbcc430ae923a1432b6a4911162213c429481394a27006b9d48c0ab5801823d756bfd8c6919502d613594aec81f5669bd4e8495292606959292467ccac7f688333b3f48a39fce5c42c9c2653886a5adf4747cc943b2416348f46df5b58e4916ba64e9664a4baaa3e0a9652408c8e5076c226c3a7932c42a846949a2a26b4e2c452f86cacfe5c201ae1321ab5c2cabda557648a849241f077a799edba3582202cb27763047219f5546cf18819322b9c63974b322b949baa491d97c70f20545886c87086721d3ca2aeab441264b516975ed0c6044a425853528424532e4d721e85cb0bf65c26082c790765b062916fac4a0dcecbc2e900c6f600270838e2df20ee0a907e3613dcee049c445640362c980a292f123c6c9b5918f21443c996016c44d2a124c5925a8e0c48e89bb167a129fcbf67adb89903e1249f6028bc176bacc722366139858e583eb582ada714e79b5ad1bc1a6f18754e100624620968d0702e080befec425bc16b650a307802004c57590897c87e65347f32c324569051d798bebdb421eb28b2d1a0c662444c7db32bf97845d7225c7539f457894eb87606fa85b5e804053fb6ecdea773566c006e540ee65101d99bf314181d666680985c78b103dd00a040dc69cff389fea7c18e48a363b943ff042b476dc86be953a5925076cf749a62a77a9406165d31dacdc3a677b9114d8bf84b43f59f647fa4023535140fde04285921184809c5f193a7df45f62187854061a4d6754da528f3b71a134aa487d9b5f7cfc6838108b8b95b51f5540c9ea5f29990f7be07efd502461033f103723093a16dd96c098977f81330249183cf35a636841bd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = pass +expected_ciphertext = acddfedd604fdb81a6bb89518b9c4542ddfa46f4acf3a1ad092de5ece00c823b4938a85cd32b1c291ffc446adba2fbcd0078e9ad7dac7aa54d9d38d1603a0707e9bd77fe2a41e2d35fdf5d1c3b7a9c4a1a91a1d6b96db95e11df77af9ad3511abc41a8f84cd1e8afe8b6d5bf43a912c3ae871cce1ad968f2736dc856208ed8802a42b164238e7529570be8a3b57954d9b6409727100153df71d3e405a633dac6668440919fdf6692e39505a7dac58268c2b9eaaa0dcdfaeb2ad38d7edc13617eff27e365ca2e015f17804ef7204158fda049ebef27cd80b4d03416cf0d34fd1298440c807079aeaaf86951dae492efcf43d9bf52afd9eb2e2fce0c644f4efa8c5e74f612537d809a64f68145df78d458908e0e8c8901e340e11fa5c0ce78cd7e2923a880f4f069934b7de2a6eb076045b7a3b43a5fbb9e56afe3de239fcff2eeea1d75e96c64779d9713d43de1efe523bbf450fa8236b9b57def1cc381a798b3b77ab02d8a3e944d388932eda80f5eb542b6e275d8c6cb92b31f8bfc0454643dcb9041e0069a0b8f6ac1c4600d4f15543fd5c25453ea1cd5a3cfc87bee71ae1a955a60087ba5db2773fda9c0acfcf22b2fb0804793add6d44413930eaf6f9b2d8c18433da6ce17f9f5352a9922741be5558c3d4eb57f9642f9774ad449de5d672226163174d82c5a00157f4b69d3d5ec3f1bd5586fdd9dd1c9f4e50cf4ab7d60201c7e13c5a3475f6ca877319a845a2f80459d7032b0388742e101c26f2831b7dfa78dca4f3b8a127cc956fc013dc068498901eec716d8f5d8cf943892c98bb435a0c3440512e10c3c6d65926549309e5a83b391b06b2b5e8f51353382527557507654dd895f0b83cee90de518228950d141b968c3e4ebe116905b3d233f8febaaa7e83170d50227ad35283dd31ebd69ceb7352e3351cec82285520ae8d56d6f597e52e360cd9586d99eb3bc1f2cdf1a1917924e58d2db1a813024cbf02f5d0a3458fa55617eefd30a5667c988984fc6e61849edb588dd66ce3be5a52e42abf0a53e93e0e0b92e178fcdc1d5a092f1d9dc9578f555a5286b112672ec8ff7a2aa7ffbf23ab5cc752a45e0ed056b3beb9711b28e415da7bb31fa2c9b5227d5bd30d56c910f58eec5946a15b6af1f69aa343070aa2aad6172a98875ea2f1b33ecacf8c477eaacf56231daba5e91a97f869e0b9f13ae213153e2933f10e55bbea8b8111fcdd68655ce09fd893862dd26e29cc24fede5dedb2cfa720f14fc739088ab28eda8c5b36ee7cc98d104ba6a463e8f6de7b906bfe165efc1fad56c499a64d923d20f49648323527dd6e172b34d79517baf2fbb975e4568c40ec4f19054721055fcb5255a7249c60528a816df084c6bdeb1986207aae2e6e2776bad47c31078891e2bd5a44495ffdd7d0a942879b33195fed959c30dc688666b718d6367867667260eb23229483123ebec5cd2d78e0f99572fd293d453f0691d1d72da92db5c84036e1a0bbfde755c9c1d18eb721856249db963ea546b4f2086f1f4f528c457 +expected_shared_secret = c00e4ede0a4fa212980e6736686bf73585a0adf8d38fec212c860a0d3d055d1c + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = f5a35b4ec7538b62289dd1204db91ac492b610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78a4149cf10b6d93283050167e737596b711a9f32a0f6909975055ce6632f4b42cf9a2361cf69047b5bde1868dd745a82cf473ebb30d86a71793364f70b1255b1c2003f166683c936a7977df156a84051e69b95e02616dd3090dd38086ef3bc12353bad25377618965c2810fca929dfbf46f20360fc847818cf90dbc044eed16b3b9052c5c70a5a430441e53a5527a689f49b35ce82b84d6057c5269fb60c710c5731f431a970b86431125910277fa7c310a2285117b47b95054e4174a1eb11da3e3c26ac25619d36712b11b2ef7405bcb943dba10d50c0436b50de5b04d96488a38f53df37895ac20c10d959d81a29fe1f319ff871831d93c54654172a02e65599f9d820ab037438e62714be6c7d868b66ac03c31c8753a062318ca36b6e59d340b9696d47c38f115104765865353a05c8fbc4b0a62a96577e94c17094de259006f169e75b8919bb4c37df6787b59bec8fac999a90b73123a5cc8772ad67585c879ebe05b5c06afdb440adfbc4ad400d0e634822a843e9b165f2f0bb748e231c0e0ceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fac291a0bbe96e9ad36a4a1d9c96939603bcd76a81c040fba27a5a39a1c387cac9d1b086e512468d378e96039aae2622fe5483673850d411ab64b892f2c29853822eae76feaf5716a660b55c2020dd3323a150ceef9ab79925d2bc09cc6faa31727a5912a7f5e9051f8b94d8866c4da173d3f2a388e6c44218338cb85702cba2f602c24e1788158b0129e7c15dcf2cc6ed55c54b456cacc07d179b432a5aa63e8ac59f0b6979a833d99c13aa0c56cb65928032e2f30583fa6c038748ceb77a91c631dd09b575f13126f1447cab00bc9c85fc7601da44ac5fea5adcbb599a409bb1a67b24ef438d750bf87a8814df22449c9256da1286dc623e81546c283b80cc88c48f003678ab35380a6da551ac7041cd5112d59d15a80032c28b61a1bb3b8a7267adf4662b5963468b3bc5918418f980cd7db3946c5a67f864dc1f3adea12142fb71fda590e070007662b5c3b8b31af169a092a2e466aa01ae879641bc4d1d62523ccaa3ed436cc089b2621456114215d1a9eefd1016dc81d5320956fd942bdda40f3a033e5170ca6a2c57ce17eafc97aa0959cf37b92e789636f159faa827ddb895553540d52a61edc1b3dceb22a7231c48037cc78594718902333d0bc4fe6b29352991e2ba5d31217457007057b9d3c07c39b7c7eeecc222d4415d6d9272ec50b81520bc607592947c86d2612e434c22513235536cd08f10022b97675b89f1de58130eb6797380f6b68773dfbba0664bb7caac84f7b06711587c6ecaa383505f62751c8346bdd502a58e9326e4a0d2d29226f794ad0064b2cf0a56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b8372158c1a7bfdcb65d426458edbcf8797383e272d3b18bee68c4d74e25751ab1ce4567d66b714cd62a8e9b886baa812a9f50739e30f296791414727d55003bcb52ab6bb74cab215b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = pass +expected_ciphertext = d4aa3d0de639a1563732d6f6a1d0e8dfa86c667977822bd99f7fad9c2996b5b0593aad975d8a7257c68209d80f676f7083b5f2d2690067a9c639882955c4717ac9f64d01676cd1656a181124b299010cef7094772a6c83b4dbc15320a22b02de44da9e532064f3dc3b6e1e540cdc168612b4271849a1c48efab76c3614c173d973ceb61bef391eecd1e3bc8aae662c4d60db2f55458f4d13c56262961268f714dffdf907aa08a434d7b897d1ecfffa32f1c62c3487adbc6f3c6d6dc38302069e2af348d26b39ada73b2c5d927eea8ab080cffe74c50f6e2a5e2bcfebc73ec4f100710c2283b42cc8f3db9609bbe487d0ab933e970cc30d3f084b179602b555f797bc53a49d56a1ca53a8b0e539b2cb41a08c306a162b902f0e8475d0332ae8c2329b54c45314b598d11be48fc0f9ea0584df93ba3185c94c063968c914e390fc7b04202936acac5c8a7e7677374f62fbb205467697881e3d8ed60b0f3730eadce1d26058e58f652e4e00b9b8c2b94102d1fa39460973ca8cba348cd67c20aaa1cbba500a998b50d1b0f48885edf46b79ea816bf7b1831ce4297a0330521bd131a9e5a43a5d8676619be7a45fe29509179d8eea1d0afd63a758817c3c5ce5076f21887a48fbd2afc142489768ca4bd0dafec9727b1fa77aa1f977f7aa72b628290265d1d3a904f5b4c22fc313f5f75d1b8496b2195742b6eb017eb8d0c4d40df0913a7ca9dd5427708bebdc435ab096d6c2cace5d24e8dac647bd5e7e8060a81a379abb478702341f0376e2ae70de9a4e7ec6213d61983713fefab2e4f7e6611174fe4c0578435cf87fed3171ae5488bded533e9e4a057c6c79e37f93f6727ae9269d0c96bbde650e4163278b54ca865a38ad0ec3a04ecb2eeba9b7f1d55c84fffaa5603a662884baf8f715ea6a30d5350eaf6b4abcaf7bc2a3db44bba3f66e84d7c0ba4afae3950dfef27985198533ca5af7d59b4e89f9dbfd29688978c0bc639dc7b3f06536ea66fe0f7aed7d5eec6acca1ed5d13f4ec5ee9e94a7682d803477d0b31ddb77daf14395bc54cde91caff9dac3cb641a1b7354d1fa9e90756bb59617cf1108e2bfdffa11bf8e6565f7cf3df3501a2193cd03047a7e7b44aced6ae6381cdf440b7ed2efac1ed5f6889d69170490b57335a01adf88fcd6dfbf8bb1e7c97038b13e81f018868ed52516f6bad28043d48abc1bd69d93f6a192d3264f38fd693f5e9b43a81446079369fd8bad5197328691dedd297ad98f1684a03193c6e6ecc469544463a70157f644dc14c341ac3943f3920e9de4a96d8091b282ae5fd5d9fb3bcc94357a67e0f616c6906e555d52bd13a24b05be0866e43ea957b297094f34a3636d3d9453a34b6d1565861fa67a746d2fbb598a6f1aad8b2c7db65043c5b7bf97eca89e32588fe105aa6ce7e30b687194169c4fdc6729079cdabcfb0085d00de34ba57f9d8140ffe1087c469d7fd5af5242e096e18648866bcf24bb5e68bec64289ba207caba330b6c8ee82bd43bb71fa96977909192ef9ffd1ccf +expected_shared_secret = 8f50401bc9b1f857fd870902d4065f6cec8cb825db3eb22573c6167442b6e19b + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = 25949faea67e908040a25908a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f12118e0685b09d30947ac76f4f72e89bbb7579bba13d3cd4e262fcd385eeca8b780d7b6d3343ca7ec1958569c49808b97586c263903989928ab9b63efac00b27037637897556b8aab33198c144d226ab9284541400138e03a31f10cbf1cc4bf633c3ad70c65218c1b18770c91d139971574dd90317a421b8bdc56c02c2564b2496793a27a12009ecca141aa337e911f0b448d913394ec1abbb46a568ba749f0fb0a2c4562637a220225a0afac0e9a53ca4f506391d7483932814dea886c89879237a95c03684cc0c2d2701b40e5b3a340316159cbc56bae84130f2fa830501257f8a8948f482ad194ccd4f6ba6c01bacc4c1b9c3188c3d002f8f18f62393b373396f6c510308b6754b8ca81f53d5a1512ffc3428a6c2a543a61fe1193a86b97b260339fb43a9f0375b1c2c62ddb4c1f6629db701b2d2a50577cc7d5d55a30766400842938d83a6818a128310d16648614a6b6df6b5d8d9a8d0ea4a127f4233b9a50ba539f5f01b62513a5c7bb8ead8463c0a346252c94f753a34751b078a06dd785ac6532c2730caef7249515514f8e18713c2a72d8949de781c698e708deb35448ca1df99b8e09ac4faf694ca71b7bd41bb7024c0435424831424f680a77f13506a56c97b6966afac4b90fe60bf5e7507e6a7093c47b5f8ca47d86c767455d645c502d82cf5b1ccd8880758bea855dc71b1c98494862030202c06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacc7117980774e12355af27e506a2ac63c4abfe585b2123e2404b9ea9753fa101604663d07e153c07b743b23c56b86a91ca34111803a1f5865e47807c012a81885104495499884b495ea3f457a2ae1363221b2a94be84e27cc9e8bca44f8fbb92746821782b3b92b1bfe87127f34076bd4acabf60e4f9b97a8f63008b584d0221af927c67d616bb9933be9486e38d7befda11a27175f670600041a6dbf0c9a4364b3ffd28eceeb0c8077c3aba19c6123a20ca72c0776aa8e21a582168591c7c1eb146ba820c9ea1aa3374625c8744612bcab37250ffb34a89d305c35169660dc9b09f7c960a4c4450b1a2e56088e8605fd75a35eb620c3c90b93fb001e03c006a15b67136ec1c354d405a61014821fa9590dd212cc6095dd011bd8801a10f08f15da21c14cacfde606ca02b7e2e1483e3514cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d58c033ba2280ec0521bc53dcc3772d48258593a5a1f9974228652b8cb4a08296eeae869c733a316d926d400cbb09a2daf532da06522da9694cec2a29cd4c87f6a6c837c6ef6182a30548afdb807bf447953a3827db3122bcc7e33576a33a943492a61f3625dcf412793996c664a4664b3666c154f90b40c3ec514c4b1a2d265a23b897177342b76c69637d52e356620f468480472923313a658683566dc8f8fc1079f248f9d8ac67d4ca703339ae28a86edb4bc21db231dfa970249aeb1e2138bd4791352151520a73b0792a0e77d4967bc8b46740cf5599d4056f382c9006b79938825dfe2806cb6afe7523d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = pass +expected_ciphertext = 72251024f554cdac42bdb223557f2c724beb9df0001783cf348f83294177c086dda8f240a793f879b84b7ddf199fab6cc89a5c1a5d9e72351a6eec092567a7fbc0f588b970151d55d1d8391783396c352f1842300fd934a2ad4a2627b455e47102c45e3d23b5ab6cd0db4b40f689762c36d0c90ceb333820e736fcdce8f0f683a3476602a5f3326fd6278ff073cb5833584d8a5317bb6349b6d4a0c86b4adfb9f3e09cad0c35acd652b16646150e40e3653e230fedace908bae8b9411a8b344b90708a468129781f42dfab8476b654ceb3042407d8ba005d7577976e6b5f918d53d3cc3bfa1426633efd8a8a211c57fcf3026daec0d1b63cb874efe2f9b0b90bc43421c39b17884fd1adbb1b7a27189743cf9b785692d2afaef0d8d7f3dc84cc0a04351085550a53cd764ccabe0dfc376dbb140562d8a923fc5d6478e5fa951c1797673db456634f948f840f534f66739943509455deb3e1b7e4249f5b35f0ad810cec14e275f9dc23b00fb89fe12c211f310620ddbb24871a15eee57527e12764f45039695780f3eca702d7cfd9cd85b2411bc426192d6e9b77d65b8bfce6fdf610564402e8be61831caf75fea911112cf42e65ac431c891c03914c1cf6cbcadaac24f654b4f853de2a7ab29f7dfa52b91efeefaeafda36feb7868b4b28f8f987b9117d5049cc61d41b253e4ae985319210509b25be27e4c1a5220503726318debc86321cd1fa4158b1afe3f1677f1474ad276e7adb6ede24cd85a67023e85acc924792bb15a4228bc242426b72672b1a443a188a2b6f95555ae0ea41e1e03a26ad7f7f3f0d1629fed1002e8477693f97d334caa9b448e0e09e9a1216fa03219854beaebb0e932c4b51f9c7f8cb869b05c5c401b3de89cb08b9bbffda04d6b675988fabae97a16c5991a9bd62aa093bbcdcb80f5251def293ebb350a4e8834ecfa67f716f4553beb0731069ef5ce77af83f29cdb75309f8488a5eb7418677b4cffd27415d4057aaf750e9da84445146b21ffbd57e3ee5fe3cb0525a9192539ff44581b96c6ad6131af9578b2d82c0d5a9e9d165d992f34e7f24805cac07d6595734a166e946a7b0e13e972f3a4eaf34b82e5c04f10dea2b31346d5b7321a718f0e162afbe6f80388ff18b4f3d2701e17b9ff3a3b8d62a412b6bfca7ffa618ec1e54c150e2b7b7b94a1ef82bad5d6659b22733105632a0949068b2b78751a660567f1f74f79f81d4bf35250fe1cac57c4bd5bd2a759b23289188444645af0de21274f92c5341781634c9ac6548684a9ffb2960735aa2562fb02562ab8b86cc5cf544e71cc1348f3fe5c25e9bb086e40773b2a860a12a35799dc602a6140e6b29a249aaeb366b2df08fde7ee87ea86a40f195b179bb355a61f71c40151a3e4bfe5298fec2146b968141676c9b24e662253f5579523621cdd775c56257f1fb23bcfbed0fa1a7381330f678493794a0c6d79c26a2171709f615898ff6a71b2af60e410b37ebcaa0de88d54081d6659a670b9d4c2967364f2995e744c884e1832430 +expected_shared_secret = 3221d7b046caccbded38e369625f69bac60c2d7efacad8f24170b10c5d222830 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = eb14cbcb226951857be4b3bc2a1b578b148e824a2414412a3d57c8213793c418bf2e0803de4a16eb9c8b5d53718d38ae40299b89793f14741792bb10d9c21d5f06633aa3cf1cc78d0dc99983076f8756b2f96b2095e0b812160fbb9494038a88057671dc692f14a956d5e6565ff752d28237c70b8f8528cb1a04cfe5e6495bd3b46a3264fd7364e0d54f2ad27dd27b022efb3d3a632a7f99551bc3317250207f2658f363164a9631a34b468e9b3c9b34b27a3a02fcbacc516469f69b3a51554b93e05fd6dcb098e8af8a3681ce89548ca311e2f5421ca1496a532366435cfd56a26a245ba68655db99cd113c1ad1170bab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b302c037bab4954627a2363020c4ab5ceef5aaf2e352ded62fd6a52acb70c84723a527ba34f179204b26ac10692822ac66cc56bfeceba65c33295fb805c596a48a0c59477405c21ac3edd2c27e56c19bc84d710584ade48647c681746038ac74ab73591fde872ccdfbc3cb1218fe12acbfec9248c00e19424b1fbca70fc5193151aae1415416ba2d7faa6a2c745cdedb94295438bb182dadb77182b2be5bd1ce0cc028b7eb71ba8cac8585cba3ca01620b63fc91bf3c210f67c65c92f893fc616158c104a5799720ab0fd907798f0678746475c8502029865dd653209a39c0c362258a266b1b244a4f42b4adc1c6bf602fe61125c3b989c018c0a0e0c73e35abc97c9ee695cd265909af82548b865eb4238376a6ab53a6baef185799489f64e200fb542ec3d1b42e8b3960e02730936d620360ff4570b4079b369a83629b599e7b27ff48c37f727a4f93bbb2d4b7e1c73fc0d6668e53c1efe0a0b547b1f38c51f4001654f45bf0e5766ca1c662f2cb99a6bd42a17f89c80a4db03c990a81ae9487e1a52c13720266083e152061aa08c03a7a703de58251f129546a42282515a3e27195ca97ceb39b00566cf4acadaf320d5c88c75ff310f10bb5ad738d38aa47c945235e1730b6cc227a194dcb04ce046a22c37319d910060b594bf8a64f2c4b8f26000031948046721e6546893a341ed2c32804149954e3788ea5054c51a43da89f9c789eda6727bdd4be32b15d47b9c327ec68422813b00950bd73c96c7175274a5ea8bc128a7c0993031b4e8a5d3c074d2d1abde8239d5af58c06509b24109c84297e3feb447fb3926dc19f39211119c4597711a222b341cdecb0698580e422a951db2305d4a7a871967db945a60439de206955c371ea52452f865da438130d2b8eab3669a97911258b08931a2e36c6c390b6845e8076a0d621d7692971ba71bda0b8aaf7ba0ad3c4f05ac23621a146c68bbc501854062b924c3a64916a1b9b19ce5b466f8672ede621ea987f83495106dac22ffab6f4a5cca797587126ce50589f68a2084875bbb505c7ff46922eb496da260e3719cdb2f23950455dc8d36e3932518bc11bfcc067ac533360b86550b6ad09e93dbb092be410721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae1907adea5772276b2929b9507db5c06041e5f9846506055417c6fa091652a4a424bf6396d46365bb40601e3a55801b93a1ccf39126ba7f025a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = pass +expected_ciphertext = 6416527ba23e80f4837873839feff13b3514abd118bb91d6b361b9bbd9abad576f3a4d8db28cf4461b9371ea96971269360f966cd6220bee62d94f3fdb9857fb66b0a9245fa492d68ee1a9e8e2a49f1610391349377d1810a55258b3529d1195ba41b6642b7c8b5ee3e14cf59216a870790088bb0511ca47eaad07326f2596cb851b00fae41118dbe6f0e3563fac9345bccaae3f1608f10e0541022de77c2f820499042e3e0398e48e8df6cef984c91675c3ea283e00ba9f12e7f3f0b5a4e9a958d648afc3e5012af630b6b64848036d95bcdc79c5d1b11bad1327853623309c5d0cd670a65d64a3737817f5961cde07a2d4adf8e4624f0cd88494b5050ec665fca1991384f9bc93e0c3be752f94d4d0fb3908fe8ebdd8b8a9968c00c4482ede3f60eb6736dd4e6a33e44652e82a4cd16751b760b784bbb778663bc514073a93be9e9626c7979052816fd54514611134fac5a6a7ad1b5c8363336ad8bf44f05daf59d6b66e28f86d1ccb6a776622114190dfdd65f5088f82f6ad4df28369d7c9a7f67f12ac36f143d9e2ebb990c4f87c4442e81d16e8753457183dc14b0dc1aa803a4b016af2bdea1b90e888ca5f15f5e0780fb6ccbe45071fa6f73035a547d1eb8318f735b15b9dc465e6938f5454808358bc4444304e82397db3d1f2b06fb5aec777e2922887408eab4804499268829b5b94e66e75b01e4e8ead235be8bcb68c801d9a92adad2abac3ccd87a486bb4c17d6717d3f679e0d8d549af5c8fad6a0a398b395a57715e8a7ab3870a475d5c30b917d24e69bf0c9fec18cfeefe54953064a1c56c00108f82df8f224469e2fedf46e2a8cb3a0105a3542284611ad45433f7782b9e879f483f4d5ee87b481f8b353741b5565edab5b252c73988c705d7adf1c3f2c87b2f9bdcb94ca5e4a0c5aabfa3ce67e8cfb8f79f43dffb385d8ebbd4e76ffa8ab641a3c8f3bb2291cda186160abc78169568e7daca87a9c536d8a7c345ccf8046c38e165488301872b1d7ca223782f5acb7bb664ad8c7448beff305147e7bb663483899ee1a4c481761f7b65bdc9c0d4396514d48f22ae383c39c9fc650b7b7f166bbdd2ec8bc54161f7524ac69a9fd9c538f584a096636cadfd633d1e64d5e89246a08a51a9c334608631c2687d63836f6fb8dd515bc7a4e769157499638d2611b69058f2615527a04f4ff2b60360e46e34bef1c8e57d499850f44ce7529e80ef0980790a8925184b4b22049b356f4fbfe293ac054d63985540cacb9f25e9180b626bf1e3f5bb3f413f090f5d468402edf672da22212f2d1214b760944f57d3c914c042eecec08aa5d2944fab51fc833d9e374f2be7c5fe94296c0df98392592e0a6b183242db0b124ea728c44a5aefeb2ac1c1437bb8ad49fdacc3fc482aaef9e814a4a8010fa2f0d0cc6a88a259aa8c09b7204e09a71fcf5a0e7a801c3319369cb933a57cbfcceb64f96be35598b4d2dab925014efb66247362e5b61cd56471a3ce4399ede77b09879ee29fa51513d4532bca164dc19be35bb7 +expected_shared_secret = 1d746afc4160c75aaa6c6967f4eee941e09546a039027f05f0f8a483710ac334 + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 86b5c9a75157e73ccc2e138518ea98a246145dfb6bac9b2ffc333c0ba5806047ca9ba8ab797937000270e773c9863709e59786f8ec948ed27660aa3758e33f59140e527787fa74a2ce22a4a8f3037a26903665cbfe8a0677ec273f590d64c97f69f396db78448535746b43296bfa2bf0a251bf986a524074c1f96077f5219cfa9124d1458520993f627aa8b7b6a0f191683233e0ba6bde24561a666fd10151b0c52c9982c301e0970c3363de27825a5bab078848aa5cb75a90c1cbd24cf67a68f3417780cca947131e4573934f9959787b6320a4b47bb311048289e2c915e35344e3a144e2708893138a15a03fce3816945464c229c587093b5cbbb519767fc65c078d6c684b8b81c1f9cc2b3ba749fb3074623e3c9124a8e1a513510357656b37087bfd02773fb59157eb885e1501740483f3ec070bd492dfc217d7db99cd7c9d57b937297634c3494deb585b8c93cd4eab1865f8a9c8bb15dfe583c7dc0427274f8df3c693fc351289964a89a3c745967231261d949552e0809ba9b7c5d258af579a4515981e991d93154bcaa170491b06752415b1d52bc2a98b7f39c5b91a87eb759a9a4537218156746930a347a5026911adc0412f10a7a7c200a1514d500805c10a276c327e4899aa3f9b95d1ba2347e0140184b1235a719e6c4a3011576235215d77084034771129c33199b70774b2130898a0c69d8f39c3a50b273c665dcd8031b4454d144a4356b9c2b16641311856cb65466991b06d1a8a74a5aad6b5b935b65dba8374ee690cd1c701a5a28b41732b5f88a9ad919a7fa563bafb529885488f544e1240b3cd673f94ebbc91b4757444a302578aa953161993cc918216bc56ba53ea17664bc5b543a38c3516d4063c35695791d8821240bb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58e507f8a105e2f71f6095621e354b3dec1f9c979ed7b3aab56b4741110fda601fac78c2edc386669118a425c634157875f61adf10c43d2184d3252edeb11a61eb67a349405ec74b9fd307558a887efbbb46c904f9469db491605a3582be433bed57363426055cc4852acc0317f24d89903a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5a0029c1513d5a1a98eae78713785bd4322261d90109a0806e565ebd9308849cc6708b536c83a2fa35995c819d99b850251c1d50ea902a053c7ca31faac37bcb1b40d6123cc4d52002909d0ac566f7d75dc89998036aabb267c5aa70184ab4cffeab018f195f62879be0a51b42b843caf7c494c181c2f06866cb2287a00349ebb136747da52a3c4a3c581798c413929ce3e698fa594f019579ae329a22d4af66f27b46453f22e61aa6ec5d7d854ff6d3c3d4117be2145b5c2ba7a57ac968a5ca43b461f808167fb5a76a942c95145098b95cd46439669c00366960e2162ab613c5ecb151359b093c27c04ab230fa7c0074684996f44939c81fc31373c8231bd0b6679991a32a031002b257b2f31101317b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659c970f94d0942124c17ce3ad50d5a7019146bf51b012d1cfa0f59b220a795dc6b3d7896aac680adad383ec46762b669d35909a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = pass +expected_ciphertext = e87c238704de82f3b46046f3501bc2f30e57e653fca6d1bf693945caf49a924072cbbb21838970324ef7c44537a67d90dfa64ad9048fdcd9cf15c7cf55af3155afbf69a498a3deef649022a61ab18ab3267c38707d732f479fbc7021038b52e0da50bfbeff9208eb6c09cd5931feed40a8ad8a6fb95fda48a911bcc1dff75e952c1c4f8d66cf7a6c1788de249b7c559c9584781ee0814b9af67205d76fb32df7dd1e6bcb11628aeb198fe307baf9db66158019ae9866263ab0b7bb301fcb36f5f78f7a70b14e8c75dd505bd204ab79519b563572b14f332f7b434733dd3dc06c968540585f07fb2533c6a4599940b92f0afc09afdd0f0e74c13368267ead2ef18b0f4c0799a6abe14c5fe16aa5c81e9189b66c8b2121e4b38422de375272e296bdca2c3632ce6e8558dc8dac44971fc55cbd9eeaa9d91f699ff664b0e8eb096cb007556afd783beb895d382aeefe1a6004f96f48cb0adb49a75612235a2ac318c9ae11e6261f2b90d975d866fcd1d7f330a44325f5ca0f792f3daf1035a5107b90bcf9907f9a3649ffaaf4a31b680184bb3f76899f834958625a91652485d84fe7567d667ba84e7d2c8bd3296a0d1b1f59975f92ed1c16e0e5cb83437a6b9d8c200ccc2e38e53d3ae037869e018958e6bb473d6a009f3c09714760bb2afddafbace214b8e119f0888f2c6b9343b9cc907633583a8495dc4178489e95dd68460b892c27c0897a2e6b2a9499515cc881673577683fbb28c8e7ed4fdaca6a58b8e98b78065c5a4b2b3414d144b17ba898b8c268afd0cd6e1c7543801a13b2218b75cd6ba9eda819bfedd4094c3ca7e439c1e9c4a8df0e6e3518115a3791d8bdc86bc712b613c7708d36f94cd95775334836f39bfe641ed8a4ac9d7e3c9642ba5ba766296154b6af09baff56b7da6c43c848b7518f445f87a31554c90054dbaf3a2fd1b1ffd91306a5888620b90838b7be589c9fa15055aba13b29e57f8b5dcd2dc7dee25d31bc977c05eb0012c261a5916cdd6b91ce7c7f3bc4662bf500d06374d59f0ee21f35cc04ca90ee4951350f2fad026ebaeae4ac28d36882b824e9341dbbbbf2b5406451c8b4eeb4defa8c572e9c83c6d60b98318369b5a2bc88af89dcc6120140f4c5caf432c67a6c51b2c47a3893f80776a6ee726300e5587bf3743d4372bc9e1e3a53bb583412297866c0174e4b81cb4d2363bd5a08355e3573118066eb549d9969205a61e8bd916be103481d0a8fbad57d13cfa057305b469b9ebaf78fcf2a333783956e2cb0e865fe4e9287eb5a608403b1353d389391b3ab57010bdb0838c2b21f8d7c1c063de9a27f4d600aa82737c805b0f0264cda08a3d315613f8741519e9dc16d7cdfab9816e2a639b5ec31cc7f66782f0e382dd1710be19610094c61230ab72f859ca4ace9a63e3dc1e101a95e206d832efbee6c3c1819da9d3a03c42100e309dee54b2d8817bcec51944a39aceb7ae0423f7f8fc7a55970defac02838dfbbc72f0a84869f3f177bde1e403784032e71dda78b484ec1eab5 +expected_shared_secret = 722fccef7142c46f74eb57a10b13e420d6554e9d18507f660bd1be96d3cebbcc + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = 05eb362461c4a2e81885084505c3862c3b647d181805205ef3e4ca5c30c46a0c21eb97700b70c2bee78d862b3e19dc1e0cec0ae6998a7b3c4fdac39a950027fb2a3bee027a8e54b4a5b981bba01badc0b5ba6a36a2913f1c1a046036960790ce2cf2583e6c62a778290f242b49606ecf24b3a0dc023b22ad8945a0b8dbccc9356475b36b2a990d7435b12e1536a21079fb7802b998488e690f763646c3b66adfbc8161855b20ea18afd87229d05e60372694e4c4c6215344da04173559d7954b029555e6ca4356f6cbe325a39431a64df06e75c63ed0e40bb0cba6ed68bc7211b02f1165c370ada1e0acf4ab61c87cc32f7017b4a26ff8cc0784f76047316af6398ddecc0c62e9a37fc4ca685017b33aacf597767312192cd330b2f3a84e0bb858480a63a607295a39f61510dc2c6998614013f45d319858da8228fe5bb6eaf3b03aa60f4b721a3f046d3088671930672c61c92d6005254372d8081be322ccead06cdd472cc5a481ee385096a5b8ce64b57781cbfc4457e917162da007bd7bad8e3803e05b08876842d9e6a0a545407a5067ede3510ccc4478c040310aaf46051454d855d1a5521e2514af676846650e0043bebf453e7488b6db8aaefcc16e26a75c52bc0ef3c80da3bb39f73b9852b54d9c606363438c45dac4ff1a1913d81b9a80544177ba7db6503a04a5405299f80a83fb7135fde04f8cecc0962461c0e80298d219531c9cbf00a3bb5b84908b5a807739a63485128512c0478084c8964f9064cd4514ce92c30454ac25b48919b719c5a853010a2eb712b80975660456562c4c448c39162ca63aed14af7f28875149857f9b8965bc1d04cb8ee2e67c14a493a3822fcd0a2dba2677e719b8f2c8bd09431b82ba56007584beeacaa1f081d244b0d771bdb0c8033b18ca9597443ff8cdf754569dcc2dc4d4c212e2bbee88925ce73034e19167cc7ac46059cd3b9ebbf6bc3a476f08438c61971af139a248821002480f42c2b9c0979ad3bc6868565ca3fcbc124a7548d53f56b51c9f8aa387b59b07638c7aa45704420b3c24642035a7884cb42f877260c29697809aa7482e3fc356d8ca061c1c443cf24c4535bdeccb02c3e3b8b1d90e5b47bd11615caf849da5811aa743b9bd7810c470187e81af9bdb4d1307303f615ace2a58e7ecb3be260e9f7c1e10eb3a84f207d2e75a30c7c741ea45fb04a9473c1425f80a9186a7f2625ea6abb4aaea3bb50602df23acf8e452cc01a909ec9034acb47b969d904213f0a79edb7766d0290005c954a1da0155f7318be854fdb038d019c1904b714f0514ac331c3813bd703b45076365be4b47ec510a9f585907bc0f461a6befe13a2667593e12134a86ac139777a50ccdad16b6891a0871621b387684b5226368400164b29109328f672cadadf7648377cd11c9232094165bb1cf12f694f940c3cd784c84925ba74c8a49dc27cda4c553c85334a860a8a55d8a75969977ad1f505b9b20ceeceb24a262c707843310f39434390ea5315a67491f0592bf722a1c2658c8a720991b26561e14b178c3a1028003cab8b69f60828f47b876d43d3f193c3820804068a5cae76dc3f27f5f1323e6a2797b9a13c86713a83ba9c161899cf295cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = pass +expected_ciphertext = f030991858a580b285c29e337892c953d068fedfdc83b1997d21c7cde737d0215a3629565b8b060f17033dd24a7c957bf76f490c814636e745689ec0582d17bae213f6986f88f9cff9fd86771b36320483b6dbb019ebbe8ca5642a4613d9fd3ebf436beea3590b08f411287b8a0a50a290621f0430364129c3ef1a5730cbb1ec741277965299bcb0b1097a9f9aeab4b4f1f392141897963f1f0f6768a763af9033c2d52988fdf794bafbd357cb19a101a11d0d35eff4039cc8142b834dc8e60c6d87304f5e1065cb982c5d1e5524d3f32b72fe65c42f8ba83be04f54a0d336fbb88a75e121a7a5a895e7a3c1ca80d70b2463b3b589fc35781cf2b8e917139a160522f88188bf92188eadd1c964cb5f2d3b14d0e1a1ad5bff6a0a5048d2b621458b1c088252b5410fa7bb8ba1d9187b90fdf216871382560943d7ffefb0274662982f83445c112a0015444415beb57bd1a6d282e097f0cd3cea94f92c761c54e7f4d3d27482cf2026d5e5bdee65ab969f8ed3d7861947bdd20a7b86b2116772168e5dee105c59cca176527e8762ceae54fc71bb2eb1301b0a3b5d77d26c4dd3326f5cd7dc535bd4e3846f3c4ca211c4e3e61dc276a0e6e1a5b278ad02762a2a6d48a6d06f73334ea229120a9a8ad71c6bef1beddb53478d1e2af606a955ad8d055f12e79b1733db11b67ee5599340e36cddd89d3cb6ec842dd39da1ae7b9b6943974dc24c497cde4263f56e6bc1dd309fe7c6a7905a6080a2dacf1c71d703c6e277c7661c7ee1f0e434a1241ae089444c31a971b141bc717bb10163af514547d7475191aae32d3adb8bcf0bc49f08b40b3860f2ba046ceef3e381675f803cdc9c4f1a0a4f8c1b5c06cad2465f6608ddc6f104494906e79faf03c3c48b89c613b016e7529e5e6494668cbc4092488c1238fba0993a81df3a3b46896a58a44848486429342f4c823c96de88c203c502df63fd6a58765a2ccf89dcdfc2b8e11cd8521c270ab50d3dc97e66a01aba506c713ac7550ca174b51efbe5c90fad46db5375f09ce999ee3ec2f30dbc5f5dcd04224827bee9fd94b56d4d5f0805300a3775c142e7a1e81905ba012c2e62000c9e2a6c2436cc919f46361c0287c56981d40c4d2c571dc7b566d189aabfb904c8177b52f525cfabcd37e22801e9025657245ee339a8f780d6103f2ebd613b7276308fb3eeb7869fe5a7038a0dca12abc39d0e6802317789514a610b265500855376207ebdf94423005af9724744fb94ce218c2c87e15107d71284157ccf6b6ed55d772b4efaaa4687f1c5a0da143ae00687c749a1e9a869cd356c04460868f581771a7e7da3674d221d074fc2d44edff15932008efbdf1ea5f6a023d1e7c67617701b6685f624448e4d2677638558997f0edd44c4ab4cb9a895044f00056c946e07936ed11aee915fe25038007ce395ed773bb281665b87920a7d9ecb49ed8e4a0d9aa277f7e19b5bcfaa45416a7437699ecad80b43e16948c2be55f69f99e7e849f84b92f45f556389008c1a3b89588ada52c7 +expected_shared_secret = ee7c5fb6a63ace944e1eae1bd4b182263d918754c33753b904853551b2b46cb8 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = 89c28969078e11664ca1554eca81b9542bae2ea8cc12b44e81b3354818141af0b494543d4674160a086f7e8755a87258e7e6a6aeb96955286924b42636e04583f74184133d8acb9067925f4969642f274085f70fc12361ff96c3130b143e23797f2a3a6cc757c97454cc8aa5d9c062f9254f4cc7335b44cb66dc712b4677c290ccbba08cfc3948c535be29f44736a23b4c8ccb3978404e419a08a67aa555becb48bcc161cbc5492b55e3498e74bb515c28a7a44a3afa0148ec3411d82a1ae103513074a13938a5fc17dfabad006d90455b4b5e45079d7bbe956c7a18a8bec9a64c1db72544cb00c6997d545ac7e3bc5c6565885536af486417e728cc99c78cfa12a1f7697f1ad26efeb7262800ac4e0121e766aa9bf0a74ae635074c62fb6ca79975761419b12a985ed7a2c8788c9020462fb5764c087681be1595a5ea4ee7234aa2d22f4119b559a536e0da0e8d0b2e493c2b5bd576459994acd684a81a0955684818e1b88e348446a22c9143a4eefc7d8ec678624763d4548fe2451f078582c93c986b0417e1aababdd76dc0532e252b59e47370e81951ef75ad48c223316a40237152e3508ec164c7375594f73b5f0483c560f52f250aaef28431e9d1b2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a7fc02eff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968aba093e8f42dd3c7cd68c8028a90cb0c93cb44d42ef9d15e6ca978ed5b88914c4e20768028f2c927a33433d33c5e6a45a6c5ae8c252a83e68ec121347b025865f26912b89a9da7472b75b9aba75581852b97d27ea7c9c5c7e8bebc0094c01947f43a2c6501c97e43231310167eccbc4c3a2022839584a12ad5b51b4cd308c94302e58c70eff7b24faa051cf548b5a73ab4254179eaa038ec95d4d4182d2971084cb33a6ca1106076dfa76ec0c4b3bb5c7266a481001cad07d12051a77e31603bf47c62dbf959c89774587111db1b038ae834e0a08c27f2b772a967179a9bada1ac12bcb8fd3b06ca44b3f11a6762ab51a9a0b67fb83def8c9a712a1469b719f2557e5a03c6bac808d0e0aa304955a3e961618920d0bc2347c74ad6725a9a855d1d8456d2c26addd849e59b7ce7c85765064ed6d63039e368e9f18d4fa11e16f8cc88bb3ffb40b4c6269996da8a6b5586365292b5b1c78bf4161c171e2fc7a6a8293a96d61d683275eafcadfed74473e30a1026809076a1025398b745be723a78e008c85b558d2b76392f5015d1024c171c0fc6c7c0c0e631bef57166e660269231c3216fb08b6cff0a420aa413ec1285b7b5ae9fbb15f9fa6b8af29ec061996a7612de524c7e0724766bb51e1264ab50c3a095815645b1d1021060b90c96555e8a001044d16cffd7719858065efca6c2654ea25506f0541fae242dbb154e420c0dd4e13a79053b431b7c00768bf0f781810a0832a2b814c5517aa1a0949523e12aa35893912256a7370bcd9faa30788b631b87731cc5c831a26e8f48ad7cf9c935301aa8cb006ac59fd2ea5bdc1736b2a5523ff3c4d8f429dc037292e863a087bb29cc2732ba30bf11490dbb1f3adb3448d6110a774b25d242602c250999ce69d1b32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = pass +expected_ciphertext = b053db98bcf8daca0c50a98c575bf2272f8f0c70343d5f78e97744c670f9d436142850638fe135a85d212ef2b4d2e23e8ba9a5d1327ac7a55454f9e1370861409b296ee2dfc6e7a4f1e5cef633489948173be158aa5192c6a9ff129e0b63b311f7595425aa29dfc758de1629be6d167fc58a65a4252863c5016042409da5227fc1c5334fa809235721f6f608a5443a67dbb33a1e5fa690cd34e9accadc99072a1db81386fd42257e1035b6fffe1a559b97fb71cab8e8e922aef2141733d39935d754e487656cb3b9b2bbb0a5a7c6bebaf62f86a407fdaf776e3a973074cdd2cebd67bb2305d67db831fee54826cfd8514be7117ac424548de1ec0628594062c97b570058bff7f0b38b25d57e953cb4a6d748828d56d643b1fd2068983d138e0f0bf67cbccf7a5ce79068eba43bc77d3abd7222ec5a22568874281ed644d5f3627156d35bd56da1e59fef74ce30a2185834df0f74d776f4c1661f6ca1343cd1149624b9bfeafc0e0084a3b68887cb44d51b7abc7f79886fe6966ee47144a78d12f99333a8a56e2a40110b7c505b6164b0a812590b4dd89d66583aed83348f27d88674a26440d423d1ead252edde582049f0f332afbcc54b4ec1ee81554dabcc8422dbedbe38f9c503722f3ca042ea0b51300d078ebb9663016bf61344f26d6bda836cfda3d06c3c1a2e8ec11ba197105b75942938117811cfb78afb5264f02d1c3a7b8cd72406ae08fad11966140a1ebf31cd5df8bd203453db15ace5e8f0a6ed9d36e1f98d55610e5c048c93c173f0bb47299e8c55bf2b2e1276ea90b22473e8f97a7bab2758087067da3dcec80749b66443e819964882f886bb9c232ef91ee1f57879eaff19f8c7472a8a709b3466801ccf756fb2ba6142ebdbf39643530879284ebfba338053479d78eaf70edbf439ec03f92c440aa15bd765d49ec0c580abf7690efd67068f20b5aa5537fd6a44dddebfa0f91bb6124c2bfdc3c6bb0eb6ea3015e202c6a5644c627963d172168c1b522bec3d6f7c83c02936fce8f3e774d91468c652e40c30ce4628927c44790f98c024860b07f758f1e09df4d6e3394d4dd1c0c5403c2c3a208ee3a2948985354929a90163a00e86b481bea2b4f14de01a0592a80695b5ae23996b1ddf4a712931612af6a6fc529f819b8361b3a8e98cd82fe92005b9c147f3bb4dc9d3155656575de568bc2199ba234bdff2ab277207d8615902229c48db3dcc589148d1b33b1d0594da5b27612a996d33b40ba2da0631471afabb3d155b2645958eac3bd6841dae38dc0adfa59b5e1aa809f888504448a56a3c822a613c998535c3aad312a41385a42dd691f7e9bea9dbe2cf0df32a86199a3fbd537aeea46e7c2768958912879115e2dcf76ab592cd3992036c83e2b2c562ad99cf42c9bba8b96aa54f01a4ced5769d22f51826b4217b2b47f721fc58d5ad5016ee4606b78e93194706332569a673425fe02bef35f942b9637c0f428a54f0bc190b6116aef98a2965181faf2f1d31a436e002ae9ef0f2a6bb912046ce +expected_shared_secret = 77cfbdae47854e9e10765cf397eca9ab2bf2b7522817152b22e18b6e09795016 + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 764b51d1dabf923518de898c5e7cb5e0066fd69522f5889dc05c41a472c983583333132052a1c93a464120b325764b8665ca42555b98d8d6a93c88a0a383ab51280f52873f2be26e12c131677027c616711d478342cb424b0463c88161ed84bf6e869abe9cb915d13534d2756dd72343359e9911624dc7c6e828b19d6cb178c43a5ceb9360d2939df2744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ec91e52c4030f5453e6bc9103b9c19cd83e69048272855b11b8af3edc09b04ab31179bee59abc76726fbe9612d271b7010844f62535f2f30d8417c35f17c1619b055fab6a0f5458568c753310299fcb335a7697e7cbc9b9eb1b14ac2d0ddb765b266b6d68bdb5b0236895328540b20f91bbd2910625e674b33a4f8b6c1b4f66c4130c2e973ab72d809282ca63edab71268c02a9d020bfc805410aae2dd4b699448a56049d1e9a58c5fc2abe159dec69c5027099a3b57d3a2560ce24a6f5017d32e00f3078b792309384421878cca555b7065d57537c804e10bac052788769b7c1121a78911a153fb56a365a2f97b070d7b61724d0c4d14c295d78be57a8aadb873d3af6b74d020b8654cf48543de8ca22371a48ded585b7073ecee0c44eec27c85b5a68f6b454b0cb10692039cc68ec2c2bf892804520c71be5b7badb807b4059a3d87d32548ba3e4b698ca150d784a8c2c35a67a8c92c68ac0037888b65a4c9800ba7a1ec050627af648fb61c87cc55b8243545aa514cbc550a8804c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6326e0bbd4402dbe26cec08a7c1a19457bc2677f15b984a74fbc52cdce48618d50c47400011b392908ac2cf08a579783a80fb2990cea90eee90b7dd81e6cc9c961372d8c720d7eb223d5a6a16d4571c1a93213b32289934f7b30a63527c6399920086940b7696503e623e63a050f4b69810b6e6f6729e5782b572221f596a09a1879bbb46a62a955043a30a2aa3e62e02ce1ab6f3d03693a8cb653e361d8783ffa37274ae06a3f2292f1a6557182006e493ff2653437a64dbea950bf6a8ca8836407fb489d42a6f6257770310f28715bc6411c81486cef3cb9ab500558f070f4a15817f8c177d63cafb176caf3b2b1cb7b7254c18fe15111fcab9e9a9682f41c9fd247ec532ccef514860a3fed330255323dafe46eed198041d732538c9424d43fe2f5481650470f08906791b2bfe65a445bb26ac87d9bd04aa648a54dc13a137b60e5c2779fe4b5a866620dc2829d42384aea9ab1552fca920f8929b7baa059dea53e6a5b3e492a6e45b5ae11f6ad24d035d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124a81ed4420c87b0601de23e3ccba915faad0c2b47ef6238dba9449274c64ccccd85e91712470e8f9a2866720059a8501c7762c0883cf9827bfd62bdc0882ee03b457be2b2794b8becf74ec0da4684282200a294c13c8a9ff376c1187911121bdd886f27514846f740b72aad5544cbd97a7e208635480acddf404fc067c82a45b5c97829f06abca5201429e9a516f66e65d07075cbc0c60c2a9734baadd68f421617fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = pass +expected_ciphertext = 4d372cbcf55aeaab39558fa7f1b3936da31e6679efee4b0af81d6b6e94e485e0f79a1a54dc8358ba0377a92eb5270b7b0cd814e464e2ee1ebba10ebdfaf6b53b5875a89fa0b0edadb5a60d815bea517523636fa18fe1780d152bb90d47d593409a2fdfa6b39c42214f709a86ddfa81bebd97ad6d18719d107dbc838111987d4f721746d75ceca8fd414f4055d206fec568c13d1ffc34ba1c243899bb5c16cfb6489c4cc018d39eb93873f520333d8cdef4fe3b9fcc117f291c2a2c1bb9febba997341404360213d9f5d7d80314fb059f57e12c884a4c42f6977b5bf3ebd6e0136da4065a91d9665cc141670e492beb0bf2d1fad2d536f2c0659a8d367c282fa5f117e0d4e0ac05610031e5624c61529b144995c155430063ca9a5e654bc84b1ecf790a635c3e5c3dbb1f980ae8b80c1b2ae9a48eee5a0f5e2aa0175eb19531a7ad6995a2d5a62dc236b596e9edc0c2da79aec60e5254c748ca80b90623f2309201ba88731d63794bb1865912866102fc732c88fc9c511d3a86648e8a5c59189941e694908ed80b513684b0cbba9ea16dee6cebf857b8d791175d623b3eece53235086b45b78fff9fe4b742803ceb85518009f5d94cae007e7cfe5cdfa2aa07d397aa97ac75b53b722c4d488ca391ec0c9f3ed196fc4326eb50b3efd27d0b34d9c9f200d7c74d0e30fc04022c331b55b0d7adfa777b0cce009786cfe71a020e33835012da068158102768cf441a078e5b9ffd6a6b1281f2c6159f114599d1096cc74a1980aa6ac45c8c4025067cd6e947c62a908be3a033367f1828e846fbc78bcf0be2d63a24ddf18336b8524c927a03ba76ce527b84a1358e3831a76e955a1b937e0ee2f006ab0d2dc886115c4fa6c9a7c831ebcde5b1aacbe33a82495349bfca371db6beb88e8ccbd8bee3585bae39a435c491292147e4e4833aa80ede11d1b98651e6d0525944106a454d76c3db9d74ecca42f52805037575420fda0ac6e6be3d798531ec283916e76159c79bb054ea23c24a41f124e1dc887e6b45babb35248f5c2ff7096a458acd6430f22eab1e5a6849fe783e612bbe435aaab7bf6efdb27220279e7021c75ceabc76422056a322afea422b17a8abfa6c3160ba885b3e54e70f3be0e304724cbe24d7b95359fc04642d3063d5191173a84f44f1e930c6c2346ab973ea722dee19f8d36065596e83d7e532505add1ad3ebbee0315d07a10c44f288a7c97ffcb03b829db5a01bca183ecd2dadd64bd2dd67aceeb0d34d039c3c4a2ab7a65c2d7479c2350663b754fd9e063bdf4ea73a04cf1cd0fa6782d46a9a834936f25baf39f0367a3e53298259a48cfc6d0c9ef767c30cd175dcbf92a559cae64cc9fd71eb630dbf78d9225e5cb216beea284440ac4497db0b095c094daed5d39695ae2360859bab3cb62673ef2ae5a1d03c4582764f2270644326a0c4143126de4d4600baf1ca099db5b562f33e9e35504496be65ba3e80f62ea820b8f11c91b64a53e6bd53ca5d62be0070762111804109bb8e1a594e5f536ecd8c +expected_shared_secret = 8be7a417efbdd3587c6f82ddd1d29956789d28c2413b8383590c5b80cc53e04a + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 5a1278bf11b37fbab1db212359473012f3b545301ddc833c69a75afe16744557b5e28bc0ee895da16c2c5dd34fe6783949d555e580c1be7994bb008daf27a47f554932b87222e82ec670490ca5139ff49d5ed896218825056a8639b31d3ac8550356a408a01404c6aa9c2b7284e7c7c27036256b7902445dde00630d81930f4ccc518b9efd8ab24fc16a365b8068c90f7e09bbd23c2a6ab12792d245551a9894f704042501c8fc49eeaa0132701e29a3c97834530a7c61f1b8440822cd1bb6b11dca2a5951b4deb0b1268c2f5aa8cf76a6bd0be3013a37ca1a903ac634405ecb3714bc54610baa63bacf0a263d8cb018b03b0a286083998a7e8b2a573e570179712130a19f9ebc2337d43926f9c96460996cc03199d81a0e19259da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f1f211c6d85499c46746bb00ba687a17877e6650c678d13861337faaa7045a16b8eb7173e7c08b6394b5f2b99ea3083ba175c55d350fd61b73aa790ca6f479fd4b01282b6baefa00a1946f6dfb855ce7bd50389d42856823301e01a228ac754cb65a0e323a0943b75741cb498cc499c8649b6bf87e991507194983aad1b57994b7d79bbcf2eb3b5f8734ccf3cea2662e95d486989144aea22c94c363571ac7dcd81f577645cf19b313f849b422afed963cdb701395020c2d18601a40a42429896aa9b0b1c10c4876928aeac59862414e143722a0b94746abd157343d15bb9fe500763b18c61b184407449b1b5ba8fb1554e4bb58ab99faaac9cdc3b698e64179b089b786204bf95eda86474ee799440478348989c91c3462446724340cd2376c682907edb58c85a4ce3ef46cc5d0ca345590ab14844b224735dc05e0e66ede94258f395fe867ab9d8c1b0fa80743002a15da197614295dc358f40758c9cc05e45bbc659b93ed611aa58845d94acc7aa75deba56d4d83c640c252975bc3165254c92957b78c9583b370ad785f2c16cd5cb9913839939c7293e6b956e23cc5d14cb3ab2a2e94f179bb076355157920085236f60b84449d43ac89c2b46dafa6b784438f3510bfc48357a5681043ba7428583bb5e912b08786562579df58a41bdb82114344b3ea3574b997f8564248210d4e50ab2277100b9a5423178b1f138e9d427762253cffc3cd095cb53a776f4fe015b5168b1a9759ac4acc77f90c69b307192b7b866753872a69813b1bcaab5cbb8126d8998e78d99f5a527992b89495a28e3fa83e75337ca2b896172ac244ab7e30761c8e3a00890046e5f599eeab65bf1a4cdeb5791cc10ade7197fb5bc754233f3b10c9ba2240adfc61c05231c36a6cf71aa752ab3c95c3756ef9373b677105d11f86e68036348bdd181f27407e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc4872617bdc17a7baa97af9a9322ff015956678e8d622cfb1a11ed929f29bb1f094c17f49417c09c1c443369123caf8701199c43bff97034efc6999424144c9395d9063bb153c0ed82b1c5659bfb23d4cd2c758a26b6c448525060f686bb14873cbf5046b3a3033c5c8081027bf5e3c51f6fb6a1d54a77c46b0ea4299a9da4ab03b95f9d3601f553d46800f661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = pass +expected_ciphertext = dee3cb7f92c8c7b79465a085e92d8061c7234ed5c76ea7548e220737a13fc67d46246d0331fc32d43b0094935c1e709f03f0d40d9f4fefd86aae871ad7bf783e8a8fdd6c690a71901970b882861591ff94792fd0bb16c04a6d5cacf617032f4efb3d032254cd04bc5b8b209c5a1eb3257bfb36e986dd6824ed046852b56f821e931973aff63ffcc586892c58e854705935c44f614dcaac0aff6b78a6aa36ee7914548c9c1413e8b90ab7bfdcde7c5d7c2619394e2dc8508346c187d051683299c041154c3e75939d94afdf3e76676d3acd2cb4de8bd4b6094249ce63155c87c561396dcc300c699e87422df2c8201196b4f320c422b6239e072f6a1ad5dd518298dd0ccaf2da7093a65272b3eddae908fb36e23c00a49d924787210ea21342e014dbf9a335b15c62cbc5c214d27c17a2b6d1c185d5bcd7cf15ebe4a8212e97ac11008ad0e645cc02ce0c7b313f672efc67776516959bec21b66c9a226d95c9dee529990fcbdc8df96b044998b3f1da1ed732e2301f180d0c419a8b95bc6584440bf4fe30b305023570eb91b16dd67c432b0f7dacf63722937bcb45655fe7445abf8ce2c946c03c4c5fe2274a7231df907a5900a3ee0f36bb2009eb4abba41d4f6c372ed7e825d99e0fba3ffef67cd52df38bd2a9588198d9be63cc980e909b978516a25e63302958e3328c10fb61375fa9c218b572b880b13966a8c483ee5967b22cf7dd7f8365e765c71e8f4bd57e70b17c8b79bf259d517826f2780adaf3b8e7774f3d9122809dea47ecb9118671e068b9c9a10cfda0b2a8f61349f0dcf623aabe70a5421427511e48c45e71553072909b8156722be3b301e421e8f9413fef0efb157845c54a593e0e7e37027b47508ba12a75f340a566a4b984226a086497cbf79dcab6611e0a684cf238d7e26c1114829b1e360de4bfe688f7405e5dd46dc3a31ae538d2177b17ec6393c1e973f69ddbfe3a465ab22fd2d2dc3035fe53983c807edceea2c7d157af345cd87c504983502c9d8b52fa86a7fbdb748cd94faa0734b6a0231a1dfa1a36447ae3a27ac1b9d39c0d65b7ea0d8c21ca23d491c7bd64c8c4495fc90247cb5e1a539657e8dda18dac206efc7cb8403d3f9223e800ff2c961321ec5ef918b6f2bf959121cdc940056d06d88910cf622fe70a5af489a069e58277305d9342c05f403ca9fa9df2a80d6dacbd00a6e622043c7f0038da2ca9b49e011bc73df548564e3f55ece3897bbdc95142857aef3f31296699671ade99deb866b55d738e23bfde2ca6d9c2f783d0f1246c3dec26ce19e4b176fbdabf19157a83d308a9e93f65c285c494f4d48b736fbad129c8ed1e12e5174cb49814e1b53ff6e1265e7ef6bd00c969c6a56bd34e4af851a40399a749c4c8f939c43bff06878c7dd80612b0c3cf6afe9c8392ff4ce10ea9ac601523e56f7610d23cacd60609bebfc37b9a063377439d307db2c14d19ea22f19141e80e994d988710045b536762773c12fc42da4f1f9506a38b9003d2eca9a4b971822ebd45bc52425e +expected_shared_secret = 79fcd201101e7e277c1b6cdc4475d63ea1dbc42ab94cf873bf0163c2aab0b5ff + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = c4a90087866b29244c3641310e94b8311a1303465975649288713e79ca67a9085c8f7449c0bb9a6ab196245b0da028cc1765a8ba0501d5e360cb3064e11554f3fc2914f1260509073b67b4a0570d7f708ca7c435ea987762f2a5a23cae53907fc9db26942136d72202d0a0bb10b65d422091abaa1c21d152dad59c25d20c016237634741def8ca26b9cce3097ffd896f1bf08300282fcb7000c7e1956673223902ae5b43bc63b6806c469a4ebb8bd34b057b375e725b07ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdcc12892d588d06655f6103e033547cf5933ec237b21b2956e5921cf10a0c55a70e4a24a57b93f6fcaab2a44bb079987eba57223b4b9deb60ec6464faa4058283b8cba6956c792ae8ff9184e93c2e2152823c15412c102518462c2691db1c64412eb1ec6d75d47c82fc5a9214670b3297067e30c6d9ce0cf3eb314cc1a4cf35342ae419513ec2bd47182c4ea52626a56f7831dbdc5719f532a5a421a7bd5a115c2195d0532e7c1c0ffe40166404137a5b45d7b2cd31752e1646588021508293fb881123f61034318700eeac429500905179b283162ed0b69590541eba0848decc94bd18c888170a4c030a89305fe97a2b0292390a3b1fd6aa22909cf0134a2754728b6fb5180276b7d65c2fd530b4ff48cc7c7093dfc2b418b97762c42bb0980c7f41d9651c69387173a6718038010f50b79b233187bc3a0f7c770e50abc62e8acbe297c58c58055387bc7711473d81ca97b6a6e6504870c0de1d806e3603ed0b04d01dc62529434014c5068c3ab3d4a909a079947127a8a2746cc8126f0212e21a0318ef273d5e0be16253848413c5cea22853c6e63b675cfac1d6590004a2bb3bb4974e79aca0dd927607a71d4b4c9980a86e5a2b5a84bcd2e694190491060411b332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d45f72d82ec24fb268537c07b81aa79b5b28ef5a657e0f8b6b2f3a4279abcf06ca2a79401312943d1d1086d91b1ad3030d0c0bb21806cb87b56ed391e6bc6aad974034664b4902336d6e45a7449cb656207d59367f2b142746636e44726f111603b28670f47113d28ce6bb11f464b181cb3205febc13cc70d3fb35924a641a1117df5cb65fd9a69c71bb800fc22a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ea920e4f2275f4f7bb361866647c04c573bf47e6b54cd31810c7814ab5cd27da1905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abaa2229c4c294e7a70f97bb6d119be54553eebab1c80c8da7459258e44a234357a1c9cc46412794116123d21db27455063672245460ebc8b6b1116b34f2401169ace16a514534154e798ae3155809b651ca963f854ba501407920765a14f826dcfa4bc4f21766b05bceac55e6854f1ad080d9b2538848a8dc7857f10c4c843c46b172adece3707e01c03059313bb96bb144996b127a16006db4063ca1251f550836e167adea545b3a0c55c0ac5de3fcab6e8242c2c5c09313646117a95ef46536dc74d869301335a2f9040484fb0c9cb85a3d034d55b03c66725d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = pass +expected_ciphertext = cb8021857be83d6c14856fa999c0296939540b44fa0973d41de5a98a7b8ef1bfafcb9b16885d777ac157f018f00899c739a8dea7feac36c5dc8402456f565488495f4c236456f7775424bfe331013dd60a242d436dc354b06f76a46e23f7ccf3cc398ca8b041f2591245a15452248d193474589b275e1a7f1a9ac3c7bb651bb17e5c4bc116d976dc447565a29497effea01ccb07220b45919790aa8be2f63dde259aef47f135456803471932046a51b0ca0a0b0418f989373d780f865f890ca055eb1bde17bcf131a956be72249d4155d35b2fd4ad28a59540d7334ec453e19561697797758c413829c46c9487a35024c67dd2bfc3cbfb2b35e556c1a271b6455ed7b9ad266a3b246ebbee224616f23cf9aa8ccfcbe019847ec34ede915970f2b7976446133c1862f961f4f059ffc9f722f6d267929819545a9fbeb6f03465339234e98cb6629aaa06a40d6159a94aec36f39b71bf0d3bb8ac93f9df0c8043e9f9cf17e78066a57c5d10d2d27dd9c0a8948275b14c82bbaf7d8451aaeaddc8eb2ee2c768d2d19d590c1be7af7ba30bee182b3de636125c9dcd80d4c64624d2c458cfa5f30fff16d99c97001404d6c64c5fa89bd225abd0a647fe92a0d004f270b7dc84a88e35892abd37a3321396815a63d1305a9dc7e495b592dd80046c82c13347395a6a92dfdbfd8fe1f7634b472f266e603209df3ba334bb0c68cdbd6d6724b32452938ea0dce4c3a6596638b0916865566586cebae4c0ee3ec36c782ebbb85e583c108436852d4545073774b2177de52f9610f7d778d7eb6d2382455965ab5b3ce9816d0995247945c31c9ff479587a9f60058d0867d5bd7ac12a3ad9dc581eaf7e4c5766829f7f8e2935bd1bc159b5e27f827c85bacb41f2ef5ff75666308c6a28765d6f2b261805bce28c6ed48cbe20a0945b31f59826be0742c711054a2623abecf9245fc34bf6c3b5e8f2f66114af277812c773f0470da69d10006e2dd44180713eef89307c3ce79a877ed3cf6f63acd681cff64647a3c08ff5a0c4fbf7c8a80b4bc3336948bffabd460dfd548c62e6167a24e841f13e1b0a868bc20e9ee55f9d89c44f58912cf23333a9b04e3bd813a0d2c61d0d087c9bc2783476dea746ebaa805de06eea87e7c50a20f1518bf6bcddf09f635bc1145932b4b323c4614882277130315ca6e5e3cce1f937de71e39505235f0ebd8e6482a2845ead61224bd8d84398d8816b31a0b178e95c0ba50f9757670e2d23df3475ebe38b6e53d8e95884fd60c38b3502a762f6ff5078188426a87c6502ac7251110f29e16bea769b1ba2bb27458dcaa225ee7e35397d3bd8c2b82401584b666fad035b2b99cc6d518ba1df7918464eba094d8297254c2e804aa06c00191af19acc9139728de08f19689a2507430b6e2597b1e5284815fb60273d80c48d2d4c934d813c0e1bbcc35b855e09ddae9f97111fa3d1f12cf449784012170e594f6e74d0646691a09a6f8956b815d9e3fa6265036ab2aca4ab450a62645155fa81ef4efa44682696 +expected_shared_secret = 6c4484b6d7b0a376f52abb1811c712368a9f34bd108ffe7ca31c36a6ec8140f3 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = e9718a491b3262d206be72a9ceb000e81b6be6668d14a124bb49be524abb09b91942a60ed38b1974e36376a7724ddc7e5a993ea9c25f40b80c766cc57e807bd5932603403458b84703ca58f8e57c451227128654df4537fce6a57bd1bd6fd8c5be1135b2c82cbfa4b96d577575406f92538034d22d6198a9cd000fc8dc8988f95608c1974c4359ada14f7dd4870c63bf79886ab2d4cad1c89a8fe232fc1c8c515b7d2aa9cc35759ef583244ea767916478f8415fdf7b1cf85a80f4d6960298b977a7abf380709ef904c1706ee3f51abf415028321e4fc79fb2e15454c47b3572bc09c62c0dc466efaa759f116e8ba4717f91220f125656ba7c52338ab1facb0fa6a75ce61f3135911d5714fcda7a5a271205547018cc0607c5aa7104a4a77266c0525579f054ecc6c62522068e79352ae7a1c3265413459939764a4421caa937c8f9b2b276a2c77ce7814fe9034783b8aec29881e2563a63780cbabbcbe72501d68f1b72c6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c9621bed149be06aa2e72f72d1b24b086836b525915b93a49d90cb3c45877c54204a605cc27f1828de6ca1e95056938a6c9651eb3b4a9b09c5aa9fc4401215d9ea9015a996f9a7b898cea466ca14f0065a5b1f374d422b4a277a011f3b3e8143b053507bee829e582528dcb3c9e950f39d17ad0a849c701779d070e34cc606c84a596650b7776a468659344446bc19186b43cbf042516a7b133065393c83b85313c53b71a5bc4421a91694beeb39760806d3b910aa8ea546f53763b656c99ea50a179986dc3786a554b819317fb58564dd69428bb1d7bc45a642a8ab9cc013f932a67222d1fd42b455930b8147d6175c66330217246c400c4b619b922182101b2d8165f93bee58757c14cbfc958552137b904009fcf845321841f8648b8f9e58d1572119b11cbcd59480246a46e255adcc1649817a052736ed9c18a262c36f7c37918db789ab177ed39add0850a509319888073b54bc3ed81000c780fc87ac5c302235a959b1164b491001b92811d4aa76876065e841b276a27b868822fd1da7c3fd1831d88c9f5d891ff610caf264fbc9280b8d4085251774ee20c23576ace6215b3eb8c1610ca2405115e89421418a7610c05bb526ffa39918e9558c6cb2618a612b6d38bf8a2569b4c3ae902a4ac744ed4bca8ed783c4eba450470aef5ec5370b87daa419145298170d64caafc2eda7c989645b9285a3fbd16c16e0c1e3fe085a6bc05248426ef106e7f6012e80882682660cd05ce49520785ea66325078f9a91e5ffc3ba0833de333326fecbcd8878f286064cd1b672f210133e30d106c61af9a75a7fc64fb5b1e1a1649fab356c0f26b9062c5dceaa7cee502c750a93187a21c11b1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee70253d77065c02926bfd9b031260b5af95846573ad09c42573c8338609fd3e5c0b50092b17a83128a4a9f1a6a232252884504846b3b7df82981dbb036f6a57c5c19136789af9690a978145ea6adb74132ec55840965083f388877a93fc01b006fe4cde4012a1814b327a12cca8991cd18027f4485b4025b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = pass +expected_ciphertext = db57de9e2cfc65b4ad9d944d6b8968d8ef73839c55b96a77ede1793f2b8ed9c8bfb6e3e711e0f947d7789c97960b9598ace9109d603c97474b5829a5729fcb19d2232f5f02ddd2c7b7bee5cdb042d2e255f986b3f6c16666a223e49b0316028bad8416082fd7e837f208ab21fe97d884d05b8bebf05c206006f6c94527398a204377051e15d2115a998faee7dfaf49be6dfd6e3288226106f25f2cd89c576dc74bce95538594b6a72e1a0f422d6f8c49c5a5eecff37d2ac8d86e94a65e6d95a1c421b83719b30cbc8a39fd82fb21ee981a2bf86dd6cb0a964b1fd408d086a86bb2fab39dab3bfa25137f7963e94ebc54dd93148316ef1c6b3b9f8d7af85264c7ff14b69cec63520b5d0e4476a693545c515252f879f7a68b4b2132aadbb212a4ed8c6ca154db4ca7299fce1d218bc95b4f058d77ab04989d918e712c266417d2e9b72b2a7c128f4b06d5131f92e2fe4285fd75412326d29bd9a1cd3efe33cdc3a5f1f404831fd7fee72facb4b37d42d33a7799df32122cf349ce0d64b8be5980d4cc140ec58bf0f52f304fa035cd6e0a9edaf54ff56c9d6aedfb61fb1c4aa597bb87298403fdb140be8fe124f9a2c8070719f1a16c58b2093c645319c137c1f53cfe9c267e00502a442918121c922cb6afb3befcc19321f067a2838a0d89ecf94ec88648a64218dd2f2fd2359b31fdbbe1a616daae89f736bd2e16f05828e70e4b9c0bc610041900a29a29ec5d7f3cbc0254442686eed9ff7aef4f42958dbc30b64352b7dfa97864122a889257a5f4ed365fb13fcafc4845080a8a4607c31eef8e8a3b49a0e4b4f6de1e1d01e871c87ca0a191f69b73c2e773b64912b86406786d4c90a8fa113e298871acfb77de35138e2f68cb2bf8b26fd7d464a02d2f1664d6df49dccdcf869a8f1adefcab1f1148bdbc97855a6ebc160394164663d04205828b711e62e8accde8c89f4fe02b2f1a6701e28a364d10bbbecfac9f113a3db495d2720e096db5562259900ff6a2c6a0be74e66012ac2e7360daae5dbd3ad6825dafc23491c732e6328f40e7af2cdb78eb88f91eee5c8163fbb3f7f4b8cb8671f0d6b0317432b4caf2b6a077a712d3cbc68157a2b340e01838fab5f22a28e432713a33b18556076681ea7f43f48cb0339d360cb6f47247220e23f313959c39cbca191b1911c9939aa541cd2d95c7a56338e09f846c4d38080100e82769ab86164bdfce24e68b6be20483d761981ddd4c963862fae0e9fedf619dd7a3e8e64561c1fc4c778ebae8741cec91a4d5161ca7f975716d2bbb4f50536f11710010aff928a03118e698e2cd20edeb34da6675ba04224cab7f5a25e1b1d9252971bd79d757362363c5491d3f2b2b0b95dff046b7168501e3a25ea58334bba7e1574bbe1c77fd4f66fa424313b095ab9dab5f810f818a9bcbf31edd63980ae89bdcea8306ef416124a06041e8a2459219fb863caa7a010843b4d41fc28abb73cd610208201e5a7ad693998b19946d05c563a8dd60e706ff5c237a17d875df0522c72fdd7a +expected_shared_secret = 8554d6af350f13471cfd45c23882e43dc81d8a094f6299e2ad33ef4c01a32058 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 14345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea81212eb91339aaa4bfa87a197a04d46a7b666837f55db6f16c095db449e9baa879ae14016ea4f8ba975da26cfcf59401237accb908efd17146e9439b1473bafa07703f2932d5c598276b59b419402d681d87111f70c20d2710e10a407634ab216907d7363af0bc4647dba208f9c6744d71a8a1c1a99082a3bd8a843e4ce581412f04877edb1709d1a9623c3c428eb111a1189073c9a3d34ad16aa1f1551a07e6880147360e60888ddd5b0956036951021af4699c96382cc0c16b3f0b960135391c6692b0c556a5b9ad2f8a5ed0cb0baea2406868ac6f7a5a44b722721535e098fe832c9af148ae027604c47ce4d3214a1bc974675289ac7bfb9a644db30235a664417c57a8a46a86e18a10f81b87f4b4727f7234017088f447f28680b0600ad1dd672f0ea19e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d0a2042c744555049c48b2bc2577738a698bc58910f55b0ede555b171838f6086ca365aed981aa5354561411990707bd3305cf4d10161fd3124156691daa5cf3795653e2aee1c4ba021b0edd0809b14905e46c2cd0bb1e165c8aa428b180ea394e6c92bd6873e12328e5e1916c94c81393172df3815127b937b9646a783524671fbd8b5f01395178c6a9ff42c47d8b25fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f27640fe59b1ef407110a317cd72023828192b131cb9af96899a69b0f51125b2828f29493a997a33023661bb7811c4593e4e579f8b17d0cbb6037d9273932af4eb235f7d01dd398b70752a925968adbf56cf132b85680abffb937c35425c244345e805bdb608cb0666984775ac1852690908cf2a60214f6a888004aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f52f10d4a852d38f5354981cdfb7a851a675c5a01c2fbe886192582d1f08ab37753bbd81ba6d848949731c99ba92278a2833cc11ac3bf603512bd6557f9684eb980c7588424db0c1e2bb2bd09196a7da29d79208da50c4a0c839284a44d8861706e991edd099e0b1467b88948c89778787c26dd4436fbc4bfd12b0acc00ab4d85b613bba4f928bbfcb04e2eaa51b81845c3a710bbc8458027a4f055061d0b39ad28482646aebc5458d0e70d396c99a0b456837376110488f49a83f48372327467ab87870d11b3c1e6c112ab3d6d486a99bc2b9b368a0695c6c6251d6bea5b56fcb96fc23475719b8cc82806875cad772e4716332ffb02189438e27097e565159e4b1790558273ca887fca2a6e7226c53879adbbc07ac1072e6aafdd2a1dd89677842041f33c447204a3fb91c1e4935111ac739cdc9fd6f2ba8c0c66dff5552f3b2bdfdb19d4f65cb3b23777292cf97cc54bfbc41ed041e53318386173d229b9288c5d68e87d0ce2032d481c46b646ef71940d97af370732533260c6ac943272866bb2bc90ec64424c67b1c877f5d2b35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866a52385c85c241677f75487d4156c85db639ad741e0412438bdbceb6092fa14501fe1c5e95d90833332debc0441554a8cb5a8f7826b047882b415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = pass +expected_ciphertext = 434defffdadd10d9567ff7de185a5081952e909d1a43b163483f8cbffb19f07b20cc3152c39709c3769e3152a3870edffc8dd78d5c9e26622d7b6c7aa341c60a5966b69c71265d8881fb94d9e13efb08d0a738b857cec7fdb63d016c025fb66e1cf8ba31961f56ac47871c7598b4cd2679fd7ca0ede0805c76a6f5564ce1bd748559f3db064e1da38f33cbe9c993c7cd1476472b4ca2075666380535d70176864275e438a543766ed89727cdaa4da0fcb36d948618a935ce49fce7148836b35d80f9885e82470f3ea9e321783047b136ab25f3cec80fa385f81722c0b02e924b7906ddabad71b8607353669aa8e3ab3826e895cc43b55aaccff387b7edfd035d39918738dfa7930b4dc7be3b3103552898c590ceebf0660db1b9d1fff96e339bd7845d6542418ce34208e662cf2c18104971673789c1c429aed0f0212868a808a5d6bd5152040285b8e7f5294df6db7129061c22e16595c57a45deca829ea1fefc4e9fe7d25a7bd5d17981bc9212eabb58a6ba17231753571f6f7f2e1efcca7b8e8db179a774da3d2994be50f8a32dc18bbcf606f73b1f72e5f36286ec13b576a013786b5af3621473719a2e069c0e59b1de69973ec0ab482a0d34c0bd4e815df2c36bf79c5e2bcb511043bc4e6802e7fdb358c5994537dd9a6e5535e281627a0a40576befe4d863e1b645585e0935f3cada9e64303effb1e5d8be5418db1fb76d1784aa7b56c2825f970e221e8c8d6b6f43e8b80f03acbedcc4224da3942016668fda692383178faa7328ca7aca8be1c4bc9ef50bcf209289eb47abd34402a7d1e21c9ff6871a3b7f603d77e08ef58853aa0db5789bca441c50ecf6b01726b8cca5656705fd2c670a8fbaac44be77fd6b60c863873dcba0b5d883667f37cdf979ca1a098cf05421ad841ae88d5c235141104b32c1075c5c9b03ee60a33415f3863e0894eb112046790ae65b8a6606c2a295f1d91e32dd37a42ce0fc5be9457fca8babe3bfe142c9abd48df57a848ca966930c1372e68e939e9b75e72d52d6a2babe0992720f3a3452176e13619ab4057a3141aa1fcc82ab50d470b31a9beffc5a57597de1415998a9e5806ea9bc5df191624432543d86c2ba247cb78ab4b6f73afbd5533041b30ac9e2a5c2221721330bbe258a84ef5e9d5a14645cdcded23af731bc9071c66a21c7dc36593173ac63d818965d835d572ca8f6562c048773321f2a546082f4f0bb479c32b5fd6008d417debd9ed9c36c15ac9ff3d990f89e5f26bec912103b5b3ced9193cee7712c6442463cf60c7e613d1215594a2086d3695db7a5f0ebd6bc953a2c388e4866a0c54770cdc3342986beb6591953bf6d0d7ec07b975d01076513d5cda1bcfeea1852ccdf15660a73585a254ef9df4199ec11c30d04935d299908aa92ac5c3a2a549ef139dd061f80f8330a92b52439bc512804b2bb75d1233f6ef04625db0e621f4d817489c34c90b99837eef09fae7484f801a97f21ce732e7f1352429e00420474936f73188eba2000465bd8961f393c87 +expected_shared_secret = f9646f73de3d93d8e5dc5beeaa65a30d8f3a1f8d6392190ee66ff28693fbadfa + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 8bd98be4597242c95c9641b194a093a928b8d3b30f33c10ba326943a8b704c09a6dfa55f700c488c38a3334716cceb6585008a853162e40a544c0a16878328f47c4e67b5aad276a2dec4c320047e2eab345cc14982b96d1d13566da409e93072377a1729546117a04ce291a2090b60030a35d5b360f9f871cad52f37e63954da0e0a8675abcc3717972f89469978730607293267cac89e3c96a98576c2351d8756429722a1278a173a75114baa4f0eec6a12b09cafdc99fee2c1af7acdae3c747b94b06517464f654adae25888a15cb4c5017076c9d3fac3b1560dd9112d88b2bcf31b15ac420fe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a972308c7b040d2fa32bfd1096503a3a0e84b9941188a6720e06e6641b896d365190369766995826b72122d780477581bd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0a423409c285d0e21bbca97be6707557bb0027e755f9a81912d04b9ebb374bd79411b2c283068670431f2de58d346bb525d192f128c9316742115275e9214def7a61da509b5848013b304216f783d77c3f57b76fb8dc984f05ab557709dae4691b519c44d41813e4b61e6664af5c970ae7a810714217745af087bb00575b18081921a854b7d953e29cb1de704e6578283292168ea73a03e2082b8b641c819649270011861a7b301dcef74e9b116a86f717e30ba6c5398e34390072e20c82f570fcfaa2bd8847a7187052e6b9d0d9bc9fec0217373bcc7b8d38245e40a1597077bb00a408e9eb2bb451c31a746d2aa07fd6432cf176382b6665d45343cf32731817023ee046577abc342bbe25416daee417f2971a8ed4c839126e996a8db40a55bd424c0e534cab677fa1c6b692d2b7e322a331305f75289a1ed102ed604722737e76501c7e7acc69842d6ffb2d31d1003c3b3bd8f4458d93b0270cba21db21a7d16e22e18584e68ea5b890ee839de75b68d60b25d5452bbb91658f3220aaab200ee7a8f070a5b5aa7fa30a768275970012324fe01910e8647945ae6f8b3a17d08e5c36af468a7f6308751c4141439b567eab03d72538ddf71debd2aec5db13537a2b0130b4c2f6662182bd08eb750eb681fce77981a3012102c45642bb8a44ad5cb27cda8369ec28190f64987eb600101aceae7a807158cc8100555a82644b3b513d7cb283a363c70a4ea090241c8a96ac562e7fb3c38f3515c3a68fecb271713729fb77a1a68695fcf995855749c1f0ae09f90741ec332e7602cadb69e55438b9d8ccc213119627410488145777907d280ddb7391d2ec9f27371277c266bb1b14f6eb8d46b2c8bccb0c68f3beb2d87b07044904d5b08e84305b0686f923985a49acdcb1a662d1a08948c9b8d95883518d0ad3933976c464a41c18351216d84066d71164a32d41886a153703c584b747555eefe8309f0810d49c0df8c5512b245f637c9448c47e1456995e922460b8210c7ac1063047c3764077288a1345c23ee0c8fa6865fdd52acb49614207285d241c14114db55cc0c92049f3537abff81b8a30a02e5ab013741b36d92191691b3197cce8d2328bbb6ff61932434899ae01412b231b0efa18d8381555866091c77981e753f8a2b95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = pass +expected_ciphertext = a07bccd6a1000b2d0f27be9021ff90c945731a7f45e8565550bd4196b7fd1b3fc4265aecf0714bec8fff9975ea86b40eed6befb80819936d437df6f83dd6d00d36692ea2c69ca0c93544e3ec86bbd6e24b12e7985e7bd89cbab9cc0167091270095529280eb6520545c07a7d76c99eb452e3fd596ac1c493e05aee285aeb22767bf7482feb0083147361198bab22b7a9b90051c42618443e621761a0e4bbf5444e23aaaa99ddd344dc738a81b1900e546d008c9e51c5a28da10309e35d40415b35fa9823364a0da0a5204a8c67e073128ebe2ae9f82dee1a91753ccdfce4247d9a3620545a8c4b5c5b1e55eecc4e9cd4338b912f5316f206ad53ba83adb62023c6d220fdcd573dfcfccff31616b50182a4f5fa42ac71b2ed506eb260f69b183d0dfb43f9e47fbfefbcc43d5704b7d4e303671dfebb03c83c79b3f7dfa0af964dcbc2edceef8821be9926ed353b9760c1d42552fbb8bc55d793a795bfd380e4616b3384bb6ac4c0dd9b73918c17a7b208138022a2835b5b0f1b8d79f186dbbf4a53300d70a18f3a0a8c3f3a8f57911d9958e5350d835bb4253b4c720675f81188480b62059d7af0935b81ca49313e49dbc2e5ace73cad23d8579218686ce283549e2f39b712dd7570aea5ebeb2fc0896501a39203769b41aa931876a2641f36136b82b53101e0868f000adcaa5157544fd010faa592cbef477f12149e0e45754bc25d66c0cf845cbc78b6bf3f52e6fdcf9e7932eb05f1eadd9e1a8d6640aaf34fc0da9cf0f64ae8398ea5ab0caad93648672d084d27a5e8f036b7390616df5a8536f1260ccbd3b8810f070149df4ba40ddc9633e7c1ac97da236c4269bda5b4a31cc39c5e1c1f2928ae140e67baee27fa30ff122fc431091558d52951b1041772439fe52a867df5c34a5d407249782a2ce947475a59d21463461a556f670801903a194cf4c55e7e2e570f89c93bbbd2e0ea1097c7d971b41c85a2fb20159b6271ce2a8feb0fcae0eb5f5c7ddf1482f6ccc35ebedacf47e67fc63581f79aecbb95d050edba235543e0c9f90a26572674f00b331226d1e00795d0323c331de978bad64cbeb8de9fbc2cecce265b7e8c85d0f334cace439e27f320cc8b475758e6fb4a1eda0021447ed963c8952c6635e6f3e5ad1372e3d4c6ea668434f5a00a9022dc3af451b0b0c8a4d9c705c9e837ada61d85eeaeaecc43f4cc3b0ba795dd712a943b09a5682a25f4a6089df5885c9a3a7e8789419753306134c46c3f6da5c68ffac355a4b8aa0a1708c7f5b66fa9f5c5cb3b4d9eea2ed038253124c3c14f572ac43fd6b817ca6211f0210a3d96e72e38cd415cfd525425536809b6d590b3da32a8c3e87c649896b1d81de6622cee43b5fa022e2bc6a378b4fa6f421f79ba8d6630afed853530d5f3b2d9341e6ce5b16da3c919f8bff21192fa4c3b0b4eb7187e453f0c3437c7407912902fb8d3a85584ec961fe7094d606719ccd89128f636119ed9ddcffbfe1d2c2296036d870fe0903b81446c6cc444bfd20548bdfe8007d4 +expected_shared_secret = 1ee252e97b69445f7f109187645cd2879f55e10eb8361ab43b3492ff51f01815 + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = a6bb3b93c181b651918a25235e22779cf052e1d30e6852557ca32aaf841834b423a9e61cc24b5231d7590f863e814aa19f123c0cba97cb3773740871ac23868731748355a85f03b275b3273486142153be4920bc9ee77ab5c05d2b96228906586ec831ebe8cf6f9bac3631b7cc904dfc768b1a717274b33f70d08b6a79c4aec3597e1c9664c9472b6c100c1601f27bc0aed37152e20b327b5d32646f2980bd780c8f476715ac04bf1e03c2d4a31da23b14dc0233c1a2c2d983627bbc845f023e349ca59626a99eeba5dcc12e8b82076ef2295238667308451c2052c6f9b127778a3c656213a23dc7e25660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b881b0365fe513fc661a03689581e045d2f921444c6a76e6344ed8a335b6681ccbc7b42b50b9b03558c64da65088f60b136882012135a8a659355503918ba25da1c167b9fb9f771b5727493c921338c1acccefa80201039d28c968aa3a40c2a28835f63bde23b9722a245ee3c859997f45e10a11f1906c1485b0b51093f51819963393a692ecdb1dda2c88a6133f69f401b124cad796217c818152a528f7d073bfcb9eaccc6cc8825ac4612533126c1ccc736db53f648201ff29a6c3f77b41e01de2087986f237200014e5fa540735513400004b5925cf64b0ffe9575e27ac19ac5644f355231bcdd70348c4507c80780f1d51abf6ac4c5e2957a94325a3f64e83a0a192516f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a723fe1a44fc97543f269f670c593935bdf87a52a1a31cd2b9ad92807407b5851b49eb1a2318611cacaa7710b6764a7e57f8962bc3fc483a8393640e602ca55526eb1be56f2c61ce802b9592f24c14aaa75aa4b002ac9b81fc1327b2a93aa889c9eb178bebdc91579ca7bd30796cc324447892558d2c052308946a451ca49816c06aad39603dd3841ef03ccc1075df164739feb342adcce87aa12f550200ce94765eb4f291a5152941b4eeaba91c3a59257c03017c0b7e0003b07657ba60b4256a8a4b205d7646813246385b348ec157dc6eb3be4546d7eb85c29512840018968743d2ce147f071c8f96c7436596337d69f5074485bf4a288833f2855787f8a18d874c5a2a41422157f65b62b5e581c2181a7023698fdc1ac60a8340a34b29f81b03dc35da2b453fa61293070b1c6db57f3040c3af7766c69b84d624dba1163feb0c71fab6582473f93c8753d67b0259a2eee1c847b1b8a73455a74fa10c3a4c21a35ad20fc36d563be9bc55350f565e4076670f0c77b3c4aa2a06f7bf2ad1bfc4fc8721618454d640189a6f8b3d6c71086dba68b213f4c51100a6037e717147893cdae20a97759204b2c684d8206fdcb10df575799aaa3de388cead4446dcba8e14368f7202520c71e453b41cce426be6c1e29ac475c45742ddacf7c520da15780a9056183900559129e5e3cbb3feaa288b25b6fc69bb8b164c1db8e24391172a8c23859545e98a13725130e45c3d1cbb5d6f5c0dc275608163916013e6e466c29502902c97d3bc33dd006abaaf2aacc40c046e55951d744e31887155a3fa880058a8767b35684445982767c697540ce339a0f4c29c2ae42b5dac5047c12c22bcc155a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = pass +expected_ciphertext = e3305af051f2b2d4d411b8846aea1fd866b2e9f2fb4c92c7d70a7c31515dcc9b9b5795d7c1716dee295b1b92703315bcf4a5506b70eecffa872a1c94585d978bf2b610a464499f36e58526a1ea99aadfd0f18ffa916134cdde7b857e72e8440c33de1187032280cb1b9cc7facd37abf84df7fb60b2bddf242dbbe89ba881d4b4a4bae19d706cd24d3dddf19e6619a0db6cfc5311c5f917dbc9eca99fdceb6f240144bca0697c2dc759446abf52f4a960afb3dab2a28c9922f29ad0c93a24b3f276138a980e7c6fe6d4dd349aa4254fa950ccf1ca5b177eb10c13a795ccbfb9b866b6c1d1a7b92e680728f45be3ba332d026820bf1f3b22ae9360d9a80ef9412194c1801838e2eb7467855bae54063ffb4a173796ee577769859812985ed1a0779a1b44b31bee787d6c894f475d1975bcc5b956201fa8029c1a50579893084874099c5d9ca37b33c24e08dfb45ad8c3533161feabf9290666218010de638757d46d8f36da00eb73f88d363382e3c99773c34f925d95da1486be5fa085e6670f34c6ad07453f21b3509bbd1eba6d16d2ca83b7942731a99766ae98f1a16df4a8d9a6c44d4c9c026f0232aa8219f37eaa2764945db0a57ce9700c3fa57849e8dc7848425b7538267b749c1474ca6f9ede161bdf7614f8384438250d13bd9fb3b86475de88bad4ba9cab85e94e3ee8c5f6a17867fae42353de0eb6807abb0180261ba13b5c28f3374427d9b70a49cafe4fe60ccd4264322f313173759383a3fbab05e002fce19a98ca8e8d112ef35fda07636fa8a23b4806497efba14e91608b92a737756d921ee5895c36aab80f5b863ce28ffac7fb55534a7643e27707c6caefeba5a60388f185e2477a66ee285dbba5ca77d79c4f7a10d40dd61e9e161f42d9c8674e3a5fb00dd22483466ef309474ad64850a13ab5e9bfef7df441adce7d678639fe4cdd49d58d23d722ec96127af9819e392f158a0b3d7f69e872349ed4eb81162529f8767a345d00e9588e8238d1fc25722ff23240202d7b1039b2b18eb14ae2da455be3851466ace03d27fafe35f5b676565c4a259634d24593efbbb13a9225f3233340cf8c3cc3504bb43158a57de9307554189d30936d5a9399aa71739074d5d487d7c69c3daaa10e40f6007668e76a7a3013bb6a7ca94cf668847996a7a496e839821cfa586254e21c3c04e3d40f730847b8aa60f4cb1e028899f4915114bec79d17501f8369c7c5b0a16cc0bdaf10a9dd18245ae33b55ab86391cb027a7129713cd130e7327639a7afca5f2d291b1f36069ff0b78979157c938619dfba02c24ca90486ce306d552d512e1a6fcf3f388647232fb0ad4feb4d3c9236e23a53962dd1118dbfe5f4ee1e47677db5f094c3bb3845dc7d9f7922ade82528e0d68a76b9608f3028100e5cfb2a989dd0690cf3bcbea5d1a827ac63a4f14992974e5fcf00981145d40c8d0a943dec836042ef5e859b9c6c12ff19ecd8957579b43ef7960952a020a571ffed0e37f7844cf37e0932f573134bf43ca169f09cd5e69 +expected_shared_secret = 1e1ea5d6a18873c5c7fc8da79093f6d3db5b28fdd0aaa42726ad130c78e9bb88 + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = 8452a77401c4e343bdcbdc985b70189ea976e3d65c47649593c9cfc112a4292238302253118cab8ec52060305392e6a131f0445a0bb4e11a1a8d7465e704b3134c3807d9be9f8b2abd57a00758685392592fa0b01e116410706a669a0ec5acb524d1561a265e307c24068b12897568490458121c572c2cc43b2464f2703212641202a40b27a41fafc4b24bea9f26711f28b1050645a38757708ad607ff6763f14c15a2caadfc2bc4d23c576e5cae6a20b10cc9cf610a5931ab4c59ecbe67ea079bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da3515288f933da602f1a2747a6856657b2102774bc1946163b534d02a1ce2e641cd9fc7f7d48b6f643ab53045bc690a249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4b414c223a52a6c88475405232c78ab3aae8861a45a817ebb16c3a3070b8e842527e965013244fe50907bac3883122393340b1e06728fa0400791b1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a58604599eb6d1d248a37ebcb17335713c4c9a0500fbf893df475cf7c19792fd56fe0a7505de0158f34603e0071b2aa0bdc8a12376a1313f571d33686d505660c4bace8ea40820918e05bc15b381b90d9b31bf52e1b18c422c3935d04140170542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472b409b1ec31ec887fd6e76ceec6812d40ba4469b3eeb028a0a6875a19b7aca51465cc3fe78566a3eb1b98c621eb3bbda4e7beb5f2344b64013ec233fb5714bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f7a228d28a5936968915d026cf683c762714830c1742ab4dff789f1f43782622a070a4ab52633efc52693b695dab939bc24944733905ae86801c4577324c625159b141c5a1014a6e458b71a959001839c461e17a3ac46da47ab687d2342ff63b83d3331510c98ac484f44b7fb6a31f6926cf047982c400008bb3b0d1ebba3cb2345613680531b0708a64b937c88b2985c01a10eea22fe5022912f9ad2bc667cea16b0a091f3fa9bbb9b8c30160717b21cef9d74458241beedc215d44900cf40709f6671f221d39c804eb6756c812364df0503355b8b01102574ac3f07234bbb1b658ea822d52a452545da3544c041c3a3f89ba30005a992b432178bfba078686a07971601f8b12c22b23b69c05a89adc2469287f052a6d4f58798e10a464db4aa71ab30a94854d1b8c16893b432a8dc2859c66a168c8c5ad4d04559056c4588b0a8755013e378545b47efbe90ca97552c9b8711d3281cc7b9057f78a68a59d5aa642d1e9233de093df5705d8639d702097f0dbc98451a46905ae72d876e1243546590599fc5923b37b4cf0a3f7cb47dfe8af00f6a999127a256681a5705bf5100d7096713c49149c7c561c0783e048cc3444776bf8997671970535c2cac5360c9b53e0d952af348a28e4826db9810f07110a48771c2c9b21da3ca719c7a5407b92020aaa0180b4d6b3ae42a1c09ca38fa59d1ed02a3a0079f2e922d0b36d9795c1fa42354ca51ddc11a315515a45bc7e1e21bcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = pass +expected_ciphertext = 9ec0cd62bc32489cf014d70757b26fb83b3bbb19bc0c216f48829326dcb00b90256a7a5c4929fe9aa669803594abda4d1daec5bc98176a0cf44d66619dc04ee086b7dee5ebfec9af3d77b775d88a0d458f2a3d5f7517a98ef5a1ccc287047250d7ccf20be0154833116bcc1974534f3336441fb7e2185c08c6c79a4cb12cff37f05473a508dfdca60d774b4bfc5a52f7338648a8b2e34382c7d909ec79c620f5af5d3458985ea89c1316ecb77eeba08a0b294744601d0ffa16608c76bcec186203028c1bd5d3c285052db30ee906a2183194b790f8fb6d7a74ff6dcd25909b93bee46af942cd43defc71c7a70cc64a146f43546d03ca0ad34d8dcc4528a8f65d3f69fdceca37d78359cbd76416ee442292b3430170fd589eb8bf278df46415c740d31624fab2b73e116ab8b01f61512de5727117818598470179de87f9fd007475eee6297fae76e20df24958782bcfd4b4c3ca2e80de164b41bbf304a31edeb81906b22f9572e4411985349e826f6f2c37d5668f93e6544dab78cf8d4787c1234a04a98e8120bdd2ec23cd69f2f2bc42877091cb42cc459d5ce7a88d19dbc6b52c9783e03931d726219cee1be57fc4c4032143a7855fe1df7df26cfd815f8f67942adaed372d13c55dd90278c3f3563233cc4441a261908cc81598f1ae3812a0c312a6860a35ec0c80173aa24d7ed55732ed793fea7fcec59b3b355102fb286029d448c3ef5a39ddfda82da997782e352b089724bd7e570ea6b2314e30a3b075e37c16e289afb3c2f0eca3577ff385b9faa733fcae2ae01d84fc685676494382cb25b14d41c0861a814eff00ed266e3c3d1f9e5f6a3b11923860ae71b0e139fa3c75a93bd9bfc4286e3d432ddef5a8de2d767cb0fedc1eb5e4742aadae6585dc8c726c8c8c38eac111a3a25e008045e11668bfb48f940a567f80d6f16e03ecd19e00ce59d1aaacf598df4ea754cede6157e5f62daca54f10e8172b92f0dac2183684dd07308a5236c480e3a6a5aaa174fc0cb166897641243b6401ed5cbc31180afd3f4fab3f9246812c5a5382e00ea1cd89d67ab1c3dc80bd52070f9654cb0f9b4c9f179aceb687396cced59ee20cfac6372aa759e9423f1bd96240741bf34af940079840229a120392c6e01a37bf5c24d026c4ddacf9c4a96364dd985ef98da55ca7780d2c75ae85ae08d462e54d2f0db2138e9e373bf65896dc2967ff481cd2b0f724f0086b932f728c201463fac0ab083d4440bd967d4929b7fa19c3a5f2f9b8ab237722d9930bb0f31b932c5538725def050e680bbe4b2f92067e739897d6d860a8087af3fd4faa34d09a9d0362edb5374ed988509ce4a61245eee1c1c531e5e72b977be3992caed8a441ef8ea849ffd4fc2efa3dc9f254d582389632b29718f638a6ae13ca506f117bdd204bdc2f1c07a182b1fe44e5b0a5ee3833b8611b0da300b28aec5d798aabae37a97b76a61af12cd82b017c2e2503e9b1c56311fe79e37af0b881106764fec52e0b1724f3b371a90f225bfb1080dee64f4d45d7 +expected_shared_secret = 24619bb17c912fc992bd8272969cd5b6fd6b030122ee5af9365cac8b38e569fc + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = a16730c3d8a8484295a1d995716a3bf93c7270671afb7886f397af65f5bac1b1a1a49084d1a672a1f98bca762287e90410ab01098c74869b42479c2cae5906ab354970c05cd256514f5c2e763230b6770884e7b700544977993df1f57969e0265fac4f474b76648b36f5711163638069820232b8a64f16bde83557b0540405d7987cc39069923dfa984ca4045999a77483e04fe6eb0be954a74c13cfcea79ed0d8124b01b740a26ed961b2bc496cbdc539a10b8151e0078f66751fe78d2f3a5100761c8beb514923a7b4f3ae208766fd852222dc31fc1a59a883c401459dc73468eb35af61d28ec1da147c882cc7f5ad5204bd8da270e4c91dc37baae1811cff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6896a288a9722183e199f608cd7a412ca949113e87a956e4ad12737d53c3be4752533bc755f7a1c4b07661e988210ac72131b4496941893a9c6f1180ba622436eeb02f3a3a090c00b1ffd310e811a7a8b87984d275d76b0f99abbfa45cc5096a1562a375f0599d9698b18012a84a0628601c731ce1ce6824907f1b16878a75418c2fb0751202fcc988779be2326e2e5228c9493a0e628441b13d58b3c79df34b7b53c7be816cc7368f2f31c380296250b33269158c4f9706d75b3b5536adfe5b0bcf514899287b4b637bb4249db25a0413533d628597ddd745a7f5270d136763e48a517ca62e116913350e7361580cf77bcdb5b607b38d49e1581654a61ad9602f4415f484bccbd833255a29d2e76262b401f7fa5a1e68bb136771c41b29333b653602b79a2aba21004e8a257df7362163b6512eda4e1376aba1facf04d1aa56c814000d718b5b504f1b9d2e627b8a678d0294c5e3b186a67c082b90abb1c839232912c39c3e02717a65e24a185a5d96e99851eb538a4ab872148c2d7bc52ec4270f708690d0678d43c783ca194b4aaeb6f2156297355d7823e0f80890608768c65073e04e7e5b45acbb1cb6446483e7c315a0a0c2066f080a53818a4ec0e4973f630f6822a437f6684fc9431f20a306a055f9906435172699b3cd0d46457be26560f692864a97f80b493093270b5225980287f1f5711b355f9ccc018d670ed8ba64f10ba98b0068e7714074e14736087819ec2cbc960fe6939a4e9a4de2045b53e81fbb845b0e546de6b34ee9e91ecf0c9f74c569dec949d3ea11785639126bbd45137021e9670735488e46a325342a2b4a959297816d1ac731cb501d628bc09083ab5c4dafc09a36c7c70f2885a6622bb7162aa2c999927a1fb749bae280237db21418e2cec419990288b813e80765b47e4c314171b849e570c7533cc5bb77cb9f10272926c382fc0796f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4da2d5264b282b32933d8c74242aa73c15875934e99d6c570572e03c54e47726e3b0416d3737a29624169778970e99de64bc2b16039ae97c7472a41c9a6c6fd45bd7738cb662505bb26a307a2cfb9680f5cac086f9bbf7799263c0b5367032196f1bd842534601094668a33bd339db59746d63ba6007887ab750f5887453e02b22c3148bf6c48c806a94cb7bf23568789a1260c87af0548c71881401c565268317756a211b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = pass +expected_ciphertext = 7c8e5f4f09ed554cbed6874d860af2b8fb97fc6de51e23a003338d67723b50616d0640c2e7e1492cd5251b0e4f442db191e500b3fb6d0fa76e6112f20eaf1e8f66e6634de166f2a67ace1d95366bc124129a016f6a4d669a643d9d90223b8a8829ca2314e88d76ce49a05e15121fb7116afe19dd38603e994f207e827135be71d62076b75453dcf6588b1a1c98ff2c517a4620f5d951cf06be81f28bbfcd08ff396e1a0894055bea6b7ef41a333df33e5c24cf30da5d78c5de7629cf8bf458255a3348f67127ad36d71641fc7a8bb9bf38c4706afd14e9de0fcc798c0fe35aea08343936f552a1dd7ca42d513c2896ad762fa4c0ab737d94f63330d47aecd1ea50a083f8660a797a9edb47ab2140748a610e981085f7dbe268e25e9b748dccfbdd9c312bb64f41a143a2a7f6e8d0bb7db83325747a414240e9316c2b4305940a42fbb9d5d7b3d0f593f63877d7461934a9a125d16673f288e828f17ffd75c0046564f092d47e99c59f51ce741d736cc26a35fec6d1c2ae909d6b4f4e635221139c9e6ea9f1b1135031ff694e3e12503e6315bd9abd54d0b4fbc9da7d48463e80ae57d3dfc1bbb468b206659f60772a2338f38b274ffc0d391a103e0a1a50833218d1165ea4e88f07782b1722fad72bc409feecbdf6a0bf99862af673488d3c39e9b343c35a5e6fa14b3c6893e727347bb965dbd9f8fd50b1ad0f23f7d3307f650ffdb5d8c085acdecc4c3ea7c52b1119175721f4a382b91c59c26220e40fdb57ba76f44238e1a77a062025daf823219ff117202f5f8ed2789b2b9e80bd98fcb4a4f42d006e299f190836b7e3f3a66e7ba13dadef54a2e5029bdb1d0f29318c3ad3013ce6793f5d4bf15c70cf79883b0fd455e9fb6bbaa0651d72596bf2392e38fa140cbe0f9e42f0beef0eee3263642a52f04f345c672560914e80ffa70b4f2700c8823a6c3352331690b54b3c20320a8a810f4c5f0a7eae739e343a93587846c4acdd4d93ec3e48e9c4e3728701ae9cfff5eb219cab6c50ce52ebe263bd54d29d4e785d80ee87cb4f064d2b38c3b2090329124ee0c74e4e7b7779769b14babd36396e1eeb8614b3af9f8867dc8f93c46376f8a5450a3761d6f4b7de3b4108c080e5e3c4c9628f160458774f0a1994f9ef5ba86933670c800a9f76866e38210a0e26650dcd110ad5f0f621e1c6cce1279e2c8ecfd4055d32d7b7a910eed993222cd2dc83dbfbba7d04e0121a849b545f646ed140e7afb1816982f1f2d8c6549f9d73148c5adeb3a30a9f3a459d3afbc552cb999bbdf104003955221fbdf7f6d06e9087e3c4ef49104ca51510c544b0abb048d1345c72d2c5e873555019487124998a67821f119ebf6ca973cec4e29bfb5704c92ebc7c742870e8de0f5811cff0107b168762d8051551133e3597ef4d56d50fa9333c0b5e6ace36ac36b0bac6ac16cec413f7e9d449f0ac9607b52f5a43f33921f3f226eac9eaa72ec17f0348b04a5191adb2e7571a4e1dfb11a1e2f731c124a6246d94bd253bd88296a9e60363 +expected_shared_secret = a990af801ddcf2009c82fe657fe3f068bae7e6bfc661e3e588354ba7d1b176e6 + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = ad735e9e838da63ac7a3e1cd3e574db17c2601d3927cc2a9d228a05f5c1e51a63634383ff5e03151f43c66a07be9e992aa65ca4ca17b1e021e06b261ccaa89b12a4916a5a4e39826a94c86bcba9fc7d65ff04549db70b300b1cb280b3a41e82b6c8b0a4a3c5e40eba59fd18f004ca3e4c15bedf22e099c99a3d114eb0c5988ba02873b9581107a23e54a8e51ae62375a887929f7333d4d763e23b20a246785e07700bb16c531692531433eb6a6594d1464bca7348022c1d4219cd8aa6614862c42376c3a0c4674181983f2a2ce8b7f32659ae87accab6023938592e188a3c1015e98720eacc9aa837a49c4617a850c89e1212478f3c6bba51c30a64a8a1c225274c92ea953872342a96ca3235ca7a9467be55250796126b30694f71b2f75b56d84ac89c4b635118145c7b8967de515ecc719e35804194b7ea9304636283cbf72339474ce1da00106110a596725574747dc07b3f0c7c527aca703cb23baa080bb7a4cfc1009b3e5aa89659121e365fd6cb6fd15afed70779a978b3ff50f915b6c16a350141721efd61085189c3265530c1a17491b317031b4e4667eb8314ad34cb7daa50566a9812377cf24076fc3dc748fd58865b1b02dbb831b25b7b7383579376fdaa6c8a5323230025a4bc66977f6a458374faeb14e47f70e654c42c94a5fc5e386a57abde3f29349623e4de92f900527c165870fcc26a2f95fa1850f2c940fb7b87686e253dd54b6706a84a0c70e3ab04ca8446efb77609e9815a261af5a135836064d44a485b5e850f10153653838e5874b76568516e847a2a9b186e8a50c34c2d2b0839ee58024211018b0a13fc781623cc313b30c26a258106941a66b3cd9481aca7c7e3ce3202f098746c42c58f4c7dbe52fb5f606fbf31b9b5022e691cbef1464f6942aa503147eba081817ae28581ecdd867a96195db320bd2d91c36db01ade9affb6b00f86c13e2e252c988300b05afcd007470cc3022e96af0768dbebbcf62b53345b213c1544491f1bc75ba96bd73be57a2cd6874511b44bf2dd27f4fc87c167815fec59f7a043f699ba4d23400886a7214160c23dc96056bbcc7007a0049435c534b66971e6e5c90effa6645c45031c0c905b9887700181565b53165bab605a51bcaca0dd0c308a46432794c38f21e04172005f4348211c63a40cffd7c32bcd57fde852fec793cb7013e74504721f6bfb7637f73319f75b08e3c25777c969c6ea000c9b79d6f16a00cc4b00ad7ca4f8704b2e54d9d27524f6b80a6d51f85447b22c29af0036c6ba486862c8b4fb03f26042a0e195a3e91bc303770ac844e77805e41ec6aca920ff3a1a3abe81b598c193723b20c8685590131da89c0ace08a592489791911c92c7e6ed55f642caf918173f190b2fb8cc0cb2139fb6caa259b5a4634cfd0a532b719903e32831489a2d390b4c5a5066b4ab5a3316441b162407096a0bc0342599804752fd4f21c45923705a7a04012ae4a900c01d584f9f41676c36681994c2f4037bdfb84a69a81fa561e5be05777b571922988eac714ff249926fc9cc4e93666e198308a434df74dff3c5a440948437a7c500582124574ae225f52d322d0909b5e946a5e22ac8f774f69c48b7874417bb1c0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = pass +expected_ciphertext = 22f3f2214b8b2b7fdeaab34d714c6c4a7c474464bf0229c2c7f31b323f65f220adf521118a41218c92f737c2e8bb753d6e19649e5fcba1f5c821a7d5603c84400015986d669ef0847ca0117f03ad3ce2928f3b88d079ad95ad6396afbeb8146131bf4d822dc4dfac100f23fb329e23f3123fc4bd0605903dd911a6f9c092259a167445caab38943790b7556469cf37c07f06d604906d4d10af9370dbd8a2e45ab870063ddf1b3f24fac5c7b5b348bc6281dea95547c84641f697ced7b000334493c35df845a12a1cc3d61efaf5a84738c2279128485759c838993d7204706ec6487010e6935d71319ed2dadfcaaae323aefdb7fc4ec8f121ad6a3bf1f31afe622bcbe17ade7db20eb98ab81a5fd91cd22fcba60176084ad5a51aa5c786650fb0eae9dfe79f74e919961e018f1718ac031e46fc3601a6ac4f83d3cedc66225a1bd7879217df9b8fc3dd0be1b9992d0bf7c8b84854d0d9bb82813f3dd74a5b7f38d174d67a00743c4bec322d6fca86ddba4fbb199c5d1a257b5e94b3b1f3a5d8a3b1fcfc4fa56eabc48520a2db9291885d912173ae0bb798b9b5ff15298cd87689964a5ac8283b4d5fd11444ded04b8abbc91727140c93acc3c817cc66176ce64c4b7e5cf3d5063050d28ae924103b0cccdf116d72df01d2b492524aedda5522dfc54bc83912d18b984f7b3e5d5b1bee11e352b44f04f3ca3906cdfd4a08324008665d712ae8ea746cd4dde1c70f4f4299a22ecd16d17d5f66f1060311a378e7b8d7e20d1d7548bd902ba9f4559d5f870d587cfb4a2f39d41743e7610861d24e8703ca8575228ae41a88d3f7d5cc496694873e5fac388cf3c42655cb521d4680ff42a12a6e1f9e4f6685c2a7e786c1ef26fd6be01bfc37ad8618bd799bad70fcc502d9fe543d91b47e10a58a1787a2caac3cb38ca418323ca97a1c0d4427fe31ebaa4d548ffd41e696a541eac93baa53219944510c4b8a891d930d656e66da78d5ee1518fffbce85cc31072f234a0584c97a193737f6044a2ddaaccefffda4ad055f01551cecd853bba68d85f24037d8e34cebb8d625c80b5602a3c6080a393255829f94dca02f7c6f31a674cf37307dc5eb649249236cd8f44281d6becf64f9d301dc2b624c6c0a7ff0cb38461510199b83b42d716c5fd6cfbc0c571bb07620ead1f72ed1960c97d76d51805a48bf594357bfb08a57c504983d1cd8ecef8a6e5cccf0abdea45abf78c044f1dfddf5a884ec3182c3884df3c1e271408712f1d55be61b80e9d4f64fe5f3a4506d85875a59908ce0223e40c775ebb258c0cc9169ed8dae85266a7f191c5729d867fc8d6185798a1bd4a6e9f7594eaafd61a925ce5b18f7e07885bb2d37704a544dcb9152d1822c5ba449fe71c499b46a6590aa8adcdc3be9d5c0a94066a53fc682f5d01800d5b7240f2188600a7f1099e2d42d9dbf4e2831c0e046692548918212ce5d52808c6556ace187ba18e0ff1bf27ef6425ac18ff437de794d546334f940fa5f545128aac740fa0fd0a44888346a70f0bb9c +expected_shared_secret = 11a2ceaa0c77f0602c4b2be3499e6df6b0339d9de90d04b2b12829f4758afaa5 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = e0b9190b548bc164bb826874c1800980dab529866b951c01c20cb4ad363c681336b13105fc338b1788afbff321bd981974c33d98a35666eaabe3612e61839d6ad65490d71ae992111719aacf12a060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b0731621cc04e6e2061e93cc4b51209ec92abb303bc638c52ab2ae40d746cfcc43b7576a240540bf410c14744f80a442d0555d474192bcd9b187a56691b63965973c7793668682852f91cfbce70d6d4832a1855cc4b83a847734c24019c508b2d29539fd1a114f787285e197b51bc092f80b559446f1076f02e984a1b27cae7aa1d0b50967939aac74cf2335ad421021e3225d94fa3b09148e60c20e8454c68a8022043206b7bb1e799c9b69286509a188db29a9ebb078420a0844c858cf4b11f9b4959934002be0229e714350451b9c2775a5cc8c45b07e121290eee32a73d46f8d7c55311a8c29027356139f153cb405fa14064c5c31060d7a964b33d76bcd4809d21b34a2f7806486bd2835b7f871164ae496d4264f89fb4eb15b7e5a7232b6c68b11351a41b09bb0c92c8437534d2b4c0ca2538023b29df93d93c98136780ff6f82846cc2868664322ab28dcd7279f68994ba5a5ed406d4d717d16c14dfdda58db1524f7c53f3cb170d45a411b07cd64f001daa0ad1bf63a11550c0c154d20f5096db44d1ab0a1c9d66581891a9314c18f778330a0936e7a2f3e19c18f7bc87cf078627770dfc5a2fe71b27eb8276863c3295c11e08703ef4a4ff6b3a1871c7b42c43a6eeb6bd1526aa95b7dcd6b38edc207c630bed1768ce9505544e9053e5c8cbf6a181a1a0f48c8a98b59c3adebcc3a5c99e61588834024cfc71c9dfab1df558711b311404a739f79b45b1a8a7633081a27a08c3c16478c9d24c1229723addcea225d39bde7851345b18b1b08254181b01623347a9a57f5d902290b10476083949556663309059815626c3ccb5302b978b2ce82af231934ffc7732352b990b21b69210f2acc048387b95c346974c2181148078154416e08564d664db3045dba82c9a7934de51ab5c1d7346a391baca48209c8c7235309943c1cb9cab4771c7eaf59321b510d430c88473ab16f54ae461a5dc613c6fec61a5e899552e835eff57fc34b7992755d178a0365c52b3f020ab40020ce21b45717654634606dfb2917fcc266193e2e5b2c4559cc5652aad1121cca0711e26c23eb33c1f7d389f2d742f384725d3268f8159f8c463585998289e58369fbb883caae21b87139e52d7ebb92b011cbe6426390458247c45f06f2519ab35b35675bf93325351617ad3ac470f73d3d3985e10277a647c96a6c56cc2346563cc496db232fd742aea3adcfbc506ca8cbada7b040a04f6e329fcea77bec0683e1a87c396113639159d9ca52a5a5484d2839869a2e80557a6bf7ce2ee295a464aaf835c542457d021c65c2b2a457c771fcc47f8b1056c8b7aa61d1843a40c4c9b083269b2e89fa3ba5959f89972805fa4b46e35abef0c57d875c54804de77071f1219195bc8b4f7c18a19a7953573e7f4157ca03be2852461a784e736110157ba3f83a6947aaa09e9bcae730b9b212bb837627293a485ed6b42ca1cf26792676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = pass +expected_ciphertext = ef721977b01338d0f77a3f31f04fb6dd98be2448a7d73e426cbbc87c9eb56ec0a36df6d71a95516b8a6880c9a722ed440407108a41d0dd34893d2a6f243a28d8ca9920ed831315fa207f059c0841e6d2d7f9c5311ac5bfd74a36e81c9da718a87d208c2eb4f1c83676216178022a27a04ef6343e958f206d22a27f565907cf39d521f5d0b4f7025f37c228ec396139233c4f56abc399818001ea2c10a15b4b46bb348df15c2da0ff6ff9851336ac936804a27455449d21822090e6a8962420e742a7ba41f058aab77556bc2be4a59fd6588246b539b003f90efac50784e13814336c4b06838dbba07f6eb287b850b05c9e4f7542ba1412c9e7ef5af7f8cc8f7d3699f9b32db4623357a24e3557bb63612a2705aae3132be9c6a1c143fb52d0d87530654f1c890d40a645df8538a707b35d173259dbbbca97c4f5ab88c047936ac72eeaf415d1e5f8d27817a45a137d66e6c25b0e6b2791f65063166042b4e750d6c445a4b5830c9c2c3ee8a879f1685f8aa7deeb693df158a6f2998560502b3882839c1508cb1611af1966f62bfe50b1554e4f0d70cca0eec02c0d295cba03eeea812a031757af2a147925daceb64f7c0a4bdf728a6536012c2e80b486a3ea82c7ebd7b97005aca5bb3e890a9515d5942de00ea502ef13d620b832c7a57fba93ec30b259512c666e3d325922394c1b4fdfdb1cb24fa6fffe747dff802d277370a97f4d0b7fd78a176a6758bdbb6cc88f1ee95639bcd9dd69f56b45e1c8faf26e205563481860e5c3e999354f38c4a34b56f8ae19848e53e1d319b3dcee667a5495a47b9fb79aa137787d2e1d51784ce0b90e8d6040d8da5b9ff736b22c1eaf1da117b258b5151239543330e33e6a61e821abc31352b41032fd51690bcc65b95280ac5cf1bb146d2cf364e1c83e654407bbd3391d68cc494c93da50e360176c3caee6e96e334a868d6ca8a0873c7a4e300dee289496c71f6d2c81ebe9895afabb3a274f8067035ee602152ecad5fa1597a3fb5e356233c63fc9e339a17204ca879e084bbcc4eb9079d7e41154cbd974231cc5a74f1711109dd06a1611f593e0ed4be5e5f2ad8619e16e424e249e3f3d7af016785582db7d228f7139649d2de795b264a65554f55d4621517262595f5170cfc96176e397e84e247cabe61bf60564a3ddd3c782bb428de86962f1b7510d136013a7dcd72a464180f59e23772843a012d03ab5d38dbf96d424fa371c28e7db3cc123304dc65026fef804d6a24c55ba5ad15b3bda23ee7e61fc2555969d87131a15f29ed7a5abc5e715126a6590e9c1960e8bcf9ab46988e0f3f2d58d5a6dec84aba81731e02d7a862350f8c54d48a5477474a1fd7d58dffeb3c2485ccf956c20dc9e0547454c973d6ed72bae9afe2ad4e8775e5a57f6663fb464077cb812268571672ca5d1a3b49fbf56db19cf7289820538a4c426f1601abcec6db5893a394b8b2f99382948738656dbff1a5c8fde40e29ef40a84a6dbcc4f184842fff1bac63275a3127435e0eb400e204e9fb45c +expected_shared_secret = 7571990ef1ef7e15cc920318fb75fd38c4ceb9abf7a4b1adc2175f99d1a0a275 + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = f1390e49f3b488ac39d0e43292b70042c52355eb48b841887ea256055a688fcac5a71c896414ce75f57bba12967215c50d4b5be692b6dcd1ad2190a3d785c19e283f87f784a03c8f52a23e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d062ee1ab3922a2c9b5b02d14557164149c62e8029b139e6950b3f8acc9e8c30274b69926c1658f7836f479c8cc70138b829848c7698b179643b7550e9193d6fa87350503c2b69136b08cc298b5c335b1ab95054d13c9260625e34c6c2fb8186e1916c137ad9907c8b2ac9d88faaaa0375236751a47918f96477b7ec01819f8ae1d72951e21608c87532a9428bdf4cb5658440cb025ce3b271652961bd935624b9eb70047e63184b9503adcd057b6744fe42908cfa325e401b9d0db5ada201f5d64350d392c4fb842823895e15720dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa3917130308f2a2aca964790baf960aa12de3334d146e64db81ef09563c9667381424c809441ee989eec93597e7c5b558a89dfaa976f6934cd18b8eacb6f2f54e8f748e4bdb69b0764fd59352575066dc242dc0f1356fab4467c8064fd23f8823148b77a4acc642eb2c181fd5ca251b323561191cb15f2ff0784900a15f67014b518453c4c3663528ffb53271e195c27533fec8c3b159ac1bf39c6fdc69dd5a5fe5872ffb6b2271a09966a5c738c48e63e141d65315051610f0f5588ac97f14100027b144aa23774f199d0d9a122953aca8782a4136820ffbcc1f2692bb919b674aa1f4d679e8418e8597c74d60c5c287cde6d44492411222636b03cb661ad66fb442193690a5f1d6b80a947442a46bdd239fe3989e6da86949474e395056a5e6cb42b25343a7c73b650d843527444243852518a9034b9efa7a6bb8505bf605ec238ffbc08cbee35a94845d7319144b381819d0928c27023b727656ea843140649c03098fe74c717aabe91948ea7698db0a86d34296b5e50dc0a9949c8ba07f64ce60da2b6e62458da229d52c08b9b696a124a8cbb791c0d255d3e4a69ed2c242000dc6476b4555552deab63ec19fe8783151daaf78e561e1844886d4418e7510bd025299b1c83c7ba22f63335b9823043336da897a44fc6a28b44c68a49b436b0dfa406be642a5bd303bb0d633685364d80440cd7189b6b34f6535101979ba9d251474fc91bf2497670bad0da78ab3c13eeaac864572a2f919546a57c719bcabc9dc8215b492d53118c2d379e879234a700638370a530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d8891b4904b8f5db93d0531caff25be53e28c45c94758e309b83abc2ba66d98d3bdbc53b7d06592f2712663c777db60aff496a217e82d8272c3a218ad8c8b04ae7c66be35c08e3a955fbc18edd07e8e68a806fc3fe218b87f87bc332b86c2625d8ff01c9ff6214b75a20cc465f847511030b47ea664a75b3d4ed9038a9c747c6872de0a57f3b76c60585ade64570a21cf8548a5be4996bc22b3d16a7bbbd20149034764b820892b9394581697e39f9b35077eaaadb06702968a5e5418983110a97d4749d3160ddb2b9c587767fb56b9ed9bb3d91cbeae141769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = pass +expected_ciphertext = 011f7beb6c4be8f266d9d6baeb2d0ad7c3f7a4257b770a8cfe675d00d80fe92975ede583a59727628ca1064987718fdcf8f8269a371accd47560caa9daa1cd606b258b1532eb341b47963281d843462e822406a41681bbdd81247255b4ce037514695a4a596ad23b493cd368897e94c654a69b102e4aed52efe1ca2407222ea5874a4366f3fb804b9d482ebe6ba777b9d79701dd04becdd10acd05b0b4281e6db009188cc9a0e263232f233091af61005f8258f05e638f7d779346f59555827b92b190829003f42156dd0da2f43a3ab17731f2e15f7207b11f4ec0dd6ad56cdd5b5a2066d1788cfb060317cf36b90ccbcf0014efffdf291606b615488a762240733fb52e0fae719f434414e245eb8e7ce84ee0a35ed39925b233a219d60458c4434243e6575b2a654c4c6dd8bee20302b442201d846261f1476098459d9c2f548a097dc4043e8403ec21f6df98a2f1020a09e7609dba49a5df6e91fbc705a09d39558d7b12ac4092c96de40c18cf4e0d2e0aa575716ef57165d38f8fab47e40b914d75e5f4dd65fd99eaf77296fc742ce9e52728297729f9ccaf0e58f15726b6b664b3998f3eae5db3803da3a98c11149ca1c7c1dcec42f6b2be604134b381e4ecb044be5b1aa0a912e71f59d56f3d011ab99d3defdc09c345591c79295a528341ca533af543a5777a5a5df06527cb961a28075491da67334ca67f7ac1f8b26855ad3b8e05291fe9d401a6d6ef19d3e915235aa3de6556b7fee9c7faae019bcd21f54a137ba08d305ded214c208f197ab65123f58068d9b770f79ee0f022c85a5e18c0f99d96ea57e3df44475746c3bf59ccc5040b88da34c1ab7e477cefb479377844988d1737e56b52e95b02ada15df5125b6a380cdda6331ac4afb8285638465b6231169523096b49b0d13bbfeb905483893f5aec46d003fcb37165dba2dc96cbe7c269eebebf8f437992dbf4dffc7b69f202580b84184ece0ee39b6e6b782e33e40add26469687b05b06a02633316b8b1bc251aad358327f998dce5a95e7bdc5c4ed526854d5f44b2e1c6403fdfe2091f9e31cf706c18cd02d1a019cfd88d7a9429d81405c1be11d57582ea371b80dc19e89a030982177e3781ce086ea0d633f09e11ee5708d90e37e8c68eaa4a419e2fa01b07ba6c2bedcf57b03e740da6df1479e3dce41a7a1b587b918851b98efc67218c19d2cb71a04961ebd147d247d9834cd8c976d42b7658ebe82194d823865cc5cf1125b0768de6f33c8aaacf45ab11379ff8d920e1f1addf6e570c3a550f8ffeadcdc0d9c8174f2cf3c3fe70f17808f25c49eea9ae043208bdf9d5bb61dffc86adf687fb60bf3f8eb289e22125ab0027383fa2fb04495a9f70c66fe5fdcf1bedf9f9b7b52d6b3f9f39db14572e707a15793d06fbaad499ea36505777455420acc090d2fbd3bea249c225403a6e9c80b1cb49d91926a9acd9c66388386ab198421f2b51a04d914738026e009b022f1d4d513d44116bb293e317e22afe91381d64629145a2aca70d4b507c8fd1a +expected_shared_secret = 27ba4cb50ae44cd938585e0a4905d76053dd851e5b6af4fd787446079aa5a4ab + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 2d7b0180596be297a4631abe0d48a046dcc99c8912b8255fc45592a2a61230652bc7c450a674ccc3abb27395738d177e7579afdcc30e74e7c7b5ac5dc235176343cfc4920ed8d9472e13c9b36a6d38bb44756bc31fbab62893656da065901303700a14b2f785d98896ae97953ba358fd53091012b97498cd7516b0e1898e2f6803c5a13d70f5bec346917249940ba35e3ea954f6ca13c343a09cfc02d8e66852c1ae0ff8b22e7424f53b1897ea11268a6b866c09efe8694031754ed1a2a147c0086283284133aa6c324e0b0570469f09e0901f25213ff9b113147990b54cb241268e0b6c7a3a90c638b7c483c71ac1344bd65c988736c4756e0b71111bf5b810fb3cc4187363a94efa020de1c3cb9a005cf472bec5685322faad5bd1cb0f240458b56fcc5a6167f22577565dac1ba9b984c33c348babb70506b87926540547389b805ba01e4443b5d60b9a407f8b060fcd96c4b717baaeb72400eaaa9853b962e8a0c8d966458cc4cff31e960c447c6b205629419478360cdc945d6b9a55504d853c1e51364e7a9aad82b64fc37a02e4139b9e6c392dc83c04005f6d1299d990a89ed68acc31b5d1d224f2c8b3cd5280a12c6e088cc2f9d3c59afcb9fee458af5135c9b4b477d878f34723e3912189d2764f9366ab8752c9248a5684296ed46f404a1739ba72d5d652c614860d41898e45b72bf66d587089fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed880048885355f193ddb1690b9092aa2a86af03a41797120be84334ef25c2e70bfe8e0a658f03435b65787f38bc9452ddc584162955f8b8560991c407fa0c12d770e80fa4a2cf7b853708bef2a44f959b9d05b6faef83f6f41a2454257b0157c55047ae7d0cc17079e118c8a4ee3358d877251970eaf86684ec70858a94bbaa4bd2fd1895c2223320ccadce636c2156471b76c48d53e6a6c12a1317c39c48bf3a0aa0dbc8afc034b43398b9f1c56d407a4b7c2bac134024df6ae9800b230e2592f529f79f0ab048867a349684b242bc4d2284a6106dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b22027d6657f12379abbd248c6967834239e2d3a0211b73a77d681b61892877b7e102a53cb4602e3dc1704ec92a9e260d9817c6393062bf520f7a845fff19123a1662fd241090ac81ee1748eea878d53969fea20fb95688fcb3d235910f154bd09a75556d890409cce0a20c6cd2a59664bc4ecca3d4725910d210db0c848ce7242cca945f1568561bb90d9a4c3dfba83074a16fb3ac934c865dcebaf6fd90d5b458c22542ded5111e77c12d8656908557649e9155a8472d5213b46f739f095b5fd4a2418074ef7db9385f19d6630aa29b28881aa3474b7ac352c5dfbfb20fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b9190064f3a862d10cb5707215f456caa10a2c240619925a140b6cba878a0d40283efb9e1562c227d716d2935e8d96649c06ae9465aebf552d68da1e7991bf987a4dff4371049a0dc9e56f110779d562959f278b069b3c7712af29027aad6109bb0c3201565c0b0892a62aa74ca7bd6b48039066a95dbca4e76a3a323612269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = pass +expected_ciphertext = 800e73bbc8dc491180b29772408aa58d07cc850910a70660127c54207460eabfaef758520f288cfb6b7f1403986abf40fad912f2ad1d40acf9ce8d2126dd59c4148e5483542045aaeebb0fc8a5d86172ff25f8b65db0b1c2ff9b2f7b10f82662ad06e40370465f74c8ab12396c4b7c877ca8c231ee5a88358be2e6efde24d17cae8d8e9185255e173f465a9df4131cdce630cab9dcfc6a84a0ae35256358e643b068c521bb3a3f1a63f751a0ac8a2ca2771a30fd8f11b6c9dff802ed6f1dab41499ed0290beed78292b1ce7807ec6cd25d934efe72177a91c4e3727956143bc3427eef3cd9daebd5d9f84ee6e335b77e2f0aad546b938a6e92504d3724a0de4e8f0d1b4ca83b119d92fda08793635b25a4547d910f2c90c143f891eeb14e52b5874905996cb88536643a64c931ddf8048430a63e1ff5be1904da5b136ee0f433217d1ae3b2040327f51323fa93a20610f273ad3af90d2c649698d524c407e04b8aa25ab6e5580be5025f34709314f80f06caa9b2e342c404679d8a08453ee3fa0b59c0b04bf14998bee7be578871deda59931c4e665a1f624cb181e22194bf5b0611cf6a41f7c3cedb2d52dd30a434a504e60ab7fe4d5238394d5b340d38bbde7260f3743f31b3637cfc6f3c6777d9f6f4dc3977d962a558bc533725f315ac425f3e2104e754d361dd24564aec0bbf5cd3253909e091941e8b7e828ca70e730abebbcfb3dbca1dbbad3e16f0d68ebfbb2b208a177ca988c8f69874650594e912fffbfc02d274e094c5ace6e480a3e51872488955176664dbc42501d9b0b4671e0fcd8e096539908d0147fc6011cef14dabfeaa9a1ca31f3010f17b1960e8233d8e2425e96c37f229e53390d800a6c059c3f6aa2b74ebb5ed654001cb760531792d796711c4eed4584279fc520a8e78995329d2ae238b1745f7410dd9cf0265caef5411606475735a6c298941cfb7ae810524c870d355211972e1856d471a7f928e4bf400bda5ed9707ec838b43a4dc080f2a96600db1a5759b246f7f870add6ea8f91608375976d085a5507c9a03ee3da29d77f4a2b32e51a90374ddd79e331a99ffd0d8458bfb5a65fedfa7196d36dba0f2fc8e04ea9fe8cee7aed584eeda24437bedf1812d30fb096bd5e3d7613d620f93dfcf1cb0cd5968530e6fe291ada0411daac93a6269d66db7e3908e91f4511551de33da82e74ca2a6fea7006705408260d7aa57387b8bb4cdd4809b2b140e264c25daaf9f50a8fc28274c17fe1dacff35b4006e311bf0bbe7ee895d707cbe2f1c46824a8813882d46d2d6de5eb8a4ac2afaf4939f36459f64a7dbadca53e098f44d8a0f75042ebe6ab566c8191679f6224bc6676f3d68bcbf422a8cae661c231c841df80d9e40566176a58d610e006811b8d0863d73aa66bd59d659135fc05d0568f438f82a2d4f9938d57811c4f1654dd127ee06fe2d99e76a5e716674d389c91ac198ee0fc0afbe93ade71540f2ea0cb2d63c5c45aef6d0cef2d624fdc309c7d312a39be86bfbcbea53fa206442 +expected_shared_secret = d17b2738213a98f29ee46747c93308ee7000fa404b9a0c1acf3f89654ca2446e + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = f3576ff861541032094855b18cf574d868b0eb783ce9011f28fc14c486b122cc80093897bfc8ac1082421f99767bc42b0ff41b22dc7b50d5556041338e6c4368ab190e92608f6cc69d8b33f1ab04de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f150658715403d1e1c957e5a914b9a3bc4c45489053306329c7984e76f169c8639de4080db1671ed01a24724a101df89e45b5b385ca2ef663586ae58d9b33ade9738f84482e6e28909e7641aa673ad772b125161a316166e1717fdbdc8d02b2b2b6dc21805619d4facc40e9a21bcca9d4da71220a4631e95b25e960192a22a39b904bbb02f1184b79a97b3cc16b5e4b5eaf278913b7a195f3107342a77a68cac90c1b5a3ca9b354a6095c29c09c5ac2b44c6cb28a250834d5f2a307ea3434977d0087017ca2692b79008640b770b41ee2c2c77bcc2605f1857368c8e12983afa8633c870115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68c2198b2fb558f463a7477b9fa7680f1e65706a888b8740a87cc7e7949156f896c182b53e464721e46a258820201887ce9b83d43250b63e2ab29900a115084a6e66584f767853b2e684c547d97266b36b6838aaba73298dab79c58c88f1b51113ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd78106ec0c5e9967a6d81139cd516027c25afbb6c47e3802d56079e6265c4f21f1315a96ab994597214b814cc53e8566330cd51fb4045f605df1c7c9c255166651de6041b7fd85c7e376e28076ad352051c65494a1054c30930621c53ee8947dce3c55bd686f186cd5aa21afc17664d36a2d7f5008ae83950b93ae510847552a5c2f761207b0f478c73c4d6313c8acc25b13ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940b70b68f40bf570c461f11795952e69f21ec4562dec99448263188ef44e71a1681d626cac69c6b56ab51ae656be1ca028672d97d044e43577f26329d50851b0f8a4a1b6c2b673ac6418ccd58005ad400c27d274dd4732e56b5d7c0b6ee731a99e15229f7295c153aa3a873c20c23a35b6137c824f6fb021a0e28f98bb3be8dc07a5b038dc89944952913af7a39a9b00f1a038a628686a735dbd4c45e0b8bcdc1c1a902cc4d0571cbd589f507a0c0dcb81bd39811e723358d6320a3049bcc90d776562eb34877978c9929548286a85efb85f7c6c76ff255f13a0cf5e70304f1cc838fa398fb34e26ca662759c8f3657125dc2aacdc4615653ef074a784500ec60980be4aac94b0c7a9012dbe73cdbf1687a684ac63526778926654a4ae4cc779a600a836e3273acb95a802051f18af32683f52363572583fdfe30287b2632874cb04832f55e0944712c86d37420137c56f6251a1352ae37a0c3fdb885cb561e63a493a15beb5e3b123aca6b6b7294d8002e7ec758ad2c22d336aae3c067703821842cba2dc0b1b7a45cc0a48202a002f927122c040f84a884c1334c1e17347108b91c055d331c0b170c6f06048b40ca0bed838ad963fb8747ca714cf1d3267b701132046699798421acc06a3bc1ade172fc62123235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = pass +expected_ciphertext = 9aeab84b3e0a280ae182a9ee4f3e5075883a9e22f0aa84470b1d481a7a1c45acd500e666cccfc98f1d01c1f1dd3fabf4d2a60e8a4bcbc237acd856622431f667719e83b8ba4d14da5131d9b377998414f3ae58a98295396e41cbe34a8a3b65ee20db915136097e6676a96c093da827c206f9619d09d218468ef0a2af7e3c06a647a148c26b706507b792c0eb9ba46f0d7e3cbe4e71488f83cec8af88fb29e3c61d43221d21329271c77001acaa2d47f2e3842d221834d20e232a5ba3a49f33f7a82fe0cacd6aaa96e24d2d75f12a71eb10e5e554c98adfa732e9d5cd6cdafd6a3fbe97d7b464b15909499f6dd739de3ba963406ce45cad0e8e25122d469857b823b821f59ffe138a29d19c4bdea4e839e5191e7187ebd96eb1249b50a0f4a8d7e3f4930162d922d296301bd4955c44775b42b8e06d25f731bb18e8cd13c1e928ce58b101ec64d88a643deff0dda247300dc7de01e1b8d1643c471369528d94534fe54ecd90203c7fc680582140ae1abc4963c0158d26be214eba6a262ee6f35c73209f9ef2611de8c37152c9e0f5d5195492dc8d91825593e2af1f348e4bd228ce205b50f24fe769a5cfb7462378e3c6f87e680501991e8ef4babafad6ac15f1bce68d0333aaefa0b8f169a2431890ea62d99cfbfba14ba9d0a203c967ba3ab036f485f96cf2c5f033919a1795f60c5772f0f6677aba09c56bdcb33d44470b02e7e1af31cf9b449056ac3b2eabd13c7ced8472744e4d0b8fb396b0791a956e97312b376eb045d7cadfe03c7153a4efd25dd393fd7a8a47bcdda4d4279183bf2dcfa553340ea026a034aa7e8c755175330fbce7c176b4f4eb45485519a72bb4d29af2e439460ffc08610c3aedd144749bdad2dfa5d674e0f6ec6e3fbba1e96ff5b3cbdf68b187c98ba31d25836e25a82e8434c0b79c4c5121dbe00d6a45947c2f4b7a6d2b04b5f6f1aea722caea639bac03b282db978e98235ab21c6714e7684ac2aebeab9b4418a77277cd3da7abb0a44c4c3d2fa28be6fd30a295d85c753dface9090ae37e56fda6c1cbdc9d4d5eff7388c3b96a909da4432877263f67492c35a48ab28ab686e1803d18009c62599762611df174ca87a4c5381b062731b3bbbcf07b846040bee6cacea3e7a1b3781a5568e7c3a9213320ef4877317cde72200ec9bd731d30d0a061cda0055761f0221a1f804a4bbc23754c829d94df4952f36664e3f677bc04b6f9a16412cbbb78b2e5a340837f587388eb17e9ec07c29745b22387da055e1e0c8cf8c01eed2140f21a28d38441d1ce9b263aed39dd1b20856b69082ccb797848177535b31f8065cd86c73cabdc68000575afa2fe8e5c539fba6ea5af3c017b6e3d0e40bd1e68278a339e49a4541d691b178758d90e3b8d016d89deab0820e4c0cf14a53b281e608c74586be07f1e0a5492e79a09f2c5464374c2f287c97d0a0b7bce04e55ebd3371c5951f46714bf52721706a1c086a1168081fc1d1a26e7c472fc1c13daf9f98a85568e993fbc14b4a635d9fcacbd698600 +expected_shared_secret = 954af53b4add522514b34cd2ab96669a76ca13f82aa2fd70826bc8ee790ccefb + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 4c376ba98c3a0415a3bfb0ab42d0a3d68cb171109c5f83147c33adda2cb07c62a9025b44523b0ae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da2a02d35610787f22966298ffbb45fd78a8d36eab454675d6951a70472caf06640bc1b97d6760e74b41c577855bc0756abe528eb4894e8776f1e739da45a9f84c9bf3c72b43262525b547f75176ab2e12d8ea808d3b0355766bd69d964eb3b450a96c835d7b238220febd62443b03985731333c54382d20200e30e4cbb2b607ac998f20def865bdf47ce78ac3dbc1abe33245d6fa7583b31b6fe7b6ede7a8ec776b20f7bbe7e376578f0933b761bb0952161123d61282cd6c80cdc8a85f9632aba1a8ef5925e410bb80beabc67735d07e4abdd587827745a3220a24a7b3902416befab3073c2cb1fa76ff04315b653b3e7c18343391f92015939829dabd0289b5aabc4cb5335d963ab842865bb7c38106eb1274eccd0140b415901279e8719c0415517b5101394f78a48f565317909371a3154d291698b0bede17052f30786dc2d46e71edc438c288cbd44445f993926bff0a8ca1a033b656c2362a659eabbcf37b2cb5916940aa9b3e850e51039c08c8588347e1099a0d8380ccc4b8cd0c87218bc24f09126a82a3d530a75500254510ac765cc1de612a4ceb14db78a7141109f947b4329158f87e4c8b41a92afccc9eb749d66a71159db90e7a36642636af22cc0d541ce52db7ab44baf30560691a637c93193a11a00efec075289953fdc9df3ec3390342aee44c08d661632fb0303681e1f89ce1300b0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66205c28766ba5eef7062363c19091c61c543d5c1b8a547372515722ee515e8ef52bf8e089d93377e2c8458e626d3391953d658cdb05c7a40077f4e19dc0b132be719014c12b0cc242466112e94809630b63fad12c99d271dbd38e5afa54c894542b940415354203a0c8a785ab94200ee0cb976991c642257d9af6998b61ba27b236fdfab86f834fb2d47cc0904b9d6acd2f8311f0d4b8ad81a24f712d92272587220e8023a8bc13bd17572d38851778f319607752466cb0de7c5c12103fae4c57d953b96be93262ba9cb05405a5d2a9e012b21a22a2ef33a385c898c80aa9663565b63241a1b206f3379abe8262cfa49ba05c3b43e9485e60cd38d66eaed114ef81afd66b2594baa361d3c3b02069b1a164bc387632e24c82a91be2ca390eb585e900173699a8b26b8916e52bd643645d3225df38ba50a50ea013b4b2a86ee1f76278e27f5a4142f034004b567f309c52acca3c7530162ed744a67481ca338861ccc3e8331e1c67886023743719493cc3caea51438e28ac4ea06b906789a65220e3c7407c874c6322be1f9b627386081753ad618a8dcc013395f20f5017ae2b57ba908617490460d5a67fae2660a56c4c4d97babda0bae0f494260877f7077af2536b2ca46e297c61dd8422bbe515519210dabc02e7047b13f16607ac15e4950574c43bf8c39a2528addfa2782506635e5626967a1f30c02fa3442fa93250571a8173999a88dc27b43c476468a6a4739972dc1b68493413a2743b9b563283cc886916eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = pass +expected_ciphertext = 0ed9d867a5a681c5294598bf4ae653943fc39d85798d3ab337f344892209275d9916e72cac7e94757cd91e9c35b23e04a29cbf32320395c0201075f704a0149acb8b3624153e2d9ebcb6c072009850f3fdaf52fb27b559dec221cd22a24080b09b1789e5c7e0e927b613291fab9118ff69ff7876eb2fdab05373240ba5b10339c168b635c811456f2fe6295f1f22f01c04c8ae0e49c9e303edd658ea87a279b48e3a63180a645c40e1d0ea1f7037f53de37eeea6b3ebc8a455d3a2356ea047e09df3ccb32cdb60d7a894c1b708b6be01ed9ab7befe611f3699bbb54c1f9fda9b3fa6ebefcd9e535ff1cd1deb3ed6645498894c8dd29c89b6b4fae20bcb4e05876aa9ffd200c2672c6b0bbf2df9143a1a1383e3ca7ff7691c5c5bb6e94f489d8d269b6f19fb411df8865f0d07168df6fb052a31579be29954d1e6a7c9204e9095824b09e9c99d1b7f7c174dc653ac55cd87b6ad0ffdc49e54afc500d7e9d3674355f199c24ed2499d7f01e789017a33aff2f739e3b60420bb9658f2317fccc39663067fc9197e3d8da3eb414339d87439144b8b6c993ac3d715ddb2603dfd2b73fb1b89d7f46dfd757c1d2b6043f83686d7a8e81b699af1d4071fd4fb30309aa7a730e134539687e9cc2ea29dfdda6ef249ce9ee85b4e1c84da1b91689ded5ca4d1c9c9d8ac446139cae39ba54207e70fb18970078cb8256a0233d8b29a0e7883bf076c45dd9219f2694f616e7f370b53a853095435b0ed5a10210a9fe9e6aaa79076aff0dbbf7f9cc4e267a1098221c9abe8e7d9e8d36401878b4fddea1049267d1928d44c3a6f99be6bc476ed91feec35d9504a085e745e39f2474e1d3d6dfd9b8994014e294093ea397845c0ccc9915bc5c800c1e799a256174ebbf65ee8701e9af4f355c657a7cfd36ead4b475c5fccec52cba88e0e5e0306218bcd333088dc31ef4ded6a2294f29793abb4e3762df8b74e19ddf32a641ad8d1fe16f315c60dc68b2d29fd83d2bdabcd92d7cfa4e02818530787d60b19618a101d71f964dc95d1a921b28eeb343ab4e6008840d226a0e9e8915c3abc535e09351c0d898557027cfc578a07376e878c6b90220fb36aa04834dda6f9b7c1d8313b9242e9df2030474afa0743c9434fd189e64e76518573ab7a054d81e1ecd1321963a078805f9a074fd3920b7d4e1a435a5ecc0a2c25466913be3b209ee3b0693ee561e3d745920029c384f53c3abdb4a49cd4281ceb70eec21a9b47a693db42ae08c88d2ff41ef3d632080d33405a21b516ba377e521e868fa3659890ec0200985469873bf42daf4fa5fb8d0292c5bb8e9435433d2a4dd176c1d27f16e146262de295e2b1046cf5ea965e33ed56fb387ebd0fb39d95893d876e33278a699791930f833f2ed6e5a7defac09e6ace406deba5b19dac8440b6bcecaf85674839f775f279a8152f6fce0674e07603a69d10950f51da09b12e084ba70a828b00067ef26c9d3329532cafa9511f78b3c84b685f9b42d96ca5a1b0b399caafc45483a805b614f629a1 +expected_shared_secret = d0bbc576fb1aa43b6e76db0e87bc4ee3fa057c31642b37f3339217a1b041b521 + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = c8735813347c3c7c05f81a176264a5ff791d9801af88047574008c870635457126b4069071242c24dc0977a8c13d43b889d27f08984d9ea657d241922bb12aa28a1408825b02663b970778bf669d585a975abba6bcf8513c11bc73a0c33897991c3428a5cb4dfed155b9a2909e6597dd8cac1ad62f9cfbcb27088860512859761885c5b6c5d89fd6b18f9e324ee8f80b4c507626762a22f4cb7f4527527896aaa97a69b8aa4fb09b16cbafd73a667e9cb085f7ca36067d4f740694e6c83c671071762fbba26a640c86422197894caf01b0af66960651998073ba7fccd3189148187ba22dd2661262766399a6b8bb943aedc590fa048816d1b9d827ca80935d30e1830c8115b18b754f20acd7a376272c119cc8210c9aa112d604b2022326f51ad674aa1579c081f12df04a9a2b4571fc1c21a8a4ae2c701eb2ebb0ce65cd2fc22fee530fb3daa6d82b3d46e33e9c918f6d33abaec34f45391245453ef4d128c4c068227a6511800d69f6a31a1421e2d322f897145961abea377c9393acbfa72ab3c3aaf7f04ddad50077e7c36ac46e083075265c58db4b7b47da253b8a9361c08a1248b53098c6b797622e228939f110ece18c02ac613e00b624c61eff4524f92c1ea632553d9b90cd886fd2c364b25c877459ba6de0ac8cc2a8b0f2c6d71a051f8727c2892d1934857eb995a8d728b9739872ea472e6602f2c39484d290109ba924933d6ae52c30eb4d80935f0d2c87d4dabf07582cae3c2f21692f0825c079ea6700065a6086b197582b76cac90a58451d7479965475ac8a6af662c7d23055c404246264c97bd23d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1e4050f97ca3e9ab31e561ab18cb3af721570380023a9349ed6bbc5df66bb243928dd3a4b5e113a0f99725c9c8bf673818b89030db28edc536c9620a1625c8a647bd3d7055039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651a0234d2325ed82369bcd415089692547b325ef28189482714c80dcdc5bff72a6152b70ac2f16707c63a42830dd6cb88ee646d882338d3dcb202408fc5210c71d1a8ba02b8c2ab7e06e43ccd85ce39a215e67914369c749c3978778592d9e34b7671283dc787446b5b70a32c4c1ca4613b01a5d0bfe55016b897130d1bcfb49bb5f08c5df9f15b6d531b06c53a389500675aafca9700fbc310fff968300360ab631ad95649f0bb47e55b90b2593d9a60bb0477ba848c0db9f8bf6c774cf8348c65695b31b921e4439e976b4306a47069c25e4a7515866c0bd77b44c7881121025cd2f28430383600e4ba0bd28074b7bbf2a2a3bd62a73ba240d644ab1f89ace0c8a83ae62f642237de265765458d6744273e4372add9cf5215bd39fa516575bad72034288ca3e0d3be57dbc7ada731f5f13fc0252bc5a9213f502c342a451b933d3060a2ad8a9c13013e3d93455327c187547809fa57faa299a843a251f8368a715508c32aa57a42f9551520433f9675add0359c5997c341464264986fcf67261d16b7a6989ee33730754a2ca0f66b6c98cb421c8e4b36002561b1a5550b93b144d5552afee236357c8093932829f864963159a8e7ca992b8fae006190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = pass +expected_ciphertext = 94f5b9ef5dfd9caea5d92ed4a48ba23b9f55754c1aed2406de032457dddf538e797c2e02272aee5ed23bae0d5cba2e37e7afb8a472c75475b92f89db6ffa08d83b9160768541c49dc9da73ffa6f928bf16882b63c29e9eafb9467d0ffb5e3ac4b95c89a9462432ecebfa096e36901d2192fb2ef06ea10d908a48e9c1b2201b115f19f7b433d74a6ea836836a04e95eb93e1b844df7f36148ba6b218715cddc3ec5766df62ab97d5337869b14d674fc568a4c249f7832d34f05ce36c465ef020d00df336b2befb72659f97cf645d4420dfa0ded164cd10130ec7e9bb371f57bedda294e603f74b268333afc0d943330e0014ee57fd5a655aa24bb8c088637afc0d6300a8a3997f3e513154381a8f240d037791da03f8b536cb4a4a46059b9ef3c16de282cafcf7abf4c840584eef2a4617b3b015a0e3734aed2ca2d7c182181343718934f6f4bfb7bb3806ff6f412ebb0df25b588fe79a60f0118c9f0de2ad09031eb00f635fae0a2dc1e25d8460da9faf3d84c785522b817442fc1c801b5dc0192480649564731eb95aa96970b00677df4b2328988ef813b13c0175f6b73b2646a90107f1c031a920aa8efccbcd888ab6f0c249d22f7a08dc725ff5bb6969ea5d8a319c7c0b905c2c3b9688a6eb0d42e9b6d51f5ee1195b0591e7f279831e427d283b439a0432f77ad85345b1cf997e6232ebf21734b1cbb6d333e73e25f9aaa94de479b7dea838881b766ffc2f5e8813b32bcfde3695096ff2c9d201741c602be13e79a84718c0201a1232a89f6d2540e343327c1c9ce9c1687b4b030e7fc410018453f363d639470f480beb007812fb88d6c3450d13a9e9924b82198d9325c4ddcda7e3b1216753eb9364bc8954f1c3373efaf5bd0b70e260b712a79253459fcb928cc8ee8f770e233eff63b9d1d7e5d15db03c95a64e24c1c121e084f2aeb506dce765d03cec76be9bf8cb26dde32198ee9972ac2a441301e49dc703a8284ff900353951d390be673710d0f8c14b4ff42c15b6d2bb9e360d0b573b608b0e28d8cc8d40b9486217fa3c4783d1bb31e9f8f7f9b6852207b4fc9938c9f2b784ca4946dfa1fac87277ba62cb6a5b69bf34defeef435e6e03ec53ccf255fde48bc843df6ea502efe32f094efa52c991cde63678a5a8c7e5265cb096298f4d32d482a8149157aa4b025ae8ff5889928ffb3fb08499d704f3d146ad259e296fee0b83ec7fc4fd2ad036afa9576d1196c3261e2ceebf52eeeaf5cfaa38ae9f4adf7be4ba96d063ac8ed6fdf3480bc26c1ec8c382539f188e5b64e2016d511af0e8744aea561734efb76a4c943aa452da6523ff6b4c99fc8b13b51c74077cca51cd7d4c17b77f5f966d79e67cdbfd9489a71836c8e0f0fd9da93b4c1edd952d6300413dedc20fc77730811008a39f2b9d2a87e67d9657aaeb98ac4e73f99b4a5d9eddedfe04eddc6665cdc6dc277b5eeb5b86750096708205ec78c20a512bb01fa825ba85c8d1887d01304b10cc482c1219f97b5b7b97e76359c20b4cbb06c4df79de4 +expected_shared_secret = 91fbc37d4749ec6175c12f0d8eb6b6a8621e693c79f85f5cd2f557cafec5e7e9 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 04a592c364aacb2c89689106aba29029c58ddf7050a2c78787358571aa506570288e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a181d4107cb723bb6d0729ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b370d37a66ce048a9dd27ad17b38c66880491985b2af8916c547e9c6cb16b506170f29304c4393e8274ee254a3f13c6b0e31105442bf92799f21774be9a0f64970e6ab581626115a1aa3ee4da7936504d036b75be6046e5778f58caba93f8640bdb24982c17ba3445f2ab983b685644b596ef66acf739039ad0a3cd61bb80b000f7e8bf53f60ebe235c0bf22c7873aecc6b3ae2f3b2cc3bb47d1b88423a188393c43c4999c32a886807cc4262bcd5a588c5e1bf8ed6a6ea9910c19a6042679926f314e7c7c85bf550482735e7fa088c857ac1578560a1a2f7e831223cbde33a46632b7e24d400a82a8c7307c23d6ca25075b58e727673d7cb5554042cfb9b7f95b11a55a9fd63b1b9f0b60f6931a0ba1ad28b485753446b0005e8710d7189bf438407b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b6c1729e7ae22e28f2082a5e653b5babb0d147a8748f2606ddcc7847c24f0d32771b910ccba85befcbd2b89c5035b2062e6b9bb40828902b82e12b752d48d52b7a6599ac014731e8da091cb30186c849b61954dff867899e5bf27428229376ac7d97fa03996160964abe56d3d0278f9f91fec6bc821fc822949ad5ec8a9d728b95b19052ad9442fa0527b3935f4697cfa3c7413ca2e81b32a57f69479e89760a46d710032efbb662f9467f0d03c806b619b9228135076fa235d502230e56669e2354c1b412ecfd01a429b5c76b17ae2ab99c73b4110957aa38c22c8fa39c00261c78aa571b953d868690761655ff700803a477917ac8a6105cbfc220a30a0cc1466d7598b2058b3899c567a71a66d5c9da75085686aa4ad4015100360c6102c84c336c13b229ff599dee4cb2c90a1516682330722da110f42f7c0a4f23a2089add65438dc66246671be41e7766641b4c9139777e08cb4d5b953e602931a7db3e1ce70d765516242ae8987454b898f19c5103bad39207bb16771b5d4191abbbdca9b5bea711081ca6521149b60975e02cc2250a355897960a8e203ba148f8be76452420d2134b607976f7809ce97597d8ca57337fbbd6748c03227607fa082195b49753c43047b95a020c7d195b01dd3cddc4c091916c37e447acb606f2d232c37c9871831c1fb9a8d00717762f18e62e7995a7393e0a82617da4674078d8f10065a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e887107d6c14488e604dfa15e55004fda8b65ae19006ea7c8a7471b354a4e746703d5c79857a02ec222b78b966ecf161d97ba7cf39b37fe173485a0156c3712a6ecb14e629899da9163709b672a243d1b87e15c0ad611419d85522252bb5a02ab725cb5eaea5bda73976d534a881b8c32c5328d117306fc5217aab89cf51c6174489ad241d1cb261d449f24a235fcd46fc19a8d14a4281906236738a060061a494947bd91604431b1a2871080616ee2e915863b2bf2d9cd86743b0cc12a5d21c6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = pass +expected_ciphertext = 4f196d816122c6774617c45e22df48ac3e86c3378f3459e569534f574842967a369dfcb6ee004e1d050636654bb9d0f7a2ffb7c574010fb2f321f85aa574dc3e62993a7870475787ad35d68e5f7281ab98488da56a7a871e8a6eb67baa98c09b9ae117427268d3ef7a3f8f012d0e0b241c39d12f3b1d405093dcb3d20ed8aa3f24a0ef8c08fa24623f3b96845f913e96b1896083f7cfa047bf50bda06000b5f8f81ace902062982aab78a5f800a3d7d7268855e8451de5c633ae05b8075f2d6c98cdc8fe55d7ce4364407f4789f0bf91870ddf6630bc84d3d5d5f8a08e20561c8645a95e51b1e657684e6f9b23fa979c97a22dd6a2e3a729f74201892ccf378db23abe5a6c6734db7de54555e033966516b08de0d652186327af83691a5af4a8f806dfda5aaea644bf1f1c32a9e3a50e9c5783623f20e0f7cceac32b57a908d28277430ac7f2d32232353c1e8d34c4a6e5113bf2de9a074d26196459638f76801619a699dce0a7599cbdbc9ebba872a1bc1ae83d07986e534454ccf1cfe526d4fbf599e79cba747f4f2c6b3a6e1fb04b993df44d87517e7657d81d5fcc1b220a3069c16868e279351ca90c20a73345fcaf12cb75f43102fba680b641536345c154cb15bf7592611313f8e958953808b06bf0d5655c74b022e3a731280ff7a7cfc92a60fa6c51161e3534e7529aa310ff848b4a0bb7c00f2425bdbc6cc1c2fb050fd0b2ac17db264f48a025eba86a7b11651108174b5b2d859205ef2480b9adada70ae09162f82c3edf176287f8e742cfb7a233367867ac8bb2c5306831d3c8d399fb5208ae3f15a24a70493b62f7a918312ea3fad7a978beb11c43e679ad45c284a47f68ae2970f5e66972a024ce0d6424e58e0262a0f94ff07621a2d5fd38817f7d989a45282e71463ef37b5687291c4f852a6b13625308f3a4e6fefa0ed84c3cb47725f00cd88687757d3c625da09bcb8910a441faa38212a4bdba9a1b513b003efc55fdee2a3bfc1ce0d0b8a0f2cb4b828c5758a174fb40b9d245f63cbe3bc07fa68067d8feb438ffba418e50ddb8ce6f5548b8319401d1b4193ec59da087badd67665e9b73ef489b5249c8794ede24e70e3a2eaabab868508adafa1c44dfc1363d3d8091a7acfbdeab2fe73de1bab8507b180f570ceaab92bb297557927909045515974c230840faa67d9df34390675fe206bdc4b5a48032b455b45bf85d150703aefcf57af41fb0a094816958193162e821f10b16ad8adb8021b0d5cf27447b9b2c2c3dcc3513832d19b11a85b00afb03e79f3e7cc06178639eccfb943ad60d5705f1e6c8ce1c8b1ac9a62aca9500bf870414aa2613fccdd9eade567c135dfcfd850f5d6617b1dc181f375806fad84bbc69e28c49348cdf09d7714fd35a49d57d75ae6d74f1ee337d2ac2e595152da79059c93452f0f89be3d1b2cb5e2c454a4fbee52fd97f51b4da45c68efa1bc08441bbaa3082f4b633e06251b9859298b2c4201759538bc46874fd4678eb27d7d5ff35b4fb497ed739d5d7119e213a +expected_shared_secret = d586b441b8eaf7d053cc96b6835f093426677a7c3acc51aaa3ddbb66dd14a623 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = bfd11fc259a2115806f9f68ab15859a763a49d169d615b4999714d550707e8a0c0a93c8db2fb5e4de7c93111206f052a7d7a5e0b5632d94c7a87596d24e950b361a185f065fa96435f312745164693fab8d3a741c56c6f10d8be52c06a5d83cb1bd327e5b28db12291d907a2888136b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861626167c5a17cc2a4cc9f668df0707d26795de7f771bc614b994b574fa309a1e1c8b4a0a4ad6240286bb78ba701ecc430269a37843149e1f1aab731523359c735694f09298e2a1a08c6ec273b4a1d57118b20524fda18190c2029da4095ead53212f609a76a343d5c68ff17ce6b92b340dbb8cc6c03ae4b29df243b93233af6b95eb5a7a8b8643b0cf5a8114152b8ea54f0e3668511ceff536d888baef85a62299c641769023b7b92088546f338448c1977804b71781a554bca5f13c0480b42c5a6626904516139abaa54b429e7a0502b17a5a2727a7f230d63c5764dd497f164b24e5ba3a626785ad1b917a6b77b175e64323783c9791832a7c442b895eb338e6a29ef671d4d7c0230668c14bc794cf11340229ac905891cf1c51ef62b6a4a0553331f7f581054da45c370bf606126b39492e4a3b8592bbe0359bc017557379471ef922367d82635d8494c88bd38a7720669a1f9145367a92090fc5df15c034b82cdd9b7cb9ca76e74b2069c36987556012bf0746424677f60ade29c9cb52c6d9cc2052394691d7306952c65ef498da41279eeabccc66b3a41747a8b447d7ee81116eabc04f4b776923c93a28ffe888652fc34415baaeb6854d4732745a4bd5ba61c35678780063ed874c81823ceae41b9684a05410266f7ecaffbfcb5285472e5b02fb8c15d126410f0ba3ba8536cfdb65d23797414a55f2620be653a98f33c95690714fbd3418c6893f8693908d41d6d69a744e63b2b0c190e3b1696a5c8b1cbbaa4719a0bd184f896c9d8f926dc933ba81b2785c05a51b22a95191f43dc23b42c050dc9133de2b003a5b6f1a5730f490454c58af291cd8d46acde69842df79353670a54e2c88cc693745516ee64c2afebb95df25ec0608ae4aa9c89215d471bbf68dc6530fc0fee495fdfa09e98ba8d37f9636b270bd1102579eb7f1bf0b911cb79f03537168867eaf60d77d48be27bc935b02662929dbf2263270670e0601e5e43008bcc07f06451e54755fcab421d584bb603008c9909caa61cf99a4b43a93ea8a3440991ba402c9a8fc51f90584c55eaa450b7a600342e98420d728a8b6344659f2a0263140e69ab86bdc6b20b3aa0920b90c70c0108358c8a92b27635154af9a0a76080ee593ce3d37e40fa33d0c654aa77171f822e0082c95cb60b54a6a26099443f671e863889f35a0b9597b3442a71fa704f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75448d21926da0938f92b9133a92e426dfd2634a677878ea9820f5c26a2382fdb1c4b8ed59db74b4490b87b0dfc35f5b22112e5110d494e53c50d3fd6c64cb485bf5ab37f7a1b709122c7086d3fa56fddc966db2c53e09b976f986a334290dd8c3c7e6582c4eaab182766ff70503b03b4e68261cd0303f7a83732795cbf84a04d78a541a0929691c94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = pass +expected_ciphertext = d1b9adfed05b0545598a380a908d0630ef5a5b633f1a0f71b7ab658c12b5d41870dc738d16dff8ab4009b04f1681382c91cd87cb1fa19fb83c6edfb215b14a21f6595e50f60d23f65c8651a7acd2d42b8093d36511183caaf38482ec02d0c5495a0ae08d86be9177ed05abc034337e502dbbdee1555a5df175420ef9d13ff88d34e3dea95109e543f83060050c948cb5248bbc30ae8dd31c16c0a2aa6bbe91290bf30ca690edbfdc3122961b529112d1c88b5075fdeae100176b48fc6e954de16894004a33f1150ec182d1978dfd30ae4db0c7abbd069ad761c131617643b25bb42855c05586cadfd35578b04ad23c599b200a42c75cb4614d4bc49e0cd69ae47af58eba9c4d2adfd39631ccc550bd3052e33514b1aef509d9d4156520510eff630878b9612a7afe6e652baa02cadd1cf5875ce07f04345a457a9cc94e4ce3ddafb51314e11701a9062fc38d126d3a5846c99ddc89423396c5dd19ae00648760bb9647d0d4d85aad167452ed2405f1482a9699cf70c99a3d9e7b897d99bb5e2f59dfed7a1c681315a881cd08a0dcff6678c7aed3211417d11f4d40da95e46c5aefa7e88e27ac0e91ebdac1b6961be17fa2c5b7ebcdc67354be0e43abf6a9a611ef02fba24a662b5b6ad31747155dcfc62ccd0149b355cad072e462331298f6b0155db2a00033f6b6aa71b8fdfb4e2db72040dc5b8e7a55efb0cdeaf6127474738fac38a5fd890259f86d5af6339c4cad26d1ccbf98408eaa182026909dee6be1069fdd9dce80f2c9233370a8cbc0a8a52b3eb999161ca9bd8c250dea2358f72340f48c9cfc0a8f347b7480630659e13708a34a9b121beeac05af0bb9f8475674affd1889dd75146d104ce6d50992311e3132c4724bdb1f793ad76bf1f6c3e30d9592aed479e406dc470aa810198c30ef25b549fa49ead13b66db0107201ac624982ba4570f97679afdaf1dd174e1121d6e02b26d8435795fde7a05846323c5dc7f64532375ecc44b9081ade905e4e194d1d17ba0c91507f16e34d4befb2b6ac08a0f0d3a8f09d2a1bfb01580ed0dab28645faa28866135961e2910481f9d39ce5a0ad97390a1d05f40a0645c3ab4b0c749127cd17b176199b5eb9e87f625bf322cf226390f9de5006e207b63c5e1863bcb60c6b05f7d3577cc59e9d9f7c8be6b30ba9a22f17b6d860ca6621e00ec18733645af0e9b63a40810225fbaf470ba8d232420bb004e779ec73eac3d688ee30926cd1ea673ec6ac7acff1d255189ba3ee8dd5d9ef0c0d3fd0bc911f818ebecff8cecb65339b8762492e79d4f69c2efc9e0d6a406b1640f820454f4cec11ea7ec441bffc79de43f9bc224a570aa693edd08bd637a3993de98eb29a2f8db93347875ad3adfe59ef1a1017ea9a2151e8e95c40b92f357e7bab7c5a74349e1aa557483667161762594cf28bc2f837815679729da4e0e1a567c7eb92d4cdbae032364db056ddec3dbab4d2cf2e94ef0719ea60465374d37110bc7d89baca24f7a420870cadee72f58d8504a37bb7acb384a34 +expected_shared_secret = 409bfd9102bd4632c6b5d3610eb349fe3e3bc51e73acc78a8e994a070e20e10c + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = 12422cea108045d2888e2c29ce0bcd454b95c09730d6c4698e779987523de0e972332544c34350d29c7bc030bb6273b9f1c98c3a63170abb2641c54dad64790e83387c51aac922814f834c4745409273ab00051b2a819eefc9a048f222626409fa7b3f8d27a0dd754f9372aa37eb92f6454fdbe3116d406b571203dc05201c31a52ba8b2b95b191a7b7b55e743c4ccb80a710863ab741b727f176224012c539af2bd062ba6be7a42eac08c5b6b420becbb41b55454ec1f41347ccd984f11767bfc82665286a56dd31598834b37ca6ee93658999798ead094298160b7e6c76978370db3180273401532315168a161e087d4c6086846a3b60b80103c1ad814843bca7ab329c7914982ed32bf16507b3024a16f231281a732d3d155fa60260064919c484c1741874ba96cfd91aebe5c314e407a66d7cc4c846176d759618654ac2a52fe69c69a375ecf625e2889abebf395fa20561ba6300a72a2091356fcf197c866ab5468a3af7bb3de755836d9784f7c0949445d83b3358721c7db3c09b5120f7f757bfe3366ae4365b677255ea680f27c310f768e56f1aab8792259340bd6b984406148a254bb605a291c0946c83b1e9c5bb3f879a787b9106f98809e94bdc23c062d592318f9854df04bcc343d64387baf398599bb352f82b1f0a5b530e824cfd69d7a4a15cb5624f70cbefe1c61302b8fca337d70d1900dc817837619fa893208da873c350f02892097708cc637093eb25bfb4b3c793331f0fc73c5446cb11276824cbe419378a224a683fa0d17c671fb8c4bdaf18c20c53a21a4bb8fba9ab7a1b7eccc81946bb5fcb15e1d08ada7761a55d503dba912b73765ff93a6ab642b5fb72ed4f16657ac448a1957413cae547ccd76d9936c860c70c5635c28754421af13448959d67cdea3997ee923aa326129b5397c15ab90f95832f263e080a42460cf9f081152aa59cf17263d008acbf146f34a7808257689a3148e58a0a0117fbb47bca97810a42a7e0f734c0a17745afc6ade752080b39f3267399c20b1fdfa195437b83ef5125405aba8d2ca42040371c541a5fc339772948a21b7efc30c909c7938779bd012642441083150118ce431baa72e989425210945a7c47479f4873e3c3ca6698ecb2a050415066d0bbe5e240222a2884b3cc17bacc14164be0d21330456a279547579f8a4e9443d913a154210a3fd1a1a263186445a8e1b884bbe8b54d0196affdc47544c8d10a69378fa139bc8a422c44c5568555f9080f170bc6e97284f448e6c23885d603a732c469b376a762b5068e29e80b74f994588d9822f3e81ba6ffc273a9c905d0910062bbe94aa1e0c8c3424303845779f8c9b515dfa0864578a66da8ad7b56da2810c11e1a2888b88bb55b8c096a145b62ad9d2c98e003658c9729d7b82550527411a9c0b981f3479251c1774014749d211687dda83626c6bfcd5b08f8075954bc10f48623838a736e38c1143b9472b4df5d30d37f0bd7c727a2f16a3cbe0015dab5a12e27a63f7aedb841d6d9bb1a79a5c3e903c9e374da62a298c549b9842b77c33aab6b4939aeb55704cb610d084950c41b746afd7157613618f6f1574ba51b36f7828af0aa4f79c0840ea3d679013df619046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = pass +expected_ciphertext = d7ebad4e7d0644b802bf0d325f8947e10343dca6ce3affb6645153d9842683b6d7526bb86e2d07892ead2b38662504bf8829b3591bb44eb03822d34976031ee39bccd8b418ed77296b2ecf1517a37aeff2193fb1a6f90cb8b3b46a213aaf471f7170a04b7eb24b8b62f273061fd3f04e567c695f9f85c1749f052a508f04917c7fdea48643f2aaf8d3f4208fa6e5e3ee001054826da4ed89240acbc68471bb06acd6843f639875042454ccc3fd0aeaa0ad416c16ee17afc0b8df9a49153ac2ba53d536fa4587d69df1360d98c82589f9cab145b07a4230e5c82c856a74f0ca95d205ce5d074c9bb54bb1caebfea0fe7afc30b69b852663752f478132d54d26e5372cd62f48e0f33c836a1e5f38562b6728061c2875126527ae4e84ef15c4e29df126fb9c555e9ddeb9cbc6c07036123bc615aeddaba1d53b0159ccede60943e1d00d7eeef769e3eae0181c69556e5daa1520103403f8b16e9e921be7338771d65339fd89e180caa88ac32154b9539289c587738fdf65eb3ee011961e0f0f365a5e885e811fe2db2e12435ea84ebcbb9e70ff8c8db1325578a7e82b1dfc53dc5322f971ba2cebce3772c019504d44f86156740d31d44fde5d877e68c108af3b22dacfee863d21d40e0402209eac16c3ea6934d9031fe217b326451b29130e42788e62a0def2eb2fedb2b01f57447044f0f61af4b71205b6ab352cf46f738d9582e5554d6a1088afae1fe4c7077beed897d13641adf5b6c053cb3d4e11311ad3b07627ab4519e51c0c767c8abc656648524aa42d8d4d3bf4fb82baa022a82e095a39c16b6945779391c3125d8249c6b66453123fd713443dbfefa85f1a74981b40e72065972af07d47e7a1de0f42a159dc1909ab3e8988f43c4a6b729da0a8dd33110c777e2344f1b8179d83de58bb2b95a8998b00008b2022b50a7ab7524d1189d840cb027c3ae29ccc809e3a977bcbb4aefbf16c524497e98acf053e14bedfa90b01750b1cce2c2ec50a701bb8ec8f9f5e3ed0e6923f8926807ff5dfae71256afa331f14fc8e73aeeb30ae63b3881ac4c27f9973eeee6095ec9033df4bb73537c304fc037a9d04932b3aceb69769e71cc73eb020864395e5b4f455e6ba92bfbf8588cd5bd3ecc7e9ec7566e2daa123d4c4037cf1fef134078f463e4c0a901d51071fbebf889245ccf13c0c0a889822a485b06fff11b241960ee95b0518f668c3c663b9fca9dcd911246e1d01d524a309e96cf50839deacf9eddde59ef2602bacc13cf145f23e98c4f033c7ce1896502f88452201fa81f90a16cd2816f19380c0dcc61f342fe479ef17f7f8212c3afb8f607da4673cefb3d58ad5d70ff938db0a593b1fbba0418041093f386761616a851a23fe0cf576ab1c0903c31f3f01e6cb76997f0b7dad2b088abffd67aa942c09635ef3a90b09115a5be2c694f493d076df5152e02756bebcff329abba5ca82bc77a699f650102e4f80d57d6c74a45779e53ac6717f2c449451f65f16a92a76fa87ff7c2dfa5eb564ac66e79a74b1bc75 +expected_shared_secret = 5dd151a8015c0b16d79822832ff4cc0da7fd38eb73b7da59bc519d4d2374b808 + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = ace2af54375d684a6cb1fb38bd9c803a158483f91175263779e75b6d42734dc72fa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106e91e32341aaa4808df6528c3ba98886184e0195e3ca09d9cc525980cb5a2e9027c6a88e9042bf77653b9dc02ad3cbb04f594bae08da4683dfc960708d85e39a28ad6e6a7dc81a2f0f8167633901298628b695cc1868756a97d80b1afebb71eba5969a1086de4d611f737af56a83c7378c6e5e04e79a8967514cc668bc8fb7c7a1a671e29d55068e34d883a8320438ae7a44f01db1d4dd07304081d684796a9257154381ec44562a8d005f3dc4c94d5ce9e36705132acc8876142194da54934095c2d5725a10e376432b17bf7d1b085d342cb3c633a085e950248ccc9c7ff350efc341d07d0ca06e6bec943353c479506691f2347a29ccb34ad09c929692ed98640e6b8560529cb17030ebfa4c769fc7707c75d86c234edd78e7b3010fe86bf71748cc1c5b00023944774200b2163b403b8207093dfc959b6aa09fe6b98f6e83f972a50abf113e9da2fb9fa10d0d05789ccaf05c448854249ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf428087d8333b16b1a9e59794d49a40b513b50867979230243b27f3d784932e1caadf8b58fe11bbea62da4875d004a73fbcc90b566ab998a45099194d449cc60b0562570648ad588b213cb99a01283706878287930a71b68b43f87023d2f49829abcbde6a37a941182b78b8cc1b93982c7a24457a9e1683d2bcc97b4259518e0102760100e1c26cdd85022a04a91168486ba3413613ddd6c42ccb563379a08096b287b41a011fc9594d132e33957f2a5bc1db4c57b4c8d9d3135476095ded35b2fdc09d8f996e332baf7939efb1032e529606677bb1144374c41c08807c9c0868b0c32772f18b755d7bc5c5b12f8eb9ca9dab589185553b74408301062c90b2d68504f0718d42a1989f050f9097889aacdc175cd7e6768d626a8c9aa1b0cd6cbe91b10af1a3e507575b47b6ac8c2b7c801a81985a81ad4ac04b32d0dd880d43b3d36857738369b7898b231b24ce6e9944526b9ef370354e21e38f6aaefacbda63497a85327a2112a5db95179c5285d805698209f2a1b67a7730405b02b3507b4e4b65298734f5eb1b66bcb68f9369abc01c7e4545568d432a685a6e038122253987edc55efaa3d926413dbdc43f9908df1925031f45d28712734fbcec3724653b019f7d5698da7b0c3c90eece1a1be3567a253a143723b9550c8f7333ddae88208667353a6184853a85a99c0c463189eb5763fe59d678349f536c56d014cd92b56ed2aa6b0518f1221a49fd6588650057ff00aa29b93f182b3437386f1f846d2a3c60cd900559425b2b7a5ff88cfabe24bedcc825552577b5c12e4856ddcd91b0713526098b5fa555f105a0f1219110347af9016254951c3cb5c7ebe602564242276399b0048ad8d370b544b1cb9789694c7753ef2cd4ab51513cb33f38bbb10c83c9a1a5fd1489d97476d9bb314849581d688c3dba01662b539c50b0db8e889a4654e6af708a64910fc503cfa0abc21b8abc233ab978965059c41d1123a4bb90306aa09263b25be885f4db186d0e720e97524464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = pass +expected_ciphertext = fbac7fc21143080d74a75a743e156d9095fdd7cd5a13091f191437df1788125c9f908390b664d8d2ed2b9c56f0805df3254604d1f5bc1a9b49257247ca57863636a9c61433fffeab86eefb6ae8c2cbb725f7baf4d75e1f9ace6420cbf71bc7be58b5df198fd08bb2247bb19397754bcdf63567eef5de89120e40dd879993fa9dabe971abea02b5bf2e01d7cae26b98fb9ea5f253c6db007d06ebfa7047751fe66e471a2bb0781ba873074aa8d6478ca81f090a6134f5808fe60ea283557fe932d8916b675f5fd2f7104e0f652d9effc565288e2d1abea97e5313b482b8f83cb36b203cc63df3eb063c54f2088bb20c6a0d53d982c1803c646e57e6c4a5645b86b71b5890d488991716f3ca3210e9fe4fd7403aebcc5c54c6d59f5a9195d78d8223e459fa223e4f3d54d3c4443b54026128c71ea5d9171b26f63746d592999c63fe4d21a783666cb737351f88acd1428d46db5aaf965f4c55263895018246ad78193ce1e347d9d2fc71b9bb196e79115ad14625e562819d16bba8fc27371afbd77dbac73f4d20d4eb1d748a17ab00e2ef7e51c439ecfa7137c7183c3700e579b1f0ca20f4c2ab04645675d3fe763eb820274538cbee1fbd659e790bab87a9fe7d243cd3ffdce8e3ab157c4b42d354f37105b412ffbdfd0f626f196fcf44084e6d4bef2a77d92b6be9f4cd19a1e48f084982162dc832c36500d5eae06665f241b85467c3687b1ed0c2845fd98862a7426997f70973fbbb16bbb5847e4df7b793cc123e247dda4b1609aca09f9e9e41ff14d70a7fd54a0dafe80dc324d6c8cd03e1d2b7ee594a2c71e8b1bafb227b100b57fe8d04f13377af132f3b0fdc3db4a67163a47a8878f87a98e6956f7346bee24a2f5a3b1a393602e940f21040b4739dc6fddb41024730eb3756f0873e6696a3b8c2f7b507c36e9342a41a774fd55eb91123c54b874fb501b8c7bedab5436b50250f7c85f228b9b8ac016d548680a4554d6019ef68ece514be2a20b8148af168e0980aafe69772a0fc11cbf50c0ee4350d4cf72f4212605477cb2abb6ebf4f492452e194f79abc56f71ff7b00cf68b72a4763e442150a6c507e52e7b47f9984444680f7204a5e848a770cd27cd3364f6e020f2754d852b6fa82bde6f97d41909e66a4855e56c82dfb21d126039d9f06b802959d58c103abf59e90426809492053bf9793ae348d53759573545c3b0b16739938ea6122f77e1a56209edca1377141ebf98b5a79b6c7f1ad3e3afabfbb0e77c4578cfab6104207ae4194675ae9078eed0af2b2cc27d47d66df086a8eb89e17b65a7c5c19e0f038bab8e7f687477b01780ef556aefefe059f3fcecde27e8c1f83b92a4e325e85398aba2de802a6c574824d9bf627187e5562408e6dd53110bffc6269112be727a0bb638f5f011b1f88988faaa12f0fd2de21f969d1ef5e76a3c32b28915b32377a54eba21160ec0e62ad4209f81dee1cd58751967f3529c9590bff1c21a2caedab88c88eddfb7fd7099c3b097f4679d3a79430c2dc9fab2afab +expected_shared_secret = 1c729b8e580e124e715f19ea6f2409fc6de741afa3d9919b2b8bf3e54c053b51 + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = a9c823efc5c946dab44b5b2068d61f00e7b0d87ca67706343927bfe4c12d20d69c4a5ba892f97eeeab7b5a45742cc4ac4d37219ad72ac312051d31b8385ca2293415a13bb8983b8457b8af9dcca9e6322094ca68399ab77dbb9f6aa7ced5f224641c3fa07507da9a08e0d180d52585dfb3b2fc95cdc733a573a888d403cbbb71c120baae2a195278370bf33299b9b2684accc5288a3cba1277fd3999839a6ed29bb91d71a528bb2e4f953778ba23341cba4b9b3c17f9a8366212af3b722397419e24874b163470b3b2b7f24ae62258983b6161c6773b5ac90969c03d01cf4669b9d1f46e05705d4f676d464264d7549e1e2c3290c9b2bf5a71132057531714bedbc7a91bc0ad56254d298908d33d588951333b3cb7924abf14b0d70652c45aa62cc3062d851e45c866c6200df4e74a9e559b9e6ab738f2b0da9693ccec3d968a866f0220ca95b7c6e8b04ec41d39c17eafab77444aad4ca3a9d6b5b5d4611a6c074fdfb01f7df68ad2440efc5588f3b4a5c4106efa3b9b6bb35c327465c7b656d1c1c6409993fd91cc20172e53190dad63ce02691ac326904cbb6424c906bd091312c1bfe6969ba6aabef954b5c8d439da5064a248c92988961fd2254479946dec829c76cba61690e3c541648228b59805d7fb2adb6aaba70718985279452a2fb1414e4704ac3dc84d3eb767101c8f4feb24bc8148316609bf963afa826a9b87638424052067ce8fb393d9ac579ab1080d1c549fd5103312a1ff9988dfe7805ed906fe9228e25942d49484a4510e0ff9a4a54a22cba6be945126ebe461c5940a74e1517c60603b2651e8371973da7051eb7197713f5583ba51b92a9eb3179b45a8a8a5099b40c29f59146f25a563291364f236038c79b784bf09524fc6810f91b777bae252e5b723e8059c06157653e335549784a15553ff9a7a29407d87725aa6b7a2a2669cc776bb810672967cb5b8b9a9ba751a9e69a8ddf796b1f324348712ff0c23f49a1debf210c027995b8a7cc5b288c4c74218e5086112237128cc57f4bfeddc21ed23bad00c58d835b5a3f0c8fdf1001e0ab26c2cad47d5caf2252cafd3520e36ae21119e56fb456f277132059ca18623bfd994878c794545ba4a04436d804231f430b12808fb01647fa15d94b975bb6798ab7c3f6355b9bd50bc1ca00ee76342c8609be0bc893deb398b65a453ba08bef83b805b61945229d98422f59c27e86022da5620d737867828540c20b097076bc6c03e5435aee1b9af19958a7dfb921da414280429da389eefe23fc9578b714b4f2e5b19b792903ff45aca045bec0b3d83c204747a2e24971b440c10119941d9316f45a87c4ab2ac0f7c4bde9bc8ef73a7f42513be3420c56720ddb984cb173587462aed9996d2a848d11344eac02351e6c5a18cc7ae813bfdc50d5b143f4d07ac72a213a0577f9802043a585d95031d017b319358a24b06b7c2ea19f22b6634146cc0a123a8051c51e6ad6a956b1a935ffe00bc65c44a60534d1375570bc036edfbce66255f523bb377b2256c29b870da2c870868299828f6fbbd8e0a109386b8d743a6e7a38384d5933e64565a037b9f520ecf8466f2073eeaf03d1b606f947ca2d2ca49e4b41de9011ffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = pass +expected_ciphertext = f10dab8353de2ee40f5596160fb8f0be1722abb0207aafc3c475de6199bf2da4bcaf41599880c5c55d27ba1d6de27644a8b42748885222a8f6eed81503421dca84978fdd41f0380fc9b43c1aaa4e4a3437f3776d0f06a88eabf23723970ba13f127ec73d37ecff2593627bbb505362b29d8b6c6dc10474b373a7f5ba819bda564e0d7e24c298a557163309ddc91034eebc1a1bc4efa22909819f7f47a42f2deaa4025d5296288bef197c7fc71b4bd2a769a7bf73883e7d0fec631777d560b74a384a518abd2f660be886618c9c2ff82cf557f2c3ccad1dc29b444fdb5e0c6f82f111c338d9ed7b9a6ad148290786644b9107b2ccf3e78b57807e3b77f2b29bc58a3abca9505d3760b71091d0f6d9cf93a0f5932a194a25d3b87c5aafd8b7679eb75187b62f85fe5f6b12480f34d91b33aaa3c4e279a7b6dc837f203106248a49b9202e0676a6e697168b357a07ff4233dfaa42a2fc255220c33514d65ff3f7f8a41a9982f911b918e720f756b0558e996266b26c4dd7a95e3a7ed8b15a07b2b560276f06eff062be366108b7d6be96fdb25cb210fc1defff0d89f19797d4be632b04047f29f2d6a8485afd5303b1430e3cbe052ce2fab2b575fd07188832661059284c6bbd2862b9b707c954ddb05e7cdc447a7f0e102e348f2cb7a6ff9140b80cbafc20eee2282ce3188549f1f00a1a1a45c26d0de74dd818cedade0a1ab1543c50a05baaa07cf5544a338e7e1f9204b8d883d9c14a6ff983c3012b65b781d9bcf0377c9d8ec7167adda2b2582fc0ad2ae9b96b6a92e393023e785018a4317e69d852bee8566efada3e6de2a290949724dc0fa39067e035b3727040b2bb96be824688e4ad0b8f929987af4927fbb9ba08f49dbab197cd320a276740f48657cba5a295db5b599a3a15e00ea17eb9db3d91929029895912e11c5e0d8550343c4b9f414fe0d4517f3578ebe5d76c78ebfab79c1fc6b528f693a3d58fc2b735498d68f137530e5b992216ba093257425c51027d18acff20f980254beecbbde3c87ba75cb4b3718981bdf0b4bbe00eb30aadc8193a7200a5ef9a3f1361e724dae88fa0e9e329c5fddf8e1da9f77d39b512c263380891d57a14003ab607f44ece6794a1ad41d0aae15aa7367e0a74d04f0138124d583bcc76c9f79334ecd7d8db31e70de23c29276fded2afc2495ae70baaf0ce1c28f249e3d21ab72129093b53ab25ab2f6e66e022dc23c5649b210b208dad52bae848f0522f336f1cc732f9b0d157a7d8059cc851853b7fbc5865d6b79863358284f6493254df3fc3076b443e0539ca8ea7d92f2f738a8b58176829b7c2462a9b43171d4c6a857f4a51f1fabd691e50b350a13e6a2042e7f52ea47d810b77ba11cd0facc56a47b03d0f829edb9e13e355ecb8583b12c935a177191828317856307537b5d4457ec2eb19bef36c67499cdc0d0d5a04b7e80da3c0f82f838154f15106515e5bbfaa6d38a9ca997a54990f1f68cdca6d9512edb6eeb5bd67d733286c9a14680f094c4ab6cce15b6cc603 +expected_shared_secret = b95ac8b73c703ab1154152b3ac73f054596ed23d3be328fbe20f936ea95fa926 + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = e71b4ff986bee57636f904c856ac93e0c18775864b7b932af200251b0328f5b3caa38116c5a187305622b4a152ca337ed7a3690c31161862447b847f5639c5851133f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c9582407a0e59a866991564ca55b21a48ee530676a435d26b749c1264f9e58c3fc619d1a23ef5f6300e96665eab70e7350852115f5859bbf1a8308977648ae5cf5a55c9fb42801aca4f0592254461a632a94a9c3a7ccd05c8b7c3b09666be54f072cdc58d8cba687d609d1f021115085c340153ce63a37750acbda01a6944a46cd16cad098464a109bbb611a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534eb80a620c308dd779b074c11f31679ae98ae569bbe79cb04bb127208e24ba008bea28c5db5ec18f31c50712171e27042651701c3004e057a6865d54763843d27873220c174c57154c9a9705da162e8685a035b34e15c411fd1b7220c57265c2ba7579f4bd9ab1461650e8027c0ba79f2ba3f14093cab6015d8cc092905a6b8f09dbfd5743818489ada2bedf88ce592396074a79824457f7caefe334fc84869ff43641821ad60e80407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac382222c193bddb31275b84374cb4679a5ffd803eff07987ed085fbd43e45752dd9a32f5ec03e7b74567ed9674e1070b026801e99ca27ebc0ed24742530507e19b97a09877a1b511da3b9835268ac35ae44187ea14b996dd96c35686eb98a81f1b2ad90a80d0c989b12813e7df2b34573b876289e7c79481c7247e637a60f9b2d3fc129c379a759756408636048565cbeb24c2186a875606a43d20bddd8b9d70781b1848be54a075fe978a3e112a567223d21beb3395921d1a100c578e7ea0455949b7b420b6494688aeac00697ae1914084eab375d86243b50a948874dc973b7670c8f9173228b64647e58761442a2cc90165b188b58025f8eba65cc654575a1bb3823a1a29633aaea1763f24486aacafd611c28774c98d89b3ce8a696e29f62775b5d5c50847c3ad4bb968c441086aa070097508da888b5b202e5a3b5db579943f0861a5b6e2d58415019182262c444fabb77679e019cced4e0a3854507fcd0935bf81b0e8500dc6c0b3c154ecba94d166407c5dcc67bfa6aea8b4ef0c53859ba4416d5c1975c1feb6bcad8076e6b020a62b077f0141deb5ab5986b386d51cb7e8c779654af5e5485a969467012c572f62daf788d1f58bf9ddb4bc6e04b00218cb671ce8b2515b072b76cf253a4006ac5437c107a077f162a3984586978ceb3752b1fa1a2b525961f96c63d7207ecc4c0268a354afb00231b1cb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a53730405c92130f756050771999e469cf07cc8c308ece9b827d7558bf882630556150a602d9400e3d4abb229a9d8b8132a7f0c0c5475bb852000b63228c490472b42488aac0ed647b1e834f248534fe2195adf6952b83b6705593a1e53f0315613d2596aad44e27a26d632b9c71e9c9e5a6ab733c7e81e54db3437d894a19b4710a3cd5075602b176ec369f5116638775574c74425789154b0bde48bad6e52c91c451c87b48ec406674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = pass +expected_ciphertext = d876fc40a1ee787db486792f9ed3a749a6e996dc5e20935d6b76c8cf2d6ee6cf6c9c05fa7d6a37314a06dc4042088cdb68599f8d27958ede9a31054cc6abf51dbf7cc76e7d6b20408447469d5860fa09448f2e54efdccc8d0255cd6d7b759b7e665f0641df729b4468789cf480c9a606c8d1860245f0995e972b02dddb7606b85e3efc19a93063d095ff068112c6bc4d2b3edaf8205b76b8fca8e956e3984f945b06527a49121a6f1754236e70aeabc770049bcc240d47e003f47bce03c988e8c1731e85f307d0dd74b8bbaffc511e74d04db81f04b0e0317d57c25d5a11b9128280a131ee849efe204836ab46820ba4e03710c67e79e0466a506c8eec2834f465c97e0118f138e8fb7d6aaf1c933ad13e3cffd84b6b2db732048b5720c108a6c1f3d576b57a7726cad853c31e4af74ac59e7620f87e85dc2035887cbc88080c28e49d986c21a9216ffad3b95b3391a52914ebd10f0202fe4d5c5fa11af3cac6e4a7358888ed83cd8567eaa4fabb73fd6a675ee4490722cd3ccf4fc3efed41ec07a5409b24864004e1ec0dcdf7bc630d537a9e303334e3353994d14c225d59f4cd88466185f8e0c01724ee0db468c2ff12aed38eb4a14ac13a50c7396fe0622704a45ccfa27053a15ff14046ebffdcc8b8fcbf1b347f3430db409c4b7b30bf138d712ca9177debaac6a3138e6651092473d86223943e889bf89a498fb0c0c662973408e9398229c76bdd59b5f626a2d06f80dee6db7457b917cd1f2a333f3853d1355a214509cd14db558afd1fd061d10113465d1682bb40044879b8b64910d19fe8c45d27caa82fd7d1370f7205669e1c62e03772d2a0fd8844fbf6a0d09ccdf877429d59a84efff509731d38bb7f0c17b90eb54b2bef365a4f014e6ca6f6f90b3e8adf99cb3587d7ef7892b488119cad921f0607dc6fb7a72aa5f33e93b6b53ecf3eeb3bd735056f8ba8a003dbd99a3563e85a2dddb27fd544a798c8bfc220654c9e3892a0c2fd9664f33243f9bd3660897bc41ffc7c862a139d1178bfc94cf067bd979ab0c66e984bfeda086c3280c9ce101798cfb73eed86cae129d36d72f79a8ce1114a3e74537e990c53a5b30b3334b1be3d2646daa719dbb216df3536bbe800db830de08769f04a6b874c109f7419febeb34e1e30445427ec154f2fef4a288b070996985e255a362224aa33fa5020d7b0b086e76600319f79ddd8984fc3aacd54b2a47e3bf115c7d297ed410649ad557e87f880c49cce91403fe5ecba4904b6dafd2c273d847e440d2b34270a3dca4ab85a1efe5318f3a124058399c4e6f607002314534fd603b4e71819396b5c168e52e3b47d347bb2dfb1c0f2f7c2e1bb0dd86de2dfb4d680d16cf0987d644bb4a38ab0b14309708bab82903f942267de8f6585d82db7af561ece89d635bd61dd9cdae73afdb29b6b7bf118294450696aa15601c2882c9a2d406e1e9ac78a46006bc62e565fda3b5608dea7f528b06b2826dcb07a1ed7893a5767891b6f740b1c88cebb26cc970f28059786cf6648 +expected_shared_secret = 8c3851393e5c5997cc95f06da96300f6dd85c041343c98db2e742aaa5f78b298 + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 8518c8d8dbab01f270c3131ac1586bb783b35db82f3c24ae2b767e2c4a7d15c2a86eb19fdfc41113a7501367cd70d73d0f63705487ac4e0bb1c84001fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b52f1cac91b6c36f37a59780e454c50c5dc354b56a43040804de2394bea14c2d385e082c5f181228d62307f5a6a1aaa1eabb84f90f34310844df95a4e6d423d8c993fa7f390e6984e482024c2968254b54b7d3418d6f859e295665262246e1bc8cd6c9b726581cee69140f85c02024c5b59aa0711813d66433aa384b2a4a3447939378a1e6a98936bf04ad075981d93c53e9635b5e285f96755f8689b5ce5429142af6fa02edeb1a719b272f6b0a6211a5b9807ce6ff368739b51d4d9480bd884c8b456569027b08a3cb928645d450c6264c5fce2a2de2b241f965034a08716649a3c71020a6986fbc8bfb5b4a2cb162749264cc1e44bd66223f3db1b9bd2c68744b52ed7bba0b9773df128883110d2cc4757dacaf7f4c90fe02884e1a581d89af687ac79444c9d801d156325590a3a24441b7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d222a5d36b86ea2aa2006c54940a5f843ab708d19d5937643309c12d522dd479c3b2d57dd5696d25615abbb573fdb62eee5c6a6546cb1fb188f356800ff4177c69b636cbbf9ee9a7c7d512ca156490c96b347a5bc2cb257a061452dab5fd15bdf5026677f14967b6c825d03eb782cd0422bd1078b7781624dc318a33b0c437d6c35997a22e30496e876762ba5dcf5146c5188dde6c684c265a8f05031904572f7554123832c78767ff4b5ff525680c773ab3ba1a93776897d57b0d507b9391712344326f090b3d964df8c293b6638fa36815c7cb9b7962956f903f62c4ce3d7646ebc1a8ec04a815191cb4bb085ec8693f2188f490731c087c23a8bc7cfb32fc019d106934b2d17706526cc6f787be424bce5b26329591c47402d57548110ccb42955c422323addb4987fb0f3441558964bf14021a54277ba14c5773a10b81c1427f51173f5c6cbe1b7575a4b6766ac355bc443e479a2953a51f7010f7b04b23e0ca93d08836432e3ae5a1a6bb62f5476c07914f88532cecd00ceb340588ab675f93c286e7288da1c6ca3621ad6a4ae1fc64aa15b27a7c3eabc120e7460737585b5773ab18e23ee185c900ecc3b765983cb807e2f7047e6c999c6716e26801ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d172db81947643a84fd2173fcb0477ab87b57b55899a308d51311c9ba6916f15947d707d88b9228d0488ddaccb25455cf782b7a18264e55c9b6798f39a53f53240c82fbaf461364cd5202c5c94cdff23e0f731624e69310e5b47964b2bfd3a59a5b0d55a026e260731de346f74938abc607b4f579b8b200ecebb633614a46983e60e442a4914c93fa62219025e4a99d71032f0b00906126365c467e0a235570a544a7640f23800cd5f2a825479a632343f20801f1774f0e8b7db96a860fd40a43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444bfe219452c464eeb2914ec19031152cacaa00dd541fde81ecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = pass +expected_ciphertext = 101139d23556eb185fc84b7a91052c0739f48c9850ba8f6886b5c2d4c064d37c525638d8a434f902c4f80b1bd8f87a573f7426b109a3bdf6a1d6ed315e459c73ffc28039085eb8f426868a7b45921e05ee78eff266226b92296339fa679def4d89a2f1d53e3d8d868fedade22da561fcb57297da23688c1617e422ac3a855cdfa30d7454920b68ad591dcaf0a45cf95026841072f304c03054c5322684a8e4b6ef489b39ca40df1d7fdf47b73c4e1d82a538752f59521060e47494b372c8d3b5406fd6e5e39987cdfa03bbcc2f6f6a7cf3d77f1f775c22cd11b4a74b8fab4fefd93a9bcf5bad44993057fc2b8f35d9898acb25ac1574462621c29b74ba64f58336e817d5ad2c9df18f754bdbca516a0b41624ffa2f9a8d67f8ab013cd0a9010c21296649bbd159f3ef908fa368e212232948181b0b8679f658ea55064b59a354db13d44e2d9ffa372492250a8dfb8f1adb1e7593c3d7c3a54c6360488e82ad056071d0562cbcd6fcc82015a9e45109b7d49beec8fa187d4a2a41f1ab0928b0c2bfb20b92048ab9210f0a27f258e90e31b2021a1a94fd0f32dc8911b2ae5363f93e3d70a0e3ed6cee2649e6c4284133c9412aedf464fd83c291c477099cb8e1d7ba347c53a99c7f455872a51204f4c30ae0c41080287a5b247619e2713b79e506e564c3ddb3baf52f15b82733a7b367eb808db1f19f079e9374bc06a0bc6d059458e539cd3ace055e3895e8246a9e888226f05a9022ffadff3ab60bd6a4cae8700429162004532f1bd30843a1cb6b72467522c8e41908ec9c1573551e0b2485c287f48aff967c7a0586986f07c1bce12099d5011a7808b629eae7f3c2e8bd5e79235f958fdfb1377ddd4850894dbd1d78ee375ea3f2165b5acc7f02bc1bb54e7ac58a077c513f0cf17daab0c7934b1a9c3ef073e8543deddd3bca0c13926ebd64823d0ef62b15c26532784b323a67c37e90087a1086955087b1a1a9cc8ec9788609bf404fb2553d7a233691501b37a311968392df5704b8513090bc416d39b5d3ea4a7b21eca56c8b5eceb1ffb124dfdfcb36cb0b84a49808c6105087caa8de272af17df3d99f90e482a704bf135fbcb27c068be5b16d6ae7579c0a046a3c6825df0facc8b9402fa5cfc492c2272f7b325b6b71298c471518de97bed53084c8f559c8435a6b1e9a69a70382f4c35f6bef440a5745dcc98623c9bfe3cedc55be17bb22ee5de49d7b9fe8341137f0ac2907f897a639d816a096911c8c4b84119ae14d459f3377bc7ea7224fb1fb218052f9b03f29cac0aa72daee1170ba56939de8d02d24bd4d26c5814052a125256b083e9e59cf2c7252f6ad6d75eaba807cf4620d4145103f105a6c07f3aad6c4d9ccd783c1ceeec399349d877a82a8d25e56fdf771a56162f5d46ec068e2b7ce7ee89e8565fb95fe3599d8129e3b0737be46484dca61940e9f5f438c1be101ef4aabcc5c23f41121936d0d54af535e53f8880c2a99a70d9a41ac69e137ee32f2eefe7d4aca9c3fb747c3b21f6e7c9eb26214e0 +expected_shared_secret = 4b681fff6a755e1dda908d070f0d9ac610d85c73079c1022fc67d255e36f1f71 + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 5e55633267468551b3ee117792c80c1a802230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab5f11602e977ed051115508668c244a44e09569a13507d4009ab72b16cc3bc615c12ada7c56d50ba6307d00801bedf8526f0a9366869a4830314d162f63ab8f51996663c1138641275e164ddf60c7708a75376bc235e16d5c22033de1a149153d1868679e1825f638967becab5b9644a6e201906771a703b7844cb5cab61748d202d38b5b8f03cc45626027895e23d0c1c1b526c6d519620436ed593b58732164a39639c813f6032eb902b05db15c5d8825c8b11815768d29522536698a751bc1f9964dc579358adc57eb83a0d2201b9b9354b1b39c6e7008d5f3189902964973af9a9c694eec1298d68d3372783d34700b0280d692998b49a9bb76293d7a95363b317670352a71822f415b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b3905df7f58c6566621eeb25dda29d97b598970684c5780f665243feb854f9f566177200f9331ce353cd1a23cce8aa4529bb667d1b9e59b1a312a7c6ff08871cd95c6934419f475c1c08395ce1a3aff83dd14784303b4ba7751054aa59f5710e4ac6039f3168c1b601a5278562b525abb11e66193dc9d34446bbcc8163578cb8065f89b9f43407f79246cad2b6b8b40f16b839a060a95b76855237bab2fa315db48e40842f8306125fb04145356bc50b00e3389dcca26ff048af5a730ac573b5b80331d2597c4188227682075bc0000186b8fd26a383e1bce5c19f13b18cb21602f2160dab202bb07b63d925b71708095daa662cf25dcbecc99395400a79842f5c40e79b46b5384ce730439f537bbc8a8608f61520e120ea9843456118a0a4cf36384832b12076044c65f06c8f8cc31752469c8a1e33dc529ac05485548a6e075f46a089aa8446c0d465bd43cdf0343acc9668fba2a7f7191a9d29be7e9300cef33d13a11edb2b409de297f30b8a7b077fd4ca4d1ac74b31092aded0503ccb5818d1834a734e15b74d3fe550ee49773a800d86f129b4e0250ea1c43da3a3b802b0757c6401ea090f98a28291621341a9d98c67bb001e46e89973f40c1c4950b0e34f07772ba6379fb6a93ecb57369b48b3aca26ef815c615b4a97ac2190fd2b15e83aa10545fb859635d084a57b0268ff085d9ea4b7ee1763b914e67b33dc46037f39815a1f8c58663c88662b91bab0db6758288c682372a269c64cf3ab5c46de2c8f0f1b7780a068948b9480c6af10251453c1fe213855d74675cacc7b162917730ae74ec7a8e7673a7d0887edc175791309ab28e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a2a1c2456a108a5cb4de1b15356ca737369668b0b5c7bc10e22377d6b5fef7515b4f348015872e3518c2676079b8a06de8b53bd189ec9766c04c084e74c6e747c783ff3a99b930547a72fc3a179cbd62b52d46207e79e37d65c9f3c4839d1afc167ae4041671e2c1bf3324d875b78615067dfe11653e6bd4dd5414579ad8c942081db4f1a10b0e1054fa3d79af6a285f2107d4232700676b8a007057d15c923a7889f115762b4c242392ce7c4438c68c6c3fbcccae4a071e404c24274f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = pass +expected_ciphertext = 188663b7ec7e4a08f623c7e55c2148f8a6ff30aaadf2adca46e99287a7f8a6b37a1c6036653a321614ffad06f531cd01c62ae6e3491af8c06aa210c42fefe0edb96389306ad1baf1bd911c106ab8d32d681ed8238aec43591644a19b1f3689a1d9fe2a6798a4ebbb55316a2bd3725049621ff553a688e9fd101e4bb9d1c2cb6f1afcd2189990279af782458152379988be07135f061ff3d3af9796aaccaf78f01f4c9f0a89841885b8a015c6de80788fb3787ecb7ef2e36e9dd4b1d3c9df3d0ade0207cc37e23c8f758248a030d7d2d7c43c00c06711d00de431e53405dcccfbe3b21730c453a74365e7d1fbfff706a2c12b060b5ae1dfe6cb211a42a2f0fad86c6b0b2c70667bee5454434093afab1f37f955b895359749c4e61264e0b18a630857c7c3a98e159199e9fb1fa0fd6f07e2c696ede68333465226933c566da073297623168adbbf6d5ad7e9e22bc55d5c2aae513016344a7f2a5ef80d247ff1c71b983ec3fc88b4e2765c0b26a6614292763c14b8612b63ed0bdd43f78b5344f10a28c5df0b635b2f44f9d5c6496a801f7cfa5db18b2018eee66a664c0bac6bcf39f82e00e57a6eeb57a8097af864ef693b871b5857a42e0a99eba019a8ea639895e1a6373a3035bd3148a7b267b5e0e3ac6709a4cfee2085413dfa55000e09b4ec889f2f5456d4b5b9f42d23695e925643f9ec9b2618e09283c99b966f91284e176edc41265d3bb436a6771644460d97ee02afb7f1ae14d06bee9aee03a6279fcb36d069bda332d586851d9e32e9a58bc12104014cf7a167501b086e120a97498d0cf3f3177c2ff3b32a93916665137846bc21545930423e907329d8b57c2ae202f7a7c2cc9dce39a681e6108e233cd955914047a5e20552c9b3a482c8908f536feb396406001f9bb8e24807dc931798a6454fd6ae43600717ef03bef80e6fa53c2b9a74211dd82ce9aefe1e24f6a4f82b6d2b8d8ef6975c0433c14605357379276d58b8ec11d55b4e99cc2d3516198f4eef6901f70d6d74b96c289496adfb0109af4e3da8ba074f5dc936dc1268836a0bdc000ad8dba6bd9c6deca8487dba9324d07e66b07608dd4d884223460f0414228819c430ac30cba5825e889a07eeb75c8fcede709cb12dfe76381381ed76f89818c4d3e177eccedabf6a7ad44888e298b1eb51dc2f6a1d6bc5b0d71a9cc05796abb534330f1c9dcebd5a8144cc7471df50a684b424d8fe1db0f1351926f6c45c1fc120472f0a35a8332fed29b24c7534b90439629ff7ef469785d851703f070bce95d923a88bfd592cba6975619f07f9aa96733eaf9d3e44adfcee1a226bf5c6a006ea58753b9a1b0679a36e619bfce738b2125dbe1a517c6a4ca05417e267081c26653510a1bd1992468c59f6e56b857c8e95bc192f427c77a6bce7d4af50ae875e7b38aabc08aae9132188029576153204575e28035de11efe643e5a5195a49d50d590436912b25310bc4ac0d9e303d6e6c56583b9e11fcf15fc621e45fe7be1c118896918cb09d0a219e8d5c004 +expected_shared_secret = bbaa67f1dad879f2fb33bd4ead45aec354bc8f05c7cbea1e433509faac022edf + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = 420a3005a17c7b4a08178b83f8540601145b102970b3fc29f30a4ca1a8a5bc4164051931ed68a59efb2b50d549bdc1a65e9909f5aa690b0235d32b1c6b2886ce2959fa189e2ce24224e99255863e6d964d4f422c02646a461bb5abf86f4b4c0975765a5b0ca01081677334af26c3467da771cdf40ec4293608801cad9c61d5f80839774eaff772b139051beaa65632120f00171ad020276a1fbf23517582149ad2c73450b11315ca4b244e7218800350aeb5808da774030635bc247508144740634ac4a078a5af2816e9206a645287de06263277242dba12af2a82ce13ba6787c5ac3020e5d30cbb92452985ae41027056f492bb1a5e23332698240b5038302e552c5acc0443a8795804126e15369ae96cebd7c9765233982458ad6520550baad77bc74296badcd4cc37240d0163caf8c806a0ccc3f4125a0874cdc1c67e4626c9c753453fa37b208caf5f523388d6308248b7688c80f6c925895670a1397880933af0152da1e54f7a7b512aa87499f7a718e62a7cc5bf5687add09060426b0d3cd292ab9b8372083ee462182872815cd740fd69acdd24615110bb618ca1ef662715f028864ba0872b8c199abe40f35f91906a821b8ce0742f931c661c65aa2445371a300e68f23b767382f3701ce685cea5f59c50e82e45234169c3bbac814ab9d68f83842c513a8faf475590b3bac2e3a4685b8f71208357d221ae41310e8454d315670c3a3409a2a95258b9057b42def7a7c6f588f6da61183acfb18a7cedf138c7984b50a940f17c687e5a2f83451d94398f4c82c93a375be195b4b219232e9a766e77040d3b9125e70fa4097d807a6d25323342508f2490a59702575d64af146088f59802aa2cab3537a8b4e92a10ec447bd89f9fe738d92a5f83c2861628601e42bb427b87c2153d4bc44b19413b79baa5ef55325ba8a42e1a88548155d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526df1adbea64930b6995f60181544356c0982e957c5e5186f321b9467d05dd5970a96e226c89673e50a056e7c0a8027aca8a5cd93723353ca1991730dfea1aee943cb0d62537cb5ad88c14f52a78cb6228ef4750eb7db0aa831a4202b178ef47446a06a17e7caf5274f384b36832a07ae0a66069bc59fe439f7b6005f064d865b550505210768bd636c61f0e7a1bdcb3c3065908d51302ee234a3fa113a1a1a2a618750075a6ec277cbdac535fc1524a62e3c0601aad1c46026ab6b8495c1b7093f776f9e6b3b533267ab99801e83bd18570166387f14ecb4d279b86cfbbaf90649e5c514e432561f850497d47c2bda1bc2c398b306751991392c399df6f408ff836f989c41cf76234b9445d9f81f4aaa987c1721c0c726efe44c311a589abb5e0afbc4add9bff6f87597a52e16a53d6c3551b7e6be0a1958a89a739e0717f0a86be0385c5ca433b68ab9506ba3a6e00debeb1ad0519e228b5b2d9aa3c9b4a2bfc8b35bf0a04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996109113446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f1f30d0cd1c40d14b09429215e0c5325bb2b069b85c9e0bd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = pass +expected_ciphertext = cea8231a59705364e56bd14bdfd745a5edf808a710ed23de250ce3d4cd42c931ea20d4a888f594ef8909096758d207e22f7e6f1a0120d496fbbe491a9e7d02f4a332ca25322e7b3d8c5cce294b8858660574748a9eec1a832653b8586c29cff0c33424fb9dedace9204299642f9a34d7391e04be2d2b0b189291373f6238a5e47d959e8b6f1a7e965ecab91fcbf4b5fdd264dec224e291f3248c9bab12c2149139ce73d1409b21c91f02cc9ef9c41124c15796e1a04e7e57d727b9b3d54bd51af1abc79fb6316db1f23ca3e29fbc4812e828d2038408ff3e9164d503ddf3a31ba263cb38ec6b307f01291d680feb21730a7bf3adf21f7ea73e2cd21a2ccbe3b1808039c00d09f60a0e54775510e8121716d6c25ccfa1f0b402dd186a8f623d66f685913fc597d24f63afa8e5b88654019de57939ae9c169f201bc53eed1e5c9a6bf60d7a2ce5d0ff33cc6f9143619e13fcbad787bf3752f1563e9c3d201b8716eafa70b15a7adc241aaeab81e0ddc1945beba409b3bfaab9252e30cb26805e6b42946023c9664764192870cb05ea9bc0692c8ef1408db412117e2633c011ea6ab54ef7750670873284484c754a2d374a381e253d629b09c5402b12a73b90a1c70a4d18cbf3278457039601534745b5bc4a404f17184de598afdc6c38cee8d89af50473e3748ca229715d575ab7e31a05316c02df4d19a594056ca4c250402fff7367e5ce0bc30910982b098360e00a44652e4734e14f490532d5f6ef377d48d69da43d5bcbbdb679e8096298f2e9be4ad3a3dd322f9675f608930f7dc0d00bafd4d2253eedc5dbb1389200157d7b0fe5b49c5f2845884616045d2ca0d4daa45a967606c0e4319e21af8c4eae03c0473b8d902ce55cdfedcec31b3c4923ccb4563834d3683ee3750c39d1782e091862e08dc99e9aa709483e7e0337047cc9ccd4aa1d6ef65a4a4cd1817a85a5a7b0d59c9585073fa0fcde6eca76a83d1cf1f734096d767c9df176f0ebbee8dbb511db823a350c671739dd50913a4220a6d7d9f0d98ada716ac2775348d22f2864b2000adeaf081d730d02246d07f1f1b18d5a7578458387731150eebbe79126ad8a63a2562d4e937c39b9f99ad04df3abb938d29e5dbd29fa640fdd4007964c9e4c27a1b440597a3415c789fa6b241bc7d533518a60adda939f62872cc61ac2e09adb1d3c6004fbdca01498cb37538d5298cfea058853b7d55e0bc3d00bc4ecadebc7ca9492705d7c1db971a8fda2e10e40eaefda7d32338953f138f03fca15d2d0cbd1f89ed97723e8684eb6e4cfec9aa81182e90c695e0a747d2dad465d4dfb7fe28afcfee0a1240858fb6798651a326e0e81e09621da3a529405daceab67657fa4af019191f0ab9898a447eaf02d072adbb028221b509235aeddb4f0d82e84e777cc2ef6df4d3ca6b65b9f40e06db24b62260c44ffa7eadd11e1d05eeb0c5fd163f8595f15c2ab7d3a897341c7bd2c7ee9a0175c113eb454e49f7955a8c17a7a02236778ba7e366d3c1fb1bdd6d0e884959b +expected_shared_secret = 2c7b983d66978be80250c12bf723eb0300a744e80ad075c903fce95fae9e41a2 + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 63992e0d6a8f811b3f0d30807456c84c8bbb008d3b126a31424954cbc6cdbce91e25b19928f4a41b1371447ba3d173915580bbd7899e9adca37b4b5a21e715101717710bc7eec56ec2e58002127d1898bc55f8a3be385d607b3ba6561991ac6f0913617303830da25f0cf0ac14e67abb8097d17b0ad1ea8c6c267adf51a15a9a363d7aa5c8ea535a89115c984ac5d6bfa922c6fc44a3b35cb667f939fa6b2676ba212c17bcd25c82e8172f6a7506e8b77d82cb21d7066da93a7eb3cab8e881a24c7592bc6b656e459af33a06fc2846d71221f1da641004b68bd65dc28a59036ca678508614b15a93e74f89b8af58200d50e718dab1c41c4556cd47b43f14092ca47397243983406e12e423233c90cfeb661a32ce65ab464db58c922bb693f56553961868b064e17a11162a7f0e3ab0b0aa76b8494ba394c902c598c23721dc16c51d46b8258c635763776b922fcac747985b94c006696f18ba49d0c5eb0525cad1349745691320969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960d61a6f94b317d488d2d04a8b42c7fb7d89d52d89b2de30336333c50895348870bbc311611f27845c7775128a9cc831966fccc06292d86b582a18c6ab2fb3cce03701ba91047227a9fcbc6f16130710756c5dc288ba92402b5b7dc90c39193737c206f3f8230261852f1694258d47c469c7452156e70634384825bc52b03e90720066b609a4102862433e2621987e23af51121bed807810501200b776f847ff615c0f594420dc29ca6573276559c1c84b0723569dc2a76728909d9d1279a8c240a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb434132ed5f1340e2c669430b13a709f7d1612af876454f06ccb7841f84c60f3806d5e423cb34b23bba90ab630403a46783329707388a1f4232785d4723c993cc62284d0e35242e52cfd6981268b86f598b11472900f83333c48627d402abba59c6740b4a40abc3200b5d9e13010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6e3017c94ba93c7518f017695f5bf5b99214c8555bda863fdd11d40053c0d652696286d2ba14d569915e4532132527ce1b88122640ad668a20964476db20afca5ca663c6c17156ab3cc8e4b723b3a5209d2d10767da52b2443764f91a7f3aabb35137ee18a1f744562e22385716892ca77d518c4bec578e0f1145b3241c1831bf782c760f9081a1191812790531648954163b10e6a1f02b2b9e17cdd439c6707aab0df09236ba33d9b271196a398ff0b2c9521e57b6c8833489c5328f4866c14d2cc1ce037400dc610b28cd99150404a175662102f9617205c1cbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d3e12f5b56406cc51796c66a6e871deb601cc767c0b8e45744346de60bb160808210506c5779bc275940e000314f30555677689f23009a583cd6f9779c83530e5b2a5a0a771bf1376f0091c627afecac104fb2ba251c074e359e5fc44dec244ccb78423532a7eb27c8313a341dc1431035162838835c85c677a420b67c847dc6605821587c8064e0bc2f4fe6a6b22113e73519125b92b3a66f15564666023ea99273d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = pass +expected_ciphertext = d17ae2301459a388f0adddcc7afd2405cffdd627343e2d01651c3fce83f51eb81a69fcb5ced2966fa4645360d1e89363c3b8104f2799e7a22591cbbd38b2f7ccb8c699bd1c9ed043415bf0f3186a916f854136a4546742d98b1c36084eaad725af2a92bbe8efde8e66a3ae38b0f4221bd7390fb6e99d4b5268dbdea674436f949b4fd7cc00c5424f83c669b3c2ae905501599bb6961fcf2f92bdc83c025285aa3194432fb7e0a1e66ebfd5089db70a061cd8a44527830139fc40e67985412768e74ad81d5cf41411238ed3535075931aefb8006e90c225fc9510d645b59f97c1165082fef535b25bfbc57c38a6e5030a2925b5039b7c3c6bd4e56e5eb2d6b48866b91ccde538bee232a3ec190dc8bb26469e02025bc5659e98ea50813176dfea7f4087beb9c59f825789bba86472714b676041fc385d4773332bec39b99fec6cba68b3de5ee080fed1a65a650c1c193f1dbd98d555320143d1db61db609ad6541c09135dc0054c4056b194321a63cba4142a8f397f4e8c6f5d04ea3988a1f769e191a43c0743644cbae9ee20fe4b1da409fb8c3bfaa2d3e02efff51816c5daf25374f7d5270a807ae7bc94027f8ee673b03e1b860bf4e3856ed5eae78b067b8e1af3cf0c4d9de86908a96472db51e7ee96fc8f21065e6f3ce849b09644e543b27b4573db1ef9e0fb407045ebce6457290d225d490d209d2b762d08e94ffc36c4e717954ac4376acbd322bb745200ca84c3e67115c5ec5566908083f6f9d06fca56996c4ae48e67182fa9bf7b547252a552e037f387fdf4105d147b9919f8c2f9c588bc7787a75d60b57e441687a15e057a379bfe9eae7ef0f222ce5886a7dd4d8adb1a1048ad15efb70b951998c7ff236e5401110c904dee9d34710a429a8bacf98a1f14d9f635db19edf5bb564c8a598de2bd33de9a33a8f96fb7d1742313578f2f83f382545264aa354dfdd9f145914260faeaebdb769df30203e41662e183a5dbb991aed6cfffca5db84058a1eb808beeb3b9e6ec299dc51a0c5a4e89a5cee1be3492eeef9e9e573c427e33291a3fc1efea7943760ed4a564e1b93049902fc35c282e4ea9b39f26290e6c88bf8f7c59dff676604db287af7e3af34b5348dbfebbab5041bb92bf0e114d12bbee1dce00e33bc44130f849113d80e95438de828684c8da1366fc3803f79e893812e81b5dbe0b417ca3426fb994a5b8534e941b9bbda4d9a975cbca174854761ef0f7e2dd14eec51f2926902aa84479044bc3275f5c612b6ab3004771f6b590eafd45c3cfa3c986d203b19fcddda741d6652a3282133353a66c45bf46cbdcd7f996d3b0bef58cf1e0276c34452f88babe26928e608a880baf525895ff3cb1114a5ed5bc4d5ecfe3ea527e4651743e7a036fa21c2794dae4772162a93968ec11385e2d4c73fc13a212cb957e9b40a99fdbd4dffa137926ca298f963f10eb9db3f5fd96744ed1e8c0f38f50a43aa06ebe280607c14ae30ec63bc4750e31a2923680966bf9973d799117bd0f514bce085d28dd49e3 +expected_shared_secret = bbc58d06cc14f9e96a10acb1789d93b93933f1429cc53a1735b3cd995f086ce7 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = 192042d43a4271e44d1546306137a4427130c86a2025bcc297eb36d3c44e7cd4b0b1c22005fa702ac12569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb3a268165596fd0470400ccf5e3b56714792f7a87b9e03019751425695ad70e4ce0b2769571901c6c2003b58152fa9757922bd28a094771b0cb1dcc73741b14b402e8ab86dc0f647525c131e9aa1a9729075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4c015ce5f65fd1042a137453462b8710704bea463204c463273bb71056378850ad28f37ede664e38514dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd0a0417c2655a5476f51a68cbdb4aebc53f00c11e78e5ba6692a516c076330c20d0a09f167bbfe1c956a619825a8305d1aa9ac5736e6d24145924b2409a8688b41f33a181a9e4858325140a797f2ba81d50f21af88650cd0ba8e662077708551a947c97c0a3355852a77576ca5b054d3b0b9fd973dada618bd02fff1cb59eb56b12c71b24bb1f02e27282d21281493ac7d07a20b124aac30b7bcb8c2ff24b2c927d3d62ade0357bbf7c1281fc94da2b21d10a5e5ee07a3fd9cf93e34615b871c8da7db5441020d0522c12711e1963be54739bd43949999083115988a09c6020ca88124b35c34ebfb0743b494b2666ccf5b5235968275fabcf9a054ef92833d8ec816d68c07fc53634a02ca192a411c87dd1f17ffea094b6868638716cf593b33483591e4049e4e7c65c8618b242b17d6021bf0a70c7c59bc81c34f5441b063b9a1d95481e6529602b95f874bf1c649d95a072e70a52e9252e1dd1bccdf64332345355f7cc48eb7dd1aa2f2c31ad1fd58b8b3a711d113c270a90aa2c5c79958f3907ae3ba071aa6144b88ba6c5575bdcf5331729a65d8acf3db97aca4191b72a2bc1433fb3483efff09698c291dd868275dc5a86d06d97305ba596515e434a8d956b2b73b3c00821ba055aa7541e4f35896113acfd9320fa91585f3212cfd5b023a77d7c5c0ceb746723c2c7d7417bfb740e4bfb2299b29f987698edfc1b8d7b33de2c80d0cbcb44f05b1ddbc667005b6e4335751ac281022cbcfac0a55226fa69cff845007b9a16d2b6bab3135b325b12c263a81fd423120a6fa639910159b693406411a289863736557a028bbaa23e0c984f04543e61916d9bceb4f64fd48823a4b13e4f83b43d443f62ecc72fd304f71772cce318c1da9a57a67502a1119313b93c4a66d03c2316c2cc5c2285b1e80c413b2f29c447dc975923d9100bec9db958acd7850ab0777d82814929121bb87a6f4f07880510331ee6171797bdf23850d5fc1802e432b2f51b3cbc37631c9729892b6a09baf6717e6ec39ec2b3489b33baf257c35b9cbeffdc1a1334380fc35df386116baa9bad3a0a8381c4fdfc4b1b98836f23ab923175eaf72c59d9c500e10944fb0fd701ba5142b3cc358bfaf2732d643d0b135c8f991b0c73789c465a7e1b3ea6804b5ab9ab2e42ca1e91158019306855a5767893bcd17e92a41470d721f6432448fbc370c64c3e330d83987f3a9479f000c75320a296393e253a68e0e1c05969784f5612adbaa2662459b09638202b74d8d5cbd2b01a915ab2ad06b08670546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = pass +expected_ciphertext = f597c7ed20fd0069d448c8616f8ca0a60aa23923c79f3bd31a13638775b7b3507bf4e3145221ce3417a8f22282c56862f8ea58cba7a512dc6a3fdc2da6716961ff8011c58c633ce653d39d0399d2e73d4668464a46417545674138259864e639c1f06d6a7a315805340fc277e17d774d3a74938390f399d53514947eded14cbc65f7e33b12662e956478000bf8f2cef30db0b975a93a7383845be2de01c4e87174db7af718e2cabf1b71cb22f166d9a75211bf30aec147c47a1b9d65d9d82c86e2966eb0c3d3b393360e13d085cabcc195c702e1cc4c696cf1860a9fb9b89116a7def1c2215ba5040cc44da0a908209f3554986ec2b60f967d09cbb6291f8fa38319cec24ad9ba588b0c3c6c46bce7d5ece8496313a3ba853ee2060608fb0ef119ea35ef976c77a006352a86796db6e531dbe6598df8d2074b27a170133cdf6c0110995a39796de53d4d7da5068a0090bd08cec831ce7d19b25b49f133b21670b1a43b52ba1c4f61cfb6c9b1ff1d42425501a054697a1fce811a4801aeaff05643ddde4610df7917cb89b82c22fa3940ee67219c6a0d8ea964a4cacb30e3a7d3e9c3bd83b1f0f815a6c0ec6dd8f21c1a49fc56e9d30245baca996c8480d7855e3c87094f1e1100bfb2e45f36698f69c6f2eb13d57e8e40e30f60abeafd09b435717fc89966077bb4f636b6c97dfc6ca7b3d042dcf04aa866afa00a4eb45d92d45bce0dd436c2e4726480cb543d0e95424c3077ac5328d0114a5749ffcfdb48753da9e8b2a02eaa4427ef17fc98cf6298ce7e793910d8b28649a8362a9715eace1cb82df37a96ef30adca9e945512725c4a1202408e6adedfdade710fb80a81c3ea45890beb0e1224763bb018be9f945f4ab02ef6ef3a143edbe9dde24802b01666946785125fd9dfc47066d4635701aefb93360443c5d38d72e5c0f1ff6d3b6d9c0461a91a91b2ef7af8f6533169f6f215b69a71e038cf1add2c04b8bf8e805b1a2a3c60b74bc236ff4f3adbe3cd3d6d1a245cfd080141f54dc036b6916cb5a8b5121b083d7d89d0df82cb924fa847baea59d016847c03ec506bb33f77baa0ade649403545f0f398a9165ca6e5a07eba51caa1a86514e47bfa152d6259570e04fd5a3976bd7a816266c11ae8b5db9330999e9bb1584c4cf669850fcdb064c9d58d959e4fdf4d732b5c7aa7ee5322ba653ffd4fc376f712b8f35e3832c37986fccf33330b1974655d158f3563f886acbdb73f76556c077812c3113246c03ff3a61e8ad973d869aa5f0537d987c0eb001a634b1a01c63cff5c141bb058ce3923d7e0bdc53c44a88fadc9aa48acb254f95d107954b50861fff2b15e9223ed5d575741ab66e6453185dd0c70cf1ec5a3baa6d677cb79a48f54db2d2e105e70809c78b4ee926b903dfd735f9e1ae9aac04c5ce73f34d4b3e3ee562cff04f7cfc383192adab68ae3cda8ec2153887891284ed5399a24d85287ef0a2669abca1eecba26d997219d98a2b81d9f8f91e508ff0d9525aa8d077591823b7cc28b3f4942f8ae +expected_shared_secret = e045e0391e15a66d6208467078f2ba5e429cc586c410ca6c5f3c032c21761955 + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 38e84df3c6a2dc2389897c3745183e08c1681b5b9f57c16aa2c12778528510868964122c1747662cf97d8b0353bf23693a70b3b2a7c8cd5c5508a227261cb7c3022058e318d3dc39e320770724351ad78010eb423ffbae6714999226895ac23735a9119622bbc0811516d617353c7f769628925bbd49629fe0aa333d1909a16c5c27604b7db0b4e602ab27987df23c3718630ba4c2846444b83fe914d840cc8ed79a85b645a32809ca069ffbb8b3201131cb129db9282b73174f8d4a14a37393552b109d2271edda8d968ac3ff67aa3374a2355c2ec895441873325db71c91020e91f19347d965f1410f606862f69643216b869673b5a70583fd1218639b5036cc11d051a13d219f3969c817326d2b60ba5c13cd8cbc9313aab478833d73716a2a48438fc529084c241bcb4fd67179d1f5494b4bac2b05a5767b9647ec8829a500d1365bca7b8ce7b75bfea0c68f8a28edb7bc4a3817c0d32c4e10169832b9abe271cb0b473aac2c3dd39ce895551a297a61f47162d97c41f051d48b62e5a8882da62fcee16eacfb89b98a12ab626e69d77ceb3b6b02878ce346ae5cf754c3f6097e0b5eb7ac80b9b8ccd9418f63e545d01c7d17a71e45ea3a6d927484d4976ca936fe392cf2052535c201de9464008c932617cad94085c5816aa41973a8d21610430ac4b3080dd480169258e65b53e340759bfb70d68b15b868c4098847901a6b255938ecd15d5ea94232b2971e3bcd56205fc6f0425f50ab880821f56c7b25f51f2412cd7fa023852cad04f2704d4103d4362e965473add3563d9b36e5097c982506865454ba30af132bc17c807309723847257c697c525e27cc570a88a1688134f4193db67eff018f54751e578483a77a119210106fd03066c403b3303ce54b39493323c4334d4a7a20aae04d8ef529a15cb7d0900fbc4236c717310246c9cba14d6874beac61b566593b5ec5887272b914ea655d254d595824288a666f10c7da583f933052f43b0b0fa59248b0584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea50b00a5503cb542c254a26f456aa3286b0126350272638ef0b4a3abc56fc8d0aea2f7396d97b64c56817d58c32103996db88345d377fb7b2644fc99a24258c50730045b897ac908f7fccb81bc2b51c286899c8c499c1757c6b0a6ac0a8482159d564cdb746037a1224ca72177f79ed19a398040426664abfbbb7b7ba99906e7982b665a551881e0f02a97409a3e2acd37fa96a4f9293f786a11b21e1f0bb22cf400da06081bf68111a9bb64469487d4cbc10578106b381b8b054ee29339e1830dd613e19a9baf9a81c2b9ad1d121a47d40234bc9d4b79c2f5f165bab5a2db68c59c0737e0e4786990a92476aea44105f3c77feefc342b458e4310b9b110a8b2c01593b512f069944828a3f6a219354bbdbb1c344f24aa0784160ca704bfd89c4933b6123c4434cb9a6ce16d3f042f1fc571db728119f6a33e4a9f6981193d60be6ab916818b8e1ff9a1d1a59de8824f808043a1949a5520b675d8834ef65c1d47afde2710c6b63998d43ab47a681f0a856d166c24494081e076d5fc05b541145d3155e232a5af0ab96ecc0b09c2c41e285d350500a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = pass +expected_ciphertext = 349dfba896178907a635a6d93910cb4ce0ae4089e9de6c1092bce826d207f0c09a6584f829136258e4fc56f90c21ec74f1984a23afd3515e45b45bd34120e761682de9d9b71670eef80dbc1d5b0131f740c708594e8c66d8096a571be068b6333075773f92a082d2ac79acf46b19de4d595b3ba7ba407cea9d4901617de4f13679af9a45e297aeef0946c2844681134a6d869ac2da7c90b089f66a805518146ec3bee2cd95744d0d2768a1daf931928e9589ee8fccbe3a44d010b794149f0397ac81a7bef9ff5243d98b9492c220e872ff5fea295102beb6f9381815aff179c0b2c26d2416aa41cee61ead73a2e91578d584c8c6bbb5c154a12b94cac64afece0f7081c7c2e071dd1e63e56b44296578a4402cf3775eb713146f13faa0d933e85030d0bf6a26f906f12f826c1b728811ad3ad141b4303763d2e9a651cd6f968af3ab97207b6d17f95c0b40fa6652637d8b84721f3a9802645d5f6f828000e58a4e5bcddf3d19053bd1f8f8b6b125cafaabc09d08abfc852858c7b860542e3b08f4e6661e0799d34ef209bb62df89d5a84e9bfdeb853410e54dedbfe0bc9425226d9aa4b00c51eefd9c2fcff48082e6b65720b45e7175f3bd9f1f4948495dfd9ac595d9b485c779f27af8d4aa8b781cb8b332105e0f38ad554696ce80c4ef5ff762f506214cc8e1e3fb1d7a230b20aef8e55543450eff4289d401861fc37c30d64c4093a2d512394c07340d814aa25476ef992919e6fe58577fb6bf70c6778aa976742bbcfc4677d44b79fedbad1424641915e8599b8bef53ce2c8ed682a1e10716e1d07d546801a7eaed846ae94908475ea20eafda70be83bb7e7211698a2ce33370b83da952140ce4029ef0491d8d039fbf1996cdbf1d04e576c0778b30e83572d05081238743f5b4ebde402629aa9ec70399e364aeae31894e56c397e5430c7250e80dc4d0b749a276ed02ba76e190bb17a2740f098785b8b0e2de69d65cad3e770d853316f7c5cfa508a7ec990c81fb912d1e5eea2f0857893d5e10a1b7a2031169de2ecf3935623c769652de3c48ccc671dab69bf992226d95fa549adf29533f6c58f3e79bf56cb5b0399c2ed2a5550e54b4f9cbaa157719c47f3db6b7ee8f32c04d830cfc4bba8573bd3c43c5f9069704448649bc3e638e46e5ceeac812d356fb616835acbf0711c31455124000d451926c1d55ee0b44295d2fbec5913828b5f4ac5ae3589045192a0e006b3466d8ce6347019f0879e4bb7baff07e53a95044525a843d7f6d91e06f6ec2064b975c1af4017eff586b7681c8c5f7125b6238703bb39333ef122e281229d9c67d495eb3d2c6ac5f176caaf3abc6fafaffd4443c353972b5276f4cce612ab4f2d11fbd30b71974655afecbe8814b9fd088655f1da3a3f7408b36c9292a6d086fab471cc98a21888298fe7eda2c5a1a732c7cbdfa70286ca361914ff83657b7537b84afcb8ad0c653c7bbe623745e95a7067d7cc698e80bd94bf02a0d52b1ff03f22e5e4e62af3fcf152d5c35a20b61cbff2a +expected_shared_secret = 0b8584b75838e084839d58c89cb1749e82ec06a0e85464c7546dd96870547d29 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = be390596bab505e51b3fc147af616e0f94506635a758964b3e7cc067b80827db21dc87450fe1415ee41fca8a2b56b355fff13616622fd1a19a7cd98f5084610d1ac9f1b8a6e78cad9281a0afa5a7c2a9a87916710ec9c5b3544b76b4808d01399f219b745962536026c79841f11961b63c10c99074edbcb4ed786f7e8c3826609533e5bb4cb80f3e515299eb757c217da2806d26664f154c0cc2b4a644b224933502adf5a66f5b54cd45a71589219aac65be0623cf5b4c0df17e72cab64b91bfbd903d75e164e2a0c9e2c997f36a0b432177de617f5e6746bd82984bb9375b4a0a12e96d06045a3a984667d03d8c08cd980b59cb2b0983b13f9c53790fd43653e78255882f9b0c980ef6b062789332a6b67b2b78e9e370b78181531846b9980a8af905fef403f47b891a6b440ee71cc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36613a15f147938d32673402164b001975d9c4a8ba5ce84d20b47f26eba5909183c6fe1343d062389b9b99cedd21e30d5841fb68f3450a47f4c4be5e8c413c37ea4d5ad629141d7430938158cd04492bba8aedf7477ed13a0b97c8217a300dfcb22de05449547626d21409f491098162d7ab477e3ebaf0e15124f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb6705a467a3d4d9102ff2b6ed976ca9d856e9f257d5d586c7d8a4c2617dca73aaa65719a21538d9e6997c5637df8c5a2ab98a169a5ba8f708bba55f2c0a9463c9b4ef0c9822fa64ecc72c8bda4030157bde5073fae6a6e6f036121125dfc5a9dca1504a1225e6da9db4d0665f6413386153ae25be78b3410369bbdbd84a86c6c7bc924dd70005bec0c54e07b4adfa2daeb8265dd98bcb8968a2f683a3b07633aaa0290550665c01fdeb22398aba31140fa7494fd6a0087194673f51ac7d759d649a2fa4d7520fc67138f445287b681f5c3d1678b497129bc6624163e3515c8381e85c173d6a4cc0038dfc2064a213c557931e2e7138fa1a6bc3eaba08965bd803bd5759332cb1bbc4c41337bccca153905990970c261cf63a53204b6f8cb228d4234f08837425a82f1da9be43775df88a20a0381f70044c76b3524b437cf365cb131baa14ea6f24502336762c8e126afd009e1997b8b3bc20c246070df7b33bc9a7bdfa8ccd576925968915f186ca4a5a4934528dc75282e246b0824ef7118d39dc1f07449a218836d47cbb7365b677ec7d6222abaf33068b5730d9e674cc008125226cbc5382a76a9823db1b42976c5c90c23bc02eb7b874dff93699e6035a838b22a7126aa42d62682505f9bbc77143dca061f5c38e99652fc2e28e30ca8d62127af02186bd9c95602992e20baa636ab050ab870b11c52da19b3a68b7a07a8cfbe7bb016a2537e50464265ff6f065d7a8c30f659998a35d79032f887b4629d07bb2dc895f09ac0387cca9c5cd1aebc08a687798721f24ca43c2c5ad42d1b6641838efc2a72ef210bad10218846f25da336a4c00c4a29eac8a608f2261b8c76b18f10b7aba755771376dc7b876152f9fba5370262919511d4ad50d76aa5cd6566c29225dabb3b668608d9de5bac08320cfc3570a0ac8deb4bbf3d941f9325aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = pass +expected_ciphertext = d0bdfda854711dd009645b9d16ca8d8f4e44c064c54bba2037633599d73cd05e6473dabd029e5518b3b9a39b6b01f6e36734b5dcd4f8aadb4e4ed8e343b8abc4732753d7942f22cf1bf6e9b7fe074195d1c8f414f856c8175541cf0745b755fd58be49ed7f6e8c48ee393f508eb373e79a8a06fc0d5696bbf3f8f8270e3e2b890b90946fbbfe694c34d4df5e70a92a2e6acec73fec7dd90cdc7ce99dfc563e9bd766779f1460f4776d7fc223e4110ebd68bee47a383bb5adc2258dceb67fabe8933641d2cd6f973c157dff849f6e190837fc795348d9e78b3aee438acf7dbb960f6cd9de2630b730100b913e856256c3c5d71da1c83bc29a584bceecee94a3a1e16cf22b7a610066603c14d44268dad9bec3cf53f72a0774ab0782c0cfcc6eceb9413769d4e6f531656e5592412152ad35d7dd7253b3e9578d11bcfd7f0cda76f89c5a3db06236c73f580d7ec441f67a67aac3ee4a80f9f56b56abf7debc9ce34dbc0bd01d5cf3bfab83a06754ad655c1610137071067feb622ff6afd666b74e52df3d95cadf8b05c5e2a20e3821d6e2620f778cf103af079dee56604169f3fcb4170e5ff130bd6365e3a6de215925f4388204da9579b40e98d5831c43fa0d9b60fe2c9f95cde75b2b324f3353206a3d978b805e524211f9e257ef0ef5d391e4258141b489cd52c8e1aa96e5ceef558308952c3ac6b9a01b5cd6f712545f686f9542632e748bf6b492af2c94e8686687189e2b330a71de41e1a9ee6e6d74b95989dc6412302817081b68d1739c82a2f9a532a58c7ae6fd5934d04aa824c5d1ec5201b755b3761a3756bde866b085778597087f99adccc1ca9fc04fce92a423631d4756cfbc70b7b1b96ce5ac56bb61cf14d84fec2fbfd0f62ef4691603a55b114d2216a24b4f6ab07fdf35d7038610882a7f34cd9958d94c9f0b99ce1e5601c72ed128db8779ab1c3fcf8bd8be63c01dcd14748a01e1d1232210006f4ae5183904137d04c9fdbc76e9cddba4316c7cea1eff42e9d5e17dea82804ee9cc40207e28cab35b342bcaa802555f35cb260cb481daaa76739911a4260f26e9567033d69337bda9b11f6a1f88cb65d17ae0a5cead6cace4b93a1f8184c6303cbe5695d37ebd3a7e27f813ec8afb0d18a72968048d27f38cf9de4cbde27b674a672a400aee9cb90c5c170153f56dc3ca8f01035ad173e6931332180fcb2a74e4ed21d6d27cfe9329dc4e275416be050300a90c12cceefca2bee8bf52c71803cd8cf39e29a51b60f188bcf905eb3c35039193d2d0852a62c8543c82f3b2b3fe3e4d51e752eab0130fa0b89f1141dc2f1e73536b8a963022c2a7914eb8f80f9af9ceaebd96137d17c3172bc2af2f819e0899d9e55fa39d6a6c7139a8a2866dcf41f46a78beec546de4b4b47f408128b9317b04949e6b083976cf9e0fb6031a8b88d82f0f6dc64cf5334483a339f7b1f157031a13c751fc62805d6d01295352df2a48c1520fd40e2924e8e7d5e4728dd21cd7069f85913ed776631125846e2e13301d8ff7f2 +expected_shared_secret = 3547a15b5748990a5436bdc4db283738eb7d64bdb6ff566c96f7edec607ccc9b + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = 99315a88d083bf5196f65cca4541bd4ce3526e514dccaa8ed176ba58014bd0ac486056240ce06c6c182040606dd98978d6cba367eb0ec18401ed348743780ddbd277f2ba22e1b34208f215f8f91a048ca497ec37a7663587ac85f221810e64acf87478a101062535287250907d0854b93a9d4bb39cd5788be361c00faa87bbe078b26353a51b7bdba58d17e5496efb263df826a59296a13535abd799cb931fa5886e35476dfff97e82870653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b27243c42634045506762ab1817534f419591b04622c650b828b3d4a66d9b163d09847bd172ba8ff452759184c07b11183665c0185e0a089c957135dce64bda52338b6492a27a1238aa567f017dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02901b73885557cba188f72ab5a35b489e98ab377691033934029118a34af7d176a436139aab3ac127a8f510c8719936e8676caac2211c8292a42f274c7fa85c542b21422c5790079f34a26f0678c005818bf4981a2b4c7db780c0bd43ad55c0acdf1ae0e0761d7527813076f3174a1d49c74659a453e09c2b4468de6f185d5f3c04f2b7e59e05317586e743285e6817283ca11faab44271a4667912df262c0c03843730acc24e80e2ee0251cca86a83853e6251e3036714576b1c171a112e7a15ca215f63039aaa7632ec77880b89ef8a45cb0b3746202ace1d7221fc98afb73a28a6ac2ae443f16e6072d6b3da1a3be5fac533a9175a5f176fe131f021795f8880d320c6096ab63f53525d01b32a2ca90e1a9138e4ca72502785976bee4e566dc0cc1f3827733b0a7d00cb58b6b89c5e26d2da00429a2450e269da77c46b5c954cee6bdc0339ba357a9b9951802a255b74a4f4ca1297d124056147a0f8123eb903071546d2c22723367308601a22f199f9588734fe1241450a45fd7395df965f46574a030581cc714a50c08da03a51b367b524a2ee4e56752db9b66d9c6b07702ec23bcef798d68300859383c5baca9d8f08b71409ae5552209b5237e697ba55328a1693af7fa0ba27020de2c35f643514db292c061c8e2085d06c101644c94d17c07560811c093afe61c6b4ffb970382ce9fd25f76c6728108842b3841dbbac62504185edc32dfb817c45878189a7ac02859eca77ab445797e030e910243b121a859a05d8caa3c32fa54d033714d20a771c7cca73999f6d91d4db4683a9543d3c978f1d56816d75590642cd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b8290078e2c0ac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4127a214e5532884274646b91f49a1e36a3b42cfb90b27425d2645c5acc2482289d0b4b84a6359007f23b9f528718e6c499590d6bb2a5bb674e89561ab1a48e3988927ac41d05ba143799214701b2f6d708d365be84baa60df8bf7d969a425c93452a0277f218790c80c60b4b59fc6131e7865d1135ac84a6655507c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4152c005ecc44fec299094a285ff50b09388b6ac3972911cfb8ecc9f0ea58761741ed23ce16fc02af5a341f65043f0802c0353d987c718fb72d3d922cdc861bb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = pass +expected_ciphertext = 65caf8276607786d9560a0d97f5165b79d5e4c80e07999acacee06bb02246f54a362cde4a2e7ce7f7119e974d8c6fff713df67997041a7cfe52576028d2c90a456390f6004f6e7a5ebde39dbf7aac49faa5060dad9259525da2b466d7da1c3964e94ca16413d7a1ee28e7398b31a0595bb3f06e8eaf26c350f27d348e957bb7ab37da03c120e61be9c4a7dda41775eadc1911a31bf30bda208db0e51dedfe7ef0421f35c2be9c891da2c636eedf8f46395c1ea6d87ca96f17387e444e22a586b4e9818a6cfe7a972fa3a6acc7583be04facf1b9c76cfec8d8d9d4456227c3990ba386bc3b7f8fbdc1a492f3c1ce46424248d6da00e9ac3f868312bee1754539a44816d85d9d2b9764d992728837c0765b9d03c7e8a070de91c655bd3b2cd1268f2a310ae5ec444281e87176678c6f0194d2640459a2b9a7867bd519ae9e092b28910dc45a32190302d34dd90bd068ea9c5ae9443a990b33818beaca0b6c64fe67b847819b943046bba7af092f05170f6a87310eaae2a813ca69fbe6b20fb7d09835b2a134d29b1018d6d05d03119297fb0c53526514aa14921b6cad0b89117cb9b80ff669f635652f67b8e9b26900278ab879f2dfe736284d501b38a48286e29e43eb90f3c6162e3db81ac69722145cb93e57ab98cf7c981ffbce25923ae7c2444bba4bfc007d1f7bfb56beee3425d6420a4c6952a70f85941565c83d9175b98fffa2b44a3edfd3d9665af0ea523daf7d88c739ed491680c1fcc0467c7fb2a4626d26f970f034062acec4ae7a8ad10c3ce34d6d2658a2d3be94e97929faa3e9e76f20e8e1ac5ba996e6bd2be769213164de7fa49d04e2dd010bd56487cf5f00210ffee81030434658e0cbef81757fb3845e3ee5bb126fd6432d19861c9a59a1382a542f5607e7686262f577ee7a5fa51257c286c173e6694533dbe4710e3a9ed6516b61f572bf9a343c0790af2160c97d21510df91ebadd881a8d3b26d5449ace1aa07ad01a192504d95f4b9c352bd000313273a62d099b73d07bffa85dd4bc5ef80b715186e0de4445d30a3eb38059ccf1c3a6f1dde918bb6034bd58975bd891b96aef7f570e9b262cb3b0e9cc721c4e151c1cf055a880ae794acb5bec31b855df972c7a642c28a15339064effa3cc97a9b5136f01f1e8d10b497d4bce88ed4776c23dbd1abc690a233377b39a4559c6e19b2b008484ad5e0ed9b0d449b908e20f9b042105064fa5fc2549e680f038aa3264df28f763db9db51e5e31bf8cc057ce596e23f8dba50c35f44c50e15d08f80422530cf2dafa1e0b9d250ee61b1672f2d01f82c81e396dd1b5d8a68af3635974f0f27242be9e7573d0813e3e77e1811635c0a9341d8647894659cd00ba490a1076cf2ef0c5c605c95cf8ff51ac83a856c45a903179ca136e38425fe005bc5c74aaacfe7f10cdafc5d9690d5018703821b168cd112a45cb92197a50e2dd989744a1da2e70c05ef4c770ab75678ba64a97521a112f579f9e57aa6d966777e128b979b85248793655296fcddd9c8e0c7 +expected_shared_secret = 852ba9be42763c5a74a75778eb839a3738a8ceed1520b0588f9dccdd91907228 + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 2e7240107059c16c3eacf4a1a8342b73911db6a51d3cf12bb168229a1b29f7c334d0d1ad99932f21babfd8153bae937fdd2393d9748518f12689ca7627a1041d868094aa7440c6724b4430ebd20776b602940c9d1fcb5a109978573434da891962b645002508e46992c0c148f5a039609826baf5834ba7271c443b69dc5110c4b7089068d16202cbab2e1e4525738a19c8315fae806fd139be91f4c1e192a2c04983291340dad4018a8a83c27a57c622408f933a51b7618148b16375a80e0a901f10aaf6e7803cb2a693abcd4ca8bafb942086f42f6b743937098e3d2a607f212f766603c9d89accf7ac584491f230bb1108b1465b865f824215d79fed2525d7e95c7976946e22a9e6510afa2a9e8af29ddb65c47be8820561661050b70ef3b7bb249b7fd0cedd688c37d7a3de667626c2b389b38be066089405703bd51fa32199e9c83d5265bd62a2aa2ce521b69973a18777e32151d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64c9d00e55d814536171496037036a078d026164d7b07e3277b7ecaa770b06dd291b9ad29241c3bb43553bccf66a1dd81fe2e2bf79f1a21e1539d0bc517a9ba8ede2c39deac4cdb7c65ff96048461ba2e350017095a35c1bfa25c242b000affc8af29495a2d349133c343d680eea815cdcd89c4fc283cd5136b89abd473b4aefe2228f4cba5e0c10ec7a1083833735f081034aa7bbf20c11319ca263b52262096e505c45805e73619e2ceb242e559883d20dddd4120f0c9e49f4995376284147cc2d2a96a046bdb3f56b6dc1889976ae1ed732eba43af5941831b2202d6091c16b680001a82d98ccccec212b79b5a884756c75cb2545316fc072d903c670864d5a13534e545d836276ee594d3a7841e5f91d6b738d97e73a7274671d6470cd2719b0515fdd67c6e4969ad213254502c5ac9ba23c264a375237369b46d0c45745041a20511459d3321ee9b395978f2c575ebe1c6caed03afc7027bc457e03f527b0ccbaec71850e0955f0a2b54d9bce69b6c8fbf90850168adac411ad5c973b578424c55ce01b3ec2825b0085232469968b8a96fe7b9f26846f789323a15aae6397242a712cd26b0465bc038a4aa30dac42c0036c062c21c3a4178a0c92b8992cbd54a6044b789d943f1eabb0bb24c3d0d4c067251779374579b27c84fb435e6c745334485fba84676750a27c520f79366d008e4be93fe8a958e8d06b8ec323bfd5bd01e86b1f13302eb17aa3aa8fdb3445ae5775111b2124e2a35021c04945661b2c510a29264ad855836c7d8eabc069011f8814934bb4b32176c0b59b04c5fb6cdbc8bc41b0bcfef4423635c0c7ac43e4d5286c74920ef37c951266b92074d239b2bd0a0d6c096141fb6a718a213a3387d75b927ce176169738abe0cfa6b68d3b064157c3cb03c5793a7400c1960351b059e43a7f1b28ae5073780cc606f7e40aeb458dbe95a31c23af7e760001b0bd601647ad1805c4329e46f490575ca928fa908b5a30fd31520c61c9f1cc5ef18578b350a929164de33b008338180ce41c45327152090a91b8c9b3928c2629a48d78abd1992720e841a52ca91a15a1c7953d18b4ba1f990af34ca408ba2d449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = pass +expected_ciphertext = 9520fd68f1a0428cf46c71f124f0e6f3f21fb2d5fc390d54127819c49541346d0da18c5e2d1259564aad5a1709d33a87ac8f070e9509c6275217407bdcb1802849d2d6428878a121717b6359e8aeb075304fdafd10a6e77eed31f4dda3dcf7550abc55cdac8476eccdf9b2088559a5cf7cd00c426e9cb3a3d3d533bdac13ea257641a324719a1c92b3f27dbcef88916fe9d7e7494a3b4134d5aab08246923053b3500dcec963dee7d1e483c20224f480fe6c2606facc609e7fd47cb0d70116467153719562501afce27d9d08981254b96836690a369c9fd2cca3ab0399e8eb794295cddf714b543612303b44b6b86280feb547e36e10bbe4fd729f3a93297ad20fbd53b665c91aaa966e7b0e2e143505f4b4c930cbf0c19766e0f045fc3cb21b09df4331157a751c8daeda28a8d515ca09c53dc37bb9c1d6b99c4689316b79f4745c969f10be1f601b81b989ef3599040917d23e20df69b716794bf332e9a31690749319f08cd3de0b3fa6a820fdbede2c8af4c5d1cf5176d6b457b8f57d18821ef22d16544f4b6f3450f87a181fea90893f917f379897ea322aeac04ab1b4207fa1723517e4831ea7b2c8918040c995c3265748931bf9bad6f66a112954de7fa799b75ed1572aa999d91232c29bae2f5372dfabc7bc6d5dfcf96e02747ebf039adcca1036b4b4b13c59aa330f817c2bdfa29edb911a613f5018128f72dcdc73dfe06ead3b0bb323275e3a74ab23763992031f66f20ac134a9e5c781c5948b533b08d777b4cff4d74edaff4cb27025592a670ff2aa74332156b4917f7ec0da54d58fbc7cc63b62d3bc1aa420b80a7bc4cd22a237c797fb633ccb0efaced8bead400b623e0f99d2db72cb5f9e8d44f97470917c303f4b1543346c4482532f795202c131c9cdcae8aabd5df2f3201e9dbd247979c1ad198ffc9aa45d20d052f48d3a675fab69a6e33e1a46f50413bfb73f377e260e5b150a859ece8eccc1d208bb6f9221e145f1a071b3fef1d6c4ec186fe8eff29129a31a323e7c6769eedbbb125c57b4fb13272147f631f5089b6b49b9bbfca3c20fe7d0955b9f9e2bd717a8f14705b5785391d28064499c5c1af95fad2f57e339e14498e1b4f2c59265223e7362042ee6f51541483254c9184130e45372be466796a6349cd59a002a3f0458bc72e824917a13d32efb7dbb3898a2cb830214388db9ab1a60b299e8671d42e92b096b704246140217bf522ea5db18d65480b23cae658bdaf48117aaaf3f555aa9521174247a31847dbfa4e592046fb1f4e60606aa894b2e6a78941c34fe79bfc45143ffaa8954388140e4b369a224067450c6d6e6e39348d8a00b784188a6229e6fb983cb103a30c7c8bbdc8ca658edf638a6acf29c6df500b91ae0c9cb9d8beecd9b58ce1ac8d1ef506d1bd5961e7080e9a78d37aae5f67ff01ab1f4afa1cabe98b5fa66e8f8c6d687a271c58c6003c6e499445e4fb9c85b6dd5ab4af31a33b3fa4e76bbb29283a9bad6ab7d9d2cef241d30fc01123a3df4b47fb270c222bd5d +expected_shared_secret = 618a8496b8850609c09dd1d18798ee2bfff3ed7ef6f8b8034fffcec98f291d69 + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = 45fc2d1bb1872a743763f12d29d937f3f2a41d257531c1172af59c90806c7e5a15972a8cb9dca049bc92700a72b4fa5a739033437c946ee062aa86c12103b557822a08084be63c4c74d1b92608c3b02c6520b2991f8499470114fb659f89a937a25897faba6c0dd142d8d4868ee3c6483128241b287cba0ae49430dd6a28d1339605a4b750e6029f73baa1fa8ce6219c36a40e5542ab45cc781a613fdf416502743df8cbb3c4b864d0b448a20c0b0942a829601f2b131fb038587a99b80ef44033061b2e4b8f9a12c3c03193506b62aa1c7ab08569c7d0a88c8a098f87061ee41000fd202e2c3af4e625b34787bce55f74aa58eeb9124de7089e51a581893354b36fe035ce5fecab74018ee6209b75fc2702429c932abf71d89b8c82c047d77725cb6ed98608f2ba0b3462c1d428352c6376f6269d9869aff4bc821870b63f2284d296677b6145683ba6282c12c72512ef015eb19ba86b3571be7438f17311655c118a530266bbc6d9d10636b6347c630607864949dabfa558522c100f6c7941a076109253b5ffd76328c99590f48b3fc7ae7a5847cc958fa5523f540ab54ea0a302174e6c401341759c121b355c9280d2ab6a84f9028634bf7e3ca90679aca188667d5086df35b88d95b262e8478561a414b627f43b0fb8731d3bda73c6396594694a9f7024cfd55d3ab88342516cb34a922e6835eb8c067bd35ce0b3711d7bad2d7529464c493adc40d8ec8679c903e8984850034ef4a828d3fabcae9474f7278cbe79c8e5c1c948b94798d4c68da8255237ad8b0b38cd4a8dfde5abf6b2cfad98a677a8c40e208206774661490c3c212d23327a46a23dd6855275b78d29830b23900b13c638e31b4745a917d4fba95a04956c371212e475271ccf94f6295346118806316ec01d08454b0cd922d6f1a3e4a651a7a931f380042a09244bb39973ec5872c28c8d41c4bcc72ca4409a363c49995c45c7909522128c03814612214a5eb01527b67bce4463202cc14e31225b36a7d7d10e26966beb389877ac0062f9172c0517ca8676f5a44a10106fe75a31a4aa86688c075918a4d8a7461dcc1ea1193913c259e3b44c2d976ec67613468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cb514bf7178e14112c8b31727a38bdd20a5ad087746768957f837179d50d25f6697f4a88d056451a593e385b74de8a01cf0244e70ac9ae36b2d76cb91e5419165c6507d141148869d6676f28645653bc78c96b9e7f382cb0c6768e2968c513c7ab076928781a6530cd3ae3286b0c681743a58d9c524be5120c880605bc139f672e30174095932a000800d58a926cf40873c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaac9f0344c9b6bbb25cb0aa084f616332197295163989e1448784082c327075dacbb7d912025e4786710b0c7452f827aceda11a73ada09c3e54b404419dbf3a8f8b6096a73528dc50fcd230155a97a614663174683d1095d97b7c0e994764df2095ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1ba061302ba9cc20cd46f769e1021c03c43ab07bab1bb0c7f3426d252a15ed5a27854ca7b177a6f79502789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = pass +expected_ciphertext = 027cf1e2d501b25ffc3a13f5a9fae7f3535a8749d0005ef28c3468d95a2931dc1d4b6908ab8a4d22012d7ae11b21d594275a9288ea7f12fd1c5a18c9bd13741ee16bf946383c8d18de5a8008d98187a7b55a42685a5a79415cc55dc2bc2b81dce12cac0494ee667b948f6bd14b8503a0bd549f54cbec3e1ff25aaaf142e03c8461f8fcfddd4b0ae1a8eae7f6eee9915df2f80c501dfbadd8911463b73d254385dd5c6bf96d3295495b27788822759e13deaf2665b6c5fe0b2d51425c447c7ca06d0d86e803194140433bd02877ca9e47c23c28133e4463fe0bb00292929bb4f7806cf8e71a0b3bab86fa386fd0611f96d6b648a30a079719a283f02116db38ba5b32778f15e9d65d11fcba269dd19f85b4de540508ebee0142a10c11bb0814e0fba0b4d0d951d0f5ea38749534f0c3b1f6d30ed9c17e13a817174844d21d399b36b71241e1b49e2ae1937bc6d1a255f61230e2aaba3432eda6da8c0e3a7906f07982c5ace4d484853c4358401745ede71fd8984acae82d098d9c72a0f8ed9ae7a0ec72d69cfcd56197f082bdcc04d3b81c2a10dab91e3a4e4c15b815d0bbc66451bdd5d7293d0f7823989f7d6e2704ecda52db3562cd2dfd139e0e30603c7f3317aa2d4131ee7bc1f9aeb697f4201505c3c102d42def728dbf05a9d55714da3ab5d4e8c0a0c77439118f804efba1a3953972a62ebf20da30ceef4dbeacf69746baf9c392ebc4d0ace031c46eb4a7fd1466ebe992d6262ed24779c21f17bb3c20b63e716ac68fc90fe5fb1ecadb031ce87f6c2d13abd5c2dabc67e726782f44498eb1dae0b601863c02f13d3ab7eae309c48369fa77a7ba1f185547ce10696da86e2668a67eb3283074c4e3b7b8fe27c6c81060353eaa860a89ab08259ee015deda20bae823e0c15a6734e835ab4e64b540963753782db41b9451083ab2ef38e675e1a792678a9b0a42bd35586576cfe78cd86450db997759dbd4f9c4989b777272ad6adaaaf4dc32199fb0798a11d08a006a47ffea9d8f9a1489562effd9741dcde99d267a40868a781ff3817080eb34bb931b1dcef5e4bdc7bf904615a2e6353e1e6ebdc37a85b9f81f72e2afe2eedf6414c07c95fdca8a4d9b58f8d4313f636c3f6c83aedb5e76c63abd838404b1f86b9ab1ecde167501e9a732ce656efd9dfd39a266f457d3a73879618c46b4c034f0d2e6e76edfd39154c65e8e601f40a5c199e802bfc96af5e557c0addcd3cecdb9e7c7d35a5c66d485b18def8a814321856019808746fa1df56994240d9f0684f6291d86971580f85f706a59c6013eb57a52da5b4d15ea564214d2106a1f5c131a6a8ad3f83f86bcf9a8623069cc8df231b7bc84147155f1f7680bdbb7e0dff61706d849aa7b89c549f04d3f5b53e6440c2ce437c65731e5d76fac50c6f310ae3734e4fa46f75af8d8aee4e25b93e84e3f7319fdd8bff9bdf3bf18ff433bd5a7af58e542bc91ff81393d04794cf85bb719c6e9397f355b201a85202de2dead155fc4ab4d01a1bb379e71c78e053f5d46 +expected_shared_secret = cbb8b7a05f48b47d163cf8c2fad32bc586f47f2c2e0911da349f29b1e3286c22 + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = f6446774b30fef5b426f563962cc29ff78ade42b497dc3b970f1b848b1141d7a5f45a37c25b125aed61863f22732a06128bca08efc8cb176ab6343239b572e1c8c138d829810227afaabb81cca0a73131155377730a120558231e8f8a598a2b730578edc7800b0d6c5627530ee92930eb2b40a9888cf648263b688f0a12e08f004f4bb449a25282029cfb73c32f8d31229d0a58e6aa08698517fbc5f619837ae3331cf763631d305e88c8f85413e9d5420cc282bad24a783011184011a79a3b305db5b3032b75c55907ca5c7f839320028305c439c39484895212b1e87925999681819416dcbc7ead45ac2b1262154bce16866c04561eba2c9ec6022b07a57a67c7b901b5da3bb8025c7585c86bda0810c442c39374040236a82884199159729834663d3b1967df9955de3a387d93d50f5001924c4fe433d016bc2b6614f2d3ba72fda226864ad6ba5b8c31681dc104348ec2b29c39fc9f567cae17bdf1c6e215c92effc60e2d6a3a3106bced0bf301b542f7987b582b0780b6d398631eb8559459b1db01a0443100dcc731291c737499c2f86452394c0b6662401fb57a4db232e40d1b0f2511ee1eb15dbf7b603e2a67808c064fc5103fa7c9c954fcd12bc619582f82590b323698a328cc14acb87c217e39c309421c7e6ea15ba6c3bd8587126c5aa02c26308c9912d7262dbb91ac2c2cdbb9cb009a3ae10761771740b2e6558fae775deba7a66086859270ec07b584334900c278002d8a47d01547dba3036336616a8c12415b86a1423a6c9aab5f085c7fabb6355b3db4023e47c7917c10c284333110bc978b2c08e16512ba95a07237cc35c97bfa51bb1b25e30750e65664377ba49200aa6e935b4c7451e547859edf03bcfc6904df05220c02f5e576604a873ee82b7693b962853b5522a5b0986348da63df86a64671737c17201ed556e92acb56f065eebd31bef43ca85db1feac395e19110a2f0c5b90459838cbf779c27247709765569e5a649bf160301003169e4ac2baaa4c4697f25869ab99179f9f792d9b19df0c148df7c6b9aa20e63426697d83a6e33b35f4c7e798175bfd73ce60a050146a3d893c4dc9b2fabf5960bd80fa0679433bb33bb91915e93c1eb2aa16cb13e0b9870fef99835a674b1bb76946bc4064cafde3063498ca30aeb3983f5cdb3a6b9c4970459d969f4d8b6ba27755b6ca8fbca178dec28dfeb2ac03318be7002a9a4cd7b1749a7fc7f09a6b560740da89baab8130872510c99630f3b588069d50a9550c97f8198b7a46148fa7ac1580632db1ef49528f9125784a5bb2757235fe44e74529a7ce88e91543b2ff81d9ed78e2647aa07033cf3422d34942e7830191b104c7ed56b8951a9c8706e4cb33cb0b918387b869084386420c13b09be75d2a5e9276246b674e96bac7782541e1ca441e53ff3b9c702cb95ceab628d1617704a448ef743e8b811fe52c659cbaae22377f28646c45642a9886628c9b73c510bbfb645d4077c1d8b954bdc8b707b7f6bc4701bb1af0f28b88dd282b78b7ee96732521aa6180b6021aabb415839dc3a1f6f545c1320c58b965b62993abf6a10c18a22ce6a45539685f297b1f04a130465845d189d17552e2f4917e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = pass +expected_ciphertext = 3f6f05da5d7deeea60bb32a85c0fa85f2f6339a48eb45343e20ad802329006d35743ad24a30ea7e1688ac9870485fb2dfcec77a5dad30ba75d613ae6211674f12620b2f84e32f5bab410123f921d8967d7a1b8ff92f4d17885b2bfcac31442ea09e40a41b54588fca2cb4624663895a8e4990d121cc261d97e5211ea06e12278d550d5b0d5cb815cbe7a6b5c31cc01edca9d61917346ffa49163e363b1edb342d496dea50d463c3c330cd453b903dc4b2fa78b93e4a78fff529fd38a1b57ea5e714ff924c14d97654d390b8dfedba47034db426c371e158359c733437cfb5b0bb39b1f4b7cd3874394822b9d137359c7dea734e1bdb51e77373f7e6a37561a8051fcbde5da7f65f5a1e0dce2b1559a4a90c0d0fdfc57e11d8e8ec81cac05299b3f29bb211756e3811622b768eed23d84e20ff27a2dfc7738cac348a938c0b51f6e1340587f2ed4cd05d1ad2298dbe751863be092d8e0f9ca870cc7759f898cf2497249206b14dca4f06783d7b54d417fcb578904d87a674b82967a820e525bf1c708246565291998d83a78feb27982b3d7b9259936eb08239455fa099181df240787c3855e564ca1d53253e45d7f12230ed2d623e7dae75e53dc57c41678b63f66622f5b762abf5374a01265d82eded50bda26177a09007eb30d3ecbecdfd7d7f9ab455949426773a03f628ae86261c11e6c17b276a4fdb7745ac76c7d536ac83a7805f9aab8f86810f0250367a86ad682c070367d6ec4d11581fc9d0913daacc0053f381218f5aba830740bf531fbc9e823d71dbf1d8f3bb2f2997f8a257f02fc8b6b6d9be236e190bb0f83794824e6ac07d6727add717472a0894b27692b6070b9c4197d0af9db339b9eb13630bdc016bb43712b92e79c35f8be95d4469cccf385a15cb76a48d0597ffaa710d4fcdc62e9587eba1713afcde87efc2dc6002a2dcb4105aa473c30a827d8d4ed21bfc7da7293617029f1f0cfc0857dc11c273c86e18ff68a129a74039f717dea458e3fcde1383d70d800b3d369f20163d2eb0b3333267ca8428c8937ec809f33d3f532a6fe3054edc3e88505f6e7001247e21597927729affe877ac665a6d606c36cbe8fb737ca62e2af6f6a3cf6a1e3706e5259ba689c4931b88827250f0e1f5e5fce0e6d2f8930ea41f3a80938d9a50c2ac817302d7f60546ed233185326e8f872558ac16bdb5c16c132cc2ec05c2b2a19912ae41d900274cd8d9c52b025246fcf14ea1bc299efb10cbc74481a58a5a7a284f3357702556441de77647b29a727455f4196960a10b86e434cce0c69dcba15af5b1ed7762e7f211b34c3a9223959725e181f0a2421586c6d36fe7d31944ede70d63e2340feaa54f1983a3a37d834c2bfdb9470fb8df5c9c4ede73d1820f87961448374b19058a23970a63150b730cf6a7816c8ca21145b2cdd46ebb01a65015bdd5d982ff8e03dcc1adee845aa5bf09a590c695cd2ef7f5c1edf40f167b28a894d9c33baedad48da0afb5901a13019f72c3147269bb3f2cbf688b2dbc574ba43 +expected_shared_secret = 1eef87404f318351413d52ba8a07cfa5e72f235d6f91afd7fb8ad3e683ce0a55 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 5fd557f7434fcb61b199e793c5e763764c48df412acb7c756e1370cd117f8c10cafb39cbf0c8c3f5dc8da1855203d02b39647856b55c38e944617b8348d16a8221962a42398fb61978f40328c83a0b49bc843060d1711e289434db4b5b0838cd87949df5ac0727d8a528b8b5bf30ccb9e37a6664050cc5880d34c13ca42c1779b8d098c5e0876627c17a79b6bad44a9a38c56883d97cf2d2b114a1c4f1a502ab4a9b7b5398d9e73e543b860f87062e27a9fd1a2035185f0d98857b0759bf1c39a41984c8c1a1a9027944417f84cca0dd4206e9133f6eb6a989075d004accd9f57cdc928cd455443f0222dcab9a8890004c2596efeb06903b5d0af33a88f14fec760fc074a3dcdc744e9864e7ebc608a56002e483e60b8202b31377dc7f5a486d5a060733fca9836aaeeae05909c6b6b0db4531271fe4f3548bd5bff1e92160321218f963081c518874c0cbb792fda4513f7902be6547745a0879ba6ccd7c0f73b123dc605bc7995bdd14b018d8278c8c3966aa87a24b4a4bd3abafe0c8173c028df14daad39c288943eac139210392bed70c38d7af7439697be96977d23a27cb6e7de7b785673c9d1b33a081a9cd417129430c6c6300c496b04e1796c9c781e4211915162de147501b7bc55f8913c66c5cbd209ba6d115f753ba739417c8eb182200113ce17c935a0622dcbc674553b9dabcda17bdbfb4865d58143c149512cc2e74a2b508f67be8058461252d95042f8b7641e1d85161521b81a616a02110d7ea3bca4723d003a4db1673d64273b34c9432ac981a0c01dc8b8c0ed5a05d20c5331831ce56014ab0732b301ca2f8569fc061ddaa95d63667b9acc7a1ea656f821d55a31b41f32dfb3b66ddd5cd2155438db6923069430b61c85ab309bf56b0ecd990427c1b7d93991e783a647b1dd66696659b5c926485e1642854f0839033138a3a54c349c138977275e71e0fe985493cb85e0923095804037462ae248780006d0778334f664262e88498fcbb22d46d4f4291bb90afbbd40fbf2b302415cf195542dcf3375e78602fe1067638ab995b70e6dbaf7b75bc11701207e489f361512b590a860401a3facc1ef1375d8b64e0e5c7f863786d3984710c2f55ecac578c41170194d832929075671b814fabf45c6e2bcdf8c0cbe2954c5a414e3f8878ab68ca13189d97f316517abb4c5187dbb03413da654e650ec1cca0bc9472bd4bcc60ca6fcdcb26e77a025eb70ec0e60e20b19d30fc261ad11d3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a0531315dec20d9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceeda5036c31a897b65612d2b176e9648352899bb2869f48b1e70c1ff04864487258526226a7dc64306b6838f4286b9a81a3193f5c9c711dfc5b9fe79bc6cc14c934591f93860b66511aab061295af186b8ceff5772fe50dffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b159a1c84c85d717824a0573cbf219fd9b2a32ab66bf8a498a04aa4e22509a5057997b74ab5a1b27b96656bc194af08114551709a41142b715c6e167e5ba5945729bfa702c236073fdddb4ceada972810253d642ec094333c028b0af40ce2e29993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = pass +expected_ciphertext = fdb35f966ebbfd16a07385adad48cfce34f8e312619d54fa614ae387f2d7c1e80f07d8233ca39dcac87d98d0b0972d96058f3d949dbdd749a759c31ad696837f7e687624d20d6a921ef055a55cfadf48a5952eb98a1d1508dfaf0c83d9623f08f7e6424a5dc45de4ffe226b3e1e5d5ee5ee53ff0a7e12a2497d5d4ca14dccfe23eb4fc26f27a62398d4f1eb268565487124306da0f7cd8a89e4746a9f42180ec5aaa8ac3d821e3f24cde824489fc38f7f26d83f1a134a19929e3ea4f3a3eb13bae2434104e115e451d7a7dd0732f57d764d7aa63399450b5e3a74bcf5cabc0b597919a1a14d6112549483e6d918ef6c0c1c8fc71ad382c63c3b81f14ce5a9c2f57ec3a3c58d643db18637a2e84c1ac4288dbde2660f34f12911000662b519e69e2aab4ff6f7093ef7330bc91b6a808487a5987389e380a2bf5149e955349e378f96eb17131d9d00b218df9f9de4a607614c614447ae1af7b7880412e686643396720978dbedcba4eab3de76233545b578ef85ceeaef3689c0f7a8e1b20c601d96ba4d9f2326f35d60a7c30b17344002cc37698fd84536fc9ed0848b12db94e17862bd2cea1fe8536211bb99bac84097d3a81661a452d05ff7be7f1a9febb4931351bd9d9515b69ce4030157ee5a468dbe9911ac26a93478225cf10d79ad86c75ab0d2c825cd43292515a317c1e9ed74bf7d51b8fc88ee3573634586569375c91731ac0e4eabbcceea2ac9efca2c8f9de612115eb02279826d0212de5fb25327084f1b07c364591e6fe8b1c647eea063dc923f2dcdda841bff87befa0feac5dae47626125989fb007f89632b87ef8318a2b0a669c554a830f29ed10cbc3820f1cd4bba6fa367ec20665858fc1033be26a443257a43329ddac6683649139b13b5a4237643eae57ff3a65dbf70377d943f9a88a8a355f32480a739d6913c0029ef691b6f9e14d8bde603b2788e9d1169086276702ad55fdc02832033c729e6ddbb142cda0fe072fd781072c954f07005189612db4ab774664793f8a00942d4d3304ef7d412f5717d476d67204a02667c3230cbee8ee41c6eec7c2d3fbc3582a7584e24b71e1e204a98c8e0073e068c6bfd607a1bf9ae1cdadd86ba48478b051411adfa3bef3dfb021f0e6acfc17a1722d0fbb802657ca3a1a3bfaad6f244b518284e2a88e7bea955e41556fc97eaec1fb6864a2f13b417984196ccd70d067b1d746d332062b2998c51f89ff9e7493b17562dace6b0f0dc521bfc2f833a405e1e5263006aecebf880dcd2cd489aec589793e4ab46681ecfdb07992f7b32973a179e7bc03ee5237eef3352489d81aec6a0fd039da71590ce193003816b04936935ef214d109c20c02acc085dfc79e4e4dd8b0640e78e8a90d45a421eee92b4ec78db88d63d3d21d5fe2d2550ed3cebcfa7a326abf3883d003b415cd3fedee17b934960bc2c2ce114a5cda73f7aa783070b7d9b04a7085c76d2862c9920e88e91c1639680db6b03b9947947136f301f4bb33048c323e061ba7948e1e058a01a9277bf6 +expected_shared_secret = ca2c0bba56645e4fce4b7e38a7bb4b839e754bf2834a302a2614377eddd6ae60 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = d5f135d06aa99635c9b53244e1f898d8494b681312bfd243c8ea5b7e71ccb7a5386e477d01fca3ef4122a63934843450a446caff55184d052923a393fd887df6b045659cc282d1424b19b17cc2a2384132eff067a0347f88c6b392aa56a3519a440438d3f90f6941112124c91fc31187ab0ce6752d9b336a1e230f97837a657599e253b7798c912a66a48314447c352b84590941355c6bd1c0951374105858a46502ef39cbb58b8e63a64e2b99c4825912155695893a62af6745e76058d551a946161f25f1b8fc045602344a7f342facc50e9565c1d59a459d34233c1921ceac6e0bd936b496c8fd6a619d8b0649eb458f8943eac97293635092666688db559d255ce9f280227755c3605d6ed007ca718527227fa1f40dbcd88792801d8db6b2374a23178a72276c790f902d7e969f2686c9508186788905e77132dd909397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca64918370809d3b1b70cb09641878e7c0a141573030aa2b687761bf43ac89a81e73376793ecb32db53368ec9e079172e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca582017892a188fb2440ca7240c3c22577230b59ab8ec038bb95cc49c2a2f59a4a22c0c482713544fbca9d7404b3a6ad86e8764a601b7084289858bf62a2828d3091ff015089726ca23b1ca0f87195ba1abf80b01f101f8584c15289196744500000b431a60267174f2cc56860bc5ab4ec20d19ba8ed47535eb42fe1d33f2980ba211805a3618f2ff64d1cc634caa6b40fd23615538366dbaf41971d8b5857298c1e406a293c1b8b7f4a499a97be8cc51b5382020ea9c7cf809fa7323134290fa461218f4a6f495caba2d1511ea48b7e0905b0465f7a6711f2716b17dcbb4b9a1b31933d7d3622315c79f3f11a93c8058fbc01c4839a808a5d2d45b99f7918faf52db1d81d669c7988ba7eb8847187ac7b76404b1a139dc4e4917c9b4e29833fd9fbc36e4bba96e25bde691ce0c369ace7183c762bd04785efcc6b614165c014a0fc4b64b24b3b46418ac5b6b7bf69cbc75090b69aae46b4a12feabd4e134bcaf14922367b50f17976c6705e175ff34612cf7b086ed733deaab0ca815a53c99b2985963db89bdc284d251340b0e3ae20990ee93344dea18063db6ef4374a331244ede00b46676475937a9472c82e124b1751a9e4203becc77ace092b055abf0892637b39c3a9a011219c88139277b8bb73b9508142421939380acfc2b81523c72e923609a0505e2979e086ab85f9663e549f3350a694458ce7b02bd8716c0f8b8946a21d99d97632952bee898989c1adeb710e15bb25b0a22be598a65465bf2b899719d00f9d16367e9436803ba8c17b6b3bf62a10a017c177125396bf6745163fe24c455319cea69393ccbae42508156167b28a1d1050bdefa5a789bc389031bd86e72af5f5bc80a215260737839654998295d5aba8c11a5417b55d67201243393b7593400d46cca1d321c027bfb09cb08a1738c88b7d47e876ef7517f8d96cc1c93b9e93b7062227a55996fa958a684aaeda89587b015a6b336dfb610721298ac6ab713f3a2e37b2aa7b1ccd2a876f03c72546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = pass +expected_ciphertext = 2726c88c44097de218b782b16c655fc658d29386b80ccc0168220bfeb554b12a3ec13ade45147b3b68cf67384840e1b011b86808e2b922f7b9e0db40b5ebf11ee131a1b4c10a2d350c1cdce92b330de7f838e29062bb243e25f2f62422ff334f7ecb5863419b44024039d1f900d3a21f5f48bb78f066aa726e070711973c1f8de28efd8d71e0cb5ee72a9d675974c02286b56029dbba45e064bb68db2e25131243d9cdab71d2dc8b56263a6fe2b2d6bedf4cdbea2572e333c4b062c91622ee60d1e506384e17a10d08d61cacd407ec924944e9690a81d1f7f989cd58c243607c4cff68058ac8c970376585666d146bfe8816fdd0d20e13bdc0afd88ccc1282a17827adfa9c927c55ddb520c248216378b68908155a718f335c39d0504bfac4a069aaf2c64b8cd935d5494e31a399257997fa8df3c4237e4209deb9da336d4cbb116c531a8cef2f0be5184dd08668630632d030831dc13652370f0d7b54aba8b122f968b2e00af4a5d9c1790554b9077b2fec861ce9e8dc89eb21c23ccb68e9080c2cc0ad9dd4c3364183a164e9f57401653cbf95d0a58d289f481a38b8b13cef56926612848fad81e5f2a1468808ff45bef6de82c121a8d3e956710b5a0a37cde624d1aff6efefda13341a7cf6d1518b633f65fcf0b3b91c06769f307f94347c7e1efcc80e02e823dadbe0ffe2cb7f3bfbf3a60e8dd31506304155467d28b12740ad712177227b4468d5f4bd305ddd6341ba68ceaf4d4fade19fdadaa3db805d37671f1cac1c57882bd710b2a7545594320114ecafd0fda32fd9e06f7cf2f08ef27de1ea119239411a10598bef458b8f3604ba82afefbcfb7b6c92cd65e92e7518f506c684b08d156032fd00c3803cdecdb92351ad7a3b7768159deb534a24c9642684389399205a8b69f52e460be217ae7b5b08e8c1360b6ddd6ff35462d9066618ca07836a136d044794954e3812e29ed9b200d250f3dff0672aae2509b4f32cbd580631627085147c5fd76fabf284b88a836fc4a48911a892f03a92a4a497d62dfda5b71acf4dc4976c7670c88993a23b1bb0c21f6cef59b0ffa88c4c50393355a72299cdb456a592deb3f749e1341826b3e89c4138badfa1503041e50c70f8236ec881b08bba64c46d611e160cc9765c512574d875b50a5781a7871a6b4bdd02cb344a586bc1653ca974adb1175519a0371695d2490a54b2ac21d53916d584f597f7e861a051f93b64d5219339ec403d7d537271d5d9928e1530a6c6d0fe8e1055ce1eb70e5c929afdfd591cd8f9942b6fe252fc98801dc4ba50b9a9810819b1b245ca74a6d8238a4bb7a64cc6f3c7c4541779ccd0f8509d9202a88af0ab2552417b13c075e1c609af2281740847648719ed72e7695af239e0c288bd630c72d5957632c76e89b0c5dbbe74ced4a1536b1e7fbb2b7e6edf8feec8223428616ea5f967ed05eb2254598f3572e2627b6035025404911ce26378e8df914b06c6415e528f9e2901a90992a5eeb0a2326c8076ca8da8a80931b222b809bf62e3a5 +expected_shared_secret = 9155619e28de6cc0670ce70e0ad270f0e885e5f5f8d6d38426938ae1036d6ffa + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = 26ab73a3355199a1833a1268a37a087ddb57ab621046db1f407c804c488e4196048ceb762b9024c2157e7dccaa1a762881280715a1467e766dccb159f4780a39bc4f4a59715700070318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa913052119904745ec68cf3502f4663bda74522ddd61a318539e10a853bc90a5b06aa12018c6bac4a8123719c567719cb723b420540ebcd84c2787f37a76c6c40fc983436c26f7fdb14df17062be752af2c1f1cd1026856500f3831cca75eff7a08d4d9c819d295674550c1c951ff9a0155856c3cc143824556c09025d55b0db7192d969926c18912bf5ca8629401b8c53e23832cefdb369020583b360595541f48573ba1557fd0c1058a8cc5ea7ca7f092b7dc7b4b04490fa4e72a37aac0e33b1746aca327258d9d29acf140c5f70b8f94a23195d60d30a498259c6f9d06bd69f82398953b4fd39adeca972851431b59c9614b7867cb1228e2519ac130f003903d801f70bccd776a9b916684cd89cd71723ca732a21fecbb90d547646b987155cf5425abbb2406cdc1821afa8da120a540d1c3af175032444e1fd85f43f47903665be922636755b5e75a90931c66e89345f57ca4a032959bdb4521cb62bb1377dc5c99fbe36c71347b81a80b6b7251fac3732475009a719f4374bd5ff01cce4601e761a754e05756968f33fcac4d6a540d93951d0bb4d0d838a3112872020c2dc67718888dbf408941b877eb6543432675c879aa85f102e608aedf267e32d333ca9c3860f907f17b553580aec75902ec304e6c7996ee34061b40a9f4f8ba2ccc55775490dc9c2a6d5c0134e809bd305d7445c9ebf7b89f9604146b2e55a1090597033bab2a25a3886dc524f4908adbe98dc2d74386806ad641712d9c23a19562e4ac7f57a86fc98663e455bd963c4e63d8471b504c14eb718d8bcd6475cc45687f55099f8fe2035f3812f081b6df2a174999765cd69433e5312be67698346fa1030a40943f8927b2cd8a1e2cf2514333bce85a89a6a99d03c4a5c0b847550972f9d1448d1819b3582b99a50ff97c124398cff30967013c4dc4d374379b4e8b037eb0e570aec147a1c99cadbb651bfb576ad61bc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a192211b4d6918260c1251eaa1014c6f41427465609310d8b665c6763639c71ad48019905cc0874be438023936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953778124c2c92d29cbfedc21678e54861eca5cd350fa09b1365fb74435316f37386b9b510e2bc585da30a71ecc7b9913921ec8d8fba2dbc97807b693b1e306832507cac90410e0576611ba79c1ca9c0b106d0147680790ec5051798592d3035aef57a0174cbc70b435710c51695852841907d41a8180123a4d911787b674acb513c84047bbd5851c3e83a8a046062c06bd84397858241c95b8d8d2a2c53038856247506065a70a5a29b701bae1b488a68c2bf02472d86bcbfe263e7820902102c612747cd60344957a871c7774a0980b70b56f7bc45f8e2bd2085af080cb923b55640bab2aa2c30f206ccbad17bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = pass +expected_ciphertext = 0a307d1a8a695cbb2a421d2c316ba05165535ccd1cc9ddb641b9edc8dacfd10d001d7dc8166a7e405f6251abaac6d5f466438f4a2240557bd7cd6ef811d4e1334b76274dee6c34b79979e02db09a682b3f965d6356e9fe640643b03c9d3cc37af284ff51f1ac542060c0377df1bf3f577d387c8a5adb0b0a615e9d93c7b54a6c7e3593ac118fdd7cd1985414fdfcaaf20b5ebe647a7de9aae9b43f0e1836493fba2aedc459aec78bf697469daa96819fa276113504ea82d956255e0de55f8c6268881e2795527889278ee674580866739fe66b66e94ab71de0f7637214c2e804bfd8414ffd95a5aa0d1f694760169455a5d47bad6d68f277279527e8d2e6e95051c6c92fefea4e07610abfa63ae90fc38d3b819df566ff44379354bc4479007adb0fcc603a346debe6a2bf14afd1da6e6c04b1483637f0814b5bd5f92984ed8f895c35c9f7f2fb5032614e52ab183639e6caad3796b9ffead73a9822a23e997e0c99acd309d93d227b9bf1297edda5a443e4b01a0f67e5a25b2f395635a1fa9d25241649767baae14de7a4bf3d5cc8d7360460ff85ff0cdc646a4a2f8b5d1edd9e88e353f4771b2395095026b79daa65e25bf9c4d19761f3e9bb955dcc6f2f288b1537b263a026b7067a309b08130438db1c6790835695987b705520a215118b20e636145264e37a1577c7466de14c26e4c372b33059bbc913a559880e31820fd0be232eb7d289f5d6e9abeebd9018fa4247acc708f602b1e8692ad10b0dc6499f0293d1b0624ee40d7f13b235210087be1a8e2c709b88f6460db6135ccda532f8061772a5767501750e58ced64397bd0f7a280558e86d7fe81d34a24d5736e4e65e118c7296b020c55af0887743bd53e2a60f809a024c68bd1324f833e8e1d505080fec99b3e2098df4e844341f7becebd889c15706d7dde9dc754b6393da40167a2f00209eaf0583ae4ef4048dd026ccdc2884f17238207afb355a419f3666f80d963f338548b6fad3c9b4a569a964691f8cd20a1abb3e01fc5744aa4db5ba0594cf863f566e7b3eb401e62e05a84b30054b7798d5b81bf994a4fdd3a876b46898820fa4480dd9a1a5ca970b459a4366e5097b6d792ca598ba6785b0e3328aea07f594706af89d88727a0fd7a5d16604766aa73c21081303bd676ccbe0ab287f2ae1ae235fad0a3d2346df4da3cae145a0d2b7f2a70dbe3cc70304ce49e528e1ca56fdf81f33267402d271203b8990773a1fa03f18380efc7dab62ca34e28d5db918dd6365c2d79ecd5d70c95a395211afca1a0542201e731e61c1dbd31316dbc41ded48e70ef47e4fbbab6bab47a56dbdf58c5d741008c74823561937fecba694bd31538064bf242eb926875b094d0282a9583886bee06c948496c24d563210cd96579dee6de96d29066ad4e1f9d1ef1ed463f7c9d21bac44c9cf303922fff1337fbfc5b9559736801f80974dda71ca185baf31f4e0e2936b4d3ba6f85539816b69a8d433d84a7a88d2c3abacc5d4838fd3c2952f293a0adfead7b2829e4d +expected_shared_secret = d1f24383d5b8d0c3c0a6a5f8f7d38ccce13ec179a84b0b09bcda4c9988f3eb4e + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = bac16e6e3c5e5d9c8ca207a5c77c7883b917fe0463d3101962b802549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a6204903b9bc9311c66b907c5825621b7ebfb52f6c7cf75c169c17129595631a2fa95920317aad4cb338329adc69c6795158558638c474710c78763e012240cbdc2e586adf93c028522321a94cb766f9e983fb5110a10476ecba92fc0c120cc83632409940db249ec569ed5740471c86623b06962910307781349f342c759886f7c376ce708091019fc407eeae76409387d151c97cf7270319143471a84994bb596f9b5e1a78d33428740fcbab415c575e478db4b4e30771802e409b8c1ad4ecc9cec1b7396e664645cce83a40d512684e0b2750d8445d2180be5b4cfc09bc9fffc8d6e49b49d68c4d849b584512cbb55283722ced5566149811545609a4c5459f523c1c76667859760e690385f65768331b7654c30b8c0b26f2b8089a3c5b4f21eed42179c54ae61d22736512fa3aac6eb018946a47cd79acd545719c829b304477541ea92b10a1ccae8b36ba83d5ad83083fcb51df653ce899227c52581699b7150456cfa1910212f7678056a33755ddc7d0648164aa297f196057060009dea8d87e86b6abc0106a5536d7c83933ab12e294b4f50870fa0bea16ab49b88a60ba7790549ccc0e6571e81875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a5e295e3c3231f4132e1117b835529456a53d3d748c16280f4d597573685b04780f611094c665c66164a1323c290ba8c8b1031b142a3b53062ad5c59d8d112f9926e5aa591aba711ee2ba1509aa09b86c60a969020d74e238b849374bcae7788fae61296d5ac7ad0927ee30912c4287e3981b7851d5823295076365196bfbee4a3cc189020254f31b06fd8d70c43a94cf380c01936465a334fa59b3d39296305dc8b775269ee204639bb3a30ac437936cbd734a5c6477b2a451eaa0159e571bb12473b77698621d5247eb5012f608c6f070a67551f6f63abe87ba12a56b2b2dba44bf72e01c9a2c490579d2c103ce91a841c4f4b3aafddaa0cc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d1421aa91216bbf56bcecb89f11588b4085a62ba0a47ef9a184c2c9346525ce006ca4819857fac8b1498c9ca1222175ca5b01b6bd502f69f8977a0b3b04987a1897a8f2f20dcddb098ad070d15c15c099a5672c17087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c85971fa10d465970d61446f106cca6200f85eb2de2947bb4ec57e58c1f7be6b6fbc025a4a41eb05c516578ae9ba4c197b692d20976116ba35660cc5b612b616269a837012230b65f2913e5d0362d0b510f1272716a4dd2832d3bacc914929ff33354c01217d8a0745c9263b5d80a4f497d99d98a4d895b59a59a1dc173ca6945fa54c398f351c8c3ab8d66cb8971a68157ce3ce82104094fc83c7306d242f1f0497180842beb8e126988c5a830d2a39c2711b033490fe1d53e432c7a453b4ceb05a5644253797135231228f246bc6a1445efc16b2f2bc674327a62ec32dbc209f2c4a5c600920d2856dc34549bc4656f7953e697cea6f2891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = pass +expected_ciphertext = 39acb3d169060aa5a9a7aa6d76e53f8e4cd790e536b1947c3f0e5c084348c8f3f5712ad3ddf33d798b7522fa7e8f570108897391abd2c0ef86e04823b115adc2f106ca8239a4f8a52d38653c256262aee0b5560b9f74e285ae1c190d2ce0e0eb65668087b98ebc9eaf32db83fbc09b83410dab78038cfe192ae229ce2bc82fed7d653ca71fef58d6f3ea9acac45967d09478080760dfeebf095d0bdf723836903b8fde5b3e74cf57a1edc1d178bc29c6cab5c4381bfb591952bfc70444951193c3bb0fb8645c7d9eab913d64cfdb76e1a2f02bd7f9c98c8042146c5428d641a79046d92aa6f926d4409f62ba47f73255ca57a781cc01f2a6c1c5bcfa890ff164910e4780b322c4f2a0ecd2fd2f8fc7a2870fa3c636afb0910d25b4c56e060bb22e969a37bcdc29f3a3de70bdca6a59d803f59a942694db2cbf73de3a787ea166a1c111556c1866468898539a7f36f2ed7d15324b76879af9b9b70bf99546345e0ec17fe6f1311e9f438dd92cbca8a02d7c3778f5b88f9191ad12395ffdba04509f3f338b0494ace5d52b1e8e3534b901fda4001d493f9b83f89a30ec57a5aaf4d5102b82b0451566634ba68e1f7e93cec122e7ab4f250bc78b6df0a9b7d84a4de5fb51e1b7381497ddf72ecb010832b5e0dbd34e41e1189744174dc01a7ff3eafcd717dc2cb56cc145b6a8dfcd404b748a1dd9cae69b1f3db48e414584d1cb902904b7652512a9f191dd7a95ec60d1387e1bc4b6943c7a6bda205343e2e67583dc06c72495722a678ae50ef4a8eb0caacf9a41dc13a56c5dc3e2d0b98d2804fdf7a43d0fa2d20722405bc002d71432424c88ea9dbdac6e8dcc81e660e85e4c650a90c7e6d0c50e5e14a2919b399b1838bbd7543bb95275e341ce086eb85eba4dff4c9d3aecc99829efdd0d68514fc304e5e2529d04c9fbf79897620d9307605bc566fc6ae6f176a25ba26859097a241974cdec07837a0c1cb86e00fc8f8a4365a7c348379eb60f12e0b1253f297fabf6e6b38c9cb226f14a4ca9dbcb1120969fd56c2ab38dd075351d33f853ca3c24f4afd756370b0ea4dba295652354b89d004854cd89f57cd583b7a7a415e48e4a5e38941dbcb1c0e5d55c479a871b8eec04e4d5a73c93ad1a7183093c28589612c6a4041d98809db41238efab617150bd9f9b51a279682ae75fe7a057cee50f9a98d6abb1c7efdc2a0b1c0bbede9e1d19a2762047ecd4f37416a3f86dafa241e078b3defcc414afe25cebda4008af5a356d10ff83dbcb6ca1e71268f60524849dac904d7c0e638fa3a0716141bb8f5c019228c930cac73143953e4cc86c554ee7a700bf5aeae2c8e872da8fe7c6f27d901bb74d87e1f1626fb53ee3bb080c21fcc41f828032214a738e28a51cd5085d0f5a0b15629268461561ed7caffab7f22c2d00a2fc9276bb80e9964d0bad8a5ce2b627479439a80587b9e22e0b579c59b59ace59510c206653842b2a4a75d38f2c7984503ca35a62952afbbe25049ce84f5eed70686848790a96f42a3e3572f130b2 +expected_shared_secret = d2dab0b39b7f62de3ca9826f9dd15a4201191a0e0c690d3e52b305a9d3af2d0f + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = b873b2397a7c7ada2f4b0b589ebc97c50174e4317ed5d9cf2878c924937bd258bacbfc83283a218d443d8ee43f8cf3c64459b189e6b3ad100a6c6a3ede9916f89b8bb67cac332c0519f502a4c427f5c9af1a16a59a2122521a0c624a20149765e986339ed63567cc29cff15d7e8ac026c96f08d6ac4e057db4e66361b18ccdc3bcffc300a996ab7346232db7310662c75b39ad7aa080b23763ece54960397b8de836071b8914d56f95a681accb8fcb9529e5e4cfc2ec0601f7b0b291524e180aa0a69fa74ac2f17aa88162c481f51543a5a527da5c42b59f9a72b14dc91574b51e5806ace3f022d1f19e3eb621560478bb70beb8407719a01e16313d2f0c785e3b9886f679acfa465ba974676c0689a149ac04996f4132dc4974f2fc322b56115a64b0b5dbb8dc71869cc655dd61390b032f062b024bb71505640a41cc6174b68870da11eaeac28ad061f3abccf4e12231655eaf9285b205251ea69371d90527793495835715ac005868a78b1cae80025426848c4ae869b52034bb266e1b97480aaa7a31e384780442d9933fdb750efaeac0bfa802e5314d28a17d374caa05b46121e16362e8341dd923a66872df3c942177b58951c40ad1641f53a53d8708ebcc22aac67ef262b6155007dc6880a1f45cad3a5312b282055b1e0b181d9b396591fa78dfccb9d6a92d5cf8189c14c68cf4238654716f0a1e4f2542cd35a7e4e2185814c1f5b16d8c423213c69d5958c46960b8df589c185087ec5474df3c5112b5bb6bbcc6ab7160abdc2ab28801d775caafa049479a837cfc8847763559ea86239889385baa43a2848b489087fb43aa20acd7ac05606767798500f9271271e52032f21fc2a82d8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851116c2cd2fa4671b95cf7e60bdcb4976a2393647b714031870b1a6b2d486a5cf2a8093b7b948c9418f3a27f6296ea12336b8a6dd5a5715ce9a70dc6978038369a10332e3ab6c2971961d5c66441abc3290113b21c46e96c509aaf09e658d9b77928935b9a122e42bba23f920b58ea48f3f19a7924128669c09e135f772c275e55904400495153a691794a8d182ee1314446371501e87c41a944f850c9cd288cc2ea90a4e27864c79e554cc5924c4ca9a217dca424ee8b76e49993ae4b085e9809eae27401eb9c6c794a67a31705876243478f86d5b9f9cb3295422816526439950a412b4d1d28a70c6b9794c959be155aadb39e00b418efd0664b08843d20b71c547f1468c5fdd92b9d818336282f34f19b515946a7961b5a9319d9444cdc1aba840cbb57272e4da4ab20facd5fe4958a57c3c812978fd772c2862dea8b60b30a601b692dadaaba0f361cff27c5c734a42265341641b861b7899cb311e7e0acce396bce2809f24289c5361b91cba88493991987c0aca3b070411481e154104c15780abafe725dd3e1adf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de252a4f24795e9aa631d5198f07511160300a2e02a402b4cf8aa556ce67bd341307ce5a1eb6609efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = pass +expected_ciphertext = 0899b2fb6c3e1b50c82cc10ece1871e4288e619f6f83fe6c3373b7aec9bc0fd4fadcb8a1cae8c76f7bca200d22bc19130fd47fabe13d5af97b927166a5cef08c3b54a9311ca168f27252a389b41cf76b7ed09405d0805e44134bd0a90c29e28bb2488e063debef324014a7783cbc81741b0b7dc2a471ef3aebebb593d995b91eff21343f19521523e53319a21a03996e55036989a3d2eba8986100188daa5b243ceb9bf10379ac3cfa54ddc3b83f91d038c9dce1238782129682d38b605f652b73ea182b0ac01460fb45f0c05cc545808b87f84f00d96fb14915e1802dd6456f5466f8eeb70571afb129844dc95f87bb88d4270edd50971247ce1a2c2a07573d5a3efe3dec8989e9670974139102270b499ff657c2ef9aec1a1ae2a6a0ec968e58a0bfd58552bc4ad2de49df561e1c59c471990044dbd6f29ce4509a92466337704fd9deb5452b6d2558f2f76d6cce661414872dc0a0b9faca3874a9baf70c07e72562941e9b74b027818cf9e20519ff714f743fa7a53a778bb161739efb49e8cdf3ec9bcca18a72ef9a34f3cda4b313710cfed57e5bd7a6801428f7eae5b531744d8fa5d7aeea0bfd0b58d7585e328e065908fd9b4b853041fabea2acca4875cbbbf2bb73cd8c876fffae08c5c91e6d0938539c1c6f96852ae9c9aa90865f1ba78e5a17a00f8656ebd1e52024c940995b3b38b954d1bd3267636c74498cf4a996ddb024db76445b9d34687edd5ef67bac73c01f3a334bfc866a2fb036d2b00972ee4dfb7c6e8748cfd69698e0ffd9d9062c00ed57285cc96759fb99dc1ce49e6f76a18034f77fdb1dbb83b8926e37ffe62662e49a8f42d7affac1ea512302cf7f590865f01aca869188da43018a3f21a15b917e2878500ba1d1a2ac7e87c0f06a23bd20f7ee2e7399fad9a0f728161b6cf3ed9c4e57e66e71deef1838a56a70d4b59b4b49e0411ea09c91bf5fed61fc9d1d164a9176cd5ea8cf7639eb9896529260a8b76e2c26987278c11e0129f3ca598290ce7ee82353af0f99e15baf1470f6c3a2b3dcc141fe2090f87fc43cbe17769b3b7a5ee05cef079d4a153f8f160744dac6d5a8b208b544e51e75fc9a332c5cf95d39a27b21d4f98ac411273b9605068e167a583f8d43d6c764c6974cfcbaff4966ada842b9a60607b17897ca32793522da30460fadcbfc25e053d3f14877852769bd2d55fc27363b8e9ece93d9194dd65305b0b251479f0a90dae87758e08f0b4ee160e3c31ffa7f1570dced7f8a8a19f64e5df2d77c51696569049eedc6ce026f9228a01aa3d9a9a2d8a571b124763d1c9456fb695ce0284ae655c64315debec95c5587d25fb0fe9be32146733147cb7988bd8e1d9256e460958adbe92dd128327c0d4b7fe9443b01628260ef3edc66da4242077f1b29ce31d9b5b31d328972652e81b7d96cf4661ea5910343cf07007a5a07a87eac17fb52813ba186c499db08b584dafb6331255c53070a5795540ed2927ec82ff2f0cb4e182ef5517b1110646b2216ed6eefdc130fe528faed +expected_shared_secret = 6869ca370a496af2dbaa866265d91ba6be54b9686b1b8dd5714f6ba861b0d1e8 + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = 0846c63e2c3018bc8733f05f8ce3b614088a787669205ac9889bce2d3b523f366f4bf811f004666b2b654431b135d97a70a00fb9a3928c1a4a2c7285f6f7b19bb766bbe6b966b4013ec06833ec6f1118a772c2465d81b77ba740b7ea33129218542a41e2f1b10f42bb42396e9a6c5011351e783641aa692a982272d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1d901855bbb2b68b988953ab63607d988999ed96e5a4b963497a061ac69bd90c4eab7c0dc17820b6963b0293d4ca30d82f5997a877a9aa71c5c7893c1d153ac6779d0a88190b13df828bf3afac9d7ea392fea899ef844535187af673972399a5fa31034c02d70b57b97434ecbf3b1985c86ec75b23ac0afaa67225f12a257b78341966bfd2569670680e012899c112ad3873aaaf26d2f4a5c8cc133c92b9a446530c169b6b87b118d03329374a71ada1778a2035986ceae200c763a12b6e2b2fdb672b4d58d8be640e61576f2cac617a5ada5d1b874bbac9d272ee4c881bbdcca1c9a84626012b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac252bda1a83ccfaad69e38ceda6b149c1b3ba295fd5025c63225ce88ccdfbfa6b3950cbcdf96e14dc0962745a5fa32d10525f71d895a2085620c89024d922359741be366ce9038aa3b260320a456858a7b8d01bca12316e9c6d1782bedcb590a1d2ad9ada0c26d3818652ce6f3b6403c94dbcd1424d090e9deac559472c9ac19cbb26c16e8b27db9140a1161ea96a171728689cd6b6ba0c8002ba6c46719a1a0c175638770cd088ae29a7fa958209788ade14354a1b0880f05ef7c15a6786be063b357fc7521973abe4fcac0a8c26f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7d316f75accdd1911df10a7e838a7c2023ea1eb0a956abb53fba02c48396807229f492966796805e04ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf171899a911fa910dfa6687b2c28c1d419a4817abcf656ff669b587b72374f3cc20b92858361d21bb85a3b9aba157100875c993b54ccbc84db2d72374bcae29c5479cc95197e625da047447ea5797551595853651912daec4891e68901bb67faa98bc5050bb50e913645874fb7a0e51c816acc88a7f8a4ad383170a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb892aca3941cdfa7a487c13af9787a309779b759cdc037c13e839314803bb10a3ab19b7fae477c8c322bf05bd3ad9cfb0b241371c85ffcb607748cb518a6c896830b191737ba289b15288ab59869e22637c57019818801ef9a6b7160ac1b5b4d7519b41905e6687b3fa7230eb88a3c9530813561308b68bd2b740e7aa08ca72cd6468c008ccab34ab99b6773c533b3914b19b2b80bf7e783e7bd9366c8962e7f3410f34651ee606eb737e6c9c5f6d306af7348ce955228cf02d15b8abaed16994b56260221beb1a29be5596e204b9ce111127989bd2ab49cf27c976f74aa7b084fa6b8400a25f3c36213f7c2d160045d865c75aa14542f5a4e4d1459b5676491c6a3fa0a2f0319ca1a63a401c9c3a14c94f0016a9a69e64c522aee93e8b96b4f6691322242b20353e0d8b995a6a9129e961ae7349f92c92a90b833e82b9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = pass +expected_ciphertext = ed4b1d8efb6224a8c0139d9df0f1dfdafd3a765d70e60099d700efb4910568ca3241f67b34d34aba653d0ee0beb023b5473f34398e5e5a62bc482b81382cda3249bbe50339843c37ecba16481b66da65c38a092a970d949d8e095f474e2deddea94e1d9997001a131e738956253fefb026076dee64e97ceead6b43109ac533ebcb1a05e606f1cfaf62f956bde4963f6b91f3774d4432114a4b14091790ca9a583a3418d1a3adbca8e04944a8dabc7d636819237991837eb8144168f4ad813f56e48aee382bf8e01a837e65a4e0ebb77e5e533bb718ca1bf0374da381fcabc5a38aa37f9a68f9d70656d0381916b7b74dcac08d444f532fa357323534bb7bf1e0413c8074e722ecb22a748636dae0ba5159d071c8a7ab0d2e2b4610e8ab3291492f429ef31f22f9d9a8a209a8fabc2c2e761eafe57c96a71e2cfd119f78c4240e6ef8b0aab89d4a0acd23d319b390a18696892d33de135092fb0035cc5f7e4d221dd4531cf6cca3e0e1c9eb0607cec1bd279ef77681b8ba22a6f8079095f6762d518c7472ab9e7292980bc2486fb8cc80d91fe175c668ba11429bbaaff4dd0088782ebccfae7eb4484800e0a183e598be22a64cc27aecabecd69b73ebe3bba2170db602e9c0e6553081458150f05d50d8a804fd80bfab0cc8119a865d4e558f06a7875b885571be68645b568de8182614c66bf0ed74a9defaf039ee478d1c026112dd94ff4a89b553a015ec5e21503312d7b3e3d163103c660a5312d1b56b009fa393ead12030f50cb495145fa4bf2fb95831aba27609620c0281d2887c2e49503ef4b0dd91db1b6fdba7c133846b775bc861dcc122514a3640c0098e628c8cc8ca313d94a4a2acca1da96ec33efa49eede82545094056ca79ce138b79131ed8ab224ef00839a388b0b5338629449bd5e2614b83ca644ded974a3eea42fa7bf75410a1c52ecc691b9bcaaf751beb00d0acbc5e05c5f1c6593dc674a049f652c2774e8337a72d94be074ec12863f37e6b719993c010a449e80c49998c0b7771abe617811e930300ff4302a3d1901a8a2b8fd5d5a569ea76858dc51c72cebc66f1a2eb7f73296d4bb251a8e9e5e33fc73308ba7cc5412159c0700e8d0a6ba332fa23386c06b4e551c849f11b00deec734870391cff398079a70e3f4f883e5b0c2ebf8d6a52146e62e37d62fc9c1ddbd8b1fb29d6c149d4573c435199056611b3bd76458a02f7f7daacfd2ef1b1ce3da534bca74a4bff0559380569275ba97f51538edc74844fa5a034a2b1b1e99f03de9647172365abf7cf7f3e94f2dc0fcefde3a9a6cb44d0da22d8bf35f9445bbecb3941ab70f0b9a7ea7aac71d6c49789fc72693262aba0a6a16fcbbc0956b8e04b4446b2791865d34fde941716a13bcd76729508a92dc7c5b2d2ff8160554f5fa5ae3cf701aed0d13128a76d0d0ed964da3ae47e50bd49650205effc5fff4d1dc1dbd426aff5d387b47ff9c54d7f1fc4fe65d60600c6f4b98aa53b0fde6a8e7e6320e8e0c98a59cb8aeff013cab388f5ea822 +expected_shared_secret = 502d92b2a7e1804892ffb8ff009987a58f35baa30c0392c83859fde82105a9aa + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 964435fc16be2cd2276b7bc78ee8b5c963af2af4673a93940b429131663cc124be5a706bff5c157dc17dc5cbc2a11418dc4b8a28c841c5a831b1a2ba989a20fdd17dd06706ceabc0d20714d5595d54216e9fb6824e3272de0a1e262aa246494152b1cfd95c970f38aa35fc0337b26e76c77a0a76bc2c57b80757550b11807a423b85e32ddb537ab6d4694cb8b9ed58b11c9a6acc746749c21011a66dbd7896329c3a31d0a7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1bc1a133a41565305cd4a09fbb10934e7a3d132bb0eb83559c484ebc92f7cf93e445020b7187e2705a2d1a8386c008ec7f22fe172088360cd3fd160e7020b6d0c747ccbbeddb1b84fa7549f625dbc064621fc2e13f720188c200c1ac1f10394fe4117018b9640632fbed570c942575ff61a7149a51f9993b90827ea2a08c32a330747ca27ecae452154ce1a6a67a8b63676998af929e8a7a9d2ab709e2162a2e0bc0721bfc7e49c5b2c9ba975b3bd881aa3782391f5cee4cc1835c83732c84f54b373eb18869b2c90e9f986a0ea345cbb020333893b463671c95e6aa07193d06f7e62bf4361cd0009b1e528c85d147d0e650cea7b0c67f1b4fb754bf2f1a7b9cc621d4c34682a6195776bbb9b2cc866cfa94c368a2b4b346c75a2a6bfe946cef09416aef21b15d3c72b7cb408141608c058e506271380841656963174c70e09c1f593acdfb9bf4a3a9387b693f882495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b610f00bf4f4a282f752a070582f2f3c141e168f6fa037f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a6f82ecf8863c1692dc2073cf517cbed3c362a853beef1a8cf2247000cc4cd8176ce980d683b8ad89b3eaba3b962624f5ab3695fa10a88055ddd664a2ba0749e439a39c6999496999be3ba7bba2ffe06388b1a6c83068ae70a1c6f8a36e788b8aa148933c896eda61efc86cbb7d5c9cc96c9f137c6a9210347289010979bc1e16700a610c7c990d685550f537ab0c45b2bc57e5ef4c08b2220961c6e17e95e2e4482a4a94da2e17b6854ce57c263d69429e1566bab646fdb216e0444cd8fcb7df4168ae66223a0ccad971583b5917c4805271a17b4a1e17462815cb39332699ac447332a3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd2131b98aaca67343cdbafa3db35661c38c0ba1e18043a4c945067adee46e428a16011abfeb58c1bc8b2330288b57cc319389921857c9d015a0471128c34cbc13417db24b91a3567ac299cfa6d4c2f1123661a3ce0996111d340d9613b966955c6a758fa7f3556f6716e5ac7ad3a93174b2032a983cc0c73c0de302f9f83a0de89a1fb576cd3b41505b5ba712c387730c45399b8cf0b0e548cbed984e7bb5095cf7263b05cba437ac6fc369ebca85e0211715133bcc314723d79c9b93abac57ad3d3a5e77f2986a3539eb795a5b4967ac7753115b916236a97900870b658b9d4b3e35827e1aa9adc3500fd9ba18fc6b03465903858c61c1259cf485338cb700eb731f31643b469bb259210cec78c158e3290573c5228518e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = pass +expected_ciphertext = 74bed33073033310bbce2a4a3856a92a519570deb8779e7b4dce5147f198bd71ee95be287839ebea96cf5b1fb11f274d63ca2b6d14c15e9cf2394aba065c27a94f7c6f1eaf6ea0655fc0cfbf7a773abc14d174ee861e6bab3c69beb678cc362135a5c2bd55f811edfdee774efc6c2b6675c2a94bc44845ed9bc711cb657ae894e80db0027c88935be4bd91966aba98726e111a549af8664dcfa9a343da9db39dda10ca22af7365da7a14d40dea90cb216c902a9dee17e371a538c85b7832fdbf1c3ed0721527204bfd7b75bae01f56a51b2b8c995ed7b74c1222d849a6df69fcb5502898c3e578668595c405a73514939d9b4a0be52c8e7846765c43771083e49ff08f3d06df2252a98ac8b096c729306b47c07b8000d6af8bca84416d7e45fbd749ce32952ef7ee2359bfc31ab36491f4445f231205d0766884d5ba5c32e361a269605a2836b092bb611e2aa1e8d0a761b36c3d7e2cdb14755ad1c79c104f46ae33f615601033a60ef387df1cfc1e2985f0052076805eb9900e67bb1e9048c6a303b6344422a714162c92c9f724311b7581e18b214e27aa099f507c1614a1582b1ecbcfd23b7809976ca80cc6cde473a7046207bc0d29af3fa4c509adf1f199c7171bf6a8d029d7a19e171dd272a7d95a268c6d1f757a65e4da37b8a63e1ad50fcda5acc1c377015bb942b946a0b6ac718ce4caffd229fa6f1fc2f8e02087c72dcad9062d2b7905a73830577454e6d63b602781056a43d5c0d39450fab97b35fa77456812bcc48670abfaf71cbab2e8255b5bc8113fc070dc2fd00d2cd5bc597631bf798858df26bd5d9398e0d3be2b8fe7d6fd5ded8b2694934b5fde4e1b713453b9397b2c8be399c1c835815485518e6ba6e8854e39d61f474cd4ebd752a61e06d7b76a713a7de9e80c6d34dc4069d0492768659bc8888e3d5a7462f820bab3adb4547e50e9afa891aaf477db8f24bc620405533b2e997f11276043eee6a3002ad901654abf4f3a89f9726c50612af40be942e809a2afa71c30ab00045a8d12cb57896e79ea12989dc79ddd43bc1542142c77af2dd2dbdd808f5d2e52f709f18fcc908338e126ab921879fd1931b720ed9e09c6c1e57c58ac310d8f5149037586a0bae9d8b119ab91f8951811ee7426dea158f32a1b7140d4e9402d68b26150288862277c370a4bbf6c296f440a55412cd1886f69d064bdf1ad73a5fc147129ca5f13ca8b9c1c7c816c2dcc2af54af917910dcabd247b614f4377a236aca35c4f8d29bea865858891afecac4acc0c6726fcb3927c12878a060aa4136b4bc3419b83f64920a63707ec048b5f9f1297cd38142148380f00f6d2dde4934ab78ead5c3414b6dde04c49843f2c54598fd511a5b222b5bd2d349b3bf8c555bb3980b42c7ee256878d3a8c8ba403d710a16e39b96fae3526abaf9ea9b99dfd7fd28579689e4f3787ed8000e1876fb531014e722fd2183371677071a6d2efad5d5725df77572c5d1cc20b9bae3fe89b8e0f393245625dcad1d0531ad787f69692e56d +expected_shared_secret = 48eb4b840c0d957f28808e434786c02a8f99d3464ccb3caf91cef4a0f8e70c4f + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 58718343322db0162d26965d5e946b700ab88d702fd5a1376920b5be702297aacde28588da91c719d40c1fab0af109742ac26c456961338c44c93c83ab58581635499545cca66160e15a35ba4931e2b91fee68a8734acbf72755e8d452d17215457161284435eb6a7a2933c8d146a12679143b80740f68ae052087eeb988771a8fb43b34d6ec79868a0670551bdd19cb5313892bcac9e4fb500d3375ae471a3ed551b2d9c76142b22607615454a910f8578e44b448aa9200d805cf4c15eb635013bb80a65593ff578c794066f05abddb850ff976c74ed6acb4c41064fb5eeab479a13ba57dcacf7f02421603194a3cb549f08c0d700790809ee0e585dce4088f96a740320c57d5a632c8bf5dc173f0f841173aa47ca42004b808ebc2a6a1770ad9dc06027557f80420db47b0158a1d1ff32007fc058875c4f5d21fabb67bfe8909e10b51bb35c76d0605d0e6a97e56cb93dcc58f722d95f33008b0a237b711420a20269a7097396a4a98be20b8226e103cb1136ea3fa39d438b305b63fa049c420cc378392b9f911bd7800bbaaf2bdd7586780c7078dea622df51c7190841585bb16bab9a0d83625d55826e3949ae018e7c4703ca082466b9a078393c30a4f6b7b1fc775c9dff7cfb5909cafbc66ea946e6f098f881b3039c251fd3ac142029e8728082f838a202cc3586672cb6285b021c41e3c16f5787ce6e319d849483fe40d989c246f7c36c11a991234ae7fea68770c79d8290aae3bb72ba014aa1279fd13977a49b0cdd494ca00c610cc2306059b695686399c1590f274f735142639425dd88026f8be0f260cd66672a12b5c7b5c7323408a2711677f062625eb8f3541098d079c13208415dccf3ff72d1999721db3c271f7521dfb0f129b3cb6885310a0689166a3b97b09610347ceea5579650720db621db20eeec24eec2144fb523ed2d30f64b9c6655928b3d06e1fd9b088ac8b7c964213e5674757c7bd48a3d066355f0249a50548f430c55a6ca0471953eb7c67e140aaf6322b7741225931622db114ed46b9ea997974c9ae2f54b87125ce79e8621d712688b50c7a49877d52091643a4a43148550135f27bb30ea131521583f5b79255309465f4b9f2233027855cc0e7c93bb33705136c88392cca717254640c540573d3a20032c9b297eb5b02c954c744c4c6143a56eb48f1d15439f885803ba5acb524f3d54bed37145cd9173ed92a00f724273787cf1b89c788184de0905bea74fb331ddba00cda70c1547c634c706a8447145489752b0633628ba4f5286851e1b5ffb8a7fa2bbad3f92c542ace74e67aa07b467e70b6a7d3056592b36a7a37c6c7114c610721e9c6ea933742e43609c41f6f3803e99a8d5a27b069bb73c892bf07524a8b2989633c96ccf33791ba29f3d575f249c640093046d1684fbc701ac633381bb349bb7d351230a8bb1a22223de3850258ac7043b887770a307c3746002cada2826e47f7694ef51f94fb9e3645aece6273298592bf00c0fdf14c07d8c9fca401ff351d2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b8b11d0e47c323d6b3c0ba12dc235d5c310ce2c7bc1f0a8467d627568a185855750e12717760355a0b8a756468e95406d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = pass +expected_ciphertext = a36c2589f709a16d07ec8ad94f92a168e6ad851e9b19ead54651ae5b5135f38d38eeb1e3ab60526f5724ef7741cb2bf962b4675042a9754227472604eb1ba179142c9b91a7cebf0ed64537618a70dd66f63c0e52f7c548906309e8fdcd30d573b036afb4c17cd882eaeee61be968c40ed5067b4d72a2b6a49e76a3d77dc36f1d9bd051bbaa501bfc89d3eea3439cbea585073aa09887d504d08a5cd0da0079f0698655ef809603d27f5b3c3146983c5fd8ab0df9d4e3f8b6f4781d35972425e13d03701b1aca48b7b9c87aa449bde4e4c37fabd70a69aadf9170359d1cd8d0c87121e468c385f099209575bbde29c5eb745d90319e96a1163867264383e6e908b9aa251547d15f8d95374e4e07b8e10e7f70758f19d76ab0d255d2870086db6070b7acc5242f92eec7a784515c584b9a831659ac86f3a610a09500b3a65a1f1c309adf2e4432111e0ccb6a2403de2d1395afa4d03de5a5f3c9c319ae0dbae6d3c40f6a4c0ca0a371991c7a4c55c21d50093e5257dae97ba3266a312e4647045780091194a40cb4543106dcefe181c104a29e2913d8d0491c0ee792b25fbb87f482abe52a7e38cae57af8ae52ef7c006e34ab21bf93127dbc744bd09d1f275dde2beb763479ea3f77db387703fe0e97a8d648a208379c9f0ace66bd442ae1254b26f0f3cb267f7fed926cafd59df43500564907e2a06eb3b6cd480b5f451f4f94562853e92974a13af6335661e69f16e265d9433a004402d9489f89e631e360c3ee3e0b2bde5ca53309df77a479371dfe9b2bf12734752127358f36a98fad6e60ffa1c3e418ac8c81c3a8f54d5fe592b079a871c0f1cf36bf2229bbfc5cf88f74757bc11dc826c589541d93e771a9870fd8c07562c76d6f4fc1dd2a2e82ed136f5e9981aeefffbabfce661bb5597e7710edcba41cec1059e96f15d667010dae62cce9bbd8a2e239c3dd762974af32e47ecfca58e4643c08e0a972b149749e4aa4a4e97bb89cf12acc2183125117435417dd3bc3d18304a8f56db2e88ad5ae15d20a7f68ffdd9f7a76355e28f8d308604b6945da697d85c5c965383e4247b03702d2cce376b651cce0c9a36f26485562f6b38d4389cb855f74849289848267f17aa874c475ec41da8e4548a3ec47a389d33e20de412d3fc37e630965a3fc919672c43865e9cdd9282f23401e49b9d110f73886a00c839905e3fb7cbf2d4b881b24d5a34a2896a6a93ebbd9cc176f5a00b7ac139f477541e8c2c412ec7ed30b01bac78595fd18194bcd608dea182c741af8de1cab857b551b7a541bf76dc6f706e32b688401435e25f9ff303ce8a487ce1c5140ae2a1b1aefb25320c91cc641cdea55069acf7d261d6d5539c0dd11789ddf6b7ffca89a2166a0ec7391db587faa543f17d98b16991c50f0d6ccd5ed6c80aa44a3ae3172e7e242e9569a1df9b1def0851d9c150d5a8825151569e56d06a53e624827c0b99bf586ec7a71c09d53643386309c74e25e329a7b3b8d0f3eeebccec064d83d98c8f1f6ef19aaf28b6b4660 +expected_shared_secret = f9507f70421be90f21138a1e135329ee8228682cc948a6914ea58624d396df0b + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = d8279f9a0681cb98bc38cb551320031f46262799c182b0355eec82cdb58d750596a4e6bf1213490810415a4b347e13c9e8514890a0995843936be342e81c7f4971bf9b75925d61ac8c961492a85d83fa8e33c12fa37ba08d7c681c521ed4060481f58be673007a081321e01e21419e232283a01cb1a4481550dbade263382eb93b7e42470b265027a933c480cda340a9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a3671c18479db082a706768a63109d2c4224d71c7c95755ca24b056c355e9c22cf5006662b3218edd4b317b19962cb514af123245b152eac41391cb432c6caf9295c66da4e5737ae3d60023f46aa7a604c64a6c403306ca4b96fc2929aed5b4ce7e6c631b473d7d61cbcd19826ab82c0c58880d77ce8f9bcdbf59d645424baaccce334809b43acb99248bbd966c88793a273ae857946902649f97b5516fa2ea2a84fcfbc054653852d8421b6b78c289b49080c8efaf85df195ab5562a03e7099c43c439a25ab41390b86db4f57188f002129f3ea1ffdbb9e9c688ebbb26e0d7ac6eea395b698a134f70f98480e87313b79444963557cee82534e9c1cf10b74718caede3bcbd98a68d9956facd8a45e2184c16b14048b9d28e8bfbf5ab43d1b650ee8cf13148caf451cfb144656052cbaf82e2f765c8c9c66c23b0cbae0257d6000f247200ab87f93b5167478a27b42ad7681b6919529bb1430dfcc809e171a334b33a0527a1d9519c18130971c55f6ec172b86248059830fc57c7356c9bd8263f7d571d0f7bd87d2a1686a7c41db9306558cbdf39f0176959a188b4d457b40c152b7ea09f6860d4d945e78c45eb68b579d48774eb26ad43bc1be3c0ac327c80b4c1115c2cb58bbc24a18146470abc223ad51fa10eefc311f1ac02af4c7432210233a4abc408b1db484e7885d239c0c2b9c4952e577a8ebc3d6a7684e711e12db96e1f988df423a395301d2c15fe2f1abf708bc64147a30e2717f7868ff602d50fa9a3d0b3a0097259ac52057dcc14319c438e113da967f6dfba4279245b72cc86cf724c81769dae271e18c0b6cfa84b916ac89b12a1f8b05d88527ad40346775cc832713146806a2b2884e35628169bc12f67811b507bee3bbebca81ab93b5d700aa92898b3f5cb6e9d345483ca3743457fad8cc5bec2a8e7a22a41ba8b67641ab181d42abaf94d0055206b648c81361f8486408b610bb3552299316b5c0b7d301d9f1c3d55621859ab2ee922c59b11ea9f2a1efe277c534128f2cae6b598c0fa059efc2c24e8a0c2337bc2c57a0bc64a7fce190c656b529d21244eb66a900288b5c484bb033020b9b9ba3019b72387f2746b3b893a1427882bc3135f0a17f8271f9c8480eb60732672d44336b32f851a283224144c480aa302c05836edc1ac4569a6020130b341466322d17811229441c4513a2e8041c85e035113992f16799dfe8c1eef3aff8ca2f341628808a81e8b66ee5ba47ad0863c735a904565f036a85fb1203058137aad2206c303f22d3027e732542a342caf3376d6b065a745e31e865fc2243da31ce08eabbf8183b4294700bf8928da8ca78bc08490810c39747fd3851211b22f26451f6772e0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = pass +expected_ciphertext = eb9daf793643df194162e69b6c518b5c2dd3eb2e3a02334fe7d5fbaae8cb5b1946998a06dc8e3ea0c2e5f009e2fe5214d735c46855fdbb1d45cf47b78ace270537aab983305cb7b2d31e4587d71166b463f3ed2c21bb5e2467682ff74ba01cdf6aae255ebda0cf205ac9dde6d55a9e3c0ec9b9383f2a779d2286a86988ede3e055fbed98be3376c7f0421d629d34d753486a0e80a53d12d1a2ad0e8120687a92455d720a072e5df030d7dbfe55a7df9f144b34e7686b3f75b78d41043e945b3d2757e4625d0bf038dc9671b16c81f9c91574caa2d9ecbec25c0486c525a6b08e9dbb3de04670030b580d559159d0c95f0f962c1a0c524f10244fed82ae8c161bf97683f200a3447d3dee1794ae518a6bc7384930a6dba9e761498ab266e73aa99ab3235b65b6d8350652efb94f28e54e86e63628c5d86a88051400deaae123f80cf0e35c3f9b48a2d48e7588845bc327a07a9d2a0edb7ba9adbfd257ec2529e2bf93cebac1243c91508c0ef7b61d913036681468fe9768ffa4789ac24f44327035561df783012e768139313f5c58aca8e47302a5871226855403d9e3e862b20ae66c521135e67ecbc0b947f92cd1cf8f74b2977e826d513c66e00672b2d16e693aa088441a32b64d77387e963876ecb5853ab458ba1e4d5567fababf1c9efa0a255140c94c3f286600f04e87a1cfc5c4253ad5c5c9d7c7e614a2f6808ec8b9633d1bed84e1f6f27aaa72080b69ce6f1885cc63d9ccdc006139e67fbecb07e56a2ab8807f2f0c09d22ee1504a9aaf086656bea5b2ffb8d2f9ec1c586caa86ed3db23284f5952fe2fc4f0cbcc127071b85e1e6c6a64a87b1ab3f708b40812854cd3d187ed627f4c3612433aa2e0c4fd6709c4ef07436cf31801f6f77d6fd28b0e070b54191909d443d24e95617e39f7065066d65eb45353e80bbd11529f2c9385606a96b6b7673f258725a1587ac316dd56dd3d25bf2484d855e59d77a44272240116d11e725ac45766759dc89b3aa9e5cbe96ff7df371f4ec039f1472d241fcf233836b3da13224d92cc710a6caef02b2b77cba408539403e5a9c3f06c6984d43e05b5e278898e3e59c28af7d35a1a2fa982c7e014b185c7456a986ce41277122c50fbf2d7dc3014c5f2d3da0773f31afc83a138461ba19b21df959be21e2e9adbd059d2a141439cfe8210bfff745a5c3108dc34572ed87d3b60e0e6b1ac41e1d7a9cdc10e16ed2ecc2a20bb4669bac747726c8bb112874f48c7d618f0273f098e249e2ef0ac29953737e036ebc361a8512071d6fd3bb6d8661463856e387819ff9201476178f7683b983cf8473ce6688d93ed5e6a4be6d2fba23949a25bb2a1ae3f5634599ac8c83515d8d904357972c659ca5766105ec7108fff659f428f3100ecfc2bfc57f97e87249ed6640d47948ec2376268180a7a627e992930ac7d7cda5076ae04a1405b215d5d5f8bf98a40576615e02c3cf85aa6dac1b47632c66b947d8da73b1c6725032f70278177761ea063308d540a60acd162d83522fa6d188 +expected_shared_secret = 24caabaafe2063f812eaf57c58b6c0376ed8ff778cec1980ee9c3228801a75a5 + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = 41aa7b69158362a41767486ec3da09ab4335fe2a25dd6c07366478cda91c691c5ed9264f771124c1f3693050802f480f5df89d5be189da765337a69c5c838488a0a4ba7880e91871fe346cf3abb0aaebadb211b5acd3b773c9146cf97920e509dc202f79b14734c9777a567cd44a43500b5eb8005bf4c5a387701286639e6d9ac2574b33f2432b3a787039e34b2ae511a27825cba7a8e09b401cfc6123d3b4c42318e7b032331230da960a09f61a6a196dc185bb8bf1c1a6b691a06cb57f12be1e45269c56490e256a83c13352a878c724242ff0681881160ed03166612d69894951d65b95e690db46129d149afba2c835d3b138036931423d2f84ca51179466a1028d1601d5c397cc81b1b5e468869185b25095a0e5b5dd6a421b5c7eceb58c4cf97b7feb114fbc435c78857c65098d3017ff8a58f5927e5ee7712fa0c2962939b9d8c84bb6428b3902881188df17479ec01e4709b7840235ccd77acb0bb3a05995693781fb711d61f2883827a96ddace29a9cd43ec6abd4691be1a758b72a629f6aae1c795981c0d8bf8160bfb3b8f5047e1a410cdd49c6a42adf0bcafed1b21eeb95d504b1a48b1ace228bb5e1508bf05128f0cb63f5597851b9df4caa5b6ac10f7f6188dc41b02761f840caa42871c55205cd09771ac9125d6265ddc56a466249fbd774ee53756035349ca12a48237221bd53d7ff1ac18242442935ba818a3b50007a3fc14a2fa3abe437ff14705df0cb5af97561a608a3fea42a809a7a7d5491453c849dab7acd99636931c007a70d01655c7302f9a26012c494de47839c1ea2951a87ff73968dae83a86f392f021873be4c75d2b0700a3b540f50cf6fb664a4627dda9c75394032f434655755d12d4c781e2324ae00dd61744cef6c5ec9680f379a26284bf9590a33350905e080e9b70547ac1cf3ad888f30232fdea7bd2c184f9e1a9b6835401e737204c5ebf2b28f2b58edd399f873c7849cba8064b8a20c9c391841875b4963bba2097b958d752739383bf26787e64ec215974b45848185f44b8780c0714b9651a7685e673cd1b6230c5d6639ea5629c20659802bc6f2b95df274836241165a524ea99a941312fefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2d31916522701d80252e9c7fbd7a17d306a4e1e02cda405f3f07b38eb65824d5c9d8b91f7013784fba0df0348f21b00ef5a325c745a829714a5b9aba16acbdf029771d5415e867590cc5a57360a8969407f0749ab8a08a65e37e70146fc1b7bc40d789eae83761e77749a07859bbc046b5a87e3a92a5368251127f12d27789318f8b9c3c1f79211922c852a0b0e10bbb631599190b49a66937920b3f113185d89c6e37da5f7ce9c12d37c12cc24741cb9a79446606eabe8c9ab06d8963c959955f198e03a0bd127242dbf2a2180281a7b65f54c28ec9c6cafe64881d6456c07607cdfb89e2ca2fb3ba8f8357720051c30952734932b08b508402a6a2f4f9c76b053c12a267618928032b5d9e41990a18c2c04ba7c2868ad9f4538ff1b494707eb9da6b81374d7f9731f9a26089d7033a8c24600944d65871d313387b4101c0aaa27ae19d978653638577bcf4caf48083eeeb57f401544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = pass +expected_ciphertext = 0b19df76304bbb9eac107e0cde980f205d0be113062aae748fcd6f23badb6faf0dca0b9a52a0c1a45fb39a5434d97795de72799398a6f7729dc32bc0fbb724aeb6a9742bb8e1f5ea50980b79c61da2118aa15b92eaa122bcaf059658bc763cd04a22318f8db35b6cd62d7149e4d5896b651ffce990974cfb4b0342946c13697e68a5ad08cd94b13b83a78ef022754434636363dd2314433a11c96123bbdbb242cb1224f31b1b171a30b975ea7f6e2baf749c0eae2271d33c58a247c56bfe1c362554dec75f8ac8a4d170009efef05ab92f0afcb47b6afbeb88c718430a98a09085f377a34c84922d1f48c004f790d9ece2eefca8daf3f44cd526aa074101a3ab083f05a163601b68e16c63eb293843d0aaa8e438ed68e71227959fa9baaed20eea22ae66b8de0b7c19f2a777928fba4fa17e137cc40d14ae3cb8a711cb4637f3d94f16a47b6be2345cc046a1f64c1aa0886098731cd9809a3b2d40ec95f6c7bddacaf68865cb22c32b38ddfddd008f11065167a4acea5212b1e1013d704ac9048775d6eed6ada96294971b6da0100def9a754e57b9fca70592974ac72a6db96c38c18844f5ef0c213cfb7077b11e8c53dafdb091fa81445975f38709741a295d46ab9e6b1f2c3449bf6b906a610484cc40a2c8ae35ab4311a08cc5f5e9caa90f8c5c03ca1e4c02921d24d38eea84688353ab5724ef73b16bd4e881376b78e992e9105f85c00cb30214c60e70b16e37f5d1c8997d7de9266f7f4cf419fd0e1be6cc1ff2128d3b21b46c2782af8c805c7fb7cb441ff4b5fc97a94902beaa56df272d0be1e48120dac00bee41e8795a210170eefe920682468eba45ca106e6e8a6c963d8587734baad6874229f8ccf5daef09836878e3ccb8edb7d0d3f10c466781ad04d943d478d40a1aead1537073b405ea712b6e879983d6dffda1885e5bf4354508c188246b4e205ea087ac883843d868742247a5fbb66baaf0eac8e5a92fbb8316bb5cb560a72a140ac57fdf41682729a69f2e87bd9d096ea7fe2243e6c958ee394158d70831c9d06660c46d86a14a39c8a2566588d72118eb8d53266dd16e35e3249e16aa16e0d5af04966f71037698e278e129e65de8629e28fefdf3cf399277f0eca62e9ff1f1d18429a3b06402c88e30d47aa4c1d5a9fb1cddd516ec907f3c97b0dd3076504b083004cee7db4a31d98d80c751b3a5ad56c4299434effb58b86149869bc0818738f95ed0dfb269b2d7a4747cd3d08036501f7b20fc0e66635bd89056e3de42228a607511a85dc37682e4c64a89c0592b86026d0f7cbeeef3b436e4d2f399e68334a29f514825ea8cc8e0b0e61d97391b3b62620b5f288e271365e3670d26e2e9faf37d41e3bb0cf937c446185706713b4fad79c5a4e358a3c208c37c66ab57ac40115ac256feacd89bb5ad0ae35c49cdabebee5d1f051f5ce2a5b4b23f00c53ee4adc430f8aa74f81f92871a4f6c87ad22c4d0c0387bb515e3acd8865fc1a14e9fcc5c4082fb0a1b8247736a510f45a2cc31f4724b44a0 +expected_shared_secret = 9f734b15fc7dd99bc10d6cc7de5d2c93ac789a5665e508a95d075dffbad25abb + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 32b6c92f059443501427ac964fa569cbb074c71053f179bf1963ac704489ebb9936e23950e51ab7e26a98d6031c652701fa4ac59aa7c15d88c0337a067257b8d916db0456fad9622f44a928df6cce84a3e6634c9caca246208920c487b9a666342abc389c14c499785bcb91a95dc868fa20d25b08ac0e48c72e9b486151f21b11731d1bf049174adf279f9020aa98c38372877299c4f54a4493a3b20f8bc71cbc490b363c4162055cf3a5c13650db1154687462fc01b5e5b78c9f603255a24189b808358e17e01b9cf736a77d78a32520b6ddc9c1dd65a00e84b562b607b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf040dcaa766bcc18d6b8a2f91e51ed6d49aa37aa44531bd9dfa25c116a842e50f53a68bf1617245e8b7da778eb3343d3f2575ea84627c640a6509133f4c5d78151a6695245659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e647223c0154388912ed028ae364a9fa9a018d8558c3e9b179b66f2488c2be8792b1849fac0401a9756f209889fa637cf7ecc4f2c0249eb5c6f7e0219faa2a9433759ac70dabc7baab623c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d467273268a0797b8d6fe57ddfdb03fff7ad3d5b9c80dc1939720ee8810933a04f51b78262910d7e28c0eab06b91980b65056472a293f2361183125670ac2426e514790b945d6b09c9ec354fe7c895a30231d95794f89ee60761ac9b2aaa9a75ef168c0950afb498915b2518e010c3800764bc5a65c0c54b2af686b7d954e77bc4cf8137ab398fe93429dd0ab80fc846d4cc8db2b9b2b4bb36d4c4121639c1e74622e59250701302301b4df96b2fa62736b29caf0866096f842898b2c6012b93b5ac23d1f39e192002ff0b9005fbb8cfeb8930562a4e0aae7a40c5032b8b33d0760d96c7c203920e2439d3ea02372c7f5d80b92259349076ba20c3ad4fd21752a3963cc5126342a963a363c1157f33189732f7243e465b14969f1ca199af45b50851266742151a235a8ba9a595534bd6aa31ccf52b8c5885d571a93d2577c57057e2caae68c9c84f565c72681fb15056a345236b02a1e5b13289388f035a2f8e03402f8b0a44259179a904c94725319acacd28ac1e449b87e8916091940e33861a4a35a8600267f04ffc6a3e06c60858d578bec60ee7716fd4b0225e5cceb5fc5437387522200f66fc880e0c874119c71f462cb4eaa24e67be77ca67278344199b27e2a55b50f372b65345122225d7324ca9504ce4d12bc101639e93b331e3b60e1b520e03c9703a69f54c2b1a52254ac44b86f310a711263a5a9b87a7116ec5654f7297ea76b63f939c1f49ce99d52bc58876160401558193ad98c7c8f4b6822712429679214bb2b6e8b324b58e1f57695dc8968bca7ec3717df12c1279408183b49679b349e2e45686e722c3a57bd9547a65656cbc79aec1d3b129837d84a6975d018c7ab04c88775e9c68839955775fd66ab02aad69b76307f51db2ab33915aca61969aeff14674a557c322af6997b1a8d9c51445884779227ee742986446ea1719808996049038e0d9aecee828ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = pass +expected_ciphertext = b7b48ff76d8b1709c67027c3f1161313114a848d6c0a3460850f2b08556a47dd82a0ea4e4818a1667882dbff42ff428caf7516cf7d32a31c6efb18dbebc69a7bfb17c04eb69bcfd8b8407b85d4e68118efee310f122b077560af4bd157bceca4b72a1b4e927ff144b0443d3fc4b00ddae83dd88c33e728b7520944cad9b1106d3c43f5c469efb9b00068668f0ee8528b0482ed82cebd51bfd0c0dfea9ab42338f3636a369578792e07182f379644219159d90ef9b309b312309f3e1b4e6c86ea904f0f49fff3469b23958bcbf00a4efea040530e20d4b8a19e7a67fad4f017b2e03224f0e2bf9cb88055743cad55c59d7965a490b1cab9be13852bfaeff93799d08875f55a765bb78bb7bd3bfa6573962a233951c99a8a1ce020ac8f2cad10927a766d4fadac01ff066f8b42bc071c1de33c0c0bdfe761cd607020ae3e2c559d77717dad70f62dbf147c86712d92a2cebbd80584f1ec5dc10cf94372d772e6087b9f73c62e7994eaaa8d3a52f2f7a623ecadec7d9cd3634e44cb282e07fe20ff0fe7c29534030b12c1d6e5894536c8815e7dcbdc82f291fc8309af952c489cbfd86560db108c731c877975bbc076435c227c3c6e5546c9c9c475b693625de1896ff066e24ce650483a2a391f31ebfb68e172641a8be54ffc35f09208bd2aa1d837f9302fe2cd7d54dfaa1f833c85222135609b4af0901daeb0f46a81dfe8396aff879acd5ab17754cef6a8f1406563f8899f379fd1ff99371929304338efcd3465100e0e7e3f94fcb26f20b28eb8367b7cf3d34f74ac992b5c37050daebfafb35919ce6703d6cb3c0b1cc40e7b6b8de1120977a5e7d09943423f0939839cb6bc53df64b387ac018fee33ac33d780090ad582432c4d61514198d74acef79ed0c8710243aac73bed13ec6661e46d1e8605634578bd17e1c94b1e705c6ef1307cd7f4e828b30d3cde1f65adfca10439ae9c369f5827b94c3f553d258573f0b7c7884133cbe8277d207681800291c139dd0787f0800763d79ffbe667c1c56ea8bfc020e339f22edde053a4bd05f345e66322216b56c168a7b11bb1e630ec1fc05cd30cc3ea0ffac9a223e3aba860783728f9ecc974a0279f307f984baadee9091ad4f4db905dc75014a29e9ba246b2edc076f7f82cf5a49c4b5f85d3b3306dd9d391ed8500a7d8c567cc25f0e25e46af32bfb44d2f57d59490884b494e30499669d5e8e0ecf5b0f8024e0e1cfb9d25d5152eb7b010398f49d169f57d7565a0b51edcd362a591686d00c6c72bb1a0a93c05b52cf13b82b08e4f28062b558fda675c5a9a2fe5a0fd13d7fa0b54ca094935971149c35c0feb38bb658e929d291920fad23f27818a5184e15a7db054e4dceaa162a1fad1ad647ea7084440e80e54c6805708c4aa9b269c8853f274a6097d313dff1e36cc789806a9acf77f1a18cdd88e1e8527abf12c3ac3bc45b506939f9cf8cb65a66f83fabd5037477cb29a0a32234eb4034692edc2ec6a8f79450f232c443639979d2d4a442963d7c63f04a8863e42 +expected_shared_secret = d27e55f2a1f9ef336c8537f11da9875e03cc7dde8951d81b0740457609654107 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = 7c6b065ef3308afba0cf3607b2c98d83f76f7c058262b55f7c0746b3c22437f00de9d7cb69f40afd60ae74b0506afb96e30669f51c464a27b4f177666f92459b293dc208a0dac5654a8058a8fabc2d1853009743a598bab2c248068750f01227be5a4f7c4c6948f9167e88894d43b5aa44687ff177de837e2f0537f708a8f73a11fe6632dc285c9026bb23424ac2d1cbce39ac6a0a7686f088d617b096436c9f773e7cc50cea1c08db20c2949a7878d18e7372cae746b04558a8fbe97df0b9a69090449a507e6e1c07a35680412033127037607b2f0502690b47bd300a84c041650dc748ac2c060260c933a0b81847243fb3267f3cc8dbea4cea40790f37cd0373a71ec00634bb3b3b087a82ccb1e1dab77300156d8094a1d61d1f1bb3f977b749c938ab8092d71c93394856ed133075e2bbdd3cc0f27c2a2d34bc0f633f5e55c0a6c989b1e277ee9132f8779923eb2e22f78a1502ba5e55b6d53a05137867c10536e672c7336a3ea1f237263a6046f260ed3871f1d479be589744361a0d819439779075cc47a5a33e18326615134d9f09b68b6873c6ccb682f6b75662cecdf5432c37189ae09faf36735ea01c12f9ce64f4116d509c70e0072a242ff126710d178daae86539226c92d090d9b60dc63539f51b46dbf24cc8d54eda255e0ac19b03d34f5a270b6fda6d6408bcf1d2a46824b5290b8a26a8131402c9aea052d0101759345f86a66a4d238a20c6531d792170c52deed889ac3050ff87c659524337830c205622a989736b788092101933c0073c0b686106a9b88c17958a8711d272392ac448b01507634df4a23846aa9d594c80bca99f17505ac1793f2877bab4f1b211d2985842795c4c1b9fc018dd15b510556ef89b687e6b01701cbce0b56159a90f7b2c6fc1039aa38449a596c087a62b2ee5a7c3799f5a601bfaf8b9c598834fa115ae010f71167fd41b5cccc45146009752f380cdc56453e554cc779604f976fdc34e9f135261eabffbf00afc514f2699aa6a5aba0638542891c6858c7f6c6c4a12e4ce2d89b50b04c33ef262ee8b0d9a7777d3c56c85b1bafac7052fdbaed24303c843110c1892381887eb351134798b9745bc229208b277c2c999570075903deb530bf22f7906b75db35c3b24b04751bf6ed41724058c70988952d86b48519264d25ec2b817894ac370bc081362c841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d21470586510acf76fcc683035b18c05eca7d0702e0453ae00a8144779117d7c19cffb568a3c0959193d689a6adbac13df43907fd45fbf3313d49425d32ab9d81c6bd9b3486c3636e6e0015152c1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fcf020cc611e3e2c8e52f5ae886b8d9480551d012885318e5e6c1ecee0a3d75b342667c691d19f34fc7946e7a7047097f7938516cbb6c7f3abdb85b15e302a5547198ac0b89e7c2bfbf74050970e8dc746cf16bee6147076bb89c5124a89e070a785427cea590301cea7ab28ada228ee7bc7fcc17074063358a706989c8d6c82677287905722cca0a24ff91958c44a3044787eab3599eaf241eadb932b06b151a1a02ba8b244e9262b96144302124dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = pass +expected_ciphertext = 0abaa530450dace740e8afd009c206de7c0d5d5e81fcfe4034bebe306027fa8372da9cd5e10572bdd552e82a2e596dbf9b6571f8a009613b4c9795d44d377353eb4f9ca13c2fcced279674bd21d310f5704ffdc74b4ad98d72648106171cdd082ab3f78eeca66e7355c012838a5129cc0084d722948d24f00a91d2be8bc44e6dd949c1e241a22341e3256f7c751b8541332ac389d3c57a8d69365bb4c9a4757dd870f5cc7ef86aaff94e26858c6f006dbd1a63bd7e09cf5e4fa6b1d2c5e03e58c3d6823a524a76336db51447a17e64ed42e7da5e9417cf0b447f32143e689ed01c4e2e5a947bdd5e2f2f701e407276c341ef766238c8e04fd1c051f71227771e36809e6a53cc68c303f190613334737bda59b4375629ac14cf16d7e98bb435b9fe348cce9b216b6ad2e6f95aab87bff03b49f440e4e284ead23353bb85c81811731705fdace139c7264797eb2624ce48122dac337e146ada469011dd6a8e3022eceaf82b27938be256f84e74878aa568930ea88e6d823514491eb9a27d956452a9aa81b9a2068d3e4fa1c27e5eec5649aa395b2ee52ee8e87033be00e7c4aed4e1375d01a7be8b16673bed2758b22eccedaee993bd26b91e8e0c25dd1a5bedbc55cab0dce5e308259efd45cbf7e6185e2792ee36a453c693da35a668d685a8d70d49d75d4be3b567fcc9a978defcc480d2f70888db31de14cf90a2f489f020358095dc8b7588ddc8ce441fb1385be6843a6e36e5775fdfd14f03018e33c5a2c027cbf4328106c33afe57b0da9700e27b3d25f905438adf34a23718cf7e6ca992dc72b32aa1c432ba1792a626fd91ceefed47c8cbec2b9cea537b0f9253cf9a11176f3103c7a98859e4211e995610a4817527977eed6ea70b310f1c91ca5b6403118084159e84b497c9a995e3918216d5ea0706c89031c2d5ebf8febd8e68b594f00d266e41ce12e3dbfd16c130d44a0378b114dce1a6eb50f227d4d43f1f8d615b7b278546bb53dde219677c980f215c8b2b2284655e596a343d1aba0e277b8c98de9df84208a9e045828a75b1573bb15ce0e8d7c39809e57d118e0b8fb2d67d72afbe8e9750c4eacd95c4a69e03a16911d27f1bc5351a35212e69241dc4d780fbd4c9dccf01bb79fc2a40f4c29f0e22dc552758c7f735a9bb13685b1e45772b47a97d4312359ff0d3ab6191e572bbf9505210582a470e58a16b3c5cbede72d07802d973e09f80339684eec8fb84ac613c4c869cfda4c6ab82ec54d8d3aa70bdf89c792ba8b5ed3c2b3632fd391e43fbc66733212d439e5a67d20f237c2a0f782f96a9e2d93adb6f1333182ce55056d4cc807098b5333541269a10935d6132fc5dffc549d99b25a1f48d67999e669ed8b5202f0ce91f3f368882ad1eb67bff3a6941f16ee6349019bd41433c2ddd70f7d5b789b000503a2ec1f48e77869240ffc649b1133374e80a16ecca2e28baee086b973aeccd3692fe9597d934af1c53668af5ba474979d2d746156fbce5cb86367134f0476f06c94c3b52ee1f1b675a67 +expected_shared_secret = ed5903d1cf02861444cad7fc3793b4e1b9b6d0324bf6babfb768bb2f84300086 + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 9e686b49d538cf32a05ab82372f7525df40085b3413f078226b97c234b815ec615b2683f1d9ab32dc0314c6cce6e9620c8e73b1dc85bed5205cde5a44f40427865a62356ce44751c7278a3b236bc2d208c7b383129661810a6a2962496d058ca4875ad234c2df951612e665984bbae791c279ee835b105202d4751f1a330dc6b0bdcc38fdd6458b0ca7a9bda026bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847487142561863b5f38c5aa4c0158ac28e95012c10a8b8e99ef7db12c05009311a74791c6c8b355e4a861dd3cb6fa085884d7a7e8cd270f656ce29f9bf3b91b798032c16b00f8cd722a1cabfbb25c3002324c56b66df87182504581a76297ee1181cf05a6d89698cc94021b16574264435f2cb137a7a667a4548c96f835cbbcf27805ae37448674aa998818cf26d15a63689777a9b98219ac3b9ecf84203826eae294800f5a07ffa886cc86e7d095f42c471c121a69a1972a7906abbd31003f6c8c0d07ef481b55fe185811084d9a472ccbcc586b6a9a6f24d269ab36126a3f0381b29532d027c2d5e21cc5b9c6ec8303e4b388a6b7216b3e581c0566558107c8b94c599f09c2ecc4b7a824fa3db9a29722317d5bc5d43827f4bc6d3a91f65dca56bc26de9d40bf2f69263cb010a9a24a749c931631ec2d13ea4d5136aa8a97ee019ae1291ea34b0807886ffa323ad3b0f83f82e5d9a2d748945a3ca34b9535d0460a6f734bbeeb66a4e3c257bb079f5d80f6deb0dbec130fe4a182fdb16291403f37a191c381723965c3fd90d9f2b67c36ca3ac141030ab516a01453532aa06b73a91b5ba7d1a308e286fced38f2858801022a453320a857b564179c55f0436b25cb191865de69877b47041d9d0c2c9bc42ca513f207a72ea9a5cc48b573fb402ba8b5ae6d73f2e0b044b8ca67c1031577099b9975fad7103c7f6bf80099bb51138d8a7af7bb509b761a9c6407dd9826b7ff87879098248d779d6f26aa0215084f286ac77c50849ad19f29a32b07ef517000ff71799d6be1d177508bb969d9479c6c037a5a18bf4302720e240dfa603b7f8745144906bb88522505b19336bee5572188853a47b4f8ed8a040b251307299be642e086317e1504784990f2149cb2d89b1a8542e4a19cfafd57ade9a234545142afcb3e544b49df75b0cc78f5aab935752746ee7a7f7936777330a66c1063c50becc4286a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5db8251de0267ea3c0eec342b51505469aa7fe936a5829463892645438a3a182859da136e033b926695421a1891610816e136dbbe36adc08cf00e4b44649410b2a11ef254144c27787e54cc5a533e8e54f11ea94f7e9c2009d25a6248321f04a53c31787c12aca9cc78fcc06b161701852215bc6c29d1779f5c183152cacb583a90399746f75c5bb337f1b580b9029b112579884f792ea5a52187a109f547cda89b7fbba90c66065a33423da4515d13bb5ffa074aadb0c55119065a51239511bb33288f994b121da8913992b979a59bbd64036968621e76ae336096fd6125cdac4f767a883e6448b078dc04b1f2b7aa49a1180c0f3bc65d2a93458291982652063419a9cb7f1042c38f483c4a90e17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = pass +expected_ciphertext = 5794df0ad781361c6821319687c08ace02ce58cfa47ddb4d8d9659ecfc28c7997b98665da6b0e985ce869168935c6dc81877db1c88d3aeb37515cca3dbdde9eea44707066a89fee8c42d3c64921c97accb8b62249e20d248c7507d5b49a5849c54bca761745c7d2c5f83fe7551795d9c1979cfec5a0b31361a515d95899cc121934065a0cb0f8e8aab6f6789feda87579f26c14c76081ca22bd24f65c5d1824ecf796520e2ea33b9feafaa45da662c032e866b26f5ab26dfc7e7baa2e4a1d14c4a3fe70d3aea96e5a68d7118706a7869e37651524046df15eb0fe51c70b89b9f6462ee7481ab1472d4f9997a65e06650276b1fea8af04fae7746309307aacda58e3af745df5f02e9102b8c5b2d981321cbc3ec8476a2f7873ca3013d4ad3b9d1914d331a97ce1eaacd85f9145759ae255ab80c34564794d2f58c00a1bc10e69f5c28934b163ac554512b43587af22a43cb01471ff8ec21cdbc2d708476036805bee7199078b139009ced9b39a402bf0744842222515aa55d8d86d2fb04e81ee7a8fad1d7b46862cedcf5ec66503bcaaaac78f336107c4b406c4e67283b0e7ea99ac08d222822b6721f1e1669e3ecc52573d477c6784ef31637808a50bd3ae98701bd1a8831e11692be8e0c84474c9ba739dd01fdb24bdcbe8e9a3a12082f20ded7d06ed3bfbefd1f0e90ec2dfcb1cbd039f1e5c4f657296371ca5f2947b27e686541e8991603850422a2091a9ad87ad342e936f0d78e4211710f8b51b947e8a2aa98fdabd660119835eeafbcea6e2bf2895d22d264a9d558222926469d2454fc948e843c0d086ab8980665fdd0f600d03a14f14b0bbb2756a2f17b38fffaba6ade7db5768c0ab9473bc0e1d133e2467020c0ed4e53b94b722a3ea63ef74433a49ee5856848991cf9f0b24bd39e90d57c00dd86ca0bb4b3c0af67a84127a41cfc3d233ea766ed7de7784c9fc0a422f3f0d2b6432583d93d001e167765db6af0aca9b2320640d83d7b41bead197632aeff5b952ca216c0051311b6547d04f5edfbcab178ff1891eb6e42fd6c2986654b58f41c644b00785201b26f4606bf4b5c0b3d4f46d1f606df167be6584979b1d26d3f8b61a08d65c6f733c6ff2288d252052250fae9373d9b3e2b314be7cc454b749fcb6e5207d051be4fa345abde67f1603f12a5433a54d2badeb7a9f5912209b733f2682e7d39208af7a21872e4b64ef835a41e1606f8649823aa236b47579fc8263c2f812ad4846b2a8217c847656e2d54ab774fe8ae617a341aa2b3fd2ea3f6959bfe58c26a9db8c3badad7a7557c7e75ead54c9bf85ffe9e4249dc1250e37c9bfe5343aa0653618e0e651bce7dec72cb14510f1580c43c8ee786ee3ea87499c80183544a48db67b8a8435be1e68d8d3c6433aca5f42c8fdd3c144e96d3dfeb60fb1d9b1d92d8da62e51fa1e060c973ef92c5428e9be6d0a547c9aadcc47e35c0e7865b6493dccf4381da972bb51f99d7b6f4bb7ffb8950798217480a4230859480aab0586e2f09eec53c2f4f645f82 +expected_shared_secret = 0d301028c1cb31dedc8a702a9e95b7d3589f68a6a1f600af84ae0f543e625361 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = ecd4c65cec93a9b26efe3b667405482e3aa37d48aeea67c1698008da4b68683697dfd34fd72a6f39ec0aa0806ea5c59b4554182f6034b9c5b7cb438e21a14774d58afab0099e478a4ba8568e192c71db7c208b7115d29bf649bfb3d23c2d70599682c549ea28dc16597a43aa6e65c77c432f554b067a64ad62ab71492a1aad6045677c74e3e8773fb8665259abd821bf07d2157c09199435bf41992628534daae814ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0d828174805da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5da2467db42479b478f0570d48071f028110f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b2c12d34027aede4a22fd80abe26a9c93c938c6b1348708d1bda7fe6c55bf66981695487ab81362f50b7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c3a2181b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee4a13b75379d2776a7510abb21941c2b36357e8248686a5d973b946b82e40802290651a073636b367671c9c001ac91ad03b9d6e83721ae1247cc188fc05b0249571656a276eea09b6d3376c208335618b1fc2748655ceef805c39165d0ce9bfed062add0c0a50e43167c80e5301a076c9cdc1f13852a5987aa3cef5e5864a706b3de947d2ac8e8cea0c3f83745bf3185bac9fd0162510f70bd20129d7c5215026114c4b5ef044a8a29a3f01fa02a0a3ce928a65ce8cb566848110994e7ce20ea5c30304d6ccbc7477bb78b3ec527758b7828b836dbb2742af6095a0bb882c2c9d8e162618029c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca85218dc27678719ca0d4a8cd8e9bcaeb944b7c0670ab171927c56c35034ad92bb3e6714d0f7c137c2b9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b68240ad193e95c0311aa501b3c1c44b20ab6ca2d2de1c56b65618ca53f0e91550851bfbc289206d1406b27047fe610ec01a86e8ba94516aa926b99879836dbb27a7056c4d54bbd19a44096d1b3f3e9956cac29e7ab95f175b9d9a0078da633f10a6fee899f400533f0f77102da19fb02610003674828758e23b5ec724c6829b95b8a6750f1988f431e7537ca9d05701ac8ae2034688082c5c20a122c6349db27ab958504fdb4c527b223b2420db7246a4a69b58085a3c1e6997db19fe17a2bc23bcd60b924cc393ebfca864da054ba38bb733b00fdf57ab147b922278fb132c5f5774bfe368dc2b66583790d30d282a248b7e9d43a562ba1892a985b75a7aff961762a05fb35b9420905bb8c4de00a3846e38ca7d71411e89f9e2c9489c597834c7a5315080130648f5347639184f315bff2d580ffd0227c9185adf9203ed50baa43a9174a7ae9b5655f2245a15c30f877bb7dcb2ec184138792738113895a980dca31baf6b5261e10a1d98ab660c066bcb05ac25429775c3bd1550d4a823fc96442cb2770751c812ce67613e48bfbe66a0fdba909317513220ebc3c55fa1364f318812199009af24f9f70c36f81b22b20be53208f0dc44dd3b6abb7236e1fd37c53fb1ee8c86810863a86b0029a58955dc73ec8a436112b5c3a75ceec356bbd91355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = pass +expected_ciphertext = 1af07cebe18b64049fd34156f0c1f2920934c333ba89237d4b942881e51f495d5cc4e1607d128519e51b8c59997b6a0c1402df0d3b032f6c3d0b4c34d48a5935ff61319530ec1e6ae306dc8b30e220031aa5549b00f4142201aec84beabf37c661c604bc26825e96075fb2ca24bb539187e1913849f7b9d0e6fabda2304d838021de30fb367172a9d0d0627398f966685df3de86f3d74f501eb56755844eb64f6b739820acebfa24ee515d7043e259353c7744dbce3886122abae686e4a4532a5863f6e898d4fda096266d25ddc674c28614e4d0ad2d38ce80b6855ac742b6f3cba2602056622565b486ade99294683b7de8cf7548b630ff5a6b0f6d52dbbfb9b5ddfae1d98eaf68a43a2b33cff3dd605aceed93f539b3da3a070d30efc2c1e9fbe027af86d87c3b8f84a2f30fb6359570ed3721eeee8efa351da77c69043c19c695e46a5f9535338142395c9e3660aee95765ed84646d6e60cb3343b60a61a4d3cf65975764d735f6aa57cbb07c06ffa651932e698969842dc1709ba7092192154bfc55c3d6362fa419e38b2001439b41a2d149e8ac22a5d9bb7700570b08dc2d3b91f764b43b70dfc2ebd534951701b6b985ad3b3420290b88b42e50b2e3edf857ff854f1693bf0977523e012bd6332381a1155b64e0bdba2dd7cd68d408602ed0912bb5b3f672f8ffa42eacc31da8601cf43fdf187a673b1309ff1bd7d8392bb76f71394a596bda178273192746c40d34eb4f80888ceae88291418b96f333cd1b15d7522b21ea6b57f12415509e932814505053320f84004637e479d1c6a944eee6896c75ec69367beb5cb7ecc5ce284120fbd24be653f61cea186f2f7b37a1f7d2bef08b8e1aa006118232bbf8217171ad0c0a71d0396cfdb42e64a1d0705439e131be2137af000c553d68e7830e3a3fefd5174bbbec523df366b228fca4c8fd4dcb2dbee571526549cac4dca391de5d82e0ed17962c52399aed8ec81c86717fc813139fa35dcf7a4a6c1b110883a86daf45840ef4bf7194122719b50e0980a7098fce047913348755fbc1f23de982560b3ecff6b82aca52f54dbd4f3bbf308ba1be699fab8207dc80ba11a923d7754769608a88c98835903054e66d810341f9809cfab29c53d16b3a804b9b51de50b07e7aeb9e7f378bd106a594c74af3d60e6d6b466d6f5eefe64f7b71a6cc2fb6b82a5c44b768e89dda891891ae853ca43da23068556a857fabd5f1689adae488c6bd4af811e9176b868deeaa2ad31caf71bd6f4ce8ba595c47c80ef6a24aa4d950c090ba805a99df998ef6a6305f176739ef2ae0bdfabb999a44aaa72fded16b7806d99248cd65394743da26358a661d6283c44ce9b8ed089eab79398513f8ebff93ed127709a43f050a7742100941def83b6d526fb499216d04d250e39fe6f80b4d36b303bb6898bc06362734370b3aba94c1a6244a5a8c7caa9d282082514629a0f864ebb91669acc757f9d7b8aa3059c9e44c7f1925ea18c3c80d85549686f74b7e8a8197efc89d42d2a15d195d +expected_shared_secret = 354d86b389021a3196b75c6582927b3a005fbfee0951f34d9cd5c8f415fa50f9 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = 8c5785417b65b2e4235cc67947d7b214627d326ac1adebccc3a64017e004499a8887c4a649e443e74720f0b1bedd52b1a8eb78b3ac2d5516b7a3233be9448575209675f4a813120422684191d6771ef2b44d92b2ca3bcdd5f5ac20a63efc237ff9d99bb4f5094afc187ebbad39b8b9ce75902190741640babf653886162645a84262a24b1885c626403f23136707816acf28950bf181742c98347022cd5941b7b69e21b5cfc2b4c6c5f301bd32a2e7882a1e1a9cd94743fc86af0cd26b51b3512003cbe8628d299663da40baef443677033da8b8c21e0a0f12fb93f4d63809375fc877866394a1a5409e2f13b3e5011a2a5877732415281b7b19991e6ee0a470561b6bcb46d87b4086f18ca29c5fdcd622f4315dcfb11db2c6cf136b7b0a870ae89669ad1011477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f499435118d9143723da05ba8f13e5cca1813f91ce01092917ba1d798ba3481121026713be1889b58375e5c4f9bb0bcc5fa808e2c00a36ca575c68b1d232778f71bf0927c5f2092d0629588826d02005db9bc0dce456e2b928ec9fb9c7a138e7b1065a2b660c287c3d062144cca71e5c1294442073ad48afc555767f1bebaf550d520659496af9237a22c27670a080f8a461778aa42c6ca9a954c28a658c73847a586fc3ef266562240acb6978e026152b1149b8d426aefe37bbd263a00da05df48375e53bacf9c4c11d4bbb055666ad008736b9c323a9974661215495e032aaec611af0e6a9244c2bfb6f3195d5121edc3c0719c3fc1365c2bfc70d5c6140e6a383714a0931ccdff946adcf73993aa113c90aef03374e251ace73770a350428ec32a9ddb4aed8832526968412863966228644b9af9842c2e967957f10d350a3499876f25d157bb2812501c8dc95365f83bc64b6340fa6cb4c2816b31824d028726de0112aa9ccc9e0b6869099d310aa6e5b79609487e7a20a56ba75c45986f92f5a4d1672f3d99927a1193ba15bf5df2586e823292593c49321bac9044e4844a7a6bcb08309e2520b6acf20e73ba5b05931e29ba43b2000a48c72a5df05ef715cd8865cf16a835a83c271402071d1068a426839ca424cb666545664ea5e7461af147b9d84583285ea1a05a02732031bb0ba40b14c828bb0e82807fc57882b31d9cf509be7b712f56994721b55da921eee8ad45c8b4e99931c9b71b473a89a2d4821213a1acfc453a41784d35b522e93c2d994d083674c71583782128476b04fec71f17ccc65b9c83f52c207b08adb10824a505b6da8a78d4c599a5b09979d9491e1383ea155576730614fcbdec1a8c801b94083a0fb55790b136bc5f37b752f3a6c636481debc5da8892ac1b04ac7447953015e7251838acbb6e24b508578b62d7450c46c76272806ac407112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b5b07b861be5a750bedb4a909605e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983be821e79682ffb18553b72cf0797b2d2117add5ac0abc71cf0e4ca83c26d218295aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6124d18b9a4606305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = pass +expected_ciphertext = 6e4a75139d037fe938768f42f9de93f12feeff1328beb5a9f23790e2eabec1f605207994eefc2cb37851f718bae8b94570cb06fb35ada46207fc9a0e25d535731cff7ba833963352ee9feb501bb3e1365e85ae3997630c5b387271ed60ba872afa7ee2b87867aaa14da0a174f83f7d488ec12b72107372c0a31677a6e933144ce571955be7a06a7b152b6693a5f07ca8f90a0062ff6c88bf45956e13df2e92017c6e246c4228ff0e86b50e0e6224000a44edceda07b3e8d6be399da183ebea434db5e9e5703dd199e340b02797bf62b29f442e378f9b0d99ab7c771d39102ac07341ed6d823a4fe6094622e3a12d74f4615e7b216d4c3da113bf62109b12fdd8046de27fadd35330879359b0ed0085da5578a1330c3755572958001f25524adfb9fa6220e24417a7d1bcaf63ea1044a3e9b02fd249a2c0e281b2f9e2e18b9f7552f4446192b7b65f881954cfeebfaa3075860d1c6c4e819e40873a992b6837257ac50a7fe7e3d759deb249fec5755da72e4c93d2c412e316e22694dba50831ff7c2bf0a294ff6329d0d2022b3aa6a9791de9fe6face1ce67ad828cc0c6293a7e5d6bc26f58e63e025c757576e849a11f122e6eec09ba7025951df26ccb414cdc914f47584d443f06310e86ee20c303ef9e30e269f7a67f8e67313cbbe0b06d318a172d0c47d6a7fbb1aed20fb6da5a28c53277d1d38800593d571b6dbdf2671ff6802d7c346232aaea7fb96134d8d16ae62b07804474cac1b3ecdcd5c26c112bcc9f72a003c4931cdbe1c89158505ab8267e3f5cb5869aee93956bc0334d09b719d898685f04a70a32ea8b0e56aa6b36405221ce539690e6e85f2227fc6cf40d203d55a2de22c902f1eb16339191576f3dbbbbed0c2ef90a5e7fd04011b33fe9a0eb2ec1a8fad089a410995974f5b2ee8d72e80a716b2c389322a279a2bf71c0a563da36779887c8943fb2cdb5dc6396d459acc88d04d09d1d1f0ad82c8e26c89f48c2dfe104483145dfcd2faef8807c4a160fc4fd025fd35f188b55907556dc55bed560970e3046c4b621038194bafc02da0503f3a9828da90b7dcc73add69908421d8169d32225d54111d122a456092b08e012a3c0d8994cc43fe993d7501fb7c7be94ec4b223dd13f50272afeef76c7ffcabdb509f9c1f9baf4b72f9908cb5ce3770a3040557797f666c8927dc08608709eb97942a64c31a1f71ebd7066031f415034f9d8e9c267b539a3274196919959d4f919ad4068b21b53fb18cdcec7391b9ab46f401672a22f2302af1a5104088d9f6628f894a7e04a78b4666f669eaf906e9ed3c8c9bd7ac220104967485cff8df46b064b982a2b552cd521b477e8b8e90b5f1ce11ca9ba16b045f4dc0f36a3b4ca8fe87b1fa6057b5334e993508192c6b46c79b196012dede5a06e4655b46c2540a64ee40830c7ed1c85507809810086d5be4ea8f1197cea21fc56113e45368c6f3d590fddaffd2848481a3424c813f3047dd8697a6316611889a74c0b5a4fa071de935d2d473ac2a0d4f62ac009 +expected_shared_secret = 3afcfdc446f93a8169024a24fc0383692843cfd6b4854a8e490892fc35aad4cb + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 605471feaa9e92b94016a9a05f585f3c52a993a91a6db73c9ae6364dd2a07b6c2afb449122e76a3b273d424b94343b3bd7e7b1e1366204820819c8ba8970218a22262ca649d8e3223167be77d9a466c860ad7c320b227e873a0d68faaa441c0907805996d64f7759bdeed65cce25b367f02094714be404ca9fe56f6ad99e7d38b5396281314898036493002cb516878db66ab19e09478872c0f76abbe0f754b443b13dd5afe610c1adfc52fb3c82488984dbcc4d9850a0ee4bbc07d0051208c87914a3fa5159c775ad91a552c2fa2ac573787ffa68f456012af600af60183f97cb3e2936ef683fd8e2b5742c6de946b96f825cd0f4807640a532561c70600d4995bf8d2ca543db1eacd68d28b207617c23cd9a57bbf75abcb620d941913e6506aa0123f89c261ce9c39c605646904d22586643f4ad250870afe94dc950913602cc1cdbb77bb9b4df518d1a18ab0c5a25948302c0535908e70f84587eff169114161c3e646740893faaf6b37b42168fdbc494549776d528bfa2c2baf6a00a7498f403347a646c9a58328c59274ae8cff8b82787a29d67336dadd3404fb5509640c29c9456fcf82d4abbcd9899ab108a1fef872617c5ca780970182861c046a594d62757d33247b79e12873493634c16fa70983c9b593814e69bb160120b4129370519327ac2332063992af4370d9871e7a27d13420a6fb16ed9b579d1ca1d36a2094eac96b537109ad83f4df1a1d2e184c309ab65d75a3e409c57578214ea4035657757ab92aa930a76d251a1b87bc6b58f9d900e38156d73a1961c43be2e044314c89ea9601937c0a87d9c4b14cb9e79d83e722cc40b048bec5ccd038304ac0a65bf93b9a787105eb31b5be8845c5c57b9a9caf6243f54438ed84159f5b1b8b246073b1715b0f635e8078991118dfee2ce08887f9680bd4e672d3aa78df8954554d398d1675d785b85dd28a1675944d7597968f22855999f148cceabfabc2358c315076c6b4333a82520a8332543aa100034bb0a6776cd959bcb263074fc28956726d0d99b9d81a7dec14f13ac5ceb5b9eaaecb28e282bb517cac09809073c3d085718d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0eef3233cf91c0bf5a6a9279f6ad136808a9a3515b02e303f4da26f93264c5ab9010a9c8550b9076d6471c196675edb08223672c1a229ad31c05ebc4fab557f46b4bb37dc2b605a87b888a1f475516db87b92451127436eda7922bb45b8b8462122542de969c31622cdd62676a8faac5663a8bc2191711383ef4c1cd7a183bb55cc3c83b566e5514f233d79a2963710c5e5225f7b09b0b6176f451a7f77570b1c17b7ba335511bc3c3feb884e459add3a594dd35662419272499b4e9258dc9aca946ca80911999d455d06407cf9c69e814478a9f5151780bd754a440bc69925155fff0a675e0c322c69174c27cd804279ebd3260feb62c0e24eb63c7a042996c25bc9342c589c340e99999f9c5054ff35c760a43974096c5fd23bb9e51e2483722a132b0277bb24010297c4ba2c58bb286c49ed20b7aae98c5d9b0601f06ee53c1808e07fda53114efc6d36b28b906611be3a29e68a8da76457be5419d70059f7c329aad28692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = pass +expected_ciphertext = 0739932f7b5b6ed0d363a0fc2a4829b0e1fb8c071b315c536b97eb6ee3c7e6b4022a5f6bc0770e3c48b8c0711029b6cb454b1e80e807ca35b55c06abb75fe24dcb4327ea8b1a7faa63d3de0f13c0a9be2c9bf101a293a078cb33489ee8b6ff1c21f5c4a42e9e9b16d4b860b0a624e00b5151b7f6c4db7893e485715b09e2964dc97740cba20650522f21644776c28b22a26ebd5e09cdcf07ec0415d3d464bdf785035b98aa1fdad58bcf06f87509b3690b327d9acb8b034a34f5b1061f58872f214b57d6e5451ab568c3e8a700fd8c95c82ed28427c7fc569fd3dc334ff8d9faef54b972da4ad8014cc22db0f1aa82663f3a8f205dc5ff8d1ebe30cbc1a590542bf5872ff6b0390345aa14eb43e06f52b35888915a0d8d64cabddc8194ea6a6bc96fa805113a0486643b79721735c0ff55d28501254faa73caad71600ff139a1a5d0d7930dc5d202512ed49e16f6fbe95913898688f3928dced939f2230aaccd2ace43276e0820c56bb7cfe0a1ed5d4aa4d044d2c6e6e895d408fdfadc689ec2b5f4cb24a89dd87cad740477ec812b2f8c9ebbd77aa73900c9a412c8ec72c39ffe3ec82cd65e036056acd5d37c4f45f25c65fdb035e1afce1e6743e985b8de817bf5d43778a0fc0edb3cf6825bcdfbb42c7cbb3a8c7fa02068ff0e1a1a3bd0eb3fca906a100fb92463c7c221e776d0bb43a13037d9a07b96e0f2c421ced63ff9f5442711a7d876ea5442c1d77639c7eb90d7dfea7a635f887ecaefce74aadc6d3cf722f75172835a24dea2664c09a70ed2ceab70a314f061187297428ca7d65d07e0bc8d161c5cb43b0fe2e3cb9cd74c9b2f3237bbd318c18d8058719ee0e65a3f1cabcfda9e10b8c685bece284a62d514c2e663b263220c29cf3a207066bcc53df0f734ca27f2360e5d67144104f8c13f5d12354d61ab96b939cbde93eec145c7332511127944a26ce2ffebdb03504982d25c86fb81bccb6441edf24d3975df84a0950ab9d28866c796aed23c91d12ebbc0a90774d60fa213cb5459b5e55f8d8a6d7aaa94973d88988832eca7cfccbfb9aaa7c44b08a391c6905fa75cfc6d7f1796168c33f8c4f4b04d89d8dba51c840bd0e08b2d660dce30b9880cb86841ca8ea05c3e6b1444a61c318578cef85c9cbe2146affec98afb815380298dcb39ee3913c63a3dca559ce4d5dcfd17152f68c8db381679ffdda0859b6d09866f296b9bb3c6953a4f3c9de9a6901fb46c5548cc150ed9eb30468e8473e308c9d80ec708f031dbf7860762a020702dc6b92c155f2b7f2af9147ba4012fb23290085fcd6a7590a4ee2542f8bbeb2d55bc81d49bbb439018bade94f8282c4f9bfee804f4b53782cd4e912e76f34839728dbaba746dcbcb94194496dabbc1c0a658888137cfdc6b42f6b8f9c6a83383ebab751e29fb29e97b5546e941e895f4316432cee99460bb680ea561000f268602ee0ae9ad74102f7cc0c212afc97f1532428ed658a59d8b80ec5f649726273ca6a5871d8db2184c52e25dce3ae7e2b20ea7c2532d +expected_shared_secret = ebba9a8bae936c829c1445c68595da96919041ee3d9b0fe27ca93db691146874 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = 5b668ae6721c79e07ee5d26233936d195b62b192058cfbcb0a5a73ea0154d78224ebe84b7b611ced7256d0726492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9a725c5278c21d896ca5d706e5f03d71526cb175ade2606e3c3a24d510b4d9816aa6846a77663a80f5ac0d364747307068da942b15cd2e02a3eed2818f9056d697897b509bd5048b178240c841580bbb77a79423996072f39497869007b19442f401009ba1a039c18f191cca42f9551713cd791c9fb847690cf6247bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32da070fe29411f17a420521fc69c0d09a6425a20affc98681568b8ccea88e54b8dd9f12aef4b3c10f256eb1519671091984a1dbe972a901bb4b24246d7db01b86665374bb6cb841b3cdb2593ba5c96e32c20936ecbc4abfd24af76158b36a2c752a9bba8946b34c414eedb355a3ccb87431221aa2e936b0bd7540e697142da0817b1b51314fc71cf4017f50544474c572c70bd142c676b69afba4292f5f19e88163f2ffba3b1685073c3bbcac825b095b5d259228a459fa7e866e09735e4cab8fa733d4db6a98172846397883394059c635d23c09fbee3cab350b9976c6a8a900c8e1693c3704e779049cd1221ce767651bc23755a3a49c6be0c314a8c501579f7a447070effe0314fa3687ab92090738434e55280a42f22a66eab77a2932b07e6857a32e31a527a2a909865e053a32148b59cbac224c12468e444916ca375dc204c600899f90ba7c854b3646f2af3981797afc4e261c7a93aabc40a93990dabc82564336d01b2447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad66161890325533818f845301d9311bc8035714a722ed9206967123e65410562a745fe28f90d50d772a9cded6354132688ddb1ae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbae00a91040456f4023174c73dd8a4d50f9714ad1cff718321677a6962587ba6ca82c341f02a7382be9715b41994db91e6d0b487207b9b660793e62470b806a7444b6faab38f48747484062ff443ae1da9e7ef41f797398f0527406787e00e197ac3248ee4a0e5037cf6c754ab9a24d08936e9d3313b99ac18886cfa9972030f1a40e58b25939a21698c434391785a3a98f0445567a9dbc0b4284d49652bb1862bb76fcfc6abe60831cac9aef6469464319411a30f7601b5358568b014e67a76ea42acacd7c3fc2f983bce1bc0667897b92590dc724b5284fecf7c36b3842c61c27af1a2f2ec95899591e707272bea384cb9c8c9409bb26d743faf196d3b8b33119a379d5cbf6823d4176ca83ba4e2a426745f346a42861a7b5343ad3ac26ea8895f24a379c449156123ed91a4ca701bd789da84ba0ed5c707d373634ab7a65680667191f806b6f62cacb4b40afdd649cc9d1650c3a5e40c8346c91b27ec1b1a957c778ec9c968c670fc84645fc07881c54946b5ab0b6033f45afcc6a61fbb99746f3991f5b827c22972939c5ff620bdc4b131eb393d108c56556719abbb978452ff0a12a1d138c9065c304c8514658193232c832b05b0b21a10483c6faab378c6b1415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = pass +expected_ciphertext = fd2b69a027c2fc20dcfad7a6765f0946a637a63374b349868b77d6b6d84a3e32392775e1cbc0d9f986843f3f19966f7a2ea83e4ba64b46efbab4c88649ff6e0532f5ebee8a218b9444bd815a44e2be4bee845a961815fc122598306b1d60c402ebb170402220d97bae5e04cce58470800966acc024c00c5e20aa3f1d4bdb672f1d4731cfdad84388c2e918191dd95d2b70ff1a5228dd38e7f2d936fc7e571d3d288f3c6b3f71c1219669c478a10fa46460340ef9c1ae9a4981c83df9a13d5b5ea04cf9b44d08688bf66e59670b9f13f1096f921604c68a44ca5fa79e12ea7bdf671fe1deda8488ede59ccedcdf265cdd168c3d8e9981f10fe225ab88f714d0c31bb53eac599fdfcdbd24e533327cd6efd32a39b24474da685eaabfa3f50cd290d8d681f684481036a19e741ecf16e4b59059522925ecac163083cc087f4b6d78f0452b429eae2518e7623333bc84bbe39bc85866e41367278b995af06e382d165c6957ce03f303965c94b9d857151840b1ad140923950c931b501a7f97c6ae2cada15a16ee5a7636a6f412d19358bf807130f8bcd614d29d8eea8016b04b8a9e2343c951926417fbf749f7f7bee048daa22d966f98975daf5481f3360a0ad80f501f2e4e5d0f840f48adf8f066541997b67504ad8aa89cfc3c12635b8fd25f5f2611c8b8bf0e88398846c9edf3ea57a49978d1fc704692c29165e6b0f4e8db8d298776e95f36dd21504d42f4ec2342a7354a47f4ed0536e6cb206e88e070a2d8a2c5ebe8e1327b1041eb34fe570b9af85f7945f9e2486966b5abc9edda49cb4d8603328f4a4dd77db3dc569894cb21b6db52665f86729c8def02e53f7051f406bc215827d9c82fb5f106a777f369c39c447cbaf4ed2efd105f93a46e5cfd346ef86af228b39f48c27625385f01f78a1a9622e58fc72a8ab21ccd362c7c27af6cd1844cba5cf0953f5aef4f7ce44e681926c691bbda9d1de170f78669546aac55260cadcb5ae44eee3459e3ebbeb14e053fb4daf6c1d43fd679a120e7da136d931238bb9df93cf2ea88b1112e46007c27164e36b1f8a0827d42a2950f5b58bd3eb1d643034d6c04970e00b686489fb493b8a68a87670d02e85b5097987cddb5f59286322ff9308b6de9a1c5766ea6ed47dfcbe40e42c4bc3a82d5ae872a82951d41bf062063f6f8f87ec5356055d94610ff915f930430330981af065b131bb5352e3172d59a09a4dcc84299ee5fa611f31bb61a011df04d4994c713a8774a6ac21b620c5cbeb7bfbe7e26f2478db2c105e02a194b237c8cef57867592aa3a1d0cad24c30d53be0ffc0fb50fc83e981490409b20e911e9ad3b1de67e51a4bee820dc5e136b26f9efdf38282889283f33f4d8ebdeda6c0183bbb27351f7869c3c59b05da65a152b6668226cd5bea860cb1b06de463fdaecc1853889bd2fcb98e5fe337a727524b7bcf3faa23aeb6de10223cfe128769025375e94f638c55d838bb1ff301db74f03285624064cb20142d9cafd33631038b0d0593a4fb141a48b9399 +expected_shared_secret = f063c0908deb2e61faa0c4c0f5051b2c8af7265060681df14bacb30f0228b3b3 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = 98cca518437873f144e7e261e8465b3720582cf7706d684f84e618e8834f35857d4a8bbc303134b5e235dd1b2387a81c663876c5530293f99571b97ae5a299df0c012e9662947089c9f81687722fbdc30ce50689690b30932a8a3ce7bcf6a353bf988dd310a2c347bfe6b30999e69c455b9f472b9bca0216c84265e5d9486f6a7f1f3125c16467ae41b9f85180497b255adb06a406a13a221388e14c0de8cf73b6a952c2b2501644831c3700b7c273b7a3180a7641621f33b41c0f9255efec1025fc46f658c64fc89352c54c264b97e5a91c2386cd3790605127740da2076eab4876e128f3746843205b8328cfcdc65feb92c2d973bbbfc68fd7a46db51641b7830e73589f41d413fb571c37685dff142863078acf00043395bfab3589b0cb435981b84e54318ab46e398389b8e146cab2a9666330ec4c90a652a0f036951519880a45bf5d000d4e40c6b6554cd222880d0b91b67153c43909eb2c0926354d436c2318c593f9fc214b548e17245c0c9b83174a6783508b97ac6a8d8a88ecd278e2e52c3c9138b1685dabba2bb1425075b298cb9120e790afdcb9792c88698cc156ca5a789474992f470b1d554514823e87bcae52ccc872c951b0c24b4a2b0460f488ee7768d56b07dc79b3b4cc321e5878ac0a5c3146aaeb6ca123206b0c7b5aa6e0bec5d0a903ac9415da345af199cab86ba99234c9526e6e8812f6da8001f31337b8498a8374ae527b6032a0cf3142d1d34181a5afd6aa432a588ae1f644f5a100fa593f0ed2753f441ae5677484738ff694abcec58781b06d0213579f827fb4f97b3fc343a445ba3035aee989685e7b20be6103fd39afabc334417379bd666181925ed369680b851a54c41b6546b9c04ca69742b2a814763674abc9cbcb03e96f9466cbeaec698cb5c9acf814e90887f8d15bee556b28f50b739185eb7a5a06e896ed0048bbd905e016436477a68ebbab1e172928ac8fa9a8b0a0d999b135a753a29a47d0136865b0f382572b0697d0fccadc8a77c1b591bd73b639e13f9c21b6f0969b0aba3ea807303377afe0f49421b68d0712823fc448fa9a468fa000d5964bcf9a9e7fc92dece03bf6732a36935b25023b47fc94c15795dd983bb4531e935a19778305d0e8a75c2cc770eb46b6d5759df503bac33f0669c775729c59eb94d48223d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb0b1ae805b1498471ac1149d578b454041aaa2f5cf13390f10a72df3385c6a8a1f990bb946f4c888e585069b5849882788a1be27da0725276ff9db130519050b74cff69a68534222499cc61f5845a8fc0ac5629e0cda20d3ea2f0046b78a2267fa0187f15721ec53083018772097892be85c1be99480247e6e30aac8fa2c593c630b981e57515e0f7414cfa8b606d931280a950e567c93b319fd23ca1b682fc0b960dd309f80455cabbbc71979c59a025008462c0681465d748ff2a6ae24e86c79922e2845568ceb5063fcb81b78295b93a80b221ae7e14a9a9bb7182c1acf347f2fa73784835f3375a29ed05e4bd120a119cd0fda29f76a1eb873aa88d0cb3c661ff0d5652f2b4604e2bdb1497486687f17b8ce7a096a59e0922260ae99bb7412e306cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = pass +expected_ciphertext = 39c2464c42bbb75ccc9421eca048aa426c45eec971a442ce8790e14ca23260c9346c2681e7985e4e27e7ccf84f8a03b25b0604b9a64d943c2340d4818e28d774a3b4e04b6840a2cb81e542dc7e4fbd2146db158edc7250fc8ae2bebb24bf2b74c2cff7a9c5902a8963d576185576c4c6c4ced7c6f0878b67aee7ea494c34221d8907059bb989a65ac921c511c3b1f23c649811220f1cd528251a208641774228d513e80eb2ee079e9de73eb9774c2b51445235a262f166ada853256c6b53ec6ac3258059e4bc6fc23c6f0d9fadcbdd15d7f7f3a6a96743815ccb65117c06b2aa9bd134746b20337075f1eb45327942e22816cca244236514db48a46f353d5c0b0f9029ce274820fcf479c1600237028558b9acf943e8986c9f5d21af0bb5b294a421ad1a8a803ad0cd38b085dfdfe8f8f19206c027394d94b2fdf6d752b1eab11cd2ee871870d5f9a444077cd5f563faa1b1574b630704c01be830d9fa56eed3ceb9dfa8f384137ad76a461d17bb062b3b6a0325f787702c26e77cd649f3184a10ef5625402e7c7e1894071f8772331a714a4facbe583a1e1810e75c141440e1f6a903b6077783a2e2fabdb61c3b9a5deb1e7bf2c3852160aa8a366578e873d6d4a9f9b54f6a15f0fa3ca20146b608cb63a449656916b393a0633366b527b7e652eb2315e2921711125f9b2f0aaccd30474bdc2880bdd83ee40f94acabdba84810a02733fbcc1770ec56fdc8cac2accf15d6e739850b48616b7d56beacd5c0c30ee09530367675771567db0b05fe97f0e4f6244c020dcd1fe8b95560c8901cf350c9824b0ed5a4bf06ea63110d97ffeae97b0ed0fb5be0c91856cc0cbc4ee16d78d1fa3f2539570623bf53058e9b6087e252e86e0896c78e5bebb4dfe870d5d3a2d041f45346b559e81e24ff09904230d40125c17836aa20027ebf9fd40f045f9485582c124e01fcd22d05118ec6986788805cf0522e9b9d162e3b1003d7bc913d27c26a9171264f49db8463b5f69936d7abef9f28437b6caef081e1bebd7c9a39a43dc0a00ff49731b15e7f1467cc389b03a020fd94b90f5a491572d167ef6cffd5aa45b3b611fe7b9691721f4d9dd76f9d9ba3d068d8d9578f1e238742342a791e4b59f8271e09575a53f77ea871090907710c40973a8b07945109c1fbefab60add3e8ae3b783ad222db7f584b7bd60671afcca5713c0cfa96048bc3c52d62d73fb5182a70b499d54cb6286817cf85c63189590189eee2c81e05cbfdcf23dabaf7c7269a18b801597aefec507d0772f30e21c1bf49226ca74a8e0bfc334f7de59632b564a54aece295cf745784332e873ae704022af6732657c81d7037f9424920c1bf238921d6b596cc247daa20d763f61ecd3fe0cea7d79e7a6094f35606f19976e1e37ac8f81fe5c63e51129cd8a8ce602ac56d9315cc5d6c68398f01bed2e9fc79121db26e319257c40212220bab87a274b97784f932649517f462b05a423a0fdf88582dffa35f330a0c345755cda858b815b6792cb28b5e45c500f86c +expected_shared_secret = 02d2e466e170bf45d3e9d357e2f04c34cda408cf147e9ff7a6e8c715f2c88ace + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 5e451e4c8c85a192c91df27c17c0684baa6375b17586f8bf1ef12b91615bd08a340c58629cd45f7a392f10a04916c249af956b180bc418b8a95f66b2d0847e79d247b430812d682b1fb91879faab68f25602579bf0d895073780007b7d61940239913eb217cb16a63ea08b29656712a21a32c754953335c29e769df17125d84c32b3250ec96067b975bf524091ee4013a8b67a19a331daf38a396a765f7820a5e3606a734f5ba854d1e6b6e70cb9ee5b00d4d18d928921ebb8048e284a3a05a3df9469ec53195180ac9f869a8e8866d69019e9730fd6e672db024b6ecb4dc55729024033703b6fdb7bbeeecb2345782815843b7b7664627cad52038f98db605fd23d24080f809a276419c876aac69977998b1400395829656c97be262e053197ead738d9bc995145cb2713b5e181223e04497c8114ec5a05384aa31cb84406f93365d7059dd88db8f94a8f068fcd10be96e32a0e926dca518b3fe9286a755f29d83cf667407758141b2011fbb1764d3334f3a763a17cce33c2816ac79ec4cc4c2d842b004c352aba419be87281779300708bb20143a43413a2a55c41e36444046a3c021a4d7818dd146d1dc335c66152866597aa69a44f39a2814a4830e002672731d93b7fe5f77587b782aa279cc9807d6126392f812e83662d49db231dd3060f882d71d2a0a4c94adb3784ba1785187423d7e8a82f379eecba7e6f6a67b568698ac3a2c0b096b015100bf9acfee522a0192e49880439cc1fa9b30fb7a10544e1867b0c34da981ce6e660cebb8853545994454815178c60b04dca7073531aa2a5095f7b8578cd9889f3428a7d1c72b8fb320f304fe5d23a4291666bf7aa1afb5086532fc5aa347dc29279a4484261614f2774c81374aa453024b68d384b01565a36d98b751297477a61780e98135375af8ef68359332826da01ba6a73d5263abc659454f57d83172d0e515d3754270ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cc407bf027df7e2a505db531d47344552321107b651fa4e47d4b389c5825e02ca1f42839ada4d7eea2ccb24a74e34672bf1bc4f33c88c3603a3fa6ce87aa5cfe30125f99e81550c19b58a807ba8a586415c2924a6e467ca8bc85a5400f910457e8b9d74a11e2668c0f1a2a1d0389361d09900ec6671206139380ebf9390b2401555ba0a57fca36d2742f569a573096a2b442c5992c3fb65271479291f097cb94589fa15bf73cb9319d93860eacf1cd1bf7d380e03587ce3faaeb6360d79574803b5c49841b74918768efb518ca46b26929f68639eb8fa9f73e61a8b69b004cb5d9d92cf0dac9abc03171444a03409714dc1514931182701c19e242ae73b465af335c8d3588ff468346abf76604b6ef887a7eb8e8b44005bb55af328155af7928c732e7805010cf0a50ec68e29acccebc4a39e2aca10084e2543746be6c81d482f6f3c1fe0d31c6a69329d783a1bfa0b43e289a2f843c71196809ca4b82c75c59c7aa5d311350aa55e89735d9c34e6982d17c033937253d9778ca31a14a9894c5d801415056552c410484970cf2ac86b374644a37976ec4a123c0603ccc01c6c6e994514f13885bceb2f8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = pass +expected_ciphertext = e7beaaf8f14f63e4b07afed36ce1aae517129415537b323347ab73d9154cebfbdf51a20e75b6625635ac552fc88f30866afc1eb1347e7963d1d634b9943db25d14e21030580d7bca1422dae24b0be423349735509ea2b756043498c41a893055f9c7b51a5783aed508a6888416b4f544019a6c0e3766024d804d8c067660161cc17196c98fc0a602b89be5b089e669efe0ad5086971c6b23883567df50c0bdf5508dfc8f62888238b34a0aa1736322838d00be507cd0476739a0903ba622f42f13478b7a127b43799324b990aee9e8bb603c3de3d679e34ef6f22a8d309bb882e61c04dbefa54004eecf710d80bb09d091ec716ad0f4392396ca1c06016fa1acc111308eef78eaf6f4ff1b87743fb7629da989c79f58b69619aa6e3333de32e8ab0df5001b12cf27318d45ba24343a6a1ba4745b3b702ca2799b4428af6360c526b67a2532ac2dc488bf386e7f83fe5dd4049f03293af0459f4879d71483f07dfab14fb1cfeaa7474b45d8a3acc91478723a87a2a16ba6fb69865abdff0e7e18606fc60613ed6f1968bd36b122f345682c2bfde19d0d0cbdbbb051651708d839593dbbe010194280394947ef157a0ee77158398b0d98f7a1f78a528175fde7891e40d7c2055dcb908862434c3875b06922cc3332f3b4acda02402b35514445c90cfaec583aac99100712b3fabbf6317cb7ab57bcfd7057e53580c978ae42be13581f547273dbd53f1c168d0acef9a38b29bc0c35fbb4c534634de64271fab4d9ec326cae654c4b6d8a8b2402e970dfc76a7d31a9649dba063ea5377741216adf8fb01d7aeafb80e8a4ccb9bc9fa2b62118b216815a6fd7c2af7c9b55e666cda56e03ee8ba78886d8b1a19ca0f844d5e2ce6f8ab530baed6057782af9b133a8a01a930c1b900ae48017283fc91f86e81ea77bb6e17c8a00d0212d2c9dc8ab39c90f7bac717c73fc6c05af9a1436241c8c8db904bd2c1d8d2b6df8e83d46220982c0debcedc62c83d547df31374fa85fcb59a4819ff45b8aafd06aac7845137c0dbe64f530c37ab877729222541303a13211c0a9b315111f836fae49fe0c2896a92f6da3786887a42b0c339e0312f6c2849f43a931b5041fe10e277465ea9f6839aee65ca2144668151172a781dc59d7a559f73249f6f0399a80049b15aac6de8b46f64100f31b41c4f0a2d99268b27512d61f69297761bbbc9c61fab51a02c83e13f6b104d89e9efc1f77c7926585cc84a19f3d17c2dbf16f8304fa942002d781be0a3e0aa3347731fd19571700f81cbfa0d7d30208611345023193885bcde430f7868f3f64fb941e8b22192f9974dc8bcf523a3f7c4f9fa73dbbbee9a5c32a1fd7f9e172f5f1d7c0379aa0987fb374018535d5e3c288e855ff53472b5232bec315437513d4905fe3851cb8b5c089da4fd4cc667321e1693a44e598d42ab61880426ff3c27d134db34a7f5f236510cc3474899657de4432ea4b878667ba9140d0257c3616d140cb9b501b0afafe5f2f91ca5b85a528fd920e2c9a53fde5310ca5 +expected_shared_secret = 6a5b0842c122ab6ee251399492b061d2ab3e40843f4dc01c12fbd5bd545c600c + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = a20c8da5745f754b89a990746ef771cf07a6d8109998936b282757f344a1b00b851eaac27a9a7fbf480d44262868542128461598b5597b10cd3a2a26e3f941a9a4719ab2033fa1181ed08e3247bdd396a834e43f5700522cb307ff4b150bba9d8b6aab47361a7947b7a04b8d923202ab1a3d6644be06bc6c1e0735d5d92821c5b8e9b9a83c343d0c456b181b6fa566b0e83602428b6cd33405a95abb623a73299c5b4550a7d6c31d6ef81473489bbe457e744b5d1e39ab74d8a051951abd01a6cff3942a102a33080327437635c1c17966834340c26654a3f38616e5eacb0e489141b14e9d1b15b7fb30927715273547999b93ea2a1ca2189f5645cc4889943f3ccd95496b71f392f78a82aa1a21d66382c37154323c0616804f50125d6b0698e5dca3e2d5658ce153bbf57e4b1908c92587b8c863ff4872e9e1963ae6c971c6ac3932bc974b9f15e5743ec069ed203c3624a022f9a7420ba951425a432b46c5e8bb666091d6f223e357ce96c55bf067b3c3f51abe70abd85a73a42233800853031313ae9971d280b3aed18489e75cdc16cbb3ebc95a8c97a768aaa6c0bb0da7943037bf2b4a523e33abf669c262941f326b11ec6bc8ef51b0666268d6d433b5190bb6996f65925a7eb0761eab6906178be9a923d1c61c0b7683cea681648c44608217d6dc86441a8f423a9d1c288b32ebcd049c15ec151e256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7bd4145e837b756003bab223ff1a74feacc2e449b5dd9b5777d62ff0e20e4b395821474ab428aa2ea219bfa169b95039616598dae0b9282c69ce329b534bc7aea58e17467b1348b1ab2a031324bf835c985371b0f53877dca53570199b23bc4d70a9425a32b54749082e794e10012e9b458205e106da807c03ac3202a4350050815487626bd018706c69a6ab02fcb92621114a16cacfbea02aec424f82fb874800c61cc23bc6618ed75674a70a6c43c4068e2a7c9723a054967e4dab09f337695bbb01053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd7661dfb0b8eecdc2a4134103380988758379d0a73b0f348b00b4b13b115e74674aaac2ba8c2a7ff440340b622b5c0bce05cb601259913c488fee540d7c058a28a0c28b856ea800d26a6a26f8bcde7d78298314cea6056b00a845321a245949a8c7c98d9f8821f1264c658a8061a3014249b7e522d586a54ad7a12ad805544247d74058bc9ac0f603a44ac5199bffb69c1570c4076b345064ec00c5ae0d6a2308947593a84ddb6133ba40577b7b245c20b5d04c5d08281ca0aa10da2a358386d2a4c048c89a2402c9150a7419c0a1aa17562fe786f00486dc82a9809dab08f7b16d9432981087b6741269424598eaa99082525d5db0deaf1b96f55b41ee209f57aceb895babc38828b712724204744834303c496b7171fc458534f46892627ae54800fe6f11d06b6af2b6b9259144f769b1f16c0586c9caf01f8491251907fd213aa6c0bce5b08f060124fb99822d964c502ac49c16ce9fb17eb0c91af559947c056af77ca687c4f675c89be35aae91584cf82202734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = pass +expected_ciphertext = a2e6548fa8b141a9e4657c41ef47720a20e1c548a4258cde5bab41b42b58d69e30b6f887f84c676f295266398aeec9b24a7650d710e0211ae2c76b9bdc0c6bf40e057aca0adaba8ad028c66df5ee016268a50ec7a4d5300e8fc128e6a0aa5f781a4108831554b2086f27938a26b62a3f26fa4c9315da5d43e5699e7dbf424f81f6069e3f9512952ba6958108038471aeb5f8317c3767723d1df5f982d6d7a653a561da3f0f0c4f1d8268770230ecb039a3e269ad58cf4e62732eb0a93cbca5611530371675faec5d5a22a86285b2edacb9b79ab07945f7a7d1e759234957a6bfcb47f13853a2d2062543bdee3b833b0925d9410b0fa83f9849cfe70783041a5716842d8d19d26c0e04c9c63fae13ea49197f2150c5b2e59273af8e4c45603e0f3d655e7e1d442e9e6ed3aee5fe0434104a006a3d5aee9f0af9593a9f9b8e7ed1b6b5f4c3be440d970d1b447c0343ea4982ecfc262a35c1567dddbc61439447f2b72fab241632b448e553c05d7e7ace39338a0df928c4a1a47d9230cc89f4f9a596cf5e08d5a724b85ba10132445bd8e5a91b9547bf602036ab50e31d069ba9f542ed462fcbab1915829ddfc05ce4801758d1792271bd4c68a475dac3453aab9ff0271600e80e68dec303b25384bb61febf82822b46efdbdae5a789040f0bd08714dc06fa8fb051f5a74d9a54be204a51e0fa41bc6cf8771dd70ab54e328381b581a809326331bb37783620dc2f7e9f528b7d59d587d3cef8a952f7f96a2bdfe89d33ae7714f3c53aed207c4cef6495ffd94be2673abbf7f3d3a81279b9342ba3093da3f9d280d381211955bfd5f84fab0ee430e63e4d485182e4152bcc715d1bf917987ec85888972645515ac8b2cf0d47c736aa652221c379b4c622bc1c9696faf0895d42d805b971e340291c952b931fcd85e7e56c43a120102252ad42a258791518677f37c5c6c5be67beab159d136304752daf06b210389ec4c07604bd72da410934fd08f053c91be2bdc410fd0b5e5886e0bcbae2033d8a6bfa579e24f2bff7e96e70b880331a4a7211435fdf9f78dbb758b1bc977fa22d3e09611510f84adfac85b151064796623278a0e791c1c38a6854fb344ffd786a8f9cdee2f9be606bd4bb55f57892046fd0d096e1bd577fc71b74c00bfd1c7c683f77f50b57eb93a93fc5a03acf43002dc35025d3731fc2dcadf031a2a0473e2f7530eb5246fc53f32ffbbf94494555d077fe6b01eeae398964c7a7412d5cfe03b758105bcee79d07524efb52065d94f3ebcc34357bfebb2cfacb51481f5368f33b4db2d1a032ed9283dc876c813f2787e14b55de96b6792e73697db908388499ff13a7d14f5a343b8fb37278ec1836cfccf592d47d7d4942332a6a2453af2d82df45fc0ddfc7b83de2c82b28cf7df01ec9171040c434b92f3adfe59dd5243cc80e76bbb95747a2672ea343395c79bd7154c8d6747f3a8cfc93abb97ea2191b0feb819d9649cbb4df6fd9c1835695e944e7815ca7ee52952bfef13a9027598dd893749909d49f +expected_shared_secret = 2486c0a6cf17d9635dbca1f8395784cde54dccb7df10fced92183f983478fac1 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = db55c6cec7b63c0721aad84d2b6551fa941167c78a0c105ed9e5300a24bb2c8b2265251a38ec2b9d05a0635b2849a81a2a7c6f2660504d5602fd2763046820ca168d70b76e35b9641ce46a44f2a394f496dc32353c1a84302381e8d74ce4294a4a260a5b0704797567ae831d7c4410593cb7b9ab74d2042c84805c3aea6ebd193a927c8189082333b3a5e96857e3970be7daca4c884d7bb0b3b9c250cb4135d0b8c90ae320dcb3c423e8a6de79ad594240ae7aa036e320ad8807ccb7a1bc80c704c9532960864a9528347636b4123337db7e2de37823c6ae084418fdd05ff7e904211924fe5a370537762dfa012a2153af96a46987776d245fdcb9434d66aa10524a3ca74e494c9de919c8e23c3ff77c58cbd1cbaf5b8a69803a32e23959b2a7d9f808689906a0985aeff5a8464a2af64ba053a3c18d89b2cae3814cd712484288abf7655063c403f635d7a2afb9d804e2e89677131bbbf7009c981548036726d25f05f004d605a24b7c2bccc4294f065c013c8ecb242d25611b5c82bcabeb9e578758f2f3ad3f087bb6813db1f3990c867a2e679f47f074fd012e87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c870364192c555b81af58962ae771df477ff421a9b46c6e64bacd1a8a6d00da4d9507212c910ed2c62d199c7e330a11982c514f27aac092a5216b13ad54beebaa4049065a68d8ce9b1c969ea01599a71d633197bc33c2f6f958f72ccf14c7c09d973770f170f1f7bb9e458a00936d8677717f4a17655bc7a7ec56119779f7aa391d2356ae3a97d7ca04971cc2515154e148568c176a659a8decbb2c5c449ccd914d3cb7431cb3a0a400a8c7b59b1cc770c5bb5b64e0932c61783c9979d6cbac042216a0cc5800ea160c8c8556e0721d610fce13992396c382e93bad1514d780cee046525c443fae063c5882a01e5a73658a30864b1d6344a6cc46729bab7810c46f5b480d309a263e30461769a55a2965ba6ba0b44054f211b98c6c2355150acab81881e5ac1e561a4bc4b39f9902d1027e56155f5d71b7ca67415185319ba769f88345611ca2c20b233dcaca9ddba42edb204576bd028a79bfca57c9dbb0a54b933c970de35032b9b51d00c9922abb5106897cb896065fca846aa486d9c27f5b616e99ea0ada711729b75d86669645b9a223959b3c1c2f3ab6536d74295473c4c055aef8c2cd2d321e9e73cbb872698b3a60667bc768014332083139d08c321157cff1481f259ed56a7a3ff1717bb64fc951297c709a4ae3c05fe3910d6507ac947f944b970070570fdc9843a8a5ba564141f80f1654766f93048be6297a1cb76c105a7ba3ada06a42ed1ab3c17542201712f11824766c07bf14685ab0a9f69a15ad6574e59709d2411b37b509de3b7fe5e8b0ac65922df23e680c33141418f9551660467accc0c794a67cc530a5b130b4cf1c28747601d26983764acbddd30e42eb96125956a5870142574419977209a12e09ab3c5e8a22c1c5252527c90987a816b8830a757ec44b12e2e2bcbf19097d02b19ae47cc7bc99189370a1aacef36415ded82fa7a63be809b515f79f06612dabca5768201c59e2c92eba6d13b72c31648ee1d504ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = pass +expected_ciphertext = 459624a950aff4a380db1ec8f9216591e74b0bfb9448aaae1aaea886c781c414fcc95ddae21c478a1f1692ae703b8b80008661919cb910ca02b76b9538fc9dabc00140c0d790a88245d3a3e70823da64629066e039361442e60d25defc22c16e33f910c3ebec5d045bc9dd1a763fd42a9ca61037cbbccd76c64a494c0e2b58cc2a4e8c1210001cf0da6a2595c30b36b3cbde8d08dc0de26377f0a428a35ca414cdcce0f7e3d4b45f0a32b167587521e57c1e677a23ebb39753f1fbdce24a3a8316d2044165d2aebf018dc0e4fa4e89c75477ee02ba8afee69df1720cbf5db1d6658b7fe8fa0c5672bdc7af5fc691cc184fa80c9a4000b37b7bf8ab63ac072309374277e8b01a08b6e717a4ed0c0357487cd7aaa702bc593b6669e63ff8215e684049ee8466654cc978f81514740b20038adebf7cabf9b21dce2405726d7ed474f246867edc20a729434fdfcf2402675d4622230ae94fca7ebb4a273380d53416d587fae57fbb7907068f04ef35d7205806ffbb3ccca0ae38945966b7303ab930dedad2d02a4cadbff6c991c6af14dce43b59c55614d970568bb8137b600401299d2f7bfcb7ecf7b11ffb26a9d0c3b753c7c58803447edf17acf17e77d1977aa8357acc332662bbd3f4a1396091d74203b1f06c1993df3e34da20762a0bf8bbc1d0732d8d011d0f09264ebd1d1977bacf77c4fa030a4d346f152e0f1a132ca1b4f996b548e93104ad66593d8fde6d3c6eace63e1d0b53372f6e0bacf148b0f4bac5fe90e7467dcf62682cb70cd550257445758a6e159e092ed1952bf66e1be065e541e32954a08f8e0eca909ebbe54d4080b1f2e482952d912a32592aa089c82d7621d43ef59640a910f57ece74e5ee0af8a6eb59836c266360ef293339b97c194904bfe37b3462192247132a2407e27fee0639b4e3ce3e62208d0fa299d9113e3430d52eb295b170320511d110f83c05deec70b3e6fd864fb15912ec7e5d358ef277019719bfda9eb01e80b98d98af154aa22604988fc246fc4e1a1a7cf7cff87825ac183f5333391f32049ca0b09d57e1a2bc983c091bf55e048db026372f7cf673bcfd5e88d36fe0faefa7326a057caade1b50cad49a2413f9718f1a01aea81de054c0000dbe33e21f9081202f5c5e824bf240561c2f4f50763cc9718e66746da4443604148be687dedc2075fbb3814d7e0a2d79eb6695e7dcdd45ad9afeeecf58590ea21b1f78e273289259afbc7f97ecd517bbc8f33dd95bd9ba0da7b8e72d8ab1f336ee0dbb6b0e43612f87d558ae2315c91abed8f8c38c2d6b00df17206ba9752a8e958da506595f2c65a53e767d0453da2e70dd14c3beefbcd32fac60fafb379b67ea1d69c0febdac6558bec1f7b190028eeddb618e0aa70f4c65169533eda0a5f3a2e35cddec4d11508685278ba688b2e914ff23997c4d4b4d36e15113fd7bcd644cf3b4995799206e0d2f87f2fe1566b7e7ae721c49b871a30d16ac0cbccdf1747333745a91807ae6dc9b272558fe1eceba01bf5b68dc54d73dafb5 +expected_shared_secret = 85690ee044e4d8e0540ff984775b59bb5134383c4e229e79e37d7d77632fadaa + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = 7a2912329482f244226ae33507ba8fc8366736352380b346ca39a936190f09576c5188c5e82315e3532f34d41f1b50bccc42c1138802ccd5b50a7846ffa7bcadd91fe757ab7fe30e873ba233e13b21d25461030593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236218f199c3925142b53500291a3164516fabb941f98f0daaa1e2d619c9622d649a0408ac02d5ccb9b787c1f9b196da37020e362ecdbab03cccb63b659c6347104074b1f8254499c8452364726b1294669a3a24ac8b487752175b30cba68860184d5f78b845b107beba80f8750475d059dad57caf827878b926facbc00b54388f24b7b431347e334ffa046c45e234124c958cf66023dca620e1400cd5c08b89554a474d7d04086e5cbd0d051c03c4580d3442a575255c833026bc19dd301a70367fed300ef27779d2a49819a370519c7fc404acb3fa441a931c67a3033799519c883bea134242f35f92393dc134bce15713ddb33e252b991af10c7134a8acd09408c8cb2ada36bbc25224e8867a4138ed9b4daf403a477321614b3ee5c7bc2281441936b0b05513c1525421871d007346bcf52d6e09b756b4529bb5480aa3165e617cef41720167707f35a4415975a62114c7918ad83bbd8905a283d14d22b2400cb29fb1e102562cbee5a9c10929229f8c60a4b153c430a361812e75b244e4c3954a945459f735d45572e83b505030c13867c720567fd681c539d7094f5558dc5a86da79b38049b0a45a1259713af2c1640ee0279bb7191f0c0ec59c2f91184ca70a2e8b7576ce493e32f2c549c4bad6c925039c4c57114075281ac7631ff4d94ee0723c3400cb2d73c184489aa5b440ad470cde548f2f70903d08b9b4cb6db68a5d4fbb049a5a9727f50f9e6c59295c62bed7182ca96d6093578dd014f7eb0b121ac6faf917fa9b47f6650c6c7336d8848dedb92a0f70971e456e9ae625cfe266b1000c4ea6252de1ce20c014bc161fef405ff327cddda37be4919c2a0c097d6995b0eb743ff66a548307cee1080a13841ed12333e62eff081514a5915022c550c6021a27889bb0421df3a709ab2f9f3b0c0f6019fa8810ce3a9c37f53cd651acb4e5bc1d8b231f373b7a4ca6723a9710681016943f29697b09f6abfc1c60e8fc4c201a9ab05c260d2452c83b88423b904df74f425a9b4d116de0d059d96779d61017c2e984c2bccd6159c82dfa5ae7bc63e59304b1105ca054a71d753e7e583742e715bfecc80e51245ff53c16854ae0ab41c581402221cc8834a5f4556a84c19f6172c7c80c759299a42c71bd67040a29185a45c14b91b56a4af9178e0bbb0c4c197549b5c9765a8874686c63445dea7a85d43ac4d0b979b4ca13a80bf8db634a163fe3f4327210a7a128716b9805bc1920dd322b15c74fc722a126069abb8c95bd090f84497d832a1ab72358d4193b6542bfd627a139374404dc1998416f46054d1b4b538e778d6d0507fbf5571bd01ce56362164793e58355366495aec80eea35463c4044b202451b3604d6ab96acc3617acc1015379564d6a5ff1a6ae4d802712a94422a99d90988206776055545172b0282b5162b479d748a2e9d22356af11daf2629036665eed0642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = pass +expected_ciphertext = da88cdf0e629ad2c8000929d89554053e692132ed02ecf7f3947121c3da49e64e1fbf87f48d8a99818864eab9fe3b715165503b6adfd94b6587c65864d0ffa31a1e2bdedc66d2ba36ecc03ee41520af6302c4150a1ea1bc153edbf1a8736f3d57b22e309118019a6262138f311055e9b3750cdab2b9fe95b8be05934a61eca00f64aa6ecebe7ae12bcc6da07b91001fbc1d3161ef92592d0fa8a86d2a5241991174ba94a054f1c975b16bf36d4550ccced94a96f52433846252043839a01678167bea5a5f613eb41b4b33707999e4380d10097d089a44a721eb888528310188f6d9e642dd7677aa1e19fc710c94f645fcd2ce7514d69ef2e4650c6df9034475f6eada37bb02a268150af7b5181db8b5ab7242d601e4bb2ffd9d508d2988d4e13b5ab0e85094aaf296c8ea577d75de39a08e2bca7e3bbf132d886a2965b3476f04541e47e883e659a8bfe1f4c16881c70425528c5142a389d0a3f96cff2503c77a40d5ed881597fe8e5b9ee4d3db92cbf20e97aecc5a984f4d14445a33c31983353f9cfac3912150c7c6a48a8237f3ddccfc80fac8c8d73e4e527012170b3f485faaf8dbf3ce42f152b16bcdcc40418ec45e78beb00cfa936f31e16626278ba94e8fc0589abd8619aa057880672509a4344500c88f05210705220c0ffc327e73a9751a2e03606d0400d6f3c5bf4405ff0be6dcd9629acc2817b7bd28ffec361892bbcffd220fc3d9813e73aebf0929b814953b3d02a5d5000ac52e3a81cddc5f64e2666d4c86af23b1f45efc634f18f512ceddd5cd52fbcc04805306a794a61b0a502a6eac8e069e3aedf5039fb6ee62876795e874d6cc7cbaac232c73806644b49e10e5d69b5493e3ee647e7f92467cd255da303031270f8366c6e39a91143f92b9a803fbdc42e83251761eef40928e447d43e75abbcd57b97c207cc35a66a64c81e81a6ff33aa58e5e6dc047912171b53e34bb3ada16e57c2d7aae76c430f764b672f60e7691ba73fc1c6eaa57c2d06609ae2a6ed311c6479c9d3c8c12c4be9ae17ea146850f5676464a63d3c688c485e1caaafb515bb7ed4ed7f3d47455002eeb53c6282ff810ad5cb2bec2c5e52a6c6e5e8227c4ac72a882c45c9b2b90262111e58280f0cc6de4c86c667bbac46151d06966641e3cc67c86d06825c3c53bfb03a2505bc5731d0909d384ded3669197a2668c9d9c9baebcffe8a489dd5b6c42a3e2b65b236a9bf62db7342b0dbe07a04e2b8a53e7d4cbb520e1a56d25f427d2bf61a1cfbfe72e6c09a286bda114642237d6416053fc077f0824f439ace9a25433f57896157298f449cab005f4ce8395a904a3590f8940212a9c39c02ba42fc6dae73451e48605f2431d463c2c26f6050a3412c7d5b16a318286f8fd001285b28934f956138d7ebdaea7704451dea0641687eb19d87b96dec22f8a2ba755a62435a51f9246777923a9430310f529219ba8ba0d948c6c6dd13d2c0ea6f8c921ad9a3b4d2c9829aa9571279984c2bda818a338f3af9ab411c29b17fc4caba1ad3 +expected_shared_secret = d179d901a0570bd23aa52570c5c233a2240d4724e81d98c9ceedb74187eb75a6 + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 8e892a62437ce84445f2e82b495c9730fab393dc6f3b36bb2a63759a79ae27b162250076a608522440ac1e04630ba766b4c256341c6ac967b36e6934dc58cda15621827b9558076361192e89708ed88a71826a20e8ec948b9c7915566c70a7c15a72c36ecc7a3cc644eae696022657c53500a0f13a8ae50fdfa432d8d2530999275e5b9c1d341fb34b8a5a7421b7d290cbc3218486b555c92572bac8f1085f058a87fd48796824844553261ca11f06978a03f3a8d68657c22064af83166280af52270e004731d20b18982283e51ca3db7a2679da6fb0aaba1e75a2d283add699a797e1be93502c6823007ba5b9760a338768615b671baedc6a6a6937b9e1c35575776a4a791fec7751079c6683ba29ea28bad199175b9629c44bbf219cd88a19f1089aa551946e58032a9c9dfd29bc4ca3b654f494990cc02bbb8e1280b54ba3920ef98903f171c27a5c0fb679c8e84774f22136e89915a534d973733410a96280a3207407235ca0d81a636a35b9dd628dee9a64a12918d0dc6d4c600989168a163730fab8c78e61a57970c16c813b791a0ee9f625c438ccd1a9429a93062c4ab38da5890188829ad116a6f1564a43a2e4f3bba3712207b65e701995c99b29d691c86bd9844af2471eb5cecd934f764629dc25839c809432e395fd8582cda980359246eef0637b9771fa5853099007f173c8598164da69c8e67a910a50b9940b213547815e0589326b02ff21b89bc4200219652dea6ccd59883e29127e2abe3787738b124d839a67e02195d64989520737e3aa99c6822f2c32249256c45455cbd931a5a1fb27cd56a21e22b51c03217aa387e151631cfa445b2b77ec90ae01828601961ada8a8e6192104f02ba5064c4efc27cf2dc3353fc98f34bb947b21ec5235fba6caffb6bc6b1c09a783ab8ef14c4921a28a3896bac07ae8ba98c117b3624e01ed0496a8c649a38a33fb679bb535a7d1960028ca6c8ba825178e74f0e50b5d74c2a9119b595b863d0375a3da173c63a03d8c60a8d613cc08064588890e3894a9bf4580704038841526ab84e27cabc8fa4cad6dbbde9b53017f100778478b86138fbd6be713a7e695358538bc4cb5a4fff531bff178bb16ace5a295ca0340985f34267a3a931998b29a36935d3b13af0631cd37777689ca0b43b9208afbab88ef886a8672b331224c66c6086b8b15a8eb86107fc0ae260bf08f970cdec98ece9a197751b6996258ffb6dce05306380770dc63498e9b5d65acac5a179d8946b27630525b39c3755c070a120c9f468ab3aa8b1a48848081b888baaa1156bd600733be887abf962c46107c432c34edca8e549977d9a6f7eb77eb9974bb353896e8261502820f599257cd9c2852328b0fbc5c2b98658d67e4a636575a46e074a1efda2cfa50a0594b0a421661d81d95a9ae0ca1c037532ba7eead089961c29765c443d428bf20767d1f08615e85d0c08b0fa5076e297143249283c13486f61a4d9d39780624055d6043120a510d4a686f9b490c74f2da782ab42157a00991be019e093a509c0c00b7c1e6ab611dfc4373c640a2f488e7632be1289666206cba2b096a479b2140c6aa301bc448b13b6839447c4675aa1be46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = pass +expected_ciphertext = 3a289f96c11468b574dc8fba9ebc8e41d2cf47c1e08dd6cc9fad7519975af392d0f0608ff43bed72346208e0de7a19b1b5c6de3ff343cd5647afdc94a8d079b12207802c5b35fe1152c55cb37d5457835251f7d101d540c7fdf80e220bcda0305d8ab89f1105436071ef5c588addb1753756710e7ce507768236bc4637ad18749522ff2d5c238980ce4ff37d820ca43330e680d8cbf149abe46c8c856642191c8393e2471e3078f2860e57bdd8fbd5cc1c696e145f57a179a5c85393e05604a76c70342c2f708ebbf150765d7f018101a0b13c808886974202ffa8fba17e7579ed9a7ff1a97f323d8b3e00a00e19803d2132fe804248b86a13f4615de551a0dc65e2f2704b24c9b43c7efccb42b5ad4159a4e5b74c87f7df156874cbe4fbd91c2048299b27181aae40bdabf64657427570badae13bed38aefbe8d7f130ab272562bc3724a1ee05c32004b3e446cdf04a31e7d1628a6fc3c0ca547d7addbf959ce5038f5f6ea655df4d4d2ff45e124c5395833041582498fbdac6fcd27624e015f652d16cf7d8938abec77ba550807c598dc507105e855ebc717c88082481b92f1687bdb9c7e486774693a9140549dee7b387f28227a83968cc61715f68122e5e46b847056586fdc5037645f44d9654fe0aec4b4132d15056a2afcae3b31f0a0deef2964a7d039f61bd1920fb47facd8718d6ccc429704b8dd2c830d3c168405e9dd90b7a7e1fedf9c5ea36126ace5621404c6806e5a95b1c6495a3885c6c6d62ba4c5122303ee901c69c14f9383e51f8b565b56c1a3d8b54f048dc01a0193ca5af367e4fb92c47a019551becffcd2568ddc7d57b66b3cd5449cf3841c66d901e2c9cd6a9e93831c7b9e78cc26673fe3a7a54c85d3323029e5e9a3bec39edf9d4c00e5e1d939219842255c35265066c534bff32f32887a3a277e96525880bd4bdfa97e26083b4342c4f6882a074a14acfc1985732f732f96072f20e95328d4f52be6f3ba7d3e3972d6bf5d584ff7c5385af1b749af453356cfd6984591269c5014f717fc992b6ce5ff945ebc98e6df117d4e237112dedc2d8f1c88adc466ee74f612564ee5d49e94cf33470f735c3dae296e8fc1642c08308e285f20729c39256cbd63b664a375eec8a04e6e9cbdae34d5f27350d3313727c7b2f2612657865db4364551d315d8849a96e8525ce6e100ba496f6782e11b5d42c6da5f91cc4bce2c77c65c029de1f67f6977217d9256b70f47c4712260a8102a110a94bb3b7e26dade7b0b9cd0c158bc95262f54087eaf92eca527ae4cc835d443ae7c58daa2eddf7680637e42da68564168840d87bdfd5797ba90967299dc367ed48cd1ab7f1a0f094bd2915a9508ff2db189ab6aa2f7d813a9e2eb219620c8a1487993417319254038037c080051a98da562a0176436990937e64d458be7f34ed366aa942d169e486b163cb8153924d750f1c152759f36672de638b3f3afc7e569ec52165887acf342123a9d88d6c795ebdf6f5cafafa6c2a6e03249c33a74e2d12eaa9a63a44 +expected_shared_secret = 6d574af7fcb241fed8763b2d0a352870baf85ef686e90eea31f8500c35945ef7 + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = 61101724795296a2499158c8e1b50e4c900d65c8ae65503932dca40e058e8192cec2a997cf12c8a1227567b12a1b21bb31d3198c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397a9133d99654e6c56e7465d9b98bdbd624c12e36c62b60b6a32c9086a8eeb9b8919706f4573a33c393f74bb51d5609231f1707e152f23f36f6c6830ef28253c8cb81ec5c27adb02fbda5302212826f0b88aa4b4d72a509e29cb1bfc8177c019c60598e693bce999aabc4621123415235208e7869f62aa7b50a51724c13da2db59d5ba5302c772f2c1820fb0882ef32f73321c17f40d019cad39c3b12c57c3519ca0b38366ac4353b133c39262be6ee47ecf660286f6ca8eb7090418aba0d9833e22b46b761fa2872fb80972b551809c02775be07c796636a2c619fc748b90d28e1e702ffb0653e250c8c3759178c39e42411327a81c7e7887b21915a5cc032c37a11382c4d9186221b1c66afcae8184559910201c8baaacec62bab984e080433b9465e64a2d987028e9d9090cb2c41753742cd77f0998c672441e83d45f2d06c22899c2136362271b731f6ba3965b32e2517463e627aeca0ae5644bb8602f7fc599abc120aa111e2e549a276a18d2a92c39502f6f9519ce76c0bcb514e8084c7122a321479338f59ece08a0acd30f0ad68f2091855d5980219083398a6c0a63c70d3743678a1c0202a69dc526ddb77e30b779c36ac2575704ead94ddf1661a38b2624e733f2e2ae18467ce2c3083b75017411390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae1c29bdd6656cd75d9ba453aa115a32745f2dc1829881a9f4d5cc2cc053ab79b89d107e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b102378d93990cb8280b21a5d5ba8415c48ec17288044623a9631577c16639922978258cee0b6c51bbcfe3f70be07cbafb7c58111cc7f2f922aa023d5ad01d2d31a57e0469ac428b6fb88a97d957ae22beb768c3cb7c9f02f583fa2513db7c580d2986984314e8b346a06501d8972e31ab8ef5b983e9a15e8ffc624d0041fd523570960e09e57d616a06297bb3f9d938f5655628b06c4f6c4fa5f8136f8cc05dfab7389237ea75aef46117bf1b67aa978ba622491260128e743f28f95f533b708f3c59230b23faba96ffb5c239b32b30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a0812f59d9b5812916246228f2523175242cd1f432f9fb054a8b52d824349dc0756091b2f7c21e2a899362157bf9f631287b90d6c80fb55b1469273f79892435d031b62982c49a1464e2274f815f56f3b6f8c949be11388df1151e7077f603ae592623e4259853a2b90159344b041aa29c8afc5074bee81959102e0c57a761f1b1aa65b1dcb66a18bbbbe12b2b2942a37d13c77c77b2bde758eb1901f74c7d57d373a47737d6e23998e35dcee70983359b4162c7135126e90a807604034d52add3530456b66f0da64453150afbb67d67d9b359137c2420250c279a1c537ab06952e4823f09372198c253d5b71a7e70a1c48b1dcac3a85feaac35a11e670b2840a57f2a7c77b6a00cc80a282f0a1c8160080c702d619a6b6d68c757306c93a5b21ba8185b1a46c79b03c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = pass +expected_ciphertext = 85c0bb95389f7e5801345480ef8cd5aee04a6bdaa435f7198c4478ae8a16110b5356cfa6c84c202c0d7ac5a13fa01a5b08611373ad41db6bab6783bd8cb03964d27ef42e9ca1d123ebec7f32f21bce5ee855a48617e85ba20ec6da894b582a88367ab489b68628ebd5195d7ce2e969e5c4141c9295b95d0cb8bf18ccc65b9f6b36ade0ddd93ceb7c0473d2f1abfcb788d4b92262b8a220ce9d99ac358ded7f108c2c0cfbc54fe75f53cad2f7c8b2e1d5be8e24bb0c554548421d821ee1e8c6187c9ba06ae2c7d0ac58062282a8082713dbfbc536ee7a032f018bc8d85b0d01c4ab2a94ff97eee42322ed7ddf060ddee5803bd30268c29202817f8b698e87e03f5ed608a194d7ba1e89d027b31a4a2b7e23df5553c9194bf5dfa9ae4c3428d31b4851adf635a5f772e7747da34ac8698eb78835258006e4dcd1e2b6aebafa19924864263bad9e52f70cbfcbe8fd31f993515852a431ca984f0460f9f987075a244b8df3a8c6fb8cc5e46c31874ab657a31f32be45511bc49dfec92511335eb15aa3bda5f637349b1cbb8c1a927da6b4eb2af8d603fd988744f677bb7355dc737fe1f161c2181d45fd6b2792501aa6ef68de0621511a7b0bea9132e7b99dda23c074e8f2ae80dc5438123a63152f6305c6dbb156dd572abae44d3530c35b4f1458326d2824e636ea5b8476d9287af2457e528803ae3c546c02a24f3dfe9aa872bbfab2437ee2352eed14a2d94efd9b064c2dc59d076e882177af81e3e7571b8f73c3caae2c5880474f705327c034b6044d899635f16c15b45dbce6f3be9c72b5a9e82ae6b2c2cbd994e88987447d2a1b4f1ba3dad60c0ad9c6544296127aa9fd858cf2015dd5d6cb297744bce70b462dbabb8fbbf124e7723836a84fc613fdc0bc6b07ce574379197598e902912844813939ca8bdcc88f861b97ebe58d8aa250d89ab513c68625358a783b4df50eb5728fdb4a4dfb00a4059c3012a3a67fb942eaa4adea1341b3cfda696d84ccf833826750c27b5d9cd84683e5c3a562c89e8e2e4043d469ea530abdc68641e2171dafb8718ecfe9451430561bbf7c349acde5f73eb3d296b5d1bc0f0a004c4ff8d84e335a9ee548a03e1bcc2903495744637aa2de638ed226b202d126d4b80c0d56cc14e2d23a71f57baa5a866a19b490caa860dd01db946356c0e162727ec75aa5321ea332898de7356bdbf110cf32dbc9cbd9c6bcb844e60f0e7b064bbf8220e443d7385c0967d7f32d6e0f7b68d75eeac8a8c6dc3d8c69caea30222a11d4413c294b2ece3c5c14f8e17e685e0753a393218ff4dad9e0d3be4bcfb6d21274bd2be7bcf4ea0f5147bcbd7117f137d106d1ac6ca8c6c772bf815bed18aef0b16b7a000ac610b1d289626b1a8127879e5312462f657439e220b13cd94b0ac3977b4143982aaa10f2e3caea6457fc8377fd766bcd2c96453f6d0c03450a78d10fc8108ec1a21bef17ce36ae5ca62a5e3e5093d2db9ff8dbf8d9034e450d7b98b17826545a3065ffef40d932d94661681676be4f07 +expected_shared_secret = b1090cf26276a81c22ef0e4479a4c705fe294d3b892051ddce7eab16495e0783 + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 657b941f466659fcc971c1174aa4459551848e7a116b751e5e4022c8f2a4b3152a1b26a3096539c9b0bd6a435ea1e33413ac4d5f401f5de8570cc11cd4bb9fac473328d55501702743e2c8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b9571200b05300cb30bcec4a58b06f70830c2b32d28992b70427781854456129cbab53a7c72ff557193d3a221d06177d002095bc04e993b8606245416c3b998b01716af3b43a535f7a6bea71270b34ec808ca00e9453ae660b732963ba634f14378b1691a90e3708125cde31bae3d10451a5643f526cb790a8d6e091a725681fb539e9b05bda7b04c48a31b39da6e39e6be624663b6284de9f958c50149ce4090e6a486b68511ae90a0f093297bf090db3c81d34400a40cbe11d74271e23bbb7a49ea875ea7f7cc25516a899198362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b4314c4c44f44c96f48b29a8e7b85339037acf131f2692b7e7a49282237c8f37267c835c24883d1a189d4dccb7c6bb1fe622fc31301a6d3612a448084e0a210449b7e15a4fd84a9a538b2d5844dc170c911fc1282bc513e8c18c469a01a548d1ce4853128a03a8b1d369b353c3003b0a29d210ab6af23acd010ae3671493c774efad8b3746180746401d0e5862a3265e7969f247c954955b4afc13fc420143c10263eb1c6dabbbf5a8857a7f3bee7658c8399503c21a9a38ba554132344e214cd2036c2b30d0770cc5dd87ed9b246e7f955ea926965748cb9e58351a938f7e4ac249ca5c970cfde48c0ade051ba873d36a581e0fc50d9583109a79549fc5b32ba432444046ac0a66f3c64ae1498f43b1b36d8082442b5aaa7bbcff2c4cda8c0c4d2c62cf9135a75709ceb5b82ba4ef5716c4986a36bd7b4ad5c3a505869fd34aec2d7caba492f4bc30d232382b2651d5923242bb50df87092ace5566bc5a18fb2925cab467b641df7b5b91142318d120456245f2f0887ff13516d23216637393c469ce1f776cf2426c6577844cb3d4e0a92aba85ffb59979a7c33eaf51ea2bac9862160bf8a85553a3d4edc05da102106f632c91b8d1df2a9b2734185283941ebcdfd788107b307738786d6c0a0e7d4957dfb17488c5d6cc11b83e3504ef2923034a06270563e18a18bb29f48c36a64c132aa626dcfc5a615e4416df76746673e500186a117a27c5007a4b04867213c33739e27058adb23c0de35ce6158c99e59b88b147e2ac05f09f7c0a414c3240abaf65c24cfdb6857eca66bfc58e52472861bab1e03ce70d2115480b443a9bf799379af9ac978d0072f75bc7923816a189da5974ed948b8a709a8191cc9be60ac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac47260785c1b86a98a5dd733d3dc2b947d148f698c5a117821847604151068412268169c86d50be92d77683386025704575177aac0b9d3d3196a610985e860e2f799f480b1331ba346db0c379cb1833223836d88fd4e11dbf2985825c78330658b9a189233bc76b172127bc7a98e6c644d28da7b0857f67157ae2c27659297c32a7eb653697a295097a32ac235a11887388265ecb3b46a75c865c239395300d0f8152cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = pass +expected_ciphertext = 175c3b39d3296365a6f8e1e6648985b0c1b353b852a83a7950bc3bcf8ccde62f52514f63823ea758d4e58bbda8b6e95a0483faf6e20612d042765dba9b60a3d370808c7554c79b1ef6454419e80924c202304ec41a6b4d1d12dbe20934727b94e3d60e0f76c37ea60f4c385c3158e882cec48b1433fc62135ea6f05594fd98f13fc6929be35492b354b58e26c8035fb07fe179929649c91a532831df262188aa0280e46f5ea5cccc7eed59586ce55d5aa088692b25cc3ab58c98ca228306b09c26fedd0a823b36d845d90f6e5496e3b6d70c07300df9fa5c90ac1798c4ca5ca25c16d8bc2738c475aa76b8e2dda6cd00279935ca1bc8868d6bacadc33c77656af0e53b10be68cc1679c54404c686837c4aa3f86c9b18c4d98e335f52a80ca28f61520929c8f6c044eda9b7802575051d89287d1af7b47519661d529065eec290dc145a7e496d6408a5a6f067a9e1db3f7d99fb0fc34ec167e747fccba45052586f12d7730a489da235d84d612777b0986c501c1e028232c9090fe6c8fc51a56088c1881c4e09ea9baffe50a6c2491f61c5dc0711d96c7396b8922551a70ade21f332f5236f13d9df8388cb6f0e461106d32ab61817305aa5bed1b9ebfb44f85413634bd424a95d913c9a2ca3b5c44ccb65e65be918dc2917cf9e5aedfae4d4b49dff4a613274f504b7f30b0e1f2c076d2ef31c8395219f9712ecab9df8c0d4b9b843a514d520166323dda4e9a35c212a8fbfe6d16e3b6892282bce66ff727a8472326705726e147761a2128752e2541c5f5331b8962265039b78bda79e326c3d7124294d29c2a60c9a01dd244d7edca5936560fd6323b9aaaec48fecb8e275930a882859a75cf7aa467bab38f54b34f3b35e8d29574dd2e301cb9b4ebe7043a350c14f46c308c5001bf680232def77f2b7c8f5fdcc8cc11d65b505ca393b97c0a6d2d2484401dabdded20fe2bcde15773a2b109952af594a4d943608b066cb78580d77403707d189c8a11c0ec5fccbf8a82967c151c955eed18b395350fc85506f42639a1f1e6382b269ff2611833286310ff91d97996e9c3896fb1c7994e877e98a89f9d0d1e69cc6ab6da66eef7b75cc147d1633450ac4d8baea19dc6bb88a4b93d2d7fe842a36d900d5b52e77165967a003ec5470282891e770369cf21d21d71a982aefd6e2d943c68b51ee312d537ba02a952baa7f6c0fbb6f93d554a4f13fbb8c48c04e2d9416cb9ebdae2ae2bad31d6ca5ed0f7cd01bd4db174bc79333c4d9292e07dbcd48e72cb7e63fb36dc54f0553ca0e43b48ef63ce225781f88a556c37cd2a1fd24130f41f1d778d8d9d0a0eed1a5cb75b924bff5dae57119cb38ceca4b9cbea6b6b7c5ac854a1f115945772b981634f402dd69e536d2bcf51466a20ae144fb853c475c04ae4c40c5828c230532982dc51e53810fc73809c1113ef54015290aeb9bcd736aa8ab1f747d5b90d188fdb45c8bbf14c06c41515f354746c7b08ccd2adfeec6bc02266a78380b972b7ff44e1d29cc4bb1933421cb5450 +expected_shared_secret = 2fda9fa72321be3a0946d6d914c7ae714b9cc175619ab8abfd1f1fd499e0dc27 + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = eb9b77f8c16dce72611902a8ccb81e8cd4c5a2fb1d8fc30ce226bb45779f41073ff3ec0362ba152102cf45d3a95874a551c14c8a621436e248ffbbc4ca3b4033d50efa392dbad9c339745803f845736c30bf309546229ef52788ab223758c03491f62913fb4ca4307dc6b4c7fd9503a701ad21671387cb2cbc728ecff4641e312779c7034ce720554a948a021751d4628890ca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934e4144922ccfa2035892c4cc2a8457300946aba4ffe77868d34c7a90507be43748a366c49d0a927e66610a08cd0152a2c1bada92a05694b6e3d2610acd4579d5634fd2675f2101290e2ba1855252b57a438b50fcb854ea7b6a89b109ea9857c23aa38333428b94ca5a524977d72077b56978328c18980382ebc967dd37e6136360a958d5f00c3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347d9b018d437b3b065c120d26e9033078b5838dfc7ce68f244b32c5b4ac04def068f58fa733e99a418176575ec2ba0f78d4c402d67176db5717023b57f8d26c636a11f49b926d20b277d2613941c3e786b1a9a3c1135993bce22a1de16434a5902c0f101993b65777399828ba52330a2f356203521a3c59b6007c3aa41d198a8232d27c05f8e0280c9076d54d5aebdfbc95c7c06bce24507892641f90d2b774a2d98764c42bcf009799432b706da59bd84cde4892427c0586929c99850c7d769ad9a221c85a4062a62b2a1847454554224c4cc47898574fa66d147c4aedc59ff612f49285db54170508c89e6787a8ce6515cec673d4545970ca8ec486802933e319800fbe46d5cc14c8363656dac0600d895fe383fcbc3614fe334cac0a94c185b73db30cb5a56a8d04cb271b13859862f164f980625d78ac35ed120605cbd69e6410eb05168819440816eebf8cc9ad153cda5bc2efbb00a7563a55856711231cd12873a9a56996c174ae43b5c172a1445bb40cb3deef9051035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54b6021d180881d59d2458564acba148b0ac36cb501cc8242919064ee24343f26a87a0696000533a20943445c72b9260b4c8a46a1c921c582600d978c5370b400b2412f73541a13ba0349e66fa4025735cab6402aac51e08a019b48115c49c665f415244fa91c208c6b1f2bb02bc18c47a5aee366edbe3bae1e41a8b405ddeaa22a2fb254a6b70dc5a16c0217e4dfb933a127039b788e6c035df8993ff86923500ba466a81d34a0ada271da4262f33123a1b81a13621211845a167449d93370bd95a89725a56a8452b510a7fd2642af41a4a7856abd9688dd7c85433a868103679a8eb2bdfaa0cb52cc141267e91e2c1e57162c6b4897c9004a3d375c1c8bb87c5ae2cc80c2a107e0f904e5bf8065ac96c9152aeb07322fa181a83a9cba0224c9faa0f06cb67e2787eba832d3f53ac60b7b014d28945361759689c3ec65f8b885eda081443a2afd2a735b1c57c201aa4d273b1302267e5a63abefbcae8e1b2d3883439e2be2436382eb9bd62146de0e446b6e2baf8300575091db145a646c733bf352989938fdd8003218a607739c60da6758bf448bf18a22630b08ac40635382e3bf86d16625c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = pass +expected_ciphertext = a79775edf0315a85e2a48145e0ce0e7b2bb5d25d995a78c8b4905aabe811328d595575e87409438b07a0b772e9544246a296961385f20a180addf607531c8aa982b4a5ca6bfae414956a40e52de3c1427a087c74017b0b711696459fc50369e06023bc915cc0f37ce9b1a250bc5e3ffc1404df54edfb9935b7ae1a5d73811515e0c1fa539eb9b11b08d0329c1310d3e49c816249d1142240f605e39abba101adb143a143d7e4ca7abce799e13135033c98555fbfc900a319824691886026b395841387bdfaf4f2cb712e455e48880edf86c40563bece6cda265ed7eed3ed91e649cc086bdc81ccc5d9563567cbd45f032bf78235c2576a12d7fff82170b4e0d0d6dee1cdd075e55fde2e1b00a03edb1615c8f225674525d7a1c8f17e8f8dd6863dd41e990826b482a307ddc522e29d271ab97fa57f2e2020f50701c7151f445fc3a8ef1afb9443aea1919edba5a68d745e3863accd6e3ba32f016d405018890969148785d00ac8830c17a7610376a0450f037ee4f0510096cada7cdb7a38d9a765da618e8b5ba2fb0083cb761e96a753fa119425bd50e4b996c5cd4f58377de02ec10ffd8751e6b513c3b33e7b6e45027d25a910a380cc16cd6e85f079cfe1f985ec15be162efd333d594c2fc333f3389f3c6cba92ea1285d68112fa07ab65d18878c423ae22898d0c63057da644004de424d312d099d1c47ba88fc9e35d6f51691a95e0689ab180955afb49caf3891a329858f625bbc4c54871aa82692bd0b32d0ffa87662bbaa75920f8bb546bd0fa4c67c63aa72501f7e213f72a9d2b767eb5fc2c7b5f83f492bb9eeab10bfa746248d1ce4ea4d497ea4de28878f764a349e2f6c268b7b61fec881f3bdb7910a7fa2dffcf4dce41fa8ca4e3cf4f720f72bb29799c93e7affaac971734837e9e4358508b5570c4946938245c30b566292e7fced74793a089046cf396aa77f277ee2292d1ac516e09213b1a334dae4e4ed4c6bbecb9e6f12840a3a7e111ac10714dc73f2c74a137a7b662b515175b9ee56e76eb21d26b75bd5b4dfc7cee9fb6ff276c27c6d531b06e5fc26b740090cd6830c126a1f32e7ae449507eaff06332b792d82e68a285f5b7af77f030dd4535b8eeb713948ade1ea09559555fefb1a332ee3548d4a29f2a4cba841c7194c7d309bc6aaa4d8d299d99965300347aa16b35c90871c4c7577bd419b2076628adea586d73988828327220dcdb509807b7dc921d5f7771bd8a0de19667c965e3ab22d3198880e837716e506068a70de4b4d300a1f1a386ce65d8127bdf38b2bdbfead80d6b7b89600b880833d84a38b9dd9cce2646a5cf6849595f0ac740b5e65e6d7e1fffdbfad7d36ced685b4fd17911ff697a8ef8bbb37272a95139920727deb0bc7d5feb6fabc89b4d342421b29d71d0796c5312484711af245a0c53629148ebe4c1a61bfdda623775b75e263cee799334be799dc8d26791a7b8ff002ca4f92ea37660ce55199ea6b25134eb9c692b255d3f59c96133c6857ff5aceea9c32a3d90c3e1 +expected_shared_secret = 23798e8b9eaa0b369842cad83a2bc32206f791229c830d7593b9150161168011 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = 9bd11c902a159f41cb5395be189b1b7e98cc23658dccc7bf9a843a77b2a6bfa27bc941b04f391950d998c607a59b49330811200b38b243060b55e381c078100da84975091f3a0acb06f22ae3fb1b7d756d36f54200a367c109b13cf40f3671231d5b0ce9e5908776768767209f4726c54277d0f8b0e05bb4cd50bb5547a01051c89abc4a352745316c8d85a3187d68382ef05dc96294446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c308f22b8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf2325cb060638c723364b27c8e3123fe26cf9862f247cc31c844ae77754206b03b497bb3283cc7e38664b23771f709e1d308cfaf5086f25acbd04cbd9f1612acc2712d129c9c195bc024cb057b0766aae7b533e60f04d947947f920470bc37e5eb4ac4fa1c48066877b4456d4ea2a5ee089de38a7fc7573fae5480bea823727132651a85d873378cb97d6f7be1250a94621abf5eabf0114952665cd2a5005af338b36d19f6e4c8f77e2cfb6f24d3cb7a909315a026b5aad50a9cd4baf3308059a91323b1c226ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91546a2354b59328d411a724cbd8b3689efa335d879996fb0d1d2244edb361be4b2489e84086f4a995f20ffa9404082c4e66061d3ef668fc155bce04916c92b8fa46b77a4a9fa82c8c0ca5a5a5245883d25fded230e74b22394169464bc33fd51fb7f2aa9214b1ed546dcfd00ad554aec80882ec170c6ec44794204170d738ef9341d6034920a7aec3b68fac00527b2812d88969c6207f9aa122464a4d76320ead6271d2836e574155310a756cd4249fa7474b301ca978a0653935b7740a16c50df1eb678c1bc3eb451cf6fa35beb903cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4252b093d2ab40884c39a4abcbd19b108b81172e18a84a288aac2982d113454335423148168bb6b9d97494179bba1ec8760be59d06251b94b4baaf82a6481c4a8f33b0fc3164635452e6497f992308688352cbf44537c618000536f9c41a64361ee162236f9227219b8b84a3984c649ea82211207c974f6c7575027aeef57e496a58ce2719096a58e2e31e82844f4d674a4cd9cfcada79afb0c63e634d2514ba4d8604ccc42b2eeb64691aaf23727c93c4abe1423c27b3b7abf0b649334760056e591c32fe812a753723f7c93ef5524c8e0267db177e6e55620715688cd0ac70b2a90e133caec86945bc74d7ea1cb88479a37b45eae4993bb7048e5316bf66b9715591148c9a20a35412c2404bb62c512b3800b9ae104453d95acffe000d3ae85b96d8092532796a03039ba2154f84afa4a402acb673b8799441bc505e836c3b558e1fe2057fa79153e1630d72afd96aa4fe9c0ed4822ab33a559719b81d274ef0a2773e405761a036521278df5ab3617cbd89d7543cfc7c6ad373b2d0b781dc78dd3b2afa34b6565979231681fffb8c62843dcd11686ea59406e23cdf96aed95554e47027c5b6976f5515bc40b0e3a31c556219f89b73c0871e1ff552ca04c33daa4a363794cc7c0e05249b53d20460eaa8ad217787c8c9423a7eb71058b5a8081b82454dc91f77f8608d60caff30a7c42424542a1746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = pass +expected_ciphertext = eb2ebc83c36b4b470e983a8f9befb67443567e2c532348990f62418cf62208d84c1e97c114fb76ac3d30491056f2f820178164276804a16267eab23b270f990de9307b5947680ac4d4c070a2c764ad520cdf3f4f0bedee9c2eece09f07df98209e214abf99c07e7f50e78e38cecc268f84ceabfdaa8010b1c8b0450f440923f23b22465770d19fec10e0917874dc78243c3483a38d49fe28526554b217b2a0eec4bb4b45fa8f92954dedca998ff1cb649237e0e056e72216660a10253ac5064dd0faf13d0675ddaa9a3142c399bfcd2efcc353c316e4e8d3bc9b6d27b9ff8bc7cc4f87dc4d4ef9f156b0e80ff45192dee9413e74b83dd98a6b5d3a0348202bf041efe408dceda6e1323c887e414f126ba35cf6d78da697a47ed66f8053d9cd0a096ddd6649e74138d69caad22d856297f4bcb2e4f7fd6930210e63325693adcf4c60a346b34b17fd2193cc3e6d484949106820fe308c874f93f9538365b9cadbe25230dd5b3d7f153bf54fcdfb1f2f668e039f3186d9e4f9f336614e88954ceccc791d584ca318d942917678f511ff1dec3f1534569bf0168dcdd1505fa98dcff66951fc28dda492f0afde670bc4fd0adf3b5303f3ded36d323a89d58c5b37b9df02a21174abc8f2d517bc15f2afadc22aad49a678392d3dc5c96c3969e4b55ffa30daef78b07a01563ed24b214d662648afcaec2ec91b5698b638889b701ae84fe06daf92974b545a007b73ed5a12602bd0fd6cbc5c62949ffbedc1337bd4d1c10ef41040e31168135c45c765245c00386ffb54a6d62eec1266a18daee9d4519214663d307d43e729954807c859c4a6834b1c9b7a47966c6bff8e8b4e062d1f9be53329e0961abf7872e42fa510cfe350c15030a0e12c66e8de05af485b9688112b5c4612973b81f50cee871d816839a2beeba30bba36981e483fe600e2993a60b3493e016596545243c7887f9ee9dc1ab6c875621c1d4b8c600e062d5d37a30421bfdb811b62fbc73c0910d305b71919d1c80169ad86c0205cbeb4bb0df6bf7bedf96c741870d66a78a62d8ee9cd7f7e7fa8ebe0adaa1389a4932245ba6f85b908366d1589db6c2715265e98d0f5e89ec8a0e35eaea4c9f50aaf213158e729e3766c50497e6c2b9f44668b4760e593fb509789ade992d9e7d047a50045093f2d935452648c7afaa320b52465d48b9e15acc640b9e89a2b0b893a6fbc8c257f386e4cc9a52bc5d2ae7590cc2161bcfddecd17e8daef627fa9dbfa92b76942e6fdc0a2f09692fd82391d69546986b364c5a22b2e91819d957e1ca654faa71b11a16b79c37130610c01f4f9c2da974da0940ab94febbd955578b28ce30ecd668c8ea876ec9b313ad41e5a29a04039e50fb24233716a726bb202e7662c37b90adbb942a6cf708eb77abafc6850af6d037024e6c781994c421b3fa916ae07cabe60dbd701f9dc7c29ca13dc810c89970559853066e00152d171823b237a0e189c1fe72d14186f420c1bdf6055270b3782d78a2d924be110794fd3eff58d8493bfd6 +expected_shared_secret = d5c63d2bd297e2d8beb6755d6aefe7234dea8ecfba9acda48e643d89a4b95869 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = 8683354b3c3f035586b50b88c4140f346a05ada7ce4beaaa5f096614cc767af89ffccb95124b00e8379efaf76ca381ae4886abed9240bda4710dac62a71017059b07921c770da1ca2d209338536c3a9b5238313bce565fb861bf8ad3a78f030b3f646b34347f1d215e8ec1789d602d92a971fa3c2e892a09cfa68968f96f206a7535766ed7533497fb051c8036b0aa81c2c802fb7333cc6744ec830e4be56ef1e4874371409486c477cc4ee90092d2919f585ba21f32bc973acaef42b4969746ab2618631b6536ec298b2828abf41e24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d1712e9ffa937ec5194a3541e3fc9c685102f9a47faa077fecd688d607996e5b60c1715e617994b842b46574b87086a061488bb2445b357a38934b612c16168e662112756bfd764a4fcc5f7b1634f6f28094464d600046ee03b4540c1049bb3d18f783fba2ac5bd36ecde662d9e08e2a89cb754b090db7175277941e5973d010ae08a4b4c922aa99f47f657a49c3b81fcdb54c905a3010405ed544bdda9942bc857b6d979f796c859e0627a5212543477ed791c2adc95fdfac9d21d19750b8b5ddb95f02d721a9304099ba6b2cd0a40c1a2f9dc1649b2318acc93a5fbc52e3f4900bb44d20a7250142ae5f3b77c0720c77104b74c78eb821bd32e260051c499b5ccdd9d716521163557b5e4526acaf09a2beda04994188a5065b4a975b215171eb288024581cffa37d6289813773b29f1c0ef5587f9c98049f548d2a0c3a5c71c1693b5ec8c64ce0267fdf625485dcc4b5553c5736a0d0623cfe20596f984c014aac0380ba9b58257a993b1be3bd2cb9ac25912b36b2c085443074f093510a46cde5441ee3cc88dc2cd636a5ef77310f91cb21abb149db2541407726582b54b50306cab4b5356492c220c138c64b4ab293680e01c2aeb369bd611064fd8955b790222bd5997dd76bfbe50a2bd039c1f14f0469b623c53195a3b2ff068182d951dab05ffce9a6c8fab42886987b7999043c12870965bd463980aa6b35e13b5bf9c25b64920d7788a291a98ebc30d3785783c27e53ca9ae809004f23706e3cc0b9ac0bd571084100299c932db2933cd91566aaa367371b16069a706be664e86107b33b1cf05360248c808ea250fcacaf9096715478463932a1c632cc9a185eeb08583a9309259c567743995af013216b1086815b851655d0f14fcc43682720acdfc36f35806894177ea2144f6e28837cc887e560874ddcaaf60a3580fcc7a5f1733180b1f1202a08182345370cc5c46cd28a507ad846d1d9415af679d4b22ee560c6c1b2499d5b74aa2758da090e62713343b3a8b14c68e415a3f196c2573c5e828a16cea51443104f9cd899ad03c3b727774b48ae61db98feda4c1e029b57f89d1735381166b70450215af92120ca61a8a38e575abf2cfaa54c613031a9ba60275d23178ba553a3ed7179aac44fb3607e93c1c57c7bad6854533844bf3d6a9b95a966f891612239cf6cc41df1a859afea9c0cec6d2679cd7c71c2cf251dc9759666c871853a1012294022fabdeb2269b430397f337b3f416e528748903ccb8b24c8fa28197244c0ac3a0345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = pass +expected_ciphertext = 333ce97c3ce5fa6677ecc0eb829056e8732a4bffb16f97895f2893ef0f27f669208abef07f251184b011f5485050e7dc471ae61c651499318a2634feb720f81edee3a9153a82d840069601e13e8a05e35fa2c18b0fa66745e104319b785c36adcdc4a2dcf03b152bf488fbba844eda7eeb4d289dcc7e926dc0ecd84f651a3f6406929b26223509789a1465817de510542cfd42424b594587c1cea93790e88688a9492146076b87cd9b3d52e772a072657148cd22c6e3f1cb724795d4811330a0469f91b3df0cc389e3e7c6280a20f4a8086f66f1d8f37446060ce019d1781b7900251049389911c0ca210cc2c6741ae7b2ae5ac5bc5905434645116cedd2ec8147ce6021bb953b98d7e7576edb3c9ce8ffd31dfe2aa2bce390e82862def5de968971fc0463666f754317e0e5670d4a573fee33ace8196dc5767be6adc9976ccc07e9a11fb7fe8627cf6b09e07c22da8c829785a3cbe044f8622dd130498ca4aaf6a66e5980c7e4055b6e66666893309345f7e506426152a6ebe811f80e000634c09c356306bc9c4d6d535edf4f72b860d0f52f24acf910ec731743d0856075fe2e0f9432db321d509c122b2bd69b18b62f2d8925cfd35c273c2ff4c0fc184e6c060707d30de3014d8cfb9d291f2d6d31700805da5d41c1c6c3681fb7603ff518b3132fb42f95c23685b6b72652404b1e6dd61ec31d27ade50384541336230c6b2e435ec32fc783972bf5f48666690687642732dc5f7090d81460924e2a7e64c05d189b88d4276bf9c6b51632f197f3f76e5a97571467b83a2d8754ba7fa8e827bb2e7517c30e5ae5c0fe9735897a86ff3359634adf981201f6ea59adc80a63264c776a08b939cc9c5565281adea113cdf3bbb201f5c6754dc2874b9a67e4a68cd2853f2ff5becc9d3a7c43c8d3a917d7829078a76d097f7117f87b7d4054a439c22dd41183d0e74d5e496ec19d66d555b45348ada3ed9d3ae1b3d351921f68bbd1d9fb4c87185614bc7b0bd3a53dc81b9fab161794a9217ca0c5e716214621c2fdfe6ccf9682135a14d52800f7844096dab5c59b0a07623657d505701733e409c8c0ad70a143cbffdfcaab8e8f122942a8197fa3cb2b9e0d4b80d30fbe7a8fff8d49df0f59725db077839398f75961bc5b9ae4f1d03f6aaa4a42b3960b7212b535bfe34360d1809317b3cf268905e41c923752301b0a9660da97cfb14726245e55721637ea2a075c202753e33c97ae9f20aa5ec6ac03202af9bd5700e93b5f94d63a683cbbb8242052549c21b4380f13be398b8d2db55dfd9fb04c21387393183a7f5547dc7af9fdb6cf7fc8b0f1665e57f67d7bb59a06933a15fd7313c38823af5fde333572b15a5f13b2740886a6bce0e942f6dd5b82f4007c224c500b1675a25a5c0732b72391087f2bd04d8c9af2ff040ba18aef056fa13f088b3b564abe07536195fcb800800fe2ff41c79aa0cab8c561cddaf1bad9bb35792f0e61bcb242a3f2e3443f89391fdd0f1951c8b2b615b684abea2be35b1af327620e00a83c +expected_shared_secret = 29d6a229adf49a1139794209307b0ca24be5825b2771809232fb718660162475 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = b147b4694b12c461130f3126f8f71673e4643b2147ded2a7270ab360f6303dc05b03a314bb776c488318686069c3a4c91cc62435e829a6a8621ef5cf838311a4278d7f453ea5484d32f94c2e9628f5532ff93771dae106c8ac9cc80ad07d306b1da78463a08226657680e5acaba6819543cd96194aa5973d4f7b8682b13a07e7a5194c91ec95a2d671a2627710a4c78aa107b3707942d0c78f3eb2b3a58b7833fcb0fd7785e349a2f0027aff079b62a68e3f425122f7bc0a0b4c053a6696f90a67088f139b2a39f542d6439091e4c1a0824734d8b6e5e6483f48ca738c39a5bc2016c0746cfa9c1889297f5377d614acff2833ced20abed0aa6c7024221b73d53610575c6d91a262a5e834abb63cf74207437b31b1e989ecd7416b2c4e7bf807b5f8973006877e204a42774c93a1b394e885cf727b7fd286def2b4c8d5684460219c31b1b225aa08ac2ee1da3922e935e981b3b5e2c3d044a784bc965a580d3052ac48000ef6183b94b0a870e65207ba8029c0bd34a10443e5706792207fe2224da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1a518fea187bdd08072e47588527c3b9a5eb244ae9e910f93c92b69faa7250bcf38e68e9c3a2b2b733b18032f37673907097a4cd65a9b396db4859312d59113e07b39746c52126ea697a69929b1b625b5ae1b809ce9a811d13cca70971ae8bd6ad223206691af6897f136cb451699e0a19739d52d60cc89dfd654a320a79b2c7cd55116843239d6847b8bdc1efa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93dc2a395117426a17af4d404151814cec80e856b777eb35085f1ad14285078803c2d76ac1d25c3f8609aeeec4adbcb64136516a2077cff4c13748c5d1fe6386782688d944e0027a2f8c9af77b79352ea5523767cbde4577877af1f8017e4db244e833e99dabd0fc70824bc3c50a38275040446a5c74406873ba0b5bfc2570a406570b424727379e5c1c39ec194a29a8aa249844bea2a078c1c0f25a400d6bada80731a00b87bb5a19325b4e79b78af0bbb2c52c3db38ae552ca972c3927291145438115a952bf2a85e78f6141e1cae8516b056e614b7015017e71d54268ab9919b7eba09d196768d99651d60a334fc443c8ccd9064a420263a68531f0e86cdc48776a3d44b4726916273a0d3002de095526257bc5e6246dcc10814d1907885207a53241a184ab7e40d87148a336a33262a4bb0826b417abcdf957f68737adee682194115348ac58814661765bb321254a874c4a3c6745cf984528c2b9726ac35441015233219e169d0ea761425c06513720881b330185b48bc271b275dc024419d8761eb23801eb704f6326f162656713acc2915a1a6f877a583c8372cc391ebcf2cb22873c5bd22c58c80640cce759b2c09b368ab4ab504c613493479b7725a18811837213f9237734577af09c4be0b3fe07ab78b712b0683060be76920cc5fc56993e56c7b46a543ad675b2d13357c008911320e0d292268768b8370c66ce757af191bb703cb5732113acb8f02618eac98693224abccea04e7b3157c03b27a3cc4f0b880dc4877ac35077c1c2d5584b971261d2c4bb767c75907827ad7370f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = pass +expected_ciphertext = cd3583987c6395ecdc3ef180fcfb4262be1bf772a99b337df5eb36eff544d69276d7b4608b69022bd044fce397bea7d55a0a37807b53455ac6fdea5f0435dc71e096568cb19afa1992770c96f34f9f2eb0ce27e5e3200a47bf36336a1104f9de0d11706098fd63bb97123e29bbc4661a4f6237378e23272315a95b587ca6c289dfe0391fe12a18a257e3aea5a362dc0e60875d65ba9524999a010c23d2cd094744cf538e461cf77ee3ad166e54c8f7d2a746998d08d25ee34d5c8127c1f2f13aedc7e1cf874c087e123d9595a4ca40a482fb0696871438f0d3b07058131e532aab8041e95a42cc35b3a5937c59bec36be6b7b7773f60af694ebab7104434c23cc78e122724a912d9921b4aa0b1a44755161264b6f9cec639d4a7059d0d08ad9d1e2c1cfa9f0689dce97c04f070712bc54e19e9c053710f9ab5777fbefca8dd81761f93883f861cf5ab169fd701a39b9ee3d3ae5d1f961ff5b07ba15022f51deb1897983f2bb94050e099b573c2268e788e406dcc1e666734e1c74305bffc3c9a6f6b4ee4726694d5ecf499dc6059a17482b672df791ab1495e3be6a1cf0d7cb6a0c88250c19937f5233cbe4c2680f31c6b440c253fcbaf8de742c2d8af3f3734b0e8c433a7db21b105bdcf8c5717c2dfc8db54512492b0eaf284b1a6b33726d055d5e222ded00da6f81bdc30b728226d0aa46b64da409e2f884c1972fd4d123ee016b9fcbd7abbe92fe028d8b36ed4e9321c8baf833c0dca79d4ba16172adb1225d3db8f597bfa40bf58854641743b40dc28e8de9676f815eb5244499cf8b4a15d83b9f864ac4e8b1c0fbb684c3c2056abad006ec44b0c18ab5366cccc3f4871ebc15cb94d61ab91751d8a559b8dacea2b66409095460b7b352625782ac17c976936d75995d74c6f89318176951474c07b19d31b9bcf63ca772af3f923528839abd1929ca63fc6cf5d67435c34675d4ee6caf474585c65654c3d79c4e6ea59a42e2825c229a364a29ee84eb78f63846a7ff08b21fe077eac0559b91c91452e15147ed5f7109c59b510856f11a63f355923562aa0434b2e16d6067dfcdd619dbb80a68be5790c195e0b9d3b9e9ee13273290fab34969bce02c5eef6867b0fee382a7159b4c927bf56d29fd0d849831212386a786c2a9bc086895db111c7a3797a40c9236f425454380fc5a1f96e2df779f05446d123cdffe072aeb9e64f87f3f7111470061d87ddd0b8e4dfbf1aab0604e90da29ea0659fefdf17748425b2730b8046af71f948af2ca5363eb63d2f0399a22f8d3c01414c1291a5dce3cd654206ade8758077275458c95003452c1078cc787c6a4eeef475b78bccb0419c0716938a1ba1545cc87dfab4b18c253d8b7408093e2305359359f80bea22a69709a89f4b1a70d62b529d14ebe929a64132a1b53c7b6cffe3214eadfd77d385113fe3ca4a743cda6af120b25009b5bdecde4d956beb970b8ec1e2c5b7647dd5bd099f3f843c0aafb2d00e26b1bb368a82afbad3819bb34ab810ab55222ede8f28486a7d +expected_shared_secret = 2a56a7a6d5b4c0500ec00a92e322e69be9e93006240889552072482966c54f56 + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = c0c8122855031d7bb0ca735042bb43b8ec6ee13061046acab9b873b13519c22678ace2b59f92aa4e8269844b1de5e3426d66c0451a8d78cc07e719033a536c2bf4c7397c64c6478be5f42a06413b8b44111ad9742b8b020711446d63cdd64490c0917557b884eb429b05dbc0df7acec032adbba55d3e104f7bf391cba28b903a07712a8da3a1a92f5682cd650a628573844032a307704fe77af738696e974181a85c5ca1c14f7546f8713701115883480be2cc686625a37b62292367b5e1546f4189592639cda4cc20974c6a87c0377d15b8ec5c84b70233b64800b79c62e536553b43263532c6bc2b726970cc58bb20f0c0bd35b317d9b66b327bbeb5175d9611985ad799ebb19ad0587aeb856c288464d983256649827de9af0fc79afa1aa5817c06d3447a25ab3eb8248167ba60a4462ed47c007107b1eecb630ac4707b837f24d26da46bcda77c4b6ed5b4118b79294744788b9a9c21b168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb8615262408ae25c2985189ba8ab99643624b70557a984011474586c357f1c7551f0bb069336fe85bb903040f48c4a111113507055f2716d37ea6a6ffa48f40584914c4738397430d65756f298aad345671077da8a4173728364a493bdca944b1879b114166cc3b8293937221257c2e78f8f1c7794eccbf0368ce34921a2ebb01e32a92255a676e77c39564b575aa5d1f9c7d1388226d636f4f12c5636b2e2f712c59ca583a811bdfa56448c013cc820f21a36c3351aec3c2c6f01243ff47bf17181ecac752108c43a97729c6b9472270fcef5a7c08665f7aa9faa55b152163e8446c1bee5082192b5eceab269ec13e7879da3768bbedc0a104c5e9496c63e9507881a4c8e758211076653f369e58b59bd7cae5b9a64772c2a84329e43f492fecabbb56514cbe70970f361e6d3c6595065f6cc668c64bae7d587fa8bbad129136d5c9b6f757a51e653d2754aa0e35307845a55b80086d5a0e86302d306b9ee1550419b495d424f701a098220897fc47333d5a1e994c8584a00d79804e4989a1cf02dcf9a0ac2ac52be1090bb149778235ff6091075a5360ce095cb705c81e3be126984f51aa471f90ff98c21d3989fd936502a8a2b38c4a2320a618df751c7099d1063495a6a5936c744a094cc1ff1b04ba8b56b0464e852bbe06176034cbf5239cd2c687facc2cd37329adbec3a77b4842aec40be902e8af72fa5805345668408cc7b6073097391921e765e4d76025fd5c78e246da268a4db21446f2cc3273861d2081daacc2cc775631927b709dc1fa8993b1e92619590c08940342219682af351495b2e0aac74786c897fab196abb609e216997c2c7b283bfefca4b1f2b1b6e98991bb32424321ab7d61e4d13c44dc93295a75f6145bf2d4b8f1a03109bd7038ef4b16fc15f44ca6ea3411b68400eb20c46c11cbb98201d705a6cf4f4b792aaae80d97a6ab830576aa651142793fa7da0b8bedd877217d54897375ec285849a79268babace85176842c601ef8c740a21c2c5321436a21cb968ecb5410e811912cb0962f713322021516535907914b86e9411d27cf164b580528768ad37b57300dc201557bb0a142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = pass +expected_ciphertext = a611a3c02dd6d3201596fc2e819f631c7c468d7437c5cb5e1dd20d69079b6397e4735b54ad9f14ce7764e1f7665ee1027423f129ce329d4f89d967b7e9a1f1851a86b9241695db93f77276c8c13e115603394fdce1e29768218f10b051481ba1477b0f50424462f08232899c6d0da4d1760e9baa2523a59ed4bbaa1d56ba1610174e99c81d56aeb8f9811a88cbca115e98b4f16fb0593ab5ac3b86f2c0c1b66d8be9d2774b66c0c2f0f9cc2df6ee453d97f0256ca73338643438b03e3c59ed591646afad1424bee637a50eca224adc62d447c64c3b18a55aa01b938d66ab90099a76a48f201cc66e067d4db6f5b4f58568eefbaa68fea67ad5eb8c253bf4a1c30ce0c1993bf097f9a9b5d04a92fbfe666e326b92ce22de4f11d3a87024c315e94e4c9aa404cd5e4d2ec1d2c7d95657ec50e15ecf10801329ab243f1dc95af92518fb4162656f1aaac8bc8bb8832a6755e29d7ff78fe1e4b93578fae62c4e6b2d896200f7523427f55d6305b3eeb5285a47db7c5e4f628d29d2ad39af473167625cd848efe6dc72e45d4b531b4a0af4dea4206a6087d7a494f7e7e27ea24b5650fe06aefd954da1cfb8691c10957ebfcff92a7683ea584b112bec9e0a67f831b305e72b7f3e58f790988e96ff9fdad1c6b2b5f5f03084fd7a7d6895f8e7bea32a344117dc9be191e89abcc8888b72f091c0a742af35be4af72a657e93df0b48bcd602e3a7141d962d692a3ee90b33a625b83945356b13ae531a5d43f30afa5901bf791f22650f3f2faba02817dbded8b9712b7641372d4af4ef2916b8cdc05bb5800c3289388e2fdbf07f2fdb95b154a2e1cc6998ece7a514bedbd489ee21cc1df314b4fbc452c1378bafafa083ef00842e2dd585668eef7b00e895f013edc2611ad882e76f9b85074be087bb9f8b45990d1a65053eb561a34c8cef2b61d017d50055ac478e82c6fc881e64cef53b0598b0e354c2042325d5a55fa7d592bf8bd8f01fdb18b391a069d3eacc373765859468700234138d0cbaa4cf64862ea30b66afc2ca9effebb733e007fdd6fdeb483d5d6e3523d32092fc0fbf94ffd7918529e192603a609ef632202c37f49e34ccacef9c1be4781dca2208097cdef7365025141ef427b789fa4da96a07d58c2a22e158de7b4394c38e17d98b1e363579560199088bf6bda0e799132ca391849ce59c0742282d20e2ad70df32d8484dccb5247322514f6ab1588723450f4245920c6551088f0a2d204b6806f054c185501b031b0d1885c33ca17ce9124edaca319c16aeb066295b66b86b70ea7762cf502a0b6d785f645a3283e2f9c97fcd54ec07ace7ca8ba0fefc013c201aa18a3c36ea8592984783e128b076d5b99a237cf99bd449d2b92eb66c1c2503ff190ec0eb172f6d6274008c5cef30b5b08a1b295d437b357fb2febc2bc7a480ce7b22fd7af4d2805d786f3502d743fec304d7ccd0c42d25a7062049cb778f4492ef4ad90a97ec1c2e14ad79248c325e297101e73d65960aa0085f688d41cfa95e31744e5e6483 +expected_shared_secret = ecb62b03f640ae4a9d89685fa0070efa93c24dfcff0d555142f9de25b62f861c + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = 80b3b92647a1dbec6bb883a4b2160e4dcc84c89c6adbd955cc055933d3238e325fa826acef899a555873a5b9c189117844202c65e40eaba07d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885660b1d3df32d1bd50cc50757c5227928b32e0c567872e66bcb58128b15c8696710a7b33bfda469128996f6979f896b93d22910383c90d0d877a56b4b7c77c53c99128719c2995497dd36877276a25fa8b74a4947e223215a314a075585da457daaf17c41711363950ef9013a8ad95f9e07635546485a3568aa502d608321061a6999057e705c46b6691183874fa9ea38bc392f718c99ddbba59a1865a135207a00058a408b6c61772ce777456c92b28a51ce823f7524a26639ac64aa49d6903cc2b2b5b60b59643bc950230362caba6abb5ba4f6964331b1f62099cf385be3f5b43c2b8402006bb3386f5a16354e45118f0b759c3363ab4069ec2c4c15cac4e07a24fab0c682548337d157e6ba213c7801dc5a0a7045a442b4939d611469746e9da665e2e910b51c56b77a035900b25490216c0bb53e04173b3bc454a7a17d77283ee278e7d30496301480c8c1af6b3e1dca213b174f968c8a45a3ba2044bddb1492bef2af610b4ed2481ae0823df53282ba7750fbc7a764db58e3789ccaea778083c27ed101e3c75be5486249f9818a08047f97447773c7dec3ba7c59aecb5778a09cb7f1182b2e0a01c182a1bd13ab7d72af97f96f564607a9a970b35a6adff275c35c22c2444ad6e997d821c065ea49080900e766c0079b7acae7bc7cb3b31301656fd39591e0bfec2c33f05a0dd633bba463781f1c519d902342bc12bd16c1ac8305ea9769e489073297784ee45f99b248670749c728385f601fc84c1ffb298bcc447537785226bb5de712b7bdd04a0ce39226919105f06ecf6bcddb0cb5ec3b5505b5a169b05480b2587ce4934d2b232a44a6683920a81a6038c59497c9b47faa62f4f2120b15c360616e6573bcc5a23a88887b50d1a7dbaa429bb00a9f87b63829b1b641922425016c979db571ba0f1a139267bb362c68f47689715cad6636402049c2b5c616c321cba6e43c1c1a48a0e141cf3a71c0099bd183a5c0e59bca9a2fb637c1b534cb6687493eac495acc7c5fcc4898a52e44094fb1b7014a15c88e11a9e7244ee53c2d5b16708c233ed37859268501630a296d63c094f563f0e559c59453abf05a93722aed5ac0c3cc6a0be7890f8c3191677c21f70c8153ced3e2bd96a4bfdce27f86b809d8ab04dfaa837fe030f420b845d23c78cc82a2d7c440897c91c3b726b4622445899de72bfa263b93c3cceaa8500b4b0c240046387b25bd98b5901aa670180a2a8b27de424f4d804a68dca2e044430d701b67e9b4af33c60fc54bb3a94a8b8604fa5882a401a5647b8dfbb20878e4b4094136bd4b5bc14288463c2e87f0cdf6d9497fdb5f42f26d2f9ca2e048a757a59b440c2c5642232e714d11fba959ab9ac52126bf689864ac98cbd1a633baa3ecf75c09c4c6878994cdcb3e882798ea02aeaf39915dcbcebfe2ba14e620f53b3d83ab58bbf99509033db99b0acbac29fb4674c95cb94982ac398c2771a8ab6da1ce9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = pass +expected_ciphertext = 06cbb7fcb9fd91bf6cbf7f1c8a47511fbe998d1e0c6c20ec92ba6c6d86e71a22e7233c44494ffaf7c9f1075222019d9a57dfd3f9754905a5ebdaae12d2e2b16b537eb00ab967016539ef46700d15ea21fccb92b17b7edc5c87e58ec518f167acb81ad4b96e4e4d51e605b3ae45fa0d6816c9c6f103bee9687ff098f1543fef241b80d1f6ba194fcb9f21ab1f5a90bf7053bafd8fef1104ec367de4525c6f60b01180b9166dfb66f192ded9707cf59c16761ec1970eac7b031821bab340f23758daeb9e36ee899ceed7cf2c42017f0f808743a6f7b97fa7bcdd5a35a72402da6eeb5d10e4a1ebc6eb5489c0bad8d529fcb47f4c6b4254ee64d31ebb149c975d5e14b7ef9ee3fc64bde6dc0019585e66f19a99ffd1db55bc58a3aa88ef7a575f2383f7e781f8b41d36bcea14d03fa9bb65a243dec37efb3fc19622340ab99a1183fd55eedd7c4d12762b7d5de711dc182b9281a5bb75cca2a5d179b2213fd7c940991a30b88297f0a9d307ad443363bf776599ea76bd25ffe9929cdf7a9e148f23e51ee1597e63493d54c4d9487cdb8f524b5004711af2276cfb8377cff0787c615d38536167b8431837492069b2667cc311d3c1be3381931e702822c04ae2041cd3a9e3a96527efc1f427d60aba9b4d0327537346bd853bc6e9486013ba744e922931490b841aa8bb1396f05a11bc1346c86164486add3be92c27b76f1e9edd2ca9150b1ebf682097341fdc85095dbaa32b7201af8b2672d7ac76c5d2eceb2b14eb911c48571a7fbdb6246300701122374e761a0ef1d6392498ff8bc3f82f77a555820e79d4d99e9954770f0259b54f01757bf9f19ea655b2baf3f4edde69613cfcc1cdc3c5997ffe893cb2c65fc70319579495c071ee08b18bffb1066b3202bf75313e45894f328a56a33299f3b9bdd413cf5d8e7c299ee920ea2b26d5e0d44f994f76ed0554ac767427d73ad1604236634a1d294b1f246c544a2aca45b0c35a7cf2f8b66390f1ceef3209f0562c39a5f340c85eb267ca91f2a8786d0bdad4968faf8165c10e2cd52f8455fb7d118dc1f75517a7ee655ef7069840b8ae9a03b788bee0ea758cbad93806896028dd050e6f1a7e62871e7f4b69e5beea271682dd667f01106dfe97a423a4ddbe0efa184985c25a20fafaa0cdecf4c940c43d4b53a10508e13cd703258ae06072a88a4ec02913b6f3bf7a66fd7f207dcb8ba2d988a547fc3d1d267746d0ff35c4975c3814e53041d2937a2a19ca7a639792c132a64b035bc6273223bbffa5cc5b65878f47ab6b56943a2a2ef39918b2874594f803dd5f4cb5228b41ac59ff34dd50890d0e99f24891d4fc04a6f30a4311f958fa8740010f74258e87727f855a4cc466f5d12aeae18a9073071e0c4be2fc0cd130431fd753630de8d347f6949b79c046c0b90e4e636656978f3e5852bbf6044d9964747de482b448dafd3f7b8e169cbd1a56eb7a803e1bf06dc11bf65a0adef9eb33eb2aef852ffbf03afb82459abd087a9f260d776de5f735a311318f41c5273481 +expected_shared_secret = 6cc30699701927e07b559d708f93126ed70af254cf37e9056ec9a8d72bfbfc79 + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = 03a20a0337040adab8bd449e0beaa93b07512485ba33f291af1a44540bd04af4a3dd2a09f6454d7304d0944674a580551061ba5f88217aa57c10640dc1a97396f138c1a32cf40b0bd9286f88c4087f9084a9012d248c63efec072d77ab0e736719a23a913b7b8b62aaa5bb40be97cbbc1c29edb283c776aeb9b032e2c2691aec9ce89617b84b09712b40e2b713e566c714e0baa75957d6ba5062ba76471357252b72ac66ba97e10921ca2313a232a6ba908dea13645b5617938381fbcd748a11f61cbcb615c458d056f0d55a449c4f544c6673322ef106010cf139d1c586aed5a5dc210fff7a60f3138c34a4244398b692c567ade5beb55c1edcfcbd93183e1ed0c2aff5bdab67b51e39a58bdb8388d67cc1ec0d7313b7ec8a56cf3c9b73214c4ada14592794749b6834e9b81a2ba47de929e9ac7856b56549f40f38f0784ba0cdfc195952d3155222bceaba0e3c233ff7e19a65822437217a42721f9c060ac2cbb9c4e6bfa9fc3014d8add7b4bdf78291423511f9874a07e06a82b6369fe349e08333c7f56b7b7b808a0b4e888a95799a2df4873944cc43eb958b1508c66e571268e79a69178793e7a4d430507e1259d01c86f999c16772cfb7b4b330114ff55a51ee5407bce95a6d27875a91773420c24f8734b3023e9db777819ca2163c431de46f22f38398d46ee352b815b6b07e1a242b01a4230b59ea8c7b0c3c3dbe2b7c77b4c860660daa04c452e391c710722c67bc0632c072fc1e5296a2e70932d4d38efbb96bd636bb41260a7bf27cf5e71ce3708e6884cf0b8584adc3cd3b5c5ee1003a13731704472a203c8f9b49534309bf2b60cc3e2448e02b5a46d889ffd78fbe722a709a2d5b5c8a7d805bcff44052c553cb990ad016079bd87db7573eb1d431d1e549edc8ab56a0bf52999f32555e8ef2b03182bd8d812cca638055a73b548c8b432a2a7d4a6a074aa212d50362d1382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1edd04f8f8cb7af4c947af224dfe0af6a42c7b65120b9c18abe9161d88cc5c4780fd74403cd177f7160281884a11cf686f0f523f39cb7ad39b780f13a8ee83c0d646f9d85babeb306d53a7df53ab00b5a1aa8c215914a48222940fee10d1939ba5c93617690cae113a59de071c969436b3771fc50b2f4aa641a4c852922380a420fcdfccb81816f4b474a2ab293a4d97b2b280cef031148ea7e4c9c0db7e7cd0e50b203a6b7519c3cbc8062c9b60b8b81cd956463b8180c67f34be4868e3ba94b9f0226d9f010d9ec5ef0bb62c865c807184b96526d94170af9474bbc100530f7c77e46b98c2aa41f92a48d8027c855c7f84684389bcc8e7c67164a204bc5c0c90828faa439fba235b6f20785cc8ef4c090a708bfbbe26e1933886cc96ad9b4562a119d4c66589c85bf0e55606886206734142d432c1b032e0aa93ee3731f069a8cc069a03b95a8ab873b447a04ead3a32be3054af834882bcc581712be18539b805577e50ff5d982c98c0b0dfccc96a4c6429281068c8429997dc17a6600f0736b8453e3d77636faa8d0ca89f9193bb34819ca1117ea368ea23198ee11345c613993ec052992954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = pass +expected_ciphertext = 3a00a38b5cf0894322b8f5c5b35dd486f4e4cd14b18cb3a101345718ff843b13fab8ae89af0bdb731cfbe6c5bca36200e5ac90b9faf0c7296b6ce324513504bc1ab4ebb91e77e9736743722cec11ed929a2d536c25855e7c28d1a6ae521eb9b6391647073c55ed0fab85084ffbb47552721bb6827a0dbc65bff589165f25610ade382367ac20c48dc380bf89c459d98cd5bb01da5899431e29b938262c29e68898602dafbcb9465d0f166986e19d51c00c94131d3a5c0abd1ffbf793d6e9a52e5e11d72233565cade9c20a8810e55f4d2fa80072db2c1ddfd98681e693730b693c3ad8d01230e45aa8822d191a8bdf90cc62829dcd40e75f568b8f562aa61a6a9c6a7d1be451ad6bfa404216c102b4d6aeb4599951b0b96cd81e2a03d825380a96a831b321c6f14ea5af818d008d6d80f28b93f2e3bbe22195d4ab020abd3af6b545473250720bc992ee57ed9f328f0cc1988033728fc2a28dcbefebd698215b3a91a05ea5270cc8bf8b0a1ceca7e9bc13bfd8359892c795aa6360e1fe6d8a2965356cd5ea7f4f8740a2e9073126d0c41f07fad51c74cad707c9f83140a2370fcabe3e9f48673d9f1d007b41c647ac0d195f279696ff29ba14b6841213b7218d769be8f684803bb1d29aa6df3a0d6e52f29b19063a81f1446e54fd8f1a6887b0132da286053836c0cbe97bc36c8770198e203908d3496c43941b35257dd86fd1a9c5f5177b1f75a426b00ba9162e1630779c6aa4dd421b4abffdebf19472a3c3e27d270d30d17812c49dcf3c5b49109800625eb8454098e1f994bbb193c2f6260caa9ea62cc2eae8bf26255b7f3b1a2fa57231f00a7cd97387d5348d68737e167f7f22f6f4438b911a040e142fbf2d9228480d83a474d54018d92635bf2c14ebe728bf901689f35462801aad5545cb411fdac9dd55354e7896c92cb9eac3aa0b88fd6e2b82f8c93281d5fcd7a490a537efe83e9f3b8ddcc8f8a83a081354f0e9939f77f8368fd6f8aaa98c7019ac6c2b74a59067d4ec0b5c9bb1d7f0bc6b6e06b05d2332284eb5f24cc35e14af83d6633020df2e74c124bfefabc42338b4acec89031cbbe5c1ed3f2d464b77b4c479e37dc0f5d5d4497e1b97dd00aad4fcc47013791b2ba6f098bd751b66b51971fd886c03cd6a45addf8ba4af20679c498ef3b92f793d1f6a7a460a665c65b58796f57f1d8da4c127a2cba6af842125ee6f9c10a1cd9c9f06cdbe63ec6ed979b6be2048db2f83e4cd16a80e3ec5908f8090218e2e9f97b60707337dfa770d3ad27076d9c0b0c7aa1eb8e220392e3683cd19519660a17661d2eb92621f59a75a8c2e008119465793477e055c14765262b33347245b96dc1347792ed7271c5d20f73def4056f96100a80fcb89f69c451da786f045fb2556a2b3d84aabec88dcf99d2016c3697cffcb7f8f452c654375d1eb30bfd9a7941c6cfb1193f1d371ab335966aae0c14b68fbe23f6a12f5160d786577b2ffa3af2dbe46fea002bca529419faac0a3c9da0b2c161beaa83422fa6e875f63 +expected_shared_secret = 250e7f67bb34dd5477471e3a701fb71a8138a1920eb807824380f88a944a6fa3 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = 611ba36d3a65c0d17cb22b7f3a682b593595b1c682d521a16dd621a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf101bec273bca5d606a5e76fdc183175a233c93373e956580a522badd22d97d71199c1a7b4149e652686eda541e69187a2abb68f89ae9492443547cfde7b5d609b4835911d154c33e49248c4cbb244acbf03e93e52e71ed87a75cbc43c3f505422c1ac31c014e82009d4b13bf2cb7dab16896a320fe6c0476f37767ccccd80850dc94b410b983fbbcb484dd09b44a817fd95686106c710d983cd2bbc11dc4ae59091a401a6941bc704142c792c407f7524ede1a71a726e2f921b0626768307c31dab514a783febd67b50e93479d2c7d1787142f591607b7a5626a718d502b37a6f5b8766e8175c6ef276934a12ac1107aa3362840513d3f5c02042ae681181dcab30f6810389db07c3fa1790345e786031e3196bcc01c22bd064b2f9c439d7b7a7b7633232aaa4d88e0288cdb791049b8a8c64883637098def7c88fbcb974554af0f3c51c70a758176215871227869766452871602093d6949e1d078691537d9d7030b36926147aff8151cfba202c0364795122d1d748a18289cdb33982900b38ef9aaa5d10d146985c757ce5cf82ae0a2489e0c00c83550d455a03fc885dc7a5ebcd71529ecb0ca13ce1259186f9b0ceb4b90789aca0762c8bee063780801ce365540f440b0aa0128103ae0f5b4a5d9b98ff3aec5793e8fd046a7e15b517c5c4164105e87c593db19b85792b6c705e615c4d95c38bc4bab4f30737a20241a3189eb38865c6b60f6341dfb931626e729ce39313e122687862bced934ccf88411730fd066be831542abc5b15a1cb2d3f0aeace904cb419754d9a5cfa35d72e570c8d3b0bde5a5b18201f14cca3e3564c16769757a2daa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436bd21282d6a3242417b36211c84b75f388151f087186cfc01e59383e8218039db15da50120aa1c5489743bc42335a774f8494a4244acb6677b22a46224df7bdd8a9292ae58e07f3068cd975abb51e44631172535e52c910b48748a190c50d877903a4c7b9f4b18993669d254ef566058528a157428111d43d360ab54343adebc2a3636720f1e0c8ccfcb0fc3b71b55353c2682946408cad171fb711cf0b3ab561ba6722647acee4b8daf0aee2c43352609dc617549841adac54adfd3319efc715dd917ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a551230a335510f55733ca4f3a6329aa0830894e06a05ee578c45b3117fd07d62718a9842ced5f49710f7b15741ba5b06298c550b96bc6fdb0561926240faf09012e2cb49c66868e27ea318aaac50bf882c5bb8e674381a96645b7a7dfa936201933c31955e24912e436528027b39f74a909aa5ef4653cc23c5e448be6f81088fd322fbb1779be52ad60005c2f57241932ea3b435c47a39e6e0477b989c00bd5ea71ba671d8a37dc64d36216ccebb14e6dc7420c362926b555598b92f6a78061423a4cc8961d57733982fb8c78573c35584185fed801ea674a7fda06008517b42d1a45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = pass +expected_ciphertext = bc05257f294ebb1d9f523ee049a3a6730e4cc5b52e9760cc5d47e7401dd902179a830fc9261554103aed30dba87790961d9524952048d442623264dfeb2e4a4a1da9894a07d994b9054d664efba14181c35da270672e2a96b6c912eed8c5bb9487ee426399cbae893fe08ae6000a4ecddbeaba0187af28aa9f30f11e46e2e622de5f5fbf89e4c84a10c94724cf0810334fb4a9c609619295cdff0a7079a55d7231c05cd13b9fbc381d1b33a3f9170a4aef32889beffb76d91c3f9a3ecabe60430006aff1c59e6781c816fbb4a8338f4af1a1a9a719497b54bd7b753611ce0da6177850f0762d189312670c6028f3af43b6c8d9f9297c636c8e4e6cc926569c81f93e2c1b7844eb83420070b57b5df5357adbde5d794fc5d1c2c6c411b563450dc843a1139a405d16908c277db81f202cf53b2bf3a6231121e7d8445b6d45d7b258ef24483e34bbcda7c2670ff02e23b6a7a6fef8625fc83bdc56baaf2dd7987f37e565dea443b2c2e25363f74009a730f8f986d021af214692a702b38cb56d048a1a5ce2157cb932c9d8a4663c33b500485f7f3147eb9c50a49bc8c3d7eb5dad6cf206e275921ea4fb4e3e7b00abf9eda1c9c2b93f439e979a7b0331bb5cda584e59551564ca3bf065ae9097d0327220d265e6ace108258fc09ea5e0380e5c97114ed4fa4760220568209cf52a79f0aaa1efcab10e58b047d44c2cdd74921aa81ed53d6c98a341bbd0834b19628826691d6aeff3df36f123dbce39a84045011a7d9493911cdf171a63cbd7ef21a6fc206abaf9ea46d491d94e12e88220dc27891d1e4a728538f3c930807ddd5292ae905e22b395cdccaa6431ad6f3b44e299aeb2772db97de93963eacb47d24f09791380d98165ea0e38d579f1b5f6249686a0c1610dfe223ee389c09a7c4ecd67bfbde3348b4c27d7087cae132f88b1ac82d31e1c41c4418b6354b57e2c37cfe8e60218730beb2154437b66db7531b16bbe4b4b6a1c8cd1650c732f872c8cfc6761480da34dfdb6f538bc28f91962bc52447b2898815a8f79bdab2ff82ffee5073e3c90d90960d9b0b6c389969decb7a41686cdbf12005c0e96f3a096175425130b485c94424896ef25a9d7e00bfea40f0e2facfabe7355937901af2fb8da23b69eb2249de3e6bb98b84b3c11f65b2889a01073e75b20b7077df34c4a3da9461ad036c41a926f4c18db0989ae4963ad31c59aa2c14d177bf94a12f73d5b6d61c9a21702fad90a2f7f519f502585e3fec795463eade03bfdfab04f17f3b8dea98e713f91e21f3284a6521d3c051b2388c6c5683f5bbecbb1575db97be5f24418fba1e4d30a3b3ed014fdf028c3b8d80a91274995c21bba4cc272d31466d54fd6ef2a593c5aa5511fb95b02c3aa932aea4bc5341d90ffbed8f7fd8f94c2a511abddb4e2498caa887512d6662ac02fe6fc0a01df4377c05baf88a74cfeb50fd3bc6403a6dca1d794043ca59584bd6c5177731beacd58ffb2f0b6177d0ec260f2df873b594500bba6b7888c772a61326bd69a5574 +expected_shared_secret = 0210935a18f1add5ebc2e1107bf40a628ef9cf8f6e7cdac81dc0291bb50a5a3f + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = db0a138c9442fd3a7580e68eec01077d31525465babef901806363a2d664ef8c1908a30491e336e27b0f8690ac71c30adb145805a15fc654ab8982565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a20e224e4361977b71c694a88e5252f608cac97e97dd7c80a5ad10d62681b57162269f7b8d812af039226ce2a7930e43007c0b3ec6a4cdb3897ee85796d051cb053881e1b9706a572ccc75d0ef32f92610c40db4553824f1a352fefd979a310124b9456a9106367ec6a50db6fe0b057fdbb00a46028c0d6a638bb7f2139ca6df68f014c4e1e0b79670869353912b5d67edd4b77c70c067aa76d174cced6c7a901c65737082276188cffe28bcfaa2604447e68d490c0f11cd22b8c351c2d63e7a01ee460bc408e174bc4a6cb023492c6eed42f5d85244ec883b1b49b8e3584f27835f21b6b2e6060e0671f289771d124168e196edacc1aba26cec9e09fe7367f46893c2ea3677caa3005e34e722608a3b64a3b987289952dd695a82de89b9034390355c5e33546eb833f602cb9324c095bb4cf66c05fa0ab98d69bbdcff155c3169f3df2a575901724b678fb080b67f32240ab8f0198cb43176f6ffc93fa602748d591f0b2acb9aa67a8d8b15c27140c320b0ee040e737077a8c9fd6a20dcb865ff51c41808757b0ca750c502a356b1c7d821f1bf804ae2b337819c5ea89542e079045c887ba6550e4f05693f5c7012424d37a17e2294669c0538ce69a1f1c1f121784e3c3537424bbc4d73cf1a685f03a24c4ba8fd603b328d2a07fa2b714dc1eed17693727732ec7be2b02c0614caf3d42b222061ddcd758a0674133e6cfc5362f855b717695acdb971aaf16320690606c1c42238856d757b5d610bd64427f04c97abe1bc6b0185116cbbb2dca28b5d7a9aee205dbd37e92bb36311c8936d958aa1744ca67332a600d8c719377273c7fb0029f27c75817746e1058dd196de71b0e4302682da21b4ec1beca3cbdf690509573959d816cf5fa034ce01d6a4ac477e3bfea75732678aea6c0a5401c623dc225c7a9a7ae6a572f738387181913cc71b9379a5a2bbdc45773c6a1167fe756e13731f47226bc678331312b99428b07b2122b2b9dc86b01c5f090ff632fa83b598863c0b42623549ca831f66bdbbbb1d4747d56a97dcef9c81766a3d90043c1a99ce5e81105e9113043342a539de446a7c5f9c4b46a8cadec388fbb8bca527d90a56c649200cb2a7f968611934014f9a7b6faf3015bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e35771947172118eaa02cd95f7137c93e2159d9389607c3011a76363560a97df950b0329258b0126c7bc10e4081ce46b7c7b0af0752b038386e9afa2d0a7543d85ab909376b618c0a2d33875d264b76941430e81c48832f43270160176ed5938492a06cc08392237caa8487abd3c83019000bb6671784109c7bc4c2a0362a5b5122e620aba511c49ca42d75091b3b1abaad9b8162bc27f182ae310872e789cf05f6c949598c41c3b73a1a9cc0808e68f95c8ad8392f021f77c79618685db2fb1d04a9a8acb8441ccc764aa3b191736f5a24ae31c23428390c1c22c6a6052664db63b94960a433584036c05e031a07823a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = pass +expected_ciphertext = ed678ef3105bcfc14050898f388a2daa0d61c5ab310fedc2107297881a1097f329c679ccd9d1cebbe957c137acacb33cb7ee31c9f5c148ac51e57caead59178132f69a7020a8419f4f833bfe4b8718691b26b771ac6e858551aabed2b9ea3c904a8c2723f5fb8b87d519f4a93dc43cba81c39063f732ba91116f359721ff3b6fcae87c5965bb728f4442f35dfb3f2078106078aff64f51cad6c62a5c8b056a5e6fe7e08046f097ebb1311603f7b719d93b53a1efbad985dd5bd5d2375d118f81347104593e6a05118836beb278a62d5479c7bd62e90b2aad04f7c6c0a4b5b410568b9033e72f1cd6c71c53717faaffc9fb72e27a3f00661f2b65a4e0845c2e7aaa391fc1ba253e6ac33abca8a2839eaa0be8e350101af3cfc7363424626ef571c6db515cb8a8ee209aded9f56a5bdc3dfbdb9d4f1a94b73698838550d4e348e5826a8f632d556385d3135ae872580986b43a5d77fe471db736328931dae7f9554604ffa969d5d2e7802130afd2bc5e05b3f3947483fc8ebc680176d792b0fce9f7d121ca199011efd51343a9f68cc40cf3c019338cb6e1b46f3ca920344d1207be283329945c1729704d3baf1953440474be9aadac1f705cb5ee8c41ca4f29645fe9b5044897952899d18ce25b841383ee086ba8ceaf712dc69d23e564e35a3cca5309cae57826907403065e943f255bbcccb64f39a54c18ab26a8164ef5d9d07f6522e7cbb50a2b80040bbadf0799ae1b55abfffd5d2a74c9c94b43eab75f55c2b438475bf4a4f0a123ce8e91e94b6ca6106b39ca34430efd34fa0a741cf93e0286642d45e78d8fb26af2ea594152a87d1737f54238c7a8cdaf174ce7e9e13aa207b627ebb4a92598d184bdc62a643934e114b356b4591ea5415fe42a9f47332d559b9f748752c46e4c8e1196a9d16df310ff2824afbe1abf520ee7c6a8ad7a833e01e1ac3fb0784cc85f3d731b40a12c667e6a0f3ad83505080aeed9309fd7492eccc9a81fc5f047c47c624941a0ba626563813f74eeb0a8a558fa968f809deda218f6a73b821f30700307b3aa52122c81ab3d48e4eab8e1bf8ce95f9d77014b5edbbfd21152305d427abc30c19ef3bd6e206eb128d245ef3f0132008957577081e1863ac3ca83232ec8e3a9d95546948c9fad4275e0a1863d5fa2a54fc42d0846dab4a0d74bd55fe5071c6c514b0f0fb69a8f27347013b87fb48d00a670b6fd28e8c844ebbd6cc93c527b5e0da483b3625e754b5f39257c9a167e5b381bd60f3cdfd5cf0d65fe96e02340922e10c488f35df7fa4ba9296f1e576aec3e425cbf92d648f6095726ac3ee8a6d812fe9ee629413f78978e200fe3eb1816fdd1eda1845382a1bec1ac57b23b79189ee7f67f9ab45731d2a2ee4f208025f0f0530294bc2e38868118bf2464fce482113463325223ef8395f945e0002d395c0e9695c9b8a0ca20fbd1f3b66327b69e6579a1ddb49f50daf499031b090dc2f8486e65d8e715dca3b5ee26a1cb3fba97d4df8e3f283c28a4e2abbfa3ae5ba78b6b5d8c +expected_shared_secret = 34169fc520e944f94ff1fa3799db802a4c1b26cb2971bf196259a937ab8362ca + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = 35a0c8ea287462d8cf8841cdc9016796500e61e89eff672e87c667f453c8ccd148b94c9a9a3765649ccc6e1c05e5350218d091783b6c7e4958a0807e73e9839992c8c36a87891b7ce5d7122e38b5cdd745feb1058fc2827b882df77cb564323746855392247b054527ee862abc91a557c431e55b81d23b1c1a94992ef540e07338fa944d24b17ed4e693eeb8224a0c5307202457c8033aa4651b2b30f85a9bd8070d1b11675fe240a1009dacfab21d50036426a6dc9c3dfc05cd1612ba91da51bd5a0f7ef9b235f1b3b2641747ab8a380b42c060357bf259548cb80788cb41da4c7d3c4b9401925588920df255167240f6b092c1329799f0039b74cbd549b2c053a71d4641071a3a95a460b2b3a8ada727193267de555e6ce87986ac06e647c4b7967cdbe5083c4b99a1b44b5df58959c48beaba0818608fd4046ea0c09a28416c6a97a1066c0650ca619d14a056252d38539f1c2676b69cc53502487389648fe596783baad0d7627cc6ab2da5b6788410b67285841a323e04d037f25e103b38b07672248186c969b04661ac6b2753c5429eeda389599b78e84608dea89556a9510627b29e13b1713a1442158561db8f435bbd6234a420618985dc4f71f0a5f15762fa16084f178e0e76bfc9ec5c35fb52e52301e6809cbb287d42b7591828afe605cfcc93c337bab78b55237b075a8bf08c48c15087e82600655234fa99f6987da7904ef50a1599867d56760ae1d70006925ade67157508289f137def9b9714f4cb72a017ee6a6325f9418f3a0ea3a8762c55987ab406dd9a6d248a33eaf264774aaff6f00607f37bc20041d3a170e07407792a43c5407fb3622ccb065b74bc1a54f86af9f7246d288fee725a6fd85e82477483f778d5388728c4565467a9ba3216d92089bc1c742a20b03bb526b73573cdc91aa8e085f1eccd1866280e791bd1e43d4843a440e050e2967daae26686cc2d32f512332cac82095ab0005133023e75c9c92b0388bc8b2822a82f93fc3520972e2e0a062a388931092bfa8758f251895c641186d1b40f6a332df3088bb24381da133ce40d3461a7d87a93e702472e49ad91cc013c936b02a96c4ce14c2b23ac79869c6d139c8d85b58da27c6eb4c4250bc3ddaa56dbbbbffaf452c09074e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779db92453f7aaa4e58401cbc6f3718a3352013e1383b4222572118878c99289b91b02d929dba06c6deb6f4c2b0459f86d04fc8d287b6a676b17e45997027568bf7bcca05c3d394c1557873711174242ca50cfa30bb3d715d1400807cc5ff1049ce720be3c360febccb61dd7244f4352b655a517485ab13b413983cc089749ac7144312966b2c67ad50096bc176142858881f09e3a075f8fa6bf638a13af572ba026a172b23317a01a999c8c1ef478422cbfa9802f98f2856bd6a11f8584c532807771c19c411a2900c5a57c9b8e44b4c07b3be3477baa738ab2c407653a309d7a82cfc6b86a1b59ad1251e008598e453e04e3306c1877dc703869da25a9b91fec80aaf4f30b4d0a83e2daaac73990f05a9002d6ada0409450454291e37112a9ad97147cc89999dc89a30c809757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = pass +expected_ciphertext = ac958722deca4336b0f60c62e7c9e13fcd4b006cb719e07b26fce400e3467d481cfffbf51699fa8dd5706cc65dc69d8ec2c04229c636a94d6a0dd59bc81e90b7538bc0622489f18d445cf2a7082c5062f4534e0a156b4b77095af6ee36d2599ed7a961b0288f40a52a769b5ff92a7bc835cebf20b0aa61a33379b669be2efa997942b71204a97391df9461b2ffa7f58c85f437effcc82220484b1d352f17ff76ab8516411558fa3e3386a79726ada7c29e8195fb41d480b2ead4d48faf6949aeb157ce17f6524f1c0468defe260f6b5f634b265428574e259b546cd48050f2e8144033f686bc08d202563d55833c217bb649d50e68ebbe5084a1752cf479a24332f6b87229ba8f38a3f75668f7478cfcfc4de61e65495b22e746ed7cc8ca5ef1af1b3aad68dc224d8c458eff394747e235c191780c8c405bbfd7ada024558b04e93afc1b09ce5e97474aca4053be829cbf7668c660fafe8296e7f0c625741e5cd0ece5c23aa4e5183559cc09616dadd9fe4a471158d27d54bdce7b95c6374d88353e8f09907b6d910d228598f77faf7d14eb4faf5cfb1aa6cba24062878f06d2c8bf4f57673547abbda6266f26d6893ea8d9f09c5adc8918eeced2aa88c93a6039d53adc5b5722c2bc4bccadfd2768acee766d400c200babf7330e17be15023522123bddebb445274caaf1bde7ea23e2918f9b520a3173d7e060791126668a997c29241af3e531ba30e1c26e7611b32a346f733de31d26c7971beeb6d8a9725c282b2b07947e4a6899de0d7cc703bca6cd09c2f6d24922ef78592106d1dd0fb8ed29173f6d79e82df387526ceb9f0292b8fec498757d1680a1784df0c22fc05f409a908816bb060b7fdd6cc95b180fc3dddd50405c4deb8af5c68e166c841710610ca126b2469f964c8d19b3b0e9d54aebd19553e9c791c0e50b90e9c676e8bbd1cf0571810d6ff0134bb77b451bca63b37325e4574e67b553d834b537c4dc371a69352822844fc8e68786f73826fd3e38b8735966b96caebff7a67b5053f7e18f3fc0133317c6f3f88c0bafee7b1ea9dfb9733c8834f401171cd8837d7466a9114f58dbe278b6882050730eb0a979919a267779cdb35eeb4c2e4d1187c0e0c96f63a067bec7c8a91db1342b95386e062af1e43e619a04c040fa30f40d2ea3123ca5ffcbc00b353e8df0486df38da624cee432284b18d22c6051da022255d16fd85736cdc5a1c635279f28f2348d5ea50c22f5ad445e3e025ea208dfd9be4c42953a578e238150253364530c51fbeb90b9e83d0c0bfc59ba37ade7f001272eaf84e88b82bfe939d43830fe7f6cab1309392352fe2a91d05ab5a93b3b530e1bac3dc3fdd3157dcef43983cbe0a5b4a6f0dae4912126bbe5d4c62fb9ca542a25c2bf463d519ee01642425b0c93893a9adb034ec67149d8d3e91dcd643758094449e1cb3675760cef095c91b52202748ad12bcdd4de0565cb0d214d0f2cf40cf9cdd21ad6eb0ccad52cd6eba41e72fb3ac7b401cadb08fc6a6de0b1ba1f02eba76c +expected_shared_secret = b5901e97eb656a09d2dd132528148ad07a0a89f638717eb53516a9ad19aa36bf + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = e4749bcd8577d50a102352b869402efde59f5fb54bbee919e7d4a8bb8cc40fb8c7240401113152ba727cecfc8e4b817c5d537df050902bd03df866317006a2aef59cac269813a47fd337a0c5b694f4b080f100089255614634a2b0bb1ecbcc3f1d84cdfb3054fa749736e531c2e673716079cf45c89b444b7d821d892c7ec39a74d39b815c2b9981ca47f5e56840341ff9d23fc877285f9b90fc78bea1b9c5c647ac52d066ad7b8ca2aa01e0729fa22c39d9c3c6cd833c6aac061aab1c1ee6819d2a245997b8580a9e1630112cc6b62c4952215a3281111675f25a10ca0c32bc68c7bc920bfbc7bcd82edfe130b0434afa29b2b9d90ac3f1143b5664e5e51984b52d976439794507d92cb256a1520078972b843ff3dbc6736602f68b289e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a45a1a62e0b749ee14a38e11a094bae60a38c84079d81aa655782138671a0fa186a727457d351a8a45b6fe05369f7b158de844e31117ddc47af9fe52075c6acd5f93a31c38ec7f608ff9096c8562e0271a35fa7265a56b24bf31c6a727376d1ab3f600573342e60884f41d355b2336e464b94554b7c108614c3394fbd561a2e74ba7045c0d74032877901e4f8a95c41ce9fc72013c51fa93b5c0b3c3b0a8c90ce0960f510a9f6a453b8b0012f7c2430350b8a4b6143ab5adc7aaa6f3533e230c3062b7caa33b1e9a3bfda7bbffef8341ad0a33ab272bada717a4790f4c99cf430bf114b62854810eab7af582a2ea327a599c490e25795cc5c42219771391b33df4c7fc01524c4c520eb4559c2ea8c38ab5cfe27035c756248662c1e969ef478a2d2419ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2941b89b803ed1c7d8de65f64a29d8e7bc2020b723d391987f83db0bc35e96aae7b2772b37159a3257ead277532119cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352cba074bc4714deb09f9cd81624d2782de91efbc30882c45631e96e35c9b53f77cc0d268722ba5eb858a1de719a88ec240da229cd7766b9a237641c1277c006a6672bf61ab5dab4c223b7381fd3c16704cf7920b2f11210c969b6b46a152b72598de4aac1665d72a45bf51370de61559f83081dcb6aa49339e489968c80498550afc467c8aaf0c6c1b9085699b801c75eacc3142be38de6f6a64ad6708c426eacc13b09d8bea819bdc200258d31a8d1f308d0a7470dd35161379191576a03b81d70ec58565ca7c4a6bb333338d8113d70f5bef45b6835917e17c2945a06cbb7f2225675252f351593b06a6db504b6e67c6e88763fb06879187c5053029724b3477281cc5c5294b36b64f12a08084eea098489d5cad338a0cfa61231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b130a103c6244a17870b75023e0014e6d8433ae5cd2b145bfe253a8bba300b6465fce277e2fabe36d6c8112887cb0a6daea4a54e258cf89071e407594de1bf1f4aa2beb50263dc5d5fc729b632957375b5ce6373d9b93211a66a29736a6ed616ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a1f4022e6c3bb3d2294c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = pass +expected_ciphertext = bef2266443f466793113b5d0fc7413bf46e39fdfb568b88550b25cbe578868d6074a6b2de2dc03b8ce8a7a390cbb67c46c500c7e6a044391db3af04e95c88f2acc12c63613b2a139a4551e9189b118ef4f04de5da17fdff8338483df67b9f683ef87a2ec36185a33bca3147fae6f6121cfe41ad623f9f15676bd40fd7a2802568e9609ca00bcdf1d59c6595ca1b67db3a3bdffdedc7dee22eb33bf9e444c9f115ef088a32fe4c800bd57fc854ba31c53979d48a8071f8f8b83049dff41f729ec4bdd5423fdc088592b7bf04206b920cfc96aa4721a55235520237e1c7cf15e7905d864e6a040f8625a55330a2dda784554891d35862811969c77ae7260f776f1a768606117fc922d936a058151850df0aa94a05a9ef0ba817533073f831b03097ba43b2a3433eaab922a1020cf60b5e02994ab56d8b1c746fcb7f699c42254f3161cd53388b50c9c089a73f30ce34c2ee1168e8acd73c3665c89205c7b1caccb8baf5d94ec9451a6ed00cdff4515fbb8b3cbc0fdfc0d2e249eea42ace1990e519198306dc8c040e6b8822af99755825d2ae48ea94dc5304e7646863a7af04d393a35305f15de1c38e4ab78c061d0006e85074af2e8a7cf53a3ad7f631de6d49c84124271b3a29e32e40ce001e2d21d26cadb65d825a126281a157551c87f712d32e754b5d8cc66f3c0d719ad0c0fa3afec198c8a89d2459d304d4b8fe164008a9432fc62e21199f7a3f648f1d990a55f1ad253995cc848f6e5e7e320c221e33a31e8517aa35a6001f75a75b1e3721aa912ac92e4a4d0c5c847ebdb834bd6ba30addb70c613d4ce7e83e3a17e5273441eccdfb05f9f205d697e0e3c4aba2070fff99e2496fa5e9548767f6b3920eb3f6825c194cb6d720caa133bf75d98bb858bab11d4e1dcf57e251aa4fb82bffc1629acffdf25010ab54a6226c88b2582ad8f6adafdb62723b0d173377e5f7bb894ad70b26a2c22fe0b940805f1b5160aea7a8396729e1428446308e3ca349207d6354e2197b6edb19496146cd71edd1564e07afb401888c22aff7ddc721d276819cd908915e0d7797b20bc7d8e2e63c9fc3d899158a0862df09e506e437bf194807544b3ed75813ae767538beb5f2bb1f25abb08e9b446d8ac4e965d759f033cb68980121660e2c9de083caa42f8543ae4da5dd31a1c1eb9d460b5175f5b913a0cdc99e81c696ea831cf6e87066f479950c852a240f716462773205e5ebbe5b769f844d36729ad0996a40f69ae558da55b9792c328403170f2b917b65a971d0ece55be01f857d67ed4a8ef59ad83f7ebcf3163770bab4f583b32e8213b000b65d5a7c2f276430c4b23cc33d9877a72bd2d755a131ecbbf88d489fa75b36159c17a9f1d61f109048a48507dcce311875a52920010712c6af5a181051de669c4bdfbd370590218f597e9e39afd39adeb31850733df8928d7daf5a6e2f3ce694854d340557647f4b8fc0f6cf633396f2ec7e03bb74b1f8f3615a78555dfd3a35d540151d4ed385967890818f997d8ac26a4c29f +expected_shared_secret = df5117706beedfb521f0f021069fe9650d0844194339033de6997dced05268c8 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = e26411e0cb6648d36c6236468793848aa4b7f4510377e0a24bdccb712bc98cb21ceabc08101328d3d032cfe9c82d21372924c69ab5a402e9b3d88c87e9bc5c90335e5ac231a1b87ea3c2527b82445d7c8596b10a609616e4da431c9593b91a1aa21a2e436a359a7a5901902a6b516d562363bf95890501af4c5946626ace3f276af8966709cbb9b666b9842102f3077978e4872307ac65ea11002cbe4dd0bb83677419b89c9e0c9847fa6441c86b8b601663e40357831d1b3c21b4a8985ed50e546c2917f332d4acb59bd64d9be88efb981362458b8d868da7ec516ea9c807a29c5d51385781302072c1f3295da2559003d4265cb330f43ac5b774562c182be83636fa034bdbc3cb25ab6c8c21c69b873329321533a788287a40c1659f457c5e6e15456da54a7fdb18c8ba246447606f2aa340a48b4fc667d7e67efec47910e05c3da4463b75359668821711530835357b6a8ec62a3e7817c508c79754063f7110362be73416a46533341cde577c17a75b3316ac59575eb1a1575ec0104ee77f70941e91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797ef827f0bb0821ea69bd9c43abf2181d0775fb64b8694c74f0323600fd3e5f1bc5cbdacdb2329928247e4759747c02cdd924cf1c93bae5c37be8c3b9c7e09b4660c3b9901ee33b62350a695d799b52743d5158c015cc609e891c87f9ba02616ed2d3a1c14aabef101b4b42ad5c47916481bef01b11b9496819ab76a428c0f5b8a69ebb24fb5b3407e1c22e2020341575c7098e63379406c9b60b6a1733c171682b1776719db5acbd2ac6ac4b97aa0a3c8c168a5ab389010a01b4dd01829ee4a402e54e633a229a94cf96e01f72ec4054c13335b89bd6e91e965bc324924c028b433074c9705ac4ca2682fb1b385f058d574515319397754cac9f68cb70022882a24242d1c3f1242cabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a5849211d831abc2c86834be35bc3500cc44522bf9aca86988aaf580bf45a5ff7f8192e110e163356b8a52486f772204bbbbc19befc631433f081e8556579d288b3b27c1a8209ecfbaa30a82b34eb722fe2be60534e2f625c0ae477826a9e75b7c5aed2398525358bf0ad127c15915133a32a9add47a72270a98f942807fc59f2420e14365a758c534f289160a65cfb34619c7c9b2992083cc699f554bd64586dcf379605581711d607235c944820cc28416ac761498d8b54193a8cac8b815d7b19a21b02a6d5a737c4984f3a888c0b9e3f51b95ed9430327642a082787132e94d6c26b298b77554e7f2237ac286f419266580697fc9316ec1176c4d763b194c52d79b25604974c1bc899560b72094701709797c5183391a268853b9ff3aa277c707906be0b078fd6619050e14b48bc73f877bee69a3ebdabbb8b2198cf51b14b2cc9abe673caa803b419be1c34b6341c2e83d2013152b557a87ac4fb55c5c86ccbba995492cf960479b044b3d6233317677c78a453d4e247ecdab3fb200c3d2a0564c4100a995c4f70597e498cf0897b507ab35e4587e2b875030303dc2ca8ceb41ae2a9725085c12040c8d0cb20ace46f1936725bcabd60d0b880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = pass +expected_ciphertext = ec483fe1e90af388eaccf12f71eee44a9868b9d22fc604716b42147fce466a3d9499f2ac1a601e1eb6a268ac14025edbbb5d02c0b2f8a60a4b1419cfd3682fb6f08d8d62d51f535753b05d4a3c3bf515dfb7f32ba2dbbf491739ae06850b4ff7bf94bbf18395a3f7ba4f504899f21e27f31c58b2389e5d018aa232cbb3287109d52655efc595e46faf0724426fd47db5eb9db222f9f325bcb97e7a273fa1c1bf3e5a22c2b5d3b915f7b27ce6d7fa9086cf92fafb7e0f1cd466e74add460ca84d518ee5be65c64f5cdd3eb13b1a5447b0e3cf1f5bbe40ced8a2f6dd6a76b175d017400611951e2711fad5a880412b1a29bbb3774b432020e93f90cb7643e0cc43b4425fdabfeef2586ee284e02968773fe186facf694782feadaa1d2c10a54d5eb7d274bf47c22c8e7545c5992204760f8f1fd65e26978da3bae8c85f0117e6837a87e2b4239363968d949ad3af50524733291c72585f21c8e91fbba2dac44e6968a3bed82723b9da8b6bf64eb4ed0b7188aca874835bd8591a14386ef6f6a968b8306a4a5e38ae04acb5533c3aff6e36ef7de90b6e9946ab7a1212714efb564e9464c47a1dc0173e6668c61f7fd24738f2ae66708abd047b582cbf5f8b794de988092c293a21ff273e1249ad499ebd36cc7ec6a7a5e28694bc820e8f9a5e4b17eef4dcf421f6a4a872fc3c5aff93e6f2c4753e84fa352178ee1c2defb18aca27c55a32cd3f09c24d0a5cd1eef3c33f8dcb52e0613b6c45f16d4cb2058f89491310027ec1fe23a61ccf5778053aab940d4091fe34b713205b074e1fdcc6f7f95235d46749879717d64d012facaaf35f4326670cd5d312adb6cdf493645056a13fde2b9e7be6e83e09056e6b54c51bee49551b333126d35987d7a75a494bfc8ce611b2dbbdf954adc160599e14930846ada2e76a457d473f8bd2a3d0e4b4db62ec8e4255369466bc9ad4df424ebe5d6727029e512517a68d7f426e5fd3f8c55d4b1ab1889369da30b38664e77e9b8e6458c70c9ba6d7ee3eecb61db33b71eafb21544ecf68a22b0499912ece6db40c6aa0283b76446ceb8388a7a6929c100b4f0f333ca49de2b1e68495336b70468a43877cfff03f30dd306a813961979ce3118ca0309b4c8be667393e9de346b2cbd730cacf59a2499330e3b0c7c8ddc284f9923ddced65f067bfc7474a4b673f6e1e0a39916be5cd05e71d96b797dc9c072bcc2a4f6690d6bae6594d9ca5333a7b8280150f0debb5e0d2d14a37540efd2ed2691d487d144c42676d96bc902168239667ff39a0d5d82b8ed9af5f79a972fb571dc1b47dca3cecef6f3dcbc045a730971b9e417ec682cedf562e4e129de4285e590006ff03158f4c5de616b0280524c0a50898f13d21adb49483f3dfe51388582e4ef2b3776ae8c2ab36726461a7bb404af15745a751d48c78c3f82475dbaa0e634d4fedcf2714000b16857d8b25e71acbb407bbfce4926cfa5d527e90798c58c820f7052a7dd3cbf506d63ec499e953a9c21cd8144b3da89b6f02a04b32e6998c +expected_shared_secret = eed6ecb831c881508f99ea115745448a7b312a4fa97f65044ebcede172dee2fa + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = fb262aa9a031e49084a6127b8410a5a46cbcabe6b18f607c97d4af6c6a598a089bb40c1998d16cd307895035b15df2c34bfc05f634813eec780c96b83fab557075cde3b64eae6ba98b65106e729b81d11c926404e99164bac5b546997d2a842f6aa9ce1f6bb7ab7551a06a3649e1caf7872ac675cb8981a124ca05a318bff9a234853821a3036a86404b0f056491a5b20ae09dedb123df8b4e9eb612a00207c6ccbc580373b0921fe2831f50610340865232c60660655184d8a0867a47811b88bcdc4e6dec5874839919188f63740588ba97405bb1ff2925c1553188c0137336948f7809dbb96d2f910a9c0aa95d49267e543057976e3dc7346cdc7560e68911b8829d37bd0eb20dd5e2b0eb1538a98a76a68798b5469f9dca82a08648a2da13bdc1a9b52a7b6f345626bb691aeccd14ec20f1c252b4fb2595474b2dea0edda47b87cb51f020072d489a2e79cfcf9a12b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a029e1ca5cea27d729065d7137bb518c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee590d1ad93852885db721b85d4061dca1327179acdbfc329416b23234572901b3f63a2cda36aa65b17035f449af2b404691957c30028f053989c501d8c2cf8a8cc0c04aa59f3b19a98777f814a18a0753a7180264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657256015f68a8c887c23205a6655f30c51084925167bb75c98b8a25b7579bdf40a912365164814794bdb0b78824fe9066cc63473496ab9cea06248d883d1846fc8084d59f05277aa3eec0c3186d68bdceb6c240cd0128a6bc1361467b861ab025309c82183233c37b35e8af1b464331cbe7cc3974a48a8e015a491677567472f263e31188966eb556151819cf52772053936abb0d0a48e99357e558301dc8157a8a7853212828269786919a8f9032e17f9b692ba8efaebb602e83bd4b75160541500779d1907b1159170dea870e6f57f5229222e85b178dab32f897bf45510ead084887566942656357b7896570756ab1614994f982841a525c8ec63ccc8e4575df03be2f5cf96505ade252fa4e80fcff664f6fa8c337980251904a9135abcc509db15a49fe4c6d57b41bb6383b3483ca5f5ce11641f9eaa423c0c3254a508d4319dfe72168070cc8c771ed3e06ce74c93240947a8dab87d889f9ad894f37243b25259153324e103b73c708371400ebf007bb5459ee084be938a18d055af7cc7aa98fbb88a156849765936e7273bc385a1bca94a74368168cf26d8806c7901eee2359c8694b5439f1e82c0a6892e4a68c4858a9a00b1496e177d1efb57eb9c0ae382b56626595673230903cc19c79714364cc4b10891823535e21cbcd45c90d471e684af1fe243e925c848565a1989637f7614c900af1bea9049b78e07f00950ac800ef72860e209c192a4aa0b901090987bf15a2db6165516ad0238a40b0bb233a365bbf2bab2f60eeb8a54771a8d8e5279e2740298563aa2868e2df1be582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc3659c03d37240bff084d77f09dee76b60952221ed2c1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = pass +expected_ciphertext = 9e87e3da4198c29968ff7e7ffc34af342463c33e928f1269f1f9dd9da05f7e6ccdc1368ca53debeebe88475d7a820be6266995b186c27068361275e3b2ea5fcd04484f981e77e150612841c15f5d3eec0e42ddde5c8dff60c0357fef646c13656e83947706b402f0bf4e7529b5912d6ce1478f9afa10b33e0ad8e64fc0c511267fc3802c21e8b39904ca88e8336f6eeaf9c9588001868fec48c5417e131345431b56db9b6e4468a2d9990106051ba1393277e9a55666916059e75ef50b399a45bb8de993ca4423ba9eefc797f1b2f4e9b10c63a79912b697d36472c3a53666542bbc5614b1d7e598e04d6d7258ee3a870bf3c715f3fbd0af474edb638cf94d4b000d4aa1f84f938f21e2b64b4f5aaf8d4a64e66a39268eb54c3f283c6ab0163b7ccd7a8c830bdf7cb5e7ecef736dc3837f6db70e18e23221cef0d6d2a3a50bc789116bfd1d3e4c6fb4ead0f5cfdf66e2a8c1e5f769595aae06555f0473247a48edfc9b5952bf5b5aef540eef286955347f4e16423dd6401e34000ebd9e330f2d8c801365c62551250f02c30128422992e34ff615ae123fc30a203382f8e5d190ae6e5347e90086351e4adc328f01557addb597968791490bf99baac1b5a4c7c5fd0348f71f9f62d0e65932e621cddf5de6732b182a7549c7d945a8e03857eacd7578623d993e1b9fabc88bdc9ca1007e79cfd0ab258aa1eb8ccea56c28b6da4bddcd74012d4526a39cb7a6c19175717f65fb02b10ae0ff90189c9672fa53fdabe48469a2fbcbcc5272d26f6ebcecbb5db514a53b2fe5ea45a1498022353918e67e3d53373ccbc0616c3f72d87f13ca8660641ddbc8c6f345aaa4e8ea397a690009fb080b70c7bd7b442ab8c5f7caaabc284fa140484636598a725868235a78b91c748c6e5a5c5fecb7bd9504d35745b1f06fd7ce6f7823375080937f81e8d8c6d894e606fbdfa64c928ad9beaaae76cc5f4ae37bd9cbbba7ba34181442961aae39cc534d44cfae600e79cad2d198969c85b66760dd7aac5c4aac439af9c8c49182e8d1151c33803fdc45a7bc9b3fc7ba063dbabb7670b184ff4092bc2f9e50156f5a85fd75dabd385740eabcb5bd816372b869bc1b751bc8db94fabd51c9759ecbecbc0403b233467fc3f08d2c94f1d0e0a6ff92a6824bcd6088cec85771ed9f6c4006d36a92c0aee038f96cc1378821827cda9ab645391feafcce1df8a6e8dad89abd81e87337db2ec1981159bd6cd17f39fa6cb02759939722e53eb0f42cc4265f85ea042027a36a9d77fe2d9099a48ab1644102538c958b7a5ec3a55a4d6291e885086605c07abd1d21b05e3b54962b87a2db165e6e351d91ba33ef882d83cc3ad5dd01d248db82642df1a0ee9175d115f86b1df2e7a3f5d1b33b1f6a41ac0c9f1eb4311c8720687886a5b9abc0de282f5925bccc89f9b779970cfbedf951ab1c7a06e4a0c04d7d1692f0edfc61eed1eeea7e0e3a440daafc6abe72508bce43e8516bc2eb9f7e2eac1ca693863b4b07ad985fae99980ee736d32c69af71b1 +expected_shared_secret = d6cb77dc96f9ae4bf8b2fc0e277935b3b7b7a59f749ff2c08ad42659dbce386b + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = 5226aa8edabd5a4a5a7cf6633a394b756ab38bc652ebc1bdb728c74ec316d039ac982b118f1aaefec04e48448d45f72b319289691a93a20283c3cb1fec992364ca83226332107704d3390f71e1883b46bc2f31b4242744e0847e72d5645586ad0b8c0fe48ac04a003045ac2d2101b52c7c1d494673bea69766a5adcb38ce3a978209471b5d7095a720a4c1971d94970884f11fa90c5c8b7009e2e1769b382004c93a2d9187b23929d941468444cdde233db3791656c860705b714e3aaf076921458b8dddd61e09ac461e96a1b1e9af19ac6984129b6c8ca9d4e39d70277b5d9a6a4b605f5e0454ac05729c2691e87a8d79353289678490a822c41c52a2f56b91a35f89918aee8935ef2bbc48485bd747cc5c59066b7577739b669ad21a5561018f021663f5cf48e08f39881d221552c846ad789810030326c8530dbb369681c69cc00c2390fa857a37ad81623eed4262db69929353118a0886e6c1ca3d36c65898968eb7c187b7b866f18a8bb369aec780e0033ebf1b0df846cd60633a461c569683598c7744fbecc54282725e337cec503d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a222418bbc57d7e1325fc2a075608988bdc44e276af10ca2d7e52b045514080597a0ff73732789d0f955f93ba77e8034900251416b43e291984cad36c53c947cc954a8320c11424be43283a6dc586a9fb39b2927867b79772dc1caa16234233adb5ac819f1a172da5194edb997f924a827a85fc7c7a8281c98f7a9cee443f68a2aea6001de7c7475b46b55ee8991dccc6527b5fa1393c9107c4d35a073ce29a7ea205a9279b62f5ce21f3aab0838b42e6679000cc4c182504a2a4e81757b7f6a183428786f09c76c69e2d7598f1e5049cb57738daab6972abf6d8bfd2ac7137493bd2b8b5f997519b2026ef38623294b91999a5419356bfe03e338194e471926fe5842e79740f416adae2a24f441ba4a0c08acc175f347ee3b614664496a5e51c01a55b1d2a3e8486cec4c3ba461970868502a0f9553d776514857bb8a872c7f736ccb432b1392e99568b51b9c9a56c441ac0ccbe785693722f90d63a0f78c8ee777236ea43de2583d0e093ec8bcab7c8c6ddd8254258b7a5732939d953e491a6bf310449083986b2a0f236c5b9a300db22299146b9a0943115845f3fe98045ca844bcb1132e0bc98cb54746937b1479dadac5a4f9320dc572ba81cb250f13869d132fa259604a76a5dd56a7543b96c3096d3046389a917dce53cbdd9ab04a65b31c6c5cfa23a2ad53faea3bff3985fdff9ca3e3965989c072f4659ee8914ddda0acf30a64a1a823b78561d5a9304950ea3056f50b82915c71ae0b6883ef319d061464d8050f37c24c62c7693f204dd4b4d74b66dd7526fdbd707a3490769764adbea61c09a2d7f464d7e932705212d6a9151b46c2ed93a7b99c1148f679d622419a4574310ac20941b3e51591ca5d53cff51a6ed2c081ee7b4bc23c8ba8b1aa2924406618715731b1cc404929a38911020fac6647c24306e349f1ecb4e2f530e8f200eb9c0a315606a3e130498f96ad5865ebb4cbb55265e69316a3bc96e51745b02f4a593b796b5951f48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = pass +expected_ciphertext = 7f5651959d131f3dec04f463341a622dbbb71494fb88a8df3c32ba4f398696feeee85b56a6870f77362e5bcce245c5e26e6ac9c8a995cf8b16591a3fb13ca611acb8b464556e1301b742b18b85e79bd8aac5e0c7c69faf37d3fd6c04b22a6a0936e8f3ea4acbabd6e6e1c5254f30061fec7939d165fc83196071a4950da73299adb4797665ab76167b024f7ad115a89f937eed5a9f9223250f54cb496e94509b1368f6ff28d1a5a5428c7f43158fd8b4b962db4e69f95841c82f9b9456999ac0902787c6b94b6327c13c40816afdb3d27f5a5153607d48f79d3dc3a40cee37ef2b255685435af03e82e4ede89cd639c7f66ad44a8a6cb2c6aba3d3362e075d6d11ac78485b6c69c77048db47d59c5662d4ba1462b40d1b7851592a9f442d6ed6e1db0614203a0667589e9736fed1621446b4d92c6dc550964d3436cee676aa72dbc7f47bc053434aa9fe04ee2ac3d37715fb6df7156a3bb5366fc2f50c2082556abda2695bd8b46de24624b11b3f275265c441e946c0b4e37981a4b2229db4b1b04f37fd716e2b54e345c12b231f201ac546386a72d0d2657f5ff3149e6d2981dd87c9bb1e2f067e79935ad015130ffb2186e93fab5be37f141a04ad649ced8f1bd1a5c745a28df4fbf9da9d7650c3cec51980f5bb0117c0c5835eac133f0fb570c86baada7b5d8b6c68fabf9f0c9b76580b512ee9b0d265cefd838bb7d6caa92d7487574d6d4d710e5a6edb453fb3d6227d8eb469539911bc8273524b48957eb32bac6898dc09e8538ea3a0508c860ff7e61580c5a8d146238ea6620be7b435d10093e184ae98228300f9b0ec5eb388953ffd45392dfbff64cff7ebd2f62ef5b4adff8a2dfe16d8d97481ef00ae4cded00e75c6dca982df4c06e703dd6c42ce47fa61cf576cdf11752496003331985b032de9cd03168559d483101a48f4e3febb92bff1ca9a07ffb6e0f9682b346316b567abfbad857e5ee520fa659536959d7082ebfdb86c92ca2189dd74ca92b9af4bba9b989a7cd218cfb3bd58f4cc9cdbf59f42ccfd9f86fb7f68e319753fcc1d2863e730f0f8e0f51ed12b991c8f734b440d7de3fde744d49d1c3e403dd5f5f2a845e157263b514ae72d16bf9ad5634b80f9ef434d9e35c3065057f23cac769f29e2ffbcad8ad08db5b0dd3baa828e035240a5498a87180be4f3afc748da484a877085ff2b2e74580cad830a9e3b98fa6b9db91e902ec2ddde406e1c8e3bacb333be8b6b5e83f81ef20e3bef0a8ffe7da5b0d127c67e64c0e0498f2e117f53e7dc1e052f181b9c8e2320063acf49d8db7645b5222b4a255c22c7ccd050a0c246c9c1512eb6830fe3d93fc820fb3edbc8a6482ee06989dc344489a54ed242cacf6dbe0ce21ec394ee7662dcdfde16c178a890e0f58d6466dd2244881beb22017d0a915a1df3ac4c78d8b67f50748b3937b939be6c36ece06c7908a8fbd9a444da6dc496f3b8acdadd2cfbce80a78e2f4bc1df3aed9eb195aeb01a01714a2c15b28b20460961303a44721b10cb8583f7f5 +expected_shared_secret = 1592f1413331f1871b41ff298bfa669bca667241790370d81163c9050b8ac365 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 724abfcd15255f0a5efb7783d909031ed02c52a203de570873c7a7c556202d53a6c086899802bdc877bc6a813ab59b781bb95f4fca9ee76028aecb9142a992dd7180bc1c15dbebb66765c5abbcc5ebf764d5234d89a378d5925fbaf63a00e35d568804b973450a045e55c7c5f4907fee390fe6877963e386bc20cbe929c3d247611e346eae401acb972843dc204eeabb043644eea29ba2c1a160b98f0d28caf0677ab2aba362b7bfadaca4e1197f54f03ac8033814a71e1cf407972b3f1d9a986637a972b46d3ac46509c053efbcb9a475bc4055265961c79e1374c2159bd2409a84f22755a1b32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f02270bbb19508e903888aca4bab72e332285837b9ebb466e5cba74d5ab6bb3b2a0fa26209a97f959c905bb4b058ba8abf30a5a6c190a018a9803ac29d84ba710b30da9a0844cc1a1478c289c32737144812355e0d7589b9ab765ca3b23353a350876f05081f3e4b14d8f66c998b81f458a394cc68c3b7bfd37366ec93113db928e5f9bf0e9aaaeafc619e332a7ef3898a66020dfc64f671879691c023409b53686770f8148a2b6f7b62b6aa42981ea0cea7753599585034b9ad99c9ac8b12872b1a47a088bd8afca2d42093928a4fb770198c4cc50b0214c4c94fc7b62b5e636423c6adb553b138591f6372ca6d53343ff7c70782a2ddc4801b262f220a539181c13f3c3e8e0a0d7191a43a54ab008d326df803fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdad2199bfa332b8c22c136350adb9553e3643d0c45413782f3bc9e941965dc051df98738cf50113ab422e4a22759ca016bea6fcba390ed64540112842f5b1373a2847107a43403b4aa5ccae154b9c54831e3911239b79f1fe997bae30a542560fe6647a2e7c4916097fd484c3d040456ea2bf8b63dbcdcc8577b7aed99c05fa28d468272876b614045095e918600f7c94bb0944f62235c169b58789ae8bc3e6f677ca8d238602399e307553e235d11836be120b3bac41b0a668e0841ab11f49e27aabdfc27afcaabbf542911b6a220cdd626d819c44c72556a3946df86c43d1b8693944d399a3b5b1309b9780e34330ca387cde8e4c9b2d0775a962f447828d6295873cc1629777fd93c062098b6149a3e7c383e2c33cc3fe7730537416fc1adb6c09f4caa736e4c796d2a97fa3807c9eab72993b4b876136b856c7bc75ad054288ef491effa872247a99aa39a9c2b7602027d65a169317cafcbb77c37d89ed32489e3c2557998a06689b06ab96615bb5752d439da446354cb0640686aa794444a806c31d721b8c6b820810a5afc00932a885107b5f968b5c8ec98207293d8851892a01dfae4a99832326e3863bcda75190c4a487b46e3914b702017b1b520ccc30a5c475fb2da94ea217f76556bfee825076533973bad3ac7305b5c764cd040d723617090af4a7811e9ab206c6a331a647d9385a5e7d8bad6c89b390b617018c4a0691d262429bba173598b37d7c245452853506437e756a399670ad8e292b0d820e3567047c82870e82236389d99d678cd9b49526aac30d1b830b12f4e62407a59c8f88b7b5d088a2d08b9f114c3f158650f32c682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = pass +expected_ciphertext = c1a71212d3e37d620f58b896a7d06bb05b206b6d84c0ed4b08a5c55d1579cebee866e8f58273b10eb698f9769ecf270ad900ee8871d8c89ae01c90228f57eb877f7f6ca888369ebbfe2efd2509ccef519f80b678d33c6f63cebe6e003e9f63d36dcee6e76663677ecf437d59b71e8fe106477a92bcea414662a647be78bcc02c65836f83e0111d4e2eab9b14f5de6b940663ae6edc3cae8bc090116b84ea78ec7e8bff76d91e735280eac3d40556d4389d2a7c39720118dafe3c8a8db614905e620b7b1abebc1a0b17590a25e30cf46abee0c4cf1c498a1c81a68e22165c76e857b9f6fdf4a2a4e3414ed47afc180351dc441c8b3d534703cf2f36f630b1416c12557115dbbf5f0ef3575b0115a9121749a061e2b674d0336e3ba496aa54f376bf594786d5d6de95e27e0615b67f6c318be228f1e89afc8ec7589627abe3e024224b85d9b11542411267ae956a6057ae955ec9ef8848c9a300ef227fc0569531d233713d83ab84afda6481a7ac32b4460ac0df8611384c6e9104048f7fa8f5d6c0bc9b55f52cc0e733ed6b21efa1067bc86311e929e991ed38e5ebd2acfe72964180e775e4abcde3106bdc514f8c47bdf872ae256346dfd90b9109e27f4eceef8ca436c868aa56a9ee277f8152e10658e8643326e3b619d0222f3fcc3ac878073f1ec5db29bac0da0c55e1ae7d818083f3fc071500ad6aad2e84dbf363664b4b54c88cb4598121e45d86367e215bc6a436d864e6431aff34b79c4e6617e9ce5599189494b9cfe0b87d34727c2839b6756434ac84e83e0281dbd8048d2b1b19f831faa198528245f77a102e1b0bdc93649219cace43d961cd86eca2fa1c77b65f2e5cdd785fc5ab7c237d8fd1181e598c4b8147dfc597df9dd6855eebb3685d21c82e9e80707c65c2f84cffb4f44abc15d563ac82e8fb46be179c01318d112c36608db929260c27c280b5e3ab11901de1e15f41dbcc578ffee9a1bed3f31ed3ac49527c442ff392044c98e6805a82fec28f69904e9dd99eda5a473590172478c1d637c12b949a7f6639a86fd8548e2c06fd9b1861c64cf9f9f3a0ad913a077cdd0305227e50f2e38bd7bb726ff7408907f71e68427976104de4d2df0e8e21f4cc601ea968f51a933383f28776d0abe02b5680562c15883b6ebd2fd5a6db063546e13c47036a657bd80b9dd917227a52f5b00b66091dde66f950617c9ebe73a0d464506bb3bf89d6801f8803e770e424a12500ddf6b8fbd45c533a99ef70c42788d4660eb5968cda54df25a994bd2c92aa5ecf72282bfee5c376a2391deab3090b292dd574e630859e7c2a866ec9c557558bad78b236460c05e0fae86b9b0e960974b340ed31ea35ca171308bf54d40000adc56d8b4ee6d10c238c5390dfdfa034e28609e95ae09d4f431c5b96232ae85c537742b3068a4059d3e8894c41dec04d87901fd25a78015c845c858ff75d15cb8c1de7ead6f1487d2fa582156a24d254b6633b7a027c61c2cab286ea16dd9d1799c606cf4102d6455740868fca9ef583 +expected_shared_secret = 966f35c6bc47b4525d9af1ba350e8f44ea448cd1d90cf4e9c55ae5878920b7cd + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = 30e92dbf312758b73beb83625df3b8d5c47a7a334d4e140915ca1401d461d7052e9ff05f73a1598dc9622c324c1c8b5de9b0386ea3cd95b86d80085588ac69ae310be6b5b5379202f4f14878fbb5508907b99490e4191b1e13a6890a9209f0a12910a3e096747eba94a337af9e609da4e8a9f8003633ec099983b8e778ca3d72bca1c19b4fb4a0faa4459ea06782367580b7aa49ab74b60c4cef7ab3bb9ba081227a7e1ac2f5400f8f7395f96567403b2401a2abb0b70e92e6ca2102c597f496cc8881d7b688861c7988363112155b5b88271072a7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be3907d15852fced4675547796d3046535390d44580c24bcc3d67a50cfa2ad8936d46121a7f60179be7aad0746e8a2c8cae124d27181a374493da6a68d47387a44460b39a45b2619f1d29b08ba4495230470b87bb926279eb760b9041632317c4d7a19e7753458dac07eb73331d808ce318555e1a2828da2f1d101cdc9b8363990b85064f63226c36c71061444e17a28c3b56332bab4bec2602f5c31394c870dd21030997564de52602c2628c41cb7ac2388ef35371f870a21675ac522660268a1802a2e4ca4c7152a9776410910175fd08c5e0307f4c2a61c877abbd2185ce58738fda15335aba2c77a804f94077a777fb49854c7a78462263e435a1d7b4a5205ab879438a91eb60397704cd937e66c7310625a6276182d86894ef9750f1817d85709bc578092d3b65f5c84514361264909dc2147ae6f3a577097e64bbb2c679c845d827b1ac393497575e385bb39563e125c3a3925a21160201897072f03f45d6ba85db7eb1d5b8ec7111dd785ebde07056653507e967385945389493b95c0a95827583f01dcd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa1323a34432b72c7b68f658868a2ae87306109b1053ed2bcedcb7037ab72d8c2bf48d29a0822575cc91ca1e5698286c9b19a7471a5b652f6a900659df9183c76417f0fc89d743aa635791d588cae6f650f3d314d65a6ae81a935f38b964f290be7a1a75f256776f17383f9bb9f9203415622b60b2a152a7ce3420cb49c3592ab8aaec009a237a12c2c04abaa08a382622dc84a053c94881664a97381ab88ca41846e82c02e00c6033b4721db29b71fd29069297a2cc387f2aa5336816c66e75b594bcd144171c3f7ac6df8a9a10a71f35b39a3da7d53571cb33860315288c2f7843e855d27db6f27b38940f973b2b063eba12b3a8b73d46c6781ac87f44c91e982cb27e534161212b367ab74a318b0f41e7a060823f17814f9a6e4f5a9093a6379fb0291d99916b15abc596550f152bc79703f1b0393b720cb85a510d4c9557acf3e620cf994c0bf8c06c2606041e7c3ce6044879a7612c3a2fa587b1b7676b956291a7ba5a78527a163ae08696c7c881076189bc1623c8d360c8d85c287a9c0c6965d0fa315e2037eed604084416fe31b2f01c7678311ada765acd7f70de59a9a85a8249205c78cac786aac9a0a0a7352b18f9cf936165a9c39d99aac7c175a5025f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aa9c205c1507a8f40512a45cebfb2b39f3330a962ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = pass +expected_ciphertext = 8111151e8888872490f4154b113ec0c4ebf57a28a670a85c362c7db91f1024cf7b6ac8030cee1081be1531a8af52275a3b94cd0647a949a6211ed50b0b362a034bcb17829dd73864bfe5ca9b2364ae0fd13e9824f8fab68922e937d2103a74e170c6829446e2fab2b7149bf2bbacfa817a68803e6b70a17f7dc65401f6a6813410887e4e8a784bd2d1f492c0052152cebacb091795ca0ee732486c992be11867f70789385adf6c0d82fcaa8eaafeaf706fa6434df3896d859e07d94cc83ca41e691cbc8cdb5f49222d2e883e9c900362476632b102761aa641dbe498c090b39789e88808dbb3ebb7fb7ee3389401e754a812766f7b8525411af6575036714a2be871754442b958601c1b2318b2d381ea5c852b31e1fa7c8db120482048181aa13014c361baabff04cd155e23c16496aa62a65e0ab8eb1cfb2b594f1714ca530f7893e89a3192ed2db714568e04d64fc8358f0735bdbf58570e179492365c1e1316be77c0b2e2ba15f5481c16db022bb314e3ff0593a3159d28ffe314fde190ebbb779590e29ad69136f695750a7d5948132b4e1871ea2ebae888942ac10f3d3c7a6960bdca579b43f2c258254e6ca45211f37e6cc324c646a51cff077271b959c7d39334e1617afe1c6bc54d0da480a5ed7b175d4bca69d97aebf3b9e399b1c498f985f2224f00845a8d78ead7b81ba0c324c5479b430fd8c4ca9c63e2acce7252c1b3530456a572ac3be23291437f1d11abcbe67a8df9ebcd22019b2d54cc3a939c5c72dbfbec61780b3a47481677c069197529c0f436e5b94abb7a731e6bc0622739eb6a9f9e3716c1ae50850d9f104e1193a9d3b05c2fef5736a5078e45b233c4bf9f85521f4b8a663b7a1fd63faae4825a47c0bbc2ce5fec7d492019c7315ea6145e53a91057c0c7245cad154ba809d6d18660cd9195273a83170c9add780de366a4e6bcd3fa5cddb4f84ba8d638b2318649417dcbed7936397e1850ada27b7ae967e6fb1b7a62721e8e70bff0d0de1959ec2978943feae4efe55bcb5de33ab5b71d6cbbeeac12af32c353e34bf53fbc05e1a7cb431a808260153cedeaf20da4a087b69fef49b05a8eec70d85cde26b8313eefff1a458d8d155233a54d025f013aa6cd0cd3d54a714e19fc5fe22aec2557c465144eb9315e2f1b1534678196d98c2991487c29ab085d363bac01f32d77a8d9d1ec055fab8cbbd68c8351a7e62bc76b860fb7829ef3e19c123e60991046305afc39fca4fa79040c7a22be2599749a7fe847992a7a588f8df9407e3692a34a52a9348e3bc5ec05120d5f0541083893eea1f967dfc45ccf4951f613c87dbd9cb3758f4ed4a46af79a11d9167fc931f13bf9356249fc2e3342bbfe977938518d6f807a7c62807e87a4dd6df7d3b205fe5f31898105b7a536aad8ee82018be1c3c331c4dde0b26d8b5c5c55e872f46565576088eec6ebdf37c8b0c36c98f9034ba52b98f225a69e0784a1ee452c2e318a098e634b824ea59ff3d57aa5b9000759cad7bd2a4db030c53906b44af0 +expected_shared_secret = aa333af0226492126c6985130ac7df2226a64d6d5c5314ce3f7a99add6696d49 + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = be0aaff4d255d72c6e8424c2d5d23f0aa4c28094691ac4bf0f56a51ea4799810cfb024c151c35cc3c6cc90a41ab964370c2bc953a84a73c87a02813de34b933f233da28643a93388f944c033236372fa6e6aca085b598123f27122a40074a4af57684d46398e5d58b13a863b0b984e224a7ad52c1c4eb26909451dcf2a15dcb11ac4ca38d93ca350078138e0ae87f1390fc9045eea420260c913c6b54dd93495f31aac32350cd03500da308fd8ba0777c999cb4982c91e569a1c52396edc506ac7cc43264a05cc880191501860f1a32f7760ad3b17ff693508339fcfc05fae095c6a96c1e6864baf147186bc22dd882620e5a5f4516df92b8b715394c5677d0db913efb25459d6c636442a8ce22899f8943957bb2b281a8ed14bb5d0ce6de3086ea8b6165798619b2ecbfb22727cafc6409e23088c6c940c23e86a603788c07ba89d6badcef07d79174acf70c55b7b30c067bd8202a1a70998459c54384196f814515ec9c7f360061270090ef37ad32115242c2aadc0121e1a08623038b311982c669de3dbb1c7789530191b07a947c9637bfa241ed35aa1d03c81f0d70f8b95112a3b1b08b25c34dc7e1d577fd30a808ac574decbb51538c2a017287e62128f32afb0f7a73ec8831e6b975007592b5c652fa636c7315baa474f873a5da2e82fd146268dc951689ba83e046c0f4820447c3b3e6c78cd240bc4d21e0a4660eb1c69402b617b83057874122e203bd6313d7874a987f2987599cd4d7946e50665f7d9a80651cc8dbbbc4df605f48274fba0640f8609b6554a7760856259c32df00d3056aef65436a285583cfc9d9a644f66e382d4907c6d78aa461a2b6ba8887c238f81d31e796a675ee8b7a598afd5d79a0587965420a2e9f2782b71331737680a499aa759824d11acf1a001f9a5865b6568ed8a1f4f4cc38f74c24e231965e9830232924526baa377b2ee933a1fc4677ee74fd98a0881628315aa95085c7415a1a51a98406fa345a69802ba71cfc885816ea30fadea0232b13eafbc24b84347124bb41f8c663506665ce4c3801b09933c19675c1f9ce54c418207b69215c91b10451730de65a4aab6c97804ad33c50233f83599133510bb334d9c1f4b7970087700ef45500ccb31b7933fe74a346aea4c9bd409bc5a186f00bdca67cfa8d041dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e6e1a11fec0938a3a886e9b328a8a539557f6c700285693266742f779bbe2e7a0603060673c7be9591be19a57a0cac91cd1c61860a86356b90715886acac2306190cff686883a61e56140f64ba76123c1b07614ff5c8a4b402cdba738ab68b749c1151da62c30dfaa3bf826d4848c4910c9ea20669735cca4df583e0c5412b610bce816fd17ab9c203a7ea42081901c8cd78940f090efb49718ac90ad6a101093580c13b5ffa0ac0d7b094d913a9ddfab03f835f79173e966746c69a0228d06a2c363e94522ec68312cd312eccdc688c4a88f6a5b7c3464cb7ec842fc1377359a162032c8c504105461936714f451481d8a4942d1715b6a65583999b96b0c47a914f2f721f5ec6315c91b009e714f6518bfdc75e828256f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = pass +expected_ciphertext = b13cbbc323f152b23a9715d1e210086445587a3a62a216ec00b74c0026982b21e6c2fd63d059d5f001deb171703127d47928a6cd9cb5093c3e6dab85d8c36af2815563817e53ea71610b8ffe9f6d969f0515550a62a7712341fa7e3a98b4823bcf0c3a98ba7976cd5ff343aaf0e01872718010bf60f6c28ec3955539b117fe8c0b5e59021462f4f32e5253514d41a31436190b9b4cf0fa55647d71742893a7b83aad7caf98d5bd0394c8ae4ba6dc192288b69e0406fff2b0c61dad7f474e7a3bac1cd2dd2c96ec38521e0a3a37d807d554316d7f2f998d91389aaedc370845813833f147ad4494f7aa59899a9b23be3daec4d79038c746728021e6b341ce04c2904b323224a8eb48e6bc6f81bcd2b3484c5921e2e6c243e1d2b66593144c350ec5ecd7a5939527bcffed92ae72d7e1c71aee263bcbdb50e5bf91b276b3fd2582a8533c4d2088d7d079d821b5f5b25775d60b6512b8fe64d677a67118656ac602b0033661f6fed92237c6a078f037c3ec19fc4a9d8f0a31b9ae80a3e060868b2af0011ee08afffcd0b62c17d91d96c5eb13edc7adb97b6a245d34585094541b138de269f38ad87a3edf3062a24d551d239fd5c409b038b45581fa8529f64859cd5091094e9639f18bfc422190356b6d8bb92368fde8c670d053aff96539ff179e7c8e1385e328b070e9b1e40174d7344e2f552eee4eec8ce9b6e81ba9f67782cbaf0d187caf801d0fd4cc66e88139698eef60638763f90c24f5d072f6895f1d04243b4ffa6fb106d6db627b5e0fddf2452b383f76020ac14be23977a17617666bdaef26bf60ea597407ece5668f334290edb4abf51baddab112fc9486ca90048bdef3bb79a18bc6ce4d7ad1abaae3e593115ffbbdfede454943370a7a5f58a47930f82fa7999a8016028fdd906be7bbf4a21bf4f4851278515d3d18ebac857326aef3273a82a7a78538f9c4a0365acbc61a0cecbaeffb5f66efad5d47b78a690a7aad41fc8c9787af7c09f4a5fb38def3eddee45eceeaff670315cdcbb174b4fa5f0a5bbd7e2d8d65f0b0862e141a9cf6350e6611cbc5ee2ac10d1ec3debafc912627aea0607c4510f9ae4d8ab076c84546a0e76309057fc66e4813bde218346a4fff9e026446dccb73225308605a2ba9b552db468f43f22d81b305bd255f59e4fc62a7e5e0c559b839e2be1a875826fc22dfb4f57eec3bc7cc45064d7438f2b11ddbd319c9405a5479ddaf567c0e6ac8e8361350ccae87e5b2219b6383bb16be9aaebec1df4f736ada17e663afd9f65d68aeadaa66d74b4f8828b14f33466d6ac3173d6c290608d449b493d6f45f9afb00fde8e10007b367596db43f5a931fc83c3e8f5cb3aa218c25b76ccbeeedc17bb1b08f0ee9ee08e380d663b482d39cfdf5167a2b862a65107471852df5f50591212b42fd3942940f5e8a8693d107306ac7b21e4562fa2413b08375c92b1d73476d6d67cca6ac3776de360d3da5d330f2e0ff9df91df9503162d5723fb1bbe2edb8e04a21dba70bd868d403a2c42bdc11 +expected_shared_secret = 9535303e6035e30c6605c9e0f10c553dcd73828d8525cb190fea79937e093331 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = 690b34b6586039100e84215eddb39ad2d40ba9f80165623122a2c5faf3437ab0376894ce67397d32a67c3bfb9761850c1c68ad988348725c83a378143d504400f995157903b9d04ee43404ab2cc7c35b8e0e09cce4559945f5640450703f81c35ed332746162f7b8328f78bfc3359e7c1b4fcf06155fc745c70245ffec09eca957c8475c62b05bfff288a5e5a5c78206e48c3ef373658859c3d9636786980578c07b764641d6a87222224557d10436fc72b563883ecb0934e50b6ec89429d7792ec0bfcda416fc2ac323a58df3fbcdb6e023140478868055251b1c09fa023e240e109869c1d2967f598a529042d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f228083de6a04bdf58655c59bf57b107987b88cbc001e010b9c2458bdf138288190f955b62c7013dd5784c809a7b1a29f8c3c33f0311a555306327392ddd44ec8f72fd5893f56f58baf207f9ee98b7e31092f761c390763a8b57409c7c5c665a913e20c9b62a5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5e816ff841456261bf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36674194df1ac3f595a294c28d24c26e1b1b5af5b542e025a182868e1555442e0b0d064865ed5cc1665074e55aaad601779e591e1ed2ab07cc551437603d24ca743218fa846822b2857f871fa26834e0422746a6c7dad256bc0b4bfff21bd7309482d7669f8857543a0436140ec684c959d26f2f827a84b37534b7aa3bc0a08163689f01141b511e7d11a316d2aa7d73909e889dd000c20e38667da048278b5ee87188607b4210642f5c38866fac1549637c600c8be8c60c11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dc8070b5687f7c6a73225b9233685c6b703d33677998c24e40a72894193cca1c5acbe4a133d85a6912587ad4ad522214974cbb1f877e16164683021ea9c335d41b000cf52a3ed45b2d95b7e2d061b5213db4c6bc36d76df5db9ee6984d31bcb1f6757de7e51871f1ae7f388c5134956d3286a49bba39967889c9a424772bf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15df419f6ec22d15a95553831be379ed0489749c495e3b6b8e190049a8065dba8933fb21ba3a751cff289a2e2772b06a4687338ca88c0eef1488b848afa1041f4f9607eb18bc0650055803041b728f2f1922cd984d228096ff29e71f097921423cb82254c40a615240a2482a3f5f095f5b399a8f9addeb6b726f43e3af64d09038cafea26686caa2ce2194cba660edbb083f92dc2a51142bbc922958c86c62ce7a4b3a4c95240d72244a912c3c193485208cddc4514495b35863cfc6cb41fa721a78080fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c832000c1c337fc019f0aac04b2149a469420c15b2daf5281dba5dc3618e0135c043f139cc74b14e7451fc11328f06b73f124766403541131d94506628c30b7ba68564179faed9c9d2a20f3b61793a33a65e92b699a47fde974eecbace22690273a757da903a886778002d283a819cb1ea2d34b8462dcab57c85653e363629d9270738434ab1bb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = pass +expected_ciphertext = f4245573118edd0abc115298abb1c7c118cc0d6a4365febfec360b289f244e1971e472049c9cfcef5f27d6bb6ae106138e1b42573f8dcfe10e41c49857cf586c8e1fb88e14e4e96c51d7a3775b84c38dca2361c4cfb637caf53ccfe6789ff289c1771b68832d0b445b66453699e534d81bd7d9faf248fe49b5e1be19a5e49c837191aa8ab301cde1e69b49481a2788c1aa99eb974ae2dc0a8dfc94f14baf821ef4cecee893b1c296903412c48a4aee3b1eea76370961fde96f772fa1b20a3209299e2926f76605dbd256938a9069c2564ab418c5343cdfcec02ffb2bb5a422615fdbd12a661a067e38cd35b86af9e18537e3c1f041b601e1c305ab6712d6b42ee2248f985787701270a51b052e32a52a4d9db52f1f9a775b387b0c4dccf4b5efcaf4e25c522b515cca2ab912b2cf07b7c421747357109205530c9927a3c9b639c7c473a991459f7b3391c0392a63534b0f0e604a969b3da8c29969301d8be3ba068d9a2723a6277334bc651f906166d78366e632b686145a0afd0b940221a0057274fb16b7f74fe8674c2c59199ae2f296dbffff51082655c19928eaa3bddce0fb27e5d72af612c7484d715c61fe11bb9d8b17b741aeb3b14e501999764dffca386f683d07d1b1e72329c7da38b029a970cfb1a94ac74901e07d0ccd40225ded0a778870419a7c3b32ef6ef05b1419521006706916f7d7663f8603b62e7396e047e1fc78661d7d6346623ea28e80510ddddcf918e2b985180a1a1c58ee5d40bb0a287890c0344d3cde39fda5a8c64a4e4c906dbcca97b593918ebd9f70ab79412bdc4ecc3417eec3a26cd5854b479d623cceb9129c1ab490ec98418737e5501f1fe51299eddeb86655d702d85bed3c4ae44ce16395124706cd763c80af32464504fa0d267f6ee03990b57afa2fd3a8067cd5d34b92a753bf9f590b506e2e81862cd7bc617bba82027bb9f900b55c7fcdb11485904ee2df24ffd095fdd05c1eb5d2da47080a8d3ec103d5ea7d516e1fc59bfb4f76591e10ea9e047b082b9fbeda25fdff8a946acdab298ddab2df2cb3d9ee0a781685b3b47d97009324bec36e9ad95e615fedd28505b969004b5a49aa517eea6d20ad42af18a46361df1caf9d3663fe5bc9d043d407faba0515fed3b6a615b03ef11685e4657dfbc165f20df62644e62074b9d86606e736d362b855f31402f936a2cd8d5cb96e3c209b7862b2687f054306b106b3b92570ce066ae63de2b1523590c7fbc03fb516d17ce1e13ddcc692e15f2d262b87688b9334edc0b33bbe4113e608d16c7e34b23bd3e854ed1cea39cd2548edaf85e1ff413c2afbee72cbc9d6d91ea2e98e4a1afd06c44b419b5a6a75579d89917e828edbefef6aa33c26489d7cda35e9c781b7ef5e41601593c4536aacb5cda2d8b75655f5c807f1e555da5c1415076ab0dd8d925ccd8e9493ec4a8185670d335bc7e348d8e3af544b17beae9d910c3de0b9ad5111dac9e80caa2d9960f3808858cb7be6151b76530254e8966fdb2b27cef7b7b941ebf2716b +expected_shared_secret = 0caa79e0054182c15e54159fbe36d9fb09481331a560ccd9714fff81db5615c4 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 44bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d7c227ba5c64afd5c87e01c1ad12a294758f45804719dc7369950e9e6398bfcb60a7819585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586056201ffc3cbd92c3a42d6851ec064a89227b4d1551ca7af6b5b3e892b4e44571669412e4240a08c42551dcc50086389f9e0c0290956b5ac58844a84be308d0a5562b57b5cbc594ceae87910a13167f27ce63b822f201af5e9c33bca746ba7c5e8541fff17324228321c7a0ec976646a6b5615f80fb56351d319b31960aa8823426682a610652652994d4a78c25659b533f5b40e6236a6e704cd891502e9c2d1858ca64c94d3734ac0bbcab2db2f9e03450e721a38c82a4c26a487f006e1966fbf8063ab115e74f441837506559ba5b7266f62b17e4d959209b657193689a0354149880d08434fbc282713118d9daa89c52186ea918ce2c170d8380e45a32e9f710cd6f89daf91c9210b767d743f61655a9702051d7c8a46f17a681b136c0863cb62430d084d282099d1636c04d6b1ec212a74046d2d8108470123dd751db685a1a1fb3a3b2c216f51302fa13ad73b919a439d424a4ad9e12994d1963b3c0e0316739ce50a1a7c23d65acea61423a5792321a84ad2e1b3f5b595f11637eaca77fc753260e04cec9ccf55d70d4d567bb78749efd005c9525f6e921f0630c25cb9a129781b9b864b7556272d5b4164e340d9464bf192979a073384f6a5e52aa0b6b74d43faa5412c5914524974161afcd91660705659dca87ba482d67c8c1400b069e66a19905b331243701ac8261952c5b736b25290235669fbdcc254631294fa2e97c440d97a0211c35c2ff4b6009aa66e27cc09bc09307c7b3794a5d189892ea60b2b323e95057ff355114ab48613e2760e00baeb82b0a763067e216aab899e7ca06e195a5e92486ce8911bfd5c7d956318ac3b029436a9d88c56aae2a3dc7b382f2c5e7265a037a827761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abe42cfc463c2f1542ae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0ae91cec8235705805af096cbefd0cad6dc0bb5130907d64e76e4be957a117d121d66071598112ea7d02b9648cf53e57af9e7cc3c9803aab327d87c53e41cb9bbc42368d332e0a963c3385c18936ad7483a5f4292b625c844c2282f25af0c86984ddc09371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dbe147efc2a34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf0b12d7f5453e669be2d805dd6961454ba8b40c6efa961e53da19eea2243c998b504c8ab9eaa2db11b2f9b591990040954a1567074e69154ad6e618d0830d3b554fe4c99f48b51cf6609952cc9693acab000c335b98126b4b45a9f317f80a6049558fe9d855a026aefdc649d295387c530e075ccb32aaa202171c6f6907a4a2202a9c5fcf252d98328f12f927e31c596047140af9b177e0352b120954d00529a07d6b2bce5026a6d7cba01231a85ba39b1692694788c9215b69fcd111fdc8934a1ba24cc7890eb479aef01ff29161b0a7ad921bb72a8b495ffa74c62c880bf03f0bc175eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = pass +expected_ciphertext = 692da34419ae1d6ea887c5910ad9c1e027ca2717684d8cf8d73519be768bbe6844139f4e75a63b0251cc9842de4aef1473122681f288a19ce658cfb921114e619de23dabd7db3eb80befd83216eeee6639c589aae70ac2fb8f1b839e953a9070d287e498329e5748ac3cecdc3effdb7c75b860a64ef4a389262959b42070bdffeddbf1b41853cd7c5517a6dccbfcf74f392fa85ba62cce1dcf30a3ed8cf6608381a06051767b3f8b9e836c44c20bf54c4e174e1da9cdba988d049ae0f43f1eaf9ccfe4ad537de224db0d54efc313cdc8a16d356bbca595811f6991f80f94fbac41c45db49892ba56b20256c375b130d64a24fda9c9d796554923418dc18fb92f4e93df2ae2351c5a53566472f57e0e206d818e1d1128abf61f984ceea23df1697561fa48d0d6d5a0ff59f705297da6949955091dbb013c091d200f5856bdcb6166ecc42c36038588791f0b47dcf6dcc7a045487ba59b0075e3b53817bb8544e98a9b60a426ecdabc139792367d99e18611ac931680d59c876fe55954e3cb311c683f514520ce59cca491e3c4fc4b0f201d554f9b7667b19642639db4866c1242f0745d29383a2d009c844d2605e93e9c62d65e1d44b7030d3cc943bf0f291547f7a91f9edf37c3d0dbf1ef9d770e838f626e591e751ed64ce5b94e114cd443be38955a2ab79ce76f28800cea4cb662c1dfaef1985dbc955e09fe1156dd87d93701d05641e65127a96853ec478bd59ce855f28674db4f21188ee0572e3cf0840009c1029edad1dbc119ebb219a37f3407427c1dcb96b4f676979bd77ceebfdc0f89a8f0b759fd19787f3105c98d0797ac038d3989e1ded23fa49f3c9c580a5147d847a9f0048ee9d816176cdedc5c3bd97961687d59794dee37a2a9c7c4e6c8028b48976e944c8d45c7d7f637e50b25e4440263a67ef562e2baa5ec3c978ff8e6c390b57ff082c202272fa7e6bd4e482fb5fe7205dc56962d28d6f1ce85659299cd913938cd036268856b564a154af0e877fdad96ab0a185048cd1ea6b7dc8de79412378126be5d10ddfe4d5cdc027f183fbdd80cd9005250d72b5b2b8d824cb4512e1d15f85f68626ac262b4e169b8201ef197da7c208378a3c5d495de78bd780dbdf8e0f1b55811512fd78c1695f028f386d7bb591dd962b403da023977bb66c4145239e61730da1d91741237a65e686bd48fec1be0a6bda744a16db76f0c4622fca5d3dd2f87628deed85f8efd90f8778b2d9ff8a4150028b65aafc318571a8b954819c1c9bf0eaa2d1aeea6373213513696feb1eef11057106a76aaf501ad784326caf958c5c94bb473ad548b8db8dd508d44a667a420f7252d44e46148e76a9dbaaa766ab0578111ebc542aef2a85c0249893053ec5fc19c4fa0979227ca550e46367fd2e09d018cc894d9c24409b946f6464c54987a09b54a96bf5e672129b391b0aa95aab3903066324ade24b51dfaca8af884369f77dfdfb5e5923bb5a497e721f46a6332a6d6b822c25e581f4190080834b2e973263f22f8bd9708d7 +expected_shared_secret = 744ce1aa5a9c515c6571ad6e2f5985df8434e35e9f714cf3659f184b5db4086f + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 9eb92fff176a27197eb4ab0171211dc7fa954c652698c50105b5c2e9f7a2a887bfb40880f8624e1fc67b1b43a51139ac6025b9eeb60925d424bb82c58b4b617618c43c99b07fb14e5b86538d29700e1ccb4f53a52bda2ef566b20d8cce1d7616dc81398d14abd03964940c794e6100da994d5bc0bcf28b04a8971214e7ab9285515ef09a7b486ecae5c84655c9ee15255b715c3b784d9c243993171c604a3e29450728396e7572228610bb9ac04b06577b3636c137a24e2139b48db005553152c6b040cf0b2408248675eb90afb66d6105537a316c7c989746f43c3b284342e2cdb5f2183a16ce71ab39c67797112b0b907c00f6a47f17db08d924826d526cf88234a25676d82449f93b2859076978860e499a0de134a936e35f06a7802456008c23970818318aa2b55a1762a9394dda7a49ebb4b38469410f5945dba2801ac25ba39a2df819b0db194b53c4247fa5065ff99f73e71d51c22f51fc262dd2809ebcc6879b0d90004da5ba7cc9462f6c822ac8fac8ab95b769a465cd743ba2babb26958ab9c3494d329a0c736c28a9cf84f5c90c5a0594485a9b339212d01bf6910105d44109b09bd063b4f2f3b903c94dc650812ae5cc87527754d476ffa82f34f39b5462006029875712cfb1da648dabace5aa1590b5ccea82c20e74795c71bb70826ef4d0bba580a447693a42d8af3256c64ce327b370ce576b6343f2bf8fecc76e1434d5e448aa8a3b326584ddc56496704be54108f8572170c2bc39680598017641422bb81645959b8092e82a54c68aff60b78be78107e7bcacb241b09913461579b52aac5c6c8627cc033be2273580a523d4cb7979cb65d7056643856be187ddac112799559a87168aa96a18089a6c547e87da949c62b8ea876aa0192af409bfbc354f05dc08fed46904a2688fba59fb71b83031a19bc8a6350bba93552be0c01b73c89964563fe588a5b76971dacba69868b588bb2f9076532d6a8fb4316dda4c85c2945a2a29b6ead3900e50abef2b44375ac36bcb0e028a20cce58353c827f1d53a9a0510e3827cbd1383a6d18c0d22c374e2b6061c2197a6cb094ca9dcb42f0418c24a9cb893c45423447cd5eabb0b9b410c9144013543e5c3bad525377ce8073d4a5f4a22bb24874b7e21523cca731265572b487e3b42ae581a617437348c290f00ad09460aa0c7b6a1a53128e4e01b3c406a296cb35ca0bd0d1917dff42a4848ab3bc28a2a28044c719ccaac45c513ca007653bc854dbdb79181157aa17220153ca3563b21be77aceae06bcd02531ff5b7f5453db0119364dc4e97ac7a495287815b5eb512129643aac4f42b3af35afc1207db0a3194302fef097bae37bf382c154e78154b3407bbd90bb2143bc285af1ea0b1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83baf26ef19367724b1c989c39bcb4337deabf7d531fe2b3327f4ab0f6457c5f3869590c49664923993cb2b0103b8e8a41cc5793acd192a047972978a2ea1b9e354cb135f2ad8928574b2c14fbc1a4c02715292c9052b69ab2a8329c02938bfa0994c209f816a24eb13f4365af2d20240ef66f9bf6b39d54ab5d350c7cb3cd6f645379815aa3028232bc89bb89bfa2c62e351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = pass +expected_ciphertext = 6d7d3b4a4c4089566f5519cff32e125274f9706757ac5e10fd2e3b104025ff7aa64192ecfc2ffaa86e2f48c8afbfbc635b75ddc04d2867a39054d0c3489ebefb7297215a505e7f65d93115592d78a709195f9cdf6a3cd7a7cc1b9cef75aef9fb2bc05136c5c73714d6b078cd2ba88bbe9fb61302e1d0771520509b90163d1514bb510d2e2a0e4e4872e607f303ecd6b9d36bbd694c3ae905d7c9424b604be28ef2e985977a575d778e219dad4a16b0107cd68af5ade5fe9e3ca48910fd2b6545ab2a38fb9e7159ed97b1c8d3aa7b962e4eba2d75439a6846f9c7447685d8208934c6b9dc0a47103fc71ae6612b10d4c71beb667746e9ac680a2c750331d1d79a54b3e991aa7eea7ff896d98a63c7f499f646b349b695d74aa849a4268c450d72aa8f531784641282c7f58f207c085144a1bbb28b657e9dfeabc03ef0784fb4aca22a2fd0678ff1b365b987c170225c6785540ec2112a577c20151dbd47028e88bc2b45723c3b50edc0efc0bafc741c4b8208aeca01f2af5c223d5c6016676b09c8ffb64874616a2891031a3fcb2c4d21c073b5bf14b6e5e313bd252267ea4165b347793de3f4f93b9f269ea07a60548c9fb8560a49e544aff22017ceff150ef44b12dc013b6675c1b709d4f40808fa37a9352dff8d37acf1ac5f7e6a27673dc79e83cae6b1e69fe113155646cd1b6e87e2e9cf67c3f2d2576a2c47a6156caa33fc547f343c51a17932368e1290e0ba91e35482a70c7777eb45a482f261f77cd88dfc4ffdbab03e01740fac45457a6653059975519f2db38c9155a31bafd22c57c5212483bfc55ef9bec51be4860eb574bde711dda9825db976e39f535a7edfae6077e1e1644776fadff2f9e18e98eb238c7bdf35c9c1af1889f08d61f51227387c5b01d0434178b55aabbc1945c78cc4da30d4b799ca4da2228c410bd8d5d4a01a0a8b0530a61277c9db721946cc605d089fd944a8c8787aeaa9f3fc6026bff912cebb5b85923d25cce52e1372b5861957a39db748cf275c4530479b3f0d061ae44599fb392337b2e5f8cfe8a77c73dba4c9a77428e47abc6011cf37e86d8a748d2899bea405b2fe43172ac5361482b69c3b16afeac9f43016f3dd0191f627624e5faff4a92e1853b16f4635b41cc1b256f27f54930139c3b50d5b2126c86121ec72f7fd11d06f728412e309b9df172d2acd8f1f7c1a6c86629e3e0174023e3e73d01379327a59031829aa7d6acf01b22cd550b1fe31af06d91f43fa51cd5b6df75e6081c84875773b053c6e473b8cf1b13620633082a47f1610cd60e64da50902801f0077e65a0d4d2a5467e59d7e1b95b0eeb95db0642ff81c2cf6b76d42e6bdb58fbfc0730a55f81c2886160df921a8c04c6175008743796a4a67494cea3049b8ac89df062aabaab5c277bf1a81a61d4b42000b2fb55b027d9bb6d3e3e984ee595c6a76b66332b9554b38fdb0e93b77cfd9f891f25c7105fd2c1679a04ed526cfa6a26984e19d71b2b57ac3635f233dff02a799e9cdd565bedfca93d2ed66 +expected_shared_secret = 726f7d790df4c860a0b2c40de9d62c85d0ff70c704ce5a1b3f6bf1b3e3f66cd8 + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = 5c405485d51fb10cb0f150b9db466c53e070f5849049d225047bc47aa15f630a6d62c5b179906ee6c067fa3384a4c22748f984eb31ab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b261beb0eb4eebcb8548139bbd6a0a844ca1e4e59f3d7c4372ea8632b278a7e68b59032012c5518a8021bd5367557077c9c1b4a50944ea1a834bb61004b2cba7f6401a57839a3cb85b326449a25457851b4a2bba2e2187f040745fb608079c8b59d2b191813d51c5c3f329b1f5e40771e1b33f63ca400555ce5351cffca2ddd268d7855151618587c8b037e7ca290467e4a7c2c38290b84ab8dc4a839f57102dd559114092165b13b130b41bea2f857c84ae45c1734375a3ea91021014d29ac58f12bd5a44b91ce986e094a66089479dcac23a6275b864195df24f2d4a97f1b26b508c3a5bb89b9f0a913867c1294c252d5022d9fc60ffeb3ff3c29b2dd1aa97f22271c5c8e749cacea39f2c637ff4a235882747ceca1d95e093966462ad401510ec112026bf0fbc106270988b2c35cc7269da693a7d67052f9156d30c916ad6552eacaa3ac2396bc56668686ea8a1578e46658a71b4b7365ae56a263c783973c1b63100b1aff4c3feb64856a781334c6e83519e541511b4d581914c697ff31239dac56662a145316ac4d14e522480782c4ec52b1a2b8a85f657217ed11426a2a606c01c17171fd10824c07042b189225d40919aac5cbe05b031689b1ea61041f6091d961a8910a205e62ff21909c6b4095b270d87c9727a2b611118c84aac033ea9cab5f40efad6117f2160a56505fd775d3f415aae9271a9b2b1fd1964edfb772a9c4875f06826a49c26e93f0b1846e006468de71b98ac6fc0f81ab146236739c9a7b6c13952089d621936e8b265b50dd4016547a2abd52339daa0b459d265558a1d9b61c73e49346396b6155195c9c3a437614e68e23143f09fd28857aaea50aa808600f5c5ca33c5963cc00c4b1c1ce2609486ac4f1b2ddb7b06acb62398a32320f315dabcaf5d4a833e2a01a6e7c971ca15e40c459ef18db8452aabe1584412b4c4dc52e6004ca56b5f48555041cc828a7a6da77c435f05574e5c25efc3c6057443eb77993c987cac2363c3030d88e288f4d08966e624794078a39c53ecf273df178cb022a5fb025a2687409a785cd6c019f5761b0a3087ae91844a69c2a89c1a00b1caec7c1f7a67425b87be02d80b67ca6c7dc3b45bf425dfd33dc5a13e7531907ed6329593c333466d9628668b98422c985182f8c0952cbf5052225363398e516d23678b5320a9cca38e21c6be86822c4fcbb9094277bce80992858c5498c6bcc57db982c196b1a78c317975544ffdf33e57a30dd29a5ca4a22a918746fd9a84ee1008db920432e39b6ff182c930243cf350c6f486832a807a36c8a9242a5c39140eaa7a45bace0086a86fe36be28acec756b5e9a47225638659b250c52b564751ce8c42c39bd1046d2b6cda70b7951707b63073f0eb5ea3fc5229f816ebf4007ce97307c6607b4ca17ca30330570d4f39bf76998147060cc04b33d4b91294f85f4a717ef9c288e3741f70fa5823ab8329f56d9d0b05c996701a050a387362db09427d5587e7751131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = pass +expected_ciphertext = d1a47ec5e9df73d00ea6c31f8189070b3cdbafbd59d3561ff50a2961820739bbd40cd0dc9183f9dedf28da0dc608b7c0da800fa9ee2b44331062d972cfaf9a08a943f60e4cd3dfb6eee587cb152308ec9c772c566452fcf0e16745d5ea6854a2fd14812c4c08e065464a0d494df56861e6fe82fabb22e955825d303dab2abe42d094f0abe8f10b788a24f90180dc9434b163db2aa4d461566111e6817a92434a2427c365a05232fc31ece1d49463cc3667a92760480857c893a180bbb4b4afa50ca382e9e4cfe5cd3e3a424d5b927fc75387fe72f7e38c267fe94a9cbc12b64141b574c45d6aeccc7cd28ad9ff4563d5ecdba1dc19baa079940d6c71f18819180481fad6025ddb5254e7cf39cca79bbb190cb526c427d15551a9af18c003f92f35c8f8db6bbd27af8e6108f9827332d836dfb5299cf9af20d6cedf3f3bdd3c29d0c46350dc4bfa046ebd38125f4a5480e6543090c4b3ecfb11ae6b31c501d38ae00b21d4889c10d697207ece62b5dc607ed66997bce2a2c2aeb2db1e8e9346456b9bff2f40668d0ffeb8fd3909ef59b7bf2e23c81938502a702c4c531024fbd6265980b2f16c70fbadde02abe62a9e530ac31b2bfae08581146a2c47691c755cc4e08e35bff1acd79cd12dad150e308f0d421dda9539b3d142fa544dccbf9bef3441fb8dd08c21756fac0d4efe441ab6b8c1c21a5e7604914a3181a52ebafdb7de84b0b634cac7cf9c616d851f8a7c3a1e6d1e7362642cfd00870fbe15dbe0fb122ec58ab300e93c65462f8e9fe59be9a05919aefb568edf13e4bde5ecd0b5912b29a044e3f33477a35f925f32d1f52adb91620e8f667d5a55d428737b3fffb76439db79b74e7da3ead61f3c43a13e030cad345415ee18d7415ff6296ab1cd0d306058d3a785fb1cb27a18d245dacee17fe8a0e3aea3299f6d3c211be3165dde7caf805efab878de257a8051fd2650473e6d3ac4eb9233e38ce9452ad85862d3684d864220902358d35027451962ea11492038fcaf2ef3faf3cfd8cf77295e30b7dffaba171f48062e6b9213efd6d2feeaa688191626dbb2fcc89a0175ab32351e7c72005ebae83c13d59bbaf0d4a5f1030168de6a7c76c83943456867435b63fe864550dd99bf934703debf2192d6a1cc1a363e8933f1b5e176941b3189ad53f038423d90b9a2ec584ede715b903f1a9917358bc7616a6d5bfd20c73f98104bf1509aaf19960fa2145caf47915db32af854b2c75abccd0763d06c5977efd369ef5a55df1c3e13ffaebd2a9cf99ea1f75e796c3a6bf38de65fc10aaaf024946d1df9f429115139fd5564682773e5513f2c0ff6838a5e31197fb199284402274c10dc157da502a06a2c610822a1f970adebf555e5832767f21714033581699b1c01e554099a7ac9b31e890ea981cdbc917e063fc162c877c51358431d00875c4270160d54d93841535c582804e1b68bfe87877fc265ef906fb62331e4b7bbceaf9f12f255df44976e4e34e3f5fe186a21b2b411410c45deb34a64911bf410de13 +expected_shared_secret = 68f3e22d1b2d8c57bff32160e550becfce535fdcb327394aabeb60eede263213 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = 7e395f02d56d41b5c5889bb6b2f149425a2ac8aa06ff23a82841887de199b56c91846392a026b50e87453f44588ee6ad4a443f54d25ecae39aaf286efb47a760da01b6c13fa178811c47a0dfb14110fc6482543e8a3a52abec3a8d7176aa2868b2d46cf68538c27514222a34371c25fe832184206e5abb699d61426027a942581d0bab075a367793c81b7fdc11e2f6772c8040d271be5d07d00b330a6c874b46d26f51db8f43f22dfcd72613f8c22d15c28a2b384051142c148b07f7362eea4771959b635a215b1351f650342d2a071acb16dd8ab50539096f295e44173bcac20f3cb271a8041e3008a742057ef2fb2d78f8a3a3c252f6d38d8e85bd57a75d45ab4dc21b8033992caa623866e8989f98560de33004d3409f233020899340b2591e1a4a0223a79e20b4b85c632ce7609c0c45a0246251468c1b6c20716315a54520c5718f4c5c7066331fc7e953ed91aa5f3b92e69617b29c256657124242ae8305780cc0caf00c92896929a1648be9b47f86f144a3b12d9dd51f347875e6da935f0bd043abbfdc7b85066a7836d442872c56fdd41d9a3a01d9ac6a12531079f74b273ca129f36a7ae463f6464436e50fa70cbc2756bd25234893b50a2898345e588b819c0955e9c50072517d58b0a3e4bfc9832b727c7f2fa924ac672d4d104a8f3ab81200a624c61eb6aa7b4553aeb2084360f1c03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed6b12e8be5a6ccc74efea7cefc7a0f5ee18857250d08f03cd94cb4c455141d7aa2fbfcbe3eb896c2404bfa3580bc63b73265581d87618b206caa9468c65bb1863b18f560413d1b1d392259f37c00f7d89124c56913483513006feff89092f218fdcbb8b118b206b64f2de52be0b553665c32831bb4cba3762991716be65e6a222b30a0a5cb246207352732bc3c8ad7a2c3243c62424af222a922787f7fe44df05299da1105f9ebb0c5aa18b6c6c73f43390af9c2454442110aab4aa629c8f300dd38318c43a25d269885f970ddd8ac1e5918e59a3d53dc8a44873eea97c31f34108b893b634284d69153779230c28b2a1636b6b839a4d91b7e23f0414b111f2e7c1b3ed58613120fec37c78308587494233313950d82ce946778e044c3d245a19c29b09a80c3b55416a811af33032a0068c7a4767f05e9aac3e8b99b967f88d5281a38b072b8c4e194794c40bcd5366714525e846048e55c008cb48b5ea0c61655b8819b08fbb88337e20d63003f2453462598ca66181ace033c707c1ae9760ced165596b2b163e54934540c4f7097bdf14d29ea850b95be6fd42973436144270549a81b5f73192c2c6ac2474686a9a3ee556b6f26a9039866176026e25a60b5864e963850cdc8219d21859b5c5c3714434ea53bb16786dde8036f317c430b3bdb025e6b62c097340f1e961b90e0c5182183de05b293a05b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b835c0e2973261bdaa43e414153118b66c641f834c949e77fcdbcb59dc27089138a2e07a5b40c7666794fd8e6b97685bc4a3c2a65912c35f50a278bbad765c8c775bacf28181d61530e54ae7fdcaa2681a01bf51c0d7a033d6b005893b98da86005381f1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = pass +expected_ciphertext = 9066923999bae264f53cf96f4712cc8655ec53d9a692221863ac713b2c6febc02e5b43163d008e1a5a81525dab273757a27c568ab980e5f15dc01ba4e370915d2f77cefe1a1e6fc2fd189e7717f135d9b5ef2cb4097715a825092e022bd750abcd7cb3d6ff8f73918443eafe6c2c06a00f0c65d45dec9cf12626e19c1ec4bbb01bac2a34e02d096be6836153d0802eb8e62c1f4e46a53ec661a304a223b0b3c7ae0799f8f0b162b962ab3c92dfb5fc8168632bacdce1bcbea60a0e88956288152d2a2403c3ec1cd483eb119eb62c5878694276a18d58b20c849bf41f42b1bd8abdbe68a9f0504fc106f47ed36c2b1fea208583737ff02c23470fd81597079bde3f56845a3a444870671c410f7010af93f253c1f14fca19737738923a90b78e097fe52a130df7f2fa622203a05a7099378cd22de5511db73715839a043b17adcc7d9ea75fab128482182efe6fcf9d87af3bd80fdc1afef0a635d387f39b27e73948540953976e66df8672115184bd7719248ece5afa6e85e59bac2415a9c242c7e28556d26ef5a298c2d7b4e80d05854e5d8148439695b645cc27e041095bceafa10e3f049f23f42c4a7bae8b58f031a1885ca2a18f1ced48148e52d16ebd12b63931dbb9f21e46209f6714a092535f454a8d3968fddd8022130c6bb989d0dd84dee9849ea3f75496425654634adee5462d6b425ba4e911fc8c47f98a67c3c116d12f372608d0bfa2d066bd5c3b961c64044a0f8186833213551415b2beafcb74d9b77f59f8b78568c9337bf73449f70c08ead3086c50ad0193082925cce5ec4df8df4b841ac1deda751873d1b0698e8037499fc3ee3434fb72b1710e6294909bdefe9e670cf80260066fcad5d7dacf233af61960c651164c40eed1d08e91f87ed638cd3879e2c933921108a4da065b4b2cd8f965a3365b130ddb2d1f0ff017f6d91e9aac01fee659403e00ca1008198eccc6572f0e49dbd0ffd8006a45fb6daeda45ad2a7ec4970406b44f6f0c5252bc2234b9db504810a15ba85ea28dd19ffc0476a38d0b74856836588a31792ac185f5208ce4ca0d1a5e2210d049a7a38c9b6953e8a4a154a34a15d4dcd1a758e5a03a746ae1fd576cd14c85f09d0bc8554ad570dd55e6ca80308a927515b215c1af914f9e409ae14cf99960e8355d6316297c6b18132dc89ee1a5bcd3ea1623a8c0b974e17048a18081ca47c2a22049c98f0c5c640d304a7fd80089bd1c0baf634b7bafe352e7d57c12771c8c4f944e4ee03b50fa3d4561f615f8f87fdd3f3181cc6d74e63b2393e5e38e71b1fd2a3aca442d45f1ffd7776184c5e2eb5637e31aeb60e547ddb12c7d276304f166c7be9c4569f34209875407fe3e273842b4cdb28408515e69313cbef447234f6dd7fb0606aa3bc42293dc31d1be2c18a221dc650644708dbadc53849c80fc2e91abaf51f869796d5e78c5b53d2ebeb3a2efe02dac17a177aefb0a583bc271cf7ab5d73686fc971db994575adf973fc84bb9ca50609c52a22fe421cc3b6f35735de793ce75 +expected_shared_secret = 7f6085840a30c6b1fb9dca782e0c78a2264d54726c04c3127956f131165426c8 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = b5d6022ef207e7629736d614527619e33cb92600a1e39a20b25a5b16eb0ec1070e5d566b28449bfb38936f44721ed428ced5768ee647a771b7d76a30c7e5563b515f5aa89ffe994cffd9277b0695049c355267b3a07c61f3c5a2c0d4ab8df76129c19f44f762b51bc0374a43e6f6c1155901b2430b2b77afc9ba4e14d3658607387dbc2d12b99ec0c0b0c2721af298a6ebc92a7e6b97bc460674931e21f68377c8303b24cae8d5ab720c79c4399414a514254603b565397857a7078b36e24a262cf9070a92c034c76614d5ab455b60b3b3388500946677195cd587942342a6fc91bef144ea412ece186a422b85a213c43fd0c361aa00698458f5c5370c6c553a9c238201754e2b2e2785bb03053e0b414e472087a0276bf2d805cf477378ca34d8f01c21b433f33b49a8b9bcf762451460558fb9c3cd071e654c250df04b6541baa278c1669bb49ca3ab4c78cc92d0137a2864bae0c904e23aa28395edcb435d9c1cf742562d603bc61c521145ca16f69192b137ee372f04402527bc557b754e187355a388410751267561a6b1f59e04190ebc604ff64a2b08b244b57abe84f18938c5a9ecdc972191bba33915c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f421281b5763865c584cfda6aad7482d00a0520d947fddb173947865fe178f9800570d4b2b9529a42a514a8691c8531a271c18e5f84380c20cd9a992051d29b5be76b2235b511514904e3b284e8854556334515162db1b09894b18a3127982269509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bca04e2cd90db634a3d52b734e224c4c60ba3c8240d7b2755ae5892a09a0e7ea1b2424402c45a0ad59563ab97ed906a1a15b8c4412219203ce6826b91dd00ad602089ebc5163b416c0d02009a7a5440350a00a7b49309ce39ba26df79ece038f23f4b4300c01287a51f5fc619eba04ab1b78e6396bb23c1cb86a0f3bb11f7d31a161a480b8f33734cc63ea7219d76bab759b1ab3405ca61b535b893b1bf2b678849751a6a4f18923ef44470e543924d0c462d8a078782b80241334f547d2aa474d95b8709747162b228993ba15a0c4fbd8bd662a1a2f01cfa859ca723a011949823fbb55947b9c27c2bad547b0e6d29665071b30f3c8c536651e6437c0d4a314ab38a8f707928c0c2b864a3a67397a936dbfb98fab2c0935441b83157d05072891a43573882be97686534c8bc7015ac267b75f0a79c6991cb6c96c735a4bea90acc9bb6ba1b12388f0821a074018909f76944d9295b5eff73e70ac1b0e1644e3a40685305f8a0626b2f05969fbb4cae07c61f6213159b3471654a88ab58ec3a648f2944625820f6592c67126bc085dce216fa708089d4947ab911ac14c00e53782a01580fd967594e0b2b2a3272d590aa70c7a3f419accd33c1b1294d21242c739a3e8e577316c23ebd4b4c4d0577b2bbb12cca71841b54c0b76729320bce26dbfe5bbc017c92491762a6c938d4bb0099aaea190813a3a78e5685d83975050d719d6b6a80ac313d3018d25b9054b5013f832c1353401e6cba3fe527b8d2906871b79836cb35284725e733d8fb60e6a8410e5f61428a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = pass +expected_ciphertext = 99d62a49c06c371bd6d26ec8c497e9383a842e6374424085f3922951dd554e866a4593f4651c64c1ec8123ace1cc6f54674e685018b756d6d7a5d6ea146ce22f25743c06aaa95093177f25ca0be23e6e76f5f71a5b741a29fef9c82137aeef17392972687f24184bc0c90344d3c51759546dcf761aad332c7d31ec3e08bb6021e07efe3b8fde04f6d1f718eca765e27fec6592b94315e116cae292d94e72004bae5b6d5a99d03801bcd0420a459605498f299cee4b3ce6cbbf0178894b9e20a421b885914e436b7356294e69f1d419a9633a712771931cbdee3b1c02539e4a080ce2be2dffc33f15fff7d3368dffb2fdb4ad6ebccb71b5746ff2bb19c809129dba5cef8d17ae011b64472b38107416b88585645cb3c80a794febed9e0e16c169ed0dea7ef52c079ffd05e2cd3cf2c6b3cb31813ad0780be61ff258b53f04735c2a3e8ed23dde9d44b5e7e182d0bcf1e19fc9d7fe5084f06e311aa4cffe8e2dd79457024b94a2b0a56f2f6f3caadc4ca3c6dbcfb538ad58862306e63b50472194578d708e5456aafb34d4a31dac16c6e596367b636dbb07a5a932b863d86d3b9b9a20514c6aac42b135b98b747b6bf1e0ee53cc9d9ca1b6ba97cd4b029ecf0ba3fbcbbe01392e43593195e34442100017655486b8bfa442f65256ce79a8e1c4c0429030d4d37cedee7d1fd6749de72d187a8b4554756842f035e7e873f06794a315ac8f1b26a6357447813b60fc9d6c4757b696df2290529765e2276418a8df9d22408cb9b8b1b34da3778cb981e9d08c69e003e251d98651050676d4238698a0879209e772fd5db2e552c38e38a822a1d6ca1c0f2fbf8399501991606ece8480f8b5f84a965a0e1e3da39459b7e6adfcd4d4bfe27119a608b0edcb134ed12d5798796cccae06970e1f283aa2ec5c5d736fb7afdda1dbfce7f89015eb195c56ec23ba0c10ef7937ea39ed252a47a812e599ec99048c50456631214fe7e76d11d7f1e2a5ea7b52c93c9b810a18f71309b0ff7aeec8c9243bd8695ed9b8311f18022533f6f294e281a9ecc525e99774627628f8b8bf9da0308e1910f255494d9a349211d4172a2fcb7a135ad940c4bf579667685833b21b7232b818ce2a40d4a14b28eabd8feed6016181c591de5a569e3b663338b9c710649bc7fcc5451785cbf6c2888fc5e7cf992ec049c46bbfbc20f7b4da3df1cfb59f48d8e24eee95597c77a18243544a693010cd2a0b2209a260d6d7d5ecf8d86a57b54fd16a5aab3908fa9f4c4da42a0c4f686dc08dadd5ca536a80213cda1fb230ba45b45f3d6d590b17f6844f54132e6e8c422be287117d35c12ad0707c6daa0cbb0fa039ba168621c78f91b65f48bf23af0c84493c77edc132e1a335e2e15fc3830b90df5d1029c08afb86703d46b1b4e018b9234a54cb76eb906f2b50a414e68b59d44a59d6b1cecde5163684933361055e51337372e239c0f94940ac4a44cbb780594d3419df9a896e271bd2e2306415317278e1bf7ab91ada048ed232065b9df3379ff9cde44a16 +expected_shared_secret = 96e30641ea4280168da37291a3063342ced8e77b33b5415819938c0bd7264ffc + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = c55170fe0945513748c0ecc9098a02e9d51e44acc267272633645ad562816d479466b54d2150afb682b4f32265f1f4bced21caf7c7980105b08056cc4192bfe0da9aa5e00864b0a34712204cf6ae82dbad360a7c840b4804826c39a59ae029056c1b2542b6a589eb47c14a70acd1731bb0a4d657656915b91d696b2f92afd82245945c7b77958a5b6a3b6cbb179ab83a0f32591b757e8b68368d6a5ee63490604aae70ea7fb4619c91a455429a6b195214bd28bc717385d3cb8235991c05088c7939bf852125dafc3bc368479165438092b530bb2b869246988b8f85425a2a523ed108c6d2f54358580944d64d801078a4b621f58012f9d8a17a92ab8ad43821e24e2f87bfa844abd0c6b08650ab76d5397f2cb0060b31af689fc8612249d46374848f496b360e733fc991809da804dcbab14030a4bd18cfe37b41cad91a66a263437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524c616babd17a8dc7924f37345dcc32de04273c5a0ac038a133ba01ce2481ffb57ba153826a7cc4123570293c82082b6a75fa05031cc7fdbb9031e10ca94aa283aa26eb3546f894b646b9a85afc5df3b513db522efb340287c64492aaaac5fc25547129b56b9541eb0912222c2e60a11b9304692a749bb174cb47679cc294253b0f768a7872f698c23493fd908c9ff95f9275551b947bfe84780f86c1e0bc105f6cb7c9430369b58bbb07b3b0c87d8541618c76a43d52c98a08166e052b4487177ad222e6a002f7fa3f3601cf1ef0b4c02ab550d76447eaa695561118a46301b544b493c368b5b77ab17c5af4543fa6a8c682a46af39ca48046b1529684a53d0e492e1b8596f55334ade15591dbc4b411537c88a5113458f187a6d77278675b0c85bb017416b6e9543fa1b924b631ac1ddc5556127548fa8ce0c90125139bdf13428e2c7805607a44251a5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343dcb062ea3a039e949a7f151c8900484368f1cfa385bd13cf55685bfa4b959f8634ed7c437fc9c044b401683cc7482722c98583de24ead414c1833858be987672c557db87aefe4ce2db8a676d14083462db35862dc0cae95f88ec1f59426fa2e24e9cfc54813be07c98f78a87b9703276b455e15474d7a283d5738d4b639369077e7790dead3336e1467c871a571080004a91162fcc31d2912646a9406902248fbbf28dac4343b081c327743335b9efa4b7fd13d5177064a5b6e8065b64d8c6580b47e6472c8f5139268145ba7a23a02f59acf680692b20ec2dcc087a99be036bf7e9c8c0df15f168c508ae28e33d951740a9b0f0321e35cc01328b7ba860592b566cb369b21f51b7ae583d26652da729f07f5b8d59caec65aae42c7c9cbe73c68504f26670bedc542fbdc67a95c9f2da1a08e559797170ee63147a4688c8e101e5aab48a4d1862506cfcd297c7ea61a9ed4a54fd3a28380292fc1570fa2ae43920b0e940675b60534425c69f35bba714c88b3a6c323090b4c56b7f89963059f8ccb0994373fc1344412f694175c2eabea110e035bee6abf546396d79472eeda164bf49350f54c2e75754f502de4a42721b37974a8266c49b57c6837b38a28ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = pass +expected_ciphertext = 39afaab7974b00311d124330c72214db54b573bcd9fc3efbe3cdc82b4b680c4699ff19c1af2b0ba0fd7a2ca1016de5fc566a098d40dabe6c09cced8fc3466bddf7fd4166bf9f69dc4f8dd8baedddafa1c07371f85cee047165b030a99897eed64b7bf34f427ef1fb5ffa56fc4150dfcaa480385b86e215c116de9636b59cfb5c1485c1364bd6ee0c12d471d219701d78d470ca7b6d16d9bba3fd0610611fb7e0d13acff438b6ab4644a1d97814f2563d7159f7b11f632c3f5cdea5dcd4047a9084515441b5e16f22098b6d943cbcb71f705ea675544193fcf2c8b0f0457735840bbebaba9d6dcdacab820de3ea579e8ccad0d59ca19fc1f70578730254ba58fd00235e77dd346c92f4916d7bacdf6597232d18beabe0f7b4f8f916d661094066060b9a0383170758e3f5b2fe0adefa80a2c7b553f03f83d465a1cf090ea5f5d04410f620e509f9b7c81dd0dde465e4c52afcce12f5ffe58506162e888afa1ed8700741ec4d424fc46e1c7baa9d7da6a450019be4522f23088a239ef39d0ce1e3e46a8d7d6dee09450b06dbdd701cf9ca5b920bca236d0ff8d2932acc4b590b16fd314c8fc466809c06c7066dbe7e4716d32cc40d48dbd3a74820ee85b0e8f200b375ae5729b8a708ea902780ad6ade4ab87f8dcde5e9552dafd56599ebedda9e43a220b209932227210b744b7676098cc1a9fca1a325f28c6537d56e6ea922c6a9ccc48ec1fab814631b8eb8d5dc466f6b2d7f5a48a5dd3cc42880751cdf7b6649cb662bb973b0e0b88c95d8de90571989ed9e2ed115bf7f7bfc4caccf262247e90a7f63febc66218525f255329c75e957a6cd8650583560605faaa84676225cd42580e1a24fe7f3cbca951812762adbd5fc514bf094ddf9fefa94c72e22ace942ed493ef021a87d5a794f4c27ba5cf6c06408f79cddc81b21d416eeb01982120e77ea036b11eb2aa6f16ef380a90051a543e45d3aae0b313be0a9332b71db12dfafeb0128623553d69a30b967ee7894e54bc39131c376e73d2b947f0d06d3b5d35bbca914c8896a683ca39947247747def3ade0ee5a4049fbcc26989f792309fe1793becff2235de7434a83c6cb7e5519f8a7c67970d5acc472d3303dbef8fe7491c949cb8155614b692f17cc0ee844f7f0c3b2b538a70d9f3b8e9c698a77753616721c4a26ca766df1af04c8011472166ec8acde6ae95f002005dcbb5ff0f2d6db1eb3b49c258a23c9dc052e8d44a6fe08515537bf5175b7618882703160c285207b64d55c1f9563f50cdb151f4dcc5918f6d34c345160fc405931dd97f7e3403f5117a84a16c17077f6e13119bb5fed5cf8f128c50b46e81105879408ea5a90a128e2bcfd54c3c091633dfd9cc48be1e492d2615b8c3766730b7a9484ede6d646d3c45a09b52e3180c8b281595a97ed66c0ec03b66aa3a364926ebacb166b7699f7dc56f3606538db5128bb8b408c8fea3cf2ab0903fdfcdf5416c8623cc5a700995be6f0bec2ab7283df510d95f6ba323bac70fc058567daed0a06f1cc81 +expected_shared_secret = 47e54c85cc0e2503629a8bfdcfe038c3cf692d723d462bab733c7c8e0aa37b02 + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = d3b1cdafcac7f6d08082da095a7658b3a45f7bf717d4b80a3a050a04cb23e01103ffb1731b2c35a9dc23c4341976b188f5226459a02d348bc9d2064d574040147b41612914cfc2954e4190905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca662024335a083911aa53828d6d79c948425422c32ec471c2fa843b54f6731fc401475612a135aae4b146fa829871c0654c075dce41190483c3ef60b7336200a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0d402147a08a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb3f184d7d6ac6ef64cdfb89d1ce66a059a4659d8137dfb3c95cbc9e8d86e064cbfdfa50c68130a8d82258407bb7b926f7a802b53209f3ab78784102e88fb91e6311d496251f7b574aee5797e881ba1db16af40281586267d826c0f33a0518c26e6533e19ea0ebf29474a131d882a189ac03b835c16c34c9ae7a1c4d9f5159f85b8542284e0409dfb0876fa6488e6519867b5c53896867772210e95399a1733d2e78532b7651ca9704ac063df086cae4aaf65150093f27054f34e2849449c7680ef1ca1a0ac399a01a9b74484a967592ce85086230582518414c247bb7680abfc2a04a35a20a851b73548a8e4cfc2b84cb5ec24108396c28498a6614790d56bf8d1b9f9e40bf574c497218eebc06217c9bd361baa5d0715e666c2d3d299346a79be0bbe4b7ccd49f948a60438514129c126aa1f3875718922c5124728f09fe5437ae83194ddeb81f0d744fd2b9b59fc223e2792501b4932924facc16c1e5444dbd6a823016b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c59910628c8ca22b1138d884842c387b594b544e5d99784b06acc3b5d80ba81cd34739a20af11f7735d645d9ff25c07f8af9b5902524a1953ca2a58d6b796e3695a006ad6c703dd161c12c01b9bc995773c5d2ce59470c765c3f5401cc07885c77bfb3c15d7f766f0ec7cb3f601dbfc210d599093a21c87d82002212b06898a5a878d4ee913eb451dce14a1bc424838d4797ed14d9eea2473b304d6624f1725c820751a9d313cbdc79ac9a26548587fb41371c5f48a4da04d37ab7189685aaa054853f0491a0388ae4b7af4259969e29eaaa2b2eb9503518c7c53ba0e6bd20ea8355a63f1c481eb5e662a0b792014ae4c0981274d902759af794338072a839b05d9d42c1ebb1a3da33b54066d1a63024a3b1d1437b37a83bbe816075cf416275a6f58336905937105e63a1a017f87911cf0b41daa41a5dae3856a606e2a9333176628198b49d2517f54a9182e4ba877760517dc94a079538822251204b4c4a2382cc7889bf84923c09072f86bd1c5879ecc3a37678e6d031568c24012578dde5ca01005b2df71a4a0b0455a03afbe7c366bf1b086973038fb5debd793a303b4c867b611772733f66574cb0d7c303563c389b2f1b46e98945a94b142b2b0d647521f4b58f12326fd86286a448909191bc600bc7578b0169a45c071c77f280c583788f9c2aa1200a73431ad56d23b20471bb67a627a594ba9922b1ffb75d2d030432a954c71235a9278857c3010a8a8906c070b77060fb831842140770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = pass +expected_ciphertext = 6a97fb0d3fc17256c88c551781f6f142a05547fb8d0d96cdb0242069d0aac67f102232efd259c853d4a5222e4d8b9e5cfd7028afa9de9c3777669fa77bef10515be69536e6dba285206b1a924690cc8882178f04702dbbd541a38dd036ff8e6d81253e7e902c6de5151c04eb29236b261b30cce838b8748c3da04e524f3c71f8344235adaf16b54bfdca539be81daee0c2640a03e69f55f974e8573af1f42813fc32f99f31bd1d462324dcbefa61641e6eb2277a143ba321f3524307976d26ee122a758c330c80c91fcf5c7a7a5709401607f723c3386cf8314cef0c14a69b6868f117811a7c3caddf1935fa2dd230381eb62d1564072f6d3e68d4ad87e4fd2915d2fb80ab2f6f3b18e853dbf0d06a057f930aa61898f1b04148f5387ed19d6c2c36669ec31cce3974dc0717a188f1d2e37cc31de7b15b7d0712d33ff646b11b724b12509ba41735a771c6ccebbea8da3e651cf795c2131f910689f11a2b6a241ddd4b71605d794ac24778e2ce1d47566f8f68d22251b265fb0dd9ba211acd4652b509a6b412536f4348a0cc95a7c8bf736ab2b2a9870bb7e75af32e6b6ca5d318c5ab752234ee9e09f3deef5e0bc52fd7c8dab5c2e965b41397413b063829f194e9fc8d9a92f0dec9619d6d6aa8bb368a5a80167a4511225fd88145be368f210e1dec5cf94f28e1399a53612fd7d4003eef30a0106975c1d198a97055e9e44aaea6f9d21056ed983b54524eb706b89d7cdb6372dec8adb8217a214bc29f02e236530f56daf7966b31997ec4201be6d776880a5b0cd7a8784eba3517c2e7613c53c1ae23e5b1fe3d2f95ad0ef951e06e5a249d8225d48e70dbb406731ae18e404d4bdc2d7e10c43e62b7b18b7308b4effac86680f6a84bcfed751ab5d3d68f093800c1bc243a28ff898c66d3636820db810bb7b5b92087221b2afe6bd8e953694f87c38ea2c59c151929ac831b120c66de1fb05cc39a9b57ab491a7762dfb8ccebbe3194a993b4867c4d336a04351b30ec4d2f0370440acb6bdadad12e4d3db51e701aa49c455296e15b9d13cfa68340915d2f694b8b67b0f34d275867c3a53b6215dcb0c3654e6c77663524301d1e828a0ceaf7d2cc226da11d1cd78b072ac7f3ee14d2b06f8cbb9560c6d7e60dd95ea5d402b5de9e7b96b64c4accb8eece2a4bde33e8d27859d6fa6ff7b609ab159d1201df7734d4c73ad0a4eed2d80f24b8638273e9c0e53ec0b8272ed6fb82a6ec30ae431972f929759d000e4e5b801189473cc3ea318f07dc495b7b9eb7afda03f7e470345c9095bbfc00bd0321eb5498991c75d29731df41db55e24890e4beb84d5bd6666347a53f2dedc5c6480a93b19df229b8d7ee732e02c62db28623fb11c24b2de9d2ab0707e4c174acdc7b1ee8e287b62d1d797a3accf53decd3ec40fb57e571d129f1a7a70da324d094e51cdfe1a648650670736e0da6aaed753822e5bde4a2b69cd0c05a875b5f75148a6a65ff26c670d17a0fb598bff1643ba62d03c2bf9d1ac3d33c044a0348b762f95dcd +expected_shared_secret = 8569bd042465a2c4af628425cb102b15ed4f5feee16090e2234f3a884a0fa938 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 112b1dd09313b9a25b7094700639775f89b8d0314eef0186adf7ceabac36cc9292c270717f27caea51b1afe1cfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad4841b229fb7a17bc213b969935c672d0993a94ec170bdc8b7c800e66bc6514f84fbc81c7d1c9417b79a82e5b3980acc792a19c46d13a2e75a3af791beb401f7555793d94c0ee1b9e98a5b6c52777e537bfb287268ca9524a4438ad87a0e85279e474c5be7740b7867d8b04781a2436a8d343f62274e236c736dc3c59d5b326563b9c86798ab14a6c9a0e67b36db89a82af690da7016418ba2d6c435e39095bb81a0e49c01a73a31ec9159844d1a3eb233d16b932919421e6a342473a71de629477183e8f34b2b7c8abb7a3b6e516107cb5229d780b93417f9bc94c38bcaa58f34dd88835308c742875cccf4928122199cd932148f48a94c5c2252295890bb4645761d3c2c0f33ab3e1021aa56b573e9c6fdac37c83f678b97148ce573a244b0487f3cf771bc7b6a13fe53a6ba58854b87a67a6a17d6a301c85f7c061071b4ddb27b3f404dc402ebacb8254a0568d48b2d299bd831188886a65aea5cd8d987f6017a2f4392f455c2b4f9b63e6cc1a27ea38f2588b0f8086d7a5c5e4b05b76d2b8918820cb8851704ca6d730861b512fefb0a76b61401e23b01ea710c5e3b73fa716dfa6408a635423c61372592dbf174d6d811eef7c4d885bca5fe669233a141e43810ad10235cb59f824728bd7acf17765bcd354a493aa60438f07d266d728b640cb07d50275bc2605fa6c964614b2c8143b37b184f3c30668662149bc18c6038706c12f0d31b896b69a7d588d0004497e4808d8c12253987f000168ea758a5b32c195f03f23a07c5a546a6607084cf79e073bc6cc1cb372e385ca827c490a42d900035bf735c6242031b8332bc57765ecce4792706f1cba0c7cc390e7bd3595ab876c4e397c58fc325c9607b0ee39692c31730eb4744e967e7ff8139fd1a545622ec870516b2925628ba782cac845b2429c3cc0ebf7747f414e8d35cd4a91c959d2276404a5df4790f4363104e6a0d1d60a48b65bbd92b417b51a5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3c31637e14c5c0279cdd6386e20ca89a53671fb2f04249565491ac2f900ad380d1a68b67693b185f26a232aa1b43503398002085713ca4b2f94cbcf6e837b020404b7f519a2b520f93b901943c918393f26061346a0193ce9ba8a48b5c4b01b0efa231eba0528c5b38cd32cd5d22586494734fa746b411759303a51a12ec58b03fc99a1edfb1cb01375032054878a6ec9dc4425945aae387e7fc6cd399c90049854cf51b3db690eb78a0a2db04d05102dacaa9834620aba427b5733bf1d1693643c88bd265af0280ecc66344b81129c491b3998c6c70ccf03257c2d06115b72aec35b4c8774cc7936c578b29fb3b0a5c66709363b73f41b08db919cbe57ad817cbb5df62b7836af6ff4ab8cbb07c9fcb7e3d601b2117e6a7242abb24ea96ca867b597e9e9b45c01aba9b54d2d323df8b38d3d37b72c2790e1041037355f274cceac2714a92955b31c55d4903a85bca55b2bc22c536aab22557d912fe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = pass +expected_ciphertext = 1bd710a00c224ca78beb7e27c43a7541a1618fa3dc2615317cc4aa233e6169785f2b722e6e1c73d77d8ed134a6d56e3cebde5fd64b5a7b6030bdfa7a9c95960ff5d2c0cde027a437f272311bf4e79c00be9b0700aedc165d911ce9e3b7c75d9b4c6230e734c9d1d6b9a835da5d666cdc8c129f4cfa5b640bea9c1da52aecd5272e65d80f1e53d261cf0913ba405eb4019e0f9a54e99239fd8e247ab5db67d062cb3cad1d6e2ec8c0c8f13bf2db8a1596e16966e68454c10b9fa416441d15113da81165f2813a727b7a6b3f598311405b7051532dec40035ad088a5c598e104ef624a06a98f58f28f7fd22ad53d6b54d26449fb289d0fb6c42e6f5039eaab0fd650b627c62a57228119920435aa41190d51418896932e338c9dde3b0e532fdeffd03551d0e039940134695412f2e81a99c73094fbbf9b03335155ab2ed25f0a96d73fdc08b04fbc32a2e5486110997f25a7308d33aa8c051d3e6aa887b7fc5294ce8c4a91812c41fa6160e37f928d9e6e10ad719f3dd7ae18f6444b9645991a1ae8e2d7f284a96e652a7f40d7f132e681f6da4f4041ed9ce41de22f879ed09fb765bccd340345095642a07bbfb8d8d1854c1107200e0288da6790603dff76906b44365c16a3d05e5de2a22c3414ae3e2033218e918edd9b1c3275927df7e771d7b5b1c5e07953f3a30da668b3ed6d408b709791fd5ede9328561ec40123606673a22d496e6ddf6e5ee838a47528f44efbeb9718e4872fc6c63d8c9860ba2c1689958b77cbe94057b6779021b039e4c18de0b75702b2d9c7123a2e281b979b22d1e476e6941b82786355ebb6a76f8ead17349c1e5d779b494d0b7e0153e56e967cd4f5cc5b0f136cbfa965d323998ebfb73ab2563a62bd222f9d4113c16accce74ea94468e0d721fa7f5019c1f9d31439560a5bd93a071f696dec1d0f52f4d671767cf4e25cfc46f4eb5f6d67fa40951ba31ee8aff31eca1a7787c90a4ac7667bcdd66a220e2c69df7b7ec49f7d6d8558da91c4a05dfea6da06d774a420ada78866c2d5cdcf526dcd2738a27fbf2df61322fa7e8964da5b634c7bf19985dfe77a1e0683844b101242b641e7d0913b37bbf9d3f2bf3519c8ce95e917126a7f72a8c49daf48d4bbe37e9cccc9ee4fec24f47bb2bcf661e6c0dc9b2b1753d929430cf923117990e0f22b43a74854a2b3fa62d3618faee0b877061317128ec4553f74bef2633d847141ae3b0b2dae44605b97fd159532cfec972103342b21e6edbfa9f03f483a67c45cfa31d338a668870a26b34023004ddb2246dcecaebdb2305aa4b178c4ed57fb0e1b33fbe37f3246be553b68c240ae8e54b7d36fa4bdd0a0f7602745e2885c7a85832320815eecd846a08c0974a2a35542373092dcc4f7fbeaf61092c43b25616a876ff66d9a2f458955056972c5a7460a4ba22fbf65680ada0d1c9664e5747740c4fe921e2c5671d9c6e30374217578c769c3a8f089c5ccc9f3d19eea5389db458ca87f03087006cefa7f3669753fe6fb712073d267d18bffe82 +expected_shared_secret = c184e0b019c2db772e2c1ca6f97f47478d99cf0c4c5ae1406f51d15815022123 + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = dbf001bfa28b07e21adc142c75111b9785aa2109a795ab792de4cb7b6298a504200f8850d32cc44e54182761a1c9c9ba591a9fa6873a61025515b068099bb1e63751c5b887d283077f86b733e4344d13310ce12d22322f254a0e92779a87067d19c53c70dbb927e14e1f2892b5273949428eb4c70c49da8aa7fb87048961db4892a6f89f18f0bb69347b9575025a964047ac7bd2c7472838383a6072f8338b23aa07d6b7b221e18d4e3c62641916106694315a2fc5bb88c6d664667680df556c3c046398a88328421f32ecb758bc64cf246815a25922021dcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532dcd138a4c03e2ff5024c52bb486ba7665b27610b822975c412331ed6c98e66721daa1897936371113a4f17d96ea735a5cdc019809c3907c03fa950c00eba9dffc69a902151a39163f2931e1c0271d491562e0a87fdf7b7846c31151017ef08727dfb68f22a8585295659ea358cc1b85c9ab4d107413225b8259804b31850eb347e1fd37f5435617a7a07b15321cc204b1a6b7c30d67e91c088a458bef5cb704e6b662189a9c0079e224a94e21502c0f1a4dff6028ef6645cba38c0c86eaf673e9b2613620bc216914a9781645fc48e33cb9ea06182637439f1d1a19fa50cfd3b5e2cb8310229b74ecbaead4b079d535521b8587a2995fa9b8c6694be6e432343c97c16ca23bf53883e23cc38f10c38e54f5639b9fc0943a4f41cd0acc8db40cb12e644cb74b9d4b858f7d6767830b92381a42368476cf2602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859902d19822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a459c0764cd943e0b6a5b61b8358530459685e2842ae9ab867fa712172207e692a7affa872323779087547c3d8b89f368ce078acecd55aafd5305371a5bef24fb255211b2169f4543927c845a3049f7a88513a682303960c2d12bc277656f15738c4368deb70cff2a32a1d179f4fdca57812cedb21b356e0aa63270788b510e58b4bf613473fe931dc80a9cb8bafe63aaac3913936c8a939c413cca10a1277409250b5da321ee5c24ad3d093c1c7095fba34b81380e5da561bc039e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d1a08127db4cea30340b5589b2327988c97b78f003d1315dacb301520a11f9f0b4fb33ce7c0203ff11c6a66136c0aab83928c145f4b968783b131281f2153925dc13ad133fcc5247b595cef0f03ff0da0a429c0de9a54f66c03f1a616c7210b7ed3624fdd27e99f38472867a9283c6b294b0d7014cf9eb62f0d7b051b190f093450453c056081370b45f5ebc4c03808fbb5c6d8b659bd22612c2872de9034b11c6aa6d356b2baccea0f909da0c775969c12fd5bb0c8a9bed5172a9358e01c29d308636b5d668f5b2c9def1380ba23b5c84259d887d3dc4882702b41d99c72c800dd5b19935d7722610741a105c1d227c38c5665cd5a6daaa991a9868499830c1697fa430bf4f95b03004126fac283a167281e4b847eba8487b0032914edb0b67b1e320c25bab50499378115cb07a9000e0156c9c93c1d90693b9c22623a3eb15618fa1c470481c4cf292b7462410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = pass +expected_ciphertext = 56faf8ba810d4962b71cf915ffbb0c4dc4fadbcedfb4d7778d70d364c15a803aa91866c8b086db348f84680b08f13c45d0b154b68e5b355b43e277a6457b3d304f01b5dad75324aeac512ab2aa2864129a10fb287e12fba81843ee33def6c12dd9e4b29c170592a907d3350850a55addcbe92affc8515287f73e4fca3199e536d0c2e2b74dd92ce862c3f302621689d666b8dee9fcf90b4721818cefc3776f9b1195cefebc7a45d6088b3b588ce4275d32685d1c06f0065079c8a73dd8d8e7120907a141f189ffd63b2b7568975a21c90b0cc69f2120bc94e5ed04b8c3628aa1fc7d494a2b8119f939afab0e5e99ad377661b04e85ba80a62e7468ac3e90e4dbd11c196fa678d3246d69928a20e4b9d6bb0c3fda5d33b4ee8b8e8e7c651bde38a9918f9131f60f4ec5b5c340ae3e64b39a1c507b77ced606ef9b93246a204dcc5363ab0302726bc94daad4214807f33103c7a7c57b460f432b8556b54953e6beab1a116b6b73d38bf54758e65a236ba13f10c8abb4345f336660b215d9e43209f8b85363342a930d8d9f229765258bea0d520d6d9710149b26cbbb1929fee006a63de21194cfb90c32deb5c402743c4d6643548e82071ecfe64e6d0a5f333bbfc7eec513a7e4bb5f16f563de4f45df83d220b8df76ef10c750b90f48e18a9fb7727dd64093dfe9fb6c381f7e19189200a53efd6e1d4d534bd3ceebbd3021e9410485465adae7340cb599a987f6792d9c8d675a12debdc06bff40572eab9ba1d405204b6fb7f87c5fedd49603bc743082cb3752e8893ae720668481487e86160d590422f6bdd3ac742081e3ae4fa0c145c795281f0f61cefc18e79fdaaa2d0d6cbb06cc0e4b9e7b3c0c3b02d2d6a9efc4b61f0156d510ff5effdd8fb74b32acc81d31dc38abf0211ae1ae1669f2d7753d209e00d9774434291a105695c9e618800cd518591b1facd18ccd4939b51a410c1b3c0e3503a0d5edaaf37b0b4d55e33aab5ff93ba38fc1ae300d42f1983cf3367b0a300817cb79fedbbda6132e2fe9f815f5f88442ab6d01d0eecb7d8185762d30fdd94978865dcba58a6601f407e1b3ee3c3fddd40439a47ae414aa37410faf9e10d6b661d452b38a1091781f3cb0c7236be1ee528f174c58397fec391f7c02a0627879e943e317a8cc075213218354c81e73bfb9f7c8f95e2953872d42603c844304ff42cbe05da1bcb1880a3d2d5858f79390ca5f60bac06968c5c0b9e159d5c49677f0c8313701579cd2fa921e4e4fed73622a7e783a9542653e000e530144a60622d79a804ff48cb933f84599b5183e6cb93e257de282e386f6b211f093e37c3c2a43247c1e6d97686a5c46d02a5e8c9fbf611f4a0a308f15106e9561e8c5a2b1c78c45ab0d4440972dc28a6d92b5786d5652190bd8f5460ea8d0dea988162fabfe7597a5deaa75e3ad2de1d2172d3147d3332f3160361b41ee990d5a89b4b2d27e97b2d21fcbb3fe26e04672366bb03c34cf5ac6975219297d3d299ce5852c6e63a7dbf632cb14078f31621ee4 +expected_shared_secret = 6d72e23c8a4cc60b2f14adc788a5c480033bbf6eb111070912bc83ad7b89280b + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = 2df84a0272c13da5a495942ba848ac92d302a98a3e55937b8b1b49fe588be32a540ec90b5cebbd90d1b80dd24d32eb85fc041a7ca307e522b8c5fa9c85bc258c8abb9f2678d29569f313a1e660a2454730261a6766945ce42c140e5181c68461eaf12d1f185c358233b9bb4902fc5089f851bac83ce3f07bd7b185ef08626d7029129703334084375bc5ba27ba023ca6722319a916baad529715661e3a413c8137cbbb206e313906df1ca77cba73e5499f54fc53047741af2341d5623278f76131ab47af10bb4dea8f493b6c0e4829ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d02d1131e493da5a0a1117b41d4ab3db35a7a2e95c6055ba70ef159e7aa0dd5452598f91477087bef1396acd48e747b962205af92eb99faa809b4bc47eb93bfd3860102d4adcbfc39be80024550656c42785a6788c7a851b107823a02a3daa4caf25097f1f9afb29416dbb360c4a824e3ca2a30e19f94b805de181d0a028e685c378dcc225112899a6b79869109ca4b094909b21042c179c6cdeb22564cfb6f89135022fca3028caf7abab19a4045dd5a60721c6bb47ac53e40cd932511f2e5473d3b4ceeb44be1a00e090a886d345b13a58620c49ca0893f23058412054ae5069c1014361cfb0379c2215f330abc647114a3c597765fd014c64c8c1b1b45b3bd02be9d5a55b0cacfce297581fb48fe0256f4c0cfc84aae1c542f36730e5f10795c72157c653210686801210418b549a7398ca8b7c70ed007cb153d2a55178ae23a5b095ee2d116b9f3a1a9f19faec40d75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c6701368b8ddc219a9f2295e6e01d22c4a50bd08179a08044b702ffd786faa088f867b63b951a92751cb0f839cd554a83745444c3bb88d3609a9a4bc2e0bc73108a71cc7534217872539bd6e942cd36a09aa0374a3894d279a1f7c38a56e7c0298948c330b8c3a5b6aec3bbdbb87384677ada78017564a7fe40c2983a9ed3acbce5e29e3a78502952a9540a44975572a1512b1d4284d9bb528e538f43a15216f4b4f2a5208e06c43896a19c416c99c3b677564975948468792edb6532f9b0567f407fc6d6c302766c6d1373bf78a18896188cf20ccec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f314827e0b24539e2aa91123b3fe42308f041dfb6c876d079d60a3ef5735ab8a36abae34f4a12729be4a00f753c7e4699572375e6c7b037948684206c08a27ec12b26f7349cdacc3559ac29d5cbc35c310870597e391ac4e4c02991096f37492083bc1c43304bc3d5925843622494c735942dac8904cf195387eccdcfcc8a999b6d1b744a542359e6b167f91022be1660bbd218a6a6861aa17c57152552172f38b43d5281956caa77daf9b94cf60cbf08cd9d9b4c1edb6c4a17bae3b36800891910c280c3e7cbf4aa11f33a7c70e3b419c2b2b9a64709c31878f913fb934d77b4c36e329ba98b44f394631e0a289042061f527d67446d6ab55ce7b43ee1080fbae67085a2a03b36cc9ad9b5b546156c3c5a79b092a67912a19575f6b5546397c15ae334b451c3d919422f28b70727c75fb631a2ab012bd5971b5b2b75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = pass +expected_ciphertext = 4894d82e0c293e45df99ede632043a85e6054b1611e5559a4cef6e13de2f1a4900f0765b01da4ccbcb823fd715242eaef76bfca91fe70349bc1c24b265a0d3c8294e1dbc274fdf5e0e14194c418f5ebcaa17e602986608b1a7456713cca5e121389169a056d1ff870c6f23d44c96c2afa779fefc28a9439a6f17a28c76c80b83f54916db504d15c3d871e9c31da20d957a71fd5553c7b2478859124f74a5bb62891586d6641cad19be57b806e59ef42790ab89a0ece8ddcaa718e965c7cb91f7b2e7e8bda3db23a4f7281d0ec15a6455775705d00a6cd2a6a900e4cf6f584163990c211a49da061c2174444d3794e76fe271e7dd01e580a2dc34c5feefb118fec7bbe3d28505d39713b985a5d8391589ca29f68834db1f5acb42bdc6ddc7fef72b0528c6aef837ba5ddbfa47638cef78adbfedbb93104a8a8ca1d121038bcc3cd29128b8cd93a69872d21b00f64e0c6f64e970d0d5454f08785af96a7f3df920852456b51d1c6559be74ae8b902f499e4f47bf65916cebc9b092939b3fac9097fc29e33d9c60e511763c7d48d05e30db42845c102ecf542b2296fd448b4adb8cf6f3a2b1ecf59477357feea532f41013f6f8494cef0ffeba1c7e88dc31f3a80e110060f9363638aa577f97d56554a9cb48ccefcbdf211665ef0d19c0e5667d4970e46b3a122fd9feb6369ea20dd39bae8ebed4f2ebe7bb388b2c38abff8010403ce5c63a9ce090b2ac371587353fa892cb221a6f104c58c0f24d5071a1a3f2fe15e0936de0853230b8a8ca393182276641286fc393264b4032ca117ccac3b8ab44660213cb645b0a91ef6f40227f13ed27c79cce843569a5e6fe0ac49d1aea0508902f33e3b4a4ea6a54c6e0baf40315291a367950b6bd7efa92d1051c135de04f5e2f041273db77ccc0b6d99886a88acf4848f5c235534ee1503afb3152dbff0fbf85d36aa8854c84c9b4403bab1cec6de2bf0682dead6a5aa800338aca87b7d2627d26bd842ee17effdbdfe3fa6df0db28ef11f01b0a93fda3edb75fcaa9921068a4c1e7d96d99864ddce1eea3f4707abb56bc7a8ea6519462209ace4535f2e119d37e24746e9fd3b56c078f01492b3f800ae10dc633d0f64f106dac5c60d928cd3e15097b92c99a5163ba27d5b0961cfdfb49aad6acb76e8d3c09ae9c3b093e887d1ff0f79ebf6cc2f1377bddb95a2269d18781a4e046fc5a9d13b366906edbd308b546d7584c9533615857680a22dd7865644d8c62d27f5585c1f8699762f86fa3f64662e77157793a33f4babdcc657af6de6267ee3afa991c510be7af8a0aa0b154d78646f0e5df267c9a7b0e46dbcbb02fee8f3c53b2f5388f01674c21dee845450f659bc7fe4776d515a99f248df58bc24819857d672dd2e83d84ef05476ea6cba94b0587d85ddf6214873fcb332b98c087666bccbc8df96687649700471eab9ae063bd544349c5d39e1d43363802d8fe6286401b2ccdea2408280bc53e0087f9905f13c3847ec2687897375c8ddf9de7aeb115b712fc8a7ae189b661 +expected_shared_secret = 29e6b1edac0a9aa33066c113167e42c64d70215ed04963d8be2d4c2dcd0f6589 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = fed53d194419c06b92e51498ac2601869a1024eb0370ca3a420c48a765a5b99bab88a759251cb83259a628603c54a831ac0147f3a97b8329474258b7bd6067476605a2b2b8311252fe54565c865e2dd96ea9e43b23121c27ab02c348310acc38d9d583b0d8105dc87896c238069c689027910f9bcb5d29aeebf57c2b9c78f76866768c0699c6bf743c0b43108c128a5277f39b32c351926369fb8754cd0197eb9ab602f391c4ba564be2c3423005266229a10b21d31a7cc3d40c2e7192cb6628afa692d3e75aace66e7bb1169893c8ee45bda5560e7f79c711d32d52c0c783eb40bf8977c3063cb114b6368a8d1486a86cb108d146a648e080751440f4d8087116701987c328d8547d0573f8c03d321ac07138a60954297cd832dfb989fd99aba8b213e7501cb3d25b384c023f66776efa3ad4981037a54400729634a782adfc24404bbb4f2405a27a8500cd79e8521daee48848e485f53a28de91089d849ebfb54d97d0cfb3cba46a27438f426eea1a0122f2180630864ae46cc5f3a828725cae89331d540b5b3633eebc0228000d75908f21277104d7816f56854c3289ad1a5c72c1655830089cfb9c90b1306724cb2828be679b989a3565758b058ae983c1ea9b71f10553795537d454eed50f50a40274592ae165c846d85527e479e3fa8d8865047bf68d200287c0a5b8a6a78c4769bb3a795979b774713a522dbb723f3628f2f4126b639e3b4c5c4b076d321a208a123d82852aa0db6ff8457e745b6b710b396c8106e635a379e22c59f17df7b7070eaab38d5448e4ab67e6b21078d5b9f9979c6d7365cd1423cef6b4c2b186ac6b792ef9351b6040f423ca22e7a1455a0473273e3b53b92a132d7c44556477907fb41f981a06cac9beeb9655fe90c4fe93cc33337d78294f7c128ffee82b0d4211e550342c599c9932a201f3cb8bb253a0559fd667a3d2cb46a4936f5cf9c4d0d105880a446066ae06841e12f259e4e6220d932633f77f9a6b463e180778d53c37e0bf423717f4d476ecab6bfbda7e461ac3cc9806ff4b38fb80c0ac9b0dcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f53816d79c6a1fb40f1ce200334a7e74760999f8a0294c3029bb23ee0cb81700b95ba20140cc5de537aca62c9808240e74d508a93263eb14b7d202a31ddc2147747192ba1f38932538241ad1db35caa40097393038957b64e716d4cb3675aa9ea46257bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cb62c702165c74864c3a7ce67d8af92eb78496c4e8eb78b55db7963b016a252a85e655c95936d6006bc07ba6250e458a387bd7bb43a3f5a16cd8733b66565377c1a74d5488c1a0dbfd7a6dfb474eaf29fa80aadc83267d0b98eb7a8ad3aeaba977a0a5e55b8937ab68e385f94db13fbc6c26bc23b0b8ba331a578b99b493d875f206c278a3b4f63e156fd386fc13104d6dc96ae9bb3055481b846183de71eca09273e58c466ea225b1824246c799ab8b045fb844572882299bd6f1b2787e1094bca102fb20e0a274257062385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac0151687859b155ad62a8539cc6b872aeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = pass +expected_ciphertext = 2f2b7e105dc744c34852481001d4d1eb1d0bcdef8c5845d58258f6bf6310b2edbb26de7891a00b6e217fa62ff257dcae69b6651ee5e074ddd61c8a17946d1ac239e629bc2c99a3076e97cec64c5a626cde2cd58e30192aceea1d0c743ade2914df45089b6fd8dfcce48bfd740d0bbfe76572e2619fb648c2c9abbe128d3c4154c2e95dc29e3f5a362f6e7a54c5a1c903963c5759533b9a6824eecfa1aa486c5008c3039fe220739e8fa5b135d0e68482623d46f4486e9ec5161c070a6ad330027316b5b7fa0a7d6f46c4a18460259a0185f63505442053a356cd3866e2d8652e892e9d4ac7a87e1b0beefebb3ff94751d7d82247264c6701daae5fff0860e72d7cd26596e7d6cf4e01c0e5deff512ad211e516db0a91a0104d0f693fd924702ad578d535a024a06220e24110517c0909c71bc8d1f53dddb4d1d00d87e529b02081ce5ddf7db06613e6af9fe774e81040f37b00e7408c9a6583c273bf7a742d71f14bcc5b84aab2ae54217891f9692c57494e0a13c64d1434f9c47de6677947de61b092ffab34d05488e0277b5e8c29ea908c92ae68ca9873057cf0ad0c1e7ec0f4becf830b8edf3f6a9f3f06850a3c94ee0b62a39efba961f067b2c09d6b0eb774869896924620687037d052ed339853446fe3312c676d28e5bd54f22dc080961f546767a9c683e4267d8e0b412fca766268aeb72aa35111a5eae473ee808fc143113adc424fbf120029493bd311bc6c0f5084b371f20c73dfcaf52c77cbbd39fccfa4c1b0ca5ca1e4002a891b4ca6b0197c34b3e23b001d6367208edaf9085173c81ba7d25a139c4bea5798f4d2fecbcb46261474b1fde3dea181d8b0158f18297eb0eb3eb493dbb5de70543db4e193ec0eb79aa0097729bc8cd5d93303cbfbec0b892ac9f9de71c349f651c75bd327eb8e1c1e3b9c2b6e2244693d000af2a37510adce9e542c4b455aceec3909b1d3d0775466d14e185135b7cfd3f2b5c7d6c33d4def0e55299ac30a129c79e3d66ec9edb0ad0001fb4e18327aa3428659ec4b2ea509921eeab807459c72e214977e4209b294b9c105aa88e432ad017dc2698291ab51304fa00402a6d0085626ae7462ac4e953c6d9f590c7d2593c25a90b9b212b71e4882a4dc449bacdc0a5b338c5712c3d6865ac00e9f4e059d0fb87851c77822f17875563484e3aa7310039fcee3b6e6fe6560a925a1efb23852bdecbc7bdafffafc1c769cf7f1be11185cb0a426f49bd4ebf60e52f6196ab216ccc5fa5ca40b3ac8626626de041e4e14270aab1339c562dcc40adc1de8c3e184ef9868def9f469b035c082a44764352fe03db55beba995197d04f1ffecc5cfd47b31be972de5db28137a6fd1d80a958d80b35d20c6094f36c6584646a644b9357b36cf4d307165dc8849be47363c1c1d7244d1d4bb13f143fe8978ef5089b38966ad6961f2bedb2f51d368798b0b3859a8f165edc5a02adecb9eae1ec60624d523aacd6da4f2ada45004f096a6911227d62e2b9d6ff277e34beb6d2ce6ce428311b500 +expected_shared_secret = cfd1b82181543656807880f6e2576f0b095bf84629b3367e9bdede24662ee42e + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = a0e473a9d639b1299251b46d07c79c0df1ceb995a968b5b707b760d8bcb120f6226ef5b742f34548902a7c73338a8cbf8d6b02a83470874b1ec5845dcfd3a4067c420f8485fae1286a23adb7373b9217c6dc173748870bfd164a16d62a3a6608f5e2b7fe78b92364a4b821967db45ae29aa1b11c0cd67cb4299b32d263aad7a26eeb3a69ba56790fd806abe3935d82487aec3205a856b4981e7f53b8f82a30d13c1b725b1418607b6619b0e8a8870bba6070e33545730182fb5f6f9938ab2ca68c50719fdb472a88384ef210b0c22785367dedfc840979ab758479506064b7971426d70af9a95e7d585dc8b67d4ffc2082bc45a4fa9b4fb9541493c3dfb88fca757eccb50f1a9cced9c046f37062e3879e13958bcf063041e858810b057680276d2ca12a307f511217fd626561587617674319382a4a00ce5e3bcfc5ecb5b3816133910650a469ac663f7a4a742ddb87c4e5be636213880c246370b1cbb8adaab6bb7e1185e1f95c945bb001a0210cf56f326b35051b8dbe85245f9bc6d973b39afb3a3b961501862b4caabd0d55693c201390f48fb7511990571985764be7373a7fc4bbd5e82b31f52494b15b6c2c8b5b593182028bd7ac7a40fb446ea756463c396de29d0fdba2569b9001e169f7c824c8a42d313a15b682bd52004867837344324e2f91a06a4c9f7ca447d6291635257cb0934e015c1937f732c1bba2c13591ccf4add16960b2303476000d984a8fc8036772c3b7c5721261387ae535129a7921a1711c98103161a95ebe16c0e0a28555dc3598cac2d701a98ca249801a4bb10379a5c29a1932acb6f6c3d040639fa98fa7297c6d453e35587488576db9bb2f9d1c37f8260cba3ba90e4b779867ad97db03ff005ecfe3470d2c25d54105ca287a9e0c039c2a2b71a1cbc6260d59a268d60c05d61202ec336cb8285b41a043bf58949df50def5937bee1af32d174e8fb463d03449ba747e92a79a1eac8ded247aa0a50821a16ad4c9f533a0fa24684d452a71df461aee15cddc2185551112682b4867c6cc27c43bf835432cca184840b85886a5d970e9f515f7f97151410c401e9baadf41ce2b8642313c295d28587a327c41c24da18967a6426663642dcf389c50892d6847718365cbbbb80723c1397b90447b197842c96a141bf6cd317bf12bb64c664fd237e886a9f793313aab15f668c91c71149c4b90b35b147f7c34b8ab6948799897855b22283050b113d64a60aac739948844a9f99c448d21c414425d77560670c298f493d891128ab1665d8141d2b1c8e67950a68255b7f9376332b1cd7c6630ac05ae7c127fa7acc35e640e94285e78661b15b21685a36c889a8cc890ce53c36ef23c2f17cbd8c31351beba827949f8707a05324abf05aa71857bcbe690405ab0030e648fcd3bfc0f2ae2c627e04f490bc3ba237059ab93085de218029f056b0f57abd342170f5b16db069073a3c16bb1c0bda5136952919b22ac477ac2489237bb0869656614e4ac248b003799c761b2ba5f2711b24a01419c88937dc4ce745acc16c796e0123a4228ec623a2a4e059b80b72beb1329c9204b6555b0a62c14df0b19b4a157bca985090b428dba8587b53ca2714b2ec2a04d306b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = pass +expected_ciphertext = de60b879b315048087f7a044acf1495002d4d8c1fe775d9f05319b141573f998398a2ec9e0a4783497271e5b3ebc33db67f59b721586c2d09e45cdbb77e59dea5f83c2e4a9e7fad83769ed0b29c89a117ff7ef7172a63dbbaeee3c1f6c6ffa92d69cd86a3e44639f718c0b3e713c17449b0ecbf674c8d84d1a33d7a96b4527c270c206c00aba5bb834930469d7dbaa5019dced9408b12774c4a36361a1d9bef01b95af6532ac982345cd45f6926017bb2189031aa64af89b83ac99db3fb349191de25ea482c88f3232d6cdbf02e445f76bc0aa19f35d178684c4715284d52ca3063e2129dbc757ddf36c3fbf08051bef13c498feddcc27591b69ba34be65231e6e4825e28e6cc626902e1ece7a4e08cf7e6f029fedab272f79c928ddc22f78113b9cb94455afbcaa7b7c9a50c1238ad2eb31adcc8a88a4c02a8fa3d90ff586f8a45251b485014a4e8f154181f5ec04f6ee3de1d7c5a0088d4ddb1e9563dbcf0f9c0f2576d87017cbc89a491317f388f06757bd8cb8a34d7125e2c66d7c00602c785104912bb52e9ef681e54425fb384cd443837338cf3f093ee407f3b5989c2d8b7477d2765c1cd97a66d46f1dad4a837389a1e09d0d4a6b56762efd058eecaa8aae088606b8543dddc23dda1bc5a4fa76c94755a7f5ee314ebd22832cdd17b05117919c07dae55aa8419ddbc9ecf4747e38a9780c2cec7e956a58687b082d7d873f5ef4258392b8713b1728a6e295eedc87cd848c3f8fe88340e2a32629a5d373512be9a46b2f6b286edfd3b9bed40c55dafae968340f711d48ebc28aeb93fbcb039714eb11d698a5c73eb3058a015a4d0e01678742a312b8b9fd2a6cf7eb26078cd4c17dcc903d4f51bba698167882912c7f7b6417d30ca0f074c628a6d5b16356c813f592e568fbfff725900a8313fc528bdf6beb60cc5b445ebba573ec49721bc9aeb6025b1295eb536f4287c88d3dbce90d5dca6b9c27a6a879f0032e01fceacd348c92832003bcac4e766888f849ea6e7636687b766ff8bc93a94a7ce3d2d2c8236ee3409404c3394e807c108c3f6e17d69fc3dd5861f95e959049545a4422957b11c65ce6cb926c3df73104d19f67589fdf09b44ff4d4cd0c7056125df52ac7952f8b6800652ca91452ceb11de8ebd09b52dc4bfe9b60559ba1547fbed198001637a4c8abb24b78964f461f910ced77c71d114fa44e7dcca920522100c8470e5699ee58338e715ea09e257f74df146e9b2083b394bab377e472b918a8e94274595ffad4f27e7660f5e29f2c292f3364b2bc758f741f11e215ed45427c5f512b7216270513524814b931f50b1b59a89752318a23b927d432b2876bdc663dc04cd30de442ab832d3e20f77ebbe261d64bf4124f64f6aec0100216f453420cf66a65d4620bdd74322fd270fa502c7f4c100c39c79edb4c6d09d065036d7cdbe0e8da3298f65408f6b010e19e3e9990f46793e32a52713991a9b88a3814a80ae52bfeca0f60388eadf5c51bdddd5853a591d56f9008e491e11710f2b722ca +expected_shared_secret = f7331b0a4674969838482b7184fa92e5246f11f5b5e284c3e179effff7eb6329 + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = 4d960c98359f5719b20dca6d1e2916f2829e73f79b55b468170b64f2f8b0c788796801c8ec244e1973c7e033b768414c55d43079b2711bda630e678b184a70dd161c4dabbcb91c07fb634620d1450664a444e82d22a0a4f54ac6c7c02d74120b2ce205fe49a139b9c8194341f4295ef126b37f3b22e35792a8853b60eb3f7ed01314491c4451470870a5ea5b1d23442019bc1def547fb8935ecbeba0833228b8d7bf2a4aca52436a3f993f6164666ebb3c38317bf5b48cc7182c00d58d4a095d0fd4c60e4229e77803c4f38f22464c7a4259e45ac71e8ccde6e5738dcc798777317f9847f8357dce21b24ae462d0465f1d58203f3b8590d88deb9c6df4722a1420a9ea0813ec3777a6cb11ca0271292b6c662a870c292291164004299c82442a8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c053203f265bab420eee2c95a5960f8a87c3333785e1b89ff841a6aa5aa964f3a853e512acabb60e29c3a4810df33830134c0e49bc5e1ba41b07b671e1ba6bfda82576406e6da854920a46914c8ea986b1d6a0328d4a450fc0ce698b9d16954aaa0c52b6f2b5ff7b5347e84c3af403e9b31ec180238cd5af96f5c6f0d3644ab51717f7255ad6551f44378294778937cc56b610680704bfb37e3ccc07c5276777e37f36623dec8225388c3a5a2c7026eb902c63260ce27ffe657bce34a47db43667b9293e04ab9677b6fdb0b0a429a4435a9f5624628a2c07bbfa8afed562be4233019524e67cae6f955226437433bc59835561c462071ac38058c145787c242d4b6dc055170675190882792ea49726dc8b2cb638763784d3c23e1791c93a55383a8c4b59643626f8948d228b670312893ab3ce5b123401b1b24432545889d4d124d2b846070c1663b87a3475c01adc4f4df286fc91c76b018c05b5a26a696df86c4b1fbb2ed3050cc9b54ca2786839f854b9461655972fe21c3c98007a693a4d0b8aafa3ab73f1c411dd283cce59528477b6e089847ce6518f29b523602f80ac573618070bca649efb84fc3947d43b229e05682914c153809521ec9b7978a6bd667f59b18f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734df18a218c5bacb364c9136b8e055053567a1856c21b96a1a2723913c98cc364bbd1fc4edef37e1853c523727a6c677ca4c82ac4d49238e1b60c1531d1dc9835c4a96124a0011c09350353aac4568a84293e8666f6016e56c38371489eddbb3df3e53e6767bd01e231eb122f13f59a83a35101844ab389954e8068f6d7128c738ac1774edc6465eae8ccbabcbb41271467c407d36928d9e3174c99665e3a9af0fc1b2733925b254a3aba050ec3925dabc511427c0b2930bca63ba7629366c1ba620cc0d7090752157b5d70c098745e37db7316056c7bb37c024226425107da8ba0e9c30e2606752f31a017e50a0e10c05332677ec851eae14f594a55d07392c23a962248ccee1221feb2c8f801860892b33ef2247b801e5ff55ba97675a71037fd133133840050b8b7914125e9d30165847319eb1e483005ca0bb8338b75eed618c47408d0260ddfb1527640a148f29e64f65fcafc59a8715a8126830024767009bad41a3385c0173be51a35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = pass +expected_ciphertext = 9ce63bafe883f7e6b5932e071982bc35f643185589ff435bf663b9fe433014e07285e8be328729d3d01079bef62ee178fbf8e7d9ed1c2529fd9912958b8f120dee444881a4634d0e96973b8c47c004b373d513ecffc97911b53cf0686fe2cb8fd33eb7c0f50fd38592e9b7f73d119eb8b7288e7259894812acf13f81191f5f383279dc7c05f290e580f6e0a2e488a002071abbcbf2cefc4bcb73eaa86ffc1314e120b8a96edd6c0ee4faabe7037dbcc63d8dab849a55a35f39e75502c961f1051008ce4c9b0fe062cbfcb6bbd6d99ac1cb24e979d72d39e057233212af4afa92a3284b1b272509d0aea213d5f18e5ecee943d90cf8bbdf9061b7da7329cf363e54237ebc2f07de66ad90cc12744a74c6e5d577c8517e140d64bcd40018995143383f5ddad2f7828163d25f9c3af254119541fbd304b96f70a8cc9822087cc2ba3fdcedd9529cfb7137991dc8842c5cd1ea2cfa9b831f507c04ee4db010780fd3703e54fe7748597f1574683f88c3a0e8a5bb36695b7c5b1d6f566f318263f3777db8f433019b287ca1b8406e7755426e593134880c908ff7cab24f2c8a446dfe1bb1b51a546ef9ec43ded91f7ec7f1f97df2ee83d8f52ac9e174639fe9591deb37b9d9f9dbc9d1be6b2ffa2e8c4b5eac3332ec069e9cec31bc7d21c5253bb20ee61ee701985a8a73cafb73b479cc19ea62b998eb85cabb5b4ff462088255ce5cfead669cf5e17871733361a9e25392a8baf8958bcf08da7bfb12b3b174acbdbb8c9cc1a87b2f6e48568f19b1ccde0e9f59ef624dd525168ce64dcf1e63b0c118a077cbd7b48144234001910dda0094e21d0abaf3741aedffbff4dd92d291180c67e3a253799118eddccb6033e3f450ecd84637b563dfa9010a2c07e9b4d4d55fb71c7cba9485b612561ab34566c40575c4c41eb9ec7d0c08b100421b7e07af4c864b7d8997fe4458867ff0cfc02b001250eece27b8e8b71a1a04983193520762f4b7c4d2fd289af45f1316f89108f19caff5703960efb9ba42823a6b9d9aed333e37e5989c8720341ed60f4b47223bd313b56e6160fae8a3bb56f97ab1092a7e36e2811226f9bc14d63bd3f48db4fa2abfdc2b7b8215d4c5afa301783940d3c9f8f0b48ef9c35b02e272a7725c77af66a4c3f43f7da5852569115857f7036f7fae04db993d6a016913c8c24912eb8c6c68159059fc3c3a4dc6c47da86cbab270506651e2f3a2fd268f81aabf83239d885c886fe85df698f72d019aacae6d59eae99e2e1b10e77207d047659b00bd0cefe7d675d7b4b50669056e536539a0c29d35633c6a059dc09abeb473b99a85b067d665374209a5e2b729642d03bbb9a41df15d8a2f12f65d32c965c0f883c6acce98ec4692cf48c55c7cd4e5ccca0e93048600b3a37fc6b2cc617f03926d033c2b6a4255968cf927c665c601a9a23c58db533f67f65e6b501d42ac65365e14c0180349580ed85e9c5c1f4f0592644460027830ec2470287d6ccb55ca108d34bf1d373f27e46b64b848834c85fd585a239d +expected_shared_secret = c89d62938a5caabfd5b30d82ea88aced52ef5f8ec0528e59a654e1f6aff1cc2f + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = b49b9264faafe731c0dee965ac981965a28ff907ceabac477e2c9b6dc95aaeb0531cbcb65d8b3f6251be17ecaa89a5b57c1198ea66af1f4461b91c360e4531c4d49269896107f10ed1f1070e68cddb2a4e06c387f3126087a71a366a250b450be1567dc957bbd034b66ab65fd4eab2d89b8481ec2427a4af3c1b861c799263f492779053a0128508c86ebd6201c876bbe8ab8053b790314047a1901c9f327207b2130be5bce8504bb03817a380975cd81fe0c0416986a7b74a16a21146636abe4d2b2c5c1223d39265a6845804d49e5f160abfe3ca21a345b5d044afa5636c37b976f2894869bf4500c62ae9941b9b3c3e6064fec351268243fd75bf287cae8aaa9aaefc1cfba1032ad2623a6239a7f834a4826f86132b59ab24efc9c57cba929a64ba90271b987bc08a913298911650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348c6063aeb0bcee9066028b3340aa147b09c42752cfd6d491ffa497e17ab6c0726aefe59c2577764a1a996fd879e58c23f1c0ac9e9372b3f0be42c829b7b09acb722e3189a2b3e72124895ccab565dae583c6c76c34c2c0075568379639869325f6e92e0b91a2d4100b2f4aa6486b756cd521e1b781a964a21b8b0c72637a2e4299fe15c1ac275fb077cf42f36453e7603c91a648e09cbf128ed188639b7247584b333003a2175bc587925111654f24680c540b32643b035ff38bb4598785524504ebcb26163d513867d74744c8b562bd48989b3a328374a125ca05fa962ac08b0d22277e578206a165a9e3d31a084b4492c664448aa62986b55fe8c8420816a5a9c035644f592969fd0951b6e9aa57303d1f9927ff6b3de99263e2e11cd8317cfc899a45706746e9850922b9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc56285e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38c807f7274708aa0587f94a107089a99694fc627291c30fd6b0430eca692db54a96019eaf89635cf54f579a63048070b7f32dd2c32a18e2b7e8400344412e9dc5943bf3af11b4aa6c328499da7c220670958a22bffc89b8f0091c8665b6605571d8a1b5c934ce4686c7c047ae416bc6e39b7ccc92cb076de94001374217e9b8820354351cb377b4f06b7fbb69f64c7b48f781ded2cfee998718d875eb94866e7c5135358ea4ec92849978438c77cec1ba1803bf9933c8856657c953125eb76014bacca8ec9be6290936130d166b187e1463e55cae3ad85e96e81bc574220ab0cd374aa1f657abea849259b4431f1a00ee59b35486beb09302bf71b4c2e840963333b4a3be37f8048d42a0f67c886de9b47611555495248ad4c587577d45775f52135518793ea14582bf153c74210c36b9251609a4b28559ade5a93203725a475971b92beb88a69357bf83f384577cc1dfb62c70fc65401073c67a66af878fd961bacf46c633e7cac0e5092458cbba0c3b69494c4c0c0da6025cd6516c1ab89b3216bb9ba123040051563610251974a0b11be7190504522a128ca3107938f5b18e4441b52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb12f40ac971cb475610a0e6c546998dafe5c2ed852d7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = pass +expected_ciphertext = 4106b63bd9cec4d8be3ac33234128e2bc1346ae6388357a3258c03ad9689e68cece1992893dd26409f62211674a84155d1af8ba9750add112f33c812c04adb0a1a59685ca91bca59979af97c948d5443c38894543a225f05317c22e6a8afa332f4cb4dcd6638df6b3a0efaeb8f065c576c06f8cfe3cc0b3c823d0dc638e2203b886efbd82e6cf5216a055e364de238948c55187ba2d5503a3fbfbb684cfe76da66ab53f97ffaff0322a1c0224941e8f64e3705a2e4e9d58d022d31e6403329b220546268abc3220bd49db91521cfd149fa186474001c2a86c407ea8ff96ce07cc335b3cb692998ee7929e27e80cede8eda4406494d289f479f15c51d3ea30873cbc9e5ca00ae20df9ee94901542c02ef705e068f589a4056a9521b6e003a345afb85cf66319506ca2f5a75d15baf62c6c5db502afdcdc010f93cbe1d1fe4212d6796f7876c3f1417508480678fe36aeb0715cd76fcb15f4154a7006a073e55ab89fe90b708e05279a9d51bb83d268e729e47a832c2a93642ab79023b6aa81063cc2c82030012cbb2374e005b9f0ded74e82aa174496744434220d74afb7c018b93555d9ceb8a23c5fbe22744d8dc9381d43ebd2c8088db2c699c320f7a45fcbb2003573157a848459f587b22d571b37b94a76575f1f2341085e08e31ec55f330b66ba4f5040b199dc847262f6d87e8ffd3196367beeb904241f7e0c09e9e2b0094a26ef78ab7ed8e7400bab8094b6eb75601427af06fb9a3ceaadf3eabe93a4e3aed4b8e1a72fa616f010bf0642ddfc84dd435e9ed98cae09a805ec5fdbfc740d6d218cc7ba34790debb2141990a3402145d48ad84548d5d2a1c3455379f1c1fda6e6b03cda2c6286f9285e9f4b77aa6c82e7254ad5cab2c9028a0e47084f1494978d58e2f8bc0ee2c7f2cbb38f7c50e7f60049feb80073493b1cca02a700f0d51901869432fae4687e11639144785a8c53b285ab1f9cb7bffdf5c5bcd322684fc871759e6d43bd61bd450cd69ee905724111e11f3723eb87949bdfdfbf769b76e5239814eeef6d5ad7fd65c8e0c32015868b9756f7f96afafef2861506e882043d1f947e7a21572575a475b0ab0d11566428cf7714f1497ea85de68282038563fe43e72ce17ab525e93265df6d62d0254f9c69ceebbc0fd6a30e37d2ad218119ea8d4aa85e302e4e70e25e2428032c00250b14f6c434f2b02557c4d8367792692fb31e79259c76902bcb37c4c00a1beb4ecc502b7c66412358f93382ae592a25505ccc42fc8f02e43ee8e8ed6a3d93c2d9505de290ea8fca4519237b7c76a6ca6fecbaa47e7f519f68f118ac54443a5e7ea238a61a1348ab16fe8bf1a1e39462babacf98e39fad4af8033a0dac02c806ef6715d6d9978e9b91d28cbb6b894898de9cbca5ef3b49ce91e19e23be8b75b187bfdb14fe943f30e11f253065df04b1863566e456c0f4af829d3ce3c88f728bf08e4b38efa11758a308fe6a2a45d0deca930b9929a51e72b7f8da6a45596378e071f7bfca861117f534573b35e994e +expected_shared_secret = 204d9272682710b52fb39b1176af3ff737848978770310df0c67996f6cb596c3 + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = bc962535672a8d77c9eaf9726cc1a8b8d87d61b1461f33b7f7f5a003a8657297cd100324fea561ba879ffa75287d9a838275734593abc2b842d9353906334d3f9324c7d00eed794c78310421db45cab6900817348d67490bf1485e85a3dfa255694915d286ab5243b62d3a91f8493f0b19626fb89c0b9109c6e1084bd8c848c06b3472a65a2646dd89be2d922a0d2c5e816652c826854ab36f44809ee56c9f7e26a1dc30823535997a05255756704aa1029b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e512b1c767347ae28ae046076c20179d0977d2d54a3f78add2ec6bc06071d9447f0461846fb1a5e91a760112424082c2994a98d07aab29e818fd15134de437c7fbc59469ce8ba80545a4a5bf337fe142b72e602d8a1b3009cc95975759ad38274e234aef0552b8aa65cdfcac975495a84c124f8426a9c87d8db03ce48b0382642cb9e31ce210b774724912b09b16d88ae007ac4542c092f9bbed9c262d823d9d5719b357821d4c245f384fc923cd334b9dff579e324a0bcfbcba61fb7ae9f69b3ab88693e005ee32bd1a6a3ca950a22421125391a060276b07242a795085d0098906969c421cbc469128fb5393b72590fd391dcdfa3cf87b9f7a4c6cc3a1791ae1717478a5280a3b7580bbedf88f0dd7c1c09aa67d6b284334049398ba983bcbacb8c56237bc3efb3fbfdcb358a006457832df7a01efd937e68b3299580cbe1c9f69e165d22683b3721e4189adaaa91846b7717d41baf8d9a1dc76c387f0b55c2552533326597466ecf06aca624fbf73226e471d835b0ee4a24a8f1c5fbe359c61d974a4d57c2f7c49822286ca27116839b784d6782c13b606b87804ba0969c7c47c7a29ce16cecff5514028c3d84944ec8cab4b4acb5b681723511087e25b8ae84f3741a2de6cc21e7a370b35c255c34555f29645d4b420494c4d993ba3f092ee240f1d3691753420891acfc9421c361ca2186b563ed63456096227eaa738a33ab56029976c1125dca790114aeb83aebcf271ed59bbc2e8377301b53d697cfabb4c6b40bae19b6cecd421a1109f9cac7b71c749e60a2005a30179c393d5033cb4f8795de4c98d91538fb9a8cb1654b1e6a82918471470461f54cc71fba50deb3e1221c55aa616ad5262e352adb7a89ca04557a2090fb05704b9521809b8cabfa325892ab46765cee83850586918422212c812373a1c6217ba890b4c5310f7b0d5d8275b884aa9e4914c85023ab53bea88ad4281a7f501a87534ac1d806b0f8691e9f1bc7171001043015b391cfac09b5fa88f840c63194632bd5a012b34b50441ba08c879c44654f136cccbb7114f7b4099016e0193cbbae63522927df4b740b3ca5b32b741ea15a47370b98926a1f90618f5235357e8087443c93444803dd22bbdd5340c876d41f3ac1db59e9ef17db71369a315600fc6801a54483fb015ad3766284a97cbc241ad73461f4b2a0f6645ef428805762a6e57474d29288404ad98fab63ae95e25436626bc66ee10c01e55103597288ac521b463886f863833948455319d3455110b68bf7bc495d1a922191a1a230a5f036c3c4ac05ee2609d09891ce368c01f037d818805a566193a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = pass +expected_ciphertext = b1ddab92816e9b3d6c9414ca303b6d420087f1f154d8fb5ea6dc1d5508e37f6edeb9e00b1fcb7d14066fc3585c6b61452303e8f76c034cc94efef7c29b703f2c5f997b2e3e73ced4e264bb8d940cb26ee5e048c7baedace34c3404752746593b40806baf5a7d13d1d4f43e7d178a85d3edfc37e840f7d7aebe4748a4a6f862073e18e916f795fb9305fe250574f2e7de19aad589e2a2640167d49da76c63e0dd54065e83345c9672367cf0e64596ef1357c0bc580ec438aae9b9293eea6bb2dc43eb39069e6d409ec1c61633c436959cab8f564858a835fc468815fa445c647fa6b4ff9b32a5fe4bce0ace00e15511108feb69fd12ec24900fdc7ccbb3ace5677279b33be301ef70247b625315439c805eb3f1d68ab316635cd5f5eb8e9ac9439b5278bf7df4e58da1353508c6601af0db94691f15de3d2fa21b5e2ca7052330f55218f207fd956b2aa774e0920dd6ba34041c0c801b69f4c3feeb1b6d64d78fb8d3d8b4d13792ca75894c28c1f172272a99799fcde0c9e10eb3671eec271855eea93d50e8a341ef680056eab4da00cc43c38207aec9d678c0d00b64f695aaa6ae2ba75d11f275d2985ae217514407c952084b123219c2a119d2257c1ca1b635d770cd1a01819d03a2d6880d6b0ce1b8bc59da04ade0ae64b543fcc6e96495bf5fb5d88807d5582c36088883dc14bd616971f1d98ee6083dd74a2bfbe96dd08d2711798643a84f07aecdb2f30797cc98939f61fd5d5ab12ae0dada77ed40c8187ce5e505ca5e8da98c7f5705c252b0a6ea56d8e347912b854f414c606d36bbb60aa9dbf30fbb1152afba2d335d82eb865a38baf10a01ef2cf5f16f06bc826b1f980ef49ce6e7e411a15750adb337b3d3e7503b3b50a3db53ae8a7bf59f26fded1abea8fecd430cbc72f4c6b357bd30d01d4d03d70f07c2644282c133b0408ede5a61f797b01d288d9a8326ba620f071f4823e73328fd2c18e6a3376fe5b41a54f63632338b70ae5e85b7bae061621c35c609a6c2754229a57f65d8be1b0889a148fbd19d58c002bf5d6e4651a3feef2fe29dd8732211e9dc7a68f8e2341c33a573e815e67026bd559c398121ccd61305961194f69ca1c21debc8caf921f54a2ae0de9285966a9d0a8720cebbe6d18363b724be75e402da9d56aa1a13ff4bbcdcff699adf148998f5e47f6ff9a43355687c8c7baddca273b8bd337464a42fd11dd33feaf6f3c218be2b3a3817019a4e4eb9cc88529285274d5c5e5c2329a42392cc28aea4ae431dc29e6d33a8542fb79593d93fc4d7702791d16ed6934e6d1473dfb21305657d2e57b5032388b1164165e3f6446c024bde67994c7d1e9fb32ce1a9ed53094744f08a5e9fcd34c390313555ab80a08b45f91e2137bc555da994a3951711eb699f2c0ee681e2abeed06f017798b5fccb3e0a8ec4eb880deab51ce1b21507d47c3065766325f03032b8b747c63b0feed45cbf1af5eff06681096f49b2f54de23430f165ad9cda134bfc9d1554eea7336094381a91b75e861d39416d +expected_shared_secret = 76e5f7623e3e867fd12f28dfda4311f7cd90a405b73e994e857f693573fd2b8a + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 28441cc07c18856568c4fc0eddc04175f564bda148788608b71756367551a5709127668efbd60b389877001b948f2c50ce62c7ed63122daa7c1889400a4175ab959d09ab124bea2c9d3659b8b4861e482eded950dbf57a47c87f79fbc143d20420f4162f711963c47dcf7b8ea7faa329d6a70f601d3a1b15a7890804917c84477d95f916a3761e3d94a0b0d69d9b7c39692b7f4acb9091f87583810ccf67bdf86c4be8f08762f2c3428646a3d33df4b67eb87a2662353a208403bf59334bd9758a9439f8d8bdd45195f2255282a73456d168a2b249e8d180d5b310ba828685b3a1daba2fb88783bb5062c13b79c2b0c3a10085664377eadbb477329567d1158882085850b95697248c6271f44988218777d33823ad70791bd40e29825ed124b963e05d06547c740a5ab7a1488e38c464b53b6f016ba1b7648a14aaa111907846c5df162f61cc62747386915724a3b054e868bc04c934d64b7f2ff461aae980fa806cca7a9c4d7255564b420887946f7a72e4d1384d8222c70330b09c08d9a70aa176529f0685d087b8f9eb464a776f93606b05d0729fd2afa7969eec2662ebb7c7fc821d6b5393707acf25c0c2c81702cb195f8cf730e8a46442e91e18fc7577f4aafd6933450491ee24763bf6786d794d889c3005a323cef2a8863c7ae00998d2e3ccc1f5a6c8a933d5d615ce82af312990969c6288b6893c42142ad87ab483362461b87c641f646410ef5b393283230220a34730397188920b6873f16478331cb22a5a2c73273d865985533a1f8e109dbde719c10c8ed87a831ab65562751ebbb15d3d5b6e01f78db26a54e47943d6b31f916a552ed01a39f96dff820765d6ae52265010545162d509f6ac3f9b7c0fd0ecad4008732d6a9df9449b2017b389522f11870704127bc6d018e0a420dd441ebf636c31b3b63da9c00dc15be0b3188371bbc855254217b99294815d78194fdabcd1970e31e38d37b4b1cc69bf428514f50ac9bcca9125e6473028571be535fca274651752dac691ff8a28c555036378b260acb060faba9573b0b65cbc76b892425294d65658f4a1b3309b424c6865bf1ab307b88022087f97f6882d4360ecd91f3d2513059a784bb256e47670afd5c1ad5c177142a2955b082fd0b546577ca5286e0f1c85af8b0bd5650038609e8ec8344e6ccb6df93a056644cb89294fa19266948e9a561bfa66517a900b67f6be5efb853c703ccb4a296a493c24607a6ac4a749361d8f738080a80ca62aaf658b6a972894e6ca402af3c09d2a6e9c181005e0c4d193361859011173bc8b97755fd1085b52808373b29733a7d0488c5f890364abb9716920c074645ae023679bc9c2b3ad29b9051a94a124a43688a1027c35b90f9303664aa37aa92284f97dbcc7ad0f12b5b6ba38ce0a07130110518c74ea36ca6d6a44399a3983101458f926e0bb3357bac5a294446463814806ad1623185f295d27f2c913c9608314174b2bb8bc03a92db6cc6f044d964a7e3e289ea8f064d9b5c0d0eb43357495d09c0fbc4069903bcdc683763bc4c6acc2517b7c94e3e0265029bff55773421bc6143a38f57410bfb50bf21bafec948548a87667d95439bb78cca2c9da670beb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = pass +expected_ciphertext = 968bdb85e8be748513a831e247218d164bda5f1f8f433ac105e0798820c1300777ab82383d265ac6c7464c42f2f1b82734ce4208cbd57abb0a0eed81beea32d430ad955c6535d8576a4258a148d8ea33449ccf1e63b4bedfe1752a6006afabda3f7a6f6bd81bd49065357cc1a2b4252faa112997cb4d8ce361dd76c9dc1015368e8919fbb67709ab3dcb2cac18ad6e8c06e05d1586db41ab3555a43e5b0631022d04f5e784874e3a68b8a2f3ae31f49279fcb83c4fc1600870b1d25e433c68339aa9a5bcd1985da955149fe2fccf0e1c912b435beb46a083fcee0c924acdb192f87504b27018c27a2db9c71d4d870676631b4b94fb023df02f6fd2b97f84741d8ebbb055cb786d0734b83cb2bbb2f094a80b204a5a257c770053e94373d9e9dd13dd345fc4963fc05243ae659ab7be475519f85956d2640068e28bdcf7dad6b44372d1d032de309e4e228cb932bf12f7da347acce0e24bfdd89ff7710afeaa973f735d7d69574dede21e4099181d0c885be477d176b19e79dad497f8d46b8843456a5b338c37aeece04596e6ee4b74dfe3976449627deb97e2fd6ce4e903ba2b0adb9396846cfb0996ea32143c4188abcaa15b3a0f38a44625a52c62fdf3bb9cf81e1e6e0cbc102e251a91eaefe8a3e0c903414397ea25321672985bd8d91e07e297b7472e04fc481ac17ef4a61a4e618d2fb3aa728c80206f367d5c44c29ab4704a405cdff7c6aaa34db06cefccd64ef24370ba1c0d2204069c1a48f0556c7664cdd5b80600c466da748e4c774a4784e15234c20f7258cfd998d764eaf8359e69c3fab08b148b634257ddab72777698e63b55f817e370b804851c40b642df365fc97f73a0161140b127ebd3affa31da4a2f59918b095ffd877739e3d1d7af7455e99a5162c301a66536d198d18e2db6876e7ad5f95422a3e363dc637ce45dc663a975dc0d27b9e92008df453364256c3c12acc52e7e4d228c931dd5fc4465151a4d7b453775ea131dcd06dbd05f8e8a9001dcca04a23b2d4d18abf23fb50484a382e1c07e33f9a2fe69ab38ccbe51510a9389c2d522deb000a66d406b2b09c29fe4dec4cde29f358e813b72b38ca32afbb5990cc37f06cf18386e39a06cae8529400fd479152387f0c60d301344666765405ef92b98a7379e983ee89a5104cb3306a296b53eb2242e6fae55f04cb29d0c875bff6b1856439375ad697c88673e49b8753d4180db24a28ea0c77051d28752ac9cf6c571b129fd91c3b0c79b19a6b1afc1b72d1d986658740dc01a7aa7ac69144e99af53089e072be0f2d0e173f579f91acd0047d28b1259147fedc28d0e66589bea1207479f2c13ba9e4896d45a715e0aa9a401f5b5a35e29bf1f791d45ecb581063d6a82fbe7f623ffa5ebcd804932c81904a4756ab940eda4c4c7a4b69ea22701597cdeecc857b4231fded57126cbd5fd91da14548f5b82cf33605abadab82565ec80bdc6f63b8366f08a2bb9b252f33de69f13ae4dad178897f8ab66565b2e0ebc143427d35215ac75f4264e +expected_shared_secret = 874ac966970f29935db73c231e71a3559b2504e5446151b99c199276617b3824 + +comment = Public key not reduced +entropy = 147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615 +public_key = a73cfd9c843ee9f8313ecc7f86e6f94d69e59d9a879a64fe2619f2adf999051cc4530dc9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957d2e9327f7ca73b4d07e26f7f01be1cd8d573c15aee674dfb866fdfa7bf40dadad351ac4ac155b97ce4c8bbe3dd36fcdfe5ec4bb5572fe6e6554de7bdd53dacbea3e96fdb698d66990ab51e6dd3783a8b3d278a5720454cf9695cfdca08485ba099c51ce9fa7ea7587c2de5c28f6d9a81852602bd6051ed679aa482e6ef61ec36e36b8719686f17fd74c54786488f4b496acd5a8caf7ca3a77cce73b9669f3ca554e422b9b61f475474e608bce6c9b8587a33cec5dd788f88b36b717a46965635deb67f46be29ba9d70909c93ec8db43cfb3f307d443a7cf37e8520e7bcfc416aca5fe8c7a9ef62cafbfc756ae03278f0ec66dc20576978f4ba6769865b6d1d7148ef6f54e5af5686baf906f994ce38a5e0b938f24add7014df2c03392df44d1b1e4a3a7ebc6161449f73374c9cde40369343e9f95fd05e2845c4a46ebaab6ca5492f6800b98c0cd8d3653a4b1d6e6aaed1932bacc5fefaa818bb5d2859ba5494c5f550fc8536a9c4c18881516e7f90d98f7bfa99c39bc5dc7cf3b69d0a223f9ab69d53abaa64fde63e859a8b3b3ca3359b750ccc3e81dc7ac43c8191cb5d68870c06391c0cb8aed7fb897ac6be7fbaacc676ed673e4c83630e89448c89aedf04aceb23abf2f4d9ef333c622289c19bfe34e75dc45257e47475fa33aa537a5a8f778d2157e6c50d470e3284963ca64f54677aec54b538fe62b05fcc824fe1e4e83fd0e7454a6b5a496831769d64024745978cbd51a6cedc8955de4cc6d363670a47466f8fbe6cf3604ae7bf22acdb7cc984bfd8c88ee4e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697223f75647be94f36758673a8ee2ef84455afc7a8529f69c97a4cfd7b8c636c0ba55614b768f6f4e81f930f77616acde7167f5351bc74b47395ee5fb25a23e3ca5e64814c34c979cbdfab85954662cab485e85d87a98cc74bc8fca3deb5bf38d3238480638c40e90b43c756de7ab9e7f12de51fbbe169987b372abb5937ef7006c24f7df36b84b9dde6d06247d42556e7fb498d89e58b0368bcb31d3e79353eb587860c24f2e486e62f4f5bc248edb82c6592737e1de6d2865bd167b7eec20ff4306cd2fe35d52bffb3b5a55a0d8af022d9a798ecdc5874a9880faaf4054c5e8d338b5f48b5b7bd09c53b5e3ad84b047d277a861b1a73bc5e488eed4ef573c8533da0470b73175c9fa50594f66a5f50c4e50054c93b78e86f8b5cbc49316c8548a74fb2b37aed454c7489ac33b3dfce6678d9688fa2c2ed866e2ea65e16b585e7af8618bdf3184c1986878508917277b93f1d706b26e4973bfa94c7310fe9c709cf31a1a8ac8da3e4a529a97f469bf64962d92d648453d99a076d55d4cea824a58304844f99497d1da25148618b3e5d72ca857d2bd4d575b94f85c01d19bef31ebf0aa3362f7d41fd16596e8d8e867b44c5dddd1cda3418967718fe47d0fbf1b42aaee74ac35d0b92414b95863eaadf463ec73d5ae5ecaf79174003ff6ddecc813b03f772e8529d95a4e83da7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046 +public_key = 6de4d6b49b9ca0354680df6c6c0b824bea310f435fbe8bbbd353db5c39889e7be17e994e2f08823a33789ff858b737e5323c6205af41d9835ec0da85c5884a8aa6f10229d99c8c383c28f63238d357ceb4f298405258a170f8e624e861fd1d82d31867a9037e3c9db0aeeaa065df7020da7ba79398fb9fa963a8a294e7720bd4cd9fbfe3f18d63079c4d56bd94bebc4e979444f56fb967a7fe622d6fcd8d337a1eb02c7396bc64405f0cdc77cccd2ecce21a734037cb90b77846b2359c30a451bfcfda6e7fc238284e5effad1dcea33fd5a104965c8635ea596360d65ef40a58f8231a827b0e68b6d8ac7e27328173886453a9c91498766cfbd9ea9f666bb4a1e6df992538a1a746df845574f99adbdf3b9744afa81c7fb79a32b175706454438f46b8995e32b9eecca11cfb10bde1ebbf428b88cfef9378a62f8e55d7463dfa5022c998abd6354118b5116b3bc20d4f0018e34b85a1cf2a9f40aae0e14b6d07cf6d8e355864c35bc71b60d5cac33b5e3efdf6b9bb83bc880983682c8fb8b8eb6927ca52e93835956795488181a8cd83bea50ede8a25f35e2643cdd77cf82f8de8bb99624f13e418fbc8052c4179b43a5998be9b2dcd2d8a883c3e3ec38f59830fadd657e971c88cda6d7d3b8d52519930bc5bc71ca465245fb4d036f0b8d983b9849ce8b8935f1a4decd3f50de7b0cfcb49eb7b74e0b5792ae97634bd92081c3c6bf58f1b34fca086e0c3387098ac3f109d43901c61469dc4ebbc64ce1971e824694a999cbcc430af9f3a153fb6a5aee1632e3c429481395af7006b9d49cdab590e823d756bfd8c691a6dfd613594aed8ef5669bd4e84952936d6969f92467ccac7f688333b3f48a39fce5c42cacf653886a5adf4747cc943b34e6348f46df5b58e4916ba64e9664a4baaa4eda96534d8c8f5d76d2f6c3a7932c42a846949a2a26b4e2c55ff86cacfe6dfd1ae23f1ab6cfcabda557648a84934ef077a799edba3593fd2cb27763057f19f5546cf1881942fb9c63974b42fb949baa491d97c710fd645886c87086721d3ca2aeab441264b516975ed0c6044b4f58545f8424532e4e7f1e85cb0bf65c2618fc790765b0639e6fac4a0dcecbc2faddc707dd270838e2e0fdfe0b9d7e46e3dcfed49c44564046fc981af92f123c6c9b591902e443c996016c44d2b1f4c5925a8e0c48e89cbe67b1f9fcbf67adb89903f1f49f70f8bc176bacd8ff366139858e583eb68fadb7e4e79b5ad1ccea6f18754e20d62472d968d17d2e18dbefed4f5bc16b650b3d7813dd4c57590897c87e65347f32c324579d51d798bebdb421fbf8b2d2adc662444c7db32bf97845e8ff5c7539f457894eb87606fa85b5f8d4053fb6ecdea773566c006e540ee75e01d99bf324e81d666680985c78c1d3dd01ad40dc69cff389fea8ce8e48a363b943ff14fb476dc86be953a5935d76cf749a62a77aa4d6165e3edacdc3a677b9114d8bf84b43f59f647fb5df3545e40feed4286afe1858d9c5f193a7df45f6218785416ea4d6754db5f8f3c7ea134aa487d9b5f7cfc68391d8b8b95b51f5540c9ea5f29a9df7ced7efe6df461033f1047f3094ae6dd96c098977f8143d249183cf35a63694ebd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9 +public_key = f5a35b4ec7538c7ff89eeef04dc9eac59fb610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78b4e49d0edc6da3f8316de67e737596c7e1a903fb0f79d9985d55ce6632f4c4fcfaaf361cf69047b5bde1868dd745a82cf473ebc3dd86b7e793364f71cef55b2cf004fe66683c936a7977df156a8415ee69b95e036e6dd319ddd48d86ef3bc12353bad25377618965c39edfcb9f9dfbf46f2046dfc847818c09debc044eed16b3b915fc5d7da5a53d441e53a5527a689f49b35cf8fb84e6d57d5f69fc6dc710c5731f53ea970b86442ef5920f77fa7c310b2f85117b47ba5d54e4174a1fceeda3e3c26bcf5619d36713ceeb2ef7405bcb943dcae0d51cd436c5dde6bd4d96488a38f53df37895ad2dc10d959d82af9fe103eaff97e831d93c54654173bdfe65599f9e9fdab037438f6f714be6c7d868b66bcd3c31c8753a16f318ca36b6e59d340b9696d47c390ee6104765865353a05c8fbc5bda62a96577e94c17094de269d06f169e75b8919bb4c37df6787b59bec8fac999b9db741f3a5cc8772ad67585c879eced5b5c06afdb54dadfbc4ad50dd0e634822a843e9b165f2f0bb749ef31c1edceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fbcf91a0bbe96e9ad36a4a1d9c9693a6d3bcd76a81c14dfba27a5a3aaec387cac9d2bd86f6ef468d378ea6d39abef622fe5483673850e5eeab64b892f3cf98548f2eae76feaf5716a76db56dfd20dd3323a25dceef9ab7a9f5d2ccd9cc6faa31727a5912a7f5f9d51f8b94d8866c4da173d3f2a388e6c44218338cb85702ccaff603cf4e1788159cde29e8ce5ddffcc6ed55c54b456cadcd7d179b432a5aa63e8ac5afdb6979a833d99c13badc56cb6592813fe303d583fa6c038748ceb77a91c73edd09b575f23e26f1447cbcddbc9c85fc87deda44ac5fea5adcbb599a409bb1a67b24ef438d85dbf87a8814e0ff549d9f56ebef86dd6f3e81546c283b80cc88c490dd4678ab3548da6da65eac714ecd62efd5ade5a8013fc28c6ea1bb3b8a7267adf4662b5963468b3bc5918418fa8dcd7db3946c5a67f864dc1f3adeb2fe42fc7efda69de081dd7662b5c3b8b31af169a093afe466aa01ae879641bc4d1e6f523ccaa3ed436cc089b272e456124f15d1a9ef0eed16dd8ed542d956fd942bdda40f4ad33e527dca7afc57dee7eafc97aa0959cf37b92e789636f159fab8f7ddb89555364dd52b6eedc1b3dcfcffa733ec48037cc78594719adf334ddbc4fe6b2945f991e2ba5d42fe7468dd7057b9d3c07c39b7c7eeedcf22d54e5d6e9f72ed5db826fdbc607592947c86d36e2e434c22523f35536cd090ed122b97675b89f1de58130eb679748df6b68773dfbba0664bb7caac84f8bd6711587c6ecaa3845d5f62751c8346bde6dfa58e9326e5add2d39f26f794ad0064b2dfda56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b848fe58c1a7bfdcb65d426458edbcf8797383e37fd3b18bee68c4d75ef5751bbece4567d66c7e4ce6fa8e9b886bab8e2a905d839f3df2967914157f7d66dd3bcc5fab6bb74cbcfe5b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85 +public_key = 25949faea67e918d40a269d8a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f23ee8e0685b09e3d947ac76f407ff89bbb7579bba13d3cd4e36ffcd385eeca8b780d7b6d3343ca7fce958569c4a8d8b97586c2649d398a9f8ab9b63efbcd0b37d37637897556b8aab43e98c144d226ab9284541410e38e03a31f10cbf1cc4bf633c3ad70c65219ceb1887dc92de39971574de9d317b5feb8bdc56c03cf565bf496793a27b2fd09ecca141aa337faeef0b448d913394ec1abbb46a568ba749f00bdb2c4562638af20225a0afbcde9a53ca505d6391d7483a3f814dea886c89879237a95c03684dcdc2d38deb40e5b3a44d316159cbc56bae8423df2fa830511f57f8a8948f58fad194ccd4f6ba6d0ebacc5ceb9d3e88c4edd2f9fe8f62393b373396f6d5e0308b6754b8ca81f53d5a25e2ffc3428a7cfa543a61ff1e93a86b97b36d339fb43a9f0375b2cfc62ddb4c1f76f9dc8deb2d2a50577cc7d5d55a3076640094f938d83a6818a1294edd16648614a6b6df6b5d8d9a8d0ea4a12704f43b9a50ba539f600eb62513a5c7bb8ead8463c0a346252c94f753a3485eb079ad6dd785ac663fc2730caef72495165e4f8e18713c2a72d8949de88ec698f7d8deb35448daedf99b8e09ac4faf694ca71b7bd41bb7025cd4364f48324f4f680a77f145d6a56c97b6966afac4b90ff6dbf5e7507e6a7093c47b5f8ca47d86c767455d645c502e8fcf5b1ccd898d758bea855dd7eb1c9849497fd3030fc06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacd7e17a8d774f1f355bff7e507afac63c4abfe585b31f3e2404b9ea9753fb2de604663d08ee53c07b743b23c56b86a91ca341128d3a1f5865e488d7c11fa81895e04495499884b495ea3f458afae1363222bfa94be84e27cc9e8bca44f8fbb9274682188fb3b93bebfe97e27f44d76bd4acab06df4f9b97a8f63008b584d13feaf927c67e6e6bb9933be9486e38d7befebeea27175f6716d0041a6dbf0c9a4364b3ffd28ecefbdc8077c3acae9c6123a20cb7fc0776aa8f2ea582168591c7c1eb146ba92dc9ea1aa33756f5c8744612bcab3735dffb34a89e3d5c35169660dc9b09f7c960a4c4451bea2e66d88e96d5fd75a35ec6f0c3d9db930bd11e03c007ae5b67136ec1c354d405a61014821fa9590eefe2cd6d95de1eebd99dea11fd8f15eaf1c14cacfdf6d6cb0fb7e3ee483e45e4cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d59cd33cbff80fcd521bc53dcc3772d58f58593a5a1f9974228652b8cb4a08296eeae869c733a316e9f6d50dcbb0aafdaf63fda075f2da9694cfcfa29cd4c87f6a6c837c6ef628fa30548afdc8d7bf447953a3827dc3e22bcc7e33576a33a943492a61f46f5dd05ef793996c664a4664b3666c154f90c4dc3ed5e4c5bea2d265a23b89717744fb76c69637e5fe3576f0f46848057f923313a658683566dc8f90ded79f248f9d8ac67d4ca703339ae28a86edb4bc21ebf31dfa970249aeb2ffe38bd479146fe5162da73b0792a0e77d4967bc8b46740cf5599e4d56f48fc9006b799398f5e0ef806cb6afe85f3d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216 +public_key = eb14cbcc2f6951857be4b3bc2a1b578b148e825af4155efa3d57c8213793c418bf2e18d3de5ae6eb9c8b5d53718d38ae40299b89793f1484e792cbe0dadfed5f06633aa3cf1cc78d0dc99983076f8756b2f97bf096edb81226dfbb9494038a88057671dc79ff14a956d5e6565ff752d38f37c70b8f8528cb1a04cfe5e6495bd3b46b3f64fd7364e0d54f2bdf7dd28bd22efb3d3a73fa7f99551bc331736df07f2658f373e64a9631a34b468e9b3c9b34b27a4ad2fcbacc516469f69b3a51554b94ed5fd6dcb098e8af8a3681ce89548cb3e1e2f5421dae496a63f366435cfd56a26a245ba68655db99cd114cead127dbab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b303cd37bab4954627a2374df0c4ab5ceef5aaf2e352dee6ffd6b5facc7dc84723a527ba34f189f04b26ac1079f822ac66cc56bfeceba65c43f95fc8d5c596a48a0c594784d5c21ac3eedfc27e56c19bc84d710584ade48647c681756d38ac74ab7369efde97fccdfbc3cc2fe8ff1facbfec9249ddde1a4f4b1fbca70fd5e9325eaae24e5416cafd7faa6a2c745cdedb94295438bb28fdadb77183bfbe5cdece0dddf8b7eb71ba8cac8585cba3dad1620b63fd9ebf3d3edf67c65c92f893fd6e6159ded4a5799720bbdfd907798f0678746475c96df029865dd663f09a39c0c47ff58a266b1b244a504fb4aecec6c07dffe72ef5c3b989c018c0a1edc73e35abc97c9ee695cd2669d9b08f548b865eb4238376a6ab53a6baef185799489f65ffd0fb64fec4deb42e8b3961fdf730936d620360ff4570b4079b369a83629b599e8bf7ff48c3807f7a4f93bbb2d4b7e1c73fc0d6668e53c1f0eda0b547b1f38c51f51de654f45bf0e5766daec663ffcb99a6bd43ae7f89d8da4ebd3c990a81ae9487e1b5fc148fd266083e162d61aa08c03a7a703de582520efa546a422835e5a4ef7195ca97ceb39b00566cf4acadb04fdd5c88c75f03e1f10bb5ad738d38aa47c955f35e1730b6dcf27a194dcb04ce047af2c383e9da2dd60b594bf8a64f2c4b8f271dd0319480478fee6546893a44eed2d3f804149954e3788eb5d54d5ea43da89f9c789eda77f7bdd4be33be5d47b9c327ec684238e3b00950bd73c96d7e75274a5ea8cce28a8cd99313eb4e8a5d3c074d2d1abde8239d5af58c075d9b251d9c84297e3feb447fb3926ece9f3a3ee119c459781ea222b341cdecb0698580e52fa951ebf305d4a7a97e967db945a60439df2d6955c371eb5f452f865da448e30d2b8eab3669a989e1259bd8932afe36c6c390b6845f8d76a0e6f1d779f971ba71beadb8aaf7ba0ad3c4f05ac2372ea146c68bbd6de85416fb924c3a659e6a1babe9ce5b466f8672edf6f1ea987f83495106dac22ffab6f4a5cca797587126ce50589f69bfd84875bbb505c7ff46922eb496da36de3719cdb3ff3950455dc8d36e3a3f518cdeebfdcd67ac533360b86550b6ad09e93dbb19fbe51d721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae29d7adea5772276b2929b9507db5c0614ee5f9846516d55417c6fa19e652a4a424bf6396d46365bc4d601e3a5590eb93a1ccf3a1f6ba80df6a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88 +public_key = 86b5c9a85e57e73ccc2e138518ea98a256e45dfb6bacabfffc333c0ba5806047ca9ba8ab797937010f70e773c98647d9e59786f8ec948fdf7660aa3758e33f5924de527787fa74a2cf2fa4a803d47a26903665cbfe9ad677fcf73f69dd64c97f69f396db78448535746b53f96b0afcf1af51bf986a534d74c1f9607705f29cfa9125de45862d99406f7aa8b7b6a1fe91693f33e0ba6bde24561a666fd20e51b0d5fc9a8fc302ed970c3363de27825a5bab078848aa5cb75b9dc1ccdf4cf67a68f44e7780cca94723ee4573934f9959787b6320a4b47bc3e1058f89e2d9e5e35344e4ae44e37d8893138a16ad3fce48e6945464c229c587093b5cbbb519767fc66cd78d6c684b8b81c1f9cc2b3ba749fb30756f3e3daef4a9eea5146ed357656b37087bfe0f773fb59157eb885e25d1740483f3fcd70bd492e0dfe7d7db99cd7c9d57b937297634c3494deb585b8c93cd4ebbe865f8a9c8cbe5dfe583c7ecd427274f8df3c693fc351289964a89a3c74596734ef61d949553ed809ba9b7c6df58af579a4515981ea9ed93154bcbae70492bd67534e5b1e5fbc2a98b7f39c5b91a87eb759a9a4537228e56746930a347a50279e1aecd41301da7a8dfd0a25e4d5018d5c11af76d3f7e4899aa3f9b95d1caf348fde40184b1235a719e6c4a311e576245f15d87d84034771129c33199b70774b2130898a0c69d8f39c3a51bf73c665dce8d31b4454d144a4356b9c2b16641311856cb65466a9eb06d1a8a74a5aad6b5b935b65dba8374ee79dcd1d7d1a6af8b4183fb5f88a9ae9e9a7fa563bafb529885488f544e134db3cd673f94ebbc91b4757444a302578aa963e61993cc929fe6bc56ba53fae7664bc5b543a38c45e6d4063c35695791d882134dbb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58f5d7f9bed5e207f06095621e354b3dfcef9c979ed7b3aab56b47422edfdb7defac78c2edc38667aee8a425c63415787506ebe01dc43e2e84d335fedfceea61eb67a349405ec74b9fe3d7558a887efbbb46d9d4f9469db59e605a3582be433bed57363436d55cc4852adcd318ff4d8a9d3a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5b1df9c25e3d5a1a98eae78713785bd54ff261e9d10aad806e565ebda3d8849cc6708b536c83a2fa35995d8e9d99b850252ced50ea902a053c7cb3efaac37bcb1b40d71f3cc4e5f0039d9d0ac566f7d75dc89998036aabb267c5ab8de84ab4cffebbd18f195f62879be0b5eb42b843caf7c495ce81c3fd6866dbf288bdd349ebb136747da52a3c4a3c581798c4149f9ce3e698fa594f019579af3f9a22d4af67ff7b46453f22f6eaa6ec5d7d854ff6d3c3d51e7be2145b5c2ba7a57ac968a5ca43b461f818e67fb5a76aa4fc95145098b95cd4643966acd0366960e226fab613c5edbe5135abd93c27c04bbf30fa8cd074684996f44939d8efc31373c833ebd0b6679a9ea32a13e003bf57b203e2023e7b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659ca7df95dd942124c17ce3ad50d5a7029e46c05eb013decfa0f59b220a795dc6b3d7896aac78dadad383ec46762b669d369d9a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b +public_key = 05eb36256ec4a2f8e885084505c3862c3b647d28e8062d5ef3e4ca5d3dc46a1cf1eb97700c7dc2bee78d862b3e19ecee0cfcdae6998a7b3c4fdac39a961df7fb2a3bef0f7a8e54b4a5b981bcbdebaecdb5ba6a36a39e3f1c2ad4603696089dce2dff583e6c62a788f90f34fb4a6d6ecf24b3a0ecd23c2fad8945a0b8dbccc9356475b36b2aa9dd7435b12e1536a31d79fb88d2b998488e79df763646c3b66adfbc8161855b20fae8afd8722add5e6047f694e4c4c72e5344ead4173559d7954b029555e6ca4356f6cbe325a3953ea64efd6e75c63ed0f4dbb0cba6ed68bc731eb0301e65c47dada2edacf4ab61c87cc3308de7b5af6ff8dcd784f760483e6af6398ddedcdc62e9a37fc4ca696de7b33aacf59776742fe92cd330b2f3a84e0bb85858da63b6d7295a39f625e0dc2c69996e4013f45d319858db9ff8fe5bb6eaf3b03ab6df4c8fea3f046d3088671a3d672d6ec92e7dd5254372d818ebe42fccebdd6cdd57fcc5a481ee385096a5b8ce64b5788ecbfc4457e927e62ebdd7bd7bad8e48d3e06bd8876842d9e6a0a545407b5d67ede3510ccc4479cd40310aaf4615e454d855d1a5521e35e4af67684675de0043bebf453e7488b6db8aaefdce6e26a75c52ccdef3d8dda3bb39f73b9852b54d9d6d6363438c45dac4ff2ae913e8eb9b8d544177ba7db6503a04a5415f99f80a83fc7e35feed4f8cecc0962461c0f8d299efe9531c9cc00da3bb5b84908b5a807739a634851295e2c0478084c896509d64cd55e4cf9fc30454ac25b48919c7e9c5a853011afeb81fb80975660456562c4c448c49e62ca63aed14af7f28875149857f9b8965cced04cb8ee2e67c14a493a49fffcd1afdba2677e719b8f2c8bd0953eb82ba56007584beeacaa2fd81d244b0d87ebdb0d8d33b18ca9597443ff8cdf754569ddcfdc4d4c213efbbee88925ce73035ee9167cc7ac56d59cd3b9ebbf6bc3a476f08438c61a7eaf139a2499fe00258df43cfb9c0979ad3bc6868565ca3fcbc124a7548d53f56c5ec9f8aa387b59b07638c7aa457055fdb3c24642035a7884cb42f877261cf96988d9aa758fe3fc356d8dad61c1c443dff4c4535bdecdbd2c3e3b8b1e9de5b47bd126e5caf849da69eeaa743b9bd88e0c58de87f8eaf9bdb4d130730406e5ace2a58e7ecb3be36de9f8cee10eb3a850fd8d2e75a30c7c741ea45fb04a9474ce42508db9186a7f36f5ea6abb4aaea3bb516d2df23acf8e452cd0ea909ec9034acb47b969d915fe3f0a79edb7766d039d005c954a1ead155f7318be854febd38d019c1904b714f15e4ac43ec3813bd703b45076365be4b47ed6eda9f585907ccdf461a6bf0ee3a2667593f2fe34a86ac139777a50ccdad16b6892ad8727feb387684b62f63695dd165bf910a3f8f672cadadf7648377cd11d9f320a4e65cbecf12f694fa4dc3cd784c859f5ba74c8a49ecf7cda4c553c85334a860a8a55d8a75969977ad205d5b9c2dceecfbf4a36fc707843310f3943449dea63e5a6759ef069fbf723aec2658c8a82d991b26561e14b178c3a1039dd3cab8b6a06d828f47b876d43d3f193c392d804068a5cae76dc4ff7f5f23f3e7af797baae3c877e3a83ba9c26e899dff95cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663 +public_key = 8acf8969078e11664ca1554ecb8eb9542bae2ea8cc12b44e81b3354828e41bfdb494543d4684e60a086f7e8755a97f58e7e6a6aeb96955286924c4f637ed4583f74184133d8acb90689f5f4969642f27408507e0c12361ff96c3131be43e23797f2a3a6cc757c97454cc8aa5dacd62f9254f4cc7335b44cb66dc712b4677c39dccbcad8cfc3948c535be29f44737af3b4c8ccb3978404f4e9a08a67aa555becb48bcc26ecbc559fb55e3498e74bb516cf8a7a44a3a0ad248ec3411e8fa1bfed3523d74a13938a50ce8dfabad006d90455b4b5e55d79d7bbe956c7a18a8bec9a64c1dc7f544dbd0c6997d545ac7e3bc5c6565885536af4874e7e728cc99c78cfb1fa1f7697f1bdf6efec7f6290dac4f1ef1e766aa9cfda74ae635074c62fb6ca79975761419b12a985ed8afc8788c902056ffb5764c087681be1595a5ea4ee7234aa3efff4119b559a536e0eade8d1bfe494cfb5bd576459994acd684a82ad955684819eeb88e348447bffc9143a4eefc7d8ec678624763d4548fe255ef078582c93c986b14e7e1aababdd76dc063fe252b59e47370e81951ef75ad49dff3316a40247e52e45d8ec164c7375594f73b5f0483c560f52f250aaef28431eadeb2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a80ddfeff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968acad93e804fed3c7cd68d8d28b9dcb0c93cb44e4fefade5e6ca978ed5b88914c4e20768029ffc927a33433d33c5e6a45a6c5ae8c35fa83e68ec22e347c0f5866ff6912b89a9da7472b75b9aba7558195fb98df7ea7c9c5c7e8bebd0d94c01947f44afc660ec97e53f3142de67eccbc4c4af022839585befad5c5eb4ce3d8c953d2e58c70eff7b24fbad51cf548b5a73ab4254179eaa038ec95d4e4e82d2971084cb33a6ca1116d76dfa76ec0c4b3bb5c7266a481001cad08eef051a77e326d3bf47c62dbf959c89774598ee1db2bd38ae834e1ad8c28ffb772a967179a9baeaeac12bcb8fd4bd6ca44b3f11a6762ab51aaadb67fb83def8c9a713ae469c7e9f2557e5a03c6bad8d8d1edaa304955a3e9616199f0d0ccf347c74ad77f5a9a855d1d8456d3cf6addd849e59b7ce7c85765064ed6d63039e368eafe8d50beee16f8cc88bb3ffc4db4c6269996da8a6b5586375f92b6bec78b04e71c27ee2fc7a6a8293a96e6ed693f75eafcadfed74473f3da1026809076a1025398b745be723a78e008c85b558d2b7639306de5d20f4c172cdfc6c7c0c0e631bef57166e660279f31c42e6fb08b6cff0a420ab4e3ed1f85b7b5ae9fcbe5f9fa6b8bff9ec16e996a86e2df5f4c7e17f4766bb51f1f64ac5dc3a095815645b1d21fe060c9dc96555e8b1de045de6cffd7719868d65efca6c2654ea265d6f064efae34fdbb154e421cddd5ee3a79053b431b7c00768bf0f781811ad833afb814c5517baea094a5f3e12aa35893912256a7370bcd9faa30788b631b87731cc5c832af6e8f48ad7cf9c9364deaa8dbd06ac59fd2ea5bdc1736b2a5523ff3c4d804fadc037292e863a087bb29dcf732ba30c01e490dcbef3adb3448e6e10a774b26df42603cf50999ce6adeb32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2 +public_key = 764b51d1dabf9245e8de898c5e7cb5e0066fd6a5f2f5889dc05c41a57fc98358333323f053aec93a464120c3f5764b8665ca42555b98d8d6a93c88a0a383ab5138df52873f2cef6e13ce31688df7c616711d478342cb424b0463c98e61ed84bf6e869abe9cb916de3535df756de7f343359e9a1e624dc7c6e828b19d6cb178c43a5ceb9361df939eff744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ed9ee52d4d30f5453e6bc9103b9c19cd83e69048272855b11b8af3eecd9b04ab31179bee59abc777f6fbea6e2d37eb7010844f62535f203de8417c35f17c161abd55fab6a0f5458568c75342df99fcb335a7697e7cbc9b9fbeb14bcfd0ddb765b266b6d68bdb6cdf3689532864db2109ebbd3aed625e674b33a4f8b7ceb4f66c4131cfe973ab72e8d9282ca63edab71269cd2aaedf0bfd8d5410aae2dd4b699448a56049d1e9a58c50cfbbe159dec69c5037d99a3b57d3a2560ce24a6f60e7d33fddf3078b7933d93855fe878cca555c7d65d57537d8d4e10bac052788769b7c1121a78912ae53fb56a366aff98bd70d7c6e725ddc4d15cf95d78be57a8aadb873d3af6b74e1fdb8654cf48543de8daf2371a48ded585b7073ecfedc44efcf7c85b5a68f6b455bdcb1079f039cc68ec3cfbf99f80462dc71be5b7badb807c4d59a3d87d32548ba3e4b698dae50d784a8c2c35a67a8c92c68ac0037888b65a4ca8d0ba8aeec15d627af648fc6ec87cc55b8243545ab5e4cbc550a98d4c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6327edbbd55dfdbe26cec08a7c1a19457ccf677f15b984a74fbd5fcdce48618e5dc4751dd11b49f908bcfcf08a579783a810bf990cea90eef9db7de8ee6cc9c96147fd8d8fdd7fcff3d5a6a16d4571c1a93213c3f289934f7c3da63527c639a9f0086940b7696503f6f3e64ad50f4b69810b6e6f77f9e588fb583ff1f596a09a1879bbb46a62a955043a30a2aa3e63fdfce1ab6f3d03693a8cb653e361d8783ffa47f74bed6a402f92f1a655729fd06e493ff2653437a64dbea950bf6a8ca8836407fb489e4fa6f62577714edf297e5bc75eec81486cef3cb9ac6dd559fd70f5ae5817f8c177d63cb0be76caf3b2b1cb7b7254c190ee5111fcab9e9a968204eda0df47ec63fcce05e5860a3fed43d2563f3dafe46eed198041d732538c9424d43fe2f548175d470f0890689eb2bfe65a445bb26ac87d9cdd4aa648a54ece3a137b60e6cf779fe4b5a866620ecf829e4f384aea9ab165ffcbafdf8929b7bbad59dea53e6a5b3e492a6e45b5ae11f6ad25dd35d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124b8eed55fdc88bd601eef3e3ccba915faad0c2b47f06f38dba9449274c64ccccd85f9e71257de8faaf8678fd059a8501c7762c0883cfa8f7bfe6fbdc098fee03b457cefb2794b8becf74ec0da468438f201af94c13c8a9ff376c11879122febdd886f285e4846f740b72aad5544cbd97a7e208635480acde04d4fc067c82a45b5c988f9f06abca63de429e9a516f66e66dd7075cbc0c61cfa9734baadd68f4226e7fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b +public_key = 5b1f78c01eb37fbab1dc3ef359473012f3b5464deddc833c69a75afe16744557b5e28bc0ee895da17cfc5dd34fe6783949d555e68dc1be7994bc0d8daf27a47f554932b87222f8fec77d490cb5e39ff49d5ed8962198f5056a8639c3ed3ac8550356a409bde404c6aa9c2b7284e7c7c37d36256b7902445ddf0d630e8e930f4ccc518b9efd8ab250ce6a365b8068d9df7e09bbd24cfa6bcef793df45551a989407d50435d1c8fc49eebad1338dee29a3c97834530a7c61f1b844092fcd1bb6b11ddafa5a5eb4dfbdb1269cff5aa8cf76a6bd0bf3d13a37ca1b9d3ac634405ecb3714bc54610baa63bacf0a263d8dcde8b04bda296d83998a7e8b2a573e67d17a8ef131ae9f9eccf337d43926f9c9656d996dcd3199e8ea0e29f59da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f20fe2c6d85499c46746cbd0ba687a17877e675dc679de3861337faab7d45a16b8ec7e73e8cd8b6394b5f2b99ea3083ba175c55d45dfd61b73aa89dca6f479fd5bd1282b6bae0ad1a1946f6dfb855ce7bd50389d428568244dee02bff8ac754cb66ade324ad943b75741cb498cc499c8649b6bf87e9925d7194983abdeb57994b7d79bbcf2eb3b5f8734ccf3cea276fe95d486999e44afbffc94c363571ac7dce8ef577645cf19b313f849b52fafed963cdc8de3961fdc2d18601b4da42429896aa9b0b2dedc4876928aeac5996f414e143723adb94746abd157343d15bb9ff5d0764be8c62be84407449b1b5ba80be654e4bb58ab99faaac9cdc3b698e6417abd89b796f04bf95eda86474ee799440478348989c91c346244672444dcd2376c6839d7edb58c85a4ce3ef46cc6ddca345590ab14844c2f4735ecd5e0e66edea4f58f395fe867ab9d9ceb0fb8d7441dfa15eae97624f95dc358f40758c9dcd5e45bbc659b93ee7eeaa58845d94acc7aa75deba56d4d83c641cf52975bc3175f54c92957b78c9583b370ad785f2c16cd5cb9913839939d7f93e6b956e23cc5d14cb3ab3afe95fe79bb07635515792008523606dc84449d43ac89c2b46dafa6b784438f361dbfc48357a578e043ba7428583bb5f9e2b08786562579df58a41bdb82114344b3ea3574b997f85642493edd4f5dab2287e00b9a5423178b1f138e9e4f7762253cffc3cd095cb53a776f50fde5b5168b1a9759ac4acc7709dd69c3d7192b7b866753872a69814bebcaab5cbc9ef6d8998e78d99f5b5f7992b89496af8e3fa83e75337ca2b896172ac244ab7e3086ec8e4ad08a0d46e5f599eeab65bf1a4cdeb5791ddedadf7e97fb5bc754233f3c1dc9bb2f40adfc61c15f31c36a6cf71aa752ab3c95c3756ef9373b677106eeef86e68036348bdd28ef284d7e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc48736e7bdc17a7baa97af9a932300de6956678e8e6f2d0bea11ee9f9f29bb1f094c17f49417c09c1c443369123caf98de199c43bffa7d34efc699a4f4144c9395e9d63bb153c0ee8fb1c5659c0bf3d4ddfc759af6b6c44852516df686bb14873cbf5046b3b3d33c5d8d81027bf5e3c51f6fb6a1d54a77c46b0eb4f99a9da4ab03b95f9d3601f553d479ddf661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2 +public_key = c4b9d087866b29244c374e310e94b8312ae3034659756492897e3e79ca67a9085c8f7449c0bb9a6bbe96246bdda028cc1765a8ba15d1d5e360cc3d64e11554f30cfa150ef70519d73b67b4a067dd807d8ca7c435ea987763ffa5a23cae549d7fc9ebf6952e36d83fd2d1adbb10b65d432d91abbaec22de52dad59c26efdc026f37634741def8ca26b9cce3097ffd896f1cfd830038ffcc8dd0c8ee956683f23a0fae5b43bc63b6806c469a4ebb8bd35bd57b375e726bd7ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdddef892d588d06655f71d3e033547cf5933ec237b22bf956e69f1d01da0c55a70e5af4a57b93f6fcaab2a44bb079987eba57223b4b9dec6dec6464fab4d58283b8cba6956c89fae8f09e94e93c2e225f824ce5413ded2518462c279edb1c64412fbeec6d75d47d8ffc5b9f1477db32a7d67e30c6d9dedcf3ec3e4cc1a4cf35342af4e9513fcfbd57e82c4ea52626a56f793edbdc5719f63fa5b5fea7bd5a116dfe95d0532e8cec0fff4d1674d4137a5b45d8bfcd31752e16465891fe508293fb99ee2407ed34318700eeac42a6dd905179b293e62ed0b69590541ecad848decc94cde8c898e70a5cd30a8a3d5fe97a2b039f390a3b1fd6aa22909cf0134a27557f8b6fb5180276b7d65c2fd63db4ff48cc7d7d93d0cfc418b97762c42bb0980c704ee975ec69397e73a77e8049de0f50b79b243e87bc3a0f7c770e50abc62e8acbe297c58c58055387bc88ee473e8eca97b6a6e75d4871cdde1e8d6e46d3ed1bd4d01dc62529434014c5068c3ab3d4a909a0799481f7a8a2746cd9ef6f13efe22ad318fff73d6edbe162538494e3c5cfaf2853c6e63b675cfbced66add04a2bb3bb4974e79aca0de9f7607a71d4b4c9980a86e6afb5a84bcd2e69419059e0615eeb332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d4507fe82fcf4fb268538cd7b81aa79b6bf8ef5a657e0f8b6b2f3a4279abcf06ca2a7a4d1312943d2eed86e9eb1ae3d30d1cdbb228d6cb87b56ed49ee6bc6aad984d34664b4902336d6e45a7449cb667fd7d59367f3be42746636e457f6f21e603b28670f57e13d28ce6cceef465be81cc3f05febc13cd7dd3fb35924a641a21e7df5cb65fd9a69c71bb8000cf3a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ebafde502f75f4f7bb361866648cd4c573bf47e6b54ce3e810c7814ab5cd27eae905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abbaf229c4c294e7a70f97bb6e1e9be54553eebab1c80c8da7459258e44a234357a1c9cc475ef7951e6124efedb27455063672245460ebc8b6b21e6b35ff401169ace16a514544e54e798ae3155809b651ca963f854ba5024d7920765a1408f7dcfa4bc50fe867bd5bceac55e6854f1bdd80dabf538848a8dc7857f10c4c843c46b27fadece3707f0ec03059313bb96bb144996c1f7a170d6db4063ca135ef550836e167adea545b3a0c55c0ac5de3fcab6f8f42c2c5c09313646117a95ef46536dc74d869301335a2f914d4840bdd9cb85a3d034d56bd3c677f5d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641 +public_key = ea7e8a491b3263efd6bf7fa9cfcdd0e81b6be6668d15bef4bb49be524abb09c9e942b6ded39be974e36376a7724ddc7e5a993eaacf5f40c8dc766cc57f8d7bd5a3f6044d3458b84703ca58f8e57c462ff7128654df4537fce6a57cdebd6fd8c5bf1e35b2d8fcbfa4b96d5775764d6f92538035effd6198a9ce1ddfc8dc8988f95609ce974c4359aeae4f7dd4870c63bf79886ab2d4cad1c89a90ef32fc1c8c515b7d2aa9cc35759ef593f44ea767916478f94e5fdf8becf85a80f4d6960298b977a7abf48d709e09d5c27d6ee305ebc04e50294fee4fc79fb3ee5454c47b367fbc09d6fc0dc466efaa75a01e6e8ba47180aef2101f5656ba7c52338ab1facb0fa6a75cf6ef3135911d67e4fcda7a5a37e205547018dcd607c5aa7104a4a87f66c15f557afd54ecc6c6263fd68e79352ae7a1c3265413459939764a452ecaa937c8fabfb277afc77ce7814ff9d34783b8afcf9882ef563a63780cbabbcbf7f501d68f1c7fc6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c972ebed149be06bafe7207fe1b24b086836b5269e5b93a49d90cb3c45877c65fd4a605cc28fe828de6ca1ea5d56938a6c975eeb3b4a9b09c5aa9fc44022e5d9eb9d15a996f9a7b898cea466dae4f0065a5b1f374d52fb4a277a011f3b3e8143b0545d7bef8f9e68f528dcb3c9ea5df3ade7ad0a849c80e779d17de34cc606c84a59675db7776a468659344446bc29e86b43cbf0435e6a8be33065393c83b85313c53b71a5bc55fea91694beeb397618d6d3caedaa8ea546f53763b656c99ea50a179986dc3786a554b81a3e7fb58564dd69428cbed7bc45a642a8ab9dcd13fa3fa683ffd1fe4fb455930b8147d6175c6644df17246c400c4b619c9f2193ed1b2e8e65f93bee58757c14cbfc958552137b9050d9fcf84532194ef8648b8f9e58d168fe19c1ecbcd59480246a46e255addce649817a052736edace8a262c36f7c37918db789bbe77ed39add095da50a3e9898d73b54bc3ee9ed00c88dfc87ac5c41ff35a959b1164b4921deb939eed4aa76876065e842bf76a27b8699fffd1da7c40de831d88c9f5d891007fdcaf264fbd9f80b8e4d8535e774fffdc23576acf7fe5b3eb8c171dca2415e15e89421418a7611cd5bc5f6ffa39918e9558c6dbf618b6e2b6d38bf9af569b4c3aea0fa4ac744ed4bca8ed783c4eba45057daef5ec5370b87dab4e9145298170d64caa0cffda7c989645b9285a3fbd16c16e1cee40ed85a6ccd52494f6f01d6e807de2e80882682660cd05ce4a6fd785ea66335d78f9b9ee5ffc3ba0833de333326fecbcd8878f296d64cd1b67303ed133f3dd106c61af9a75a7fc64fb6bee1a1649fab356c1ff6b916fc5dceaa7cef5d2c85da93187a21d1eb1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee80f53d87d65c039f6bfd9b03136db5af95846573ad09c42573c83396d9fd3e5c0b60d92b17a83128a4a9f1a6a242f528855d4846b3b7d08fa81dbb036f6a57c6ce9136789af9690a988e45ea6adb84e32ec55840975d83f388877a93fc02bd06fe4cde51efa1814b328befcca8991cd28d27f4485b50f5b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c +public_key = 14345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea92fe2ec9e339aaa4bfa87a198ad4d46a7b666837f55db6f17cd95db449e9baa879bee4016ea4f8ba975da26cfcf59401237accc9d8efd27e46e9439b1473bb0ad7704ff932d5c598276b59c4e9402d681d98ee1f71cf0d38ede10b4d7634ab2179d7d7363af0bc4647dcaf08f9c6744e7ea8a2cea9918fa3bd8a843e4ce5824e2f04877eebe709d1a9623c3c428fbe11b1e89073c9a3d34ad16baef165ea07e6880147360e60888ddd5b0966d36962df1af4699c96382cc1ce6b4fdb960135391c6692b0c556a5b9ad2f8a5ed0cb0bafaf406868ac6f7a5a44b72282e535e098fe93fc9af148ae027604c47ce4e4fe4a1bc974685f89ac7bfb9a644dc4df35a664417c57a8a46a86e18a1108eb87f4b472707f44027d88f447f2878db070dad1dd672f0fae9e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d1bfd42c744555049c49bfbc2577738a698bc599e0f56bdede555b171838f6086ca365aeda8eaa535456151e990707bd3305cf4e2de61fe3e24156691daa5cf3795654efaee1c4ba022bdedd18d9b159d5e47cfcd0cbee165c8aa428b180ea394e6c92bd6873e133f8e6ee916c94c813a3e72df3815127b937b9646a78352477efbd8b5f01395178c6a9ff42c47d9bf5fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f2774dfe5abeef417e10b3e7cd83df3838e92b23ecb9af96899a69b106ee25b38f8f29493a997a33023661bb7811c4593e4e579f9be7d0cbb6037e9f73a3faf4fbf35f8ededd398b7085fa925968adbf56cf23fb8578dabffb937c364f5c244345f8d5bdc6d8cb0666984775ac195f6919d8cf2b6d214f6a8890d4aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f530ede4a95fd38f5354a8ecdfb7a851a675c5b0ec2fbe886192582d2fd8ab37753bbe8eba6d848949731c99ba92278a2833cc11ac3bf6045e2bd6557f9684eba8dc75894f4db1cee2cbfbd09196a7eaf9d7a2d8da50c4a0c839284a44d896e706ea9eedd099e0b1467b88948c89778788cf6dd4436fbc4bfd13bdacd0dab4d85b613bba4f928bbfdbd4e2eaa51b81845c3b7e0bbc8458027a4f065d61d0b39ad28482646aebc5458d0f7dd396c99a0b456837376110488f49a83f48372327467ab87870e1eb3c1e6c112ab3d6d486a99ccfb9b368a0695c6c635ed6bea5b56fcb970cf34767e9b8cd8f806875cad87fe4716332f0bd3189438e37d97e575e59e5be790558273ca887fdafa6f8ff6c53879adbbc07bded72e6aafdd3aedd89677852d41f33c447204a3fc9ec1e4935111ac739cdc9fd7ffba8c0c66dff5552f4bfbdfebe9d4f65cb4bf377739fcf97cc54bfbc41fdd41e543e8396e73d229b9288c5d68e87d0dffd32d58ec46b646f07e940d97af370732543f60c6ac94337f866cbfbc90ec64424c67b1c877f6dfb35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866b5f385c85c241677f75487d4156c85db639ad84ee051f438bdbceb619ffa155d1fe1c5e95e9d83343fdeccd441554a8cb5a8f7826b04798fb415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e +public_key = 8bd98be4597242c95c974eb195ad93a928b8d3c3df34dedba326943a8b704c09a6dfa55f700c488c38a33357e6cceb65860d8a863e62e40a544c1ae68793f8f47c4e67b5aad276a2dec4c320047e2eab345dce4982b96d1d13566db4d9ea3d72378ae729546118ad4ce39ea2090b60030a35d5b360f9f871cae5ff37e63954eade0a8675abcc3717a7ff8946997883d607293267cac89e3c96a98576c245ed875642982fa1279ae73a85e14baa4f0eec6a13bd9cafdc99ffefc1af7acdae3c747b94b06517464f654adbef5889ae5cb4d5d17076c9d3fac3b166ddda2efd89bfbcf32be5ad5fdfe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a9733d8c7b14dd2fb3fbfe1d96503a3a0e84b9951e88a78fde06e6641b896d375e903697669968f6b83ef2d88d47768ebd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0b4f340acf85d1ffebbca97be77d7557cbd027e755f9b8e913dd4b9ebb374bd79412bfc28306867053ef2de58d346bb526de92f128c9316742125f75ea2e4def7a61db5d9b5858d13c3d4216f783d77c3f57b76fb8dc984f05ab5587d9dae4691c5e9c44e4e813e4b61e6664af5c970ae7a8117e4217745af087bb00575b1818e921a854b7d953e29cb1df7d4e6588f833afe68ea73a04ffd82b8b641d8e964937d01196ea7c4dedcef74e9c1e6a8607e8e30ba6c5398e3449d073ffdc82f570fcfaa2bd8847a7187052e6b9d0d9bc9ffcd217373bcc7b8d38245e41ae597077bb00b4d8e9fbfbb55ec31a746d2bad7fd653fcf176382b6665d45343d03f731827d23fed46577abc342bbe264e6daef4e7f2a7ea8ed4c83a1f6e996a8db40a55be4f4c0e534cab677fa1c6b693dfb7e42fa3323d5f75289a1feed2ee6d4722737e776dec7e7acc6994fd6f0bfe32eed03c3b3bd8f4458d93b0270cba21ebf1a8de6e23ee8584e68ea5b890ee839de75b68d61bf5d555fbbc9e65904ff0aabbf00ee7a8f17da5b5aa7fa30a76827597011f3250fde910e8647945ae6f8b3a18dd8e5c36af468a7f6308751d4e41439b567ebbd3d72538dd07eeecdfaec5ebe3538afb023db4c2f666228fbd08eb750eb681fce77981b3d1220fc4574fbb8a44ad5dbf7cda8369ec38e90f64987ec6d0101aceae7a807158cc820d555b8f644b3b513d7cb283a363c70a4ea1adf41c8a96ac66fe7fb3c38f45e5c3a68fedbf717147f9fb77a1a68695fcf995855749c2fdae0909d841ec332e86d2cadb69e55438b9d8ccc223e19627410498e45777907d38dddb7391d2ec9f2747e278cf66bb2be4f6eb8d47bfc8bcdbdc68f3beb2d87b07044904d5b08e84305b0686f923985a49acddbea663dea08948c9b8d958845e8d0ad3933976c464b4ec1845e216d84066e7e164b3fd41886a1547d3c584b747555eefe8309f18e0d4acddf8c5512b245f637c9448c47e1456995faff460c8f10c7ac1073d47c3764077288a1345c23fedc8fa6865fde5facb49614217f85d34ec151e4db55cc0ca2d49f3537abf08ec8b3da02e5ab01384eb36e9f19179eb3197cce9df328bbb6ff61932434899af0e412b33eb0e0ae9d848e555866091c77981e753f9afb95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c +public_key = a6bb3b94ce81b75e918a35f35f2f779dfd52e1e3de695f557cb3faaf94e834c4f3a9f6ecc24b5231d7590f863e814aa1a01f3c0cba97cb3773740871ac2386883e748355a85f03b275c3f73496e42153be4a2dbc9ee77ab6cd5d2ba6f28906586ec831ebe8cf6f9bac373eb7cd9d4dfc768b1b7e7274b33f71dd8b6a79c4aec3597e1c9664c9472b7ce00c26d1f27bc0aed37153ffdb327b5d32646f2a8dbd780c8f4777e5ac04bf1e03c2d4b3eda24be4dd0f33c2afc2d983627bbc84600f3e349ca59626a99eeba5dddefe8c9fd76f0ffa5238667308451d2d52c6f9b127778a3c656214af3dc8ef5660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b882bd365ff5e3fc76ea03689582ed45d209f2444c6a76e6344ed8a335b6681ccbc7b42b50babd3558c64da75d88f61be3699fd12135a8a659355503918caf5da2ce67b9fb9f771b5727493c921338c1acccefb8d201039d28c968aa3a40c3af8835f63bde23b9723af45ee3c859997f46feda12fe906c1485b0c5e09305e919963393a692ecebedda2c88a6133f6904d2b124cad7a6f17d8e8152b5f8f8dd73bfcb9eaccc6cc98f5ac57ef5341f6c1ccc736db53f659fd1ff29a6c3f77b42fdede2087987ff37211de4e5fa54073551351dd04b69f5cf64b0ffe9575e27ac19ac5644f355231bcdd70348c55d7c8088df1e5eabf6ac4c5e2957a953f5a3f64e84ada1935e6f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a7240eea44fc97544ff69f77dc593935bdf87a52a1a31cd2b9ad938d7407b5851b49eb2af31871ecacaa7710b6764a7e57f8a6fbc3fc483a8393640f6d2ca55526fbebe57ffc61cf8d2b969ff25ce4aaa75aa4c1dfac9c8efc23f7b2a93aa889c9eb178bebdd9e579ca7bd30796cd3f444799f559dfc0533d8946a451ca49816c06aad3a6d3dd3841ef03ccc1075df164739feb342adcce87bae2f66df00ce94765eb4f291a5152a4eb4eeaba91c3a59257c03017c0b8fdd03b07657bb6db4256a8a5cfd5d7646813246385b348ec157dc6eb3be4546d7eb85c2a6ef8410e8968743d2dee47f17ec8f96c7436596337d69f5074485bf4a288833f2855787f9ae8d874c5a2b4e422157f65c6fb5e68ec228ea7023698feceac60a8340a34b2a08eb03dc35da2b453fb7ef9317db1c6db57f314dc3af7766c69b84e6f4dbb1e63ffbdc71fab6582473f93c8753d67b025aafeee1c847b1b8a73455a740ae1c3a4c21a35ad20fc36d563be9bc55350f565e4076671fdc77b3c4aa3ad6f7cffad1bfc4fc98fe618454d650e89a6f8b3d6d7e086dba68c2e3f4d6ee00b6d37e727e47893cdaf2da97769f04b2c684e9fd6fddbe0df575799aaa3de388cead4446dcba8e14368f83df520d7ee453b41ccf4f6be7cee29ac475c45742ddacf7d6fdda15780a9056184add55a1f9e5e3cbb3feaa289bf5b6fc69bb9be64c1db8e2449e172a8c23859545e98a13735e30e45c3d1cbb5d6f5c0dc2756081639170e3e6e466c2a6df902c97d3bc33dd006ababffaacd4dc046e55951d744e31887155a3fa99dd58a8767b35684445982767c69764dce33aadf4c29c2af4fb5dad5d47d1fc22bdce55a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183 +public_key = 855fa7750ec4e343bdcbdc985c8de89ea976e3d65c47649593c9cfc21fa42a2f38312f53118cab8ed5f0613d5392e6a132fd445a0bb4e12aea8d7465e704b3134c3807d9be9f9bfabd57a0075868549f5930adb01f1e64117d6a66aadec5acb525de561a265e308cf4069be2897568490458121c572c2cc43b2464f37d321274e202b4db27b4efafc4b24bea9f278eef29ced50645a38757708ae6d7ff6763f15ce5a2caadfc2bc4d23c576e5cae6b2db10cc9cf610a5931ab4c59ecbe67fad79bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da45e5288f933db7dff1a2747a6856658cfe02774bc1956e63b534d03aece2e74ecd9fc7f7d48b6f643ab53045bc79da249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4c4e4c223a52a6c884764d5232c78ab3aae896ea45b8e7ebb16c3a317db8e94f527e965023f44ff5d907bac38842ff39344db1e067290ad40089eb1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a596d4599eb6d1d248a37ebcb17335713c4c9a16ddfbf893df475cf7c19792fd56fe0a7505efde58f34603f0d71b2badbdc9ae2377ae313f571d33686d505660c4bace8ea408219e8e05bc15b48eb90d9b31b05ff1b18c422c3935d14e4027d542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472c4d9b1ec31ec887fd6e76ceec6812e4dba4469b3efcdf8a0a6875a19b7acb5e465cc3fe78566a3fbeb98d6f1eb3bbda4e7beb6ff344b74d13fcf33fb67e4bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f8bff8d28a5936968916edf6cf683c7637e4831ce742ab4dff789f1f4378272fa070a4ab52633efd5f693b695dab939bc249447349d5ae86801c4577324c625159b141c5a1014a6e458b71a969d01839c462ee7a3ac46da47ab688df342ff63b83d333161dc98ac484f44b7fb6b3ef6926cf047982c51dd08bb3b0d1ebba3dbf34561368063eb0708a64b937c88b2985c02ae0efbfffe61ff912f9ad2bc667cfae6b0a19ef3fa9bbb9b8c3026d717c2ecef9d7445834ebeeecf15d44900c04d809f667203fed39d8d4eb6756c91f364efd503355b8b12ed2574ac3f17f34bcbeb658ea822e5fa452545da3544c041c3a3f89ba310d5a992b432178bfba078687ad79727def8c1fc22b23b69c05a89aecf469287f052a6d4f58798f1da464db4aa71ab30a94854d1b8c16893b432a8dc2859c67ae68c8c5ad4d04559056c4589bda8765d13e378545b47efbf9dca97552c9b8711e3f81cc7b9057f78a68a59d5aa642d1f9f33eed93df67d5d8639d712d97f0dbc9855ea46905ae72d876e124354669d599fc5923b37b4dfda3f7cb47dfe8af00f6a99a1f7a256681a67d5bf62ddd7096713c59e49c7c561c0783e048cc3444776bf899777e970535c2cac5360c9b53e0d952af348a28e4826db9810f17e10a48771c2c9b21da3ca719c7a64d7b931fdaab0e80b4d6b3af4fa1c09ca38fa59d1fedfa3b0d79f2f9f2d0b36d9795c1fb4f354cb5eddd1ea3165e5a45bc7e1f2ebcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f +public_key = a16730c3d8a8494f95a1d995716a3bf93c727077eafb7886f397af65f5bac2bea1a59d84d1a672a1f98bca86f287f9d410bbd1098c74869b4247acfcae69d6ab354971cd5cd256514f6cfe773f30b687d884e7b700544977993df1f5796afdf65fac4f474b76648b36f68ee16363806a9fd232b8a64f16bde83557b064d405d7987cc3906a9f3dfa984ca4045999a77484ed4fe6fbdbe954a74c13cfcea79ed0e8e24c0eb741af6eda6eb2bc496cbdc539a10b8152fdd78f66751fe78d2f3a510086ec8beb514923a7b4f3ae208766fd95f222dc31fc1a59a883c401459dc73468eb35af62df8ec1eae47c98fcc7f5ad5204bd8eaf70e4d9edc37baae29eecff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6897af88aa8ff184ee99f608cd7b5efca959e13e87a956e4ad12737d53c3be485f533bc755f8aec4b07661e998f10ad7f131b4496a4e893a9c6f128dba622436efcdff3a4ad90d0db1ffe3e0e91ea7a8b87985df75d77bdf99abbfa45cc5097ae562a375f0599d9698b1811fa84a16f8601c731deece6824907f2be6878a75419cffb085e202fcc988779be33f6e2f6ff8c9493a0f6f8442be3d58b3c79df34b7b53c7bf8e6cc7368f303ec380296250b33269158c4fa7d6d75b3b5536adfe6bdbd05e4899287b4b637bb4249db26ad413533d628597ddd745a705f80d136763e48a517ca62f1e691345de746e580cf77bcdb5b607b38d4aee581654a61ad9602f54e5f484bccbd833256af9d2e76262c4d1f7fa5a1e68bb136771c42bf9333b65370fb79a2aba220d4e8a257df746f163b6512eda4e1376aba1facf05deaa56d8e4000d718b5b504f1b9d2f6f7b8a678d0294c5e4be86a68cd82c9dabb1c8392339e2c39c3e037e7a66ef4a185a5d96e99851eb538a4ab872148c2d7bc52ed4f7107d8691dd678d43c783dae94b4aaeb70fe66297355d88f3e008d9916d8768c65074ed4e7e5b45accbecb6446483e7c316ada0c2066f080a53818a4ec0e4973f73df692fa437f6684fc943202da307ad55fa9d643527f699b3cd0d46457cef6560f692864a97f80b4930a3f70c6ff5990f87f1f5711b355f9cdcd18d77ded8ba64f10ba98c0d68e87e4075ee4736087819fcfcbca6dfe6939a4e9a4de2045b53f8efbb845b0e546de6b34ee9f9eecf0c9f74c569dec949d3fae1785639126bbd45137021e9670735488e46a32544fa2b4a959297816d1ac731cb501e6f8bc19d83ab5c4db0cd9a36c7c70f2885a77ffbb726faa2c999928aefb749bae39df37ecfe419efcec419990288b813f8d765b47e4d3e4171b849e67dc7533cc5bb77cba02df72926c3820cd896f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4eafd5264b282c3f933d8c7434faa74ce5875934e99d6c57067fe03c54e487f6e3b14e6d3737a2a6f4169778970e99de64bc2b26d39ae97c7472a41c9a6c6fd45bd7738cb6635d5bb26a308afcfb978df5cbcd86f9bbf77a9f63c0b536713f197febd842534611d94668a33bd339db59746d63ba6007887ab85df5887453f0fb22d3e48bf6c48c806a94cb7bf2356878abef60c87af0548c7198e401c5652693e7757bfe1b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2 +public_key = ad735e9e838da63ac7a4eecd3e574db18cf601d3927dcfa9d228a05f6cee51a63634383ff6ed3151f43c67ad7be9e992aa65ca4dae7b1f1fee07bf61ccaa89b12a4916a5a4e3a8f6a94c86bcba9fc7d65ff04549dc7db301becb280b3a41f8fb6c9bda4a3c5e40eba5a0de8f004ca3e5ce5bee0fff099c99a4eee4eb0c5988cad2873b95821d7a23e54a8f5eae62375a8889f9f7333d4d763e24cfda246785e087d0bb16c53179f531433eb6a6594d1464bca734812fc1d52e9cd8aa661496fc42376c3a0c467428e984ffa2ce8b7f32659ae87accac7df3938592e188a3c20e5e998fdeacc9aa837a49c56e7a850c89e23ef478f3c6bbb5ec30a64a8a2cf25274c92ea953872342a96ca3235ca7a9467be65f507a7ef6b30694f72bff75b56d84ac89c4b635128e45c7b8967df5e5ecd7e9e368d4194b7eaa3d4636283cc07f339474ce1ebdd1072eda5977f5574747dc07b3f0c7c527aca703dbf3bbad80bb7a4cfd2dd9b3e5aa89659121e365fd6cb6fd15afee7d779a978b3f05e0915b6c16a3501427f1efe6e085189c3265530c2ae7491b31713eb4e4667eb93e4ad34cb7dab5d566a9812377cf24076fc3dc748fd58866beb02dbb831b25b7b7383579376fdaa6c8a63f32310f5a4bc66977f6a458374fafbe4e4707df654c42c94a5fc5e386a57abde4ff934a6f3e4df9ff9015f7c165870fdcf6a2f95fa195df2ca4dfb7b87687ef53dd54b6706a84a0d7de3bbd4ca8446efb77609ea8e5a36eaf5a135836064d44a485b5e850f20e53653838e5874b76568516e847a2a9b186e8a50c34c2d3bd839ee580253ee019bda13fc781623cc313c3dc27af58106941a66b3cd958eaca7c7e3cf3f02f098746d4fc58f4c7dbf5ffb506d7fb03ec9c6df2e79ecbef1464f6a4faa513e47ecad81817ae2868eecdd867aa6e95dc4fdbd2e9ec36ebd1ade9affb7bd0f87ce3e3ef52c988300b05afce0d7470cc3022e96af0768dbebbcf62b53346cfe3c1544492febc75ba96bd73be58afcd6874511b44bf2edf7f4fc87c1688e5fec59f7a043f699ba4d244d0886a721426dc23dc96056bbcc80d7a0049435c534b66a7ee6e5c90effa6645c45032cdc905b988781de81565b53165bab605a51bcaca0eddc308a46432794c390fef0427f005f434831ec63b4dcffd7c32bcd57fde95ffec793cb80e3e755d4721f6bfb7637f743e9f76bd8e3c25777c969c6fbdd0c9b79d6f16a00cc4b00ad7ca4f97d4b2e54d9d27524f6b80a6e5ef85447b23cf9af0036c6ba486862c8b50bd3f2614fa0e195a3f9ebc303770ac844e788d5e41ec6acbafdff4aea3abf8eb599ce93723b20c86855a0e31da89c0aded8a5924897929e1c92c7e6ed55f642caf928e73f29db2fb8cc0cc2e39fb6caa259b5a4634cfd0a532b719903f3f831489a2d49db4c5b5d66b4ab5a43e6442be62417d96a0ccd34259980485ffd50fed469f3705a7a0411fae4baddc01d584f904e776c36681994c304d37bdfb84a69a81fa66ee5ced5777b571922988ead7e4ff249926fc9cc4e93667ee98308a434df74dff3c5a440948437a7c500582124574af2f5f52e3f2d19d9b5e946a5f2fac8f774f69c48b7874417cbec0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33 +public_key = e0c9e90b548bc164bb826874c29dd980dab529866b952cd1c20cb4ad363c681336b24ed5fc338b1788afbf03f2bda8e974c33d98a35666eaabe47efe61839d6ad65490e7eaeaafe11719aad01fa060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b083e621dcd4e7ffd61e93cc4c6ef09ed9fabc3d3bc638c52bbfae40d746cfcc43b7576a240540c05edc14744f80a442d0555d484e92bcd9b187a56691b63965973c779366878f85309ecfbcf7dd6d4832a1855cc4b83a847734c35de9c508b2d29539fd2ae14f787286ee97b51bc09208dc559446f1076f02e984a2bf7cae7aa1d0c5d967939aac74cf2335ad432df1e42f5d94fa3b09148e61dfde8454c68b9df2054fd6b7cbee799c9b6928650aae88db29a9ecbd78421ad844c858cf5be1f9b4959944d02cfdf29f7e435055eb9c2775a5cc8c46bd7e131f90eef3fa73d46f8d7c55311a8c2a0f7356139f153cb4050ae5064c5c3116dd7a964b33d76bcd58d9d21b34a2f7806486bd2835b7f98ee64ae496d4264f89fb4eb15b7e5b7f32b6c68b1145ea42bd9bb0d9fc8437534d2b4c0daf538023b29df93d93c9813688dff608f946dcf868664322bbf8dce7f79f68994ba5a5ee4d6d4e7e7d17ce4dfdda58db25f4f7c53f3dbe70d45a411b07cd650dd2dbadad1bf63a1165dc0c154d2005da6db44d1bbda1c9d6658199ea9314c18f778331ad936e8aff3e19c18f7bc87dfd78627770dfc5a2ff7eb27ec8f76863c3296ce1e097d3ef4a4ff6b3a1871c7b42c43a6eeb6bd25f6aa95b7dcd6b38eedfd7c73dbed1768cea5d5544f9d53e5c8cbf7ae81a2adf48c8a98b59c3adebcc3a5c99e61588845df4cfd7ec9dfab1df558711c3e1404a739f79b45b1a8a7643d81a27a08c4ce6478c9d25def29723addcfaf25d39bde795e346be8b1b18f5428eb01623347a9a57f5e9d2291be0486d839495566643d905a8e5626c3ccb63d2b978b2cf8faf231934ffc773245fb991cfeb6a3edf2adcd48387b95c346975dfe81158d78154416e08564d664db3045dbb8fc9a7934de51ab5c1d7346a49ebaca48209c8c72363d9944cecb9cab4771c7eaf59321c6edd430c88473ab16f54ae461a5dc613c6fed6ea5e899552e835eff57fc34b7992755d179ad365d5fb401fdab51df0cf2eb45717654634606d0bfa17fcc266193e2e6bfc4559cc575faad22fecca17e1e27cf3eb33c1f7d389f2d742f384725e3f68f8159f8c463585998289e58369fbb883caae21b87139f5fd7ebb92b11ecbe74f6390458247c45f07ff519ab35b35675bf943f53526e7ad3ac470f73d3d3985e20f77a647c96a6c56cc2346563cc496ebf32fd742aea3adcfbc506ca8cbada7b041ad4f6f3f9fcea77bec0683e1a87c3a7ee3649e59d9ca52a5a5484d283986aafe80557a6bf7ce2fef95a464aaf835c542457d021c65c3bfa457c771fcc47f8c1d56c8b7aa62de843b4dc4cabd8326abfe89fa3ba5959f89a7f805fa4b46e35abffdc57d875c558d4de87d71f22e9195bc8b4f8ce8a19a7953573e804e57ca03be295f461a784e747ee0157ba3f83a6947aaa09e9bcae83db9b31fbb8386f7293a485ed6b42daecf2689f676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34 +public_key = f149de49f3b488ac39d0e43292c7d042d5f355eb48b94e887faf56055a688fcac5a71c896414ce75f57bbb1f967215c50d4b5be79fb6dddead229da3d785c19e283f87f784a03c8f53af3e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d16fee1ab3923afc9b6cdfd14557164149c62f8d29b139e6a5db3f8acc9e8d3d274b69927ce658f7836f479c8cd8de38c8f9848c7698b179643b7550f9e93d6fa873515d3c2b69137bd8cc298b5c335b1aba5d54d13c92616f5e34c6c2fc8e86e29e6c137ad9907c8b2ac9d88faaaa037523685ea489e8f96477b7fdde819f8ae1e7f951f2e608c87532aa4f8bdf4cb5658440dcdf5ce4bf7175f961bd935624b9eb80d47e73e84ba5d3adddd57b6744fe439d8cfb3f5e50eb9d0db5adb3def5d64350d49fc4fb842823895e167f0dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa391723d309ffa2aca964790baf960aa12de3334d146e64db81ef09563c96673824f4c809441ee989eec93597e7c5b558a89dfaa976f6934dde8b8eacb6f2f54e8f748e4bdb69b0764fd59352585d66dc34fdc1fe356fab4467d8d650df3f8833e48b77a4acc642eb3ce81fd5ca251b32367ee91dbe5f30fd784a0da15f77d14c5e8453c4c36645f8ffb53272ee95c27533fec8c3b159ac1bf39c6fdc69dd5a5fe597fffb7bf272ad9966a5c738c48e64ee41d663e50526e0f0f5588ac97f152dd028be44aa23774f199d0daae22953aca888fa4136820ffbcc1f2692bc9e9b674aa1f4d679e94e8e8597c74e6dc5c287cde6d444935ee222636b03cb661ad66fb55fe9379da5f1d6b80a947442a46bdd239fe3989e6da86949474e3a5d56a5e6cb43bf5343a7c73b75dd8445f7454f438535e8a9034b9efa7a6bb8505b06d6ec238ffccd8cbee35a94845d7329e44b48e81add928c37d23c7f7656ea84324d649c13d98fe74c717aabe91948ea7698db0a86d44f96b5f5ddc0a9949c8ba07f64ce60eafb6f6f458ebff9d53cd8b9b696a124a8cbb791c1df55d3e4a69fdfc2431dddc6476b4555552deab63fce9fe8783151daaf78e561e1844886d4418e85e0be0f529abec83c7ba22f63335ba8f3043336da897a44fc6a28b44c68a49b437bddfb4d6be74fa5be3d3bb0d633685364d80440ce7e89b6b34f6545e01979ba9d35e474fc91bf2497670bad0da78ab4ce3eeaac86467fa2f919546a57c719bcabc9dc8215b492d64ee8c2d379e889f34b8dd63847da530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d899eb4904b8f5db93d063ecaff25be54ef8c45c94758f3d9b83abc2ba66d98d3bdbc53b7d06592f38ef663c777dc6daff496a217f8fd837fc3a218ad8c9bd4ae7c66be35c08e3a955fcce8eedd7e8e68a806fc3fe218b87f87bc332b86c36f5d900ded9f06f24b75a20cc465f84751113db47ea664a75b3d4ee9d38a9c747c6872de0a57f3b76c60585ade64570b2ecf8548a5be4996bd2fb3d16a7bbcefd149034764c8f0892b939468e697e39f9b45d77eaaadb077d2968a5e541898321da97d4749d326dddb2b9c587767fb56b9ed9bb3d91cbeae24e769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940 +public_key = 2d8bd180596be297a4631abe0d48a046dcc99c99e2b8255fc45592a2b6e23075fbc7c450a674ccc3abb27395738d177e7579afdcd3de74e7c7b5ac5dc245e76343cfc5afded8d9472e13c9b36a6d38bb44756bc31fbab62893656ead659023d3701ae4b2f785d98896ae97953ba358fd63d9111fb97498cd7516b0e1898e2f78d3c6ae3d70f5bec346917249940ba35e3ea954f6dae3c343a09c0cd3d8e66853ceae0ff8b22e84f4f54be897fae1268a6b867cd9efe869413e754fdea2a147c0096f83294e33aa6c324e1bd570469f0aed901f35f13ff9b113147990b54cb35ef68e0b6c7a3a90c638b7c483c71bce344bd65c988736c4756e0c8ee11bf5b810fb3cc4187363a94efb1fdde1c3cb9b0d5cf57fbec5685322faad5cdecb0f34d458b56fcc5a61680ff677565dac1ba9b984c33c348babc7d506b8792664d547389b805ba01e4443b5e6db9b4d7f8b16dfcd96c4b717baaec7f400eaaa9853b962e8a0c8d966458cc4cf03ef960c447c7bf05629419478360cdc945d6b9a565d4d854cee51364e7a9aad82b64fc38ad2e4139b9e6c392dc83c050d5f6e1f99da9da89ed68acd3eb5d2eff4f2c8b3ce5f80a12c6e088cc2f9d3c59afcb9fee458b05e35c9b4b477d878f357f3e4aef18adf764f9366ab8752c9248a5694f96ed46f405ae739ba72d5d652c614860e4e898e45b72bf66d597d89fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed99dd48885355f193ddb1690b919faa2a86af03a417a8ef0be84334fff5c2f7dbfe9eda659fd3435b65787f38bc955fddc584162955f8b8560991c4080adc12d87de80fa4a2cf7b8547d8bef2a44f959b9d05b6faef83f704ea2464f57b0157c55047ae8ddcc17079e118c8a4ee3358d877251a7deaf86684ed7d858a94bbaa4bd30de895d3ff3320ccadce636c2156471b76c48d53e6a7ce2a23e7c39c48bf4adaa0dbc8afc034b43398b9f1c56d407a4b8cfbac144d24df6ae990db231ef59305f9f7afdab048867a349684b34fbc5eff84b7ed6dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b33df7d6657f12379abcdf48c6967834239e2d4ad211b73a77d681b61892877b7e102a53cb56d2e3ece704ec92aaef60da8e7c63a3d62b05f1f7a84500ff9124ae6630df41090ac81fee748eea878d53969ffaf0fb95688fcb3d2369e0f154bd09a75556d890409cce0b2dc6cd2a59664bc4ecca3d4725910e3eddb0c848cf7f42cca945f1568561bb90d9a4c3dfba83075ae6fb3ac934c865dcebaf6fe9dd5b458c2264fdee6ee1e78ce2d8656908557649f9e55a8472d62e3b46f739f095b5fd5af418074ef7db9386fe9d673daa2abf8881aa3474b7ac352c5dfb0bf1fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b929d064f3a863eedcb67d7215f456cbbeda2c34d61a9f5a140b6cba878a0e5df83efb9e166fc227e7e6d2935e8d96649c06ae9465aebf65fd68eaee7a9ebf987a4dff437104aaddc9e56f110779d66f959f278b069b3c781faf2a0f7aae7ed9bb0c3201565c0b0892a62aa74ca7bd6b58d39066a95dbca4e76a3a3246e2269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6 +public_key = f3576ff96e54114fd94855b18cf574d868b0eb783cea1eef280ce5c486b122cc80093897bfc8ac118f421f99767bd4fb0f04ec22dc7b50d555614e338e6c4368bbe90f9f608f6cc69d8b33f1bbd4de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f1506587164d3d2eec957e5a914b9a3bc4c45499d533073f9c7984e77fe69c8639de418ddb177eed02af4725ae01df89e45b5b385dafef663586ae58d9b33ade9738f8458fe6e28909e7641aa673ad87fb12526ea326e66e27e7fdbdc8d03bfb2b6ecf18066e9d4facc40e9a21bcca9d4da71220a4631e95b25e960193af2a39b904bcbd2f1184b79a97b3dce6b5e4b5eaf278913b7a19503e1744fa77a68cac91ceb5a3ca9b354a6096cf9c09c5ac2b44c6dbf8a250834d6ffa307ea3434977d0097d17daf692b89d0874db770c4eee3cfc77bdcf606fe857368c8e12983afa8633c97d115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68d2e98b2fb558f463a7477b9fa7680f1e65706a888b884da87cc7e7959e56f896c182b53e464721e46a2599fd201887ce9b83d4335db64efab2aadda125d84a6e66584f767854bfe684c547da7f66b36b6838aaba83f98dab79c58c88f1c6ee13ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd88e06fcdc5e9967a6e9ee39ce5e6028cf5afbb6c47e3802d66d79f6f65c50ff01315a96ab9945a8fe4b814cc53e856643dcd51fb404506d6df1c7c9c25516675ede614eb7fd85c7e376e28076ad46fd51c65494b1d54c30930621c53ee8947dce3c55bd686f186cd5bbfeafc17664d36a2d705d18ae83950b93ae61d84765fa5c2f761208bdf478c73c4d6313c8acc26be3ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940c7db6804dcf67dc4620ee895a5fe6a0fefc466fdec99448273e88ef44e72ae681e6f6cac69c6b56ab51ae656be1ca02877fd98dd44e43577f273f9d50851b0f8a4a1b6c2b673ac6418ccd69dd5ae5ddc28df74dd4732e56b5d7c0b6ee83ea99e25f2a07f95c153aa3a873c21cf3a35c6e37d8f4f70cdf1a1ef8f98bb3be8ecd7a6bd38dc89944a5f913af7a39aabd0f2ad38a628686a735dbd4c45e0b8bcdc2cea902cc4d067ecbd589f508adc0dcb81bd39811f7f3358d6320b3d49bcd9dd776562eb34877978c9929548286a85efb85f7c6c76ff255f14adcf5f7d304f1cc838fa398fb34e26ca662759c8f3657125ecfaacdc4615653ef074a7856ddec60980be4aac95bdc7aa1efdbe73cdbf1687a684ac645f67799f6654a4ae4cc779a70da836f3f73acb95a91fd51f18af32683f52363572583fdff3d288bf632874cb0493ff56ed94481fc86d37420137c5706f51a145fae38adc3fdb885cb561e63a493a15beb5e3b123aca6b6c7f94e9dd2e7ec758bdfc22d336aae4cd6770382194fcba2ecdb1b7a45cc0a48203ad0309f7123cd40f84a884c1334c2ee73481d8b92cd55d43ec0b27dc6f16d48b40ca0bed838ad963fb8747ca714cf1e3f67b81ee32046699798421adcd6a3cceade27ffc73ef3235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925 +public_key = 4c376ba98c3a0415a3c0bdab43dda3d68cb1721d9c5f93e47c33adda2cb07d6fa9025b44524bdae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da3bdfd367ed7880ffa66298ffbb45fd78a8d36eab454675d6a5ea7057fcaf06640bc1b97d686de74c4ec577855bc0756abf5f8eb4894e8776f1e739da45a9f84c9bf3d7fb4336f525b547f75176ab3fefd8eb8d8d4bd355766bd69d964eb3b450a96c835d7b2393fdfebe6f444bd398583e333c54383efd200f3de4ccbfb607ac9990fdeef865bdf47ce78ac3dbc1abe33245d6fa7583c3eb6fe7b6ede7a8ec776b20f7bbe7e376579fd933b86ebb0a5f1621f3d6138fcd6d8dcdc8a85f973faba1a8ef69f5e410bb80beabc67735d07e4abdd587827745a332da24a7b39034e6befab3074cfcb1fa76ff053e5b653b3e8ce834349ef930e593a8f9dacedf89b5aabc4cb5335d963ab94f865bb7c391d6eb1274ecdede40c4e5901279e8719c04165e7b62de394f78a48f5653189d9371a3155df91699bdbeeee705203d886ecfd46f7eedc438c288cbd44445f9949f6c0fda8ca2ad33b656c246fa659eabbcf37b2cb69e6940aa9b3e850e61d39c08c8588347e1099a0d848dccc4b8cd0c87218ccf4f1aef6a82a3d530a75510f54510ac765dcede71fa4cfbe4db78a71421d9f947b4329158f87e4c8b41a92afccc9eb749d66b7e159db90e7a36642636af22cc0d64ece52db7ab44baf3066d691a637ca3e93a12ad0effcd75289953fdc9df3ec339044faee44c08d76e6320bd40378ee1f89ce140db0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66206cf8766ba5ee07d72363c1919ec61c543d5c1b8a5473725167f2ef5e5e8e05fcf9ed89d93377e2c8458f6f6d349e953d658cdb05c7a50d77f5ee9dc1be32bf7e9015defb0dcf42477ee2e958d9630b63fbeefc9adf71dbd38e5afa54c894542ba4d415354204adc8a785ab953ddee0cb976a9ec642257d9af6998c6eba28bf36fdfab86f834fb2d47cc19d4b9d6acd2f93e1f0d4b8ae8ea2508efd9237f5883fde8023a8bc13bd1767fd3895e77803ea607752466cb0de7c5c131d3fae4c57d953b96be93262ba9cb064d5a6dfa9e11fb21b2fa2ef33a385c898c80aa9663565b73f41a2cfd6f3379abf8f62cfa49ba05c3b43e9485f6dcd38d66eafeee4f08eafd67bf594baa361d3c3b12d69b2ae64bc387633ef4c82b9ebe2ca390eb585ea1de73699a8b26b8916f5fbd643645e4ff5df38ba50b5dea013b4b2a86ee1f76279ef7f5b4e42f044d04b567f309c52acca3c764de62ed744a67481ca338861ccc3e843ee1c67886023743719493cc3caeb5e438e28ac4fad6b906789a76ff0e3c7407c874c642fbe1f9b627396d81753ad618a8dcd0e33960fe05017ae2b57ba9096e7490460d5a67fae2660a56c4c4d97babeadbae0f494260877f7077af2536b2ca46e297c61dd94f2bbf5e552afe0daccd2e7047b14fe6607bce5e4a5d574c43bf8c39a2528ade0af782506635e66f6968aef31ddffa354ffaa3f50571a8173999a88ecf7b43c476468a6a4739972eceb68493414af743b9b563283cc8879e6eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a +public_key = c8735813347c3c8cd5f82ae76264a5ff89ed990eaf880475750d8c870635468ef6b406907134fc24ecd977a8c13d43b88adf7f08984d9ea657d34e922ccefaa29ae4098f5b02663b970778bf669d585a975abba6bcf8513d1ebc74adc33897991c44f8a5cb4dffde55baaf909e6597dd8cac1ae6ff9cfbcb270888616ef85986e885c5b6c5d89fd7be8f9f3f4ee808dc4d5d762686fa22f4cb7f55f7527896aaa97a69b8aa50bd9b16cbafd73a667e9cb085f7ca36067d4f84d694e6c83c77e07186ffbcaf6a640c86432e97894caf02bdaf66a6d651998073ba7fcce3e89158e87cbffdd276e262766399a6b8bb943aedc590fa048817deb9d827ca80935d31ee830d9ee5b18b75502dacd7a376273ce19cd8f10c9aa112e6d4b31ff32605ebd674aa1579c0820efef04a9a2b4571fc2cf1a8a4ae2d8deeb2ebb0ce65cd30dfffee63dfb3daa6d82b3d46e33e9d9e8f6d33abaec34f4549e245453ef5eef8c5cd68227a65129ddd69f6a31a24f1e2e3f2f8a7e45a6eabea377c9393acbfb7fab3c3aaf8fd4ddae5d077e7c36ac46e093d75265c58db4b7b47eaf53b8a9362cd8a1248b53098c6b797622f2f893a0ee1edee8c02ac613f0db624d6eeff55f4f93ceea73f553d9b90cd886fd2c364b25c877459ba6eedac8dcfa8b1ffc6d72ad51f97f7c299fd1934857eb995a8e7f8b9739872ea472e76d2f2c39485df90109ba924933d6af5fc30eb4d80935f0d2c87d4dabf0768fcae4cff2179ff0825c079ea6700065a6086b19768fb76cac90a58451d7479965475ac8a6af76fc7d33d55c414f46264c97cdf3d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1f4d50f97ca3e9ab31e66eab18cb3af82e57049dd23a9349ed6bbc5df66bb243928dd3a4b6fee3a0f99725c9c8bf673818b89030ebf8edc536ca7fda1625c8a647bd3e7d55039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651b0f34d33f5ed82369bce4e5089692547b325fff818958f714d8ddcdc5bff72a6152c7dac3fe6707c63a4293ddd6cb88ee646d882338d3dcb2034d8fc63edc72dea8bb0fb8c2ab7e06e43ccd85ce3abfe5e689e4369c749c3978778592d9e34b778ef83dc787446b5b70b3fc4c1ca4614bd1a6ddbfe66de6b8a7e30d1bcfb49bb5f08c5dfafe5b6d63eb06c53a38a5d0675aafcaa7d0fbd3e0fff968300360ab73ead95649f0bb47e55b90b2593d9b6dbb0477ba849cddb9f8bf6c774cf8348c65695b31c9f1e4439e976b4306a4706acf5e4a85e5867cdbd77b44c798e1220f5cd3ff8430383600e4ba0cdf8074b7bbf3afa3be6fa73caf40d644ab1f89ace0c8a83af6ff652f37de265765458d6754f73e4372add9cf5215bd39fa516575bad82d34288ca3e0d3be57dbc7ada731f6fe3fc035fbc5b9f1406dfc342a451b933d316da2ad8a9c140e3e3d93455327c187547809fa57fbaf99a843a251f8368b7e5508d3faa57a42f965e520433f9675add0359c5997c341464264986fcf77f61d16b7a6989ee33730755afca0f66b6c98cb421c8e4b46d0266eb1a565db94be44d565faffef36357c8093a3f829f864973e59a8e7ca992b8faf0d6190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60 +public_key = 04a592c364aacb2c8969aed6acaf9029c58de07d50a2c78787358571aa50668df88e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a28ed4107cb723bb6d17f9ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b47dd37a66ce048a9dd27ad17b38c6698d491985b2af8916c547e9c6cb16c5d6171ff9304c4393f8f74ee254a3f13c6b0f3e10554fbf92799f21774beaadf64a7de6ab581637ee5a1aa3ee4da79375d4d036b75bf6d46e5778f58caba93f8640bebf4983ce7ba3445f2ab983b685644b596ef66acf749d39bdda3ce6ebb81cdd0f7e8bf5306dfbe235c0c0ffd7873aecc6b3ae2f3b2cc3bb47d1b88424ae88393c43c4999c32a886807cc436fbcd5a588c6eebf8ed6a6eaa9e0c19a604267992603e5e7c7c85bf550482735e70ad98c857ac1578561aea2f7e831223cbde33a46632b7e24e4d0a82a8c7307c23d6ca25075b58f7f7673d7cb5564d42cfb9b7f95b11a55a9fd63b1bafdb60f6931a0caead28b485753446c1dd5e98edd7189bf4394d7b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b7ce729e7ae23ef8f218fa5e653b5bacbdd147a8749ff606ddcc7848cf4f0e3f771c9e0ccba85befcbd2b89c5036bf062e6b9bc4d828a0fb82f1fb752d48d52b7a6599ac01483ee8ead91cc4de86c849b61954dff867899e5bf284f8229376ac7d97fa03996160964abe56d3e0f78f909f0ec6bc821fc822949ad5ec8a9d728b95b29d52ad94430ad527b3935f4697cfa3c7413dafe81c3fa57f69479e89760a46d720d32efbb662f9467f1dd3c806b619caff8145d76fa235d512f30e56669e2354c1c5efed0edea429b5c77be7ae2ab99c73b4110957aa39cf2c8fa39c10f61c78aa571b953d86869086e655f07d1803a477917ac8b7ed5cb0cf30b3da0cc1466d7598b2058b3899c567b7ea66d5c9da85d85686aa4ae5de5100360c72dfc84c336c14bf29ff599dee4cb2d9da15166823317f2db2edf42f7c0a5ff3a2089add65438dc76f4677ebe41e776674eb4c9139778ed8cb4d5b953f6d2931a7db4eece70d765526f42ae8987454b898f19c5103bad3a2d7bb16771b5e4e91abbbdca9b5beb8ee081ca6521149b60975e02dcf250a355897960a9ffd3ba148f8be764535fdd2134b607976f7809ce97597d8ca57337fbbd6748c032276080ad82195b49753c43047b95a12dc7d195b01dd3cddc5cd91916c37e447acc6d6f2d33fc37c987193ec1fb9a8d017e7763fe8e62e7995a7393e0b8f617da4674078d902dd65a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e898ed7d7ce4488f6d4e0ae5e560d4fda8b65ae29d06ea7c8a757eb354a4e7477d3d5c79858bdfec32fb78b966ecf26ed97ba7cf39b37fe173486bde56c47e2a6ecb14f6f9899da91647d9b673af43d1b87e16cdad71e419d8552235fbb5b0fab725cb5eaea5bda73976d534a881b8c32c5328e1e7306fc5217aab89c05ed6174489bdf41d1dbf61d449f25af35fcd46fc19a8d14b4f81916f36738a06016ea494947be9e60453eb1a297e0816e6ee2f9e5864bfbf2d9cd86743b0ddefa5e2ec6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376 +public_key = c0eeefc259a21168d6f9f68ab15859a763a49d169d615b499a7e4d5517d7e9adc0a93c8db2fb5e4de7c9322ef06f15fa7d7a5e0b5632d94c7a87596d24e950b46ea186fd65fa9643604ef745164693fab8d3a741c56c6f10d8be53cd6a5d83cb1be3f7e6bf8db22f91d907a2898e36b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861636e67c6ae7cc2a4cc9f668df17d7d26795de7f771bd6e4b994b574fb3d9a2eec8b5ada4ae6f40286bb78bb7d1ecc430269a37853e49e2feaab83e523359c735694f09298e2a2ad8c6fcf73b5aed581e8b215f4fda28e90d3df9db4d95ead5321206daa76a343d5c68ff17ce6c9fb340dbb8cc7cd3ae5bf9df243b93233af6b95eb5a7a8b8643b0cf5a8124e52b8ea54f0e366861eceff536d888baef85a62299c641779d23b7b92088546f338448c1977804b71781a554bca5f14cd480c4fc5a76f69055e6139abaa54c4f9e8ad502b17a5a37f7a7f33dd63c5764dd497f164b24e5ba3a626785bdeb917a6b77b175e653f3783c979193fa7c54fb895eb338e7af9ef77ed4d8cd230668c14bc794d0ee4412f9ac905891dfec51e06fc6a5ad55343ef7f68e054da45c47dbf617ef6b39492e4a3b8592bbe0359bc017557379471f0aff367e8f635d8494c88bd38a7720669a1f9145367b9f090fc5df16cd34c8fcdd9b7cb9ca76e75cfd69c36987566d12cfd74642467806dade29c9cb52c6d9ddfd52394691d83d6952c65ef498da51f79eeabccc66b3a41747a8b447d7ef8e116eabc04f4b7779f3c94af8ffe888652fc34415baaeb6854d483f745a4bd5bb6ec35678780063ed874c81823ceaf4eb9685ad5420f66f7ecaffbfcb5285472e6cdffb9ce5d1274e0f0ba3ba8536cfdb65d23797414a55f272dbe653a98f33c956917e4fbd3418c6893f8693908e4ed6d69a744e63b2b1ce90e4be696a5c8b1cbbaa57e9a0cde84f896c9d809f7dc933ba82bf786cd5a52cffa9529ef43ecf3b43cd50dd9e33eefb003a5b6f1a5730f59d454c58af39ecd8d46acde69842df7935377da55efc88cc6937465e6ee64c2afebb95eff5ec16d8ae4aa9c8a2e5d471bbf68dc65300ce0ee495fe0ad9e98ba8d37f9636b37dbd22df579eb7f1cfdb911cb79f03537168867ea06de77d48be27bc936cdf6639f9dc02f63270670e17dee5e53d08bdcd7f06451e54755fcab421d584bb613d08ca9d9cab6ecf99a4b43a93ea8a3440a9eba402c9a8fd5ef90584c55eaa450b7a60044fe995fdd728a8b6344659f3ad26324de69ab86bdc6b20b3aa0920b90c71cd108358c8b9fb27645e54af9a0a86d80ee593ce3d37e40fa33d0c654aa87e7209ffe018fc95cc6db54a6a26099443f77ee863889f36adb9597b3442a71fb7d4f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75449efe926ead93809fc9133a92f4f6dfd2634a677878ea9820f6cf6a248ffdb1c4b8ed59db74b4490b87b0dfc35f6cff112f5e10d494e53d5dd3fd6c64cb485bf5ab37f8aeb71aef2c7086d3fa56fddc966db2c53e09b976f986a344f90dd8c3c7e6582c4eaab182766007e503b03b4e78f61cd13d3f7a83732795cbf84a04d78a542ad92979ec94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830 +public_key = 135ffceb1d8046df888e3cf9ce0bcd454b95c09730d6c4698e7799885f3de0e972332544c34350d29c7bc13dbb6273b9f1c98c3a73e70acbf641c54dad64790e83387d5eaaca2f814f834c4745409273ab0015eb2b8e9eefc9a0490ff36274d9fa7b3f8d27a0dd754f947faa37eb92f6454fdbf3e16e4d6b582fd3dc15f01d3ea52ba8b2b96be91a7b7b55e743c4ccb80b8ed863ab741c7f7f187ff4012c539bffbd062ba6be7a42ebcd8c5b6b420becbb41b55454fcef41347ccd984f11767bfd8f665286a56de3e598834b37ca6ee93658999798ebdd942a8e60b7e6c76978370dc3e8027340163f315168a162ed87d4d6d86846a3b60b80104cead814843bca7ab329c7914982ee3fbf175d7b3024a16f33e281a732d4de55fb7df60064919c484c184e874ba96cfe9eaebe5c314f4d7a66d7cc4c846176d759618654ac2a52fe69c69a375ed06f5e2889abebf395fb2d561ba6300b7fa2091356fdfe97c866ab5468a3af7bb3de755836d9784f8cd949445d83b335882ec7db4cd9b62fdf7f757bfe3366ae4365b687f55ea680f27c310f768e57feaab889f25944dbd6b984416e48a254bb606af91c0946c84bee9c5bb3f879a787c9e06f98809e94bdc24cd62d69f318f9854efd4bcc343d64387baf398599bb35308fb1f0a5b530f8f4cfd69d7a5ae5cb66f4f70cbefe1c61302b8fca337d71de900dd8e78386e9fa893208da873c45df0299f0987d8cc647d93fbf5bfb4b3c793331f0fc73c5446cb21f76824cbe419378a224a6830ade17c671fb8c4bdbfe8c20c53a21a4bb8fba9ab8aeb7eccc81946bb5fdbe5e1d08ada786ea55e5d3dbb9e2b73765ff93a6ab74fb5fc7fed5fe6657ac448a1957413cae547ccd76d9936c96dc70c5635c2875452eaf13448959d67cdea3997ef9f3ab3f6129b5397c15ab90f95833ff63e18da4256dcf9f18e152aa59cf27f63e0d8accfe46f34a7808257689b3e48e58a0a11e7fbb47bca988e0a42a7e0f734c0a17745afc6ade85f080b39f3267399d2db1fd0aea5437b83e05e35405aba9dfca4214d371c541a5fc33987f948b2eb7efd3dc909c7938779bd11f64255ed8326de18ce431bab7fe98a4f5210945a7c47479f4873e3c3ca6698ecb3ad50425d66d0bbe5e34d223af884b3cc17bacc14164be0e2e330456a279547579f8a4e9443d914ae5431da3fd2aea273e86445a8e1b884bbe8b54d0196affdc47544c8d10a693780ae49bc8a422c44c556855609d80f27dbc6ea7f84f448e6c23885e6d3a732c469b376a762b5069ef9e80b74f994588da9fff3f8eba6f0cf83a9c905d19e0062bbe94baee0c8c34253d3845779f8c9b515d0ad964578a66da8ad7b56da39edc12eea2888b88bb55b8c096a145c6fadadfc98f0d3658c9729d7b825515f7411a9c0ba8ef3489f51c1774014749d31e687dda83626c6bfcd5b0908d75954bc10f48623838a736e38c1143b9472b4df5e3dd38fdbd7d7f7a2f16a3ccfdd15dab5a13ef7a63f7aedb94ed6d9bb1a79a5c3f9d3c9e374da63af98c549b994fb77c33aab6b4939aeb55704cb611dd84950c41b746afd71576146e8f6f1574bb5eb36f88f8af0aa4f7acd840ea3d68ade3e06e9046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54 +public_key = adefaf54375d684a6cb1fb38bd9c803a15848309e275263779e75b6e4f734dd7ffa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106f9ee3244eaaa58d8df75f8c3ba98896e84e0195e3dad9d9cd5f5980cb5a2f9d27c6a88e914fbf77653b9ecd2ad3cbb04f594bbed8da4683dfca6d708d85e3aaf8ad6e6a7dd8ea2f008e77633901298628b695cc1868756a97d81beafebc7eeba5969a1086de4e6e1f737af56a83c7378c6e6ed4e79a8967514cc668bc8fb7c7a1a77ee29d55068e34d883a8320438ae7a44f01ebed4edd730418ed684796a925715448eec44562a9edd5f3dc4c94d5ce9e3670523facc8876142194da54934096cfd5725a10e376433be7bf8deb085d342cb3c633a085e960f48ccc9c7ff45defc44ed08ddca06e6bec943353c47950679ef2347a29ccb34ad09c92979fed98640e6b8560529cb1713debfa4c769fc7707c75d87cf34edd78e7c4de0fe86bf71748cc1c5b00023944784f00c2e63b403b8217d93dfc959b6bad9fe6b98f6e83f972a50ac0ee4e9eaffb90ae1d1dd5789ccaf05c448864f49ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf438d87d8333b17bea9e59794d49a40c5e3b5086797933d244bf7f3d784933eecaadf8b590feebbeb6fda4875d004a73fbcc90b566ab998a450a9e94d449cc61bd56267d648ad588b213cb9abde2847d6878287930b7eb68b43f880f3d2f49829abcbde6a37a951e82b78b8cc1b93982c7a24457a9e1683d2bcc97b4259519fde0287de00e2cf6cdd85023ad4a91168486ba34146e3ddd6c42ccb56337aad8097bf87c4ea011fc9595de32e33957f2a5bc1db4c57b4c8d9e3e35486d95ded35b2fecd9d8f996e43fbaf7939efc1d32e529606677bb1144374d4ec08807c9c0868b0d3f772f18b755d7bc5c6be2f8eb9ca9dab589185553b744094de062d9db2d68504f17e8d43ae98afd50f9097889aacdc175cd7e6768d626a8c9baeb0cd6cbe92be0af1a3e507575b47b6ac9cfb7c90ea81985a81ad4ac04c3fd0dd880d43b3d36857738369b7898b232bf4ce6e9944526b9ef47d355ffee38f6aaefacbda63497a863f7a32efa5db95179d5f85e8d56992d9f2a1b67a783d406cdfb3507b4e4b65298734f5fbeb66bcb68f9369abd0ec7e4545568d432a685a6e048e22253987edc55efaa3d9274e3dbdc43fa9d8df29f5031f45d298ef734fbcec47f4654cde9f7d5698da7b0c3d9deedeea1be3567a253a1447f3b965dc8f7333ddae88208667353b6e84853a85a99c0c473e89eb5763fe59d678349f536c56e0e4cd92b56ed2aa6b15e8f132ea49fd658876dd5800ddba29b93f28fb3437386f1f846d2a3c60ce9d055a4f5b2b7a5ff88cfacef4bedcc82565f577b6ce2e4856ddce9eb0713526098b5fa555f106adf1229e10347af9026f54a5ec3cb5c7ebf7df56434f276399b0048ad8d47db545becb9789694c7753fffcd4ac5e513cb33f38bbb10c83c9a1a5fd1489d97476d9bc3e4849581d688c3dcbde662b539c51bddb8e889a4654e6a07d9a659e0fd5d3cfa0abc21b8abc233ab978965059c41d21f3a4bc9d306bad9264bf5be885f4ebe86d0f7f0e985f4464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3 +public_key = a9d8f3efc5c946dab44b6bf068e6ef00e7b0d87ca67706343927bfe5defd20d69c4a5ba892f97eeeab7b5a45742cc4ac4d47f19ae7fac42fd51e3eb8385ca22944e5a13bb8983b8457b8af9dcca9e74ff094ca68399ab77dbb9f6aa7ced60ff5641c3fa085d7daaad8e1de80d52585dfb3b2fc95cdc733a573a888d403cbbc7ec120baae2a19527847dbf43f99babf684accc5288a3cbb1f77fd3999839a6ed29bb91e7ea528cbfe4f953778caf3341cba4b9b3c17f9a8377fe2af3b722397419e24874b163470b3b2b8ff4ae72f58983b6161c6773b5ac90969c03e0ecf4669b9d1f46e067d5d4f676d474f64d7549e1e2c3290c9b2bf5a71142d575327e4bedbc7a91bc0ad66f54d298908d33d588951333b3cb89f4abf14b0d70652c45aa62cd3d62d95ee45c866c73dddf4e74a9e559b9e6ab739ffb0da9693ccec3d968a86701ff0ca95b7c6e8b04ed4ed3ace7eafab77444aad4ca3a9d6b5b5d57eea6c074fe0cdef7df68ad254defc5588f3b4a5c51d6efa3b9b6bb35c327465c7b656d2cec6409993fe9ecc2027fe5329ddad63ce0279eac326904cbb6424d9d6bd19e313cebfe6969ba6aabef954b5c8d439db5d64a248c929889620eff54479946dec829c76cba61690e3c541659ff8b5a8d5d70bfbdb6aaba717e8995f79453affb24e4e4704ac3dc84d3eb767101c8f4ffbf4bd8e483176d9bf963afb8f6a9b87638434d52067ce8fb393d9ac579bced80d1c549fe5e0341fa1ff9988dfe7805ee9d6ffaff8e25942d49484a56ede0ff9a4a55af2cba6be956ef6ebe461c5a4da75ee517d6d603b2651e847e973da7051eb71987e3f5583ba51c9fa9ec3e79b45a8a8b5d99c4dc29f69e46f25a56339e365ff36038c79b784bf0a5f4fc79edf91b777bbef52e5c7f3e8059c06157653e335549784a15553ff9a7a2a4d7d887f5aa6b7a2a2669cc776bb810672967cb5b8b9a9ba85ea9e69a8ddf796b103f53497e2ff1cf3f4aaedec0fe1c027995b8a7cc6bf88c4c74218f5d8622ff37128cc57f4bfedecf1ed23bad00c58d835b5a4fdc8fe0ed11e0ab26c2cad47d5caf235fcafd3520e36ae221e9e56fb456f277132059ca196f3bfd994878c794545ba4a04436e8d4231f430b138d8fc0e6480ae5d94b975bb6798ab7c3f6355b9be5dbc1dbddee76342c96d9be0bc893deb398b65a453cad8bef83b805b61956ff9d994f2f5acf7e97df2da66f0d737867828540d2db097076bc7cd3e5435aee1b9af19958a7dfb921db4e42814f9da389ef0ef3fc9578b714b4f2e6be9b89f903ff45aca045bec0b3d84dfd4748afe24a7eb441ce0119941da3e6f45a87c4bbfac0f7c4bde9bc8ef73a7f435e3be44f0c577f0ddb984cb17358756faed9996d2a848d11344ebddf351e6c5a18cc7af8e3bfdd5dd5b143f4d07ac73bfe3a0577f991fd43a585d9513ed017b319358a24b06b7c2fae9f22b6634146cc1bef3a815ec51e6ad6a956b1a935fff0dbc65c44a60534d1375570ccd36edfbce66255f523bb378cff56c29b870eafc87086829a8f8f6fbbd8e1ae09386b8d743a6e7a38384d5933e64565a037ba06fdecf8466f2073eebfd3d1c6d6f947ca2d2ca49e4c4edea1eeffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df +public_key = e71b4ff986bee57636f904c856ac93e1ce8775864b7ba3faf31df51b13f8f5b3caa49ee6c6ae873066f2b5ae52ca337ed7a3690d4ee6196f447b847f5639c5861e33f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c95834d7a0e59a866a9e564ca55b21a48ee63d676a435d26b749d1f64f9e58c3fd6e9d2af3ef5f6300e96665eab70e745d8531e5f5859bbf1a8308977648ae5cf5a55c9fc4f801aca4f06aff5456ea632a94a9c3a7ccd05c8b7c3b09666be55fd72cdc58d8cba687e6d9d201fe115085c350e53ce63a3785dacbebdea6944a46dde6cad098465bed9bbc6e1a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534ec8da620d3d8dd779b075ce1f31679ae98ae569bbe79dbd4bc1f7209ef4ba008bea28c5db5fce8f31c50722e71e37d426527d1c40d4e057a6865d54763843d27873221ce74c67e54c9a9705eae62e8685a035b34e15c4120deb7220c57266cfba7579f4bd9ab156e650f9df7c0ba79f2ba3f14093cac7de5d8dcd92905a6b9fd9dbfd5743818489aeafbedf88ce69f396074a79824457f7caefe334fc84869ff4364192ead60f8d407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac48f223ce93bddb31275b84374cb4679a5ffe8d3eff07987fdd85fbd43e4585fdd9b3ff5fcd3e7b74567ed9674f1d70b026801e99ca27ebc0ed2474263d507e19b97a09877a1b511da3b9845f68ac35ae44187ea14b996dd96c35686eb98a81f2bfad90b8dd0c989b138e3e7effb34573b876289e7c79481d7f47e637a60fabfd40def9c379a759756408636048565cbfbf4c2186a8766d6a44efdbddd8b9d70781b1848be55ad75fe978a4fee2a577f23e2ebeb3395922dea100c578e7fad455949b7c5fdb6494688aeac00697ae1924d84eab375d96f43c5da948874dc973b7670c8f9183f28b64647e5876154fa2cdade65b188b590f5f8eba65cc654576aebb3823a1a29633aafae764ff4486aacafe7eec28774c98d89b3ce8a697ef9f62775b5d5c50847c3ad4bb968c54e086bad70097508da888b6cfd2e5a3b5db579944fd861a5b6e2d58415029e8236fc444fabb77679e019cced5eda38555d7fddd935b08ec0e95d0dc7cdb3c154ecba94d1674d7c5dcc67bfa6aea8b4ef0c53859ba4416d5c1976cefeb6bcad8076e6c1fda63bd77f024edeb5ab5986b386e5ecb7e8c779654af5e5485a96946711fc57206feaf788d1f58bf9ddb4bc7ed4b012e8cb77ece8b35e5b17fb76dff53a50d6ac5437c108ad77f26fa3984586978ceb385fb20aea2b525961f96c63e8fd7ecc4c0268a354a0bd1232becb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a5383d405dafe30f75605087e999e469cf07cc8d3d8ece9b827d7558bf98f630556150b6d2da5dde3d4abb229a9d8c8e32a8fdc0c5475bb96fd00b73f28c59d472c4f488aac0ed647b1e834f248534ff2e95adf6952b83b6705593a1e53f0315613d2596aad44e28af6d632b9c71e9c9e5a6ab733c7e81e54db3437d895ae9b58eda3ce5d7570fb176ec36a06ee6638775574c74425789155bdbde48bad6f5fc91c451c87b48ed4d6674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9 +public_key = 8518c8d8dbab02ff70c323eac1586bb783b35dc8ff3c24ae2b767e2c4a7d16cfa86fbe9fdfd4e113a7501367cd70d73d0f63705487ac4e0bb1c95dd1fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b53fecac91b6c36f37a5988de454c50c5dc354b56a4314d804eef394bfae4c2d385e18fc5f29ef28e6f307f5a6a1abaeeabb84f90f34310844df95a4e6e4f3d8c993fa7f390e6984e493df4c2968254b54b7d44e8d6f859e29566537ff46e1bc8cd6c9b726581cee69140f85c030f4c5b59aa081e813d66433aa384b2a4a3447939379aee6a98936cfd4ad075981d93c53e9635b6ef85f96755f8689b5ce542924faf70bdfedfbea71abf72f7bda6211a5b9807ce6ff368739b51d4d9480bd884c8b45657adf7b08a3cb928645d55dc6264c5fdefa2de3bf41f965035ad8716649a3d8ed20a6986fbc8bfb5b4a2cb26f749264cc1e44bd77ff3f3ebeb9cdfc68744b52ed7bba0b9773e0ef9894ee0d2cc4757dacaf7f4c910fdf885eea581d89af687ac79444c9e9ded1573f5590a3a2454eb7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d32fa5d36b86ea2aa2006c54940a5f843ab709de9d5937643309c12e6ffdd479c3b2d57dd5696d266e5abbb573fdc6feee5c6a6546cb20be88f356800f04e87c69b636cbbf9ee9a7c7e5e2ca156490c96b347a5bc2dbf57a16e452dab5fd15bdf60f6678fe4967b6c826dd3eb88fcd052fbd1078b77826f4dd3e8a34bdc437d6c35997a22f3d496e876762ba5dd05e46c5188dde6c684c265a8f15d31904572f7554123832c78767ff4b5ff525680c773ab3caea93776897d57b0e5d7b949e712344326f19db3d964df9cf93b6638fa378e5c7cb9b7a6f95709d3f62c4ce3d7646eccea8ec04a81529ecb4cbd85ec869402e88f59d731c087c23a8bc7cfb32fd0e9d106934b3de77075f6cc6f787bf4f4bce6bf6329591c484d2d57548110ccb42955c4233f3addb49870be0354e558964bf151fea54277ba14c5774bedb82ce42806ee73f5c6cbe1b7575a4b6766ac355bc443e479a2953a5208de0f8bd4b24edca94dd883653fe3ae5a1a6bb62f5476c089e4f8863fcededdceb44d588ab675f93c286f7f88eaec6ca46f1ad6a4ae1fc64aa15b27a7c3eacdef0e756d737585b5773ab19ef3ee185c900ecc3b765983cc8d7e207d57e6c999c77e6e278d1ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d27fdb81947643a84fe2e73fdbd477ab87b57b55899b3d8d523e1c9ba6917fe5947e7d7d88b9229dd488ddaccb25455cf88fb7a28f64e55c9b6798f39a53f5334dc82fbaf461364ce6fd2c5c94ce0ff3e0f83e624e69310e5b47964b2bfd3a59a6bdd56bdf6e36d731de346f74938abd6d7b4f579b9cfd0ecebb6346e4a46983e60e442a59e4c93fa6222adf5e4a99d7113ff0c0d906126365c467e0a235570a544a774df249ddcd6ffa825479a632343f218d1f1774f0e8b7db96a860fe4da43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444c0ffe9452c464efbf914fce9041e52cacaa00dd541fdf8eecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89 +public_key = 5e5563326746865eb3ef1e7792d8dc1b9df230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab601e602e977ed16ee15508668c244a45ed956aae3507e4d09ac7fb16cc3bc615c12ada7c56e5dba73d7d019debedf8526f0a9366869a493d314d26ff63ab8f51996664dee3875ef75e164de06dc7708a75376bc236ee6d5d3fd33eeea149153d1868679e28f5f638967becab5b9644a7ffd1906771a703b7844cb5cac6e749efd2d38b5b8f03cc466f6027895e24ddc1c1c5f6c6e5e9620436ed593b5883f164a39639d8e3f613feba0fb05ebe5c5d98f5c9cee815768d2a6ff536698a751bc1f9964dc579358adc57eb83a0d33deb9b9354b1b39c6f8dd8d503e99a0f964973af9a9c694efce298d68d347f783d34700c0f80d79f998b49a9bb86f93d7a95363b31777d352b7e82304e5b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b49d5df7f58c6566621efbf5deaf9d97b598970684c588df675f43feb854f9f566188fd0f943ece353cd1a23cce8aa4529bb667d1b9e5abea312a7c6ff08871cd95c6934419f475c1c08395deea3aff83dd14784303b4ba785e054aa59f68ede4ad6d3a03e68c1c6d1a5278562c5f5acceee66193dc9d34446bbcc8163578cc8d65f89b9f444d7f89f46cbdfb6b8c4df16b839a16da95b76855237bab2fa315db48e4094ff8316e260bd4145356bc51bd0e3389dcdaf6ff048af5a83dac573b5b80331d2597c4198f2779fd75cddd00186b8fd26a384eebce6ce9f14be8cb226d2f226ddac3dfbb07b63d925b71718d95daa662dff5dcbecc99395400a79842f5c40e79b46b5384ce83d439f537bbc8a860806e621fef0ea9843467ee8a0a4cf36384833cef076044c66fd6c8f8cc3185f469c9aee33dc529bcd5485548a6e075f47ad89aa8446c0d465bd43cdf0343acc9668fcafa7f729ea9d29be7ea3d0cef33d14beeedb2b409eef97f30b8a7b077fd4ca4d1ac74b3119fadfdd503ccb5819de834a734e15b74d3fe550ee49773b9ddd870efab5fdf50faec43da3a3b90fb0757c6401fad90f98a2839e62144ea9d98c67bc1dee46e8997304dd1c4950b0e34f0787fba6379fb6a93ecb57369b48b3adaf6ef815c615b4a97bdfe910dfb15e83aa10545fb859635d084a58cdf690fd85d9ea4b7fee763c9e4e67b33dc56d37f3a8e5a1f8c58663c8876fb91bbbddb6758288c682373af69c64cf3ab5c46eefc8f1feb7781ad68948b9480c6af20f51454cefe213855d74675cacc7b26f91783dae74ec7a8e7673a8dd887eece7589e309bbf8e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a3aec2456a108a5cb4eeeb15356ca737369669bdb5c7bc10f2f377d6b5fef85e5b4f348015872e45e8c2686d79b9ad6de8b53bd189ec9766c05cd84e74c6e747c783ff3a99ba3d547b7ffc4ae79cbe6fb52d46207e79e37d65c9f3c483adeafc167ae414e671e3cebf43f4d875b78625d67e0fee653e6bd4dd5414579ad8ca4f081db4f1b1db0e1054fa3d79af7af85f31d7d433f700676b8a017d57d15c923a788a01e5762b4c24249fce7c4438c68c6c3fbcccae4a071f4d4c34f74f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b +public_key = 420a3006ae7c7b5ad8178b83f864d601145b102970b30cfaf30a4ca1a8a5bd4e64051931ed68a59e0bfc50d549becea65ea9d9f5aa690c0f35d33bec6b2886ce2959fa189e2def4224e99255863e6d964d505ffc02646a461bb5abf86f4b5cd975765a5b0ca0118e677334af26c3467da771cd04dfc42936099decad9c61d508d939774eaff772b149d51beaa6574fe2101de71bedf0277aefbf2351769fe49bdfc7355db11315ca4b244e721880045daeb68d8da784d30635bc2485d8144740634ac4a078a5af38e6ea2d6a655f87de16f63287f42dcae2af2a82ce13ba6787c5ad4df0e5e3dcbc9f452985ae420f7056f492bb1a5e2343f69834db5038302e65fc5adcd443a8795814e26e15369ae96cebd7c9775f33982458ad75f0550baad77bc74296badcd4cc3734dd0163caf8d8d6a0ccc3f51f5a0874cdc1c67e4626c9c753453fa37b208caf605f3388d6308248b7688c80f6d9f5895670a1397880933af025fda1e54f7a7b512aa87499f7a718f6fa7cc5bf5687add19d60427bdd3ddf92ab9b8372083ee57fe8297f815cd740fd69acdd2461521dbb618ca1ef76f7160df9864ba0872b8c199abe40f35f929d6a821b8ce084ff931c661c65aa2445371b4dde69ff3b767382f48dece685cea5f59c50f8fe45234169c3bbad8e4ab9d68f8394fc513a8faf475590b3bac2e3a4685b8f722d8358eff1af4e310e8454d315670c3a340aafa95258b9057b42def7a7c6f588f6da61183acfb18a7ceefe38c7984b50a940f17c687e6aff8355ed94398f4d8fc93a375be195b4b229f32e9a766e87d40d3b9125f7dfa4097d807a6d263f33435d8f259da5980f575d64af156d88f5a8d2aa2cab3537a8b4f9fa10ec447bd89f9fe738d92a5f84cf861628601f4fbb427b87c2153d4bc44b1a4e3b79baa5ef55325ba8a42e1a88558e55d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526efeadbea64930b699607de81544356c0982e957c5e5186f321b9468dd5dd5a7da97fff6c89673e51ad56e8cda8027aca8a5cd947f3353dae99183ddffaeaee943cb0e6f537cb5ad89ce4f52a78cb72f8ef485deb7ebdaa93ea4203be78ef47447ad6a17e7caf5274f384b36833ad7ae0a66069bc59fe439f7c6d05f064d865b550515f10768bd636c61f0e7a1bdcb3c3065908e5e302fef34a30ae23a2aea2b6e8750075a6fcf77cbdac5350ce624b6fe3c16d1abdec46026ab6b8495c1c7d93f776f9e6b3b543f67ab99801e83bd1867d166387f14ecb4d279b86cfbbaf90649e5d5e4e53f561f95d497d47c2beaebc2c398b306751a9e392c399df604d9ff836f989c41cf86f34b9445d908f04aaa987c27f1c0d7f6efe44c311a589abb5e0afbc4add9bff6f87597b5fe16a53d6c3551b7e6be0a1958a89a739e17e7f0a86be0385c5ca433b68ab9506ba3a7fdddebfbead15e9e228b5b2d9aa3c9b4a2bfc8b35cfda04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996119e13446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f103de0ddec40d14b09439f15e0c5325cbfb069b85caedbd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7 +public_key = 63a9fe0d6a8f811b3f0e3d807456c84c8bbb008d3b126a31424954cbc6cdbcf9ee26be9928f4a41b1371447ba3d17391568dbbd7899e9adca37b4b5a21f7e51027e7710bc7eec56ec2e580031f7d1898bc55f8a3be385d607b3ba666e991ac6f0913617303830eaf5f0dfdac14e67abc8d97d18bdad1ea8c6c267ae05ea15a9a363d7aa5c8ea535a99e15c984ac5d6bfaa2fc6fc44a3b35cb667f939fa7bf676caf12c17bcd25c82e827ff6a85d6e8b77d82dbf1d7066da93a7eb3cab8e98ea24c7592bc6b656e459af34ad6fc2846d82ff1f1da641004b68bd65dc28a59036ca6795d8615be5a93e74f89b8af593ddd50f7e8dbbec41c4556cd47b43f24d92ca473972439844d6e12f4f3233c90cfeb661b3fce65ab464db58c922bb693f56553a6e869bd64e18ae1162a7f0e3ab0b0aa76b8494ba394c902c598c247f1dc16c51d46b8258c635763776cafffcac747985b94c006696f18ba4addc5eb15f5cbde34974569142d969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960e6ea6f94b317d488d2d04a8b42c7fb7d89d52d89b2df3d336333c5089534897dbbd4ee612ff7845c7775128a9cc93e966fccc0639fd86b582a18c6ab2fb3cce03701bb9e0482f7a9fcbc6f26e30710756c5ecf88bb9f402b5b7dd9dc39193737d2d6f408f30261852f1694258d47c469c7452156e706343858f5bc53bd3e917f0066b609b5ed2862433e37fe988ef3af62ef1bee8d78115d1200b776f847ff615c0f594420ecf9ca6573276559c1c84b0723569dc2a767299d9daeef79a9cf40a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb43423fed6fe340e2c66953db13b7d9f7d26e2af876455fd6ccb7841f84c60f48d6d5f4f3cb35bf3bbb9dab73d403a46783329707388a1f433f785d4723c993cc72f84d0e35242f5fcfd6981268b86f598b1157f900f83333c48627e5dfabba59c684db4a40abc330db5daee3010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6f3d17c94ba93c751900e7695f5bf5ba9f14c8555bda863feeeed40053c0d75f696286d2cae4d56a9e5e463f1335f7ce1b8812274dad668a20964476ecfdafca5ca663c6c17156ab3cc8e4c7f3b3b6fd9d3eed767da52b244376409eb7f3aabb45e37ee18a1f744562f2f385716892ca77d518c4bec578e101e45b334ec193ebf782c76109d81a129e81289d531648954163b10e6a1f03bfb9e17cdd439c6707aab0efd9236ba33dabf71196a3990fdb2ca6fee57b6c8833489c63f8f4866c14d2cc1ce037400dc610b28cd9925d405ae75673ed2fa6e7206cecbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d4feff5b56406cd5e796c66a6e97edec7decc767c0b8e45744346de60bb1618d82115d6c5779bc275940e10d31503d555677689f33d09a583cd6f9779c83530e6bfa5a0a771cfe37700d91c627afecbce050bfba252cd74e359e5fc44dec244ccb7842363fa7eb27c8313a341ece431045e62838835c85c677b4f0b67c847dc660592e587d8d64e0ccff4fe6a6b33ee3e745e9125b92b3a66f155646670f3eaa9f73d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65 +public_key = 1a2d42d43a4271e44d1546306137a4437e30c87af025bcc297eb36d3c44e7cd4b0b2dff005fa702bdef569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb4af68165596fd0470400ccf5e3b56714792f7a87b9e13d1985e425695ad70e4ce0b27695729d1c7dfd03b68e52fa9757a2fbd29ad94772bdcb1dcc7384eb14c5dfe8ab86dc0f647526ce31e9aa1aa7f9075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4d0e5ce5f65fd114fa137453462b87117d4bea463204c463273bb7105637895dad28f37ede664e395e4dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd1ad418cf655a5476f51a68cbdb4aebc53f01deee78e5ba679fa517cd76331cf0d1ad9f167bbfe1c956a619825a93d5d1aa9ac5736e6d34e45924b2409a8688c4ef34ae81a9e4858335e40a797f2bb8ed510febf88650cd0ba8e77fd77708551a947c98cda3355852a77576ca6bd54d4bdb9fd973dada618cedffff1cb59eb56b12d7eb24cbef03ef7283efe281493ac8dd7a21cef4aad3db7bcb8c30ff4b2d9f7d3e6fade0357bbf8ce281fc94da3bf1d10a5e5fed7a3fd9cf93e34615b871c8da7db554e021dd522d1f711e1963be54739bd439499990841e5989ad9c612dca891f4b35c34ec0bd743b494b2666ccf5c5f35978f75fabcf9a054ef92833d8ec816d68c07fc53635bdfca29fa411c87dd2fe7fffad94b68686397e6cf593b33483591f4d49e4e7c65c96e8b34fb17e7df1bf0a70c7c59bc81c34f554eb063b9a1d95481e75f9602b95f874bf1c649d96ad72e70a52e935fe1edebccdf64332345355f7cc48eb7dd1baff2d3ead1fd58b8b3a711e1e3c270a90aa2c5c79958f3907ae3cad71ab6e44b88ba6c5575bdcf5331729a65d8acf3db97acb4e91b73afbc1433fb3483e00fe9699cf91dd868275dc5a87dd6d983d5ba596515e434a8d956b2b73b3c018f1ba055aa764ee4f35896113acfda3f0fb9e58604fe2cfd5b023a77d7c6cdceb746724cfc7d84e7bfb84de4b0bf39abf9f987698ed0cec8d7b33de2c80d0cbcb45fd5b1ddbc6680d5b6e4335751ac2821ffcbcfac0a66ff6fa69cff855d07baae6d2b6bab3135b326be2c263a81fe4f3120a6fa639910159b6944d6412af89863736558ad28bbaa23e0c984f04543f6e916d9bceb4f64fd498f3a5be3e4f83b43d443f62ecc72fe3d4f71772ccf3e8c1da9a57a67503bee19313b93c4a66d04cf317cfcc5d2f85b1f8dc414bff29c447dc975923e9e00bec9db958acd795dab0777d838e492a2febb87a6f4f0788061d331ef6e71797bdf23850d50ce902e432b205ec3cbc37631c972999fb6a09baf77e7e6ec39ec2b3489b33baf257c35b9cbeffecea1334380fc35df396e16baa9bad4ada848ec4fdfc4b1b98836f23ab933e75ea07fd59d9c501fed9440be0d80eba524fb3cc358bfbff732d643d0b135c8fa9eb0c73789c465a7e1b3ea78d4b5ab9ab2f4fca1faee58019306855a5767893bdde7e92b4e470e7f1f653f448fbc370c64c3e43dd83987f3a9479f10dc7542da296393e253a68e1eec05969784f66e2adbaa2662459b09638202b74d8d5cbd3cdea915ab2ad06b0877d546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335 +public_key = 38e84df3c6a2dc2389897c3745183e09ce681b5b9f58ce6aa3def7795f85108689652ffc1747662cf97d8b0353bf23693b7db3b2a7c8cd5c5509bff7261cb7c41ff058f3e8d3dc39e42d770724351ad78010eb423ffbae6714999226895bcf3735b9e1972fbbc19ee516e6e7353c7f76a6f8925bbd4a6f9fe0aa333d29d9a16c5c286d4b7ebdb4e70fab27987df23c371873dba5cf846444b83ff9e4d94dcc8ed79a85b645a338d9ca069ffbb8b3211e31cc1f9db938fb73174f8d5ae4a37393553be09e2f71edda8d968ac3ff67aa3374a2356cfec895441873325dc7ec921fde92fe9347d965f25edf606862f69643216b869673b5a70583fe2fe8639b5036dce1d15ea13e2e9f3969c8183f6d2c6dba5c13cd8cbc9313aab478833d747e6a2a48438fd5f9085cf41bcb4fd77e79d1f5494b4bac2b05a5767b9647ec8829b5d0d1365bca7b8ce7b75bffadc68f9af8edb7bc4a48e7c0e3fc4f2de6993fb9acef71cb0b473abcfc3dd39ce895551a297a61f47162d97c42fd51d48b62e5a8882db6ffcfee6eacfb89b99ae2ac6f6e69d77ceb3b6b02878ce346ae5cf754c306da7e0b5eb7ac80b9b8ccda4e8f63e545d01c7d17b7ee45ea3a6e9f7484d4976ca936fe49fcf215f536dfd1de9464008c932617cada4d85c68e6aa41973a9efe61053dac4c3d80dd480179f58e65b53e44d759bfb70d69be5b868c4098847901a6b255938edde5d5ea94233bf971e3bcd572d5fc7fd42605dab8818f1f56c7b2505f0251fcd80bdf3852cad05ff704e5ed3d446fe965473add3563d9b36e5097c9835d6865454bb3daf132bc17d8d730a7f3847257c697c525e27cc570a88a168813404ea3db67e000f8f5485ee578483a78ae1932de070dd3066d4d3b43d3ce54b394943f3c4334d4a8af0abed4d8e05faa15cb7d1addfbd4f36c717310246c9ccae4d6874bead6eb566593b5ec588737fb914ea655d254d5968f4288a66701dc7da583f943d52f44bdb0fa59249bd584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea51bd0a65d3cb64fc255af6f456aa3287bd12645d272638ef0b4a3abc56fc9ddaea2f7396d97b64c56817d58c32103996db88345d377fb8bf644fc99a34f58c50730045b897ad9d8f7fccb81ccfb52cf86899c8c49ace757c6b0a6bcda859fe59d564cdb746038bef24cb7f177f79ed19a39814d426664abfbbb7b7ba99906e7982b665a551881e10dfb984d9a3e2acd37fa96a409fa3f786a12cfee1f0bb22c04d1da16d81bf68111a9bb64469487d4cbc10578106b381b9bd54fef933aee830de6e3e19a9baf9a81c2b9ad1e2fea47e4d234bc9d4b79c2f6fe65bab5a2db68c59c0737e0e4786a9da92476aea55ed5f3c77feefc342b458e441db9b21da8b3dde593c5e2f069944828a3f7bfe9354bbdbb1c344f24aa0794e60cb7d4bfd89c4933b6123c4434cb9a6dee6d3f14ff1fc571dc7f8119f6a33e4a9f6a9ee93e6dbe6ac9e6818b8e1ff9a1d1a59de98f4f818d43a1949a562db675d8834ef65c1d47afde37e0c6b63998d43ab47a681f0a856d166c24494082ed76d50cd6b65ee45e3e55e33fa5af0ab96edcdb0acfc41e285d3515d0a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732 +public_key = be49d596bab505f5eb40ce47b06e6e0f94506635a758964b3e7cc067c8d827ebf1dc874510ee415ef4efca9afb56b35500ff36177fffd2ae9a7cd98f5084610d1ac9f1b8a6e78cad938ea0afa5a7c2a9a87916710ec9c5b3544b76b4808e0e39a02e9b745962547df6c79841f11961b64ce0ca9d74edbcb4ed786f7e8c38276d9533e5bb4cc8df3f5e5299eb757d2e7da38d6d26664f155cdcc2b4a645cff49345d2adf5a66f5b54cd45a71599f19aac65be16f3cf5b4c0efe7e72cab64c9ebfbe9d3d76ee64e3adc9e2c997f37adb442e77df6e7f5e6746be8f984bb9375b5ada12e96d06045a3a984668dd3d8c08cd980b59cb3bd984be3f9c53790fd43653e7825598ff9b0c980ef6b062789332a6b67b2b78e9e370b88e81531846b9a8da8a09d6fe04d4f47b891a6b440ef7ecc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36614ae5f147938d32673412e64b10e975d9c4a8ba5ce85efdb48ff6eba69d9183c6fe1343d062389b9b99ceeefee30d5841fb68f355da47f4c4be5e8c413c37ea4d5ad639e41d753d938158cd04492bba8aedf7477ed13a0b97c8217b3d0dfdbf2de05449547626e2e409f59e09826fd7ab477e3ebaf0e25e24f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb77d5a467a3d4e9e030ffb6ed976ca9d856eaff57d5d586c7d8a4c36e7dca73aaa667e9a21538d9e6997c5637df8c5a2ab98a169a5ba807d9bba55f2c0a9463c9b4ef0c9822fa64ecd7fc8bda4030157bdf5d73fae6a6e7fd36132ef5dfc5a9ddae504b2ff5e6da9db5dd665f74e3396e53ae25be78b3410369bbdbd84a86c6c7bd9f4dd81dd5bfcdc54e07b4ad0afeaec8f65dd98bcb8968a2f683a4bd7633aaa0290550666cd1fdfbf2398aba3124dfa7494fd7bdd8719467405eac7d759d64aaffa4d7520fc67138f445287b681f5c3d1678b4981f9bc76f4163e3515c8381e86ce73d6a4cc0038dfd2d64a213c557a3ee2f7e38fa1a6bc3eaba08965bd803bd5759332dbebbc4d4e337bccca153905a9d970c36ecf63a53204b6f8dcff8d4234f08837425b8ff1da9be43775df89af0a048ef70044c76b3524b437cf365cb131baa14ea6f256df33686fc8f1f6afe0d9e1997b8b3ccf0c256d70df7b33bc9a7bdfa8ccd576925968916fe86ca4a5a4934528dc75283ef46b18f4ef81e8d39ecef07449a218836d47cbb7365b677ec7d632fabaf43d68b5730d9e674cd0d81262f6cbc5382a76a9823ebeb42976c5d9dc23cddfeb7b874dff93699f6d35a838b22b7e26ab4fd6278f505f9bbc87e43ddad61f5c38e9975ffc3ef8e30ca8d631f7af12e86bd9c95602992e20baa636ab050ab870c1ec52eae9b3a68b7a07a8cfbe7bb017af537f5d464265ff7fd65d7a8c30f659998a35d7913ff887b462add7bb2dc895f09ac0387cca9c5cd1aebc08a6877998fef24ca43c2c5ad43deb6641838f0cfa72f0fe1bbeed218846f25da336a5cd0c5af9eac8a60902f61b8c76b190edc7aba75587e376dc7b87625ff9fba537036f91a6eed4ae5dd76aa5cd6566c2a2f5dabb3b6696d8d9de5bac093f0cfc3570a0ac8deb4bbf3d941fa3f5aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152 +public_key = 9a3e5a89dd83c05e96f65cca464ebd4ce3526f5e4dccaa8ed176ba590e4bd0ac486066f40ded6c6c28f0416d6dd98978d6cba367fbdec194d1ed34874388dddcdf77f2caf2e1b342090fe6f809eb048ca497ec37a7663587ac85f32e810e64acf87478a21ed62545f8735d907d0854b93a9d4bb39cd5788be46ec00faa87bced78b26353a51b7bdba58d17e5496e0bf73d08f7a69f96a13535abd799cba3efa5886e35476dfff97e8297d653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b37f43d4f63404550686fab181753504e9592bd4622c650b828b3d4a66d9b163d09847bd27fba8ff452769e84c08be1183665c0185e0a089c967e35dce64bdb5f338b6492a28ae238aa56800e7dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02a0eb73885557ccae8907fab5a35b489e98ab377691033934039e18a34af7d176a446e39aab3ac127a8f510c8719936e8676caad3fe1c839fa43ff74c7fa85c64fb2152fc57a0d79f35af6f0678c0068e8bf4981a2b4c7db88dc0bd43ad56cdacefeae0e0761d85f7813076f3174a1d49c74659a453e09c2b4468de7fe85d5f3c04f2b7e5aed5317586e753f85e78e7283dae1faab44271a4668aefdf36fc0c03843730acc24f8de2ffdf51cca86a83853e635ee3036714576b1c27ea112e7a15dbfe5f73d39aaa7632ec77880b89ef8a45cb0b374630face1e7f21fc98afb73a28a6ac2ae443f16f6d72d6b3da1a3be5fac533b9e75a6fe76fe23ef021795f898dd320c6096ab63f545f5d01b32a2ca90e1b9e38e4ca7260f785976bee4e566dc0cc1f48f7734bda7d00cb58b6b89c6ef6d2ebdd42aaf450e269da77c46b5c954cee6bdc0339ba357a9b9a5e803af55b74a4f4dbef97e1f4056147a109ef3ec9d3071546d2d2f72336730870ea22f199f95887350fef4155da45fd7395df965f46574a13d581cd7e4a51cd8da03a51b367b525afee4e56752db9b66d9c6b087d2ec23bcef798d694dd859383c5baca9d9fd8b724d9ae565f209c5f37e697ba563f8a1693af70adca38df0de2c35f643514ebf92c16ec8e2085d07ded1644c94d18cd75618e1c093afe61c6b4ffb97048fcea0df5f76c6728108842b3841dbbac62514e85edc32dfc8e7c45878189a7ac02859eca77ab445797e13de920f43b22ea85aad5d8caa3c32fa54d033714e2da771c7cca73999f6e9ed4db4683a9543d3c978f1d56816d7559074fcd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b82a0d78e3cdac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4128af14e5532894f74646b91f4aaee36a3b42cfb90b284f5d2645c5adcf482289d0b4b84a6359008ff3ba05f8718e6c49969dd6cbfa5bb674e8966eab1a48e3988927ad4ed05cae437a9f1480eb2f6e7d8d365be84baa60df8bf7d969a425c93453ad2780fe9790c80c60b4b59fc6131e7865e1e35ac84a66565d7c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4153cd05ecc44ffcf99095af85f05dc09388b6ac3972a1ecfb8ecc9f0ea58761741ed23ce160cd3af5a341f75d43f18d2c0353d987c718fc7fd3eaffcdc96ebb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800 +public_key = 2f7f40117d59c16c3eacf4a1a844fb74aeedb6b5ed3d0efcb178f29a2bf9f7c334d1dead99a3ff21babfd8153bae937fdd2393d97485190ef789ca7628bed41d868094aa7440c6724b4430ecefd776c6d2940c9d1fcb5a109978573434da99e962b6450035d8e46992c1ce48f6ad3960a8f6baf5834bb7f71c443b69dc5110c4b7099d68d27fd2cbbbfe1e55f5739ae9c93e5faf8d6fd139be91f4c1e29fa2c04983291340dae4d18a8a83c27a57c72f408f933a51b7618148b16375a80e0a90201daaf6e7803dbfa693abcd4ca8bafba4f086f42f6b743937098e3d2a60803eff7676d3c9d89accf7ac584491f33dbb1108b1465b86608f4215d79fed35f5d7e95c7976946f2fa9e76edafa2a9e8bff9ddb65c47be882066e66115db70ef3b7bb249b80ddcedd688c37d7a3de667627cfb389b38be076d89405703be5efa42e99e9c83d5265bd63afaa2cf5f1b69973a18777e42e51d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64caedde55e8e4546e714a6d37037ad78e0f6164d7b07f3f77b7ecaa771bd6dd39eb9bdf9241c3bb43553bccf66a1de8efe3efbf7afea21e1539d0bc517a9ba8eeefc39deac4cdb7c65ff9604856eba2e350027d95a36cebfa25c243cdd0affc8af29495a2d349133c343d78deeb8e5cdcd89c50cf83ce5e36b89abd473b4af0fff28f4cba5e1ce0ec8ae083833736fd81034aa7bc0fdd123e9ca263b5237fd96f5d5c468d5e746e9e2cfbf42e559884efdddde4e20f0c9e49f4995386f84147cc2d2a96a046bdb3f56b6ece889976ae1ed732eba43af5a4e832cff02e6d91c16b68010ea82d98ccccfcf12b79b5a884756c75cb25453170cd72d903c670864d5a13534e545d846f76ee594d3a7841e509ee6b738d97e73a7274671d6470cd37e9b15e5fdd67c6e4969ad223f5460fc5ac9ba23c264a385f37369b46d0c4574514ea216ee459d3321ee9b395978f2c575ebe1c6cafdd3afd8df7bc457e0305f8b0ccbaed7e850e0955f1afb54d9bce69b6c8fb09d950168adad4e1ad5c973b578424c55ce01b3ec38f5b0095f32469968b8a96fe7b9f26846f78a3f3a15aae63a7f42b8efcd27bd465ccd38a4aa30dac42c0036c063cf1c3b4e78a0c92b8a9fcbd54a6044b789d943f1eabb0bb24c3d0d4c06735e77937457abf7c84fb435e6c745334485fba84676750a27c520f79366e0d8e4be93fe8a958e9dd6b8ed3f3bfd5bd01e86b1f13302fbe7aa3aa8fdb3445ae5775112bf125efa3512ec04945661b2c510a39f64ad855836c7d8eabc06a1eef8814934bb4b32176c0b5abd4c5fb6cdbc8bc42bdbcfef4423635c0c7ac43e4e5f86c74920ef37c961f66ba2d74d239b2bd1add6c096141fb6a719af13a3387d75b927dee76169738acedcfa6b68d3b064157c3cb03c5793a84d0c1a6d352bd59e43a7f1b28ae5073780cd6d6f7f4daeb458dbe95a31c23af7e86d002bdbd601647ad28d5c53f9e46f490575ca928fa908b5a30fe3e520d6ec9f1cc5ef18578b45da929164de34bd08348e80cf4ec463f715219da91b8c9b49f8c2629a48d78abd1a9f720e841a52ca91a15a1c7953d18b4ba1fa9daf34ca408cafd449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c +public_key = 450cfe1cbe872a7437640efe29d937f4ffa41d257532dee72af59c918d6c7e6ae5972a8cb9dca049bc92700a72b4fa5a749d33437c946fed62aa86c12103b5589ffa08084be63c4c75deb92608c3b02c6521bf991f8499481ee4fb659f89a937a25897faba6c0ede42d8d4868ee3c6494ef8242bf87ccadae49430dd7af8d1339605a4b750f6d29f73baa1fa8ce72e9c36b4de564fab45cc781b6e3fe04e6502743df8cbb3c4b864d0b448a21cdb0a4fa82a7def2b23efb038587a99b80ef4403316eb2e4b8f9b1fc3c13e93506b62aa1c7ab08569c8dda88c9ad98f97d61ef4e0000df12e2c3af4f6f5b34787bce55f74aa58eec9e24df7d89f5ea581893354b36fe035ce5fecab750e8ee72d9b750cf8034f9c932abf71d89b8d8fc047d77725cb6ed996d8f2cadb356fc1d428352c6376f6269d9869aff4bc82197db6402f84d296677c6e45683ba6283ce2c735e2f00e5eb19ba86b3571be7438f183e1656ce18a63d266bbc6daeed636b6347c73d607864949dabfa558522d2ddf6c7941a086e09253b5ffd76328c99590f48b3fc7ae7a5847cc958fa65f3f540ab54fada302174e6d5de341759c121b355d9f80d2ab6a8409d38634bf7e3ca90679aca188667e5d86df35b88d95b262e847866ea414c6f7f44bdfb883ed3bda73c6396594694aa08df4cfd55d3ab883435e6cb34a922e6835eb9cd67bd35ce0b3711d7bad2d85f9464c493adc40d8ec8679d9d3e8984850034ef4b8f8d3fabcae9474f7278cbe79c8e6cec948b94798d4c68db8f55237ad8b0b38cd4a8dfde5abf7bfcfad98a677a8c40f2d820677466159dc3d3efd243f7a47af3dd6855275b78d2993db24addb13c638e31b4745b9e7d4fba95a04956c47e212e475271ccf9406fa5356e18806316fdded08454b0ce9f2d7fea3e4a651a7a931f49dd42a19f44bb39973ec5873cf8c8e4ec4bcd7fca54d9a363c49995c45c89d95231f8c048e46132e4a5fcde527b67bce4463202cc14f4ef25b36a7d8eede26966beb389877bcd06209e82c15e7ca8676f5a44a111d6fe75a31a4aa86689cd75918a4d8a7461ddceea1193914cf59e3b44c2d976ec686e3468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cc5e4bf7178e152efc8c3e727a38bdd20a5ad087746768957f837179e5dd25f6697f4a88d056451a593e385b74de9ad1d00f44e70ac9ae36b2d76cb91e64e9165c6508de41148869d6676f28645653bc78c96b9e7f48fcb0c6768e2968c513c7ab07692888ea663dcd3af3f86b0c681743a58d9c524bf5e20c98d605cce39f77fe30174095a3fa0018d0d58a926c04d973c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaacafd344c9b6bbb25cb0bad84f6163321a7f95163989e1448794d82c337d75dacbb7eaef025e478681db0c755ff827acedb1ea73aead9c3e54b4054e9dbf3a8f8c6d96a73528dd5dfcd33d155a97a614663174683d1095d97b7c0e994764e0fda5ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1cad61302ba9cd2dcd46f769e21fec03c43ab07bab1cbdc7f44f6d253ae5ed6af7854ca7b177a6f7a5d2789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2 +public_key = f6446774c3dfef5b426f563962dcf9ff78ade42b497dc3b971feb849cee41d7a5f45a37c26cef5aee6e8640ff833ad6128bca08efc8cb176ab6353f39b67fe1c9ce38e8f98112f7afaabb81cdada7323e155377731bef0568f31e8f8a599afb730578edc88d0b0d6c5627530ef9f930fbfb40a9888cf648263b688f1befe090dd5f4bb449a35f82029cfb73c32f8e3e22adda58e6aa08698517fbc5f619837ae3331cf763631e3d5e88c8f864e3e9d64f0cc38fbad24a7841ee1851eea79a3b305db5b313fb75c55907ca5c7f839320028305c439c394848963efb1e87925999681819416dcbc7ead45ac3cef62154bce16866c04561ecafc9ed7df2b07a57a67c7b901b5da3bb8025c7585c86bda19edc442c39384d40236a82894e9915a7f9834663d4be967df9955de3a387d93d5005d11924c4fe433d016bc2b76e4f2d3ba72feaf26864ad6ba5b8c31681dd1d4348fcfb29c39fc9f567cbee7bdf1c6e215c92effc60e2d6a3a41d6bcfddbf301b542f7987b68fb0780b6d398631eb855945abedb02ad4442dddcc83e291c73749acff8655f395cdb66634d1fb57a4db33fe41deb0f36eeee1fbe5dbf7b604efa67808c064fc5103fa7c9c954fce1fbc619582f82590b323698b3f8cc14acb88dfe7e39c30952ec7e6fae5ba6c3bd8587126c5aa03cf6308c9912e7f62dbc9eac3cfcdbb9cb009a3ae1086e77184db2e6558fae775deba7a6608685937dec07b584334900c278002d8a47e0e547dba3036336616a8c12415b86a24f3a6c9aab6fd85c7fabb6355b3dc5df3e47c7918dedc284333110bc979bfc08e16512ba95a07237cc35c97bfb5ebb2bf5e3085de65664377ba49200aa6e935b4c755ee547859eefd3bcfc6904efd5221ddff5e576604a873ef8fb7693b962853b5522a5b0986348da63df86a64671737c28fd1ed556e92acb56f065eebe3ebef43ca85ebefeac395e2aee0a3fdc5b90459838cbf77acf72487d9765569e5a649bf26d3020d3169e4ac2baaa4c4697f25869aba9e79f9f792dabe9df1ce48df7c6b9bbfde644f6697d83a6e33b35f4c7e7a8e75bfd73ce61ad50146a3d893c4dcabffabf5960be8dfa0679433bb33bc9e915e93c1eb2aa16dbe3e0b9870fef99835a674b1bb76946bc4064cafdf3d63498ca30aeb3983f5cdb3a6b9c4a7d459d969f4d8b6ba27755b6ca8fbdae78dfcf8dffbfac043e8bf8dd2a9a4cd7b1749a7fc7f09a6b56084dda89baab823d8736edc9973df3b588069e5da965dc9808e98b7a46148fa7ac168d632ebeef4a5f8fa1f5784a5bb2767f35fe44e755f9a7ce88e91543b2f08ee9ed78e2647aa07033cf45ffd34a4fe794de91c1d4c7ed56b8a5ea9c97d6e4cb33cb0c9e8387b86908438652dc13b09be76dfa5e9276246b674e96bac788f541e1ca441e53ff3b9c702cb95ceab628d26e7704a448ef743e8c8e1ff5fc659cbaae22377f28646c45642a9886628c9b73d6edbbfb645d4077c1d8b954bdc8b707b7f6bc4701cbeaf0f28b88edf82b78b7ee96732521aa6180b6021aabb415839dc4aef6f545c142dc58b965b62993abf7ae0c19af2ce6a45539685f297b1f05ae30465845d189d1765fe2f59e7e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495 +public_key = 5fd557f7434fcc6eb199e793c5e763764c48e05efacb7c756e1370ce1e7f8d1dcafb39cbf0c8c3f5dc8da1855204edfb39647856b55c38e944617b8349de6a832e962b4f398fc6e97804d428c83a0b49bc853d60d28eee289434db4b5b0838cd87949df5bcd727d8a528b8b5c03dccb9e37a6674d50cc5880d34c13cb4fc1779b8d098c5e0876628ce7a79b6bad44a9a38c56883d97cf3dfb115aec4f1b5d2ab4a9b7b5398d9e73e543b860f97d62e27a9fd2af035185f0d98857b0759bf1c39a41984c9cea1aa0f79454e7f84cca0de5fd6e9133f6eb6a989075d004accd9f57cdd9f8cd45544401ff2dcab9a89add04c2596effbd6903b5d0af33a89fe4fec86dfc074a3dcdc744e9864e7ebc608a56002e483e60b8202c3e377dc7f5a486d5a16d733fca9836aaeebed5909c6b6b0db453137efe4f3548bd5bff1f9f1614fe218f963081c518874c0cbb792fda4513f89d2be6547746ad879ba6ccd8cdf74cef3dd6d5bc7995bdd14b018e8f78c8c3966aa87a24b4a4bd3abb0edc8174cd28efe4daad39c288943ebce39210392bee7dc38d7af7439697be96978df3a27cb6e7de7b785673c9d1b33a18ea9ce4e712953dc6c73d0c496b04e1796c9c781e53ee91526fde147501b7bc55f99e3c66c5cbe2d9ba7eee5f753ba73a4e7c8fbe8231de13dee7c936ad622dcbc674553b9dabcda17bdbfb4865d68e43c149512dcfe75afb508f67be805846135fd9514ff8b7641e1d851626feb81b6e6a13ee0d7ea3bca57f3d003a4db1673d74f73b34c9432ac981a1cd1dc8b8c0ed5a05e2dc5331831ce66d14bbd732c4deca2f856a0cd61ddaa95d63667b9acc7a1ea65709fed55b3eb4103fefb3b66ddd5cd2155438db6923069430c6ec85ac3d9bf56b0ecd990428ceb7d93991e783a648bedd66696659b5c926485e174f855fd839043e38a3a54c349c138977275f7ee0fe985493cb85e19f30968d4037462ae2487810d6d0778334f664262e88498fcbb22d46d504f91bc9dafbbe4dfbf2b302415cf195542dcf3375e786030fed67638ab995b70e6dbaf7b75bc128de207e489f46e512b69da8614d1a3facc1ffe375d8b64e0e5c7f863786d3984711cff55ecac578c41180e94d93f929075671c8e4fabf45c6e2bcdf9cdcbe2954c5b4e4e3f8878ab68ca13189d9703e7517abb4d5e87dcbd3413da654e75dec1cca0bc9472bd4bcc60ca6fcddbf6e78ad25ec7dec0f6de21be9d300cf71beeed3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a05323e5dfdfdd9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceedb5d36d3ea897b65613dfb176e964845f899cbf869f48b1e71ceff04864497f58537ff6a7dc64306b683804f96b9a81a3193f5c9c711dfc5b9fe79bc6dce4c934591f93860b66511abbd61295af186b8ceff5772ff5ddffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b15aaec84c85d7188f4a0573cc02e9fdabfa32ab66bf8a498a04aa4e235d9a5057997b74ab6aeb27b96656cce94af18e1465e709b5ee42c7e5c6e167e5ba5945729bfa80fc236073fdddb4ceada97292df53d74fec094333d0f8b0a04dde3ef9993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b +public_key = d6fe35d06aa99635c9b63f44e1f898d8494b6823e2c0df43c8ea5b7f7eccb7a5386e477d01fca3f05ef2a63934843450a446caff65e84d15f923a393fd887df7bd45659cc283de424b19b17dcfa2394e32f0fd67a0347f88c6b392aa56a45e9a440438d309e06a5ee12124c91fd3e187bbdce685fd9b336a1e33df97837a657599e253b7798c912a66a48314447c45fb8469d941355c6cdec0951374105858a475d2ef39cbb58b8e63a64e2b99c48269e2155695893a62af6745e86d58d65ea94626ef26feb8fc045602344a7f44ffacd5de9565c1d59a459d44f33c29f1ceac6e0bd936b496c8fd6a619d9bd649eb458f8943eac97293635092666688db559d255ceaff80227755c46d5d6fedd7cb7e85282f7fa104debcd887939ded8db6b2375af3178a72276c7910adfd7e969f2686c9518e867899d5e87e32de9d9397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca6491847d809d4beb70dbd9641878e8cda141573030bafb687761bf43ac89b8ee73376793ecb32db53368ec9e089e72e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca69fd1799fa1880bf540ca7240c3c22587f30b59ab8fcd38bb95cc4acfa2f59a4a23cdc4837e3544fbca9d84d4b3a6ad86e8764b7deb7094f89858bf63af828e3d91000f508a7f6ca24beca0f87195caeac08db0202def8584c15299e9674450010db431b6d267174f2cc56860bc5ab4fcf0d19ba8ed47535ec4ffe1d33f2a8dba2128d5a46e8f2ff64d1cc634caa6b410df3615538366dbaf41a7ed8b5857299cee407af93c1b8b7f4a499a97be8cd5eb549fd20ea9c7d08d9fa83f313439dfa57ef18f4a6f495caba3de511ea48b7e19d5b0465f7a77e1f37e6b17dcbb4baaeb31933d7d46f2315c79f40eeb93d8d58fccd1c4839a808a5d2d45b99f89e8fa05feb1e8ed669c7988ba7eb8847187ac7b774d4b1a139dc4e4917c9b4e29833fd9fbc36e4bba97ef5bde79ece0c369acf7e83c86fbd04785efcc6b624e65c014a0fc4b64b24b3b474e8ac5b6b7bf69cbc85d90b69aae46b4a12feabd4e134bcbfe4922367b51fe7976c6705e175ff356e2cf8bd86ed733deaab0cb8e5a53c99b2985963db89bdc284d251340b0e3ae20a9dee93344dfae8063db6ef4374a341f44eefddb46676475937a957fc82f1f4b185ea9e52d3becc77ace19fb055abf099f637b39c3aabde1219c88149f77b8bb73ba5d81435fe93948dad0cfb81523c72f9f360aad505e2979e086ab85f9663e549f345da694458ce8cdfbd97e6c0f8b8947bfed99d97632a5fbee89898aceadec8ede15cbf5b1bffbe598a65465bf2b89971aeddf9d16367e9436803ba8c17b6b3b06fb11bde7c187e25396bf6755e640ef4c4563e9cea69393ccbae435d8166e67b29aed115dbdefa5a789bc38913ebd86f7faf5f5bc81bfe52607378396549a8f95d5aba8c11a5417b55d683de243393b7593400d46cca1e3f1c027bfb09cb08a1738c88b7d47e876ef85e7f8d96cc1c93b9e93b7073ff7a55996fa958a684aaeda89587c0e5a6b336dfc7ed721298ac6ab713f4afe38bfaa7b1ccd2a876f03d7f546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689 +public_key = 26ab73a335519aae833b1f68a38ad87ddb57ac7fe046ebef407c804c488e41a6d48ceb762cadf4c2157e7dccaa1a86f88138d716ae467e766dcdbe59f488da39bc4f4a5971581dd70318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa91316fe19904745ec68cf46dff4663bda755f2dde6ea318539e10a853bd9da5b06aa130e8c6bac4a8123719c567719cb723c5fd540ebcd85cf787f37a76c6c40fc983437cf6f7febe4df27d62be752af3cef1deed26856500f3831cca75eff8ad8d4d9c81adf95674550c1c951ffaad155856c3dce43824556c1adf5d56bddb729fd96a9f6c199e2bf5ca862a4d1b8c53e2393fcefdb36912d583b46d59564ef48573ba1557fd1ded58a8cc5ea7ca7f19fb7dc7b4b0459dfa4f7fa37aac0e34be746aca327258d9d29acf24dc5f70b8f95af3195e6dd30a498259c6f9d06bd6908f498953b4fd39adeca97295e431b59c9614b7867dbe229ef519bce30f003903e9def70bccd776a9b916684cd89cd727f3ca83fa21fecbb90d547646b987155cf5425abbb34d6cece821afa8da22da541dec3af175032444e1fd85f43f47903665bea2f636755b5e75a90931c66e89345f57ca4a13f959bdb4521cb62bb1377dc5c99fbe36c71347b81b8db6c7f51fac3732485d09b7e9f4374bd600dedce56d1e86ea755ed5756968f33fcac4d6a540d93951d0bb4d0d838a42ef8731fdc2dc67718888dc04d8941b877eb6543432675c879aa860ed3e608aedf267e32d333ca9c386009d8f17b55368daec769d2ed3d4e6c7996ee44d61c4da9f4f8ba2ccc55775490dcacfa6d6cd134f8d9be3d5d7445c9ebf7b89fa6d4147bfe56bed905a7d33bbbfa25a3886dd5f4f59d8adbe98dc2d743878d6ad74e712dacf3a19562e4ac7f57a86fc98663e455bd963c4e63d8471c5d4c14eb718d8bcd6475cc45687f55099f90ffd35f48e2f18eb6df3ae74999765cd69433e5312be67698346fa113da40943f8927b2cd9aee2dff514333bce85a89a6a99d03c4a5c0b847550972fade448d28e9b368fb99b5dff98ce24398cff30967013c4dc4d374379b4e8b037eb0e570afce47a1c99cadbb651bfb576ae6ebc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a1933eeb4d79e8261ce251eaa1014c6f424f74666d9310d8b665c6763639c71ad4801a9d5cc0874be448d23936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953788e24c2c92d29cbfeedfe678e54861eca5cd45dfa0abe365fb744363e6f37386b9c5e0e2bc585db3da71ecc7ba9e3921ec8d8fcafdbc97807b693b1f3d68335d7cad9d410e0576611ba79c1ca9c1ced6d014768089dec515e79869fd3035aef58ad174cbc70b435710d5e69595f8429d7d41b8e80123a4da1e787b674acc5e3c84047bbd5851c3e83a8a046063cd6bd84397868f41c95b8d8d3afc53038856247506065a70a5a29c8debae1b488a68c2c00f472d86bcc0ef63e89fd9032dfc612747ce6d344957a871c7774a0980b70b56f7bc45f9efbd2085af080cb923b55640bab2aa2c30f206ccbbde7bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9 +public_key = bbce6e6e3c5e5d9c8ca207a5c77c7883c9e7fe0463d42de962c8d2549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a62059d3b9bc9311c66b907c582572eb7ebfb52f6c7cf76ce69c28ef9595631a2fa959213e7aad4cb3393f9adc69c67a5e58558638c474710c78764fde2240cbdc2e586adf93c0295f2321a94cb766f9e983fb62eda10476ecbb9ffc1def0cc83632409940ebf49ec569ed584d471c86624bd6963aed30788e349f342c759886f7c376cf7d80a2de9fd4d7eeae76409387d151c97d07f70329e43471a84994bb596f9b5e1a78d344f8740fcbab415c575e478db4b4e3087e802f4d9b9cead4ecc9cec1b7396e664645cce83b4dd512684e1bf750d8445d228dbe5b4cfc09bc9fffc8d6e49b49d68c4d849b5856efcbb65f8382fced556614a9ee5466d9a4c5459f523c1c76667859760e79d385f6576843eb7654c30b9cdb26f2b8089a3c5b50fefee5fe79c54ae62eff7376effa3aac6ec0e8946a47cd79acd5467e9c829b304477541ea92b11aeccae8b36ba83d5ad83083fcb51df653ce899227d5f581699b725d456c0aea113eff7688d56a33755ddc7d0658e64baf97f1a6d5717dd09dea8d87e86b6accd106a5536d7c83933ab12e294b505d8710adbea16ab49b88a60ba7790549ccc0e6571f8e875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a6ef95e3d3f3204e32e21e7b8365f9456a53d3d748c26f80f4d597573685b04780f72ed94c665c66164a1323c290ba8c8c1d31b24fa3b63d62ad5c59d9eee2fa9f6e5aa591abb7e1ee2ba1509aa09b86c60a969020d74e238b849374bcae7788faf6e296d5ac7bdd927ef3d912d4f87e3981b795ed5833f95076365196bfbee4a3cc189020254f32bd6fd8e7dc43a94cf48dc01936465a334fa59b3d39296305dc8b785f69ef2d4639bb3a30ac437936cbd734a5c6477b2a55eeab0e59e67ebb12473b77698621e5f47ec5d1306d8c6f17da6765ef6f63abe87ba12a56b2b2dba44b07ff01c9a2c59d579d3ce03cf9ea841c4f4b3aafddbadcc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d152eaa922e6bbf56bcecb89f11588b4085a62cada47ef9a185cfc93475f5cf0d6ca58e9857fac8b1498c9dbef22175ca5c0eb6be6dff69f8977a0b3b04987a1897a8f30fdecdebd98bdd70d16ce5c099a5673ce7087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c859720bedd465970d61446f106cca73ddf85fbfde2947bb4ec57e59cef7be6b6fcddf5a4b4eeb05c516578ae9ba4c197b692d20976116ba3576dcc5c7efb626f69a847d1233db65f39e3e6dd362d0b51101f72716a4dd293fd3bacc9159f9ff33354c12fe7d9ad745d9f63b5e8da4f497d99d98a4d895b59a59a1ece73ca6945fa54c398f351c8c3ab8d66cb8a7ea68157ce3cf8f104094fc83c7307df42f2fd49728d842beb8e126988c5a830d2a39c281eb03359dfe1d53e432c7a453b4ceb05a5654f537a7e35242ff8f246bc6a1445f0ce6b2f2bc6753f7a62ec32dcdfd9f2c4a5c70d920d2856dc34549bc4656f7953e697cea7ff891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4 +public_key = b873b2397a7c7aeaff4b0b589ebc97c60e74e53e7ed5d9cf2878c924937bd258bacbfc83284af18d443d8ee43f8cf3c64459b189e6b3ae2dda6c6a3edea9e6f89b8bb67cac333cd51905d3a4d4f7f5c9af1a16a59b3ef2522adc625af0149765e986339ed63567dcf9d0fe5d7e8ac026c96f08d6ac4e057db4e66362be8ccdc3bcffd3d0a996ab7356f32db731076fc75b39ad7bad80b23763ece54960397b8de836071b8914d56f95a681accb8fcba5f9e5e4cfc2fcd601f7b0b39e524e28daa0a69fa74ac2f17aa8826fc48105e643a5a527da5c42b59f9b7fb14dd9e574c5ee5806ace40df3d2fe9e3ec6f1560478bc7dbeb94d771abdee173e3d2f0c785e3b9886f679acfa465ba974677cd68aae49ac0499704e32dc4974f2fc322b66e15a64b0b5dbb8dd7e869cc655de6e390b13ff063bd24bc7e50574da41cc6174b68870eae1eaeac28bdd61f3abccf5fef231655eb09f85b215f51ea69371e9d527793495835715bcd05868a78b1cae810f5426848c4ae869b62d34bb266e1b97480aaa7a31e384780442d9933fdb85defaeac0bfb8d2e63e4d29ae7d374caa05b46122ee6362e8341de9f3a66872df3c942177b58a5ec40bde641f53a53d97d8ebdcf2aac67ef36fb6166dd7dc6880a1f45cad3a5313bf82056bee0b28ed9b396591fa78dfccb9d6b9fd5c08e99c14c68c04f48654716f1aee4f2542cd35a7e5ffe85814c1f6be6d8d4f3213c69d5958c46a6db8df589c195d87ec5474df3c5112b5bb6bbcc6ac7e60abecfab298d1d775cab0ad49479a837cfc8847763559ea86239889385baa44af848b489087fb43ab2dacd7bcd56067677995d0f937e271f5f0330ff0c2b8fd8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851117cfcd2fa4671b95cf7f6dbdcb4976a2393647b71413e870b1a6b2d486a5dffa8093b7b948c9418f3a2806f96eb1f336b8a6dd5a5715ce9a70dc6978038369b1d332e3ab6c2a7e961d5c6654eabc339d114cfec46e96c509aaf09e658d9b77928935b9b2ffe42bba240afdb58ea48f4fe9a7934e28669c09e135f773cf75e5590450d495153a691794a8d28fee23e444647e501e87c41a944f95dc9cd288cc2ea90a5ef7864c79e554cc5924c4caabfe7dcb4f4ee8b76e49993ae5bd85ea8d9ebef7401eb9c6c794a67b3e705876243478f86d5b9f9cb32965ff8175f6439a5da412b4d1d28a70c6b9794c959be155aadb39e00c4e8f0dd664b08843e2db71c547f1468c5fde9fb9e8e833638ff35fe9b515946a7a6eb5aa3e9d9444cdc1aba840cbb5737fe4da4ab20facd5fe4958a57c3c91f978fd772c296fdea8b60b30a601b79fdadaaba0f46ecff27c5c734a4226534174eb861b7899cc3e1e8edacce396bce38d9f34f89c546eb91cba88493991987c0aca3b0715ee482ee54105ce5780abaff7f5dd4eeadf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de35fa4f24795e9aa631e5e98f085e11613d0a3fdfa402b4cf8aa556ce67bd44e307ce5a1eb76d9efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a +public_key = 0846c63e2c3018bc8734fd5f8ce3b614088a787669205ac9889bce2d3b523f366f4b08e2f004666b2b65453eb135d97a71bddfb9a3928c1a4a2d7f85f6f7b19bb766bbe6b966c4d13fcd6833ec6f1118a773cf465e8eb77ba740b7ea3313afe8542a41e3feb1104fbb42396e9a6c501145ee783641aa79fa992f72d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1e9d1855bbb2b68b988953ab646d7d988999ed96e5a4b963497a061ac69be9dc4eab7c0dc17820b6963b0293d4cb3dd82f5997a877a9ab7ec5c7893c2de53ac6779d0a88191be3df828bf3afac9d7ea392fea899ef844545e87af673972399a5fb3e035ddfd70b57b97434ecbf3b1985c86ec75b23bcdafaa77f2601fa257b78341966bfd2569670680e11f899d2efad3873aabff6d2f4a5c8dce33c92b9a446530c169b6b88be18d03329374a71aeae779bfd35986ceaf3ddc764ae2b7efb2fdb672b4d58d8be640e61576f2cac617a5ada6deb874bbac9d37fee4c881bbdcca1c9a84637de2b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac35fbda1a83ccfaad69e38ceda6b14aceb3ba295fd60f5c642f5ce88ccdfbfa6b3a5dcbcdf96e14ecd962745a5fb3fd115f5f71d895a2085620c89024e9f2359741be366ce9038aa4bf60320a456858a7b9edebcb1f316e9c6d188fbedcb590a2dfad9aeadc26d381875fce6f3b6403c94dbdde424d19de9deac55957fc9bce9cbb26c16e9bf7dc9e40a126eea97ae71728689cd6b6ba0c8002ba6c477e9a1a1ce75638770ddd88ae29a7fa958209788ade14354a2bd881fd5ef8ce5a6786be063b357fc7521973abe4fcac0a9cf6f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7e3e6f75accdd29e1e01da7e838a7c30f3ea1fbda956abb53fba02c48396817f29f59f966796806ed4ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf27e899b9e1fbaeddfa6687b3cf8c1e4e9a4817abcf656ff669b587c7f374f3cc20c9f85846ed21bb85a3b9aba167e00875c993b54ccbc84db2e7f374bcae29c5479cc95197f6f5da047447ea579765e595853652aefdaec4891e68901bb67faa98bc515dbb50f9e3645874fb8ade51d8e6acc88a7f8a4ad393e70a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb99faca3941cdfa7a488ce3af9787a309779b759cdc037c13e8393158d3bc1da3ab19b7fae477c8d3f2bf05bd3ad9cfb1bf41371c85ffcb607748cb518a6c896830b29e737caf89b25f88ab59869f2f637c67d19818801ef9a6b726dac1b5b4d85e9b429d5e6687b3fb7f30eb88a3c963d81366e308b68bd2b740e7bad8cb7fcd6468c008ccab34ab99b6773c533b3915be9b2c8dbf7e783e7bd9366c8962e7f3410f34651ef6d6eb737e6c9c5f6e3d6af7348ce965f28d0dfe15b8abafde6994b562613febeb2af9be5596e204b9cf2ee127989bd2ab49cf27c976f74aa8bd84fa6b8401af5f3c46f13f8cfd170d45d865c75bae4542f5a4e5de459b5676491c6a40ada2f13e9ca1a63a401c9c3a14c9501de6a9a69e64d5f2aee93e8b96b4f679e32234fb20353e0d8b995a6a9129e961ae7349f92c92a90b833f8fb9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147 +public_key = 964435fc16be2deff76b7bc78ee8b5c963af2af4673a93940c4f9131663cc124be5b7d6bff6ce57ece7dc5cbc2a124e8dc4b8a28c841c5a831b2afba98aaf0fede7dd077d6ceabc0d217e4d5595d552e6e9fb6824f3f72de1aee262aa246494153becfd95c970f38aa350cd438bf6e76c77a0a76bc2c57b80757550c1e807b4f3b85f3fddb537ab6d4694cb8b9ed58b11c9a6acc74674adfe011a66dbd7896329c3a32dda7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1ccea133a415663d5cd5ad9fcced934e7a3d23fbb0eb83559c484ebd9ff7cf93e456df0b7187e2705a2d1a8386d0d8ec8ff2fe28fd8846dcd40de60e81fdb6d0c747ccbbedebeb84fa754a06f5dbc0646210cff1307f1189cf00c1ac1f10394ff5ee7018b964073ffbed570ca4f575f06eb7149a51f9993b918f7ea3ad8c32a330747ca27ecae462e54ce1a6a67a8b63676998a09fae8a7a9d2ab709f2e62a3edbc082ebfc7e49c5b2c9ba975b3bd98eaa388f391f5cee4dce835c83732c84f54b373eb18869b2c90e9f986a0ea345ccbd20333893b463671c95e6bad7194dd6f7f6fbf446ecd0009b1e528c85d147d0e75dcea8bdc68feb4fb754bf3fea7b9cc621d4c34682a6195776bbbabfcc866cfa94c368a2b4b346c75a2a6bfe946cef0a4e6af0fec15d3c72b7cb40824e609cd58e516f7148d841656963174c70e09c1f593acdfb9bf4a3a9387b693f98f495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b61100dbf4f5af82f85fa070582f2f3c142ee68f60ad47f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a608ffcf8863c179fdc2073cf517cbed3c362a853beffea8d02f47000cc4ce8e76cea8dd683b8ad89b3eaba3b9636f4f5ab36960beda88055ddd664a2cad749e439a39c6999496999be3ba7bcafffe06388b1a6c83068ae71aec6f8a36e788b8aa148933c896edb6eefc86cbb7d5c9cc96c9f137c6aa3ed347289010979bc2ee6700b6e0c7c990d685550f537ab0c45b2bc57e5ef4c08c3ff0961c6e17e95e2e4482a4a94da3ee7b6854ce58cf63d6a4f9e1566bab646fdc2e6e0444cd8fcb7df4168ae77ff3a0ccad971583b69e7c4815f71a17b4a2ee74638e5cb39332699ac44743fa3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd223eb98aaca67343cdbafa3db35661c39cdba2ee8043a4c945067adee46e429ae6011abfeb58c1bc9bf330288b57cc319389921857c9d015a0482ef8c34cbc144e7db24b91a3567ac299cfa6d4c2f21f3661a3ce09a6e11d44dd9613b966955c6a758fa7f3556f77e6e5ac7ad3a93175cfd32a983cc0c73c0df3d2f9f83a0de89a1fb576cd3b41505b5ba81fc38783dc45399b8dfdb0e548cbed984e7bc5d95c07f73b05cba437ac6fc369ebca85e13ee715133bcd3e4723d79c9b93abac57ad3d3a5e78ff986a3539eb795a5b4967ac7753115b916236a97a0d870b658b9d4b3e368f7e1aa9adc46ddfd9cae8fc7bd34669d3858c61c1259cf485338cc7d0eb83ef31643b469bb25a3edcec78c158f3f90573c52295e8e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c +public_key = 597e83444ffdb026fd26965d5e946b700ab88e8dffd6ae376a2db5bf8df297aacde28588db9ec719e4dc1fbbdaf109742bcf6c456961338c44c93c83ab58581635499545cca76e60e15a35ba4931e2c9efee68a8734acbf72755e8d452d28fe5467e61284435eb6a7a2933c8d146a12689e43c8d740f68ae062d87eeb988771a8fb43b34d6ec79869ad67065ebdd19cb5313892bcac9e4fb500d3375ae57ea3ed551b2d9c7624fb22607615454a910f8578e44b448aa9200e8d5cf5ce5eb635013bb80a65593ff578c7a4d66f05abddb95dff976c74ed6acb4d4e064fb5eeab479a13ba57dcacf800f421613e94a3cb54afd8c0e8dd7918d9ee0e585dcf4d88f96a7414fdc57d5a632c8bf5ece73f0f841173aa47cb4f004c8d8eccfa6a187dad9ecd6027557f814f0db47b0159aed1f03f1070cd68875c4f6efefabb67bfe99d9e10b51bb35c76d16d5d0e6a97e56cb93dcc5908ffd95f33009bda237c7e1421af0269a7097396a4a98be20c8f26f1d3cb1136ea3fa39d438b305b63fa049c420cc37849fb9fa1ebd790dbbabffbdd7586780d7d78dea622d05ed729d841585bb16bab9a0d83625d55826e3949bfde8e7c4703dad82466b9a078393c30a4f6b8befc775c9dff7cfb69d9cafbc66ea946e6f098f881b303acf51fd3ac1430f9e8738d82f838a202cc3586672cc6f85b12ec41e4ce6f5787ce6f3e9d849483ff4dd98acf46f7c36c11a991234ae7fea68770c79d839daae3bb72cbde4ab1f79fd13977a49b0cdd494cb0dc610dcf306059b69568639ace591ff74f745e42639425dd88026f8be0f36dcd66672a12b5c7b5c73244d8a281e677f16f625eb8f365ed98d079c142d8415dccf3f07fe1999721db3c271f7521d0be0129b3cb6885311ad689166a3b98bd9610347ceea557975d720db621ecfdeefcf4eed2e44fc5f3ed2e3df64b9c66569f8b4dd6e1fd9b088ac8b7c964213e5674757c7bd48a3d06635600f49a50548f53dc55a6ca0471953eb7c67e24daaf74ffb785ef25a3e622ecee4ed46b9ea997974c9ae2f54b87125ce79e8621e8ef688c5dc7a49877e6fd91643a4a53e48560e35f27bb30fae31521583f5b792563d9465f4b9f2233027855cc0e7c93bb33705136c8849fccb7e725474dc540573d4bfd032c9b297eb5b02c954c744c4c6143a56eb48f2de5439f885803ba5acc5f4f3d54bed47e45ce9e73ee9fa0007f5273787cf1b89c798e84eed905bea74fb43eddcbddcdb7dc1547c634d7d6a8457e45489752b0633628ba4f5286852eeb5ffb8a7fa2bbad309fd542ace74e67aa07b467f7db6a7e3d5669fb36a7a37c6d7e14d7ed721e9c6ea933742e43609d4ef6f48d3e99a8d5a27b069bb73c99fbf085f4a8b2989633c96ccf33791caf9f3d575f249c640093047de684fbc701ac633381bb349bb7d361f30a8cbea232f3de395d258ac7043b887770a307c3746002cada38f6e47f7694e05f094fb9e3645aecf6f73298592c00dc0fefe4c07d8c9fcb4d1ff45ed2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b9ceed0e47c323d6b3c0cae2dc235d5d4edce2c7bc1f0a8467e6f7569ae85855750f1f71786d355a0b8a756468e964d6d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea +public_key = d8279f9a0681cb98bc38cb55143dd31f56f62799c183bd355eec82cdb58d750596a4e6bf121349091d415a4b347e13c9e95e4891ad995843936be342e81c7f4a7ebf9b75925e6eac8ca6e492a85d83fa8e34deffa37ba08d7c681d6feed416d481f58be683d07a18e322fdee224e9e242f83a01cb1a458e550dbade263382eb93b7f4f470b265027a933c58dcda44da9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a377ec18479db18fa706768a641d9d2d5ff4d71c7c95755ca25bd56c355e9d2fcf5006662c4fe8edd4b318be9962cb514b0ef4246be52eac41391cb432c6caf9295c66da4e5737ae3e7dd23f46aa7b6d4c64a6c4043d6ca4b96fc39f9aed5b4ce7e6c631b473d7e6ecbdde9826ab82c0c58880d77ce8f9bcdbf59d6464f4baaccce334809b43acba9f48bbd966c88793a273ae857946902649f97b55160affa2a84fcfccd54653852d94f1b6b78c289b49080c8efaf85df195ab566fa03f7d99c43c439a25ab4149db86db4f57188f013ef9f3faeffdbb9e9c688ebcbf6e0d7ac6eea395b698a13407e09858de883e3b79444963557cef8f534eacecf10b74718caede3bcbd98a68d9956facd8a45f2e84c17be4048b9d28e8bfbf5ab43d1b650ee8cf13148caf55ecfb14465615fcba08ff2f765c8c9c66c24bdcbbfdf57e7dd0f257f00ab87f93c5e67478a27c4fad778eb691a5f9bb1430dfcc809e27ea334b33a15f7a1da5e9c28e30971c55f6fce72b96f48059830fc57c7356c9be8f63f7d571d0f7bd88dfa1686a7c41db9306558cbdf39f0176959a188b4d457b41ce52b7fad9f696dd4d945e78c45eb68b579d48774fbf6ad43bc1be4cdac327c80b5ce116cfcb58bbc24a28e4657dabc223ad510ae1eefc311f1ac02af4c7443fe0233a4abd4d8b1db484e7885d23acdc2b9c4952e577a8ebc3d6a7684f8eee12db96e1f988e04f3a3963d1d3ce5fe3feabf708bc64147a31ef717f7868007efd50fa9a3d0b3a00a7f59ad5f057dcc14319c439fee3da967f6dfba4289f45b72cc86c07f5c81769dbef71e19cdb6cfa84b916ac8acefa1f9bd5d895f7ae4d346775cc8337e31478d6a3bf884e35628169bc12f67811c5d7bee3bbebca81ab93b5d80daa92898b3f5cb6e9d345483ca3743457fad8cc5bfcfa8e8af2a41ba8b67641ab28ed42abaf95edd55206b648d8e361f8486408b610bb3552299316b5c0b7e3d1dafec3d566f1859ab2efaffc5aceeeaaffa1f0ef77c544e28f2cae6b598c10ad59f0cfc24e9adc2337bc2c57a0bc64a7fdee90c656b52aefe244eb66aa1df88b5c484cbd33020b9b9bb3d19c7f387f2746b3b893a24f7882bc3136fda1808f71f9c8480ec6d73277fd44336b32f851a293f24144c480aa302c05836eeceac4569a613de30b44e4674ffd189ee22954ec4513a2e814ec86ed35113992f16799dfe8c1eef3aff8daff3426f8808a81e8b66ee5ba47ad0863c735a904565f036a85fc2fd3068e37abeff06d3d3f22e3d27e83f542a342caf3376d7bd65a745e31e865fd2f43db3ece08eabbf8183b4294700bf8928da8ca78ccd84918e0c39747fd3851212bf2f26451f687fe0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24 +public_key = 41aa7b69158362b4e767486ec3ead9ab4335fe3af5dd7cd7366478cdb9ec691c5ed9264f782ef4c1f369315d802f58df5df89d5cee89da765337a69c5c838489ada4ba7880e91871fe346cf3abb0aaebadb31eb5acd3b773d9e46cf97920f5d9dd3dff7abe4734c9777a567cd44a43500b5eb90d5bf4c5a3888de286639e6d9ac2574b33f253fb3a787039e34b2af5e1a288f5cba7a8e09b401cfc6123d3b4c433e8e8bd32341f30daa6da0906eb6a196dc185bb8cfec1a6b691a06cb5801fbe1e55f69c56490e256a84ce3352a878c734f430fd68199ee60fdd31677efd69894951d65b95e690db56e29d149afcafc835d3b1380369324f3d2f84ca51179467bed28d26d1d5c397cd8eb1b5e468879e85b35d95a0e5b5dd6a421b5c7eceb58c4cf97b7ffbe14fbc435c78857c75d98e4de7ff8a58f69f7e5ee77130adc2962939b9d8c84bb6428b49d2891e88df17479fddee4709b7850f35ccd77acb0bb3a05995693781fc8eed62ff883827a96ddace29a9cd43ec6abd4691be1a758c7fa629f6aae1c795982cdd8b08e70bfb3b905d47e1b4e0cdd49c6b4fadf0bcafed2bf1eeb95d505bea49beace228bb5e25d8bf15e28f0cb63f5597851b9df4caa5b6bce0f706e98dd4eb0286ef840caa4297ec562d5cd09771adaef5d6265ddc56a466249fbd774ee53756035349cb1fa48247f21bd53d80feac1834f442935ba818a3b61dd7a30ce5a2fa3abe437ff157d5df0cb5af97561b6d8a3fea42a809a7a7d5491453c849dab7acd99636a3ec007a70d01655c84dff9a36d12c494de47839c1faf951a87ff73968dae83a86f392f12e873be4c75d3bd700a3b54005ddf6fb664a56f7dda9c753a4d32f434655755d12d4c782ef324bfdddd61744cef6c5ec9680f379a26284bf969da3345d905e18de9c7d547bcecf3ad888f40f32fdea7bd3ce84faeea9b6835401e737204c5ebf3bf8f2b58edd399f873c7849cba8064b8a20c9c39194e875b4963bcaf097b958d85f739383bf26787e64fcf15974b45858e85f44b8781cd714b9651a7685e673cd1c6f30c5d6639ea5629d2d65990fbc6f2b95df27483634e165b5f4ea99a9424effefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2e3e91662f701e9df52e9c7fbd8ae7d306a4e2fdfcdb4d5f3f07b38eb65824d5c9d8c9ef7013784fcaddf0348f22cddef5b3f5c745a82a7e4a5b9aba16acbdf029771d64e5e867590cc5a5746da896a4d7f0749ab9ad8a65e37e70146fc1b7bc40d789eae83761e7774aad7859bbc046b5a87e3a92a53682521f7f13df778a3e8f8b9c3c1f89f11a2fc853adb0e10bbb631599190b49a66937920b3f123e85d89c6e37da5f7ce9c12d37c12dcf4741cb9a79446606eabe8c9ab06d8963c959955f198e04adbd137f42dcffa2190f81a7b65f55cf8ec9c6cafe64881d6456c086d7cdfb89e2daffb3ba8f835772015ec30a5f734a3fb08c5d8402a6a2f4f9c76b053c13af676199f8032b5d9f4e990a18c2c04ba7c2868ad9f45390feb4957d7eb9da6b81374d7f9731faaf6089e7d33a9cf4600944d65871d313387c5ed1c0aaa27bee9d978653638577bcf4caf58d83eeeb57f50e544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917 +public_key = 32b6c92f0594446de427ac964fa569ccbd74c81d53f179bf1963ac704489ebb9936e23950f5eab7e26a98e6d31c75f701fa4ac59aa7c15d88c0337a067257b8e9e6db0456fada6f2f44a928df6cce84a3e6634c9cadaf46208920c487b9a666342abc38ace4c499785bcc9ea95dc8690bfdd26bd8ac0e48c72e9b48625ef22cee732debf059e74aeff79fa1fdaa98c38372877299c4f54a4493a4bf0f8bc71cbc490b363c4172d55cf3a5c1375ddb115468756ffc01b5e5b78c9f613f55a34e89c8d8359ee7e01b9cf736a77d78a32520b6ddcacedd66ad0e84b562c6d7b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf14ddcaa766bdce8d6b9aff91f5eed6d49aa37aa4463ebd9d0af6c116a842f5df53a68bf26e7245e8b7da778eb3343d3f2575ea84627c74da6519e33f4c5d7825ea66a5f45659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e657f23d0e543899e2ee0f8ae364a9faaad18d8558c3e9b179b66f2488c2be8792b1849fac14d1a9756f209889fa637cf7ecc4f3ddf49eb5c6f8fdf19fbafa9433759ad7ddabc7baac6f3c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d477f73268a0797b8d6fe57ddfebd3fff7ad3d5b9c80ece93a8fdee99ed934ad4f51b78263aedd7e28c0ebbd6b91a8db65056473af93f246e1841f5670bcf426f5e4790b945d7bd9c9ec354fe7c895b3d231d95794f89ee60761acabfaaa9a75ef168c0a5dafb498915b35e8e11dc3800764bc5a65c0c54b2af686b7d954e77bc4d08e37ab398fe944f9dd0ab80fc846d4cc8db2b9b2b4bb36d4d4e21639c1e756f2e69f507023d2301b4df97bffa62736b29caf0876d96f94f899bfc6012b93b5bcf3d1f39e1a3dd2ff0b9005fbb8cfeb893066fa4e0aae7b4dc5032b8b34dd760d96c7c203920e2439d3fad2372c7f5e8db92259349076ba20c3ad50efe752a3963cd5e2644fa963a363c1157f3318973207f53e465b14969f1dae99af45b5096ef6685fe51a235a8ba9a595534bd6aa31cc05fc8c5885d67ea93d2577c67d57e2caae68c9c84f565c7278efb25d56a355f36c0fa1e6be3289388f036aff8e03402f9bda44259179b9d4c957f5319acacd28ac1e449b87e891619e940e33861a4a35a97dd268fd4ffc6a3e06d6d858d578bed6dee87e6fd5cdf25e5cceb5fc54373875233ddf66fc880e0c874119c71f56fcb4eaa24e67be77ca6727834419abf7e2a55b50f372b65345133ff5d83f4caa5d4ce5eefbc20e639e93b331e3b60e1b520e03c9703a69f55cfb1b6ff54ac44b8603e1a82ef63a5a9b87b7e16ec565507f97ea76b63f939c1f49ce99e5fbc588761614d1568e93ad98c7c8f4b68237e2429679214bb2b6e8b324b58e1f57695dc8968bca7ec47e7df13ce27a4d8183b49679b349e2e45686f7f2c3a57bd9547a65656cbc79aec1d3b129837d84a6975e0e8c7bbd4c88775e9c68839955775fd66ab02aad69b7630705eeb2ab33915aca61969af0fe4674a557c42faf6997b1a8d9c51445884789f27ee742986446ea27e9808996059d38e0d9aecef8f8ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e +public_key = 7c7bd65ef3308afba0cf46d7b2c98d83f76f7c058262b55f7c0746b4dff4380ddee9d7cb6904dbfe6dae75bd506afb96e30669f51c464a27b4f17766709f459b293dc208a0dac5654b8d58a8fabc2d1853009743a598bab3cf48068750f12ff7be5a4f7c4c694809e77e88894d43b5aa446880fe77de837e2f0537f708a8f74ae1fe6632dc285c9026bb244f4ac3decbce39ac6a0a7687fd88d617b096436c9f773e7cd5dcea2cd8dc2dc2949a7879de8e747fcae746b04558a8fbe97df0b9a6919d449b5d7e6e2cd7a35680422d33137d37608bff060f690b47bd300a84c14e650dc748ac3cd6036dc934adb81857f43fc3f67f3cc8dbea4ceb4d790f37cd0373a71fddd634bb3b3b087a82ccb1e1dab7741de56e8d94a1e6ed1f1bb3f977b749c938ac8d92d71c93394856ed133076efbbdd3cc0f28cfa2d34bc0f633f5e55c0a6c989b2ef77ef9e32f8779923fbfe22f78a160fba5e55b6d54ad5137867c10536e77fc7336a3ea2ff37263a6047ff60ed3871f1d479be58974446ea0e8e9439779075cc47a5a33e193f6615134d9f09b68b6873c6ccb682f6b7576fcecdf5432c47e89bed9faf36735fbdec12f9ce6404e26e5d9c71fdd72a34fff126710d178daae8653a2f6c93dd90d9c6ddc63539f51b46dcff4cc8d54eda255e0bce9b03d34f5a37db6fda6d6408bcf2dfa46824b5290b8a26b8e3150fc9afad52d12de759345f86a66a4d238a20c6531d89f170d5fdeed889ad3d50ff87c65a5f433793dc2066f2a989736b7880932de934ddd73c0b686106a9b89ce7958a8712df72392ac449cde507634df5af3846aa9d594c80bca99f185d5ac1793f2877bab5feb212df98594f795c5ceba0dde8dd15b510556ef89b687e7bd1701cbce0b56159b9df7b2c6fc1039aa38449a596c087b6fb2ee5a7c3799f5b7debfaf8b9c5988350bee5af1edf71167fd41b5cccc451470d9752f380cdc56453e554cc779604f976fdc34e9f135261eabffc0ddbfd5e4f2699aa6a5aba063854299ec6858c7f6c6c4a12e4ce2d89b50b04c33fff62ee9bdd9a7777d3c56c86bebafad7d52fdbaed253d3c853e10c1892381887eb45e134798b9745bc23afd8b277c2c999570075903deb530cff2f7906b75db35c3b24b0485ebf6ee4e724058c70988952d86b495e9265df5ec2c8e7894ac370ccd8146fc841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d214705875e0acf76fcc683036be8c05eca7d18dfe0453ae00b8e44789e17d8ce9cffb568a4cd959193d689a6adbbce3df43907fd45fbf43e3d4a4f5d32ab9d81c6bd9b3486c3636e7fdd1525fc1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fd0df1cd7eee3e2c8e52f5ae886b8d958d551e1ef8863e8e5e7ceecfeda3d75b342667c692de9f34fc7946e7a7057d97f7938516cbb6c7f3abdb85b15f4dfa5557e98bcdb89e8cfbfbf74050a7de8dc746cf16bee6147076bb89c61f4a8aed70a785427cea59040ecea7bbf8aebff8ee7bc7fdce7074063358b7d6989c8d6d8f67728790582fcca1af4ff91958c44a3044787eab3599ebff41eadb932b06b152aea02ba8b244f9f62ba6e4441fe24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2 +public_key = 9e686b49d538d03fa05ac8f372f7525d04d185b3413f078226b97c234b815ed6e5b2683f1d9ab32ecd314c6cce6ea6f0c8e73b1dc85bee6fd5cde5a4504d427865a62356ce4485ec7278a3b236bc2e2d8c7b38312976e810a6a2962496d058ca4875ad235cfdfa5e612e665984bbae792cf79ee835b115f02d4751f1a330dc7bdbdcc38fdd6458b0ca7a9bead26bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847497e42561863b5f38c5aa4c0158ac28ea5d12d1da8b8e99ef7ebe2c16dd9311a74791c6c8b355e4a96edd3cb6fa085884d7a7e8ddf70f656ce29f9bf3c9eb79813fc17cddf8ce7f2a1cabfbb25c30033f4c56b66df97e82504581a86f97ffee81dfd5a6d89698cc94022be6574264436ffcb137a7a667a4548c96f835cbbcf27805ae37448674aa998818dff6d15a63689777a9ba8f19ac3b9ecf842048f6eae294800f5a07ffa886cc86e7d095f42c471c22ea69a1972a89d6abbe3e003f6c8c1dd7ef58eb560ee85821d84d9a472ccbcc586b6a9a7ff4d269ab36126a3f048eb2963fd028cfd5f2ecc5b9c6ec93d3e4b388a6c8fe6b3e581c05665591d7c8b94c59afd9c2ecc4b7b8f4fa3db9a2a8ff317d5bc5d43827f4bc6d3b9ef65dca56ccf6de9e4dbf2f69263dbd10aaaf4a749c93173eec3de3ea4e5e36aa8a97ffde9af1f91ea34b0807886ffb3f3ad4bdf8308ff5daafd748945a3ca34b9535d056da6f734bbeeb66a4e4cf57cbd79f5e8df6dfbddbfce30fe5ae82febe62924d3f38ae91c48e723965c3fe9dd9f2b67c36ca3ac24e030ab516b0e45363faa06b73a91b5ba7d1a308e286fced38f285880112fa4544fda857b564179c55f0436b25cb191865de69877b57d41daddc2c9bc42cb5e3f207a72ea9a5cc48b573fc4d2ba8b5ae6d73f2e1bd44b8ca67d1d31587d99b9975fae8ed3c7f6bf80099bb61e38d8a7af7bc5d9b86ea9c74d7dda8f6b7ff87879098248d779d7ff6aa12e5085ff86ac77c50849ad1aff9a33bd7ef527d00f07e899d6be1d177508bb969d9479c7cd37a6ae8bf54df721ef40dfb6d3b7f8745144906bb885235d5b19336bee5572188853a47b4f8ed8a041bf51317f99be74fe0873e7e25d4784a9df2149cb2d89b1a864fe4a19cfafd57adeaaf34555e42afcb3e544b49df75b0cc78f5aab93585f746ee7a7f793677743da67ded63d5dbecd4f86a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5dc8f51efdf67ea3c0eec342b525d5469aa7fe936a582946399f645438a3a28f859eae36e033b926695422ae89171d816e136dbbe36adc08cf00e4b44649410b3ae1ef254145cf7787e54cc5a533e8e54f11ea94f7e9c200adf5a6248322fd4a53d3e788defaca9cc78fdcd6b26e70196ff15bc6c29d1779f6ce83152cacb583a90399746f75c5bb337f1b68db9029b112579884f792ea5a52188ae09f547cda89b7fbba90c76d65a344f3da55e5d13bb500ae74aaebdc561e9065b5e23a6eebb43f88f994b121da8913a9fb979a59bbd64036968621e76ae346d96fe6e25cdac4f767a883e6448b078dc05bef2b7aa49b1e80c0f3bc66dfa93468f91a8f652063419a9cb7f114fc38f483c4b9de17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241 +public_key = ecd4c65cec93aabf6efe3b667405482e3aa37d48aeea67c16a9dd8da4b68683697dfd34fd72a6f39fcdaa18d6ea5c59b4564e8306d34b9c5b7cb438e22ae4774d58afbcdd99e478a4ba8568e29fc71db7c208b7116df9bf649bfb4df3c2e7d59978fc549faf8dc16597a43aa6e65c77c53ff555bd67a64ad62ab71493aeaae6d45677c74e3e8773fb8665259abd92ebf08efe57c19e99435bf41a9f628534daaf8e4ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0e8f81758d5da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5eaf467db42479b478f0570d58d71f038e10f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b3defd350f7aede4a22fe8dabe26a9c93c938c7be3497d8d1bda7fe6c55bf66981695487ac8e36305db7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c4bfe81b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee5ae3b75379d2776a761dabb21941c2b36357f8f48686a5d973b946c8fe419df29075ea073636b367671cacd01ad9ead03b9d6e83721bfef47dce88fc05b0249571657af76efad9b6d3376d2d83366e8b20cf748655cef08d5c39165d0ce9bfed16fadd1cda50e43167d8de540ea076c9cdc2fe3852a5987aa3cef5e5864b7d6b3de947d2ac8e8cfadc3f83745b03e95bac9fd026f51007dcd31ef9d7d5f15036e14c4b5ef044a8a29a3f010ad3a0a3ce928a65ce8cb566848110994e7dffdea5d3d304d6ccbc7477bb78b3ed5f7758b7828b836dbb2742b06d95a0bb882c2c9d8e26f6190f9c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca96fe8dc27678719ca0d4a8cd8e9bcaeb944b8cd670bbe71927c56c45d34ae9fbb3e77e4d0f7c138cfb9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b78f40bde93e96cd311aa501b4cec45cfdab6dafd2eeec56b65618ca53f0f9e55095ebfbc289207de406b37d47ff6e0ed0ea86e8ba94516aa926b99879836dcbf7a7056c4d54bbd19a44097deb3f3e9956cbcf9e7ab95f175b9dabdd78da633f10a6fee899f400533f0f77102eae9fc0f610003674828758e23b5ed7f4c6829b95b8a6751fe988f53ee7537ca9d05701ac8ae203468818fc5c21ae22c6349db27ab9595d4fdb4c528cff3b35fddb7246a4a69b58085a3c1e6997ebe9fe18afbc23bcd60c9f4cc393ebfca864ead54ba38bb734bd0fdf57ab147b922278fb23fc5f5774bfe368dc2b6658389dd31df82a248b7e9d43a562ba1892a985b75a7aff961763ad5fb35b94219d5bb8c4de00a3846e38ca7e7e411e89f9e2c9489c597834c7a5325d8023d648f5347649e84f315bff2d58000eef27d9e85ad09f13ee5dbaa43a9174a7ae9b565602f45a15c30f877bb7ddbfec194e3889f738113895aa8ddcb3ebaf6c5f61f1da1d98ab661cd66bdbd5ac264f9775c3bd165dd4b8f3fc96442cb2770751c812ce67613e48bfbe66a0fdba90a3e75143fdebc3c55fa1364f3188121a9d09bff4fa07dc3708eb22c2dbe542d8f0dc44dd3b6abb7236e1fd37c530befe8c86810863a87cdd29a58955dc73ec8a436112b5c3a75ceec356bbe9e355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175 +public_key = 8c5785417b65b2f4f35cc67947d7b2156f7d326ac1adebccc3a64018fdd4499a8887c4a649e443e757f0f1bebede5fb1a8eb78b3bcfd5516b7a3233be94485762d9675f4a8142fd422684191d6771fffb44e9fb2ca3bcdd5f5ac20a63efc237ff9d99bb405da4a0ce97ebbad39b8b9ce7590229d74174dbabf65388626f645a84263af4b1885c6274d3f231367088e6acf28950cfe81742c98358df2cd5941b7b69e21b5cfc2b4c6c503d2be3fa2e798fa1e1a9cd94743fc86af0ddf6b51b3512003cbe96f8d299663db4dbaef443677033da8b8c21e1adf12fb93f4d63809375fc877866394a1a64d9e2f13b3e61eea2a58777334e5281b7b19a9ee6feda47066eb6bcb46d87b4087fe8ca29c5fdce6f2f53e5dd0ceedb2c6cf136b7b0a97dae89669ae2de1477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f4994361e8d9143723ead5ba9fe3e5cdae81309ede11d92917ba1d798ba359ee21026713cee889b58375e5c4f9cbdbcc5fa808e3cd0a36ca575c68b1d33f77807ecf19f7c602d92d16f95898f6d030d5db9ccddce456e2c9f8ec9fb9c7a138e7c1d65a2b660c287c3d17fe44cca71e6def9455fd73ad48afc555768febebaf550d62d659496af9237a22c27670a18df8a56e778aa42c6ca9a955cf8a658c73847a586fc3ef26656234dacb6978e036e52b1149b8e4f6aefe37bbd263a00ead5df48375e53bacf9c4c11d4bbb055666bedd8736b9c323a997476e215495e032aaec71eaf0e6a9245cfbfb603ea5e6ef1edc3c0719c3fc1365c2bfc70d5d6e40e6a383714a0931ccdff946adcf73993bae13d9daef03374e35eace73770a45d428ed3fa9ddb4aed8832526968412863977ff8644b9af994fc2e9679580ede350a3499876f26de57bb38e2501c8dc95365f83bc64b6340fa6cb4c38e6b328f4d0297f6df1ee2aa9ccc9e0b6869099d310aa6e5b79609487e7b2da56ba75c45986f92f5a4d177ff3d99927b1e93ba15bf5eff586f8f3292593c4a4febad9d44e4844a7a6bcb093d9e262db6ad0fdf73ba5b05a3ee29ba43b31dda48d7fa5efd5ef715cd8865cf16a835a84cf7151fd71e1d68a426839cb4f4cb666545664ea5e7461bfe47b9d84583285ea2ad5a0283f031cbdba41be4c828bb0f8f807fc57882c3ed9c05dabe7b712f5699482eb55db9f1eee8ad45c8b4e99931c9c7eb473a89a2d4821213a1acfc453b4e784d35b522e93c2d994d083674c71583793ef8477bd4fed7ef17ccc65b9c83f53cf07b08adb118f4a505b6da8a78d4c599a6bd9979d9491e1383ea15557683d614fcbdec1a8c801b94084adfb55790b136bc5f37b752f3a6c636481debc5da8892ac2bd4ac7447964de5e735e838acbb6e24b508578b62d7450c46c7637f806ad4d7112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b6bd7b96ebe5a85dbedb4a90a6d5e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983bf9fee7978fffb18553c7fcf0797b2d31e7add5ac0abd7ecf0e4ca84cf6d228f95aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6125de8b9a56d6305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3 +public_key = 605471feaa9e92b94016a9a05f585f3d5fa993b9ea6db73c9ae6364edfa07b7cfafb449122e76a3b273d424b94343b3bd7e7b1e13662059fd819c8ba8a8df18b3ff62ca649d8f3f23167be77d9a466c860ad7c320c2f7e874add68faaa442cd9088d5996d64f7759bdeed65cce25b3680df1957e4be404ca9fe56f6ad99e7d38b53a6f81314898036493002cb516878db66ab19e0947897fc0f76abbe0f754b443b13dd5afe71dc1adfc52fb3c82488984dbcc4d995da0ee4bbc08edd51208c87914a3fb5e59c775ad91a552c20afbc573787ffa68f466d12a06d1b07de83f97cb3e2936ef683fd9efb5742c6de946b9708f5cd0f480774da53266ec717ddd4995bf8d2ca543ebeeacd68d29cfd7618cf3cd9a57bbf75abcc6f0da4e913e75d6ab1ef3f8acf61ce9c39d6d56479d4d22586643f4ad250870afe94dca5d91370fcc1cdbb77bb9b4e05e8d1a18ab0c6af59493d2c0535908f7df84587eff16911426ec3e646740893faaf6b37c5fe68fdbc494549776e5f8c0afc2baf6a00a7498f403347a646c9a58328c69f74ae8cff8c8f788af9d67336dadd3404fb550974dc29c9456fc08fe4abbcd9899ab109aefef97f617c5ca780970182861c046a594e6f757d33247b79e12873493634c16fa70983c9b5948e4e69bb1612fdb4129370519327bcf332063992af4370d9871e8af7d145fda70be6ed9b579d1daed37bfd94eac96b547e09ad83f4efea1d3ee84c309ab65d75a3f4d9c57578214ea4035657757ab92aaa3da77df51a1b87bc6b58f9eadde38156d74ae961c43be2e044314c89eaa7de938cda87d9c4b14cb9e79d83e722cc40b048bec5ccd0393d4ac0a65bf93b9a797e05ec3eb5be8845c5c57b9a9caf6243f54438ed94e59f6beb8b256d73b27e5b0f635e80789921e8dffefce08887f978dbd4e77fd3aa78df8954554d398d1675d785b85dd28a1675944d75979690ff955999f148cceabfabc2358c315076c6b4333a835f0a843f543bae00034bb0a6776cd959bcb2630740cf99577f6d0d99b9e8ea7dfce4f13ac5ceb5b9eaaecb28e38fbb517cac0a8d9073c3d0867e8d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0ee03f43c09ed0bf5a6a9279f6bde36808a9a3515b02f3d3f4eaf6f93264c5ac9d10a9c8550c9d76d6471c196675eebd8223672c2bff9ae3ec05ebc4fab557f46b4bb37ecfb605a87b888a1f475516db87b9255e127436eda89f2bb45b8b856f12264fde969c3172fcdd62676a8faac5663a8bd2e91711383ef5cecd8ae83bb55cc3c83b566e5514f233d7aaf96381dc5e62f5f7b09b0b6176f451a7f7767db1c17b7ba335511bc3c3feb884e459add3a594dd356634e9272499b4f9f58dc9aca946ca80a1e999d455d074d7cf9c69e814478a905e6188dbd754a440bc69925155fff0a675e0c322c79e74c27cd814f79ebe3f60feb62c1ef4eb63c7a042996c25bc9342c589c44de99999f9d5d54ff35c760a43974096c60df3bb9f5ee2483722a23fb0277bb251ed297c4ba2c58bb286c49ee2db7aae98c5dabd602fd6ee54ce809ed7fda63e14efc6d37bf8b9076e1be4af9e68a8da76457be64e9d80d59f7d3f9abdf8692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b +public_key = 5b668ae78fec7aed7ee6df6233936d195b62b2afd58cfbcb0a5a73eb0e54d89ff4ebe84b7c7eecee7f56d17f6492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9b7f5c5278c21d896ca5e7d6e6fd3d725f6cb175ade36d6e3c4af4d61db4da8e6aa6846a77663a80f5ac0d3647483d7068da942b15cd2f0fa3efdf81909d56d697897c5d9bd5048b188f40c94e580bbb77a7a4f39a6d72f3949787add7b19442f51ed09caea03ace8f191cca42f9551713cd791c9fb847690c06f57bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32ead70fe29411f17a4216fefc6acdd09a6425b2daffc98681568b8ccea88e54b8dda0efbef4b3c11ff56eb25e9681d91985aedbea7fa901bb4b34f46d7ebd1b86665374bb6cb94eb3cebf593ba5c96f3fc20936ecbc4abfd24af76158b37afc752a9bba8946b34d4e4eedb355a3ccb8753e221bafe937bdbd764de6a7e42da18e7b1c5e314fc71d05de7f50544474c572d7dbd142c676b69afbb4f92f6fe9e88163f2ffba3b1685073c3bbcad8f5b095b5d269f28a459fa7e866e09735e4cab8fa733d4db6a9827f8463978833a4d59c635d24cd9fbee3cab45db9976c6a8baddc8e1693c47d4e789d49ce2ff1ce767651ccf3755a3a49c6be0d3e4a8d6de579f7a44717de00ee314fa3687ac9f090738434e55280b4ff22a66eab77a2933bd7e6857a32f3ea528afa909865e053a32148b59cbac225def468e444916ca375ecf04d7dd89909dca7c854b3646f2af3981797afc5ef61c7a93aabd4da93a9ddabd8f564336d02bf447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad6626e8913f55348e8f8463d1da4eebc8035714b7f2eeafd6978ef3e664e0562a7460ef8f90e5dd772a9cded635423f688debeae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbaf0da9114d45705df3174c73dd8a4d50f9714bdecff718321677a6962587ba6ca82c44ef02a7382be9715c4e994dc9ee6d0b487207b9b76d793f6f470c8d6a7444b6faab38f48747494d62ff443ae1da9e7e04f0797398f15f7406787e01ee97ad3f48ee5ade5037cf6c754abaaf4d08936e9d43e3b99ac18886cfa9a7f031fea40e58b25939a21698c43449e785a3a98f0445567a9dbc0b4284d49652cbe862bb76fcfc6abf6d831cac9aef64694653e9411a30f87deb5358568c0e4e67a76ea42acacd7c3fc2f983bdeebc0667897c9f590dd7f4b5284fecf7c36b3842c62cf7af2aff2ec9589969ee717f72bea384cb9c8c9409bb26d743fbfe96d3b8b33119a379d5cbf78f3d4176ca83ba4e2b4f6745f346a42861a7b5343ad3ac26ea8896ff4a379c449166e23ee9ea4cb7d1bd789da84ba0ed5c707d373634ab7a6578d66729ef806b6f62cacb4c4dafdd649ccade650c3a5e40c8346d9eb27fceb1a957c778ec9c968c670fc846450cd8881c54946b5ab0c6d33f45afcc6a61fbb99746f3991f5b827d2f972939c5ff72dbdc5be31eb393d108c56556719abbb97855fff1befa1d138c9065c304c8514668e9333fc833bd5b0c2ea10483c6faab378c7be415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f +public_key = 98cca518437874fe44e8ef61e8465b382d582cf7706d684f84f6e8e8834f35857d4a8bbc313e34b6ef35dd2bf387b8ec663876c563d293f99571b97ae6af99df1cd12e9662957d89c908e7888fffbdd3dce50689690b30932a8a3ce7bcf6a353bf988dd41da2c347bfe6c3d999e69c455b9f472b9bcb1fe6c94f65e5d9486f6a7f204ef5c16467af4eb9f95e80498bf55aebd6a406a13b3fe389ee4c0de8cf73b6a953cfb2501644831c3700b7c273b7a3180a76427fef33c4ec109f55effce025fc46f658c64fc89352c54c264b97e5b9ec2386cd389d605127740ebfd76eab4877fef8f37468442d5b8328cfcdc65fec9fc2d973bbbfc68fd7a46db51641b793de73589f41e4e3fb67ec37685dff24f863078ad01dd43395bfab3589b0cb435a8eb84e54318ab46e398389b9ee46cbbfa9666330ec4c90a75fa0f036951519880a45bf5e1ddd4f4dc6b6554cd32f880d0b91b77e53c449d9eb3cd926354d437cf318c593f90cf24b548e17245c0c9b83174a67845d8b97ac6a8d8a88eddf78e2f5fc3d9e38b1685dabcafbb24f5076bf98ccaef0e89dafdcb9792c88698dce56ca5a789474992f57db1d5545158f3e87bcae52ccc872c951b1cf4b4a3bd460f488ee7768d57bd7dc79b3b4cc321e5878ac0a5c3146aaeb6ca1242d6b0c7b5aa7edbec6dda903ac9415da345bfe99cab86baa9f34ca5f6e6e98e2f6da800103e437b8498a8374af5f7b613fa0d03e42d1d34181a5afd6aa432a588ae1f644f6bed0fa593f0fdf753f54eae5677484738ff694abcec58782bd6d021357a08f7fb4f97b3fc343a445ba3035aee989685e8bf0bf7ed3fd39afabc334417379bd6661829f5ed369680b95ea54d4eb6546b9c04ca6984fb2a814763674abc9cbcb03e96f9466cbeaec698cb5c9ac08e5e90887f9de5bee556b2805dc749e85eb7a5a06e896ee0d48bbe9d5e016436477a68ebbab1e27f928ac8fa9a8b0a0d999b135a754af9a48ede36865b0f48f572b0697d0fccadc8a77c1b591bd73b63aee3f9d2eb6f0969b0aba3ea807303377afe0f49421b68d081f823fc448fa9a4690bdd0d5964bcf9a9e7fd9fdeded3bf683fa36935b260f3b47fc94c15795dd983bb463ee936ae97793d5d0e8a75c2cc770eb46b6d5759d05d4bac33f0669c7767f9c59eb94d59ff3d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb1beae806be49857eac1149d578b45414eaaa2f5cf1349df10b7fdf3385c6a9aef990bb946f4c888e585069b584998f789aebe27ead725276ff9ebe30529d50b74cff69a68545ff2499cc61f5845a80cdbc66f9e0ceaf0d3faff0046b78b2f67fb0e87f167f1ec63d83018772097892be85c1be99480247e6f3daac80afd593c630ba8ee585e5e0f84e4cfa8b606d931280a950e567c93c3e9fd23ca1b78ffc0b960de3d9f80455cabbbc71979c59b0f500856fc078e465d748ff2a6ae24e86c7aaffe2845568ceb5063fcb81b88f95b93a80c3feae8ee4a9a9bb7183ceacf347f2fa73784835f3375a29fdd5e4ceef0a119cd0feaf9f77aeeb873aa89ddcb3c76eff0d5652f2b4605efbdb1497486687f17b8ce7a096a5aed92236dae99bb7412f3d6cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16 +public_key = 5e55ee4c8c85a29fc91eff7c18cd684baa6376be7586f8bf1f0efc926e5bd08a340c58629cd45f7a49ff11ad4917cf49af956b180bc418b8a95f66b2d0847e7adf47b53d812d78fb1fc9e879faab69ff5602579bf0d895073780007b7d61a4d23a9e3eb217cb16a63ea09bf96577e2a21a32c754953335c29e769df28ef5d84c32b335deca6d67b975bf534d91ef5de3a8b67a19a331daf38a396a765f88f0a5e3606a734f5ba854d1e6b6e70cb9ee6bd0d5de8d9299f1ebc8d48e284a3a05a3df9469ec63e9528dac9f869a8e8866d7ade9e983dfd6e672dc0f4b6ecb4dc567f9034d33703b6fdb7bbeeedbf34588f815843b7b7664627cad52038f98db6060df3d2418df80aaf76419c876aac69977998b24d03968f9656c97be36fe063e97ead738d9bc995145cb2713b5e29ef23e04497d9ee4ec6ad5384aa31cb84406f93365e7d59dd88db8f94a8f068fce1dbe96f3fa0f9f6dcb5e8b3ff9f86a755f29d83cf667407768e41c3de1fcbe764d3334f3a763a17cce34cf816ac79ec4cc4c2d94fb004c352aba419be872817793017d8bb30e43a444e3a2a55c41e36444046a3d1fea4d88e8dd146d1dc335c76e52866597aa69a44f39a2814a4831fdd2672731d93b7fe5f77587b782aa279cca8d7d612639309efe8376fd49ebf31de3d60f98fd72dfa0a4c94adb3784ba17851884f3d7e8a82f379eecba7e6f6a67b568698ac3a2c1bd96b025e00bf9acfef5f2a029fe4998d439dcefa9c3dfb8bed545ee867b0c34daa8ece6e660cebb8853545994454815178c61bd4dcb7d73531aa2a5095f7b8578cd9889f44f8a7d1c72b8fb32103d4fe6df3a439e666bf7aa1afb508663ffc5aa347ecf9279a448436e614f2774c81374aa453024b68d385bd1565a36d98b751297477b6e780ea8e35375af8ef6835943f826ead1ba6a73d5263abc659454f57d8327fd0f5e5d3764f70ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cd4d7c00f7df8efa505db531d4734465f321107b651fa4e47d4b389c5825f0fca204f839ada4d7efafccb24a74e34672cfebc4f33c88c46d3a3fa6ce87aa5cff3d125f99e8165dc19b58a807ba8a586415c39f4a6e467ca8bc85a64d0fa1d457e8b9d75beee2668c0f2afa1d0389362dd9900ec66722d613948debf9390b35de555cada57fca36d2742f569a573096a2b54fc5a9fc3fb75f71489f91f097cb94589fa15bf73cb9319d93860eacf1ddebf7d48de03587ce3faaeb646dd79574803b5c4994eb74918768efb518ca46b279f9f68639eb8fa9f73f6ea8b69b004cb5d9e9fcf0dac9abc13e71444a03409714ece514a4ee8280ec19e34fae73b465af335c8d3588ff468346abf776d4b6ef887a7eb8e8b54d05bb55af338e55af7928c83fe7815d10dfda50ec68e29acccebc4a39e2aca10084e2543746be6c81d58ff6f4cefe0e3ec6a69329d783a1b0adc44ef89a2f843c81e96809ca4b82c75c59c7aa5e3e1350aa55e89735d9c34e6a8fd18cd33947f53d9778ca32ae4a9894c5e9de415056552d4e0484970cf2ac86b374644a37976ec4a124cd603ccc01c6c6e9955e4f13885bcfbff8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1 +public_key = a20c8da5745f754b89aa9d746ef771cf07a6d91d9998936b282757f344a1b00b851eaac27a9a7fbf58dd4436f86864f12856e598b5597c1dcd3a3af6e3f941a9a4719bcfd340bee81fdd8e3247bdd396a834e43f580d522cc3d7ff5be50bba9d8b6aab4746ea7947b7a04b8d934fd2ab1a3d6644be06bc6c1e0735d5e9f821c5b8e9b9a83c343d0c456b181b6fa566b0e846d2428b6cd344d5a95abb623a73299c5b465da7d6d3ed6e08e573489bbe457e744b5d1e39ab74d8a051a5eabe0ea6cff3942b2dfa3318d327437636cec1796683444dc26654a3f396e6e5eacb0e489142be4e9d2be5b7fb309287e5273547999b93ea3aeca2189f5645cc4889943f3ccd95496b71f392f78a82aa2af1d66382c47e54324cd6178d4f511f5d6b0698e5dca3e2d5658dee53bbf57e4b29d8c92587b8c863ff4872eaee963ae6c971c6ac3a3fbc974b9f15e5743fcd69ee2d3c3624a022f9a7420ba9524f5a432b46c5e8bb676d91d70ff4e357ce96c55bf067b3c305ebbf7dabd85a73a52f338008530323e3ae9971d38db3afde8489e75cdc16cbb3ebc95a8c97a768aaa7cdbb0da7943037bf2b4a523e33abf669c262a4ef327be1ec6bc8f05eb0676f68d6d433b529dbb6996f669f5a7fbd761eab6906178be9b9f3d1d6ec0b7683cea681648c44619fe7d6dc86441a8f423a9d1c288b32ebcd04ace5ec25ee256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7be4e45e837b767dd3bbcff3ff1a74feacc2e449b5dd9b5777e6fff1ffde4b395821474ab428aa2fbfe9c0ae69ba5d39616598dbedb9282c69cf3f9b534bc7aea58e17467b1348b1ab3ad31324bf835c98547eb0f53877dca53570199b23bc4d70a9425b3fb54759d82e794e111efe9b458206fed6db8d7c03ac3202a435015d815487626cede8706c69a6bbd2fcc9f6221e4a16cacfbfbdfaed4f4f82fb87490dc61dcf3bc76e8ed75674a70a6c43d4d68e2a7c9723a054967e4dbbd9f337695bcbd1053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd776edfb0b8eececfa4144e0348d988758379d0a73b0f348b00b4b14cee5e74674aabcfba9cfa7ff54d340c6f2b6cdbce05cb601259913c488fee540d8cd58a29adc28b856eb9ddd26a6a26f8bcde7d782993e4ceb6d56b00a84542ea245949a8c7c98d9f882201f64c658a8061a3014249b7f6ffd586a54ad8ae2ae8d5544247d74058bc9bcdf603a44ad5e99bffb69c167dc4076b345064ec00c5ae0d6a2308947593a84ddc6e33bb4d577b7b246dfdb5d04c5d18f81ca0aa10eafa358386d2a5cd48c89a2402c9150a7419c1aeaa17562fe786f00486dc82a9809dab08f8be6d953f981087b685ef69424598eaa990835f5d5ebddebfeb96f55b41fffd9f57aceb895babc38828c8ef7252d4744834303c496b727efc458534f46892627ae559ddfe70eee06b6af2b6b9259144f76abef17cd586c9caf01f849135e9080efe3aa7cdbce6bd8f17de24fb99822d964c60fac4ace6ce90be8eb0c91af559948cd56af77ca687c4f675c89be35aae91584d09ff02734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb +public_key = db55c6cec7b63c17f1aad84d2b6551faa4e167c78a0d1d5ed9e5300a24bb2c9bf26535ea38fcfb9d05a0636bf849b8ea2a7c6f276d504d66d2fd27630478f0ca168d70b76e35b9641ce46a45ffa394f496dd3f353c1a84302381e8d74ce4294a4a36da5b17d4797567ae93ed7c54e0593cb7b9ab74d214fc858d5c3aea6ebd193a927c818918f333b3a5e96857e3a7dbe7daca4c884d7cbdb3bacf50cc4e35d0b8c90af3f0dcb3c423e8a6de79ad5a4f40ae7aa036f3f0ad98d7ccb7a1bd8dc704c9532a6d864aa5f8347636b51f3337db7e2de37823c6ae0854e8fedd5ff7f9d42129f4fe5a370537762d0ad22b2e53af96a46987776d245fdcb9434d66aa115f4a3ca74e494c9de919c8e23c3ff77c58ccdecbaf5b8a6a8d3a33ef395abfa7d908d968a9d6a0985aeff5a8465afaf64ba053a3c18d89b2cae3814ce7e2494f88abf7655063c403f635d8afafb9e8d4e2e8967723ebbb07d19ca8e548036727df5f060dd5d605a24b8cfbccd4f94f065c013c8ecb34fd267eeb5d8fbcabeb9e578758f2f3ad3f087bb78e3db1f3990c867a2e679f48fd74fe1efe87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c97d36429fc555b81af58962ae771df477ff52ea9b46c6e64bacd1a8a6d00da4d9517f12daeded2d6fd199c7e331ae1982c514f27aac19fa5217be3ad54beebaa4049065a68d8ce9b1c969fbde599b7ed643e97bc33c2f6f958f72ccf14c7c09d973771fe70f1f7bb9e458a00936d8677717f5ae7655bc7a7ec56119779f7aa391d2356ae3a97d7dad4971cc2525e54e148568c176a659a8deccbfc5c449cce9e4d3cb7431cb3a0a50da8c7b59b1cc770c5bb5b65ed932d6e783c9979d6cbac053fe6a0cc5800fae60c8c8557ed721e7edfce13992396c382e93bad25e4d88dcee046525c443fae063c598fa01e5a73658a30865bed6344a6cc46729bab7810c46f5b58dd30aaf63f3d461769a55a2965ba6ba0b54d54f31eb98c7cf35525dacac8e881e5ac1e66ea4bc4b39fa9d2d20f7e56155f5e7eb7ca67415185319ba769f88345611ca2c21bf33dcaca9ddba42eebf04576bd028a79bfca57c9dbb0a54b933ca7dde45d32b9c5ed00c9922abb5106897cb8a6d65fca846aa486dacf7f5c6e6e99fadadb8ee729b75d86669645b9a223959b3c2cff3ab6536d84f95473c4c055aef9cfcd2e4fee9e73cbb97f698b3a60667bc7690e433208313add8c331e57d0fe481f259ed56a7a40fe717bb64fca6ef97d7d9a4ae3c05fe3910d75d7ac947f944b97017d570fdc9843a8a5ba56414108e01654766fa3d48bf6f97a1cb76d1d5a7ba3ada06a42ed1ab3c175422027e2f128f4767cd7bf14685bbda9f6aae5ad6574e5a7d9d35eeb37c5d9de3b7fe5e8b0ac65922eff3e680c331424e8f965e660467acdcdc794a67cc63da5b23db4cf2cf87486d1d26983764acbdde3de42eb96125956a597d14257441997720abefe09ab3c5e9af2c1d5f52527c90987a816b8830a757ec45be2e3efbcbf29d97e0fb19ae47cc7bc99189370a1aacef374e5dee8ffa7a63be809b515f79f077efdabca57693dec5aefc92eba6d13c7fc31648ee1e5d4ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d +public_key = 7a39e2329482f254f26ae33507ba8fc836673645f380b346ca39a93629df09576c5188c5e833e5e363ff34e4ef1c5dbccd4fc11398d2ccd5b50a7846ffa7bcade9efe757ab7ff3de873ba234ee3b22df546113d593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236219fe99c49f5142b5350039ea3164516fabb941f98f0daaa1e2e6e9ca7ffd64aad408bcd2d5ccb9b787c1fabe96da47d20e46fecdbab03cccb63b659c6357e04074b1f8254499c8452364726c1f94669a3a24ac8b487752175b30cba68860184d5f78b846ced7beba80f885d476dd59dad57cb08f7878c9f6facbc00b54388f24b7b53e347e334ffa046c46ef34124c958cf66023dca621ee400cd5c08b89554a474d7d14d86e5cbd0d15ec03c4580d3442a585f55c833026cce9de4dea70367fee4ddef27779d2a49819a370519c7fc404acb3fa441aa3ec67b3d33799519c883bea134242f35f92393dc134bce167e3ddb33e252b991b0edd7134a8addd9408c8cb2ada36bccf5224e8867b4e38ed9b4db04d3a4783f1614b3ee5c7bc238e441936b0b065e3c25f542197ed007346bc05fe6e09b756b4529bb5480ab3e65f6e7cf04e720167707f35a4415975a73ee4c89e8ad83bbd8905a284de4d23bf400dbf9fb2fed2562cbee5a9c10939f29f8c60a5be53c53da3629efe76bf44e4c3954a945459f735d45572e83b50513dc13867c720567fd78ec539e7d94f5558dc5a86da79b38049b0a46ae25a7e3af3ce640ffdf79bc7e91f1cdec5acff91184ca71afe8b7576ce493e33ffc549c4bad6d9f5039c4c581e407538eac773eff4d94ee17f3c350dcb2d73c184489aa5b440ad57dcde548f307d903d08b9b4cb6db68a5d4fcbd49a5a972705e09e6c59295c62bee7e82ca96d6093578eede4f7fbdb121ac6fa09e8fa9b47f675dc6c7336d8848dedc9fa107d971e456e9af6f5d0ef66b21ddc4eb6f52eeece21dde4bc26eff04d5ff327cddda37be59e9c2a1cd97d6995b0eb743ff66a5493d7cffed80a13841feef333f6feff18e514a591512fc550d6d21a27889cbd421df3a709bbff9f4bdc107de9fa98e0ce3a9c37f53cd75eacb4e5bc1d9bf31f373b7a4ca6723a971078e016943f29697b09f6abfc1c60e8fc4c201a9ab06cf60d2452c83b88423b904df74f425a9b4e1e6de1dd59d96779d72de7c2e984c2bccd6159c82dfa5ae7bc63e5a3d4b21d5ca054a71d753e7e583742f7e5bfecc80f6ef45ff53c16854ae0ab41c68e40232ecc8834a5f4556a85ce9f627fc7c80c759299a42d7ebd6714da29185a46ce4b91b56a4a09e88e0bbb0c5ce97549b5c9765a8874686c63445dea7a85d43ac5ddb979b4ca13b8dbf8db634a163fe3f432731da7a128716ba8d5bc29f0de4ffb15c74fc82fa126069abb8c95bd19df84497d833aeab72358d4193b664fbfd627a139374404ece9994e6f46054d1b4b538e778d6d15d7fbf5571cedece56362164793e58355366495aed8deea35463d4d44b30f451b46d4d6ab96acc3617adce015379564d6a5ff1a6ae4e8d2712a94422a99d90988206776055545173bd282c5e62b479d749afe9e2f356b0eeeaf36f9036665efdd642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b +public_key = 8e99fa62437ce84445f2f8fb495c9730fab393dc6f3b36bb2a63759a79ae28be62260d76a60852254dac1e04630ba766b5cf56341c6ac967b36e6934dc58cda166f1827b955807636129fe8a7d8ed88a71827af0e8ec948b9c7915566c70a7c15b7fc36ecc7a3cc644eae696022657c545d0a1fe3a8af5dfdfa432d9df5309a9f75e5b9c1d44efb34b8a5a84f1b8df90cbd3f18486b555d9f572bac8f1085f058a87fd48796824844563f61dbeef06978a03f3a8d68657c32d64af93e6638daf5237de004731d21be8992f83e51ca3db8af679da6fb0aaba1e75a2d283add699a798eebe946dfc6833d07ba5b9760a338768615b77ebaedc6a6a6937baeec35575776a4a791fec7751079c6683ba29faf8bbde99175b9629c44bc02e9cd89ae9f1089aa65e946e68d32a9c9dfd29bc4ca3b654f494990cc02bbb8e138db54ba3920ef98904fe71c27a5c0fb679c8e847750ff236e89915a534d97373351da9638da32084d7235ca0d81a636a35b9de6f8dee9a64a139e8d0dc6d4d7dd989168a163730fab8c78f6ea57a7dc16d8e3b792adee906f6c438ccd1a9429aa3d62c4ab38da5890188829beee6a7fe564a43a2e4f3bba48ef207b65e701995c9abf9d79ec86bd9844bff471eb5cecd934f7656f9dc25839d8d9432e395fd8582cda980369f46effd637b9771fa58530aadd7f173c85a8e64da69c8e67a910b5db9941bf13547815e0589327bd2002fb89bd4f00219652dea6ccd59883e39e27e2abe3787738c1f4d839a67e12e95d64989520737e3aa99c79fff2d4ff49256c45455cbda3ea5a10bf8cd56a21f2fb51c13f17aa387e25e631cfa445b2b77ed9dae028f8601a6eada8a8e62afe0500fba5064c4f0cf7cf2dc3353fc98f34bb948cfeec5235fba6caffb6bc6b2cd9a783ab8ef14c4922af8a3896bac07ae8ba98c117b3625fdeed0496a8c649a38a33fb679bb535a7d1a7dd28ca6c8bb8f5178e74f0f5db5d75cfa9119b595b863d0375a3eae73c64ad3d8d6da8e6e3cc18d64588890e3894a9bf4580714d3894e526ab84e27cabc8fa4cad6dbbde9b530180ed1778478b96e38fbd6be713a7e695358538bc4cb5a4fff63ebff178bb16ace5a295ca044d985f34267a3a931998b29a36935d3b13bfd631cd37777689ca0b43b9208afbab88ef886a8672b331224c66d6d86b9be5a8eb861070cdbe36dbf08f970cdec98ece9a19785eb69a6f58ffb6dce0530648d770dc63498e9b5d65acac6ae79d8946b2773d525b39c3755c071bef0c9f468ab3aa8b1a4884818eb888baaa1156bd70d733be887abf962c57ed7c53fc34edca8e549977d9a6f7eb77eb9974bb353896f8f615038f0f5a9f57cd9c28533f8b0fbc5c2b98658d67e4a636575a46e075aeefeafcfa51ad595bda42176ed81d95a9bedca1c037532ba7eebdd89962cf9765c443e4f8bf20767d2fd8615e85d0c08b0fb5d76e2a7e43259f83c1348706ea4d9d397816f4055e6d4322da510d4a686f9b490c74f2da782ac5fe57b0d991cfde9e093a50acdc00b8cee6ac6e1dfc4373c74da2f488e773fbe1289666206cba3bd96a479b2140c6aa40ebc449be3b6839447c4675baebe46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5 +public_key = 622de724795297af499158c8e1c5de4daddd65c8ae665d3932dca40e058e829fcec2a997d01fc8a22f7568cefa1c2ebb31e3e98c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397b9e33d99654e6c56e7465d9b98bdbe6f4c12e36c62c6db6b3fc9086a8eeb9b891a7d6f4573a33c393f74bb51d66d9232fe707e25ff23f36f6c6830ef38f53c8cb81ec5c27aebd2fbda53033ef827fdb88aa4b4d72a509e29cb1bfc8178dde9c60598e693bce999aabc56f11244e5246fd8e7869f62aa7b50b5e725ce3da2db59d5ba5302c772f3ce8210bd882ef32f744fec1704de019cad39c3b12c57c3519ca0b38366ac4353b133c3936fbe6ee47ecf76d286f6ca8ec7d90418aba0d9833f2fb46b86efa297ffb80972b65e809d0f775ced7c796636a2d6e9fc748b91df8e1f8dfffb0653e35dc8c3759178c39e435ee327b8ec7e7887b229e5a5dcd32c37a1148fc4d9186222bec66afcae8184559a2df01c8baaacec62bab984e18d433b9465e65afd998df8e9e9d90dbfc41753742cd77f0998c67254ee83d45f2d06c22899c2136362271b731f6ba3965b32e35e7463f6f7aedadae5644bb97dff7fc599acdef0ab2eee2e549a277ae8d2b9fc3a6dff6fa5e9ce76c0bcc5e4e8084c722fa321479338f59ece08a0ace3df0ad68f219e855d5980229d83398a6c0a63c70d3743679aec030fa69dd5f6ddb77e30b779c36ac25767d4ead94ddf1661a39bf624e733f3efae18467ce2d3d83b85d1751e390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae2cf9bdd6656cd75d9ba453ab1e5a32745f2ece82998ea9f4d5cc2dcd53ab79b89e1d7e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b20f378d93990cc8f80c2ea5d5ba8415c48ec27f880456f3a973e578ce663aaff978258cee0b6c51bbcfe307dce07cbafb7c58111cc7f209f3ab0f3d5beded2e3ea57e0469ad4f8b6fb88a97d957af2fbeb768c3cb7c9f02f583fa35e3db7c580d29869853e4e8b346a075d1d8a7fe31ab8ef5b983eaae5e8ffc624e0d41fe5f3570a6de09e57d617ad6297bb3f9d938f5655629bd6c4f6c4fa508e46f8cc05dfab7399f37ea75aef57ee7bf1b67aa978ba72f49137de28e743f28f95f533b708f3c59231bf3faba96ffb5c239c3fb30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a19eff59d9b58139e6257ff8f35f317534fcd1f432f90bd64a8b52d824349ecd75619eb2f8dfee2a899362157bf9f631287b90d6d8dfb56be469273f7999f436dd31b62982c4aae465fff7508e5f56f3b6f8c949bf1e388e0ee61f7d77f603ae5936f3e4259854afb90159344b14eaa29c8afd5d74bef8e95a2dfe0c57a762feb1aa65b1dcb66a18bbbbe13bfb2a4fa37d13c77c77b2bde758eb29d1f74c7d57d373a47737d7ef3998e35dcef7d983359b426fc7146ef6e90a807614d34e5fadd363d456b66f0da6445325dafbb67d67d9b359137c253df50c279a1c537ab06952e58f3f0947f199cf53d5c7ea7f7da1c49bedcac3a85feaac36beee671bf840a57f2a7c77b7bddcc81af82f1aec827dd80d8dfd619a6b6d68c7583d6c93a5b21bb8e85b1a46c7abd3c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4 +public_key = 657b941f466659fcc972dee74aa445965e848e8ae16b85ee5f5df2c9ffa4b325fa1b26a3096539cabdbd6a435ea1e33413ac4d605def5de8570ddeecd4bb9fac473328d555028df744efc8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b95723ddb064ddcb30bcec4a58b0607d931cfb32d28992c7d42788e854466e29cbab53a7c72ff557193d3a222dd6178edd2095bc04e993b8616f45416c3b998b01716af3b43a535f7a6beb7e270b34ec808ca00e9453ae660b83f963ba634f14378b179ea90e3708125cde31bae3e1d451a5643f526cb790a8d6e19ea725681fb539e9b05bda8bd4c48b3eb39da6e39e6be624663b6284de9f958c60e49cf4d90e6a486b695e1af9da0f0a3f97cfd90db3c81d354d0a40cbe11d74272ef3bbb7a49ea875ea7f7cc265e6a8a9e98362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b53e4c4c44f44c96f49bf9a8e7b85349d37adfe31f279fb7e7a49292f37c8f37267c835c24883d2ae89d4dccb7c6bb1ff7fffc323d1a6d3612a448085eda210449b7e15a4fd84a9a538b2d5844dc27dc9110ce382bc513e9ce8c469a01a548d1ce4853128a03a9bed369b353d4dd3b1af9d210ab6af23acd11dae377e493c774efad8b3756e807474d1d0e5862b3f65e7969f247c954955b4b0ce3fc53de43d2df63fbec6dabbbf5a8857a7f3bee7658c8399503d2ea9a38ba55423f345ffe4ce2d36c2c3dd087dcc5dd87edabf46e7f955eb9f6965748cb9e58351a938f7e4ac249ca5ca7dcfde48c0aeed51ba873d36a581e0fc50d9583109a79549fc5b32ba432454d46bcda66f3c64ae1498f44beb36e8d8254fb5aaa7bbd0ffc4cda8c0c5dfc62c09e45a75709ceb5b82ba4ef67e6c4986a36bd7b4ad5c3a505869fd34aec2d7caba59ff4bd3dd232382b275ed5933f42bc5ddf97d92ace5566bc5a190bf925cab467b74edf7b5b9124f318e2fd456245f2f0887ff13516d33f16637393c469ce1f776cf34f6c6577844cb3d4e0a92aba85ffb59979a7c33ea05efa2bac9872e60bf8a85553a3d4eecd5db2df106f632c91b8d1effa9b2734185283941ebcdfd788107c3d7738786d7cda0e7d4957d0be8488c5d6ddeeb83e3504fff923034a0637d563e18a18cbf9f48c36a65ce32ab6f6dcfc5a615e4416df76746673e510e86a117a27d6dd7a5bd48682e3c33739e27058adb23c0de35ce6158c99e59b88b147e2bcd5f09f7c0a414c3240abaf66cf4cfdb6857eca66bfc58e52472861bab1e03ce71efe1558db443a9bf799379af9ac979edd72f75bc7923816a189da5974ed948b8a709a8191cc9bf6dac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac4736d786ceb86a98a5dd733d3ecfb948de48f698c5a11782184760426ed6852ff68169c86e5dbe92d776833860267d4575177aac0b9d3e3e96a71d985e96de2f799f481be331ba346ebdc379dbe8342f3836d88fd5feedbf2985825c78330658baae89233bc76b27f127bc7a98e6c645df8da8bd857f77e57befc27669f97d3fa7eb653698af95097a32ac235a11887388265ecb3b46a75c865c2393964ddd108e52cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384 +public_key = eb9b77f9ce6dcf7f611a0fa8ccc8ee8cd4c5a20bee8fd3dce226bb45779f41073ff3fcd362cae5220fcf45d3a95874a552ce4c8b7fe437ef48ffbbc4ca3b4033e5defa49fdbad9c339745803f845736c30c03d95472f9ef52788ac2f3759cd349106fa13fb4ca53d7dc6b4c7fda5d3a80ead2177e387dbfcbd7f8ecff4641f4ef779d7d34cf7f0554a948b1fe751d462899dca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934f4e44a2fccfb2d35892c4cc2a845740d946aba4ffe77868d34c7a915d7be43748a366c4adda927e66611ad8cd025fa2c1bada93ad5694b6e3d36e0acd4579d5634fd2675f32de291efba1865f52b57a438c5dfcb854ea7b6a89c1d9ea9857c23aa383344f8b94ca5a524977e8fd77b56978328c18a8d382ebc967dd37e6136360a958d600dc3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347dacde8d437b3b065c121df6e9043d78b5838dfc7ce69ff44b32c5b4bcd4def068f58fa733e99a418176575fcfba0f78d4d5dfd67176db67e7023b57f8d26c637beef49c9f6d21bf77d36e3941c3e787bea9a4ce135993bcf2fa1de16434a69d2c10ed2993b65777399828ba5243da2f366f0362ea3c59b6007c3aa42de98a833fd28cd5f8f0f80c9076d54d5aebdfbc95c8cd6bdef450799f64109de2b774a2d98764d4fbcf00979953fb706da59bd84cde499f428cd586929c9995dc7d769ad9b3fec85b4d62b6fb2a1847454554224c4cc47898574fa66d147c4aedc59007fff49285db64e70508c89e6787a8ce6515cec673d4545970ca8ec486802933e31a8d0fbe46d5dce4c8363656dbcd600d895fe383fcbc3614fe334cbcda94c185b73db30cb5a56a9dd4cb37eb13859862f164f9816f5d78ac35feef0605cbd69e6410fbd51698e94418e6eebf8cc9bde53cda5bc2efbb00a7563a55856721f31ce1f873a9a56997ce74ae43b5c27fa1445bb40cb3dee09d61035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54c6d21d28d881d59d2458564acba149bdac36cb501cd8f42929d64fef4344ff6a88ad69610d533b2d943445c72c9f60b4c8a46a1c921c68f600d978c547db401bf412f73542ae3ba0349e66fa4025735cab74d2aad5ee09bde9b59ee5c49c66604e5244fa91c208c6b2ffbb02cce8c47a5aee366edbe3bae1f4ea8c4d5ddebaf2a20bf64a6b70dc6ae6c12e7e4dfb933b1f7039b788e7cd35df8993ff8692360dba466a81d35adada37eda436ff341f3a1c8ea1373ef11845a167449d9347dbd95a89725a56a855fb510a7fd274faf41a4a7856abd9688dd7c85433a868103679a8fbfbdfbadcb52cc141267e92efc1e67e62c6b4897dadd4a3d375c1c8bb87c5ae2cd8dc2b1d7e109d4e5b08d75ac96c925faeb083f2fa28ea83a9cba12f4c9fbadf06cb67e2787eba93fd3f53ac60b7b015df894546e759689c3ec65f8b885eda18e444afafd2a735b1c57c201aa4d273b1312f67e5a63abefbcae9eeb2d388343aefbe2436382eb9bd62146de0e446b7efbaf94dd57519edb145a646c733bf45f989938fde9dd3218a607739c60da6758bf448bf18a2273db08ad4d63548fe3bf86d176f5c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302 +public_key = 9ceeec903ae5a04ecb5395be18abeb7e98cc23658dccc7bf9a843a78bfa6c0af7bca4eb04f49e950d998c607a59b4933092ef00b38b24316db55e381c088e00da8497519ef3a0acb070ffbe30bec7d756d36f54200a367c109b13c04e0378ef31d6bdce9e5908776768777f09f57f6c64f77d0f8b0e05bb4ce5dbb5547a0115ec89abc4a352745316c8d85b3e87d68382ffd5dca6f94446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c30902fb8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf33f5cb16d638d7f3365bf7c8f3e240ef6cf996ff247cc31c844ae77754207bd3b497bb3283cc7e38664b2377207d9e1e3d8cfa05d96f25acbd04cbdafe612adcf713eef9cace95bd0f4cb057b0766aae7b533e61fd4d947947fa2d470bc37e5eb4ac50aec48066877b4456d4fafa5fed89de38a7fc7573fae5480bea823737e3275ea85d873378cb97d6f7be135da9472eabf5eabf0114952665cd2b6dd5af338b37de9f6e4c8f78efcfb7ff4d3cb7a90a3e5a026b5aae5da9cd4baf3318d59b9e323b2cf26ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91547af354b59328e4e1a724cbd8b3689efa335d8799960bde1e2f44edb361be5bf489e84086f4a9960fe0faa4d4082c4e6616ed3ef668fc155bce04916d9fb8fa46b77a4a9fa82c8c0ca5a5a5245884df5fdfdf30e75bf23a4e69464bc33fe5efb8ffaa9214b1ed546dd0eddad554aec80882ec27dc6ec447952d4170d738ef9341d6034920a7aec3b68fad0d527b38e2d88969c72d7f9bbef2464a4d774fdeae6f71d2836e584e55310a756ce4f49fa7474c4deca978a0653935b784da16d5ddf1eb678c1bc3eb55ecf6fa35bec9d3cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4253bd93d2ab40884c39a4abcbd1abe08c9ee72e18a84a288aac2982d113454335423158e68bb6b9d97494179bba1ec8760be59d0635eb94b4bab08fa6481c4a8f33b0fd3e64635452e6497f9933d8688352cbf44537d6e8000536f9d4ea6446eee27ff370aff7219b8b84a3984c649ea93fe1207c974f6c75760f7aeef57e496a58ce37e9096a58e2f3ee82844f4d674a4cd9cfcada79b0bdc63e634d2514ba4d96d4ccd4fb2eeb64691aaf247f7c93c4abe24f3c27b3b7acfdb649334760056e591c32ff9efa7547f3f7c93ef65f4c8f0f67db177e6e55620715688dddac71bfa90e133caec86945bc74d7faecb88479a37b45eae4993bc7d48e63e6bf66b9715591148c9a20a35413cf404bc6fc512b3800b9ae104453d95acfff1ddd3ae85b96e8d9263f796a13d39cbfe54f84afa4b4d2acb673b8799441bc505e836c3b558e20ffd57fa79154ee630e7fafd96aa4feacded59ffab33a559719b81d274ef1af773f4d5762ad36531f78df5ab3617cbd89d7543cfc7c6ad373b3ddb781dc78dd4bfafa34b6565979231681fffb8c62843dce1e686ea59407ef3cdf96aed95554e58df7c5b6976f65e5bd4db0e3b3ec567fe9f89b73c097ee1ff552ca04c33daa4a363794cc8cde05249b54efd460eaa8ae2e7787c8c9423a7eb81d58b5b8d81c8f454dd9ef77f8608e6dca003ea7c434f4543ae746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b +public_key = 8683354b3c3f035586b50b88c424df347ad5ada7ce4beaaa5f096614cc767af89ffccb95125bd0e8379efaf76ca48eae4886abee9f40bda4710dac62a82de705abd7921c770eaeca2e2d9338536c3a9b52393e3bce565fb96ebf8ad3a78f13db3f646b34347f1e2e5e8fce789e7dfd92a971fa4cfe893ad9cfa68968f96f206a7535766ed75334970bd61d8d36b0aa81c2d8d2fb7333cc6744ec93de4be56ef1e487447e409486c477cc4eea0d92d39e9f585ba2203fbc973acaf04fb4969746ab36e8631b6536fcf98b38f8ab04ef24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d28efe9ffa937ed5e94a3541e3fc9c696ed2f9a47faa077fecd688d607996e5b60c27e5e617994b94fb46574b87086a061488bb2445b357a38934b612c26e68e76f112756bfd764a4fcc5f7b1634f7ff8094464d610d46ee03b4541ce049bb3d18f783fcafac5bd36ecde662daed8e2a89cb755bd90dc7e75277941e5973d11dae08a4b4ca2faa99f47f657a49c3c8efcdb54c905a30114d5ed544bdda9942bc857b6d979f796c859e16f7a63ef543477ed89ec2adc95fdfac9d22de9750b8b5ddb95f02e7f1aa3d4099ba6b2ddda40c2aff9ece649b33e8acc93a5fbc52e3f4900bb44d20b7f5024fae5f3b77c18fdc781d4b74c78eb92ebd33ef60051c499b5ccdd9e7e6531e63557b5e4526acaf09a2beead49a4e88a5065b4a975b225e71eb28802468ecffa37d6289813773b29f2cdef5587f9ca8d49f548d2a0c3a5d7ec1693b5ec8c64ce0267fe06f5485dcc4b5553c5736a0d16f3cff2d596f984c014aac048dba9b68f57a993b1be3bd2cb9ac26aefb37bfc085443075fd93510a46cde5441ee3cc88ecfcd636a5ef7731109ecb21abb149ebf5424d772668fb54c5d306cab4b5356493dff0c138c64b4ab29378de02cfaeb369bd621d64fd8955b8adf22bd5997dd76bfbf5da2cdd39c2fe4f0469b623c53195a3b2ff068182d951dbbd5ffce9a6c8fab42886987b7999044ce2870965bd463980aa6b36ee3b5bf9c25b64920d7788a39ea98ebc30d3785784cf7e53ca9ae819d04f23706e3cc0b9bcdbd68ed8421df99ca3fdb2933cd91566aaa367372be6069a706be664e97ed7b34becf05360248c808faf50fcacaf9096715478463a3fa1c73fcc9a185eeb08583aa3d9259c567743995b0de4217be0878e5b851655d1fe4fcc4368282dacdfc36f368d6894177ea2144f6e28837cc887e66d874ddcaaf60a3580fcc7a6fe73328db1f23dfa0828f34547dcc5c46cd28a507ad846d1d9415af679d5cffee66dc6c2bf499d5b74aa2758da19de637e3343b3a8b14c68e415a3f196c2573c5e829ae6ceb5e4441d4f9cd899ad03c3b727774b48ae61db98feda4c1f0f9b57f89d1735381166b7056df15a09f220ca61a8a38e575abf2cfaa54d6e3031a9ba60275d23178ba553a3ee7e79aac44fb46d7e94cec57c7bad6854533844bf3d6a9b95a966f99e612239cf6cd4edf1a859afea9c0cec6d2679cd7d7ec2cf35edc9759666c871854ae012294022fabdec2f69b53d397f337b404e6e528748903ccb8b24c8fa38e97244c0ac4ad345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50 +public_key = b147b4695be2c57ee3104ef6f807e773e4643c2e47dfdfa7270ab360f6303ecd5b03b3e4bb776c4893e8696d69c3a4c91cd6f435f8f9a6a8621ef5cf8393e1a4278d7f453ea5484d32f94c2ea6f8f563fff93771dbfed6c8ac9cc80ad07e3d6b1da78464ad8226657680e5acaba6819543cd96194aa5973d4f7b8683be3a07e7a5194c91ec95a2d77ea26287e0a4c78aa107b3707942d0c78f3fbfb3a58b7833fcb0fd7785e349a2f10f7aff079b62a68e404f5122f7bc0a0b4c053a669609db67088f13abfa39f542d6439091e4c1a18f4734d8b6e5e6483f48ca738c39a5ccf017cd746cfa9c1899f97f5377d614acff2833cfefdabfddaa6d8df4221b73d546e0575c6d92af62a5e834abb63cf85fd7437b31b1e989ecd7416b2c4e7b08d8b5f8973006877f2d4a42774c94aeb394e885d07f7b80df86dfffb4c8d568457df19d3eb1b225aa08bcfee1da3922e935ea8eb3b6efc3d044a784bc965a68dd315fac491ddef6183b95bda870e65207ba802acdbd35bed443e57068aff080fff24da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1b5e8ffae87bedd8072e475895f7c3b9a5eb244ae9faedf93d9fb69faa7250bcf38e68e9c4afb2b733b1813ff37673907097a4cd65a9b396db4859312d59114ed7b39746c531f6ea697a69929b1b625b5ae1b809ce9a812de3ccb7d971ae8bd6beff3206691af6897f136cb451699e1ae9739e5fd60cc89dfd654a42da79b2c7cd66ee6853f39d6847b8beceefa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93ecfa3961e7427ae7af4e4d41528e4ced8de856b777eb35086fead142850798d3c2d76ac1d25c3f96d9aeeec4adbcb641375e6a2077cff5ce3748c5d1fe638688f688d944e0027a2f8c9af77b79352ea5523767cbde4577877af209de7e4ebf44e833e99dabd0fd7d824bc3c50a3827514d446a5c74406873cadb5c0cf570b4d6570c4f4727379e6cec39fce94a29a8aa249844bfafa079cec0f25a400d6badb8d731b0db87bb5a19325b4e79b78af0bbb2d5fc3db38ae552ca972c39273aee45448e15aa5fbf2a85e7806e51e1cae8516b056f6e4b80e5017f7ed54268aba9e9b7ecad9d196768d99651e6da334fc443c8ccd9064a420263a6863ef0e86cdc48776a3d44b4726916273a0d41dfde095526257bc5f6f46ddded815de907895f07a63f41a184ab7f4dd87148a336a33262a4bb18f6b417abcdf957f68737adee6821a5ee5348ac58814661765bb331f54a874c4a3c6745cf984529cfb9726ac3554e01523321aee69d0ea761425c0651372098eb330185b48ccf71b275dc024419d8761eb23801ec7d4f73f6f162656713acc2915a1a6f877a583c8372cc391ebcf2dcff873c5bd22c58c8074dcce759b2c09b368ab4ab504c613493479b7725a18811847f1409f37734577af09c4be0b3fe07ab78c8efb0693d60be76920cc5fc56993e56c7b46a543ad675b2d13357d0d89124fde0d39f268768b847dc66ce757af29ebb703cb584fe13acb8f036e8eac98693224abccfad4e7c3e57c03b27a3cc4f0b880dc4877ac45d77c2cfd5584b97136ed2c4bb767c759088f7ad747df4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76 +public_key = c0d8e22865d31d7bb0ca735042bb43b8ec6ee23d61046acab9b873b145e9c22678adefb5a09faa4f8f69845bede5e3426d66c0451a8d78dcd7e729d33a536c2bf4c7397c64c6478be504fb074e3b8b54e11ad9742b9bd2081e446d63cdd64490c19e7557b884ec4f9b05dbc0df7acec13fadbba55d3f1d4f7bf391ccaf8b904ad7712a8da4aea92f5682cd75da628573854d32a307704fe77af738696e974181a85c5daec14f7546f97e37021e588358dbe2cc686625a37c7ff92367b5e1546f4189592639cda4dcf0974c6a88cd377d15b8ec5c84b80f33b658d0b79c62e536553b53f6363fc6bc2b726a7dcc58cbf0f1cdbd35c3e7d9b66b327bbeb5175d971e985ad799ecbe9ad0587aeb856c288464d993f56649827de9af0fc79afa1aa5818cd6d3447a25ab3eb8248167ba60a456fed48cd07107b1eecb630ac4707b837f25df6da46bcda77c4b6ed5b4118b79294744788b9a9d2eb168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb861536f408bef5c2995e89ba8ab99643624c7d557a984011474586c357f1c7552fdbb069336fe85bb913d40f48c4a122ee3517d55f37e6d37ea6a6ffa48f40584914c4738397430d65757ff98aad345681d77da8a41747f8364a493bdca944b1879b124e66cc3b8293937231f57c2e78f8f1c7794eccbf0368ce359f1a2ebb01f3fa92255a676e77c39564b575aa5d1f9c7d1388226d636f50efd5636b2e207e3c59ca583b8e1bdfa56449cd13cd8f0f21a36c345eaec4cfc701ef43ff47bf27e81ecac752108c43a97729c6b947237dfcef5a7c08665f7aa9faa55b152163e8446c1bef5d8229fb5eceab269fce3e7879da3768bbeecda104c5e9496c63ea5d7881a4c8e758211076653f369e58b59bd7cae5b9a64773cfa853f9e43f492fecabbb575e4cbf7d970f361e6d3c65a5d65f6cc668c64bae7d587fa8bbad139e36d5c9b6f757a51e653d2754aa0e35307845a55c8d086d5a0e873d2d306b9ee1550419b495e4f4f702ad9832d897fc47333d5a1e994c8585ad0d7a8d4e4989a1d0dfecfaadac2ac52bf1d90bb149778235ff619e075a5360ded95cc7d5c81e3be126984f51aa47109e0f99cf1d3989fd936502a9afb38c4a2320a618df751c7099d1063495a6a5936c744a094cc20feb04ba8b56b0464e95fbbe16e76034cbf5239cd2c687fadcfcd383f9adbec3a77b4842aec40bfadfe8af72fa68d5345668408cc7b6083d9749e921e765e4d86d25fd5c78e246da268a4dc2e446f2cc3273861d218edaadcfcc775631927b709ecefa8993b1f9f61969dc08a4d342219682af351496bfe0aac74786c897fbbe96abb609f2e6998cfc7b283bfefca4b1f3beb6e98991bc3f4254feab7e6ee4d13c44dc93295a75f6145bf2d4b8f1a13e09be7d38ef4b170ce5f44ca6ea45eeb695ddeb20c46c11cbb993ded705a6cf4f4b792aaae80d97a6ab830576aa65124f793fa7da0b8bedd877217d54897375ec285849a89f68babace95e76842c601ef8c741bfec2c63f1437af1cb968ecb64e0e91e912dbd96307e33231fe5165359089e4b86e9411d27cf164b580528768ad37b584dddc30e557cbda142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83 +public_key = 80b3b92647a1dbec6bb883a4b226de4dcc84c89c6adbd955cc055933e3f38f3f5fa826acef899a555873a5b9c18a1e78453dfc65f4deacad7d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885661bed3d03fe1be5dcc50757c62f7928c3fe0c567872e66bcb68e28b15c86977e0a7b33bfda469128996f6979f896b93d239e0383c90d0d877a56b4b7c77c53ca9e28719c2995497dd36877276a25fa8b74a4947e233f15b3e4a075585da457dabfe7c428ee363a5defa0e3a8ad95f9e07635546485a3568ab6dfd6093f1061a6999057e705c46b679e183874fa9ea38bc49ff718c99ddbba59a1865a145f07b1dd58b4d8b6d6e772ce777456c92b28a51cf8f3f7524a26639ac64aa49d79d3cc3bfb5b60b59643bc95033d362caba6abb5ba4f696443eb1f72d99cf385be3f5b43c2b84030d6bb3386f5a16354e55e18f0b759c3363ac4d69ec2c4c15cac4e08af4fbbdc682548338de57e6caf13c88d1dc6ada7045a442b4939e7ee469746e9da665e2f9e0b51c56b78ad35a0db255adf16c0bb53e14e73b3bc454a7a17d87f83fef78e7e3d4974de480c8c1af6b3e1ddaf13b174f968c8a45a3ba2044bddb1492bfffaf610b4ed258eae18f3df63f82ba7750fbc7a764db58e3789ccaea778083c27feed1e3c75be5486249f9818a18d47f97447773c7dec3ba7c59aecb5778a09cb7f128fb2e1ad1c28fa1bd13ab7e7faf97f96f5656d7a9a970b35a6ae0ff75c36cf2c2444ad6e997d92ec065ea490819d0e766c0079b7acae7bc7cb3b3140e656fd39592edbfec2c33f06addd633bba463781f1c519eadf342cce2bd16c1ac93d5ea9769e499d73297784ee45f9abf48670749c72838607defc85ceffb298bcc447537785226bb5de81fb7bedd4a0ce392279e9106fd6ecf6bcddb0cb5ec3b5505b5a16abd5481bf587ce4934d3bf32a44a66849f0a81a6038c59497c9b47faa62f50fe30b15c3616e6e6573bcc6af3a88887b51dea7dbaa429ccdda9f87b63829b1b74e922435d16c979db67eba0f2ae39267bb362c68f47689715cad6636402049c2b5d6e6c42ecba6e43c1c1a48a1ee41cf3a71c0099bd183a5c0e59bcaaaffb637c1b534cb6687493eac495acc7c5fcc4898b5fe44094fb1c7d14a15c88f1ea9e7244ee54cfd5b16708c233ed378592695d1631af96d63c094f563f0e559c59453acfd5a948ffaed5ac0c3cc6a0be7890f8c3191677c2107dd8153ced4efbd96a4bfddef7f86c8d9d8bbd4dfaa8380ed30f52db846df3c78cc82a2d7c440897c91c3b726b4622445899df7fbfa263b93c3cceaa8500b5bdc250d46388bf5bd98b5901aa67028da2a9bf7df4f4f4e8d4a68dca2e044430e8deb67e9b4af33c60fc54bb3a94a8b96d4fa5882a50ea5647b8dfccfd878e4b40a4e36bd4b5bc24f88464cfe88fdcdf6d9497fdb5f43ff6d2f9ca2e048a757a59b441cfc575ff32f7e4d11fba959ab9ac63ef6bf689864ac98ccdea633baa3ecf75c09c4c6878994cdcb3e882798eb0faeaf39915dcbcec0efba14f6f0f53b3d83ab58bbf99509033db9abdacbbcf9fb4674c95cb94a8fac399cf771a8ab6eaece9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b +public_key = 04bfda0347d40adab8bd449e0beaa93b07512485ba34ff91af1a44540bd04af4a3dd3ad9f6454d7304d0944674a68d55116eba5f98f17aa57c1074ddc1a97397fe38c1b3fcf41bdbd9286f88d4d8809d84aa1efd248c63effcd72d77ab0e73671aaf3a913b7b8c6faaa5bb40be97cbbc2cf9eebf83c776aebabd32e3cf691aec9ce8a6e7b85bd9712b40e2c7e3e566c715edbaa75957d6ba5062ba76471357252b72ac66ba98fed921daf314af32a6ba908dfae3645b5617938381fbcd749ae1f61cbcb615c459dd56f0d55a449c4f544c66744ffef116d10dfe39d1c586aed5a5dd3edfff7a60f3138c34b4f44398b692c567ade5beb56ceedcfcbd93183e1fddc2aff5bdab67b51e39a58bdb8388d67cc1fcdd7313b7ec8a56cf3c9b742e4c4aeae4592794749b6834e9b81a2ba47df9f9e9ac7856b5654904e039fd784cadcdfc195952e3e5532fbceacade3c233ff8ee9a669ff4382e7a438fef9c16dac2cbb9c4e6bfa9fc3014d8add7b4bdf88f914245e1f9874a08ed6a82b6369fe349e08333c7f56b7b7b808a0b4e888a9579aafdf4873944cc43eb958b1508c66e67e268e79a69178793e7a4d53d507f1f59d01c86f999c1687fcfb7b4b3311e4ff55a51ee64d7bce95a6d27875b9e77352dc24f8734b40f3e9db777819ca2163c431de46f22f38398d46ee45fb815b6b07e2af42c0ea4230b59ea8c7b0c3c3dbe2b7c77b4c86076ddaa04c452e391c81d722c67bc073fc0720cef5296a2e70932d4d38efbb96bd636bb4136da7cff7cf5f7ece47d8e6884cf0b8584adc3cd3b5c5ee20d3a1383e70457fa203c8f9b49534309bf2c6dcc3e2448e02b5a46d889ffd78fbf8ffa70aafd5b5c8a7e8d5bcff44052c553cba9dad026d79bd87db7573eb1d431d1e549edc8ab57adbf52999f32555e8fffb0328fbd8e9efcca638055a73b548c8b433afa7d4a6a074aa212e5d363de382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1eedd4f8f8cb7af4c947b0ff5e0edaf6b4fc7b76ef0bace8abf9e61d88cc5c488dfd754d3cd177f727df81884a11cf686f005f4f39cb7ad39b781fe3a8ee83c0d646f9d85babec3d6d53a7df53ab00b6aeaa9dfe5914a48222940fffedd1939ba5c9361779dcae113a59eed71c969436b3771fd5db2f4aa641a4c852a2f380b5fdfcdfccb828e6f4b474a2bbf93a4d97b2b38dcef13e148ea7e4cacddb7e7cd0f5db203a6b7519c3cbd8d62c9c6db8c8ecd956463b828dc67f34be4868e3ba94ba01ff6da0de1d9ec5ef0bb62c865c807184b975f6d9427daf9474bbd2dd530f7c77e46b98c2aa4209fa48e9df7c855c7f84684389bcc8e7c67165af04bc5c0c918f8faa439fcaf35b70fd885cc8ef5cd90a708bfbcef6e1933886cc96ad9b4562b1e9d4c66589c85bf0e55606896f06744e42d53fc1b13fe0aa93ee383ef069a8cc069a03b95a8ab873b448ad4ead3a32bf3d54af834882bcc5827e2be18539c8d5577f5dff5d982c99cdb0dfccc96a4c6439f81068c8429997dc17a6601fd736b8453e3d77636faa8d0ca89f9193bb358e9cb2ee7ea368ea33e98ef1e345d6e3993fcd52a9f954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b +public_key = 611ba36d3a65c1de7cb22b7f3a78fb593595b1c682d62ea16de6f1a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf20ebec273bca5e6d6a5e76fdc183176af33c93373e956580b6ffbaeeffd97e7e19acea7b4149e652686eda541e79e87a2abb68f89ae959f443547cfde7b5d609b4836aeed154c33e59f48c4cbb244acbf03e93e52f7eed87a75cbc43c405d5423ceac32dde4e93dd9d5be3bf2cb7dab16896b4fdfe7cd476f37767ccccd8095ddc94b410b983fbbcb484edd9b44b8e7fd95686106c710d983cd2bbc11dc4ae69d91a50ea6941bc70424fc792c407f85f4eeeea71b7f6e30afeb0626768307c31dab514a783febd67b50e9347adfc7d1787142f591607b7a5626a718e5d2b37a6f5b8766e8175c6fff76935ae2ad2ed7aa33628415e3d3f5c0214fae691e81dcab30f79ed389ebd7c30ae890345e796d31e3196bcd0ec22cdd64b2f9c439d7b7a7b763333faaa4d88e0288cdb8aed49b8a8c64883637098def7c88fbcb974554af0f3c51c70a758186f1598ef2786976655f87171fd93d6949e2dd78691537d9e7d30b36926147aff825ecfcbfd2c03647962ffd1d748a18289cdb33982a0db38ef9aaa6eedd146985c757ce5c08fbe1af489e1cd0c83550d455a03fc885dc7a5ebce7e529ecb0ca13ce1269e86fabdceb4b90789aca086fc8bfed637818d1ce365540f440b0bad1291d3ae0f5b4a5d9b98ff3aec5793e90dd46a8ee5b517c5c4174e05e87c593ebe9b85792b6d7d5e615c4d95c38bc4bab503d737b3df41b3e89eb38865c6b60f644edfba3e626f7f9ce39313f2ff68796fbced934ccf8841183dfd066be831542abc5b15a1cb2d4fdaeacf9d4cc4e9754d9a5cfa35d72e570c8d3b0bde5a5b29fd1f14cca3e3564c16769758afdaa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436be3ef82d6a32434e7b373eec84b75f398e51f097e86c0cd2e59383e92e8039ebe5db6de20baec5489743bd4f335a774f8494a4244acb6677b22a56f24df7bdd8b9f92ae58e0703d78cd975abc5ee4473e172535e52d9e0b48748a29dc50d877903a4c7b9f4b18993669d254ef576d58528a1584f8111d43d360ab54343adeccfa36377f0f2edc8ccfcb0fc3b71b55353c278f9474d8cad27efb81ecf0b3ab561ba6722647acee4b8dbfdaee2c433536d9dc61754994eadac54adfd43e9efd7e5de9e7ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a55133da3366edf55733ca4f3a6329aa0830894e07ad5ee578c45c3e180dd7d637e8a994fced5f49710f7b1584eba5b16f98c65db96bc6fdb0561936f40fbfd9013efcb49c66869ef7ea318aaad5dbf882c5bb8e674381a96645b7a7dfa93630e933d3e955e24912e4365290f7b39f74a909aa5ef4653cc23c5e448be709ed88fe3f2fcbe779bf5fad71dd5c2f57241a3fea3b435c47a39e7ed477b989c00bd5ea71ba671d8a37dc64d372e6ccecbe4e6dc7420c362926b555598b92f6a780624f3a4cc8961d57733a8ffb8c78573c35584185fee9deea674a7fead60095e7b43dea45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f +public_key = db1ae38c9442fd3a7580e68eed1ed77e3e525465babe09d2806363a2d664ef9ce908b3d491e336e28bdf879dac71d3dadb145806ae5fc654ab8a8f565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a21fff4e446e977c7ec694a88e535ff608cac97e97dd7d8da5beedd6278eb5726f269f7b8d91faf04aff6ce2a7930e43008cdb3ec6a4cdb3897ee85796d15ecb053881e1b9706a572ccc75d0ef32f937edc40db45548f4f1a45ffefd979a42de24b9456aa1d6367ec6a50db6fe1bd57fdcbd0a57df8c0d6a638bb7f2139ca6df68f014c4e1e0b796708693549e2b5d67edd4b77c71cd67aa76d174cced6c7a901c6573718f276188cffe28bcfbaf604447e68d490c10eedd22b8c352cfd63e7a01ee460bd4d8e174bc4a6dbd2359fc6eee4ff5d95f44ec883b1b49b8e3584f27835f21b6b2f6d60e077ef289771d134e68e196edadceaba26cecaed9fe7367f46893c2ea3677caa3005e34e7236d8a3b64a3b987289a5fdd695a82de89b9034390355c5e33546eb833f602cb9325cd95bb4cf67cd5fa0ab98d69bbdd0fe55c3169f3effa576ade724b678fb18db6703f340ab8f0198cb43176f6ffc93fb7df748d591f1bfacb9aa67a8d8b15c37e40d4fdb0fed40e747d77a8c9fd7bfddcb865ff51c41808757b0ca750d6dfa357bec7e9fef1b08d5ae2b337819c5ea89542e079045c887ba6550e5fd5693f5c70134f4d38ae7e229466acd538ce69a1f2cef121784e3c3537424bbc4d73cf1a685f04af4c4ba8fd603b329dfa080afb714eceeed17693727732ec7be2c0fc0614caf3e4fb22216eddcd758a0674133e6cfc546ff855b717695acdba7eaaf1632079d606c1c42238856d757b5d71dbd654f7f04c97abe1bc6b0185116cbbb2ddaf8b5d7a9afffd5dbd37e92bb36311c8936d958aa1744ca67332b7ddd8d7e9377273c80cdd29f27c75817746f1d58dd196de72bde440f682ebfeb4fcebeca3cbdf79d509573959e8e6cf50ad44dfded6a4ac477e3bfea75732678aea7cda5401c623edff5c7a9a7ae6a572f73838728e913cc71b9379a5a2bbdc45773c7bee67fe756e13731f58ff6bc6783324efb9a4f8b08cfe22b2b9dc87bd1c6fd90ff73ffa83b598863c0b436f3549ca831f66bdbbbb1d4747d56a97dcef9c81766a3da0d43c1a99ce5f8e105f9e13043342a539de446a7c5f9c4b46a8cadec388fbb8bcb5f7d90a56c65afd0cb2a7f9696e1945de4f9a7b6fa03d25bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e3587e94727f118eaa02cd95f7137c93f2e59d9389607d3d11a7636366da97df950b13f9259cde26c7bc10f4d81ce46b7c8bdaf085fb038386e9a0afe0a7543d85ab909376b619cda2d33875d264b76a4e430f8ec4893ff4337d160176ed5938493ad6cc08392237caa8487abd3c8301a1ddbb677e7851d9c7bc4c2a046fa5c6ef2e72daba61ec49cb4fd7519eb3b1abaad9b8162ccf7f28fae310872e789cf05f6c949598c41c3b73a1a9cc18d8e68f95c8ad839301fef77c79618685db20bee04a9a8acb8441ccc764aa3b191736f5a24ae32cf342849dc1d2fc6a615f664db63b94960a433584036c05e13ea088f3a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002 +public_key = 36adc8ea287462d8cf894ecdca0e67976dde61e89eff77fe87c667f453c8cdde48b94c9a9a3765649ccc6e2cd5e545d219dd91783b6c7e4958a18d7e73e9839a9fc8c36a87891b7ce5e7e22e38b5cdd745ffced590cf827b98fdf77cb5653f3746855392247b0555f7ee96fabd9ea557c431e55b81d24bec1a94992ef540e07338fa944d25be7ed4e693eec8f24a0c53083df457d8d33aa4651b2b30f85a9bd817dd1c1e6760ef40a20d9dacfab21e6dd36426a6dc9c3dfc05cd171fba91da51bd6adf7ef9b236feb3b274e747ab8a380b42c16d357cff59548cb80788cb41da4c7d3c4b950e925588920eff55177f40f7bd92c23f979a0dd49b74cbd549b2c053a71d4641071a3a95a460b2b3a8adb7f71a3f67de555e6ce87986bcd6e647c4b7967cdbf5d83c4b99a1b44b5df58959c48beacad8196d8fd4046ea1cd9a294e6c6a97a1067cd650ca619d14a05635fd38539f1c2676b69cc5360f487389648fe596783baad0d7627cc6ab2da5b67894e0b77f85841a323e04d038ff5e103b38b07672258e86c969b0476eac6b2753c64f9eeda389599b78e856d8dea89556a9510627b29e13b1714ae442158561db8f435bbd6234a4216e8985dc4f72fda5f15762fa26d84f178e0e76bfc9ec5c35fb52e533d1e78d9cbb287d42b7591828afe605cfcc93c337bab78b65f37b075a8cfd8c49ce5087f8f600655234fa99f6987da89d4ef51ae599867d5686dae1e7d0079f5ade77e57518f89f137def9b9714f4cb73bde7ee6a6325f9418f4adea3a8762c55987ac4d6dd9a6d248a33ebff64774aaff70dd707f37bc30d41d4ae70e084d7792a43c64d7fb47ffccb065b74ccea54f86af907f56d288fef7f5a6fd85e82477483f778d5388728c4565467a9bb4fe6da2d89bc1c742b2db03bc5f6b73573cdd9eaa9ed85f1eccd1876f80e89ebd1e43d4843a441ed50e2967dabef6686dcfd3205e3332cac82095ab10d51340f3e75c9c92b0388bc9bf822b8ff93fc3520a7fe2e1ad62a38893119fbfa8758f35e895c74e187deb40f6a332d03d98cbf4381eae33cf4dd356ea7d87a93e80f472e49ad91dcd13c936b02a96c4dee4c2b23ac79869c6d139c8d85b58eaf7c6eb4c4250bc3ddaa56dbbbbffaf452c19d74e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779dc9f453f7aaa4e58401cbc6f47e8a346fd13e1383b53ff5731e8878c99289c9eb02e9f9dcad6c6deb6f4c3bd459f86d04fc8d287b6a677be7e45997027568bf7bcca05c3d395ce557873711174242ca50cfb3dbb3e7e5d25dd807cc5ff1049ce82dbe3c46dfebccb61de7f44f4352b655a517485ab13b413983cc089749ad7e44312966b2c67ad60d96bc176142858882fd9e3a075f8fa6bf639ae3af67fba026a173bf3318bdea999c8c1ef478422cbfaa9dff99ff856bd6a11f8584c63f80787ec19d5eea2a0dc5a57c9b8e44b4c07b3be3477baa738ab2d4d7653a309d7a82cfc6b86a1b59ae1f51e008598e453e04e3306c1877dd7d3869eaf5a9c9efed8daaf403dc4d0a83e2daaac73990f05a9002d6ada14d9450454291e37112a9ad97147cc89999dc89a30d8d9757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e +public_key = e4749bcd8577d51ae0245fb86a5dfefde59f5fb54bbef9e9e7d4a8bb8cc40fb8c72414d1123e52bb7f7cecfc8e4c8e7c5d537df15d902cdd3df866317006a2aef59cac269813a47fd337a0c5b694f5bd80f21dd89255614634a2b0cbeecbcc3f1d84cdfc3d54fa749736e531c2e673726d79cf45c89b444b7e9fed892c7ec39a74d39b815c2b9981ca47f5e5684044effadf3fc887f85f9b90fc78bea1b9c5c647ac53dd66ad7b8ca2bad1e17f9fa22c39d9c3c6cd833c6abcd61abbec1ee6819d3af45997b8580a9e174de12cc6b62c4952215a32822ee676ff5a10dadc32bc68c7bc920bfbc7bce8fee0ee30b0434afa29b2b9e9dac40ee53b5664e5f5e984c5fd9764397955d7d92cb257ae520078972b843ff3dbc67376d2f69bf89e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a46aea62e0b749fee4a39feea094bae60a38c84079d81aa65589fe3877ea0fa186a727457d45ea8a45b6fe05369f8be58de844e321e7ddc47af9ff5f075c6acd5f93a31c38ec706d9009e96c866fe037ea35fb7f65a56b24b03ed6b7f7377deab407dd57344fe60884f41d355b2336e464b94554b7c1096e4c3394fbd66ea2e74ba7045c0d84d328789d1e4f8a95d4ece9fd7f013d5efa93b5c0b3c3b0a8c90ce0960f61da9f6a453b9cdd12f8cf43045db8a4b6143ab5adc7aaa6f3533e33dc3062b7caa33b1e9a3bfda7bbffef8341bdda33bbf72bada717a4790f4c99cf53dbf114b628558e0eab7af583afea327a599c490e25795cc5c42219771391b33df4c7fc025f4c4d5f0eb4559c2ea8c38ab5cfe37d35c75624876fc1e969ef478a2d34e9ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2a4eb89c8d3ed1c7d8de65f65af9d8e7bc2020b723d49e987f83db0bc35e96aae7b2772b47e59a3257ead2775331e9cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352ccad74bc57e4dfbd9f9ce8e625df782df9eefbd3d882c45631e96e35c9b53f77cc0d268722ba5eb858a1df7e9a88fcf40ebff9cd7766baaf37642ce278ddd6a677fbf61ab5dab4c223b7381fd3c16704cf7a2db2f22fe0c969b6b47ae52c7f598de4aac1665d72a45bf51370df6e559f93d81dcb6aa49339e489968d8d49865dafc467c8abfdc6c1c9d85699b801c75eacd3e42be38de6f6a64ad6708d4f6eadce3b09d8bea819bdc31df58e3ea8d103d9d0a7470dd35161379191576a03c8ed70ec58565ca7c4a6bb333338d91e3d70f5bef45b68369e7e18cf945a06cbb80ff35685f52f45e594bd6a6dc5d4b6e67c6e887640bd6879187c5063d29724b3487f81cc5c5294b36b650efb08084eea098489d5cad338a0cfb6e231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b23da103d6f44a17870b85d23f1de4e6d8433ae5cd2b145bfe253a8bba300b6465fdef77e2fabe36d6c8112887cb0a6daea4a54e258cf99d71e407594eeebf1f4aa2bec5d263dc5d5fd7f9b73f957375b5ce6373d9b93211a66a29736a6ee6e6ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a104d32e6c3bb4eff94c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b +public_key = e274e1e0cb6648d36c6236468793848aa4b7f56ed378eda24bdccb712bc98dcfeceaccd81023f8d4dd32cfe9c82e2e372924c69ab5a402e9b3d88c87e9bc5c90335e5bcf31a1b87ea4cf527c8f445d7c8597ceda60a6e6e4da431c9593b92aeaa22afe436a359a7a5902adfa6c5e6d562363bf9589060eaf4c5946626ace3f276af8966709cbb9b666b9853ed2f3077978e4872307ac65fae1002cbe4eddbb83677419b89c9e0c9847fa6441c86b8c7de663f4d35793ed1b4cf1b4a8985ee5de547cf917f332d4acb59bd64d9be88efba8e362458b8d868da7ec516ea9c808af9c5e5e38588e30217fc1f3295da2559003e4f65cb330f43ac5b774562c28fbe83636fa034bdbc3cb25ab6c8d2ec69b87332a4fe533a788287a40c1659f457c5e6e15456da54a7febe8c8caf46447606f2aa340a48b4fc667d7e67efec47911ed5c3da4463b7535966882181e530835357b6a8ec62a3e7817c508c79754063f721d362be73416a4653344ecde577c17a75b3316ac59575eb2ae575fdde04ee77f70a4ee91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797e08f8f0cbd821ea69bd9c43ac0fe91d0775fb64b8694c74f13f3600fd3e5f1bc5cbdacdb33f9928247e4759747d0fcdd924cf1c93bae5c37be8c3b9c8ed9b476dc3baadeee33b62350a695d799b52743d5158c015cc609e99ec87f9ba036e6ed2d3a1c14aabf02deb4c4fad5c4791658ebef02be1b9496819ab76a428c0f5b8a69ecbf4fb5b3408eec22f3df0341575c7098e63379406c9b60b7ae734ce71683be7777e9db5acbd2ac6ac4b97aa0a3c8c168a5ab399d10b0eb4de0e829ee4a402e54e634af29a94cf97fdef72ec4055ce3335b89bd6f9ee965bc3259f4c028b433074c9705ac4ca2682fb1b385f058d5755e5319397754cac9f68cb711ff883af4243dec3f134fcabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a584a3eed831abc2c86834be35bc46ddcc455f2bf9aca86988aaf68dbf45a5ff708ea2f2ede163356b8b5f486f772204bbbbc19befc73e434fd81e855657adf88b4bf7c1b9fd9ecfbaa30b8fb34eb7230efbe60534e306f5c0ae477826a9e75b7c5afdf398525358cfdad128ce5925e33a32a9add47a7237da98fa4f807fc59f35fde14365a758c534f289160a65cfb34619c7c9b2aafd83cc699f554bd64586dcf37960568e711e6d7235c94492dcc294e6ac86e498d8b54193a8cac8b815d8be9a22bd2a6d5a737c4984f3a888c0b9e405eb95ed9430327642a18f78723fe94d6c26b298b77554e802f37ac286f429f66580697fca3e6ed1e76c4d763b194c52d79b25604974c1bc89966db720947027d9797d5e8349ea268853b9ff3aa277c707906be0b078fd76e9051ee4b48bc73f877bee69a3ebdabbb8c2e98d05eb14b2cc9abe673cab8d3b419be1c34b6342cfe84efd1325fb557a87ac4fb55c5c86ccbba99559fcf960479b044b3d6233317677c78a453d5ef47ecdab3fc3ddc3d3ad564d4e00a995c507d597e498cf0897b507ab35e4587e2b8750313d3dc2ca8cec4eae2a9725085c1214dc8d0dbf0ace46f1936725bcabd61ddb880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9 +public_key = fb36faaaad31e59d84a71f7b851da5a46cbcabe6b1906d7c97d4af6c6a598a089bb41ce999de6cd307895035b15effc34b0cd6f634813eec780c96b83fab557075cde3b64eae6ba98b75e06f7f9b82eeec9274d4ea9e64bac5b546997d2a94ff6aa9ce1f6bb7ab7551a06a364aeecaf797fac675cb8a8ea124dad5a318bffaaf348548f1a3036a874d4b0f056491a5b20bed9deecef3df8b4e9ec6e2a11fd7c6ccbc580373b1afefe293ef517ed340865232d6d660655184d8a0867a47811b88bcdc4e6dec5874839919188f6384d588ba97405bb1ff39f5c1553189dde37336948f88d9dbb96d30aeda9c0aa95d59f67e543057976e3dc7346cdc7560e68911b8829d37bd0fcfddd6efb0eb1538a98a76a68798b5469f9dca82a08648a2eae3becea9b52a7b6f345626bb691aeccd14fcf0f2cf52b40bf695474b2dfadedda47b87cb51f13dd72d489a2e79cfcfaae2b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a02aeeca5cfaf7d739d65e7e37bc5e8c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee69dd1ad93852885db82eb85e4d61ddae327179acdbfc329416b23234572a0eb3f64afcda36aa66be7035f449af2b40479e957d4dd28f053989d5d1d9cfcf8a8cc0c04aa59f4be9a98777f814a18a0753a728d264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657267de5f68a8c888cf3205a665503dd51084925167bb75c98b9af5b7579bdf40a912375e64814794bebdb798f4fe9066cc63473496ab9cfad6248d883d1846fc8084d5afd5277aa3eec0c3186d68bdceb6c240cd0128a6bc146e467b861ac0f5309d8f183233c37b35e8bfeb46443ecbe7cc3974a48a9fde5a59e677567472f263e31188966eb55625e819c05f872053936abb0d0a48e99357e5593d1dd8e57a8a785331f828269786919a8f913fe17f9b692ba8efaebb602e83bd4b7516064e500779d1907b1169e70dea870e6f57f5239f22e85b178dab32f897bf465e0ebdd84887566942656357b789667d756bbe614994f982841a525c8ec63ccc8e4575efd3be2f5cf975d5ade35ffa4f8dfcff664f6fa8c3379802529d4a9135abcd5d9db15a49fe4c6d57b41bb6383b3483ca5f5ce1174ef9eaa423c0c3254b5d8d53e9dff8fe6817dcc8c87eed4ed6ce74c93240947a8dab87d889f9ad894f47f43b35f591543f4e103b73d7d83725ddec00d7bb5459ee084be939ae8d055af7cc7aa98fbb88a156849765936f7f73bc385a1bca94a74368168cf26d8806c89d1efef359c8694b5439f1f8fc0a699fe4a68c4858a9a01be496e177d1efb57ebacdae48fb56626595683f30903cc19c79714364cc5ced8928f3536ffecbcd45c90d471e684af20ef43e925c848565a1989637f86e4ca0daf1bea9049b78e080dda50ac800e07f961ffd9c29fa4aa0b90119d987cfe5a2dc6e65516ad0238a40b0bb233a365bcffbab206dfeb8a54771a8d8f5f79e284d298563aa2868e2efebe582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc365acd3d3734dbff084d78fd9dee76b60a6ff21fdfc1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91 +public_key = 5226aa8edabd5a4a5a7cf6633a394b756ab38bc652eccebdb728c74ed3e6d039ac983be18f1aaeffcd4e48448d4507fc329f89691a93a30f83c3dbefeca9f364ca832263321087d4d349df72ee883b46bc303eb4242744e0847e72d5645586ad0b9cdfe48ac04b0d3045bcfd220eb52c8ced494673bea69766a5adcb38ce3a97820957eb5e7d95a82da4c1a7ed94a7d8850ef0a90c5c8c8dd9e3ee769b48f004c93a2e9e87b249f9da4e468444cdde233db389e656c860705b714e3aaf0779f1458b8ddde6ee09ac461e96a1b1e9af19ac69851f9b6c8ca9d4e39d70277b5d9a6a4c6d5f5e0454ac05729c2691e87a8d79353289678490b8f2c41c52a2f56b91a35f8a9e8aee8935ef2bbc48485bd747cc5c69d66b7577739b669befea567ed1901fe663f5cf49ed8f3998ed221552c846ad78a8e00313f6c863ddbb369681c69cc01cf390fa857a37ad826f3eee4f62db69929363e18a0886e7ceca3d36c65898968eb7c187b7b867fe8a8bb369aec780e0033ebf2bddf846cd60633a461c569683598c7744fbecc5438f725e337ced5d3d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a2234e8bbc57d7e23f5fc3ad75608988bdc44e276af10dafd7f5fb0465e4080597a0ff73732789d0f955f93ba77e803490035e416b43e291984cad36c53c947cc954a842dc11424be43283a6dc586a9fb39b39f7867b79772ececaa26f34233adb5ac819f2ae72db5e94edb99809f4a827a85fc7c7a838ec98f7a9cee443f69afaea71dede7c7475b46b55ee8991dccc6527b5fa1393c9107c4d36ad73def9a7fbfd5a9279b62f5ce21f3aab0838b42e667910dcc4c28f505afa4e81757b7f6a1844f8787fd9c76c69e2d7598f1f5d49cb57738daab6a7fabf6d8bfd2ac7137493bd2b8b5f997519c3df6ef38623294b91999a5419356c0ed3e348e94e57e926fe5842e7974104e6adbefa24f54eba5adc08adce75f347ee3c6e4664496a5f5ec01a55b1d2a3e8486cec4c3ba4619708695d2a0f9553d776514857bb8a872c7f736ccb432b149fe99568b51b9c9a56c441bcdccbe7856948fff90d63a0f78c8ee777236ea43de2583d1ed93ec8bcab7c8c6dde8f54258b7a583f939d953e59ea6c04ed449083987bfa0f236c5b9b3d0dc3ff99146b9a0943115845f3fe98045ca844bdbe133edbc98cb54746937b1479dadac5a4fa3f0dc67fba81cb251fe386ade32fa259604a76a5dd56a7543b96d3d96d3046389b9e7dce53cbdd9ab04a65b31c6c5d0af3a2ad53faea3bff3985fdff9ca3e396598acd72f4659ee99e4ddeadad03da64a1a823b78561d5a9304a5dea3056f50c8f915d7eae0b6883e03ead16e464e8d50f38cf4c62c76940fd5dd4b4d74b66dd85f6fdbe7d7a359d769764adbea61c0aafd7f464d7ea3f7063efd6b9e51b47cfed93a7b9adee48f679d6234e9a4574310bcf0941b3e5169eca5d53c005fa6ed3cd81ee7b4bc23c8ba9beaa39f44076e871583eb1cd4d4929a38922df0fac6647c24306e349f1ecb4e2f63de903ddebacda3166d6a3e23d498f96ad5865ebb4cbb55265e6a3e6a3bc96e51745b02f4a593b796b5a5ef48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d +public_key = 724abfcd25f55f0a5efb7783d919d31fedfc53bfd3de67d873c7a7c566f02d53a6c08689990fbdc877bc6b8e3ab59b781bb95f4fca9ee87df8aecb9142a992de7e80bc2ce5dbebb66765c5abbcc5ebf764d5234d89a378d69f5fbaf63a00e35d5698d4b973450a045e55c7c5f59d7fee49dfe6877963e386bd2dcbe929c3d247611e346eaf5deacba7f843ecf04eeabb043644efaf9ba3cea160b98f0d28caf0677ab2aba362b7bfadaca4e1197f55fd3ac8033814b7ee1c04d8972b3f1d9a986637a972b46d3ac4650acd53efbcb9a475bc4065f65a6ec79e1374c2159bd34d9a850ff856aeb32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f12f70bcbe9508f9d3888aca4bab72e44ff85837b9ebb466e5cba74d5ab6bb4bfa10af6209a97f959c905bb4b058ba8ac03da5a7ce90a018a9803ac29d84ba710b30daaad844dcea1478c289d3f737144812355e0d7589b9ab765ca3b23353a350876f0518ef3e5be4d8f66c998b81f458a394cc68c3b7bfd37366eca3e13dc9f8e5f9bf0e9aaaeafc619e43fa7ef3898a76d20dfc64f77e87979ec0244d9b5368677008e58a2b6f7c6fb6ab4f981fadcea7753599585034b9ad99c9ac8c1f872b1a47a088bd8afca2d52d93928a4fb88de98c4cc50c1fe4c4c94fc7c6fb5e636423c6adb553b13869ef647fca6d53343ff7c7088fa2ddc4801b36ff220a53928ec13f3c3e8e1add729ea43a54ab008d326d08d4fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdbefe99bfa332b9cf2c136350adb9553e3643d0c45413782f3bc9e941965dc15edf98738d06de13ac4f2e5bff759dad16bea6fcba390ed6454021f842f6be374af847107a43403b4aa5ccae154b9c54831e4aee239b79f1fe997baf3da542560fe6647a2e7c4926d97fd484c3d14d456fafbf8b63dbcdcc8577b7aed99c060af8d478f72876b614055d95f9e8600f7c94cbd94507ff35c169b58789ae8bc3e6f677ca9df38602399e307553e235d11836be22db3bad4eb0a668e094eab11f49e27aabdfc27afcaabbf5439e1b7bff0cde6f6d819c44d7f556a3946df86c43d1b8693944d399a3b5b23d9b988de3443dca387cde8e4c9b3dd775aa6ff4488f8d6295873dce629777fd94cd62098b6149a3e7c383e2c33cc3fe77305374170ceadb7cd9f4caa736e4c796d2a97fa48d7c9eab72993b4b886e36b856c7bc75ad064f88ef491effa872247a99aa39a9c2b76030f7d66ae69317cafcbb77c37d89ed32489e4cf557998a06689b06ab96615bb5752d439da446354dbd640686aa794444b8d6c31e7f1b8c6b8219eda5a0cd1932a885107b5f968b5c8ec98217f93d895e893bdedfae4a9993f326e3863bcda75190c4a487b46e49e4b713de7b1c5f0ccd3da5c475fb2da94eb2e7f76556bfef8f5076533973bad3ac7305b5c764ddd40d72361719daf4a88e1e9bbf06c6a331a647d9385a5e7d8bad6c89b390b617018c4a079ed2634f9bcae73598b37d8cf45452853506437e756a39977dad9ef92b0e8f0e3567047d8f870f8f236389d99d678cd9b49526aac31deb831ceff4f6f407a59c8f88b7b5d088a2d08b9f114c3f15865103fc682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21 +public_key = 30f9fdc04ef758b73beb83625df3b8d5c47a7a334d4e24d915dae401d461d715fea0fd5f74ae598dc9622d3f4c1c8b5deabd386ea3cd95b86d80085588ac69af4edbe6b5b538afd2f5fe4878fbb55099d7b99490e429eb1e13a6890a920afda12a1da3e096747eba94a337af9f6d9da4e8a9f90d3633fcd99983b8e778ca3e7fbca2ce9b4fb4a0faa4459fad6782367580b7aa49ab74b60c4cef7ab3bb9ba0822f7a7e1ac2f65ddf8f7395f96567404bf402afabb0c7de92e6ca220fc597f496cc8881d7b688861c7988363112155b5b98f7117fa7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be49d7d1595ffced4675547796e3d46535390d44580c24bcc3d67a50c0afbd8936d472fea807de79be7aad0746e8a2c8caf1f4d2728ea374493da6a68d47387a44460b39a45b36e9f1d29b08ba449533d470b87bb936f79eb86db914e632317c4d8ae9e7753458dbcd7eb73331e8d8ce318555e2af828eaff1e2decdc9b8363a9db85064f642f6c36d7e061444e18af8c3b56332bab4bec36d2f5d3e394c870de3ed30997564df5f603cf628d4ecb7bcf388ef35371f870a21675ad6ff660268a190fa2e4ca4c725fa97774e0920e75fd08c5e13d7f4c2a61c877abbe2e85ce58738feae5335aba2c77a804f94077a777fb49854c7a78472f63e435a1d7b4a5205ab879438a91eb603987d4cd937e66c7310625a6286e82d86894ef9750f28e7d867d9bc588d92d3b65f5c8451446e2659d9dc2147ae6f3a577097e64bbb2c679c845e8f7b1ac393497575e385bb39563e125c3a49f5a2126d201897073fd3f45d6ba85db7eb1d5b8ed8ee1dd785ebeed7056653507e967385945389493b96cda968f75840deecd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa23f3a3453fb72c7b68f658869afae883d610aced53fdfbcedcb7037ab72d9cfbf49df9a092f575cd9eca1e5698286c9b19a7471a5b652f6a900659df9183c774e7f0fc89d743aa63589ed588cae6f75df3e3e4d65a6ae81a935f38b964f39dbe8aea75f256777fe7383f9bba0afd34166f2b61bfa152a7ce45fdcb49c3592ab8aafddd9a237a12c3cd4abbad8a48f622dc84a053c94881664a97381ab88ca41846e83ddfe00d6d33b57f1db29b720df9069297a2cc387f2aa53378e6c66e75b594bcd154e71c3f7ac6df8a9a10a71f35b39a3da7d5367ecb33860325f88c2f7843e855d27db6f27b38940f973b3bd63ecbefb3a8b73d46c6781ac87f44c91ea8fcb27e534172fe2b367ab74b3e8b004ef7a16d824fe7814f9a6e4f5a9093a63790bd391d99917be5abc596551fe52bc79703f2bd393c7f0cb85a510d4c9557acf3f7fdcf994c0bf9cd6c36d6041e7c3cf6d44879a7612c3a2fa587b1b7676b966f91a7ba5a795f7a163ae08696c7c98e076189bc26f3c8d46dc8d85c287a9c0c6965d0fb3e5e2037eee6d40854e6fe32bff01c767841eada765acd707dee59a9a85b8f49205c78cac786aac9a0a0a7353be8f9cf936165a9c39d99aac8ce75b6df5f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aaacf05c25d7a804d612a45ceb0bfc39f3330aa6fed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f +public_key = be0aaff5df55d72c6e8424c2d6df3f0aa4c28094691ac4bf0f56a51ea479991dcfb024c151c35cc3c6cc90b4eab964370c2bc953a84a73c87a038e3de34b933f233da28643a93388f944c033236372fa6e6adad85b598124ff7122b4d074a4af57684d46398e5d58b13a863b0b984e224a7ad53cec4fbf690955edcf3ae5ddceeac4ca38d93ca350078139edae88fe390fd9d45eea42036dc913c6b54dd9349503ebad3f350ddd3500da308fd8ba0777c999cb4982d9ee56aaec52396edd5d6ac7cc43265ad5cc98d1926de861fea32f7760ad4be7ff693508339fd0cd5fae095c6a96c1e6864baf147186ccf2dd98f620e5a5f55e6df92b8b715394c5677d0dc9e3f0bf5459d6c63654fa8dfff899f8943957bb2b38ea8fde4bb6ddce6df3d86ea8b616579861abfecb0bf3727cafc74d9e23088c6ca4dc23e86a603788c07ba89d6badcffd7d79174ad07dc55b7b30c067bd830fa1a70998459c54394e96f814515ec9c7f47dd6138dd90ef37ad43ee5243cfaaedde21e2ad8633d38b41e982c669de3dbb1c778953029eb07a947c9637bfa34eed35aa1d03c81f0e7df8ba5e12a4beb09bf5c34dc7e1d577fd30a808ac574decbb51538c2a027f87f7fe2903fafb0f7a73ec8831e6b975007592b5c652fa636c83e5baa474f873a5da2f8ffd156f68dc951689ba83e046c0f58f0447c3b3e6c78cd34dbc5efee0a4660eb1c69402b617b93d57884e22f2d3bd73e3d7874a988ff987599cd4d7946e50665f7d9a8075ecc8dbbbc4d06d6f58f74fcad640f96d9b6554a786d856259c32e0dde3056aef65436a285583cfc9d9a644f66e382d59d7c6d78aa462afb6ba8887c238f81e3ee796a675ee8b7a598afd5d79a058796552da2eaff782c7e331737680a499aa759824e1eacf2bdd1f9a5865b6568ed9aef4f4cc38f74c24e33e965e983033f924526baa377b2ee933a1fc4677ee74fd99ad8826f8315aa95085c7416aea51a98406fa345a6a8d2bb7ecfc885816eb3dfadfad233be3eafccf4b84347124bb41f8c663506665ce4c3802bd9934ce9676cef9ce54c429fd7b7afe5c92be0451730de65a4aab6c97804ad33d5d233f83599133510bb334dacef4b79700887d0ef45500ccb31b7933fe74a346aea4c9be4d9bc6ae8700dbdca67cfa9dd41dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e7eea11ffcd938a3a886e9b328a8a539557f6d8dd28569326684ff779bbe2e8ad60316d673c7be969ebe19a57a0cac91cd1c61860a86356b90715886acbcf30629dcff686883b6ee5624df64ba76124ceb086e4ff5c8a4b50fcdba738ab68b749d1e51db6fc30dfaa3c08f6d4848c4910c9ea20669735cca4df583e0c5412c7edbcf8e6fd17ab9c203a7eb5fd81a0ec8cd78940f19defb49718ad9dad7bed1093580c13b5ffa0ac0d8bd94d913a9ddfab03f835f79173e966746c6aad229dd6a2c363e956ffec693e2ce4efeccdc688c4a88f6a5b7c3464cb7ec8430ce377359a16213fc8d5d410556e9377e4f451481d8a4942d27e5b6a65583999b97bdc47b9e4f308fef5ec6315d9eb009f7e4f75e8bfdc75e838f56f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48 +public_key = 690b34b658603a2dde852e5eddb39ad2e4dba908d2666f3123afc5faf3437bbd376894ce67397d32a67c3bfb976195dc1c68ad988348725c83a388e43e5d4400f9951589d3badd4ee444d4ab2cc7c35b8e0e09cce4559945f564055d70408ec35ed332756e62f7b8328f78bfc3359e7c1b4fcf16e55fc745c80f45fffcd9eca957c8475c63bd5bfff288a5e5a5c89fd6e48c3ef373658859c3d9636786a8d579cd7b764641d6a872232f4558eed436fc72b563883edbd934f5db6ec89429d7792fcdbfcdb4e6fc2ac323a58df3fbcdb7fdf3140478878d55252bec090ad33e34de109869c2df967f598a539d42d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f238d83de7ad4bdf58655c59bf58be07987b88cccd01f1edb9c2458befe38298e90f955b62d8de3dd5784c809a7b2af9f8c3c33f14eea5563d6327392ddd44ec8f72fd5893f56f58bb02d7f9ee98b7f4ed92f86ec390763a8b57409c7c5c665a914ffdc9c6fa5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5f8e6ff94e45636ebf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36684e94df1ac3f595a295cf8d25cf6e1b1b5af5b542e025a182868e1555442e1bdd064865ed5cc1675d74e55aaad70e779e69ee1fdfab07cc551437603d24ca754fe8fa846823bf857f97efa26834e15ff746a6c7dbdf56bc0b4bff02ecd83d9482d7669f8857544ad43624dec684c95adf6f308f7a84b37534b7aa3ccda0816368a01ee41c6eee7e1ea317dfaa7d73909e889dd10dc20e38667ead48278b5ee97e88607b421074ff5c38866fbce549637c600c8be8d6dc11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dd8d70b5687f7c6a73225b9233685c6c7d3d33677999cf4e40b7f894193cca1c5acbe4a133d85a6a1f587ad4ad533fe4974cbb1f877e161646841feea9c335d42bd00c05fb3ed45b2d95b7e3dd61b62e3db4c6bc36d76df5db9ee6984d31bcb1f6757de7f5e872feae7f388c5134956e3f86a49bba39967889c9a42487fbf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15d04eaf6fcf2d15a95553831be379ed0489749c495e3b6b8e2add49b8d65dba89340cfeba3a751d0ff89a3ef772b06a4687338ca88c0effe488b848afb1d41f4f9607fbe8bc075d0568d3041c7f8f3fe922cd984d238d970ff9e72fd979224f3cc9ff54d4da61534da258fa3f6fd95f5b399a8f9addeb6b726f43e3af64d09038caffaf6686caa2dffe94cba660edbb08309fec2b5e142bbc922958c86d6fce7a4b3a4c95240e7f244b9e2c4ce93496fd8cddc4514495b35863cfc6cb41fb7f1a88d80fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c94fd00c1c3380dde9f0aac04c2e49a469420c15b2da05f91dba5dc46e8e0135c044fe39cc74b14e7451fd1e328f06b7401f47674d354123ed955d6628d3db7ba68564179faed9c9d3bfdf3c6e793a33a65f9fb699a47fde974eecbace2279d273a757db9d3a886778003df83b8e9cb1fafd34b8462dcab57c85653e363629e9f70738434bbebb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42 +public_key = 44bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d8dff7ba5c64afd5c87f0ec1ae1fa294758f468d4719dc7369a5de9e6398bfcb60a88e9585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586067fd1ffc3cbd92c3a42d6851fcd64a9aff7b5de551ca7af6b5b3e892b4e4467e66a5efe434da08d4f551dcc50086389faedc0290956b5ac58844a84bf3d8d0a5562b57b5cbc594ceae87911ae3168ff7ce63b82303deaf5e9c33bca746ba7c5e864efff17324228321c8adec976646a6b561508e0b56351d319b31a6daa882342678fa61075f652994d4a78c25659b533f5b40f6f36a6f7d4cd99e502e9c2d1858ca64c94d3734ac0bbcab2ebff9e03450f8fea38d8fa4c26a4880dd7e1966fc08d63ac1e5e74f4418385d6559ba5b7266f63be7e4d959209b657193689a035414998dd08434fbc38f7141e8d9daa89c62e86eb9e8ce3ce70d848de45b3fea08edcd6f89db09ec9210b767d743f61655a981fd51d7c8a47fe7a682be36c0863cc6f430d084d292d99d1636c04d6b1ed3efa74046d2e9ed8481ef3dd85edb685a1a1fb3a3b3cf1705e3030ae3ad73b919a439d424a4adafef995de963b4cde0316739cf5da1a8cf3d65acea624f3a589f321a84ad3eeb3f5b595f11637eaca77fc753261ed4cec9ccf55e7dd4d567bb78749f0edd5ca5f5f6fafef073dc25cb9a12988eb9b864b7566f72d5b4164e340d9464bf29f979a073384f6a5e52aa0b6b74d43faa5412c59155f497426eafce9e6617d5659dca87ba482d67c8c150db069e66a1a9d5b341f43701ac8261952c5b736b35f90235669fbdcc25473e2940aff97c440d98ad211c35c2ff4b6009aa66e27cc09ccd9307c7b3794a5d189892eb6db2c3f3e95057ff365e14ab48614ef760f0dbaec8fb0a773d67f2e6aab899e7dad6e195a5e92486ce9aeebfd5c7d9573e8ac4bd29436a9d88c56abefa3dc7b382f2c5e7265a037b8f7761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abf4fcfc463c2f164fae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0af9ecec82357068d5af096cbf0ddcad6ecdbb523d907d64e76e4be958ae17e2fed6617e5992efea8edfb9648cf53e57af9e7cc3ca8d3aac3f7d87c53e41cb9bbd4f368d332e0a963c3385c18936ad7483a604f92b625c845dff82f25af0c86984decd9371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dcee47f0cfa34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf1be2d7f5453e669be2e8d5dd6961454ba8b40c6efaa6ee53eae9efbff43c998b504c8ab9eaa2dc1eb2f9b5919a0d40955ae567074e69154ad6f6e8d093dd3b554fe4c99f48c5ecf76d9952cc9693acab000c335ba8e26b4b45a903e8f80a6049558fe9d855a026aefdc649d295387c63de075ccb32aaa20227ec6f79d7a5bff02a9c5fcf35fd993f8f1209f8e31c596057e40af9b178ed352c2fd955edd52aad7d6b2bce5026a6d7cba0133ea85ba39b179f694788c9215b69fdeee1fdc8934a1ba24cc7890eb479af0df0f39e61b0a7ad921bb72a8b495ffa74c62c880cfd3f0cce75eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13 +public_key = 9ec9ffff176a27197eb4bbd1723eedc7fa954c75f698d5d105b5c2e9f7a2a887bfb40880f96f4e1fc67b1b43a51139ac6025b9eec6d925e4f4bc8fc58b4b617618c43c99b080be4e5b86538d29700e1ccb4f53a52beafef566b20d8cce1d86e6dd8e398d14abd03964940c794f7ed0da994d5ccdbcf29bd4a8a7e214e7ab9285515ffd9a7b486ecae5c84655c9ee25f55c7e5c3b784d9c24399327ec604a3e2955d728396e768ff2871dbb9bcd4b06577b3636c138af4e2139b48ecdd5563e52c7bd40cf1bf408248675eb90afb66d6105537b3e6c7c989746f43c3b284343efcdb60fe93a16ce71ab39c67797113bdb908cd0f6a47f17ebd8d924826e5f6cf98f34a25676d82449f94bf85907697896de49aadde134a936e35f06a7802466d08c23970818318bafb55a1762a9394dda7a49ebb4b38469410f5945dcaf801bcf5ba3aafdf819b0db194b53d4f47fb5d65ff99f73f7ed52dfff510cf72edf809ebcc687abdd910d4da5ba7cc956ff6d9ffac8fac8ab95b769a465cd743ba2babb26958ab9c3494e3f9a0c736c28a9cf84f5c90c6ad594485a9b339213edebf7aed105d4410abd9bd063b4f2f3b903c94dc75d812ae5cc885f7754d476ffb8ff34f39b557fd0602987581fcfb1da648dabace5bae590b5cceb8fc20e74795d7ebb718f6ef5ddbba68da447693a42d8af3256c64cf3f7b47dce576b6344ffbf8fecc76e1434d5e448aa8a3b326584ddc564977d4be65ed8f867f171cfbc3978d5990e76425ffbb81645959b8092f8fa54c68a006eb78be78107e7bcadbf41b0a9e3461579b52aac5c6c8627dcd33cfff7368da523d4cb7979cb65e7d56643856cee87ddbce12799559a97e68aa96a18089a6c547e87da949d6fb8ea876aa029faf409bfbc354f05ecd8fed46905af688fba59fc7eb8313ea19bc8a6350bba9365fbe1ddeb73c89964563fe588a5b76971dacba69868b588cbff9076532d6a8fb53e6dda4c85c2945a2a29b6ead3900f5dabef2b44375ac36bdbde029af0cce58353d8f7f1d53a9a15e0e48f7cbd1383a7de8c0e2fc375efb6062cf197a6cb094ca9dcc4ff0418c24a9cb893c45423447cd5eabb0b9b410d9e44013543e5c3bad525377cf8d73d4a5f4b2fbb24874b7f2e523cca731265572b487e3c4fae581a617437348c39df00bdd9460aa0c7b6a1a64ef8e5fdeb3d4d6a296cb35dadbd0d29e7df04fb4848ab3ccf8a2a38d44d7e9ccaac45c513ca007653bc854dbdb79181157aa28ff0153ca3564bf1be77acebed6bce0f531ff5b7f5453db11e9364dc4e97ac7a4a5f87815b5eb62fe29643aac404fc3af35afd2fd7db0a31954dffef097bae37bf383ce54e88e54b44d7bbe9dbb2143bc285af1fadb1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83bbff6ef19367725bec989c39bcb4337deabf7d63efe2b3327f4ab0f6457c5f3869590c496659f3993cb2b11d3b8e8a41cc5793adde92a047972978a2ea1b9e354cb136ffad8928574b3ce4fccea4c037e5292c9052b69ab2a8329d0f938b0ada95dfd9f816a24fbe3f4365af2e3df40ef66f9bf6b39d54ab5d45dc7cb3cd6f64537a8e5aa40f8232bc89bb89bfa2d6fe351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba +public_key = 5d4d5485e5efb10cb0f25db9db466c54ed70f584904aeff5047bc47bae5f630a6d62c5b17a9d6ee7cd67fa3384a5dff748f984ec3eab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b36ebeb0eb4eebcb8548139bbd7ada844ca1e4e59f3d7c4372ea8633bf78a7e68b5913f012c5518b9df1bd5367567d77caceb4a50944ea1a834bc6e005bfcba7f6401a57839a3cb85c3f644aaf545795eb4a2bba2f2e87f14d745fc6d8079c8b5adfb1928e3d51c5c3f329b1f5f4d772eeb33f63ca400555ce5351cffca2dedf68d78551526e8587c8b037e7ca290467e4a7c2c48f90b84ab8dc4a839f67e02dd559124d92166be3b23db41bfaff857c84ae45c1734375a3ea91032de4d29ac5901fbd5a44b91ce986e094a66089479dcac23b6f75b874e95eff4f2d4a97f2bf6b508c3a5bb89b9f0a913867c1295cf52e6df2d9fc60ffeb3ff4cf9b2edeaa980ff371c5c8e749cacea39f2c637ff5af35882747cedaed96ed93966462ae5de510fce12026bf0fcce0637d988b2c35cd7f69da693a7d77d5309e56d30c916ad6552eacaa3bcf396bc56668686ea9ae578e46658b7eb4b7365ae57af63c783974ceb6320db1aff4c3feb64856a781334c6e845e9e5425e1b4d581914c697f03e339dac5676fa1463e6ac5de4e522480782c4ec53bea2b8a85f667f17feee427afa607ddec1727efd118f4c17d42b199f25e4d919aac5cbe05b031689b1eb6e04106da1da6ea8a1da205f6fff229d9c6c4d95b37dd87c9727a2b611118c84abcd33ea9cab504dffae6e1802e60a575d5fd775d404e5aaf9f71aabfb1fd1964edfb772a9c4876fd6826a49c26e93f0b1846e006468df7eb98ac6fc008ebb156f36739c9a7b6c13a6fd89e7fe936e8b265c5ddd50e6548afabd52339dbadb45adf65559aed9c6ec73e49346396b6165e95c9c3a4386e4e69ef3144fd9fd28857aaea50ab8d8600f5c5ca33c5963cc00c5bec1def609486ac4f2bfddb8bd6acc6f398b3f32003e6dabcaf5d4a833e3ad1a6e7c971dae5e40c459ffe8db855faacee58451fb4c4dc52e70d4ca56b5f48555041cc828a7a6da77c435f05574e6cf5efc3c6057443eb77993c987cac2363c313dd89ef88f5dd8966f6f47a4d78a39c53edff73df178cb12fa5fc0f5a2687409a785cd7dde9f586eb0b3d87af9e844a69c2a8acea01becaec8cef7a67425b87be02e8db67ca6c7dc3b45b04f6dfd33dc6ae3e763e907ed6329593c333466d9628668b98422c985182f8c0952cbf516ff25363398f5e6d23678b542da9cca38e21c6be879ffc4fcbb90a4f77bcf8d992858c5498c6bcc57dba8fc197bea78d3e7975544ffdf33e57b3ddd29a5ca5bffa918746fd9a84ef2dd8dcafd432e39b70fe82ca4df43cf350c6f486832a807a36c8a934fa5c49e40eaa7a45bace0086a86fe36be28acec756b5e9a4722563865abf50c52b56485ece8d4fc39ceed46d2b6cdb7db79527d7b73d73f0eb5ea3fc522908e7eb04d17ce97307c6607b4ca17cb3d33067dd4f39bf7699814716dcc04b33d4c9e294f85f4b7e7efacf88e384ef70fa5823ab8329f56d9d1bd5c996701a15da387362db09427d5587e785e131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d +public_key = 7e395f02d56d41b5c5889bb6b3fe49426afac8bad6ff23a8294e887eee99b56c91846392a026b50e87453f44588ee6ad4a443f55df5ecae39aaf286efb47a760ead1b7ce3fa178811c47a0e0be4110fc6482543e8a3a52abec3a8e7e76aa2868b2d46cf68538c285e4222a34372cf5fe93f1852d6e5abb699e6e426027a94268ed0bbbd75a367793d8eb7fece1e2f6772d8d40d37ebe5d07d00b43da6c874b47df6f51db8f440ffefce7f613f8c22d15c28a2b38416ee42c148b07f7362eea4771959b636af15b1351f75d342d3ad71adbe6dd8ab50549d96f295e44173bcbdfdf3dbf71a814ee3008a742057ef20bfe78f8a3a4cf52f6d38d8e85bd57a75d45ab4dc21b8033a9fcab6f3866e8989f98560de33004d3409f233020899341bf591e1a4a0223a79f2db4b85c632ce7609c0c45a0246251468c1b7cf07173e5a555f0c67e8f4c5c706643efc7e953ee9eaa5f3b92e6a6e7b2acf56667e2434fae8305780dcdcaf00c928979f9a1648be9b47f87fe44a4cefd9de5ef347875e6da935f0bd043abbfdc7b85066a7836d442872c56fde4ed9a4ad1d9ac6a1263e079f74b273ca129f36a7ae463f6464436f5dfa70cbc2756bd25234893c5da2898345e588b81acd955e9c5017f517d58b0a3e4bfc993fb727c7f2fb9f4ac77fd4e1d4a8f3ab8130da624d6eeb6aa7b4553aeb2084361fec03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed7cefe8be5a6ccc74efea7cefc8adf5fee885735dd09fd3cd94cb4c465e41d7aa2fbfcbe3eb896c34d4bfa3580bc63b73265581d87618c2d6caa9468c65bb1864be8f66d413d2bed3a2f59f38cd0f7d89124c569134835140d6feff890930fe9fdcbb8b118b206b64f2df5fbe0b553665c32831bb4cba3762a9e716be65e6b3ffb31ada5cb24620745f732bc3c8ad7a2c3243c634f4af32fa922787f7fe44df15f99db2ed5f9ebb0c5bae8b6c6c73f43390af9c2454442110aab4ab6f9c803d1dd38318c43a25d269885f970ddd8ac1e69e8e59a3d53dc8a44873eea97c31f44e08b893b644f84d79e53789f30c29bfa1636b6b839a4d91b7e24fd414c2eef2e8ceb3ed586142fdfec37c783085874a4f33313950e8fce946778e044c3d245a19c29b09b8dc3b564e6a91eaf3313fa0068c7a4767f05e9aac3e8b99b967f88e5f81a38b072b8c4e194794d4dbcd53667155f5e856d48e56cd08cb48b5fadc61655b881abd8fbb88338ffdd640d3f2453462598ca6628eace033c708ceae986dced165597bfb163e5493464dc507d97befe4d29ea850b95be6fe4f97343614437d549b8eb5f83e92c2c6ac2474686a9a3ee556b6f26a9039866187df6e25a60b5864e963850cdd8f19e2e859b5c5c3714434ea53bb16786ddf8d3703e7c430b3bdc0f5e6c6fc09744df1ea6eb91edc5192e83de05b294ad5b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b836cde2983f61bdaa43f4e41541e8b66c641f834c949e77fcdbcb59ecf7089138a2e07a5b40c7666794fd8e6b97685bc4a4cfa66aefc3505db278bbad765c8c775bacf38e81e6e530e54ae7fdcaa278ea01b05ed0d8ad33d7bd05893b98da8600548ef1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2 +public_key = b5e6d22f0fd8e86f9736e6e45286e9e33cb9270da1e3aaf0b25a5b16fbdec117de5d566b28449bfb38936f44721ee4f8ced5768ee647a87eb7d76a30c7e5563c5e5f5aa89ffe994cffe9f77b0695049c355267b3a07c61f3c5a2c0d4ab8df7612ace9f44f762b51bc0374a43e6f6c11569d1b253db2b77afc9ba4e14d3658607387dccfd12b99ec1cdb0c38feaf298a6ebd9fa7e6b97bc56d674a3ee21f68377c8303b24cae8d5ab720c79c4399414b5e42556d3b565397857a7078b36e25af62c09d80b9fc034c76614d5ab455b60b3b338860d946687e95cd587942342a6fc91bffe44eb5efece186a422b85a213c440ddc361bad0698458f5c5370c6c553aacf3830e754e3bfe2785bb03053e0c4e4e482d87a0276bf2e8d5cf477378ca34d90ded21b433f33b49a8b9bcf86f45156d558fb9c3cd17ee655cf50efd4b664ebaa278c1669bb49ca3ab4c78cc93ede37a2864bbedc905ef3aa28395edcb435dacecf84f562e6d3bc61c521145ca16f69193be37ee47ff055df527bc557b754e187355a38841086ef6766ea6b1f59e0429debd6d4ff65afb09bf44b57abe85fe8938c5a9ecdc97229ebba349e5c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f431f81b5763865c584cfda6aad7482d01ad520d947fdebe739478660ee78fa9dd570d4b2ba5f9a42b5e4a879ec863ea272ce8e5f84380d2dcd9aa9f052df9b5be76b2235b5125e4904e3b284e8854556334525e62ebeb09894b18b4ef7992f69509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bdad4e2ce9ddb634a3d52b734f2f4c4d6dba3d8f40d8bf755ae5892a09a0e7faeb2424402c45a0ad59563ab97ed906a1a15b8c452ff19203ce6826b91eeddad71fd89ebc5163c4e6c1edf009a7a5440350a00a7b4a3d9ce39ba26df79ece038f23f4b4301cd1287a51f5fc619ecad4ab1b78e6396bb24cecb87adf3cceef7e3ea161a480b8f33734cc63eb8fe9d76bab75abeab44d5ca61b535b893b1cffb678849751a6a4f199f3ef44470e543925ddc462d8a07888fb8034e334f547d2aa474d95b8709747163bf28993ba16adc4fbd8bd663aea300ecfa859ca724ad11949823fbb55947b9c28cfbad547b0e7df966517eb30f3c8c536651e6437c0d4a314ab38a807d8929cdc2b864a3a67397a936dbfb98fab3cd93554eb83157d0517f891a4357398fbe97686534c8bc80e5ac267b75f0a79c6a9ecb6c96c735a4beb9dacc9bb6ba2cef389fd821a0740199d9f76944d9295b5eff73e70bceb0e1644e3b4d6863d5f8a16f6b3fd5969fbb4cbed7c6106f23159b3471654a88ab58ec3a649ff944625820f6592c78ef6bc085dcf2e6fa718d89d4947acaeeac15cd0e53782a01580fd967595edb2b2b3f72d69daa70c7a404e9accd33c1c1f94d31f42c739a3e8e577317cf3ebd4b4c5dd577b2bbb12cca7194eb54c0b7672a3f0bdef6dbfe5bbc017c9259e762a6c938d4bb0099aaea29d813a3a78e5685d83975050e7e9d6b6a80ad3e3d40e8d25c9d54c6de3f93fc13544d1e6cba3ff5f7b8d39d6871b79836cb35284725e733d8fc6de6a94e0e506e528a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b +public_key = c65e70fe0945513748c0ecc9099ad2e9e5ee44acc26737f633645ad66f816d479466b54d225dafb78fb4f42f65f1f4bcee2ecaf7c7980105b08056cc429fbfe0da9aa6fdd865bda3482ff04cf6ae82dbad360a7c840b48058f6c39a59ae039d56c2bf542b6a589eb47c14a70adde731cbda4d657656915b91d696b309fafd92f45945c7b77958a5b6a3b6ccbe79ab83a103f591b757e8b68368d6a5ee63490604aae70ea7fb56e9c91a455429a6b1a6fe4bd28bc717385d3cb8235a9ec05088c7939bf863ef5dafc3bc36847916543819fb530cbfb879f46988b8f864f5a2b5f3ed108c6d2f5435868d944d64d811d78a4c6f1f69de2f9d8a17b9fab8ad43822ef4e2f87bfa844abd0c6b0875dab76d5397f2cb0060b31af689fc97ef249d46374848f496b360e733fca9e809db8d4dcbab1413da4bd18cfe37b41cae9ea67af63437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524d6e6bacde7a8dc7924f37345dcc32de14f73c6adac038a133cad1ce2481ffb57ba153826a7cc4123570293c82082b6a750ad6031cc7fdbb9032fedca94aa283baf6eb3546f894b646b9a85afc5df3c5e3dc6ffefb44d287c64492aaaac50cf6558ef9b56b9541fbd9133ffc2f6da11ba3d4692a749cbe74cb47679dcf94254bdf768a7872f698c23493fe9d8c9ff95f9275551b947bfe84780f86c1e0cce05f6cb7c953d369b58bbb07b3b0c87d864e618c76a43e5fc98a18e66e15fb4497e77beff2e7bdd2f7fa3f370ecf1ffdb4c02ab550d76447eaa69566e118a46301b544b493c368b5b77bbe7c5af4543fa6a8c78fa46af39ca58d46b25f9684a53d0e59fe1b8596f55334aeee5591dbc4b51e537c88a5113458f187a6d87f78676bdc85cbd17416b6e9543fa1c9f4b73eac1ddc55571f7548fa8ce0d9d125139bdf13428e2c78066d7a4435ea5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343ddbd62ea3a039e949a8fe51c9add484368f1cfa385cde3cf55685bfa4b959f8634ed7c437fc9c044b401683cc758f722c98583eef4eae4e4c1833858be987672c557db87aefe4ce2db8a677de408356fdb35862dc0cae95f88ec1f594260aff24e9cfc558e3be07c98f78a87ba7d3276b455e15474d8af83d5738d4b639379d77e789ddead3336e1467c97ea57118d004b9e162fcc31d39e2646a9407adf248fbbf28dac4344bd81d3f7743335b9efa4b80de3d5187d64a5b6e8065b64d8c6580b47e657fc8f5139268145ba8af3a02f59acf78d693cfdec2dcc087a99be036bf7e9c8c0efe5f168c508bef8e33d951740a9b0f13f1e35cc01328b7ba96d592b566cb369b2105ec7ae583d26652db7f9f07f5b8d59caec65aae42c7c9cbe73c695d4f2677dbedc542fbdc67a95c9f2eaea08e55979727dee73e47a4688c8f2dee5aab48a5de862506cfcd297c7eb6ea9ed4a54fd3a2849df930ce5710afae44afdb0ea4d675c6d5354f5c69f35bbb7e4c88b3a6c333d90b4c56b7f89963059f8cdbd994373fc1344412f694176cfeabfae10e035bee6abf546396d79472eeeae64bf49350f54c2e7575506dfde4b4f721b37974b8f66c49b57c6837b39af8ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec +public_key = d4becdafcac7f7dd8082ead95a7658b3a45f7b07e8d4c8da3a15da04dbf3e12ed300bf731b2c35a9ecf3c444e977be88f62f645abdfd348bc9d2064d584d40147b416139e4d0cf954f4e90905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca673df4336ad83a1eaa548f8d6d79c9494f5422d3fec57ec2fa843b54f6731fd4d14766e2a135aae5be46fb8f9872cd654c075dcf5ee90483c3f06db7347fd0a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0e4d2148ad8a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb4fe84d7d6ac6ef64cdfb89d1ce66a059a4659e8e37dfb3c95cbc9e8d86e064cbfdfb5dc6823da8e9ff58407bb7c9f6f7b9dfb542d9f3ab787852dfe88fb91e74eed4a6f51f7b574aee5797e98eba1ebe6b05df81596f67e8f6c0f33a0519cf6e6533e19fadebf29474a23ed883ae89bcd3b836ce6c34c9ae8aec4d905e69f85b8552f84e14d9dfb0876fa6488e75e9867b5c5389686788ff10e95399a1733d2e78532b7651ca9704bcd63df086cae4aaf6525d094ff7054f34e2849449c7680ef1ca1a0ac399b0ea9b74484a967592ce8508633d5835e8415cf47bb7680ab0cfb04a35a20a851b73548a8e4cfc2b84cb5fcf4108396c28498a76e4790d56bf9deb9f9f4dbf574c4982e8eeccd6217c9bd361baa5d17e5e666c2d4df99346a79be0bbe4b7ccd49f948a60438525ef9c126aa1f38757199f2c61f4729fd9fe5437ae93e94ddeb81f0d744fd2b9b590cf33e2792501b49339f4fadce6c1e5444dbd6a8240e6b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c599116f8c8daf2b1138d884842c387b594b544e5d99785bd6acc3b5d80ba81cd34739b2daf11f7735d645da0ff5c07f8af9b69d2525ae953dafa58d6b796e3695b0d6ad6d7d3dd26ec13ddeb9bc995773c5d2ce59470c765c3f5401dcd7885c77bfb4ce5d7f766f0ec7cb306d2db0cf20d599094bfec87e8f0033efb06898a5a878d4ef9e3eb55edce14a1bd4f4838d4797fde4d9efaf473c3d4d76f4f1725c82085ea9e3e3cbdc79acaaf6548587fb41371c5f48a4ead4d37ab7189685aaa054854fd491a0388ae4b7af425996aef9eabafb2eba5d3518c7c53cade6cefdea8355a64fec481eb5e663adb7a3de4ae5cd981274d902759af79433817fa83abd5d9e4fc1ecbea3da33b54066d1a73d24a4bed1437b37a83bbe826d75c04e7275a6f58336905937105e63a1b0e7f88aeecf0c4edab4ea5dae3856b6d6e2a93331776f8198b49d35e7f54b9e82e4ba87786d517dc94a07953893ff51204b4c5af382cc7889bf84924cd9072f86bd1c5879ecc3a37678e6d13e569cf4012578dde5ca01005b2e07ea4a1bd455a03afbe7c366cfeb086973038fb5debd793a303b4c867b61187f733f66574dbdd7d3d3563c389b3feb46e98945a94b143bfb0d647521f4b58f133f6fd96f86a44890929ebc70dbc7578b0169a45c17ec77f38dc583788facfaa130da7353ead57df3b2057ebb67a627a594baaaffb1ffb75d3dd30432a954d8ef35b9f78857c3010a8a8907cd70b87d60fb831852e40770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49 +public_key = 113bedd0a3e3baaf5b7094700639775f89b8d13e4ef00e86adf7ceabac36cd9f92c37d717f27caeb5eb1b0eecfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad494eb229fb7a17ccf13b969935c672d0993a94fce70bdc8b7d9dde66bc6514f84fbd8ec7d1c9417b79a82e5b3980acc793ae9c47de3a2e75a3af89ebec5def7555793d94c0ee1b9e98a5b6c52777e537bfb297f68ca9524a4438ad87a0e95f79e474c5be7740b7867d8b04781a2436a8d343f72f74e236c736dc3c59d5b326563b9c86798bbe4a6caade67b36db89a82af79dda80e6418cafd6c435e39095bb82ade4addea73b3eec9159845dea3eb233d16b93291a4f1e6a342473a71df6f9477183e8f34b2b7c8abb7a3b6e526e07cc5f29d88db944e7f9bc94c38bcaa58f34dd88835308c742875cccf59f8132e99cda3f148f48a94c5c2262f95890bb4645761d4cfc0f33ab3e21feaa56b573e9c6fdac37c83f678ba7e48ce573a245bd487f3cf771bc7b7ae3fe53a6ba58854b87a67a7ae7d6b4dec85f7c06117eb4debf7b304d5dd5dfebacb8255ad568d48b2d299bd841e88886a65aea5cd8d987f6017a2f449ff456cfb4f9b63e6dcea27ea38f2588b108d86d7a5c5e5bd5b77dfb89198f0cb8851704ca6d83d861c6efff0bda76c6e401e23b01eb7e0c5e3b73fb7e6dfa6408a635423d6e37269fdbf174d6e9eeeef7c4d885bca5fe669234ae41e43810beed235cb59f824728bd7acf17765bcd354a493aa60438f08df66d728b640dbd7d60f75bc36d5fa6c964614b2c8143b38be84f3d3d66876f149cce8c6038707deff0e3eb896b69a7d588d0004497e58d8d9def253987f010e68ea758a5c3fc196fd3f24ad7c5a546a6617d84cf79e073bc6cc1cb372e385cb8f7c490a42da1dd35bf735c634f031b8332bc57765ecce489f706f1cba0c7cc390e7bd3595ab876c4e397c58fd3f5c9607b0ee39692d3e730eb4744e967e7f08e4a0dea5467ffec97d516b39f5628ba782cac846bf429c3cc0ebf774804e4e8d35cd4b9ec95aeff76404a5df4790f4363104e6a0d1e6da48b65bbe9fb417c5ea5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3d3e638ee4c5d0f79cdd6386f2dca89a53671fb2f0424956559eac209d1ad48dd1a68b67693b186ff6a232aa1b445d33a9dd20867e3ca5bff94cbcf6e837b0214d4b705eaa2c5f0f93b901943c918393f2616e347bde93ce9ba8a48b5c5cdeb0e0af41ecad528c5b38ce3fcd6eff586494734fa746c5ee75a3d3a52befec59bd3fc99a1ed0bedb01375042d54878a6ec9dc4425945aae387e7fc6cd399c90049854d05eb3db79deb79ada2ebd4d062dfdacaa98357fdabb4f7b5733bf1d1693643c88bd265af038decc66344c9ee29c59eb3998c6c70ccf03257c2d16e15c7faec35b4c8774cc7936c579bf9fb4bda5c677d9363b73f42bd8dc9e9cbe57ad817cbb5d06fc7836af6ff4ab8ccbd7c9fcb7e3e6d1b31e7e6b7f42acbf4ea96ca867b597e9e9b45d0eaba9b54d2e3f3df8b38d3d37b72c2790e114e037355f274cceac37e4a92955b31c55d59d3a85bca55b2bc22c536aac2f557eaeffe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467 +public_key = dc0dd2c0af8b08ffeadc24fc762eeb9785aa2109a795ab792de4cb7c6f98a514f00f8850d32cc44e64e8286ea1c9c9ba591a9fa6873a620f5516bd68099bb1e63751c5b887d293d77f86b733e4344d13310dfefd234fff255ade92779a87067d19c53c70dbb928ee4e1f2892b527394a4f8eb4d7dc49da8aa7fb87048961db4892a6f89f19fdbb69347b9585d25a964047ac7bd2c7472838383b6d72f8338b23bad7d6b7b222ee8d4e3c626429e6106694316affc5bb88c6d664667680df556c3c046398a883295fef32ecb758bc64cf246816af59231fedcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532ddde38a5cd3e2f05d34d5fbb486ba7666bf7610b822975c41243eed6c98e678fedaa1897936371113a4f17d96ea735a5cedde9809c3908cd3faa5dc00eba9dffc69a912e51a49e63f2a3ee1d0f71d59e562e0a87fdf7b7846c31162de7ef08727dfb68f22a8585295659ea358dceb85c9ab4d107413225b825a8d4b31850eb347e1fd37f5435617a8ad7b163f1cd2d4b1a6b7c30d67e92cd88a458bef5cb704e6b662189a9c0079e224a94e225d2c1fea4df06d38ef6645cba38c0c86eaf673e9b36e3620bc2179e4a988e645fc48e33cb9ea16e82637439f2dea19fb5dcfd3b5e2cb8310229b74ecbaead5bd79d535521b8587a2995fa9b8c6694be6e53f343c97c16daf3bf53883e23cc390edd38e54f5639b9fc0943a404edd0acc8dc4dcb12e644cb74b9d4b858f7d676793db9248ea42368476dff602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859903de9822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a45acd764cd943e0b6a5b61b835863d459685e294fae9ab867fb8ef1732d7e692a7affa872323779087547c3d8b89f368ce078acecd55aafd530547ea5bfff4fb265f11c2e69f4543927c845a3049f7a88513a78f303a6dc2e1fbc277656f15738c4368dec7dcff2b3fa1d179f4fdca5791fcedc2eb357edaa6337d788c5e0e58b4bf613473fe931dd8da9cb8bafe63aaac49e3936c8a939d4e3cdbeda127740935db5db4feee6cf4ad4dd93c1d7d95fba34b81380e5da561ccd39e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d2ad8127db4ceb3d340b5589b33f7988c97b790dd4d23e5dacc3d1521ae1fafdb4fb33ce7d1fd3001fc6a76e36c0aab83928c145f4b968783b141f81f2153925ece3ad133fcd5f47b595cef1fd3ff0eada42acdde9a54f67cd3f1b6e6c731db7ed46f4fedf7e99f38472867a9283c6b294b0d80e4cf9eb62f0d7b052be90f093450453c05618e370b45f5ebc4c048d8fbb5c6d8b659bd236e2c297fde9034b11c6aa6d356b2baccea009dada0c775969c12fd5bb0c8a9bee5e72a9358e02cf9d308636b5d668f6bfc9dffe380caf3b5c94f59d887d3dc488280fb41d99c72d9dddd6be9935d772271d741b1d5c1e2f7c38c5665cd5a6daaa991a9868499830c1697fa53dbf4f95b03014e26fbcf83a167281e4b847eba8488bd0339e4edb0b67b1f3f0c25bab504993791e5cb07a9001fde56c9c93c1e9d693b9c22623a3eb156190aec47058ec4dff92b756f410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4 +public_key = 2df84a037fc13da5a495a4fba848ac92e3d2a98a3e55937b8b1b49fe588be32a540ed9db5cebbd91deb80edf4d32eb85fc14ea7cb3d7e62fb8c5fa9c85ccf58c8abb9f2678d29569f313a1e76da2454730261a6766945ce43ce40f5e81c68461eb0efe1f185c368f33b9bb4902fc5089f851bac83ce4fd7bd8be85ef08626e8df912a7d3344d84375bc5ba27ba023ca67233e9a916baae5f971576ee3b4e3c8137cbbc2d6e3149d6df1ca77cba73e5499f54fc53047741af2341d66f3278f76131ab47b01dbb4dea8f493b6c0e58f9ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d03eee31e493da6ada1117b41d4ab3db35a7a2e95c6055ba70ffe59e7baddd555f59809e577087bef1396acd48e747b962205af92eb99fab8d9b4bc47eb93bfd396d102d4adcbfc39bf9dd2465d656d4f785a6788c7a851b107823b0fa3daa4caf35d97f1f9afb2a4e6dbb360c4b8f4e3dafa31ee9f94c8d5de28ed0b0f8e685c378ddcf2521f899a6b7987aed9ca5bd94909b2114fc179c6cdec2f564cfb6f89135022fca3028caf7abab19b4d45dd5a60721c6bb47ac53f4dcd9335e1f2e5473d3b4ceeb44be2bdde090a886d345b13a58620c49ca0893f23058412054ae5069c1014361c0bd47adff15f43dabc647114a3c597765fd014c64c9ceb1b45b3be0fbe9d5a55b0cacfce297581fb48ff0f56f5cdcfc84aae1c64ff3683de601d795d8fe57c6532106868023ed418b549a7398ca8b7c70fedd7cb153d2a65e78bef3a5b095ee3eee6b9f3a1aafe9faed4dd75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c77d1368b8ddd2e9aa02f95e7fded22c4a50cdd817aad8044c7d2ffd786fbad88f867b63ba5ea9285ecb0f839cd554a83745444c3bb88d3609a9a4bc3edbc741d8a71cc75352e7872539bd6e942cd36a09bad374a3894d279a1f7c38a56e7c0298948c43db8c3a5b6aec3bbdbb87384677ada88d17564a7ff4dc2983a9ed3acbce6ef9e3a78502a5fa9540a44975572a26efb1e4f84d9bb528e538f44ae5216f4b4f2b5f08e06c43896a19d4e6c99c3b67756497594846889fedb6532fabd56804d7fc6d6c302766c6d1373bf78a188a6e88d0fddcec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f3158f7e1bf453aefaa921f3b3ff4f309fd41dfb6c877dd79d60a3ef5735ab8a36abae34f4b1f729be4a00f753c7e4699572375e6c7b0379486852d6c09af7ec13bf6f7349cdacc3559bcf9d5cbc35d4ed870597e391ac4e5ddf991096f3759f083ccec443d4bc3d5925843622494c735a4fdac99d4cf195387eccdcfcc8a999b6d1b744a542359e7be67fa2df2be1660bcefe8a6a6861bae7c5725f55227ff38b43d538e956caa77daf9b94c06ddbf08cd9d9b4c1edb6c4a17bae3b3680099e911cf80c3e7cbf4bae1f33a7c70e3b41acfb2b9a64709d3e87809e4fb934d77b4c36f3f9ba98b44f394631e1af8915fd6205f7d67446d6ab55ce7b43ee118dfbae67086afa03b36cc9ad9b5b556e56c3c5a7abd92a689e2a19575f6b5546397c15ae334b55ec3d919422f28b70727c75fb631a2bbd12bd5971b6bfb75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94 +public_key = fed53d1954e9c06b92e51498ac36d186aae024fbd370ca3a420c48a765a5b99bab88a759251cb83259a6296d3c54a831ad0e47f3a97b8329474258b7be6d674776d5a3bfb8321f52fe54565c865e2dd96ea9e43b242fec27bbd2c348310acc38d9d583b0e8e05dc87897cf38069c689027910f9bcb5d29aeebf57c2b9c78f76866769cd699c6bf744cdb441d8c128a5277f39b32c351926369fb8754ce0e97eb9ab602f391c4ba564cefc3434dd5277ff9a11bf1d31a7cc3e4dc2f7e92cb76f8afa692d3e75aace66e7ccee69893c8ee45bda566de7f79c711e3fd53cdc783eb40bf8977c3063cb114b6368a8d1486a86dced8d146a649ed80751440f4e8d87116701987c328d8547d0573f9cd3d321ac07138a60964f97cd832dfb989fd99aba9cfe3e86decb4df5b385cd23f66776efa3ad4a8e037a544017f9634a782ad0cf5404bbb4f34d5a27a8500cd79e96fedaee48848e485f54af8dfaed89d849ebfb54d98ddcfb3cba46a2743904f6eea2ad1230fe9073d864ae46cc5f3a8297f5cae89331d64db5b3633eeccd2291ddd769d8f21277104d7816f56854d3f89ad1a5c73ce65594dd89cfb9c91be306724cb2828be679b989a3565759bd58ae983c1ea9b720ed653795537d454eee5df50b4d27469fae165c846d85527e479e3fa8d8875d47bf68d210f87c0a5b8a6a78c4769bb3a795979b774713a522dbb723f46f8f204e36b639e3b4c5c4b076d322af08b1f3d8295faa0db6ff8457e745b6b710b396d9ed6e635a37afffc5afe7df7c7d70eaab38d5448e4ab67e7cfe078d5b9f9979c6d7365cd24f3cef6b4c3be86ac6b792ef9351c6d40f423ca22e7a1456ad473273e3b53b92a23fd7c44556477907fc4ef982ad6cac9beeb9655ff9dc4fe93cc33337d78294f7d1f8ffef8fb0e5fe1e65d342c599c9a3fa201f3cb8cbf53a0559fd667a3d2cb46a4936f5cf9c4d1eed5880a446066ae0694ee13ff59e4f6f20da3f633f77f9a6b463e28d778d53c38edbf4247e7f4d476ecab6bfbda7e461ac3cca8d6ff4b38fc8dc0acabddcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f548e6d79c6a1fc4df1dffd0334a7e7486d999f8a0294c3029cbf3ee0cb8180db95cbfd140cc5de537aca62c980834de74e5d8aa3f63eb14b7d30fa31decf147747192caef38a3f53834ead1db35cab4d097393038957b64f7e6d4cb3675aa9ea56f57bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cc6fc712e65c74864c3a7ce67d8af92eb78496c4e8eb78b55db7964cde6a35fa85e655c95936d6006bc07ba6250e458a387bd7bb43a3f6ae6cd8733b66565378cea74d5488c2addbfd7a6dfb474ebff9fa80aadc93f67d0b98eb7a8ad3aeaba978ada5e55b8937ab68e385f94ebe3fbc6c26ccf3b0b8ba331a578b99b493d875f207cf78a3b4f64ee56fd386fc24ed4d6dc96ae9bb3055481b856e83df7eeca19f73e58c466faf25b28f4246c799ab8b045fb84467f882299bd6f2bf788fed94bdae030cfde0a27425716f385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac015168785abe55ae6fa8539cc6b97faeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c +public_key = a0e473a9d639b1299251b46d07c79c0efeceb995a968b5b707b760d8bcb12006f36ef5b742f34549adfa7c73338a8cbf8d7bd2a83470875beec5845dcfd3a4067c420f8485fbfef86a23adb7373b9217c6dc17374897dbfd164a16e6fa3a76d8f6efb7fe78b92364a4b92e967db45ae29aa1b12cdcd67cb4299b32d263aad8af6eeb3a69ba56790fe8d6abe3935e8f487aec3205a856b4a8ee7f53b8f82a30d14ceb726be4196d7b6619b0e8a8870bba6070e3354583d182fb5f6f9938ab2ca68d5d719fdb472a88384f0fe1b1dff785367dedfc840979ab758479516d64b7a7e426e7daf9a95e7d585dc8b67d4f0cf182bc45a4fa9b4fb9541493c3dfb88fca757eccc5df1a9ccedacd46f47d62e3879e13958bcf063041e858811bd5779df76d2ca12b3d7f522fe7fe6f656158761767431948fa4b0dce5e3bcfc5ecb5b48e6134aed650a469ac663f7a4a742ddb87c4e5be647fe3881cf4647db1cbb8adaab6bb7f1e85e1f95c945bb002bdf10cf56f326b35051b8dbe95f45f9bc6d973b39afb3a3ba6e50196fb4caabd0d55693d3de390f48fb86ee99067e985764be7373a7fc4bbd5f8fb3105f595be5b6c2c8b5b5931830f8bd7ac7a40fb446ea756463c396eef9d0fdba2569b9002ee69f7d8f4c8b4fd314ae5b78fbd530d48678373453f4e309ea06a4c9f7ca447d639e635257cb0934e016ce937f732c1bba2c13591ccf4add16960b33d34771ddd984a8fc8036772c3b7c68fe261387ae545e29a89f1a28eec991d3161a95ebe16c0e1af8555dc3598cac2d80ea98daf49801a4bb10379a6cf9a1a3facb6f6c3d14d639fa98fa7297c6d453e35587488576db9cbff9d1c37f836dcba3ba90e4b779867ad97ebd3000e5ecfe3470d3cf5d65ed5ca287a9e1cd39c3afb72aecbc636dd5aaf68d61cd5d72fd2ec336cb8285b42ad43bf58949d05deef5937bfeeaf33de74e8fb463d03449ba747e92a79a1eac8dfdf47aa0a50822ae6ad4c9f534adfa24684d55fa71df461afee5cdedfe8566ee1278fb4867c6cc27c43bf835432cca18494db85886a5da7dea05e5f7fa7e5151dc401e9baad04ede2b8642313c296df8587b3f7c42cf4da18967a74f6663642dcf389c50892d6847718365cbbbb80724ce397c9d448be97842c96a24ebf6ce3e7c01fbb64c664fd237e886a9f7943e3abbe5f668c91c81e49c4c9db36be47f7c34b8ab6948799897855b22293d50c1e3d64b6daac739948844a9f99c449efec4154f5d77560671cf98f493d8a2ef8ab1665d824ed2b1c8e67a5da68255b7f9376333becd7c6630bcd5ae8def7fa7acc35e640ea4f85e78661b16bf1685a36c889a8cc99dce53c36ef23c2f17cbd8d3e351beba827949f8707a05324abf05aa71857bcbe79d405bbd030e648fcd3bfc1ffae2d6f7e04f490bc3ba237059aba3d85df2e802afd56b0f57abd44f170f5b16ebd69073a3c16cbec0bda5136a5f91acffac477ac2499f37cbd869656614e4ac249cdd3799c761b2ba5f38eeb25bde419c88937dc4ce745acc16c796f1ef3a52f8ec623a2a5ed59b80b72bfbe329dafd4b6555b0b6fc14efdb19b5ae57bca98519db428dba8587b53ca37e4b2fcfa04e3d6b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4 +public_key = 4da6dc98359f5719b20dca6d1e39e6f38f9e73f79b55b468170b64f2f8b0c78879690ec8ec244e1973c7e033b7694e4c55d4307abf711bda630e678b184a70dd26ec4dabbcb92cd7fb634621de450664a444f8fd23ada4f54ac6c8ddfd752fdb2dffd5fe49a139b9c8194341f4295ef126b37f4bf2e35792a8853b60eb3f7fede31459ec455e47097da5ea6bed2354f019ccedef547fb8935ecbeba0844ff8b8d7bf2a4aca52436a3f993f6164666ebb3c393e7bf5b48cc728fc00d58d4a095d0fd4c60f5ff9e788d3c4f38f22464c7b4f59e45ac71e8ccde6e5738dcc798777317f9847f8357dcf2eb24ae462d0465f1d68f03f3b8590d88deb9c6df58ffa152da9ea18e3ec3777a6dbe1cb0f71292b6c662a870c39f291164004299c8254fa8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c063f03f265bac5fdeee2c95a5a6df8a87c3333785e1b89ff94ea6aa5aa964f3a853f5e2acabb60e29c3a59eddf33830135cde49bc5e1bb4eb07b671e1ba6bfdb8f5774d6e6da854920a46914c8ea986b1d7ad328d4a4510cdce698b9d16954aaa0c52b7ffb5ff7b5347e84c3a04d4e9c3eec29df38cd5af96f5c6f0d3644ac5e71707f65ad6551f44378294778937cc56c6e06817d4bfb37e3cdcd7c5276777e37f376f3ded9ff5388c3a5a2c7026eb902c73f60def7ffe657bce34a47db43667c9f93e04ab9677b6febdb0a429a4435a9f5624628a3cd7bbfa8afed562bf4f3301a5f4e67cae6f955226437433bc59835561c57fd71ac38059ce45788cf42d4b6dc065e70685e9098f792ea49726dc8b2cb638763784d4cf3e189ec93a55383a8c4b59643626f8948e2f8b6713e2893ab3ce6be2350eb1b24432545889d5eef4d2b846071ce663b87a3475c01adc4f4eff86fd9ec76c0e8c05b5a26a696df86c4b1fcbfed315dcc9b54ca2786839f854b956e655a7ffe21c3c990d7a693a4d0b8aafa3ab73f1d4e1dd283cce59528477b6e089847ce6518f29b5247dff80ac573628d70bca649efb84fc3947d44bf29e05682914c1548d9521ec9b7978a6bd667f5abe8f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734efe8a218c5bacb364c9136b8e055053567a1856c21b96a1a37f3913c98cc364bbd1fc4edef37e1853c5247f7a6c677ca4d8fac4d49239eeb60c1531d1dc9835c4a96124a0012cd9350353aac4568a94f93e8666f70e6e56c38371489eddbb3df3e53e6767bd02ef31ec2fff13f59a83a35101844ab389954f8d68f6e7e28c738ac1774edc6465eae8ccbabcbb4137e467d4d7d379f8d9f3e74c99665e3a9af00cec2733925b254a3acad50ec3925dabc5124f7c0b2930bca63ba86f9367ceba620cc0d719d752157b5e7dc098745e37db7316056c7bb37c035ff6436ed7da8ba0e9d3de260675303ea017f5da0f1dc0543f677ec851ebee4f594a55d07392c23a962248ccef2ff1ffbfc8f90e86099fb33f0ff57c9dee5ff55ba97675a81d37fd13313394d050b8b7925ef5e9e3d165847319fbee494dd5ca0bb8338b75eee6e8c484d8d036dde0be52774da149ff9e64f65fcafc59a97e5a8126830024767009bad41a3386dde73bf5ea35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947 +public_key = b49b9264faafe83ec0dee965aca8e966af8ff907ceabac477e2c9b6dc95aafbd531cbcb65d8b3f635ebe17ecaa89a5b57d1e98ea66af1f4461b91c360e4531c4d492698961080edfd20ed80e68cddb2a4e06c387f41f6087b7ea367af50b55dbe1567dc957bbd034b66ab65fd4eab2d89b8481fcf427a4af3c1b861c799263f492789d53a11f8508c86ebe7fd1c876bbe8ab8053b790324d47a2adeca03f7208cfe30be5bce95d4bb048e7a48d975ce8efe1cd416986a7b75ae6a31e46636abe4d3bfc5d2ff3d49f65a6845804d49e5f26dabfe3ca21a345b6dd44afa5636c37b977ff894869bf460dc62ae9941b9b3c3f6d64fec351278f43fd75bf287cae8aaa9aae0cedfcbed32bdf623b6f39a7f834a58f6f8623fb59bbf4efc9c57cba929a64ba9037eb987bc08b9e3299aee650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348d6d63afbdbcef9d66028b3340bae47b09c4285fcfd6d491ffa497e17ab6c17f6aefe59c2577764a1a996fd879e59cf3f2cdac9e9372b4fdbe42d8f9b8bd9acc8ffe3189a2b3f7f124895ccab565dae583c6c76c35cfc007556837963986a3f5f6f9fe0c9ea2d52ddb2f4aa6486b756ce5f1e1b781a964a21b9bdc72637a2f4f99fe15c1ac275fb077cf42f36453e7603d9ea649ed9cc01f8ed188639c7f47584b333003a2175bc5889f5111654f2478dc540b32644bd35ff38bb45987865f4504ebcb26163d513867d74744c8b562bd48989b3a328374a125dad5faa6fac09bdd22277e589fd6a165a9e3e3ea084b4492c664448aa62986b55fe8c84218e6a5a9c035644f592969fd0951b6e9aa583d3d1fa9f7ff6b3dea9f63e3feecd93e7cfc899a467d6746e9850a2fb9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc66f85e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38d8d7f7274708bad587f94a117d89a99694fd6f7291d3dfd7bd430eca692db54a970e9eaf89635cf54f579a63058d70b703fed2d3fa19efb7e95dd3455efe9dc5943bf3af11b4aa6d3f8499da7c220670959af2bffc89b90dda1c8665b76d5571d8a1b5c934ce4686c8cd47af4e6bc6e39b7ccc92cb076dea5dd1385fe7e9b8820354351cb377b5fd6b7fbb69f64c7b48f781dfdfcfee998718d875eb94866e7c5135358ea4ec92849978438c77cfceba1803bf9933c8856657c963e25eb76014bacca8ec9be639d93623dd167be87e1463e55cae3ad85e96f8ebc584f20bbdcd374aa1f657abea849259b4431f2ad0ee59b35486beb0a3d2c07eb4c2e840963333b4a3be3708d58e4fa0f67c886de9b4771e5554a5f48ad4c587577d45775f52135518793ea14582bf153c753edc36c9f51609a4b28559ade5a93203725a475971c9fbeb88a69357bf83f384577cc1dfc6fc70fc65411d73c67a66af878fda6ebacf46c633e7cac0f5d92458cbba0c3b69494c4c1cdda70f5cd75e6c1ab89b3216bb9cbef3050d515646e0251974a1ceebe729d5056ffa128ca3107938f6be8e454eb52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb1204dbca7ecb4766e0a0e6c546998dafe5c2ed95fd7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = 17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb +public_key = bca6f53577fa8d77c9eaf9726dcea8b8d87d62be461f33b7f7f5a003a8657297cd1013f4fea561ba879ffa85f87d9a838275734593abc2b842d9353906334d3fa3f4c8eddeed794c794ed421db45cab6900817348d67490cfe485e85a3e0af556959e5d286ab5243b62d3a91f8493f0b19626fb89c0caed9c7fed84bd8c849cd6b357fa65a2646dd89be2eaffa0d2c5e816652c826854ab36f458d9ee56c9f7e26a1dd3d823535997a15f55756704bbed29b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e61fb1c767347bef8ae056d76d3de79d0977d2d54a3f78add2ec6bc16d71d9447f056e8470bea5e91a76021f42418fc2994a98d07aab29f8e8fd25e34de437c7fbc59469ce8bb8d545a4a5bf337fe24fb72f7dfd8a1b3009cc95975759ad48f74e234aef0552b8aa65cdfcac975495a85ce24f94f6a9c87d8ebd3ce49bd38274fcb9f3ece31db7757f4913bd9b16d88ae007ac464fc092f9bbedacf62e8f3d9d67e9b357821d5cf45f384fc923cd334b9dff579e325adbcfbcba61fb7ae9f69b3ab88694fdd5ef3fbd1a6a3caa5da2253ee2549ea060276b0734fa7a5d85d0098906969c421cbc47aef8fb5393b72590fd49edcdfa3cf87b9f7a4c6cc4ae791bee717478a5280a3b768dbbedf88f0dd7c1c09aa67d7bf84344d49398ba983bcbacb8c56237bc3efb3fbfdcb359bdd6457832df8ad1efd937e68b329968dcbe1c9f6aee65d22683b48fee4189adaab9e846b7717e4ebaf8d9a1dc76c388fdb55c25525343f6597466edfd6acb6f4fbf83f26e57ed836bdee5af4a8f1c5fbe359c61d974a4d57c2f7c49832f86ca37e16839b784d6782c13b606b87804cad969c7c47c8af9ce16cecff5514028c3d84944ec8cab4b4acb5b78e7246ee088ef5b8ae84f384ea2de6cc21e7a370b35c255c34556ff9645d4b420494c4d993ba4fd92ee34df1d36917544f0891acfca5fec361ca2186b563ed63456096227eaa738a33ab67df9977ce125dca7911e4aeb83aebdff71ed59bbc2e837740eb53d697cfabb4c6c4dbae19b6cece4f1a21d9f9cac7b71c749e61af005b3d179c393d5033cb4f8795de4c98e9e538fb9a8cb1654b1e6a8291847157d461f54cc71fba50deb3e132ec55ab6e6ae5f62e45fadb7a89ca04557a219dfb067d4ba6fe809b8cabfb3f5892ab46765cee838505879e8433fe2c91f373a1c6217ba890b4c5310f7b0d5e8f75b884aa9e4914c95d23ab53bea88ad438ea7f60ea87534ac1e8d6b0f8691eafebc728ed01053d15b49ecfbcd9b5fa88f840c63194632bd6ad12b34b5054eba08c879c44654f136cccbc7e14f7b409a0e6e0193cbbae635239f7df4b740b3ca5b32b741ea15a4747db98926a1f916e8f5235357f8d87443c93444803eeffbbdd5340c876d41f3ac1db59e9ffe7db71369a315600fc6801a544840cde5ad3766284a97cccf41ad73461f5bfa0f6645f04f880586fa6e57474d39f88404ad98fab63ae95e25436626bc66ef1dc01e65e035a7f88ad5f1b463886f8638339484563e9d3465e10b68bf7bc495d1b9f2192aea230a5f036c3c4bcd5ee36d9d0999ece368c01f037d8198d5a576e93a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key not reduced +entropy = fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176 +public_key = 2854ecc08ce8856568c40cdfdecd4175f564beae487896d8b71756367551a67d9127668efbe6db389877001b948f2c50cf6fc7ed73e22daa7c1889400b4e75ab959d09bbe24bfafc9d3659b8b4861e58feded950dbf57a47c87f79fbc144efd42004e7308ee963c47dcf7b8ea7faa329d6a7107ded3a2be5a799d8059e7c84477d9509e7a386ee3d94a0b0d69d9b7c39692b7f4acb9091f875849edccf67bdf86c4be9fd8763ffc3428646a3d33df4b67eb88af662353a2094d3bf59334bd9758a9439f8d8bdd55e95f2255282a73457de68a3bf49e9de80d5c3e0bb8f8685b3a1dacaffb88783bc5d62c13b79c3bdc3a20d85664377eadbb4783f9568eee5899fd8595db956a7f48d6f71f44988218777d348f3ae7d791be4de2a8f5ed124b964ed5d06547c740a5ab8ae488e38c464b53b700e6ba1b7648a14aaa21e907846c5df26ff61cc627473869167f4a4bd54e868bc04c934d64b7f2ff461aae980fb8d6cca7a9c4e7f55564b420887946f7a72e5de384e9ff2c70330b0acd8d9b7daa176529f0685d087b8f9eb464a776f946d6b06dd72a0dfafa7969eec2662ebb7c7fd9fed6b5393707acf26cdc2c827d2cb195f8cf730e8a46442f9ee18fc7577f4aafd6933450491ee24763bf6786d794d889c3005b3f3cfffa8863c7ae00998d2e3ccc1f5a6c8a933d5e6e5cf8faf312990969c6288b6893d5fe42ad87ab48336256eb87c74ef6474e0ef5b393293f3032da3483d397188920b6873f16478331cb22a6afc73273d865985534aef8f1d9dbdf7e9c10c8ed87a831ab6556285eebcbe5d3d5b6e01f78db26a54e47943d6c3ef916a552fedea39f96dff92d765d6ae52265010545162e5d9f6ac3f9b8cdfd0ecad4008732d6a9df9449b2017b38a6fff1197d7051f7bc7ede8e0b4f0dd54eebf636c31b3b63da9c00ece5be0c3e8847ebbc865f54217b99294815d88e94fdabcd1a7de31e38d37b4b1cc69bf4295e4f50ac9bcca9125e6473028571be535fdaf74651752dac691ff9af8c565d36378b260acb060faba9573b0b65cbc76b892435f94d65658f5aeb3309b424c6865bf1ab307b88022087f97f6882d4360ece9ef3d35e3059a784cbf56e47670afd5c1ad6ce7724fa2956bd830ddb546577ca5286e0f1c85af9bdbd575d0396d9e8ec8344e6ccb6df93a056644cb99f950ae9266948e9a66ebfa66517baddb67f6be5efb853d7d3ccb5af96a493c256d7a6ac4a74946ed8f738080b8dca62aaf658b6a972894e6ca402af3c09d2a6e9c28e006edc4d193361869d11173bc8b977560eed85c5f808373b29733a7d0488c5f99d364abb97179f0c074645bfdf3679bc9c2b3ad29c9d51a94a124a43689bed27c35b90fa3d3664aa37ab9f284f97dbcc7ad101fb5b6ba38ce1ad7141ee0518c74ea36ca6d6a44399a39842de45809f7e0bb3357bac5a294446463814806ad1633e85f295d28ffc913c9608324e74b2bb8bc03a92db6cc6f044d964a7e3e289ea9fd64d9b5c0d0eb43357495d0acdfbd4d69903bcdc683763bc4c6adcf517b7c94e4fdf65029bff55773421bc6143a38f584e0bfc5dbf21bafec948548a87667d95439bb78cdafc9da77dbeb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = e7aa41194214caa340115002a25d547f794ea33200dc8a9ee0fd033e181ac23a +public_key = a9278597d0c32b74436bb246e27291976c4459690d0bf64f44456f48859517969ef6a65c95e55f3140542e7204cc1370b4354054678ffd7789b03c81ce0759f89155bbe210e3c730df30b6b8d6c5903650bb2674d9ac3bbe909743f54b624c9ef7c9722acc168b332b32e1b937fa8dc2fc3c28b8cc6eb43bbcf5828c0aa415a7202cc3b3aadcb093003a1ff8a3d4f96fe239cc4dec7aa635533e48053b77c6c649a312cc5067441bb8d97af2062758e02978db44dd3170d7d143a91866f79a42e2e097aa66255c15007b7659c0408a8f4c93fcc490ad119859d21d84b1a2f8108054e7bfc37a0cdcf7b2be9973f7336769e849c05767ab71bcfe8420ceb3227afab3e9d764e3f328991cb42a90119f2b1aa95a725ef3869690026d744e7298a48be948d1b65232d54444b67c53d27a4d128db9563376c94b92cbc443992426f160ebd51ac3a2bf445700abac99f1a09e8855398a8c6b580abc335b7461aaa5a664b4039b10c15391c160885f3495d291cf7f854be2f455ac3b05d8c385d86749aaf1c6a61851910378e1f402e7f2b1b4c6b344856fc51c3a41f429a7db6a0703a0f078130b4592fc59c8db156112e13e9ef85ae6cc20bb932faecb5bde57795e3163fd +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 7e2a93bb6dda4ddb1003e9a868447d77a5ea223ab645f9f6d4dffbbefa5c8a0d +public_key = 596b2651851c8bbb4af78d0d934b6b57b6f58054708a7a71f0962c9530fc5bcb11a62b3f740be7d15264a168840ab984c390dfaaca03c38ce580660deb8286da090dc845af7a63f691871a17540b582033cc6195d2664f5359e0201ad0c941c7610a9c7714d0522877fc36a5772aa7492f8a061fef6288253746c0a98338c038a0868d249392b62a8107385536a1c74d1a4bca0841d88677f5328b692cc1f478a3d98a32f3b5a48971bd224241dfb67f714caded6bc19026a709e87fba8265f11c78f3b7c9e406021eb83204558065e4cfc45289b0a1a383eb23bdc73d567529f8e369b364ae9438c5b89c53d55b3cad61a48971c6 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 76bed69c7b1f6011885373da211145cb9264b5a50134a51354c2a8f5be06db37 +public_key = 77b951081b67da7e7c32a0619a473b5758f6fa0e5b21bcf338a80cf7cf5798c79a7085e3a6c13ea99b2c894419785afe9b005a152924fc4257105011c770ceeb88a2bb90dac14949f64bfd25258262b8f3331d508288ca6cbce219b69487c805bb133ec66a10461276c486ccd8b5eb0387d4a419b91634e69152ee9888163549cf7cb945a2732cd7b341078e8a97996064ba3a54175045c64401d04eb25e4a539a82b39ce29b8d1ddccab74ba31f28c68c211f3e03107c066994681e3a80a6d82a487ed24366fa79789a42 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 6d1edc7be0c8f9ff8b1ca62eca9cc77d6337066c91b9ac04766c9cc833e03ba9 +public_key = d753fa68a8a2e2848de7520d9b72a5f63ffcb014c7f8c7ab08c3b925729c2b2893b322ec81c1ff4963c0e644353a05ec16ce3cb025a6ab283f7ba802622a7b6c20f63121263b6d6f5abb20eb18d86a7936f8c0c5f56a555198d693bab1b822811a322d98b4e6656b4693cf1db390df7353e23a28a801110b77cb3e920739abc7b8451463e90ca7e7801e74a04de31eaf9bcd3a0708b93b66d9d31298d7b5bf086e297006853345b59ca0d5955681c2916b4bc1580c35d3a5ae0e2056f705252520b0b1842b97821aa5fc50660629 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 7625b3ef9c0efebbad28dc6b15aca34bfdc4f2b93e8ecbac8a432061452dc364 +public_key = 83096750a176355355151614848711af1cc83c5b2a7aa78262c6d10205657078e78481e812e2812b9658029b928a537676f5324dc0355f36184037d798bef4c1046469d7914f7bb647a2d50a4c366231385c6ef661df6c16aa15327a787b115a4e165c41c98052457888d9a1866a293f7fb05ac6a81410e50b61729ad6b9024630a46d0b5a4aca0b4b610c39094b9e6a91deaa4531792a844441636568d1b005aa483cd251b92d1cb2afd620c7086e619c18e97b6df7798c27934126aa23116c5bb1ba8768976e870777e8b17f370887dce67ff99647ed634ee4398e93e26e7b30c2f6628af1658854391b23f993219974fa9b0019e4b9a9b1972949497eb076a6f603d2031fd5c520449576bd13ac8c1a39e4e2cdc5b11d371b803dd22b2f557f79ccbbf10c0e6858c13407496a1974ae599232a424b8707ccf350b197ac6215a42f9f52ccf5c5cf7965da25047ba190b472164dd7c9b3206696ee47dd93baa8ef3159b1130aebc6d5c6a60d2fc0ecb66aee0a2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = d1f36787c6e759092521de965f09bda02bd60d990b3fb221b236c60c57264c12 +public_key = 39bb5c9e62566a368ba98f90c5ba5c3178b0291f8020e49b1a82f143083258e48b713007906586796d064d167a56a6364ed5742db8063e332894eb55a020e85faa603a372c8dcadb693b224f0cda13df7432acd3823f448bc8144796b57748937cd469087653023ad32ca7a731e90a8263d38bb7ec42690107cbf136c85acc26a2aa0603b168e64e81ab224474b5ef53b2a0e1c093c742aadca876e13cdf5c420b43757e543b7692cc97c3202499b985f9cfd3d87c7de6a3e09b9b07d1088ab38f8a9a87ce27a4ab567b4574cc95e67587b8a68ad80f08e60594512e4dc87e45eb63465953f5065491961dc66398 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = e38e66918ad06c6b64df3eb7c2c64e39f23db5ac2c81539e42bb983459df95e0 +public_key = 90ad188208b84f43f59a56838ae06847081490b4245c0ce2a2f0288a7c084af2d4134d78487a63a22c21311db23433cc8e60a7cdbd2cb6d1b2cfa341a8ee9514ea63a02a09a9bb595a45ec86ce995fa441977172983efa37fdc82890e4bf7ed8b4f6bb10c4d899ef4a72f414a92385650d3cb4b9518a857b24b916c4b2a71c8655856b7a96bee4bef6f50dc2d093a1322cc33610390a919ee14f6104957988025d480dae65c202da5b22258af89349e3ec6b48472920b7af04202cdf694881b33660926666e91f2528cc4de3ca34a32df5c938fd04065d2a6de6b03b23eb835e79b66bd68b9a48c87a245e72ccbda435873ada060cc940b327b24bc15a840605339719ba569f7b21c35ab7273209b77e9749a90a0f6b20631fe90bc07167cc658bc8da933cb9425d6b5bb6c67888255037a26fd592724ff1474800635712cf21901a99ebacdec07689440a3072be6b1abc19096834344ba965844a4518176011b9b217541103e10580c119460cf57b9c006c8e2a1df95604d869389c77225fd63f65f3c692364571395d3502798df5b0d3e719275b215a8893109196b5d507c4b904b3b029c288a64b1657049b391e4842e2e8befe22310030c4 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 2ab0bfab14e3287e1512f002927672c6229b6adbf1c8f31b72ee90dc4f96a584 +public_key = fe19b4cc2786453b3a7d088e391859cb9b741e1b4a551a4b7b821850229b9aa955ee4686b27a4e31021114c812c7398030965f8c0b1820f1489eb343028454cc8c9e735a7320a0a0b44c43d8d79b0ec61593dbb0ccf9356f9566bc21b5e1473e2aa2658ad382f3034c25112e50f8613632641536ce6db3543a90cb38f2 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 548c87eda498c4033938de91e98c50e3f370a74abbc9fa15571e7a3e091c541e +public_key = b4c64512b6bc6df9c7601fbc2ea6170e93912d7b6c7101f5317ef06134e34f224873c042a1b566432f0849af1bae8adb6561a778d2260495d11fed1c1f327ba2f0 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too short +entropy = 48db851ec75fb465cf42c6822abd73405a1d5ccb6b37227aecfba9b8a25369b3 +public_key = 547771c4c1bfd844d72b034765ac858364928024b86045df37bb1ce34b9d097f932b5263d2ce5d25140d8b481a48b9222b22524cb03c981576d477fed73098b058d7f58de050112b98ca56589a4bf686b2f73ab5180089672607abb833d2a9a176696ef72d9de8343cc5c6e5da8d51a2216ce0745fb084ed875324d9419dc35d99c69f461c6d39fc93fe363678d343bda7cdfa416fb5528d6be008ac94b890e48672d540fdc6b46e06cafb4b213a17884f687678e99a637732c856a388a2bc79298a14496449a274aa9cb9c08531868aad2fcc6242795c0050990b752ac15668560b658ca385624248110416a2625f92050c5d16931d079c76e82723c03baf46b91bb082169a7a21047ae6c55ca4b527c98b2f0213597e97cc64887028faa548ac24285c5e9a535b473593e96b3e18f7bd69d354366b402da733486620a4248b87442a647a0a7522c307c933c4fc66b4123a0d3465d9a06a16a20080ecbc1e100c6c90b0a38a609b722e85186611752b2355a0e7fa298f562acda8408ae3177a4993dc0863b05180ac915ae1d4393a197cd11430433541889655166594f164bec86751ffcb916e0075ef517d387574e7709ad9ba5260192e0b147105a18bd18c5700506fe382692d544278e2ba2922869478435255bd8530c398417adc301be923c63ae53cbfd13159cc368e4c99fc24b509f880593964f5650da53a8fcd776bf9722e364b2ac431a1d1ab6b1efa266738cca6c514c8ba32e2f4b137127d5834194a6413602b22fb17a81f82bb580613e8390d20879b56e1b17896a22150cfb23b205b68b661a52d54b6c353305a2870052f30a21f5955493a61af129c72d1a56980162b9caf94f42f80d1453655699182805be506e56c0c6d8081c3c4a37fec15efd413f8cc29e3772c88e68bed981457f59ab1899acc3a386ce145d246adc7509a2ed645aa536903b5bfab4b5997db1cc31826fef7abca0919b0e013ed497ccdbb4ce2635fff4c5f0d59ad193b2e61ea90fd95cc21519fbb1cb47da973dd04bc46b2094d0058811abc016486d3e72295b5b496692d65f916df48517f477473159d84bbb07eea8d447b2b9bd246a73326760916fd890e35f05489b1af973ca5f9ccc2c8a26edaa145a55980ed79c19d680e74400ae8c241d0681152f2128e7712af916e87ba118825bdbcf4999f2889fef1c76afa4f40052a3463ac3402ce7fe394ca2b506981204f21be971c1bb75744c61054c0fb2453f76deac45b5e5cb902a9a5a9175cfcab87e6d135306b20ac +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = b8ee47bdbafd6beed55b1e018c6675c0e91912f727baa6e2588b2506b92da3b8 +public_key = 5d0062ad244abe3b3a72c524a6c16372c86aabd585e73b712c06392849b5e43b0d2c8670ec604dc9230ceb2767e9f32d5dc11033a774c257031f238dc3711edf07633ba794bbe2c9aa650bb8e4818089a8c02170fa58a51fb82bf2e29afc5bad08038526f23f3742a192daa8f19198bb369811c23f30568b11a9c749171e3b389e3375b7ef6b1ccce09ce02185ec612833422f78869683352c7694795a5412c880685f72be06acb409b8980d7b2b9f220d1b04665f3623d4d97110eb55ea9266e985ce1bb85ebc5c6acbe4149963b8eac16f809a27ce565a4901758d30765ab674c7d4cc701a3346d24bf9c83069d778ed28c19bb21c355814a4b41ac4b514e98c3bf8aa9135c650edcc51dae8b81da827a07c70dec5ad994206f77a203d3c67ebe46edb4418d5fb05fac7c02e13c475647b9c55af5ff7af890510e3bc75b74c090291bcb5f6777aa51067b44b6a045a6af207812aabcaa33b1c63588d4069d849b35e16c56c966299ea2b4b7376ab1bb1b2db4430b838bd530493e77842393c60789b17803b0f173dc52197fd35a6aba77c3d3b77ab697cdf1a05e7d9c6f5d82a2457aa22f2b07926006a75217e5b9fd7a66dbf4472eef641eb70a9478899e793ab360b368a1278c34a920d97800474ad29cb790f127d6b6127fcd384bed26f158725748307659731315c690194a29e91722bdb6c829118c9a0389cd2a74b66898a698f1da84c24342eb0aa994125536f010935a90be97a3af5846cc00c8ad7994719c0a3cd478c150ab781782513ba417df33084cabf81cb4614990df074330c7aca6952401b2930ec28787246444c33a03474ce5e497c1c01a55ac2a3802a9efea48117450e63ba3de7c5a99a3aae86c0a0eb486a0aeb8d8161696449a10b79b88ff8bcb1bc29ddd59d8a4c71d10abf44f68c0c9b8cc1783501d236aeab975d000219240383d7484c0563f00b53876178cc5577ee3740d0e1b9bde97d4d8140f311165fb30f1982538dd30052722b54848ce461420f6bad21a9300ed408eb180294586019156060ea8ad2c6a4d5789cd5d9a48a9ca45aeb10c7832455aa5ef1b3797b14968a51032143c785db2b4c1c73ac6069fff324e69699966083c3448fe8530b4b63cb7f28977b201835081286704a80c357d9d0a8d2ba75c74601ce602dc6b58fbea07607b61985d599cc174644da260f214789f01ba089a741592b8221656cc76dc3656c19183d4fab72c7440040f198e80178fac10623e63a0b587daed75141a718bc4b81e84ca0ab061262b875a3160beccc4ff335ab4e58890dc269d5f33e55773a139b7bfef850502cac669435d17a17e36935f50197bf358acf97c026da64bd6039efdccc050a1caa322484ca8ebd11875f2878bef1338c7c6e78158eeba40d04956ab4912b5a103628eaa464e4cc9bac08274b5dc0bc741052629e822a42ab7f9f380016c530d3c233d1015927aa9bd521ae11a5af908204210413e9cb004562a974b016655bccb3e7a3c91b1518e92d55cc7e73e977e9736a34705ad217701390972aa15ef2890eaca90e10e3089853533b45c1dfd624f1f78cfdd88ee0f7bac8f359507481e5a48d5a20432ce374f8b9be0b39432a376ec5f44e3d641b1b7b3849aefb66bd91e3db9984d538db503fc8057e4291bbd177cfb1b97069ba3e6603ba2de033 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 1275309a0e52464d441f3cabcbe2b27fbbd8bbb981a87b526174a834aa52af00 +public_key = 4e491344d49efe772863ec7cbc8861629a6a49b771779c8e51b02b66675e7e4c01200734cfe61b01bc6dbe3bc1417442b082ba90c009a997c045e5b1b5c41aa72a7fa8c9c90bc3006d91a9ed031d8e443fbd7b8686d4bcba416bb7995c9248b114198857a8059fb111e53009160acbce8aa7d6d40b43ac8ae9caa1e9d0547586bf54ab15118a91f976682dc910b1b64f49247e142607f7c06cd98b6a670aad00ecafffc51fbaa806b4c74165516b8aa1523c526f5b19c61ddcc64870b12bf291ccd8467fe593d5458424a75af9e5cde79ac7f934722a6a63545a1e72b831a7a27a15d8062be2ca91f803f7d146d6e9c27bab87321c7c4ab58c305049ba021413292b0cf38b7e27a2592b4771ac6edba6198b357775615ee8a2aaf927330a3618ed59773d98ad1b0b104f67641afb8e46ca51c682a26f3b796410655dc78c775b9768d9ade68a6dccd94206410b4252c65a2b791793343dc293c0695e9c9c7cde442a8eebcb2e7336358aba6ffb31ff9343ada2b71d96c69e744cef8b5844a48e55928db6ab579e9a4b59087663d9a1918639c4395ad877312c000ec3bc7ed693b5b03a32c68818fd1b8c32807bdf24bd34746d33e4be2c637325eb1b71376542782640f0467e22404e00615555a8297b286fe5708ca2c0fb5cbe18e62218711a74851037d412ac6a73d1d47d10812418a6950f71928614141d2715395008158605fc898b58f36c87db133657868013c59fc730010b79bf0cc22af72682314bfebcbbf1f4336f216ba81280d954c4c034615c25636d95782704b2acd5997758560cc209dc4b25484cc29ceb856aca342cab436cb354f6ba8bbef9ab7ee1a93c40312f4184603a012855bd00c8b55bab4122f6b687a62ae7b09852d9ba00e6be8799703f886959e472e8e1a54d479b74c13a596b4ec9c9226ee0690875865d2a99a715a1497354aa0952ec8411a32b5c95c2761b9961f960c9e47246e974176720cc11863be1a9c9fec97450197e89e077dd805044a669bb725815312e3a1b8643574dae1b27c63593591a3beaa05d1de6631b160d3f3a001e39387f45c300e8001a6c07485729e98c60ea3a5f0034ca8220002a5ca59de27601477cdd51cf9bb59071e92563003b88e20cdb0a619a37442bd121fbb86fcc5b787c52c3c5a6a9b42867d9f68f38e044733b0ea59c15ffc78de0c57df6aac61aa96f133a59a48969874561e7b60d2433790ad2666e691531479c7478a3b7a28530013e1cd4c5a30bc1041299a1989f0d32a690e46900655218485dc4266ef70ac863b8126423c1936a1174070326949b8315b8e741b45601471a350d103586ca34476ae385808c43eb58089631c8cdb2b906731da6f47ab7aa59c9273fddabbe49a65409618d7ad043e48b7e22c974fe124701839a8e56be77f51715e2410a8c95fad86426b59f18737612bc91d822911737c8daa61c5f816d969081029982c6f7c217627defa67f66e53ef1d24a6727b4bccaa659878c0f3743edbc0cc02bce335867900898a31a4b901738bb817b04a34dc962c27684c343b44d2b8c0edff0c915682dc5c42a352c538d4bca11a9911404bdf79a73c8349d4eb73f8b394cb15c5426fcb9828404ec5dc350611e37ed85478252bcd3ca37458ed350a3677a495fe2e516055ea54cfa88a8c392ad4e83d10ba209b1e048d45cb12cf0dd3d4fb34beef58f44164693 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 7a7bb5b36c93d5c628d54563f043e40c1207bc6ac593fb52888dfca29203b166 +public_key = 8316b7e641c7a6117a817113ad41a753c859c7d8563eab9fabf70f13263d20899b09a068858474101935a5d9c7c3d9777b045bb90c925040755ef38bf2bcaadfcb6ab43ac97743a090c71d20fa6ea817833dd5c6bb337998a7435757501f1396849b4d3e32907696bd562729a4c8cba6bb4ec884b57a5c90449372af68aec9a8b77d85187dfa5eb4e90ae04c03056784f815648045ac8ed2946886bc715285d5b37805e41cd15916681b7a3e06436ab881f3a08bfd66ad54cc79a9ec0ab1072add62a105b15f48a15750d78864218321704f69ec387c76b52e562a28ab5974d9607ba09df3744e59b8c05ea29fcc466053988512059191236b6f0a7935a87d74825436825be6c8769ec59ec1c8087382be48a0388d6c56240143eef1693b2b8906b0a041e07cad50602aabc1239714b655b894371b5d7425d6e59b9c629d2555281ea88d2f3b41b883c477c47c227a7c03215d1e456900f5574de37945b2ce52e0098c186a0fc96cec4c0de0450b3e8a65618190b8219121601c28c934e0cba4e6ebcebc857ae0b84223e289467844bf2624d9d031dba3586e7acd5f9261739caebaf634a30c2db1172fc64bb465153a2285b52f99978a076b7536311d06a18d589d979a7be8b45aace744cedc1ac6e04798d91773e769ba31151c584fe9abae840a53a58b8efe73c9c1f195727a641fd2b16a358e16f7097f151246c9c9aa1b4200d9854d9707fa95b01a30b15402375f73127aa90d0816ae780c923f5c2764060874b75b2b94463062a60871b6868172c596c18f140406fa78667c336310500e14a5aa3294e9d33b357a204a8ba0b477123d0498c7a549c20c2c01d29c1871bcee723ac5e51f558c295e258046ca8bd024553725a1ffa84c876271896bae7938c2de129f154331d09bc2a082144bd2af39e49c0b15ce77248bdaa45f27901a6426484cb711a221190246c5bc9334a0d79792607d7e30276eb936a4ccc4ad8596aa29671a353095f117ad420cb5f8bb44d63a121017a596141935b07f6a148d6a4c39c42b0ea71da5b514c7e58fe0d74646f94c286850c33303e5da76c385871150024f944ba6c3b8c9434ef17c58e46980bf650ed3f7190dc692c34bae36525ce03827bd914539e3ce4cb8898c43a78b1ca785d9ced63b044062b954657eca3271c984029b8bc753f142b5ec27effc5fdd99c3769766d1e76e4d50cfa06a8860e12cb03c1db4a25b37b3bb1f974a805b62e908bbce296445809a51d4189a7838a2967238eb5867c35f99c322537a6862686586d56b0765591b5a3f409bc0fd8a52c204befeabb6d56b430ce25414fc1f15c42b54e69ddbc6a36e1c3371a38589a4594c18676587ca07f0c9078597e2f472e92c63e4925d8eeb65b719ab69d25dd0963eafdbc3bd23cd83e6424cebb00270706317a7e2f8633f60396b946151b097aa433bc9e13a05250c0085af9c10c8790c4287d2b8e958be3535379a40cd253b559196ae7d7c3031f73b6c8002410a632d46be332b041c863cfe1a80fec2304c881bcd5282e9cc5129349b499705f115cca73b579969709629a1f34b43f39156cf485193b0173dba7ac13c6636693b2c848fe1565819ac9c48591d4645488c580d5994bb4f9bea102996d76bf89b87cb028dc6f998f431c943259dc90251ca6805a23266c3e3e99466e04be1526abd7ad99459f2b5bb8d8f +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 7cd774275c35da9c0788b0315ee68b8c6c5476ff2b1ab1b8b6db794518e080c2 +public_key = 32360f5accbf0d107f76ea906a4546d36586fbb422f2d40984733b45f55c8db84dd7aab3f0aaaf42c6bd5421a8f22c49d011612b8649a3384a5dab221af90a58a991d4a0aaf3e91db46c6ea326c107553890c6cb3d940dd95761649c8a9b192a1f182864ab2621c5c485ac03ab414d32d4c48c463dfa167ac72a036441c0bfd205bc676998c979731954ca2686bb17b07bf3458aa11bd9049265f49ce3e92a7b70762492b13f30699d76131a4bacbd007a72fa9c0cf53974c20fc864c4dce6817fb584ad88a5eae3a3dd434235da64bf3107c097b10445bf8c72760a93a4c786099a77b3f7fc319899ba1ef473765345d0a10c9e64af960307b6d503a151239dd79707d379f91563c13b378d6575f22180fdd22bb5394883e4210900c9cab99c26510dba4680ccf3a7c6864139c0aaf8a710190b667b386860c82e63425a1b0863043bcae2b630ed802b26e22854ac6d0ef77f2a3194e79bc4309c864ca99235684aa8a60fe095343f50202f950441d587b34b930a824f06a20b78bc8ef888628d81620f1143f9352ef4831c73f6828935c81ea95d886bba2ba06b3aa34879caa4aa177c096498551a9cea5047427c6075919f9c145d7700652b4c828ada4764c956f7dc965dfcbb048a09e5e704b0605cc7161406c0b2e384aa39f6cd2001a9bcb12b1a683643620a765a29736372e64c084ff609e0dcadb367b69ec64da11ba469585d003bb41ca48ef6d3c9f3d4bd6efac805c188dbfc95c7514313820000b21fafba9c70533e03b27d0bfc9695c419ca311248037f96aa8a9fa3c5a77368f5f8617763a8b5a17c6206922b2524750488b347418267c14169673d5a1f6a1218c8e8a234305b2371429e483ef66622595a81e4baae5d8c3e94b1c85e602e6b412890f2cc14892f97eab851a8214912580c176554c005d81a9fe79c99db1bb286659c97498701d546fa8cbcbbf98bf90037abc51ecb404ff1272d7f09afaae5943542181906c5e095bc135201c797cad99c69d74c3ef287a321b09e17700c42a574ace85138f72fc2418a8f4b9aaab5961c6b622ebb6938b7b0143aab18271a3fe2bcc638c9dad0650a0053dea7c32ff07a0f821e3af5b671216b2b2a764b56444be3b196017f723567cb2998a9626633727433a2126e07c717119f8cc3064c028d3e266af186346046bc13083d509b4655896e9af508621544970a034be202130c8ac52b18418b9315c5cf0874761e4132b8fb4e55d4beaed18b70e8812ce98cbdb633ddb2b5da7670ace03150174963f741ddec2dd499a497975891c0658bd36419db478acc982b893c3cb55711b18829f2afe9e24d24f642befc089ea4108db57dbad107f7411f00c342cf759f3afa528da02fcfe785b5c98b706a4e942a3adf27c3e38155d2a694ecf07c7b7728a7369e66276ccfec254f64781c668d86bc29e8a3c5c975399a6b1114454a4bf75486811d94e2ad659a457546a2b7e094450477836c0e7fb7444102abbeb68e305cc661591ad1f3712e388384d51656622953054b60229ecc5133ec5c8028e42ce7d554c1921ef06c44e265ced9fc61383bc536d07eb528851956460cc0011c4c6372f6980bea0a9362a4d040816d506cf31030b20fccdd7ae031448370d9a1f07d21f6f8cf63793acb543d1a0d330ead1b3affde567268578fcc1c212e31b672924cb5ca045b91a67fe479c3f74a48 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 0e057f85c9ab97358b132d71fe786ce1dc78a7a2adca7c5a550a30e762f00f26 +public_key = e24b217a6472aa8424dc92029430a4e3b314181cbdcaa0732293a150701162c7bed76574fe86b383780fa5054cb3387aa3139565d330a1e6b5b9d5be6d5485c226bfc6537247c665f6b6a1de3489671bac0a30560ab30805307122e0837f39c0e8f275be6b5d5194413790786c5209997c0ebd6b888098b3ddd8057cbb24ae376231e29e87234b13076144e11076794d3804a81edc430de922b050b5e8d2aed5b25be1cb189504456ca22478c2bc94095b034549cc5ca518997143b3527d9aa5cf66187bea7b87173d712400dc330294a56ed9c32ea4c4712420137ec82a499b584e30b626506f7be9110be59a398610a82a167bfc71911337974c2af9138a28724d76084cb6171cba495d053463898c3f31d8c6b3d6a6c43574b9d1a5f62cc6939a68d693ce6553bab3a2878d690e172294d7009a4bfc1b7e42abc93b0c469b98c9d84c223b5c4a25790129c6aa1b4e225b9b00b005b1f68368a9496066821d55682d2913db598f7565c9c1e57bd0b27770e8a3703c3dccf48f38a46c2df73ae8c2983bf814aca09239628a737c56079543cb2289f1303936396a5f72825df3c3bc063b3c2b504b860dba38369eb0b69d9134c9fb08f3bbb04cd56f13d20b2f2a8dbc5c2579a235e2d1cca9c520e0d2b3fa52b5e329067614216e411b41c84fdd16881b5b083a40192e9b237044ce67f87c7e6c2c73204f4609b3e28acf30b31e38ca0d75a68448944ab595c1e12b3089a587eb346d4cf35369dba082da44a0a8c26f202b4e73be7b9c0ebdfb3ce6b692f78948e6f656dfe1a71e4584bc5a8180e22d9956356139acf17568db0a73824c3d390bc3b6c1a94618ce32974563471eb3711b86dbc1e1dc5ebf07716f492b576c25223043ac6706f89bcf4c5b0812d6a3cce4816c3a4343027c7ce968d1f4b0e01874deda9821245a372599ee29bbddf13f4e970e2b7c2597fb7072a57c31e36a4b4c5bc3844e9256ad0e3492ace30b9ecc6b7609c8349c56bee45211e72099056a5e161db37575bf1534692559d71930526704cee1bfff2bc4ad410ef88941a4d83271750c9698540f669638859c7ac350ad75a3d8794f0f12a2de5170fd5b1b61b28a5c8527f87411cacb8401d11eec98caf8772bff976f86d87c67f5ab912644e5d827c99261c56c323f666bc5f7624ef35c0d118614ba64c88b2d140c60848976a674ab8db7a4da0a06fca487dbf4c3f4924f77dcb69f152c8336ce1ab6007c8755434355e99b6f99b212a5762f998b693aaa5bb6c62593767cc4646d3b341628e371eeb7af34901121084cf7f341606a3d47cc7b83b0b440a0ba3f27c597210920a88c47525ca7f4b5c4471ef834983169784cd0671ae103c0e2494d37339dacb0d12c388acabb88f0a64567a1bf2926a0f164b536aeb0846dbc265fb10744d0ca87eb28bc1a6cb424fa9a70f390b7e4c05ba7b7f306867507431e38a2f9f424bf711228476705c78c005a67bbf8c0142c941ea56874c783b4703da13b3ce4f72fcce11c44929064a389da4982c384a64fb06b32d6186b92c11e7303b7236716c3073745302136bc4753b302b1cbf3eb1d30e56d08ca2eda5a734b34c990b25454c0cea91bb63bd6784f599e987c69715ccbb7a55022f94f2c75f671913c9a0cc385c444ad46659696fb9408844dd81c844f8d40b644b1 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 33c3399bfb3e20debf852c6ad6b90f4e7ef474319d55001486fd78757c5e050c +public_key = 00044255aa623931925023bd7be0b322a0a49bf48839477523cb285f3909360908c5a806ebd8a697d28166d14ca2b940a129aa37808efb0871f36c99a0b36aa5449c140a19b7625bcf4c7337c4206f6b5210d12c97f4aae6214c2f404e899a49ea74458a9980717953675004d8e1c796a7484766281821b34fb41b24809790ca3b2edc10d0329925411db681a23f654156a94e8482608c9c55b93809686149e8247a8eb61eaa46a00c6542954c40caa1a84a7514e4c2280bc1610159672eca600a17afb3270d0981441d1a90fb3407d238b7c9b00f4cb28be24c3d97d71ae576725e98208950b1b6b34c108352e3b28a85a458eed46ec785cee85745fdf186eed115edaa26ff188654aa4317fb265e2730776210f3f3000e63624a4aabefeb618cd5a133f125f9589c0efcce128ab7bf39c292040805e7cceaebb698fb176715c8554615595cc13417c086531581301fef291fc3da084e79bc14a7acaf1b511db929b7323b7a80086465c858868e02b72516301265e1cd90dc521208acd0f440ca5ab590c5a74366c763dc3242248d14c22e5265cdc7f5102a1c5f78a6746942b451d30a44775ca80c3fc2f7123378ae8fe9ab517839fd468e8c378ec958a8b63461225381a53059afb2c4f30cb0e8b62f0d997f3abb773ab2941ca85e2b88469dd78292bc73e0006ead96aa100abcadb4b432d49f200152bc1765a621151062741ac77c58515d5745aaa19cb32cf0215a148e96bb368d7c5e8abbc487e519f8dcbb2d82a7e5fc29e7422e6ea4124f607eb9303ba268591ce27a222bacf6417d568b327109991dc464c9d9a5081c14539775be160b88977feba69f48fcc2def3249523aa2126bd6781cdef757136886183d795c770a3ab8053125a916b877921b829e6a33b7e7c8215f1842fc644631aa6d47ac7000954e8830d566b5c55e93eb585259879621be48bfd013199b09f7789ce3986abe1d85a01328351f6766b446883b17aa29476d8064a5b536bfda6aa6304c20101519c10b15ac73b0ac6cbd2889509514a1df987215b8d5b6313dd591e59458ead82646477551d838ea91699e2996bce13283e725b50944585285e2cbb0c1468832c009ceae651701c76f3666ced69160866b1d8e95edadb575d2c01e0044020cb4a89317cbc9534cd8a15f57a2c930cb94f343d42113ffff33ba0eb1007ba3bee8a3df0d05c9f0660d53a8d446756afbb295b6282b66cb93af99b779624b491974af776a2a6c0c24038a11106b2c48bd2c8a43718b3e86a867672271b9c48c7a719d189a45dfa0823887deeb02b05e1574ce48ffbb3997a4c19b037bab0977b90995b4fdc357bba4c7b23a3525c6d04734c6ef2c909f2bd91fc7ba03921eae81cb30c8c41435d1fc6a6b2e695a7a1497aa82ad7099b8ee3539b4687b60264a0ca46462867cb92a28ee57b5e03a58b5b5fba6248c64b3877c38f0e552913d2627b18ba7ccb7fd801b30d9b599e612bf536c475c03ecbfbbd345a98f21bcf13134a1eb61af2c417ba67c1014b3aee00941f798af106a584c3a03ec05f83f443f05c64838c0292d15bf8e8851cd0c03b6a6f6189601cb7ccf26597992726379023d23a6643d79e0be7b401405c9f51c05b982b4a09517647081db586bb859272ea11de5e75b2b452192deabcaa3c90e668d12d9d11315ce1463ea54ce4f66b +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 110a8285f4ccb5846782dc61382e517048cefbf2ddfee70d94e4872f8fbaebfa +public_key = 7a35c2a489130ef451086b0082c3b6bee40f8ab942fa21bbea1067b2ba6613005c04b04dac6183a3745e27104a64424b256272616b76b8f5c1acfc64c04559dd102bc3e7a71762a97045c1fff7538efa775cbb0d3cbc3cfe971d584062c274b5bf1c09cc046782e2b2775544ee2240447353f1cc75060a1f013a9b036736c4d68ab6d1b96e5407611515fe25acb1b4c9c02318560736fec53e3cf58d82cc1a1d4214efd7b8ab2863c9600149b3a75efc0f1774456f2a31a84925ab2c1e4c9c6a4e26bf5de1311dd21a1fa28cd3b2555c0a614f781f50e26672fb23a45a729ba8ca8262078b53168749b7170187fdb9c166b8120a039ee1ea304242c79dfb77617b2a6dd8603dd04df316949425ca8f60497efc0118d814a6aa677a4a5f238b93ed8729b0a20abb301345c83d630aa866a50f83351e32c02b4e287f8d6816c51aadfc7c7d1b2b2135b6c34b932656a8981a98c65a1316cc856d50005fe55a0846c9a79a4c30f4126a2784c737213ebd25c96d9650ded059d583845644bd08b7adb4a9a0accc725235b8eafc5feee22030e79a87bc7c8008acb7271ccb20bc21161c077906e5b6b501f038140317620b44a5a719efc4b5fad60c9fec30fa761aaaaa69179491585159e543770c589060fb69698bb73c4791c9794b15db2a79e1163d4468b7d2582762bf61880f59737ac2587a7c1c6b804b72f1ec52189599e7ebc37548adcbab54133361320296c3b9cbf75ca5242645da2c296bb1c0c9e696fd980d57e2a1e4d90222372961c8c7ee157c90b789bc4ca2d86a00dc500a7bbcab92421cf218a18ad8b674b14171e1769a654ac8332123d58d716c8aff612ebf3a3d58935d99904a48a02450aa77310306c76927feb19fb28c5af5cc6329eaa7d7357a64a959e9b03ee926ca4af62f65468b6c0b8761e7348820519188a1cd6224749c4cb2809a6c544bf5a44c32b1c96a388bd75c9cbd50858157b9d4b98935a53e1b6ca39b9322a0a0202938a0668c9c3c5bbacc71b9ef233116398521d125f423960c7837b7e13ab7b056fd194a4249148aa3836f4b993b0157921aa809d60837105560312e62fc28b26519a7abbedab7373d73c7b833b345626148c526073629d6c307202b1c2c767f179602e4345f4382a9c3138924e1163c60298beb79cdd132b3d2966b404a0bac255bc4aeec8ba4f6650a2f610604243aee1904394c22b57c6b52d42646b64fa413741c467eda04ad3f1239e419b29ad6005be09b8127126ff38f0f85b35232909d26c4428a1bd619505d47913784567f117dc19cb353d43b4f1c6b823628c7436cb43bb8255940f32b27ed11659ee3629a02b4bab1c1d543b28e45a91483766fe32ac4e57b0e922fed3835a5346f5036a1480c2439d15c71fa73bd0552aa6695e335cff1174b72b2137f39c92a906b7bc10ab974c4e1d62d225b1caa1098d5250d7f2112e37460cdf2afe2529be1ea551878cb2dc26143602d67c9686e6538f3732ea249c8a74c5d3af1ba8c72662f211c26d5891a407234a146fc084534449ca53b5a1bc661cc82ca89bcbed9733a301080bafa426562622dea33bcb5c4a8a049b8db755bb9108db910eed8c97a773a6d8b5ff077aade0a495c81274ba3f6e3953fc310e318fde5119695491a4af40bc41710cf44dbcee343401b93cfd45c19b4eedb383a19c6c3c18f7ab6eb16d06e +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 64fe129938e76b4f1d2e29a94d64143d847e43f5f05498671243e5f2692809e2 +public_key = 695393088338e8ecabda1277daf09a16956d1df7999f58be025024f3c399cb7069d3a3b7738274ceb082f9981b8b43592bd3860eeb76e181a3a58386efe47659008db3167004807355b763b519b8c0a3200e2461c49b80b6f2b8dd208ccf92cd1b099a6d5193ece1bf0627bde3f23a1606a9bc283b1830a050ca35aab9440e46387469cd32f03fdc537275426f3a00487e6b9d0bc83af6eb3b2dcb8d22a278ea48c3e6996b0baa42a2cc55ea5a5edb60444ed81b65a61243853cb9a08dd2e910bb86b16f66befba1817ae6403288775e80c483961282b4811a2c4dc3c9b71325315482bde4762d70ac1fe83128910b97ab469b157c9f6eba53958b913d2a6fa0744c4f8993f4d070486bbc4d6a943657440a894b5ae69145a4867c7c13221635a2158c549baddd7553c06343276237db06a480ca5df4764e779765bef25a064c999a8c3648b391bf77828a5b6a0894c76541549900335b4c9dd2d956026700d1ba7fd8a59282e4cd2161c2ab1906d64259fb505b8254265db5176b3524c525353bc2bee01b8b9f95bffd215155a5300ae8b7e5c15c0b8c5fbfc75c20d67a0acaac18ec8b3ef08e27cc7a107b75bcb2243df99a5036b705289a61943afd8595927170de3230eee6297f58ac7e08b1c3b6342d43cbe8248fe9962c7dc63eaa010eaebaa4759a9ddc5248db27329c36526ae674546b4feba77c3cd87f92076825ab2793a56d0e44b56e837d60991a6581a1461a191370b9367374b1e82662d699c72080db3c5a249700b9c4713eb64cae673c839b0cc852235beac0616645bb0a5910889b4a7bc66bba939a9354b94854543c32416802e838572a56aa01f2a7ae9425afa58847cc7b42389597f4037f133338218e25327e8f022139228782c0049cc7be6b0c95a4c380ad110369a64baa5cbf795c51375910a1bc5f03fbc2e77c9d0ca318248c82b217a46c7189add46bb6123a370ab81f7c0551674c67179fcf48707565be3452a2719c032138c82b149bc0f546f80153fb351529243be6685c5637ccf31746fef4c8f6fb7d15b23a2c2cacc68a8d6f7aa02f7c8be36a162f70a19f93918cf52bb3263afc2b5cd9344ff253bc5665cdd237c1b8d85032fa8633c93f8b8534c01168036b0ef96bc5491930fa9316ea47782a043297f57eb3e4465e0826ee0874981b3c88f84e9d06b2355272a8140ef9606934a77c5361374de806d02bb215e23653f352059a5a8da9156777bdad3ca004101f27c2c441ec311ef10f730c1e7c214ea51a535b9b617bd540c63806bf011e654c059cc6098a6209370c1c6a1522a047ca1f771f3dab6605dc24de498c564863a0806698444e8bd62970a7938436475b884e6ca952c4eb87472bb61f043cd92a30727a5f19829d3f744e63d870fdf09eb26994e5d86758c65a194011b7d584654595a180c7d4c4b819b82f3789856ae74b85d722645786c0b24101c613809ba83db637702c2e07fb3ef0a9732bb8958b43618ad79446c95ed25a75801aa80d08a8a1f452823ca734767ec30897d8307e5dba124dab03c3c61329caccf8a91cc20b2fe719734611abc7516bad91c08f443e01371607166dc0350b5bac8a8ca22246db0855321bbf75ad3be635a915329983c86d09967482430a8f9f16b65b42e4ed2ca53d1b7d8e2ceb1350 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = d276a3cf659b7102429ad9f0590ce40bd91720908cad1d9c85d7aab0189cf890 +public_key = 8674043493ce62224d2273838ab0976350172a847bd91c3925160d7849933d217d551a7def409516354ecda39ae8344aee41679f690123648921fcbac9440d4852cf0d1a2dc9b13335106a2a1a508a7a2c6b1b04929527313147e86bbf3eb49e1698c410046cd85818444589f127152a412d79927dca274546248d2f4383abf1a9e838b63b37657d1c42ee866b01c53577d96cdebc6cfca534ba2011d454333b8c37ab427c44614602553e88f9b17d7c625f42ad52a19409b7c8a002c236d454e5d54a78fc3f023515db624a15391e258a8baa637642b7590282006fe0a8906217b3d4ae5be0bd005289257c13593a202fa560669c13ddf9a05ad4bfd3a3ab40866fe913c7a9ba865227098f042bda40a92e78758c8b5307b0598c0c1c32008f159470643091cafb4dfbb4b69a89bc05d88c130b80a6e13c18a93af59106e84c27d22281586bc9c8a5246cc78051b7b44a7129025092a6a497f0ac28ab1b578b97541f767089babccc629554a68c36ebcb4e645c7e0092f40c4003e15c98c184f2450b2aa1990caa6f2dc830c788190b697cc71664410387b151cf42190fb4945b1658cd9b22b0f44c2b165a7dc28a95d7a252f80227345389412b91d9897844d465bf35b64fc2cf6583c7e97b239f064061d45298db87f85b460fa989f570751cc3bbd2e64238958ec0f98af7f5c0987ac10b064b153419be7007ac4949b961335bc043392a26d4f238ad0c69d4fa91aa578cd19c3f04280a3bc0cf4701ae00746da433548490756ce08953b31243f2753f3582f7a4122676ac2da36d1ba3a559655300d6ae7492bc046c470e779306fb2e8e634ef2264b0536ba21854ac899b605526ad9eaa3fa6360a3069e3ff75846168469d0a6df500402a688e73867a52754fdb8095c330bb37131d7995b658aa62b2790115b5653559b09d99013e6b656a04c9fe79442e7b9b8728c94c19239590241cb8bda9294600cd095783aa3b324646034d11776842c871720321eb1c76ee3631a318e8c7ba05c10760fd14bcc8468ebe40a66665f85e606bc302346e542cb07bafc9b2dff6934530850a95a6913072db65053ad2a5089a560ecd7bfb607b93d46a621421404b2cd3eb2b4df616ac2f4a0a2c17b123aa5cafc2b12912b59f7684a7b1c71e1a1d4044427b92ccbaca1d2372ad857aaa26415d8f53b45e63524734fcf4b3dcef007d66c3f46d3b9fe3566dd5a0c2744104292a9c1300bd78bc566a49531588dbad6800e4319b2479c3e41b9d7573786f9897e43692ea8134fd4b65302cdd1230e9b98cc20d104b7f4c15ff4992c411ea12aaad103277ff01adef2bf4e64311c4921c594bebd7bad19c5b01ea075c7e42869a04933145bad699f0ad5b1a1351e89208e7c88b3e65c0b5516c4a5e39288001ed9337d9cf8cfe2810085c70fed4372e145b2dcca905f484ffcc7b082a4276fe9ad23e0b43de05246fbb9d0a52b95c47910aac0bad6cec5d36a0b924849237bca33c417f4557e09c38fd77082c78f637c2504e6860041469abc3f28f05fc91b04af0010a4088a1834b45ba58b809960782a5d6429744cd736e2c9166866b36dfbbc5036826dc20ab6fb4f9f062ad62b8c66d639c2b76ef2f5f8784bea83758b91d5e1e080ac8e7a6b3d8b1fc4ae0109540efdbeb29146e8ce27729db1ed40 +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Public key is too long +entropy = 5fe02039e038b1d1c3629a7a8a20f7ea0c3979a07f658846b6384d1557224658 +public_key = 3510bf4f191ee7289e32b990c40b380413551bea86311c9c3dd02d05d1642ad53989e30117f9334fb203152045c1d96f0ad86713ebc082ac76a1d2cf707901bfe224625420df852ea7f3b48cd8935b882a51d80aa62792f6b536d8410091c74416e89ffad7a7b28c8222b3b6e15a5e2665071a3c3a9ecba5c262c600b38bd0e80e92cb511a524b0a394bb15b07f9dc639c872eabc222de2766260513ce7145453a00a54308fae3a20f5a8e566426d8c78a404439eed2cdc8312f60e87e377568b5f9971c61205752335d5962e24813de203523b4a48a60a344f6563d75baf7c80bb1bcccf583cb9dcb72cf7c1e44e9223e0ca138a49a2e38b878b989ca686eee90308d4822ab371ccb1861249264c4a8313fb89785a9c410ac82e44191599572a4b5472db14976348490240b6a59589d764bdd225850f8b8dcc0be03c5b98f852650f86de501084b3ba5f52cc32aaa823c51a873254d9158b2d0706e48c1738409c9a6c208cbabac2ba020705b18f2c8a4f5819377f0211752b6f65585046ab3afea983861931664198be80058d58579160eeb423cdffc1a02bc3b45a1be40922a3dcc1ebe59c3e8c50b0bb00e9a82442006932172af56836b7a504d2e7abef48924be3ba16f2c1f89b316e50c2e789c1ea26c0b320b1d2ab97fe53ca84a811431a683d1aaa01fbbc00d6439562bbf527425541104a7c139e230110f843e19f111ad8c30a8679a28f811a4e06dcecc77a9922a35c4ab9ef137f52b4a253a7ade933f70a47a8982069ef55c2f9071d1db51f783a37eec8fa2739e4a3bb397896b006b57f1928e40962000229f05cc1628a1939ed96b4c1a5461302e3166af5d909372b5cb23a0374b20bf96260cdd941ba3c345a5b56ef63b3899a0c54171111af1aea877c75f0a000095852d8a7d8353a5d5ec3e994566f8b03611926fe0245bde908ebe2497dd70756d893accd79bb2788a84330a1cac6a4762636a125efa4261af91904aecabf757aa9b9a3bae2a1b4473c46f5ac4cf574844d5873343bc1aa755574193bde293cf7080cf67b98719778c590050d936e0d8c5bbc7649ad413ab2099e7073a0b916b812565101908e64c73fe7a90daa499fd3cbe79ea0199b774921725da00742952760c637e841b1c5b0656e1351ae1c933005d5ac5c93eb43c450673af50c52e18619954c4a2080031450a46b45bcb1b348f46c24b925049d469c97749887e37af2cc737e977677f98830a53263fa1a4ac5a14073a0548012acd1286c2d0cbffe4a2ee6a2a1d0c04c6d89a85266bb884ca9e16c5331859ff922d0410bf8e657502175c7ea2b0ee824182982d05a4c05b249aa9dac2c3559d810a3cd4fa28e49596da2213f5b5bcc686c5801a184f39966a126f98a9061d1866a9e01a1b6297a83cc04f0a7f69a7a52b26007552797a8146985681432a567d4a16c31194a8acb680396252d6038a807fdd79885114901a267557c16c59f2abe95acf967006cc44606382703e98728ff48515b4c39113ca5154a80ad583fa3297aea645d4e52eea1a8277553097a917cd6b0eb792b2631a854e079f892140b6c1c57e2a3d68c88befb6c9cf842a6a5a325b47553ea4273c643818a89878b2bced19f41922b91c2a3e708d5f3e4ebcf69510158065f6da061cd646d1787013d2c5094a2182a411704fdb4e2814e153e1587bbf +expected_result = fail +expected_ciphertext = +expected_shared_secret = + +comment = Zero secret and error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 7d3db5cd14b6db21e23580dcef17133205df090d24fb80487306aa6d894143dcd9bf9c47f9ae2634d4c2bef2400f839d42fa417a2b53baca917ac3e8e6c62083d8d1e849603ad45a6522f8e1058b328e38f66aec79c96065470ab0d15947dc61aa1ee1bd4a178c957bf81b8247c68425c4bc3f2e243b8ccc50fa0018ecbc215f3487b4f54a0fb18333ea2da8e2200a608a83554ac5649445a53da1177a3a11f69fe12c6ce093ac3cadb9be5ce9e6fb895345dea2a4cf386ff6ed2d477719af3bcaf2dd34f2f6746d039f82063fc589e5322b02dda783f524bf59fe9ea30b101ffd83be9d1965ed3eb16c52df822425f9029209e303df1725842e94fd806476e684f6f53fa74ae4960f498088b5eecf024b24eca054cff625feba4d133e6263b07617a467e0d9c0bdc0aa8e1f12620ade63643fdb573a798ebd81e1b0cda60a08ade91c92c3ff8c5877593ef0a90e6c20fd9bbcc3797d3dcc7a5bab85ec1e08471c73c3a19dac7d7690eafe2ecf5d19f3d0d3de2b700a622d1ef40631dae81f725849a2fc8a0225598b5941d74da237376e3c4cb72749e3bd76a81701d79f1423b2787a5b4276ca277e5279a820aa9abf164d921ec41a5a3598f13665c19311d0a75a0968926ef664869b8b2e6628db1887ebb2a7ec06432662b9c1494eb399142b2f05b6ec71d37ab33392f755f2a9c772f60a802648e3e54494c6006067f95946c09c6db484c526a4bdca4a663b329c45d7888cf8cf6cb20192b57b21f06800d711d1a79301d05eed76bfe406f85c2bc32e8680bbf7742719686f59564e39ad7f77e1d6226efa41e5918c4e4fefd8f24e7d3bc885af5a3e4965dbcac0b0ca594df119af883309ff10183b2f6d26a43f0cb9df9284c04e5780ea2bb2c160bcfe25a764fc0789bf40da40f7001c5d92e03ab1907e9287c7879c3fd3d30a1fbb3f4b5684d73b8cb0e7e0b8cf455ccceea2c5e92e8f90e0a1f99ab2d2353c391d20d9d9fcca8d449ea1b2d7b2e161bc198f34aac1a9221f5e6178be1f15dd26fb5973ef7b56a9214ffba6683071370e619ad805f6fc3aca3dcbea742c975f72d3c1c8b6f7a0fb86e9b4dd4fb76c5531d8d5a48be510e3c3454c2ae8196efd398bf117c2dc8c9891c8ac7db5317d4c98b5b300d6422ff8ad7c0b748d8dadedbea0a0742afc0383f6082c8428c97f49f1225a40e9f10ff3cd42d701d7a8d4d24fed319fd3b601601a9e9eea1552c1d169b4b7073b3212bd86ba3efe733b549950ec4b71078b3f7c09880a810492463d8152b11ef165a1ac29b81a17b844ef04bfde87f9c090a1453299c231c7453376f3a676f75e4836ac80ac294d69da31f60f1e470888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_shared_secret = b30f8bbff487ef7613d1676569986a72ed98afa9f37842013a2467a9ba6d013f + +comment = Zero error +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 1c398b2065bb3d95582d63859ec7006f9c80b1d0c26c22666dec1784f76b4096b4fc5892a49c925ad388a3e31ab2bab228c91985b295b730861ae72cd0f733a0ecb85d26844ddc8d28766dfaec97486105a4281663c67585864367b7521e968357940bb31ac0658ba60e23baf9d5cf4b2600ed8b19f6a7c974fca655b0b2e5bc019c8398bfda6bd6442e51d365c3839e6e4cc124cb5529782692bc68a58617517a9d6a316ad9e93695e48791897a0ee3010c43809d0a6f5127ad9f43578d5842ed91902ae068ce3ac8cfa419e0dc8c90b0cac51a47a2a16162c515d0b98099a02c7bd82cce9532590c2588955c8c37c5d957736c25cdc7329f3951653747b7b8f9b1da32027121a53d62b949e9b15a7a29d07716a74486ca28bf6ce3b8bed381cc391890f2259e60a12dcacd293908c97c503606a78a4c035a10a966415788033cf870234986820ac71db9e322392652547a6f5836c138b869dc409c16d67f1deb186454ba33e6c45cb24e969734d4da25946a427346915d598a0cb45986fc73dbd63c387421bf95c11f6a0956a76697d6216485352da8932f697e8a02c293bb76688c550c63ca633a18f1e07bdc07951a996cec3644755c4a0f55230c48844ff6a82511976e4a0a17a499e768207df0c309b814e30a099a6511d6f3a499994a821c9dd41872860a977e7406cc2b3b69768b7ea720b2f5858df28f97b77f05d2361c62b100271db35c660493b12b66938845c1c799b5231251980a99ccab6356a0b445e86098108126812121176f13979e59a1029cb040bf36aef192aa622523866ab99459a01dd94535477e1755101478b53ec165c3197d0110a7b4b4892a3bb82831b300e55807c44df5f6c1571ca125b74bc33863603501abf51120acb848eb1daa2a7f50e640fedb74e01307f68798e98acee0e91bffd8150f2bc9780956b4a2697a825da419aab3d3946797762aab8cca9a5a65dc2edf507e8a9474d803c8fb637e05c94cabd721eef5716ca4410e69220c4a22deb89c82526a5b506bdde8789e2359352c07cbb90f3faa867c538d1926051e3c318939302dd31c34e894e3917e4ddc60f3ca9d3775242003ae7642035267757438a5deeb96c46489670abb8918c3c4b42ec7c7c3f2bc74f1269989080782c8941a2838439c3425d88f0d5537282a677ae1102ed695dc447668113481f89e60659f1e017dcd3336ed47710a8721cc421b024595a86125af941203392fb0f9cfb2fb7af950772319070ac60f97c2932ffa71bba6a94d47c695bca3922835d86a94cfc360ba637939034a7850579c7c5e6ef90cd7ccc983d28f357ac379a6b7d6f328bb0283d79356d6b28041aa0151d16605798fb65652ff270114f29241b8774f94553351536526aec996be9396282c66c77b63399310019ad8474912bff5bb1503d481bb4aab4fa23824c68ae5058230ac2ba43a4805ca8cf6b07b810ba6d415c4bad388d17373b4535af6234e42187d33ba51dc75a8cdd3c80870cbbbba89277c1b79e631f959c8f45689fdb7a6e72a97257aa188f8548da934533076937a140ac62c598a40adcb0bc0e0af7af639efa4128d10b8dc0197a12ba1e3c9c68b461dc3a7ab2975482c62810a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 8d0f4960c3b07ce8148731d6f2424e614145f9bc98adf02c0c9faf944c708502d96b8142b0823b6283faa03ab500500684ab8646951f90a09ddb241f5afefcb2a75c3bbe742961ee3dde84518933dd19dddc08fe0c2157743a5d464738f430fcb0940e3b12d8a2458234cf3d2dc475fbc589d90f5918dc8c1be0bae511d6bfa0c26598529a3646453019008df6bd4d2689ec76d5b0bf1efcad50bcdc1945bc670b24db9e0fdf1880aa9d90687bb1f4d4186ab444d2cd1c91b7a7c57324aec0e96240f9d817929f6b91d136447e46cfcfe0d6e11ab16d47dd095252e13d61ba2ba1f5ea4fedcdc0cc16b2780edc9b4e4941e8b2dddf791da9f8aa6b67906c52fd368e1808035377af67def8840fc44bd11896e594deca14d4cb942b28df99583081a3e9c0f5c8a989d781a062765214ca381cd65683faff599eb6db4752fc667014a8dbd7d2fbd64016fa33c7c8d39a36265f300501d52ad4c532abd18f43662e9a0110b5c54797f1148615e52ebfd60b07f9dd61c5f22f563620735a5c55dd3173366b0ec207722afa4e7791453f522a898b9fe97759e6112e096185e40b7447c112d508ef6f8afd64b0c2bf1f75cdaa42c9db11f0d997c38dc5417fe39d2f99f00abb50b66cf1f9ba5472b05605d492b8d483b7708568753bf415938a3c26ccb361873d0a1d1d42820cf5ec6986cce388b0356b40ba6d572f19be691a654356dc7e90b31bd04e8ba9e27fdf179037c0c8e2d4440eca4d849bc85d61f2df423bd09d90ba00766e5e6ba946e53a66c119611d5b017032c5a39c9a533097dcae083d3832821668b1633ba1aeab81f556d61dc96d3052b6497f7cc349b548f90fde55604c33ce018095d72e8c1a2468da1c6c5f679234636352e5ac1b08c7508a887b1fed6fe466520f88cb5951b86a4aa6c94398db200f4ad7e51b3321af70124f7f34823c4af599ccf925c3002d297760bf4baf7fd1465e95cc824853562623540c544c8d46a4c4e006837983f976d47cbce04b703dae965111948159ef0c95093df21d80555016265c582b19b0dc8403e4e297c980129485311ee1ab7ee9e4f37f627ab239f5c6158a7434b8c6a654dc305e338b2e7c9da053d6932bf4640c2215f68e2020658ec82ace46300fab43412d12b2cfd7e09954acc0e7b928b2fb791f68f7fb455230292eab955b4818031e65a54bfea008ee5605205fe4d68b26de0e60e99ee5acd069a23e5d83ba43745985bb0cf05da32028e66bba8516889e6dba565a006624433c6cb23147008dbd238163739adca132ee73b4eb0415a3b754fbdece10f926f7979c6f85d0a6e9ee0e881f13f50c657cbfc345185f55167c215d35dd0a0f88c3736119d1c5891fe5555dc3350c86e2df0383aa876ed91f03207811e0d6d752669b8832de3836481c33d416f63ac05234a996d7330b00837c3f267f09c74f0b4b85a2bf0b0ffbcc23ec403fb621f7f94ff5b14db6bc699545f15e448223e677906f8d4eef5a162e0b2d4b95e205b57ec7fb50a03c7ce1f53d7b +expected_shared_secret = 6f68f7fde8fdc93b27a91e7989842c6132d60007d2bb9d99fbb91d4e1c79fcd9 + +comment = Zero secret +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 76da327e31334a81297ac41a07b9c1d4e04ef3fb8b06e9bc13071c98f6a80523801d0c6e5e7848d143a5dc011eab319ce6308bde406c4ca459fd3c20c5c76dab11c3eff0a060f52d6c677242b6019ea40c0709d071f587c06557d0cc36f7c428383834b69b877308c55e8c816d8195f614336e50357da66fb3f03de7c3742fb23c2398c7868690648122afe321a0b2b55abb99306265b8e9c4be1771b7727775a25adb2108a8d62bf5c18571267e6c1b5dfc547019c331532a40550579e79426304b52c88cb722da72d63a8da549731d5625a6e28db6ec22f3d1733df7775d5771857382bbca11dd271fc35b4854f58b6ffb25fd42286823790b1bbccb40c105e38092f5a744e19d7b758ce2a5379fcb1f401aa4db967fee4bcfd73811b214516a098d1cc726ba418118e14970aaab00293bdd9b18de001075e2a1d25183bca677db703b010a7f3166b7a4bc374b913394c504463a42cbac84ea799d70db4ac0db6dc3da8c78149bae1cc5e4b65f701bca315866d6a67e9bebbea36ca91fa694929cba572c60a1d1006c95941a640d472bc2b30cbb635087170381a4328cbd462964c80692f224ca17575fd7cce32425d6fb19a363cd114524d8c4106cb628253bca70377aa242751b626447fc43de18333dc21c841c236eb0b2073a2a8f9a268c931669daa4c9036228394fc8a0a2cf809a1a2929a5ccc98f924a9b7282f922c5ecd96cd1436b5b21692610a44747a2435807c50581dad25268d737fee3834a54967e76c3e7f537023b57f6a7b58c191427a12282e06421289448c97f7cb042ca66927a417e6747b3dd501d119cbd4dc43d18174aac099ef85839c7d9425d87a17cd77ccd568bbf4bb0fa8ca4e5005f9ae815a307471219a9aaf60bea631e07162a1818c3c5da6c29385fbeaa76ff4804beca79d1f842c46b9fb29c81fc4875afa0b178564d26b26cb21aaad891822ecb471b76a869b83838388b9f5839e0c344a7eab55c392c99019a0841b20dd14f36875853c6150fa46c2572828f51b9636b00bad5940912923252be3c49190577c928d5bcd6983bccf00875db487287ada1849d3339069195380c1a3ea34703792251e5c7877523c1b6278f9e40cfb1614a04c01d966c41bea36a10492edba56a90e370c1995de2203aff43002446a30f3771af65924b8354e0dc2fb4aab0295925a23576e4e9770740845ba541eb23610125c782c6c82af506d9a25d148373f5f48537d7b0df7c9e72f10938f9cd66aa6b2dea9322412eb01cb04de39797f78efa29186af03d90588d8488914f94033b644663269435e2c26b47297af4a324526301f2cea3446c2507717e83c29c8a53f277cb739851bfc94db3db6c6d2a35df897ad06420452281d1659e7aa89e3062abd2a1a7113cb373e6856b7acc402abd86418c554858eecbc2b38b8b9920cc0fa091b891c8a4248cbec13d52984c6512a025ca69b34477dda65e12b7839128427c42832a1c5f31e5c3ec09497667ca7e0059c5f43889460344fb6985441afee726b58172e2ba2312aa10639737325cb82e2947299b94aa8bb021857232878b45b03f9f0ba5b0ab75c1773c471ab51e666231c3c37f1bc4630628a9b1272fb9af0a60e1a95e846cdcac4c779702db2e7d39055c815cffa89c71595bf461924ef2 +expected_result = pass +expected_ciphertext = 591416ed43f689aa76a117f623b7647c6ebade29bec5e089f06a7ba3048178df0aa0c26680f99d0186432f9fc3987e0a511f2bd3d075603d315956b2319b4a61c250c09a5f8a49445050e6c2260daa43a6e12e7f25bde3a94fba40f990c950bd30f9229d5c65b6bb4e13fb8ea50baa866cdda065636656941dcf58907f6bc45c778dbb8e1e8a9bc1eaacbd3ed5c034136afd74228e70c4cf735a82c696ba386a451cecf4b43a71340012ff8676c7d5b4b80e0e59f1c548a40e7c4d25b8526bc4fc14aa9fa7935c9860efd43095538dc081982ae2c81a96f9634685f506bf7cfb1fa7fde39594c5252fdf753818be40ec6191fac29f9512ab94e8c03ffaa7990e3b788ec43d749d78da8f729803eaa864efdba24dc3db1a65d1110922f612ac60c3cc731d65f8a1ee946ab348d5ca8f4d749d5b07d0ec91c0f74923533f86640cbb30b470650d2b710c690651c99c03caf4792d923e5a094ce709678efad3b474e803a87b7d390ef05ce6fb2b84eee8c31f9cd325479f78ed7dcc82d06d390c616019ad6bf8d7c18cc5f719afb06ca331034d620b108da68656c2c5bcf206046cf954ff9aab6f76833312f55b0ae36330035afea8e4b9c3fb522599d7158f3584d7d0d70e4557568b7838e437f04bb41d4f8e8d41969fc8dd2d35fdef69b85d331fffbc5d47e1fdcd60e8a10979f35722a430c55e9564126182a8d9140e8cff41386b6e81a1033a9b40d75ca6aec60beb7e3080223dbde023eb59decb9054663fe1170f2da33c352c86b10c4cba4cd79878a7c4e83745764355b3c1a8b4a61384e1e9db00bcef2068ac7d4a4e67a1aea96c52ae35f998eceaef3db46b43b85dfcab0a2994dc700868125e3460e2f9c11a0402432e34a0193ac2cde8fbda0f1a81371b43f271f737d7af2af211f5287389989f71cff7c107fadf8010bb837d3cf2ac884653ad9854caf494d5196d4fbe49585525e50b009332eb86303ba5cf5ca11cd19b687b5f3ab06c2e36327c89e0ce03efb32a813190a1849382e82cf554d86caa9cc2c9385bc3b203d20415d0282543ed33ccec14b2275014a13121aa206a98ed60261e22acf4a8eac9c853e96f99d09ad7c0c46fc8e93db918818ebf249f871dda0c5220c4a46475266d2dca6b609167e120930861bce88859a822f18d044befb231ea1e6c7459bdeb14b6e988a85c50b4969215451d96a653ca2990c8db43f44df0809dd894b072037e647251aba319267f7448b408aa959825d79e011a5792ce8dccfad35553e4fc662867811081836a839927a4060bc9be4ddc69391e0824bb16d6376f03077919e3525a6865410c71a5fc8e86b9cbe9043a294c90650888808008088888000008000088088880880000088008808080880808008888888800088008088000088088800800808888880008008800000880080808880880888880088008080808008088800000008000880800800880800088088800008880080008080000088888088880800800080880880000880808888080080888 +expected_shared_secret = 1ef65648be69ac3ca3ade1382a2b4a4ba1c0c7a04eecbcdd9e34af67665bbff2 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 1c63473a75acda757b3ac6ad26221ef4f671e01461ab865f59c26f22c61de17800336b18365a190e7a123a34193f375e9f9643ae99889eda085d5317d5887e6b2c8999c133e20c49b3294aa0e064dec63c7a00acc1c08fabfacc28203e616b5a06f02e66e87fe1789725e8538b405323b9233fa61771980626b98b014ccbb9573d57d85dff1b000b38502af474add3a32f1ac7c1ab8adf93350ef1939ea376226a37c9675fa33503fcb753a1c86ca8c10e10ac74658944af239b48b97ca2b85ca4034ca7d662c91237c63c6b35137fd0429562b5856fc11662d0777c111ad9c6c34bebbd61eb6b538378b0123033c11ae1f0715553ae62cb27f15ab26b46ce4e540d39679ad9613fc91a35ca1073497cba5c57cc2c77bc75e7281e518f7640ad48451ecc32bb26bb2512fb76c9f6c46dfb6dad9c7be4762cba596184f37259143983e906002b34acac2be801c837c53771b048dbbca14b6c33e9ea7886c3be529a488aaa4deb590fdc96aa62a68f67abb4073b2f0f13a874fa7065e3c16a8b549987c5f2733ac4bca74be87f2e14cdf7d8916d47b69652244552a7d74b846961333a5755ec1179eba27b598333a07aad70626429153b7609a131e63c6bc94c32e345b9b293345598ae20a6f6cb25ff143f68e28013793183b5c9bc8a9d289967ccf613ad510a63c94c2b6b32214a9248fa89f85949ee3cbe0ba3a778ac7b754498dc3a79a95519606171608840587040a70aa1331899bb1082802c2aeef31ca2a773ef27382c2a84eb04ca518a83af9b44028c56427013b7036e441c20acf86ae09a82b8fb6ab2a234853a7b3ea386558a0bdfcb4487455a95c30cbcd54a6df965c2830f37c41bfef65013671411db77b8d69f6d386fd254ad7e175ceed98cc1e16190965b97e7375ce1105a491875007030c01cefc43e7a45615b665e073b0ba41a8309fc7cd70a271e71a36530c80ea227a9b57645899003c60e97609aa0761e60e8aa1f414518006cf1c62ea53826d53981f2264bc6c24ae072a2699886b75912ecc880ad6939b6a40d539232fa155b0d101aa7791cf74a1fa459ab8c8cafbe2911289312ca990fba952cb0253b71a792a5d9c6bfb31219e898c7125197f7b7a90aac7d527f62bb5fa7e00e106961d1babcc582590989262f1a1463e44d839221717b49b28980ea8b81f5f2cc44252c771b47d5550e3d68a8f5599aec848347ca728eb6c93b717fd6dcb7d8e338a6543d3a434245a44c2191a550794783212f44a94e46a64117f0b98157015fb0c6fb7564847703674945ca3b272e14aaa3a02cb8eb7fe3445e45940315b4408c5b4400812b0b48925862cd5c27abd9a2a0c3656290b11f6a342ec589720135a47b555aba0b098b37539cd0a05e729165d82b82ca1988dbb5bae64c7cb44a3bb190fd701b7927257a0c564fd2762f0c999341600bf86ecac593f7320e4f77bf720a42399c3b36642885b5b53a527a7b9606de8703805a72a777b1bf3674de08419e3ab4e424678e42ac87c15ed6c49afff1c246fb6b80d1182f57b6360203bb6640291a0b9d067aad6b8e3465a84275b923ea4853f799a7d31766bc84b5a0230aa43b9a3153f509b0ad9c63b00b4f68c75e29a6cf40d7000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 515463ea5284839dc84869288f9c03f0e384e56fe04c60cd7af8bdf53057698a984c2ac336de2932d3d4ba3d2073b481a125bd6cfae82da6ded2b0e8fbf7f579dfe5d590a6c03a95b53df59baaf4f0dad94a7b821cbf9c1c809b5d089d38be1c30d455ef44fef503be587c4be0929e2cbd931d10f1a8027ef2d14e15a931f3881a2bd914adf3fc93f97ceeaa8a521762540307ce5a670313d828d5ac71680d4f46bb1ba551ed7fb47e4b82e6c6b4713228038d5011df91b07ea0fb98790924b4cb859bfaeb309ffea5c2cbbf3f12fac5a063e1fe7bbdb0de70683837b180a13e0cad655b6fcd1f5b635d3342dc84298269c1de8ce6b39452297fa6bffca90ca6045cf304c4691cd052148dfb0812162e7e000dc5c18c21209df9d9f0fe7dd8d0962cd0ac01402a7f8170265af8804747857d31aa7aea612900e9067ba8970e1a60ae3ab1105b1eff223c755c045b81de79659d001b7c45ce64dfd2dc16853276b50053988337ef88e4c70ef5861dbcb8a7d6d1b2a5fc5f044160be5694e12201fc57f0c8e3ed5e48c83c2815d78fc68a118918615b2ea0898eb7a33d446c449aa92c82131fb80267666d9e11425c9bb8e10f745828b72570194465c7b2eca785228244e08c06e0d8f20222221f5dec81fcb478945564e2e53ddb68dbae7c6b1540ca7f4087d2833a752d97a69cba3f604483a6eda26e8f5ec27f3ca84730237cf1bb30d70aee528eab3e4493c7f5787f5757ca6a3ab5c278c631584bdbcebfba318db0fcdaee34cfac4422b448f00006c97abf3175c379fcb16f5b150e398355212d8c60ecbfcb3503824565bf841743bce55fbb2606dce0b45a5e2c1fc9fa20c1847e9173de2d8dbbdba840b42b002cf5c0c1d34e709816806e525ca217e37cb2d23e3c268fc4b31608f89ceda1c78c7d3c6b23863f2c6b80747dea4fd11ddbbb8421728c4dbd97fecb9bb652150278a3a3dd388789d2edf85baeff8f6153317a9cc9b72af8f69f260ca96cf602e2831cdfbc14958bf62968e7c019d7c71f6ad55fb51cfd9adf82894e56c05f6b19304cc04d2906b935639f2e96b56768abe27199b5af84268ee89c97f42925bd3350aaf8832d1f7b2225515759ef64d2d75ab29039b549774a3ed7209e1e0e50656794b315ce2bfe35e20a33bf180ac724b9a47cb9198ce2174f6b9cff075f94ede24074f169f15a8eadb54d5cd8241efe8bdac98ce02706ab86c10089ea23470e048c0f9bab797c240b5c499f75ffef8ee6da533642301c897f66770fe1860a01e82449c4259f54be74a46d96ff5c78f0c07d43f66ab578a795a5f3fca06a1d3cfa16449a278da74a5eb6f0494ebee89d4ce6dff6c008e10953b9df95f0e2e7310d33239206598cf4a729e1466f3718534d914617d260298b45a5314d045516a15701c269ec948b681a4b3dba464878a193731e174ea8902873b7132eeebacfec09ccbce7f50835116ce5b0a9e10fbc7c76559ce0044ddc494a9224bc197c494510f2c44e43b037798c1613416f2240394f +expected_shared_secret = b177b87b89197809b36026136b06fc1d749dee4cd4881b4ecf113f28df2bd4ac + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 2597a577981e1c300ed316423494735483aed71b9f85903dfca56970907910317d72a309adc2cfb0f062d4cb215a1caf67f4543f499001ec9db4db066d9989b600223d3830bf1818809881efb057a7626ed7948f2dcbb9a1582d6f421e08571655916d3a99b14ca30145e3330b31086d5a039a89ade149c9f362cd03c1919b4abe4178713a8400c0d0a21f866cdeb55b1a4202c79a5a26874004eb8a2681742f5bb97ae578faa58e856a8d186a07826a54c1495503d9180073275f139bc1a3749daccec551a809981520aab0c19c3bb59571e9cc0942799f71b502475397e9508d673b14652b65644565a436bba2aa8fbc4802663608e97a2da50249f6187217e01d5f4812f889b958d2ae4af89b255836795049b87bc45ff47549532c00499964e046191c26bdcc8eff1553ff488124d709dae90df510204f234923dacebdb46e5efa933c693c00b4823e276b5d78af2b336309919168fa38a224415ee61a6f729958f5605d57b748a09993f8c809212393b381f1e7c139844dccc37273488562a28fa232b51b6b22de4c0b4c909a03231078f2cb05581cce12432d44a66ea24ddee28ccb2a20a31130822cc74112686599ced4320878826ca51a9e892a5be735260be64c11697fafea1cfe152eae96a4d3acbf21594af1b5507c417679e6bd85e169319931922631e8042c093a6269205b4e8121fad69ea1f4037282852afcb3ec477cf7d25343c59e94e74eea681502c6939c297367dc3502e21724a77f2535a70d383a24d29e872aca63d9cbebd9b737fb2d565968bfd2a27d44061aa88cee5869e3fc96e337033de554ba4229d9ac62743c509ff3cba9c25e7ce3913e9812a5b9ae281c1374e86f653b7d78216af6f233e47a5b9830c5e3c3b932d2604c45c7777898d9078bcea38138a170fba8b41012648983b6c6e1cdfea72ff838922fd55cf1e62688798b6d425d20f2ab12c75714e8b3ec0028441259ff5aa175184731d98d2e7215c87970141580e91cc6cc2561de55387e63346acb04a6f017c9d7cf7ee39b26dcb012fb59eda233efc411aaecb51a6037ed4ab3dc227a4a977100ed804aeab9f7f585c7f5b76f441ef3b2b5b96434a647012fa13c1fabc08d1b46cd8a05753b7f7bc345847151c4a40ffb19238c122e7ca6220ed8acee34129075aae84b3732bb23257b33892c80309b89a0f33b1d7a4102d55f81b1996c90c5258a880e2aa0e80700803b9a80952316e654cb6c2349a0c88117b5f60138a571250ab0cadf7294457646215ca866487e6b8590fa926c2b5c367d1a234714a733671fe6f8b966b9b96b4296692981bd19b519a4a951eabb0d40751d916f03b3223ae4b12851b0d1e7486543272e71097bbaafce2a82642252d650c82f38a4a40b9360d789e00a3a903b71b6b91bb4bc17a67b864312c4c030127de12552f97dd814ce03ec14ce737ce3539a8f71b369c8947a759d18dc2b76aa0edf820d512615e8a7a8dbeb4d7aa92e8faca354f7192f7a42257b92fdfc017de9016a969efea146d1516316e31ad40b5829c06fac16b2c6d425b0b5aa17623af5a26ee4e0587f6c67dbac006c236f0ca216eeebc201c107b2879a247a60b1a7be7094ac8ea62841cd0933ae000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d8e28962213efbabc8a9e3efde9de2573855032cecc3be756c87151a368e15e8c734155213614c931c083fa04313898680f70839229ee7f34eefcf639bbd35f3c375e49aaecfcd3b0b506a1708f4d8c26a69a46483c5db50201db95c0de02f67fff0811b43d58cfa1f2a61838835ba909e87e58708b07ed43c69b1cf67655baac003b6dd004434d22bed1aa21796d3c9c1085a2c04ce5c03797023545a1cd0d6dcdec111b896a7b34b36c24be3bc890a65d3b1f9fb96fc56928d456b845ed5b526865d9d588df3a977cf7ad0277c5e02ffb8ab67360d0009279eae50e8b038d43390000c2805875e9978879288c827fc3fd49305d3ccfa9c7fdb63833b5765b21f70d52ccf2802644332f961029dbec5c0ab56ff9fc72dc3df3b97311ba4058eee91b0634459a59213df74385ecedd341fd0b7235b9d7e061746149ec12cb1c6fa8b28bf995672f1c7cd1c01b80d2be48493988f0a43bba9ba45b6098fa8ab08ff8941aa8ffb2b7fcc82b07afa401f02f562d6b4656eb0fe8a3f8c2e97e45372c35a8b97041e4d2bc92302bd4fab1bd989e16e5ba7c315a8a2441c0607368c116159b005fc18504f12c96d557857e35726f9a4bf2c0012453663cea4481f3b4efbbde568664c54c1be3e346a499ee98e06ce2534b5d9bbcfecb804b8f4ce6b876e1ee00c12ca97b90940334d6cc0fd4cd010e3d83c7c4ae91761d8f73d699d2086e7fd635a028b1ed094e50b633d153f71161094b9aa230cf1bc005a9b2591c4ed06ed9b1695479bc67c41b0f7f3e25cfab21f06c4dfc68fdef64ea5b86ba05fad5b8a5316593c9ff8a9f3636167cb3148e97af82869e42e1bb3f110ffd711478427796256d82a665ef33745ea2b949a4aa55ab56e86d2f5feee5f0b203ff6354399a0ebe00c36d09060e467b434db070e77e9a125ea82362dc76cde94202acc71b47777e6821dc477a466caf6ac724761a1ba63020393ff2c33b6c0e14edca3527e897e184509e48424526534c4f2ef34a91a28711c53675eb4cd3c0419c747e2e67ac03ca3015e651dae27bb559993b2f0d20f0179300e5e69580323534d1289117ad6ee3ba03e3cb5f6bae436b9ef634a8c7be8e8c5567c5576657d1820f83c6578385d7911de91585a28d1d4c681ec03cd69081b40bd5143387fd020a9dc5cbd5fce0e8baed3d16ad548435db9adbe14566052c2d8d93d0b24bcadae084ba69ec63735cf19a6d46d534efa4c65bca47ef83f94d9fedd42578f794549bd5331b9aa1a2fce0c6d83a6e392cd4695e13245f8c91f3e76b187c55ccfc0c0a6344a6c89fa6544a86f762df3c59da21964ba4aed245647c56817a600ea3ad3fcc3c104197e2bc7e09fb81d9f8fb7ef559514da710f8093989f51c5c6dfe18cd821917aac8c7e9bdd9c61296ea839b8a54e466e49454e212314f39d50dc762e6c4c5623a88ddd423536aa51007bf6c56e3697c3879fcc6f2a55f0246a032dbbb073a1048f91d0264845c405c5063852cb507e4c9f3646db75c99abfadb6cd50f7a1 +expected_shared_secret = 8a746f85a41b6c46e0ef358c9407c702c86fb907e85f86de98d6f7bf7d6e9866 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = d4aa88217021609b2499381632883e6c690d720297f130a546b8c101487a31579bfa132c9b06aaf8b6583e633487752aa9fa26551650afe52d67d182bb035848e30696d1be1e56c687eb6387043e28e6a381b4536eb18dbfaaac8f6123ae066ed7568fc1fb580facb933875eea026d182329214cc62f75383d68bccc63788d228f88d17d3aab08f91c19ded4b19a876bc19984075a529dd267b823b7c83bade5e6a782013f8de263e992031e8a32252035e6d292f6d98e022c632d115ef2c60d53e47345e470aadc7816cb6c43f0ae1ee2bec3786b6b159b8d2a958ae567f364c70e4987f237a5d7dcada9066df63018ec4b21f0000f4674a4ca155e761c41c6a54490b3c64c42b2777cbdcc5cce8543a5f9a605e7aac50012c7c2088721d69910f9b3fe26013f45c68b7b04069b9d41555b5d7339c371389c95ca419b77d2c5c1a5b068846972ddab9cafd26308f790ee0a8e7d73ad4c12c4256b237a9659a6ca866197a2ccf39c005c47b4102ebd47607181795cc66a2b677ee68b02a5fa4be222c5f2a5b44436be13aa589044b574997c5f085ca099bfe8b2554ff981d2872a78d6a08840caf9a9051609c586409923a989ab4bc1521b8d23ba04f30a3df77378ce88abf81309de61646ae15e7bb62c8f300b5a7952c5d4881bcc2a81e64a6c612f7c6a9eb8007a2742b4bdc8bc0b5a0218479506c746396867b1a869038943147ccab4a9c735fb318a7b84efd56ed70b05e8a9cd05a650e2fb7ef5c48be6d39222082080b74aa7f4ab869b4e189710770cbbc5a70193597a0282a02445c5f5772750e505b968bf5c665ef2eb79c01a8e12948ddeb641fae4c4e8d7a88d13433611553292910e831d786b0dbf5cc13f77a881f82c98263a86174223184fa96a2c53f1b77c0c12c11c54cbc37776b568b4574b458494ee6b8e0c356a4195bacdf2b11876bfd3a84804a3001a37967b40855326c261d778cb544d346127eb7091821a5bf5eb3c6215b3c7933e05205754635cb4b15a89f827289c20844a6f7e4a817bb140057991858a6091157fde0717bd2428b50711443195f4a9b462eccb9c2325a092439452aaea85521556a17102223a65452c5b152c8b476db176cf76a6575188222215d32b5c08a80e80bb84e7007a350776165c1ba259a2eb06c5a3b36d27ba4b7530a104d2a18cd896dcbabc020a6de3f09bcf24a1e5e5772cec886f5102c71930dc00a07dc71f56fa905cf8acce66a717279ef7718fd9d40864474338c0729f4cae12d2b0bfa579f742c5de322225b0c633359108d8644c47b539d3b6f99cb8bcd42d39208fa5dbb87e600ac3cb1179a63936881748eb99a7bb8631d65dce2078edcc4abf0608575977ff4a805cd81b5679899d36227d1479d25a52072c07e7ac65148559ed558ccb164b9822b5f80575dceb5166121f4ef56c32950ba46217f0dcccd3f4ab8b42b4b0213adc08a5136a404f4532449915cdbcb3fba8ba3aaa7f32a63371f5c09ea1cf1094b205b2681b476375c481a5f336f38251d4bcb652c2a849daa65c827d5163359292b8e4b98a6e6c38fa592fd068197661282d457df84367f5f46815905203d635e9540811b66b990045e4e42532862012ae783c1d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1ea478e56a462e1f366f167cd818372a44d1d0311631d74a6e2ba29a86357bd7e066489d32f4eedb2398e2baf12dc4e90188b81cbd961047889a81c4a2f1c040a4527fef9518029458d524cbdd897409255258a9da92edb0d9bbaac73705614171db771c68532750750a70af8acfdcba1ebd423858b01ce3ecc821f9359c043b37dafb9574c5f4abda2cea0d09c0fedd0cbf40041a613e4de883ec725de57a89a2d0a9ced380acd54bea2eeef2abf769f81d92b302911b4ce0d865b5636372543e218e52c5a1ef0872607e4422a6c10aa77022120ce4875e9b11273281044b5d200a61e3c29a69f177a6fe530399fbfdc4edd2f0aae57102e66a4c48e549afb78e503c90517b7d741abbc2dfea9681ab74bbbe5bab1f25bf4be19964548fe3048cc27be264ad196e837e2e0fdd8475e6909d0d464cfc8df600c1a71523582378d1d70224330c852aa2f70b9536f1768736e95ef8ba0b5f595b683ff8a0a2e691522784a38c44171250719ce54cda4216052df02d164034acd650cd47d465be69399b9a148a5fff2974b7b42beca2039ad52358626e2b8d808b6a52d8b7eae2fd92a7d5b019b018f473b712c2df01295ce33cdb56cead9402adb1f245682d29af706c270d16f63edef39a49e9346a2a647aa8e481e5f72ac87aa5348af2c655c074ecaa0394bf531d9ba5851ec692f577e09918e4013ba53d529dbddc98dc041cb5e11598474f34e5356877c4adcfeda2bc44872ab538b908521088e06a166b58424a462dcbf88ba92362f691ad015083d83aa686147e635842fd2dcf58faf92d94a104719dbf7e5ea19522d395eb4e1092bffabc6aa314de0549381b8ce4b416e102c3fac0adddb2094fd1eea9451d6c14295446606f9e65ddac902a1fcbe65fdda0c1cb5322af2805dbd33633e5d5ed3289bc133983920491728c9b851b46e04c7dbc6a2bd24bfd63d3f5236ca8b2fabd0ae30506c885deb0696317929f3c8aa27b6320ee241d434ec50f2d2423d7c958c6fbfd04b059b3e98214faceb96ed5e3b8fcccf169c7873fb87c1c236539cd1297cbc9f8c3e66408666a678d80ad6e29b85df490fa0e83686aa3261cfa5e123f3fc7dab946691524bef770da4952ce4702d1d854996d9c2e30f8bd88accb0ef4917f3d5f9aa7cc51e566b9f94a3fdddc7640a6bfa0c7b6bdbce57c7fd76102dac7de2761aa971c949020cf11981d55d5a283a1b9943b2692b3a280b6312e32ed52d4f50a38f366b91cec8167f6fe4769f1403ab0750671257194b62b856ee5459d095298001e381d36df7e2c1a5c10241ed4c278d3d477bcbc1973728d7934f9ecdb0ead0d26ee993ec91199bccca33fac5881ff093880b727e2226658ad44c4edfc74b0c3893cd281923724482e1897215d3cad17f1b27dcaba869971f7e24adde068943faa11b45f88cca96997291126523d7ae9f956908a0003e93b39d1b88dabe66ddc777629b8a6202bc0adb7e97f754b0546d5bfdd2a13ad7b316d199b10694de28503e77d6a514e376bea64 +expected_shared_secret = 144bfb50c676e6c8efda24b8f5c94e9305dd281e3a6493d877f3face684df1bf + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = 2a278678a38ca0034edc7b238f66c60b9ac1f309147c4cc7c78c393ec196c5b04c7906cc476b6931c494d0e4b11187948019cb75b0abdba480d61b6a58f4b8d9158486a7b94c05521fd7a1d0e8ba9c5a9612a8351f1b82c6db939ec326f34c13ba5497d7632e076c363157b156a289486a0b8a1b01a7154059149093a59cbe69ab6d8a67673b808fd217fada63f92402261327f84cc85ab50cb93517f4f3697e7b7c684064bc474ee617363f11711e4a7d5a422f68834abdfc685385877444cfab3b42a5e7649e0893d953b0db408bad47a6d8d061b884551e8031d4d2c207c93ff984b71a46c8c6b8174f22604c4a6d2d1c125117a281d37c2e001bdd6c42c3e3b90ea3c4386a7add997018a7330b0c2745f075ec10441870a890722d003d252923ca79ec870291329795072ed804a8045a34651191e824810b4c70b8a00e2c1504ea929364bef4027597f12a5c392889295fd6526f3d36572470a6b48188602093aebb3feb5b54db342bcd70c7ac881da4874f1d058dc3db26fd736acf9377ac64803a4b37743c6ea55969e13579872a6237d374adc29b5eb11a1d9b3aabc0377f550555d367cc7bc0c1b960a877a80a391aada5486c620f58182090436a8e26ac140292e547031ffb16f33c2a3cd2277a50903ebc67a22997d599a0037bbbe73057ef3296c7d3271cb17b13cc844b2aca8cbb1329b4886472747c026f63a1c4131c97dd8253c2a05e9a414b78c3c4fa2a6003712512310ab9b19090d7cf127b29aaf59923db8f33150fe2c34b0ddb8d3989513fd7b4a10495c9d86927b2cb505863b7bb3640912a39d0903db082ee47c0e8a01ab22b256682bbf6bb69b4b2394fe7aeaa939f4b624906b0c1b67665e6560f82c55b6b188aa7762ddd224e9648cc7c2c2e08589f948cc3f2f0b09150879a47a0e8bc1782c5befd0734120069e83814e34c663f115802b220f5277798076863e54ad0496aaf55baf21b5dcf60aa6ca42ef46c3c30052d7b78acd9e40a7079aa437908495c2506549750704577695f70725ef3eb8e98d88683501b3ac08ca8e5b4364c8c68eb5c7e4c690db96ee7194e5cfab7db691a67914c3fc3c219c56e52081f9ccc592de13ee5e266df71a350a63f1a63aa4984b2f4319e3399b058b4b56528bd14191e0657a76476392e9a5d84d83e87a3009b800004f60f4b4ba8d0bb2beac7362e762b417824e1539a2c39be5db8013060c76cd6453e313bbfe87a350982dc04ad7da459dbfab6c3f52b5a779c33047ab4f9ca16238d0049200d394cf44b92caec54659221e2e6b6078ccebb35b6bc045aaa331c8f29b55f3654e51b0ab20c16eb331843d2ae43749f5632056e101cf2ba7bc2921647aa0875f099cb7ac083ea662ecb0be57c383554464ea40f1248802fb9a48ddb4ba409b6db621b5395720b215efe32c47bdac84c5aaaf05c61c4dc2781a87b00710202fabbb077cc93602df8868756334362d3564baaba98c6c80fa15da5b2c924b8c85c918fa0d18bea758fea9b750da0c37751370b4300a1b6a3d7da6566375155793a97269cf4f87172832aee156ac1f18fc1179003637b3aab85db0b7b4b152b4fba7f990964d56c2dbae99d070419690a7b4293c6f345000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e60755df5f91c38cab8e8769ae6c40bac77397480afce10cb1bccb30c8b8729b1bcb2d6be360089e8edbaa14ecaf528c488704870a6b9b299fcdfd910431cfb7da36eb755ad9fecaa91754a28ef2461886a0fea6c757f8e5298e047d5b61ded088a8c04787d32650a9124ade453b9b233832d699e5a71403ac186aec624d25ae3f8154c9b7c1a3723847c9b6e9f97870e81a6fac4888629e3b81e7df3d8a56f911d1559ff6f5fc15eeedbab77b70231d9e4a640ba4e1fef23fbcd073ae4c1793ad824b5c30287f24c52522e6d315e2d90c7fdf692c795b7634c3d935c98012075e0d263e917aa5c9f05ea049e1a8e8009b65c26d53017cfe5d2ca2212a78a5039e12e2b0490c2238dd693978f1d75551539834a954dac8f745a1fa48218eff905a592d0548bd927a5104185934f16c8c46dfe581f6c6ceeec019c73d0a0c041dce578ec5919b9ccc7f5df84822c4f5e82c0e020c6a9c326fdd74626da86fffc3a1067d3081d3c8ab58b3613a9d0f3013eccf6b3e5bc34bef9da1672bfd11d9b51222d109e5d3c66244d9723a4d4e1be1520a15d58f966349fdeaeb587790e2a0d87647f2445b8673be9045940b01647964e3e611433fb126e5619f8cc96a7f2f6bcfaed300592389ff60d40315ab87fd91215249b911166e648708b3c71f412c2b06fdb3fec91d287dcabe7c33b96318381fcde852017cd911bfb0e9bd09fb481af1494ab51c9057d77cdec4d615207d7637c007d2f2515bf532b7402a496d0687a82cf6a603348501585fe9fa987b47e06393f377832f16a6e3bd2022e45a81174a12de22b2a5af4ec78a55c2ca1488c564af9becdbcf2f7b635d88dfa14caf10fbe1ae4fd89c4d57eb04b35b810529b3fe3aa10d202b14e0c2417b1c2cb2adc02474fb4bc74d813dfec562e17c43fcfc1a35df1008c6bcf73a71e67525c78da2b0c5480edac41f839f8f67bddcc14b92d5a04412327a9e1cd34d5c3f5ef6cd1a59af4526d05996fc049a39db14dafd81d96a8f1b80d77a4f330747dc0bcec5214992dbe7fda726e4d0413ddac4ad0f583018a378c844c56d9ea0329904945cfb4f55cd0e0f4ff2358eed74675791d74cb7ab3ece8eefc771106dc4bccc7525e3118b8fb13956125402b310596c5ad0eea3ac8ef75f8b63bbe11ccdf7aad66d05ec052ed9b54becc2fc7ae185c9c752209d29c76bc02d1d05b693e12e660f18a326cc42a4ef4b6dbde69f4c4676c4bfbfd1bf3dd75c262e2f5ae9b4db247d3e824d1d87151c40a7ab56ad5fe9deb8ab40137860e87fcc972e12f6eca84c284eda1b925a2dd4b36eeedac18f1052f280ba55ce11f55b0f45443b4943fb0fa7354068259667defec383e380768276f97af4a0bb7dd2ef1669e69345d08155a0ea23846dbb9397cbdd023d5dbfc4a544572e82f21ad601f31cb01def894978cdb210b3617e65493f898bd6492adf5acdfcde3474f6aff97a86497b9fb6bfdc51882d3d5a3a35c4c80ca1c21fa3031a3985c7a2e34eadaf1ab6182c1a471721ce2d +expected_shared_secret = e3f0f3e54c7a50d4047b6fafea1311637c76e6a426940afc55a432bb7a23956d + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = bb3c06376046b4f295572947b7fc5597b38596655f25f6603255aa19ea7f9fdc5c9efbc5b1343b9d214923121da4fab101076d9144b2881ab988092fa858a407db97248516981a9d4c336df1395c8920496f487c60d46a97368103bb9af9b62162ecca0c023b7bcb71086c1b1ba92efa1b0521b472539b0a87030b7477bdc4d980be20ba45c0aece03c49de971a6f9c8f7522c1a4a6df1225e836640966348a777bb325c4f4b972d484a74c1c743ba88b7d9a3305755992eb5723cc8280aea6ed64b827a0518e7b4cd2cf56bcd97023195a7aca9486ce2b50e35a967da1f8c39c9fcb895cd9895e116b6f58555ae82609fb703732452dd60274ed87adfe293b5a2be5554ba0c455836c98267e77ba6f5b5dd90134e126c703cc1648cc827754c9c2928073493332b6394511e1499c0818866fa0951f8c1400fc51cb9eb6cf37b4a3eb3959ed2af6995c480844291766a66d81713aa6351555068324f84262c9460cbe041598f519c8b387b442a6d6c873508ecccf6b2ae4e89bbd1306f962915a2d759e2e8184df59620d8bd60fb2464ba40188666aad85279423cea249db21b34525b55191375c2f19dfc811d3b77ae56b9366262834c2b1dd500ac17828bcd44c024e90e06e9a7a9607aeaac2c93d48236d114d352859d9a559b9b6e003cbb9a07c65d0a9f264288083609434ba7ab3a826a821bf2db0306a84f386252f7c56011b96fab3b3fe2ea43536a3cd39c2f11d1bc62e03365211e82e4b5287740aac771cd772575c17f0c712c6e1485e8f4cb8e11a89fc4a0296b567e835b6f18946cd3887b56bc4bca9327c52239ab34925c2440ac7cfe6644c9c8058f840143d782ec82793a234e9ce9a2d2f7c96085c6899436cb9c97ba4bc3187b2ed5e622c212ab557bb828e196e0336474e1231ae72f16233ac7f844abf5434d457aef124963c85c25b7414df98bbff69008c27b9f25ab2d9990faba0bd9c00f7d27944f718fbbc1446b3a0e98611af4c22e4ae958ee993f8abc59e3c41252b160de5407a498a0d4f90505da3e90a4b2f8697e99ac7e7c769250a5bc489a74b44cae15a59be7f5922705ad8deaa41d4cbbcde7919c3360e2892914640d19765edaf3203ec950035550072a53b379982b3a3d1d18763f9b1601854679965ba34b1b073809ba675e09997a8519510780b593638dea00cba3598855125ac71c91ad671bca1499037b7791f32fb82134319b1ec041475a238bb5c4ccf3524d613c8aaa096217b5afcd2c4803720b549c8916bcbfac990ada5509c9362488d66f80b2556964a856c06b746a6a27877c0a213bd501b939796ef0cac630705d44e66a1d3c2517f940bbfc711ea1c5dba3a491b61fe4649428c6007052517004416b0201f2440d467733d923277d54bafd729d84e2440270a259c14d88a4564fc9941152b591aa644fc93abf08371ac162b9e180c0fcb2783653e5137a9faa04ba137113697b11e419dbd708f18b2fb5f20409448f31906c2a557da57621ad4242524a8f9f754e199a2b62e87132a33af47166dc614dc7034935c4b21b7c102d71762239c03084bf0e381524a94b6c22a7e499baf0ab6c9bbc8573909c8e99ab09a44e6d3b017dec2cba8b60c134000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d388adf22faa385735ac4630979b0d692aab8fc502ac7f8a0e3561400f8d04a4447cc9ad1003d530ad2f7b5da076b02bf291aa837ba4212d43bfc514ee60a422c07471572340d7fd5fd127dd82283a4e0d145e294841124d0dfef27579119d8a9eda24bec0aedce586026d1107568831363fee0187f8a0bfaeb384bc9ec4282d03acc461e26c4b2826b15943d95d96ed7cb72c53665e19ef8b4641f6eef759a1d7fe860cf72c342b3d3e2fc784269460e0a1ba6c394a9c24db5a4c5f6ac523a155491d149806d73550b2b9f8f00074dd06ba24188a3bbb5f3370f398011899758365850054928429a7565ca5b9935f5e1b2600a779152dac16e78486a716a393cbb917f060c83a5a0cd56f1ce4de12bf088cd5e80e540ae97a2ce2b8ea35b3a7011116c7131aef928c23809b3ab4a464497d4be034543d5ff1112c6ea13242c4b60503607b9f4de544cb49c4580518e15ba51c12518312cd44dfcf39a4c544c71a84cfce3f70b789e4814ffb36c1e0767f15ffdc82ae5f0800bd8e2a973b8f30f34ffc792c9f7db5a91c2e0e02461ecaeaf2ae5d33e879f01475e102f85609acd1a8f0b1fc57739c331c25bf0caccba793b659d90483c220bd9cbf0691c5a4f11fa0c87fd630243a9f6e9d6082017dfc84b6ef1cb1fc793d14aad856fbbe051c724557eac7c8f123fd50c0c8368d48f153ab93da02b09fcbe5a91eaf3ffc9a7837b1e68170cd544057afff19163d3ff479b1d2be4f834a5b8ea082e2e37d9932936e5b3ead4ac83201a504ef4bbb6621349fb473aa38bd0370ee39105c5b635c1b149e263f5513867abab92c00c4019e6206600829f1b3ac1c849139cd4e04247801b2d126bfe94c6c019916247ea2fec03598aedc84197dcf7db900653fbb5236c52b640f1b489d79ccb4e4d062e77b6f9772218f64b02b3c29044c62279f11755791d8600758850cad537800e77d7727a63802e3a256031c94f3cd3f7cd20e10a781a29c2f699a3b4425ba4198d3e9fb3e5fcc726d99bc735ff16e2d1eaed171fe4ed00b0fccd81a8d08dd5d4a6c72bb8909ab98c35e0efaea3e9a4ed31ab0c6ddab06444150d36637077275796802b792354567f2af4dfe79bbc095f2bf801db578ce720e8e4fc9ff772d016bf400e5d330560aa5d91760f3dbfe7c0a175f7d0e730665ac079b4aa29f9b51a20784bee6020be8cd3862b3d992863d25a8215e1169f5eb4cfda064cbba34e1344009b461334490f7261c9a6a4457fcfe7b8536c59a8ee36703e8b439feafa9b4536119b863a91805706dbeb6e79a9aaa8d3c959acd75ed03cf0137546141fce29dc5723db5356661b62a5e2addc6cf479cbb4b6214e44b0674381fcf8d23bff22ab413701d8613cb03e140e85e6c00f75204a6fb1ed29ce15ec90cceaed7e216876b5e5b21b7e99da01f6c2c6318591e57e188548dc9a98e14a61c472d9726cbb09635bf99b32fbad21e4777804565d749b380924d7d5de3ec6be5b4b2cd2b784abc179b478c9237e111ce04f99706bd85c7 +expected_shared_secret = a8006ea55b49d054de26ec8780ee0928650ba04f33699616396fbd980d9bbd72 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 1c5c222e297e1951c5424665e24b2f8c0a98fe5988a202b02db7021b8caf6f390469cb3a3a44b1bba8028572290ad3987c84380706046d3147f2a098f6c11912d204ca7830b49946da095d77e4b55fbc763df31a6731b9bfe871f8f383d3645a44b18e8b59bf1841c48da75a66a1322a70c186d7751853949a83af71494384221876695a35eb526b3431b4c02a00503d962c1e35898cfe9666b5b71aa88309266ac0cb7c50121707c06086e4d7aaa918ba75f2ac0502a43d985eaec44c081b7aac733c065b2af38807477501dfd6a84436bf9609b5ee21c78e2c5ea1e2053853b0ebb570fec357fbd227123683292c58d082b4990c7b8a9b8a15b1a72017844b572eded48d2f902621280cc4d0174e0a04c712b558184ab893bb70b39f7e92b5c3ac61c4e0a4070a78a6b0bed6170a0e07606fd15f0dbc553c64672ca3b8c30821d6973a5176aa2a0343fa15a75d26953b965d64d94b6e3c5873fc2ecd13199f9caee6672847a87dc7d31534870502c3a0b9493aaaa5441099b29a2c0078854e13f15e1da411cd086a12f587ccd03038c049e8ba7532db25d4a855a1f7696a0737c1fb5e2130a4f3ca0ae1a45429a44ee55604e31858db353241d620818a5b9698556833398878825f22a2f0b739d39c07242aa2d349002979929af37c74457683f940e503ab5e475035921abc92b5850b39f6d2052f811a869c11aac93fb6e063e7b495a958670e276e6e64bb63268bcd01064a782ba3443c4e0255e3db3e55ba7082438bc303c94146bc67270a12265eec0637761c47ef5c19fdd22d4685c335146998a4ab70e6b3a9f63c7f95257cb7a7ac216c480568056a825ba6b6a25b084a604349bc4fd668a0c6bccf84db88fbd504aad20b68b67ca7d7c9881b948af06ba3f172456b250850aa03580de5312bd85b9ff9e746fb26c8e3da128e2ca463bb010a6872bfe975947b9b00bbbae5e53cace8380d1c3b34e71b35517764635f1c29be58b9aeb4704b2bd58f81a7a20ed1a0a505a994b0a8e71a72431991541c9b39d4b7de179df2ba5dbc12af93f057358301d701c3fbf119d1f450ba9900c483546e3cb55716ab5f193dcbc6c175697d9403816b263bbb71930f55081d8c945db976ff8b130ef1164d6bc8d0d1b2244a08b5903587932bbdbb7d60a29ec8016c9cd30ec7b81b1bd527b59c063c134340d35495d89f3d46728159874b8cb8edeab232885d635c1e46f4653c70c95aeb0370da4529d319a812c9b9d210f8655222ab13dae5c0f9bc3b6b55a23edc15b132c937c0833beb8058529a1f2a880d7b198c947c65db8a0423848720248d7cc937346bf0e01996032106192c58131335fc52b6817c97250d71f613a0217fec98b713a08998b8932ce850097361f077683147740a8a18cb16367fc1cc8771bb50fa550c667fa28822ca407399634eb42a79250483663708819c55fae2c4cca04ebfbb7582bc84ce27c2796955d334af342589ab196b3d03ba7b58bb209017c69a95672138b526245137265948239476496a6100d9ec7092d931f8009bfff9a7dc22908074c3e41a8e6ffcc199fca488753321467850514ff99606b7a8b975c03b05e3c031a99da72bc953db617dc41d664cad9913000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 852e70f6d10dcba613c39fef87c4147fbe2af99288ad6c18b6e266dad0746ee662ad0926f4c0ebd669b27b893777a545d12744de0ee34da7b38568eb1809245f9a03547704e353ba537f35d5784c37ca5cbf3696975aee1ead6b376960131f6e73250307390b74a10645cb38c7c16a7bff98324f994e6e3a8d7a0c0ceac903e8be98892bab7d7691ca83233d61a31c2295a134682176787a40a263f9d8a97c9b262ad343f3823739bac811f95014f6403c0bd8a7fea4064454333e8eb63dfff6b3a9afe291217b0b0178c075cf04ee3a0895606c422e24b634237c1ee72784e14af8bfcc232ebdbcd2b493efd28c9a849bf47737e20948ae7a399907b0f2a5ac9ded63aee710a30f76327f3e1ad042dc12776fef148daa0acafed5598650eaf46dd53998e6c38ed318ce56bd35ed18f99a34fcb4f427b3de31f4fd0ce2bdce0f80248ff2370e08cc2eec3e6a71783aba779abf38a8bcdac9abb75d80625bb4420e2bca3cf4d8867bab62d6b884ae9e6f98099458158947e1169685b1a6f7d6f554bffab3dad8488e0a159232f3777cf85d9dd4399a89f1610943bb7279514e0fc3737ef8ef9ba12a4db6d11933db6f57c48b54db03470b0deb7dadbff48d75ccdf374f8bab3b7d3752c8dc4b513070fcd884d94e435e63b4b40c15abf109ccc5d9ab51c4d069685550baeacf37a6736daebad595f96e2f82c5c458a27e129af4dde2eac2a5768f5e4a4970a0bc68bc4d0d32fbc275d1aa988ea425838297722b826852735c4931b97e145be9c6b399bbf4e970c83e98bd5c1be7942c6419b0819e600015ea82ca0d55894b0ace32f24b2652424b85b0f86755f1f8db64138a704cb6ec6f3e2a4a5e708713398101e0cf8d6029ffccdddd03d8a8074792232622e00384ee5b9db3535d7ebb14713a32806861877ed3ad5b293980b68f0408eedbbeee9bf449698f0ecee6635f0a8905d378d083f80a482334d30443c139cf5a1e2ea7048cc4a1829ff36f9e0f674ca22d794c2d7e9dd3cea60318788e56b3e6670215b82acdd4c9534fcf5545eac516261dbe4bb2e7fc38face7c59668487507ac122d295ca90af4035760c9b89ec44f432e8977583ea2da6a21249f667fbbb5c4307bd3f2e47ddfc8aeacb54bc33d1365ca3b6f75c0b50917e2c84849f1898a3e1c76ea67b21143f39d4002026b0e2686908bb9fa502a88c7b5c747f57c13b9704452c1ceb14a5342e40cad9987bfb32c769f110d3d39cd41178e248d51fe7d7f1c55a5f64764814495cf92a4155640a4d3411a74597f4c8571dd0662ac2ccf0ec3a82750c0ba5c3745247b7f09b62dd9c6484a1e0a0199555078d3a750784c96be465053f3e024189cfa2875b3763971b48b5c8ecd155f879f494d9be7f4e27417a6fbb8843200eefceb4334341f8a5a0e98769cc977979b405fb0efccbf442008f7cfa18b28b48ab56682a91d8362b6b5df54db3dcdfa25d4740a13ad8dbe014b210ec14af156b34511896e64d08f37b2cf2a383466351270118846b6fe505 +expected_shared_secret = 8da6007bf6e536286b9f65fec6f014680d193306a55d37978cb56b245e256eb9 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 0cc2bf4fcc4e0ec002da4250cd5320095843f29795b36b634ac922e3796ae428c894b1703332b83d9759027588f1ab2539180b75da984246a745ab595c46ce9852029995997ab27fa2b94e165025e7e7061f2cb35a907eb6ebb0e1d2a29e139f179078dbe13abf1787c3282fe45a1578e5752b6950e7428ff2693c6e6c4ad9b960f024a7e1f41783f7112489112af688b762819b222e1d6246717b730aa9b224ea64a1a45ace60257522505e69bd1b2235f8d71f8ba5b5ed425ffcdba742379a7e1c28af1c8b35994324051d7b46a6047b77762c158fd5977e57bd4f398d4f1a70175897de6c8a3ff6ae90373065233d7c4a0e5dcb8b0731914b37cbdd29148be2649f055df6bb82fb398a630a6c556c3fc442ad78e24bd1406a35d82c5f582610bbae17d118b3f0347bd84f7b8a6deaeba8c698c456502eff6203594966c1f7413a056064d09bdd273b0ce56e506c0cce2267df24a13d7a0cb5513273f37438b568c569681314c3b6db28e05478e075abfdd53cd9291614c2650dd58b40f66b10e3a5cd11ae650aac35821d5ff612d1662a3714962b3411e5996e3ca3b839a58898848ebfb869e9b214635109129c333e931b22d34c63c96a74c3745be124c153512c060ccc6a36d244139f106bcd78808db7cd0dbc3e5b452ec753a643107a5f946b8f319a0fd28bf86c08bd16cb0324c44a0ca5165174f4681b6fe85b21791bbe1b11874270069839213b5829aca7861ac642e4757437742898416e2988c3277f9ce35f82218e9eb72afec300b9e59bd1b10349994bcb34c9fd2b31ff7482ac4c75b693af46a581dd85cf33d21e600bbc2921ba49053cd5d28595799fe23541a7d6b4e4e6b59f761e0339157d5a272406be1a776b3eb2c3d33055626712b304c4e651996f26866dd8a99c607f0a044a4ed4c04eac8122114eb6f567e1133a7d385b4edc71d19655668a86cd64503f0bb1cfdc06d9d387e55296c4a76a71b78e64daa58440264a8a6e73d2bb8c028ec970c3fd7535bcd65110967cff563ee9c5777a465003fa7ad97230c2c76bfc41b5c9d26d9a7c3605905fcd99b36ad5c6ff585513f633b26617f144a3dc4c70cbb40b7c3b8d0331014fbbb7f3c59179d226dcd4758ccc3cab8679085103e8949ea10c796204ae993750104a2123ebb902aa8902b6241be505a9e3a6734191734bba77c969e92a9c0894367dec1f0d50ce5046ad6f3aabdb138f5746a737082bcf6b8d0777b4bce1a9a35b2e0d794ef713736b4966d1322594eb8e90a5af2b42c2d7874296401f4e6a66c088a73580362031c9b0119d22dc9e6b649ff220919d42167f5ab863603d474051e3c424a0f8516ec0652545c6bf0831cd8aaa992c120d2477f791ba1ff56ed2bbc2e39266cf618580b7b19aa94755869d7834a7d4a87e234c25c0e595cea31a8715bd76d3bf5e6badfc4a758d7bcb88b5a018228c234836a0c77bed231a64249a064402d5f0b66276113022b3bca4486efa97103560751b108a5a10579c73c1e06b0eb117ba5a635b459e2f3887734b83dceab3ce9a7dc758265471b795221958359ff3ea282bd2c099436fe3d3c5b2000cf0db36a63123e9c897249130d1d27bba527eea241d8c930ff80d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = b931ab298f4492e30329ab86e3d92e6241f72c568f8a2744d493c2b02b8d5d41470f0d73ffc08deb1812a6f4143f97afee2682f6d4809a0ef3e97ac2ae4468a5d436c5549f751b440167f86cf238270eb8c2e3d3d9ac004fb9ef5245d32b4740fe79543c073b41c8a1773f11b41c04ea5eaa467758660c17a6b38cf19b151e9b6c68fc35708be261a9e7cc45d771853132a5d7059e3b6b9bc94755f451452f444377be5821aafcddb7e708fb80f31bf1a89e1691009e1e36b09d754870e24fdc640afb41ac6c4260b68dece256aa9467dfbd29a25ab901bd1dbaf2efc055263f06780a73fea14bafb12f14ea2b6516c97b1a9f56713554b218613510ed7637940272b502ef32c3f99718efa3fac323207da815c6c5d04823dd28f99049ec50fbc590f519d843e0cece45713e42ceffd48dc1b7a739124c698acffd4fcf1390351af06ac1212be3abc5f8a51369c57b0108fc593c5d7185686c6a27363416e53f1d578e7066456e6164c030328ac53c2ea6fbb6ff508be8c2f973d3a43476831c94a7e85de88b71fa77be26168f82ca3620d1024e2bf998340271a4e2df0654ef1b6c9d5a8d95ace50a5f5ca3d321a9286210a21ab97d64066390e287d85345d22f6b42d597c5ca8888c1f871e34a4d1d7e89380abc284afe3f1f7784d47f75c674354825791191b2cbf5607ad26931bc0bd05ad2113d5c93c9e0e71a8b6c69ae4df3383baf71877bd3274de23d68ae57d54e3679b40950c73fcd38c1b8ed7c58f887e5cbc74bd388f77b72875828667b143571f6d0b69cebdf828b49d6f4a6d9dbbdb2188e1b0b30eea6a5b9970962f00f8b8440dda64629988de710a3e086e6a220d27358272b680a91195115741c77ff04c0bed30a2c47422664669aee91d263a196ad48dc24bd386dd9df5724965f2af73bb7a406bf9d17f3485f140b52fdbb06b9153bd96cf0be8ed4c0024571f859c8492ed4d970e700e11360d4cd51b3cb29decc38944a895978824ee94ee6ccb6988337755c07491f43526db47e557636740b393d460b3434fa70833c490ff59aa62e0fdff9a0e664dea7425ee586c29c7648a3ce8ebe5b441f647596af140a87d9525643bd97707cd910e17cec76ed33f4dec0c5222ca182654c8b5ca12d5801ea4c26bc7ab9877d9f838d8455b59c5590f4c602887e219a12077f9639be7a6f5d227d64540f3636c46cbc1461e665f677b0183c5ce13f77d923b368d05030b04c16ceda5d511fd0db061ef3b626e50767cce8a5cc108486e941b7912d944a7a0e0acdf050eab2f600c242c250bcfdb93ab9218a4b495457dddb959e0a8f976bbe147674d5ee92ba71491812ed10fb7de3e607d6ae67344e0a611a6e82a1b66e0528598b30daf398c98d5370e6a1630b7d10d98b12a1470fff4c04a1859415595362e29c3245164a2f1124189c3c0e7b0c875c658fab040c5e0ab690193e3eb1951f24ef0f39bf51fdacd68b65b445266b758dea04de3b3d3137c9445351e9fb80f394b76f24383c49c747e9b15814 +expected_shared_secret = 46f591e3c6491c7e12d58a7d06ea5354bbb77337572b70d94e4badf7ce394e08 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = f8569c9dd09912b200bcb155e7f388139675afca87b0aab4e4e2535207b4d1123062772bc8aaa028597d15f02f1240b3a4aa96c1b344b0b892bd52b3856ccf6ae94028574f13c09418eb998f741c1607461bdb8cf4094c795acada2c015bc2b5f4da99bc85b6715b6bd57aba2d016220ba2db3a9ccf6524474e0c3cf0003376b2aec2b031cc4a224b66e139397e338a8a1ca0ad7c8a8356b09078588955157fee40e4ea1177f7c13261427eb047d14a826fbdba1cf607547a93a61c8a5ba200abcb676deba97fab023f5234b46c99cbbb38f27fb68b0a2b89937be4f61b3bad5446b74542b52048ec9310b1a2c30c25c569a2fba55be118472f6147dd65b171c654e8c3acc53637a2f409dd14b99ab1a772d755bf34a43fa745f7d2a55600a8873a5cf852b1f6356bcbc2a70d134471c7720918528b63270e729472d1093ef72629c521e49508a3e584f81250717f73909e36e231b0883d9c474ea0dd64400d26317fb8569106983b4bc3d0818987adb741d547fb15235811819493c1a92f665352a92495acb6981aa5fe83fbcf620045275017bb652ccce8b748eb9354bc374c131a74854f9a2bba3173b1c4004607a2c975e3ca635737a7f5bd35c8798174f6bc30473c5e700b42a96054de8237b1927f999351f370f1e241d89083ab9cb09a9e908fa82a0a3ec9f37375f30eac10e20ae566b4ebf811513825baa99c7a9265f73b2833808a52a755bb106afce71721e71c693f29b402b8e483000e1a6375ba0848881c817b47d3cf8a2d64a757eb80e02109a8e0a873eda7333e7847902a4f4c44e533a8a8039516549aa7f172579e063d73999eaf47c13d73749796dd022cfcc9522738127a1c984d9d3755c29bfc6b52c08297662e24ab77790c056101bb2916385bf418222d752408ad1843cf6bd80353a2068ca714c082ef86503064274f94065926fc59c107ec5594b365606b20bc010946f60c7516c4e59c33a527ca3229b2cc35459bcdabb9dd8170b1b319571b535d514f37b3de62a906a05bb90320b88b989d3204511a2151bf39425a1572c192d8be2b695f18dff4a7ba7206d4409c9e51c54f5797ff9055837d2459dc85233d3c95a597f7596580a83ca3cd6ced5278c24142f90b653280b54fba3159147cb08095422d4765112030f5a696a628d8a67b90d27762665274c338540d7a32894523bc53dbfa760146b32edb938461c14792216a4b94615615afb151604f31b518c37ccd502709325a2013aaf22ac49a67350067f405809addb023e9a13d6734ce5e71f802a147c191536eccde7a67295bc86322a7fb83308f40a5517b61a790a8fccc469dfd752a45416f352b6eab11f0623551b49a5ec2754a674c1847bcfce66c9f80946eb65a419c06747c2a037a492d11947afac79db877af9750a85652f6b06447216bd69418a86169614e27b3579a8b3b669f8eb8b84c252574c856d91b081043710d0abca178b215854f867c5b0da0266977fa1e75d29d560015755f64b867f011369ab7189a916207c99deeab286e635b4aa6521da156c310cf4a592926b33f49062c94129a9547ae24a7e0bfb6d4f67bfefaa68cce739f46815afe593e8ab3a63a90797c01aab7a5f0e73a2d589000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 87147134ba6c085c2b878dd751b77273438b4e9efb50696b22e725bca466abff4ba40a150b68401f043b73127177e579be1d727ad37ebb79b2f5d3ba038d4a8a6b74633f31bffb103290c0694beb9c4cefcf47fb2f33ffb3d8b6126665cee64c6eaf385a816167d149a328df0efd29c4bf324e4f3769f8d7dc784da38bedcd8a653a42b0738661d3799db5c9a8c65b88849d07b27c5c88032a3b090026fa2d818a4e26672fc81a97769e432b217df4c551243354131100947f91df1cb442200a08eded975c39b74da9c22dca588f8fe63cbbb6470e3b029eebfb5ecef2825e834fdcfa2337f55571506498dbf2c97fc02baecd0d14ddbbbb4bf48eae0de95d42cc8b364d6703574a0faf12f72df2482b78b005d800e31bf1492f4250254a0a48990505300d90baf577191d8cb6161a4b39d18c84515f26216af074d110bed4b2af846ae9b13fc485e55f9a72f7347efb147045f27c914a415fffa32ab9f8251a03fc7efef160da5dc25e5b5ff12fd5e999fb7e55c9014a9866e2018d09a4e5b3a3c1c833985e3bfe3cf484a6910248794e636822c40f6a7ba6cc35baafd7557e1000da487574bc7f252c9b82b19febc1455de0b9b79ad1f69931180b47367c8f621b46fc09d8a6d43d91078121956eb44ee1f1548f8d3513a300c626aabe660ae38fc0625ad42afbb5786694b747c65fa38292cd5127f20d8ef0039daeb8963d8639a17a64012357d1612910591faf05e842e23f14faa4b01cb657bb4a4cec7a11d35cc2dacd5556ae116a1dc53a82d1f9ce151a41dd05c953407669f86730f9ffb68478179306d56009f2e937e77995937ff72df576c552672893f1f4021d1be8511ed04d02278c9628b0ecd3182a32ffcd9e37ab0795cb161b50ecd0f97aaa90a9b4af816dcc21ec5f1f54e7170a4167dd2017325888732138e854aaf7e2eeaa964d974cfd3fb810386937e92ad92cb4fd0b730004918aa6eba5b64d1df55f9c2d0d4c2db8188918b7812a71592d4a0924fa67b62e3feeb78106e491cbb7ac9d456c3bcd747db26ebd3b822944bbacb1e742578b35b4d6d9f49efca4c929276ca6015739a0b4a369a7961babe2ac95b3df89214630218182aaff57be9268367282e4a040accded4cb93170cfd765535e26d2ffcc4e6eb6832ebe880497dbe5edc3c724b659727d5aa9b067719b6a9f02616504cd3eddf0d56e33766856b4542132560619866958f8aa54d434d302f9280208fcd3ff42bccfeb450d6ad4f0dad91208d357b2174fa67df22ea7b4b3176843bdd5e581654fef45c16017fee95b92e5a1f33cc6e3eb1db250e7c6485d368f8fe9e53f5c863edb436d7ea007af06570d3725f07213f24989a637d9481ee38e26a4713450d122849990892bb2f95abb6c402053a9d41bc8b9cc9281bc6a45e295997a1523942f125c3f899f9722397dd1678d3d30e43c20fb0f57ba95e6d825adb66ad7cd23c7a921709b921bf1bdf0c22838ccadc9866c61880de260f32aae94d6fb6e5310e72ef8d881c3d5aa08 +expected_shared_secret = 05c30333e58ef628d111f6aea0cd8eaefb393f4e1b9ea8ce21c16decc506a407 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 4af3214683995edbbcb52acd7830454cf669b608c3cda86752d97e95c16c99b258ae01735c94a7bcfb585f451d58a0673103b203e32f64dc94b301363cf1542202074458b6d6e8cd0076327718531ba40f2543a1a91b0fbbc76a93ba4c6685bba5560a9d6c6c42897fff8594ec665e311ab39edbc99580c35b35796b0c3b0d89b8658a1b140979ecd28e87f135b5b781374a766cc18f1fc03a7a3ac7f5fc0c639a2ffb43bbfe74c709b303abb1432614bb3388baf38980f18a141d502797674d76bc8159a8062c79146f24973d090bd70390961ba5ef62a5575abad1219e5bd2c3a063acca14702ee58a32a593c5236bbd4ba938a339108c8cabf2a08516408444584ecc4124991cba6219c7f031ece14288097ae7ca9fd370a52ed7835388403816bb1bac26d56809e9ea77a788c8d6bb215b0caeda1717884913754c42190cbf10387e56f92bf46209fe448312d930cd735770b6ba940cacd71a04d1692044a1930b0c11b701c851a26c2462b0451930180415de6a1addc504724042bb832faae8576f2316fd718657d7ba8c975f6584cc91c9cef5609a433b6cb1f08476363687944bc58c888a00925cdb862df89cf96b5a9e7948c53a51d02001e0a97bcf4735d99554bc86106f0970869a4470794e20051723f40ec64625ade826bbb9bdf962a0190c708c0946d96263ae580e0968b01d03c31d494bc002737d990bd0252662bc34337b1093b97d084baa73eab8636615a832b7df2a9c6196495ca7422ebc208d6048e16c2390c1c91325a30f9ba64b06911fe41b5ce35f62c1567029018d34775b6a0c8f70081e5c12d0c73dd6693b34e29c6c669fc485c6b5004fa06a7fc2d2c995bc15b477a1f7463d12016613b24332e4729f8784f9024c2b4c2e91a9055cda9347f7cc02f532c3e80620fbb124f0b8da57abc6e421606b2422dc450c5b97ba040d781a0ab4ba5cb7998aa5ab8a0681339dd4b8c1eb77ff830a4e865f36897899d003bab7395f5b580b78b0046014181c640341aa0a5920b1609245f140bc7a31fa942157569096495affa32248c4a67ff5456fd8189b5593412539173c6fc898118b2b98535401ccccc1fa7945eac36bd248cd081925c941937213263c81274bec5773abb1c4607373029c6fa59723b893fde7b77124929361467aeaa1a86278e6b3c47a68cbc28781ad199c68bc09f3538f2933aa011b800f9609f6887ca4fb3857f869c1ac3147a842359065b6a59d999465ebd4228735a5c7f984cc93928d4c7c44ec4d90d55d66709ef68827df87abcdf433f79342ad4152e405ae69f56689747ecbbc0b23d55c5f86b5a699a06df3573d8715c6e667bab949da615dc1f9620dd28d2eb1ae6674506ddb212b315b7c89b050e48fb76a4946b7572e6a187dcb4130c80f38328037e2ae7477bcfaa71efc3531b2438800744116b96a0f48a1e549a33d19b0a05c206baa07345ac3427578650a97ea1150ab66cacbe848d39c0c744612b4d0738075251f7bb508113126a6b0e93b67bef50e07843c271614a4dc8799bcbd633a1879195f570907c05310fc91ae2e6a7ef474c6cc1112653589b32393d1bb6d741c19d616b6a93c2adcea5762d35aa285702882463b1d5cb9de000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 738318f855b7a4cf13603f7cb528da3e04dbf38e61b3947e9c98d96d4733e6a2096a06afd90b4ce3eebdad11c4635d9e1ae8e058908df28e936cd049100ce5b69a29f80ab7e827c3be492bd854d20f9b0788fd3c933f3827add6ddfceb81a95f116d48adbdd6f543bc312fd5fea9f1fff44f97ac89b1695ca27f6afdd4a01eb80182830f4e1fe457f1dd7ea64c496f49b4904e47be3919a0d90da460ce60c8a6d66bc8d3ff55a8a580899eed0597981b9118c7deebbb746d015c8e117814f9abd649d6616bc075239cd7301413c4815eb880f7162666f296e06e4df2349272058d8f13e7255707830e98acc340195c0f0b61080fa8aeee33f1ef7a02e3faad19f1ced92c3941751980f5dd3c33b933423ec450f16543f480b6c3773764cd09a469db5d4fda16c64a0b80105f796adcefea0cf17fb41887e29d56b86d35574aa8a04992160408b6c30bb6370ad3b2eb0b8d772ef1680f1160e4fd3a6431ae5eef86ba8a4550b9344e2155e7606f211e85160642e83a923c76989d5f131986ba424c2d007b22d3efb868fcbdcf0b78a41b59d34c9fb24d3d65b9fa3bb87e36601ce99ecce01cc44bc120e983aa0142e6a56a3a6a19ca75c73185d48bb6179f8dece198e59ab821dbb83c429336e81f90b562f3da63c3fc910a13b8bb04a8e53ec067377fc1f1db752e9b2caf3827870e01f5f632734658a2c69da353959e5f00574d595bcddc551bb728bc13267acb7cade43b21b244a54716ba3b765ae331fca979948ded2c7fcb9a773d6bbd4509536d29b730712dec068353fdcb9d267b5ef0f905f34823a21a1be3df2657a078e678f6eeb6e0ab1c65c034b329421bcbc8f505a58a78d250e1a003d13d928cd6d305842dd127cfc805b02280d6f6146446b551ccbbbac16a4f1316359e5c2b801a31f674ec5a48287d7818f7e8e56f53c77a0004d8cabb530f95a54477fe5ed63dd47bdbc3d3d26194d9a488a909fbd4a3ec97163c7b8fd0467c6bc20d1cfd03046200baf232f6f5a6798300b70c197f1f616d12cdd17691406636fb1094a2e3e4343beb84f9a67146921397ae9be4160c1c81886db504591122ae7c90f1131572e54152ee1a203f521405bb928af9441a63fcb5445c5e9b2afce13800750babfeb6fa88994a8330d8d51061642698f02380d853bf2a57a8eace6b1d52361820342d00bfffc2dbfbbc3c0a8699c5f80fae249dc1bac232383b6eeb243d9e960809fafa5bea564fd610ca7c399c4dbf5000e4386f4700a561450d02d92d8b5ccf428306a9e57eaff931b31a4ca17e4d6a179db2abe53452560649f5b8f1858c0f66bf64fcd440b6384dff5e62f8983d46d924d85a4b449543ef8d5e0c023353aefc8f552e186b84378a1c34375cc28d83a62b04addcd057f4d83b42926f811b2f9e0bdf9d59cc1f65dbed5835b60404c048b386a3d09e0e7700735fdcb124c4238e1874f99703a685645cbd5cc3506799984d0ead93cfdcb6507d0cd757d2c0f1e350b17a1258e65965c2c6c092b6d4663aa3 +expected_shared_secret = 10198ed9166d13a1ca423fe3b36244be9b94fe16deb306ad742f505ace69e1d3 + +comment = Rho leads to frequent rejection on matrix expansion +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = cab527e162b7b5b390723c83ffc170e3e153b16285676101d66999fab321e9577d9f284fc3531e50715e790a2714e404232640de9bb0a4649e344ba2c33977f20c4488463a0dc58c1f71055b353a749a54db7b9dd1321d1f2812ce8a90a503a1e0e36ce0ab91309424b896bca7d39575bb6129e0460282c76b3937313839ad8672d4a13ef0f9c738c3c473f38be4a84de989c745576ad6f3bf7933879f69b8d72b93aff64c3d29292a794db4a140029519b99abd78017e5d84c578369a71089ac7b93c97a114e74a62c98b0b7ad707e60b0332b82af5d346f8373c11c83bfe543d8fb10cb9f128f1509ac3e02ceef44e52070305853fab0831bb05bc4ab8b311a2867a051b2e43a8254c787fd437838160ff13b752255e52a466b8543865dc61a40681b1e74eb7504442e943f99b7a4a695119628dd8603f9ce29bb9ab9202cbc52b78bea806d0d2305b442943c3d812e2d2cf07f2c2df778c6d6794114189162c537a9540a0bb75660548ffc56b1a5598aadc5055067f87d545f87b5bb232ad6497bf5f68110d16530bf80380410b67a47b081587fa78acc0621e70624605456aefd9ae2849c715a89a00332779216a6a8b3418196e23e76f919c6d4476b4ca606fa212258bd520e9d9162b066ac4e12568b532d584cd091606eb9a2f91882daaa2815230bc21ac33e8a8408be21b13c1cf90ab1e6f753843f6b5fd3446f93a2072cb3a94d5090e870ff2d788a94c912837899c2b04598c0085409acd1767214c822cf3579637c8beb94ff9b6327ff47ef5618e70a5bdcc76c287551ee2ac24229507b0d87b779cc59be8cc4d30ae0e161ab62a05c7eaa9a209152f37c798a2b1c76b2265dbcf930b131ad88c65224c4a5a2d1712c2a631c2982bca5afa6029e52824920c3c7b3093988d998001bfa23d9b01c91b111cc0fb7accb88d34f34bb7829192d21923d15faa81267e284b7aa18df181a02932a56dc4662f19148d055a91f8a3d97407ab9257108b7447e24a24c12a65fb1331dc2d06f60561d7bac9c993797255340c6770025f776270742c88ee4a899609304d75b55dd2c303b97cff2871cca3bb9cc8400b930087571dbb4c73ea1460bfd34595650098f38548906c2a8154b4017626a6b8a1db4b2a221c010937fcc8c06d6c7132688e1f2bccc869ca8f881303a52bc6313149b6450de00728808143f438be904c8de5923d8a02482a3a201b050d4b1735867eb8e7bf11d5023668c37c867d156ccadb2c383e113dace4a090aa9c1cc530cd17a94fba6c6ef062eb357e3293b343b169c6e169209b0faf0bbd5e42c3b6c077b1728ebb2a1e44d431f7c34835d9b0021871aac86d0782448d08236d94c0f69a46090b6c5916339baa15222a0496600dbf012c20faab5c7b7613c85a5c759d178c6a9b1596d291ce6b975363e47331b16735db2fee1027ffd018d8f338d712b2a79729fd20392c837fe40b3bb0ec9f11fa566e426637149d9041088419575db0734d854d0a0c769550a8dfb80da3cb9f4a7ba9b4c84e45b3457007ba2f380d19098d4f915023ab00e0872dd6485e1b365802d0326bda7c75e7346b001cfdb5710d1746bfccb0946151abeb7122baa4b79c4f6cc10828771cc916000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 37abc2d961d3bba2efa196b62a4f9acbcd14137a7253a9b30fadd1455c22014f3542558291c55a8a00cb44aabb2d0726210b887933dd24955282fb51d17d1838b6804186de8130529c251621677d8464131c99dc5de3879df80b5130df5409f0d75526357ceecb0be3bc1709ffd3df917e38680bc53017f934179ba3467674d8231f6513c64f4f06507a2e3d10a4f2e145d759a23897dcede141e5b13b235b274074eb976f84edda05d507b23f248dfc3ee139f4309ba099fcb250d7c4d0eb61ba359fec9ba74186c5956f118c90417931aefd5adbc179f58282a1885679f21d2ca69a30dadccd896b2e84b4497c347a17a9e3bfb9bd8804c3b3c7b689e1ca00d3d32e1efa17edd4c9c8a9c8f1ff06d991142c193489e1de0e4bce1e989491a0e1eb2447fdf301b5f72a31601a119315af7bb534a088707920f8ec8a951f22929f90e601e231b7e5b46e930d19298afc429fbc0a68a6227757b14fe547caeb56826e008786e5cb4d01feb8ffa890612127c17474a50671890c5ea51460973b3944b66295b917f0bbd0c188e37e6d85d3a2aaa1f8e0045a2d954fd6d22a36ea5f6283652feb40a694e5e46d1953de2e17a090d60fc16dfae7b0d0ab5bccb33ff90d13860be15cd4f1e4c12233a009537920f4b4738ef1e5d40c67e9aa6b07f921ed1100a1e6138c779062ffce429167c4f204fef3b6912f3b35eb44c9efbe164ce5c939027d8e9bf77ae311a6df1fdedb4b5fde5aff35dc94bf023048507371ecc567a1a7ffd9aec53e2301e2c8f9660890c61693fa638cb62d94fb436709c7e619248a8ddd71104d4b45f15c1878a847aeca848f7826e319856c09c4418b9ca0893b983734daac815a97985e4529cbc455855122f8754ced61b89d43df961bd6ffb1c6a7a74ca4a88bf7c2bbe9ff412b8f2a41294503425a3c39a64627a41d70499ae7cdee4fbc33f042e7cf4fa04d7f60452d6ed80076dac04c7fc2c8c9d79d7f7ac8f125b3b7b12dc36b6a50f9316ef24843594ff5d0f42e6bea4fd893d7f59d5d219f119cd682438a917c28166ceb2e96cb5d7e096889543fa145ca760827f9734171ca2c46f49f195e38784bdc6890d953b6edc4d04c4cc635b34847563edb6371e1cf168b47a506b324e66783890f5e21780a94f3d0a9d3021bd426a6e8c5c748661cb11ab4e4101db18f077bb973207634a674c7940863cb87481884a173aab7d5929b5a77127299868c4dc275669a1827a16788a0adaa52e85f52a349ebf4bd8f864d052e1b6978605a6d368dac7cdbdfb13f90ea6d2039e375928d8b9fdda278d896d847faa28a9a1723b16af26110922c76bad4154ce7807e5a8f7720b7b28ff4e097bcbc70bb8f7bf25a565d8a81b81f7569ab3e3d868abb474845bc2e6850ae4c3caa887524cb34950f8434baad75e7ce00808f1381d93d6f6f6d8d85c86b55678e5bb819dd1283485f4e1dab73819d8882e5149fec4e34357f881bdbd0345a6868e520c6c51bd9b355765cb129248cec784e7658e33f8929e0d4 +expected_shared_secret = 2bb1532ce907d285b2d2860eb9bb5070a41ae73585743b26b948cccd1731ce66 + +comment = Rho leads to matrix containing zeroes +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 0d849d09133648875d99c8a2d199343e2069be06914b183e36f76206920fbb9294e3f17787c4595ab553ffe18287896cf6452e149cad67b901767a6e37740624d12b4657072571b9ce524780e2374d1b381e211159eaa9e8f5ab21315e3ae48041f50eb75430018199290325406bb65eca0088fc5e0b72ae2522a1e65962afea8cdc2c1ecd1a8efdf38d12ca5d4bdb8ba4d50d5de96f25034707aca01a296e63033a58200f32079cb8cab973026934180857d054dd75371700ad89102434f2438a823048900ff4fbaca832065ad99fecd12a742c286c067a93ca6de6e85304572a4bc2729ee2b421a41316c0bd766087eb2a88d50cb182559da4492a0324afcfc519e0c1c83336913881cdc9504ead243878caa6783557eb26599fc56fa26c6209f31222b7bda6db9b50341f5741b6f029a00440bb1af6b4e07a46ba9626d2a3475fac7bfb2047a9b3139c225c36bccb085a3b60c51a6227230df260d8f47ae6598ae065395e5abb6d5478ee97a9eb1a369ad367b075642997513159a1bd426c19542c86da7de7d626c7828dff7c9a6b53006ce03cd54c4f709c231f70829593358ab2515bba53da61c71c9b5b1df2029fe3404a6a1b7bab3be1299577c86997e48d38a17242e75847a23a8ad5a7511bc87a0261a8ab0e07889a53323ccec92e497c930dd57e43f39fd495b5cc2268cadc2918cb8ca24aa28c110b84c5b2b075c2effb3d44b6351cec34503c94e8aa016ac837f504aff5f68def8c8e0324754736950f28bc4d38bb6115584fb681b1b05f8f8ca69f924d25ca3f7715c72fcc1706f83f8538ac14b79581e103cf385dd8962d012309ce7774c687ace4d8372d1ca7acb1cf8f27545c07b6204140737316cf8971b3448127434156c9a4d35352dec27dfa82bd5e72522517bed633a3686ccb64759396db9ba279a5e967c5284814058a2ad44b8b1e9a7786ec1cd7f63a7ef72bc1f5c35ceba1a0fb934a2a547c86a6e00a51e9f89ff8eb68e3a48e7ba03418072cf0fbcde0bb15a6ec0ae648c012203bd6d83e3dc917b7914ca31505e5aa62875aa96c4b4c5cbc5b368b18f68264cab71332a38680826895d339ca656d358a0d40db12ec43733e60a287ba3998e7aab76972ffdb3139b30abc0ab3a089a6223a04c92a9880b89daa915130fb21ef6127fbe74721677d129793fd035d6fa2a1f1719a710a5030abbb917bc659b57f166304a0474daed828e8145423a87abfb36822d8211d9508a6d53994eaa9053c1a69d03dfda68593b1b9ad2b3cc4591067658f8d62347e022205823942c0981ce6846bf02fa16a8b20f39e1a53caa21a8f8ab4667b00c040228b262724d7a95e1718af48ab870675a4ae537d364378560b4dfba04146381f4977647a333df3e718ced96d66051c3f5c2fadc67f29596c3687948f455c3b7b13e2789b518866968788758c2a172b0de0fb370722571be5259c76b06c101250a49b542375a97907d393328afba0dc21948d96861b5cc8059b5feaab36aed39a1180a2bb11ad797752edb36a5cc98ca13c4e90e48f91404212e9ccd4a76569d661735bc9709b0aaf7b068a09b598c96557ec2695755c53a7a70509d0294a55a1707e040b2a8564a623c5ab9094000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 37fa90752936a8099c78fb7599926bdca1d3ee985af00c51add7e3ff7b282d26b1690f34cd3a8997ead23c2ccdceb07ec9df81ed6a8967b848c406340dfbfb9bfb223b6dc849ca5b1969f7aa519a011e33cf10e641fec3c0411d22508a18bfb316946ff41be61a16a75bff04d87c44f33bb3ff9faba915ef3e94ea4bdf1a6a296bfdaeb3dc50aea22c4ddf77b1b53b753f3c228876c6aaeeafbd5c59d748b5e596535995e075d5e47370e5b0b570408b1f8ca0bc0c6d60099c6a465c5e6600deeca2dffe0eec616d97d9eb534671251956505e1c546975c8f125ef2a50192d5106be103fa8b475a407a1a0452310e8b1d78c1147640e3873ecc21811678c276185f24e5c6742423a8778f5a2d74a3fb7ce6862c5481a079f7574864e23886658b2108891480a481b64fa372d5d628948c202a4232bc0f8bf80ce2eb4f90fa47b6ff1dd55a6c02a41f6a7c68ee7f83a2fa094789ea8bdfc70126de68a61b5f8ff5b92601f97ebf53b3e196fbd595dad44490722147737f54d9e69835a98d42ec10cf1524dff2a267156028a60bef51cda83abb1f5df8a5672aa336c02d6591aeee7a4313b4e6dc2e06404158a0714bef56df074cd290fa8a16daa8a1fc8f49ec7067be5bb5856f23afc6b2ff72a2a64c967c374a7917c3552ad54124633285b5f0cedb49795a20116b692b8ed2b49b0d421eef3c51cb99f7aba701b0387059f34f71b12d8517e7495eb0433b69340bce1c755449f1d08789ef7cf9d0bd528c262178af413d4f40cef52392b87d805a4d88677b1b8275640b066e46fdf1ff25264fb5f4eba7e9e1fc2965a27108bc32dfc4ce565b98577f0d1bfe37471d11c3afeece6a411b33ccee3692f32c22f077401135713e33f5f868ac1852120c170336581521834e762070b403f49e08e52ed0458866fa7df50d8d3b5fa8e33e931313aaeca6bafee1cbfb2743762314ce70fd9fca8fc34b402ee5a2ca330f60725d5b81a6d35e1c41f6d8c88939859e3f48c654dd8b9cbb4e9e0afb8aa3344f6abf18b6f5d011d8905e12f4be7e7d4081573649d157d4cce8b7b2c5e13875e0d2c7dc4bff5e9d436ae112338390acd59c7b7e5a086cd3b00817a1a377681a73531d4f1efc7ebaaf6d528e984d9609c81714efb89b3f0bab8505bcbcdc5535dcea227d3507d38cf72133c252f5b425cb800ab6198ef3b33391bd5043ec17293fa73eb8f3f972e64c5dddc851f50f5c48175117e533c87903f2d215a27c01f6050795109d200f5e39793554b35b2a339695bfc55d1d32a06336749c09f0ece1e197dadb485e2d544823e013cb84a11cf44ac7fb4f74dee147e4fb805059fe67fb1eb7daea7be1c5e7a050236ea8079a6cd1578715d8510a53c03a94ffde8a21507086d007145080e07aad2e7398cd98305536e6f3a0a67f83b16698232591337d0cb465bb13c3570df161e97f6e1deb3b6548aa7ff4a30d145f64f2571bd7f748f3044afc5a8d3e2f01113430ce83dd59b0a627ca759551a635a68838246af6c304ba843 +expected_shared_secret = 359de9eb5f1a17bf7215b7c1ab7cc320d7801f826f917755a79f413876973ef6 + +comment = Rho leads to matrix containing zeroes +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 40da241478b798a39e11830b402803ee9c4decdca918a7276f2168cce60092c29bba4cb8f532bb209367748599501572dceb9560ca00bc841e442a41e15b590cd63fa7921b344018f1a223e9e44ec933877c330d2b72531729ac91746e26c61381c80d98003265c306040c85fb95be547a46e3c01671401a42237da688795dc8c9acc86208c36911295ad22b05a2717d810076b63b632eb254491a414128377de53f941cc7ea1018bd83cf7e6a76d85211af63cf2ec856e636a9210b04a24abab1355478d132805802725345c43a981c2cc3fb0318db62531a045d2ef57680b547bfdb9d5d356464592f47c2360cd249e73a0f59fb470f4491a9e55d6fa9a982b97ee235adbbd8039beb9f07ac35ee5cc6243897f5c81bd9db5591c7225e90587279b35c5a1c075ca5b7106510559eec9ba2d2e7143c01afee598283403a6d7597a38b01bf1c02582035ba743e1aa20c49983779ca8279bbb53d5115534916184c5edc70ce4372bb25c48a2355c22a5b15e7563554e9a0e6f5afdb3aa3a1cc5b32b67ffc13756d65309dc95d561c91d45a1fe57a83f9c4ae8716bcd8708efceb851e4c3cb3acb4ebc7993d1056a485bacdb50694a81d12dc098d39a1f407468e215f6e055498d215f6f4bb8471121eacb2a324635a07864199a0199b0b6276a8a4e5b9ff0ab9ad13474ea6b2ca46b2c41027644a416771cafa07a1ac28519bbc0888f3878262c871b138aa109966040447484b3a999b7b4a75ad185475ac46ed92a373070e03a90f8e1ba97a91b5ace881377a51c24bb1fa85451cc94c72517f3d72024e7b421666cd3814066ccc5d70595efa756bc3760688123e9c3aceeb270a30a23261ab23e30c7f0785a360e8a0bbf5401450114f80580b03ae0b503419a25861331d58c11ec1c21d47ca9dcab60a56a5baee20417172a4535bb6de18b151bcb4159aab3fe69a31d5adf64c530726677db07dceda5d94a7427c189344027fe819c50f10ae70e550e154bc7e5a698c324096e9cd1e78053c6a05c7c11e9b2b532d19a87dc08dde0c73f0d3357f732c441462c8476e5dc5881d55465893438e60350175178213c0b1d8b503782d786b63c1e66cd3837bbc4c891a364b42130c1864c675097f65b6acab701de01124ded8aef4f70479eb996c5558cff287ce1826ec962bbf554abb282442a1bbcdc210ca389c50105eb253ae05c1477ff0523c85a294e084504616d7f75ce624925dc0c00b9c3f2f1363d2b05cbcf165f365390376b9d1817cd24560604c1512720b09d25a82f7179b74399fe46db356253a8320b393b068f064db6a353ada951411390171b47dc29bc4f05a2bf99aad4087ad54be6602bc7db23ae34b27d594b83e798f22fca1fdb56333374f892487e7289cfb01be4b8b03f0d9c2a589ab101494517264b6ba494cb0490a1871d301483a4c647e5c88be907c7c92abd813865606728bb95aa9058bba6cb3953b012cbc2af7a4770eacb6f2a7b9e8e94833e0592717be06517e9d33389b993a53833f9ca20699cc3dff64995ef914c05bbfe154951b7221fbc779740b86cf59ceb353233288911b1242c579c508149ed71052aba9bb79903e23c75258a445611c9deb185efb25524bd6000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 06f9463d5e9d8718bd3f56e92a41b4147298b758e670e938ccf1b048a6facc0709e58ded8fe9a88a11ff81007e066c6038388b7fe0e5496c02edd8c28509f584b9d58604c7a01f3196f99d3bb5fe1e9a6d2ebb47b2d2e0da69071b0f4af22dcc830745229081c266780c1c5dec5af5b74b9a2355274ee0d0b0243ab75a5f59f09dfcc2bf305f5df0ba6fb24c01c9bfbc38749681dcd401ef1f38d2bfc29ae990835c48a80f56b0869e84f7524f7d469ad2c63aee4137130575cacc87dc8fada26c4b2195644b54db3ebfee1e4fc3f13ab744dabfa044ed7cd099ac836b8faa41e510d3995c129429e2f4c8b188b612ef32eed540915294be069d64c662bd301381a430123a6ac2dfcf2c6ea4eac8dc5b066d7cca6af8f399add96abb2154b9167f57fba21a145288ee90a4e47595738d7c32be27cb1b0e5e16cebbfcf5323bd0b719a641ca98bec4b148128e3fa11963070eecc2329efbe9bdfed16df4fed34cfd03e65a59e20bd3c7b8f012e88b8262473c7a36d00a381bf37c15ee6d709f9f4f0042080d4f67cb6f4777f92a2f0a4b07bff9e925a7d7ab581ce46f055f35c1963d283e4a210a59dad5dfc7a679cd828ad96382046816848b1789ffc84babaa60991082418286bd281947c7b664543af16b8ade454d3d8ae5b416f82cadcd7eefc5b135bd6ed577e8d85848419ea73c3e0ad7276b3ce8773e9881384b9d48ddb6eee9d9aba7dd2a3e0ac8972e301d9cdb0f25893c90e68f2d1ff8ff892c6b59bae088dfbdea3135e74501236e416a01c770bb3c77c3a634a29ee6d99a0f954171078c1eb44d76612d25d7e51fe3756df2c87482a709384825f52dce92884f8a3ea3ebbe219e0bb36327660b1b7c44583bdd924bb4ffd6baa933034e92a5feaa13b3bb8e8e4c0a54ce58f4a48ce0c8baa273e963d74538c55d2414891bcea9789764247e64897c25a8b154d2ef8d1356a77b8a5909c9a53d45d2e4d7362e96edbddf27bda011a439bfefcb09bd46bde933b5375bdcbabda95933f859c0c43cd60f21186439701b7ab4f19c8bcd63ab3adee01ff5c2c47867297297ff823c814bbba614e87898bd0bad020c6f51440037a687bbb96c558ddc0f2a250b836bbb36d88009a2575728eabbd15e3dd14b47c00586f371e8e7d964d2cb7c7acf1bdb0077ef2f79ad0c20e6134b54a8add35540cecb4a1db7bd8bec65467745c2dd4763d7c67d9a53826c42f67176354d472bca647540b404c0e84ab05e4d474dac551f0624ab099d24fefa1066f495e0bda8439291e4c18718ba9ee97c16c385309c0d9505e51ab5651470148223603cba76d767ac5131a13f097a537eeba099a18144692b718cfba31b748a72b69f03d8226bf5f8ed7b5ca93b40f7e64e5a56e6edf2829b61e96283518594414603e7acb8e5cbeee0a8e9026196afd72dd3448ede9819a89a580992060b1852af4e2d3451ff7518f18c75c4e4c453f2d7dba5cdd60f5f4686b5e2ef272ea958867501a3e29a9746bfb41f42d08ab860d862b6c0f4c0 +expected_shared_secret = 9cf796413560833a3c2e39edb3f4f4bbe551109a4c0b9a25c42777d7d89361c7 + +comment = Rho leads to matrix containing zeroes +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = 13c4781290679e16c822f2246004c38ee6ab27fcc694e665ec690515542eee6350d4a13740b417d1b91883537b2bba248a61108a818d80c5c67b1c3265c124f9e56be2a13129121e030aced4585189d58978cc3750815688763bdb44a0ee46c678999081d42ca342b414cc00539b6d19645ed18ace96a46c2453af3af9b73ad649febba71e40802e3871cb3661c2c7c1480b9e15625fb61c322f0141268583f4c9b19950018c70a55ed500625cb207e9219d2c9cea134c6f32a606393e94923e3fa5729ad2264fc8667d140d232a3b68a93caa9098fe242f99305a0fcb3413ec8b22472e66754edbec064e89245301bbf48a8994d36b4093401943a427cb5388132d3543944e656ae51c72118821102322a8f7246368b5d9e4756fd45d5886477e476e641b10d0f196cb6638f6c30ac2e6ce57230d4036cb23d14e8ba30d66e92656090199f1652003af17393b1fa912df25b6fba7bb3fbb5037915e46c8217cc88142e14622f028fadba21455b00ca96b2d039663f0aa6d48b0b5b3672203b76330ca4a14434b877cf83a818e71b97b77a4eb99858542b316c809f1630f9bba7e00a265ef2b6b2aaa45611726e1ea7d96a50f5cab524b138288f74b8575256fd7504740a256e1bf34318733f6b7a53aa30536bf0e5079e5b0395189262027cbd497c350b1ad89f4aaf88b219de48801c7bf97486824a7b7bf723f516293f2f786a6989a35c192eb8b009fd37f950cc6e08592a1350c680952e92887b5759249cc70bf477277cc18a9e95da3579bc4bc42761c505504372eac4cee71b4d82c787356983380666b3718b288948372c11fc855b3950e633a70762490ca13c11c6b824478a293f5161c782c4ffa5fd0a64b5522c23979b2434ab52b783a37098ba2da100da063dd3191c29c12bab3927ca721263cb518924483091070981a902518df41ac1280bfc7ba2f2703cfe2f8cde65427818215fe57b68669ca97c977af38845433295e770c4bd4cc308cb203d823c84639cc9496d31424ea778b0f215430437deae7b8c6906bd4fcb589d251b637030f9607e9bba487fa0fbeb9545eaa8353c738a9f02b78e19774b84ab8144f20e39c62a16032d924658262c75b91e5a471ffb95ca40b5c1d388be8b55e09f4980a274ef5a5cdf5137c1afc0325913bb1ac608a210ae92220f4a47d8ec6806dc6b5efc67ccd677d5be615bed15cd76625ee4300f1e8aa9330952d49aed6b14c8550204d2c3c61828cbf36322fca4faa3190a6635e2f0809f45b5064929c14e0762d62a3c8839663fb8b9a135b715440d81836bf40a6cae8333d4496e4703b4ad50482e8ba9f5163838271bfb66d1fb462d51418e2792cc7370f7806d0ce7b7b4a66af2af770f5a253c46001bf82988a4c0c008b8bebe64bcbca680d3136e48bac4f030cb495095af7cc418b3acaf95bd6b636a4f92dec211c4b2b4e8bb90969681c61ac380c16ce7dd0aa3236957415b29144737c5b9124575872950a23c5315bd3b0ccf2a608e6a0d3659cd1053938cc1e68c131095cca20c4b2b358c65192b3d812cf73e820f89ab1c5b4c4c2270e7b465e2253c179d312bdf77f22252d3332cf685abeac1c4026f95e9b9b79c5a3842a49b4ac59000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = b812896d14f191fba331fe20ae245f968a421c46ae8e3360f380a9f0a00d50da4247b232f5181ea946b494e9d99f82e7fff27d8ccbeb6fa8dd5e12f12d2afb02004f2bf046f23115aa3f7e9e5bab06803c4df1d6a0bd935c882721d09a3b5c41050afe0ae3706fc83f87c49fcc22ca331fedf7787ab7ab0ac9f04fe405f21d3384b1f377332feebd65e11d7989f56cf7430ae8441072a4a8e9c8be24a4a1fcf380dbc0a8543d2159de861281493516d3fe7f0819da15d259aa2159c37d325c884217a03c83d8f4d5c1b9f2af4e734aca05ed1d3951d3bd5c021a4e81069678a210ee5f5c9404b52ffa495ebe6b05cd02cd84ab3f3795793e03d26e83a647921c2c970170c0ecdaca8d2e5c469b1a3309e46dcc9122623b6f41771131db303eadbd7b7df5c86bbd6ab0060df29c95a0c014da4939271a98c12ed92a91d8b3a37e2236ba269e7df73f7df2fe447a20bfc56e6b9249485cd71a9fc83af54946537872649949b49f3d98425453fce02defb6d09790322afe334c53ca802510a87f543264e5bbce4665564d23695a08161e28db4c90bb6bee38c00c5d3cc2e403e225afe39ed45ca3c23a35e64769486e4e38b122e3d1bd2bc8d1a38f689e5ccf26db07c8b7c14b19431686ef783382d02080b9221d2a15b41db02a63db7b5396e4b516d241ea0ba533c6f1c90b67d0e6bb2bee066015dd7c42f0226809fbd81a8a56630b93aecd63bec94c168142bc64f0086e02ddeafe7615192575e74e174cf7e2c4df95b55ae810d5cd5cc706605800a0417bbfbe3097890621721939e01e51f46dff10e0777bb93e0b87e8fb88c5100b47ea0c1f356fe669ab2ede1f6eab8a52b45815f9698e86baf38c35ee99f5d3613be4fde9febaa6c33f3a493a37eae52530b8ff0282671a01a13ab74b547c4bd7ae87666c20f857bc4fdd2eeb15a09722cf158083d7a31cc13dbc53e0fd2b2957f5032761e777474f17188835bd79090087ffc0ebc01af02e4d0e0be1d532eefee9ff92afff8cca34286cd6e9c03b2c41b2080484c725afc5aa3c76d4c807e8c5beadf261061c4df268b4d4e6e24ea68f2fa085153d37be084e9d69d2bc48c819f898ab482c0b80659ff473e8b186cd5304c62b4b3f3b714c628478b8a29cfc5be37773cdcc4558986d29578b5dd087ce0d989a70616d380c3c5f68410b3a7a0fd247b7a3d9c9dec0e8f13fb1fa1e6cc579e31a202afb994d6fb4e40e6377dd2ba3247e5150db44d4515d31296f00bd2ff2838d5070821396ffcfb424bdba4ba3e9bcd2e02fe85f5feaeb0106fd8270a47aca634101102c08dae778d40d070d1ff0542414d71a7dcacb25536b4462014e5093710ead409aa1ba2c21c1716cfc4f1091aa39b41c28ac9cd3293c00c853a267cab452473fac0c84bbfafb4e2754a1c1ba244fe1ba8fa356e78f89a94501e068126acf20ba176586adfc0c03535eb6fdb1ddd41c6272d0e8c49f039dfccd737c284351ce14b2f7e0d01639d502d519fa9cfab9e41632b79353ff861303508f +expected_shared_secret = ce303d3ea30cdad19af0a9f428943317278b22f4c7c229aaca25d0709b23e6e5 + +comment = Rho leads to matrix containing zeroes +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = b08c45bbdb5d4053b675fc7ffba8cab1f105c8095a0a209c4f16447198cda9d73c62bb98dbb3c86e8761978bb77a5c7a28f03f10d8558cab3c71d498429786280383f944b75c7139e533bcf7019fbf953dcc00c884446e8bc3ccf75b3dee9190526662b33527600296aab664ef58c5890111c4d1c04262ac22985181c80f3906cf11f38af489a75cf5596757a8ec56cb3d3a7c2594441113c427f7b43a019ce1bb1756a9223b8b15c3cb649e93497fb34ed17b7c4d185ea1e9a5a6dba569f1414aec8bacd1adb784c714a7b2b89989bab281eff81ed093373d5c6d3f36ac3952aec99ccacdb0634928668264bc70303fad4a746592778568570ff75585422bf3cb6a6960946432928a0b39e5bb017840c7c4d99b8b25a0c76349766b0d39f7076a839abf883252743731b53c3f650a32b0297e806addd02999d61086362322c840d8dbcd820ca008e5ac150b7932f081491415c1c3300e0976e7f9c14fc045be34983ca26b71690d216989a01b03b6930fff0964fdd98b2ac6bbc408d0731a501ec87a93e19096fa3161870bf7964ab5d6a5ba764ed8206815d83045b24db9a9483bb776dbc3ad85435d7cd449248c4058e3568bda4e41061ee5f0bfb0e29867491bf796140e8a2194572c23f75922c4ab0014c9ee5a98663ca78741a4b15335d14a3fc92a24b05b5233a43914b274ad531e94656309249f79fc93c13652933529e72690e1b8b7c6a21c756614307229135977fab1727a497617c695b9299d81358354c9962d231183d8512adc5f10e56a053610cb042cc4fc2e485099b973b320c090a4459f8dc279beb9568f840932c77d28ebafa40ca22bc60adc785449800c8fb71e80ba9a67c4383049b36fc89f0248a688298453e480ec525dd45803dac94ac380c468ac2c85015560965b7c7838e59a8f90cab718246dd4a0578fd41438e09716d3530a3272618b191c521887ca38aa8c994c93820f78673f5cc95ca93e3eb976946b8785ec3f12641d41f60db3085931aa365970190b93c37625332fe92e4532519d8825c46200e8b576592ca557794e370144d378a62e5c54cf6820f1671934db0b6c47ca8d302bf18a8b82152926853df7d255da51cc7a19657ed77377fa4eb8b2a929b46ff18910d1832b71842cffc3849a66107702ac7a86630769889fd90d8ea22788805876321ca2158ec7bc878c568822c0bfa03c10c9f5b5a8076357c6b934b75617a20606712b0e8cce40f4ced0d17defa628bab4751e56b3ad040be6e3264e6011fde7c4cebabee0701c6023c218d07b47ba4ec811b286ec3031f5254302be6b776666897b3062649252c5f7c1bb0dfab6b4f13155c91f318963109421a4a33306eb0b66da38fdbb541bbb3e2037c1a0d4493e0878aba23e7138bee255b3423009ecc8920a3a4b86932167b1affab27a8821598851bee698665a2130816b66b7e81842819ea1560a0c5292be2cc7d5428aaf3b7ef5002d5145aee9a82c9d44bdd0842adf54b38d9213e904052905adf3255828147fb64960c9167b17126d61b05007c759c938cd2086695e0636b25b69312a70235b6e201c23e2f9a9ad696716f53333d004fc663d5c0b0776f875ad988aa6c6230218cf6806353409000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 87099f26e8493f157e405f8cbaf679f5fb0aff16ff9e2c2fa8c263c6819287da7484cf93e0a6cca4d0a94d0f710081c0bfab292981dec83558b651abca873980d077e9febdfa82398896e88560e805948d84ea38cc77554e9421dba3a85ba24f3328ffeb4de0bfd1da900412a71903908e3b8cacf00ea86f21e4eb124167b3ec769a8a22498ec6cf26cd4b1470e95c37b3716462929ddd9e247d3f23b98b3efed529066532b8f6042ee8eb6ad00233329e0b634e300ec2932fd6631b1bf14d7e992f54b985b51cf1b05f5ce7d9f7458bb3b530fa3feb7ca1a72dbb8c4b01c0f03d8b45e550514fa4fba32705c95316960bf50d64e3f07c48bcdc31265f0fadb5f348799fe0364c93765e2bb4688704f3027e69689861dbbd65bba05f158fd329c5474386f9ad7afb65b297004664ebf3cb7ac1e8a34e33ba15ac0c92e7abedbfa96fe4c68ff6d7a4d1dadcf56824285883d74370e2840cefb887b7b934fec461c50781dfcae2bdcc9983e0b34c3be81a0dca5ff0ac834f5bf71b4e6135c79c27a525bda87c2c1c05e5e2addbca7c43e49ad11ea240cb09bd77d22e7e9d0ccc4d638feff6fe9bc04300202313197a9a53b99e67e96aa72ebe3200758c1f17b05c0b793dba17278f3e79563a532161190eb3a0724524b210f26038ccf08d55c0bf29b95917c0bf97df6872438b25d6d90091ada34b46ff2df784370c8bd3a523687902dd9a1d70f9aa9b1a06dcf4a1fdb740ac3a0c25c3840bba2e5c6cd1dbef9aca23d5f29ffc00cec2fd9dbcc187cd2d3c690f436e6265f8cc6857b3ddc1cc1415877d83d80337fc4c4e38808b9e05b14173497330077fe4c38699523491d4a3248e5dc4c401a3a29054c924c744f7514b7a84e91ca6cd2cdd5cb51c4ab4f2dd4aa0027b294b299896b558754264ab10b0c0306465ddd4e88f2e42b580801746452467558d3238d21a74ddefcbdcff5d79886b101c57c0d4d1bd4af284aef20f558928ae0768a07f397c5f9f7f334a446755a22549cd7fb1efb14bab48513e52c454e57c381518ff6d3d02278abc01bd0d54d53e77d361bef85c33efbbfb295bbe3aad332d5131e8cb5cd90a960bf2d429524b45abd686ef95882ffe6751da4f750a367fcdf0e807fc204834d6957ba8fbcc0e9e3d4922c45085aad54b08934e0d909b334d3952cd479931c75c5f4aa1ec286099bedbe5ec17123384e83dab7230ccf5fca4f085ff348197d837b752c2bab7f0fed29e6347624c51059a48dce7f4eebe03b5bf9b15b13ec85e8acdef861fbf93f17e377e950dbe9d6cc96ae83e94a3c5848dbc2ccf6090882f048a174bc42107cf9bb0df711551e2d550e74d2d416453be7fbdae5a24ceddc7dbec4329b4a67d187461ebcbd9845c5ba04967ee59da4bf822460053383935cf1bb1766a7ea5568f16ccf8400d9a73fc86a7570742d76d4f52d20ec80b8ce2a937d53fe88f60bd3deefe27642fc7cd7d79cbc59fbadef2ed189edb3239a948aae68bb2bccbd42c872dabd7a261625af4fd0b92c1 +expected_shared_secret = 53865f61850687872fbe708ccf896f7f24ea01283510faf76481abdb0cc17e89 + +comment = Rho leads to matrix containing zeroes +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 0674c3adf498654b7d8078c405881705953d58fb08954a73cbeb43d564894eb48e104763d35563358693f2f2442ba8a01c38af0d94be822a1bfb7560e75abff623401fa043d4f10f8cf688b20c56cd18867712688c992f18617331631527cb4c7b0a526aa488b5122553e332280ca64deb0c0ad36db2267b633b3f8bb8a83551000e1ac17f7b426813caed005892a7077c4bc02f703befabc0f6b324b1422ec290ca42f630bd441d1f119f1c633b2031cc759322a4d762265c5e642462c0b38ae5339747a62062e07aacf8aaae3725424c4f30f38e1c727f40e53788c68bbfbcccd8db7364388a46a366b53bae89f09d64c7c1955357e256586dd5cf508967cfc97b0b481267566b7eaa00dff67158f81cfd8a406dd8c0095c2c6e4c9e03a466ec79232885145ab0a321149879a25c77378dd1e231be71519122b4f1394e1998081f271840a245e1774012d508bcc0830c5901cfb7cbc178875fab73b4aca397d13da45b9e93342d4f5aa813048d46e0b56c8a9ad7194fcb6046da9b9d16d56da6399315c924f18c527437c9fb03ac3774ccb272614b0cc55968ad346187a5f1716a944fb3946783a6511a6997cd482ead064356f843bd6b6379f6c662c9c655705c6265c8702729c3bbc022a8828312bbc7c7b90c373448a59cb67ca2da3771882130043488eedb9c91b39917a1629918580381972c34a0e7abaf372527e1902088e1354c5353c900a0a16536435124a9e51369bb46d226170a064e91e85dd6d987956820b1446a6181535d3ac8a994341ca43b0cf06a83825a85a5ad192582554864561c5bb2915287a502c39b8b54abafce465abbe7092a83384fd35d91d5604c7a4c14395cd57713baac0d7f906ac9274a8bbb34074b3f96fa8fa23831ece3975f3011a815bc7a4c1a96849d386511e61a9ac187024eb50135aaaa0ae2347a804e55e4b3d3e3c678da9e5997419c836948370d1af0a1c1c15d70f4711e825244b1521345304af589877b64afc28ac625a237a3226e1873101345e9ebc060a255fe0862de4800097a89fbe07aac5c1cb983049c369c8f0924c8320df70ac9da023cba2b1e40757a3323833d12229ce607a63275f305c3b8bb830dcc9f63bb479969cc0cdc30afc75a8308cff8e59d5b2a20d46b200dbb7d80e011bb726e33c968e3ba8809771269a096e85260828c1fb0a719fc638442b2935ae4cf82a2c27bf471e48264ccf912d4f09910ac12c19077a8f52bf3b2c8fb4ac7ace2ace1250347c3beb2d89299673a6328c8483805be327079f8552af16117d12550042b7eb635cb0a8c0d370ab508a7789235fb81bd60b882c8909140eb487c5acb092c024a9c6c8556b832c36bd0dba31565b70c35c2ea4cbf7a1b42d2d7184d37b3bb180b9e1078a793b7fcb2bbc97bcd8bd7cb3c0758f398a482565d185abfa4310c3a84b77b9280e7a6222098aa627497fd13abc2130ae6d34ea6c626fec532f1eb4ca97266eb95a728434ea1987e7e666ad09c0f08c6c581dc733f962fd04780a7565355083b12a56a7c4ca774b3cbf4cb762949631d8bbccf7b48e2ea459343a6beb3a2c38b64990a01971579014b41a3a90c06eb3bf83c502388a5bfbb0c9be9beee4f3c26cc000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = f557aae24c7a8527f8a1ee03310c78172826128ca814882e33e4af6612c938d174209b287ae8a53adeb6fa0aa25fe6d19f027367239cfb89bf0dde0f99497ef7d7477bd332264ba237ec0e1035440029fbb5064ddcf9bfbd136e92f1b35a0a2cba8405ba42b8ce36cd2a686bde2fe338a013c230b1f1a99113c01babef6881f471081c9b9fe25f28c0fbf828c243284e6be4c0feb138729ac4a6d6b2869493abdb39a08563b2bbabcdabc3b349f74708b714f7e11243d90a69f68585b21de1cf742ed7637fdb5248cb5fee5a3245136e85dd5042163f2417e58a634224db95d004a4e9665ce10dd120b80df855c5ca5e464875752a70857511a705be5f3edda976ce536a5a83d5173c194d0a9ecc24f83a6b6c12bf06521f9494dc56d3a85df270518bf930474d9fbc3c77b61a1799db7146d5865d3d71e84a64e52deda9e16cb73ca1babc487a5b653664278f6256954397300b150b9159e5ef19c71e45fdc1919fb99508606e180305f7bf11f9c772e49e7a0890cb5b0264749035c3725e3f6dc99710889f8501b71872ed3674557e5fbbed85f819fdd9f6d83f1c40a04afeb67452dc3a44c77a90bbe770ec918557923e61fa704b3c08012873a0c672e511241612de52cfcb8c8e129f3b81f3ee76d99bb42398eaad6a1028b0c618b6c0c2afc7713ccc226d4c853227cc6864dec677e39dea238d79066f427c2cf7e9597b8b5a0c59536ea78485511b3c804be288c57d894322dcc2ebaf11d2da207c71381dc654a7458cd22c34703e0b720163ced269283a7a3a50f5e31868ed996227f49d8f0e02e6eca130356cb125f948eeaa0aaa8c324401f5931298fb20fb0ca6cba46bb98b02575e7abd822838467ccbf1d80868ee866bdbed1f7d84eb1604abe5f88a39041a18d301967260f8589cadb4e35c39cd50fbbd6a3922234732f25231ddc0df32fd80289fa8ceaebb0d19ee014200b3bc9f896e1e2585a0f6ece96a9983cdebd5738fa4b10a90536d820ba5f91b3fccc8e77a8bd01a56721608d402e4171cd91a56ffdf9236fb75e7041903a327bb2f8c487fdac2e369a4895b5affd68bb2967c2bf4f46144e6bfa796731ffa338eb9acc96374f2db1429b5568e79cf9cc077e74b3e048894c3b0686f4f071203c2ac7dd94e029ad9b9d8ff680d8bd5de38491c43ae7917c18b4cc50cb9793dc7da034cae15b8740b519d8c673d276488b8bc9c3c6fd127a7e9bced8385f39538ae500d76283779a4de8c360a976bb237822abb96dbde0408f9f9ecaa639af81c941460ea2c19541ede082e0635fba083de29c5d460079d6ba038e961745a0837edf37f7b0548c65fc6f8eae8706e54056b6b2819b79231139da08c6f66a4455be50ad702f1469770e30ba9b108b84d77d30e0fd4a220a4f4bdb7d07878ec837553f4210385c760fb7f180c943a965df8b3118e3423e28f6172a2c9f9c268342e1a0cc63e158c51abfdd23efc929b8dc17274063ac8c3e4a9f1b3ac373f7f279257fdbdf044e14861f4ceb75bac6710 +expected_shared_secret = bf9eb969821d6b129da2e353e7ee8619859fa2e1480599b3546f305e56c7be7e + +comment = Rho leads to matrix containing zeroes +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = 80002535317ab0223bcad8c9d0c6876dd03beb06403e50606a33937515359663546cc0bdb16a4a9d6ccfa0315882739380c591e4b3302d807f76256f441b99acca228f17c904f88143840648971cf03735ae9ab070b6c4057c6865c88964748d8e1c5fe919037f3853abc58a3950cd307c39f8db6b9c6794d6d921da4b5ea23391d916b7f2bc8b50061eed220e901495c9744da194790cabb66a3b34eb020af87532a7967a5ab190f1898cd402c093e4c0a7967460d5b0ca0bad973ca86e533435536366370388178d28349aab06090ee40291263c16d26551a03fac734b0f17c2ecc693bae40475f7cf5edc778060186e5811a3dbac9d34b9f478c2b7e1c7654938cf8031e433ce38c47dd5e9aedabb6eac802123a82c6aeabaabd76a254c451460639fa646d87576ba154fe0b024eb114af1d2b17e245c442ac9a82bc948db520ce2c887d57f0621270b819aeea5422129372142ac87c1762e6b891af95a47912029d09118f97c5a67628dd2997c669523c542393b97f74c4974395a857bb9b47b39d22b00d5e946365a2dda868934e514b35954ead55a76d812cf619113719b322b72d6d94187ca4d3a26847437b2195a1a034b530ec0b8c7e1401be0308237094abc79fc9c92d79675f590347d7b706361556f2c00277289ba296aad73c9f3f654d1893062735869255c68357a97558f0af74a44879ccdf7122ba5bfc5d21d805430432abee64c7f271a930db3aaf5f78d8889b59e654c18ecc915db8df2eb7930426bf64b62088406c4b5948b984d29f149ee897c1bb8664a8617183a3c477994aee870d1089cc77079369200eb944a79f5aa8c5315da8a7571a6ced0850b2a71a9ba6221cf14be48935e12c8a4cb7630b1661c3504885a065ab5e3c1f78327c779122d772cf64c4b3a63aeb7b7b2c11cbb8ba98e5c340b8634bf743731f0942b8c333261a8b9e5d60c91a707d3e4035e30bef3bb6089e5017d154279b89303a2a10709bc8a44ae248827c477c7568013db462b34e8a8d7731340f7658486c3e83631e21938c4c560e00b521e76695d09844a0a35a6b758e711687debafc31532d2d6a41e512e3ca5bc88770fe49a794292c0437017082c5d11b8a6fb36401fc92aa5ca7cab8b550fab6a74119b5ffa8a14069f58f81231f2a646eab240fb56e0bab328c4637d3559c9b7351f4c7f68eac27618a874790f0ce75e7c32333bf534d0512fdc837d7fdcb49762cb3c8529b8538fa725476e0939394c9eedbb73ccaa0a8879b2c029b9dc350e911278720240ee262830c41440b89e18446f195c7fa50c8a94b02ceb5c93d2eb27f406b80e758da7f99eb320cb28b2aa6465b50c6c42b9a77390b521f3e2830f789a3882298c649722748edfa9c8ff2b7abbe61aeac3171cf16ec0997952323d11bc29fc1a76e022cf2a07300e3a87fbd47047c1504e8516c4e2358113b8ab8078d6466ca802ba3141287181777ac12618081892529a0d5879f4ccc979286ddd4c3112145dec7a711548214d62b92c238e82b4cf1cd6b78cd94d6490ccf69005d9ea13efb1cff0028f6c1543c501255495118d76137fa4c12331800c5250a71a4a8ec01a30bbbcda5a038c682f2b85b6885714f6ec2e27fd000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 7a47d5eee9259bcb9ff2d28b7ecb9b5cf70cc36298f0578b0b8fa211f51453fccfbefa32711bf6e83b796bb7927185afd4776069ced5de3731a1b4783db069092607bdceda88782b7c7bce5f77bce5bc70aa9edec73634c6d55b6c7e66a80a1628cc5a0ac5a83141bd060c5e790c6d1e2d604b948df39289825258a575d559e1c06090ca398332b5df350870abdbf17a5aff739c49c50bdc1f92df4555f4ac757f5e98e43b287873a6ee4f35970785b7e43213d5d49078504d0f2d376d590440eebce8e86cd12a5f1669ccf0be6e8eafa396ec1407be8a02198a287649865cd0b6c149403f6d4866bf117e2f9b5f3353ef662b64381acb92bff6208dea2c65f49868404a02b5286dfaff50472d24300497d8b673098a8ffa09a3633d91853491be3e925b18a6f81d757da0585c948afd41081c654853f3c7d6befd41ebafa1a2393bb1415e312d0930da60f010775d4f86076c19f2957da96a0ce4903b9ca5f7ef18d33c681a4252e58e2eac4a1d292ab9952b0339313cf5ede08f000b3bac1344fbd5a23ce63f810c993285816e42a2c13b35ee685863d691bc1dcf61ecc4b2ae54a2732873c065170609aa0654279cbf77f790056f337f45d9ef3be9b278565decd4f86574322da9d37e4e6afa7165cd2b5d1d96fd6a27570e1797ca8ec1b64db363ee5bda8d756ae024ae1061826d90ffb68440aef1aff662c801255906fb040cec10e4b34353193e3476612ca6467a19a2635ed3497cb565b8d765642a8cccbdfb2fabea1e2a64fdeff5ad9b8cebd9505872132286731bf566bb8caf5016ff4eeda1fc612593cf812d69b12dcdfe5ab34d03a8804feb9f79683f3ea44da7293ae812f68d6a21cb0b66bb610cedb2976531e6b174d8a1cb46dab41d87c3ccf4e23c5f0860f0cf118fa50cf8429d239d80d81311e090a2533f88c707a64ea25cbaadecf72eb202c647fc1bf3bb76cad5c05a305fa2e67b4ff8fefc82d9b1868aea7dd7aec33d60a4039c08f0f10aec4826d3e1b8e0b845082fbb95fbae30293a92d5ac73856a72ff52040b5f5844b61af07de922d65319b943cbfdbcaff62390f3b162e64956320aaea0e2abbbbfb9678e15ec9dde1509edb4643d997b25db8ffe372ac7845dbf2a0d703340cba5bdfd9225526f249561a16e21fb899a71293750b122fa22e23424aed5a72bbce45995050f6940a51e495931fcdbb289bcab11607eb21a18f35ba5fccf786f04d536c165d4d3f5055b661a31f43deb64575aff3c2b61556c20ed98939517179e86902083ffec6d42c6f744487cc4fda790e87a73829b8849990a4c3c0b5ab5c0ea8f0567729bab9f2ffb6f032403ecca6e4bacf608851dacc924ba6b8051bf48aeeec8c5ca87b56e3cf440521e72f569ec80e07a8683fe06f4a584e7faaeb2ce6c8031755648755c75475a2d83941d96b269dfe365cabdcbbf207e79e00075dc4259f96cc9fdb3429418072c93ab4f9322246b3db1f436e579d1f541306ce036a8effa25efe0fd0b2a208d340cfd70cb1506 +expected_shared_secret = 43e175ccf07fb358c9b4a6117c15c327b88d4d8b95a645fcf1ed096f0eaa17d2 + +comment = Rho leads to matrix containing zeroes +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = 6cebbc9157cd2d0228c6385f0d9aa0f99335c9cb777e96b597551a0a644a34d3a419b3ad5351876d93490598a90f31a3a2a227119b7cb397988c8971a0459b2c811ebc8a19a094457c118f6db50b7b1ba6de5aa85e316f71866d759cab439c71d90691f1d27da41779f2c3380c600196133f15938125583ac7650eedb0b069004073205b49943a4fc00ab5ec5e68ea5299b95b303b1cb08b687c0b533ef3a98a7b0c3b6419a6cb825874c4ca5688dc5cc5ba5c49448b479b84baba1344a29493fa3828e953b3ba64b087ac9f5b9a3f12cc6cf9942612606998207a852b35f42ab80f1ac8bada3f107b37cc6c1b8df40391b1afafe848a92853c9b32b9ecb758b88c8f76a9b5e866e8c359f3fa29019f439eb0c9b5d4b2a516877de0295fe7409dc79caa4da5f6a87a26f9265581cb6d141c3d0e597f385bc77f966ae1c01cf29cf0bc536ddb0a8d75c8c5db79e967c899b46bdedb9528f596de02c120fa2702f73b3756aac59a750ef97ae2a7213ee95797f2149af542b992405c9d79e085521d2e303c14146180904f41937cf4180edc666d70238030b4b6572af377693677a5762ea7775c34b9314c10489518525cdea77cfe8b24233dcb477e9cf48acce10911dc9517587b409742b06e3142ca7a54f36d6ba225bb933632ff06802779563fc43a231a11b42b91feba135d7229f1d29781eeb65d93537c58525c4e48b85083b3226937acb2c7bb3941f95664c254c18bb9f91f54f69263a1d590c64f51f0d8789cb60cc9682082bb399fd87279fe4039c9bc69202a309faa488e26a4e3a5d64ea4161b9a8bef9997346ba46da3414965c4ac84ebad1c2f067a3ec5a0866e4a5a26a7403bbbc447c3b13e9c282ea36307c83a91b25b8b565155146fb5a5146e01c21f4aaa3dc7082e93a2dd95e7364b6a97cad2b0bc27d0aa3f393195250118f9c635f41ce82cb1c8ac2158b3101e3f44132a271a545240938bb56d11520e2474678391d4abf7200b775b27dbe81970ccc517542222a67b693d151ecf5485c198838a2cea0060da6285c6f0321472710d62a78c42c9edf07518704157cc5669c3ac775635e09356304819d718abeb0603886c67d8c0c523691a22b987af137a18d20ba3af239de79cb85672d8ed6beb818c5b09baea6c456ae3a4a7481343aa890a94a15a6502399a0101da2448f55666aca18d0259d95838135097273ab117a60cecae8108dab28d6945cd0a30099645892737c3238974588bc9b4384615917e8ec0c10076b2249a42f1841252533376830f1c2bd85456f4e8577f7ec1bfc7a92165ca5a83b85ed4c0dd0652b0ccc9bf5fc6946f710b0bcc42c9529de51bd99166eb4030bd1c394cce0835dcc311cfb6e3c951643f5736045baf1c3a7f11603cc168b6a47ca7eb909c6d9806543380c603a09d435f7695e6b117b75538d92fb03fbd92d05c7461b113eb5dca813c43efd7835525a228005076b969e9446be37c707ae0025e54863fcd72462b6aed873850cbb92cdbb209246945df26c6412cc16214155e57bac92562c5c14e1da60f9e036172cbec09caee2d14242d16b1b1b9659a7705a59b23fd93e6eb23442825473c820df8342bc33177f39451149340964c3ccd2000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = e4cc5f39086d1886cc8362e6210515fec1d8474263af5d7eb7b5ac9c1bfc65109de928c818728fc17548bee754bf8df9f972fc2f5943291e24d0911a1963bc3e4999b6de2add2e5c15b3100a83be4647f3fadba3d61022970ce43a6d0cf5a84b387b5d05847185cc862eb6b71b5a8ef9747a12e399866b3839e73f3a73e38877a1faf8b88c3283f22f6fc2dce6fe43118ff68ca6cb9e88471dcad4ab28c657e30462f64a34a108bec7e3b6eb988c6bdbdf4a300d476c170879ecd62ceed6b530575bcae1f23da95ae486b3322470523429052a3059eb75b699a9941a028da267b970eb0a8d444296e421abeaac7106f0a45dfcb30a69d5336ea98d999e65bfa6a2cf43bd302512f086f8441d92c11937b2773b1cf33b82076a64b8327bf2f94f7ec3e83037dc543bcc8bfed37e3a2ef05e009745cf504f2e261fe194c256292d86d935c7c971dc4c32653fe88fa2dd822fc37b644a3d5dfbe5a710551adc671f954beb44da64c06b9f5a0fb78c1d1b3f94dd2c0a41829fdef6395da7493d18423b52bac69b26b2773d0c4242d5172722780843911f864959c14c4bfbd83ae4c19602460428f9f111e43fdd3c64f9eed410da10348444e6af25f0f83970fb23f0f5515c68041ad694cb9ce9621dc504b564a4757dc4d8ead6db23a889fea5a7982fdf403e609f51758ad7bb78dc6b69a53e32b808fcfa44b547d7b23fdce81ae90070e8cad630ea8000d8f840af81c6feb308b8a5135db80c2963203e9a13d2c5b4926e68b8893113c309c3bb4cb48f06fb87313d414b9fac19fdaade98e1b396d789381b057a293de05fd96454f4394b122de31d72bde9b39a3c171c4e1a036d7d94b8e59506dd16aa28596513c3a0e6d2618fe8d39671c28f33630745b3e671c872a01035da1624c6516b57226aced46e63c0a5c6f791f188ddc8b0c4637695b1b711a92ee422225f5509d9a53e894c959438fdd81f692b930ffb29bbd9b7418c97ce03263877390f86bdf59b617622d181061e9f146c6c355c7d8c16924f99d9b135174935fbb63b09d06734e41eacdb7c55f561da81126487732cc6ae18a1d8df377f865fde5db3289f0a77359550ff31b7778724449db57483c59a94bdcfb7680476a9a5a38cdac1c1033be8c1f4e6689bc7551a7d01912bc00e804b6e9e6b4e84e096b9ba4f07f0d67a3baea5e2fda3224387e298a144c06d78f26948ee7c88c11c121b4ce69ff2912c93ee7cd96ce4faf7ed6412b3ac238c05c9378dff1051e3a48c16a3daa8597ee0ee83fc0b95e2346f5195a2d8af8df16c9608fee9c1fed1d5ba11f31513431d304a3382f18c9ffce39a7c637caddd67153c18ebec8138b7cfe9e08c9a7844e879424531f47444b1cb48bf2cb4c92756a1c03f1d37d1f6a2a22967e5a719aae38732dd5e37f795591ac91faec146131b354ec31fc0e0f80d02c79cb6f40f42f3ef1d0ec6ad1cb208fd6e56ace109c1e5a82079eb7b6a32d358963ea06f7234221e84b67c716d7e523b502de542fd468b130b9ce5ee +expected_shared_secret = eb7106b4bbabe9796e68f15931ea311dd171561dd000bba4a80cbb13c17e9709 + +comment = Rho leads to matrix containing zeroes +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 30fcbc7549ba7ccb22607740c4a4ae9c72a7c9d75f27120e6551a24baa69b07859abfc0a3f81ae50b410cb4b13f4d3174acc7a36b3cac768430678b86030a92506bc3a37bd721320f658bbd2798bf78135c8a29c5c3b7eabd292aa278a0f58620a89c8b502b3cf9b0ed7d3606f612651f28f5d39646b5b6a16cc57b4574b42fbc5dc6b15b92723ede862ee02cddfa891a7b243b4b8ccab0969ad050a35ba05a8d650c2b19a77f8c97b9c15386233cb543063645dcf1c976d79999b5b16e095724e872c9a799246e9c68388573db17fb137a936aa3629e68398851bab14cba8d1c0be8c213453863a470b6e4a640adab4c97375d72422c1e55d6c892fd117999c9b0a000b7a51064505b237055882c3733020fb6375e48d1a07454cc6b2a7c40bba61c10062a9c1957037310aa66a1d560a61d2e2362d912ca5953e8c3a33967b6121b9a888ba87c388bf1b80064b8b75fbd6afc7dbac45d45cb3d9410aa9c56ab369cb4b3ecbc43942d344a3a6785049b78329610a297512bc9a2920bca6aa08e44467572c2d93b513fa83c97b1a29c161c00bac6484659c67e74ead90095d19481fa476bce539459321aa258da0e2579b06cd91e88bdd297447db2f5b836d2c3613d25a8cd00331948a93cfb6bcf5e374f9f623f571b330ca63ce6210c7d229d27256ffa9a32911aeb77024ccaa5145ab493eb29a2e2a134f7bae4c39ab6a162bbac174ac12b1df51bfd02c159eab2dad955ad3a978f85449a9f7b253a74b4c81adbdfc3efd90ca2d7c8b63e574a09bbda6599f98761ff0c1b14ad429512a46e3c1392a800594f95cf3603a760cbcd6c7ba86ec1c9c74c232f31a56f8a3cfd29f05914ad5220bb4dc23900b55ae5607e00022fc0002dc363ed67c5aa49abeed31994e3440253b82dc937ec718273e25293c01305f4c2c47ba47a5558c17fa2f9640034eea6e2f2955189677eca2af91aabe48fc93ad497ed05208d8401d921a5aac231964fc169673289b270ceb9c745ba2b07dd402d3961c2653c27a697087a58a184a9d8b4a34e355063da16bacabaab34c0f6a35ca4500b7e7ec51af92480f726b034b6246295ea017ac5d7586d2b17d074c7ddb3cb5e9597c35692e405a900a535958fa713d0ab6c9466baab305e83597d167783e22b7099bb913d932672954724631225b6b7c1b717388746ed51050d26f4ab89c56e12697a9ae925c5d91194097da004b7925a90cbb849a2e8e250532fabf1c9bcbdb15a5f17395cb93c7e374461c254ca69c3567c01468aa02d3e445a1dcb194303cdc3c580ebabe6d95aae182621dc52e18055050274f024ac6a5180a49dc0fa5033f07295d00b70a5a93be6ac1a412c4217fd177a8c433f4b26cfb14303d42a705984a27c305e1f08da46213da399eb658c14eb03209e601e38887f2c5cb2aa4384a1790ed16a19032cfa3f368a9c1218abba6b0b606baf73d58b4c771baab5481ae971188a4a323352a2b0f0c3e45e808e88b2ab20942c14496abacb28c313f246b807ce73d7b09a612382ad295c74bda7ae1249dcfb534143acd4ac6a68f7573bf256a946395cfe4463e76bf8b0263559b9618a859f46bc3aba5ae34f903038a1df1e02603801be7c53f12a5000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = f28a06a7b862171162d64f9df3702b7336c47af5e15b1ced699164ae57797974e7fb78276e883360e2b51016d72d69164becd785570d9906641b0650c34bd1c556013688dfd9f2858c1a2151465e5ab51aa40c595ef4909b9c0de1eb7d4ae92467721131e5ce21f7365788798d18682a8035e14d2e769ca10589531ec5243e077a60abfae9bd0c03d8ecd7c4717c90137515c764ae0540a99fb2bb4057342eadca362c1b540d97d59408b2131df36a950d0a257eea95796f9230d649961d1cee9bbd30d1b88bb3680075a4c5976efeb95211e184db3665c7e184a912bcbcd3ccaa249c722b89c35d7374256b5490bfce5a449c2ec93793f0426c4655ec82f5b4492d44cef93e55802eb64d3fefe0d3b450c9b72df7bd85997c6c6b94033102091d4829ba10ec59dd5ca88feb328c39748d26bf44c5b5310d814c4cd9a1291a041169b0ad0af9dad279dd80a5f465bdc74c5060c2b226dcc04f8d8c03cc38a4eb1437c8500c9707170bea771fa27343b0efeb485c0c2b0b5fdd2d0e9c450a05b9d7f554031125e336484d235643f429c015dadfe10d050734e2dec4b915c3350277ab2bfc38479dd3f773f6d54a397eb7825a398e415664ec884dcd6d958c5794d53ed9f8bc8d1de0e48a12ba149626bb1bda6710b48e1803347412298db17c224f8279dbcd311a4e67711fa0a8de2f7d4234ec25952a415c96f4d3a92e8b9dd6d37d726375145d0dc68afaa08701ad5af5a9a029cff366e01f6bfc1d63069d8c2b00f9db8f1794d714b36e6e783b6a2fcbed61d16eda97803602bb0211cbf5b8895c2a451407fa4937369f0deb8807759b16d81f215b69a257e207396df441eee6f8069a9637cac41aaf6155dfb45a7402596370faeb1ef9bf633aa5eb96a207cd3ade1765a597d4f277b6f7c33b36e816d2368a19af20df4bcddc15381f2d8f04e4650157ec4cc0943ee080d24bd771bb35c0f8269be961249ff8a5a315c1ec1ed4ffe5a4210b5455f6d367c2df5f0da09d20eba91c6dcf63b215b39dca326fbc4649d7862b56927b41db2217459c23a9a9b9e83d79fd6f34295f3853eee312bfd30ee31d02fe026eb56adb6135fd51a8c9da35c171dcf5c999b1ccd78de1b9574b029cc0a845b196330a3e32309d61294468cd40ac3d51011eec5e1af1e397c0f6d2355e4a5bf69391e7e90825c524d76c688bb8cf495d2dd70d316996d3b0fcc8d1008427413f0498e63d5001e4ec571bc0e68c37947782e48d71feaccadbd1d99888bb6c4f22e9eee0800c09ce8ddee3af45272b4d9a3ff372ff1a7fc3f5fff8fc2eb3cc909fe273eabe09983223dcbe0cdb6641b5c905be7bab920a21ae6f43beacac025fe07ebd3d5065d49dbd0ba5d603f2c534b6533049c62628bbf3002c0da4da81f1e0f4e957565d79c4b1896b6de04393629fb453512f1e1d39b1462ce7f693ab482224dd376b0602dd2fe0ac592d7d0fb92ec5657af2317255ae3f757b01aff57e112c61f53b850d41a0d2964121a33d15db32dab2ac7583136e +expected_shared_secret = a39c5a7a5e9f4aa4a81e5463048c7028d0a2df5491fa678d38161dbd3a08825b + +comment = Rho leads to matrix containing zeroes +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 92a59b6806bf4af964b370a7a5c3b2681cac9561bc4f59c0f32151e25ac4b1c80452e7cf2544824ebbc8d33ba3ade7ab1a585a98a51cf8632a02295284f2acb78373b0078081a291477510e7f6569751cde2106f8a064a24ec6a921103b8e5b820410f15e51ec7a49de77799b16c58d0c350f83a5aa63a286220c9ae97c2455780d917b2a7d6738735be61964574805f848c1d0a689060e591d60c7f057c92896a71e5109c07c0aaddd3622b672109664fadc3304118afc71644c2b7844802529f38b9a2212301dc2d2e589e7577ca2454a7fb78bab8165ce4f94cf8f121eec4531afa5fa02251090caa9425aac327af64601fdbf19feba983b0f55a22616048c646cbf08091b315dea5637fc8aed7b4418e09a70dd90ae1004d8162b5d58c24eaf7cfb47b26ffd98c48870c583aa2a5a6b5385b51e5f46236081cf9317c662498cce911b1c736e02503650761fb528d33d6708a4bab573456c2f01a52a024996a80ae0311dd56aa532709be25ac0e9b7862205e300253bd31210974b44477c3d0c62ab02b1f7d8bc910e5ac0ff29af6c66f05c48edd4601edb547ece62f8c4944af201221886da1f36cfd937e98d6a8bb606507c5099a76bc91a38812b822da60afa0d1606cac59b267ad4f47782a882a8415b9cef663ca89240c474ea265adc9f71eab97cd8215c10a32cc45287ed53180e0982fc6aa3db2b0cef48640992a33365454761ac072f765e84a46504304d775929222a6fe7a3c790b48bcc255ff189b5391add20c4581e4c59d09744a56a1941734fd24a81a968322b33da31234cea9387d31a9e9374cc4203a608285de5996b62143aa9a4dfa5a2cb0066d2bc4be6885587a4408bb3103a24b2561729021458b77951c8b8564ef0a08add70c3b7a1afcd3b4d5d3be685ba1439aa66a2393531b86a707576da189ec3885f5756c851abe689024bdc2671d926ca511b7c3b41e03c79c2b3caba27bb31f5a3184e16055c8127ba7b0d87216f81318a0d88f1665996a6b47bc7808daeb799935ac67653c59e23178da6a7cf40f9ca22246ac56db9417e5062d487c1b9ae3664109a9329567bd8c577d8cc0ed65cf1b6887ec3836fd16bff20a7671cc37b0921129b410a5e22b01d3477da0230ee5018a571f7519610c4badf145c5c4f5a29357a17f245f24e3bec0d22937457c38955f0aaabfb4d80bccf57909892e120546868b9b556289cc5594c7cc083e808f66e20d9c855d4cc936db566a4ada6e46b680df8b91898a002d9494a30127855c4cb843a8080205fee96f101b9c06104191d0bf92273fb0cc6f089a202984c0ea1c46d1f3b037b7c9b557af96e89784d990a66a1634888dabe6058d03c8b857605621a0b031a52cf26385a55f72d36555b87c5f2a36fdd4a72820ae20e90025a077e82c20cc7a8ce4f64c12940976d34e49b1200bd2b11b94bc5fd379f88779133a2f6453797f5c34a7b916f4f3bdc8c10de83b08312ab49f34cbca4917311401c7581a3cc02cbfca9b1da3cccba54c1ef7992335b25e282ec7677698c8ce94a1846443b1ea9261ff688f467212977493b27a43aebb681450ad64f31e158a5cb98a9ed43554c807090c22a1f343605bdac089362c0e2bf23a83000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = cbfe4560b3b067abd9cc82c2c40676f02b730c5280fb13645666b719e7d9d5527e029f3d75a3024502b338be060364a41981db3c7f52c59426b43fa835fc2fccd92a26c903adb74de93c2dbdf590996ebf1a9e2003e77cc896e2afce50d15bedf3fbcb65675f125745fcb1804e25ef99b6f792578520e82e599c5e83a500428b191bd93798b73645ffd10c9beb3abf33535bf149a3471f85f55789e3f73b55425185449c60bdf62c01a8fb1936f50db5d436066824b378902a81c5edc3b74b3bac3c58eaf3a993b3b4c1f2a0027cd7156b7127412294214fc7aae635edf26f6e5f8034464abc05f4059de6cabc5e4a8fb83a8c25bc88e7e9bee1a8cf312434410ead60d1b482399422621006ab52127df15f7385d62480bb0fe494843775aba4049ef94cceb78e9dcd3318608d3fff2e75e29769cfd8df0e12a77ba6db5f54d69be74a2b03d62db822a8cad7f20ad4655bfd73c62064d23fe521d37daafcf143f693eab811d28da6d0929be3cdf61a56e487289c02151f11342756bd419553186ce79bb17d5d5754752bcb72349b65cd64b8fc6066656a9cedda0aa9a09f567cccc23e547cc9ad86f636233be7815dea220e29863d830d0ef9b0a13a62a56237e2c6f443e61410253957ce3b0f95dd422012e1b84d32ec17f534f56641e7fe92ed181d830b4d0f3245df6ad891c26bfa116d40460c497d8fbcb6def0ee530ff4422d132726751d724cd84f8dd19e286e0a4d891af0e4a913352b9afecfbaf0210077c5be9ee7f5546700754f7f0dd2c2600f113c747d2a706009a8838a7b2b958324842f8fe3933b8e522d63d772a3bd0d5186342a20ff3a5e7a5728fcbb3ec18d0c90e5fd2430359affbd9648d1ca2400a55a99586807bf18041fe7af6f51120ec366c99fd4994f20e540e31caa71d5f95e60a921cc62db1fe6f9219a7705edc1a7015e7ec126a22f7ff0c9bb4aa3a1126d83ce4987ebbda148fa5b3cc07bd7c78f26699486a3dc690920fd21d75fedc4b631841b634641594fbd98ce2d8376b179da29f925a31589e04c74c4fea00db64289e30ac9e58043955ccabd9515e0c2a88e6b50dabdec8b6f574a6c44f4a0ba4d00478396852263376574706e5f92220492782df64becc8149b24feaf808c85723b7911961051468d38bb94421a18364e2c158035172e9368810d2f68f64499b6b407bf775223a3f345223ea3c1c5f456f48983d994fe4da62d0eca318b130bc8ade488a900b7746633187bf12a598f6f144c55738d4831f0ff3802a6a8f742d7a9f64f95f2401194ffade9def6f73fdc67b386115c9d905719808f41e2035947cde0bbbb44d92e51258822bb4e4493a7a4b0ce64f8620b3c54078985a3dfd4cc2b3b5ec3fd870cd6ae095c39049ad69234966c5f1f70140f88c75f11f03fa25c3d673e5ddc14f79f567bdb29a2fff88e11660327559bd0d2511d21a8ff1957c0beaeb1a26f280b3f1146be891b39ce13010c77b775d11552e59dbfabbb64409553d3da222902d0ac1e78b21677ef +expected_shared_secret = aa50a536b37f28e5f80904269d0555a6172d717433bf9a680e75e98af3209a91 + +comment = Rho leads to matrix containing zeroes +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 89f5b871bb5473b52efb4ba5b2a8317c7255790b7e96937f9c95466431a268b0bbb12aa639d418775a56d3595231262c6602be765498dfc0b5cd404a630cbf46e06cb235ca7064a8b7e2471fe34ec3db94c8ea14abf797d5259ea7236391c3b7ddd3c3aa1745cc6857dac8a42693274507985c32bf65535d6644463753c00e18ba859b86b654916c9b14be78a5d11a2fbcf9ba9225566b600b0edb3637a18319027aa494a9631c6958221703579d75b9cb09d21c34409a3d2b342c05bfa4b82b19444612395bafd8ce0bd772b303bdc37c1e57a26c6efca874fb244ce314f63b6635c7af1be1a3205498204505a80138bffa0e79b60f58675965578719813e31b352390ab04376b45344bd8efa65fea466e8c78d45680be0e1381ca5af4cb666749676b2eb1e02d003dee20f4298b720aa6895a80a17f242a983c97a43981122043d444a5af3066816c7a07c7c880b2b2b8958323711e5551c91268b1ecbaa3342418b322766334d5d4691e0111d56e48637c012bd04a9b06524c30752fb7834a2506db7ac7ead1b72cde45dc793cf875085f67a055f6cc0f7b703e29c578d0329dd2a01ff05ce9b1a5a8b993621611fc51356b5d4a55c4a6ca3b5046d7b9e305494c93177c2e78ed1bca1110c7221ccb07ef99b3aec74a8f083ee5a897d55515a5117b1c244c0898738636e577ca59d16cd1c44299d41c311a8728ff38bc476b1027426bea27795396e2bc24e0ca43e17cc8e63bab9463b42bb6812e7b840a9943ff11210aaf11568c85978816bae1457ff364923c846548b5908b2737514c625c8c11a0898924ba682b3c8c30437e8b23477d06d89d39f590c8e2561c698362e99224450217cd0a393ccf870a84159273083008345b2973e98d78089317f7993c299b7c64ed3309b5b6594a236bb8c1c67cac692a2a1746987ed6ca84d5a5a4003b1b1347a9846656a36034d7a148cc8157afa6c915a05a81b1d88568fc3f62b9996062bb99e43447bb22a5b29473a728c929d57b6ff774f5364c9f4145944b979bc549c1d5b0e9e676b2d493f799875762360ab9bb4b322484bb78fa399bcb889c08c94638d95518bb8742bb2a801233adab5bb95903f355126629aa87477b19d3135af8695f3da81df3559d510a7da3cc364939c8b507c99096630601d60999278b731824642c6a018c22c82a60bc9e0203e0b8139dff977c2a903b812a0a6c79c9bf21618b4ca7a836e20346f64483c277750d38b0a204baa8b258db85b3222a5cbbeb599af8ccb19c649ae048d97153b5a7c974738a08c1c653292496287682670cf30197142dcce7fac5694f58bb9e23c9b496f0a939636d6522129038e99179c8cc37697c83e908aee62a1fd266a613853fa12180407a222682b49bb41c9c23c55c63cc7d115da6cb53bc688fa178f632b0b9042631999b6de6165322a817ee3037bd33e6d6024174439119993e1776ccf6862e104019cf739ebe62e0dd10628dab37946c0f1e762ab4bb94fc993cffa89ba245d7e48055c43a8819c4701bcbf44044210c451fd4c5a82231676ac2941278ffd12c686bb21547a1e832a48cf991bca13433d4a55fb485f04546c8a3201dec55d1889942d1928250867ddbf1a9138000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 0802659cbd143028c3d5f499c51d88e361522a2a6c353f8bad088b1f0a6eb02f94458508a80aa98ec29952e405f754a77ea9cbc07ccc41ff66fff5c4664910a6363da480ea8f0de3e7bda007593199494e6be43c713178b791119adcd4fa712e077eb46b39d1bb073ba7f39b56885906fed63a0d6a1be4bfc2d512a17ae327fea8f1f8ddacc103fd8a1131908ac348dfd01372968ce3ed40ae90f747be9294f8e3c356f425dcc5002e9363189969f3316774acfe7982361e6f057a322d667032c5e1b235cb44a7e7be4cf46d3f6b59154ba303abd608e75e55214ac4993683dcfb5f4cf3d99b31b43a054325cb6fc3614b76ba18c6f40ca3a289c6ed338a5ede7677f6a57cc4d1c0ba121feb6cd170419a7c9b85c63233ede2db86d8a52018e2f00ca1ac31157154dbb539cb65090b2eb3a5ddf6195dcd25a2c3c8ada060d2a9fcf43bb1e67ac25dcbe67709f00abc94b9ffcf754fe742addb0b928df78122f0b86a2a3b7db85db4a9596f53048cb0bd2e849b97f99f1dc4deb86d4333a891f1e5e205637a31956cdf6442632618e97b8e2f71f0d97a88908925fd1f19956d34b67b258c49058c9a162626066731ac4c8272682c6816e7a513178ab4468772185d461ea5db42ceeff258be448ae8337f1c8ce44771bb79d6e7736949db9b68307388c7a28781a0b0180bece5e0f21d99309621d6ede5031cd791d591b7296f8fda67af0563598b463e19aed4576c369dac22c7e74ef6c1be036a74e9483bdf534cbfa78455a84568a7a2ec9a43b0be67ea16758cd60c999cd72a8b14dbe544bc142eae6ebe838091602535a127f7c1d6ddc92c07f5852158da2ccc90551edac0f043a951e5c47259001c8fe9ef8a9af5d4e40422dd8b0244468a5a9f0fc62e300f0b80069993cb0b5fd6555c5feb71a9e07fa121c82dca7d9df561b967436dadf5752e9cad9bf587a3e6c18d6fcdb00aa21e6698617ba0166b52f4406b7b184abf053a713e55e4b6d5148651fb29ce1297554a254df7ed1c97c2e30e6afb19289f1e8c94831211af2fcf6e3cdd67a04a65c19ceccf08e80f649b5120f6f6efa2af36c53884ab9a5fb5ce24971b9c907a130605bd996e6a7e4b8fa852d421c5cc46d05148957288a98ede63b556c96b6056496736b1f1832463e5ce4ca602eb3c2e86712cf4d8e44942554d930ebfa9eabaefe29358f23939948616c5ff831f162826732c25c319155808eeca9d7cc5e3325b01bffbecb7520a72b3b71e4c50d959f45b6a79789dce902ad29e3a66373bc1b40a821c6f0e6057c9427f30f3a7cad672542aba0142ac6b371fc3da667a5aaddfecd70986571b49bec52c59eaceac305dde821d248da99058e3a23df496fe51cdcb45501b02cf5338df7fe762990c2a6dcefb23dc1e5a257c14962501ab1e479881ffe5868e00074cb8fafe6477b16530854da6223153680571865a6ebc058e64c11f09236886c736592e73a41de2c093e88348631cf31de6440ae21bcbd045166d3af8539d77f2aa1b202056d23b +expected_shared_secret = 9f4a910d1fcff86f96149e88e28cddd95526ee64c491291e72a2719f97b2beb9 + +comment = Rho leads to non invertable matrix +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = 947895240c96489219f575bdf7b6305fe7ba4db674f8b57be7d17947b73ba481a51737962bd0ce801254d54bc9d6d5bb184609d844501eb81ad43007fd3513e7e6aabde15bfec8b74ef67be8e4b61b4358d4828914033d65f89915e6c27e5676c98423f0d2508c343e049cb8044a4a77666a3475a52a4c73f38acd49519486e511ee7b8797b35fa8301ba8fb793f6906304842604b5608fba93f3505a765ba5c329289fb4a69347501c686b5d126ddbc58f5b8c5bbf044a1a58926d77ee9a7bb0ffb69f1986cf10719b2379130872b8c6640ab856622eaa08b298adf98115e68615d9627f339c4f08ac67fa464ab5b4824ca3765e33a16f7706ab7c1deb31b262a3e14870ee4bc30a746171f3c998fc73663320ea3475564c25e9fd869f1e3b94ec15ea8f355e6944b874c469e96050b0ca62985912a4b87c4aa5434e4929430b06f220737cabcb771b6714497cb07b319e57165449bc7904201012fac808013836dde3555ff6462a77125a6a0c6f4aa0822006ba5357ffc494602d87866854ec8b646ef5a545430bbf155cb4e9c36ce2c42b6e48fc26296b2c1415cdc8d06c38ec4c37f9e16afd6fa232fa396832a26c7562fd55b80bea977fdb5b7a5f95e221401a932687e535b0213056297391d36b0cb320cb3358e1ff19a2d239a8f5a75cf40a5b4130ac2972c1a5b9e4fe799394c23196805459336deb36367b6b2c81cbbdc56840ee0058ed799c5c735df07a99043201c2427a4699f5ccacd3c86299e458f3783628258677126556c485406d0678d030afb082b88676745189800fd9d6267b557a3936e262baed80ce471997b0147b3556a8f74760e85391300ae4f84c494a09da042422f196dc0ac3a65687d33ba4219788037a14fc4087b585842290593dc853c68d70c410b98117249654c3332685de518a3beebb5469c4d2a624855124025544afad7a26f5234bba21b8e772c0a58572608857336a9ad070b6b01990fa4bf797902d0765c83604ee4767e11e4bf45ab7dbc9ab7efc180789070380badd67b96f0c90cb95a4152144956309cc0ea6771655ef11579dd703caa09c1e314493b758e8a12a8e7dc8336c29a2a9198873b2065caa6c8ec545c03827b39b210544668e9884353791348bc74032d4a7a00396744813baa1a83b0d1139ceb18c75f6cab6b13cb8722647a730f67219096b50375a105a5dbc960142648fca49aba468ad77a031334ae650ba879a859e80901a70fc2d80083c2b0786a589f1b65e0f83527b60d298b8b93a177901b78c61bc6ba296a342a412f1c48250340a0bb5e2b227b42451aead12b196540c9f001907a40bc68821b040607f918d9199693395d4f828de0502c8c601b2a787d15dabdbc764ad9022cbcc87fbc4a84c22840a39cc610905423a5c4211abe722b69ae78803fbc56b5f3671491495ea9a7b067541954650582a1a6358af04419c4d2acd16910a03a2c04a1ac3ac6138f162d61e6258c863427a8937b65c183734b533c4bf0e52c3c06cb5422c2bdd063e405d08bd7a82dc731c2e526a5d19156b19b68db05421c5d099334bba29da2d953164c6cb5c6860de4adbd60525dc96e1d261786d79f09819d680598a900c42c3042e336828a17000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 2a7190d8db048ee0963d59eeb251bed93d3223db4415e438d40fa06cfb65c5dbc9cdc219a8e007434870fa10c8d64f0aa3e5016c67378b670852af5615e23b612f08d0f83d26d4f48e108b6e6a639649d618245055270d7e6f47c48152ce42effa918f74118dfabf87a497a412a0cc464e99d2460e0dcf6a16b99e8f35224894defa85a02ac162e122a4389a7c85668781c6d682422bdff1edcb442a73982c4512111c54545fc8cb65d1fa2ee1ab685cd047aed9085af1144014810959fa49e7c08ef15bb7c97e8306e7a28404c9c26e21b053e9fb6ce86a76b13fc28df94f3719bd55dd281ad1b8289f8c53175838fc406a7d705c4a91a2a0053507fd7176c1efe28bbcac57f555504f5b2ad0a7e8e9d941fc80080f6615130284e428fa18740af5fdfbf848b4c772e38347ea7cad57a72cf02e41b114de1380238a6fdd35d20e1847e92c64a84039fc3564a7ff85ee6c4a7f5b05fc90f95cafe52747b34e3a9ae91b28c659f4941f2c9ad595700c31b0dedb53d6a2d4fead5d754637e89c4aa7175f17882aaf775d850287460e4971dc112c498000f4da174aa4f4f3f3202ea9e119cee357caf9c1fa9623fd1033df981c09a010dc44a71a7d43d55c328eaf205586b225ca998c066623993046eaf93d827a891f1e997fba4008db106e430ec7528286b2b2032d299acf11fd3f8fb57aa2cbb2642412546e09fe139b377ce8f6e1890be4a23f50de04b5c93b701a8679ea102f90f4766d603a164aeb7270ca85faba085f15eabbe1c89ff2edd4b50227503cb31c34f645323fd38c7bffec6a825621579b565339624b434abc090ccc4c1227bc63d4bc1a6e2535cb5b299ef03061f9bff77052fd23984d7d6f63d986cf310474feaf338791b158c542a361c9c222f4012d4981247f4cfcdc3a2cdbbeebf9aecfb97e29f9c328be170d5da3539b277d3f4295c6ed3712627b5176b7ad1d2aed1445ef2e47e46d251b74b906f6dc3c3d9f54968245845f2fcb33522659508bf54e6358dd3cc43c2e097b880371c6cae243b11f36f8c34ade6ff113da5ea0868c4f8a5d0eafa3fd5ac8f5bfe776f5f72791d654fd845d0ee6c9d28fd835dba5c367af22ef2232526bbef604c163417542bf6fb768ce2c29000ec626cd56acd6f3dbd18b5485b710e4456f2a01c25bc0af5aa330a5f9d45bdfe985710351c167556acbe0fd0b7bddbd3a86dcc7d7ad63130f33b651afc897a7fb2a724c205867c4dbc86d53e68b1679626c750fe5335853a3489821e52402d0b1ed47c69992179c663ecd914e77b0c94e870ba17929d53e567d444e592e580b23c160933fe3024a49fa8656236d3917192c44b0c5a30d79a121ff12411dd6b3d443a5490276dd379fa9e3227b1756981b1cc0ce44fbb939de802d16ef81bbb98ad6add920c42d908c72b7abfd6e946dc16598272be95c72a05658070a211801b6ba7b04248898272e6a348b26e93207185c2d57600493a313ad162561da704b75b52388d84b240993fb3a4900a2951bd380589fcb +expected_shared_secret = eb34705a8743c042134c4f17ed6fe334ee260a7e77223af5bf77788ddbe5cac6 + +comment = Rho leads to non invertable matrix +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 33e5bf55f1b014715eeb1340e17172a3414c573732bed83d3318b40e32a5f4fb064a8988dba93c5f1aa8249b1d0d0393ec765cae519961c109f607306b8322125b0eb6bc000a061b2222b58faa86fa706e27803b02b79aa4e9b26e37130cf14b903a70bf042f4d72c091297179f3a1567b1cd98bcc4be1c38a75139df8c422769289fa73562a8429e88dc60571e933b22d8a9471cb7bc11a6b74e0b62643574f91413e9913229584dc8936016cc5f5560a044488183a53822c77f5b26ff9f2c289e7c88795301e095efab2b84f90350524549c855dd9928dd735a0da461450a31ee2e3b285698b5049000b58344e393a33ec7b114acbb6c69ee40b62b986a7a70a6bda64ac03423517360df820cc2f5a0e279b30fc77a41b220d6ee3ccdd4802ca3447d5065dbcbccc0b3a79e932c1225acc8c02c906c49586037e6a16c5b6c64e6e6c338937ca94c77d9cdab427a258804768e739ba637725b7f98ec064b645e23710d50e1a563719b190d8127e8d8557165a7e61770008621b211c1ad9f004a97556d41511d2a8a290490a0f6b289d3c35cb8830f5f6c4d60b9cbda14b50677c210b6539229d44c7376159c4d4f4b7e1557e1a25a51f6456bbb983177599f7f1ced0b15c751b1046a1015b4acaf53c8e43c7ae7a14202a54a7e3037027fc5e8736a4d7d9145a56cf65b862f03b3a9848c8c2704295f328a6cc83cb17774cf20f9db1162fe604c77100ece175ac3a9f3f297c72b7a3efda073fb6397e0aa8fe60c9e5d26281699c911632d055434ef4792a87c96d17228611828c0282ac82abc3041fc902c09a1c918fe20a0506788a31cd01583847373db827b87b7c29c519ae2071185910b4f586be80488ee85a31c63857fe02a11bb270337b6b92a32103197f260b0929e289f9c9308056a7539394c0071df82591428bb8a2b734db430074f9749da3bcfc46163c3b5f31430e4556b91efc1f62aa912361209746909eca91b40ccc815c1274762b9c697cb7659dd200a29a641db2404b954a1c17994d5b3a49af157f7d645df88863f145734d7262cbf8a640d2b31e601124717c6f456db325b1b4b344bf3a922f624df598756f8a2c2acb0c4e62140ffa4cacf4c6e03828ec903acdecada6d0074b2364057584b3f0530bb587666a88d2e354ba68bee404227d7a963d8bab4c7545b95a984d117ab3f576fb1ba4e912b468889762009eeb83949d39613ae7054d9c76ea556ee4a8286bb489e4da9e4bda4db0714104da37fe1777adb632c57020164331bc29abeb356344081e3907c467657ea53a1111d45ee2f416f945396e6c63df328575808640ac5b1d5a711a5523cb7a18263224ae615840f9c448274409369b2d66b135e57648f07333fa326045681dd20cd9bac300c834ff582c1be9223f427bfb13731b27175c1028f55736ea50a7adbc819c742c22328363632f1917cf5c89441b841c3532693c3718a1fb693b28c103ca3ab9690502965f907b82cfdb4e0fa2884ba7ce8b0768ad36a32ff60b4db45edf64a5d02018836a8230c6a2f8a037b72261f4436b987066bbc90f65f2c940635cdbf1b4c5a853a1113c86010bb7b558f9a773cab0434399874e01afe167908045c34d3f452196000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 0b52af120747b8cc02ce11b70f30e159c9f3028f0b44757f23deb9b62ec75c61d64dcc774729b5ed59c23cc809a88d075021e7799b50024bd9ebdd3ccf710f17dfa89423d20542a44a97ab3bda0bc0825f76f8f481a52e66c344c024d0350e4d28b49bed05dfa166d8a5ec175e43a2a535abc6dc4decc1cb9afd9f05634d5054fd7b4c17dac997a70798c5c712b276e56e2af4543f9b9e5ce362d2f5f7c2f5af150c9782af88ea561161a6e5892c6a7d22a367dd461971cd801e9c5f2e2fdfa70f39550d06157e66e0806143fa56d5a9667e038d0c818b2be48de10408c67c948ec5cd1c543fc92d76fe299af65f94edd82f0be2ab3cca31272592549699555dc08e1de7097e20b83fe3eced16446d90f79ab46ab702804cb3a0358c927b7d126799f52c47e613a2730680713e8056135a26bafdd8a9e38d8c30e628a090878037da0afd82b9fe89a601d3641b6514b0450e3792fbc60d3e78c7316301b2e3dad4422c85b4afb1d1af20de6938a1d8aa2625b637ebcec8754ab5b66aed8b13b669c81f986d158cdd9bc82db0eaff8c80895d9289e30f0595131bb9aa1e77fbba451c1988117e2ce8b4e3cfa6f0b5c00d894753a9c93d269d477b1c86fbfaafb1dc083c7ecf3c688b36b4107a2c800f17d14acaaf795fe9ff913f702d188a204a26a3c301e44a84c5e32e9c8efb7236943849dc442bba5552fb34dd7e7c486959fdc8df5d380b199a9d637c1d11091406b3e3d2ab587794eafef76f6302c1356813109acf1dbc7380f6eb082a2e5cd4e53f93dc277372230997a0858229f9ffec2691d39f748dcf1c911f8d49d281bb9299582e1dabcac1119a7bed289a1d5ca9b471542be7e5bae58d275061eed3ab92dca9e444061d641f3e128d9d44757b350bcf673de1165abf6e10f87d101562eb6585baea22583fd8193da19f15bd88ee614523305e2d996b04db09aa3ddb422c7b9dfe93237e3c85043469916763bd58132835795d4c6d01682fbd877d132589ff21de3e4882a927971ddab6e2b31a01f3c32ea60f506bab44f8ae74cbd33e551cd7d52791155f390b409f169f2fb2166719265c6d4fab72abdfaf530842ca86e6f2d6a04ff0c96335ea20564f6328f4a10caa1b9ae6a2873a966e2d2ad2819f3e398a493d878bfea76b4372d2b24b93edc9f1e2438ac6f3fcc1944ab99c3729c3526bf1069b866f7b630c5b6ba7e10696326bc0096aca3a6e526e484b8161716b7377f9c5ac7401a850374c3adc7057d0f783eed9c98a3004ccd529a5f0846bb6cecf98c55470a7b55d3c1be06cbe3a3fba17f118dfd68aecd0ba783cc7489b7ea3bb8fac98e70c1e8f047deefc3760dbcf6571305eb1cc3f88ae3fba08359217ba391c1990d33b89174a5e896d655aa36909a4fb65495651ce122870b5e870edbc4b0dc9d72dfdb873cb219d1d7b5143993c01ab6929baf37ae6de2d920eeb333eb55a0a32a1a9ed2d4f29f9dca34969b268a9f26aa6c0d8378aadb5f206beb4f607f308ab64a9b1669c87fb74a55f +expected_shared_secret = 4ef9b4bb13acabdc211c3e0860f1b2dbb4ad467478f8fee194ac57a869a4a8cd + +comment = Rho leads to non invertable matrix +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = e1b4c439d04b5c35913283bdfad965fd4749a9eacd65d1182e83b448bc3d8f25b525d57db01394cd2b99fcbb6b3140c46c9685916cb4d572a78f59af75342188156fe6b991a7780ad5366104630700d585a6b93ef15a8025b8a32c57681ffa88c1850fca4b65928970549aa668477547b30afea83bd3cb6efa038e451688d6932d342336fa074565775680790404770a520b0845a7a09caa5ab20326c8db671541305ef9264e0074505804ca2b7bce041b69c20d0c67a50bb46e57cc920d4405e4960ed1b20a14fc8fde1626f7607a77cbb9e7835f1407b83ef53c66e3145d764cd297badba3c290957180f650844c31feba01ed2631cad26057fb610f302636500e3337b073e33b50fa647eda24425021c5c1c8eec6163ddbb6419aa3be57bffe37cca885b8456652f7c00ea65c78d2db431a28883577679485611a9cb77f95339436787f1369110203ecb1859fe49662bbae39b6bf736266e1670940780db319c969570c719499ef871e87ab61cf435114551295ea4fba96ca5939ace7a9b712635c09667a2ca87a241380edf030abb8290d1856b520aa75e52fcd3316ecc31a8c71136480c41e7c6074207be522155d66a70d73c913a62fc4f77202203c3fb58171706d55455adcf115314b71ae00745764877d44321df625916a5eb5a39bc915a7adb5c16835817ba9438d8772273038abfc29104909da051dc542719d19007a786189e2cc9ed9268486068a1a531c108659ba37383a9585440dff07116f4b5fe9b1a2dd73320b2051216009a498c2c64b59aa539244e487464475918075ee807ee8bc9bd413af46f80717f31365653b1173693f1c5992b45770c515323c74296a0ef3e8b52be344f1000f22971ac19233f25a4c0df631a2d2b14fb5cb85d6ba9c55a5dcf42be1f18f9be91134a64c57a723f02a13d2e4029d6baa6d0aac1dd5cd6d483c3b7bcfe7f69202d321d4423962a304dafb930cca0671eb6ce7a0754866827a94af22b26985e264af1278cf481193390a2e870b413884c3da9928caa8ea5595a4c4aa2d4a6f3a9956e87c87ce699f04640d2d699a4ff314abf653674b351c69367a7c6041b87aaf8a47ce07857244b71c16112db463dc3239c3908bbf715b86a2b7edec09080c1840a2687c4b57854238a2555d9d2469e798cfdbc6ca06470bbe3659e1949df3f8a6ae42822c8702271029689b4ae1573b66f5541177ac5e05118d4364f43c79d5d2cde2567811617b06965cae7491aff33d5fb4bc24fb8a69f4c0c651cd53084938a56e792c29d941abfd448a38830f9b482b26fc0f5f8a25a2c570c51a62e605cac0a0b19d3b3d5478bc879896a3e01d5e6a97a8cc876bc96ff3040a81c87afea285a35b3375d5b8f95665c1bc6896e46b09d4a5b13a48eda54cfb168a74349887a93ed9e5a1f40a5e37e2a97823a2aa7c5cb028a3e30b19d4b94857090a3e8276ffd45eac0240dde5a80f46ae14f184fbc29804726ca50462ee2583cb92953b22839a27aaac963013b13c1d1847130c96371202b8027f3df427b03119e5e57284f4751ee76cffe81f315932174560dcb211dfa13ee9d242dff22934550227ac0f59698bb700b97bcc95fec45cc65b12e25663059565330c000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d421883017a28b1b0fb5cbd2e19168a0405633601a3ca939f5660877863828dcd366e6602ebc6b7410fdbdbb148fd9d9b5f803467e0bf26a4b3c84f2f90aed4f64d60ba2862eeecd9bda7f4ddd0c031c231f5727a9681845774573711afe23605c2aa64a89753f8aa0c4b51209c3117f111b82e70aa6c55826e12be53216d299b1ff18d2fc2c8c207131e462d614a92171bfd0855a2319ed6a4812d6385a3786a39b489405fded21cf7a9e5d581900c3f04a75be593d4ef5955fd7419813f65c3d672a8be0cf12b42f19d3775a489090cd8cbd07f2f5ea5d4895e15c53737f43dc934d2252873554ba8f50bbbc4a6964c746c34541eff210290c3b128129b2f8d7e033ea6c945d666c4baf45883fc724da572265bea46d6036f029a7d25b9adcb0e88f290c553378a940bd0425caf60374cfbc4dfc54879b95f7ae4331a8789c2086dc4ade9c580bb8eb2fd07f3170cc5306136d715600e05499fe6940aac16f82759065a153bdaf51335affd893c296bdfad1ba11fe4b10b49c2b2bb54444b613d6b5c4fcf458ccec4ae711f840c5bf7c75e4f808e5da7d112b735345d7b7cda8f6aa8489fda2790d096dcb9f8733c7f589ed047e9a56e4dc0c5adea121966be8a1215eda38db95efe2ffd6356209fabedcdf2ea4cad4b0b180ea2522d98cae0f09f793f037dbedd5f03d12db9016bfd79e07726cb575981da69f88a8aa5d104e90ea53ab57fe27b291bedc7acd5aa4449053a7ac8012fcf9899bfc423c0018e539321a986d4011f9beea70ca0e984026277290bd9373da79389341c90f1ea64de20a5415dfa16b7857df261e68d515c497dae0a6fb5b21224f0b2a3125dc3fee9395316d4f269154f528f5bf3ade728f8cb9d27147751304ad1239b955c911ef2f61f0c193365ed6305d4c0bd97c9b2f70e3f5f60fb9cda8128bd7cd6e6aeb1e7909881a6a35d34df4224b0db7631df1a497a0dd699a086aa8efaeef0e3cb582a71deabab97bfb77fcfc2067652311604d56ef3999c34b72793323607c59febf9b41816d03a4db06afd9c19444abf09e1126a5cb19842c9316718d3cfc48e52a0181521008cb90607a18548c6521520d887935c0d789942ed48e68c28905b267c9493e33004056ca159b823aa7e42d9b5104ccf165b0a8e8dc19a3db59b415049b1d82aab62bc6f2adfec2ae128c8b79c0c9d750ebd0517b6ed61f8345aea60c04968896da13f84224fd92d9c56862adb73c0d5c3ee8fff1c05a4586446f0a74ebf39898adec7f07a7ba97c138530403f2523d85931e406d476c8569e0877f73aa37cf41f0448dd2ebc89556e79bc9a081e7f34586cd7cf2f960ce8156a3e500e63fc9d652f9af37bcc36117449b06f67caccd7b9f94782d84791990497761d503d07fbb50e1891dad302f20b16bad86e1e31f7c03a9172a6f079e244314551ca5772d43ae75b4c3e44aa362f9a950c7007a7e3d9758f8ba2664add4e37cfbede8066068b449a100db9e35386da603f7abad9fc85d32090ddbff01052c1601 +expected_shared_secret = 96b7761b785b1423456e7b84f37464eac941840ce73cb0e5903dda9c4c43a296 + +comment = Rho leads to non invertable matrix +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = a58974c8174cf998b681737830ab9132c2b925ba0a9dd7573197a72997cfc9fcb9b7fb8f7f7b881b280e43b1719fca705a209516981c2e88a617625beba7acc5a2335aa57daebb02869339b907cdcd2c4aae01a57a58702fd0883732c9b334bdc6a9bd8340bd83d5b0cef4ab2da156ba283005111360695be97576dc880d2e2a32a9e666070666e4f46b14f2a52d7006c94803ddd872b02bb31ca08901c42834d95a79fab04d8c08bb2bbb0348261f8426cc16720fa188458a4224b92dbfa067c3b518cd74a639119555844df56c0cf9023259d97fb326c45067c18adab10a881fbd4354f348139613b8f5e911b969aad197cfbbf4c1e24616b8f0b87e4206e2c46201b99da006a3c8a704ffe6ae36e3a7c07373dca58e1aab2bb6cb62a3ea5a248450df074dee89511e837b66b409061abdca119d00047252668cab621d0ab82518c66d41d951af924cb6b0189f9654a4a7b58359bde2e5ad4ef729e3d35ce95a589b237f03d10604002debb248e80a93957830c2a06d483c9f062c59b7313cfff647a80834809a3f6198658f792ecf9cb679a53ed41519b5b91015005cebe8b343d16928b9480daa3b025c68c8e9cdb7276bd588c8af8296eaba9a6ff44ff257a4542077e70a73a959738a48c007544d7fab9e87d25b04a01d27a8473ce83a6f91b3c8c9cd0493c35aa01fb38613f5d1932ee81e8622ae09f30cf5394e6ecc849fa881a555a1c4a7931e91100b7b26797b643a3a5773648609b5013f565ec161b657c653de89266a34aa6d80b35450bcafda7fbf1c0aacd8647508bba9e9b2ae6675149a9e042b6378c76335857f0bdc2b2a93c2e23b6f89d743415b71371c9e61f4590254508da401b0d8789b66c6abf2bc31a8560f988586301f54d6123dd8a4e7a41e9246ce3cabb721db810ec54ce806be4b203b8ff6574b397f8e933d930c23f6a128f1c17f017c2c2b22bbf52b4741a8c2198b6a2aac6836c09a3dd1115074249e26180c850567c33fa55b9a23fa365cb8c425eb5523dab4243b3cfe3a7fa7e75aad3b206a32a11282774745bc96c566b05562a6696efc789fe8989a6fc218011c4cbf15b960401b4e4937c752aeda715ee0e39225494db1a0acd61c704a62bf903cb6219951fb568934f2bab9595895390eb5dc3ae6e32390a942875826b453b42bd32045c5cd917a01e283812ec0274de627c1061a8208c7ea0a4b5d71004c77419fd080e662051eb2692d7676c5f319f728169db707e4b9c538f9c7f3d823a53199fc9a9f27f8a183d62247529ad152cffae14bb2d33e15dc669df777ec06600723a7da656f7d4463f0694e46649fdfa1446306377541aaa7e3948b83b7b39522e0eccf544859f1459375db295a879f97755b40e514f6a22d90f20f22674cd071a5454275af02c461152f79b8a247f69a56aabd6a4275c9757ef708ba492892473ca461730bc069a5ed103eeeb21ab5d5b96e868f5b64bb5f18174710bed8108742c25f6fa5b598a81c8a509454d8b6b3744a0e85a64ed9c5855c3014853d4836565419adc67b6566968c2d82bc4bdc424737894f48c19f60079df447b82573c2d28ac4bb29c9272580776b43d21474e52e09ac2255b95e3b3c7ff02442dc47000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 2363ea527c82054080a7e6dbfd16d3e96e07463bc44815397c970be5db84d68b72bce2772578c82f916b29fa0ad068e9c383bde469fefce18c63557db19ce93f1c302a9fa6d1d39faf7b4b5774b045f825ef9139cf113b531a12ce15c7c24393092eb886df18e295acfbcad1ad8edb5d20be0a412afa1857e722a20c2740d1a3ba0b101e7ce331933057f0b1cc19161344c87340f2b78510dd754395e6368e222bfd9413df061a3be812022ce2da08bc4de3bf6e657a3a80200e51f82fb098ba9770178dfded93c3772c4aa610648e7b5b330ea921c1547cae8d2a0621afbaeea92f43435bb40020776f529a7754e7f318f9968bb74057f371eb11013daee9cf8128046e492517b16ec8722d993b345fb0d0c7eb615d1e558acbb39f74e08572bd8ea2503a319767899889196a0a42f26e7434e359594a87f0fdd68149028bbe8bd26e3b912e95776884e83dcb3da50659c54c7f49832996faa3de449cb61715b81f75887529c7e8e98f39eaf3af683b5fbb150f7dea6da5867e0aa9b2ab42ba7ba42fcfdcb076690255d5ea8260c7b106738a63e887fc6993ad0bc93d1e6e9ef893981ae0540200ca393ecb5f7b90394dbf15bd33afdfa499199eb2c3ccd93a0e54fc2211b705640e87475c24e5524bfd5a80fa0ce6cf9db8d263cc203e52e6bc5891755331cff855b04c98fae0b416c61a8e38f669619a44b455752ddcc94fe1bb5608ace3029ffdf881e09c49cd7a1e397efd9f47c2c598c624cab914ead90bc50bbfc5c1aaf42362c48d4c2feb42f95057502f30a1a9d9baf49199d05c89db7cff332c24c7cdac1c3317bb884c4ab041580d3c50a68d3444ea0046850473ebc5bccbbac4f94de8dcd7453ee15e001242214cd26548bbbbb0681e4169223a7e0fead1299152476e9eb86f2a84c08d5308c61b9af960374f407e0d49af22d871a7fa048aa386fa83bdcda6bf1fd27996d597802595cb0d85360ad1717b9900b3f6d68ec680693de41eea73607de43668e55491b9e2670deac0ea38fc3218fb4797ec037b5c5075f7a65bb958a8eb551de7c0886f8d5056c1711cdf2c705be5d879d4dd45aeb3d514b09864333b6c8393fb37c4585018c8ed0d952df661c4808baf4ee3b2a93248e0ce1ba65b04d2ba5e520eb2520039f76c637749751e504acc792dde698b04a4b0b9e2f90c98ba8beda3c1a26c6941e509bed0d4b44809e27c982d1373f89a6a5cc60c3e4042f6182fe28d2d1a034f21ba4a007fad040aa2e0762adb6bbb92a218d3d18919714acc77ee1c281de78743337fe9a0d788d9993b91808f7aae1e88193f6fe8422c0876d225d724bbe5b3967f0fb2c2e4e2aa98fff8a8d82be444b840294f51fbe7972dc8b4cdb701b733b465002c1e49fbdede6f4137a2d4d12235f3f9e7726ca176e4229ebf382de8210a68280ad795199ff82740c5ace14acd100cd39c29a28bdc49a8ae8393c832416f52dcae1f3c24c5a9afa613f8d2df09eccfa1194f39d69cebaa778572f42b1d8537c9364cd165f05f +expected_shared_secret = e02c8542d46fcd5031c0efe0464fab43d07337181fbc4ab3d58bb7bda0cfd7bc + +comment = Rho leads to non invertable matrix +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = 82600ec863a0a0831fc05c3ce85c3ee9417f6c993412227e7be59aacf03cd9231c2e0aa9020c2d17510574e2a1e89a9905722a13b23d3e8561fe37b034916f0bf61aafa00bdfb1321f798a8b0c61062b9835f389c33b18169a156c11917d8949e9f1c8ca2bc0e3803674436f62798295982b6b3933b09378cb837c5ad440cda657c68c76806b96dfa865e0352bd5290b91a42fc74b1e47033942b07632093b5e717b9b90120ef389b8b2c4c7bb324807251b26c779327f4b776644a55e17e4a67c1a3ac2457636a057cb29329dd0b5d0f3295d128394259649e5b735ab80b3738495a170dc9880be07ad06c2a60cb7a5791295e9c03f4ab96fd287097df52942352cc31c9ff50683ade3c0a4015216b28b0b695b2cb62010aa19dfaac2ad2231dce54aeaf75197db12c291568d5a9a8147280cd956d9d67f7bac1296025801f36eeae79a2f71065f01759f68b30d521333baa96a998dd1946f90380174450692fcbc0e56a31fa238cce178a8b50477831f0b203da58943af694caed2cd3b2a6f58ab3ada92cc5a1860e0f9845f5639a1f555a7d1045d5a07b428b5f2db893dd3a80936759b73642aca1ec7b1535eaa36dd695707b89a9062ca107178673ab34d31cca4944642babd3e79045d4bce48c8b7d46c522291a6e81330f1071258219b4245cd5e381686cab8a9e10120e625516c1299c184066a3bf60a1dc8535398c43a8deb7546000ece3a429003982940bef6870be1585c58423f419a042c30289c80b6f5624458ca8da2713c564282aaba77670c73be5c7bf0e58d1948beea9a97750a06bfe472d721bfa1e54b23a35cd5672b4e84677179579a29723d5003e7a44a8e691cdb015f4ad123d13a8da615a3f52763d334a6a07258ff127e15ab23b0f29e3b4061914b8349056d45f06886051d6ed5a6974bc4d38a7282b837f18082759530c20689f838831a937b7ee74d4ec64b57693c72a778dbf73ebaac041c4b846f78585a81971289bd51a3359035ab12222a3af7bbed6a64a856601af10efd0b23e3d06df7d243b04ca8c07a0e2d0b883c997d74fac67957469189a1ac592b83669f2f638e0976c373fa354045799824bfcf9c45cd408343239ed168b8e25b831d2c200be6303e93103a14549ca30d9f8a0e4b976870801d6bb50d2ef8914371414bfaa56e724582d14879634bea15ac530983a996a31fc9578d88cb242b63057802e7bab2cf2981fc2a9aea2cb173b873e1569a73356cef7476b9fc3a0b18cd978011dcd8b6e0b3c0769069dd94a6f39c940f6a5764d8671208271820c444d1c2ade4043677b1a9d7cc04871981838284c85850d416b7d2825ae95f79bb95f6262bea8a37e240bb02d6ca8fb03ef2d221ee818454222c4d4b998cf586d3434024b304b6ca68b478c773955f2933921e882f15c3ae726547f9a019de89b8335ca3e7f74fadb8ade6c061106c335e85311dd3208724381e28cf3636ba7f784da2718e857467e70a6682e5891473002e176adb848a96b26641e89463b488c616ba0cd4206583804ef8ad9ce3668129157077922bf00999b711af0973ae169ce7f81157d298fe033a7d547cd5b617cfb908a8db40cce2022578006549c05c594a8b13ec66bf000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 4cbe8e1ceb4f29a5a28a605625ff03b2ab4a82f81154af1731b0b930c6bb04af7bff3d7c2058c5788b389cd258851b6d3a17b9667d12a8fa61ba7c98b573dbc9cedc3e03a8f53b96214a4e1dd1d38f321d7e3851531246fcc1a2a1f937a101eace805aff3877438dee254bb7bb8b7ef71f2a202d36f532f2bb37f236021662f7eb0473be940f1b63f74276ac8c8fc8e92f805119e240b1df416dbb599a1a6055eef456d7ddc920fdf2277c6b72ed23e3b4b77d604974e7c10290214ed8aa9d592c2f0acee64a5a06ae2d95cca227c23e48abec08b22d9ee7ad35b0fa799b4b5f4cc0effada3f23fbf30a50ebef37ef6f30f6aeba700c6b8d10bf3141dc87e8c118d13bf23c9fcc8aa7473d2748d7dcd88fe5c2311d69ea29c6f5beac3b0d47fb5563b3c57277ec69e6fc2b91342e79b70d976c4359c00e0d08733701690dedd6f93a2fc751fcb020407d9d53ac454fcc8e0204da5e9e5e5f48cd7f3d787a95cb37e01f9bf9ee87e174e4367a0ce9f4aaae125a631d55e13e3cef3e6913f3203b9239a9ab31f297b6aeb5e0044d05fe3f620d3494a95b19bac5c782321651443716ee815ddb9bde2fd4cd0f274feb208dcf50e3a8f68971b69e847e21b948394bae8be37dfd645006a27aae0c4301a0801adf533e5229c6af3d9f9196e38869f68f71ecf720e837062e13ff754c72d101ee202b023c105765db30e5c51c06679b8cd504b83525a3e4a277eae5b2e6d59156cbe11df8792c3563c74076f93357917a1855943db2d68d89dfd53041143014142361d1617aedb76b1d536ba5b3ec8bd008e8d6e709565e02fb4eaca108623468071c9efd3de94d0a380f7b84788c7d17a5ff7b158531cd2fdd72181dd98f2c03aa872cb429e6f2f5474f27f6533d0a24f8a78178f280d9232e3215d89978ed0e0e00cb9b90ae09132bf14d9e0bb23e3f6c1a2d3139d912fe0b2dad2adf2a4a06f392db783167a332db072790324f9fffeafb3efa8547186ff8c198fd47fe91f0c2d513a91cbf36dff2ee65234b9ec53412f44c32d3bd856478507d293761cf61b9f9ab82a1c54d9952124069865b94258d29a2752a3c518f2c8407e022e66577281aa704fe6628282896ce6b7e8d642c7193f6cba50e8ac0b2ef48992649dc8180632a4f9b393b6ec5c0ff2ef5e33d5550c445ae9e60ffdf7adaf9375d3111c9d896d8a4673cb25ec0d05d2c8564137998e43f7dd51f7b7a438d1c09e02e6caf1aeeec2819ee801992b3326d45739263b66d5d7e483c6fc00bcf69b969421844a0042038907be2e853d965f26f3f5d543230cbcfcd7a5f3ddcaea581869cbac5828be28c4bf58c45f539e6681091f9a5699c9cab2f17f0862cf65454513977854339a81aad65fa1a631a4ac1d9275bbf46b11d8b62c9417bb2f5c30502665ebae8784f281cddb3dc0ce1e76d61f8420aee5419242dd5e09949d18d3fa1a81307b51b6b8a30473076e8041f46847b91278ce78bba4e7bdb2b1aecc7d3e3bf6c01e61ff59d9e1e9eb7ff7393d9005dd6 +expected_shared_secret = e572300d1bb28e65f38527a8007b312961b7c6cb204572fa0c7f53531c6c98f6 + +comment = Rho leads to non invertable matrix +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = f8111cd446cb2c44753cf29cacd39a7c9cc96af28545c40a6cc64f5974810ae45a97380302375de7c95b44318815776f80397c4608cbc22086e9fc06fed87c6c780ead85a8d5a82f0fc2ac28366f229566cfdcbd0c65ab3c112b70a908a85660547719e8304d513912a215acd011918cba5423e9094ccca3ef073832c3b81863242c864a90f1bd9e6359d9c72dbed85e76a926f6a84cc4a4839e5266aa9020f445ae1062b3751a438fec3dd862a8d7831db1c84fdb9102872b2c55b28e6f00623e2a971eb4982842392c10bc3e786a5ef5be5a69903728196c028a0ae20fa5921773f35c296770c8cc63a48844022a32e6d928ef042e0537876d3b276ad42ee7585b8dd38cfb58492e28488b0488330b935ee8701bf05372abbf4bdb1ab7da67367ccd8df4469c13355992a036d0a0eef51045a9b40ddc04c492c784a945e99c2a8ca52b99734e3116caaf2330ff4195bc2776ff8644d4d510f1d7cea4682b1533b4c567a1f0d052ce387237b92fd14246adf34ab4455f97f579d3e746bd97313ce10e4a331bdc8a1974481289000b39baacf9c757dcc357b2ab4756309849881289d66f7692a084dbc9b92b671ef115b979b26a8873480977ee621faf6b6a506b2fc2570ec44a9d5eda9d46f2437749367eda6af411ab661162ce8809e2c6999cf26ba5a37fcfc009f60b7dd857bfec86a3fe095df844388c31ab44c26b090c4afe58052a80bb39e614eca3c07e7871811b19b45224e7db6cd077aa4dd366b6755623453fd29b42af2732db855e0e829a9b51714f362b083bacc9e68eaa8507b0127b40227b9de014dcbb93b8db567343c1c1807d5f81b64031c364210531008976aa1daa866579aab9a6e1baa049624487cabf044c0e576902373ab2c0ce00f22a0bb61b38f98f4bbb5bb4018f6ff8a815d4338447bd133a610ebb10365276b2d0a473281c64e8c3677741a1a0c360a8797a3a4dfa06ca5bf50658600de1175822e27f187b6cf7198b8427750246b8db6653e448a16b21ab2e343ed4d55287341155a7b1b9d92cfadc26e138c3e784c03bcb6e36a1acd0e0ae04d78cef528b9636ab4fbbbdec0b7ec5e3c94c808f90646b7f833867b654fd9415d4b971e67920432103d00928f0f3af9274bbac2c5a7bd7cb27d2b1318b840b899257065026a576931735600698e2d49b136c641e080e034544325780fd683ded1caa11052fd89b5d18869f8a8024d4657e4870ced241974d2c8f6194886b509bacd5ad2ecb8cb2850bf55200d2226602a640e8812eb26a4cc0a960979ccdadc5b31d98cc59283df09a6c2d5b7f6ab703a6305709d10cd968826c6a019a264210c699030804db419c5ba4460b25510cb43e16e36eba7b74449612eb73662c79ba481816598045f601be5da995f02229d5d130f6688a57585c959c69cab00e462512e6129afc9bbc5845c9714a3cf14a1061b46139c79e02849b6114b80a75828cc946a5f00096a4a43d065ddd5897f3756d0bd208b4f8685d2a165442c132a74f78da6370422d0b01b812c009da680ae91ca0fc56bdfa36a32a6308c8eb32ccd23ed3eac3c9a029186a73c8d63e8fc92a5dd42905198405c76a2ad92f9a21a2b62b11e8831b4062425c62000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = fa75f5533fef3b994435bcbd3d2080030cf8b04d5773762f1ca6fbce54d86af4ec2f36fac7b3f249f4bc11cb376b23e70a7ebd39da39d9377ee63a7c02105ff9538d6752482378b4140266f13faf8c7ee695dad10b590b40ed5627ac417e8399dd398cd7413587f7d5c530801c6c3d7a33838cd42ab4d4d47d263f4e1366c539319faa0bbe179e069a4880f928f7f5107298b1bc2bf75e6f9d135cd9c96e8fd1483e3f9211bb73fbb5623b9ce1154cbe01797b4d69b9940c20d4fc5b1d1e103a9fde78aa11310e9ec3cf57bc2f41e3296c42991e03b19938e2c57efe6579c192b66077b4da4a7bffb383d23d7315ee81794f2c4f74c4349904190a73eeb1eebe03ea314f708f9f103b2862f8a4a05aa8aaef91818e6deba42b60a9957e5261e01f7c68efca04eb61fa7ff86996b69a2d7e293a6407004bebe90bb481daf560e446338ed6ba259e1d0910ceed2afc7dbb520629e8cd92f1759803bf0a598ae25254f054c4551009f9f331d24c9e443b3942ce662b28c5dd5a6f082ed5aa2725ac7a9e3abc6e57d9d8603052015944ee9d6d55198a5fa9d9fd953ab5afb63eed2e0e6d01983a8e2dc19708c404ce6a7092f2761b8dfad19e0d4dc657827756a99932c88643c6e3adb0d272b9cd877079754fcc2e60c5f222d7c751914621873edd16289370e246bf6e63ca7442b54f7d6198c99deb20e635367fb3c187063713d4a6059ce5623fd8203a73b62c2476605107a64efa177e435b5c7bf6b7c36627e1192a00d6d376612bef6560acfc270257ea0b561af6c2e4738207d60197dc1126c89ad7416e45af6022b227f9e1c4beedd248c8fff802675e21b15f06c3aec36400515c4bb9f4ad2e878ba4eba2658c66f4f38cdb2c73e71de1796290133857e90965bd334628eb83ac769cf63fa9a59298d089302cec86c2d10aa03c6d620a1e735176665435479ccae37a168a0827d7f4d8070d98065ad0bcde435c9e9e9d75e71ad0e40d061a2dbb2a3262e18704649a14310e545e8ce93be3b33fc442d437acaa3b5bda4f770f5eb60f56b0fbd0e9a4820f3c464cb900be522928d9a3a29573b07884e19da158b317fcdf047a2307d0066f16a3a4e389f0166650937ff1df8c4e637e24e2d50f4d2b731e7befab3b0c33ab81b4b031174a61be15d992315464f99d292696bb1536ddab0195a140beb68e72eddca6220d01d4fbc77ef3d743ac1dbe06450614d9255f13e60417624dde40a25515f19b52750c1fabcd7f128b472d80337c469cb8ff95bbd2875ed03efe8df9aeb677146002c138edb668a22c1e1b671cdf636a725de9bfa9c0e12035939c8136b8da4792eda4e82f29d33bf3f67954863eb993e51344ffc4d144d651219de292bef3f3763e2aa061264b11016b6bd4586f46215eee237b8b616a260071004e253c7e1424d01c4b71bf53e085f93c6917a028e6f5134e2c04bc8d9a371083180c3d95a709bf56f79dae2be4b1df4db2fa14b075ca14d0cc7875fee90f8ad2ef73fd4bbfa3422475bd9a7b8195 +expected_shared_secret = 0749d8808bf77c517e622f26abcf23f7c40144b37bab16c6605ef1c97636689c + +comment = Rho leads to non invertable matrix +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = a86b5b613c6c4c869dd552a711040a0a205a6a9b7ee5c7607825a76206b3db25aa6a0960da259ec279960a5a947106b51a299792707447856085a12397e60cbf91713a6c4bc56b03531081b0b38b0866718c53bea1220f3e5c3a59c74f10c765148c595becb9aaf0ccf2e429575889b462bd59678f860a5e501aa758674d22842cf65a3f8dbbaa7da061c54073a92cbed742163df301e3675c5ad96b26b12651fc9507b7361a8bc0cdc47e7f38c1ad80456ac3443bab147e86924ec112adfc9f1c1b81b478740b752d030537c817a727451668d9ba1fe092d5e116c20262b722b6f895b78e3622c00596ac8b5d4ec11b0413635e85637ecb9a87516cb8c46ef2aaa6fdab62860160c4b29e23f921ed3a381711540cfa5df115a700d40c38b99efb870c6ed14f2261b17ac21900a427528cbff423b0ecf29c2a901baa9c7ae3d438c145385c73b0961c4e9dd5cb48c2ba247a30b9691dd8fac963a5c46ea44de03274896c8f36e57f84dba494c473af0a64d97533b223a32f8078d933bc6db125c2e7a779e0676e09648cf6b85c2968b71146763b7082ca2fec33884d6704afa71f5723617f83737cebae33b95be2393cf1f104c093b4caf26548704490b4aff5d6175ee4c7a3c0718436bf996003039aaaeeb18e92e341938b7a71609082b18995aa042e628f18e8c6f67b67770597772259e0e7b1025c29ea809beb994483a6863d038f6b9bb814a5215d299ad0b0b577d70e7c946be6c93ee257c68b1653ded84761b3a6104814a265988bea5a6ae96951f1bef6f53f50aa78c1f655dec149706ccc561a846d9cac61a339c3c279a290829f972a1931ab5ddc4893f71127d1a96796a24152a5d56016bb5c9d483b9b4346a8550784a828a3b53573e61104b6392d0bb246b8116d8f78021bd012c322c8b0d8392677afb40b36e49c0211449a2bd841e44b72b25b11cd099bf4ca292af2722dd9ca2ad3c36f4377ee54986b737a6a0b87817384ae9964244b140689b2d2db0deaccbe9f63b182164b89c932bdb22e6127303044b91eb76572e19785747e6da01c20318bc8092a7dea7ecfcb638e0584a6e00ccf243e06c577b784704c3b448e22a2b2c9c1dc0224c7ca798567b1c5f3a7ba660af4028387f2c573a52a28a3449c26342f214923e3932f3bbac2819329b83a2e89b78d93afc3c134be3c5fb8c67617666c22c71c4cb99063898f65b41117893785f376d2330b3b5a2fa946374f8a1a2eca1645d255c2a28fc8d7734fa10c67979e5950a1b5e085e2d52763326f3dea8b783297d509333947b9a47a9ce9caa0fff56637a54ffa6a00ed942e0d382ac6c834a7e40859f58d3ae991a9e359e91530bdb75c5568330236149e71040dd9219f5c24cf35c4e6a670e0719b2e738969f509cc55bfb6ca08c68c28165bbc43598ebd9744a18820b5947f0b41a311846588187c0aa669843bc6f4620cd1c62f1aaa90f93b7537828b42f59c153b9ebcc9ae1168b2ee7b2f10c062bdd49259024f4fd51c8994acd60478cd3a00593c403a3279877801d3c88f65b7bd83b76fb54c49bdc8af3cb4b2717741bce1bad123cd062211e74782f4620e9130a9950423afdc98cf0519a643a265e4c6ba4142557d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 0d6a627804b6e54c49e39e098b20c978cfdda91acd2d5d883111b0fe855460e981f041682f419dee54cf5b7f923c2017b1012f0b3233d507ed065e96ba51f92f70a38aff0ce071110bb0513b22262aac6ffc1287c63c07f312ca2310293a56e85e429bcf3b8662426c086f388312513825888762fb3aa87a40653de37f48870ae16c19ec088bba8911e944b41a8cd595e2fbb680971981b5352a9032b28fd3bdd63ea4a72b5d999d6fad88e19aa84e5d60f173283f7597b682f4616bcf532ae1cd5e9e5e231c6bcb1c9d5fd0e50d54c53ec8a4f1162696aa72c02a6fc97e80686886b84899a7ad7a1ff6468031dc403dfabdcd793bc31a3036d5937f5af337f806001f4ee79dd889e72f5585636205a3a906c01588150d73571ffaffb9775970af6c98a17f1a6a6a0161de795ee20fdfae34fe40e4423012dcb1cb918144225716dc32c6d9d453a148f3a5999b6df6748a97429ab5b8c6007f2595b47fb52030ffaf99735f22657fa8e93f31238941436b76088a72dc6a133f96f0461eab8ad3361f59d4539090c2dd4b05ef665786de899af3582a8a41400b0421c6c646050171f6c2c8231e7fd295f855d2236f6b17f36cd998b47542ad2a73c1751883175a71ad2695b7b372b71ac8cbc2729ab1f4b76eeb8187777404ff81e46aa3a246cb0c9dd3b7fcc443f6a89df493b64e770aa8507253aebc041587b3b9e365688138518d2e84b635c045c9f7e50e62fedc9a42344bece5e21e05c52baee9da1e5fd50ed674aa83845343894439da9188a149b04d7110900fd3a6bd950be022cdf91e6bc896125a10e64ca3e55785aa5ee668e42f338abf50690c61cf19481b1162cfac86b4f8b8800e3c65e82e94e987e37986a3669e401f199021a98294018a602801c07b51faa641a34183ae5a101189887189f072943a712f74b3710a98ec0a992ae4ad1d4d56a508ea3d0762d1b004f399261f2fd836b97740f4d96e3a939ec8854b711ee358425943d218f92a7e07799215ea2e4e097448f7d75e79850560fff7695c4b3f1266f60c430b602db4cd75983e3e252c541f5d39cd15253441f76534cfa94017f1801797503b9d1518fe4857a27e79c842cd3909eca55ec46d9652ff448ae113134c7d24a506987875e9aa17841c9453ff951aee63372957333e8af8ad72ca7e8bff5e0372209fd0bf11881475d0900c643b42b911ed8da750f4d0afa53d13c749bedd5c69a006dfe44a736a44232de96075b6db454644ed3403bde16116a670d7e6c60e03e25a72711ba7b17e5b65bb8af376eb71df16f7d48af1a903bb6eeb599d8acd74d7990053b39d4c81887411927689e20b51006a582fa0c0416299c850e75a81fea3f4dd3d3985087fa7b5f163827c89c2737a86bbdfebc4240c166acd4fefdda881f76be78a079295033b10b5e2bbd9590e3354d86c2532e43b9d1ad7c66766d2faf2877eb0ad087fe52fa1ea1a0d5661872735badad7ee15754168059d5f527c6b188e6dcee930e09718f6551da8475df376ece9e890 +expected_shared_secret = 951e3d8eecad130865f9f89c27c36ea8d091b6f3c00e35969f92bfc4f91d657f + +comment = Rho leads to non invertable matrix +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = f486c7d6766d95f2b7296a07c8c7b767c1057548a18263a4366040c003c50084bddd31af425b261083ccaac26948ba1882739732bcc1e73685b52287148526bdfc47d8822d1d5853c9447b21f200592937b9229b471646beca2cca630502e167b7c861d03cbe302600c6e1806f6040cbe518e15c0eec4395ec1a47c44c8456830709a3be9d05cc5cb3266f616f9f8a7adf9b2a04bb623f801da0c8c0cb4b45c16282c412c24ab90c7471b554057b6c0623481a46a0aa53dc167c15ea8a723c81d9d56691b060bf00554548c34f1c603b17b705a72b2c3091ac134d192806635385a5ec9cd28a3bb56b83cd2b153e00b66eb58d8580a47e696aba9abd36b19b3cd47a0dc4ca2d6b7ef106a3b94b349c665b295433f4ab8711a01e2de8295d58b20eb2ca49c23d595c96c874a2749087dafc044c0b8bd5b340ffd12fec07640099753d4c993fc69d986210dbeb95bab40f6ca0096ea866ef216c6b2657600813052886452c130e7c925940564918a5266531af820d0e69c10471ab3b74585f2cbaa1b27274589fea64b2172b4020b4619b6953a9d56d022c7bf937650ee5608b15988b3377bbb617c4016c1ea3a7afcb9665d995eebc2b0ce76c38a0b6bdf9436ad78bb97852ffe8a618f3c82dc4afd81c99a9512777094b12564ce1a469cb49045a90aa3d2c20fdabbc5bb4940d30360f17a66d58b7a3ba7920c102ccf8b30f03621ef722776b2fba0164b3426d514104a6689286649862b7cbd84011008ba69c6148201b576a7b4b58a53035946a0af9646251b8c1cc7bc4c058ed8bbc53c91ef74cc06e1c32a211ac42570b7a7181f23552c762118a9c0f4862687a502c232b9d43224f5fab525f6186332969b246082c44cae7236e38865e4dbbcba87c12e90b2b970097c0e307dda00d7cb98574915a03d25384d4584611c837e19ca906a80868b382940d909091527b0bf261be5ac0a9ea151b8979ae46f2453b420d5b6b1fe02605fb8bba1e065bb9506e1be7c471a9b8083734a110aa6aeb8340338b14aa71189cca4ff01777e7a251b7a0cd1cba9a9a7b9ff3953fd9c87f5b043f719f692a9f4c7352a0756393e50f0592cac59bc21e198729f23b4500d0e620bd02222a88c5688ac02809315cce210db4169fdd1312c0dc85baa25f3d48ceab80754987553fcc7806827441b590cf9a8d5c590b2e00bdbc9b4ac3d2883f6cbf9e047407858b99ab6577a66b498b0f18628d16a389a5f5a20e1b0ffc228eef287a36968ed913b8fd74a34de23ede7743da2311fd10c46eeb84c38986bca7536ae8a3a42acbe5dcb3fe9432bdab1f3d1226a99148d01219f3e68f68d7a689e39d7502b6e13b665cf0235af1489bf4ce8619624eb4509c7639ec411fa223793b4cbbc990256b390fe23a2624977477428ec39835809343023c1dfefba3aef98e7aa15ae694861ad54e0c74a6d8122ab181c9d23397902c99b0dbaf78a463682294a2eacc1cd36c8fc1ad2e282a72fba0bc179520ba2b410acc977b9f2cdba3213175204568dc249571c20fee0874fec364eaf210ad31b6018c2d841269bdc95ce753cf6a765af4bb9deba17253985277f71d2563a585a7573d31c87b80913c0a38d3905a41de6fdc47000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 068bcf0833a0a08f1a1c9128e6575a62ed3f2e075c4444f2b4584b18e4af26b4e84f16b697141c2b000847dc2916b8718608465198935e67d873335d065b994e2946244d3d739b1d31ee6b8d54c5bb04fc9d7d6d22496a869e5331d5e293a712408207fabc35004b13d3ee3aca54200182249642c5e9de88bf5a489cdfe6330170c0b2cbae18f65043ee306db39d333344c37fa76ab05675568a5dc576290abac1d6f28f6ee1d800a3c638b91cd40cb02e531c88c0a3328a176f872386082f07b4a782f79d0b2cb2df14a62e3db5a30fc753f25db235588652c51b251685ffc1090ffff37671384482d4ad055f0d51a5f00c1c14e67824a29ff8910d9e9295f633b6e8dccaebb2da47cb628a246c6a443b87981453e4ec64e7d0df499f026977b039f73d5edb354bdb536896f35a5431ffed50861551f5e6114da8782d3e1530858e516fb623dc3c0bea0c8981bd3091af72555ea18ba409bfe2419a60d769999d82f7bf588be754496143ef980a3995daa51e370984e212f41681fcf6f1235871389fd3b52e76537b84af594f5405fdfab1d90c79a302c142f88affab1f4d524a139ca894cad46f270270f2d8024d06582492fd1502a65e7b70ba0941dd957808206ce00c6be60d8fedeaaa0149f17ff0b3b775fe59317e769024c91ec83a191cd72481e3d90361a4dbf59968a33a56ecde8aa618a8046e0c021c6954f983b489bba80d15decb9955e118899d98c1df865355f5b9ffd97c52c097474704088cd2dcc01f303ec675d87938d21cacba1fed2483e144bd6bdfaf5a9a233238313489e1aadb82a060390adbbedc55050ff86f967b4b7aefa563117556c4ca5ce9ec3db571b5d2c9f5fef63e731c86b0ef3d84239641fb082063ee3c3756006b306754124f9b964dfffe718c72b93999255fdb3c4eea7907a8bfb5936801e799d499269226df5d9d3232b5bd5dba5c2ad9b03826b961535044dba6640b7da63a9f639a834f7311e7d9ec4a1591d041de4f080416acce59b2f1fa4f4a7654368761bf1025a2de5f02cfbc2150685f3e457aea26ba25ad3b828f9dc07d33a55450a0f0c6fc3898dfdd7a43488ff012cca26828e5a1dc5a0d605c59afcca1cb0c76b3c20524eecca2ba2afc939204bf06adf3a5c0a809641cd83bc1c5991c9d16696a4e4e6462ede7953d2694ec9ce865523b1faa9ec4b8d5f737ab31bd929c45ad6292a6926e1c62c7d48cbdc6c6e30f289a539feeaf84cdaf23330c37c97de3ba6dae06b737e2a51faaf0363a961cec9aadb8c74779e242572fece99801eeacb7e972931da610b75a3ab2f7803b8f3b9460f1ad39385e9bd1fde1b46b676132f5590c6cefad5450de5c52087f7f5dc79ae1ea8491dfb8b2d205361eecd231f3af8d95a12da4ece84d6985325f4d948eccfd42fca19014e7af568175879101da556d615b3f4d81e0a4878bb32ae24eb4fa91334b214b379f6deeeeca45a89ac0d16d533707ea5e4b5e0c06be84656e5475c4257eeaa3353d4444cb88e499ce7f5a2cb2 +expected_shared_secret = 5a7f85e2ae8e79a1b178cfb5f38cdf9e240b9997584fe9c432fd63607139f08e + +comment = Rho leads to non invertable matrix +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 029b98bddb329742ad26390f48a7c0f624c336e5b71727a4cc29c06e1a2968d864e131b79e5365dce048453ca51bd8718427a35c63ab784ac5476627ced945b656adc438a5294800b6b62f62320adf193b198998a845954a2488e0ca4154a442b0012d44b7b24fa5a6f03a8efb739ccac77b8b54cd235ac65773223f3709d0cb8195671f9ed7b324a11d920332d41c9ae0c0c30279721c80c3a2423cddac9311cbb39f7512d8859074558942504d9c087d9524bb21f5cad2826688e5bb86b91c1f120da1808a654348fd3ba11f3b20bc7612950c392dc27cf6a4aea8f47b841645d4860cba4b3a865c46c0f259af1a60c43141f548308088353617bf95427fa094389a3a6d2df6ccafc7384efa1cb0ba2ae5a2a8d89335d1eca833ea026f9a08c9e2586239aff1845fc5fb6472d0056770a0cae059d81812b8c679c502b3527ab21c9b142f89bc4092cca0a6c20bd1a22c29b773b2aca72ab0a9922d85a8bd676267e9d6452235c270698c5a7a13a1640e5d20c1abc844493ca3634c1ca0813e7f73532388c1e059c414c24bfef16654850f9673afecf630fff9c3aa0a56fab46eb5cb436f4ba94f046e5d57a2d1897680631128c42dca353861a7aceb79267a48b429539f51475414c66bc66a1e8155435df18ccc2993d5e93642354921e9b2205a6270e34b4622c9c69915ba80c9ff994263a11c46a95b8f5c43de1c5221b0745fd2ac0ad5696e5323935a688c906aa2050f89881d3d21605c9564997b66c6452e333cc33ca839db53c17192796e9213b0d7a2ed796e7b2842d9aac2398c3ad11abb5cd342eaa2c6468b70130a5b8b2aadfdf08a2c39732708842ec03d62f60c59b28b81f726f078a06df43faeac927d8c52d14664bde5200bb55cfb06478ffa9b62db67f07565a5673393a388ddca18b7d7978f338d93f37d24a38ef8786e3ed14109421e5884c18da611cb7b62d745323611ade1527fd841a4f3e7122bec4c81609be78b1e1aa274b06193a9291bfcd88ad0fcb90c69c2d4b4073f89a733729d3adc79ad93138b8116fc05b07d7ac6d1645e3a7ca15569b1fe923115133892279f2da7be3f96a3a4417d3b929fb4d842ac017368bb461dd4673da34583f71dd89963718a487db15dba89b26f57b5843804f4f77467936157a504bf106fffe93b82a5be0396161be988c415666b1a26823755274310b8c07d2db27b4e0a7f62747b37527b4b3c87c758603adc3b240a359639634480834de99a6efb12cee23625d563cf969adafba20feb785ba71a5278cbe18a112c673e3332575fe982c6fc853ba675a610357dd2275aa0c6ebf3b5a66a38d253b13b8a21170647c28a7397498d9473c463b7b4762939af5a8dac0066e9f14b8e7534c21342d4c7cf4b539d766a350d882b70c29bcde61f854aa75d427a84780220278716eb8ee1698fd5825cf206a0797552e2f18d3ad062d283719dd61d160681d685ac3004c0c9802d78ba41e8404436d8563de6174e911ebb16a4ffe945034932f335467b250bd95b1d80966aceba882f2858e2011f9be167e6e3c70b234da466a28f8140c9581a9755b5216882f0d43bb70751ffa702eebc7dbf12450cfa3b542777c35b96077cc1cc2c5fa7ab000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 9d12c628e857d6fd5a1932a879dcd28bff777cd6132e14fa17480771b09c7f325a9127f610aae2bacacf515132f848a943bd40e75b894d37b55018284ddc5899431636325a5e86a79222196fee72545b368cc998059b0d88587ccef6e6eb833d05e08123f9b18c13ce6d456f4995340e17a26a9c3eb97930dd207d5155fca9a160e5e8c3f8b7259637721391d9f0787a34af39b136f306400b4805befbbeac25eeb533678b6994fe71ff8691c85bb2cfaea77efbd0299415a4adbf6cff3f4e63cced78154525b5b3d21cc838a5c89f42a1f7c2e2847c8cdca0351c47c1a6fd3e0b20d2d24989b931e1bf6f9e3d015a1fd3deb195a959a44f87b168976b71ec5096a92c0708d96ce00930abd77f4dd101c64106671656f668a07934c89353ce8b27e76007c7d7aa159939210295ad05377625b6dff8744332b834382df6ea2254d523f415928831a46077488f925dea5bbbe4ce007852ea26353de810a78d79be4da1fa41546739b74ae5153d692b14693ede93e2e5248a9244a35a7b64acf95290d1547d6e4e1d63c653a0e52c83264d7349d209147c97c9971957336f036c7195aab3e80afb7189542c45194024e349ab7f62c9cb2983e238a8c76f4c5ad6dd07516d29fec6f38579abcabd1c04005c4106b22c45d27b7786575b15ba00be22d752d6dc7e689aeb21ba9980c63476e742b1f780e6f9e220ab09a5952126ab01a59277a52ba8159d3f25dac39df888ba0e920cea9cf8d40525f79f74766f62bfa2478afaee5240f30a106fde661789d15780bdfe17e15cc033e179735f1de3aa82089dbfcc9df71253bcbc99cec3c5cf163abdba2b8a37e8321666ebf0639e9b240a3fd1cdffd249b8e0f04228ba21b777b8cc76c1942656ae9ff36410564a9d776b82f1e61728e71fd88c1077fa74d08bc2d5cf59b82163e122bceb5b05f6bc493ee02b111af667fa67bd0f7464d8738d6e1b47b282e83f3d83b1ed5c32e1534407c6976e280fafca2dc950597dea6efc162139cfd2bdb5379ddaf6c2d2ce876801bf5dc8ace9bb766be0452105861e99534f84512ecb98ddaa2bd2938e371385deb1623a13900eb624f734cad7047790251bffe4af673e7caa5595138b8dcf15bbea0acfb745cf84e98053ed593fc1103e80fc4ccbdea7cd3049c43dc46a21d68bf194a101767570d6ecf7ce087dd34a526673b6b959a9dd83e809ffe8984d5d86fa9c23c0a47ef11359283ebae3a1c5e6cd9f61a73a2a875d0d8fa1a801d31826ffbe79179c9b32f1ecae0097350b44918242aadc9ecab9bbd1e889a113d9cf1454163317684e0a99318d66f6435e373eec3ad87789afb0f7dae49d2b03610b5db9788e2b3e0c96474baee4bfc166d3f5580c7654ed4b19c325503898b38eb24aa30e4496eceea05954780dd389939b87a4eaefaf86ce855d1d1708660add4c70d30f7d14262aec22a294987b2b850390b799c67ed354bedbb86bb8c1a69e38313d4d52ed2619b3c482f2e16153263b3e6b7863d8cff75fbe549ec30da553 +expected_shared_secret = 5e36034b55f986e8e39485c2de5de7f5bc816322c6f36ce00b8ef8d7513edecc + +comment = Rho leads to non invertable matrix +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = c30b1c077bcd1dd852cdb9736289bb441013f7132a86664c31990bf601cffb845d39a9a95f4b44e285c537cca542335e77b8ca7ac4037c56822d524f74b76f2a113693a63400334967f9a29008ad53f01921499e54e8c315b47788aacdaae2269957010f4652c48a19cea9b2a32406b4ab4128e150beb10e0811b2aed3c95c89639a0ba3ecb689a911acc463708b733d3b724c63b100f62c1863c2771cf7c6aa215e5848687546446c75a1b3d56d8f07b3a8f8bf79dcc360010fc833056d04a80132816a63122c591cae5a4c26ec119a7cccf7f74db33c8a83c379f8f3cc75e85a8016529157aeaeab503e7b9734c8801c309ac580b792433f46451c8bcc0fab6a9ce7b0a2110a933d62cc55f953a036b3bcd3a9078c01b16bb6f78c9f14aac2949617bd6c0a99f003ed2bca0a3690ad444d314a1c44f1638db6c31a3884823a92a28aa3eb498452895733d97aba3c3c7d26139843adea69b3730451fe75aa74f6a1dc87988012318cb172b37843bf1385bb400018416344a4c61ed9436e142d9a512d63693c46f47e2581a97349bbe6f463e5ec806f2bbe56025932eaae009591ec6260c83202b4574f6274414e998d2999371d39855d7b52544558a0da3456191950f96f0995313bd06ac4371207f606781870244b3994ac91a0030b9b26072e121322c7b3a7723527340606c9657007b70700739b278da9a14759024537aabff70bbad9bc513e5809677bb170d8886b2176b9999fcfd5c5e260475d315445d9a6a53b8c7e5919fbb6209d2112074243c16c783fdc571dc842eae4379378827721030cf601b92a5f06aa877b8070e0b3a44762786645cca13c8e5c84a5010290459a3637d7c240cb8b1cf0c58a649c1b33cbd0c62636707d321cc93960a42807a8a4fa9f7c889a4c6ba672b14206926849257bead619167c8cc7c466186821bbb8c67618c6c0d9064e71519902280534623bac0af20259304a46b0352f0b62707d7645b1ba5817e41079893b1ac00fb14480bce6bc19b337a05cc79e96ca15dc7686b33e2e85146224b96266c8164b4f17ba6c3070960ce26630fc454cb25b51e935c507afed34b029838822a0a77a24bf45e9b9047627dfec040e648738e05a62fbc972e4c1b4218300221ce3dbb3db904e82bab6f207743422b453f728084501ae7b96c26534913568edb18446c409613b3ee4f52af5b466c9ea7af349bdc5eccfe9a510f6fc24226687a9e19f6a925b8653209fe4a932588cd52bc41e48404e369394385d87a5b28b80b971836e3c8929547a6e002d5f26dc4417f0850c44ca3905708aa40556b426b6700d4e9126b8ac7081d291fd7569f0b08f789b8556864483ab668fb781db2837e73c20891928e1eb3d29f7a9a294641696a1fac1c4bd526e1fc73c78c01ceacc4a5b707262307f8aa28f61642d71d4aefd205a5bd414150188fd679636ba5fdb21740fe3738c5bca69ba72d1f0871244b0fd430605253499d351fc102280987956e287bfe40daa05a6d6179ddc75aebe5076f18a676ee71658283752ba79a2457fbb107c1f7b7540513df0119b40fa2342b64b2aeaa21c94905a5c68f222c84ea63e9c0b0afc55bc605a46a8179edcf8882ac203302879a33b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = bb7e0dca6eca3ef57e945d921c2f80875556f7786d6bcca1312f86b3bea6d0f0a73f7d6036a7c38c62d4e356961ec6a28d8026a2d915d9721ef815147fc09ca65a3394aa5dc14c08d41cbe932337b9a531ddf68df20b6aea297194ac398f15919830e3ee6c20145c0aae7a2cd276ccad7b5c414212f0c0ae7106333868938a6a00da19377d996c7796d400606007dff30fe554a5fef86944d43ba047a00da5c2c2a1aad053aeafcc75a1e826a417b4c320e60a68e63dd7b54827f5b8b0063a00043f29ce8975d95bd418eb2ed29db0d9263c67fdcc153ba9b5a33279becb7ab193c2f257bd660fd7012712be3fdc2e52490ade145e8e030ba1ee5368791e6f3efe00deb34cb454cbf7fdae3a507261d9fce66ab58998ca19380187e3455d425977a8396cee3442935e24347aed45fba9b323a289f1b98691e35017ecfd7a423cd8d0149432a2063e0786c2f912e1134ebed188511c905a1a9890cd55d496e8441ccf637b4d660d93c7a46c3e17219167c3b4740878ae35766470b5eff3c6b1fc8c30e5c9645a94ebd48d2d40fbd4baf9d822deb26c089da84043340a564e6c311bca18c7a2c868831fbb866d89652556b53297b9c0040e98a692fa536af4c9a7aa09321ca27068ca66c665b1121ee4529cb3e6d899964de759ab915b0d2c571c5aa76cd64df4a4e55d9de59eca7b4379b30f8559db41e804a18b8771f594b9bee3de9ae98a003430aac58c141e6f0b7b1e5e08e27d1127b682882be055ba31e280dbace7878ae60426626ea4c5bc034a9206e27f578edd17fa6c33180b649bc7bd437b2c86ef4e0f4583071f99090b95db1e415d21ddd88a910b1fd10e3a04e391d947558a6619683ae070be04cab88300614839503f088e2f04cc4a7d091af9833a4f957cfdc574b1c994673ea14dce6ad89adebf5130d266c1440b3f544eea380ba245e21651f1f2aeb2b3d578000a87683dec69ccac18b0702d3d030077981076766e7e5f3ae1174eaf21bf03662c6bda5fd209da19ff6792c0bbc5d210851061dcdd2e4794d2c3c0c531e92a2c4a23556878d3e890b65289a6a02530bbd40ed66db3bb220aeb71fcc3c0b5d5b3afc71377746b22ce636dba028bc052c219783d468fac1d4eed555c1b4676705c8d27aa8a09c6fd8640a6f7b6790ff173ac39b5f3c709281df4274cccdc1e3b690ac0a77f7ece34cdf3216d2b6058baf5f649ff5036360dff99334ff06a366785c0404c584f623801190082fe5cdf88f9cf41032681e8fd6b84d127add01d4b2286af648b83fe69aa8d109c9320bd40621cf75adff8603e3da00be36f03ed7925f19b2e913d756e952a9402cd4fbffc0428cd7eebdd7fc7d3b4cde181b16b26811cd53d9f5d85d37c1670b957d4b3d04fd06567ac68d3f9dbdd45d182619180cf9292e86f42bcc213e94900e0c759e051bc0e30ffbdb91a2493913dc8b81ba4c3e8ba0e7277dc38dc91eb2b27823dac71b6f1c47e2a04136e2c0474fe070e2e4bf8e6fc98e73143ead3c5f778ce8a4efde4 +expected_shared_secret = 5b357f714a293b6724c0dc2e2c5509676782a9dddb050d88e6efa0a6d09d20b7 + +comment = Rho leads to a matrix with unusally large entries +entropy = adf510dc0e997af14f96e4863f316475be59850bc861ca0d1b057d6b94c3b5d6 +public_key = d7dab73b47cd1ca43c7e036d41c94f8f31a0de404fa38a1da0992933d752acc0407234883488a581e340bf5a8dd7112099259ebfdb0cb094c8d592485f25729e1844870a3d57d63fe9c1295fc2c4a374508f359a7e9b062348c6c807322f1a2dc887a20ff1b8e951b103698492504dd86babc01339f5b0c9bdb01b65514c8df3a61abb7941da84b8005648fa0e5b094e54e56a56e8c840371349820dc3f48ef0fa488f180f57b5c0ad663512467836d6765f6517ebd0172d886430357baec25c709b3abb9c01dda27e2ac7c17cac7511726a39050fe92399e14780e3288ae775612b2c4baaa032af561d0356c43175c6263c5d9cbc62f57194c9f76fb5293e86d9a95a641325013dee98067d513525eb5d2f7cb5783915d0917faee635bcdab95a61592fdb1de202c439dba37a235e3888134249044519732701111385b9c91c2fc96b039d6483c6d1bba2223cb0f612c3f7c6dc62bf64a04b349a0fab73290acbb15ce1cfaa15c68d896493e67dd9a518782b35fe141a4d70bf33e97a616c51193b711b04a40c9634bb62726f748572155667146d311016880c670067c653e9a8dc0bc32865adbf41ba99f19b2dd9ac7998bfc8679c689a05a5038042885742a68ef84c429984588995a6cee077c3a099caa7a5d3761cb4411d1dab8fe7258c75903ef515b6b0629ff659436ff687e6625d2080671e0cbe0cb624bf8b367e780452ea3713804e083aa6e0c7adc15618cf223b3587a364320d56c58be8f037f89cae0be209ded78cbae29ed73767ede6793f0051cd5692f63661a257ccd9d859a92ac08784070bfa7ede4577e7ab1ff6c7b159089b8dbcc5ba56357b2659a7a04c8748a86991b2b775c2015a4c12341ebb419e1244396c233c161495366104b8e29979e571c9614fe10c868db56cd934c5b2d04986a70be8dc25d61cb6f0054d5e4000ef72557b712658d962b1e673a07222d59bcbc4e8339bb5b37cc1c2bbd38780f8233843ad420782b4951c3321888fc3b488897c8bab046f79cc456bba9f666ba261284a1285bf1a9a9d274d9b87788c225c0ffa20388183f35817e5825d450a1eee881f94a5a129e688ce6664021356580190a3ec5ed220b8a5878068ec5cd485816f8c1ee05c3c23ec0d0aab7f73aac249142d8992678b38410d41be710a285d3b593a8245e514a870c3c348fa45f99aacc464b399ecc0cb3c306c273e5f4c671b806864120a88c07caa53a550d52c5641203a7927b40631e21344a9337da2d128dbbb5f97b68b8e57cfbb1a67ca7741c60c2533e49ece409b0492a2e81523e6b6ad655a6dd1870b5de3690de3369c898b557886c4877ad1d67a1583bc70502b32a44afb9b60f88838eae005e2703ca26355ddc479bdf1a93756af16b7789a3221fed9a4e468b710035060752e884c56034b768d0a7106a4bebde7622bb46b6649195301192c498bb555c653c42f6d84883be82e8fa56ea303caac534014b6bbf38a9f73283e5a40b36e36c9d8b1a9856aa7d9913b22c40cb103b74853c53c3ab4ce895388aca8584449fae927b16534f48b3aaf350030a8460c8572bcc527f1f62bf1c5a9bb8ccf3ee66f66dc19286782911a6765c72db77ac0e976a2bc114a1b11000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 1a2dd390e05984bfc0f55ef96da5050fd9bb03891d4d2ddea46c463aab28fdfaf63d4b2e0c9af992e4f1421efc26ae86c2b296f6851bbe2e898b8bdf4057e875d4a98469b7d2646edb86a5eb5259341e0d14986a8ccf93563bc6ac067f8ff6997c2e7bbd897f02e844f180769fec5af9d6fa017022cb0af622b6e4f7a69d73ab01d3d09067b118d51805e1b6413b7a9e0ef292a6fca18a8828912a2db675f0244cd63d9340aa3ca00dc5d70c915b0061664b1e1d64d3d4dced3ef739302f1063442569efed0dfbe8c019c27823a3aabd865a47600ff9e24f748302bfca1bb60faf4105889a548be9ecaf266d8f02d3aa4997202477a70ee71b6e79dd1609acb4dabab72a38448758d8debf55369c5d3e0870ca193018e0ae6d0ffa33b93e962598b43e89d5978a9d55a608b98ceae5e897363f8a9e253acf8af560c57e07c4c4bde807620b6deb76d581bf92b7f514509446f5c4e4d09430b1855e62854988302c931b9e624644a636ab8acaec56d7673b26852c692e8325fa1b6215f24ebfb388ad1022fedc0bef272c87e10dca97df1e63f1a0e9582daae0f49e30c6acd119f7c4eef59d47443f491df846431cfbd23900341086a304589f52de1d862c26af32095e922b92650c68facfc13892430d428f626fba00cf9501e1e4646e55f5304c806b5acafe100084d7635702139725561522632e7e3871effe883298a7264a411484cdef78f9e721c0e5f3937f2fb7d40bb91620e473f9b97adddea69b3ac682e8aea2513b985fbae268176c1bff90e401a31e729fe8b76d13b5c8c85ed833d9b076b5e11acecbf0e96edcf8ff562255124edbeb5b9117cf486f30d7883aa353b9e433a77ac6912cc8e5093c12385ad926be1d0893afc7e64fb9ec55d3285e01a3ca63f3c07b95399bb4411c3f820f53d8350d1979ee9cc6bbf2d7c92d0cb2fd0a1de910d92589cf1aac29992489bc179676c31ae768869398fda50ff14860a1b4dd3bb2e4ba8b2c87aef7ee00d375956a62dc1e5d548a59f209448e62c4b1221631d4776dd5192154d637217d31feea1c4cb3ef1903b8987f4c184cf3d6b5355ad53c7bd3e0ae5373d9971115698214a93e12b98489cdd75028cf22c1da41096daca95854b35d8bbf7d0d4ca2727aa511eeb6cec5352ed487bd3b00b261cbabcfa9f082ba7300610c6f92725d532a86e00b2ed1929a8be7a342c079835a2285569dca92a808049f170fba39d990884ef39ca511aaf9a713b8d78973b4f4a2fde7ca8b6adbdc5a70241fe3ea7d005b33e48cc9fe6ce5bc2bae0746827e548332adf83f8aa707e703fd688c494136d8dfa50961a9e5b69b542ed6ae0e70ae159df95dd9d4789e284a675fe048585214047f7f6819f7f011141d265de9fd4c04f4ed5dead63fa4c8938b2f42108d263d5394d164b3254294402cbeb48663cf1ab2c296d6ada107e8aa5b505da49af96e1cebc6b302faa148216d38b9e8130cc654974ce299172cb875742e62c32c063ffe7535db2726f65fc8f600d4dbb1a20f +expected_shared_secret = 54c35602dafe572b99aedb7069a59c4f7818c860b27a947347657ac1954d6454 + +comment = Rho leads to a matrix with unusally large entries +entropy = 3983da6a4615805f6d55c14ba582d59a40e646c7ae77f4835a51afc6c37f11f3 +public_key = 47340db6d04313d3a689b357566b9743cace5d5b906a39249f1c2bcdf335f37aac2565932631ac318bbb7ca75db36ac198ac6b15a02173049721d10f7521a52f358f35f3719269a695a4b0fa03b32d8a209aa12a5d786d8dea4ba05498ba222eadd647dd5a397e655ed309883d76326231a6764a7ba4226567022d70fa20cc53a045cc5a1fc54abe0189a4a2b6bf8a969d61706944bc59c6add2992b6e562e9732973d32b97956203dbc523803ca0a462ae118633483cab85c645ee3ad51682c0596378dea5e93bc7ab652648cf1954745172a75c2bf6a3177a7841b089b6ee911149871a9d987c6d499b6e0c4d15c9b74685401b680d3e112d6d70bdad6a3f9954b0057335ca36823328ac4e124d55b9932d548f58b85a32844e9f0260d8a4339285ab46152bbc05a967c5f16072f16178687b0bc06b621f5a4a14ef86b9cf1bade0185c5c52b3f2c407479467e5516ab9a1128260317605d4db250e8f4b59bf28a6ac2606d280af28664b75092fdea1fe9374976722dff579728e121fc1944891c586625a880a7bd154aace3e919b841b1f5f8c0fb841d1eac1fb18002ece216d42cb401dc1681836c1198653456c9392944054200a3b95b986a396d443a306b66018b525fbbb042e662ec108f6b872749d3287440c12bd07d1061a524a01ad7342d74f8a4b76222c5a439eef4235d51c9494602f6624dee256ea7fc09ceba9877f9332bf195c43502ee43c75e78720c306c2fa47f4ef6b7d69038dbcb8272b334c98cb665b306c04252fad3559eda4b96c14bf50b78d4a9a37081a2d61cad33b3b9418bba25409fbf4a5bb3c775a43b39520b37b5b82191b4983398858bbb0c6c8031b9736a5f76cab0e647443cb6d983a5e0a6c27756cbf471baa17870015566db8c8a51aba969e976a1c6cb2be166f20680893950ddf09cf8e3827a2a884a7a65d61c7c70a522d17ac0939625fe63958741255b012712e76fa8da809a8cb447d730d4097bd3e86471019dc8897bfc82c3804a76a38919f7cb50ce79bc13ec4bdda215bda9789503aa822c71ad8107a35818a7cb055b303338e465933565b94950c11836e8e33ae8093b0aa0c5d5d555cbec5eb4190eecaa1525014e8a341e9400180937afeb126c278a5bc4713fe9c417c50c1e47c8756fbb6a6b265bdffb4c1456c5b7d7a895b6932dd9a55623341354549283ccfb36abb3068b2db7348bdb1172318357bac12422ab93a32b453bcc0faa4e8e595b05a145e614aded6bb77278bd78907b828b18a22aabea48bdd69cab061522a618cf39406f6c78cb983354384415d8b857cb451e01b24f489a3133070d775307fb61a0f6d56d1255c4d4e18c62e57d8422080cebc919b81e67c4304cdb560ab16d929413af650a53f870e8017e90096452ca3ea648ca644010d34bb79c5898b775b197189a55840f43371dd9cccb7b4a28a66309a515658f06acdddc47042acee250a37632b42af51adf1c0666902fe0acbfc8f59127753a40161de4ca07a5c8bec0d8ad3141487da4a842147b9de945e4962699033375548d680b88ae8354d6114efe284517778eb9b7957eecaf5b4165424a5f82f100d02b7d39968b98f69c2cea1a0b39394f49265b492ea8f4000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = bc07d2caff561b4645e3878d1de0730a88c05f46348526829a396f05a0a00603f0e2fc79e13beaacbe903827c20d9d687f3fb4eb2a8e9335459fb21380b8bf3734518778d8cfae9524ead1427c6a2dc379ddd2e985e2977bb63e932ed59c83a8b9a593e2adba0cc5f106620fc8c6c4cba5106bfdb4105def0c1d7b6800327cacb964e1d4ebbddfaa15b279115a1d05754c0c8a715fc2fe5aa09af7b96d5a93e758458aa5af8cba03b942f4d3c0fbbc2a45d3f7af5818d67219a72f4f538883ee2d3e507e2dbf4f7748446443bb71bfbb4eff0f57d8154d29f5cb26cfb52c51b676e9b1ac08786d5f475cbbfb49697a748b7902a83da49d285a48c7e9cae74b66a30b02a353a287b40a66a0663e7a71adab7d03272f2ec32d47097d4c303396db3e7b7a947f467a70646777cda227d72310806107b5dc16cfb36918e88784524e3a46c30242a40811593aa8f72c742f885a9623534753b2bac5e29110a1a854646abe1c0337251e85987aa612f3a095409a5a632af14acd19491577223c278b18a9c3ffa7f72ae49b89df6dc45ebb2803ece96cfa94ef9ef5b24fbe686ff90d130d3ae953a4f9ee6581a346b0612f84cb6ccad4fe94a53602817d67c61a9604d288319f5933f4a97dcc6ffc36cf14db593fe27f873be712186a6695d949d4552dab37e36e2e0ced229ea9dccd6d3bae22f9fb888ef400b594ec08a15972e8d2478e50f11947b52bf384c731b0e50dcd4ba116abab8af3b880c54badb11d83b4266d3e5fc25c2c8dbbba12fee2fa5c2017987f31277a67ac702b8dbe110894a8c81011c7c662ce9ab96a2e25cf5056a3e202dbf6bd5bef2347537f7811637e932d13ce02283d48d032c284b6cfb84fd813b6c3421017a7527eafcd3fbc5d4324b5351b30abcf1b366f424a8a0b5edf6bc1f3e8702b03eff875687c6caebd7bc15f1118696cc63859e3aab75aa9acc58484da7f2bc9a120844e4830429c0eee2b2324890bde302bc93f661edd9c04e1183528482f9950654e8c267234245aa9482d94e90e00e929b65431f986e7bb34524cc41f4b4443646713c7abe6c4131a2d67f3bf42f0a7f2eddf82b5c08a94d99a0a7d14c1b0b375fc158b7d4276eab22efb438f0d0a9b30e9dc127026181e42643af8da0b24bd10a532069392724948ad722b25477b481006fc1fd030aa62b217e6695dd4c7ad34dbfb75aff1df5774b061a4ea8526e9bcdf9679405c0d2e40dca00c9e80840e832fd663596dc55f602d094253893405a02d4414f119d23c4544cf832888db5ae8494dd2e8ee357753515d929b8a37b5b45446ffac20fb204b5c937f6344c453ffa449fe839b4afe1da61301057338fe29df93aa962a7374a2ec181ffff9252c8af5c3f75ebee02fba58a76066df4c6acfd5d1c18390652eb2f469d35dd708e63a498c08c5241b2717333904ba0e6e0845dca8c9608f28bd1046805cf7b220498145b23cb18184a259458dd2fbaeb1c383005a0d289562b0a9daf7d1e320aa302fd3d9a02c65fa901d46d4 +expected_shared_secret = 7e1b4195e9cb70e6884d3d00f0b3f0a66b4d8c00ce112e1e79a1dd236ab62b26 + +comment = Rho leads to a matrix with unusally large entries +entropy = 2676b8426b9d6a30af007094bb76d65d388c2b3da938215dd6f6987206400e13 +public_key = ddabceea01649d9c6588d68c05e93cb6959fbe348468cb6e7f482d2b0507a097625325a7ff5740086bc203410414845a177c578698b313842dd2737d79806fdc8aa4ad8b91b514b6aab60885a49be68ba60d05891dd1cb47c1850b0105ec15a95c93136f22a170e346d2256a0cea672941335423cde35492967759b4317981c34fb0d759a2b08aeb411c362b2630c4b8ef342cf844206d7a5a3934bdfda95ba9fac912fb1844a0bb62041868ba0e3660a5551951b39880eac2959b5028eaa765492416ecf7a05102450eb20eb2a28be460972066b41ac87abcc28b38a7c92d91779e0c7cc8b42f107b48269521edf0c558a1b767536d295c3a7e60b9de6a8f299563be7c4d33d33940234af8c7764b181fb7b5af1dc88e4e830725533656520af7344e4ab40f6df34a90a898c672b854021d0631c1b1e9999d8176b22a5ce829a240642e19472e635a83c5086f87872f72a62e5fa038481a6861141227666f9203675db45a444c6310518d86a9221c9b6bedd753bb7914f7995e39031963ea056536a96c9b14598c95652091dba9210168467d7388b73770aa905052645eaa877c6f8a45acbb775d080521479314e214a5217835667dc2cc67dac17b0103b1049a03585b30631c6dac53b6d4056e5877786b295fe94c8804b57a027609bee938a8812666d12345e04c92469463443fad1c2188c951cfc6a06c3b8c3ad8856ef26a67b7841428a1f5b69a3fb82cad843a55645b78219d6de824701b0b1f192d4f816f45032b1cd5b465d33b3a9cb2fb04cb271a3cc74a8bf7ab6ac7a00e8ce6a0486c660680219c6ace0917b31595584f4756c9c5273ee36c37d25d5da146e57613edd34795b9cf61bbb7ebc441d575631215a87c4070159136348854c297cf3ca44fb2814448e30eb2c555aa2393bee966ceec0221a278f048aaa6d09b1d801aa0fb369ae4480f051329390af222712c61a59f98a31a03ba90c1a6c34c1c98c0be7bf59fd717ad9894786acb1cd081405c66a2e79a1fd77cad853761461c99218aca3cf4920703654fb9529c106f41a78b259294709bbc91679d0442bb383c28d64683ebdc7b94f4592c8ba2c1126c9dba9377040d3a124176fa33a3905cbb96764bc89a69480b74e38f558b422ef22e390bbc76e048c01129c97c26125bb2f86c4bcd274816265d8c41167223b0a22406d2a193ad3b1083b0cb75f9542e55b9aac02845f59618b5aa580b5b2bb44c192a906ce61b8c368278618d8ca8409fc02bb9b097acb208e3c2a9b651a316b70cafe6b9bdb32ad794b4f018b66ce55639e5558f5a3990475794bcaa06f17093d490fa583e6fd9596b40958359a30f813b940b1e1e4223d3857cfea691eeca944de845c2fb502e35a5f1a3750454593fe1c41662a3b3da407aa269c43167acc98f5f3c662d6177d3594d0cb800087c6a525c586d86c12e941b046625d90c8ec6dc8a5c546abb19a0b585aef39379db926691124265103bbb49cfc4e9100c803b4ef68a904273a6c899e48609bca003bcea9cf82203d52b5f9b65c409ba9503b3b16c7077465aae45d2cd4ada79ca43a9e99a124b7c9fa24a323f6c6bc18b81d9a6161191561f3776740b539479582a46bd913ad73e09000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 79efa2d537baa2b87a787317162d3dbcb40cb3c25f540ddb91aea6cea9870bbc5a5f86f8900b913fd4154bcfc7c8a463b9b66118c502ddad539186fcb079664f44a5363cc8d80d6a4c09f28cf8952157526cfef7bad2fc2cb69ff03ac39e37d47faab64cf54f63919303badeaab9e59df7040511ae335c5230e46e00a666b994d647d11cb032e7ee235b5e18b1894621ae93ee129823334580381b857cf0360196cb75180410f9fe7558d0e189502a5dbac5b4f0597cb3d1d201f89de26f7b4ec0d200a418a26cfb82cd4496c3ee22f6eb60f3ad2e1af981c238da13063d1746d65f77ce0ef30894468b687b31443c7acacfc3b3878fc9ec56878e7bd1a9f72ecb1706a4e5face0a83282cbc2bd15c89afbe3c97dfaf395a96ffbe1a3f75af03311afc69dbc01b11ffed2aeb8906505e910105806febc6e1298fbb5c0bf501232b888b7e8b285953d250b866a20cfdc7833a732966b3a03485ae2852d0a3fbeec6dfd0ec8015db5de69e55f091e956ab4392834c5128417105541b1145b27175fe35efbf3102277b35e42bd83aac25e25da6c55c28a03b9e2a8135871b4cc49fbfd5598c9eaa2482f249c0b6332a6999306be55921a3016499bc63a072a6e9eac894a3ec209177d07208d0d271c47f8065d0facd2e975011944f7884088768fdc053cf86f31f6d348222c06467fcf8ce0d404a2558e8cc422521a4e249549037d3e8a29e03a9a9bb511d9ffef4c5185a380d874732c9e862a6e8fa3fb72b213dab2ad0d91b047440b1d334660067566e6d2e14765d8fd0a45b9b8e8566419a6d7138e5a106c31b1278d50027d152bc8658d7045cb2297bb8382585b38be2d5fafaa7e8c867c74be013793874f181a9798193dee26fd5812eb469d1b842a969cda65d3440c67b00e6d1c3ae8630165499c1b4cf3153fb5731916ab779a2562ec62637d747d61342d832aed330e5cd794de900fa507d4b5fbdbc5f3ec1aa69d0319b3644d46d9502d435c1b5a329c0d3524611a145e3024595e91c2afd577a422d59d4d54a430f439534003be467b6f018736c4bebceaf7c83c799c2b7745ce7498dc84b9e455b96410dba1a0a5720fe703b7c0d859a42445eee7ca3353f294438a7d463fc3e98f4403f93b5fc4add88cc22db7bba150a2988639ba96cba8e2a0c980c9bf8cebdb5beb262d79e86cceb774750cd9a192ae93d85e60722ec6590beb7df8e4d036837c97dc05c7964dab00034683a576da5b51aa8a0622edc27975978c7daf1b942285572b09c170dd332a99bbf703d84becc6a96373fd1c0b355f063e4c2c6e59f5437802676000a819b9b99418df893b98a8e6ca22d95da2c151fb24a3a0e5944ac4ca6376e6c281b275589a3907c0473282967a121f1792d09a15e9d71e71e73f9f627ef0dd478061cf053af434b0663624c3bbafe0f37d7a32504e9c686f41bf48e287aaa8fadb73fece907f26a9576611ab2176a58e5c1f3e98ec0248a15774434c2a81c7a8f57f9950b83c0d3770d17c4e57582387d6f19bd +expected_shared_secret = 2522e72d308dc9d7d701e0b024af9e15627572f13573b27c406fa750df9636fd + +comment = Rho leads to a matrix with unusally large entries +entropy = 319c51bcb76124b92f39820a5653c0ecfba79ec91d632b0488f4020e5df4e37a +public_key = e2c1184862562b91806efa62f1b72a8ec43e70663de1f66a59687ae0cc1d9de1ce69244fccb0841b4b1de2e964e29408094a1ac0a9b4daa836e94454ebb942c6e9ac66f39abae73f61a99834292ada3c824bb53c8e67912a07377da92e63087f8d947f59d94a842b7aa8832b2c3c1aa957577f55027e76c106f86946f036804671b0e0416cf62e70eb8194d88030e2b38585181c4ab1fd8165a821bd68dc8fb3b403016ba5fd129bb9d23182029c4a292433087632816c009a237a608e65cbae17d688a326bd6c1ab4634576fdab2322b983f29c3e63b31303cc386bc90641c84965572c49a91f4e8258764834f38ca7f869cddbb10674d4296e5205ad805ac48462d3b31a9e6067fc0a27470aa593b896c3c319357b9bdf0632bf0786fadb0ac242609462a06f82460ea75762a678fcb07c350649d13c24c9e33200c9ca0e9bb87dd2c8578c7c4e27b1b75681a0b6aec6a55e767c4e14820f2ea609a16b862d5695556b0937f53e0ae370086c8f771295b1a09f0003a07bf512c4272f7241752a6603f8f51ea9a088e5263a59eb0b13b87a1d2929c2c29557681f180261f46c294de4aeaf380ca5f79efa2c64ed3131272ba489494ddbea14c69c46fd6346a7ec9f72d89559435e139a67bc3240bca29b3774127dd85d53c20bef719724612c462bc598c54738c87a00a9cb8c4b44e4e7ad4573afd9324fcab820cbf2091fd83fea52adc1b82b3f6c86369aa358498197631a20d40c790c2ddc66b0871c1ef882305bd978055bb934467d3ffc0359c2b31748cb19f615a63262fdf695f555be1ac432126b08e4a97acc18b8606ab6adc5cbe4589389e1121d737ba2b3a84d02bfbaa669f3a06b1be13fafd42a1773c830749cad35456e956c0ee64a5fcc46f1763c3b0c0d3de5c296a28f61194ae72979add8c7ce710d4ee846af81cba3e18d5e459addea9fb565b010e9ceed5798155227dcab155984635d7539d68c9f0d30537ce8b573b6bef1170540d0c10528737d6a5b219b2d96e5709a721b40536ee3c416fcec0bdba013b0fc0e786c9765d312692a80a5c9a3d65a6662788d194722d63b4bdcaa700e4c3daeb911e4d45674c3720be35269a21c0717a4c3aa2f3e1ab4f20a885cac44228138ebb70bb4548dedf8678d2163c339c1a9c719c2f1a51748571358c1451b0ced7b90109c98591126fbe57e1c913b5a935eff14450a22c4a108108b99b6efcc9bfd8438b5024677144885f1886ba068a6191ae17b9ffac1087bc94badf510095baa7167a7fe245a89a2a627d2631706a15d5aa081d037a4101b217c1c45fa0d83dc790447121cd9a533592cf8ac424de8770b45307f0aab484467c4acaa82a5669f7621e8ca42ec0b9222766b52775173b288ff5b01d70a60a853aa44917b8cd09a4b666138e91a3206c97877c96d690957b58553018f55f168c1c51bd9a48ae762a65dc73f366c79e77c42e793750924bcc1472cd5e552e20868a42047593842619c2e0fd40a3c7bba9557bb5c71185430a0158b9b95d04fefa266005141ffb4ba5160a5eee1499c09b11c549bc88cc501dc94a0a5828ee8a776a2a4aba3bafd410cc8354216cc3a93a457e9847af39b898b04b60a0c661a72a2df2b000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = b0e578cabf9deab616e52934955f42eec74bde5ea98acb022c427e08232142dd08f9120eefe5f455c8f120e672cb68f3a146c3aa457b637d0901fe2b4cd45e8b208e06823b8aae09778cd00fff5bed5232d219a2c33645f2dc30593e591f697118a8472eadbce05c9fbbc5d4b717b880065173cc0854182555376dbbe39194e4204067358808c890e5fe96028921fca344e3500b615f2201a1c4e4d13dcc889cc9b1ac72429074c21a52f4c78ea2c467d65cd2c9ed682f21f31b27af4eb5cad33dd633185bf32e726fe6e57b03168803f693bd85f5a9f2c3ec6944e9ded2b8f3270a89139ce50ba6ded6bc6b0be8893f44aa5856acda60dc1c4c0834d45574ecb6183d6e59a183c0125ff45c718be2cf85b5ce6daae6e37336ea63856561f1bd4404df725d5ed9263038d1c623b2e1aeb35924b79de474407168834891af783fe5d83a631eb14d7cfa949d698ffa45e7d8c46ed4abf75cc666b78526c9b95ebb2920c77c56227eae6c893b57f9f463ff2ebc9acddb2f7ad543c5b2259047a4cc87ad05c08bbf02e8bb267bc490c4b67106fb598d42135c927fef3397f4c3f6838776787f23a9759dd3214075e79eb3929932becde84e82c257e4638a19e1e3312cfe09d4ac681d653d749c8fa6efa6dac35ad59399f1e233540fa354681ca55db90007039b7e504e2e4082aa3e4d672019741aa02a281454d4e1c73a1c7d0b5449c2e143ceaa3b18cb9a74a89f1ba74963dc5dd4155a356211277af3a267947700a2cfd84a605ab02d37bd6faa8a26b50f7b3d9bdc79913272c31dcc0f0183d05933a9f233504ddee2dd851529667ec5174a3d23bfca197538ebacda36bc29ca675384c0b3f45e4f67fb66d8dd4aa57b7da50ead391e6b663af173e7f4d46139f5d0f4cea84dd32e4e718967c6b93617271224f2fb3a1ca5febff5f26c4edc60e9acdd9e464ebb4571dced645814e1038a50515a7e06501adb2de19fec4119dec7548c41097964c3151226153ccac24abd1415579ba1c37c805a5827332d97ba90713829fb30b7b09b275d75bc10d4a26b33980a0ccd4b00844d9f379551bd0170ee895286526ea9625a72b6cb8decd9cf18e57262f8102a025025e8168465a65a7c7e4d5fc8742781acdc16171085d51dd5ec9f4f71f58cfaf4557a55d07e7c164ccf7eb427145c7f9a800e9bd9192ec0f74d19fc17d3881b1d55e8600aa55abf78fd1e226d9dd6e8da2bea15712f5f43325d4b9c083d6e37d35c043f2bc8c796ade072555263331bee7fffa54e2099135ea363575847abb770322376cbfd3f1b7980a1857c55fc82aa80bdcd701c7b7d66221f08492efb5438a04d041b485bcb61f6fd306e96cfe758d99ca1cee70b200eedee86145fe37ab7aafcfbb2df694361fe9923e754187c3277cc895c4a53732ee118c7b6156b55b30847a6e828b7069a5d4be623abff66ba87bff49294dd9b1f698ba445d610973d052a80691c9968e3179aa3eea5b0bccb3cf674c5cfe7d2c14d7b6daa7a4813abcd56ef930099 +expected_shared_secret = 1cffb3d6d9dd9cf90d79fb2c5c974818c5bd6f32ea4d44c302337c4cbea44334 + +comment = Rho leads to a matrix with unusally large entries +entropy = 00ff48b3769ffaf4e91c1c9110eb8ce9e2cb99f060b486b37035407d2f4ca517 +public_key = e8014b4f4687bb6670b1c2a29ba577100943d5b926cb396423663f710328a8b536403530eee05006e7a7cd679ea44c29146494f1775cddd3b43ce6a903283f7890979ee98842d5a76f93777297abffccc0b8faace8f362c081aa435c32a5c31773bc046e61921f1a5707579fe36067588a0f32e2cbf91aa3ca6b38a0e12ffdf8685874869028775fcb7d7fd7a1e37c611316515638a510a13e950960e6f39395e436821165e734837ed575ad510d4fba6c3ad67e039b71a9b6c2a7ac240ccb3742d65b4b1c50a6a1a496995da77921ce33624fc48135e88c59caa47b299605ac1c79009dabb2062e375547ec907590b9bec52c86a6b9e394ba5f02401e4545c462c5f320939075b516c4a5dd0aa5d879456449a115125369584a609a83df8685ed2ab45f038559dc6b0ea170b09680e7e747cc7246b6c182d9199941847d9c1168a84400da2a98215a9e96f6bc869035a8822b27d459cb52147d966e0c354b70ecbe46daa9034074019acdac30055d8a1a02741ed8e602e2cb3185ea44c9e61fab637188554c8b12cc5abb9073b35108f59f6832112ff23b00acb0936594c00c0534a8c4c11cae4787092bf497b60b4a44116156e8368c0c950f3677f6424690803ee92373ed5c13d84c355bf041edcc872965816d6723b344244d0a54f8ecb0f1703ac251293503baac445996a1c9bd6ab851eb52f042692a2b10e4b9b44dc9625973af03fba67a3a93ff849dbea64739f643bfb803ea8653c2b9ab9639614000994bf48a8024c4e61c8a07a5c79b19540084bc7664ad44122e46ca1fbd517c8e68aeb3d835e53846848742a9fc2a4058047969bc11a773e623462c7bac66a34c62db861ef64dedf23c0b7441f6b75b4e60b86fe309b1b7746d558987f6a92cb8513792360ef76cb6548f0813ae8dbac418c25a1d95b06c530d79c6751e7569a2027f8a5354de3a70752764fabc632f3a1bf2473e8aa2a5cf815b3856a89afc122d98ba3f74185a3b2c09049601e23ee226329f024ac2692adccb2018b22a592a450b4a5819b2a498738d29f7145e534e527c859f05ad96cb963314c58a5a6b050ac6ead9adc4782859e3383170cabe4871cfc17a30ea4ac55cb998e77e1a26662a255f99f4ac7b98723341b2c7134adcdcab12a473bfe001127bcb01f84df31384af06171776263085bed1aa3374da7136648608b569a88663d2122e84b4b946b35c1f24a836e924202b7c7828c15507b17f906bc0e4b28c230134d90655696edde11a32c7a70303aaae3363e2a6947b4bccefe9ce62953f92521029959096a8910e71c51b69a0615ac790341c0ac3a574a79d34c11b4a974ffd7cccb05995d4089f8186b545b80a166982cb53123ef644e82897c77889ef91bd8c5a4ed1a4a414389d77307d53487940fa32782061e8458e0c601c884321d121b48ec04bca78c60d39b0c4bc9291945ae18224ec73ab7a451b9cb511bae34a20e326a497cb6ce46b5848c289da630f497ea3975eda79489f18a405e91bde288379f291f538c1a1426cf1634bc033098bbc9958f7af6e408354314e7221c37c1610bf904cf9e7807ad327f0f316761939674867ec7223f06a245711b0d47832b1a699badc8e1217798c0d000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 3159aa52482f4262cee553f9eb6d853d091a507831f5ed1af37b9c55f217eb1e87e8b0dfb653932c27e9e9f2c4d45cf89e9cfe9ba0d5175be56b7fe3751a4255649cfabdf0cbd5a8704d58511acf6e0580eed572561fab262b24d39c3a430a4e54fca969394037df12fd8cd71b7b6ec3d8f7345b05d4c16c5871b686690cee9804012a3379bbcf720f405c3c83f59aa391cefd8b00a73b41147d42c8b7820b0e779c44e032209067349fa4cd35e83850ae37ee73f96fc6bc5b71ff9b0462604b4e07be60cc76903175b045b908c9b8e7e94c6bc7c48ffd49698873913f9132025e51614317d27a874e319d802923804d1ce1626420d5794bbbe5e077cbd7fa3d958fb2d9608a3d41f605908d21fc7f942e3152337115a28b661f76405620b056692bfcc066f370449628f8e31b7453e5b7b10702f7c195dfb779fb3253f86acbaf4444ba9ce01c9b043133a233030247f8fc44d5b8c9b024ee83c186a62ba9fa5a3e45389217884a478f238d6a9b8eaf3d87b7b4b4375d4d5226dfb80255faab42380365b5511567978be9726d21178eced7294463a348b1e976d800b1114fb8230115b28e51f628a31aa8cf2e3253a7dccaa37f975fa2b8d32a6b6147033cfcbde33ab8857e3a6af95e4cd0db62fc020f55c2d6c9204a05835e2cf878c66502f572016d95b30c45c2ef6048471ad0cb7fe14250dddcb4014c392c22fb1dce1adc8e02f416d3e9b417f41c1b4065b975de472d0e9fd5b3a012ee9bf6311345b4968f6f18262bfc2a38d56d911f9efb981813f77a8a8d6af0618e015b8b005e7ea957f89f140192c7442a645ea7012b5ea2ba9f8cd2fea2ad3e41c6a57582237d53444fceaa933d61eac36d03a2865bfb7f12fd8cf451edb5050a35a75c95dd328296dc32daf61622ce0cc457c5968414b634b3e12a0ce45bbd733e3982c087a037d89cc86d546007bd92eef33949d19dbd4daa18e59c7ea3572bf3155a9a46af527347f4f4dcc2be3cc285d65f2f86c681a137850431ce8d2f76e295e74bd0b3c88f1b68885522dadb99fe1c8e40d938c9610e466770d62c34e9393241907d9cd7bfa470cb8fc149306d9450a7a1887d03cddad3fcdeda1ea54d3f126bb29a1ac3d7c5a60ead90d74ccbf1a75b4289a74a49e0a7c4006ab76a83915ebd4a95a471525444dd2c3e748b1bd347774e2cf01f90f05a1672c58f4f563e4da083e95e0fadd4ba57acebcb45611a3923da1d0d73f5c9a55489fb0097e123694e413460252892a0c6317dcb56efa834f7a51db4a413976afcb30ab4dafbe737f43da11c1b08a2472cdff3995dd7d23382b866873624fedee76823d37ec230dee2107258993d5b802fadeb89c9469a33c66c91567ea92581e0c2c1eaa2e2a4696b024c7c6009687d07769438a8b2ba75a7bfb32841dab8acfb8cbd4d1e26c5eb68bc49bb394b178e6f89dde843f4e2c5353b04390c245a0bddd1aeaefb87528b719fe42b35ad2a89ef34826d9e23f95b1bd3c3b24f785985e10dcaf0eb33f5f71f5cbe55 +expected_shared_secret = fd9e333ac811ae8be12c052c65131e3a7a32ce82e39055012ea564e10acaa85e + +comment = Rho leads to a matrix with unusally large entries +entropy = 4960ccb1276f96d7aa55885b6ae6f90343d42e1391e8241b5952931a979837e1 +public_key = f6513e1ec8234bc145eba3446eec18b3826b2ae709792648e071a7c4627e4ac7716db5b1d6040ba7b8ac39b347ef721a99c879453846e1aa591b8495e19003df973580d4192cabb72ae2b1f498bae9b3cfffc8bbce09122cd1910a406574106810dc556894777f35316c992f3b902186dba411ca3462b927688c81f7269b7c2770de5aaf90c81f752a3ec77942729a68fcb38a62946c601c945249bf0e280b66764ba71a44134ba84df1400bebccc61456fdf3bf50aa85e8e60f491ac1c1317d831ba5db6601133883fda81115c67fe4691d9df01fd3732b336bbc3899cf067b9e3905294902ca5686480cc94eb4e98260408b4dd060cf4b5344380c89d564b31158ce098ce1e06b91446c4189c6a4d89aa7e81befa900b250a7060406e25725e09399963c5e3e04219d390e6c28983e335646485023312c4d5bcad9aa7ee683b935d71af1908703fa2c9d66c8b6c55049b3319d39c047b5824d04975a9034e8ca1a9e1a5b0bcb222c5b5c848818d14503c31270d4f8446d013d4ecbc250b72dc25934726b426afc85631ca1065ca6e957ba00f1176a6a45b68a5e93274423e642451129ce83b7de439963c0c4e5d8b25f3b74fc053151610b4263725fe51423e886bed19c534165b4cc90fbd67256839b9371290af9853c948251c768e157041ac91fe6649bd1b1855dc417624b8ca0d798b1947c720b3414db56f01500fba30207322ede05612bb6505818a9a68538c9eb98f2b0a83dd38b765891f0d01f1db768d2355fc6b7a47414527c92ba104637072a72a6c0ce74772664e68660c9c0c28347315b17273a6846a79904a04b90a60c5b15973630209d9460365529bb72524404b3d9cacc013b0a7355a7eb2172d317cd356a07e5a341bab7c33db5a48fca4b1600443df6bf441983cc05125f6aa94f114a8c3ccea3f9c498c1126c072f27e97555456114f6bb3244c4698c3f6091864274a16bd82aaf0711eb8c4fd86a11b35b3b8b0528cefc253d7906b6b05382e37428253ebda5b48b6a068354381b24348dec73c279010bd32e41431d139a021a398f0e5c7fc1a98863f069b9d42a96b029455670caa89e0b867781f73fb7549392124485cb032a008d63812f832cab899a8d5d24b403e76d17d6ccb56c729e15abb2e04e32928c9b8971be6a4c70b15bee620eef375489347df7c622d9a803a86c2a9ec5a7a0554ff763912bcb7f57eb8b8633cf6ef39556162eadf8c285b61a53f4837c8c9ef48c3a58b3b6c31b8227c98df0b9057d452df2c258da8a1de1b99449c0054c48a0bc61a2336323367077cee252d366661904b12ea6215b3ba55aab06f60a517704a4046312731325df563cbed805e2c7b2a5848fa1cb97e17a2f926664c2947a2fdb56ed1b3c5e084a680073669b2b9e888ee010410acba461910795958e7c0c98294865cc700315e86a5c54912dc2affc2469244912d8180eab244332a00b7536c4cab62345872dc31ca3c0d2078d07beda4431f278aeaf2482cde53afc56352a894dfe3948fc14956917a4dc836f54369eacd4af052b4aa6b60af5e86bc868be275abd1118a83e5acfdcd4c92a3c2e2b13cce7101a9d303339f0b2dd4a282499579b803ede0b26c75eb8af34000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 5ab063c95a541d1be3fa0744e0db7e0ece17b6b47cca0fa41d08e7969fe87de63f319f80b9a31ff01e203de6e518e62e6133edd108e5a3e08d3f8ae0556cfd36b399dc1ebf3b229bc5013d06d7550512280bad2b27657d3ca0679d9fc62f0bf875dd0b326008a89b4f29e97211ee7ec75108a9e4a320a34daed15fd7ad394a1747e4e35bbe4f1118703c330aea81bef3e3883fd41c3efc3423ab46b553c7587894ad64db57bb0fe4d289d54c8ba78d40683bdf6330ccecbacd3f7f41541f1f2b1a7626d3969df6586b4214c02f921451f6adc04f5e8de1e3beda82e4aebc5e06abb33f4cd8a3b3b5741617b6a385739133cf5b77dd5607a5c8721d5b51c6c0b6df551a5b440082093f49f31910a04e4226b9ae6f41383672e0694bc4075207034e39c40668aa3174cfc8a75fb1a474485e9aff01f3572a5c7e4914e7519344c8ce7b81377d8c2af66bebc558359601b21beb984c1f00564d46585b4bf02c958c6b348642be25119b12f34a6e5755588f649837ba53c0efaa4c6c95d109a4ce1f761c1dcecb84cce8376cb1c4e34ff932408ccd2d06f20c5397f6277bf9c3234b20cedd45afecb7e87793d85af15909546c6ee41987f36d85865c8c1e281e13d9575abb9a9f215c08d89420535f73643dc584707deb7d5275252e862393fb6493f9e126c651b7981f26af8daf978153fa4476d615183bf147629fe36de7cceaa670dab930ba8a684b0bee24b55961ea556123b34e29491704d2122e46bed0f6fd50601e13a5d46c907b915f3b8e695e0bbf474aab6e082d156e79e59572731b48338892f2268dcbb8fc21cfd537979278ceb210fe3efd052365fa249c97e8e596ae6225839e5b8b296770f3b42240b8727a0a730534d0f42f8c6ef148fc04e4285e1aecf060c3666fc17a1ff794f584b26b0b1c41f0fcca249935cd411a151932b09402016a99832850b3f56c4846145738f709f5e11e28a90d9137e4e43f03dd1ddb6565c67c2a138aca59e8aebcfa61984bc7ac13a60ddd2c1f0fa84fcf9264ad5049c888b9f555e024f0fa685474e083025da168e3b9c4ad91f074e7e711f84bb808604114e09d1ceb83b697cc0f045b5089b0bf7381ff2efc08e7316ddb7eb7be47a1d82cf533ea898e668f0da124d2e87fef2b558f877b50b13a08641c74e2726b19fa7c0f33ab213f403c328ea60d08c07155ca0c19bb75f7f6716de89e34c20f9d15ba8aebcb98e9b6461477f56f9c65ea7e8744a4d7306e216f806ea8f9f1dc45781c1adba44319031fb9e81c6d33bb317d959bc53a677270f13d96da19833965aea9a18172f6f975bc4d03036b1239e7c315ecacec35cc0f788be1220c0497844fe7c989fff5ef7fcdf89c261a0fed3915cbfae94b1fba22827daaaaa0f968f1ac71e9772aed587d607d5d3f57c1500b6e08760e0b971c1999d01553bf87f55fbad96ce61d0750d75180623543f40e5b0cee74bb429edbed1b4c2a3e1aab86c8dc7381afb0b9e7d4151a3f76b7dec4199b97304d7b3845788e19126e +expected_shared_secret = b4b4634ad37852e19175ccfb5eca50093291da8f76b86be7511379188bc20d92 + +comment = Rho leads to a matrix with unusally large entries +entropy = 456be124e7f43803de5f734ea016455d68164a7f054c003f4ef49e46f42dd8d0 +public_key = b0abba905c1559715f25f720b7b745a52332355154e60577e598c754b6346b335b0195ac305268bae78bb4617807ca4666738ca81515bb041d43a4188003c52ac4ae4b3808d8c755d3e99d00537249d39d4cc02ed9f98ed4106895666c47538f79e30f5104adab1540a1fc58d1a857a1a4611257be37e0327491aa4b543aa6322ef7816a5c9a55eb3bc8604b15540b62c3405b861a84218211c20bc3d35a8a506b0153306fa98b9488a7841d85197c170f84c380098077e42cafdf1913df369f37f3291ec47289710c57f152b74572c23324f83618fd281f5e41976e77097a570a991b3bc623ad6331a1bb34673b1c328319758ed731ca2981b50a5a2cf8c66d31b10e88c95ffc27c3b6aabe8b207e6cb4373464b1b83f4a5a9806449bf7fb622360bf9f098b56729c5738191d57492b377ca8f989a87922a7368d724b07b7e36133620fa0735d60f5be8b51c19ed1655de5108681cb27273d511c643b7867516c2982a74f62e4cb759bb1f5f0808cc90e1baab60365722293bb07841803076504d00e6fbaae853749fc322e3458810ea41d832b35bf05a10e62a4ff8317b506b9af7216c445663c9061cc62914b0b72b5989d7d9c2b761c2fc5a28b5839bee5596c0de25c10a15776447e17770edb666249a2310962152059c5ed5738741a29e899072427891fb53606ab8b5dd06c005d239adb7bc368b10b74508c45c4aca726fe59c7729cc1ad617236e1b75c760e47815df33297c084429ca371c16c5761c9a23ebbcc2cb43ae9734ba9495d5a86a89e75aef50b9e73470d8d9974cf27a961c0cb2c180ff36140818b005f05afaabc86d8b8bf5c2a62f0632ebeca0c9c567514c9311ba6216fb13f1603c77656cced520d977ac75031044c8790d1b4c97dd38b2aa43dd8808a79e406f8e01503db8f7b51cc1e4265ee830461f41cec398251ea60d2c573ec59b4d28b09dc9446bb972f6d134e2e192e987153b39538e1f631bd81b2e65c2c5c68a96d1b78360889efa4c692b7cc374160e8dc485f47a676d77706e047d3e717386bb49cd942e4c05374b3a1cca148535a3ff1085102f4a7077b5f9c7b1a9ed651edb32691037f9388b672a662bc247beed215d51b414d3530c6b0631999663fd7c0e5da7e411c32c506476fd08a09d499ba3c27bbf6a804cc7e8be5c1f3f97d7aac085dbb3bd1076a69db89bc990efe59b00ca943ef8560642176e926af342b48e8002f6d1aa99b58cd013b03e0d285455786b54a4be3c581419730081361c04697b1b2c07df068621213c8ca6554b5982d5a1aaa113ed9343a56101aec68b838a37ef2c8a15d0504c672b278556b40c766c2066ac995caa32676da182545773881545cd58b71d3d7a02a209bc7407f420a830513b9d9d6c93c56571e42c8bf154afa060667a46d13cc542429c9d1a35be012cd3c9abc2bb7484fc89a4a83a20f7c2bb088793dab732ff370cbab614aa851fb77ce176b8f806c4f2e6068235b93d08c39e96badb37a457e8a790b2b8ef00b0b9e941592373fd2caa3ec3477c6c440d0daa755ac0ad2285754ac64b0852086112b0c9794f1657916fc173209a40425afc9b19946c529ca95154f24ca3cda5f9547c429836c377123c6ec000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 925fde875ae198cfea88c4eeb3a0091897e25a793672df1de3f24ab4fd3edb2cad0b07e698f35dc97bfd1d551fcace3282c8c3d8131857d96ee9986da7b79a02ddc6cfc9fb7f2b809a8e5511b1c1256dbab33e7606d8a5fc048b36f6ee53c7f556efadf94494595a549ca260ac9c45bf9962bf406610ca58dc286a9eeccc447a767b6db3ab009f5848558acea4503de747d72d43218babd6f68c091b4581f4e41f2e850047f5f543a02407e7331202b0eac7bed180061bb53f4dd3504ccbd3f298d96b43bbaf8f0c2545be54c59830e1f343ca88bb9c6812c66bfbb59a6d68298985767a73d34fa69b52cea98d95d8305f97c4d4fd643b56c60fe31e3c2ee7e938ac2e4a5da2297e670931c1dea5fcbe9cf118c62a76a461495f10f640fb416ff7bc2478c0e8a1356bb840345f3d43476bc4cd990eb7f7cde7ccb96452d055397ee402be2ce395a29a4f4061ec3d85b99f086341441022435b636028a1a04c5d787abe1c24a5a55653b7063b1cacdaee40ae0de77b4034b9ac0e860a90c8834b352c71e353c02b1f46b135fa68fa7a5c1c719896987d79f3174b8d0b0c28ed64cf9f2907924497e35bf519d519a9199a4dd68025992c6f466604bb2ec3d7b13eba76e4803fb73bb125b83413998ae86691a0b35c0054e1418898f435ab26cc12a12fd4dcfa9e80887af7ebb6c856a7fc010cfcaef9e1c5a4dc24a91a622fb7307521faff0b8e8e966b7b6ae849ccc75d31c8d700a3b6a9c3f646b2a88d1e9391c2ddc6c9ff15db961874c87dd94bf0165cfc8f719806539a8beb8e28350610461b1252872f0f3ac273b3366abd78d9fe8868dca1a5eecb683ab8b50ced8cf4a5ed3b721e0fe6b205fb191985ca745ff5dae0010493f8296b6586e1c96f7f23fcb4ac4dda15eab811107c977aa0a16439b06986a9027640cf7a01051934dfc758215d22c6f06866d5b871dfdb6ed240a73dfde43f7f89c0ce6909b54b0a633a25f7253c10906166f81ae91a1419028d6182c1f277dc7872b824c7a5a22bc7afc02afeaa9ba4c271ee68882397e6cec34a955cfc672f4e6f5ed870a35ebce97f34542cf0a162938c91922230ee3fe9ed9a166a790ccf450b80cb5f483c3c6ae5b2e52e907824b45e69e5ab38226cbd6519de995e1a62a910fd45ed189540e0b4058ff01edbc6ba4eebd58d55c0e33702de299eb53d6518254b8471f282779533eaaef90602e52373be8b519c56a2f6fac0953c0f84135715c5674e45d15804fb94d9e0525ab493aa625fbf73ebdf74f0a1246e1eb0e4e2e261b24ab81d8da6e1770634c747542450cf0a2af23507f8b6766a16dbb2e67b2c94859228b91eec6c59f5a271902b340320412ae947398ad102073f8b9b8c021f81f786622c3483e61f812aa76232e6f9453eae044c5e918e6e4e0e18a78efaf6cb36f7b75929d0036c44edf928d6efe1ddc87b96288c7c624655d302b98865978ed7bc779c800e6113a0484dd225aef29796c8ba300b3f48dd566fd877dfeb5d25f96da5d07e643c5d +expected_shared_secret = d4b9a0f77a52d4f8b9c95951257348d1931725c27eede694ecc09204a931daf7 + +comment = Rho leads to a matrix with unusally large entries +entropy = e8ac9e76377d67d84f85a142383e777157805be0d0f679ba89cefdfa61583780 +public_key = 038c5d80656805b427d0b9167abb3697444af88a0f3eb48bf658be44f36b01233902291860215084ec7bb3e170e517c65c623ecf4a488f69923f9045ea18334d5c8ee847381b5a8903a6233796b1def36e46d343cd3547f4a757d82c262278432bd555fb5430e7f936affb453ac1a031c70cb1b3a8f3762dbe226461501d13d10052fb621be30b8ce63ce93591979863816397f0d198a6c534b55213d778ae7bb1a20ef1809ec37b08382c43e82b4a758458d7758d23a350538b3e524d27c9074d1cc4e3e1a17a6b06fd71178c5b18803b1c439b9e903a0d63018d2f765fa7426a0684793ea789c30435657b9aed58886cb8788e14426ea0295da18293024eb1a39eb99a20619a3e2db48a93eb90dbf42b84fbcec1f0b9571946b6f150ef5a672686a30e52be2d536bf3664550f60c99a89b81f3c911784d8a371ebea0b97ff50e2af68f822a72e9a76cf473bcc1cb81fe2a03051771b1c91f1e1a444ab6119c0a83b25a434fd598bc767315881aef9cb4d4c51ceadbb3b1a1142e0b87d5826b161233ce253d2adc9a00bd00e3cc21fff09abd919b54e09ba6b505601a358e50593dfa117eb2b8d7458745a25e7c7321cda0c432aa5bb41aab60eb3dc7e03ce4017b245809a534c3dfa49e97f4474689901e814a97fc0892ca04d0c00e3dfc836b36bbf74256e77525a031160fb3bf8ac31502c049d0a264140104c7488e36a46d23a76f4535b5902677cb98a5abec57b9357b0cb3b36b68349b273a2f8396e6c8594b4a32f0aa8a622378b3ca0426f44443942c02162907b2651ac2168fd1279b040192716bb584211df4ba36cb363b8c3adc39b410977ae3cac26c21470426837a43b821f65d8ee1950c87b4765a034aba1a35579f4148b8c2f39949812cf9d850d5e25be7713ce62ba31366737c03ad45f23e9b226d1835c5ab01c081063dc193630d72821cfa2a56d16108c40ffc483177d075b6a7a1bbf5cac7da0834d755acd10b9b9850a7c97d90a1061ce94efa4b0c0707339dbc7f160a45eeec022815a4494334254c08ade388c07c34e3a07e51ea60fdeb9b20b4b9afdc6c3c2b63e872aac9b2a90b798bc2dc8d585c69c1b33c1d51372c583e835b9ed561c218a2968c044051f8a969a7b2db6a7031d20cc9e024bbaab4385a3ae13ca264c25f6c5b4170b5c0da13044664a10f335ae9045bd6319abe139bb2b8b635bb06e2f48427e256a16a0f71f119230a9acfb19f0fe07c71828063f42a844a5c703aab9a844f689944ead511d8c97127d99429fc87ede190e0fa002261494076b7a10496dbe12919f585685733ae780eab3ac168287aae3842cfb637a94483f68170f6a3092d51b82ef10496a6374572a527aa7a7d1a99315953f625842ec0bc8851180b98cbe411453027c9b8a4a07fc3bbe32b897fc09e5e65a0457556a8b28e5b7c8b28db24e5431893953c912c195ca52db5d125c3f595f2ea75a63b6c83c8cbca257824ac60ce16bb5be02b30488974a22a66d37b19531e3cf17b59bb43d738cea25326dbd6355243ceff3caae98446927351ff623260472f8c7a715016ca5480af5cecc001c6b65f41221b16bfa61863e225709775b5e6393e4b71920c0c539c6bc5ec5c609466000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 7c06bbeca8b58423e2ad420ec36064ed42c881e3655668f8865a2d643ecd1a4eecf915b6c64b37c98947f06c3ccc8e00bbd16017c246db88cc83f12c887aaad7db61b4d567c285841689169c3f928f1d178a0ddae50d8c46cfd95258667d6239c300595738defd2e806637ca46baa4c6c7b97f1a9b47d53cba9ffe074f88d104c4971d250d085b1800fcbd91584d8cc48e145fc81438290d74765e7ee8c1605e8048b37b9d22b050791fe008b9b84b7f23b0f49955e32c0eef78d7a3a0b2effe8b37d124e19d4cb6f6914204598a525239d9baa116e1c9c39c47f9f37f965941b2aef8519782c65f3ad3a6509d1e31e7efb67db21911e4edeb1f7e9c37b3f852c81d63a95e4775e3f2a8ff315a214680adf44d290e42ebab8ca95bf471140b9d7e03f5e9f97864289a0ae8c9a105e00409f714e413b69be366303b4a138ed51264ab0e5cca5f6dc9387c6608109e8859893efa3bc7384e9f418468b1078807dadb768e254094039d1b807d67353c8e0b5a03d28b8e41ffa0eb3ce0837a132144597908f7a059a097b79a1bac323757324e907b445d064e25c378d2069e7c5d671036871e4fe36705747635e40c6e835319e3ff81714cacc44515d671b703c5581dc76afca0b881f37c1ffc93f2e4afab1e8ac776ca883f3adf7f9ab99396f7e19541c26342a7d5618958523b81871326c357ad84ccc6d3574d97cbd875524e7b08a102263d80f318a48e510c22126568f76936c904c231700ad042d73137eec741c827a082de4a45d296745c55b8367719dd08b8295e38d8d3894b9f8e2f9b483b266e1fc71d6374353ca7d9ed1c6b73ab5a42f6abff7b2ba8fd484d1ae6928b5ea92ea3577be01dc1e88abcd0886eb771dca4d36e91c45bca4807c89736b7d6a927cf64b22c5f323077f5488f6044976f310b4b99f7d486335dcca60571157ac0e480a4dba79a826b4bac3dcb7327a33b16381eb41e1d39915e91a58750ceb71098ec7f1a2d7e44d4bab75bb7482eec277df206502c497eaa345109a145a4da6bed1900b680ad12fb028d33563bfb204ecf66e6ead587c5fe27f8a2eb0e27471925ea0f35eb9d5e53ef801eba3acaaa7790b105eb6128ace992668181c1d7cf203afdccdfefbac67dbd97cad05d499239df84e4cf7372117932c973957e5c70a8520f822be430758990296877df62069d818768513d14df0568be8e63e123bdde35036dcc69a98197f52dfbaae5e5e0cee4a48c67fdda605dad8a27651625c2b35e81dfcacd2a41a6d17f6d7067a67faf2479b3868673b248270f4a2d8ee26de9c787ce966ecf186c1401ad9d3bbf2c43b1d5de32bdd77f5433f4325427254a13985d733ab0863e62a4f3d484ab3f5d3b88f23049079143b058babffc8367cebdd9d2468d7af782979a3ef12841370da6ef2db03679e6bca0db72166c361adfbfc02234119abaf98d4fea8ddc6e8490c2fb5a1be4806a61bc7b36884cf4631cfd53138a23fdda11e597aed323748314282672473a1819ef2b9488f6744544ad +expected_shared_secret = c9d0cf3edb1172344364afec3615ba98477ce9316f92ca46ca5f42b73553a9f5 + +comment = Rho leads to a matrix with unusally large entries +entropy = 2fe6b9cf4510f212839e348d671b3345da68a477f57513ce363414e87299a717 +public_key = 7dd722a23522b0d8cb522a67d63a75af305c05f3659bc496f1c47e410582a0e58bbba80751bb2f5ab71414051627f46a78f9708e3139f8950b999378df4709a08b9b511982ab1b2cc4d51d177578ef263c8e12752f914733023d9e8068d4fc1aac34106fa72197f6b4e4bb26ab29ab64d7c848f98ef5557ec2b35edea70b67c084193921d8cb52e132a24372be7046aa2af66696007e2e0830df1c7b4396bcc8f27aca46932c463b49db0ed88882f3a45901a4b96ee3b74e78afb8dbae7bc653be895179f208c27c6ecd60c26e54152aecbc13bb5ece39840574c56fb39fd2385c76d62c59a41b3311702d5a99e366467b6c4f6c252a95db32e5096e61d1ba872924d358b346dc099a485c3df72a94e437a82a6cd778888995c473c203e091309ba42511950c19db3acbc5987259bea952b5a549839f197d7bf64ca0772cc1dc89572a0e04690fe651a79ffb3dc07388c30c06711c6b25572bbc83ba868a379d54c6439754bcd67c9b0364ab3790967a062948084ab33a80ac5971fa99830aa7d1e9263e7087af67ab6a83ab34f405dbd72b3fe46e9f2114e26cc6643b6d3adb9de63090394213e72b64ecbb2242266139579ea9cab2e51868ef82ababaac38e7ca0b9554d665365dd8b0b58f3020cc9218b866955f54d9f7b9af9634ab995a0b5e234fcc78cd1594e1cb8a845ca0cdbc82e3fbb35414c53423b76875ab267a702d51710149061e7655a0168695053aa61b990fa9439883640e7600345033ca90678925b1d632962deaa0ef5642b870610be3387eda90cf608254dc2b000c06632331680e12e9b277597d07633a31f6445318ac7b9cc1b087cb58bddd30a07ea6e1b1429950b7e7efb1a6b88b037c92cf987c904268ce39cba4bd3c163f5a8bdb9698488152a18b02bc98a83fb6c28a55a018b48979660ad5b42281b8745a4bdcb02cabd16735ab1523916adcb031e34ccbf4c50bf61bb7d562804d4104d3f6ac183f447e6608acb0bc40a34ada4897e9a91c542571877931864b612cec01c88010cbe039d42540835422f5900c944c7025ba3365543536d093a68c27abe1175bc227faa590f8fb8ca9ab1a87366574422379fd8659fe5bb5ec76e179666adebcedc7b54f1aa9388b2907a4ba5c48441ad90499c64a57768631d4a961d88976c816adb897da7715a100c75099cc122f3b1df183385673a3bbc98cbb0ccb0b090b3517993815e3f6b26b984bdda32c11947b2fa5411004c2c41f2a646036b86bba618e72be7f97ec6369af5ca2ab2dc9493d9078a0c8598841385205177c80a3be42a31d1166b02cd1dd2871148033c794242962e8645ae2e4867a3e5c74f71a1d978379ad45f7fa5c70066cbfc4cbfbe05cf23612b2dea551cc52dd90a8468ec771ff071371544e96400e288a82e9c9eefe807d6f4903ac567741abeaec9707533b38dd8c4366bb33cf86f77272478e43a2d8061293332c8d805a4516238d5ad1934a9683655674aa6b6d91610d4c82e966d74c41dfe7ac18e993c22d59b2d286a0b5272cd44988510b9b342405757a25731729e934c58c601f5c311a244a24dbcc772088a20dac4c8410167304fda18445f6c6126b9645d4042d6033419d246968848e1f5000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = 83ea5ed982570cd981b7430de924469d4e2faba68e03261a74f5114ab8c448376cfcd1b9cb3e72bb031bf0fefe772bc40888abc6acffc1d335d46d267acde2cb89cf1b3c67a139796d6a5763805d5edcebb81070b44ffe021b6c2b3c6c3d5dfb6d9e546930223ab0139990c6c5d6257520fe394a3aa30c6a71d47f415ac86b68eb8c83b131a3c5cbf051971fef5ef3bda355d3868e71ed8a0e2c6de8a759bc0c9e760277cc2c04c783d29d1ad3d3385accb85cc88c39bc8348f84dd8c714c5feda50b0770414a333136d6678be6ccbc5df488bafdcade883fbb310c99cc648493aed72680fe1e43c0cf523d3dd06417d29dd97c98ce53089505d36a476c0ae6d89b165c3ff6b2c62ba954fb81ac5782ae648a6802bc057c64fabd3726559ba79de9c144aaa525f6a840ed55abf21b37231c6c4cbb0110fdbcd0004f6f4974ec644c33a8aea34ef4a0a146f7502650c3def5a313d2f309cb428880502d3bdf39196a99bee296f9231d87972efd1159d3cf59bea05f0d0373a0e218ee5e0528e1ac7132440980d1153b9423bb2e099d05fbc8241ec1f316bf0add575a69982f546e99c64457c12ac83951ad46a5f024f6a61c91b7d3853ba1fa41d5a95f6ca811610ba3f32addf011ea4091ef217cdd126ec5e45cc40ec6f1292602b16c02718419646370e5b2c7c55c1128fc5d6c767cc75248b79e2379d40f91a8617e8a3db43c42cabb5cd39a7a7969147f30344c4b03de7034b12d8a1c3639697c97c4483e4191ca0fa81d8659f40e31b899b4ef4610644b1314ab2ef14b8dd8dc0082826fe65dc17211572cb14fa376f1b1784a00033c8dcddc44d6a1128a200eea668b6516ba42585cbb2e2be2a42148120013d0a9378ed7c185071fa8fdc09102164c63a665fd09c08d34104c9abb64e394b2e2a00dd834f7c7f5de16f6c02906ae37acc923dd76e530c78f2143396bfc371d14e6c48bec072b6b4e18eeae967456beb3f897a06eae17de174cf09be1435e691350632c0b1eac69dd66549c1d980fb147fa295ca6f21b5dc398e63a7c4263c75b55c85b4f38fbd7cc0fad84aba90dda1f2c9ca88d88905602096162486dba1ed0a8caa6b897c99e25934152a35fd0d476de09fb211abf36565af3744f3fb737247f5d8f172fbf438ed04422a6b3e17bdfe2cb0f09a1d57f1f1a113a768697f23d61ab288f15abc760feb0f5c5d4d5c0b1c891d3dad6089a3b7e54516b8f9755d38430312cf17b21efeeecbfd2719b62480225b9b3ee8940b1f1784ed5630d152635a1233acdd16e5489a9a15eafa7bec99aff25b18d9cac1e726c9e424773a7083f213cea53dcd310b0037aecbde1d584657f32cf548a6872c6f5a1a3a70d4db29ee3773291c94b00b5a596e1691f7752e246ca0960561cd233ec7d5f54496d34ba65b359a856315f02d16c990cdf3db2051b17bf283fed1b808ac79a9ce8250c806896bf75f2cfe76465c09360aba4c9688acea341fe755363abe41c0cba3ebad00c6c7bcc3f7ce091f87079f60094b92 +expected_shared_secret = 4bb6a6b27596869efae3d411c69c593afff99b1a703ee1f4ff3e0e7e9756e75b + +comment = Rho leads to a matrix with unusally large entries +entropy = 86630b4f72820d19e9941784183b3a0d770609becd6fe0dc463cb6edac432d59 +public_key = 59b479b444b510d9b6d89b7001b237f4a34c57509f69208c7e6b956144bedc8b2d19b12c1baa725dd106f5418ed943370050808ed2636fa634add059541a7a8c7976b0990e59c20c00343d1c37bc3ab587e312991bb88a74227651b340346c58bbb174ac18c204f37445681bc5905354d834f86016d0921219fb467d829daf24901815666d664b8c4aae307485cb95885b7cb9125a14d4d988d3a42c0816ba7ef14de9b622e08871988b8c02d857626b65065551d5bcc81112384f979cd8d2b9ecb55c6afaa700e92e3ecbb285c01112a19cbdb90b8af135b235914c901e2314902a43c939d065481128f83ac801dc2fa69c912f2b69189736d72414df12646680c9c858a9afaa28b994531960b0f2b82fc6b9c6f10706930786ab5c6b0da61ae813cdb7387c27324499b111c6ca5767056070e608cf421af52cb45a842da82560dd86acf45a7e70245e0b535f7559a9fceb9369c44032c09302438cb4670925c7a831d52f083a7919e575be844d9e6a009957c15e6c5f84f050cc4801561876f9f483ded505b3c77a4a97788358801f012b59d716fed55975f8abd3464420d849d89c16dd2a95c372cf631a93a8897ddda2a038070adc2a97b5538778c0215cea399deb8279b2ade6c5ab84bbc8c6e181c091b7002a4d5f395bb60c817e03966b63ba76e88fb05b79d126ab0975c995b5bb2ae6550af78d80b96af40c9514f945d72b0c9602412242c81b60b2df97999fbbaec0404056195879535041231803aa7cf064b5fdfc8b86344d65eb30e52cc0d5b86947b8051ea93008d789914493b58abbd5395b657560f5823c387574db554118d06b26ba14b9660b4b390f8b828ba8a852870cba24a114a68094cf0168b721af8f0998e599b5db2135a3e9360b5754dd49155eea830f0035c2c116dbc9039cf69034c505ed998f8460a170eb5f09786d902664c8135ad77101d0b802248b6f3165a847b5c989131d7ee3135cbcb48b3cabfd100074c00f2e7bc85d4c84bec8980a6920e6f318a4bc805900b548fc7d98316c1b3c3b49f6c5d90595ff7a7b56465385620544aa3f39114e53581e851849726023d953b5df56b87be98854b253a39297f060449fc1c02725c3442a4ed8624f7f6abf3854cf04166b24c3b5a38358bae933ee4777df09720415314b152efc0b175b664c0c0a3521cac1817314d1e69fe03b351fe211c4c44639622a73a4547ef52d46b033aa52a79182baf49a8808fb259c048a04cc03f8a1038e9112eb30965c797f90c277b3549df4f757526351bd1a100767b4bcfa7489c17cb181b707986b9af85e766aa1f99b08aa2a7bc8a385d294277cb00d705b4ce2583e61c16be2b18445d051d7f0cee51703db3162bdd328cf0b0b24a424bd830c6574091088ab746a291c737e8cd595d1b51f9646c7813a8991f89c168489d1a3b61a82466d98ac9de55b4d5aa020243e638328fedbc93d341e1fdc7eb861bba3783a57c86a7184aaa7d5051b7018f3f18b40b69fd7780ae9609194db70123801729c561e973dff3a7ea5ba9045b24e5fe5bc63ea858c687184a8276612c80ab600cc37699583b9ffa8c5a1b7934f3c12873522dd1c4f976b73121bb79766803d247de1dff18807000000000000000000000000000000000000000000000000000000 +expected_result = pass +expected_ciphertext = d4e89c9a1b36b648551ac2180f2f59158514568358f66a6fadd88492a0e1c122d1d7806287eecbcc8e8e6a463dc1c909f13842f734b9eb5bf690291c9d5b7836de8f4a28b8242c21131c53ebda4002b329a1951f469168ce0199f0a1d2edcdf3e6566f9e638e5a1095025cdb591aeaed8bb115ca3a1f1e9a8e911b2b9d3838608a27e50018e9a99e65b04adab67a75db892676c28ff41f118286f0ad2f5b650baf9441470db659e262e64cbebb4e808b1e7cfde0ff5c1ffbe1336beb42155fd9cb1cef90f306f5aa2f121b30b4d6091b19f37243cc15df2a0a16c4b5f70ffba99456f535af0eb0df80771150ff28c7925da7293878699c00f5136c340d1d06460b0ca7223f37ca553be904ebb7a7f41daa8288aa244202247eb8c35b7bc6d1dc8b95c220319532dfed22dc5d0f2f77a4bba0f5ee599420a94c446d89e3e8532117bd8ed0f7d9cb1f0a58a92bbf30a9d7c16d5ebffe16f39f682c18a8fc2ec0a551370c0e3ea706259f52333f5e86a83fb60b9ee3776f08e3f85ae4ee66be8c653cbe25e316e6ad33415a13e5139f53480625f09f593a598d6fd864729362efc3d09f5b171b0eff76cf860c8fd80583bfcae3bd7535e0270d622c2c09886bf9fddff6dfd045fea3259d26f17500b6b1e0b5068dc06a510da4809fabd615221f672f6d1d220c22dc080c9dbd7544ccb3369deccb76287c77e1a2af0afe133cd19325e6a77a8bf96fae6dc0381bb303815df4de480a9f3f97f1baab7774d7d5d9eda6c5927692fa2277934b0ebd30b4e7785f0c61a44357f49adac4430fdff3af956904b789c2dc9bcf87eb4cf93c48256ae13e90a1bcd713f77446593837b81baa6fd7050455d69a16b429018390a47e6e881467b57a2cfb043ce5a8cb114c4bd916ffe353579b599994efae24ced2dcf1a2923a0d0d8e771e7c230d887e596b80e01d84c908ec9fe81270f12e2f9ba2d783b1200fdb106e9d340c21667b722564a0cb4603dbc2193d3b455e06cf8c1d8fdf3e7ebe16a47f0181407f66c214379a5f336545818782835f6be2e9ad89f180ae0747067cdaff1f3b9386debdf3f057cd02f6eb00ecd656838e2ee5bdb99d6260c0447707d747bb6ff33ed65c2b3e22074ff25a7a0933be3e9b51de95d99e02ed4204f5ed8a6ff864e2f04266c9392c6feada8805ad44dffd5abe8d4262ddf6d2b1b4099367927b0bc075cf1d1d802f2d10b6d31d7f8c48b043340cae34b5b7c2f1e9b5043a0c2a977c51ff038171f8c81f04b284b2ee262befb6a54bdec146b84dfa116542bd13123ea79e4a660e44f3d23a0ce35ae4eb7b45611f87ae836081742d3cae6c65a0f93514bfe118cbbe7011e2a9502b197ac4bf31fe17016e184657b8dcdd62a223d1bd88b98aa0bc200ca91e123fa956b3d804b2c0ea139f934124f8d0c3f4412d8effc554f8364b0f351a789cae775b241cd6aa6d15251cbd28f0f85fd4f2a48fb467444f2f759ab6048d33c27832cccf9cc45fffaaa17a6f5e4b766f861529cb1a0641b6d3854c11 +expected_shared_secret = fc501515ab8bf04e3cdbc78c032524d6b9ac385122bd2324b11a2ba812158fe6 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/keygen1024draft b/libcrux-kem/tests/kats/wycheproof_early/keygen1024draft new file mode 100644 index 000000000..933632076 --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/keygen1024draft @@ -0,0 +1,500 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +expected_public_key = d22302cbd3399facc630991fc8f28bdb4354762541527678bcf61f65c241146c426d23b9bfaa6b7df18c97f20c1b6125bf874b1d89475852c448215db0eb7737f91480e8cebd9a0871574f5ab62d9020175ec6927ca0b54c09818e42cf92a383172422c7dc1831d63b0c295de75159db8034e9e07f7b0b910c3c1e5fb66b3dc523f1fa6eb4910cb89a6c17562c83ab4c18d0cd7e0796592a372aa409b1c557347ccacdc4644a119064d06dd474929d1c6fb4d686e5491ce4bc89a30bb4b8c41bce5157dfc1360823b1ab618c14b10f98c25067398ea7018c278a4b3df31334d603b2044ef187cd9bc6ce42725bd962c264983e9e18155a8b9c47143d70460a26a56fe7658c1f150348c6087ef758ad167887860a007a5fc37358d43b5ebee820acea474f0ac07b76802866199c61231d5c747c93774d2c1e0c1c67e6c81b82752173e125baf39b4fd19a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a13322899af659cf1b3558c1b5001154b625809ed89aeebb89e6ea7d67f723d045ab05715c42355da6a5c8dd39c8abe3037751a01ed1c7374919f3121b5a52c53d1487316769f80721deeaaad3c90f76e7ae9e12ba92b32b5fd457e3c752c2650dfb885771cb77ac3c785a8c562e6a1c63c2a55ea47cf8b90eb8225c123c346452566235b2f31823a33521e087937a345d8d663eeaa05658917bbaa008c2e335f8850a90a326d0e66432f44ceb8289e4ecb2d12958e984072ecacb88e1348ff0b55654acba5b54971cbaeba88ec4b91a94c37192fa982becb9f3da421603b61a51bc8e36cbd053851c77b1b926b17a272aa9023246b02b3ed47f66a00bd5684823634e7ce58cf8f306e35b1e5322824d904801f0a2fa7c2bc9c252b0a56b7ba2ab0f636021745a70a9a43e2b0a8d615970b65309624b5184bcc30b911679aedd76025fe3908fd67897b0cf4be5a6f5413d7dd98564b23e42a93e4aa8821cd45054c643edc1158db6b3deb13fb5a51ebd1a8a78b87225a7338e101104c4a220d9bdedd48c85a1c2dae781a80c40e13b87eac73a764201c9b760ccfb1ae392699c7039d27c39362b27b8fc6f07a8a3d4410f1547c48a9997f62c61074452ef1515f8a649ebca9437205a4e8a61606b41daf6834d671f4d852c0c9c4096611648c6a3170678b1537cc1828d93580c9e5849a9653175acb753f2be7437be45f6c603e485f2ec301bb42b6c37c225d7495a584ae231890ab5c8c35c268cf4bbb0213c096019319561a8a6947637aa40d006b415bb2cfa2237e0890b6a3bc134abf8f6585e108d15940f91f4bf5b0c818055b21dea6e63b553988c47f4b94e7cf800a493b4734705edc56a4b6021c629500675876804cf0b951f038a5c7fe58e89774ef2992fd7c63099d352a7d21560b788b405709861817e59a96b3a3a83cba803b16934331071905bbec6532900155d8ac88cb32e4e21a3bd3a03fdec325a51cd2773964e6784fcf1853737aa64eb67564727272661abf84313a57a44b123c65509cfb7a6f6641cdcc3b57fe628c7b8192db44ffbf5796a8613b1fa126f6076883c783dc24e2a4464c40b3a41ca70ae87620866cf4fcb2bd204bf5c283812ba056ac0c345e379c4ba24d750901279bb2f3a16f612bfadb35703332c7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377bc200e4d315a30a6bcc3256f9734d06e9779caa5442a9a16069081377c76e75154368072dc446ed6c8b8e622a21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543546284eda2a26b47f05b735bcdb1202220076dc8b4e4b9f853533c8f6c7ff38817ba49712835785f17f14ca01d0c1c1e98810fe0b36e5b427157b9418449cedd641a4293c85c32700102acec22ebad98ed160a5f027bd4cda57f1f3720a12c134654dd5e73f829676495390d0e7929d6034e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7a0021535a6e25e437d49a780698be22ac9953949f571b85a685725f8207a2b0ae849b601ab91b159b3df4a154c2041e776070afc42969322380917c97510799f3149131477e16663d3174c7c1caea788535c6c005a64f2868631b31b66e205fd38c1d84542d0f1b578f58c9bf5a0faeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_private_key = 07638fb69868f3d320e5862bd96933feb311b362093c9b5d50170bced43f1b536d9a204bb1f22695950ba1f2a9e8eb828b284488760b3fc84faba04275d5628e39c5b2471374283c503299c0ab49b66b8bbb56a4186624f919a2ba59bb08d8551880c2befc4f87f25f59ab587a79c327d792d54c974a69262ff8a78938289e9a87b688b083e0595fe218b6bb1505941ce2e81a5a64c5aac60417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3683c0b7b10029fc203418537e7466ba6385a8ff301ee12708f82aaa1e380fc7a88f8f205ab7e88d7e95952a55ba20d09b79a47141d62bf6eb7dd307b08eca13a5bc5f6b68581c6865b27bbcddab142f4b2cbff488c8a22705faa98a2b9eea3530c76662335cc7ea3a00777725ebcccd2a4636b2d9122ff3ab77123ce0883c1911115e50c9e8a94194e48dd0d09cffb3adcd2c1e92430903d07adbf00532031575aa7f9e7b5a1f3362dec936d4043c05f2476c07578bc9cbaf2ab4e382727ad41686a96b2548820bb03b32f11b2811ad62f489e951632aba0d1df89680cc8a8b53b481d92a68d70b4ea1c3a6a561c0692882b5ca8cc942a8d495afcb06de89498fb935b775908fe7a03e324d54cc19d4e1aabd3593b38b19ee1388fe492b43127e5a504253786a0d69ad32601c28e2c88504a5ba599706023a61363e17c6b9bb59bdc697452cd059451983d738ca3fd034e3f5988854ca05031db09611498988197c6b30d258dfe26265541c89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9790a26d17b0398a26767350909f84d57b6694df830664ca8b3c3c03ed2ae67b89006868a68527ccd666459ab7f056671000c6164d3a7f266a14d97cbd7004d6c92caca770b844a4fa9b182e7b18ca885082ac5646fcb4a14e1685feb0c9ce3372ab95365c04fd83084f80a23ff10a05bf15f7fa5acc6c0cb462c33ca524fa6b8bb359043ba68609eaa2536e81d08463b19653b5435ba946c9addeb202b04b031cc960dcc12e4518d428b32b257a4fc7313d3a7980d80082e934f9d95c32b0a0191a23604384dd9e079bbbaa266d14c3f756b9f2133107433a4e83fa7187282a809203a4faf841851833d121ac383843a5e55bc2381425e16c7db4cc9ab5c1b0d91a47e2b8de0e582c86b6b0d907bb360b97f40ab5d038f6b75c814b27d9b968d419832bc8c2bee605ef6e5059d33100d90485d378450014221736c07407cac260408aa64926619788b8601c2a752d1a6cbf820d7c7a04716203225b3895b9342d147a8185cfc1bb65ba06b4142339903c0ac4651385b45d98a8b19d28cd6bab088787f7ee1b12461766b43cbccb96434427d93c065550688f6948ed1b5475a425f1b85209d061c08b56c1cc069f6c0a7c6f29358cab911087732a649d27c9b98f9a48879387d9b00c25959a71654d6f6a946164513e47a75d005986c2363c09f6b537eca78b9303a5fa457608a586a653a347db04dfcc19175b3a301172536062a658a95277570c8852ca8973f4ae123a334047dd711c8927a634a03388a527b034bf7a8170fa702c1f7c23ec32d18a2374890be9c787a9409c82d192c4bb705a2f996ce405d85a4c1a1ab9b6aeb49cce1c2f8a97c3516c72a00a46263baa696bf25727719c3216423618ff33380934a6c10545c4c5c5155b12486181fc7a2319873978b6a2a67490f8256bd2196fe1792a4c00077b812eae8bed3572499684ab3371876761e450c9f9d2768a36806d7ab2046c91f17599e9ac592990808dcd7b4d0919072f14ec361773b7252444c323c308326f4a30f8680d2f748f56a132b82674ed0184620b82ad2cb182c97b481626647491290a011cc73828685a8c367a5b9cf8d621b0d5c1eff03172758bd004978c251cd51342228989cae6332ac486437cb5c57d4307462865253be217b3515c73df405b7f28217ad0b8cf60c2fffaa0a0048b1fb4acdcdc38b5250cfec356a6de26cfa7a588fdc86f98c854ac64c7bfaa96f5a32cc0610934baa6a586b9a2054f13ba274174aa0d2b3a81b96a940666f789b5a6bcdc0a6a0178a0c9a02578a493f6eea0d2e6c13951c9f249a5e8dd71dd49a742d451f1abba19af8c547855e0afc728e90abb499c9beeb766f4729cda22263e324d22302cbd3399facc630991fc8f28bdb4354762541527678bcf61f65c241146c426d23b9bfaa6b7df18c97f20c1b6125bf874b1d89475852c448215db0eb7737f91480e8cebd9a0871574f5ab62d9020175ec6927ca0b54c09818e42cf92a383172422c7dc1831d63b0c295de75159db8034e9e07f7b0b910c3c1e5fb66b3dc523f1fa6eb4910cb89a6c17562c83ab4c18d0cd7e0796592a372aa409b1c557347ccacdc4644a119064d06dd474929d1c6fb4d686e5491ce4bc89a30bb4b8c41bce5157dfc1360823b1ab618c14b10f98c25067398ea7018c278a4b3df31334d603b2044ef187cd9bc6ce42725bd962c264983e9e18155a8b9c47143d70460a26a56fe7658c1f150348c6087ef758ad167887860a007a5fc37358d43b5ebee820acea474f0ac07b76802866199c61231d5c747c93774d2c1e0c1c67e6c81b82752173e125baf39b4fd19a4f453dc57976b1d97fe6996992bbb65b7cb25d077bbaa6a13322899af659cf1b3558c1b5001154b625809ed89aeebb89e6ea7d67f723d045ab05715c42355da6a5c8dd39c8abe3037751a01ed1c7374919f3121b5a52c53d1487316769f80721deeaaad3c90f76e7ae9e12ba92b32b5fd457e3c752c2650dfb885771cb77ac3c785a8c562e6a1c63c2a55ea47cf8b90eb8225c123c346452566235b2f31823a33521e087937a345d8d663eeaa05658917bbaa008c2e335f8850a90a326d0e66432f44ceb8289e4ecb2d12958e984072ecacb88e1348ff0b55654acba5b54971cbaeba88ec4b91a94c37192fa982becb9f3da421603b61a51bc8e36cbd053851c77b1b926b17a272aa9023246b02b3ed47f66a00bd5684823634e7ce58cf8f306e35b1e5322824d904801f0a2fa7c2bc9c252b0a56b7ba2ab0f636021745a70a9a43e2b0a8d615970b65309624b5184bcc30b911679aedd76025fe3908fd67897b0cf4be5a6f5413d7dd98564b23e42a93e4aa8821cd45054c643edc1158db6b3deb13fb5a51ebd1a8a78b87225a7338e101104c4a220d9bdedd48c85a1c2dae781a80c40e13b87eac73a764201c9b760ccfb1ae392699c7039d27c39362b27b8fc6f07a8a3d4410f1547c48a9997f62c61074452ef1515f8a649ebca9437205a4e8a61606b41daf6834d671f4d852c0c9c4096611648c6a3170678b1537cc1828d93580c9e5849a9653175acb753f2be7437be45f6c603e485f2ec301bb42b6c37c225d7495a584ae231890ab5c8c35c268cf4bbb0213c096019319561a8a6947637aa40d006b415bb2cfa2237e0890b6a3bc134abf8f6585e108d15940f91f4bf5b0c818055b21dea6e63b553988c47f4b94e7cf800a493b4734705edc56a4b6021c629500675876804cf0b951f038a5c7fe58e89774ef2992fd7c63099d352a7d21560b788b405709861817e59a96b3a3a83cba803b16934331071905bbec6532900155d8ac88cb32e4e21a3bd3a03fdec325a51cd2773964e6784fcf1853737aa64eb67564727272661abf84313a57a44b123c65509cfb7a6f6641cdcc3b57fe628c7b8192db44ffbf5796a8613b1fa126f6076883c783dc24e2a4464c40b3a41ca70ae87620866cf4fcb2bd204bf5c283812ba056ac0c345e379c4ba24d750901279bb2f3a16f612bfadb35703332c7c136f68eab6755c66b6a4ad1aaba7b768a58acaacc10a459a1cc8ef29377bc200e4d315a30a6bcc3256f9734d06e9779caa5442a9a16069081377c76e75154368072dc446ed6c8b8e622a21e383cf9ba1fb434e2ecc81e7b78cee986b8ff798ab18cf9634543546284eda2a26b47f05b735bcdb1202220076dc8b4e4b9f853533c8f6c7ff38817ba49712835785f17f14ca01d0c1c1e98810fe0b36e5b427157b9418449cedd641a4293c85c32700102acec22ebad98ed160a5f027bd4cda57f1f3720a12c134654dd5e73f829676495390d0e7929d6034e9c55f7d55ba658bc587988e8af94960f6cfb8d5af7a0021535a6e25e437d49a780698be22ac9953949f571b85a685725f8207a2b0ae849b601ab91b159b3df4a154c2041e776070afc42969322380917c97510799f3149131477e16663d3174c7c1caea788535c6c005a64f2868631b31b66e205fd38c1d84542d0f1b578f58c9bf5a0faeab6ab6494893053165eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539228a39e87d531f3527c207edcc1db7faddcf9628391879b335c707839a0db051a88626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +expected_public_key = 05d918331371de92c27a1a5ece876015a959e96aaf3b1a60e9e77e46d51d9d85aba374263bbc65ad78b2d5a53cb909682aa0bf37d49d172bb46a0271d30716cea8aa095992dbb1132e81265a29435ef2c51daa9f27fabf3a799813e67efca087ac12247b64cc0ba15a5486245dec1648cbc7aaf40805115d78f6687c47c553d050f1e6821b368f98da22f4aa7d738a81b298a81bc43e16c8ce1490147ca83d2dd98bb918300a26cb431c99a952471b84bf6118a4d5c0a898532cd277bb4443cd7b6924c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7d31921a66403c587c165bfdd341011d19ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fba176f9bb8dc7716cac344684334c5704d5a54c932535739948acc61bd67b581f75a2169a89a11076274b10563141722c9aa9a34bb28a69ad677292be84455b24559cbbc0f347e7b36a45555a8336b8adfa07e599633f5d1bb6adcaf86ac9e7885039a3c1d308996ab6c966f017f8297009c9b4b573b70da8921a0c256a9a03c0cd6a4f72c6edb5630b1219c4a3c30d1f1586cd936e3437684ac60efa62d0a345fbc4881b24372b5692c101195c66c3ad647ca04d37f91f813a7a6795b371a574565e14779772372cc4a79c40308eb1233ed643808e939f27571c72b2f719023e048c4d15c71b3e116482c413a816c6d3a3877f862559b4afaf04df9c62d02cb364aa2adc64078b8bcbefe043bd6f32ff62b9555fab5c1009cfc102b9b4b88b8a93b66e3a65a62b184bb5406dcae7b3ab6047754bd215251ebaf102356ba688095a8c9eb1a9d8771cf60e864b7b4a5588843922b6d4a7445476997a6e5620a528510439b02a4b0de9c147bb14433db144fc9ab4b4128f7291a637b7e609a7de058a3b58a17501c833be09143244cc7e2490eb01cd292454523ce413a6e8cbb67a464aef43912b4559651258b9b812989093540dc8d202c652c71cca1eac46eab3f9ec199eae025b153348a600b0e373b7cf2620f5560a3c64c15ec85b5e81c0bcc4840466c63cb124ca45994babc31f12486f3712d22b1f649a07b192a2451cfb079ba179c2b857c41c4f8842a916e06f9c6a07cc6a4d2821401a65060688713ced4bb72c08241aad91b50bc1b968bcf3bda76a8e1b20060975e8803dd7b762d9a49b988568cc575a6d34bca13a0ef701b823296ff114efec9031d79a20f6c640d4519a1906183099926d44e88703db7636e19394b2f65abe9a8712c868697b46871d830bbc09ae02487e8d59537c3841d5b080f503aea769b0335493b84b94c4a498b1a6e6acb578201bcbae6baf0e960aa975d3f14b5179051d933c4109361f03461f265274f72416df79d1187b6822a0c38177a02b4afdd635324eb6737c11a631784916452c700d09aac42ea2634abc68bd3f41a2ca679546414df2314d57c2b318bcb98d7b46fe1b5a7e3af1b2047d193883cfbc6e7d29049fc9c97b344736a0a48082b0a145aa8776125558df656718af59964d42f0704318db88d1e91b840690b96669c8851bdbeb6043f04c017b59b289bbf550a94d0aca4aff18ca84630a99b82711a661e8b202b976e65f53b5db52b255a88692852e06bba321b4de782b5d951ab02eb27098813c98b0f7cccb778b08704a068b4d48afb30274c0759fc5bb86fa59fe61688296846b2481e18a05fb9c02931570596ec436f570c187159b25c1f6341163b79670f62334c6b9a7139044a8bbd2b5183e0f82d3b6666735a94478784aa6168d0d3272876b5476b64f7932f3aa4151ca9b604bc7fd5d1395c3708908015b0d2c8cf04858eb23238458f70f964687bb2137a0c75c06a868c3490166cf2bc3afe9b3746e40c231b3638a3558974bfb0603cf4c28c21003dfe87b3eb959dfa715b78ecb71bf404cdb2b675160138a46501569918cb7deeb0489a72a4799a1a4ac625d5c6021f51c357895ccbf26fb5aa372343bb1c516ceea47683e5a4d094a3d5188270811751fb1e19d68ef637227e491cc6387760eb5a810b387f596aa20741c4627b1c13a303d160423bce1e422d929c06f067adb7d96112f1607d3c7e43e7aa09ea248526c6881901852123f1b734a8c1891261bae6e7a23dd5296858b6f7813196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_private_key = 94b49ea42526935245c45a7d580b6aeff8bbe0f5342bb8bd2550212ad5935f45cba7caa6df914007fba79e9946c9433a86a2c4202bbdcea008af78975e6619d3582787530dbb7318a530b7b5a27d24258c7ccaaaf505ca92cb853a5818d4269be812becf169a05e71eb957557787c2f3b72315281dba87476b157a06095a30d52b388ac22840755b43440a931df8a709dc435b415a7babbb04ccd93cda00ca1fb090646b1d6514813368a794d38c907163b5917496b018c519b160c5144d6424495626e3a5ab9ffb8d8d3168d77599a88a1d12c07d86498d88dc1af7fa7de15073fd4b62801c1a902b215e7cc3eac350bb63adeaf9c7594844795a9a6274aa3eca0cd10891f05795a77b30add76b6b1a35338b8156690ca2ea1c9c3b602b23324925314f726535b36dfb355225d37e7c85be15a5976a8a6ad4e2c35d4c45acc954368ba6df88a47dbb8c782336f7ea507a6c2d26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b692729638af69b03e6db9b82e678a42969fbe770fef65723f77da6437c20b203601c884a9b9e08c0b1ddbbc1a66517dcfc76b3f125f7795e5ddabef0cb00119778575513e05ac38a7901a0e8c8794685c0f274050097bc50168818a74aba5d71980f5c76279ec0214cd51efa8a21391567fa052e6dc0cf9bf216cff9287c80693645a53d71b3d7509f6a432d51b2b0aad129b594278da74ffacbb713357d735a744b7c65e482b7e172c67a5b4edabaae11222b8bb6b4564ab4fb20c28b4981614b69bb188db6056607e089f64803d89210c7e604266b00548a2ae27996196a6d6f762c27b22731f7942543ccef3856edf9ad1b1b1652a33c3e038dd9b2cd9a4612ce174315e67b26dac767e50e68508d104bbae1a2b89b78266d27b109f90bce1581a8b8888c90c1c4ea5fc1f009d5073780cb4545087c88026b9b9abddab923db52620713c8b5ac3301e8715ac39d13084926e841fae41a7bbb7912e10680a78c0c363a251720b2d69467b6cac5d894f862595072a7c9b14bfefaa2fdcc75cc42892cec6184b52962b9b73d663b7d76c1ea499d538bb45a4caecee0c8eb93bba5ec1a8c936156382b10102e3211b2dc15663412805f60590ec33dbab80d2a3bc05fa8af5145644f712e004c20f799650159c40dc952c9a54c27e816c3a6a95efbab24a31f6c402300f9baf88a46644b4df8a24979e80dc30425b9e75a753a36510b87c5fa95cbf36e19a12245876003b54d4e008ef7ab9d83c5a2406014b5cc33b6167f4c452af45084b7412ec19556d82b0a6a90c1aea60a72312d8a7a8e5060189717094ff950af2b503988964f0aa227c523487471d3bc905b6672be20bc714729b7a71478b07a19f777dec546c624723af7b5f6c142274ac5652a7c2d7abbf1171f2bdb12f1ecc876681a600806d6fc229e6a8f6424419187bd22e49b8f27486db25371c169b3f61e81131b57659b1030a959790ba5d6424580b1f588326db9cd01a260b21b8c42062b883854fb173ea7613764d41dd6b89468c7ba6c4236d1a0436b945b8b340983023139293fc48c07659b955453bba07b0eb4e2a91f594232a47c65c66e1c5c8279f179925c55ee3a0b3f5423e20a8620572a687c2b64b6ceccb5944d07107648ba73a19fdf6bb3f57c5fa079536c675ff17a6dd22439c8d968f2e3136d3000dd70c5db6aa212a63c9e16222bd39201d9b64534c87aac3b53b357bbd522660caa73b02ae4f45e1b9868ed45cbf8533720f99a1282338a107647ecc8008ab2fed262512a059ac6073264817e08332f9c8031c9913f2339169851d7b746ad9a8f2f54633d470c3376302250a3255687dee61c2625aa9cda852d835ec95c4348c9be74473049abadd65ca055239d85dcb11e6297e1667ae548664d6bb19b347288d57e3de27369a52ea25150675507cd5282cc4875fd8c67bf29accbc296e26c4b4ac813877945de0a52c355526e2404d1f262a2505dd542bf3dcca6f0121a5a45b77b419094408f409261e3c25f90689a5680b146fc6b1b76099f6cad427c6ac4281db70b34cec467ae35186d6195574935a1387c5dc795523257482a7210e1009f5337d773b2708c694359a517152168775695acba0735be594c8390c760070c4912e37ce33b3bad965205d918331371de92c27a1a5ece876015a959e96aaf3b1a60e9e77e46d51d9d85aba374263bbc65ad78b2d5a53cb909682aa0bf37d49d172bb46a0271d30716cea8aa095992dbb1132e81265a29435ef2c51daa9f27fabf3a799813e67efca087ac12247b64cc0ba15a5486245dec1648cbc7aaf40805115d78f6687c47c553d050f1e6821b368f98da22f4aa7d738a81b298a81bc43e16c8ce1490147ca83d2dd98bb918300a26cb431c99a952471b84bf6118a4d5c0a898532cd277bb4443cd7b6924c3185ce55cadc7f877be93306357ac71a67ddb4c545fe7301d339e933b81ac145988369fb7d31921a66403c587c165bfdd341011d19ee964b62e4c8cad2b88e8dccf3ac75cd3f835e2938d027c6789f54d0fba176f9bb8dc7716cac344684334c5704d5a54c932535739948acc61bd67b581f75a2169a89a11076274b10563141722c9aa9a34bb28a69ad677292be84455b24559cbbc0f347e7b36a45555a8336b8adfa07e599633f5d1bb6adcaf86ac9e7885039a3c1d308996ab6c966f017f8297009c9b4b573b70da8921a0c256a9a03c0cd6a4f72c6edb5630b1219c4a3c30d1f1586cd936e3437684ac60efa62d0a345fbc4881b24372b5692c101195c66c3ad647ca04d37f91f813a7a6795b371a574565e14779772372cc4a79c40308eb1233ed643808e939f27571c72b2f719023e048c4d15c71b3e116482c413a816c6d3a3877f862559b4afaf04df9c62d02cb364aa2adc64078b8bcbefe043bd6f32ff62b9555fab5c1009cfc102b9b4b88b8a93b66e3a65a62b184bb5406dcae7b3ab6047754bd215251ebaf102356ba688095a8c9eb1a9d8771cf60e864b7b4a5588843922b6d4a7445476997a6e5620a528510439b02a4b0de9c147bb14433db144fc9ab4b4128f7291a637b7e609a7de058a3b58a17501c833be09143244cc7e2490eb01cd292454523ce413a6e8cbb67a464aef43912b4559651258b9b812989093540dc8d202c652c71cca1eac46eab3f9ec199eae025b153348a600b0e373b7cf2620f5560a3c64c15ec85b5e81c0bcc4840466c63cb124ca45994babc31f12486f3712d22b1f649a07b192a2451cfb079ba179c2b857c41c4f8842a916e06f9c6a07cc6a4d2821401a65060688713ced4bb72c08241aad91b50bc1b968bcf3bda76a8e1b20060975e8803dd7b762d9a49b988568cc575a6d34bca13a0ef701b823296ff114efec9031d79a20f6c640d4519a1906183099926d44e88703db7636e19394b2f65abe9a8712c868697b46871d830bbc09ae02487e8d59537c3841d5b080f503aea769b0335493b84b94c4a498b1a6e6acb578201bcbae6baf0e960aa975d3f14b5179051d933c4109361f03461f265274f72416df79d1187b6822a0c38177a02b4afdd635324eb6737c11a631784916452c700d09aac42ea2634abc68bd3f41a2ca679546414df2314d57c2b318bcb98d7b46fe1b5a7e3af1b2047d193883cfbc6e7d29049fc9c97b344736a0a48082b0a145aa8776125558df656718af59964d42f0704318db88d1e91b840690b96669c8851bdbeb6043f04c017b59b289bbf550a94d0aca4aff18ca84630a99b82711a661e8b202b976e65f53b5db52b255a88692852e06bba321b4de782b5d951ab02eb27098813c98b0f7cccb778b08704a068b4d48afb30274c0759fc5bb86fa59fe61688296846b2481e18a05fb9c02931570596ec436f570c187159b25c1f6341163b79670f62334c6b9a7139044a8bbd2b5183e0f82d3b6666735a94478784aa6168d0d3272876b5476b64f7932f3aa4151ca9b604bc7fd5d1395c3708908015b0d2c8cf04858eb23238458f70f964687bb2137a0c75c06a868c3490166cf2bc3afe9b3746e40c231b3638a3558974bfb0603cf4c28c21003dfe87b3eb959dfa715b78ecb71bf404cdb2b675160138a46501569918cb7deeb0489a72a4799a1a4ac625d5c6021f51c357895ccbf26fb5aa372343bb1c516ceea47683e5a4d094a3d5188270811751fb1e19d68ef637227e491cc6387760eb5a810b387f596aa20741c4627b1c13a303d160423bce1e422d929c06f067adb7d96112f1607d3c7e43e7aa09ea248526c6881901852123f1b734a8c1891261bae6e7a23dd5296858b6f7813196f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2c9ede13be3dbb0edc3ab08226cae11771ff4c0b04a564b64a0d9ff10e373e986003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = 4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +expected_public_key = 042b035f126c4fca9e059972fe92c9f4b3755648b5b2b7784d55a62e9b101a7a059cdc2f3f4b8888fc3a56cbb1447673a406c78e9a045df1be84da17ee2350b64c0d3bb63965328d16b3c446214c58731ce3c405d3d251ac560d0d9108e3bbb268c6931fc49d7b454594444dae401b2fa3011bf3c697e67ad9c1540ea945ace6c98d49321dbc36447858d783bca93ca67132800672513e577d14607cc046af9bcb4896f2bb39a0208405b3734505b239967ec72f8e8b0c2bf06228bacf834029dd123c83fa3f8f83892b504c1a11b809a9acc494c5e5c79c18401a41a6af6632c11266ae5821b3dc7c263e1b5e33a1a7bf172d6d142c79782e20ea38d6e791ad3b86517681ce389620562bdba89898679ea0c748d90a963e738a3e9968f3648e984c99f0e04c952309111396d112523959b9baccc43df715dc94ba3253332ed27cccf56f5812200e8c7e2a11ae02087e0fdc4389e98eb0ba5693cbb79680a6124074d3c998d911ae4e142296c0ca245719467402124574f8d271624315359c7842c761bd6057b92b4640a1703200cedcacbfe0e475f7316ccea74b74257e37c63035f04a880910bc042802332ee8b3c3612290c45793cfc5581b92236b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab999031d470aa948665aef9974df5a2fdd93bccb74762a0b7c2fab58430942f900de1c835c8b9cd42d521e54c434fc240add0b23ca1aaab0581ed9a593487b95a16353c0c7adabb285c85105a667af674344c3666da142049413973051268d94cea41c3cc9682b791ae17f0696df29f7f559375965f817a8d9a3297639017f5624f9df1b259412f89a8c88a361940ec9c3045c4a78364e1e06fa95500f5ec0704a365f4698b2f26a7ee348806b74e1579c2a466ccea209e515302493443f8ba9e32d04e03a7557380c7bfc83f191b84093c98aed14286f762d3b5513f996481d5445c7a7c931c1b9b52bd86e0b3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7e40b93b5108861576b3594966c40860f74cc58b9bacf51a5db6ab2d4ca43d964ffd831130b21457a08af7d8060f847e3695b8a7e8c9858a70d521908ce1c38c0713469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af944165dc9597392a6fc2068297d11c39d8648f550a7d157ec4b64c631a7ba7b94c6cd7083e21b149b484817a6f93e011a8e76931da4921e08aa604756c0bb63f897afdb8c6112a4ce21b2cc1935dc6b38b6c4473e2b0639266386ca988456ac843a1084c220b74f72b18199ab17aadf0960f50db4dfc7bb3454a9b29e74b09c410362cb8a5516e0546a3b09356b520a303e284569b2df6d263ead36ce75c82f6d141bf7c3e5b87b3eec630fa7a65a4c58676181916cc23e0c6a0339827571930bb65089376ba4bf60f4ca71d7090614f468732e60989298384a93849031a989488e144be739a78e1c49cac60af115c55a6501f010c100dfabbb462b1b3b6469c8b0d8b91061bea5da74a28d17cba84f04d2232076cc91c8bb21fbd558426f99b00e13525e37c23520698e0310c8a53c6b36192d82837ba0d3ee27b059b3e8fa1a315b64ca5159de3d9be0fa0352b511d1a803c79668479a1c3561a8ee6f7aca9ab4c861554a5b81b5e6115c952b3239595b9782fee01b869380ff09cbb5784811966b864d0414249b7dd0b53a762155170990911192e37c6c7263be626084118266bf7271356bb66d35aea64c5ea913db432c3caf989b0ec702139504fea41fcc782808bbf26d3b12a962d2b1a142c755fd1acbb802ac9b93713ee71af9d4430f240c7fcab059cb435a8373633417e79106a274882f5d40a4bd732c1e8202e41131497721792ac464b3b26a6456a9374a5520054e50cdb06a32b3973aa948a37e4798544020a7ace817749cdaaab1c7713b467a77593c034c20de0a9c71c712d6529820a5b3bb4e76202080a5e5c7ca86bb78c392a39aa37a91b4e75b3c5f2e56211358cd5aa2781ebc548e21e5351209b7a7d871a782da1306883a4b6b070a06b97639a3ca3273d1218a8000b7e85d6011000ad018527a25059c2ca252e5726629b0800b85ffe02745e9199a705d0cf4879719a53d33a95b2cccb52c1c9655419543aa146241b98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_private_key = 72408d44c2be6e83c803da2846d852dec1848ee41504b5c91f774f6e512b51f71dd1520203c486f63240bab4c1dbb212299753b8627f9bf2117cd6a83be4075a385782ab804a420972eb25bc553eb981aae7d7a715111338529f6116c10b10bbc20b31c3161d4bc1a5f050220b5584abd6a546ab51a9a10120ecc131220502697e9d61bdbad346fc43824135692204b49b5b377b870b7b28c86946077a215acaa11abd851eca479988bc69ccc9975eb42a33523c525434bc594217912123957dcdc18e410a6d6a811bed8a0b4135b56f4562f343aaec34396bb0556d7962679a76934b016b4b4bacc14650c55c3aec9bc2e85b548b5d3eb891b6596f0c44009bd0982d98bf81ac77c8da98264a719cd8568e48279df9c8e9552b94aa773b43a70742c75f041915752551347f00447d72d934bec553bf1014f4276015e0b4db77cdf8c546af05861804a5b7d92838744511ac6c8be55e883acb7775b98c4b4c9c8789aee317f8f02b4127a6ae879d02c13772a003928041c53351d8d70ce59b14cab5ca31d717f69129c8fabe46582ca5298ed156209c25bc57870eea34255ce1b4c426211f957d74876dec169c4c516c8716b3ddec6c3e610c31f0c52e13650f0b1c70124dee27111a76abef82c8fd3172d554121e6a87e9d3b58e11379cb812b7f4b95d46104934ce75c715771204d7c46aa9439836453bda709cef3bc1c9341994f25c48b5c80fcc8a67e316c431bd302b20904456b3283e9ba1bdde494ce9f8a3f0b432dca69d0ba9c43c703e1616272cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b7631822c529fa48835f8a08f322615e96b9087c71c9f262b68851f00486489d25c92221c2759c89440ce733614b8c7a06f26b374cb4f8a6a7d67da521eba7232c0a4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d09f212c9330c83990ab2db7095d708b6c3589bf929fea31534646537d2ab023887fc286f00f46f8a360476998e4fe7315f03c234929247bba2a05297a5e01aa9cc6158458e2302513274a2e3359d66126f5fd44d348ba2b634642ea26c6cb616f64a2d2c819abaa48bc565ca0ab67e6cfab1129a0144c10a003b44bd3879b4e62e0ad3a58bd86a7030be34309f3309642b017b0aa03ffab4012b36adc49a95ddba67cd81306ef6bb20b546bcc55eac2b815fb38bae991d6ae7aa87d42ecbc740cc816a3ef42e9d204ca0177cdb30cdcb870386c320ff51b137578b029125ba518a5b887d7b9050dff113468608f6335ea81a59b87cb753724ed0e159fa4709ac018a31194247a6a9c65443a35ac36e11bfa6a8559cf20e50116ee5fb3780fa03dcaa77846b18c04894e50486acfc3b8feabb8cf860d79c2734a700ab731739244580653699b51b7fc440b8cb1d6bb1360291bda5b11aeda3c77a25b40f96763a372512561e0d52848fd6a3a8241dea49c4c24692cb43aa22067072fac2dff7898f298cbae17f9ca68a132321932295161a1f31c178932004d17854d7d9c69f6640ee216747102280191a5695433763b6cf3b86756aae22a37f9f6920c361c2ac68a7e11c8f5505af2100651595bf93b2644ddc8d68053cde98863922230f89371683bddca6bc63b8c61ff4932a0885213234d5004ee9223745117ebabc5e149a5184a69836c69670e81ebb94c5abb711abf91fe3970f805b9ed7d1648361153b2911c7e20186f90907f28602672cd6c383eb373375924e832a156241bc7c5b231d74c49430c1d5fb7dbe49c6f7e20baf245d43c9b356a1be2a63ba24d4757dfa960ea61a65611cddaca48d7aa88402b0fbe16279445c8e663db1d8ca70dcae63c120df1c9bda547272c396c29cc93f0c3f002642b9d18ba0b87198140c93b55965f8c15712319ec6a95b384182618e08f134dec88732407de7ab934555af4f267051e221c4d3a0471bc6e3166bc24270efc54b5f9358d83833c295b1a5791c6bcb0610fa33d49a70232488b27150f74cb99f3643d5c6acabf5c18166cbb5ba55b4b78400e0bcb7205ea5591df6f803c464c549729faa7c9b75985088c8cff068890425cba4a2aa617c7d416b77e6c618d3f9112f3b9546a99090a1a499dc613323c0770923a917b2aeac15aaf9a7042b035f126c4fca9e059972fe92c9f4b3755648b5b2b7784d55a62e9b101a7a059cdc2f3f4b8888fc3a56cbb1447673a406c78e9a045df1be84da17ee2350b64c0d3bb63965328d16b3c446214c58731ce3c405d3d251ac560d0d9108e3bbb268c6931fc49d7b454594444dae401b2fa3011bf3c697e67ad9c1540ea945ace6c98d49321dbc36447858d783bca93ca67132800672513e577d14607cc046af9bcb4896f2bb39a0208405b3734505b239967ec72f8e8b0c2bf06228bacf834029dd123c83fa3f8f83892b504c1a11b809a9acc494c5e5c79c18401a41a6af6632c11266ae5821b3dc7c263e1b5e33a1a7bf172d6d142c79782e20ea38d6e791ad3b86517681ce389620562bdba89898679ea0c748d90a963e738a3e9968f3648e984c99f0e04c952309111396d112523959b9baccc43df715dc94ba3253332ed27cccf56f5812200e8c7e2a11ae02087e0fdc4389e98eb0ba5693cbb79680a6124074d3c998d911ae4e142296c0ca245719467402124574f8d271624315359c7842c761bd6057b92b4640a1703200cedcacbfe0e475f7316ccea74b74257e37c63035f04a880910bc042802332ee8b3c3612290c45793cfc5581b92236b74a4f3f4bacc9ac3dd563471838d11758db06461061acc84d99f29b858c339ab999031d470aa948665aef9974df5a2fdd93bccb74762a0b7c2fab58430942f900de1c835c8b9cd42d521e54c434fc240add0b23ca1aaab0581ed9a593487b95a16353c0c7adabb285c85105a667af674344c3666da142049413973051268d94cea41c3cc9682b791ae17f0696df29f7f559375965f817a8d9a3297639017f5624f9df1b259412f89a8c88a361940ec9c3045c4a78364e1e06fa95500f5ec0704a365f4698b2f26a7ee348806b74e1579c2a466ccea209e515302493443f8ba9e32d04e03a7557380c7bfc83f191b84093c98aed14286f762d3b5513f996481d5445c7a7c931c1b9b52bd86e0b3943cb70a16c9efabbf4c7c80f1f73438399ffb464e7e40b93b5108861576b3594966c40860f74cc58b9bacf51a5db6ab2d4ca43d964ffd831130b21457a08af7d8060f847e3695b8a7e8c9858a70d521908ce1c38c0713469c3d294a7fedbc5c5446904dd76733e58f86693a7ec4af944165dc9597392a6fc2068297d11c39d8648f550a7d157ec4b64c631a7ba7b94c6cd7083e21b149b484817a6f93e011a8e76931da4921e08aa604756c0bb63f897afdb8c6112a4ce21b2cc1935dc6b38b6c4473e2b0639266386ca988456ac843a1084c220b74f72b18199ab17aadf0960f50db4dfc7bb3454a9b29e74b09c410362cb8a5516e0546a3b09356b520a303e284569b2df6d263ead36ce75c82f6d141bf7c3e5b87b3eec630fa7a65a4c58676181916cc23e0c6a0339827571930bb65089376ba4bf60f4ca71d7090614f468732e60989298384a93849031a989488e144be739a78e1c49cac60af115c55a6501f010c100dfabbb462b1b3b6469c8b0d8b91061bea5da74a28d17cba84f04d2232076cc91c8bb21fbd558426f99b00e13525e37c23520698e0310c8a53c6b36192d82837ba0d3ee27b059b3e8fa1a315b64ca5159de3d9be0fa0352b511d1a803c79668479a1c3561a8ee6f7aca9ab4c861554a5b81b5e6115c952b3239595b9782fee01b869380ff09cbb5784811966b864d0414249b7dd0b53a762155170990911192e37c6c7263be626084118266bf7271356bb66d35aea64c5ea913db432c3caf989b0ec702139504fea41fcc782808bbf26d3b12a962d2b1a142c755fd1acbb802ac9b93713ee71af9d4430f240c7fcab059cb435a8373633417e79106a274882f5d40a4bd732c1e8202e41131497721792ac464b3b26a6456a9374a5520054e50cdb06a32b3973aa948a37e4798544020a7ace817749cdaaab1c7713b467a77593c034c20de0a9c71c712d6529820a5b3bb4e76202080a5e5c7ca86bb78c392a39aa37a91b4e75b3c5f2e56211358cd5aa2781ebc548e21e5351209b7a7d871a782da1306883a4b6b070a06b97639a3ca3273d1218a8000b7e85d6011000ad018527a25059c2ca252e5726629b0800b85ffe02745e9199a705d0cf4879719a53d33a95b2cccb52c1c9655419543aa146241b98f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751ddff2546623aee72025fb6746fba736bae0e80e257e66edbf09d8d4dc11049cda4e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = 050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +expected_public_key = aea72a5c370048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f58987730d4becc9de18019e5142f94984fd0a6d84a8930bec6d96d413bbe97b14138e95e05cb05345c86b96aec66babab7cb8a2ad8f774086918795c39e95ea3e40384edfb1ad3aeb931419c1219286390b9cd2154348ba19ceb280c537353b701976236414f21939968190892001d10f8ea83ca16803d2ac4cc5a96cdee3a424c935b673732b312aa1d722f303bbd5175ed83087cf856c15364958b678e74b3618cabf82ca58befa00c6462b3c963edb4a4b509792f890b228c7ca68082a8f38c388839190942fe3ba6224c4c58fec51ecd52d044400f8eac86cfa6904aa99f47712ff29c3f73b02d2127f1c687a00e2c48bc032cad5b261b94fa44649c5b459fcd18d4014c34a3978f6ca6b9d667e5d93b87feab5c6f36472492b1dfc74cc9430d1818c0cc90dc947b01d33cb0c086849f81b570a407e5248a3527ab58074ee52313e678fd5876dce81860b4b06f22768e3e26a3ad450da516224e06bfee2235f8631f2f7697e3638d3911bea2bb486667336e4072c061180a886e45144fb266643ab524ab95baed92c1324045c7768465cc177a6543376be40e132e702318ba52eb10837f0bbbc64e10b5079a24564bb950915701a06bad9cf1f0662c63bcc1ba31985149c2cf79befb710528b3f3a1406869872be1c59bc011294ca50837852f6567f6cba9b5ed028bda8aa4ff26af2a4ae90eb03c65a7f03c61baa3008480b8a006c29d6a2b52e2278659ac2faa877422a3e0809736b576564d800f5287c5a73c27a9c1e1748b159dbcbe9f566cfb05fe76419c84321b8fb772597262d2b48f9c43bfd2a110bcc93aae57531c68bb222ccff36b2e8466fcceb237bdbc336e855755b25eb4784ade55cd54b644f6404b549a2103b31a0433363337ee7e520db9a8929f607368a090fc77aff437020109001b40de05035394a7032524cd8395916bc2fe12a7b9fa2a4ff93000cfb3077c23105ac40ed0162d8fa6e22a37f9670a4c686a93e556ad82509db3aa2074a47bd9605184a9a1f82bcdd033116e046ce58a9e639c8b506cb5c17129b3079fa96cb625115ea887c11a7aa7484c03ecb793a07adadcc25e2e876fc31766ef11379738a8bbacfd46c5d53f7091e6ab6108356d8ebcb45e6ba20d36d10b1aed4c2701f6b9924bcaba7934919c2a64d340c8e9a42a98001e75b09d902714bc47252b9b15c2a08f2345b78b97077bc989c662560e94f551c3aa7834830761dbee93d343a4089c8775ec85091dc1cccf91bdf30620cc3b92c6a25cf147385d1c60a5886cfb6bee5f30bde74c579689251199ea26a15a9388cca30ad565a83ce397e07a8665b0a9286d223402059a8238137306fdbbbc2f6e4c6707534559acfb4628f803250ed8c4ecf846d8aabca027b9471e4308d727987a49fdb68a11869adf57a6f786043243608810a6353c36cffd18e1ce8bf25512a04378e8dd7a01b5c2b563902288624c25c06ea881fea70390a039b82e162f61ba6c484bd09b703a4812535427a8843b41c405c7ca0abb8e17ef4c82589945e9bec2bbf348da0219160e50c54d965aaaa4a628079eea53898778331649a8851732618bf307491fefccc7074ca2a7a56f04309e39272b74a30e526a6db5c3ffac70ce46363fe596ad5c377c7f2464dba68d42851f6f70d4b8a0b0cd52d75c48a9cd31ed8f270b36b69244237f9da28e6b0512676145677b418309d1b491cd9cc1defd06cdf9c182ef4b33610b257d68ce0b12a3f024ae0f0113ad538ece90b4a3b85bdd99c495b0fad7780fa1804953041f643183bd7083c5969255406f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d80a0b153c8b8147676a212e6ed13687941132010a83457ca155888946c8bd8506e6301f1bb78cd9a0c4ecb73eafcb2fb7b02171885b6968ab52b89109bb2941e10683f30591c322261155d0dc7b0b1821eeb75abef6023ed67e16e0ba40c78109b45cd03bbe2c800fe4b19db4a960b3d11a45392c6b088cc6cc5d8de1275f035357d3a847313eda8c1c0a65c27a743a000063ac6a89754818ef7991469a39f39536a7b70964b33d25f01b7ad9cc4fea6546f82c3648751e2b41ac410e764255782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_private_key = 548a01803a231ca63843872abf16b2c4b9ab7407a093b354f8882c6775bacf2931de0a501c5a7ea7ea5c3baa067290b9fca059d69cc6de9b772cc058470544b64b11abb77f490746384b83283740f0702e17d046759b61e75030f187c2283045b22b4f9e222ca44980dcd0a42e5704504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac0f00a6f592770d8082f6157addb170a956456c7616c856657835970578b35fa87d8f79c2ae54ad36823c6a13a4207453ff324f17d13d43a400a2102b6f6224e6f2132bb14a32fa3f10a446d7944428b66e0e0a04b204c5993c03c294927c60540f836572793c8825376332b64d109bb7273147a878ff0b0bd2808b62104515d0824c90a4e249b4ec8c0f6b572bb621b7a74089de4b49eac5a3cfb61a5d6b420779a29e1c5ae98ab30e01a0b45538c9a14ce61c4dffa27a4e462757a3bdf00c0206c5bf5233132c47b7111771daac633e22132ae82cbd616ec92b4e9d1c88e7285b84d9a12e14897a020c06832e9cab42102ab999838a93a77141d12ff068ac13dc4c685328c7036ccfc2087bd92ca5a675cfe40ae4c32b28eb770da04234a456eb889ef92a93a0d3ada8061599d99cd8a96880a2b5e440766a9c81e7a24f14c295283c333a0576b49c569c99450f8714160c4cc49828090bc2ca390094e14bd6a3011a5c038f0927fb4bad38440ea9f96fee99141c564a91f9c86dc72498f89d05b047461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a45137881c691352f6240abd2298488299331cc03b1a3106f242d2871525587888e448d0f45a61480bd7e377dd5b63e143093fcc8bdaa563264baa458649ce7fa5826e4b9b49159e7541d432143c5093a2a5bc5b835535fe7395ec556bd467a10975ce26304bb892d056a6ea4c5ce08d033e9334cf7f6750cb62209ba21f6b147ac875c3f1195d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ef0ac4b32ba7d563af40228b2957b8a95063a65bafaf86609b4bfe1127c029c2eb224465e1c178c74cb5db4c0c2aa46456761ec4a528ab2bb8f92c120a1b78a9517a29c8ee408ae7fab4fdfb1941cbbae4c3630f407a2c23c4d10a58a8e64546727153d61766d0242c5132236f637b7323905f4a7811c1b8019a808946c11a54f8ca6c16e06ad9a685edb094616a80383a79e482c611760c249988547194266000722743346d13c80f72117c25cbb48490e05789c6a5e85ecbfbc73669f249c10a12eca037dfd15994cbc450eb40868abc2fea05b5058429b6b04dce2c4e2630a13dba2bec9be9c30b9f90b45a97040a1f227200ccb4a4413c8b0c5b169830d451bc7993eb3d5b4d914a02c3183b7423d61101b0e3ac0a2a18673126f69511f27ec55e28b975e22a8ce800c37473cac71788a42cd39c26c176c9c255c4355a62c0b84cda33819a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c392791b84bdb4580326f5128556d160100622affa2756e1cbd0a0a1f217a0c198a6dc043b1c50813bcfb3c2488a5c02c79393b65f39990b610274fa77b814ba93784562e0794c179549ea0927d9b4a9e2c128a339f73e3b9d3a99a151c873c555f5e3c3fd4a59823666e2bbb92e7522098240dea1b35fe2b13e103a020e504dcc1bab6b44b3d862c35c76f29d2bae150a5959b200563536ff6cec04a3b4e82c04788977f25a6d80c7807404c47a4697b1a6ed8c903d9b71ac45962d8d4cf7b71b0f54760a4799e76312d805a9b6e508f47734619e57c9ddc93fe345818615940386951a61d83248db78b669f596c2f652b92f18f51442b23a20682a34a08cc356785b20806952003354ac7ba31a355346ca63ce8030a022ffec604593496f05624e5aa41d5fa61e4e07b76a079bd4079e645435e5058a8148bc8fc8083162b38757637b72875c6a323f2bf01c95d89dc0dd6bb6a3b800df3d42481170510e6a94eb57c3dc1b6232446459625b6f93932ba11c3b2a8b9c6a203b129ece1a76f5c067e4b3bffca18be65a3b15ac638538c5ef51cd313b1c65a08e2492037b924c09b8536134f09733f5c2966588307ef8aca7a6cc5b9c27c86bac9f9754e6772096ff68b706ccfadd711d50b4a0ed155aea72a5c370048e5b9f9e7825145a2d726ad12746e980aad5ac63b4cf86295195029f58987730d4becc9de18019e5142f94984fd0a6d84a8930bec6d96d413bbe97b14138e95e05cb05345c86b96aec66babab7cb8a2ad8f774086918795c39e95ea3e40384edfb1ad3aeb931419c1219286390b9cd2154348ba19ceb280c537353b701976236414f21939968190892001d10f8ea83ca16803d2ac4cc5a96cdee3a424c935b673732b312aa1d722f303bbd5175ed83087cf856c15364958b678e74b3618cabf82ca58befa00c6462b3c963edb4a4b509792f890b228c7ca68082a8f38c388839190942fe3ba6224c4c58fec51ecd52d044400f8eac86cfa6904aa99f47712ff29c3f73b02d2127f1c687a00e2c48bc032cad5b261b94fa44649c5b459fcd18d4014c34a3978f6ca6b9d667e5d93b87feab5c6f36472492b1dfc74cc9430d1818c0cc90dc947b01d33cb0c086849f81b570a407e5248a3527ab58074ee52313e678fd5876dce81860b4b06f22768e3e26a3ad450da516224e06bfee2235f8631f2f7697e3638d3911bea2bb486667336e4072c061180a886e45144fb266643ab524ab95baed92c1324045c7768465cc177a6543376be40e132e702318ba52eb10837f0bbbc64e10b5079a24564bb950915701a06bad9cf1f0662c63bcc1ba31985149c2cf79befb710528b3f3a1406869872be1c59bc011294ca50837852f6567f6cba9b5ed028bda8aa4ff26af2a4ae90eb03c65a7f03c61baa3008480b8a006c29d6a2b52e2278659ac2faa877422a3e0809736b576564d800f5287c5a73c27a9c1e1748b159dbcbe9f566cfb05fe76419c84321b8fb772597262d2b48f9c43bfd2a110bcc93aae57531c68bb222ccff36b2e8466fcceb237bdbc336e855755b25eb4784ade55cd54b644f6404b549a2103b31a0433363337ee7e520db9a8929f607368a090fc77aff437020109001b40de05035394a7032524cd8395916bc2fe12a7b9fa2a4ff93000cfb3077c23105ac40ed0162d8fa6e22a37f9670a4c686a93e556ad82509db3aa2074a47bd9605184a9a1f82bcdd033116e046ce58a9e639c8b506cb5c17129b3079fa96cb625115ea887c11a7aa7484c03ecb793a07adadcc25e2e876fc31766ef11379738a8bbacfd46c5d53f7091e6ab6108356d8ebcb45e6ba20d36d10b1aed4c2701f6b9924bcaba7934919c2a64d340c8e9a42a98001e75b09d902714bc47252b9b15c2a08f2345b78b97077bc989c662560e94f551c3aa7834830761dbee93d343a4089c8775ec85091dc1cccf91bdf30620cc3b92c6a25cf147385d1c60a5886cfb6bee5f30bde74c579689251199ea26a15a9388cca30ad565a83ce397e07a8665b0a9286d223402059a8238137306fdbbbc2f6e4c6707534559acfb4628f803250ed8c4ecf846d8aabca027b9471e4308d727987a49fdb68a11869adf57a6f786043243608810a6353c36cffd18e1ce8bf25512a04378e8dd7a01b5c2b563902288624c25c06ea881fea70390a039b82e162f61ba6c484bd09b703a4812535427a8843b41c405c7ca0abb8e17ef4c82589945e9bec2bbf348da0219160e50c54d965aaaa4a628079eea53898778331649a8851732618bf307491fefccc7074ca2a7a56f04309e39272b74a30e526a6db5c3ffac70ce46363fe596ad5c377c7f2464dba68d42851f6f70d4b8a0b0cd52d75c48a9cd31ed8f270b36b69244237f9da28e6b0512676145677b418309d1b491cd9cc1defd06cdf9c182ef4b33610b257d68ce0b12a3f024ae0f0113ad538ece90b4a3b85bdd99c495b0fad7780fa1804953041f643183bd7083c5969255406f1346b3a25c96bb7b1568c5bf5686b63ebb0ab9a331ea6a5172543d80a0b153c8b8147676a212e6ed13687941132010a83457ca155888946c8bd8506e6301f1bb78cd9a0c4ecb73eafcb2fb7b02171885b6968ab52b89109bb2941e10683f30591c322261155d0dc7b0b1821eeb75abef6023ed67e16e0ba40c78109b45cd03bbe2c800fe4b19db4a960b3d11a45392c6b088cc6cc5d8de1275f035357d3a847313eda8c1c0a65c27a743a000063ac6a89754818ef7991469a39f39536a7b70964b33d25f01b7ad9cc4fea6546f82c3648751e2b41ac410e764255782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258125b786a67de17d61b2fc0e85a13924398aab931896b6174089569f08b7260687de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +expected_public_key = 041a9057ebcd8df95cd5eabae5e776ba758d8ef9c8702406afeb9d82d91c06e8a27df57be2d2cec9893e9c0a678ec02e94c21181993cfd22c19a7620d9cc494394b2218a81f9cbc743047160b0a551b6c802e44d09e52ea613c5f60940d77c3aad232f9df0561f159ffc0c88ac9c2f1109a9d89ac87b4a756352289d241b8bd694a1e140f255163f7888ad1314e6208082c0bbdd72220fca50d57c65c3b05d701b567550316c440c6f90ba50a46ad9662f99c61ad6601a4a26874e30ca1cb97998a13e68683a28996933ba186f469dc903b0c46a348a1c307ab9a9a4d427730920ae296d725bc045d2807ce2cb325cbd5f6cc216a0c0bcda1e321c5b17565ed0028d68554c892a9755643a69cb721fe6296acb64b93966a1743ed298b5e348817d62a93c453318db713e95cc53f8bef7d6a5dc2a7001473851324ca0db3052448da3136347008ad8d8b6b95a62e8a48073d2634a58525dd663da939948d49da9b12b1d758bb6f328d0f42a38837675e487403148729c4ffaa2ccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63feb255360c4796bbc99d95461b30502b42ce4e6aa92120b61a283927184931fb6c98727cf4163284732d62216b653c633659045549a40bb0c7c0a64adeb841596516bcf97e6ca33892ca8fe6ebb45e58313fda81d164193bd711ab5b65e7f2611b4b558f3c03294336043884e8b92390d11903035ed46289925447d3ab1a53802376cb2ae1960e4a7a13d0d05a58c89f5d0499be72acb9fb7dc5468afd332f483b1dac2370a14326b52467a205638fd603d835a628ab940a0463eb93814237415397b5a8b062b915c3f4278ed1db16ed13b03002c158700852837657b94a4b5ac43da32a7179a4c1a4303350652693844949029aab4222ac62de266240fb48bec4bded28213d945c3626aba1856c5e702589738fb5574380b74071dbb401696deb422b9de3699a0949e20522a3782e20a6aa2c364868ca41e7202ce8ec8bbc2165a09019a898bd4615741dcb73fdac5fc7c35503a937eefc08cf88570ed41163bb7f2e9315f0249d2bf5cb93b74627041bfb79c2b26754c6f38f8b802f28d7a775aa7cb082cb5755a195d66371fbccd1678478c462ca1896b201098d66b3991b2e73c299674bc645d2737111cfdfe89b416a7da8ca182164bd708119297283de6a1ce84cbfce07c683783402539f88b6b071213732b7594052bda614c95860b57bd5ad5ed10d8139348ad549bb573e3549320e521c0aa3919eb0978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ef030c94b2e93ea67a081af3413aa6ad1c41091364e558cd561674340430bc490a52728cc188cd1281c7aac45223a341eb60c8eab4959701aef2120c891b5ce115bf8aa17cee2a980c6895ec5061ab49dfea7431d755015117a5f0a0f200921c4547abba8bf13b5cb7987b0250c2885a0507094795f7274af995647b5b6e559275115cd55cbcdc9b988073b2ea214551752baf467432904ae95182514e39b3b418a49c410e4832d5377b95227b3091b5f782aa431a1962d6a907d3c2371161d71a9640b177a488a1fcbe57f108900e8e08292f4cf97460893004f5f88222d059b162207ad739650537bcb8b813490ca702555f134406e9c04cd54bb85a7689a1316cdf3c401d9c49b22816f47ce750aac7455a222490940f030f108086262479b8489fa00a12d09cfb5d4b6a4176fa0f62b1288c46af76340d81eddec842a548be29a3994c53a7e631baeaca3a0f8afc4412b6d51426d496d2a04bf29934f17e668421899c6690853876434e87f8f10ab52e61ff35b54227ac0fb7313d2f1c308405e5d767541c8c3bb4664c594a257ba30fbe34bd182790045bc1bb377f9d54ea8db52a945642075b0df8b2e6ac87e71177a4860157f83829bf7003558b7f35a1690920d494b4391396dd61a7f221991a1c6856f7b1ae5147422742aa0ea005fc1549cc034b9c11267e00fc32c2b3cd172975397a3647a41b1c69f9bb663835db97314468540973c339ab0cb36a19b2ea807fa788402d48dae0ac01285a8c5f3725fa674d0418bfff98f6c64c2fe21a4c6a7cae7b014277413781b7c3da207badc70aaac10e684c42940705b8ac37ee7c0a101bb3b9bc233845ef75908a83108a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_private_key = 944ab695c2345bb67894d451ea2a5c92561a5467c769352379950879899c9cac9d05e89cb2729b2bb47724923fca357623c69643569d66912b2f9b3249908090d4c5f68388a6141163c931df430d70290950b07de410af913c0e5a215c3059785ef05b824545aba0b95e7279d1c5726b59890b82131d5c62e8b3be33b8016ba0c321c248a5293c71eca570c9536f958b84663b1dd5bb6f272c3e201f014aa3ae05640ed92200274d45d9bf4410ce8ea72d680ace1eeb04cd8b002de72795db60681bc9ecd387fcea796ff7726fb29877f895e6832eb7eb179a5956499ca3bcf3283fc8489d494a88668e6614b1f49824f12a448b31a42861190ce3a9f73c6ffa25622d7a504e0694bb7c75ee71cc8e718ce9d57ac86a11721721e6181f157c333ae098f8a6823f765b60f0300f4733cf65240c779569620213b8a331731a7b31937104becc0995ef57255261ad9b246009f855ca82af2001b256760c1543074d70b3c578279b35137e16ac2089a4c60038b8671d308964b68a2211187154746c27f59c8105981c8c7d0ad58717978c01a66b5ee1697188bfaac9b927822c940c5380409f38459f5b302cf7dc9d6bd823a0308b0da45c35d541d2346bae4173fb0c677eec26a94c4158b28d4d7b4b0f62a4ab06bae0b42208b099a174bb4c482c7c321aaca49c4a517114a5cf408750e8588545134f83a67769cc6e0b413bb800c04093184625a7ee24134a721d5fb1571cd82dd1d7c5f9103e0c2c4416cb775aa28df48643084b391dd2caf39278e9a31d2254871b170ae1b60a4e39b1f5a8473f580c7153caa1369d8e9ca381660a57ca8d2523202816767ca8cac0914c16f1cec8ea4ea5da930e0403e7a876c390ba31fa250d946a2eeaa479888011db7942f7676a120338357bca38c4c95088a4a0884b8b4c14e9c09e831f8aa658ed77cc164124cb281f61856bd6c965b6b6cd60b1b1034888f3970555443f0f5cc29c800f578806beeb4730ab9af4b9beb89502ab48761e188cb9aa95ba06b28cf4b89c200b2145a4339a53406b6790a518f54902eba0230a8c2a45447125b7330f12645d935e00651cb4996e395543b7e643137abf3df59e042abd6fa11927062d73d0a107ba6fea0908ff6759a972c11e864ee7393254051bda558d4b272e6cb2c337747a7ef46f5ac872d5d5238521c09e21495ef98b59c22961e5a4967370efc4865f06a72a41464d37ce4dd1803bc117888b681d35195c857a47b764c6799a86e27327eb0403931e29f90fee8628aa43b333615bc0f251707024ad41a24e3c4f15b99e72f536dd989c0325225dc682e3611640d99c1552506e687e18a883f90882056c14385bc08be82616d811a4fb2dc93670945b7efa17593c4b7bffb76f9a805f5230c50b065dc77b409ca8cc0b7190aa61614c528af2d1ac130c19e4362e85a40693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fdf026207e3b207613d2ed74c085707edd555fe4c00b40b2a83aa219cd643f1d83ec0fc21bcf94fba6a8262d959c9fb345f2221082c40a1501c46c55082db2709230b04090558cb6d6815173525725d8cc0bc93c881c99a16041757d6a05ac71a15e887c1682d3300673d851fa1aa423c5b76a7330ee7041e7ae96c36cb6a2ec473d83096c122b9af6a16faa56505d156df9735dd3a82681637a1747eb48a0aecc8aebdb7a15000367a7b023bb414cb67587bb29d19182948c72b60b2cdd7e222a12713f6a6c3e13c782b23c494922f4ae07b346c1d52f94682c11a0d52b584f7c8d8c740d9e0353480bfedb3168774cb1ce31331e8cada805045a37c93cbbd28ec100e089003458cb2f09cc39640774c7767183a4ae4c974e305258a8d128ac84650bb044c60311bb2515703f9ea8ad3560c6f382c7d173f83d30ddc1b637de633ff357a28ca32ecd834e4698da363ce2380ceee401eee9b31df6967c7c15e94e765262134aae5719838ce9579c8406234a9963756fc83dae5427788bf98358da8b356a2944b7d8917cc0884a2c58481c8299f194f45e33c0b30cea23142287ab15c1a429e588fb3ba32b6897d771072266096c49576ff5cc537577b76ba6c6d993e01c30dfe519bae481aca72990a39711a60afd67c1b50d417883a44e1dc24b93421041a9057ebcd8df95cd5eabae5e776ba758d8ef9c8702406afeb9d82d91c06e8a27df57be2d2cec9893e9c0a678ec02e94c21181993cfd22c19a7620d9cc494394b2218a81f9cbc743047160b0a551b6c802e44d09e52ea613c5f60940d77c3aad232f9df0561f159ffc0c88ac9c2f1109a9d89ac87b4a756352289d241b8bd694a1e140f255163f7888ad1314e6208082c0bbdd72220fca50d57c65c3b05d701b567550316c440c6f90ba50a46ad9662f99c61ad6601a4a26874e30ca1cb97998a13e68683a28996933ba186f469dc903b0c46a348a1c307ab9a9a4d427730920ae296d725bc045d2807ce2cb325cbd5f6cc216a0c0bcda1e321c5b17565ed0028d68554c892a9755643a69cb721fe6296acb64b93966a1743ed298b5e348817d62a93c453318db713e95cc53f8bef7d6a5dc2a7001473851324ca0db3052448da3136347008ad8d8b6b95a62e8a48073d2634a58525dd663da939948d49da9b12b1d758bb6f328d0f42a38837675e487403148729c4ffaa2ccd1e6ce8a4c8be2e7a1ba2b7b633aacabba686dda63feb255360c4796bbc99d95461b30502b42ce4e6aa92120b61a283927184931fb6c98727cf4163284732d62216b653c633659045549a40bb0c7c0a64adeb841596516bcf97e6ca33892ca8fe6ebb45e58313fda81d164193bd711ab5b65e7f2611b4b558f3c03294336043884e8b92390d11903035ed46289925447d3ab1a53802376cb2ae1960e4a7a13d0d05a58c89f5d0499be72acb9fb7dc5468afd332f483b1dac2370a14326b52467a205638fd603d835a628ab940a0463eb93814237415397b5a8b062b915c3f4278ed1db16ed13b03002c158700852837657b94a4b5ac43da32a7179a4c1a4303350652693844949029aab4222ac62de266240fb48bec4bded28213d945c3626aba1856c5e702589738fb5574380b74071dbb401696deb422b9de3699a0949e20522a3782e20a6aa2c364868ca41e7202ce8ec8bbc2165a09019a898bd4615741dcb73fdac5fc7c35503a937eefc08cf88570ed41163bb7f2e9315f0249d2bf5cb93b74627041bfb79c2b26754c6f38f8b802f28d7a775aa7cb082cb5755a195d66371fbccd1678478c462ca1896b201098d66b3991b2e73c299674bc645d2737111cfdfe89b416a7da8ca182164bd708119297283de6a1ce84cbfce07c683783402539f88b6b071213732b7594052bda614c95860b57bd5ad5ed10d8139348ad549bb573e3549320e521c0aa3919eb0978dbb7aabd683dad74d00f549af5b4f0583a42d27a21ef030c94b2e93ea67a081af3413aa6ad1c41091364e558cd561674340430bc490a52728cc188cd1281c7aac45223a341eb60c8eab4959701aef2120c891b5ce115bf8aa17cee2a980c6895ec5061ab49dfea7431d755015117a5f0a0f200921c4547abba8bf13b5cb7987b0250c2885a0507094795f7274af995647b5b6e559275115cd55cbcdc9b988073b2ea214551752baf467432904ae95182514e39b3b418a49c410e4832d5377b95227b3091b5f782aa431a1962d6a907d3c2371161d71a9640b177a488a1fcbe57f108900e8e08292f4cf97460893004f5f88222d059b162207ad739650537bcb8b813490ca702555f134406e9c04cd54bb85a7689a1316cdf3c401d9c49b22816f47ce750aac7455a222490940f030f108086262479b8489fa00a12d09cfb5d4b6a4176fa0f62b1288c46af76340d81eddec842a548be29a3994c53a7e631baeaca3a0f8afc4412b6d51426d496d2a04bf29934f17e668421899c6690853876434e87f8f10ab52e61ff35b54227ac0fb7313d2f1c308405e5d767541c8c3bb4664c594a257ba30fbe34bd182790045bc1bb377f9d54ea8db52a945642075b0df8b2e6ac87e71177a4860157f83829bf7003558b7f35a1690920d494b4391396dd61a7f221991a1c6856f7b1ae5147422742aa0ea005fc1549cc034b9c11267e00fc32c2b3cd172975397a3647a41b1c69f9bb663835db97314468540973c339ab0cb36a19b2ea807fa788402d48dae0ac01285a8c5f3725fa674d0418bfff98f6c64c2fe21a4c6a7cae7b014277413781b7c3da207badc70aaac10e684c42940705b8ac37ee7c0a101bb3b9bc233845ef75908a83108a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ad35e259a200d16048302df38d8e7f9e1c3352502c43f086fe166325048fdce9cbe2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +expected_public_key = 7bd4ae7ac89ccf0180b971854b229829c15ed8119f77ea8c7a80a4b7290b92a4bd7ed21e3b317e15d2ae5593ae3b3413d4552b767b5c264a2e31c28164e18c424a00b013389663ca580ba5b94a5e3c3a9234f15de0f4aab90a240b55b6cf6c4bf5d29ba93480014023f25c66813996f674cad2f72c34882bc441a851413560f54df40146fe9c634ce98a8a659b38d71cbdf934d29bb4c469c660190fccb1820cc365490a8a79228b79d95c3850c536f7ced9ebaa92c159e5f9a28c9562beb95d9fa000371a2670e5b066d16e5af730c59a03b8d2364eb048df031618d09e8c07781957b3d06c6ad4534149fa65f8c513733b8b095b6badec8d0ec0cff1618f5b754e71f50f3f7c9a209acbff1505a7a40621b0aa817a9f7c6a1caa1441af16606376c845c473b89bc8cbf95460192632098bfbec366b1914d9216b16a19c8cb45204379a782c203614b37fe411dca18c20cc033cd6510b649c09431afe167826576e19d425026b02f628c92e389d884a8e5975c3a3a252e0443239305e30bc6e73d33fd3b0cc63a8484721157a491535ec1918a99584808e75c26de2535227a7120bf97b64f320743338c642bdc9d02b45a29903f22ef3e789e29c4119acb125347749f373c3f4156a2ba0bdaa51fdab2185bab69801055c1743e7f7541198cd6935598cd00ab2a051667ab0fc67b9751aa6cb76b38b51754d66296d8abea1e6268d410c68412424c780bf8198a9bbb1227771114baad6a63977163fd432131f96168131cbcb536b8d223d521583e9b31e025abdec005a6ec66396d94b17436609e6205f1610a805cb39240bf3d19f81b20cfb94cef7c10bc7b3110b2231c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63165c07a81e15d8a5313552728bc5c2b7ecbc3e35975a9bc5c341a7d6967757bb7c67eb279f7b34c33f95dfa49185f908686a55cba343af19635d07b3a23d6442d15cfe58c04ab586930029d072704b546a4af3aa9cdfa148018954a857b3c8992d1c567e3b20ec300ac438b53ec808ad0753cb8026703c1892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71387c09ae312e00368ed4198fd23884f1bba5651ccb94488166943b2972ac73615a21e32ea83b9b23596aefec1785329238e210fa1528243ab9fcfb974a6316e26217d278596d188c43684d8c349d91cb43d301c961e4b51b51b202c58ddaa10425412f13228d16fc0c75e2b8eba686fe5172768378f16785247b9c6e1ccd9929a8d17a829566b640f0744bf565ea512402707e78aaa6809b75c5154dcf70bdea1cc05902bed4bacc3a6c3518d2a605cb96e3cbc5209239f4994df6b503d5f16e04562ed689a2130334ffe99b093a5cbe2282321551e943ba7c988561d332663ac4e8b367427133cd216240f659d1542e54e4ac32c42da7c39c0b5c105ddb872a9b617bf386d7259661c2823522198802be252747381053ceac84c5f827339c90812615eeda92dd38c2e1db2268a3929087480f393643d17cdec6cd059c2b810b464646a26427cee030b311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b42099de3c6d252467c0525131128b18508aac196a8b45c013519d52950a16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f5a16a98857d7f57945f05925b45a55209895b7ccd7a9831d93ccffe55a8ee0c63cc57a10a0c8f905542856594bb41359fa9f5c312ae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3c9222c020280f77b9b731514d2ba49b1b0b0e6533684fc5ef2665c25840426563ec3a2aa0a01812186021d40c4f3519da9799feac06afbf04cd390c0a52a0b687a5ef0877f053c319fa51ce7e53aad0313ba3b6a7ba5892a50cead19356d8068d1a93681833ed4b8c975e99d969aafe1a6a5c2326c4e290d65eaae1323125238303719c545202178ba17eeaa1504f13cd96838b7560c1a35b1257a1672c599b1b993a55ca982a1ae29b6664998469f171865562ee027c4644234f7e3b14621c811caab7498b204a55c8b302033219d6b2b9bf7939e9fe4523aa9cc9a41a1ce11c18fd6bb9bcaa8970534a7106199b76975ea8af98233f031a371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_private_key = ac65af9fc8b905d09638374e58c551da08ac4ef86a8ff04489ba462841a85d907ed0c70e1a790297ab2df7d6cdfc5c6af513144da105dda2c75f00736dd91564a79668e335fbdca1c9d31592e73d60066b959a2fcbf55474f9c21bf058f021457586766fda4fad521f64940d4932b07ad8ca7e1a06662730ea6c15aa1c2f9662552313176af04fa4a98962101492566adb8bbc3ec04f9cab9ebfe5860f886d57a2c73fa050a3607a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661cd000d10d6bc31ca1c249a9b3931a4d1c57904dc6df923839d9a90aa2b93a87c44b5f82e6a925d22e679428064ffcb9621067b75477fb7d51a1d3b9d9de4051cf874ccec12976562752cbfcfc59f56c2c60b8b4610a9bb36e9019b974502407d57289726ab8a38d7a6c880074a5686619abfffa5757dc79e1449408851502beb8196f493f4a724b9d681645a07b193586c5c05d8d10e2c968bd251b88691c368dc18cf8270dad3c22bf5093db4cf05668f8c6315c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af53141eb5e7534fac4de481741e48b414302e4743789e250c39c45c0a15cf42e7b3631b6a8c0971c8a34b8200bbfe11004ab06bfc5949c3615b02947c73e7a0717c6b60f2679daa21afe4c55768a08e70105868aa6ab4aaa848c79bf125883907b9daabe367afce273e2c168aab02acd27855e2944b67b938170a9258f67397770136e466758c260ccb7da226b5a95692514727fd48953c62959c88c8784a8a52131c4ba5a6d757b4311048b602b554e8ad509b0c12b0a64553cd4270ca92f36cec227e16a217c769a2bc1aa6c356a5a39c69f4963ba6273db9232f1d8a28ce65b5b9058f1b8a164ab0380c42a8eddb6c2b8b19f26b557c387e4db9aeb92c4d7d0a2ca1e35f97e05cf590bc511ac5efb2357e70525bd027b36c6781c4b86b0069e7b89c8ca643fb9990ecab2cc5a8a5a5b2b0441076ce934d96bca9ffc10eb6e7bb093675e97b68894bb030581d89123642c1118364115a76ad1c181eed4b691bbc15df182dcde00c71f8685b71883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5057a0886d760460cc4a3a713f4fd4bdebaa93b943c48e6348053703ed818fdd9cbd62e246c0b69a265aa381822d6a474c5aa530aa5306a0c8572c413718a278194367405789e1f749ab4a02af87b362067f3da12ec01a83acec26a390cb5419b351bc95e08c7338fb933b81476ea950881275a186c9e9f99dab63634e6b7314188bfd686d74ec203b71542b62b1c0c7712745940f7b9237551467470e5b1ba2f8e34cf585adbaf980317c9db1147382946c12223c3a45973b879a523855bef121151bce620216dedc6c3457ca03951ff45b662f79a1a7a5cefe9a846dd5774c7c2a22f842e4e465a94314e036bb55a2787a1a0f0f111143872dae74af706a369ca54259b80578bacd497700871842b98cae2ac3b572f98f145cbaaf54569779b616242060b30b2a482daf335c9a502cd318296958c696f7080c7a3926c7b62f36a5dbfb87ea0518358155e8e94390b6c0f808b91c166577037df60a21dbacb5cc0758ecfb20d4c38ca54c4248e07168b19f7d925a8ce8648f812a8c5b6ff69b8994e95859d2c5cb67259787739cfabab0c1b093e690c50632f7c336fb139700d43a04892db5220c28912a59ebad66bbbf0fe860e2e30d8eba9cf21c6c1156cde0b255a1a4507e3c880b749fe959470b684e03268b43a960f3d76ef1d4c4e7266f80792eb74959a12a6f1c91cde02b8d5c14a500ccc7224c8ce3a70b99557c87b9bf09b449341118b3f998509b1ab0492e0fb84340f81f8f51c08917319d9350055bb889ba2d6ec7b5e281a9ee84ba90ca4d33014f9cec2993915c7bc094e9b926ea086d84434c2748bba95569779947cc744dea189b2080afc548710b94a225799293090cb3a6c932336003990ff766493f4b17cb834cdc70a0b209b7a1fc42ba087d7c10c02c383b60b63ce4e44bee916920156de9ab95aabb44f28bbb3f0612338b0a5077c898e3ba0f197f7f31c467b8803abbb0a82a7897e7a39c0012049788d27b70c8503c719ac3df958a7a61affee0a2c79a1703d6527bd4ae7ac89ccf0180b971854b229829c15ed8119f77ea8c7a80a4b7290b92a4bd7ed21e3b317e15d2ae5593ae3b3413d4552b767b5c264a2e31c28164e18c424a00b013389663ca580ba5b94a5e3c3a9234f15de0f4aab90a240b55b6cf6c4bf5d29ba93480014023f25c66813996f674cad2f72c34882bc441a851413560f54df40146fe9c634ce98a8a659b38d71cbdf934d29bb4c469c660190fccb1820cc365490a8a79228b79d95c3850c536f7ced9ebaa92c159e5f9a28c9562beb95d9fa000371a2670e5b066d16e5af730c59a03b8d2364eb048df031618d09e8c07781957b3d06c6ad4534149fa65f8c513733b8b095b6badec8d0ec0cff1618f5b754e71f50f3f7c9a209acbff1505a7a40621b0aa817a9f7c6a1caa1441af16606376c845c473b89bc8cbf95460192632098bfbec366b1914d9216b16a19c8cb45204379a782c203614b37fe411dca18c20cc033cd6510b649c09431afe167826576e19d425026b02f628c92e389d884a8e5975c3a3a252e0443239305e30bc6e73d33fd3b0cc63a8484721157a491535ec1918a99584808e75c26de2535227a7120bf97b64f320743338c642bdc9d02b45a29903f22ef3e789e29c4119acb125347749f373c3f4156a2ba0bdaa51fdab2185bab69801055c1743e7f7541198cd6935598cd00ab2a051667ab0fc67b9751aa6cb76b38b51754d66296d8abea1e6268d410c68412424c780bf8198a9bbb1227771114baad6a63977163fd432131f96168131cbcb536b8d223d521583e9b31e025abdec005a6ec66396d94b17436609e6205f1610a805cb39240bf3d19f81b20cfb94cef7c10bc7b3110b2231c61c333a3577730ad02009951689a2c867558d244a70d437f1aa3453743b61a63165c07a81e15d8a5313552728bc5c2b7ecbc3e35975a9bc5c341a7d6967757bb7c67eb279f7b34c33f95dfa49185f908686a55cba343af19635d07b3a23d6442d15cfe58c04ab586930029d072704b546a4af3aa9cdfa148018954a857b3c8992d1c567e3b20ec300ac438b53ec808ad0753cb8026703c1892f53357f58a9e936bcfc344e82686c95ec375b8c43baea58e28c71387c09ae312e00368ed4198fd23884f1bba5651ccb94488166943b2972ac73615a21e32ea83b9b23596aefec1785329238e210fa1528243ab9fcfb974a6316e26217d278596d188c43684d8c349d91cb43d301c961e4b51b51b202c58ddaa10425412f13228d16fc0c75e2b8eba686fe5172768378f16785247b9c6e1ccd9929a8d17a829566b640f0744bf565ea512402707e78aaa6809b75c5154dcf70bdea1cc05902bed4bacc3a6c3518d2a605cb96e3cbc5209239f4994df6b503d5f16e04562ed689a2130334ffe99b093a5cbe2282321551e943ba7c988561d332663ac4e8b367427133cd216240f659d1542e54e4ac32c42da7c39c0b5c105ddb872a9b617bf386d7259661c2823522198802be252747381053ceac84c5f827339c90812615eeda92dd38c2e1db2268a3929087480f393643d17cdec6cd059c2b810b464646a26427cee030b311f591b7d96858ca9fa0b53076e975e88582950350c2fb82c8bb33a9198aaa5948b42099de3c6d252467c0525131128b18508aac196a8b45c013519d52950a16d48007b339f8a9336349c50ddb656b55874bfc7bffea795f5a16a98857d7f57945f05925b45a55209895b7ccd7a9831d93ccffe55a8ee0c63cc57a10a0c8f905542856594bb41359fa9f5c312ae6e86dd116a292c66f47b9a0791a72dff47c55c69aaa8a6465c7b3c9222c020280f77b9b731514d2ba49b1b0b0e6533684fc5ef2665c25840426563ec3a2aa0a01812186021d40c4f3519da9799feac06afbf04cd390c0a52a0b687a5ef0877f053c319fa51ce7e53aad0313ba3b6a7ba5892a50cead19356d8068d1a93681833ed4b8c975e99d969aafe1a6a5c2326c4e290d65eaae1323125238303719c545202178ba17eeaa1504f13cd96838b7560c1a35b1257a1672c599b1b993a55ca982a1ae29b6664998469f171865562ee027c4644234f7e3b14621c811caab7498b204a55c8b302033219d6b2b9bf7939e9fe4523aa9cc9a41a1ce11c18fd6bb9bcaa8970534a7106199b76975ea8af98233f031a371c79a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc95a5db7d619be642bd87294527b3f859372b279a1e6074824d9632b5d7f616e42a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +expected_public_key = 202275f93924ffe79141ea0abf85a4c970c45e0acfb20c426cf545caeb594907a23be6cdcd38486ef2cc1234054fa47c50c629657c91e71103c029539e632089461effb67a0f8cbe74b91793ab033bd89a2a0a68ef390ac90669aec42530c785ec3a0dab424c8184bb051780b4e80838539c81a5097d42cb854cbf324a26f3cc65024a6404cc2a335378fd10adc8e10cb99c323ddc55e70b32a06cbfab829e53aa059163c46339b7fa1090244a358dc647d4b1783b59383a0988ace605ad979f655038aa422981ababaa0c2f28899a352572f4f6515d62649cf88591ab7da91ca2c0e44aefd16ed3f174cbd0bedb7736363c609eba4655b2a31ba20f05e412282b28e15125eb212596e0c54181028cec9b106849ac366f62e8c1c5ec9502f01ecfc1749fa3bd7b251b2a09c731c468dc2988f69649fa9b46e9d244df903ac9004f09cb1dbcc9c69b33ab9e928fd2072cfed1186f9799ee3c2ccc2b68a3d662c7fb4438240d6e0b70ce98478e6c28294047400b9088eb4aae3a5a076979af8ab4234164b0846a9904ade949742d7402c8516ccbfb1d30581a288c9d1c69360a2b06b21541382ac9b4101b96d4952e89725258cf7fd33ac4f522d12b6f65b884f33a0a4d1b0e41d660d0861beca59164f8760d3274d6643ef7d13043d63a4cec67961c808cd64b9728872f74412b8867a2e25cc58174653b2a1a0ac0a24316f4c14281a0a739bab2de26ba73c4921c50b909d188e8b3c4db1274491c792028515930ad45e667c9e6870d204554556bfff44d09f95fe9dcb7370320bc6740f3053ec5b7396db400ac671b01f33dbae59838741b59e4c7f076a92ce92c5213adadc47c8f50bcd4756de7642799d5477967339e01455e6898d2194a7aa724338946b7db70608c0337e305ac876f3d87c6ad857162e491e469bf62c26285f9b817858b149358cb67248a298cb21771f1504f4997965ea38036d274ad72849164262fb58f46cc96ffd75f23b4a0c990a9d59160e4365b07909f7874a22ef1362035312f43b6272bc47eec6ce9c0b4418b60c5022502485bd92730ee75a9bb4a8c81a03ad4b292f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe274c268a11afd003beabb50d12b8550eb3008ddbca593c7bbdf6768fb561ac452d32c77d74352310e4322ee53b9ba879d511368b445df20aa17a7ac8f205a302f75f3c679557f2a37de221cde6c8f7248e73ec25de603afbc5baf1b076dc3b304550c198b6b49159c12490bd964b661e6ac0eeb2b09a78941675a2132527d0016d89ea6b3cec5d19f1818e4501134947a547957a195807774a8c40a9c50833790aba5628c2eec2148dd0430294b331235d4246770c293046a237f03487993043573a71f250090aeb01dcecae4b878633c59b5403abb02151d8048dad408473d63cdd018d3d295a46ab556c8aca53495683976b2186c6c818b852005d20964cdbcb6061a50910b9c429ba9f10a06f4e053c9e1c4cbeaac35949c8f23c3e890234ca990b2bc890d43c2a4051aa058a402b7caf4a3925f52c95c6b6c7d26b4e3d43b21d7b0fff3b37e5d33e391b5e617785f52128c581969e094d82d062a8631a76b093703626d8708c5f310abc1951ee8984bf858a7b582038a6a624f5921257764890b73cc9af94e5aa82d831f341486aac17cf29ac351483f7f26c80111f6715634ab69ca71a6893b13bbf50cf58c16b29d6b7c9b58fb3c0b9295a6320210f1db8193bb8a57889a28ce3b196f32cef048a4d60466e3857c07847e3883c1b7bab89224c94fabb3fdb921ee3c7fb716ae8c520d547b1ac49cbad256ef43015fbd722b8b31d6db24937338e6614402d9272ed014710fc5b0a7105e6659de2513101b22c81dba972fabbf23756b5d524d41a15b6d682a1894e8439b6946c64d10732ac603992353f03e61c1a136011b52c624b0943a3464ee92b8a7b970ab5ba9713205e4a22b6a12e063c35e8c65470b32f9e29255d9847de80cae1091fa536213078bba0181fa33bad7f3003d2065b8d997a7207b595994e816a1979ac5174137ead82bd88295f2cbc77e01c0fc9119ffcf25d8f2044a16aca9ca052bf917746109320dc076e1895399741ee690702b477a2d07242e03dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_private_key = 67a93bb27acd00c9b95aa03552809c38a08480dbaa67a9584a460345e20e5f381c9a82710ef1709ca51393f916345719bd3144b3121a8608c0a48017963387f7a31c5febc6b6749e6bd9be3c58a9a77b53d7762f5854a3467a85941ca2c03873c0458b940275e5ab85b83a5c2027894b92246dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451922761ac274b5cc8569ccb93917a748e93c190320e3f1381e08cccca70903975ae25689c12709c8e9096b16a26e4439c2552a088194368b36efe3871a6a1cd54ca0c70974ac936e45dca01de296a14c7d20652999e61841dcba6c0171fcb406e14a95b0c02517447bb9370996176bfdc5beb4316c0ed34a13431e34ab27d9dccd3ddaa49d314659bb8d89325099d0b06931796ce65c0628c817393bb1870f19a10cfe3546d8bbc2509058327626f490a1bbca6fbb653ee1c3555203353509ab14b64cf8a29c32b17096805b8d751848dc4494279266f2cc474228b2b703cff81f0f29152f4570151517995262d705afffc08dd413c12f37b605bc32ecc1292b9ac99e4a34f911c8db990ecc9a3dfb37517446908b91b1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d1929e5721bfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c8b20b3ec750b082bf2cec89a6f8c2881650e5b71a0135c865bb3fb12a4c2c3c917d655a2997984c8557ecf1943436a9fecc5c84808e38701cc26a251f458334f59bd40bb0d8f82e74071a5ae3c9439541aee59c6e46a5852834ce5712b3665018154c5339467d606af189ccf20c68c583c96d969815109cd3ecad4f5ab0a8bb8a7b68359b0319078a7405821c2709a615864422ba0a3970c8ea138ffc1522b1a53ed1c71d396a0ed6b782c6552c70216679bb4761a600634276d553cd703897c6943a859112caf9a7ac99517c23ce6457aa069b6fd2775efb262dbc27b02fe6923d14b047a25cdc6b86d20a55d85108ff276f121a352e098e5d4cc3ef92b3a1c4a38244621b055d5f812189f6941b492330fb1ab0a442a656655455b38b522ded5640cc4136df6cbf4c4b0651531cd8c95280e2af13fc57c977bbd1a8bdd253096ea98c3ab33a516448a8301a4b141ae213bad2f640b2d5846c99a25884360f604333197816ba9dd1d0c427c5b8d3a6b434207b8539ce5092ccda67a755d6a6d7e8bb6bb02af1ca7283e797f24a1042d29b64262f29b0482b840bd70a3d6d54205df412dd6490e3dc38c1236758f65e461b11ca480b476875c692508e7bb90c430797e1917041642d88506c07255aa92ea32508462c2f4a1661c05114c9361f651b7c5ff70b42659ffee71f58cb79e445536b8948142cb4ec16cfe5b21da659c2dce452346323f1632c37f128a6525f40e03d6c073e05476252b2b0483c4b87c1c1fd8c972cf651eb9684fafba3f862c8619c089f01277c14be7cf7790712ca1e8877a48909efa31d814c1c21f4a151b886076840546419a1c8b6ca4466389a3f6dbb69e8494d7b25a4e9b234a8d928a26b946ff305b8a33b0bf8b3eb992d68c312b4074788e69d1a5a211c3b55f8c654ae778fbada1d75fb23966a42c4f189d861760f7a5f30f358dfdc482014c25845706577763ba60ea00a378daa1b0cd1c15c5c04bf847babd0ccda7c61b0a956229bc992029dab7b05923c5deecc595d766c0040946a229259c75e9985bc0519218df44dad36abf20c2baa92c3c34cb911d77c0e7603e8639fd2870ce0f6bdecd193c8c261c53a9ec8d4767303480529ae2cd23561c9215476c617453274881092443076e731a459cf603a7cfe81804fd1c8293baec711a694f98f59d01cdf79827e777b9e452f0a388a7e7cb83ba37676d2b70afb02c7cc0fd2a05411f41732233bffd8917d9726657c68c4e34f1983b6007b43ceb87a6fa033b3c674a090999cc94a4f2889a8b71e5228c1f92c16db841099c57a73005f81a5cfc97a3a1bb6092ad60eae139d9bb174c9591ae20c5db48390c46bb456e49e124559dbb230cb6b5118078c8baac9e959277aa55b521a351bf34f9bf7b18dbb4120ebb60c914d84a80123f338035520620783824c676175cea40a812d896839993c4ce211118855e5349e84c8604d1c85202275f93924ffe79141ea0abf85a4c970c45e0acfb20c426cf545caeb594907a23be6cdcd38486ef2cc1234054fa47c50c629657c91e71103c029539e632089461effb67a0f8cbe74b91793ab033bd89a2a0a68ef390ac90669aec42530c785ec3a0dab424c8184bb051780b4e80838539c81a5097d42cb854cbf324a26f3cc65024a6404cc2a335378fd10adc8e10cb99c323ddc55e70b32a06cbfab829e53aa059163c46339b7fa1090244a358dc647d4b1783b59383a0988ace605ad979f655038aa422981ababaa0c2f28899a352572f4f6515d62649cf88591ab7da91ca2c0e44aefd16ed3f174cbd0bedb7736363c609eba4655b2a31ba20f05e412282b28e15125eb212596e0c54181028cec9b106849ac366f62e8c1c5ec9502f01ecfc1749fa3bd7b251b2a09c731c468dc2988f69649fa9b46e9d244df903ac9004f09cb1dbcc9c69b33ab9e928fd2072cfed1186f9799ee3c2ccc2b68a3d662c7fb4438240d6e0b70ce98478e6c28294047400b9088eb4aae3a5a076979af8ab4234164b0846a9904ade949742d7402c8516ccbfb1d30581a288c9d1c69360a2b06b21541382ac9b4101b96d4952e89725258cf7fd33ac4f522d12b6f65b884f33a0a4d1b0e41d660d0861beca59164f8760d3274d6643ef7d13043d63a4cec67961c808cd64b9728872f74412b8867a2e25cc58174653b2a1a0ac0a24316f4c14281a0a739bab2de26ba73c4921c50b909d188e8b3c4db1274491c792028515930ad45e667c9e6870d204554556bfff44d09f95fe9dcb7370320bc6740f3053ec5b7396db400ac671b01f33dbae59838741b59e4c7f076a92ce92c5213adadc47c8f50bcd4756de7642799d5477967339e01455e6898d2194a7aa724338946b7db70608c0337e305ac876f3d87c6ad857162e491e469bf62c26285f9b817858b149358cb67248a298cb21771f1504f4997965ea38036d274ad72849164262fb58f46cc96ffd75f23b4a0c990a9d59160e4365b07909f7874a22ef1362035312f43b6272bc47eec6ce9c0b4418b60c5022502485bd92730ee75a9bb4a8c81a03ad4b292f14746fe686c5588b842646b59a38f6fbcae85f3491c38abf066cee2f4a285e961395bbe274c268a11afd003beabb50d12b8550eb3008ddbca593c7bbdf6768fb561ac452d32c77d74352310e4322ee53b9ba879d511368b445df20aa17a7ac8f205a302f75f3c679557f2a37de221cde6c8f7248e73ec25de603afbc5baf1b076dc3b304550c198b6b49159c12490bd964b661e6ac0eeb2b09a78941675a2132527d0016d89ea6b3cec5d19f1818e4501134947a547957a195807774a8c40a9c50833790aba5628c2eec2148dd0430294b331235d4246770c293046a237f03487993043573a71f250090aeb01dcecae4b878633c59b5403abb02151d8048dad408473d63cdd018d3d295a46ab556c8aca53495683976b2186c6c818b852005d20964cdbcb6061a50910b9c429ba9f10a06f4e053c9e1c4cbeaac35949c8f23c3e890234ca990b2bc890d43c2a4051aa058a402b7caf4a3925f52c95c6b6c7d26b4e3d43b21d7b0fff3b37e5d33e391b5e617785f52128c581969e094d82d062a8631a76b093703626d8708c5f310abc1951ee8984bf858a7b582038a6a624f5921257764890b73cc9af94e5aa82d831f341486aac17cf29ac351483f7f26c80111f6715634ab69ca71a6893b13bbf50cf58c16b29d6b7c9b58fb3c0b9295a6320210f1db8193bb8a57889a28ce3b196f32cef048a4d60466e3857c07847e3883c1b7bab89224c94fabb3fdb921ee3c7fb716ae8c520d547b1ac49cbad256ef43015fbd722b8b31d6db24937338e6614402d9272ed014710fc5b0a7105e6659de2513101b22c81dba972fabbf23756b5d524d41a15b6d682a1894e8439b6946c64d10732ac603992353f03e61c1a136011b52c624b0943a3464ee92b8a7b970ab5ba9713205e4a22b6a12e063c35e8c65470b32f9e29255d9847de80cae1091fa536213078bba0181fa33bad7f3003d2065b8d997a7207b595994e816a1979ac5174137ead82bd88295f2cbc77e01c0fc9119ffcf25d8f2044a16aca9ca052bf917746109320dc076e1895399741ee690702b477a2d07242e03dab4664cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518ff0d1acd4fe1bd3bad938c23ec5a7f320766e01005e32769724abb4ebac578def84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +expected_public_key = d5ba702b276804716279e61c4b3a599005270578414141c09d070d9302cbb10aac8b8483f11b1044cb83efb8315ff38feccb09d1775e1e29c59b1759d894ccafbc147b228debb52e83d2584552bd15b9b18f02ba12c6669ef94190126f6fe364d106a9d4762522f25a0298cb5e40cd6b89045f275456e8bc32e2c11835b31e6aa628e50e28a9a18226c73343479d0ac61e5a81c6a38c0506477e58001b6890155c3a71f21e1df151660c376cc61d90d93331801b31dba89b6853c2630d33578551399164db647665ad52f912831a956b8ab283f91c10209b0b055ba765cc75587df545b670ea13c6b917393666bd6a9e07a21ac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837b02600c03c9f8f1481414a241766df430a6dec7936db2374eba1dddcaa58c8a2984094c57349a78102a48e48c450ca7135a057eb2858a6176e67316ad21122c44643fd42cded7caa55a628a503366077058b286aea157e540c598822c3736aaba5298a41765fb949190977456e1b5c1810db1301342104b9526a82459a0f78b9a7e74808a49243a0902d8c6485f887ce62697a72474a1fab0d1342d5ab7a8d9ea38d3b129661c2ceac177d63a59d5b62be8a11379a51055b36ef78817b677ac30f05bd38c700cda17d52b02e8b19f09354ae074b4365ab379667744363b9d4ba17c061ef955631f1ca916a74cddf05160b82994c49688d71612676bb0d95f6fc58d92970fb71c3c2a250b4161b32b3405abd605d0a94ae017bb28801ea54588bbf0b9caa8cb5920bb02730454085871469cbccbbb26911d934680afda6ede5b29b0e4a0f9b15d13392647ec9ab1922943c88dca974af1c95d01866e906221c901319e2bb4db5807d3b22ebc077834c29aa555226903a4b53c7b5d29c226144095e03a4886a18a26b99f389a71c41849f10fafe816d213be109ab7ed104114678d16242547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fac2d2405bef464cc60c58efc595da6c1ada9200d8eb1631f119e99b38970db26be02333be37e661c2bcb483dd1156a7e016dbe39af9ba9a7a6fa8173033bf4283e5160b1b2d4914f453bcf3406304859205118c6056243209c87a76a7c3259258786e6c64b0405bb8ae22e33b1617bc9815bf57b182748cbc6c4e8cac9a9a22965e560fac66beee32f7b8248c241cb3213194221c704bc821185041ae5510689a8d7c4ce5a6c3720e9c845116d2b3b9de703937bf500c9249fd3b2b134998ca657562b19857f6acf575264eb1b0b27d50049542d3f87041ddb755cfb340fd122e4c46663a7b556921b41b50713d71cb20a7888955689fa4e43172f134b1a2b628119c22c391408b16092cd6c8fcd6cad8ef34e129c6d5fb8881725a3b8180a14ccb625a65ae7c59f8b7888afb126f2d8ae8457a273c453cfe69726d951b3a241df583af9995dcbd73223884560258459d0bca1e794c94214276547d3d740a8608c33662eda195f4e26b90d86955c2b4c8470592d1c075bba0fb49b6732b2954fe76d0dc3b3e840865fdac146f03ba0f336f0397c6fd450770a2bfa5837f46096d3c673c562c9ce79b5e978c2a40450ed36b43210386a769de3a9063b93455b694c5cb3837e865ae61b82aa96661e57c41e405d260bc7ac84cc0e1c7515c47c320c61723177f0f57f599958dec24a3f81ab7f1b759c61487a243ff13790de540bbd1b90af233d8658b2805152183bb220e1ce017795ba97753e9c06620a85d4e28591aa6c1f440240e9c22a9acbdb568a98eb745ef435805cc00c2722b0822c1a88b8b80cd05ad2a69c6a356889c2389ac128c49d627a1f3c844ec85b82a405a2e1834cb753b415e32629b7397713aac7c70ef01a7bb3db86ae13b4ed51cc77e2a90de08c77d6938b903e05913477d1c38c98a80dd034caa3746018bc32034b27602732bb0a9cca9dabdb795c6bbe181576e69413c419674b646386b62c0eb8251572a630b087851892bbf726fca0b7dd8a170f19100d6087c191ab56f066a3f61f973c47fc62c331287dec02518039b32e7c320376b0fd82788e2a8ef38b1dd977889c2712ad258d4feb5f7426a4ed147e742b0995a97c2ad876e1860aac6ccaa82287edc68267362ea53ba9d0d91549a448fbb43e3f90802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_private_key = 0fcbac2fd83a9eeace0215c784e20260f0991b225897e94ecf93368b79565b478731537eac74550cd599d5268e03a25cf327606686ab8864677907a3c3555018b478fbe125498652d5259a31c2b4649c14c89bbc5758a9b53c64e95bc9ce30c306372d431cbc642c0d60e25136c3919f3bb48b280b9d5ca0b21bb4e1510ac49aabdf02c9fd66420b475d0731918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f5604863ba6dca297ee29238ba79eeec5096e9b336cf0b24dbcc9feb8bfd77ac888554472d7732e7492c231302a073680c684870b86a05592355baf2620b51ddc7b17c9328d7a74da6367d9ec2b87e9221c297b5398cfb55c10e8a68323aabbed806c2272c192fb180e7a5b958a02dca5c55654a43c74216b192522bc2a2dc05bf865062cf56839831ebb837a3ed8c7368c15933730667b7463ab7026848bc9ba14616b2e88e17aca4109b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895400e245df8a324899273efb441b564305ec48ab305c69d37e846ac9b77a2917915e82286ddb397936769be7e37fa7f27a003090c7f2b9b395a41370b5a38c07c2d8314627267fa06bfc416d8ac1155df645c6150bee70c4cad8c6a5c564ba2571c9bc9bfaf0c2d12578c8198d49e1414cba5749d712556a537a4131f3f085f9047735482e23342b218101ad30122113060cca4196f778c77cad2ee58b6f23071a85b79c1215f0a7c8745abcdb768c3c26042d09a9a0355a5c45745d1acf52c205b949acf581ab75cac74f2364406a43a74269645166fe167642900d169a1e84929da4cb361e80c42dc702a79364f1d664528b6cec667bf230078af06a0b48466dc90b34ea7101512e37d8ba3a351d7023aee652351ae514b8d217faf09a07654b0cba1850041d7206cecb05c8f6703f762c97dbf82255daafcc3608e8891e3ad8b3d4e18dbcf6a1c2e74cdeb87d15236d70943daa722481692890a548d7c69a14fcc1155202ca4941c3900b57a452f281091a94781c64a9583c8d302c21484cc6159b88a931aedc4291e097982eeb0528c152a43b97dea2a0b36922fc60c226b61068c792f377b9f655940d73702d41bc515086e8f9266c53a4c15a35907cb2fc2a2f19bc5f974034677a33b648322cc9bfcc6b947b5346df2044249623e53430895295327c9b35f59ecd4a9521f4b93a4c031a624c12f40ba17b9f36908e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b5640d683b7a45009a1efcb5e50a35244c9431f21f1b6826311673832ccbc1794fea917268f5323726698f67bdb41bcc012218929649c972149393845dcbac7fb58582964405d4adeb814037a39e512c3fcf72a22ab70e21fba3822b493df9983866412f0439e1a613914042c982739031949b2780d8133e13e632fc4281de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09e304210d5cce3ca3dfef261a809bc5dc44787a20afff49f3e0156e7b428ae1cbd3292c9d818844d4767342708e4016eb9bb0f7099876c26729f443e7cb3b9666441dba01c8397953f586e3da4572ac12d00cda40b715e50422849aba436c1aed529a50a2448ad772495c6358c8050b323b6636871e092aaaaf75cc2d869dcd71e870384a6c2c51000cce0515a8c2459f3966c853749d27809905118cd897fe04a76f196a98b71a5b7405e72e9bb7b3b3f0638016bf15d45e60ea054834ef3af6d2817b59c1bb5740986d626fbb8a98af56ed2ca9828643e3bb604e256b6ff8830606a68779a659962b7837bc46fa9781a1a8ae398ab313c597a4b7070cb1b7dea82a6496f3d00adefeb361c980691ea7d261982eae4b80ac5550a91532f81971b05908dd84ba13544d2f00615bb9ffba14fbd4b6a5ee46f5b6701f064a25dcc4a8425073f63ac00f41a194409b4e12195b8910be7848ec8454da99c0a0c839371a1907183bbd926fd8a107e2160aa8443ace7c77743c5461c37b4712160d5b08aec019025651038c7fa975a261578a82865b1d034a7fb9785696ddea901b1dc3e07e18c456b85464a0a04d91b56311393f51c56f4763aaaa4daa788f9e631b8e92660d2850b738686706531f72bd5ba702b276804716279e61c4b3a599005270578414141c09d070d9302cbb10aac8b8483f11b1044cb83efb8315ff38feccb09d1775e1e29c59b1759d894ccafbc147b228debb52e83d2584552bd15b9b18f02ba12c6669ef94190126f6fe364d106a9d4762522f25a0298cb5e40cd6b89045f275456e8bc32e2c11835b31e6aa628e50e28a9a18226c73343479d0ac61e5a81c6a38c0506477e58001b6890155c3a71f21e1df151660c376cc61d90d93331801b31dba89b6853c2630d33578551399164db647665ad52f912831a956b8ab283f91c10209b0b055ba765cc75587df545b670ea13c6b917393666bd6a9e07a21ac46cbf3b5cc5a079488f97902583bf61f5a7074babaabc837b02600c03c9f8f1481414a241766df430a6dec7936db2374eba1dddcaa58c8a2984094c57349a78102a48e48c450ca7135a057eb2858a6176e67316ad21122c44643fd42cded7caa55a628a503366077058b286aea157e540c598822c3736aaba5298a41765fb949190977456e1b5c1810db1301342104b9526a82459a0f78b9a7e74808a49243a0902d8c6485f887ce62697a72474a1fab0d1342d5ab7a8d9ea38d3b129661c2ceac177d63a59d5b62be8a11379a51055b36ef78817b677ac30f05bd38c700cda17d52b02e8b19f09354ae074b4365ab379667744363b9d4ba17c061ef955631f1ca916a74cddf05160b82994c49688d71612676bb0d95f6fc58d92970fb71c3c2a250b4161b32b3405abd605d0a94ae017bb28801ea54588bbf0b9caa8cb5920bb02730454085871469cbccbbb26911d934680afda6ede5b29b0e4a0f9b15d13392647ec9ab1922943c88dca974af1c95d01866e906221c901319e2bb4db5807d3b22ebc077834c29aa555226903a4b53c7b5d29c226144095e03a4886a18a26b99f389a71c41849f10fafe816d213be109ab7ed104114678d16242547ebb69f55bae884535889bacc55a44e1ab9eed3bd23456e0fac2d2405bef464cc60c58efc595da6c1ada9200d8eb1631f119e99b38970db26be02333be37e661c2bcb483dd1156a7e016dbe39af9ba9a7a6fa8173033bf4283e5160b1b2d4914f453bcf3406304859205118c6056243209c87a76a7c3259258786e6c64b0405bb8ae22e33b1617bc9815bf57b182748cbc6c4e8cac9a9a22965e560fac66beee32f7b8248c241cb3213194221c704bc821185041ae5510689a8d7c4ce5a6c3720e9c845116d2b3b9de703937bf500c9249fd3b2b134998ca657562b19857f6acf575264eb1b0b27d50049542d3f87041ddb755cfb340fd122e4c46663a7b556921b41b50713d71cb20a7888955689fa4e43172f134b1a2b628119c22c391408b16092cd6c8fcd6cad8ef34e129c6d5fb8881725a3b8180a14ccb625a65ae7c59f8b7888afb126f2d8ae8457a273c453cfe69726d951b3a241df583af9995dcbd73223884560258459d0bca1e794c94214276547d3d740a8608c33662eda195f4e26b90d86955c2b4c8470592d1c075bba0fb49b6732b2954fe76d0dc3b3e840865fdac146f03ba0f336f0397c6fd450770a2bfa5837f46096d3c673c562c9ce79b5e978c2a40450ed36b43210386a769de3a9063b93455b694c5cb3837e865ae61b82aa96661e57c41e405d260bc7ac84cc0e1c7515c47c320c61723177f0f57f599958dec24a3f81ab7f1b759c61487a243ff13790de540bbd1b90af233d8658b2805152183bb220e1ce017795ba97753e9c06620a85d4e28591aa6c1f440240e9c22a9acbdb568a98eb745ef435805cc00c2722b0822c1a88b8b80cd05ad2a69c6a356889c2389ac128c49d627a1f3c844ec85b82a405a2e1834cb753b415e32629b7397713aac7c70ef01a7bb3db86ae13b4ed51cc77e2a90de08c77d6938b903e05913477d1c38c98a80dd034caa3746018bc32034b27602732bb0a9cca9dabdb795c6bbe181576e69413c419674b646386b62c0eb8251572a630b087851892bbf726fca0b7dd8a170f19100d6087c191ab56f066a3f61f973c47fc62c331287dec02518039b32e7c320376b0fd82788e2a8ef38b1dd977889c2712ad258d4feb5f7426a4ed147e742b0995a97c2ad876e1860aac6ccaa82287edc68267362ea53ba9d0d91549a448fbb43e3f90802ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b7008db565f7ab9c362dc38dcd3e30e5da873c559e9a9222710e8d2e7f6417ce699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = 0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +expected_public_key = 707206a4b96ff9ac116a585f4394c4e83574bd16364b02bcc4c89dab6231e5ca7550517a335536b08665a136b47cf76ef816b037e91c3aec389b2411f3b397c70847a3f178509357db63a5d5caa882b2079644af11f01d18d9b79fc92744850a7e8b1c39e479c57b887e854cad028d17c84f5dd90dbb2042fdfc82db061afc7245c458b05f934d08849bef6bbd90349c4bac3ce44c1a51c622734265051787f7509a30d9ccf98250b42cc8e75c6d62a5a53944484578b262850e06b8717508c75d702783781290f64a412bc3f741312ecb795d15c17d198334816582209606210b73865fe79662943552b69b11bd141637b054a64497cea157e9156da70891da159c3e138f86c87e27376eab0204f8ec1edcf49ba47b1521870e46171d18268d277c1467b3be6c8c6895461166fc2c3f597fa6478348f640e44530f966c3008902c8625b46cc6120eb2d82506b01e45a9ed7a19f1c0df13c0346aab1f2cab8e01032b1f303147b5ea7e149b4bc19772408cb923e06614c9b1cb76e0b1d2eb1c4d1f6bd8294b280cb9ebae45cf0943c03b239677b7ea7c71265b04ca7c1580578768deb1cf10a2898143ef9d1c5d614b76a8322331a09c48422fd8b1c822384ae1886ff108e930692263965e949319ab94ee1b6763e460a0812780428aee4d446a61254722c9308c512711ab175312e39467aa21bcf454b8289803d85f33400d659dd8369dde71be20907651bae89d861def131ff805f56557cad430d22cb84a4aa65ae68c3f278b5816b86bdf57188240f60b54a8606b74cda0c47323639a578eda52575a32efe03b349b6938d763dbf4c44f13a0f92f75fc091658c60a32691a52c78569f322521799c91aa2cb550c9a683b061647cde186ea2ba57a8a1ca929420ef1895f2193cc6944a26e2688e611ec0124269f8c9e18c4032b731db827fe2930d3479528da2c2acd56a8182231b501b05c6383b070190782225d732f84273eb9655b2a4c5d04256a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd750bfbc28696808f52b13b09e43ff5cc098bb2a80b4c8f6a3c8a805cc6c69b7b02ec4f67651c65268431057fc7d1cadd8c4ba4965d67db44ab0c54926723a0842546fb0799e71483169ad17b60f9353777765157bc7e25d02ebcf9198c70a53bfc0fc7d51a42e260f7c5222a519937a48492ba079df30adaf127db4ccff100112e155501b3719a2a209983358771b05b38ceea677be4a4b086132c12f4594f427400f6ba5af4a07673464118cacd99a8ae5501ab22a235173412479cd759139d18900ce6ad44e0ca5ac230caeb82b6a98da48b318b620ef7093f06f20b5a0b4b95d986aada54891a00314094ca9478b790825a368f2f092d2978195ef2c52b64602929837d0b3efa65a61991ab61d8cd87f618cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a43272d8ff943261c5bda7a4f1092c9a6b7481f05bc3ff05ca5f1cd0b2bceb936233e0952f3380c4b7a1612c5628d5a6a05f837597c94ac061658c53f3da8ccae56adfa5a8156638be426cbee2025860c105da76b0e953c69957e649c5bf7151c77160a1d2ac9c541a80ab20c1b866c4fea987e30790b64b8aa5b12bf3429f47585ddc8780b9a6e1e7a3c030226ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf47186107219df88962b302010b755e002cce9d87781e4b717825fadc62a1a95589694581a18a188143d22f1bbf8769b3da59813fb963a78adb8d82b6155b02889371df684e3060134e738c682a03da9c62d2922c06425ffe8c2e18346e6f5296b7c4722e065d984cd17c8590b202865761162e6576a403e2806bcf618101fd5155702364f6920c45470bc9b1180b259c65bb552253406697e2371224a80045295a0e9b06899d06bf2b5824c9b2e6ca144647b01f45a811102afc4c7682e4b7ff8bb4464987757752942ac106389c847ab4dacc14c22b40cbed29d1e81c89704c21ea25747114f7b910ae8715b55671fdca0545007266f08851dc22446436e15827a1e834f270b38e5ec60222b1724c6054af281747739178c49ee04ce0fd39d5e7cc65644ae9a60303aa54a28a7c0ec4ac2ce7149fb8932ee26b67c2bce886a5fc9f321f5b06a03fa01d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_private_key = a5c7981510819ea27d27a945a0f6619d730dd196b6f3a158a4c48acfb82d1c348540160b0cc665c43c4c0e4567b46867ced06d2cf228d0b64706227593db7392395b7ea95360105c1bb05472787430654aa03b6e894c2add2a0467ea51b9486f3df18274c0a2079459df3b9aeab15d203b466ea426911572251b0c8fb51a31aa142bdc4142e393d3c527c841a03f796e0cf7cc71dacb47456fdd386527bccf6e43013eeb755924a22e3a55f74a8974b38e06908349fb3da5887d1a041c8acc6f07a75198462353942267d7600d5243095bb012d2a70be0a3fb2bb599832f8aa68652846ba501bab3aa574ad08bc991c8b86717b87a45041657d0264f35f0c2b70324eac43d591202cfdb9a7d357489f70f86d6308d3382cf9139106cb28d947ae3bc389ef18b728c1568436b3ef80644009a80f01ef550c794011e44f2812ef507bd55820a872b90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2053c037b87c51436cc83b884f7634a6950c419684af3b78d41006467105f753194144539df45ac7fa46e71815f53d2304b474a434b02517b083b058aed078dcf86746313bd8108148ea34658613560ca722a126dda147af8c5733705bc8343331bacc5b5b80e424ccf6114955056329a68a2a6403d65197c21da02a390c41ef713a814a798a434145b9e3a5c31a9614cdac8a8bcab6b5274490f5c45b2a307f492c28ff40ee39c2068a5826e8466542559e9409ff11b463e9a4eba0a2172ec8ea6332d3a5bb66531b670c52cc2f8b651b513e60a9e64795369e0c2cf56a9921669299b6b5399537e112ac358112810abc6945bde69aada92552a10219a630e26e4ac7d9b5c7469a960ac64a6d127971296c53a15df4c847d061e69cc030b9cabc6e58903c5adc88882cac147f2888263ecb6ae97a9b2aa245f131e2e2939f5c8bb8ffc012cb578b9babf90db062502b1923ca88b35c424fc6524128fd1d7b5ca719f5a9a538a51a97ababce07b006eb701ad8490b74462f93648fc39a2004db6e951b4c8219ce49395891594353b92b6b496d09376fb28711d87221851a5fdab80cc52a6352c062f06c80f891da2a07573b42bf0f6cd5d6b63fd4b1c5bf2572fc8460385a642e6290fb79a9b1cb18cbcb34bd87f7eb595f0598c67709d72011fbdd07a0eb6616a88b8e33571bfa7597be4cbd6976b93e32c2c088de3ab59dcf2234e553a5b2ab143c46df13211e816aed6d02bf6c13fa7f8b282237f249aaedbd3a6fe8771014c1b811c05fe86102c0b0e7e9b961c1000c82408d8a8aa381552920803418c49e1662c7ed8c3d35763c510585a78664ea0012a8a02f34b2bd7e96ee5c298dc296537c985577cac3e310568353ec2ca8eeab4bb1ee2393d5b3cdd25305b148fd8ab11f60b5871e9c9359a46a5da003e98b61d82c51cd9262764301c86268db87fa6273f9fa3c35b1c1fd822aaf2f74edf73ab5af9175070bdd7d5cc7600a516726c3e49348d138d19836391a54954ac4a0c029b1441c37965422019c2ca49cfca81317a211e22ea2297b865da163a0ae2a9dc25701e71847a05754cb733620a824f090d591c51c345420e226b8f3b846fd356e78b87f4555783dc39667349257c73fe78a616762278a8696eeb07871c96f9aa472ed463ce592bf0206d231a277ce2cdd00487e8307a97202e45755d6818cd5c9a82114b3bd9c00b9d9aa53ada6c5a4a0df518912a86c2483174ebf0c478e4cbae97b61a023e46528c1d917c230946a1aa76c1766d7e0259b4606f7fcb07579c54ca0424dedc1842d5307617225ffa8a9dfa03f46a596e343154aaa3ff6b2496b8b972b04f4c985fb7ea87d6e4cfc47490e130712155a88c1329c5119f91fa854e052dd8023a99c31612e791bd807f241227b9e54a9b6cc6421a9e038904b6565e3a91683a6891702ba4cfc576d24b58b0f64fea1325d0a6c67ee228c9c01b65470d79f086217bb5418109a0b5906b74a2dfc68b34797231c64bfae38958f636fc94b868961342c66017b8bb1d0b25409325e8012b75c08eb4c9a9735a570f3bb3ccc2838045a94473a65444bd2a783812e031382b5ebaf44279f3195a7c731f49a25c582d31a979a6076625811b62d809bcd23abbc8c923a888d9d3b875cb723fb52c707206a4b96ff9ac116a585f4394c4e83574bd16364b02bcc4c89dab6231e5ca7550517a335536b08665a136b47cf76ef816b037e91c3aec389b2411f3b397c70847a3f178509357db63a5d5caa882b2079644af11f01d18d9b79fc92744850a7e8b1c39e479c57b887e854cad028d17c84f5dd90dbb2042fdfc82db061afc7245c458b05f934d08849bef6bbd90349c4bac3ce44c1a51c622734265051787f7509a30d9ccf98250b42cc8e75c6d62a5a53944484578b262850e06b8717508c75d702783781290f64a412bc3f741312ecb795d15c17d198334816582209606210b73865fe79662943552b69b11bd141637b054a64497cea157e9156da70891da159c3e138f86c87e27376eab0204f8ec1edcf49ba47b1521870e46171d18268d277c1467b3be6c8c6895461166fc2c3f597fa6478348f640e44530f966c3008902c8625b46cc6120eb2d82506b01e45a9ed7a19f1c0df13c0346aab1f2cab8e01032b1f303147b5ea7e149b4bc19772408cb923e06614c9b1cb76e0b1d2eb1c4d1f6bd8294b280cb9ebae45cf0943c03b239677b7ea7c71265b04ca7c1580578768deb1cf10a2898143ef9d1c5d614b76a8322331a09c48422fd8b1c822384ae1886ff108e930692263965e949319ab94ee1b6763e460a0812780428aee4d446a61254722c9308c512711ab175312e39467aa21bcf454b8289803d85f33400d659dd8369dde71be20907651bae89d861def131ff805f56557cad430d22cb84a4aa65ae68c3f278b5816b86bdf57188240f60b54a8606b74cda0c47323639a578eda52575a32efe03b349b6938d763dbf4c44f13a0f92f75fc091658c60a32691a52c78569f322521799c91aa2cb550c9a683b061647cde186ea2ba57a8a1ca929420ef1895f2193cc6944a26e2688e611ec0124269f8c9e18c4032b731db827fe2930d3479528da2c2acd56a8182231b501b05c6383b070190782225d732f84273eb9655b2a4c5d04256a64ba74d245ca744cf8a0b516015847cc34f2e98566ad95fdc87a8fd750bfbc28696808f52b13b09e43ff5cc098bb2a80b4c8f6a3c8a805cc6c69b7b02ec4f67651c65268431057fc7d1cadd8c4ba4965d67db44ab0c54926723a0842546fb0799e71483169ad17b60f9353777765157bc7e25d02ebcf9198c70a53bfc0fc7d51a42e260f7c5222a519937a48492ba079df30adaf127db4ccff100112e155501b3719a2a209983358771b05b38ceea677be4a4b086132c12f4594f427400f6ba5af4a07673464118cacd99a8ae5501ab22a235173412479cd759139d18900ce6ad44e0ca5ac230caeb82b6a98da48b318b620ef7093f06f20b5a0b4b95d986aada54891a00314094ca9478b790825a368f2f092d2978195ef2c52b64602929837d0b3efa65a61991ab61d8cd87f618cb9c54a42cbe98d96ff84c84ac39bf89f490ed735945a65a43272d8ff943261c5bda7a4f1092c9a6b7481f05bc3ff05ca5f1cd0b2bceb936233e0952f3380c4b7a1612c5628d5a6a05f837597c94ac061658c53f3da8ccae56adfa5a8156638be426cbee2025860c105da76b0e953c69957e649c5bf7151c77160a1d2ac9c541a80ab20c1b866c4fea987e30790b64b8aa5b12bf3429f47585ddc8780b9a6e1e7a3c030226ceb84ac958bb5f5ca07596be91e63182cc5b48a7caf748cbf47186107219df88962b302010b755e002cce9d87781e4b717825fadc62a1a95589694581a18a188143d22f1bbf8769b3da59813fb963a78adb8d82b6155b02889371df684e3060134e738c682a03da9c62d2922c06425ffe8c2e18346e6f5296b7c4722e065d984cd17c8590b202865761162e6576a403e2806bcf618101fd5155702364f6920c45470bc9b1180b259c65bb552253406697e2371224a80045295a0e9b06899d06bf2b5824c9b2e6ca144647b01f45a811102afc4c7682e4b7ff8bb4464987757752942ac106389c847ab4dacc14c22b40cbed29d1e81c89704c21ea25747114f7b910ae8715b55671fdca0545007266f08851dc22446436e15827a1e834f270b38e5ec60222b1724c6054af281747739178c49ee04ce0fd39d5e7cc65644ae9a60303aa54a28a7c0ec4ac2ce7149fb8932ee26b67c2bce886a5fc9f321f5b06a03fa01d08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165143b9c53320cdb1b7e8d71efd1f0a1ad5ad1e1ce84dd9fe7c92f19c926388e3cda1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +expected_public_key = 83306092965daaf95fae22ab9782be28474bab8785f6030f9b360a861c741619619a74a96fd30cb6334b6fe379c9404f95c5571b2143657c956e031f2a5a03733aa24a73224f89106f7514a8db8515bb9c7fb4179b9b410b7197dd849c3a869c687705c692842aa8bdff5169cf0937a0d669bbf54c92651449252245476b4ea5126041b5721002ff129272fcb76952791b635b8bbc6867f051935508aea7bbcd722c693990e3e8078b1629d21c09e1b417795445fbb857e8fb4f0a1aa6f761657584165d38ce815307e6d778cd63a283e081a5372b0ef040b889cf8041cc324145a571031f5c218ca816354c2c41817f196272976c2ff6115f5257cd13b373bd2a757dab65d1e1863ca4b7ce559c73ca919198ba574a9ee64047b85a6afaecc043327e0800cb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a6fc2ef7d2c4d175c2c8bc812d5b3d54695027a91baf657a60d4befe7562bdf620bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b602b02cd036a24c23816c96deb45c2a8cc7d623bc31e8811468a7c2b85c209b27364c4956b6c30c8094af8401a233c5e4d348980491ad24b04dc2706b502a9c8390ba3f611344c44bf50241cfcaadb7851685c73603b429eac840c6b9a7ada53416470f13311c2218017681204e33a588981f66a02b4e97f1cb8ab61e6a7fe45232b5545a3a35eecf43e67a4c29948206088b062b81875b632c1767789563bc947a59305afc91ac53387925b4b3c7ba24d84ab126d3b88e852433dd0ca40892d3429962be6cbeaa85a3abc46a27b525a562670c801f5f0566a7558197600439a2b98b16009f87147c55f99fb109515b125963f7240b12a4535cfa22ab53a3c5eb8c2500ca5ef9b2d26d93115480863843656c59a85b4a40cf8059d063cd2e7115d862015d059d3577cc1803e6450b811ecce3cc83e039520d6b23ef8576bd342094ff2a908f42f4ad88e483229f4ab41db2107e48aaf1b32a275425492b7bb423632e42a6c31e320528327713a86b4e83e929b217c69b34ec3afce8628c23a6747666735360b7e70bffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c4756421ac51ec963493c2d72791cfa2c69b58bd5463c544a3ca679b43ddd13ae979bcb158744d45639586959d6ac5784c074d0ca20f326696b607a206895d495f61525793a839a5631cd94bb7e39b609db1caaa3144387c46a22b2ed393060a679bcb13a7c781aa7be1a9d4d3a58a9831f15372825a08d4e41d0e3371e9f796ef0ca50e128afbb5b83ca78ad7ba50276ca2244b3452d02d803b0e8854181ed57f04aab2bfbb1a48cb949f570eeb550a9352c3887a2c37341d8881beff0acd11a8714665a05274613fb168faf6c151277ce03b9f711034e642425aea6e37f536c27ab4c859a64b96baecfa10abe982fab01e82a48538c12f2f615abb815f7fbc46d20378c77626fd4447fc088a7cf626180b2443226c0d560d028b54f884825290cb5ffabc1e152626e62816069a8f9965d89a09b9a19b9c8734a2f71808733a49f30bae54659c375de1a1181b478e08fb7ad85983d7809a4c7bbf67721beb9447191a63a10c2cc709a2d9489dba469ad9c035664aaad90bb8b7846152218635816ec4b1b39ad3b1e37201fd468a134445e183bcc3430cb2a9015a10b0369c079e60a42d387675dbb292985dbcd4b954c75b56a1152942ad9ecb12c8074c1998710826b4b1044a1c368d4808d081d7be1658193c1c0f46739ef1043f1ee38e90ea989db0c9d6d8568eaaccf1e986e4f3b39b596f4bc11e32fa03e10418dbf464f435680dccb76e0bce29005950ea7762e0a86fa4cd5e8819f3c95ff713b006155438d9211350c317589a5c599619530b664070f3715bd3947427476124f328b850603533a651a38c4119c2da956383c0090bf31a378474992636eb10b079b319c821b4ba9336f413929850550c9271f547344e682780eb9d2dc84b742b49eab256b6d8149a904ba0293a0a40731b98751a71371059b84d323970a385408807bda11497c42478bca048b1c50ed3681aa8044e8884458085b4834e313825b3951e8b743a765a166bc1a133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_private_key = b04c33b257b199352a85b55624f1a1a42b2ab72c4810b839b2bb2f51a502cd498aa258373eb3bd43e03973d129e4fcb61df58986809ec4ea4333659f03dc0fab236cd4e815d3f9524e90a28a3a0af869735b362fed9837855429700cb815c43a6e650e54d6267a832dc0385696274e1e73a12b5960a8409a4b4564de909b797771b4839782526fd69abf516a73f9eb8130f41cd6103a6e67c6724186d1c709d3d90141b1bc1c028e28324de4846bcc6837fc243c54dba144c40fcc6223fd19b8f54c11bc0982ffd366530abad387946e1495a3c05d9cfbb62b28778905ab7d576610a74b3daac9767a051b153af7c6bf0177a4074397be410411cb33ddcb895091990dfb85aee15e9f288d01ec5628034a4adb01da09283493baffd36d224b1efe096289a2afd427b82f8b04ea44319f4a16bb07bd21026f2ef550b919ad01cb3744b37103eb54e62400e03367001510776698e28b4fc367a77f1b4690cc2916e8ccf1fa55aa3495014724f1e66ef7ca8283d917b501c931274d9808a8103004176bb69783c094bbbbecd5b90ea14e7cdb9768498b22332283f6a079991988ac6a85bb591ef299bc57027b0ca9932a41c14c193467374f133bb8539c2d5164ef11b70b4a2cfcdacdf6841cd835c4f4e174be3c26b55770acf4137666a431d669fd5775a71749922c0b223abe36284fc880c3aa2a41f45a4a299c647d6738585287f7a47b88ea1c6c088c6207646d99cef5f56a2e02cd3ea85202c7725dfc99d04b2d52600f0f89366a3a83f8dc74e4a27fc58a622061a6332403ae8cbd0179149b841f5e0ba193ec237ac57a4cd5528c10545cb75e35a20c3ce63950c09a7b0810b84124f3a00c9ebb67bda9b2ab42113e631123b4a85897160637a32eb856d55c2905f7c655d40c84e92e773056d2392d43e33c4f9256dbfc7aa0683802d04d218139f829ae362c1f48096fe47b09756c36873cadc5300cea8094e6f8925c1b81ade69fee5420b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd53d1235800681dbc7657a777bc267637ca2954c09344110a05e2bb90a83f95990986fb559bb1282778933631701393b705a5c122ec3645c1b364367c83444d30fa438eb3a478a0bae14270cd49556399085c566d9e6c467dca66a3f36370693ad5f86a9932773ae5064e9bc73ff7979a5510c88198beea7ee2aa494eb046e4d70a3f9ca0f88b234f6918f7eb41db97a327654836510276e0154e7a4dfa088b8acc5f02f598d1494bfbd07c3132c5ef6c3b466606b3d93da2e69c96744095435fcacc2d24c3016002b5c4b988877ccdb9233c490a8b121ba7821b529de85e638168b0565d50f735d1cb54cba91cfc1b9eff882a643121e877c43b6147a2a8266196346859ce53340208253ca419276b884dbb3b7a30ac3de983c75ad73995a0b62de7563ec9a4a715bcdf376dfb6433de691c54e660f4aaa4b184015026b6189415e66c90dd32c0b015aee63b5d8b3cb9ea206e45ab4938bc86fc54c7598c6553c29ac34b2213b90afd144c8b4629a560382778b28d666667caaad49633a8f985730318eb033374b5cbebacc7f453ccd8e77c5a9abc12da1bc1733ebaf908ec85a79ce5c1e6653026011d5984546c99bda921087cbb63cadab07a18ad591899470582aaf443652c723d954f7e529579f4a65f9736ba1b34fbe728215b14ee450a89297c8ea15b0706314b269a8d88ca27210d94a7109f261dd7b6b2bdf32f94c9cf76fb196b6b60451246d97a2b34f05fa23c408782a93452a9ff43a8af57a59e8305d29237f58c1d2539b49d77284e5583169247b252bc5af5a9aa958846c0cc0ce76ebc8622013934d2e4a0ba1814da282312fc6fd9683048fb308b159205e7050f8b2cecfc0e136a623230711574901797826f02159aa69b45865f12712acb794acd187309c447deb51a81643f82945be8a864ea1ba348b48214e4c003a641d4d74e3000c5a4392ff7d65a5e02915d43c3fa8646e6119a5e23a099f0860039cbcaf82031948c65cca097633c27d11cef810936c4358bbabf9997948577b7504bc87dc53bdc96a68a4c5f9ee52ac66748beba0a4cb1654836895d795f45423b33d06f927aa53527a2d1c000c18a87f2cc0bb589284dea64e96c5083306092965daaf95fae22ab9782be28474bab8785f6030f9b360a861c741619619a74a96fd30cb6334b6fe379c9404f95c5571b2143657c956e031f2a5a03733aa24a73224f89106f7514a8db8515bb9c7fb4179b9b410b7197dd849c3a869c687705c692842aa8bdff5169cf0937a0d669bbf54c92651449252245476b4ea5126041b5721002ff129272fcb76952791b635b8bbc6867f051935508aea7bbcd722c693990e3e8078b1629d21c09e1b417795445fbb857e8fb4f0a1aa6f761657584165d38ce815307e6d778cd63a283e081a5372b0ef040b889cf8041cc324145a571031f5c218ca816354c2c41817f196272976c2ff6115f5257cd13b373bd2a757dab65d1e1863ca4b7ce559c73ca919198ba574a9ee64047b85a6afaecc043327e0800cb127468310a965456ac851a768f777053d48c860a403693b607fb6d8cebadb2149d8ff665a6fc2ef7d2c4d175c2c8bc812d5b3d54695027a91baf657a60d4befe7562bdf620bb3888645a55a0e935bbd8504c27720828ad8ca9a9933b402735564a4a44d7265b602b02cd036a24c23816c96deb45c2a8cc7d623bc31e8811468a7c2b85c209b27364c4956b6c30c8094af8401a233c5e4d348980491ad24b04dc2706b502a9c8390ba3f611344c44bf50241cfcaadb7851685c73603b429eac840c6b9a7ada53416470f13311c2218017681204e33a588981f66a02b4e97f1cb8ab61e6a7fe45232b5545a3a35eecf43e67a4c29948206088b062b81875b632c1767789563bc947a59305afc91ac53387925b4b3c7ba24d84ab126d3b88e852433dd0ca40892d3429962be6cbeaa85a3abc46a27b525a562670c801f5f0566a7558197600439a2b98b16009f87147c55f99fb109515b125963f7240b12a4535cfa22ab53a3c5eb8c2500ca5ef9b2d26d93115480863843656c59a85b4a40cf8059d063cd2e7115d862015d059d3577cc1803e6450b811ecce3cc83e039520d6b23ef8576bd342094ff2a908f42f4ad88e483229f4ab41db2107e48aaf1b32a275425492b7bb423632e42a6c31e320528327713a86b4e83e929b217c69b34ec3afce8628c23a6747666735360b7e70bffdc586cc75c7768c6b9497ce7c93c8938a81a8545244c4756421ac51ec963493c2d72791cfa2c69b58bd5463c544a3ca679b43ddd13ae979bcb158744d45639586959d6ac5784c074d0ca20f326696b607a206895d495f61525793a839a5631cd94bb7e39b609db1caaa3144387c46a22b2ed393060a679bcb13a7c781aa7be1a9d4d3a58a9831f15372825a08d4e41d0e3371e9f796ef0ca50e128afbb5b83ca78ad7ba50276ca2244b3452d02d803b0e8854181ed57f04aab2bfbb1a48cb949f570eeb550a9352c3887a2c37341d8881beff0acd11a8714665a05274613fb168faf6c151277ce03b9f711034e642425aea6e37f536c27ab4c859a64b96baecfa10abe982fab01e82a48538c12f2f615abb815f7fbc46d20378c77626fd4447fc088a7cf626180b2443226c0d560d028b54f884825290cb5ffabc1e152626e62816069a8f9965d89a09b9a19b9c8734a2f71808733a49f30bae54659c375de1a1181b478e08fb7ad85983d7809a4c7bbf67721beb9447191a63a10c2cc709a2d9489dba469ad9c035664aaad90bb8b7846152218635816ec4b1b39ad3b1e37201fd468a134445e183bcc3430cb2a9015a10b0369c079e60a42d387675dbb292985dbcd4b954c75b56a1152942ad9ecb12c8074c1998710826b4b1044a1c368d4808d081d7be1658193c1c0f46739ef1043f1ee38e90ea989db0c9d6d8568eaaccf1e986e4f3b39b596f4bc11e32fa03e10418dbf464f435680dccb76e0bce29005950ea7762e0a86fa4cd5e8819f3c95ff713b006155438d9211350c317589a5c599619530b664070f3715bd3947427476124f328b850603533a651a38c4119c2da956383c0090bf31a378474992636eb10b079b319c821b4ba9336f413929850550c9271f547344e682780eb9d2dc84b742b49eab256b6d8149a904ba0293a0a40731b98751a71371059b84d323970a385408807bda11497c42478bca048b1c50ed3681aa8044e8884458085b4834e313825b3951e8b743a765a166bc1a133573f3af78dd296a398d581661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75f2d009cde4abd55a2c7417c9341792e60eaa8e26b53a3aae805746401c4c446f56047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = 2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +expected_public_key = 6cb55b5e77c06784a223b9cd2d59478b608d2e79b1dd02803a272b54f2ac66498ab1f621abcc61afe10141eaa935897f89208acf9b3593aa90fc9081b8993d48a84aed0252d7f28dd48571f1b318f2d22ad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9c211f8e959f0d75b1e11486f197368188c8eeba30a0865711e046f9483d3e953a55802299f02968a35374e6a2b9251af66790b73c200f74b5fae2c6c4ec024feb61db55c28d2a99a67436bf5879835bb42fac07b9399ddcc01a6d5739c2c4c4ab217a3e28a06e6ab367354195c5080f334e0674397556047fb02d195736db39abf7c61e02c11e9da5b1c4829039f159ac3baaf5e47a2e6c2a17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd492bb4dcbabef3c20f83412a6940b78053e26227fbf7608f2b6233ce17db500641b295e9d4a468486818a9375e074b1de9124cd44c05fb975889192666a38ebb79f0e80a21d1c0358f24eb4167dc1bb2cc4fc076bc634e37421e0a5054490b6f45695e59cbd4e7947204c62cf0b61c2422f39b2a1abe24229e456cf9b374c8a17c85664f5c02b575a640074354e385e36a5b0d373bff3105cdd110cf0ca235f3bb18a051b4894c26b6c6b8a4a9d185a6be6127a1f172fa4e75971552ea357c891210cdedc7a0f3278e930a0529b056820c7dd699a436b80017354d106698401b6092a049eda3a07674d65956943b96c9191340046148aa8c6837acdbca06fce4a341d526d437657388ba7b7632085a921e447024c5b5ab9198b7b7a6b8380b4daacaa6b17bb508365c34b8145aa3b2f5b11722345d80554919489e49433bb558a3c332eb12b1a36746e5a531eb2a6afaa1532183550defacebf4c6bfdb0a035faad062b1cb2276505da77dd99935b1a3bb762666de6506d3cabcaf8b5dc876fbfe55feaf4acc4a628e0347a66f424ca2095e2a3605075786f9b728b5905ac09113e217e663a91f3430dd6d4244bd2cd50b69968d95bf9b07c0f352912e28fa9f0600943a0ea1578955b314ec1bcf13bb4cff6c1793b11cb1b08bd55bd850136e539cdcba0c8f8b1a1aeb183dfda8b64718bb1d8707889c74d92737ca3619e42b7d971783219882b14c671c5005c352540cb5621c6409366adfae73b79957539f15bba26166f181a407b5e7bbc14c54119588b630b782621eabe39567032d76716b9684e217895d82e0ce9473cda40e0065c2d91a846d7cf9e86b934381a36f130336c7eb7913d0aa466737c8aa34453e4c0c21d098906e0229afb13b96b6e717a02089a19d479826c585e1f8695f9586b696c805f0533970ac5dae753903044ce0cb180276c4caaccb71169080474b3003e0296271fd891c1a788a264482de92b47549bd2867a8024bd65287f80b25dc18771f8f697d8a830559b544dbbcc8c656db07ab70174855192362dac79783357b199b090840dd5d474227bb8502528cc5659fa1b1575c7798052393866a48a006ab2572d7b8635e71448b1d48f0175baf92bbf98e12660f6730845164fc42aab8480871c3b2f844cabac957f62aba397abd4aa1319e7adef132aa7f55abed6143efc5483e2c32b1aabfaf3161bb24c19e50e95673fe6668617111a38525fa76cc314f891c9520b88d7b82f5c415b7310d20b5935849ce2d138aa162bee6a5822c52c5704b1f1b6838dc88ecf0b3acf5a5868f2576a58730fc7b986361dee901f5e050841ab06364c72029b259a754f74a95b32179bdb35888b0872c844443faac6f9f67aee9055e4f909b3d424d6167725e960185738df3a30930b4d74dbae5a07463126b9c6ba257ab8cc893758759b4d24f75cf2f745bc6337e366218716bb4c5b8d7f0291488c8e20990faec84cad2616653104d621b3662838c0d2a27e4a3b85b25f22ec350469582e75408ed36141033043e459fd7b0087077aac13058519ba1c210f68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661e007a8484540363321a08975f024353d72a1b08252173c874e515e543ca12959235537cc4f314f7c81015d462e2182130c24d3f572de234441ce52e48aa67cd8b2941508edc9c421ed797b52343c6c792e4e8a4001936ad81108e4080fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_private_key = a5019e7b82405cac3c8f45bec4e70e20590bd7e543d465ba702cb1447c0f114cc44f404a31b091c638347cf5a464106a2f92a0b4e600a3d86ab9f57efff088d1887865c695c3aa29ba08356da1b4042146e8817f2bd56bc014071b896d5b2cba9fa124cba45e294a0f30fa01e4eb18262059cc987c64f9185aaa12d7ea1f2780308a91a3b2f171d9c41d166872bc7b070d44af8556a356b631a6eb2e804cc09c531eeca476adc8143eeba767298bf29c19fb2496e0c573938babcd749ee2d02e9817a3ee5a687f9324e7e1082892142c04ae9715c4a6980d73c6a54c16beea97a659da476e49c1dd1b8292e04321783e0a66a36267673e92c2c7463668b1742987405c1621f94b87ce88aebaeb7bfd787116b30a5b64a7e8956321463b351a9753a0389937b7aed431a5028d309cbed2d8ae67f859ce371cd1b3cb11a8a70d3b9b92e15530a260d1874118ec505fd451897712ae4104e67b1d2bb2676589aa4e8833e03b017aeb2666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb325144111c75e96a13b5566e8258e36d34a76096f9b013236b3036bda5e3d431aad3ca33e9a0916d8cedcd3466c75c1b5603a3e724c60a796e0844cc0d79686f086c510ca0cb11c2e936ecaba446560aaf0931c6a82298bdc7fa82aa6a0b32d361b3335cb83dda38417720e9e745bb9ca008908cf6931ab2b4a7b78036704153359dc4fdb5742ab3c39a346005374cf3107b95cb771ff1c9592d59c810a93e3593169ab26de85077dd79a3b3aa03c332a9d177d7ef88624c285a90099d1d0209a0bb0c425ce6ae9221613b2cd596aa77ba2bb98a385d2898d504d68117ed06233e69c43b541438b3274b579c1a5c27b0d85159836aa48907f768c97b6b2b19f475655022691182b2d9c80aec12eca0890c9e47bf764684ff1a94d1083d85905212431afe09342004b44a090cd71357d2431c923b3ce08bc836b3edb82ab2fa3c508867eae87bf2768ad61d4894b123b6f861db52b9b3eb77a8c99839e9108704c907e258f8d8001567078037aa1ab87b03a46ad3a0a30c753b8bd790923b7454f84c67ab6bbbcc105edc36ab6ab67c28c1d3a54bd06f9c09c12cac8483e015301db6650ca3228abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6600a0d40489d0534423776184c85057ae00e9636bfbfa76c2d329625747968f53d1eb26cf4f95d6cca45c60b2da0f1899a7a1fc651c12bc2c3a2ca16d8aba4e05c0cbcbb2b72c48ef55403462ab49cf6576d8c358a865de1f795cc0629f4b13837b6b1704250b8e97f7a116fb63a0dbc12c955b49a67094cfeeb0e8c7b23abe4bdabb787d3e45ead108a96d3206a4977aa128866e596dfca9d68996d82021a4380c0991561ae40a96bf490dd5538f0718098479a5763787939453a7a87a359643885bc5d6149ea048b5ef1adc65c78e4a9c917160bdc625352596034b3558f98637b33061f769cbe341f9c764238318882caa978996d1c321a92838d109c187011bf84d17fefa0271eac7d5ec90743130234e79089f5b9a6f0267813939b5a3b22321376fb1792d8bcf8b072f387305ee56b027908acb477e0e744d0413eabac316c13c242a818cf873533bc3714ba136d477a7ef0c8e620b9e18843f4932b6af212b566bdd93c74ce56abf92755cf136f79784aecc9770a136fd8e245efd79c99095d1225885df1a752063af9e45ce5e10634b817f31013acd13ecf16b7e023cd6c39869b98cb86ea5ab2e655e89b27ed83a65d7a849cb68346e216413239073bc7a5793584acc60f320524048bb9e99e02597eb5e68a7af1033c9603ecfc8c833061f5d27124e4be67752b39406c91d01d5b7c0e7889ae037bb338e64c69ab5d96296ddef899e54b72609105af54a9216890e842b0287bba2698a41f12705a68888b3397311bb9a60c894dc71acbc44f8450b2132962d0f8a6d992a26594a3e2589edd2460cb62a57adc71753a7a94d7134bab8fc1d9c688629a99b0860efccb33c8238c1abc54c11c8aa6c29aa62da3235d97f0c2f65092b551c9a9794c89716ebbd119a27a4382101a3e4b9bf540c1c0f05c3bd53c25f416a9ea3221c110dcec6262ab14114b566cb55b5e77c06784a223b9cd2d59478b608d2e79b1dd02803a272b54f2ac66498ab1f621abcc61afe10141eaa935897f89208acf9b3593aa90fc9081b8993d48a84aed0252d7f28dd48571f1b318f2d22ad487541f23cba785b8d3cc8a3338998c9c37d3f4622a357d9c211f8e959f0d75b1e11486f197368188c8eeba30a0865711e046f9483d3e953a55802299f02968a35374e6a2b9251af66790b73c200f74b5fae2c6c4ec024feb61db55c28d2a99a67436bf5879835bb42fac07b9399ddcc01a6d5739c2c4c4ab217a3e28a06e6ab367354195c5080f334e0674397556047fb02d195736db39abf7c61e02c11e9da5b1c4829039f159ac3baaf5e47a2e6c2a17d6906c095a484577fa435d39f4774de4a1fce9975c0ac10c56b3ca653fd492bb4dcbabef3c20f83412a6940b78053e26227fbf7608f2b6233ce17db500641b295e9d4a468486818a9375e074b1de9124cd44c05fb975889192666a38ebb79f0e80a21d1c0358f24eb4167dc1bb2cc4fc076bc634e37421e0a5054490b6f45695e59cbd4e7947204c62cf0b61c2422f39b2a1abe24229e456cf9b374c8a17c85664f5c02b575a640074354e385e36a5b0d373bff3105cdd110cf0ca235f3bb18a051b4894c26b6c6b8a4a9d185a6be6127a1f172fa4e75971552ea357c891210cdedc7a0f3278e930a0529b056820c7dd699a436b80017354d106698401b6092a049eda3a07674d65956943b96c9191340046148aa8c6837acdbca06fce4a341d526d437657388ba7b7632085a921e447024c5b5ab9198b7b7a6b8380b4daacaa6b17bb508365c34b8145aa3b2f5b11722345d80554919489e49433bb558a3c332eb12b1a36746e5a531eb2a6afaa1532183550defacebf4c6bfdb0a035faad062b1cb2276505da77dd99935b1a3bb762666de6506d3cabcaf8b5dc876fbfe55feaf4acc4a628e0347a66f424ca2095e2a3605075786f9b728b5905ac09113e217e663a91f3430dd6d4244bd2cd50b69968d95bf9b07c0f352912e28fa9f0600943a0ea1578955b314ec1bcf13bb4cff6c1793b11cb1b08bd55bd850136e539cdcba0c8f8b1a1aeb183dfda8b64718bb1d8707889c74d92737ca3619e42b7d971783219882b14c671c5005c352540cb5621c6409366adfae73b79957539f15bba26166f181a407b5e7bbc14c54119588b630b782621eabe39567032d76716b9684e217895d82e0ce9473cda40e0065c2d91a846d7cf9e86b934381a36f130336c7eb7913d0aa466737c8aa34453e4c0c21d098906e0229afb13b96b6e717a02089a19d479826c585e1f8695f9586b696c805f0533970ac5dae753903044ce0cb180276c4caaccb71169080474b3003e0296271fd891c1a788a264482de92b47549bd2867a8024bd65287f80b25dc18771f8f697d8a830559b544dbbcc8c656db07ab70174855192362dac79783357b199b090840dd5d474227bb8502528cc5659fa1b1575c7798052393866a48a006ab2572d7b8635e71448b1d48f0175baf92bbf98e12660f6730845164fc42aab8480871c3b2f844cabac957f62aba397abd4aa1319e7adef132aa7f55abed6143efc5483e2c32b1aabfaf3161bb24c19e50e95673fe6668617111a38525fa76cc314f891c9520b88d7b82f5c415b7310d20b5935849ce2d138aa162bee6a5822c52c5704b1f1b6838dc88ecf0b3acf5a5868f2576a58730fc7b986361dee901f5e050841ab06364c72029b259a754f74a95b32179bdb35888b0872c844443faac6f9f67aee9055e4f909b3d424d6167725e960185738df3a30930b4d74dbae5a07463126b9c6ba257ab8cc893758759b4d24f75cf2f745bc6337e366218716bb4c5b8d7f0291488c8e20990faec84cad2616653104d621b3662838c0d2a27e4a3b85b25f22ec350469582e75408ed36141033043e459fd7b0087077aac13058519ba1c210f68c47959f3a98ae5a9387964873cac12056c0fe689d1769c017a661e007a8484540363321a08975f024353d72a1b08252173c874e515e543ca12959235537cc4f314f7c81015d462e2182130c24d3f572de234441ce52e48aa67cd8b2941508edc9c421ed797b52343c6c792e4e8a4001936ad81108e4080fc88574fa663e0bb4ca5d47c9714978c6a86000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a1f06190bdfd692cf499be99bacc4beccf048c89926769f1b254cca9a9a44089a8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +expected_public_key = 8045b8693056995a847dac15ff49b59a1b9aeb2188c46214fb86a8ff8138c5e8b63d6c29447bb60a56210ba594a3027f4d7667edd310b678523e87830a469e5a758024fcce5a7741a7368c790cbd86204f6ae2a71c2a6a0ce80d14f26e53c175318cca9fdc5fc0a110f6834e1a32986cbaa0f0283376b25276b304dd4c9debf7ccd4c98bb1e605abd84bf824a61f5218671b17918432b32359feda8cbf822c62e86061ebcaec22af3ddc83b45252166a55fa2b3942e346a688cff13272a092c22c5c156ae0b63214bc7919aa90847f9de579c6eacab9690c6281685f4184736092d7b365c2d0aa977b0999635cfb0c44a8193377205a49033fff2133853a4559ba895f0b5b36f2cced166f7dc4aa6d064e6223a114580b58128dcb30b5c8da30b97a497300061c9cb9c7eca6924b6c6b19469645a443851e59248a3759164c02a8a86a9d1e86c51907074c7003e1e0764ea650c9aa9f1ed14831363e56104d4126bf09207d5544c5696a69daf7a748ec7be4b2cdb3c628d5a302f1a82eeefaacf731c5ce3bb6a26a80e7414044087487648e62f9c5d9e29cebc8b5bf111995616b8677778a8cc6b55618a26c6ba74753a2d943fcfb838b6a14935a38cb96906fe2008d2ac8622b50ca4a79035a403946180fe69844020bcc093bdba58d1496ae7dc5741ff16b5b5185a86277ab65c92551b48180972ba55580cb8cd274bc58a83041c7c0349191cf7c9be0a24f23e81e9892c2e0fa979fb4aeb3648ac64534e6c3823ed28cb24569e0931506396140b72f059818bd483d70c8132bc38ad19b995cd9859bbb06342ccab0180e8471c77ebcce2cd9a09d32c7de1443f6c588ac2308612b3b3cc51c670c935a91b973063a31703047a630ec03375831a3357940d2285ec8363bee2b8626656669b36875875f32592e9fd5c1e48879e58746dae41a9e8043ad3975de6c0f59f6588376682c770bd2cc3e427ba50070a3d1572fc7a61f08773d60bc1dbcfb087d726372d23bf89647ce6792f1a12fb87298fff567e6ba833423c43bb157b507009d46c8bed6704e5b23e5c431206bc3d6ca5665db9051d882be08b714950054a6c0a341bf953c4936830a74db1e7236c5cc3b49ffb6230c02978b63020ff75e26f375621b26730aab7ed79dd7facf6bc7a038b779bfbc43866123ea910c4620363a8b885c7017741a22c35506fad12fa5e2360c55aa99528db32709b41c79e7a1730be27ade379ec986239cbc98c3e2bb818b3c33c29ce1b6cff56a58f97c0968e83156a5617a579e13fa208c840591ab630d942ff415479c8343230a9f150b39b1e8259a839eaa370b9a083f50a8992c2b90321549a15b482b752c65c11dbd5b302e630293d2463a47cc54a02c6b7784ebe8c6b487b185898887f1590ed21c1c757d248cb712b7449f712082b7591b34604af799f9b5ce2aab6ce9464528418b01b1abd3e4598ca45022809a708460eb72bcb708c5bb8c272ea187e0158778760b7ca864b0fa51347b4d7130a2ecf4140a8988b94498db660229f78852fc149dd9c5692c41123a6f1310743c892f761345d2f685e5f3a924e620d7122cfadb4f8fbcc95f5a65b31728624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a340100ad8384a2955462bd703237d331eb7742349876eab4c2c933133d3c833d185f129c5804aa1453b0947da3cf3bd44051f70de00b3cb28396c180b501e70157c22486f8a82282652bb21fc23c3bc123b6c3d6acdf079906b149ae2b52efdaaf3d9b0ecaa92ca9d8694bf07d4229835f3a0a21253877e1a39b4699039041abc8c0b3f6aec29bb22e847131670c0e7b5abeb2455a246d03b6066114552476a18c23b013a812d65a15d021c117f926607c076892499056c1bf058c52ca1703a0812678b4485b82814bb6960a86c3454b99b731cfe15ca5ec005f866b28235036e632b89cbd9aa4a6e70ac944ab82661134ec2ba3b871272864a85ef61f86f51337651eef063fc6f07a39d3ba7aaba5d7357506c550bed913788947a1863a25209cd01200272517adca5f1087c984e11f13404d046c5537711c56577adefaced330230a42cea4e13d0e899394f120ec34c2a6054e5d2ac90696115515345aa2125dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_private_key = 7ec737ebf52eb7905da8b3c58508928dd74462e8968a1265bb3b9780649210c8202e2950ac11863bd78af3123ae9899ceff1992608cf5bd1b4eb0ac1c13ccaab4ca89a869424bc1af777cfc7d90a071273f5aa5df310493fab17ce5b6477c773d8cc81d995509ff3a40ce80e734a9e8968b7fbe79a9900ab85f7b442077a890688dcba0bd5e64ae491ce5d39b554e6b82b7602a149a686c19fcee21b8e3b1792e7529f2307505c77ed84a63a68258e832bf0f118bc05c91a6b216ebcc051b90143b9748b365ec841b6098c4eece8aa8231bc24b03e732a0ec55aa5b0e3231efb7c7f0ab21e2544072c22b6b4075049b63fba05c68a936989baa2e55ad1846fd1e335568b01d4acc869e710357708bdc25db545447e41727224545ca8c16bca5458eb24d746a12e170ef191cc8dd840e26910cd9484b4e40d0c7446959a521618b9bc472c8001ad0d1c8428c43c0fb3230fa9b17694284375a0e1563fdaeab6cad367c9949c4723802d6931f0c212b03004675652b958518d31c8d4b06dfd99820702319e668dffb5c88622170b0c0eaba56ee7b77ef5d7600b9c0bbbea5b99e05a9443bb81a68c22c7904a1755d4c80a47ac148ed13c3981c6bf4122a7880fdd597429a32d6046981146743ae85cc8c0ccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398a9236d02bed9b951f6d43a67ea06f7fb803acc33e9552e7150c34003a2e2e11bfc0badfc537eb2b69122352ffb62b285b6cb0935adfa0385dda074f7a63adb76bcf4a80aa83a1c32f87be3a786537acaa32178b136c8bf817ac1cb1e25b44654266f4b2b14f33358b9b75a2d916d78e89d3cec68b782734fe052449598d847b2a02c3056a64e72c5a3b34685e9fb2c0037736e0a21df39a356310777a36fce908c243a4a50216b6199cd63c7bdb18b95fbe4615e9799757176fa4a88c93459bc3030e09889ede148890cc221362472586e3c026b0dc10ba5a823f07acc1c693e9bf31518b90359b7aaec54473552835b3590174109337b6171eac38de29bdef8095da13a8f7014b3f531fc152ca5eb19859673d52067e28c7513141245376baf368b07627fb1b844fc033361994ffb3b39822a2a2de17597d16601329866f42c3697a6f5132dcea2140b871480e50523c3c5227537a5089fb6742cbfca55ba9c307a321abe440241e34151b2c2aab6ad55817b115330c0b15891fa35bf344be7d93ad44bb27962101982902427242f5b06f85204e738aec7a333a15001252004b21b5e6fa95a41a4456f74c9522657a9a40f8c4a162f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4dfa173b96869fba6c72987f4b328a0e56a08c96a00d78854d6762ea2394c2a102162143cd40192749cfbc5031739711f1ea8c37db5b635bcfe9b6396e2902d56bb135eb8975e1b0a171258d39a7ae84aabd46baf4dc2a6ff18fb6002ce232b7a45a532dd54d3da8c580d6cea4209098930477d207622a7cdedc2e72c24eaf5787d4b2b461889d23ab93a4ba327c371eff58cff7f65738886abd046895834aa06a6cb57973f1011353fcc1452b015a324c406515e9290aff4356fb393b57f4066077b2152819b6a69d6072bd4baa364578557fc727a6519088a183e1818dce9c5bf808ba36e539b40440f1ec994b46a4a128ce3d8063f608cbba032ab13102cdb3c725603d14610c76f542ea4b641c411d8297033caa114d086d00ad711224c585f4ce74c401cdd3bd8a893a04aba0fec1625bb997ea24766b5a3059983436627718d83ca5499b7612919705ace8553d475c68530464e2745a82b1c2c7d152e3da60f0b26bda3324f751a40c5004bd510df886a8b6f488af3b36a3e50ba362250e34c333b4567b812960c8301fca1946d58a52e0847e164c780254ef75c0f3ccca27ca8afb711bc2a5100e535633d0115ae135b5464c33c7c4c614350b562fe8b641e92583d49546cc4b2b45fcce125acaddf67c786acefbc919cc70cbb8a2ca1b8353372c3894fcaadbe2693f09cbb0783c4df1635818cc06c5732b846b8024b9456307358212dd0649abeb4f83910f58f90fbbc855f86780cc85a48fa75aa6bb5b25050a15588c1ed63d107b7e4b6a9e3f025be483a52967c249e7413432816bc8ad6aa29e75da4a8045b8693056995a847dac15ff49b59a1b9aeb2188c46214fb86a8ff8138c5e8b63d6c29447bb60a56210ba594a3027f4d7667edd310b678523e87830a469e5a758024fcce5a7741a7368c790cbd86204f6ae2a71c2a6a0ce80d14f26e53c175318cca9fdc5fc0a110f6834e1a32986cbaa0f0283376b25276b304dd4c9debf7ccd4c98bb1e605abd84bf824a61f5218671b17918432b32359feda8cbf822c62e86061ebcaec22af3ddc83b45252166a55fa2b3942e346a688cff13272a092c22c5c156ae0b63214bc7919aa90847f9de579c6eacab9690c6281685f4184736092d7b365c2d0aa977b0999635cfb0c44a8193377205a49033fff2133853a4559ba895f0b5b36f2cced166f7dc4aa6d064e6223a114580b58128dcb30b5c8da30b97a497300061c9cb9c7eca6924b6c6b19469645a443851e59248a3759164c02a8a86a9d1e86c51907074c7003e1e0764ea650c9aa9f1ed14831363e56104d4126bf09207d5544c5696a69daf7a748ec7be4b2cdb3c628d5a302f1a82eeefaacf731c5ce3bb6a26a80e7414044087487648e62f9c5d9e29cebc8b5bf111995616b8677778a8cc6b55618a26c6ba74753a2d943fcfb838b6a14935a38cb96906fe2008d2ac8622b50ca4a79035a403946180fe69844020bcc093bdba58d1496ae7dc5741ff16b5b5185a86277ab65c92551b48180972ba55580cb8cd274bc58a83041c7c0349191cf7c9be0a24f23e81e9892c2e0fa979fb4aeb3648ac64534e6c3823ed28cb24569e0931506396140b72f059818bd483d70c8132bc38ad19b995cd9859bbb06342ccab0180e8471c77ebcce2cd9a09d32c7de1443f6c588ac2308612b3b3cc51c670c935a91b973063a31703047a630ec03375831a3357940d2285ec8363bee2b8626656669b36875875f32592e9fd5c1e48879e58746dae41a9e8043ad3975de6c0f59f6588376682c770bd2cc3e427ba50070a3d1572fc7a61f08773d60bc1dbcfb087d726372d23bf89647ce6792f1a12fb87298fff567e6ba833423c43bb157b507009d46c8bed6704e5b23e5c431206bc3d6ca5665db9051d882be08b714950054a6c0a341bf953c4936830a74db1e7236c5cc3b49ffb6230c02978b63020ff75e26f375621b26730aab7ed79dd7facf6bc7a038b779bfbc43866123ea910c4620363a8b885c7017741a22c35506fad12fa5e2360c55aa99528db32709b41c79e7a1730be27ade379ec986239cbc98c3e2bb818b3c33c29ce1b6cff56a58f97c0968e83156a5617a579e13fa208c840591ab630d942ff415479c8343230a9f150b39b1e8259a839eaa370b9a083f50a8992c2b90321549a15b482b752c65c11dbd5b302e630293d2463a47cc54a02c6b7784ebe8c6b487b185898887f1590ed21c1c757d248cb712b7449f712082b7591b34604af799f9b5ce2aab6ce9464528418b01b1abd3e4598ca45022809a708460eb72bcb708c5bb8c272ea187e0158778760b7ca864b0fa51347b4d7130a2ecf4140a8988b94498db660229f78852fc149dd9c5692c41123a6f1310743c892f761345d2f685e5f3a924e620d7122cfadb4f8fbcc95f5a65b31728624ca247579dea035dd5839dc6bac581e63202cb56b978c6a08c3e3d5a340100ad8384a2955462bd703237d331eb7742349876eab4c2c933133d3c833d185f129c5804aa1453b0947da3cf3bd44051f70de00b3cb28396c180b501e70157c22486f8a82282652bb21fc23c3bc123b6c3d6acdf079906b149ae2b52efdaaf3d9b0ecaa92ca9d8694bf07d4229835f3a0a21253877e1a39b4699039041abc8c0b3f6aec29bb22e847131670c0e7b5abeb2455a246d03b6066114552476a18c23b013a812d65a15d021c117f926607c076892499056c1bf058c52ca1703a0812678b4485b82814bb6960a86c3454b99b731cfe15ca5ec005f866b28235036e632b89cbd9aa4a6e70ac944ab82661134ec2ba3b871272864a85ef61f86f51337651eef063fc6f07a39d3ba7aaba5d7357506c550bed913788947a1863a25209cd01200272517adca5f1087c984e11f13404d046c5537711c56577adefaced330230a42cea4e13d0e899394f120ec34c2a6054e5d2ac90696115515345aa2125dc6464c584216a9b0018b704e8640ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28cc20155074cd7cbd43ec2380dc6a71b3a88c9a4bf168ab2bf426a899706fa597812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +expected_public_key = 6db66dca0819602701895a6e3a2071623403b78438977211d33331312c8715e34929757ad52815c65806ea8b222ac2a5b4b718411732d6a0137c5c7ca8e285c02634130950e1143160f6a34cd64dee440b1b3b8d64458c78492095517892c5a169eb7ae87733aef3b16a5133788ace5fe57cb41ac0e5b13c403441d374aab997500533744714a84dd56ce547a10c782d6071bdcbdcbfba391dd44926022b9098e61d079b2198c4c4201295964aca9d703013341313a50a9b124427209bbb248aaf96ab9efc9028cb9a298838465984647aa1e2f4087c74ae23f2606194447e403ee45198e29c12aef2ccb0c4b07c98a02987068b4a4f14a778be34c362204ed4b31788e3b7d2e54d74e07a215c7eefbc3067f9c67e625bb43b9ce25179f58a113bd2cbbaf85c34ba8fe26a331e0b0610893e0947495cbb1e287047da04527cca1ac68a2ce1742d8c855576941b4d627f0d326a7e543497f09fe1fa536e997828c19977b0b82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e79501817d8894004c5586c78c1a54808c37d40fbe3171f6e950e287850ed19d975446fdcb1b0cac2d4a611d832acf1c20a28c164201638110e0997fb36b2d24c6b349c390d4a13e06aa95c40e878830827a440985870a4b6288f82dcbd9ae23175462fa054d2a9c6f6210a1a7cabb9a6ee8e37ff144043ec0123c2c0c4125ab48775529a86462c34c00b128a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a716a27b1576561f681e346ccb74a07b71938676c25eee2a83ead225afc408cbf085a4a342ddc2b058c6a138a94a819c737b6baf4a4493c38a52c1452a302535dee813f1dac31e09402cf720a3b16751451df057bf1b7519c8a62e1be69e339910e6024c59c13fbac116d6a6578ae40765f78a7147b5dcf93f4eea1436b559ae373888042c63c0a52cdb2777e8699afc229d575ccdf802c59c15bf3b6f028494594b53d2f3cce339229b3a03eaeb164f325686590f79dac06f482254838e5af209cdc31f9a5bb893961c5576c445a02034088e89140ec2b28cafcac58ad352d0ab34d0659332d9266db85bf57bccb67814bc74c107c41dc2f30e6330b17b4b710cd7ab0b1c01d9f82d3fa0216e51198d723f1e52314e850220052309a383e63b774370713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a85603fdd8b392a616f55c3783c28b5308a4b0a5c1c757b677c475c60516a65f656b4868cdec6bfa723c66e52931b738e18cc518cab93a7c942e7db127d239c11580c21c71031f20079e9506ec57119688e0df98e4045b77e87728496c2060c93f4819ad2a79ed10501498891828080f4841a8af6602e100981124f6a16c26f3380e4d3635fd3cb77cb6c8eac22ba212a804917b922218066241e848e3ba589569a5a6420019370ca04bc196e88cf2f428595f1912fe9670b9ac97c487ee2e7a77a621ab3b9b2e4c23c5d4c8657277951b55aae576524769ca5b83b37d84868367d7e9323d9ca4cb7071c352ac3da2b3ac58525a152a00ec268f85ab6559027ead8abaaa370751c64f51473b02126d7b3be27812bb008c45797c1b4b05b5cbb8c2dca419f85be36bc390ef5c4d3670c8ef7c00b59a44c65ad11d68c5af4b2b675cf40c002a1b7844fc9a6c32886c74a1892a2514cb930e4387904d1970168181f7b43c020a8071969b868a5b44729b8d04b3ea9716269cc005808bad63d0b063f21c23ad1377e80bb07d608786d849d79eaae94813435d602214075bde7bad770b28b380bd0d7139a7780588c01c8eb6622f1a874968c874b120ff81c988c5684f3c9ba677add2c23400283d6d325d8289473f557eb1c2977f04e95fba614ba7613720c704905f7a73a2834996a4232a8ac278a444fe5f7a9148b57124580b7b03df89ba646aa4233611da9b5327d61b6b1aa351d25988e0c25e6e2563168c005666ea90852183231ef5ba371935c4c0abe6b61c0a1da756ef390c120621af2ae243089f84551185616779c90ace0593b815dc5d8b2d5726a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa4a001c002374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33921c307c05f69f90cab5602a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_private_key = d62c6ce5e7594be682a8167743106a44482e3a79ce257635773513f0b0bf77a161c8274a705b93d2eaa899d8c0126ac8adb7b3bbb5891711380da1a9de0541e4160dccabc13a165b5c54178da95b919457c684b9cef81e97637c73f22a3ce9295de79bedd83c3ff871087b9412301863e291b04779457807abe4687368c84b3408e26aa30bf58bbe4bbded32adb03607598714464222524b3c2cd4c15f98a2e6695463257bb8fa9a84131a64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51af611d4bc03e20cb12a216072d7834d996ae99e1cc6522a42b48c54282cd0ae8cfdd1b874fbb4ec17434ad584af5b4561bc1597aab63390b60fe7c052e57846e1a8c4f6c6758798b70503507554946382fa6e2004a616a40dbc2b0c596c2cb2873c38e6ff82ff159ba93563d23671dfc433949d3705f398b3752680169657623937a8c357864c39d82c16da5c1ee407fc7fab357c0b114965e89815409964ccdc54cd8d5b17039aa9283a59e746a45a2800e4806064683c292b425c18f73aa2f720a6521a050c5196bdabc9b094895b9527759c1a7210958e11a3411b05e67097fce2c11ed024a85a22684b51edd652ded89c23e1440ca5616bb754361c549776222b8b297f8f4bb7f818d3b29b16c369cc8ba9d91e6012bf006999c7057aa2a44c30237314079b2a55c63990c3ab657cb80d41022651097ed680d200195be82a9b9d08b24f039bffc42c66459b0c8889dda6714b63762494a5e6106f34223990772b1cc12dc660f5be62eb0a15c16d4a0303773d768c7dda7b749711f7c12720c150d30ec6b625624e3f94861483be03271d8b05780ab62e0294a8cb193238530b49455718c872428bea1d84955f54a3bb619dadc6106ea3ef27094a085634624377312648ac46559d7a7dd902497aa9f22879d131a08b9223a05e5b76a00807225b304480f6105cbec8a11cea18e8910a9bba691047c95676c9e2dc7ab76537691dbbee397738c613e1fb00a79f06698c10ec26c97dc00b82a54af572a02801aac20983311f42bca18699a2684e4b5aed83c7ad89a1705f1605a87cabefac499a56058d8b02bd597743524a90c3686d9405e33c3d70880b6449d41a76f83e23759664f1f301d3935998d690a7167afa11a59cf8b87624283a738c0d221b1b55453504ab64fb89824351a49ebbcc291465af92f50d7b53874c1190a766dac5e70706f88097be4500942534df5e5887c48b234c11992f32bf3f2867cc055d7d6c3a4d25d2a141be7d706bc1203814667552888e3bb13221a10dc3a4157d811a7ca23088ba5aa1a3fd60c0c6af29b3b52aa6da319d8e359d842c6dc65c29eccc0523115d15b19a7b90d1090c5949cc66a004f0a0513132640a284a87384c7ed06782607584bf5cdd8f099acb0229cc9588b024b0f3b5ba80b962218b3bce4c0f542bac9e8c235362e33ea30d789094fe82fbf64569907755ed7bfd00c3f6f446deb00a27b37bb92e454aaaacb69dc854532c718c85508ac8742c7180ea805a78999111915bd414275e92d75c1953c10968c802e4aa6429eca0a5ef49fb4046ed2c93914400b0d882b67c275c483037e859c8c01518ee49046e3594a311320e800ae2cb182553684d470df629b6c27a9cc5c17a0855443262983e800b9375e0fba1d393953f1da232c41bb30600e3f0596fd3c786223a165522bd60c8a2d404bdfc0a145f50b44fb1cf3e8ad9b1914f3264425627635bb9734807b408215fb0c6a617c695025bf43e225b1c54d261052f33a825d65730ec7519c9087ff5626a244a1e28669d84bc8216a09cd224dec7623425023d05a51f98b8c220cb7b2dc46b6aac461744a30a671eb828835dc32efe47fff21370e73123135ce2e02789a21b03e1c55167c3fcca2343db1cfa8d11e838948382084a7890e619c652ac49c64a3879658c419c8c813309aef9bb606d126a652bc331329501c61f97196f7db1a398a0b6d947cf903a9bb61119c2c45f8b440f29344fa22c2d9b1cecd5786089402c6b649d8563236fab8d208be6967b14074cefbc7aa44c02766ecca8f0673787b33c2dc2c7501be94770e68608ab06aa5410aceba544a6f8792c4db01c07c1bbf197e4d17388adb05fc910bb3bb0b947c21c482256db66dca0819602701895a6e3a2071623403b78438977211d33331312c8715e34929757ad52815c65806ea8b222ac2a5b4b718411732d6a0137c5c7ca8e285c02634130950e1143160f6a34cd64dee440b1b3b8d64458c78492095517892c5a169eb7ae87733aef3b16a5133788ace5fe57cb41ac0e5b13c403441d374aab997500533744714a84dd56ce547a10c782d6071bdcbdcbfba391dd44926022b9098e61d079b2198c4c4201295964aca9d703013341313a50a9b124427209bbb248aaf96ab9efc9028cb9a298838465984647aa1e2f4087c74ae23f2606194447e403ee45198e29c12aef2ccb0c4b07c98a02987068b4a4f14a778be34c362204ed4b31788e3b7d2e54d74e07a215c7eefbc3067f9c67e625bb43b9ce25179f58a113bd2cbbaf85c34ba8fe26a331e0b0610893e0947495cbb1e287047da04527cca1ac68a2ce1742d8c855576941b4d627f0d326a7e543497f09fe1fa536e997828c19977b0b82ceac4c45a3c06fc9a2ae8a1e6c461cac9af21e79501817d8894004c5586c78c1a54808c37d40fbe3171f6e950e287850ed19d975446fdcb1b0cac2d4a611d832acf1c20a28c164201638110e0997fb36b2d24c6b349c390d4a13e06aa95c40e878830827a440985870a4b6288f82dcbd9ae23175462fa054d2a9c6f6210a1a7cabb9a6ee8e37ff144043ec0123c2c0c4125ab48775529a86462c34c00b128a333844b7c474a9ba5e6087392ea661d56b4dd0a8cc1e44ed94b994915a716a27b1576561f681e346ccb74a07b71938676c25eee2a83ead225afc408cbf085a4a342ddc2b058c6a138a94a819c737b6baf4a4493c38a52c1452a302535dee813f1dac31e09402cf720a3b16751451df057bf1b7519c8a62e1be69e339910e6024c59c13fbac116d6a6578ae40765f78a7147b5dcf93f4eea1436b559ae373888042c63c0a52cdb2777e8699afc229d575ccdf802c59c15bf3b6f028494594b53d2f3cce339229b3a03eaeb164f325686590f79dac06f482254838e5af209cdc31f9a5bb893961c5576c445a02034088e89140ec2b28cafcac58ad352d0ab34d0659332d9266db85bf57bccb67814bc74c107c41dc2f30e6330b17b4b710cd7ab0b1c01d9f82d3fa0216e51198d723f1e52314e850220052309a383e63b774370713435c6b9a3485ff3b83009b79de7bf5a5933723cc94db671f25a5a85603fdd8b392a616f55c3783c28b5308a4b0a5c1c757b677c475c60516a65f656b4868cdec6bfa723c66e52931b738e18cc518cab93a7c942e7db127d239c11580c21c71031f20079e9506ec57119688e0df98e4045b77e87728496c2060c93f4819ad2a79ed10501498891828080f4841a8af6602e100981124f6a16c26f3380e4d3635fd3cb77cb6c8eac22ba212a804917b922218066241e848e3ba589569a5a6420019370ca04bc196e88cf2f428595f1912fe9670b9ac97c487ee2e7a77a621ab3b9b2e4c23c5d4c8657277951b55aae576524769ca5b83b37d84868367d7e9323d9ca4cb7071c352ac3da2b3ac58525a152a00ec268f85ab6559027ead8abaaa370751c64f51473b02126d7b3be27812bb008c45797c1b4b05b5cbb8c2dca419f85be36bc390ef5c4d3670c8ef7c00b59a44c65ad11d68c5af4b2b675cf40c002a1b7844fc9a6c32886c74a1892a2514cb930e4387904d1970168181f7b43c020a8071969b868a5b44729b8d04b3ea9716269cc005808bad63d0b063f21c23ad1377e80bb07d608786d849d79eaae94813435d602214075bde7bad770b28b380bd0d7139a7780588c01c8eb6622f1a874968c874b120ff81c988c5684f3c9ba677add2c23400283d6d325d8289473f557eb1c2977f04e95fba614ba7613720c704905f7a73a2834996a4232a8ac278a444fe5f7a9148b57124580b7b03df89ba646aa4233611da9b5327d61b6b1aa351d25988e0c25e6e2563168c005666ea90852183231ef5ba371935c4c0abe6b61c0a1da756ef390c120621af2ae243089f84551185616779c90ace0593b815dc5d8b2d5726a2cacc97e45c527e75849e35b7c5b77fe436c303535f5c690517ba60be7aaa4a001c002374ae97f0cb99f34a4c2c0b85f36eb31ac7c907999bc7335b33921c307c05f69f90cab5602a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f1326077fbe004761fc37fe7597638e5dae8b44bd44c8d6efa2893a0a84b104ace6ac48e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +expected_public_key = 3746054cc692001b531bc5a46a5cb02c910bf24519198c1a2f2023a4367e9d2ab4cf5887c756299efba70d9008fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9c9f228475e0a454639892d992503abfea8b82908a087761bec6ab7d60c1892f41bf1f99c6ed256b64c78c93a316b31272d6f236371ab2ab77123eb732ab303a5e89485f702f528a38e1920f12ea72bba8868c855e305425d84a5edd11918b4cbbe5c0001a5637bf8c022128b81de80509ea72a0f66ad870257e529a31cbaa39183f006a0fafac0fcd7781f1033257d766f78b4c4a9b10c5b8208a40368b393a39e7762467463b29a7baf4307285b898aa0bae485a63e739ba5a7a080215f4221217fb43177635aae61f218850a1d924052a9c0626a7f11646076176215152b5508db2c52da7477b7e2b0659b999148a214a12b9a3e770998b1a26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa94368429f763991911681c1ebce5ac515bd5663308361e2b068332763752047ee14ab31b914e2d28457395cf61c69ecf3834d305af9ca18decc6ed39ccf69a79c379044ced7440a248963c269b6b58a049a8077e0a0981639d581a8c38a16f4296af798cd2556889e9697ba8156714166f10a57c970c6131386d9154894d495deeca298e33de4b09a94dacc2cca1d816708fa1b1b5e0a7e8046143fda893f0b3eb2b60ca7a02878729768fc82d8b06a05f647916a9cb84b69ce532edb5a7ec4eccda5a5a4fe8c52ebec6584e6c0465529f57699706cb9a497c2e96757af06783a4aa6a00087079803a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401abc1b8d0c8eddf679a8ac0fde11917376a7063339f2c2507ac02ccc512c7a75b00de0701124ce3057a8c28687b2576c640bd0ea5422a534aa4bac9fde1735f35112c98528298218a1f051d54231f7ac5c4353be2205c3b6518df442775b9771ad19ba9252698bb6cda102cac759a5a0734cf07791a38c7ca940a86b584457559e7b933ac5750c4c43785ef61f5c121f8f4175570c7ccf864c4bb7c49c606ebdf7950e49433a841643f78273e117780a5e1e4cbf3e0016b45994c1821686d41133bb353dba0fb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb0e0baa50199d80050dae3266f228134a4c67ffc5241a757e0dc2485a64d4907934eea5fe503653311c4ef24bf09fc3f0388c88ed9cf965ca8a109297be60893559a0f3696e77b38d677a7e9f4c788d67046c28281c8a7f71ab250e77ad87b4f64237077d1a63b753a21b088c5149af5d40b928401e4c407e71b6896b840d8f717e627532f3cc604e64b84204730c8330ea35228580b4b886518e9670d6100826560f9623045291ebad1ae5fe6840c30cbe69ac54e62bad8010c98c513956534beb356cc6555c1c4225b7862c4651e55c4452448063b4c04e105b63daaa90f9a6b0769b161a32f49fb64010a91e0b4410d86b7bd4c91f421ceb091a88ed9ac5e01c81527886897a8e6697c7571ad95b818f942a5692459f9979ac7a8078883aa8a445a5af84b1b86c4c79a224a5c8f3a889eee0c768af29fd75a506ae75f9d578c26c8645bc8a8bf0441b6da2bb27b6baab43031047c6b826fc98766a1661be0626cd2c37864eb23f4240e5fb601dd645ffdd9898396273d3000d5486cdb67866751378350068a8439944ca11f9a5e7959ad43bc1f5cc8c741a220bee733aed2a41edc34fbcbc890a718f608794802bed150a0398b0a836a68cc0b58dd705353a41f28883cacb94c797b8cf8d23cad9bb9a18c53b372c50aaac124fcc07b310907988f38164f46d70305a381e4a1673145b0bfd8ab91a02c28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c45057dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c6a1c7e1589e98cc995a4a2b21288057fcca694c0c00e7ae05d861b90a520eb34002732a2812368931a18243ac62f34cd7027fd80436d0454aed978115034407e30dc19813c5100c3e13a26c3283d4a72e254ac3f7e637d9435281180dd6fb35f0433788d470b6216b310a63d5e11b373a073dc8098d3950819937e7f66ff954caae52b3bb86c80b5680851170140a1e59ba0b23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_private_key = 212393fa68c40d1153ec29801f4472db30b8e6516647cccc6a160bdac4299d515717d46bb4248673d11558d8af5a6373720a9c96a4c51bf12ac506cbe51b560ab742ec684ddf86cb08121bdd412e2476842d051e3182c415c49b7184c9322242f70b63a960576296a8af5451f5d474019c47e1822e2b1503d30cb8ea20b3cec334a2114fc2381d910a98e633716ef9ca2f7939c7033bab756371d6c2e906061df822113c57dd5992c8826adecbc9ae381931473558ac94fe8a19c9c4bea3dc40defbcbde234a211623f8d80bdefc74f657a797098ebbe2b6b57438c2253f89d13bcbd5c0c4204def79bb37859e36e920768ca7d0651a7ec9bb63336698acbfb6c9a384084defc1bf5d9c050087b691d40344e107bef0241bd99463532a05b795f820213392cb16d668605ca86df134c03c4a7df581f8ca7daf732f5aa75146457163c3abfa9c655f966a607a69aa1234fd1ca2a97213f280a10e84c4aad26c0ea2cba6773d63b39ef7350f6d284830ec3275e5bb9a318b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bcc22d617aaf8b14c10d0037ab970b8cebbec0cb866be5057964b7cae6c9b3084a696602a25961dc53558c065d6d8b25248aba262b1b635322bb82165a8cbede60bbf6b72459d47b64a964b3c32ca563ba5aeaba8ed912d81b2e733b4b4587a99ae5037dd21dfc9aca5d869596e36547c0336ae774b8ba637622a597c05dcd43b092d938429886c708448b24a45a701ce9fb9db54c67bb531bcfb82ebc15c127409b02a3350d6168f1296784b86f7310b9160681f0133a66356843401b9c0414d7f687aae41a36857ccd3b26bf8c11def30769e30630169365aa3c3b53cc89d9cf47c2cc6c166f197c9e5c5b2408b03c41b0613703cc4872be78dcc4b28089d7118ca1186baeac1355d5b9d4e45515897ae233a26810356a373dcbf6cd5f02cdde8c468be006dbc67e60a69908d1171d4a5ec1643b87059cac80c259788eaf195f4fbccfc4c0284be822f94c2978fa119371291657b927f8b332124d61d17e21a36485d2c3f2893865f305589a8d048b06fba7bb9f087f96d5785678a7f2d16c892cbb2273677ed0cb70f5729af0a0403b0bf0608acec1ce32f2924535c16e8423be0c8854e439ea395dd792399dc98aeeb7493b64965858be35977dc053b3c0b3788fb4244cd3b49e40934f90b454c983da38b2b5c88521347788f832e9c64a6cd012511234275c9f6c251442a87b496743333a161d8c04e3d78be3097942aaccede09b9cb673e1fa261be71dbeb5c4e1049b2b2a00311acad4470f8afc85172476b949aefbc0110a261461291b5ff7a74697c88ad40c82770fccf68b9ad5382125879e637b7cebc1aae95b03219cf2488b2e3b2e51480c8cd8022c2092470236fe6042dcebca24cb9ee9379386d80e54c232dec93b99b694e99ab5e41cc8cfb8928d5c08edc7a707044b49b8a131986a3f37bcdbcab5255b64b4905a93a719d01a32384a87543b6ba1a22db75c9baad257bc8b9d8b78641b394c7ae064087454cfb17b307bc35a97cccb842602990747d60f30d220ed3171ffd7a2b77049dc210e2377607b817f24c011dd736d7918874aea4bccf017fe3b303eb7b30e426099bb2c90a0b269e88390b5879706b163e1b27194ad68b26204b512ea145c43b029ff20898ec589c6691c7fc5857b387bb1916b407a641ec14d01c82dc7f4a179a3558d8abc8af937a3b2682d638e3881329e484b28bb1ea4a9b6a20097f3bc145345b032ab8051d44a8615c9780521429bc1007a28e3659433ea295789a004002fe980c2d1043761eb7416338b68f688221ac004512c9dfc7889241311f78145699361cc1c46d55a0b5c1303789a3c0c4c57ea1fc14b8fee92798a188d165982de273cd9970be03279dbdba64838ac127b78ef4b16c3105fef180d0b936558aa005bfc0c2c5a2a00ca207a49675db34b0029ba77f76eef65646ed13bfea533e5536683b2402a380b1426b45e1b83e498758393907cd4999909812e823828752d4b956925892a0d038d2c695ccd22bbfe0062b5eb0b9c370c54e31229067df3d0b513667be7e54f520839af94c6d71a066309004de4cf7dc98802232b77b10dcfb266ded346770b8df09768a5099bbef238f72b853746054cc692001b531bc5a46a5cb02c910bf24519198c1a2f2023a4367e9d2ab4cf5887c756299efba70d9008fefca93a3694d7245ec4649bf578b81f07c1cb37776ffc9c9f228475e0a454639892d992503abfea8b82908a087761bec6ab7d60c1892f41bf1f99c6ed256b64c78c93a316b31272d6f236371ab2ab77123eb732ab303a5e89485f702f528a38e1920f12ea72bba8868c855e305425d84a5edd11918b4cbbe5c0001a5637bf8c022128b81de80509ea72a0f66ad870257e529a31cbaa39183f006a0fafac0fcd7781f1033257d766f78b4c4a9b10c5b8208a40368b393a39e7762467463b29a7baf4307285b898aa0bae485a63e739ba5a7a080215f4221217fb43177635aae61f218850a1d924052a9c0626a7f11646076176215152b5508db2c52da7477b7e2b0659b999148a214a12b9a3e770998b1a26cc984a9a96aee4c52b6343078ab8bddacb00cd5c744750e379970fa94368429f763991911681c1ebce5ac515bd5663308361e2b068332763752047ee14ab31b914e2d28457395cf61c69ecf3834d305af9ca18decc6ed39ccf69a79c379044ced7440a248963c269b6b58a049a8077e0a0981639d581a8c38a16f4296af798cd2556889e9697ba8156714166f10a57c970c6131386d9154894d495deeca298e33de4b09a94dacc2cca1d816708fa1b1b5e0a7e8046143fda893f0b3eb2b60ca7a02878729768fc82d8b06a05f647916a9cb84b69ce532edb5a7ec4eccda5a5a4fe8c52ebec6584e6c0465529f57699706cb9a497c2e96757af06783a4aa6a00087079803a4d834c7f5cb839837c1b5c1318bc21447791c4694365c401abc1b8d0c8eddf679a8ac0fde11917376a7063339f2c2507ac02ccc512c7a75b00de0701124ce3057a8c28687b2576c640bd0ea5422a534aa4bac9fde1735f35112c98528298218a1f051d54231f7ac5c4353be2205c3b6518df442775b9771ad19ba9252698bb6cda102cac759a5a0734cf07791a38c7ca940a86b584457559e7b933ac5750c4c43785ef61f5c121f8f4175570c7ccf864c4bb7c49c606ebdf7950e49433a841643f78273e117780a5e1e4cbf3e0016b45994c1821686d41133bb353dba0fb8d7c10158b0bb58605f1c6b8806b2ce7ac3095356bf7b50e63aadb0e0baa50199d80050dae3266f228134a4c67ffc5241a757e0dc2485a64d4907934eea5fe503653311c4ef24bf09fc3f0388c88ed9cf965ca8a109297be60893559a0f3696e77b38d677a7e9f4c788d67046c28281c8a7f71ab250e77ad87b4f64237077d1a63b753a21b088c5149af5d40b928401e4c407e71b6896b840d8f717e627532f3cc604e64b84204730c8330ea35228580b4b886518e9670d6100826560f9623045291ebad1ae5fe6840c30cbe69ac54e62bad8010c98c513956534beb356cc6555c1c4225b7862c4651e55c4452448063b4c04e105b63daaa90f9a6b0769b161a32f49fb64010a91e0b4410d86b7bd4c91f421ceb091a88ed9ac5e01c81527886897a8e6697c7571ad95b818f942a5692459f9979ac7a8078883aa8a445a5af84b1b86c4c79a224a5c8f3a889eee0c768af29fd75a506ae75f9d578c26c8645bc8a8bf0441b6da2bb27b6baab43031047c6b826fc98766a1661be0626cd2c37864eb23f4240e5fb601dd645ffdd9898396273d3000d5486cdb67866751378350068a8439944ca11f9a5e7959ad43bc1f5cc8c741a220bee733aed2a41edc34fbcbc890a718f608794802bed150a0398b0a836a68cc0b58dd705353a41f28883cacb94c797b8cf8d23cad9bb9a18c53b372c50aaac124fcc07b310907988f38164f46d70305a381e4a1673145b0bfd8ab91a02c28b86e1dd95c365bc88bab5e526aa9e30b7694cc67c45057dce459a4f561e9c8aafcbc491a6a7269734f0658acaf753ffdf735cc0cb3c6a1c7e1589e98cc995a4a2b21288057fcca694c0c00e7ae05d861b90a520eb34002732a2812368931a18243ac62f34cd7027fd80436d0454aed978115034407e30dc19813c5100c3e13a26c3283d4a72e254ac3f7e637d9435281180dd6fb35f0433788d470b6216b310a63d5e11b373a073dc8098d3950819937e7f66ff954caae52b3bb86c80b5680851170140a1e59ba0b23179f5e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c49cbe8daa7dac02d7795e907b037e2ae56624fdc8d7c6320f9e1e69dd0f6286f8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = 38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +expected_public_key = 8f57212b9b824d071bdbc45143b4663ada61ea72608ea85b82b49075d3adebaa7d01bc9cd916728ce121c1fcba51e42732d76575607d3e574c654043d717afb96532da23924fc124b01026a8f8b859f4bcd1aca153133905904c3be8361200abc6e7ad42f236a0826c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f18042f2075e0a8c58a5c244e14119f5b6d5538385089400e23bc1c106b2cdb59f287c538f32917c202fb682b9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74096e0423db52e7c0099963c5147c2cdc7101b0d01cceb8ac64937186c23b0da108f58f5271e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af97c05041b0494ec11daa36facf034210383acf9089d371aeaea975c489211184d55db561c272cba9881acb88159c74bf9671147490fb7a4cbcde1689ee7cd777b3f83c54850e8082e884a7c3b3333d7cdc6318d5347b0160a4b67e46a24d756105c09ea0043b66a74f98599129b52eda51971b60b6c65867b3545139990aff9c088b7b114c03d10972bc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d6a1315c63136139ca954a86302ca788c27b4f82c57ea35bd7c31d5d543cad66bc4ec9b93df67d2b019e56e372fdd7808f4453ebfa3092676224670f79ec579307052832bb4f2150da4c06e8069855573378377c44a9508410cc62c60ad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f6152bb2845a3de24807102a274d2b33f84392648c6f64ac85d304a4c024d88c0a13f0874231cc6d2bc8d7c99c0530087f61856c000180e78939148212d2b065df99fa51a0e768995a8f3bd71ca82a1792afc7c05f8b07db30aa18dd25180b73d175382158a1c3d5135fdc40f2068c17ed11d32022caeb404c68418e7ba2f352a510cc203179366249385a2db3639809795cab6ac0c11450220d96356bc6b45ea943c5028771eb8c58097966b4821bd1504ba1a1836251047c8468089c58ac851999b7ba017267c3a6e20c5223fe5a41a52044bd5103f5b1d31fb9b0105ccba387cca72b6ff1bb27119005d6a29a6200de9dc2c19d85be067793ed476b0324c24f10a8d106b55c63bb346b9ddf44b9a5a5349b766132824cc955214315267d69f82093642b9c2360c2b57993b1ff2c52d8118d62375ac851f5eb181a24badfc165668e7a36817cf80f5873f87a6dbc3cd42c0b2bee57f0e06c93a9807b0bc32de588808ea0037db50b3bc14bf98affd4400dc9566ed8022a4c7c34fc4369987904b362b1d04cf3451914e5909ef750dbc56af138529a601a261932efd626510a528643693ee79284cc3987e3694cac828ba3964e637925b201e270744fd41190b3b1c088a79f31581b0641917dc161b000fb4a8281f6a6b7b1392949acd277b9901637c3454a058589299c48b3401a2e0f788744081cba76b5ec378bb83789f63962ae2af1175176ff353c1cb3632bc0e206194f4b7367779146df4acb6d89652b946a9b9c2b61c0553360616f90e97fcb190c43faa544891745ca9b97950384de8534626914ffcda63ad302c9f001a361ba7a94066c9d8b1f30111faba3728fb143bd788aaf04491951d541078aa1069741352fdf8c032964717ea1791472a2069cf43da46a40046c61c79cf4a7d1e093526d75b444a08b0ca984f2869026a4432244d662951df52ba655ac54c502e83e8587e21c4757166b78244da2b5364d3299981859cc61a67d02b32b19c8ab31b78146690690096d606befbad0ee628103712f0f81e5fb4bb22e65e9ad1410504ca75d29386f73b53b0be140a5b548a48b05313de873e18b030d6f691322a2409f4603c7bc24c103111fba7dd5acb3f019e7cc22bc3f6b1e6acca131364d0fa0694866e2322281cd229c16aa82116ce6fd0187d4034db33c2b3840db1f42c5df49825fa7c6bd62c31a625616270565a2fe3f4bb50c58597f70e6124c2f46a83c3fcb62ac65a5a66557b22ae31c7813243a1f0c4b905a31a40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a0825ea860af29b81586b25832356c1f976370496b6fe7493e482e0dd9483e51372b093d37f29b9d1a83c209bd98a363df8a3ae430ba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_private_key = 69e774db244d05192a2e064257f3a7b9b08941a2018aca28c610b8bfab59176bad88b9a7781222cb03aabe6a4c2937be24645a28c3a7931240503769edd1865f72b44c4842114980ba64a59a647438c5476a700d0dc4a63277c4dc73a3dc9b59bfeb0ddf0817612ab73ab14378e93fa4982d15131c5016b36a639e4f689e9b6b2d2bb2501e130eedf72afe4861ae7cbe7e717b4c4001b78bac719c6afd40969392cfb1d918794b4988a7c03a23c8c5a751ed2c39d3e18474b43cf8b7814a5932224141fd543871ac102bb0a349153eb4a13ad57ac06602bfc6c1b4425284ead058572a1c7c0cafdc6756555b2033d2ce67f9155b16726625928ea26d13e2c0c0a66988eab99643b4cf23ac68724ce635188dd8b3f2f421e8e8a9f838b707a16fbf27445a7555cfc052982cb002130ca3500cc428aef14281564997d5f37d0a1c411cf73d3d2082e4c26c3bb7beb9fba2d9ec631f8953b3d03075318b4b720b4fb5b177d43c11e8979c640639136fa20b718c0846404b2f0604c55ca82f519241d811a697000dbce1c743410e92922e83446410a93150178a4a2b52123174db128b2eb97df4e8a617d5876ab9977daa8b7845537db0a2b6e0599c0cc165438329d1251d6aa09d5b30f27040082a135c2b831b7722c416072c655c4d511e1fdc0284932849126d49b5a03b3593894bca250b0d198601a02900c9406d8f5b69beda735a3512bd355dad587bca7330364031573b44eb9c2bd103bafb7283c1b923ac3a41f0607d4b7b7e1e681aac9b4090538b6b7975b9c5c64c6196577b7861cc88ed6c3365aabcc9b97a6a318a39a2ba8b17376509a563b58dfbf4584e6b00d56bbbec309164982d1b906635a146c04bad613c02c8e2c2d0597fc285779c628f3e290a84d8710745c444410f129a140358991d601fdc787faf4506c6003e2130c2e03b3ffed39ca3b9bbaaa34abae794d4266e59a80efb44528b2b234d70025767a5dea09032767722c61e53423417458de9e809a42257a27001e9c8ad43b775bc853d8475abdac86811d568e9e38747618aff0b0901283a3913b6595cb2a85b6d42101dcbc90146ab85ea5449850bc9d8b1356f820ef365731f176ec0a0a5b7f35d9848c426f32d6a37046574a93cfcc043614e8708026621a06ac00582da7b64421d4f50aaac1bb10d6bbaea31808712b891344b7b865243614cd706c2dc098b0a069fcedb89ecd67de8319c92f3aa0a9b92a1fa256302587a5859408b5cab563ef1814cea386becd756db669fdf87a003ea1e7654cab281220b21cb234ac1c4b459ee48517bc838082191de35b265d5264119c05cb500a05307c806ae8246128a8194f61024f5b2b7c410689150c0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73dd91e9733282fa2559ac53aa2819811190b5827000d98433241a3da2b77f4e588b0088e3d3318cfd049c4777f7b08678144618e2406b9b6b72698888c4529b7e3b272e92620bb36792266c3da4c9c403d1d49650b5530be017c3b99c068890f2705702440aa0bfca823059822c18981a03b16670e127386265487665aca4c171e023621a853965a629757148e37833d31e453dc9b20191c94230833a31089c41324a94010ec097210f45592630d6c1bc28e09551c85c4677b015a7b957b1b4e0eb8886cd77835351458700ef5f170d1d0c81dc920e4cb7d16ca9fb6b8cb6086527106b5508996d24250026470740586eac42011db626ee74a8d7b6dbdea073aeb5f6a8a9f9de70cecc03b203a5bdb2abfdce8798764a88cc84cf9ba31008470904c46c523748a4b39bd46cb527501f617c43c83adcadbad1812ab61aa7dcf71b3fe4128fd087766e87344acc8429743f5842784095d1dd3a43eb7a835044cb990165a8b52a9f43f6fcb3fd4e04ce699a4713c4ff2b19b7205c256f643ce050d467132d635170a4c6c854b45e3c65ac7c24f1fb70eb0b6ae852b3d526a527d41b8f562bf56ab9a44d4b00c371b4055cf36089c905bc8b42006098ca18c58b89cc5cce6a454b02c754f07045e274b3a2a647b17533215c6fee12e7e988fbe692c308866c3a133edbbbce1d4a06931b75c5561dbd87a74cc0197071f360185c680a14ce508bb280895cb2c4ce4007ddbb21a1907d2ac5d4e163c26a3c58f57212b9b824d071bdbc45143b4663ada61ea72608ea85b82b49075d3adebaa7d01bc9cd916728ce121c1fcba51e42732d76575607d3e574c654043d717afb96532da23924fc124b01026a8f8b859f4bcd1aca153133905904c3be8361200abc6e7ad42f236a0826c03475385153cf538782c7c8a469a43793c3e81ecb524aa838f18042f2075e0a8c58a5c244e14119f5b6d5538385089400e23bc1c106b2cdb59f287c538f32917c202fb682b9c5aaa5fa343a3bb6b147c6c9ce3b4e6e74096e0423db52e7c0099963c5147c2cdc7101b0d01cceb8ac64937186c23b0da108f58f5271e1c5564a7ad07f62f93b4b89ce5bfd28462d4053bf6085cfc254af97c05041b0494ec11daa36facf034210383acf9089d371aeaea975c489211184d55db561c272cba9881acb88159c74bf9671147490fb7a4cbcde1689ee7cd777b3f83c54850e8082e884a7c3b3333d7cdc6318d5347b0160a4b67e46a24d756105c09ea0043b66a74f98599129b52eda51971b60b6c65867b3545139990aff9c088b7b114c03d10972bc6e5a353da85497b95c8bc5dfc156542eba57e96cc5a4c3f2bca53d6a1315c63136139ca954a86302ca788c27b4f82c57ea35bd7c31d5d543cad66bc4ec9b93df67d2b019e56e372fdd7808f4453ebfa3092676224670f79ec579307052832bb4f2150da4c06e8069855573378377c44a9508410cc62c60ad1db5f3077b911f76cc148c354733c0aaccfafb85b0336838ac43f6152bb2845a3de24807102a274d2b33f84392648c6f64ac85d304a4c024d88c0a13f0874231cc6d2bc8d7c99c0530087f61856c000180e78939148212d2b065df99fa51a0e768995a8f3bd71ca82a1792afc7c05f8b07db30aa18dd25180b73d175382158a1c3d5135fdc40f2068c17ed11d32022caeb404c68418e7ba2f352a510cc203179366249385a2db3639809795cab6ac0c11450220d96356bc6b45ea943c5028771eb8c58097966b4821bd1504ba1a1836251047c8468089c58ac851999b7ba017267c3a6e20c5223fe5a41a52044bd5103f5b1d31fb9b0105ccba387cca72b6ff1bb27119005d6a29a6200de9dc2c19d85be067793ed476b0324c24f10a8d106b55c63bb346b9ddf44b9a5a5349b766132824cc955214315267d69f82093642b9c2360c2b57993b1ff2c52d8118d62375ac851f5eb181a24badfc165668e7a36817cf80f5873f87a6dbc3cd42c0b2bee57f0e06c93a9807b0bc32de588808ea0037db50b3bc14bf98affd4400dc9566ed8022a4c7c34fc4369987904b362b1d04cf3451914e5909ef750dbc56af138529a601a261932efd626510a528643693ee79284cc3987e3694cac828ba3964e637925b201e270744fd41190b3b1c088a79f31581b0641917dc161b000fb4a8281f6a6b7b1392949acd277b9901637c3454a058589299c48b3401a2e0f788744081cba76b5ec378bb83789f63962ae2af1175176ff353c1cb3632bc0e206194f4b7367779146df4acb6d89652b946a9b9c2b61c0553360616f90e97fcb190c43faa544891745ca9b97950384de8534626914ffcda63ad302c9f001a361ba7a94066c9d8b1f30111faba3728fb143bd788aaf04491951d541078aa1069741352fdf8c032964717ea1791472a2069cf43da46a40046c61c79cf4a7d1e093526d75b444a08b0ca984f2869026a4432244d662951df52ba655ac54c502e83e8587e21c4757166b78244da2b5364d3299981859cc61a67d02b32b19c8ab31b78146690690096d606befbad0ee628103712f0f81e5fb4bb22e65e9ad1410504ca75d29386f73b53b0be140a5b548a48b05313de873e18b030d6f691322a2409f4603c7bc24c103111fba7dd5acb3f019e7cc22bc3f6b1e6acca131364d0fa0694866e2322281cd229c16aa82116ce6fd0187d4034db33c2b3840db1f42c5df49825fa7c6bd62c31a625616270565a2fe3f4bb50c58597f70e6124c2f46a83c3fcb62ac65a5a66557b22ae31c7813243a1f0c4b905a31a40d44fcce89372ab6faf09318a876bda6c3d4d787dcf088ba345a6814cb9a0825ea860af29b81586b25832356c1f976370496b6fe7493e482e0dd9483e51372b093d37f29b9d1a83c209bd98a363df8a3ae430ba3b2acd5bd679c7d4995a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815da333d474be9bacbea4c301148be2ddf13c3c25d7e4f52447a549a27b6d12710da2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = 97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +expected_public_key = eba27cb3f055c38ccb7a5a78348cc39e6039a1126d369495687342f9b7c7c88a5f0d1c2b15e68366532f17d6ca8fd85d8e9249ede8c5ce6572d816657d5755236ac059125743772ea7ea7f42785b48f62974a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33921384aa9737af3a3e2d881224629a76c50712ba306b60fc88b85da88b716a41509a95876355fdd49a2eb7130600abd277810301062b0b9be3c97343e345e8fe25f6b58cb16c90a36830452547f4f658110f0745329406dc8a698a71449888e2554c5b039076f67397a94cd13e4b9f9558bb0464a39074fb6e556494032b5433d3df005ce4a1145f0448af07a089447cee578c2ab5d090a2b9ceaab2b472420a56caaa04387d7969fd51a1923c14959834b905617c61a68645aa51150f0079ea64bb16a8a8fbf701c9f5ca74a1803519792ab169976f886cecc709aa90c408720fed90b58d006f2f50d23c4bac1432176a47627f6090a788403042efd5a7d1a22c793aa8dd9a91e381acb0b5625e0fc203fe0b4c7e816eafb87cd774a5053036afab5b293c23598932ed3658f8453b958c1846c61c4190386343435b04c14ea3597f84a22f70124cb293781accb8ba008425149643e52cc124969929721486b42ac9b592eb1c15c4f8c6bbf901b8dd419c17c38d68bcb9d519e16021e62b211c6ea00e5622486e41f81f6ab58c49ba5729c91b2396f7bc9cf8462af8b06d1c28b0cca2faeda8b829943f64456bd214b7ae57061a325bb9c097b656217d65b36f575d39c11f971157abba074ecc1ba302d5318085e13aed84ac8d16652361b67a02c41aab82d10fc339c53b3e096aec1e1276a572ce1a5700c034014884392cc6eb4f9ad80a52b711053e2245537e76acee36f530610b8ccc4caf241a0f3c1f8195cad80c69b644c45f68ba7c448431705b3e9bb84568c895b56351a09bdd8ab2763054384c116e272f5d0a7f1f158e5f68ed0f47f625ca3732729e53a87d223c1ca807d277b726d0c7ee938667ff1c4af519ab7e1446a077b6045995d3001ff289014e43c7ab738f422aeea3269c878b3a7d979aab698c4b57462339703386cb4d0bb0598272349b04230c6b6708c894bb409755dd4e09fb8a84e6ee678c896992e845908b963fbc407589acdec414546a92b1da98c294b23a53ca79a27859ba787a7689202833b87893fde1b230b936916bb038316b025a5b1039a775b055d6b26797482672f02985e39c88911a4540327e3680c574150b74331ec63076d645743c677abc255d0b11d9489a35d65448a2c1bde4228b4d0ca03441d90b57d5c16b6bc6562b4d22e61e167861cb62efb1a43f008877a2895e95b4e0428086c7c34c146f5fc2c9babcdb0f74c76680a62a5c8a82348e7b396b7d95bca26169ffb90125b765d104ecba32d3291a38079567a599644cbb4d36549f26615fd31a6232688bd1694d6c72cbf04c91638ac4e7c1d8be2cdbab51fae70093af3272b885e56f62bfd925b02d099602110914a50d3431f10a803608806d9257bde17123e939df7e1951883ca93e1820e852f2b511218152011012b8adb46d9c400ef099ad3e412eea953f7eb7e627a762de88e7af6ae0b832190b91950aa40713521e0f54955f2039213c16a604b29cb6dba67b89947bcd81b22700569efb06548944decd13bd133877e44ae8480c46b6b547d72bb1ffa0f88fc3b13e2a48e5b490301d00df251e5691d36295a16dacef03c7974341ec3289ffd87434854062ed9475e758b6c297acc679730e291cbb52562cb9408b07bd70215aed0a1034c6fccbccec88b72e44944ab79592e659865f019280b8723c578096220ce5a0930dab0075bbf09b952c217b4ad8b707b8106f9f5180eb514176aaedcc3bbe0a9bf876895ffb1565d61b01f0a3f2d9391c56b6e6a9363d434b1338456313472ad730cd9374c8d81788fac62d68694df05bb88a6613ee14d13cb6e18f69b372c2944a7a76d3a16157686ab6250a98b42d50b15aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce132814b26c0fb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d5d286d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781ede06a48c1383938a9f242264aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d56524122156503823b600236d3726edd9087504705cb4698a1515dc0d80b3f87c63d575170f45d121a848d897c3c0063dfe9b2d616a96552384fb72d6226a193f90e15b364ae667c34ba27fdd0ac0debcf450578c6d182da365d40786522c37b54e0126ed7b3c6bccf28f40770f23736b394210b67ebfa72f6b27799fb1f6e48cb7407261a86884621c529974635b35f5b4c530e68bee8cc213387b66a4127d01223180067a2ec24b2ebb579f74bfd5417fe995bbf816737722912b5b4dbb4c938d0686d1c2a44880fa7231944c195fbd67c67e60861d169ddc41f8150b52a68c14425190be2abbcf5babb734aa03538899678d4290738cc63eee611e4344ea73b9c41f36c712a4c6c72422000cb93e144f3c588a2299d5704cb347b90b2905cbf69cf1dc5c670909c478094e88c01bb3b3e4fe246f8dc3c62da37bb13b6e2046911d85d5790869fa4a54ff16794620480919c0dd74b9887bb5c125c34d76b3527a42a46b689fc4c57571af13c44b7d30a041028e97c0a1e50621567374de7a4207acd4cb18417c7984645cf4f2b5a5434be8f119798c0760229301e14431b0b652c643c0ea0ccaa13cbc6fa6dc8d348b908b78343978fd5a0eee90ca5104184f33f107837b3ec667eb207000570dd33856939bc8ba671b3731edb2a94596a8f2f37bbbf5048087091fd2ab164f5c6a8f92f65239f08844ed4f605e3bc1bf780877eeb3f4c85bf696c691f85a947461331aa33b15973ab4923f429c7913731bc025539232217f801ec7078e2f0af3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfc6165773a965e55034dd1094966694d7806f2f505cebc3b3dc307405431fca21614089c633b522510a5fca73462b32fd69200dc614c5e88454f181d845b19b8866259a2372bb3361b9abd5aa278b1773057e26108bb020a9610bc19af13454df46b4fb5a68c3e7aba6e7197ad63439c7252cf9507e32072e437296883c93902250165a1aee8be0ce6acc2029e10e97536eb958b691ae3e3aa9996986805c6d1f6356d26c1e63c550381b292fb1b95e183ca933d5be1baf6294c4b248b4264724712b2a2816ed3d09042287eb8a17ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb90c0456e1cd663137e11185536b02d8708644539701b193ba52258064b289d053404bc78a397ab86895baf1934e8b2f6cc3ae48869be7422e581a6ff748519bc30bc96c716b0a24a02679acd5151cb2a0fa127c81ea513c3ccc3b84a34025522486ce424bc04c860edc5758aa990fed372db324614fe91589d78acc88c43c2643d540a509f090ebfa6214832c76ca982faa1ca4465f9c14ab4e6459f072558946ceba113b5fc7024a364970c72933331a6a4b0d4196b9e6219595e229f3e28fb2d5c6c4c041db226ab611b04c3a80fb5a7f15e08df3347def02663aa39409ac4e8c8bb0934b46b6a8816cc70c8c0b11a7ec1cce57bf5baa30e69207d7e59c9e386d5cf7863c133ba1b510f5e06c4876ba7849611bacc369b039efe173df6b8a22469e1f200f2aa53ff84390b88302d9f9915c4b8257754b3423097e7c6b0df0a71b2162050a67be291b2dca0460a455a68068c3da2ec3c5c4fa3a272d45b55f58a01f2a8de5c243ae791c0fe643bcb35817c154ffd29315cc7b4c3843ca4419146422f63246d1fc543f24a884839b4788c10f0846b3fb87e98bc4ff634c05c60f250b8c2bfb46c50c8a5cca5ceed866badace5a8c88a2e2590674727f969056569b2b0615e641931c3b94a12a715925ce33716a985a5762544af3b442486b14316c9ad100396e9885c7b0ba8c67621b6c1e90c13a248a3bf6c0be9f96601572c87154041878891a2a5448ac965c2c7c283166ab39ab1576ad253491ab04a11b824fb6fa516b6709f57b98a610b94b2a2b87f50480640e1084a6eae10faea01c281b97b8eca8575cc00a2020e1533c3ec30d9a55883ea9c5b2681fda938f1536546cc474e5e37a05eb89ae4a822cc6a32b8c828ef782065695dd630063cb97e953b04911aaaea90abdc20af3695492b49b07c26f79f59f32d74674f37971d2668340a4803996358c59051685cf15410a72657355692816699cea982cb364eba27cb3f055c38ccb7a5a78348cc39e6039a1126d369495687342f9b7c7c88a5f0d1c2b15e68366532f17d6ca8fd85d8e9249ede8c5ce6572d816657d5755236ac059125743772ea7ea7f42785b48f62974a7b7270c93b4c6c02ccb87e54ba64caa6967176e132aa33921384aa9737af3a3e2d881224629a76c50712ba306b60fc88b85da88b716a41509a95876355fdd49a2eb7130600abd277810301062b0b9be3c97343e345e8fe25f6b58cb16c90a36830452547f4f658110f0745329406dc8a698a71449888e2554c5b039076f67397a94cd13e4b9f9558bb0464a39074fb6e556494032b5433d3df005ce4a1145f0448af07a089447cee578c2ab5d090a2b9ceaab2b472420a56caaa04387d7969fd51a1923c14959834b905617c61a68645aa51150f0079ea64bb16a8a8fbf701c9f5ca74a1803519792ab169976f886cecc709aa90c408720fed90b58d006f2f50d23c4bac1432176a47627f6090a788403042efd5a7d1a22c793aa8dd9a91e381acb0b5625e0fc203fe0b4c7e816eafb87cd774a5053036afab5b293c23598932ed3658f8453b958c1846c61c4190386343435b04c14ea3597f84a22f70124cb293781accb8ba008425149643e52cc124969929721486b42ac9b592eb1c15c4f8c6bbf901b8dd419c17c38d68bcb9d519e16021e62b211c6ea00e5622486e41f81f6ab58c49ba5729c91b2396f7bc9cf8462af8b06d1c28b0cca2faeda8b829943f64456bd214b7ae57061a325bb9c097b656217d65b36f575d39c11f971157abba074ecc1ba302d5318085e13aed84ac8d16652361b67a02c41aab82d10fc339c53b3e096aec1e1276a572ce1a5700c034014884392cc6eb4f9ad80a52b711053e2245537e76acee36f530610b8ccc4caf241a0f3c1f8195cad80c69b644c45f68ba7c448431705b3e9bb84568c895b56351a09bdd8ab2763054384c116e272f5d0a7f1f158e5f68ed0f47f625ca3732729e53a87d223c1ca807d277b726d0c7ee938667ff1c4af519ab7e1446a077b6045995d3001ff289014e43c7ab738f422aeea3269c878b3a7d979aab698c4b57462339703386cb4d0bb0598272349b04230c6b6708c894bb409755dd4e09fb8a84e6ee678c896992e845908b963fbc407589acdec414546a92b1da98c294b23a53ca79a27859ba787a7689202833b87893fde1b230b936916bb038316b025a5b1039a775b055d6b26797482672f02985e39c88911a4540327e3680c574150b74331ec63076d645743c677abc255d0b11d9489a35d65448a2c1bde4228b4d0ca03441d90b57d5c16b6bc6562b4d22e61e167861cb62efb1a43f008877a2895e95b4e0428086c7c34c146f5fc2c9babcdb0f74c76680a62a5c8a82348e7b396b7d95bca26169ffb90125b765d104ecba32d3291a38079567a599644cbb4d36549f26615fd31a6232688bd1694d6c72cbf04c91638ac4e7c1d8be2cdbab51fae70093af3272b885e56f62bfd925b02d099602110914a50d3431f10a803608806d9257bde17123e939df7e1951883ca93e1820e852f2b511218152011012b8adb46d9c400ef099ad3e412eea953f7eb7e627a762de88e7af6ae0b832190b91950aa40713521e0f54955f2039213c16a604b29cb6dba67b89947bcd81b22700569efb06548944decd13bd133877e44ae8480c46b6b547d72bb1ffa0f88fc3b13e2a48e5b490301d00df251e5691d36295a16dacef03c7974341ec3289ffd87434854062ed9475e758b6c297acc679730e291cbb52562cb9408b07bd70215aed0a1034c6fccbccec88b72e44944ab79592e659865f019280b8723c578096220ce5a0930dab0075bbf09b952c217b4ad8b707b8106f9f5180eb514176aaedcc3bbe0a9bf876895ffb1565d61b01f0a3f2d9391c56b6e6a9363d434b1338456313472ad730cd9374c8d81788fac62d68694df05bb88a6613ee14d13cb6e18f69b372c2944a7a76d3a16157686ab6250a98b42d50b15aa8bc9647a480c7388a78a78d9635460934c7ea57c4979c9b48c5d5b75ce132814b26c0fb06aacde963010d592ac173171b55ae4ebacb3777dc9aa8021fc90d5d286d2769ffb833812f6a6e806bd70c74f87ab6442257f56dc7881a781ede06a48c1383938a9f242264aa93918bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc35d109f57ea2764642ea3473a4f192cedfbe153a37f131cdf447b60e92310eeadf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +expected_public_key = ea9213f8fb3af02330f61ab15d3a31cbf57898f016b419430d790f4ba8a594e2ccb6483e46e5474518ccd033543065cbe6a5755e97790c4109a5cb18b124992d885493e03a262c3da395b46a069b9154c81294a7dd59bd092b69aca326220475fc792aeb639ccfa62cb9c549d28736a944af91119ad865c8e13700ce9482ab6b89fa7794f9d273bab516d142455a78675e21a8e74cb13876c82c738a55a4649304cb8f9cb2dce220c1bc06ddb0c5291595bd5867fd105236a91d3d61b25950c4d991625d3aa711a2449d118a51a88a1c4c17ca680c3ca950d141a220a0271a2b0593db333c1ccbe6a1380e465fe60404055bbfc511895861a32433a7037a00cac8197ac11528011e4eca80bbd921f2bb8162c0580fb94207c89471da649ee7cffa4293c4b6baddcb88efca19ab6c6e71f54814b8a2eff67ed476088dc30727aa0a47b81f9390bdfb93c3a8281ef3b92be88b130fa739023aca492549d42103663b97d7318c01e0660696984aa5c5bb1019024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785a41a25703627f0a51bfa82344723c0ba43184a77556b8cb107232f480488cb24f8bf324be8116fb49c8c329bbaf00c9ac7751a39a222217979a83301c0528b87992b87cbd5c576c806b4e8c383d5fb025ce83104fc5abc9d235ea374588505018c167a78902adf24f33ac22811c612cc09b4ab1240fa18359134cf4f657fb5c96bc544f83b8b02620b5564694284452d8d0467716bf41504dbd6574f5ba2879b674e9ec858700213df91f5f9b18686669c9365d2f2cb9def360eda91272b876cc75a022724c7caa7e003cbd0b8bcb5b8656fa7255f0c8be4bf2398e3106e47ba27a934896370d52e0cffd9263cc85b6266018fd6303371969e7b78d326c9fc2c9a5b1c32e68e218ad278a8d5ca5629210ba342148e45217d594958bc0eb6a13b5910af6f616e290472ce203a7f76f1aeb4651f00397fa537fb419ef2ca0f28834ec0ac07b11bb22b3a1a1b1cfb4679586f720bf6151662303f6fa774ca020fc03cdcac3b74c319c5b23ceed4c24ebc48f067735cd5a02f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f6082965579be60a0812d34361695ee6282998219366628ed9575203d6652fb127074cbaebd2c1b25c520468a4abab0b550503cdd33851ecae8bb27726396a15a63dc26078368aa5a7c1b075e781fd231ec27cac42eb9e507a82751b7c8cb7b3547b0a1a58c82cb99da9cb926e311b5a9a1d682bb8da2c40fb679ae4c15ea0360a39eb6fd10719ae253aac91132938579d3616dff29ea1d33640e3b71cf2652e85c786873e1457762d230e99b81db1a99dd0a8ce052849e1f8a5ee050eb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02907032337720dda9b9f8174fc20afb4439a21fb979af288f7b7101b104e2c7a9002b353dc1c80bfb00797455640b603b65c4cdc89254014079fb33217a15c31f6262c1430002aa148ca251aa15981947d27951f24030f9abc3e49370a94d803094881f3017a8be248e2c9515822439ae537776949641513c99c695625134348172b76b8ed929d1063b05ac774d83a3a6b0482eba52b2f07bd17021e0fc4b7651347f4b95e72f0a6d676158ca191a5c9975b1bb5b5218093eb9716e350e2d340ace90956c05b5d874dd60a7c9716894f551dc5986e378c830af8ce327a027741431d48714223c83f7b1dca94ca5e99814e1311c69481f38ba87fac128ea30c19b2baab1a2383113e5d282bbf0c4175a69fb4db66fe4421bbb26b990203929b3a58a85245bacede19159d1ab21537cd7861191d15185cd5b4f07a2559110cb42bc0cba54cff480750b56933666cc470b2504895a1213db43c5c176590c9d97ac7279d6dc55ccc7b1d4d82bb33f240b4c635a936beb5d71f787c396371c088d65f7b2a395071a4e6c381a1708ec05a6e55959845b456794055864c566d445ad9091834b77a30228caec6a0829bc243a9330b42010d62149d672373812dd014873bc79f627b25b1ecc782384e0dc8accffbae88c0415f6cc03e7640895c744f4707e130a9c9ac6cbcb70729db69ea7c6d8c8a9e94c1438c96289b41419af6ab083219f8a88753ca8b6ff168d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_private_key = 953b6e6f452ffab6b9e27b707f600992e228f5fac92680aaf31300154b218ae51a012a4cf53840cfd714cb63cb4c7aa0e8ea6e50803ca370bb38c7205d9365448b38308868c83348acc365be62b4fa763ecc5112a48558e57230d92b5869d77d99a5c0bef49819500b333300910117e05b082d15368ae529923c6bc9d3594ab33c91b81549829a2ee55ad152493e80aa80399f770899ec05417a698e6493aa647691fedc92854c23702caafc8ab3a3194ce8437b8e2a7f69454adf3170c282972abb93cf152dd85587f6272b0b71590c81b3a9f680d19445fff0c395310a17f55272cc3e1364a9aea7a67af4561cf10043b7b7eb4ab0791a8d62814f4b6536cfa69ca0493fec1a53d58709fbab9c87578d83c9441d62c267e7aa4ef0afc7106c9f834a5a13206c4b58d7378af90b85f7e05237559d6d7819f455aa01d68bc297a8dd760a0df971542919979218b4861a49e45aab12be67080d197c25ca53483d781ba27893d23baecd393dd1643dc2a53275c84a19900b364ccc94a8ba3b5768f8dbbe08a7b08fd2746bec62c98c5e5198695b12048ba5c98753aaba88bfbbc6c8de490afaa8343d334aaeb72532c63d60667079b41b6a287b04c797458acd9104c94e96bf18137b0868737dc00a8e2164e0980b9b2135dc7c0e80e1b930c22874fc2cdbe0b5542732e8fa80e407a1a6e5af0aa3168a963587379aa3e6a2b082a8a35604bad827bd6aa1fea76a608100ddc40b17283eddab2335b8796dc1bb57887787a4273c4185867368be581f6e5767bbf0580f07b003556ecffc3ae336260fa0a80a2c9e4c9914144551c89a9d68373ed9c7afa83c75c6b8affb54187d3b46abdc61d9e070b5584be7564f932985ea4c739cc906732a7cf79a65f0f7b0682caa5d2070b3e0699b1bb3ac0b38caf22ca4db9472d06b02954e36c0a3d8890473588c77e43990da1c7103985761ca711109bec0b805607d732a36baf897e93c6d9a988b94c67a4592b7583126fd452ff0b45a033824983715c60478685b9c2d013d41b47eb342a05fb76232554df30990d6f1b37ea9172020c66fac8f415615ebe07833a2588ef622034074b214ccd9395648071821d1109daa87c0e00cd9573254538ec3b8459ce56578c09ca66a508e88c4dbf6183a268b86fa4b7733a8cc89ac81619af8f56d8adb1f665a7ac413005be730aa41cef2b06a7fba535552c8cef73e90a8584a8b799c323f61faad4b8c25d06cb883493147069eb1c9c8fb262b699693d0601262e9ce5b383a0d27c1572c49547bc908c003490827343a690859a15b20119975c35aa991183052f117b53d06c5f4683d19ca5ba6f5595b8b269d96c1b3524cc8fc6eec750ca33b5518603f59b50741d246642bb88ef61a8bd4c54f48af3f573d4cdc5143ecbddab5a281400721544e16e35ea7a05f161003a6c3adaf690189bcb074f546bc2033b1e8b00d56cf32e0733dc81d05eb358d148a91faca963b814a9c5fdfdb4de79b729dfc26c3d9b48a4730337b0bac8c2a3628268159979f6b10aa9ab90adab98b9c0928fc4e3570ab01f02d5a64c5f605596e3498ea532472760f61cb2eb734c174e48237c656636645886b65c566bf95d927b692a02f0100ce756a60b508a18754d8f6bd8b884e0ac57f0c0b8f12347d40fa30f364121147263860825461bde41136af083b303ac118d685622cb7c4092bc0063328a2484d3392f8ac4d91b64c2d19a8d2a1936efb0ad83c76b51310afd878246c52a2b13e8d3719a6729bbf057365185e997603164c63495a651a65926ec96c7c54a03cf00a74a83fd59b1bb33c55711c4e268ac89c730f84858e67142f051c617e131bf1a66fe39c5ba4d12676549d6331b9ab32a10cd9ab9a686216e0cc652c981f74c3a070a2520a9f45336b955c46cab108365861e5c79bd4f92d36959804bcb458f8436241ab5b204bc9d48bae38bbfa500de53a7ad671bd4a29057951645a346c2f7b1e6573323cf6836433505cb116361919ac640a8e504307dc9b0641a2900313fda004a1c4a8f0eba7c42985472a57adc37d90139dd6f23e39b15db0736b8616603da46ecdb42be478b728519bfb1a95a33c9b7c2a52fa1a089d647fa6bcaf16b83f27791a59c89011739909dc13cd0a8e32381087ea4024189fea9213f8fb3af02330f61ab15d3a31cbf57898f016b419430d790f4ba8a594e2ccb6483e46e5474518ccd033543065cbe6a5755e97790c4109a5cb18b124992d885493e03a262c3da395b46a069b9154c81294a7dd59bd092b69aca326220475fc792aeb639ccfa62cb9c549d28736a944af91119ad865c8e13700ce9482ab6b89fa7794f9d273bab516d142455a78675e21a8e74cb13876c82c738a55a4649304cb8f9cb2dce220c1bc06ddb0c5291595bd5867fd105236a91d3d61b25950c4d991625d3aa711a2449d118a51a88a1c4c17ca680c3ca950d141a220a0271a2b0593db333c1ccbe6a1380e465fe60404055bbfc511895861a32433a7037a00cac8197ac11528011e4eca80bbd921f2bb8162c0580fb94207c89471da649ee7cffa4293c4b6baddcb88efca19ab6c6e71f54814b8a2eff67ed476088dc30727aa0a47b81f9390bdfb93c3a8281ef3b92be88b130fa739023aca492549d42103663b97d7318c01e0660696984aa5c5bb1019024862081ba8d464b2d10ac6096b5b04b5cf867c51141a785a41a25703627f0a51bfa82344723c0ba43184a77556b8cb107232f480488cb24f8bf324be8116fb49c8c329bbaf00c9ac7751a39a222217979a83301c0528b87992b87cbd5c576c806b4e8c383d5fb025ce83104fc5abc9d235ea374588505018c167a78902adf24f33ac22811c612cc09b4ab1240fa18359134cf4f657fb5c96bc544f83b8b02620b5564694284452d8d0467716bf41504dbd6574f5ba2879b674e9ec858700213df91f5f9b18686669c9365d2f2cb9def360eda91272b876cc75a022724c7caa7e003cbd0b8bcb5b8656fa7255f0c8be4bf2398e3106e47ba27a934896370d52e0cffd9263cc85b6266018fd6303371969e7b78d326c9fc2c9a5b1c32e68e218ad278a8d5ca5629210ba342148e45217d594958bc0eb6a13b5910af6f616e290472ce203a7f76f1aeb4651f00397fa537fb419ef2ca0f28834ec0ac07b11bb22b3a1a1b1cfb4679586f720bf6151662303f6fa774ca020fc03cdcac3b74c319c5b23ceed4c24ebc48f067735cd5a02f579693c6ba2a58c8a5ce9b5cbd88e4b246cb75b34e286455a7936f6082965579be60a0812d34361695ee6282998219366628ed9575203d6652fb127074cbaebd2c1b25c520468a4abab0b550503cdd33851ecae8bb27726396a15a63dc26078368aa5a7c1b075e781fd231ec27cac42eb9e507a82751b7c8cb7b3547b0a1a58c82cb99da9cb926e311b5a9a1d682bb8da2c40fb679ae4c15ea0360a39eb6fd10719ae253aac91132938579d3616dff29ea1d33640e3b71cf2652e85c786873e1457762d230e99b81db1a99dd0a8ce052849e1f8a5ee050eb607ae2db8aee4d76845158617e4972bb97c10383a7c19a02907032337720dda9b9f8174fc20afb4439a21fb979af288f7b7101b104e2c7a9002b353dc1c80bfb00797455640b603b65c4cdc89254014079fb33217a15c31f6262c1430002aa148ca251aa15981947d27951f24030f9abc3e49370a94d803094881f3017a8be248e2c9515822439ae537776949641513c99c695625134348172b76b8ed929d1063b05ac774d83a3a6b0482eba52b2f07bd17021e0fc4b7651347f4b95e72f0a6d676158ca191a5c9975b1bb5b5218093eb9716e350e2d340ace90956c05b5d874dd60a7c9716894f551dc5986e378c830af8ce327a027741431d48714223c83f7b1dca94ca5e99814e1311c69481f38ba87fac128ea30c19b2baab1a2383113e5d282bbf0c4175a69fb4db66fe4421bbb26b990203929b3a58a85245bacede19159d1ab21537cd7861191d15185cd5b4f07a2559110cb42bc0cba54cff480750b56933666cc470b2504895a1213db43c5c176590c9d97ac7279d6dc55ccc7b1d4d82bb33f240b4c635a936beb5d71f787c396371c088d65f7b2a395071a4e6c381a1708ec05a6e55959845b456794055864c566d445ad9091834b77a30228caec6a0829bc243a9330b42010d62149d672373812dd014873bc79f627b25b1ecc782384e0dc8accffbae88c0415f6cc03e7640895c744f4707e130a9c9ac6cbcb70729db69ea7c6d8c8a9e94c1438c96289b41419af6ab083219f8a88753ca8b6ff168d85c8a2ac94cb6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2cd65fd07a78e48c1a02e235ec76fdb509cf9903a4f5a850c51d9d3fda383cc67df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +expected_public_key = f1564b86096399f0415e5b757e7a6f9ba5120dd8a938e06c7ad8581fecb46b60afbbb444ea375e53837827f80de1e3753a4aa255a4917f1c8af87923f8397c9750cbc7e5864049315e718aa2732b6bf7be35694468f55b45449934715e460c6eaf734f96a1adf87609f8551dca87a94f0217e4e507c2b637f368ccec681f36d6cdd469be9d0bc7828c1bf13a2d28b8093b59a174d271ae9736b6397a4b8c9e4ed085a705a4987bc56dc172caf58e543bb9d151b259e735ca851dbb685d5158596d61a411e7c542a240c4900bceeb6e6aa7acc7db5dbf60c178813051574dcdfaa38d6b8eb595712c8b758f7827a981944f550597d120e926486e623ecd029e92825ebae4b6d049011fa7216dd81c005b376bf6b1171654b5a3ba932bc98111b8213343b9e18c9e7479611606961b476adab27e457225351e2981a4e65b6a7f0b02078505d7d3b7dd671c1bb79610dac7c92518a8b851ea5c3115f5cadad3cb24923baa686542e83482b725474381409a4016e54066c32420e99349d0c5a32ccb0b010983b96f8c657018ac0014a34020888317a13c8296a5fda3937ebc61f2d1022b2b00e7a6341bdc70d1a11b9eb10673c07e612363e6f0413095561dc15c313138efe56c67877c51f216476ab182a233f34801205a9087ba56a938900a0cced6e16462a5bf746ab679aacebed1b1b62b78a1e2aeaaa336f5286a84fa76e1fab798749d8eaa1e71c48ef6a08977235ec54179cebcc349863a9e40b61d68c1ddda72d60b061f0c42e6c179c0228d8722ae90d022d9747ccf9326e4e27bc87257c24892043aba248c1ccb8405a66712779444ee39bf91292b9f926d1c99c65a7941bc7c1378f682f390b855d88273e56fc1067088232f679c5544a03b64cb2a8d9b8319d254c3b19aa6184b1db0529bb9750df0cc6cf5a39b7139383876f633763cd07feb86393f6053a25b043e6b736b0309e7743103f0262133a4b701028db889fedb88b0f5a49d77938c33a5af559468a91e6184bb9ee9bd71d060c6f0b2a2413bba67493fb9a12e7b8c4f35497ec192b4086b4741402e46c97dd85f12d79a9b915160c788bc552a00c8ab88b50506363ff3eab9f84b5aca7460c882015ec08b3b4155621558effa01b4e1c3ffc310a2405dd4d4561e8bce8af738cf65279fd56571bb2a76faa6b1ba9b0b9c7c8e8c9349d504952c8883a4bea1c2c7f0528840119bbff2b2887310a7f1030bcbb0b8002402c2c782c183853658fb374de5ac9bacc24dad86b088daac4b62640fbc5eb9990e089b1f49e95bf3471edfa0521fe910c0da89a1193d2acc253c9aa8ed15bb4bcb16d3c14d262895d594693825ac0ca0567acc11c94a6c27438d6a5403a320b2c4c47400a9817a2296be402dc688957c7494600870e84cbaa433076b201cc64b3a3a51311f7c5a3ab206fa37c0a1c98048271648b5a5384c119dd73ea44370358182c713ab2e399655a171670a5295773d2c36b6e4b934599656c7808f13044084a82666742eb6b605dd2751de5872df234694a84397aaaf3b894e0a7507c3a354dc3409ccba4cb16b5387406bf7d005a17352c4d331b7801596f031a7a15044e1bcc00c4a920a1ff7cc1b904847977261ede038c5c51841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c45c2471ee52019b952bf716a1bb4059549a8c0bba67519ad4f10cfee06bb34496f38f9491c172f2be413da1b0a7de20dcbc1aff4103e546c8fcbb20bdca475c9161dcea2aa3ad534fdf042b2776b04477b14f2c705c85b3a7c5ac3803b3548b132c6af8e90ba88ba49981729a8621f30c2aa0dab04b49bb28abc92d9cc8311faa8dab45d545611a36b86549760cbeb4ad464199a35811a63cfa00a8a1bfc202ba75d73560eadd235c2490c8e514ca29b30ddb0996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553035201e48c406382a842256162b067f887729e298436485f10236f67f96d263c9d0835171dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99393c1c35cba50014163c84977edc8f02ebc9b5ec5045c6b1091ba794303e8bb52c7b8238a635c23d3c13d9e918d29025474098419aada6720c70da55905c197c1114c60054fcc651ab6aa9876430d4d530ec7a7a734189a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_private_key = 87c0b4d44cc9eb48c126c5877ff87929b08485fb81e479139c3299c70c43c3fc8c238a81d4e61e62a33db2499c866b7107d116b7fcb1b0530a7e758a8d487d11575079265b3158302a23732bd07330071bd7cb7199476c39b583a2446109e99fd5c95be21a292cf37490906e84a82605b8455825c82eca4b7e218644460ce581214c78ac4473688bd6a9a826217490ad791b7835a85935782847981ca97b6dfe88b63701cfbe3929a2dbab1628155506c353639d153656b90c5aff36baedf1b87da5bce2a108fb6c3b29e77dae803a0dcba48ac6882f6c1194e88387f30a47c27d02c37d988346a2a29584a55cb5d3c44c05a18619a4fd412babc31a046221b3994c8f22ce272c9e6e948c3d043295f413349796c38911f8dcadeae47351c15e9a1743eb65bdc7471f37fcc93cec867cd4808ecb281fc17efd004dd64ab432d664864b43f8a9b1e763529ae2c413abbcf30a4a478a30a0104d802037c4a8af01b534dd600e31a1630ff13b2f730924cb790166af3b7322baf4409cbba500c1bb32894e65445f04e4b4b4933de51267635037faa44e2775caa4212f4e0600e51069aba662c86145e2117347bb1748d63e412550c004237cf02b02aabb18d8533d19b1a879a079b31d529aacbf5258483c80738b380c83119c12b23cdcbc7d027506f3705ce1316dd24594a4bd32d10382f8ab47478f23763898398d7430264203a76b0c4455237f3e765ea5516388595ce9e2bce2dc2258b5b96c782865fb5354427a2d7806123b0cca782b1c329411c6c133934ba4a959da88a072bc6e2d63a007572e36b82c5643564bec47bc8953d4aaabd146ab5eb36e33f825fb9ca01e223253c320f76c98f810ca52a2c604622f7a60378809a59b19680aa69eed2003e272b8a1f3c8a55bca129640c5a00d187bcaf465204c73cee66a2feea414f02859c9988356d26665196674d25e64cc5689965cfdb2c0e47a531ce32b3daa9c649954342a3f62253fdf826aafca7dc85a7a8e15161435212d7a4a3bd4b57a2ccca3506999d407d9b6abcc97209fa97454b0974dc2c7cf3c3fa40306cd6239dc450536974a8ab773374504b9889cb42bce4ef4606bdaa559346f18d087bf8b7f0d9b21b0c9b75b5903194b0744a1c47483488eb4c1ca2c83d8198cc6a523d9329f6582863cac2951268c01770a8081c1c26587d7610088e6068e020e10472c825c395ac6783f074efa8597feac3734399bfa247e4e1531eac70fe49355e44b3ba5439ea1e65eda94485fb710124bb968490f1c8b68e87a4c4682156fc06a33275b6b202aa0d508b3789aaca627f0f0c19026cec38a95f7547d936b255be7a7525c97ab4282714c32a23c4723a82298f2ce90fcb4761b9eee869e4d3484ba2b222dc28bc612b1f41607cf57781990009f29617549c0b2179705a34916db154aa3747867c3ef6a0693bba5c1d42e14b3247b41059f92607a60afcdecc1c6f3839db943f5ebc4d340aabe21269095b3f7d9bde9ebc21de788794b63e1098cc2903a83ca2027e8bcb78b855fd56fcf16b45e47994aac71fc815c521ac1a1b697a18569ac2816f52640cf9059c4eb95e6fa1b32b77bd7cbcb6ab384de74b6a2708400e980eef5acdbe5733be895b64107266c565af2a204e98fff0058161637f5f0bc5e539bb0e12590a00f16f57fd0962b7c9589f6d3062d81860ccb94882c0a06d5965cc9bdf6213215867f1a0c30822046c985896f62684d95765ae1c25501186a3aad77820aaf43c955a83a259982c77b2904aa471bc683bcf97e65e27cd82c545b096e9b762bf3304d9d5c1f3e6663cfe80953a86abd0007e1f2628210b042f781bd59b2dbf2899b97a0cc345628c4c3bbb583d8807140c46bf8931ac3c34cfa78230882395fc1a51c1b50ba71274aa2383374b3ea238ce3b87247e0ceb0991ad9f74745698d06c1a5ee089e48d9cfe46a4fe733826462c188e8615aeaafa501b9d6c6a96ce24ca097187f618df5686513684ce2a9077e81a83068423a916fb4a8a47df2cb88572f8fb4405ae59391566c88872f8ac48e705b0634a370f0ebac6cfc66c4b536d3bc22459b2b3499acd921367459c4bb3a2babc2916e9b99e86a6c649c18c8e946eb106ec7a97595a503e42419a23109f1415e329290ec5581f96c8cf1564b86096399f0415e5b757e7a6f9ba5120dd8a938e06c7ad8581fecb46b60afbbb444ea375e53837827f80de1e3753a4aa255a4917f1c8af87923f8397c9750cbc7e5864049315e718aa2732b6bf7be35694468f55b45449934715e460c6eaf734f96a1adf87609f8551dca87a94f0217e4e507c2b637f368ccec681f36d6cdd469be9d0bc7828c1bf13a2d28b8093b59a174d271ae9736b6397a4b8c9e4ed085a705a4987bc56dc172caf58e543bb9d151b259e735ca851dbb685d5158596d61a411e7c542a240c4900bceeb6e6aa7acc7db5dbf60c178813051574dcdfaa38d6b8eb595712c8b758f7827a981944f550597d120e926486e623ecd029e92825ebae4b6d049011fa7216dd81c005b376bf6b1171654b5a3ba932bc98111b8213343b9e18c9e7479611606961b476adab27e457225351e2981a4e65b6a7f0b02078505d7d3b7dd671c1bb79610dac7c92518a8b851ea5c3115f5cadad3cb24923baa686542e83482b725474381409a4016e54066c32420e99349d0c5a32ccb0b010983b96f8c657018ac0014a34020888317a13c8296a5fda3937ebc61f2d1022b2b00e7a6341bdc70d1a11b9eb10673c07e612363e6f0413095561dc15c313138efe56c67877c51f216476ab182a233f34801205a9087ba56a938900a0cced6e16462a5bf746ab679aacebed1b1b62b78a1e2aeaaa336f5286a84fa76e1fab798749d8eaa1e71c48ef6a08977235ec54179cebcc349863a9e40b61d68c1ddda72d60b061f0c42e6c179c0228d8722ae90d022d9747ccf9326e4e27bc87257c24892043aba248c1ccb8405a66712779444ee39bf91292b9f926d1c99c65a7941bc7c1378f682f390b855d88273e56fc1067088232f679c5544a03b64cb2a8d9b8319d254c3b19aa6184b1db0529bb9750df0cc6cf5a39b7139383876f633763cd07feb86393f6053a25b043e6b736b0309e7743103f0262133a4b701028db889fedb88b0f5a49d77938c33a5af559468a91e6184bb9ee9bd71d060c6f0b2a2413bba67493fb9a12e7b8c4f35497ec192b4086b4741402e46c97dd85f12d79a9b915160c788bc552a00c8ab88b50506363ff3eab9f84b5aca7460c882015ec08b3b4155621558effa01b4e1c3ffc310a2405dd4d4561e8bce8af738cf65279fd56571bb2a76faa6b1ba9b0b9c7c8e8c9349d504952c8883a4bea1c2c7f0528840119bbff2b2887310a7f1030bcbb0b8002402c2c782c183853658fb374de5ac9bacc24dad86b088daac4b62640fbc5eb9990e089b1f49e95bf3471edfa0521fe910c0da89a1193d2acc253c9aa8ed15bb4bcb16d3c14d262895d594693825ac0ca0567acc11c94a6c27438d6a5403a320b2c4c47400a9817a2296be402dc688957c7494600870e84cbaa433076b201cc64b3a3a51311f7c5a3ab206fa37c0a1c98048271648b5a5384c119dd73ea44370358182c713ab2e399655a171670a5295773d2c36b6e4b934599656c7808f13044084a82666742eb6b605dd2751de5872df234694a84397aaaf3b894e0a7507c3a354dc3409ccba4cb16b5387406bf7d005a17352c4d331b7801596f031a7a15044e1bcc00c4a920a1ff7cc1b904847977261ede038c5c51841c88be1cb8b214caaa5d3bdfadcc66fb49afb234dab467c45c2471ee52019b952bf716a1bb4059549a8c0bba67519ad4f10cfee06bb34496f38f9491c172f2be413da1b0a7de20dcbc1aff4103e546c8fcbb20bdca475c9161dcea2aa3ad534fdf042b2776b04477b14f2c705c85b3a7c5ac3803b3548b132c6af8e90ba88ba49981729a8621f30c2aa0dab04b49bb28abc92d9cc8311faa8dab45d545611a36b86549760cbeb4ad464199a35811a63cfa00a8a1bfc202ba75d73560eadd235c2490c8e514ca29b30ddb0996798a4f5f76765d977033a5f61196ba517ad5764c0e1b553035201e48c406382a842256162b067f887729e298436485f10236f67f96d263c9d0835171dda6d1e5a89a7137e39c39bcc7488b1b365a1ab99393c1c35cba50014163c84977edc8f02ebc9b5ec5045c6b1091ba794303e8bb52c7b8238a635c23d3c13d9e918d29025474098419aada6720c70da55905c197c1114c60054fcc651ab6aa9876430d4d530ec7a7a734189a5844ab93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a376f022313718aba325ef4c3b720e2c3ab314ace74e983948ba2e43ee3a6ebde0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +expected_public_key = 14b0961b350facf720ae691dfc4a847b143d9c9a2d2e7a35b6e33dd78b761125bd8c4b1d6994cb8e01186dfabe6270a51cd85b8b39678af4c337bcb4fbbbc0fc260d48aa801f86538eccbd3787a12a09b42e18afa2e8c77bdc11b13b5a8404cdd7b2ce364046ae059a4c950e1e4638ccabc8157b97a238a6fcba379bc6afda874335956d2325376fe1ce4405bee3e37ef818b9826743266c078c01c36fd62b1d17adf33467d9c1ca9f2ca28a2867bf7a8084daaed0a19d2d40a0979198135c229720205763401045879ed65b09825012e626a24118cee00216930d44a9bca32bc74a6683a8d1bae1701b189bcd8feba2da42cc3b572151e7243712789b2801043196bd8c15d972cf7674771dc55e74931fc0a55c434497a517c99ca3276d262ffd83cf66d87600d097b1ab5dd8dca86de94080da8c2aea980b3a1115b847786aa96b94ac818148e3e4c7fec633cbc6bd3104ccb216074a5b2a8c757a455ab38e1333435c3c30d94d8e922e8e77c0260b6128865bc37b82c7a6a276040edadcac335a10b569a2cc53a93b6729728b84b74b01d502b830330000aa1ccc9c4d7e7a74ed218d47ca60016411d7369248a261d6b6240d5b15d2fa5b3229373484c8d23bc8e78830062959d0504c92c0bac310967ec40af0c2902f82742efa78f57b70bcf54a73aa2aa93b0fb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad107711aa1729ccf857a14b0002f61575365f3ad9c18b947bbe9b3e31a7571a918728479710d64dabd569873461e12a9dc1103ba28028e001c8d5a79d24d30756cbb4a3ac9e48435ba09286ae89ac3c841e8909a4d94226a822c90b5a40f239cb0e8b98e86b5b06e20dd3764e42e8c8095052b1f66b76f164b3b867a98cb299e0995d44b5febc7a1f2c0cb2d0cd4f3ac5f9d5444797941666afd319a3c6713ed1e31338a41a6e2b548208cff5671a6fc7ab5df260c2d8a703a67eafa381c9d576c6c2b1177b6a66d951bd3c426fa79cc7b552ece197c92856b2c7064605079404a3b5d8b49afb9c87ea48e0811a61e81e2f101ca25a6a599947341040e381a52cec894dc9b6ad25b79dc903c35c450201071dba35ef8c11e17a1ae5ec7e13468c148a5946d928ed0321d717640e5a5767942ef2275e05e395321052e3e5059af77fb04271c2e511f450be168aba09d3b9eee1288ed1baef69ced005797982316e2c731f9581cd455300f35a6e1a5872552ac6eb68ccacaf636cc713516c275823e4a1a30a722f8c46a8932550db624dbb8b6e0bb51c3d54089fcc2042f38f5cb5988e56a1f42a65d5d788e2551f60487490b57904127433f685ad4bc53d6213cdf52d6b0991ae37882d37b5dc084e5a49bef660a4e8d03e24ac93e58bc05f8a759895074e156c09e73e6782c00a6cc80cd04829d270c7848d89bb2c321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a08314b29c81e31b63a008a51d283bc217adefe37d2d9b15c7257cf62a68751c2942c531bb55abfa321c581822c90c243d94b598fbb958e5950fd4c8b1f1cd06bacc30828fbf73a83f7387ca252e4f9805419c02d63189ee7b4661b5c1bd398ec82cc8da173ede64a38b3c1ed53a64db130564d2a54600bac8017d46507b3d56208975a70351a558d5774b249f7d634e6f21102310b6bf8c1544e217c68768400c3d721ba5c0f77b9d20795c8059145956ac7b7728222853a3c325d070a9eb256775c727118eb9cb7134748ccfd09f32c930881826d8e20af48b2e1ba10efc67ce0ee7730093a7305403eec951f59044a5f7317cb85caaaa2e2b5b90ab2b805a808c1be755f9a4c342a96e8ae83cc4394d73890f13bba0d35c45393730e4118d5345006ae62d38445666cbb7c25823c59a9d62e08bb8c7cd22b331be153af7c359091081fac67d96384100f44951422e83599763ab739fbb8ba2a064a41cbe1679a1c613815e9a51d5d6251ee73431cbad479cadeb64ac94f92a38d0798a4b6d3ef7233572b68d2a12d125a6d4e27939f341a4810f0c07bfaf993f8a74bf8e9710e7b29389ec3dfc498a4ff1839a1268db8b70e82670e689b5b3e333908b6e8b4a78fec249e798bf57b7ce985a42a5269435c81ba441230ea52319550476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_private_key = 4dba785b32456e16a8e9a20fa7536f1b4555a9b403a09738657a148361788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c12c284f848b89585f76892fd65cb906d39b385a04d2f5b2154abd1e77ad9501abac73237780b33c601fac50ba3fc07e8525819593b7d7e69fdea46f14f1128a475e4784af38985501dca6d20bc8dc1c5c7740b33804358f71b6e97b2a0e7350f7608321736083dc54e0253c6e5c5665d0b7e68355d4e98daa753c1abc1429b397da773b043459e5aabd093a5b0210502bc2cab250041997861286924aa0a190307431719588cc2e6fb68711c964fc20393c73b7c967c603120a3cc11b2efca3dd6616d0e2c835fa92946a40c4cc2f4655301ecb09424286b3c7a07ad3c6ea37bf6132aae2d9a335e34b6c816d93cc7ede020ab723b272b70f494834ccd93bd7800bc39919dea4be4c585f827a4351e233026760dc83377329ccbff180a562ac50833c0f861e795c00ee74b584f693222b28eefcb445f19b06154abd0110c6a017ed525b5fa30c64e60663573b8691ba68e2bc580157f1c66ebe388aa2747c50919af644acd903a801a5c04a6a2eac686c89835cf59a791ad5642274a0f78244491670c66c9bce24ba5cf6b86967aefe6728dce8973fd29045db844dc80022297cf530c8eca4808f603a90a840ad70a803e6a0bfb44b38616816073c5d7ba26a64048f81a3bad3a0c9cb0672c7466e38824529298a7c0d82940540c312f429411b403f64e419cf720e1f73026184cee538b27cfb91f16186dcd3904ba6a34254155b3cb3157937d5618568f46f283c7c0e88696324a4fd77c3e6fa5b5dc0a13116274e5792fed69eaba973730a79878103bf63934d179143dc23ed39585d40c06a99aee0f4462f123b8a6b539dea9e05117b08338dd6754398e7496f612b4d892ca54a13ec9b2dc7022cf779668809ad6db97a6e8b15ff0a862e664d292c4af549195a23c19e2b9fcdb9b4a5b9ae517873ccc644993196de5c2716d58d50e7cf11558f44a16580c980654c8ca581671121cb2f8cc6f90529c9754cf0700b30943eea1a7b05f0bc8fdc1cf776b0cf2c2eab927dc83197a4071dabfc07f983bf4d2c613e087976eccaac031b88420ceceb6df0350f04ba61ab39cad4c6b2b32503d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5c40970c435508e26cba50705c6538686249d344bdb7c820a5c8869b371b8fe13922a5af390bbb7b809c392266541671c75cc2b7a7248d0234fca16da64265e5c70257d770d2e9982d5a1c6d19bf0ba48b53ab900fc8280c754c14774939b83c63592a12f35d198194679942ec227b46cc8f353a0547e929175c3585107239aaafca151df3c835e770921e5c9b134ca7e27a18c7656bfd6a4fd2431ce1743576e575dbba8905f4cc38108e3cdcbf0155b5300a100958aa99940bcb473ef64b05baf55e91952c46851d313b0990ebcf2148cf28130cf49c8d080841fb81384e73367c792a11099f5b898416946826714e252457b23a3a1e33a36ee2612372cb2c04030840a87f96a31913a428cccdd2817b38372da4637f46044f2218c28d525a57d9c0cd2864fd43aa5c9a003a09a35ba786a7520c9d9971d6258cf3c6695885684d1a5fb2b3818015ae887555fb1997b7a35a326481a566839712033a0ca13a844ac6f21a16269876a27b2d49458515b3ef0a77f933c9d0f1406121bc8bb666a1284798055595901488439150db602a5428ecd32109731bee5bb8de606ec8d227a432994dd912637bb0b3b198171a89daa720bb712cb598a75b4ab304a9468088a62d0059dac56e17bc95eeeb6c22db8d8ea3c6f272a793e0358e193d52029e2a4582cdc65848c06652e44310506868365012c9befb412d1a844e8c21a613627b4707873dca67ca5c0493a83eaa227fee44731d24938709680e1879b2a41b12e71fcfc39cfd81186250b6cf4b5796e831a49aca2b8c2931328ded15cf2d082643735ebdb8ab019609ecf95f5d093a147c3caa73946cd38b4e21073bd72ff958c7435088ad73a5d343ca768a4ad4b2a49b6b6e17a94d909837e872a05c815d18ebb4e817bdfb327cbcd46404060ddfdb92631b2e3e262283bc3292504cbfea8f30f085fa12270c834d6b6a5d2a46098f26029da3bf14b0961b350facf720ae691dfc4a847b143d9c9a2d2e7a35b6e33dd78b761125bd8c4b1d6994cb8e01186dfabe6270a51cd85b8b39678af4c337bcb4fbbbc0fc260d48aa801f86538eccbd3787a12a09b42e18afa2e8c77bdc11b13b5a8404cdd7b2ce364046ae059a4c950e1e4638ccabc8157b97a238a6fcba379bc6afda874335956d2325376fe1ce4405bee3e37ef818b9826743266c078c01c36fd62b1d17adf33467d9c1ca9f2ca28a2867bf7a8084daaed0a19d2d40a0979198135c229720205763401045879ed65b09825012e626a24118cee00216930d44a9bca32bc74a6683a8d1bae1701b189bcd8feba2da42cc3b572151e7243712789b2801043196bd8c15d972cf7674771dc55e74931fc0a55c434497a517c99ca3276d262ffd83cf66d87600d097b1ab5dd8dca86de94080da8c2aea980b3a1115b847786aa96b94ac818148e3e4c7fec633cbc6bd3104ccb216074a5b2a8c757a455ab38e1333435c3c30d94d8e922e8e77c0260b6128865bc37b82c7a6a276040edadcac335a10b569a2cc53a93b6729728b84b74b01d502b830330000aa1ccc9c4d7e7a74ed218d47ca60016411d7369248a261d6b6240d5b15d2fa5b3229373484c8d23bc8e78830062959d0504c92c0bac310967ec40af0c2902f82742efa78f57b70bcf54a73aa2aa93b0fb34a935dc5924977caceba57afdbbfa69942623536f167830685bf481740e2f434a2d3ad107711aa1729ccf857a14b0002f61575365f3ad9c18b947bbe9b3e31a7571a918728479710d64dabd569873461e12a9dc1103ba28028e001c8d5a79d24d30756cbb4a3ac9e48435ba09286ae89ac3c841e8909a4d94226a822c90b5a40f239cb0e8b98e86b5b06e20dd3764e42e8c8095052b1f66b76f164b3b867a98cb299e0995d44b5febc7a1f2c0cb2d0cd4f3ac5f9d5444797941666afd319a3c6713ed1e31338a41a6e2b548208cff5671a6fc7ab5df260c2d8a703a67eafa381c9d576c6c2b1177b6a66d951bd3c426fa79cc7b552ece197c92856b2c7064605079404a3b5d8b49afb9c87ea48e0811a61e81e2f101ca25a6a599947341040e381a52cec894dc9b6ad25b79dc903c35c450201071dba35ef8c11e17a1ae5ec7e13468c148a5946d928ed0321d717640e5a5767942ef2275e05e395321052e3e5059af77fb04271c2e511f450be168aba09d3b9eee1288ed1baef69ced005797982316e2c731f9581cd455300f35a6e1a5872552ac6eb68ccacaf636cc713516c275823e4a1a30a722f8c46a8932550db624dbb8b6e0bb51c3d54089fcc2042f38f5cb5988e56a1f42a65d5d788e2551f60487490b57904127433f685ad4bc53d6213cdf52d6b0991ae37882d37b5dc084e5a49bef660a4e8d03e24ac93e58bc05f8a759895074e156c09e73e6782c00a6cc80cd04829d270c7848d89bb2c321ac6e76b3e8715923768a8b1a644cfa95b890850819767249c48a08314b29c81e31b63a008a51d283bc217adefe37d2d9b15c7257cf62a68751c2942c531bb55abfa321c581822c90c243d94b598fbb958e5950fd4c8b1f1cd06bacc30828fbf73a83f7387ca252e4f9805419c02d63189ee7b4661b5c1bd398ec82cc8da173ede64a38b3c1ed53a64db130564d2a54600bac8017d46507b3d56208975a70351a558d5774b249f7d634e6f21102310b6bf8c1544e217c68768400c3d721ba5c0f77b9d20795c8059145956ac7b7728222853a3c325d070a9eb256775c727118eb9cb7134748ccfd09f32c930881826d8e20af48b2e1ba10efc67ce0ee7730093a7305403eec951f59044a5f7317cb85caaaa2e2b5b90ab2b805a808c1be755f9a4c342a96e8ae83cc4394d73890f13bba0d35c45393730e4118d5345006ae62d38445666cbb7c25823c59a9d62e08bb8c7cd22b331be153af7c359091081fac67d96384100f44951422e83599763ab739fbb8ba2a064a41cbe1679a1c613815e9a51d5d6251ee73431cbad479cadeb64ac94f92a38d0798a4b6d3ef7233572b68d2a12d125a6d4e27939f341a4810f0c07bfaf993f8a74bf8e9710e7b29389ec3dfc498a4ff1839a1268db8b70e82670e689b5b3e333908b6e8b4a78fec249e798bf57b7ce985a42a5269435c81ba441230ea52319550476c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd7944e5d79dabf7b7259df5ced02669c81b7dc4590e0b10764729d812f6bd85d74f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +expected_public_key = 8eb8491c75171340b7774793b7912bb4186a7e3837e33414af6aa211061f3831c4f4b16b753228e998a721385d7b14211d8a7096c54ac3101dda7668013cc1555163f822b1cc144e240c284dc87b5075a813872511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e39298872552f8bc4b0df1632255588ee99b4bd373a21c665574bcd3fbb35690237a6cc691f80523390485447be94b76fc219e7d75c6649ccbeb00271fdc1d666351f396c08eac20ecfa784d45bd4d64847ea126d9f0a23a3b1727396f299951f95a68efe55c5d4c792e136148aa35d0663d64f2c040586e44b6cdf60c54e0c08f365001513694e27569a3d6c6ed2538937a7afaa0bc2ceb6b18914ac77c65922ac49e47c74447b889a39344db09dcf1bd73ec5c48263c214a1e946b2cb806668a32b83c0c97ad547989836a53f1025348ac068a69357c7f46c69f963c5634908b9963bdea79689b9679223824faaa920439356c10786a646472372be8729c4f2ba1e2897728cbab136757ac5a75242608d6d10e20aa6446a4800eeb621ea822c1a61eb7c5b84e764d83452f60e5bbe79b275c4a4445715d21ecae5a569073475a74ba62383137974bc071c27cceb5bdcb1991d393784ea8b28f259b118089b4b77f9b68ab0ca953ff8257a3938482313f4c5963c4b101eb0321d608c2f3127cf451764e15636eeba98021c963f359d2c44a9e92357f2853821ba0c8105c488b242d9c02ae637b2002ce644132069a8babe23d4e9a056fa0b8be8095113b86e6b5c748706924f6aec490a46dd398444499b95289f13a84868188fcebb861a004254068f6d9b4b83aa81c9b5433c70868ab5364a80d870b841a216506663aae569b025c5cc43b2e5a6821fc300eb6574d0088bbfb7483959892703666da17797dba514a489376b19707a144b6f80423073efc608347ba2e639b0c8f2a52ac959592b0b0c1a5b4fba61483f225344051dcfc4ec124a9d10cc2c557339325c699f091319853ef7a445b4064d8e66895f8c0bc887786f5240b72c319fc0b55933b5864063d14c5f732472c71340ea26bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa110e2cfa9ea61287716f199af376b106fb097760b3f11237fced41eb95b798f2787b3039f9c213ca5699aabfb03af86adf5d52d6aaa1ea952bc04725a22b2a28f4006cac30e265c793018145573cd1c715a69d704217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbecbf25804a210daac80612972acf605e91303a2d59b1ac84ee217872bab85cddba9c6d1381e312b4c574097d95b8afb595bd91c46fc0df0a761f596569f99b7bc6505e922a1f90c045493cdfb9a3c650224bdcc26ca199849128945ca5f97e230d601283aba102a26818932004bb114879139ebd637ea035c20c3ae176b70999c3ffcb7951742c73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab4d07bd6921cbd95c18ac60e7ed35aaa352e143aa1fc49630cfc8a09845cffe260ad953b71074e42f08e265b7473db4d178c269f317ac035cc1124540a4a47886b6e5b04418a760777e73aacf8930f08c2ff10815559c1e04672bf4b851233011d7b3a84155d76279f9778a72ac9803d36506824a34524c835222224545deae1aaaf193b778751889957d5082a9e9a34e6e44840cb7ddd712ce9313c5033590e9ab54c25852aa8b2f09252bed793bf6b972b593ca9317ba278937a607c6b9b8f79069fbe452fddf01622465006373e2f661e366a90ad1483fdf76e04c388d61646f0162195d36966d75dcc89a3d96b2f98c79d9e0babd9816aa2084611ebb558735c076576e102b3857c1eb2876d53c5777f146876e55020641072010e7a1b773d357d81b52b4071b9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e768295192ac02bbc0acb70de25a27b724ae7d3121b1a4a869034e70f279c3914d882422e1785709599df782bae64316aca97d42846a52d03eaf423e813cbb3fc26c0e1134ddfaaa3275226f6416d9788ba2026c78e2bb1850c681825774213628a23494db886aa29892ec194791a84c73b36fd5cbb2b4bdd3d664ab10246cbc9bbdc97d8ea5528ca41924e240e544a747071caca25b05051587173c9fc851edf10fd0171c69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_private_key = ed55584416844e1cb3c75acfb3771013d1aaf1fb3ca8a5b718a8ce02a15ae26bacc7534f8b084a665b0608780e532a161686b07faa83884c6a0efb490a8a3fcabb50add21f58ac43ef4355246b1a661c5937562fa6067e7aa66978e4b36ea1431ed41e4e4282d4003d5bbc06cdf7af225b6560c44f43a278677abba8c6b79741b3ce7c0d0769ab407c9b39c032f0e42d1866addf2115e2f3336384c61ce9319cc92ac1350b264cbc4059b94372631c8241ca376aa6f76111537018c01d1346019d628f1f00cdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc957716373460a7a94151cc548f0c78aa5a323581c192d00b4d96219806a04b1a0ac829002b7fcbc8cbf8a8e3abafd3dc2164d03a24c19d50133e967c7668aa8b81977b400067fad2ca802a76716b95e3d28be5603e4977c33d3ba5df2446f6265827464641204ed972286b58567ba129bec0cd6f1644c4032edd6239309aaa259a3d997b1ecc535f17d773ab1c5350e3c82c600175269700a56b0d4211dd02c13d4bc7c54238f40163441702613a1de34ba9b0b42ef0a29300098667e8003588577e64b031139dd2180db113623fc4b74e946eef86a1a6bb52764c6c12911765e37a685400888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2e818ae3b7480f500fb6bb03bd50019c33bd37b060bc2c45e8a2267d18927c0af66076619889ff6b1769fe59e5f131f5fe40db2815bb6886b7bca9da659935db493ded9a808157e4151b04c153e673333424b7aa939559e4ca973f7644a813b8d9c1db8c87cac6365c0e008e329403c69490976cd3f006f3138114a6b3e6b3c4f054451e5bbcb7d232f285a2ef5202b81740053512f8e4b33fda87ea61042d1f9736ed58e9047c8744735a728b636dba7abc33b2de0b1572a28b23c25a8668cef9291990a499bc8935f955e1cf0301a65be870b7f01f06099192431f3436aa5aa6564c4689c1d2e11540355138c91ba6e0182b6daba0e7a177ff320c6b04977d47da0d51672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca611893044460495d8a46b242201886cb52e38d91d25d7fa8262290628d91323dd2a51f8c7a33487232f4934133117699028381751d8594fd94910ee4115389c57262ba579220567a7b5b42441a641fd6630d7bc06802878c76bb9ea576965ee45acb90ba549a01b6e873a1d8c741662067a116e64c8897e83204170c9bf2676ef60c20f3450804c7a1b80725da17f9db18f715b7894ccbb53321cf01755d168d19a96356ec07efc62d9a8c3a8ffb15500433f915137ac42a474b8e43f283bdb2b46cd62d509a5aee8cbe23b74cd48079d82293bfc9cd931289a0aa27d8a930beb2000acc2019e3cce107a18e9c4408c516fbe19e45459ed77231851b88b6b73156ec820a4c097072c2fd61c83d23413ad510662894daeb238992138f98185042b53a637aefa83378b026fa7bc314516b25d343f0e0aa7772cd2da27f8b39a8becb44923792a7d586631b2ab963ae537768e45961f5f96cb42320e75738a964168b9403d5b3591ac5679a61857c818b2a486bb299019c7b03beb50d2d40a17e84712aac01895ac6f73c0e571b779f71c4691ca515592bf6270a32c58eb9a494c1a6bee0d86581135216441a8397b5be554c000342172728f4dcb504a11e7f594d7811c21b7a477f2526d817017e5c87c6b376d95c8c6ab628110762546188f3f602359a85b422aacba4802417ba44b98fbfe05121cc2c58515cf2f3979400784f6152925a2d52d07d15a69a3e223feba90ca1b3a112947299123912b54321344ca400cfbd996d523b72a505a8f0945e00a65025015c3f9c7132d48bae4129a0f0c4e22a1509c439c011a2e1cbada30453f6110dee9c7f4b0866aa92cf5a31667ce38f8d871f9902bd5e2a2b7af030367a6306d4c48387b694c7bb2169614a746fa783619f9c7264d32feda59ec37063d1f11c6f5183f0e9be5a493e5cb199358b19f1706d80844ff2968e95a24d72dbc348a88d0ec9bbd01c3018a8147291b34ec21290211304da40c46632b352810f0a2d73046417885cee0c231a495b7db834a1336980f2b34cf140c84ac878c558cd937b7e0a9982f99b3c8abddd441b79f621764ac38eb8491c75171340b7774793b7912bb4186a7e3837e33414af6aa211061f3831c4f4b16b753228e998a721385d7b14211d8a7096c54ac3101dda7668013cc1555163f822b1cc144e240c284dc87b5075a813872511097c45a87dbabcbae6e743dec482b4eb47cdd4a1e39298872552f8bc4b0df1632255588ee99b4bd373a21c665574bcd3fbb35690237a6cc691f80523390485447be94b76fc219e7d75c6649ccbeb00271fdc1d666351f396c08eac20ecfa784d45bd4d64847ea126d9f0a23a3b1727396f299951f95a68efe55c5d4c792e136148aa35d0663d64f2c040586e44b6cdf60c54e0c08f365001513694e27569a3d6c6ed2538937a7afaa0bc2ceb6b18914ac77c65922ac49e47c74447b889a39344db09dcf1bd73ec5c48263c214a1e946b2cb806668a32b83c0c97ad547989836a53f1025348ac068a69357c7f46c69f963c5634908b9963bdea79689b9679223824faaa920439356c10786a646472372be8729c4f2ba1e2897728cbab136757ac5a75242608d6d10e20aa6446a4800eeb621ea822c1a61eb7c5b84e764d83452f60e5bbe79b275c4a4445715d21ecae5a569073475a74ba62383137974bc071c27cceb5bdcb1991d393784ea8b28f259b118089b4b77f9b68ab0ca953ff8257a3938482313f4c5963c4b101eb0321d608c2f3127cf451764e15636eeba98021c963f359d2c44a9e92357f2853821ba0c8105c488b242d9c02ae637b2002ce644132069a8babe23d4e9a056fa0b8be8095113b86e6b5c748706924f6aec490a46dd398444499b95289f13a84868188fcebb861a004254068f6d9b4b83aa81c9b5433c70868ab5364a80d870b841a216506663aae569b025c5cc43b2e5a6821fc300eb6574d0088bbfb7483959892703666da17797dba514a489376b19707a144b6f80423073efc608347ba2e639b0c8f2a52ac959592b0b0c1a5b4fba61483f225344051dcfc4ec124a9d10cc2c557339325c699f091319853ef7a445b4064d8e66895f8c0bc887786f5240b72c319fc0b55933b5864063d14c5f732472c71340ea26bf8ea7db5fb9addf3c5011cb0f0d3720dea819d3aa110e2cfa9ea61287716f199af376b106fb097760b3f11237fced41eb95b798f2787b3039f9c213ca5699aabfb03af86adf5d52d6aaa1ea952bc04725a22b2a28f4006cac30e265c793018145573cd1c715a69d704217ac45d1b6e8823852da64784d4b84eaa9cb7f75121cbbecbf25804a210daac80612972acf605e91303a2d59b1ac84ee217872bab85cddba9c6d1381e312b4c574097d95b8afb595bd91c46fc0df0a761f596569f99b7bc6505e922a1f90c045493cdfb9a3c650224bdcc26ca199849128945ca5f97e230d601283aba102a26818932004bb114879139ebd637ea035c20c3ae176b70999c3ffcb7951742c73d48993287c3276c4df9a8365beacda08bb72c55634ff35c2d848ab4d07bd6921cbd95c18ac60e7ed35aaa352e143aa1fc49630cfc8a09845cffe260ad953b71074e42f08e265b7473db4d178c269f317ac035cc1124540a4a47886b6e5b04418a760777e73aacf8930f08c2ff10815559c1e04672bf4b851233011d7b3a84155d76279f9778a72ac9803d36506824a34524c835222224545deae1aaaf193b778751889957d5082a9e9a34e6e44840cb7ddd712ce9313c5033590e9ab54c25852aa8b2f09252bed793bf6b972b593ca9317ba278937a607c6b9b8f79069fbe452fddf01622465006373e2f661e366a90ad1483fdf76e04c388d61646f0162195d36966d75dcc89a3d96b2f98c79d9e0babd9816aa2084611ebb558735c076576e102b3857c1eb2876d53c5777f146876e55020641072010e7a1b773d357d81b52b4071b9ba8c8f69683181ccc4ac49bd2083bbaef7ca0beacec46a39e768295192ac02bbc0acb70de25a27b724ae7d3121b1a4a869034e70f279c3914d882422e1785709599df782bae64316aca97d42846a52d03eaf423e813cbb3fc26c0e1134ddfaaa3275226f6416d9788ba2026c78e2bb1850c681825774213628a23494db886aa29892ec194791a84c73b36fd5cbb2b4bdd3d664ab10246cbc9bbdc97d8ea5528ca41924e240e544a747071caca25b05051587173c9fc851edf10fd0171c69c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c692176b38737a053dce0551b63e3eca81884bbf95e1d8975671a2f7f1dfae2511c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +expected_public_key = 85e9a58ffc4aacb3c476327b705515c6f1980b53b3654720296742b3a793258138d86728f4846ff1030f6f604d092847f011cd59165b9dcb400a8723ab79bd137566d709a5a7f62cc7a7948331920f75530c915b1bb086e422145dd74ea1b557f68b511ff8a1ec0a39845c0aa94c2bc05922e3cc52c7f59eabcac2d36b5535eb0d7737768d6322023a2ed2fb0128c2724442c794d794f302b89fe8b1a3e8326253362fc44bce193fe7725d1864acb29bcaf2c0bab9423dc593733bd99c077534cdda88f4bc2fd846b810ba71d2139fe1f50ace7821fcc5c9ad7c20baa4a430b8085441cdabf16251f8b686359c755981ec4c8fc834cf7f019e599051afa87584f2c41ce13aa9babab5aa20204974a10bc36d4aa1c7706a3838b8dfccb1fe16038d78aa78eb3594998a20c72337405e2f36683a01b87199764b533077688a9a755c2c38632cfa4c2047663e860a2998937703ba0f1780ff367918eb208b917cbd340b69577806e282401767c258b38b0c6b21a057f42b59a6dcb2eab48063116fd2b1ab64c0a864326e8683cb63e053fc03a5f6d6b58f0820f500ab1d78504dd80991e68fa6f91658fbc64c594d32a507be17b465684df8e65bd5745fa8d6512d382785ecb9b207746686aab683b0cfac43d07a0113317cc895a513776611b981f05bbf7e1bbf867923992441176135b394c6dedc8d64ea47971994cfb46bb7692f47e1b372994f3ef19a282799ca530ac7b82fca207537865ee0f4c73b0a0a84e1b2d2b058175780a287ba9a435a0fdc24fdf48ef579b55ce1b55531019060193fc5cbf013a8bf521c1f459afb125c78d2377722824736ce01901a16a54652d064e9058f918b5552936dbc77136b009b2108862f962244597386a2b078c6b46308436144b75b9926133a46ce1c44ca7b5f52a678463191d51953a516a1c937101fd236c962a8dcbb671bb1be92035910eb0b40d8672317aaabcb04bd8b716f104c3eb49c1e5bcba7e17d15861671950056e5278b845afd6cbcce9b2119d86fa1fa067f1c69bfcc7e693020cce979869588337aadd7d6ac7ac3ac67a3034a035a12750dc30c99c8692b9cd74ee2918a23248a3a6875e25bbce8c6902cfc81ae878fa4ba1df57523d3013fa79a9ab08894004042cfc00b0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b04034791ce31490459733ff1c7752864389ce3bcb826608f966342147d6a3626c4ab842480b571a9487bd8785c37a7ed10c8cada99aad1a19b144accc2be8a17be87111093189efc951d08799b5dc46e46e571b370b74e881326da687ea02e1088c400067ee3d885c0db3fbcb336416c74398132090971e2aa1fa9f6ca7ad186bd4c139be57665595337687742b1aec0da12922783c6aba7fed24d18d142392b26b3650731c07a15a987455986252b8234123e3a4a54c08b599f1948d1383183992e2cd17d3312cd9b3cb4149ac98ebc054f17cc516c67d8b26517316143c6640eab5134f41d6987c25454ca62070c985b2e0eeb24e05870667627ce5282f95635be4034d90232e997c18409b1d4991b7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54b9328cc492842238ccb6b652da6c037ac6afdae2be4b894dd66a70b5840f20fc18bbaac111486b9558137269732f2924ee050242329c0d1583bf890847b30d5921198814420b60475ce0047d973269424c54bc9e3b4c94633c1418db9a03a62f6cc224c59074809b9e023a5aca5757d3a789062bc3067698a5f216fb2c7355609a99aacb81b99087a087ed64cbc462301754931048999a2b9b0e06c9f251bc41b39092201ca3a727b5e498e4db782dd53846c7635ac12f6e89c30480bac297188338a58f338d6b7075003278cce876bbe18cdb00326e44745a4009209b04fa53ca742438336ac4f9cc337b1636898170a1d97c58661415dba67935162636a87f01bb87b66865d415360220edf89d0514663dd73a951070f68653b9c2b637259a395c500565b6b5a05b3f6555fb249946c9904ab40256d63b1d6c2344f80dbaa5b1be7b10299a7ddad03781983f8eccace5c85f3c3bb3a9d61c040141757a2e881c33a9784e48293374ca497cb59e12c07a4b6b420d3094400b24cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_private_key = ffd8874d8b37c946409d69cb03529b7d1a43ddb24792d4773cc723643567671b8e0fc2b903d302679a530118ac453b0541a2389c46b38f317b43130972271d8146a66593b8fe659db570c941f1abb4f295493085a85277062c3d4db168e466015ea506b5b8a805a435ef6812a6b68afa9372776717c1042e24e7a10a842182e7c40c4cc547b98fe007a1d98804ac5bc3c31b6511425a558c73e5b1935c7a664ee224955b6d67ca54d47b04e1622716a27b21f12a2eb27c16d26a541cb0c1ba5a1a8629b7f2222b84cdfed9cb6f666b41c92fd0b074f42b5d2ee72e8c5443f34c5dc2920da165558af074e3ccae84c1cbf1f70624e1a3a30a7db045a2c4a79bb1a4b0f01187bbd8b29a8c60b07068a72264d9b305b5e391521bb945d53ce1d65436441932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542cd626637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356146c04bb8391197d54d0f4202f160824d900b27b36bf8abc7876ca331c2c3a8a161d98523adfc1ef9d538c9203a6729cfcf6089f7d72f57093ea3a34113749f23ec21c051ab2c836679b0210a549f2678c7187691de949994a25769d4647fd992be411e24e302c07569cf26c11f3942ca505391a794d42c77da0a324b05908aeb9c70b88b38a95f371b1902e06d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab967770465a056de9c4420662c046aa8ca32093ae23abd80406fe60bdcd1725daab0e50931c575a0c9137fa61442b1101b05686d398a6fdc0bbbbb25a073e99c3702b9268ca91420a1198b5c54501a03c878b6827e6d586ab42c2fa47258d1255711654968fc80e1364886f18e98fc10eb85645b399788dc225b1a233fe564604a86397a4483c102203188df667961bac9ef19b99432475c0a2c9978c81cf5314a2b2ab37479549b14c8d70ed8f0c6625938ca4a92bee5a7aadb286e507ee8890772c3353e35c2de8696041bcc8b81997f8c7800417c91c32e9b8b34b62a25e5c2af2854cf902269c3c5b50a5209dc1c63f8835b3a73137d855c69f9335fc66efb985933f4a66b084aa58909e658998a15ae8b087120f59a00426cf9a327dd48467f8c12cfbaacea7bca7407060c42950cf9543cac1edf9c296d978a2c36aad92b665d6c9513b59278ac1cc781204e555e27f81e976a74d3055a48035203472960e596c7c4c2d0158a006d884f40681c6610f1124574eb9ff5323e10480d0e306f1e398ad1e6cf8057024d072def4719e3a6be9aeaa07b56077be495a635c67066a2945376c9836ebf4c413a05a9b1348c31329884bc7d820a6bad7a63bd62518878a97fb525332433573973df74a00ec02d50198a2b1306005335e6a51191505fb244999cc333bcfa4e7845b766b050cf66607982014d28548a4454f86a06e9321c82781478cb938c709ec5cc81ea1a9269543dc8ebc6d253be1698990c81c587d7263e7445baf53316c23eb8863d151a4e5659928ad704c1c7b2bd2a1987907a05ccbd2f0c78232a10653452e3dabb7598ca83d37166791ef11a2524f371180984bf72a6e2291301606b7351a284a1a66866044f6088ba91217305bcf24c759bc348e75325aa7cb4c6b41077979a2b02b137966016868a66b1780ba90bc7d089b97c6bae2963a2ea3bc2072ea1841da115b83139401a9416db7c8722306d3a81bfb4d1cb5d964f04534f7f79c6de1789cd6767e1f6930c88b69b168cc6574e84c9c282f257d2200be0874392e12c57e6c989d8320b1c1135f88c97d824ebc82478cb4962ea409dfab7b61c1091b15072c18bc46838dba3c1f6aa00eba64545aba2d0ac9f44d3a2de976f62b8aba4396106f031adc4020d46c78d94350dc0ceb844af1bac32d1c27cd3e93c6d279cfd3c0d20255b8f11533dd387207c8a8a4c8fd51472fe21350f274a375a81aca592ad450091ab07facc360e528f7a6a6e41265d45f513a260605a2595a22c3ab5e8396fa033dd443da518c44a869218052a3fe06a20451ee4aca7928c521df980d73b2b7431ba37f485fc29b2974c1de5bb80d40708c5f869cefb8d24a56c72ba04892078a963753c105f088c8c326c1f82b3b246a75397d47435151fd314b9e5284385e9a58ffc4aacb3c476327b705515c6f1980b53b3654720296742b3a793258138d86728f4846ff1030f6f604d092847f011cd59165b9dcb400a8723ab79bd137566d709a5a7f62cc7a7948331920f75530c915b1bb086e422145dd74ea1b557f68b511ff8a1ec0a39845c0aa94c2bc05922e3cc52c7f59eabcac2d36b5535eb0d7737768d6322023a2ed2fb0128c2724442c794d794f302b89fe8b1a3e8326253362fc44bce193fe7725d1864acb29bcaf2c0bab9423dc593733bd99c077534cdda88f4bc2fd846b810ba71d2139fe1f50ace7821fcc5c9ad7c20baa4a430b8085441cdabf16251f8b686359c755981ec4c8fc834cf7f019e599051afa87584f2c41ce13aa9babab5aa20204974a10bc36d4aa1c7706a3838b8dfccb1fe16038d78aa78eb3594998a20c72337405e2f36683a01b87199764b533077688a9a755c2c38632cfa4c2047663e860a2998937703ba0f1780ff367918eb208b917cbd340b69577806e282401767c258b38b0c6b21a057f42b59a6dcb2eab48063116fd2b1ab64c0a864326e8683cb63e053fc03a5f6d6b58f0820f500ab1d78504dd80991e68fa6f91658fbc64c594d32a507be17b465684df8e65bd5745fa8d6512d382785ecb9b207746686aab683b0cfac43d07a0113317cc895a513776611b981f05bbf7e1bbf867923992441176135b394c6dedc8d64ea47971994cfb46bb7692f47e1b372994f3ef19a282799ca530ac7b82fca207537865ee0f4c73b0a0a84e1b2d2b058175780a287ba9a435a0fdc24fdf48ef579b55ce1b55531019060193fc5cbf013a8bf521c1f459afb125c78d2377722824736ce01901a16a54652d064e9058f918b5552936dbc77136b009b2108862f962244597386a2b078c6b46308436144b75b9926133a46ce1c44ca7b5f52a678463191d51953a516a1c937101fd236c962a8dcbb671bb1be92035910eb0b40d8672317aaabcb04bd8b716f104c3eb49c1e5bcba7e17d15861671950056e5278b845afd6cbcce9b2119d86fa1fa067f1c69bfcc7e693020cce979869588337aadd7d6ac7ac3ac67a3034a035a12750dc30c99c8692b9cd74ee2918a23248a3a6875e25bbce8c6902cfc81ae878fa4ba1df57523d3013fa79a9ab08894004042cfc00b0665bb894772e648caebec8779a8ce0a38b05043a8f3187f199a56e2143845246810c33b9b04034791ce31490459733ff1c7752864389ce3bcb826608f966342147d6a3626c4ab842480b571a9487bd8785c37a7ed10c8cada99aad1a19b144accc2be8a17be87111093189efc951d08799b5dc46e46e571b370b74e881326da687ea02e1088c400067ee3d885c0db3fbcb336416c74398132090971e2aa1fa9f6ca7ad186bd4c139be57665595337687742b1aec0da12922783c6aba7fed24d18d142392b26b3650731c07a15a987455986252b8234123e3a4a54c08b599f1948d1383183992e2cd17d3312cd9b3cb4149ac98ebc054f17cc516c67d8b26517316143c6640eab5134f41d6987c25454ca62070c985b2e0eeb24e05870667627ce5282f95635be4034d90232e997c18409b1d4991b7f05926e5aa6cf67b5fd569fbfa9493fb3379d1b6dd14c54b9328cc492842238ccb6b652da6c037ac6afdae2be4b894dd66a70b5840f20fc18bbaac111486b9558137269732f2924ee050242329c0d1583bf890847b30d5921198814420b60475ce0047d973269424c54bc9e3b4c94633c1418db9a03a62f6cc224c59074809b9e023a5aca5757d3a789062bc3067698a5f216fb2c7355609a99aacb81b99087a087ed64cbc462301754931048999a2b9b0e06c9f251bc41b39092201ca3a727b5e498e4db782dd53846c7635ac12f6e89c30480bac297188338a58f338d6b7075003278cce876bbe18cdb00326e44745a4009209b04fa53ca742438336ac4f9cc337b1636898170a1d97c58661415dba67935162636a87f01bb87b66865d415360220edf89d0514663dd73a951070f68653b9c2b637259a395c500565b6b5a05b3f6555fb249946c9904ab40256d63b1d6c2344f80dbaa5b1be7b10299a7ddad03781983f8eccace5c85f3c3bb3a9d61c040141757a2e881c33a9784e48293374ca497cb59e12c07a4b6b420d3094400b24cb49a9bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff2f54bedb19919171eca777186dd743b11ec9489aea09534c157faa75adf1c77c6590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = 89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +expected_public_key = 16e63cac8b2dd05a60cc593000322c9c566b472b375e8484843aac71e74bf0315af59a8a4f6104a43159e198716e239247204753f629c5202c7812c9ae2351d88b4256e7a82b42b15e54412e0130d5e25388240fc05b253e7b0c94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e67766301b386b088f71922ca370916319d8f099f263caac7d7c0f81959c4b13a0da0b5c269760036a552016f8b591f6b37177cfac940f706c975a59da7c04fc7210ae32508c28204ea204073c73b474d74b54cec08bd14361b144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613c917393761efe2c2e4dc73d4998a1cfd6a2ff278b6f68b1f108151b857ee913b3568171bdf1502953b81fb085650bd027c4b66a8276319201ac328604100ca4f684f2fc65f220cac1db9c434a218814a14cb630b5b18410e11c37c92b31600e37c8bf12c895b1f315f0da01cab250881966d3c8256f5513cfd68e383bb8ae248e27f3b479f7a82da2aa564b121586bade1ab522776b49a02a16e3a798acb005d70d3ff24a8ca3458a826788aa09889293e4d862572907111071f0d58d679a0c620155ffca45bf03a1778941d41776ea11cf3ee899912c703d50c8e88ac447b2bb0a0cc3bfd83ef3261ca592915bfcad6cd26409472e4be62ebfd65f003c59d39b7f9f710f6a76a1e8291c834323f145aa3b8a9e2e4c2e98621074c49fd0716d3d61a2787a0598e8096ae05fcd7aa4250a7ac4a5314c842b8dc8b563c6b8f626763d865c141474c72c1439ba7012661985a061ced9679ac94983957dc99c4bd4061ea43c893bb707c0f633787c1b11d8622dc08c47954ea907ac1513aa3c4420dc48366e4045c79cbfc3b52415324e8c6669e52c2c16b1722ddc7d521558180781898a2e681a55693398ba712712b9c515d72255453a3c4212bb7b3692b3998d1bc6781ca28fea483c276a92c219a62797a88702b2587005208512aab304799a99acaacedb1699993150b41aa3291423bccb6dfa31a7b42be4997581b9aa54716cd5d62cb1b9bea0e8165eab6a6300242bb5a711f36e9a43b12e24492ab95218e084e1d2976a222024263e4c87cb93cc4fe556812096686ac72152f1a8a12b93c6530d08c99b9be3634dab9c93d27f2a4099304b4c61a4bf0fd9cb28803d0824c5058a515dc69c81228687376865852fe9daa07e45a889e650e0c58fc2cb71846b5296e76d71105e87ab2714b2b82e06342218822642acea28700486709c43b2fc421eeda5070ccc8ad1367cf2834e88eb8ff8d2059f455c2da34843418cd3449497b753c92826c3174e5e304437c04c7f518fa2eab149762c916b1c6a676a8d5b3bff02b8ea9a366f1706be888fbc40285d6cbb924249ce963646595573b5a5d0079fb9b0275ff031797899ae0bccb3ecc32eb48ba3769bd5e56667cc02723c773ba00924a961102225f2b88ecef333302077c2c761f48991755a83e09b7c3406bc8784031754bbab6b49c361c93f5ab9778b39b9cb66501b63d8859af0a00bbed32947b92f49961c5fc38bafc9b0a763802c9709fad39f040c6736a4c45a110a08822e26d93bc6ccb566a687ddb786f5d31378505f5d575746c3cbfff55899c933f0052e1155b776b9201f0272bcf67c3fd26868bcc42b2b9361562bec56ce1991ac7347b6bd500065e990b257bf20e1537988a560dc21aa652e3bc8650d80870a1a4190014fd1c43229043bc1068a5fa074fb5087581a932ddb5923730ba05216895ba1e67947c71aad452861371a542325607a7752b8485c48fa9ce930793130996bc63d1b162517c34449f5263077a41f576150d8b062718e493242f57041f2da6f271c0c5ba3a00a8c8faa0aa9fd61073dd70adb7991df8a143e797a9cf6b0cf257ceb347dff45cbf6db25d5928074b3a6ed918fd35895bc7b93682897c0d322d46755962928f3390664499a14dcc025b1c0780858db32826679a923e20ff56755a26604a2c8606fd7087218232cdc3b488423fa9328f9eca8eaca9fb4311777592157b46e4476c885581f6ca524ad1cbf663a0591a7679e515de5b65cea3a0971c9139019735d421a25f7126a9bb66f67c177f3873bc5a8a7c06026913a631b1b370aaa17019a7cdcbc22a24f9e38a69637928788bed0560a235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_private_key = d32cbc1116ac88219f9af2c33beb59bb94b372f97815278f0fab2c690c94b8f209dd1575bd7c0bc7f48aa133bfa068cf1af1612c3325b8d08963bbc66d938f46843fee424357e535c2259ed958a75ca6203286190be53a9b46373f8b41cb38c1cae2bcb91898669a872f1a8d9cd21227e42ed655569202cc6b494cc6a6bdb08731cde417f48b86554ccaf953b8fb70aec727085510cdbaa7cd2a0ba853928886332fb1e3a419c49b34ec90fd31b716252acce7a79d05cc04074d69ab3cc9809102261a2191a086231dc70aa583e86912e5beb2c1a22e841f39db531d5c26cc333834a20480d6b1ccf19a654149045791d33b414696375dc3c7b0644626e8822c5325d52ba764f2361d853d244416cb9a5bc0540e1238ccb53438c90a196a45571f743894f060f6031fd623abebb4afea05190dd9452c981352a78e09579f05e24db2033aacfb10d9335986e8542d9480bf5603fa932d2d0878c3753e6524a809324ad6f169d7fb6d9c0264423a632996abf297707d8412a6b86160b69980e18add1c372faa406f540c00ed0a75c3544811759c3b5026e6c19102b7160883ed002de5807b5933934fa01559c4a790230ee93c215bd75aff117d0f170b4feb7aef5b007aca616e688161fc00cb037c8232cf2dca569f01a2e1dc2af7ecb6111181f2ebcb1df27c6ea84251d8a2b6b6582ef915e2b8c7f8fb6be8844478fc570b8054a067b34120b47fc6ac68125cca8514db4540b7796c9fd05523e7014db34b8ec94d5eb66c9f5cae2f838191d2234f43c72262a18deba17ab495b7f0529d89b8e1e407bd5a185eaa2444d20c6c9566526b8707b13bb0cc8d9589773db90952a5cd78e43bdc68cfa4401d7912618f456eb4f97ac1b49ab948592976233f962b1916531fd1672bb69be320a2985b38b80279572488c5f86bf3d55fb9fb90449b66fc874b94292000466786fb7e393765c7057051999711d234b4d277419320e0046ec0925b41d6b89c62133bd2734e296dcfe90bf6344219a6a22d2cb50c75bc02b07fd0da11fe0a0a0b9aad76001d5d7c8fede065dde87d5d47821e756a926638395883879a91b94c6164a40895476269917caeb12944dc956174b6cc5154944571a6f6553f604d3212728fb08af6e8c0ea00265ac0c5464595b31a9131871d79298867aab426d009480c0befc08ace14991399079cb62de9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e63c162ec911101c5a49b35475ae68634a7b0cefccfbee608cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687c92cda9ac9c03a9333a866a9639803c76b5b189294a269f389abb5010789d410b88215c554008cb10274f781ed6b0be3903576cd16934c4b6b65296c477aa174043f06792f3944efd0206e34042d827caffd2989b936b91694825c4bd8b10c0777b11971cc1efb93ec1b3674afb4fd07568ffe89c707b5785c140d51b433b7942d88a6ef9bc9d091472833004005aa803a050ce03b2bb551f62fb1fac6649d3e14f0141b2eaca73b700489b73a8d840834a7802a96864610b10ef5a030a6670a866b02e13c3fd48056c092b241513f1d498539b1d68f498cb049c99d33c32e1b491997697a0b6af529e63a85a0a7b8ed6c005d61963fc5acd1e609af8160d6f823063385065640452815aac2463ab8524e2713e3f584fd475a23e46bf79b97f83403fca999c1ceac629f47261e499e211051c7059e4aa14c2c4649e398add5b2ca1d070386b4f9c284f84c930610a3b22936090f3c03fe7a25ef323f2c326b3a7c9a7a5ceeb395cef08ca8009a810986f33164054b26bfa61489b38ac81390bc6ca863455c22b589e8a4bb5ba87aa0ae03fdb611b7f364387363e728a6de48aa47af676e73ab655396711e64777b27fe45474c3f29495939704d34e24661ca43aa94b71ceb2d3c008b135a7115762997879c2391cacadfa092779308080a1459b09ab16e411157abc386a0e8e322cae09a60fa290a91419d47513788980ed60a40bd86e6cb30481c65a853a188442004c93421c799402e639dfa3c73f9b227c64c0f8c17d4723a06c73a9ad02ad2571587058513122012df86d16e63cac8b2dd05a60cc593000322c9c566b472b375e8484843aac71e74bf0315af59a8a4f6104a43159e198716e239247204753f629c5202c7812c9ae2351d88b4256e7a82b42b15e54412e0130d5e25388240fc05b253e7b0c94a43c7e96728ed78522e688ec2691b70943b8cbbddf19873e67766301b386b088f71922ca370916319d8f099f263caac7d7c0f81959c4b13a0da0b5c269760036a552016f8b591f6b37177cfac940f706c975a59da7c04fc7210ae32508c28204ea204073c73b474d74b54cec08bd14361b144c481fa8561b6c73aeeb7cb0a65be0965b2176705949613c917393761efe2c2e4dc73d4998a1cfd6a2ff278b6f68b1f108151b857ee913b3568171bdf1502953b81fb085650bd027c4b66a8276319201ac328604100ca4f684f2fc65f220cac1db9c434a218814a14cb630b5b18410e11c37c92b31600e37c8bf12c895b1f315f0da01cab250881966d3c8256f5513cfd68e383bb8ae248e27f3b479f7a82da2aa564b121586bade1ab522776b49a02a16e3a798acb005d70d3ff24a8ca3458a826788aa09889293e4d862572907111071f0d58d679a0c620155ffca45bf03a1778941d41776ea11cf3ee899912c703d50c8e88ac447b2bb0a0cc3bfd83ef3261ca592915bfcad6cd26409472e4be62ebfd65f003c59d39b7f9f710f6a76a1e8291c834323f145aa3b8a9e2e4c2e98621074c49fd0716d3d61a2787a0598e8096ae05fcd7aa4250a7ac4a5314c842b8dc8b563c6b8f626763d865c141474c72c1439ba7012661985a061ced9679ac94983957dc99c4bd4061ea43c893bb707c0f633787c1b11d8622dc08c47954ea907ac1513aa3c4420dc48366e4045c79cbfc3b52415324e8c6669e52c2c16b1722ddc7d521558180781898a2e681a55693398ba712712b9c515d72255453a3c4212bb7b3692b3998d1bc6781ca28fea483c276a92c219a62797a88702b2587005208512aab304799a99acaacedb1699993150b41aa3291423bccb6dfa31a7b42be4997581b9aa54716cd5d62cb1b9bea0e8165eab6a6300242bb5a711f36e9a43b12e24492ab95218e084e1d2976a222024263e4c87cb93cc4fe556812096686ac72152f1a8a12b93c6530d08c99b9be3634dab9c93d27f2a4099304b4c61a4bf0fd9cb28803d0824c5058a515dc69c81228687376865852fe9daa07e45a889e650e0c58fc2cb71846b5296e76d71105e87ab2714b2b82e06342218822642acea28700486709c43b2fc421eeda5070ccc8ad1367cf2834e88eb8ff8d2059f455c2da34843418cd3449497b753c92826c3174e5e304437c04c7f518fa2eab149762c916b1c6a676a8d5b3bff02b8ea9a366f1706be888fbc40285d6cbb924249ce963646595573b5a5d0079fb9b0275ff031797899ae0bccb3ecc32eb48ba3769bd5e56667cc02723c773ba00924a961102225f2b88ecef333302077c2c761f48991755a83e09b7c3406bc8784031754bbab6b49c361c93f5ab9778b39b9cb66501b63d8859af0a00bbed32947b92f49961c5fc38bafc9b0a763802c9709fad39f040c6736a4c45a110a08822e26d93bc6ccb566a687ddb786f5d31378505f5d575746c3cbfff55899c933f0052e1155b776b9201f0272bcf67c3fd26868bcc42b2b9361562bec56ce1991ac7347b6bd500065e990b257bf20e1537988a560dc21aa652e3bc8650d80870a1a4190014fd1c43229043bc1068a5fa074fb5087581a932ddb5923730ba05216895ba1e67947c71aad452861371a542325607a7752b8485c48fa9ce930793130996bc63d1b162517c34449f5263077a41f576150d8b062718e493242f57041f2da6f271c0c5ba3a00a8c8faa0aa9fd61073dd70adb7991df8a143e797a9cf6b0cf257ceb347dff45cbf6db25d5928074b3a6ed918fd35895bc7b93682897c0d322d46755962928f3390664499a14dcc025b1c0780858db32826679a923e20ff56755a26604a2c8606fd7087218232cdc3b488423fa9328f9eca8eaca9fb4311777592157b46e4476c885581f6ca524ad1cbf663a0591a7679e515de5b65cea3a0971c9139019735d421a25f7126a9bb66f67c177f3873bc5a8a7c06026913a631b1b370aaa17019a7cdcbc22a24f9e38a69637928788bed0560a235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb7a9232085a0222b9c863931ec3bdbdd51be3f16d6cab3009c138e0c8cb692563b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +expected_public_key = 8b2755c2e64d1fd9b79f5a2c7072419b955ee69a6f453b862528bc78905bcbb44ed989b5e71b9126a6a920e67a074b2960d6a3ab50128fd9ce39137b03a66968616f134bc485770e87f01304a17c70d9adbd4159d67b888862b0b6052d9e8496084ba93d197766d10f6477679ca90fefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c398341a4810c6698351f7cc4fa59c2b0a86418145743d2b850cd47f32502e00d96b0a67cb3ababf62785b11a04de252813efa36bb83001ea322490a7dc5c54f32274b01fa71d40717ff917b81fc899e28adc5c4a0c41742c7d043195cbf8393a84206ca1e87032c553b68776f9153b4e2e0a445d2937fdca7539b8a2dc497a1f338802c073e891a3f834505a82a39f54544a49921e348934a028b7c54f11b26ed1a9cc2db7c58ecae2586168b120a2cf4487a6b34b8015e64816af26b864b7b30b19022d5038f89431056153dd03169a31a18c5f6649f6b638d4c249b712bb9563e4adab4f3e83c5bd05e2617b4530161b5264ee996abd5905e025820c7e1b1bc05188adc559fd0a0177473d816a166025bb4402d7e98b7f148ad42f72920d24e024a4d7a8a9dade92ae250bea3c519ab515fa2581b1f88c4caf62d59050e4ab1512c14b581d7c012645f89a0722ad2a1c2f2639b2b11051059549417d8f3ca8ae80fc241adede55999222b05b7b7101885cdc149be41cf9d2b9137e3bd0054ca89818e84811bc21944dd19bb2c1a54251992f2a51ba93a452c290272850225e9b2489324972cb6982c338f55192b4b87c2c91cc985ac9151c638aa741a476f25b3853afb4b106830d882a1e8a26b1b1305cd045e112a7e7a723ba9b801c48358e3004ba12b347d28a571f8a6c05b7c81fb3ef2e324b1819df549abfb871e25053d3e4676c9088d277688d9f85db7fba99fc62306c0414654509a086d0247aeb60a9924a2ba77f76d669c1880c302e67b1e1e638e4f74628ba73e0c565bf7766ea68206fc779f9c55b1b48c350dd095a5566fe1a611ee9507e729142b384306527c7928a7c09a74e7c03925e87d71c45896444522a63bb6b78615003d5cf37ca7e55e82888c17f171aeb440952328ebfb9eca10396b2044ce7275ee2709e917cee9425ea4c8a95b163876a2159907003355323d56b62e243cfdc714102a345af05f4e1052f9673ef57abd43e802744316642c26809a9f07805ead090a676204cfba52f4f04715e5788a08754d23b7c5db0d7d72ad20dab9ad776d52d1954a99407eabc44174237b127c4670aee6689100ab4e9e003a4157b69151431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb783115803170c1f8b2c84d0dbb801473084aa130d5c9c99eac4e00c2355a04556a26247a73b4a7121fd2cca08168d2399a1a45b685a921b9c0aa339390068348a3a8cb55653987c691e9c86cd67c385cd580892a01d160c9e86a65bcf63a50777b353b948e70061d03154e5ea518bc687a4a6b6c83372c0d16932accfcb13525457979218041af9ba2e012f82d79fc245356aa98b11f186fd2c538cb5159cf9562b5a5344cc1c44b3703a50850358c6ab4a5fcf830bcd2b1a0c932059f2c5a43b932e32a2fe9ab9f2f3b1ace7a3c1290cce509a5aba7d50a172fe51c65bb142b54ca6113baaacd44f3eb76aaff63a474a74614a0793cbbd7a1c822292bd75b2cd9d7b579fa995b9561a2ccccc1de89e861832522412753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dab154f96a4062751e79c4aed5a1c6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dfe021c47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc18a0b6591760576c819716560159908903a32111daa1339d8a8c66081894a52465f542b011bb607177d6af34d88ea80d7247ccbc269ad67a15df94f42a22bc1a525abc7480257694e9918597a8aabd1b537b163d6dca6dfb77fdba61949e3c15015b567fb88b509b43d4665abb834263a47c5a6007e2807b267aa50e8af44452b01a62b3034ba54ba910b018c629266e26514263820fcb3390dc117f9878c0ac4b3ff899d83d922184c42990088bcb03ba65993ca46c18bf1583f5599ad549801e934b8990fbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_private_key = 818b55fa5ac30a81891f3a3643924b2b046feb6765a61cc81c9059d1f82f6a0067a102825c88a530d15f0dd95f0b4742d29abe7044c62d45a05bdac46130305e3c3417d67f60b92edeb6b2a398119ad160ee3cb0fb52144435a5bb5412c0512dc6121bf6e72d0f87a3834ab5338196fdc950a3cb1b7354c4e50369bd4364cee9066a221dfcd580f1b914c0c335f547748bb19264b7879f206a9c610573b8676bd0bdfd777a2a0ca5ec891a1317c5289784de114e84c53b983778bf8933805256c9a9bd05a11af8f5ac271ac3f1e635eb9a8263c855bb230f58ea3b7e8287d76258aa57646b97560e593944c4cb3567a2c382a795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b50722a144737ea38b14be51c41cc55c53340ed158ab4a0b0f0a2612962b89cc2aa8b29198f2e04b0f0cb586f271c6414f31a71a45eccda8c597c38415d262571bf0a7bfa17115e0c7731c70c2d01c492c85de16c511102c5a96973c724f3b58b504eb65f56116aa7779b76b2554736d9d6176dfc6ba007a590a311d4b86a7a6251fffe6086ab3319db48c4dcb91fe680f45a9480241242e4ac9861b62860837cc813fadf00751c8021f7a1c4d7a1e5f13bc3e8462f372cd7498197d172eff98b1f8bbc37974b025295a80e3525d282fba8467f8079d78fa6068e23bdbb3349a31506e474ea228c3927a554d7747bd3621a0343cb155bc786075c3015c3692c0fc65b194a12152a14153a03d5147b0cdb423a3b50ed6461813f9ae1fd63ab7a53031dac2d0f87cacd1cb81461c8c08bf367c4ccae7626343469d417acc705546293498035195240387fb1f2e7c005de000e530b9e21cc7dbe463e7d24adeac1127026843b87cf6fc1bb94674399b0636506b1acab72f623adef866f883762b5b4509cbb2be142c5c550046e10d29fa431f9b7d977253928a8d2d4c33add899ad736b40cb4fc656be02d90bf8d393d632a1ab509c432511f1ca16b01139cb0627f6503bba75440414af97a04bc5239567c060ef94c9ba7221d4612eaa640bdbb8b72e32a4668401aa79421ba68115261a8d94878c90a0468510b247968b7463ff49a0578044c5e9147f0739f6a17b18828bdcf56966b1caa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e742cacb74e1d45704fa4cfc91c142453ba5c08558de1321ad6a6a2804769a0bf69770a1264ba5148b40a3a9be3c513a382cfa3c244c9a138ea9cb8da7627b350cff87ab064a079876893d893250ef59f369c41f9ea40daa5a5984c19ce06cf9bec2947932133a4157bb8cc3c72a1fd25715962a9c88026c018b7202885224019466540c9eb5482a87e665157be7722bc64133c827c20b97d9e692342f23fdb1b75ab2ccb6fa5973820b92ef1bb45c2b5ed1330c1417ccfb39fc6301b8a749d3613b3803a6abba20990151305cb32ba6a5b558265c2e27d8d49aef3e91819920db20360355919d5f641922233a1c24c0045172cb10f9564a029f07578a48a4d215248f3ac7a912ef8e56e366b03c567ab978c750d85454c68a5806ac38b7b3395f19fe78a001c5867d3e90e9b54bd63954761ab7f4a57b1fa32b65f285742c1207aa06818fac83b928e3e14644dd6999f310fbfac9e372b576a0470a9f9c5d2293bfe5255826c534c1800bdf348b713766507674ad820dd0c7c570037c6da35edbc625ff0223cea7dba19bf044699183c1454c2c2318c14ea8c451cac1b585324c0f9489f94a9c14992abaaa393273e4c48b740b764216ab16df3b9eac38d04aa3bac2185f250a82be093d2359a1dfc7f2e60cbf05b4568c86824808f4e073641290513b247ec7585593389c5c0459173cc74918c7a93798802af77553b3ea32acd760b9008ad3851b2a5632ad41c11ba095131192f37a06975294662e4298302622a236f57f4119ce24e5e478098f20c108c0af3a3bd7aec511391cf77baaa9b427884b9aa88c17b81d387d65304d75b9e5d4006deb878bab34151b852a5757421b82090c44fbe85a81e076f4116c025977d9aab838624b340975f7ad16bc10678709a026ffa53748021d00bb7759579c6657183b6a67c3112bc6a8870d56dc329b483484af78a81b5f87edc200e4eb24386b6c882490a87d168a62818d6566b6bc5848b2755c2e64d1fd9b79f5a2c7072419b955ee69a6f453b862528bc78905bcbb44ed989b5e71b9126a6a920e67a074b2960d6a3ab50128fd9ce39137b03a66968616f134bc485770e87f01304a17c70d9adbd4159d67b888862b0b6052d9e8496084ba93d197766d10f6477679ca90fefc6b13c7472020943b4b6305988bd9df4a655799ae6c7c398341a4810c6698351f7cc4fa59c2b0a86418145743d2b850cd47f32502e00d96b0a67cb3ababf62785b11a04de252813efa36bb83001ea322490a7dc5c54f32274b01fa71d40717ff917b81fc899e28adc5c4a0c41742c7d043195cbf8393a84206ca1e87032c553b68776f9153b4e2e0a445d2937fdca7539b8a2dc497a1f338802c073e891a3f834505a82a39f54544a49921e348934a028b7c54f11b26ed1a9cc2db7c58ecae2586168b120a2cf4487a6b34b8015e64816af26b864b7b30b19022d5038f89431056153dd03169a31a18c5f6649f6b638d4c249b712bb9563e4adab4f3e83c5bd05e2617b4530161b5264ee996abd5905e025820c7e1b1bc05188adc559fd0a0177473d816a166025bb4402d7e98b7f148ad42f72920d24e024a4d7a8a9dade92ae250bea3c519ab515fa2581b1f88c4caf62d59050e4ab1512c14b581d7c012645f89a0722ad2a1c2f2639b2b11051059549417d8f3ca8ae80fc241adede55999222b05b7b7101885cdc149be41cf9d2b9137e3bd0054ca89818e84811bc21944dd19bb2c1a54251992f2a51ba93a452c290272850225e9b2489324972cb6982c338f55192b4b87c2c91cc985ac9151c638aa741a476f25b3853afb4b106830d882a1e8a26b1b1305cd045e112a7e7a723ba9b801c48358e3004ba12b347d28a571f8a6c05b7c81fb3ef2e324b1819df549abfb871e25053d3e4676c9088d277688d9f85db7fba99fc62306c0414654509a086d0247aeb60a9924a2ba77f76d669c1880c302e67b1e1e638e4f74628ba73e0c565bf7766ea68206fc779f9c55b1b48c350dd095a5566fe1a611ee9507e729142b384306527c7928a7c09a74e7c03925e87d71c45896444522a63bb6b78615003d5cf37ca7e55e82888c17f171aeb440952328ebfb9eca10396b2044ce7275ee2709e917cee9425ea4c8a95b163876a2159907003355323d56b62e243cfdc714102a345af05f4e1052f9673ef57abd43e802744316642c26809a9f07805ead090a676204cfba52f4f04715e5788a08754d23b7c5db0d7d72ad20dab9ad776d52d1954a99407eabc44174237b127c4670aee6689100ab4e9e003a4157b69151431aa5bb9cf9350eac8501895299d93d6078c6a9888a6fb783115803170c1f8b2c84d0dbb801473084aa130d5c9c99eac4e00c2355a04556a26247a73b4a7121fd2cca08168d2399a1a45b685a921b9c0aa339390068348a3a8cb55653987c691e9c86cd67c385cd580892a01d160c9e86a65bcf63a50777b353b948e70061d03154e5ea518bc687a4a6b6c83372c0d16932accfcb13525457979218041af9ba2e012f82d79fc245356aa98b11f186fd2c538cb5159cf9562b5a5344cc1c44b3703a50850358c6ab4a5fcf830bcd2b1a0c932059f2c5a43b932e32a2fe9ab9f2f3b1ace7a3c1290cce509a5aba7d50a172fe51c65bb142b54ca6113baaacd44f3eb76aaff63a474a74614a0793cbbd7a1c822292bd75b2cd9d7b579fa995b9561a2ccccc1de89e861832522412753bb03a193b15c7a5e04643a217cb6ffbcaef5a3750033e2b0c42dab154f96a4062751e79c4aed5a1c6806b56e59b91f2943da9d837ef94c2d1a3767a68b44db44dfe021c47ec37e4596b4668c0899a3a651a9004337bb79c68dd59acc18a0b6591760576c819716560159908903a32111daa1339d8a8c66081894a52465f542b011bb607177d6af34d88ea80d7247ccbc269ad67a15df94f42a22bc1a525abc7480257694e9918597a8aabd1b537b163d6dca6dfb77fdba61949e3c15015b567fb88b509b43d4665abb834263a47c5a6007e2807b267aa50e8af44452b01a62b3034ba54ba910b018c629266e26514263820fcb3390dc117f9878c0ac4b3ff899d83d922184c42990088bcb03ba65993ca46c18bf1583f5599ad549801e934b8990fbcaa46a3f6cbe714c47a83c7595591df9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f6481642d52117145ea2956bd5e446b895609be84a9344ff0f5cd1ec62af9ea9e3c076eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +expected_public_key = a7823bf24c9fed4588355033f5b22ace43a30478209a8965d587c91428b92fe034a1714535cc458c5146aa8b8c7b2c047ac76fb3d306174cc370873e25ec207dea86d8430a7ed130701c671697185c385dfe0410d91799ee546b4d6347ddc146947a9a5692c64445ac60a9259a7596ee8421eef78bac115dc95067e002aa89b814dfb1498ae7829517c8ab587afef52d4f4068eb21686e4416d93c51efc2ae6eb1cb1304228728769f08a4bb64893231c4be107a6de473afe6a1a3969b610a87fe2bbde35c31d1530b05aaae1afb69c07b6c6d4753b16588413aa588726f80cabafed3323f412abd2579096a44c30991eba87bb4d667bbab5e848a0bb178441aec4d00477310ec4e33677925985e1aa7b9965a103cf14fdb004a60406994e0a2fa5a5df0465cbb11a54298cfb109488564aea65b5eaef171716719916a4615d3ad708c8a825874b7cb671a5b61f5c3c9b9325ff964046cebc4991343b0eb199b9099f04c97e28aaaf0bacdeb4a007f956530c712ecd49017d73c8e498fab650608106174c7141a7373e27b3d11c2b06455b4f1c1471f8a0bc73c4299c47eadb75fa75210cd813798d84aea44a1303c95ec02cf4602a496a86ba364babeb7603195c7cad66d75b46d763094fb0b2760b048af1262954b5bf5833cbebc2ada183bc207290f094b6e9c2ba622914604aeba35237d17606d1b76330172f74a06821b07d8348979070b31ea32166568c261c91df097e41cc1ae4bcbd3e1525f179f8acb232bd056a5e18eca475f40e0cefea85d664bb87918339f407831c27da3ea42da34be7be4beed4c8a5ca805cb209d51a826d32c2125e204f5c87944372c3c1952d5f8b1873c1c6899b85748448116b3aa85156df381371763aab6c8b801b19ccaa1f87c4097c3c351c62ef1c697763915eec69389671081562e76701d805b2a62692b6f3a17fc163339f49edd205e65ac81fee42eb689726a960711e1b2ab7c15e385717946c27c86116b635873324bf2fa21a5c194492571ab5a7afa1427aed8245164a23f2518a4f4016bb9af0c14a16ab67675767d5a165948261f4df2bf1ad7cbd259cd31944cb7880920dcb227d62b17cba049388b340173221559f0b70baa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab32142888d6c070357b6e8500c43182240863b002bad191bc0e189c0a0f481afe268dd9abf93938d572cac462c710b67507a913936739e83407412db51ee778570692006a3399e12beed2c2bef5a43bf356a27d1222f267b2d6ca313315905b7550c7c150827c8eef97803159d86127029388fb3b733a6f1b83b638dc08778ae53bdb4751ede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e98952f410e774b520413a847046149e1a36339c8807cae45144180a2bb7445626f1b2bed9c0d9fdb5620450b69fbb972f6beccc9cd12591b22957f94f47ad7022acec4233cf86e25631b8e975eef2348776207b56acfcfc5b1e43c3e64591fa4129077c4028c7b5c54734945a7bc986a4f4719867f219978115aeaa06929812506a40426f43a899892de243da4e9940db29ccd421fde03c80c79ba1c1a1b163170abf21cc32130c19ba2c9f30d95b78d560344971ca8fc9cb899b082fa21aef5110b32dcb13a369364d44f3aea0c4e7c49f22cc0a3c07b0c134e9ca3bdff78283592050f8c99f0e467ed39cc32a9cff97cbebc90aff850a1b1a20837e02d516033ec9cb4337a1168e013587bc4db0a7a4cb52c3496c0371c1699520d05c68d81885920812af1841eeb8570783aa6cc0088d67ba2f7acb19370b1a9e2066528bf38830e9c72c3021b6e49640805979bbf662404236bfb74717659268d4129943120aeec2132c5a205b7b3a6b8bc6c944fbb035315c24666f1ae53451b52b9b850f15e0c71a086391741cba130d07b96faa70971a2d974bd6219a2339098356ba3b573a33b2837d3d186a26559b0d2325ab88ba9e0cccba484a14b2f73c54204c3111e846249a9cbbbeb8e7d1b448f353ff7a35d1600a6c8e87c06f653930bc1c3796fc0e8001a3cce3a37745382467f614af24c832757390cd0566f0c443c7c5539c72927ea1394005ce4b8bc223905639b1c7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_private_key = 91c087e623025864c3c5d9049e865c6226cdd2b39f8a1578eb69a864ccb2fa155db32702def5b50e973495997e18c6c21756568802a4bbb86c5018016fcb0655b09e6a4b39a8ba2d70e32bbb255bdd296c998a21f5716d49968dd02a9c4f4cb9dc72c874c232011225f8e8840f7589c2d285c1e72c8588c0a33a502a385d0527186cc6809185408e9c7fe6262725528a439332f93a5ba2943e6dd7b30d79a25939a4c0802bf57c755a5a0ebbdc8390f8aee407a541c46cb1530fe1642215556d20ab942ddbcd1627826648acc3fa1367db0b45075470196b46697d9ec6974f477eda553f80b701e853398c69a6e4970a746534928631e6b811e533a4d1e89cdd6969bfe0c861d2cec3e16d0035bb50573ed61b5dbd45c8c5b223cef4266c5a6daf104949eabd27d3319bf12a7aaa4e5f636732b28e902a1098972977d98c00a267225b84af1c8c404a52472b8d1a793e370b17a9935ee590331256620e302e390474dd6a17d17a50291b6bb940bc43f89fdd22109a72c8ecf9acb1e67ef6a423396225e6acbff2880c35673135c5183ba37df968330ce992dae04e9455267a195a41893194bc51c67393251a11ed3c0829d99a3d23ceaa387208e00974e73178459bda539bcbe89f5eeb05ee21be3b1159018a3262120c21d4972aba1a1350231d3a646ba70fa5b641ebea1b130470a5ec7c40627035b03d15696be1313b458cc9ac8460cf281a6976a9d2ccaeb9fb157300b4289a55eca386d3d8a7d16c21102aacf361578010042c3a6397e2cb2ea5224141a1d451b38fac14d7b64bd7b72db17408b0a8906cec108bb926df54299261b6b5c6a636b395acb651ce6b6018ea9c92c1525de1624b5570f7000466cc09a909cf36f34687265b61db6bf2882514705fb37346385cbf4df33b98686e0189bddea7268f598db1b6cc7b32792d5546e242a807e760ece7080392823004453048c6f743b87c1670c6d10e3001008a24590294bc9ac899bd588197530fef9c2b85ac66520a195c77a7aff61672c8cb74c07d43a2bab7a764e750663091a005c9af8cc4b55d502169d4293e79b365f60085b1cc2f4900541588819b5edcaa3b80253178639f63a3091701c7e7b04e95435bdd2114bbd3abefb23355591b0ff102bc94b56b338083b82328712733f2762c5b1d0845073cb3b46aa28ce2cb282a4347f2118a6e062d7e8524147545488a01378a853d489c03eb0c6527307fb0ca5f7aab6c328438d33cedc10733ab8a68c7ab88e0b06fc51c92c557fd59488b6245796b7dc291728121bc7643aa5d56c483186cb55086d7e8654691cd5eb97580f0a553a2613c486c0b9566a6f05f9d2b82b57345aeec1368cc126ac53b9e794be471c16a498b743c1848a14d53478fc341a0ada42bc2e0717fb6965737876468515195050d64079d624da1596f88819fdf95653b8217f9885d151821a9529420ac95dd928fc429674025882c9758226194615304f1f5caaa456182c1bb11f0a02b6c758eec4ab6441879a42450a024559697c4494d8aac2f7045342234cd8081c0077c9232e66838460ea26274329988af3a82b898c4efb033ff4101f302a898e84bcedcc45e369cd1bb7f3517280d6655574c5a13f43e3f834632a041d31a7e01ab4e0f06458007063edc8e9d9b31c8ca7fee525656fa4ee9d36258a0bffa5a12922718df123e7ab52caff3845a801222f23eeb946ee00a4a78e0261a6c2a0c16279b5406bf7bbf4b7c3cde22a4beb9c6837c83aefc90c7b0bc21ea3d5854b37da36059dc4094181065d873469cc40db021474abbc8d80fc20a0ad1237dc13716c6a735899bbc68d71012b40505ca6c386ca92080b857a7bf8908476008c6c5fb7e30456e26a6a0c247a6a0a57049c1ce825154d2101f57a5c59dd44d71058423d6449327ae1fc3541ee73e31043ed194b89509bd7c113b77075ba694064dc442fff94a2607a0e25009920a438c537ea21477b39863f38903729875f4e5bf9b05baa0dc492e9b15fd729cbcec5de2d6ad727408e69a301649822e52681721a264696d8af076423babe37ac6c7676e74724804a04cf35ca840e206d99568bc393bf817a8c6a5ced2b9a76b036dc17996c6cab32223ae814338b7169ac1824f129a71eb50a554f8b684b929d9859ce8c019a7823bf24c9fed4588355033f5b22ace43a30478209a8965d587c91428b92fe034a1714535cc458c5146aa8b8c7b2c047ac76fb3d306174cc370873e25ec207dea86d8430a7ed130701c671697185c385dfe0410d91799ee546b4d6347ddc146947a9a5692c64445ac60a9259a7596ee8421eef78bac115dc95067e002aa89b814dfb1498ae7829517c8ab587afef52d4f4068eb21686e4416d93c51efc2ae6eb1cb1304228728769f08a4bb64893231c4be107a6de473afe6a1a3969b610a87fe2bbde35c31d1530b05aaae1afb69c07b6c6d4753b16588413aa588726f80cabafed3323f412abd2579096a44c30991eba87bb4d667bbab5e848a0bb178441aec4d00477310ec4e33677925985e1aa7b9965a103cf14fdb004a60406994e0a2fa5a5df0465cbb11a54298cfb109488564aea65b5eaef171716719916a4615d3ad708c8a825874b7cb671a5b61f5c3c9b9325ff964046cebc4991343b0eb199b9099f04c97e28aaaf0bacdeb4a007f956530c712ecd49017d73c8e498fab650608106174c7141a7373e27b3d11c2b06455b4f1c1471f8a0bc73c4299c47eadb75fa75210cd813798d84aea44a1303c95ec02cf4602a496a86ba364babeb7603195c7cad66d75b46d763094fb0b2760b048af1262954b5bf5833cbebc2ada183bc207290f094b6e9c2ba622914604aeba35237d17606d1b76330172f74a06821b07d8348979070b31ea32166568c261c91df097e41cc1ae4bcbd3e1525f179f8acb232bd056a5e18eca475f40e0cefea85d664bb87918339f407831c27da3ea42da34be7be4beed4c8a5ca805cb209d51a826d32c2125e204f5c87944372c3c1952d5f8b1873c1c6899b85748448116b3aa85156df381371763aab6c8b801b19ccaa1f87c4097c3c351c62ef1c697763915eec69389671081562e76701d805b2a62692b6f3a17fc163339f49edd205e65ac81fee42eb689726a960711e1b2ab7c15e385717946c27c86116b635873324bf2fa21a5c194492571ab5a7afa1427aed8245164a23f2518a4f4016bb9af0c14a16ab67675767d5a165948261f4df2bf1ad7cbd259cd31944cb7880920dcb227d62b17cba049388b340173221559f0b70baa055ca7ea75b0468ea1997fc88c39e1547350eb4f6d7ab32142888d6c070357b6e8500c43182240863b002bad191bc0e189c0a0f481afe268dd9abf93938d572cac462c710b67507a913936739e83407412db51ee778570692006a3399e12beed2c2bef5a43bf356a27d1222f267b2d6ca313315905b7550c7c150827c8eef97803159d86127029388fb3b733a6f1b83b638dc08778ae53bdb4751ede5cc520e7787e86cb3e5c64e69a7fc0b678783a702eac5b7cb75e809b61f3f46848b55f4224bd2f098fcebc7d5e98952f410e774b520413a847046149e1a36339c8807cae45144180a2bb7445626f1b2bed9c0d9fdb5620450b69fbb972f6beccc9cd12591b22957f94f47ad7022acec4233cf86e25631b8e975eef2348776207b56acfcfc5b1e43c3e64591fa4129077c4028c7b5c54734945a7bc986a4f4719867f219978115aeaa06929812506a40426f43a899892de243da4e9940db29ccd421fde03c80c79ba1c1a1b163170abf21cc32130c19ba2c9f30d95b78d560344971ca8fc9cb899b082fa21aef5110b32dcb13a369364d44f3aea0c4e7c49f22cc0a3c07b0c134e9ca3bdff78283592050f8c99f0e467ed39cc32a9cff97cbebc90aff850a1b1a20837e02d516033ec9cb4337a1168e013587bc4db0a7a4cb52c3496c0371c1699520d05c68d81885920812af1841eeb8570783aa6cc0088d67ba2f7acb19370b1a9e2066528bf38830e9c72c3021b6e49640805979bbf662404236bfb74717659268d4129943120aeec2132c5a205b7b3a6b8bc6c944fbb035315c24666f1ae53451b52b9b850f15e0c71a086391741cba130d07b96faa70971a2d974bd6219a2339098356ba3b573a33b2837d3d186a26559b0d2325ab88ba9e0cccba484a14b2f73c54204c3111e846249a9cbbbeb8e7d1b448f353ff7a35d1600a6c8e87c06f653930bc1c3796fc0e8001a3cce3a37745382467f614af24c832757390cd0566f0c443c7c5539c72927ea1394005ce4b8bc223905639b1c7babb06a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a0163017a26dba83777c4c0f46f31375ba02680ffaba588a9fe91f97ccb99c445fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +expected_public_key = 6bb90f94c8b62859c31e146647948785b225ce860769fc51df7c4310984254f927b1c200834876b23a635869c90df39bbe36094bf6b4835750a6f3788bbb7a3140a7f85b1c5cc8bdb386a0f15297ca9c6462b21df7c11845788c130313c642ba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fc913ef440addb37107e3032476aadb55cc0cd93e317a8ce2439f2464278884915c54b97e882dc44817488994c0109adad13c5102847bec7730a57227158c4ad1b51afb66d5c01bb6d2cbd1a7083fa6b049912f736824ad40a1acb22f2cfc9c3d145545bb6494d0159c40c12bc84e8d22bb8e1a76c237020949698175b21410cd4c7bb567c52b08fa6253a50e4f1573abb18f74abb9837cce85545f8992c9cfab66f800525841948b18b7ef3a2b0961c4c7e8902acaccfc865b45a5209fd5a4db705f94122fc69196e3b56139173b32ec9063c4151b2819bf9c7b5d7626b01cc420c86d1070428d4a774177035269a46ada8ec0e02230fc6b066c57dbb875a8f294e66166f3d7b95edc3ab66b15d7b55dac16182c13b371d82c42b85313c65da7eba0920914acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c284f1589af30d00dd6893e70d571700b9a07baa6083b2c50ec4eb95e2236402f7b50c87a9305a8b5eb25664d74d4337af268b48bd1855574405ea6237bc057e191cc6743742dd5a66373b110d380bf7c03039296f56ca700ae07d1a826965d55d86c19902762e75f10cef33664f099f8440634b2299a474bb8af328a3e011bca75db90b90c52c1699c1bdcec31565e411fd1c6ad2d08eba8c50b66a57cf10a98e2335327b011a4c3e11f58415b6c38f1821a69671fc2481920c896b389cc5783c5fd3b7d974ce03375142815e86e13ed4e052b1e009a25a2097c02f3eb337c3c85551ba14e1c22036916cb993612c809bec807da4e25cd8094c36720d376982650a986396504893bb0d82389886942ed1aab5bacf3957aa8d191dc56c4049a0714d89bc3af9680ee602e154b5e1c35f1c0440eeb0ccab22103945623fc201939aa71f99ba8c409bff83276f84879e590d9a448e1f052188285de9668260282e8ecc630c15ab164271ace0c954f13944fa9f4eb3a848f11ce7f0a439ba07a469720d4506ecf6cfa241136b469c12e48f137601f39a5adacc54b094127d2c27fe38aa461c76003b9ecdcccaaa2b16d1e9a164122a0b1a1fb751bfefab4a1640a792d2381a74aae77084a4e3cc33275eaa595733fc4a99d43be88803244b449ac71da53b2cf30043c929811c9a558a165da241afaa8c45b07c27876c8ff77b721b21022c958323b41ffb606c656519875b8bc6e897854c08ec10611b954c693568070528824b509f83a3e6c505b6e3203afa863bca408403c0ae86a374c1613917bc06b94dda73a8e0c98cf54a60cea727cf1334b324343b2c47df4a843e467989e4160e1611c1558928717d794290cc3911eb70200f51152d04871ca46d2753836791ba98aaabf697adc925a827cb7f3ad01069f5748778b5946c78ef9688e16a5326577ad5a5773db939d2631b04545c530c9b99141f4d213158d213163bca141c7949f24958b9aa67089488a732189ca923301143a1728a6707a6e8aa5bfc4d05b6cd1971290114542386231cf04c2c80cb28e50026c66763a570d173612f142ef1ebc6cc9a82f7fc10b7104b7ed6b30c95c5a63a5e1e52450c1c26ca11613b2b3ceed10968e85c0a9539c28242f1b9a083c0109036c6aa9349f201648ef14d67094af9715422885c7d69627702943bf0955d90496dbb0c0f2b3137b89c62903af74b2783b11748bb6df46403b69701e1d9a1e8a63f01cb969fe9ce00d7b539159e75372dff7a85ba660aa8471ade291fc782403f16bc2bf1c4d1a138a0160cf44246fcea7666276318940624a32b4af5b15f8b4da5a05557bc819db8884825b8c2770d6636a16a296daec0752e961cc4d11d61826d883a61f74203006a83380a0f9e5280fc1b831567136d178a906363bb801411e069b461027a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a5401916b35e996e1336cf13249d0cc33ecf610f9811c27aab55c52944298c3a13158c38501813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_private_key = 817471e55466b5babf92a2ad879c9c951ba60d230add630984b2528f9aa07ff755d7d79a2f9ab53d8986fd90895d5401dd97ad3f7a922516279b5858f2087e6491b7bc42b8a52a5952f23622d5603a0a3152990cfd6ab9cd863345d8be5e295c06b79332b0ac89282e61e5534fe0aac95aca140398b64175235b94417b8799a4b6d6933a8b815bfbdccf886664e7b8c5cb0b999bdcb2bdb288d569666c421e2a950d198158c0d36ced3a74d9032ab7a2b9f276be025296a773266e516826480e520b844eb69710120373a94705f9030ca200a7f85a94db1f55d46081570925a476099c3ebdb32c532a6d8f16be4de6416d0c30d450808cd3c08131a92551985b92255282be6087703f182156a13cd144aca3924fd15492dfd253ee5c9e78853590930521e843a0e37a26994197b3161ee1a60861c344720286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb3803f8053591b29bf64c2dc660ea9938200738e2c0c318b77ff86749c43c72f9667d80d462d549bdfea30cb0d9641b29308a461df72914b4b40213b62e68b161f83224c1a45472b5464f97c6d6371c69ca0d520426db8c1e938a934d50ae0b03be706b74cb8c674ea955a4d8ae1f6c0b56263041fca1871a5799921c45d9bbf13c01f0a9c5d973086b33acf923a2721c8b2fa7b058bb2e64f43bd80260b6bb19f26a4f55d53e7ccb1bfe3aa424976132c3b4b3a00908e722557a3657d285c8580ef45b76a207cb31a71402ba1ef280048378b80dc3312f78a74065b2dc873b22d37990e465e425b992722a25009a93a7a005d91b9460ab7c2336bd303883a151e829234c964265e42fbf8252cb89858d590cf0830e59c54021b83da94884a173be6bc454ad5a719252beb52a4f7544a7fbc03ce9091e9acc0568306e5bec2ed942b39a8455fa341b84571ac3fca43c14563f91395d117ab021c8f141a4ec7364ba4abdd8896bc6b281c751a66c767ac960ab52058335e14e7fd8a4e1d44de2670f9bbc67f682a0657530eba11c31381897d989bd392fae02d0afbaa5afa1748a80847af4b326f970c6161e15b212a1c66003a4317348374e66b29fe87f36d01af5f1c75be11bfea21dd8626765c46f0c153d0555b419227d50da5232810d8517b1a5e4147a52ad07012d8da23829f39a40c70d565937c58a11b1a25b27c8207246c4e1b40230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26eb251ab562c0e44bd238874e93a4d3b900a4b2b08a0b68c2b82c0cb56325548da3316279672913d2021d742c3619823c4391e64112b5b77e8d707f9c1a37d3464cd5f96543f720a0cc6c9631458cd9cedea7b6fcaa76d1e60c44f74b986a772cf593ae712214e21179519c39fa533a724fe8177ea59b1123e831e1dc561543a7e559697572157b60499c4c615d02099d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf7d25f49f61bd7363cbe3841aafab88524b0ca3381f5b22dc84c6a112979c3c39e45157c0749c04b022f83f53733a21e1f1842e0e72f78c6ae1e337b53215ae8563b16d99ebd6225766185a0d92f9a28bbf4e2b444b7c8225148f601d014bbb8839b4b8b21a2728268a0941d3a733170fa7606b5bf25739e5dca5da49c1bc01295d6b47faf3c2fbe8594c4f0ac085cbba4194ba0613f475b424e7ba1aed1c5a272062fd878b02644d3b90f66c12c4b64c870f806ccca4a36ba838d4799a861b3f32ac8dc9a403930b5c529c8ffa8038db52c5dd2a5a31ac425f835317589369631036b487f192fcfbc9ae2b4834135365f27cc57c1208204a2ce7c03f9467ba6688a9555476a935e6006b6912091c80ca777d9a0cc9274ca04366e9a967e047dde5105eb196f8e71694a01bab8c33e99e7acab053b4785bed85c9eab4276b24274a843048de5a49c289334fc0d447034ebeb5681d87ab1a8a5b938a27521cfb89212d6594af040719f344931704a74e294886ac351a4854eec2a01b0006e602bf6d0b545c78d88c7c76fb13547ba600ab07ce5c87770377c0868204df75ee4f84a1619ba335029b68278f45b6565029ba5cc8c0f1b900c845ff1619b7fd9a9ee148003e9b09ed4c7bba8a8873b8841bc20d1aa257f78ca54941bd0a0380a922eed8a226bb90f94c8b62859c31e146647948785b225ce860769fc51df7c4310984254f927b1c200834876b23a635869c90df39bbe36094bf6b4835750a6f3788bbb7a3140a7f85b1c5cc8bdb386a0f15297ca9c6462b21df7c11845788c130313c642ba127c8de50695e1eac8e245535cec4547aabd3f455fed566b733c499fc913ef440addb37107e3032476aadb55cc0cd93e317a8ce2439f2464278884915c54b97e882dc44817488994c0109adad13c5102847bec7730a57227158c4ad1b51afb66d5c01bb6d2cbd1a7083fa6b049912f736824ad40a1acb22f2cfc9c3d145545bb6494d0159c40c12bc84e8d22bb8e1a76c237020949698175b21410cd4c7bb567c52b08fa6253a50e4f1573abb18f74abb9837cce85545f8992c9cfab66f800525841948b18b7ef3a2b0961c4c7e8902acaccfc865b45a5209fd5a4db705f94122fc69196e3b56139173b32ec9063c4151b2819bf9c7b5d7626b01cc420c86d1070428d4a774177035269a46ada8ec0e02230fc6b066c57dbb875a8f294e66166f3d7b95edc3ab66b15d7b55dac16182c13b371d82c42b85313c65da7eba0920914acf8a28f44acf54bba1ee77736c9763036c73f4a56eca95da849c284f1589af30d00dd6893e70d571700b9a07baa6083b2c50ec4eb95e2236402f7b50c87a9305a8b5eb25664d74d4337af268b48bd1855574405ea6237bc057e191cc6743742dd5a66373b110d380bf7c03039296f56ca700ae07d1a826965d55d86c19902762e75f10cef33664f099f8440634b2299a474bb8af328a3e011bca75db90b90c52c1699c1bdcec31565e411fd1c6ad2d08eba8c50b66a57cf10a98e2335327b011a4c3e11f58415b6c38f1821a69671fc2481920c896b389cc5783c5fd3b7d974ce03375142815e86e13ed4e052b1e009a25a2097c02f3eb337c3c85551ba14e1c22036916cb993612c809bec807da4e25cd8094c36720d376982650a986396504893bb0d82389886942ed1aab5bacf3957aa8d191dc56c4049a0714d89bc3af9680ee602e154b5e1c35f1c0440eeb0ccab22103945623fc201939aa71f99ba8c409bff83276f84879e590d9a448e1f052188285de9668260282e8ecc630c15ab164271ace0c954f13944fa9f4eb3a848f11ce7f0a439ba07a469720d4506ecf6cfa241136b469c12e48f137601f39a5adacc54b094127d2c27fe38aa461c76003b9ecdcccaaa2b16d1e9a164122a0b1a1fb751bfefab4a1640a792d2381a74aae77084a4e3cc33275eaa595733fc4a99d43be88803244b449ac71da53b2cf30043c929811c9a558a165da241afaa8c45b07c27876c8ff77b721b21022c958323b41ffb606c656519875b8bc6e897854c08ec10611b954c693568070528824b509f83a3e6c505b6e3203afa863bca408403c0ae86a374c1613917bc06b94dda73a8e0c98cf54a60cea727cf1334b324343b2c47df4a843e467989e4160e1611c1558928717d794290cc3911eb70200f51152d04871ca46d2753836791ba98aaabf697adc925a827cb7f3ad01069f5748778b5946c78ef9688e16a5326577ad5a5773db939d2631b04545c530c9b99141f4d213158d213163bca141c7949f24958b9aa67089488a732189ca923301143a1728a6707a6e8aa5bfc4d05b6cd1971290114542386231cf04c2c80cb28e50026c66763a570d173612f142ef1ebc6cc9a82f7fc10b7104b7ed6b30c95c5a63a5e1e52450c1c26ca11613b2b3ceed10968e85c0a9539c28242f1b9a083c0109036c6aa9349f201648ef14d67094af9715422885c7d69627702943bf0955d90496dbb0c0f2b3137b89c62903af74b2783b11748bb6df46403b69701e1d9a1e8a63f01cb969fe9ce00d7b539159e75372dff7a85ba660aa8471ade291fc782403f16bc2bf1c4d1a138a0160cf44246fcea7666276318940624a32b4af5b15f8b4da5a05557bc819db8884825b8c2770d6636a16a296daec0752e961cc4d11d61826d883a61f74203006a83380a0f9e5280fc1b831567136d178a906363bb801411e069b461027a0887dd14ad80867ea0f595fe1951f1cc8403198ec483632b189a0bb3979bface3f9a5401916b35e996e1336cf13249d0cc33ecf610f9811c27aab55c52944298c3a13158c38501813c8d7f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516fb21cf5cc9a8a47a07cb2a154f73676d39a98a7d12a4abbd37378595c6332f46ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = 74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +expected_public_key = 9532712120555db81fdb599de13109277a48d20b0b16db7c6fa73622acc63ab1036c9c07a48c73dcc4111e10c919d09b3a48b96be05e56d809efb66ea3bc97fc360b85533c4ad1a9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6582274b7559be1362ddcb91e5c857b0e836349d4023d461b1b24cc873c56e6404149026cdeea16affb5fd715766617b9a5058776b74b72075e25002131baa50ca093bfc909b6102e8e5ba2c748bdc5ebca2be715b2800abe643ed542a8f4c055a0c7122854af8460016ca079bb701db46b2b17d0013dba7d24685fb46966ce53b3842cc66c8baca0934efad619459888945759b3842e26a914c835bec4410fabd4c98350717ffc143b2ccac4e72b64d195fe1147fac6171ba8b213eb5724039d889620c70a55ff0145caa543bbba3f732ccae4b0846200ae7ac6c84396224474568c058fd4785347f077da03acf744005ac1cc02f93f2130386aa2b62275722e11589c625044335779d8bae917a632652536337db7c78272241b4710210cc7954b6622bfe1653f4788450900d3dc9bcad010f9429615d24c9a4bc80a2c078f5b6e3c6847af5b0791c27fc99950e77676aea63413a3b259051cf6a83f0f9c5952462ab315af64b978bc4154be10702d5b266ac524ca2b5570199ca7ec91064c0247b08e01a8ae7f194db11b88d584237b507e44b411d5c5112dd22c7acc8d6f3513cc8caa63342284e6bbb16b2f63b9acc9cab050a19fecb758ec455414992aec45bd453639564a0c2bd164c1604d035380b0c2350f530770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe542054094a450a8c9f7a686b7565a3036ba7126288ad157bdf172c5e772ce052689d2495d00159a920b68a86fc905364c20027f90171845347366053d8c718a444a1e60133fb954adb3a47a7242b8100a8f9784181a4e7e479ced14190a282feb98008c09ae2b124a8743a4230910dd612cc75bc0068a4d866ca871a48b071cced3336d5c01ca3b819fdb2c22acb71b2fc2cf61c95b6cc164cab078472658e5d19eeceb823a373b4097b4e83b0d86e9a50488c1a35418c497250bc90aadab70ad35a16facac83093570399e8f615933f48e7fe8c04e517736732d6792c59e400a228a7cf4896af6c6c4d2f3acf279c861c83100b2868cfb42bc75052b26b6920591c78aab2de99c2ac0971dc90c19b6072f388ffe054166d95a785b8eeb141a9eb0482ee6b57c896d8805a33756005978a98f3817ae53b09ab4bad0011218382269f062b9895697514f9ad872a49392166c72c380a86c711d1f00c9641a6a03083a3755a482ab70cc213cf6f1bf7699164998a96a8258e819652ecb01f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341a62631f0410bdc0fda9ba4710a21c8934d6132ac21bb4a9292b16f787dfc58ace7d69efaa67c3a5405b98a9a07b276bedb636c18a668a1c36acb7170ac82253a85d1524ed79bbef4f046649b9f6a31b924196c6f72b12f108b6d95af9b373e34489155da84b8a810cf005caffb8b28504739590fd6b2a5247a5139b39236a2a496a93717854b162584bc57044f510656906ddae771bc029a0473a481eb2bb95397fb903a36a2042a4327c8c54bea769c419cc5efb83e84692513936f8f8775a1b114c13a4318d522194b8f1f7b05a8408348b3ca877b0a59f34dda1169a8c12d716ab9f558ace0b72750c1b4b9f11be405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbd407d36457c291b4027a6ebed8003658619fc4cd617898e8ca2e77a505cbc70f20aace50f301bc16c398d30473619326e261e2713375a68d83cc719a381284216d1cd011445010a2d24379b8024c30ad70841eba93cb65621260f41125c8cc03fa2894e84bdcb06b4120371a610ade828beee4b3495b4e97e25ed28bbd50223ef0c6b5a6c53470d22abd74c26af08cd44ca194815bed9c58a1775cd0431b41553454cc892088bbaa51b26d37c25a1000a7f8c54abcb1f5c0c3c61c7f6d36bc45320a886280fe2ccc24c704a376294ac15d70f1a300a8ab1dac505f3b2281439b3f93c4d4f62f5883bc00d9589f5a89e3413f425248a8f7c011f616d65b857d2353c0d28bc574c1f2522c2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_private_key = 60e93beb5544294bbd612141956430cff041e0f969e954a48298c7b5f321b9e1b70b7c796a753cc5bb93722b20380abd6b8aac4f0b102ddab380b88ab9dc040fcaa8b775882a673864fb757a3453273627df0690c90000b54112dca50235ba14fea59a764736a018a091b822a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb792645325d6755d79b972ae993c9e3413ac040b3bcc85c4f98a2e185bf4ea1d19a4737dc78547847b7ef385d2a07bfe272764cc873be8cb1286a0e7c83539d2b9bad5a17f0893ccf41e2b5cab8f66706955c5e168a99e9820a8402cb25a434f1a149f0148761014d32a51bc73a8cdbcb104c29be554b2724107ef314c25d082c7252e0ce68833a47a619a611b08394960a64d8c22c25aa1121a8033605c9bf35221730b15e6269cc25febcb8e3336870b3c1c9d3a89de4a9042758f517b55f85133b403c501590a0f53542239118f93874b319be0d063ad82144eca6156051424235d785c92ac00c412f8ac0ff5b88f056142f8a0934734b09ba14c00089bba136279a5fe462082ab4b0709a6db3279f8e9544f3909ff78b264399c2ed129c803b341d816eae96bc531952d55059ef0233b0c18e1f7aee5498ff6f11dbe801dfe193bb61b870008ae57483daeb8ca7ccb460193c68a509e8dc738ff227fda89b21eba0053992a4d3a1f8767c0d3f3419838c8c7a2c0b3d68e737ba77221c68a8570948a322a143e5a03888c08a1bb7c42e9db9111819ed94523848bc32781a881a468d26aa7fa4acb926ab8695b24a094b8ccb0423192cea88c1fac818a6b0ca19e423b7afcb51b121d48ea44037963ec1a325dc0bf7555977f468feb49b8346338db983e512b2fdeb35a300495f437cba88c36d01536f7a56bc9dabd1000b77751031102caba7182e2c440919435a14bc1ae1b354499324862885c9c301b7258faf778cd0a4721f26ee32c5dcc7a7283dc10e3cb04713255d0044bf1d9234f5180f32483f7079b2c0558b95c622db01be885b2580931fc8617b6940ddfd54cb327712da02f90a6a8ddb6ba17a31fb1d7231d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fda08897ba1edf959f37029a84e707ef676b89fcb5e94b8997d95542e26cbd28a7d01b1fef76b1c91ac327874c04f01b2d6280fdc60cead3587bc0aa6ec76f064b3263b2419bf3120aa7791053bfa6e089f6cb8bb020b5c5e2517d4b2f34ec3c4237af98dab3f4d44ae161773ed53f391a689d7b38f01155fcd080869656e15baf9a2a6419b38c2ec39112b4216fbc5d94771fcc4369eb90aaccf3a752020e24f97c30c4c67632180e9b928a0941c23c03ce588f7d841aab91b74b7959bfd8b5b042294ebb094b523dfc425e9ef70bd2e2bcb2937eedba0ad018737ba91a3691030c1a6e54c0bd4336a4bbb7c5dc79057ef5c574c04dfcf9c8407cac999a54975b1a45519075ca167b8285b2d554eb81702e30626897413051aa546bc63a42723bb95f0dcc525944c967d7a5793c34c7638ee59608c8680f2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93378f15dcf2959d0e02a15e2277b7ab78cb2ba78703f13dab307ba1b663c8666252621ab1b9fa42dc69008881a2f0933c03c183d4b82cb149511f344cdfeb0adc0c9b0cd98240a7a7c97d6ad8eecb20a8a04119b8aee8ba273730965608d0ce921a6dc8b8cbb0098d722edcb88cedbbfefe2a04935b5d766577dba7c20a73e4a8b81d6b81bad326817f8b9d654b005d7437c73761c62a43412b39ea821f9547b433c57c2512268da14bbcb38b3906348fcc9facbcdb2f44e713125309515b6d4716088071b60861998115ec97d9cd99eb773c343942105b4926c14979fb62f7e6616d3ac1b0f12a96cdc7ad22ca6148800b9d1047a8358a1563cb310607108198c084215bc1630a002b96a74d92198e832710de036b0332bdbb2269e23417a82a1dffc57abb971dc0a34d04378308b90ad36064548c5480bb57384b7487c299a016be645958f64c712b75454532e4021ab21c55020b609e2e4a5dbda151f8a9cb9e9c552b73b8241445f97ac15e0a5e7a357c2a6608d388652848c066b5f345c7ee7a1410db478aa517fff742ba1965abb0687286273d9f993d7d730988a709532712120555db81fdb599de13109277a48d20b0b16db7c6fa73622acc63ab1036c9c07a48c73dcc4111e10c919d09b3a48b96be05e56d809efb66ea3bc97fc360b85533c4ad1a9e4ca6359ac6241ea6c4586c3fc983742756ad1fbc6582274b7559be1362ddcb91e5c857b0e836349d4023d461b1b24cc873c56e6404149026cdeea16affb5fd715766617b9a5058776b74b72075e25002131baa50ca093bfc909b6102e8e5ba2c748bdc5ebca2be715b2800abe643ed542a8f4c055a0c7122854af8460016ca079bb701db46b2b17d0013dba7d24685fb46966ce53b3842cc66c8baca0934efad619459888945759b3842e26a914c835bec4410fabd4c98350717ffc143b2ccac4e72b64d195fe1147fac6171ba8b213eb5724039d889620c70a55ff0145caa543bbba3f732ccae4b0846200ae7ac6c84396224474568c058fd4785347f077da03acf744005ac1cc02f93f2130386aa2b62275722e11589c625044335779d8bae917a632652536337db7c78272241b4710210cc7954b6622bfe1653f4788450900d3dc9bcad010f9429615d24c9a4bc80a2c078f5b6e3c6847af5b0791c27fc99950e77676aea63413a3b259051cf6a83f0f9c5952462ab315af64b978bc4154be10702d5b266ac524ca2b5570199ca7ec91064c0247b08e01a8ae7f194db11b88d584237b507e44b411d5c5112dd22c7acc8d6f3513cc8caa63342284e6bbb16b2f63b9acc9cab050a19fecb758ec455414992aec45bd453639564a0c2bd164c1604d035380b0c2350f530770e84792a986d7f8bfee6c4ee164a678c893f3ca5149bb5fe542054094a450a8c9f7a686b7565a3036ba7126288ad157bdf172c5e772ce052689d2495d00159a920b68a86fc905364c20027f90171845347366053d8c718a444a1e60133fb954adb3a47a7242b8100a8f9784181a4e7e479ced14190a282feb98008c09ae2b124a8743a4230910dd612cc75bc0068a4d866ca871a48b071cced3336d5c01ca3b819fdb2c22acb71b2fc2cf61c95b6cc164cab078472658e5d19eeceb823a373b4097b4e83b0d86e9a50488c1a35418c497250bc90aadab70ad35a16facac83093570399e8f615933f48e7fe8c04e517736732d6792c59e400a228a7cf4896af6c6c4d2f3acf279c861c83100b2868cfb42bc75052b26b6920591c78aab2de99c2ac0971dc90c19b6072f388ffe054166d95a785b8eeb141a9eb0482ee6b57c896d8805a33756005978a98f3817ae53b09ab4bad0011218382269f062b9895697514f9ad872a49392166c72c380a86c711d1f00c9641a6a03083a3755a482ab70cc213cf6f1bf7699164998a96a8258e819652ecb01f607ba18c7b09ad5c28864468dba9727443fbcf6c40ff44341a62631f0410bdc0fda9ba4710a21c8934d6132ac21bb4a9292b16f787dfc58ace7d69efaa67c3a5405b98a9a07b276bedb636c18a668a1c36acb7170ac82253a85d1524ed79bbef4f046649b9f6a31b924196c6f72b12f108b6d95af9b373e34489155da84b8a810cf005caffb8b28504739590fd6b2a5247a5139b39236a2a496a93717854b162584bc57044f510656906ddae771bc029a0473a481eb2bb95397fb903a36a2042a4327c8c54bea769c419cc5efb83e84692513936f8f8775a1b114c13a4318d522194b8f1f7b05a8408348b3ca877b0a59f34dda1169a8c12d716ab9f558ace0b72750c1b4b9f11be405a82e37beed883630b6b9543367a1736c9ea7365bbbb5fbd407d36457c291b4027a6ebed8003658619fc4cd617898e8ca2e77a505cbc70f20aace50f301bc16c398d30473619326e261e2713375a68d83cc719a381284216d1cd011445010a2d24379b8024c30ad70841eba93cb65621260f41125c8cc03fa2894e84bdcb06b4120371a610ade828beee4b3495b4e97e25ed28bbd50223ef0c6b5a6c53470d22abd74c26af08cd44ca194815bed9c58a1775cd0431b41553454cc892088bbaa51b26d37c25a1000a7f8c54abcb1f5c0c3c61c7f6d36bc45320a886280fe2ccc24c704a376294ac15d70f1a300a8ab1dac505f3b2281439b3f93c4d4f62f5883bc00d9589f5a89e3413f425248a8f7c011f616d65b857d2353c0d28bc574c1f2522c2ad76809948966543bf757557b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae591aa9c81277503a34441fbd6cb59c6d1ecd5e00298fa56be9df562576250c52e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = 013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +expected_public_key = 3c614fd2510dbcdcade2f57004cc995db29139a713ec106607f815db318f03d2caf4a294caaccf34914106d463fe118bd0b65021f086f1f9a8f34a42e197525859767d89b0eb29cf54a93e76f13bf43344bab7578ce167796976e5c7a2626b76ca2222cb358904386a5485c67fd58f7027543185c71ba82cdeb93b619455cef931560452d7650b25617c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5960a08a6d8992a23aa5840c97adf727e698c990684d0c19ac71bb816ae30e71351c3300b2edc22601b6bb7545a87869b9712997aa5c3ce6080afa8333e6159c1de61333f4742e5c49e887a8a4ccae2df6c7e218a509124d151a711da99a11d7b5841752c498521c3c4699113dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b592327d0242ac68ba6d01369257c56427928aa5b0534200ff8a4a7263f9f955598a0980ee67337442df706360faa20dd6941195036831186dde104c5e6cd79a84afd6917c1122070ac6cfb120c7f22276afb4d51f52d0ef2bd4322164f938f66269703ca1db984bcbe337c710142d024ac0d7502579b1b804bcaa5fb551274ca547301fe6597cdb0754ba6af7d74bca789c6a7460ab599cb14825fffe28683267001e32ec6f7802826c3d5091f8c520ca52c51e1e2b649222bffe45d9d373f8224b9e3e973a852a0d6acafd22561aa1376e9842ab292a61c21308e209d3ea353d77a8d835a46e9315ee19bbafec09ed462269de56b36f6791f771922b49a51b3870ad0a0a2f3aa0122ab02648ece97c96ed24b9e99b6ac2c964cf356e4a39c21d0274eec6fcc8893e7cb425c68c8e99a89d22647a5522ffcbc46184ac181d556616503aefbad90966d2806b6bf26903b18b1bf5a89167a10d47cb4a6f101fb09473710559f39b3046bc7a55331e8da418bb34089793c2a7606112011e89318267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd85f815c9c15b36077e9971b4ecf7546c4486ab074e511b729ecc835c175b8304038550aec0c6c22eb76f866444859293d21b4743e0202a3b6db7d2342585a5c098ca66822f86f01a6a9c080b414144220c44054801c36199432870f8b39b08831c8623972b1ae3442d0fe409b47a5c22e67738008a71ecbb8016ce110794b1d313460650ceebaccaa637f9625429538dd1e00ae8930211063f3265ce4b7c6ece835faba9236cb228ed003cb22cc8b3c5811bd9c276944d929c5c67b26b8648be93a89396c2949e26866ed4121c3849bc6c15adf8942fd4ce8f12b5dd83cea1322ed4c0bd2bf9b591fb01a7dc49387c04e7c1416abbaadc2c183072ca13c31f8e964c2a9b56912571fbc07878584f7926a9cf13c0f4c114c59b1b44a94014c2963c596471f7771cd383c235aec594b61eeb17266a5ebbc4828805169d1a2e468448e73a1e3c919ce3f738d2e1242c0895b59c27e12cbeb10c591a54108a7b730d2b902185b9a8da9d2ae01807466c456c4eefab336c13c6e137b6cce922b1113e1cc862c8883eb69acb0667a68fc58fc5d6584af926b25159f4700c110c43bcdac03714714ad4c07afc4d54200cf0184e5e8a6e5df1ae6d13c9f9401ce38c6144d3b87dea304625cb8aaa6ea0695fbbb775c6d0b7f79a6fdc4c53c9ab072d027da097a0d69ac77a9cab23941aa160bf36d95b10167364a0c866e44be2930199a00972936275cb9f3340812d70968a95428b3000b21c68a237961b99a2c7f62c9988675f01b1604910b0d8942b21c49e676532603ddebc39876c8479603f9360a9538679c4a83dc1c33947b5c01a5c659d30187db308bd999d68e30c79e40b631bcb8725b72a414e3be0300e4c7a30f56abeb9588fe0292dfc23c4c994ca20726cebcce5942a3b376bda76a965179f56e66a2bf94ca35090af041607c18545472db1e71af96570538796418737b048859e676480727e71e3534510998402ad13d54284b76d6eb04715934fa6f05cadd2a6cd6683d981cb5f6a884d04ccb008657f990545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdb304558423f4a47961e230c9091f0519c15de10275da4757d40edf70ce729a5986724e8701101c208e4e3bcd4341098d8b07708a2c81eb6044b82ca3868a4752cf42f2596c7ba678723931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_private_key = 3a756d6dd157aba65d60721c41eb4edbec38834c22e9ac88f03119b472bda0961d1f5c3268ec6492f92d5d066dcba69ce9c20311e1c15fa81fa5014c6c956f88055fc2d35e6b295d05d6167e4375bff23257ba72c0f97f452b609f22b57f7c27f71a4f259938b5aa18097399a0d32c3602203bb6769015495b4bb7317c9e99c966215c58d3455efcd36003826c2c7b1bb437a66a968dcba35dad7098fce9133110a109c2b91764719ca25866c98550082e88f29e78b38b40a53c4d626fe63390a290b54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f59505809b1095405949cc55c109a1108649552d5f83a970083bffeb6550893b5c5106417b0cf1e44b6b05a9f9093e386c9d43f14d4cfbabd3b17efb49aa2c571ae99197d2e4b7d58775962570d528b8ebb8032e8065bdcaa391837d483a27239a4a8c0b8f13013f4aaa6bac0ca86e532523d9620bf9c2c3e2aed2365e90a1699a4cbf454c4d2e2c4273e93456142f737c8b3697b9821039142c3e25b346d020c829850d6ce2649087ab762c25baa2639c8c7a852bc76d456ee69747fe561e267844a7e51ae05c5820f0c2b880b05cc935a3bbade2c6a4881cac21938a304c4cd2c1cc1bfabd932b777cc459bae4be75389862464367c6318a0521dd62c5f070a139a95522d10d2e4134c06522cf52834562a208b22a95431014934f51ec49f5ec087d1435db935bb5223c3ec87bb7f7427a458232474ad9cc222b422149977c7f366f48b0b14ab260bd0a8c04623f9b12091ae049725064d0bb4a249075816aa249718f1a7768c3469aac7182d2f01d6373038d7c4ca24802693a354c19c66dba1c05eb180ad04c1fb095b42947d16b66139384c71206bd0ba9ad9bbb5dd7593d08616c214fd9013e792a5b4930122d1c571f1315d235562c167d7546c8ef7536a929982f6a55ce7209b0d5735f69ac6c52a824e508d2481a5be01075c54d8743bcd76767b69b5e350989e629c97ac1982a75806126245fa692def22b15a29499c82ef7f993eb3472f850527d900da2f513a9366a4fa978038b9e46752dbb8084fb12cbc591008d692544078343e9ad67909dbd77c18bf18f02607210f4a0f5dc749f8b0bf371309027968968678b0135af65138c5544abd57ed8a646409224d32052bb14bab4d51dac981ccd838b4a513a36a351b81a0785ca281d7106872583b8babbd62a5787bab8ec9019c7009130ec6be4e25d9992aa1dd13da9c1a7f1ca27fd78968741436003789b8c781c599c98d2465c7513cfe85154d7a655216e5b3b800deaa6b9dc7c0d998b9ce2b99da6afc27a5ef6c152eb16184d91cd038cba69835ab3500ac2e87368f37888ba90f219ce9da24109f0b3e1894db5f640a17b0e705195a350a61ec62b2c7a216231c530f557d4c5605346a6500b7c1484012fc87dd4526823c447b71a726d65753716b30c212565dac474ca3acee664218285a5c4a726f681e98619e2a289d08895bea26bd6a3bff3a5c5c1ea894cb6440d075004f879b41a14ebb82b74ab0131d0b3348742db7244e750ae2b7bb57f8a95379502827880f8a50ecb1394db2553c07627c113a300078db1bac7b50078d6e2443af5c1099633ebb4b9313c9f82cb967442211ccbb7dd9b4711f85e99e7b07601c07f10373b104fa849a9c9416c3304c09c1b2f22fa159bbb043a58415a11cbef06b85fd728b492bcfd0767571848652503a5a162e0d478d74cc05ba5160f398df7361b340226ed49a5449467a9a39cd5297c52bc0cb9634325854043617faa817ef2a94aec5a49f0579f085acfa164c3247959ade02dcefa8acb965705060b08499c33f70fc6055fe1752a06f0547f4c702f851b36d23da24c8ea79a942dfa6912cb00c8d892b244c765d0795545423233a6bfc01f38fb05b8f953ffa532b7b6c2d667913cc966f6b88f63c1bb06b3bce5310a8be69f0837b8a0494995844d65350502c061d65c563fdb6b82d41e76495ef15b56f3f53d5537cdb2e6c349844f02121ca9f404a19c6591600d88babd8ca4c25c973f89b0765ba6b4121358c1738e7c718f6cca0d6186594b265fd53106eca59d9ce51c1723cff7f7053fc6240a3718b0aa3d942084a97185701bb213d489c4801bfeb22463d9608b92053c614fd2510dbcdcade2f57004cc995db29139a713ec106607f815db318f03d2caf4a294caaccf34914106d463fe118bd0b65021f086f1f9a8f34a42e197525859767d89b0eb29cf54a93e76f13bf43344bab7578ce167796976e5c7a2626b76ca2222cb358904386a5485c67fd58f7027543185c71ba82cdeb93b619455cef931560452d7650b25617c51d93d9223cb2083ba29d6a66ad798b5e4a49afb5960a08a6d8992a23aa5840c97adf727e698c990684d0c19ac71bb816ae30e71351c3300b2edc22601b6bb7545a87869b9712997aa5c3ce6080afa8333e6159c1de61333f4742e5c49e887a8a4ccae2df6c7e218a509124d151a711da99a11d7b5841752c498521c3c4699113dbeb652a4c6754b0b8a7b1341d5a3c99bb39c9b592327d0242ac68ba6d01369257c56427928aa5b0534200ff8a4a7263f9f955598a0980ee67337442df706360faa20dd6941195036831186dde104c5e6cd79a84afd6917c1122070ac6cfb120c7f22276afb4d51f52d0ef2bd4322164f938f66269703ca1db984bcbe337c710142d024ac0d7502579b1b804bcaa5fb551274ca547301fe6597cdb0754ba6af7d74bca789c6a7460ab599cb14825fffe28683267001e32ec6f7802826c3d5091f8c520ca52c51e1e2b649222bffe45d9d373f8224b9e3e973a852a0d6acafd22561aa1376e9842ab292a61c21308e209d3ea353d77a8d835a46e9315ee19bbafec09ed462269de56b36f6791f771922b49a51b3870ad0a0a2f3aa0122ab02648ece97c96ed24b9e99b6ac2c964cf356e4a39c21d0274eec6fcc8893e7cb425c68c8e99a89d22647a5522ffcbc46184ac181d556616503aefbad90966d2806b6bf26903b18b1bf5a89167a10d47cb4a6f101fb09473710559f39b3046bc7a55331e8da418bb34089793c2a7606112011e89318267348baeb7b39f6c85b0ac58b4c8c187965eaea5940da89cd4ac31754bd85f815c9c15b36077e9971b4ecf7546c4486ab074e511b729ecc835c175b8304038550aec0c6c22eb76f866444859293d21b4743e0202a3b6db7d2342585a5c098ca66822f86f01a6a9c080b414144220c44054801c36199432870f8b39b08831c8623972b1ae3442d0fe409b47a5c22e67738008a71ecbb8016ce110794b1d313460650ceebaccaa637f9625429538dd1e00ae8930211063f3265ce4b7c6ece835faba9236cb228ed003cb22cc8b3c5811bd9c276944d929c5c67b26b8648be93a89396c2949e26866ed4121c3849bc6c15adf8942fd4ce8f12b5dd83cea1322ed4c0bd2bf9b591fb01a7dc49387c04e7c1416abbaadc2c183072ca13c31f8e964c2a9b56912571fbc07878584f7926a9cf13c0f4c114c59b1b44a94014c2963c596471f7771cd383c235aec594b61eeb17266a5ebbc4828805169d1a2e468448e73a1e3c919ce3f738d2e1242c0895b59c27e12cbeb10c591a54108a7b730d2b902185b9a8da9d2ae01807466c456c4eefab336c13c6e137b6cce922b1113e1cc862c8883eb69acb0667a68fc58fc5d6584af926b25159f4700c110c43bcdac03714714ad4c07afc4d54200cf0184e5e8a6e5df1ae6d13c9f9401ce38c6144d3b87dea304625cb8aaa6ea0695fbbb775c6d0b7f79a6fdc4c53c9ab072d027da097a0d69ac77a9cab23941aa160bf36d95b10167364a0c866e44be2930199a00972936275cb9f3340812d70968a95428b3000b21c68a237961b99a2c7f62c9988675f01b1604910b0d8942b21c49e676532603ddebc39876c8479603f9360a9538679c4a83dc1c33947b5c01a5c659d30187db308bd999d68e30c79e40b631bcb8725b72a414e3be0300e4c7a30f56abeb9588fe0292dfc23c4c994ca20726cebcce5942a3b376bda76a965179f56e66a2bf94ca35090af041607c18545472db1e71af96570538796418737b048859e676480727e71e3534510998402ad13d54284b76d6eb04715934fa6f05cadd2a6cd6683d981cb5f6a884d04ccb008657f990545e38a7c044645d9cf9b7b49643b7415a63a8b37b6fdb304558423f4a47961e230c9091f0519c15de10275da4757d40edf70ce729a5986724e8701101c208e4e3bcd4341098d8b07708a2c81eb6044b82ca3868a4752cf42f2596c7ba678723931cbc646e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a61c6c4009e28f6a20aad0c0b14b7cc0a01aeca507c366913ba5cadefe6656881b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +expected_public_key = a2685786391d97d3b6fec35d89553e3dc1289051a39501a814cc5efe04bda7d7ae7531ae70706277f71055ac32fa25abd26ac6ea6975d5a91618476d62e311a9fa3db53582462467b19a7a7f025a3b20a3b5e183eff249c855bdb3719d5934c3be5b64576b71ce525bb2874641a09c036bcab46684e6280b5806b74c4192d0a55a54a6329ee7715c88ac3f1112bf49b7cd642553b152a45366fc925a4f34c2f97646c51511c0c9899161914654c052a06c6311022023954c28bbcc22b4641bc327aa37f494383639aa3f8a4153127f28ba56837a198b604ddac05f82cb4c11834aa19637804c6643125c9465ac03516334679f36175b35c0c4da90797e7a0cc36173eb07b8c541ab501151d9331666267adfa60315305be5345c46f628746025e7959dbefa1fc0593ac94ace87fb515a03b00bc84b66507ed2c6ae4d931fd28186c396582a56a63cc35af5ea02e980ae2dd21badb02699d69e857334b1e96a5086bddd7152bbfb2c49a411085a94321a43e1491f0f0067b06688a5ab8d0aa17a9448004f25c1c5322b8d7b6563977fad0c70e7bb961ce84cc685aed34b25f0d30ec53a7a5ed943f6ea3dfc917b01985c609c995f765baa071b3749c89346805550ba19d958c535627e606b2f0c2706632fa466504c267dc7805e60a0680ecc158d6b4f75ebaa030292ed12cceab06d5c878cddca919050cc386386f5c8b3679b254959a06ebba5520646e65250ce8b7cca03227d1b43f49c9e9297269eeb64409712fb868cc47b406d9425868b6a304aa46e472acb0197a071ab9d1622861916cf31afc12466a4022a3a635ec89433635bb0afe2c5f73670ba532714803b1ed473608c5e00c1ad9fc90c91281d5e081692d85dbff0acaf5579e2b1b6c5c1b61c3579cd13a7c8011cf5c19709366bc9676cbb8b2271c784672200e6a0254bfcc9b6387d42993e275ab2da100301b11f7e4881cc5774d2f849e3d3ce63639ccf303a7f7914287079c6066525a4870b974d3da72a9290b96c6846eabbcbac2b730849a9b014100adb9c66d0b5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebbb136907a02eb5a351c94607fda4eb44458c9cb8b50da190e307fcd63885463523086036c5655e8e2621d4516a39084fa5b4f9744a921f497eee3a46eda05a4f1481ac5b4b819a66753b5b75a95640b0cfa07aa8a2033a8f51cc526cd1be8cee5677a78f18af9608da3a565bbe1a79c58691a45ade1aac936f15eb238bb4879af7da68ce2a106031a322c198527b94984a16d9b4a55bcb59e9eb4b2068182cc9b17a8cb2b8a776206b59258a2c9a19243c9925fb5d135604712baf09e2cdcbc6ed11fdd530d83a901f06c166130b912a53c075178195662d9212e4219c63271485ffcc9aaa6222c9aa2c4e64f5d686bd4874aadb456ed086ebdf151eea4be6bf57e2cca56edb04c0e68aa4deb1580d005d9da4fc1943c85f75208d0ba3b517f89a82a2fd8bb96ac07836391b2dc3b6b0533f0d91e170986cd245fa2a90d6a345679377b767086a1173dea82969fe3bfaa643af8f98b97a8432afa1a8c748ee7055630812bd2d80be782a726743627e707f7ba069931c9929b37a9b0b04bc23405e5b890700dbc419bbc635c12c390e0a8618ea01f2abc84eccca4b9f576664237355a40b7e931195b606c6759848c33a002b74b4706266aa93fdc2054d95e7ec30f1ef53f4730af8a31a757a55a9fc69765f67ce7ac0413dbbb12980028baa2ab2a378a55a283a6c5b73837f8462259c2aeaeb36c7be5447ea22a85a561e2477742c61dafebc969ea66ff992455db36b6029d863a8b896057251b8adc659f294707cc643a91f3aebd594b2d1c3c1168b474e011e7a280e316890d467b77732e48c7bb0216381ac8bbbf6a7d61b90c9266a33ec7744099b2e4d464f1a11e1d38883de5c89371585a2247c4b80110566817808e52dba03061848fd6338cf03992c1ab83f68a13e75c6565868dd419815a19983aa8d5c4123109a34fdcad5fbc3c37c87d1d4a6b1366906a97099df940b2564f00e37760786ef28c7896c09d04c0cd24820596e538ee3876b548667cb26dfb6073eaa5631b92c4bd05320c923b53552384d4afaa047a2241416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_private_key = 0baa531a985251b6b10153c8fce6938a280e93f9ace7a56dc7f44fa8bb2f88c09290888da8134a0fc43ccbb75b50b6a724d6812183acf876036dc252fc893419280314c7611750875821b2f3ac4f1c20b06365709bc07ad4161c94c41930568996f8cca58c4a0536cd5668488715593e66621f96c87a2178a36438dd4c390ca0532d30b88db712cd3c50d30baa91c98cf0bacf32c60c81468307ca35b47abfe59174e53467cf7b1d376758f1a5926fe225f0078ff288ae24d23241709e471624285c4fbd35a333088dd643cf6cb0ab6b27c8b679792ecb8ba4c28cd8b09677f0a7ebb692eca6777922c4ed6c20402533cbb9a3f1e0c10250209ef128a626b763b30b5e49c4c4691e3a13c2c2601b6666aba1d099987990bd1bb00ab5806390ce8088cae30a5b20567295aca7f0191cbdb4795e78bf150c7954f9a49880c218c23e59014620e18f18c536da0b7807b0c9e11b1e341c2e7e5ba799653fc669c1032aa014cb79769361b01091b5e000cbe100933c6d05714481f491b2355e72638831d0c4f4daa18c6b4ae6e825e688cb812490fa13b43d306e5bc857fbc18a61923f6b685e5fbb5be9c1871a9822ff07caeff40318482144143cecc5b0c579c84fc949ef359f0b24b20fc0a9f3300a3217a8058469c78b7998744024e275cd1c70a96a75fd86019ca031fec081dbdb796a56186d9a1df8c098940527d34a1df2db50b5136b6737829f0cb1da3b131ab238207a011f02bcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae81627011a2633f1c159c3870f7c69126b3c31f50d356888f9077fc207168cb075e0940fb7a0becc556de78089ed512a39a6adcda9c3c5126d874b50c163ba7b091656e52f9813cb318c87abab12a3f8996a4cb446d0793055ca177a1bf455cb956443e56c160f4788cdc6b008c086403bc910332d3e3274f9825e9964484d7a52c91c275e153a496801c0e6c8084b25b53c8eba77a9412291df78bd39895dfed82fd3c92947a1beab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5eca0c6b68090a338eab57a222fbb5a482837c097bd40141659a2a71d81e3bd38d60d0a903592b768b0ce60a7044350a75fb02f19482138603a9d8cb89ba6a32d37a15549548aace4636047d66ca4de6cf7643c2a5939478a39873820578150172f965d4dc6cc6d7adfc360568a53c97d268900b7b20122e50cc5e460304927333beb7bf73446064d76c3af1274b503203804774b00f02534772ccb83caa8475651460b156a7238da2a9847d445f55687a84baa06dd69d4a637efcc1c09f81bb97b541fd77a96883869731ac776913ed6c02ef03183b27b4655639509b1e8bba74837375628152814448f270b6dd865c888180aa071a2ab42740e93f05b32a9c85a069420be2ecc5335738f9d46c90c5af1625779f3a329dd693706618afb300b5c7099c220126c8398fbb8f32a2a35888bcaa187950365f022585c2e08243f53122b6c5ee9a95b84151afd10b2110135c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702e327b3e53555e24abb670ca6e505df0e0aecf7513f7e36374988dd8977a0d93af43a37e05a3463f2cb5f920b7fd117858380a96681229e87db5912cd91115bbc11712c690ac98c449e261bf959ce716ca4acc65704a5e93a7731d1a380dc9534a9611ed89c03e72210b1640fcac8003235d3f3a09da5b89c2eb0b7834142591a8a944a77bacb8ba6260ff3b0f434021502c0e97686c7feb6e3b6214e12030c05316fa89a474e49db8896284821f910a4490a40458a48ef0cb1639234c966609343a46c2f547aca939e4e471280c1009e34bf837180b8233a4a2901557b3d4e91b707414507449296ccbaec642470c8a51e6b7b759397f28c6e1163b0d6691322bad05ea09a4f17d3d19262d81b22c5b2009b80d3e4c23a33144e9cacf2dea1e496472e7e0922e4646c5f23c532a62a718c303e993dae41d7c1a2adb7c7cbaa8ad82b46f7784a71fe40d36681ef2fc2d1b757496ab547375415e5894f1a89d46a0206727570c8cb363343d0f4b73cbe08b3d639c79a808baab3791cb7fa51a546d39348e1a6e1162789c2a2a5890c3df94380e53085127c200b138a2685786391d97d3b6fec35d89553e3dc1289051a39501a814cc5efe04bda7d7ae7531ae70706277f71055ac32fa25abd26ac6ea6975d5a91618476d62e311a9fa3db53582462467b19a7a7f025a3b20a3b5e183eff249c855bdb3719d5934c3be5b64576b71ce525bb2874641a09c036bcab46684e6280b5806b74c4192d0a55a54a6329ee7715c88ac3f1112bf49b7cd642553b152a45366fc925a4f34c2f97646c51511c0c9899161914654c052a06c6311022023954c28bbcc22b4641bc327aa37f494383639aa3f8a4153127f28ba56837a198b604ddac05f82cb4c11834aa19637804c6643125c9465ac03516334679f36175b35c0c4da90797e7a0cc36173eb07b8c541ab501151d9331666267adfa60315305be5345c46f628746025e7959dbefa1fc0593ac94ace87fb515a03b00bc84b66507ed2c6ae4d931fd28186c396582a56a63cc35af5ea02e980ae2dd21badb02699d69e857334b1e96a5086bddd7152bbfb2c49a411085a94321a43e1491f0f0067b06688a5ab8d0aa17a9448004f25c1c5322b8d7b6563977fad0c70e7bb961ce84cc685aed34b25f0d30ec53a7a5ed943f6ea3dfc917b01985c609c995f765baa071b3749c89346805550ba19d958c535627e606b2f0c2706632fa466504c267dc7805e60a0680ecc158d6b4f75ebaa030292ed12cceab06d5c878cddca919050cc386386f5c8b3679b254959a06ebba5520646e65250ce8b7cca03227d1b43f49c9e9297269eeb64409712fb868cc47b406d9425868b6a304aa46e472acb0197a071ab9d1622861916cf31afc12466a4022a3a635ec89433635bb0afe2c5f73670ba532714803b1ed473608c5e00c1ad9fc90c91281d5e081692d85dbff0acaf5579e2b1b6c5c1b61c3579cd13a7c8011cf5c19709366bc9676cbb8b2271c784672200e6a0254bfcc9b6387d42993e275ab2da100301b11f7e4881cc5774d2f849e3d3ce63639ccf303a7f7914287079c6066525a4870b974d3da72a9290b96c6846eabbcbac2b730849a9b014100adb9c66d0b5c0e7877db476ff8a8ac947341d297c5f9697029439390a7e6c084ebbb136907a02eb5a351c94607fda4eb44458c9cb8b50da190e307fcd63885463523086036c5655e8e2621d4516a39084fa5b4f9744a921f497eee3a46eda05a4f1481ac5b4b819a66753b5b75a95640b0cfa07aa8a2033a8f51cc526cd1be8cee5677a78f18af9608da3a565bbe1a79c58691a45ade1aac936f15eb238bb4879af7da68ce2a106031a322c198527b94984a16d9b4a55bcb59e9eb4b2068182cc9b17a8cb2b8a776206b59258a2c9a19243c9925fb5d135604712baf09e2cdcbc6ed11fdd530d83a901f06c166130b912a53c075178195662d9212e4219c63271485ffcc9aaa6222c9aa2c4e64f5d686bd4874aadb456ed086ebdf151eea4be6bf57e2cca56edb04c0e68aa4deb1580d005d9da4fc1943c85f75208d0ba3b517f89a82a2fd8bb96ac07836391b2dc3b6b0533f0d91e170986cd245fa2a90d6a345679377b767086a1173dea82969fe3bfaa643af8f98b97a8432afa1a8c748ee7055630812bd2d80be782a726743627e707f7ba069931c9929b37a9b0b04bc23405e5b890700dbc419bbc635c12c390e0a8618ea01f2abc84eccca4b9f576664237355a40b7e931195b606c6759848c33a002b74b4706266aa93fdc2054d95e7ec30f1ef53f4730af8a31a757a55a9fc69765f67ce7ac0413dbbb12980028baa2ab2a378a55a283a6c5b73837f8462259c2aeaeb36c7be5447ea22a85a561e2477742c61dafebc969ea66ff992455db36b6029d863a8b896057251b8adc659f294707cc643a91f3aebd594b2d1c3c1168b474e011e7a280e316890d467b77732e48c7bb0216381ac8bbbf6a7d61b90c9266a33ec7744099b2e4d464f1a11e1d38883de5c89371585a2247c4b80110566817808e52dba03061848fd6338cf03992c1ab83f68a13e75c6565868dd419815a19983aa8d5c4123109a34fdcad5fbc3c37c87d1d4a6b1366906a97099df940b2564f00e37760786ef28c7896c09d04c0cd24820596e538ee3876b548667cb26dfb6073eaa5631b92c4bd05320c923b53552384d4afaa047a2241416718c51c97be1df9c3a91995d515b21b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc4576536d1bace29aa7c31f7681222ddd15a3cf6ea6bbd3528d2ec8610d68d13471600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +expected_public_key = 1a7c33d6425e068141b06c2ea57a010851a3b30ad021f6c0aa896e81f13f02d341faaba798a73a96d0b66b00bad5119a8d44797a1218b18224657573c9c556f5bc096f057f72fb749fe41fb9d290e76801b3712faadc58a1d3a8aaabbb996277d6902707a21ee099b5906854d2d45de78c1f134293d3dcced2296c5dd6b1469ac91c2508008951c7fc23eccb9a97f23501b21a625107a9c56ec39b724189ca111a935c3b58f262a29ff577f8459c74d9147dcb8eeb8689ee35aa131369cb805362289ae5973eff1420a8abacb650a1683104d2d82acbb28e54205404d68292f99c9c222bba8045769b73b890c33512c04af0cd86273234e31e94349a322aa13254484c3b99a2ac01f6ca00a77ba7b78711c73249eac054d34a1b0718814f407fd9d62a5d48212fb3afe5518e3a671bcf2cadcf4c8acb972603f960f194a4214cc8c9941fb31a6093a34c102ac18c26ba171a048d39860eec35e890149b9bbf510a4ff2270c72a507cd4a0500ba593841974c419a7ee37859a76f02463cb8303489e61ff21492afd03124368ae02c794642b7fe758f76219128ac75f19c41ab01adfa1a51b027c16e5b15279587e4f4a929f34ad51b06a060058521af6e4a24d54920a7e60c4174baec0b5fc4b498b23711c92bbba383556ea6169f558f5ad29443012c5b82524cec7ec43a448fe57d88c4ba220b56ebc2bf90a2471bc735e88c2e73a8771d669a1d76566ee80b78410d7cc02407091f4b6ac97cf2afbe67a02e445eb51389b8233080d42e74e20650a514f995395f8b23ece04e2a5930294b37c79aac8782ae62dc0d7fb60fff5c8d54e29fdda87562250a70038355a70d6bc0c3720726f0586acdc727d993988032cffcd5a9b909857be58c3b6a7c10041976a472d2bb7d3a0932a6c0cec9b68126b98b40d4041f5439f395cf6ea5213d39c69ac91b85696b009084e662aae8053df014720b5759c5f81b91f296bc4103c7dbbbb6248f87e8543e8a660bd6bbb9f81ad5721d7f36cfc776acbc8635e1910e4191730aa68e5e177d2d2234a645768d26cc069254daf0c94a09414a36a3d19ca05a5475378254ddb0890cab0e686438461a1d499aba23eb3dc2b61aa6a46c4afa2a262c6f09979f01fa1a98f62b8098be6416c6ca5b3f8ee79e28c07cbe2855bb64c88f67947a495e87f03361080cfa3c2aeb2791671729248b488278c72e85ba2dac1dd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb97e0274975323a7b20d27937f0c785152209060b05088243636039808c555ce29fd18a449a9a188afba922650f17102fb0a28381ec046164358e344fa250c05df6be895a5a0566b409f893e9d99cea7b3d71eac7a4d0081d951eb755cd39215c60c1a21de05217692bef3b8b4104608d198ab11c4c30941789919830cba4e7431dc127ac770957257c19eb80595ab9bb9d4a0ac266b7a37b94bc517139c904595c327f5c1430ac7d7e33bee0ba9c7bd7b266e290c3645821542f0e0a920fdb72707544a6d10c8a4c5a46148c2458b6c5ab06d42c2d7db03ceb0c00ca37303c67bae0038e0a373d539b918737116ed029a4d78a71d74f770ca53c9b4ecd19bfb172299c55a0cac83fcdc8c74400c5be76907679b48e0ac041987f96754588b83722b49159f92b41b82e6625a6108a957c34b2d0e30d536218acdc56a093ba9940c075362c1028c6ba42a775864bbbbabca70a5b7da5cf05821a9a81ad022784202362e587bce2a5b090530be4c51ef77a887af373637326f436c891304b72867dced161c2f0342f23aa15d69fa887652081a9c42b0669a689c5fa77649bab20eac8a16a51759ccd0f86c06c610a88162291e6cc1d911a88fa26e7ea4a23a224582807f20a8f1e2202a92495b6393036a25d4cd97fc72a741e006b7e919358f6ba3c5ab136823ceb955382bb6fe3f61b6228467f3c6f5de79531f11fe4f268b7f50f662c85a49b36a7213ae958a14e9bc45d0105ad13c591aaa7f1663301aaac45427da3c6a8873ba78e7c7473d41bd79534df8145d1749f94cc9c82377cb388129d0692f839942830c5814a8fca410e4cc754f7315fddc20fc1d588ac4c3cfe9c40277b3f6173809dc063f6813852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_private_key = e0c2121f06048fbc565fdaa305202d439ab3a81b31fa257aa6f4273547c1465610ae51c2c1c8603aa36d1575754a86c9194b1cc6a9b8c9f77ce6484c5198a193ea4369293798943f7918142f849c8d7479eb0588e6e6b4abc4ce81a406642414eb4137c2da905ce4ad2b750e7d966d34a3b1bfa8ca5c8070456b1f6d5b71e582c9e1e2bf9dc37ab60a09e797a43f66b27b04c13c034fa6f594264c9d7da884c762b159d775f7750a1862216e8bc992c9b2e0d18513f409df8b0811ea89d2a69b66d34e59bc93f5c7bde25140a976a3195541ee22a7edfb7f9d647616b31399b6c924022f036225af7c34e6d221213ab5f7a20b908325835266da1b456f5649b895bb032142fc5c700cfac4c2a44cf1f96d57b8ba1ef2c9332a612e8bb9043559b5567090873d3f9450f37670b473a96f812ce1d71892e43c9fe61fa594601a27a98ec817dd822c625b98e0fa8f2d5a311a87a6c23b4dfdf44d7511373e64a4a18a833d654a946b0da9694329023086013a919971cc4c8a45916901b45c25c28eb6051600644660796935e65a4700496bc32204201d5c8708fdeccbfe949d1339947c6baabcc67ec901659d220fa4d1a3da1a4adc2b1b323bc4cabb6065d9032ccca3dd3c8689c9a35810bcb30b99b3f55cf2ac8258c5b85c696a372c7aab5b0dd62aba06804466fa4c22b2ca0e09b7d47c4644898aacf6899c79b5321110f010cd40253e40c5920db980a57c01b55c506a6662be1253ff171412820272613940704f63e70340414322b69b60b50bbb4459c1d6a0f25065da032455598edf678505f54b51713209565fc4812ad5f8a05a926340fc3853719146d049017475a09a1fd2d47b35371d715c455debb3a40a8a0e83247b6b8ffc05b2e857b5d8b201e56c109dc155b720b2528301c49237f7a629234231fba25c75d600bd360796a68991bc68cafb5b0b7c748ab7039d8c4fd1b3b4de76c193123e50109ba70956b9556f245ccd4330b888d43a84714e8cf17e5713b5ae5a9fc3a331718c227ef4bdce131f31028d68529f06a218ac32317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d790b0fa67cbcf36c0372c056c268e0c243132db5de7365310f5732151b80bc98a2bb76f9e8c616fb1c90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834ac0f2ac00e91b32e4e7aab452249d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c85823928877954c28d052a2c116bdc325b687d26d1ccb3386cac9bd4c10c3ac381e056f9060c89e25a910c78e677964d153b74554c8f38939f881543f820b6f11989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c5400cb1bbcffd2707be12c31acc9b5c94b806b71dafab1eaaa087efc1419cd2978ec1b973336d27b69af2fa85f6c33b73770c0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a3528de99cbd7a875bb5b299c8a6dfe416104a59aa9e958e3828d3c651b5a9a7e81d7738374692033c4c68254d5170204f83a9b8520016466fd9189efbacaa23ab8f962af7d66aec2e27e468b9c326711673839541262aadc49bc135edd11792dd9678da0991a017cd1239df3c9b21c57623362bbc1182ce6000217f6ab0eb9ad6344ac71aa30048b7bfac20ae1e97559109e45b5a9fd052594b4ce4c5c73fc105c9c8b63ccc7331b70662015b5e36057b4c71e4a510a55eb7fb039cfc9a8ca4b002a50966a158ba7d4d21449ab67dee747a7588b4a5b107e15a817658cd56927e84816c07ab3cd968c425a3431f65e25496fffe96e29214445eb2ac1e78a644305a9724761d0c51ac0c19b0b4839c94bc2fb5dae888e0b797506806c2fe27f1f4280427a34bef3643f022d05866bac17595906438c363c4d53422d994370b1c8d2084d25e101830a57be5c754196b75db44e84800281db3829d8a0fb519ae7c3c854650d09e232d993af718501f28c292b59c3f0d50d50d75bac422dbf23ccaee4466556a4cbbb8d60932016d63f90e4c84d12c62e4b0eb0176fe7012530b5baa8f531608241116c17868600bde858f9a9bd6078165bb34fd27273717b5cc5d423f19caa54ca4850ac896e163c70f9140432041857521a7c33d6425e068141b06c2ea57a010851a3b30ad021f6c0aa896e81f13f02d341faaba798a73a96d0b66b00bad5119a8d44797a1218b18224657573c9c556f5bc096f057f72fb749fe41fb9d290e76801b3712faadc58a1d3a8aaabbb996277d6902707a21ee099b5906854d2d45de78c1f134293d3dcced2296c5dd6b1469ac91c2508008951c7fc23eccb9a97f23501b21a625107a9c56ec39b724189ca111a935c3b58f262a29ff577f8459c74d9147dcb8eeb8689ee35aa131369cb805362289ae5973eff1420a8abacb650a1683104d2d82acbb28e54205404d68292f99c9c222bba8045769b73b890c33512c04af0cd86273234e31e94349a322aa13254484c3b99a2ac01f6ca00a77ba7b78711c73249eac054d34a1b0718814f407fd9d62a5d48212fb3afe5518e3a671bcf2cadcf4c8acb972603f960f194a4214cc8c9941fb31a6093a34c102ac18c26ba171a048d39860eec35e890149b9bbf510a4ff2270c72a507cd4a0500ba593841974c419a7ee37859a76f02463cb8303489e61ff21492afd03124368ae02c794642b7fe758f76219128ac75f19c41ab01adfa1a51b027c16e5b15279587e4f4a929f34ad51b06a060058521af6e4a24d54920a7e60c4174baec0b5fc4b498b23711c92bbba383556ea6169f558f5ad29443012c5b82524cec7ec43a448fe57d88c4ba220b56ebc2bf90a2471bc735e88c2e73a8771d669a1d76566ee80b78410d7cc02407091f4b6ac97cf2afbe67a02e445eb51389b8233080d42e74e20650a514f995395f8b23ece04e2a5930294b37c79aac8782ae62dc0d7fb60fff5c8d54e29fdda87562250a70038355a70d6bc0c3720726f0586acdc727d993988032cffcd5a9b909857be58c3b6a7c10041976a472d2bb7d3a0932a6c0cec9b68126b98b40d4041f5439f395cf6ea5213d39c69ac91b85696b009084e662aae8053df014720b5759c5f81b91f296bc4103c7dbbbb6248f87e8543e8a660bd6bbb9f81ad5721d7f36cfc776acbc8635e1910e4191730aa68e5e177d2d2234a645768d26cc069254daf0c94a09414a36a3d19ca05a5475378254ddb0890cab0e686438461a1d499aba23eb3dc2b61aa6a46c4afa2a262c6f09979f01fa1a98f62b8098be6416c6ca5b3f8ee79e28c07cbe2855bb64c88f67947a495e87f03361080cfa3c2aeb2791671729248b488278c72e85ba2dac1dd2a8a3933a7c7d44cf69f959c5acce38daa6b796328565cb97e0274975323a7b20d27937f0c785152209060b05088243636039808c555ce29fd18a449a9a188afba922650f17102fb0a28381ec046164358e344fa250c05df6be895a5a0566b409f893e9d99cea7b3d71eac7a4d0081d951eb755cd39215c60c1a21de05217692bef3b8b4104608d198ab11c4c30941789919830cba4e7431dc127ac770957257c19eb80595ab9bb9d4a0ac266b7a37b94bc517139c904595c327f5c1430ac7d7e33bee0ba9c7bd7b266e290c3645821542f0e0a920fdb72707544a6d10c8a4c5a46148c2458b6c5ab06d42c2d7db03ceb0c00ca37303c67bae0038e0a373d539b918737116ed029a4d78a71d74f770ca53c9b4ecd19bfb172299c55a0cac83fcdc8c74400c5be76907679b48e0ac041987f96754588b83722b49159f92b41b82e6625a6108a957c34b2d0e30d536218acdc56a093ba9940c075362c1028c6ba42a775864bbbbabca70a5b7da5cf05821a9a81ad022784202362e587bce2a5b090530be4c51ef77a887af373637326f436c891304b72867dced161c2f0342f23aa15d69fa887652081a9c42b0669a689c5fa77649bab20eac8a16a51759ccd0f86c06c610a88162291e6cc1d911a88fa26e7ea4a23a224582807f20a8f1e2202a92495b6393036a25d4cd97fc72a741e006b7e919358f6ba3c5ab136823ceb955382bb6fe3f61b6228467f3c6f5de79531f11fe4f268b7f50f662c85a49b36a7213ae958a14e9bc45d0105ad13c591aaa7f1663301aaac45427da3c6a8873ba78e7c7473d41bd79534df8145d1749f94cc9c82377cb388129d0692f839942830c5814a8fca410e4cc754f7315fddc20fc1d588ac4c3cfe9c40277b3f6173809dc063f6813852e47746dc6a9898918a149f5355a8a4f6a7475a31ddb485fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdeea5db7a82254d19c0a0c552ccc92db9c3eef74cd73a9937b7b7298171313f120e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +expected_public_key = 0fb39b1e4b0c22871afffa785df48224d887a73cb9b9a68aa2a768b3ab087bd9cbf6253378885113bc6168d631121a5fad30cc822133161b0c39c0a2b30c5c33383555b415c6fb0588d16b3b890894026bb507d080f93e13327707a54725a3a859661e49184025f66f2eabc07c5072a21275440c9d520c9d0570cd4bf8752dfb37ca066ae450a3e5e6694b9581f6195b4b580fbf55b9f933c6f9867af36786fc8c24ca71b47127aa08798f99b113c1c661483a6ad196028b7752d9d4732622934a5b05c8b5095789999796039928b453e480f008a4bba7a49aa65462d71672450b56c441d2440fd4e151c9d0518d10534f24c1a355a5fe3aa1c4365493c7ad66f254300c373ac264b3339f3af02e2736b8023a270a20babe69cc15d494803bb515ec54719619bacac9ac2a58a4e67fe303ad9565b33c8472335710e0544c4a96bebdd98454058413db3bfc2958803a5963c725a4ca074ec9383dda1e892ac9e2210a60d19d5e4b3471f9519adb6bcb79c16742c07e933767ea4b20134ba8329c0c026da0e8a5e12770c8ba4ea7361bae91af0f953b47032da6640f202a8468a096bbe92cb8b02cd524b38a7a4c69d5b9818c8b88da78a7f2236746217a75a1f6e2805533a17996b7f972939a23c75c9023b715a714ac346f8102c2f8a04733495a4b456f179372202477e60b60ba210365274a393d999390628c7f63d2aa2b05cef68776db9150c39b6eca9ab32da9c6753208d74a2e7911af644a028d2c5a68494ea3da6b08a5b67d11090c587f580800e04c942445bfec357e33388a0bc328808624e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b350cb557bab3f87a05b22edb886812935402915e5ea51f41b70dea48aa2aab4f9f247d3f637efba51120a258cab867be231e67675ff29c83bf982e7b15b766a84cd9369ac28c29af664f5c7a7553ec9a0c3285caf26ce0b9c84d504ead34617f303f6d0ca807a7c0da1388f7407bc03c3111c8c87ee158e68b53ce8c668e8343b2303bcab6a4d98857c7070bb103c47c60cf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c38f028203357eb2a37967a60a95a1dd22b15f3d723f812890ffa105f1b9b2a238914f39975c1c0f49244e4db7728e15329f2ba8eca4cbe7b76029c9a6f721c72e27149807ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b37007fcf8486c6c5d0ffb3abed3cd8be0b87d1b2c80ab2d3e40949f94236e727b92e83a9ff0b40100b200b6519be545e893b60d09b881c2681d335f9f501b0910572645060bb8a141e910e6aa582f652ebaa79bf2f77b373459ce87c474213ef0257295abc192c05bf31ca3eb061648455fbf82710f8777636c229ef49c6986cba9816d11d636186b62d2b06212932e9e727954530182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968243289e1cc8460130c034b45660b3668863d719aa9c8e11df72084ae53c3b4d85a7860c42b2482c9a050b1065dda241b43ec996e368c6c7bcbab69a433040e56bcbd4f167a9d71c5d336234ba4a5e47a956459b4c0477b4780769530cb6c9b4a2cb6aa27423f76a58f89753196d8cd99107ec04741be761696c642cf6443bb72c5dbd336967c336672aeef98af9b203ee6f4096531034f890b1dd0862a0737777278167a2aead708533206b3624b906c57e4abc42bf61364e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f501104b9240cbc2c87b0531f6e008b38f1287be901af59a45ea19de5b2c4ce78ba4eb1abf4284ce0ea22f18c2a26f428bba481e54a1745702a8af06cab649bb5c7aed2342413157a811a35b162b6f444cf2ddb22a24bce8e2925d83313d0b760017b65b8867419c7a1f57cc785b26bbed63ec79b83feb60674e2497b87be24aa1f899ca59d6391c1f2ad9aa90806fb1c97dcbfe5b9934ba169386759532b1117115e77884623c84cfee522bc0735e1f34eaf4b452530418f652e6f15cc3cd88a52e98078424d486cccd38272a0819887d85811e6bf8dc3689a3112b1b86d77d2bd91a53d123a11b6eb4ce3a8471c35126c017053c8a8f46054bc9c92752631ab8a9100b04f79e14c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_private_key = 25933617206ae881c4de291b4f269f2e51897ff29d3c6803e1a4c58e53051e879f1af333393c75b366cfe2e84cf9cc930d1928298897480571d7050751601bc119b1071412efe8873ad325bc00420d13a752d33087bb6f884628def98f4fd21d01113219203f93419875c91cd33c7976b7a45f510f70e6002957ac49b862cd35640ce84e6b989201a74eb76422f88b31c94acfa811605a32634199be1639a50b709e89683c5cb0c975d627b76223ea48a2352c8bcc254abc60812a6a5ab7747ca82073d1d31fef708866a9801ad067a6da0d848c409861c350db559a0ab1d91c9be0c149d6c241a13849d9eb2da4b9b9b30b348217491449a43ea4544467824ff954c4869c8dc0b2ba2744c8d38ba584cb78ea6f6188bcd090267ba46882f16964aa003e2c60105415f937cf13b9cd00456d3545bc5e48b6ddf61a14eccbac23bb1d071bb14361b4c9acb7b48805b7890c3676b550238391b388260cb0e2567f725b0382c7174440d82ba8a6d226d325cdd1c26abd510abb195b73d203f9db7db44abba87581a3c57f079b44a9455e3fa16ec87a0cc14368569b35517272220ba7760a8a0508bf0033031d42763fe89b611366b8b93d2d523d5c872bb99bbb099515a5911f1182404b7b4ccea91462c6a5abc16c64f55ab38a763a03ba48e0268819b6df8ba88704ab4c7bcd8f8a150ca434ab0632adc522a49c0e45997375d69901416792f845fcbc1a18789b22870401d6872374b15c851aba4c3cf5a8930d34c74fd444a2c87f90d9353cd77361e26c99c8027b50504bc5b3f2bc27f3978822113e13d71e19e3915a9a4f0646aef6d513e155b41237b2ab08bdf38322bf4c00706c0f22854d080bb8ecf58cc9b75d19a0185412a74b3c7d61a04dd8cb07bb37156c46221a7183beb9321c58a924048ab86032f54815da1bb33ad4312391c1a6778d9070b1a4542aae231aac97bb5e1a1cf42792c9921313c07aba3a8c15db5d1be417c3888a2e0921a7aa1926044ab865935a2738b4378484b44471da250e41925e976beeca9f93d191b0c85b487badfcec4be7c7683c508412e096ae888bafb97cebd3266ef7397004cc56741f53683034fc3160522e6bdabad190c51f31926aa94b2f2a4506d69705623e3047176b46169ab8a715b84848bb4fb9830be744cad7591dd8d128c1a40f8a5b2829a92177d73cb1f319c0f45557a69ad790c87a6b8314e618444081c221c07c4ba5c1c450b8080db278770a0c110dc386fb8411d4b983503964f7b6afa10ac5154ccea9e6222b4a70e5175f125b0a83010474311f8ef84fdf3aab6d508b313a93c29675abe12cde50bd4b5b7e13c7228d9ac9df569cc1bbc995eaacbc2290b0293a2bba70ae8757c5a7ce84386093e02b3201573c56bcc368a7dd404371453c38823ba4752edb663e5fb99c5e91ca9ba94caebc9d60a6318cf62168a86c0c419cad1bc4fe514a745bb2c81701b89ba371cc1f10b50d95086d99778383108dfed849a1f74696464aa1d67f7f40bbc69c1fd907696d6227cf20750d68a3d36c600448c91a523a16e5c84b40819bbb2bfabb2cb03b658fd0656f410752f52bfc9bba4a3a8d09d5835b1540f5dc673df71540f560d411b562f2b047e195e5c5baae8a93147c41d8f282128b8c455100865ca55516709ffb8f33d20eda56796324b6f3b249d982c7d49a84ff076be2187dd4a51efb5592f9549a27ea274959087d3c2a5e217ca3b73391505de8aa664288b95926ccd8028bb7a7c24562cf2ae14fbab852521978dd05bfb52885d8c86cdb6a8df1755f8ad12a7bd7b00b2a7bfa49693646653d1c50fe826cc9c39988e25d316975cac26108e5b9570979dea5843200c346e4c360e0b0f6ab71397999f4ab2f7af368d3218093d1c69853224f016fa11c408acc211858bc53c62ac6d395898b9a02eb0f80e5284031b39ad5409d9c28ee549d45712dcf080fc6bb5b08b526a615173f543b10baab4f9254ee7b7690c758d20861559c1fdff88c10a14eeeb2917fe47af7e63259c1154cdc4df1a56afec68855fca341451ba7f617e9595f009b0ddef81741d78bb2851c3bec505c070a8c9241e54b2a2f661b06323e62365a90e7b5d0d10704a184b1d5782967122d9864eedc852e592862dc868db21f70b83d3a482d0fb39b1e4b0c22871afffa785df48224d887a73cb9b9a68aa2a768b3ab087bd9cbf6253378885113bc6168d631121a5fad30cc822133161b0c39c0a2b30c5c33383555b415c6fb0588d16b3b890894026bb507d080f93e13327707a54725a3a859661e49184025f66f2eabc07c5072a21275440c9d520c9d0570cd4bf8752dfb37ca066ae450a3e5e6694b9581f6195b4b580fbf55b9f933c6f9867af36786fc8c24ca71b47127aa08798f99b113c1c661483a6ad196028b7752d9d4732622934a5b05c8b5095789999796039928b453e480f008a4bba7a49aa65462d71672450b56c441d2440fd4e151c9d0518d10534f24c1a355a5fe3aa1c4365493c7ad66f254300c373ac264b3339f3af02e2736b8023a270a20babe69cc15d494803bb515ec54719619bacac9ac2a58a4e67fe303ad9565b33c8472335710e0544c4a96bebdd98454058413db3bfc2958803a5963c725a4ca074ec9383dda1e892ac9e2210a60d19d5e4b3471f9519adb6bcb79c16742c07e933767ea4b20134ba8329c0c026da0e8a5e12770c8ba4ea7361bae91af0f953b47032da6640f202a8468a096bbe92cb8b02cd524b38a7a4c69d5b9818c8b88da78a7f2236746217a75a1f6e2805533a17996b7f972939a23c75c9023b715a714ac346f8102c2f8a04733495a4b456f179372202477e60b60ba210365274a393d999390628c7f63d2aa2b05cef68776db9150c39b6eca9ab32da9c6753208d74a2e7911af644a028d2c5a68494ea3da6b08a5b67d11090c587f580800e04c942445bfec357e33388a0bc328808624e56979161c3c7ad3bed206b3fa7ac6befba42d067a1b350cb557bab3f87a05b22edb886812935402915e5ea51f41b70dea48aa2aab4f9f247d3f637efba51120a258cab867be231e67675ff29c83bf982e7b15b766a84cd9369ac28c29af664f5c7a7553ec9a0c3285caf26ce0b9c84d504ead34617f303f6d0ca807a7c0da1388f7407bc03c3111c8c87ee158e68b53ce8c668e8343b2303bcab6a4d98857c7070bb103c47c60cf59049901667b3a27b0187aa53008cd1a57c0f2465655d8cdc03494a6074c38f028203357eb2a37967a60a95a1dd22b15f3d723f812890ffa105f1b9b2a238914f39975c1c0f49244e4db7728e15329f2ba8eca4cbe7b76029c9a6f721c72e27149807ad9536d76a57cefa39eb1d93700555e324ac5149a45793667b37007fcf8486c6c5d0ffb3abed3cd8be0b87d1b2c80ab2d3e40949f94236e727b92e83a9ff0b40100b200b6519be545e893b60d09b881c2681d335f9f501b0910572645060bb8a141e910e6aa582f652ebaa79bf2f77b373459ce87c474213ef0257295abc192c05bf31ca3eb061648455fbf82710f8777636c229ef49c6986cba9816d11d636186b62d2b06212932e9e727954530182483110958b99b4cd692944b2b87b618c6cd7765336e4642d6950a5c5642daa8974e498ee2968243289e1cc8460130c034b45660b3668863d719aa9c8e11df72084ae53c3b4d85a7860c42b2482c9a050b1065dda241b43ec996e368c6c7bcbab69a433040e56bcbd4f167a9d71c5d336234ba4a5e47a956459b4c0477b4780769530cb6c9b4a2cb6aa27423f76a58f89753196d8cd99107ec04741be761696c642cf6443bb72c5dbd336967c336672aeef98af9b203ee6f4096531034f890b1dd0862a0737777278167a2aead708533206b3624b906c57e4abc42bf61364e550326a62d4a74fe889ae41839820fa6fb487569f53c1851734cfea5f501104b9240cbc2c87b0531f6e008b38f1287be901af59a45ea19de5b2c4ce78ba4eb1abf4284ce0ea22f18c2a26f428bba481e54a1745702a8af06cab649bb5c7aed2342413157a811a35b162b6f444cf2ddb22a24bce8e2925d83313d0b760017b65b8867419c7a1f57cc785b26bbed63ec79b83feb60674e2497b87be24aa1f899ca59d6391c1f2ad9aa90806fb1c97dcbfe5b9934ba169386759532b1117115e77884623c84cfee522bc0735e1f34eaf4b452530418f652e6f15cc3cd88a52e98078424d486cccd38272a0819887d85811e6bf8dc3689a3112b1b86d77d2bd91a53d123a11b6eb4ce3a8471c35126c017053c8a8f46054bc9c92752631ab8a9100b04f79e14c74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d21972998cc3abc79487ca0a4db5b17514e9961916d30ab9b500430ba748c5c7922650a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +expected_public_key = 319442d0786cba94aa139895eba98bff419a6b42644b68c5ce534b0f705225f4a7b28cbaf879b30fb633fdc2aa70c54639f180e76b927ca4622f086601a62afff5335ffbbbcb52075ab7681a55625e01cb31248e17708b7d728905b64976409d49583272fb6208e06ed7539fc4f87b1f0b821de4155b79531546824bb4a13e09cadf66b7889c6baa9679df6187690c9fea246226a7a405b997c322b4ab041d7fc0b24ab54400813a29c87204ea29414a7c80ac65d374998494b914467f44241251402adfa34616b021caf86b2adc690267a41c40b763c11506b658132c59c0e887888a2d5a8658bbe403758c84cf86611026a5bf802ae4e5031771c42d047ef42021a7c59c2c0a6e3f10b9adf716bba29d824b271d787379021ec44b4b39c3493bd980bfcbba73e5772e259ccdac1f062a887cf25887c30817da33ac19c2527239e7f6b434f0affd278130b1a480348aef2998924c684e3ca8f49694dfe149152b332128061c659cf2c5861ca003d1e8bf33dc06b197abfe2862362a9a15fb35f6009481d2a79eb18826581abcba4bbba6846238c5edf5b30d6830437714addb5f6751a7f6d79558148c0db07a7b2a784dc78c8176a2a36b4dbb7855602742ec2624d6c6c589c515b5224ebf92cd70b954c5190e4212a0542857a16cbffe060f56140e4f3b2e03b86ab0c8cdee1a3e2e95cb43c852c40b6cce660fe61bc7631a849ea28e6c93203bd55c4c4928d6ca777023264d2b2f96f99f3bc9b23d51ceadc713572542eb00b77ce79b2f0ac533198a60f03939ea1502e09807b5a7c19ba98396167b116c88e889b022195b016c58125de60708890793bc582717253b6608b0933b0b0d160c42bc3efb602e899555265189dc376b15c04cf5348753344f0e8349b4ea29a6b85110f81c247029ffe93ec5891194963bd9aca2ef5a3e912c255e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d4331ad5a30da5a57636e75f4900285b927289e7ba510216e73189b6d76db21c600e8c26488449041529700539c42195624bbdf1c19eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a645862416fbc92df042baba25ff1381f3c09b79e2c89410625462018ed38a8480afac4a313da239ba44090a7aa296c304dae24030db60bd376ecb7779f2f2414d144e624a9b0d2bc181268229ac1f92929d61c15250730d58b75e663a2a175b4b98a906c3871f1f9a46f0e842c7b48238722124e7c2882b7831576a03b1ca105333e4b004bf286e45d3a9188757faac58e8d995e7101129fc560c9021ba159d748619204b7963f957e7410592028f97d297e2a8042bb8b342f1cf1af6a843a1598b1a0e851cbe6452842762109eac773cf58fbcd5845545485eb47be86bb51522273bb7782223b855c221de3c3ce3290c3fb4c9dee73e23c06994fcb437a93ab885230ce5521f8224521a6ce6c5ac8f682353ec78f22cb133c1c48aca73a461aa128b96590b2b508832f9a04a1099b7775101fc349b6a686b9cc3c7954567f1c605ce1543a6e967857a19678b5e6a3b996fea65336794d36c3045a0ac514962c79a6b03342b2ef826b4e4a2aa4b8e2d66ac920557915058c551b82bc0134dc489d55742b59c143b88ac8903cf6ca8aec2c784c1dc15e3b46ea8d7bcd43ba3161564b6510459f7956949128d6373c1ea8b41b92396d124b3b978325b1d21c290b76a1504a01adb164b3a6cb9bf5422a6b571f209a4f18c31c3a647d8e3cfd335067c75308026c40c5ba20dca0317cc6954341758274330f35df38abb5f1b59806a831979bc985576ae6a8df2608d6305ae2f7406f347cff1415de856b859d8306271c716495ec273a2c96355e195326883c4f024943f54c35f0003e70c9dd5c412f6c260f18a6adf1435150abdf28084cdb13685881aab0c710fec5272417731a65eb9360684e170f6c7a13310686471b0e91b2002b789a5a465128043ce6b7c29bb5dba20200dfc69d242823e477e34e146c828022d78c37b8c8fea50294586cda2f728d9b10d0cb58e1b091b68dcca95e6ad22416e1c9a7b0a75047c72309a284426fa98b3c905f1491a44d1338e0cad6bf2ac3c845005c268eda736b1c997a64438323501b6ac5628455694573afd782ccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_private_key = 719950ed1960ff6c2d7d59bbecb83aabe1ccb569b76cd9b053389c552cb6bf847cf4fc1f18a03e66f02cdb284c15d656151644f78caeeafa8b12cb7c616256c032ce6112735a74285d66a90f3a745ed8733c195f6b1b9b272897520a02fafcb958a9669990b73420bcce373acf5a1c86a555c3c48f78166c0fbb023c49608592261060884b408c9fdb1f4b023506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa32c01ab64a6ab7491d50303b4e8a134086110d220462395b9d89d9651205aea9e1b88bc80c4c8bac44af4f1886ea788a0b259dda78116051059853d2cd073ed8cadad9ab04f7175d57c3224e953509588e788713d5a6714d0aa48e972f4fa55f16579d9bc6988f562ccf1286e87aa785929bf8266d7e340022c0221736c3cb372b85723042382092545a45032eb727bdc750449c786145acf42b85d4618b0d6f009d0224a816620f1db67f59713090b0849559a51b9589532ce2dc25df8f09aebda932073a2ac2115b12c5f94c64750220d645b34c14ac1b2208565377d61426d7f2a25cbd969a2705ea330b676ea6eefcbbc6cd40da9c0716d147b398b7d469a919d83baacca80f0e41414382804b0a321362e14e766db2450f599963cc2899e1048d839754858910d12c23f99158a9a3149362690a9c5540133e5f217a7b66b0d627321c810f7d1639cca948d708616047f85ba41cee9211df72731ac0986d1c3149854b71683faf68179799b12c031a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c048359481ca7a45cbaecbcf34407d8e378733f812926599df5c156a94945fc7911db26bef17074470a7bd6b60f771cc3f396e847195ce26444b641f91b468fa1670d0184942472667aa76e42976fac48e78da72ef0c207fc7400f92699b46345e4c9972a35daea31adbe87980438de4f211b005c8dcec1a6eecb56d891677f9006c49385e8ab20a19b74325a9a95083bc711537480db30719815352616b2c5721979bd4267fb134188a75b9cb303215a76a246d8f69acbd173d069b2b99b727829aa5469a0212c006a88aa4a6b614674674fa75500aa294711c178b741b0275280bda27813647a5dcac3a258991db4bf436c23f37c697115143a2755fdc199ff32b19209d7ff904feaabff7383884c1bae3c0cc20d019066653b99c1cafe366567c9238785b0f0b4d1432a9e02ca2d9a3b37d84646b157684d7ac720727af4533749a9ff99bad8f3877dbe5cff9c75b38c4002178ce30773ee36a14f1497ab386cb36420f04d85c8312ce25b357d3108226925f6b85c7a3729064f81aa66336163c00506bbfc82030f4f33a5be7330926bb3f849d1dcb09f5cb814ba8a722506d0a037e6eb26216aa3c4d4c05d5cbcf0358501936ad2beb3563c341e2315de6d68404acab0149bafa84491ab67a2dd82972220b0df528da7c4d441c8cdaf508cfa2c0224932e7e5215572aa433c9212022899e43a93cc7c8f4aac6ed5acbd0162e4da4b897b7bdcd72a0b2a2354f61a6c211089c11e476715f3369859c3021584b6593b5784344d53b40da0725a90804c45d02f6eb7670071660478c53281b5e290bfc77ac46602b530b1300628a7a4f20ce22768edd699c6bc5dbdf66064041e42329605e06dcb94207211c7bef41eb150aeccc90725dccc33eb762a92442dc02ae1555cf726a915240508e227e270a4932636a2806d8a5c15a40a3206ac91bc8a3cc7245f7b5b0438fb3dcfd112dff7bb01120087e09abf5580081008d43bb862f6283726992523acb1dc82fc260e64dc395c778d8ea7561382c9918b531cb8b0fc8b7a5a9634d3a7349475a8a117b0c2331ca0b7cc8e5a92f609b5b558435e15509fd78ba747be495b9e78ab178b03c117d4c679d13d5b07b58eb675a72a646763a9358b61ee31b1156866cfd7ab6e7498d3e5ca92799fda467dbd103a5e717e0f6b92a815546f8c221fb2c337e86142d8ae205594bb2c93e50b4503c80b5ab3a19de4ba63d918343260b5692296cb02efa77ead006bcb99013e317b5ed802e8e5209d87c7e584c1de051ada436044caafd0033f51f649d275a7bbe4455ce8035a97945f597d03a1740dc576f0225b8cac3ea76c49f5d6a183f3853138becb6949a158a5ec045512b74016fb841c8881035448319442d0786cba94aa139895eba98bff419a6b42644b68c5ce534b0f705225f4a7b28cbaf879b30fb633fdc2aa70c54639f180e76b927ca4622f086601a62afff5335ffbbbcb52075ab7681a55625e01cb31248e17708b7d728905b64976409d49583272fb6208e06ed7539fc4f87b1f0b821de4155b79531546824bb4a13e09cadf66b7889c6baa9679df6187690c9fea246226a7a405b997c322b4ab041d7fc0b24ab54400813a29c87204ea29414a7c80ac65d374998494b914467f44241251402adfa34616b021caf86b2adc690267a41c40b763c11506b658132c59c0e887888a2d5a8658bbe403758c84cf86611026a5bf802ae4e5031771c42d047ef42021a7c59c2c0a6e3f10b9adf716bba29d824b271d787379021ec44b4b39c3493bd980bfcbba73e5772e259ccdac1f062a887cf25887c30817da33ac19c2527239e7f6b434f0affd278130b1a480348aef2998924c684e3ca8f49694dfe149152b332128061c659cf2c5861ca003d1e8bf33dc06b197abfe2862362a9a15fb35f6009481d2a79eb18826581abcba4bbba6846238c5edf5b30d6830437714addb5f6751a7f6d79558148c0db07a7b2a784dc78c8176a2a36b4dbb7855602742ec2624d6c6c589c515b5224ebf92cd70b954c5190e4212a0542857a16cbffe060f56140e4f3b2e03b86ab0c8cdee1a3e2e95cb43c852c40b6cce660fe61bc7631a849ea28e6c93203bd55c4c4928d6ca777023264d2b2f96f99f3bc9b23d51ceadc713572542eb00b77ce79b2f0ac533198a60f03939ea1502e09807b5a7c19ba98396167b116c88e889b022195b016c58125de60708890793bc582717253b6608b0933b0b0d160c42bc3efb602e899555265189dc376b15c04cf5348753344f0e8349b4ea29a6b85110f81c247029ffe93ec5891194963bd9aca2ef5a3e912c255e3c53e908c1adf75453075fd9f956a4ba555886a82a03a29cf778d4331ad5a30da5a57636e75f4900285b927289e7ba510216e73189b6d76db21c600e8c26488449041529700539c42195624bbdf1c19eecf8bfcb97a62eb46468953669b380de5a3f84a962cdf3573de9c4f989a645862416fbc92df042baba25ff1381f3c09b79e2c89410625462018ed38a8480afac4a313da239ba44090a7aa296c304dae24030db60bd376ecb7779f2f2414d144e624a9b0d2bc181268229ac1f92929d61c15250730d58b75e663a2a175b4b98a906c3871f1f9a46f0e842c7b48238722124e7c2882b7831576a03b1ca105333e4b004bf286e45d3a9188757faac58e8d995e7101129fc560c9021ba159d748619204b7963f957e7410592028f97d297e2a8042bb8b342f1cf1af6a843a1598b1a0e851cbe6452842762109eac773cf58fbcd5845545485eb47be86bb51522273bb7782223b855c221de3c3ce3290c3fb4c9dee73e23c06994fcb437a93ab885230ce5521f8224521a6ce6c5ac8f682353ec78f22cb133c1c48aca73a461aa128b96590b2b508832f9a04a1099b7775101fc349b6a686b9cc3c7954567f1c605ce1543a6e967857a19678b5e6a3b996fea65336794d36c3045a0ac514962c79a6b03342b2ef826b4e4a2aa4b8e2d66ac920557915058c551b82bc0134dc489d55742b59c143b88ac8903cf6ca8aec2c784c1dc15e3b46ea8d7bcd43ba3161564b6510459f7956949128d6373c1ea8b41b92396d124b3b978325b1d21c290b76a1504a01adb164b3a6cb9bf5422a6b571f209a4f18c31c3a647d8e3cfd335067c75308026c40c5ba20dca0317cc6954341758274330f35df38abb5f1b59806a831979bc985576ae6a8df2608d6305ae2f7406f347cff1415de856b859d8306271c716495ec273a2c96355e195326883c4f024943f54c35f0003e70c9dd5c412f6c260f18a6adf1435150abdf28084cdb13685881aab0c710fec5272417731a65eb9360684e170f6c7a13310686471b0e91b2002b789a5a465128043ce6b7c29bb5dba20200dfc69d242823e477e34e146c828022d78c37b8c8fea50294586cda2f728d9b10d0cb58e1b091b68dcca95e6ad22416e1c9a7b0a75047c72309a284426fa98b3c905f1491a44d1338e0cad6bf2ac3c845005c268eda736b1c997a64438323501b6ac5628455694573afd782ccaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545ebe9631b6d4237dd6884ae3647dd8622fc13d1cc689f3c8ed94ec6bcd4bbdb6980f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +expected_public_key = 8ba428266b1dbf30553a10aa6c5118f85ab9daec1c521639b686bfc4b198c511939a039982cc774aa074d391bc5137419a22892005114f3132f22497ebc5316e190013325b2c0c1f23ac61ebf6875640c7f56c78df4937c883bc9da38d1f709a6df68026d8af0ba51f1f2c5ff0806cac1a396a7272a4065660906658a25c570c7067d1972417142b0b6bc244b8e52b1b7a4b915832486f8a7486230cc63a981b195431448671e71c38527effb2768ce1574baa6a23226563794e714c1c7f75c05fc4b2630a47ae24b2a1d3141516941d61a58b609808612064881347b4765e892438eaaf1c538e0baca4e6e1bb38821633a385b7c1cd285b6edef2739a675110387e6ec747016a6a1007c87949368d31cb7a63a50e210ce168c825b86695223fc1b8789bdc89545a3394f9c1bd943094546f640b0b129c4e78a9ca0b8107bb18923ce669da26268d57c7eee01f15d0454cb1cb7af05f2e787833bcc4d4996312c82714043907b30a8d250ece8aade970cbe463494e759f463131c12b636503c747f64249d2687b3301387620307503d9562e5a033d86eb23546b83b0f70937fc6b70db7c1d519fe1ca0b93137a41d89843a635fb5c389d420558746be267440e8aa996124ff97b163eb828fe492e96a367ee7c22e2f4031c44688935b0e6439776e34c2c525a31664386a5b6040116d487846f538e0da71fb17a750d4b0b8f4c37ba859810a8aa15b573eb029c8f7052124bcefbc48dc60743e7a455a0c4cfb7c57847c50afb1b5725d735d013441f7b1b43d93840cc4373dbaaa71035ae110955d9cb60ba5b5de5999b082335ebc1d3d5b6a6681e2e4714423b50d30aac28a4006869a85941247f0a8f8da236421b761315b6adacc513f5ae525373cc57482dfb15286546d106925adbc71f4cc1bd33641cf63035b7c02669ced392b0b8c70e776a768f859c04e3b1c1f05d9a909025f075bc0021b091b0bd29ae7e7c787a0a570cb99f9337986d714595023b53147913b72f7df50b6421319825304af61ee75765f44581eb0378ecc979f81950437ba7603b751dbcaf1261a17346cdf645a65cea895320211089a07101bf617b731e38a8114335e3267169d060a9c09e7e829d0168a21bc580087554a17688cd742ef7e4a2510779b666a2b613bf81d8060e06385398babcf2ce1ae7abd2e66ac06142a2f73598ca2a1ff769923a0aabcc22268710c0a2143b96269bbace0f69a25142bb9f1a0c05266003f7a69ab405dcbb3360290ba355c8c6f5b1035697865cbecf8a20209019ea08b6416c86a098af524a2dcb9b7d16253960670ea96897b406c5680b14de691fa5305405f35048865e549c3847b3bf01856a15a25dac28c5afcb6be3e8adaf3689a0e5bb056b000a1308ac643ccd94c28711acc4653b52cc87c7d6bde2dbac47678ddf7101484379de232cae6975b4ec02d6a043ae14a53632ab428666fcd98b9f702432018e783ba3c7d32079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4baf2a4083a91e3d58e89270ef4560669d555fb0444737c6dae111cd1e18f55f1780ca0bb8e7c1ac3e7168d0c9e4a515ca4f11c49c967bd78149af3abc3e692c4659b30851eb86ab41d575021fb146d60069d242569d111e510b731724e6eb456c5428754db8903f31b365c7aa9976c13210438b50ea3e778e5a60e25f85c42bb10b24b72bc820300c91547582fee167eff958894e4898c198a4f652f871c9b03234f98e7a237778c679b757db3225394a356991b2810cc6ca5c7ab888dc9e59529f3498ec40efc47051c03c75225187da36d3daa9f3f0977da80a14a13a990ab20dd415c2036003ffab31b7aa534ec7cddc40a9877ad6cc61d07b7b1d8b71db1d1a2b71923337532e464853357400aca0f6a883ed84b56e77b755594b7bef178115b18c68175dc2c390d462ab641ba14d80b1d36cf290c6afa532d8d7091da94703cfb7334d667f0e3150b60ae8bfcb56dd40e3a58bd4d09a5a3e8a167841118a51490a126d6b85ee90a7f3d5432f59635b1d5587821818afb74ce42569751512c9840f364b6370cb318c1677a304be1a2938234b56bd2632f768a93750158e844df96c720007228c2829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_private_key = 4da026f053c3ec1712c7f294dc891e26196894a1b620f97429574edee9568e113feb564d89a1883d5a0329929ca57ac001925c8d616791842dcd291627d61c7c2c3f842b547f074f46f082a06bb4282323a291c3cc07904079125cd5a854168d83ba8ab6b160b5e1881d25403b297c73048e3298287f51529a8ba2deda6b4d7665a373171b03b1c0baab6482c50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2ac0cc80c9d248b97ddc51d00a10ca3324fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48faa514319b8f9a0491f9212da443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995ef2aff817907de5c66899824889a760ca4a38a57b3afa880a3524e138b37487b2ee7332d2689f99a5a3748020fbca43ed6045a5aba65f6c67783cb74c217ba987ad381938b4a651b6908fa4f18e6d073a6992160438ba3c9547e4557e1e724192414c912648d25907bd8b069c845465616969161c483927f5d610c815638e242323465839d36a8149bad494b71f1336a3f0a954369d4265b6cab935f06694c482b500cb77bb32c4d805a295a692648a31611b206d06c2e86c61675577053a747bd3a748f452b480028edcbeca8a10eb843ea8a71e21e9b822d80860764d8c5a77ef0222f8004c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe59027fb424e6c580cc3b41c041984ea552bdd6396d52867887430a2534a44ba544a0b285c061d7d6618c76945a5c3b29bbbb09a724b1ac53e5954f66708c8c0b2d7da57c62fc8b80e73d737741f9141f7164b4eac08822a4c340b5b74cb5c2d407b9d63365c55c14c5e6ab43a8bc68908c34074a9bf4816e000ddb464656c379fdd829b6961c22e5345674243ca64705212d52e616664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1af828bb26263a8a898bf3b7b0ed07988e82dbe3c0405d46b1cdc37600570fc37ad9b2237e3032bab1a0ae420b6f011a653987305aacc8876ac4d014b7e619227b8b35ba2616c9575506870fad2585549a2f902b185d7a61139c027912ee2a00ee460328b16cceeb259149a0881f8152d563bc0243302d29fb98cc57a45369517640bf0bf63a555a900269878c4ba567f8d376176d6941d34957e1373b7520483394c3606089d14aee0917059227bd848bb22e088def4194bfcb36eaa81d4da713e37be79e52f51ba2c32f05d06405947838625e49f5f6bcda5e683d014a12fcc0c81601b52f80c39b6659606a8fea82c62e061a939cb4451869922083268561e16381b026152170104e11f30b2399f4097b94078adc66f23f85ba6651e861237700bcb1ae92e2bc652cbf19bc0fca0d7f7577c9c96dbc9b8b07b917f258c15661da17621db1287ebaa7714a54052fa660f034f227198ea14c2467b46cf9877f4e0c29962992b560a7db93c8ec13343f734d86bc548246a57473d1285463d0942f288245d933ddab7a09766a9f8c178ef539f9ce9a0e97364cac0366b5b08b4c1b081e01d198c2aa5288617a50019eb3a40a300af538119d733f2544d18b9094f387a3f4c17baf01523f1453f68a916436c8e6a80cd05472de7239ae15dbd52144a9609c1017e88c1a3fb301323b060242ac803133c9bc50f67c436de804e7e7b54a3489e5dec22c83a982b45160108535ea7b588018b0d3b0ccbb613a0716eaed8b61912073cf728c747bfc79741616750b8373235408aeca1abf7e09e72cb181bb09e8c31010e3ccd05db0f487c8a29c4c822c59cf447124c973f57392865ea82af9a15382bb68a708a6ce92e24484eaa252f97635e60d4bcbc8a403dfa166fe5c6a8500332624122a15e25d5041de8b88ee92e1b1b0762734e63ac80ce9227c43980d8bcadfe4caa420045b26173b6b953e3c97c7f655244d534b2963fabd264a33466dd79440f4361c8c77f1afa0a8f31c183a369993494480cbf7d13308bd58e78d88a53d45044026c7b620e0e8a7124b957f106aee02598ee190bdc68c53af48ebc5436adf0bf66227f2089aa4cf461f2d7bb990c3e530872c9d157a839a15b4ace0b2895fdda50d3caa18ee60fa11325946a689e96b651c6a9b4a41d0e83238d52990b5520f21c268ba428266b1dbf30553a10aa6c5118f85ab9daec1c521639b686bfc4b198c511939a039982cc774aa074d391bc5137419a22892005114f3132f22497ebc5316e190013325b2c0c1f23ac61ebf6875640c7f56c78df4937c883bc9da38d1f709a6df68026d8af0ba51f1f2c5ff0806cac1a396a7272a4065660906658a25c570c7067d1972417142b0b6bc244b8e52b1b7a4b915832486f8a7486230cc63a981b195431448671e71c38527effb2768ce1574baa6a23226563794e714c1c7f75c05fc4b2630a47ae24b2a1d3141516941d61a58b609808612064881347b4765e892438eaaf1c538e0baca4e6e1bb38821633a385b7c1cd285b6edef2739a675110387e6ec747016a6a1007c87949368d31cb7a63a50e210ce168c825b86695223fc1b8789bdc89545a3394f9c1bd943094546f640b0b129c4e78a9ca0b8107bb18923ce669da26268d57c7eee01f15d0454cb1cb7af05f2e787833bcc4d4996312c82714043907b30a8d250ece8aade970cbe463494e759f463131c12b636503c747f64249d2687b3301387620307503d9562e5a033d86eb23546b83b0f70937fc6b70db7c1d519fe1ca0b93137a41d89843a635fb5c389d420558746be267440e8aa996124ff97b163eb828fe492e96a367ee7c22e2f4031c44688935b0e6439776e34c2c525a31664386a5b6040116d487846f538e0da71fb17a750d4b0b8f4c37ba859810a8aa15b573eb029c8f7052124bcefbc48dc60743e7a455a0c4cfb7c57847c50afb1b5725d735d013441f7b1b43d93840cc4373dbaaa71035ae110955d9cb60ba5b5de5999b082335ebc1d3d5b6a6681e2e4714423b50d30aac28a4006869a85941247f0a8f8da236421b761315b6adacc513f5ae525373cc57482dfb15286546d106925adbc71f4cc1bd33641cf63035b7c02669ced392b0b8c70e776a768f859c04e3b1c1f05d9a909025f075bc0021b091b0bd29ae7e7c787a0a570cb99f9337986d714595023b53147913b72f7df50b6421319825304af61ee75765f44581eb0378ecc979f81950437ba7603b751dbcaf1261a17346cdf645a65cea895320211089a07101bf617b731e38a8114335e3267169d060a9c09e7e829d0168a21bc580087554a17688cd742ef7e4a2510779b666a2b613bf81d8060e06385398babcf2ce1ae7abd2e66ac06142a2f73598ca2a1ff769923a0aabcc22268710c0a2143b96269bbace0f69a25142bb9f1a0c05266003f7a69ab405dcbb3360290ba355c8c6f5b1035697865cbecf8a20209019ea08b6416c86a098af524a2dcb9b7d16253960670ea96897b406c5680b14de691fa5305405f35048865e549c3847b3bf01856a15a25dac28c5afcb6be3e8adaf3689a0e5bb056b000a1308ac643ccd94c28711acc4653b52cc87c7d6bde2dbac47678ddf7101484379de232cae6975b4ec02d6a043ae14a53632ab428666fcd98b9f702432018e783ba3c7d32079a5ce9378621018b52de73f7eca9c8577803f14c0e2c55f8c988fd19353cc4c729f545d3203be1374caa91945e21ab4baf2a4083a91e3d58e89270ef4560669d555fb0444737c6dae111cd1e18f55f1780ca0bb8e7c1ac3e7168d0c9e4a515ca4f11c49c967bd78149af3abc3e692c4659b30851eb86ab41d575021fb146d60069d242569d111e510b731724e6eb456c5428754db8903f31b365c7aa9976c13210438b50ea3e778e5a60e25f85c42bb10b24b72bc820300c91547582fee167eff958894e4898c198a4f652f871c9b03234f98e7a237778c679b757db3225394a356991b2810cc6ca5c7ab888dc9e59529f3498ec40efc47051c03c75225187da36d3daa9f3f0977da80a14a13a990ab20dd415c2036003ffab31b7aa534ec7cddc40a9877ad6cc61d07b7b1d8b71db1d1a2b71923337532e464853357400aca0f6a883ed84b56e77b755594b7bef178115b18c68175dc2c390d462ab641ba14d80b1d36cf290c6afa532d8d7091da94703cfb7334d667f0e3150b60ae8bfcb56dd40e3a58bd4d09a5a3e8a167841118a51490a126d6b85ee90a7f3d5432f59635b1d5587821818afb74ce42569751512c9840f364b6370cb318c1677a304be1a2938234b56bd2632f768a93750158e844df96c720007228c2829f0b779eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd847db13de94d97a88d5a3deae31c246f5f04d0c7d7f337859e024764337a08f25a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +expected_public_key = 3db4bcf2f3231e1aa3e81c7336e49c4d760454729e9a47c4550062afd77d971228863c24f1881d589c111b38a7e3f08788298e5cb26ccfe7a71b171fc504b86d4526a2c0a3e0251710a21fdd68047612cf215a46f1cb3d5376cdba14829ff67f7d4704f199ac398777c8ac0ed24c4f00715c976b0ef18a83dd177367078b43003c10e588dfb9c7c99c5164bc14755114d5138715721eb3022cf2d016f97011f37502c44a397aea0a7818546c831f2073a4697aa878d00c4b7ab8312233cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078293e11e43981f00a25988f076e20a7d69e25fbdf7030e8404ebe35f530a8cc5793cf3eb1aed34b3ea742f4fe853fc8b7aa77a2b17669a116c49a0a114770b14801a62868839ab199e3c02c810cb6e0489820f25c524969a57172811089c5c81659f6859a1e5197ca36a33da0e2ec00cd035b23973448d12b251793da4bc9039b11c4312cf3db1abdea0657467885191334fdc8f590973b201addd09cdbb545fe66a0aacf679f0b89d7914268084888d358b767a8475e85da48590f0809e0ccb2c7d286f12fb8c6fba2f1b16cafc97a0b9863b107826c197a7a6bb0bcec280c526ce18058e2d47bf92e7bc0d4031d4c8c8c8f57bd880c8b12c556d750eef27ac96fc47f37c2c26468a8d27b2bdab5483f241aad905c3a76fd82308d2938bf7a070e6dc56e100b99dba0e46f2729a52a365d732965875b020b82ab23de8f8807442ca89b31fcc76162961564060a119002b116a510b0c2e1f301c55992bc48519ec5a1abd49a4e9da97bba98bb4774c0e6b939ac720cc22b2df733bcb128c7d4165cce67710719c1c978cc49257ff741ea1c3b5a6479c4935447987bd61d99c1d80c833f671f6a44be835a8d8d733adf4af4dccba087c4b8681a8b49a863bc21887a0b1d50b05ae1513dbda0960bb156be96a1321b553f21aa0e14295d00b81096e1c557ad6c949bec43817a836f09b0ad0803ca072b488a1627ad2c017013492a955fc829df7d800c99b1ce02b1d35a68d3269cb322b4d66ca9ccd279fc738c4c3910a8a4a479bcba7b1a6ca8745505b80236b63244d54942305c3c0f89bb4e771a5b09dbb072d20417f469b47cb8b64380b1a99b6a83cd111a881af60ea3ae5a314dff60841592f46a39beb80234ea507b1c9233b898a33208d8c936294738cba7287c5ba7f2ab0b7b63a0d475ca3d6486858cc0de5580e95c56c635825bdac834c71337916055d1c9490e7977982945941b8ff196ba5c23f92553f9a1b962a56ac9498b69ce0c9393621f7a662c6074c9e93b44d099a0003390748547e10052506ac88dbc1d3523a16b0825b4656552383ecf067b2a423bd0aae22ec0971e52963241403438c3c254724e1565ee569b0d357b416bf3d770a729a277caba335519724b2098a107f3f4c1aa1f49796208e739304852c949debc717dc8430f23987d60f0a0a3fd5f97aae412907227fd2da078f1a1bf46c0b66e596839632b121c5eec37694809861541b223619850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcc805a0f4655c61a8564c3577273d198184a2b4443a11aa05931dd1827c0720214eb2798af1a83678808913c9c6dc57eea4c1f2f469bca44aa8a8082cd4082464a9e6ac0a86da0d1e0021dbd3196b726ad9b43dff34cda455c7a51ca343f1af8ce2c580c581e4ecb1517cb36959114a481a0e73718f07a8eacb71a7c2beb2654fea5a7e01a6c02f183686b89ca0c775d0605e17225a655a544838a60f252412fa5baf353d2d264c4e4c2cd31bb4f3075410c220632b3d605c7431479f5694870cb1b1724c0363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d6252c8733cb40627485df64a4e872cbc574134c319cf1464a6b69a6318038896111fb69d306a6c47a393069b0f27911255e0306bc4ca2e93ae71336daa3a8bc0517eff101989f9c19bda6751724e1bf816d4cc7397cb5a57a14c471aa511e42f18e4937001977d063a4ee855f326811ec26c8662b5825a95780a3d031948d53337a45679f5c328573c109e5944b68c0b4d2b466fc48f921328d6fc74705491077987e6cc936e2bb69b534ea97acf85e60f2522a55c115cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_private_key = 1f83902bbb77a97b032277079cd0ca70d09d57385ce5c1b3c08b80ed95b2bbe70c101cc1912b71b29b87dd08254b593d616a31ff4957c7c0c325f82024f6a7b125b0ff799fff47afa6a9a7055382bca08cbfba71ea1b530bda5a4548922c90c6de8927494370efa6c96780086bf585ae6534dc05344dc1941ef793eae214312a371ecccea680c1a166ba97e128064748269922c9a19cee4b8a669abd146491abe31a57b724f3a173740269a33309f651c934e09a564627896150addb8ba181cf2503256512b0dd5588f4372781f35cfc0328c0dac842a1b3f418b6e8c567f410568f2c6be8eac9bab558deb08389ba08bbaa50e1ec5dce044efe5830743402402a167a9369e1d281d37713eb656662600840409c4fb971c0fa7771ba53b6c13ebffcbb85aab3316a3a99a9ced8bc4596932b3d052fbb13a5cbfb762ad7a08ca4aaf33862b6325baddb0e56d395e8f92ebc7347e847956b471695c978dc2431ef7286c0e0a880f7871bb05160209900c0c403da599b988a8ef0a716a9535b71002b3bcdade60053f5a8bc66419fc907f1ea718b7bad6bb76fd3f710e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edb500d884428be2c7cb6a6c86b807a6059739e23f70433d8a7a4aa768975aa6b0c3924cc8827cfc731a464121090a685820068019197f489315a2274a7133422b2968830271fc94b1c775c5a21e3b07bce543b32f00b7250cabd0d04a2529347848830c975261a54717324533ebc0ec627f2064ba693a9bf9a16fce87a8d7270759a06c00eaab71a5cc25034120445334a39d63baa2ab3254d77a921209750f6869e6971d05da1e1bb29cec9cb7b4962370e5c139ba472a75114b28bbb8e7069c5a8201b730db571c1ee0b10e1c42b4a97fb7f7ae54670d12859d68199443157ddea85760445895e7175ef8bb919c7213f427301c4f6561afffb0b03cf1ad05613c52dc5ca71a74545abe77d239576303bc9678272873d9b28f4a4aacfdb46940f59b0a82a75642a0cd794d63d03d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c7b05cf8293d3e23fdfda93506c831455b648e2017fd866c87683ab307c6fd9cf24212509d777f34b0618776864ebae9fa5318e739692c5aa86648d49778b67f81347b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464cd1801d02ab64bbba4f932c0003458ff73011282bf444961c54c5275408c4f79c3c553424aa4aa13a53d59b1b785c0ffb686fda185d5438af5c494d98b80381c821c493bc0e7797cd1995db681ec9e18859a9229c497cc251af12d9cfebc6a19c599c9d364e587c7d32245145a60ceeb54cc7ec5b541b71dae959c800a747eaab53f8cd24365c91f53b7b0b9d3630361d41ade4c82c85e04d8ba243763b3f9dd65d60921f962337a3421051d36889253a423939abeb0ad962ce1e1a9931c960d9f4948723ca17a731adfb4834615693f622470225cfa7b036b931a2240564cc35e59a7acae48707491576cc1410a304e0885534f577692c5a237344a5f674ec7c45bda3242d70b004d5ab620ca2b1ac0a56c0cd5b942529b054e0f840e3c1837e0053539b4a3eac9c6dc6283876c745fba8d505681b923e315a99ed34b04e558be2373cd3a07dc6a26ea98136bd197ad8cb1e695544fd93a23a29577e26114e5c8b4257ca7ec5a467d53fd9e037386c933799bc3ba921a50cc98db79f1f7b96da7a5ab4604498a223ebbc27aaa87ede5b4df226c6b5c382e5ea3545e50b9b0a7b30d15c77927713ba9b5fa52a64985128530a84003b1b867a6bc87f295bbb15814ad3bca5eb3240f72894f147092387cb072692bb62161ee3ca1f75ba423653c21582004d8c3ef207f55746e7338cc94c45ee5928702559f0c783cd16676a342ba9a652962c50c030983172a196ebc901a13ef6472c7e67230629a5ee8917e965cb0ff990dae8cff8d3a7f361c31130ad8cb43a9ad48bc46c51b9a56722c34f5681c71690cf5b746b0102c635171e4f1aa199fcc38f566a0275cef828534746ab958abaf2c8814b15961601cf13436ade37047d1c5497c74aab9a0015218c8a41c719328a0a272d96d63dc946124441ca20a8a30af11f07190639993d4cacb58c46754147313db4bcf2f3231e1aa3e81c7336e49c4d760454729e9a47c4550062afd77d971228863c24f1881d589c111b38a7e3f08788298e5cb26ccfe7a71b171fc504b86d4526a2c0a3e0251710a21fdd68047612cf215a46f1cb3d5376cdba14829ff67f7d4704f199ac398777c8ac0ed24c4f00715c976b0ef18a83dd177367078b43003c10e588dfb9c7c99c5164bc14755114d5138715721eb3022cf2d016f97011f37502c44a397aea0a7818546c831f2073a4697aa878d00c4b7ab8312233cd3880a3493401bbc3d8ac5ee715490f89474a8a9e6f078293e11e43981f00a25988f076e20a7d69e25fbdf7030e8404ebe35f530a8cc5793cf3eb1aed34b3ea742f4fe853fc8b7aa77a2b17669a116c49a0a114770b14801a62868839ab199e3c02c810cb6e0489820f25c524969a57172811089c5c81659f6859a1e5197ca36a33da0e2ec00cd035b23973448d12b251793da4bc9039b11c4312cf3db1abdea0657467885191334fdc8f590973b201addd09cdbb545fe66a0aacf679f0b89d7914268084888d358b767a8475e85da48590f0809e0ccb2c7d286f12fb8c6fba2f1b16cafc97a0b9863b107826c197a7a6bb0bcec280c526ce18058e2d47bf92e7bc0d4031d4c8c8c8f57bd880c8b12c556d750eef27ac96fc47f37c2c26468a8d27b2bdab5483f241aad905c3a76fd82308d2938bf7a070e6dc56e100b99dba0e46f2729a52a365d732965875b020b82ab23de8f8807442ca89b31fcc76162961564060a119002b116a510b0c2e1f301c55992bc48519ec5a1abd49a4e9da97bba98bb4774c0e6b939ac720cc22b2df733bcb128c7d4165cce67710719c1c978cc49257ff741ea1c3b5a6479c4935447987bd61d99c1d80c833f671f6a44be835a8d8d733adf4af4dccba087c4b8681a8b49a863bc21887a0b1d50b05ae1513dbda0960bb156be96a1321b553f21aa0e14295d00b81096e1c557ad6c949bec43817a836f09b0ad0803ca072b488a1627ad2c017013492a955fc829df7d800c99b1ce02b1d35a68d3269cb322b4d66ca9ccd279fc738c4c3910a8a4a479bcba7b1a6ca8745505b80236b63244d54942305c3c0f89bb4e771a5b09dbb072d20417f469b47cb8b64380b1a99b6a83cd111a881af60ea3ae5a314dff60841592f46a39beb80234ea507b1c9233b898a33208d8c936294738cba7287c5ba7f2ab0b7b63a0d475ca3d6486858cc0de5580e95c56c635825bdac834c71337916055d1c9490e7977982945941b8ff196ba5c23f92553f9a1b962a56ac9498b69ce0c9393621f7a662c6074c9e93b44d099a0003390748547e10052506ac88dbc1d3523a16b0825b4656552383ecf067b2a423bd0aae22ec0971e52963241403438c3c254724e1565ee569b0d357b416bf3d770a729a277caba335519724b2098a107f3f4c1aa1f49796208e739304852c949debc717dc8430f23987d60f0a0a3fd5f97aae412907227fd2da078f1a1bf46c0b66e596839632b121c5eec37694809861541b223619850a368684863a34761b864314187989ab4c68d965b3cc994d734ec4c84afcc805a0f4655c61a8564c3577273d198184a2b4443a11aa05931dd1827c0720214eb2798af1a83678808913c9c6dc57eea4c1f2f469bca44aa8a8082cd4082464a9e6ac0a86da0d1e0021dbd3196b726ad9b43dff34cda455c7a51ca343f1af8ce2c580c581e4ecb1517cb36959114a481a0e73718f07a8eacb71a7c2beb2654fea5a7e01a6c02f183686b89ca0c775d0605e17225a655a544838a60f252412fa5baf353d2d264c4e4c2cd31bb4f3075410c220632b3d605c7431479f5694870cb1b1724c0363e470f1b8a38175c79fcc9ccb33571bf9cea9653722b5bdfad66ea7aa4d6252c8733cb40627485df64a4e872cbc574134c319cf1464a6b69a6318038896111fb69d306a6c47a393069b0f27911255e0306bc4ca2e93ae71336daa3a8bc0517eff101989f9c19bda6751724e1bf816d4cc7397cb5a57a14c471aa511e42f18e4937001977d063a4ee855f326811ec26c8662b5825a95780a3d031948d53337a45679f5c328573c109e5944b68c0b4d2b466fc48f921328d6fc74705491077987e6cc936e2bb69b534ea97acf85e60f2522a55c115cac8cb85e5a9ac9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89adf122b76b83c343de27054985634387fb7138f6f6f105cd4cd3f5b02698a964b036b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +expected_public_key = 24d25e62d57365c8c611f96ba675aae5a14164b5171d74146d792d6203ba384ca81ec71ed87b8ba40023ed8bc6ac54406263ca3d97c5bdc20d9e2cca82b0aa54586863d95d3ed0075cc897f6726caa441896e86e03711a3d109f5bc311e81a5194363f8bf735ac9a2caceb7ec4826f8af2b303c3914e9b7c3c5337432ca626970761900b44cc92630ac8469a6bd9d2b46d88c225223dfc405d6f1447f9878610d021cf3762c235c414025239ab3827ab5a4699c82e37b1a27b460f0264f4089a98e41c924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad0873935718bce46b2f19864e06486a4f5c8d689adec32a2e7c6b57071be67017fe25b8f52ca525f99be536a4c1468b5f9f418025450048692f961ab8feb5075b543e04a0564c26c58a72ec6433b623a2d5a086c85347e45ea7b99d03ab50664149414c3f81d219a5b5e732c0a52c060e90e64e14873c02167a21a67da6a0b945781341cb7c65aa2dc481b0998de5c8d893a548f055f8fe420f173b949862a5549b0ac1908f202ae0bec6b19c0b3e5178f4e40485ca33a93947522c1aa6c188ac2fc4cff214b995b1bd69229d01a8d3d2045af723a1de559abf78c09928d71aca3c0016038340ae715058c95cd33ca85709b2134f78b86a84ae764ae94b994acf1354e42126638b57ad207bad29f1e60471acb5b650332b4656ccc808c15ebb8df203ff0821bea62aa67967bfdd09535e7088ca98e3795aa1167be9126348a946507c08243a969b2f9238fd29f0370356288cb1708024ba7a9cd58a12d306d4f4579893c8a04a10c1872b6a602c155f70a8ba6987fd28dc842b9f60b4052890a4482a351533b4752061e30957f8a16b6f8502a1b4d8f91b56b71470ee2cef40648533bb1d9179b3e335e051115b817aa30b3707b64121179318593b0460bcf6e57a65e045d00353605d60a0705468c6b8e4db422c31476c8a0b54ec166ba59b75f9834633c0052757dc437005f653ed4c19ceb7c774eaa75ba0068f2a997a79a98bee42abf9a3b7597394d4907e430737f860454407b8fbb2da0a054c2a4c737c8724c02684a070da34388fe9927be4259859849ea9cb6ef5990eae176efa10154556ce5650cf264bd11780055b5931bd6c5f51816d135996757b386b76a03893efea95ef964b402079cad080b67098b2c092f1e9768782a8e3daccd82741cdc5c8575796d08e3180b34b4ce227e7593ae9264417e7b53daea2987a01fdd42150a4262441475370c1357a575288571996527c95a9fd62c3bf54a8c8ec0a335c3a31b934002443d07f27240860e8ea76c821a71e67132c9a5a1d4d3b5f29cc9a9924081fa3c33f4a11285458954042337701c392998da8ee556a544f0b49c9c2b83b58dd8d165e6751318363400d61652d7170ca44b3033bbb20b45072708e6453b1708b5b8206419e050d7c8843e0bcc227b9d6b426a9f693945d69ee98558bbe133fc6427a8f73981786f42dc03fb23621952ca8ae03810648b8cbab5c1d2816fd1c231e10f7eeaac9a798c2c3a4cbac428c6971851320191d3195fe4419ab69fe913280d0763a906c33c4a9d311c74d9459ee85a6599061f09376a14803e1ddc67d8328bef1c7f673b62bbc234b20a29802ca9c19c89b9b6628a6bac7ae29897b1136a0b8c28b0441bd00a9144c85c9897a48902d176b9b03a454f36885db61b5915811d60c170f74abf894bcde1a088195fda3043be6080b8b98dd48168c12a68d0b74242472ddff790608170c271a4bb19907288854cf1c4cd744d1eba1201fb643b805c7c7c1f6cc9437038bcaf6616f9a6a214785f5fe71071e4564d0070a401b457023685a65d63fc525bda14b26c1f5381885b24786a939669261b769068c3f97eee28aed3fc68d3b08d6a6b77ee2449030c0190c016394b0d9c8085bd550d12f5110e647b9a1549e8f67f5fd0580fb39358114aa668bfa3a202c0369ddbf5518d80aed20c403aa3cc7148119cba54ce1667c2654d9b5a833d5a552808ae72629a2da12498319a30113b314c870e8752e442af5ed67bf1481f071921191b2b21964fae23b33df528a22090e4bc6ec2911810e02e65758397b48d1906013cc0cc0c2c73944b45bef04c2781acf467336a107ff7cb12e6305ed85342d2355b047862be56057cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_private_key = 8b78635ac351c94bb6b1d2b861e4914dcba415f66ccc465b370578e136330a2c5cb0ca2857e1cb733a75e5cc4fcdf7a12580017f1c0ff484401cb23318a98000637b3d065608678103940d8ba75ccbe58206c130ed62bbc0132317b6556a9c2ae8f71a43712002d795ca52007782652d291dfe535f75034b0d624277527a6ef623168aacfbf721a9e8753195b82eb9855467322aab0ab1701546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830df61fe9600ad5717bfa2c8e59e30c8a20179b27b59341c855677880330afd1a227b6c6313e17c46e87d109a4aec4c1795908db6046598483159907a667378f80bcb84472d5a748043b1bac10ba5bcf61b07a2b13b12c347f3253e26c25ef0af6a003a67b0bee98a7c5a489c9ec9ac1f042c6f2bc7585cb01bb4b55496a93de903ec974398e277ca7cc25e3265a879420ea0bd8451716ac21f1bb806c12b3488d408ebf18b89b79b1f8c09eaca235f1c165f9504ff987139590f9977513ee037249b4e25e51a296526ba76cd3295895a571cac279bc65642cba501c8f131eb52b5c7cb73b17757440b1ee4e9295d404177e542bd744aa587738bfac0ef3c1fa0f19b0a5c5e28b53c2340c7fa061ad354c85ad26993087b61ac2002795d5ada7a3e6747ab8110367c824988ca705b818d7a921dba33371405ad235b18e463a8ac88180c88f071579fa5ab6d904a2f53b03f7c7ec39c473632369f984f8cc66dbd1924206a6376706ca36601be7b16edd17e93cb9a0437b3615374329b0712794f5058790d88182be4863293133a83aa00e07c8e79c6f12c33fa9437ed984a1392903da89bd43184db6c8dace3789af5cbba092010b889ca98af99e5b0b3d4399bf61266e833a55a85e11784708b98efab223a27aea1a16e76a73c2027759fd97a7db870f9fc79afc89435d092db556e0a738c133b259f86c98d78a43a49744f306da8cc6c9098a5a9cb091c9bad94970f03b543d669a9aa4944e0c08ddfcc1d7d485fa414b0765a88f175ab6c94b12a2177dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f084277532841f51c3edc5c1873bce0f07a8871740c4aa82bb5ab164916082b795eb0660be32da9972840c927b7bb4061343d56757258ba4c91624f21da11cb265b00b9aafbb1665679c86eabbda12b74f1c5917101d0ea2bb293c71ad5b556369378a8d5b7297c9731705dd4493dbb173ad01458686a93287b6da0a6923b913989b69612a915a03a0962379bbc466a03f5517aaa0c0b030c6ca420636b2ee8821916e9c7f2ba228bb2aeabbc292f6c07ad85c6f43ca90d42629759536046394936c3ac5ab979d5cec1a1cc19b5c17edb47b0f47f34d616027b29a12725bf14b62fbac4f2cc6eece89ca0467d4868c11c17299373687b657d132c55785080f5b87f0e3c1504673825b98e8a0aa35f2c8d84f41b060ab43a930e7be1c9d04746169bb4ab403ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a9550ee494466a49617b541068f2c57ad4108ab813db58526c7647d55c1cb657ccd1143343aaa8421c23bd0c822f763b6a82b7d0041648a143bcc431a72b204e680a3bf11cb6652255143c4470b18ab27ba5e6cf2f1064c37ac2a446243442b0d2714d2d6c3208e303f974748012a7f0aa89dc01035ddc3685657d457a6cbe9c7a9e8aa5e522ab7dbcb1c646251bea398431339619b1ee972a46da3a063c909392c284b4c5ba840c235588ca640a54963252e45e33f51227b11700f135756b3567004216417f2beb77f9267e72e444f3a78ec649131ffb364b11bbf8ab6472996be20829011c3f32183fa1a39eb2bc0ac20478ec168e4e2ba66a01742d973bcec937a9383c62c725cd0528bcbab546179a6365819777412c5671def8cfbe9b27af037de11c268ff2c1814222664bc9a7059114511cbb5b361ee050634405f8d1908d6a9f3dfb3c1d888ca74bcd244313fda169b23345f2c804db569a12293883994940fa236a7a5df76c1d6c853207a04d2de7793c6a6bf5330bd31c285a923071c2331c23432c427791e17711f50688130c3daaaf532060ac0c9ae2e9cc338145d8a5787904c133817947430890361777818990c5780a4440b2202d24d25e62d57365c8c611f96ba675aae5a14164b5171d74146d792d6203ba384ca81ec71ed87b8ba40023ed8bc6ac54406263ca3d97c5bdc20d9e2cca82b0aa54586863d95d3ed0075cc897f6726caa441896e86e03711a3d109f5bc311e81a5194363f8bf735ac9a2caceb7ec4826f8af2b303c3914e9b7c3c5337432ca626970761900b44cc92630ac8469a6bd9d2b46d88c225223dfc405d6f1447f9878610d021cf3762c235c414025239ab3827ab5a4699c82e37b1a27b460f0264f4089a98e41c924773f4c83f5c57a4d0f6959f6c59fa6aa4a6047ad0873935718bce46b2f19864e06486a4f5c8d689adec32a2e7c6b57071be67017fe25b8f52ca525f99be536a4c1468b5f9f418025450048692f961ab8feb5075b543e04a0564c26c58a72ec6433b623a2d5a086c85347e45ea7b99d03ab50664149414c3f81d219a5b5e732c0a52c060e90e64e14873c02167a21a67da6a0b945781341cb7c65aa2dc481b0998de5c8d893a548f055f8fe420f173b949862a5549b0ac1908f202ae0bec6b19c0b3e5178f4e40485ca33a93947522c1aa6c188ac2fc4cff214b995b1bd69229d01a8d3d2045af723a1de559abf78c09928d71aca3c0016038340ae715058c95cd33ca85709b2134f78b86a84ae764ae94b994acf1354e42126638b57ad207bad29f1e60471acb5b650332b4656ccc808c15ebb8df203ff0821bea62aa67967bfdd09535e7088ca98e3795aa1167be9126348a946507c08243a969b2f9238fd29f0370356288cb1708024ba7a9cd58a12d306d4f4579893c8a04a10c1872b6a602c155f70a8ba6987fd28dc842b9f60b4052890a4482a351533b4752061e30957f8a16b6f8502a1b4d8f91b56b71470ee2cef40648533bb1d9179b3e335e051115b817aa30b3707b64121179318593b0460bcf6e57a65e045d00353605d60a0705468c6b8e4db422c31476c8a0b54ec166ba59b75f9834633c0052757dc437005f653ed4c19ceb7c774eaa75ba0068f2a997a79a98bee42abf9a3b7597394d4907e430737f860454407b8fbb2da0a054c2a4c737c8724c02684a070da34388fe9927be4259859849ea9cb6ef5990eae176efa10154556ce5650cf264bd11780055b5931bd6c5f51816d135996757b386b76a03893efea95ef964b402079cad080b67098b2c092f1e9768782a8e3daccd82741cdc5c8575796d08e3180b34b4ce227e7593ae9264417e7b53daea2987a01fdd42150a4262441475370c1357a575288571996527c95a9fd62c3bf54a8c8ec0a335c3a31b934002443d07f27240860e8ea76c821a71e67132c9a5a1d4d3b5f29cc9a9924081fa3c33f4a11285458954042337701c392998da8ee556a544f0b49c9c2b83b58dd8d165e6751318363400d61652d7170ca44b3033bbb20b45072708e6453b1708b5b8206419e050d7c8843e0bcc227b9d6b426a9f693945d69ee98558bbe133fc6427a8f73981786f42dc03fb23621952ca8ae03810648b8cbab5c1d2816fd1c231e10f7eeaac9a798c2c3a4cbac428c6971851320191d3195fe4419ab69fe913280d0763a906c33c4a9d311c74d9459ee85a6599061f09376a14803e1ddc67d8328bef1c7f673b62bbc234b20a29802ca9c19c89b9b6628a6bac7ae29897b1136a0b8c28b0441bd00a9144c85c9897a48902d176b9b03a454f36885db61b5915811d60c170f74abf894bcde1a088195fda3043be6080b8b98dd48168c12a68d0b74242472ddff790608170c271a4bb19907288854cf1c4cd744d1eba1201fb643b805c7c7c1f6cc9437038bcaf6616f9a6a214785f5fe71071e4564d0070a401b457023685a65d63fc525bda14b26c1f5381885b24786a939669261b769068c3f97eee28aed3fc68d3b08d6a6b77ee2449030c0190c016394b0d9c8085bd550d12f5110e647b9a1549e8f67f5fd0580fb39358114aa668bfa3a202c0369ddbf5518d80aed20c403aa3cc7148119cba54ce1667c2654d9b5a833d5a552808ae72629a2da12498319a30113b314c870e8752e442af5ed67bf1481f071921191b2b21964fae23b33df528a22090e4bc6ec2911810e02e65758397b48d1906013cc0cc0c2c73944b45bef04c2781acf467336a107ff7cb12e6305ed85342d2355b047862be56057cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a69684c3182ca7a48afe60eb85790dcb50b8005b568921dbc724130b0ce83f127845475d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +expected_public_key = c6100d6d7952085257f692ad9173888f28bdae384635b2057a8183ca07853de05f72437d6872575ff4c0efb06259e397cda6a87a178498c9aac54b046a8219d98c48f113319984995f68b1affb863ff97dd8d14cace2921bc192e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e731e0a68940ee5b8307460b402651457ad1a7883d0165c8cab4d88f565008155ac009776500f3779530958c3003c7603c900e50148088b9420b78eac241dc0aa11454195a03998388ac747fc465dc140e9193a9294abb90b8022b493e069ae430ab3fc9307fc89358d3a88fb054e9836cefbe45c44569b285b01ec892d5ce8288ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc06a08f521b6063066788841964696a31547c851b578fd02434526c7e641fb9721cd390984bb121518a88633658c7c7c6b0830cb6800b2368cbe703cec33a4bdf319b49909b590a8bbc6542a108bf5927c49dbaa2c5c5009e002e242ba210a64f18b8542be1cb92a8293c56586b568b489ca697d6c4f819c399590472e8b9de9573a1d2934b86bf2d2b6f92ec8489430e0a681fee0a22bc3a705396ce6a74c1d5d3a91aa253da718757c875a1442fef4241f95b516d27220973c25e29b1d335846db494db4cac3a0b76388304b4252ac2362ff032a8b5c3322f6a0e5658799f1193ec69bf15c77e5ff2a3a2925690496af4320ec688450058b5727a0e66f98270267b3f49270e310714f353dd4b74410a9a0e778a1e030461113cfb05a142001cf39721215026cf84b1c0e706dcfc4d9ea80514061463a16e069750c026ad26ecca10f5830b2b756d515ef1c64d6d2c5e73818998aa9230d19d35842400c4568f62397eb0a42cf86c857c3ab009c8c831257d246b456996bc1bcc378a44bd88a0fc3469b0da0d22410218941431a12f37831653342f12206c56c4b3bf980a5017114b3112a6100b06a2a62104c48ce8639d1830e785cb3dab23f398691b48458d2acce79511ad276643476bd6c33d8d1c40fab1b81a96a7dfe36115e49a07f8c72240b9b3f24a2739b963609b0c2705f928c6ba7c2fcc0c164be46fdee5baa5730cd7a55e1221cd73305bff9b8ae5c126b8621bd6116c17286974002c88785c745bc32f0b86dba92e072a395e91acf7257ac5ec5ee88a7095acc39ad023a904b72c0ac845a318d18c7c72a0c4387cb470c8ba438498c5514398c70967b46109e18505543a98d51a3753bf3c657aef7264a91c2253f801641c609628a7f13a246d5aa13f3a4d1da22221ccba20091c6284452f376b32cc2d27d3869137a3fcfb06b7c93f70f3a20d84741b8a186d78af94c204bc0b6da175175bd819479485db23bf6eb2cbbb62a088f2bda7cb470c26b281e29e0f29a111688cc2e7cd61985eb39287546967ad991eccb99a6dd4b111861755964a77e3a7d2c5b9dc966e6f51bd53d72f9775a624f344fdf4bb3a9822d26b6db6b11efb527a2138c45f27c5e8a834ebc780e1e8210a9a7a4b7c3fc63b1757a22b8cab57bc07aa27a228cd30411ef407bc276ace8c05498cb641366b4ea0caf8101198b35a51d502a1c1894eeb700a832d70e627ac0b7a57543769991f007176cefb10c6e74a987c1d9b9750db5230317298a800b508d41c942b48c36035915c0504646726ab767a5059d39996a3e310ccbc610d878f9b7503b08822bc1541a359c807526d27a7abc1d78e3c0c3f67f0609c699e44ca8ce2c7a78e70042be21f4c569e9d0494a6e8c2f0592ba5060b365b57d1b03916e27fce04c42205803af0b213e27b21245e480b6330bc8533888e72e9bb2148059ac42ba2ba2550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de4898181422a34b9a239508878a0682eb2466a44a59542b268d31989f049f433a7a0225d556770f4391dfdf4432133a0d888436afc531f4584abc40022c36314757e79538cd1c67da58a049cd10baab7a7fa38293ca84403291372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc7e1c2e62a2616838d5d13674b832694975cf1396deb11a1cb5a1bcfda55ba86583884aa9593399a047f00e703cd458ad157333c349c46021b7ae1970bc2927f094c77970a7c9bacfb0a6e02108036f809c9ac23877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_private_key = bddb6a1bb704f8b530860b719752402098c84ae4809b01c8ec7583a66a3f4bc290bf2173abb41868225606d54991f5b547c2254c74391717045997a57ba534a97b3605e1ad9f7c6446ac08bbfb1999179bb8f67731a63ce1c717f30b57fd17bc00605e8e14127eb0c26e324aabd45138484a51a15dd2464440178ca7e966d4d58383f6bf9bb2a971729074781a8d978965f9a51eb2729ba8c308474d56089f2cc869b523c41c409507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373d5185426b7b3951256154a7b78cb1f5049df0371b840ab21b83944fb383cc84ad9e24ff42b2731276c1d26b6120534438b029c4ac7c0739453c2860d32acd75229c63a23a7201c303032bc0a410319035d38a3c9802d41a56a8c6c2496db10441a2bcd13a81f90cda2564cc9e4020a47595a30994888b383e996115aa282eac3e3594447110c2d07774f9312d796c6b74a7634b6c0da2291458a35d3022bee048483461cfeb152e1d2ca9195afd1f9aa82131804d35e739299c539b913c54a0c58683259b3137aa464b9c6e03b0eb751999b6c5354d6171c78cbbef1b456ec4c88199764a5761d18c0849c1b0a263ea401b86cba549c712e4a251830f7b6ee16b2bfabca3ce018c3833bb881385c272dee151ac35a2c9561b3c1266855219b0c6b485e669fcbc49b24c50c6c3237aa6b116085085405115e0422d956beaff9360b58bf915654b9b887ad9733f425a5c6990b3f0223d8099bc0e95c6a5702cf5667209ace08fb4697d02dc45caca8074185f54ec4641b35bacd2f0b770fc215fdc171c98baa7ab6c0450ba6e47a838575a528f7be221c3c91f02734269a9425a2edb76cb6d077ed76040a716d39c9c87a58ad8867954c752367a905aa158e0a9019dda50a6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aa9a0418c79a948199365a6a1045238104280ac704b33791e156a2377bc83e9b9c86d0a3d2aa3287272be6431bb4e598232312d10d03bcb13b4d838a9a624566c6a25fa44a0934ab6cc333e6d52af3ec26a6fb97615cc3c77102d1a315486bc69c555a3e8271660222a406022e8d97251308a90a15f748153c1168cb133593c1641e164c8a06cc008059c55449413c2b28667b99122ac42b8bffbc15fe395003249c676db7589d2896e7405bef8ac510782ff204454c8a0390c332ceb7a5a3123eb1a1ad0470096058358ba779df70106e24990da77aaf09705110993f16a2320a941d8865b387236cb8528babbf2d9196c15898bf71040d3ba500cb7b1ac85df11003a058d838c2652d4577306023c756ae9715136e91b20699fef425e48953fece15baf27489d929876803eb0b5764e6338bf5970c2f35d1e815bb5b0b1bab630138859b729923343c3d24922a8522e38e19868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5b71ea78c2819113fb3632d5d995b02926663f2ab8e3a73dd6ab93503192e0243f2593618e3a809684bb6a31674e77802828fefea3a50fcaeb1088f7edc036cb84329c988d965071e97c1311643bb1ca2b43cc57c84cd5ea9109ae36de2801cbdca3bb6f977959578954ac17d303841d5726631663f12816edab5c22b0286716d1da2b9ea03c5c23806e56679f43b33fb553ac921482f0b61db90acbca4b91ba19a22c5709ba48777979538519da6ac5e2b576c545b35e510b1a57bc651f69ddc4634588b19a31a481a216a365941bbf709679a9ef8a6324c20c6842818ba97cca6d26ca3fa79f3571e0cdc651ca753c5f2b8e8c247e9b064cd266d268ba3c18a30168452031b9458b3c4a084a7a9542fe7fb88fdd828f5d275cc1879fea43d84a38db1933298f6c98c08188b5aa96d9065e7a638d3746265652fe72a2d4623bc97c40b61a7124c899876c3aeb0d9cd2672795e0a65d44c0180436e8f4c2876e66cb8071262da0947a926c80c6b67e13697c7a200b55f576459478731ac9b62b7572442e04105a83134561ad9a71a9d4696f8fcb791c44593a680ad34b8096ba82434828c492638a9a870b14b611bc4fd43a005624895ab6760257d181954f3f934e3f6742dc54cec3cbbb8c229f8902d18517374cb6fa8a0cf6bca0487880d30173cbf6a0386f12ecbe135cb7b620a5b7b3999b947770401a917c6100d6d7952085257f692ad9173888f28bdae384635b2057a8183ca07853de05f72437d6872575ff4c0efb06259e397cda6a87a178498c9aac54b046a8219d98c48f113319984995f68b1affb863ff97dd8d14cace2921bc192e038be06a5c58205cdc68a3d1ec34d58697a7b6bca3e731e0a68940ee5b8307460b402651457ad1a7883d0165c8cab4d88f565008155ac009776500f3779530958c3003c7603c900e50148088b9420b78eac241dc0aa11454195a03998388ac747fc465dc140e9193a9294abb90b8022b493e069ae430ab3fc9307fc89358d3a88fb054e9836cefbe45c44569b285b01ec892d5ce8288ed638d1876663e3c33c25c28297609fd94cd0bb923a746a4f55470b3b6c03c8a930e7bc06a08f521b6063066788841964696a31547c851b578fd02434526c7e641fb9721cd390984bb121518a88633658c7c7c6b0830cb6800b2368cbe703cec33a4bdf319b49909b590a8bbc6542a108bf5927c49dbaa2c5c5009e002e242ba210a64f18b8542be1cb92a8293c56586b568b489ca697d6c4f819c399590472e8b9de9573a1d2934b86bf2d2b6f92ec8489430e0a681fee0a22bc3a705396ce6a74c1d5d3a91aa253da718757c875a1442fef4241f95b516d27220973c25e29b1d335846db494db4cac3a0b76388304b4252ac2362ff032a8b5c3322f6a0e5658799f1193ec69bf15c77e5ff2a3a2925690496af4320ec688450058b5727a0e66f98270267b3f49270e310714f353dd4b74410a9a0e778a1e030461113cfb05a142001cf39721215026cf84b1c0e706dcfc4d9ea80514061463a16e069750c026ad26ecca10f5830b2b756d515ef1c64d6d2c5e73818998aa9230d19d35842400c4568f62397eb0a42cf86c857c3ab009c8c831257d246b456996bc1bcc378a44bd88a0fc3469b0da0d22410218941431a12f37831653342f12206c56c4b3bf980a5017114b3112a6100b06a2a62104c48ce8639d1830e785cb3dab23f398691b48458d2acce79511ad276643476bd6c33d8d1c40fab1b81a96a7dfe36115e49a07f8c72240b9b3f24a2739b963609b0c2705f928c6ba7c2fcc0c164be46fdee5baa5730cd7a55e1221cd73305bff9b8ae5c126b8621bd6116c17286974002c88785c745bc32f0b86dba92e072a395e91acf7257ac5ec5ee88a7095acc39ad023a904b72c0ac845a318d18c7c72a0c4387cb470c8ba438498c5514398c70967b46109e18505543a98d51a3753bf3c657aef7264a91c2253f801641c609628a7f13a246d5aa13f3a4d1da22221ccba20091c6284452f376b32cc2d27d3869137a3fcfb06b7c93f70f3a20d84741b8a186d78af94c204bc0b6da175175bd819479485db23bf6eb2cbbb62a088f2bda7cb470c26b281e29e0f29a111688cc2e7cd61985eb39287546967ad991eccb99a6dd4b111861755964a77e3a7d2c5b9dc966e6f51bd53d72f9775a624f344fdf4bb3a9822d26b6db6b11efb527a2138c45f27c5e8a834ebc780e1e8210a9a7a4b7c3fc63b1757a22b8cab57bc07aa27a228cd30411ef407bc276ace8c05498cb641366b4ea0caf8101198b35a51d502a1c1894eeb700a832d70e627ac0b7a57543769991f007176cefb10c6e74a987c1d9b9750db5230317298a800b508d41c942b48c36035915c0504646726ab767a5059d39996a3e310ccbc610d878f9b7503b08822bc1541a359c807526d27a7abc1d78e3c0c3f67f0609c699e44ca8ce2c7a78e70042be21f4c569e9d0494a6e8c2f0592ba5060b365b57d1b03916e27fce04c42205803af0b213e27b21245e480b6330bc8533888e72e9bb2148059ac42ba2ba2550ebc37e437487c581d069bd27d739d4daac6d5b6c9adc8de4898181422a34b9a239508878a0682eb2466a44a59542b268d31989f049f433a7a0225d556770f4391dfdf4432133a0d888436afc531f4584abc40022c36314757e79538cd1c67da58a049cd10baab7a7fa38293ca84403291372f97c9eb85d120b541bba94098673e35358e4f97ec124cbc7e1c2e62a2616838d5d13674b832694975cf1396deb11a1cb5a1bcfda55ba86583884aa9593399a047f00e703cd458ad157333c349c46021b7ae1970bc2927f094c77970a7c9bacfb0a6e02108036f809c9ac23877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e4359601c371b50b50b5306de33cfd476d3b5f811700dc4918beb345840244e3a248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +expected_public_key = 49548733578aa80987b45a404d892f45f83fe6260b4521181484a7ab65aed79a53f2e495ad444066d1108d14c4fa74847fda990a783fdb923734860238a94b8634217de964ea35a3d4c651a15c719301a2cad86352257c2ca1a87f329092e18c5c782ace76ba239c6001143f87a0406da9437d7b19144386b9687023a34a46814eae040c71673aca3993acc03879c9af60ca0e4eab9205b7ab65c33ff1295100d349f84694abe062672135865494ecf58db2912a3af380c228b78d329634f359008871769696bb357d552c3e9fc17d8b636e1b905303bb2a5b6a6f07f478d4229daac38ecf47c205371705b72092f7a438d01267783e24370080362c659796d7443354d92dfb9bca5ba5355e5c3608bb3d9b312fc7ac435b81cc1a6ba84a74283763a520381e9e3c998dfba80d8383d416495b42b7b6ca3e91789c8191b894350f52b6b7a3e38a45f50f39497794e0971650c446551d7d304c87515bb415773c10bf08cc20506c0f515428e8b9037c42a837469de6a3a37c695b602407a46b7796593623a9c840accb5a6b1175a30f62c8b9461c444eb73bf1e22418347af3d92742175bbfb41474156745eb0dcbc4077eeaad6c13c314d3188d3c9bf2f73784c0cd1a215c4623a8bbb19997d82be2b1719346190f054a1ad92819d9b812028633469c3661238fc66cab7c05bc5468a132c9b3a50ea5a4a8ea04800c97c3b391115725011e597312b7a0440ac2da794859776ca73b550d666a8f058477a1a0c9621ff6184f415114d35514909719234c166734b5535b863afbcbc5a2264a86b0642a41763b6d6da15447bc930f925415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da37862790a282b8db833ae37bc5a6940a8b95926f1f468853b288c9a4c7c128bcb56c7a218c3fc725ad1b89c829799b0a8a1f3718fb489b83b900f1cc9b1ee16369f18b207d022a35224330582bc4848e4634f3490c12c756246dc9f3cc27550057a1863ccb91a4b891820bc882c0e6024e1bb037677092c633f2cf68b96b666e1034339ca3e43f6ae7fdb22f9fc7649e559e5d22a07075bde79a82e62b5a5258a0e685a2cd1bc8566cdb4a19d5c581236f0cb4e7aad6f561ca9f6850d30a6fa0c1eca230a06e11cd6f26194f56f40bbcdc99bb4c1f32c851bbb7af48f19d813f89b01d9477861e128631b9b4d72c4c7ccbe59462a4519a8a34a44dd84586c4a542aeb6e1338b6836297a59283af07ccecec01ce074d8469c93f509f09f7230c092c63f2245ac2137a4349078a473d81cb3f87cbdf843645500b932bc326a85fa91095e4513e9dac02d92a69f5acc4200bb1dc0270b013b1f2372bc75aa609e291f0385bbe9376953cccb3f99971dc9747cb913760506fb051ed186454255fcd642aff73c32743158d467b0ad012aaa439c9335b4ee23a426cad3ddbc4ab882076c2bbe83321fb684825b032059838e3d43da29852309b1a7c15c08a5669a3ba2200b34b7f325a5f47b479aa49984060ace979e9db6bb68466973a3e0030c0bcfc4e6c6c13f734b1731ca956f89341d37b1cd5c40bec802a98c674869c04571993e461446b2e2a68ba71915bbefc2d40dc8756b9ad9bab639ff6985e03b5a861785981a7b1449594d584bc1cc4ef7a4333e5453944c61d0145a5b6c999900df26299ccea5cc1d36fbb80c1a5e9c619a4347669377d541519ca47f06884b1984408d43b4133bdcc488bddc599c4057b14a027d051420a5c17cc1671f18a2128b58e9b7a5e233a6ed2da288130b51e47038c9aa2751556ba24b284515af73a81a6881d665426d1d27a8a763fb3b2caa19bc310a9c10024b7d722606c3b6f19c8935b744e28333df8b9480a0083eb588380e6a12d777862e5c7d3e1874e8b1405a5787e92accdc798a873539c133502569e6de7a29c7025289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960750209ee517629ca2280bcb7df35793bf233fa074185a04894ac515b8985ddb5acab68ab379a639c49216a8ba4f9b125947150a907385e9729a7d621a5a9bf8c4a1234e6ce4411923c18ca0e925cb372c59220a502390e4c740571f71eea1083887a5797f5631f614f4e91184811892c6086b0f5bb6fc322afa31653509c8e11a8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_private_key = c6389f081ca0932ab66f658046c1278b38bc42b5c4e1a7c7a51b09d8a159773b67aae1c2aa8666000c6e6a014b5c0369dff147688ac6fd48c73d783e3025c92d782a479acbde8a7548384b763a868c46178345a773a9852016b9fe765db0bbaba5751e8056b7564c53fee8040d3c0125115d323c62a3f0a2b518330b6cc4abca84f62c792d07c1e1a0bbbd7c5b9a698cb683981f8828ee69912600311a0281dbf9c6c9e69daa26a446d136e8b0310f236d7a5a49b2bc616fd346c3462ab09544998c8d5ef641e7b48c35ba7a68f25414f703fb02b501c69c58a9b798c8c76923272ed9bf432208bab30f2db45e1cdc56f6ec11792a33ec1a62b3fc992441527e63328a46003db49b7dc07f73f705ca0220de94bea4967213d612b5a03b2c16a9bd4c66e0ac893263169a87aeae67843944628e6374b5518bf40919840b8e6c64172be3a35ee5a29777c035463380203072ea50e7daa4f906d01c502560621137b91649c97417cc2d3e1677006226d4621073cb1aa213525199bbbfa78f1899a53cb2b8d00819869867a41b2f48c615efe2c8da15a4e6965bef0c4207a499a2156ebfb611478182d85a71c9f8776d28051d1a6e4a104e54615992e0595ca9b0cb2a0ab0159575863f3145b3401498949502b2ea4392c77728215f8700c93f5846a1a8126eb6b72248bd1047bbe62aa58737268428509e53575f945735e75b42db2ba2f21b24c990a847241d2c3533b10d50847c85d98143fbb2eb5138accb055a8b8bcec8afd7b5697306165af982190821a14301ef0a90c3d829ed9035430725a99c67745ca415600d10d7c29b228998d7402efc1f0d0476c4d74c34754af9a1aa1213c9a0198065378de2d023eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c604760ca679b301ab08ef1a948a5a83debb39651310b368c736a56977f78af0916364f278a4e3973374213f7a28ba70296d1916fc65cad3b33c4e1597f818cbc489ba970680999c373dbc246740c07d97c5e1ea5aa1d627757f4467e84ab9c5bafd9ba484f1212706788cf5ac1829c7ff0a66f26c30aae327bb7e167bde95fb5829340b187162a5fde3a7cc6a0a05fdb6f26902bdb0c6c4f75692e67ab1c8b1b46a40e53fc901dd892a3e612afd1cb2cd52bc5b0c3191137e602b0a5872d3a961ef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2db29b637a5e22559a59971be46004fe2a40f7c330610377a5b0eacf79d85f3c86223a4c90c31c2495314748601431fa1f49abff2575410af33f7367c5540084b75d6736ecaa010290839ee2456ee16bbcb57c601f26aa104916254a689c24cae98296e4bcef8770ed7485511f55a46c75592c88d6f76005356c397eb1e61caa04bf55a05c8409e644055759a7e60c1c8210221fb97780b92c2c8aafb6b94c259a9ce6291e18a801a82456b93c221a625129a1720328f11574a5c35c3650a7b57619c61f47ed6319329f118f4c31358a26a7e9191cab61012a71b27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13d41256a0b442f0428de78f90609a11b8cbb475083712539e1ab034903c30f6b73bb8229ed50f901b142a597e7fe48b6333ac8e01205481b10eca15f509140987166d81cfb7417dac331ca141ccc61a446b285c05d9a68aac887aa23e17ba7deec8521aaa3088cb03cc7056560ac669772609c53153118b45d855f7dc44618b743c22c779145d58867d04f101904579ccb2cdacb28be7e019c01511644b3a9c288a1fc84658281ee2492124f609d4997765f315370176a0e3c327458027facf937a38eb88ad7c950db7eb5c49e17d48532822611d8625581b3b2425288872e00db25037542360cb5685bde15872a935069cc09d04395fd1a5ae62084f74b66da89263a11e8d177dffeb686a2445119065d8c59248f23e0d515ef2502177bb273ac62a9fea23e0e48c9224596c44ce974650dcc81ae7dbba062bcef017898beb0625c75eb2ec3444f20eba3195f5f9018309b026a32d4211430eb1c1eb2b7d87b0c282f0a04633499c3a9478a7b755e0b1904794f5a0b94f52c05300c838c67f4c26803c52a042812da9c8cac5650c3367a770220f43e3c039c3109a506731076c8dd1b1d99caafda48254a73ebfb66849548733578aa80987b45a404d892f45f83fe6260b4521181484a7ab65aed79a53f2e495ad444066d1108d14c4fa74847fda990a783fdb923734860238a94b8634217de964ea35a3d4c651a15c719301a2cad86352257c2ca1a87f329092e18c5c782ace76ba239c6001143f87a0406da9437d7b19144386b9687023a34a46814eae040c71673aca3993acc03879c9af60ca0e4eab9205b7ab65c33ff1295100d349f84694abe062672135865494ecf58db2912a3af380c228b78d329634f359008871769696bb357d552c3e9fc17d8b636e1b905303bb2a5b6a6f07f478d4229daac38ecf47c205371705b72092f7a438d01267783e24370080362c659796d7443354d92dfb9bca5ba5355e5c3608bb3d9b312fc7ac435b81cc1a6ba84a74283763a520381e9e3c998dfba80d8383d416495b42b7b6ca3e91789c8191b894350f52b6b7a3e38a45f50f39497794e0971650c446551d7d304c87515bb415773c10bf08cc20506c0f515428e8b9037c42a837469de6a3a37c695b602407a46b7796593623a9c840accb5a6b1175a30f62c8b9461c444eb73bf1e22418347af3d92742175bbfb41474156745eb0dcbc4077eeaad6c13c314d3188d3c9bf2f73784c0cd1a215c4623a8bbb19997d82be2b1719346190f054a1ad92819d9b812028633469c3661238fc66cab7c05bc5468a132c9b3a50ea5a4a8ea04800c97c3b391115725011e597312b7a0440ac2da794859776ca73b550d666a8f058477a1a0c9621ff6184f415114d35514909719234c166734b5535b863afbcbc5a2264a86b0642a41763b6d6da15447bc930f925415abb3170337c6985c499570dfb98430a56cd1784eeae57a5da37862790a282b8db833ae37bc5a6940a8b95926f1f468853b288c9a4c7c128bcb56c7a218c3fc725ad1b89c829799b0a8a1f3718fb489b83b900f1cc9b1ee16369f18b207d022a35224330582bc4848e4634f3490c12c756246dc9f3cc27550057a1863ccb91a4b891820bc882c0e6024e1bb037677092c633f2cf68b96b666e1034339ca3e43f6ae7fdb22f9fc7649e559e5d22a07075bde79a82e62b5a5258a0e685a2cd1bc8566cdb4a19d5c581236f0cb4e7aad6f561ca9f6850d30a6fa0c1eca230a06e11cd6f26194f56f40bbcdc99bb4c1f32c851bbb7af48f19d813f89b01d9477861e128631b9b4d72c4c7ccbe59462a4519a8a34a44dd84586c4a542aeb6e1338b6836297a59283af07ccecec01ce074d8469c93f509f09f7230c092c63f2245ac2137a4349078a473d81cb3f87cbdf843645500b932bc326a85fa91095e4513e9dac02d92a69f5acc4200bb1dc0270b013b1f2372bc75aa609e291f0385bbe9376953cccb3f99971dc9747cb913760506fb051ed186454255fcd642aff73c32743158d467b0ad012aaa439c9335b4ee23a426cad3ddbc4ab882076c2bbe83321fb684825b032059838e3d43da29852309b1a7c15c08a5669a3ba2200b34b7f325a5f47b479aa49984060ace979e9db6bb68466973a3e0030c0bcfc4e6c6c13f734b1731ca956f89341d37b1cd5c40bec802a98c674869c04571993e461446b2e2a68ba71915bbefc2d40dc8756b9ad9bab639ff6985e03b5a861785981a7b1449594d584bc1cc4ef7a4333e5453944c61d0145a5b6c999900df26299ccea5cc1d36fbb80c1a5e9c619a4347669377d541519ca47f06884b1984408d43b4133bdcc488bddc599c4057b14a027d051420a5c17cc1671f18a2128b58e9b7a5e233a6ed2da288130b51e47038c9aa2751556ba24b284515af73a81a6881d665426d1d27a8a763fb3b2caa19bc310a9c10024b7d722606c3b6f19c8935b744e28333df8b9480a0083eb588380e6a12d777862e5c7d3e1874e8b1405a5787e92accdc798a873539c133502569e6de7a29c7025289a9913cbc7aea55718f96f2b2c6394b38fec3a7b79238bafa349c03960750209ee517629ca2280bcb7df35793bf233fa074185a04894ac515b8985ddb5acab68ab379a639c49216a8ba4f9b125947150a907385e9729a7d621a5a9bf8c4a1234e6ce4411923c18ca0e925cb372c59220a502390e4c740571f71eea1083887a5797f5631f614f4e91184811892c6086b0f5bb6fc322afa31653509c8e11a8eb3b7d32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2e1f6c5a99a49d6b1b4aa18089439bb4c56ca465785bb36594ef2ebd3af20d5641646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +expected_public_key = 08aa6ac1e96fd9ea9bf4595a7cd565d91416b583be0c3355ef18b9b4bc1ea59135d3701eed6bb0b66bb320572189525bf4804a8d75a5f973393cf53ebed81a1f2ca339016e35617e77b58a38e15d417043e6174888ea4408cc8583d196042317f3c9571e6347424c032dd459ecb873d7f9312fe891a0a81261136690363b816a3b538923e56741cccbc86d477c629a1713e99a4be8aae2b3516e863ef232755fa0025e40a664b714bb5c8b2a42568d824246d069ba2469ca370c1417a6a632978dd39503e433ac8566708c21ab04924d257e8002804e92147db57a8d39168c709563e7604674ae830c176914ca2ed38b9e793515231b7e15b5dbac4027daafb276099c0036f81621f7dbac5d24c5067023dc6b219881cdb9f290bb9454adb45a45eb1b975b1094aab8b2a9afe05a8240476753ba802c15495c5034f9348ec8c732724c9703e9a08220854a29598cf42b6777a19eb462c4907f0a7b5a3e991a5d7c4d8a70a78ed5cd35dacf9e98c19c596ccc1c4710ec9b029700acc002a1c661c13ba1c25a1d853a851054546c33b1f4032e1f089e9c4c8af9a99c3c72ae4077272c3a37839b817b55a31ba99b66580766fa2180c35a50462c0b98adc38c6ac1d72a7396b28e36cb6a601cdf7c9857f5413d380a1d031bb5801890182518ec414dd78a8ef86edfc0a1f10572205b5593623c41d873da21aa60e3870348032497b367bb50dc6176d415ba54f8809b4155462ac6d34593fbf57fc7d5bf64c10af1ba368d52afc8e2ca3ff8467528c625b26709122c6b1b34648247849338a24005aa9100a790b054640ed59383eccb6415f7a15f2aca63cac12609113d843aea83814691072ab8292b7c5db1d973aa6c7b2bd1a4aeb4bb1d58ca7da26b2e0296211042488c0dabc511308791d7a8ae725c922ef374acc53d76ba5a12fb2a5bb94c309824ee119c87a62f5786996800af28d11e59a83de0504413351651d0209e98b76513747d087333702cff8463db4c353557632c8c46c3667623e012e5d7937f6b004bb549960c5760d15d08d1a4e85c288a2044d1362aba2962d2b078b7854f997abf6072c390342536a8ae8f62385a5770d4752db9f979fa09037bcbae54d4583e17c4be538100349a379502dc69c283638ecda028ba0cb1d21426334c4789715cb39c79cf408c2d1720afc8986de03627b28efb773ee612630b2ca1a0a81239b6020e1380ac69be3cf3742014c52f9b22a118aae7092efe8c93705c0a7a1a8849c0216f776695840bb0a168d5b991e4ca78af08255646000fd16373831f8ed490724019aa15c57307bf06011392859167d0ca6fe88feedb49878c7bb0609aeb604429710db83b1fa592c7a5e911ce795e093a9602875700306d38234e2a70bfad422df30380986533bcec5d8c119bdf3b99e1596a05a123e2d3acca83031ff778c2181f75d268d6aa98520c969306cc80863789724c0ec5552eca57c3d84fa141c69e07b39d9518bcb52049ea04145c34ad355cdf65cf6c1014f511b9c6bb9281fa243000781a99301c06b77ed606c0fa1eb5987e76aa5bb346cc85c85aca114cd0a51c06448c1eab496299515d7a1598940c33c8bc58db4486867158a09080b97674cc9a9f7a176fd5034c139b19a50d4355011e2b65d47ab642c84812c74dc16a83fedc38873145ff3143564c4aacf969f34ba743a14595bb0b5000c30b47662a7b4eabc0980aeca368573550c3148811386ee589a88a53cbc6be1ab2755e58441b6c87e83baba58b63bfd097f0d4922ea7c0aff97143666d912199fc4307a3bc086ab13d6a6481f411bf780b10f5e04a41f27f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9630c2c0dc6bf3987789bb59195f416f8661e6f5395839c68a0d85d13d0ccff807956a28124e47b5b3c9f3aeb9537c3403671c03d28a09610c89c8c6c69d9733b320382a84a6cc2b9407743cc66611e84999d11356115060e6c2c5f9610fa820d18b355b64890b0a88fe784a39ac0c9e539732d79a36832492439944b643436b84d4bc870b5c21a5e224e321a5e7a6931e628342ed4616fb4b1997cb12fe6be06b20e7794437512be498aca2c532c3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_private_key = f75196a57024be817edc544dbd552f6b42ba121c2b8ea95e55017856a10c5905a8bb2590e63b449364802c6b438fc19eefc875017acf652a8f0d6ab0f7f5aca1f1833ed3551d37419d906d2b55123ec14d5f109abcd9382e990628bb30d882cca8665957346c3a08553c870d32f77e66348ca9dc321960b7d50b09de64178411439c021899f2b8c583762043a4508c3160544ed2264735c600a6ab43c8515532130583298a11450ae3b7c99ff559a1d33115dc2d2489934518bd52fba1cb9a019d918464b59cc90941599253957364dcca9f95a08035f8be5bd36db6b19f1f191a6e4b7fcd493b7a41c90bc76fe882aa0f3b39b6f454785c5dd1d106c80960bbe5846d90bcde837cd277a039dc22427b86a6658f97a60101665f3f69125445647f3bb2d3125c80d89aae6096a01c24902321933909a8a2925faa1e7407b3c90c8a53d958c1c83465e557ab620e53509ee8c960b3c547fea08d4ffa215742113ed9661b57ae1b30ba5768645c632de76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0863273c345c4c7379cf3f873fa5953f53b9a026a4dc120c96e279085566c7d090eba276a0928693e639b5564a59c08aeafd25915f5478dd86e938a11529bb9a2b0b83487c696e79f1fd034ef000fa502328184be42b8959d9c0683f3bc20e71902423ab14a4744e162f6a2b474dbc4a6f21fc0432ca7422cfb253d0f952be9c13125458df8753f5d551caa38bcca1625b533051c5226c8768335854e7477064320cb765ab9eb311a1859b4b5a006d918bd8508a971205e6902897cf95e0b652e09030794b46fcf7a784560c0a18b8e6334a57ec177ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa0104063696f1020bd1b443419989798826e141a24a3533494391fa233cf848451cbd609d014508fe137534c42d6f22ed2cb82363c847865aa243ca993b14992572cbf5535845cc708bb09a1e8a7834c200d8036768755afab53aba85813eb859ee83efea7563ee4bc158599f0cb04033393c829aedbda289ed852e1eb1feda9484777051f967e048041ba3c313a1414d463cf3ec36801aaa1aa540deab122ab530ecaca30101a1089087311972b338b045a1637189020c3030e63f707feea9af844c7e1b20b4a5348c1a432f341bb9f598b8c0c2f6f55c4d2c2c22b187430748f82842daba92283dbc4bd20636b6754b20a7127f01fcfd4013a1155e4746dbf3ca1f34991fe7c39ed99bdf5760d39db8e6c428f2de8157be0139415aea96bcf6fab633f2257b582312d3c7acaf6a5f8e55ad699672160ca01246545059e58502e28199cd0f5505adcb91900a283f0b059f33d1a8b352010a3c815717fb3a9482c946df0c74a526353d5c9ecd2590c5050996393a02286841580ab599bfbc8838a53301bb11d5fd492af40ba26224505969d88f6b193ea42b0348954180e17124ec2c64b962a92aa9c3fe2d72f94301531c4aaf847243702bc8f9c37d64b54f20ac003b844c52417e1436d2e75ac09c313c83b8575e791a7c95d0412cc61521a6826997561485dec26ad7baa8e065e9a279add7301c5c74c5b95c1b6915e69c9a6d4b4679fa180aca9817d6817e17314da19501344231a58c8547148cbf38081a8889c00cdf77234d04169ece6bf0abca31517c986c44ce771a32feca99df60524380323b31d92c9c100749825f30e1f7c9c079907a5750e3f8b18ad040194092093e7934219a5b11b4028281030774818416d53854975241efc6bb8bb751c5069b7099671d0768f3bf74219142e88e08e58642b41b04eb66324392b094fd0740cd4585a27ccb3f25ef972cc26b9512c1900f8b61040ea7921d21f142c7e1a99b886e32bb80721e6c75f6a999328a2abbc3c797965c09b2081671346355b4bf8c78c72c6cd98d0116db3423a1b69a0f80515e423bc1bc6522b5fc77abe492740d6fa8227235e3b7226fd89064ca494e9012f1cc62b02f95523f147bb321938cc1fafa4323173a8df6264959a5a6052a3b218622007af0408c3227a053dcb71164c9a80cb844f59050b113f497aa3a65c11c317c9e6b6a6e8028c23fb4589046a70db1026f07aba9b45ec78ca14d9babcbc2e62ea6130d8414e98b85de8a908aa6ac1e96fd9ea9bf4595a7cd565d91416b583be0c3355ef18b9b4bc1ea59135d3701eed6bb0b66bb320572189525bf4804a8d75a5f973393cf53ebed81a1f2ca339016e35617e77b58a38e15d417043e6174888ea4408cc8583d196042317f3c9571e6347424c032dd459ecb873d7f9312fe891a0a81261136690363b816a3b538923e56741cccbc86d477c629a1713e99a4be8aae2b3516e863ef232755fa0025e40a664b714bb5c8b2a42568d824246d069ba2469ca370c1417a6a632978dd39503e433ac8566708c21ab04924d257e8002804e92147db57a8d39168c709563e7604674ae830c176914ca2ed38b9e793515231b7e15b5dbac4027daafb276099c0036f81621f7dbac5d24c5067023dc6b219881cdb9f290bb9454adb45a45eb1b975b1094aab8b2a9afe05a8240476753ba802c15495c5034f9348ec8c732724c9703e9a08220854a29598cf42b6777a19eb462c4907f0a7b5a3e991a5d7c4d8a70a78ed5cd35dacf9e98c19c596ccc1c4710ec9b029700acc002a1c661c13ba1c25a1d853a851054546c33b1f4032e1f089e9c4c8af9a99c3c72ae4077272c3a37839b817b55a31ba99b66580766fa2180c35a50462c0b98adc38c6ac1d72a7396b28e36cb6a601cdf7c9857f5413d380a1d031bb5801890182518ec414dd78a8ef86edfc0a1f10572205b5593623c41d873da21aa60e3870348032497b367bb50dc6176d415ba54f8809b4155462ac6d34593fbf57fc7d5bf64c10af1ba368d52afc8e2ca3ff8467528c625b26709122c6b1b34648247849338a24005aa9100a790b054640ed59383eccb6415f7a15f2aca63cac12609113d843aea83814691072ab8292b7c5db1d973aa6c7b2bd1a4aeb4bb1d58ca7da26b2e0296211042488c0dabc511308791d7a8ae725c922ef374acc53d76ba5a12fb2a5bb94c309824ee119c87a62f5786996800af28d11e59a83de0504413351651d0209e98b76513747d087333702cff8463db4c353557632c8c46c3667623e012e5d7937f6b004bb549960c5760d15d08d1a4e85c288a2044d1362aba2962d2b078b7854f997abf6072c390342536a8ae8f62385a5770d4752db9f979fa09037bcbae54d4583e17c4be538100349a379502dc69c283638ecda028ba0cb1d21426334c4789715cb39c79cf408c2d1720afc8986de03627b28efb773ee612630b2ca1a0a81239b6020e1380ac69be3cf3742014c52f9b22a118aae7092efe8c93705c0a7a1a8849c0216f776695840bb0a168d5b991e4ca78af08255646000fd16373831f8ed490724019aa15c57307bf06011392859167d0ca6fe88feedb49878c7bb0609aeb604429710db83b1fa592c7a5e911ce795e093a9602875700306d38234e2a70bfad422df30380986533bcec5d8c119bdf3b99e1596a05a123e2d3acca83031ff778c2181f75d268d6aa98520c969306cc80863789724c0ec5552eca57c3d84fa141c69e07b39d9518bcb52049ea04145c34ad355cdf65cf6c1014f511b9c6bb9281fa243000781a99301c06b77ed606c0fa1eb5987e76aa5bb346cc85c85aca114cd0a51c06448c1eab496299515d7a1598940c33c8bc58db4486867158a09080b97674cc9a9f7a176fd5034c139b19a50d4355011e2b65d47ab642c84812c74dc16a83fedc38873145ff3143564c4aacf969f34ba743a14595bb0b5000c30b47662a7b4eabc0980aeca368573550c3148811386ee589a88a53cbc6be1ab2755e58441b6c87e83baba58b63bfd097f0d4922ea7c0aff97143666d912199fc4307a3bc086ab13d6a6481f411bf780b10f5e04a41f27f5784402c9b5e1ee459fa8c4705f36756b34989bc63bb9cc9630c2c0dc6bf3987789bb59195f416f8661e6f5395839c68a0d85d13d0ccff807956a28124e47b5b3c9f3aeb9537c3403671c03d28a09610c89c8c6c69d9733b320382a84a6cc2b9407743cc66611e84999d11356115060e6c2c5f9610fa820d18b355b64890b0a88fe784a39ac0c9e539732d79a36832492439944b643436b84d4bc870b5c21a5e224e321a5e7a6931e628342ed4616fb4b1997cb12fe6be06b20e7794437512be498aca2c532c3a865fa2373742da3a4067a7881ab97fb577618336f3d9750fc9b04e044922246c645c74b7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bdb8aa8568431ffc4681caacecd4475c838cf7348402a06413e7a9590ba405ea5e79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +expected_public_key = a936ad0edb0ae5a6b9a66bab5538cab0ac6e0430bebd798c474ba1ec345ea6d3ba9fa0377d46606e70c86dd1be281a9f46fbc0d890c607dc009f46b459958989852b5582566cd30d02317cd4e0b84e6b1917e692e45c9beae45bc8e8bf6a65587f206a67d93a4872c571200bbde620e2639659302068088bb2d8bddf33c98ef34541b4c2a22897815b809b060f86200aaea90376234860a66e9e8843bb52ca7033010e47c41d573fd9ba40c4faad88026eca797e80396a2ed5586f8109a44bcac355117a7a3f72950030cc506482aa0ce39369bb350fb07b1388981c89400ab5a632c172d159c6f0e126bec96e17c0c18c615be5110818e0cfc2900f76d706aec990021aad6eca787b453991a896f4622537051e3e4a11a0954995525b8f2b11583a3a3e594400ac97b82a4b5da822891910c721ab0bbb9942f2ba777a0c5d8c532393934b391fe5669850bab01740905b684aaa96be0cf50df463406b91a28149174b555c742c3f78569bf294681ca09a336531edb94bf30459893cb2de348330fc56a7304ae2f7cc33d13b7966751414420dd089a48a6036c1cd7c5608727b52612864b63694005590859aadd91b068b053453d1c6f9287c58aa042073087f7959fa932284231b39aa991c0523be599ce85b1f0fb52d465156c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eab32960332860e2a25b7a25e86d0a7aab0226e877f0488877d941fc0a0541461b8a4744de6456df6c5ae6c621a969a02f9c943f68a48809328a0ba3892d7af2fe169ee41554f0ac1a3836e151760c8472f60b77e274948ecb6748c404a74005bde6c5849401fe2d667748b9f3c19a41d659474b0b4a6829d848a898b93080c66aae85b3660d392f34a6ee9c6b10df567dce1892f4932b6babe31e0a50f8217985c6537188b817b3311c25e8c63ca265b568ba9cfdd451e6fd517e18317fb99c8204abfdc937134e845cfe00018e097022997653a8d5be32cfb07b34836c242b74ef9d30ba0d7ad8c2b2944c766c025804eab23a05b6fe6b85d331904c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2e70e1a63815c760da8195bfd431a9fd88443e26dde85c5b08091cb19349cfc73ba195923a38ab6a044d1c9cbe498195c1b5a27a2b07b627c141cac61d391ff1b88c9893327447d32234705d42f10374b77c86d83d71e3711893188310c45c51a5473003d8566d87fde99c67b962f6b4750d7851d3b6201a2faae68fcb1011404b252bcdb341e68702c8dd6a237813e049c42aac05977637cd3c81103e1973f6b45b8b0b56f69afffc9cb5e97bae9b6c5809abaf47b5b0b20471bd77ec7455e1dc25fbfaa7018e58133a44678083c06e06334452890a35240526225a33736a042b1595da8452c2eba086acc1a6cba45beccbdfa23acb2f01cbeb75ff179cb39242ceac33eb2889c4784cb970938ad336da5dc013aaa2973043372cb99657297e7ca05702992b578a65c00c867b43eaca93e975695f7625aa8240c0e5827e1636d72ec4a0480408f911ef631b48a1c4462665b230550924b23481bade7b43a1d76cbe6791e33874182f955313cbe69bab35aa59cd1b133fc326ba571713a1c4dbe2a662b514021bc7bae44343f39138444173dd7944c6291c50973ff0b9c0aacad9409881ac232306354d5362537b507e2ab84b4a0a3b5b9819e62c3b6dc1fcbba0224b48da7114dd4fa3103069caba17c09b7bbef8b94b6e15f58321b708c9c23a40288708ccec56f3fa2bcc7397101fb9e54fcb7e7e816f149356570a006f69779fa6e30b1310e6bc6d983599eb81c202c5e887659f5e7836fb7a72eb80474116c6659c24dfc4c38dc2e8d6a0787a3b6c170a23ba53865a53849f4c3f25b2363e582bdf079793bcb832878b0f7268f658b72b3417135684393a4b1f40322ba7fb147416ff0b58d3b62a7343a6c51b4c8f6894f0b05e33476ba24c61c276652048b009ccc1a768e48cac707a42f4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2ed2429d547b4da5176a7b621a38681ccb3e72d98f1f9926b1b30325d6cbd3862c7d044dc16b8a25dc59c2a53e295040d7627f744bcdafeb522cf8ca6eaca400106b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_private_key = f8fb5ba9d24c8681558cd13593f0cebb335b6f65bd5dda6de6d19e09f15165051f981ac6472b263cec43883a79149707093066fc129ae148b04f860c2df119f8a51056eaa5dfd89bfc564226e56dc391ade1cc2a1df58edd4572c5a147bbe21283b97f1b213bc276a471b63a7df1cdc86c7a69a34ed17a425b37aef969c1cd079529ba29a2e2c3412c5615e23523f3124c00c778752bb9b3677b90885cc21b0e257bb7f335fd53928b737d19da3b3208219e6c898e96b45f801135a09a1425a0986c597e2b4042c1a4e6d7a4d0e30e729c73f2bbbe85b579c3c13a34344a7403b95d425936486c3b602804c08ef6f5ab22c400b9523ea3345abfe666023bce6a1b63a872c33e3aaf0ccac2c40a4d5a48107d0c7ab09001ea67ca6f4c1fa7137d259c860d032c396bcbcb4177f82439852463b640855ce604f91c8f2e4a0899b2102c6059dc077d5ee6054355c546c2148077b8defbc313c71f1a420dace126b16c21e40064e2522f9e224cc8e3526b1a99a2f4a81efc2dd3609043246d461c7c1af025b56a9c7e72adea57584cf044c2f0bb60352c32400d1631c034572ee46b71edbc0334031aed7bc26af543028c3918109da52a6abf3217a2219c0607ba9edab5b4daad5ec7948393c4a670c340688541aa713b596843e5ccb9616b54e92610539bfd39159fab36d4928ee9cc8b1291ac0134257e242faeb595100ac113ac416ff517866021b550b6d063512dc37477117d025964c95c13535c2f09a96740037fe1846efec4446ec03f93fa6b6fd8b539f0196444a61823b08cb74b7520618c08324f0667f142beb3a34c2c5286b3d159fce3b046079f07e558ba28a8893a8c94f9711c227fac6900114c8bb6aa5369b059dbbca008482a1843b62a1b06c68c6b2f40bac6f02b6cac1633055a178a396ef35f59f1a76543953d3b07e2b8be217c5d5b1a82f9c080f4119d22275958026280bb8c96626c1d0baea6658a29546e09418aaf85a121f8647cb4789484bee0189b9ab10852c397a2e25b9b15b71ef17440dc3554db740289ba05111979614aedcca79699021f4bc3a4c68b39d0256d88cdd7a24e3ac31dac35388720671a12a765d705f8429d0891c3e0d8062ad45a0b882bc53016dfb007d1c550998963d7e12fa51c7361d86156ea3a8ad7018c627a9ea18f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50e8170892a08fd15cf2913749d0c61305c4de45a1ba2550009726a0873c70049705009dc8327be3610f61f9bc60a26d14dc0c3e67cdae4b5ac0d5a0638804d6c6b4ceb351f0c19f0974324cfa28fab704b4677aa3f2bf65686c22100b74cb9ab5f7215452cbe8d6909754304573a9314b3c8362cfc34c6302b3cbd5dc482e76576fc5900b367016c03a860a88744928cae55413231ca8a5008d210cd2e317d1bb6bc8624ecb83002e66092d8aa77fa0c6766532178a8cfb532c70f1114e5156e91486c3c7658e2a22cf0a77873c944a5a4bd70ba1686146e18b328d30813c9850c3003698c5afa2082b3425c785200596592fbfd7b2ad5568f9d278fa24c523251bfc966a69ca882e707426563d2e099295305fe2e2a96f968a92e9423dc4a1f6662f68299850f81da13ac23e272a8b64be3ff3bfe61563fc98c555ecc6625b7a84c79c6550c399977ceea525b12a52f9098191b004cc6b83a8d89a63756ca9460fd21758a0701e5e71280055cd3ec2a218168d38e78861ca2d0ec6c56a880f5091ce656bc4dee3a8061801255865067982744439e83b893b3055f67466a8b722ee0339c46160d4c40cd92a2ed5601199e5b214c9c48d311e3b26032377b637ca10c5579b7bb381c25bb7bb82159b0b1ac9592a9e9817ccd8b85631adc7c44ca1f6a8e7529782302dd2266fb0a7b04fc16857f034b50b37b723b42e747947e1a6ffb1c8162181be23a1c82ace8d4a1bf522143e495c39bb9e63f17768411289087258e6a07192656c7269ad688bbc5cb66f094737dbb85ef146c0cb146c7010ccca769aab3d0e3b52fc61b637a02bf0c7bdab750bb7a9a367302a4f3115f352675b2b458eeba2db040db45abb314c5583785925bc833f82caf0d6687f87220652886aba525cf89900e0b6fe4493ca61cab752261a432cd34121ec58348f1aa59d4476ec8b5da936ad0edb0ae5a6b9a66bab5538cab0ac6e0430bebd798c474ba1ec345ea6d3ba9fa0377d46606e70c86dd1be281a9f46fbc0d890c607dc009f46b459958989852b5582566cd30d02317cd4e0b84e6b1917e692e45c9beae45bc8e8bf6a65587f206a67d93a4872c571200bbde620e2639659302068088bb2d8bddf33c98ef34541b4c2a22897815b809b060f86200aaea90376234860a66e9e8843bb52ca7033010e47c41d573fd9ba40c4faad88026eca797e80396a2ed5586f8109a44bcac355117a7a3f72950030cc506482aa0ce39369bb350fb07b1388981c89400ab5a632c172d159c6f0e126bec96e17c0c18c615be5110818e0cfc2900f76d706aec990021aad6eca787b453991a896f4622537051e3e4a11a0954995525b8f2b11583a3a3e594400ac97b82a4b5da822891910c721ab0bbb9942f2ba777a0c5d8c532393934b391fe5669850bab01740905b684aaa96be0cf50df463406b91a28149174b555c742c3f78569bf294681ca09a336531edb94bf30459893cb2de348330fc56a7304ae2f7cc33d13b7966751414420dd089a48a6036c1cd7c5608727b52612864b63694005590859aadd91b068b053453d1c6f9287c58aa042073087f7959fa932284231b39aa991c0523be599ce85b1f0fb52d465156c795cf3bfba270ab9cf94cc152774fec76ae77b9acf0f37dd2a9547945442ada8eab32960332860e2a25b7a25e86d0a7aab0226e877f0488877d941fc0a0541461b8a4744de6456df6c5ae6c621a969a02f9c943f68a48809328a0ba3892d7af2fe169ee41554f0ac1a3836e151760c8472f60b77e274948ecb6748c404a74005bde6c5849401fe2d667748b9f3c19a41d659474b0b4a6829d848a898b93080c66aae85b3660d392f34a6ee9c6b10df567dce1892f4932b6babe31e0a50f8217985c6537188b817b3311c25e8c63ca265b568ba9cfdd451e6fd517e18317fb99c8204abfdc937134e845cfe00018e097022997653a8d5be32cfb07b34836c242b74ef9d30ba0d7ad8c2b2944c766c025804eab23a05b6fe6b85d331904c4c99a1fc992790a70f9ec52e25bc17b949b66f49040a59e7eb97491c546bb3778e2e70e1a63815c760da8195bfd431a9fd88443e26dde85c5b08091cb19349cfc73ba195923a38ab6a044d1c9cbe498195c1b5a27a2b07b627c141cac61d391ff1b88c9893327447d32234705d42f10374b77c86d83d71e3711893188310c45c51a5473003d8566d87fde99c67b962f6b4750d7851d3b6201a2faae68fcb1011404b252bcdb341e68702c8dd6a237813e049c42aac05977637cd3c81103e1973f6b45b8b0b56f69afffc9cb5e97bae9b6c5809abaf47b5b0b20471bd77ec7455e1dc25fbfaa7018e58133a44678083c06e06334452890a35240526225a33736a042b1595da8452c2eba086acc1a6cba45beccbdfa23acb2f01cbeb75ff179cb39242ceac33eb2889c4784cb970938ad336da5dc013aaa2973043372cb99657297e7ca05702992b578a65c00c867b43eaca93e975695f7625aa8240c0e5827e1636d72ec4a0480408f911ef631b48a1c4462665b230550924b23481bade7b43a1d76cbe6791e33874182f955313cbe69bab35aa59cd1b133fc326ba571713a1c4dbe2a662b514021bc7bae44343f39138444173dd7944c6291c50973ff0b9c0aacad9409881ac232306354d5362537b507e2ab84b4a0a3b5b9819e62c3b6dc1fcbba0224b48da7114dd4fa3103069caba17c09b7bbef8b94b6e15f58321b708c9c23a40288708ccec56f3fa2bcc7397101fb9e54fcb7e7e816f149356570a006f69779fa6e30b1310e6bc6d983599eb81c202c5e887659f5e7836fb7a72eb80474116c6659c24dfc4c38dc2e8d6a0787a3b6c170a23ba53865a53849f4c3f25b2363e582bdf079793bcb832878b0f7268f658b72b3417135684393a4b1f40322ba7fb147416ff0b58d3b62a7343a6c51b4c8f6894f0b05e33476ba24c61c276652048b009ccc1a768e48cac707a42f4e3b685cac54aee57203b78ecaab3a44aa8dd7daa43f2cbb2ed2429d547b4da5176a7b621a38681ccb3e72d98f1f9926b1b30325d6cbd3862c7d044dc16b8a25dc59c2a53e295040d7627f744bcdafeb522cf8ca6eaca400106b003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984984f4c4ef2371654067ce0f22bbe4648dc9d87eee23842f31affcdc36328e8db1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = 952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +expected_public_key = 6461a7a463b8e40c03739a6b5fd196655871adb3c82ad10fb2b2b538e61e1b664fbaf761f09b4d5e358b518088b3206e1295bfd0461a2ff8553b40cb92e36f0f928af9fc7ef54c358d88280697ac3d5548029c3faf882ae2da732e0c47934b9c98232c40b84a344421e708226ca6524c062302765bf4d593e2d75d3a783f1dd7328767315dda868e685eabc18fdaec2ca8b037fdc3607629cc3ecc8e848c771b94c6a20a28e3003778ba68b923b711060bb6152554707d7e4c135ae8663d87643ec4921c6a5c20ac69e67b0b795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e7b03189abf9b4a91eb782fed97bc3a6314d0ccb528b313d165b2910859de867d7d6290bbc85185b0201561af34b9656a00b2ec32323b26a04888786f81007362814bcc82862a7280a5cee73a330e6c2e01fc9afe2741b12166949532c884ce8bf2281aa4b860756463bb49bd1524b8ccc6ecb6051ada819865b8bbe1bb01141b77fa3ff5713f95baac10866303939c07483b6bfc500d61b7ad494382c643e87508e410c30fe96b37960ad4e707421944b13b31d6686745c52ef6ca4fff3074f19c1695038367b1218e8b08d8e6180870b0fe5b5511e3b4641b6fa44156c561aa2aa9a1e163aacf73c24d84bb764004b3b329ddcb0f15716e17c51c6c432ba1407c0d063b0cf2c073763a790cd0312abe6d26b0d75390492a88772763fcf67e1bf28e1a01c0a5714bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5e80acca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f052450875a8997c335ae85d5b790377301f5a094a5b43b515206067e36fe51ab9af296583d47450a34a302844b0526a4ef891d01c287602453126557a876c583c2a06561a88f9651e39929d0b43fccba48595925c01adc0677200c39c64e44505aa58a9b5c88311c094dc3aa5314f167247b501798c4a0d5d9a04b77c6552369542e96172573e727890fa3b2e3551286113221fe92f81c481c125bfa7a6199ef8c0eeaa0a5b8973c9a33807a464fd4a50eb294741c5a8fd998171872c0fd44ec86112e19a707dec768f7245dd2a6f60a554490947e5152dc3eb9d9e7151ff7188127b5313757431d3a41c673e203c7e8e9963d0ab1276b5c1114c38ec8cc0ba0a94918cbccdcc7dc5366704415cd2ab9a7fe55ed49498b8b7105fb312f4a153e394a019749a23dcc180236468a47d96d47be66a0cdfd16a2dd15aef826041192b8028b1ea782fbf0a2cd5fab19011b219099f8e87c74cc69841f4a927e181e98ac6b3db7846ec38c0ba8aa9f50ba7a423a474060ef165299b12786bc8c05a384ef129b0f6c06c1047e582c02a54aa8713422bb6b9a6a4195fe6843d7c639916943b5793107cb8e63365dab357cc02a9f1b33e8da29f25f9839d862285864ba790bf965292470965e0a9c1d1f65b72139908d791a4d89e489a983279a703a0c34222786e123b45c793c925b1a146c006f15fb4a1c85e181f8b1c6983e1a1d7210c12091d83439ac8a15d965a386be47145bb946162cb8869b359654121092d81947ccb5717e805478a7c0ea924692b361ccb730f3180c8f79041f8d366757528b0828b7ff9531c76690c37cd8072ccb1c36a195a84197a8797446273d686aea96fefc153f1710d98229abf35b6e6127f2e5a5c9e88a33a85a1006a1383988e3c72692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f0362c1f84954408ba3c9284442b59c1a4904128c0bbb50b2e34c98b819a1d6793de75697cd814ee162ae3dacc0d50bade8b835c3f27126731d2721ab61802f544967df987b5b0b02efbc95847a5f06113737e55ca4db20c4400580b5c241016b50db710d7555d8f67cca13b2d86103d3870d5713b217d03b3984334a6ca272d43911ec23db3b5c15139efcd510a95c96d68a70d2988adbd048122678ac8a051282bb4fb47d6d5819a3a9866571cf53b78ed80a76ffecc971b221bfb917bc69018dc0177468357292495d98a022634ea7b0b1f517734ee40d0e927919221ce9eabfa05596a801a342b87267ac9047129995630271c1c2f02a4d1af2217b65c05609b8745306b6a90f86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_private_key = 5b47b61ce23572623c431a498e378c6b71a5cdccb58e225310217f6f2b1b7140b97349b965d9c95332a66d7a9879f24c479851a0ea485254755db347bff9a06d00502ae3a910c06771aacc0a51add07a291496ac10e2899b6562dcda7b6b9b7eb516335d222c43498859d87a44cb8ad589a06e609fc5798ca06744051533d5c6154608c790a8abd776cbd2984b57e1cf4e0638c77915dd89249d3c0775b45cc159b44bd32f49a51a1e398763e35dbf5c6ccb100929c9b91047a1ab98a140e00f77f5076310c33179a8c80449591c4156c244eb8c8b3009328139c18f8c59e1961a2b91c840d552c2e4b3897265b16c28de6abb72d218ef713a1d179cea38561663c9bf21b68166aaa45748316877a9a5bed6f5230d3015193aa5a9e1b34dc6576b57692b543fff321b14879a24728de3d6a297c06ac6cb28ec3482da708abab28fa815272624af6e26a879f65c6432812470c52de01edce20681db43a967069dc9bb34f9c540a21b8d7322a3675fee059f5f655cfc480ba31255e899c48a7c25588303d67055434702ecca24d31a9d69796df408328912ada084ab122c6ac53c3c349c105270c9aeac73923614ea9129ce4c9fd8d78bd33045d8557ad3d0a698b34a7c073b93783670662f8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dee04497c997c9e74044230690354b7af23bd94aa02cf599554391095c0d53f5c1db19ac33189b2b9aa3c48bc4e09bcdc5029bd3b45a370c59045abcbfb257ddf30085da053056c17dd0b5ddc6494524875ac189e6c7a7cd483288f03abc155bc2022eb427b7d5093f4616c124b7c29a0043181c7bded83de7592511e3617a75652d4568d7c7b3ab2b7464c514ce6ccf54fa8d73e61834e534966620dc59196ab44b736151a27c02e065a000611542fc296a69a24989331ef980f708142d7274ea863669a52039b59d48b90bcc75ce4b434f5751cef621cf3a29873c003a57276128e70bb4aa5de581834946741a8134890491d37b6051959739fa8eb81c6947141704683124136c1c382760e13f00c59ab5bcbcef98b973831b91ba87fec02216619f012859faa6b01b1649786b626348182398226cf794095681d1c25800b18bf33cc71123898ad2aee46905a8118916ba8651328a051697f8041667789c874394e96a0efcda8998d420684217952496ae9117c6c618513c147148979f5c8bfef8c7ca1836430c3cfb66b17cbca63ed1a2157961cee600617157aad986b5021f4f69c3bee6ae181a076c3cabf076903bd59814352f4ee2c04a138ae0eb018a2193ced58981caa3bb032317499e6ec4bc5cfab8b389467ef295dbe7305bd1cd099364d7596b1801008ed734d7775c5606af0f1a2978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad10a025f46af233512b126230cf928fac14d753160bad961bdcc4d5e1b4edd241609a0adc6b3c6cc9660e5371d6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aabe0bf05f75ed0b092f332aa83808f897ba21906af25e68a88b61a357a10ece1977199203e465ef9bc020e145f6421abd11b18ab198549b67b4f0c11fd7b001e43731f2383f62ab90adb3e13197db7279020d212105236fbd8746722a99606b522c69648543f9e65558162235ceca379905100a2b98f32824ba288aa3cb7dc1734bd49c0769cc5a44483e0317dc62961471b195483683f774243e689ff504c02ec73e04b5731c49d0853494adccd6608a575388d245a312a1a38f1f9a17d26073eb3b6fe41175f362dfc697ce5d2cda6b0145a739e7879c17e277de2750733c9b539a915585c237cbb66cd4b1afa425ac5f22f06724ea5783b579331928b57a9fc407c56541117c8665aaa2df1ad0dd20d6a2911faf73c9e653d6baa0ee73720dbfca1f5ba6a1db99e0f87955fb85a253105156a2b9fd3c35c8ab458023ce3d381132b488c122beaf1b740a526513b31b63cca1ca8389f9a26e22c3ff1d50b42e3c71cfbc4465745dcd28b3811bb29e52558735145ec799614926f5a55d57c640f673e4fb176e8f56f73aba60e60a4cf464373f5104416c6ceb386b4518c7d154b86e58a04b2337f1ab43660b312f0c905bc776461a7a463b8e40c03739a6b5fd196655871adb3c82ad10fb2b2b538e61e1b664fbaf761f09b4d5e358b518088b3206e1295bfd0461a2ff8553b40cb92e36f0f928af9fc7ef54c358d88280697ac3d5548029c3faf882ae2da732e0c47934b9c98232c40b84a344421e708226ca6524c062302765bf4d593e2d75d3a783f1dd7328767315dda868e685eabc18fdaec2ca8b037fdc3607629cc3ecc8e848c771b94c6a20a28e3003778ba68b923b711060bb6152554707d7e4c135ae8663d87643ec4921c6a5c20ac69e67b0b795a6febe794fa86b13866697b15306f667ab867c1f2ebbf3cc63c5e7b03189abf9b4a91eb782fed97bc3a6314d0ccb528b313d165b2910859de867d7d6290bbc85185b0201561af34b9656a00b2ec32323b26a04888786f81007362814bcc82862a7280a5cee73a330e6c2e01fc9afe2741b12166949532c884ce8bf2281aa4b860756463bb49bd1524b8ccc6ecb6051ada819865b8bbe1bb01141b77fa3ff5713f95baac10866303939c07483b6bfc500d61b7ad494382c643e87508e410c30fe96b37960ad4e707421944b13b31d6686745c52ef6ca4fff3074f19c1695038367b1218e8b08d8e6180870b0fe5b5511e3b4641b6fa44156c561aa2aa9a1e163aacf73c24d84bb764004b3b329ddcb0f15716e17c51c6c432ba1407c0d063b0cf2c073763a790cd0312abe6d26b0d75390492a88772763fcf67e1bf28e1a01c0a5714bcc685570d34627ca5896dba36a6642c507680ec744ccdbace6835d052a42e2379a5e80acca643cc06b62f3e5ceceb4708c3ac4bf88af58c7cf37f43d2797635bb985f052450875a8997c335ae85d5b790377301f5a094a5b43b515206067e36fe51ab9af296583d47450a34a302844b0526a4ef891d01c287602453126557a876c583c2a06561a88f9651e39929d0b43fccba48595925c01adc0677200c39c64e44505aa58a9b5c88311c094dc3aa5314f167247b501798c4a0d5d9a04b77c6552369542e96172573e727890fa3b2e3551286113221fe92f81c481c125bfa7a6199ef8c0eeaa0a5b8973c9a33807a464fd4a50eb294741c5a8fd998171872c0fd44ec86112e19a707dec768f7245dd2a6f60a554490947e5152dc3eb9d9e7151ff7188127b5313757431d3a41c673e203c7e8e9963d0ab1276b5c1114c38ec8cc0ba0a94918cbccdcc7dc5366704415cd2ab9a7fe55ed49498b8b7105fb312f4a153e394a019749a23dcc180236468a47d96d47be66a0cdfd16a2dd15aef826041192b8028b1ea782fbf0a2cd5fab19011b219099f8e87c74cc69841f4a927e181e98ac6b3db7846ec38c0ba8aa9f50ba7a423a474060ef165299b12786bc8c05a384ef129b0f6c06c1047e582c02a54aa8713422bb6b9a6a4195fe6843d7c639916943b5793107cb8e63365dab357cc02a9f1b33e8da29f25f9839d862285864ba790bf965292470965e0a9c1d1f65b72139908d791a4d89e489a983279a703a0c34222786e123b45c793c925b1a146c006f15fb4a1c85e181f8b1c6983e1a1d7210c12091d83439ac8a15d965a386be47145bb946162cb8869b359654121092d81947ccb5717e805478a7c0ea924692b361ccb730f3180c8f79041f8d366757528b0828b7ff9531c76690c37cd8072ccb1c36a195a84197a8797446273d686aea96fefc153f1710d98229abf35b6e6127f2e5a5c9e88a33a85a1006a1383988e3c72692038c2a713bdfb266f22a4657548a91554c54a948e189a62590a3f0362c1f84954408ba3c9284442b59c1a4904128c0bbb50b2e34c98b819a1d6793de75697cd814ee162ae3dacc0d50bade8b835c3f27126731d2721ab61802f544967df987b5b0b02efbc95847a5f06113737e55ca4db20c4400580b5c241016b50db710d7555d8f67cca13b2d86103d3870d5713b217d03b3984334a6ca272d43911ec23db3b5c15139efcd510a95c96d68a70d2988adbd048122678ac8a051282bb4fb47d6d5819a3a9866571cf53b78ed80a76ffecc971b221bfb917bc69018dc0177468357292495d98a022634ea7b0b1f517734ee40d0e927919221ce9eabfa05596a801a342b87267ac9047129995630271c1c2f02a4d1af2217b65c05609b8745306b6a90f86eb48cb0a4777065c449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a174841a59db1202eb2e3744bb36b9c5a229a33cf9eeafca4b3d02d155d870b6bf62d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +expected_public_key = cc40bee26ac378d8b540992eed54b23676827aeb4bd44857c2c21d55d72d0db795b0b6c8bc9077aeb59b71588abfe926f7ca57d305141012a41eb063f5281018563eab7252c34aa832a4bc27dacffb008e6d255cd547a0ebab65f410035550297c50b1a637cdef9172b6d4ab96ac598ad7622c34c3b98890c77cb9a5a08e3411a235da946c92a81d7bc57998175531b203e21e3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2991def527fe6c838d3e1221bb7a48cf7a247895dc77328a07b8c342c731d24ca8a83b9cdd7a47025467aa81bbb0878ae5c8e6fc0ade2f88c68a328fa132a4b5a0298ac19f46098a451870993015360093bd7b0ebe3929a028333312361e07a7dac8c90b50019e73893f78d097028fc5714362c41dd42c4dd71cfbea58e5aa96d82b03f5ef65d572957ede919e094a70aeab998a55ae4b2988890c88ffa1095273b132550068337586284976a30b0c538474a25ec076960d1bee0620a2a875fc53054d28042674b1f51b7877629a1fa815e2ef578afe936dfe5c7cfe6472ae7c264809a3a1285f6a156448246e4e832c75439cef074f62bb4ab5a4bebf24a129c046b0cb215552d126c32ea74088a2a7da6bcbc380354a00642ddf9810ca8c0df8296c55c057df32a4aa14f45192846e31c38919185e2c77cfa199b2003b80a5d6a867cc6764fa4b907646cb923e39bff6a14f335392363890cf66a10026e7de62d09daa31a50a5458515dee1ac7e092dc19ca6ff506dddf67aeb26ba4d720a92310fb942581f69024ba975598c97c41a6112c812aa6a21258060badb32dde0a5eaaa4fec6983776b1348c06a7877bb1b44223cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a277625298f403114a018b8b78af433a15a69de14158657ba05855bce24402243746de13728b4c4359409a282b994f3053777a72e6c30686eb0e4746b88ab57fc9f2558a1a0820c59c2cfc801b97b0206833d4c389e415330ab87ff870c90f86218c3b2c058b97b1e595f87703f6d34118965cc88423e3bb4e182210c225902fe3229e4559ae8a231b34395989c732f54be1b90b3f846adcfb5a36089f1b057c70931921fb36207966666413c8998c509a6268a6bcc1271ead333060d9753820a0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040ab2773976ea3e6876590c152c897d59543fb576e6ba22f9b312995f9969c91cb9098aa2046ac4bc69a38ab5c7a206eed57514de7821e64aa6626299c99b2a7299dfe933ba386a19ee01cd7a24db661356a19a68f68018a6847f56c0247346e294158c36c3da5e51af8604c3ff26014648f310977ccf8bfb36316be8321c71a4e1745237f964b5df9b67f8699454a810fac4fc83493aa2a7e4af61728759a12a769fb751d0d2125413cc0d4e0b5aabbb63b8c8ac5d385a95094e0650d16009da134c36a7c8a59ba90260b9af69542add7a72922c8dbd2b9e1dcbf39e6b19a4815d1544d31547f9c336baa44c835805c1a03610c0ca2b33bc44557583da206ccdb50f1c7309de949996ac72fd9803ec5bb7a151fd8f0b4e78008e35c102a33a9412b40e4b7a247864277bac3c1409006a75596d0cebc52621e91a7af791672e29861533e765257beb06fabe44c20f0a44a288c42d22851433c2be639404aba3e6b356c4671906a375894954849431f71717dbc1a26b19258db8096138cf83894182c88c6d9a56d718f489040667184ad175ca0b02ecdb1b5fd0a2b785197bc696a68471c9b486d7596657318bfd1f46aa29414c436c0f69252ce96bc09837cb4325903bb15d81b3f5c62cbb8dbaced7421b4361a8c196601b002f79877158c97bbc80072ecbc8b69557a4c60c8e90d23427dc7ba806ba6234189bd874c30ec696710c53540f74bf61b2a777606721952f930358b55c183db4f1ea17a761a0cfa14c55ed47cfba737bc75725c3471aa8b563050bd424512df66b0684948d068b94765adacdc5a24e18035c5164c54ca64171143a023a7a07ad8b5ce3aa095c7307eadd6499d89cceffb00f635334a3c91785009fa6a93c1211854882e99b7a32306bcf053551bf99f99c8a458106a55ec98a0c06c7c58583ed757956a89533c6c7b2867b8d3a5fef526e13abe818919fb03a7f9f0cfa9025fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_private_key = 2c021f19322a908456f1677d31dc8a4a2a734a2571d19c421c47aecc507c3c53a931113290b693afd1b7ffeca87cc90b0419c48bc4359d64146d9932beec78766408f59216c692228fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c36828224c177d3a3ade3c2c20a907c830bc32906df70b021b47c38c606ef951acf7c1512ac15fc0d761c9057a7db1ac6c56198f9a8ed2f67a0f159a5ee6612109254d57745736cc3cdb634f5658fb684d805888fea8582135bd4890343a545e4e0a6f0c130b8539125ab06358f8bcc0a4b44a7a4903d018c960ca45779bb564a30cf1b340b4c317cb77da50bf899c10b4676f3c295b90e93c2540a9e17c3bde560f351c81c58b545306449585718e9199a6302e3b0ca1e737c07a4b7e21ec154604590d415f4b82778778905360cc2e49be4b08c94a744995f18959d4492f0b7a3f53a98f9a8d914863b9583d866712fe583fd2677e8a3b8ba5341902178824f4c41ba21cbf7a4b666acb413c31cfa744b9a5405efc5b53a2c64481270484134753c1b0407e23b95850a8c026843643e42b329bcbb7422df5cbb968b04f39210a4ec959e1b5c9cb32a180588b9baa690f7459b1282d9e9200bd1a0e910a3efd948c3bd0af04d866edc61c866b48d7aa22e6fb5025c6892c66116e271b998b888e0481abda592c8b36f7464704fc22c51b5ba995928fe03594a8073ad790798aa304579822255e61d11557092bc9b5bd4c94068c60b2940c180831c5167487b7538c9ab47dc268215c8c7f324563d3973fa73bbaf07c771b15070d880478d2693535425fccae0f8272cd7224f3795a70241d480425e4a74922309906e1c11c5107e9f34fac3536354100f911234d55769b763cf2408b9812aa6b7c2601161953cabf0733cd3af819f5158a136621fb159db3dc6c3f3220adb8acaa8cccb7cb2ee583b9909c903ff43612d178c568aa7e9217e345cf4daa9aaf17cca1b5a4a5a73ce9b0581e73bcc019bce2b68c8c273dfe588ba0861c5a73a6edd9bbdd66935af04e5ea81a55d62c9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddb425cb4189ed773d8adb91e2708f12b78a0105bffee30873c1b6d5d5469f6464705741ec4310a8185a1553372f6091c769109f19527e95a6802c2a49127077b21126e7531a5941298bae199309cbe00d97513bde1ac82292ca1a76957d20a306932f83994a00f21d89519e16138f0477667f338a67450e1248a682142a79d9ab6b58b88754362a32af3402d062a554ca8a40da0481ba721a9b023da71987b744c6b9ab5e80830f8b7200241007f0eb72ae3694ee92814df4b1db269f4404cd0c77a844d2b751f5a0bd1cb93d61a628098d0eebc941827f77139831575b98e47b7dc3676d887b56d0ad96bcaa1f280049776339cb3fef6489dbd26205530cb08c53fb0839b49909864ab06b2c3fe15957dda96ccda90c51904df02c6a1e5846f892a1683838b9760ab900664a1a039b6a1c75f9c4b05340ede9881f48869dc881da0191e24bb5aec448ea052e57e69edf254575fca87a1b50e6d39520630688b04328a70ca1a871ffbcb0a8823dfd4747dc859b3472cfa9e02ec7f2c5b3b9a08e4534a971ca46f7cd93547ed32c42dfe064577a5291db057df43d59741da0a12ad930a14319a0d7516a26b5cdf32ca566a6cfb1099b2da1a37b487ca950199f9212d14c83064742ae46985c398749f392046bbf13638b19b716e6fb94c8d5331b14bfdbc2be35699627641abe618880d8947ef059696185de186069cb9309552e256987b4f071f79a9687d85fc61292c19548c3272cc8e34bba918eeea5181a52b68344ba8656409f00426d28869e397f077a675cc169a17264634a0b2341b758a37d54f1c1fe154893a1560a7b10618094f8c060330cb03f978cf765133aa4c9482b0cc169802a8128b108b7ddc5718ed6377a6a11922b72d6f3bab633b3c820a42ae2825a43093f48bb73a0432c56b56565aaef028c2228be23618a6fb8b9d121700f8b25b79578bacc1d3d7a1ef5d16355a07dceda8a5b358f20641113ab967f75c3b2dc7f4c1c81f18b35f8e573d8039466f210b89baa4752af1b45b2f71b5642eca69f50789fb153c7f9b62dc29440b36ecc40bee26ac378d8b540992eed54b23676827aeb4bd44857c2c21d55d72d0db795b0b6c8bc9077aeb59b71588abfe926f7ca57d305141012a41eb063f5281018563eab7252c34aa832a4bc27dacffb008e6d255cd547a0ebab65f410035550297c50b1a637cdef9172b6d4ab96ac598ad7622c34c3b98890c77cb9a5a08e3411a235da946c92a81d7bc57998175531b203e21e3cc9cda7d4bdb46c517c08a1dbb5bee25cbdf2991def527fe6c838d3e1221bb7a48cf7a247895dc77328a07b8c342c731d24ca8a83b9cdd7a47025467aa81bbb0878ae5c8e6fc0ade2f88c68a328fa132a4b5a0298ac19f46098a451870993015360093bd7b0ebe3929a028333312361e07a7dac8c90b50019e73893f78d097028fc5714362c41dd42c4dd71cfbea58e5aa96d82b03f5ef65d572957ede919e094a70aeab998a55ae4b2988890c88ffa1095273b132550068337586284976a30b0c538474a25ec076960d1bee0620a2a875fc53054d28042674b1f51b7877629a1fa815e2ef578afe936dfe5c7cfe6472ae7c264809a3a1285f6a156448246e4e832c75439cef074f62bb4ab5a4bebf24a129c046b0cb215552d126c32ea74088a2a7da6bcbc380354a00642ddf9810ca8c0df8296c55c057df32a4aa14f45192846e31c38919185e2c77cfa199b2003b80a5d6a867cc6764fa4b907646cb923e39bff6a14f335392363890cf66a10026e7de62d09daa31a50a5458515dee1ac7e092dc19ca6ff506dddf67aeb26ba4d720a92310fb942581f69024ba975598c97c41a6112c812aa6a21258060badb32dde0a5eaaa4fec6983776b1348c06a7877bb1b44223cd67aa088b6e0b593eeebbf320a76a95999f2c37da487a277625298f403114a018b8b78af433a15a69de14158657ba05855bce24402243746de13728b4c4359409a282b994f3053777a72e6c30686eb0e4746b88ab57fc9f2558a1a0820c59c2cfc801b97b0206833d4c389e415330ab87ff870c90f86218c3b2c058b97b1e595f87703f6d34118965cc88423e3bb4e182210c225902fe3229e4559ae8a231b34395989c732f54be1b90b3f846adcfb5a36089f1b057c70931921fb36207966666413c8998c509a6268a6bcc1271ead333060d9753820a0f1786faf467d9f645c45fa9cc8ba5d9e09629b47a040ab2773976ea3e6876590c152c897d59543fb576e6ba22f9b312995f9969c91cb9098aa2046ac4bc69a38ab5c7a206eed57514de7821e64aa6626299c99b2a7299dfe933ba386a19ee01cd7a24db661356a19a68f68018a6847f56c0247346e294158c36c3da5e51af8604c3ff26014648f310977ccf8bfb36316be8321c71a4e1745237f964b5df9b67f8699454a810fac4fc83493aa2a7e4af61728759a12a769fb751d0d2125413cc0d4e0b5aabbb63b8c8ac5d385a95094e0650d16009da134c36a7c8a59ba90260b9af69542add7a72922c8dbd2b9e1dcbf39e6b19a4815d1544d31547f9c336baa44c835805c1a03610c0ca2b33bc44557583da206ccdb50f1c7309de949996ac72fd9803ec5bb7a151fd8f0b4e78008e35c102a33a9412b40e4b7a247864277bac3c1409006a75596d0cebc52621e91a7af791672e29861533e765257beb06fabe44c20f0a44a288c42d22851433c2be639404aba3e6b356c4671906a375894954849431f71717dbc1a26b19258db8096138cf83894182c88c6d9a56d718f489040667184ad175ca0b02ecdb1b5fd0a2b785197bc696a68471c9b486d7596657318bfd1f46aa29414c436c0f69252ce96bc09837cb4325903bb15d81b3f5c62cbb8dbaced7421b4361a8c196601b002f79877158c97bbc80072ecbc8b69557a4c60c8e90d23427dc7ba806ba6234189bd874c30ec696710c53540f74bf61b2a777606721952f930358b55c183db4f1ea17a761a0cfa14c55ed47cfba737bc75725c3471aa8b563050bd424512df66b0684948d068b94765adacdc5a24e18035c5164c54ca64171143a023a7a07ad8b5ce3aa095c7307eadd6499d89cceffb00f635334a3c91785009fa6a93c1211854882e99b7a32306bcf053551bf99f99c8a458106a55ec98a0c06c7c58583ed757956a89533c6c7b2867b8d3a5fef526e13abe818919fb03a7f9f0cfa9025fbcf4677fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f7243d71bcbb46b9a423431b3b30947eda5fd81b526cce79a36730d8ee1be42c01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = 588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +expected_public_key = 5993b3dc543a4939519f942b982aa75743861387558fd01f3066af48080751346618e25c2501979f70cbd722528c713e9bf1b891043de54424f7022e45cc287b7a8138c842f1bcbad18795a382439c5c470a91309fcb8149039d0435b9b80a0773778111134c104cc5e7bbc455fc0f4d157f2afb40972c41fe85622825b5ac48c0e357cc2d953140015bef5cae1cd2bf7519398b610c9b191fa34767ee67880fd9ab6d5782350b176d3a7c318714f8208f71c80a1b189bf10827b763acf096b49cc5c0b2a21c268a6c69500ce889785825438890a6e7e399ede411d83a53bbf81fc0b0b472692db25b69396337b2724f1425aee7296fb29a399a16a13ce748995806cc5c64ac87783af77bc05329ba849a086304ebab9edfc5435b55503c2a6f9b996d75359e963077f4a88ee2e259a6b97635a3bc8670b9fbb94af2fa3046b51bee299bae327f1519ca170a1aa443ca323c1d336952a3d2342d481b10b4752e34c2f03866ee8c8508a77a4721c387054cd241bd54b8be0bba7be18616d3b649a452123e347f8f52c0c5ba2d9fe7560ad88f2bb77622212dff7474b2c250b0341d9ce6ae52dcbac5d3b99807af81744498031477b6178d4552d3e813483c3c6c4a73dd111e7874b7659b29db53946538cf3b51bd53d63dca591d16043469310c512cabc763b208a19099fba9f82b445c05bddea259a0156940e3099d97928c8079bb7846b566b4770c904b75b430151b3198bcce1830b9b8cd5381a1b255a880e49865297a801291f491201684c658d288ec63b8e6d423c4c9091f9552926253876629266969acd09a8c896ddac6bee964832bc0952b98a95ee54422da547ad9174503093835c74693047d782829f06327d11b6a646ae2e8703c3a6bfe9516e71915e7294a2d5a4ec8406792b55692c5591af95d3e7376f6ccc58caa2ff787a126193175162e6a084159e957d85383a0502bbbe091da6a62a7ec4441453306f74c40c483abe092a36a5876a60e1893c8c4fb3dbc946d781873d49cbad7ba431ee820f6e0246b5548f045ad65b0670c341d3edc40f331b59740ab0d167e02fa36cb23b10467084a63b9f1facabc9c86e6511f8cc6928de03913001927ec47e6b001264c9629343e10f945e4f9065e3985e8b4b3536b1aaac91a02a7b701c961a939388f57b310c4652d7649d604a0a7006686c5c0f467486e5248dc24be13f411fd524a6efb276bd75875d5cf7a18482dea41b4579f168486c3d87545b415ec495f37185b6762b754194f3f415f82628ed9884b658465ffec83f5213ec15264c454cb4cb46106c21bd8031d11fbceb50b7d897aa771748cc2e5a23fe99fa91347fa90c642b5410c2c4382b0a498f479aa94011959328eeb48e8222c5ca82930f5a4d40a7460a827c756c28e99a88440b0ca206241f4472c06ca74d48a5f565b8a85803e214f9a6cc92ab2b80bd16c0c5725a9c7bfc6067109600d8142a8bf681ee32b3d2bcba3ea21aefe0655fbe06c0c0c6b303c6b2efaa6e8e6b29fbb86cfd13c6e143d7b104ec625a6ab2c782bb88d4929ccf7528aee89947ecc33e5187bde373c21f2ad26252163a48bdfeb74841987e797048b506c8fa6c60f431294ab03ae304e1e64a1489a05976355f44b6bdbac7b81d2b003729f9ceab9190165677c81644a5820d8a158da62ce19657e947170472e67d87fc5c526b2db8fca728ef881198ff809b80bbb3c1652fb9a51c42aa89ce96844721a9da7274d52050b106c7505497629962b747e117c2970948fa1e6bbef069cf4da83314083f57455d9b031639202351bbc4631b080f936a1e017810632bcc19b41ac0fc7939d5bc6562b074eed4267b9f6a6d110ae51f2b6d9b39f46061031573c5a10c2f23b6879338889e05efdd4424820cd98298b59dbb720a101e8e62887303d5efb4ea99288199b54a3caa85476876d969b2ffa0b72754e85d3979c17155d784e3ed0a2874cbb9890b4bcf6334c8855f7ac45159a18e4f29ff5d8a5e5f34142c01e3fc53a2d07cc7f6c582718c434c062383bb60d4c54dd07a06d2642c8ca4920d5b7fa723f6f2540eaab1385eaa17b4339b8b3cd08f60e5727045fa947bec4c6e766b850f86b80d2b559507137234cd9856b7310aef4f50034ebbd5336c026530b5ff525c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_private_key = 47a7741316be87861aec518a9b38146b43aa54a98f47e242866b8d79f731d98c754b572a2a9170a7eb4b0d73b38d6665d1e43af0b61ab95cb54879707805bd787913ee369d231c600b76949bf86366579ab62724caa1beabbb02fc945bf007cf57a225afa67393cc58804a15016a12dfb90d5a52be41f907b1f2c4fe93712f555b0ae896e85931020089642a23e4c38581d4c40a46aa8ddb3c26db0e29fa5f7a12b6ca32cd2ab6b50327ad0dd8139ad83dce676ab2dc0c2774c86a2c72a5fa2d4dcab588a66d6551c040e91ae045698ac0a1dfb95048c545d08654c1b560384561ab07bd8c61182f99c79a2267c961ae66434321e8501d474ad84aa71286a948c5ad187232cf72576f167d63992f62d3423ce75577c2052ef84019404b0e1706ba704fe3d116a518293112b8b80708c094bde829ac38e362a404beb67026ea6782362035cae099302c5660931ce31b93b665059633699ec44c28c2bd230b1942421f12388900081618bb29e315beeaa090a06ac7feda567fd1a12d1a41eba931c279acdb875d9ddb7cd9a6adbfb32239e843012a8cb91776775408316b056fbc42758772c1e53ec0344479c2791b837a6a34aa77710d35593a55e57572fa99711bbe5a83454bca7990e834ba285a09aa11666cb2b2f39704904354687d0524888cf6461ef302139b042540138e322453619b3dd715b617230e08c4585478f9996798e9b47c712f82ba45857551ea4c79b4a0577938666403174e84585e684783d33f3b701420f66d48473fc6bb627b399e90697e760783a3e09d6531cc524568def8507f0437314488af7376bf2a6bacf783b632197d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85afc18dc81a8611bc4adaaaaa440471b530053adb874db67102b6a64ffca8bf8487e18b2f7582b71fd78d85f819c24b892741a83e67585b6b1ae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774e805e001b44c8194660a280d0d59bfeb35ebe9c943e626b98e488f8984275401bdc4959993345c38bc801b95d56bbb47a2b23f5f1223d5a0e2a827d4578948cfc5432627c9586275679202e3c970fcc980af56757912080072a4af234dd030ec481a6ed8030921691d6126839635c6b270497ca4a87d4bef47cac60752383712636752a4aa18af13bb36ef445fe653628704e4dc2cadd62839f9842f9b2c264ab4ff648c59d15708f55ae4a396d5f4bc75d20603c03cdec4252facc579a0cbd1f64a734e8350f03aceaa2734de2b486f6b93c36ac11803e564070aba97d2309078fb43768f98ef5d03b09fa10ffbb0beb3b5fe01310065508100206a640b93de87bd94a634907730e30800803b233b95d1cc7cce49c08ab143734347f3459a5be0230f9481d50b4b835a91736d6a7b351c8082a4d080967b43b0553835bf52943a380051f48c27823c5aa0b20b7b733dcb004b2a7819beba4b3fcb1f991789c2c57ca01b50523214af309fdf421187492c411c14128744bf4a83599a30b86194473c2bc9222fb4ba34108689aa8065aa24ff3559a76f759768c81a8cc5aa2a6792f3033b2437b05068bed096475d9280bf34980b1c478681e53190ef7165db8d7be89e82411a5cf76795d545b69feaa1a2065b7a5c00a50e6a0871393dd54af62e9b858e3453d9a86bcca62526837855324ba191f6c1914754ccfee7ca3be778ffed14646224d19ac50494a634392a7faf6b502772820a61de5bab6be04b7e2f2b8b05ccabb22cc4709a19ca96671b59f611350e4a5227503050ffa19c776b0bc26372049b8fe864e328798ec49c5e4128cb1498432061a5af628ea5c8922845b07300c49e7a929f76232ac2aef1cce07d9c7e8bbcce4f99f3b6b0b1912648784c69493c9e9201b8166c0725709bd56af241834d278152b5a96ce480c9c31c9af0a2711b58e8539b93037623dcb9561411d3c03c457f560b41ca23b2a7a8d66b1b686ba4566577a2a71448648ae3b988bd21829012d3cf3a18f4a596262a33579776b5a5b2c8a0e1a5c5e87c06cf9833c13269990719beeb2a0ee333012b8c1acb7321cca98f086aa4db73988cc49762ca541372566abb0ed081cf6201b4ee8a17c45b8ff6046317648bee9247b93b6013a405993b3dc543a4939519f942b982aa75743861387558fd01f3066af48080751346618e25c2501979f70cbd722528c713e9bf1b891043de54424f7022e45cc287b7a8138c842f1bcbad18795a382439c5c470a91309fcb8149039d0435b9b80a0773778111134c104cc5e7bbc455fc0f4d157f2afb40972c41fe85622825b5ac48c0e357cc2d953140015bef5cae1cd2bf7519398b610c9b191fa34767ee67880fd9ab6d5782350b176d3a7c318714f8208f71c80a1b189bf10827b763acf096b49cc5c0b2a21c268a6c69500ce889785825438890a6e7e399ede411d83a53bbf81fc0b0b472692db25b69396337b2724f1425aee7296fb29a399a16a13ce748995806cc5c64ac87783af77bc05329ba849a086304ebab9edfc5435b55503c2a6f9b996d75359e963077f4a88ee2e259a6b97635a3bc8670b9fbb94af2fa3046b51bee299bae327f1519ca170a1aa443ca323c1d336952a3d2342d481b10b4752e34c2f03866ee8c8508a77a4721c387054cd241bd54b8be0bba7be18616d3b649a452123e347f8f52c0c5ba2d9fe7560ad88f2bb77622212dff7474b2c250b0341d9ce6ae52dcbac5d3b99807af81744498031477b6178d4552d3e813483c3c6c4a73dd111e7874b7659b29db53946538cf3b51bd53d63dca591d16043469310c512cabc763b208a19099fba9f82b445c05bddea259a0156940e3099d97928c8079bb7846b566b4770c904b75b430151b3198bcce1830b9b8cd5381a1b255a880e49865297a801291f491201684c658d288ec63b8e6d423c4c9091f9552926253876629266969acd09a8c896ddac6bee964832bc0952b98a95ee54422da547ad9174503093835c74693047d782829f06327d11b6a646ae2e8703c3a6bfe9516e71915e7294a2d5a4ec8406792b55692c5591af95d3e7376f6ccc58caa2ff787a126193175162e6a084159e957d85383a0502bbbe091da6a62a7ec4441453306f74c40c483abe092a36a5876a60e1893c8c4fb3dbc946d781873d49cbad7ba431ee820f6e0246b5548f045ad65b0670c341d3edc40f331b59740ab0d167e02fa36cb23b10467084a63b9f1facabc9c86e6511f8cc6928de03913001927ec47e6b001264c9629343e10f945e4f9065e3985e8b4b3536b1aaac91a02a7b701c961a939388f57b310c4652d7649d604a0a7006686c5c0f467486e5248dc24be13f411fd524a6efb276bd75875d5cf7a18482dea41b4579f168486c3d87545b415ec495f37185b6762b754194f3f415f82628ed9884b658465ffec83f5213ec15264c454cb4cb46106c21bd8031d11fbceb50b7d897aa771748cc2e5a23fe99fa91347fa90c642b5410c2c4382b0a498f479aa94011959328eeb48e8222c5ca82930f5a4d40a7460a827c756c28e99a88440b0ca206241f4472c06ca74d48a5f565b8a85803e214f9a6cc92ab2b80bd16c0c5725a9c7bfc6067109600d8142a8bf681ee32b3d2bcba3ea21aefe0655fbe06c0c0c6b303c6b2efaa6e8e6b29fbb86cfd13c6e143d7b104ec625a6ab2c782bb88d4929ccf7528aee89947ecc33e5187bde373c21f2ad26252163a48bdfeb74841987e797048b506c8fa6c60f431294ab03ae304e1e64a1489a05976355f44b6bdbac7b81d2b003729f9ceab9190165677c81644a5820d8a158da62ce19657e947170472e67d87fc5c526b2db8fca728ef881198ff809b80bbb3c1652fb9a51c42aa89ce96844721a9da7274d52050b106c7505497629962b747e117c2970948fa1e6bbef069cf4da83314083f57455d9b031639202351bbc4631b080f936a1e017810632bcc19b41ac0fc7939d5bc6562b074eed4267b9f6a6d110ae51f2b6d9b39f46061031573c5a10c2f23b6879338889e05efdd4424820cd98298b59dbb720a101e8e62887303d5efb4ea99288199b54a3caa85476876d969b2ffa0b72754e85d3979c17155d784e3ed0a2874cbb9890b4bcf6334c8855f7ac45159a18e4f29ff5d8a5e5f34142c01e3fc53a2d07cc7f6c582718c434c062383bb60d4c54dd07a06d2642c8ca4920d5b7fa723f6f2540eaab1385eaa17b4339b8b3cd08f60e5727045fa947bec4c6e766b850f86b80d2b559507137234cd9856b7310aef4f50034ebbd5336c026530b5ff525c277590d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c4092d5afa2f038f879184f7344800ea49a63543be9600bdc2b184207445882900e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +expected_public_key = 3c3830f0332f31f89ec458368a31cd2466203c2b510cd773d66c92cf2c95d7700d82b54faafc8931300f48563aa4cc976ad602d31c4b4b6c96c6f527a637231f1b94cc38767a608f44922a3f391b9e6c5f78a87bbf6cc19849ae619a2d84533441727e79e241efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ab71ce07276a78546859e21ba695953c8521a07bc8b4264bf1d3403eb8cbced71753b6619a4309599c4ecd32826e6609d7d09f976c02dd4143db7ccf9ff09365910757268f49141445b689a6dc0706c92fdd8382c63010f7a026abf217ce572256360a9a4ab2b7acb235f6929b8661dfd5bc4041813e657c95ca1a36535e97d6a56c7022dca5cbf8d121f24ab6df3002fd4b619b03ce2c4b57ab65732721901448b9c0136b1c72145b2b101fe1bb555ab2c0482caf3a1cedc926a007858e7a4ed9dc120eaa7e945275c4a847146c88a468ae23ec173ca76494732792d9a952178d83790b725ca63fe13ff7c5cf5096b3828b463aaa0ee913c390359c9e4346cdc063b8517dc5830a24e578f2053f33e5999fac5603ab62ea785080bc39e0aa206c98c560597d219746737015a5668ba4f0b06f45a7385c753a854c4d818f78466b5b9421fb84b0bad8b5b0cc3104ba8b9531b9033c52fe7c718ae81a3b06ced360a879d9cb3f73b8d6c09781462e6d7c13377006d95406329777e2651ef2803c69e984d4e719764ccc1307a64a1633e7516b2c5380c443a9bea049c91cbaa7bc385b989d1453676ecac1c2123f05e83ac0295c6e36ae6f0364ce5b35348037b7379bd2248af8fba3acc293479b24cd0a2b0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2940761e48e665461bf30c2e9702ac726ad1aa7cda90c5655b9904ac1699921ac4a3a1981b566c6015016ac84e7964f64c0b5eaf69fd5460b9a17686952951ef9a04a55926bd482e669bc6b731aad4465f9901337a0544f27ace61841a5c2b0efdb2e4b897bcbf1c032142b73f70cc0f7b509d6847f61ba4e209269acced24a0721ca6d9e634167622928b65447a5aab30765efb7c977a56020b56abfb82449614df3fbc118369e8aab020cf989015696140b6a5c960db2fcb5be3c41091a6729c62547db67307ace42760689c32c2388310d1269915470286433c5624fefe684a12957d90c8b61fb334bc56cfeccb229f01f0312a11449310e432e75037ba429adb4507fb74a293823364f81b756673adbdc063d030fbec029569c8db185a0ee8011000cc7b2118a046483fd975d9a0122fb0596aa8a6d9b99ce7303b1c8a4342696001167a742fb9374d4a20a8377e8a6495e21ca6eb106b2c680a48ca6c138673ed09897f4c731412ec536759a773a1e3aab3b335301eb2501a5cb48c33a1e026e4bb25e2f867271e48cd48a029039519b296cea8b04953bcf41b515429237e696503e9283ca4165355585be315f20266438523d41543194aa6aa476bb2c229f2f12648a179e46c1696581607b4585c5341359aab5c5f0b2ca96177010c892f8299042a880b9c281483ebf0a96ecd9cac2f13bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b09178f2883e8c6397c74352aa32a49468adf650441a73a2a0e7489fd7a42a9421c8366ec7b5a0ba8b0fe721190f825bf5ca839fcb22f425738e92b68608078316af96526965331d16a41052f2154faa17fa843a5e2278cd122aee688924e57029a8902a03186bc562f99b2e72b9cf8e578bf28c2f5a86b47b4555d50a1512ebc131280964165f139b7a8860120ca684cec34cec402552eb3b9063b7d8266735cb1be8a0b253c67710d80d5d1b128e38085d40cdc7e2cbf4b8c9e1861d2f41a79e1b49aca0668e4b9312003986045415b194f0f583811b181fc15f8cb5788bf14762095bab613f51f4351bf00f669102bd349b70c40549b75ecbe16394a3062c5316bcc4a1ff57cdc976950618c7d103248f4c4cc2087bca854fdf6840ae98238c26656615143f0538c960888f32bcabe935732b6a5c24372b438449812e4f125b07b836b1e076f7e629fd3578132c70776635c5fc0d4b435ce2e301703c20ec130a25657eb394013924bb88090b1599373c5b7624d59d2f2c3b2d71a308a25092d5b0eb6ba81c5b0c650104b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_private_key = 35e4451348cfb9a06f1836296178b6af41a1c0196f26525831c081ea779e6b8c4b3f150afe2963aa756968358bfcd47d76415ed4294f02a843f89b87d6803bad504a9165b9bedb0c946058965b64bbf953e719160b53552c100d251cc9c111837e0a7c4c043ba0777e53b39f658b41b5f8900d4721268a8ab868b15a12c3b8f41316dcbe117ab3a027b8fc2cbf3566569a130d6db132ddccc5eed69a392bae8e4a7bd6c9708a48badebaa79fa1ac1e729eee0399803a374d3733ae501f1a846cd2f5166dc31b4d53750bcccf937b1ca43c3a6cd5601eeac251f9aab8b2489e22ceff436f1142ccd1bb17dfc75db6125a1a433325a5599fd23b49bbc3d1b9195b984303735f9f2646efd050097ab23a8aa5569ab744a934c2991ba046cb012467d39c3936eba9cfec4268e1a0eea559980133b4121f9d5a603e092c199818c057b7c841a7dd00af2c0ab3637878a9ea90bf377874fa38bf290fea6131345340857a1a53d4bdd9201b99fb628d975a91001f907a2e9ad37c9b99b8af915070339fdf76125d9556b1716cb74a9f18092afd887880526fd82cb002ca49e879c50e33af2e747104674eb1f30859e3c22f3aaebfd30fd672b6ab855928c4085130488540c8cbdb832ae25249f46b7178af9769a4b359664ba48da4a746c215c58ac2752e43835b5c2a9ef0a3fca159d29038cd60cd60f5bf508521d3d59c4f083653264776501b4fc62337fc37562973a1f9bd9532b4bdb25c21597a11e17096b155cd43c76874c44f25c1aa1bbcea897367536ecf4124feb6cdf2360cd5a082ac03b5e94232dfb44e1f124fdf65a4bd03b16ed729884065d77135f1f730a7a91fc2eb43271c0b2bfb8e615c07df54041917a95b0544e8513e8c6060d14c0fb802c0f2680051341960654f3594c9972c08664b7bd30b2f031827307b95fc525a2632c2456041b1286d6f175bc0b41942e8b8be69bb364a11ab4cc199f20aeb516ced1acc1f4b2b91b860331677290c643bb9a00b4b65644592c5ca5bb19b25d2a7080cc32b08910c137946a3fab6c8e31a1e97a4735a5c0a239b073c6e056053cd6498117497870718d35235019b3ee6050dcaac31a27167fe35ce57586c364c13bcc7587ca066c6e05673e2ba0186281d94843df10bb3a93c05025c0c691a0c41b229a55b7b506724026c4f1b48313788a212b0c951783ec9447e64314e878734ab59401923ada0586225c7a5c00a5f97bb76632dec47c15c06c7c20090c790404b3044136c79f46181cb1123a7d3cf969b72f6cabe063a35774a60863267b1ba34b93a5d3db25fece84a02429a9d142ed897320bfcc114391bcc097a078b04bd9356113b3cb993c19384886df182e37ba659d5b8bee24445411e318cbd092b8f8e53c63bfa3896a2cdbdc66e27f25c83fa85c260a34fd6cfe6872172f1361aa125e6c5c6c902cdec68708c14c175e910cf002ad647a317f78f52f76bae006a3aa51780d37a00aa20c6a532281719c5ac88641a9d15549088b5a4dda23f443335abfc5c2f7c5be2a142740cbfd612a83af271af0aacb43833b56295b51a885d798825c3a2c04b399c528530ca24117b6e762c7b6527b0509b5963b68560015db4d489b5a93507e286539604cd0c35e6001127902a72ba3fb9d379833241bf849d2c11bf6dc5133c0c76e861909b375a930caa5dd105e8d96dd8698864678adf585c4ea072ae56990c25adac59ad0fa30b17d2a0ba16a444a16ead3c9f679c333cc97d830106a91a54d6e074c463bca12657bc91544d8a6e181c5b452229ca94bafdd02375d5a96de2b93030cfc93645c7282b082c29d4b466fea3c28d2b16ecc6cc5e584d35e45c5ec7233c723c7b2275abd41748a79f88797d9d03b8ae9b839ea935f5e13ff9e775af239c7c448eae6c7b407c42915c1c4cf3a1cb652b44b5acb746a5b2b576fda15fd1cb81396cc1a17752c2b5748e988649bc8caa98c2c2f09cb01b1153a59ced58a76738072a1b6a5a68b1825a062a223cf83913d77b5ba226076c939dcbaab624c712b51921b46098c48778ef46917c63a23a563a39d0c7d3ba5ef7b87857c8912a137f52026cb4628dbcc0ac53062b1b181821f65e4f622babe9882a69487407b0a715a68c110c1a20339eb559d47318dd255f4ff758db79be3c3830f0332f31f89ec458368a31cd2466203c2b510cd773d66c92cf2c95d7700d82b54faafc8931300f48563aa4cc976ad602d31c4b4b6c96c6f527a637231f1b94cc38767a608f44922a3f391b9e6c5f78a87bbf6cc19849ae619a2d84533441727e79e241efcab0a0ea361febabd3b76caaa8955ec8b963daaa8c8838ab71ce07276a78546859e21ba695953c8521a07bc8b4264bf1d3403eb8cbced71753b6619a4309599c4ecd32826e6609d7d09f976c02dd4143db7ccf9ff09365910757268f49141445b689a6dc0706c92fdd8382c63010f7a026abf217ce572256360a9a4ab2b7acb235f6929b8661dfd5bc4041813e657c95ca1a36535e97d6a56c7022dca5cbf8d121f24ab6df3002fd4b619b03ce2c4b57ab65732721901448b9c0136b1c72145b2b101fe1bb555ab2c0482caf3a1cedc926a007858e7a4ed9dc120eaa7e945275c4a847146c88a468ae23ec173ca76494732792d9a952178d83790b725ca63fe13ff7c5cf5096b3828b463aaa0ee913c390359c9e4346cdc063b8517dc5830a24e578f2053f33e5999fac5603ab62ea785080bc39e0aa206c98c560597d219746737015a5668ba4f0b06f45a7385c753a854c4d818f78466b5b9421fb84b0bad8b5b0cc3104ba8b9531b9033c52fe7c718ae81a3b06ced360a879d9cb3f73b8d6c09781462e6d7c13377006d95406329777e2651ef2803c69e984d4e719764ccc1307a64a1633e7516b2c5380c443a9bea049c91cbaa7bc385b989d1453676ecac1c2123f05e83ac0295c6e36ae6f0364ce5b35348037b7379bd2248af8fba3acc293479b24cd0a2b0dd350b10676c93ab5a6f76cb0256dc64cb8a4f677d2940761e48e665461bf30c2e9702ac726ad1aa7cda90c5655b9904ac1699921ac4a3a1981b566c6015016ac84e7964f64c0b5eaf69fd5460b9a17686952951ef9a04a55926bd482e669bc6b731aad4465f9901337a0544f27ace61841a5c2b0efdb2e4b897bcbf1c032142b73f70cc0f7b509d6847f61ba4e209269acced24a0721ca6d9e634167622928b65447a5aab30765efb7c977a56020b56abfb82449614df3fbc118369e8aab020cf989015696140b6a5c960db2fcb5be3c41091a6729c62547db67307ace42760689c32c2388310d1269915470286433c5624fefe684a12957d90c8b61fb334bc56cfeccb229f01f0312a11449310e432e75037ba429adb4507fb74a293823364f81b756673adbdc063d030fbec029569c8db185a0ee8011000cc7b2118a046483fd975d9a0122fb0596aa8a6d9b99ce7303b1c8a4342696001167a742fb9374d4a20a8377e8a6495e21ca6eb106b2c680a48ca6c138673ed09897f4c731412ec536759a773a1e3aab3b335301eb2501a5cb48c33a1e026e4bb25e2f867271e48cd48a029039519b296cea8b04953bcf41b515429237e696503e9283ca4165355585be315f20266438523d41543194aa6aa476bb2c229f2f12648a179e46c1696581607b4585c5341359aab5c5f0b2ca96177010c892f8299042a880b9c281483ebf0a96ecd9cac2f13bfff4c87845b708c73404979af7eac68bb45f6b7c8597b756557a38b09178f2883e8c6397c74352aa32a49468adf650441a73a2a0e7489fd7a42a9421c8366ec7b5a0ba8b0fe721190f825bf5ca839fcb22f425738e92b68608078316af96526965331d16a41052f2154faa17fa843a5e2278cd122aee688924e57029a8902a03186bc562f99b2e72b9cf8e578bf28c2f5a86b47b4555d50a1512ebc131280964165f139b7a8860120ca684cec34cec402552eb3b9063b7d8266735cb1be8a0b253c67710d80d5d1b128e38085d40cdc7e2cbf4b8c9e1861d2f41a79e1b49aca0668e4b9312003986045415b194f0f583811b181fc15f8cb5788bf14762095bab613f51f4351bf00f669102bd349b70c40549b75ecbe16394a3062c5316bcc4a1ff57cdc976950618c7d103248f4c4cc2087bca854fdf6840ae98238c26656615143f0538c960888f32bcabe935732b6a5c24372b438449812e4f125b07b836b1e076f7e629fd3578132c70776635c5fc0d4b435ce2e301703c20ec130a25657eb394013924bb88090b1599373c5b7624d59d2f2c3b2d71a308a25092d5b0eb6ba81c5b0c650104b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60aad7166f31b2650d125c8ef23b5825fe11afe25d0cda306fa6c7a824b4c2d31d4f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +expected_public_key = a99ba278867903f11dce73ce433c475e3b7e0b3c65921b3c842b142e139fe1d15efe13b7bc3625177282f4a92ff5363027901e2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703ca521be85af4651c52ab82006c95fde5779c10ca73866911a4c48088742b8b2243f629fbea924b7d8968bfa6200361a9c344a45466de00b7bf0e5b78dabb1bac3278144a94b27193b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49944d161a9290b4ff328e4fcb2427292a01367c713806b37cf92649009c09416a915b84c23efdc41d7e7859dc81276042357663c0bb68282cb71d891177148a17c315b7cdaa9aff35b4a4369e83453097b88d61395da62431f19a7c8427a2cb15eefd30b810bb74342a306b1bf26a0490af566f5a17885baa8f4a60e1c9432cd02a15915cbc8d574cfb23399ca1d93b95bb1e7a68a798a9b9a6d4dc92bf1bb84ba1109db395dc4b59f1931087e4524a090ccd037be1be6237a6483ae1a21b859bedc7a5a57a46fc02b13f5a446f4997b310b14c734160c7a19a36507876cb4c0cb2bef3bbc5d26281f15ca5d7654de307b20f9b3ebe90dfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358db0784a9c7dc25cb6f6236ad96784759277f660c49130a8ed9377f85394ca90e1d59467ef98eb555956755aa51127a26f498f3a6a2d2f972357b0b40c1254f143042199bb380ad86a04c1a8a1c4fc68166606152c5950ca8b0b3b86d99167727f623927963770a1423a5cbc9629f248409183cb5a0d99e22c915991c7ec3e5288400add0c355a3f94e7a4962a513b05af268e31c7d1c4b3fe0f0b8be500812bcb66ffa0fcfe66928dc86d769ca1f4095ea3124c5e1c7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c1703a0b7b86a691935824299062c5bf927fd5573e413552a7731453171c945748e9943429da1c00588742c8c2acbace1ec1a290e3830006610d21b945647180075194db0170426087112764bc23718bac96281ced834396cc8d4d003d3246641577bd11a59a765001215760d8122eef819f2d1416f998c7a8a080718a11774072f3a563a0581b92e5aa24ec05ec9004d578438313913b176e783c01e4d313648123b9db69d9e7c648d2cbfd42587ef1a2dae065fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9cf818b938843f78ac68ef8349f37468e81c06044ad9a051585c34d33d76cb8ecab0c0886cfea5c725b3013c048db0b7efe3792c6777a0b8413481aa0ce5b58228479f90c941517631319415dd52eadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f5903163a9f45d681f0c637a5f53f7ec0cd30c270e3b78ee4d575a3040b71c30106c6831dab1f2c8515fa8a6c5477c311e7023d779365466228aa3d1fc2b819b51e0771c989720946aa19e6b28a463577214c58bd35237c33573a75a11cc1b5dd8595420cb87f9063bb7247d88789f40198a0395c001877cc35a5a5171e3360781bc3588930827339c24233747d9b5d96f6a31712cfd71cb962b7a1974c3ed85c05a525a21aac83af06c68136cc9bb8b7d74216da468d78f80153bb0cd2b2316dc975ed6c09b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df8117d8312093bb3363d02c72f727f3371c2c8491dd611ab24765fa2665f612517d1d66882056903a67fd4173575166255609a54a3245d74b46c075c04b702ac4bc88e71b757907091c228b0182e10305b7c1cab0df3447a93219df5390a0302f99a0ae8bc51108c7c3397590f4b241165414952840303606e6c1b98755264b01280a8caeeec25c0818840d494bc436279a939d96c6f9160a01233afbd576f46359b2c75097bf15c37047f31a186b7bacbf23aabe9b7ab649938b08687a4b1734a834d3fa62a8a7a180cca4fd0a74c32a76db42009daca9ad0c3a6f8a06699630f56a6c793927d155b229269b1e3c94e0d23be1ee3121e4b638216c5b722ba3aa3129dd49bf1f93e78d16d1e820485527564405df9fc6574b7809a8bc289a02ea0e455a3a7813c195921194756558a6d481ff86a0de4dc39a347ca01562454f589f953837a256cb2ba49f200a7d1b22ef801109e2a45e28c57e201354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_private_key = 03a941a829c025261f44172acf806bea5b216b58bab845328c36cb925a5169d6b1ff141ba44010ff2c1a446113c443c6d98ca879e673cccb84d5519067619edf59c23798b9b6bbcdc0d49df5f4b21563ae54e287dcccbe4c53c62918a6a213c460eb8c92377cb57a1b6d6467d40297fb90c6907b6be5b03db314c3ad5b2f46999743ec7ff0b055af2b2753695395c6157c60115e183dda398d136806b7017bb4fb4f36b7653bd17cabd1bffeecbaf2eab65b853c710820818b05afb86388f327fea6c3562a027c610afd9c0bbb23a571489120c2baa0d7aeffd196b2dc8b40d4016fda16062512a64462fe806d5959c49dfc0c9b2955e6480b7af0011edb2d44c6a43d08b5f469656cb9396c9c640bb077cc24ac0f293bab4cbadd998ecdba31534408b74420cb432826cb5dc8224c48159626053096063841153f723761f83315629c945778a24f826a28a90a5854ba7e80c48e44929eeca17e28304babcd0af4198962a045292f09ab5b7197a685a67d07ec9769b69e64ea1457fb8e1a70b23ac4a797132b021244944143e936c6e5d840494b674fdc9aee84a091175f8e3121150b1375e028d0ab6b709a443f14c56ab67e3a8721a4b698eac9615fa12c0e5277e4a412508446ed4999687ac5ac626ccf5468f3e944b8d099fdc319337c85e5024a0798556cfabfd47a40146691d32c0f179b5bb3c3088f2cb29e2b961b630610d1528fab952dc75d23339c26a38f68421c12c2360f369abce128cd64551ca29455e02aec7c359cf9182f5642f1bab42814aea8f2844af15670421e0e113063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a6e070fb665756f98156c65a6f407e1014bd6540a92e8a09ef6c944db876250b951d16332251c5bb6b79f88928adf6bef819a241068b08337136b8bdc33476fddb0292b68ede75490db193e267bbf2f8459fabb17d10bef7018ae895995200453065ad45457e3e86a12c554db3617a99613767598031c86bd5815585444dfa41cbe068034fc0a1cc2636d010230870776d2645db640b409a292acc909aaa11d0d05a1b1469ea2673020bb7ebc7381190c271e2cf73d37f61f12c8389843b0540117c7ab924c140d1409f701ab0c0596103a1aef3c93a2a79be19c7870abe83232a7de265a1a1280d30490ff50c414a006d8a403c50948da4b1054b18be35a8f9252079c5acb2104bd42ccb51617839e07380fb3a62b3a5080295bcca410215ab5c30a89b727363185363027bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bb718dd7facf5f120303ea259fb2bc32a5269ab45e6bd8ab9f9456a68b869a4c13a0b6c98dd1bf276572efc9a31591acb33b9945919fd20495db284bd4ba7c66620754e58396c0a191f20304b545aa2279cbe62d08eb4c82e60569598147f9910ef70abf792d375420bb999e4a9cc28db0193a124d0cc78807a54d13933b25b350a16c842e4b31337bc7734104fe564c20f27ed6ab800717baac4a9c954c6ec5238bcdf309c6fc497a6a9b9e4973d7d44ea53b90db26912ac7796c327d24d3705db5bd0266b17b145fd8ca77624c8eccac1c209073b2a6399cc7704d25452a2a0dd6002020e51b0ae800f9e93250591bc01b7274927da637823cc69d3ab59f7a0194b5b653ef0a001cbb5d28284576bb0670aa0e6f94c06f7b2b0d6904d0615fd1831cd6800ba590816e06022b0502d165340c38bf824a35d6c227db3680a3c1964c4727aec40384d0c413731e85f2224bc9cd4fa24e93d0439ee97c9b0852aff733c2974fd6e4241b1a46a86a09b48a59acd13cacf617adf9b0bf835c20e9b05b8b58a5218587ab1d50800cbfc315c1814a8203c442158790515d83ba576c25ce9eb0539b26accf471d299b3cee6601bf711a1bc913c0f88f478ab072cac1541c892e314d733350c0566385a04bd8d759b6b81ba0370069d031e352266fbc8e9625c373c0c4c3a600f37c5576e678ede07fe17609c774bc28f2c7d7889dbda78b0b041acabc1997e93e1682393fc655daf227be808d9b395ddb659dae366c87b7b07f072b7fd9169474ce4fd0578952b4e926abb7e039d04cbc94371c0c967394a95aada9594a8cb4d5d1945ada7bb18a5e52ccc5ea5672a99ba278867903f11dce73ce433c475e3b7e0b3c65921b3c842b142e139fe1d15efe13b7bc3625177282f4a92ff5363027901e2ecbca0dfb928e86bb51fa7c6a2ca93c5b893855703ca521be85af4651c52ab82006c95fde5779c10ca73866911a4c48088742b8b2243f629fbea924b7d8968bfa6200361a9c344a45466de00b7bf0e5b78dabb1bac3278144a94b27193b2c8214ec97527931dd04c2e43b4c64753d8c494041683168447ea5a49944d161a9290b4ff328e4fcb2427292a01367c713806b37cf92649009c09416a915b84c23efdc41d7e7859dc81276042357663c0bb68282cb71d891177148a17c315b7cdaa9aff35b4a4369e83453097b88d61395da62431f19a7c8427a2cb15eefd30b810bb74342a306b1bf26a0490af566f5a17885baa8f4a60e1c9432cd02a15915cbc8d574cfb23399ca1d93b95bb1e7a68a798a9b9a6d4dc92bf1bb84ba1109db395dc4b59f1931087e4524a090ccd037be1be6237a6483ae1a21b859bedc7a5a57a46fc02b13f5a446f4997b310b14c734160c7a19a36507876cb4c0cb2bef3bbc5d26281f15ca5d7654de307b20f9b3ebe90dfc074050e67108534832c95e55e57ea6fc6a050461cdb87f0aec7c3b069358db0784a9c7dc25cb6f6236ad96784759277f660c49130a8ed9377f85394ca90e1d59467ef98eb555956755aa51127a26f498f3a6a2d2f972357b0b40c1254f143042199bb380ad86a04c1a8a1c4fc68166606152c5950ca8b0b3b86d99167727f623927963770a1423a5cbc9629f248409183cb5a0d99e22c915991c7ec3e5288400add0c355a3f94e7a4962a513b05af268e31c7d1c4b3fe0f0b8be500812bcb66ffa0fcfe66928dc86d769ca1f4095ea3124c5e1c7be5c71ca7abc0ec76b7b0b572895c7e923be57f39eb0f430c1703a0b7b86a691935824299062c5bf927fd5573e413552a7731453171c945748e9943429da1c00588742c8c2acbace1ec1a290e3830006610d21b945647180075194db0170426087112764bc23718bac96281ced834396cc8d4d003d3246641577bd11a59a765001215760d8122eef819f2d1416f998c7a8a080718a11774072f3a563a0581b92e5aa24ec05ec9004d578438313913b176e783c01e4d313648123b9db69d9e7c648d2cbfd42587ef1a2dae065fc359951ca56f8253b27b3878074bf58d3b51cc7bafe7bb9cf818b938843f78ac68ef8349f37468e81c06044ad9a051585c34d33d76cb8ecab0c0886cfea5c725b3013c048db0b7efe3792c6777a0b8413481aa0ce5b58228479f90c941517631319415dd52eadc45ffa383f149879cf698f3c7990848353bd5b8e6d7333067ac67f5903163a9f45d681f0c637a5f53f7ec0cd30c270e3b78ee4d575a3040b71c30106c6831dab1f2c8515fa8a6c5477c311e7023d779365466228aa3d1fc2b819b51e0771c989720946aa19e6b28a463577214c58bd35237c33573a75a11cc1b5dd8595420cb87f9063bb7247d88789f40198a0395c001877cc35a5a5171e3360781bc3588930827339c24233747d9b5d96f6a31712cfd71cb962b7a1974c3ed85c05a525a21aac83af06c68136cc9bb8b7d74216da468d78f80153bb0cd2b2316dc975ed6c09b6384ad49735f1ac99e03c95e8ebc851f8b24aa65df8117d8312093bb3363d02c72f727f3371c2c8491dd611ab24765fa2665f612517d1d66882056903a67fd4173575166255609a54a3245d74b46c075c04b702ac4bc88e71b757907091c228b0182e10305b7c1cab0df3447a93219df5390a0302f99a0ae8bc51108c7c3397590f4b241165414952840303606e6c1b98755264b01280a8caeeec25c0818840d494bc436279a939d96c6f9160a01233afbd576f46359b2c75097bf15c37047f31a186b7bacbf23aabe9b7ab649938b08687a4b1734a834d3fa62a8a7a180cca4fd0a74c32a76db42009daca9ad0c3a6f8a06699630f56a6c793927d155b229269b1e3c94e0d23be1ee3121e4b638216c5b722ba3aa3129dd49bf1f93e78d16d1e820485527564405df9fc6574b7809a8bc289a02ea0e455a3a7813c195921194756558a6d481ff86a0de4dc39a347ca01562454f589f953837a256cb2ba49f200a7d1b22ef801109e2a45e28c57e201354be551e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44737933cfd8c0e61085f2ae264d85c4ae05f8bd40bf29976c6d52e4f1c7ff709cccd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +expected_public_key = f44a0e9b691f0a718f02246fc688a248e3c2f387a55c463f0d976af9a2399cd4845c22516e0b3c882625aa609b64195c90925afdeb2901075565db2562b11d2c07c8d0d94122462c25a794da3639879a409256018f7418af91608b63ab222069e31c2ac0233e8f73ba8be2b0ac0463c9bc79cb048ae517295e8a01d2e16437088d20168f135c4d63b41021060a557003bcc935c6c97b3859176807b5637659f1b5bc4b488d4e5657e9f7b37c320b5df12bf31330ad27a7f205907d6614949bc97f3c1e94f21dd235606602a5c13254f43ac1bca2a6269bc5e6a96c31e30c972067a6030665ca7b05a700c53c560860a11371505457196cb33152b10f9b99518d4ca6433724a93219db1bc834499a019c02665c650c7c0d22724bdc0bb852c9523d1a9e5b06570a6610bd1175a74b869cca729e8c17ed5101d43c814fb18838f840884a4159bac515f7b5a637b703385e5f7115cd187e2964be55828a33656ef0384896525d4511aa2fc40046729f54acc768353b8001201bf508b5904e3603abe5b426dfb77f213c54b443b7d5ca6998291b56c379ad5216056198bf5617e58977a0490c308bb5a6873ab980a1364b1d25f0b01c3acf3221528c942fdc83a9a9a60d819c015fe06d2c684194c56a98c286b2122ea3fb9b18d003cf91453fd09940f7722999af0645b67179bb11b35a4cc56c2fc1c581f168f1918983ea00693471f6e33144c642dc5a4c28b01ef514449213a4e4749f0b2c40e6e06052d6870dac120cfc54aba5143d8ba4fdfb946af9c90f99ca2eb158f001003517b9aa7a1306973deb713671a16ba714245ba96723e3453718a3bca2ae2c1b4d0265102ed901b3a1b6b6ec639a8900eaf67b5e500876137122a5284cf52de9881352770a9d20af5aa59c71189694590c549831021aa911948e550765f8897671621e5d3771f1263f87220c0f0b28804726c112a7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d4d0021633c9744440f0f9a309d1467cca4d67a917198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62006d29fdcb62526714cad2ca04fbc28983b54b6b037436917da15608759abbc316e8359a26c55e7df179a74c39269c02caea7e61ca571dc771e7679e611b9eda31bef53b11e3524ea3f600fdab967fc8a23b0b73407738955b20b76c75b971c4c1105b9c5a3557d57af4db036454a22093a570f0bb10038bb3a46a0c92866c707c28a91b9e6172314408dcd3b051f363775842274988340165887a027bfb629847b9271a5f66c15c286537c76c31f62b45e2995f0aa30dfcaa6bf2883d1deca9b7b2029515c564d3b970143c29956ceff588e99b8025a2343efa5233361bb2332afea2499656203cb712ac8cae4ce1489df2bd9223c3c65737c101c0dc5c2bfd83444a29c64d8812cd69a68f004d2596033e903d744abcb688ae65b0371d711b187b62e6c755f2f947d828446fb45f30c42da615b3c5f682f2157e940691ba674571573647c09225748416529653845a6944859dc3c62e7c0a9da78a4ea492f57386ec31b0c8730206e5adbbb0253113a173e20313610fbf696803718a0d393e7ce4165e004a450825d8935f7738aa7c6a1226640f3cf40ffa6644dae2280043c501635550bc76e8348d133a55cd73001fa3197c1a071bf30a1ff907813aa8b8986449918c08164817720f30e44828010aa6a11a378261e8b141d52779f73927d7f505dd99c7a43a2db1197ba33a2950c280549564733706009185a493b59bba67bd511e4dc55a4f458d9b1003b90a30aa87874fd83707f1cfaf11a4b9088bd41c8d69bcb77853b396c15e24948722943f0e28c4e896c56f7c9d3974144d43a4765392bdb0c2ef5bc72b27b11ff57d03a8214de0520dfcb3093b5ac72003c615c04f64693f68c0d17cbc34f8cb1ea068d681c917315836005dcb423c0695ad19a06801847e947b045e7b78c9728cd321579ea31e5d7633b121884ef65095354dfe63891945983d54cea2583ae4b64f54065cb5631272e1149c151ed0715e93a30c38c85c59415acf73ce76d9453697a3625a607a205204b307dc3c92cb140f1a75c671e916fcda070567b42a2aa12a2499e26293da440b664bb8337b6d5497471b002435c8b40872ab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_private_key = c842401604c8c4c78d8417c804c2723b14733044aa2755897f65987951218361a07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bc306f851c9e93ac266e3c9e9c939be422b07e512d28503a6efa9d3ea8861e39b1ad481b8ad1805a8c0d48179aa1203c2ed7bb59d5c8ef651281c77f83ac7b49eb997965b161db025b47ce6e2c09edd41f5eab1c8b7b4d20783d60c90dbfe6ac387b629be10351868186f6a0bf68905f8c1cf34303fb577c25212919533c7044697d9425bfb76bd9d367f43b2d3613351d95395f4c2bae63b2a4608c69364f41e85d542a08f35b940fbc3b48f63360b50aa88259c7cb4634e5a34300c5957a3644f6ae381389b53210110329fc61519113c17e64782239941cfbb11a647b814372e313205844592cc3c17319b41ff21a0bda3f5acac3f18bad085c8f27b7758b7519316653ba9c253dc94ccad37f98d00b9fe67e2a13662c77921e4a9a86c8089682811e53a60b1089a1038483e615e6eb109a3b7636e02a44c2c3a81b96d84336cf594d24172be1bbb9c7b3685ea45e45b81d731b9b75ccadbfdb768119b20a0c346156cbcd5bb107a00a0e3c6e949b9db0b4ae21026c915908c5f38413c648edb20623f35b382b0cd5f4a8d7062bebbbcc9e809bdbb5c84042bce2e81bb0d795c6786af95a7e7b0629f7978a03558f98709a86319570273bea71986aa92560260d022569d4c98a85bb98aa198deff63dc6bccd1e6032ebab8caee5cf4717b17d89125c67a8a472c371153a4fc9045fd3304a74b983936060f42c80454a005342c1318a284bc5b9a71a39e748a94739536b517dac1619c00db64c81001acbc2793f9f29b42214442fba962f331d48c300da2186d21a4de61c4b5948c7edd1b9fa5865caf2280a81b9f7171137d6a678c92745b1aeb9db686ba84d65f6beabe332ff036bd113161fa068e74032ca5736d3ea3a01f1acfe067dfe5a5b398575bb9b148ee6155be2b4b67b348420ce758c5855102fd06a1fe8d347ef1b073f064f1f7926be5b2343029e5b7468e93b8abec6be231b6bee714031e04ed23c6da37032ecc00374706eff7453dd931d80029382f17e82a85ad7a8b25ea97d1d2aa21238b25517008b0400281168328b02869889f7f142cbf1ae8ddba5ef2713de649aa9ac56229494db211b90b96ae3b2829ae528c634110a3bcd355a243f3654295b0b79b9b7d43272321959b3632313aac107c8b7aeb83172778b7b199e736307fdf5ac6aeb40cfe750b7227f46a00b9000880d405877b63ff6c616bf4a51ca11c863a79b0e099308b42cbb7997420008268a3b762b9a5e181da14a4a92a5b55e7950268a9a83402889a98835cb9562a5a627750a5348b3398b39783009a081a058bbabcc7740af00b8cdbb4e0842c7f14b47ff4cb424b6252ccccee30398023a9b50b4bb4a2c1ff0a007a0a54eaf421fc2113f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c3420bca7c865aa22461b3d95522e9792b37b78c5555a62a3439f3ba7646076111336079bb8352a286e542094bb58b07cb832e2b288021034ed4934469b1723e57e57e358942730196140f47658258a761edcbdc046c08bb897f349b2930214c105792df1b45ac18e1e05c136921935f40951fbace0acc5c7bacbcf34c35da30a90671b63e50525d08b94632709b119ff39925362149e5b7caeb6a0104046ed846b41bbbd9c6b7ee8f3ab4e672b9353a929764c239832d9f6604522072c964ac98196d8302275159b9ca71b19b75881d26ea3374fb74181d558812b602fdd094b9e40692697cd4cfb1d20570256c0bcbbdbbc8206476fd27c0d0cc624e839c32254c0d76c558999fc2779ac592dfe07a347e9316a3bad42b78a048071cc9b67e46ab223a138e747227f777ba8310c83d170c2cacd25fa391c08a6d35096c704cb3e275d53f32c592884b096a7ebcb04ed8812f5469306eb6166073dcca7a5bc26357a6702b51688a9c13353bb1883d47accc185d16227ec704a60e57186e3135521cdf8ab1382a7b70f80bc782cb75f28c494853175599290657552ca4b406b54a9e607230156e14667ce32a68c3938ab9b309a36ae9b524999812779c1aca66208242a188617469930212f23ce0ea81a6d63a509b0686c5a63f44a0e9b691f0a718f02246fc688a248e3c2f387a55c463f0d976af9a2399cd4845c22516e0b3c882625aa609b64195c90925afdeb2901075565db2562b11d2c07c8d0d94122462c25a794da3639879a409256018f7418af91608b63ab222069e31c2ac0233e8f73ba8be2b0ac0463c9bc79cb048ae517295e8a01d2e16437088d20168f135c4d63b41021060a557003bcc935c6c97b3859176807b5637659f1b5bc4b488d4e5657e9f7b37c320b5df12bf31330ad27a7f205907d6614949bc97f3c1e94f21dd235606602a5c13254f43ac1bca2a6269bc5e6a96c31e30c972067a6030665ca7b05a700c53c560860a11371505457196cb33152b10f9b99518d4ca6433724a93219db1bc834499a019c02665c650c7c0d22724bdc0bb852c9523d1a9e5b06570a6610bd1175a74b869cca729e8c17ed5101d43c814fb18838f840884a4159bac515f7b5a637b703385e5f7115cd187e2964be55828a33656ef0384896525d4511aa2fc40046729f54acc768353b8001201bf508b5904e3603abe5b426dfb77f213c54b443b7d5ca6998291b56c379ad5216056198bf5617e58977a0490c308bb5a6873ab980a1364b1d25f0b01c3acf3221528c942fdc83a9a9a60d819c015fe06d2c684194c56a98c286b2122ea3fb9b18d003cf91453fd09940f7722999af0645b67179bb11b35a4cc56c2fc1c581f168f1918983ea00693471f6e33144c642dc5a4c28b01ef514449213a4e4749f0b2c40e6e06052d6870dac120cfc54aba5143d8ba4fdfb946af9c90f99ca2eb158f001003517b9aa7a1306973deb713671a16ba714245ba96723e3453718a3bca2ae2c1b4d0265102ed901b3a1b6b6ec639a8900eaf67b5e500876137122a5284cf52de9881352770a9d20af5aa59c71189694590c549831021aa911948e550765f8897671621e5d3771f1263f87220c0f0b28804726c112a7756c85dccb8a6ffa3969bc618a83af5c1caf2de9ba439aa4d4d0021633c9744440f0f9a309d1467cca4d67a917198bb873f5569d8c8b5718a5b65a7457f55e3d1bc71f4a62006d29fdcb62526714cad2ca04fbc28983b54b6b037436917da15608759abbc316e8359a26c55e7df179a74c39269c02caea7e61ca571dc771e7679e611b9eda31bef53b11e3524ea3f600fdab967fc8a23b0b73407738955b20b76c75b971c4c1105b9c5a3557d57af4db036454a22093a570f0bb10038bb3a46a0c92866c707c28a91b9e6172314408dcd3b051f363775842274988340165887a027bfb629847b9271a5f66c15c286537c76c31f62b45e2995f0aa30dfcaa6bf2883d1deca9b7b2029515c564d3b970143c29956ceff588e99b8025a2343efa5233361bb2332afea2499656203cb712ac8cae4ce1489df2bd9223c3c65737c101c0dc5c2bfd83444a29c64d8812cd69a68f004d2596033e903d744abcb688ae65b0371d711b187b62e6c755f2f947d828446fb45f30c42da615b3c5f682f2157e940691ba674571573647c09225748416529653845a6944859dc3c62e7c0a9da78a4ea492f57386ec31b0c8730206e5adbbb0253113a173e20313610fbf696803718a0d393e7ce4165e004a450825d8935f7738aa7c6a1226640f3cf40ffa6644dae2280043c501635550bc76e8348d133a55cd73001fa3197c1a071bf30a1ff907813aa8b8986449918c08164817720f30e44828010aa6a11a378261e8b141d52779f73927d7f505dd99c7a43a2db1197ba33a2950c280549564733706009185a493b59bba67bd511e4dc55a4f458d9b1003b90a30aa87874fd83707f1cfaf11a4b9088bd41c8d69bcb77853b396c15e24948722943f0e28c4e896c56f7c9d3974144d43a4765392bdb0c2ef5bc72b27b11ff57d03a8214de0520dfcb3093b5ac72003c615c04f64693f68c0d17cbc34f8cb1ea068d681c917315836005dcb423c0695ad19a06801847e947b045e7b78c9728cd321579ea31e5d7633b121884ef65095354dfe63891945983d54cea2583ae4b64f54065cb5631272e1149c151ed0715e93a30c38c85c59415acf73ce76d9453697a3625a607a205204b307dc3c92cb140f1a75c671e916fcda070567b42a2aa12a2499e26293da440b664bb8337b6d5497471b002435c8b40872ab33e490268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923ae96ec4edc7ee08108fe6c0411a96f48731066ae4be12edeb7fc667039c9c1de8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +expected_public_key = b7572f8bd73104745eac83154707cf81c85377ba36b111c9504a180f01c880d08b55c3008a9594e75b3f026a103724064393351dfa7eb5ab9a1c774a59c47b31437011816abba42b75780c1ea8769a7bbd1ba60e686c726f2aa6c9101614c213a8147cabf658d5505aacb288f065bd31c5b7494b377ef1ab72925fe513c49ccc130cc542aa34abd31b5d99cb8f6e2b9a1c5417a4ac9c91011627e6353cb6529ac19697d05d076bb197790431f9ce62a31fb8154797583692ec9abf67b678e0c204a822e228b09bbb7b4cb3a5df788b0930841aba9e4f7c1212150c87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa500245acb15b7dbccf9a013326c2b0336b66c101aa499159a7c875eb6cebe292d266821bc193ced74b04e61845aa5b1ddc953699cbb7743cd76d930bff38efd943c34b01a8d973a81247d966825d1a9b3b2fbc5769c9d5ba883fc357946d54f3cc3090ee48eb2fa80b4d86dee07c57c215f07dc23aaf8c4aaf2c9e03ca2daa433fd9c584bf582793919449925f27786b6dc2de9c5cc08220feb501fb7e2900c243b1c357c8fc814cf87b233b70ce6f0938b56698c160ca893afa877bba49c0a8f606e30761d9dd14be7a40f8db95496865c2441a47aeba1ca7458256aa5a910948d4c920d32712c55cd8546809704c1760c8f8ed991d8ca570cab3441782b6e4035d82c24105397cfaa8ad86a385327873a228bb0c02801a50340b70e5483709ef03de0483bf08b940c4aab7a61c24e9947875c8e2b930dc208ace4752da4d0253ebb2bfb333a1ec9bdec73283d435c4d061df6b0692df903c6481179e07adaab8d69277958458f6ff5c6e4c92804ea47bc8a03bdd707c1a78d912467a83575fe74aa25c043feea0be5899210d7c8bc8b669fec5840f5b1782a5a9d947e78301eeff9b12635c9b15176499a3593362fe5a946fc98c7083bb185c2087b58b6d7caa3599427259a72c6f89fedf61f7e111c04f008053cbefca2ca13a06d09d9494cf29f82c5b93bfacac8d705e35874d0297aa15c7fb181878b32459cb09d6d489671e7700e4731e783c73c86b5b8731ae765a639b20f8c69844559b0763b5cfab7396c1aa09ce238227c29ba34a48891a39cfb37f1226cdb35517d354d422000c3709b7cf53bb9807e2ae7321b38bb29c327e5eb3d02036b1a4c61a2a66a3e91af4288875719496003988b488d84535cb66a4a1f1ac69952817fc13ffadaaff145780aa02ac41cbebfcc9d798cc4d9a090a4212f0fda861b8760ceba5f334c1a54d52567c2b51628455c85517f67baae5c694293c29a684984ac3e711501d5219fa8279bceda4d8aebcf17babe31fbbffe6c297dd27cd894be83b416ee182306d65d2a962f64811ad1faa4ce72a6cbb1c5d22a1c4a2c1eca36b38618afd0a928c4db55b991428ad72a40679ec7521a170929cf10a41cf63bf0dbb5f1316a23d2acce5c7c34c67f6b2450f36556bd987b525a009c77ac7e23355de3aacad177ab7538eb7b25d613a3e9c11c79e59fd9ea263c0178d47885c7384b492909fbc63ac0b2a4ae455dd3446b395c0bd001765f31c79649c53453252e02b98af51f23f8b2f5f2c8d3eba71ce67a95170237b7a408235429826637f8cbecb11a4dc351fd0134a0cc7869983a02a50ff3958e445a9dd35023900b7a3c41ccb66a54628741adba17da89cef8d83e8f66893bccb50918b6cfa1480b051dd0153fdf5a0561c2c782dca0a02861b87a8aeb304927716884905e1e0a004f3a119b3293fb0850cbba7581f1363598c1384ab228d8720b4c6124e2ad1a9774d7a16880542d30dab2f0796fe5536402bc10326c7577971c496083e0c24541e07c813a01989013ab9580abcc038284588294b743086357d50b01e93d841c6a7b929d32291e47d2419b464c3c692847f7706865a29335a4ff50c536991fcb790d0de50f68914d1ca5b438bc0a43393510fbcf15a895d5d546850c0fb1d970517819e841cc42dc279e8b398a563c174c57876605e1212be53ab714486588f96b8599262d67bbce891b90308959524355338355598b233aa89e4679749207f3ba1086ccccf836c7e3528989d0848b947487781a2b025955b2c748c700b479216c3caddcf63564392d6515767b771a21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_private_key = 0c9c633ff39d1c6c29f8356aa02981dcf189d6535e2ac00750c30b111a88b21024e4823e7d543614f30112f7c78f1679dab68b71aa992538658fd0c8e2984abdc09647453b3fd99dd860238cf40c9112a7dcb57e06540148ea4ad6f97020474afb65c5c67ab4fdb1515c6592941b1e38d4097155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b470ca3fea3314b4bb404cb66e3bbf8f2953f2682cdb65cfb47906b3962443775796564d75cbb4b9bb24a8a98d7723269e8204ba89782f974ae591808e97cb2468252c8539c2454041c9232f33b43ed8359dd6856c98ba4fc09e92f9a4ad497f8f1159e159b5af795ab09c20aa753931f47764b6cbab6968c7a779802b469abb1e7f677a0a485ff5cab2f028112ee8c35152703bb14127b33fb00a0ce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78557b1d31686c6b4c3749958efc60891f12c9e0b7c19613823eeab1d8f672089339e46c16daf0c3b7d53727605c26a723518a2651d8762ac373817bbddbec1ebca2cf91fa2a66896c55a4c946a791e5502ff19aa21cb132322bbfd127c10d87563028bc49b222e5401acdc81991828e4c111a54566e5724b40a452c0f4632b7b85f0445c881938134d516113560b0065beb409fceb25f796c0ba0ab190fac0214007916ca93c2abb11bd88553aa34c3c518bfec423728c86e529c300a1f70225f2f683911040ff9405614e1baac070e0e90337e134e3c93081514a937f9798ea7b57b3a3a0b829a2697b0778c802116c067a5c368576395c43d33882f97c770519c16426284e19bac180a2a6cb85d65b1a115316b08541dc231c123c184e82c691f20749a4b92f2d1040d09519df7678ac282fff9cf5124acbe04388ccab61bf71b87ab3b830a3ef6700a68b06770012424031e89a895ae81c8aca9169d6495cf01cd8ba0c27ae132c16aab0ebc4b13abb37d67ced10a0246e87be1233ff09a6802f6371858972d21b48d410d8cf3a8a1e664f62028cf851a134037142c20e8eaad7de32581b39b5d93221cf72124a73daa2b61f3d7c8f25a973a815b351206800bbcba60ac8c2a86a7758b38339751c23ea5523d84ec982a260256c69af739349d206ce9c9a70dbb0a950a0b63815994a6878711578bc22942914df8489ec5a09258eba796e8a6ff5483a71887e55783a94201e5b88898870e67d32eaab132519624f4b28f22e80903e591331ca792c0cef824bc62168be6eb8f7ba299bc519b0c370509e38377f171761521f8fc882d1b8d0db3c2109a43d1754f75529f7b071b7492b753688feef12fda217ccba484ab79192b7933781811986430bcc010b50a5621ec15dc7bb545cabc77c336892a0df4436e732b905d70769865cdee0a9906438e9d921f521862a3227bab93202da0cd19f6221bb68fda8155ae38132cf2a30a4a5c3dc0b17df0016fac3bdd56cd9d06cc8f2c6b4ac41207fc1aead0cd87506caf5c043941513f0a4abf725818c7686f0745ece93c23f2951ee263f51a3fb3630076dca4ea80a156dc6b4248246f638024b8782c9757e076ceaf18cc27284c321ba91766454640ad32d97e65650b39c9b23fa80405f8cec82abf70ea4f4d24c87e8b253f708f9a563c78655877795c4f05024a788dd4bc7ec1190b606602aa40364692478b3b552c46b5720acc5042be92ba8760924c05a60032c52f63b40ac50086a62548dfe9b312f2904ab17da59842da877355360e217917d7a3c3f1a9b9f2466c8fea980be798d249ade8389e626a4693ac38a844294842382e0c5b92bc25b29abc3212543ec39eb2409858f9c8a22713b043713bc00f1a77bff5d269698b9c91706bf0326899791f161b481b531e77f95de95b45522b9a4f0423eca7afbe418848137b925a6ad13bc792194522f00661742f5e4a0e4d85aad8b36b6540a1b25a4a38c32305e543a6a13c37b48296fb84a3464ddd3016771b79e33251cecbc2ffccc6d3c06d4a660622d3630661543a001a3f9ca586c9354f513f3ba5c6de933db0d0690e4102c9918720437f437354a3107849775c95c4417bba787f172407fa0564498cff67c545b7323c442b3cfb11952079f1d11449bbb622630a6945c402c7008dc7a35f380c2df7c5edf8c9c64432afa34cf0547882f202b7572f8bd73104745eac83154707cf81c85377ba36b111c9504a180f01c880d08b55c3008a9594e75b3f026a103724064393351dfa7eb5ab9a1c774a59c47b31437011816abba42b75780c1ea8769a7bbd1ba60e686c726f2aa6c9101614c213a8147cabf658d5505aacb288f065bd31c5b7494b377ef1ab72925fe513c49ccc130cc542aa34abd31b5d99cb8f6e2b9a1c5417a4ac9c91011627e6353cb6529ac19697d05d076bb197790431f9ce62a31fb8154797583692ec9abf67b678e0c204a822e228b09bbb7b4cb3a5df788b0930841aba9e4f7c1212150c87c4b871e978db33a5395356b25aae33e3b9d7153e4a497c7d7387af0c4367e95fa500245acb15b7dbccf9a013326c2b0336b66c101aa499159a7c875eb6cebe292d266821bc193ced74b04e61845aa5b1ddc953699cbb7743cd76d930bff38efd943c34b01a8d973a81247d966825d1a9b3b2fbc5769c9d5ba883fc357946d54f3cc3090ee48eb2fa80b4d86dee07c57c215f07dc23aaf8c4aaf2c9e03ca2daa433fd9c584bf582793919449925f27786b6dc2de9c5cc08220feb501fb7e2900c243b1c357c8fc814cf87b233b70ce6f0938b56698c160ca893afa877bba49c0a8f606e30761d9dd14be7a40f8db95496865c2441a47aeba1ca7458256aa5a910948d4c920d32712c55cd8546809704c1760c8f8ed991d8ca570cab3441782b6e4035d82c24105397cfaa8ad86a385327873a228bb0c02801a50340b70e5483709ef03de0483bf08b940c4aab7a61c24e9947875c8e2b930dc208ace4752da4d0253ebb2bfb333a1ec9bdec73283d435c4d061df6b0692df903c6481179e07adaab8d69277958458f6ff5c6e4c92804ea47bc8a03bdd707c1a78d912467a83575fe74aa25c043feea0be5899210d7c8bc8b669fec5840f5b1782a5a9d947e78301eeff9b12635c9b15176499a3593362fe5a946fc98c7083bb185c2087b58b6d7caa3599427259a72c6f89fedf61f7e111c04f008053cbefca2ca13a06d09d9494cf29f82c5b93bfacac8d705e35874d0297aa15c7fb181878b32459cb09d6d489671e7700e4731e783c73c86b5b8731ae765a639b20f8c69844559b0763b5cfab7396c1aa09ce238227c29ba34a48891a39cfb37f1226cdb35517d354d422000c3709b7cf53bb9807e2ae7321b38bb29c327e5eb3d02036b1a4c61a2a66a3e91af4288875719496003988b488d84535cb66a4a1f1ac69952817fc13ffadaaff145780aa02ac41cbebfcc9d798cc4d9a090a4212f0fda861b8760ceba5f334c1a54d52567c2b51628455c85517f67baae5c694293c29a684984ac3e711501d5219fa8279bceda4d8aebcf17babe31fbbffe6c297dd27cd894be83b416ee182306d65d2a962f64811ad1faa4ce72a6cbb1c5d22a1c4a2c1eca36b38618afd0a928c4db55b991428ad72a40679ec7521a170929cf10a41cf63bf0dbb5f1316a23d2acce5c7c34c67f6b2450f36556bd987b525a009c77ac7e23355de3aacad177ab7538eb7b25d613a3e9c11c79e59fd9ea263c0178d47885c7384b492909fbc63ac0b2a4ae455dd3446b395c0bd001765f31c79649c53453252e02b98af51f23f8b2f5f2c8d3eba71ce67a95170237b7a408235429826637f8cbecb11a4dc351fd0134a0cc7869983a02a50ff3958e445a9dd35023900b7a3c41ccb66a54628741adba17da89cef8d83e8f66893bccb50918b6cfa1480b051dd0153fdf5a0561c2c782dca0a02861b87a8aeb304927716884905e1e0a004f3a119b3293fb0850cbba7581f1363598c1384ab228d8720b4c6124e2ad1a9774d7a16880542d30dab2f0796fe5536402bc10326c7577971c496083e0c24541e07c813a01989013ab9580abcc038284588294b743086357d50b01e93d841c6a7b929d32291e47d2419b464c3c692847f7706865a29335a4ff50c536991fcb790d0de50f68914d1ca5b438bc0a43393510fbcf15a895d5d546850c0fb1d970517819e841cc42dc279e8b398a563c174c57876605e1212be53ab714486588f96b8599262d67bbce891b90308959524355338355598b233aa89e4679749207f3ba1086ccccf836c7e3528989d0848b947487781a2b025955b2c748c700b479216c3caddcf63564392d6515767b771a21f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e4e23909b028699d6677eabe6bac4bc4e8437acbc52b0b17f1df5760c0455c2b5e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +expected_public_key = e7c99be7540833828e457c66edec8e201b07d8068bdf671086d6af0beb628685790487707b66be4c7341c654a8119774e8b262b2f34944898e42752149039356c1348eda779b526da7ac838551855a4a8af5780c5567295dd16011e3177e267948ba7643174391a34c5597b7af774256329f211518e1a67b2f35898e610f49500c2b4647297723004ab77f9b538524a9b96b1e5fca8f224c2e24701bb726735b408323784e9afaafde570b2f4c2bba88bb54808ee73aae69ba352612268e9b4460f004af4998a6c484474c0d04111f2d1091d31443ee2447be719e8f4c3a49e918eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523ae006853b5e09706259605e72e78ad6fa602bfbc7bfbb0d2d78b5155b3d2017c9086803be862ef501196ebc2af13b2b0569473e9620fab2c85fc23874ac14b59c0f082029b553184b01c76d856858475914f025df1914c16a209dc90a306914c3371a6cf68473a431b2886a8cd40a5302834a73359e001658b90725e02e63c27403fc0e1953b11ee6a6415815d2b2bda0b13e54511c96b801da22b5ae94b68dea940ea4787f3a1506e290696c3535b8ce73351a6e48bed272af5e456904aa03094210494c90b280c2942682dcacbec8c644e9a36d326816a42b23b96b751afb7b951a87d8e94db48932aa14bf73e92b06b85f7afb4387e949645c5838622ef7bb2fee0175914b3c931b25f80a010568a179a21727f52ce578aab6da1a88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e18fa294b7b8055e6acfac6242d671855f29979609b821566acbb381dfab0cff8bd47204fec023ef281226b63a7d0397091a9844e23b28f57a0dd205a520a48a3e517276977388b575522c5b78627c4253bd38840a7889fa75a7bacd10b8f27a3e13bc20aba3ddaeb88ae62b2930338cdda41e0770b4d2092da100aeda2b5f5600718d69b032a45bd677b8732965b82908b877f5f77446e4aa132d46044067b21090404d21d01231264651b38832137da53caba0865957f5af7ac4d640fef96702f853bb4a70767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5c81471539c42144b4cab5d8d53285f8c415cd8cfe2d30295d00dcb47b4ffd90282f6b582a57bd3f13eb41b088ba624575b355f8c7fc0f34f1e924fe7d653692c4f44e1c64f9cb145fbae9e789c029421793a4c43856469298b4ec648b21babc0167c04d90a3a8c554df46b80b407dfca54d5f68e2dca4e98a92ff38b427115c26aa33161503a83143714234fed912829bcb924d69049a1c958e6a3088cab51f956c87862e776320e78457cf31c20957158bb377460bfbf93a44c079e1f1bcb7b4268a0cb1cb8151512dc632252700cf06c988b2a3b254ac6422c73432ccb143819105897575c8672b7b0464e61a6a8891bccfbeb51f96120107cce8e950802b2c04650a1f264aba721541897538278bbac29b73f811940a47249035b04c0023084bf57806d51da03605c0ab0e6a6b65cab53cb26425666dd1b597418864211c6bec492d4577bc127369af391f8ec72c53302df5013c2c7c62d364b35508219749f131b7e2792cb206a9abe2c21a565bf05c1a7f8995c89549aa3120ffd83cc7a8b8a95bac3e7eaba48b57f55829f05bb265cbbb8b0b7983f7618f2511b3fe3ce9a0b735f2c1acd189f9115a1f1933ce19a8535958cba82464ed9829bc9a0c1405266f697d54128cb31cbd5b95c72740fe16219997210512a7343130e7dd00556948abc6c0dbd215e9db44a2d80c5606b930c6c8b949081bb453461a21026943929d3bdd3c942f8951aaff04276d2186cc052b6f67e84d5aa6be0c67ad74aace945ddd7c4b75248a0854593e8b27e971895b58c08e8107214afea3aa1b41a17ca121fb8308eea899e8cf04f7e884cd40746f2106a86164489ccc20f526154e613c565a282d5742f4953e963c42e878ab4d6668cb9c15f8629f537cdaa078db33191ee281a46ebc2a3036639e5cb1b201384b222af46873e1c946438125f060afd4734e21794a8da3d7b266c4125b60c9c480091874ae9c242f550898a30281380fa352c0d4466295a24653181e0e292ae099abec3275f8a89f22c983c8a0875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_private_key = 2ecb7caa911a2f615a13cb82e5a8be85e1c2bcf06c71b9696682532639b57a91537e470e8514390949cfadc80b0e5c3ee3eca869e22250560d8896b5f6eb0fc6ec0a6d01760c9108b7a26cd79039bcb3cf9ea0432fe0581626cfedabc12f758b407c8e9dfa373f45c377fa6d41a7205a7322b737cdabc8114df437e864c4abbb3dd084964f971b36e24406a7a7544a260d917c0ef95ccf33b1833bb6d4232bfce37b96004ed7779258faaedd9abaeb5051d8f605eb85be0f9599ff28b40587488fa376729685a8336c0dd213f55447e2c4895111b98e73bd783b2d08960abce22f6f894ae5456577a81156c66f6f1bbebd9c04d1ac43b77936f13060d3305a3893a825781e47928fc492adc16b31b2669882fca10581603b400f297b7fe7525d20e82958099b2d118ed3a14a8a915731525c470b7852a9b0ef04b4a3b0b65b4c5d7d486366175540a91e752993ba979d8a446f94088c7c3a02fd5c051f900a141957e63cbd71aa012db60a02b3872f3a623218a6b1f628fe8580e8725d9fb647f128c2519a8a0cd0649671616b462b83904ce621c95ff44697ca71ce930eaf0b28a6448a1c6b38c14800427683b71c954e49b6a3b978417b78ddb1a1b9729b89160b4c7ba49f312e23632460913d82d655d6e00b5b17a635827d8a0781e12a68c536ab40909f46a7173fa9cc9990371dcbc0b8a433436133ac123a73664a14e1409b4476ab001c17f26ebe968ed8c6a9d491b92f234499435e2df615c849be5f6422c8bc9de8f148a7c0713d93642dc852b33652287010f02b1d7b77972c797add3a38651b4c11ea968ce53f10d38df4160101fb0ee557bcf5b3328e12150a7c0d769812abf2ad2c1c7661844e6b34b25e7a30ec64b6e7d4282f48344bfc6f33ab3c428c76705cb9b1e9637721c9ee60874017013374082892b4af174749041c606b3f6690146bf1b0c8d2844f80594f265a8fb639e209c9b7fc418a230aaf340bba34c1c66b7d570918ed6caf8f62768620058cc7cb4fe1c762aa96a5015b82216e204c5821022caa84af9b12b9c9bc683747a2724c88e650539779742edca6a6a6c5f5d68faaf73d4cc7aab9b105f3a1b46cc96c915912e807aa6c841f6be63812062ed1d07bc9164eccec7e6662056313cc32f63c6181cf3343adc9073888d5756f508d65025bf6490a5f6b164a942466e60c4410c72aa69d2ca10459b890a4cb22a7613d44e70ac96aca21169f932a6134d27a6c05582e830c0ba137df060c6249b360831cc6b993e3d455c2e61694b11b520c64078bb552a65a3bab407d46c0ee173bbb52a95c7cbd8612380fc0cf1655c8e691bb0493103ec80a5fc92b4951a0d78768504284ad52580f16247b3c44af0a397f28ce3d0c0e4d34cc48b26b3998b060f2a9a013889685446b6281b3341c08e8300a013390a881a3a4937b412bf4745b069acbf5315b9955aa4999ba827bccbbf776829291a9067272059104522d69d1834886bde76c078a6061305833fefa710ebbc0dd0729493a285acbcf2708cf93ecc76b85691e20bfa4379c8521420c231f68429bb5c76e69378f6ef3475fca5760a5be829c2b4fa955e0e0931423b0a615194c26225bc538e2db29e928c686892be81b1a04f94e9ba65ac12a68d013885a021d91cb21cd7b76f0138667b5ce8cb742e5a54bb34bc17b28c8af5c27bacc6c308cc127a0152120755dd61145970d3cb02c664c3fb8c5763ac841f845b7799c9cf7f61318511b6728499e843ce1a18093ea1caa879bc6f1c4aa5a279e80afedf5353c5121a5d0433ffb748c0790161b648886a87fb003380a1dc289ac2bd876262c90081470453b12f5970d939c6bb573263b902624b03e403395a3a9a3c8b897c2dc5a6b630ea4cc87b6f456b5616a008c8dffd6b970541117335189fa4ce92883b88b3a0917994974cf4837b7b31c16d36bcd867181411239086940c3a03dcdb612ca1411cf6038dbe35eb013658037b98d329d4a647d2fbb7983136480a722dc791e2281c251040155fa5b0c092d437576a4f055f1708c58e3611d3071eae9053c4bae4af8769494077912af5ffc129c7164749ba2eaca0676f02a8c4bc1545c405ab16e90012a4915c4b470c230587f0bbbbbdc3487387635e457c66e3ccbce8c75048527959651e7c99be7540833828e457c66edec8e201b07d8068bdf671086d6af0beb628685790487707b66be4c7341c654a8119774e8b262b2f34944898e42752149039356c1348eda779b526da7ac838551855a4a8af5780c5567295dd16011e3177e267948ba7643174391a34c5597b7af774256329f211518e1a67b2f35898e610f49500c2b4647297723004ab77f9b538524a9b96b1e5fca8f224c2e24701bb726735b408323784e9afaafde570b2f4c2bba88bb54808ee73aae69ba352612268e9b4460f004af4998a6c484474c0d04111f2d1091d31443ee2447be719e8f4c3a49e918eea7870f199e1507bf0bd543deda7eba63aa1704a02eca523ae006853b5e09706259605e72e78ad6fa602bfbc7bfbb0d2d78b5155b3d2017c9086803be862ef501196ebc2af13b2b0569473e9620fab2c85fc23874ac14b59c0f082029b553184b01c76d856858475914f025df1914c16a209dc90a306914c3371a6cf68473a431b2886a8cd40a5302834a73359e001658b90725e02e63c27403fc0e1953b11ee6a6415815d2b2bda0b13e54511c96b801da22b5ae94b68dea940ea4787f3a1506e290696c3535b8ce73351a6e48bed272af5e456904aa03094210494c90b280c2942682dcacbec8c644e9a36d326816a42b23b96b751afb7b951a87d8e94db48932aa14bf73e92b06b85f7afb4387e949645c5838622ef7bb2fee0175914b3c931b25f80a010568a179a21727f52ce578aab6da1a88d8b7461a5fca7865c108a477363d3f9a960bfa81b4d34a551c4f1e234e18fa294b7b8055e6acfac6242d671855f29979609b821566acbb381dfab0cff8bd47204fec023ef281226b63a7d0397091a9844e23b28f57a0dd205a520a48a3e517276977388b575522c5b78627c4253bd38840a7889fa75a7bacd10b8f27a3e13bc20aba3ddaeb88ae62b2930338cdda41e0770b4d2092da100aeda2b5f5600718d69b032a45bd677b8732965b82908b877f5f77446e4aa132d46044067b21090404d21d01231264651b38832137da53caba0865957f5af7ac4d640fef96702f853bb4a70767dca757da900dc73e17fba67ca85d94bc98378a6a71c5c9da14738e0c34f5c81471539c42144b4cab5d8d53285f8c415cd8cfe2d30295d00dcb47b4ffd90282f6b582a57bd3f13eb41b088ba624575b355f8c7fc0f34f1e924fe7d653692c4f44e1c64f9cb145fbae9e789c029421793a4c43856469298b4ec648b21babc0167c04d90a3a8c554df46b80b407dfca54d5f68e2dca4e98a92ff38b427115c26aa33161503a83143714234fed912829bcb924d69049a1c958e6a3088cab51f956c87862e776320e78457cf31c20957158bb377460bfbf93a44c079e1f1bcb7b4268a0cb1cb8151512dc632252700cf06c988b2a3b254ac6422c73432ccb143819105897575c8672b7b0464e61a6a8891bccfbeb51f96120107cce8e950802b2c04650a1f264aba721541897538278bbac29b73f811940a47249035b04c0023084bf57806d51da03605c0ab0e6a6b65cab53cb26425666dd1b597418864211c6bec492d4577bc127369af391f8ec72c53302df5013c2c7c62d364b35508219749f131b7e2792cb206a9abe2c21a565bf05c1a7f8995c89549aa3120ffd83cc7a8b8a95bac3e7eaba48b57f55829f05bb265cbbb8b0b7983f7618f2511b3fe3ce9a0b735f2c1acd189f9115a1f1933ce19a8535958cba82464ed9829bc9a0c1405266f697d54128cb31cbd5b95c72740fe16219997210512a7343130e7dd00556948abc6c0dbd215e9db44a2d80c5606b930c6c8b949081bb453461a21026943929d3bdd3c942f8951aaff04276d2186cc052b6f67e84d5aa6be0c67ad74aace945ddd7c4b75248a0854593e8b27e971895b58c08e8107214afea3aa1b41a17ca121fb8308eea899e8cf04f7e884cd40746f2106a86164489ccc20f526154e613c565a282d5742f4953e963c42e878ab4d6668cb9c15f8629f537cdaa078db33191ee281a46ebc2a3036639e5cb1b201384b222af46873e1c946438125f060afd4734e21794a8da3d7b266c4125b60c9c480091874ae9c242f550898a30281380fa352c0d4466295a24653181e0e292ae099abec3275f8a89f22c983c8a0875e7424c3b66b1aa8f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433513906f5bef81445bd210d63fc4c9b9ef0b61c17b0cd5b229a45908fcbaddcecded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +expected_public_key = cf76c08745bcb7cb2c3478823c977ba1f3565d880d8e731337d798fd273bee2a03416cb6d11774e0b7c177e23a619509e04c334e486f97a963035c2952fa286c8108a3fa6857c080076143185603ef480c7ea135c76497ac2a4ea1c65c535385bb233c54b0326d415d2b01cb0fa60b969bcfd5578920a06659291b59e5100441b0e535b46294680627646c052d13404e486713fc460727f50677e48e64275e4e2b33da225686d920941277caea4d8f4a7c7b96b151b36836a76671c9010cc7546ed301866a694104169540a8620415037654a55ab132d56590663c21c267b94a2f1a162bd61808512c2e7c671247142c3cc54622697edb50514895276efcc21bb02d45c79a4549a501e79859361457047aba280f91c13556d06095a13ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a482afe97b508304b6140ca9da2c33f26522d51363662a0c437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fd927c2e3207cc77cc127790ff2634cc2220ad001e39ec393c5c5b5598193d628417b7bf5f903e9274c2a1a38f72db99e4c2aecd8b5b5b445d3d259057b2b3ac1b3a0657c2dffb6c75c93b20ec3358180f9c124fdac8a64d2b73ce6819bc1005602151f7e4c804bc89a81797ca8313650910c7b2a36ad2a690e3af7a99cb2bb09cb1eaca0891bc69d989cb7220faa3626342cd33438877799835c2782413a9f1ca29861752f294b7e3c2a3980618d0540a5cf00c01943db920bb4693436d3b7436593e7b9a83cd21cbdc692956cb3f7a17c41f46af94bb15059b8661349248235adf68b69d9944f2f30f93173ffda657c9d722d0521c12b2790e230afb49496a930c46a62a4d8c26601a4e783b73c2a465722401769365719681c5086d8a7bbcfff451e58b2cf32b363c501e978971d8c5ac6f41b458693c711765c7fc1ad7319f3481a68bc456eedc04fca898b0b3ab59a14b7fa1c148b6b792352e7ccb1456a86a5a0377ff98c08ac0bc4c997b0370baa76950bd0874f9478e6b8150770c4ef2885e88d119126492c09b8e93110616406e6bc7ab46ccb0b47587c0da1c54828f98941dae515d279308302b672ba10ffa0749395269f5c5a03581799eb3b60fd53355b3690efc291c3b77aec797fd09b1cccc8d5bdb8b4dbc18857c28ecf86ba3a654b8a351d0174df4ea4d7f4159656010f051462a3c4988e28e74c39cddb557566b7c757874d9061fa5f85693ca2124822891a4a0afb000a3887522326dbdf4a54e851cc775405938bdbbd39370c01ba010b8b3785e3880a54470546b617ad86bc984a70de844a510e6a14e241f18c765fd04c2006c6781ec90c9e16881b7bc4557945d68a4543a5f16968b39f38e8f5aa7699171d8567e35da662087aecea63aec3094bb4c88f08432b86780237218afc22ec78c96322a81b8060719fb6742c290ecd8664fd378a95341f3c326d992b3b7417c5f543249d57475b3b526b93307664217b8837c1c48ee6322df891cbf6943fdd445f2da71f8ac449c718e8412cbe0bc2efbe601ad08af68b48f7d2677dbe05914d9b1629b6cfb69a9f43a05b6fa560143a45f21405b25983115b537315964b3525117158013a434785fa13b30331148f028a2e3e299c9969fbba917cc27b851823630bbb930ab2336b59d1e0060e74230d6a0399087ace16894d1e4236f3b9b708645a3b27378a86c960bb038080f93e66bd1bcc3e57739591c386c45846cecbfc90ab3fd506ec50c0d0ec9a2422cbacacac17f62472b4ac6ccc645d48b0283a6c62136a60d62354a983d4ceb74eddbaae57711bd958614f054336a38630535f0dcbdaf918e5dfac711093974d2987dc1109ce7bf7429cfddda9e1826172114254ce0bc526ab358e359c35cba02e720c4611dc17122b8bb02702a962db3470e32620d62291ad8c9db86615e9ab48df3aefda4003f815a1157640e765afb2527b2c532011ca07e321673c721c3f32a2613394f68b687a042724c0207cc3b87675ab51a60b4f12d312a0fb5443cd0518b1f9788fef9a36752291647c234d49daf4a6a4bf420e990307f676271a47cfdc68182500a93c914ea348dbd544b3163780a2c2373282e319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_private_key = f3ac3178bc3e6b8002eb20046ee3288f9cc63c1abd0b14a118d52e2c9a998d4c67e2014415084f520945f55b985adac8c503079789aecc491eb7ba540f32be8823a4a837786be140d260cff5d46186588f4fe2419e0c4ba1b619567b9d8206b53ab1289640520f2259f5d6854871498b23696a321813d7a544e77fb3100b34c89af2c63856fb43bb0a74a6073958d1199b4098386984847962b353b4d81aaf4cf65349c8197db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b4820369799d352ce72415cf1c692537a48ab603b9dc741a08a66d874bf46daad570b6f1f4133067a1d900ca87cc25e91c4ce1c84b46d3c5baad46fed227268f1a9dba968eff27249b3c6e4c7c19e8a13046a2b45bc24f4304a80c09d37ac289f924f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773707046c362d94ea547c3050ab251953464f4e540764b08103a88e448446f6b82375c15e3ca9a98798639b83638ada857bdc1e3c6705471975c51b8087a26348babefd234d27d6c055d3aab7560b28dcc13d343a79530ac868b5f6ac83af04b8d7a20b64dabe9de32a5c1b2c2acaccc4588c1ba26f5462aaa5c1bdbc36467f346a1ab5c5840a07bd33ceb44093659bb0451c4c87ca4852172dc0bc3674b4275078cd2b9a3afd61bfe454107d092e5840c4968c547adc723c1970cfe705c5d33e3a4533f0028655c6ba44ab22c2a4c85a82b4b6dcc09765124e43c985459cb2ab1519db1ec6f348d017a785484802d90e0222ca2313b4fbc465dec0cd4f3a5675e33cf0db79145867d5f0b8f340526c8a744929728ceccd146b6e66d03f660aa4e2e15d200b5960f3a03b571bb2e59160048e498c15379027e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc789e062571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c8655503f2f970071b40f6ba3544c64c41887184828be6057a9e972631604901a7870733580c6ab8d4aa18b49cb4d567577aa8b0ca2490edc68b168583b8b38415d32f5558996cc911a9470951430c36f71712f1c579a12327c41c441c980c286b71a31748ea54df2a557fd1701c3173944b7b40117ef9cb08a7d03d45531b8de4c753f697ec4b4303448c260b0783c81ed599425d9b16806828bf795c8cf65a95f366bb90110cc75d3e6064bee17cf1497f36c48e68b46ec07417b2a876cb556c705c7ddc387d74f2b0aeec9070d227af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94a92388b1afbb5408cb1c0fcd3c945e2923acdb7e16a45c03ec3298b3c44e9c1e75d049b2ebbcf2f29a2d3b7fc68644530010e052a0d357809009cd786604a39898b385b70ad7b3be011ea83b93d4426f4f20a3d0836fc6fb532fa14536285013050c16d01c5752884e49a82a4a0bdbc8bc2c7598d548278703ab4c607a16b1bab64052f40a06d3915cd03825f12c069d956f2a5662e05804183932b5216ca66274214acf5c01a7f4c77ebf522db776068f94151f7ac33831259b53bc48e99c50b260faec0b7bd3cd4fa9b5a5c2588cf098fce5aaeeb15fe651355537953d9b8580313b56336f9e6a723f412123c51e942438fcf65f92cb91a0f99b3dc5b0d90a94d7f9b0d9d4ca42408750169540a2bcf2ca20f13bbff3ba60f6faa2df7c176f74cdc2090555c658f24273980c4d6c03461751b9e7e59e87062037433d2a79c72fa6307a77b3d0c42cd8d1aed464b90963c351b2648ab5bc113909ee6c15bb0189603194155051fa534d0e723f4e28cea0b7ad34b3767e1029598b16cd87181d9b8332f87b38795eecf1622f7955bc646e470b54bd3bc915c3bd2fe40eba8b31a21b79130a3ea50cbabe79b7370b5130695ed8a61291125f79122b8a19666fc571076361af26b1979a939d481b55b781baca19898119db5ab19cd22617a59851a04b5db78e1a532a4da80ed29c8bd11a5ff3609e9c6b4b2417155045af7edb0d91506a7bb5920a5095c3327b6182a74aa14bb4957597077e93c880283137d9b424f3c16357051c4bd88549c090ecf23bf7650941ac00234c0398c56d0e3608f1e348db9a0d4e252f78b05c9bda80dc01a7c0b720646cb3475514ca43b2254ba566c929d9d68fcf76c08745bcb7cb2c3478823c977ba1f3565d880d8e731337d798fd273bee2a03416cb6d11774e0b7c177e23a619509e04c334e486f97a963035c2952fa286c8108a3fa6857c080076143185603ef480c7ea135c76497ac2a4ea1c65c535385bb233c54b0326d415d2b01cb0fa60b969bcfd5578920a06659291b59e5100441b0e535b46294680627646c052d13404e486713fc460727f50677e48e64275e4e2b33da225686d920941277caea4d8f4a7c7b96b151b36836a76671c9010cc7546ed301866a694104169540a8620415037654a55ab132d56590663c21c267b94a2f1a162bd61808512c2e7c671247142c3cc54622697edb50514895276efcc21bb02d45c79a4549a501e79859361457047aba280f91c13556d06095a13ef8ec756556b31c1a535fe895e3aa85a78346692b9b225330637397a482afe97b508304b6140ca9da2c33f26522d51363662a0c437cc3dae5ad97b491d8885dbfc65c82ba88e6d78564133fe5ec502543340736b2fd927c2e3207cc77cc127790ff2634cc2220ad001e39ec393c5c5b5598193d628417b7bf5f903e9274c2a1a38f72db99e4c2aecd8b5b5b445d3d259057b2b3ac1b3a0657c2dffb6c75c93b20ec3358180f9c124fdac8a64d2b73ce6819bc1005602151f7e4c804bc89a81797ca8313650910c7b2a36ad2a690e3af7a99cb2bb09cb1eaca0891bc69d989cb7220faa3626342cd33438877799835c2782413a9f1ca29861752f294b7e3c2a3980618d0540a5cf00c01943db920bb4693436d3b7436593e7b9a83cd21cbdc692956cb3f7a17c41f46af94bb15059b8661349248235adf68b69d9944f2f30f93173ffda657c9d722d0521c12b2790e230afb49496a930c46a62a4d8c26601a4e783b73c2a465722401769365719681c5086d8a7bbcfff451e58b2cf32b363c501e978971d8c5ac6f41b458693c711765c7fc1ad7319f3481a68bc456eedc04fca898b0b3ab59a14b7fa1c148b6b792352e7ccb1456a86a5a0377ff98c08ac0bc4c997b0370baa76950bd0874f9478e6b8150770c4ef2885e88d119126492c09b8e93110616406e6bc7ab46ccb0b47587c0da1c54828f98941dae515d279308302b672ba10ffa0749395269f5c5a03581799eb3b60fd53355b3690efc291c3b77aec797fd09b1cccc8d5bdb8b4dbc18857c28ecf86ba3a654b8a351d0174df4ea4d7f4159656010f051462a3c4988e28e74c39cddb557566b7c757874d9061fa5f85693ca2124822891a4a0afb000a3887522326dbdf4a54e851cc775405938bdbbd39370c01ba010b8b3785e3880a54470546b617ad86bc984a70de844a510e6a14e241f18c765fd04c2006c6781ec90c9e16881b7bc4557945d68a4543a5f16968b39f38e8f5aa7699171d8567e35da662087aecea63aec3094bb4c88f08432b86780237218afc22ec78c96322a81b8060719fb6742c290ecd8664fd378a95341f3c326d992b3b7417c5f543249d57475b3b526b93307664217b8837c1c48ee6322df891cbf6943fdd445f2da71f8ac449c718e8412cbe0bc2efbe601ad08af68b48f7d2677dbe05914d9b1629b6cfb69a9f43a05b6fa560143a45f21405b25983115b537315964b3525117158013a434785fa13b30331148f028a2e3e299c9969fbba917cc27b851823630bbb930ab2336b59d1e0060e74230d6a0399087ace16894d1e4236f3b9b708645a3b27378a86c960bb038080f93e66bd1bcc3e57739591c386c45846cecbfc90ab3fd506ec50c0d0ec9a2422cbacacac17f62472b4ac6ccc645d48b0283a6c62136a60d62354a983d4ceb74eddbaae57711bd958614f054336a38630535f0dcbdaf918e5dfac711093974d2987dc1109ce7bf7429cfddda9e1826172114254ce0bc526ab358e359c35cba02e720c4611dc17122b8bb02702a962db3470e32620d62291ad8c9db86615e9ab48df3aefda4003f815a1157640e765afb2527b2c532011ca07e321673c721c3f32a2613394f68b687a042724c0207cc3b87675ab51a60b4f12d312a0fb5443cd0518b1f9788fef9a36752291647c234d49daf4a6a4bf420e990307f676271a47cfdc68182500a93c914ea348dbd544b3163780a2c2373282e319b346e7ba0b1eb67a1f92f57648fb68bb6cc9865fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e4f8b3e9ae47d3b5b95c080d4f18440c24b0691c19f06f5547554697bdfe97b011c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +expected_public_key = 2e225b33d590a3bc60ff331f856884594944a1055f1ac6bbd5f7bbe0c7b5363c984d408b493b92bca2a9395b7dd9a46c17b632976324206179bf05406e629f86875573d05b0599b561dc5ee8f54a73690b5c3b414fcb7aade872a9489a5530025b442c94052d5e892cb47b7c7585547a72a9e3a3cda629aef1876c96c479063c49e94b952cf819af8b3bc39995d4563337bbcd419c17c4f5696a6002cbc6b760e344a7fc49c2d0c0ed52b54f16041e5c4ecf2426442b9d59ec05872190a80b4f341312f91b7737cc77696acc5e0323e02100563519ad3002fb95b0591aa126a70ecb708143c7a502c53a77a82ae915b25be77c68006f4ccb0252463dd668537c24bf4b0039cac4a4e6b3c19ad37301b595c504909d8a4b8af71c0fc2c905e26b5317703b3195712070b0d5677bd5101c4baf9186582a8b70d163ab01c6151177b7c83b6cca2bbf62f6abef41c6ad6764cd8392819a85cad945ebd210b9c08f1333a393b144a4782e683ca2c73c5875f20debe3ab59c8393f7caf4328a57618197450097d250e9a77266d15cbd7b3867dc49c0e83c7717513bda8235e8b89fde06cef1413ee0a0e42c814b4da9d0b0c5961f73e90c57c1dc614de43c396118979cba7144316607bb82e5451e9475c0cc4127c58a69fc47e6f02a3fbaa03949a9760573b2bd3c6606325c56a23cf4aadd8024bf9d1020332cba28c7fee610d45674e17281e047822138b04df69ce9e11aa644c47fffc688ba4b6c91b01e2747d2765b7d9579485a37e7090aeae19ae2773cb4cc17b998c9d25955a33a0a9c47117fba45f02611f1fb59d415a93aee26a2e4726e50c457c692766d55477546785f76a2ab7c5ab983a90771834da4016a755a2040ee3f6a24145cd2f827729bc74b17bc92032548b663f50b307ac511c47e24e4ac4957e552c4662915074373d83b34f468bd66091b984692dd32669332b0527b0a0bb3df41556aee9693eaacf97047516b6aa455311cf97135b697e7e9a2e147756e8fb0b657b41a6352fe6a17f4b031efe17926b7757fa74831257ce2442066c624bdb106d3330b99d730e7eac1d1528348156352e266475204c6e13b5dc06b2596097c1da6bb2d31e139c34f732a70bc09afd6a8e9700bb20fc78e3fb15eba8b2eca7bda0508b1d8c0c9393557e62836117219fc2201c79346949c53d8414c7e673106234e98cc1508c81317450670ca7de957bfeaab0e6780fbd755eeb08a441f983e3c81468a7bfcbb152bf6a581a901564f2cc6ac13423c32dad054e02e6509725bf13605f646922bcf84fcb4b456c7ca25457415c7275ba54ae8c4717157a299fa18b49fa6be7460f8427516649440d4c0dd42814b8c4692d71b7b6c0049473472e002a53392d183b4ab70b6582557f8ed067eebc00b670b517433466ec6b2f967ec1720b8c68c41d2923fae5c4285c63b03a8416926b93496dd57b6e241b14f2576e7b9a28076b2dcb8c2f475152a5fa7ec98c952a263cfc221282d57bf329a0dad122046a75399507574289a18226afa90ce4d7235ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fc817899375f890470238004cc7520be51feb8291cb8bc336813dd14a7bb24b2b8b8b425a969c4e410ac4876787f67ecb61409885518e0533884c613f70a22997b0b8cb1e2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db8614024778225b92d5826e1bcca780400e79b42e0fa3baacc5825bfc0f45cbc485d69c024ca504a975ada9a5a822cc0c11cb3fbabc64d07db6133a7e91223c3658725686ceab91eb74060bd039cf1488376660225b42db441ddbd437d5193bfe777b35513ac8d85e6da433faec55fe969fd3865eb9045589b09769a41c963596ce70238cf7b407b096ea546fd5f141ddd54ec001b76cf634871240d9f82f77f5153e84a6a5c41a3cd908e962c5b8898ebd4287fb2c97a0710b448c4ec93cc5ef1719c91b92ae77b35cf2628396160f0bc3263003e2e89243f073726a657b2386173115b778cfc842c67a4b71d5276a934aa94d92b452286a35913b0262af2a4007642a0b04f76ce58a31bc776d6f1b8966180e2ef026763a87519a10b8049d799a8a3d038d5be31eccd5676550482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_private_key = 37f7089480382622ac6687b4b15bbdbc1a9ad7467e8ff4cf44f0614de74b9591b9c5410d2d7084bb57ac27963aafac148de80dda6232f4a0c634d677a80c226fe67063191c05a54afc026080877538f63df93cc6fdecbbc0a9a0a4215488da1a2f7b1ea8f8b917f32f397b94c80170bcd423c1f1ba4c736449f84bafd6711b0070dae72de1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2cc1518fa4bad3c23438e06952c9317d198b0c112d79a89560dc3361f5732f820ce4d16ed448ac2ed221c8ea3601602c27f640dcc394a7ecb5079978cf52b80de15c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb524c2090a54ba793c845420a7c2c29e78a9b8c83c310d780f74127c02a59ab68c1b29952dff1196d0940edc338df3e1c1c8e34fd0dac4d5596f97a2afa98b1e8be46bc0a96df412639ae5b52229086229b5bc79ac020b61a56c04091c10cf9940f798a9c50ba1f5fb30bfa947f20b62a60215c5a88d23b70c0e299c53f49a1ed511ac5812558133d9f195e1fb5d77314559ea79e63a88e781c4224155abb5ca91f089c0c609cecca32e549b0cba167d9307a3a64681a815a69c5d7e787751162483e7701437034f0864d8d53201fab9763c7921eca6f11247e7ea364298c1c3ab893549572bec45c1a8c3b88659cfd526810b23f2095aa6c1424c7178187109f83063b52547b9c731f9933622a33c7a8b927a50191593488f9a0d12331017919159c7a027c3956fe109393a167a6475cebb49224736847319d161490ec52396d7babfb638bdea29f50c9ce37314fc858455f63fcc70cfcb751df12274feeb45a124ab1b997c917a550c3469a0c185eb0238ffcb4dcbf751e12ca17a71b807b1446ea7180ee302e6998ef8d12a857c84ffc377f5e42fd41238a54345229916a715977025b3b4a6060f778de7d426a2f95927335cb202bf4080b8510cc0da12c4eaec4bbfa42997e21504b8c5d32604f1d66e8d55b50c393f973acd37a236db595e3ef08239c42fb5e9243d967181b9b94f4521c104a8aa726dec057abd419bc8c6cf350c91acb78b0832144f409f78992652e30eed7ba2375b3245d877c8e8b873f0427071c956633495381a2c642b15282b9945c758910fe469cd091b4458218105da96a479be0ac6b3ba155d359b2815916e93e9bad3d431945b852e519df0129174b24a32cc9fb8a62de96733d153a799cb8fba3c86b9101cf3d4a97bd3b699467991a57129607c27274d3224cd1848c17f1550be47b71a119873045e215bb817cb92c12a7bdc6347df8b64dd686873d800b4672aade8af56d2995546cc37c06f9212a54745c5597184ea85cedca7b980386fb91b8ae677a035a4547b5848879c2567c8cd6ac285f6f2460dbc0b73f5ae0993c988418c234895380c556042acd15a6c015a13ebe16cdea4be38528a9d244230a0ab053c568e31c64d06a3d7bca0e5207b7669811a3512f8ac6887137b0b7627d2401ccd604ae786753fb6568cb522b28712211208c1849d1f75cc4fb951d2aa081ada952998b0b0e938b77359233a76c135897e91059cc5639e978c12c6bbfb735fef4bcb1d60180df21dd367c02e79916d697f20197d07e9980af13d3a0ac5d2e010a8bc850476630f5b8b37cb8a88c14a047a1afd576b6fd0aac283981457430cc62a900c7e81f47f2574802eb91707e54db0e77c223467ed07c29b7c5197a38b9cc7c77d99018faa271ed10b32843a92001be592afa651082a646858e4497f777c0f589913f50b0952669689bbdc033701042f32dc48fc26038a63142e17a6d7c711f5f058c2392a50779eaa221c811975d957c389513f39f42f7a58175cd1a6a50b730888102dc93f4f056bcb42710572b6ce36865c621a75d7717412a12cba792988517540a3d8493f3ea68858654c62807794cccc4102a9e24328cc722971012af19bb7ab6c97f4813ffe5a2f13403a37b7477d18bd35e4613b73b4ee15a3c639593c8530211a0a52d214b7d48dd93ab27ce23975f2cd9d8aa70c878fcf342cd8343488d7a0b75228dd3cc8ebc1148271af1526583603baaee2110c400ae5145cebfb63fd118f958081e9a652c322b793883144b96517c088f4237f9a067ad83bb3a59c1cadbbbd2e225b33d590a3bc60ff331f856884594944a1055f1ac6bbd5f7bbe0c7b5363c984d408b493b92bca2a9395b7dd9a46c17b632976324206179bf05406e629f86875573d05b0599b561dc5ee8f54a73690b5c3b414fcb7aade872a9489a5530025b442c94052d5e892cb47b7c7585547a72a9e3a3cda629aef1876c96c479063c49e94b952cf819af8b3bc39995d4563337bbcd419c17c4f5696a6002cbc6b760e344a7fc49c2d0c0ed52b54f16041e5c4ecf2426442b9d59ec05872190a80b4f341312f91b7737cc77696acc5e0323e02100563519ad3002fb95b0591aa126a70ecb708143c7a502c53a77a82ae915b25be77c68006f4ccb0252463dd668537c24bf4b0039cac4a4e6b3c19ad37301b595c504909d8a4b8af71c0fc2c905e26b5317703b3195712070b0d5677bd5101c4baf9186582a8b70d163ab01c6151177b7c83b6cca2bbf62f6abef41c6ad6764cd8392819a85cad945ebd210b9c08f1333a393b144a4782e683ca2c73c5875f20debe3ab59c8393f7caf4328a57618197450097d250e9a77266d15cbd7b3867dc49c0e83c7717513bda8235e8b89fde06cef1413ee0a0e42c814b4da9d0b0c5961f73e90c57c1dc614de43c396118979cba7144316607bb82e5451e9475c0cc4127c58a69fc47e6f02a3fbaa03949a9760573b2bd3c6606325c56a23cf4aadd8024bf9d1020332cba28c7fee610d45674e17281e047822138b04df69ce9e11aa644c47fffc688ba4b6c91b01e2747d2765b7d9579485a37e7090aeae19ae2773cb4cc17b998c9d25955a33a0a9c47117fba45f02611f1fb59d415a93aee26a2e4726e50c457c692766d55477546785f76a2ab7c5ab983a90771834da4016a755a2040ee3f6a24145cd2f827729bc74b17bc92032548b663f50b307ac511c47e24e4ac4957e552c4662915074373d83b34f468bd66091b984692dd32669332b0527b0a0bb3df41556aee9693eaacf97047516b6aa455311cf97135b697e7e9a2e147756e8fb0b657b41a6352fe6a17f4b031efe17926b7757fa74831257ce2442066c624bdb106d3330b99d730e7eac1d1528348156352e266475204c6e13b5dc06b2596097c1da6bb2d31e139c34f732a70bc09afd6a8e9700bb20fc78e3fb15eba8b2eca7bda0508b1d8c0c9393557e62836117219fc2201c79346949c53d8414c7e673106234e98cc1508c81317450670ca7de957bfeaab0e6780fbd755eeb08a441f983e3c81468a7bfcbb152bf6a581a901564f2cc6ac13423c32dad054e02e6509725bf13605f646922bcf84fcb4b456c7ca25457415c7275ba54ae8c4717157a299fa18b49fa6be7460f8427516649440d4c0dd42814b8c4692d71b7b6c0049473472e002a53392d183b4ab70b6582557f8ed067eebc00b670b517433466ec6b2f967ec1720b8c68c41d2923fae5c4285c63b03a8416926b93496dd57b6e241b14f2576e7b9a28076b2dcb8c2f475152a5fa7ec98c952a263cfc221282d57bf329a0dad122046a75399507574289a18226afa90ce4d7235ad9a658955b6a25359a435d5a6798b1d453b90679b5849e3fc817899375f890470238004cc7520be51feb8291cb8bc336813dd14a7bb24b2b8b8b425a969c4e410ac4876787f67ecb61409885518e0533884c613f70a22997b0b8cb1e2e333d51ac4e5fe854c657c0cc748adee498b6c389d4b498d206845daa6aa89731b1dbb33f2c38db8614024778225b92d5826e1bcca780400e79b42e0fa3baacc5825bfc0f45cbc485d69c024ca504a975ada9a5a822cc0c11cb3fbabc64d07db6133a7e91223c3658725686ceab91eb74060bd039cf1488376660225b42db441ddbd437d5193bfe777b35513ac8d85e6da433faec55fe969fd3865eb9045589b09769a41c963596ce70238cf7b407b096ea546fd5f141ddd54ec001b76cf634871240d9f82f77f5153e84a6a5c41a3cd908e962c5b8898ebd4287fb2c97a0710b448c4ec93cc5ef1719c91b92ae77b35cf2628396160f0bc3263003e2e89243f073726a657b2386173115b778cfc842c67a4b71d5276a934aa94d92b452286a35913b0262af2a4007642a0b04f76ce58a31bc776d6f1b8966180e2ef026763a87519a10b8049d799a8a3d038d5be31eccd5676550482cb48f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc1b4fdc4929c2c7e4501ba7a9feb0be571e27c43fa96f9a7f934636ed9a86110bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +expected_public_key = 6806cbedb0c2c364c98989815ee9081d132427943a0adb0da7197cc7430757f3868c49c045d39c8c085665d13bed825fd7cac7fc6933adf438a4cb6849b91a1c737d394c5e08649d88e9274009c4375a4fad4b164851540e43ac603ab6f488628fd7272bc1981ba03121c3a22e587ef30a793ba097d160025ec1b629a348fb8b854b54139d5b6af09a7515ac4ba457c8289108c7c316c069a8e454a8d1084504c2a4e03c0a321681d168933e0062bfe1635de39ec8c9aa2a5a48983c1bc34798fc64114c18ae77f13408f753da60cb892c52f811c8382b3c455c4c0f08248bf7278b9b4b927580a3e50930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c22529ec61343537944ac07cc5a1ae713ca8fcba73daa688c9ca369e8b8d99fb812489482a727d40c7aaa6290f5032ab8fb5b09ae4985d7558b8c55b9f0accb3781b9b2405f11c05e99cb3723922d0da4963e68487631722c0cc643b3920b8c2ac34b54e77c1fc748c96c186b3a5439fa2b3b2e1a75b16357e2210da4b3fb620407c4cb78f18178f2b6c4706b619f18dc0863c72794434978d20933fc79193894041183660f0437a2e309eee87bf538a2b8c7672833820805bc2cbda61e8f04b7839b1493372759aaed528980e02726eba914491b7317099215135175c41986858fa31cfb689a865375e8547932899867b987167115031f5b4dd263f0341395e1176bff3a69fc9b9c020ac8515af5e665a15f48a3cba1c4a96390ad7795f7695e654279802c46275bab1e32fb7111619c55c8787cc01140f0fc03fcaf4b6df9877e0f24971f06749bb343e1a5faafb66a75b4888a1c63f593bbf3906c324083f737a39247ca110279a677736e77eefd3b08f645100e249461657da00b365a58beeb48de3f96b6797850119145975388ab4c9025215dd4b0a0ec066c8a7a593fc0a1ca921c3c54659d40fdfaaa4f63a6b0d55a761e9a57843617ad6963087396a0187bdf593d98009ba825d056bab8e3b6ad5eb31b3f195a2c9b7cf9281c176b58346cdc24c580f23131213a08c4cc1c776c146893e8cd44983bc01494793028225f2161f916b888c923c8c30c43c41c1a2d12f18a4918216771cb992ff1abdbb33aa5f363e6cc044a0d68e6b36785951566e4a666af6cf9d3222fa17566966c734a364ce14933da00305930b47dc1e977b88e328296461c302c35f3e432e5d01243685c176e1b6876b03e341ce0a1c52ef32966d67004cb4abad9cc8a534b728db8c32811f7e71556beb656d773759f04a71f43413805c1334385e396e8b128225929977f41cf776450460707e0c247980ac42c69cb641af3cb36724d5705af745965181312a91aa000b42b82670a9aea43ac26a5cb3ebfbbdafd4225535255609c3a7d04332e6c816fb68e5ac05daf42c95c78f6db76213a083b3237b4665b9ede88c1bf53b4473005d4627bee21cf225bd35eb728932543956ca142b4f3614816d891895b14f0d28ba36d298d6713809180621d1b12ebabcf032aac6691b22cb9013d8a8dfd70ba1281a77f237f9318b43d043f193cf9e1004cda26f532ababca3528c69200624b613fba988bccc73288b7996c2de008f22755ade918784f7ae2f69ace6e08e0cc528e3bcc85403967da02cf1463c77976555460bba2824af0923f2dc4336ab44d54ca0658417f8fb5755f397fca11e07759c5ba86accac1e30523349168ef3740f59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d38752c435cce3cb9b176086019113ad638cf3426970de0013624313ff57ac82b1feb24195028b1b65bbcbd5c4ef3a60116125b3580743cca16ca9abe8fdc1ec1ca2e4d717a0eaca0fbcabf74034b74391d8d9668198a14e5491ec817701733be7ab11635e4a1e6910f3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b675a1660b7c22dd1947bb24f1ebc8b22b1ad1b81600b545f74ca076e468513c0a483466089dc1cd7090c4c5623b02b7824d2ba1894c4e200222bf867911c89d3264b5a081d7441a2f3729cfe4106a780237e179839323f97c04979887c4c223f23a81af875a33cf28cbf75722ab92308c320d32625ec326734a532333c8b1ab4767bcb682850750620c402878103056cfab5417354bd395084f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc85521d549b978b054a9b8949e519e3fc3a653607d794491341039713037d31c9824eace39e7127a974403441e25b714fafba4b98041e85b2fd8d8acc2a69aea9c80930306b46baf5245a505d48e293a77aa4174d1c095b0b4a45754a4a94bcb01d4543bf7c7def2ae2009408725c58bc76bde03abef3c4ee0831d3c6b2632609707b3b861f093e857902d52a2a48619b1ec20dde7a923412f79c22389601473076965959b2aa3c79dd31b98ca9847731c89b0929ef5174cc6b92972ce2c07c8139a62c901216245cfc92b2da158079e1c93c8e08ff438a02ddca4ca948f47a106d40ab6a5b0afaf52052f237e44f0765b3436271421308611845785e257cae691c39fb8c80bbc1c5fd687a547b7e8e3aa1d7c15a918984b6b359cd24711cbbbb95716ea54a8d3511c5dc983fa1b019e0b0d7de90c3c0a9e7652c18e72cad6f9c510e64f0cda8cbd86502a5880ee1536edd16ab36bcfd859ce879b3f5d6a0d90630668b7385c8599ecb1849a4942d87a91497129e196309156c9ab245f4c637080c963f9648fb2ba6f32d2566f88bce680203dfb827438295f8670c9bcc34a98497851bdb0e631ea06accc26373809986da62fa714012d2579d5d61443330e3b882c800b6c9d02c98e9859a4022db4a09510fc91a3b95bcbf73b3a09311cd13e52b61733e02dbb400e8a54a30668311ac02fae2b55fe05c95ac43875d92f3c2acb3d4a6b53d363d5d75a697061055a3a788bcdfa051edf97c3515ca920ebac9e7a998bb598b8436bdb63550e416d2aea5057562a901b609b129d92b27536e02c26ec6a3b2c5f6b733d0529330e9a89600b089dd30a0bb52530a3062be741b09818a78b4fb9f274b7262ca23b3f2a40542caa64fe38a6ed06beb5498733a38a7fd0b5aec2673aca2b07e00909e68d40aa207fb179cf7a60a9e13719635a15cb221d1cc88b921e950c94cee17d60f80ca5b4a656f501d7136d1245207479a1da42c26c48664297562a0bae0e7906e9d853fc7c490e4078b5b3b226b37101a31b5d05a26f1ca1f231a853f23f59d86a3fd269a0256eebd02cc0c6b77f1b1c613114e1084d8d1cbabd0c7702f43d2ee01db985382c562f1b7885a7015edf59bd8988b5bcea1cb04639bbf5b119e6293f908245455070da3013d2b6e2116776694b44e3a7e433407099a51940870b336f547677665c7066e181ce266ff0e508268731bd13afa2ecb4546276a5dc50772a6fa38541af968ae5c59e2d04c3b6002c7120a6a970ada2671590411552e48e7119c7b7f7ac97429e9b7cc0b5242df277cc10e7c48976266643a9b2308cf1799324780743f95e65851c03599fea7129d5552b86ac35aed10b5f00058a8742c02a3e4f6cbf5df61c66143ebe933060c98a4bb55318566184601bb395625fc86e4bd47377b54459b45e50c145596b9178d57d01bbbaa9a63bf444889fc810f1e40e07d289e0b04a58f84348463b9fca3176aaae6c1c119cf679bacc6eb685b9f443c2a9e304bba0adf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c16029e18d8493a524fc2a41738a25e735c665e79ac423aca37b5222d97030e794107262a30e76c2c712597527d92437800967c4ca2407d826ec5d0c1bfba5c96b82146320a7f74640100314b1b448db72ae1a57efc949034425da38c4fb03107a06c26e81773edfbc3eb265460d345375081bac591b3cc847a954ae1494f25190c84464141fc95c840c1b19aa0d700073f01381bf2b9c14249fb6719670460e0515d93507f5245b3dcb68e0f00c5e1b227e8608308280b4a54403b5a9df3d392ec3608eeacbc08e10c84158c97920ea670625f08658a17590c6575f41923027b637f2a881c3592271b3e3dfab7adc1a3596ca1c075167847a4c586394ec7735ca93266519c7ec49fc0c1964a47b00538025e1028ff304eded54d5f323cf5465c2fca52993352f70bc1289128ed702a4a6528ae7315d8f4bde361ab6865c182460e1f4a6e49ab5ac81b07c53800c65762aa0594b3c7cfbe449dfe238a63f35463c94b2dbbb18f9b33e6548dd7398f0cf833f1243e72d123918b35530414afa37cf88aba62003bd1f46b158b4a91c1c5eb3c851f513f8a760424a65002d87d6806cbedb0c2c364c98989815ee9081d132427943a0adb0da7197cc7430757f3868c49c045d39c8c085665d13bed825fd7cac7fc6933adf438a4cb6849b91a1c737d394c5e08649d88e9274009c4375a4fad4b164851540e43ac603ab6f488628fd7272bc1981ba03121c3a22e587ef30a793ba097d160025ec1b629a348fb8b854b54139d5b6af09a7515ac4ba457c8289108c7c316c069a8e454a8d1084504c2a4e03c0a321681d168933e0062bfe1635de39ec8c9aa2a5a48983c1bc34798fc64114c18ae77f13408f753da60cb892c52f811c8382b3c455c4c0f08248bf7278b9b4b927580a3e50930b7af9c04839b4bbd95e870a7289b5b2ab92fb339c847a9c22529ec61343537944ac07cc5a1ae713ca8fcba73daa688c9ca369e8b8d99fb812489482a727d40c7aaa6290f5032ab8fb5b09ae4985d7558b8c55b9f0accb3781b9b2405f11c05e99cb3723922d0da4963e68487631722c0cc643b3920b8c2ac34b54e77c1fc748c96c186b3a5439fa2b3b2e1a75b16357e2210da4b3fb620407c4cb78f18178f2b6c4706b619f18dc0863c72794434978d20933fc79193894041183660f0437a2e309eee87bf538a2b8c7672833820805bc2cbda61e8f04b7839b1493372759aaed528980e02726eba914491b7317099215135175c41986858fa31cfb689a865375e8547932899867b987167115031f5b4dd263f0341395e1176bff3a69fc9b9c020ac8515af5e665a15f48a3cba1c4a96390ad7795f7695e654279802c46275bab1e32fb7111619c55c8787cc01140f0fc03fcaf4b6df9877e0f24971f06749bb343e1a5faafb66a75b4888a1c63f593bbf3906c324083f737a39247ca110279a677736e77eefd3b08f645100e249461657da00b365a58beeb48de3f96b6797850119145975388ab4c9025215dd4b0a0ec066c8a7a593fc0a1ca921c3c54659d40fdfaaa4f63a6b0d55a761e9a57843617ad6963087396a0187bdf593d98009ba825d056bab8e3b6ad5eb31b3f195a2c9b7cf9281c176b58346cdc24c580f23131213a08c4cc1c776c146893e8cd44983bc01494793028225f2161f916b888c923c8c30c43c41c1a2d12f18a4918216771cb992ff1abdbb33aa5f363e6cc044a0d68e6b36785951566e4a666af6cf9d3222fa17566966c734a364ce14933da00305930b47dc1e977b88e328296461c302c35f3e432e5d01243685c176e1b6876b03e341ce0a1c52ef32966d67004cb4abad9cc8a534b728db8c32811f7e71556beb656d773759f04a71f43413805c1334385e396e8b128225929977f41cf776450460707e0c247980ac42c69cb641af3cb36724d5705af745965181312a91aa000b42b82670a9aea43ac26a5cb3ebfbbdafd4225535255609c3a7d04332e6c816fb68e5ac05daf42c95c78f6db76213a083b3237b4665b9ede88c1bf53b4473005d4627bee21cf225bd35eb728932543956ca142b4f3614816d891895b14f0d28ba36d298d6713809180621d1b12ebabcf032aac6691b22cb9013d8a8dfd70ba1281a77f237f9318b43d043f193cf9e1004cda26f532ababca3528c69200624b613fba988bccc73288b7996c2de008f22755ade918784f7ae2f69ace6e08e0cc528e3bcc85403967da02cf1463c77976555460bba2824af0923f2dc4336ab44d54ca0658417f8fb5755f397fca11e07759c5ba86accac1e30523349168ef3740f59ea90b1f7577ffac0f3f675fa85314ad49cdfb385b6a68d38752c435cce3cb9b176086019113ad638cf3426970de0013624313ff57ac82b1feb24195028b1b65bbcbd5c4ef3a60116125b3580743cca16ca9abe8fdc1ec1ca2e4d717a0eaca0fbcabf74034b74391d8d9668198a14e5491ec817701733be7ab11635e4a1e6910f3745a68035a76f35aa3b3b41e7eb581ce69142586dec698b675a1660b7c22dd1947bb24f1ebc8b22b1ad1b81600b545f74ca076e468513c0a483466089dc1cd7090c4c5623b02b7824d2ba1894c4e200222bf867911c89d3264b5a081d7441a2f3729cfe4106a780237e179839323f97c04979887c4c223f23a81af875a33cf28cbf75722ab92308c320d32625ec326734a532333c8b1ab4767bcb682850750620c402878103056cfab5417354bd395084f4f95ad375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14fdf4f164c11041dbe981d8ff2008757b7e694f564a298b92cd182129ade5e72bcfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +expected_public_key = 2e5317c2017a6ce707b079cb56a06e388b924e96254d26c853733b50520224bc51798578c4c53bc92552e8a42a07136992213a6763056a025106255f57e4670a6a4262445aa745a916a9b629ea64ac757186d136fe301c6226992129b493d0c2d635b5187cc2359cbbf235a90eb24f7feb5137e4157ee0822b0cc1761c18c25b18f757392863c24a13ce6dc84e3c28aafe018acc1b338a27746acb22f687af1e693df043625c63805ad42b9a368f13f19014b456c78236fff57c7de2b96e7a2223d00d9eb8973ab04c67f3b03e8cc1cecc7912033999101b37ec643605c0d70c1161a6cebc512380851f6a834de7631bbf47adea0bc17a6478f122c8be309804d2995541558d688b9e080c22bb3494f43c1b1a0c874bb4d5246688a2be22159a56151ac2e6385b1384d0c635ecc94b80bb8276f435a64883ecf51c43f066d481cdb5a21485380ca2874a38b39a691c12d983cdfee9530212439d154df71106e2854222454c20736f6daa41e9c949941205d84a7b5730b95cd3251c186dd97b1d4ec329521bbdb3394c819a984f87a7b3992d1d578b5e57ccc3ca151992395cc6695ecca7ab67806f2c2c0ef46a6bc02c2bfa17a8ec41caf87f48a146f2345b7a185baa1379880b00d0044f90e2a148186cbf474bab0330b8f029c72802f1b1698ab158e5c81343d34cb10255dbd1b9b6265d4c4a3b1905a650c29acf22ab6929a0d95357bc76983a201727b1a0f7c8464de2bc0da3a48a81b338a1855a759f764639d9e7306341a96b9aa52994bdad71ca3eba0cd695a701a0ca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d282b73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1ca0454a33bdee7aa80a2ac17fc709167843167208837594eb8a47ae1a38ce819c4ba7dc4521df532c0a6eaa5ccfc37e1f76e6ed20a1715139d9a41e2fb46cd5c0b3bea25f60a120222aa06e15504e4188116ade33507a26b927d10bed839577d2641b9550e1e921932185467b8c2856a430ed28275daa37b166e025073fa513a0c852091555b0e19a2c8e858c1584e229c6bd2bab500ec032abb4b8028b90e3b24feaa3fe2f826efb574a786c3bcba9829e49ba6318b2b24cca031c636c863f224619df40949b08ffee535a25c7187a92fb522376cb30d4fdc7ea9368594cc53921c857f7a1d9e9528a9cb817e423d25f791b4cb1e95e7b3e6dc406c83c9140385173073f7ac23d69c6aafaa6cf82862fe05a409521174328539b6a907f34d553aa77980c9f4959c329c563d8c03920b98563c5f13a0231eec58876210a5a78f1b43c1fb8b4490d18c16687065939535363ab88397e51760ac356c69f7b25458183a10a0310363f31c5c16f1898d06701824565a615ffc232f33513fae22b6bafa22177b142ff88190a207b4eb5edd4bab67185ab0c9b8acac2b37ac2108ab09f96461a3f079c3c018c6c058d2809f1346889e17cc488cb645c698ad3730084415647728c2116e013767b37bb513000feb359b84105bef19cc7dda7abcecafcbba381bb0727c8554bbac2d42c18bef471fce337e2fb99d69a9a54fb14a1bc6856dd56a020317c4a57e315cbbc371cd673a0b0919209f2361990068f0570b530b0678e01032ac6f95c2021651a1159b0b221545134c500d857c7ba0aab92cab5b5298c1b7b8ad588d0d53860f0563ad9c309a12a82b14486a10b79d7b6d38bbb03d9bb49db4c90610bcde5c383c418088f51eda6a99e386af8e1802d84b6d7f236104c2526d577adeaa8dd1c468d812cbdce44b04d64ad2938fc6495fc0a84e62e506ea548a8f5930c032b59e54aa54598f9653a118c5c83dd07f1b73061c02195436b6a66301bdc21953eba0e0e351e01605d9919956968601549abd9ccc9d284b3943c666cb8bf8c2112f52a5c733691fc2003c5b6eb8589d9594b8c92c4c4c6abc2e5b2bb67078f81849e5b6760cb1391b9c5a57f8705ea61f2cc475f1f3a45a2a0b12bb976b2874cbfb4f7266b6e1e20e6c2c490bab8daa779f0109be1a662c985016c483a71e636156186471a9ae452bb973ec28bc135133e9744cec8b330c0752451c6944b7a304a250595d86b394c6762d104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_private_key = 469963001d4d93da7cbaac0acdfc833c47601ae334dcc0022a9220138c16b9eca73ad1863431a34f593addca4f0ea393fc4595d22a7cadd0a8d89827086a955400abad84226541114cfcb3e3a240fb600dd6c0960a7976175c56b0b48c66721e13882e3aa5784e12869f0c8518037955f876997975d27a7c92d4cf005ab859590504c768b02576a94263c87c4bbfe1afb09b8c0a5c067776a0d96a5d12925b44ab3d3e57c6971b0a86617f65a16c7e9b42c283577219409e1ca4de08a92dc5b4e8e87051680c1b24068dda801fe871e0b28ab0611bbb97cd49bcbf159b7785830bc9d302c0a61ad138277afc2374aa64e983506bd11288f4a20376b50ae1c1233a1acf30af1da67301a5a420aa826db58322dc1c7ad8bfd25c3b21025b565c357b4a0802e615a35a384f1794a0612e030228a865a0390197e7c27f45a4258fe26082c850170cae86721bb5c68cb32153b9934de4cb11528c570af363925ab0fedac79748b3489b7180e81ff6db702d5a100336955ec02fd2b9c86c2cc001833b0ba1b7dbc9699c6556b448324d29b0f6a4028bf48a49b1cf60b4a9f91321aa64ca849848cee2be0a29219f783008417da307710f87cafa2603fd206e5698177e81470af4c608a6128908541183a5b4769e74166349e55b4d2a2a84600ef712c2d1f13f4fb3c91bca8cad209cb5ba0ff578bd6e29a0cf07a972d262a2ea3c4dd44a5d55446c174b345b96871076fcf785cca68545eb6be64bc9be17a7d5914d8a50b286d3a2a8e1a53faa53815acf0237b8bf204c34766e97883071e56539361bbdf29187c180414c83d9c09e30983995aa4850a6b2358aa6240642cb9b0fdb739fa5a93ec60c11061aa8b5e71316a517be2baea2f74baee32eeaa0a75d2030f5e8bbe1b517f56511fd8aa499621a9ef6c88b96a9f33b2b3cf04381b5c97b743063a6286751ad9ee14903c4674b308dd5e28bc700134c43c788b04460db78a0e795e24698553722b4c3a095784828960672cbcafc11af32c918ace0580d5bceaa574409854051a2419f148809147133866f9b651a38622f21e0614f10139ba53724831ff312157146169ea29293d2a3f1250ab9cc877d448ecb53139e6c5487dc2931d45b4a74c34bba11cbb965e1e664ecfca54db7bfe7e61db2382e50076a70a9aa028670a354013c894b729945830b1125aa53f4d352bff33fdbe7c64bf70a4c3acff3680976fb26368693d928122ed5707b453a1dd714fa9c5a8e6534d45b53a2ba464e217dc0461be31c5763715bb66b6f3a4c0e7a3a4cc107602cc3b67487a7d162422468b5cf33c8e5a63f801c2016b15c40398f914cbcdac9664b7601680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86408922fdc9650df7577e5a89215c8636d5c376f4596c329158964084200c91af4a7699018c6d139f521204bc521110aa222203774db88ac0ac94cb97720a71411eabee0b2863c35607a617e761298825acd91c73685198be96b84a98ac7295142f6c19bab0082c53a8a50a3a39eec2a34e859cfa2c88c9cbc77b1bdb5377981f61c1fc394d70820336baf21820d44c0956e09a5ef7786b8427a10ba0aed54573ca5245bfa751ef891e1072ab20a4f74795a3f296bc5e9587f272a9ffc71a878337f5149e7ac47a26532b2ba2cd848ad5e7a621ef3b0ac470ad0e64490f6463c0a6d091c1a1156771999697e576eb1155789555392da8d0f0cc364378274922b4d11a3013ac273db2e0606ccaff52048d30821093d5ceb0417a4347e5b178eb5b59d37c54cb911ac08cd5461b1a61567f4448288e78a3ed70c3af85c6bdb72d4bb6819bc1c5946bffee0974e91c56b47bdd7647990948834d463361c1919a977dc84506a0c13ec7a9da410cdf51a9fb67b867dfba51e029e6e99a35a0064a5f640a36b3e41c45d586804d9b5a8306674c037a587427af6160f7568518edb10e4d83e6fea21b23b20a1cc92d66c043b5328dbc9805d7c7d938066ac238c3461a2162624b75bafccf47f58065eef38207d22895e321a0adbb16d2001657a9f622849a0008ea88988359b508ccb764d265766d2b1e1f55fec412afd07a2c9a22729b8ce84ea770cf4612d369653ab92698c6358769d2e5317c2017a6ce707b079cb56a06e388b924e96254d26c853733b50520224bc51798578c4c53bc92552e8a42a07136992213a6763056a025106255f57e4670a6a4262445aa745a916a9b629ea64ac757186d136fe301c6226992129b493d0c2d635b5187cc2359cbbf235a90eb24f7feb5137e4157ee0822b0cc1761c18c25b18f757392863c24a13ce6dc84e3c28aafe018acc1b338a27746acb22f687af1e693df043625c63805ad42b9a368f13f19014b456c78236fff57c7de2b96e7a2223d00d9eb8973ab04c67f3b03e8cc1cecc7912033999101b37ec643605c0d70c1161a6cebc512380851f6a834de7631bbf47adea0bc17a6478f122c8be309804d2995541558d688b9e080c22bb3494f43c1b1a0c874bb4d5246688a2be22159a56151ac2e6385b1384d0c635ecc94b80bb8276f435a64883ecf51c43f066d481cdb5a21485380ca2874a38b39a691c12d983cdfee9530212439d154df71106e2854222454c20736f6daa41e9c949941205d84a7b5730b95cd3251c186dd97b1d4ec329521bbdb3394c819a984f87a7b3992d1d578b5e57ccc3ca151992395cc6695ecca7ab67806f2c2c0ef46a6bc02c2bfa17a8ec41caf87f48a146f2345b7a185baa1379880b00d0044f90e2a148186cbf474bab0330b8f029c72802f1b1698ab158e5c81343d34cb10255dbd1b9b6265d4c4a3b1905a650c29acf22ab6929a0d95357bc76983a201727b1a0f7c8464de2bc0da3a48a81b338a1855a759f764639d9e7306341a96b9aa52994bdad71ca3eba0cd695a701a0ca483ba6f16b64a9b59c68747a22086efc38b3344c32e67c66f47359d282b73428afead6cb07774bce87c27a5734e39895771cc490783f149865eb3cc37d8576c1ca0454a33bdee7aa80a2ac17fc709167843167208837594eb8a47ae1a38ce819c4ba7dc4521df532c0a6eaa5ccfc37e1f76e6ed20a1715139d9a41e2fb46cd5c0b3bea25f60a120222aa06e15504e4188116ade33507a26b927d10bed839577d2641b9550e1e921932185467b8c2856a430ed28275daa37b166e025073fa513a0c852091555b0e19a2c8e858c1584e229c6bd2bab500ec032abb4b8028b90e3b24feaa3fe2f826efb574a786c3bcba9829e49ba6318b2b24cca031c636c863f224619df40949b08ffee535a25c7187a92fb522376cb30d4fdc7ea9368594cc53921c857f7a1d9e9528a9cb817e423d25f791b4cb1e95e7b3e6dc406c83c9140385173073f7ac23d69c6aafaa6cf82862fe05a409521174328539b6a907f34d553aa77980c9f4959c329c563d8c03920b98563c5f13a0231eec58876210a5a78f1b43c1fb8b4490d18c16687065939535363ab88397e51760ac356c69f7b25458183a10a0310363f31c5c16f1898d06701824565a615ffc232f33513fae22b6bafa22177b142ff88190a207b4eb5edd4bab67185ab0c9b8acac2b37ac2108ab09f96461a3f079c3c018c6c058d2809f1346889e17cc488cb645c698ad3730084415647728c2116e013767b37bb513000feb359b84105bef19cc7dda7abcecafcbba381bb0727c8554bbac2d42c18bef471fce337e2fb99d69a9a54fb14a1bc6856dd56a020317c4a57e315cbbc371cd673a0b0919209f2361990068f0570b530b0678e01032ac6f95c2021651a1159b0b221545134c500d857c7ba0aab92cab5b5298c1b7b8ad588d0d53860f0563ad9c309a12a82b14486a10b79d7b6d38bbb03d9bb49db4c90610bcde5c383c418088f51eda6a99e386af8e1802d84b6d7f236104c2526d577adeaa8dd1c468d812cbdce44b04d64ad2938fc6495fc0a84e62e506ea548a8f5930c032b59e54aa54598f9653a118c5c83dd07f1b73061c02195436b6a66301bdc21953eba0e0e351e01605d9919956968601549abd9ccc9d284b3943c666cb8bf8c2112f52a5c733691fc2003c5b6eb8589d9594b8c92c4c4c6abc2e5b2bb67078f81849e5b6760cb1391b9c5a57f8705ea61f2cc475f1f3a45a2a0b12bb976b2874cbfb4f7266b6e1e20e6c2c490bab8daa779f0109be1a662c985016c483a71e636156186471a9ae452bb973ec28bc135133e9744cec8b330c0752451c6944b7a304a250595d86b394c6762d104a83936b5fa76b32d3aac91874b16304379133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4ced722667caf175df48a3a346ec7cb1bcc37d67d3137ff7b7c70a07f202893a3320a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +expected_public_key = e4783db3d78351b11b00e292ab5425ab7110a6847a7fba29c24241999ac07fa77b461841c12519e9388635513837dca2a51434bb03bc43e89e9b73362cfc5f05007428c6c96271674a574f64d51cb5793454590fe9d42728c5c51858b2c5554b143acce2e1a9a4238cc9b88b12670e884b743168c967574f1ed1b700c50ce9f84d32ab1cd1e85a3a31a324770ec851a2de70805497a27148cb66249f8ba7796c02cfd462823dc9020f997114ea758511b5daa832fb6b4d05e10fd9f53d0837a5eddc05add9aaf668b87af55516b63a82bc64146b21290763f46b00a6ec3cfd71c702a28719fcce1f1a2b7d124a4ec8703d63865964036a27274c806ea1ab9067e5bb6d1766faf4b58ed05cca5c6688a86a5f9216ca7187423cb9d453825404448cb7290a5bae8848c41ba4cad130894cb385f68916d3a5ab6eb045522ba80c1154671617afa25e15734c5e5051f1e3173562899873ba90d670d644ae4192351b108f8511c89dc2c1633516b0a850a0345d46465bd058999ed227c8cb8f02625f4f0570a72a77fb1171aa577eb0239bcc2cbd00c82ed1baa91992ae4283be56094be2bb4c9f0623fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf30b0900716416a152be54946aebbd7ab8cc2cf535321a57cda44cd34060f86ca496830a16652a88d069802c59f902cf08d91afca82bb5b3aae6b4af650a3d7f5a0cebc8ce63a2a7c7e07c5a0cc9b18ab56698087dc65b2a014b8e00af240397d8c00c7454380df1497293327b81cec6e43154e97b93d9695d21c807f621576835e5b79f42d777230c8dffd72cf41a05fbe51765280bc6d3928c1166a6838e33a40b81826be34685203c7041599c14a84d3df2a044540957141545b465f03579167cadd8a93d83a03f7911406bf613562bb6a9863e80d886709978cdb75037b36a60f073ffba561fd87f6fac17d04b3233f797e091221114c78e794b9a9073bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372767060ec6951809848ef7cffae9aadea314d57780599cc3e55a8b0b04810e5b3a2cd9cae6d729e4d994c4d296f2b07dfc97596f8aa4636c70863ca52020b1c21c074838a4ac0360f88154c8e8ad820c3778275b966a3568b36b3f44a50a019a8d588849cb39dd813d5ca8905460bcebf94efad35a3a2ca588eb4fdf999e778b24c41259f198c20b219aa6c1715090000f4407a7217ff5645f8483a408facfe24b368d9042eca9bc803b9d0712b21ee36047016e5559b5d9bb6e046a63ba32a9537380ea73a22b662ee892a62af4b2710a2920a36f1740bb55b36700426287329e4f3b63acc77d6f6a94411a2612316da5b612882605a930a000c18dfb6331f9005427d63bd5c66bb0b4c496b6071cfcc8df3c4b350bb252d920b9ab3f73392b3a6682eb222c0fb065977b93c8d133fc07249f6a0a47d19fd8702f6c618d2c170dba4c65317c1d0bb188a09c9c4e97212ff004d9477fc36c1a25f3c725a7982146c4f3d20b0b07356fc8bd18289f860bb8834078d7d4813da9bcc2d3746f0b9387600088f277f9f747a9862be9a851cae219257b190c91c17c910dd8315a107967fc619c20093ddd6532b6a096838b1be3263f314c42a8f4b8b71586dfa279550ca54d87a1bd46b8d9c75861080294e9a084f3970d217610299aa8fc5814611a40bc01d8d60ab7878ec5c0460b916dcc183f826888d0a03a89dc3e27569b2a7a461ad847af7286af11a7c7a07ed8c3aa76b209d98c7aa72a5c3049be14f723c2062fca960c28925e6521534f855f3fec4054f3224851137ad18c4ef959e47c8134c86356f09b82606a69116b5d572a7c40a6a300b689721d37e80148821aa74902c0c30331664a65976c29e80034c00447245fef8a3a3dac44824b210a3b04f3b7af5a824632fcc5ebb45948ec3cb971607ee94ffca362ca60cd6e895c9aa0ce699570bcc4cab9832638c2269dd9b43f880d4f507768e4986d85814929afe4801008103900230956193e7262a0af2a6036f4cb85c581a5d1256cf78c1657598bf1c45f3048f3fcb0a37ab971d30f7f124e7662b171a5070bb14a750b26af9b020a929fd7b2b244d5945e58b5bb64b2f60b7296491d0ac31bc6a046c7aa3a1738b8563c234d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_private_key = 3c14bdd913cda0f267abaa8b0a30a5eaa527638c01926623b0bc2ba55b0b596a92bad72e92845828e8050f4c2f40873918e4524cea8505208d345783f71202496721e361a582c5445fa31fb662a64941abf9fc203ab4a741c9214c1b80b4ca617c4976c819794f53cacdb3509978a6df5900016278388234cc1a09b804679f36718255b2db60a7eee5bc3bc78bceea8060354b54031c4c76b30a1a8b1ebb697ff8606ce408fba72dbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895be01ed5c23a0d22707d89467a5b9c662767a0d77d5c49adca983ce7401f34526dab1cb9fe744bde8c54c230705548b9ed00b9f4ea055466cde77019324c0a7c9ba404b641a6530ae64a964ea47e6e80aaa4652c9a8b66061103f385479e50a780249a909c92b7913329a478880162d8857d58fa39d3283f5a2a7f8ff6abffe2463db40728d06166627e9c92283fa57a2e46190ab869b6c21fbeac86911284153b259bd2a442070d1cc581fdd333e5990f84ac67f47491df01128f0959ada0891c236e0aca87755289c0e6c8fb136974c97dbb1b8871a4c70aa001fc950f0cbb3ace4ac44f800252f5bd76fc1dc09a3d2f8860385a4bf8d765b49c5379140e0a2801dac947c23803ab6b467f2bb1b019b9d53771418312f51b28db18be216794a0467d79ac8abaf2c90f4b1b3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935dd429bf8319bc0b8199cca9d3f78c483b8e0771622ea764fa610ee13c1a188c56d0b5c17094c1b7a45321bb69d99a666a7963268a1d0a0491b8b5cb700a7d86ab9039330edd8bb17cf1ac79355a82166458d2323e070ac109c98d201358f22bf9a3b513b8bba43905d1a790a7b1a11f682583ab4fe0a82f3e316b7c70afdd823c8fb7acfd330b22f378e8597ca5357454a71197cb4039e9a81d7995d14587b479657584407b281886d6a7fe9b6170a056d2003bf898027c275b7c1c3d1d0c157145ba52d264699b969d60aa3873a9606041c20b17c90055b8016ea703539638cff8aa0a219542bf51b68cf153a86149881c087d898ef9c3a089cc70a8656117131aa3f233c73cbf439022d224422920501c07243432aeb925c4023185d3f897a79a983d857c6d1422f9b22234005e00882f77c7704cc74adea4c8f3971e7964ba1a530c1f722ef696828c46946f0b329d909a47b83353330630359eb8e9b7e78abc50fca8c3aa9af967c89f464430c815d1959a21a226a966a6434301fa600a4d129886826803ec49a54a34acd62b50e33fd782937571816421341cd76a3570c17ac9c338e4ac4c51077650b98ae445d236904da694f755c1a5b288275b517b4c9b896c49bbc18933e52d34969b6ad8add604b526488c6397842a54b6657b93386b0ed7d36fd2f448efe43b0a144c33f729df530c8b6340cd61897b3c50b0d8ba81228604f7a4bcd120cd2a7bbba3b4818177c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d93589021251d14c920328c4063c2af3c8c41228355527adf41037e1ac6aa69a427a55354ca9d54025306c16f93154776b4a7af9c9ef2298dba9b669c40bd0601abd410357b8940511beb6c96543d121535437d8eb5fa6a6414860ac4e849f5fcb09104a68ba7987f52bc859dc9025450332b28f3959ca78f18cba09c3c4522d365c93cd4756b780a9ab87a040b8202c2cb7ac3c880796775feb4ee8e5228ef4c62bc93e5d068226701d244348f3665941f59415c6275e1656fe68487f3500739762d13ba5d3ec27c5f77b7703a1b2e645b05782e5a21952584a323282df23c8a9695c0b537ac9d6bb4e7907ea4bc2cdd684ad647ce10b326585a0f7e486a4bc15418454ce4baf62b81131c0008d54cf9a6abd94e212c0193c724a54f8c12b4ef6b6ddebcf678ac0fd84cbca17284a326b7edb071f9c2a3df66334e29d588b94d684474261b3f8fc6bfc7a9328b7b91bf2023f088337b331b0c143cb86549264bede51c9bed644796b53d3f230327b14c7d699332457e90a5d40a053309403b263a59d7cc6e56b3e87592735d95e3aa819c41182dd9c0972592fcb2caa046883e491bfb4c34c87b995f143ba5f7c51dcc45c5dba619822102d005eda5ac7d4b02b05b8c53f1c79df7a92a9d4cae4783db3d78351b11b00e292ab5425ab7110a6847a7fba29c24241999ac07fa77b461841c12519e9388635513837dca2a51434bb03bc43e89e9b73362cfc5f05007428c6c96271674a574f64d51cb5793454590fe9d42728c5c51858b2c5554b143acce2e1a9a4238cc9b88b12670e884b743168c967574f1ed1b700c50ce9f84d32ab1cd1e85a3a31a324770ec851a2de70805497a27148cb66249f8ba7796c02cfd462823dc9020f997114ea758511b5daa832fb6b4d05e10fd9f53d0837a5eddc05add9aaf668b87af55516b63a82bc64146b21290763f46b00a6ec3cfd71c702a28719fcce1f1a2b7d124a4ec8703d63865964036a27274c806ea1ab9067e5bb6d1766faf4b58ed05cca5c6688a86a5f9216ca7187423cb9d453825404448cb7290a5bae8848c41ba4cad130894cb385f68916d3a5ab6eb045522ba80c1154671617afa25e15734c5e5051f1e3173562899873ba90d670d644ae4192351b108f8511c89dc2c1633516b0a850a0345d46465bd058999ed227c8cb8f02625f4f0570a72a77fb1171aa577eb0239bcc2cbd00c82ed1baa91992ae4283be56094be2bb4c9f0623fc53a9d1853afa9990d1998b1e7459dfc3c57db5abf30b0900716416a152be54946aebbd7ab8cc2cf535321a57cda44cd34060f86ca496830a16652a88d069802c59f902cf08d91afca82bb5b3aae6b4af650a3d7f5a0cebc8ce63a2a7c7e07c5a0cc9b18ab56698087dc65b2a014b8e00af240397d8c00c7454380df1497293327b81cec6e43154e97b93d9695d21c807f621576835e5b79f42d777230c8dffd72cf41a05fbe51765280bc6d3928c1166a6838e33a40b81826be34685203c7041599c14a84d3df2a044540957141545b465f03579167cadd8a93d83a03f7911406bf613562bb6a9863e80d886709978cdb75037b36a60f073ffba561fd87f6fac17d04b3233f797e091221114c78e794b9a9073bd0a66822aa3aaa4ba8104994de5718a44ae76aa7a8eb59c1f8c59ea9cc32724372767060ec6951809848ef7cffae9aadea314d57780599cc3e55a8b0b04810e5b3a2cd9cae6d729e4d994c4d296f2b07dfc97596f8aa4636c70863ca52020b1c21c074838a4ac0360f88154c8e8ad820c3778275b966a3568b36b3f44a50a019a8d588849cb39dd813d5ca8905460bcebf94efad35a3a2ca588eb4fdf999e778b24c41259f198c20b219aa6c1715090000f4407a7217ff5645f8483a408facfe24b368d9042eca9bc803b9d0712b21ee36047016e5559b5d9bb6e046a63ba32a9537380ea73a22b662ee892a62af4b2710a2920a36f1740bb55b36700426287329e4f3b63acc77d6f6a94411a2612316da5b612882605a930a000c18dfb6331f9005427d63bd5c66bb0b4c496b6071cfcc8df3c4b350bb252d920b9ab3f73392b3a6682eb222c0fb065977b93c8d133fc07249f6a0a47d19fd8702f6c618d2c170dba4c65317c1d0bb188a09c9c4e97212ff004d9477fc36c1a25f3c725a7982146c4f3d20b0b07356fc8bd18289f860bb8834078d7d4813da9bcc2d3746f0b9387600088f277f9f747a9862be9a851cae219257b190c91c17c910dd8315a107967fc619c20093ddd6532b6a096838b1be3263f314c42a8f4b8b71586dfa279550ca54d87a1bd46b8d9c75861080294e9a084f3970d217610299aa8fc5814611a40bc01d8d60ab7878ec5c0460b916dcc183f826888d0a03a89dc3e27569b2a7a461ad847af7286af11a7c7a07ed8c3aa76b209d98c7aa72a5c3049be14f723c2062fca960c28925e6521534f855f3fec4054f3224851137ad18c4ef959e47c8134c86356f09b82606a69116b5d572a7c40a6a300b689721d37e80148821aa74902c0c30331664a65976c29e80034c00447245fef8a3a3dac44824b210a3b04f3b7af5a824632fcc5ebb45948ec3cb971607ee94ffca362ca60cd6e895c9aa0ce699570bcc4cab9832638c2269dd9b43f880d4f507768e4986d85814929afe4801008103900230956193e7262a0af2a6036f4cb85c581a5d1256cf78c1657598bf1c45f3048f3fcb0a37ab971d30f7f124e7662b171a5070bb14a750b26af9b020a929fd7b2b244d5945e58b5bb64b2f60b7296491d0ac31bc6a046c7aa3a1738b8563c234d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d14550c4dc82d723965476a518ea0915c1554bcc61c814c80ff120c37e7e8ed6d5c407b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +expected_public_key = 44bb41c301705ee232e0a6bdc2e4c6bc55958859a5afd2b82f502e88a746a20179fcd60fe0276affa12828129543471c7c620fbab41db49173ae4a144eca173b23899a99785a25148e6c92e6b5b3222ca7eb3bcddf6508c4b19a039143b9d87aafc77ae80627cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861d950256484802a7b479b67a803fba87d916d0918bde0973ba3f2c0228c0dedd302c6fbc9366c4eb708234592cae1f3c58499cd177621731738f0d8573b53018ce88676ecaace719063910aa3d08b13a2ca2e64afabd52a309b2e0a849f3537109518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98aac23f489b85a9b18245649e8ec3bb8397c4125864d8695752e942437b315b7286675279df55cde5d20aefab94b1015030c40de0735472e02aec59027c8caf0074b0fff4bfa12267a3a5bc6a380632436041cac792330a4ed585379114b641bac7ccaa534a3863b52390d2173e4474299c8e1a2571bfe215c71b1d23c14368926a2d0944a1f20bbc536c84b7c8218b3937946cb227134e35c36f81c73d6433d4492cbe9bb1631787376115f6f9c3e5b76e83812494719b60231dcc4182c3e8a3e21122106b9036c62755531b6c5572cda5647746b9fe64286d395cfb759caf4136466937b70146cb99010af4088aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cb907022bcc72617cfb7bcce57988ca4c3d60e94d12c34588f173473a5d0929b5bcb09cd8f91534e7bea694576638889fb29c2074058900587fd8889c89593cb5186fba07bc103f4196a7063ba5c4229170f8830e254862457adeca7219f73f201130719b39e0b84845709f2cac7adfb60b26658ea9137a940b1ad8ca7966dc1c0e540eff9999822b5e69f58133902ad3704345914e17a30a96d6a879e320ccdb91f9f7c68f683c00532449f5420e8444e4c01df8b203e38327e566130c164d91bb14bec93b6eb4419a22c744fa9d92e861ae7bb13862288030551aa43bc4f809817675290a2413e71c9d29578df619be496061f7307248ba88d9a322648f969a2fbe005d9f895264887898cc0a8b35cfd0ab7afc594c9771536677571b9188d3b5411ae450a5a75e6dfacd813ca905b13f0a52153d0793c908b2d641b00c3a483293399d0b1579e28f240393e13c86e0121f1dba46fbfc9a5d062c1ef670e01c4b6b7a809470ad15f725b80849a0ac6f5370c1c96a309ff964dd1a9db2016b189a61311cc82dd652328596d6a2aab35a8020094ff7438064a7801a050090a18e9e4c2b33c14cd1f97b518ac9f4eb9a1156c816e6ce01d6053481b57b1787bb925faf531fdcba1be23570dccac4312c148e7833162c6219835ce3da23b1d149e434928f810577c37d0340b6bbb45945d789f6cca8fd5226a3c066595399ee696fbe2025701669454a83e3162535d51b11216affa7bf5c62a62d696d4532954791ab088ba84208a7dfe76b33861ba6d6b51dd322005700b38c8e4973c934e12c374c3c86c099fb42b2dad468a8701417e2b5e902b674b759a0f8366a3c00be49b43c39a016288a1282c9673c1204a73fe2b45e90aa2732a46abf8496cab31c52066052684d078c1926d374da041bee98939b4a597b2166451801cf89cac513a3d0890c3163150a54734b7960bf5701f837af59e9a4c631ca49768829ecc6d23122be873234d825209400c883cb47db7b60b1b1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342a4198366a8bdaccdab8349f9b9aef229ce46d4818bf188338aab48420b9abc13eeb990ea41ccca136fe6a3c3827bb40c33c1c749620db32dbd773043302b8b2b52de82910ba96ee430283fd51f17c38bd1734b4aa353345777ffac17797683ad603cde78c51dc45403e97514015fee950215b7366d76b29980c79ef727622919b59931e9a78ff6977d9e49c8da013a2920827a21988a713e8a378c3db9c90b8a2703e2961b246a5d867dd98692cb60093d617fd9493edee2820bb081b2b1c3c9e6941817b408255a0cd09eb8aa43c7d298954b2a92250aac1864d1086fd7338ade31a36f756425303a51bc1ac7f920a69273aa11b7f077000f9ba015035dfb96159d28282bd9960290b9fc51a79be9888d737329801428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_private_key = 2d149d32c41889573ccb5166c597c3fe207cb806bd13a8a7bdf86267a93da7110a31f22221a17a5381c367eb1b9cd00810189c1f12358b59adbff2060ed6ac6712c660b51b553402d406bcc1d2444a863b6ff261e17aafffd01baa2b05cd83050ab460ced09bc7c0c2963784b7f9798d837bbc0483001539f0ea65a0574b46785645019b25130095725fb71556add2832ea245e250973f504dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ee31e0fe931d16cc9da767c3a48bad09874f7730fa74c349d2163638aadfb59a462e904c5530a0b485541e391b6037041ec6a0560563f186be2ab97a42520a7daceabf1216e16870437cf012a6b6d082bbb23349628af4dd8ca9ea986498a80edfcc2418c3f5a627ba8baadf3739b3c578b2f193f57b72dc2827a2dc379aa31b6127c65352338c012cfcce0af1b33150d488cf47134e06b5ebaf0432c172090fa6671670bf7b66002e135e7c43d938343d5729e22e5597a06209e0793e65417de945b5e1aaeb2740fb1b350c902c1390a97586564fa94120cf7538b21aacc0ac0831b477e37c9e984b73ec91ed88705ef4cafd2f15a50227c0e4c0627d2a6d7875e9605afec339799690bb6f0a5b01141a6976fd51aa7a079827d37ca89726686ba95d6f275a59341fa229b4c163c260c4dbc4587c50ab8f0ac777849b5f700209f17c15251854c35aa23c20d486122ec8145565966f4a067251b96461950ac2171f1996e94517610338b88c091c356804cc691922449db0645a404ae4a641d1482b58e6230c7965c23605d66e96c8f0418ad786801d7530cfa2b5b757e06abc10518b274e3992e538922b717866c7eef827d2bb4c05ffa3322981cd8069dfe028d878a8b7a002472d302253a83ab84adf5530cc5f4671bf5219fe600ba97abd2555c52857abb76ccf4760adb30346c55aa5340b189e1968f72999e64c0b76297d232412b3c9384783457b83309ba7ef74abd50d16ea1c32a2362aaebd02da7790fb8827ff368261cec14f3a2095323502446703783ca9b6aa595d690031297c59b25414455c155924a47896716ac45330ce7069d131b75a57769fd4b4ca1990170a3570160cdbef1c930063d56e3546f09b1cd913c82057c0bb89111e6b1bba88eb8cbcd72078fcbf5059fe25c84bb5607d7b20bd0733fd96dbae2abd9531ddbe3cdd89a926361bb56ea0e5f9181b2c8c1532312f3f9005135c07dc211b824b1e63ac96e64845c35c41e0313511a5d429663796abf2443908d353766d40f47a910fd04a710ba5d6a5b301832a5b6016338d8858b220e8219512b643b8b60ca2a9347ec39638b787fdb44ce72408dcd2504de24af91130abc09b2e7c9bb26b3393ee06fd77019ed3466e019ac92a416c9683da22cafb1a9ad3475af17a15ee9f97446096647578f77fa02e79904fcc008fe509425446ca2a4c1dff32cdfa4ce120230bb5cc9cb49a2e2841bf69a1c49a762ec171698ca0445201c485a15fef2562eacabad3259119c9ba4185677e03aa0470ca848709c4ba0c8e5814416c5678033c819773db36e7a90c65fa82ffdf6921c38285122163bc0744de5c5363c9a973428a6daad20e5a62d37017b464da7637d9d26c6ffc2b5f17610072c7e1ce668cfd97c29eb597ef51c039015e4b35a7d049db6488e271851d20cb61655cea5a074338a722a10a7f77b5bfa0c8bc41b346bc5ba4bd17784b166dd83a6a5066e0724af7b603d4cb3a880f95040d53b9f11ced9fa55b1771900e8924fd7656ae198b392bf23a83418519e3c754203a9035c83903df9176004be81aa0cfe690297d67cc3432f815c4db7dc5797a2cb99140e28e880097a0f45415ba730b616572c2316895e7c0d11073c4ba5a6ddc74f59206deb3917e84a9d8ec6c63fc83a001da56b03bdf9c077be63645331596bb962845594907a22f8a85b084aa80eec51b4f27e1af011464cc73f6615397c22833ca5b81cb30df1982a18bf148a9d3fa5c6a46c323ca1b5a1fc4392a2204379bcaa3a63ff679f3ecc00930052ed80c965a82e55c08389d284d4060254a42f87c6aee7211933e2c6678caa453b8c006a94960b0de5192631f9ae68811d5b729eaeb1c0cc8aaccaf180fdc09792da38e194358124b7e87b7f55181689b3c5537011bdfc9e44bb41c301705ee232e0a6bdc2e4c6bc55958859a5afd2b82f502e88a746a20179fcd60fe0276affa12828129543471c7c620fbab41db49173ae4a144eca173b23899a99785a25148e6c92e6b5b3222ca7eb3bcddf6508c4b19a039143b9d87aafc77ae80627cb0b96e2b849e86aba25f74b93a43fb21cc5c4e861d950256484802a7b479b67a803fba87d916d0918bde0973ba3f2c0228c0dedd302c6fbc9366c4eb708234592cae1f3c58499cd177621731738f0d8573b53018ce88676ecaace719063910aa3d08b13a2ca2e64afabd52a309b2e0a849f3537109518ca4094ad4be6628e3c4a713c59f8778bae05cbeffa3e095b98aac23f489b85a9b18245649e8ec3bb8397c4125864d8695752e942437b315b7286675279df55cde5d20aefab94b1015030c40de0735472e02aec59027c8caf0074b0fff4bfa12267a3a5bc6a380632436041cac792330a4ed585379114b641bac7ccaa534a3863b52390d2173e4474299c8e1a2571bfe215c71b1d23c14368926a2d0944a1f20bbc536c84b7c8218b3937946cb227134e35c36f81c73d6433d4492cbe9bb1631787376115f6f9c3e5b76e83812494719b60231dcc4182c3e8a3e21122106b9036c62755531b6c5572cda5647746b9fe64286d395cfb759caf4136466937b70146cb99010af4088aaab16b6579733843f02766f19cabc7c6aca7e44e7265823cb907022bcc72617cfb7bcce57988ca4c3d60e94d12c34588f173473a5d0929b5bcb09cd8f91534e7bea694576638889fb29c2074058900587fd8889c89593cb5186fba07bc103f4196a7063ba5c4229170f8830e254862457adeca7219f73f201130719b39e0b84845709f2cac7adfb60b26658ea9137a940b1ad8ca7966dc1c0e540eff9999822b5e69f58133902ad3704345914e17a30a96d6a879e320ccdb91f9f7c68f683c00532449f5420e8444e4c01df8b203e38327e566130c164d91bb14bec93b6eb4419a22c744fa9d92e861ae7bb13862288030551aa43bc4f809817675290a2413e71c9d29578df619be496061f7307248ba88d9a322648f969a2fbe005d9f895264887898cc0a8b35cfd0ab7afc594c9771536677571b9188d3b5411ae450a5a75e6dfacd813ca905b13f0a52153d0793c908b2d641b00c3a483293399d0b1579e28f240393e13c86e0121f1dba46fbfc9a5d062c1ef670e01c4b6b7a809470ad15f725b80849a0ac6f5370c1c96a309ff964dd1a9db2016b189a61311cc82dd652328596d6a2aab35a8020094ff7438064a7801a050090a18e9e4c2b33c14cd1f97b518ac9f4eb9a1156c816e6ce01d6053481b57b1787bb925faf531fdcba1be23570dccac4312c148e7833162c6219835ce3da23b1d149e434928f810577c37d0340b6bbb45945d789f6cca8fd5226a3c066595399ee696fbe2025701669454a83e3162535d51b11216affa7bf5c62a62d696d4532954791ab088ba84208a7dfe76b33861ba6d6b51dd322005700b38c8e4973c934e12c374c3c86c099fb42b2dad468a8701417e2b5e902b674b759a0f8366a3c00be49b43c39a016288a1282c9673c1204a73fe2b45e90aa2732a46abf8496cab31c52066052684d078c1926d374da041bee98939b4a597b2166451801cf89cac513a3d0890c3163150a54734b7960bf5701f837af59e9a4c631ca49768829ecc6d23122be873234d825209400c883cb47db7b60b1b1fda95b0076b6ccf97ba855ae9ac8a9e9fbbec589c342a4198366a8bdaccdab8349f9b9aef229ce46d4818bf188338aab48420b9abc13eeb990ea41ccca136fe6a3c3827bb40c33c1c749620db32dbd773043302b8b2b52de82910ba96ee430283fd51f17c38bd1734b4aa353345777ffac17797683ad603cde78c51dc45403e97514015fee950215b7366d76b29980c79ef727622919b59931e9a78ff6977d9e49c8da013a2920827a21988a713e8a378c3db9c90b8a2703e2961b246a5d867dd98692cb60093d617fd9493edee2820bb081b2b1c3c9e6941817b408255a0cd09eb8aa43c7d298954b2a92250aac1864d1086fd7338ade31a36f756425303a51bc1ac7f920a69273aa11b7f077000f9ba015035dfb96159d28282bd9960290b9fc51a79be9888d737329801428564cdc7c4940531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2c934c11e2eaa7c3c4e764863e436ff12fc9f517c79df6344ab98611f57fe7296f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +expected_public_key = c6e762e6e2c322cb783f069a7e5594cd26a0914b3104b87318d0489a63ab263c88d561a4c8fb9a77c72ec2b917f685333c61989a4b3995d74589300688d2512943ae79335dbfb0c52cd14b16c085d510918696087d2ac47437c0294b8626a65f1e373d19a0107de053219a22bd0907ba19b4e7326f765989ea61174151356f04585cb89ba8d05a99808283b550c8a3816eba213362b5cec5773e152d14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43ea22074bf46f252a125d3740066509c48ccc347abdaf436153911dafd114555964c49ba9e2605213dc8a71a05e37b305f922a4e9a3b31e973e19b161bc4295d290535dbb8b6b359855d811614c14a408c34926be2700418139998e356acd5b85281b61b0c78733b0aee5a1ca99b56737c669d535b276c5546aa72673c5344fcc7923f69a0ada7096d75e81e32e0a8644ad73a4e7d19b3be97ea3d773be842597761818275cbb8aaca1206fa41686613986ddf37949842ba1741e812217593815c82ca7b583513938931b0bc829aa55d85a32b6822013244f2a3bce15791620e6cbc96b8555d0c77705c7cf996292cb5592e490d6243bfadac9dad7270a125e14faa8f8b321cc6c9e3b2407000340702a4c97a0189febc47e5baf51cc060af7cbf48642d46911e0889eace6bff53ca189a1036ba94912582b0f8b679a3b6ebdb31b7bba4f9c4c349052c4b9352d45e68463c865ab331884982c05f3a1fd78081d946a71d984887041a0e894f6995501233363027a3b7c321dc4a21d8463c9369abec4826f0906039a1a83cb59cac584d7c6426c91767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444dd52b236d4cd2c26cfe39c1cc8321cf7156867b37f85188abea7a040400dbf4830ed1835b2d47a6b8991451a7889020ead45451f46623002b31839c556a22382130b7689cc92cab281b164dd237357a195f4688f8f385f8f45a32432bc238a0c7f78324bd5b9e73aace5391d60f28ddef61e4e2c493c136b74229edda96c22f70f54435c6240747d963e576b2aeab0bff2009ba0f34b65c2a35b72477f36c914d048545c513ad61f964829a78bcccec39d2db38496a209afd760f1a51654d3125dd42c3ee13353f93e0114469c2abdf879050cd9466b4606241158a60b35ffe1a8956815419b9fe843913d22b93c7283805ba3098a52bc16bfd9b27c29155a22c99eda56530a69964466065ccaa447b13c4c8115adcc6285d947aaea1378a76e163556c18459b1ac905abc9b39e21e12486a5e56a228395093b150fd550feafab094602672860e5c74240ac705f25903e70667968435a4dc3e24dbc77e9806ee94436ce00b11bac776b46bd85a94634c1a3bf91e53781f03318aed41011a390f48e5b7e2866d11783c7b959882821fd4745a2fb3bf1e87756008ba1103a508a584a3290a4aa4783f10a9e62a73f11a0d18f9b8e3a608a58317f3d3909a5a622bbbb09b52350a7a681e2a63f02504aec572328155f67100b6331f38835fd56361fee46b903ccb020a2998d651bd2cc022f1b4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f43259025724ac0a05e9de54257859858685cd602bdedc01047fb903416a2e2d770aabcce2460903feb40274354b2e705111124887b331cba10673c0d2aca027a2c6ccb95c701568c20346ec747a29de09ff6311fc172910e41031b95330e240ebee2026048047e03c6de9a293f501604d3c7ce57a715db0aa91a6151230731e02f467477d04a5aad9b2b8176a1f056c3140bb1454cc7ffe380cf97139f4800fc4b740a22520a3b2a8730caf5e7580352b936ab9eafe3cbebaa87fdc771b0d704e455b8153c4b6cdc780ec415ac7326be810c63669a7f30a138a187108880b5ab97265a2158f542c37828c80b4bffb474ac27c6513bc54f0897ccd9948dd3c78f60c4cae733aca6caf41b9ca8052f25e58e78526ac8eb30afa960a04a322c582e5ebb286accc225a187a074877c21329856343c587e7ab6b09c3427091655f34127e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860ca17a63d0b154c9941d9c219c0a7c982114fc0c85483639a0f047a217a148346fc844c44f37270e775c5ca414ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_private_key = 85b01a4a587bae308d39792b47f71997fc55fdc2746f881ddf7bc215145c56d399c6447ada39230866384bb718ada160a7349747867cf695cccdb8a4f1fbb3e573ade85ccf38924f36482bacb9798d481521a0cae103cc9fc9675184490f281d3516cbee910287758a4c374c0a4313f1c29251b1655522936dc329f540a1fd887f0c775823436df736c367aa3013341e66854fb39a9eb90b23caec3e84690ad531141f39914a77a767a47b60f2868cf11311aac9da94c72e9624d21814cdc99c89a4b35e1c4c63cbb3edea06888162e180503cfc6616b24d270601d0d275c03109dd9486220b66d523a8111b4de5b99d236586a09a4f77a240cacb4a737c770bc4915f55b609075ee68499654baf90622647052a8369872a93114c80c60fca1345e20114552119669a0d3a7188d3326017ce92112f0b715c26b40851683478e5c719c11088f00aac577f5a8763d4a76e3cd00cd9061f021672847ba0d4785ea7b1b28fa364e64c4fb7f718d2352b1fc26858b6552419a4d8e1b22f8c7992e3b5373183d040948777c356d514fdfb2d0c5a636bc5416a799270e5c975c0a62f3a76fb134646b333b75582f7f2c51cf4bd37835c3fdb2ce1ea86306362f8216d27e40ca43a45edc9554f08c604624659aa10ebd29e59a60f7bd66eee447f4398addc73387579148bc4a26b6749c961926fd34296db3044cb0d2d1312ca6a6755ec48c46865a36a6330a9aa5d39167c6062ef1a7c82ca5c0ac1b163b85e43c278312c4304aa127d66576e7218c2d0c850108076109919ac6931264dc2e919ff441875e607a97772feb45f14881fbcb37b4d00b45f416cf56c9501c6598ff9425249740eacca49d92e31d679a4f16c3ccb4384db45e47621719c6c585ccc03355216d43625c08760254ae3cc4aeb1287cd5c3f0911641b05c7036c9bb360c72902325830bd25eacb5a88abdc926e0f205ee857aa66c8c47e434d8bb4a6cfabbd8b681c427846f0e18a2762152b170063b489a3e6b8ba06b00f14a3f2e6ac00725e5724cb629b7a312b3a1221c9460917c07637b71050bb644a38a8192270c857d43ea9304495206bf62b1c4c11b04a817aaa996b2a266ceb8a80aa46674f16207b61bfb484af461b6dad9a9e6c22c56f81bb355a6705310e921239497809012159e78a8a249796c155a9dc7cbfe7384dd092239c29773f6610e536a77b879eef054c5e539a381043c1b53d69566a96d1931b166c6f066cf0ec81e7492a200876d42007724ac916460a1266ab77a327ef1282479685bc43a2718c93a806c3de3a0cb918c7a734cb04759341c5b1496679987aa5db93b70f903a5f4024c3da6fe8bb2ebc27182e1179611c61f8f6214069ab83c7165a46caa74bbce0897fabea9b6b58cd34e7535b0297b4359960d23e4a498cf7610601d92af2fb6163c4b2761615121b62a7900b08d61065c83a69d51253d48399fc665962ad36275ed3774f114a079f13b8bce420b44638cfa6ce6018b58bea422a8287a6680eb21c75456592e8b24cb6c26ec3d3c1dc4a19ca16888e9b7fea1a863b7a0143307530b533269a8b692cb4522ac1aa27b01d38603fd009e1c02017bbb36da2049a2c5045a63081266d69d88eff7c2147ac956a33b4c198c1eab2ab93c592bb5137f291824c08258cd0b0bc4855a6b83b81858ee7b4beafa59cf7e4a03675113131251ff512c50aa885878d0c086d7461677bb81e46e4790c30a9a7ac4e0b3b600f04ad6381424a4b430b0a4db2387703f77c4a0c51072bbda954b473f86ad2aa1a5b926d18e0b0c25261502ab2d31ab5e837675b369880a2786389c9ff0ba07f1098e56c3c92557f3ee934573901d0168b3e35c4610385c324579686571a051d4852257ad329fdc85178438014fb365a11cd6a40b41ae8caa46a6eeaec1b264b8cdb2c040e928ec3829f3a7025c66525e937874e09c7fac652ab059a5017698d7c0123cb6dc889b4c3942a6e834d029673955a521318b930fa4553f46058922b57831e947015aa0052b4514deca02213e3171d7063bab2305a3a173ff68a1d46106f1aaa3967bef778af01c84450daa35b06801c5121425869d61213bd4b44667b7c21541103cb1f24b8a472e55e468b8a6cec630314673c8aa12fbc135b79498480721180c3dd1b72c6e762e6e2c322cb783f069a7e5594cd26a0914b3104b87318d0489a63ab263c88d561a4c8fb9a77c72ec2b917f685333c61989a4b3995d74589300688d2512943ae79335dbfb0c52cd14b16c085d510918696087d2ac47437c0294b8626a65f1e373d19a0107de053219a22bd0907ba19b4e7326f765989ea61174151356f04585cb89ba8d05a99808283b550c8a3816eba213362b5cec5773e152d14d83563dbb57ec89eab558c6365bc5ebc577ea46c6b39c3c76b43ea22074bf46f252a125d3740066509c48ccc347abdaf436153911dafd114555964c49ba9e2605213dc8a71a05e37b305f922a4e9a3b31e973e19b161bc4295d290535dbb8b6b359855d811614c14a408c34926be2700418139998e356acd5b85281b61b0c78733b0aee5a1ca99b56737c669d535b276c5546aa72673c5344fcc7923f69a0ada7096d75e81e32e0a8644ad73a4e7d19b3be97ea3d773be842597761818275cbb8aaca1206fa41686613986ddf37949842ba1741e812217593815c82ca7b583513938931b0bc829aa55d85a32b6822013244f2a3bce15791620e6cbc96b8555d0c77705c7cf996292cb5592e490d6243bfadac9dad7270a125e14faa8f8b321cc6c9e3b2407000340702a4c97a0189febc47e5baf51cc060af7cbf48642d46911e0889eace6bff53ca189a1036ba94912582b0f8b679a3b6ebdb31b7bba4f9c4c349052c4b9352d45e68463c865ab331884982c05f3a1fd78081d946a71d984887041a0e894f6995501233363027a3b7c321dc4a21d8463c9369abec4826f0906039a1a83cb59cac584d7c6426c91767167b3a4564237dac2b623445cb5998717bc4c8c9e3364915c5ba86b99a02dc444dd52b236d4cd2c26cfe39c1cc8321cf7156867b37f85188abea7a040400dbf4830ed1835b2d47a6b8991451a7889020ead45451f46623002b31839c556a22382130b7689cc92cab281b164dd237357a195f4688f8f385f8f45a32432bc238a0c7f78324bd5b9e73aace5391d60f28ddef61e4e2c493c136b74229edda96c22f70f54435c6240747d963e576b2aeab0bff2009ba0f34b65c2a35b72477f36c914d048545c513ad61f964829a78bcccec39d2db38496a209afd760f1a51654d3125dd42c3ee13353f93e0114469c2abdf879050cd9466b4606241158a60b35ffe1a8956815419b9fe843913d22b93c7283805ba3098a52bc16bfd9b27c29155a22c99eda56530a69964466065ccaa447b13c4c8115adcc6285d947aaea1378a76e163556c18459b1ac905abc9b39e21e12486a5e56a228395093b150fd550feafab094602672860e5c74240ac705f25903e70667968435a4dc3e24dbc77e9806ee94436ce00b11bac776b46bd85a94634c1a3bf91e53781f03318aed41011a390f48e5b7e2866d11783c7b959882821fd4745a2fb3bf1e87756008ba1103a508a584a3290a4aa4783f10a9e62a73f11a0d18f9b8e3a608a58317f3d3909a5a622bbbb09b52350a7a681e2a63f02504aec572328155f67100b6331f38835fd56361fee46b903ccb020a2998d651bd2cc022f1b4c97966274353b745ae43265d79fbaf20d7969a8b4ab5cc9f43259025724ac0a05e9de54257859858685cd602bdedc01047fb903416a2e2d770aabcce2460903feb40274354b2e705111124887b331cba10673c0d2aca027a2c6ccb95c701568c20346ec747a29de09ff6311fc172910e41031b95330e240ebee2026048047e03c6de9a293f501604d3c7ce57a715db0aa91a6151230731e02f467477d04a5aad9b2b8176a1f056c3140bb1454cc7ffe380cf97139f4800fc4b740a22520a3b2a8730caf5e7580352b936ab9eafe3cbebaa87fdc771b0d704e455b8153c4b6cdc780ec415ac7326be810c63669a7f30a138a187108880b5ab97265a2158f542c37828c80b4bffb474ac27c6513bc54f0897ccd9948dd3c78f60c4cae733aca6caf41b9ca8052f25e58e78526ac8eb30afa960a04a322c582e5ebb286accc225a187a074877c21329856343c587e7ab6b09c3427091655f34127e09c3de1d8c6cdc3aab3eac81a99aa1a1443794c860ca17a63d0b154c9941d9c219c0a7c982114fc0c85483639a0f047a217a148346fc844c44f37270e775c5ca414ba49cc59a4b94dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc5b07c8359e6ec4989c34b31293f4df965b5d95802afa5836beabb001d5cd4daee6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +expected_public_key = 4eb491efdb1988b9794aba1c0d42326e9a797c67181995999a1053b3a1ae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f263916041ba9ebf2b86e21b127c5951d7709fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4d50fba956ab9b881ef55a6459199c2987162774f573599ee0b6b001cba6bb5302df24ea0622d3fe2a7db12a063d528baea6dec8a97bf12a61249010eb7056ec5a9573c77b848a6c6fc13c070450919054c05be006a40368094775032efdb98e087991d76a703924528ec05ee50bc56d206895552cbf4999c6a7617ea35652c8d5cf22590bb9fcf62aa0e055805279400b2c9522cabe1853e06e6965b517cd04538d7f083e27b95c29b073ae13cac42beb549337491b88c877af8910bf8659fb2f309442460ee93a0344ca83c58c1840c95ea482c81380bae24c01c763b2bb05b369bbf074c8e96ac2b5b73920ae07318057a643640fd58c691209b08c9b5cbe972adf001e8c00fe853631341c8a634cc52c77754790a6540ce9585290aa243231332d7ec3161b096ced68d80208c362707ed892921634b4de6679e08a10f55c72043348bc512ad39c07dd41a88d3c8c06769b6c080b9a24080684aea9637527a099bd53af1505eaf0272a1f537593669e6ca1d5135ae9d77b737b77a475b61023777eef22477b663d5848ba7d8859042713bf7353dc46c2e3b9e75788b3813b4844c0a233019529809487531a820a079fc2a43da0874c332695a79aaf3c6d5997bfbd27783064c1c055b82b3be463b5b54eb8c2e42772cd56318c6658e0b90cc31596b3880033338e6e41e9d1187e3732b75f50ed961501a030d221370a61788fc8b164625939e7b19d076b45b51c555d063433709dbab05746641410cb34ae53e3652a0ade7ae5dca29f0e22048668abe03869914117b6cc18617946c73a20b49826748981367090e8b72b8181ab696b878c79bd16683b2ca698e1489daa23b54eb017f4000d481b268e2c7c02a75fb608217bcb1290746f7251d010a581df15ebdba8c5d379441d22e591c4be3c9cd9af05956674f558c2387518bebc02dc3c2971bd264143271ce28b1f419be088922e6644e939738b846cb651267a913936d80b2f4e8987b5c48c37672a222037fa1529a764be14a87939b6c72b7730ffc4db926836c71a56112724a88c9f55aab44638a4c9186717246666b28e1003ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed16b0a526c019e7399d1996f44755fbfd86a79d19fbe3957ee97a08d668adee16b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd2c0b398383378ab973c9647db074921531a9441fb53a94e229b7c7ba8f2ec9a1e830b9826bcf1d353d91abb56b89c33fd37ee6130757d08a1699929808c881f9907556af18a95938a1bcec20191ba5a9ae32b769e3c56d4cc6baf9c9152359609a9e8dd6aa9ccb12b35c9db5605bd8868474e65257f785b429c1869bbdf6e118024c906a951195dc4361aa95d4c53ca418a7b6926cbf539ec1f242dcb3b96e47bbe6cb0cd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091c701ab73271cd86765e760f0a58beb61b0e2d12bc7511d04b98e8fdb5412f618964367e2cb694af203ab805889e0936c55bf8553b2b006093c72015d8629b494a04e3b51cf18347e7a025064a488b42c0328cea0c57dc14763a74368e36159c72b232c8424fa01b5be63014fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc4529a00c1ab9f67e84de76500f59c7088b1b9dca9ca9f0309b5f12eb4d55f3d734e086a843a39b29de99162a062b1e6874281221ea3314d784572bab031a3732010a50c0ac8150691b621687b6020a5b347817a3899f141bd6454ee1b25e0b130bed368c5f905c1637c036c22f65ca761270a9e8bcc18dabdd78bab5c48a3ddb82a01c646c9dbcccf972b9f0ac4edabcea3088586e8ca08f7177ad3cefd578f9fe6ca08c99167c65e4c6193251288785720ad110f58f81f4b938dfd813b76887cab48bf0cfaae5a8a16f3b110e130be7313411d517e6febb2e0ac004d44380b8ab62e874538d005d4f744918a250e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_private_key = ce732e28b21f42f2bbd1b049e6b80264b218b581cbab8c9186e325f7617895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b652f86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458e419cd10c10c890c94fd3564aa25f1ec3a3282607d8b1864022cdccebb1b1e48961207e29264a9ca86c94b71d5382c9c6b8004c818f51a52006706285bb3281618a157c80c2c00905c33316516c17f04460124fd79a1c330417984220334c84d96a66fc8a5556814c58f7826ee86f17319da3f504f0124c3f06ca50792c1e1800feea8a8e8805a54bcb90c52eca144677327f5058cca151617f443dabba304b353f4a5caabf0c179a772582711c033b3f3c1225f191b887d8294fd18914850de6b194b91c250374963bdc7215b07cdaa8001372a21f0c3845979386c27949e0bbedc0b004258866a01ec5cb82fc751ba2f4510e514a3fa09b6aea7e5e45762076b81d781c2ba91dd6f40cf13c91e947a7d7abc2a2aa91a1404d87462b42aa71eb15209a9b0d4990c2265b051163cd2ba8319576758237482f500f7e94b3ff099616225737a766c10b6aeb213b5b073eff93c3ac91bbf2b93ff47c84d7ca2e794990e2db4a7e9ab19cb50cd522427e6a935ce3976490b21792cce5e4b971668c4793ca4954b477703730411df1f5ad2557caef78c914d0c223d836c407936ec58825f3b2a1925a5164b097a94a13d8ad3a27bf1ffb0c08c72b92215cb1b67c7d2c4a7bc7a6a8a054d2a34de69c78195bb149e4b4cebab78f41612db19540385f2f74757c662c2da3c7b03a34a9524e2ab90f5cc21fc0d2ad84bb996e6c73426770ffc1c9942cc22aa2934d97a66037a18760c51b0236ca1b1880a2286ee5241ffc220a4c6ec0e296090874b3ca751dd701086a15f419c67eb4514744047d7848980c036107586d36818e74ad98989c8c02afab4134ee0b545ed707876a613ffa10be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d6e29b184a38d8091b6a2c288ee2cae833a68a3cb6b30bac5ad7567c788d8c803a7b622fbd8a253b274b93593115b5b7a5282eaf93706c88c178bab897b7198c23b844219852a60410e8afa85c902edcb9a5e87a31ca84ac6b89a75830566062bc159cb129277af0645d5817c8822e384040f1621d66d41643897df21c1013cb1b426a703f120f21c780c67bb011fb3e8cb746c0b14c9f847dc1235f72e6bdfda1c55bd26e377395c4b17b764a41e0f7312782bf71820dd379befe58901a011fadac1efae549e5933aa9f9c64ce2273c486b56251674d56212c0ad7637854c7b8447a135fb960ffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cc32b395aa73a916514533857b4c3405fc32c2946cf4f4251b2091b6cbb00ce296459c45e558b5048b79cc4cb8aa01bd7e82320637a62e2038d5b3c0593b42d32a38be8312ab022ebb496a5fc4a991a1baeb660a23988fba329a79dc7144d20b5246466f25af4ad971014970ebe2b36316b86b3585f6b0753711a0bf3952c688b4cf6c8a24c0964cdc1f5c1c34b3c28359ba232840063ac30bdda83f0611042fd8b7c2bb43de68b712e67971e76e7adbc0879a41afa358c2258888769b0f785f2b4716e76753d41c4215b98bea2095f5c0ceadbb69c46ca152b3045b95a9ff198ef5302667d31f36e2330a3c1c44e983ba4388a7022f1613a47d19249f2534c23ac25bb76176aa102f103d1c6578ae141772e36ed5f30f2bb02aa34480b7d57e935b5097c5c5b61422ff6249b3531361c284d67b485fcc3f942501112408d01b96bc841df1c0a9136c01cf2652ef067efd740a68f80f2c1b70476b8b67eb14e97104722cb3c82c42d9912a2f2618d50c27312c13eba245839313ac08aa9ac7918252122a6a8ad632c691c8c0f84bb02aebc6f401c2455121ff33653e377805d3b2c8633d8b141d6b6370981bc63a7141eef2bf7e86692f28764716775bfa41043315e5cc1199427fc7f6a9889165b6b09d0bbb80a609c0d52063204bbaa619757e1748412cc1dcda4c2a102396927229ba83b1eba239f41dfa530b8a2779060877a5ea142910a6cb1ac97ca2466ab58625e823fba58429a613f2c92de06993ac7006c8e4834eb491efdb1988b9794aba1c0d42326e9a797c67181995999a1053b3a1ae542a7e1bca4aaef5910a157c713cce03ba4d34a9c427a53f263916041ba9ebf2b86e21b127c5951d7709fd036465784a4a26b91af48c7b3574d6e537676b4bf8eb5e5d6496b7e66ac4d50fba956ab9b881ef55a6459199c2987162774f573599ee0b6b001cba6bb5302df24ea0622d3fe2a7db12a063d528baea6dec8a97bf12a61249010eb7056ec5a9573c77b848a6c6fc13c070450919054c05be006a40368094775032efdb98e087991d76a703924528ec05ee50bc56d206895552cbf4999c6a7617ea35652c8d5cf22590bb9fcf62aa0e055805279400b2c9522cabe1853e06e6965b517cd04538d7f083e27b95c29b073ae13cac42beb549337491b88c877af8910bf8659fb2f309442460ee93a0344ca83c58c1840c95ea482c81380bae24c01c763b2bb05b369bbf074c8e96ac2b5b73920ae07318057a643640fd58c691209b08c9b5cbe972adf001e8c00fe853631341c8a634cc52c77754790a6540ce9585290aa243231332d7ec3161b096ced68d80208c362707ed892921634b4de6679e08a10f55c72043348bc512ad39c07dd41a88d3c8c06769b6c080b9a24080684aea9637527a099bd53af1505eaf0272a1f537593669e6ca1d5135ae9d77b737b77a475b61023777eef22477b663d5848ba7d8859042713bf7353dc46c2e3b9e75788b3813b4844c0a233019529809487531a820a079fc2a43da0874c332695a79aaf3c6d5997bfbd27783064c1c055b82b3be463b5b54eb8c2e42772cd56318c6658e0b90cc31596b3880033338e6e41e9d1187e3732b75f50ed961501a030d221370a61788fc8b164625939e7b19d076b45b51c555d063433709dbab05746641410cb34ae53e3652a0ade7ae5dca29f0e22048668abe03869914117b6cc18617946c73a20b49826748981367090e8b72b8181ab696b878c79bd16683b2ca698e1489daa23b54eb017f4000d481b268e2c7c02a75fb608217bcb1290746f7251d010a581df15ebdba8c5d379441d22e591c4be3c9cd9af05956674f558c2387518bebc02dc3c2971bd264143271ce28b1f419be088922e6644e939738b846cb651267a913936d80b2f4e8987b5c48c37672a222037fa1529a764be14a87939b6c72b7730ffc4db926836c71a56112724a88c9f55aab44638a4c9186717246666b28e1003ee006ac915530a1fc4bb786abcec5b35476436efb7c4b4bbfbf183ed16b0a526c019e7399d1996f44755fbfd86a79d19fbe3957ee97a08d668adee16b996a71df28acbb239dfe03ce8ff5ad62ba992863afd086ba74979cbd2c0b398383378ab973c9647db074921531a9441fb53a94e229b7c7ba8f2ec9a1e830b9826bcf1d353d91abb56b89c33fd37ee6130757d08a1699929808c881f9907556af18a95938a1bcec20191ba5a9ae32b769e3c56d4cc6baf9c9152359609a9e8dd6aa9ccb12b35c9db5605bd8868474e65257f785b429c1869bbdf6e118024c906a951195dc4361aa95d4c53ca418a7b6926cbf539ec1f242dcb3b96e47bbe6cb0cd4a7936cb6c97e8663eae6cbdbec645c8942f6b835d2e44091c701ab73271cd86765e760f0a58beb61b0e2d12bc7511d04b98e8fdb5412f618964367e2cb694af203ab805889e0936c55bf8553b2b006093c72015d8629b494a04e3b51cf18347e7a025064a488b42c0328cea0c57dc14763a74368e36159c72b232c8424fa01b5be63014fd7b2733c47abbc4d8d8474d5eb43fb76b03708872b4cc4529a00c1ab9f67e84de76500f59c7088b1b9dca9ca9f0309b5f12eb4d55f3d734e086a843a39b29de99162a062b1e6874281221ea3314d784572bab031a3732010a50c0ac8150691b621687b6020a5b347817a3899f141bd6454ee1b25e0b130bed368c5f905c1637c036c22f65ca761270a9e8bcc18dabdd78bab5c48a3ddb82a01c646c9dbcccf972b9f0ac4edabcea3088586e8ca08f7177ad3cefd578f9fe6ca08c99167c65e4c6193251288785720ad110f58f81f4b938dfd813b76887cab48bf0cfaae5a8a16f3b110e130be7313411d517e6febb2e0ac004d44380b8ab62e874538d005d4f744918a250e4b60eadc6cad0363e0dc6cba04949f893f75e5c48e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de037f1d7e636b4ab366dd5725957b9e5d2498e4ee1929f2213f9d05c882d96a1065a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = 6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +expected_public_key = 8c06203871ae8b0a2c3bfa4695c43050870392401315764ff65c9ef0db06b03b5b5582b57e1a7ec6ba4ad832a04e31268a853aaa2227f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f26d0769aec141c0686f750c1f17784cae142b942648655bc8a0acb8247462713a2183223dfb093a737306e94386d878eb8babe7ca066fcda152a0a81a792afc9ec32369101516122782100b24b02d5b8693a712f4711176b348e2aeba7314a3a17d0ce11315412e54a6508937a393897b01d361b1fe9b0b7cce01806a62d12470ad5650606883872a55030827b5bfa8a05fba19c9207f113c99fe5985eb70e88325e5cf35eea9605317579f15b161f55a81b694b0a79b8210b2c77524383aacd1936ad36b43f66fb6b5e668205396b40b3889da25e21fa985bbc6af4980d9fda368507a7659785363c6537f067eeb596f5337640e7b3b1877804f21c14d76d69d01b67a941e76cbbcc3765aefb0a74565470e7320605a0cc009c60e57c9e765d2f835dbbd91482d43b86858bf82161e1c3586290acaba2964f3a9b83352cf40aa26442634ef069e2932a470a59aff725b862b880e7a75fd705ee50624ca368e8c39c27ea0588c8983a453bca30897a5785cce2335ef8cd48217eee4485abd47a0769a0ac99089bea59c4481b18d27c15d92e915285dc62197f4804ea3b3e79bbcbf57671dedb8678f1264b420bfe191f21e489675b7f1479a390d0c8fe2a801f4cbad2f90138259904705f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fca06dcc3b3cd617a3f433174053885f785193c8a70432ac83c37b60cb1ca407f22c7b577f4acea879a8ae700985028aea3475426a3f071cc5162233e793aaf9936dc625a292b84d185ba31f964a4003c3a96701c6ca96305205b5071c3a6540d76c14e969a8061146940907ef20b857245c6f202b8978a23a6c84ceb3de596c10bdabb2732008c6a224de0ad219b9987099f1cea007d1466ab0719e396618014787ca6b1a2680e96a85c949486105bc4357a93a3109422e52a44bccb0c8c1aaca7931973560a82c65d253c02b2171688648a2c9f93f0a26ba58061c8cf64b54f2930a2a4c064cceaa6d34c76ba200c382a1fd1b70119304f278a87a77837856c68a119ca692b8c39782a16ac11cb6c4d9bc7acf335aeeae65f01a50d4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd440c449b8bdd15a3de54a3c1a17a444cb469e0c1cfa347b5173fe6f4749658984ca0530483a86b773471799b9bd53faf04d0a3c07515a3b915964aee1010333127b3aa72ad964f38ea89a4c561e36143eae3003a19cb4de14fe88bc5b4c236ebd1930474718ae654f43277255b1f508721ca318d2d5255db804166d94cf305bcfc6c91465b18f3aa4a64b624bbf395a10967861ccc3d13a17706511c8946ff31954962b9dc68aab370baca922b4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2b526eb4131e48546ee449d8eb7b709e296c028c6d085a3d614b8856a6d076cce23ca4ebc192ecf14954ba06415280275ca743587492e76a5ab5593e9d15b10f829dcf73a94e040d8a25aa29616ac8a88cbb148e1c727b608305841b8f3c63e967843c9a50c43c3366293868f1b1acba037d95b64dd088e07d42f2d218b18eb7eda5a2506cab773444f2383a5e40940e4f26033c336e3c7b5d7d2bbecdb39180c87127781111b318fc4ab8c50926c932a122aa79766a48abab6707710c66030668540cb5c8d87272dac2683ada81dd20aacc3c01df6056cbd23735dda391332c773934e361a1b6e247711a843644226adaab77089a831e37d571517dca952a58c0835705b03187b77e6ac91d426ab21b997905fb658c6b7510ff5e45e446204fe935a7612a364414014483cf1bc844a6935ce351d1e090313a776253386a01073a416b47a943712c0b7afd130fe833041716530c4af95928ebc541961558a707320a5fbbb3c113e8b3c88b0c3b359c13ee24172c8b649b67c645e07400cebc486383d8ea2afdde8c104e69dab368f092ab3b3b85fb70c3036fa5925301430d17603902b1373258b206b814bcef5a2588981339cb725a5f38a079935f6a27578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_private_key = f76c7d8002b7ca65bfe6a59aa3645a8e51afe5fb80145241134cc072a60ad4b72d80c2bcbe1630eeda661cb62e01b0798203a1a287c4b8f725dd422beee6627c864149ebabd84280739193067a2348f2861dbb7f1a0914ba2bb3ac6c80d5ca1f483c8b86c1cf5a2c3bf8f6728555799381a1b1f3cd02e445cbe798ac0361e15335380051294667b9149f38d85a1839ae43d331bf14091c4accbb24c8e8105a9d1185ba880b7e13cd3563aa235b899e7509525280a37162c043b089d5a0bd48b225ebb2d0538f49c8ac3c3b0677d8093cf70b3404016b4686d653ce4715a85953171bb937f5a1916271ad53318e8155269dba4d0a520d057963e70cc01e680fe8408d03d3275c95a2c528190924749bc32dc31b21b58c6f5e4b59c157cab7653c0d146dec9a3f94e241993b09bd62446f35ad7772279e116464fb316db8449a3ab7525b3e89b12b54f14fb19057c39510b072894831a5747782d404487926ad756b1bf81cb416d94265dcacea475fcdaa727d0b5f01b376250b123f717fbb0b1976b7704fe5ae5ac10cd17b87fa8bbd3d824d3b91b567b5c20243677d741ae2cb1c1d049a842b7f9da9cece8931851bb35776caed97c27d395108e42661aa60cc181abb2774c67773fb29b445f3554d386c87d489d895a43ef268af0c81f6065e57e744f719120323b013d35801e26bac2700968566512106f5161ee8528372d45a42b41022239fb0b3cd23c4251927b355719a1f2a0689a4abc508660dbc282706b765ca4bc1887fd064cf8285b1155863e15b112bcbb1962255b362ce8fa4c51c97cfcea7004daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b86724c1adc3e67d756c1c8647fb4ba32b75a6da3a05a870fc1e12cd279666ca046e064a74625530e742efc72c1d5f959c9d256389c4c63609fa11a8fb5e70e1e2256c8164d80c69fb8f4008a647af7f3ad960265f55cb786e8726b65689a6a751fe045b7d45aecf50605d135a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b225728eb8836ad1f373f66a2134b8b429a8457b600c5a3274b0157f66f091ec88436d5667802a15749b4c9c499a36c58fc5a7ccc10a604ed00de74bbf433502c02ab0ed949f5da8b9efb83c4a2395e49413a7030f4f95901e8aa2716a3ebb09aaf61c9384586021301de0f8c085421460a10fdd176c68b4c115c91dac04121924213855ac22e8c98e3643c3d7c3b6c6c4ca964308510525c5aa00c32ad9ba258bc44a9f521a2873bedaf7c56bfc26a320c0fe95cfbe12c0038c1a65b62c18c37e61a2b9194c9ec1db8b9fd036c7c3a620b5c661d8ab0b46a6cd3391e53218e40cbdb082c2207630c2715541b10e3c395bf2a5a15ae8b506880dde937432ecb150f9b3c136881058a750024d9b247232b7289bd07462c051b7ba599c985c6eb08c7ac22135c99e85930113554c59ac06ae298d5935658f513644b01132b4c1ab84677e342a1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f782784e4b6fbad380c5131fcae11d4ec89df82490b4f1babd4673d7417b9cf04513718f2cd0cfc297071450340f1b110ae53ad21759bb5b8c8e495f55cba315805921485b73a248535ab3519a544f440b03b0b1a667665bf068f165570d9aa52fbc2cefd50738109a2f18011d1b0b37142f24a52843a81c44eccb8b083b8c98a51067197737bd47fb2b40a5a96e385364463cac81348ca44e9b8b2e457701fc0571dcc6645ff724e44b1370fcc235ac9f735b1c85e877dc30a9654006837c5dc318cc11f962837c0f26a59f171b6ee21b0ce02925c280710e140ea46486e68419b11b548d880406e929da097a99f8969840979eb861d483337d605c7e657c024c3315f76440f8437057710cc71817956c8135873ebb9d84b801cac006930443c09773a5f542cdb838e176b45497b97091a613c305e6bb240ee08009e699c6d30d44f4152ec0a1acc16e5310acba766278516470613ce1044e46a4192a145beb3727dcc22f53a98b4c7c414473160d85872f31c76edc5dc2e822a91976761a5d933b8d284082bb85162fab7a7d520ee3889f299956c7639dea77127bd04ba5500feb9077949a8245e4148cc2298c06203871ae8b0a2c3bfa4695c43050870392401315764ff65c9ef0db06b03b5b5582b57e1a7ec6ba4ad832a04e31268a853aaa2227f8e382d467cf2d998284884fc7ec971ac439315978bb8a8edf287f26d0769aec141c0686f750c1f17784cae142b942648655bc8a0acb8247462713a2183223dfb093a737306e94386d878eb8babe7ca066fcda152a0a81a792afc9ec32369101516122782100b24b02d5b8693a712f4711176b348e2aeba7314a3a17d0ce11315412e54a6508937a393897b01d361b1fe9b0b7cce01806a62d12470ad5650606883872a55030827b5bfa8a05fba19c9207f113c99fe5985eb70e88325e5cf35eea9605317579f15b161f55a81b694b0a79b8210b2c77524383aacd1936ad36b43f66fb6b5e668205396b40b3889da25e21fa985bbc6af4980d9fda368507a7659785363c6537f067eeb596f5337640e7b3b1877804f21c14d76d69d01b67a941e76cbbcc3765aefb0a74565470e7320605a0cc009c60e57c9e765d2f835dbbd91482d43b86858bf82161e1c3586290acaba2964f3a9b83352cf40aa26442634ef069e2932a470a59aff725b862b880e7a75fd705ee50624ca368e8c39c27ea0588c8983a453bca30897a5785cce2335ef8cd48217eee4485abd47a0769a0ac99089bea59c4481b18d27c15d92e915285dc62197f4804ea3b3e79bbcbf57671dedb8678f1264b420bfe191f21e489675b7f1479a390d0c8fe2a801f4cbad2f90138259904705f2f07afdd4a5394b64905154a914a7afef7cbec54a7d5267a3fca06dcc3b3cd617a3f433174053885f785193c8a70432ac83c37b60cb1ca407f22c7b577f4acea879a8ae700985028aea3475426a3f071cc5162233e793aaf9936dc625a292b84d185ba31f964a4003c3a96701c6ca96305205b5071c3a6540d76c14e969a8061146940907ef20b857245c6f202b8978a23a6c84ceb3de596c10bdabb2732008c6a224de0ad219b9987099f1cea007d1466ab0719e396618014787ca6b1a2680e96a85c949486105bc4357a93a3109422e52a44bccb0c8c1aaca7931973560a82c65d253c02b2171688648a2c9f93f0a26ba58061c8cf64b54f2930a2a4c064cceaa6d34c76ba200c382a1fd1b70119304f278a87a77837856c68a119ca692b8c39782a16ac11cb6c4d9bc7acf335aeeae65f01a50d4bc7458fa93e5e24afb7576b41b631bc884853046160f77ad0646918b947bd440c449b8bdd15a3de54a3c1a17a444cb469e0c1cfa347b5173fe6f4749658984ca0530483a86b773471799b9bd53faf04d0a3c07515a3b915964aee1010333127b3aa72ad964f38ea89a4c561e36143eae3003a19cb4de14fe88bc5b4c236ebd1930474718ae654f43277255b1f508721ca318d2d5255db804166d94cf305bcfc6c91465b18f3aa4a64b624bbf395a10967861ccc3d13a17706511c8946ff31954962b9dc68aab370baca922b4db66cbeb7a4e16c6dbac64937b869edcb585b4785b2b526eb4131e48546ee449d8eb7b709e296c028c6d085a3d614b8856a6d076cce23ca4ebc192ecf14954ba06415280275ca743587492e76a5ab5593e9d15b10f829dcf73a94e040d8a25aa29616ac8a88cbb148e1c727b608305841b8f3c63e967843c9a50c43c3366293868f1b1acba037d95b64dd088e07d42f2d218b18eb7eda5a2506cab773444f2383a5e40940e4f26033c336e3c7b5d7d2bbecdb39180c87127781111b318fc4ab8c50926c932a122aa79766a48abab6707710c66030668540cb5c8d87272dac2683ada81dd20aacc3c01df6056cbd23735dda391332c773934e361a1b6e247711a843644226adaab77089a831e37d571517dca952a58c0835705b03187b77e6ac91d426ab21b997905fb658c6b7510ff5e45e446204fe935a7612a364414014483cf1bc844a6935ce351d1e090313a776253386a01073a416b47a943712c0b7afd130fe833041716530c4af95928ebc541961558a707320a5fbbb3c113e8b3c88b0c3b359c13ee24172c8b649b67c645e07400cebc486383d8ea2afdde8c104e69dab368f092ab3b3b85fb70c3036fa5925301430d17603902b1373258b206b814bcef5a2588981339cb725a5f38a079935f6a27578298f5ddaadaaf4616cfb9af778875e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1a5383897314d60ae0ab1a8b50d6f5de454a2eb8b0502d57001e6e19223a82ef2b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = 2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +expected_public_key = c17c04d8c082f06a8d497768755ca932d2663637b2641c34a379ad8faa55c15246fc5a13a3963d4d36a1a1e06bb811c736e10301d96181207f65e992a66b7b3d1921c7f7247f34bf3951cadbaca9e346bde27887b61ab58fbbb3cd25466b3684b48223b24c34c6f1ce5aec8513717cbe5a0059352e4ac62eeb157a0ef76936c16db808572cf93adcf5bb44b1935d43abfca1b06d375f4d5a4d2a40392023a86e05796565abaa806d9ba0273e543ab03809c4fbc74fe4156bb2b60c76be49c7a1d5d45410627a85026a58152e2833b445a087a4f011befb1e03b7102ea4b17d6b5c4e3791f9c2babcf2471d86c720d412342529728cb560828c7286035e612698632cc054079ad2b53517b4c953969d8bafbdd0c09845191ab426c23a8b469b601c8751b02a4af32b670e6592f2e5b943924853e551bd80c5e717405eb2480da7a6ffab19660cbb5956546bc64def60b800c252d76c96d2fb3d22736143b144953a410653334c8967a367284e2197f5864c5e811721a49c29ca0e43e9aff5a7264381bdd5c4af51c51b66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7ed026efeb5b271324bc71bd73d09d923182fb7739405159d51ab7e51a0765c56d98d50fda35546bd762c21204f5661a72aa3a731a0520409c62154cf54243a32914a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6b917d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b1551d4ff31d11435a97a61c0f4430757c70a4d73402d94338765c8f708502774d36ac34cf85af4683ab5b36c61b04064705c68b578f7dfc4b9886140d28335e78c3b5ac7ed5bbc3dd6ab0a76a97858257c519cb57f0c949c2818c43962cc24695c5b3a6242908f20e14239930a9b8fee51bf5e62822f42095f37299316479c9371bcb567cd5cc138828ba5036799714dec18047c84aea562d67e375ce697536443ae087a5787a8de6314a30e81aea1312f3fa12bed1ce1fba8e637009bb7998d41a6654d70b2f9436f6737c9d118de76ccd885b4b0f3751990b93138a70acc047e4416fb2e21bf2359ab022696e67b6ac6b8045f3c826b81b76c4589a687e42d909ee5473512a71b6369d22877ab0f91a7cc2c01533635d896b6bd293f85962f05a2bf14315e42582188bb09f2c3cc86632f636adde80817c0681a3c8c313a65ad918cb12582ad1d76ab42643efa7ae8d94a4721b1f4bf77e8e47af68642112ab9629e0a2e3316d6185668ba373db4708add91ed47a5044eba47c346b7d230d4b324b30c6193184b493d111fd8362812b5fd1e19d4978672c505bdf9a2f888469faa040a4b3c5648929abaa66ec435d3173519b882ddd7474b1210368711c301961f4855a49f75656d356930c79ae11983a32a17d4757ce42a2d9e26f6a77475c12056a5378abf7c7cf097a7fb23badc4ae929a5d1eb46af442956a370d7f9a635926859e6099d2b121a807c107cc15ab18ae4634834c22144f689e92000829a4a9793ca767e43d707bcb2e0118e810b32f14007231721a5a1f1621991b556b70389bc8652b56d824e070a5f9552de88b14df346d43b460807662263769ddc268a78cbf4c155e46484c8e02087aa6493ce73b845289e9499d0dfc1b156621683521dad7176de52bc294770ca02ee08899b79673f562c5ec68157c758d4726cecb986c1355444d96402bdc20a620128ad3c9407a64537ca855f820c7166800839e32b5a0b9404ec4f375c68336c2c098ebaba5d1865a99a8b45993533b0651ef97477660c48ef40ea7261bcf9c43bfcc740a0605765c5cd84cc5640c92e533a2ec923a1512ba57d11924542f53329598598a0717aa91986901046db1c763f25098103b208933085b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3cabc04b7f7ca57072216c859e73183288c8fae0a71b98a2366a99f276c0b68688759e6b34d51a0f5fca2c52585894a5ee52253d6f963ebd1283431b6d681065426a19157a6384b27bbb0495cb8a4f42c5649f185601b4a19511841e775868c0ef0e010a8147a743285ea16a6f01323a9acb46c1418418c0b94793617db9fcc1039b0060c167052b3766e9452b65f4789d9123e5e299c0e440986013226b63db7c78109622eeb8880c351c6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_private_key = ab150a2298917b1707af1ac0941acc5b6b259d1aae8f878bb0a37089b845991b203ee4c8f1a58cf9d2cc0059ade2db131bdc5fe3049e17f350a805c6f30479be91b12a36190a5332eca4737df5a32fd60cce222b592060add75a62f88d5bf6426fb18a944195f1ecb1babac1dcf20c39339ed45ac8c3ab582382480851107683102fa1914e753731964fdff686f0a354703858c15c99f30a19d9c281ae93004c718d1ca5452fe58183d806dd666792da7a76b0927dc77793396e4508200ef5097e45095a33af5683a4dd1a5f6878c1e6fa85771a990ea16f7a28034a897855769db8e4a9a425860fec7031d09e96b665f57662b2bb86e362c3f9a706e354c12423ac6cdc74973a0767d73e75f5739747433c3451f8e5b85e5311b6e009f79c00cc07ba26b74d512520496b1998a4445c19249729225044cffd51679b495511223417b2bac86cc242241f2b70966e9a7a03c3cc0ab526abf857dc1a140ad85825757d2b5a59b97b7f8c5015da02159d013c1f15491ff4cf64c564e50c389f6c85b7c060f98011a4518cd3b48c2df68c67f3497f439c11f8504e577cf49acfae704a2b093238520292602cc2138762d87536f6285c001d6975a242654ddecb5663ac44228bbe5bd58d9b90426c66802b466b21dc8d7a23893a953033874d0a93626c00b6a4fa3fe9eb0dfeba2f3e789aad8103ca153fbd7218b95547de700ca526aed4f159639c59a7699296486188c3ca111479ddaa747f99ac825c7593911d6261683ce92ee8aabb77f82ab14838db54149194b12791c4991181c66bcf05c67e19f05dcb658d8dfab09c180967311f4e2aa03d9b8218889f87c5a5680299a7459afdd69db27302d9761daa20be37900b971694d3b6aea8c6b5d53a686beaa478f2abc17c1c461807597148719925590c1e482aa05bb73077c017c1010ea576bfb5a63031875a23b0a019d608d64a30d0dcb39d750099d1c7583c34ab1cb1dd99a115547e3e4ccdf2a872e821b2330a5f6b30918226b7fcfc9fb4f37d8103437db12ee073a49d29a7359316f8d922f783797e49b8c2b6146f76c7f8a66838c86364a788d3c4ae67d02ca09391e8547edfe86ca1d131c5b96caf479d9562688d1238c6196526b17844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d04810311a28880247236a3761236b068a9a4edf55317e8841218441eb1137342977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e41531204bc0df8243f81367f4d979bf0125b84eb5d5df53318463102938a85214ad7355960300db40719a2acab9297381a6708391c78a8d4029487c324291a7e4a0945a806e0f24368c7a2af91b8bb155d04c557759228673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357be9227f9c4ce8b98003452c1d8d19c7a8332403a41308086346129d3f929b847bab1aa5d88935d816a708c6a5e41023bcd4252569cbc724a53df1b88909267a932186c751339863c8dd49cbe200797186924c26edb976de613cc2c46beb06b39f5c264716a76e67831e4198822d77386592c777a0846f9b278064656903bd1f26a8a87832d541541e8a06e5733700836c5f16a06f17ab68b6ba229c9e740765ddca88a01469a79bb44f2a4a55547abec4f74861b83687d69fb0402d6cfb0573e8181929070483e85a9147801ce7b8a707093b2c67a21f1c65222981ed55755025805823908d908a6516488a0b87800034937b582368cad01c99c47c84c2c09d494a6fba19e5275bb27c998c5ec863e01612f3a75951a0fb8790cb5b623b3c089cf40779b6936b632b54b981c7ec83930f7cafccbc365376a3fa3c1cdb162b1751ad8eb3b2fa70150b637d1963600b0badd755e3be7486f8cc306d9a05d688227f77514b02dc7d47c93986432c2b58c674a74218d6e9482f8a3b8a6c5798a833d97a65df98b3117203aa566ce46499dfaf56f69310bfe821c16bb794dbabb7068cff6fa3d2cbc376bf1c4e06ab2e4a73256a618d9236810642c1d1bb3c13ac300f20eacf79d1ef347a38084dc222bb8741849c2b038d9721ae56a5300be8b9b4ba70c530593a5816309ad50420d63a7bdd0375b9475c17c04d8c082f06a8d497768755ca932d2663637b2641c34a379ad8faa55c15246fc5a13a3963d4d36a1a1e06bb811c736e10301d96181207f65e992a66b7b3d1921c7f7247f34bf3951cadbaca9e346bde27887b61ab58fbbb3cd25466b3684b48223b24c34c6f1ce5aec8513717cbe5a0059352e4ac62eeb157a0ef76936c16db808572cf93adcf5bb44b1935d43abfca1b06d375f4d5a4d2a40392023a86e05796565abaa806d9ba0273e543ab03809c4fbc74fe4156bb2b60c76be49c7a1d5d45410627a85026a58152e2833b445a087a4f011befb1e03b7102ea4b17d6b5c4e3791f9c2babcf2471d86c720d412342529728cb560828c7286035e612698632cc054079ad2b53517b4c953969d8bafbdd0c09845191ab426c23a8b469b601c8751b02a4af32b670e6592f2e5b943924853e551bd80c5e717405eb2480da7a6ffab19660cbb5956546bc64def60b800c252d76c96d2fb3d22736143b144953a410653334c8967a367284e2197f5864c5e811721a49c29ca0e43e9aff5a7264381bdd5c4af51c51b66a450751cc5c7f75683954cff0385436ca38f0759c93ccd37c44e7ed026efeb5b271324bc71bd73d09d923182fb7739405159d51ab7e51a0765c56d98d50fda35546bd762c21204f5661a72aa3a731a0520409c62154cf54243a32914a82c8ea6f75adf55b885ebc8d5447345159ecc78aa6b917d42f9c09677caf30b879cf9b73f468da38880e7948788ca42b1551d4ff31d11435a97a61c0f4430757c70a4d73402d94338765c8f708502774d36ac34cf85af4683ab5b36c61b04064705c68b578f7dfc4b9886140d28335e78c3b5ac7ed5bbc3dd6ab0a76a97858257c519cb57f0c949c2818c43962cc24695c5b3a6242908f20e14239930a9b8fee51bf5e62822f42095f37299316479c9371bcb567cd5cc138828ba5036799714dec18047c84aea562d67e375ce697536443ae087a5787a8de6314a30e81aea1312f3fa12bed1ce1fba8e637009bb7998d41a6654d70b2f9436f6737c9d118de76ccd885b4b0f3751990b93138a70acc047e4416fb2e21bf2359ab022696e67b6ac6b8045f3c826b81b76c4589a687e42d909ee5473512a71b6369d22877ab0f91a7cc2c01533635d896b6bd293f85962f05a2bf14315e42582188bb09f2c3cc86632f636adde80817c0681a3c8c313a65ad918cb12582ad1d76ab42643efa7ae8d94a4721b1f4bf77e8e47af68642112ab9629e0a2e3316d6185668ba373db4708add91ed47a5044eba47c346b7d230d4b324b30c6193184b493d111fd8362812b5fd1e19d4978672c505bdf9a2f888469faa040a4b3c5648929abaa66ec435d3173519b882ddd7474b1210368711c301961f4855a49f75656d356930c79ae11983a32a17d4757ce42a2d9e26f6a77475c12056a5378abf7c7cf097a7fb23badc4ae929a5d1eb46af442956a370d7f9a635926859e6099d2b121a807c107cc15ab18ae4634834c22144f689e92000829a4a9793ca767e43d707bcb2e0118e810b32f14007231721a5a1f1621991b556b70389bc8652b56d824e070a5f9552de88b14df346d43b460807662263769ddc268a78cbf4c155e46484c8e02087aa6493ce73b845289e9499d0dfc1b156621683521dad7176de52bc294770ca02ee08899b79673f562c5ec68157c758d4726cecb986c1355444d96402bdc20a620128ad3c9407a64537ca855f820c7166800839e32b5a0b9404ec4f375c68336c2c098ebaba5d1865a99a8b45993533b0651ef97477660c48ef40ea7261bcf9c43bfcc740a0605765c5cd84cc5640c92e533a2ec923a1512ba57d11924542f53329598598a0717aa91986901046db1c763f25098103b208933085b59c0cc538bd344cf8e268e30bc4730887ff4c559315ca3cabc04b7f7ca57072216c859e73183288c8fae0a71b98a2366a99f276c0b68688759e6b34d51a0f5fca2c52585894a5ee52253d6f963ebd1283431b6d681065426a19157a6384b27bbb0495cb8a4f42c5649f185601b4a19511841e775868c0ef0e010a8147a743285ea16a6f01323a9acb46c1418418c0b94793617db9fcc1039b0060c167052b3766e9452b65f4789d9123e5e299c0e440986013226b63db7c78109622eeb8880c351c6a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273500dd7b94b28b5b650d90962962bb9a3ae96e70d35723217f3f178cbe565905124c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +expected_public_key = 56054ad4251def874aa0051ea234b544d7a0dfa60b1d5bb60b8bc95220c6cc96ab6ed53eea9c7cd1715e9c29291a361b04f205cb094ff888642827aa19c64893685ffc004b6ed9516f6638b9bbac94404f91c29a4d5ac6a9615179798cf6c486333a7641846cb49c6b78425aea240cd5f98ffaa826aa3b7b643a0c5f4c3ab4c21ea9081e9439445c98277b9a507bbcbb82d31aced3c378b017f7d62270749bc1901ee53c72953576125574dea727080a659bca4f007b6cf7c9cb2d0254ba9a293290c493654d25e7ac0cd88a6101b12622ba2627000de87d88e4990ccb9cf4a08918d044c2d52cf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348ae706f400a28f0b1c9f8a40d8be14fecc0b2f282ca8f5c499f2a3d16bb7501003d22965b7e33826d343f72a501e0b219bf868b3e47bd4fbcba0d6635421189c17c32479aa5fb0abc84549f878490bfcac6934a6393a0a14874a878d65aacfa3678704919240d31e9911fb703dd339684d5ae6090bd3478578f7a60d1d72da9d70eca9266b19c79115322e626ba64d52d26c9a655f1325aa63881e8800e16382a46865ac2cf015abe3a420ecef1290e5a2836500176d7b6d54868ae3a977cc26a40a2c20ec3b346c0a4b81549d274a7bc6b446d6a42512c55b9823d745402a630065297973b99b569952aa9a66b440430d980bf4944cd66513220f13964a30e86f738a0eb1aec491908d2c07a35591a384d0e560af91c1f7910b2d3f61e69234375b9b6cc017891eca65b83332df15773baa489862494435538db956d9c09660499d7e343c7d68fe082997b73b69705b9498ac9cd989efce26f4aa2b3d5e7b445e4132185a4e734175ee4b5b7cab33e42ca33096755473d774c758b3ab1b7687d62351c3c5251653953701c81e2cb2667c885e75c814f375eb946adef027f78036b28f4151f1c799fc1556de38bfb2ba996db3e3e70b79be2614b073cbd150c04313013ab88c477297ee615fba0a9e00a50ee3b0f66498ba09acf338b7342b8670c31428f4a52ccf9b4b6dc98667ba43792863661738e63653c34b9147b60ebb21ce89291891bb814096d662806d1d012481b922b9c2fefe9a66b919823970be95bb12c6619498228bec78db0739a5b1c93654a2aad73851355a0485a52c3896c3527964e88727c3805eec01a65cca1fec8466aa44bbac56e53895251892b6355c5e39953f680683ff72e0968867b536c11a33470f8ac74870d996557981711e5d0abc65c671f423ee4b67771055952b54df8934f0b6980779abe207c4f8ce1cf17bbbd90b24d1ff875109366a4270202036a0796146cc8ba70712f98b042b301c5143a6143e01b79b2af3a944100eba87da1725743c370d85894892469c00a95f3866726138c2099b9b6c47ce9b9630222c7656623260d8500b4d7752b6779af5b5b858016057f545175f61477476e3a02aca3d1485e0882b305c9f956908da84ebd8083ed26b8b2b8b50a347a4cda722bdc6ffc2b9043491da64b0fd0a39b7f1550186a0038e07598d6887e6c8c2800288b1c9a45a66233049d77d912b1fb50fc119b0b7455c8d90a3edcb046f2064d401c8f108b833caaae5573a10b9fd1775ab90226d8a32088ac614e9b20737c88dda963d0e77c7c592179b4030881987421a886ac7a422c98b6d51c53d8c1027c84881491994cc84e9b1185b3425758bbb1e305a1103ff6989c633a5697a97e5dcb94e7191d9a47330ecc60acf85083559d507a77f7033965a0859fd6306d27c0ed2b35e7b3444d957a52010ac49a8851952f6061ad551b7c74814606510a0bd19d9ee7998310c74ef507902cc71103134a411f90da122fe72fd14448dea00932977c0f27628f092da3ac07d901c2c3613d22d48ad6376ac1d008c7d19a31623ebc616e4fc3887d68c033bc3ec0e5840d415f6fd2c15355c223da1c45289315cc945aa39ae7498767eb3a6692b2a0ca6e7bc73a5d97644703aba392b5d386849f91bcc7f5691f295a267ac0c1fb84e5e31c94ab020e351ae410840e4198e417b8f397aa33f88114030b07d5c702c6ab64bb7df7276f593ab3d133232c919dbd06b6df756258b25c7132bf03c62077084ce937ce829b0172810b92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_private_key = f80c63dd6cbda93b6cee719fbad6bdbe1a03f18b3379306ace5625fb38c5edac9c8c94525c85961e14a76082bbd760ccf9b5ac777088b0cc80e0304fbcfc697cfb13dcf1cf777325eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd2f07c76e8b7a68b92abc870b56202f7634b9b37902d39bca04653fad9a0e4f0be548abb97c7a1fa18c34cebbae3987f4b3c52a5006629159ac6875276053908b389d931bc7e2871751169b6d81c8d8b5f52854a3e644c5c504675d688ba030e9e78a79e7788522516ffda2ec9946aa9791a634b6ab6d04456003acf348bdcd859567a74a7b73556820f8dfc12e467ae2fd11025e430114a5a60d3b42bb43845721637a69596eb953ab7b3e3b28b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e8552bf7135698e15b8d99b0777a0a5af1b7dafc172aa6a4d69202f10351603771876c580a7d24479db0d804b6513a09281f291f2706ab128905663aecb0bb31a41046771449d12c335051a2eb50ca81ace90940a8a6a355b21a9c7505491ea3b48b5323cc567ead909fbdb380fd504c851452bd34f0f65a39ac62d922a3c50a8566edab03358745d701332e4011022bfd4839ae7b6745c66aca80abab8213369e299253b40a7922df02ab70f9723baccb1ad563ad20c5eb8a01ae564be24f40ce91a0f06ec68c0604c74250909d317f8968947a12ea297a279821f1b5377b02653d66897aa526cf51553c268481f7174bd9495da4b0305650358a637a5fc31c99ba7ba304c6811b555e4b1c2f80eb4223c54032d16238861fb650bcba24b127026fba51f5985476103fe1375b94007a06bc2ab048bcb4a78e6d3c748b141be410992733630b8c917f89960273740a595071824a9d02908d52d334373e8a575d5d52e96e5ad0cc95bf2c761ae577b9ef6bead33103e5033e0765d748c409f8a44227b8f55838b38695c5e132f2cb9bfdd7cb8522906e9bc03dda468a04012277417869277e2169c63112e6a8942a1c13aee97300ff4caabf862058b6e7cc16f34c79ba200853701a98d630936a8a595098c8b19820ac91f47451e011069aa688bfbf5ac4ee018c53639a1b0573c8a420c4619166b011e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fb70d52b3ca5d01729935bf7e4bb984576f2acb7466c8248f975bad539b2260568dfa34cf2974d83699761c95405943a7a88374112f8ae79b4d244bf2d683f7cc7a533229bbd8b5e822c8b3449548634ff34bcaeff25a41aa84a1fa1f52f486f89630a7730e4f81ad23c14d6906816a849810951727042ed0782ef26c31281c0aade6c9334a88acb917b781c4f16327196422c24541065b5e80f4374da0853d478625a68f728a20c1c82ca4fcc4d62744fa658059141221a917d6121187d3b621179aa8f7b7cd0904e6e0787f9a5f65eaa78011b6b63290a55542c80a4bfad64677467dd1b12785e6bfbc31c1f3d46db55c0a035604ef658279db3232c675bc0bc97717ca3eb71d4f44caaf1b07bddc90ae982886594f98c41ae7481562cb63d0b2539eec589146735490a4a87b6ec5cc77bfc0810627aa3452cb061a1648ec7cbb4937826602185a7f5b9306d822633e2b7d35a39c135ca5c1c5c1bc80ba25eb91cd6a3d71341cb1314deb05a164d31123b0a6c5cc7ededc1301154e875493ff173d74880afb7438c44085bccb29095ba859a4cb2d77bda5d61fd9600d1b9c45592682bf161713c80d0aba348ee8bbf370bd4b1a50e6723b9b2499030a0eea58a6531579f8b110c7eba4ca3a57a5b6a5ad511f896a9f78a62908cc0fe0a0c06e652240f34d1e16ba51b41ae7077c3e982608216842c499a51ccc4365a864060f4d2b854232b56d803cb91c7fdd830a50cb2ae465c91416bcb09190be99c56f870c065c7bcf4b421718c17f3394a3684cb0bb83473927b3a1b4f8334851861044305137746ab39650949c8cd43839fa75b0a78c14d65b2d9139175f9756ce3865db6c77467b086c4826921047d13caac87a61e2d6b6a6a8cb67d18a0e910dec05aa5c3525ec86a2ed7c24c0e520b44a5c94940ae8d17f6b175642cb49640bc3254957c1e2501cd5017d3c297137a59cc06b69a861bdb73a0c739733dbbc5dd91628d85b56054ad4251def874aa0051ea234b544d7a0dfa60b1d5bb60b8bc95220c6cc96ab6ed53eea9c7cd1715e9c29291a361b04f205cb094ff888642827aa19c64893685ffc004b6ed9516f6638b9bbac94404f91c29a4d5ac6a9615179798cf6c486333a7641846cb49c6b78425aea240cd5f98ffaa826aa3b7b643a0c5f4c3ab4c21ea9081e9439445c98277b9a507bbcbb82d31aced3c378b017f7d62270749bc1901ee53c72953576125574dea727080a659bca4f007b6cf7c9cb2d0254ba9a293290c493654d25e7ac0cd88a6101b12622ba2627000de87d88e4990ccb9cf4a08918d044c2d52cf42a938d6430e544cb2e369ed9e7c7304b55a34a8cd193a096d5c716383904b7b8cc89ca471980b84699f546bcfbc348ae706f400a28f0b1c9f8a40d8be14fecc0b2f282ca8f5c499f2a3d16bb7501003d22965b7e33826d343f72a501e0b219bf868b3e47bd4fbcba0d6635421189c17c32479aa5fb0abc84549f878490bfcac6934a6393a0a14874a878d65aacfa3678704919240d31e9911fb703dd339684d5ae6090bd3478578f7a60d1d72da9d70eca9266b19c79115322e626ba64d52d26c9a655f1325aa63881e8800e16382a46865ac2cf015abe3a420ecef1290e5a2836500176d7b6d54868ae3a977cc26a40a2c20ec3b346c0a4b81549d274a7bc6b446d6a42512c55b9823d745402a630065297973b99b569952aa9a66b440430d980bf4944cd66513220f13964a30e86f738a0eb1aec491908d2c07a35591a384d0e560af91c1f7910b2d3f61e69234375b9b6cc017891eca65b83332df15773baa489862494435538db956d9c09660499d7e343c7d68fe082997b73b69705b9498ac9cd989efce26f4aa2b3d5e7b445e4132185a4e734175ee4b5b7cab33e42ca33096755473d774c758b3ab1b7687d62351c3c5251653953701c81e2cb2667c885e75c814f375eb946adef027f78036b28f4151f1c799fc1556de38bfb2ba996db3e3e70b79be2614b073cbd150c04313013ab88c477297ee615fba0a9e00a50ee3b0f66498ba09acf338b7342b8670c31428f4a52ccf9b4b6dc98667ba43792863661738e63653c34b9147b60ebb21ce89291891bb814096d662806d1d012481b922b9c2fefe9a66b919823970be95bb12c6619498228bec78db0739a5b1c93654a2aad73851355a0485a52c3896c3527964e88727c3805eec01a65cca1fec8466aa44bbac56e53895251892b6355c5e39953f680683ff72e0968867b536c11a33470f8ac74870d996557981711e5d0abc65c671f423ee4b67771055952b54df8934f0b6980779abe207c4f8ce1cf17bbbd90b24d1ff875109366a4270202036a0796146cc8ba70712f98b042b301c5143a6143e01b79b2af3a944100eba87da1725743c370d85894892469c00a95f3866726138c2099b9b6c47ce9b9630222c7656623260d8500b4d7752b6779af5b5b858016057f545175f61477476e3a02aca3d1485e0882b305c9f956908da84ebd8083ed26b8b2b8b50a347a4cda722bdc6ffc2b9043491da64b0fd0a39b7f1550186a0038e07598d6887e6c8c2800288b1c9a45a66233049d77d912b1fb50fc119b0b7455c8d90a3edcb046f2064d401c8f108b833caaae5573a10b9fd1775ab90226d8a32088ac614e9b20737c88dda963d0e77c7c592179b4030881987421a886ac7a422c98b6d51c53d8c1027c84881491994cc84e9b1185b3425758bbb1e305a1103ff6989c633a5697a97e5dcb94e7191d9a47330ecc60acf85083559d507a77f7033965a0859fd6306d27c0ed2b35e7b3444d957a52010ac49a8851952f6061ad551b7c74814606510a0bd19d9ee7998310c74ef507902cc71103134a411f90da122fe72fd14448dea00932977c0f27628f092da3ac07d901c2c3613d22d48ad6376ac1d008c7d19a31623ebc616e4fc3887d68c033bc3ec0e5840d415f6fd2c15355c223da1c45289315cc945aa39ae7498767eb3a6692b2a0ca6e7bc73a5d97644703aba392b5d386849f91bcc7f5691f295a267ac0c1fb84e5e31c94ab020e351ae410840e4198e417b8f397aa33f88114030b07d5c702c6ab64bb7df7276f593ab3d133232c919dbd06b6df756258b25c7132bf03c62077084ce937ce829b0172810b92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b143c4467b507971523509bf97d2bdd733ad9eb94f312e4226d036e8fe827a205333afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +expected_public_key = f72bbedf8059fa51188fe16e54b22f88a59ed8a92d72188f1b687222500dbe642699493dc08c97b6a13e640b51f2173cc8a417be58077803627a7c9bb2a7b96e9596e3d96c74f03926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789e02664ee7552ce5b4c3e16af4299c775a4dc322ab9ee16d65a1298294adef821e94a5119e713175b69f03f941f7c56f565439f1e24f663987d65b00bf899495d5c2f178812ee73387a1627f98029344928e5c9100c50f87cb6f99b27e3ec7635c6b132e0b81229807e4d9903a2c5ab8985ddef435fc8462f67a6c01d2188d731412262392acb98fc49e4cbca7acf522a8d385dff01fd02c4be4b878bff659aac05a8fbbcc1565a53cc36af88b41a1a3a18b04c728b1b66a7698be968db6f0bb00f1665088cdd4e3464e34261e72748705b5b7ea5e4c02289365a56739a4ee34a5dbd5509ec297c12a26ed1116929a8eb4793248bb78a1c21d981733ec874eccd2c9b4bb530c4b6b10e136e764af55059da3da93b79076aea089818210bd076e2a8a49a5032405a857baf295e7868bd82c958c90474bc4403e62b85201061b7bb6ac533e96870ad0d7b9f8e6a835e6c6cb4c8437489448a273e576b91ae8062e411593b4c541098185198e49c0790db516adbc2852a220725a5d50d47333ac058325b61325840634140bfb7af0110b34fb408749998df156668634b775965f05aef99713d1f5bdfc5302337b1c041448f5b09af8c5560076ae90ea3d2dbc39bcbc8e9ad26981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc49199c2c35e35d6107ac61744df910c021591d6df53e4358487f26b4d4060958095fe464ca2703394d885625806106ea31173017f4f0594550bab828993d55628aca5955f61f4e4b316a8aa9971c65813949a16828b5792ad841772aa1b85314527ebc2e6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485b8064fc585ab8c2af6212441a763540f7af3d8a8620c6cf40ba81a914ca28a8265248673d731432ec9c70e083be49816098494e6994b385b509397198e2a50c76a8949c25ecc9849ed45d59c966444313d5f0419abc929b8ba51a2a49589978a0e29c680c07b9cab2be0035a06c18d561b9b0e862a2957d5d41a0a63c4be99c1d50f76ce57862b4f61cb42591f17ab1e85c1ca2dac3f746940c001d64d81dd0889629d60727d5a5fd8ab7549b439d66a30316883da6455dc023e6e702fb4742a82a101f60cd8f3a29d3d88c7e418c3d30803a541d6ce1aedfa540371c846c672753a858b39b5880d69b8d525c6d57522bb6530cd7a4edb7730cf720541454cab59595e8a5d6302249300a6fc2180eb31ba43398a2a18adca92af2a686c20454fa8a1864d73c0b91167b6b4730c2b67c55b425e92c663465b7f7a1d2163f7d7a8a08a962fa0149cf2ba8c4066cae7c0a22a989ddea22a5311ee5d895eea9a5416739f810ad5ac901471a72aa78956b5183b194b26c361219401aefdc49b6ab481be838f85290a0d96060d68e5fc71358a924b95225070c6283b401296698310bce2f1b7c8a531e84f625585429ad3394fc04bcd8a200834cbb9c9b9a8c83601fdcaca281a93f47c6e32c133414ce71f32e60fc52b4c07a1402c3932056fc3323ea2241a6484e6a074676996e5962867a61cdffe8811764953004cc9c3697e78ab5d156cb952b1c53ec674781792ac831d6e20b5b29c3b064520fd5968bb351a401646ae3267522c234a8404b02529da182b473051bea4b971b170d03aa378877fa47bb60f1c1e3519110121bd58b17ae373be2d21fc6d7ab2ee2085f4a194fa7717ec83f6c144e256807aa921c32b843aeda0a5cf85773b77efc579a677816cc998970911152d091f21733dd1c0fab31808f2a3a64fa783efc2e4a252b56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277961e67e555cd6c7c4a630fdd897cf61c9c5779594974088a2b415806b520503ebb416481e87a062582a479b3e05b9413aa2c7af59c5a9c5034722f43032f0d6428f8425f4cda38876ac45ba2137fbc56209823b05abbc00aa9e6a307bb164fe0413311f22be44244aee55268da3135ea5996f7cc3f51856610ca68310dfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_private_key = d809438c90aea78b897a528534fb009d716de8d513d32168a1537489e52255d00f49c424bf5b5db0e15a3a9b9845eccf287776f9700ff5bb7ab9f40ffeab7f148a9633546846b672cda9ab8a37c8f9711b76474e7975ab7e16675a8626f8648b605066a4fb4a5c255a0a39387b03bb7f618c9ed1b37e488d4b7175b593860f6c97d637a2d8761d3b933291b2ccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cab1bb1cb746ab01293a2b2f2638beb06030d476bcd2c335dd5226b7450f8b5b2b130332dc9210640c10daa5faac16c1381c2a0c4aae3174be4faa53ca9cbf29769084715d6f8c163a0185030b0c7c9621336a9875946fbb73bda9774c07615711451f5594a44313878204c291ab7550aaf981409d4d7cbee727ba689400dab7382605f03873f38566421a354b59a3b48bc8f62a09519d932af5800a9a0c6efd5783bd93483a0aaac7853c890c3ba18835d1a2e8f14bd0768cc7d0b951909825c988648f797f5711fbc654380e661bbc41cf89b088e1410f19669aef65fd817564a4a4f40281b5e16a69be2b503495a4b6b680a08a54fe0b80ae668041aa120c7a363e38aaf2156cee293bfd4396dcc503646acb74b9460142e4476807c058d72c9610e3cbb50a29ed7244419c2c258659b3a8a23e7e69a3047298378424b7a12df3cce34f1364732b292b105eee6a487126815bc0013d66fb7099efd4931e4301d570bcf2facba0b433b9a03147242c298052650416651db690ce81c268381032b17c429a8e418b7e2bb63d30b570da588cbc36dc3798c65f81ef05530b9043310e182e88bb3e58356de408898738c9b3c457faca42b9b81ed7c4118869d5153338ef4260006c6be294b528c779bd6c8ffcb16e2aab439d3032b8ac45216282346200cf1c812033a4f9667af842481d807f92245bb322e04343971a656087cca8ce9bd3117013ae816ba745888a4ad51a167a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b4f2879a727028d4a1c61900d0770f15451a01964366d8a6ad1b5bc520392d43bca270ccf9a72df3d68b955c4bed0352b3f78151c4716512097bc92f2cf0a2560923d01358ab1b5f8b7bc687f5c110b04c6512372f119fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494a01c67e232b93080d5df1542dd59f21760a24747e98e26466280c04d1784d9b581b4cabcac1c3dde1ca8e00588e0732f76b99ec844032d99ef65c8a9ef4a661e78a47b0542b3129e850647862132c208cb9b3986eb5b510ea1854300ee966b0d3bc09922260ffc96b894a181a95a41f1bb3acb2572475b3fe8933fe3902c965678b95512289cfbac30a2b159b8f2b3535e40881d81c204cba9080b9a7b23190965eb660754368955c0c7929e9447b92ac78e7867c1b4770596047fa820c03a11caa3c2ba48120e29ad46c289920222c511c9e18343ab20067f926435c6d6b040955f9394601b805e38a751bc8a1853fc05857eae658a8a7cad729373e73253e7728fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ed82b23f4b6796209d51425e9168cb22224f39f069d4bbbb07a395d3633b71c81a238aa549b107530519119262fe4052cab4215647c0c2ca573efbce84881b45279dbb0845dac9ce5ca807666a76c2a18dc4a39a09234095d426ac769dc4d5584d9473705477c2373bcaec3eb1b911e8f9cdc581c2cd330f0a2ca0f937204323447d2328591761e3c093b8dc35249118015cafcf6bbb98626e43eb12f97b12a1c158cd473bba2b3d2aeba488859d64120a668a6be0f30a6d76211c2576be6a95654621eab6541b65c956bc51e0117306873ede094169a956e50c9f453834a6f5b4f4e7bf3d644284ab2057b653d40479cfb63679e2b50e6975dd839100e1888cc35dbc461a7bc248b5b756d10338cf68c4b8ea281493c9c7fb4d1504ac3478ce8cfa7100cd6411fc74bf054d6932a41d234eff8ba54f72b4ebc52ef605cee08358ad5bab7a0966d8b36b2573387c587196a72be1e47132d6b3bb92241e735b47aba99d28797b6382adb0263d6817dbbb71d46a17c43a63748a3f34873d19497c49515fa8b4ae5c588bdacc234f9a74ae67734d14b7f72bbedf8059fa51188fe16e54b22f88a59ed8a92d72188f1b687222500dbe642699493dc08c97b6a13e640b51f2173cc8a417be58077803627a7c9bb2a7b96e9596e3d96c74f03926387f34c448eaf5885eab4a52945333fca41dc4ac4ca83db05a5a5d54789e02664ee7552ce5b4c3e16af4299c775a4dc322ab9ee16d65a1298294adef821e94a5119e713175b69f03f941f7c56f565439f1e24f663987d65b00bf899495d5c2f178812ee73387a1627f98029344928e5c9100c50f87cb6f99b27e3ec7635c6b132e0b81229807e4d9903a2c5ab8985ddef435fc8462f67a6c01d2188d731412262392acb98fc49e4cbca7acf522a8d385dff01fd02c4be4b878bff659aac05a8fbbcc1565a53cc36af88b41a1a3a18b04c728b1b66a7698be968db6f0bb00f1665088cdd4e3464e34261e72748705b5b7ea5e4c02289365a56739a4ee34a5dbd5509ec297c12a26ed1116929a8eb4793248bb78a1c21d981733ec874eccd2c9b4bb530c4b6b10e136e764af55059da3da93b79076aea089818210bd076e2a8a49a5032405a857baf295e7868bd82c958c90474bc4403e62b85201061b7bb6ac533e96870ad0d7b9f8e6a835e6c6cb4c8437489448a273e576b91ae8062e411593b4c541098185198e49c0790db516adbc2852a220725a5d50d47333ac058325b61325840634140bfb7af0110b34fb408749998df156668634b775965f05aef99713d1f5bdfc5302337b1c041448f5b09af8c5560076ae90ea3d2dbc39bcbc8e9ad26981563ec254a5f3d97220ecb6c5e76706ba933766766024839579868ba43b691496f6bc49199c2c35e35d6107ac61744df910c021591d6df53e4358487f26b4d4060958095fe464ca2703394d885625806106ea31173017f4f0594550bab828993d55628aca5955f61f4e4b316a8aa9971c65813949a16828b5792ad841772aa1b85314527ebc2e6d6351deba9429e43e7fb4991fcc98c67aa6f3287a6eb9485b8064fc585ab8c2af6212441a763540f7af3d8a8620c6cf40ba81a914ca28a8265248673d731432ec9c70e083be49816098494e6994b385b509397198e2a50c76a8949c25ecc9849ed45d59c966444313d5f0419abc929b8ba51a2a49589978a0e29c680c07b9cab2be0035a06c18d561b9b0e862a2957d5d41a0a63c4be99c1d50f76ce57862b4f61cb42591f17ab1e85c1ca2dac3f746940c001d64d81dd0889629d60727d5a5fd8ab7549b439d66a30316883da6455dc023e6e702fb4742a82a101f60cd8f3a29d3d88c7e418c3d30803a541d6ce1aedfa540371c846c672753a858b39b5880d69b8d525c6d57522bb6530cd7a4edb7730cf720541454cab59595e8a5d6302249300a6fc2180eb31ba43398a2a18adca92af2a686c20454fa8a1864d73c0b91167b6b4730c2b67c55b425e92c663465b7f7a1d2163f7d7a8a08a962fa0149cf2ba8c4066cae7c0a22a989ddea22a5311ee5d895eea9a5416739f810ad5ac901471a72aa78956b5183b194b26c361219401aefdc49b6ab481be838f85290a0d96060d68e5fc71358a924b95225070c6283b401296698310bce2f1b7c8a531e84f625585429ad3394fc04bcd8a200834cbb9c9b9a8c83601fdcaca281a93f47c6e32c133414ce71f32e60fc52b4c07a1402c3932056fc3323ea2241a6484e6a074676996e5962867a61cdffe8811764953004cc9c3697e78ab5d156cb952b1c53ec674781792ac831d6e20b5b29c3b064520fd5968bb351a401646ae3267522c234a8404b02529da182b473051bea4b971b170d03aa378877fa47bb60f1c1e3519110121bd58b17ae373be2d21fc6d7ab2ee2085f4a194fa7717ec83f6c144e256807aa921c32b843aeda0a5cf85773b77efc579a677816cc998970911152d091f21733dd1c0fab31808f2a3a64fa783efc2e4a252b56548fb38bba8625b9d4a8aa6a57786f1c9e1dc49dd7686399494277961e67e555cd6c7c4a630fdd897cf61c9c5779594974088a2b415806b520503ebb416481e87a062582a479b3e05b9413aa2c7af59c5a9c5034722f43032f0d6428f8425f4cda38876ac45ba2137fbc56209823b05abbc00aa9e6a307bb164fe0413311f22be44244aee55268da3135ea5996f7cc3f51856610ca68310dfc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9369ffbf2275f12c29cbb69f90a8c881721ce39b49dbba550ab93a2c4c94bfc669230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +expected_public_key = b48117f3ab234a4bc2e6b80b05f97f10a508b9ab08c0650fe66185f146b0ef5993629b3f7fb646dc248e0690b77557971f02bafef88a9864c28e885562ea7b54dc217c5521146122aef78cb893a99c1c9621a6b51a43117016a7f2231f2380764dd81162a4433d6ca171062704294030d5a3bb9859a983c6b7f009f130444303932f141f506896fbec852a8a6934e72ad8c038319c58abea4c73319df541ce4086a90976356d001cf6479437b64dbb318f7db813d5034840e23910ec67519c93e9648ebd1b70edc3ac24c983ecc4003cf5b130eb251a6199814c715eb54fcc8ba9cd638a294bc2015c8cd7d28736226863a286dd4c0878345d3885cc4b2acc0ae08a277cc23e397dee84ad6ec2b4d73c520910b4eb4ba447071de01311754060195a37eb701045103b59a94d59131faa1b0a99741bf8b186f44c6f66f76695eca6932647e408966f7ac4b0b8af15f1c4fbe27a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be945113013d02197ba78b0f5f8008ac89b28ad829e5fc2516dbced3192242e074cde7c8e2b11ed1192b25db395f09bfdcec8b1a8671975b692c84714ba3049a636494996143212c54058deb770ba709ceb7659868998d6560c8f4386629331f7fe77dc5f5390443865d1215833c78ff2a6e24e3655ce799f62c3b5f24529c051c28347c3c792fdf8700ec3b6559f8bf6646352d2013bcd704bc2b26c0b8a231acafc7675d0e8a0459770f11d04aa0fa79d6062178ea4beed06057444c4b4a76712201937212de48941f868ff3184a9a700756a59e1297a71c3912cdd40e6f883295d0a62904a4be9350edb4483ee6bd20201d253997d983cacc0a4730a4255824ba9e4b7ca7908ce84a2562ba6db8e38b860671e2654f2c9b669ee9646d683e9f907733423d4b139bbda51e785a86a97103d8e14d645064b6e02a3ac6bd56abbad5cb09f1968fd70a84018692c2866af2b85ef8031b7693444cd1a9ca668bffdc9889053980a88bbbe59c883acad0f00dd7ba954c487b585910a10c95f571c245f0b415261fe348714c288220ea84d8bc524e438f43f29a9d42a8ba8138dfcc264182ae8cd7927d0cd0f5da7c2a321914e84f716836e53025e2ca75c8e34b04092752f1b77e9cb872e742aee71dfe2c1ece8c9fe82bcf56131ee0774076cba525934e21ca0387e43d53624caaacc88af2a59e234e24e262a1201582437656f97cfad4a087c622de1563d2a16758875b03ab514291c7d3ebac7e44304c32712af58b079031993ca79e35146723bcbffc96f16c6ab7975151961f1c3c3fff9a9ec5940da90a99bb2cce3f376cc4d9a417fa715892411b649dea698678936c35123e5ee8ad4cfb2a85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8db9a2e14f49581f106ab14779278a6aaa303ceb5ca7c246b5ac13162a9273a9ac00c745fe6f01598575e5348670bb82d8cd04a11a7753fa7729c89196be39ce7d543e24ab509684256e82825277da24b84d8f95517b55c2a301864b9a13ab809cb0ac7ff3047e58b9091c5b55dd0c23cb1964d8b58dfb80aeca479eef16f43ea66e185b6fc263e081458086585b8150b8239a531936e926ba339b79f18461851982ddb2a3069b235b8f15e8d74aed3571cb4a55067e385f3b53549fc4cf02079b8a41626a0aa52c5647ca634a37588402ca812f870abb94e09c2bf31bbb865dbc2a3f197bd7c679ec436f21684d7773de6cc551d370d75cc6217bc8db75431159aa5308570b173c7e90b6b09c16267b0169677610f57580640a536301d6b6b7c58525b6f853a5aa73a05c766f631c0f1c82f6ae54eac6659f2a37fc364b266cb0fbf8601dc5651daa87d79fa1852d950f29441982a71bdbb74d260c6b75630e3e80643676c4d59960a445b86d5508dba0c41f1516f44aa309a799ca626d4ca8b7fc5cd54c623acc96f15841c85cb1265f5ba3f6754b178a281e8106a23b04744ba248c703f0279cfa055dc3c70b8c68e48dcc84cea9d725b4ba5b628d9ac62899a460c157752366c00aac16e281ffe1233e217202fba0e2bb3cc5c170e1e373fda503a1d75af9e7a57ce113706d833ae662429e2774fdc686dec4a6268093743b718d3cafe703d2c27bf7b902dd1482ff611cedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_private_key = ba45541ce7b3de134e6b17030710bcce09bcdba837f23566dbf1928c99cffcb674cab9c41b3151faa3078177b9126c7973e25687452da075965baa804276859b092d9d4095b5e3a27943776da65262511f62a3aa875b258c7929b502ad6cba00e3b38011c943310bb5cb24791a71bc5a2796d6197192d9594936089d88bfe976058ca16c152193838a3d7306b312f8160df15288f9063514a403acb76be298f5c92d65a90a0bcb28a4f438ea447a9c881808a18a2f5c3c1b876b3ae94ed28478fddc1e98a64fd797a0931cc4a18777e5d481d9e92c0cf2b5f5a58635b368cbc8c25dc733550774c0861795939b74e83a23757c212927805663de14a0fa00cf10f51850dbb4cdd7caabd5c09b2818cc0a09a58169e3827969518e8fc7bc8325b45656861a848347a358ef1155e5d43f7910a738a132c8892977075c9a19c1eb6399f2e7bf1dbab593a907bda509ef5b0de35a222fc951a0829a838591a0441294c35ca0b86be6fc02e1ea1b7d4004e5bcbcaa2a280ef37067d72790bb5d59587e050272ddf8b117286fe80c1bbf078e6d259a9b53bd6ff1b43a86b24adb27bbfa3546c179b8f295726ab768bc7fc8dc2a62715030d93581165f1e4a03d42374a31039d55741c9c49a1c807468cc826f0380b90c9c3f319cf1f73811d674b05c147bb2613ba56365ea04872b9244b236b0d480dd0b47b7797a23286269f97450e13791b205c8aa3310b72f3423b263d93ca320ae1ff04fe6e3bb703a6c4fc17dcfb6341aeb485576b53d1cab71d9049dcc68cf86008bdb6152994e70152f96c8ae4a0819102ba5077b26086b2dc6b04b324a31aeccb372cc18976bb9da42c8eba89640149acc544511546c5dd293c3173ef28ca92b85b86188bc6fc09e2725307a2c3802c6086f922cddc62b5989c5a6846496d2bcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a78824aae4322e1a69dbf64336efc3348e414ecab04010b9f7399310253679b48af3c23961bf345b35172c1d472f9a31274c730373a29154a581631a0916a21259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435124101e5d42ff0848bfe2169a49485c094226ec6994cb50ba9f6476fb2a39522a08145b987593f2fe67a2b2ccb036c4e6540145758c6745a389955ce9744cb8030bd85a838a5904198b318a4d265eea61c70e5a34156ba00a53f05c9be7f1ac214f6a75dc8154eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fed709c350a28a34873ce76f0fc7a4237aaea0804e2d3874d726aec41c3ac8e02706da459c01736b7a5e0936b3abccbebf146350ea2a246c225ba897473817f28c8d6bbb55fe98a48de682a91770edb1bdb190a0efd677a7fc29fc62690668924cb5887f4078179aade85c0dc8e3529862b2760b187b7778a56c6b026769e339aca5f8c948801fddc4acc3bcc7ff548dd9fc12cd7a394c24a7cbe18d3d22ae3b48beb295905b217af384393705107f33b02547822b0a2cb1b57b6fc637e071c0fdba2f87f010d0c81c42db454f5c7be69ac0069c33330bc40532248fd0b90a28908f7471fbcc543fa944038186979c1f5cd147b9f69218509c41c41873e0718d35b8c6c775f1f069bd22339d3c440f6caf9fe91e3d6b97d2a546e09ab4f6cbc2f5c1481eeca81c3a77209425ccb6c6427ab580b80350b468d9c0795441555b3bcf75343ed3966f69ca80bc850663776ad8e36fad9023baf84bfc59668e6567ffb6698fd0b0cf9cbe87462e35b9694303a90b2673a62b85c74664d5055cfee3ad39fa83206024299745cb7c683479399e948ac2254117f491ffb3311d69455bb925e7426d24b697ed44995ee73d9632459fd37facd4cc1859b0c6054cf1fc5c02e1ae82c2cf2ed21ea2322e315a196e825c27b2ca1cd0b93b4b9ce8e4aba0d248460814f5a734346a0577d55e0b680f01fab8c9a859385733db6342dbc16dc4ca42777a7dabeaa136f149666239cee53880ac4267a727920a9ca43c93a3e301a9859e01abcea7f8b2bfaa11cd3728c9c0ba4f7c7c89a466ffa3c5f2330a5ae87265a009b33c74d61562ca0132c55b8abe791b2e59ade002808ee2bb5ebabebc314e2d66b66ad566ef98623b721ab48117f3ab234a4bc2e6b80b05f97f10a508b9ab08c0650fe66185f146b0ef5993629b3f7fb646dc248e0690b77557971f02bafef88a9864c28e885562ea7b54dc217c5521146122aef78cb893a99c1c9621a6b51a43117016a7f2231f2380764dd81162a4433d6ca171062704294030d5a3bb9859a983c6b7f009f130444303932f141f506896fbec852a8a6934e72ad8c038319c58abea4c73319df541ce4086a90976356d001cf6479437b64dbb318f7db813d5034840e23910ec67519c93e9648ebd1b70edc3ac24c983ecc4003cf5b130eb251a6199814c715eb54fcc8ba9cd638a294bc2015c8cd7d28736226863a286dd4c0878345d3885cc4b2acc0ae08a277cc23e397dee84ad6ec2b4d73c520910b4eb4ba447071de01311754060195a37eb701045103b59a94d59131faa1b0a99741bf8b186f44c6f66f76695eca6932647e408966f7ac4b0b8af15f1c4fbe27a2037b6e7fb8f4c6738d1a3aa480a6dded4871e89a9be945113013d02197ba78b0f5f8008ac89b28ad829e5fc2516dbced3192242e074cde7c8e2b11ed1192b25db395f09bfdcec8b1a8671975b692c84714ba3049a636494996143212c54058deb770ba709ceb7659868998d6560c8f4386629331f7fe77dc5f5390443865d1215833c78ff2a6e24e3655ce799f62c3b5f24529c051c28347c3c792fdf8700ec3b6559f8bf6646352d2013bcd704bc2b26c0b8a231acafc7675d0e8a0459770f11d04aa0fa79d6062178ea4beed06057444c4b4a76712201937212de48941f868ff3184a9a700756a59e1297a71c3912cdd40e6f883295d0a62904a4be9350edb4483ee6bd20201d253997d983cacc0a4730a4255824ba9e4b7ca7908ce84a2562ba6db8e38b860671e2654f2c9b669ee9646d683e9f907733423d4b139bbda51e785a86a97103d8e14d645064b6e02a3ac6bd56abbad5cb09f1968fd70a84018692c2866af2b85ef8031b7693444cd1a9ca668bffdc9889053980a88bbbe59c883acad0f00dd7ba954c487b585910a10c95f571c245f0b415261fe348714c288220ea84d8bc524e438f43f29a9d42a8ba8138dfcc264182ae8cd7927d0cd0f5da7c2a321914e84f716836e53025e2ca75c8e34b04092752f1b77e9cb872e742aee71dfe2c1ece8c9fe82bcf56131ee0774076cba525934e21ca0387e43d53624caaacc88af2a59e234e24e262a1201582437656f97cfad4a087c622de1563d2a16758875b03ab514291c7d3ebac7e44304c32712af58b079031993ca79e35146723bcbffc96f16c6ab7975151961f1c3c3fff9a9ec5940da90a99bb2cce3f376cc4d9a417fa715892411b649dea698678936c35123e5ee8ad4cfb2a85868a94b3344426ca65636d0dbbb9b2448faa1345e2f7b8db9a2e14f49581f106ab14779278a6aaa303ceb5ca7c246b5ac13162a9273a9ac00c745fe6f01598575e5348670bb82d8cd04a11a7753fa7729c89196be39ce7d543e24ab509684256e82825277da24b84d8f95517b55c2a301864b9a13ab809cb0ac7ff3047e58b9091c5b55dd0c23cb1964d8b58dfb80aeca479eef16f43ea66e185b6fc263e081458086585b8150b8239a531936e926ba339b79f18461851982ddb2a3069b235b8f15e8d74aed3571cb4a55067e385f3b53549fc4cf02079b8a41626a0aa52c5647ca634a37588402ca812f870abb94e09c2bf31bbb865dbc2a3f197bd7c679ec436f21684d7773de6cc551d370d75cc6217bc8db75431159aa5308570b173c7e90b6b09c16267b0169677610f57580640a536301d6b6b7c58525b6f853a5aa73a05c766f631c0f1c82f6ae54eac6659f2a37fc364b266cb0fbf8601dc5651daa87d79fa1852d950f29441982a71bdbb74d260c6b75630e3e80643676c4d59960a445b86d5508dba0c41f1516f44aa309a799ca626d4ca8b7fc5cd54c623acc96f15841c85cb1265f5ba3f6754b178a281e8106a23b04744ba248c703f0279cfa055dc3c70b8c68e48dcc84cea9d725b4ba5b628d9ac62899a460c157752366c00aac16e281ffe1233e217202fba0e2bb3cc5c170e1e373fda503a1d75af9e7a57ce113706d833ae662429e2774fdc686dec4a6268093743b718d3cafe703d2c27bf7b902dd1482ff611cedf63bac0847ecc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d36945441bbd3f5c241a6d65b510dee6662e2a8f35757b0403dcd375e7a15991a7873c21100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +expected_public_key = 6daccb26429b4e18c04591cef2a49a51f34aa224a4f7e0bdbb1950b5b9bd633a1ceda3c94da93cfce38aa962a45a135a45105c6e2548db96698d581f42ebbb7c4aac8da6805024bbb2b0c45806015db249b4e10f92536495670bbeb0402d0c1be9b01e47a2a77d29cf03647fac3730878c7bddb724f7d8539e31274e20334949a92063634d6c1c0b5a1999460e25259fa91737d2b9a6457588d41041d8d1786ef80ec2951cd0c84bdc57108f02a7aa5297174c7be5a6157693c07a38242f85b79d16260ab37786e67d7d9a77c953b81a2a4b9e01697bf7a714fca3d9904795671d4b99b5ee83765a532624b4004fc6044c1840a4d07d45240251d32fbf922ec329542471037dac809f477fb6ba5b198683443c683cc8494bd1b7bbac7ddfd39f45a10c77433b868c981b7aafbbb2c8f2bc8a6e3134eed7bddd54b9fd1a38dda8a2ad60b4111b10571928c7b55721c527150668a1da383b8606f4e1575ce164dcc911af678a33973c807a159bdc12811b003d68b8edcb12de1614707b555a853290870b5e5b48d7774a9d69a116d13808961164cc0cc38325f49c463e41c043f120af24239c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4554a2ede21cad465be2e3001fc9c955a3b6dca4612d0763299aa8334b28830e996ffb13f7195598c55a704ec9539bcb9a44704c77cc1e9c2a7cd371d46c02a409215333acb076bcb2355acb6c5bec8cb2640c86882342ae3938059a99ae7a281d2b6ade8073d1a90459c04a5db7547b681b007ab996e1a7fd6a030c7b34332854e036b8e99d0369bdaa123a86ab931776e437271a2219af7a4c7b8b78aac0365c78d1de15fae8c4c397c7b6eaa4d02b06f8da7145fab7948b786a78639a4e80299e3c12e5b3847f508c5189d0c735f5841a7f5b34fc7e194f4f20f348475c1d4a3f4e8111c9cc6eb06214c43838b41ccbb6524da5715e5a2644bfaba69b0cbb54935db0379b52668e2b8b84ef5600ef76686bb0651f7c43c1c120e20af9de18aada655d48b375b4a23d21c51e1c3ce9e0131b61c345112b5ca302ca9e183443495da4b309ac898e02c4f70fc7359a57d25778457e70bca8a1c7b444208b00e24da7e0ff89c19190675ab24b605295ba862eb732e4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e08c172467c80ea05262831660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6225b1fee03cfdb599bb024416ca980c8181faf51b421b86f92147e12d04caf335a87fa1dbdb2b0e66c0795cb5f65130adf3bc8ee3bcdff9223cd74ca9c4a8544208b31cbc7a05b21392b0ee03b9abcca42cef8b5448482d8d8013ac221ae01436cab30e1c126f6f80af46baeb4a828f54735b5513c8f11228ec2af7d854d84e3688799ce24c8454e326fd0f52fae773ca5d408568551de89cb85265115092b960ab9792ab8612c012231921b6c697bac6bf53174ac50a6ea2ab3f48b532af51a6f6939d1ba14b694c149b5503f3320f438b731a59b4c22810d1196ed4a90eef2968d1ccd92327b37866abac1c24cf0c2b2228d0e41a3a1ec6a4227a36218b6437b5023e22d43f04b712c2c6665bd2deb160aa95199146618cc1ebefca7691248acb7c549cb66cdd59f5c4c0470205791c742fcaab677f966f746721f58846d1ab2fbc11b6f2978ddd282730402deb863ca1a7e224cccaa2b34f788987520c9da9c0c328cad6dfb46a920bf8ce22f4d265426cbafb31023b7e748252561cd678bb10218d4e5cda45488c4b2c1b2cc73c5c163da9467f02b5ceb4a5ecd136a2b518470719114d1c310a688e46bb80dc38dca1a092d36a3edd7c4c6d37074692e266a0f5fb0501e9791f3f90cdd93386c05c93896b950c7681f0abf8a044ab1227b68210c169b6057528315ca5fab7ab2c9dc7743d8943c997801a01eb2d9a195d2c6a8710fefac2e60702b68523667650e6616cc0b7b5bc50809d1d45e1673be8dc435b7355b0a26728205ae8713be0372cca8169521e574fbd18c37ea3cb6f02aa5c82a5834819254077e1670047997863a5ec7692bc26cacfd8c346290564fb27a50816f2d592277f56167027fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196e92ed698157064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_private_key = 2d80a415a1b29961459e396204e5b5e65540a2a9ae9cd52d867a9e20952fc7565b66151653448353697b09723b17e3b1ef375a3e260a5869b579883fd1eb3a06da5c11e493f4cc9d18381856fb2c36223e7214ad78a178b2153dcde882451776478a4e06b392ce9b9d0310a5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc4568682ec2f5506f59742601c46db34efb9665b5815574518ff677be1c0991b644b5931b112220c6eee10c37c19316156bcbf354fb661635e42f6b26b07f9552d7b1a65d51c7eb6a132034bd755674dfc14345aa72acbb85d4724b2ba14925421e570543ae904f9bc4016bc0389fb9922cb12a393a24df219290dc506e501003c0ae8cbbc685a25a91147265207f93f190b12baebe7cc7edec476553762ea45e48694ddd172b6787b7d9719e89d77563c9c2ccb77caeb23d7aa9181b82b6cba09aef1851235c7986194c8322280b4192b94262fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391a314555674cf415292055bb39319dcaa7b07230204c068028b3ae7a7223df112032d60edd1b6b52ea1ed13b86231a1efb2969a691cef0d219835a44e907bb0cd2ce6da1442af1460f2ab882959e0862bccfcc6e3fc2bdb5eb673b218d6e9c5dc6461d8796945b614c81a68f9cf381d256bc1e63285141814077af5f54c2c6b487dd29cdb1d2ce08f09122d09632ab823cb00d86a57f8933743f347c203894d0043f5692a6e12283abfa1b98b39c6d638132ea4b94644e89a0adc35816be01a408f752b3215029d7661b554bd39abaa906af32f877cd4b28bcc217825ac897d06a4c233462fba602a81321db93279a19bf44131b86035db3c4ca911f1fa30146f9be0333650c3c24a5c85bf5e252413853defb040f8a16f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd5b18df1d947e171272ec5aa1137ccbe50ae73ecc106250c0392a41a73a4861acea19257be33cef406b7eac1796f605a709a4bc06bbe40867966e830e8aac19af626a4642a8447276f09cfba6486564079e1aa38d7e179d9634e3398b743a1812f02818e979b4434a4516c2c77672600d5b7d3bb6d7e3253189c3694120dbe2519c62c80558ac1d522855682962df611febc9f33fa27a0787501a42802863b5cdcc6aa81b964cc2c9b8081b63750a6358db5566a0d3229d2989e98199855a2448f54688ed2487b816f5cd651206350fbbb5cdd995a9db37b089caa57ab0deddc9392ea1c0f99031a42c350cab7b6f54c1e4acdd0e28d7975a188502fef055feb5889bf87929b6006562626335b05edfc544f10cbd927ab3c4c9e806700349b9a0099801d5948cff3bf0977a9691a25ac880d593a36d1e5436eab078bd9a6bf25bc3d6b5bdfa02aab06ab5842c440e40d430aad9311015a8767417b233fa8cfc64914533031ab39b845a3c50ce00ba0f1a586053768ea48293044f3a831b456320600404761c7e826a0b111ae37db49b31bb3e9389bd3e354f08879906996df2036ac49b9c773af5fec5375519ae7b8c61ce475ac544d13a5b421b8a686251b6d1c64f8a353406248b0430c8a3a308b600d0c9506d6509aac9a46093564eaa957b62b0b18078325ab1e847521dca74f5f212b013ab90693c3725729a4888c50533a27a83a436a627a3c1e0be10e35d1900791cc598413a818bc2f58687a502fc5f747ad365dd3348b3f96a9072c521923a513540ac402aabd74a5b364912ec36260235162492ebc96bce5c8a718e124c0669da4d0080117b07680ccfdc79ef10229cb8388460bbe664255513c71bc2243a2cc2a1122218581cc540514ad54365696245cd98ecd445653766847a03794959f15ccced05863e4656bf2571ce6445e9393c95ba11e5de102c358517f7672c0f26a34d8c7bbba5ce9abad9c8b4a6e9788b82bbd399838e4e138c7c1619ca8988a05caacf14a6be164c569444d49911525398d0a460d257e61e6b8e0d2614aa0b55ac0435f34493c298ad719a9900b94abc08acba78f42195637a464fc180013bb081bd7a4a8f66909557e85784780c589aeca24402125b661a068f81d046716e5b5072d754a6878004ac9423092a3e051521caabe98e955c093ad95d74157918960157dd5383702f3adfc65436daccb26429b4e18c04591cef2a49a51f34aa224a4f7e0bdbb1950b5b9bd633a1ceda3c94da93cfce38aa962a45a135a45105c6e2548db96698d581f42ebbb7c4aac8da6805024bbb2b0c45806015db249b4e10f92536495670bbeb0402d0c1be9b01e47a2a77d29cf03647fac3730878c7bddb724f7d8539e31274e20334949a92063634d6c1c0b5a1999460e25259fa91737d2b9a6457588d41041d8d1786ef80ec2951cd0c84bdc57108f02a7aa5297174c7be5a6157693c07a38242f85b79d16260ab37786e67d7d9a77c953b81a2a4b9e01697bf7a714fca3d9904795671d4b99b5ee83765a532624b4004fc6044c1840a4d07d45240251d32fbf922ec329542471037dac809f477fb6ba5b198683443c683cc8494bd1b7bbac7ddfd39f45a10c77433b868c981b7aafbbb2c8f2bc8a6e3134eed7bddd54b9fd1a38dda8a2ad60b4111b10571928c7b55721c527150668a1da383b8606f4e1575ce164dcc911af678a33973c807a159bdc12811b003d68b8edcb12de1614707b555a853290870b5e5b48d7774a9d69a116d13808961164cc0cc38325f49c463e41c043f120af24239c36abb899a3d37857db6548bac59b40e7b233dbaf859ab4554a2ede21cad465be2e3001fc9c955a3b6dca4612d0763299aa8334b28830e996ffb13f7195598c55a704ec9539bcb9a44704c77cc1e9c2a7cd371d46c02a409215333acb076bcb2355acb6c5bec8cb2640c86882342ae3938059a99ae7a281d2b6ade8073d1a90459c04a5db7547b681b007ab996e1a7fd6a030c7b34332854e036b8e99d0369bdaa123a86ab931776e437271a2219af7a4c7b8b78aac0365c78d1de15fae8c4c397c7b6eaa4d02b06f8da7145fab7948b786a78639a4e80299e3c12e5b3847f508c5189d0c735f5841a7f5b34fc7e194f4f20f348475c1d4a3f4e8111c9cc6eb06214c43838b41ccbb6524da5715e5a2644bfaba69b0cbb54935db0379b52668e2b8b84ef5600ef76686bb0651f7c43c1c120e20af9de18aada655d48b375b4a23d21c51e1c3ce9e0131b61c345112b5ca302ca9e183443495da4b309ac898e02c4f70fc7359a57d25778457e70bca8a1c7b444208b00e24da7e0ff89c19190675ab24b605295ba862eb732e4a36640b28bff1cbcdcfa8cbe9f9add36b71b3268c116b3e08c172467c80ea05262831660bf35a7d945a8264b228793ef0284b724480b3b54451a7bd9505b6225b1fee03cfdb599bb024416ca980c8181faf51b421b86f92147e12d04caf335a87fa1dbdb2b0e66c0795cb5f65130adf3bc8ee3bcdff9223cd74ca9c4a8544208b31cbc7a05b21392b0ee03b9abcca42cef8b5448482d8d8013ac221ae01436cab30e1c126f6f80af46baeb4a828f54735b5513c8f11228ec2af7d854d84e3688799ce24c8454e326fd0f52fae773ca5d408568551de89cb85265115092b960ab9792ab8612c012231921b6c697bac6bf53174ac50a6ea2ab3f48b532af51a6f6939d1ba14b694c149b5503f3320f438b731a59b4c22810d1196ed4a90eef2968d1ccd92327b37866abac1c24cf0c2b2228d0e41a3a1ec6a4227a36218b6437b5023e22d43f04b712c2c6665bd2deb160aa95199146618cc1ebefca7691248acb7c549cb66cdd59f5c4c0470205791c742fcaab677f966f746721f58846d1ab2fbc11b6f2978ddd282730402deb863ca1a7e224cccaa2b34f788987520c9da9c0c328cad6dfb46a920bf8ce22f4d265426cbafb31023b7e748252561cd678bb10218d4e5cda45488c4b2c1b2cc73c5c163da9467f02b5ceb4a5ecd136a2b518470719114d1c310a688e46bb80dc38dca1a092d36a3edd7c4c6d37074692e266a0f5fb0501e9791f3f90cdd93386c05c93896b950c7681f0abf8a044ab1227b68210c169b6057528315ca5fab7ab2c9dc7743d8943c997801a01eb2d9a195d2c6a8710fefac2e60702b68523667650e6616cc0b7b5bc50809d1d45e1673be8dc435b7355b0a26728205ae8713be0372cca8169521e574fbd18c37ea3cb6f02aa5c82a5834819254077e1670047997863a5ec7692bc26cacfd8c346290564fb27a50816f2d592277f56167027fdf376a2ea97be79466a3b86b01286fe54444bbc4c4f32460b2936196e92ed698157064cc073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb290261ff6a1d2fabc75feab002d16cdc44bdbdd0967c728ebef0e9814c60b5e57a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +expected_public_key = a8102cf7e4cef04582be990060177980606196d12ea824ca65d485783a32e42a4e20d41806e8ae1c51544c63c3156a42bd8abe55e36be37c6be6a51eacf02274eabb03f64c4ddba2a6806cce943cf338b09f50c5123c4083446802456ce85248daac7e5d9637a541c755b03300b43c4da96164c6c42c3910d36522e34895055c43847459451b8022d39a2c287ffb85c8459c31c2d183f98c684a959b2cd0a224cbb38713c4034a6668e14cac3c8f9d1b95ee6251f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ee51c62d244502a3a044f4c95fdb42a7fa0300d079ceaaab0f5720a1ba852fe7148d4a1642d1330942c81b27882c631c3ca3758f56b7718475404ba20cb8b436bcc1116690380507d02c63e62ac58f551072cca75a761f237b5abff58b2016242fb910f24baaeaa47dbf010600881ffd228aaef714c65b496795bce329819418c26321b5c73cb603d15ffa162901f386e9e815940bb5703477a996b313b50ba05a1d41ab65f233abbec534c106224c792a3dc14688332a8313408510386253c7eb076711ec35f6f929c301422192b3f611b36b97aff38a94b00764e9d89f38072ccd6b978e1a31e391cdb2cb3f9e344ba947a73db91891b944de4935d48a5663f85c94ba6ed8a3026c278d645b7b593702733865f12a3ceda3be2787a1efc2a2fc2211f405c3ad1c8c46257059e6cb43f36ccfe6231b730040849233d03b7e90076a7792f865467b6548e541bfaf5b7c3e6059cb426cd263494c641bdbc7616aa8348c6335d42719c0e79ae52931a119856c168897d48dcb44242c505c535698a35cbaa9f80a8145927af6653d31977e827625e3ba18ab7af3621df248434c2cc5e9324f34c60e1ff1253b4904b1952bb7e16dd979c03541a6be9bca09632120aaad6c457942b0077ff01b6808af3fb82d390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399e2255e030833485bc69c5c94cc48bbfe7bae3754bb49a2fc1a15db012be519ac8802a5cd005a6adc31abe237d9c2924134235db04b78c96876b084d41c62aca10008237a6f0c12600fd134ac59808418fde238aae358e34c1153842a31cb030bd97ab2cab83f74164358a1a077591c356162d53970ad65e21a994123c4000277d72ccbd0d712026217de9054fe9b38c61fa2c80871ba83a88bc98105e693a15f2213eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7a90a770717b14b40673591e986a1dbac4a87b111ad2854899808de206e6a768770e84023931bd4d996238430859a6f7628964e4465e5db7a9f5a0a77272ffa95a9ae759d47e1885ae6a4e3e78493a25153387f008a74ece68a67a8224e19209f20770bf4c8cb15cc39dc4147549c8cc599b760700db4591b284905562afe554658a07ff22c8645e29006d331bf09936085c4e7c345e2993a7332c9b40124d375c40e266a251002eb03b5dab50760972b7e9785dd585df7c6488ce9218c0171db28a99ff7a557c34936780fe9aa78bb395885085e0243887ffb27030393d925cdeb2a2cc3365ea95b5bcbe4b0bac9bb32e1a90b009de0f6be8ebb3e684514d2425f3f1688f54056f41c8e364b5e89859478349c793a70982818c28a245f690057095b320b2773206a3a856445290ea1636f5029bce3d8baeef0a73f912e110570817bc66d9b8dfab95da8b270898b6e30f28418ac5233a954f05009c2bbac3cfbabd0db906188abe7b72cce5001496360758cb477dc2ec02a590621c93b9067ed346378c419ab634d95267def3148a594be088bc349ec9669e4bba474c4aca165e664986c34a0dfc5c5c4781a61063f10f2c175693b5b5cb7c9b74442050f5d9421e6900cefe35bd942b49e469787471f43b35ef0c86340235525d50904263b2cc052757b01b75414027c9d02db50b4e47e5cb19f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5bb1a9788565de9455be321b50a39105a33e60a9533b506581d03459696192c08626009e723b228df1cac15c645db16faf697a7df68d71a56cf263639aa0185ed25bae84551c60205fe6b98d9328da3604d8d1c70d84c9ad68cbf266baeb8c6b3b9716ee50a8fb5a25bb6a32f0f971369601f9552a52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_private_key = ca481db6775f3d276a56ca0e60ca79be147e63b6898f4b814c69a06f55111c9824cbc1c109a01a7baa259da651a1a51d60bb358432550bc1aa1cf3656e0667d726c69a39ae564bb99162c824634b8b8a706d82175bd9657ec09a308b51a3b429822667a5135fe4350a8b3ca10e8b03b6da0bbd616ceec0a08476909c6182ef0314b284cc3f43c337307facf7b617348779d7493ae0a25d415124bc5d9134182169238cea1a46a3001a8165713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcc3032e4c2f1e92841d73859c76cfbe245193816d87c12bb3f12763174997760d6887a429a37f78c32cc1ac8facc587aa235821c254a2341b7c6bcf8b52c908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953554021af73c585b6ef248c07ed23116baa18c845571823d25cbae0af57d4f6ab2473b5919cbabdd7b4cccc1be89150cfc585953389172590edd61c3885446b500495247aed57a9fb1140ceb6b29f7f9a9f524106d8cada3432c12468f9bfb9a50b920cde85654c25249350f6760293ddaa28c771963497c4c5230c05862a4391330f54cadc3b0c92b9798f5bdf8b21016725ac8f565466464c2033872684608111248fccf94c61337eb6b1a9017e342c29eb2b148936119797fdb2757bef51a9a2601a00c6f0547b1831b1ca1118cd2e1cdd601a0b491c588cb5ed88ac36ae183848b9f87264cc5b020b2e965e5b89ff74c58cd2b338177bf1350afda9a74516a5845381e5fe132b4089506e8cde6346fcc760759592345927c5c6a97045b0ad3973e806778759b35988953c80b3e7574b7caa225c744372ee3042e07cce978a3f964395d40176aab7905a4bba98250f594c5a96bac41851e09f897df0376a89516040c1f8fccb93d44ab474c56913826c9e2171ef67510b53eb31153fc028b3625aa7a353bbe79cc76d393e209115dd00b5d6c98f80101705544604351cdb87715618343bc3fa227c1e9fa1ea3989390b02c59ec9174e5165239427592a2d973774ca62dbd9410164bcfd95834c11621f7da54dc55c44c594785fb0016448f2cc39a05e01d8581658a2410caa630347c3f0f6c86f344816bd13b3a04313a730f2de9bb50659b642353f6463d2e2a1a78b722287616cdc266b01098b3544632152db3b23938d67c63e51949496e13182326d5b7d70b81d90cc6c5d84d4e5907833a7a76d3850ac4993a696c4b210dcf352a32b4c83dc9114305308129bb4ff73a91d733303bca92fc0083d95d32ca54557a6ff3c42c2bab46ff913e1d39ba3f6092e30ab47f9985c7c439448c92b245259d388e291c04de427f378011ca983b21b2ba8bea9d6eb36001ac4fa5061ee1670066f9252524848973782774cfa795a2285a2669515d4fda7093bc54439753fb6b4e6b781eeff574155b2438e074b332417d751eab1ba1475436e8fc1b670c3928a3553d2bcfd1a59c46ea2542884f91f98a38d42ecc026ebcf91258acc99a50ae1edc88b90c98b74c3961b70759f39b3c20175fa80386376cde2b66dff213151b800921ab6932b45b720932a540c79cca0eaca0a9d5bc841c3acf3c08096c0446326114f05cb09745ebb986ddb76913faa6d5f411cfe987b5808d5b525759f50742969136a5089b060ddcc66c93aa7f94ea179ea896834bcb30147effd42753c9528643b5026b5bcf02aa1ac9be4ac5525f734fc1049f93963fa046b0ffa7647fcc19ccd2a89fe6582bfbcd70cab789e0ba67c6387462bd1dc35302b29ab65b53ee8cac6f7b5cf257b437819fd9ac402019563ed5104de97953453bb139835c67415515aedb810455855e63b5a442940d1ab85d8c80703141c9bb0a6ccaa6949a797bc0658f56065822c52eb14aabbea75c434a22409578f2b695864803c32649d9068857bc4ccf492ddbb216cd73bebfb517235218c6da930f26a1f7353dc2c2bca039b5eba4cd9fb3531523b1d5200c3c822c135b03126154699420e036ba827c849b285b28b81eaa64adf41b33895286ee8410beaa4a1c637617718f26b3a206593571160cff48437b5187bfd5830ebca6d2204584f822703075a40076b403aac5aa32da5a8e2ac0160fc8a5b5e871478c30d523c9f1967b4fe4aea55976fa803568c6863bd50c7b0756eac8ae8da498a8102cf7e4cef04582be990060177980606196d12ea824ca65d485783a32e42a4e20d41806e8ae1c51544c63c3156a42bd8abe55e36be37c6be6a51eacf02274eabb03f64c4ddba2a6806cce943cf338b09f50c5123c4083446802456ce85248daac7e5d9637a541c755b03300b43c4da96164c6c42c3910d36522e34895055c43847459451b8022d39a2c287ffb85c8459c31c2d183f98c684a959b2cd0a224cbb38713c4034a6668e14cac3c8f9d1b95ee6251f285835444ae0ca4bc2b9aa40ccc564f7943e9bb697f76475c5ab3ef3878ee51c62d244502a3a044f4c95fdb42a7fa0300d079ceaaab0f5720a1ba852fe7148d4a1642d1330942c81b27882c631c3ca3758f56b7718475404ba20cb8b436bcc1116690380507d02c63e62ac58f551072cca75a761f237b5abff58b2016242fb910f24baaeaa47dbf010600881ffd228aaef714c65b496795bce329819418c26321b5c73cb603d15ffa162901f386e9e815940bb5703477a996b313b50ba05a1d41ab65f233abbec534c106224c792a3dc14688332a8313408510386253c7eb076711ec35f6f929c301422192b3f611b36b97aff38a94b00764e9d89f38072ccd6b978e1a31e391cdb2cb3f9e344ba947a73db91891b944de4935d48a5663f85c94ba6ed8a3026c278d645b7b593702733865f12a3ceda3be2787a1efc2a2fc2211f405c3ad1c8c46257059e6cb43f36ccfe6231b730040849233d03b7e90076a7792f865467b6548e541bfaf5b7c3e6059cb426cd263494c641bdbc7616aa8348c6335d42719c0e79ae52931a119856c168897d48dcb44242c505c535698a35cbaa9f80a8145927af6653d31977e827625e3ba18ab7af3621df248434c2cc5e9324f34c60e1ff1253b4904b1952bb7e16dd979c03541a6be9bca09632120aaad6c457942b0077ff01b6808af3fb82d390573bd666f4b89a44d4b80a49b86470981614bc6b0e3cad5ea399e2255e030833485bc69c5c94cc48bbfe7bae3754bb49a2fc1a15db012be519ac8802a5cd005a6adc31abe237d9c2924134235db04b78c96876b084d41c62aca10008237a6f0c12600fd134ac59808418fde238aae358e34c1153842a31cb030bd97ab2cab83f74164358a1a077591c356162d53970ad65e21a994123c4000277d72ccbd0d712026217de9054fe9b38c61fa2c80871ba83a88bc98105e693a15f2213eb957cb276691d4ab70c9b3ec0b3e4e846979c375aaf9b13e075a83267ba7a90a770717b14b40673591e986a1dbac4a87b111ad2854899808de206e6a768770e84023931bd4d996238430859a6f7628964e4465e5db7a9f5a0a77272ffa95a9ae759d47e1885ae6a4e3e78493a25153387f008a74ece68a67a8224e19209f20770bf4c8cb15cc39dc4147549c8cc599b760700db4591b284905562afe554658a07ff22c8645e29006d331bf09936085c4e7c345e2993a7332c9b40124d375c40e266a251002eb03b5dab50760972b7e9785dd585df7c6488ce9218c0171db28a99ff7a557c34936780fe9aa78bb395885085e0243887ffb27030393d925cdeb2a2cc3365ea95b5bcbe4b0bac9bb32e1a90b009de0f6be8ebb3e684514d2425f3f1688f54056f41c8e364b5e89859478349c793a70982818c28a245f690057095b320b2773206a3a856445290ea1636f5029bce3d8baeef0a73f912e110570817bc66d9b8dfab95da8b270898b6e30f28418ac5233a954f05009c2bbac3cfbabd0db906188abe7b72cce5001496360758cb477dc2ec02a590621c93b9067ed346378c419ab634d95267def3148a594be088bc349ec9669e4bba474c4aca165e664986c34a0dfc5c5c4781a61063f10f2c175693b5b5cb7c9b74442050f5d9421e6900cefe35bd942b49e469787471f43b35ef0c86340235525d50904263b2cc052757b01b75414027c9d02db50b4e47e5cb19f6dcb5aa93b3e4874740ce7b99c5a4387d392f686a215fc5b5bb1a9788565de9455be321b50a39105a33e60a9533b506581d03459696192c08626009e723b228df1cac15c645db16faf697a7df68d71a56cf263639aa0185ed25bae84551c60205fe6b98d9328da3604d8d1c70d84c9ad68cbf266baeb8c6b3b9716ee50a8fb5a25bb6a32f0f971369601f9552a52367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d7ffefda144195d79e581c91cdf0247f4346e811f890f54f25226b4ab835871a48f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +expected_public_key = 9f711edcc2ab20e136f9412f7151bcf330987bcc5332408392075a25c27e3747c65b5206a91483eb501b48cb5e07d501579b5093255d5e565cf5ca6247064ddaeb7e909a190da61348365c1c508820208ba282b5d48199d7a947ce9946f633bae9d24eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc7419d9c67af522a744a506e73ccc5afc2cf27663e813bab0c82c6c64023fd4cbb5b74d6d5bada2a33ea3f407cf5239fdf56bcbb455f39b9d69813662281947659534f9443f84266937c1000d8cccc430d5f9821126b9b28226d8a8c1d7a247e2d0cfce23c52c3a2c92fbbc45a86394500f7d984c9103bb77030b41b6c885b1ca1c8b1107878069d2bcc23b52a38651c8090f3cfb023826cb84089809e9abdf107e0b261a8ccb3cb8e10434acc40312ae18b93b89323c3a7676d0827beae3b4e7407827579efe5750c47a322bf76851a762caf62cc64370742ac715f182c4e6a77f47c5f23644f42010fc029c49c538c9b821c7761c1d2c27d7096c9f66ac8801660beb39cfd23e531603c7145d61668a612b3406d16feeb67bc5578bb972147fbc5e3f14059f55c8941177cf24910d1c94f1380f2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecda81133a299fbca37b4a69ad509ba44403ae3e5b2cf4277c8d22b68fc61f5e105dbd8c31f99609ea2770058352b81836b473ebe95c9cea90aeb682ca81b3e70508bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d3270406e5b4589f5401261b790cb02219636ad9c65ea5c48ce79c2cf4758db9bbb55e003e0c64f9b025ddaf1a341f8c2f26593adb9af185915c0489c77f1038abb9802ec812885af603267b7457210f5a00c917039b1b8e1bcbdb8b8b3ca9418d27ca6e96644f7090322993797a54bcb13cf59428d24d499c6f631e8694c50389496c6454fc34aec2677ebe05a0d61cb7ac553e2017c93d7183f06cf461331073786712a2566230f191c8169a1bba3a968a44a3fde764a0b5724e74615f3cc0f819616bbb21055d85f0fc40c667048fec26fe98b901b67a2923c57e17ccd2ed20f8c3731f10b58b7e9234c4151f6f4174fe6216f5aabfcd3b634122896a156bcc0ce93f41a8a25cd825334b53269881a682d8447975b45e839b8fc54b53f8c70a5aa9c786113ffa708ddd5070b841b58d25820fb6e4d8121ccd016b9601dbbfa4116e1aa9f904dfb5ac2b4d607f43a3961161e02092b9233c75b7020d5ab4bd7e3abc3b679c6d003a6a072f0038983677f606ab976474d8616a5dad0c15ebc10986b9be9f19df7c740fd1198adcc019d43766a847f05fb5cd7c16a6215a0dc251c894ac585a5b530e2611c839e98786fc5d1c1b0817da7c20dfafbc67f62bbc872cfdc153d83f328814abdb5f7babdcbb125298127a83bdfc503d6a8a2359136225b2bbd9baa2a11050774924b8662bcfc608848840cdba8f5d72fa3876ea79784e4784860047915c8922c96bd8f625d56729b96d88c3dba9eb3aa308a7940e90147c9110770f712cfc81224f36fa61c1225ca7a653c5ab8d0b4327c014ec580b9b347d0403c235b25cd88c992582d44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f6fa1f9e8c34d46a391e80bdd48691a930b3b0dace1b6b4b90b948794c14ec7b767ea6b2161702f9f5cf7336badbd2cd5bbc114f7b84d73a24e0049c03f83fc60b618ee23bfc5a286751970bc37b47432f982101e8fcc3ce01089d5898a46baca7265f05e4027ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedce0373a39b545738371499e3b7c88d20179434082ca235bdfa7701624a09b20bc65a10dac15c6c14268fc73be9d7a2f6556044c49a2006403848a726e767d2713be1dd04828da143df7860a9253566c9932fa54c9561ef5a26d990c308cb8a65ec8ced7181371a517c16a28ee9989f9d5acd50c8ba7085e95c03de98c978999c37195356dfb2e1da0768647c2e4ca6ae1d6bda251103ed17482cb0ce78ba17c69848475835a0c2e9d08b27bb220185a7ca40713aaa70068f75140c37d259150e6b4581670a6f8423a5979645309b7b0ebb0e911a68e46c48b150552f3093d425761196378863c431605ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_private_key = 90d7129b79c095b3063f53058a4baa74c262a99c822894254a050409215fe67773c26c7a6dcc739d8406a6055b388204604c7b065c0cdccc16fa880858a36d6200c6cec473bf81b245e09c6e5a55a8d8314334c23dc14fd6a9c011a2ca93753afa8609320b1d01fb9a2a4263ddeab8d5a00c40346b8f84afc7b945f521321103a5219b533f52bee42256edd1b9a526013a00ce07d44ebfd66c0bb67775d1acde4aadb7c98731931e54f5c458264894971df5d0ccd93817bb77a2e7d29ce47aba205c0971f34096280cc725a3c22a4ee24a9938cc2fcd9a670272a463c852efc04388ca8ce86a8e9f63273aa208610c2274709c55922ad371c197741af0526218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0ea2075bc25b797d82a8e0385ef1094d0a2b1731624308487991a7164d8a507f2390f354b4fa3a225d5a46463145ebb57b98724f1d3cabf11ad4fdc00bfa267d8f3107ceb7da37c060aa23e247c28ad0069d30681e37807117ab841f23548caa02212afbc1bc54297202fa549def55ddeb5ba4d10ace2650511366ebe9c1d61fa9d5574c86c0714aa523cdf946e1fd259148a7e2ab5c21884314e3b8082bc210b5209ccb6b95eaa2ef62203a0b707bf9c5db1a155169b07d41c0edb9709744caaa36622f189773ad7a59dc142317454d9c81d55d1c637876f104b6836a6842b87174290125505461eea77d63a8dad03c7941b69d7f66e434922e13a8182fcc35e51c9ce81978e35818504cb32e4a6dfc777227a5484409a38b2a1e2243110e84d024b1fe0e0bb36d4aac0622152599fefa177b294bece391d47553983e420de5462c72ab588b2934680a399ac40ef35a5e8819458e0a7bed1afbb29a446ecbcd4e45a50176ee201526e314cde085afda30226039ceb41a14d87256bf566db30ac77acb80b29b1f9d602e919707c96863304372a353771e1ce994241a12369fbf42bcb4315592724cd5085a589b1b4ca46dc49cd65a1247178151e455741c8b5d7c9cafcb75bf27a5b4ed05b22e932b1e3bfb0c93248400e5485486e0c39fd5ccec680c78e6137be96823deca37c6306d31c9142fc03ec540ac0120ebbe9bd5237583e1972d0c4676708ad35b559fb89bd872428a3e0504350451dd65f58bcb292c0ba437394dae55e6df13a8f41827939016a081935d1788c4807a53a011b89528fb60f386632e725b163e83e105324c3914f26f389dac199a926a25a02624d9a530bf0afafa4c5ffe6a5ef9422e422019ff337d1bc2fe16a07d9a046d183137d477dda378e17a95fc7e02ecddc0d551724a4f36ee7648c9aa771bd15ae29b7259abb63d0983917156ede6557be445735ec539b2199f9816c562842627cc83bcaa659075f5179abdd1a7056d27f7dd96a6813a940a9321cfb1946e95c16836ef028106bc26a3ee450d8e569eeb23b70722bcbf828821648b1668e6e47869afb16c0e4b827c4cec3c4c9948a6c7f874968dc80160a811cd06d58a885d033210341a6f7907f53a82c98468f6bdb7cc7a60107973db0e70f9a387673234d6665019676215ee4597c65a13a2636cee74266f373a4e48bb1db019bf44ebfb0a509e4bdd324314736292de1566f165449c3b618c53c0e7468a801b962ca60d6834276ba3073f725e800a39668bb515b73bb2b055fc55aa3099f4c2b12e027333df63567043b5e81a53f7993ffea69bf0927bad9a6e56cca6f96cad9fc434dd1aa6f2814171cc8b064000bb36931f955858510e5a951d8f3728b2b276962254d061ccec6727d758fa0944246a70d053021ccdb9710c046f5888bb1e0c75455a09394090d0144578053d46819fca8b923227cf36c5d874bb43b34463db3a502b6cfc0b38415f413dda5a1aeda6faeb55269fc2566940615f714ac0883f0cc74645594c17b6027c198a368a608d50258eb75dc00c793912e133290e7954604629de990808cf8c1b7f0795d6cc62892127229579d2600b8b17a16ca7fa2b389ecac698ad722779ba264c1027e39ad6a7c952ad9224b555344235282a6b6a0711fd854740a6a54a9728ae504764f943b7dc92703c03914cc0c6e9376aabb4cf52c00dcc211cdf81ede889529d06ca404a08b719e35176f86c2aec7e40d1210169cc6a09f711edcc2ab20e136f9412f7151bcf330987bcc5332408392075a25c27e3747c65b5206a91483eb501b48cb5e07d501579b5093255d5e565cf5ca6247064ddaeb7e909a190da61348365c1c508820208ba282b5d48199d7a947ce9946f633bae9d24eb77680ed38b46379bc96b87f3de694e4c759375aaba76981494ba5cc7419d9c67af522a744a506e73ccc5afc2cf27663e813bab0c82c6c64023fd4cbb5b74d6d5bada2a33ea3f407cf5239fdf56bcbb455f39b9d69813662281947659534f9443f84266937c1000d8cccc430d5f9821126b9b28226d8a8c1d7a247e2d0cfce23c52c3a2c92fbbc45a86394500f7d984c9103bb77030b41b6c885b1ca1c8b1107878069d2bcc23b52a38651c8090f3cfb023826cb84089809e9abdf107e0b261a8ccb3cb8e10434acc40312ae18b93b89323c3a7676d0827beae3b4e7407827579efe5750c47a322bf76851a762caf62cc64370742ac715f182c4e6a77f47c5f23644f42010fc029c49c538c9b821c7761c1d2c27d7096c9f66ac8801660beb39cfd23e531603c7145d61668a612b3406d16feeb67bc5578bb972147fbc5e3f14059f55c8941177cf24910d1c94f1380f2ae449f9f56a8b87a8425a9eb73b62979c8c6b9894d6443ecda81133a299fbca37b4a69ad509ba44403ae3e5b2cf4277c8d22b68fc61f5e105dbd8c31f99609ea2770058352b81836b473ebe95c9cea90aeb682ca81b3e70508bb724b9e4c564d6a9600ea59342e9a06d6c4f51abbc3d7483401737e36b6d3270406e5b4589f5401261b790cb02219636ad9c65ea5c48ce79c2cf4758db9bbb55e003e0c64f9b025ddaf1a341f8c2f26593adb9af185915c0489c77f1038abb9802ec812885af603267b7457210f5a00c917039b1b8e1bcbdb8b8b3ca9418d27ca6e96644f7090322993797a54bcb13cf59428d24d499c6f631e8694c50389496c6454fc34aec2677ebe05a0d61cb7ac553e2017c93d7183f06cf461331073786712a2566230f191c8169a1bba3a968a44a3fde764a0b5724e74615f3cc0f819616bbb21055d85f0fc40c667048fec26fe98b901b67a2923c57e17ccd2ed20f8c3731f10b58b7e9234c4151f6f4174fe6216f5aabfcd3b634122896a156bcc0ce93f41a8a25cd825334b53269881a682d8447975b45e839b8fc54b53f8c70a5aa9c786113ffa708ddd5070b841b58d25820fb6e4d8121ccd016b9601dbbfa4116e1aa9f904dfb5ac2b4d607f43a3961161e02092b9233c75b7020d5ab4bd7e3abc3b679c6d003a6a072f0038983677f606ab976474d8616a5dad0c15ebc10986b9be9f19df7c740fd1198adcc019d43766a847f05fb5cd7c16a6215a0dc251c894ac585a5b530e2611c839e98786fc5d1c1b0817da7c20dfafbc67f62bbc872cfdc153d83f328814abdb5f7babdcbb125298127a83bdfc503d6a8a2359136225b2bbd9baa2a11050774924b8662bcfc608848840cdba8f5d72fa3876ea79784e4784860047915c8922c96bd8f625d56729b96d88c3dba9eb3aa308a7940e90147c9110770f712cfc81224f36fa61c1225ca7a653c5ab8d0b4327c014ec580b9b347d0403c235b25cd88c992582d44ca3e1394a0251743262b3d0a059c1beaa7ce47a32f5b72f6fa1f9e8c34d46a391e80bdd48691a930b3b0dace1b6b4b90b948794c14ec7b767ea6b2161702f9f5cf7336badbd2cd5bbc114f7b84d73a24e0049c03f83fc60b618ee23bfc5a286751970bc37b47432f982101e8fcc3ce01089d5898a46baca7265f05e4027ab367c8178580184771975a0ce9a8006ba7774c4e68e443ae644f19d8bedce0373a39b545738371499e3b7c88d20179434082ca235bdfa7701624a09b20bc65a10dac15c6c14268fc73be9d7a2f6556044c49a2006403848a726e767d2713be1dd04828da143df7860a9253566c9932fa54c9561ef5a26d990c308cb8a65ec8ced7181371a517c16a28ee9989f9d5acd50c8ba7085e95c03de98c978999c37195356dfb2e1da0768647c2e4ca6ae1d6bda251103ed17482cb0ce78ba17c69848475835a0c2e9d08b27bb220185a7ca40713aaa70068f75140c37d259150e6b4581670a6f8423a5979645309b7b0ebb0e911a68e46c48b150552f3093d425761196378863c431605ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c13dd780ec5347c512cfabf4c2e6a44cb2b17993c7c746f93c1400a5db9f12511e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +expected_public_key = f3fa06111b74ab835cc8479a8ebab78552ab3a3ac845a332bd1200c0635d3ad6768a4773aa803ebc08a0d7f772ff78ae9c90b5dd1b50e86724fc89110c128bda8209f0173e4d23210910bb05832b32017c182915308563c938695a0a8c49e6108c972587b04e6c916d5ac10ab425c15b370b0a4273d33530245048e62222d6211caab6a25332651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6fe701c23885e2141df14b4933c70040a295144a74a440487741116175addee87e656136a455bc9d1c5d611a22157aa3dd288b4ffa1d79668bf152bcb71108dc5916a223a703d376f3877406081c45a08470e4ae5679b34d2b4381335d8d5120282a656f121a861777d597a3b8910a67749855dba05f36831bd101ebbb427c92bd62f9c7f1a99a47c94e9dcba438835f3e053011f180f501c82611a64ec79e8b3563816a3fbffc5e033a114b8c94c9fb3391e0bbb8d4a33be98b219500f53b782fb2482fa9089b46b6f32555ba583370622771d02c6142647e6b87ddd382428552e58b80a66255394ab3815aa014c31878b74e7121b9f6d084edba988b43104910677aa62a1b27035de440b055146d15c466ea340b4658a41a885fe206c382923fd079f988b831a99d42241cc8637a647216eef18497298509832f8ce55235771e408a4bca646284771a0ae66ecdc2bb9d696d799c3cfad47a5a8b49575618bdac931d00c718049760f880831092fe3acd56d517377b00b156accc3ca6957ab22529673a59bfe87846c5431ef6b9c6c3201841da1451b881b2e26e44ac71e8858eeaa55aabd45281b56345222453440f7e427ebaf90bcd23c75e1cc96776ccdbf92766c778ad3b0a43a82463d09d79b90919eb76084438413573eafa0a60d26bd45ba0f75824c5808112406950d1ac5b226b9332709d1374b61957bb20ad7c33576bb68d265c7ddaaa12788c9e015a96009c0f99521e98e5c0cb38089d2101ef8700fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794257a277a983ce87c29c18f8535b07960bf20a3014974883529ba033a9604370a926778689937c774e74a3aea922f5fb717a7b73631c2e1f8c33f499674e584dc7f48e3efab83512c0f723ad981452003840215912e3d0abe816a58af87e1cea37daec759da34e24033c1842b2dc0a6909991b9e205178596c812a0cbaa48efb3586b5b6963fd445140bcfab6b4390832de8e27851b10619e699836a692bf44ceb23cd1f6938222b4b83f4a25a0c0c9ff397195bcf5dca633952aaf0321b121518f887c5ae945821f9b1150bc1d2401a7547ca3386bc33232cc58c6370508542994ca6cb098b01033c0c97ff468bc1c726a992181882ca810115fd2755ec18ce0f88cd37fb61580c039ab121ce95af498bbf4eea277eb780d3e0a0959a388d6a290fe58a64829184b763d3636b0551a90e5a9723b26f2c4869ff14ba806153d6ec32ad4c42d27161bf051be85303d9167245684bdb3198673c668e579a72136b6d252225b49f25746298532990352b90d82f6e324fb5877176555a078b82ac10bc8ea63a2b9067f13026584abfbc473909d50c58e9bc47bb99308298e6e90b3671adf643742e669a93e2a90b26723af4cf6bb64446619bdee7b5088369fbd737af0c4ae367313c699f384205c14c13c38599604390c7c911a5781bc2511208679510dc0d0dec26ec46718c748b59418bc353b7618195b77992858c06ff15a9077a37ace35101554e8a3932a9a9138a800bd3484b1b977d53f50a0443538aa5516780a094e6306e7842ee6a753c412d2a89c23eecb2b26a6ac90b3e890466a557394b520a07cb671ae9cd2c43621bf55a99a98392b9cfea6373d4b136dafa78c6e93ba7573b429b50be5949a254714c720721699290a510581b6af396879703aaf4a9781268446ba96a072009ffea0250c793237744e36bb0d3d752e1a6caa346a2f9d1695d49aa1aa2535c6449e8f4abf85079c0b99b91ac2e91613de6368c430a886eb15b192805e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c4d1a15b5c335af4091acc5bd189176b477938ebc700042cdbcb7385e10c3121b179660eb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_private_key = 0246c2025246911b525e6c3421584bfdbc83d73ab936e76a26236a85215c78db7ddd010c2e038e3dda69b5aa2e9f4997d8589bdbf918be1c046cd518e6958ae6925146009d185b53456b5e16d59257f20cd0f6677535510d02602d5ba5b61c440fa07fabb1b5fbb38437e90522665776892ef205a41a1a2083902648844dc9d65e633266af871481f036a2888d3fb9901355397f37875a4494777c781ec40478d09a820204a4115701d25a74b4bd91676ea6391fa160617c80cd05b0a80e040cdf22b29978ca55282f2c40316a35433dcc8ff7cccf4280c0b11c548b5cc08fa45bd0760ce03a02f25689d0f057fae44cb1574c42e760cb331c2ce4be16823dbb2870592ba844f30dc407298590a088425e023b856e106437c6074547260a856e648cba07e51a23e70d7cc65656b4692ec24277f04905c4aeeaaacd36341c705b504cfaba73201c2745ab06b056f1768447981e0d676ec904698edb230f369190d8c1dadaa5ca59001ee8a68c302f04298dc5700c56b2b577d89cd9a585b239089847cd3e96ca80d928867b27f3657987724ff9031649c246cbcb4673f6cb8544150c9975a13938c89a68cd0b6de5237fc8d2b7a6bb94e0c0856f00b821636801e9ac84f35276065ee4108bc1d755c1c428566a1ca3762d050458dbc7093567a4465453ab8656272a3c03b4a3c55929271437724471d5d4926109c9792ba49d117813948106d27c33069eb3c40aa8370b79e23f35934ac28666fe72b43f722151f3c26c96cc3b6a40d9e1876e55970f252811070fefc00d70a009e4871f136a08515ab239c33e2de638c4260d0c89cfe30b8f8e5927f2c59fea3947ffd0bd636b10876c3c387c00e15469b42b80bfeb8681dc7715c2b248ca6fed92a9399b72d1023f9507229593bd9bd936a0f6abba09bc3367782370b60d9cbd0e8b3d5744101c8ca97eab822fa4cc399b5be3195cb1e3c9260030af60bbe3295c4de898c502543589142cf48dbc7505ec9a9d93cb6dd4c9678c1cc0a082c5631a255142603dcc01fc07c27d628d89f09b473816b5d5171c18a3f9737bd6d3420d4bccbd3a5624a2686e54062ce4696e061c83bc2586f1a618639e51e63bc6c64825eb50d4f88334b29145bacc49e28dd564b7a578217fac230ad00a44f3acbf8753aa572d66e1ab9198cecdf9bc722455bd267faf98424eba4031c3bbec8298a9388cabc6b3beec7a7fbb1c814811117a9d550407c9e6099cea65ece641f69454b6a0ca9bf86a3dd472f7c0a7703c6a5b25464c0b091b29258de673220857878434ea14cf50054fb2e63547e9be15107beb7a78cd5c00cbb1462a0347e72b51a15ccb5c333894aba511295b37c97c7f4c2eb6d97219559b40a67310f457108015ac1b8e3ae15acf85689c4058ec8a0bb18b75615011f2701bde8ba70986b39d3368e1f978675a49fbe8509f1239a1c88f1df4adf0ac8b68a87e2a403373fb808a7b1192371c7e68b80854b0e4335739090b953a2b67999f9878a32415b78c22289eeaaefe3298fd38abeb6abcf5a55bca388004e46375a729cc45926a7c3e3bc8b4e2a2b196aabe5651b642c1cb50f666a1bb6da4d1cce8c6344356a68de044214453d03b5ccb82225603ca7e339380d63a4d9160df03890df722683b10847b89df2c46757815d34942eee95d9a0904f50855c73104eac00e22893e3764268a84bc1940b2d5d3befaa5571b31869b238c8ec7aea5a70203e67a0d9851dee23d3801777b2243e2b6328bc4aeb10a468ea96db01b77f68cbd63e4bdc157408ad378f637580e5723b544bceef3962c3a49fd836e993386e4e2c91bcb92725216979c132a0879cbb49f4ff12a46b194851b76dc910c20440535f9529d68acd39ca13aaba696237c400c6b297368f0d6c304f012824783a0b02048d5cd1797c5d61b3f5792715e7b72be1cba7cfb12a638720f7962243933bdc150ee5b26d4368e8c9cb985b7a0e5ea36bb942840a8b3053c09fda45ff937396ba8433bc3175806b0e0a77e2e8cafaf55c69b44bc626c3fb6d9c37d1a83170189bc5c47ab44cc82cb97732b8ddec23596224cfc4894871787ea25493bc48e4a37b70e404e77436f9a91970778c74e21b19265628ba0bdaf0744a5ea4507f5b4a0e978cad763e26a112f38bbd1a34ef3fa06111b74ab835cc8479a8ebab78552ab3a3ac845a332bd1200c0635d3ad6768a4773aa803ebc08a0d7f772ff78ae9c90b5dd1b50e86724fc89110c128bda8209f0173e4d23210910bb05832b32017c182915308563c938695a0a8c49e6108c972587b04e6c916d5ac10ab425c15b370b0a4273d33530245048e62222d6211caab6a25332651eb49541754d9ec46e63dc4c1b9886efc3ce63596aea297aafe548b20581fb98a755ebac6fe701c23885e2141df14b4933c70040a295144a74a440487741116175addee87e656136a455bc9d1c5d611a22157aa3dd288b4ffa1d79668bf152bcb71108dc5916a223a703d376f3877406081c45a08470e4ae5679b34d2b4381335d8d5120282a656f121a861777d597a3b8910a67749855dba05f36831bd101ebbb427c92bd62f9c7f1a99a47c94e9dcba438835f3e053011f180f501c82611a64ec79e8b3563816a3fbffc5e033a114b8c94c9fb3391e0bbb8d4a33be98b219500f53b782fb2482fa9089b46b6f32555ba583370622771d02c6142647e6b87ddd382428552e58b80a66255394ab3815aa014c31878b74e7121b9f6d084edba988b43104910677aa62a1b27035de440b055146d15c466ea340b4658a41a885fe206c382923fd079f988b831a99d42241cc8637a647216eef18497298509832f8ce55235771e408a4bca646284771a0ae66ecdc2bb9d696d799c3cfad47a5a8b49575618bdac931d00c718049760f880831092fe3acd56d517377b00b156accc3ca6957ab22529673a59bfe87846c5431ef6b9c6c3201841da1451b881b2e26e44ac71e8858eeaa55aabd45281b56345222453440f7e427ebaf90bcd23c75e1cc96776ccdbf92766c778ad3b0a43a82463d09d79b90919eb76084438413573eafa0a60d26bd45ba0f75824c5808112406950d1ac5b226b9332709d1374b61957bb20ad7c33576bb68d265c7ddaaa12788c9e015a96009c0f99521e98e5c0cb38089d2101ef8700fed95e7f643a5dfc686fda8ee3588042d54e3e78b4502bab59794257a277a983ce87c29c18f8535b07960bf20a3014974883529ba033a9604370a926778689937c774e74a3aea922f5fb717a7b73631c2e1f8c33f499674e584dc7f48e3efab83512c0f723ad981452003840215912e3d0abe816a58af87e1cea37daec759da34e24033c1842b2dc0a6909991b9e205178596c812a0cbaa48efb3586b5b6963fd445140bcfab6b4390832de8e27851b10619e699836a692bf44ceb23cd1f6938222b4b83f4a25a0c0c9ff397195bcf5dca633952aaf0321b121518f887c5ae945821f9b1150bc1d2401a7547ca3386bc33232cc58c6370508542994ca6cb098b01033c0c97ff468bc1c726a992181882ca810115fd2755ec18ce0f88cd37fb61580c039ab121ce95af498bbf4eea277eb780d3e0a0959a388d6a290fe58a64829184b763d3636b0551a90e5a9723b26f2c4869ff14ba806153d6ec32ad4c42d27161bf051be85303d9167245684bdb3198673c668e579a72136b6d252225b49f25746298532990352b90d82f6e324fb5877176555a078b82ac10bc8ea63a2b9067f13026584abfbc473909d50c58e9bc47bb99308298e6e90b3671adf643742e669a93e2a90b26723af4cf6bb64446619bdee7b5088369fbd737af0c4ae367313c699f384205c14c13c38599604390c7c911a5781bc2511208679510dc0d0dec26ec46718c748b59418bc353b7618195b77992858c06ff15a9077a37ace35101554e8a3932a9a9138a800bd3484b1b977d53f50a0443538aa5516780a094e6306e7842ee6a753c412d2a89c23eecb2b26a6ac90b3e890466a557394b520a07cb671ae9cd2c43621bf55a99a98392b9cfea6373d4b136dafa78c6e93ba7573b429b50be5949a254714c720721699290a510581b6af396879703aaf4a9781268446ba96a072009ffea0250c793237744e36bb0d3d752e1a6caa346a2f9d1695d49aa1aa2535c6449e8f4abf85079c0b99b91ac2e91613de6368c430a886eb15b192805e9b5cf7e587858b852f1d73d1f0b557684af2dcabcfc14bc8bfb76c2c97f030aac9768982feb815e2471c4d1a15b5c335af4091acc5bd189176b477938ebc700042cdbcb7385e10c3121b179660eb65365d9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d5acaf411ccb64500879102d9cdf6d9fcad673d874a4153383806fe174b2fc1e393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = 7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +expected_public_key = 5987636a96b26372851e703a9bd36d85e966fda580cc79af69772c2a9a7042363a3e3c116dc7711ed06fbf956dd06266329002630508b7d1ca73cbc853e62b23a02bff7404ebe390fcf58bd57262cf1044aa22225fb36446d44e1b8171aa67c415f96db0e109afa31fd00631bfa23f3b6c9c02b20dc3dc1ba6f30e6f20c9ec7471cef6996350bb87d43690c059065cacf697c63b6bc98c881d3ca56f07c34a5b0b10cab263bb75399d162db389206939b15df58448837e0d443b8df132c65bac83d2166c780132875fad888a1c53aea51661c135cea6956c2a4b87a53baefe726fdf09687f6cade7bc9ef5bc25dbdca95a0acc47e0caef22159af5b499fb6e8643c70803ba40a5938a422433053bdec4b729744b565066962046c5d2bd14f14bf0b4030be99a8a198b80b99ec939791bfc8572942e98d47b00814c6a85c39ae7323cebbf353439f3961f0abb687b4c18dd06b706db4350fc4a2e868229272f499709eb1450c2995d9b809e77e676b628aab0212475e602831a367d3948cdfb0d43eb0865eac55c516069893d09f24a8176a3beca0c6065abca0a3a2b3053da2a3bca6a7088f39d9bc8b1e685b67612413aa3b2ba4673b301cd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a8f134fd1cb590819a65190af53355a6483b6a9909bef36c76836c77168c679757ef404a8528cd569911d036c751d4ba4cb1c34b695caf487866cb1de5554196682d32285490a75fb5d18d3b40539adc4d9ad71452016a6fc7156b34014117bc0dc45eb319a1f85b642f7ca7a12164bc7a1feb9114a7c5ba8d7456cc08a883ac86100272b710b225e49de711115b418946f503586076411c6ca3ec11a5244774a27baacc543556582781b273bccab4326b4140b5643c86d310331bfb859f80062ad27e38ea1724dc4b7c3498a8601c11f25c99001db2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8ac2ce68b6b8b2e51fad7939979593f8f19e19b2c18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01a8065c6756e6ecb64de11fed0acefdd45fc50c1f51b045d8e096a9e77f10dc8e8349b5da9723a1829e2ee3cc0379942fc47841b81df7a94ec7f40bfc2b737d9725486316c2ec3e2b516dbf7cb4936217cd4b23e4422122854791a2cb136a1236677a4e42504ae43bfc93259441bc0d676f8932a757c087f806b59e6380197b37719a2fba88b64ca54fc69ac8e2b79df7154403249441d103f931a25283bcded4c8b51a7995655d49611ddb2ac406b28ab2a80342f51bb8126afd65412b06d0596622e5722465b846a52b47fc6b5842f12acd602ef9c74065d5940d2462f7d99d39ea5f62b46f9fe297f1c01f5183c73c3ccb63c564dbc4c1c60877960202d9369b750129d91060d1708f057811e68c47c4b68781c102f2765e093c94f6c43b784679c4257287680825fc5116cc04b489add5a009a3e65b09644d5a9a9745d249314c4693f017a6d5b054d07fde34cbde568ea6fb9bb56c8c5023142cd19eb2b3b0c6b8bdeedac8b78909b1bb1894b382e6fca4fcd63390cabfb4d516fb18526bb45a0f9a6aed971050788cdd044248839d954594259b562317cb163273b12b453638b70be1085e51c5ac0b6cdd15c218103e92c53750f107ada702d8725548ccc663947c3dd959811842b62b13f9a24b1b4a18f5691dc4cc331c362747f1654e1b785ad1c07443aea2f6006bd670d7128a8373c68aa36ffc59797ab3994bea35ce894466f0c64c061b5d48b9a18c5544dc0820479722795d77c85f161b865dba01a70cc9c00c15167aa35bf0a147147a81d540346489dc58926c975333cc3d286b4c529a2e3e6aa6d2225016a7126dcb46669c72c453bd745632e772bd2da7c1ca87318276ad21ebbb6c419ee2eaa46a733e3934c0ae933950da8fd2eccedf2919d7e8a6812897780275adf78e6dc21757c7a0a489cd8cd95126a569af7c67bf317b146743b0d32a6762103a13698120cf7d07b72be91177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516c5115c724af7cf05049a012c8e601e8b5237e1aa5652cc5e4e1a6d0504331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_private_key = 34c91f6ec981b1830501d8969f8847b2c6bd5d5c43dfa044c43b551e610d5675bb7e7c9e393b411e69575301bf4ef4c7fd0b4b59e213905a254eb5540aca856c370dd28899541b725091c23907c04390ad32a56385075f42a7545672544fe177b74c7ed99507e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d5201165a47391d21a7ca732fe9b3455c44ee4e54fc3a6518d51402cd5a2d49429b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5cd040245543431c0d2c9091376611cfdc2eb9181b21c8417e3931aa2b1141c1051cb82aca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac7524f3855de2b00967b7bee0668112d51ccbc139fa73374df2685a3cc06838b150f92a64c17772053de2b05cc4d51832b8a2b8428436d99e1f2484b127ce0d861dc8a11ab0b0019e0b3439733b36a7a600f4638d820ba5624b445349a86465e1b25de787207dda0b629cb472d415a42a8ba191b76b5829d4d987a2b0c235521c187a0baddb603d755eb37396cdd57ff76276ccca997b00cd481587cb8728830021dcbb8478a267b744a5bfd08b4acb2c1e726121996e55b60d40f6975637831c392845d6823d4b9092151149992794f4ab29d4164a44239f07c365a87ed9786af7a57ac0bc0d491018007b6bf7705a21b082d1e040a4f4c25e329ef9a8518956044e7683af94728487a4f95305d4e15aad45c040f1cf9c442c519b2aa47a4dfc29063243c21f8b838171701b4b73516944efc4b61fb5bca63c3ed12a123f55b832e6c312e8bc48f145d62953f5901f7530068f2c9c9f51ca8fcb342852936d414fddc2c04f551c827071f99c7c24c991f9c97e10e051694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0bb1c2d3e859d3eb03c0a23b290518ef88ce1bb02fe71399ef71b380ec1aec4c7c6bf3830c1b15f7718d0e471d10234393d94fbd3305abd09cdf070a0abc09d7497d2f9b939794b923eb3f28b40904a53a05216a526132d9f3cc64606b40f26434142645d79481a8316e8cb0a9321a4c530a0ad139ed5953168a4ac864c726874e1366ab09a249f251ce5b1a7f5ca60ad66375bfdbcfa3d7ad23a13649c03327d409fda64581cb00a696557945c58e96c1c889be648c4885958adea79ab212a0bb15506bf5635e437ecee47b60032b4273b8c96806639c87031b6e23b71996b4576626124281ae4ca0a8fc081e1c91667967b25f76c4f72624cb29bd0a865fd67a4dbf14acc7a09871bc7adeaab37b298f12b60b6372b741681627e4c8346c0d34392716ec173b1b711b1c0a1d010dca486bd5167223658a5c55bcd0739dcfe30dfcf9bd8aa45b3ca0b5a90243547767a1843e4c87922031819ef9249800c6db8b0270f9cb8f2624adf4199741870b0630e1bb1b325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310c51eb565baba36be54f6a3151a104911c38ef78e61f1654ef35b2c836c2321a52fac710d6b03811444de5b8403569c8ce0444ef615dad54ae5649e68ab437c00a2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee7c23607c0683a2826fbb4bad4a58ff6e3bb3122bcaa202e6a997c647886db545fe6b94e81456379e7550db446a43616808ac610c3abf273b02b1b748296a760d78f0418355f61ce2898ab3bf9069576827b80557d41000bb0cdf5881d660a7c2569613ad6575e4c528a7c5b9ec91365b05853ab200aaba1ca98aff17a845a209fe4932f30bac0a8873cf5da17f323375627adc4786e906010f6b91333112d0bea256d3a126eb39965db773e7c3daec35060ab2d782b9a7692bc40525171416e7a12163d36837ee3c731ecc38e7236ad09712b4144030213bb53258033a8eafa677fd8a2cc013c5ab46a33531968a9a6c5e6a89613aceec3a4cddca52cf00b21d85657599d21c80692018a07b061db607d7df491cfe59d90d43a6eb52453b2822c7bae0a3336833469764516ec106e8d6912c9c35432984514ea5eb9a65c3c0aa24173bb736723022a6c31f06236639a0e0a25713c5a7855399637aacdc033c0117447730747507b69bc7a3f84621167ac83e4b45ab03b613ac4bd7217abb799027b1a33f55a9b550b3857ca53438dcd157b103c9e5987636a96b26372851e703a9bd36d85e966fda580cc79af69772c2a9a7042363a3e3c116dc7711ed06fbf956dd06266329002630508b7d1ca73cbc853e62b23a02bff7404ebe390fcf58bd57262cf1044aa22225fb36446d44e1b8171aa67c415f96db0e109afa31fd00631bfa23f3b6c9c02b20dc3dc1ba6f30e6f20c9ec7471cef6996350bb87d43690c059065cacf697c63b6bc98c881d3ca56f07c34a5b0b10cab263bb75399d162db389206939b15df58448837e0d443b8df132c65bac83d2166c780132875fad888a1c53aea51661c135cea6956c2a4b87a53baefe726fdf09687f6cade7bc9ef5bc25dbdca95a0acc47e0caef22159af5b499fb6e8643c70803ba40a5938a422433053bdec4b729744b565066962046c5d2bd14f14bf0b4030be99a8a198b80b99ec939791bfc8572942e98d47b00814c6a85c39ae7323cebbf353439f3961f0abb687b4c18dd06b706db4350fc4a2e868229272f499709eb1450c2995d9b809e77e676b628aab0212475e602831a367d3948cdfb0d43eb0865eac55c516069893d09f24a8176a3beca0c6065abca0a3a2b3053da2a3bca6a7088f39d9bc8b1e685b67612413aa3b2ba4673b301cd9d87728db6bffe79391493a36b4aad46339dd2b884cac471a8f134fd1cb590819a65190af53355a6483b6a9909bef36c76836c77168c679757ef404a8528cd569911d036c751d4ba4cb1c34b695caf487866cb1de5554196682d32285490a75fb5d18d3b40539adc4d9ad71452016a6fc7156b34014117bc0dc45eb319a1f85b642f7ca7a12164bc7a1feb9114a7c5ba8d7456cc08a883ac86100272b710b225e49de711115b418946f503586076411c6ca3ec11a5244774a27baacc543556582781b273bccab4326b4140b5643c86d310331bfb859f80062ad27e38ea1724dc4b7c3498a8601c11f25c99001db2868d68ecba0019baea1363ef738c5c07778c5b4663447e73c742a1a6a3e708cf4003512804b9ca9358665aba8ac2ce68b6b8b2e51fad7939979593f8f19e19b2c18f03639776483ddb4373184a2d2741839c65f5d47e63597d14a5ab61a6bf01a8065c6756e6ecb64de11fed0acefdd45fc50c1f51b045d8e096a9e77f10dc8e8349b5da9723a1829e2ee3cc0379942fc47841b81df7a94ec7f40bfc2b737d9725486316c2ec3e2b516dbf7cb4936217cd4b23e4422122854791a2cb136a1236677a4e42504ae43bfc93259441bc0d676f8932a757c087f806b59e6380197b37719a2fba88b64ca54fc69ac8e2b79df7154403249441d103f931a25283bcded4c8b51a7995655d49611ddb2ac406b28ab2a80342f51bb8126afd65412b06d0596622e5722465b846a52b47fc6b5842f12acd602ef9c74065d5940d2462f7d99d39ea5f62b46f9fe297f1c01f5183c73c3ccb63c564dbc4c1c60877960202d9369b750129d91060d1708f057811e68c47c4b68781c102f2765e093c94f6c43b784679c4257287680825fc5116cc04b489add5a009a3e65b09644d5a9a9745d249314c4693f017a6d5b054d07fde34cbde568ea6fb9bb56c8c5023142cd19eb2b3b0c6b8bdeedac8b78909b1bb1894b382e6fca4fcd63390cabfb4d516fb18526bb45a0f9a6aed971050788cdd044248839d954594259b562317cb163273b12b453638b70be1085e51c5ac0b6cdd15c218103e92c53750f107ada702d8725548ccc663947c3dd959811842b62b13f9a24b1b4a18f5691dc4cc331c362747f1654e1b785ad1c07443aea2f6006bd670d7128a8373c68aa36ffc59797ab3994bea35ce894466f0c64c061b5d48b9a18c5544dc0820479722795d77c85f161b865dba01a70cc9c00c15167aa35bf0a147147a81d540346489dc58926c975333cc3d286b4c529a2e3e6aa6d2225016a7126dcb46669c72c453bd745632e772bd2da7c1ca87318276ad21ebbb6c419ee2eaa46a733e3934c0ae933950da8fd2eccedf2919d7e8a6812897780275adf78e6dc21757c7a0a489cd8cd95126a569af7c67bf317b146743b0d32a6762103a13698120cf7d07b72be91177bc5d18ab5f0eb53fc4a5cc4feb5086947f42c3516c5115c724af7cf05049a012c8e601e8b5237e1aa5652cc5e4e1a6d0504331e3b393a6a0fc05c75604646a943ab2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8152641a683dd690d4ac3edf0261200cd9244ae7dab962eca2f3d22a554d0802eeac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +expected_public_key = 3c2199c59446aa08c7646c1f567ac35c18b82cb24ab1c51f2ce8a79ba51f432672ccf12c23a5750e9c9a6818b628a49a812377587323b1e63d8f21a9dfc76095827cfe352667c16e888b1a621736c28c8acea052f8c4618591b36650a63cf00b904120ce716fcfb40db52347b12486442267bea46c1b778a98268481155c53a72c5731ac2ee36fb72c61b60273d1419ab8e82611921c99dbcd4e209d2af64a08ac27bcd21fb7b9373f8a84241a1bad24c8dc11203b3554ac802dcd18104dc8833a4b60edb07f9135b452209b65229bef0ba922cc60e32954096794b7248f94b134143b0ab3a8c2288a6065e7adf5049e918b3447ac156bd462a204a6d8d680761b9e70d8796fa149dbd45509b6169bc34ea8b876d30c7a2e51943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397db06693c20cd7caa079576834a0991761c79fb660843778229b2af530276c345ef8c420ee395455ab47df46609b0bd34e2aa7f35af596750c71c4aa2754afdc48481a018f2499fae61584eca38f331c571bcbf73ac01b349953081908979499f2bcd6939b81a5199fb5838324928372aa2efb6c8da025873318c08117fcf47302fe99a31b923ba947871c6ad7168246341ae1c567f8706b88f240473a646173a58d559cb5d3865f2072d99b78cb7d63617fc05dd16391830cc22e2ccdec55c46f84262f59d1718c473626f55c8022849935b3a32f55180dd7b67cf496c999189d177cceeda613721718b0a2e74e0301e667ae8aa36d83298b2983054a3824d64097e380585c4288be24e5e711f09e72d31d29164fb34ec7068987241266587a367b067284f3595663f927255c66bc7c79e5575744500792e8236288a432b092597069182c28667c51b76c4a422dc8a023127b58979290043cc79011205cc7e61aed141bcb4c090a6405263e3c9d613a5d1b5b7e0a8c5915611fef213eb4a9891d49f303967ec3ac40ee145e8724e8ae90c6eab8edf970fddb459b66b654c8c1fe039ce07ebb50e441bbe386ac39473b9a6a26f0ba3799155bf047ed33a56eda493c26b6bfa912cd56623b18254d84c3e8e34a23b3948d4579d1dc301706c835d879787cc5964334e52875836e4b105fb9abb613bb3ac9a65ba8f39470e3aa20bdb1741f1f78d527555e10caac4e17f57e89a520514716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df76281d4515e4229547d235be6b6925063cc3832e08d192b6193d6c02a0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fcf819403ca08684a418c04e6e6397cad03b77b2bf3624b89d176f87c82508c9cb13d60b9b3194ff52a7b58413088b2964b2b92b94463f2cbd92444a888154410990c2d5c018916b5f7059c2087cdae1bf06942d05d997bbcb289bfb0725db84f6e23c96da5c64595e96969097b8b9a28c5adbe36093203f01039a0ada6e63a21d22794405940142e0c959bc624619b964dc6b60a1cd31dc99c4342d1ed67c534570a658361376378e82896f216e57c21159967212481845c112fe0a3b1b4b888ce4c22b3c73fb87084d645359a23d7929704738af9ee7abaeac15cd8c6d87295f849341bdf68b24a85621f397fcd31a209b3089151bd44c9d90092ebd2844fe173392a8836876ccd9d97cad570bfb55523cc7763502acc4d337e8634f97647f4a0996514264b0a3c6681022b739a66a98b92cd0577cf1906bf72cfdb23605169d0ef37ab96baa1aac1322149bf682025c3bb7adcc79c1a9c8fb52c3d4b529fda48997bb71d18a3d4fd201000c4648b634778b7a5ff190a27c1e631381b777ac0e858db4033509c66bf1bba3a5828fb7f578e8fa51c7c87bfca883ea96a968d78bf312983e6ba51bd05617c90a1677159ddb6d4ffb62b8642e56eca75cba3f9d810102037b2c57c7502a60831b15b49c87b7a14fceb228d2f0b82e1a5cb632b8d3070560977b24d591e7cc0c07017a09104d2ee24e6dc2c3af1231af922d62629c32481bfbe309d5a0cb4b61c2eccc7e9bf05fad1a7fcfc3635192c90d76668fc91a297cba04621dfefa729996bd118a308491b59c16cb7077456b0b48da4757f23b90253ca5a2c1aea9a524e08293d77022f66b5707aa4f30f6b099332cdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_private_key = ab4545850434076342eae8409fe0590c34955e860267305fca05c347bb3e53bc714e3134a6e9b338674a9aabb02f021d1a09a190757f03d573c27687f7e35f2d77294d10cded732218395b344523f1b704b27689dcc286b5c98217f239c159ae5d655436f00517a50c6dc6b7f4f111e7f37a0f319bf6acc7b0e3345c9367b2a2b8d9d644936220c0a817fbb38ceb3469cd55c661e1c58d06807504443448c4e53204dc59c60a5153494478eb4056c9a85967a42ebbc287afda51fdd6b84b285523d41d80a56f7a68a168a4527d902311b18d5e381cfdd578bb7924fe687d3aea5607906815181171a727e4dbce1b678762a8b03c2a2bff1635ca85332ae90f14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83b90bec27172ac85154ef27b91623841e188d76b040f958c38c8a112c05b54103e55a159de0954f2477e798a573339508b7c2ac3872a623429777ba3179060135c083e2198d1e0aa01967c39c27372a1a36a92bac3bb13ee3c94b1f0391e2702c50253dd497f16f39bdcb9c68ccaab6312084884b113e70f38555422767f4e613b2e87affc01395fca37df0a1aef74263c1001392732d9d1047cc7c6fb910ae6136c33094526876a113514f2918909532a759617dbe2c97e72176490995dc82b663655df65324b1996a42150be41b2a1c90f03b2a6f04174da1b1cc7fbb024c3c972b9714300c683c28a90f48b01c28607922c3ed25601a609673481b365544b7c36a9550ef20c37005b0e395a268e90ce1a5271e1421b46303b80cbcc81e2894d7569e82c2f5d8c6996c766bc505976628cadd84a3f468c67c209117c8254bbaa1ba584dc2661728a69e959949ed6c9f1b42f01ec8e55614aeb7168cfbb5e16504eb9f585c7789c48e59c17b5975c444bd6e32a6654bce298a605043bd367400c14b1d8e1a592a034543c04a44c85711aa66c807fb07378fb525600c19d9a4a9a8c920ba7db0b1d912a45f2b6d518b469e9121d25cf40499196376d3d92827e1b96ae255aff288037793c7db07e1d15533c07162aacae3255c0cc368e2fba3fef09540952910eac0fb2f3ae376aa666fc97a3e122570ccf797c79ec575835e0be6e808b3cb1b72d8241c3679bf15020b6a63be65b95a2c9147eb98c6553c71c550e37603e6b73c877c94e7b603a22eca456c1409d5aa049673d0ea17c123b1835692253fcb589186baa498f39481c3d0640a4d34931033b30f26ebed6ca9c49ba6fb219d6dc8461937284235a6417cc9c0ca0ad385b04b01c81d5a7b97a34977250e3679ac55c3d76d83b1f7b99dba039dc179147223b5d6c11fc9109dc062a1e4b7c88c710c449320949bb4405b28ea2c04d48c58aabb46edaa58e442f3ab6c9810b6d702855f7ca91af71b0e574bac1040dbe864ddaa76827874839414cf3418d1702c6f368a10714cb25e208c8a5779f639837a07e348841a11714f41399da175c49678307d3634d6b9921880fd43ccb8d7842e5f34ce44a4923e7ce6b671c7a989aa748604d147ce7ac25a1533e80ab321b7aacb8d523a3a6298beb0cfda435d77714993173d080827fb07b7855769eba987696afdf58231f361d2164277bbcb26debb43d1395a23a8d890a2cd71362e2340eb68b84f0b23345d1c449353528c2998584941722a304677008da1a13f8c8fb0687cdf688c707a73d121ef5c609c2150c1ad346a2f85fe3f58aad4280f92c35125345610b901c305f6042aca2f6cc2a4a0d1ea46e378098125b1956f12f54154023549d64d799d6972e3b283108e779028c1f7339a9c3d8676ce316ec9b9f09d654d8b84ac1d26223b36aedb584084855374b0562a113d02cce4bc1ad3ee1b69cd76efd0504b48724d25c3416fc2d12eb58f174a9278a6620856763744a1f863bae4504c779571d83849a88c023f15ce838b524a9c450e2b8592b98b4c89ceb35990bd39b74b87cef750aed976f40bbafa6f03c531b0a9c47ac22fb2b24609324f262e3233274f088e05181b9ab973a4c727ef53d40f914bae5c99d919537e67ec61061c7b61b7d17b72eca748894a25a5a97d5876d4608bf5c2b55fd85243b1117fb907843e47c83d29e51a11d53419051461bce776c040c848cb8522fd2c14880b87fa970873b8f3c2199c59446aa08c7646c1f567ac35c18b82cb24ab1c51f2ce8a79ba51f432672ccf12c23a5750e9c9a6818b628a49a812377587323b1e63d8f21a9dfc76095827cfe352667c16e888b1a621736c28c8acea052f8c4618591b36650a63cf00b904120ce716fcfb40db52347b12486442267bea46c1b778a98268481155c53a72c5731ac2ee36fb72c61b60273d1419ab8e82611921c99dbcd4e209d2af64a08ac27bcd21fb7b9373f8a84241a1bad24c8dc11203b3554ac802dcd18104dc8833a4b60edb07f9135b452209b65229bef0ba922cc60e32954096794b7248f94b134143b0ab3a8c2288a6065e7adf5049e918b3447ac156bd462a204a6d8d680761b9e70d8796fa149dbd45509b6169bc34ea8b876d30c7a2e51943d2ac5897486ac67b2fbb9b0bafc49c39cb459c8a397db06693c20cd7caa079576834a0991761c79fb660843778229b2af530276c345ef8c420ee395455ab47df46609b0bd34e2aa7f35af596750c71c4aa2754afdc48481a018f2499fae61584eca38f331c571bcbf73ac01b349953081908979499f2bcd6939b81a5199fb5838324928372aa2efb6c8da025873318c08117fcf47302fe99a31b923ba947871c6ad7168246341ae1c567f8706b88f240473a646173a58d559cb5d3865f2072d99b78cb7d63617fc05dd16391830cc22e2ccdec55c46f84262f59d1718c473626f55c8022849935b3a32f55180dd7b67cf496c999189d177cceeda613721718b0a2e74e0301e667ae8aa36d83298b2983054a3824d64097e380585c4288be24e5e711f09e72d31d29164fb34ec7068987241266587a367b067284f3595663f927255c66bc7c79e5575744500792e8236288a432b092597069182c28667c51b76c4a422dc8a023127b58979290043cc79011205cc7e61aed141bcb4c090a6405263e3c9d613a5d1b5b7e0a8c5915611fef213eb4a9891d49f303967ec3ac40ee145e8724e8ae90c6eab8edf970fddb459b66b654c8c1fe039ce07ebb50e441bbe386ac39473b9a6a26f0ba3799155bf047ed33a56eda493c26b6bfa912cd56623b18254d84c3e8e34a23b3948d4579d1dc301706c835d879787cc5964334e52875836e4b105fb9abb613bb3ac9a65ba8f39470e3aa20bdb1741f1f78d527555e10caac4e17f57e89a520514716a6a7fb3a5e4c8792ab5bdd7c6bdc3b6b78ad67054166dde3ba339f364df76281d4515e4229547d235be6b6925063cc3832e08d192b6193d6c02a0fac9629ac6b431846bb39a9d123ca6c147ab5aec49fcf819403ca08684a418c04e6e6397cad03b77b2bf3624b89d176f87c82508c9cb13d60b9b3194ff52a7b58413088b2964b2b92b94463f2cbd92444a888154410990c2d5c018916b5f7059c2087cdae1bf06942d05d997bbcb289bfb0725db84f6e23c96da5c64595e96969097b8b9a28c5adbe36093203f01039a0ada6e63a21d22794405940142e0c959bc624619b964dc6b60a1cd31dc99c4342d1ed67c534570a658361376378e82896f216e57c21159967212481845c112fe0a3b1b4b888ce4c22b3c73fb87084d645359a23d7929704738af9ee7abaeac15cd8c6d87295f849341bdf68b24a85621f397fcd31a209b3089151bd44c9d90092ebd2844fe173392a8836876ccd9d97cad570bfb55523cc7763502acc4d337e8634f97647f4a0996514264b0a3c6681022b739a66a98b92cd0577cf1906bf72cfdb23605169d0ef37ab96baa1aac1322149bf682025c3bb7adcc79c1a9c8fb52c3d4b529fda48997bb71d18a3d4fd201000c4648b634778b7a5ff190a27c1e631381b777ac0e858db4033509c66bf1bba3a5828fb7f578e8fa51c7c87bfca883ea96a968d78bf312983e6ba51bd05617c90a1677159ddb6d4ffb62b8642e56eca75cba3f9d810102037b2c57c7502a60831b15b49c87b7a14fceb228d2f0b82e1a5cb632b8d3070560977b24d591e7cc0c07017a09104d2ee24e6dc2c3af1231af922d62629c32481bfbe309d5a0cb4b61c2eccc7e9bf05fad1a7fcfc3635192c90d76668fc91a297cba04621dfefa729996bd118a308491b59c16cb7077456b0b48da4757f23b90253ca5a2c1aea9a524e08293d77022f66b5707aa4f30f6b099332cdb36b957f6adb81a6ad23469a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab9cc95efe512c84010ccd7118a92522cead44cff28d6e223f76702a47694c8f053fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +expected_public_key = 5651279153af42d2940a191c57e30e0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd4e0794d55bb26379871fa7692fc7fb61c8f0565916db30861a2a61b346986697690d16185753395060b229326681b16cd5b8069fb5498aac4ac9023adc380aaea764fd8625f765f5d73a1189a7524a6bdd1209a8a23bbc5d96c54b89b9f256d20f396b6f61e47e0989ac04cfb267b175a8b38395dc3e976feeba1967ace1c491733cb3b005580fbf666ff6093597cc59362cf60d074f6d33c3be33bd02bb0d3460abd45889cba06129ab11fe978d4749a675c32e2e9bb2d6816ce198bc5e67bd6069666c6b1ef780765664ef650c9847566e02c116f5318d1fb240a167a89b2381cb4cd7ad60eda125bfad338bfd668a008a9f9354999949ce5fc09aa21025a83cdb2c7cfdcbb3e03e0212d58b78e00ad85ca97e3f64a82e79d26053da439862eaabf9bba6a11f225ce27be4cb2ac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd8306370672f20f315474836509c93ea814c9c77a4366325d13c52b0d5a231d79ddf765e774c9c60f6a2f7b1377630be03149a31d7112e61b32296234678bebbe05bcc4857453858b06680399c699fd23a9f96b95f5978437b5d453704c32317beaa45222133d6cb8a5e984633081170c154d68674896911ce5014a9054c37901411ba72f77474b5591e0e1477705a3e1b535d4ed3b3c1d043de517b23035239a39694005c00ca332d9b5c98a16034550d4a92169966882bcb28f01171e276bb36f98dc3dca74058462f2caa4d5a9e60991f848b6c519c45332b18232b900d9787dc78a685360336b685d5301315923f8df99d34b8267932496ae4981a2cc94739cf075343de4231736b42d9866b0ce7030be42aca98309021b24a1a518dd0107c2b03a75552c169b605635323d9cfee4c607c656724b48f523a1ebee51393e1538dca234d864066f7417b1b67968a2c03f9b85255148a9409bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f63c1646e015d64066402a2a8f36b7c96e0a50ea13c220103194bb188c6947e533b1a173cdaf225eec27720a61bb3017205e98258fb470641633d955d14589bc566c9fce9590b6141f9c662baa60ceac1a7b0e518e370c27da21e2a098d62433f2fc336340851e2e536e0b2ae8c2b2b58057b5d30a8fab602c48ccfada926455549ee4c15f2369f58742d5fa85415990faab1b76eeaba47d05a0c35653b36192a6b108046bca55443fa075f072270e836293ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccab92446a09c8be6653f9398b4d5540e8544d56d5c88dd20ea99344b747304f56b2aa725f1a858eb7bbae293b891ca61c2d5942204455cb726c29a23231eacfac678dbd002ea8395203172b35a448ed3944bb07bd2e11b9fb52caca2213dd482159821ef5d9a98d09147e272d3a9b84023172d0d1ade55662b02a9574c13a5d5b79575c25c9d46bc5c766e4768836f787cc6a771a772518e7c5a2f4716e007900db8abc8a630916a268b080cf12ac427a02c474ad28caa73a5793bb0a7593913debfc4cd353ab92bb23d78a2822527e58f52f4d5a70b2f05eb0e6231dc43e5fb7c27bf6870181709f1b0ef4175753687a66261f32773dcc520c752ca7ad6344155bc63f000e1c18be1d154476a4a639d2ae5e36bbc157a7c7f8291b6506f12aa8003784927284fe1b1a4fb70aba9a39d0775dfa293f9a29a4fa3712fda54c41e45c6696aca509d09e42618164c34f78b5b385750ea93d39abbbac58640ce09e5a5245a37847c78765d731596bb10123f51793ea5d97c0321fb5810a22af50406e53806569c53750153ca7b49dddea12baf4ade371b4c7d05e29369a5d1c71ee1ba62db26c74b456cf30832018cfca235b32174c031c53b4c653ee205c632218ce05676f2878930334c2c284d7e3b73683cce303694e68bc7f95b0d186acf5101d95fb6ce55acda6743c7512638e42978af9037272a1a5e23e3632059ee1a3367ca9bacb27930700d19327a0c6ac9fb57d3e41bedcdcc47efc18653c2c5cd78200ac77b066b018d137facac920790bc9e593cc243761cab947818e8ad7ae6701601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_private_key = d7e3338b3ca1d6118b7485bf85ab9e8f6c36e158b67d2c3530b0a544b8afaa0a8604710987429d0d1b1eaaba8f06422e992c475dc4cf909061efe673a3547575e8b00ba47d5a158c22e6b2c280b3152165a5a01a43d801e96791b6d99c92c0b0602c94c0b13f2672146a7044e4372c5fa8843fa7974692b0f292af9fc3b5793092c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe061509be046b3a048a73599ac20466f0707e9b46045352f94507659ba428cc6994ee3375b07d09ad3be1872c15692c7394626cfc01bf5435d7922bf9199533a22cc4ff021a97c571db311485b36e2a3344eb880c67819aea18b09919fbc57cbc11cb228f8c24f38a445c512245c3a5cbc65d20269ee849bc268899981b9f334704499b60a891139d9470a1a147f38470752c4eaec5b14d51817fcca22e7bc1c585cd2189131960a9e9284ac7940b2949707ec7a67f22db280775d8163394a3a9557bd48f50c26f177ffe83030a3455de1196a763f8af156df73ce3bd07ac70447573a79dd04a59e8b40e39c6fea736e14f1b1b67b5cf556c3adb29facfca4e6d8b759d37737863da2a7ac4a645a8f202ad61c17068385c21415f7e14146d896020b89cc73aad60135d5a3b94879184e086f1066a9f56041b6029d1f538fb5b18a7a741e04e2c158b69927a1a7708bcc411988c0c315d0d1bc3a31b0cd473fcd3abacb1bb3eb23224379b5350081efcb8c45584d3b845e2500420453718ad83194130983a355b1388bf246b9fe7400443c52629812fc1125c3800c3f824c0ff95bc24a2e8b306d5e3278fffc585843bbfcd06d2ec3482295717a5111aa7b6475040083106a01491cf981197eeb77d9b01c2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57cb0ecb3105d94715c7b1ba7800785edba95a7352583354b93cbef98c78bfa946a7431813ec36ac45488b170859c098b7c6813cab2ffb519814c3a9de3c254ed7a144fb6d15b183cb48a9021972233382fc8c388511add6a86837801f4bea0df0103b3a152648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f6717eaa18cb489b446d24f5ce239c79a6e34215e87bcb8461b5b509c895ec22f94c17c3bcc5904d968c469b200d3322b423761e3749556476d925a915971a62a5a330acbd106ad77da7897815cfa31cd44310d44915d762164b6170b2916b5427c694ff3340fb16b73500e92833ecc35bb25db6e652701d85ab215b366a173604c2797c2a9c420e069e7e4b3d1120dbd1c196d105211134478d23cc4428f8f56182ff3a51c7b84f01a08ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f7c06883c99c4ce934f9b04436d250ef262c42d4862b90c11f4924087469210a25cf4cb29d139d85d9c904004cb246348c60736d707b2b9b111c91acd3937d9e8934032746aa5025bcec8bf637936448a0dd67a27db2a74b60bba82bcc87d73d4a9033c427a85883613eda43829c7ca3c7a8f24364633610d8199a5ec8038d0b6686abbd47692ada94282c40799ed4bf8ecb65ee7c8b2047c41eb255318c139b89ce909831fe3024bac10b4110ca34f1bd752858a4c0c307537263723987f6c3e29918fe816ec4956c5b4b33d532367f14230b14357e94bbb7e8a947453e4eb606de4c695468c9b12458340cc59d0b23b01b2255173af1206383aabda0bb1fb76a65a814bb2a4a1a0108650617090c3a35ec675650745381e56658cbb71a81cc386bccef66cd599b1819629ee02015b4928a5d12838892333974877a2995bb2b73bf3b292da0ac34d26dbc501a2c20be0e054b8b0bc541ba92d135118a5a17c19a2b3501c60921b960e013f88ca623d4b37717ba5882bb3bda2bb146c42ca4b339a01fcff7c35ee467a4e7c282f175985bc07481bebf5395e0d3843759117459c2b7a45985a672657b787768c32cf37aca5a419743c70f48bb78d53f6d65b5d3d079907975b77698649292ab0c8c93938147b6afe695b9774881cb11ac88ac3a1321965e598b4e01b76114c6b47316657b01116412b0e4c5aeb29e0c1856382569fa800a91f6b7699928a12ab0bf92a395f643234c98b66501bb66b8ba4b88c516101594338ee57700b95ce6e334b7d4425651279153af42d2940a191c57e30e0f1c6a3bc553d805aaae5982c663c2dd034e6bd48dd4e0794d55bb26379871fa7692fc7fb61c8f0565916db30861a2a61b346986697690d16185753395060b229326681b16cd5b8069fb5498aac4ac9023adc380aaea764fd8625f765f5d73a1189a7524a6bdd1209a8a23bbc5d96c54b89b9f256d20f396b6f61e47e0989ac04cfb267b175a8b38395dc3e976feeba1967ace1c491733cb3b005580fbf666ff6093597cc59362cf60d074f6d33c3be33bd02bb0d3460abd45889cba06129ab11fe978d4749a675c32e2e9bb2d6816ce198bc5e67bd6069666c6b1ef780765664ef650c9847566e02c116f5318d1fb240a167a89b2381cb4cd7ad60eda125bfad338bfd668a008a9f9354999949ce5fc09aa21025a83cdb2c7cfdcbb3e03e0212d58b78e00ad85ca97e3f64a82e79d26053da439862eaabf9bba6a11f225ce27be4cb2ac2ee73742db5c074597fb25b50b83cf03758853576c8ad4c8e748cfd8306370672f20f315474836509c93ea814c9c77a4366325d13c52b0d5a231d79ddf765e774c9c60f6a2f7b1377630be03149a31d7112e61b32296234678bebbe05bcc4857453858b06680399c699fd23a9f96b95f5978437b5d453704c32317beaa45222133d6cb8a5e984633081170c154d68674896911ce5014a9054c37901411ba72f77474b5591e0e1477705a3e1b535d4ed3b3c1d043de517b23035239a39694005c00ca332d9b5c98a16034550d4a92169966882bcb28f01171e276bb36f98dc3dca74058462f2caa4d5a9e60991f848b6c519c45332b18232b900d9787dc78a685360336b685d5301315923f8df99d34b8267932496ae4981a2cc94739cf075343de4231736b42d9866b0ce7030be42aca98309021b24a1a518dd0107c2b03a75552c169b605635323d9cfee4c607c656724b48f523a1ebee51393e1538dca234d864066f7417b1b67968a2c03f9b85255148a9409bbe6543be9319a3777fbc586bac8aa5574612078a6e9a78640757f63c1646e015d64066402a2a8f36b7c96e0a50ea13c220103194bb188c6947e533b1a173cdaf225eec27720a61bb3017205e98258fb470641633d955d14589bc566c9fce9590b6141f9c662baa60ceac1a7b0e518e370c27da21e2a098d62433f2fc336340851e2e536e0b2ae8c2b2b58057b5d30a8fab602c48ccfada926455549ee4c15f2369f58742d5fa85415990faab1b76eeaba47d05a0c35653b36192a6b108046bca55443fa075f072270e836293ff543d729400693483f7b44f0c65dbb17b5919858877acabd77ccab92446a09c8be6653f9398b4d5540e8544d56d5c88dd20ea99344b747304f56b2aa725f1a858eb7bbae293b891ca61c2d5942204455cb726c29a23231eacfac678dbd002ea8395203172b35a448ed3944bb07bd2e11b9fb52caca2213dd482159821ef5d9a98d09147e272d3a9b84023172d0d1ade55662b02a9574c13a5d5b79575c25c9d46bc5c766e4768836f787cc6a771a772518e7c5a2f4716e007900db8abc8a630916a268b080cf12ac427a02c474ad28caa73a5793bb0a7593913debfc4cd353ab92bb23d78a2822527e58f52f4d5a70b2f05eb0e6231dc43e5fb7c27bf6870181709f1b0ef4175753687a66261f32773dcc520c752ca7ad6344155bc63f000e1c18be1d154476a4a639d2ae5e36bbc157a7c7f8291b6506f12aa8003784927284fe1b1a4fb70aba9a39d0775dfa293f9a29a4fa3712fda54c41e45c6696aca509d09e42618164c34f78b5b385750ea93d39abbbac58640ce09e5a5245a37847c78765d731596bb10123f51793ea5d97c0321fb5810a22af50406e53806569c53750153ca7b49dddea12baf4ade371b4c7d05e29369a5d1c71ee1ba62db26c74b456cf30832018cfca235b32174c031c53b4c653ee205c632218ce05676f2878930334c2c284d7e3b73683cce303694e68bc7f95b0d186acf5101d95fb6ce55acda6743c7512638e42978af9037272a1a5e23e3632059ee1a3367ca9bacb27930700d19327a0c6ac9fb57d3e41bedcdcc47efc18653c2c5cd78200ac77b066b018d137facac920790bc9e593cc243761cab947818e8ad7ae6701601644aaccb78ee7bc4e233aab6cf57188333e7b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e977918b12f00bf09aec2b492cf53686beb31c558d0493cc7b2b9a9dc7265fa9edb685d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +expected_public_key = b7fa152b25c460c63c4d18ad733422163c0e26ba99530074269c212f2697f2073bcac61e4e603b18b575bf696d7feb8724400848f05e91186052b05ac7828127802fbd1672b3fb45ff418374d61f1aca1c1b93af018cb60f006d04418088216844b29f9b64bd46710657ca30a054bb1bb0161a857edab220813170d1cb96f3d82365317cfee94eb1a8ba6bf82af10acbe3626c7284b622b314d72469ebc76d3ad8cceaa93e08793490ea0a73408a1cdbb066b67d1351af5a6c477d2b90b68a3982b70d32346cbdb15ef09736b28c23cbe03d18998270013509f13c7eb95d5a03895301cf2d0cbece1908b3c28e73e676304b0c98f7932bc246107ac07b27090c2779ea2b8c987b084d86bcc40496a1c44c751438af5951acf276b25414d4e37aafa3a1fa5b8fb0fa11be21bc76b7816aa3a1df142446aac524a6a41aa3411e00609f297e698026f852094e2a2e5e9146f812c283529e16256050204ad3b03f04e35af7d36799605903e8c3e2663f9e89791aa8cbf1b8047f2a159dd909d01a3eb3f081a930b26b6b3c32b7172b77bbaaf1ad51401c645b63828842ea7b7803f9699740cac72b56f434ab7e1c09b4ac5368dc559d603c5aa471cd673bac5abf0f858dbc672e16f819149094f2b144d008c06ba0c36ab2a61053629f994fc233a38576a7821229e79685c2147b7b15156493c1eaa2c087134f1222758b00b3cc10804561b24974742c2aa016e23cb19c868244c65371b6bbf31d5603b46e58bebf638fb7924ef4181d02f6a1da6321a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533d62b8d31889e6679251560d0fbb4f768501aebaffcb116a23422f48ccd89e0c645a11b0f80ad2c77a2f30b8cf415084e5c9f655824eca8be8835a81a6c9832e09c3c596417657657a9c85a13a54d3c0d2c427a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9c92ab3ca1a8c47c89d1a742cbf4352b762a60226cbbbcb28272856b2bb3f176ab32955c96a0274723a508730aa94730f998ce0e04ce1e67726412233e8b96c31481bd017c67f1aea09a3e96f897b70b969cf405ba7424a0e8aea4b45c6206752c075e2bd3b3abc53f99f2842a459a55118a10f87d8f0c2caf4180ec741738d6a04efa30f9b3b9af587c33297bebf8778b960596bc3095439ef3448c11871d228a0dc24718f6c59c8c73234a641c47917b27b46cda986a1857315911673ba0468641757ec5ae71c860de0b5ebf05cf6889a170743a27350b19e406a77427421a54f1c163862a43c6ec1260d45139b7419b0538ae31a0ac78584b3264cca519ec35acd94c1ae5b436eaf82fecfac8681224fa810fb0a95581528ae300081efabd7e599517c21f469208f4daa500b9225560b9381707440082675293dba332ca00c4cf746f46041b78d219eda4bbbd32cf07e37e20e15c25f8a96b5706fcc71f620abbf052a572d73b24c5445715c77187a1baa883a714329d619a10cc2c9c84b2c4c098f0e42c4c00a77c44845b45003b7c1bc587a3f6c10d34269430765da39550e2b78fd7b97cd9128a5d8653b7aa05164101a9285a9c1a77a8b255d1b8533a1315a82bcf7e6620c4224ce830b83844bb16560d6ef98819e0ab4523acc16961229a0b0847410b19647ca7836345b275609d5d12bcdfa5163b0c4caaf2a0f05993ed16b89dc14d33a60b56a0a298e453a4883c7b6c7bd2186718da1a29895b2c066bc6a2896947431fb224ab31b11f204f8047bd5e421d92b78357694d8959991e56b6a123373c00463bc259f78a3c2e7b3526331323e9af2bb55726795fd904160c302242b1bd7d65103da1395d82aa5f662e4edbc812479b0b79ae15f25a07363080d887fe8a0df37b51b5ab7c3e878d21086ca0e1cc47d877194cad6e384a81403adf05c430d22d47516acdbc946498a281611bb9f73ac3424f6cac3146faae1611103ca4008fa95a8ebca35ae114ffe14921a855f5049447643c391588444217a510ae31b82b5c159c928ba434890aee2c7268724bbc29cfd152b05d73198e7b62b43b9b03e081cd0a1ea7395246cc890735268f189f21c143e5f5cec76692e6d937faac7af3abc5480464f8b077c9352b14a22dc65514caf392d1ec6c81d96c33175f5832ab3bc19c54229f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_private_key = d338b8576c1fd9168551a681f9c590095b6b8d8474f571226a4b68ee81a83738bb964356edb663d925960388c92896029a201ec7f046cde497e3384f613a444634aa3c41656c6031d5233720241603612bec1032afa7b3d41242ce374c8b118cf6219fb5e645002530781cb4660403f88287d115baaa07ce95496a7232862282a653367fbbca1e337155a3c8905e368c1974418e735f93b6965fec11ce7b43d81710d727a4c4b434003b9110d013568b7bbfb341212543031c862fac505944b86394554772047b2a864a6675ed984583269362759cbb464e7e248a48c3554b8054ed9342aedc8e221439f812697b691bd5c89b7fb11ec716bff96c97dd73c45b00980bc6b1f69117c2329386518058e97b26626d98196025724baf0c5729109399e035ace9a630cb6d7ca9cbc16ab560da5c01e37601bc0dca7a3af891b80418c0056145c7ac8c176605411a39bfe843cafb4fa61463b20a504e984308f2b82ca7081a97951d0961b2664e2d7b41df902571d02c1fe24ec0ea998609248cf51cf2f81d96a983dbd29bb37b9a7d559c72fc0baae894583a842fcac92d910c7d682dde70a4a7b26e3259b290a182392cbe36b68d2e321708e9c00d8c06dca5043c1a461e76438b7801e8faca17045b272b16999471f8fb42f53a43294124c3b2b7f7a13eee8b195a01871909a70e41a0cedb37f3f733ee259f40c1cd12c79daf90788d78ceaaab9e1d20b7ff8800a17ac28953a4e90b257d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a59822bc6382b9cdc6072f0a6cf65c9dff2309d1a433ac52e6cbab472e788f76558d57986bac5c79b921f06e509db18c70ee88af044b527e221e5a5105a19610f059fbf6009b985190ac81640607cc4fb69d4892b5d9ac12bac26765aad5c874fe3080beff77961cb9e747a8e4b4acaf3f3b81d51a4a755ae8ef2994e8a722dcb5b8014c1ccdc6a79046664c3b75c02b91e0b4c5c250b8eda5d67e9a0984a6052053d22266b2413b98d841e8aa686f4e0aeb8d5b2ed2c8bbddb0374d0ad8cd47a0e6945f0ac352307ac0db224eba29bc09397f05b1308828cd42b85c556bf0a938959fa7cde083d3d0163c21b016133145ae0c47ef73604999e76f9ad19432f82e762ba8174f89a23d09333f7e677f33bc15bf996ae6999ada8747bb0c454412c2b651d2a90382937427ea555b3856d0250ab1e3663b8d78f3d96cf9eb90b5a501129715df5db38086076c4b351305a9718903abf12609fb1bc8a59162e2152f8e0c62241ca5deb5260d71ae162b7ea827a342584576b00dc674a5be149c7744d7ff43a5b04a3ebd38c110630ff656f2ff042eb603403d14f18eb17cf675c995c2790e936cf8b60e758484bc04314e50105b28346829077aaaca72acb46d331e9127b17dcae5e639d2b33b9f3cca468f731bf0b332ba41d196ab77b3c436702078730369cf59144540ea08b5025a4c880c1530f40a852e35f96519c91eaa680d90d25a4256feb1878b48e39143ce43378eb3335d3e03f2a358782e0b54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf29e1472c26b4d7f80e4bb3192de06ec05a6a85479e1fb34c240cb0164b0170c151d330cfa3103f41183e458a4c15b414a043a1b7590ad2c79cd3d39e2e6655f17a1497f35c801064b95912349c8878c910ba7bbe3fb25488947315b4aa1c5c10870b0c81b8ca3f6472d89638c2d283efd290ee108a9abb71d353aa512a5601f67e02b5b9074881ff96650b9bca29db27bb8a2f84f09069c75ef6e42f5c989d3229b759908262818215958d1bbc1a40dcce324a5b5a18cde861c2ea085641a814be004e5435a837f0cf7326710fe73bfee27a0a739ef5c08204c3a98ab98a1ba865c51a82aea57f1c3a62c12b7cdebc6a87ba13df51a1ede668797199b5943cf5a6c595452e627b27c3554a92b4488a476d28348124f0ceb2a29a2ea926cc656496b4656b4c0323361483469bd183604d1ccdcbf8a25d05adc1344c1315263f46a5c37ba98a96179b5aaea3d14b7a7bb6c6cb4a1d068f6809938f5a55877137542642cd3a06b03400d02cc9fbe83a94b63441fa1c28f42de5c81583d19c846020fb17ae65b1512580bb4d066c536926f7d571b7fa152b25c460c63c4d18ad733422163c0e26ba99530074269c212f2697f2073bcac61e4e603b18b575bf696d7feb8724400848f05e91186052b05ac7828127802fbd1672b3fb45ff418374d61f1aca1c1b93af018cb60f006d04418088216844b29f9b64bd46710657ca30a054bb1bb0161a857edab220813170d1cb96f3d82365317cfee94eb1a8ba6bf82af10acbe3626c7284b622b314d72469ebc76d3ad8cceaa93e08793490ea0a73408a1cdbb066b67d1351af5a6c477d2b90b68a3982b70d32346cbdb15ef09736b28c23cbe03d18998270013509f13c7eb95d5a03895301cf2d0cbece1908b3c28e73e676304b0c98f7932bc246107ac07b27090c2779ea2b8c987b084d86bcc40496a1c44c751438af5951acf276b25414d4e37aafa3a1fa5b8fb0fa11be21bc76b7816aa3a1df142446aac524a6a41aa3411e00609f297e698026f852094e2a2e5e9146f812c283529e16256050204ad3b03f04e35af7d36799605903e8c3e2663f9e89791aa8cbf1b8047f2a159dd909d01a3eb3f081a930b26b6b3c32b7172b77bbaaf1ad51401c645b63828842ea7b7803f9699740cac72b56f434ab7e1c09b4ac5368dc559d603c5aa471cd673bac5abf0f858dbc672e16f819149094f2b144d008c06ba0c36ab2a61053629f994fc233a38576a7821229e79685c2147b7b15156493c1eaa2c087134f1222758b00b3cc10804561b24974742c2aa016e23cb19c868244c65371b6bbf31d5603b46e58bebf638fb7924ef4181d02f6a1da6321a7c6a74038bbaf569b817a72803a4725569c82bac9f1c593b437b533d62b8d31889e6679251560d0fbb4f768501aebaffcb116a23422f48ccd89e0c645a11b0f80ad2c77a2f30b8cf415084e5c9f655824eca8be8835a81a6c9832e09c3c596417657657a9c85a13a54d3c0d2c427a8bd6bf91245e80ac30a1b630bd395c02296cd5d63d9c92ab3ca1a8c47c89d1a742cbf4352b762a60226cbbbcb28272856b2bb3f176ab32955c96a0274723a508730aa94730f998ce0e04ce1e67726412233e8b96c31481bd017c67f1aea09a3e96f897b70b969cf405ba7424a0e8aea4b45c6206752c075e2bd3b3abc53f99f2842a459a55118a10f87d8f0c2caf4180ec741738d6a04efa30f9b3b9af587c33297bebf8778b960596bc3095439ef3448c11871d228a0dc24718f6c59c8c73234a641c47917b27b46cda986a1857315911673ba0468641757ec5ae71c860de0b5ebf05cf6889a170743a27350b19e406a77427421a54f1c163862a43c6ec1260d45139b7419b0538ae31a0ac78584b3264cca519ec35acd94c1ae5b436eaf82fecfac8681224fa810fb0a95581528ae300081efabd7e599517c21f469208f4daa500b9225560b9381707440082675293dba332ca00c4cf746f46041b78d219eda4bbbd32cf07e37e20e15c25f8a96b5706fcc71f620abbf052a572d73b24c5445715c77187a1baa883a714329d619a10cc2c9c84b2c4c098f0e42c4c00a77c44845b45003b7c1bc587a3f6c10d34269430765da39550e2b78fd7b97cd9128a5d8653b7aa05164101a9285a9c1a77a8b255d1b8533a1315a82bcf7e6620c4224ce830b83844bb16560d6ef98819e0ab4523acc16961229a0b0847410b19647ca7836345b275609d5d12bcdfa5163b0c4caaf2a0f05993ed16b89dc14d33a60b56a0a298e453a4883c7b6c7bd2186718da1a29895b2c066bc6a2896947431fb224ab31b11f204f8047bd5e421d92b78357694d8959991e56b6a123373c00463bc259f78a3c2e7b3526331323e9af2bb55726795fd904160c302242b1bd7d65103da1395d82aa5f662e4edbc812479b0b79ae15f25a07363080d887fe8a0df37b51b5ab7c3e878d21086ca0e1cc47d877194cad6e384a81403adf05c430d22d47516acdbc946498a281611bb9f73ac3424f6cac3146faae1611103ca4008fa95a8ebca35ae114ffe14921a855f5049447643c391588444217a510ae31b82b5c159c928ba434890aee2c7268724bbc29cfd152b05d73198e7b62b43b9b03e081cd0a1ea7395246cc890735268f189f21c143e5f5cec76692e6d937faac7af3abc5480464f8b077c9352b14a22dc65514caf392d1ec6c81d96c33175f5832ab3bc19c54229f45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df7233c98fa4af17fd014a60d11ca5e929e4fa2524f7db289ce0947ad90657990c153b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = 334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +expected_public_key = d3539de5422f470189bd6c462361c8105549370a09e8ccc407908a4e433813f73e3ae465cf99af30105e6e4456b899777236466f05bd36a05494b347457439cc9ac66557580ef049071c7922f3770b4220063139a607c8019b52708976d184949cd88714f18130f0a6c91ca38680863eb9be2542a4b27a629dec949e552d8b3c86883211ec341b637555c70a8fa503412a771853d32cf1a5939fd7b6eb012b26e414b14710a4639096025a95fb8cb581358379330999cb6b93527ceb079b134021c19c9122640f90c11c234f808ccbe17b3e031b1a7a94654f82289e2755ae38b9fcd477afe576bad2218ce692b51205f61a59e644808c011c0ee0ac36a050a4c158edc9c770444d310097235890f2d630f85c0ded24443462906fb84d7cac3e7c1777d08a57a689302e99a3d9302faa4c0dec854d4872579365bdd1645706c744fa5a167b563accd8097e8c626ae63c8280663a382c11ba8f6c1b95ff1161c3b5679ec6c661c2b8081c1c39f6c732dc97bbdbbacb133006a7c94de933aa19156811a224829769637a54b9512d8a4e82071af50a66ab52301241bc5206bab6bc0b29776a4b630e59e72988c4c7fd83912499175a2a3d3a2270edf3a2977049bac7524cd69691f59442db348243881e04b8e9f1adb4a436555c52f2f729c345ab278011cde73521172e8fbb5509746ae871cf0e72416c2482a280c348862b313c9686d37ff0d73a1e216ffcd936d2941fb5bc77a9b0b771354fed30ca16121514541b5124386b835c22540ee2f9b5970c1508e41dee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfbd05acf507686d53257c372dc8279e89669284c76294aa3098462efda8c743b0b7305bde0693d98048412907b2d2b27892397b9f3cd31dbaf9446598dc886a4e1bf0f9c39e9faa3aca90ae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd1150cbdfa3609708e4de5365013c819fbade55636f2a311d7a2b2ef7b250632774ff22ef2e76029569346266e70bbc82ec09533f8caf60c4356d1023b4b4532f7c1e5da18f4582d40b8861166885f52c0db58357e7579c7516f9da7046d3092303219f327ab52a28cb6a246b5016fa6894599d9725fc3c2af262b53a4592f881f2a195d5ae75bcd36c30d6b7646424c219302c4e5794057782e7034eec6c488395710c8211ef954f9f7434265590862b2219045b1336af22889abbb4639ba0758e28f2378cd1b1a4225b4171c53691a9cc5986a6c3ff51ff53b4ffe3c4eb8585006c8667bc17b3a28c67439ac5f3c08a6e93a926aaf515c24f8a7c3e3b2ab2f5183def46f8ac996e400acc320b49254042ac43c7cb160ff32ca605438d7124b5a727099f48008d60ea2e63f5bf9b81e3183e1647251017e82827620070c96a32fe122632c4aae1590623ac191bac113e9c3676ee645fb762b0ff982e416ca2aa343f607a70405720e9c42ffd815be984042b37d5f76646db400da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca541169058521c28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceebf916a882b66752a7a6e96dce612ef5754c392207b5b1c69d362134aab5513ca757aab9cfc94db5302510101a73b7cfeaf7a0f1d259893c76d9111652a4ac02348c285b94f16c671fe953e1bb0ca222a3ad751096a1a05bb2789c0c14da099e75477ed038849dbb19de489fab582910bc70a3a80c6f76152d494fa067186958191a5101051b6d55449dc5a4434925ca9f610ba498a24b232ac6aa08cf477a99f5a223067aa4c91a7749b834c90d6e247653c6b6db65c5efa72f3cd9cce1510437268cf92753db242742e042def3019f85188db7573a43830abab80d4c176ad551c5c5216870276160aa61b92863c1725083a56df800735c5428b28adc49b75da02bf120996be7ccf9e20d43dba59b6900bb50456d6589cb2c0209e51258336034566ae1bccfc1fb314afab759b00e103c0a7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d63661ad0651d0f3286d3f055d1a307aa7371ae1a74f1a68d57a7438e4b5107bc0dcd8c4de5736adfe3170f8a1f01535a3772229da4386b4acc072c1611b53c899352b5ab5b39bb9cd4ec72e622c946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_private_key = 9bfc3a71fa83a4070db5064ada8410a770845e818c49b91e09a251e1925edb226ee8ab153f94b2417560d88959113a6bbc854b0065748e6a7db90977ada0216f3c41cff70e5202b306cc22ff8a138c360d75b9cb1bba849c5bcc8c9b55e80647e513c9e3e15f66a144f013822da24266765e3f1125f435bda4c46ef57430eae331e1d54c91960eeb363ca25387d0d441abb930e4a7c329191c5ff7a87996a4b1aa74162611e67b303e284c7098a65069356b55304b11b8bba66c5829647493c09bf62166017977a988333092efe98d9c13a2bce53f8ea2c81a0099b7d5c2b11704971366a5565cc14610df796c604700680226cb165e9acaa6ab507a923b4d472a4b6c9424e7f5a622f87f4f8a1083b4755067a93c285cc0748d241c7051971128cc5af4db5c1f7c144f98b6bf9703f5338628ca22df4b84d10312edda9df71442464a24491a62687928c22455dcc23eca964e9248543520790d813924cb58a0c156aafbcf63906ec5fa891936c7e16b5fafd98026d64ea2012bd75b6c5f376eeb74ae9b29cff7041c650b91a2b852c021562ba33b66ebacf787be40810f22aa43f4174571c77710f775d1719968a5523780b613262f94bc36b611b63f460dc6e02cc588af99f164302276b0386e697469c55928c0e62438c25af90577de0883cf45819262905ed30d9a1a7918b82f9b4a28ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d510245f8834e890662e06774f389c0c623be3212aae5accedb101c43463b68889ea9a2c21aa0acb5329ff80a336f8914fbc602e2b9ae452647777651ccc4bef70ac06423b66ec5982c861ad9723dfbc834ca6a6433174c1d6c1ab9569265a96ab5d48495d72122763b3a7275b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dacb140666610ec7a15ff18bc741aa69425508d5cf682bafb6d3c9dfe02d80349597f56fbebb7ec8031fe71b6d6c065c4e6b5e5d17abf3b412ded81efcc8b6b1935fb37b467a5cc61f318aed20678800726509baa73bba244030500050d4b23e4ad71349cb0877566ad100ba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ed80df4095d59ab482fab7fca432ef5e76affc77f74f4cda522a0085a4917d04167a00b09863850d6caa0621c2d473de0763b7d3168b6147bdb009eb260901fa82013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c43010ad15ea2eb1e05267029e5ad8139728a907b98761b65dd6dab895363159b48875fb6aa80882256a04460b2977280688745c5914c089b37bfc949a8f9864afec2e4dc13f6092070eb561d09b530eba2ccd66b87b0986adea1933448066521e28ac2ed9c57ede492799b401cdba8377d593dafc1a0d233004e25877242c30070779d8bc5bb488dd3988004b5a8554861b560ebaa5bfff7c89ded193ea077f421c216996c1445b165b912901b217315636a168c0216ac026fbbd4239858837b02dab5a39d1be6b072468a264661c5e34f42380c66526377c990092434bcb551a744227445c5108fcfc3cb4526d0b711dbd4539cea05a08a78fba723f314aa643a9260baa22b96842fa4995601c71dfb42a5719c6f3b9208b19728a8c085d28068412bbf3461dc09206feb7b1250607c1e33ac229323082cba12b139bb30eb21a5861d902c0e35cf2db3c227050cb8c309dd256ff4871186330be93492be78e267640b49776dc98adfc0197c896a1fa27af841351b5c790a6519f58c98bff08029fc09e3b960b6898577c92612d264833737c3e4aa1765c5d5b49bb12bc0df280890ec6b7ef55ac5fda82989603a7f513c5a41c04b341e1197b7d4049e2c01cdef47f27208a48aa0a2ba5706abb474c467897e154daea8410181c6d4cbbc9e73746d46d6f372fe6836d82da12a31b0673c10b35c9673d25830ed32ae795bb7d1aaf2cbc0433939a79d06dd33cb485a4bcde071b5c083978d78bd8e359181152fc535770548df0eb33a780c0c9e7bf907540a1f953c972b43527b0bc586b8b2abc865b9127caa4ea98a5de1aa2bdda772ab0702f983ec8a4231bf48c2fbb37a4247783bb0221098a15781c3dec95c1990b21c88cd1f911624600252759d3539de5422f470189bd6c462361c8105549370a09e8ccc407908a4e433813f73e3ae465cf99af30105e6e4456b899777236466f05bd36a05494b347457439cc9ac66557580ef049071c7922f3770b4220063139a607c8019b52708976d184949cd88714f18130f0a6c91ca38680863eb9be2542a4b27a629dec949e552d8b3c86883211ec341b637555c70a8fa503412a771853d32cf1a5939fd7b6eb012b26e414b14710a4639096025a95fb8cb581358379330999cb6b93527ceb079b134021c19c9122640f90c11c234f808ccbe17b3e031b1a7a94654f82289e2755ae38b9fcd477afe576bad2218ce692b51205f61a59e644808c011c0ee0ac36a050a4c158edc9c770444d310097235890f2d630f85c0ded24443462906fb84d7cac3e7c1777d08a57a689302e99a3d9302faa4c0dec854d4872579365bdd1645706c744fa5a167b563accd8097e8c626ae63c8280663a382c11ba8f6c1b95ff1161c3b5679ec6c661c2b8081c1c39f6c732dc97bbdbbacb133006a7c94de933aa19156811a224829769637a54b9512d8a4e82071af50a66ab52301241bc5206bab6bc0b29776a4b630e59e72988c4c7fd83912499175a2a3d3a2270edf3a2977049bac7524cd69691f59442db348243881e04b8e9f1adb4a436555c52f2f729c345ab278011cde73521172e8fbb5509746ae871cf0e72416c2482a280c348862b313c9686d37ff0d73a1e216ffcd936d2941fb5bc77a9b0b771354fed30ca16121514541b5124386b835c22540ee2f9b5970c1508e41dee69bc15c8c5a16abf91487a1a5c3c778396fb785bd9465dfbd05acf507686d53257c372dc8279e89669284c76294aa3098462efda8c743b0b7305bde0693d98048412907b2d2b27892397b9f3cd31dbaf9446598dc886a4e1bf0f9c39e9faa3aca90ae387aacd698906c38e81a4990a08c80ef340b17a78fa89bb9a67813439bbd1150cbdfa3609708e4de5365013c819fbade55636f2a311d7a2b2ef7b250632774ff22ef2e76029569346266e70bbc82ec09533f8caf60c4356d1023b4b4532f7c1e5da18f4582d40b8861166885f52c0db58357e7579c7516f9da7046d3092303219f327ab52a28cb6a246b5016fa6894599d9725fc3c2af262b53a4592f881f2a195d5ae75bcd36c30d6b7646424c219302c4e5794057782e7034eec6c488395710c8211ef954f9f7434265590862b2219045b1336af22889abbb4639ba0758e28f2378cd1b1a4225b4171c53691a9cc5986a6c3ff51ff53b4ffe3c4eb8585006c8667bc17b3a28c67439ac5f3c08a6e93a926aaf515c24f8a7c3e3b2ab2f5183def46f8ac996e400acc320b49254042ac43c7cb160ff32ca605438d7124b5a727099f48008d60ea2e63f5bf9b81e3183e1647251017e82827620070c96a32fe122632c4aae1590623ac191bac113e9c3676ee645fb762b0ff982e416ca2aa343f607a70405720e9c42ffd815be984042b37d5f76646db400da5c4f08baaa41b33fc78ba147f3cbcdf63f3f543752dca541169058521c28449d0c78cc8bc95784d8ca6cac6ecf2745a78bbd589353404bceebf916a882b66752a7a6e96dce612ef5754c392207b5b1c69d362134aab5513ca757aab9cfc94db5302510101a73b7cfeaf7a0f1d259893c76d9111652a4ac02348c285b94f16c671fe953e1bb0ca222a3ad751096a1a05bb2789c0c14da099e75477ed038849dbb19de489fab582910bc70a3a80c6f76152d494fa067186958191a5101051b6d55449dc5a4434925ca9f610ba498a24b232ac6aa08cf477a99f5a223067aa4c91a7749b834c90d6e247653c6b6db65c5efa72f3cd9cce1510437268cf92753db242742e042def3019f85188db7573a43830abab80d4c176ad551c5c5216870276160aa61b92863c1725083a56df800735c5428b28adc49b75da02bf120996be7ccf9e20d43dba59b6900bb50456d6589cb2c0209e51258336034566ae1bccfc1fb314afab759b00e103c0a7f5cad05a4bbf1894050ec9c2488bc3f89b685789912d43d63661ad0651d0f3286d3f055d1a307aa7371ae1a74f1a68d57a7438e4b5107bc0dcd8c4de5736adfe3170f8a1f01535a3772229da4386b4acc072c1611b53c899352b5ab5b39bb9cd4ec72e622c946f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f091210fb4f6fac00a24167d9bd2761e601db0a3734e3c835d1e9c5865b1e379caba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +expected_public_key = c675bab636ac40ecb18567a8e6fbc63a52327520bb770a5d64349817a13cd365c96741726aa9107e9a4c04796dbe92061697131e728104c9c6ada26ebfc51632898564d89b2919438ca1308c53387604c162a424afaa2af9ab0c42b50cc50b3318a15738057c2f1806017a7bac76ba523acc1c66111d45c253ab299463cfce584ece769707a6b35d6114a8b92939a16d27a7be7f72b660f0b851e4950c20b33c074d307c8fc9b51454e41a96a8ac76cc30a568b4bc442177e7748e4b0f7d31201569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2bf23a19a5740fc9b9bf18859efc79f9e9178bb542823a4fef94be8ca589abf740d7880380e78853708cb9220e5d0ace428c58a543acffd8333d2831857c3784090e3696a3b011683899ae31b40513e9589467a3cf2891439871a1b240fea31f2fb89956d9966ca204a598050beb2c36f9a6851820c87a5262a9cff23b1e7bdcc9d060484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ec103864b75ab25a013d7c183955884bd01c4f58cd410344396358bd6901a94228275c79a289b385c788884b2bd3371d0852b0ac4a24107a87f1da0e6fbbbbd0a25c9cb14b7f25b7432c8148a0c91f8c7616c7bee7119a8f9aa4da5291a820922ea68f2bd62c4300cab4d10a73db255b1aa33d523d774aba41fc5f26326220c8b3575520788c0476bb3462f73c61016c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a93001a8c4c539f576c735068661c02026bb22ce5932bcab118827107a784ce94c2c89444a7b03a2386772d89106b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f502042c388292394a4940c0470458726b76f39037e10821fb56b3e4f38c752f4278b8b1fc332a48da56cae9c56bd03343659b4abc262fee6855875ac2b8aabe02a352919ba6363c6e75a8358d3297386240aa80f0aa33b1a79cae3c9ce40f87520ac713bfc2dc9da6c5b2bab6443383279bc9f3433e4080c7bd5bf22306e4fba2a8ff0a1f7978bc6a7bb809664783c36ac81445d4964c8ec6e9616384c60636f6ac08aa1c23d182fe70034ff2390442190f8c2cd68c9892bb0a6fb29c5e3480697145b150675992137c5a16c507c96180a3129417d9e30815e30b90d05835b890cec789e3ec8ab7dec509919cfd670241250822c539fa2ca8d9d619e22f050744727bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb569147804112a0046e2149903fb5ae0e56a4ec2b44397973441394175bb675c3198800e1bc56185ca7076345ac1623ac0ac1f10f099fcf971feacb965482a2bfc585bf30647d90f7ba27cd76891ef5b3ef84b988f2a407f5552be77559d026e385627baea2debf3ae73e3cd1461b1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526cc2fdc6c7a39da80278182347a3330fa332e071d8f31321bf32f4507b16e328fa7892758f2948a1a951506222833c0bb68140495a7a5e942c6b17e674733ce754eab747e96d2a077e7024df77388b6bdb807744db74612a8c72011be7d8b0949c75cd1b6107c2422e30c1e577b3515556a10c1ba712aca7f6988b3873705257cee724acf431ca0f9961db020ebc784e4f27c6fbc062857015db28d64004cb41bb7ea3b5657e6b65200b3959c642b213dda13a1b25377c4a47c43dc2dccf3607aa02ca28a4067095f541b359e21b39004590ebba6d6db8fa461a1343b824d1373f872343e8bb605729b674c66f7e5c76b536539f06f919213cc14756ffacd5789a46e7c8ad789ba0f6237998487c1912e86b087c9388d3a6a9c18d505fbba2f7aa6168508b1c8702a2fc167f2202ac21ba862917f6d78971aa7296ce1306d2a1f2f06b8a3a214ed45765f6a05a7445cdea385ce7922e8006b549319cb38904f38a6f932304037c4fceb9647fb7ff9e9aff5dcc951aa3e4bf50c296b71259650b5047c94ea2696837e26aa1d18938851198928db1ea22758c6cac0906a995a022998a7a942626c2cec7a5fe83948d74509c61915819425120d9e6580c0a3776ad41a95b52b2e867b6d7242ccf281a241a88049058d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_private_key = 5e484946337e3f4135d738b0862b69f7b247a5bb0812d56201300c53bb87b798b2b551ccea75a87f002d7de7878ed08e976a2cb62b4aa559bc36816e9690973f608b262612f89b5bc784365e33193fe9013c05818e0a7151297ea53c95089388be203071d0335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92914137c33773660aa15557c32b7a086a5a1cfd125dea60183ecba94da22f0f3a18dd2131bc792c4013b7bf84a7840c976c53117653c4f947839d8cb35538bb97899418688a9e062f9fc17d77450d85261aab01bd9ee77e917966bd26bd3d3990aabc8561cbaddc5a22f8c80d99453fa7350b2a022e4ca48dea6c9c07309543611abfc7cda76aa03e51acfdf0cc73921ef2d02f45990aee50ca77b93f14e4bef44576134391f7b67658e1cc7876713742267a556ea8f562bd858b24e04314b025ccb5be0650642a23460c3c65e0d6cb68232cff709204b7b7cab0741807100a712686b982f632095d7730dd9385a7a26c23741474e12cd8fc259ef346b5f287eb01b046104ef8415372b47da145ab0c5c1774626b5dea7d72db4c62fab14c03ca51384420690a799194e8aa05bb914db21956bedc948299baed7289c884ab9833c8669422adf51d4e1a0466056eeca478f11ab55ce2ce34430addc889044a5601357ea6a5b097b54252b046fa83c0211c236953954c36840e390d2707848c0b879aba2354ea200fca56cbb86c0c2269a81c790b966893f782aae9a4bd1b02fa85995a757ff2083fd26347c97711e07560af77cb59c7cd64f7cdbc880ad26a7bd7fcb9b210710e581c49453a3200ac08554a641068e6879ba6665ae9f281fc14c8fbfcb0cac0081c1a06db017d80048b324248f699825a489d0726893e109127a0ae802cca29ac56f6118d209a54cb842c9a8c539e43b9681cb868018c95d872c532a10a77bf52a796d33187fb8aa3fd780bd2c4b30fb7394dc64b0fe05b81128763a1325bd00eba411247b1c22a1146feba1b255c51f74999dd29a9453151bd9869e3d548347b93c1b798fe92a053b88c80d7afa5c561d31435d61251253b9a4c2b0f42830c81e990006dcebddb7002240ee8e276d4e31c2d249b84414f3997b9c4f5c0698cb2a24c48e3605f6d704e5db734ead12d62634dedc68ed6a1248273bad5ecac0651978b098ffcc148667671d4b59ea6095b0b363c31299e5b90282f914bebc66f6291338bb7600c8310b83963336952ec33854ed7c979b71f30188180b11bb66314c93242ecb890123c9f2aaa786acbc7dbf560cfc1625d06c3828998ed51b79d28c583bb38719706d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d7113edf611c521761be671fe37baada7a2b4a114dd458a19966a2a42914d61b47aef5abccf8240c88af752b51bcd0a3788c2aa38aad8dc00d835476c8386dd3a8628b261f1d6b2b9f771842c97da7bbc3d03696f60524be6476430044f6a8aa48c22901f750dc55c1ea7813ec3518b26b3fd0657ea6fcb6be94c026244a0401593664673faa680f866e174143b0cc086fdacc1f7126c3e941f090332d8487d5e66061d5311c9b5c8edc39bdfc34948400a9a3aff3a85adc48b21e11b57f853985689697a591c5170b2766a18d18937ce92857a99095fcb6a2524bea122ef1fc8f6aa724f754832fc17c932388b728359e55800e3110c89b8b7b711aff4785259b3e1b2b0b886a057d71b035617ddc7c0c8b1bcdecd50a7135c8a68a2fa2f7b62b10baf6325da837368280102d7a7439d328f91b2173d8625d769a6ea936990299a02329380a85a818524f601b36e6cfa8046ed2f7c1b5c13260152aa34ca30e1887f2849c61b41649913138b74c817b2da9174d3ad4ca15653f768896837323dab2c18781a8ba793d54c9126df6a6ec044b7e709870422a8a1c030f238767c91d75185def8002c105806cf728897b382aa596dff7ac969a5cedb9294dca50ca1c74ceb7605e978722b148817964cc1159883a6dc5094f02a5767d4bb5df6304d3148bf009068a1b2e4df78bf021182e985982f4b2629c049dc26667746c4503ae0491728202ba0b55a8248c700484597bab32dae41607538bcc5c9dde4a198cb81ebd9c143eb9b612930da8f56fe3d8c02863c04cea9ec675bab636ac40ecb18567a8e6fbc63a52327520bb770a5d64349817a13cd365c96741726aa9107e9a4c04796dbe92061697131e728104c9c6ada26ebfc51632898564d89b2919438ca1308c53387604c162a424afaa2af9ab0c42b50cc50b3318a15738057c2f1806017a7bac76ba523acc1c66111d45c253ab299463cfce584ece769707a6b35d6114a8b92939a16d27a7be7f72b660f0b851e4950c20b33c074d307c8fc9b51454e41a96a8ac76cc30a568b4bc442177e7748e4b0f7d31201569585659b55deac3a6ca4dd264985df553c85c9ed07b61e6d58f2bf23a19a5740fc9b9bf18859efc79f9e9178bb542823a4fef94be8ca589abf740d7880380e78853708cb9220e5d0ace428c58a543acffd8333d2831857c3784090e3696a3b011683899ae31b40513e9589467a3cf2891439871a1b240fea31f2fb89956d9966ca204a598050beb2c36f9a6851820c87a5262a9cff23b1e7bdcc9d060484115568463b9ae44b33d7b6c0f46619299596fa3c3ebbcc15f37a7a3ebc9b42332f483708f7ab08e285a08759ec62aa06838c7ec103864b75ab25a013d7c183955884bd01c4f58cd410344396358bd6901a94228275c79a289b385c788884b2bd3371d0852b0ac4a24107a87f1da0e6fbbbbd0a25c9cb14b7f25b7432c8148a0c91f8c7616c7bee7119a8f9aa4da5291a820922ea68f2bd62c4300cab4d10a73db255b1aa33d523d774aba41fc5f26326220c8b3575520788c0476bb3462f73c61016c9349bb00c5c59b7a740044b639ab59253b49e23c8ee36676e015a93001a8c4c539f576c735068661c02026bb22ce5932bcab118827107a784ce94c2c89444a7b03a2386772d89106b49acb607abc86996a351b6b7f364e9a05c746377520d7a27a154f502042c388292394a4940c0470458726b76f39037e10821fb56b3e4f38c752f4278b8b1fc332a48da56cae9c56bd03343659b4abc262fee6855875ac2b8aabe02a352919ba6363c6e75a8358d3297386240aa80f0aa33b1a79cae3c9ce40f87520ac713bfc2dc9da6c5b2bab6443383279bc9f3433e4080c7bd5bf22306e4fba2a8ff0a1f7978bc6a7bb809664783c36ac81445d4964c8ec6e9616384c60636f6ac08aa1c23d182fe70034ff2390442190f8c2cd68c9892bb0a6fb29c5e3480697145b150675992137c5a16c507c96180a3129417d9e30815e30b90d05835b890cec789e3ec8ab7dec509919cfd670241250822c539fa2ca8d9d619e22f050744727bbec916289aecbf47bf48b9c6ed6ad5ee5745a865859253c84b39fb569147804112a0046e2149903fb5ae0e56a4ec2b44397973441394175bb675c3198800e1bc56185ca7076345ac1623ac0ac1f10f099fcf971feacb965482a2bfc585bf30647d90f7ba27cd76891ef5b3ef84b988f2a407f5552be77559d026e385627baea2debf3ae73e3cd1461b1d7f9ba55daab9c4bbca8045172cc8eeefbb36647bfeb033495986526cc2fdc6c7a39da80278182347a3330fa332e071d8f31321bf32f4507b16e328fa7892758f2948a1a951506222833c0bb68140495a7a5e942c6b17e674733ce754eab747e96d2a077e7024df77388b6bdb807744db74612a8c72011be7d8b0949c75cd1b6107c2422e30c1e577b3515556a10c1ba712aca7f6988b3873705257cee724acf431ca0f9961db020ebc784e4f27c6fbc062857015db28d64004cb41bb7ea3b5657e6b65200b3959c642b213dda13a1b25377c4a47c43dc2dccf3607aa02ca28a4067095f541b359e21b39004590ebba6d6db8fa461a1343b824d1373f872343e8bb605729b674c66f7e5c76b536539f06f919213cc14756ffacd5789a46e7c8ad789ba0f6237998487c1912e86b087c9388d3a6a9c18d505fbba2f7aa6168508b1c8702a2fc167f2202ac21ba862917f6d78971aa7296ce1306d2a1f2f06b8a3a214ed45765f6a05a7445cdea385ce7922e8006b549319cb38904f38a6f932304037c4fceb9647fb7ff9e9aff5dcc951aa3e4bf50c296b71259650b5047c94ea2696837e26aa1d18938851198928db1ea22758c6cac0906a995a022998a7a942626c2cec7a5fe83948d74509c61915819425120d9e6580c0a3776ad41a95b52b2e867b6d7242ccf281a241a88049058d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b246c206507b89f46c6e9cd5e78b6cc78fb3677ee609cc090cf3782c876fd5f941b0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = 995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +expected_public_key = 10089c89021be2da6c17ea926bf636c042c59a1b79941c248dd3079f623095437766139de109c3346147d1f8a069b2316ed2606ca1454e364e9c43a80b0bae79f005e0ec3e006d1adab7bf69fa5b098166aa9520de263e25a36436d3a9783b96a763c9321727eb65a7207b51d526c6182c1d51372316cc0ddd946077a81f6487b34d68b59841ce41e779885027912c5d6271adeaccc07ddba319700694f927a374b794584de181b890f651043a1b391a7956477b436307dc8b0d0467bc05206074d17f560160774a8477509bf5a936811bb9acc179834a9d1106af0438148d076e4c3a7c70d7231dd475f06778eca68e40210859b092915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91c82028eb18d99556abec2cf3aab979d125c137b75586b4d419758ff68229870869be755950100f9c2bf6d706cb9bbc5289489df8acf49046ea3d27fe7f0cf0e148286970010151a11b879f9035351ab10a536b6a3144a806b8fac1389f58b0395fc7ab90436b440bc9e66ae3c73a5e8e5ad59662286fa9a03e62c5eb100c9b63dccc74793080ce967b7d162438a492ca2815f56950d02aab7f12254d75c499840c5d662c0c10185b4ba3f84a91b37745d1ebac3a2440dd899619706756ad70468e1515d4c0a765942dd5a84af8a894cab90a724a95481285a160102eaa39591ad4e2c871a160be835012705598ee166bf2622bae3acaab37d4fda18997212b831b9b043082ef2b7b86423bdc15d2be82687c35e12c85fce726f340634c1107df0f50f3253764fe4cf0d294d27f28674f94ad16b7d03f91fa62a42ba154e35496e9b2aa884ab27b5332514c377f78a2fb5e7ad85d643ee94763095b2f2616bf87439c22a26c46287125bc7bac3aab30b1aeacccd25532b326983a37a623f0a2df3d7cb732124f89c37ec1881f2c5993667339d825b68908cc7923d02c55e7f967d3d3b8d01ac87128b85c465b285d60869290a78b40d48d9c39e92c298b313eab8a8b1607b6da8c22967ada0294696988d5d251ea0565c84571914156feb5820e5ea145f411f5ff64b587a99b88cb08ff4270cc89573d901cdd5624c0a2c3a654b99a0bf602acfdd15c06d69077aea18e73ca0c2e650751a68b659a568c2742b626d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1e12041e056ba02bce42d9ca15f5a241db89e2510469762690d270d1e16cfcb92f715975f68b44e75bcb98e521a5c2be1e4a2e5ef07bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fbd00ee503966c8118a1993910c6ad99511da8216431b26aa7b09a5f304201acba84670714c410e21a2d4517a0a1f139304a6fe9c63371f65d43b095b16040af3ccc487840cc41a63bbb6e2dc49731013ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef33b176f31104a3185dfa62404dc4a771877fb94656d15c43142bbda1417a7c69996681a0c69b2d7395e694c4ade0a5886d28f207722855a30273c91e2c19a2b40b62a554f1ef9c282b51015504c4b84714a99a3ef33504429976c2c036a9782b0f2be79924d98700d6c066015b10c03db90844b7d4ffc14b49ccd5680b1c1d9c15ca935404737093c20a05461c45abcb81c6a19b3a0abc168356882b8ec3549836faaf354d3b60d1a5290a883ab1e19b9493c26113b3d03b8c3fec053bbd14b4be12c80ac412b6bc1328a4fa5f1a3f46bc4bc685c7da98533422aa2a8c9822237f62c969ce064ea0402cc656a88c39ddf221e3d6a52ecd38f160a3f71c281a02a24beebbb1c6c9025dcc51447a7f5679fb0e382854a29d8088b5fa11c59c439eef92f869c4fc8b66ac7656c385c0983b07aa98a71abd2b576212fbbd14b96b19559a6cfe5dc1f3549436a4263bd9b8a185740b4eb16e09184dfbb07ffb7266c275438e13208e4a2888b63fcca6cd8b5abbc14769bd61a74f34627b896f1e85c03202f4d58932c183d7cb4a5548cc540a32aa9c558e9889e10d706a809aca75218740bb6c39761bcb0bb0c76725eb80bd5a46d074864dda334359b4d4dbc7c8da2b413dc20a1201ae9e7acb49c905145307ccc92fba03c02045c9632564b68cdc1e9527b239c1f9a7f72358949b2ac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_private_key = de4627135b3976b8ac07c0059bb28d09e98e3428228c1786c2e8a1d6029d93cb9eed217d09b03e9a7561af7441e4271c7b6c8c862c5a93e955a05a87b01a63d9e8a334b26e1fc0346051bf31d078860a9afe939f4a90c2a395b2b6c205475164e36a0c2930cd26e26420470b0d068e36971a978b17be984a418a3cc5c6b62ab00d6dca5657f71e08b215edfb88a5b6751eaa525dea4b0bd41430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638d808f78535b9fc6c6bc0c1402e16f0b784f9a22a30e5c6c1932c2063bc558a7b2636c76d5c0cb77e6c5518b3b31d920a23b2bfff3ab93fb03b3386f670b07655989c5185d5d393631e9acee701dad333379a63efbcc636bf2b4fa05b84a375559079c5909651e481da96b01a771befc7bc407db7d9f94b819a468d443a7aa8c9b4741266875268602336c1b1160a4ce5d41c57fb915335c87a72a7345316373d921a6d0ca09606154199c4f06c244a7c568bc5d82449149f92ad3350b51d3c474e77a3a1053160570c876132434aedd92c8961b95588910102c62ae1a75479175cdd666ab85478ebb6133920e9154441f1383b0f147137614dadc823f1848fa478b1f301d3f745c647c216c741dfd3b3195483f24f1a5313cb458273ffeb559689004cd534ec1369b0c68a873651f7413037118c6f98c538dab9c1ec649ff2301a03a650cc0c138e79d15f9079a639737e840a7dc720b173bb329a34cf65418495e4df2805a491a4c96b47d452725850ca8eb3944399f9d14157fa46b76f0891525461113766dc025ee1c2e735198c3db253a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb441cdfdc9fba20a9ce2943759c4d08c57a0e74bb0e1888e94723169437aec19aec1a2a46c81ae4645de32bb18f3527f4dcb8221a0f7be74f3f5a8cab0609be216465819fb858232b008a855c9e6b54439a67aaffd9701967bc46a274d1d6ac1d45cee7c54cf49669e89a44ffd7b73b2a12327a85bf5938e6975b949c03ef3a1d824ccde033cb175a3356c8a998e4c69d94630a896606fc1979dcb5c172a54eea2e99d5ae331bc64d708fae45c514a2544843ca59c3c122947bc3660da7357ac0e33f55485e79eb3117d14c42ec5c56653e0dd1a4e8205fe571823098ad8d9844a25b92238063a92040c500cc0bc2b25b493e4cf69de95c87b03b773a796d13f42014847727345888eb06d9251aede24d03e292cb452a3a38a0a461c8b4f9cd9f87b09bc0ca98e62e5027595c24792f818865777a346004fe3b5b587452648263aaf688154526d591acadb74520f3627d7395ec7b71dc3c6e8414985d591a05c88b6455870c48b12c576d7b328b88795295c051ca6293b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c83c28baa424b19370afe997d8b08e447a2eff376024f5ca54dc8ec0972b96f057acf5a6b0d32869fab3e1797ee2571b1620a076082c4ba6799c27b07fb073092a7a2f7aa110635cb94900e487a6664b318f54956039c57ce509ede489faabac96cb11f58c87708a8ed3408a526701bfb8507d67415fe64e7d41081ac12c21f3092af02810c604f02c4064e348b4f98f6be65d87650e56e7667cd5179c347a894b5a9da3a3a413c2d3a23e5dd0c7dc841e10e4a83b3bc0ead17b5983a57821489dca73d1656e97632beb9a3aac017855a74f5f393eb5e42c96a207b06687030b28b5e09afd66225ae892200969ce41420f960e44963f634bb9f69c7c4cc2849f258040257def4941d9b54476d2ced88799140807531b817dbb1b2da7a4477abd378155da169a84086150ab09ac8a980fc14db247b3a76723fd67701644bf72810394b0ac77e74bf94416d866489cfc286da29d62c1947be88a0cb78aae94610d48738019768df89b38198258dc7f70d62a3fa72479b9aaaa4a84259837bfd4872d8c708d478a0e674a66da6cff330a6e140577c6acfb83cf4eacc370ec57fa76c76c765c39f5a07b8b1a244265cd03ae02433d3fd438d5a885ea03808c6196e4a3a459ca6d6b456a6fb961fed58ec0d353ad36143c841cc8a0390fc55f35d50400156398020051a10c22c69207fa839e12750cf0a5ca404c6b5344b9671e6e15502ba17c37872a9bb390cd379281651047fac2b6d20010089c89021be2da6c17ea926bf636c042c59a1b79941c248dd3079f623095437766139de109c3346147d1f8a069b2316ed2606ca1454e364e9c43a80b0bae79f005e0ec3e006d1adab7bf69fa5b098166aa9520de263e25a36436d3a9783b96a763c9321727eb65a7207b51d526c6182c1d51372316cc0ddd946077a81f6487b34d68b59841ce41e779885027912c5d6271adeaccc07ddba319700694f927a374b794584de181b890f651043a1b391a7956477b436307dc8b0d0467bc05206074d17f560160774a8477509bf5a936811bb9acc179834a9d1106af0438148d076e4c3a7c70d7231dd475f06778eca68e40210859b092915782db538e650bae18537ac3f7a3e46bc76919af12bc47a3b67d0e44b91c82028eb18d99556abec2cf3aab979d125c137b75586b4d419758ff68229870869be755950100f9c2bf6d706cb9bbc5289489df8acf49046ea3d27fe7f0cf0e148286970010151a11b879f9035351ab10a536b6a3144a806b8fac1389f58b0395fc7ab90436b440bc9e66ae3c73a5e8e5ad59662286fa9a03e62c5eb100c9b63dccc74793080ce967b7d162438a492ca2815f56950d02aab7f12254d75c499840c5d662c0c10185b4ba3f84a91b37745d1ebac3a2440dd899619706756ad70468e1515d4c0a765942dd5a84af8a894cab90a724a95481285a160102eaa39591ad4e2c871a160be835012705598ee166bf2622bae3acaab37d4fda18997212b831b9b043082ef2b7b86423bdc15d2be82687c35e12c85fce726f340634c1107df0f50f3253764fe4cf0d294d27f28674f94ad16b7d03f91fa62a42ba154e35496e9b2aa884ab27b5332514c377f78a2fb5e7ad85d643ee94763095b2f2616bf87439c22a26c46287125bc7bac3aab30b1aeacccd25532b326983a37a623f0a2df3d7cb732124f89c37ec1881f2c5993667339d825b68908cc7923d02c55e7f967d3d3b8d01ac87128b85c465b285d60869290a78b40d48d9c39e92c298b313eab8a8b1607b6da8c22967ada0294696988d5d251ea0565c84571914156feb5820e5ea145f411f5ff64b587a99b88cb08ff4270cc89573d901cdd5624c0a2c3a654b99a0bf602acfdd15c06d69077aea18e73ca0c2e650751a68b659a568c2742b626d37f775d2b9b66da7a331cc4bbc087866b596b7b55c600864595743e1b363ce38bc1e12041e056ba02bce42d9ca15f5a241db89e2510469762690d270d1e16cfcb92f715975f68b44e75bcb98e521a5c2be1e4a2e5ef07bce98bf8bdaba631433c5a96f9fe7782e756b8e54714f0466fbd00ee503966c8118a1993910c6ad99511da8216431b26aa7b09a5f304201acba84670714c410e21a2d4517a0a1f139304a6fe9c63371f65d43b095b16040af3ccc487840cc41a63bbb6e2dc49731013ef885b0e3ac5e2ba78d19265b3f36c1bdec49697a48252a78d7c4cef33b176f31104a3185dfa62404dc4a771877fb94656d15c43142bbda1417a7c69996681a0c69b2d7395e694c4ade0a5886d28f207722855a30273c91e2c19a2b40b62a554f1ef9c282b51015504c4b84714a99a3ef33504429976c2c036a9782b0f2be79924d98700d6c066015b10c03db90844b7d4ffc14b49ccd5680b1c1d9c15ca935404737093c20a05461c45abcb81c6a19b3a0abc168356882b8ec3549836faaf354d3b60d1a5290a883ab1e19b9493c26113b3d03b8c3fec053bbd14b4be12c80ac412b6bc1328a4fa5f1a3f46bc4bc685c7da98533422aa2a8c9822237f62c969ce064ea0402cc656a88c39ddf221e3d6a52ecd38f160a3f71c281a02a24beebbb1c6c9025dcc51447a7f5679fb0e382854a29d8088b5fa11c59c439eef92f869c4fc8b66ac7656c385c0983b07aa98a71abd2b576212fbbd14b96b19559a6cfe5dc1f3549436a4263bd9b8a185740b4eb16e09184dfbb07ffb7266c275438e13208e4a2888b63fcca6cd8b5abbc14769bd61a74f34627b896f1e85c03202f4d58932c183d7cb4a5548cc540a32aa9c558e9889e10d706a809aca75218740bb6c39761bcb0bb0c76725eb80bd5a46d074864dda334359b4d4dbc7c8da2b413dc20a1201ae9e7acb49c905145307ccc92fba03c02045c9632564b68cdc1e9527b239c1f9a7f72358949b2ac4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9920560200b8d070d1db2cbeedf3cb322ebbab3edb80cf474b4178633c210b2fc74b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = 3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +expected_public_key = f2810baed633638b1737b5ab13fcb47e181e6cb86c69301b77b85e2c64305f1584e370934a02aafdd27c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab9599544ff08a4a13643e181db6c752a8a5c948d010e8743ecc064ea034444f3a2b207bc3a0606600358907708bc87016261a61b1547bcc8421c009778ee31598d47a48d3a99e9a24ce230b9568cbf4bb61d9a0aa512b282e2506a51b0fe92507bb7cb044e93ca230b6d9f97cfcf31b9055c9775419684aab2609a1e11b2b354223c9761f7d6b5b02a16f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824c115c69510666308330901208d02f1a6057a0f5481af4956ea5281c956735d28e49173031b688a30289d385a7718c2c21c300d7ac3fc81bbfc6747c60f4cdb9c037c458c50dd1605ba167806a6fc32c759f2942dd81962ad657b51942b3fc8d925b9db72b1fd2b303c05043638a3217d1856d8b243018b0d8679db5c3364a85b78c913793e87855b382b3456d3d7c1c2b82bdb94c6e96732c6f455e4e631fd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be1b09430f2ce72482d6a8673a8d511a8a1c506a2cf4facaa9e489d6a3a5322410464d590d0f52b957b28937b543bd5a01f07261afc810d41bc815469e145862a3238bb194da838c642b817db611e18c08325502778922197e73aaa2c030869ca3ab06b22827feb4465ae60975a61255a405db1f112a2087218619bc9dc064035774306b14d4b6003949181301253034323f55bd0818097193d449a3ccd1315ee375c7efb833d03a87a881cb5dab7e0d045b6b80505cc18d8e9be1f1a7740d4981e31339503b1a2b22061d484d9368b8a5193d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e470999e90627014b34a7a8b168010ddb76f994783b5f41ebd60697198262cf42efc13128a45024386c78851c709389262d10d65c4784eb10c2cb13d9fe819cb4c6dc0c34da8c22b69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbe917b37292630518b093b98d39c6fe0138257467f93c76118ca748556003c05810e7cbe83c60f8791a72494889289716790242199262e44b356a98e38429733f07e4d2329da534fe8d4998872429793a6c4d14919d3adbda51c60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f11471d84064732b11d62d40633d67affe2bd75315c54321d3f515078b1cac4e1ba9fd529db1b92a47202c0e768b271826787bd6098a8854460d5da5d5744944887cbb1840125e2825393b64644b8c0b6cd9536be03d6c3e7e6ceb13b1901f1cec3456903f5b15e9994ed1207ff52915ff2460c098ef820a1e885c2ff231896a3c1dcd5ce49910b30927597d988808721cdb68f98914266919dcc46125278774d4c1861466a8197c4214493fad00f83808290dc6064a388633b0ffd2b1fdd84a6c3fc3576345d1a654f3b129fd6c2a6b95b46d235a9a7f44a6f9558af20a451a69c6f5c119712cc5ed91f91b946678520e7165ab4cc367d1ab985692f85e68a3b05c738319e0d7107f2f89710f32c7c047019f6cf29854bcda6b319288944e9907975083e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b964101aac6a016725c3903e5caa639614650c0e052673721b113f48d5cda5cce6b8a7449ba5308ab9f1c25c4c4335e2c4a3be318c99787fdd98f7b592d942617b4346fcc402df7a41043b0bd87c318757bb3878b60421ac5b2234863d2888984898d198d002035dc123091532371e444204ab05c8a9db00c4756135998369eb181882ab3c0c3d17189267f03d64af8b2c3addc90e32b3f44c43864615af5001b45c9677f59b8ce680edcec5088dc17865a790f593ab49bbe5327718a4b0a4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de04100878518c722d321740f4c4035a813a5b1c9cf081679e957b795a2771485874e5bf75f57b11f8ad9fe3b1d2d72a1bda04bb1517296193763776fae451b6615a8e9c788a5c8d65173bb9307b2cf9c863029553f56717b355843ab1dfe72cef8c46d6a8367ab70f83db71c4c410960a7b6221ae2ab64a17441f4b50adfa971f25c719dc8705926c6bad712cef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_private_key = 84d7070ee80107976bfd1b0db6cc33f3c98178817d8460b63dc012311638aa43b253a705bc994931bab38a62c5d1dba793b8437bd600a8725d36aa898e353d6b955b80f8578f855bcee194ce2c6e4c6179ade8176e34578fb24b6d60c395b674a7a8a4c72550f83a09d24582f94125690428a4e76972b77a53e852ff3718a440b67d6521ca699e5a8c434dc47a38032129bb76bcb4c810028938fc94f1741a1fb26ec95252e259b8f9176bbad8763cb63da6f295b460cde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b24e09d4144ac900b43cec07f1dd2cc4f7c976eb0baa4d8637bcaa70946391109981e978ca023313b200092d26ccc823ebbaa85b8ba1680636d0be656f01769555b058af7825fa00d10a38b0a2b127a773cab406c1d4310a0882889759f20b44aecf68dd24416d9491cb523a1afb1a1ed87b28e5589f4059132603e228b185d426f49031af8fa21b11cb0f37c4557f94b2f158340921f95091128c5616f54105d47253f150ff335081d231f5b308a526b9506b03e0b5c6a88394f0c9c6e7c2b475c7508a3a8b1e0d571d1c364784cc8a7ca7ae6c2b24366a0d2865658d42a8495b24a16c9a9d8b1ea77332a1058dc292ec02c4723fa7204e93eefc24f10c4877425975cbb6142026a2aa649fc6c77e8c72dd3e5b0d9e9495a02c251b12b7ab51f6a9853bfd151a4873cab4102db62676496a8b38c8038e4c6d988880a6b2774875a5fe69693d9726af64a51d77a03e523bad8b2a6dbcea137a051d19e81059d07437e38db7891956c5b2c8abe282b5a02a5530c56a7b4b46daab256588b04344365313a3ad94a2d7aca4ba7072cb9259e2676a5c86215b24faa159bc18bce05451c69d2699a056ed3f6a7f2bc7676f11bb06cb72dc53d7ea6bafee89797b57445f3ae11262543a2882b863cdb455d5ea03eba56946dc61d798a76bdbc4ca7f2a102c518224a2091211ec4d251ccfb08aa2598065a79b8b61a56e925031a579ac5bdeef1a6e0b1381fe180db008f19e775e030052a624b91d1550fe5365260150ccaaf228acb8fe471d2c8b4b27bb57d62ae9ad9ce15a0b72ed98b8a619cfdd3a17ada37cc455d77640ea327088e9c33d4281b65dc9a27c68d27088b1f2a5fc586bb0993753e62a67bc3886048274ac267a95b42aaac3e60c2699321a79301acd350b92899a2c0ccc4703b243660a39c5901e3b6bb146c588dd3431c4a5bead8aa29e04f8fdc0d04783751707cc25ac359952abe7384f839b42d9c9982dc66a21c7fb5cb7316748423e25005d389bcd56fc498080f88cd75ec974ca9ce9f2ba995b50eca85cf09612fcbdc492ccc6d0662a59f8cc0ff3355f17424abb6c774a377b81c12b9982f60777926ba0b860123434cae8f926e902a5e633019e3c62087a1bdddf2186768baf91656d903c4f1ca88163b8dca041823bb6ee525583816cdfafccbcfe63dcae0b93c46a14fb72114194cd084c208921925e7c55ec807ee6c0a8ddb71c4ab3bd5836b7fa160009dabd1e5498d005718548324b0339ec71ac4a75c81f522dfd92b64e3676b337758490e068c3cc747bc004da30cecab9c542ffce8266d8106e77631e9166653d50b220829b272c2ed5568fd00c52de89e1cb76adb4963623c082f824afde530e842838d6c331d80ab47f33fc2730bae2407b8a40c10642bdab993d363612e5b6250825c92fb6a78535fb1ebc52bd83b6f5b58f52669ca138370f1b21fc80f09d7011a005a20125630d63a9e596dc782962c622bbdd44582fb8a2e4638f7a0029c740f87dacf6300a8ae8b4ca91abdb56534654395f9e2c7cc087633149ae3609089567c7c7b20e13c03a059a5c95b22be46671733b28b41b354f30b043ba5edcc15ebe74e7cbc3188b6ab37fc40dd3bbee7e02da545942138739479c4f610cdff564ba7a281b7249267c3740966c7ffbba92a8a1c3328b19f58c058eb27e27857e46585e0a4ac62f1a361e44f92413e37e7cca667ab53064dac9b3aabf3363451c95f6778ddc114f8c3673cc302e7183d49379bbdec05fd361399ba5ad58a5a8f823efb096e1dc522179100626bb67ab1647645794b38af228787b425b03f7c15082abd063125086c8586552070f6897252936cc00bf2810baed633638b1737b5ab13fcb47e181e6cb86c69301b77b85e2c64305f1584e370934a02aafdd27c972cb252b95d01d6b6ea9a52107aa9ad68a021b3bab723ab9599544ff08a4a13643e181db6c752a8a5c948d010e8743ecc064ea034444f3a2b207bc3a0606600358907708bc87016261a61b1547bcc8421c009778ee31598d47a48d3a99e9a24ce230b9568cbf4bb61d9a0aa512b282e2506a51b0fe92507bb7cb044e93ca230b6d9f97cfcf31b9055c9775419684aab2609a1e11b2b354223c9761f7d6b5b02a16f72a9910f7ccb63263e1e45ad9e0349405b8a8b876d3125824c115c69510666308330901208d02f1a6057a0f5481af4956ea5281c956735d28e49173031b688a30289d385a7718c2c21c300d7ac3fc81bbfc6747c60f4cdb9c037c458c50dd1605ba167806a6fc32c759f2942dd81962ad657b51942b3fc8d925b9db72b1fd2b303c05043638a3217d1856d8b243018b0d8679db5c3364a85b78c913793e87855b382b3456d3d7c1c2b82bdb94c6e96732c6f455e4e631fd46cad78085556fa7fdcc649ebe587d7dbaf5d1a77c6fc70b3bbcb89744be1b09430f2ce72482d6a8673a8d511a8a1c506a2cf4facaa9e489d6a3a5322410464d590d0f52b957b28937b543bd5a01f07261afc810d41bc815469e145862a3238bb194da838c642b817db611e18c08325502778922197e73aaa2c030869ca3ab06b22827feb4465ae60975a61255a405db1f112a2087218619bc9dc064035774306b14d4b6003949181301253034323f55bd0818097193d449a3ccd1315ee375c7efb833d03a87a881cb5dab7e0d045b6b80505cc18d8e9be1f1a7740d4981e31339503b1a2b22061d484d9368b8a5193d29b3cb693b3de6a357414be59d5aa64c6c4ad9964e470999e90627014b34a7a8b168010ddb76f994783b5f41ebd60697198262cf42efc13128a45024386c78851c709389262d10d65c4784eb10c2cb13d9fe819cb4c6dc0c34da8c22b69d5cc3ae995e0a965a267cf64d69d2bac59801c8dbe917b37292630518b093b98d39c6fe0138257467f93c76118ca748556003c05810e7cbe83c60f8791a72494889289716790242199262e44b356a98e38429733f07e4d2329da534fe8d4998872429793a6c4d14919d3adbda51c60ca58c915cb53b37580d960525a8dafd591d2cc9fcd8a615704b4866c6f11471d84064732b11d62d40633d67affe2bd75315c54321d3f515078b1cac4e1ba9fd529db1b92a47202c0e768b271826787bd6098a8854460d5da5d5744944887cbb1840125e2825393b64644b8c0b6cd9536be03d6c3e7e6ceb13b1901f1cec3456903f5b15e9994ed1207ff52915ff2460c098ef820a1e885c2ff231896a3c1dcd5ce49910b30927597d988808721cdb68f98914266919dcc46125278774d4c1861466a8197c4214493fad00f83808290dc6064a388633b0ffd2b1fdd84a6c3fc3576345d1a654f3b129fd6c2a6b95b46d235a9a7f44a6f9558af20a451a69c6f5c119712cc5ed91f91b946678520e7165ab4cc367d1ab985692f85e68a3b05c738319e0d7107f2f89710f32c7c047019f6cf29854bcda6b319288944e9907975083e649a93289e04054496f63234bc4cdcb9a2c3d8b98c9c63b08c75109b964101aac6a016725c3903e5caa639614650c0e052673721b113f48d5cda5cce6b8a7449ba5308ab9f1c25c4c4335e2c4a3be318c99787fdd98f7b592d942617b4346fcc402df7a41043b0bd87c318757bb3878b60421ac5b2234863d2888984898d198d002035dc123091532371e444204ab05c8a9db00c4756135998369eb181882ab3c0c3d17189267f03d64af8b2c3addc90e32b3f44c43864615af5001b45c9677f59b8ce680edcec5088dc17865a790f593ab49bbe5327718a4b0a4fbbc0606b7f0e6b9a4f4857b3146500839bc47a8825e890de04100878518c722d321740f4c4035a813a5b1c9cf081679e957b795a2771485874e5bf75f57b11f8ad9fe3b1d2d72a1bda04bb1517296193763776fae451b6615a8e9c788a5c8d65173bb9307b2cf9c863029553f56717b355843ab1dfe72cef8c46d6a8367ab70f83db71c4c410960a7b6221ae2ab64a17441f4b50adfa971f25c719dc8705926c6bad712cef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d03a2484828bce833f9262405b562bcade9ff04877838558409d2b60f1b689d137d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +expected_public_key = fb70ab80405c4c59421f913a78e89f67767e71fa51431061746a74746b1fd544065788a7f880b9c81c007e6091e6118f3acc518bb06579b45ad1374404284b0f1c370c53062cb79a08015b4086626d3083ee7b427b24613947588f7149777a3fb5919c73d5a23ef5445f24aba79b94bfba774f71c84f929978c44e07a84bb9139b32fb97d4b20e363a2098838c6a3c51ad244b540b90020c5a0ce2b135918db1e9093a0cc43ab210d28a7889da51d88c7b3d1452d7879f34a130bb263f51429086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e56881b94376638f507e95809862b0897744d3d8658e33c89a7791b93acb17ddc91ccc5b71b01b9bca81a7485c5e4428538a3ba7f124d24864149b26d0f246e9aca34c76103d676cd7a54abae1c895c37b1784476180601a67a5d04996d195363c61864caf95e7d3b2f4ed68ca2db09d9d34f86d5666aecaa468587fe5a3c56434ff4815c61094c831699c5f1be9301299e3016b4cc602bb62a4f1c2f1af247b4fb92d4a10430e29f0a71c02df70e48e0ab79c0a31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114e62417d9bb054110d3284b3285110b7069fcc58e2e13cb50daaa0fc082b7c87eaf13063c6a966b4cc24334a7e6fb8c3131461756a35f2b9842811f233a6a7127a33b7cc559b477b491c0155949f9952ac9631c32451b3872967955c1235b61af676429c94e9034405be47ac5873c9dc33ed94828c9429dd7cc29d076871222893f207b0f3a8086d77c3d7792ba25ba8db46a554b161a30cca878ad6397974acb3812767a95a01f73ca80f1d83006e9460d2348c047ad60f2841db1bae58952142aa3491cc7dde58debbaa27621c7caf299f4325ee978caab6ccd4bd7510f318b20e98d26a94ee99c935629394e6b80a5614891a75b45d81eda8a6cf8d8b43d62ad9399369023c4d677ce75f14f84b05d01b7b021e15e459bc5c82cc9c4158ba32c5d50708ad9f620297333a4d899cc7a90c28740039b351345bc7b971aaaf39d97326553740238e569d4870bb09c66af75b532778b9b0a631d362d13d61567212e6ab523fd4c3ebd5839e4aa1421db5e06e33bec836876d8a8624c22fa56c43d4060a9e52f1c905ea8714d8436569d050c7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dc5242c5a58f0c8caedcac7c5256d8f3b40bf57b055616c24569a51c5bd712279827bb00d274d767156173c7ecb8766202376e9a7227517bc4488c029b9b6b2642858344bd14c8837ac908690312ff5a6de7bcb88f2cffd40a9fc666800f9ac54fac76ff5a42ff83b9d49233c841607aa348e2a5dcbc572d2a482f78b2cdf3ca4bbd22148c925276b6072d777d53081311a286f37ab14ba2000ad4cb82769dc889de981c969f732eda2717cc405cc276fc965ca2bcc80054c557c1343847bc6054157a5276432917501f88bef0b44521c0d5fa168dd89c9e34aca4df0a348e53eb5c939650a240879c0911a8e1ce371d7ea45e6f90b8db0520b115f826085ec25a108309466c11920984534c99dfbc7467af31d5f941784586bcc0347412c48d0927a4b95a22d98b49a1a20cc72272f09bb63aa194e4450c3bc2351ca6d2043a68ec30c705cc856b00f5054a66d3140bfbb47425a67eddbc4204944a1e379e1516e45216e12d06b2d522398a125728822ced62dacb220c845a444594b3b6977eea89e256878e52c766a86a3fd04437b4165242553fc747b80952769c10547804b80c1a6d85a29620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d7452a3e2c6a1f87c4efe1234bb9971a1026292c22c94449b7c8a2cb117b8175c7416284742120c11378c03256e4d2b80d502bc5ddc1d4e3c022bea80140307a3a214ba51c807db26f2536829a62400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34bb128bc0556fdc40ea9eb0b73193396d51c1bd533c4910b358969ba135f862b64dbda9608dc7665fc61ccd645f8926d1835adc34386cea20ffe3283f900a4ffb693a223755a50c4771379307242e4548ed4dcba4574410d409a4838233499a337859c64c6941d477f70bcb5a653bf571602e5224e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_private_key = 47318b2cc6a9d8bc6ebe7c12489017c03214325b61a2a8541fb783c448c3a31c1d82ba7906b09e3512af8d00d0706a3d391281f0315044c9c4f92b0ad72c60e18637577b942a442589cbb466ac344438750b86cc86b97d16339a9db0365e6696b183041543b031c9220e82bfb89c21a5b0a0d301109568b1c00b2b878c9284375949c88394f141abc188ef7607cb8151bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee518202c9119c80081beb38caff81f5ea51811f13be9491f431b127783227bf9b691031145d6a144213fb4f1c89c38c00c81abf075c4415586bdf28b946380c948b94d7a0c3a793100842230663f4eda9174dc7214884e0f552a50d16dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4bb22e174b061bc80e91428547576b6205490ca3934c9b15fcb69611a1639974478800b2cba3d5243a0e2762be2f87035295fff40b56be37ddc71915434c4af6472c1e5c519506e691703c49c715b50b360a5c2fcdb79f59c7ade27380f9905eb7aa6f5042c6a32bae657c699eb85a53395c0303e87e89800131f96969bf45b3f574a40ed813268603a24f1c3180607814914775350b88a1fa7e1034c9cb155879668950ad5950803abc0cc58bdfc408fc1f2bf7d3a2972aa66b58844c048150c0b8c89aca3bd3269474875bf10a94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946d70b8b87c56b81b77024503ba87485ba3655f669770410e89fc84925b87c008c3cc13c7b9447d82fc2932a1c641230725a422b6219d9bdb5ceef17e121132e6615075e0b26cf71e91a1593210a09507214716a3405b2503ca5f29d4479914cd10b3457aa62a6bb71bd08736e1519e69f709b8c8439b4441bbab5d0911bc6737ca742747ca592e5ed734a8aa1b77450a9d4188e05422bd9240e285865d530e718c6f1a816153cc27414446bba8129a1716171aa60ae086ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee6603f7993083724a596069f3270c071b6bab955844a081a896096f76059b9738d819ca3b6588d5f578058d28d2d0710b2bb2e307a5f9e18533713c41e172a99614a97c00ac0a83a25526c399cc9fa9b74cc4774830c8e754231b04274c90c526dea7fe3d203688114e7a90d3ac02ae69a139649b754581bb56825a215c3ba282a26c036e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781cd09ccb64993299745b34b6d7f897c0e05e1a6966e6757dbee29af2eacbbb7701dbc39294db584c7c3a7841112258951d88145cf73404a17adb8cc4d11788225557a83b652f95053e8507093b2a8b00ce77e7bbbe83233dc18880f2274472c05e646b90952fe92440d164092a058d69c96869d8a83377a2da92c2d668607dec3cbefc6242b49a9da97c19c2067722c8d309cb898593b08b5d8138bf2fd1c59081614f764acb392d7feb205a85270dfc1129929cf7b53d41031c92944972b8bc9a9c494ab384996647e177a87a101c45c747660aa4a38088a5f7919ca46dad338576463a1c1425a6c4409e2ba8217827ae83bed4e6c80ab528a6bbc1ad58c868b995d9f72c77e84173c9cac4311d8fbc5895d694498a68e0b16037a95f9b61c95ad0b052e01ddf68a1fe5c094d3b8726545f1f857be735475a8abdd7c7b749377f2fe1adb0ca283d6721a109790f4242ab1711b08cc2cf7361177969ee3106b8238e4d41795111908fe17dd68a461c490d165316e927781ad220fb371d5b1951c4d83d047b72f258865e4296a9727052f4214eb55727b23a52bc68f73cb417cb40ad595888c941ac9360c11c0d17790e3efbcc97373afddb9ae3f61030729d5b7b200e4555b6d25d3e6b16e211bd05dc2c724a33ffa8bb3aa4684a422c19892731630ee2125ac8d8cdfac2b69834bd888aa2eca804d7a935a8d371899023488c9799b55f2d83a7d970aee1750dcc59483cc49451991a799044a74326eb0689a1c72186226c8102b344209fb510c21a885306a69640f6add7858dacc86216a189984640d518312d553626da12c9180948492eb5d1090bb896b1cc315105b2a0002f83b3997f02a227740bd4421ade421696031c495892cd3bb68aa38ae1f02afb536e9499abccb904973661fb70ab80405c4c59421f913a78e89f67767e71fa51431061746a74746b1fd544065788a7f880b9c81c007e6091e6118f3acc518bb06579b45ad1374404284b0f1c370c53062cb79a08015b4086626d3083ee7b427b24613947588f7149777a3fb5919c73d5a23ef5445f24aba79b94bfba774f71c84f929978c44e07a84bb9139b32fb97d4b20e363a2098838c6a3c51ad244b540b90020c5a0ce2b135918db1e9093a0cc43ab210d28a7889da51d88c7b3d1452d7879f34a130bb263f51429086e39051b8acb15a8a34d7a856e6a89248baac15ba1138b680e79e56881b94376638f507e95809862b0897744d3d8658e33c89a7791b93acb17ddc91ccc5b71b01b9bca81a7485c5e4428538a3ba7f124d24864149b26d0f246e9aca34c76103d676cd7a54abae1c895c37b1784476180601a67a5d04996d195363c61864caf95e7d3b2f4ed68ca2db09d9d34f86d5666aecaa468587fe5a3c56434ff4815c61094c831699c5f1be9301299e3016b4cc602bb62a4f1c2f1af247b4fb92d4a10430e29f0a71c02df70e48e0ab79c0a31827b996b4328294864deabf8114b4dd58b53919b1e86ccbfbf7931523409da691ddea60dbaa6114e62417d9bb054110d3284b3285110b7069fcc58e2e13cb50daaa0fc082b7c87eaf13063c6a966b4cc24334a7e6fb8c3131461756a35f2b9842811f233a6a7127a33b7cc559b477b491c0155949f9952ac9631c32451b3872967955c1235b61af676429c94e9034405be47ac5873c9dc33ed94828c9429dd7cc29d076871222893f207b0f3a8086d77c3d7792ba25ba8db46a554b161a30cca878ad6397974acb3812767a95a01f73ca80f1d83006e9460d2348c047ad60f2841db1bae58952142aa3491cc7dde58debbaa27621c7caf299f4325ee978caab6ccd4bd7510f318b20e98d26a94ee99c935629394e6b80a5614891a75b45d81eda8a6cf8d8b43d62ad9399369023c4d677ce75f14f84b05d01b7b021e15e459bc5c82cc9c4158ba32c5d50708ad9f620297333a4d899cc7a90c28740039b351345bc7b971aaaf39d97326553740238e569d4870bb09c66af75b532778b9b0a631d362d13d61567212e6ab523fd4c3ebd5839e4aa1421db5e06e33bec836876d8a8624c22fa56c43d4060a9e52f1c905ea8714d8436569d050c7a574a74535aa3c4c194bb3d4a867a07535dcdd93f644baa2dc5242c5a58f0c8caedcac7c5256d8f3b40bf57b055616c24569a51c5bd712279827bb00d274d767156173c7ecb8766202376e9a7227517bc4488c029b9b6b2642858344bd14c8837ac908690312ff5a6de7bcb88f2cffd40a9fc666800f9ac54fac76ff5a42ff83b9d49233c841607aa348e2a5dcbc572d2a482f78b2cdf3ca4bbd22148c925276b6072d777d53081311a286f37ab14ba2000ad4cb82769dc889de981c969f732eda2717cc405cc276fc965ca2bcc80054c557c1343847bc6054157a5276432917501f88bef0b44521c0d5fa168dd89c9e34aca4df0a348e53eb5c939650a240879c0911a8e1ce371d7ea45e6f90b8db0520b115f826085ec25a108309466c11920984534c99dfbc7467af31d5f941784586bcc0347412c48d0927a4b95a22d98b49a1a20cc72272f09bb63aa194e4450c3bc2351ca6d2043a68ec30c705cc856b00f5054a66d3140bfbb47425a67eddbc4204944a1e379e1516e45216e12d06b2d522398a125728822ced62dacb220c845a444594b3b6977eea89e256878e52c766a86a3fd04437b4165242553fc747b80952769c10547804b80c1a6d85a29620aaf7054a54aec77e0e3c1aca9613e0b877d39cc9c1c9088a96d7452a3e2c6a1f87c4efe1234bb9971a1026292c22c94449b7c8a2cb117b8175c7416284742120c11378c03256e4d2b80d502bc5ddc1d4e3c022bea80140307a3a214ba51c807db26f2536829a62400fd3a8d06b788e5cd43896a9a349a4c0581662999b9ac52803ba34bb128bc0556fdc40ea9eb0b73193396d51c1bd533c4910b358969ba135f862b64dbda9608dc7665fc61ccd645f8926d1835adc34386cea20ffe3283f900a4ffb693a223755a50c4771379307242e4548ed4dcba4574410d409a4838233499a337859c64c6941d477f70bcb5a653bf571602e5224e40f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39bb8615509158b63be5f5e51a0e690f2ad6fd0c56fa886bd85902abd52598bc81b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = 1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +expected_public_key = 52dc3121b31062ca9d2d7599b62b942c221868e9030e52b016bb30bba71109ec9cf44930d76757d16452623010828925c340a8c2a7772fb71a09e1cd8cb73fe5c1a8428219b9f14eab47ccb13703ab2aac1bab159fc57b1ed434b5a00d5221c05ee77faebb4a05ea04d9c6abccdc5764e876305025e57b9e25473dbebab8bc207148f720f224b1a4887da3604e23321f17167b01d546b5074cb27bb5b6a365b91232ee7cb7f47102902285fef001e4914499da9e31eb1376e110b3bb06fbb350a054bd79e84113021bd1a1637be1a7d3057679b41f20fabf3d764c158457e7a967cd4440d4eb2c2d09808296c1d666784698115a83ce0840467449080e038b81f1c7743c7f71861d0a150c5867bb71db4ccf5c5a92955cd33812d3590b7b999708b38d6867b979650a73a63cc9fb9bf87653c5396ab8730e38201d3d493443369a7b424fc895cbfd96271445849c38ba8c9a969cbb70626698f12223e450c58cf5a384fc784914072ed92338f11693bcc2c48c201390144bd52584260a15bb48401baeef381affc95ac96033816c3414d03ee70ca8c947c7b9ba2052393d3ee9856cd52708ac02294c4cc58461b379a8b3b5c85396b4e90b678c9817c34b2ed2fc9e8bf346ebea1e6987b81e32b6fde7947a1772230257c0b1c564427b0951a451c11c6f2a7c27b6391c2b0581d19bad322038989c3540084132bdcd6368682927524149a4620326c7b968f6090ebca4b7da889b48723ad977bb76369d3b07873b5bead9cb08766702b90d16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7d0084f324bc15a0347ff2264bea0c88711364ea0dae46763a02c3a90b1655eb7d74a59d3687738f1c8b26e0929920089237a196d64a3ea58facd259c4d72e17721efb36c6aaa1572ea88d1171134fa331c43125eac801d1eaa9ef426efb2cbd6718a4be981ebd2375b73c91b7248ef21c6bf6b29a4c385ee899007e44a50af44ff7a4a973d933889241aeb90358f84943917441c7840d0348526b25ec3a15558562f107cf33540823788075931711c5133f8516bef21c8425088435405275b970c457abb73f696612b253221112a34376c3133164a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb3690ba32476f701c7af32575cbac0beeec43bcd8b54fe2c026d6c4b4fa150111bc58a8119c083a1a755e0e0c57be5c0929f64946015f8ac80c07a249eb68afff3388f205353327b484cbbfdf6236222867bdab6bb2fb4fda4260fa1b47bd47b43490cb11a9c3aca191dcab94080bbe8e394cb988ad474c122964739f05b5964070ddaa7a4bf2227e96498f7205e17b77d926695c3508f1105e4774126f014b61194436042c3c155e4a5134dc95583c189aba2bb29268c44e2b6b6d52b70198a4e193c0b4587ab18a0166c51365b05949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a048717b60c22d5b2a6cdfc4158d5747925731aa85bc66ec37d3384ffc7910ec5b4d2cb5442e25ac411112dd4b983b68a90bc57ddb122d73372794214e4e64a07ae676da990239498257149c299a193fa1cdeb371cc354bcde26c3238bae59230f4ccbc4614708fdc39ca5d916d80873908204b70391788cac2a346a1ac72a92673532bc9286455d7eb405c830beaca707fb865aa1d41315628ccec14d431434fff6350e518f3ea8422b44cea3b6b39910ba6b5265e8d18452f7119384244228a983c3aeb0b139a96830ae90b9c2e569fa885406c1270f1654cf69a34c2375f2bb537f39a61935af753cb6ef139317105c9f4b3dea094093d667396552b2b9562cfc0e9ea43c54f99430931f10bbcc0c81270ae352cbdc29658188e67a3de915469ae4263667665385381a352b48176539f59d4e2b19737309efe6c40a1a4d3f52a7fe47089ed22fb3b3c24531865beb47f823221c690b60586928ec5cb9505ac6b9c764b62b63273165f70e76034614ec354b38786feb660704a5de79b1d3399da5c8b1e0416af49c22d7a6982a338471cc88b18258f2f3b55bf51bebdcc53a7829e4c875f18127c7b5473f0252bfe4735c59388b305f3f106803c27c6bc3c51d38070f1561eac805070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_private_key = cd28aa8c74142a0508c2534d5adc64284806bb2c653bb9783adc640e9945c253af86f57c19b42c6697ac85d1bfa46b5231559c11f5a0da9b2bf43c40001d4e6c00b81237343e15a41da190cf8940b641a4b42b72d9cc8bac681369dc07d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a63c269a5821557299ff63b9f0161368f6084132c8b56984f4d1626d7436dae2596e1b24a86562374b066d2483a1b354fff9766845480ff396f6ad089b724b0f15a34c2288deb05a8418909803cbfe2f3c63c30056f358fab798f4e385eb0e35ed0c38ade7382787a2502d117ad0bc6cc0a4746aaad23345f10074b21970c18eacc898472766b2313472dd3348c82f69b7d961cd35a8c61984e7ca20ae6382f04a977a72b532a1395707cbb7cd595e0da0202498058e59f22e0c340c438851674e3ab1e0d872fda3baa7f87b67f449e6bb461bdf1cd771475d5b59facc30181599ddac8ce68dc2de5741b21422fdd512b39d9633adb202af3941e323c9326297cb58086c3282f722c4d50b94b32153ff30b91f07a811a9d9e07b7667846806b6f7071ae29323156b668f831a9f79ab7949cb363dcc8d151349db4b5ec1266e7f5af98105c95c0a4d47648aeeb01fbe1113948b407fcbe199bc2cdba40257745d765c6a0766012f19df41a770e96cc95d3cbc70549f7e61914a73dc71062f2a3a377ec26ded59e0cc85b11a74f43c3237c7561cb7046c0e660b5bb0ba0634ff2b211438a9b9b906f241b04b2439f29a3cf0ad9128d683f0c2c26ca050978cc179872b1664a751458c072106fdfa07d97105188278268b0481018782f361d08555fe5799a0654398285b378f7a9f143ce20673184c75e8b662085899812912fb8a60485921b2f7b3feab95cb7aa327d8b9dbcf7c7256a131270b731e33f8f555cf4f8b7a1e6aabb4c83d2938b7b21beb1c3b3cb3bc08bf52fc1f5715fa89ef8e205d85862f6a2cf420592aa24568fa0b8dcbb90d0b654c7c82c7411b6c3e219f46c352aa034c4fa0aa4fc47daac204b351497727b96714359a66466f6c4cc2b83bf6b87785367c7116489d6c5feb975e41c4bbb2a3d8fda920021c523227a438374d96032f62c41b17422584ab5880475cdda8b7f4844e5420c25d97235b0acf71012adab59298bc80052aaf1807e8015695d92184741bad318ba9ae27c306a2e42c80512534963b70b9d0b7f5ae70326c33e7d43249e8c9ce386947c167c8f33c88947244989c45b4858203249fa5a136734153cd94f1ad467b5043f7ed77f58d34490d1b5f9e323f3e2146011921b8a9f94e419bb85ad965443e7f4a73534457be43ee5f677a63a7738762b799600fa0b9cd328ae4cf507c1d9845eda77c30bb7c39c618afb402cd9b016f0092cb61e8be13a18925ca122a142409b8dc637a364093cd76925a194aeda21c61709255ba2de330693b888a6c2c6f0c39fa5b4c7fcfbcc198b3253c0abc5ab5edfb438ed3a82b72b5f54a39d21c37879480c4a648f182a94ea566c598ba4cf697140a20fdf4cabbc540b80e8664216a6e880553899964a7b239d00c68e720706512cd2a58b9c49bc0acb90283b506ca196f7855ed69ab21f059a11fa3fc4670dfdca6dc0a17c3e407ca5f7c0bf4481d006bc6f257323700a3027b296b58b4c4716200c8b382190c1cba73b87c1497b69e8755f9cc5228efbcde6f2c0120a524d87080590a92222725892b588bb8ec10760dc535dc2029e4bfc7dee8005a82446534462fa1443ca492999c01d87d71e0b6c9d0e7a9fac2264c8c80baa5052f9e876ca5b5d2c286d78467b8bf35e51c27b7f34b45d5534b45b520aa18a85e54d22babe9b618b098a49810ccc2adca1b8226f8ab826ecf9c5fa2b665ebb5449075bf6ca53dc5665ca639eaa96120585b9b772a77a17bc2634c268fc9df25b516878901a1332dc3a0a38cac0104c59522947b92abec9aa8d943aa710305a9aaaa751b564cba271355ba882bcaee053487b0c899af306678bbef3b603a8902cbd61aa78639eeac2a387158e27f629395422a3c922ddd45ba7c93c6b97148dc7b990c51c63101672d87d10c8782cd48dc34a925be78b245016a144c392447f576282e1c83745fb395bb2a4f5f2bc224a0628f75621817798f70437e6381fcbccc547cd52dc3121b31062ca9d2d7599b62b942c221868e9030e52b016bb30bba71109ec9cf44930d76757d16452623010828925c340a8c2a7772fb71a09e1cd8cb73fe5c1a8428219b9f14eab47ccb13703ab2aac1bab159fc57b1ed434b5a00d5221c05ee77faebb4a05ea04d9c6abccdc5764e876305025e57b9e25473dbebab8bc207148f720f224b1a4887da3604e23321f17167b01d546b5074cb27bb5b6a365b91232ee7cb7f47102902285fef001e4914499da9e31eb1376e110b3bb06fbb350a054bd79e84113021bd1a1637be1a7d3057679b41f20fabf3d764c158457e7a967cd4440d4eb2c2d09808296c1d666784698115a83ce0840467449080e038b81f1c7743c7f71861d0a150c5867bb71db4ccf5c5a92955cd33812d3590b7b999708b38d6867b979650a73a63cc9fb9bf87653c5396ab8730e38201d3d493443369a7b424fc895cbfd96271445849c38ba8c9a969cbb70626698f12223e450c58cf5a384fc784914072ed92338f11693bcc2c48c201390144bd52584260a15bb48401baeef381affc95ac96033816c3414d03ee70ca8c947c7b9ba2052393d3ee9856cd52708ac02294c4cc58461b379a8b3b5c85396b4e90b678c9817c34b2ed2fc9e8bf346ebea1e6987b81e32b6fde7947a1772230257c0b1c564427b0951a451c11c6f2a7c27b6391c2b0581d19bad322038989c3540084132bdcd6368682927524149a4620326c7b968f6090ebca4b7da889b48723ad977bb76369d3b07873b5bead9cb08766702b90d16ea4ce99a7ffd3ac1b2dba13cba3dafb3761f09ab7d0084f324bc15a0347ff2264bea0c88711364ea0dae46763a02c3a90b1655eb7d74a59d3687738f1c8b26e0929920089237a196d64a3ea58facd259c4d72e17721efb36c6aaa1572ea88d1171134fa331c43125eac801d1eaa9ef426efb2cbd6718a4be981ebd2375b73c91b7248ef21c6bf6b29a4c385ee899007e44a50af44ff7a4a973d933889241aeb90358f84943917441c7840d0348526b25ec3a15558562f107cf33540823788075931711c5133f8516bef21c8425088435405275b970c457abb73f696612b253221112a34376c3133164a617c6002a5fd143b7fa094abae345f78a734dfaacd7f6377ab48f943bbb3690ba32476f701c7af32575cbac0beeec43bcd8b54fe2c026d6c4b4fa150111bc58a8119c083a1a755e0e0c57be5c0929f64946015f8ac80c07a249eb68afff3388f205353327b484cbbfdf6236222867bdab6bb2fb4fda4260fa1b47bd47b43490cb11a9c3aca191dcab94080bbe8e394cb988ad474c122964739f05b5964070ddaa7a4bf2227e96498f7205e17b77d926695c3508f1105e4774126f014b61194436042c3c155e4a5134dc95583c189aba2bb29268c44e2b6b6d52b70198a4e193c0b4587ab18a0166c51365b05949a438e1f8670c69be929b5c44e851b6c6af3d1bc3fb9cb99a7a7af7d6448099a0af87362ee950bafa5257d840f427adcff5a048717b60c22d5b2a6cdfc4158d5747925731aa85bc66ec37d3384ffc7910ec5b4d2cb5442e25ac411112dd4b983b68a90bc57ddb122d73372794214e4e64a07ae676da990239498257149c299a193fa1cdeb371cc354bcde26c3238bae59230f4ccbc4614708fdc39ca5d916d80873908204b70391788cac2a346a1ac72a92673532bc9286455d7eb405c830beaca707fb865aa1d41315628ccec14d431434fff6350e518f3ea8422b44cea3b6b39910ba6b5265e8d18452f7119384244228a983c3aeb0b139a96830ae90b9c2e569fa885406c1270f1654cf69a34c2375f2bb537f39a61935af753cb6ef139317105c9f4b3dea094093d667396552b2b9562cfc0e9ea43c54f99430931f10bbcc0c81270ae352cbdc29658188e67a3de915469ae4263667665385381a352b48176539f59d4e2b19737309efe6c40a1a4d3f52a7fe47089ed22fb3b3c24531865beb47f823221c690b60586928ec5cb9505ac6b9c764b62b63273165f70e76034614ec354b38786feb660704a5de79b1d3399da5c8b1e0416af49c22d7a6982a338471cc88b18258f2f3b55bf51bebdcc53a7829e4c875f18127c7b5473f0252bfe4735c59388b305f3f106803c27c6bc3c51d38070f1561eac805070ac24099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305cf14252096e4988d8ecc4ac6d29ff09c55d666865863d03a68db523728910a8273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +expected_public_key = f1b45961c6216fc930a8760d4b79afe948166ce6222b16acc847ab4bd9540cb68872c9095aa7619b88414e313051b7abc0248eaf745c7bea31b01b29c5105fd698119ae0186e7c89aeec141027b19a5ac3e1c419dee19825f518d46879f43c8720e23f8916abad006b3bca9600932a67938015964b25b75d95788278d0af8be577ef5cb1fe61cfadec5500ad17de196a1f95187106649ea4227ac9a96091617d673f32454fe68442f0509faf86a06d4c421746310341257f48c51c961342372954e8373796a089721cc646b6c27b2d7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331aa082d1b66d708304ab884ec6c7e9ca98d7edb489fb2ad522a2b0881997662205a38a35ed77d8af15b70346fb825a25b0962f0a8befd5c602550925ac9454b6a4c02db9ae9a569dffc568d70a1bfc95c108b03f16c799310a4aefb74ded63c3ad4791ce3ad8cdab1df854adc814b2a1164e551a36cf87daf367f8767b122d4c2ce30632f22341b5458eab4cd2e9547f83b2d50ac57d8c30ecbf5387db6049a61768ef21123936664a46b4a2cadbe1b7a5ff752dec141f38aa5b0b85546b77f67d32d40f6a588e63ef136013f0ba4e2889714c309835bc0d8e858863a29622a843cc49dd2b85e66214c0b2695dec22d3c4a0f6544940ac77eb8a1c415aabe7797bb4e8079cf74943c5190a549a78038883ec62093a70ee6022df193a4fd7ba17714af692923b650b94f5b854d07139b240c29361ae9a2cf34fa4f1f6c2924850471d6338206a1b8c806697589b5d8a2ab860f4d1614426452038983dfe2ca14ac40170aad48809c99f68e5197a0f02a78b481062413cd8779c59ea9864bd9c68e8705f4179405d5a5ffb2273051bc1366a26312895345b81e780fd1683ec8e3261e1291723978a5e3350ffb6e1a7923b363162eb14247684d01cb3f48b7abeb2154a2751061327ea5c3839fa0a0db315b7ca60b0a7c5903309589e8812f5301dda14e98c92c028c1bb57c1b23f1b90ee5bcdb448229fa6ef147c56862babd6aabe7eb142e9a671de69786010720eca14ef6ba53d71e5ba885d50bb325707865b564e0018d89f27f8fd2678be207ef830b3a6457166b031a307cea082b8260937ed83f20646e50bc022f81cc6738b16f16954d983cc7a38d365462a564c8d4417c29ec50daf373f0c8134d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f8810cf0be61ab3d678757131ff93b5ba9a9efc54aac9fb279991370742af6be65145ca215ef35dbf512f13f88873f87b17f3c4d9e475f90a02d270ae72734029710522b93762d404691910a3e79686f6aef2118446d23955da68a477bafbf278822276b3882feb3112f2a47ec753510fa97bd5e4111ec67a66909fa3557d637c3686a214a81a6c9e983039d5cbd2b1853ebc7697a8c0ab34342fd3561d8b3ddb0575eb62c0f509079a5c5a3eea1b23417d70eaa585aa36ac24993c6cb463d63fb6129583e7908dcc4c6e55ba3cf30eee2842696777989b90ac577bdcac111ee344ad1478dcfa7bd15911d0e745a523a64dbc28f03c336dbc9a86c146c8f842478a172706cdef994d87c562d3b39911441e6570397f503da1f07c0c6045c3e863c7f3bcd41b787c8016058b81fc7b3375e9185696813a589c75995ede730d39715e66a370c127121235cb7785a42bab8a091872650062a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b85342b350477688a0fc2c5905216a7eff70bc742723d34a3daa13b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066083b2805846267cb3c989926d72fa18abd97cc0531a8747ca42d0b35c89478ffa2d3f769b1b2c0961ec877e704212115df3e171eeea463877b2f911878a15310b6042c1624f6232867578a842cbb477202395f51c3c129385993023325ee405975e062c705a63951b080bd4b98e3388c74cb6c4d9ab3d66a5e543481f300c2f8a1a17e7cadc83195ab4c840756db9fc11c39196bd34071e1ac098ab332354bb23d5a376ca35862070c933875ce21dd7383a41ab9abfe2ac96170c22c5133e07089940c03ff80ee80aa18b33bcf8061fd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ec711a0e259e3548f38022a5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_private_key = 8dc4a33d0a013d102a7ed6a5303693669033816bce0c8a83594695531999647a48f6708c65220be4d9a60f013201a36ee053796356b26e3617126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0e127f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab222318856ba8b6919c5a0a667866c0d2166b69ae04432c044f289bfd7255542cc7946b82c2db388c8b656f234a3b607c2f6611acc3a5a12c8111e42138abca9b8dba79921a177682c2ad1138b133636951f5aa77a52b7554943af52f7b53d0b84ecf44fd77018f7062e564c5e58753994724242d6b3a8f8a66df518f7e13a0a5c1c4b253dce12ae197342f5d72c296498bc9888ec347f528958aa689c8ddb81870184c9e2254f918b7465354826870300790044165216c8bc279ae93854381c28cb438bce444b2258afc3a84cd4f91de8373f877b30137c4ce4664e4d330bf763b344489604e97f4c9c24ffc226d07c5824ccabe38cae22487ea2ea0e89920f304bb911b401f45735089512dca2298ea1a57f643cd7524a3d6c9f055b25eaa62fbda318a7b8c8dc9c5cea953ad5170c0452a7bc04469987712d0522256a1ec52961561175c32abe93dc5ed37289b9d4cbd3966911fab85fe47b3c68692cf5a845286baef91493e15c6d23437bf7517ec5cf609c8628d82ff7cacb54d4a5ead25c85f59ab51151f9350247782459b598a2089a85f2c9bf66797e863a4ca0732268a4e40c57009d0c7d1ab1ff46b78e350dbfc19fcae823bcc040183a27182abde00a966a6075e68c011aa62eef913024ccc85b460098facc9c4c81d17c577bc009b8f9416d225d156c4e75b84691a90948d31883b1b2ab3635dc357ae867b2496983cf9595423c541e3c17947042b3d141ef825c99862302ba911c67619434b3f9cc489e8c8abae92af1ec3045c895edb41f745aa1f3d1a625e47eabb49432129a5608571431c4890c8fa5769563b8b1f9ba3c1b77b034f568038865c90304a4f79f65f74c17fab9e6b52236cb636ef5b686271f955a9e889b7a1ea1a010828aea1a838de1723f0149cf172f48890161c34039e99b36185f068b5707fa476d650bf149479b8c928f93089a4b941047b5b528135685797e0b9e65f595d9016a614393cfd630c6a217d0a03091853f606b238ee13c92c2b5d9e19b2c57638ce82a3d767639e115838b8eeaa5a47b7b686ea05cc088abd47a10ae593ae39a07f55cb4c1347acaf7cf59422182749e6aec39d62ccb876094ba3cc0b871c57a03a00ad67c5c1c6ef911c6dc36b13cab713be1a6610caa46db4ebb86b76572a0bd60adf163b325c89b506c33cc343c37a2bca7cacabd90494f044b550778677c2ebee76e03622705556b509c204087b5c5e5936c0153857691c3149521b800b76c43195897067529a4a87d68e974ed57178b7980eee227e4150af1234025757eaa3b645064202d632eaea3943b40cb10922bf569ab2c44867c411bc8240d110134d78143d3d44b450056be166b57921fe64a44f80968a1941d91a971e10c347aba369702b1ed542984f28b6254bf61d94b69f015b0e32b05e8897502238fd21d87978eaad45bf5997654b40a903319ca64095c9297b6393b33066d876c52c5dc2f79f0501ae14475e179fe3b5747b7b11af7b6c7187eae775e4beaaf1e904f96a741a6a4820027bfd6b15513911d921835598090b1f145d2885063c24cbc26b3ccf22787ecb3b67cce6df4c1c45270239545463b0ffac611dad17a6e81c4b80543e6e7cec66c25c8e23560d32fbc8c29740433462749f15658dac545347c8d4d5470e15610f7515756cc4eb73966718baf841995d1ecc081d68b4275cc8e33a87cb61df5dabd0f7cc980d5a043c431d8b6bf2b661d7841caba2ca6aebbba4f338459561c0cd68b07ab2d6764c27eba2ce3e33452f072a8dc37b5d192db301cd2937015a5c08442731c97a0d9333a62648b43453750dc1fd4752ef16845067271a6b236857c69f3cba42a2c5818564d2cbc33d0e43c926a4d57c38f618b51fc0c86c6e778d478916c4a186052b4dc9a89f7e4c0b089aa23a771bcc06f3b43a8804a18cc4b8ded358c7ba66b5f7385996968a27793fe845b40a4af8177ccfb45ca82f3513d29be6dea3046c9bb080220bbb1a0b30c10f1b45961c6216fc930a8760d4b79afe948166ce6222b16acc847ab4bd9540cb68872c9095aa7619b88414e313051b7abc0248eaf745c7bea31b01b29c5105fd698119ae0186e7c89aeec141027b19a5ac3e1c419dee19825f518d46879f43c8720e23f8916abad006b3bca9600932a67938015964b25b75d95788278d0af8be577ef5cb1fe61cfadec5500ad17de196a1f95187106649ea4227ac9a96091617d673f32454fe68442f0509faf86a06d4c421746310341257f48c51c961342372954e8373796a089721cc646b6c27b2d7e594b4f9ca5ef4767fe24920edc60ce2abe17e36331aa082d1b66d708304ab884ec6c7e9ca98d7edb489fb2ad522a2b0881997662205a38a35ed77d8af15b70346fb825a25b0962f0a8befd5c602550925ac9454b6a4c02db9ae9a569dffc568d70a1bfc95c108b03f16c799310a4aefb74ded63c3ad4791ce3ad8cdab1df854adc814b2a1164e551a36cf87daf367f8767b122d4c2ce30632f22341b5458eab4cd2e9547f83b2d50ac57d8c30ecbf5387db6049a61768ef21123936664a46b4a2cadbe1b7a5ff752dec141f38aa5b0b85546b77f67d32d40f6a588e63ef136013f0ba4e2889714c309835bc0d8e858863a29622a843cc49dd2b85e66214c0b2695dec22d3c4a0f6544940ac77eb8a1c415aabe7797bb4e8079cf74943c5190a549a78038883ec62093a70ee6022df193a4fd7ba17714af692923b650b94f5b854d07139b240c29361ae9a2cf34fa4f1f6c2924850471d6338206a1b8c806697589b5d8a2ab860f4d1614426452038983dfe2ca14ac40170aad48809c99f68e5197a0f02a78b481062413cd8779c59ea9864bd9c68e8705f4179405d5a5ffb2273051bc1366a26312895345b81e780fd1683ec8e3261e1291723978a5e3350ffb6e1a7923b363162eb14247684d01cb3f48b7abeb2154a2751061327ea5c3839fa0a0db315b7ca60b0a7c5903309589e8812f5301dda14e98c92c028c1bb57c1b23f1b90ee5bcdb448229fa6ef147c56862babd6aabe7eb142e9a671de69786010720eca14ef6ba53d71e5ba885d50bb325707865b564e0018d89f27f8fd2678be207ef830b3a6457166b031a307cea082b8260937ed83f20646e50bc022f81cc6738b16f16954d983cc7a38d365462a564c8d4417c29ec50daf373f0c8134d53bd6edc509f544b27d69085d6a0cbec817609b8bada6f8810cf0be61ab3d678757131ff93b5ba9a9efc54aac9fb279991370742af6be65145ca215ef35dbf512f13f88873f87b17f3c4d9e475f90a02d270ae72734029710522b93762d404691910a3e79686f6aef2118446d23955da68a477bafbf278822276b3882feb3112f2a47ec753510fa97bd5e4111ec67a66909fa3557d637c3686a214a81a6c9e983039d5cbd2b1853ebc7697a8c0ab34342fd3561d8b3ddb0575eb62c0f509079a5c5a3eea1b23417d70eaa585aa36ac24993c6cb463d63fb6129583e7908dcc4c6e55ba3cf30eee2842696777989b90ac577bdcac111ee344ad1478dcfa7bd15911d0e745a523a64dbc28f03c336dbc9a86c146c8f842478a172706cdef994d87c562d3b39911441e6570397f503da1f07c0c6045c3e863c7f3bcd41b787c8016058b81fc7b3375e9185696813a589c75995ede730d39715e66a370c127121235cb7785a42bab8a091872650062a4fa6f5825a5c2138d0cc74ed874c6a8e89cb7565879d66d34865b85342b350477688a0fc2c5905216a7eff70bc742723d34a3daa13b7e094970136d5e959119a79894f4b72f55941b157c601a9ca5066083b2805846267cb3c989926d72fa18abd97cc0531a8747ca42d0b35c89478ffa2d3f769b1b2c0961ec877e704212115df3e171eeea463877b2f911878a15310b6042c1624f6232867578a842cbb477202395f51c3c129385993023325ee405975e062c705a63951b080bd4b98e3388c74cb6c4d9ab3d66a5e543481f300c2f8a1a17e7cadc83195ab4c840756db9fc11c39196bd34071e1ac098ab332354bb23d5a376ca35862070c933875ce21dd7383a41ab9abfe2ac96170c22c5133e07089940c03ff80ee80aa18b33bcf8061fd838b44ea3c73e278a7ddc7e1e7b56a63bc2fcdbb48ec711a0e259e3548f38022a5e3553db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0345118a7b9bcc773f0ec10c3e353eb4365d2bbff3b812df4635d5c8265b5d8c5a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +expected_public_key = 09167020156648552c8dc941c1cc6424693025e263aef87f3e0b7147d0b8164077dd580f8c5b8f8ce10d77b217adfab3c65a2e6a04a662bcacc640b0eee6b08dc32c661751c0c8bddffc2e0bb78691a68e7eba25457a42aa0c3b15e17787619824e02edc7804161a3e7fb092e897506b8333aee03fd8b11c943853f1a9a44f5927309abde1321d60f73e41538cb9f83e3fa004011a94a200cc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29ba2274d759906a9043f2575f850f1152542585b9feba4368598c883c65120048b7c85e1a361adb0941e6479370f01604d4bbe85ba4683bae545b3772755765073899b00b0de9a6d810137ba8a91aab33ebc21c34274f3c995fe4ca8aaab926e7ba0d83175100fb261272137fdac3ec38ac299a25d2d9c514937e4386a06831ac39e21fc6e702a50476493754a37261c7187cab94922ae12f2b032228934782c056aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c6717905456d55016360d789a1f5ac166b1508d6100b0ce914216ca0476566ec33417ac234597a45c8a519b40842e5ee66b8b69269be2848053c50b38c258e38ad3104e9a1a50e9872dae129c38a367418c84f0cb5acedcae229291c3f6aeca507007042f609734dac77fa01c1735245d06f64aefec7736e077d5ac9d8767346250c7dca28105477b18c681fd779123e93788624007bc729ab13352f9915d062df3367d1acc58ed8478a9e6216a826977b770819796f24cad7db1538cc41c03a8192f2323c68a9f28fb0145cb543832639158cb098b7693c615b820ba01a3838cf805b9972ceec7689e9bac7831701d543e87a880fe91b59743888aac439d1222a5fc33f5068844fc3ae421cfe80c50db3031584a21b4330ce1a7c014b11eb3526ee4dc740ca7179a428dac27c128421167665f809959a5494c6e3a53f9d74f6e85ba7442cf68d999ce2a891da7cb6903ade2f576f858a5f731c259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a3896917ebd7c2e8c521bac1c612f0aaba462e48a30ba3d37a28507a16e20658f34ccd3905db5ab94d6333b1390e7a93906eb0c59932840cf55227f19a2c8728a7d385189057144b462a2338df6151e02bbc53d35412e4235d7045e47154e4b910a47ca8ee678595bb690a6b4459b23fbac0b51b055402a9a83f29691ae02a500c9c6352658fd1816a7a9e3f593ffda6939820530793382ba38aa851433585a39c68c7026461f9e0000b365ff2b67a93eb83437b5207061961233013a41cf7d1ce8f86c6b8159a65cb979161410d24b1b20a1ada82b72d127e941846e9d16d16f3b9a63b9e678057a20aacb88238ed9ca1c722307e2c2f3540afb2b78ed999981ff6a0a0e15f3c3ccadc9b242b886d12f29ad6113d63c8268c56913458ad31a04f6130845a1942fe68b9384c3fd2f62fe034c8e6ba23bb6799163553291ba2376775c4a67914f78bb75026df18aac6c8c9e6e77351dbcf8b97106d7ba0df874b1ee2bc508222794543ea60b3dc95093f288220f83b6a6b456f2a3bba809af288ac08b44ba9411bccb5ba61961817e20b7cdb6efdc4563a6b4b4888058f08ab01d702fb015f20c9202af713de66c1cf133bcde0277f84a5c1876b7adb21fc5a82555474b70443bc59355e3932d20c14887c25e9517c69d807c30a842cf50549da1620ea315e5a20549b59106a6e1fe56d6c4657d6f69891a7449a57239de5137e8c3efc2994bb0b2bd8cc49edbb3661820da27199414a33d804acbb1a80da68ce288c0974b0b1a8f038fd1819bd8090fb022fd648331699724b66059d148d6445acbcb9b910ab14cd0482972858b56541596b5b809aadf81657796c544c02b9a6eb9160bb0cc6445708d71051a89a88830c03c71903892860b950fe66495f992829dc783691876a06a1ff983965d67f2207a60643a6cbb59be857408d802b86f054d5137ee8e6a02d2603e29b4e970a9ca5f49e64e39f70fa5912488c98d28daedc20da06c811a38aafb0064e9ab2f3628587f7a099036a0ec71d70b04ad0e26919146b4006b15221ac78ea0599325b9de25c81506a786949deb23bae43c27c60b79f73635dd64b35002ce5d40f9808ae6a51cc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_private_key = 38bbb649e7520a59ac57783e32a5022489365713cce30171ab46ab219b7e81369af44bab6f5badcf613e963938a0829ace625bd8594ed3c0981c5963f68874aa87685599041c4c296b4cc181e57667d499b2f961f44773ca958193e97988d816d702078c0147e41390f503921f139384d75efc91cd08544536b4c9c09bcc2914a807e090d98b5c07c1a4a0c16ff0eab557e5ccc1871ba1a36ff66b1acd113facd6bd16053f22cc85634a3d56e564e30862aa1409d48aaf92643b62009f8e206c2c8bb7f357b9432a8474349c3e1679f1d154cfd4a373665a86c481b9c3163308cf3a1a265a6313d0068ba2181ae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2a429aff3c9eeeb869ec9982d367c5809396987a2efe93dfda2cf45e774cc3541bfe655a7280af9b7601fa5183ab62682465fdb273ab435355b84563047bc4c6204aec310d4b91e8b849182c16a57605a6f5690d3804d8857379e11b324977f30b461954a17cb16c4dd93761224a47f4c680373c51de251cb69a2c737cbb1f76d7278033ae86480c7776cc7ca02393f333b6cc00c200ae58922756d3664a30d7b262302672c27a7496746f8f56797726340c734473522fa880819d76a004a480f48b74f7c6ee1998741d39fec12759670b4e8057aedc67950b929e200526ba5a27e0bbb67570bae100b77d525af70b7b6143a7419a35273c14b492e1e42c5b5918a62f3c829a50c1fd8715b030cec454c90c72e6509ab1936ae7490c6b62a6720a840aa714f7b6b0134335c75c44a421598b790631e2ca497e256be08910b69c01997bcd20591d1967ef5ec5c035b0c1f19a01bc0103de6cafda45db70950cf551da2442741eb7233b36396c124c6365a83b66d9cc896ff448f54194fa05267b8154895173075039143dcc58062cbbb1946a917abb184788052920d1428c856bafb3461a463627ec7430671ce75bc2adc95622eb2925a582a15e487787389bcf14dfd84801a37bc39136cc1a49cab7cb924772606d48d3941bccd3221eb418b12a6342ab6c357f273795339bbc720439aa9cd5a478122b8b01769edb013686c8e872a4e2c049a755a8f954614665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc642c091226667c40957c17b3c92bea102143dec663b6155464ac7a9559c533a647c5a106c38972a26beab45c2f04c974c9bb860bca64615b6f0782305c81862abc973d280088bac791876d3172d4e340f26452f60009a49989bec107b680b62cdc12751f9079ed07c28143a405a600a974230b20719b0953da3c2da574ce2c31786c77600646e25b3c305f6507d91084a836366c273d62c526e0630f9b483caf335d6bbb5bcf4adeb4143443a07055349cfb690948487f7795b67dc2e45430e7a5c9564cc84cac0ad0832480aa844417446b9b086a493b7aa163b76a50f35b7384bd054147a8621674843c3040ce06eaec68b6ce8a2c5b42390c76350e10dddb35c9f4c4a1cc148ba08601f92b2fb12c9088922c3463139239a62e878e4db61a3529a8fa7905a7a1aaf90216dab5026469b27d4122af5561bb91d111a721a78587eea259a4c7f6b743574398e30a11918896ebae2cedb5b35b095c3ad863068245497e16b94852d25f3121e5792d337c712206c2ef151ed58c8ced316160979d74b4c54b1be2448562cc6c23b96c7eeb3600a028e91d817ecb13c9269bd8ea15296012b13281bda6213f1753823037d24f14e733267b3c31cc2e2b235f1665bd6a81568c7bafc902a6184cea493508772866044a2f7c2aba3a07d560d535b97499bc0e07423221797cc11c46562c721a99c100530ce0b0f8d09013d27bff057a2456a622475297d49bb98595d6efb69d9353561a028e6b5a9da9a4207ba35f0a10b4cf66d7ff4aca409c8edb8160e8a60c5101fd480cdb05362430c98bd8ca34a318405024cb2a425a45384d501889e75c954767a1e274392c830694b59778a158f0b06cf2b444cd2c0134710b35cac598b1de47048d3b204d004a7d8d94810f9a751d782b7ccb158f70f262a53fa7b3d46676569f12b37370e17e1ce35cc0a230465a03903cbdb30ef18ce8b2033e9c5c1a686067ee639bf934b29b5cf2b921015549075cb0f609653e202afa388a409167020156648552c8dc941c1cc6424693025e263aef87f3e0b7147d0b8164077dd580f8c5b8f8ce10d77b217adfab3c65a2e6a04a662bcacc640b0eee6b08dc32c661751c0c8bddffc2e0bb78691a68e7eba25457a42aa0c3b15e17787619824e02edc7804161a3e7fb092e897506b8333aee03fd8b11c943853f1a9a44f5927309abde1321d60f73e41538cb9f83e3fa004011a94a200cc80eac685d85adf295b3dfcc175e4ab1e3cc0cb03c472655e29ba2274d759906a9043f2575f850f1152542585b9feba4368598c883c65120048b7c85e1a361adb0941e6479370f01604d4bbe85ba4683bae545b3772755765073899b00b0de9a6d810137ba8a91aab33ebc21c34274f3c995fe4ca8aaab926e7ba0d83175100fb261272137fdac3ec38ac299a25d2d9c514937e4386a06831ac39e21fc6e702a50476493754a37261c7187cab94922ae12f2b032228934782c056aa67861775814fe5a8095c617bf590795c9b65aa6ee60b60575c881f4631849c6717905456d55016360d789a1f5ac166b1508d6100b0ce914216ca0476566ec33417ac234597a45c8a519b40842e5ee66b8b69269be2848053c50b38c258e38ad3104e9a1a50e9872dae129c38a367418c84f0cb5acedcae229291c3f6aeca507007042f609734dac77fa01c1735245d06f64aefec7736e077d5ac9d8767346250c7dca28105477b18c681fd779123e93788624007bc729ab13352f9915d062df3367d1acc58ed8478a9e6216a826977b770819796f24cad7db1538cc41c03a8192f2323c68a9f28fb0145cb543832639158cb098b7693c615b820ba01a3838cf805b9972ceec7689e9bac7831701d543e87a880fe91b59743888aac439d1222a5fc33f5068844fc3ae421cfe80c50db3031584a21b4330ce1a7c014b11eb3526ee4dc740ca7179a428dac27c128421167665f809959a5494c6e3a53f9d74f6e85ba7442cf68d999ce2a891da7cb6903ade2f576f858a5f731c259446219149d11f35d61fc3af43bac9e1a6a6f93469ce7a3896917ebd7c2e8c521bac1c612f0aaba462e48a30ba3d37a28507a16e20658f34ccd3905db5ab94d6333b1390e7a93906eb0c59932840cf55227f19a2c8728a7d385189057144b462a2338df6151e02bbc53d35412e4235d7045e47154e4b910a47ca8ee678595bb690a6b4459b23fbac0b51b055402a9a83f29691ae02a500c9c6352658fd1816a7a9e3f593ffda6939820530793382ba38aa851433585a39c68c7026461f9e0000b365ff2b67a93eb83437b5207061961233013a41cf7d1ce8f86c6b8159a65cb979161410d24b1b20a1ada82b72d127e941846e9d16d16f3b9a63b9e678057a20aacb88238ed9ca1c722307e2c2f3540afb2b78ed999981ff6a0a0e15f3c3ccadc9b242b886d12f29ad6113d63c8268c56913458ad31a04f6130845a1942fe68b9384c3fd2f62fe034c8e6ba23bb6799163553291ba2376775c4a67914f78bb75026df18aac6c8c9e6e77351dbcf8b97106d7ba0df874b1ee2bc508222794543ea60b3dc95093f288220f83b6a6b456f2a3bba809af288ac08b44ba9411bccb5ba61961817e20b7cdb6efdc4563a6b4b4888058f08ab01d702fb015f20c9202af713de66c1cf133bcde0277f84a5c1876b7adb21fc5a82555474b70443bc59355e3932d20c14887c25e9517c69d807c30a842cf50549da1620ea315e5a20549b59106a6e1fe56d6c4657d6f69891a7449a57239de5137e8c3efc2994bb0b2bd8cc49edbb3661820da27199414a33d804acbb1a80da68ce288c0974b0b1a8f038fd1819bd8090fb022fd648331699724b66059d148d6445acbcb9b910ab14cd0482972858b56541596b5b809aadf81657796c544c02b9a6eb9160bb0cc6445708d71051a89a88830c03c71903892860b950fe66495f992829dc783691876a06a1ff983965d67f2207a60643a6cbb59be857408d802b86f054d5137ee8e6a02d2603e29b4e970a9ca5f49e64e39f70fa5912488c98d28daedc20da06c811a38aafb0064e9ab2f3628587f7a099036a0ec71d70b04ad0e26919146b4006b15221ac78ea0599325b9de25c81506a786949deb23bae43c27c60b79f73635dd64b35002ce5d40f9808ae6a51cc00185ddd099212e3cb03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b772f50f7047714627bf76bc098e0b919145fcd8df6922ebac383e5c556738390e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +expected_public_key = 50672c2e47609ecb47db696d4fe16e54341c0a510ca0293c25f69d027a4b7ccb08c184a68dbb0e8822393ab7b05ef08c4610a0b84c8c4cd5b783e71327d925959782b6c106b08436861a8fb2c1ce2f239f19a73b84966698c52e3c380a7da81b54ab76e62929e6743c88b05457868fff3074f8f085dbb05816c8b4803a7398f1c0f2cb3765e84672b24fa32838f7199a8f738b89334dc6f391125569b12a670cd37caaf00ac919aa4b92bd4da706973681b696b33871441daca919216760b41f5000a7bf782ac33491382b1c423734016cc8ee4b80e6e25be4720ed05439b9dac5fd240193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f2902da9c4a641fc36a1289640a371ab965b25383b7f017834fb4c3c3477910288f8b305031a7b97b69f3eb48780d3558c7c741171815b169e4e9a62a261460ff2caa333150aa2698d243ec55abad0329cf8fca935094c6795489c902303fcca7f257c7d072eaed4a31c9146311b21b09b38326aae0d914c55ab756d7b0cd761510dd12572b912ec79b61fa230e4eb9dd052b29b775d891b7025bc89c0dcaa0a18855988c215c74f06b36976101c0f697cf8db4c0fe25f1c016cd11154f5a5cebdcc4add13b31a63336ae621f2257837b16ff0f6c07eba6fe5b058a42122aa88629014256017bbef582e123365ae37063fa97277b2063d3860d3920beca27638f02807fa3bac4ac08614ad1590bdc6c855f4d3b292982838923251a348cb48753ef773570ab00768341670c21dc7a356931e5b8ab51e8b2615f5689e607953f685aeb6b999815b2cc66c24f65d2ec64e4ee88d4cd830da4c61e15a033e37182731b5b0b506def921bdc19a85624630ba9102226f6c2467c9eb21483bcfc96a22d8493f9ef8b7276378ffc16c3a996f5cf6755d924716524dc85c39d22a8254e74244229c975b467ac94568312333eb578a197f4530ab74514fa174855904c7fd09b2003c3b94bb41c4559b45c00f7a73935ed15a39e47bcd46497141942c3b669642060533ce5ddb0cb4c1369dec82b8d7239637b615a086d4aa87630439d712a55556cdb911734a23779d7c5ddc628d0f326b5502a79da80fcfb3aa8e607fd5c25b8f2768515618538a990df66fe57c5c3b3a354655ae4fc098bcd7a382301d0b721a1e74795ac23ffb8c5493e14c0793cf03063794cb0d340a018461ad89e17ea89b7b88382b9a288bc4b13180db6ee6224fd929b628049c20c1c830504e09651147417b552b6ec810c744210532bb011a93baf28c20512558bc1c4c4a07565779b7fcb260839506e0e0224099c5751a93d6141f90816ea8da87cd1105715a67d0b969d8b748a46831ead199eb4c28b634a82d8b988d2a6d5c797943000d2546957eda9b1573bf534b552f225253d768706c8ad4c42e2688b40965c0dee151be4b7625d92e79fa40fa7c00093148125c65e841cdb86aa90a02099e2c6c4c0bbc95f14fd0734872f2a6d6b3c9b3d0285b7ccbb5b715e913245c14a5aa146f003788d4a76df1037195da2e939cc08f56c3c25405d7d1851249496d33421e5bc386645ff3a8367c3bcfd0542c8962ce146720012087693c60e3a47de4570887473bf9b68c22699afc314afd801a0cda51fe4340e4e34ef18c07a9c7a40190908ac323068c95d59bb04bfc11ac930f99d082d547c99a807c8d112d82f1b81125b41f57a243006b772673efd286b4d24684d2b046b53d7d26b6bbb862d64c42e0e909e813391d6a8289647e91660dc5891479c43769d9608c10763e5a35acb9ab7552a08d167abc9b02d3798115d4c0b6b0782c77bfaea4bc27835b4ae525bb052f6dc04d65074e00207213d612e746a44cb5bb55311c0d4a43d2eb3c2003cf3eb895fda1001bd55484992a384561152779df9534b933244654b2c37b3caa368319235a1da431d958a4dec38da311412606adc0d26022f8a822e4913b8b5e97b6c2525636b586c8b3c62ab4dc73539a028fec33a5704bf95183847361a8143d1c22495ea4a229b4214fc22334b857344c721ac2190b554f7a30479bdbc8854c0f0219b4002a0685119aec442242d15cdde0983f8c9ef2b3aee24ca7ed917b90407d5ad86906c0c865149060b36db1cb1a22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_private_key = af361347809757c2ae0c4a60393c90222c394cf136e95517552721ff136dcc234d64715a1ab43d15708187f89a6830791e0062cd43253ee486ac54179d320fa6a8bac4d0c07b7158a1eccfe52c4847403849982d73288877d04eaad37d392aa487597f80f19af7444e5a82cfbe51609ae515c1b320b6c75aefc121d5e2904a0185654a418e5c7a379b41838ace149b45c5a4040dd239ada846102a6bbc811ebed4710b2393ecc4bb8c6254dc815d2667831f962887a74eb883a5a8642e0b427450d01321246a8797b7be1211eaf64b0c706eedfa17cba2b010626112ab6b2b2b928df38ccbd9b639b9c6ad090e92da98b5c9914549beb6a9b5505579a56943d210722bf590d63c1ed56534a96552005226c34cc1ac32572d2ac0823bce348086096525188088df229536bac34a1c95083309a0971f31d975de0598e4e009d24661b2a79dfae85343b94fb1bc171493ad77d767e0814837348616205652eb4f98838ce536691de8c3af0a4970eb0c3600b4605841bcb0884e08bca3198b04b2afa6f575229c56462b9516026d32d2ce33a4b1add3b411371ea6516765f457613ccb50f94ab9395f6fbc94395a6c9c104ce3b79171a83a49b22add3a915086b804c3b42301bc1f14630ee3217f059aef485c019a4248b4a78a516d75919eb2b15bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bfe30a7578044867897c332687d925c8bab05d0c35693f557f541b571d6ab7e4a752b80267b0329d7558fe4bbc54c8612aa95c03f81641a129b1793160dba78c4e0269e9361087328a73c67c0044217a25c2e05b64a1b8ebec972606bc220b1a456d8ba86a76ac4a3c06429cfb6035ea50549db887a5f6170ea282bcc295a2ef000f571038fa97b6bd98fe0399ece3755d4b55e16261f7fab678c394c83676cb9f080bcc915c8b1c67dc998d7097074249585e31c5b30bd0250abc570531db43f546c2e05983a7b5219127809987343cf722fc38525b2ecaad2ca703679cbb7500420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04d3259ad003db768559e173df06a08793b10e5a1a46145b6f0fbb230ca504424b4e9617cb3f509993567b4cb94cb2cb39811bc1eab31b5f5691ff4108e5a6eaa9b15dc2aa45fc4ad26b9ca007a7c2a680acefa88f12790abec7e3da1c13a355c1c669117070a7e1976f6859921e273f53632b4144b58e0a74207100d2cade0c8a0410814d40a4234843a44978d0d4a173be52434760423235f5d7c8e1f56c8181487bba930cc9272acd524eb6c9d71d753fe62b0e9ba33a478b7e82b36d9690607550aca261085a08725281b02e531432b35398b7ed1355b8172776926bfe41880df90af6951a58981c708724deba6b6c2bb8af1c0009c71a0b82ac0d14cb0910a8ec3988251dc9e93f17e067608115c85bb6c47d33a2a9359a35beb47c3a04ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc04008873004bc535bd5c74dd49247419601513c4e8125731307bc858845896a67d33902afa4b58b50be969b947851bbd791d66887cc6e92e19a2b92ba6bcc2825c4239ab2894b2467547ff3a63bef65edcd579215aca66a13cc6705453c4964f1c29499179cca36a3b998bcd173458127b5f5c9db4d12448d3914f4092f7f37f4d826221ea8bef6889179919eac60dc2547c5e6550f45bcb3d4b41de1b12273675a0f1c611b6199f27cbd277a38a67b77aa3ae87751e96f4b268f75b36d070cc1743b469a2ed493d50004ea5269e91bb4111795741f713918438b9945458f2836d42247254b2fec86cced59b0c721f3c372923c0072f31576bac1c8b986b25e035fef91fafb1c7d0c19c94494f4ff57d86064b22b008214375d0e61361e2cda31472c5d1853f6ace7f8765659abdf95904df05b976039336c9753dbbb216e599347664a7b170eb563ad464a16ef963fca77564b794408acee8395135aab683a14b0dc18413f31b8a4929111550b07b50db2209403854bc4391e115095d2b2f632a76d4015b7cc34e9474a75c124396483c8f0c03800b1f539623574099077b7dcd364e34a122bb0b738d863db019cd19967e48a181acb23cff56346f32135a30aee015af3b463885497a844562107a6350672c2e47609ecb47db696d4fe16e54341c0a510ca0293c25f69d027a4b7ccb08c184a68dbb0e8822393ab7b05ef08c4610a0b84c8c4cd5b783e71327d925959782b6c106b08436861a8fb2c1ce2f239f19a73b84966698c52e3c380a7da81b54ab76e62929e6743c88b05457868fff3074f8f085dbb05816c8b4803a7398f1c0f2cb3765e84672b24fa32838f7199a8f738b89334dc6f391125569b12a670cd37caaf00ac919aa4b92bd4da706973681b696b33871441daca919216760b41f5000a7bf782ac33491382b1c423734016cc8ee4b80e6e25be4720ed05439b9dac5fd240193746e6b196c938b345b39bf5485b5bdaba020dc90ebb5ce8398c3b0fc59eb5ca95857abc2f6bd04bb34f2902da9c4a641fc36a1289640a371ab965b25383b7f017834fb4c3c3477910288f8b305031a7b97b69f3eb48780d3558c7c741171815b169e4e9a62a261460ff2caa333150aa2698d243ec55abad0329cf8fca935094c6795489c902303fcca7f257c7d072eaed4a31c9146311b21b09b38326aae0d914c55ab756d7b0cd761510dd12572b912ec79b61fa230e4eb9dd052b29b775d891b7025bc89c0dcaa0a18855988c215c74f06b36976101c0f697cf8db4c0fe25f1c016cd11154f5a5cebdcc4add13b31a63336ae621f2257837b16ff0f6c07eba6fe5b058a42122aa88629014256017bbef582e123365ae37063fa97277b2063d3860d3920beca27638f02807fa3bac4ac08614ad1590bdc6c855f4d3b292982838923251a348cb48753ef773570ab00768341670c21dc7a356931e5b8ab51e8b2615f5689e607953f685aeb6b999815b2cc66c24f65d2ec64e4ee88d4cd830da4c61e15a033e37182731b5b0b506def921bdc19a85624630ba9102226f6c2467c9eb21483bcfc96a22d8493f9ef8b7276378ffc16c3a996f5cf6755d924716524dc85c39d22a8254e74244229c975b467ac94568312333eb578a197f4530ab74514fa174855904c7fd09b2003c3b94bb41c4559b45c00f7a73935ed15a39e47bcd46497141942c3b669642060533ce5ddb0cb4c1369dec82b8d7239637b615a086d4aa87630439d712a55556cdb911734a23779d7c5ddc628d0f326b5502a79da80fcfb3aa8e607fd5c25b8f2768515618538a990df66fe57c5c3b3a354655ae4fc098bcd7a382301d0b721a1e74795ac23ffb8c5493e14c0793cf03063794cb0d340a018461ad89e17ea89b7b88382b9a288bc4b13180db6ee6224fd929b628049c20c1c830504e09651147417b552b6ec810c744210532bb011a93baf28c20512558bc1c4c4a07565779b7fcb260839506e0e0224099c5751a93d6141f90816ea8da87cd1105715a67d0b969d8b748a46831ead199eb4c28b634a82d8b988d2a6d5c797943000d2546957eda9b1573bf534b552f225253d768706c8ad4c42e2688b40965c0dee151be4b7625d92e79fa40fa7c00093148125c65e841cdb86aa90a02099e2c6c4c0bbc95f14fd0734872f2a6d6b3c9b3d0285b7ccbb5b715e913245c14a5aa146f003788d4a76df1037195da2e939cc08f56c3c25405d7d1851249496d33421e5bc386645ff3a8367c3bcfd0542c8962ce146720012087693c60e3a47de4570887473bf9b68c22699afc314afd801a0cda51fe4340e4e34ef18c07a9c7a40190908ac323068c95d59bb04bfc11ac930f99d082d547c99a807c8d112d82f1b81125b41f57a243006b772673efd286b4d24684d2b046b53d7d26b6bbb862d64c42e0e909e813391d6a8289647e91660dc5891479c43769d9608c10763e5a35acb9ab7552a08d167abc9b02d3798115d4c0b6b0782c77bfaea4bc27835b4ae525bb052f6dc04d65074e00207213d612e746a44cb5bb55311c0d4a43d2eb3c2003cf3eb895fda1001bd55484992a384561152779df9534b933244654b2c37b3caa368319235a1da431d958a4dec38da311412606adc0d26022f8a822e4913b8b5e97b6c2525636b586c8b3c62ab4dc73539a028fec33a5704bf95183847361a8143d1c22495ea4a229b4214fc22334b857344c721ac2190b554f7a30479bdbc8854c0f0219b4002a0685119aec442242d15cdde0983f8c9ef2b3aee24ca7ed917b90407d5ad86906c0c865149060b36db1cb1a22d97ca3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfaa9f015f625356a6bacbb5e565c70184940891589309a571b7166c2ee713b8fbb9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +expected_public_key = 25879df1312d41f14b53ea0fcb973ead32cdf833463ef73eed9a0ce2d09faff9ce3a06030b3021cf4360f3e4cf93528bdbe69d0655171ba7b6d93cc220a10d37e828e54629c6239ee13c0a73e58f0ab6632e764a840753393b206c180b3c333275db3f05516fde08803f7bcc10589f8f54793f732cbfe82658033694e6aa74823b92cb616433072d405e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb56292bb1d796bebb5c400f30098591447191a7ce6a3b2cc3fc7ab7b5c6ca02c6808be45671012867812c2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd6734736907dd3a9e60e4637e2ab768e9558339921d8c1a8218926815cacca840224052d574164a4661afd903d4516e43e3984b31554e5b666a9cbd332a9e6c63036d34189616cdb3d100331bba659649ef0abb86502fa994b941f9a354231110b8080db75c69ec6ffcba48642b0ef54479dd7995f7f9ba92f8b473cc7e31d04948648af330aa09996e868c75bc3949bc3bc8e5923df68b5dd78bafd3318ae4fa6224b8a7dc9814f7b35839b05cb709cb1cf2c1e80aa879c58b29677cda375a5e4229bc8431d48bb08af0bc27f982a6723e60b00df6e607665b7a4b4cb35e5162ba3698b7140ae7a25a3ea76db07626afc773854038b3d13654b7cf0a1a8e75959e5ea0797ef4a64538c19f0028dcb5cdb5803815467e57aca68fe00c3352602897aa88021203a4b970ebcca77846e5c01adb22859e41cdbfa8a7be9b932aa2c6d391379a035455d84282d5ab90d5b6de056f211cc6af61c1d5b643f8d299c249c055964c56906f88778a4600bd054850a9d92557ab2c33dca2eb2857b9617018ab08f25493b265b10ce74889d8cafec53f7b6805bfd637a6b6ade8a65d7f885c3af645cf08bae250753eac8e2b734a75976ac9eb8d2633a980285ec33b154c1551162c81f0254d2eb55a7db13f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d0609e5b36b8b7e097d40ccaccf496f3f00fb957162445025ed62592fb61d41a28b16a1f3a3cc83b1b173e9599e5c49a41b93169dbc4fd006a93bb233ef73df88116e091b17a06125f651f52d501dc86a856a96a43601c46f32b1fd6900a6513f7d298851b443242c62b34236c7495881cc3fa592ebd4397d5422f3c40ca62980188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3caeb0a980d13de0f3129e151c0813b259d53efa07681048888dbc082adc4dd324a028d48fe728701398ce20425bcc9b410687363ad771218285617a39f3c7bfbb2a6c006125d6fa6df88898f7b236f7581a8a077038a06394782ce7862185f4ce98ac06c25b611da7701a80329228391da903607793bc8a2189a123c177af9d987ae9d1c6d2d01bc5910f56514532d582ca092939119444b3b736abc0fb5140e14c723b1c6abc2034929a7edd48ce3d469b16b09cbba5008728baabd54d15f427d2eb5e890a5a13224038328fcb227baf6a7ea3b82aac5844d809ad86b6adca537c2c0b4e0d659606f835129905a6760cfd68b5697b9a8ec00159450205cbcfc0f8c9fb8898f135298ee99a154977fae7bae16ab9325231178a764c1b10b5c427598490cd9539b69b1848980d09768c435233f52376371b7971d861c8612ecd160655e83ba1e60a553b4905d35efa1bbf58318d78353da822241a354b439b2449a2825d43212be80483c167e6c5b50883412571cd2ac3c1b5aa1ec9c232e6b9b5a2091e189b3ab0b323ff13654bc60ed42857755902d063619ab98fd8790d05d85bef1ab23a09a9c241a3cdea620b6c338eb582dbdca9a6ac40fef7615091445a93b8fc2001e09816ffd54f7870b5ce6a4fbd46c3f42b8e63619b7675716bb65eab17299b57c45c834226dcc6c1f98593782c9733a078db34a137c5422cc1dd87a614c1604972559937102ae60337d997caa06b0f33c43b093af04595e5ab48a7a0966ff318a735024f004d6f1893b48b74b42135c43425c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a230cdc1249b09833be95c5f46bc5905b73a82206bd6658464659293691eb58551973121a42385ae81ac9ea2eb6419a915441f41946e504a6b9d5716e909bdc49337909282c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_private_key = 31cb44a14c3ff840758055bf2afabad14a723c048d4d20c5908bb781844d574a96a0807c59d5192548a0089396a78b953aa52677b9a111cb012954b674571c5d0c7c5e6488d498290f7665f4f32dba7228ade2a724413798ec32619901215663b2c26360612558070bd06261bbab86b4f96056a498bf37b1b84238c5099ec8f1af4251c0862b861f334eee85af8d364a54f6bad0e44a23a0577933ca8482889a955086ea3a2c94b057c1c20d540cd6d2976126854ac123cd386a855caa385927318825494861079ac84606ac0f1810eb78a8398740be69cfa1777c61a5cc1d758ae28c072d6087c379a567648558ac8a1883734c64361db33cdd156fd371a2abe534b162c6e336143b944dc2309aac106525d6586793a2b3420358185fc787c2cee3875e3425be5627c1d49313413ee498b17e8c295908b718b3c4a6e03024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd0422ae2569fc37902ab90bd2c236f4da66d78301a61765a77e43ace81102c7355749c1463b55f10e26727086d73a1800924c6b0eab6ec905d5b01adc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67cb20b38bab1a8d81cbd22a5ea8c7587a13bf8eb8a37e5949084c26b4433741a31c502a4c412535fc6a1c5000057c65103027f78f81ddfc4a8843c59f8563bebda15da543be2146a3eb7b521700958bb2a5064923236193d981bd1e2920d00b1cfc504e32495dbb116c5bb7aa21b6cec5c9fc0b1ab73330544e7af5bb1ceb7c159e3509938d0332cf51add245606617dcec688f117bfedc27dc5b8b4884446861b592b720b53fb23cf08513f66c3b51833e51b9a63e297054a8c03f8baa257c64c2c8a265a8a92052c41146bdb3a32ce0b7196aa33564806dac33ac05a20178c2a0cb04000d484f0325c9d16956da0af88f68bb72b7bc6b122a486cc1eb01bd3027aa316c6d7c1ae7d8b9a747443c5d7237989a93ed939d905832e76afae4172d5f70589e54f7b5cbabb536e5f316b3d38911513b400ad83f7b2a3c72a6c09ea3b4f68129ed285fb99442fe61237d61756a2ad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea5920128356c369878855126c22f1ab66a3a4c202892c8863b609f7926175cf1e3967ea93b7ade7a8e6779672023dd5d81bd4d9345af36a38db17e96b8d85b7c0beb586aefc9fd9ebc585f071c1b9c34fa2283a60884a0cc5ea210887aa677d24192db582f05117fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e9410b4ca99a4a880b48053878a45340d0056031068a63113be4b51a630016875541e099935ea92b2668ae84c5a183cbbfed619691038973cc07b72adb803cbe26986c827ac75428cf183cd5fe7c9c719378438058f470b62fa977dd658f219983f97b517bb1aed01a478a18dbb89ac1b916419a3b25f388c276c190b866356ec84c33b29022286c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c7b2473719f4e2b5c4ab8a4fc172a132439e0e3af22a1beae17ba4cf39a155925c62a4c9ca76436496646906630b9349a335a4852c01b018f77da15a4a47efb74a64fa803b5d6927642b16e3ab78d13894104882ab803da0015b80021eb029fda191edb38370c2c4d0f1c9d76d776cf4750bbc0116263b65548cb51031748480225d85f364a0ee2f18e0c1a19203c9145bcac3f175acdf926d42b9cb6d987b9698167d775c04a877a460e47d24866bba3564727eb2a2ddb6868899262404884a138b20b1aa21a7003e35a79422c35ac37059e59164f805af26a4a8b3aa0a0931e08182f347151616c2c86b6a83699279ac00195449a1ee11490076a5fda3f044a75e844ae996b7c6022b2e09c0992fc08a16c29686c7c20fa5394d0a7378202958719633281435b055f3936ebbc1bfcbc5f4105b32ea37e4a222368919eb5f07e0c07b6e7d229e4b51b3bb9586bda9e90383f958b0c9777a2d8331c7e777021ab9da0a45a14b8b88ac78425f19bb6048209223786d19f5463724f009c71caa35dbc67f661ae04e5b3fc9b1d59119bc5506fecd01d6c574880fa8920c54a3204c61c717e47676692dace4b48236009a85cc212f7d9447aaa52acc65d25879df1312d41f14b53ea0fcb973ead32cdf833463ef73eed9a0ce2d09faff9ce3a06030b3021cf4360f3e4cf93528bdbe69d0655171ba7b6d93cc220a10d37e828e54629c6239ee13c0a73e58f0ab6632e764a840753393b206c180b3c333275db3f05516fde08803f7bcc10589f8f54793f732cbfe82658033694e6aa74823b92cb616433072d405e3b38a42ba35252a99cb0a568d51b4562cb3af733af7a179fc66cb56292bb1d796bebb5c400f30098591447191a7ce6a3b2cc3fc7ab7b5c6ca02c6808be45671012867812c2bfdacb9db982c2893d150b6c70347091fabc0297356f033bdd6734736907dd3a9e60e4637e2ab768e9558339921d8c1a8218926815cacca840224052d574164a4661afd903d4516e43e3984b31554e5b666a9cbd332a9e6c63036d34189616cdb3d100331bba659649ef0abb86502fa994b941f9a354231110b8080db75c69ec6ffcba48642b0ef54479dd7995f7f9ba92f8b473cc7e31d04948648af330aa09996e868c75bc3949bc3bc8e5923df68b5dd78bafd3318ae4fa6224b8a7dc9814f7b35839b05cb709cb1cf2c1e80aa879c58b29677cda375a5e4229bc8431d48bb08af0bc27f982a6723e60b00df6e607665b7a4b4cb35e5162ba3698b7140ae7a25a3ea76db07626afc773854038b3d13654b7cf0a1a8e75959e5ea0797ef4a64538c19f0028dcb5cdb5803815467e57aca68fe00c3352602897aa88021203a4b970ebcca77846e5c01adb22859e41cdbfa8a7be9b932aa2c6d391379a035455d84282d5ab90d5b6de056f211cc6af61c1d5b643f8d299c249c055964c56906f88778a4600bd054850a9d92557ab2c33dca2eb2857b9617018ab08f25493b265b10ce74889d8cafec53f7b6805bfd637a6b6ade8a65d7f885c3af645cf08bae250753eac8e2b734a75976ac9eb8d2633a980285ec33b154c1551162c81f0254d2eb55a7db13f5d766330f65ceacb55fe058ad06686e50bc544b48f1358532603720079b7d0609e5b36b8b7e097d40ccaccf496f3f00fb957162445025ed62592fb61d41a28b16a1f3a3cc83b1b173e9599e5c49a41b93169dbc4fd006a93bb233ef73df88116e091b17a06125f651f52d501dc86a856a96a43601c46f32b1fd6900a6513f7d298851b443242c62b34236c7495881cc3fa592ebd4397d5422f3c40ca62980188cb4aa3499d5d2799f23c7e86057a14476ab4c7668f1c3caeb0a980d13de0f3129e151c0813b259d53efa07681048888dbc082adc4dd324a028d48fe728701398ce20425bcc9b410687363ad771218285617a39f3c7bfbb2a6c006125d6fa6df88898f7b236f7581a8a077038a06394782ce7862185f4ce98ac06c25b611da7701a80329228391da903607793bc8a2189a123c177af9d987ae9d1c6d2d01bc5910f56514532d582ca092939119444b3b736abc0fb5140e14c723b1c6abc2034929a7edd48ce3d469b16b09cbba5008728baabd54d15f427d2eb5e890a5a13224038328fcb227baf6a7ea3b82aac5844d809ad86b6adca537c2c0b4e0d659606f835129905a6760cfd68b5697b9a8ec00159450205cbcfc0f8c9fb8898f135298ee99a154977fae7bae16ab9325231178a764c1b10b5c427598490cd9539b69b1848980d09768c435233f52376371b7971d861c8612ecd160655e83ba1e60a553b4905d35efa1bbf58318d78353da822241a354b439b2449a2825d43212be80483c167e6c5b50883412571cd2ac3c1b5aa1ec9c232e6b9b5a2091e189b3ab0b323ff13654bc60ed42857755902d063619ab98fd8790d05d85bef1ab23a09a9c241a3cdea620b6c338eb582dbdca9a6ac40fef7615091445a93b8fc2001e09816ffd54f7870b5ce6a4fbd46c3f42b8e63619b7675716bb65eab17299b57c45c834226dcc6c1f98593782c9733a078db34a137c5422cc1dd87a614c1604972559937102ae60337d997caa06b0f33c43b093af04595e5ab48a7a0966ff318a735024f004d6f1893b48b74b42135c43425c1ca48a93691603ab62d2b80fa5a92eff7a218239b4814352a230cdc1249b09833be95c5f46bc5905b73a82206bd6658464659293691eb58551973121a42385ae81ac9ea2eb6419a915441f41946e504a6b9d5716e909bdc49337909282c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1655d6f749b0a013bec99e017f5e13bff76680a2f9386f2ac6938d7950d5fa1f9f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +expected_public_key = 32a8b2861c097612cdb6f437e844b131e016f3299c31185123951b2901c5fb8296762292d6b37f5bdb67000d91974c77adda0e8601a03432c648848e38e45d8b9a45d8263e64d603e0f50d3f438acc29ccbe54bf6cdb0500b50344a96837828bc568cebaf055f070737f4771c8b4cb87230afbe824d6312ed22ca5e2d4c5dc354d44935ca64aabc5a64186e51697b9444a50569861404bd7a9b76898a3626edbfac8a806751d328bc393b83525514c56b7727110f802cc41bb9c43666b25e26987cc813fb7193954a0258c61b4e13f2da32ce3f1c030bc0081060a7e091929cbb729584a888a06610489f3312bd576666fa09013f4a191b498b9637df5ac5610103de4734c7e82c99062c34063b01fe2210d0bba1a15406836275aa119042b5072e77523a655f41316b3dc31f39840446886af337d2ea0c532999635786d9a6948164c361877891ad903a0c725289c4c02f81ed3452858d93489a07ea071847c38780c86c6de1c22f1db704a2249c6a96695ab22b9868d639ca4a8346ae0845aa8ba151e14941bf447b2701cb715456cb91b927c63f829c562628e01f88499a60aa69a0f3ef410ebb2698889711891b008c0b11a98c47e291b763039e5a214d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a654d0b13d23b8ac2869b4062ba3a27af9f4468a216789b92bdcc8ac7ff2b86b134606a693a1915c55421e8260a872f57a73047f496442d7b1cf44830a8cc01b27b54f495cb984e732c4a40f99a17c5f469f311b6bff9c582f888910da60e6211c788c2ff2ac489f1163826b672e6abfefd917184b3f66d72deaf652e6a596ebf5248a2809c3187c4a3834f220c28f55b589e161479882aac21407e56d4c541282b1b330a7681db50bf30463168733faa52cecb1a8c2d51724b7afe1976e42ab7fefb1c234da45aafb803e80c972559694548ee98ba2c818010ca940f41429a8222b8739c872b1afca093faab792c3e965e7b0bd8850be2498286ed9b8c9a6987577b98ec4a7835cae03b28ae9130ac40c5af971738e423f7f905a223a6c27752bfaf4c495874d0a984187631f50b8aa87ea806e78a1c18c78040548443587486171a11288d4d2a7d19b809ec8c5116575f3c47a1b419529112417a15cda9a0fab5b7968a0937b4c443dfa3d0cc893d4bab60bda28da5a7a7fe6394f6b1dbb207b5abb9b0157a029063ededa1d0f162bc536cda44b598396772e4a3173ab4a22cb91e4b165a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee7923c64baaefcb99bf37195ea6b657d442097289db24568d970ce526c11f507cd7bdc3facc879893c33d35b734fb9928f82867c5266dc1199ee679ac2c337c35c435f90c8ebd0aa29e22a169bc36d605d5a2cb1eb914534f5b3d89a769d806dd87b0d32c63d0225cac6aa1b8c3b7d9258ca68cb8086b673322716389876d85c71d2f5bd3d081d812ab37d026a34324135e5988fea7833973d3b25ad2b8777f3f8691b5671d05b266b61c272076ed0d23604ec7a670c634a7074e889c030026a1b29c4b025c59d43029be2c2a2665dc2f1423c063e1b78b79b550db2281c3bc88dced5345882b30ddc400a62bd35c52bfb063213947b89a91df0fc0f34f53555853a8724a9d15a00b285abfdb39e97b5aaafb429042aaec4d21303f1217a3c0ac7d249a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d650bebc225fcbc132936c9741b496d1c95d8318b6b9b9a71c071f7af5547f895fc4e313e3a262d31695b9471dd8f50f6e227c7774260d60ad56ac7608430f1c370cb917adc3b7717b484b52158740740366a42d9f010c333611e0d29523b04618895cd91a21629146bf1870ed2584ee8c0a728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba0b0687d39094e034399973e2d09116b225f2d41a86b61936743806e41a242b63aa19532f19c5fcf0204329537e996a08bf52acf80c39ce1938fb581543cc77146cd34a5223af8bffe735fb327c888208b5dd648d41ca209f976f6f226f853545a525f3dfb258c8074ef9a442c639a38459fd906a8982a69e29608da98b4c4a59eb6ec04382cc584e663f5751f6aa0486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f2c10c6e197927c89e57088c4960c46b767e27129fe78c7cae38717e6a2a7fc16dbc1582ac697e8915c90281a0a784c4b75345a13161bc6a586166d4385b507748d3b9516b10550f05782125c10f3761aea2c631afa83870c003950b891d96ae721317b192f21a50f2b2caf49f81177790c29c02216759b005692ccab4281927a46739ff7a9583e9a5eb9a62314e4967f5bb375fb627e5a45b918c801b4b1dac24d55c13aa7fc5cfc104647295650b5cadcac2c74aaac28b82233f64c1c01ab50f16213154d0312c5add25af449cfddf494045000a01c449d1084c876163c83c13321b1f6f87757dc186d4c30ce916240e538f196936ab9bb419093fd593409f3a308827ad9002e5a621fb1387ac06b442970cda9c720ac9049cff1c307806e9ff9209fd0cc52b9517c685c36c45801875dbce490163c91c707755cc8701af04deb9aa0ce460f24c72e5d811c4ecc297abcc4c9ba304c75812196409c19be10c494a8b138a6f05fb5558e7f2cbf6f1694e7d417f73781205b941eaa3ecdf91c71e998f9a8b6b72400a048a77ce4ad17eb265313303cc86150d477e42a39cb4b8c5a3723d03550f4b76d5fb7b524ec2658d374a8c955b0fb3fe878072ebc0201b2328b737f9f19bca8411f35980890d71e7bd9707c917545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cdc05fef147fdd625d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22e81cbe9bb0174a2b526b6ba0641456a3cc941569124557d3bc652dc8259ac66552db0ae06cbaedd091c268c2c6f4bc7e948329778cf48c3b37f9a3ed714c5c8e0099036514d9a052631b256fb7e7f7c91ea0311b8db8721d5001ae90991111c5873499bba20a9d08a135abeaa544706dabf7338497c578084e1bdce9155f87417b29313dd39505cc90c45c12c324b5d5af01eb2656d58607724725485465e33a6a64da220421c038f0a625254ad127ac941eb23362649d2049f8ae8c057321aeeaa31e0e98fe3da74d53938f4f900b6a33f1305a383cc12b35894ad498293957950010cf7912174373967c294bb89a90331c828048e3fa862fadc95283025e2f66dca10104be8b9f286c198b8c9f0f24c79a454e8dc0742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc09251fa2780ec0da59d8b12b17179320d23b822a3395466dac34384a364d06882592734f72ab0d2dd7131196afd4da54fc5801d85928cf61bb257274c98479ee0c2f65fb985f6c669d948fac153158530849311f0bc51ae72bb8c23ab5fed55e793a4e8489b423044a1b017273a4be35a305e19934b99b45dd2734ad4cb4c5b368c7a32650f306b7148c199a44bcc3a297429cca6015e906204c827cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648a52bb8302e32098c26e9a51a6571c9c290005265b6359f07598b10c7674f5356b0365ceacbb55b1a1822811c92c44f0e4bbda4a13364749c5384ca7670acce69bc48b6a0b0b2bae8ac5cc40aca6ce24957167cc0f24dd0caa3a0228c13934fbbb0c205f53d713aa441f5b0feb01fbd008209296cc096645da876b961b0ef736996d95766ba0d9f89a4a9ba5d8e31af9f5274bdf093e40169c9b94b0958ab9a585645da158a6176c8bb196692bf52a8158d7c9c2cc6937516450f50baa77022c748c19e68cb9bec6c115806a30552ec242d81b036d840c3d1a9bc15ba4434d4176418686546cc38f35ceef112689850b6bc3f7a3a544eba0ba809153d4c3a21e72a2a9c09845cc07efc1282123652826efd0267f5c9481d8c5b07370015d593b1828dee3aa6f55b31525b9ea8c9772740ba325b072e9211aa104baa516e7f528202c5b0f6f8a4965332eb711ecc9a9e4b85bf9d0cbca759093916c4992a338dc385c9280dcfb50805d95525d59603e8051bf70049698629267b2f29bb93f769b3c3b553f20cdff72bb77811b39c276623c98197cb528b9f90e470dbb378ae9750f1405c11551e6962709a266e6717760ed607db4741468a81aebc72abe9080b428b5844b646855f01f989378702a6894e24969fd605b261129bc0a567389acec88b0f15acb1189718115556cbd99a32a8b2861c097612cdb6f437e844b131e016f3299c31185123951b2901c5fb8296762292d6b37f5bdb67000d91974c77adda0e8601a03432c648848e38e45d8b9a45d8263e64d603e0f50d3f438acc29ccbe54bf6cdb0500b50344a96837828bc568cebaf055f070737f4771c8b4cb87230afbe824d6312ed22ca5e2d4c5dc354d44935ca64aabc5a64186e51697b9444a50569861404bd7a9b76898a3626edbfac8a806751d328bc393b83525514c56b7727110f802cc41bb9c43666b25e26987cc813fb7193954a0258c61b4e13f2da32ce3f1c030bc0081060a7e091929cbb729584a888a06610489f3312bd576666fa09013f4a191b498b9637df5ac5610103de4734c7e82c99062c34063b01fe2210d0bba1a15406836275aa119042b5072e77523a655f41316b3dc31f39840446886af337d2ea0c532999635786d9a6948164c361877891ad903a0c725289c4c02f81ed3452858d93489a07ea071847c38780c86c6de1c22f1db704a2249c6a96695ab22b9868d639ca4a8346ae0845aa8ba151e14941bf447b2701cb715456cb91b927c63f829c562628e01f88499a60aa69a0f3ef410ebb2698889711891b008c0b11a98c47e291b763039e5a214d35485ce4884317c5ed2449ee97566fe948f8f397864538ce789b2a1b3a654d0b13d23b8ac2869b4062ba3a27af9f4468a216789b92bdcc8ac7ff2b86b134606a693a1915c55421e8260a872f57a73047f496442d7b1cf44830a8cc01b27b54f495cb984e732c4a40f99a17c5f469f311b6bff9c582f888910da60e6211c788c2ff2ac489f1163826b672e6abfefd917184b3f66d72deaf652e6a596ebf5248a2809c3187c4a3834f220c28f55b589e161479882aac21407e56d4c541282b1b330a7681db50bf30463168733faa52cecb1a8c2d51724b7afe1976e42ab7fefb1c234da45aafb803e80c972559694548ee98ba2c818010ca940f41429a8222b8739c872b1afca093faab792c3e965e7b0bd8850be2498286ed9b8c9a6987577b98ec4a7835cae03b28ae9130ac40c5af971738e423f7f905a223a6c27752bfaf4c495874d0a984187631f50b8aa87ea806e78a1c18c78040548443587486171a11288d4d2a7d19b809ec8c5116575f3c47a1b419529112417a15cda9a0fab5b7968a0937b4c443dfa3d0cc893d4bab60bda28da5a7a7fe6394f6b1dbb207b5abb9b0157a029063ededa1d0f162bc536cda44b598396772e4a3173ab4a22cb91e4b165a3587f687bba350698d6f87958279e8176a9f52c7d99c55035164706139ee7923c64baaefcb99bf37195ea6b657d442097289db24568d970ce526c11f507cd7bdc3facc879893c33d35b734fb9928f82867c5266dc1199ee679ac2c337c35c435f90c8ebd0aa29e22a169bc36d605d5a2cb1eb914534f5b3d89a769d806dd87b0d32c63d0225cac6aa1b8c3b7d9258ca68cb8086b673322716389876d85c71d2f5bd3d081d812ab37d026a34324135e5988fea7833973d3b25ad2b8777f3f8691b5671d05b266b61c272076ed0d23604ec7a670c634a7074e889c030026a1b29c4b025c59d43029be2c2a2665dc2f1423c063e1b78b79b550db2281c3bc88dced5345882b30ddc400a62bd35c52bfb063213947b89a91df0fc0f34f53555853a8724a9d15a00b285abfdb39e97b5aaafb429042aaec4d21303f1217a3c0ac7d249a3174fa8e67de44583bb3549aa585404dc77a81756d05a42d650bebc225fcbc132936c9741b496d1c95d8318b6b9b9a71c071f7af5547f895fc4e313e3a262d31695b9471dd8f50f6e227c7774260d60ad56ac7608430f1c370cb917adc3b7717b484b52158740740366a42d9f010c333611e0d29523b04618895cd91a21629146bf1870ed2584ee8c0a728b7535284ad30a3ed13339db15b77a8cb2599954efe44d0cc57ba0b0687d39094e034399973e2d09116b225f2d41a86b61936743806e41a242b63aa19532f19c5fcf0204329537e996a08bf52acf80c39ce1938fb581543cc77146cd34a5223af8bffe735fb327c888208b5dd648d41ca209f976f6f226f853545a525f3dfb258c8074ef9a442c639a38459fd906a8982a69e29608da98b4c4a59eb6ec04382cc584e663f5751f6aa0486ba48ce69988cc535190195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb91c3c2aed0ff6944819c93f9a9fe77d14a16a385f644de118099fd4f7f57db9a0a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +expected_public_key = e0f7b1cab23a3379caf84ab285e12ebdb602f431a82e0b098ea1a1f18b18411989cb1b035d0726865712f5cc1e6b51674887b0e00c2eb067731dc8419e64b816955b407a1a813666d73b53d7955639a877a961b4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a391bc55b30dccf33dc1a93b9b784c7c3429ce8684e1910800739839bcb926374932a7241267835caa9131818ef9aa4ef5c1a3e2f03bfc83076d8a827c082f0d0c2ff89a8fc2e62a96396dd411259d26c7b9c84bd38c557fa45103f3b793097ef6b775f050033109ac7c606e2cb05497c9c596639a63171f5e70775de9c545b919b9e199f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a203825297864ef536cf578c277b6541083168d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b7a018e3e5cc8c581198e2b4b372002eb756bc7a65a4d67c86ab022f549bb97904e035173ae9c1073a9d23a315d054cf0e3ba27d401bb04569065256be9447a06caedd97871b52624f43916d475c7539bbbbfab35c0864c8c77b12242797323bb12935bf5a08c2ea4d446305a7345de980a03067513f6402e14b29e7287e30194dd76856ed80c55bd65849c1135d398994007b1f14a452e36bbe7283ca7b3ed1b67d0fc3667387c9b3c3cd8314515cd2c4e51b96a8d43a1c755c65740ba9830f65356290953b9dbb03600b18f4681f6f039379f26d40f2c8cab57378b66aa245197cea225eb9b712c95c4bba470b07bc6c458aad71bce067b0991036f5f54636248c516c88eae013232c0191257cd0a6322704c9a6d005fc80c6c6ba0636e701bc5847c091045bab969ab85f5644a5f8f43858c94b276201a7e77aa5c413c57b40726302559762ec40178199526ae63279fb510c8917ab40c1b1bb15dddb6d1c2b22520780f222c15ab2a16bfa28753a61a949aaea6abc3e3083a467110334a959fa582261561d3c8fa671ad34b8b7ff2b682020651935cab1b227d75261e3c98930961457a955275734d9f41c61069e1a5569d38a1a1ca1876e481d94851e62918fbd550e45fbb79a7130643bc1fea1c722675398498c6874ab1a7997008a166c9146882c37e4eb64c3e306d2b2b4c1409a81da2122a5360430774fa56c5a3520a7e870aafb55773124d93b17451c01c7e21be33a9de7a500fef26c7117c13599024ebab75ba9710c5465a089375b2a751f5c3eba8151bda4182ff3280826c3190b9b11b89bf9d151c4a939510007378895f916bbb8e107031459e27c9ee698a269425ebf5a484812271ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd82c10c997ace9e09f77cb9fc4f8c13b25a8a12c52c7729f22a3290140c7ad0480c00a175db293cea64d422baf4bd306c5d446d48b062f751f47891a8fa82b9786148c364e4dd85507c07a9b4448e57c2795554b3cf53d5d14ad3179669862123840a7aeb57240d69ecadbb48521c196dca4705671b1e566fe59b08cb963f417abd01a1915a33367508cfa9c89413b7709eb48e9bc2e809a56b027b6dd3a513a2428466c29b6ac802f9a83536ba1adfb96270c57a0743c12733525311e8fd04e12c52f15468e84c6af54d8bae8214c152c56082465b79a6cead444aa767571cb1351e4cc05a8a75057c5745abb125a5382cb8a3ea2170c104ca21cb5da000002b7231a8a0a23e50d173485c7d1cda9e8c1da913161e34fe0a986ed5c1183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d21f170569165ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93b506a8554738e522e11bb3b7976f9ab17ce8a190b0cc810258972a10283c21b9fa36384ae0be5556aa252a59c1aa7617b480729c0272576dfb0c6108db290a0cafb8588f6db8b933970ebca0933c9382acab4dc0c75c4e9a469ad60c86d7474440b870e7958b600b6a3b48cb13c938652198c183347358cccb4d45ab3a4fd7c7730470c2218726157f89facc31b6449fd6b4666081572ca291ba6e3657165b053c6a239876ca5eaa0bc659b0b1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc5d006ca6586818664ea6108bf0080966ba83c77aed8fb2066c94458e70a90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c464442cbe0879fac60cb733496ffa7116011cada07377eac759172db45c9035532a5a48c18f3343e7fb3a0a7a1da9c75f647648a822bb8fcc59a2e0476fe958cdf968433b46ea296056a8460edc0b7d4430252b227cc38c8dfa639a72759de9325d3bbbdb1a5305e546580127b11332bb666236924ff1f13105176b81a777ebc946bd4b962e8050c0f80be026a513f7c9c74308f8336a9bc73bcabc8353aa10afb69aa502b3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be442bf2162dda987c602030770555c0bc62b1422367b95a91399642155cd0b17dbb848b642c765fda2400358040d4cd154a68db36265bb525fc90988fd0c04bf0b66ce052bb216d6183b444cc385bb8ae17388d5e8024aa41563653b5f72899cc16b37d642f6ff7385f557c941571a1c73bd9425fef3c343ed9b88bd02a9be5652736ae69949e43b5c9719c4b8e42c9071c10e3d454b3c90d315c93579cb106a3b16bab7163983f5c514b818516bba802b7fb1166679ee03c4c41ebcffc6322db61a7988927dd83b48c24bfe82a4fb1901f70e2c39c411fa65c43d56c02c79849e7745bee15b70e405939b055c2a76fe1021e094b4671a290f5d708ebf0b1155b94fee9b34cd9858d3a8dd4bc27f5fc0627f2a80d6681c11324ecb74639540b72a23083c3758cb29ad40c979b42679e1436fc56b3a7d1115137015e2a2af9a8bef038b6905c8847c16558ba2bc6ea92ad90b026228695d664720c15e6708b0934064760a745ea4a5587ba211312c7203005f838a2d5b7bb09b8dc7aa39d4956d494472f71a268991ca907aacf8048fc98c095798d0ea043c42c437f6762ed3678b6d701560016f405cad66117c786b56b3a88fb5968c26869f73a2227b129553b220f67cae75b5433b29259553ab4375a0aa6766b2aa0ad480b6969201ed21ccda0a39f8b8f565112565065d8d26dbc1a57425a29fe0a606ba826ffe45a69493b08b11712e88a2b4b0371db5c0ec0125e2659ed08275d18277b9c0ca51797d46cafe91951737868483a418427733ee2637b4aa9496c30fecab67b0b7278a76da2da201874711e6928b7a40e7859378c867b9ba81529656200584ea9a5881b657b68980ef8cb201338ac1b856c4ec5b0c48a80bcd6676c0ca624f05296e59155d5587c2c20bfa1bef1005bbe9840db205d9658935a67614595bb3fe48e52877fc5ba639d023f54d534c58cb90a0a98bd1c2e9e940fdc61193d4753d17463d7eb8c9c6575e0f6845b5c0a5bc69c5f90128d3078960671394b75c5c72eaffc1e8ef4afdb395ffd40a2f6bc75fb9b79e1d8756705b710b0bac1dbb4ac312fff30745590739c08bb25cc9ec62caf1226176c161ece62aedec392a3591ec2ac80e92571c1417be7d82b2f9a1990d50dab78c1dee631304ab5ac57274846a8fdc6547b224c72e0781b233ff8a6c876eca3a3e060a00b560f661042e85340c4a8257660c0592a429c7b81b5137d410b5492864e156dad292dabf59035fb0e02247e6c6847cfd86b6958c74209a8f389041e5389ebf5b9b633b7fcc08cfe14ba466a36777830d840b5fa9b7234403074861984e0593c72c3d5405bc375255e239258b47d782056f106a4f9a493b584909006061cd98ea65a8c131b6ad696b993a66ecf2c32ae1a12e24c83c7b696edfa64b69b71ea7a02a85097d25bbb21fb1475d250d64a9c87598ae12c0dbb7bcabefcb48266b483aa5310e2a734a8519449bcff963c4c10340ff42e2dc883d9c15d744a9bc2d1752383b6c9409e29b331e87c27a11189c41cb8ab182f82a920bd7c9ebf785b09b5be32813e8c128139356f4d60b2cf5c80bfa609b9026a18360dbdfa75d49755dbfa421e9407df6218333331e8917955a551a7f962b8e7be6cd43a8a35318406471161205b5a71e238b911ea2b536c861b0208b654a1fcdc0b77e5429379295354ccf6e93d41c2233852451c8b44b151286020b4093988fc23c533fb83c510720a278e75eb047a86ad2654225cd0445d7b9585873672522e3b18c9bc74ac2f536b5e6bbe6c1a250e50183c16bd79a970bba86693cc508094091e207600009d3893b6ad96433720bac145b6e0f7b1cab23a3379caf84ab285e12ebdb602f431a82e0b098ea1a1f18b18411989cb1b035d0726865712f5cc1e6b51674887b0e00c2eb067731dc8419e64b816955b407a1a813666d73b53d7955639a877a961b4915483af565b006da5423c5644ab3f243c7aa64c5233d4b9a391bc55b30dccf33dc1a93b9b784c7c3429ce8684e1910800739839bcb926374932a7241267835caa9131818ef9aa4ef5c1a3e2f03bfc83076d8a827c082f0d0c2ff89a8fc2e62a96396dd411259d26c7b9c84bd38c557fa45103f3b793097ef6b775f050033109ac7c606e2cb05497c9c596639a63171f5e70775de9c545b919b9e199f4d76508549ee1eaa404f5534ec862e6037b5f484afadca26599a203825297864ef536cf578c277b6541083168d14b3e782a3ded29bbf8a8b1a0f831658582b68b8744c66ef3f385b7a018e3e5cc8c581198e2b4b372002eb756bc7a65a4d67c86ab022f549bb97904e035173ae9c1073a9d23a315d054cf0e3ba27d401bb04569065256be9447a06caedd97871b52624f43916d475c7539bbbbfab35c0864c8c77b12242797323bb12935bf5a08c2ea4d446305a7345de980a03067513f6402e14b29e7287e30194dd76856ed80c55bd65849c1135d398994007b1f14a452e36bbe7283ca7b3ed1b67d0fc3667387c9b3c3cd8314515cd2c4e51b96a8d43a1c755c65740ba9830f65356290953b9dbb03600b18f4681f6f039379f26d40f2c8cab57378b66aa245197cea225eb9b712c95c4bba470b07bc6c458aad71bce067b0991036f5f54636248c516c88eae013232c0191257cd0a6322704c9a6d005fc80c6c6ba0636e701bc5847c091045bab969ab85f5644a5f8f43858c94b276201a7e77aa5c413c57b40726302559762ec40178199526ae63279fb510c8917ab40c1b1bb15dddb6d1c2b22520780f222c15ab2a16bfa28753a61a949aaea6abc3e3083a467110334a959fa582261561d3c8fa671ad34b8b7ff2b682020651935cab1b227d75261e3c98930961457a955275734d9f41c61069e1a5569d38a1a1ca1876e481d94851e62918fbd550e45fbb79a7130643bc1fea1c722675398498c6874ab1a7997008a166c9146882c37e4eb64c3e306d2b2b4c1409a81da2122a5360430774fa56c5a3520a7e870aafb55773124d93b17451c01c7e21be33a9de7a500fef26c7117c13599024ebab75ba9710c5465a089375b2a751f5c3eba8151bda4182ff3280826c3190b9b11b89bf9d151c4a939510007378895f916bbb8e107031459e27c9ee698a269425ebf5a484812271ee667e8c6b9f5ab3624dbb09c5b83d5fca7bd54af3b33980ee435cd5a4e3e6bbfd82c10c997ace9e09f77cb9fc4f8c13b25a8a12c52c7729f22a3290140c7ad0480c00a175db293cea64d422baf4bd306c5d446d48b062f751f47891a8fa82b9786148c364e4dd85507c07a9b4448e57c2795554b3cf53d5d14ad3179669862123840a7aeb57240d69ecadbb48521c196dca4705671b1e566fe59b08cb963f417abd01a1915a33367508cfa9c89413b7709eb48e9bc2e809a56b027b6dd3a513a2428466c29b6ac802f9a83536ba1adfb96270c57a0743c12733525311e8fd04e12c52f15468e84c6af54d8bae8214c152c56082465b79a6cead444aa767571cb1351e4cc05a8a75057c5745abb125a5382cb8a3ea2170c104ca21cb5da000002b7231a8a0a23e50d173485c7d1cda9e8c1da913161e34fe0a986ed5c1183d383067b7dc6c75ecfe4c044c7ada3fc8010aa4e8f28bfa72c4d21f170569165ce1762248370b8cb76ef5797253567fc98a2856870b9cb312e4a3d93b506a8554738e522e11bb3b7976f9ab17ce8a190b0cc810258972a10283c21b9fa36384ae0be5556aa252a59c1aa7617b480729c0272576dfb0c6108db290a0cafb8588f6db8b933970ebca0933c9382acab4dc0c75c4e9a469ad60c86d7474440b870e7958b600b6a3b48cb13c938652198c183347358cccb4d45ab3a4fd7c7730470c2218726157f89facc31b6449fd6b4666081572ca291ba6e3657165b053c6a239876ca5eaa0bc659b0b1635942a90b39aeb6b22f2c521baa4aa98579fe79b541e3acc5d006ca6586818664ea6108bf0080966ba83c77aed8fb2066c94458e70a90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10357d61586f671648188f070899d2eb3408158adf5e8056ef37ab6d8817cd8275e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +expected_public_key = 2c12be5e04521dc3892ad41cbbd769aa8b79cc9801866c87f7194d89fa56329100f63788904c7511533ecc5b8e7fe45659bbceaba74402605a84f195925a71e3153827a5b417e0b994ac6355071ad98b1328f919d6f8c30ec7ad3366683aa3472132c801e59176711e2b20c251281311a6041ae71f96b9ab225a35e6273b5878ba6e362bb1ac896a557078495d1ed08264984357498d119706b7f4bb42a8700eac4e80164e19c2263a425f4fd18f39c2b3e6d70904e7481a14030b40bebc26be4930a05b4236436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b1261355bf296be8726b04a066138c714b229028b2dc5e5233cec7abe672a0f67572ee2a0b84b6f231a37bdab5006a9ca184cbb82948c46b6882df10a6bc12a8e637d3d437023b99197c207acc2157c43396be138ea06adc0bab4aa2aca95d5989cb6b9f1987a58d52b0b460956452f6c00d08a188030bcaff3e9ce91ab88dea04547baaff1d64bfe3c2f5050a398cccef166a6fd82151738b227c04288e8bbde4c45aa285af2767d17b4a66529a06291757cb52ea67865afa5390a02d0e93226eb200a03fc0e83203e08390af0875f2331b8076259d9378dc77877652747774b85064b878b816cb30c6341c4529fd112b1857d2c2c104a57c52e6c7ed5274873e43303238d19f21447cb45ce568e3ca4863be289e5917e38b4ae2ca117ae7a45b29c345e8a463cda4264877964033025b5a77e8824b928bd2305421b810732a1a2a96225cef965e46369cdf15e0b6129b5aa061cb88688fc0e0da00d71612a56085be7d24f88b4c2e6b7125a58c253c8272b04a0df60485147b85bc566fd34ce78a95a235916729778e4b521ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629e712b8e3ceeba7b32ec4a4b9e115576a6f74495a7210c68af925c7ca5f0818390ec408757170c8090c4ec78fc312a1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7b52e32bc1799b649497b4542970a50ec5a412594d50234cac594efd1b415b777ca759ec6c51197177dd183307313a3ea9b7976879b85703bb81aba1ae3727e962c0ac0ba7f60cf0cd6c8e863a0c6f395b41935ffe6b56d7026a0655d2176be3cd9537c227cf79243e09a5d04783ed170af46ecc670b16a47803ffac59744ac514d84aa544350510706aa408b91e1bbf4387d13e05feea35263446bc7d32648c8131d1b53d8da5ae774634b85bc77742128bb984ce4341d1b05cff711ee33aff31b849c66791fd5259721bccfc8a1836cc95c39540652a305c410e61a980ea5b720c472683811c7c596b635072fe7589c1700d72bc2a84106a296636107454a7a47c66a1234a3a3abd91cc7b049738b6ab7d70f450c64daaacf2cf9148c1806e2308f9c883875ab36fa20593559cef890006eaac701db9d80a762c448ad14c4b8dcd22c2a4b26ff23912e30c1c4f0467762b39689bb9ecca9ae56bc20c1347c6b4657d780d0a6c0abe904c9fb8b7769c550a11dbf54be2f2b4fe895b74002ce859228eedb676fdc15fc52c5a0679399205cb0b964e8e3576dab64f21741009082b04a9a4881c91be1ce9a68291087619b8922524222b1385454f59d355231f75071cde1cc1f96b45425932406380fa54653f521c5a178eae6aadab4bddba968fa037a94688643961fbceb633cf95c253668187784b09a7270993f6f12c96ef91cec254ccda64bb71582f20227dac5bdfcd535de1324520731747cb81cb96f13633da59318119150a002a2417ab8963b51f4fcb4c3b34ca9964fd5d94e57b23acbbacfc1267641da2083e55f5ca34695c7a45a283b15365ab9dab4118cb230ea06eb4a2fbf952f1342710ed07a2cf16e3145490a2a3a9ff308e0555e0015029e65aae08024b2637da6b0bee9797536004f9c54a782fab6ee67a8847143529c8564c37845f2c281664366205f51e8b577b19daa25162f291e21cc498a5599a48c439457a2c98cafe7e600718b282c45c58f04306aeb59e5d6ad6f3a3140903c6b8636eb2800c554c4753a3c981914d4c6c6914b56fdc26132fb281e944f27b4abb3eb937cc49707e89eeda1694dec921b6a6d9c238681dc2f844096af3bb25d61bb81d557478904b87511b5c2acc402a9164807909376b800b8ac970648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_private_key = 52d431d74363ba07b7ec47c2a5b98157f616b8c7b7d3e68ce3f2a31365bf4e21747203c5edd758000a8c09d38a83457fb7b015bdb187e842b46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556a62c8aac92f0ff59651c1abb789970a32c69d153b14a687fc2a56b9e0c382ba4f907a0bef79bddff781776abd042044a1c84c4c80ab9ce9a76bfa6374e9cee06081e3661a09cc3272331936cc85d6b2319cc7873227303191c36842b61013c0a41082b82034a2e1bfc8c47916859eda53033d5427741510e842265ae36d530a19e5d7365127bcab5b506321abe2b69de823b660b4699f8859de76899098159c211cffe51c7198cf1025bf9ee69236c913b16aad84aa4c381a577b6c7a3403627b323f11ebc1f304747f47407db9a8c9e4b866082597f28b6ec272ad2140a43a52188b061650bffae19761ba99ca724b71191b6dc5b16450cac50b247415370d5b207701aaec3a13cb477983f180388050175658ccb4714acb603b6b3aec340dc6c164fcb81331ec194c382fed024e0d962b056627a5b05a00b5511d78badaa489f8bb3f3c5b484f9c1450708b89828ef24b815eb43a6b8b127bfa49acacafc46434987bcaf5f91a926140bd56504fb4525ee1921b63733db2986dc133078caa44518871ba12894a553bd024fb731a0ac44ab80199394a2385bc440515877cb69b73b0c847e40adf238847608908c20bf7e1b86fa84781371d4cb52fcf2cc30306c8d98c679d4cb41eaa0ea8b395c08cac6df2348474a9504592ecd34a93b3262c9751e42193719b617355c59a25679d909a5e756c8db03e3b174e1a063edc733b9350b4f738618648baeaec5b76376d05329be6e706e632bd61292755f361096cc4565573562053b4402c42c85b5299b1cca0b9cfec4605d63665f24561d8c1dcfa896d1c6d8918a3e6f2a8d4224ff97503d1ebcc8d5395f0a64d1454623890bb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6b220a66d96d426b9a1f4c4c4d0349ce2bc790732247ec5d98e43bcd37cd94b652bfca7b988b063bb102ea0772df0aaec74c228261b4fa7a49f3b329f2c7c6d04c859c9816d5ba2aabb85e52dcae066b9af4d9951766041cc783dc672dde42558f50473bb43bc1f93bc6ea7d33f46ac4999cd33698eea603c7da265ad713e48691c8b048b21134c9998da19060cfb6ae31cb5a3b7387f2257fe94bb3ea4c963d01849fb021741395f1862085f031b6b05a7834551a6c8f0ef91397a29e12db6d776b05c7f12c8b260cf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a851be9a82c9a79a25cfa727c632727c765d4c496d466942147a8a7b65aec4ba84e4e2745671bcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ff9a0b663d79bba6b2b8908b32fc145e4f65c6a8a379a99c9e68a10c278130a1969e0cb708d0ca6ff1669d8756d1d530ade051aba3a07903b5d801456315057187758351588bed222785c9fe83a0fb4c59245cc2a72b309767348eedb7c2097b457bbac8aa96a67d785803744e149b3f131a8b1271ed42222f95622d63157b80a5e83d887c54c8f0303749d48a91e2c2f693abdbb23246667b8108b921349a8a945a27172807d72992cd744626662b1c4aec2567972b8452ceb75632bb81dd156eec21aeb92124b417f828a7339b90774520db6e890df621c559bc58b7c66398676806b502313ced89800d9a26e1579b565a66e3132199be13e6fe8001e36630143c96e53736e7672a7b2c0ee6aaf122ba1d49416c299795dfc47f7c5841134b429ecc73a974248642454760da77b8a9d13a297c4399d2479f3e6b0e56462e113300af202e745487ed781c98a8cf26c23abea748eb851ab09beb51097ee06b124225070f83d80d5af5f75695cc89fd42566946948abdaa068032a7c31c35a1b29423b8ad4b7537af1bb187c111d55576f9c382e391a56850231e36ac8f337086b81b0256a5d32880391732285a9092310bbe67701780cd77aa7e2d54ca2e03711988ac2fa27a9890b3720c783000bfd06224980199ad092dd515456f2cdb8c23ba190594e4c9a0de60e2ecb483011c0bcb3612c12be5e04521dc3892ad41cbbd769aa8b79cc9801866c87f7194d89fa56329100f63788904c7511533ecc5b8e7fe45659bbceaba74402605a84f195925a71e3153827a5b417e0b994ac6355071ad98b1328f919d6f8c30ec7ad3366683aa3472132c801e59176711e2b20c251281311a6041ae71f96b9ab225a35e6273b5878ba6e362bb1ac896a557078495d1ed08264984357498d119706b7f4bb42a8700eac4e80164e19c2263a425f4fd18f39c2b3e6d70904e7481a14030b40bebc26be4930a05b4236436698ec5a5591b88985159cfe5c55d7d84afe7a9bc6999b1261355bf296be8726b04a066138c714b229028b2dc5e5233cec7abe672a0f67572ee2a0b84b6f231a37bdab5006a9ca184cbb82948c46b6882df10a6bc12a8e637d3d437023b99197c207acc2157c43396be138ea06adc0bab4aa2aca95d5989cb6b9f1987a58d52b0b460956452f6c00d08a188030bcaff3e9ce91ab88dea04547baaff1d64bfe3c2f5050a398cccef166a6fd82151738b227c04288e8bbde4c45aa285af2767d17b4a66529a06291757cb52ea67865afa5390a02d0e93226eb200a03fc0e83203e08390af0875f2331b8076259d9378dc77877652747774b85064b878b816cb30c6341c4529fd112b1857d2c2c104a57c52e6c7ed5274873e43303238d19f21447cb45ce568e3ca4863be289e5917e38b4ae2ca117ae7a45b29c345e8a463cda4264877964033025b5a77e8824b928bd2305421b810732a1a2a96225cef965e46369cdf15e0b6129b5aa061cb88688fc0e0da00d71612a56085be7d24f88b4c2e6b7125a58c253c8272b04a0df60485147b85bc566fd34ce78a95a235916729778e4b521ba59b4187a34f1e5bc47c6ac83fb82428c30796b5629e712b8e3ceeba7b32ec4a4b9e115576a6f74495a7210c68af925c7ca5f0818390ec408757170c8090c4ec78fc312a1d9a4cbb4533a00c5acf67c845e9b7831b5824b44a0d7b52e32bc1799b649497b4542970a50ec5a412594d50234cac594efd1b415b777ca759ec6c51197177dd183307313a3ea9b7976879b85703bb81aba1ae3727e962c0ac0ba7f60cf0cd6c8e863a0c6f395b41935ffe6b56d7026a0655d2176be3cd9537c227cf79243e09a5d04783ed170af46ecc670b16a47803ffac59744ac514d84aa544350510706aa408b91e1bbf4387d13e05feea35263446bc7d32648c8131d1b53d8da5ae774634b85bc77742128bb984ce4341d1b05cff711ee33aff31b849c66791fd5259721bccfc8a1836cc95c39540652a305c410e61a980ea5b720c472683811c7c596b635072fe7589c1700d72bc2a84106a296636107454a7a47c66a1234a3a3abd91cc7b049738b6ab7d70f450c64daaacf2cf9148c1806e2308f9c883875ab36fa20593559cef890006eaac701db9d80a762c448ad14c4b8dcd22c2a4b26ff23912e30c1c4f0467762b39689bb9ecca9ae56bc20c1347c6b4657d780d0a6c0abe904c9fb8b7769c550a11dbf54be2f2b4fe895b74002ce859228eedb676fdc15fc52c5a0679399205cb0b964e8e3576dab64f21741009082b04a9a4881c91be1ce9a68291087619b8922524222b1385454f59d355231f75071cde1cc1f96b45425932406380fa54653f521c5a178eae6aadab4bddba968fa037a94688643961fbceb633cf95c253668187784b09a7270993f6f12c96ef91cec254ccda64bb71582f20227dac5bdfcd535de1324520731747cb81cb96f13633da59318119150a002a2417ab8963b51f4fcb4c3b34ca9964fd5d94e57b23acbbacfc1267641da2083e55f5ca34695c7a45a283b15365ab9dab4118cb230ea06eb4a2fbf952f1342710ed07a2cf16e3145490a2a3a9ff308e0555e0015029e65aae08024b2637da6b0bee9797536004f9c54a782fab6ee67a8847143529c8564c37845f2c281664366205f51e8b577b19daa25162f291e21cc498a5599a48c439457a2c98cafe7e600718b282c45c58f04306aeb59e5d6ad6f3a3140903c6b8636eb2800c554c4753a3c981914d4c6c6914b56fdc26132fb281e944f27b4abb3eb937cc49707e89eeda1694dec921b6a6d9c238681dc2f844096af3bb25d61bb81d557478904b87511b5c2acc402a9164807909376b800b8ac970648ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7ef07b1f4886b895a3246241ddc084379eeb0f0ed84bdcd318fe72c9b546413be9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +expected_public_key = 88b1b22e1b2cb01b18957737b65a63dbacc6828418150978215b85703586c1060740d56b50b40f806a7d2b83890d2996cdda967654506e096a9e59b69378152f4b8b2c1050a9e2bc9e20b513813db6f6b42701ba8ba3a03e80362c7904f240a49625435c00d040648262b44d881882de55cb3bc1968f5b3fe78bbec040a50972237800c378eb9ca8735f5502ac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c88509dc25276fac066199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8d514be837e0de28079e22b3f6c9991504c73bc2603161f8836a8814095ac527e0969c00dea613de63b05033b303c5937815b02ebc3466b5bf287265852665afa4d3dc7622650a0ca7438d896404e5b2a09220315bbbd5be37ae3a61953473e2be9b39cd71c072a97db3aa7546a9ebfc651500633a30919fe41a435cb5dd9b247192b233b676d2432132bd4cce04c30af99344e20aeb8e9b6545b4e9c9bb211e5add2071911dcbfdec072cfb76fd6366a74aa66c1831e1b6ac6def02d703bc9a9011480032e0b1a8e668cc3bbb46510b993958a455b25c025f19677f1c03828335b85868dc99c81d3b75d0042c3735cfc063b68630c00680dcbf561fe07ba4202b1045a2eaca9033ddbc2f3e620cff6158c904666927d61d4702c84aab51c60a748acb573704a5b422057ac3933233dcc6c6609cef96993ca951f89e10b68217d4a59839f261fac87375a38314f4b7ccaf5321a305ff7137e4207a9db03ac08370dd903a634b8951fd6c93bec205434ae6fc066eb18a4a1102297abb8cba62980340b2d643be20c067db031aa886282b03dff2870ffc455cf78a1657aa19e958df64b21cd9467a1306ad40195db3a9398c86c5e4111cc40816a860909ea742f8b14cb2309860b5d300253fe6149b236aa8ff44dc8d79b852888a9b2988644af45c030f5a69e93a44bdb454d79c36f2a1b13db7b395cd7b7da192dac99b4d5560fcbd96312483511bc8d9e738bbd4cb5e708cc0a02056a292180d06d0b0983a2748dbabaa88ad144aa1028edda8dea7704908440dd9a272feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abda504aefb2389322af5df12cfd399cd19b52cd8850510c37e6c087ac060e468c97fa97857e78712c17696ffbcda6f13248733cc03c4f08b92000590d79d74f1ad2336b9368572230ee472cc3d28a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c444929376021b7fa06f5acc940f2984b118164ab204ef2ba59de476e0ba22169888e64717e8635e7a30be99441814b5141a658bbe25641d3557f07b33d3027ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b162ae5fb9693607bc2fb279ba5b3bd19408ac8ca13e8c80f2139bf410e3065a0be22800c0305966832899753d342694ce56483a45f0d56848484cd1b9c949c192658e14e7c6abbaa51cb45441af9e46bac064376509d533718678a614c1b9e99796c0d4c8ac6ab134c4aa79a1c22692183c9f2af94836a52930680c974355104a05c0cd3a5c34d6a7b524b1dffe1459754066ab41a0b7315f302955ba23fd2b4588bb58048e981b0cb1df247874699021368277127912848cd65229c59617a7783542b289456337dd572c8e703ab1f22af68c962c9387e92d754027619b7f9accf233a10ac294ee15c3928934ee0b342f39f3ac5299ca681f5c569a2d87429bc7b4c492a9a09a48e17534e7a74023c0601e92bb13ab2f6918a44066e58433c2cd811ec5a144867c666b390841712d0659528fc76fc2ca17d3656b4b0673f682bd37980897b02d3608ecbb27b76ac848d55658f2606fb761154b0c516d0787909a59b35bb73e43988ca7459c22da04cb91c784f47e39152293679b41d13ea4908836735c3a28768509b2c6dc3d220c3db729437bea79727ae8156e2798ab7e9abef81437de27e752188dd22913e477230549f564a353fe17d513a72adf132eb0b0f3905cace01b05a073498c56221a4b9941a0223d4abadc87f83b6aa153920ae58cedb7aa5d4ebb6f4b34570079d6d1354afd1c30efb1aea9c25eeb07cb56417c134cd45441ed49182651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_private_key = 28ba2f24db8e2a5b21092964f1871e97e10f2727c8b27916a5068edd27670d26b91a93332157ac686205e23616eb0271b081b51923c5996743cc114f3ad310cd6791aeb05f77960991513ec655533921a8d14cb2589399ebf18f7ba89bb7d6cd2d7336ece1b7b63b98f26a49d356578ce7275ee67677d1482e1bb3d85b88325bae0a00cfd1288c34078d73965442b7b140705f0fb76ee3d0921112c400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313e82d51836a2dc1b0f37a2e00545f802b417a9406e55420b4d71fbc2210d05a771cdc164ad50932ea40a876051828236153b4e1715edb1453045721e89a60acd0066227704b8ab991e8a06812226bc59943c0814c847a1865c19df4b7fa13ba3ef95543e724ef854ccb28bc1db49b75c1aca3649f848bc6f32c139aa79197543c628238adb755f4da6bd67130772b4790b28c9f1544a4e9860e875e68c1cdd9cc0cf17451434c7c53f3a9be39849720b1b80a836ba4c531d49bad16077e90203c9120c23239cea972454b08a5f10812443ca75b913df98dbe29c3312157e156311f67354d414aa041833f8454aca5b3898b3572e819fb2c4cada43c9c5191d6f7aed8f310cf77ccaf0c478686952e71a8a8173d0c223b04462b96c04ea7b218a13519b90cbe3be8c32b276f90d349acbb6362706dcd54aad0497a058ab0138a8e57d514d5d431043184bd1a07b77c3299ba6c7205938eca8403f31a1c605a942b73775a1ac11c40d81988e69c15079719aa769b5f618052d5290d84714ca57418366c15b74da4e98df96abdd19884ec1703f7978c4dd72b48528789d7148f16c23ef8bcd1f353cc4a76e7c238aeb1035424300f529acd46926874190556133021a6a9283ddfe02edadb7de23a4d141b0787539b68110b4882a51f95403865becea06e2d7a1c1f534fa3366bc1ab387eb867477b92f00c0d09615bfcc1138137cede4098ad57894ff74982d71ba2eca6a0f502cdc9c89bc6a44bd84fd8b62bb5d84332faa830e2a732259945028d2830a8aa866f92c24e46d164c4f4658791c11f0703d906a82546c75f81285c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce770f04f758e6124543e13d2365a915802f75e90997b10b15e650aee33a291c87030517b6c29cf10670d2dc5c8889aab7518b4dc86d86e25c52acc4db175a5957118f983c3a4443b33803a3161ab24004b7a789778c8414a8aa8c819468ebc28b68afe5333f7e666d44b5a961533280b0021bd3b24e2aa51ba58f2f45767a5722e918b1204656a2b44ce628a3a84125f918999a6311cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87b709353a77743949277147928273f112b5e618167a5715157b49ced69a2492203a08730ed07b7aa14bad136cfa969dfa68c28af40b9763872ed1b05d4161489bce1f473d4cc067a86258f6b664d2436d4856166cc60467887f9b97439f607d336114e46b2a2964c228a18eb532cc4c6813dfb841e60c3baa59978234a06fc95aaaeabec0123230ac33bdc48a4452403842bd6158c668f28f20bb5501984c5d3992594a9238e03798d178702b86973350dc21617aab9b4466903d4914d37a2ec3d936c162933505b7f45c3a26fcb3b32bc3da91aad5d7a8af045252202312d98a7877935cd6b8c9499ce722c6566bc21fd427f1902e6bd190c8889824b35b79268e4b2c4afda48b0c98856a097bff3c4523bc02739349aac7b8cd286798cb919bb550575b44ba40226cb323f83886e1e164efb1ab648a1a738747e799327f58630134beb48a187fa5694279bf644997448b57f909292807c441b8061f8a4c1d1bbf8c55836eab38fa483b66a652c556191e9c959c45a4175244b851b294e38134284f771b81cc72bee2bc188d58053c7589394b49b5b33cbe12993549c2ac05be0dda9b63d97e45e738eb2738c59224db502a0fe3aa37d113cd3393419c850b77b4b1393884dc9ef3d189ef3499372c8851f290f928a9c05a0a210926cc1b5728115771e55fa14c23ac4b1e9f507b02164f2234050f06896ba969347b3048d42892600e7dba3b8da0cff0d1707c0185f9b16fca3921c2b648e130bffae62f0fea48ae91588a15c064a9cfb0bc862dc9ca88b1b22e1b2cb01b18957737b65a63dbacc6828418150978215b85703586c1060740d56b50b40f806a7d2b83890d2996cdda967654506e096a9e59b69378152f4b8b2c1050a9e2bc9e20b513813db6f6b42701ba8ba3a03e80362c7904f240a49625435c00d040648262b44d881882de55cb3bc1968f5b3fe78bbec040a50972237800c378eb9ca8735f5502ac220988675b99ba17414a077d8b9c79e468a7e3a7c9f65b36d41b9c88509dc25276fac066199689fd29c58a5b702b1b9f7e2c30492a9bebf99a300c57d3863365236af8d514be837e0de28079e22b3f6c9991504c73bc2603161f8836a8814095ac527e0969c00dea613de63b05033b303c5937815b02ebc3466b5bf287265852665afa4d3dc7622650a0ca7438d896404e5b2a09220315bbbd5be37ae3a61953473e2be9b39cd71c072a97db3aa7546a9ebfc651500633a30919fe41a435cb5dd9b247192b233b676d2432132bd4cce04c30af99344e20aeb8e9b6545b4e9c9bb211e5add2071911dcbfdec072cfb76fd6366a74aa66c1831e1b6ac6def02d703bc9a9011480032e0b1a8e668cc3bbb46510b993958a455b25c025f19677f1c03828335b85868dc99c81d3b75d0042c3735cfc063b68630c00680dcbf561fe07ba4202b1045a2eaca9033ddbc2f3e620cff6158c904666927d61d4702c84aab51c60a748acb573704a5b422057ac3933233dcc6c6609cef96993ca951f89e10b68217d4a59839f261fac87375a38314f4b7ccaf5321a305ff7137e4207a9db03ac08370dd903a634b8951fd6c93bec205434ae6fc066eb18a4a1102297abb8cba62980340b2d643be20c067db031aa886282b03dff2870ffc455cf78a1657aa19e958df64b21cd9467a1306ad40195db3a9398c86c5e4111cc40816a860909ea742f8b14cb2309860b5d300253fe6149b236aa8ff44dc8d79b852888a9b2988644af45c030f5a69e93a44bdb454d79c36f2a1b13db7b395cd7b7da192dac99b4d5560fcbd96312483511bc8d9e738bbd4cb5e708cc0a02056a292180d06d0b0983a2748dbabaa88ad144aa1028edda8dea7704908440dd9a272feb8138146e44e574be538183a391225bcaf9475350939f5b14ac75336df086453b69be85b350f829abda504aefb2389322af5df12cfd399cd19b52cd8850510c37e6c087ac060e468c97fa97857e78712c17696ffbcda6f13248733cc03c4f08b92000590d79d74f1ad2336b9368572230ee472cc3d28a03a7547b5c7c1e63809c9aaaf783569109522075b9c979c444929376021b7fa06f5acc940f2984b118164ab204ef2ba59de476e0ba22169888e64717e8635e7a30be99441814b5141a658bbe25641d3557f07b33d3027ad1a3c51fa497dcb6bede058c18b6adf41374ca1984a0f43a6d25ba1b162ae5fb9693607bc2fb279ba5b3bd19408ac8ca13e8c80f2139bf410e3065a0be22800c0305966832899753d342694ce56483a45f0d56848484cd1b9c949c192658e14e7c6abbaa51cb45441af9e46bac064376509d533718678a614c1b9e99796c0d4c8ac6ab134c4aa79a1c22692183c9f2af94836a52930680c974355104a05c0cd3a5c34d6a7b524b1dffe1459754066ab41a0b7315f302955ba23fd2b4588bb58048e981b0cb1df247874699021368277127912848cd65229c59617a7783542b289456337dd572c8e703ab1f22af68c962c9387e92d754027619b7f9accf233a10ac294ee15c3928934ee0b342f39f3ac5299ca681f5c569a2d87429bc7b4c492a9a09a48e17534e7a74023c0601e92bb13ab2f6918a44066e58433c2cd811ec5a144867c666b390841712d0659528fc76fc2ca17d3656b4b0673f682bd37980897b02d3608ecbb27b76ac848d55658f2606fb761154b0c516d0787909a59b35bb73e43988ca7459c22da04cb91c784f47e39152293679b41d13ea4908836735c3a28768509b2c6dc3d220c3db729437bea79727ae8156e2798ab7e9abef81437de27e752188dd22913e477230549f564a353fe17d513a72adf132eb0b0f3905cace01b05a073498c56221a4b9941a0223d4abadc87f83b6aa153920ae58cedb7aa5d4ebb6f4b34570079d6d1354afd1c30efb1aea9c25eeb07cb56417c134cd45441ed49182651aa5df5b6c82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa1a2d9ea0d2280249d9d756975c6979a8770bf4b5f6addbd76d045a816bc1be385fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +expected_public_key = b3f044ae2026d8b17f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749a52c8bfa2327db1a0258829bf7bbe4f59b1a6d8b8d3954db41bb4a20b0d660c21d6202759601630854ee75cc29454ab1a3469bffa989076301132aadec892978b3e15082bf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b507f31bc1495ce2d5943466996a0691d80405cc21b060568f55a18fec917106d7277793089e147d759988569820e0254ee7896e9797612c655e71371178a14b37b3a2c2b18bdb952a5295bdd4385c190b3d61136f128ba74c2c57612708f900c144093ae460c86c7a2f0b1903fd9a889dd7874f6543a2e112219869819c35c055813a394333ac6c9c860ad7505f8aa241046a984403b798e3211469cd1d8a57455702b2816f0b2b3ec60b273b102559099528d306ff23be250b50226b497b60b7540813f5b0c4a11732a6b9583a21b3dd2028e79a82ea0144ef34c32e4392a11241748351046b9454a50e9f90739d12a96a928e75806f24004b4a926f0e8769f90a921c4323d7fb7cc74c2e33248c30b774b795cea60c47ec52a01ae84247e53243542ebd8abc24a183e2d72247628269e108a5e93f11a45ca9561e8fabbf85aa61c6bacc2493aa93a38bb72421e8913fcc635ea0f2ae17ba41e43c5af3c83382f0667b6113591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc7c224dfe3bef7e0afdebb5f91b2532bb867ab3c08cfdb6a64ba1876285bf6463b9a241512919c9b72669ed252faa0aeefbb963076592f9884b5e60e42c2008efc08bcd1cc2bf31025c386cdf99b49283d6d7b0a24693618d2a2fac3b7acc60ec970b6d357b199fb6af3039eb6601bd57506cf8292d3181eff61cd380c525086962b58bfe53c3c0844431347a2f2112776818fa3ec2937b4b3b21c52be816637c38a68aa5373858e16c18134093311292814101cc2940b7f61953cf5971fb5ccae59ada4373dbf9c149869a0833bcb97d9bc68d6581cfb803264599a9cb1cab10a15178f6cb23ddce70d060b0ecc7a0feefa35b6db9800567417775e1df95ebd32a4e67616381b48595933f301408e2cc1951a095994428ea01883b4a8a8d780cf960d69a18425258eaf63ab2f2752aa411856b78dfd60c2da74c35f517718c3b117a98e968a72c3150105ca44fb02b14c439abb81adf5a94e2e5b7a8971848c4a9156e1445f41cbbe2c7c18785baaaac24bb87936ebcc8ef6ca4a951d1de8c2e6c5658034c1fde4b75dd1a176824298a669b0c4355aac3e201380c42cca5060192d06606e8430e135c50997579cd756da40336541a781e6702c0041c696270b65a92d531e964a1e953555628929f7fb59a7c2a5cfbb90b4f04b129cc011f7aba0942247908b22267df9333e8c762143c4b68909694de674ca14c7538604a7741fbd9004d861a04f63b74106729c6759718125cbdc40ffcc60c4aa30c7da001e30c889276d48b1329ac033d5365d76c85893da0e15590bcc064f0803cad5e80355fa56974ac577db713862545aa43747f9456b822e74e56e3a825e0f6259a3551565215dcaf4c9ce568c25d9c9c7471806210969146bb64c7af9a03ec276ab4ab10e8dc227ab491473f09718c4a046e84889d7c40f0bd0878675deea6c8e071b0e819f77147631939c035a8f9a4644b3dc35c3dc328c1c0cc6cc537af884d7c6000dba9e1e3062c2d43a30eba1873409422a5f664174d2f536e8420634558f4d427d3b8b48b96845b0f1847208c374f31d419988e9434a9f626da5258c00654b6789122de71788d6b259a29eabf83a42621b1bcc1924a79d3fb59ae6475ae6714296ba1528f30a66c2597ed308a3973a501cae96e1779813195805b12b0b008090acafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b1829428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3db0273551877522faef812d452b6444c4ecf3b9a9670810354b5bd57ba43aa5c4f271a03b2800f5290650a08ae83061f331489265b2f2a3ab1f4b3159103773b7806157e26ec1892e2c3d121a601777834b52939a658531646e713222943a0decb5b82baa4bac41f1cb2aeb3076a1a20a382698ce3919ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_private_key = 2f766ad78a0112b8cd4bf28dd0f589873553bf114f19c2719f61a32cbc85c71975b911237bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab4729d02abc5dc07309032c7112540522575d663c89714aa7a456410144d7c2bc1041c03d5a56e08cc7e5663c01f52e5077288bb8cbfba21b4a8a19c055691e05c22f94c62c3cc2b6a9c155e2a4eb2bb9d95b8c9d5a6394d05af87b038c210d9faa266cf07088b3cc7ab56ff3366fbd595b3c790b5497b34b94a72d8153fa13b40be96b51315ca4d22be3828c3556843545c47b0254266a802a44bee6e5a19a446472322c6aaa4cf47218ee3c99247564c552c93ed589ea8bb2c637bcf7277d5b5058dd80342815b2e8864b4c330920a82ec76b4a7bb893e0d18278f47f84743223a67f2983ac8c4a1845a61259670b02d6053ca181ba4c1bcca05b7af2a27c59c1e4e38da723b787aa2f36c71e3be05039183bffea6ab3bc779de2273326b327d42517b6c6ed8c7f96c6330d4c39e3d2a7b81a538693329abbbb5947b068c3cf7b45c173c1ba9964c86ed91d0bf64e209c1910c218434311a50a2128d52754148159891e00475654ab30b9693ad507b2e19acb7fe6b14f27c09c6b2570b861926683a285014631c2d7cb8c0c10a25d073d3c067ab819b9dc27971825ae21cc2e50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d90795719b237238c1f831007c690186949c600c6f587ac0d81c8334c57fe0c59db3e2815d63c26c620fdd75836261644d99327a334ea5a40571f0cda39ca716d2bb894a50bc4cc84d6621b60509dac77ecaa39b9779a3696749ce83933eb70c1e85bb2dc3421ae9a0ef40ac2d83a1fac16c6dccb0aa16aff9a94bb6d125665c3001b845e7f20e7c90a3db636950b0836ba008da33500fe47fd4a81df0e268c62974bad02a6d3b2267f917e2046df3c1883187683f030a28a129902083ce26730438b0dc0042998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913dc261b6274464b656bcb645f87b0cf4512af443959e67c47d679020c2905d45e21da586ee8291085a8a432ac6afaac594081ec298dc13175779b8635fc8eae58982258759999a57b704a5b040245d282a9b6c9cbca838399523f26695f60389ad42f6512783ae65a0c25b7258674398839af28866671329109a58e579c026549f0b7041dbb6623665fbc9a2ede41c0436635325912366ab1364b5a3162c4b8c2a14480aa6bf165588b8d26ea968291cabf66a4e26722f87977dab7807a2c65a26a9cbd339bac0b24e6b46e0a8082be95bb7a41b1b8b670ed3105eaf994a06a6414e9abe2a1b608c29c94b846012a0fcbd6959ed411d8d0c70a32559c68c74d94b2a9707b9d9755e3c69ac40782e97a1f904a32da824c7459b59b174a9fbb6b41947f47b3361d5558d831b2b444818ffa4c17f4bfcf8b9c7ce451f4ca99884c13f85c24d3cc4740d2567a54ab0583a175759fd7e197f3000a39717bfd9c768248518d50791cd84dba795e85388dca21507bc669ff0b906bf515f38c04dc838d0d1357377b1601887ae1b0a0c4490d38a871910c695c50008e5a5a0f4cbaf8497a56f6707f970b77962e13a5c09d8a6eea50840413ba51e22af3666098f23c12a9a6ff6785975ba75c6823e5980b78cb3e5d20b7efb9307468bf3b06cbdab62f0c4ca7157bb22e9595a4288e16416aac3748099229d397a1f716aef05676c2a035629c6878865940f17fa0d2ae5315c4340c7191b415046994b9188d4e22c50239901408b64c1132f854a13de43884b8cbb430b277341e74318669d2411d49ae3d660f84e35538c7668bb8c7edf39a3fb33bf7e45336fc68ab37477c037f7d4a460f3c211847468bc10e0ab67576605216f058153c4f5e041900265ba367afbb21bb13600c4aa74fc55222be11c88298b35789532f357157f48931c2a58cd6a75e82bf411a0311fbc2b84a67d7353cd13ab939a05d55157a19d226dea6191d30b28aa916624872bd067b2d7597d73419fc5cbe3a46c36d0047c231bb4c12609425c1f672b69f57aad8f091222c109fa66512046822b4c7c57ac9f2c9c701d7167697bed93c789a626af045a8d5a2c2d51383e41211bb38b76c9684b3f044ae2026d8b17f397aa66707c6846531cd5b3db17cbd072bc4e2747efbd5749a52c8bfa2327db1a0258829bf7bbe4f59b1a6d8b8d3954db41bb4a20b0d660c21d6202759601630854ee75cc29454ab1a3469bffa989076301132aadec892978b3e15082bf84897238ac6432abbfc59a21c43c0befb55e1b582d26344a6a7b507f31bc1495ce2d5943466996a0691d80405cc21b060568f55a18fec917106d7277793089e147d759988569820e0254ee7896e9797612c655e71371178a14b37b3a2c2b18bdb952a5295bdd4385c190b3d61136f128ba74c2c57612708f900c144093ae460c86c7a2f0b1903fd9a889dd7874f6543a2e112219869819c35c055813a394333ac6c9c860ad7505f8aa241046a984403b798e3211469cd1d8a57455702b2816f0b2b3ec60b273b102559099528d306ff23be250b50226b497b60b7540813f5b0c4a11732a6b9583a21b3dd2028e79a82ea0144ef34c32e4392a11241748351046b9454a50e9f90739d12a96a928e75806f24004b4a926f0e8769f90a921c4323d7fb7cc74c2e33248c30b774b795cea60c47ec52a01ae84247e53243542ebd8abc24a183e2d72247628269e108a5e93f11a45ca9561e8fabbf85aa61c6bacc2493aa93a38bb72421e8913fcc635ea0f2ae17ba41e43c5af3c83382f0667b6113591b6af80950d5074a3f8c4fc2e550ca9743dfbc4c1f797543fa784ad8687da8a643476fcae931c1c7477f063cc7c224dfe3bef7e0afdebb5f91b2532bb867ab3c08cfdb6a64ba1876285bf6463b9a241512919c9b72669ed252faa0aeefbb963076592f9884b5e60e42c2008efc08bcd1cc2bf31025c386cdf99b49283d6d7b0a24693618d2a2fac3b7acc60ec970b6d357b199fb6af3039eb6601bd57506cf8292d3181eff61cd380c525086962b58bfe53c3c0844431347a2f2112776818fa3ec2937b4b3b21c52be816637c38a68aa5373858e16c18134093311292814101cc2940b7f61953cf5971fb5ccae59ada4373dbf9c149869a0833bcb97d9bc68d6581cfb803264599a9cb1cab10a15178f6cb23ddce70d060b0ecc7a0feefa35b6db9800567417775e1df95ebd32a4e67616381b48595933f301408e2cc1951a095994428ea01883b4a8a8d780cf960d69a18425258eaf63ab2f2752aa411856b78dfd60c2da74c35f517718c3b117a98e968a72c3150105ca44fb02b14c439abb81adf5a94e2e5b7a8971848c4a9156e1445f41cbbe2c7c18785baaaac24bb87936ebcc8ef6ca4a951d1de8c2e6c5658034c1fde4b75dd1a176824298a669b0c4355aac3e201380c42cca5060192d06606e8430e135c50997579cd756da40336541a781e6702c0041c696270b65a92d531e964a1e953555628929f7fb59a7c2a5cfbb90b4f04b129cc011f7aba0942247908b22267df9333e8c762143c4b68909694de674ca14c7538604a7741fbd9004d861a04f63b74106729c6759718125cbdc40ffcc60c4aa30c7da001e30c889276d48b1329ac033d5365d76c85893da0e15590bcc064f0803cad5e80355fa56974ac577db713862545aa43747f9456b822e74e56e3a825e0f6259a3551565215dcaf4c9ce568c25d9c9c7471806210969146bb64c7af9a03ec276ab4ab10e8dc227ab491473f09718c4a046e84889d7c40f0bd0878675deea6c8e071b0e819f77147631939c035a8f9a4644b3dc35c3dc328c1c0cc6cc537af884d7c6000dba9e1e3062c2d43a30eba1873409422a5f664174d2f536e8420634558f4d427d3b8b48b96845b0f1847208c374f31d419988e9434a9f626da5258c00654b6789122de71788d6b259a29eabf83a42621b1bcc1924a79d3fb59ae6475ae6714296ba1528f30a66c2597ed308a3973a501cae96e1779813195805b12b0b008090acafeb591af94ea6394a2ac955fa1b5d8dc388498c6c8b1829428a838ab73eab19c6ce4a409fc782fc399fcadb90c9a7a86f9799a3db0273551877522faef812d452b6444c4ecf3b9a9670810354b5bd57ba43aa5c4f271a03b2800f5290650a08ae83061f331489265b2f2a3ab1f4b3159103773b7806157e26ec1892e2c3d121a601777834b52939a658531646e713222943a0decb5b82baa4bac41f1cb2aeb3076a1a20a382698ce3919ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5a57b333a2f41fda2ea72ea11d8bd642d911f6afe90e60492ebeefdc17a93219211eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +expected_public_key = c3c489ddc6bd144a0458168e5b5686e92625325a8418565eb6fa0fb7619773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7bb2578e2a42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c4801107d0326eb24c7fd4612bd91275eca20f057c27e10b92e0b27c07a4d621751ef66307ce584708a5a58661838b56e2b2670ead04a9df7cf09bb8c83842dcfe4cfab4a83e75773e57b908feb46bf44013744bfb1d3cf98d34237b29207961d5d5cb43d6a49b17601743c86640ab9cd4a1786448c89e12adf884147e2cf091b66da57883cf36363611e04005be8376fe99c28fbc50092a034fb39abdcc97c6ae0565df82d4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7df119e86b92c407cccf98581bc62ba89228432a4922ee5c47be661dfb543ef26306f5301169a31b054cda1449cc2faaebd04c2b5823f58997defc48f6db37300b0c1c475a866b035639a5bdc4669cde9297d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6b31b8c529b84cb42dd8e2a48fb240c6b703c787590ecaa1f74044b5e295122c0a81c3a71322a2f4c9a33ea67d341a4426d60169acbdf19827759c144a271078582a33541bfa9367b757baef6890cff95d32d68f6c90338a20298b000e9144112dc22f4bb3117a6abf83b86b2b3b9cc244330b97392dfa3202ec7746d081f0a036360abad9d7028ab5bbde47403ca1a7c68a2c1679212ba707663ca412692049d45017f4993beaad79a990bfbb416d3072af8749f7f251dd51ba3c8b80cf34cc21ec923ee2a52ec3c981602c94d668bdc108154429508296805c156f05ae7908310fc176ba241cd35275b4c89e52786665e5798ca71a5eea5a721b51de6a78060a58f1a24da91666fdec925231c8c9f53d2fd270920092f29515dce0a8a2c6ca1e68bda6ea24b29424e22523a7d41773252e044356650aa5aa467b3cdb72be7700d268572d620279ca0668ab514243599de939a85990bc7cb640019bf8271efb7b1d32487b2e912e4f0267fbf197f1e3c4de63ad7455bbb2204db4c5995641892330c5b5140dcf0a8009d135a92352e97584c1f294e9548af9ec348e7408b448b85d234f6ed614834706a0c978ad9a08cc814953b8bbf2bcbd87071b597343629b3745d212111b7230ac9275c037d5e747afe60cbb9b439b06beaf537d6cc80bc1d1ca3db49f53c4a935a0226f37a85b058f32e307cbca9b7c62ba581b351ff5cafb198494d5abc4406e30932355754ab2a38232561319b0081b266b1fc714567305e0b27d3d6cb8457baf9242c598ac29520432fba3c3968c8e81078989380085178489eacb2c10c452079b1c33634df13d82b81da91ac85e43815f262c133075cffab454f50ad6c35410b295a5357e95fbb8a1d80964a40184a19618d2c0b7e13ab5828b60d461e10b41e3274363687cfc5849fe6badfa11821a31c2f724735ca1c4cb365b16ac43cbb24ec865a6dee75b7a6815500072065aaaf7b9af31214ad30ab984c57515a94a67b7391a37044cc22c9976851b19cd975a2c3be0539b213b9032928722029ac59231c90945a9bad4d39ebe623c08da1421d90fcd990bf8f8807b18c99a3799de3068a09912bcda3f5cab1089caa3eccc831f64bef79c538127b152f97946a264f4085c50299601043860d95832d15ed6f06051d12386559acfc5934cf4110827476b32af4498819e3ca252f28b48a96195f0a7c8e01a81d00c9063acc0954337d360b514906504ccce6a54bab7a3624130630a5f93c97af1c1a981b50eab54937251b9e1388842847ec6f4296870b51866c04458152fe3844cd879f335a7a1fc0b04094d2692cbb2f84f4a02b500d38fce69145dac4d0e4339d7978ef6e651c6110154046050b52bf29751c0778bd5e0409a1a2145bc87b1554b5ee209ed03ce01c251f4f39a67e09f2629a8024896c6c59f2e9a2e26523273e337b2b80760db1025f5b21931a82673be930ab5358381241acf46879650c208ce840b48041997500c8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c3a2b61f85f0b10ba790512d6422900db29d542ad96d8b6c0d954205a0d2c74810ec4469bf2b902811e5f5778a4190961853c777514319cab0cc90cc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e24073df336efa5a0d6fc17b6bb2c615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7e312f81066d516be72680e5a665830f74e371bc411ba86f00704dcd3c40c8c1295d6b52aca51ad41732032535af95bef907127eab1eeb54899a36961793ec47b91d9725643664082c4375f4843b0031b815c8dffcb7f25d4414191746d5aad14093bf2c005df655f69917baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd9f81d730157a59b971e4b4a0fba8ef49754a7c2be0325c8bc623fd2a94a6cc4226677260ffcb64d75167d63334e395df5ba4505495cbc8c3a3e40ab68796d6c646775339c29683a21f921a7c6a79d39a95c876f782a27a6365908381d793b537d1a681cab5599817e050cccf7803bf9a90ccc4084743c96069183b08702979c9dca2b9d9bc26e1de849976aa1465b29eb260ffc64478c39945a9b402520172cd7861c5a0cc089a028c8200208b3e4d7b3a91cc8c209c5e1d201278b01cab34126c701bfc2913df501f6d73d9424cf1176b8616c04c10940ef9832957585ec350e9761505162aecb28884f659ea23125c382cf24f383f9b09feee8aacb981df21a6bcec26e2a67493b919fea06170c18b79e5a01e6e89516707bcc7ca353727825514aa0d52504606013e53ba916bd133814c36b98fff15f847b7383854f692450aad28231f2bb4fd839d2b532066114da65be8cc5073f9992e03836ca3a623c301999a56fb00332d1ba8a26d599d0f5a97975814be81fc9dbc536d1c165a131ca3c55d04a05d7a53fff1299d3860cafd8bc6e3b97e72a595d294303a12994510f74887fd1d7bb18da70bfc5bdd58c1f6c1cb56f5994b7f2225ce0ab29e8cf3dc851f1aa5bf2ba255f7215cc71c5da95115d6a98a2317224bc6de1b2c79353bc5c3c046a7a0933a73419f7b117b88f3a53777143546cd29014e15e37c33770a8a9a11bc2f38777e400132a812a984908b3d2b87fc465b564045e79453c0666e3682a894c269551afe25286fcdb681cb50b260b4327b46c2d0699beca103965b0a218902eb4680c1b8c3ecb2011a396b0dca97d56aad231168fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6dff91091e8b36fd2a2c6b1094a8338ad540c8f53cab80d73e7dec3977452915b616d0f0bf9e842663cc477cdb5dc94579d6222d1b647ef4d358c5435d3d0799242b66818a683e8c5651b0b26ce4909f8656ff35cd7ffa1c5988074ffa32df093bcda32aee2003825593b545b44190787c4c8656d85cac293f615811ccb35eb0413f44b1722e0a182f09481712ac68e3c9d31085ea77946a54baa91c8ab8e814c5b94206070c0a6037bc02a292082018933a5ac32141180a6dc760c2c9aceb3b1a1505464150a732664aa51b02a721b63759379a638bbfd07ff9a7a84e071fda70200c61894a8891dacc375c120a35e0a4f296a02845477bc0484fb5bc539c3b8bea3ed2511d480b1dbe76c640622b67a1a8e000b954057322cc005f88284d6290a5d720e32b5f6cb6b992bc182d66a73b5019572867640343f267133b060545d4b2668b05e9d1ab7b1aa5c3287d9b08a79c9a5c9b6c93c5165c0e6b8c40d527ddfc01b3b88354c73f2544b5506c1e043100b4c399d2b6b8de81cc6271495b3c00893b744584ae83e300baa0531d191bf77015f28b2d95911cbb2a1c16265db900761c5333ae8074f387a97258cc0ecc391500083ef0922e00c692c9ab09abaa30c54984e918cfb332f96172ee1a0440d3b92175b386309475c92c25199d6fe75b1da41d0b86a68131a57fa839a1884f526948bfeccfac320509868235f05ca7b57952b3c5e65204f11c81c3077cb14c0b33633f9006b5d3c67f130c3d78038d7fb4934e4cbe8e3429a0c737ee48bc96849f360c83f2707bcc23432264728df21d4ac896e51a06a3b776ca7386d6072046abbb52c655df001b3007af2586b07cd7c81f38333784c2cf671cf7f3830a6144d4107fa40480852b3bb4f22bd2a33585e88e47c2b539dc099c298ee492cbd7d7a3bc5707c3c782d8a96a14701c352c1ff276a15762ab624c6d307a5b4dcb323faa9ddcd52289d60531d6a93be9c28cfc9ec3c489ddc6bd144a0458168e5b5686e92625325a8418565eb6fa0fb7619773356e92da33dc0b479b1a8c62c63fed955f18aa4cb7bb2578e2a42f9b41c60c45728c75064a68d4869db54845e8ca8dd38a5840b39b00fa9c4801107d0326eb24c7fd4612bd91275eca20f057c27e10b92e0b27c07a4d621751ef66307ce584708a5a58661838b56e2b2670ead04a9df7cf09bb8c83842dcfe4cfab4a83e75773e57b908feb46bf44013744bfb1d3cf98d34237b29207961d5d5cb43d6a49b17601743c86640ab9cd4a1786448c89e12adf884147e2cf091b66da57883cf36363611e04005be8376fe99c28fbc50092a034fb39abdcc97c6ae0565df82d4b59a947434d32938e8ee6687babba86236fced497c57554df73cdde43b7df119e86b92c407cccf98581bc62ba89228432a4922ee5c47be661dfb543ef26306f5301169a31b054cda1449cc2faaebd04c2b5823f58997defc48f6db37300b0c1c475a866b035639a5bdc4669cde9297d5ba8c1348792c8c2fdf3cd2125cdd51c7c3fd6ab6b31b8c529b84cb42dd8e2a48fb240c6b703c787590ecaa1f74044b5e295122c0a81c3a71322a2f4c9a33ea67d341a4426d60169acbdf19827759c144a271078582a33541bfa9367b757baef6890cff95d32d68f6c90338a20298b000e9144112dc22f4bb3117a6abf83b86b2b3b9cc244330b97392dfa3202ec7746d081f0a036360abad9d7028ab5bbde47403ca1a7c68a2c1679212ba707663ca412692049d45017f4993beaad79a990bfbb416d3072af8749f7f251dd51ba3c8b80cf34cc21ec923ee2a52ec3c981602c94d668bdc108154429508296805c156f05ae7908310fc176ba241cd35275b4c89e52786665e5798ca71a5eea5a721b51de6a78060a58f1a24da91666fdec925231c8c9f53d2fd270920092f29515dce0a8a2c6ca1e68bda6ea24b29424e22523a7d41773252e044356650aa5aa467b3cdb72be7700d268572d620279ca0668ab514243599de939a85990bc7cb640019bf8271efb7b1d32487b2e912e4f0267fbf197f1e3c4de63ad7455bbb2204db4c5995641892330c5b5140dcf0a8009d135a92352e97584c1f294e9548af9ec348e7408b448b85d234f6ed614834706a0c978ad9a08cc814953b8bbf2bcbd87071b597343629b3745d212111b7230ac9275c037d5e747afe60cbb9b439b06beaf537d6cc80bc1d1ca3db49f53c4a935a0226f37a85b058f32e307cbca9b7c62ba581b351ff5cafb198494d5abc4406e30932355754ab2a38232561319b0081b266b1fc714567305e0b27d3d6cb8457baf9242c598ac29520432fba3c3968c8e81078989380085178489eacb2c10c452079b1c33634df13d82b81da91ac85e43815f262c133075cffab454f50ad6c35410b295a5357e95fbb8a1d80964a40184a19618d2c0b7e13ab5828b60d461e10b41e3274363687cfc5849fe6badfa11821a31c2f724735ca1c4cb365b16ac43cbb24ec865a6dee75b7a6815500072065aaaf7b9af31214ad30ab984c57515a94a67b7391a37044cc22c9976851b19cd975a2c3be0539b213b9032928722029ac59231c90945a9bad4d39ebe623c08da1421d90fcd990bf8f8807b18c99a3799de3068a09912bcda3f5cab1089caa3eccc831f64bef79c538127b152f97946a264f4085c50299601043860d95832d15ed6f06051d12386559acfc5934cf4110827476b32af4498819e3ca252f28b48a96195f0a7c8e01a81d00c9063acc0954337d360b514906504ccce6a54bab7a3624130630a5f93c97af1c1a981b50eab54937251b9e1388842847ec6f4296870b51866c04458152fe3844cd879f335a7a1fc0b04094d2692cbb2f84f4a02b500d38fce69145dac4d0e4339d7978ef6e651c6110154046050b52bf29751c0778bd5e0409a1a2145bc87b1554b5ee209ed03ce01c251f4f39a67e09f2629a8024896c6c59f2e9a2e26523273e337b2b80760db1025f5b21931a82673be930ab5358381241acf46879650c208ce840b48041997500c8e6a89da2b59fc5bb6830c5c6cec510b13c74724a93ff7978c3a2b61f85f0b10ba790512d6422900db29d542ad96d8b6c0d954205a0d2c74810ec4469bf2b902811e5f5778a4190961853c777514319cab0cc90cc91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1d3cd2febe168b1ddf776b954e96085a7d475e3c8cbde68f7c80ffc9fa46b0d4311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = 9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +expected_public_key = d3bcbe7ec12d1af108849a2cea79be2da250f029382498919d670022f38be928a341b9783e164567aa87a9055fca176ab4870a2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463d51504bd6b62a44b0c0251afac229ea8359da303066531ee34451fcf796544125f933cd52f9b2a5e72e1a42a45ac9a80730376076cd57a289d5d97e4e1c5826757943471fa4ac0b7dcb737bf95f92f2b94f844b2b26297b2a44dd9013767b8b2cc7c1c8c83583e78f12e60050ea0e45e3453ea86166b70c21b0310059c58e684ade01b18f93440b0292dcacb6c9e3488e235f219c91914302d1495134e9c2b2a3acb6f4357c740aebb4534448bc482a07ace3b2211bc6cbfaa95ba4171f955ff915a1d5b13cf07184bbb230ce99c8a13264d3b98c0ab0986d62ca8e22286ec90029623d0f033bd4c13a26f08120f76aba45a904d01266520206e6a76697254b7120296820d0a0a29f662fb623c34eb282852832c044565860200222524b42cd2c8676cce763e28555b8e86a2c710b47d40a788513d140a41a65bea5cb054b73ca98c3061a39c6276a96269cca4597897c37b25f672c0f3766be5065a05b19b4cccb1a6771421b5cfdb7094c89c48c20cafe814d98d41bb5733aca166e044810704b1f9d632ed279275c802640d2bf754a99367b4a5fc959c8f309aa028ce21057fdd943de716e3f66b76660011ae354ec9475b4452932859d2dac38a853cb1edb09e04a367e02a92e89794a0c4ad866c65f3b4657492d0b575215e7926bf455686393ae7c507b9c8b9062c89b2310725baddeeb8a3079a7301b5be5f463f826ccbc8719e017550734812f1b18da724b99641e5406244a28aad89920731b387b934d02667e86b2051d35ad6820909924551430177f934650b61eae840d952b9f1f8b7e22ac6d6b005013439a01698644b2caf2b205044846d84075b715835a18c5df409f686a78dc675aee4944ecc806339b5cc8d8bc64d24bebf75a74207e60a37787c59c5e6875f61238fb43745e58bf3d2168c844b7c24c4ea2822f3abca76163a40a219d2798a2e1a8c606520c5a622653348a63980e61f52654b385575697d56c86abc5536ad67264a7c3813c1a1eb21442b1c0ff129f93810685a359fb13167e59b2df26c6068b641738b6ab82357c95c0cac43a21f867e005c96e1a4dd240975264606cf8ce8ff7bf0984770a282c969253189cb70cd3440a92c56319c9387733af98cfc8892f0e6736c6b44a0b952934071737a24a3400257e3c1690ec9f76726a327521afea4259d87eb6978d4c77afafb1b9be81cc4ce1197592bc26908c469863aacb89b13b231fcc9669b8accb2a4a61f641ca173dbd2a1494519b77acb0dedc284f068e5ff73bfa9109c1fcbf34b15f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f4319997fe1bdceb9513c2ab34691292bb961ddd202398b99c8f1aeeed7302262359be5b1e53689103246a473549b8274a1753721c621a0f468a6a9080a007287731bb8d99360689fe616c707a9c0c04c919b05a5add406a7d1aaf9d675922439e4224300b18e5d2966a6104cbc5a43786584ec877198dc8317753c6f0109a11c3808a50693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d4f05e20c2cf9102593ce45770da720531cbc50552f1b097a5a96bf291895ad9c0fcbc6a462068eb2ca7f65217f0678d0e25c447161cbd9029ec24845c5c1b2b7832ae41172efb8fabe6543ae3bbde44a0b9f926b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6c8117091523209ca8dd342e3bbc0e8cca579c603daea4e11b06bcdd5be898b825452a28d15261bf9abe00a7eca0474ac4c92b0938aa2a00854f3a665ea56169b3c572187ec88945d6c9637b4a8f91249b8614e9647760eb68d2c08c21f390e36370cf30ca0bf0b5c48f7287c822026e30850754b51682a0ec016f4fa0773b642d4c5481502bc9f023ddffb199fd241f3c977a9522de7f61eef4b0ad3166515697ec9ec5ea87796dc6a24da4939e8b5af7fb191f861abd3850e4ecb1f8b819ddfe605ed6a113ae4075ba67414b4690f59b2a6121928eb21c4d5cbbb4551d2c00fde22b537522663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_private_key = 2220bfa6a447db5013ed5811b45742b6e95c723a35851518e04b1b619c5607944c341a1aca4c0eb297bfe3990d514aba3de30867d646cd76a1ec1176f1e84ee60704b0e04366e27ed0f321bbf42322f5289f5167435b880851b48de717e40a1b56387d4705815701bc2b80c55f33b3c20244e0e27ffcf43c457a3674000a4404b4157cbefa05c54f50021684059939a3aa088dbba13be56047df450afe33c8742abb0cf48e0b1c24e8719eece41ec4a3254836b4e45b4eebbb43d398a813bccc0c42cc4e437050740c892b657765b252943896325e3f4c45887452847aa315ba8c811b39254a5c3ee64f65823fcf2a92e3198d2981289e021530aa4cbd210fabf51094392e25e755d778a02ca145fff47165711ab9397a0f9b3def26bd0e5143c23a815c8582976521d63bc74d8b42b95280cdc77de3528628862f44d475f49ac204c87d2647414a4a136a094b7fb923bfd3496b187592e81b8168bdffd9522f60bc37052fc579cb3f7a398dd677ba14a3fca1248057a59a58531b7a1f1773735a27612520b03121390cf624d46927cec7c7d00ab13dc2ba6445236bc68642ec9659d7bba40aa692c40794bc4bf5f13fbb617e711a54bd825329ac6a9af2a88a54a600c0cd6754b4a3accadb397cabf2af41463c00512d6d206d011baf6d833e4abb8dfbf736df8036278a8125389c3b99940881760ac150967464483242dd52358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0db0edda213302677fb73c493a349704333278b201b6baa8315731a348ded27283dbaa05e057c26c35d68a5252f1715337a1543895dfa4c395f9909b7b1283b450b71730292c32dcffca05221b14849aa5f94888e2a3fd33cab3b380f8093742247ac27012e8d7a6b8702983dfba43601677679568a8051925133fbf6550dc318e387c3e3176ec9c3cad6a739c6ba5b72fa587f000ca8f06eea003cd05970652b0f3f92b8bd4aa1570b02cab21d2bd0a9937a499943ce285b32706589c11cb662461444629f5c755b4a09805dd5659127bdcf5466270a5cb6328fdd0583e701aa98d34095506284b63a6f7b39d0b31fedc43e20e4bcb39b99d82515e041627fc5402290be758a062822c26b750463141d9de8793b385f556a3a3f74bd8ab61f69304ac4082e08f2cd05e5beade17d2c87b9535a084a6b0547389d08f548030b1dda0137d170039e082c5583bc83695aff0898f7e19e54204582989556b924df35a00c518ab95cbb466b5ba0d8aef007a8294294870902e74152832365fdb79508b69e45484139b4342df8c391864b80e807b9dc8ddcd4463fd1a986986b81a62d79aa9565308ac1471f09d09a23f24e4ee5522b00265770674c61348fdb3bfdd539994b20ff22b210162961b56dba538252610fa607372db1317497b85307b61d890a62b90e4dd37246763dc6093af5f4cd0dc20081ba4ce2d6bbdc969580607022c590a1687004b0730af71c60590d1a6b2a5e51c742d2cbbaa826600055f4811287a062da1696a22808507aac327a9194c5c6d49c823557100c158e60b845af953539a855d217c5a77599b1783f7488aa85f222df73b837e4b8d1006a8fd6b5b06083a3884f67e9cb7e962cd3b8a8cf22951f74aecbea2d599c533de42a0ccb5e94439144551f5d839215d9021fecbd03d8b856d66d37331997a77f46f067a83727bb0ca6b3746f7ca6a233ea575d908775c5a7ea497917b17b51ec8d58350aacc1cccad921ca06061e82067fc9215c5a3e75b861491771196836ba56c99b25cc5ac10008730518311fcb7a2ed14972b72533c7c890d83a5e34f75e0065021830386b1456da6a6cca5a474c3790850a71c0e84bc7125fe21a9fab396b37287a106baee569a7adf0845b49b096f689ba245707647e7fd70efa020a342c45335ca9e0809982ecbc38f55d4f9a9c36578198929eb8290e55848d04ab7c952513ead8484d44cf46f6959717b0c009938917ad916909dbc764746c3cc612b5b72b4f16049140b5c261e29b326716e401470e7b6598ac37c7c57dd3d47d548377a4939a0a7886eb7780c667b4339873be5ac23765a05deca7b264978b14952920ac0880a274d3a5ffc825b9a891df5560938b9fba313e05e782691bb9c0488a7838a4b4cc6cd3bcbe7ec12d1af108849a2cea79be2da250f029382498919d670022f38be928a341b9783e164567aa87a9055fca176ab4870a2c4a68473c737b9a778467855c1c4186438a65333795f5a5b25641f86b9f5d4c682b1a878ea7463d51504bd6b62a44b0c0251afac229ea8359da303066531ee34451fcf796544125f933cd52f9b2a5e72e1a42a45ac9a80730376076cd57a289d5d97e4e1c5826757943471fa4ac0b7dcb737bf95f92f2b94f844b2b26297b2a44dd9013767b8b2cc7c1c8c83583e78f12e60050ea0e45e3453ea86166b70c21b0310059c58e684ade01b18f93440b0292dcacb6c9e3488e235f219c91914302d1495134e9c2b2a3acb6f4357c740aebb4534448bc482a07ace3b2211bc6cbfaa95ba4171f955ff915a1d5b13cf07184bbb230ce99c8a13264d3b98c0ab0986d62ca8e22286ec90029623d0f033bd4c13a26f08120f76aba45a904d01266520206e6a76697254b7120296820d0a0a29f662fb623c34eb282852832c044565860200222524b42cd2c8676cce763e28555b8e86a2c710b47d40a788513d140a41a65bea5cb054b73ca98c3061a39c6276a96269cca4597897c37b25f672c0f3766be5065a05b19b4cccb1a6771421b5cfdb7094c89c48c20cafe814d98d41bb5733aca166e044810704b1f9d632ed279275c802640d2bf754a99367b4a5fc959c8f309aa028ce21057fdd943de716e3f66b76660011ae354ec9475b4452932859d2dac38a853cb1edb09e04a367e02a92e89794a0c4ad866c65f3b4657492d0b575215e7926bf455686393ae7c507b9c8b9062c89b2310725baddeeb8a3079a7301b5be5f463f826ccbc8719e017550734812f1b18da724b99641e5406244a28aad89920731b387b934d02667e86b2051d35ad6820909924551430177f934650b61eae840d952b9f1f8b7e22ac6d6b005013439a01698644b2caf2b205044846d84075b715835a18c5df409f686a78dc675aee4944ecc806339b5cc8d8bc64d24bebf75a74207e60a37787c59c5e6875f61238fb43745e58bf3d2168c844b7c24c4ea2822f3abca76163a40a219d2798a2e1a8c606520c5a622653348a63980e61f52654b385575697d56c86abc5536ad67264a7c3813c1a1eb21442b1c0ff129f93810685a359fb13167e59b2df26c6068b641738b6ab82357c95c0cac43a21f867e005c96e1a4dd240975264606cf8ce8ff7bf0984770a282c969253189cb70cd3440a92c56319c9387733af98cfc8892f0e6736c6b44a0b952934071737a24a3400257e3c1690ec9f76726a327521afea4259d87eb6978d4c77afafb1b9be81cc4ce1197592bc26908c469863aacb89b13b231fcc9669b8accb2a4a61f641ca173dbd2a1494519b77acb0dedc284f068e5ff73bfa9109c1fcbf34b15f3c78c19a6b6eb693b64155b5e4e77d67547d35b56a0ecb7eef98798af94f4319997fe1bdceb9513c2ab34691292bb961ddd202398b99c8f1aeeed7302262359be5b1e53689103246a473549b8274a1753721c621a0f468a6a9080a007287731bb8d99360689fe616c707a9c0c04c919b05a5add406a7d1aaf9d675922439e4224300b18e5d2966a6104cbc5a43786584ec877198dc8317753c6f0109a11c3808a50693a55ca75b5f75e74d475690af046e535aa79c7b4a1606a6d4f05e20c2cf9102593ce45770da720531cbc50552f1b097a5a96bf291895ad9c0fcbc6a462068eb2ca7f65217f0678d0e25c447161cbd9029ec24845c5c1b2b7832ae41172efb8fabe6543ae3bbde44a0b9f926b1538cdb6685eb244caba69798298b8fc38fdeab5043a567c6c8117091523209ca8dd342e3bbc0e8cca579c603daea4e11b06bcdd5be898b825452a28d15261bf9abe00a7eca0474ac4c92b0938aa2a00854f3a665ea56169b3c572187ec88945d6c9637b4a8f91249b8614e9647760eb68d2c08c21f390e36370cf30ca0bf0b5c48f7287c822026e30850754b51682a0ec016f4fa0773b642d4c5481502bc9f023ddffb199fd241f3c977a9522de7f61eef4b0ad3166515697ec9ec5ea87796dc6a24da4939e8b5af7fb191f861abd3850e4ecb1f8b819ddfe605ed6a113ae4075ba67414b4690f59b2a6121928eb21c4d5cbbb4551d2c00fde22b537522663745b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef99499c1b006a0ec2c299c41c3f728c3bb7848957fb2bbbcd05b65233b89a2b1b16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +expected_public_key = 60c80e77b5c6ccfab6f463a63c069276c9321d8c961802a956f0b8f41307a73b5b4ea33828d1bab555c02616115f890ae7b1c5e6061a484825a448452bb26fb9b13d9bc002e6798d54238125477bc01babe0ec7753fc8c8c959916f16206a7ca31c7b121724e05bb5d71c648fea759a5d2b58a257e728230c2ea779ec4c55f2319cbf9cffeeb1f285a9fb0d4a391386ce69bbb6e37a548246d1061494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e53a2766642992881a2f1c8b7454586cb3822c125af4d70b15ccc546843100b1443e365cf31680656879f00e640692b94361286104c79af9c1cb2b98f01e3b9480c5b0af0988dc7bebb33bb3ad87cdbe09828a25f17fb323bd17a11ab961c236eeab89cd7c3030f4b437c09aec5f461afe64e1939c93081b44c8440f7b070fe982c16ccbc99fb0a8332739b641b326cc689c51c7ee33003a277c41c2a05676620eb9806ea6f53c2060f13a75ff67b7d1b4229443ecc4023c84293f3cc58c60a1bc00a3d1ad31aa88aa6d2923643585d39e16e5c8bc5e650a578d60584bc24c2fa2aad7b2cd9c99ffee6033353b60f506b95927dad7ab997868119b5976f561007b51aca6b36b08b03ae40a9dcdc19ffb776304bbe7d3aca167753634969cc57c48704a19a22416d2cb658e75ac2d428aaf9a13e6693e4d94df1f2a6559a4fdd16354c77129d32bdc3fa136e180d66842fd2a9540c63ae7412acb67b788936066af5b7fc44409a77a27017c9b883b705caa371b831c7195abc01530a97728708661d343cbca7ab7268b36294b2efd96f87a298092684b02569ab5911f4825826362414fa2f2b955f6a318bfeb18b12d058e4926ca973248d162164acb5b7a8a7641c9557a8a0fab208ac2744810397cc049ef46756e4d14a884745e73454e1d675c3743a5dc2546c424735813ab05353cf65b604ea3e44d8828c7a3ac9851848090b0639934d9b19ca7630844003a944238876966a62a87218714a4b3f89638a064846fc4163d03341840091d75b25dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae58012f2c3938c40cfe1281aa439486d5791e745892eb36905cb142a5c718f456b74ab213f4ac50cc000cfac943c60c3de626080b525c52051ea231f18dc126eb1c6fb76232d5722cee0c9e458c09a38c35ad64959bc64ff252358a5cb1b07384288b457ab15651935a99072f12336e14882a2d0b6f918933ca0574b49b214ba4018ca4b1373cc0f007b683a9a44f842610106de16cf202bcf0896c9506855bb4849beb06289b72041c75512e152183242a5162678d10d870aa888e218ae969c13b024729c7acd818971e598e495902ce92d29c73d355bc44eb544ac760c0cd58ad8157ff242963ae3cab5bc37b9c78ede033c210c59e20245fdcb51f7ca9588359e2264118ce4057dd7c6ade4bffbcbcba5f9433314cbea9309a0d86a15bb6f753abdc47149f6bb0eb339734aa1638fcc633244559a08af3c4b15e6bc8cdc63398165acb51925c7141cea32773fe5b0a64075d66c653e750cf42866255a9bf7d4b66c488f774193ce9b35ce52a164bbcc41f7b6779a9b35127ba7087a4b673096bba4048410778b18270674af334bb92475ce2787bf9a08b587a6d48845e44c6e04a254425ccb59b5972fb3a57cdb02f5100d45b43b76140c6047bc5ee59fb6e012660138d7c107285a2d461b20f1d49e1c206ffb28be65e26154a64df73358dbb49b77258fc45a15b9a80144099be67b76fd60b7e01518074b766211132e157efd507b5970c862d5cb870751da46ae460416eed595a74724152ba84229905880cb682cbe477995437125fcc23677c25fde14533c6aac694206aec917162b4efb61a1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d7872a694881916016c1af8abe353cd1ae2263cf417c013cf46212b3d5720af335d40b646a794ae602b5345300e30f4812e295f3cf07c2117cef1c591cb9a350ffcb718c64b0d76165e9a719ffb75f46b861f968eead3373c3cbcd6a983c9270fee433b2970b6f0947b8ce46fcad6518d5042d109ba53d324b9f657182bb110961e96a8b34c5a4b808840de8b71d0d87a510944a9973df9a900d9a6c272a61bee2200b4c80aa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_private_key = 7934a9fabc835bf9a77bb807332251daa00876e5500d2c59f07485ed01bc934911a336acde5527dd166476ca1d1aa558cd88cd7bd17ce1791958e851991867c0525c9472a953c8b04a730e2e132c6c26811cb86f3234229f4caa2aeacd2e3c840e97b8f1805b94d7317b08354bcab64887a4e6a98ffd90a7544562ceabbcce6489c6e8534119c9589c405d7a96de3230094a459549b6f37078f2c01fc9080f049464b0a969eb742419147c8b39b8065a769d400a17bb25de51a699b69d54ba460d33ac6a6965916829b7a578d0b24bff786cef9963bf961adcc20f9a0cb1c159865a344a0e36879c67852df50aca08a46e72a4a70c027ce283de5bcb219808f2635bd7540915c5485ab70358cb017882b12acb4426b22b02605873f2bd0da59a658075136cbe15418cca0a11386aad43a52e3c5ac97f36bc7f648808c260643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc6007317a165e6a1657d0277c1e683beccc956d973c7624e959724ff9275c1aa2bb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab3709d20601c2a943d5bfbb3d384a7e83a7793905301b1704cf49992077b19f0204f3394717c9ab9a173113004fd325edb797a30155d0d2a1e4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9325f1705613705628458bd525fb333087cb4b967a61a994cbefc504d18c1b8a62898af32bc454a57e264722897d5dc71e32c2495ca857e1a234ae61c77083ba9b780342d7cfdff8b7ec1257b79cad017113a3238510c5683c3a8c396986ed392b0122c16e34a7249691ea7a931c44087fa1731746c1f3855bc72414fe3484d85b5e2586b6231b4bcf27831ea7b57070a815795f43e90b2112b235f5959ea253db76192bcb11d4e16399d40c5dc0a15d98c3b3b0289f07839f7738aba3281d45aa0a9ca1d349a64e79246c2c7770227f1e1cc74db8ab7ea7b0e60a9dc0e45443b30ca656cd6a8897ab105bda51b02179936f04374554a52992710f2a70972479462a2859736c2fe4359a474939ac3531b2905f90bc38860b5615abfb1a1327814c01048bb93c9725c7c3b0547921975766a97e29d529e4d8a090c36820db0fec33277cc679cd4a51f7ca05f204bff20acf63ec403ac7ccab951a8ec166c545abfce8734833274f724e77e68137967da75515e3c270ce79838839721bf3a14c952085071d6b3a555ce62d96e7736a583f44f726aeb921caa340d4bb788d63645deb2621629dff8a2c51d23bfee95caa7756f1884a0cd263039c37f7415e83d4908507c1b17a7308cb329d829c86953422b8b2f1786a4b86b980751255339258572a02ab22ad845632f859eac223e1245ac3533d359246316a3cc1ac58b4e6386592859547171ce05dd7a76bf8e93901eb7f40114175ac45e0b35109ac57be844c52d31a7ba60a24f30ef0e45581242c02e020ec86af106836b3dba8071bb8e8574fdf208100982e55f4b0dca72521440a2aea68c57b2039d14b21a56274972eccac7eed41c4b26cbe2c973507f1cdf4e618077406ccd3c8c5118545178351522485730b1a1ca7971b01766b914e83520bcc82131c5e5a632f88ea070ef636d02752ca06b94df20de6f757021c1fe4e4883f123d097993f1959ed8076c0491191b0a05774c5a2d6ab94eab91b1cbbab07b8027fb57730820f19609136131833bad67d888aa29bd69169d8957a5cb8c3a14b54d3f78154108904ef15d1f73ca9a635fe1231ea9e18cf3a473fe7492a3636d85b70ea43a7aa68c4f3f24c2a2e88f2bf5568d790e51122a27aa41246422ea78bebfeb6038db3ff65881bce84496e65d82f5c318c0217b5b5e299b570b038f740238a264b00da749cea6ae22bba8bc314552132894d79d23e73c492857d22a6f64aa160c774f8b24a8b14ca805619231347463a22f06ac2a96660edadc1bd767524600ba35789c0896897f2bb1f0c88c0b875952c9a352ac4d78b69c55687015544066463da8e0b1a3a8481d6bc89ff3b9590b94e03aacf4c0c12e404cd51aaf3d696c54158101015a550a455a28042c73627c7a414938636481647c30c90b6073b1582e31c275cb12755a287f967a7c6c377aacfabb57422510ca4505128b60c80e77b5c6ccfab6f463a63c069276c9321d8c961802a956f0b8f41307a73b5b4ea33828d1bab555c02616115f890ae7b1c5e6061a484825a448452bb26fb9b13d9bc002e6798d54238125477bc01babe0ec7753fc8c8c959916f16206a7ca31c7b121724e05bb5d71c648fea759a5d2b58a257e728230c2ea779ec4c55f2319cbf9cffeeb1f285a9fb0d4a391386ce69bbb6e37a548246d1061494e8766fd96ccfde9ba6636cc3b4858097c7cd6b83e53a2766642992881a2f1c8b7454586cb3822c125af4d70b15ccc546843100b1443e365cf31680656879f00e640692b94361286104c79af9c1cb2b98f01e3b9480c5b0af0988dc7bebb33bb3ad87cdbe09828a25f17fb323bd17a11ab961c236eeab89cd7c3030f4b437c09aec5f461afe64e1939c93081b44c8440f7b070fe982c16ccbc99fb0a8332739b641b326cc689c51c7ee33003a277c41c2a05676620eb9806ea6f53c2060f13a75ff67b7d1b4229443ecc4023c84293f3cc58c60a1bc00a3d1ad31aa88aa6d2923643585d39e16e5c8bc5e650a578d60584bc24c2fa2aad7b2cd9c99ffee6033353b60f506b95927dad7ab997868119b5976f561007b51aca6b36b08b03ae40a9dcdc19ffb776304bbe7d3aca167753634969cc57c48704a19a22416d2cb658e75ac2d428aaf9a13e6693e4d94df1f2a6559a4fdd16354c77129d32bdc3fa136e180d66842fd2a9540c63ae7412acb67b788936066af5b7fc44409a77a27017c9b883b705caa371b831c7195abc01530a97728708661d343cbca7ab7268b36294b2efd96f87a298092684b02569ab5911f4825826362414fa2f2b955f6a318bfeb18b12d058e4926ca973248d162164acb5b7a8a7641c9557a8a0fab208ac2744810397cc049ef46756e4d14a884745e73454e1d675c3743a5dc2546c424735813ab05353cf65b604ea3e44d8828c7a3ac9851848090b0639934d9b19ca7630844003a944238876966a62a87218714a4b3f89638a064846fc4163d03341840091d75b25dc9a7fcbbca04664b218f4b525f45a4723417e3597f9b99ae58012f2c3938c40cfe1281aa439486d5791e745892eb36905cb142a5c718f456b74ab213f4ac50cc000cfac943c60c3de626080b525c52051ea231f18dc126eb1c6fb76232d5722cee0c9e458c09a38c35ad64959bc64ff252358a5cb1b07384288b457ab15651935a99072f12336e14882a2d0b6f918933ca0574b49b214ba4018ca4b1373cc0f007b683a9a44f842610106de16cf202bcf0896c9506855bb4849beb06289b72041c75512e152183242a5162678d10d870aa888e218ae969c13b024729c7acd818971e598e495902ce92d29c73d355bc44eb544ac760c0cd58ad8157ff242963ae3cab5bc37b9c78ede033c210c59e20245fdcb51f7ca9588359e2264118ce4057dd7c6ade4bffbcbcba5f9433314cbea9309a0d86a15bb6f753abdc47149f6bb0eb339734aa1638fcc633244559a08af3c4b15e6bc8cdc63398165acb51925c7141cea32773fe5b0a64075d66c653e750cf42866255a9bf7d4b66c488f774193ce9b35ce52a164bbcc41f7b6779a9b35127ba7087a4b673096bba4048410778b18270674af334bb92475ce2787bf9a08b587a6d48845e44c6e04a254425ccb59b5972fb3a57cdb02f5100d45b43b76140c6047bc5ee59fb6e012660138d7c107285a2d461b20f1d49e1c206ffb28be65e26154a64df73358dbb49b77258fc45a15b9a80144099be67b76fd60b7e01518074b766211132e157efd507b5970c862d5cb870751da46ae460416eed595a74724152ba84229905880cb682cbe477995437125fcc23677c25fde14533c6aac694206aec917162b4efb61a1bd7c7dd7dca9bd07341438c7893ca4fc8ca4c337a5d7eb9a030b7d7872a694881916016c1af8abe353cd1ae2263cf417c013cf46212b3d5720af335d40b646a794ae602b5345300e30f4812e295f3cf07c2117cef1c591cb9a350ffcb718c64b0d76165e9a719ffb75f46b861f968eead3373c3cbcd6a983c9270fee433b2970b6f0947b8ce46fcad6518d5042d109ba53d324b9f657182bb110961e96a8b34c5a4b808840de8b71d0d87a510944a9973df9a900d9a6c272a61bee2200b4c80aa1dc7681b837eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516aa14ea531df0a7f93225de1c75ace0d2692bc750b1b538cfd0d860ae9c5a8c13faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +expected_public_key = 9d9171d1fc6308f0c7b2015fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff140f77a87e44960e6fc73cf170991bc57fde0c406e432253a2aee4b0beb4d26e0194601fa576cd89a5bca45e690833592b874d3b3cf303475f1140a0fab6129296c51b4a5b30650b8c26b5e67100837d011c2aa7881bfed806f308bf2f99118565cc85323410abc6e34520b818b49b6369dca3a1ac2776f75142b84c76a43223fe2b7f78544191ab4f0b9316c3b4495514118c63c1f9691ed6ec30670945da0a92052a7d2d11c4e0f8be14b867d4708f6fb4569b6081ba685c78e2c835e0bc29bb416db14cfdf3c98e8a4aa7161859e2cf74277a4c4731224c0649a01abcf92ea723784ffc290775282c256d433a64b705899398aca7e084ab6958c801b27fe8b39ff4bfbb1aac410421c50aa911706790d3c350b6126cf9242e33a359e21e4b72561f1368c3d2265b710bf0d6acee3a5286f51dbf16c471327612ebafcbcc5e22a5b5196a06336968976a9308c075816727997b7d52e34b648b8bdbf229aa4925b3e5167dd1caf619bf0d620540f29f6e77091c4b430e708d01ec9e2e0ca44e766c7643084af17722488f4786a720ec6dc4765e0f558a7a9c449f04333476262d65c4ba175a0e2bb29b524f8465a73436bdf6494578020a425149f3cc0c9b474d5eea98ab529aa1c97a84b54c064c8902153703618e5b99122d4402681a9c72258137b94091382888b4636ca983c79a944a4ba0169a730f7401d58196dc193742fc4d20eca71ad359987086aba19ffb05c0e09a0a8581844774b12beb3692e055df16b67706902d625590037997a3beb105931afa84b5fa389fe2b2bb2b5f521169f18b012d17a5ad203e2508958954b8fda5956bda2126503f34c571457056b333c9dd265bd9d4a9ea601620454bf020120d5a0e99f837cce92e20865dd7870a1ae12f1da8b369c814fcf63a9fd830c4827f6b151449879c4ba9691e68a02aeb89f362a9bd57909c3ac1e064780fa1c74ba21daa4b6684bb64eb108987b18be7683924e3202d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e51222c4df502c8415089255e8a095efaa822b892b2a0a17a146216282991833338553c8bb4947d892923010711084a19435b5c3f6a6af7f89457ac8a5ea4679fa2921692c8af459ad8cb22ec187dffc3425d88b6396cb7fb627f5fc718752658a5fc92539668c7327b90b26572fa8bfcf705f11422382079e2333af6b51e65310751343764bcaf5a981a260109986b5c29d2691f4a981d391175a21e16a13dd2501f5a256bb86169c63ba737296a5bacc65781b8ce07b4b8f28b173b42f802baf5f235bc06c9d752351980a72b52250269ad66a098fc9b68ad57c698a014b9d1c278f3559b361e3b8ba2d690c5380765de0b2d0e3c63792c7f9c8122b297bb8cb8381d6780505c253399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa5529fd8cb5215893bec6a64201629031b16a8957623b0619b33c6b90c78f4e21f8ffb94d1a6648d330d91096bc87093417b1ba6e14eef17ccf3923a84328b5b60adca0c4348d9198262b27fe56eff73566bb5123d7ca987a26fe9a00d41a2405fe31af48baa3a5249e4c6a638985669d576dc7c9ba575380e959ef93c2dc5dc15ca87cf3f98675eaa87eb5a51cc3450b946b810d05d94a815376868c5d9594fd02891637ff517a6597a1272b7c9933c544793ad167b1537b478ee3a20c8b874f5fc95aa46851fb1610453583b23c280838573770609344f14c4cc1da33720b3257a53a8e58c1c0ee500a3e4781a2cafea727ff3b86ccbeb9fb63b0f215ab297ecb1485589766ca828332942eb9c4037bd76aa1fd24160febb8dc499c486a6125c137b77597317f06323c901ecb7b17b75180c71c6b1646751f2522f1a7d13cb7dbe0ab46385aa94b84acb565f32470fe75b7f9c876287f2ad5b0b52e4b5aac9a43eb17b207943ace482b46123652f7460cc64427710603a8307ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc37591bc1a926d57c0ddb5b52024ac3861785b6134ad8c067c5e9a47ea96f57b40426697e12846bfde94af1b27ae4305edb932b79ab745abcc265b8c7a37063ddbcc972c26864269ee557785690ae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_private_key = 46f47850e2b9aa4a6d209125be58806002c278a6295da7a4ffe85551529f17d83b358b243f2a622f353eb6138cc6380f8ad3340d7575e865a6cfd34bf473a3da8b9fc961cd921452d09b3209d041d6612576c573b08422715160b891a3370268468078f5464d7e5b84b3a3793f0c7cb2a0a13df37b9763cfbf054c768b1e65a00e8366b406251f812c5d428853d0e00f7bd58a8e348275461c1336c2ac6a39783a35d849aa9a847f37f50be0b95f617bc7adb28c0506c16ea3ce89aaa28a9252f0e228d0fca732289d05d9395133a82d8cb76db2023924273b39cb52b5a846f338b96c5b6f3acb41c7265a0c5b13094231f05943d58875ba7c2a6889f16107d325ad1b810a0b3c9e8928169d440194bbb90f771796856f9878158a432eff742fbfd5acaf59521e361f448c0bebd805a1b4435d0761d0448d83e1201a506a0b0a4980172d05e88d7d87b42054680cda74a386027aa4c3c5193fb1a893bec2722d55ab9b840d99cc81408153b383345192649eb99825bb4b1957326c4791a2722951c0ab67472f4841c20c23926c3c331f24c360e81977c2791ff3171c2c489b68c923b65d8ee6bd2d510e6ae97fb771bab401bc1a42935f38a0fd43ae2f8a24d8fc3f6e15c2c6bc800b73ccd8e91c592452484b44e6b2a624881064526182950349c78c7d58180b1676b5191eb6065c50596232b9566e4b8f0635a7d71927f8eb8572e62d57996ddf66cfed2147dc3451e95c034d6b9145bc0d30c915d66b1cce367406212f8bb40755091c9cb0306a490ef5336e21f82c1b7b6ccc8980da28a348815112f00c57362eb163a36e016d60f020bd12b6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f64e07ee6e6a300dd1cbbc840af561746d279beaa71dea5318aa3cb3c4c63c4a91e0fb60d6dd6abf1fb24d1b078de9413f1b0bfd8916577c4cc9e0b0c332625a5fb705e94babbe0659e022234586529a194012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f22a0acf114b90829b43112fdd617089c8b9d872b70d7027d74402b65058347b56074ba33fb91998e5a559d46622f5423808c8236317767a32e4772ae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abcff1be00c7bbc5b5b25a0c1d853424123c98fb330318432d324bbc7330342224baff909849d65e1d08a77e07d07cf16ce6f64fc71374eefb66bf9c742e518f2e30c480f82652b81c4ce7bf42593b990980d94062f96a7178258f31e2b90e86241c04b7b44057bf4700a040b6c0b08e4e8a6bf1cb1eef738f51ca9beb9c19b94b1cc623704a6c2455009f48b4cdd0f4a5d7f06320457670db92c7a4371743593600022da4600c56296d336a52e98888818ca10282d4767010a7abdf81bb6752048b5b163da385d7c5cb134108ecb03398500c1612a1bd563b21a0bc7b94c9719a75bf3b3e02143bf04a7e3d9b0070c4b449cb9594a1a8bbf871e595178bbcb611b466a8677905443abfa1601a9664c5f54f36dcc1ddf35381f586b4aa4566c02be610186df8493a30479f4c72aaf049a6666e806b13fd77c3b738721f81218b48984ef374babc0156f94ed581133c180c9cd067dce401739190ca80cc8d441b78a986834033abe3432f863cba79cbbacc2e5463bc3bd1b0f1307140d56a0e0768691747143721c76847dce7b86337a584a146da0c664d904441441bce3276c7d8906bd336ee07452626853098444339824dc5a82d0b515164882c99851c189de092cc955c9fc53c041471c4e4f7cc8d16aa74d83396d88264314912632e87f68f36ac0abbe568f1a5bea9e807c21a57e7103b4ffbccd02a5fe3774e54b40e6063af2cd48c73e82d1d2cc893c35434472e2a892a05d566b890369f996dbbd9c1d8d542d29021d2f4619d89826dc45f4212bd2e607e92f80b75bc9cd8a803ae3a749f539165cb2bacaa005a2787daca403c83baa258b7e8061ae4d11b5d255b12d6cfc4650af458a4b0a37c69cc8774bc4f51979a120292ec6c8d7193c5b52021b452807aa78c2c26cf4e4c2fe6236d2f3ccf5273bd3dfa2653498b5b681e18996098cb3f593947fed05a927223b27619eb484bac5561bc7ca8a112136501a461538b23d07b47b3ae35420d9d9171d1fc6308f0c7b2015fbe1aa7c3084afd14382ccb962cc7b9ce97a4ff140f77a87e44960e6fc73cf170991bc57fde0c406e432253a2aee4b0beb4d26e0194601fa576cd89a5bca45e690833592b874d3b3cf303475f1140a0fab6129296c51b4a5b30650b8c26b5e67100837d011c2aa7881bfed806f308bf2f99118565cc85323410abc6e34520b818b49b6369dca3a1ac2776f75142b84c76a43223fe2b7f78544191ab4f0b9316c3b4495514118c63c1f9691ed6ec30670945da0a92052a7d2d11c4e0f8be14b867d4708f6fb4569b6081ba685c78e2c835e0bc29bb416db14cfdf3c98e8a4aa7161859e2cf74277a4c4731224c0649a01abcf92ea723784ffc290775282c256d433a64b705899398aca7e084ab6958c801b27fe8b39ff4bfbb1aac410421c50aa911706790d3c350b6126cf9242e33a359e21e4b72561f1368c3d2265b710bf0d6acee3a5286f51dbf16c471327612ebafcbcc5e22a5b5196a06336968976a9308c075816727997b7d52e34b648b8bdbf229aa4925b3e5167dd1caf619bf0d620540f29f6e77091c4b430e708d01ec9e2e0ca44e766c7643084af17722488f4786a720ec6dc4765e0f558a7a9c449f04333476262d65c4ba175a0e2bb29b524f8465a73436bdf6494578020a425149f3cc0c9b474d5eea98ab529aa1c97a84b54c064c8902153703618e5b99122d4402681a9c72258137b94091382888b4636ca983c79a944a4ba0169a730f7401d58196dc193742fc4d20eca71ad359987086aba19ffb05c0e09a0a8581844774b12beb3692e055df16b67706902d625590037997a3beb105931afa84b5fa389fe2b2bb2b5f521169f18b012d17a5ad203e2508958954b8fda5956bda2126503f34c571457056b333c9dd265bd9d4a9ea601620454bf020120d5a0e99f837cce92e20865dd7870a1ae12f1da8b369c814fcf63a9fd830c4827f6b151449879c4ba9691e68a02aeb89f362a9bd57909c3ac1e064780fa1c74ba21daa4b6684bb64eb108987b18be7683924e3202d45a5c4f3b2aed5666a8ca54b48c32bc55b60064d27b53e51222c4df502c8415089255e8a095efaa822b892b2a0a17a146216282991833338553c8bb4947d892923010711084a19435b5c3f6a6af7f89457ac8a5ea4679fa2921692c8af459ad8cb22ec187dffc3425d88b6396cb7fb627f5fc718752658a5fc92539668c7327b90b26572fa8bfcf705f11422382079e2333af6b51e65310751343764bcaf5a981a260109986b5c29d2691f4a981d391175a21e16a13dd2501f5a256bb86169c63ba737296a5bacc65781b8ce07b4b8f28b173b42f802baf5f235bc06c9d752351980a72b52250269ad66a098fc9b68ad57c698a014b9d1c278f3559b361e3b8ba2d690c5380765de0b2d0e3c63792c7f9c8122b297bb8cb8381d6780505c253399c61d4445e244b4669a3cf1cb7dc227ce9655a9ea275aa5529fd8cb5215893bec6a64201629031b16a8957623b0619b33c6b90c78f4e21f8ffb94d1a6648d330d91096bc87093417b1ba6e14eef17ccf3923a84328b5b60adca0c4348d9198262b27fe56eff73566bb5123d7ca987a26fe9a00d41a2405fe31af48baa3a5249e4c6a638985669d576dc7c9ba575380e959ef93c2dc5dc15ca87cf3f98675eaa87eb5a51cc3450b946b810d05d94a815376868c5d9594fd02891637ff517a6597a1272b7c9933c544793ad167b1537b478ee3a20c8b874f5fc95aa46851fb1610453583b23c280838573770609344f14c4cc1da33720b3257a53a8e58c1c0ee500a3e4781a2cafea727ff3b86ccbeb9fb63b0f215ab297ecb1485589766ca828332942eb9c4037bd76aa1fd24160febb8dc499c486a6125c137b77597317f06323c901ecb7b17b75180c71c6b1646751f2522f1a7d13cb7dbe0ab46385aa94b84acb565f32470fe75b7f9c876287f2ad5b0b52e4b5aac9a43eb17b207943ace482b46123652f7460cc64427710603a8307ef748c37f5784e0379773ca7576589c7ca30ebe78f5905b350c4bc37591bc1a926d57c0ddb5b52024ac3861785b6134ad8c067c5e9a47ea96f57b40426697e12846bfde94af1b27ae4305edb932b79ab745abcc265b8c7a37063ddbcc972c26864269ee557785690ae6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0e0013ff7eb7b8266ee94659f3372f5981ce1d87584cb1f0e80da2c0c95c16b4ea2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = 6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +expected_public_key = b2197fb4a3ab3d470a0ac937d1b37a3aa5b4f6a69bff4c57a8306ab886243ee6b34e8922f9b416faaca70a850d9aa008b382383470c0bb971027cb329cc91a9d89bd46b64e26b30dd01069bb8c99ec91895769bb93661b429a0a2c6ba5ebea62cc6b6923b27d9b99b8fe2a01db93a6fe6362d530093d4167ef35626438a949ac2f77772b1ffa65f0c771a2c18cebb2b9a3366f42782353b07961d485b7b70020a36c5375152f558f3e028fbba53405f58918541afd0b89e4092b0ec372ce48c4222a6b33a192d380a1a133272a6b2a66816f33e410ee02362f6bbbe44976dfaa4bdb99bfe9897894c254e5a51728858ed386980c52064ea3a1a837b5ba02ba34fa6de770b001b9a9fcc90fda64359f37b85f203c0ff5cf1e7c4681e990a11183d158269267722441048911b41be8b63dc139859973eb4578c929b730b1cc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ed91e02930c790bbbd6f411bcba06769b779e125ae3788d5b3844a3a7b4ddf8bf3e53274c29ae25f4573a459fc2093caecc197e050075262c7fe590b9a90dbfec86a2546e800ba726d344c0c667445b35872059365626c4b9af412b701e00392171b1f8922129123f05f3696f47c405739e0460590a52ae7c875f0a088b0e4924ef3711b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfb42645f3809dcb623dd48936c0440daf036f12ba9f3573623360ff00ab58604106fd820bba7a9e9b09b7c022262330627302e0852b70c020432235b11d750bb5a700b123dce093e25c993035cc1c3237743bcaaa3620a33b16dadbc93555c13ab0781463a82df942b58930cdde7aa1f256cb7860d0704a7d82182cd494bd803684c4cb4bc278655f31eb439c9aacc78ce21967ea07e1a6b99e7f8253229754c7a97fc6411549641018cbddbe2cd0fbb12f35c0791031735d4ab51c62e2336025f0b327bc82d92dc91dfe544db159319215c40666b86917bd2a889de8647ad658c16b9a3e1d21532011fd40b5c548534f9151f39dba83cc3170db022d488662a0223c750a1d4e048cf9157bdcb0c75185e774ac10be2b0fecaa021613cac50461a380f419a9fdf075787fba921a6a9f3ba49d78892771994fff11a57fb27dfa895d4c2a58820798a7b0bcc096b2f591a4c53bff56b054f059e21330c308a2ab9e403e5b6b7ec7574640812464710b508043ffc3b5d2092ac45b39d0c743ef1873286a6779c15669b854549a156b77d42da9cb39b868c70a037d9737746b6f1b91733c41c610977a5f66b98a167d9a15e4f8750ebf00876783bf23b9e023793b6c54ad3a3c2d33ab3eb0a2a7ccb9cf3f187bd8b358564bd9948810f91b9dc426588c51432c83a4d704677f2918f6670e611a410014838e9be4c12415cd64ca1ab5dc5f81ee8610adc6c29f5da8224093d350aa4b7988303411b1a55a240ab4ad7900a4f3718a58901371623dfcb7515db485d1736068a1549714402649b1cc322ed093eec5022113384b8e40ebd9ab8654393c013c99380be30e16d565170d2f20d12859e795c2eb28c8900910e3b294302d420193b540f826b48663f726304cc936fddfa8fec5304d2100c45d3a0b9308fd032b535780dd6fb7649410867e610dafc425202316718ab0104552393084ce56e2a36a5eac1b0cd9899e3fc2816f94b59cb76c22742f736afd60b9615130caae76f905cbc1414c8274b11b713cd049803796a8ba121a95e946be67418a205759a3a285aa69ff254bc2b39ae75021227c6c48a377f9e2267b3725666e6480920949c413a1e805a52f159fd216938d0ac4743ba060b7fd8ac2071c7022c66680d80af15736c5a3500826c1448e601058ba38c278df84a6e65357adf6735f114bc17011eb9bc48698893acb932bf6aa9d9f845de9c4e4d4a1c93a1c9bce1023181746b7559ba6370fef77671769cbb53b2d6f123cb800f26ca8b6dabc7c24560d29561d8c0581391329e73209551ba29a579cf40c6bf792b0801b1d24204c20139cac32beac739e2269440c02990568ef2a9cdd3756923a100d97c42d45b71b0432176238c8c69af81755b194a2aedd65c1c4118a320c4ac672e78ba69fd80828b7094227bcbade5536f95b440fc9b953b4e0729bd185ca617560546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_private_key = 8747252c693a0d6c06ab66071b13517e1c45abb370d26aba3fb31641a170b365c5f6235d1fd688d81c72716a3921420d228a7bd5a1c48ff445c47489b8116b7ca14d3ea78b20a7b5e579c5681187a2aa8fc900557501003fb9bead185ba9e7939f247bf1757ea66a4392095ea90239a3c67a8ca70186047d9a6b06b8887fae01ba8e556319a003934c88ddeb05f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad06e116f4542c4322072e3c6713015b1339512419b4daa8c87f5a8bff481964a8ab8a101943230f9527a10a604df6275e1ef18fe54a57d7544402134ab77802333897d4769ac23093f9b951d735b5623452c90270a0896ed3a81bf1191e451a4a67a4542556af78f1690982360ff1bfcff66386827df93bcd894ac8c996be6e0a29de70ccd459b9de46acc9e8043bb82d01c40e5785845ff4b0ddb8184afc5e52a72e899093669a9eb110a100a1159241bdd40612a9b1955b1752810764e7b68d89704a61442adf68108aa229e406cd10b6527a39a6b46068685b5e802cc25614492dbb6e06ba2160e930733956e7b29ab9981d4b477cd4eab880e56eb711b278f540ac204a996b32fd06b8bfcb7729660cf5125fe1626199f6285da628faf491dce2ca3bf285902350d52c0649339f31ea3ab764b90701bd647194fb27383681c13470b8d5ccb61dd74c5f666ffea7b0714c469c4803107235599c998349b5be7ab9e9dc6f01e928593939270411ee2490f16c54ba672ee03b710978760b962319bab3c2fc67cd9c2e9d4c153a8717826bc4c3d6c7444c051a61a06a2c87a1207a20754e9d7725b91077766871509ccc93f5a1fc1c20680263082801f6b81e8f319b92110f2da22f0d8c251ee4531b127c44b378da6a0d26f55de3285190ba1357012e42521cd1855252147d1abcb1582422f55091b5eaade93194cfa0be536343a282c4a948c355984cd20a7ca454ba034ac7355b02730107a71b3986fa01faa38d17e07494fb510e5526f690bfb27294fbb963a0606e140a182a9a247029abdff6bd8e876ec92207312432cc2700ec4c6a4a7037c5b612eeb2099d54872a5884e28981d794c7855590f1f1464017c8724bc92e0b644de92b5b80a573f641e4e65bd6f0396184086d6a5a50662f9cc6241fb7241d194b6d23ae6fa3c59fe60c81309ff7e39f93f72bcb0696edc771a80cc5ffc74138ac9d01b95defe7258bc555e3e28cab6a73372337efa0b4aa0c7d13b312a7313f8b63426c6677407903822aa1acf4acf4a130c4c68dd4dc47dd061ed0a4969e5ab630baa11fa0aa51133c6509c83e603425a385730aa0e07a2bac0754358c812f483f5ca6bef3105cce4cc33532116c6493f19880f693581e08999be24db44b84970c8fa4f6784d50614cdc9e626a31966acf81309ea6a730eb42011663cf10a90a9ec12f3fe133a7d02cfb95cecc6b52cc08571bd03e8315532b7c76c2040b60e9021a24734854b6a3d77cbfd087015410b7322ad5d9b04f651f895ab5bfc25f8cc9703bc67dc5eb5aede41682a17feb1b4339335efaa44a64e8b4eb0bbe17fb00875a06318c1e68c42e6ce0946a59c61700a7277976e2e8bfda906daa229d20732b60965dc5d794dc5306e68226aa18081486c28b28093b12280fa2965cbb012ab67a05664950a069d13332ba5c19c8d8c7583c1f74e4aa60006c3e2c9b8da1bb8e1935730c31d3eb066697b4fa93ac65e21651535ac1d3983c915b72eb260980c37033ae51c833e4e3c1cdebc03a7b17e85c224ca078dd91024805c444d766bba603f225073846bef949937c6bc2a6bb4519a5b00036a5d688b354e64775431ab18c37b0167495b31328454368ba49ee2a542447466269c6c122b78ac44d60c983650237b2957fce240d39817180a1898fe589c0044819037f1f679aff2c11fc4c0d2e510fe35272d1f823c2781198ac1859e2ce252709d4bb8c0dcb64c4f2baa33985312a1193095379d9cfdb508ce634a0e305ad9d554053950bd8b902ec462d0a1910303b4bede153b11c915dbb1feb52b312c42f754c0131c1218f4ca4402c4d74430b9415c586419210196eab4c6ba4587ffaaa71583c97c329731cecaed1414ab3aba4d830a834d6b8013495c89c4b413414b2197fb4a3ab3d470a0ac937d1b37a3aa5b4f6a69bff4c57a8306ab886243ee6b34e8922f9b416faaca70a850d9aa008b382383470c0bb971027cb329cc91a9d89bd46b64e26b30dd01069bb8c99ec91895769bb93661b429a0a2c6ba5ebea62cc6b6923b27d9b99b8fe2a01db93a6fe6362d530093d4167ef35626438a949ac2f77772b1ffa65f0c771a2c18cebb2b9a3366f42782353b07961d485b7b70020a36c5375152f558f3e028fbba53405f58918541afd0b89e4092b0ec372ce48c4222a6b33a192d380a1a133272a6b2a66816f33e410ee02362f6bbbe44976dfaa4bdb99bfe9897894c254e5a51728858ed386980c52064ea3a1a837b5ba02ba34fa6de770b001b9a9fcc90fda64359f37b85f203c0ff5cf1e7c4681e990a11183d158269267722441048911b41be8b63dc139859973eb4578c929b730b1cc93a4cbb6caaad874391687732eb99170abc2812865c3fbcef19b732ed91e02930c790bbbd6f411bcba06769b779e125ae3788d5b3844a3a7b4ddf8bf3e53274c29ae25f4573a459fc2093caecc197e050075262c7fe590b9a90dbfec86a2546e800ba726d344c0c667445b35872059365626c4b9af412b701e00392171b1f8922129123f05f3696f47c405739e0460590a52ae7c875f0a088b0e4924ef3711b66b3fbdc7cf9c183183f8cb122570cb2c5f18f66faa2cccfb42645f3809dcb623dd48936c0440daf036f12ba9f3573623360ff00ab58604106fd820bba7a9e9b09b7c022262330627302e0852b70c020432235b11d750bb5a700b123dce093e25c993035cc1c3237743bcaaa3620a33b16dadbc93555c13ab0781463a82df942b58930cdde7aa1f256cb7860d0704a7d82182cd494bd803684c4cb4bc278655f31eb439c9aacc78ce21967ea07e1a6b99e7f8253229754c7a97fc6411549641018cbddbe2cd0fbb12f35c0791031735d4ab51c62e2336025f0b327bc82d92dc91dfe544db159319215c40666b86917bd2a889de8647ad658c16b9a3e1d21532011fd40b5c548534f9151f39dba83cc3170db022d488662a0223c750a1d4e048cf9157bdcb0c75185e774ac10be2b0fecaa021613cac50461a380f419a9fdf075787fba921a6a9f3ba49d78892771994fff11a57fb27dfa895d4c2a58820798a7b0bcc096b2f591a4c53bff56b054f059e21330c308a2ab9e403e5b6b7ec7574640812464710b508043ffc3b5d2092ac45b39d0c743ef1873286a6779c15669b854549a156b77d42da9cb39b868c70a037d9737746b6f1b91733c41c610977a5f66b98a167d9a15e4f8750ebf00876783bf23b9e023793b6c54ad3a3c2d33ab3eb0a2a7ccb9cf3f187bd8b358564bd9948810f91b9dc426588c51432c83a4d704677f2918f6670e611a410014838e9be4c12415cd64ca1ab5dc5f81ee8610adc6c29f5da8224093d350aa4b7988303411b1a55a240ab4ad7900a4f3718a58901371623dfcb7515db485d1736068a1549714402649b1cc322ed093eec5022113384b8e40ebd9ab8654393c013c99380be30e16d565170d2f20d12859e795c2eb28c8900910e3b294302d420193b540f826b48663f726304cc936fddfa8fec5304d2100c45d3a0b9308fd032b535780dd6fb7649410867e610dafc425202316718ab0104552393084ce56e2a36a5eac1b0cd9899e3fc2816f94b59cb76c22742f736afd60b9615130caae76f905cbc1414c8274b11b713cd049803796a8ba121a95e946be67418a205759a3a285aa69ff254bc2b39ae75021227c6c48a377f9e2267b3725666e6480920949c413a1e805a52f159fd216938d0ac4743ba060b7fd8ac2071c7022c66680d80af15736c5a3500826c1448e601058ba38c278df84a6e65357adf6735f114bc17011eb9bc48698893acb932bf6aa9d9f845de9c4e4d4a1c93a1c9bce1023181746b7559ba6370fef77671769cbb53b2d6f123cb800f26ca8b6dabc7c24560d29561d8c0581391329e73209551ba29a579cf40c6bf792b0801b1d24204c20139cac32beac739e2269440c02990568ef2a9cdd3756923a100d97c42d45b71b0432176238c8c69af81755b194a2aedd65c1c4118a320c4ac672e78ba69fd80828b7094227bcbade5536f95b440fc9b953b4e0729bd185ca617560546ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4b503f8ec36d39fc7b4b8ada1cbb933b9db9ee118bf081ed75dd5dba7590f6c8cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +expected_public_key = dd9521e55c85d1ab71750942bae014469040333767dbe4ac80e4b3d6751f27fbb0eb0418406111c9e77c39977315526bbe1c8e06150a0384ca618001b08554c472464ae8b4b9eb679a790bf0e311ffc20b9a28a2edd52c4cb51bb739712419a116b1c0de65217ac429b091bbf94cc9e24886ffb623889028490976074888ca731ae4f9a9e0e4099f149372390bd2b78516044067201da469c7950bc9c681423b9a45b579160430add2b34d3dec2ce84270fbc019847c017d098bc4224bc9c99ecef95947e358f0f85def6837c5361fce2145faeca7ade0a612138c8cb26bfb534c2087c8dba4ce1f841e704652a093af188c55ab221123540a1007190453163a573d166617f452b9b2c7b9638b0201292dcfca46f4b9c95c1c8a47f44c19380a061b51942636c3bc8950f01186878004db1eb6a3b2ad5410c3484aea11a8d38881de278124c4c2b592b61bd87aef623de1b5b8b2d016a2d985976062758849362b2631a8a08404651305484a3b2dabda9982566822002ba1e83ba8b04c7be77d4086207e5b8310fc28812584129a4c03e938e950cfd43c3023a8774b42c9338ba497e853ba684c24aa03ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc659656715d0ffb8287b86cc0964d3e1b77e7d83afa733789709714eacd47b8bede99aaba2480002c0fb9136e397790bce939086ba75467340780cc31491e82172803a57129b3cfa3957bb70b114cfa99568428c540b187b98da9eaa20f3a7771d80146ac21b8908260c2cf79383031fb99ced3be7c86168549b8e2d2474e96bfe28158d91a16d5230b2f7b27d645c3b2096659a60c78a602457b0ef8553bff9508175b5e10e08326139aef678703d39693215d5d821811bb0868e483c646a4dbf0958978352b919c1354071c42bd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa3572bda92c2f9872bd19276cf66c31ac6cfed109bb36b77378c5d9a747637f1950cf36c5b22130eb018b607b74a270e0b733f12e426a2eb02fd3713f72c682d87cb6752a6a3037816b9a1278151c662529b54c52655b76c534e09cba4ccdb85289528b8f0201081cb05066515a3cfcca9031f386d6f4a411df397e526b754a0cfbdcc7968a03ffc7349f32036aa4b15123a6ce8d47f87516c717651d56cc7e2147cff3261ec76c045a32beb047760295e79f8c501c46b099bb7b508cbba9b099f612e595b41d32a946e0bcf26a0c5664b70971853b7965725d52bb371a03f456be855aa495a2e3d9925f6a7c3b98695b5e179e64c17410bacf2035e4fd3b938c98db2526804c79322230ba8455dbefa40caaba9757380944193063335b6721225f40702ebc418022fc2590d00f918765ac41cc6b40d39b45291af80f721069c7f73096b7b0a202749c70ce672f246209c637375e75a1ec03102940e8c17566b7c2ad43167f48a56c55c6b38d289d5675b9b224b7155905c814e175052a7e67685392448003d8e2815ba9810d8930051b615558cacd704202ad50f52890500e8be5cdc91ddfcb61948788a9cc2167a0021566a863b875361153b1a57e0c62f8cb11d3b3840f570b922e4a88151aec22baaf7559f724549b892575430383473b9183214104006dbfa356e2c31ba283f778776b43530a857c8126780e29c0316c64ddb1a947d747a8ed831135a8146936090fb59192b32b50327218125814b2863f2473b708338390ac2e507715136c8786fdcd1c10e2b0d63d2ceb6a4b0d8db6f8af354bdd1bfc6c71afb627686761d97b761fc0aca584539117ca416078c784972f67caadfe67f38eb1996e749e2f11a3c47c389d5c3f1f52d33f14a094cce5557154001ae2d17a2896ab4d0744e9dd4bbdedabf34d38c1c81812a3cbe4a065a0d6ca0cf3a9f5ff0268162a5b3d872b6782cab9149c52c2726079396b01866e00a20bc82208009f625323df535f1658a1ea29b933368992a89efa0ba586381d845099c35a299a467cce67af2d5b066d9891462114569a2261acf20cb64cf3819d0e0a4c20a153cfb5efc9c45501aa26adc5b26553b520a04c4388d665b098fe52b5aec48154a2ab5053279256ba4e6975f4764c77a5fac85275fec08d62534353b17764177037bae5f010266767164b307d4d375c85549edd3261c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_private_key = a32b081d2579d7737a984126b05465963ac3d0fc3d471b94e30b242699ae3ee7a305d187d9371af3568d7bbabdc30ca69be166aaa07c67799dce7345b2024ee41c5a6f35733cd12efa19256ddb74440829c6b52aaa25b258bac8d950ccdea410535bb3a44a46ebc44f5772cdad96596980c32a14916cf5c4a2fa8538491f7eea270543abc467344ff098edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca0165528241b4bc173bf17b4e7873a5081016a1c55e4bb1e7f71b849274d03e05e866656c126485979ce9660afdf3622e3051f76d02243e660a5a78c663880a7f9765df45410926a86acc7962878b4037cf2960b06f072367b476eb24b8c57924a9c699815bbeb0bb10b2a88b0c63f0171c759d59cea91c5c043a41a8155e462325893685f18c5458a0ac3e5bf2c696c8f07727c090e1d3502d075a706551c54a00a710027c52cbd83fb9dbd7567aca2b6eb809c00838e56b209e0c5aad2e6235e2c157d3659d906452f4a8c60b26f838a51f6789e42c00580e4595a5c0a12b796cb44240a4724c298abff1332bb0970a3ec475a434ec4dc2a4aa92c42e22035a4499c66827c882b542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0bc0a0c3b86788459b659a539833629c1b585a13134d766c9e8003282683aac1486a934edd3a7511319a7952b5eb7c5947b69ab5c904b2481a7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0e982a24d344ee8a22221a02c6538154217c453ac0ecd4bb1f820baab94d920765c4ac15972aa79ba974f3b5055efa7fe5bcb454f7ae70e1c017322a20c73ebf278054060687c6301e13b52952459c56bc8d8795044302fc9123921143ec2c73278939826682126b65c7d9bac044ae6cc7ca40f92c8ff28470e41d51895adb53ae30216b1aba552fcc14ab277a872029f3dc8d56794d842ba06770808f1c097787973b0a14280c5fbcc45c102c23821a07eea6c3abb4b52ae116f4b38e4a50cfb849177766495463197bca3197b53ab72b172c163003c9ab89721eff925f56b59373f5abd1430b0731419a12ba80641628d78d712bbb74579c0a18a4cb2aa6edd76fd7605fbf8214a00aa44e486810f3ac6e36345431c23f247f251112cb8a6c76444b1a5277b7c68afd2c49d4a81fc5069b9a004cdf0587a4a193d243bc5f16357e1b1f280706b4c16f9d8b3b6a5815a1597c49076589d5303a5c89ad320cf6042f2f819cdff04b850870e807b4f2b6bf99aa8f3fd16e95b3bedf247cdbdab048586116db7a4530c360bb240fb2964fd41a5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e8461cbe906e93b209742c0abec1c1bba9baa05a8fd05637d26548f48512f5477b93d0bd54f6674158b2f6ea0488191eb023a641b175cc689a2f326214793228138d6da03bfe4466dc962fd2a7c57102cf3f96cf3a6619d2f613ca063a35f4515c0473140b8ec3c53b1d9974021616bca2459bc31502daafc861990c1b97ea1ab5ae018ead781a67a075cc4924f9ea364bec33ed167637f0a643c3a810914a49366af69b3cc25938e77422832b7078c6be562513ee3648758515e3c04f27eb5cf0c73efce032cf027c7d6916072b6984452cdcdcc5b6293cb98111e13040548c5c4ecb4ea83c01580887eba79f0d700ce25274f4612cdb8427fe9377b7aaa517f12d2766834314263e27086fb8969a38157d9a02da83772691184df5117aabb901899e0e78a42c335b7eabaa462852423748916b9261e834320cb8e8576988321aba321348e68a424183e010bef6f0844b8c7164fc967feb02c76000b372a1547c88c7402347326cb43712be145e1854649b07aed70b798e845f7c4c5b0457ba58a370a9758940053476750c5168494bd733ef0c6c3a06117aa53db762440969a1939539f85c1145307526db7f43ea595833a7a49abe0d3446f2345fb429c4adc43b2bb17bac8c6259f2551b3c28ae1b57fa49889aa6a2503a9017f832666610fc24a4a8657475d3a329d31a793a6a4024330f0b6d7fc2250e6575d8a8947fc30d431cc24417a6ed4bc131b253af142f2ca88fd0c9a44f811103b064759cce44e02cbb062458502b71b9083d097f926a0da50b6914fc70e0858644253fdd9521e55c85d1ab71750942bae014469040333767dbe4ac80e4b3d6751f27fbb0eb0418406111c9e77c39977315526bbe1c8e06150a0384ca618001b08554c472464ae8b4b9eb679a790bf0e311ffc20b9a28a2edd52c4cb51bb739712419a116b1c0de65217ac429b091bbf94cc9e24886ffb623889028490976074888ca731ae4f9a9e0e4099f149372390bd2b78516044067201da469c7950bc9c681423b9a45b579160430add2b34d3dec2ce84270fbc019847c017d098bc4224bc9c99ecef95947e358f0f85def6837c5361fce2145faeca7ade0a612138c8cb26bfb534c2087c8dba4ce1f841e704652a093af188c55ab221123540a1007190453163a573d166617f452b9b2c7b9638b0201292dcfca46f4b9c95c1c8a47f44c19380a061b51942636c3bc8950f01186878004db1eb6a3b2ad5410c3484aea11a8d38881de278124c4c2b592b61bd87aef623de1b5b8b2d016a2d985976062758849362b2631a8a08404651305484a3b2dabda9982566822002ba1e83ba8b04c7be77d4086207e5b8310fc28812584129a4c03e938e950cfd43c3023a8774b42c9338ba497e853ba684c24aa03ed33b36ef8c50be44ca349bdaf986f38a93676a7b4cc659656715d0ffb8287b86cc0964d3e1b77e7d83afa733789709714eacd47b8bede99aaba2480002c0fb9136e397790bce939086ba75467340780cc31491e82172803a57129b3cfa3957bb70b114cfa99568428c540b187b98da9eaa20f3a7771d80146ac21b8908260c2cf79383031fb99ced3be7c86168549b8e2d2474e96bfe28158d91a16d5230b2f7b27d645c3b2096659a60c78a602457b0ef8553bff9508175b5e10e08326139aef678703d39693215d5d821811bb0868e483c646a4dbf0958978352b919c1354071c42bd39e9b9394aa54ca577d9b963f4f35606fa892166ac71a3bfa3572bda92c2f9872bd19276cf66c31ac6cfed109bb36b77378c5d9a747637f1950cf36c5b22130eb018b607b74a270e0b733f12e426a2eb02fd3713f72c682d87cb6752a6a3037816b9a1278151c662529b54c52655b76c534e09cba4ccdb85289528b8f0201081cb05066515a3cfcca9031f386d6f4a411df397e526b754a0cfbdcc7968a03ffc7349f32036aa4b15123a6ce8d47f87516c717651d56cc7e2147cff3261ec76c045a32beb047760295e79f8c501c46b099bb7b508cbba9b099f612e595b41d32a946e0bcf26a0c5664b70971853b7965725d52bb371a03f456be855aa495a2e3d9925f6a7c3b98695b5e179e64c17410bacf2035e4fd3b938c98db2526804c79322230ba8455dbefa40caaba9757380944193063335b6721225f40702ebc418022fc2590d00f918765ac41cc6b40d39b45291af80f721069c7f73096b7b0a202749c70ce672f246209c637375e75a1ec03102940e8c17566b7c2ad43167f48a56c55c6b38d289d5675b9b224b7155905c814e175052a7e67685392448003d8e2815ba9810d8930051b615558cacd704202ad50f52890500e8be5cdc91ddfcb61948788a9cc2167a0021566a863b875361153b1a57e0c62f8cb11d3b3840f570b922e4a88151aec22baaf7559f724549b892575430383473b9183214104006dbfa356e2c31ba283f778776b43530a857c8126780e29c0316c64ddb1a947d747a8ed831135a8146936090fb59192b32b50327218125814b2863f2473b708338390ac2e507715136c8786fdcd1c10e2b0d63d2ceb6a4b0d8db6f8af354bdd1bfc6c71afb627686761d97b761fc0aca584539117ca416078c784972f67caadfe67f38eb1996e749e2f11a3c47c389d5c3f1f52d33f14a094cce5557154001ae2d17a2896ab4d0744e9dd4bbdedabf34d38c1c81812a3cbe4a065a0d6ca0cf3a9f5ff0268162a5b3d872b6782cab9149c52c2726079396b01866e00a20bc82208009f625323df535f1658a1ea29b933368992a89efa0ba586381d845099c35a299a467cce67af2d5b066d9891462114569a2261acf20cb64cf3819d0e0a4c20a153cfb5efc9c45501aa26adc5b26553b520a04c4388d665b098fe52b5aec48154a2ab5053279256ba4e6975f4764c77a5fac85275fec08d62534353b17764177037bae5f010266767164b307d4d375c85549edd3261c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f503341657b159925cedc8967872a45a3c1f0122979af87a878a2019b3f17c8ba67f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +expected_public_key = 0ba19153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d3c11f376b1f1cd8776b6280cfb52559b6b3bf4716e9b49997911bf8da16c4147a2cc9bb379ac5195a320783213f62156c127257a469a428834d384b1ed48a8a576b240c1c55b84d61e248df45a52199143fb141b39c29631216a32b8dfb876df873456c14178c4360b8215c71e219c08c915a9ac02304c958c1bf7e65b3742bac539059eec85fb6cb608975b401c83b490094a6d1714876727ea34cd27b7385d7575ff49931820fd5dc33f3881554c25dc41a65834115e1c899ef8a080fc6c53b81b3804508fe4c1fe6904960d96f8c1576614474c9191c99fa3a201a4143b09ae0f3432bd13a3442ce80ec3ca3c94bf2b45fc398165318bd8d2683148315d1969b70840af5b42d5779c844c48cfc0488ec65b414837a965c65902c21a2c48a590ccf9fb9c6f9e45913aa0577d2acbbb29b5357cbb6b16fe6ba9abae44645ca68573b5fe325670f2c4b5378c040171ec3a25229b1c3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3e80fedd62beeec1abd53a45a7c33ed4117f415b77a43a0d7ba4ae2031e3c57c945b9abc3b5b3b7915784eace07e7caacf256cd27b28c2924b01302c9432e5f3a2a75009d03e36fcf7089fce58ce57492443323ab494c07146db2ab8e3263955eb373031c22da591ec5cc3ce0155f69fc43c8484a9e332e2dd433a888190b05747e0971005b8026409ab874cd65f533a51a40a668900ec109de60749250890ce91290a43078e3ac85502b4f34518886578c26353a6577fc51510ddcbf4ffb6b501662dfd1001d6354b47b0528dbbc0d6a18b58c605a91957c27ba354232751810202a891aa83efae7957ac2883605375778369589597a8b4f23f325acd8683c4b1dc3103002e1c588039e08a7c3c92137510391b3f75b99810f5c932a80a7b5d8164d999c131828a59a939d90a8caed47c205681973a38074243a787866588399a199c8bd74c8b6546168e255ca13b23d0775eeb727e3cac8b4305893185517274c4a4abbed709f2b986bc02592d1dc38cde048e5f63f15086f11031348a7a68e044cbe1075f1eac3c330477fa5124c832c2c880e29da691007a82b79611ee04b64280e51d201aea5b00a633e59dc0c20d72742a925d4cb19661ca864bb79a029c7100911dcda5fa1b36392d3432c187ddc51190c563d4c180dc87976a142962023301acc29ab63853813185b6390fd84b7d395514bea0b35b22d9dc19277ab7d0d602725a9ca3af87df9f96db8bc6a3f27891f9283bd6a4c4966cd26d3c96c2b4d808a2cd435abe4173ead728a200a43f8e21907020d6c19293eb02785571a399a81b8205485c54ac19bb298c8941dc06ed7796a39ea2c84d755a0e90b53f86ebff130c6008f2dd69af0017bee0c6e13a0bb2bd73b02431bd211a5fffab76f96c080482055837a6295209cb2a62505b846005ca5a482709411b5b94bc3781a557b2efd85b575621cab87aaad6844034c4a1ddb43d70687d968bfce441e7054a9c9905c114b9791e65bb23aa0cf22ad7e005bcb38b24deb2e7741853ee7085a93250ef7624be270bedca3d322842b477a507c3ddfe3325d893cfc432f07c15a1422128b5703d92812b87915e86a8f8de97f163caf5f695ef9994ac4d7932fb9629de72a988194ba13c996c2252968708e6468687b1a91063de718331027a54aea679861b1b6b6930f8947af72a1b30895f225a7bbf7cd7e8a857b6216115c8e98689b89c7686d282c44407c44eb64d3795d51665bd538c33a7915b5f7773ff20b6d289d2425a2ea4a14e8e2a349a78c76f8760082a1f8315b4dc41109a05c6053484a1b381cd8412df92ebed7c489ea3db9915a23e07c37f7c805e448a5f08a89a860b96c4bc7a10d4c30522cc900291a8504e72f4ca5229135827626c138173f73f123fe013f3612a27df9965dd78c6f1a2c3577c7cf866e70190c8a249a6ac6c1eb45ab61f9a021470135292d6ba6c26455cf0876c9633b4afc24779c908b5619ce1df7464e096aefe51b5f43be40b556e2c5c41503857f8a6b4adb2a5d8a67cb668930889d68295736027b5b1a4b3cf44a05101f1bd4b365b8c54117c6027460e14ba516724361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_private_key = d1f46e67cc5aea63ca9ec413938661c2f8156cc79e10a64174774545b597e91a8cadb58deb15b27f343073b071873870bf858b5fa3ac3689698deb68c570406972210c2b9909571a12753448e00e6a0c165a101469828e8f60a16b55478c8899d9a38c1751bf220a60a999b0d2a429b375137db8bc9b85ad5fcc073355ae630100f8fc68ebb8534135590ce22d0a0672ab54936c8665aaf476b50293a32135283777c375767b04547501a53b72a14d3c4de4e001d16b2b2b598a22d784a3711c39db183ac82cf895b242954b41c713bf464464917d6b608d21b67b3519a6df161ad237359e262b95c6be3a8522b9248346785fd0db03cd083a21092f4d91af156b12f4c9c77c11cc0b68adbdb813beb21289743758f8136661704d0c5ca9302a064040334017d47815b7c35363f5c730298670536c69c122cc91cdfd18783efc4c39c8c29cb1023f1488a7469f1cfc1d7ebb3d1ceaadba3b07310000bd89c043290abed896e655cb1f43a1c7335aee30044d9652e6d3b8e394218f63072c7050a2984032c45735a3aaa4108aed8b9a19c13b9bac28ccb123d9987c45b91e89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1aa415df9961a4785337535869fb758cd04b798907e36197ea428c66aa516f602404e87341e154a0e09c881725cbf00761fd9645b658d97d21f33059e4a898deb0c826d9057ac302663897d71567117fc4416c860775b026e51a52663711868777d542f1224b277ec005f2bbcfc0c84146591cb36caba82692b010de229797cac57aeb64af446a896527bed9b3e55539c0f6a0e9eca5953890b95b0b282c3a4c46a44a8705a54a8806ccc0d3c736a20d34aab118813651d85f12906958933d69679d0457a4817dc83b525ccc63e94c1bcb1c869cb3a0bc46d47084481c2563754aa8f44682b870ed04996cb8886f43b91ac8767ae12856ce5b85f55c8802830ba1babf5797d0da723eec24616a195ac809371d93f89b19c874c840ee9c39e7370ca561b6e91552cea47f1d09c9cf633e7cabc9ef85f89d01a29d9cfca8143bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a82322793906462c03c20969f76c2c8c8ea2622a373c3e40164a77055ebae05787965b60a861c09658c32d4194dccd7ab1df87826590890b1785f0385b965b5ab3b870a0088696a783b5c7a69962b86f789bd43588705315258c117c4313198af42e2b7fe39894a86189ffc4e8c6bac5e7a0f03d86d18089a6999972f309a6debb365781f64197165d259bda98c7a920a9e790bddc587e7c08040d649b8b08fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5152b049850857308ba1310283a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd7712686200d451cafe599ab0d3a183d2b0df7b8fbf0995042ba0ce682eba8b71dc6c0744262c75b7638b51b9c4931d4f7c842328486a799d06027cd5cc75e4b1b6816c2ad66b86ed047ef978184bd344c00aa1200432c5d142246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375060282b7da42ecd36295fa55f8b5ce94b812bc421b47054469d39e3483a63583ac5a97cd63312e776902b73c34d5d81a35153589fb6d7590c0f9b4996f83cd4631a7fb6c09f60a0faf7c5d24f9983d9cb9b19566f1eb6800024fdf032c4032c778d74846f4c7b63a3effaa5ab619ad3c62680f5290adb5063f0137f0ca7b694978c622a9a34bae292719a7f9cb67033c0de773359aac3577ba38446a5610acb9d48509413b1cb024cd25a4a5a882ac31cacec34c25fa073bd38a8356934423a838415355680bc7155d433b4357ecc6221ba804602317c7703aecc7fdb30781a715849186f126619fe78f610420d2bb3adeb085753a710aa07ba2139c0897a172dc09e7235bbd0638d8c695dba8baa8b04f7a058edac52622b4a9638155d56448a3977786941ae23c6dbd05c4fe466412f29c74eba96921612edc0bd5d12e72e944e5105843034d9070416b649491c7b4245c14cc152107bc68b6078b76cc61a6b371e95202292584a1734f3c4214c2371b8168c6eb9c7e7efa76432316d140aa9055577d874a7ad70d16a3783f7904f3445e7d81260ba19153d3a984e76dee73b825996798bbc7c24c5e45d45f26c39a879c676d2532d3c11f376b1f1cd8776b6280cfb52559b6b3bf4716e9b49997911bf8da16c4147a2cc9bb379ac5195a320783213f62156c127257a469a428834d384b1ed48a8a576b240c1c55b84d61e248df45a52199143fb141b39c29631216a32b8dfb876df873456c14178c4360b8215c71e219c08c915a9ac02304c958c1bf7e65b3742bac539059eec85fb6cb608975b401c83b490094a6d1714876727ea34cd27b7385d7575ff49931820fd5dc33f3881554c25dc41a65834115e1c899ef8a080fc6c53b81b3804508fe4c1fe6904960d96f8c1576614474c9191c99fa3a201a4143b09ae0f3432bd13a3442ce80ec3ca3c94bf2b45fc398165318bd8d2683148315d1969b70840af5b42d5779c844c48cfc0488ec65b414837a965c65902c21a2c48a590ccf9fb9c6f9e45913aa0577d2acbbb29b5357cbb6b16fe6ba9abae44645ca68573b5fe325670f2c4b5378c040171ec3a25229b1c3df175dc1d4af59035c7ac449d07c72abb6a153ba50c3e80fedd62beeec1abd53a45a7c33ed4117f415b77a43a0d7ba4ae2031e3c57c945b9abc3b5b3b7915784eace07e7caacf256cd27b28c2924b01302c9432e5f3a2a75009d03e36fcf7089fce58ce57492443323ab494c07146db2ab8e3263955eb373031c22da591ec5cc3ce0155f69fc43c8484a9e332e2dd433a888190b05747e0971005b8026409ab874cd65f533a51a40a668900ec109de60749250890ce91290a43078e3ac85502b4f34518886578c26353a6577fc51510ddcbf4ffb6b501662dfd1001d6354b47b0528dbbc0d6a18b58c605a91957c27ba354232751810202a891aa83efae7957ac2883605375778369589597a8b4f23f325acd8683c4b1dc3103002e1c588039e08a7c3c92137510391b3f75b99810f5c932a80a7b5d8164d999c131828a59a939d90a8caed47c205681973a38074243a787866588399a199c8bd74c8b6546168e255ca13b23d0775eeb727e3cac8b4305893185517274c4a4abbed709f2b986bc02592d1dc38cde048e5f63f15086f11031348a7a68e044cbe1075f1eac3c330477fa5124c832c2c880e29da691007a82b79611ee04b64280e51d201aea5b00a633e59dc0c20d72742a925d4cb19661ca864bb79a029c7100911dcda5fa1b36392d3432c187ddc51190c563d4c180dc87976a142962023301acc29ab63853813185b6390fd84b7d395514bea0b35b22d9dc19277ab7d0d602725a9ca3af87df9f96db8bc6a3f27891f9283bd6a4c4966cd26d3c96c2b4d808a2cd435abe4173ead728a200a43f8e21907020d6c19293eb02785571a399a81b8205485c54ac19bb298c8941dc06ed7796a39ea2c84d755a0e90b53f86ebff130c6008f2dd69af0017bee0c6e13a0bb2bd73b02431bd211a5fffab76f96c080482055837a6295209cb2a62505b846005ca5a482709411b5b94bc3781a557b2efd85b575621cab87aaad6844034c4a1ddb43d70687d968bfce441e7054a9c9905c114b9791e65bb23aa0cf22ad7e005bcb38b24deb2e7741853ee7085a93250ef7624be270bedca3d322842b477a507c3ddfe3325d893cfc432f07c15a1422128b5703d92812b87915e86a8f8de97f163caf5f695ef9994ac4d7932fb9629de72a988194ba13c996c2252968708e6468687b1a91063de718331027a54aea679861b1b6b6930f8947af72a1b30895f225a7bbf7cd7e8a857b6216115c8e98689b89c7686d282c44407c44eb64d3795d51665bd538c33a7915b5f7773ff20b6d289d2425a2ea4a14e8e2a349a78c76f8760082a1f8315b4dc41109a05c6053484a1b381cd8412df92ebed7c489ea3db9915a23e07c37f7c805e448a5f08a89a860b96c4bc7a10d4c30522cc900291a8504e72f4ca5229135827626c138173f73f123fe013f3612a27df9965dd78c6f1a2c3577c7cf866e70190c8a249a6ac6c1eb45ab61f9a021470135292d6ba6c26455cf0876c9633b4afc24779c908b5619ce1df7464e096aefe51b5f43be40b556e2c5c41503857f8a6b4adb2a5d8a67cb668930889d68295736027b5b1a4b3cf44a05101f1bd4b365b8c54117c6027460e14ba516724361d34887a693067791fb183c9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa098560c001172c4734a620c248654c58f1c10135657083de776116a6acf8a55f3610d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +expected_public_key = 29d5526cbb30aa578643b133a0254d6e22c33ee80564e7424f0842b113636010c566eb59f9923a021b2a19c08bfae521e44324eb5bc9873846141ca7da45be4f8619b334a7cf52093b2177f4a71ae211081a096071f958277555709b2f459685ff22849a86375e157258d24563b8028a728c5eb0bef79495c1c53979880930539227c188c2027681236439085b41763d6378a4ea0254a7416473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c2716053bb54dbf1bc22f32e6d88c2a1947bb599a878b84f29021ead84a763eba7b9f3422466836bb6ad029543041115d638552cc2017a84ad4cf687daaba75b0c0a73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c2325a3ac19f9a5b0327b80f220b9122583f5d908cc21c97083227b568c47e58a2a7843d2141411b08f9cf61deb4a9edf41617fe26bf9c519d0cc80cd292585dc4ce5a90339216a6f876206732af6dac9b2720025b31e17ec47dff321b06107993a414f1509839886bc526f8051c4380c3faf4b64d7e3c9f9a76e9d440a67499322b37c4af9b26b2814a2b8b699ac0adcb25835d038b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53df10c578562a91b55ca04ae8530c6aba9c16cbb0684385704c15d302c1ad4857d0d1657dd85c536cc76f228641899188b9222f2b208d34222276a3c91628772c6245433a0ffd16b0812299283ac8d5a36b868b9fab4189aa64a0b90b606e695fa542b8c7c3ff0f0a46d5b00da78236d518d34756a2f32075480a4c15b7c27cc8e4a93180e6b5859120a24db2daec61a479cb039d4b9e6041e816c96862c2b1d616748444b4febcf7a129e6e7817950c77a3fac386fa787eba4157b720fc26629842a145759cc8fb652811a8a3cacc29571463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b304c0426ec26fdb17ca8fa5496d794778c49b4f74a58240bdd39c2fd6628011837451cc4389a43f3bb20959928b77394651e4c2cdc44cb9499def6b366d15550b41ac89707e57b271aad6113ef7a9b1575c69e35e4d75bcb0333e89c091603b7ea5973a277672a1c504cc2c45022906106b97d4fc01e98a876be91d88f4c908b892b5cab99fa878dd1b3b1688976c148bd0450216656028d9c2fcc3bddab2ce6541810cb84f4af414eeb863b7c7452bb79a96e790cca35bdf05b4c3b059801b2bee373da6a0c3df79c986e71a6788712fc50aea51044c2b82b3d201ac7a1245c96767f0cece2b4af175329a4973696c5deea91075a6b8ee2c347d15c89448cb48d22126d82732c1293288ac60bb3bc3ca1e208ba71054399fa4a5d1db7389379600c128b0ec1803b88de90369903799cf5ca0c5ea0b012b691b0a50b9011aa412509d1abf24e252e9d2cbb315361977770ed77310c1705e46b06a5c1c35fb5e5c9a8066d2750b388855e982bceab6b5e8018181b66717142cbc3729b13e2b34205fb06724ec13c3c2977e346e50a79498f94756069693989b77432f8b5ac8d2b06f2e227c4728288e91bcd6cac439b068e2017ce1c808c74098ec2c099d81b9dc6ab7e780c0c1669806e3cf34a1c1d5d002aa1c9301670fc4e45b64c59481d1cf6446468806683f57b3bc25b032aa40d2c188c5a2a7d47b41b4753d5f7a3b22bb70643942d6c35317f05e6acbb4f6794b1b0c3bd47893a7f9cbbb61c608068054b385a9578303111972e8888c6427afe099a1a07fb3879b821b25fd1699ad001f51b27acc5b2926ab2caeaa9341e1a627493f44f561eea57745a0764a840963024ff6c070ad95b285a74527fc3da894c06f7bb5de61a012547f87c1517b9aa5575a1ac9a30d858c912ba096cff4a24085c750aab463f8b956fb837ee300470452c6431d128b27472b5cbab268924acedeab3e7b02b2b201a44e99654910cdc8d5206496637e88929a1ba4436272f6b5ce41533450663f7a1a9144b5400d727fe6342c6cac6e2c3312015b571585303967422ed8c5d4b75e4f203bf2f86cf0370aa9324c47246a27d9076559c906ecbbecbb20e020cd9b6328857832ad8400666b943f8418f57408251b91ce341a2f63601dc751c0b301729caad8425f717250d5a249b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_private_key = 09d0009aa9878c697e2eac9cec9675a9570660346547d7aa8d4548e3aa917e238cbbc10c389445d15714b237566cb44132d6983c9610e779570b74482d5ba2742a1bb51c68142c1680b800f1938795367b6d8a56c32a0d77922c78116643530aac01cfb2692f4bd6bbde615a3335b397487db8a1175a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988766114a80b1979118eca08217540f032966688c99feaba06d0a0a1e701deaacbcff9c2f2948a209ac8ee505c85fe0444b5c70d067100b63cbd6d98f9aab73cb06c97ff31d7aa0ce188707ddc5c07d495b27957b369055650abd5d9b9f75761770920dd0b574a5841c3bbc9f6f1ab0179c118c7a83b2934e950b3dc732c84264c66fcb0df78975fcab5feaba4e6af97131696a0cda1cc9e2c40a266fbe6667c1abb361f063103311a792b95cc525ff872bf3f394ffb48b30b334ca02bb32a901e3478f811505da066de6a5caba425df83c27565ca48b16bb2855a797a72dfd57615d5117b24374c2d306473a349521a8107790d268ac6b5813c593cb9e8621f8c68fd2e8082c491c95c5ac74c86dd37b0a4ea0cb66aa576af50fbdb0a31235bdc9e8107f1859acd2674fc72c6669a3465556f90269cc30b0a8f53563378ee016a7abcb5460d5371b01754bd7373c2314e2a42d98636112f3cbe0638e513b38d4850afd6a1d3d485308181febd88b75f532e4541965e0bc592885fd1c1b3108c33f74725850617b526ad4f2c8cecc19b0a0ade15057c90ab086c26cb014bff92988903bafefa3c4c96ccbcef178f988a40d339db324257de69a119125c52a4147360b1274808299446ee768680170457acef18814559996fa96b418275e031199e0d578e86c946381c369ab839b1a75e9d6845c98aeca24253b3b0f00ec7e92cc6f6a40a4d8b04900ca3e78cc7a5c51886e0901a908bf0a08947e3b524f1c606b055451ab6eda2bbcf832510b3075e2cb0ecd493b71102f4ec69565f96651a3a2c3b738c2d55805798253e055dc8508b98822e6803785130d22e494b50025b0ccbc69667013c4ce4a140c2e9ba928d41d7fb5237da8c5ac0310ef5007b2b0c6737bc17a747c5a2c1f3c1166bc2b0ad7aaab1d870e54694c1ca293665286c4eaa35d34bd6ea7aacea04871c257cf63641264aaa0db4f65337274356f71d02310a57e44d23ec6b4185bc5cb45a65d3b592af3138216332060264a6e53702d766d0f4a0f14f70b75b780688591cc414283a59ad2f84d665354d71c2aaa1c278ab6c8ba902283b286f82761906c9b2796595bf5ac01455ed2b43607207a30c949afb1ba5c50659143c98237279003ca820b4b5963b0882a088ce09c99f4a6368971a7d6885237bce28580e2ec483fa305fffc0aca173a89cc41727a55d4e29a8c410b3fe851b3d58b58c31920759ada529da162cce47618b2f715f3658d71f5455365c67b04748b371a5a96b75f342cc4c031c713c04d2b6cdec0cc92b7596bf4a2a0c91537a0c8174b3456489d2db70d3af2995c4830245120e9411e92ecb2293700973386983a0c6591cd5eaa34d5cc00fd672d20a604e78696d5542646c120e02c8dc5162630e71465accbb47cc0ede06feca295830091000bb220cb2a41777647d6084c853cb69ab9ab97204b14b31bf4b1ac577a76110f5cd17dede14d095662b5d12c931b1404d3b0ade5b216e69fd480a9335abd312065e187a03891a4e9a91fd01a57a8e8a1ffa075d8e68152ca058a876e2bd80e46c22af8360e3734145ee882cfa06c22167f03e103aba731e7526033ba815d9c3775d311f5d92a31d552d89bb291663ace4b5916436e1086b46879950de89d453a666f0b514ac31efe398acc52370e27c0f681a97b0966a3a14b7e45bfbe688b5a1b40d9f515b688218ef95a9ab211ca429cdcd6a4913b2ed87c9f65d64681b9bed10c09c94b9c0d95c75b69721b119b95583eacc884a56ac09bd3bd6f197a0efb6659e89ba3a019ee12b8ef056a44f174f0219f89616330d2bee1580669396009895cf9991a49e7bb89719f6d340bf33c427fabb2a5c96d81c42e18a96470360d96279bad640bdb41a40aca9142275cae4b95da8acf98bca3456c574acc43d3d72a2c6542d1a25c554a8439d9565af29d8617a129d5526cbb30aa578643b133a0254d6e22c33ee80564e7424f0842b113636010c566eb59f9923a021b2a19c08bfae521e44324eb5bc9873846141ca7da45be4f8619b334a7cf52093b2177f4a71ae211081a096071f958277555709b2f459685ff22849a86375e157258d24563b8028a728c5eb0bef79495c1c53979880930539227c188c2027681236439085b41763d6378a4ea0254a7416473e67d49fc5dbceab81e56a30e2ba61efbc97367c06496812bf79d449492f96682c2716053bb54dbf1bc22f32e6d88c2a1947bb599a878b84f29021ead84a763eba7b9f3422466836bb6ad029543041115d638552cc2017a84ad4cf687daaba75b0c0a73a95f39ecc758264d48063924e9a0e793b5275c7090f9655c2325a3ac19f9a5b0327b80f220b9122583f5d908cc21c97083227b568c47e58a2a7843d2141411b08f9cf61deb4a9edf41617fe26bf9c519d0cc80cd292585dc4ce5a90339216a6f876206732af6dac9b2720025b31e17ec47dff321b06107993a414f1509839886bc526f8051c4380c3faf4b64d7e3c9f9a76e9d440a67499322b37c4af9b26b2814a2b8b699ac0adcb25835d038b495978e2446a1c33d98269a9d28c1cfc89c3be645ae53b44dd4709587c53df10c578562a91b55ca04ae8530c6aba9c16cbb0684385704c15d302c1ad4857d0d1657dd85c536cc76f228641899188b9222f2b208d34222276a3c91628772c6245433a0ffd16b0812299283ac8d5a36b868b9fab4189aa64a0b90b606e695fa542b8c7c3ff0f0a46d5b00da78236d518d34756a2f32075480a4c15b7c27cc8e4a93180e6b5859120a24db2daec61a479cb039d4b9e6041e816c96862c2b1d616748444b4febcf7a129e6e7817950c77a3fac386fa787eba4157b720fc26629842a145759cc8fb652811a8a3cacc29571463aaa7e1033cf0b4b2275b7d2034a48f49576975363085b304c0426ec26fdb17ca8fa5496d794778c49b4f74a58240bdd39c2fd6628011837451cc4389a43f3bb20959928b77394651e4c2cdc44cb9499def6b366d15550b41ac89707e57b271aad6113ef7a9b1575c69e35e4d75bcb0333e89c091603b7ea5973a277672a1c504cc2c45022906106b97d4fc01e98a876be91d88f4c908b892b5cab99fa878dd1b3b1688976c148bd0450216656028d9c2fcc3bddab2ce6541810cb84f4af414eeb863b7c7452bb79a96e790cca35bdf05b4c3b059801b2bee373da6a0c3df79c986e71a6788712fc50aea51044c2b82b3d201ac7a1245c96767f0cece2b4af175329a4973696c5deea91075a6b8ee2c347d15c89448cb48d22126d82732c1293288ac60bb3bc3ca1e208ba71054399fa4a5d1db7389379600c128b0ec1803b88de90369903799cf5ca0c5ea0b012b691b0a50b9011aa412509d1abf24e252e9d2cbb315361977770ed77310c1705e46b06a5c1c35fb5e5c9a8066d2750b388855e982bceab6b5e8018181b66717142cbc3729b13e2b34205fb06724ec13c3c2977e346e50a79498f94756069693989b77432f8b5ac8d2b06f2e227c4728288e91bcd6cac439b068e2017ce1c808c74098ec2c099d81b9dc6ab7e780c0c1669806e3cf34a1c1d5d002aa1c9301670fc4e45b64c59481d1cf6446468806683f57b3bc25b032aa40d2c188c5a2a7d47b41b4753d5f7a3b22bb70643942d6c35317f05e6acbb4f6794b1b0c3bd47893a7f9cbbb61c608068054b385a9578303111972e8888c6427afe099a1a07fb3879b821b25fd1699ad001f51b27acc5b2926ab2caeaa9341e1a627493f44f561eea57745a0764a840963024ff6c070ad95b285a74527fc3da894c06f7bb5de61a012547f87c1517b9aa5575a1ac9a30d858c912ba096cff4a24085c750aab463f8b956fb837ee300470452c6431d128b27472b5cbab268924acedeab3e7b02b2b201a44e99654910cdc8d5206496637e88929a1ba4436272f6b5ce41533450663f7a1a9144b5400d727fe6342c6cac6e2c3312015b571585303967422ed8c5d4b75e4f203bf2f86cf0370aa9324c47246a27d9076559c906ecbbecbb20e020cd9b6328857832ad8400666b943f8418f57408251b91ce341a2f63601dc751c0b301729caad8425f717250d5a249b1175f9ae8a9dcc8cd149b9bca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24647a136f20b22c63afd2b88d14fe7677cf5c2b78223a587068377021f6edfe9b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +expected_public_key = 5fc836b5e569623b3a02227b1c21a206e83a9c5b3ce1594eb9099174fb34e5b5c333e510ac2668a704548f02b47af007c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95930a65c2344510a450b9c59c24326c16cdb447231a026304bbcc9823c3a218989ef2352d445ca22b6b03186407d7973b4117c2914555acb33b4764515c4a37108306447f9eb200f8572c8467a089b824769b7df39967289a93b7f55e1a8447f862c1528c3dc4684daa9632417622c950b617e1a074b3b7ffbc23576a63857c1f386a0ff2a151652961137237ea346e691c4dabb45562653e26a806c6031368c17421747ffdd4725c02b40fc59737a75ba713311230cfea4c1be8a7c3aba9b589b6180dd701c4e704d69a0684a33adf1802eec804f44c2923aa8a577c34a4a678dd2446b7546af0021df00a431241509f6117cd32177da708a2d8472f8270e96a4bd21091f5d28b13fca8f7e2abfb57a9e4a522d95896b5811686e5b23d4577ace10eefdb9e1fd84cc51918d592857526c83f51c60d4210d92a425d7340a50423eea17b8be67325a33539ba09bb734eca0a4c365170448a126721484cf947933cc984cc7662da79d65601c3729881e9b4390a99b0ea62fea97eab9619d71b7bc282622ff0cdd0e72a3c8acb7449153df92e672c5c61b40e04854b0b523398a2634b727dae3657ed985b550849d51a04f3318892f7a4a2b73c8c301e2cb5aa60e5438d8962d8a36857f08c075948095c86de6bc34e35c8caa04772bab591e0137c4aca7c34598c65102e80ac0d677511b854a8829c08ea7766eb04c6047612aa83c17ac38a545a2863161ba3bf6a8005e9fb560597162ef1299d621b62c8a7b8c08e3a693faf0607081c6da8523805999e8b97056b5385834726bd7995bf6217c5e70863036b81c297eca1995ac48b6b7ab0ea85c3667370fabbca8d4c2d758a80bbf07839cb85d9428af1eac0d7c083567a85d13515ff399be3f5931d992c953a664eb8974a434270b47d3e635618eacd0989a15eb065348c34a19442db928d1e8b2b28a0858ed7ae8a5bc38087cc85515a344b4cbf529d7560590b3bb56de5331945c0c0b21d5bc8751d9120182c7348305edc765787ac9b784ac4bcea454e6a4c89132e6cd0a477f3bf43da356b66a8bd0980146b5d5137262b0062541960c0b19123a549ddf31d1c188171238259fb661e17363e12c57bd873c643222d014a2ae15cf6112c7fab407fc12b32c12ac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c699619d01b19919263102f5ef2a0c110752d3b34fd489b7a328638210307c6cdacfc6ada87190a98b0d008644b91aef65618507a7f59b89e7eb36998d26befc4b723741e0c35cf73e8041cf51af9832ba43b8e95e368974c1dd61ab65e24a87820cfae295d0ceb8bd6109b85174c80869716a6016ac8190df173ab61c4d3c4c37ae11593ac9a09c210b663bfefab5eebc30deb27cd25a8511bb2ae87851643b50d1b4ca5bbc66d49aa409aab9e7f3402ffda93abb53acd45bcc9978200e94cd4d617235b52d9297d4cd374b998698d82948dac3dd780c9336532c499c479756d50e9048432ce0156cbbd9c85f5ca06ab57b62981494622a74807cd881a58ea10a6e5c885fad611727441dfd52834d58b6408c7d06209bbb224a5d01eef9b491d13226684baa5a1a771971dd112ac668108963bb1864aa8ab7913917c980f3ac1c435457684ab758569247c98286b2cbc78263f1cb88478a931130b496b12f7428087162b6d525a8216061a3859a7a470cb9b88bb0c8b1e21ce4977a73fa5798cc814ccd1aa84370fa408a83e73be1e12511a59486c49c6afc1367b85231f47cb34c1a8f9a963cdeac7fa6076eb8a657e647466fc82663884d7c70eacc760db1b0be0b30779c98396aa3f2004976c8493ab90ae60996056668c8c2cb9065b6a2580a986d9853c071a02343b8903c0184991e2a71298269a17f64bbe1b6b51d0b299703a04a22e17c33b29634dd1766be40357f33a000a52597a3b5e4852473d886e06db52b7605df5fa4e0d5a0f291b5421e2c1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818db252cec8cb627455d9f792d7047cbe98b74eb26c6971be56b7219df092e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_private_key = 96d9c668915384c2847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef7f405c2911777fb1e2f44721be8cc326a80e524486a16a083527e22d51e4ef624b02625fd6a857bea2c0590a3a4e39f0e041b7284bcc501201842345ed5ceb097a5a5f730ee53176f8acbf9e03c6dc4a069718dd64c47e1d17323d29acc630db2da9922804802cc768070245380cec6672f6a5a9d14e4012bb13caf8c320a320ed63b0591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718a421d3c45bd0426a87589362e52953822cf785802b2c6aa441adaef93dc6451ac68a9867c9b9703abedcaa540146ba6dd8acf7dc317a82a4c1396267032fccb53be9306e20e4713b82842e03b7fa984e5827c441e293352b2e2a51566eaca8d9c4206000655f761729020f7ff9b230d6c4b986bc94551175a8acc7e2a2c174c500666d3cf021a9b40f1a465447291f920865ad16240309b5c838a2ddc5beb8aa11bf987aa9d7c082e8c55c63ab01d0664e545e505b4aae50606136b6b01499a5ba10174852224ac6bd242d5d21758c4342f9a02a3d46a9a845112adccbb73488cfe3055cac398b0245c467b94eb342e1845969d70511bc7100f886308cbf21c13840bc17626ac93dfcc4eb22ba18f62b15b521539901166598f25555c32587637a341017885af1a6d1841aa1c747d918253e1c873c2ccf292bad45805d8946b00dd23cbda03878f66357d175d67a1b743c1e5428ce90661067011874b062e9ac8a0f726b55b76627c53338549c3f2605840a11d5606acd104bfadcb51253af718835826628235878d6160f15033844d76ae946ae6c240053c2ad6c3a3d72e721d9565a6c79b56840cc5a878c6a4033bb9c88dc43b130348082e41c269cc0d3b05ffe356b5695bb01c95f8aa9c30e50cf31f11419e13acffc7192b75948e06a68458db80a8f71573b6edc1513aa5b060cb77b12c62761bc188159a49c95180249b3e35c3100635012637cb9cf17ca9936787aac954bcfc655aec8b4215861a7709f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61e6018ab30146d60a6563b2f980acf66186fee70a458750cc62c433e651f447ccef8a773bb2731a866832ae535f0d82e605371f6b35fd6fc1188a52080c609bdd8748c321ca37190321b286c849d35224bb5107d83e2827ef0c63859133852630b237247aa8c100678e43618289239ef19c99aa6b9156704643285bec89f0b0c21f3a091e2063e5d3029f52c33af97529e701298d3961f492e6b731d4e2064d034533f4611fefb64f1899ef563ad71a52e20b199f0d80c557cc8cedba3cd1746d3a6ac2e697637f08a43d681ece3769c8980c76a26adcc585eb1194d28ab163aba5563a5c7985720248662bbc21470022ef4110b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53a020928f7a55981b520017bc06b36d10a21433797c15124e0892a81230bd6bb4774d46f73b874602588d3f8966469194041bdee87ac54059458b19724949e7998ae8018755d491bffda76a70a64eff902a4281734a7484037c739b7bf71b658b779cf6370420d2073fb820bea1b1df29c3b12c54e6967a9faeb87bd8c0d3ffc2c1b821b42584b97a935fa04b81252ca53333bd2aa2b7f6220742b366f2877e793cd948b7c3135457e46ae107c6e74104159a82914a7059f25a2737c1ddc299add2b43a2f6c25381058476b01a14468ddb6767d18c1049c676e335eee0a23b2b14ddc7421999310396497c642e5f30003d18bc76dbacdd06bc73f12415bc3250dac8bdbb4426c92430e00bdd0234c1e3680dc94d4c30c484d610463a48cd6864eda31ba63c7880371a854551abaabdc14c225fe59265726ad0746b30f85127d12158f8181439a68cc177dfa817678b08b5a5c1b9f75bfdf0c7ba019a92a512b2ca5e91f2a6e1e24238491d3afabfe279a9bdac45971b80f187730f518194ccbd327048c9fac4b75a38cd9432d1074f4152398ec4b2b0607c9a9bace0d87a36827bdcab03e55a9b9667afaca3395ec412872427cc230c4b04bd17c2017ad39834a94b98e7b75e47be158627aa6270ddcab77bc166d2b969eb4c34ba0000a13861c4db47db85839828c6eb2074425816f026096463595fc836b5e569623b3a02227b1c21a206e83a9c5b3ce1594eb9099174fb34e5b5c333e510ac2668a704548f02b47af007c237353a468f6dd38ee8878f35fb7d7e63a3b1867b2b47bce58a4e95930a65c2344510a450b9c59c24326c16cdb447231a026304bbcc9823c3a218989ef2352d445ca22b6b03186407d7973b4117c2914555acb33b4764515c4a37108306447f9eb200f8572c8467a089b824769b7df39967289a93b7f55e1a8447f862c1528c3dc4684daa9632417622c950b617e1a074b3b7ffbc23576a63857c1f386a0ff2a151652961137237ea346e691c4dabb45562653e26a806c6031368c17421747ffdd4725c02b40fc59737a75ba713311230cfea4c1be8a7c3aba9b589b6180dd701c4e704d69a0684a33adf1802eec804f44c2923aa8a577c34a4a678dd2446b7546af0021df00a431241509f6117cd32177da708a2d8472f8270e96a4bd21091f5d28b13fca8f7e2abfb57a9e4a522d95896b5811686e5b23d4577ace10eefdb9e1fd84cc51918d592857526c83f51c60d4210d92a425d7340a50423eea17b8be67325a33539ba09bb734eca0a4c365170448a126721484cf947933cc984cc7662da79d65601c3729881e9b4390a99b0ea62fea97eab9619d71b7bc282622ff0cdd0e72a3c8acb7449153df92e672c5c61b40e04854b0b523398a2634b727dae3657ed985b550849d51a04f3318892f7a4a2b73c8c301e2cb5aa60e5438d8962d8a36857f08c075948095c86de6bc34e35c8caa04772bab591e0137c4aca7c34598c65102e80ac0d677511b854a8829c08ea7766eb04c6047612aa83c17ac38a545a2863161ba3bf6a8005e9fb560597162ef1299d621b62c8a7b8c08e3a693faf0607081c6da8523805999e8b97056b5385834726bd7995bf6217c5e70863036b81c297eca1995ac48b6b7ab0ea85c3667370fabbca8d4c2d758a80bbf07839cb85d9428af1eac0d7c083567a85d13515ff399be3f5931d992c953a664eb8974a434270b47d3e635618eacd0989a15eb065348c34a19442db928d1e8b2b28a0858ed7ae8a5bc38087cc85515a344b4cbf529d7560590b3bb56de5331945c0c0b21d5bc8751d9120182c7348305edc765787ac9b784ac4bcea454e6a4c89132e6cd0a477f3bf43da356b66a8bd0980146b5d5137262b0062541960c0b19123a549ddf31d1c188171238259fb661e17363e12c57bd873c643222d014a2ae15cf6112c7fab407fc12b32c12ac65a65cfa8674715617bbc6e0f96a5406c8a765bc35c699619d01b19919263102f5ef2a0c110752d3b34fd489b7a328638210307c6cdacfc6ada87190a98b0d008644b91aef65618507a7f59b89e7eb36998d26befc4b723741e0c35cf73e8041cf51af9832ba43b8e95e368974c1dd61ab65e24a87820cfae295d0ceb8bd6109b85174c80869716a6016ac8190df173ab61c4d3c4c37ae11593ac9a09c210b663bfefab5eebc30deb27cd25a8511bb2ae87851643b50d1b4ca5bbc66d49aa409aab9e7f3402ffda93abb53acd45bcc9978200e94cd4d617235b52d9297d4cd374b998698d82948dac3dd780c9336532c499c479756d50e9048432ce0156cbbd9c85f5ca06ab57b62981494622a74807cd881a58ea10a6e5c885fad611727441dfd52834d58b6408c7d06209bbb224a5d01eef9b491d13226684baa5a1a771971dd112ac668108963bb1864aa8ab7913917c980f3ac1c435457684ab758569247c98286b2cbc78263f1cb88478a931130b496b12f7428087162b6d525a8216061a3859a7a470cb9b88bb0c8b1e21ce4977a73fa5798cc814ccd1aa84370fa408a83e73be1e12511a59486c49c6afc1367b85231f47cb34c1a8f9a963cdeac7fa6076eb8a657e647466fc82663884d7c70eacc760db1b0be0b30779c98396aa3f2004976c8493ab90ae60996056668c8c2cb9065b6a2580a986d9853c071a02343b8903c0184991e2a71298269a17f64bbe1b6b51d0b299703a04a22e17c33b29634dd1766be40357f33a000a52597a3b5e4852473d886e06db52b7605df5fa4e0d5a0f291b5421e2c1232553ae2472682a7352775c6ca4b189f948012c417c8c764b8c818db252cec8cb627455d9f792d7047cbe98b74eb26c6971be56b7219df092e4cbae163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca1cde599b2dfc69d59036434cc0423337513fb9506452bd8f42bb82661ad0065ac95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +expected_public_key = 3d8a9e39ba19ea979ab2c504335c03da056801f4c782d95dc2e163a043cf2db760edb7772c50cf5a62bda4742d2ea296b121094ab5cbf017755c74b6465137a1d32f4ceabdbf34a7471b45b166ad05ec69238b030c31485695a9cd615db68c83e457222d85960ffa8ba6c8cb5721acbca1a7b09b155a555f406a660c325c6166233c0500a0475931b27481a015ae521c7050ac2f605f032899ec655f0b662d7b65a3b21680d1b53ff554987a99258dda8cc711a18ad8917f838cf0a16d4f663bffb33ae9e3afe97b1bc5f9b1a53052f8907145440664bcb5570a368044151b0045515b94b7b8073615b2889a280e59940131ba50b016e0b8c6df2b34c29023e0773a06431397a68580c47610b50e025b0fbf374c40c1ba82a11b69fa9b6e522d4bac7fbe737a18085056bb7f7caa2c4c3bc5b6401f06b102a3b5673c7c8f1cb269438618f9717640c76a4f058ab864348f068691f95996072354532f3a3b6ad0e1448880cac03b6e2a84717158339c063147db0c586032b7d10a69e17c1b62c1ae5344483676bfe8928d637aacc4b613f24d7e2a46de3449f17b0062fb209cd9631160ce38a95361889b167cae272cb23f85bf34e14c789472974a176c567756c1c0ebd9905cea70cb88a55c68b476f877c605390ee1274c07cb95939c9babc97ec51df82a9b7d0908ddc3434208911142ca9b8620694bb3aa9accd1bc236a9a89547a26e44816ce3846f980c893b29e6e6c99580c2d0a905643f556f592ab03228cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77d40182bb2524a87e1cb511e9d591f06b91a71594dce26ca8b20450b899e22c679aa7abf5b178b1637f998502f7c7b4a03974a840c9dd041c43017d8f7927f94989f2a16a1f7cc9b09908da388a68b13f39fba43a391d75c76148444954063d9163b6ab1509b03863dfd62d94b59e849cb545dc7ba58502f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2c40797fc29955960dbe618cc5d21eb9ea720d77c3f8b3c680974fd8c474f9d588285609abd4166a45cbab974ae884c7061c6f129a1de7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb3f263bf774623a37bcdda056ce232b2b2b4f2e22f6eba975c933191812c9ae55d6b7c6c76c10983b02462e220bb90c946573e3e2bb87540034f870fc69b538780090c3b89c18645569b124c03680dfc10cd3050b33c16740c54916c5ed1604ec092793d097b94b4ca3474b6d90382d5cb21e8bc8488451af2492310b7239d9a46f8c868890c7b531834b2bbaaca7ac34651b941d32477193cde0a3347323b77ca97b997c429a2544a1590aa8252d6e0832e128262284908ab785543bce3e6aa43d4005b469eda56cb28b45c44329cf7f79cdebabc3a9c6558997e04f980c562c852a103fb40ae24e26a8bc8bf014690b9085f6e7bb947f2ce93550327a61900aa954cfcaaee412aee44cad3958555d18b59a0835c015cebc77242052f13a780bedacfcb9998df665a1ea24887b570f36198836c6c57a95de6349d031b2b33a3b6d52292ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c6890c094b625a5b747b2280fd300455739af8d97fdc39cf741128c03283f0ba09fbe19a24598e143b5a856a5b41334839a6188e769f78aa24673b3f69c51ae2c5ae98bab4b0254ce8c85204e6ae38b80a2f24c162427a66b09debdc8235e96d25e96132617dff682cd03896290832e3d7b5959331c7025868803a0c292ae4068f1ae8152221a4607bb9e4f94a5b98701e027a8ad0913b0bbd0ba551b00b0eebe302e5450681878992a616aef08a6c16175a5c22317ccc48200bc7452414080adf9216989669a560caa70320938c812ad12278588965525538921e5920580516156fd563fc732e37e5591e000b4ed9b93211579d21cde3a951395a21289576aa5c0b0c87bf36acc28c0ab51fc86da8cb00d23c40459088a1506d8a2168f94a365fa56ebd751a51c84342931a5d569793569f8fa21168ac2df9820ca3134704c533a399219ee79f4571b1152c95333c135e442d5c5984e55516f958ca38927773a2aa526b89b79522348c1244220dfa84c6778466d2a287a774141b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_private_key = b1c127d24808fb2b9922332832131c4fd67fe8a1a070ac8d17100bf9f6291efa0bc8114d98f65c8f4abac3ab17b4241deccc37688b881bcb68503b54379838bbc100b5bab306327e7965b694644c470a5148666c7fa89872d39aff60bc533c83f280abfbc26f073331ef40b694ab25feea5b2f55196798b70681caa21537dfb5746c66129775852e5850f57c2db2e8a0e90530a57b387b1c429101d04096c3e0bb6e9af19f83b1b0b74c47bac678b0f2269798573fbca5d8e687965b13e495827adba63da8a17564a3e68037b3a4991993401c1c6b149895ffbc03760c13595035a713140eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685205b08d44a3ac8f8948f2b7bed9cace27ab6265722d8f2950e0c9ade053a4c4ca8e3f80a907a39e33db78e6065fe9dc050a5a730595ae5ea32e38c512edb79dcf345f1d9c238a1732c552ab8db2ccccd11822972896b323cc43aa03633617f82e89d63d4a1003cf9c5ce3379b1d53a63eac57adbc91510316acdc30fd74a1a2e6c23584ad1cb28444f9231661079b0913e20b3278d8a2e8b18556f336cb750694066b6c82c5d267a903b624cd440d8e187d9e438d178c8394706f016b835e1522ab6904f80cc24358b7dd3bb271039acc174164021e8a522fac473054d5b4cb3bc64bb107c6b637cd6360e312a85a3b1e3d2b64436a87e81016acb763a23ca9b7463023148b0c4888bfb18d9441841f723b9436b77b09c79fc714385a3ae97b5bde0a2a0c541dcd2b668c696281389ec270bc6d088fc42506cec85bcb4b611342af0a61b1b9d75e0df43be293cee6eb0413363716ebbc48ec6c361a48b9d871bd5742fef2ab286094a92b508cb794f2f69a8ee15c2d748d8fca8cd2284719815e75b3b0df76298e48280bf530e09a34d166cd5379777d472f0994ba8e5629ea7691fb973f45869635b61b277c375606b911aa1228271c85b047942a52187bb231412b50f5be423476720240e62b9d3cfc5b7af5ce9fb38e03349063741ade945e994a2d6492a92b1250880318b9b9ce845ba29bd3733228ae960663050888bb98a0fdc21d6fb34cfb5c1af6d9b98ed6ae454c09b89b6067401fb30a17dd331a845c713715b5bd4a087bbc14cbbc9d2ea83d0f9b0d56d939d01b7d590b3082d2405a20724e2c44b5123bc1407b11da3de5889ac52b7b7821c4af1303d3959eef3888b8847f3e0695b5b844e8e3c221718a25057e707a50e0159af4462bb1d103b9057ff7fbc1740bae1afa44138aa2b7e3270cf80a6ac745cf701040c97253133ea195648e929e6c6394940b6eceb18844f1c862da6597a46f64e0cb5d2803eaba4a08110a011a32452185a6425d9d44b43463893369514957592f519c22d2b06bdc762c519d5cb84e9a68456ac60aeae85ac6453de2bcc103e32dd509309fdc08e3b3698a193d83d62df74719703bb5f8cc5db7b88b80110d74d6949d00469b840ff7fabdd4c0cec1a097a6117c28046b06b82c8ee8204296428ab703840acf7f3333d742726b114d3292b3154b2c4095b6d465657ec0780c488a0c60443717109363c45777271955135e60b46104bc18bac09a18690b37c8078a226455320ca539f57a0706239e62716fca94ad8fc2c1e5834396072b134636aeac2d6a1b91b403b070d97c53c2c91784438708bb2761cbd4b99083096610c53ed9354f459c2e91f47bc8220f75b367ca8a8670f45cd118bbc72baf225274d2344343a51abfac2aab439fe5d2207bb1bfe2e54e58688aca733846b7c68d12a87b905243a0324698aacc579260e94fcabb28da1c8b6887ce10c99c2357bb92091ce1395c6ed345081c8b74d5a9bc961c9d79afe27a2894117ffdd9b3974526d33c2d5ff5757598853ad14520cca34b817d097a7cbdb7888b48b67f3a8d0ceb89aeb6374c97b130a658b10c1f78d38241120a3dd7a66cf76fce43a6fe9c6bc6324a64646ae09a2f948320db54177d2a35eee87918aa0874a2ce286528ecc29668d7b53591942c70206c63c6d8db92aab03053f81e166b5f40d17d09b3760c944cd24c5eecb7c780b39608c318ab3031f89559ddf76ced962c035b9d7b7cbed0985a2f0b43ad8849dc5a190c62a131e5bfac2c7c11eca951b2a19674315b811e09847c49339c3d8a9e39ba19ea979ab2c504335c03da056801f4c782d95dc2e163a043cf2db760edb7772c50cf5a62bda4742d2ea296b121094ab5cbf017755c74b6465137a1d32f4ceabdbf34a7471b45b166ad05ec69238b030c31485695a9cd615db68c83e457222d85960ffa8ba6c8cb5721acbca1a7b09b155a555f406a660c325c6166233c0500a0475931b27481a015ae521c7050ac2f605f032899ec655f0b662d7b65a3b21680d1b53ff554987a99258dda8cc711a18ad8917f838cf0a16d4f663bffb33ae9e3afe97b1bc5f9b1a53052f8907145440664bcb5570a368044151b0045515b94b7b8073615b2889a280e59940131ba50b016e0b8c6df2b34c29023e0773a06431397a68580c47610b50e025b0fbf374c40c1ba82a11b69fa9b6e522d4bac7fbe737a18085056bb7f7caa2c4c3bc5b6401f06b102a3b5673c7c8f1cb269438618f9717640c76a4f058ab864348f068691f95996072354532f3a3b6ad0e1448880cac03b6e2a84717158339c063147db0c586032b7d10a69e17c1b62c1ae5344483676bfe8928d637aacc4b613f24d7e2a46de3449f17b0062fb209cd9631160ce38a95361889b167cae272cb23f85bf34e14c789472974a176c567756c1c0ebd9905cea70cb88a55c68b476f877c605390ee1274c07cb95939c9babc97ec51df82a9b7d0908ddc3434208911142ca9b8620694bb3aa9accd1bc236a9a89547a26e44816ce3846f980c893b29e6e6c99580c2d0a905643f556f592ab03228cd1585a19f4b82fe9c1d3e4acb41b66f01779ae136d77d40182bb2524a87e1cb511e9d591f06b91a71594dce26ca8b20450b899e22c679aa7abf5b178b1637f998502f7c7b4a03974a840c9dd041c43017d8f7927f94989f2a16a1f7cc9b09908da388a68b13f39fba43a391d75c76148444954063d9163b6ab1509b03863dfd62d94b59e849cb545dc7ba58502f6c5cd89db38b2cbbdef23bd191a57b4433872eaaad5d69b2c40797fc29955960dbe618cc5d21eb9ea720d77c3f8b3c680974fd8c474f9d588285609abd4166a45cbab974ae884c7061c6f129a1de7b33d819c795c5a4dd37838cf499a09387ead56466cb54cbbc865cdeaceb3f263bf774623a37bcdda056ce232b2b2b4f2e22f6eba975c933191812c9ae55d6b7c6c76c10983b02462e220bb90c946573e3e2bb87540034f870fc69b538780090c3b89c18645569b124c03680dfc10cd3050b33c16740c54916c5ed1604ec092793d097b94b4ca3474b6d90382d5cb21e8bc8488451af2492310b7239d9a46f8c868890c7b531834b2bbaaca7ac34651b941d32477193cde0a3347323b77ca97b997c429a2544a1590aa8252d6e0832e128262284908ab785543bce3e6aa43d4005b469eda56cb28b45c44329cf7f79cdebabc3a9c6558997e04f980c562c852a103fb40ae24e26a8bc8bf014690b9085f6e7bb947f2ce93550327a61900aa954cfcaaee412aee44cad3958555d18b59a0835c015cebc77242052f13a780bedacfcb9998df665a1ea24887b570f36198836c6c57a95de6349d031b2b33a3b6d52292ee853bd3e77b44836b28aabaec37872708cba8234827ea922ff698bd4bc9824491c6890c094b625a5b747b2280fd300455739af8d97fdc39cf741128c03283f0ba09fbe19a24598e143b5a856a5b41334839a6188e769f78aa24673b3f69c51ae2c5ae98bab4b0254ce8c85204e6ae38b80a2f24c162427a66b09debdc8235e96d25e96132617dff682cd03896290832e3d7b5959331c7025868803a0c292ae4068f1ae8152221a4607bb9e4f94a5b98701e027a8ad0913b0bbd0ba551b00b0eebe302e5450681878992a616aef08a6c16175a5c22317ccc48200bc7452414080adf9216989669a560caa70320938c812ad12278588965525538921e5920580516156fd563fc732e37e5591e000b4ed9b93211579d21cde3a951395a21289576aa5c0b0c87bf36acc28c0ab51fc86da8cb00d23c40459088a1506d8a2168f94a365fa56ebd751a51c84342931a5d569793569f8fa21168ac2df9820ca3134704c533a399219ee79f4571b1152c95333c135e442d5c5984e55516f958ca38927773a2aa526b89b79522348c1244220dfa84c6778466d2a287a774141b9b5ce0443b5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c592a50c7a070b3dc7e107eb1e8b96d62305c13327d729bf9d97c69f1fe6eed2b52e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = 690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +expected_public_key = 355a23b704c6448bae0a62c2473c1dac43425852245faa8514b54c2ed51305047e5b44618f166cc329172668306984151c31cf04a9864267a1ebe30faa133fdfc040adc3cfa49a3c0f4ca85d7a52a72b71f217278fa787a2e3047922bd339176cbd5049d498708d65f2beb4ff3e544f973a4b9e19e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd39e1630db0b5fd819dc4002297a205898108050c9365014351f38c017564d6798a16382b6f34907a4850a0183b27243ec4123ce3b00cc682c1cb8a9d97845f5d24b5fc35c7e088cbed62910c4050ea6b76c88c87f9577941f6a5b3f2b614c94224c26a36a841c3b40469d2c0cfc366ddac23c8c2bfc401ad78c758a6cc1684d1ad400bad5d88417503ccf169481fa437e4a8cf78b907890cbbc1ab9f46178ee2dc6dbcc1604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11df700044a79a809112516a88c2c662965a2da9b996ff92d951337b4b9c11e7947b14212a6f3cf19d2c5d86cab5267a1c8065ec045517dc9be0783194bd846dffc50eb723eadf08ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a0128d52a34e27610d9a902d4151105409be06a11fd3f73c88b79c9ee630a98105556b777a5bc680a803f5a7b603f16643ab0a9ef7161861b3ecb5636a9529a24a59f17a389b61aff5e633b863065f37789a538f8353b80ad75b4ee876a6ca363b6679680115f4b9857bc88b845510027a0e9014621dda9a31e12222522557f8c86d29a499f0547e35a99d81b1a02147dfa3c45beb8a3026a23fd20297d20e33503cd49002a9fc7ff8200ae433b921bc93cf10209a05242788908f71bae849518ba305eef84597f654754a7808d81f2cb62bbb282911a0c5636cad75b53b454a5a923a5fc8e956c9cc527bc04b846b596c9b222a953db76485c6486907f898f6835a6f315ae20b57d3e56953170ea586658b9178c638c9c22c941097838af0123a601d0d4108b2ebb53b46233408ccbad9597633440ec1aff61743f0371ce62ca1977aaea8d98900f0016e5a9248661fbe5c1a4d261c5426a12715af037a5ffdb38b8dfbc11ee3b4edf289c3ab3995959078091e888ac0107467bfda6f3d35516ba7404a4733c8ca4adb010f7399ac5f14c2cf992fa812cf72f2c79750cf52e648dbb8c3b14698bb517166bc1f663594eb9a6c476c58bc103ea7f03f37205c5c355a2633b9ccaa829e3366fea63932550617aa96d267cdf4b98cfe3334aa0a5c7600ce6ab6aaafe7cfcce4bbbe2756b7cb10d6d6cc8c71b32a04cc652c01e2b62a73497dbd9a46eaccc382c5903fb405d950462ee6c87d2631ff97adb38939c4f284489bb9d1072821c108886842f5c1b402aa2e49d37aaae13b7c14b5a748c2dbc45bbe5bc2abbb929b613767a720ba572ca63c2080c4547c9024d2f451f25973f064941e814e3ec74b4c1770542b0782c67580b7a695c2ab29c95da2c18e4563a24101b11084586cf9a42ed62a2bd1570fc175f4d5bf50f8c4a196aea1953199143efb5183b3a905510623efa47c4a52522787723af5b5d05b86d15126ec6ba2201120b5a527324a9895f62959e24aa6f8c95d9001e7757fa5b3a80085bc48bb0d34388c0f6cb647b0a7cb992519922a730865a4032b51708fb6602b08d144336b7c7b65730d8677399436ff5711eee7b935d67054982472b96ccfe7279f1a673bd61757f7b951a5bc9c4b7e52c11a09f350737120e0923f8c1a2989f19a6faa06105391b39b266d9c768c658d56fb59f57020e0d17feaec496f729a810821fce59cebdc24e8b7cd3b869144225ca4b5a5c72432738ba5b939c64cf338021181765891469aa7af34a628950165a1328cc4c2b6874498a8205c675214137e47080624e250521ca34e394e829206df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332ac168abca2597ba39320653e8338303552b419c84ecc014ca3006b50a6f74b8ac57378f8a06006841f972b703a2b0daae868698b778bf6984dbc7bab537b29ec5462463295ca1581e2a60f5c169b494d0b7793af3313fee3742d84c1d20b6b47877320e25aac270e3739b34063b62fc171ec6a6ba7b62faa650496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_private_key = eeeb8866b17cda12a45fcc6f9d05afd103835147647a7301ee071366398473c8103ab3b064e340f4f9866190acede02473fb49635bc38debcff0f34c5175ae0ec025aaf19cccd46d658c2a6ba62b50d1452b09c21b430ee9a3ce05d36a8e1aab2bf0185f35664b4999cc8c0df049c01056af6aacb025708c184534f1172b28fcc94aac2fb7012e20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c7f710f51003777b060f8db5fe06c3520d35e97f6b5792b0ac3304349387b637686cac1a6e45149173041fd7c3cfff5a398ba832dba04dd7179d0768122a701f4e0bfa48149ff140e2978a723fb985b939458b081e1068ee5102e5f540365e6accbb8c28db84125b21e8d04622412c2f075cb57019eb828616caa245a8b099a01bd86268cf491823e440e984335af59924fac1d43263af725895c717e827532d35c7da9ac1420b46aef13c9f33a427bb5a1bc646f7b54a21760527d303bacb2a21aa39c5577bcd5f416f126741fba9c2cf9401ec20a14e9a7bb927cc8135bbb0c3180696093289f4b19539c58655b8698a5d1339c9490be7c04ad3311fd422045a5027b203407cb5755462c21ac51f523389e803f30e12fa9c0aa7b4a1fdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd3208fb6f28661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5bb222e7aaaf9e9149afd11ea5e86990913d2b543913942d148639d9815d4a8908362a84bfb6ad20b8acf9596df4187009e7b773070450010744712f9e7a9b8e9624e3e2b1d6140a9e4789775abcbd2657aa487740314ea1e446db5c09746accaee29783b23ebfb255ba5c9706f1254703c676ea09801762e9fa45d858732ae7218b37107b3708eaba05d2c035fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e55c05e6b5041552c17dd223af273cbbf65a44b4b6dabd51b341464a9993effd671481592c5a655d116b963975006b13503baae38332248f58656620098f42f97a813dfc7b4df880e5e783af5d833b89079474040ac05a6a7ec5e9ec1bdb282443c736514514f1cb7455958608a62503428464d89c66b209c417445416a54aa66234b1a5bf1c0c3f7064b6d0a7243e170b6acb01c033c5b1670a3ba6801024c03b24cc1786025fbc56bf04f3b241e4be701c9764938695bea4316adb6abacfb44f2041d2c29bb867379374b211e990f194b872a7b684a212dc179a4add943aabb1e6beb93f5cb100fe342d0781aa80989406571d1b79d08e31ae15b81740a22df02270f920ebfaa3c9d74392cd64e71f363df221134e9be32b6b855fb76e15b5c91cc6c3f750aeed71071a0803987ca7f35882ac31413a6001a6023c0a183961722b6ebba16f5577d95bea2c5ab446ac8e57acc96281a07599a8d335c2c12388bb0cb9f8633cd2251c8a7563b396072d0cf6e7b8e3af2192e5731341214c30708e128914c124973e759d4221f1735386b874905220c41fc731a22b9c665cef0cc5353b799399905f0acb549f13c6fa56fae2907d0353ff2054accec40310a2c4b62aac3f392b014ba88fc90eb868693eac83516336baa601f600518fc820bc8b0e76c664f3cc8e6a5cd6c34bf246a5d52f93643111f8f9557c3499664ec572dda5d73220a170095ac2764f09167e0b2277f08b23101bea40923a282132a07222ce0c2f1c5894318b591e5591ff20a5d8bb735cb3f7b161a1634267bd33721ba066713a4c25cae04a0973cca6834b717c7aa9bbaf1471aaa24d92c5242c388de17a42019506dc7cb6cd7315437595a9221c76c7862057afd76add8e852062b017cf77974062d00b9a6452ca040d839220372f7d44c36115a3fc5671eb652037421d08484a68b779e94b3f6aa5e74dc282525859a3945003c7fdef3b57cb5b43f14a290a1982ddbc9d8611aa6140ea8c36c4b5953ed45bb7dd96d50956924abbc70715b768975198627a9e64499aa778b9c4df403727486329678790bc8623414436d79beec3624bd20423d14c91e4414ea4784dc405e30f5734a4005b6791059ea8ba7cc224146a856f514753005af7abf5dbaadfd0492c95125493597520478304696fa30681134c5d3b71fe5c54ec7d06588798b31d6890eb842e0aba055017b8ebc4a355a23b704c6448bae0a62c2473c1dac43425852245faa8514b54c2ed51305047e5b44618f166cc329172668306984151c31cf04a9864267a1ebe30faa133fdfc040adc3cfa49a3c0f4ca85d7a52a72b71f217278fa787a2e3047922bd339176cbd5049d498708d65f2beb4ff3e544f973a4b9e19e6704b019399683758010e5b759095f17989d4a25a2d9199c3fe73d7096442f539f29ea9e6b06bd39e1630db0b5fd819dc4002297a205898108050c9365014351f38c017564d6798a16382b6f34907a4850a0183b27243ec4123ce3b00cc682c1cb8a9d97845f5d24b5fc35c7e088cbed62910c4050ea6b76c88c87f9577941f6a5b3f2b614c94224c26a36a841c3b40469d2c0cfc366ddac23c8c2bfc401ad78c758a6cc1684d1ad400bad5d88417503ccf169481fa437e4a8cf78b907890cbbc1ab9f46178ee2dc6dbcc1604d2b766707b88c1a343bc5a074fc481533caba15cd3787962697b11df700044a79a809112516a88c2c662965a2da9b996ff92d951337b4b9c11e7947b14212a6f3cf19d2c5d86cab5267a1c8065ec045517dc9be0783194bd846dffc50eb723eadf08ad7b86881cc33e4d9a9b407c7d464c156e94253a8b2a0128d52a34e27610d9a902d4151105409be06a11fd3f73c88b79c9ee630a98105556b777a5bc680a803f5a7b603f16643ab0a9ef7161861b3ecb5636a9529a24a59f17a389b61aff5e633b863065f37789a538f8353b80ad75b4ee876a6ca363b6679680115f4b9857bc88b845510027a0e9014621dda9a31e12222522557f8c86d29a499f0547e35a99d81b1a02147dfa3c45beb8a3026a23fd20297d20e33503cd49002a9fc7ff8200ae433b921bc93cf10209a05242788908f71bae849518ba305eef84597f654754a7808d81f2cb62bbb282911a0c5636cad75b53b454a5a923a5fc8e956c9cc527bc04b846b596c9b222a953db76485c6486907f898f6835a6f315ae20b57d3e56953170ea586658b9178c638c9c22c941097838af0123a601d0d4108b2ebb53b46233408ccbad9597633440ec1aff61743f0371ce62ca1977aaea8d98900f0016e5a9248661fbe5c1a4d261c5426a12715af037a5ffdb38b8dfbc11ee3b4edf289c3ab3995959078091e888ac0107467bfda6f3d35516ba7404a4733c8ca4adb010f7399ac5f14c2cf992fa812cf72f2c79750cf52e648dbb8c3b14698bb517166bc1f663594eb9a6c476c58bc103ea7f03f37205c5c355a2633b9ccaa829e3366fea63932550617aa96d267cdf4b98cfe3334aa0a5c7600ce6ab6aaafe7cfcce4bbbe2756b7cb10d6d6cc8c71b32a04cc652c01e2b62a73497dbd9a46eaccc382c5903fb405d950462ee6c87d2631ff97adb38939c4f284489bb9d1072821c108886842f5c1b402aa2e49d37aaae13b7c14b5a748c2dbc45bbe5bc2abbb929b613767a720ba572ca63c2080c4547c9024d2f451f25973f064941e814e3ec74b4c1770542b0782c67580b7a695c2ab29c95da2c18e4563a24101b11084586cf9a42ed62a2bd1570fc175f4d5bf50f8c4a196aea1953199143efb5183b3a905510623efa47c4a52522787723af5b5d05b86d15126ec6ba2201120b5a527324a9895f62959e24aa6f8c95d9001e7757fa5b3a80085bc48bb0d34388c0f6cb647b0a7cb992519922a730865a4032b51708fb6602b08d144336b7c7b65730d8677399436ff5711eee7b935d67054982472b96ccfe7279f1a673bd61757f7b951a5bc9c4b7e52c11a09f350737120e0923f8c1a2989f19a6faa06105391b39b266d9c768c658d56fb59f57020e0d17feaec496f729a810821fce59cebdc24e8b7cd3b869144225ca4b5a5c72432738ba5b939c64cf338021181765891469aa7af34a628950165a1328cc4c2b6874498a8205c675214137e47080624e250521ca34e394e829206df285e7f84a8b117c24b1450f883ac88d47142a64552aace5dd85332ac168abca2597ba39320653e8338303552b419c84ecc014ca3006b50a6f74b8ac57378f8a06006841f972b703a2b0daae868698b778bf6984dbc7bab537b29ec5462463295ca1581e2a60f5c169b494d0b7793af3313fee3742d84c1d20b6b47877320e25aac270e3739b34063b62fc171ec6a6ba7b62faa650496a63110d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa05f166082ad3ab0c739cbf0a6bbe2707741d9b5f53a0e16199280a2376c9e5a1781c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +expected_public_key = a3637b6eda83bb2281b6320527e3b22bc08b5aa644402cb674059135d9c928bc4598019722b8af0b647dd3f02d553bc457bc763883288dbc461e775909745317f67017d3ab5ac283d0462167dca55e7452438529dd715f8af6438edb470b816546d078db0ab2588bb56b2c0e06741cfa28c997a128370c1d72221147f0218784633b45207a3b43fbbbb0d0cac41fe70213475e61058cf21797564b0db1a2095cf367b9561ac2681ab8b6ce7d240b5d277169c31eb99a4b68b92b3ed1ce6333b404e8807b32a0b03080664cb9f0987d2ef56308707b46b14f5667b2ace438701cadd7b4026cc5886bb7c0160a9684d5220d422497a9162d84c2500c0bc4d8bf20a904dedabdc56a92f153770aa95244220bbcbbba66aa89823289a2335898f01789e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f020779f6b6cca633e33fac08c51330ee0bf70e8a6ae4a7df0f2be54b10c6e418426c69c212a33b6b897b31630c6928cc4865606ca1f7ce192411c8d4812645c0655e23553b13c6c7c073e0ac92f35465a1b8a505de879998bae71608af9e943b4caa34f248f6dc679d93033b51c53315aae72d843884c83a0a711d009414c215badc32a5f74cfb3179d6ef26818d7c79393b8bc8b8d212092f2250101560cef4abd4132cb31996b85432bf437037d73516927300528763472c0d5cab08294154001c3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd60fa1823e32935515f90234b7613ad5ea3734a6c0a9422a97dc7042a0434a684083e8bbb40d2c4ebc08496a7261eaa269175c2a8a0aef21474dd4837b6b1c7bc112d67a1c175b2634737b43e5475d5ec9a75827f02091dfdaa20fd43cf59922479a671363737ab1cc307225bb4118d1a714ddbc08b770283061762bc098415e1923ecb3e3c92216d30694fb869b514a314db3fe8da5fd4930ed0979011d8b1fc723ab617b6de420482e8b9fe2a3874b788f0416dcd20704c20285247784477385a1cb219313b700284097acbb90976b94a5fd8984bb6b7121bb020e589804281bedcd78c1cf0aa7ab136c7e7afc206983887beb2372784a2c388a18b1dfc5e077703c8eb7f8a966def46225c8b3fd0f85d6e3a328c8c1bcb0b55d0341cdc866e1b040e09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf04421056915cc0d79830eb972c01bd3756270975bd63e224d0f58307ec2986699d5f536ee6c21f5de6844da70b797c8ef5b9a473624c50647d171682f30a2f3fd7c670595243d59487cab8d0a7727d40350f9bb7d984ba82d8cf39e817c8984c17892295e09ff674a684272cc710bffb263bebf1be44665c85530d13f891026790c2c1590ab6159cc22b5ec76057371bba107ffbf402631297c2c59bd05634ba628a7bea14f3985d2b5260fbc64664bc9ee308694f8bb3c4ba1f4ee43dc4eb4beac095b74820a2787aeef612c0c48afd0b20ebec9417b12c7aa50f4fc86558d36fc764c5b69bb4bfab3526d533de0c2e2bc1cdd4b897c9f990e8987bbaf147a0c4428ab68ca077a2a2d3af76261a1f371fdd503f6d9517a8bb0d53499d65208baae23c77580becd252d006bf27bc11b87c19789384f063538448b98188b0dca07328265f4c4b68de438d8420874625bcd12912078056c7db367a1598bf200f39d2a90e12c8dbe7ae4b780c8f5662c78916af1a270db365ca9097a37525ae347961b13b9b72c68dfb7ad7517dfb318d5385b7343a63f5026bee90177ff212bd6b639bb15d7949680ea38336891653d2c5aec083a8873362ea5e6fb4b0b1e19e48c1b90235796ba570aa0a3b1ea6c483d3079c71cd153b246993b86b506e477625b3b939fd9616451b90da9348b87c0201e087a5592a208ac9ab7ca6712758ecf4cf1af163ca3a369e82b46d941b15a42d31f8775e6332387036cc1bb31c5505d52b1a0753098d40b4999a74e4743a73e539d9e7a9514aa5671042a68ba6ef785234622f7440241a55a71f018a09ebab25f7913691bf787b781ef818c8238cfe5cbff3f8895a19c24085337fe10ec7b326da82283f03240a02aaf2658e04f7626da155a9fa8117eb3cf3f36d1e48baa2f68d158a0123691872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_private_key = b27ca8d40a1cf8aac1a62553ff541ef56b4b4e352e38c0ae8c2cb2240c2d2525adc52b1953a1c239e3add71b5f7693196875babf8b31edc528f3b320e6569997639f1c9b5279c38d5ddb3b691b0228ac4480d45077db55bac24285c5820c49be25632c4aaaa23ed84e10a1256d9cca9b584d423a9fd37276cbfc5953c9284a4097bf71706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450b1289948323f64227960a0b24b442e78c551c5b35e89b34b018b80bd094f7594365195f44c05bacbb2e0a976a86559bd6b23d220b5c900375c6b188fb353c3b064ced669bee6751d5d22659eb89900a92b7ba84eab58b7e95cb8495191ca0491ef75a3abb9469a7939796c2f8c15ca22283235852b0a96daec403c5c057b5ac91d09cb16e01bb0d078170e0ce9596b913e953c5aa67bd8a2ff20c0261ca814f334244886daa0694368293fd858e14e23d13e66ac89a58867574804786c4c48d2fc003336c002a7776217acfe7084588455a0a85b8aa51c33e99b1cdb75541855577911db00475df42168e7a21efe57402303dfe37ab5bf10200395550a1639da2aa8e358748ec38946bbd3dfc27deb08f4f017abe33a2df3b9b96cac0e8c261e487cfff31a1484ca5e04036797cb4fc87ae6cc72f9ec0835ae2b160b425acfa8b75236d92870e4d43bfa7ea5c98827f95db6dd4200068650e3d8812de827c3f660cf8049933daa52793ac10f57ad8f2a7445927ca6022d5a485f9424662a175b2a6349b248aaf4853be709d42228c3ce3b13990794b9698869842b81649cbd9482c2435886441ed9a7927384371d02005a514717abec398bd183b321134a4de85a1fc9b72f7268ccafbae289c15dcec18bc26b81ec43c6b8a3919625165617d60c33f1e6b04cd5492414a15bbca5ce84284557c9cb481a951fa5df2e444e2c20969f38284e60ff15b0ee707115880bc6d3834230c7d22c7cd69229d1eea957f58b2d47b11ca97c926070cf1c1934ef83f5a26241c7c73959c8a0501c2c1c70671987243635fea56ce6ee292b1d6aa26c4cddfaa1751520fc3218e7e20c13c6a1df4835c7d6c0ba45923ceb2ab40fa7fe3732e47ab652309cdf28091d8d86308b73f90d86995220acdd9c544c95fcd24a77e7c90f2f15e52aab595e11b1ac0799a3ca95e0644771420aedc777a9048fa89ce94780c8f2b903548bd46a2c22e453b68736f5cca6c35ebb027c0c7035678f7f69a9ca02fbb4b23746759660251f6757be3aa1767d7280aa75b60a7a0cc892f70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc88514ced3597a594d0e28c7aa25859e57be9fb12691c047a8a7373fe1695ae742027a8f5630cb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc8625a2cb995b548d48294b2fbca97d375b91203392cc27fe835f62db97b14739f6c8b1880a53ddd388e2636f866416817a110258a098d9af4458a64c68654e97099746b9b9e23adab5653970c00719b54e4a2d2092cd7bd62ad9317357e35224184a4e24b4a58014f666b33e1530365070b73aa6da432d04f2588f34ac1cb3b3f7fb4ab200b459966fafc689cc40adad0c26108859a2943e6157c22f9861eee9ce412212bb11bc6c5414e781414711c8c61b29c0f90303dc5688da9d00b78ec8a80a4c5485b67bb83c850d2c0ca56e45a30f35250700469b957fbf90a6a097af95e4cd2060b38f8136b9f493e9c4b6b0395e04a0761834619e5b84ab33c3ceb083b1d268e468158232075f3a821ba286d84002c3757b99474b56820a414131e60636d03ba019fc37e8c63ebdda124a9370935926cbf1950ab83e56f088f36c24ea9a84e042447718220bdc53254708bf85971ed83027750301a685d2a91a652633e2e55cec7932126852d0216f3d943f5acc9ddeab99edab31e79a5bc5c5971f5b5ff6b50a57e2455f45346c3275cc1b1b0db991cf3bbb3d2a2f522a9ee5426556d84c5c0ac7d827a0e173480427ad9f637c1a71a2816858b2c152c33caae1fb5197d874d6f817996946e563c8de22aee6b5735e46ce6912b22f9187f8d75b4d47497d435f91759e1d1168341a48cb5c9fbf19137d397a2a1c75f0e71bc17a88e00837de428ba61b3a1e1c88ffe5a41570cca144a33ae851a3637b6eda83bb2281b6320527e3b22bc08b5aa644402cb674059135d9c928bc4598019722b8af0b647dd3f02d553bc457bc763883288dbc461e775909745317f67017d3ab5ac283d0462167dca55e7452438529dd715f8af6438edb470b816546d078db0ab2588bb56b2c0e06741cfa28c997a128370c1d72221147f0218784633b45207a3b43fbbbb0d0cac41fe70213475e61058cf21797564b0db1a2095cf367b9561ac2681ab8b6ce7d240b5d277169c31eb99a4b68b92b3ed1ce6333b404e8807b32a0b03080664cb9f0987d2ef56308707b46b14f5667b2ace438701cadd7b4026cc5886bb7c0160a9684d5220d422497a9162d84c2500c0bc4d8bf20a904dedabdc56a92f153770aa95244220bbcbbba66aa89823289a2335898f01789e8a845d3b5a22c34c70a6cc7ecc9eb4b65ae0551748734a1244a30a837ace642f020779f6b6cca633e33fac08c51330ee0bf70e8a6ae4a7df0f2be54b10c6e418426c69c212a33b6b897b31630c6928cc4865606ca1f7ce192411c8d4812645c0655e23553b13c6c7c073e0ac92f35465a1b8a505de879998bae71608af9e943b4caa34f248f6dc679d93033b51c53315aae72d843884c83a0a711d009414c215badc32a5f74cfb3179d6ef26818d7c79393b8bc8b8d212092f2250101560cef4abd4132cb31996b85432bf437037d73516927300528763472c0d5cab08294154001c3c7e785f3e887f1baca5fa9498947b691e7a2ed1c9f66f9bd60fa1823e32935515f90234b7613ad5ea3734a6c0a9422a97dc7042a0434a684083e8bbb40d2c4ebc08496a7261eaa269175c2a8a0aef21474dd4837b6b1c7bc112d67a1c175b2634737b43e5475d5ec9a75827f02091dfdaa20fd43cf59922479a671363737ab1cc307225bb4118d1a714ddbc08b770283061762bc098415e1923ecb3e3c92216d30694fb869b514a314db3fe8da5fd4930ed0979011d8b1fc723ab617b6de420482e8b9fe2a3874b788f0416dcd20704c20285247784477385a1cb219313b700284097acbb90976b94a5fd8984bb6b7121bb020e589804281bedcd78c1cf0aa7ab136c7e7afc206983887beb2372784a2c388a18b1dfc5e077703c8eb7f8a966def46225c8b3fd0f85d6e3a328c8c1bcb0b55d0341cdc866e1b040e09c960337a9fcc5c587c393d29e5b4921a9e2377775905aa0ceb54599bcf04421056915cc0d79830eb972c01bd3756270975bd63e224d0f58307ec2986699d5f536ee6c21f5de6844da70b797c8ef5b9a473624c50647d171682f30a2f3fd7c670595243d59487cab8d0a7727d40350f9bb7d984ba82d8cf39e817c8984c17892295e09ff674a684272cc710bffb263bebf1be44665c85530d13f891026790c2c1590ab6159cc22b5ec76057371bba107ffbf402631297c2c59bd05634ba628a7bea14f3985d2b5260fbc64664bc9ee308694f8bb3c4ba1f4ee43dc4eb4beac095b74820a2787aeef612c0c48afd0b20ebec9417b12c7aa50f4fc86558d36fc764c5b69bb4bfab3526d533de0c2e2bc1cdd4b897c9f990e8987bbaf147a0c4428ab68ca077a2a2d3af76261a1f371fdd503f6d9517a8bb0d53499d65208baae23c77580becd252d006bf27bc11b87c19789384f063538448b98188b0dca07328265f4c4b68de438d8420874625bcd12912078056c7db367a1598bf200f39d2a90e12c8dbe7ae4b780c8f5662c78916af1a270db365ca9097a37525ae347961b13b9b72c68dfb7ad7517dfb318d5385b7343a63f5026bee90177ff212bd6b639bb15d7949680ea38336891653d2c5aec083a8873362ea5e6fb4b0b1e19e48c1b90235796ba570aa0a3b1ea6c483d3079c71cd153b246993b86b506e477625b3b939fd9616451b90da9348b87c0201e087a5592a208ac9ab7ca6712758ecf4cf1af163ca3a369e82b46d941b15a42d31f8775e6332387036cc1bb31c5505d52b1a0753098d40b4999a74e4743a73e539d9e7a9514aa5671042a68ba6ef785234622f7440241a55a71f018a09ebab25f7913691bf787b781ef818c8238cfe5cbff3f8895a19c24085337fe10ec7b326da82283f03240a02aaf2658e04f7626da155a9fa8117eb3cf3f36d1e48baa2f68d158a0123691872aa74c64670437534b6dba775f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a56840b3a72c164432e6ca838693ef25b30013e5cf56c1e6142828107a10cabdd169c06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +expected_public_key = 5fec35aec29b1ce3387af3327d49734cacb798c955b329bc90122ce43c3cd1fbb939518c68d1b044e0ce31863d2eec9607410f0a6b74d40a6f93e7a88442aa0111008d38661241afaf6a2101dca37e83aa4e8747ce884cc1c29725a19510c7688ffa569cebb45dd87fa7772bdd6b6f26e48c5ec93a1d66a2519c571c1b0979e28a82eb9faf136feb21152ed15502521176c9ce3e2ac3f3dc78fc620e151badeb9b400da2029f1b1c2fa70bc8ca232cbb69b0f98a39543b03f67c1544402f518cf5477d6c4baf11f8bf44bb1208ec96082bc260e52d2ebc17c003a7816a5d940cb0bd7329912c4239b2910d27cfd2a48c77501e0586a2b88c99c1da29d0167a88abc35adb5a79c76c89f4c814ba410d9b2da6994c5a78c701ca91f42348454261f6f7a23ec89428630c5a88c9e309d08e8b7e9b353aede6c952e36973a23e9aeb8edd83b256d913b9b64e392936d538a9ab250175544a70796202154350696c9056695d9c0ff730c27ea71f1562a04eac9c7d8b38d551c447362dbb1277e6408a09855d1292956c72b39e802a19573c620a74f996492fa15322bab6342a8f90a747c3a40af020a2afda4d37620100351f3a5086818260592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b701a2c5909034a748b9891cb5e430836036cf686d8be47e2cd5559e500ee617ab436306614c4f026c6e57021da6f3356ea54e924799ed6827a1f311c0a340280ac21b110ea33809ce3744ac4539e4e912f4a99066c26d3f047ac87ccdc55529e710517ff042a893848d5acb44191c6057a4659427a7c2345e9005135bb3856733320ca4c031c3b86aa83cda29f40467d5306dc0142132f1a844466abc1b28d94b4d1b98ad5ff80886b38d2a15505e8cc24d9b3273039c2babaf8380568a1136610ba3ce49add830785a1780eb67b6dd628f718ca7f1bcca357a1531999d96556515cb680e153c98281de817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a4007f1069e6378e7f0b4ae2b890dc84294627a10039d7a46b3c705493c6471b3cc9ca2535fb8cb19798b7d4d562ea33869383b28ff7b9462124070a1c17cd4b2bf4a622e054a1cc29bb177048a62ba8fe66fba75cca14048da8a41c2e3a13da8ab593c14d0b295b1b587aff8778823ad2ce3644de2b236bc144aa4c5c2dc697ae3c681ac10b5f53ca1d84334a7908c48bb7f5c93388186860c781bc483b1975219d24677487161b15407e52faf51919beb32b6c3bb1fe993eb15a4af84a64aba7d794252fae6785b1054c24aa6b249840b08b3fd47a275d1a0930b2ca6e8b0d4b498628418af01aec4c049eff55a576123c1e58dafc5b00c2373adb7cd62120b9a69541084100fe44776d3078d66b143b7536888c4128a2a637c66d270c0be49c99f1241a951c413409d16cc653715b88e869216ea42ff505ed71c550848a98315c84550ce83bcc750e4cdb8084f882a29a5a0cb6048b5cea41b9b8c2fb3c949fb928770e411ded9902774b529320f768445349a310c727f2012678f44967f37b0a7cc3d4af05fb285a82ca568e88c87168b14a84b90bc6297bce393aec894d7b464852bbc55f3c85f447980c904bf067f9cf55c756a6967b95bc4a08427a8c9d3aa6ea8913bf47a823f0050de189c7aab2dbb040129f40b5a885caf20281e39c178a79729072ad360876ed670c192912095a01e19af47f11c30a44af6165ecf290f885998b9cb4ffcb1b7d71c7a4c21c0acfc8f9a942b7bb266c49a528a28732f65b4038bb7dc2670ef20cde470bd142a836bea52dc4460c0e01d1ef06e7e7775e9a888cdb8c2e6a6078ba3126572886bb091a14735158b4aeff26a852b6b400698434c61031540fea976b523627e1c11f5e14c5d5c878c607afad79e425b62d5a56530bb6bf889581045cc4839857ea16bd9775aad3609d5287aae66c60f916df54c88e8f291d8019c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9147016c9cb2018305de8321f4d0c158fa2452347c78a376f399780e59a5a4e1c8bb793fa14cac662732805146d2ea5cd67196257362922a81e2177ae5289f2bca3d6b2b0168a263c642cf8e2a3ce8577151aba48b828fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_private_key = 2735bc066a2488726c89432e56452acb24a2a5407522988c0732ce072128c8d5147c42988f94a8516c77873858394a2bef65b87741c5b9691b6db84e3b1b2b2f851b1305832e4210e5d05710a5bb7195b8bee0cba9b5ba21ba57b962a280565aabe1c9015635cf1a7121a8581fa0a78ab26fc82838b6a405c6fa5d46469136cccc34930664240915ba5c86e67ed9e73f4b123233c92d73bc05408005dcd6cfd62635c3026c990753c55ca8dd385a29b1c79fdb97c0b4cc8f26b28ba573b5194d6bcc065f5b97df702009c43a65eccf452447af91200ef68f18cac25e5c71e62a39fd7a26c6b64b47e29d1e4084801599aba838a3808ed83454b506965507cc6d0b34bb139300d1014168a79d5707c74bbc7b980461249fc31734dc384c9dac4ea6eb4701402084719593b62aae53c8d55719945975cfd25bff31c886640fec37cab3942676c840a453c6751caf16a4743495bcde6528a942a47e7c2d6499b2a872a76e928ef4b0aabbb21604f33231235a7cb47c96d9c976a2aad533a06a24024ad0925007984d99aba3aa8168a8ac92f662348686f756bdc1a23f8537545d13ae9f657caa801788c9368864a05f40af22e33e10705741f06ef577cade6ccbf1d01065565a5b13284690bf611093e45684d6c69fc0f548af852248db6a6e86a2a907c95ce0053fd942a92b024dd18803474b03f73fc022912257454c008d137c5e8404379db2719581af17108a03f58dea58892912c5fab701d28ca845068761f6bab69bbb75584f7d289dd921ab30379248c91106a784738b17cf0044418bb9ce34bcd913bb26d04ca04896109a255a39beba1a2b58490862409e473ca623933ac14c90f64cc74af396c3186917061b5c8c28f3e8b694535fc2c73af9843031c19166d2c8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf2803e2c3ca5d585c4ea63009c7b850f08759c278f1027c59499526a8b2e494203197a9304022fa0c4e47a3a6fbd8bc59a7c1312a6d19d3063e8078b1a1bff964af48151e4cd3cd87f49bbbe01afa3a5bf46a7f9bc97de729285af35a6a9168683658ee37ba6d9499cbaa8cb44c93beb287ef7cc7b1eb6491154c14fc2027ab49316b70b8237a546090c9687cc70cbfb82208a7f61f63aac1a42961568407343a050b1048967c5334f3542860249ff9c2fac8639ef8c125d0b9fd537fca93c1006a77499658c0286267b910c10b12a6136152bcbc03e782c41b1fe94a000cd974a3a9ade3a3b8b4bb8ed8b403683ab4ea3b84b84c4825f61f99d72eacd894337523c6b6af765bcc99393213938d66b18b2b168d6c73c2eacc42ad22255cd3ac6d75200111c0a6076f02f906b1c96213e80310b8752b1b619e72366f9a0ba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3d519e4263b050259a9a0a8823e3cadcd0b81c1ca53820323a9539133c68b0a6cac1fc834b808d9375431f961fe3233c49fc9e88ea1ed0a068a271b502c0a0376a1309f86013b4947bb671c1b048c0905c8ce16d8035c7c05b9cb8755c7d7b6db2907dacc5a91b61b666837f209075e8ac5b86444b49ac878f9b2e18d42e0f791ab7cb7c973ca8e0437f15888916dc5d02f10dae54c86cab52f2b07f023a639288b2491145d56b7ad962840132667c78473e339f99fb9adc722f956165c5a8a8c5ca5622b504a624af6ca26443e776856292851c7f25b983878c9c567523be99bb7568b9a7488b96925a0fbb07e7599448aa98dc112f6cc283e7f57758c1b43eb9a926b2379df6c40e49159985cc4061618425b1d0ab1533bb3f5d03be664b8df86b95ae8918837a4b35023c9926cef826be5645784b33b333b7b0eff9c98a2793d08b2a11512f3e9120bd0b299c6c5b17103b3264964d58c4d9c51cd8f995edb72406cc16452a483786a81c6a45bab840dfa1c9cc978d6d9c3e22c4afbab8265816cbc322abd4e510985520d9fb0ac69702a784734f230847170b532c3dabdc06b762b22c738af9c9308a9b8b3fa6c376464f6c691265b43901561f44d9a1dce88e2d544bda01080fc0b58fac9fb854c9d2e96ae20a9e19b22fd69b6ff88a6bc324514987b039804b71c1c745d77362801847c780922b68a85c17fa750e2ce19f3e7765a785b4603931f9ba815fec35aec29b1ce3387af3327d49734cacb798c955b329bc90122ce43c3cd1fbb939518c68d1b044e0ce31863d2eec9607410f0a6b74d40a6f93e7a88442aa0111008d38661241afaf6a2101dca37e83aa4e8747ce884cc1c29725a19510c7688ffa569cebb45dd87fa7772bdd6b6f26e48c5ec93a1d66a2519c571c1b0979e28a82eb9faf136feb21152ed15502521176c9ce3e2ac3f3dc78fc620e151badeb9b400da2029f1b1c2fa70bc8ca232cbb69b0f98a39543b03f67c1544402f518cf5477d6c4baf11f8bf44bb1208ec96082bc260e52d2ebc17c003a7816a5d940cb0bd7329912c4239b2910d27cfd2a48c77501e0586a2b88c99c1da29d0167a88abc35adb5a79c76c89f4c814ba410d9b2da6994c5a78c701ca91f42348454261f6f7a23ec89428630c5a88c9e309d08e8b7e9b353aede6c952e36973a23e9aeb8edd83b256d913b9b64e392936d538a9ab250175544a70796202154350696c9056695d9c0ff730c27ea71f1562a04eac9c7d8b38d551c447362dbb1277e6408a09855d1292956c72b39e802a19573c620a74f996492fa15322bab6342a8f90a747c3a40af020a2afda4d37620100351f3a5086818260592735847a32ea5a4e926c82493c7bcb5b76ffa8562aac97b701a2c5909034a748b9891cb5e430836036cf686d8be47e2cd5559e500ee617ab436306614c4f026c6e57021da6f3356ea54e924799ed6827a1f311c0a340280ac21b110ea33809ce3744ac4539e4e912f4a99066c26d3f047ac87ccdc55529e710517ff042a893848d5acb44191c6057a4659427a7c2345e9005135bb3856733320ca4c031c3b86aa83cda29f40467d5306dc0142132f1a844466abc1b28d94b4d1b98ad5ff80886b38d2a15505e8cc24d9b3273039c2babaf8380568a1136610ba3ce49add830785a1780eb67b6dd628f718ca7f1bcca357a1531999d96556515cb680e153c98281de817ae5f4762c03952c74a8a973993fd778f49c38b59838f793c71bdda96fb8a4007f1069e6378e7f0b4ae2b890dc84294627a10039d7a46b3c705493c6471b3cc9ca2535fb8cb19798b7d4d562ea33869383b28ff7b9462124070a1c17cd4b2bf4a622e054a1cc29bb177048a62ba8fe66fba75cca14048da8a41c2e3a13da8ab593c14d0b295b1b587aff8778823ad2ce3644de2b236bc144aa4c5c2dc697ae3c681ac10b5f53ca1d84334a7908c48bb7f5c93388186860c781bc483b1975219d24677487161b15407e52faf51919beb32b6c3bb1fe993eb15a4af84a64aba7d794252fae6785b1054c24aa6b249840b08b3fd47a275d1a0930b2ca6e8b0d4b498628418af01aec4c049eff55a576123c1e58dafc5b00c2373adb7cd62120b9a69541084100fe44776d3078d66b143b7536888c4128a2a637c66d270c0be49c99f1241a951c413409d16cc653715b88e869216ea42ff505ed71c550848a98315c84550ce83bcc750e4cdb8084f882a29a5a0cb6048b5cea41b9b8c2fb3c949fb928770e411ded9902774b529320f768445349a310c727f2012678f44967f37b0a7cc3d4af05fb285a82ca568e88c87168b14a84b90bc6297bce393aec894d7b464852bbc55f3c85f447980c904bf067f9cf55c756a6967b95bc4a08427a8c9d3aa6ea8913bf47a823f0050de189c7aab2dbb040129f40b5a885caf20281e39c178a79729072ad360876ed670c192912095a01e19af47f11c30a44af6165ecf290f885998b9cb4ffcb1b7d71c7a4c21c0acfc8f9a942b7bb266c49a528a28732f65b4038bb7dc2670ef20cde470bd142a836bea52dc4460c0e01d1ef06e7e7775e9a888cdb8c2e6a6078ba3126572886bb091a14735158b4aeff26a852b6b400698434c61031540fea976b523627e1c11f5e14c5d5c878c607afad79e425b62d5a56530bb6bf889581045cc4839857ea16bd9775aad3609d5287aae66c60f916df54c88e8f291d8019c6a4861d2d68edec96a19e9911a49a043086247b37b8ca9a8c16b8c9147016c9cb2018305de8321f4d0c158fa2452347c78a376f399780e59a5a4e1c8bb793fa14cac662732805146d2ea5cd67196257362922a81e2177ae5289f2bca3d6b2b0168a263c642cf8e2a3ce8577151aba48b828fd70670f45399fb897e85b45aff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1f475da2ec982c47d91b24bb5ec6c51910530eec26f38541b173b38927d23c5684f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = 527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +expected_public_key = bc859f23d76da58b31d2677f9de1841e50c263257b04d84419c3892d590b286088e35b9ed4a57257ab09286934a0e63326876eacb60fce3b9642019560a5646f522fbdf34dbfc8599829105222193903c97101a8dd4806788a8ecc223eac5206a8706f38aaa4dfc87181ab07e37bc3106590fe18996e5b88fda7af242aa56e42cac7113392317604cc89e1f067896755ead0cbfa201775329d2c8804f485cf61cabfe35a33cfbba7d2426ad2f59a98625315633b0424ab2f2326fa8488fa92895ee08edbf32f6e318dd22a5719d3c4782bc1787873e93773b310ca9b036680ba69acd75036952a330abbedfc5477545ae7b09b6f3467a900083d4677c6b5c0dcdb9886f26b1c9b6e180b8f5020ae1a68b9ecc3a154a084a365a9035841700966cca311c09b13fdeb4da6517c9c3a9c3cd9c336607a53f1972856b161b2878c5689e8ea7124cb768fb48efd92489a1bb3660422bcf72ccbbcbf0d7383ef47586863870620c025d6b65cd5c861234194448a021417cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466b528b2fa2eafc943b861c78666a94e1091efe4ae69010f0a139cd9984be6f23a237cbc1345a53fb0489fec34ceba3874f631f4a34598a7bee966225e2b251ada212b9365bfa2613bc4b2e0962493c0c461361fe555ad61bc6dd54b844114781fd37291b7c3e7090cea1a20c86b3637011493332925f503b4ac6fb625ca41601995869443da8d82b81412012dcfe22eba66072a9cbf65f34294b4c85ffabcac3358fd6193c8dc1706c05e123b10445baa34c6616863807551bd33546ed39112f49c371ad31c82ea6db593a173884d005a0a5184417d5a16ec87225bac3728530ea21913b6b05283a4c078950ca84b73e417cd1878b1ac9388241c3e006d5c0b1148db78b319293707d92210622cce348e5c0572ecd7718bec7f6c644680bb2a6bba55d412776303b8b5cc2603356a7f685095da747a3480dae39537780188e264efb88bdb8c82cfaab5586b3629410bdf2274e8e2b76673c700c45fdef297778cb8dbc4bcec24c349170b39f96a5e3c6ee7d1c8da58357398a5f0202743339aa7eb74e0a5b8542909c29a8337e6083e3663df918c6a85246769b01403bb24c25c27dc8a4841166a86698eec30f049a80f786f6fa29cc8f7414517429f4aa76421cc8cab09874bae0f9999f0a846fa742d8d087bcd929d42e89f994ba2d421058b429e24c753436b908833c2b4365047da4825eba955e9c5de3a02c11c3c8e214416f2a8efe6b3ad033bc9acb992d77d8d340c69cb97cd59c7a5b127c6b46a51267b2471031166815c105914590c2aebaee9a9286d7c7d10b42c80077ddab4ba9baac51fd2512b481d1b1713ad4136b1a4a375959710a156fdeccce7a2c7dbf2ce57a9520b7c9509075bee4c5f4e3a2b45a748bfe210c88ba484556299511c10f762c162bd0114433dd1913f628540571c04f79490c30ade20434341b59e2bc66f489058d0aa2f14575942299783caf2e7b40d2a7bc10a150a6b0b1fa2a8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c95b25066a85d1896123db2297a75fdaa015a60942ec7266f8d00511a1603fcb2e6d533e3fc7c126d2753b9704ed2c5608a226cff698a8fa53f9746eeab1c51796be3c013c44f0ad8ec2037e75369877c4d63a1fba7ac534f4b6852068ab973e1d9b96be70cc21659971c90aa7793e51a517f3108a2ff24fd3541cbb89b75786a546b346ddc92ab5eb93227057f0fb76e1554c0cf19bf0d08e33fb1abcfb71c1a0779a91a42af586cb27a9304a75e9604211640be36739fde51f2d9107fec20fbce665a45a1aeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf50c153e941158f2202de5857b834e3e553f7945398bcc70ee00cce8ec15296b2364393085f2821d36ce6f04b0b336bba762c387c69280bb4fff179eef54b925d99176167f4f916e2bfcb945a1bab4e5398a03c17c79992848bdefac5fae4667d37c75bae231d424381c39722fba787765b3005699b7b08d2785805d476679e29372b619e3568eb263c2aad8c891ca561271cb5868b5971445e1cc2e2f1a11e44c0a798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_private_key = a680635121c694ac4672c809bb3b913e8ca2f659c756db1d7bb2369f41ab4ac9b3f5141216f3c997b00dcde37352d46463f371fec14b26aab239498d44975f787504815552e727329dd78428f5568b912c76b572ad9b3d335a9f5bc0283c76aef8d81369a0ceb4523bdc4bb0607c29d9998962f76b217774d74a3453a61ff1f40f89a51365212f39a07e913824bf36b6dbf6c8934014dd8716e998a982b124aed8b082c3a2998708bc1c4733773b73e0be315203e8e264a032797280ca0ab023a9d81fbf0565f491837cf031e219084b640ee8710589e05e1701870bdb7bf0b0bb539a0b3ab0028447110288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35308a23e9c9281c61c556ec148c9a663ad9518cea36aaec71b6995110fc01cb66b75e128478280fcd31a3416a12e28c15ba617574730437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0b80033ad52cfe1a155ea1a568f5b2ef77ab74878e0ce42a1f7c3c845713d17105ab2c91b83836e11b9858a66997b22e8a67682588ca78e6b6d736298ee34b100bce61e0ad921a9f020a7032351daed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc999b2b071f84c921c585b9b3233c5bedf82637bb1253a4b29b36b42b54751dc629a215656aa1890c0c56e0cb62a3c02252b771d72375a60374bf8d84552080e0d456579930b3f2a2a3b7913c031112fabacaef75bb2da5202d7671359282cb4707b52740d9ca06ab7034b48a292404d26b6cfd08c8b0da61550044069f4cf27488c028001f2c29292840b60b321de5cbdef1ca216838091c3172ed26d141c957dd93bb6a59d9e883640d87a2a85605a9730dd5333843805374b58747c7262d5a65ef442d6843deb731c943269b4a9bf00f39b4a3847840c1bf4b9907fd7b9a66c5da724cec467102f080d4d0bc519d0b2504a05f7207edce7398d009348f64267e01b0ec207780791942565aeb061bf03719d706f87953c4757a75a126ead15c6c9447c02938c3b75a58ab25ce65a5caa21898fa8050319880223899f5546e0d253df7950691b86f8e3115438c3b80cc2e7a6178a96a0f38a0cc47394be36c9b0721580d646a89b9327210d40728f4bc4adbd8b130eecccf528a5a09595f32c0f64e602f6898b8a4c82d79a8ed31c4172a7812c295c93841929b782b334490eeaa38c17cb4e77664306bc7b01726ec656e24311c51b0524c72f0745665d43073604c59ec88df6fc9ee2f2a0476079bcfb735e562f57e2b0e1987a0220c98f0b4cdebc70f93ca709c5c2fac7098a7b866662accdf09c85974d7c88ce9afb01f48276ee320d70c7c0e15950fc0775e13173b60555a470302d0a0047260e5cf85ea2f3c326968d3c308c15eb400b13bcaaa65ebf941ef59a069ba0bd3d00841b6124574303ba8c2bc9f90f107865882c18eba462f6b09eaee05796e43a8647c59c64b7a8db9c0941299280af728b872c303755b682a3ec10c5876f040543bba028e870c02a4312aee9cf2bd1302df80bd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a53948790234f62be0f0af0cb460f782a85d7488c0b9706de1c667f41bd67b9d43fc33647bcfd1e5bb6e2aa92e653764640a6d59a8271bb278160c9a153c98247b376069cdf349ef76c20a8867892258c21923621a4828a39fc6b72443a467a4590bcb0295af866f04791b005d0659143c54a4295cc883db27ca9c5190388b84f8e41aa85924e73025a7b7932d834074a39aeb92ba5079cb6ba77a94fa2f7d305e6421cdd093582868b1e7b90348e04875b837466a174923acf40972abe89a77fbcc32810a0e400a5d0c1e57e62ad581204db84b63d522cfb6423429647cd32544339101db3ce037c15ff6c26fc012d2dc05b76a35c5fca7ad284ad04b4696807c95e0c9abd0228487493244a86d713a4b4b13978c538ee77414b354b30548fea56395220fa60467249b13c59a50c20888ae5998afd287a8c1179dfa5610f5987f6021043b7cf6d749e3ac2fd6d58b3e9c78f5ea88d0c691bd2544aa591407484cd638864bfa49ae75bbe2143216c1aa76278cc3ba3f95b413ede648d883b825039d2aaa1539173dbc859f23d76da58b31d2677f9de1841e50c263257b04d84419c3892d590b286088e35b9ed4a57257ab09286934a0e63326876eacb60fce3b9642019560a5646f522fbdf34dbfc8599829105222193903c97101a8dd4806788a8ecc223eac5206a8706f38aaa4dfc87181ab07e37bc3106590fe18996e5b88fda7af242aa56e42cac7113392317604cc89e1f067896755ead0cbfa201775329d2c8804f485cf61cabfe35a33cfbba7d2426ad2f59a98625315633b0424ab2f2326fa8488fa92895ee08edbf32f6e318dd22a5719d3c4782bc1787873e93773b310ca9b036680ba69acd75036952a330abbedfc5477545ae7b09b6f3467a900083d4677c6b5c0dcdb9886f26b1c9b6e180b8f5020ae1a68b9ecc3a154a084a365a9035841700966cca311c09b13fdeb4da6517c9c3a9c3cd9c336607a53f1972856b161b2878c5689e8ea7124cb768fb48efd92489a1bb3660422bcf72ccbbcbf0d7383ef47586863870620c025d6b65cd5c861234194448a021417cd28474743a5f9d34c3cb6af9af96a332a3ca21caecdd89939395997a39466b528b2fa2eafc943b861c78666a94e1091efe4ae69010f0a139cd9984be6f23a237cbc1345a53fb0489fec34ceba3874f631f4a34598a7bee966225e2b251ada212b9365bfa2613bc4b2e0962493c0c461361fe555ad61bc6dd54b844114781fd37291b7c3e7090cea1a20c86b3637011493332925f503b4ac6fb625ca41601995869443da8d82b81412012dcfe22eba66072a9cbf65f34294b4c85ffabcac3358fd6193c8dc1706c05e123b10445baa34c6616863807551bd33546ed39112f49c371ad31c82ea6db593a173884d005a0a5184417d5a16ec87225bac3728530ea21913b6b05283a4c078950ca84b73e417cd1878b1ac9388241c3e006d5c0b1148db78b319293707d92210622cce348e5c0572ecd7718bec7f6c644680bb2a6bba55d412776303b8b5cc2603356a7f685095da747a3480dae39537780188e264efb88bdb8c82cfaab5586b3629410bdf2274e8e2b76673c700c45fdef297778cb8dbc4bcec24c349170b39f96a5e3c6ee7d1c8da58357398a5f0202743339aa7eb74e0a5b8542909c29a8337e6083e3663df918c6a85246769b01403bb24c25c27dc8a4841166a86698eec30f049a80f786f6fa29cc8f7414517429f4aa76421cc8cab09874bae0f9999f0a846fa742d8d087bcd929d42e89f994ba2d421058b429e24c753436b908833c2b4365047da4825eba955e9c5de3a02c11c3c8e214416f2a8efe6b3ad033bc9acb992d77d8d340c69cb97cd59c7a5b127c6b46a51267b2471031166815c105914590c2aebaee9a9286d7c7d10b42c80077ddab4ba9baac51fd2512b481d1b1713ad4136b1a4a375959710a156fdeccce7a2c7dbf2ce57a9520b7c9509075bee4c5f4e3a2b45a748bfe210c88ba484556299511c10f762c162bd0114433dd1913f628540571c04f79490c30ade20434341b59e2bc66f489058d0aa2f14575942299783caf2e7b40d2a7bc10a150a6b0b1fa2a8ffb9631909bfc41c911a269859e458b7c36704e3b552ec8276e855c95b25066a85d1896123db2297a75fdaa015a60942ec7266f8d00511a1603fcb2e6d533e3fc7c126d2753b9704ed2c5608a226cff698a8fa53f9746eeab1c51796be3c013c44f0ad8ec2037e75369877c4d63a1fba7ac534f4b6852068ab973e1d9b96be70cc21659971c90aa7793e51a517f3108a2ff24fd3541cbb89b75786a546b346ddc92ab5eb93227057f0fb76e1554c0cf19bf0d08e33fb1abcfb71c1a0779a91a42af586cb27a9304a75e9604211640be36739fde51f2d9107fec20fbce665a45a1aeb76403958b94f23abe59c315ce9699203681167c379ac3f0f956070d73caba5bdf50c153e941158f2202de5857b834e3e553f7945398bcc70ee00cce8ec15296b2364393085f2821d36ce6f04b0b336bba762c387c69280bb4fff179eef54b925d99176167f4f916e2bfcb945a1bab4e5398a03c17c79992848bdefac5fae4667d37c75bae231d424381c39722fba787765b3005699b7b08d2785805d476679e29372b619e3568eb263c2aad8c891ca561271cb5868b5971445e1cc2e2f1a11e44c0a798c37250ca802eb4502d86db3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b22b22f73a770cbdb80da84f97f27a14c5df5b3372d52503d3a20c3cb2bea8b404e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +expected_public_key = de90503d536a810bc927784aac5b15feda774ed1b0550b7a7e656817866881a2a4ef682462e75391298f75f2061c70141aa682d50787162a6dcd853971665c9609bbd90ab833367a44a0286d860c04057c8ed7797712affa2557e2db46b546390f3163f05316aa8a12a7d49c4fe03337cb9a7218739ddb184c1304530667b9b54441015b9f8501f902bc2f3000a4855e68d7350e83728765057959662504331d5026c8d52088593d0acc1f39e74a7fa59b959967073bb14de163d73308c276ac0e6bc26e1c165b873e46972b72fc214544317c31556a76c09588c45e4762a1b43c7ea2a9dd238ac6e39e9cebaa1945544fd8702d7066d329c89656499e6c8264ca1be481ac792c5a52188e8a954c06a96e13604e2ec0242c78bdc7763359a47c2c5c4f7762819504740c043b2a5bc8db00cc4aa9a8c6354df515ba7d7039f0268637430067b81284f866bdda366a8c25c3808af025561f24bbf8671305ba3aed330898f18b854c501549aa9a1c68dcf1071af689f3c4a46b19709cf02bbcb07f65b44e9f9385c94c4385d88f8b502ca9e19a246498646bcfa1308f8a6c45638a0df58668f55a3d30440453c36875b0aa1b5967e617a296d284c4e2828b64b83fb176156ba7fe864007414c3eb247c4063acdd61b4e5c42b9147044b6916fa9be1d25ba71a035d766bf4c1c336b836b512a23549bbc53e1a8fada8246b41cf93604bc9b792868734fa755b06a7821e688ce17c9a00c7f9fd724dd494b070b9d4fb0a2963ccf41777f86ba3b318a1ea543913d5a653f073b34c64980e02cbe17cdba5a286443677a152b0da21ee54991f34b758b87a3cb690858f29a003031e8a99964f3a904023404ca51d730957f34a0beb402169a6bf7163963d87d9c6159b8e342cd8738c945b832b698655071286338b67b372a067305e5299043c884b4ac6f624d06f1167003cd5659b68f36bccde8b37c817db27870dd196135b21849843835ec1efed74af31a3bfc6cc33a988322622e2841799635084aaba1eca13b61ba765466b05c742279067c5a1a1355737c84199932660b15e1c124f5718e86a8953a0ea5182299a8a4c4a82f91aa901f40a64c2c1457864f0beb17f5b6733fdb8fa9a04d9ed1480dbb2ebe1b8a37917ed30257ceb062d4b3caac11cc1283542b6a711a737c64981afa7cc0dff00c7019ae2169bad10a6f60f094020b7b422b006135b65110076da0ac1e9b8f354a46200b3d58113953197e7a942671e3ca61c17f4256737dc71b12291eae2626ec136b6898047427525290a62380b2b246ad86ab59b12499c77936f816cdf15c5873147e37a71a2993aa11042cc83ca7b7656ff35429795a9ba01075d670a464b33e368b70ce7b484e864efa8b890892b8648461a61b75bd7455979325755292576878d0f94728fc2433c1c04ad8b52e55c93f36c564630c7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b59807f51fce23361e2abdb21a0803f4af1dfc8b55a594e746b241ab0bba37b285666de8431bd3e28c7d6b64e7e1377364c75c1a1b6b8147d91074cd862ded548788d825bde070ede391b0a794fef56231f36b7c451d25db6419e761e700b080db345c613226d38895d55889b10754b9706c33144805325c3295359ca2ab758dd321154ce457b9734ebe32c02546a7556b599733c036060631d5b4ff6c57a1b6c5065b80a691cbf3c604dcf49d914853c87b6758a58d56e406c04230548954242aa799e0532acbbdb9d9a50dc2bab0c91b0268bd2f0427717bc5b9456895c1660cab6c312549a8f15df9c7957b1a9f3c00a7487a812d429bb8f232b559a5daf57c27a96a99327a39f5b1ec95b4161316f1a27ab2470a162231a93761ccc64689d430d4872acf18a4ef71c0b6ebb3d552b2bf4abb43d70576c9a67c3647d5919be77a0af046bc6580bf05b109a66256a21ba44c45c516212aeadb7594fc6ca17bc436102ef3d99722fb3bbb0bb39c9a1c14085ccff8b57140488270c165a8abe44333999a383c83bf1bdc6cf63258908abe715bb383c385fc26635283af0853b3e533cc6cc95591c08fcff360fc6b506b861444b3b328045270b001a481662bc847fd15924f5744e359c18514a909ca163fecc8a1521c1b2955ab7917e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_private_key = cf8293b02a9a6f579f51066bd6e51abd270104634cfd482823102f2b63b18a8bb4f45a5af4d8202523cc1779b44fd283860bd004307c399ca5d8eacade156af824a988f5ac6bb50eafa6177a95b9752c922bd6a7c4265a6a88b11d0403e47127b1e80787742669e763929483393cad6ef91f18143e9d2b7cd3e028c6f56b91768113259bcab926a082a2a6185a1bf18656448a628258e21a3c6cca23449b4f9483ae9d01bdd4bc674e06566300ad2a215809e547e2626f8d9437baa727f3f05c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303d98223e1a4ef6536170f53a0c61004beb75fa34b8aed5156e4a538269775808283cb0ba5282607d50661d2a626fac2737c98cf33050353bb83e1c1136f1c26fe48d81973eb974ab1ba4b97c95c0dee065523430cc06620debba3db92888497658bc5c64b98be65ab2a0738f0750022b95a66c583354a63865b5237fe7098d279c53f731f3fcae8689754194a7b888199b89761fd09ff75677b2c500d7359905e76357163834712659f26d0d8c9b47192404975cfb89969a77615d1a3fb404baaa54511ff1b3b08c1577eb274f5b3b0b825434e87f60d18fa73141f912701a99a7c11305000789229a144a0899685596aa646f13573eba0b54dd3205de2c60c3ca1614066474b89f2377994bd14ee0a77e1d4c0af77748c1e623cb8947a98636694c4efaf0ce2bf779c66a317989a335a0071505831471c8d845a5fa4b3e42d195074244f70578124c4c7894ab84584daec8c13a6598524c023ca99f4c0499a68aca3e6827798b10ef9a4639605e2fe8656606438274ac8ed8c87ae0a16ba3b8e5857a7f25831d8b85bc7105828575320c6baba75489455154b31e50074a313ba9ad10b747f39405544f44949dde165070c8271f1ba80e57bb5bd1320c8a1f8fb47354079532bba51282ae3197026e18c46ae6b2ab9940eaba9f1ee421592770c9a9604263a4917c825c084c3534381f22c057592dd97940adb1a439d5128cf795cdd25640fa9229220a1ce4a6624cc9956105465246334c77ffcb9907159461cb1416637d8df34ab4b401413c27b6d5a1d23331f88273222653adf9685a614bec9840355b1a23a0c4ce60b0b678affed200bcb383bec2580c89127b2870745c15570ba1cec89f5dccc47be517bb020c57959e433c11df10810d5b37aa8ab3392b3358793246f11ece238646724beb859c861463c42b5030d9a1fdba3e1d391f9ca5a99df58a7948c66fa2b50864b73a40b52dc7cff031b3a3b21009268cd5cb00a89b44c156333b802ad03b2f07f70f7c11057ce78705ab6ee43681aff0874030807412a7743399cae832f6f3b65df56ab1b30d6967379e10b4ef53b9efb5632a23b942f832a7fa22cde494b0c7393d51ac807a38af119d526a5a3b91068e107812269ec85410aa739c288c20446b68880343f2e12157094dd424a349d1523e76c0acb9c29c22b6346386b522b0466bc8a85b97430a1df80850510c4825ec4f2aab987c4a07f11693e7bbb4662a4890a3c54ebc0cbbd75ca468428e38276e81c43d81a8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137c41fee75640774c4b536bb1d7bbce797847cf84043d49019e92fe9e9808f25990f79b52a4445ca842057b02418964fa53478ed974e781901825a3b33e0333c64c765857c97120bddab43a6154336c0a1bca4ae0aaacb3eabb4ca06928f351b21c99d40f533f3059a87a8ac7ffc5f37bc2b3722118a9aa945c935955809f1095eedbb252fa1264d37666596c771a663eab836fe703150236b769c07e23a9bdf43886a265101c20c8715057d281a7b0699df7c7a1b4055e29945952027a06454e9295b89ca0a8c873f7eb86a39e83176e0cfca61b333e32ea658120e417d65fa9f23e3b634e8a3430220ed775155e0084b9713bf2920aadc2de53905a030ac5cfc4405960772f5354bc20ec760301eb77c1efacd29878306699954ac96bcdbbcbb1642811cb18e7b96d16540a8394574a85d0ad6c4f53025b790685dcca38cb95f95fcbbf5240ae18a3913365a4f96a8a77839e1a269f7b94b3dc58f6ad94bc4f15409f775685016340c03521218df1c68fd554d0902b05f935ea20c6ba835112e408d2a756581d8bbb8ecc463761c722794de90503d536a810bc927784aac5b15feda774ed1b0550b7a7e656817866881a2a4ef682462e75391298f75f2061c70141aa682d50787162a6dcd853971665c9609bbd90ab833367a44a0286d860c04057c8ed7797712affa2557e2db46b546390f3163f05316aa8a12a7d49c4fe03337cb9a7218739ddb184c1304530667b9b54441015b9f8501f902bc2f3000a4855e68d7350e83728765057959662504331d5026c8d52088593d0acc1f39e74a7fa59b959967073bb14de163d73308c276ac0e6bc26e1c165b873e46972b72fc214544317c31556a76c09588c45e4762a1b43c7ea2a9dd238ac6e39e9cebaa1945544fd8702d7066d329c89656499e6c8264ca1be481ac792c5a52188e8a954c06a96e13604e2ec0242c78bdc7763359a47c2c5c4f7762819504740c043b2a5bc8db00cc4aa9a8c6354df515ba7d7039f0268637430067b81284f866bdda366a8c25c3808af025561f24bbf8671305ba3aed330898f18b854c501549aa9a1c68dcf1071af689f3c4a46b19709cf02bbcb07f65b44e9f9385c94c4385d88f8b502ca9e19a246498646bcfa1308f8a6c45638a0df58668f55a3d30440453c36875b0aa1b5967e617a296d284c4e2828b64b83fb176156ba7fe864007414c3eb247c4063acdd61b4e5c42b9147044b6916fa9be1d25ba71a035d766bf4c1c336b836b512a23549bbc53e1a8fada8246b41cf93604bc9b792868734fa755b06a7821e688ce17c9a00c7f9fd724dd494b070b9d4fb0a2963ccf41777f86ba3b318a1ea543913d5a653f073b34c64980e02cbe17cdba5a286443677a152b0da21ee54991f34b758b87a3cb690858f29a003031e8a99964f3a904023404ca51d730957f34a0beb402169a6bf7163963d87d9c6159b8e342cd8738c945b832b698655071286338b67b372a067305e5299043c884b4ac6f624d06f1167003cd5659b68f36bccde8b37c817db27870dd196135b21849843835ec1efed74af31a3bfc6cc33a988322622e2841799635084aaba1eca13b61ba765466b05c742279067c5a1a1355737c84199932660b15e1c124f5718e86a8953a0ea5182299a8a4c4a82f91aa901f40a64c2c1457864f0beb17f5b6733fdb8fa9a04d9ed1480dbb2ebe1b8a37917ed30257ceb062d4b3caac11cc1283542b6a711a737c64981afa7cc0dff00c7019ae2169bad10a6f60f094020b7b422b006135b65110076da0ac1e9b8f354a46200b3d58113953197e7a942671e3ca61c17f4256737dc71b12291eae2626ec136b6898047427525290a62380b2b246ad86ab59b12499c77936f816cdf15c5873147e37a71a2993aa11042cc83ca7b7656ff35429795a9ba01075d670a464b33e368b70ce7b484e864efa8b890892b8648461a61b75bd7455979325755292576878d0f94728fc2433c1c04ad8b52e55c93f36c564630c7cda98c29631b9939e64d86a8be9ceae4bafe668399b287226b59807f51fce23361e2abdb21a0803f4af1dfc8b55a594e746b241ab0bba37b285666de8431bd3e28c7d6b64e7e1377364c75c1a1b6b8147d91074cd862ded548788d825bde070ede391b0a794fef56231f36b7c451d25db6419e761e700b080db345c613226d38895d55889b10754b9706c33144805325c3295359ca2ab758dd321154ce457b9734ebe32c02546a7556b599733c036060631d5b4ff6c57a1b6c5065b80a691cbf3c604dcf49d914853c87b6758a58d56e406c04230548954242aa799e0532acbbdb9d9a50dc2bab0c91b0268bd2f0427717bc5b9456895c1660cab6c312549a8f15df9c7957b1a9f3c00a7487a812d429bb8f232b559a5daf57c27a96a99327a39f5b1ec95b4161316f1a27ab2470a162231a93761ccc64689d430d4872acf18a4ef71c0b6ebb3d552b2bf4abb43d70576c9a67c3647d5919be77a0af046bc6580bf05b109a66256a21ba44c45c516212aeadb7594fc6ca17bc436102ef3d99722fb3bbb0bb39c9a1c14085ccff8b57140488270c165a8abe44333999a383c83bf1bdc6cf63258908abe715bb383c385fc26635283af0853b3e533cc6cc95591c08fcff360fc6b506b861444b3b328045270b001a481662bc847fd15924f5744e359c18514a909ca163fecc8a1521c1b2955ab7917e343c452fc489fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e28709618588523d8fe8354d81146fd65af657da08926bd3a6ecbc2f81cb58d1aaacfe5b6e686f5aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +expected_public_key = a0eb8fea64c6c0da5d9a16254d897856a1486c8b2f773c18bab3cd4f80c83dac6dc9796100886d14b4085bb2265bd9c2f021034ef1083d58afd447ca55526d2691781d409649e88f43ca4e9b4aaf9bd9588ae52d126692b181817abb5291f660adf3a0044a0c527b233327c0f9db047c9415c806414bb0758dfab9a7d3c28484578b6084b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db333168c32033375a0321a287e133a9aca8eab024a85761ad4776b03a95130d0178f93684a2c0a519501ee5b85c4c3278e8b4e7b2b461cd4602a7918767b315cbcb885410ceb025f1342c2388637eb69ab0fc21568b1178ef3669a1b9e4fc30eadf5be70143ecdf543f1cc88e05a109920a5f3b4aabc0b8197783e8a16b1e06bc5e7089cc447186830a1d5bcc8bb31a6e91b691a65721791b0334495cd014c134617a3318a7906069e0574d83c8a44326db67ccf94a0a735942de923b5a6d55b087b4390e975e6b3aae4606abd3500fd54837ff875c54bcb7b5739ddc0adab741e57946ac0948ccef5ca791a46c669c552b97ec35633a141b92de18b0dba46ddc64431920938a927c255ab78fcbfc9653e1c0b8a0f42489674c0f79c30cf8a5073a06fbfaa888e914d53a3b6a86418f5ec6dd5a6b56973bdd9744d0ef326ab49291ba1b1a9f1a68da542fd944b3b88c6c364752fa6233d27a792e6a040f1824120ae9afa707d7206966a4ea361681627cb346572619c9a7d539db7469e60177e98674398ea296fc3005800c5da17a80ea06ad23a265ab7293401cdfe3460921596a7c228c883b0e1e48365fb02eb50950de3af481439dfb98447f3406c81161e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99c820e1f258825988d4827b5b1506a0129648101bd18823b2f2c2a142387f1a067a295175f5922eeb1de320711f0b729971bc7647889ee86cb5f44363a992369120dc837dd474baffd381253680f00675fb380bf96a89e282ae67c32b94ab48e35029145748eaa76037a98788c45dde75085d9c5523a7309804745f626f89362f7ba94738c5b9ba0b11bf560e855356e8cac1195cbb2921bfdad80db6b3bd9916a7c6cca281914f4fa5ad26d00e6f6acae0db49ae970755d16b2069b1a7ec0d7b879af301a9bf5519683bb3a59b066b62c8d150a316508b8c2c62a7f20fae59b3ccb0cc5e21055c7a638e11242c39855545b0a880484fb555f0fa4bb059ab05457bed820eee0767470628f81a321f113a8158a1ad1367f11802f71b90a8b4a1cc3c16552c11064ac01402b8b4b695d19ba74991673a963537b2ab14333633e04b0859472ecac568c87700a5076c8c265a3b0662c4250ae5cb53771cddcc2473f7bcc52ca97ba018beb6be5ba5420f7b2882f3acffbca13193c71eb60d167c1d9b256f4706a19204a017204ad28b6a0f607d61a97cb578cfc9633ba9d6ab84367cad900e5ce147ac935af727724af3ac8f0c86ec70034ea7c7f5330889b402f6b7be7bb6c7751411120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb311b338dc8a8e5b10c08b3ae26c945d680f4ad35dc07639c581301ca981be25075363b8d3a6b2165c99c0b61c298a502123c40e1cc223b21efabc1c34576e206456cc082cd4048fbb576e720bb967f5b58763342c98ae883cb24ca32e06398c56eb6a7b697df092926a8c76dc160f0c577ab476303647bad3b6951949acc2a69e793807a77c7ef163a25c842723d85665b121dc8622772caca988c5e8281d2e7055657100d31688b09104d0470d8953b82ea4c6afe50bb96b68f5524ac3a5a92cd26f26b142e37920ad36111226c763e3ce29c9c1235c8ea40995eb867ea8e844ed819c10f62172c52558667f4121bcac1815ee2806d863c22f10a20e74425f6c22b1900b520a5041b0a7f5842ad0fc0e19c893d7e42b1ecac89d9a989d8c45dedc5621565e2e788147c42ec4dc6a8ca22d4a1904787ac8b75232bb13aca7e30825e865bde0ce8ef1c7e2172d759873db265638fbacf7763b80fb4161417559a32c2d6cce4834be3316181ea4c5cd29687a498953998783057df991300f224324b207b723607961622f20377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_private_key = a428a1343429ce9c3dadbb6213410e264426d1cb5c69c68e7f377bcbc454aaf867771258faa622b6367fc5cc46e960682a3984a13230b3d7c25a69ce4ab9af0234a109878e0cc42a9b858dc559ad3fe82c4060539c08828c51b337b7c0ea768ba646a2f04900a235a4042b88e8934d3b62821a13b67a912f162aa80953cb71c396d91b91521b6665062551e0a6ce453c233460789138cb16ac6e598f670c70d6325804cc494466710d984e3ea551f5ec60c5031e94421919f62c301181831b7fb4fc61da443fe12784cf84b5ecf240daecc87d711aad10808b96233d345ba80b0469797dc03583214355e8e9a356e367a593a6898355ad129a8546a0d03b2279021889c118db3583da691a9ad544086540bb2178b2125f00c94ae753038486b6cdf1cf7e5a2202290b4e5ac807eb04bea95678b52ff76c4757c68d2eb9283b8766f1a39e06c999015b1f1d5c3164338aeb432d54b338c361b9a7258981555fc2563e585a6ff60886c32343e0045746e50fe78a0a9bcbb6281abe3474ba50e1267b3276a1327a8f128e2b5ab077618c59902c35488553f745d2a0c942b81c0aab7afd0c869b9b9c66c1847257cb22b018b81b25c468a9bc35a180b090f4bb90c4ec035c0078b799046833cd90f7bc2678cab9b75b95a6b457dca8fcb84937c01479a0b7b6da9643da507a2b8b1ae25373825189729bda8b35fcea315b3b359705cd5b486582379093e64f431309f0389ff899beb4c3ca9689b412a210eb654f183362ab8398b1e3696df7432be662cbe62666471f2c056504a5c1c91017a6326acc7306524058fd0937ddeab972b00734f60d065a1ba8655dba3093d161b99e698fc778b2fe782fa8ec7c62d422e17b24fd107b87a8338ae7af6994c70d959cbfc3720b3174b9658f5d43713cd47325eb926320073f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c2ff2a1f4a87159472e7d7a4db9243a1c6a636ad50735b870f1297b6d6b5303e2552a54aa5991340aa40301ca2d6bd9a765b72fbde1c3c44a7649ea350e00cde59628e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd544295317b55ea9ab1117989ab7b7304304e5612119396727943678c31cf2b1779c946b82420a557a8d6426263d33c7f71591c7857e90a7fa05158e315ae19d1046249b3011b22291cae30501d1423674824b852c34c97258ab972af6c5195ffa20b6cf05ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a529a1872ca25cb4a99c38b225e379ace27485d8b91fef9ceb97c04322b59f533745d23720ae457fa11b3a0b831de777d07f88ed1771fa1d89db9acbc7bac471bd423acac482bfb29de13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65bc2e6e04875754a77025985a026adcd321574ab45cda47134b560219338fc93b0a398d7f85169b4b32c2ec3a06529f8e3a57fd353327b03f87d5cb60c67074146fb460476c92619d9c23ba7a371fd9425cfc6486992959109cfa1c1a75ab9eba4235af63c6f8648ae7855a4eab5c9d3923386996181980b16b02a53060e5a64a8cf3ced087bb64f93693ccc0e77aa355d741f1f562692477ae0082a4e73e21f05fc386a8b32b09a4b79c41612eab0c29ffe610dea9713da3680be504f528b5eaab6d5caaa20c7221aa39345ad0b6aeba27a563ab6e1b65fd70a81d4cb97f6ba16e35773aeb8c1917aafc9b8f5254380395a41b474b27463f42e7c7b008a52d4395131c13cdebb7effa846dfa429af7393f8a688203bb6a814467d1bcdf931ad12811f22c0a0aa3c1949b2eb266c59aaa542605319b233769544070171801417816f730391a4d5d09127af868d8ebbd58b767b1aa7015dabef5b32b773b9329898cec8c94d80630b8447cb1c17c3c400134217c0acaaaf73b4b03132d779523e0c9cc52d28693da3dbd5507151c348b11898ad548ea305ca0484c67f1c70435c84096117702297f0094113b1c6ae66b25090f9b22a15cea69c95a2b8801a6df8611dbbc4cb92ccc21424f2a2537ad50206cb4bb90935381e62c571874f283cdab005254220d538115a75298e440924e9a3823d69a5eaba0ac73633179040f95a14026455f9403a0eb8fea64c6c0da5d9a16254d897856a1486c8b2f773c18bab3cd4f80c83dac6dc9796100886d14b4085bb2265bd9c2f021034ef1083d58afd447ca55526d2691781d409649e88f43ca4e9b4aaf9bd9588ae52d126692b181817abb5291f660adf3a0044a0c527b233327c0f9db047c9415c806414bb0758dfab9a7d3c28484578b6084b65ab0060ca20895c6bcb5353d295db2eb32170b5a214669d4c4971a1993c1b98557cb5f76e5b8e306aca954b04bfc6f0b0ca903a66db333168c32033375a0321a287e133a9aca8eab024a85761ad4776b03a95130d0178f93684a2c0a519501ee5b85c4c3278e8b4e7b2b461cd4602a7918767b315cbcb885410ceb025f1342c2388637eb69ab0fc21568b1178ef3669a1b9e4fc30eadf5be70143ecdf543f1cc88e05a109920a5f3b4aabc0b8197783e8a16b1e06bc5e7089cc447186830a1d5bcc8bb31a6e91b691a65721791b0334495cd014c134617a3318a7906069e0574d83c8a44326db67ccf94a0a735942de923b5a6d55b087b4390e975e6b3aae4606abd3500fd54837ff875c54bcb7b5739ddc0adab741e57946ac0948ccef5ca791a46c669c552b97ec35633a141b92de18b0dba46ddc64431920938a927c255ab78fcbfc9653e1c0b8a0f42489674c0f79c30cf8a5073a06fbfaa888e914d53a3b6a86418f5ec6dd5a6b56973bdd9744d0ef326ab49291ba1b1a9f1a68da542fd944b3b88c6c364752fa6233d27a792e6a040f1824120ae9afa707d7206966a4ea361681627cb346572619c9a7d539db7469e60177e98674398ea296fc3005800c5da17a80ea06ad23a265ab7293401cdfe3460921596a7c228c883b0e1e48365fb02eb50950de3af481439dfb98447f3406c81161e643f7095ca8c7a40b6d47f13d338be25335438cc457b3e99c820e1f258825988d4827b5b1506a0129648101bd18823b2f2c2a142387f1a067a295175f5922eeb1de320711f0b729971bc7647889ee86cb5f44363a992369120dc837dd474baffd381253680f00675fb380bf96a89e282ae67c32b94ab48e35029145748eaa76037a98788c45dde75085d9c5523a7309804745f626f89362f7ba94738c5b9ba0b11bf560e855356e8cac1195cbb2921bfdad80db6b3bd9916a7c6cca281914f4fa5ad26d00e6f6acae0db49ae970755d16b2069b1a7ec0d7b879af301a9bf5519683bb3a59b066b62c8d150a316508b8c2c62a7f20fae59b3ccb0cc5e21055c7a638e11242c39855545b0a880484fb555f0fa4bb059ab05457bed820eee0767470628f81a321f113a8158a1ad1367f11802f71b90a8b4a1cc3c16552c11064ac01402b8b4b695d19ba74991673a963537b2ab14333633e04b0859472ecac568c87700a5076c8c265a3b0662c4250ae5cb53771cddcc2473f7bcc52ca97ba018beb6be5ba5420f7b2882f3acffbca13193c71eb60d167c1d9b256f4706a19204a017204ad28b6a0f607d61a97cb578cfc9633ba9d6ab84367cad900e5ce147ac935af727724af3ac8f0c86ec70034ea7c7f5330889b402f6b7be7bb6c7751411120a5b6577c131cc75667990c0585caaccb1ae144140d47239b7adb311b338dc8a8e5b10c08b3ae26c945d680f4ad35dc07639c581301ca981be25075363b8d3a6b2165c99c0b61c298a502123c40e1cc223b21efabc1c34576e206456cc082cd4048fbb576e720bb967f5b58763342c98ae883cb24ca32e06398c56eb6a7b697df092926a8c76dc160f0c577ab476303647bad3b6951949acc2a69e793807a77c7ef163a25c842723d85665b121dc8622772caca988c5e8281d2e7055657100d31688b09104d0470d8953b82ea4c6afe50bb96b68f5524ac3a5a92cd26f26b142e37920ad36111226c763e3ce29c9c1235c8ea40995eb867ea8e844ed819c10f62172c52558667f4121bcac1815ee2806d863c22f10a20e74425f6c22b1900b520a5041b0a7f5842ad0fc0e19c893d7e42b1ecac89d9a989d8c45dedc5621565e2e788147c42ec4dc6a8ca22d4a1904787ac8b75232bb13aca7e30825e865bde0ce8ef1c7e2172d759873db265638fbacf7763b80fb4161417559a32c2d6cce4834be3316181ea4c5cd29687a498953998783057df991300f224324b207b723607961622f20377715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8236fc15e2340175a2a64ca1cf31a4b38ed5f797aaa8acb0c3d2ed9c19c7099f27e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +expected_public_key = 935770f4970a8e4b7b83c12a1e44c3eb360b42e77bd4435fb6f65cc14b894c387d0445af3f28cc2434138a07a667e5ac6bbba72dc3b7eaf788d8621dde4034a430c2de165b313733e2daacead1a014fb09d5b834411b8325728eb325b12310992012a7c4e05dba5017a59ba9777a9b3d5a681f79252e1c15ff8593bef7cd3c059153435bee16cd2b8433ef80bb21cbad40c6b945d7b6ddac39d0d0b558c7a42d9bcc701aadea5707f77498d5527e4f0b0bee834946302191d06f46116a77b884479a75a585a0c2105343584aeef31bd8a7aabbf669a2b2518f3805be390159b974ce43c83ef68b72024a42a942d8a03ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cb50fffc35c6a8b95172a0416130af7560ef1020ccf09c400101705ec1305ac95ca03143d22c93d72bd07e83afca94ec379142bea095c754533d802183a9b3cf2796ee2988184076d6c2235f39d250b080750762a0a31ffd26130700f6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc371c1de16bf2ba57359d060328a8cc01b948ed14197286ad0e8acef142dac64b4fe260cf066886c8ca9292ba2b3315a2d719c53b7acbb5125bbeb8d3df4caafb08ac54b8aa2816d3b44630623101f3b69e15c32c8e6912d61cdb2602734b206863c9b488431d72000e59c36e031471bd693e238314bc282dd8b4702d334e5985a8e89045f40652300a9dfeacf0c922e5b631f00c434085c5dac53bb4637c624c80dcd59a2205c8c5717554c114999e79b7ef020b7961f007541d009350bcc427aaccec0b0c9e3656214255689b24ae3cc874ff7c0574b09f0d8223e4c19cfb381a8c72f7324ad9e600669204b2590bd9ff6a589d26e0f2bbe575c39cb304ed5c8b692a17b65a7a27623144e7248eeebc4ac80239de04e8b3928e750a0bd44c30315647b5a6bf3e5955971c9f62b44ee01221ef93fa76843be32408563c111447541d98263212cab014e7897afbca8618a27b56bb9725aa1b711315e30aa445537bf02a201e5362e6b6b82f52506cf8c1e82f7912612b6e9126b7e725b30451d2001b76cb575ebc847db9b2a048277202b1434f9c936da846a6773dfe4193d019c7a7601fca114737559df7aac095849692831156a13a9060510e05bb9f48a01506a08f63ca5cb4b032962b6d484e8cb742b0709023b9926562bc83c72c047833e27760d6a8a8c559a096600254909db3668b0e2c8bbab67413827a2c808bf6c2662553b4d9166a152931f30031fb15822c12462b714276c743b2691e69321946cad96f9bd71982f47970fce751b013630f5aa90334c657d286f94d325333b64c6bc9955e859f8c51c1961400388bb9de91fbf4bafe8853b1ce98e9f1076af1406458b00ccf021da408575e126d850a3a1d51f31069194d65c4df88b94d8b43a4b6ee651654d6bc72b8c283c49093eb3b1dadc9bd329b11862542da3b770657318f13fe4b07b1d22482c0410652a3b52c2216f3028fa47c3e5934c3540b644a282729196ca366e1064bf5e57ae739229e3f092c3cc91e8e833c4e314b6cb91e6873f35cc4ad2b60281c862b9d0ca89aa0966713ca0e973a766cf303aa1082266923cba1ce7a91964440d43878fd359583c6de0f5c6c86424a1096d5bdbb843990f0b8285681bba7ae82008a56f992267133b7bd1a55f0fb37f84d6b2609cbc49c968925069aab3498ff7c986f522b0f2a1512a8cb5a6bebbe62f28901f2c5073896381255912fc482e9ef57132ea5f5f61b36a5a17366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8aad129ccd6c796b2883ff989650c04af16b339ec34912226f586286a553db3362c5e1056a369b22c1467cdd4a633b03585f82116510127aaa1459b2dfe049e6f191dd7cb4d0a8ac5df064e64b9021440357c4562302bb0ed0a6aa94ba1dd55a50829a574007608bc61508a0f17d41dc3bbcb8e91c4dee25d2ea4700d905348026046450ad0c2768ad72eb0b770d45a7416c041160170b8511da2958f44c9b06060183bb37967282062e0a93eb5bb4b2b15a4152c6f19b730b724f94aab64b60b7ef5080b251ae0290746c249b1a76c96825653a89914b1ce70982d3cd437837854c6d28f871999073b1c2024088f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_private_key = fa198bb15b4278509dc232002c75a8bbf1853c474c8248b5062821e4d77fd5880979922016d17377f76a89ab9477a1024c9780fb728f6df3295666828143c52fe817b9688c70eba292d2716ab4970840abc4603f597b5fcdeb0144813602242625a067ea48b426738dad0ab986369aa5326dd199c72212c59ab20c8f63429683721a2c682c5aa853b86542698732ab86fe39c340db2d452286fdd599336b9923599b66c144c0c7848c20a6979133fb7b5efa3726a4f44389cb93d6a9c1b7e300cb852698c236ac00b2855861c88bad062a25423362c7774c1626834ee59880762508fb518f926a3f475d01aa8e5c8c4140537091d494af66b0e9426359032a2264af67e63541c2408b1853f87c68c28c8c13417f94d77f6ac3315f23405c233e14f7762c152609ac34842553de175a6fe1c08b44baa9d15cf09a6049b05b69f71df322171701ae91d050778a6754e374878169181a2e1336677889318cb54218ac055491b918bc2553023167151c98b30e1340403e0c59b3252f4d0c85ebac1877798c41aa43c5c7b738b7ce116428c049370ba6665be646b3125aeb947b1f3b2ec5357c7566c13eab148c453d6b2274a9295a06c822df9222cb2026f19603b5602d08d46d4c71384e776af2a441894826e4559f5975c586e47bc0236b4897622ae4396160334cc97aca101805814ae44786d1e445147a4728275c32554b9bd148ae9605e10c5a6b556704f1c17297a32eb311f1e92ee5f160e8522e06554b93b5c796e44086e75d236ca88ecc533c3b348091891e35639bd6cbdb3a408720b6e3a328c4268454169267a5c5348703c412c58846c192e0a162014600dbb351424fa8d0599775bd2d851db4b07438f655aad6402628563db3a435f75d440636cd64041de162d178c923490839f190f106be0020ab63e7b3eb718a4fb59e01057c416c330cc26e485a6d9c72b707da0b297c0a25247d26d40f044844c2db883a5bbfc2b06f1bfbccc6d10b65c9bdbfb806d7a04cd71774dd60bc423c1dfa897a0512365cd54a90ba6ac509298bf6455363583843925281aa405c291f11695cda995a9ac5f742351560b38f8720d66327b4dcc47626744241679247cbe42695b8d81c37c718cad53d1b318f9f900757267c43b982f26639901028f8f636c35091f1ca90a1e329d5cb069a918f45a078f33ab4dfd248390627926aaddff47ecef1718b2b048304cd40e72fb0872b6207856a61bd764034e82bb426747405e1ae5b93c63cb12c7bf09e47e27117d26acbc102b043616e60b714316dfc17306a77800ee87e03e4b74759794ee6943dc274aec1a08197a841e68f258202b1124803064f6e3295dd51ad18949a5a383a81363bb00118a8569a38d138bf8835362c723e999402d3cf728b0e11f647ce2b9390615b9e50487e23cee6f9cefc4a1ce5e83d28d642e3c16934b43931158ccef3832a457a5e833f317918858807ab084f687a394c257abcd8435cd717d1e6b79e78a37bb71a236729839b89a9905b5d935afdc2c1e6c71c597898c6a69765ba05e9784b7849c685ab5b6de3358c6299d8a4b075045d6ee15b639601aa95603a67378157b54889c3021453e373208cd06c0deb7747e411c2150b7d93118870818d5502490121a43898dca59417088eb0d9ce88497b12294687619053d9beab9a13c663b24058b620826fc7b03442bc998f568ca7f570dc638c0f781114fa6642e2cb4eaac2f638c85251c1f99422b13a1d58bc541de67069a228098bb61ad060a39cc5fa5b9495b79c92993f97284c9a657be1e528ae333061759c38a5a662aac58d214b7f837311c92e5d042142190446aa3d646495554cc7f37656ed89749f5028b1ea008163b5bb13244dc41a394a18e589a85a2bc4e71b596e15b6fcd64c59ec031678ac9e0a439b6a31233c0f1b6b5164320f74860817cb3a82f79828191300c8b9543a5b1e2c59b9c6867eaab23c542787262233578c1ff30a3a1a06991343962119ef718cb35080c6c785f91709f8b713ec7b1f47bb9d2f1c9d394cc6fe24ce45840322912f2288335ac78402c2cac4614b93a97104719a68963696a82477dc43a959a9aeb004ad3016ab18a33bcb3f61f731f91ab66d61867a94b2729c01c3d50737720249406333acb1dae84c9eeb89935770f4970a8e4b7b83c12a1e44c3eb360b42e77bd4435fb6f65cc14b894c387d0445af3f28cc2434138a07a667e5ac6bbba72dc3b7eaf788d8621dde4034a430c2de165b313733e2daacead1a014fb09d5b834411b8325728eb325b12310992012a7c4e05dba5017a59ba9777a9b3d5a681f79252e1c15ff8593bef7cd3c059153435bee16cd2b8433ef80bb21cbad40c6b945d7b6ddac39d0d0b558c7a42d9bcc701aadea5707f77498d5527e4f0b0bee834946302191d06f46116a77b884479a75a585a0c2105343584aeef31bd8a7aabbf669a2b2518f3805be390159b974ce43c83ef68b72024a42a942d8a03ffc5a5429265214b68dfd4aa094ec4e1bdb6d8295c36cb50fffc35c6a8b95172a0416130af7560ef1020ccf09c400101705ec1305ac95ca03143d22c93d72bd07e83afca94ec379142bea095c754533d802183a9b3cf2796ee2988184076d6c2235f39d250b080750762a0a31ffd26130700f6799867cab43841ab906377ee5bb48dcaaa3bf79584af9360c937fc371c1de16bf2ba57359d060328a8cc01b948ed14197286ad0e8acef142dac64b4fe260cf066886c8ca9292ba2b3315a2d719c53b7acbb5125bbeb8d3df4caafb08ac54b8aa2816d3b44630623101f3b69e15c32c8e6912d61cdb2602734b206863c9b488431d72000e59c36e031471bd693e238314bc282dd8b4702d334e5985a8e89045f40652300a9dfeacf0c922e5b631f00c434085c5dac53bb4637c624c80dcd59a2205c8c5717554c114999e79b7ef020b7961f007541d009350bcc427aaccec0b0c9e3656214255689b24ae3cc874ff7c0574b09f0d8223e4c19cfb381a8c72f7324ad9e600669204b2590bd9ff6a589d26e0f2bbe575c39cb304ed5c8b692a17b65a7a27623144e7248eeebc4ac80239de04e8b3928e750a0bd44c30315647b5a6bf3e5955971c9f62b44ee01221ef93fa76843be32408563c111447541d98263212cab014e7897afbca8618a27b56bb9725aa1b711315e30aa445537bf02a201e5362e6b6b82f52506cf8c1e82f7912612b6e9126b7e725b30451d2001b76cb575ebc847db9b2a048277202b1434f9c936da846a6773dfe4193d019c7a7601fca114737559df7aac095849692831156a13a9060510e05bb9f48a01506a08f63ca5cb4b032962b6d484e8cb742b0709023b9926562bc83c72c047833e27760d6a8a8c559a096600254909db3668b0e2c8bbab67413827a2c808bf6c2662553b4d9166a152931f30031fb15822c12462b714276c743b2691e69321946cad96f9bd71982f47970fce751b013630f5aa90334c657d286f94d325333b64c6bc9955e859f8c51c1961400388bb9de91fbf4bafe8853b1ce98e9f1076af1406458b00ccf021da408575e126d850a3a1d51f31069194d65c4df88b94d8b43a4b6ee651654d6bc72b8c283c49093eb3b1dadc9bd329b11862542da3b770657318f13fe4b07b1d22482c0410652a3b52c2216f3028fa47c3e5934c3540b644a282729196ca366e1064bf5e57ae739229e3f092c3cc91e8e833c4e314b6cb91e6873f35cc4ad2b60281c862b9d0ca89aa0966713ca0e973a766cf303aa1082266923cba1ce7a91964440d43878fd359583c6de0f5c6c86424a1096d5bdbb843990f0b8285681bba7ae82008a56f992267133b7bd1a55f0fb37f84d6b2609cbc49c968925069aab3498ff7c986f522b0f2a1512a8cb5a6bebbe62f28901f2c5073896381255912fc482e9ef57132ea5f5f61b36a5a17366cc924d8859338cbff9782d168618ad6a7e53446bc7ba73c86b8aad129ccd6c796b2883ff989650c04af16b339ec34912226f586286a553db3362c5e1056a369b22c1467cdd4a633b03585f82116510127aaa1459b2dfe049e6f191dd7cb4d0a8ac5df064e64b9021440357c4562302bb0ed0a6aa94ba1dd55a50829a574007608bc61508a0f17d41dc3bbcb8e91c4dee25d2ea4700d905348026046450ad0c2768ad72eb0b770d45a7416c041160170b8511da2958f44c9b06060183bb37967282062e0a93eb5bb4b2b15a4152c6f19b730b724f94aab64b60b7ef5080b251ae0290746c249b1a76c96825653a89914b1ce70982d3cd437837854c6d28f871999073b1c2024088f9b8c1ea5c3f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc7526a1b77ae8a807e9de16a9ede5da5aec3ca5f23f5ea00e455d4a091467e6ac6dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = 195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +expected_public_key = 5064909f424a15515fbf534b4f660b09e9146c40ac273822eb116ac60782dc519805c41f39a306d7e21d0fc2264b8bb6637b113144b0d459ba833965d3a39c51355416f672b25811f5f2ce8cec777ba322ce506823d6005d1147600808ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7efc25874d5190b893039493204f67e11560e49412b484781c571324f76218976a1633bc4ca3c0a6d8211c6c0171e0993baf46406f8b85fa0c7f0551b74ab81d642c634ea74b269837e2588228a8645764a2b9a7bc2a802682b22c24c2a55439d14d12e620363271a4468fcacfa8ba686f1bdbfc70ca9c0961f9a488b7962b8c718b9e7a33d8b5306e6a05616c2a1484aa044200038624f65b8a92ba4739c714ac71fb8f12af92c5cc06c2bb59367c5c471bbe6099d1b19c9bb1aa168c071dbc6e01c5c72fa33171c52b78c1deb32134dd8af5d147bdea32dd6c52450c112bc5a0d9e03b06d807173304972a9866ae4bf6b053d98680858671ce1f252293972c42c4bf6ec2ba9f11be4325c34f89e7d500dd749ae3c845f7d56815f11a2fb07b9e3f88cacb51e2ed258cf5bb981b089cba18f902c14e04503302ca929319645154cfa878cfc777f2093a00916a617b6086d973208883ace08270eb16be4ec404eb2951bb1ac825840bee09eba19a90b5316ab79c3ac062c07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f28a15e49863a2139dec116d99374236c8a7169053fa716756299ed16125d699c39357133fa49fe0db960a8cbc0adb979239b64a7b3a702878fc1610868790abf3968873ae5dc19020b28f1405cca1b0800ef236e020aed6157892161b54bb3d14a4c64fa1ab949648020ca86064b17fe8b3f7d915c72a68e2b46f16267b7598bc112537b7681ea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccc51f9a5357fd4b92ce4906183c0031727c7a966bf0c485a9312f7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c33fc2033c04294a91323f1602a6da351f0a6e478264e0e4a6adda77dd6a2535a748daa074af31af028509f2c27f15f00e60e72f7a7032dfb99d50c88814167a838758c2685243839d8ac19e76133b40dac70e49b33ff83299862c3496999dfa90470b7bb17bcd14019b093b5787abada26700a83377ae57173fe528d6dc35efe846d95933d68144ea3aca554ca0e873baa6bb926d70a09306621b3705942b4e0d60cbf200c10c3c4d5f7c8c75899aeaea40cec8928ae25baa2c7f139392221cc7042c05baf58371010492bc2125d27a9bb01a28a3855c98b894d4165689af39c0a26a6b920874728d475daa731940457b24199d11841d5bc369962c1cf3920b6af974b3150189919959c3b4e556c56fb22e5597b64506575f6799dd86cb0669651a1c017c8a74e5f63cc60b9047b21dee777df6010bd6a614f9a63c72074b7909137cb7155fea72bedb7428e0b197246af69121e97923f861af31f10249e11795a180c0c6c056d58d848a62370278308c4cc2b466a8d7231456c06e4b9f1faa65a8f0113f99238c52ae3c3a24600c4e943947c8c653c946bbf6b4cee89646aa23afc7b22f0d45464337a90a7c22cbdb4449b24d5bf3c070778773b92055206ca895105e264c9757918f6bb76bfc93de826c61c77b6a51b135915235271faad3cf608c0033b2581fc522965257eef576ebf7379a173b1b269e27648189696b30346d5202b560784777f88aca2c9f900344eef8aa0cb4a86ed6335be29b91248780674bbadb5b11f967a663c2f9129b73ec584c50aaae9771d258272198261f362d93830880e4b60e4b142b3822816501c89b5011681a5ec2ba2b03cf9eb1886c33c1c72cb6061b10638931e5f1461f413e5766a7becc59a052a0e221c6419752258955dce743131890bab88b8dcc5738eb6f409c1c0d888de1d0c5a7bb03e80171c2b41dfd411f74b5165804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca4e296f0d975f2f5731d822627c1964ec1bb1ac7452bf0c5c0735d6f75304efa4410e4cd20557b574cad1674395436203db728a58b8e0b95183c10653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_private_key = 55873ec8c5bac259501e025faed327b9b659b0810e7d43b8bf7a25a8c1a51062cfbc9bbeab182747196797913398db1c1ca41c1cc3a883400a29797ab4cbb553076c204167aad2208355279f504dd9a476985362898b4e423821cc2642c335c3c953c866451cece03098d5a2ae366ddae1a06e05547e1c0c0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a921fb14042aac83a1b4897bc6a15c87fc94144828966c49b6cb8f842a3157b60d6b3271c3661529d8a93c7daf7b4de1396308c0cbbfc9f984617cbb5b1825c88bdbc4c74c58ef3d54d089613a6a431e3a59acf4201fbb6828db0061f1bc514dcbfe72023cf8102e9834d5d6bba8a354fe04c6008b37f9b07857cda1238f5a562f288f3217ffd1a1bf8b2a0fcf3af0310c84bd6cd805c246c4a227c9bcf963093a9755cba968e7c06cc4f987b516171461b69e013076cb652c2a0b10f1b0fc9d6b583a929fa3905ba4b6b41f19d862c82b5f170277530a278773fa740eca749c00a61735aa1a27719cfb75eb0768956718239f43239e25a316339db665eb9784ab581137d020b992782956522b824b3ea4cb540a4b12ad7c512046711b0463f779e1279bcd2b7238580c72df6120850376db48978dc717cd1424d0b5e7331b76d0ac0b024c6283c8418e5b1a7a297aa483e5d2a65f2181ede32c69cc4b9a8c4c0b90bb17ec06336d2100766aed931876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb737647504ea1a29d13e0bc2d060bf7480345051e9379cfb0f901b9a426641802e5522ff8b199439026b123cf9b5827ffa147567912c46c88cef0b41d9526d227a72262c0e3b3157dc4898e07caebc8038142b5172a799b8a6db0f7703730c98e1957fef13d5d7b2a52945eff5c4337b6cc5004bacbb419ba73568aa357f61c70383447c6015a5896b9c0c0a2f2c7a76d940278d736d6b685f4fb3cc392caac1830b439468b6bc73585b4205751e55103099986308702a477588611a990580d88657024fa6d371550141405a8240109824788675d2546afad54628e93281abccae4eac11d200aa5c40a9e440d9f2a40deb31c2688a3266c9e16b60461087da271a1973374c99693c8111f9d458f92ac3208268078b177c818038305ab421b6d8297063061bb36f1318bb2108163a723a4bfc3c2a25f958f28b2b806a15e4310b8852103843c8ac26c7773084f1f82151c52083e69772a049123027916f039fd08713b98039f3b84cc83a8f88b2c19f48a958a443339a5a2158dfd7a08d11983601a1892a8c1152c602edb1592c3ae555b2ee54c5dc6020c0b95626fc06d85d78120ac135fd369de6b6aa902bb015a7bc3ba13a7391960c533d2f1a6278494e78b6a3c5b91a2b1aa2a0752e5c0a30e33cc86dcba2e3232c98b9aaf1bbdf9e825b15a6dc3a741d43a53eb10ad18e93541e224ec5a952d673984990af0d81577d1bc83b09856794d11707faac63a1e49a799224b51464916bc07f0a69f06f26696f5806e92ca4ada050cda48a9c90635a9c68acc753a711115c35488758a68256a32f4964c431d50c0a8c5053d1a41126a952270a309f69931c32194fd201bc3809db548a0005585081c6b11db7a19e14f9a4777c5c12b35289100d979e5b5b306c6692136a839ca4dda2a1e9d3bb3c418a732ec4997d124b7d6cb4bb090c0f35ac2d206f2b1b19dda1929ac935b2cb24e320ea87acbcccac6d4454b8a183e89e8738dc645f50239232ba5ea03baa3590cd29c05ff4c33d8107aade2104bc879ebaa431294b201e2b589647c29c66f7f3677ec30bb1bbba093b60abb147cdc07748b098ec1f83855464b1aebb41bf30f4ceb59c41c24701a39dc74b44fd8505980c1786275cf16272a29c285406c70eac1de5969d459ce1f211c8a47be727a57a772566984452e2b2ea96abaeb3a0990b9a7fbe5147f6a438e27a3624355b97c7140406d52870c421754886acaccab09b2351ad28716c476b61d7c9082f8cd81d31554f334af75030c4075d2965a9df37af81a4588ac0241183247c5047bb81dfb6bbd7252993d69cf5660abcf2aa5c9787f10c02793e9bb1ccbc3761b25759a38cf2c28ed1ca65700112e540eb4b0587e036b9502223fb95e2815a5e6f9c384369c24b1a962c4b05064909f424a15515fbf534b4f660b09e9146c40ac273822eb116ac60782dc519805c41f39a306d7e21d0fc2264b8bb6637b113144b0d459ba833965d3a39c51355416f672b25811f5f2ce8cec777ba322ce506823d6005d1147600808ca3c4d344a5f9d47336254766003341047ae044691650c907d937e5dab543f767fadd988e0bbb7efc25874d5190b893039493204f67e11560e49412b484781c571324f76218976a1633bc4ca3c0a6d8211c6c0171e0993baf46406f8b85fa0c7f0551b74ab81d642c634ea74b269837e2588228a8645764a2b9a7bc2a802682b22c24c2a55439d14d12e620363271a4468fcacfa8ba686f1bdbfc70ca9c0961f9a488b7962b8c718b9e7a33d8b5306e6a05616c2a1484aa044200038624f65b8a92ba4739c714ac71fb8f12af92c5cc06c2bb59367c5c471bbe6099d1b19c9bb1aa168c071dbc6e01c5c72fa33171c52b78c1deb32134dd8af5d147bdea32dd6c52450c112bc5a0d9e03b06d807173304972a9866ae4bf6b053d98680858671ce1f252293972c42c4bf6ec2ba9f11be4325c34f89e7d500dd749ae3c845f7d56815f11a2fb07b9e3f88cacb51e2ed258cf5bb981b089cba18f902c14e04503302ca929319645154cfa878cfc777f2093a00916a617b6086d973208883ace08270eb16be4ec404eb2951bb1ac825840bee09eba19a90b5316ab79c3ac062c07f45782f4ccbdeab590196f8436a8ebdc90ea944c50e842342a5a558ac8e833908c0577f28a15e49863a2139dec116d99374236c8a7169053fa716756299ed16125d699c39357133fa49fe0db960a8cbc0adb979239b64a7b3a702878fc1610868790abf3968873ae5dc19020b28f1405cca1b0800ef236e020aed6157892161b54bb3d14a4c64fa1ab949648020ca86064b17fe8b3f7d915c72a68e2b46f16267b7598bc112537b7681ea2bba503d8a62d55cd76e6579bda3e032399ba2ca6cf0b74ccc51f9a5357fd4b92ce4906183c0031727c7a966bf0c485a9312f7a76554a35c065278860396c2ed4b0b44b85c3d7c16c65c33fc2033c04294a91323f1602a6da351f0a6e478264e0e4a6adda77dd6a2535a748daa074af31af028509f2c27f15f00e60e72f7a7032dfb99d50c88814167a838758c2685243839d8ac19e76133b40dac70e49b33ff83299862c3496999dfa90470b7bb17bcd14019b093b5787abada26700a83377ae57173fe528d6dc35efe846d95933d68144ea3aca554ca0e873baa6bb926d70a09306621b3705942b4e0d60cbf200c10c3c4d5f7c8c75899aeaea40cec8928ae25baa2c7f139392221cc7042c05baf58371010492bc2125d27a9bb01a28a3855c98b894d4165689af39c0a26a6b920874728d475daa731940457b24199d11841d5bc369962c1cf3920b6af974b3150189919959c3b4e556c56fb22e5597b64506575f6799dd86cb0669651a1c017c8a74e5f63cc60b9047b21dee777df6010bd6a614f9a63c72074b7909137cb7155fea72bedb7428e0b197246af69121e97923f861af31f10249e11795a180c0c6c056d58d848a62370278308c4cc2b466a8d7231456c06e4b9f1faa65a8f0113f99238c52ae3c3a24600c4e943947c8c653c946bbf6b4cee89646aa23afc7b22f0d45464337a90a7c22cbdb4449b24d5bf3c070778773b92055206ca895105e264c9757918f6bb76bfc93de826c61c77b6a51b135915235271faad3cf608c0033b2581fc522965257eef576ebf7379a173b1b269e27648189696b30346d5202b560784777f88aca2c9f900344eef8aa0cb4a86ed6335be29b91248780674bbadb5b11f967a663c2f9129b73ec584c50aaae9771d258272198261f362d93830880e4b60e4b142b3822816501c89b5011681a5ec2ba2b03cf9eb1886c33c1c72cb6061b10638931e5f1461f413e5766a7becc59a052a0e221c6419752258955dce743131890bab88b8dcc5738eb6f409c1c0d888de1d0c5a7bb03e80171c2b41dfd411f74b5165804b82ef473bdf5ca37983cc1047fb5a4a34598c8a98a5b0ea78fbe27b9929753b89a6c9f2c7d0677aca4e296f0d975f2f5731d822627c1964ec1bb1ac7452bf0c5c0735d6f75304efa4410e4cd20557b574cad1674395436203db728a58b8e0b95183c10653b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b82460170e6cf1da1e7b92037f51b4e7674d9abf74f5c225c5c6ce16a971691284ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/keygen512draft b/libcrux-kem/tests/kats/wycheproof_early/keygen512draft new file mode 100644 index 000000000..d69c5589a --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/keygen512draft @@ -0,0 +1,500 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +expected_public_key = 115ace0e64677cbb7dcfc93c16d3a305f67615a488d711aa56698c5663ab7ac9ce66d547c0595f98a43f4650bbe08c364d976789117d34f6ae51ac063cb55c6ca32558227dfef807d19c30de414424097f6aa236a1053b4a07a76be372a5c6b6002791ebe0afdaf54e1ca237ff545ba68343e745c04ad1639dbc590346b6b9569b56dbbfe53151913066e5c85527dc9468110a136a411497c227dcb8c9b25570b7a0e42aada6709f23208f5d496ebab7843f6483bf0c0c73a40296ec2c6440001394c99ca173d5c775b7f415d02a5a26a07407918587c41169f2b7178755acc27fc8b19c4c4b3fcd41053f2c74c8a10a8321241b2802432875ae808b9ef1365c7b8a52902f1317ba2fb0269f47930672107b4726fef64547394d3320c8f120b3c2f4725b0305fab88cc7981fcb09a76a1cbf7f179f43bb0a4c8b0590857f1e69708466c7f8607391e7bc5268bfd3d7a1dffcb4eca2a1c9b597593013d5fc4202ec2b74e57ab76bbcf3632bbaf97cdc418a6f16392838ca9bf45ddf023777b7561833c105190f94f302c59b531900bbc816361faa5b3380ca3a893104ca7388b185671b3e5fe3790e9a626ec46d9b0b33c7a419af7b32b6859894f575d82ac5456b5490a7af8fe61046360589ecba7244236f4123116b6174aa179249a49195b356c72fc6641f0251812eaa98570b046699070e0819dc2713f469137dfc6a3d7b92b298995ee780369153ac366b06d7249cd09e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf598159a7792cb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4932612ec915e4ca346a9bce5dd60417c6b2a89b1cc435643f875bdc5a7e5b3481cf919ea09172febc46d4fc3fb0cb9591704ee2dbb61844b2f3314a06bb6c6d34005e485ce667bdc7d098586928d2d91340f00419ea401351a240a0b041058befb0c2fd32645b7a2df8f5cbfd873327c978d7b351a28088438837024c52b9c295cd713646fb5d6c0ccfb470734ac2b2bc8123c2c13df6938e92455a862639feb8a64b85163e32707e037b38d8ac3922b45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_private_key = 6c892b0297a9c7641493f87daf3533eed61f07f4652066337ed74046dcc71ba03f30960103161f7deb53a71b11617263fe2a809769ce6d70a85fe600ece29d7f36a16d331b8b2a9e1db8c090742df0739ff060ceb4ecc5ab1c5e55ac97bb66a7f895105d57782b229538e3421544a3421408dbf44910934cc423774f1676ff1c306f97555f57b4aed7a6bab950a8163c8d318dea62751bd6abc5069c06c88f330026a19806a03b97a7696b56da21827bb4e8dc031152b41b892a9e99adf6e1963e96578828154f467033846920fbb4b80544e7e8a81ae963cf368c9ba037a8c2ad62e32b6e61c91d75ce005ab30f8099a1f29d7b6305b4dc06e25680bb00992f717fe6c115a8084231cc79dd700ea6912ac7fa0d937bb6a756662230470c189b5aa1653deb937d5a9c25a21d93b19074fc239d8153539797c7d4ab62649d76aa553736a949022c22c52baeec605b32ce9e5b9384903558ca9d6a3aba90423eeda01c94198b192a8ba9063497a0c5013307ddd863526471a4d99523eb417f291aac0c3a581b6da00732e5e81b1f7c879b1693c13b6f9f7931622429e542af4069222f045544e0cc4fb24d4448cf2c6596f5cb08624b1185013b6b020892f96bdfd4ada9179de727b8d9426e0996b5d34948ce02d0c369b37cbb54d3479ed8b582e9e728929b4c71c9be11d45b20c4bdc3c74313223f58274e8ba5244447c495950b84cb0c3c273640108a3397944573279328996cdc0c913c958ad620ba8b5e5ecbbb7e13cb9c70bd5ab30eb7488c97001c20498f1d7cc06da76bf520c658ccadfa2956424557abea8ab89239c17833dc3a49b36a9ae9a486940540eb444f97152357e02035939d75a3c025f41a40082382a0733c39b0622b740e407592c62ecaeb1432c445b3703a86f6981a278157ea95a6e92d55e4b972f936c2f0a658280ea2b07a48992df8937e0a2ac1dcc974fe00aae1f561fa258e2d259c3e861dce236039127606fc1ce009003a7bac942101dcb822b1f3c12bf73238f546e01c36b5a6936192995cc69c63237409cb53c2e35d74890d18885376fa5503b107a2a392115ace0e64677cbb7dcfc93c16d3a305f67615a488d711aa56698c5663ab7ac9ce66d547c0595f98a43f4650bbe08c364d976789117d34f6ae51ac063cb55c6ca32558227dfef807d19c30de414424097f6aa236a1053b4a07a76be372a5c6b6002791ebe0afdaf54e1ca237ff545ba68343e745c04ad1639dbc590346b6b9569b56dbbfe53151913066e5c85527dc9468110a136a411497c227dcb8c9b25570b7a0e42aada6709f23208f5d496ebab7843f6483bf0c0c73a40296ec2c6440001394c99ca173d5c775b7f415d02a5a26a07407918587c41169f2b7178755acc27fc8b19c4c4b3fcd41053f2c74c8a10a8321241b2802432875ae808b9ef1365c7b8a52902f1317ba2fb0269f47930672107b4726fef64547394d3320c8f120b3c2f4725b0305fab88cc7981fcb09a76a1cbf7f179f43bb0a4c8b0590857f1e69708466c7f8607391e7bc5268bfd3d7a1dffcb4eca2a1c9b597593013d5fc4202ec2b74e57ab76bbcf3632bbaf97cdc418a6f16392838ca9bf45ddf023777b7561833c105190f94f302c59b531900bbc816361faa5b3380ca3a893104ca7388b185671b3e5fe3790e9a626ec46d9b0b33c7a419af7b32b6859894f575d82ac5456b5490a7af8fe61046360589ecba7244236f4123116b6174aa179249a49195b356c72fc6641f0251812eaa98570b046699070e0819dc2713f469137dfc6a3d7b92b298995ee780369153ac366b06d7249cd09e1b3378fb04399cecb8650581d637c79ae67d6f2caf6abacf598159a7792cb3c971d1499d2373ad20f63f03bb59ed137384ac61a7155143b8ca4932612ec915e4ca346a9bce5dd60417c6b2a89b1cc435643f875bdc5a7e5b3481cf919ea09172febc46d4fc3fb0cb9591704ee2dbb61844b2f3314a06bb6c6d34005e485ce667bdc7d098586928d2d91340f00419ea401351a240a0b041058befb0c2fd32645b7a2df8f5cbfd873327c978d7b351a28088438837024c52b9c295cd713646fb5d6c0ccfb470734ac2b2bc8123c2c13df6938e92455a862639feb8a64b85163e32707e037b38d8ac3922b45187bb65eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b539227ffad1bc8af73b7e874956b81c2a2ef0bfabe8dc93d77b2fbc9e0c64efa01e848626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +expected_public_key = 2c421ad4a7848cdc4b73987cf2f85e660c65e468346672ab09ea8b106b2ed51246271bc9d21672f6aa0b3a9b24c8f64722842f2e24cb2a47aac689a5c57318663bc98756c199160f3a39c2148c574c23836dd060d1ac8a06794edd5aa068ac19e42ccaab951051756350c31d584a517fc9bb303276215580fda99551e82449d8675f29c45ab6354107cc94509ee55aa5db3a813adb8b04005200aba8f91b58a2d3b2b7d82c6461363353038099b7a0e981a85c75e0e422c572c506071df54bb7b715b9f4a42da1e89694a06475545d97a09ea36374f2c8ba40a5cc17eb1ad308ae862a26e38b2ffc11b7abe3b58509b21649b86aab9e0d1abb601604c4152257a6691a964657ba0d1f561402545b782960e547a4dab7b71aa95c67e64caf568c3b3144fb29022cb0bf01b895e3327d019b591ca282d22105da99b58be42bae7185e0b56cbd0c56ead56b5dd34e9bc1859b927ed78c4ee1340960256a0b63cf4e1cc9e84a53a48b2f70c3c89e83a0005d65019a8419b5166469999a453418cb94295462d9256ccddb3fcf8365cf0235f1d547498714a8b09553182fba093f447a220146182a3acf062a118b22ca49756505978f21db629799cad72ac5d17b2bfa52a6ea15672537899a313a4f0b7df3f8639906bd0163735dec5923a038fb7b5856570e279275c3093998338cb595c9a6b712c06c526166a725b9098ea02ea10c5d7cbb86b935703f122dedb05233202968b59825f41f2c17ba76ac661fa69a7998c5fc6c2fb68a7820576b1fda2c73daa29cc21dcdca47adaa1b3b5258c1575fc9270712f3b8842978be50a18da45159b99272162891cb8a63cacfbc30bae0a4364c8a6537e1b40e825c4a311488b133956690e494443ab44793d3717582701fac5486da4ffaf02c058ba688fb88deb3c94e7445cfa89a79ca5f4b991abce25cd6b74afbe9c63dfa0f40180b242ab52c1a455c0664f7357c048b27e05ca46b8605e6843c66fbc2a6a29be135c39565a916acadbbf2aa2656125b603bc88c9d710399a84850840169be61bd4ef3687777075f0c7870b61903a26e6391a88b114e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_private_key = e1785b13943f2661c372ca63a0c6aeded27f46c81b837293b9867b9f7cce0611c61b318adfd67c09969c27a095e53c124b048cd99027c9103e85c5c4d72730a34c8adc406eceb4afe02444671319df175465ea9a0d91291c18cfc9367a333475727b64e6f73e50233b81ac0978364d18f72db39a4041d4b25a095df99bcbed090496dab62aa250945a97bd297a539a1af51648c8378c1b21a2fc311b57860c368a819f2b8c15477243256970313b2ae082c2f8bdacb658a89c6bdc788325d48292dc2395f51df765a4a2e927769c84f5fc306568b4b5e7487b8b9f79dcce33c80b988c955544cca478aac902c2a6f2a4bc9a9478a9b318f78586c696942b6f4c2931e85042db27314cb546bebc2236c2136d581ee22978d2b79ea3b662a8bc7cc17ccbdb59aef8b0cd77a4a680672e9ab4adc2d011bf471865f92f4a4769a8157b87769ac3b86448851e80f8babf394907d4c8a51c7ba4ca62cd7ab7bbc4219778ce4dc22955772dbd1330c10055dbe106d11863d7b14b6301a622ec35f3ab9b3494c12e3929bc321950fa1036d98a3b257c20d378a9798bd3b57e50ec88617b49b75022e10130e35432f3abc7165952e2b7652c0bb1fa92a16d7b3273d2709077164bc60cbbe747205b6dbbe5912947ca3914c1a106b66708212d443898616273e006ed507e30d7a7b6e389739b637609834561ad4e227da0289ed9180bfaa48a58ea75cc1744f75007a99611eae775a1f5411f1376a7f25e758c8b69ba731d28bf016970a9a3579ed7150c526b098c4ad277c6d7294462ca65b6f3b7062956551428477b9c57301ecadb9c7adaca67c0423f42704b008a90861b45c19d24e521080c69fd20a5dca45aca18abb356375a983081567e22798f530aa1e0aabc2d7b3a208446e9081ba2420b8afcb8edd37db536689695749b632d99316653e97056260979974e44d135589a283dd1486856bd1af59e24394743c7a036a68161e31010cac462a6a7ac0058e1640aaa686311d939537171b8128965c70fe8eb0f10dc1a2bc50aba436e2af19ffbb3c6451a9fe7784678a519473010f9e69f9601502c421ad4a7848cdc4b73987cf2f85e660c65e468346672ab09ea8b106b2ed51246271bc9d21672f6aa0b3a9b24c8f64722842f2e24cb2a47aac689a5c57318663bc98756c199160f3a39c2148c574c23836dd060d1ac8a06794edd5aa068ac19e42ccaab951051756350c31d584a517fc9bb303276215580fda99551e82449d8675f29c45ab6354107cc94509ee55aa5db3a813adb8b04005200aba8f91b58a2d3b2b7d82c6461363353038099b7a0e981a85c75e0e422c572c506071df54bb7b715b9f4a42da1e89694a06475545d97a09ea36374f2c8ba40a5cc17eb1ad308ae862a26e38b2ffc11b7abe3b58509b21649b86aab9e0d1abb601604c4152257a6691a964657ba0d1f561402545b782960e547a4dab7b71aa95c67e64caf568c3b3144fb29022cb0bf01b895e3327d019b591ca282d22105da99b58be42bae7185e0b56cbd0c56ead56b5dd34e9bc1859b927ed78c4ee1340960256a0b63cf4e1cc9e84a53a48b2f70c3c89e83a0005d65019a8419b5166469999a453418cb94295462d9256ccddb3fcf8365cf0235f1d547498714a8b09553182fba093f447a220146182a3acf062a118b22ca49756505978f21db629799cad72ac5d17b2bfa52a6ea15672537899a313a4f0b7df3f8639906bd0163735dec5923a038fb7b5856570e279275c3093998338cb595c9a6b712c06c526166a725b9098ea02ea10c5d7cbb86b935703f122dedb05233202968b59825f41f2c17ba76ac661fa69a7998c5fc6c2fb68a7820576b1fda2c73daa29cc21dcdca47adaa1b3b5258c1575fc9270712f3b8842978be50a18da45159b99272162891cb8a63cacfbc30bae0a4364c8a6537e1b40e825c4a311488b133956690e494443ab44793d3717582701fac5486da4ffaf02c058ba688fb88deb3c94e7445cfa89a79ca5f4b991abce25cd6b74afbe9c63dfa0f40180b242ab52c1a455c0664f7357c048b27e05ca46b8605e6843c66fbc2a6a29be135c39565a916acadbbf2aa2656125b603bc88c9d710399a84850840169be61bd4ef3687777075f0c7870b61903a26e6391a88b114e96f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d213f0970c03d32967b06cca4cf58e87559128d14cb3f876a1ed10eadfe03fc1a9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = 4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +expected_public_key = 59720c3d802726470d1c567b5908698650360db82700e7b9dd26013b6a8184316df3c59194fc96a0821a95c666ec5b130262006442cef64428794672b43bc1eeba20de01bc70c15835952164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789de2153b3f64411534cfad0adbf8bc0aa51bdaf396e5746517c5547b3112fe08188da54932b9b458458c55f146feaa9620e7bb6ce21648af047e0027c3553813aa81574f26483e93a5ab3642aa1332bc34f86328e5f80b272aa8971d175ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31a9b27d3b17f63fa0e0da16a3e54bc85da61a0119a95201fa51906d6e2257b2cbd7235abe8b80e80947cecb5ce87f9af68442e8b6336c68ab0b170a67cc14f5e5377c4cb5930705775e522ca466dfebb1aa800b452262a01966ff624ce79561b3a40258be53512d01b749c25ec903923ea58e6677e02b0430e996000c637d002ba09dac9e717ac64b634688b558d598e4017cbd46a160c621dbb2b961638b08a488fe8d814aca37165a43ddd4b3908d84246794678823e794c9191332f344077ffaa50dbd2a6e0692addd353588b3e87e31f3ae4030b2371eeb1cad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4ab1f87235e1f114cb93c3150e25277459c43a6aabe39af63eac248d19f21b17ab5a2ac14169b01563dc818552ceab71eec2c2422c3e5f703b84bcfb457707a0b3edc80c0efa324d407d077cab9b416b3a97713b89c6d65c2584ca652e6c4416bb44d3e7478eb21ce1a555456b94271689828560eaf4394bed93a86d48ec082a7be576b75d00ec418228bf93c7037a49339352828af07f3729bfa739b00d04b5502b9d6054ba525d724a0df8506d9ea56d750072868cfcf07716af003a02c45d4991f4503bf5ac86024857acae4ce24850def0632a6dca9756c5c8a459341c69e93e154858b7c917592bb91c23ab622d3f84b9c81445e5a1e59262bfbf025286bbbb5d03eaa794445f7839f3ab51bf5ac48c978f0310128817d27e658d9f468f77c4c69da09dd8526539c2598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_private_key = 50d47ac334a631e3c9bf8aa02bcc7e35272025cc37f8c844641704226029a3ac14bda6458c33790c806430bc478470b94f164a1b074c5fd034466922f41ca7c70a61c0e9727263579de085eb468cf44a3dc112525b878645a7483c0916a28b0ab8ccae79352e45bb186806a29c381caba12e0b505831200f8b874964686e754b66a66b2bde90826fd34938a46711a01599bab22a148c80fb0ba8455ef42c0b5279122be3cedef27907040f9641b681500c50679de3f534c5ac8754f925f446c6a114a989cb7b4269a95e3630c582c9af505ab7d3ab6533288c9316fec5512c21ce2866ac26391c340467baf3ab3be8c007587b77d7c7cc10c036c06d8d1590f417bc2c8909bb85acc8d29fadaa766e89788c406d35da78990a0aa2a1c0d0f92f73c152cb797f976b5173010a35fc649744c69529c354b616a8ba471496970365b1ee822c65201364405838d398ba047e5342ad71d831f2762798e282d8381730184eb5536b85ec8d0f59cb5b7a10d2334f876394f1f154bd6272bbf13ffc243ea0c53b3ad3adf9382f135766d5589769b7672b5126ccd6c8928709cd638c28a38c0ac9cceb239f147ba6ced8bdfb39688e1ab90ce31b44b76c32dbaedec4b84503160db41e19f82b401b7a97d44161dba79d991468635f04545982f7b818585f28a320b744533113515ca95b9cb37512e339e716c92569c8ed8122c131ad265b7859bbb069c136818a24250339e1eccad295cf95f6290be90e2a94b21ee4ab84ea5755332afdb1545cb97effb091221b9b3690b06d66795de7898669609fb26a5d37814ed9b7f55592b02a6c1205c8f0c23f0b691b6f64194d1270f8042a7eb6563cb2b178f808aac06fcea7432b025499499f2d5b8b476ba469e7bc43e4a091e88bcea08454e83d2606ade78a4984d6b6a5586c04090051462ae79680a676735267607b256d5db4c6a7b2846a73093885b277043b7e98ceed99bf743904438c8888064ee2834109a70141f791e5e26bb5281301064935850e40641183b4c1f3776de042a78e0966540aa25cd484182b30fd3cbf0581b7b4a31250c103b6620059720c3d802726470d1c567b5908698650360db82700e7b9dd26013b6a8184316df3c59194fc96a0821a95c666ec5b130262006442cef64428794672b43bc1eeba20de01bc70c15835952164e5a32705bfa7c64693b9bed53462f5aa6de2569195147c70a789de2153b3f64411534cfad0adbf8bc0aa51bdaf396e5746517c5547b3112fe08188da54932b9b458458c55f146feaa9620e7bb6ce21648af047e0027c3553813aa81574f26483e93a5ab3642aa1332bc34f86328e5f80b272aa8971d175ee6a3d762acd8279331e849179b9638c17b525ac600a598e4dcb7ffd68c31a9b27d3b17f63fa0e0da16a3e54bc85da61a0119a95201fa51906d6e2257b2cbd7235abe8b80e80947cecb5ce87f9af68442e8b6336c68ab0b170a67cc14f5e5377c4cb5930705775e522ca466dfebb1aa800b452262a01966ff624ce79561b3a40258be53512d01b749c25ec903923ea58e6677e02b0430e996000c637d002ba09dac9e717ac64b634688b558d598e4017cbd46a160c621dbb2b961638b08a488fe8d814aca37165a43ddd4b3908d84246794678823e794c9191332f344077ffaa50dbd2a6e0692addd353588b3e87e31f3ae4030b2371eeb1cad20699bd6a459dba53e6e3aa8a56be4939b3e4b58c172cbbc4ab1f87235e1f114cb93c3150e25277459c43a6aabe39af63eac248d19f21b17ab5a2ac14169b01563dc818552ceab71eec2c2422c3e5f703b84bcfb457707a0b3edc80c0efa324d407d077cab9b416b3a97713b89c6d65c2584ca652e6c4416bb44d3e7478eb21ce1a555456b94271689828560eaf4394bed93a86d48ec082a7be576b75d00ec418228bf93c7037a49339352828af07f3729bfa739b00d04b5502b9d6054ba525d724a0df8506d9ea56d750072868cfcf07716af003a02c45d4991f4503bf5ac86024857acae4ce24850def0632a6dca9756c5c8a459341c69e93e154858b7c917592bb91c23ab622d3f84b9c81445e5a1e59262bfbf025286bbbb5d03eaa794445f7839f3ab51bf5ac48c978f0310128817d27e658d9f468f77c4c69da09dd8526539c2598f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd083553153f7d65cd5cbe201e681245eda61e1ec2c7ee6b91a9ccdeb6b76943b7e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = 050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +expected_public_key = e5dc61cc732b09e221ad8840d101040c4428a798704db118c037476701a79ae30f9b7265038abcd0933d1100492a6b2fbaa7c0d6c22704571520f35e322a4bef080fcb4c83bc62c432f75f6ef22b2b1722351343cbe4460b25b4bc806bac542576ca42f30c7ddef6082199a4edc2237e5271eeb024e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4e0168ccba259bc99b9f4c54cc2a8c1489415c422f70249235235f81404c3601079a3c8095214ae03c86bb4a1487a00710dca3dbac8a89d045de4768e56329ec6709a9208df6d3af6f8c7ddd6284f144120e1449bfccc6cea22bc3917c90f6591062525804054553a46a226093383f12b8529d306ca2fa03f3371de8641463a353513a593d601f91937c3197cd535768f78aa4ec11c4f59267b5fa47b0b2312ae97b77aa1c3631b7033cb17b5a592c89091d0a2062f8c7299a2bd7f77832899b1a84ae67a3c11e87b17a0050523b9a9bb87db0152cbee582b9d821937a2770d07d6e2113832c1456662ab38475a1527fd23287e45822c5d0c19875cc4c60c9ede44722552013b6ad7ee4b860ec2ff8337789832002026d7b54676b44667961654902912e3116402824a64cc67655018803ab2c06540123166d78b87be63997692efc099e4bd72d734b1e9dd6344df12070773b06c5c1ff3b32417546ea5416c204917f104a3e603bf1f09fefc3184fa43f06200423c3026b3a2374186df33344cde1ccde212ebf626410907fda57a9538b165b3911e016438c4b3f0e485b3ca3001ef03466a8749d1488e24685fc1cc89e012758473601b572acab4db6a93edaa6aadbca7924c23115769db3a4185aebcd09a9b045b3437dab3336b47a6bc23370a53a5e327b6654091f9a435451cc26b41ecbc129ae109475793c3977b532c6a8cb3317d3270bbc6bbfbcfa1c2ab2c41908520184000e3b62dbc3005839200b486d6b89b1719505f6fc4a3b7a41ce4a4677b64688284ec18915f17133f81c4f73c13e14632873652554685debb7b987c66d01b9049f6b2e44960022e7916b61a55c12c4f5e099ca059e3f98704ad5ca1d2676496c21782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_private_key = 456c6c1d6630bd63c8b0243d5b1a6ecc09a28b09bcbf96cfaf056e936a0184d6774d9524f4a6000e974fa7879574629504f09a12838da39c7a90f4637c1bcbb16677b491b87f653aa41ab5f6e279f917c65403a78d07b136ac8486eacf42252428c3b09ecb91f7a953cf98484b036f48622a6dea3a46e7b33c500b0e39620b640f6c14be17fc6d04cb815d4691687737f413491a8b9e30f28c7e2bcbdeb92b21a1752b6261863c84fc5918efec496311cbc7557223cb65f2169eb6e1ba98b42a56b71ccc6133a7b50ee4442ececabacdc960856b590f5792d973a3ab82b3ff6b36b64757d04787e0c4728c0649cfe16d2febac26a2bfabf985cc8b1b5511ca85760fe559b28072286e9b4c732b156db2a9d08238e54336a87837dc93b4742cac0f05c2d75ccdf06787b21548f19280c05298be80c79296bf9609a8d88347413b426a38001d59cb5787513fb53a51a0cd39c903e12a512891c43d39372ec2c0f3398dc091729ca80061da2484a01c58b8530956268eb6a5e764443190ca2ca896f142c16d83bd93014ef7852acfbc48c8702f1b39513ef20f50d92eafe74cc057adb1c363f59a9b962697c37892759859080a287d5b7ef62a4aec718020519bd5b59da69c60a249b55c68c2d523a507245d39c8374c67ba02d172cc98893761149bcb6fcf93cf779431de95132a029591c92273078a403895c40467be735b6d2346dfa33568f654a25b7586e63b5a820998374a0a01123cb915512c1557b4bd1366be2c259c511492d4b200f9e618608997b2b80fdd873a42859d9b98a279121de3a5a06652be7e948c01045ee41a08c068519d9125a7bcb79c5c713f2c4ca4db7c30f9a7a7052ab68280a4b59d22844551e4028f8740253447a479b5fdb0371ffb4c39104b51c13a3ec7364857a775f3a8837978f560c31052b01f648dacf8440eb3500c447ef81641130cac60748cb1e108facc918af165224b91fd52c7ea1a7fb5f83217284d5e20c951fa0fe47352f3a22d80d0b95875bd80640d95142db2639a830ba302f49a8caabf009104f8b136bb75a38d168274307db8d136ee08cee5dc61cc732b09e221ad8840d101040c4428a798704db118c037476701a79ae30f9b7265038abcd0933d1100492a6b2fbaa7c0d6c22704571520f35e322a4bef080fcb4c83bc62c432f75f6ef22b2b1722351343cbe4460b25b4bc806bac542576ca42f30c7ddef6082199a4edc2237e5271eeb024e154cbd2d57d4d5a59840561c0c76004a8bde4f48f4e0168ccba259bc99b9f4c54cc2a8c1489415c422f70249235235f81404c3601079a3c8095214ae03c86bb4a1487a00710dca3dbac8a89d045de4768e56329ec6709a9208df6d3af6f8c7ddd6284f144120e1449bfccc6cea22bc3917c90f6591062525804054553a46a226093383f12b8529d306ca2fa03f3371de8641463a353513a593d601f91937c3197cd535768f78aa4ec11c4f59267b5fa47b0b2312ae97b77aa1c3631b7033cb17b5a592c89091d0a2062f8c7299a2bd7f77832899b1a84ae67a3c11e87b17a0050523b9a9bb87db0152cbee582b9d821937a2770d07d6e2113832c1456662ab38475a1527fd23287e45822c5d0c19875cc4c60c9ede44722552013b6ad7ee4b860ec2ff8337789832002026d7b54676b44667961654902912e3116402824a64cc67655018803ab2c06540123166d78b87be63997692efc099e4bd72d734b1e9dd6344df12070773b06c5c1ff3b32417546ea5416c204917f104a3e603bf1f09fefc3184fa43f06200423c3026b3a2374186df33344cde1ccde212ebf626410907fda57a9538b165b3911e016438c4b3f0e485b3ca3001ef03466a8749d1488e24685fc1cc89e012758473601b572acab4db6a93edaa6aadbca7924c23115769db3a4185aebcd09a9b045b3437dab3336b47a6bc23370a53a5e327b6654091f9a435451cc26b41ecbc129ae109475793c3977b532c6a8cb3317d3270bbc6bbfbcfa1c2ab2c41908520184000e3b62dbc3005839200b486d6b89b1719505f6fc4a3b7a41ce4a4677b64688284ec18915f17133f81c4f73c13e14632873652554685debb7b987c66d01b9049f6b2e44960022e7916b61a55c12c4f5e099ca059e3f98704ad5ca1d2676496c21782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e225819df5746a44b10c1886f62b068d18152a85792781160e1a1a19a25b5ca00555f4de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +expected_public_key = 6f70c439f9cda8e34b944822c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b393269fd3478d1836f80a9cf51b03fe697846c44abe549aa16a25819e38c9ca1262ac103f4417cde8138f84050c0bba5ffb5090c81bcff1bbdcd67739bb60d236215b8ecb5c9002dbf41b36ed335dc4778153761472421d2043f06a8a83422ae6fd0680b860cfb589a3f5b85ebdb94b3f21d24f374949563e8a35eef8c70507c47dccb241dfb53be08b129a283367b48894c090b523e6ae0637fb4894707812ea9b528f54395d0bea3bb3a6772881061c28b8c24ade167633c30935a6c4f29a68fa298bd0c0bc1729c330953fdc5bd6c92595d576e4d6cb45a4a213aa299512c304fa2a3f6b1cd8d545150965bca39703efc502608bcd1e42da21cb129400dba7a9a053a6cc17066d9d98899d7c4aa3cab66b1c13d58251eb196959a6a250ba45023b9e6a6a8d192c0eb548e69d20c68f0bac8ec682b366926d62e878123e198add1d31abe91a02a5cb6fdf6a40255bc3355809fc8ab529a00b0d451dce9a657e961b4787829132a7192139532195bbcbb0fdcada2c515e3a83cf2485fb5a28f648981ddec7a80470540c71d53c29aab8009d9067c703643c1062165e3745d3ccc4e5249efc87b9f73afa08b1915065dac1c4c68422f89589526188ceaa19f64f0cad4781327e85665b5c59e8c3797f72642897db4515da47b994b2c6d3e41949363262dd721573021aa3373aa22758fcc22dbac46806c9005001c92aa9b05d0c789dcced4d427ae762f4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a4e194aff46422fb57fe4b2b2de18a060627c3f19b984aa7b738bff9336f80171f8236a3e95372975650d6b28398865f206a1bc81c346ee76999b8b889c83551f42495000eb9f5aa3ac16b9247091469815cf4533eab9be2ca283b962ab0031892999b55822eec5503d7201f446b21ec3319813a4f7b70b68a438c6147c182c48ded8c5fca18b2c7322fc3e4341eb46bb130464a7868c5d3ce5b1bb479e69bbdf20dfc59380099ccfb06789fa1183c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_private_key = 8ba88eb6987ac9337d47b0a4a56748e272cfba9bcd68ec072528aa26b45cc407754cf07202930b42371f012c9e4c2b23b69252f8d82061dacb58c72ee32b0a5aeb7feae54333411e3fa56d7aa46fc4392803925ff2b41273e23428f3a636cc99fa855003d6ca4f71253e66b87d2815f1092898b942c7173bf64832dbb05c4398c9366350d7d9ab146c6208498ce4340e75e7b9bf729dc207c37f1bb554437a6336535a42546bb4b4d8220e8660c785e96e974030d7315c94e394f8b8056fe31634909a0537cb215581ac29cc9e545311eba671c7986722cff1567851e71fc7046b92473227f1127249a7acabc8be252f4136c9b9ab6b5fd92ccc8aad370329d0418cb96a6f02621c01e7b00af17197cc7143653794826fcfc05ee91186daa50ba6336aec812db7218c0e291ffea70782a46d43e84de1b700c3e3a54c1839fa933945c4bf58692924110e72c3a7f9f19f6ec743d4585163e803973b7992fa8f3b087ea14a3d5b8110f2001e72ab8a79a34347a24d74a68b9e0406f2bca624454d1a6c77dc0a1f9fc3801e701db5247b10b0215c474086163653ebcf0b0b66260046599a9668254bfc8871e947c6f8a5212c7245647c25329289616217eebb1577020d4506ba3446a9914c512bf62a2ff26d1bf4cf582a5552332b239776b00c7730bb02be799df92377d16c957b726d89b57b29b13bf290a6c45944d272ce117b6c5d596bba18097429b6bc5b2042919fa83630bd55934ad7400804865b01ccfe84bcd17303ea205b3694cc057ab2dd42cb6826264928a05f2baad530a62ff497e3e09a6439ba8799b3a20865ec340d05e7c4c3a596b59cc62245a1f2b52f0d45b939e177c595a78ba16cba965043b210bfdab8e43241c26973654a737f6a3b8c70c3f2c472109c89fab0ab41fabeb2268095165b8e1ca5a63a53a478b398bc5e84e2b41b8ca6d2d6659101a9c1a97a11ac34fc2a83757390dc00957b124bc1d1be92a4ad3201bdc4924ad3f24216b2894286640546c865536d02508dabd619a3c258756b436b1286aff17f750511d13c0960f5080d1c0a011989bab77db0253b6f70c439f9cda8e34b944822c2396459384ad21392a627522037607b29c8d619b4729a68e2164964339819d88b393269fd3478d1836f80a9cf51b03fe697846c44abe549aa16a25819e38c9ca1262ac103f4417cde8138f84050c0bba5ffb5090c81bcff1bbdcd67739bb60d236215b8ecb5c9002dbf41b36ed335dc4778153761472421d2043f06a8a83422ae6fd0680b860cfb589a3f5b85ebdb94b3f21d24f374949563e8a35eef8c70507c47dccb241dfb53be08b129a283367b48894c090b523e6ae0637fb4894707812ea9b528f54395d0bea3bb3a6772881061c28b8c24ade167633c30935a6c4f29a68fa298bd0c0bc1729c330953fdc5bd6c92595d576e4d6cb45a4a213aa299512c304fa2a3f6b1cd8d545150965bca39703efc502608bcd1e42da21cb129400dba7a9a053a6cc17066d9d98899d7c4aa3cab66b1c13d58251eb196959a6a250ba45023b9e6a6a8d192c0eb548e69d20c68f0bac8ec682b366926d62e878123e198add1d31abe91a02a5cb6fdf6a40255bc3355809fc8ab529a00b0d451dce9a657e961b4787829132a7192139532195bbcbb0fdcada2c515e3a83cf2485fb5a28f648981ddec7a80470540c71d53c29aab8009d9067c703643c1062165e3745d3ccc4e5249efc87b9f73afa08b1915065dac1c4c68422f89589526188ceaa19f64f0cad4781327e85665b5c59e8c3797f72642897db4515da47b994b2c6d3e41949363262dd721573021aa3373aa22758fcc22dbac46806c9005001c92aa9b05d0c789dcced4d427ae762f4a1953c1a643ad2cb2220c8800d376b9f76c1d94a0a4e194aff46422fb57fe4b2b2de18a060627c3f19b984aa7b738bff9336f80171f8236a3e95372975650d6b28398865f206a1bc81c346ee76999b8b889c83551f42495000eb9f5aa3ac16b9247091469815cf4533eab9be2ca283b962ab0031892999b55822eec5503d7201f446b21ec3319813a4f7b70b68a438c6147c182c48ded8c5fca18b2c7322fc3e4341eb46bb130464a7868c5d3ce5b1bb479e69bbdf20dfc59380099ccfb06789fa1183c35857717bda2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a9415ce164fadececacd75fdad3284af20c52fa576699029d6e0ce77bf347d520be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +expected_public_key = 4870419a0b91a8b97bea251b03c51630381aa802b51353721697c4bd2891f37698ac51942d44c931f205ac15bf35708806a118dc32b51655070cb196246b6a63db0c57d727d9aa812c676880e3532a435e191935a6db1e1b110cd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb78090ca1043ea8ebcaa3b73c768892832c357b0cc48e875f849149ffe63a21a169798b00cfac58eb666c9ab68729dcb60cac6dee1497a64533989c0a68b151f8865db5f421eae77292155f12944322e579d8f61c20ea53b34cc7553b6a97db6c3df847b8aab6b993c4af02c44d2c0ff555ba6c68132cc6b9c4766acd030c33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e10561965e45551398a9632169d6a53da1314a9b4533f4c223fcc46ab0730a8b463c537c2d5ab8c9956c542d6119f76b82afa13ffe637e09297b2e6565277079081c574b05d50ac2bc8e9538d0105f828b539d47f3a9a293b4b9b834b2cab741674b8c61f28a778b736b699bb989705890951c30747896508421068dccc0f990611ebd800c942be5c886a59b008e6fcc86956aba6863bd9558417a37579b7139efb5bc47b1ad598464f287a3d8c56d748c6ae794f31842fc3aca9c5c05fb5f76c5f740d2d7908e01a173b75a35b8a70cd645e66e8a6d290919f227ef5e5bea2816b31829cd291b136520fb1a2825ee01dcbba7ae9a10c60a297d39c7b40f53d02d602627879fe6b4c00ed426a0b065429acab34be641c356be26a7c5012b9643fef007577f79dc99459152c13e64618b9f9b3be0b551dd33df8cb7d890c48ea83b68c42a327ba25fafb5ed65c31f4e6b639230aa989b1ae7a2c5ff3224b33883955890e5c7aa691463e58977c31445fba5c408047d227aeee6bc90697545ce0885c3abea2ec9668359e59282c22a0920ec76a282c545a80896f5a4705c02adedbb0f8dcba46f36c112b578e7b4c236899d81259706c3d99b0adc3ec44e58171a5e21c052767b7692800854132624ff438b03cca42473622a6db189be32c7e906a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_private_key = 7c15568ee11684858038fb1bf63793968151c90a6ff875a0b125696ad14347a3130f5665340954928447243254ea8b089fb665a3c18564f65bff5ab648a58c2fa7c7c9c101d055202e1742ef98c68930ccada716e03877ea7c8cacf13739b22059eb0430cc97feb3a41df06d2e35930ef904ac669caca41c9a24cf96075e92d36cd8958d96584dc9c85bb6851735fbafa07164a2a13c253949b44769179a2dc2b655e1f0cb66ea2c39364b5862b070b805a58b4541f8b32e5c2bc6b2c2de13107462cd2b4c5f783184bf61746043277952816ba4c6c259108f91bcc15a951c012310d78d14c96add4c043e3a341e072aa3b1ce83214813005a759519700362fab0226a58a932f71bdcb03ba0a99f3e0656dc1a28ca3328b4fa531b3127ed790398a45cd0bcb95be6c91ad3b2f94092f7c4b99abc864842466290c5f077544b4954ce06a57671213e9a7dc1405b2c1228ca2824b4b433eb65901a2903abb2c4182a144efba1fde9063bc40d5f7940b5044055d106b064b099183ab5aa34ba4480ab6266364c7d9f5689d7abc47822c456122ab2b0679f2c096d4c0c6f29774620c09378a8fce888243bc738a6a3e3607ae261396855989c445f228cad87182951586d21033f32c250c13881a2831f9c738018953ac3f53660b962517a64cbb2b1e26867c77529fc21ad452c7bd562b30b5720eb120d9b517c7f8cbe1123a090359df30c3115e57fb61bb47f4ca5ddb2a443b9a2ca56a6f58010d7d0cc05698e1ea539c32920a8424420b675205b905fd117fe0c7bb1f888c7da6da060a24b450813a613d9c8bde20c38665c918a133ba7da7c4392467cb32f21ca3f7c37206175b242070236a12f5ae73a37000e386130a0a15e06f0a4d97004d8018223726b454623ce9a31ba150cf6182ea4752714b2870a612b9c1484e0c199ada27293648035954da75ba723a82f4afb2c7085111709a63ac5b9f6e201bd11cb30f48732c84f4ee3622dc83ce6995ab81b20a8e16e1b1684062569f4ebc4f2637038f489755cc7126535d65bc6ccc0a00ac27e1700657df77a59f57339323041a2160401bc4870419a0b91a8b97bea251b03c51630381aa802b51353721697c4bd2891f37698ac51942d44c931f205ac15bf35708806a118dc32b51655070cb196246b6a63db0c57d727d9aa812c676880e3532a435e191935a6db1e1b110cd8a89a751378b5866f0f263871f7b46455c9cf34711a957d23c937e797cb78090ca1043ea8ebcaa3b73c768892832c357b0cc48e875f849149ffe63a21a169798b00cfac58eb666c9ab68729dcb60cac6dee1497a64533989c0a68b151f8865db5f421eae77292155f12944322e579d8f61c20ea53b34cc7553b6a97db6c3df847b8aab6b993c4af02c44d2c0ff555ba6c68132cc6b9c4766acd030c33374bc2d556d0d45926e33d68667780b34c4b56b1eeb350bf0c5e10561965e45551398a9632169d6a53da1314a9b4533f4c223fcc46ab0730a8b463c537c2d5ab8c9956c542d6119f76b82afa13ffe637e09297b2e6565277079081c574b05d50ac2bc8e9538d0105f828b539d47f3a9a293b4b9b834b2cab741674b8c61f28a778b736b699bb989705890951c30747896508421068dccc0f990611ebd800c942be5c886a59b008e6fcc86956aba6863bd9558417a37579b7139efb5bc47b1ad598464f287a3d8c56d748c6ae794f31842fc3aca9c5c05fb5f76c5f740d2d7908e01a173b75a35b8a70cd645e66e8a6d290919f227ef5e5bea2816b31829cd291b136520fb1a2825ee01dcbba7ae9a10c60a297d39c7b40f53d02d602627879fe6b4c00ed426a0b065429acab34be641c356be26a7c5012b9643fef007577f79dc99459152c13e64618b9f9b3be0b551dd33df8cb7d890c48ea83b68c42a327ba25fafb5ed65c31f4e6b639230aa989b1ae7a2c5ff3224b33883955890e5c7aa691463e58977c31445fba5c408047d227aeee6bc90697545ce0885c3abea2ec9668359e59282c22a0920ec76a282c545a80896f5a4705c02adedbb0f8dcba46f36c112b578e7b4c236899d81259706c3d99b0adc3ec44e58171a5e21c052767b7692800854132624ff438b03cca42473622a6db189be32c7e906a23238a6cf57559c63721c86e73378347c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9ca2232297ba8b986dacd401896cb6239f557720d91a2cfb7a73274bac7a0f6dea08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +expected_public_key = e29100ec15605818b877d7399d4c70c4e3b362a3268fbb7e41d494048740ea222bc38b5ebd3cc8d049a2551a731ef31684247f30fca3f03c0a7d7245d0e81c25359f245b9523040fd2d24ac3941a213b561b974ce45156d268a0d6c5b555e251e18b31b7753c2826bf6654453b81a11478836d08c6a803ae48e0892e927960118d456232025c3f516a99e4818627760c88f3b8813b57e9ebcb37fa391fa1c7c8bbbc358b40db908b526a85ac86a03848820879314ca86a2c326f5eb69e7ff6c5a0c3779c20214581bb5f4973fbf54353fc448b0b2f00fd746f303473717ff829218b22bb23eaa132e31cce576efa0a53015c3788c82ee55a69051a62b6293aaa9a4398d61d25dc679964c33c6028448b92acb7ac1115c50dd3b064818cb0224209193797ea3df48b6ffdd8228d148514ab0c11b1840b3843a7472876231b3bd91822e8469a5095acf5b2bb5b138425b2d60c1e018951951917630b8da2372aa239bc88d5a086b0b6aed50618ab25000abadc6684266939d4468ef5c651ff69b11b928355170fba871a59eca1f7073689516d17ac6298d2520e8328f3cbaf8de33969ab089d6a046bb979c3365b2dd2704c359c04797384c5c7f28c342227b045e40e88d4bb5c792381e639c86a12885596144b1a6cea01ef9794122466e3bb779e2b0ccf9048f50557d536621d280b02547234700e442b6278d2b0cef240946c542292c904ba31a6a38cb9328874f824fca0504238bc090bbb78e60b2eec76c900bb6010240b839d433c4968833715121a884b362fd8c8eaf90a241b66d7522b6908c43890cea4ec80ca232be3ac573bac2428192087b43cd15891585339a6123475209af6c132be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca662742950f431c93a391618c2a410834c2231a92c3d91c471803f22543ce530a17bc924fc326aee4537a5b43fb655e00e46185e809996b87e27c6361fa7b53da5ab393cb56b1b9676155f2e57092566590642bb090571c6a92f60c55b339618389415c259705fc858ab71aa50021c1191359576c8390a70e703f32ec26419602cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_private_key = d99596f420a269879b1e577a0a909430147c8a03b654d4b4d42c348c041017965b1202819e666242365779f52ed935a0a7253a38c25e55855667042e4eac0504659d64e83b9a0b2a15428a9052ce450000b215762fe0240e3743ba526226c20a6388b9d0935b208bab0f028ce7d1c2141a2d0dba1161b44dd3269754da10c9538a22eb914fa22d0a364c6433736d7bbe8335a182e14e269488a79c6322304ea2c438bd9b9a6ff700b8babc0f7303398300945a6db091229a44464ffc8d3dcc615d7a7922e62b134770bad9a9f718398202aac3aa23fd927b002d2bb38c990b8c4e5f1789f6d51520647b5a94badf1b148a38a4990836936c0e9c294e95218445e3131ac9c57c88b7da491c15b91e906c4e898114672a9c58eb04c9f0bf79b02a983027d5b5cd52371a11dabf91d79329eac48997a85aa64bea5217c43c257ec2784113a18fe28402636139075b5d76aca968742d62c89fb528ef3ac9f30c5f23a94d8cd19a07e88a25d25167082fab269a0e010979860fb7bbccf580030dd58e34993178097b79034aa5709f7366ced6a4978b5c01c7facadd7c69d856be8eb836dbb9319a575059f9541a12a0bc86976561cab8660ffd4c828ae534bc5a8b9f1368928a2ae6b397347cb7ccb104c6d3654ac497758480ff202c32944d003a7c0bb944753c4472462538f1a34e2a1774e9295abb54a1aa59eeb317e9336a3b868346806a4dcc3055750da202bb87e3c1ac87224e32154627989e252558655b08cb6b878ca8ac403be561211551ae7af8a3c9e748f23c292b81931662515ba3814d7a86ed7668a4f151ad8a1b4ddc2166aa007807c9be492ccba666ecc02c887aaf9f47649fea6d34a40ca39806af384b06b548ee55477b5a2c0d62375bf6c00a9b49f541719452a2a5e01981a8ca034aceeda83932a938a7476c21d6ced1a6874bb073b1646662f0b3c3f6654fe032a510856c67264f32ba16bb4df0d3209a025413692b424b0b01db1b5baa4621eac639c6076f1251b106217c88751aa93d28873ad4e45593164076f0ce79925e714752520c2728b96d2f53cadb79a51c96b6e29100ec15605818b877d7399d4c70c4e3b362a3268fbb7e41d494048740ea222bc38b5ebd3cc8d049a2551a731ef31684247f30fca3f03c0a7d7245d0e81c25359f245b9523040fd2d24ac3941a213b561b974ce45156d268a0d6c5b555e251e18b31b7753c2826bf6654453b81a11478836d08c6a803ae48e0892e927960118d456232025c3f516a99e4818627760c88f3b8813b57e9ebcb37fa391fa1c7c8bbbc358b40db908b526a85ac86a03848820879314ca86a2c326f5eb69e7ff6c5a0c3779c20214581bb5f4973fbf54353fc448b0b2f00fd746f303473717ff829218b22bb23eaa132e31cce576efa0a53015c3788c82ee55a69051a62b6293aaa9a4398d61d25dc679964c33c6028448b92acb7ac1115c50dd3b064818cb0224209193797ea3df48b6ffdd8228d148514ab0c11b1840b3843a7472876231b3bd91822e8469a5095acf5b2bb5b138425b2d60c1e018951951917630b8da2372aa239bc88d5a086b0b6aed50618ab25000abadc6684266939d4468ef5c651ff69b11b928355170fba871a59eca1f7073689516d17ac6298d2520e8328f3cbaf8de33969ab089d6a046bb979c3365b2dd2704c359c04797384c5c7f28c342227b045e40e88d4bb5c792381e639c86a12885596144b1a6cea01ef9794122466e3bb779e2b0ccf9048f50557d536621d280b02547234700e442b6278d2b0cef240946c542292c904ba31a6a38cb9328874f824fca0504238bc090bbb78e60b2eec76c900bb6010240b839d433c4968833715121a884b362fd8c8eaf90a241b66d7522b6908c43890cea4ec80ca232be3ac573bac2428192087b43cd15891585339a6123475209af6c132be24a387bc9657c7b80c4aadbc9bc6cb94c3e8465eae9934ca662742950f431c93a391618c2a410834c2231a92c3d91c471803f22543ce530a17bc924fc326aee4537a5b43fb655e00e46185e809996b87e27c6361fa7b53da5ab393cb56b1b9676155f2e57092566590642bb090571c6a92f60c55b339618389415c259705fc858ab71aa50021c1191359576c8390a70e703f32ec26419602cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f34486689b387ba25dd0e9aedbc53034924ea4ef9497b5772f10ca4d091e9e84684ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +expected_public_key = c51bc84c04b516a56479711aae6b9efdc04afb251a0c121b249a03cfd27d8c435892c88c0db5291de3999db794ef43a14ef966c97c02764bbcc6786500cda603062e54b0444e52835c67b5bb524f52e670553c24cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e32207c8a255dd72a3de5ab401e540359575689233e1693f477b8c8e027629b1b2815b27b9b557f8123950b307a9d91e1dc2278a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c862a74730f16a223bb97af8d82331b7421172723473ca0f3e24ba744b2bd561900c45df2f3bd53ca25df405a93ca4ad222989a58136c9403ab5428b908ca82ba0436ea046f548f9c00aefbb27f497a15ab108f39f2829cd38d9db01c05e717df09d0a96b1b24c8a6e5e5354787429e559d61c853c1354f60dc4ae522141beb5f3ad27388363a392275ea8b7d08b68ac583713b714b9cc79bd9cb265d91666242429ac62fa6991c2501638772552ea54652b4496bf790efb876288bbd6cd4500a344f0ff17264f73d0a1a10e4d63b06884f8a5c3562bc8617ba4f33ca14e3b40fd8117bf547b5910107f5863e7ab3c3ebd98522f81923dbb55eb43af41a1af1047b68b940bbba364ff69dc57c60c6cb88d4dc43d84c00b0437dfbd913ed15a3bb84c542137acf1205f4826fe82bbbb701bc00a23115ba718ba5c80ca301aa970d303a0a9e5b64adc04aa8c8c12b39513989a8a27a578309661dc31a5de69bfbb11308fa2ac4d701be266cfe14a03e961fcb6132e7678d5fd06fd1a74262837b8b7228bd297a9685a98f217976b527b1dc0662d6238c8c4f05aa29b3cc182b78a7f29172bb2a8b50fb861624cee1c19f4f0739cbb157d8f60090fc847765209aa4b9b782127f400ef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec48c2ee05996e0535dbab9309d365687a4b61d8a746696182df7126b5b8c5fb27cba016975d4648b006f2b9c2345ab61fa68c7ce7901cc09538fb6349a391403802a26316bf15ccaa90686142ccf5e709cd4b6380088a18c42826330a454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_private_key = 5e200d8f0801013081bc4a25b4480561b991d9741778034f86e10caad22023228a6d7b498182bd3c8b7706b3044bc8be88461bf6e96e851bb4149aa60981b061a45541985446a0a3fbe47fbdf9a7680bcee9d9a004968b63e53553911f262500d13cb97e66554d184c2fa005d5c56a096558ca81a20f6066fa0aa22895883f23889ec024c8401460802a6a36c42050adc1475c58f08d4b7135c000a76f26218d946289c3c4ffe80b6b903b4e8999c67b59b067c23390bf134a9acad0cfb150b09249ae101b45a8bb089962b327173801f156984656c63398cec94ddb6454405464cec03d69b0c81b629fa6bb5e15e8a86b2623f9eb7d44a4573ec58de91a2f4672042a49019187870d3b3d810658ac6529dcc145e8f4703238458313cbeeac8f393b4911a40e7f90cf8efcbd0987289a899d09d21e1dc2a810c61dc0312f2ef95934b7a86408c75923616c15594cc3cfed41888500695bf1506707561f0129b60a13e1d7a8dc1cb9cbb96f91122ea3a68668488c3be91965263619d28b22ac557b8b39e7050478e25cc4081f6c255f2c938c224a2d8a11aaa608acbd6a3f9b1a097e36661f979ce7db8a7054006483ad74564fa65b7c52c620ff28b6cb941a70570571523e419b900a16be7bbacbb437ae3f1376d21461672599b38688875cbdf489a0e080714a731c6f147812e688db77a1ac091ee1b1ae24db55aa57282fb3b96da70e4f3594352918ba207b0d870ec9e13491e4b2d51c201c62cb22c896c7f342c1d98d05b87fba883c93a17e44d27a569289ef888dbe63242a029ad207cf54d8a8df513fba39c828049b604a5ced06bc0762c4e2074771364be66263440a6c828359bf1b129eab51d3ac18ec6465ad6215442808b3036714f541abecb6679b37ee76600225c190a2ccd6674b6e95a9564c156df47436491e380c78be7861249647f0474466e781caeab7989838d9d82cb355b0e3c51963129e57153f2e58a7fc843968c331b1cc57eea37ee11424ba6673a8ebac23405e86c77d0dc316f708444649a9d5907318044ebe4857f69a5b8ddaa9ed9b0beb656f41149d4edc45c51bc84c04b516a56479711aae6b9efdc04afb251a0c121b249a03cfd27d8c435892c88c0db5291de3999db794ef43a14ef966c97c02764bbcc6786500cda603062e54b0444e52835c67b5bb524f52e670553c24cb89c8367c5ad95639e96c707ec3af467a8521c5a557347830c931e32207c8a255dd72a3de5ab401e540359575689233e1693f477b8c8e027629b1b2815b27b9b557f8123950b307a9d91e1dc2278a44b3095989399a4629e7b84a0a666c3696d1076b207aa958ea956b964c654c599c862a74730f16a223bb97af8d82331b7421172723473ca0f3e24ba744b2bd561900c45df2f3bd53ca25df405a93ca4ad222989a58136c9403ab5428b908ca82ba0436ea046f548f9c00aefbb27f497a15ab108f39f2829cd38d9db01c05e717df09d0a96b1b24c8a6e5e5354787429e559d61c853c1354f60dc4ae522141beb5f3ad27388363a392275ea8b7d08b68ac583713b714b9cc79bd9cb265d91666242429ac62fa6991c2501638772552ea54652b4496bf790efb876288bbd6cd4500a344f0ff17264f73d0a1a10e4d63b06884f8a5c3562bc8617ba4f33ca14e3b40fd8117bf547b5910107f5863e7ab3c3ebd98522f81923dbb55eb43af41a1af1047b68b940bbba364ff69dc57c60c6cb88d4dc43d84c00b0437dfbd913ed15a3bb84c542137acf1205f4826fe82bbbb701bc00a23115ba718ba5c80ca301aa970d303a0a9e5b64adc04aa8c8c12b39513989a8a27a578309661dc31a5de69bfbb11308fa2ac4d701be266cfe14a03e961fcb6132e7678d5fd06fd1a74262837b8b7228bd297a9685a98f217976b527b1dc0662d6238c8c4f05aa29b3cc182b78a7f29172bb2a8b50fb861624cee1c19f4f0739cbb157d8f60090fc847765209aa4b9b782127f400ef49cc962c96ceb7ac05df85e1e8a601dfb9117c9cec48c2ee05996e0535dbab9309d365687a4b61d8a746696182df7126b5b8c5fb27cba016975d4648b006f2b9c2345ab61fa68c7ce7901cc09538fb6349a391403802a26316bf15ccaa90686142ccf5e709cd4b6380088a18c42826330a454c8a32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b39d1850f7acb36ed2a35e9af6f94a06c31afadaae3545a069f892ecd8929f76699daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = 0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +expected_public_key = 2fd9251f7b8fb16c6878bb20829260c588bc80195ff8db59ea449209c2476da061db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa6c02b3e531ac550a25db8783c995e2716b143c8a1309572fe47049a65742c632755a7d26e5a3344309e0c14ee313b0a8d214811b64d7351258e80ed9720863368dcc1851a358668dab3f0cc77f074aae24d71e0b71cab858b29e6a06190177f9dc39051b460d338363a9b7f6c691ab17865c4735bf42a72a655155b5106c165085b1c504d6b75187a44ed198c98aa26aa15327c5b35f6b3852a58fa7613337094129367e0660a62fc28e613c762d857f99f057b4e208e39181c63a8a91723352b8c4a4e04c0c02b78ac82e13c3542634484cfc8ce738b31a3062d2579f8394cd0947157443bc9774089689094a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba819b0aceb923918112e22b5591ba032b2a0d4f8301f2567b266473f3f1101a7c9ab95c94dce238db18166cb0c8f558167df937377a2096eb99408a32e3759a88a4cf04cb57923a1b9ae7140281a3cfd6763bd92e0fb91a24e87f1c56471eb334526053db394d39f956a8e45c6ff39cd57303c0ac920af3a480329dc19c43df67c05d889fb778a0208298938ac423534b025a04b141b1eb7017c9d053b7463ee870bb17899abb19c99193b670a23672b0ce15f97f71092cc121a0fc75a4ad292ff4a4c9c78bc24c764d7d4b9e1230bb46e02ee7a66357f25716c386b91193fc5a85cf63a748072478f23b0fd432944a5cc25a7dac2297b1234744a918e7565636c674e4aa4d2c957c7aa55da692324935a4c3749a08956028675ef5b9ba3ee5111dd73f1dac282523cb4a89bfb7973a50d30085e70818ea596c7c4ae332adffc300a5d691836690228b2fc6600c5a3a363e357c66a53a0fec851cd94b29b066305365b6a78fcbe57dbb40c8d02ccb5f541d11d24ce8eba582104bb4da4b9e099e822933b6b74080f8b743b59d94f094cde7c45422317e358adc6877613b7ec0a6ce8b702a1a32b285f475af3769d8a1148b5324c6429ceacc5980b902ef043f00d42484a10ad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_private_key = 08e63b9dc03310e0b5e8157e478234286cafadd3bbefcb59a7fa6e8b0ccee499bda8c4035179c67ea35f280886f4cb4276a4a63d2823151a4c0670735165ce3b9432bed2a35b72b59f9604e4d6a00d441f6381666ed773e62b9aa159c80dd40b2612b968092a0792bec7241f1f3ac589db824b388c964903524987d4367a22d252dd837fc5552c68215252e8c26248c5118963eae4b81a7c0a8c33054a941c67da34110c45fe28736ba90c2a07c8d6f8123c5a098434025cc82e5c05185a80a53ec50b30c1a0a027cf711baaad56a844c7b1936cb73de5447d0764595c8e0c4908412131fd517fbcd84e14b87cd6c651aa0c975e02654d40cfeee7397a93893cd3a2e81568c53414a11443b0a74532c61ece525b3e98853152bc5738a27bb11ea6d0710af2866e7136f99bb27c146c00d1aeef099d7a398126584815109daa65108e1b942aa6339ef0be33a9a3969938b421b3f4f96dd8316123b3cc16532a20fa0f078c338b8c96ad9b83dd5618f20715cd4cc914f32e9999cd04b34bdbc92173f5472fa68ca0625722374c9bb7bd0656c0a8aa4d16640c8828ca4d4029ed49a8ca4ca6563550f43662e4500b00a2661d680d46435fb2c2a99c8571bf1b8b26783f1ae95ed2b4b009a3b6e74c2ab685667fe9cadbd3143c33641f2a6ae7266d8322a1ea567230f876dd2753f93a6846c2bd3b02520f03147379b4cd3485619c6d4b42ae6f838bfd67bd49f43f3781a88d75b180b9378a924bfcc61853e206ac42cd39ebaaead2700032a3d8d7b9a29c0c6f02970441061869bfd243a676ac27a7e47521569a539712121c3829e40e8f0755d5e6a8230736ee7bc3327a5df26a221cb79c2e2063f3617c54664059fb8053bca2e50a7eb4a25106781adb386c5a8a732d406f0114c246013dc4d79e8f701c053b41135a7edeb4644131ceabbacf3ec546f8d92d556387bd15971ab408feb5004247c06c4187f1324db5780ec8cacecc6772176a2bbde1ae54d38152849bc862c48b73a0ca6c459962b342670357239d0d37095953908db86fbdf66d52ec4f24a420d1f59412974d9ca888c1a6c02fd9251f7b8fb16c6878bb20829260c588bc80195ff8db59ea449209c2476da061db33a9065930b52b9cd64b8dd3586afe3ca4b2796faa6c02b3e531ac550a25db8783c995e2716b143c8a1309572fe47049a65742c632755a7d26e5a3344309e0c14ee313b0a8d214811b64d7351258e80ed9720863368dcc1851a358668dab3f0cc77f074aae24d71e0b71cab858b29e6a06190177f9dc39051b460d338363a9b7f6c691ab17865c4735bf42a72a655155b5106c165085b1c504d6b75187a44ed198c98aa26aa15327c5b35f6b3852a58fa7613337094129367e0660a62fc28e613c762d857f99f057b4e208e39181c63a8a91723352b8c4a4e04c0c02b78ac82e13c3542634484cfc8ce738b31a3062d2579f8394cd0947157443bc9774089689094a77b437e55a3704cbe01c9ec4793e0fd7625a2ba81a25ba819b0aceb923918112e22b5591ba032b2a0d4f8301f2567b266473f3f1101a7c9ab95c94dce238db18166cb0c8f558167df937377a2096eb99408a32e3759a88a4cf04cb57923a1b9ae7140281a3cfd6763bd92e0fb91a24e87f1c56471eb334526053db394d39f956a8e45c6ff39cd57303c0ac920af3a480329dc19c43df67c05d889fb778a0208298938ac423534b025a04b141b1eb7017c9d053b7463ee870bb17899abb19c99193b670a23672b0ce15f97f71092cc121a0fc75a4ad292ff4a4c9c78bc24c764d7d4b9e1230bb46e02ee7a66357f25716c386b91193fc5a85cf63a748072478f23b0fd432944a5cc25a7dac2297b1234744a918e7565636c674e4aa4d2c957c7aa55da692324935a4c3749a08956028675ef5b9ba3ee5111dd73f1dac282523cb4a89bfb7973a50d30085e70818ea596c7c4ae332adffc300a5d691836690228b2fc6600c5a3a363e357c66a53a0fec851cd94b29b066305365b6a78fcbe57dbb40c8d02ccb5f541d11d24ce8eba582104bb4da4b9e099e822933b6b74080f8b743b59d94f094cde7c45422317e358adc6877613b7ec0a6ce8b702a1a32b285f475af3769d8a1148b5324c6429ceacc5980b902ef043f00d42484a10ad08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165edc8db1ca35744a75ca14516abe07472d0d1b723f70ca8cf0e5c9341fd2e8c26da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +expected_public_key = 4e2008000d3e22d76ae0046db986b85ad166052648993355c2262dc8e3477e83bc9a843476da24444b3936db182c608bd044a76ff88cb3c2b4b4f44f35932d0bb3cd8b834ad6e23eb9d9825d4378cc40a94d007fc5d97392eacb9dc770bc2569ee1b92cbf0aa2abcbe1e8a1e10ab1244e14dee474ef3e4531e330eadf71db2a36b32e152a88b5d90b8212b45b69c483cf261ad54564a76fb0b2b0c2589037a294772ef8c0b00666c2cd18cf54bb3b9b910094a69fab10df29620a890bb07e16cd8b55cbb40c074e0aa256253f7159c07aab0a26a9104b73b2942143e9622e07c055f687a5e1c2bc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db19c2fb151ae1d4082103046032603d8716726539dce01c940a78423b37661128f88e74ce04411ae307048c82de6a2af26996b28f91e32c21722554e2c51c422bb2ff5e3a35a0468b3aa02dca384b0ca793d1b524b7c24acaa889175a171b2522a07969249596ada9e76d17395c49648740fc0127beeec0bcad5c98852c3314111d149a0221168af2ccc65c6961ce3690d64ce1554a137b373319c56dcb5152a19059e0128ca872ca6f100d4509f196c7ad4fc65ee6accac6b80a9e8315c7619870b3623d38d2778c788c62d291a32b1ea078bc5a4e5e2bcd34c97e5a6301574c7854a8fefd62ab6657e4eb9371e09b8df2b1a45370ed45214cee3b86a1417c234081047b5c84009bb10351932c3a3078b7cea137ad22b665cac0bc0c6a032778ac437f139970c377b4d651b0e284d48040402685dc3ab6d5d206aab39c361789818ca7b3e4c8cfe2c4719e054a85b383eab160139c377896fe0217d46b98f3d0ac2a44cbddd003344974f30f3b9733579c506659272c1755c9346cb31153cbe133328283637ba5b4d3a906a3ad75d519786c54143101b77b7053977cbca1175a0ac076dfa3c0595b0473495738da76ba0d4a2333452d88c82750c94e745852a1118bf7a03b6f1b448298e8a2b246b166e18760dd5c468a4187b80fab8ccd078837b8223769b2489420f456140e2b911290eb4e780dde03e1a699b38b95edbb1cd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_private_key = 0fbb5b81752024eaa896950a462bb5a422377d60c59a8baf5295252ddc8a01115c9902d05821b7468773e8b844802a284ac25bf7140ee460373ef5024e40991b9764a7c9212c57bd3d71bd65674078091dcd36a157bb00775aa8676768eb880ae1947106202e848096ebd458cefc4850b15b0c2972b8461a59f8937e5b786635298896a392c11f61a678fe25253f5798e1bc7058b79397b5c190c0a0b178558e55c05c988e497578ab556702ca7ccf04b9e4736f32c002e21993b3fbca77f1ca560a1437b52f43085a551a2cb6abcb7dd07c3310853f374f25561563b68006617e55e2bfaed4b0fe04ac96955101f1933e9684e1183c8ee6cc866a6b9946126f8a257221c18722621bb151d5d0afd98cceace1050d2bb3e1f38796ea02f1f06642692e8982b2196aae69790b6d895fa3eb2245d09e16238618e84a01a55dd3e535cb113117d0b72fe10dc29a344b1a621900883b3bcd8d407b9dc24b8f468665b10ee86c5fb3ca9c6b0217a04c129da05056f6997785a59a4bae30a26f0159a6d98bc3aa4494a3e1bcb84432c2abaf22d43e22d45fc147cadd3a2cf14437ac35709c5636eb932abfc88f12322b50f8553de2c2d69a5622a88ba7d08b1c3cb7ee546c54426d70e400d8080d129104297c2e7a06a41ba345b1a73028817fb5a498ad81cc4a545b32cb70cf8264819334ddd9ad37e14a9a187828645ee0d567dcc6853c48c5af4a836f355d369149a5d32663c5b7d074774bc1720854c66225174028a565e42bb395cc1c8c3e80a23fc664281c8a9b144a39d7eb23b2211a3ce01b175265c6396108671845f4af8e37bffd5a97cad4c11db10048e467eb314275303f1fea05dd895ec5480f41dacf725965d4c3ca0c104acd228c0f10a634a18a0d166c8b69b4ffe604c7940d3aa06234e500c8962e39935976c1081726bec208be7f6b9ca51caaaa7465f03cb8de547d46c762797b7d58b056b78cbf13286a4479c5e5c70286ca6d05b892665435da13ab997b30d5e0223aa14cd2f50a0f80b64cb072cdab19118681376b968df5b9c2a20169759572c6cb36c88036e8c90878cd4e2008000d3e22d76ae0046db986b85ad166052648993355c2262dc8e3477e83bc9a843476da24444b3936db182c608bd044a76ff88cb3c2b4b4f44f35932d0bb3cd8b834ad6e23eb9d9825d4378cc40a94d007fc5d97392eacb9dc770bc2569ee1b92cbf0aa2abcbe1e8a1e10ab1244e14dee474ef3e4531e330eadf71db2a36b32e152a88b5d90b8212b45b69c483cf261ad54564a76fb0b2b0c2589037a294772ef8c0b00666c2cd18cf54bb3b9b910094a69fab10df29620a890bb07e16cd8b55cbb40c074e0aa256253f7159c07aab0a26a9104b73b2942143e9622e07c055f687a5e1c2bc274ab629bc5f6b5c691c6802c8a4c1657a1553bcc2ab43db19c2fb151ae1d4082103046032603d8716726539dce01c940a78423b37661128f88e74ce04411ae307048c82de6a2af26996b28f91e32c21722554e2c51c422bb2ff5e3a35a0468b3aa02dca384b0ca793d1b524b7c24acaa889175a171b2522a07969249596ada9e76d17395c49648740fc0127beeec0bcad5c98852c3314111d149a0221168af2ccc65c6961ce3690d64ce1554a137b373319c56dcb5152a19059e0128ca872ca6f100d4509f196c7ad4fc65ee6accac6b80a9e8315c7619870b3623d38d2778c788c62d291a32b1ea078bc5a4e5e2bcd34c97e5a6301574c7854a8fefd62ab6657e4eb9371e09b8df2b1a45370ed45214cee3b86a1417c234081047b5c84009bb10351932c3a3078b7cea137ad22b665cac0bc0c6a032778ac437f139970c377b4d651b0e284d48040402685dc3ab6d5d206aab39c361789818ca7b3e4c8cfe2c4719e054a85b383eab160139c377896fe0217d46b98f3d0ac2a44cbddd003344974f30f3b9733579c506659272c1755c9346cb31153cbe133328283637ba5b4d3a906a3ad75d519786c54143101b77b7053977cbca1175a0ac076dfa3c0595b0473495738da76ba0d4a2333452d88c82750c94e745852a1118bf7a03b6f1b448298e8a2b246b166e18760dd5c468a4187b80fab8ccd078837b8223769b2489420f456140e2b911290eb4e780dde03e1a699b38b95edbb1cd661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75b1eef6e8c88ff8da9cc4a9b01d4c08b6b585beb5bb9e084c6c47a717b51feea356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = 2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +expected_public_key = 478771e2f15c94962e6200501bb90320cb6a0eabc78fa97f2d69c5a7a00b81db6b2a77a2b99cb1b0598af4bc5da77623fb5a2d3d1709afe65521c5324df95e40d6c20189a4cf80162737801c48c1d4b253a7741dae446162d6a2457574969105e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9c615b63311756d79efa6957766a5de25b89af140a096ca145988e6582bdf1b590c8689a366b9b4e2877c2b5c5a33320d3d532e3958465c9586f604f4f800952eb5f96d73b6287bcead21f7b8863088728ff160d1ab7b3ca594ecee60a8b741903e4892f6154d6356bc308bacb17067772580af8a1cf5157ccdb86aa642b7da9a6a583508d18773b307b2b0ca3a1cc89ff531e0df13948c288fa4aa6d3001c592879649c72450202e39c5f837051db1314be4a25a13a6a00537c20ab5acdc6be15562b1027056bbcb63d6c8227683480b6bdb83c5a74f31b0d1ab84d129d4a883e2cf48ac96ac9aee856a331a5b8a0504a461daef078d3d916f962a9f9a82fe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a3701982fcccc93353b0387df0671abd2140dc9555b8d98251924fb77570aad8737b12533ea4bee7326761e86986273bbbd447e47119b3eca4b7f565de6c0ef8494048a08967cc17ca4231c433864cc961f6193774494aac460f23d978f4267aad92b66678b560dc50c5e797bfd407b5b89b83aa1023a3046d098d939b3974c6626fdb5d4df84b7a3a6d63727ae028560fd79995e6c310cc8b6f33a3f441aba1ba3f44714975b3c3c299aeea9a714058ac74f1334e8c011a748485289af49542df7c2ab7830a3f519c41612f3066b24d594322913e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcc9924dfbb3b052622a15bcf0dc7911d148028c8a8cb574334010e222abf06fba5ce5022da143e5985c7cf277e5db727f6b07f2d8034e033a25b0b1aa9d180f4d403b7072f87c694a5962be49938783613fce30e8bfc204800bcb45c5faba48968c95199297626eac6f4c1099c903a24ab54251c353016418ca774c52294a001c2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_private_key = f4d14a47f661de38531169cb1b05ca73a3527e599197570adecc4d6d6bb1f9ca0284480a21d57269517f222c9208aa0d021a0f8df20b39682cacb0472d776ce98442feb4a0b5148e62f26bcbc018e0556912f2a847fa8fd3bac8eeab94fa5619e9c1274423aa34056676658af6505445d0347b8554dfb1b61fe59cb3c696367a1cfaa87d47639d311476ac4b859bf2ae8fa86eb042ac5bb97c6e2a5c9c8b0854f73b33cb6f3f029dad0877e79909c4c5a4d4b77b2b0c8bb20540b72494815521d2737e709162d01b7bf324068453b16fe187631aac701551f2a1cc88d1b31efc00ca79ce7a8703fd098570fa2977399b49a59d97c8ccdab74e98e1995aa1c31feca0a46a7b6d855e53e419a814cd0a9682e14c74b80b995907b4735858ea897ee09c9f1f868cc4d9c96e331480e323b627252764039cd354c59679f6d8a56acc5179e9529e481c87603216a74f31e9ace3616ed4567662d7be4b18c0e82b949109793cfc1e722ba85b521d4e68a01816ba5b44bfb4e853cb5b70adb2748270139fe53968303720f72f7d2217e805ab0bfa5f9116a01af1448718155f277f2143a112babdbc211e0cd47ec7d169707c2c4156097a8b02c48a6029dc619ef98a669b555e1741ee6c659fd57856e9214187b51b0361f6bcc1c0f99ede6b5d0c394b1b23641d5c611b588e39103ed9c50843b0630035b868052493800053eba364d95900eba7b0a7088f2629b859c58b7534fd6483911caafdec3126bc0d10a526bd5abe2737c29636383622a2739c8450ac75b029847b23c85ad1624608576772b98f356b34a08012d36c8482c11db931b22a914ddacb9f02877ee00f57f022f6d9543dc3045a304e9305b8499baa9346b42f3889554056698a784d42575c01634175a659e26fb085b83c167fdc30ba62011db428beaf78710f7a659cb5320f25b1fa58618a991b049b7090065367370f3124aa7de80d666b9c6b399013965c2c9b60a89197cc8706e6320c220cc148b60878746392f6b64c6a69092074606617e797a9bcd5588d602ca9f23c5d017aa460add3a95f11e89c8ea3408527c9ce22c3478771e2f15c94962e6200501bb90320cb6a0eabc78fa97f2d69c5a7a00b81db6b2a77a2b99cb1b0598af4bc5da77623fb5a2d3d1709afe65521c5324df95e40d6c20189a4cf80162737801c48c1d4b253a7741dae446162d6a2457574969105e93c52f08757f80aa7cb28a2960a7208ec6429e7abe3267b9c615b63311756d79efa6957766a5de25b89af140a096ca145988e6582bdf1b590c8689a366b9b4e2877c2b5c5a33320d3d532e3958465c9586f604f4f800952eb5f96d73b6287bcead21f7b8863088728ff160d1ab7b3ca594ecee60a8b741903e4892f6154d6356bc308bacb17067772580af8a1cf5157ccdb86aa642b7da9a6a583508d18773b307b2b0ca3a1cc89ff531e0df13948c288fa4aa6d3001c592879649c72450202e39c5f837051db1314be4a25a13a6a00537c20ab5acdc6be15562b1027056bbcb63d6c8227683480b6bdb83c5a74f31b0d1ab84d129d4a883e2cf48ac96ac9aee856a331a5b8a0504a461daef078d3d916f962a9f9a82fe69b3c91955ce5d34f4b3731d195a92c84ae39f38c7a895e0468a2a3701982fcccc93353b0387df0671abd2140dc9555b8d98251924fb77570aad8737b12533ea4bee7326761e86986273bbbd447e47119b3eca4b7f565de6c0ef8494048a08967cc17ca4231c433864cc961f6193774494aac460f23d978f4267aad92b66678b560dc50c5e797bfd407b5b89b83aa1023a3046d098d939b3974c6626fdb5d4df84b7a3a6d63727ae028560fd79995e6c310cc8b6f33a3f441aba1ba3f44714975b3c3c299aeea9a714058ac74f1334e8c011a748485289af49542df7c2ab7830a3f519c41612f3066b24d594322913e769386aea37064f3b65746afeaa361b8f444c717c10d04cbcc9924dfbb3b052622a15bcf0dc7911d148028c8a8cb574334010e222abf06fba5ce5022da143e5985c7cf277e5db727f6b07f2d8034e033a25b0b1aa9d180f4d403b7072f87c694a5962be49938783613fce30e8bfc204800bcb45c5faba48968c95199297626eac6f4c1099c903a24ab54251c353016418ca774c52294a001c2000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43af581c2fec9055830b38cb68fb506aa927443b1afd1b2b6faa6f92a325985c6ce8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +expected_public_key = 707a4731f46a6d2c59e27c013d7834f126719c302c7af3609bd0457173850bac49581557700cc0dcf034aff6b36c2a53a5e8580db101e0f718898cc8cf216fbbe1bc78c8984130c2ea921d872224572ac3dfd0ad0ca32a1075c9c2a97c41635ac9dc7aa2d014dc460115c93fc427c155726830b9cadcd8523c8722c3e4639d83c5898054fc68ca8588c55d89640e5cba32fc3f5cb283f2f9032f2c8dcf3847ee1b67ca698292a99348d194df068db0d46d992aa59a83c08b24017ca1048f77532f22039f92bea7139f1dbba914b10dd27abcd6912a8fdab2ac5c68646ab880554b5512459efac549950270e825e39670f06288a97a5e36a31e61a5257a0534e06c1418593b7e844f6381bf1ff5916be88c697c6a6c1c0b42ca1daba6300106784f125e7fc80a37f08a6889771461ad90938894a54914e2cf759c60b3dca1b86abecad16efed660e4422cae131f827b14b2bc4a7552073ab069365bcec3d3a41b22323fa827ad50793b3186c6a0a7e3b007c892868f18bd62105e220517c0db3057f77a3be29f8e2276a49416737c9990216c2eea6fffa7b4bdc6603aa400cb5675aa5a78458a498056511ad42b8550aecdc4940ab1c1739c33fd07bafbb287ae595fcaca6ea4bc3fa708ad3ff8abb4126d6aa9a4d9572b74cc5567b55412e901ca0c4d5eeb4c9683131522917f0a7eaf56b20d1177b448878b657700ad885cc0134a249970e1ce1ca779196215d104117c3c884c9196f33627d6712a3fc234fe171db342a24577a55c5c68e3a2350e41c14c701b1b01a39d2850b69274b2ca3a20ea2cb444294ea73042939a5a1a9a905856876b0b0e3492b6a328b40a949f1865f54558aa6263789093dea2ae2e8631e2ca5cd2662583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89d51669947f1ab44f9aba94bb239264a0c6ccaa64c0e2b3fe6212924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c4471a36aecaf3868b4b8f034a756020864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d80f31bd314cfc85416b2b2a1973714ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_private_key = 7b174b53307018768556cb04e6621bcd7558aa9c7c9ef9022b561c321a4d1be7b459826a86513bb12873fcbb616323cb1cc83ba8b6bd6de7432fbcc73d7c12b4a76ac59c00bdc431c071993cd32d63c66636337fa8f88697b63acf4a92c6eab4aec503cb352b0e40c2f0920dc94909bdc7b4b26a3826cc8bd03a49481c684fd65348a291379982a0f73e78b59ffc86a1e2b3a79f4a038205ab0c5b705e523b01e022f8a54e2db0b353241b5eaa4e8299ca1b372b3ec10bb128363bf291cf99bc12008bdfec24db711d71f56bd2cc55fdbc223042931fcc51d6d7270d6943d3fc29e44433afb0963bc56bdbd9be6d2a2f28380f2cd420ab844ef32c1e94c00e3cf8c88995ad8d234ad13b2cf45901369835e31b35595c9ea9b8338b125bc2179523328d3be672ec0625280bbfa10814a5ac707f811df3c79ab6966e5bbb8a93b6abaf389bd9a859564c1c223334da1c9cd264cae9b43990209af29c5d5a943de84461c1eb34ddf54339770c38c1b21b5abf691c3540884845d736a5728eb3226a312520d9a51a026a7952457e0f325bdba82a7faabb1d977906b8cb8e91b0034ab07b656944d416a5e9a779c0563f082e604cc673e1478fd5c0ed528373bc5d59394082160414c16fdaf8742a91ac935c322d0668490ba1099976bf908214674b6d7083da2433abb63a53403e35009d8c79ccb88c6704d5a3085bb2fd8c57093c083aa55636410ffc1b6b635b2a8b65a3ad83550fa83a7b1297ca7b1940758515eb115d7cc96e34415996a875d9bdbb0117df107d8f4375e14a835ffb89aed34da8d33dc1a08e7f103c520c48ec3b651ad79198c354330701c04c5878365abad936f8163c7f094a63c43fb793ad98750f0ea9ac18d0bc503b9ff198086e070c76c202882716920c31deab30dbb1c439a03931a6b855ba96cef757460776e8e42b4f86848b019e83667fdb97692b1578662a8d27b8944350864c016275a01062e6924b5b2a4d4454c38b6ebe471cc55981b6085e7f65b3bc6bacb52caa69f3b8e47b6ab0f413d8d138e5c73c89400a9ef7bfa5878155dc6e83b57ad8741f525750707a4731f46a6d2c59e27c013d7834f126719c302c7af3609bd0457173850bac49581557700cc0dcf034aff6b36c2a53a5e8580db101e0f718898cc8cf216fbbe1bc78c8984130c2ea921d872224572ac3dfd0ad0ca32a1075c9c2a97c41635ac9dc7aa2d014dc460115c93fc427c155726830b9cadcd8523c8722c3e4639d83c5898054fc68ca8588c55d89640e5cba32fc3f5cb283f2f9032f2c8dcf3847ee1b67ca698292a99348d194df068db0d46d992aa59a83c08b24017ca1048f77532f22039f92bea7139f1dbba914b10dd27abcd6912a8fdab2ac5c68646ab880554b5512459efac549950270e825e39670f06288a97a5e36a31e61a5257a0534e06c1418593b7e844f6381bf1ff5916be88c697c6a6c1c0b42ca1daba6300106784f125e7fc80a37f08a6889771461ad90938894a54914e2cf759c60b3dca1b86abecad16efed660e4422cae131f827b14b2bc4a7552073ab069365bcec3d3a41b22323fa827ad50793b3186c6a0a7e3b007c892868f18bd62105e220517c0db3057f77a3be29f8e2276a49416737c9990216c2eea6fffa7b4bdc6603aa400cb5675aa5a78458a498056511ad42b8550aecdc4940ab1c1739c33fd07bafbb287ae595fcaca6ea4bc3fa708ad3ff8abb4126d6aa9a4d9572b74cc5567b55412e901ca0c4d5eeb4c9683131522917f0a7eaf56b20d1177b448878b657700ad885cc0134a249970e1ce1ca779196215d104117c3c884c9196f33627d6712a3fc234fe171db342a24577a55c5c68e3a2350e41c14c701b1b01a39d2850b69274b2ca3a20ea2cb444294ea73042939a5a1a9a905856876b0b0e3492b6a328b40a949f1865f54558aa6263789093dea2ae2e8631e2ca5cd2662583b676ed6b4f04a33dc3eb956a963bba0670053c815f3c7ebd153680e98a89d51669947f1ab44f9aba94bb239264a0c6ccaa64c0e2b3fe6212924ca77a8a6b8316a20e6a5df6fa8b3e7a9fbcc54c6d599c4471a36aecaf3868b4b8f034a756020864ce4ba9a4c36cb02f0b4ddc94cc71b9c393ca6237a845b3cc9d80f31bd314cfc85416b2b2a1973714ea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28f12f3ecad62bd327f1c44ae86c0be6e7f15112b7f6f6d5ec7b13f4dfab718965812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +expected_public_key = 8f31aa78a9043268c7e25b0c43469ed0a535bb9a8d4ecc65c3cbb32bf2361838a8358b2edc1a1ea2fb66cae5070a30080a84a9ff81b3b020ab1df4548e510f03b13cecd4aa32f380172ca85cc8962acb7a51619632b53bf828a7ccec1b65c72fa0f814cd2c101690b769e452e34993b0a33978c19da61b0061f24661f20ea6a566b1d7aeacda859e52cbf32aacbd1b7e1e66b138d2cc613a26996b6ec8d89c63a34a44abcb70772083140fd6519eef107f91983f2e4557a7e21c62179674031b9e7c2edd845188c12b4745b7a68308e1e19a86968a4ca001268132e493a79595989e7b55a9f2ba83ac40c89cc752a97d6d6b6982e1033298445384c5fd04ccc06692cee0007a8481316bc02a724491e469ed7a2f1b809715da8cd130a2cf4c200b168ff33181430cbb5af152c0510e46b9aa8d83060648c2ecfb74840c5110004c25d9164e1a3dd9e181216901b1169a9ae3a760d1ab96c7bfe405c657a2cc1e62c65d99aef490892e96bd6ac08d9421975af70b16d3a12f898528130f30ba4b9b513bf42b2f5be08264a985b2ca61998a2a30030e3bd51200ccb3d0f66d08a677f6236bb951150e29531ec278f3d013bfd0afa81c009d0c78537c62557b7c5c930614e14d9600a9e8ac38f44761460666d4701782390552693b83736e3e340d5671ce0c5128cc991a984630f1f3349fd80e7756abed753226b456c2968efde96de0a924b926ab75bccec5e69b24a42aa34c110d75ab27495c5d4cab88b1afd49a2fe5c02acf3578fa4664934a1049fa7d89f666e2dc77165498ef61c575b4156ff7c2d7aba435870999d62ae36a6cebc66d04ac54bf4cae14c0ae89aabe90f3c397ebcfe69aae0618475e5512d5534f85f711a20a9699c620181acd1162b06e990096f7799f836771a05e56c99d3402599e713fd0b44be0db130ac3079c583bc0ca266a548da0895c1a3c3d1c28385537465df75b055106a215309309820813b3b8f7895d53611061bf796b47ce1019e3aa09a013764ea8ae0573ca62818acd346fe3012319db7d351c073d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_private_key = 96a50005840f5a5a0e8b1083a57c8402a2cfe227ceea80b5d9e175ae3131eb8bafd291a63e01047fb889d2043a0e814dd55594f4274bfd73bf1828bdef5a97c057091e480f3d6a3723467b989b635a7a70617647eb2060e6158a9dac8b40263062d3975bf88b24a1902ad9c72bfc7d6b69adf340cd2691119bdc67d8f5b28fa8894418ab9a0a97d9e9bd40c5741ae0be90735c1c2c140c8461ff507eac55bb16e65e93132105c46575006130c67b500030fe11be78e4a4bee364bd21041a68a676b398c1237a6864b494c383adb4a1bf369e606894be6917cf614934e145f961b3388ac3de939a309373e47a7134b57cdd5915ae98c842b936a1660187427fe771606be8421ed11412f020e722a3f51b6847391c6d77a100fd484241209efc778496236acbb8a00910820154c77916b8b0978ae3193b1aab565a2bd9790cbeb3293e4910d2631672036e60c6806aa676b8866d3284c4b3b411e7d2b4a6a75d50675529e1b4edfb5365b999711763800bba82f66e8f6712ca652cfe0190b46c377d7bb26fcb7f32160cd031c862cc9a0233578b2bb372cb231e0536d3c88f46aba8bed1a4cb6338efd847d2f5c9605359fc2a830476a027d477324a8b15586c2fc2a942b4ce340088e7e8808c9c97e2b91d9e25417404755cc71caec7c5d82c35b3202008c4221cabc0c83084f4b98b0941019be55b4a874b61e20a75ba25ab9baf806b52c52116d9d17d586289cbd40d7bc42dcb672e76382c420336d88b9c3ed690458793c6126a8c20822a7b1591a27a0de3c0ceba443ee754829a471304cc985013eeb453d7b522b365c32d33baa2d362306819e6abac03a0074b632953155a2250131af6bf6fe910d6a75fae56bc75485d247c5278fc50d5465aa67500584bc6fce25eb3b401eee5365d7c6d6bcc500c99c343476bc99cc433c173d6e74ea054adbedc8daa57a6b8a77ce5e105e759057f20a7a02cb894ec8d72424b16d8925f118375dbbb847393712a4d9c64c5f997636aec817fe593b1754bc8f2ac7afa5a6dfa2580513536541e6ccca60bd7a397b49dd34a8f352882612cc39683cf8f31aa78a9043268c7e25b0c43469ed0a535bb9a8d4ecc65c3cbb32bf2361838a8358b2edc1a1ea2fb66cae5070a30080a84a9ff81b3b020ab1df4548e510f03b13cecd4aa32f380172ca85cc8962acb7a51619632b53bf828a7ccec1b65c72fa0f814cd2c101690b769e452e34993b0a33978c19da61b0061f24661f20ea6a566b1d7aeacda859e52cbf32aacbd1b7e1e66b138d2cc613a26996b6ec8d89c63a34a44abcb70772083140fd6519eef107f91983f2e4557a7e21c62179674031b9e7c2edd845188c12b4745b7a68308e1e19a86968a4ca001268132e493a79595989e7b55a9f2ba83ac40c89cc752a97d6d6b6982e1033298445384c5fd04ccc06692cee0007a8481316bc02a724491e469ed7a2f1b809715da8cd130a2cf4c200b168ff33181430cbb5af152c0510e46b9aa8d83060648c2ecfb74840c5110004c25d9164e1a3dd9e181216901b1169a9ae3a760d1ab96c7bfe405c657a2cc1e62c65d99aef490892e96bd6ac08d9421975af70b16d3a12f898528130f30ba4b9b513bf42b2f5be08264a985b2ca61998a2a30030e3bd51200ccb3d0f66d08a677f6236bb951150e29531ec278f3d013bfd0afa81c009d0c78537c62557b7c5c930614e14d9600a9e8ac38f44761460666d4701782390552693b83736e3e340d5671ce0c5128cc991a984630f1f3349fd80e7756abed753226b456c2968efde96de0a924b926ab75bccec5e69b24a42aa34c110d75ab27495c5d4cab88b1afd49a2fe5c02acf3578fa4664934a1049fa7d89f666e2dc77165498ef61c575b4156ff7c2d7aba435870999d62ae36a6cebc66d04ac54bf4cae14c0ae89aabe90f3c397ebcfe69aae0618475e5512d5534f85f711a20a9699c620181acd1162b06e990096f7799f836771a05e56c99d3402599e713fd0b44be0db130ac3079c583bc0ca266a548da0895c1a3c3d1c28385537465df75b055106a215309309820813b3b8f7895d53611061bf796b47ce1019e3aa09a013764ea8ae0573ca62818acd346fe3012319db7d351c073d17b3f377906e484fa7198dbd639e3f98b7f8db37a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132604cae8b58e0434fb1475312355a8b40145043bed4b269aaddd654d2e562324bc78e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +expected_public_key = 6693535cba8a70d2410f72cf1b69ca2951579da03b23e997146bb3519c521ff325f9f1a1c1d506cf42079f694f0340abda4806719b8df468a53a92b5bb2629ad0b54799103c0c17936565e30d9272f44a657f190cb92887d4612a517a35e87b24fd314dbe32d99c7758e5458038140f1ca660eb8c1e813822f52865f6671cad74ff478514f87afbc4187c0c12a4f388a63613d592c1dce237d13a01ee6db54013590dd91078b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5b9d044a3950377c2ce8a010c9f59ab7e27aadc49baf10521d7b11d3ed707ca2b377912c131484c5e94cacaf88595c711599c081808681c6609227648033011fed686c9a2121e724346426108a5c514306717224f5928063549b268d87ddd91a79ccbc42f884f39d097e6246266173a79c68896235619928faa907d93226db05157319456dd06564f364e8ab68aa1fca43bc419425160a6960ffef152ffb85f24358d2bf3c375888fe8f7245225a27bd710efba2ff73901c1f080f6064c44ec982716b0fc7a88aa41532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe930915d7751fc7b1094d4757fb0baf1aba40d0d443f60cae0d5b19bc4c705567a602402d18c546ad9b8cac337ccf4a0c1a23467e75ca55090ab4435446b9737902a73c69cc86d050a8c11fa928257c5774d3f74547016995633f7c564dd4c962f9865fe78347d8d0a5eb449f6a046bfd6028fb1185ffc86e722239cd3bb19fcc117c34658f00b10914989cc24545e615fa824742a1814d7642ddd21e2a89194d13270835799e23ce97f25ca7bb82bf096358916d73c73259853c37d814425b37e9c67f5630b408785290934a70448132c653afec782a478920a085c46823b960ad795674b937053543b80b98c52fa29961380a8360034674852d151a8c1393fd0c97a0b94695b8adc652ad1d3c69764387e75b1038921fd53171fd43657fba4c919411161004b4db2e079541af110e166ccdf2b77a8709028b18a96e015f13fa6142c63e71f73236d227e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_private_key = f8d65394e770f5185b92393b4f673a030a0740d3ab2ebb263f7561f1ec5b91160832bbc444834f67ac57af33abbce75f31a8bea234af52665997137caad53ea16721e26172d05930896c9b6034680bfb74af68969c8c51dd983a778040fc7c8a14ea792db54d380cba826cb772a654a496ccd3e983642997ea9253c15c958ac162a6ab5a80956ce4e3be95fc9c06a98cabf235c35475fb58ac9e3641c208a0bb481f6c722c0d5b983d8b1f792b71cda7a69db9c0c00ab4c0f0375da298078417a618065f808419180961aa5144d66082b2aaeef26b8b55b14bc395a821c2e87805afc07bdf91874eabaccee0448cdb208f139a0f4c4b2471beae5597789c1f89a988263b8aae549bc13218eb64a5b0ea62a39b0927667f302a277c769cc0e28823817e32793350a83f9b8b2a3ac8153ce6843d65a7fcc75493d414f7c98ce4c583cb66cbf701cceee96771d2c5f94323ae2365be9ab783365b2d5c97a318cd7a4788abd4bafd31a3f19363d4e5bbfc996c2dc7b82fb98ba18070d4b014ee1854c12250b3d18157112838a58e005b3c9ac59fc8a65bd1f281fe7053d3664585b69015f74b16187a5d19cd26c503d0b2bc3ae32799d97440bb3b60c40f0f7c4506c56ff95513ef8b2b7df33a4d3a1388cc5feb44aa208aad6cc972859b15e10541ae29c2234a904f6c6a8cd449c5b86897ec5978b4cd84f189d63a072c7ba846a0884db14826743921e13ea5e105736c2f84c50dde9738a4e9588d22b296fb13d57c4347868c7e4394b5f76af2c18a90dc7491d6a5d510a75a198848737b7ef45970387a29b51c45b5623e9b4eb2a3414a1c285bc866729a98fcc08e3dd31567d63e7c57437f5a90f9ec35fcd74050858825781cc6d5a2ad5608a2d063c8cc369e6a7c0f7c7eb27ac433883a5946acdba84fc32872cf689fcfb50ba6e894185c973c196ddcba52252948c7e159114a23a242b2f5d0996edb7f2cb93408b9cbe68298f8455af632275202c6b2e1370c5c9d1f6403c1a7832343ac2e524709268f06eacd753250486025b691b9235bb2cbe833e0b6086c9959f716b9a8d30cb840b06693535cba8a70d2410f72cf1b69ca2951579da03b23e997146bb3519c521ff325f9f1a1c1d506cf42079f694f0340abda4806719b8df468a53a92b5bb2629ad0b54799103c0c17936565e30d9272f44a657f190cb92887d4612a517a35e87b24fd314dbe32d99c7758e5458038140f1ca660eb8c1e813822f52865f6671cad74ff478514f87afbc4187c0c12a4f388a63613d592c1dce237d13a01ee6db54013590dd91078b23bada249fa57a91c0467daee45af38440f008c446b6503b94772427a5b9d044a3950377c2ce8a010c9f59ab7e27aadc49baf10521d7b11d3ed707ca2b377912c131484c5e94cacaf88595c711599c081808681c6609227648033011fed686c9a2121e724346426108a5c514306717224f5928063549b268d87ddd91a79ccbc42f884f39d097e6246266173a79c68896235619928faa907d93226db05157319456dd06564f364e8ab68aa1fca43bc419425160a6960ffef152ffb85f24358d2bf3c375888fe8f7245225a27bd710efba2ff73901c1f080f6064c44ec982716b0fc7a88aa41532a99420c8b52328b76baf58d1fd6a652d7ca5d4abe930915d7751fc7b1094d4757fb0baf1aba40d0d443f60cae0d5b19bc4c705567a602402d18c546ad9b8cac337ccf4a0c1a23467e75ca55090ab4435446b9737902a73c69cc86d050a8c11fa928257c5774d3f74547016995633f7c564dd4c962f9865fe78347d8d0a5eb449f6a046bfd6028fb1185ffc86e722239cd3bb19fcc117c34658f00b10914989cc24545e615fa824742a1814d7642ddd21e2a89194d13270835799e23ce97f25ca7bb82bf096358916d73c73259853c37d814425b37e9c67f5630b408785290934a70448132c653afec782a478920a085c46823b960ad795674b937053543b80b98c52fa29961380a8360034674852d151a8c1393fd0c97a0b94695b8adc652ad1d3c69764387e75b1038921fd53171fd43657fba4c919411161004b4db2e079541af110e166ccdf2b77a8709028b18a96e015f13fa6142c63e71f73236d227e36b7b6b6a8e8a56cfec8c46746a50b00a95705bb65e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2cb899475c1802b1dd76a9783d93b4225dc558eea558ddc598cdc45a898b7bbfb38aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = 38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +expected_public_key = 3883135665ac3d6b0e710204689c2616487bf51295c5010347b4663b914bef02791a147c20574f1dbc7065e7b2a930236a99304b6529e95b9eadea48fa5490fcb8c59e6b5fbfe5522bc057e3f9aab8e7aca680cd620310a26bb4309a2f2c4c56226114f8ab63de71b74971197d6a52308910188b603ac8523493a751a1cdfd441259b03f5d140f862cad7a794307aa31cfc4624f2a740552266b22240e631638c2c17492adede14997d95e4890002110ce40fa83f416a2ed06806cfcc49bc9a1599512db09362aa01650f7cf56290d2e85424812cbc009afd5520da63b30dd814e25bb1f974b7f3f77c38c638e1943beeba234736a029342a13aac8d21da0747f41b217159869bbda51885ea9b0a99abac1b740ebf40cadc78a6fbe93076e214031264275c3d56486efdc00e9f1ab1d3bc98963c908ad13268d9b068cc2ad5c36f68a11281da7b2c325509383e71d098c22a1de3c3065f1082087338b3ab021b0a3fb2b5cbd1b29f7b3b7d897c8c874b9d71d34dd60bb686b99c82750527704a53c737b157a6c98a148ad0727d13cf770b038e9a275e568b19cc2bad360c958c54900c59b4bb69b8341362ac7fb589ca96f563de54a46d3c02c475788351c5ffccbda1998a87d7a27301095ac8577cb84c0a4a244cd8c544f4bc7b68cf02a99d9af90bbb42a1ce63740ea784e665882c6aa1ae151501e560ebe9116fa9cdfd749153b7310e1583feebc2856384923200a811b2c0f71c23076de6590a89b6b6114316eaf80c90480c1ec1c131990637765fb17c2b0cb1ca1c03a3461bc2c8534b35493b3dd3c8d7b6816d8127d192a6f7d79e805283e3e882e8120aad321bb6a197fc60cf443ace984510bc59c8ba832699c8b145bacbc090965ed08785f72d24f4b9ba70c41ea79c91591b2295cc5903b29e04bcf3566c9b7c001ada05744605f1845f3e13bf9f22744659b2913b2489b073b6f01765c756aa494a41e44b599719ef5968853c0896425085d75cbaf73abe304025ca6006858ee7c1c9cf0067b576c168651e3fdc9b9d978cb1c62354094faca0a4adb426c157166f08034cd4025a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_private_key = 5b013906459962532f06782c95fb2823a230d9610966b0a13d245562e73716a0216f566c8615848b7a481b405314c79cb5b8727408310a447e58d12a9ba69831c5a32828621fda3424b9cab229aa50716cb4b0499c5a4041eb090205131baace04c31f0467b80a663f74ac1e51607fd5d4c8d3b02d8706afbf83b4db3c8f6a72a8a61c9056279ec64c3de62378d01c2b7352357675bfa3b659f03314598611e9437e73bc0d7a7b15e9076213c77d08478d00e10fc15c1a2cb37e3b89930c9342605515b3c88b8a06062a372f8a6448a984aaf45168d891c5f0f4ce5330152459a82fa92c4127a5313b421ac4693b0bbc1d5bbf49d16a69e9482a37c42b07432fe405c218a08a5a22f00a443f258fe738cd8e54626324c6026993052439a0c47e3bc4849216c3340a7621826a778623866849b250bf25a6a28ec6a7f69962f3352bdb216d306423406c946f9b2bb211052706bc6a649dfea411e2061c9f21441ddc8628b69c4529764ae16bea89470f8407faa00bae8715314366bcb797887bcfc57c2cded27cd8089ab564576be95e014330c804673507899e7c6c98441bed4258f439c264c87becf0418fbc9fe87338e909bf3a1897c8c151b0305e1729000e93b92b40a658b871e0da0827a93d39a5a0f6950049f315fcc09843673d3efc140f9551057b5a9fc55c9fb7839084852d677c8dc35e01f7a3f45a3a61c28a38a685b330b8e0675abe736214661dc59409e31b711a6c6392ac1d50ea9da3c845ad678f38b1ca8e313d4819c75c08231ff38ba0e4c33d69286880413d5c77f95b52d54045b44b5c0c453c5c6007a8a561810289b8d192cb5846ac273e4e7420e96c6a8ef78b89842fae3a365b426c99c49acbe24a86bb7cc89759abc94e727b1ba55a5a539c2ec4879e3c040d3d5808ac05b794a46e20f67a5622235e11773b991f9ec55ac598bcfc365b1201008bf0caa360b1ce7121c9304f4629bc65041a6902390f8a5c76d6ce4fb6b357020340327b861b3148743a4eb455b66762e499694f558f19765d6db32b7b075ff6a6c3f49622ec482688964804a6158fa08be2873c3883135665ac3d6b0e710204689c2616487bf51295c5010347b4663b914bef02791a147c20574f1dbc7065e7b2a930236a99304b6529e95b9eadea48fa5490fcb8c59e6b5fbfe5522bc057e3f9aab8e7aca680cd620310a26bb4309a2f2c4c56226114f8ab63de71b74971197d6a52308910188b603ac8523493a751a1cdfd441259b03f5d140f862cad7a794307aa31cfc4624f2a740552266b22240e631638c2c17492adede14997d95e4890002110ce40fa83f416a2ed06806cfcc49bc9a1599512db09362aa01650f7cf56290d2e85424812cbc009afd5520da63b30dd814e25bb1f974b7f3f77c38c638e1943beeba234736a029342a13aac8d21da0747f41b217159869bbda51885ea9b0a99abac1b740ebf40cadc78a6fbe93076e214031264275c3d56486efdc00e9f1ab1d3bc98963c908ad13268d9b068cc2ad5c36f68a11281da7b2c325509383e71d098c22a1de3c3065f1082087338b3ab021b0a3fb2b5cbd1b29f7b3b7d897c8c874b9d71d34dd60bb686b99c82750527704a53c737b157a6c98a148ad0727d13cf770b038e9a275e568b19cc2bad360c958c54900c59b4bb69b8341362ac7fb589ca96f563de54a46d3c02c475788351c5ffccbda1998a87d7a27301095ac8577cb84c0a4a244cd8c544f4bc7b68cf02a99d9af90bbb42a1ce63740ea784e665882c6aa1ae151501e560ebe9116fa9cdfd749153b7310e1583feebc2856384923200a811b2c0f71c23076de6590a89b6b6114316eaf80c90480c1ec1c131990637765fb17c2b0cb1ca1c03a3461bc2c8534b35493b3dd3c8d7b6816d8127d192a6f7d79e805283e3e882e8120aad321bb6a197fc60cf443ace984510bc59c8ba832699c8b145bacbc090965ed08785f72d24f4b9ba70c41ea79c91591b2295cc5903b29e04bcf3566c9b7c001ada05744605f1845f3e13bf9f22744659b2913b2489b073b6f01765c756aa494a41e44b599719ef5968853c0896425085d75cbaf73abe304025ca6006858ee7c1c9cf0067b576c168651e3fdc9b9d978cb1c62354094faca0a4adb426c157166f08034cd4025a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d1a7e0760c345cb5875303e20e4c72076c794e56ab75231750a190b45f374d979a2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = 97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +expected_public_key = e7752afb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afba81681b834d55864f8e240a69067ba1384f9279576110a0809b34c81aa350cae66c535d5f24315fcb30b3469e59c45f44915d9a010e834071a60b4e29001674326e8b556943246365c87d9133a7e68a6f57b63f5b72a94d2545dd682143ca0ec892ca3376ddb188a83b3ca5d31899c5b8a0ce014ddc1bec2988171d7bbec2742feb77e286306d53b687f9c04c45a4eedd1c4dc593067086f1728724c282dc8b94978a67bacda824e6a259e12c44340159510526b6630df44bd4eca50c62b77fba073de86c167e9974316962c6805dffca9f5d4a413cc04da0b4a9bbc3db7eb825d7b1f3f942870c559f900bd0082c13dbb59d68b8b7b84906b4c5e86ac94da520b54a5bea0f51fdd12cf53e90ab317117e320afb377cca024d91685a2371612724208fd02a2240b32349893544535ec21655d398914bc53589b5a6a920dba6b76b125c32611c9db77827132a00651f6bc3394eba975bc40e87c34a696a8ebca0cd356517b4b16f53c99feb517337a8231286a0ece32a9208bf90daac845cabb86c8d61d498543c4ad2325cc82a75a11a9751c6a0d1a7015f74ae1e32485b26372366cc97f42ea0840e20bb54800028e537cbe867aee64a1ed4453d27768a55815557e71a3857012e33172b3a6abc6729b207559899043185919883c9e6f74d1c5414e5728d18785ccaaccb753b61a6518ef57b4546c5261ed80d6262ace4d72f423b15f60312a9352e19e0887e7a131e590cf24b499dfa53ac3c5123240469350e097524263cad98a50e46739bd342bcf5d454df2a82004ac7ca8c23a7b406fd396239f74ab0686141d3ce9aa85efafabe79c1bbe2883efc6b18a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637e0259e485203077a2658a73871b70e28358c94143e78802596a4124b75a2376718b548d8eea706a4a256b297271a2a0afda68030504e5c35f7f4cab2a667897774fdde85e5ae01fec059111a1b1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c817505418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_private_key = 72a882d4848542a06f83c28df39c2384c2c86bf97fe18255aafabaea22a366da3e6de5b1518465ec60a5d0754fc4c19bea36b63ee04a25617b3a0358b603998db88c05593a637c232fa0b4e417573ea5afa5036f752a0bd8f123b3287ddec26a98b24a464a64502c92d284a2e22c2a50263872649367d39bf1e315e2fc5668590a534b6ad9d6298edc57e9d008203a9206c3288634ca87ca5b7cb0aadee53ce9d58e8b2b6cf340afcfc73d9791c8c2079f352b5e6f0bc67942b58d1a2661b336c37c3be7418f93bc4205f693ad795bd2b2827bb96dcd66ae82346550228ae5c91c2bb9aef4f81924772855f695929b975f7273d4340020f33aedec90ba0691d9924b84f1ac30e4c34ef0949064892c0abc0b7c54c7b0998be1c48bf09b6df143085400ac96637ce7b6cd32b8fe778d9fb6241ee58704737989c9345e88bd46f96c3f43c6482c9ccc99200ff02a9e4c0a3f81468ff5624a050272591c04d5a44fe79ca2a575c9ca4d629001230482fafc9f3030180cf036a875afa17a979c1b8c835931a86b090de5236365acc6e1282593aca8f74172b03d72a9c58cca346d488127046660bc7936a0a78c209ffdc2cb24a4c9686a988b8437cde043ae34c528698643b916ef7b8d66c77d70c5075b1b2ab0975fba08a6ca8403a753a63dd32f7da15b2de025b015cafa85c0409a5b1113371a11243c4626f74a76f3f62911e8851b265a302a5a48a2a22861864e5c8ab094036338c1b5cc7dafcb5f66e585f6447864e505efc363a939bab445c2007973186143d7f38aea5a00b77213a5e053f6f74e9aa92574051a5b281990531182549371b9610f69a3ef3519d06a764d53102bc68c220145f4072d3ce5c7a8840bbd1c21a3034fe5584fa6191f44128652c73b09868fdc947cd90cb7ff9225be48363437c5c45314a69460c3f55882b352937ca65b344c493263ba7a0d1513796916243700b4faacc36f85872f049b399cad9df55f29e93aa6656c3139773536275de5b52699299a6548d626c0c39141d64889f20013f706966d10b60b9b311c83b69ce9888beb2cc77192a1c73f1f34bce7752afb068a323b8c78b5ba865bbd2cd6651d9659647a99817631ade890c1945afba81681b834d55864f8e240a69067ba1384f9279576110a0809b34c81aa350cae66c535d5f24315fcb30b3469e59c45f44915d9a010e834071a60b4e29001674326e8b556943246365c87d9133a7e68a6f57b63f5b72a94d2545dd682143ca0ec892ca3376ddb188a83b3ca5d31899c5b8a0ce014ddc1bec2988171d7bbec2742feb77e286306d53b687f9c04c45a4eedd1c4dc593067086f1728724c282dc8b94978a67bacda824e6a259e12c44340159510526b6630df44bd4eca50c62b77fba073de86c167e9974316962c6805dffca9f5d4a413cc04da0b4a9bbc3db7eb825d7b1f3f942870c559f900bd0082c13dbb59d68b8b7b84906b4c5e86ac94da520b54a5bea0f51fdd12cf53e90ab317117e320afb377cca024d91685a2371612724208fd02a2240b32349893544535ec21655d398914bc53589b5a6a920dba6b76b125c32611c9db77827132a00651f6bc3394eba975bc40e87c34a696a8ebca0cd356517b4b16f53c99feb517337a8231286a0ece32a9208bf90daac845cabb86c8d61d498543c4ad2325cc82a75a11a9751c6a0d1a7015f74ae1e32485b26372366cc97f42ea0840e20bb54800028e537cbe867aee64a1ed4453d27768a55815557e71a3857012e33172b3a6abc6729b207559899043185919883c9e6f74d1c5414e5728d18785ccaaccb753b61a6518ef57b4546c5261ed80d6262ace4d72f423b15f60312a9352e19e0887e7a131e590cf24b499dfa53ac3c5123240469350e097524263cad98a50e46739bd342bcf5d454df2a82004ac7ca8c23a7b406fd396239f74ab0686141d3ce9aa85efafabe79c1bbe2883efc6b18a3879a95ea3c67c7c23b25b4aa95cee8847a8ef4bbce67637e0259e485203077a2658a73871b70e28358c94143e78802596a4124b75a2376718b548d8eea706a4a256b297271a2a0afda68030504e5c35f7f4cab2a667897774fdde85e5ae01fec059111a1b1647571f2dcc0f8fb5871f8a2b154c4d1b7392a96789ea5875d15c817505418bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc0f96fb9e146a1c22cc5d23e9108af0dc5e13b7810b8f5598bbd5f8d4b54c8af7df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +expected_public_key = 4a20774e234119411edbb3515e4c00a4987d491c37b3890db4ab249d28aef2c0cee1768c52b70cee7966b31c58ec975ef8b96dd2e156544a88a9772bfc834d422599b117968b648172b2ace7633ede1624b0a4cd031779040128c0e94332b03a798579206873b5583ca9c6be34632fddcc223a76c415e262ec8831fe32225ab2b484758728182eb45c851118cfc5086974403f6b161028534bc0390dc7d7902493440134c784b30289833652e96c58d12867cccd61713b51345c21c865976c0857808422f78de8b95472627cf6b895dd4065c68156bcd16e65494da75ac2e04668e0548e9658cb55d89bc8f98333e030a4720027aba862fb6f3b006f6be711b10b6d5e30b892708f42c49006357da4f637e8b3210e49817a9026b7403d64d861dc65955d75028e596fa68c97edf133d0997d84f342caab0f52db4b1330af6ca57b8b2423275255dc605fb9111907b648834c37ad812a300a715e231dba4551066051d31b82b6c3be14928c9cb78179e16ec0088cec140d3d6842776b30df33a11154a04ea7a6ade981b8c2995a37bd16734f98e95e1f753425f15c1a9b69ac4bb27a9bbff4f1845a734baa620595a66c97b64b43eb2c54f43e506cb8a7b759fb063f7c957155db10fc194171acbbe5eb47e024730a76c04d4525baeac5bef681bc3159bf0821c5b448e3a2c6bcaa55efa55e84e5084d257a0f7a97c322c8c1848fadc7a2f3db817816758220a5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b365132ebe95dc25a9ac3a1838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1d81755877c83b6511e10ce4d52440bd94c246579711150a33c62f42192e90a178f676ddb34a05401a151a4c167391d199211644238e8500bfb94adda266e23c0cc5f422a5c0719cc1a870e768c5fa95eba105e904a9875fcc58ff39375b72f84f12672386b690710b6b96c4aa17816a6a3fcf68e7b724ef4982c05799cb7a502b08b9ecde916b3e47636835c500360f24843c265b1d282a34f04ba6246b6ade8abbdfa13681542e77b17d398088b6243b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_private_key = 2a0ca3aa8c5b212426e4066cbf85c540177324559cb5e065a31aa5daa69448b5469b24587d6cc2a053abfd4588aa657894592c21aa88c3fcb7fc1a7f5032a786cb121e38b68ec0096e253f3caa94cc6a841867a582a77494dbacd97b8adc66299e54444a2b420303429aa55022c961f0d953d9967cdb9397e6631956e59259164e666cce7d40b98072973755408ff1303d29add7770d6b6cc40297648a66c1e7e253cfd631430baa4a701d8803bb834483eb198bea06aeea9a4c6487199bc5badc3526712282edb173b07830dc26bd796661bc677d73d4ae72a5575ee389bd2ace05561651999fe9326c9109a1726a0ea3354bac66794af387ff097e37b316d079c6f22c8932b8b02f33050d20c03770495636cee8a557add61e45a20702e1a2e04a854338af5fc4478be47271c99c24d79f4a38a560488b624ca0ec5991b141b3e62141c73a457ff5635923c7c7e3522dbc937ae5bfe962c297c1c6fed6bb1c4a7b66d2aefa71b272e74559381e04fa6d795143ab6789c06384b6d22a37da12c2a3ce92ea09b705a0ef61379b98a1714c71fb044f3427cc20110c421207a05cb36aa4477c86732d949b64ccbc8f841089c878491c47940ac61a5920eb23ca823c8f45332e4317bff016147145c299db4e8cea71d000850f113f12e0429f596df9cb4aba2329cae2734b3c4c0b2643f7612f473bc0069199e1f08cb03c2eb8e96d92e6305909be11acb29c399d4bf8b48f5cc47e8973b51454e67aa5578359ff19325efb7493382a41665ba1d168bb01c1577495aaea9ad377252b39402c598c60e2b376010c9711c595f81d652c5c39cc8857b949e51a8939f4548a1959dfa464020bbcf599089ac9058cdc1061aa34c78b16688231d98792ec23063712924581bea2a315841a6a49a09e8d47666a8427c811bb839745c83bae65b154c6463b98448bc638cac1064b03565f295495eb9ca032f778cfba4ade47a906379a457c6231c8ceb3fc42f9175dd50c38323c46b71395c114a3bd1044b6176dd58ac0beeab68dc1ad57f7abc6049a04bca06c9b0c95456b19f0a2b8022412463d20e4054a20774e234119411edbb3515e4c00a4987d491c37b3890db4ab249d28aef2c0cee1768c52b70cee7966b31c58ec975ef8b96dd2e156544a88a9772bfc834d422599b117968b648172b2ace7633ede1624b0a4cd031779040128c0e94332b03a798579206873b5583ca9c6be34632fddcc223a76c415e262ec8831fe32225ab2b484758728182eb45c851118cfc5086974403f6b161028534bc0390dc7d7902493440134c784b30289833652e96c58d12867cccd61713b51345c21c865976c0857808422f78de8b95472627cf6b895dd4065c68156bcd16e65494da75ac2e04668e0548e9658cb55d89bc8f98333e030a4720027aba862fb6f3b006f6be711b10b6d5e30b892708f42c49006357da4f637e8b3210e49817a9026b7403d64d861dc65955d75028e596fa68c97edf133d0997d84f342caab0f52db4b1330af6ca57b8b2423275255dc605fb9111907b648834c37ad812a300a715e231dba4551066051d31b82b6c3be14928c9cb78179e16ec0088cec140d3d6842776b30df33a11154a04ea7a6ade981b8c2995a37bd16734f98e95e1f753425f15c1a9b69ac4bb27a9bbff4f1845a734baa620595a66c97b64b43eb2c54f43e506cb8a7b759fb063f7c957155db10fc194171acbbe5eb47e024730a76c04d4525baeac5bef681bc3159bf0821c5b448e3a2c6bcaa55efa55e84e5084d257a0f7a97c322c8c1848fadc7a2f3db817816758220a5c7e67dce856362e8c7161a911f0b5b01089dd324848be5807bc67f4ae94b365132ebe95dc25a9ac3a1838897c0806891cccc4abdecc0cc87cc125a344cf83a5b43bae1d81755877c83b6511e10ce4d52440bd94c246579711150a33c62f42192e90a178f676ddb34a05401a151a4c167391d199211644238e8500bfb94adda266e23c0cc5f422a5c0719cc1a870e768c5fa95eba105e904a9875fcc58ff39375b72f84f12672386b690710b6b96c4aa17816a6a3fcf68e7b724ef4982c05799cb7a502b08b9ecde916b3e47636835c500360f24843c265b1d282a34f04ba6246b6ade8abbdfa13681542e77b17d398088b6243b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f20bb63b48b8cdd1c7242bd4f017c519b43502656e23817bfd683150488f8b0b44df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +expected_public_key = 6c10a1acf866163b55706133db1c41474a3ef0d4c7f131637d32b4803ac902fb5246c858a7426f9145cec60047473666a5e9c37b8ca4b5c1161dc5479341876aea6c515b564d68650b9822c6a817b5938f3809a784010278751d539b75ec07ba09aa34b08178ce5cb5bf70c99df201018b55e21c8a51b9a70be2997ac10b8a783cd9c54e69cb8b8a360d0dbcb9d6210933a5b7c5853af4b22364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a45181be8181ca2515d1394e7ef46ab68a1e93351a6da3684c8272c3e41547eb9e2e397a18f982e95730529c2affb88fef731978388791cb053906a57241cf99525fc87cae12e7360bb2a68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee3b231bc28bfe1534a24e15dbeb43fdb40238443a29d3685f3180d65658aea5b96078ba150623ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f19b1cd92177c4c2019789765790adb3d63c59719a292069922c5ab4b6b9ec2523ac919081764019282b16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e74e10196ec67de372878345213754af4d2affff085c970b6fd7ca06bfa60dbe526114bb854480d519a09bf5b6831f4b2238b99428538ff27c66777a49b4108fe3ccb4ad486f54a01e514266fd96a61fc2757facd39e071a0896e93036db4b110c8d78b586aafa5f182e1d05e17446f6158cd34427624a488fb4650c8883190f1b60374b0e8418a12866aa8000a7b2ca387b4b792c3719ae883a030150a668cdeeb6e8e59ad3e420361361a5a149c85880e245888192560052b490248b91a29adc0708344280b0b153bcbc0b575593245718b0180216d9a3847a186f312c169f42853820e862b90a4429f5d927a340589e193a5bfaa46f5350145ba2e6cd2727fc2545ee5bd74d4a38e181e527a80e2288444d860e7400b3ae3827a24042596124ad345e43a03ca310d37522dd962b71e8b3b1e3b29972934bf00015b6380617c8958303494d03366b6a51e7ccf6d3abdfb242ffb8367fe3a1d44ba87bda4587a9427dac62d280a0cb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_private_key = 54e04cedf980fa4114c9a285df546391e523d49009356878bb2c49c77462053a2ebdf802d253c694e11169f940295279e9638c126895762a5c0b6ba3c7d44c91b4543163c27bf9650c74cf472cba69f71908004540b83c7f081fb827c2cb4186160362bc0a71d602b41ce5395101b0235662d441429c964b28f4730af20a802529e046b662a72ecb206a18ab7f002b8a224007e312449ca5b9a01ac4d54cc00c1224bf8c0f6034ae9c8862d3c0a58357282a55a8133a95862b168266a9473c7abd0813e9b53fadb619a492a93d708a8db2a84f866edbb0cfe0b18dd8a0bd7281a7ec5079e952a5607c07e5db6fba1a010e28167b28b684bab4dd2b76ff4a227652bf2e448dcf86ba498518f983b0b048c166256aa5f38405db95c8e848df37bd971108ac782343026e473c435bb5a3573b866134996910a5b5d91d35281bc2f928d9144f954c4ff31c3523f80c8a9420e064073dd8a6a6f85c3f4b6245a1900bd15ec21801fdf88c87a105800127d5f1060b6676f7f2cdc717c9b35ba6e6c16f448926679c1006ba0013b2bc35c37fdab07e5db79253e9669af80a98277c65425925a059dccba3c0580e8e5a86ddc8ace81971cc5a06be7b9b8fb2cee4a1b5b614340db5314be2af85c06589f188f4d42738590736a381ce333a866b108cb88ae68803594903faa280532c37a0a4cf082b37dfa7c438d9386d029be2c6bdc3554c6d458d37f0930ac71df99b7468858c9e1a2561bbbc858bcdab73b82768503e946d48e65f3a1253e99c423480cef6979ac96c7b10cc6311375206a90ad4346590d69a3ee848a1c5287841c7d58b5db0b0749026387c93a29b7586a150ca803c3f36997fd523af0014a905e3baa92b92d0d34788d2530fe774e8071830c869e2417b39ecb6f0485ec7770f25e3ba22eacf5c180e665bc8096248ea0a881d59042ab55f7b1c8aa0f348675c5b4eb549dfb770af8633c0089eec5cb979646ae579a99d58554c1a0530a85631f12db116c7e4d2a89e2b42cda77b957962a1ea4b089b42d5fca0034529a4134702f06e989113c284ad2d131a99f592d3f7b50069746c10a1acf866163b55706133db1c41474a3ef0d4c7f131637d32b4803ac902fb5246c858a7426f9145cec60047473666a5e9c37b8ca4b5c1161dc5479341876aea6c515b564d68650b9822c6a817b5938f3809a784010278751d539b75ec07ba09aa34b08178ce5cb5bf70c99df201018b55e21c8a51b9a70be2997ac10b8a783cd9c54e69cb8b8a360d0dbcb9d6210933a5b7c5853af4b22364635526ecbe5774c5a6093c2fe9418a279c0e6ccb8706c6a45181be8181ca2515d1394e7ef46ab68a1e93351a6da3684c8272c3e41547eb9e2e397a18f982e95730529c2affb88fef731978388791cb053906a57241cf99525fc87cae12e7360bb2a68b936db9d55de3a885c3b74bf94c5153336444bb6b07fc3e36979ee3b231bc28bfe1534a24e15dbeb43fdb40238443a29d3685f3180d65658aea5b96078ba150623ae2c473b6b5a8f1c646a9c8848be5c2a8dac00d4949e66558124455f19b1cd92177c4c2019789765790adb3d63c59719a292069922c5ab4b6b9ec2523ac919081764019282b16e4ac4ef7530d7a94f7eab5f0ab4afe7b5139076e74e10196ec67de372878345213754af4d2affff085c970b6fd7ca06bfa60dbe526114bb854480d519a09bf5b6831f4b2238b99428538ff27c66777a49b4108fe3ccb4ad486f54a01e514266fd96a61fc2757facd39e071a0896e93036db4b110c8d78b586aafa5f182e1d05e17446f6158cd34427624a488fb4650c8883190f1b60374b0e8418a12866aa8000a7b2ca387b4b792c3719ae883a030150a668cdeeb6e8e59ad3e420361361a5a149c85880e245888192560052b490248b91a29adc0708344280b0b153bcbc0b575593245718b0180216d9a3847a186f312c169f42853820e862b90a4429f5d927a340589e193a5bfaa46f5350145ba2e6cd2727fc2545ee5bd74d4a38e181e527a80e2288444d860e7400b3ae3827a24042596124ad345e43a03ca310d37522dd962b71e8b3b1e3b29972934bf00015b6380617c8958303494d03366b6a51e7ccf6d3abdfb242ffb8367fe3a1d44ba87bda4587a9427dac62d280a0cb93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2d19bf7937eeab0d2a7570d43cf965547542a519be85bdd4921f7d710747ec6f0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +expected_public_key = 608a70da01862dd25b9717bcce38ac41045d44876aade7c1ed6a2aa638994db7011fd42b3d474b08f87b4b2a3b83ea94b4a21d214bc2c974a078b22598a7cd7895942ac29d876b9723f32fc3bb696b467bea64b176c1219732af5e21ab49b49fdb0bcf9152600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d380130aff7a0ba20a75f8a04238294a4191ebc900d255ba923056464f6621d2b96c493c2e5379a95d16f4b5a72e5c5ba3840517a28ab3d8a8c3b8c63e882ae37f4215a74bf62c54bcb65159f9ccd88e07933d4936f12c2ff174f84a1a93e1a9163d0cce3290324355c1d6b21ed458e2f5883a8806b2d65a5f85b3bc103a692c94333331671f54629e89b1be35c25746130d7a9b939cbe017170fec7d5675b3bba33e4e086d4c6625580536d0c28ab5e073e5f37cad826173cb422f60bc11208fd0023395603d8d047fa57cabacb428d2f361a13321bc20827d5566dba65bbd827a2f952a065ca19fc208f4617e0bc9bb97e82f4322413d7317c14866bc72242134c38a7774d1580485fa4e3905122ea993b03b12a1f6323ab778fce157e3450eb02357a71c3caf9571fb83718748b2adc18296f570b05c4a77502062841ad216389b3b3b71c0aaca94a7051b0b523504209566bc153b3206b822779a98f59842442cd2b5246c674105b450f8e385d1585e651c934c4312d3208f7740a6f8a47e3393221c40747e452e1b0b7918b64d6c018a130416fd32c20ff641ddf25bec731f9bc9a36da09c1f5a058440b920694b2e9437bf23c1bc80835447a33f40a8dcbca09a14cc83d44b20da529b303d74932cd2761d27f5027fd01f93e907bd0538898078f57395ee2972642097944c19ccbcb4cfbaa79289ae31a230c67218b3c7075ff32563089a1e65aab279c3e4d9c07deba0f72a796f601382385568275c8aa6b26a8caffbb09e44409d1c404b6fd957a967a17c83cdbcab30d299a623d4b0da14a1971a09bc83a59f56a05bc6727d91572bac8fe834105616b5ef3c3e0cc2998f5006efb3673f4471b6e9005957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_private_key = cc781ef0e49bc86b3f35c4645edb42a0a37a17501f80367cca61c8e6b9715f2536a9c27edee33407a159cc1a59cba30e3d79a058c97e30e36dd4553353b057afd87e4112223e38368988256b9c6a1a2214c24b1ac0aa88391b712270607a284862b192a38c2bd62a7a64d3cd1a9bb88d03138c88880817c11105c761c7cd0fa53a2624307df5ab95b2cbe6d87a6278849bfab67c95abb0ec9c58f33be488bf4e963589fa1263d4ccb0606e7d88911c82791a91c90c674af04576e3e31405708fbfca2bf317ad03c187492a6fbf498a66389c9f5469e450c094530324db1cde5b15fea74c9cb7382aeb76405950648255aea13160e41b00bd05e4921ebaecbb23b6a87cc96d3ea8bba500903a44b8a085c97f4820fe502beb69cd71f58c6a9b7089d4bacddcce28d0b63b04b7e33b44b6cb1623e64141fac4b6d573d222a28ba8c02053515504269c501091536d598336b6391148b460a9407b2fe7ad8c439649a9a17e5554bce7a4673b7a0f048f11104bc5b5c0d1210a898502335ca8ce1c2ed6ba29c59189e6c7ca0077343ffc9e213c8f08a5241ee7a43492386409b72a6a8fd01b81836b794e82a7e4031623c977c5b3a665d05d497abb466b73ef05847cba6c7dd9554ae237f7fb92ae70cc273b44436c0070928116b065577a0acc3255956a84b7e64b9935779147819230721840515d073f2c91722d3b9c76a7ad8ecc7bef809aebdb7ab24ac9782c1caa01b8871b01878039173a9c75c27841872d5538a990b530cda7ab670742f9ea32b8289dfa832cc528260688c645f43a7b81601bd68ed2f6a4f5a61a90968329103caef59f80a9c430064bcda9c7d4710f82fc646cda3454893def63c8b3f11cb006580a8a955d5a55d0387ad9c5051cdb8e9a03520b5a7ae0cc5b63a368f6342587144165d08df4a29455b11e6293a638102c0f0836517b15f6b726b5ea8dfc354d84bcc8c3c965dc3788682a411f904d5edb6a25cb4273214ca26c2a8b787fe468463ea0120798b8c5b78d7f3561ecf59aa81ba0503a2f4e777a4dc2ad49bb29edd64cdbe5ab083905d0a19f347c789b08b2608a70da01862dd25b9717bcce38ac41045d44876aade7c1ed6a2aa638994db7011fd42b3d474b08f87b4b2a3b83ea94b4a21d214bc2c974a078b22598a7cd7895942ac29d876b9723f32fc3bb696b467bea64b176c1219732af5e21ab49b49fdb0bcf9152600a1a50b863b591376be4653dfd93b360b853cbe8b8d1e84c1c85460bea5d380130aff7a0ba20a75f8a04238294a4191ebc900d255ba923056464f6621d2b96c493c2e5379a95d16f4b5a72e5c5ba3840517a28ab3d8a8c3b8c63e882ae37f4215a74bf62c54bcb65159f9ccd88e07933d4936f12c2ff174f84a1a93e1a9163d0cce3290324355c1d6b21ed458e2f5883a8806b2d65a5f85b3bc103a692c94333331671f54629e89b1be35c25746130d7a9b939cbe017170fec7d5675b3bba33e4e086d4c6625580536d0c28ab5e073e5f37cad826173cb422f60bc11208fd0023395603d8d047fa57cabacb428d2f361a13321bc20827d5566dba65bbd827a2f952a065ca19fc208f4617e0bc9bb97e82f4322413d7317c14866bc72242134c38a7774d1580485fa4e3905122ea993b03b12a1f6323ab778fce157e3450eb02357a71c3caf9571fb83718748b2adc18296f570b05c4a77502062841ad216389b3b3b71c0aaca94a7051b0b523504209566bc153b3206b822779a98f59842442cd2b5246c674105b450f8e385d1585e651c934c4312d3208f7740a6f8a47e3393221c40747e452e1b0b7918b64d6c018a130416fd32c20ff641ddf25bec731f9bc9a36da09c1f5a058440b920694b2e9437bf23c1bc80835447a33f40a8dcbca09a14cc83d44b20da529b303d74932cd2761d27f5027fd01f93e907bd0538898078f57395ee2972642097944c19ccbcb4cfbaa79289ae31a230c67218b3c7075ff32563089a1e65aab279c3e4d9c07deba0f72a796f601382385568275c8aa6b26a8caffbb09e44409d1c404b6fd957a967a17c83cdbcab30d299a623d4b0da14a1971a09bc83a59f56a05bc6727d91572bac8fe834105616b5ef3c3e0cc2998f5006efb3673f4471b6e9005957590b749c107a513e07ac15133976c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd6907e1096410ab332e10f37c93d86d9b4657159eac1faffcd1688d182d1278444f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +expected_public_key = 055323ba95c83ac687a58a7f92701e7c388a4dcbcc611aaf6399522960a44d316b77734f025218e3c2b201b0816cbacd5b9b303297b0361b23d531a77dc965ee89694288460844259a735cf0c4c0add2457c5724fdfa1ef4546e5ef7c2363760ad478aa7806df9e35f0e46ca8dd643c36c6c9ee3b564181893b1b3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f5631102aad2b901d5a7675d541dcfe35e92239776a81e758c1c54e00d380232d5849102117d54144a20247017148584c1038a9329b9ca5c1dd337c1f758f558628c6962eaf49abab214279138db549c04f87bf243bcab3757f75b95c1f08685f20cde8c6d1a353fbdb3abc0599948ebc82e2434aca485d191287bca1678d2ca75497d73296177009bd384a9a5d0ac8b6102760261852b63d0520fe82b9307d1ae2b8c38bc1054c0295f7ae2321dfc82417849a3bba7467232830c35c08038ce2c4562b7a89171864e566121f6278a0b777e02bc50029718709af63a7014d8b9f79627f61b457a25c202a6cdd6f9a59fcc3cda84a1a43620b1394fa65841162638342a24671a6a71e092a7a19866ab7519e723d6ecb836998af8724efcd2941a5bc225f9acf8468b5c68a781b664e3614fee782c20e80cc8f27d1f455397509c86067979d7407b1bb536408c654c624adc0cc126bd3ea29c33f897e168c9c715887474cf1479450b80659f816a7e1999a8f2008cc9cc732a35c8d3b290988dfa31a80fbc1a18a58263c7bf18dc0498260e66fcc6b991b4e91ace50240e7a2a4563460d016314c404b269fa9a8d1b0c074545feb288208b790de67dc3c787a12b0041c52f80ec9f6a96733d874e986a3e06b72cc4b2ad2460b7aa2141f3b186525aa6b6d2901d46ae2f5c7a195c55a48934b4478974370a982414d9a160a8c45aba043dc597a2d2a4acec6708a3ba881c925c215a8063fb80f0114a94c63a1971249368b772a662ac38856c79c7b726884cf5a014527da479c1d7747b4d74cf33f30612b70d1e0c2faea53ea1164bf9733935d51542ba3a47b099fc82cb8ec391a1361c19484f1bd52dc2315e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_private_key = 9b828ac37baa3ee2be76b5408e60cab8e684e1c16df00c78cfd4700110051efca6161789887899bc71408e32587b52cae8570f9a0c017773b1de06aefa38b980caa7ca23c4534a87bc8b2bf24233df526cf57c7b9ad2b1db465d8529c4855589e9e58f8d52293aea2edf630fbc9968aaf08fbd539849e3912edb91b1184ef56827e104004ca05e75a6c90a4523b39883b66b653dac0ddea5383395498e0b96110c5d62ac3ea60512ca03670dfb89901c089d4c59fa95b6a5911ed4bc0008fbb58f1c0705f152c5846e753482a5f677dd7980ac7a3ea339b1c9112aeaa283b009c466454c8c892b7f8a4be7bb23e057c36e837f67058fc01bae81c259b605a02153ab7874259d7bc593574ace70a22492401e2aab8780ab893a820e33779b9285e0b60a018b3efa88583c76881a1c7277f585d82623c650565e55cdd4708415585abec0bbdb7c8f694b1e998382ea1932a7d9c8fad682d9c62063eccc63cc69f7a7a64505221b2194f24a79f1a10d7a26a1859179bdd45c44d9b04206119ca6ae64b97f4865561a0580941c90acc237e3d3427eeaa15578b6bdc8741ca9a46fea9ea0754208779e9a748a1a648cfc802fb2c1740444a6dfcca13b450c6fe8848eb2370261a1d0bbc39f16320ed4abb7a65ec2ec4ad0838310642f4f752808b3225f112b8e279196107db2407192ec084c5b4010481abcea227ec49f63bace46b67a123a3664fb8df7bacdc8fa44f8c99dca57957b446fb6c871fa64221b3a81c6002208553bcc7a2d89ac403008b1bcb344a2bac20dd166f46212059c429292a36221b6ca51645719002dfa047db11ce9c7a6e26aa77333ae1ee33d8490487f3718f8046a03740aa028871370b0f246cf227c7318558b9241190dca2b6e720e8fc98abd603f77c1a7597c49c3651dbc05540b59bff7912184593c78755421b58ff6c84f1cb173a27baeac109245260f35f14f9f2c2bd694af6146a95e7abec6198344d281b9603a32e45d1a4b359208beee62a60b67288d8663511071fabb6716867f388507a1aaa70d268458504614969c9022a920b45354a89700145941e7a1055323ba95c83ac687a58a7f92701e7c388a4dcbcc611aaf6399522960a44d316b77734f025218e3c2b201b0816cbacd5b9b303297b0361b23d531a77dc965ee89694288460844259a735cf0c4c0add2457c5724fdfa1ef4546e5ef7c2363760ad478aa7806df9e35f0e46ca8dd643c36c6c9ee3b564181893b1b3ea1b7f74c675e99bbc6fcc96d3fa677b23378a3b76d1f5631102aad2b901d5a7675d541dcfe35e92239776a81e758c1c54e00d380232d5849102117d54144a20247017148584c1038a9329b9ca5c1dd337c1f758f558628c6962eaf49abab214279138db549c04f87bf243bcab3757f75b95c1f08685f20cde8c6d1a353fbdb3abc0599948ebc82e2434aca485d191287bca1678d2ca75497d73296177009bd384a9a5d0ac8b6102760261852b63d0520fe82b9307d1ae2b8c38bc1054c0295f7ae2321dfc82417849a3bba7467232830c35c08038ce2c4562b7a89171864e566121f6278a0b777e02bc50029718709af63a7014d8b9f79627f61b457a25c202a6cdd6f9a59fcc3cda84a1a43620b1394fa65841162638342a24671a6a71e092a7a19866ab7519e723d6ecb836998af8724efcd2941a5bc225f9acf8468b5c68a781b664e3614fee782c20e80cc8f27d1f455397509c86067979d7407b1bb536408c654c624adc0cc126bd3ea29c33f897e168c9c715887474cf1479450b80659f816a7e1999a8f2008cc9cc732a35c8d3b290988dfa31a80fbc1a18a58263c7bf18dc0498260e66fcc6b991b4e91ace50240e7a2a4563460d016314c404b269fa9a8d1b0c074545feb288208b790de67dc3c787a12b0041c52f80ec9f6a96733d874e986a3e06b72cc4b2ad2460b7aa2141f3b186525aa6b6d2901d46ae2f5c7a195c55a48934b4478974370a982414d9a160a8c45aba043dc597a2d2a4acec6708a3ba881c925c215a8063fb80f0114a94c63a1971249368b772a662ac38856c79c7b726884cf5a014527da479c1d7747b4d74cf33f30612b70d1e0c2faea53ea1164bf9733935d51542ba3a47b099fc82cb8ec391a1361c19484f1bd52dc2315e1ffac169c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c379c9176059f3a7ddfe021041301bcebbc91e997a0d5bf2ed1d9d125a71298341c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +expected_public_key = 7f010097591e75470eb931b90d0a7bb708c1b5e97fca41b6161ab4c1cc9ab3cca4ef8804c76c45c44c4bfba29d978014e36195cfcb04ce7487994261638a779fc540b6d0286849b7cf51b8b648ad792bb225b42b637693f967c21758cdaa71134cc68d8bd7198b2a971071373f772f7044b912775652d1b78a9c18c7f00a86526b134aa656801b507714ab6a37fc57051df46a4ffc2899411eb6083df07a9e59c2c55d626d0bd04425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e0a1f9d9416e2b2ca22cb20f8f4ce3080aded2262d885780c9c4f171685b466a5db14bface3cfbd979895586a5f1a2bbb7626e567075c004b92301bb60b0e3208882329cb7de807a38656f98abd1a326ded150401035c816b9e7e677a29849caa7227d57b7969541e11f601526a15631c75f6e9be24d54773f906f394643ae31161898530344c07693c4edc042ae805b92157b6637722146f16f49297370a074962edca884a2cb091568e70e3a57ef2aff79b17ba6226b396a5702673704b01d7959c180513e0ab03a421425274ca53774557a8ba060817b62b8abb20596eaa16810513885435486bbb5fb83c7a9969ac593881173377b1b79ef4b7f20b0b6ea325826667fba3c4e31227cd858578bb771c27abed688844b95a4906c290596ec7b14dca4a60cf8bce7d12545833803351a0266384ddc2673048aa660b9a8db520d37ca59ea19cc6f19eb9e63d6e842076b397f5027ffee9672e91ba1bb50f0ce37410c686e9952d86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637e227c963029e7935814fa0b11c4b0e695aafbc75dc2e90d8c63740c8875601008b8959ff214b513d42056f78457b45e47285440306d15e3607a130a4d6b2bc0904c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382624c07c4f26fb449a412c37b73037131c81af9084eabc16b50956ed9daaee0f4153da0c959c40f78366867e11378d2bccae21762b543d8b2ce2d7ca79cb7ae2d06544982728a7a2ce39ab54df83521312d942c26f618ae5491bea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_private_key = f2dc1b40867ecca65895960fffc60469d809a85cbb383886b9d037785345d57936dd7ab93ae0504df32d8438662f050720262592902489f9a90233cb20a5492bfaae4b444ad1d8c84c0a37f6c928b8a89c22a326835073b978a200212c5b000334bc936fb3c8f2626c862c52025a73425a0e16f40d2d87556440659ab53d6db763b7f19a00ed6a99017a5677b62b141abd908a51672a65e31493659762a04795f80f254ca4d3683cee608df6c79a70994fde528775a991bfa1035eb1bcb6da3c63432bf958790a81620a614e3a330c1dc658e7398739b75e1437451d21368c798009178a830c19b621802d848918ab34440175c825232e70637527c2e276ba02aba363f082142c9e4cca09515c801ec78ac7ac68669c2a054cba8008603f9a3368793c0bb73462182977d202df4abeede70921110ce8e6108b784a2be9b4410876b14a097d50bd8cb933ab160860950656f006a0786f1894736c7c694e8a81a301b28b9a43be14352661a1ecd11104fc52db91c1e9f85f1bfb20ccc971f2ba8505890dddc3118ee98cb2459cb2e003de4b3d4edb74c934056f4a824b721e37d247142bbefe25acd52b3122519fee154d9c098525839d9e8593d3a5b2ddf91be4286a4ff470d45b55f5f75db92b8adc626390698bd780977ff5902e206669e092ecd5002f43801bcc14e75553ddd5a122ea24bfc1b799a727f5362ff90c99b035b3b2c545e985860bf8c1fa517d348a88bf85690e911192a643de17b25363686f6a3f7d643cac6b536c8b536ab84e3e6b1200dc7f71a989d04098ba39cc15d2776d50b391522e4ba60916625941594f76d7469589085fe45793529924d6bcea397fafe8a963311581429f194a76d627583b51675db41bf42650dd44c598c1aafc177dffbbc6bea8bdc76c143f82b032f45eeb770231e8b85c8744ba9507f7dc00b0d05772b927c09cbe92a05c80987080a69d560094b3b021c38a323622c362fa0809259df6cb8138d9774af279d4882e4334aeb7a9b1ec82648d407490d168a95c769869a8e6521156867b1db3ca7559ad74574ed6c61b5260b7eabc54b3384d7f010097591e75470eb931b90d0a7bb708c1b5e97fca41b6161ab4c1cc9ab3cca4ef8804c76c45c44c4bfba29d978014e36195cfcb04ce7487994261638a779fc540b6d0286849b7cf51b8b648ad792bb225b42b637693f967c21758cdaa71134cc68d8bd7198b2a971071373f772f7044b912775652d1b78a9c18c7f00a86526b134aa656801b507714ab6a37fc57051df46a4ffc2899411eb6083df07a9e59c2c55d626d0bd04425583317ca5c7ab86a6c3867786aa2a69cc8e114637404bc4e0a1f9d9416e2b2ca22cb20f8f4ce3080aded2262d885780c9c4f171685b466a5db14bface3cfbd979895586a5f1a2bbb7626e567075c004b92301bb60b0e3208882329cb7de807a38656f98abd1a326ded150401035c816b9e7e677a29849caa7227d57b7969541e11f601526a15631c75f6e9be24d54773f906f394643ae31161898530344c07693c4edc042ae805b92157b6637722146f16f49297370a074962edca884a2cb091568e70e3a57ef2aff79b17ba6226b396a5702673704b01d7959c180513e0ab03a421425274ca53774557a8ba060817b62b8abb20596eaa16810513885435486bbb5fb83c7a9969ac593881173377b1b79ef4b7f20b0b6ea325826667fba3c4e31227cd858578bb771c27abed688844b95a4906c290596ec7b14dca4a60cf8bce7d12545833803351a0266384ddc2673048aa660b9a8db520d37ca59ea19cc6f19eb9e63d6e842076b397f5027ffee9672e91ba1bb50f0ce37410c686e9952d86f4752fa650ca2c30a03cac426830cdf4b5745a40bbf53781abb1a2c3637e227c963029e7935814fa0b11c4b0e695aafbc75dc2e90d8c63740c8875601008b8959ff214b513d42056f78457b45e47285440306d15e3607a130a4d6b2bc0904c6bc35e4b99b55f443d9cab423dcc46460b973963cdc92382624c07c4f26fb449a412c37b73037131c81af9084eabc16b50956ed9daaee0f4153da0c959c40f78366867e11378d2bccae21762b543d8b2ce2d7ca79cb7ae2d06544982728a7a2ce39ab54df83521312d942c26f618ae5491bea73556eb297fbda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249fff5515b23187af5dac6d1d090bc7bc01df34ec781561e3d3b8b62164f749468026590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = 89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +expected_public_key = 412ac5007438690416fad3acf0bbb1642132613200006b4a502975fee79d2b7aaa8ae2745e16c0a666c8a3a24a990cc4646c8bd9e6744d6245fad4b2acc58b0001a7a351b61debc0cdf85b5b5a188d040d0994027f8131d9706aab35763e4aa232554cebd44886a70a7a846e67c3842e96a3df7233112271ba001105e2a35b5689378c108ef44f8ff858435b7fa1b1376f4c5276a4002732b81974c79ad23143d8134fbbb2426c9baf566b777803a354c5afe8a1b840ca5819a3d612752d047207181bb6c049f70656c22589d1fb5d5b9506f432b52dc933d0e816b180681d7743aca5259f92b8b2309286b680d174b267c5bb01e38224763a26db0b36520477591b0707b09e97ac78fa71e43154afd39266217067fb6271fb4c16c71e277a0ade710562ec287b7493e4fb453c098e5d991fda9abf9e9a29e7b28e0cabb4be5c8a3f490265f5cc93a0b3a52881ad806f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6c7053a48a5168934f0f2341bd263648291078554692815e1b69b1fa97031af13901c4a90546396af914f1dc6d09f58c4af89474ec34614535a6dac8d0301f67339baa610cd5d9c2ac832c54a55175567a5565c478cc5fde74bf2614c6815152e83a615de8ca9ed465a05507b9218ad6f7b9b2799e2ae040084287c19573ad0200c8e683d138ad4e8804eba5729aa81c1e1a9ad034a352c156e9ab635e849f65a37ecba8c0009843016266d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b461cdeb83b637196d757999523097a00920d0677ad5c23906a3fc9054f1a3176d5759d39a03e591bc10a7cc7e05397af2c0f60e84de24318423c0470b82acbe97f3a9889c2f45418ca28fdb092ac703a6a9bafdf6b0d05182dbf9a55dd3397de5a9b0d7c4950653652c035addb2ed3abbce4e755d2519e881266d28524c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c7811966b7e202395d4a46d81b0b3c2d3950fca0cdd208cf462b688919b79366381a11a6e195cf234cbf10724d4c3b9bdfb0816160215bc6d5102689a21af235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_private_key = 8416677d2606e578c24f59b59138c6cb1144c6311541839bf79066650180799862d0049ff1fa13d0b2c1b4227d2e673c9cf09af164b7fe7ab10b1928aa910f5e81401920cbd4c8bae6a71fa3f783bf8616a2eb7dbebca74ec94514c9a99a16b75c41a059f437e7cc3febabaac6918ac41b40f3b8bb287009e2c29a4fa586ed8400742b7c05b252210282f7959a72c2b9921ba415b5b2b78106d7c464e0a01c229046d05abf7a611bb48b07835a461264c0bb5770906812a60253570505af040338445ea2e072844445cf1050ffdc7f29f228c66a4a402b98db0c497bba0ecb68cd93b542e8bb6b40393d73e7ac51d093c5c15ef9d4a7a8d056259c06977ba75f4cbf5caa86f5568c422c1424d123721ca09792c16f948d7b84b758375e93b156466b8f0202c7bad31decb489dc0cca1c0788887c0d57f3808e16634b061d5aca96f96b9653827387651271eb05d5320230293b39747e001bb875728d2f2a4fde26981de26c68d542496a92f5871aa7438452073653d14cef0b2b6d380daa531874b26370026ea59884d47528877aafd444a7ef16c03dc780bb938f5fc94cecb5892bda259c9a625e68b89e374b6d134c3291168cb05065953c851aa1e5458e151a3b49f47894e646311575691342552a27116399b3e441d7524b9a923d616a4d9837b05301c1467991fb81492292b5a7dc2e13e44a83265aff2aa03c6465ed1c1ab1681bf0346aff84bc61e5cf3da10525c4ab56a85a053469ae73bbcc77c28decbef6007edd003cd7594b9a30ba6c18617fe15ec8d549530c3f7978ace489b4a9c0864e175680a7c8bff43e7175b393a2432126c945755979b36bf9ac10d806150ba38280a1c7299a64a085ca55b49cb723a9b0ba1009965a0ec66a7e6341b2a5c89a1a0ae6a3a2098319200bb06f52be404890f7eb66e9367ef0a5a92f526ea9e8b43f60bfd80091b4525184c223554023d7e698ec144d1acc6d1f194b73184267a03b6bc43b42a07bd9a5cac4388eb4a2323b723152e6a4f617a0649c469b839b555cb56329186e675b929c8dc4c83977b32967227bb7f971de607ad49579412ac5007438690416fad3acf0bbb1642132613200006b4a502975fee79d2b7aaa8ae2745e16c0a666c8a3a24a990cc4646c8bd9e6744d6245fad4b2acc58b0001a7a351b61debc0cdf85b5b5a188d040d0994027f8131d9706aab35763e4aa232554cebd44886a70a7a846e67c3842e96a3df7233112271ba001105e2a35b5689378c108ef44f8ff858435b7fa1b1376f4c5276a4002732b81974c79ad23143d8134fbbb2426c9baf566b777803a354c5afe8a1b840ca5819a3d612752d047207181bb6c049f70656c22589d1fb5d5b9506f432b52dc933d0e816b180681d7743aca5259f92b8b2309286b680d174b267c5bb01e38224763a26db0b36520477591b0707b09e97ac78fa71e43154afd39266217067fb6271fb4c16c71e277a0ade710562ec287b7493e4fb453c098e5d991fda9abf9e9a29e7b28e0cabb4be5c8a3f490265f5cc93a0b3a52881ad806f4b58913aa67340496c73f3656c7586d4b3a3ad06a0a3fc5e6c7053a48a5168934f0f2341bd263648291078554692815e1b69b1fa97031af13901c4a90546396af914f1dc6d09f58c4af89474ec34614535a6dac8d0301f67339baa610cd5d9c2ac832c54a55175567a5565c478cc5fde74bf2614c6815152e83a615de8ca9ed465a05507b9218ad6f7b9b2799e2ae040084287c19573ad0200c8e683d138ad4e8804eba5729aa81c1e1a9ad034a352c156e9ab635e849f65a37ecba8c0009843016266d0e4a2bdd7b23fdb638c79c73e7b51fc6c72d5b68c9b461cdeb83b637196d757999523097a00920d0677ad5c23906a3fc9054f1a3176d5759d39a03e591bc10a7cc7e05397af2c0f60e84de24318423c0470b82acbe97f3a9889c2f45418ca28fdb092ac703a6a9bafdf6b0d05182dbf9a55dd3397de5a9b0d7c4950653652c035addb2ed3abbce4e755d2519e881266d28524c2736b5426ba55665bafd66ca2875c1a96bb759ace54dc4986e6b76c7811966b7e202395d4a46d81b0b3c2d3950fca0cdd208cf462b688919b79366381a11a6e195cf234cbf10724d4c3b9bdfb0816160215bc6d5102689a21af235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb9dc0d69094efe63d751e6f9c1e92d2107a7b45fabb820222d30b11595c351643b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +expected_public_key = 54342021507ce3543789ba78abe30d6241382c6292e084319a4aba75374c0f6617bb0a92ebb52e66d790b9106553d5c2931a9534801d37551d9e7a854b9733be2b0dc6b86390886a6330b159f96dd3339ca12a206c3278603a123ac0c1e8a982933b0b29b5671a291ae67c08c7945e71891eeef048dab9370a72865c0b47c2c5b90d134132bcc48d4bb6994b2d6e1567409467bb21868bf17eb4c23184fa9eda3bb6e2187d7e9b7d503a47ab1c2d0837ba25a108805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8a612402091349e0cc0d142e9e763adee2af2d998e8e686fcd76c03b069a558605f572b359fc4bc7b0346d11c1e6f9ad71d1399eb992b9e54268ea8ec5e9af804290a19732cdca883b5062fe1a878b1696eaa0340f071e2c9206d39284d6b2499bf0a7faf99f5f8a6b77499419dcbdeb6725e776a0335286234a84474c54f952b6ae075af4729a277381a94414e8e6ae2a9bcd2e01517b99b299f3aae1ac965c086e59bc6d32a02a26b911be148c7e48385777b841d917c34c8842c9c90ea431b2f8cd71a78a15f185f77cce76959ec1748c44e5aefb140e752c97c5aaab8e936e84b5c89b3080480a4b8be81fb46b12049c6bd67c74fb9095fd95c971a2c813f08b55d9c867aa61783896707a36fcfb175a64013b071447469e768a7a1ac43fb77649802522ff880e59b322f85b919b2424650914d529ac7a147586279f1206338a67c02109194eb493d4b9ce33bab709c333a91079a542bf0d717f1c875d54f11d7fe72abc346000452fbb9178b7c87fc437129797cf38467296889d3e225dca6068583921c9767050f51246900af6689227e709c91727bf41483915b93b3225454979c0ca7b3a2c63a0521a5679caf5c26d5944186f43463aa419b4a660f2414a535b9236868c2c091616fa6522bb859fa61503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1d700ac825c501c986ed28bedac0604b40a0b4f8990597681390b2656857ac712d7d4ab4ce85673fa69c404b0b5410a531f0a6258336d2bb639f9230c16c9a85e363f9c355f8f00fdf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_private_key = eaebac1f43968fdc3e0f190ffd117773187bf7bc1d0978ad917b84f3cb8232e364456ca6574b004f8831a5972d7fa38b90436a7a773a9fcc83b8dacbacfb57c2323816f26b659a666711588ad7ccb3a1cf7e5c4592684d78fc4b3053467c28943605774b039fac98bbc1f07ae1f192962bbac65226316bcc1dc518aea752963c5d272030458b7880364138850da38c71cd8cb6454b13f9ac8aa4d508155701ee1a643251411825b68312225623be92f379006109b02cc93782a3951465ff49a36918bf4aac8328268c9db387d7936ee37aa896a50ceed6be31a59d1f415e2c6053fc9b8500597dbcb7a0d00b011ad844e37b67e52c9d2684352cf837ce732b7708386b3bbbdce3b52762627baa846ce93b13b8bd655143e6cc7680a864cbc59a64797a9897914a99ca40d4702d35c9c1c22e9804871e4c245e12bc5499c8bcf28ab37a6202f99b6bd3b64ac49c0ff74538ab11ea7194b92258fb2078c1705dd643b0539728068625d21650ed102247f1605b051ead06c00f271f68dbced3014f0026904256a4aec6041b748e6146a59b06c7e2bba5782681e4416abeeab61fc60cc68c53a501412ad07a721ab1002cc2428a1dd0b48c0e53325bf6ceddd2331df849a1939097a578add64352849afb2070c68b596d4573d09060013bbe3cb4a426e3b58414a108c37f5df6091a560e997263a013455257a24becb585307f7d7b6565a8781e33551bf26dcdb9caf2b02841d97744d71bfd3a3be87162ef6570a1caa1a6920ecba83b000242912b7986f7913b418fdcd199b66a015aac03a602767f212aa367bc4f886adf34a1f694a305627113f6074b6737fd2889ff4411605b2df3a7cfaf6ac1be726a0df282ece479abfa02baec549fa98d0c6331c3e26fe9c94d83277b4a08556b9813d4c6b080818fd07244646631671252e52cc5335aa32db09f37e8628f781256d811e84b989dd9b6df174526c9c1fce39168ac20458908a09363ea961d019c9aeca9cd2cb60fcb0c3190a401bfb139583b8c3629caf80432e71a7b657bc7ad2b3725708bc5666be813674068a8079a8a4c471b0ff98354342021507ce3543789ba78abe30d6241382c6292e084319a4aba75374c0f6617bb0a92ebb52e66d790b9106553d5c2931a9534801d37551d9e7a854b9733be2b0dc6b86390886a6330b159f96dd3339ca12a206c3278603a123ac0c1e8a982933b0b29b5671a291ae67c08c7945e71891eeef048dab9370a72865c0b47c2c5b90d134132bcc48d4bb6994b2d6e1567409467bb21868bf17eb4c23184fa9eda3bb6e2187d7e9b7d503a47ab1c2d0837ba25a108805ac4cca86d308b4979f7868788958d3c57089b5a48784b8367ba8a612402091349e0cc0d142e9e763adee2af2d998e8e686fcd76c03b069a558605f572b359fc4bc7b0346d11c1e6f9ad71d1399eb992b9e54268ea8ec5e9af804290a19732cdca883b5062fe1a878b1696eaa0340f071e2c9206d39284d6b2499bf0a7faf99f5f8a6b77499419dcbdeb6725e776a0335286234a84474c54f952b6ae075af4729a277381a94414e8e6ae2a9bcd2e01517b99b299f3aae1ac965c086e59bc6d32a02a26b911be148c7e48385777b841d917c34c8842c9c90ea431b2f8cd71a78a15f185f77cce76959ec1748c44e5aefb140e752c97c5aaab8e936e84b5c89b3080480a4b8be81fb46b12049c6bd67c74fb9095fd95c971a2c813f08b55d9c867aa61783896707a36fcfb175a64013b071447469e768a7a1ac43fb77649802522ff880e59b322f85b919b2424650914d529ac7a147586279f1206338a67c02109194eb493d4b9ce33bab709c333a91079a542bf0d717f1c875d54f11d7fe72abc346000452fbb9178b7c87fc437129797cf38467296889d3e225dca6068583921c9767050f51246900af6689227e709c91727bf41483915b93b3225454979c0ca7b3a2c63a0521a5679caf5c26d5944186f43463aa419b4a660f2414a535b9236868c2c091616fa6522bb859fa61503d4a7ff997b8a3b8920f562d384a7e6c9423daa5d1d700ac825c501c986ed28bedac0604b40a0b4f8990597681390b2656857ac712d7d4ab4ce85673fa69c404b0b5410a531f0a6258336d2bb639f9230c16c9a85e363f9c355f8f00fdf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f64816829a8aa9f8c4e949d4e6388448c2c4ec6a977f8c5fb80bd75d93a723bc9bbe76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +expected_public_key = 3fec7c38a86bfa490bbb6b001c129707b1b765416401290a94dc8e2cab1503dc4cbb2a51bda96c5828397d406386353a75157b09f1776ed5347f3a32fe6b2599827f83ebacba251dedb3c3e514b7add849ac5c40e49b1297634fdb8a6c0d9748a8fc9e98778668bc4446c1444b104db4da7ae5fb5db088cd34017ea6926dd2128e9b39419cb13ef8511705844d4efcca1219453f987cd5d0b532c6b958b202938a90ce9016792035577a4b59ecbe063a8a158b92e89aad62ea507520bab2596ef18778590708dcc62bec78a74715ac69bab4521949e8c0bf914b5304a7384ad25e79c3244e581033841ee8628ad68842f320584068cdfd91467c1051d1a8ae77e4b418343743f0a64635ac313cb722f61d0a672645413e5e92853f06aab35a067eabbf6774a291945e9157255af4008a123a25778d57308328a983c0dc8b4f21c7dd34721db734967a706ffa75e0b052f67c36168ab46c485b1190a6ffb60f4eb739c232b2eef630a00469bd011bc1eacaa9ca60c613039439cfd4ecbef6d7523926ad88b8581e619b02a182b76993b26b3784799a7a314b38bb6a17529650c7a0a556c3dabb0fc44ab8eabc2af522207e90c7c7e113fb7220cac24f45dac26d1605a70c16d1f58b6f766c8d07c56f582c88f6402fcab763f996b164047daaa7cf5048eb51297c50c44d95a664583579f18639772325ca12fae19205742e72803fa4b9991517442be7cab72996ebc50018963f89a5af785c354f7a94241051c80bcd0d9c7f8b09ccad58c0ba22820e859c9a261c6d41a6c310b310a480d0c8950fe1383727b0863ab758b2c551bc99cbaa90f0365961f7727f639183fc652bc4a2782081dc69571b298affc7af09c349124601602bac8c79afeda8531423642ed20075a9b176a75d422740c0c20fa87aad22eccb98d4bfbbf52e7b590aceb660e3982ed3f3cd328cbb6103af5be626b5036ec8460ba1fb8df516b315e1267ba1bc5770402082bd1100ba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620ddb15151b9c67a9c57aa678e7e83b3ab4196b682f20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_private_key = c3aa38df508762bcae32850e90e2cef9404bb2405b1c7322114cb440c507f27544a8e65bf08a4e19988feaf3ad91546e95a2a690ca99f54a803794578edbc9b9b955784ac9b0d9207487a2a86baf45b04da2894fe2508c06e49d2c487b87d9adf3f67ee5435f164510052974add5a26fb227b8f029de714e9c39bcad318b2102a04d03c1bd1719a87279f589401db284dc8189d48c897df69da478c5e5763968929a3771c3ad7a2ad2140b5772c091439eea807a35e988b69c531c2b47a500c71948804bb09f682c27dbb39f9bf7b53f47ce81024fb3650f32573d734964a392116fa53808411c8b035203f5564576334af9929ed78e8f6cb29c9b4f171a81c6a34dfd57c59c380180b9b7f38538bd82834fa354d629544cbc659875b1d77b63579a8fa747c93049127b45387bf6c08efb9442f7565901b71c888bb2074eb4c9ce945568d99351fd0a3acc3c54e600436ba5558ba975805025ed07444a9034c30a9c13a8ad85eb4c7d0142a2cc2e06584f37f843b103be4785694d2b2c4dd0487e030f6155bbd52526b0354847b233521312f5c725ab190572554e347183d0902737b96583a87d5774298d4a7b6b9292ea8230412a06def3551b4481d314c6931c8012d43a3eaa0d0df6cb87185b7be43e6ebb844392960e8a65f5f691beea69bec55b24f374c41a1a49560c33296beca0b07a7854c658542a8917c35326a1a1c458448b77d27c3c440c727971b47677e45954fbe9011d00a2f85b3e2cb9725601c97c7b21bda481aa04083576496900a70cc135005221f69420d0f884d35216548022126604cdac4100a74614d4b1206b6fe20a8ac07c31bfe6867362b5d2a67e60061c8bac6620d93b07b87a5bf4101fd645321bab2441185281b933a090686a8cccdb6a1705b07deb9e66ba4a10617a93ab7cadd51047e50f4988c70012a39c787dfdc3ab8c9b19fef0ac4c702bd693170e71c5ff4070b47b3609c5a9f2e8663ef78bc5e27ee6092013a263f2ec172edc4350606840393c9a771999399e948b41ab273ea061744e4a08ac7550c13a265e9b82e674063179811cd7251220943fec7c38a86bfa490bbb6b001c129707b1b765416401290a94dc8e2cab1503dc4cbb2a51bda96c5828397d406386353a75157b09f1776ed5347f3a32fe6b2599827f83ebacba251dedb3c3e514b7add849ac5c40e49b1297634fdb8a6c0d9748a8fc9e98778668bc4446c1444b104db4da7ae5fb5db088cd34017ea6926dd2128e9b39419cb13ef8511705844d4efcca1219453f987cd5d0b532c6b958b202938a90ce9016792035577a4b59ecbe063a8a158b92e89aad62ea507520bab2596ef18778590708dcc62bec78a74715ac69bab4521949e8c0bf914b5304a7384ad25e79c3244e581033841ee8628ad68842f320584068cdfd91467c1051d1a8ae77e4b418343743f0a64635ac313cb722f61d0a672645413e5e92853f06aab35a067eabbf6774a291945e9157255af4008a123a25778d57308328a983c0dc8b4f21c7dd34721db734967a706ffa75e0b052f67c36168ab46c485b1190a6ffb60f4eb739c232b2eef630a00469bd011bc1eacaa9ca60c613039439cfd4ecbef6d7523926ad88b8581e619b02a182b76993b26b3784799a7a314b38bb6a17529650c7a0a556c3dabb0fc44ab8eabc2af522207e90c7c7e113fb7220cac24f45dac26d1605a70c16d1f58b6f766c8d07c56f582c88f6402fcab763f996b164047daaa7cf5048eb51297c50c44d95a664583579f18639772325ca12fae19205742e72803fa4b9991517442be7cab72996ebc50018963f89a5af785c354f7a94241051c80bcd0d9c7f8b09ccad58c0ba22820e859c9a261c6d41a6c310b310a480d0c8950fe1383727b0863ab758b2c551bc99cbaa90f0365961f7727f639183fc652bc4a2782081dc69571b298affc7af09c349124601602bac8c79afeda8531423642ed20075a9b176a75d422740c0c20fa87aad22eccb98d4bfbbf52e7b590aceb660e3982ed3f3cd328cbb6103af5be626b5036ec8460ba1fb8df516b315e1267ba1bc5770402082bd1100ba019cade157c6a43aca6098798c7aba3bbc5b110abe3526520c89620ddb15151b9c67a9c57aa678e7e83b3ab4196b682f20699dec76be6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a90fe22b38a4fafc045cdbe0c9689745fb45760cb2f0f94f7d13cf8c834c4df3cfc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +expected_public_key = 5ca83cb627b7477480002c1ac0ab41865cb5ad306b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda5835f8189a8f1829d09a379c059f3833e7af4593f6b5736f782215c72f8a30e60262dd776116ffb50746bbeb7565fd1a585dacc7c644c15f6647a25330e6e1301844652ccfb90d4d266e3544fdd7733b89b2326f0378d214b615ca423495cea4965fb586c00dc7243d423c1819be8b97a416293467a77ebb87bf724632657348f2a7b34aa256d0826fbe905267076c92262282291ea620b262355d067c6b882a64acb8aa6892cec15b3d66086a665054c40058c7a4714165a431a8c5021102cfb8168e4b80dd8b0c8d72cc8a07c064b83b5f1800b42aad50664cbe1b671d9373ff700cec873eb8a352081bf3fd9c9aec277cbd21eb8a4a2ec126f378b3b60004426a66f167154145b28770ba7b700b538863907961cf2271daab2118f2c40ac4989ab20a056b40c99a769b25c7a38d7b76a164964fb24a27880d7abc72e324a88a25466657c352486b9b17d4c13957d4b8ad26640c3a6223ad44be71535c3c258de440fb2a69f53e22103597aa8778127e971bb074b4dd704441c1bdb38274058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc5478475821b0fc7528d932874c47df5108f3e06106e18adde5a4e50d134c3648424630c42a20c0178bab98a67714c80922a3ddf431dc1a83a9a0c3087a45731177a22928551cca0e90bc229b95589259b9824a679a5a144c0cebd690620c12df2ab56c3a633ff6a1af01357b87108c4d56e6b694c41e153334b034d568f3880744059a214e80d3f477d67a332d44ba4cee7ab25d157b61416a81024dfc92f3650aa3e9c6f89a7629f347f91ec54b13997eda15bda0412df111529497284b312de5b4b0cc70bf0d2b643e5c2385133749243b678a026b415489c31d0b902f4dcc96981accc8abc5b08b9fadc35022b2cf5888d417b4a0a188d0a305d9ec820eaa4bb89c085f3655c0a2ab3962b069bb0a1ac6932c748cdc611b1949abe4a57b7af0c934c8c0696ba6f39c32f4e6874798bafeb70827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_private_key = e2ac344c36b6a047ccf755bef0f455991c2623a76aef7988d0a072d53054d1d29c147881f65ab97ff40295b487677291fa183831b9a6799181ef2872a935530014187d706015aac1b122567ec54af05361bcf384551c71b2468758786bf61276a9db8a615442cd80b3253c862e5129078168f23757b7489d98ac60bcf04585e29b623a44ee737343e20e30e7ad5d20ce6af1187d738b60374a02b45e60f71a148705c65ac34076ae4e390234c118ecb057ed3aaa422072239a2545021b8ab5419fe79bb7e7b73fc38384437a5ad673cb903a55645d00ba659be07b708367a56065bd0ca8047b3258347871987985917199b4445bdbc4ca90173cf410d1d5179b19bef5b0675155afd0f0603a446269e3487a68569caa1d72c6754b441c00fc0e33d17136a95b990068df699ca6f14001f509c1b7c7bc816ca2548dc760516d9bcfd0a61670d9093a9b70beba40dfec2b5c8086acd164d57138a253328da0284da9ae3343003edc193231b6cbd7a0ae0cc19a72847ef7c01a850209e3b6d579a5eaebb566aa001b6a7ec8c0817859932c9570c290214848c25f9c5676553bfe734cd12b747c88aa0a59bfb389a55aac4fb46ab932f7b4400978ff2a59e8e4af7fd3b04e9b8d6e0a8875764862ab6839844f01014ab131003e876fc17bc4699523bc16af8294192116abc03a8b197852b31caccef20e536713b1699282598a4cb5bb89d56c6829c2df39c0f3494f51107c53cb60d8483d6fc69eef5014e9f9bd5aba580fb25c854a13aee72d86ac059cb7432e514f4d49c3bc2a583255988243c699d520d5d80aba6868ea811c487027412988cb4762cd810fa0f18d39670a5c249bae19b0caf653e7364a1b9557d7998e8562980e275a60b98911f179376c0139a3350d6b8c09ac15086c3780331456f0ad7d40159e705d1f8135d1f5613a71b1c6355ab8799bc950aa4802602214365f90c1acec7ff81c87a1e7a051e3a14249b27a2c5c3c61744d9b61e7355b26189197e44d5356aa2bc235b599a3a577967e689d66c4aa966b9d0da431c6727016942b4c0b9f1275888cc6a25eba388780145ca83cb627b7477480002c1ac0ab41865cb5ad306b8ae830e9758dc643cc22d8b4243a90f8b8bc07e8c1bb2b50c9da4233f3cbfda5835f8189a8f1829d09a379c059f3833e7af4593f6b5736f782215c72f8a30e60262dd776116ffb50746bbeb7565fd1a585dacc7c644c15f6647a25330e6e1301844652ccfb90d4d266e3544fdd7733b89b2326f0378d214b615ca423495cea4965fb586c00dc7243d423c1819be8b97a416293467a77ebb87bf724632657348f2a7b34aa256d0826fbe905267076c92262282291ea620b262355d067c6b882a64acb8aa6892cec15b3d66086a665054c40058c7a4714165a431a8c5021102cfb8168e4b80dd8b0c8d72cc8a07c064b83b5f1800b42aad50664cbe1b671d9373ff700cec873eb8a352081bf3fd9c9aec277cbd21eb8a4a2ec126f378b3b60004426a66f167154145b28770ba7b700b538863907961cf2271daab2118f2c40ac4989ab20a056b40c99a769b25c7a38d7b76a164964fb24a27880d7abc72e324a88a25466657c352486b9b17d4c13957d4b8ad26640c3a6223ad44be71535c3c258de440fb2a69f53e22103597aa8778127e971bb074b4dd704441c1bdb38274058c2576976fbfcc28d04a3d4d9a194aa5745658cb96acbc5478475821b0fc7528d932874c47df5108f3e06106e18adde5a4e50d134c3648424630c42a20c0178bab98a67714c80922a3ddf431dc1a83a9a0c3087a45731177a22928551cca0e90bc229b95589259b9824a679a5a144c0cebd690620c12df2ab56c3a633ff6a1af01357b87108c4d56e6b694c41e153334b034d568f3880744059a214e80d3f477d67a332d44ba4cee7ab25d157b61416a81024dfc92f3650aa3e9c6f89a7629f347f91ec54b13997eda15bda0412df111529497284b312de5b4b0cc70bf0d2b643e5c2385133749243b678a026b415489c31d0b902f4dcc96981accc8abc5b08b9fadc35022b2cf5888d417b4a0a188d0a305d9ec820eaa4bb89c085f3655c0a2ab3962b069bb0a1ac6932c748cdc611b1949abe4a57b7af0c934c8c0696ba6f39c32f4e6874798bafeb70827f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516c277a9588d9a781ddff6aa9ea8d259e5599d0adaba2f459598ebd5bc72786023ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = 74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +expected_public_key = 1e0315240833d0f09adee4bbb29459f947897c4b882780c339019161e80b4699924a5c945c1a97c8eba4af258700126747a2800f81092649523dbc47ced32938a783461aa1bf6500f66b6e8307aabe7c4005209826a98a2904becd2853fbcabfc8c24489380bb4f7a1dba07473388508792ae1e7ca257b5c15c3771c92b9d07bc0b83c7e3371177985cb61b7bcd0083fea2075ddd321ce490a483a897cf6955384002be3016f6b9e2ddc5b8d5cb7c4f728e7966e13c04b310b7286021a5551a8b7e8472d969703f54ee4e1b1ae18cf1f6454e360c7ae481ec2b3b72d4049a74514eddb57f71b81b4405dbde79e05a1787dc2b19cf72a0a93b249b15fcc061e700c5325a40b880527f33b78eaf7370fdbb8eeb38e6c1585a12c160cdc7a43a7c45ea0b9bf18c5b5256b2fa2a25c1c29289a72f09560d54662af2c359dd87d9c599288541e36bc7313a4893abcb4ac8269c2829330d26b46cb666c821f49808c79eabc046b110c75a67ca59db9035b7061cdec3486a9b152856c360e021e3c25b4036259044347af18cbe495369dd5ba76ba917fb37d2314cf73607fb0c845463693060ab67785c1c6ba8efc581d21ec2a856ca54170190e61c8ad2c91b2a08791c1cd3ce29b080b342183cb5355b08d4a153c8a9b32bc4469d5557ab6ccc4a41d1f9b6efa405549e30022f64f62e665ab8934a617a4cab60567cb62dde7bd81fb69ee60a603c9138eea88d6823cfb3b6c0448c7d244ca70f5991618c3ff504734c98268f5770fec449ae6b4c47b563b9795a9d58f00b11206f4a26e6460af0531e1c07c54f1a61a86624a64a77019642082cd2cd8464e029e94085a8ab0352710c9f41c23ab47a53f2236387a381648036cb12f3f231624862f36084e1ed6b58309a03c50838a970ea14b76ca064756512b12e0acc6d4a548e63213c746877b4054c41ac3eb6eba4ca759223641613533c2382d53352fea4663d5a121759e97849e7166a50f139f04b2bf9609ab5dc238af2c0dd59ab31c6214c288b21b9b33a5c04845c6283ad0bc16285684d1cef0b11e8b324ab3d2616b71020993959815207b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_private_key = ab994d6b166701339677e4b8026514ee41418f1a96b655b214c49e72d54652d82133b0661767a55b60203baa44f783ca78b14b4b9606895a937cc79095bc0f282862f86a7b595236c3f44017403b74148a00ab62a8502efc9522a736181e0205806544e4b4c180366a554019b078bbc5d0aba0252c1b447887ab6b08aa7f2beca0a783891d4a8ad8f11f6c052179534a9686027bac102f85cd06282c79970400600ac19c01edd69c1f0a9e837ccb0bba0c517574dc97551236b843e2b0c12985d544b88da34c78053888191ffe8852b9d86418cbc02a961694e3491b886c3fe4c53525152190431213c931100e108494f787c26c3a4d16e88ffe585e2b158f4e755321b09f1dd770c041518440aebe4629dac3b7fcf89ea9931def8a62f51ac136234e48722804da5570b41e3f041f74444d11e2c6be822f0d98a6fc23b77f2baafca1b8c738cd55e58e01bb33c652c25df081b8a471ba6bcb46ab9996b356088654e2886d7a9b05970958732694869c1f3e216962a21a8df9cd46b128ca64cc59277954110df74a4a51aa455e9a0f353434b611bc25124a3564359c407c11a261f48579bba788a499a35cfc40cc72c41a98bfcc7a0802610ead89236547ae21f6adc6515ed0739e3b9b240e0c19b2b05e2f408f4673a744716dc9d5bcd9a24389c6c2fec41ae4716dac67a43d52b25f02b4349929654abfb8e66c509c38bb4382c4a627b2b12bb6c6321da64344e91c5f989df559b0714b879975431c0448e5878aa3b0c15210149e7808adfac69dd8abf0123d10300e7a53806b7bcdd9743656cb3f8af63f61d7553d13086c71352410c155e89096d879acf5916e69046927a9aea15568660211e405fd0779672aab73452ae2948b44c67650636b1816c3fbdbc5848059fefcc59f796b6d6841aa6982b6664a5b659d7e9a5cb3e9be1b4c22828a76bbda57f79b0622c42ee95b1765292bd7873a0ea853fe46cdf521184fb230ee5284f07888d07a2de9d7a77c3006aa216b45ac1c4298b2d04a5c526096de329c9ea79d0de812b0f1189f3a686cc17c173265f72466aaea293af44462c1b01e0315240833d0f09adee4bbb29459f947897c4b882780c339019161e80b4699924a5c945c1a97c8eba4af258700126747a2800f81092649523dbc47ced32938a783461aa1bf6500f66b6e8307aabe7c4005209826a98a2904becd2853fbcabfc8c24489380bb4f7a1dba07473388508792ae1e7ca257b5c15c3771c92b9d07bc0b83c7e3371177985cb61b7bcd0083fea2075ddd321ce490a483a897cf6955384002be3016f6b9e2ddc5b8d5cb7c4f728e7966e13c04b310b7286021a5551a8b7e8472d969703f54ee4e1b1ae18cf1f6454e360c7ae481ec2b3b72d4049a74514eddb57f71b81b4405dbde79e05a1787dc2b19cf72a0a93b249b15fcc061e700c5325a40b880527f33b78eaf7370fdbb8eeb38e6c1585a12c160cdc7a43a7c45ea0b9bf18c5b5256b2fa2a25c1c29289a72f09560d54662af2c359dd87d9c599288541e36bc7313a4893abcb4ac8269c2829330d26b46cb666c821f49808c79eabc046b110c75a67ca59db9035b7061cdec3486a9b152856c360e021e3c25b4036259044347af18cbe495369dd5ba76ba917fb37d2314cf73607fb0c845463693060ab67785c1c6ba8efc581d21ec2a856ca54170190e61c8ad2c91b2a08791c1cd3ce29b080b342183cb5355b08d4a153c8a9b32bc4469d5557ab6ccc4a41d1f9b6efa405549e30022f64f62e665ab8934a617a4cab60567cb62dde7bd81fb69ee60a603c9138eea88d6823cfb3b6c0448c7d244ca70f5991618c3ff504734c98268f5770fec449ae6b4c47b563b9795a9d58f00b11206f4a26e6460af0531e1c07c54f1a61a86624a64a77019642082cd2cd8464e029e94085a8ab0352710c9f41c23ab47a53f2236387a381648036cb12f3f231624862f36084e1ed6b58309a03c50838a970ea14b76ca064756512b12e0acc6d4a548e63213c746877b4054c41ac3eb6eba4ca759223641613533c2382d53352fea4663d5a121759e97849e7166a50f139f04b2bf9609ab5dc238af2c0dd59ab31c6214c288b21b9b33a5c04845c6283ad0bc16285684d1cef0b11e8b324ab3d2616b71020993959815207b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02aed3c8cc315c4054d09deac08c6d5d364fd5d47a3c09041bee42c561f978e2d98fe1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = 013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +expected_public_key = a2ccb58d9b00887179c1e007e9624913b9924878c5db1c9e46faaaba1a2944304ed64cbe6b96c3d61b83c404c498f1ba7eeb8000c8381de471a50957b64a94c4d42005831f4b4380899b5b848c307fc49654438ea062719b20796bc39b72c34fbd717bff95c687eb1ea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b360b3de0055742563a1db2782072fcfa86945f83f8e028f80e08825782b05960005f37992fcc126b9c942a7b2c7a230c30824325228c971335fc3609878509d302c8f1cb7ee3b4a9e58013e2377c1104cddb2cf9f969794f715cc805157ab62b9b52d7e273c2f6b74f8e142b8473ea9aab2ba3cb0e1791831b56dc7d6ac7a41482bf347a63ba6cc072201e19949e7baead45a49922bea808b0ae8000aa1794b4a92056a51ddfa0e90ac818940b57408b9282c0835b2be2aaa417ed6be7328926ebab1bffaa0c2360e60b905834a9db8390bc48026f1136d48c42587693ddc15556e4472daa04d8ffbce175bac214b28b73c0f4ca2a521820f7206ce7daa7491050937d5c3608b024a97993ad0156c9cbdfca0997893a7e412bc5d6b8956385e00d7cb61696a3e94a98230c4295394079ac7b1818f1c4601301850735690abea3ef9aaad82b16b30ec4f7612364fda0f78557249aa1302d94fb9792acd5914693729531ca3bcbc42b9b2bddc768803d2611f01b8589809f15506ab5c21ce5bb9404306026b74b1685706d09163a74ecc51684757a02a9b5fcf21a59c17c894135dbaa37e89229a90130aac7cba14513de24611fa77063f4aceb30a92d3f75c4dabcc5ea3280edbb0297b7b2b842cff286e442834624936a8461752693c335916210c3d6c1c54f9ec4ed60076b281534cd497ec113aab73027d918d6fca080ec48b70c9b6cc57ac527276ff4ba3aea74270c230ab058a135995d39438e5f52649b17be2e5ba1890bfb484805c82a912e9046eb9c2b563ba9fb48bdc9b95bb9276f3d906cca8c89439c8659ba84d672e283890c468cb33877aaff06af640a9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_private_key = 4a9b766af1a70935b674049aca04a9c07848a40467f8db039ffa71aeb972758959837c5caa6c9a2ce421ea23b4aea23f4ef4890a8576ad48016af36c384407d016854be31c79c120ce826aae237d33439db2e62035d5c2b34c4b87d546b342b66413ba1cb1be43b34d550c48cc640c6b0c95fbe6427ed086f7064a4c50ad6ef0113ae7130f23ca8ef57730c4817ba45732a79d5ee835bcbbc059e640787aa9edf182d6162cdc0bb9b89b2f9ed2cef4eb5fe0bca19ff21d2825710dcc2de2e44fcff46edffc7b31cbb42a367dc2e6899e19519ff024f6d6416eb1939737250d4a9eb0ab0cbfb94b71a300a648367d099288ca2c703666f4c8ae5c950c5df6457af32842fc04f78334e2d813933616ffdc0e35e11af7f4455646a8a437552d5c3f5ec5852d2704fa40a4bd6ba7ab65c048d4027a682e7f4212dbf890bdfc8a3d2a00bb65ab8f616bc4f34e2aac8f46c83686e5cf7bb58a6a47ab634c361e3871a8b9344f361834c22b234071e34034d7aac431392c2c85c8a5d4b69aa711206b1592e5ccc598c702f36a03290c9728a5fd837f16690954517d07e545bab88cc89916fc6469bdfc4fa4a35b9db681f102bfb8a24d995415635b2a5e3a4db3c937d8a149ccb742c17ac55a0b62879a847fa97c609a13b5aac012d55409f12d98e440a97a33fff52455c880df1c05b784b4d2c63b813599750727a3ec390cfc658da262b791b3cb08a7e977a3a574277db97509201686385e5cfc74af851fdfb9bb0265ad678ca2e37829589320f367222d50b2e263241f6b8860935004bc365c356ea396723ad53a8e367bb7e6cefd1ba24920557fd71624a3a51717c1d17cc886467acc304031917007abb151d91ab93c06d050c32ef97bb02676d96c43152aa3a1b63b26685abe966a89f415cc9c92bbc05c76f126c9197c230679340a95e52196b4e8c3327c644cd430c52b32e2cb50eb9329d03c851465323cb6cf09679df87c15740c50cb3b4a5cc1037e5461adc57d33138de0d4854e46106e4b92eff03a5bc0b5f50001edb0a15da8ae246b33a9135a59d3a0d5d70c396b55f2950da7f788a2ccb58d9b00887179c1e007e9624913b9924878c5db1c9e46faaaba1a2944304ed64cbe6b96c3d61b83c404c498f1ba7eeb8000c8381de471a50957b64a94c4d42005831f4b4380899b5b848c307fc49654438ea062719b20796bc39b72c34fbd717bff95c687eb1ea034ac3baca3504a7c94789ecfbb512b499bf3f4a2caa684a796b3ece845ab477eda88bba0ba89e99a57b360b3de0055742563a1db2782072fcfa86945f83f8e028f80e08825782b05960005f37992fcc126b9c942a7b2c7a230c30824325228c971335fc3609878509d302c8f1cb7ee3b4a9e58013e2377c1104cddb2cf9f969794f715cc805157ab62b9b52d7e273c2f6b74f8e142b8473ea9aab2ba3cb0e1791831b56dc7d6ac7a41482bf347a63ba6cc072201e19949e7baead45a49922bea808b0ae8000aa1794b4a92056a51ddfa0e90ac818940b57408b9282c0835b2be2aaa417ed6be7328926ebab1bffaa0c2360e60b905834a9db8390bc48026f1136d48c42587693ddc15556e4472daa04d8ffbce175bac214b28b73c0f4ca2a521820f7206ce7daa7491050937d5c3608b024a97993ad0156c9cbdfca0997893a7e412bc5d6b8956385e00d7cb61696a3e94a98230c4295394079ac7b1818f1c4601301850735690abea3ef9aaad82b16b30ec4f7612364fda0f78557249aa1302d94fb9792acd5914693729531ca3bcbc42b9b2bddc768803d2611f01b8589809f15506ab5c21ce5bb9404306026b74b1685706d09163a74ecc51684757a02a9b5fcf21a59c17c894135dbaa37e89229a90130aac7cba14513de24611fa77063f4aceb30a92d3f75c4dabcc5ea3280edbb0297b7b2b842cff286e442834624936a8461752693c335916210c3d6c1c54f9ec4ed60076b281534cd497ec113aab73027d918d6fca080ec48b70c9b6cc57ac527276ff4ba3aea74270c230ab058a135995d39438e5f52649b17be2e5ba1890bfb484805c82a912e9046eb9c2b563ba9fb48bdc9b95bb9276f3d906cca8c89439c8659ba84d672e283890c468cb33877aaff06af640a9e87393f476ba2cf46f160359acfbcc46e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6dd1a07043fa0c6452500249601f25de742ab44213e2718cf0ddc5ff6a2a9aa6a9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +expected_public_key = 05192fbd776ea2338c7aa35efcc6a7d3281c50e1521186b785d020868b5052a10288321f363986f6dc5d28033d8e0553d9768241734561416fb1f8cbf623ccb3b74263492cc0d3c086b448073804e3a1aa93d5b1a22b9e02360297791c700a1ddb6880b9413840a828c06c4b5c69a4ae68a8069431f35b9174020e61758ee5eb6e337888bd563e1ff6c05cf568738c2683c50ba4713cab600c55b362f2a3a0907159a30a97054bab56655c273897d168cd41519a3db96c0128803342058e385c802aa7dcb60544921584821b491a4aff9155d2118bc9357bf6e78faee87606941a82129e6a401c15f41ab886b0c262a662c27e7deac9192cce0740ac47481744ca938b901cf83771946c6edec63cb99b1817f5ad4c4285e1ab6c0186463c3318a5a923cddac59a7991bf4279a1324671153def59af647aa7cd454d532a4ace3c01e040789d867d8230095df9c5ae64b1f470660a753cc56aaee948228e7b31e5d50217bc034f351fc1264512b58c6a206b5f844f881c0c833bc78df4c936c49247374590146763404441a4377a105431663394ca183f22789eb9bb96d73a0211b5db155a304584b3fc56ec2c7edf7235ac284021c5771d760edd4abd556800f61c65a263306ea81dac64321fd869e1a369a8594d9b219c26e754e1334269e4aac5fb0424d9c3faea7c0b384006ac250796a8d919ae8cf88d63f848b31c0269a58ffff9ce6f436ed877c33ee72efb5695f9e9c422dab87c6b92f3aaa3333688f5241cc996052f7a27387b6d8cca70fd1273b6473d0501b4155719dbbc464747702de4b45d3c4f0e3a8fb4826752f3bfbaa08f97804f021acdc37887f69060afbc3bebf3818bd064c4fc04cc35658c60be55dab57aa810c98ca49b790871f1a5bcf235192646c8e7b84a24185bc6c4b679586e6c9002e0767aa47b8b23905ce0bceee95f84a1a529185a72a80a95d30bdd74b4a664a0c0864ef0a557938c8e02b92a5de767a27c14d4b4269e22b1e70a869767b1486513809b1b6ad0acf683963da5248296cf1c71295529c9889546b7519212742e86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_private_key = 06f16b2689b409dbc0ceac88a1ea262a94b61951499ed4000730753f5a0103b2692f58cdc414c492439a3ae46b8c079be94958724c6d5a68535e5c0192cc3f6af8c601c8280d76507234c5c2742235265316e53365c4157a103d6f7b1df3f4910a965a1663131442c6e8b674f1f078a0738f05390698819556f424ecc665586ac387c0759eab24bf90a06afc5eadc9cce95aa1f7d19e692b211b21b33f8587ccb72a1022085c5b62a282c9d5880b15754e08971f50b769b65a03a630ac9030c06d1418338c3ac8815aa7acbbd9d7831715a05aa37fc5f7c6e4c92698213a750c842ce37110aabb40f47489a8af4f0cbba9abaef132944cf963d86099db5a5987dc7a5cda1fe5a0abf85b2b9c81c3b2784d0de87f311c298e532af380b84bd808d4a71c4e234e2ae4689a23038a83b703c1bab677863bcc4de4f6ca1d805701821e259818ce208948285e057382bbd8ac05b486e1482da7b2abe396a7c6c6136dfabbd4117fd9877f752882863725bc8b3bde332c1e242d2fe523fe2b951ac3003bc90417376f0fc27133c0ad082399afc9272394bb34387ef1b32936d3cd0ac599c74a03e6b2c20f95710d32816c043d33f13110aa7a79d885b51242ebc18add296267f7779500455019c9c3799c9cc050b85595ebac465aa01c7bab095b68c4b71468229425e60c9e708c3332c31a11e5b1b5222fc34b28a4c4331e7a1e7081927218ba30c9a26dfc7369e336e7ca5e32c83d63970817f85b0025ccc65789143961f2a029d87773b72141a3f728c18592bc447d6a0056e214b47e432c54943b10ba25a271b7689711fe145e11bb48df98208b3b1bfe059b30dcc17d63535ee7bc11d47a791a63b6c970e11bad82371e51fb0df938cfb3c957e19bcb8750ac1f5c585e4b755442957392212a2b16ee7848521549ed68c93d11bc35f0c598c44eaddc0f1018bc3de9bdfbac3d59663055315ee2223ab4e2ccdf78ad68256ad3259f0ac044e0c96128c38ae7f76c19a29390844fa69705278b7dbda8bea7d16336b1583f60c09099c3faba7df1c99cc3032537d7bcd163328ae299115b82fc6b0f05192fbd776ea2338c7aa35efcc6a7d3281c50e1521186b785d020868b5052a10288321f363986f6dc5d28033d8e0553d9768241734561416fb1f8cbf623ccb3b74263492cc0d3c086b448073804e3a1aa93d5b1a22b9e02360297791c700a1ddb6880b9413840a828c06c4b5c69a4ae68a8069431f35b9174020e61758ee5eb6e337888bd563e1ff6c05cf568738c2683c50ba4713cab600c55b362f2a3a0907159a30a97054bab56655c273897d168cd41519a3db96c0128803342058e385c802aa7dcb60544921584821b491a4aff9155d2118bc9357bf6e78faee87606941a82129e6a401c15f41ab886b0c262a662c27e7deac9192cce0740ac47481744ca938b901cf83771946c6edec63cb99b1817f5ad4c4285e1ab6c0186463c3318a5a923cddac59a7991bf4279a1324671153def59af647aa7cd454d532a4ace3c01e040789d867d8230095df9c5ae64b1f470660a753cc56aaee948228e7b31e5d50217bc034f351fc1264512b58c6a206b5f844f881c0c833bc78df4c936c49247374590146763404441a4377a105431663394ca183f22789eb9bb96d73a0211b5db155a304584b3fc56ec2c7edf7235ac284021c5771d760edd4abd556800f61c65a263306ea81dac64321fd869e1a369a8594d9b219c26e754e1334269e4aac5fb0424d9c3faea7c0b384006ac250796a8d919ae8cf88d63f848b31c0269a58ffff9ce6f436ed877c33ee72efb5695f9e9c422dab87c6b92f3aaa3333688f5241cc996052f7a27387b6d8cca70fd1273b6473d0501b4155719dbbc464747702de4b45d3c4f0e3a8fb4826752f3bfbaa08f97804f021acdc37887f69060afbc3bebf3818bd064c4fc04cc35658c60be55dab57aa810c98ca49b790871f1a5bcf235192646c8e7b84a24185bc6c4b679586e6c9002e0767aa47b8b23905ce0bceee95f84a1a529185a72a80a95d30bdd74b4a664a0c0864ef0a557938c8e02b92a5de767a27c14d4b4269e22b1e70a869767b1486513809b1b6ad0acf683963da5248296cf1c71295529c9889546b7519212742e86ba40207b54e874ce0595601b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715accf2a8cad42c743eb61aa338049ce917616899c803358541de1e58cbbdcf3c632871600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +expected_public_key = df624bf2996f55293fe31b0704145a4a92534116109e3c0b8f904db4dc70f4ac96c1572248640d73dbb88db3861d108d368b30086cbc72ab177e1bc48431afdf3208df342ddf802787e385d5344e02c49192d105ac0c78c95253ab90cefd870fde5c5315821ddbe82cc1c267bb797492409603c8536640285d396a53c61632e227ae209622725e4cdc5768e96bf3f42e81b6afe853c7fc8381b4aa6070f2371e00619d685973dac323a1513200ac6826b6bfeb9c053508160700ef6238efc37bd5ac12ed744714b45db77ca4fb998745a6012ee042142cc29f9161c72c86f7cb7e834749e647a30a078de01311d908add39b062018bbc81c96b74aa702d4a40e7a596a9720b08496d2f3a990337a1a4396c291c390e1c4cd685dc9a635e7c69f7ca82eebe24356200268c118410706983a49134c2d96365fba38b992967de41ba6a91640857c020ed955a1228e5a44c91eac6a3a6710457baa88d4bf072c32d458b333345f9f6cba68e9a4086516f0641bb311c72d72ca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74b60886a19df5ab7d2f2a8390e44491901dc2b58d327453ae306530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4b81709da8191e2a2201c9e6fb973f7142622fc95d9876d4cd893a8f27db619515b476a1560949db5a893a675e0259e98625f46aa41fb0a4436410591470025305a01fac275d8cae99a5e06561c94e01262c8b878081852d86ad4270bee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912a50c08d17254788b0264933215c74c9ca4de4262ef880571078ec2695f80277e934208c8cac7528205ab523ac08cb8d29a314242606677a8b18616f9a3ae1b4856537831cca23447718edbb056f8f9b746f14d3b466a1c4419c3c155df08960047524a7b39ec3c5778837f0ecb8f49d03204ba6a41710b07f8589667c769b26a66472ab8217c19f2b3037929f8364c09821e80bb1b5b1c2d0078692fb01a9448cd60a59db56cb96b5694fc7b7abb48a23b8a12ff327a5419342577c19d30b0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_private_key = 64a73e921150eec8c44dc94084ab4ac7aaac99dc29807b922e902be8c66b103543a6644cb437b4792815f925827360743635717d05b9b39c6247a51ce78130848c1963b7b7507b12aaab27ec848f2953c4272134c29c371c8106edd904a99c84a7d3322c55c1e4467715906dc56004068402a83179cc2c578fbc04ec2a976dfabc44e3aacb429ada191ca27857376a70b535b1d5c56ba0387cb72b9b46b537c1ec436e27a5eed282b4e7b86443842cd80be1011a9ecac84126bb50da5534d48cc8f1ae0253c203520f230c8c474c10715225cd66a0bb031c7cf4bc059bb69b9b6ec3e26406396cafba07de5ac445d60229f30c10f2437bf37aef6232a66c9d989b52f83441f046871b98cca4ac756ee8a8d8ab42b6864a3674b890713ce2f85e5ad2164172b8b8da616e008148e0ca639390df9acf29c829d39cb6e7cb201d0755819b90cba2ce8d18b4c80c065e8a6f83220208c40ef1d7784f589db95103bfd22d09d93b62cc90a3a161ba198fd1d087449a2f3dd634aa7a299c02b724286555c119cc474c55c1752796b40885c99c32635791aa794479fc6a4a989babb20b9738306244080b9a22399145a54a126d31770c9096b626a61ae9394db957711d7a38ce1a17b0f57e6b395f21c3be4590a6a45923130597939765d804272a1c3fdc082810b52e5ae8131157bfee994cab860b17402d3fe2bff4162218396c7a607bf526b346f45922d6753983a8832b7a99aa7ea4674464c33d55a6172f46a6114497b1a8b1ef835df4d1203d96cef9e43da9e97c723587c608a8c2d24ad0194164c944d56166450ca20750bdf52caca265adb71bc5cc06736501c63d626784713c4a575833d5029a19a9997c45d4649e3e942946f61cc5d3215de5b9b6723d4bdb44f9b9848c41cd3dfba38e71927fb4175a7635738487c7fb5446c2c92d70810ec9a827871215fc630e4b9a2dda4df5d6c06c46a60557c20ae26a1d734171e96223f22698055700174b118241b0063c13559cd149ae7f34b6680cb4a3e8854b030bdac739ba60653301a8ff4b63357646cad03d7b2a3032441d08fa53653baddf624bf2996f55293fe31b0704145a4a92534116109e3c0b8f904db4dc70f4ac96c1572248640d73dbb88db3861d108d368b30086cbc72ab177e1bc48431afdf3208df342ddf802787e385d5344e02c49192d105ac0c78c95253ab90cefd870fde5c5315821ddbe82cc1c267bb797492409603c8536640285d396a53c61632e227ae209622725e4cdc5768e96bf3f42e81b6afe853c7fc8381b4aa6070f2371e00619d685973dac323a1513200ac6826b6bfeb9c053508160700ef6238efc37bd5ac12ed744714b45db77ca4fb998745a6012ee042142cc29f9161c72c86f7cb7e834749e647a30a078de01311d908add39b062018bbc81c96b74aa702d4a40e7a596a9720b08496d2f3a990337a1a4396c291c390e1c4cd685dc9a635e7c69f7ca82eebe24356200268c118410706983a49134c2d96365fba38b992967de41ba6a91640857c020ed955a1228e5a44c91eac6a3a6710457baa88d4bf072c32d458b333345f9f6cba68e9a4086516f0641bb311c72d72ca446430551c5a8d33cfe2b6867176ba81ca57ae9a4e562a7f74b60886a19df5ab7d2f2a8390e44491901dc2b58d327453ae306530d3aea6d6456a3874c8f4ac3adb325037677149507bd6b98ec988f4b81709da8191e2a2201c9e6fb973f7142622fc95d9876d4cd893a8f27db619515b476a1560949db5a893a675e0259e98625f46aa41fb0a4436410591470025305a01fac275d8cae99a5e06561c94e01262c8b878081852d86ad4270bee2c81a6cc7b4f033a529bcbe3fc959da6c63676b6ccf43771738f1a995912a50c08d17254788b0264933215c74c9ca4de4262ef880571078ec2695f80277e934208c8cac7528205ab523ac08cb8d29a314242606677a8b18616f9a3ae1b4856537831cca23447718edbb056f8f9b746f14d3b466a1c4419c3c155df08960047524a7b39ec3c5778837f0ecb8f49d03204ba6a41710b07f8589667c769b26a66472ab8217c19f2b3037929f8364c09821e80bb1b5b1c2d0078692fb01a9448cd60a59db56cb96b5694fc7b7abb48a23b8a12ff327a5419342577c19d30b0fbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd3394e8401245fd6348bfa697f6990b6671577ec7b35a45b0101730a8019426430e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +expected_public_key = 65a217f49001f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e0a1688182f35446c1e972a2f923c66d2c15bd0534d0b2f418c50e0d81bf309a002c100c55040c6e6b5433a5d47d2bdcbe84823c939c3f76a681982075c90c4c712d1399a0d82c6cf713e5fb28d0ee6368cd4a708508de1530ee89cc53e8b7df748b91ae45bf2a849748a3a54695b3453975082a39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680aff2a80c4c1a07647fc5e8b87b59c8bf97c235f0a56ce2a1b7608d6445b907f4b261dc55cca76a85dc8400895b4a4c03e7e65675f5479fb4cb535240fecc628c180337635af6ac6366c8a778d84980ba659f8482785b5b6fbb1a265a99012a41d5d13cfe07c7bd82cddcc98449d0a2663a468fe9591b0450707a95538bb1c22393f7813e68719a2c11ad8e311402885a54588bfc47c9fab18218bc49c87397be532c0127302089ceaa97102bb2cb219901ebabc69ad1764bb6cb5e7553810b923be76796406994587bd8a0c4216662651b2e8787bfb6b15b98e26481559cd3002c2a03bf0d53467de01bde0bac05e968ae266678bc6945c182d1d66018cc7762ecbb10012208c3cbf3d7671a98388a30b990a4674a8b7c6f958eab221d3e58579e521922abc0b0879b825c9d64791671fc6fe752bf49f87b606580d62c8a17d85a927976daa50ee54a0d186c6c48f61f6955b8afaa1fbc805a53e22ff192161d2850093816d7235d134623d3d4bf20479aef39699426642ac1c084ac43d8657559f817ebb31901f2ac308421a0ea975a4023221080b786049c89a6c451ac076a80e87192d8d8b19a6083b689b128f90afe044d16663fd2ba1ed717c17d5c06ced28446c88f30dc8d89db3d5c531f6d6b63d5d535ffe2671a625d97254223f68e89279198296db0c0917dc338b1b5b33e60210457970aa2c2caca854b07937ae6cca428b8c4dc96029c57ec309ae6e306b077aa1d8baf3df17110207b73d056550aa7ef171b4eab2e8f7990429141c7c518299733b734cfff884aaad95e55b4a65776256d5540a057baa7450574f1266a3091d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_private_key = 631c3a29ac6b4acbaa574210be900d21f402a46653a931b8d4618b3d366d35a7628fdb3e25bb8ff1da8c5872b0c65153d23a724a918e1a63b2ac4c43fce7a430572e9ab5a39c4bb5249a7fb723701bdb9f8f900ee363c8c59501f9c2c46b62c4f5fa3b17198b980233ac71aefdf632a28800bc147fe4dbbed75930aeb8023a33288241c373d9ad4e6b14d4092e834a8443344744069591a247cde4ad5eaa4a03c4c9a12799e08b73d762a8b9b1b8e7dc6eef601b3825c399b047955bafeed1124512c72482511117630d5567fb8b0d29b09978938dca053e5306bd8f8950e4c162060734e0a79290878376b7c76b8b1eff5c1aa30a1fbdd6121dd65bdd4216b8727b5cb3cca576035e62b673cb2d95db9dc532955a98b4d90b62b53b22a2a65aae25c08607c17f727da47385da4bac7d6857ff697c22235950b063773a6f15734d1085a24a0a1103e19aac5399608ac8bad386eef981ff5807d25c1ee5291c17762ed0d637dfb82e186893b86637404952877a0b8c8545a52ca481358f5033a90c45076b366f026761621945a3dacaec577313c0ce420aa932d964000aa2c4052e49f90c62a62fb2d377f76355ad961bd8ea7f24a72caee21bd8d4aa037b7c9884af59e5035fc031a053ad276ccc8863cf30a00fd0065770c3995ad637149056d5dcaa2d634969352cb0daae78d3059707292744a513493d13a28383f002b4928eaafb2941765927259b43e36334f7bedcfa39f22292f734b478f96ccefbc5dd21b585770c3fda67337348731080b48762b2f213c3a85dc3d810b360745f5527867586744b46ef068102cb16b0b49c6139c9dc6bb5aaa6863652b358ea322facc238921a0b5650a8c7709d6b95081b4efdd42f476701d2c65633795bcb38055f845f3f788c8bf73dc84364bd1aa343c306c9a548808c10e31840cd889c0e981ed9b3c118e93b1bdc99212788391a532f716fde86c5bba30d8b23abd028c5b788c3d23a824c86667fab2804e7148e8a312c357963db7cbd8b92efc45aeb43404fe78f25529b5aa3b64d0b073a46c1d3884843261ae396b1901c730ae4c22ce79a65a217f49001f7a44a5cf83bee55a6268ac909ab6230233ea188543f144d6e0a1688182f35446c1e972a2f923c66d2c15bd0534d0b2f418c50e0d81bf309a002c100c55040c6e6b5433a5d47d2bdcbe84823c939c3f76a681982075c90c4c712d1399a0d82c6cf713e5fb28d0ee6368cd4a708508de1530ee89cc53e8b7df748b91ae45bf2a849748a3a54695b3453975082a39f9c89fa9c8866284258e6cae563b9ae7b9e18aa8346b680aff2a80c4c1a07647fc5e8b87b59c8bf97c235f0a56ce2a1b7608d6445b907f4b261dc55cca76a85dc8400895b4a4c03e7e65675f5479fb4cb535240fecc628c180337635af6ac6366c8a778d84980ba659f8482785b5b6fbb1a265a99012a41d5d13cfe07c7bd82cddcc98449d0a2663a468fe9591b0450707a95538bb1c22393f7813e68719a2c11ad8e311402885a54588bfc47c9fab18218bc49c87397be532c0127302089ceaa97102bb2cb219901ebabc69ad1764bb6cb5e7553810b923be76796406994587bd8a0c4216662651b2e8787bfb6b15b98e26481559cd3002c2a03bf0d53467de01bde0bac05e968ae266678bc6945c182d1d66018cc7762ecbb10012208c3cbf3d7671a98388a30b990a4674a8b7c6f958eab221d3e58579e521922abc0b0879b825c9d64791671fc6fe752bf49f87b606580d62c8a17d85a927976daa50ee54a0d186c6c48f61f6955b8afaa1fbc805a53e22ff192161d2850093816d7235d134623d3d4bf20479aef39699426642ac1c084ac43d8657559f817ebb31901f2ac308421a0ea975a4023221080b786049c89a6c451ac076a80e87192d8d8b19a6083b689b128f90afe044d16663fd2ba1ed717c17d5c06ced28446c88f30dc8d89db3d5c531f6d6b63d5d535ffe2671a625d97254223f68e89279198296db0c0917dc338b1b5b33e60210457970aa2c2caca854b07937ae6cca428b8c4dc96029c57ec309ae6e306b077aa1d8baf3df17110207b73d056550aa7ef171b4eab2e8f7990429141c7c518299733b734cfff884aaad95e55b4a65776256d5540a057baa7450574f1266a3091d5d53f74a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219ec9c0d68c84cf3804f14e8daffdd1e28c28d3d55ee782c98c498b0d9bd4ebb2350a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +expected_public_key = 6e1b8a3ba66274e66d3990a19fd84badcb9816036919f23c61077d12d85eb2058bb4b3369a040c5e61573d70c590669f0d394135e30570dab863488a66c1744a165c2e31144ada7b351083890a3d10077f2e556d0271134fd78d570a2fed451572d4197dd90fa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a3c154728080f0e4b910310ce1c948007990df2108b4544354f92a1fa6685ac203c11a58eebb3523b47349fc2ccd19b33c522ddc60cb97671ad011c150a29b51249158d5a131d3583196c828912e7b15572db019904a548e0967c91a684f4965bb3b3e8c008bf8531f98286c005b27a01b7ab2c13ea2c50133c3431db1c66a0b83bb92302fd7948938b4e87c7ad2f430c6516872474185d804c3b8ca891b95f5d0893cf20b90635c84aa260a48aa7b9b3c14130d77e3994e952cf52843069a42a5c285db221d4f492e152c03a51270a35738f51aca012560f84a238da294f2a17bb36bcadac68baa40b110d78966f6bc77b8930bd708a74704549560fc59769399793c26253e67bf4acb629138c277f7826cc00bbdd61dd3b97c2f8277696387196950e1e53b3cf40164c32162416308761e72756c2dac0af7945dce06571a5bafc1968d25a6628b766bc99a5d43c219161ba16a20c5b2075a62d18710dab472550edd2229f8428717b58ddfaa67025c3e0ad97657b20d3be467db6752747961713971d5cbbe287937c12872d305a128f05a53e56b43292c7ce2c2a360381a8610f1a0cef2cba93359c06b3c74e9fb4165f187376a55fff7ab9fe872c9121008579a877099581458713a0683a9425d6072c6b813048649a9f5caa4c606c1ca2f79299feb0ac1b277cebdd82a2396a02b272b4ad196d457838a262be3918dd3db84d7d821ff3aca89450478e8c10997628f9ab23fdb0077997a8ed5b26773377f7a466a69ab4e10b2d93899c66c900fc585391805aee1677695cdbe264158816755f69515d1c3d76046d18c18e07300fff2bf6776cc7ee87000815ca4e83967bc37d366b9ccf74870a678cef2b13a7636d1d311dfd5a37aeb14a3c51c9087b00a2911caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_private_key = cf32873eecc1c6215a531348d22060c1e95acc1128c0e0accc6c5f824a4f2405bcb008785a893962c65b330aadd5d2c007327ef6fab100d52e0da1260e9102d19353f29037906ca08c76367bf669f8b5a4e608a65558a47ce017605226640bc53376920ecb192187ba716842fd67045f928d5df21dd0ec1f648c58e458a86c340c0204654bf7788df525dc396ec7292059830e118ca3b2804e2c621d92bc8c7d00445ab36c38faa84e0697a2a231d550ce17aa6d903b44e9bb9222244a251a7fb2a8bf5393989b1b2f4b5897d2cb300c12b1f763704b26a6b7e1aa5a13a59987c6d6398be32c18f4721cc1c52816b17037d526218a4ffae04d1e22b95e44b9d1e2ab370507095b6062c1b98db588b745571621a5881993580b17e533b81bf1a314311d08cccd1d5a260c19b7355b68d2e5ab671cbcb5aa5538079fed022adc9a25e48b279e47316d634c7b2b1f485391d1e227b61355a38921549ba88a228f66e515e2b31d7677a13d254551646df15733c0f7420804782bf2b520d6a5760b854749a0e17434c49348f13acf502311f1c48e3fbac0dfaa67af77699dbbc34842c198d5668ff3bafbe60abffb3e80a852f8b083e1286009006a23975783f686593483c10054c5a3c9fc8a6553890a32428b0e773a5db9a0bff58257d77baabc9930459d78ab7cdc39a8ec5082a8b1a66b864523acb151220f830269537008ca87b963316a04d2783d857d21a708eca07a701a282025a26b88100772a751acaaaac9890f4449bd1971e45a9f0ae0697e43a27cf7bf4d65583720a63daac323e7ceebc6a8a8819d9752409eb429e6b85adc2a719d411da5dc24e4003772c11e58d849889638bf57bc2d62ab87a4b7837c474ec146a14c543e7a37b258c83f587ad2801dce56bfd8663db8e5a9197591b4871888c084512aa2f624c716a02023566e584155b5a784a964b46ae67c978471da9060844a3811bc67ea87a9878747202c689ee26109cc22ae93ab24c032b8b332d4bb1cbc72c166166c1dbbbbc7d70df1c49c2df2c388e7817d462afe9a3429305e19c929fc065818a2c3304723184b756e1b8a3ba66274e66d3990a19fd84badcb9816036919f23c61077d12d85eb2058bb4b3369a040c5e61573d70c590669f0d394135e30570dab863488a66c1744a165c2e31144ada7b351083890a3d10077f2e556d0271134fd78d570a2fed451572d4197dd90fa5b7b19fb588d1693c3dbb4783c690400cc3c225324fe834a3c154728080f0e4b910310ce1c948007990df2108b4544354f92a1fa6685ac203c11a58eebb3523b47349fc2ccd19b33c522ddc60cb97671ad011c150a29b51249158d5a131d3583196c828912e7b15572db019904a548e0967c91a684f4965bb3b3e8c008bf8531f98286c005b27a01b7ab2c13ea2c50133c3431db1c66a0b83bb92302fd7948938b4e87c7ad2f430c6516872474185d804c3b8ca891b95f5d0893cf20b90635c84aa260a48aa7b9b3c14130d77e3994e952cf52843069a42a5c285db221d4f492e152c03a51270a35738f51aca012560f84a238da294f2a17bb36bcadac68baa40b110d78966f6bc77b8930bd708a74704549560fc59769399793c26253e67bf4acb629138c277f7826cc00bbdd61dd3b97c2f8277696387196950e1e53b3cf40164c32162416308761e72756c2dac0af7945dce06571a5bafc1968d25a6628b766bc99a5d43c219161ba16a20c5b2075a62d18710dab472550edd2229f8428717b58ddfaa67025c3e0ad97657b20d3be467db6752747961713971d5cbbe287937c12872d305a128f05a53e56b43292c7ce2c2a360381a8610f1a0cef2cba93359c06b3c74e9fb4165f187376a55fff7ab9fe872c9121008579a877099581458713a0683a9425d6072c6b813048649a9f5caa4c606c1ca2f79299feb0ac1b277cebdd82a2396a02b272b4ad196d457838a262be3918dd3db84d7d821ff3aca89450478e8c10997628f9ab23fdb0077997a8ed5b26773377f7a466a69ab4e10b2d93899c66c900fc585391805aee1677695cdbe264158816755f69515d1c3d76046d18c18e07300fff2bf6776cc7ee87000815ca4e83967bc37d366b9ccf74870a678cef2b13a7636d1d311dfd5a37aeb14a3c51c9087b00a2911caf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eba9d7d5a52aa2dc226832f6e4603322f60b1dc21207e3360712f9c6445d37e64df072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +expected_public_key = 8cc33e478b0946e4646e934c7bfaac517294c2a75357f1028b8c32e1314cd097471f15b35707a28951bfdc88590d464750a6c7b5b62c4218bf9c152e30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1ffc00e93475ac669be33808079b2b5e230f838a8b003d77b97672844639f8b7042ae6343f681fb1f77f3c11970ce715b8033ce11c9089c9b79e9470b9b64f4feba92067988297be29413c609a3e245866dc0079ac61a61ba1c90542ce965750f2b57a02d19f59719af9191e62a1b64579bc6bc5b1b353a050d913eb8117c525b8e2a417743c9eb8e589776b885c465e4d02a51ed7072d69c8912ab6493bba5fd186836623dd635d8121ac8b97772b671d76d983c513a45e4068c6636f6f1c1b21647ed762a3fb31615e781134075dd3969366527922868605459a6202428c3b94497978429b7e1bd2384e1154bce5396f71ac49aca4c426cacd1c66c0a19918104e1e6ac72018bfb18019b9dcc75a020c14e35b3e7759487b089a45aab9773125f61455465c19a062ec90954429adca61a62d20114127312dd52903604f943ba8f3e0583341844500ccd7e06403a95328e02bd3ea6bf3b721c2049360930602611f5e9a06a795a4b1a8b8d8fa7845a12d1dd44d9d67971ad0ad0b3280b9f996d3770890582af9757360e7208c8b9766c8c673db52c22cb6e167191d11900df3b2190230f01437bdd8145ce232a1737eecab8b2ca1489d427ac74426dcd39e12a8b510a0b6eae269aa4a0f46724045792a27d7cc343459914a490a170ba0c27e1405639da5141673b8e9606cce509d353abef9b7c96c2249dad3320cd189060662c11069b36b1c75e561fc3a20631862a9b531c41683c30b7879e0c03c49b8e26c7bb59a2bf16950cb7c5eb326481a9161691859932c430e66c1d998a1be066648c569698285695c08d004586408360bb8954f195cc5198fbbe3c16a32c72ea0b577914f5590bf189833b9d38f27433d406a88876ba754d86f4d9bace1665f42092129995fdb3b790a89a2f1fcce9c2048b986c8bf16b5cfb5b4f3d21f4ae84b5057c1ad5922bf15209eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_private_key = 9388ce90930382aba7453a3493f87804172002e6c55852c72e550ee0f018afa50499c20914e6575af217cfec0c55d627e29300419657a6575552e35f5d243535e36932aa98f2a64873ec6b72962a2710296b3a74f72827b51a40f7d0a2d8544b586695887223ee1bc71ebab898142e1c4a412464526a7362af62cab1f9bbce33444f43afbe016a0d67c6b65b7872f3c69dd60adb9443e0766005f4ced873a9a22cb99083a3b857850f51af8c3571f18949b932b77e9b00863398355bc97cd07204606cf5eb80092abf1e42ae00315c79b27979d0c8350942dcc3ae5e0086450171ef17a0c48b3387921b92dc8c60d0c364ab7110c59a3fe27b7004a7a0d10f24f66c57d15fed49285b995e4d198d9fa90e46849130167238f24aacfaa4419a627b30c6c8185a5cd751313a55729b854b61cc1ba940a0ab9dafb241b3f81a590c4903c54a43d790c3fc1e2176b26e40375c294839516d0de4615e16302c935824f6528bdc22355ba9dfd77e3a0c6d8ac36011bcc760e6c04175c088d06079709edf3570cc259b57ca85b505a5277a92a5d83f332747b497721c707b44b0471638966d5319a6928f4f10396d192ab7eb340eda4ffa66284d5a7e303175bbd0ca25b2643a5571e8a74fc1828656d737c47347ac120125f12d7efa06d73c2dfac4c38fe34d1a393907ecb44834c4988c7a59d27b26b32420e98723c09fa8b19b730bcf672cb555e3c4bfa1ac2aa2876ef792b5577674eb7ec635c1b692017346bf5a24279d018eccb9aa3e04065a73061d8115bb208277243709a37139058e30b8549b2c00a54093e9d14095f13a9f5b088f1057207096091bb32bf4b85fc3c088a7cd0db9c4301374aeb907b0a73ae15026e0900cce347f2f883223166aa8b012e91b5c67d50d421bab6a6ca88fc373a2943ec7e51651a13554c30de5424852804def43b72858185c38040d6532e2d25b6a6970220200ad352636b4ba3ea8466ad678bfa958472440d5e445c4680701abbef7f2612faa26bba87da1d8b8bb1a3568144a568c4b112263a4a5292be317dad102ea5555ca1b197341040007808d68b38cc33e478b0946e4646e934c7bfaac517294c2a75357f1028b8c32e1314cd097471f15b35707a28951bfdc88590d464750a6c7b5b62c4218bf9c152e30cbcf97d8c64ac73da1c5493848397adb47ee43860949b65bc4ca1ffc00e93475ac669be33808079b2b5e230f838a8b003d77b97672844639f8b7042ae6343f681fb1f77f3c11970ce715b8033ce11c9089c9b79e9470b9b64f4feba92067988297be29413c609a3e245866dc0079ac61a61ba1c90542ce965750f2b57a02d19f59719af9191e62a1b64579bc6bc5b1b353a050d913eb8117c525b8e2a417743c9eb8e589776b885c465e4d02a51ed7072d69c8912ab6493bba5fd186836623dd635d8121ac8b97772b671d76d983c513a45e4068c6636f6f1c1b21647ed762a3fb31615e781134075dd3969366527922868605459a6202428c3b94497978429b7e1bd2384e1154bce5396f71ac49aca4c426cacd1c66c0a19918104e1e6ac72018bfb18019b9dcc75a020c14e35b3e7759487b089a45aab9773125f61455465c19a062ec90954429adca61a62d20114127312dd52903604f943ba8f3e0583341844500ccd7e06403a95328e02bd3ea6bf3b721c2049360930602611f5e9a06a795a4b1a8b8d8fa7845a12d1dd44d9d67971ad0ad0b3280b9f996d3770890582af9757360e7208c8b9766c8c673db52c22cb6e167191d11900df3b2190230f01437bdd8145ce232a1737eecab8b2ca1489d427ac74426dcd39e12a8b510a0b6eae269aa4a0f46724045792a27d7cc343459914a490a170ba0c27e1405639da5141673b8e9606cce509d353abef9b7c96c2249dad3320cd189060662c11069b36b1c75e561fc3a20631862a9b531c41683c30b7879e0c03c49b8e26c7bb59a2bf16950cb7c5eb326481a9161691859932c430e66c1d998a1be066648c569698285695c08d004586408360bb8954f195cc5198fbbe3c16a32c72ea0b577914f5590bf189833b9d38f27433d406a88876ba754d86f4d9bace1665f42092129995fdb3b790a89a2f1fcce9c2048b986c8bf16b5cfb5b4f3d21f4ae84b5057c1ad5922bf15209eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddfa7ba132b5dfa2e3ce67b64bc72d551f3290d428cfbd45ec026f44c8dc28334d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +expected_public_key = a764b9e7abb0be68520a095bca8946289731b5d068114acb1209507e9b20831bcdb2b2b6610c0031f89f6d408003ba57398b5d4bda4479134350994a8190cc1ec6b8ea0905cd38772789c9873a4cb6606e6a591410125786d7140778975c472077e42416d3223d69ac98320de4a1bb45761f04178fb63c92c71b24ff8056844455a45a37969b4231123483b341ff6652e7666ede163e9b614313012fcfdaca544b99cf922de994cf6de08799586bc5810c5c1c54882b935c52046921963865c0b82b5466e29eae6a62fb1792f4e1035308aa5ae81aaa524533ea7a000d7a128cb83bd0587138c73d66b17c585f7037be9c0089e6572f2f68c5ba09a532326419b3c19346267d8887dab82fb0176062f4c6e6707ec2ab7448215e895908d82cceaed528ba75114c7609e0b6b4e27b9b14bb8adaf0413d354f00d33409d5a185d1b95c58b7a86caf903c1de1ab16aa2054c13849edd469899780c34b8c423a27483abcf4c53b4bf2210f602aee904d2dd879054b69247b05f3b86f00a1113dfa29d47bb006a2b1fe8a540021541f412d307433ce71362f639fe39912fc0a6ae4a33ab4b07cedd1813d0009b784bdbb209a58d66ede34bbfb939c09abc80d6c71c550953494c99881a1f874791031a8ee2bc7760cbf75d82bee11668be002255b7a0309527d63bd3707a692bc3d3c927e0a406e852a7215c1850dc9aa9b17af5dc71fe9c57dd5dacb26f95478613c878b7694d74be742c282991dae15267cac6d2bd0b2d2c469bf391efd470a19d59a6db65710ac98905520c863927ec80bbee88513d70d009370d6b04af5ea49e6263d034228644307fb407c4617b8b7977c8f2c8bdab888940c2b1e157193830def0804d58b8f380316f60a3c26e27581d03351237cbf85ce4252c92c19c7a842201826cf698a074044b9b8132236ab6852718e09e033e009a1e8dbaa6ce98a81fa6371407fc2619e5aaccb94f1c8fa18236570abdbc217a0489be14aaecaba1c631b76c5a996d4bb842bbcce6798255d7365fed744865267da794cfa97ba6c7927474647a6c952a68954369297e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_private_key = 5177b63a55465cd09a42fc7c26cb3380880f239415c318be33e486582a40f3a685c060a916ea06b5dab029c73a5756ae52ac299b16151685611bfb5acb3465a591b015bba901765d2c22222338c5de7944f17487d7bc7c444840b3c69aadaa3e87852446b63d80e68e24ca02775baf035a24aed04ed5a54193693006c326f814a7379aa4141320ffcb18e2624e08e27952e75d0aac6cb4b27c9faa6850c035799b229372832bbca68ca915009b8ec877548fb657a73bac7556aad1b6b772f24393ca11eeb53d05d6996c162d785bae9033a23e78ca224cb92a770713d5150cfb8fe570cd24b2c43c2ca60b81c3243234bea625f3a05cfd434688610a7d46bbae25b14c207225fc0c60326cf33566fc340d4ec8b1af40c4584828e7709d4042016cd5cef2b77f5c3b434053a5783a761c1357c6706a490314d8d7c6a94289bb37b999739098da95d63b6b5043036c7a554f148d511b9e190a7f10a3a5f2581002938f2f92678ee28276443387b28a0907641e4371643b9ee4d5a0c2c8b6a2a01c6f427fdaa38001086624f805a7a1b4dfaa24b481c32fa280a8d85726e08f237cb3909b20ec51acdd7424d4c74f6c67bca4b6046b44c16c54a059666ea12c5e68ab7c62705043750aa67538fcd470f09120bc93b9ffb02110a75e3db179c20b125f23967e20b32eeb9b2af1c9927b52834b89e32295bf57428c2cb67c231e80d26e122353186c13ce249b56fa668ea4c599ea62c57c65b0360088fab236b3bb76c60aff1c547948212420b3d322b4770a15ac136aa279918d9003d337ad1b78cb5523903a5cb32a10c17c820d6bab430bb3926ba34a11077ab834835fa78ebbb3b766c25955e46cba5818b6d729c474bf76eb706f93bf74f046971aab7859be78a3a8bb570cede984ec72b5e53566150003cc81250e97774f273e629188e3141c8be771a53a5ffa47126b1898b2512bcba038781304729c6807c3b450335658f3a41ba91795709ff0ba02135a5c762089b8e44deef53a280a198b8275d2a00dfaf27f14c93fc4e949d03561536b895daaccb73506f94a06d5225d94e7c98e5b26a764b9e7abb0be68520a095bca8946289731b5d068114acb1209507e9b20831bcdb2b2b6610c0031f89f6d408003ba57398b5d4bda4479134350994a8190cc1ec6b8ea0905cd38772789c9873a4cb6606e6a591410125786d7140778975c472077e42416d3223d69ac98320de4a1bb45761f04178fb63c92c71b24ff8056844455a45a37969b4231123483b341ff6652e7666ede163e9b614313012fcfdaca544b99cf922de994cf6de08799586bc5810c5c1c54882b935c52046921963865c0b82b5466e29eae6a62fb1792f4e1035308aa5ae81aaa524533ea7a000d7a128cb83bd0587138c73d66b17c585f7037be9c0089e6572f2f68c5ba09a532326419b3c19346267d8887dab82fb0176062f4c6e6707ec2ab7448215e895908d82cceaed528ba75114c7609e0b6b4e27b9b14bb8adaf0413d354f00d33409d5a185d1b95c58b7a86caf903c1de1ab16aa2054c13849edd469899780c34b8c423a27483abcf4c53b4bf2210f602aee904d2dd879054b69247b05f3b86f00a1113dfa29d47bb006a2b1fe8a540021541f412d307433ce71362f639fe39912fc0a6ae4a33ab4b07cedd1813d0009b784bdbb209a58d66ede34bbfb939c09abc80d6c71c550953494c99881a1f874791031a8ee2bc7760cbf75d82bee11668be002255b7a0309527d63bd3707a692bc3d3c927e0a406e852a7215c1850dc9aa9b17af5dc71fe9c57dd5dacb26f95478613c878b7694d74be742c282991dae15267cac6d2bd0b2d2c469bf391efd470a19d59a6db65710ac98905520c863927ec80bbee88513d70d009370d6b04af5ea49e6263d034228644307fb407c4617b8b7977c8f2c8bdab888940c2b1e157193830def0804d58b8f380316f60a3c26e27581d03351237cbf85ce4252c92c19c7a842201826cf698a074044b9b8132236ab6852718e09e033e009a1e8dbaa6ce98a81fa6371407fc2619e5aaccb94f1c8fa18236570abdbc217a0489be14aaecaba1c631b76c5a996d4bb842bbcce6798255d7365fed744865267da794cfa97ba6c7927474647a6c952a68954369297e96b6612c3a0c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad29f8a01ba71d04d6831c03d1ff294fb58ef6f4041772cc071074829c32a3ac9d36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +expected_public_key = 5722c4c5abc6ba118828263017d56e8fc3871b503a8517a0e3b8bd8192746e211a1a09923b761b20695f6a3ca01eb62e7f6b5302f54b8de33fe02b8fcf9c16e7c552977735139877c95bc69bc704fe94c0333115d7ea091fb41c146c07f487961c83b1b18225e91449c961769a7bb434a93da88531a75c207044a46623acb8342d59d1455dc434e2d2bfa5c30b9807789856b76d3a4c65d642fe65827eb7040290c21f2228e40251680aa7aa106a4e150d3226b030407d293929c20bb1afba5187b1c4a300749a323168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439c30850b68f20d860ba262c992c99c2bc37eee195d2e945c1d6336c990a77e9af68eb8932eb3325e362db5a77980274aa3b699be212db904e49e326fd445e48354b1609c0942735dc6480c53bca3c8857fcd90965f61d4de0509891272d31a51f3528fb17acaf669efc1032a4240f097118697842d79239b16313a6f74aba689aac94936a35a21331961397029a823d443244f49a445527b039ec8547c35e83fc2d076225d72b7634fabe64a103283434de705bba284fd2241a7e161435c896e899579caa2cba03c53ef74ba3cb30adb80b94bc407159a5d3b35f85b3ba3491c85b4379cf6472310335dcb0cff3006bbb5c8c37e3a1b758518d4c740ab5358cf8ab6cd92542a79a97dc4498734c8c9c36baaab29472a9cb633ce5d30039bb53b03978c51402fea962b70506642b5f6242345746abc312b6625a96443111a2c78d674a755554266c5089e23c9b63ea4b255890f577bc5a442066a2c448771629b542d2981093e49961f8a87a93c068e25167483872d378c2445f398796970c92b4b42aaaa65771382b53d8c79a0258cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d61a0614f1436e3623a77d38abcbb780059521ac7148c088a89b916a0103f477a15a68489d5f63cd7c84132aab6bc63a5dd30b8f27c835a738f1f619efb31509cc9205a4716b64a3cac7725b79c8c2d304ff4a60b328013fe6cb99d94496b363d03c1a278532780fca35473a000291d8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_private_key = ae066432f2585c1097a9495a937589eca954fe6b27510a58bbfa35c166a0e697ccdd7a7a648a80e09a461ecc9a1e9b8d288c488c48cf86d9c892b2c4021cc4d5194ab3ea95ba7b73acc48568d9cb1c682bcbc8bb93a8ccc091b5fcf706dfc131af4911a947bb84002ea9388f47e4a0feb26ab1ac35b561bd5641512574647a4677e688610bf9a545f385f9b843a76952012379ac965a1afa8bbea16c6f198a579a6733a40db261b9aa449bd9e89fe72c85171b6f27f45e3c0c9664d7b0661a49b18b5180f760b4a99ebb0a2866d70825489ad817c4ccd00c303a583722a686316261607c1d6cab86fc126cda4e75576633b91614846dfbb35481508c9ca06625c49ba41aaf7aec38b49663870bcb0f331296422cf1b816543b0bcc3806ee113e23d4bdabfb5cdf173b22679de771071ebcc53903227a836084db363d251fec091296fb7556cbcce562ce54b24554e7c6dc6aac7af699aef7b8dea52465557e0fd07547f77d3ebc5a9981cf2cc7729e9aa228f62af4a8bb656932fae1adbb820b96f27617d041de7972ede45151805a59a58e3ec57d02d27d0bf448187413fc886c03d0782a8592446a414a760e5fb384f542cf0a99a57ad615bca14043a252505a6956ec64a8a4603b34426d67a629b278a9774e6873c8d688a3a5eb0690f459ec98003274c010331d73fb34595c1598091f64809b35aa05497b58cc5c5978c095411b2558c88ba2ec756850cc5107b06d2c6930caa0ca8a8eceb3097c759364992fa5d964a70236990024f72039adf5883224b64966c1d98c87018163b21aab404a697db5baf3a1626fbbc218a04ea1e92778bba3621618255257691691c5a3a11a4c1e12a5bafefa8ca3d4bc2ee98faf92accd6301e3fa3143dc6f223767c0112f26cb7e90095f6a116898dac9528c64faab8a8f0828d08302ebd2794ee71cbb47176f62c19d80088d40297977653a3bb7ee277ce0324b9d163d2506b872580f4b60971657cbe1f322a85ab5830599b4dcaca4b73584255f5fcba21e5b966197a5be218149f7cab9a0af6536a528873a20cb8a3830b84a67841a99074804135722c4c5abc6ba118828263017d56e8fc3871b503a8517a0e3b8bd8192746e211a1a09923b761b20695f6a3ca01eb62e7f6b5302f54b8de33fe02b8fcf9c16e7c552977735139877c95bc69bc704fe94c0333115d7ea091fb41c146c07f487961c83b1b18225e91449c961769a7bb434a93da88531a75c207044a46623acb8342d59d1455dc434e2d2bfa5c30b9807789856b76d3a4c65d642fe65827eb7040290c21f2228e40251680aa7aa106a4e150d3226b030407d293929c20bb1afba5187b1c4a300749a323168576aee45474a8b3507bace55a333e95370bcc7b8b664c281f653f9c3b439c30850b68f20d860ba262c992c99c2bc37eee195d2e945c1d6336c990a77e9af68eb8932eb3325e362db5a77980274aa3b699be212db904e49e326fd445e48354b1609c0942735dc6480c53bca3c8857fcd90965f61d4de0509891272d31a51f3528fb17acaf669efc1032a4240f097118697842d79239b16313a6f74aba689aac94936a35a21331961397029a823d443244f49a445527b039ec8547c35e83fc2d076225d72b7634fabe64a103283434de705bba284fd2241a7e161435c896e899579caa2cba03c53ef74ba3cb30adb80b94bc407159a5d3b35f85b3ba3491c85b4379cf6472310335dcb0cff3006bbb5c8c37e3a1b758518d4c740ab5358cf8ab6cd92542a79a97dc4498734c8c9c36baaab29472a9cb633ce5d30039bb53b03978c51402fea962b70506642b5f6242345746abc312b6625a96443111a2c78d674a755554266c5089e23c9b63ea4b255890f577bc5a442066a2c448771629b542d2981093e49961f8a87a93c068e25167483872d378c2445f398796970c92b4b42aaaa65771382b53d8c79a0258cedabd6ee33539b73642863b6a8a3759bb76aecb5e6aac3d61a0614f1436e3623a77d38abcbb780059521ac7148c088a89b916a0103f477a15a68489d5f63cd7c84132aab6bc63a5dd30b8f27c835a738f1f619efb31509cc9205a4716b64a3cac7725b79c8c2d304ff4a60b328013fe6cb99d94496b363d03c1a278532780fca35473a000291d8715b17cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968357376de9843d74252466888727f9dc1ef48d028c0f52c902aa0dfc3de374c8375d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +expected_public_key = 44d99657b40036ba1462e34b668715c8ca2a84b4c5b7e81d11e4acd7c6ae77a7a7e6193b5c8143a45b997dd291d3b08840cc4765b8b4f8c7caa7158f2b939cd273362c9302af3c59b2a08dd545ad119c0522fc60aee902f6a6b49778ba17a97a47b2018e14336cc1cbdf49b90698551059bca80506a4c8533d791bdaaaaa638571398ac85256740aaa5bf4bb35da6b3b6f514a7e364935e769137a300e9811355a9097492ce020aabbc0cfd8398792651f82b887b0d13c3e9c5632029a1670b3f8c8437b09a8cfd6b8482bad74347144661b0cf297fef2bf91ac607ec7b77ed308ac430abe56c69b668cd6201f329875f6454aeb73540e3c0f0816cd7f2b372daab8b3ec1718d362f97c5a05b35964707b4a7558ea1276fa837e4d90be1b19ae05cc7b948a32d1018f14844e1cc3b79fd631d8166d1fc072e538429ab1b09f8a0ac879143f514ed31931878191a0c203b5e69b30d40734904c1bd9ceead909136593b9c51402e5cf0917c3c9541cdfd95fa66018784ac144c610b4182a69a08cbd43cecbb8baeecca48de3ca5d21ce58a69a96ac65778cc9a5dacd663a632e63b1a4e71b012846f0c6c26b728902f64baeeb6718163cba1ac63447cad9d63eeae21855776dee780d1b6443753235f4330edc889094241930c27fac186f46428a60180d239008fcab21ad162f903a7a0984489f8a9d10840f2171734536b67a329174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9cc129e4bce6a519947d17caadc8f3caa6a5b10bf98a526ee0653af3b214b652dce4b3ff3d2c1ca4b3b2f751e3af095d4128b57c46c8a89a1de5b805ffb20d0300e6ae5c57f562fdf493562e1bb5ac0bdd35b8395889f6c7037ed636e56c1aa661289052952ebf386150bb03eda1616478a1dc43f50fb1edbb63968945e05d09d1d320b335433b701caef733a47bcb0e62bcec0e68cd6da26dde55c53d5a289284a7e6b1c239a092c0841c6e7a8292041a04b842bfc8f2430a632d55568a58282018d55876bc8e90bd1686b61d7ceba6b500ce628dce8a5dcd13cf76c81ffa1afe352c6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_private_key = 058115385970fe9640387526e37b2c5fa614ee27b6e1512e3069c5363a4b48ca44a523714c37c15c60ae17751822d14a18bba78a6b1d6b2614aab3a09c314307f06ae7c3702f37ba9891b9cd7bbea76098bb5062b1356582167c12a02529f884e05c5aa6b054aea5a58e19429bd7a8fc9c5eb0d0aa59b54526884eb7b740bc2aba74902edba3a5c1b53091f219f8ca1e79575aecb556c082700b844690c05fe0692ff2953673640d96b72889a317df4158dc4475a6993c4feaa1718863eaabbc551a11d462a8e8d5293bf666eeb3481ac80f7c4a3da10b2169ba6fd12619bb96656cba731c430b21c24d337a51fb4088ea57105027228952cc79ea03e85c3e1304b1c7ec4e98acc486c411fe1c2d539927d0b822646b8cac7c971801cec9e07625d50caa291808b4128cc1be98c73bd0b03be97645e0048117f5165d71b5ab11af63bb3d759a899c2176dc828736b50dd7f15ef480578b619f3ba8a9e5ec8c24b472d4886f07c3a07c3b677625296dfa9b64ca7d12e94cc8e18631ca6bb80b820c7a229a62b141c42c31f70075ea73ac5b4d3de973d4e364dbbc13aefc9fe43c39be762f0fec97fc0738368709c426504ea71285db774f6b56b96396b2a683939947888267cb834347dc7f3346694e06c6b024c497b950048c96c1988642f074a9b95aa5018c504cc49ea659ac9310c933af9326bf91fb06ddaa21a8a3af4b3aabc608c6cf89c554386da97ab8eb9ca9bc98c9b1ecbe550a6a53cac0d7a72bfd7bc9f710bc6d140197b465c47094f3663f9c5089175aaa8f23b3faf97a09c7afbb94c2e58baeab36b0ceb1cf194720d54bb98b03c0eb1756b7c376560a7603b306aef22a09791c96e952f077bd2f5040aa2b6e188a776aab6530890f2e34c7ef792777b4b07c4ca8a8a071da13c9fe47b451a009e0a68eec9037f89627e7a979175b7f7469215783c337dac91f55c574d223222a0b71dc4222a4716a69b3fc5533ca9842ba17adb23ba6e300565f739fac07483ec53ef192828ea113199bca45f28b558b96302900ef872f6a7972ac025eefba867f001f40736eb41737ef228a44d99657b40036ba1462e34b668715c8ca2a84b4c5b7e81d11e4acd7c6ae77a7a7e6193b5c8143a45b997dd291d3b08840cc4765b8b4f8c7caa7158f2b939cd273362c9302af3c59b2a08dd545ad119c0522fc60aee902f6a6b49778ba17a97a47b2018e14336cc1cbdf49b90698551059bca80506a4c8533d791bdaaaaa638571398ac85256740aaa5bf4bb35da6b3b6f514a7e364935e769137a300e9811355a9097492ce020aabbc0cfd8398792651f82b887b0d13c3e9c5632029a1670b3f8c8437b09a8cfd6b8482bad74347144661b0cf297fef2bf91ac607ec7b77ed308ac430abe56c69b668cd6201f329875f6454aeb73540e3c0f0816cd7f2b372daab8b3ec1718d362f97c5a05b35964707b4a7558ea1276fa837e4d90be1b19ae05cc7b948a32d1018f14844e1cc3b79fd631d8166d1fc072e538429ab1b09f8a0ac879143f514ed31931878191a0c203b5e69b30d40734904c1bd9ceead909136593b9c51402e5cf0917c3c9541cdfd95fa66018784ac144c610b4182a69a08cbd43cecbb8baeecca48de3ca5d21ce58a69a96ac65778cc9a5dacd663a632e63b1a4e71b012846f0c6c26b728902f64baeeb6718163cba1ac63447cad9d63eeae21855776dee780d1b6443753235f4330edc889094241930c27fac186f46428a60180d239008fcab21ad162f903a7a0984489f8a9d10840f2171734536b67a329174b48919a63993d8c4724a73c51b3aedfa30a86aa2606a5c8f2346e9cc129e4bce6a519947d17caadc8f3caa6a5b10bf98a526ee0653af3b214b652dce4b3ff3d2c1ca4b3b2f751e3af095d4128b57c46c8a89a1de5b805ffb20d0300e6ae5c57f562fdf493562e1bb5ac0bdd35b8395889f6c7037ed636e56c1aa661289052952ebf386150bb03eda1616478a1dc43f50fb1edbb63968945e05d09d1d320b335433b701caef733a47bcb0e62bcec0e68cd6da26dde55c53d5a289284a7e6b1c239a092c0841c6e7a8292041a04b842bfc8f2430a632d55568a58282018d55876bc8e90bd1686b61d7ceba6b500ce628dce8a5dcd13cf76c81ffa1afe352c6877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e30382cb59feee1b6b0fc129fecb8c74034da92987249bc20cc8ad4a2cfc1bfe0248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +expected_public_key = 945762aa4b7684d18022bb247f593d00f4956c728f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcc3269622355b436610412cfd92458cc5703fe2b01cb3a395927be19c8067a793bca615cea3c2ea55cf10c0cbdd94577331939e6b7332d849ac501750411223d143dc953d648152005a323df711009b81614a657487abd5476bd5d71827ca1b5ba45e9c268c6f826e9263adfd716cdb842d4f31b2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f0590b41661b3936950009c1423153c96351db064a794cb345e3c46abb00b061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345c524ba1a1345d052ae176bf16370dfbdbbeb906996eb41fad306a9153c0e8d98128a82231d73a878a8117529f8ff85be6cca6166cc5b0503134ab298c066c62260df091a15f598311815f3503965695586ba134847b3ada551b62072d03d468360150d0b17ceaf0a1496070778c7a75593acbab2baa4c888bb99d9ebaa34f8b02c27ac7ace0a15ca73905d9582b8137a223bca48b42ebf28d4360b01cd25d644a6f7e831e155928e971627c3c52a9b015e5d8a86a790ff785c653ca920151ab662c3fcbb18af3b9ca27f6c0cae82161eb940fd45555d71fa801bdcf418c5e9879fb33b675d5a27e5b45a4e2a20916c83a1bcedaabc0ac0666b4a2b403f05daea6906e773ee9eb3ff9441c06f86634f01d1c93788a08b76b15be95b296d407a9ea500d89b191c1c68b7d85763d1c2d2633277af163596a7ec257bdaae2a510b8282976bf25936a6e380a778939ee2b44bb1054669a2c5c06c77e712bf2a5b6aa405a1408b5fd2573ef231e2169c165727ee1a19b4c6343f2038537da304909c1cf81862e9676f1e26d7f48748488cd9ab64bbe3167b442719a304500d8c72128cbea470942289fc35c1fe32ccc07361bb1591e43e5a4f9076b7d416e5d2325fe0413a0a88984b048292758fcd080b5f5378d6c508927cfea478be3f68015b12cc1b05b47791ce7ca8c1a98cffea637807931a863b2cba011c8d8c35db81bbac79c5d05171be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_private_key = 48340bb266c646934c7f42388385c1ba2cad8d25b57e17c1d728b767a592505a387a46722b652f941a2d420262c188380aa638c90126b9001f9a4c193dc1a7fbf5143d52a9d94ca6f50444bad7aa84432c18b31b8a40003f393f0ad3346cd740c0637f88975f32db5b6cf2a6c0923993e680e4547aaa9015c7559ccec2823279519aecbcf0314105084c63379d92244fc9839a0efb778fa28490999872933b0e2cc10309bfcd6070509b3a50c292e45c192e0146bdc1bbf664ba93953081ca46a1a5ae374955ac771e29048e830569423a2fe9a30703992bda27257f230b924cb82a3780ba3a5efb0c60eccaaf64c5aa4f037d229342daa9089ea1508ddc1c90ac72dbb68d2324ca91aa3f153a7f2902a5eb95a45ea88ad9ea4f62769574071038917ca015463e0252d3394131090a4081247c6b038cf6a095d2a7d4a22e7ae52552513434442b4e908ec65054a4e08236b4a32f054b9598a1e2f48aa88a6b53f950aae0c183a546ca44cb111974a8d1b494ccca5f176979b008725c27f233868717502275095af902f9c91efdba917a3a1a7f5ac89f660f4c34a0d648614f8cc3dd9738af76c63a4c4b64118baeaa72ce91c4ee3ace9a847d17e996f8119039198aca1b2c71bba11a2bbc05e62b33d2b4f09a8de917bfd4687a151552fc4446edca2ef386bec16400e41864c19b9e2a603d5b1b756e3cbe5b092327d39b0cb6b01c92224cacc6ccf5c4381174ec995435041caa07552d55b8a2e8ab77d720bd31443b2c7ee7395a18d378e9e594edabc504e6c310b8617b9b099af61fe8a0c726c0334f761ef85c609266c4eb56c12b8cce7257c0dd96a1390979ac076167f3441fd91ddda9145af6183ac5810eb56e2ff85fb9db4467dc11e70b99dec0cf0083aa02022bf1a079d580626eb2b653b18e49a64344cc250ef9877d858f248c26e41a28e5952f040572fe800a5c8873194bc4430ab739d56528d1332e14b78b56c47fa0b02fb719ef4003a444c7a4f26ff270a279f44e9cd1c899187cebe1a620386d53b35540b359a84656b8bb47bc712982309ccaf8be6d37267b2166a6e42b945762aa4b7684d18022bb247f593d00f4956c728f6977bd197565696c3fc61b6ac2b67cd644b312f992c1ab45c4c6a5aff378dcc3269622355b436610412cfd92458cc5703fe2b01cb3a395927be19c8067a793bca615cea3c2ea55cf10c0cbdd94577331939e6b7332d849ac501750411223d143dc953d648152005a323df711009b81614a657487abd5476bd5d71827ca1b5ba45e9c268c6f826e9263adfd716cdb842d4f31b2588a3291165fb7d7b3f21caa0d639d2e1b9981fc4dff1c9f0590b41661b3936950009c1423153c96351db064a794cb345e3c46abb00b061c4ea6f9bf2b53a679244ce8e453170b6ee9375c7da69056a5345c524ba1a1345d052ae176bf16370dfbdbbeb906996eb41fad306a9153c0e8d98128a82231d73a878a8117529f8ff85be6cca6166cc5b0503134ab298c066c62260df091a15f598311815f3503965695586ba134847b3ada551b62072d03d468360150d0b17ceaf0a1496070778c7a75593acbab2baa4c888bb99d9ebaa34f8b02c27ac7ace0a15ca73905d9582b8137a223bca48b42ebf28d4360b01cd25d644a6f7e831e155928e971627c3c52a9b015e5d8a86a790ff785c653ca920151ab662c3fcbb18af3b9ca27f6c0cae82161eb940fd45555d71fa801bdcf418c5e9879fb33b675d5a27e5b45a4e2a20916c83a1bcedaabc0ac0666b4a2b403f05daea6906e773ee9eb3ff9441c06f86634f01d1c93788a08b76b15be95b296d407a9ea500d89b191c1c68b7d85763d1c2d2633277af163596a7ec257bdaae2a510b8282976bf25936a6e380a778939ee2b44bb1054669a2c5c06c77e712bf2a5b6aa405a1408b5fd2573ef231e2169c165727ee1a19b4c6343f2038537da304909c1cf81862e9676f1e26d7f48748488cd9ab64bbe3167b442719a304500d8c72128cbea470942289fc35c1fe32ccc07361bb1591e43e5a4f9076b7d416e5d2325fe0413a0a88984b048292758fcd080b5f5378d6c508927cfea478be3f68015b12cc1b05b47791ce7ca8c1a98cffea637807931a863b2cba011c8d8c35db81bbac79c5d05171be83f32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2f4e474fd64a6d945e85eb4ee7509cc99fd4054de99f819fdbbb05c54ca6e36da1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +expected_public_key = 00d6638044335765803648b2c7583d29185714c06345c8002f97a0b35641a2457c1f843d3ff637faa04dad093733811f2b143257c37b2f75bbe8a81b107443d071be7ff5c8a89548cdc1b11e20c41e1a6c5ddc57d7e72c8e17a5cd82a60b6c8136bc3b526187fc8774f9c316d9b7c2a9b41f676ab6f53b7e436194dc2cbd8ea324e8701d5dd171b4c20054c87970258fdf259f575a71145b1421667a16812933d645bccc8af72266d55184b1375bdcb15d87b5c1a9b4c0e4f34526194754358de8d655104241d2a30c6021c9d3e727d933147385b3f416b2418924e3369df7652debd6a3b0c457fc28cd88355bb1702d802c0e39773896ecb120a75c171069838888b5cb788990a349b44d5e85712ca91ac8a20e2f03a3c119ccccd37dc783175485be3dca1515723ff2aa14d77a216eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824a7072511b1709a4221b7526da8602cbf11dedc601ba492fde8a5d3bc27c458bb1b994432a61a7a4e333608207fdd700ecb8781887a6fe02702df120f30bab2b30c28cec7d86447371c6a5e99a1c171b64827229527c48b8e343005a58818bc8b9b9be2125aae9ca2d640701b5b204ded33d2cda34ae77134eda9fc2db12b5b12742fb4b4b8a22d8d75cb1f83df409ccdd486303202637a99cc613035ef54257a27ade904e88c13c91e42e841107be386c7ad228459298e01a1cd4151d64064666dbc954e921a408975ab6814752045324a3a9f41f322153e2dc1c8255a5e63280fc2210c52176a4c93cdc9693bfdc73156aa319582e8cd092a0e28a1a8148c13a14fbbc745f5644439905119b44405a27ce9ca446872927e06ebeb11c8fb39ed407042bb2308b90379566a18a32b7ecdb6f832c392bf205edeab45bf0110af1aac076c417923f80ca059f34101d87234b7a288374b2ca0a88950bc722a01ee4e7be48a81fe732998f536ceee8540323ae08f49217ea880de4431bfb74cc80cab0b89f327a28eb9ba932b523907164dc82c961343088002d10f02ac2647a3a532d5cd796abe16115724d37122431a57b1e9b2071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_private_key = e5929843493c5ccc19f047539427cb993481145b7899259865758538b160c1ca72877688fac53f0c306237d572d3c11b6a0b05f5f46655ac09b01509d2428e8f7385ebba74c7777c56cb571af991f33063b0239120f894cab3ca804a7e3a5896299601efe290cdc529b8127fec01abfdc930df7bc345179fb6b150a5b5796f12563df87b0dca299d8a2980b5c096b01748c2571c837ff072063c80ac323b05628333227ccbec1c9e55399bc75739f6486ea379b5e728691fe004037399ac73487a03c3f8a5be7eb09174c60f01eac9227a5784d97f0d9420a3e34808844d1772c846c3527fd36fb17490b39698197b644ef15723832df93c344d3a7c5728043a2734f73943b983a3f9c856aac75092588a24cbbf7e3916cb8b6309c287fac67837d63f8fc44dc901697f007ae429479227440f7495845b9af07192b6667db7867c6dfaca947310d956a171f15ba73994bf214c426831c3e0c220582e6d4437bbb50055abcb5a36829f93150b810ac6907ab814aba0c95439b25beeb371761803aa619bbc01137969047953a767c947e4e7115727289bb47c8016b30ee84822fb5ce5683d4f7c61696108c5413fce2a1f3b8378e65215c61b3028f589ce082386d3ae1d01806bbba89d06abc2548bbe9a80914109fa892128951d9d8a2e545aa273b8a9eb66c07af53700a95708d6610040752bb61bbca29a4a814d2485a48446079496c01b3603bdb6209f77427bf750b1c0a836f89ea5b176536b2c011441b49410c99386b15b2fbfa4a6a93226af53a047a49d738cc4af9c30ae026ca24a060895a04f456b19157edea36dfaf57fc32155f8c9a59b08508cf880c401a684440269f12f8a0c8f98b930a1190f302818b308174cd48b40dccd5fb851104b107ce48a62e86553c98570db342b024dcc5c5c9fbb48989a964771620c06859ac63b92898d218a43df21400ddb04d5e70c3abbb890292180d47fd0dcbb348131ba143e666072c8d64d3d435cb57956f5e9142b619a1da05e205bab945a79a154ce34b2b04eaa3b0ad6268c1a330d5c34dffb8116d883ccb4755ce06e2c499c30938500d6638044335765803648b2c7583d29185714c06345c8002f97a0b35641a2457c1f843d3ff637faa04dad093733811f2b143257c37b2f75bbe8a81b107443d071be7ff5c8a89548cdc1b11e20c41e1a6c5ddc57d7e72c8e17a5cd82a60b6c8136bc3b526187fc8774f9c316d9b7c2a9b41f676ab6f53b7e436194dc2cbd8ea324e8701d5dd171b4c20054c87970258fdf259f575a71145b1421667a16812933d645bccc8af72266d55184b1375bdcb15d87b5c1a9b4c0e4f34526194754358de8d655104241d2a30c6021c9d3e727d933147385b3f416b2418924e3369df7652debd6a3b0c457fc28cd88355bb1702d802c0e39773896ecb120a75c171069838888b5cb788990a349b44d5e85712ca91ac8a20e2f03a3c119ccccd37dc783175485be3dca1515723ff2aa14d77a216eac92b187bdf9366ae4dbbf593b4ed91cb79864c9f4cca6ca85824a7072511b1709a4221b7526da8602cbf11dedc601ba492fde8a5d3bc27c458bb1b994432a61a7a4e333608207fdd700ecb8781887a6fe02702df120f30bab2b30c28cec7d86447371c6a5e99a1c171b64827229527c48b8e343005a58818bc8b9b9be2125aae9ca2d640701b5b204ded33d2cda34ae77134eda9fc2db12b5b12742fb4b4b8a22d8d75cb1f83df409ccdd486303202637a99cc613035ef54257a27ade904e88c13c91e42e841107be386c7ad228459298e01a1cd4151d64064666dbc954e921a408975ab6814752045324a3a9f41f322153e2dc1c8255a5e63280fc2210c52176a4c93cdc9693bfdc73156aa319582e8cd092a0e28a1a8148c13a14fbbc745f5644439905119b44405a27ce9ca446872927e06ebeb11c8fb39ed407042bb2308b90379566a18a32b7ecdb6f832c392bf205edeab45bf0110af1aac076c417923f80ca059f34101d87234b7a288374b2ca0a88950bc722a01ee4e7be48a81fe732998f536ceee8540323ae08f49217ea880de4431bfb74cc80cab0b89f327a28eb9ba932b523907164dc82c961343088002d10f02ac2647a3a532d5cd796abe16115724d37122431a57b1e9b2071a63cb7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd50688de263a82386f39a7b82592247bf5499f1836a3a941413c75f6331ce403179238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +expected_public_key = d9f893e986491d219b6070ae339c3114e1a64d6c61353411ba2008ea358749866018c802d3dcb05b0c5329a691f57303c0d724fb2a1121d264374aab2eb209412941f7e39eaedabadba71494863f79e34eda632c1da77ebca6283311310f4918c69c6c5036a47aecb3b2433e8991b8d0bab01626034be96f31a41d98c1a2d3354f47e87b9053033b82a6a8f6b167e827cb1c11ebf4758af8c70fa98dc1f35b353c54b5552a0f37257367bc43e263e8a23284b0982ce8a6951a4ae5924d74e3481a4bc141f0a85e90c06e97ae64183c0f469dbdcb081de093ddfbaf9d4318a24615f8a38d1477132aa5c322934d5e92c89acb29aa85292c7971e61c89ab484e69976a57c2181ed5450260c05fd957163c0269e9a3aae27114a5395e398cbc198f65b46bc2108150b40493532d63a35f1882583fd16d5de1bf0a7a9c82d9717bac5e31a15baec1afcd94a352c01dcd73ad51852d618490ee5993dc617e0526556304095657274a738bd4620e80280c828c17d31892fd174a4fd8302d705cf738126c352899026d8795c9afec77f39c87f1567120e70d9211b73daa813497397c0abdbeb7124f942df311067a0ac03fd3c3e8641f202765026b7fc5511754481bc8f227e362cbbce579037c4ccac5564c015318e598cfcb538f1558a1b55e4bb61c372caf23c2a1eba52e7acc5a05f129a469bed6688788c2c68c72b75ca413b7496f3c2505eed19bb2962d82436c16c29db904b76ce5626da57bebd05bfe838725052d1103202e563de581151bba7d46e1cfafd50389a730c9a3c56d88030bd397a9d54af0e763249cad1cb0427580853b3572e705bee6f1bb1f4232f6ec2aec3059d777209dfb32710b9fbef71203f5a1eb11507ecb98e5e4cd384124531490e48a0bcd39be19e21c424c726dbc1900ebbc1bf155256a03a89b3d0537b4e00988447ca3c02a65aaa2ad5be40825d207fa683b9d915a6a5a1e8fe20b0cba4ea14378fb759e1a064ad93b6e5ad712be3551c9d4a4b0819eb7420a4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_private_key = 8977c913909b2f2050958b52666c3f7d16094a4613e8b1909e1838a3763991805d58aa1ace8209ce5cb8849a98a1616b36778f1e138abb5b2fcaa5ad2cf5372181477f7a4a7ba4769cc0758d911b28e447f76947cb5bceb39359bda2050a91186b37469295040bb6753d043561b84dc345607ce94a8f0693c91096a4c9c69155076490901f85b321b175f808c76c9698eb9036b4645081051a6674b4fe6b90e3e0753e032e6e72b3dcb07671d300e7dc5fab7275719410c685b4bcb885adb74da7db8588e54c280b82cd41a7f85cafc877c6dd212d9a889d8da091ef4974e7e0ab1112a3ce0446d8715cd309020184660d8a7358d137c825cb78a2c202c29e2dbb10271275c5225fd8a57e34b54e7700108e83436e712944848a6a0a7098f1864a42068ce81126895087a96c4d0305ec475825f44418265c5a6769f5d86d463bcfe0f324492716a862859dfccc8781b2e1ca516866847ee3af99c94e41eb9ca9303d6c6717b53444f3f1a48cc66b43883c23848b9cf7902a4722c7c9ba72dba2a1d15b6a762a9cd2182ac927e63663243571afb78c2b00095bfcc889c0b563c249fb1481cc7a4301a6ac7ea8ca194a19c8859505b267dc982e4f339802b997e183115798bc9b104c18c04c6c7727106028b20112d7b0c35e43246f573a0af1793848ba4b412bc5800e5aacb1a197b29ac4afe55567a990176002be852360be346019c310ff8c5adea09fef258ef560accba00b15321e48d6cfd3f5ce6faa85b2d6af453668504989cbcc4fb60b36cedb2eedf36e400491044c3b89440d7c2a1e3352c0e9d616fd4c58898b57d10a459d609de4e58249f172f8549a4553aabf6671a0342888e954270a78c132556f333c07245a54500c5a5b7918d0411447b971901b17ba57415a3db56c597bb4b7e55752d0bcc6356c1566c01fd79c64afe59b8c925baca6adfca4a2616a9f505313c3e01e13700736d8541f406248739fa6868bcdb3954e226287c0c4e7285ef7e040322944c79cc95106052e9289e9a14a087069352a6a0738699a37cf2adc46f13359d7152d0d98217fb3574e787a0d9003d9f893e986491d219b6070ae339c3114e1a64d6c61353411ba2008ea358749866018c802d3dcb05b0c5329a691f57303c0d724fb2a1121d264374aab2eb209412941f7e39eaedabadba71494863f79e34eda632c1da77ebca6283311310f4918c69c6c5036a47aecb3b2433e8991b8d0bab01626034be96f31a41d98c1a2d3354f47e87b9053033b82a6a8f6b167e827cb1c11ebf4758af8c70fa98dc1f35b353c54b5552a0f37257367bc43e263e8a23284b0982ce8a6951a4ae5924d74e3481a4bc141f0a85e90c06e97ae64183c0f469dbdcb081de093ddfbaf9d4318a24615f8a38d1477132aa5c322934d5e92c89acb29aa85292c7971e61c89ab484e69976a57c2181ed5450260c05fd957163c0269e9a3aae27114a5395e398cbc198f65b46bc2108150b40493532d63a35f1882583fd16d5de1bf0a7a9c82d9717bac5e31a15baec1afcd94a352c01dcd73ad51852d618490ee5993dc617e0526556304095657274a738bd4620e80280c828c17d31892fd174a4fd8302d705cf738126c352899026d8795c9afec77f39c87f1567120e70d9211b73daa813497397c0abdbeb7124f942df311067a0ac03fd3c3e8641f202765026b7fc5511754481bc8f227e362cbbce579037c4ccac5564c015318e598cfcb538f1558a1b55e4bb61c372caf23c2a1eba52e7acc5a05f129a469bed6688788c2c68c72b75ca413b7496f3c2505eed19bb2962d82436c16c29db904b76ce5626da57bebd05bfe838725052d1103202e563de581151bba7d46e1cfafd50389a730c9a3c56d88030bd397a9d54af0e763249cad1cb0427580853b3572e705bee6f1bb1f4232f6ec2aec3059d777209dfb32710b9fbef71203f5a1eb11507ecb98e5e4cd384124531490e48a0bcd39be19e21c424c726dbc1900ebbc1bf155256a03a89b3d0537b4e00988447ca3c02a65aaa2ad5be40825d207fa683b9d915a6a5a1e8fe20b0cba4ea14378fb759e1a064ad93b6e5ad712be3551c9d4a4b0819eb7420a4a54cb912888262c7035b34b2df43dd508979c555f0f0aaef43c83a65bc8c298534feb95fa4949003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e79841a29c0f2dc4089a85db6865ec90faf2f4ddd25f210eb56e49741866bbca8cf811f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = 952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +expected_public_key = 87b3281828644ffa865c43bf25ca3ee561118497bb2c1a04c50b89ecb6b8f173ac78c0380153b55d551492a95f8013b28d38710ee7b0b3f75cb0307e22f1986b65c9a890bdc7846e71b926eefc4814b255a428cb4de94313da24a17973e5d679ab44057e664217a54f6b16219be642fcd16b35952f0d2a37f37692b34c3639e9400a15c245986134aaa3e0219b98383cfa7223acc31b5a05060bc1523d32c01239c9df8338d8fb2f998634bf71187b3c458d155b01dcbc20a7558d6196b7e0b0fff5c856077853206dde97268da274fadb80ac727555e156ef640c2582c4358aa8cb78a55275393de19792ca0f6f030e2495cf1d169e3b327a2cc17fb87bac4fb92f603c93658c2135322b58a4bbdcc95e56f66104807637d4232fa3868af473355860f9850ea5b61391a8c20537ad23367097b1911efa5f74767ce9b1516936a11327623d371e8d64a753785d09f09157697a48902d4121673e2b904aa94d845a5f17e90bbb60b81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e91822857f40fe1f2c818700d26b882e58a3efde1793ac428d9fa8a94f62ba9fb16ab867a146cc1c7c0a0d45a32dd074a4ba52232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097380d17a6f6369a5dc55616950918b245be7a1a3656ff4075acd957e1df062218bc84887b74da635d9011bc02824603007e9cc594387771ab84f7bd065c741185fac84096aaddebca179355dc365516efa4873e70159e28c714a4e1149befb0a18ad6098d5115419dc4779400f8259c7cadabd41a7a270e5c91a616e5cd0b05976979967baf943b592917befaca4d6827a4a545fdf584b8a48b6fdacb1de775bd259b083693947a31d91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a3d235b870896a558a5fb2ccd7d13885969d2037bee23b3db1025be64b3a5feb95da076019b65685186a445bb2387aad029b9df7f1bc5081a7423c267978c295f2653c785293d65406004806db9f98a8a7d12ba7b87b8032e0cbe218413da907641593ee627831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_private_key = 57343b70b6260fe3406818ada3e422af7036f631c500409e82ca670f894607bb0b067ab280a99e0c7047572ca703da89429559ccb397ec7a6e779abb69cc0edd022b012a30a978b52bc28a1ed118907607d3f81e60a91167a066c061bf000bcebeac072c23738f13b84960c630b81da0d724dfc1c67c42115717bbd51bb974502c11840362c033e1d3c1b9887ed14231a7e54dd9830ece994dfa0117412270a830744358c4fe460a84e01992f92739d6a1a5a91af002371834394da3c8d83022519c292554687d02a35d7517fbc4cdd916845680995f48cd272755dbcc6128039ecbe00043e54a25f2b7a5a14cb48776d278c55ce79d8447b013f063c4b17aa5b8356601931163686c1c6764b0233fd80f0cb6919d19c5a14c41fc7ac0dfc2726cb54a4de38399041668bc88be0a721e86c5de0b3b8df862af7084c3176e0371a704a1738b8c7d0f163bd01c1cfa01181b3bc9d97ba2b8596187679986452fceaa99b2e26f0e2c6ac0cbca10db625fec82363ab746e12db473755b0bae5a71574745c1ac1648fab92675735f5b855837f0c47bdcc23a3c6fdc5550b29a75740c34ee1a42a847756d892fbc2ca334d06d6e90216e2c0884b9444b07c788c08fcda49d95a4a1a13947b3fbce992b995eeb8ab5cb65ad4a67a9335e1b3a53a7431f827b0fb86218274833ec7c00852cb6a4c88e28a99fbdc635119672e7b62d32138fb815cbbd29a7d3005685f61fa8ba60890a3dbdf58eae85310c776216d43c90ca4d68a0c7a2c0033e694bd48c78c48870b3294f6d03b6a4610633211b03a28a6f89b86743273193a6a8521034215b7cc27e72f2197d9482f26750eb6a414a9aa6b05054b111a38ed901a4c479473484fdca8c5757121733c67d953047401e9fc7ab1e06a01cf509ca284e5dba7273644a8c1b3f1f2c52b791910cecaba06b391cd807e0752d0587565d20680374bff2e48711e76155480eea54826485c3a4c12da01a9ee3f95d27a2bf6187b625e72cb02191fc9357e724c769624148a71bd8b36b169ccf23d265796120da0328b6fc4a6551bc91ab809863be6b4a1acb039887b3281828644ffa865c43bf25ca3ee561118497bb2c1a04c50b89ecb6b8f173ac78c0380153b55d551492a95f8013b28d38710ee7b0b3f75cb0307e22f1986b65c9a890bdc7846e71b926eefc4814b255a428cb4de94313da24a17973e5d679ab44057e664217a54f6b16219be642fcd16b35952f0d2a37f37692b34c3639e9400a15c245986134aaa3e0219b98383cfa7223acc31b5a05060bc1523d32c01239c9df8338d8fb2f998634bf71187b3c458d155b01dcbc20a7558d6196b7e0b0fff5c856077853206dde97268da274fadb80ac727555e156ef640c2582c4358aa8cb78a55275393de19792ca0f6f030e2495cf1d169e3b327a2cc17fb87bac4fb92f603c93658c2135322b58a4bbdcc95e56f66104807637d4232fa3868af473355860f9850ea5b61391a8c20537ad23367097b1911efa5f74767ce9b1516936a11327623d371e8d64a753785d09f09157697a48902d4121673e2b904aa94d845a5f17e90bbb60b81fd591f46c576d14383b077a2f78ca58f87f2228b09035cf56693364878e91822857f40fe1f2c818700d26b882e58a3efde1793ac428d9fa8a94f62ba9fb16ab867a146cc1c7c0a0d45a32dd074a4ba52232644049cab06126acccd996c255a0c0a5464ab65706d78aa60363f0097380d17a6f6369a5dc55616950918b245be7a1a3656ff4075acd957e1df062218bc84887b74da635d9011bc02824603007e9cc594387771ab84f7bd065c741185fac84096aaddebca179355dc365516efa4873e70159e28c714a4e1149befb0a18ad6098d5115419dc4779400f8259c7cadabd41a7a270e5c91a616e5cd0b05976979967baf943b592917befaca4d6827a4a545fdf584b8a48b6fdacb1de775bd259b083693947a31d91bb775e17c86cf78dee79b969f487e9ec5e19a34630f991a3d235b870896a558a5fb2ccd7d13885969d2037bee23b3db1025be64b3a5feb95da076019b65685186a445bb2387aad029b9df7f1bc5081a7423c267978c295f2653c785293d65406004806db9f98a8a7d12ba7b87b8032e0cbe218413da907641593ee627831283f449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a13fffc419d3d8a887ff789eb661b2af1ee5b32a302ca267b33eac2ea7e3340b9762d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +expected_public_key = ddec85c013cc70746f2b268d16f48db17616367981940214020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fb715428542f5e49b6d5c762ceb26c2520863bf025421a29f854bb52b3a5decb8a5bb7ad23101a254b89fdd95afce255eac087651a588e8caa2d5512cad48c9041a7c6f06dffd86341e62935a6ae0d4907cb3a6e4e223cb754c15e2c88d4e13cede42a636724568a1f4507adc8d0bdafc91178d260c262224ec8a176ea573e69c057c491d1234e4f39a2f6c4283a40c70223539697890cc5cd935ab8fea89a0ac513cb12c83bf6be1de55788f8a434001b7233cd3fe859c3eb3ab0d15067422a5fe1acc2286f59b75111672a3ea24515f9157835ba868a6219d2a10e72703ed6b066c036d118bef4598d76d08010967305199e3f46cdfc41ae1565bace1c52bcc89628a84f8b74252566917d440718a48226b4bb2f29c0e7743fc2fc5a3252b93053c0bd1285abf907601b93c83399b104b8b2c06ecb1cacf37059016683d2d08376111f4ed13a3204701271abded98bbcf5141b12b9455687e66abff877aafd507d01395e7da932a2e386947b015e3896d2a38214443d169b565fe8cda1c305fa668ad7d57987ba95a4e8a8e047a6039159f9c94b6e896679c325d2298a2896b256f528ee7b114d0101adc255c893530bec9d1ad397c6776ef185487e6140f2749af802cc1ed60069585d316959b2bca22e224adac5b54d0655c0939f3e29c864d087fafab871a29ad82c5533b40f67d672a16581c3d05aaeab3cdb0636c938c575c611095504fd200b61293ae1ab3c8895b6eaa64d26617afc82c6821a5b1ae4830c526777f1b9d6bb271c48128098925d607d507c9c7382cd2267c4ed7c6e4320372dd88bd5a9a50737663998934b70017386784867c5b9b11aac66c1ac3bb1793cc02df88e54a41a3db8603af791af157665b88b0b9a075f5a805223754a2005c81ac211967a43d7bf625069d098058df21abab95ca1e57d2d6583cff926eab06aa139a3da3b9bca10c9de93ba6c6346e76a88a8e1288deb6832603b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_private_key = c4f46b76f1730b277c1065622e85451922164498242b836e0b389d25919d8c818e67d64837634cb133bf64f9931ea5b79a16ce7a8826e29c817fa83860177b31198161ba4e2ba142c1e81d0d4347496cb943a2730c3784da86370e51c8000891016c2ff6063f0551aa2ac8b2a9d374ee51b7e24c9a67f47449b0469d75275ef04997334482f8baeaa2a627904a6d8429b266a4573aa0e9435f65cac4bac46ce162262b59cf4aeb79fe17b68544cdfe1b4ffb6b205c131e73091b77cc073e7c85a7559be923208fa6b90d6a3e4e69bc7f486027b2ae3af86896f060dd622777a6768e5406e8943ff1f9254a36bc1fc4178917c46b10c5dff69ea8db2488fc4769277d8b6a4082d8504fec5b4f291532112179282cc740a4db689bca79c1beda6e6ee861f3243c5cd23b18f59b5588c027f2392b143aca675c844975aee455fb8738c1b30543775804034cc01a9e3954967e552dd0b55c6cf86d71234830e453dc357b45c830a162b990f7472c203034341ff5dbb14d61131d35356172cebc60c2acc16496d1182953316bd6140a2aaf87ea6bd8002e61f346539ab1e965ccfb607df0296e258717ce85155fd17433c712cbbca74b9533cac87d30a4764142ccfa610b612acafbcab41b968746a5719014a9d7e840e0e1536daab3b12bc72695875827963a05ba0ce61aa4c0b5da3224ebc42660f87f80e55ea3d23219c5c28779c8b7e287771613f9f30075202225d1bf98a1213687bfbed25dfe61c8e2753ad428c7eccc8e294579af021763d1be13d93f9ef8cf4b700b75526eccccb24fd727ddaaada8a750cb7211ee8aa7ca5b05f06020c14c332fd02bf1c8881c2830f73316681933d84674ecd9033fcb4465ea2dc259522c4b6b14419c78fa2f4bf6114e9c4dc4dc5a6040a01911c18705c7d317252aaa1631d17e28f2cfdc7c986ee2a8d934819ffabcbb7ccaf37a0d42b22e71e609b2873f76ab42bf841ee8f51f3c2b440234a4c344581c28bf5afc9224721ea8a8cc095680bba4a561a8cf54982e882a806e541427b333991646cda51abc3342e0956d4164a96fc4a64303675862c0ddec85c013cc70746f2b268d16f48db17616367981940214020b87d2dc9d17baaa25f4c8e10bb788f839738c4a2f14309c786d3d3ac4a56c6838b54e4de4837979c5fb715428542f5e49b6d5c762ceb26c2520863bf025421a29f854bb52b3a5decb8a5bb7ad23101a254b89fdd95afce255eac087651a588e8caa2d5512cad48c9041a7c6f06dffd86341e62935a6ae0d4907cb3a6e4e223cb754c15e2c88d4e13cede42a636724568a1f4507adc8d0bdafc91178d260c262224ec8a176ea573e69c057c491d1234e4f39a2f6c4283a40c70223539697890cc5cd935ab8fea89a0ac513cb12c83bf6be1de55788f8a434001b7233cd3fe859c3eb3ab0d15067422a5fe1acc2286f59b75111672a3ea24515f9157835ba868a6219d2a10e72703ed6b066c036d118bef4598d76d08010967305199e3f46cdfc41ae1565bace1c52bcc89628a84f8b74252566917d440718a48226b4bb2f29c0e7743fc2fc5a3252b93053c0bd1285abf907601b93c83399b104b8b2c06ecb1cacf37059016683d2d08376111f4ed13a3204701271abded98bbcf5141b12b9455687e66abff877aafd507d01395e7da932a2e386947b015e3896d2a38214443d169b565fe8cda1c305fa668ad7d57987ba95a4e8a8e047a6039159f9c94b6e896679c325d2298a2896b256f528ee7b114d0101adc255c893530bec9d1ad397c6776ef185487e6140f2749af802cc1ed60069585d316959b2bca22e224adac5b54d0655c0939f3e29c864d087fafab871a29ad82c5533b40f67d672a16581c3d05aaeab3cdb0636c938c575c611095504fd200b61293ae1ab3c8895b6eaa64d26617afc82c6821a5b1ae4830c526777f1b9d6bb271c48128098925d607d507c9c7382cd2267c4ed7c6e4320372dd88bd5a9a50737663998934b70017386784867c5b9b11aac66c1ac3bb1793cc02df88e54a41a3db8603af791af157665b88b0b9a075f5a805223754a2005c81ac211967a43d7bf625069d098058df21abab95ca1e57d2d6583cff926eab06aa139a3da3b9bca10c9de93ba6c6346e76a88a8e1288deb6832603b7fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134f1de70b1072881eb659a5e890a92c9313c7378d2e960a060b9c918260d4c245801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = 588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +expected_public_key = f839cd5b3685e864c874197e1bf074d30c41bfe01fb82085c8f5c43a26343aaa9184a095beeb6e01753dc7da7482f2199dd798d17660c5ccbad047978bf0a62d3b9ddcd92487f9103f00adc8fc9ca566a9331790bf93a1599cb3daa229f5ba8d2e33a8c7451130e17c9d4c91ba2cb187495c9a9a9916700e4f8551a4f8793a6c7e85327012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8b51fef740b0abb7ef3bbc8dc00599f711b47a4c858798a76494ed5f01796c43688339db7c40d06cc7d205b5a6aa3278f561cfda647f8961da7966efd47b433650ca5405770f5742b919c81356d0dd2a87b21bb9dda76d0b330891952c81c5d84761476063b452a6503f7565d406fb60b56cc14a9734a297283b2601536fcea5a67c42ead903d22b672d4828a93e2a321fac920771c1d038ab40075771a9f0ee97929c69143808578d114c5366fd0b7abda8a7ed521bded7bc6e231057988c362c5befee06895f89b2637c2866bcbba39b152651d5bd912344a9b68145e2ac69adb853d06f513e108105f65622ee25750595a4bf983aaf45921454e70a06ca392a78eec70fd5685b83a0532f4aecc8a09c2468fb2037f73fba689b82f590891bc087cca35772596410969569060a5d5ea0ae34b0be06ca8df188cc458cbff21615b1a4e0259925cb3012105aa50b494b35a45d4e9312038866dd4131fc4578674273e182d7a1a1bd049076d70aeee016a6c1c520d2bc404eb4fb28918f1990024d579175082ea9795f0616e584b2c7f93ab33944401c7bf7ee64040a3336ca5906e89cf406512539c8579f078d957a2f4b625f90561be79bb59244b0537a41fa0202072aa760a0e34e94fa751a49d68602d97c807b9992dd637c652563f7317084946703171db7262f71737518c52082966f96cc386e30bb6f89d02b93f8db8b9713580c7c62c06963a18681a1fa54a20d774e40c0abb98a6da5a148377a264d0cb705710f3f708955b16e8eb22754b26522519ba833fcc3000db88030546298b610451b50a247885e6321fbec37b2572a246e181dcf97b3003727141194337a108a2280d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_private_key = 22f7af6da8bfe284931c0a69afec56c4e4378c8b563ca29e2b88741ee94875429006f26630bcbf0bb9543ac427fcea1565243d876426500bad4b171d3e31b1f538c5d4602195570ee02ccd004608216c9b864c378ac308b4e0b514e423c96c2ba1b24f68843892b825b4105faa1342abb97488bbae4abb29a7caa75a1b065e652843a52be3f571a74b7b3095c1cc155cd5821c921c193fbc7858fa23ed502bfdf971f02501d3c37c2ee137dab0c63a2909de9c8720c17429d98675748c9ba93235ec2b608451c3bca7a055c913191fdc44b1469b54162c3b037289f1e039f8e3475e259b8e3c899bd28b0a093d7bd65f405cb957912fe015721e45858bf2be4d943303d0860e4496ef85519f393e99d54a15dc69f8459abc707f5bf09073e1ccd7f7821f455da0ccbe95c377ff449b95019f15698384238df4c27f6df48c1d89a0e9c7845cd6b365b13c2a7841275986a05b8d8b6cb3ffb66bc9322141d54cf3a255e3fa3b9a2c236c4201a270bec078c7229973fba093f745bc62c98c8e2c305c75667dd5a968d04ef4655ec0c04333e8b637209d0e9919993ac11424c1629c164b0589e5296266a06d51ba055ec1670fa22359e0a3115a58be094bd0e8bb7a6336bc7b1128359c0b4221347886588c099b16833e93bf8f6010d135020a8ca9489834d88b4127b12803faa030a72c49a7623ea66cb889535880a2d0756eb59936b725347dec4ba9140c33654b05f6b711850ec8154225607b974b55cdc64c41da02e537646f2591078c563e0b0b58fabe99a9696e1424d161aaa1f72fe8e116b1242224ca210dcc248f43ca754014300aa2bb89b36b0977babc2a52d97c615727903072242aa1c3376701892e58e418ea2a3036601e37a42ddc375a2b41745dc9bad55a5443109e7fe23d75f2aeb48ca4dfd335af158f5d7345687ac021f037a8ba19170a41c447bc2e733b5cc10a23ec678ca32c172412873b0e7fc7aad9f53e41fb5aa7928aa8247f157a6e5df313b8aabcfc58c2c8978cc6539498f5aa204189aa996a3fa52274a0170163b56331489734708a8b6c59a66edae8b575d975f839cd5b3685e864c874197e1bf074d30c41bfe01fb82085c8f5c43a26343aaa9184a095beeb6e01753dc7da7482f2199dd798d17660c5ccbad047978bf0a62d3b9ddcd92487f9103f00adc8fc9ca566a9331790bf93a1599cb3daa229f5ba8d2e33a8c7451130e17c9d4c91ba2cb187495c9a9a9916700e4f8551a4f8793a6c7e85327012bb8c2f756fcc1a4bfec39181e8ba95447282755b7c5c8ab8b51fef740b0abb7ef3bbc8dc00599f711b47a4c858798a76494ed5f01796c43688339db7c40d06cc7d205b5a6aa3278f561cfda647f8961da7966efd47b433650ca5405770f5742b919c81356d0dd2a87b21bb9dda76d0b330891952c81c5d84761476063b452a6503f7565d406fb60b56cc14a9734a297283b2601536fcea5a67c42ead903d22b672d4828a93e2a321fac920771c1d038ab40075771a9f0ee97929c69143808578d114c5366fd0b7abda8a7ed521bded7bc6e231057988c362c5befee06895f89b2637c2866bcbba39b152651d5bd912344a9b68145e2ac69adb853d06f513e108105f65622ee25750595a4bf983aaf45921454e70a06ca392a78eec70fd5685b83a0532f4aecc8a09c2468fb2037f73fba689b82f590891bc087cca35772596410969569060a5d5ea0ae34b0be06ca8df188cc458cbff21615b1a4e0259925cb3012105aa50b494b35a45d4e9312038866dd4131fc4578674273e182d7a1a1bd049076d70aeee016a6c1c520d2bc404eb4fb28918f1990024d579175082ea9795f0616e584b2c7f93ab33944401c7bf7ee64040a3336ca5906e89cf406512539c8579f078d957a2f4b625f90561be79bb59244b0537a41fa0202072aa760a0e34e94fa751a49d68602d97c807b9992dd637c652563f7317084946703171db7262f71737518c52082966f96cc386e30bb6f89d02b93f8db8b9713580c7c62c06963a18681a1fa54a20d774e40c0abb98a6da5a148377a264d0cb705710f3f708955b16e8eb22754b26522519ba833fcc3000db88030546298b610451b50a247885e6321fbec37b2572a246e181dcf97b3003727141194337a108a2280d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34cb0c77b5407577a9a9cd8864efb80974aae107fa2801b6ccaf341d5456a86621f0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +expected_public_key = 1ea1cd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856560e0688f75c96b524fd60bbfb40c18533b11d3f6b24069c5303cbe3e6558f376b71da5161c6310ae651eb0c9a8dfaa2c265b85478c59a7b3519cf95176768d048018e8a24be09bc99f6a459f9cca9600aa8625bec4a76959d157371b2abf19130a6540f2f69821aa161da542861955ddfb729a95841845635bd208ab5a7b85527c01f811a98aafade122ebe57cbc89c5ab551c6645bb40b36026b0b10b40b7e645cb571b664faa9d06270a1902549c507b33a568da51a1a7322b53b95b92158dcad6b85e07adf6042f843a06318b7fdaca35867910b0db0e09d03ae54c22b580c33594b85361788dd12764729b54f92b74dca45a973872b00412da2d83eb12d8c51627c4be48955d8eb67b54eb1879479803b30479b59c578c175448525c514b9e685b3ce751b035836b229012709c679c1bb710b947a27ccf07261d639314c2b1d52a77de2c9c2230761ff5254714af940ab4af7ba85c627a1a633a994752df4125ada5c86a60709f37970d771e96f01eae2b322780c3b2ec01fe086be76710f51cb4690a58be890854b7b03dc04c6f632eb56caebc393bcc70410375457af17b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa240ceb7936fb90c0673877d0635777f8c2a9a5b03d8b731e9a0fda08187b44037653bf44dba3f29074995ab3be5a59e3073e52938561fa9496b3ae0031ae0bb27a7dd67424c39f250b5f9c2512e507878438cc8b086030cc588d0c2dbcb1024167715b52130ce969785b4210da26b8a6a18606597829bb40fbbec83ccdf76913685c48817111bfc216699a9966b94590e80a0d45307c36499c006d37a83a46e12bb9fb0712961db7f33d49d633a98b7a36a3b2ad5402ca190da1766071473fb21529221559526a2e5bc5944009cf2d47075d0961721989f8800307c91e04883ceb97308ce6c03a7cc39cdcbe8723822561132b6705f54345ae1480b9fa11184c999aa8a1efd17944027e1969267973cc3456c54140b57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_private_key = 8dbb979547a684b4cac2e4824a251b808a646bc8b49a92c6e4d83bc82a30e9649c42b4b955263725e505dfe8614cd8599689025d0a189e556fb073011908609d86cea8f77d0c687555a88e8f786e2aa65c9154685b038252d06da3eb9f2dc068a14a50d5d641993cc152641881dc27f026cd49540d7ae04e06d99d5d45a056864cef0bbaa0e92e84f4593f59c636f41b7fba346c70239fe511e9c2b39fbc2bec1a452094a9f7cb78c3e9c6d72b5dadc8208a41050925baf9824316b17475e47bb2e7663ecc88a5c60e5308c34ac6aa97c6b5754b434d7b6e1d500d080cb29bb66ccd707254d824a5d84ccf883328033048919747377b9e628e99c41a9756ac4fbb4f81b47b9da81278b99b13b5711b936b42189d8b88ccafba398760738599089f905f2f2c62dd406b1decbf29815cf506971dd32fd3f28870f81393c2ab701a7426b542662c2611043705da7e8090b84645516e37cd4ec48ff2e1c51d0ab393877fdd660fd433ab8f2401a9206ddee1055571258c613ffcc8991a006a30dcc6b56816d0266a0665cc7e0c8ddd48434808289be16d236c6c9f04c3115923d6e879baea0c33c717a4946342b0c31057b848269a5329b8c5218d5b12c7ed3746aef52af89574a87bc90f4864bedb85911a1b6bb5c744a623f96b621430535662ce03b8073d21906636c5d959661dfbb32b3548acb63469b1489abc6988b8732571725cfb71833b4dd959b15783c8e0121ae95100304338d900a741597008f67312414e75c545c1d6af2eaa70eaa65fc742185ec2a0662443ccac36c06426c3dc49a14537cae1b8cd3a647db059e681acd78006df966213a757bd27a4c79b79905556906789bc00177191c0ded1b63629a5e462cccdd772589a24a04ca6f4cbb47323adb755781bc09edc7bce6e10b5aa11067df3b7d7f21cba9692a5d5cdd26ab8274a1c6b8b1fb1c3724f2b42be94758b701a19726a171cb4e8505c8281575106336c90aac7a25bd785ba3b298840f76262d561038348b15a61c6d1b6eba4922b7362f1300f53414dc0bb77cea68d49e676c3302cdf50106da230d1c2319d38351ea1cd19983f91737c99e4b57c67b7def879fae835156a33ed67524d856560e0688f75c96b524fd60bbfb40c18533b11d3f6b24069c5303cbe3e6558f376b71da5161c6310ae651eb0c9a8dfaa2c265b85478c59a7b3519cf95176768d048018e8a24be09bc99f6a459f9cca9600aa8625bec4a76959d157371b2abf19130a6540f2f69821aa161da542861955ddfb729a95841845635bd208ab5a7b85527c01f811a98aafade122ebe57cbc89c5ab551c6645bb40b36026b0b10b40b7e645cb571b664faa9d06270a1902549c507b33a568da51a1a7322b53b95b92158dcad6b85e07adf6042f843a06318b7fdaca35867910b0db0e09d03ae54c22b580c33594b85361788dd12764729b54f92b74dca45a973872b00412da2d83eb12d8c51627c4be48955d8eb67b54eb1879479803b30479b59c578c175448525c514b9e685b3ce751b035836b229012709c679c1bb710b947a27ccf07261d639314c2b1d52a77de2c9c2230761ff5254714af940ab4af7ba85c627a1a633a994752df4125ada5c86a60709f37970d771e96f01eae2b322780c3b2ec01fe086be76710f51cb4690a58be890854b7b03dc04c6f632eb56caebc393bcc70410375457af17b27c5817a65b7a0064d8fe5a1a7aa4e3a6b56c8b45c59145190098dce89c891939ba0e63afa240ceb7936fb90c0673877d0635777f8c2a9a5b03d8b731e9a0fda08187b44037653bf44dba3f29074995ab3be5a59e3073e52938561fa9496b3ae0031ae0bb27a7dd67424c39f250b5f9c2512e507878438cc8b086030cc588d0c2dbcb1024167715b52130ce969785b4210da26b8a6a18606597829bb40fbbec83ccdf76913685c48817111bfc216699a9966b94590e80a0d45307c36499c006d37a83a46e12bb9fb0712961db7f33d49d633a98b7a36a3b2ad5402ca190da1766071473fb21529221559526a2e5bc5944009cf2d47075d0961721989f8800307c91e04883ceb97308ce6c03a7cc39cdcbe8723822561132b6705f54345ae1480b9fa11184c999aa8a1efd17944027e1969267973cc3456c54140b57019ba4f28a8b7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a255d2e2fe01c87cf70bc30703644fc255f83fb47cc5cc5ae2c0e49d6198cae03f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +expected_public_key = a1f21b5f97535710a214345eabd39b1fea121ca7c866981a22d06c547017d6e16aeb14a105ba22ff5b2304e10c948c0c4a376b9e5c2425920ff94953cc831ad45b3f81056b6f321d4c063f8323b0e23813a5a0873fd71d93f9af8059900c973327a048802a2585f29f9f81714a869047b0cc0f07ae4a9b5d398469c9832a7dfbb79fec3fb99c5f9910183a5651c2077f62817ff62c80c0f3ba5b89a19c8280f62b0162a87cbb2c39d98445fe49072103a63782c09e7bc3bebbb21901b081729b7db37379017453f090e5c672a1fa195c49601735c0cdf7338e0521ec0946ad2784eb1a5e138c21c8c04244d2c8e7e0a43c7551505aad3d85c9d640885ea8004fcba8e64c9da72c0ec19197732156278c3ad64282bf9590934a2806680f4e8aa14a8b030519ccf3896abc085566bc5757a467359018c79b57c149338ac2680c249b94fbadb134be1a911deb09add46ab710f930c4c24eb4298c0a05a1af583059b7724d7abb6702bb6680ce2fd3bfc73203d2a563f6d0b8ca54b0886998a449b70e256f22f7a3837263929b22e4a6c97d4141c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320b426749cc971c6735ac769c2072ee88407998399308a1a81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec325295000157857b664b548fdf9bf3924b508570b1a003cdb5158b4e61a8cc0054ecc9b42491bdb9115b8492848f0b6b236b963571ba882279ca3b6dc2532a481cd24375d8f9a199d955824a48916502beedc12c138998a14cd75190b9dcb65c5b20af7fb254b97bc412bc338a6c0b1873802884475636af09a1f222ccba2363c0b873555360325e18b2be4c33edc29e6b874eb74bb12511ab0364245f058ac90561d144ad230ba7882c893d9a73c4a03f82c5accc04031507971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13eca217b01647db07c8726418251703cfb653bc72e3a32192e489d334c53b91136d5b9794c96a8d3519467571a83e0b754b655c85a818d51014a15b03564b665a80df21264c5ab8ec8902be351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_private_key = 51688c6a414adb473f37a6bd2a73c9a6f6c96fc25e68e45aae8670d003b353c157a8d8b07436c59f1a12b0a63416f798ec80bf84258ae127895748a22e903becdc5fed6c922eb41aaaa0bb5fc2cb22384d81bb53dfc78ed4d4652073c40da785585102add4bda7e90dbe491c06131efb583d6ceb7f09c781e62337e202028e437cce0832b6d02edf5403f04571bac4cc6961729f638821048afd80bf2bb9925c3c1964925fb3b62f615c590f4abd78679b44823117074bf76b3a0d104ae073b7ac0c564c220e727a7e5a958e37ccca5397448dd55b5024a439982a431a6df39aa62146410b477f95473ee07c73662114d14bc7bdc6697e4040354bbdfb511a72434073301cf1b2c4ade05fc291aee99771a8e9863596628da860afcc1674671fb9a6307f562babab6016809a3b88960c0622b9d21b3c632df64bbd68b92dfda06e8f1a14dbb5ac30e6815cf8af301ab4ee508e0099256e290235f683ffa6470618519310a4ff4576444011f97aa9a5bab14ea90475828b9fba6dd4134ad3d684d52660522091b6971ff7d88b74746326e5990467a4ffc78fc8e177bd2871c35195a4790e4683b3ec81a20c39b5a784c8e00508793aa4333c009a907d0707a0fec5697a52725b563984c73a306388acdc57eccc650089b12cfa34a0335fb3039cd786233b5509bdd2787f63468691c8ae72363ef1723c614fd6bb1f229a691369acf0dc84ca205da8d8b9d852cd4f05a621bb5aefd2a26534a7459c76b2212a8883c772f661be393ece185bb0e34c5a9212ead05be4a417b383a11c081b46a67685aa722ccc9fd7d124ae686d1144c5fcb38d0c0896da5944f018886b671801239b13d8b3de035884f30bb91547d26b7a3a058aaac800f2f48715a3bee7bac856b11b455a54d9c84f30b63eb6dc3bd58aba6ce0b05724149f21ac79f6545a3b705d951a5dec9710e44078688449210ef0107949cb0ae720000203870a23849f95602c30c848064959c53a33a400af949c6b0042824299abdc48bce567287a749e0c11285c8ab4669ce6e53558e33c197ac2e96a3d97e5992db7c4c48c5ec42bc2a1f21b5f97535710a214345eabd39b1fea121ca7c866981a22d06c547017d6e16aeb14a105ba22ff5b2304e10c948c0c4a376b9e5c2425920ff94953cc831ad45b3f81056b6f321d4c063f8323b0e23813a5a0873fd71d93f9af8059900c973327a048802a2585f29f9f81714a869047b0cc0f07ae4a9b5d398469c9832a7dfbb79fec3fb99c5f9910183a5651c2077f62817ff62c80c0f3ba5b89a19c8280f62b0162a87cbb2c39d98445fe49072103a63782c09e7bc3bebbb21901b081729b7db37379017453f090e5c672a1fa195c49601735c0cdf7338e0521ec0946ad2784eb1a5e138c21c8c04244d2c8e7e0a43c7551505aad3d85c9d640885ea8004fcba8e64c9da72c0ec19197732156278c3ad64282bf9590934a2806680f4e8aa14a8b030519ccf3896abc085566bc5757a467359018c79b57c149338ac2680c249b94fbadb134be1a911deb09add46ab710f930c4c24eb4298c0a05a1af583059b7724d7abb6702bb6680ce2fd3bfc73203d2a563f6d0b8ca54b0886998a449b70e256f22f7a3837263929b22e4a6c97d4141c0c79f33954e42da92633779bf996c7c2b7324379e6944c524d43320b426749cc971c6735ac769c2072ee88407998399308a1a81a3437326cc0bb6c3be3c3b1d0ac13a28a0e5f4bae613493556c8ec8ace279b9ec325295000157857b664b548fdf9bf3924b508570b1a003cdb5158b4e61a8cc0054ecc9b42491bdb9115b8492848f0b6b236b963571ba882279ca3b6dc2532a481cd24375d8f9a199d955824a48916502beedc12c138998a14cd75190b9dcb65c5b20af7fb254b97bc412bc338a6c0b1873802884475636af09a1f222ccba2363c0b873555360325e18b2be4c33edc29e6b874eb74bb12511ab0364245f058ac90561d144ad230ba7882c893d9a73c4a03f82c5accc04031507971649fd457aa4d36a99cc856a2153f4ecc7b4f1cb13eca217b01647db07c8726418251703cfb653bc72e3a32192e489d334c53b91136d5b9794c96a8d3519467571a83e0b754b655c85a818d51014a15b03564b665a80df21264c5ab8ec8902be351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f44763b304a19162abdc4234e6046109f99f955695580a8b782017e107e45575bd78cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +expected_public_key = 7ebcc6700b95f778cec6f514b10c58e323ab7f013904345308601ecf1707f8350b9f29cb39b261580c3dd2651f96e28f89ab9c1ad86cf77cb3db7aa8a05c007d0a1a93a0a83e85be418a7f141078581a5e60c25e4564691e11b5f16171564a1214d8be06c15f6281324997a98f6572adfb62612c6623d4c9cb24bcf0d896af9a16bfe000354a41f9720c53f1574f97c6e8a49886484830d5822751c6e4c94df54aba2ba767b2b3199148bf8a0a89c620866f1ba52c46687af31abc6a7b4fea9e5d6c70a5570f3d6a6113674c92173b6af4902f614f1d508b3b456c406522d986c31aacc3653098b0985ef1879b204261bba81752425d7cd549121983ffb30b17e181d2b8b4dc049f248b55a25b561aa54507141914e580684395e332225089bd29a934ce114f60936d9ab50f568362fcac1153620791d318dc735253085c8c164719b6c0b426c136a311d704d009f226fbd340ece426a25274da929bf5a206b1520bd114c754db2dab0b8a881c03aa569091f40ec3e38422c3b8d4b2c77373853e57068a591663446b17f676bbfb941abc0e1afcb01d939b426a551417acc95988d712600383063dfc5a6be917c3e4041ea5496ab68855b6caa6c92b463692ef2390ce797969715141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e163144d56a191e29c66eb75f86d6baa9e2320b43463b300000083c49a88b6338c374341cd83c1c15266fdb266e1e0933086c7358d82770aa652b7842b2b9b6f9165613d4a27298c0125a2609885d29715f9cb854cf6a0c308b36697cb1f5b530c7625694487252872c70ac1ada8b4959c681f64c46c5ccc2b3972b6188909a1955d99b65b0b80aec1770f60421cda11d7822621ab46fbba61cd0dc6df4082609105839d80ba850c0a8342be5a70d999386167ca06a485368276b4f7340cdc0a9b3010c3fc3726da1ad68043c1665b1aa4413231455078cc898d938d2c5663b1c200fc87a3b2c2b5c5b0c507c1b7f12ba711680951ac8ad9c7e430345f2f6ad3eb9317b044103a82bb03949eaf288b2377b66f629268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_private_key = ed777aabf42a95e30fed857cd4c4758c2076a40ba9534b56b2749527ccaba7530a422336913283fda435751b6d2158abd1e304bdf91160e389b8a3b94d610fed22268f685350590a44305cc57cc98c97a6a2345c5c29bbe6cb49d182cb499c83f19aa5876ca90ec3bed6592a35744cdc44770ec1094f6989add64378f739aaa85f4f4b98b9750d43a05820444e5536601f71a537ab58d738b7c643c623302d26d70b5b242e0749ca31b95a33581be9770665631aeeabc6e6bb450664aff4116e6e818d72683a442c7c14e21f95937c22d696706383d9e84910c4cfe4c57e487768cfa0066ee79dde868ae6e4a7de470c251c2cfed77a154b0bdd258ec7409a694645ef8326f7195ec8c07de2fb5964478422263a5440ae351917ddc7b7620438d31426ece458a5609e2d404aefa94c1de2275bc46fb9493ee8b54b323150fc5abb4221aa602c9ce36c34ff854da0e3595f2199cc2b1b2750a0a75637239a1266f9a7d50a6c86d68f1ec7886f90c351e7001021be347aa623e964eed3cbad45a6bf92a6f5c61bdef076aaeab527f38ef7304f7e2a158ebc5a06b23e16c356f9b69fc4e37920089a6496237bc86e1e86b24bd1956eb67678aa416249417f0c87a6fb9c88e96e39b7ace53543541c425655b2a5e405cdfc433ab68ca568115c535391dc80db3a3b62f3153637a0c4db1d6434a1c995c093a0ade3b1749a758a83c0c02ef7b117f77c74d2cdee2314d3cc458dd89ebaa56a0c295b57c19a315b3ae3e3ad7c029a9fb381e07ab2f4b07a81415913f21b6df48f8c77418e9a224450aa2731984200c0a7c75d517836a7d7463e3c04a3204ab331aa42d7cc56b52e49fb92101400ff1972a8f3bfebd5a1a6a3946a4152982a10d29c1d04cbcf1baa86140a7fa9915790dba7b311b2f3acc6fde8537193b6b950829ef8438f8c90127c44b780157682486e01928083b552f86f894ca6e638af02c1215c27b33136022a129d7ffc5fbe641680a89535774c2eaa259b158f42ca50ee75a7c9f62604bb5bacdabdd2b304ad837986da0f8c9980945cbb29e64ec0c264be853e02b1af4944187ebcc6700b95f778cec6f514b10c58e323ab7f013904345308601ecf1707f8350b9f29cb39b261580c3dd2651f96e28f89ab9c1ad86cf77cb3db7aa8a05c007d0a1a93a0a83e85be418a7f141078581a5e60c25e4564691e11b5f16171564a1214d8be06c15f6281324997a98f6572adfb62612c6623d4c9cb24bcf0d896af9a16bfe000354a41f9720c53f1574f97c6e8a49886484830d5822751c6e4c94df54aba2ba767b2b3199148bf8a0a89c620866f1ba52c46687af31abc6a7b4fea9e5d6c70a5570f3d6a6113674c92173b6af4902f614f1d508b3b456c406522d986c31aacc3653098b0985ef1879b204261bba81752425d7cd549121983ffb30b17e181d2b8b4dc049f248b55a25b561aa54507141914e580684395e332225089bd29a934ce114f60936d9ab50f568362fcac1153620791d318dc735253085c8c164719b6c0b426c136a311d704d009f226fbd340ece426a25274da929bf5a206b1520bd114c754db2dab0b8a881c03aa569091f40ec3e38422c3b8d4b2c77373853e57068a591663446b17f676bbfb941abc0e1afcb01d939b426a551417acc95988d712600383063dfc5a6be917c3e4041ea5496ab68855b6caa6c92b463692ef2390ce797969715141397b40b86d5219b0a8c3858bacc615283169a57151849aa9bbb7e50bca52183cc6d93e163144d56a191e29c66eb75f86d6baa9e2320b43463b300000083c49a88b6338c374341cd83c1c15266fdb266e1e0933086c7358d82770aa652b7842b2b9b6f9165613d4a27298c0125a2609885d29715f9cb854cf6a0c308b36697cb1f5b530c7625694487252872c70ac1ada8b4959c681f64c46c5ccc2b3972b6188909a1955d99b65b0b80aec1770f60421cda11d7822621ab46fbba61cd0dc6df4082609105839d80ba850c0a8342be5a70d999386167ca06a485368276b4f7340cdc0a9b3010c3fc3726da1ad68043c1665b1aa4413231455078cc898d938d2c5663b1c200fc87a3b2c2b5c5b0c507c1b7f12ba711680951ac8ad9c7e430345f2f6ad3eb9317b044103a82bb03949eaf288b2377b66f629268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf8459233c598a48b06d7474da19ca85aff6b2b3303b5d25b96088c52a08cc7f1e87c5fd8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +expected_public_key = 1a986b25b24c36a66d747b761bb2c2a09415fed46551c6a26ab62819aa605a84c9d164b5146c6996f3a33475aa76d055ffb45617f256e22028426b71ea1404cecc96aa815f5cc804d83bba5d417caf64731906b8cdfcbfbaca0e7e0c924cd19475a88668c59f24b7b0aee4a63b936942ba263bf4533dd29e7f51760ba638702ccf6472305e5a0d404732e0a220b269affe711db0a8c2db11c2573b7c3a83b673d37ecd8a725553be79755b803cb866a90e12a4bf7d8275fc7ca07cd20ced0ac9a45c54953220d5caa8210bcb3e43289ba03c6c3a982b5b2d4b73853b1b7548f7aacbb0a4ec2bc676c55dd594aaf630ceeee7a58f076348a09fbb5b335c43535be99d552298acb1bffb30c9adf1c5fd221417874898132c00b83cb367bd79f734fa1c56cb63a8652ca5a12226961131b14018139937c20c82ae6964e0f4bf06f30cac7382bf2341829236ef27119663c1bb34819da72cf71b3faf01460b9a20440947452b52ca4bb9c4eb9cefb8c1a308b2dcb20dd88270bc71b9e95a2c96306ca17c769d301e01021775238fdc6235f89939b47774b5fb5293d2cf4875a698d33827ea2146b4c3aad66f2c918d9e638874dcc883a2399df38120b8baeb9a52b45c6d0cb2a3c766336d0ba7fbe55ca5eb203e26337d29438641bfb3a29d50500947064e65f7319854b6756b2e40c75b755ab983b52e72f9c5cb293e2aa34cf2b23ef9868278c531bf395434fb347f29c079395f70f62342fccbe37cc7fd4ba1eb49699ed30dfec751157003f8bc438381813d0c555183524ba8a248f531495210a6947ed6963da96c85af7bcb1fd8161a07c707019b67f373c4692c27279e67b677c2c4cd42b33c4662b012ba8a59b19391c25aa846814395119d65b585c39e738359a24bb0d31b266a81471ce25270d0715cac1c473c10270039489aaa70b5cf093ac930a91e9ba356d6a76fbbe8903781924487ca4cea7a67558e55011ccd4190c6ac0d8642357441545b477e0538b31230b07b17595e55340ab681fe860b21b9b893408656f920e8a5599fe94dea1b8ddc7a6eac61cc0457299c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_private_key = eb7abb66c3c749399680d531ce787eefeb5a80c16c6501056eb314568c776fc320e496c7b55b54b253c669126f612c3a5395268826aedda5cea1a7077f946a6cc0435c35955087acaab395328c91c753975b8716b3647ae8d21c75f613fe461216749171b000fcfa3c0ca38e1da915c15578bd102e06234d59e88c51047f68c4cc12c60d0b536b672c3e6a9a322db89431200532c7bcbfc68cf9d775d0d722fe7bb9f0fc7bf8dbc4c19547c1031d23662173c302b23a022b3c0997914347081b7d433834446ea56b43135631932133fad226010a3b6a07424d2c361efa7f27fb65033c17a1ac3ea85086b3440efabba894762808068ff4e1579b356f6a186d96431af9c2a5724625ab88a36a6b3ed4901e902630da4a101b8445be9ba9738a761c74536f911fcb1178a6a5680035ca0d607d77d07046eb8568113cfb4a02fdfa8fc207d0b9db8eab68296e9a8e33b01eb11c81a8a94def449981747cae41394ffc5ece2581e398c319f557448cb4152b301276519810193b864a09612d5b982f8326750dcc472cb356dbc1cca28a145fea0ceb8803e03c36449b16464a673d3c4b67aab5c1d11fdc06377a41846f60c4db0b3a7568060a970c64989000bcab2eea24a0520a3ffc0916ab67e6e557860164b194b59d552c199a0e2803b0fb2b1306ea6b0ee687db661357739a3c887a8ef551a9132473b2c000aca4b859624e690b6eca49b20c43656397168c00e7ea1335f48f473cc018219985d72bced63c23b4c0fe036322e060619177d1984ab885bf11c0cd20f518cdb8a447356847d8b95bd9ce3285702286949e3c61c0c435c8e312d9092b60437531d8490dca08261ba4a57753661b2f853307cfb071fd3b0f0d005d6155b117f298e2a84a3a34bffae668d91b5235192a0b55cbdd5b723e8191087c847b116ceab7292c17480065c93ba665656749c6264ca53a87b27485c0e2c024893374312a58c7c0eca0b155f5cdb19497c08baa82a71908639e45121c827c7666209cc149cd71f50598672893895521a994b9160dd01baf081aab12681a9f26220e65531f389920b110e931401a986b25b24c36a66d747b761bb2c2a09415fed46551c6a26ab62819aa605a84c9d164b5146c6996f3a33475aa76d055ffb45617f256e22028426b71ea1404cecc96aa815f5cc804d83bba5d417caf64731906b8cdfcbfbaca0e7e0c924cd19475a88668c59f24b7b0aee4a63b936942ba263bf4533dd29e7f51760ba638702ccf6472305e5a0d404732e0a220b269affe711db0a8c2db11c2573b7c3a83b673d37ecd8a725553be79755b803cb866a90e12a4bf7d8275fc7ca07cd20ced0ac9a45c54953220d5caa8210bcb3e43289ba03c6c3a982b5b2d4b73853b1b7548f7aacbb0a4ec2bc676c55dd594aaf630ceeee7a58f076348a09fbb5b335c43535be99d552298acb1bffb30c9adf1c5fd221417874898132c00b83cb367bd79f734fa1c56cb63a8652ca5a12226961131b14018139937c20c82ae6964e0f4bf06f30cac7382bf2341829236ef27119663c1bb34819da72cf71b3faf01460b9a20440947452b52ca4bb9c4eb9cefb8c1a308b2dcb20dd88270bc71b9e95a2c96306ca17c769d301e01021775238fdc6235f89939b47774b5fb5293d2cf4875a698d33827ea2146b4c3aad66f2c918d9e638874dcc883a2399df38120b8baeb9a52b45c6d0cb2a3c766336d0ba7fbe55ca5eb203e26337d29438641bfb3a29d50500947064e65f7319854b6756b2e40c75b755ab983b52e72f9c5cb293e2aa34cf2b23ef9868278c531bf395434fb347f29c079395f70f62342fccbe37cc7fd4ba1eb49699ed30dfec751157003f8bc438381813d0c555183524ba8a248f531495210a6947ed6963da96c85af7bcb1fd8161a07c707019b67f373c4692c27279e67b677c2c4cd42b33c4662b012ba8a59b19391c25aa846814395119d65b585c39e738359a24bb0d31b266a81471ce25270d0715cac1c473c10270039489aaa70b5cf093ac930a91e9ba356d6a76fbbe8903781924487ca4cea7a67558e55011ccd4190c6ac0d8642357441545b477e0538b31230b07b17595e55340ab681fe860b21b9b893408656f920e8a5599fe94dea1b8ddc7a6eac61cc0457299c43410677c421f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e9911b6283fc6dee66e16d411fe39bbc9f53c30bb54f05044b96c740ca051c61ce40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +expected_public_key = b0141c2b68b888e674a38351470a3c831923aa3c3e40a2127a28c1a8818d42e4a48c036191681bcf982c0f13a79d643af1fa13eb32444d1577e0c1795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755a8199ec36c2c128c68fa5b5854348d55a1798054ab98a5203dcbcc5121300b15026c8b4d1aa329b804b13e61faaf672f0a304db82cb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b15211950b5551f0722a9b6a7ec554567b2c975af35b6b88041c01a1f182a50853998cc395c1081e0d755d0fbcaf69f85df21567a0a24474571d2f98ba93f37a0f5941fb8204b0933cf3cb20a706a06359cbba272c0df68647318774939d18528b8818ae682743071795d512b29c794cc8a6c0e4b827c1148ebe2a0e72fc50a3f71df0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58cc229d9623983564da34cb71a729abdccc3cf70bcd7d20aeb82c9d306464e132a6b9989c8561d90824f6796420e8b8c08a0bb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943181b16f747b7d04a7f6996983c494b0d527879366c3a4a6872a79c8c3aaa13f11695d36065d7843acbb04014539992ad369024f56636166990c23c661f34a584c12ba06a16aa582c887015cf96b293757a041b53ec695cb520960d959d96f57bd6da44e40024f5e04a3a135a1f112ecdd57ffe459bb22c84008d5a2ee831823b42102017f14a71b1329bddc07ef7bb02e8ba40bfc64362bc369e490675dc68a9c0b54a91b43386cc7a4800c9f60f2a562253904c71924fc7a9257b94aa9f78c6853a85d09ab7b07101b58309424420c744076c446e7e873c67d67a40cc3993d48c1a81495e54a5fb1200d497080bf21b33211e919730dad71c2a1a75ddc983853cab3cb55a3fdc0d778bccb2c42037098956307899123f7c5b7cbcf107fe1788e55c67fa65968f57bd85b53a29005c6a2c2c30ecccbf09904218390fc17f4b07aa2d350e9953705da8bec6b4048e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_private_key = 8ca51836784896f8268d5256f73a3619466dc1317bf82932e4a62b454657b756c17d810928f742105b41ff16531c649f95490e4f6a53b2bc0eb36cac6195ce6cbc974cb032cfd5505fb77bb3a6638a05b23c47c5b387554fc88f70b06feb8a59d039a5b727c2bfa60ba0e785ff0c66cf88078df29f40915713563b7f33bb89a014d27b54be5a37f8fc8dec209b06ac8000c8816ba97e68f6c01766788b1b732893457a38abd2798eb16920678bab9591b9e4d644ea213f3dac45dc5263cf8782b7f9a5f0e01ae409599112c9041a8823a88117953ae944cc0541851719a66a219d9cec69b554112bb861f859050f456c13c73019684edbab9fd1e127703740ce863caaa602e8c2a765f259ac91a21eb5b9db6a6105489b3cf08e1c58a10b35c7341441ede777dc81cdd6c531e4168743731803fc95ead4979e57676d05004a2526fc9369bd86145003a8b6b3bf5b4699745728a64805fb89336ef991ec97233c6718775969164634438c77b7e1b86c25b60967a9a0d25b50c8a19fbc55ab656a9e354e0f7b20233009fe907a92361a3fe60352e25c3a1c06697113b996b867f307712544274a8975a5855cd39180b1644960b0254ccc9b38c3bb140dd38b34a3b220cc5c13104305c45a1a8461340b4b30bd69497bf3ba0524526fdab58d32b8fd3b03e05b61aae5014f5684c52cac3d81ace4701a4b7199c93a813e549170c562432914bfc02f8a28a3a95a3b12150e8d7ba897e634a8835410741001b49dbe6b82bb50632f0846ce6210bc4c35266b3eaf434ccfd885478ab671c6ac1238cd02b3ae1b1b76dd9418feb30498a8683d01044587545ba5c5e3919f7996ce6d51cbfeb65fd61538f8592462ea268d07ad28325094ba467c6405253c07aa405ccdfb9dcaa5993fac5c407ab29192a3b81462b9bb6e783c3f589122e4848f3402c1c63b4e9cb13dcfb894f29c89044b9739b0c4fb19cafed1390f2936f529007c292c5d7cc22e3a3ee04b26f23cbcdbb87eab79abe9288b0534220ac3b8e935cad8a9494f58ab20573155385628508a3d87b6432314054b2623434c540b196d78c8b0141c2b68b888e674a38351470a3c831923aa3c3e40a2127a28c1a8818d42e4a48c036191681bcf982c0f13a79d643af1fa13eb32444d1577e0c1795a6a7bb2b361e449718dbb962d636be1054700337fc3fc7c1955755a8199ec36c2c128c68fa5b5854348d55a1798054ab98a5203dcbcc5121300b15026c8b4d1aa329b804b13e61faaf672f0a304db82cb875b4bbf796599c43ebc26834617467689ae524a33dcdb5916f783b958b15211950b5551f0722a9b6a7ec554567b2c975af35b6b88041c01a1f182a50853998cc395c1081e0d755d0fbcaf69f85df21567a0a24474571d2f98ba93f37a0f5941fb8204b0933cf3cb20a706a06359cbba272c0df68647318774939d18528b8818ae682743071795d512b29c794cc8a6c0e4b827c1148ebe2a0e72fc50a3f71df0b3ba9bbc4906dc30e18c7d6c8850647973e46bc58cc229d9623983564da34cb71a729abdccc3cf70bcd7d20aeb82c9d306464e132a6b9989c8561d90824f6796420e8b8c08a0bb3de745372cb24413a7046ca37ec66191c6cc9b9c6d0975566f996ba038456736973246c44f545222f3afec4567536ab3a09943181b16f747b7d04a7f6996983c494b0d527879366c3a4a6872a79c8c3aaa13f11695d36065d7843acbb04014539992ad369024f56636166990c23c661f34a584c12ba06a16aa582c887015cf96b293757a041b53ec695cb520960d959d96f57bd6da44e40024f5e04a3a135a1f112ecdd57ffe459bb22c84008d5a2ee831823b42102017f14a71b1329bddc07ef7bb02e8ba40bfc64362bc369e490675dc68a9c0b54a91b43386cc7a4800c9f60f2a562253904c71924fc7a9257b94aa9f78c6853a85d09ab7b07101b58309424420c744076c446e7e873c67d67a40cc3993d48c1a81495e54a5fb1200d497080bf21b33211e919730dad71c2a1a75ddc983853cab3cb55a3fdc0d778bccb2c42037098956307899123f7c5b7cbcf107fe1788e55c67fa65968f57bd85b53a29005c6a2c2c30ecccbf09904218390fc17f4b07aa2d350e9953705da8bec6b4048e4cb432a78334058b2ef4590893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433e78d350d2836d1d17e6ec375a0cbe0d6b2afe1ac036272dd41f8aa769c9d0668ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +expected_public_key = 2fa2cee53ab17754381f14708ccbbd3a19ca2017a1637b08f2e9344ef76d5fd0ad937b027ae58787045b9da90acd172d29c02f2ea83b378690d6e694eebc39dfbbb12e13331503bccfa62b6058792c2642b365a9fc687661464768221a80d529dfd9abcb15813a4a6aa012010ec6a008419a6c8238f068671dd1b3bb3b10ba023aea01a90513518d5c6582329ae43c07a6929c3ce1740aabc291e440f909362c7c8651a64e0eb84d82448e9439351650318293010d718e8762c71dbb6cd0385c5be0c37709924bac6b6783c82431527996523ecc9bb462a1eeb0cb6276c344eac257bb4c4ab0124d6b1b7cf7473c050e9cb9762e856786ab1b5a9bcf69fc90318b3352e0481aab1b97279c088b397b419cc4cba756451e67628f535642b2d0cf71644e6a3b6f9b5409fbeb284356812d613ed338cc28babcdd4b6753f4bce7a7c54b077a5f162e96665a3299b938ca48ac0ccc7710bea5384fc4948dc1b56a1c7272bc4a3fdf53706dec2385db3767c4261e98c49164683cfb420c33cf7ed68cffea4f43e41da5ac727e87a981877e4ff12329e91ecd524790c1ab38784d89258562bcb5841ba8f0f17ab17236634a7019a520f48695ede951fe9042eba78e048791896844025a37575b2be610635ad358d0ac7ea3bb93ca4c8dbf6b566d00654f1541919650c4a88c9a19b4444a5cc7fb4ff087552fe1a288a15bb0941f71f4568ad3bd01c1991110bd2f755a9c7806ffa005803733e2e639e2da05b3fc71dd7a42e834190e4872841215454b294bf32a48c096d4476609e792a4e5465d5750aaea38d9eaba07fbb05d10950ce23256727850d97e16397e9376674c37be4fe3187c2842c797ace9475b1b42c10910270d917ab6cc42a573c51339c04c56a6b0150868a9a330620d886a5e2103248043b44e005a7344742ffab697f086526691b073aa70914b391c3cc31a83ff81a11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb07323c74a7892e5b3ed631370a65cfd4b1a4212348e54506648ccf0732a36c9b9cab979ac6c4c16b9ad0138860a392bf49490068807fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_private_key = 3f609cd3a1a40789a492321ce6309782d8a57b34207ea50472820eb39827d715c49809aeef03166b4169624b7aedca838ef52544c8422e4632162212161117187b0501d08c1c20417044a44627449086847b7867e1c7c4522972508856000db4eb0673d0a07ed0d62ed7f46b0c69cdbe2889b295b5efbaac4989629cd74311097a78fca8188460de2087d467b8f382b030e51b2ce940a032675ed9751f6a7411ec0050fabf4b3a39b678719c692a5886a4175261c1a989fee70255666a0071303e5bcc9f3598cfc840dc7224ab0cbf4f547dcc4b1d7bba4655205c5431445e69a221ab1680985df6d28ffa7c01f7e99228c77926ea4ff6477298f86545289603162c418bb33a824a0ffb8c62d9ab5939cd22d56e5fc8b087c96018e46aab76b194a3aba45280f3401300edcefaccc5c66050b6c194124a221be240e1cb736ecb523d74291ef08312b666b6d5287c56a70fa677065149fb030bbac88fafba8174c349b2a760b36296a66cb7ebe9978de623d064b5fbe8c2dceb34ae2882d673a5eca0bd3b256d81667f11d951f26a8416331ddd0c76bab6854694c43ea50fea5b55518989813482b05484532410bae28bb890c15246c4114746e424a8da008f3886c6d1d99d7898425ff68d850bc0a6b82f7f04bfc0216e71280dc6b44930e7a7d5b870eea9c258d7029aa936decb5c574bb1d4d5244d5a1f1f2371e498b70ca1a035d403d6609fb0867e4eec9e4c46650d1368ea70a8193989c4b8b9b782193d15214fa9c37ec64c85741b6e746eed8698cc8bac3bf0a4f8d332d8b6ab888733b0c1158750bbb9e73682879db3091c96244a9bb0c68f1b2985833009978134bb2d64c24f8f60a40df182b8b3abc2a407f765cb54f2af96277e02075271e901cb360d8b7160da057daf95cfc7bb5cb59563a0359800eb78def9bdabb2c655bb4af0e71e98c38569eb74da86c2ba30020276028b0b59d94a21c5348ef34341fe292a1f419fd9d03030dc7b6f525428781fdba04c25d86fdbb3650c2c8ef5153398d322d338cd7c892cd81b80a17b9c4ec77f64d4476698029c9645dc649b23db0e2fa2cee53ab17754381f14708ccbbd3a19ca2017a1637b08f2e9344ef76d5fd0ad937b027ae58787045b9da90acd172d29c02f2ea83b378690d6e694eebc39dfbbb12e13331503bccfa62b6058792c2642b365a9fc687661464768221a80d529dfd9abcb15813a4a6aa012010ec6a008419a6c8238f068671dd1b3bb3b10ba023aea01a90513518d5c6582329ae43c07a6929c3ce1740aabc291e440f909362c7c8651a64e0eb84d82448e9439351650318293010d718e8762c71dbb6cd0385c5be0c37709924bac6b6783c82431527996523ecc9bb462a1eeb0cb6276c344eac257bb4c4ab0124d6b1b7cf7473c050e9cb9762e856786ab1b5a9bcf69fc90318b3352e0481aab1b97279c088b397b419cc4cba756451e67628f535642b2d0cf71644e6a3b6f9b5409fbeb284356812d613ed338cc28babcdd4b6753f4bce7a7c54b077a5f162e96665a3299b938ca48ac0ccc7710bea5384fc4948dc1b56a1c7272bc4a3fdf53706dec2385db3767c4261e98c49164683cfb420c33cf7ed68cffea4f43e41da5ac727e87a981877e4ff12329e91ecd524790c1ab38784d89258562bcb5841ba8f0f17ab17236634a7019a520f48695ede951fe9042eba78e048791896844025a37575b2be610635ad358d0ac7ea3bb93ca4c8dbf6b566d00654f1541919650c4a88c9a19b4444a5cc7fb4ff087552fe1a288a15bb0941f71f4568ad3bd01c1991110bd2f755a9c7806ffa005803733e2e639e2da05b3fc71dd7a42e834190e4872841215454b294bf32a48c096d4476609e792a4e5465d5750aaea38d9eaba07fbb05d10950ce23256727850d97e16397e9376674c37be4fe3187c2842c797ace9475b1b42c10910270d917ab6cc42a573c51339c04c56a6b0150868a9a330620d886a5e2103248043b44e005a7344742ffab697f086526691b073aa70914b391c3cc31a83ff81a11e0b5ff71462915b742d438c6abc8587089d99a8c6f24a6f6d236eb07323c74a7892e5b3ed631370a65cfd4b1a4212348e54506648ccf0732a36c9b9cab979ac6c4c16b9ad0138860a392bf49490068807fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5820c7564d087683c0a4864844335bcbd62afa1ee542c3c1dcd8b72c80824b501c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +expected_public_key = 8529117dcb33b7d246d122ab27cb961b63bbc579c27f644213e6825aa1a0d4b44918784e1954b469f106d6464da8db4de1eb8cab31317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f5a1443629def269cf7b98235569c1b396fa9164e2e0336cc8babadb160b082ba8edb209a426b25c435c35c0bc9b15af0d541d0ea5514ea354b828eb3772ba1ab1c81768a1e286ce2a01d1b900dd1ea9fc6d685f1095efc105b71571ae967bd9f9a02028729bbcb53c6a74b37950ef023b334241d2555845e882de3636cdfd45a76e1265f6937130016f8e1710b748959a8add626cb79b65de177c06ba2cd8dd759d86baf1d9b85f4da3b2ea9049ef9545b72cc0a6a736d5581c57a1d7d966f88c578dae60438292cb3ac26909baac0ec8d74471d511bc7e928b67913c17e4cc26818b2f301299da3910458be4bab41d3137cae0189225890ae91a364dbb683288b8d59b6619bb786dcc98a51910fac5c65e05b3c75a4185b99e00acf009535adc07c269aabec98adb1195ab0b5a623d448fa454e90c2a6be925ac912b086b31616337661d0a6ea7154e937a39d1a60a4b7923f4b2e88438386ec879196cc47d9179d382546168a36865246f07b86e48f3629c5b1bb99c62098d800cf2654acc6fb8057d25cd2d48c2cb71ef0e917bf106f99b35df1830d62226a1f7220be6c1afb229982067439934bd27b56171ac3cde09e2c1b3dcbda08c386355f328dc9d01827ea271a43651bba49a5a66f01966cca037fcf02aa074a7059d69de85961c9120e6d89349ada3af4d41175a6267aacc9637b8cf4d513a8f6b3ebcc9319c25064b337c0e90a88193e79a9810d2ba9b0eb089e437f473b9f5dc4b8eb95b24e1b85c5d0267da39bdf35831c1263fe923a2dc7bd54a5210e38203422a6dde30ff9c59325d36e99973e3e991b4284c06f673751bbc8c99b04c4990610dc2906b27369b72187aa2a13791cdcd47bfb37a19e149a32f8cadd638ac0e071771c9dfc58253a864c0e15cca60514f545cbe161030af806872ca2d0c67f54e04b4ca55f41a54b1de405a22ba275a1b919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_private_key = af54bfc65182aac49a785108f30c5048428b97fa3843c48a4032397b479ebd8cacfc079444e54c4f764574f11418f73c8bc7bef0a18f5ca7a2cbb6312d4c63405a1cb76823c7a53cd301aeafec586e32118d3c7b966a96b4323e86f7846fc634e3e97659455d4cbc3dee95a519452bc8c50089d87440c7b2c0851a6309a07bd99e5e31520eb458b405763c8b0c4a2261b0f4679d70cd254a5484e02aa747c5ea320d6cd5584d517f7a664e2636a891762594d20557177f66d25c2b551f67cab766599d7aca5e6e8475239bb649437de88079c8ec645f423a9b51b8be13bce19579269b6c36eb16e404c2dbbc7ee06c6daecbad02cb8de945c1c8bb2edc298955f825c870bc29e582a810b27cb22c11497aede1b50c477840488f8b5a3fc730044070a30e573275299e6bc2526171255900743bf46c21ea708925a6ae27a8bbf5a3f30c1a5c99b0a84a7e66910a1f85842a5318c24a6038383aaf5940b1c8ac577359778b0f16350e8e582e19db11e13346dfaa90e132186ea660f9cb21776b4033c5c46d987fbdd5370bb7302047336f1066fae34c074a133ae89ad33c7464db9b4de654608bc71de12c64d7cc24801913543c10d6c77e24be428b2f4dd088e5988c5a76a208f517951b14fa95711d9c6fa6b84101139627e645504c00ad5209bf0bbfa7da39688429308c166b264f4b66a851e24828c23c93dac66980c84ca071c2b4a0db729cf2d73fc98855a9e66ff10693bb36756c4bc724f23f30b075927830f3e55c52607347fa7a09459635166c7f05834f2bb84126cac89421627a8217b9aa488161ed272b98973e63906d14f3b03b7b5fed63484eb545dec0ba674119d4c4bec2a844154797f4866af210bab216c1c9441d4694c0c7a969dd103307525d7b4722552b5489e83de29893fbf76498969534f8cd7aa04931758be6d2ac36983d1ebb2de14130de6bb7966b30a996cf2f0c4f83e78756129587dc5e50a40c69402f840852f2543a90e063d22755fbdc909f60b19ceb33aa749674b6bf03a3224e1891bfa641234ca963bc28968c3a598ab042ea5ece8c0b47763fd918998529117dcb33b7d246d122ab27cb961b63bbc579c27f644213e6825aa1a0d4b44918784e1954b469f106d6464da8db4de1eb8cab31317885c16338969e5c546cfc30319cb37a7874369c6a0407b75f5a1443629def269cf7b98235569c1b396fa9164e2e0336cc8babadb160b082ba8edb209a426b25c435c35c0bc9b15af0d541d0ea5514ea354b828eb3772ba1ab1c81768a1e286ce2a01d1b900dd1ea9fc6d685f1095efc105b71571ae967bd9f9a02028729bbcb53c6a74b37950ef023b334241d2555845e882de3636cdfd45a76e1265f6937130016f8e1710b748959a8add626cb79b65de177c06ba2cd8dd759d86baf1d9b85f4da3b2ea9049ef9545b72cc0a6a736d5581c57a1d7d966f88c578dae60438292cb3ac26909baac0ec8d74471d511bc7e928b67913c17e4cc26818b2f301299da3910458be4bab41d3137cae0189225890ae91a364dbb683288b8d59b6619bb786dcc98a51910fac5c65e05b3c75a4185b99e00acf009535adc07c269aabec98adb1195ab0b5a623d448fa454e90c2a6be925ac912b086b31616337661d0a6ea7154e937a39d1a60a4b7923f4b2e88438386ec879196cc47d9179d382546168a36865246f07b86e48f3629c5b1bb99c62098d800cf2654acc6fb8057d25cd2d48c2cb71ef0e917bf106f99b35df1830d62226a1f7220be6c1afb229982067439934bd27b56171ac3cde09e2c1b3dcbda08c386355f328dc9d01827ea271a43651bba49a5a66f01966cca037fcf02aa074a7059d69de85961c9120e6d89349ada3af4d41175a6267aacc9637b8cf4d513a8f6b3ebcc9319c25064b337c0e90a88193e79a9810d2ba9b0eb089e437f473b9f5dc4b8eb95b24e1b85c5d0267da39bdf35831c1263fe923a2dc7bd54a5210e38203422a6dde30ff9c59325d36e99973e3e991b4284c06f673751bbc8c99b04c4990610dc2906b27369b72187aa2a13791cdcd47bfb37a19e149a32f8cadd638ac0e071771c9dfc58253a864c0e15cca60514f545cbe161030af806872ca2d0c67f54e04b4ca55f41a54b1de405a22ba275a1b919778fb4d69f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509bc56eb5880e9d9d0fe7901747f75eca1996c722ac47b76f34a4dbaaee0ef8a611bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +expected_public_key = 27dc0b5977446a8a2769da6dfa5aa672b16fb8b63a7961433811b6f0a973935587f60c8bb78326448a89bb291a32f1406282c3f8772a4e2b43ec8209fe907d1ddc8d47584a822b6684da85a4c54906320a9169118b1c6eaa058dd3233f13922e249932f65ac9f3932253c4c1e5ac9595d5a10ca6cff03403b641ce79252ea2b999365c2c8ae62b4f369c45eace0d35255dd4703d06ae06f22c25b50d312726e6165a968587a206a7ff789c40f1a195076dd3340f0dd8c6b3049be76b2168ba6aced5cb794516432585bc5a5deaf09bc5eb3306f7633c82bdac28bc27cc1924312462e48e6fb087d3a6b61a4a21e1a8917fe4b2c0c13570d26e8830a0e1923e649a756a5216844a368efa096d65a2c4c3102f80841a4211960070e1ccbe6538be5c7cc09469c76a37089a163aeefba6d340cc18ca86599a7eae767ffea39403792853834423920f2e026e2bcb6a40167e1fe504df7908d1bb7fc8c36a68dbbd30e611742bb9ac65334ed34dab7a8258141e0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e27075c73339d38b4441c7a4ec79e1e6a60c88729a26b8a94739c3b807141713650920d6be7c628551cb3169b3de62afbb746323400411b4039c16bdd4c7ebeb039db0cb8e3d1af20470e5a5b154a7040fa650f69dccbfd44119e4371d527822770557158573943683b32a80ea50241eabc322862cdd9924a00443813b6ef4a7b94fac2ba88542b4454ee27b54edb090bb688e7eb1a3fab22a11a065bbb52a66069aed1cdc3e78d36848a1f8b6bd15108a3846bfe14a51d89382d8332bb311f0b6909eed19d43182ea5044db4d43ef3a9173dcc669fe5a8a36abd300378d6342863cb2e9b4651aa8689991557e9636c92c87cef06848d500f2a3cb85c665f83e64eb54abadd777e10a23fbbb1818eac65d928b1f610851fb7433e255efe666daedc1e52e32a9f1a1d9aa4398253a644806073734c39441d511240798ba315599dac72cda9925e5a8a0183867cd442bee54b7a431253e9ba21f2098bb5350f6e048f19a51d90e7cfc408bb040859bbf59d80f8cb2702798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_private_key = 3a77378a267782691cf4b96b2079605ec20b738890d0c73074cc16250bb722d4a07d2c4addab34ed49489873b8b0a1310b96aff2b77e3bac6113f3446aa414d191c8598c8207e8aa35b684e718cfac011ee32093de65346dc1056fe20bd90b0275444605da00573b335670572489ab488243170bc1cfa87e0ea183d691759071b358b94ca4830458737a9ed085d0249a2af3293691bf248016bd966f23077d83a6adad2235c7d1892290a67e485c18dc556a098a546cce24b520f42b6cffa320d91231b2f105fa0a6ef93044cff90a990a12bad553a4b0c1e29761e4b71a5af81e2a8b834a4b2b39b354c7b0719b204f85d259b7a32a08c254c2ec740e27922089cb4e5b5955a34fe9d58cd4c5bcf8bb52453b848c82ae39f0144de978c974b5bbbc7d47b52b62b398b4352e455ccf20f03d38598a435b65dd86bda4fcb5d3a514e5285069b18444823fdcf820e5a093f8b91b7a51313327cd644c19c170ce6fc8126f97664b68a01a887791456e8935022d935fb3fbbd98c45ef57a36edc73dd1468a0e0023fb9b2435b925b1d88e37177789856ae6d15d2b753243386b85bbb879cb48e90a0380a07a7cea4278130f9fb90142e67a9a69bb031b7a7a32aaa9811886977d28922060527175305538d9b1a0b2aaf014c41ff38afba9c2f1e8abdc6bc754ba5c51f2473e378c84db250da85acac43654ac5ad4060cc5fb09c0eb62676601af9c1fee6c8e04537f66a561b93b39da17acc6616abee22692ab867c091f250c5a451b2d181b17fb889d2e91a941d9ccdf639340417641688eb6305bde148e0241cd4818c8f12c5524577a6a4757eeaa2f6fe24084102170b43539f205e7a800c5205e2b036de2302cc7533faff17f72d8a212477187f14ca8a1398a72c77b858becba4d4f75ba02d4b8a640abe0464bac158e531a7b7bd858e20a0159b989b8737698741147062c37b0a030c30bcb2793ce51b28eaa378d2085e99007de2b527396accce8bd1b285b8c2c06f23ca77eb02ce31a1e4a6b53abf43e13a945d38c95f3096a1555cbc5e852fd248cba66991af865a916169e383a3ebab427dc0b5977446a8a2769da6dfa5aa672b16fb8b63a7961433811b6f0a973935587f60c8bb78326448a89bb291a32f1406282c3f8772a4e2b43ec8209fe907d1ddc8d47584a822b6684da85a4c54906320a9169118b1c6eaa058dd3233f13922e249932f65ac9f3932253c4c1e5ac9595d5a10ca6cff03403b641ce79252ea2b999365c2c8ae62b4f369c45eace0d35255dd4703d06ae06f22c25b50d312726e6165a968587a206a7ff789c40f1a195076dd3340f0dd8c6b3049be76b2168ba6aced5cb794516432585bc5a5deaf09bc5eb3306f7633c82bdac28bc27cc1924312462e48e6fb087d3a6b61a4a21e1a8917fe4b2c0c13570d26e8830a0e1923e649a756a5216844a368efa096d65a2c4c3102f80841a4211960070e1ccbe6538be5c7cc09469c76a37089a163aeefba6d340cc18ca86599a7eae767ffea39403792853834423920f2e026e2bcb6a40167e1fe504df7908d1bb7fc8c36a68dbbd30e611742bb9ac65334ed34dab7a8258141e0dbc403ff3bdabb96a17e5516cb86d10c55e9f4a759e27075c73339d38b4441c7a4ec79e1e6a60c88729a26b8a94739c3b807141713650920d6be7c628551cb3169b3de62afbb746323400411b4039c16bdd4c7ebeb039db0cb8e3d1af20470e5a5b154a7040fa650f69dccbfd44119e4371d527822770557158573943683b32a80ea50241eabc322862cdd9924a00443813b6ef4a7b94fac2ba88542b4454ee27b54edb090bb688e7eb1a3fab22a11a065bbb52a66069aed1cdc3e78d36848a1f8b6bd15108a3846bfe14a51d89382d8332bb311f0b6909eed19d43182ea5044db4d43ef3a9173dcc669fe5a8a36abd300378d6342863cb2e9b4651aa8689991557e9636c92c87cef06848d500f2a3cb85c665f83e64eb54abadd777e10a23fbbb1818eac65d928b1f610851fb7433e255efe666daedc1e52e32a9f1a1d9aa4398253a644806073734c39441d511240798ba315599dac72cda9925e5a8a0183867cd442bee54b7a431253e9ba21f2098bb5350f6e048f19a51d90e7cfc408bb040859bbf59d80f8cb2702798f074bd375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f717823f0b58cdfacafc795aea529561d11374f02964cf635c27848671043766cfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +expected_public_key = bd413efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816eb0dbb4a0f5232b0c4b4ce98098441227f25ab91ec97319ff68a916910fd0ca1d5209c3420508b64acec450140165620d9bf8b8170ad328286e49fb049386658179986512fc07d47d49a1aa5bef5a4beb499a007065a79e164a1713804b108a95072ec9c6a1be395baeb09fd9a8e0a749049e405137a5c05c80715f9b30022183ddb127cbb1ba7556302d2b1063b798cf164f0f0bd40a202c13785009bad8769c3155b643f7a19f9509987bc2bccf41a3b9c1b9a844fcc537d8a8a28cce0641b16a0fd49969df2051a6b36b5b58741a0cfd49868bd136cbb4763a97660694539a2025649a7884a64761a1059cda78e07c5abeb297c9e61407ae00606cca7d26c0da8436c4343aa216c6b71375e4c9a0ecfda7697e149b72c025696aba086251826435c79c742058b644b7466b857cb5792c539709a59ab15aa296acc5bf5d30bce8b0b11b56d578837f922a7523927b8f0323bf79ce8c372c8655082901ff1630e0d27baf8acadaf284742e73ff5650a3ca80c47586a1d1664128a4518e83a0e4b13352b4ce5838cde93826f0ba92cd6027d0869bb5342ac1c11dad0938c5ab3a836a646e37cc2d42d3a9324ff0282a4d38fd9055bcaa715e8da77d08434f535465c9b880506831b33174b974d41e680000b5ba3835b457768b3936d3810557e72407d9a953111990c741104fa243a922da7b03d65d2b41438449bb0975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba39277797352d24eb2625645995a12c2e69a62f421b510225ff21b817878aa0031d0f70a68433b422a7360f69abce2bac840b57afda2144aa62949093f643a5cd209486b6cecea226d205ab14e76c17cc86345b0d119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b5420ebc19de137c2b4e55b749399c5386af0870250e853438321ee767012483d8b460239350c82f8700e3568dbf453fa275d5f612ec8fc6b6e37854e8131870862f8046881185c3903440008c4b3464cf43b6f5a80a47c473a6870137924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_private_key = b25157949acc7dab5dfe796ce8902e9ba933ad2c91c1c218c85230c65a8084756151317ea17c0d313375dae0afb6e63971333408c86cc3131c9496ad1f745f96379391c48554a939c73a01379479938a7019f55fe294291eb6793eb4829cc0af6a37759cb7a2cad703838039cd3b9e95da69906b2f4a5661ab57a165db6c6d49554ce7bb2b91a17139bb444764d1e7b92ac88083503876081a36e675d76635808a611b4b2823350d1d01ac8be1c75a3b8a59609b6b2cb553f1c9a016cdea341b7c1ab79d0c5a64bcaf47e0b6c1921e8c701b177807b69715fcbb9954794b68f9435332155b8abd33d128f3e9a4707793d7524290da5fc96b5996fcb62e80c5e6e22183293b2871293a0a13354a6f3de7894a920432ebade7a878c06836e7eb3fd108129536ba88046407a72869824370243f9ad048b144badd49af5eca04e5a74f77bc188c665fabf14b0480b0355c8f8252c3a0c33c77b29f43ca629637af1b724fcb7a27ec876cc099c098e4c469300aebc99497da620a3a0037f79ac75cbd7ae35094e98609e1460ba55ddc32660ad239a6614e0413891e2c94ab73114f1020b9976a3193c62467856ab2a2854859ffd3074aa46de6123d7f64b4bbe83ec9483bec29c0fc472671027e1e4905a2219c67f37f54716f13e0a4ffb57c6b0c1671f874bd7399f94a9d72cc86fde021e5a85919087339560ed10110b430570b7c0a7e8ca0becacc37c732773074a2f1bd73bc8d9e1822015944a140ba72e1293b5a392d00bef7bc9fe6777875f32bbe830edd45818ab8a201113a4e8a441426251cf5c84ef678463702e2c01375a80e7f2b4618430683e88b034b64b4ec7b54030e19a0713b459e0a35b2678c2fe8484fc8717765f774ebab72b05687da090412b669f6747041c01bc9a5c1074077b878732b4b922e58b6b96b45a6072ad8f0b7b88ca7bab621151c5aa666b5a3f550fcb136a3b283562c347063bcd9e7226ff5ac4004b23542057da43f998956a77b684d6c1d450195b2d4216de34512048a166761462b27e3b4c47e475551d33cd9b70d9e7a119d1980270b126e84bb1faa49bd413efb6cc0b49a447a9a5f2cc99d7d5cbfeb4c934ec948064aa816eb0dbb4a0f5232b0c4b4ce98098441227f25ab91ec97319ff68a916910fd0ca1d5209c3420508b64acec450140165620d9bf8b8170ad328286e49fb049386658179986512fc07d47d49a1aa5bef5a4beb499a007065a79e164a1713804b108a95072ec9c6a1be395baeb09fd9a8e0a749049e405137a5c05c80715f9b30022183ddb127cbb1ba7556302d2b1063b798cf164f0f0bd40a202c13785009bad8769c3155b643f7a19f9509987bc2bccf41a3b9c1b9a844fcc537d8a8a28cce0641b16a0fd49969df2051a6b36b5b58741a0cfd49868bd136cbb4763a97660694539a2025649a7884a64761a1059cda78e07c5abeb297c9e61407ae00606cca7d26c0da8436c4343aa216c6b71375e4c9a0ecfda7697e149b72c025696aba086251826435c79c742058b644b7466b857cb5792c539709a59ab15aa296acc5bf5d30bce8b0b11b56d578837f922a7523927b8f0323bf79ce8c372c8655082901ff1630e0d27baf8acadaf284742e73ff5650a3ca80c47586a1d1664128a4518e83a0e4b13352b4ce5838cde93826f0ba92cd6027d0869bb5342ac1c11dad0938c5ab3a836a646e37cc2d42d3a9324ff0282a4d38fd9055bcaa715e8da77d08434f535465c9b880506831b33174b974d41e680000b5ba3835b457768b3936d3810557e72407d9a953111990c741104fa243a922da7b03d65d2b41438449bb0975aa8b1d1c3751444c91359bc3b149affa8ce3413692339ba39277797352d24eb2625645995a12c2e69a62f421b510225ff21b817878aa0031d0f70a68433b422a7360f69abce2bac840b57afda2144aa62949093f643a5cd209486b6cecea226d205ab14e76c17cc86345b0d119aa3f9cb94f5f93164f863feb4b513083c53fab20da3605f83b46b5420ebc19de137c2b4e55b749399c5386af0870250e853438321ee767012483d8b460239350c82f8700e3568dbf453fa275d5f612ec8fc6b6e37854e8131870862f8046881185c3903440008c4b3464cf43b6f5a80a47c473a6870137924c09133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c7a13afefbba39ad59c088825380398f43f1251b83b0ca9debba0102f902d719020a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +expected_public_key = c7c3b4465b0efdac63724548ff25b73b9a0ba6b5004b82a614918e63400146f36aab60c8cdb51600fa1218e9c3d619168d1ca7d1b29a20b995dc254080108bde2836a53c05aae73f95d4997dd002c21c9e16711ddf2603a845a5ad8518a3d3cadfb57a5a994cfa262d51f06d3d1c857de85cdc934bdff1ab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4c3158a99482b7511ccd188b5ad42627a49240257b5bf500e382a577dc57fd84af49731b6a49224815a43d2c6bccf03ed1f09379918c882cbc5fe33303cc37621c21d9e5360b3c4029bc2c9f580c2519591f6ca703283f93e759dfeacfc63101f6a9bcdb30839b1288334562b608b32d211111a79c8c2c4b19a822d18646190051c65c0a42ea51c0009ac976a06c4b3c24ec1b47c117865287b836738473af07f2908935b5c0dbca76c44e48f5478f78aeac138885721e40b8ab84c2bf8c69c3d4ecad4df0ca07e89a6a245bdc46105dd21a9858a819310cfb239fa735186407a88105b3bf156f95f87d9b3b9db0da6bd67075c70384553b28ca89ac9131561b9c8d37a5aef7a4152f6aa0a7f54af2f3819d6ccf8a07d0f4c5310907403020a01e4bb94d4c7bd257ca0944a6aff6cfe00c9182d508ff329505c3cf85290427a2c06366907b2b292aeb2b13b954f211117504a18f37025860cead9717869c60fdea3e31e9845d439989839bbd7ab2222b13fa921133906868e6671659b18a1c0f62d8bbb7b69b0eb62967b85b21375742757ddb960cbfe450b9a415fd083aed8ac0cb05a3732b39453180c97ba6ce5c426392545e2b6d15683300ed697faabf21a2423409ba37a899c602b72a5a4ca1e3a7c4423c5cdc3765d0972f22cb9386bb347617720c6cf9e32964faadd4a625a1586985571d40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041b82479b23f18d51a77f1086098c3a9d2646fea3b822994ef730b97569d05aba38f880909fbc441815850e0beea12403d0024d95c6c1691584c6b548e0068ca7c7333ea8d07f12b615433da2a041572a46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_private_key = 19d08d4d81b080e533b6a900fb54351f55832d411e4334454a1236ab2ac28e6836b28105ce7b4ac3422dd2367d86bcc33b539b7d855838f665d5d684e932870c567838038588508252f43cd214cef3e259d5e4c79f078c3e3a8098834698c1cdb503780463bc8022b0ed36a14fc606d9141984c41a6611723b74c16e4679945a2f8f47493b2072fdbbc93a143185638869515cf62a0fc842388cdb4be5c90d2f4c13a08a330e9cbb5424be008d13ca09c9a9442763dc09ac61c891aa324fc30cedd2a92d488de28b4ed28458e5b18067f11ccb49cc6e9b25d8f444c574a487a95ae047aa9d6070e100611c5c711ad844aa1a79400a4977ba45a1e686b7ba864f8a75188273f3692fd76766135611c3fc37444c34594005bf251571060e59ac3b9be01a7e50cf4809220bd74437268a119c074be236ff5938bea04ff93815b975181a4c996ee486c857608a9119002060bf41a17fe05093dc8cec793e12c3970650197f4b4a9abb63fb0a1c875b54c9884a4d875fbdda9ebdb68fe4c8a7c5d0580401932bf30c5cbc76ba96722cfb3f838b4101b01bfd41aaf542822f09cf33c40d54f32b894577eb3b4f0706a4a2a67f97568e0ef9a9e10331f84994a2909848d5cffbbccc6efa1ba49725b5c92e0e1918a0d1a8bc4746289906f5992fd6b1922e6104b1264b7f96c7156b2d927c166cc47f2b2c4a58c2550c826b3a9c1ccd6c6fb0cc980c752a90e915f8b0063790a7f09008e91b416e18c7eec2a4f30b2e1294461cb9124b45913339132003b0735c7997e44eb318abded91c753527bca55953e71455247ac0b53c05931d5c8715d674933d889a09e05b590315bc710ad73a772ea4943d810869c98767490b96c6ac83b48b21ea171148bbacdc66220b6ec5e98124e7548ea6bc0ff59c883c96ba8aab5969c6e765c2c9e70deaa17d8035164c240eb03a34e033ac4fb78b99b84c7c5a276e325df1ab83b3801294ba6f56988dbf08c57b59202c928a3fc720a842547016580f66c51e614dc9db8166dbb92e5a576f719e1e986ef39578312c6cc59a9671112a96a40ef27084b72bb8b742adc7c3b4465b0efdac63724548ff25b73b9a0ba6b5004b82a614918e63400146f36aab60c8cdb51600fa1218e9c3d619168d1ca7d1b29a20b995dc254080108bde2836a53c05aae73f95d4997dd002c21c9e16711ddf2603a845a5ad8518a3d3cadfb57a5a994cfa262d51f06d3d1c857de85cdc934bdff1ab1b1891a5a37b2e6aca37493d7f6cb86948673a57ab438ab8ba1a7cb98b556ff8bc4c3158a99482b7511ccd188b5ad42627a49240257b5bf500e382a577dc57fd84af49731b6a49224815a43d2c6bccf03ed1f09379918c882cbc5fe33303cc37621c21d9e5360b3c4029bc2c9f580c2519591f6ca703283f93e759dfeacfc63101f6a9bcdb30839b1288334562b608b32d211111a79c8c2c4b19a822d18646190051c65c0a42ea51c0009ac976a06c4b3c24ec1b47c117865287b836738473af07f2908935b5c0dbca76c44e48f5478f78aeac138885721e40b8ab84c2bf8c69c3d4ecad4df0ca07e89a6a245bdc46105dd21a9858a819310cfb239fa735186407a88105b3bf156f95f87d9b3b9db0da6bd67075c70384553b28ca89ac9131561b9c8d37a5aef7a4152f6aa0a7f54af2f3819d6ccf8a07d0f4c5310907403020a01e4bb94d4c7bd257ca0944a6aff6cfe00c9182d508ff329505c3cf85290427a2c06366907b2b292aeb2b13b954f211117504a18f37025860cead9717869c60fdea3e31e9845d439989839bbd7ab2222b13fa921133906868e6671659b18a1c0f62d8bbb7b69b0eb62967b85b21375742757ddb960cbfe450b9a415fd083aed8ac0cb05a3732b39453180c97ba6ce5c426392545e2b6d15683300ed697faabf21a2423409ba37a899c602b72a5a4ca1e3a7c4423c5cdc3765d0972f22cb9386bb347617720c6cf9e32964faadd4a625a1586985571d40cb8895136b47f95ca8688d9e4776d5eb3638f9548ebc7d40acac9f0c6041b82479b23f18d51a77f1086098c3a9d2646fea3b822994ef730b97569d05aba38f880909fbc441815850e0beea12403d0024d95c6c1691584c6b548e0068ca7c7333ea8d07f12b615433da2a041572a46888984d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455dd4cfbc29de3568663a3a044c3f897714363b0fdd3b6ee55f796292d34c7c79b7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +expected_public_key = 83fc2701341ac042ba3987b25411406b32a000a12e00f726799b88f2219ab42bc6d08b3396bb77e51a38808b5a00823d45fa46dc142077ac63dd25b5209b0b35c0a3bcc30537248f568018f1324141404c3a603f8bfb30f675710b33b1f986b78475a2d4b1a6c44b6277b881c8f69c7198657db21fb0a9887afc4c3af212d1751a1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6da906e98630ba611eba0b5d622670b33152c3d91311cab5fc052c0050097d0c9bf0a4729a58b216b92537f21948c865e471276918b712037569a079600b1eb611c8d0424f8903404b9338d4ca368c0a42df6a9b6be6692ba24232c68a82b22076b72c5a71b5cd603f52493beda57f12c660f241a6b772bcf007819acc094e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b242eff33c5263685afe47dfda38a8250cc54160e4c22bbcf9765fcdc1b34a94faa088d4927a6d8121ce556576ae682e5fb2761035981b442245c1d114285ca20b3af733c2d3a8121998bbf87734479505644b568301244e31bbdbac05b8c5d93121668ec64080287ea074f02323a91425c7362428c9637e61bae86d03238c96336081a86198e0f31c17a945e50e15634e23100c6499bf1b58a48813bfbc7ceb3322274329366267132a972553c6da19e13898b89277a33836371084a5297bae0298288fa68a27605a60b274620111d376227d157d066181714ccfd42a3d33882335565f9a0babd7154c5f12e67215567676193ea837ea188def143e98c7721dc539914c678e1876d334fb99627b848616190a9f5371251593381bc933bc47c1e5ba50429b1bf71ae7c11ab43273cde9538fe8b21b310c8da5a68d7828c60761f2178405ab96cc3d179e75837f7c69c0990c75dbc2718003862448eb3b03e6abb535ad733f5701699d543ff893003b3674ce997e0c6ab8b7b2bb834c4a437068c9271f55c2fa3abb4608cc88128b13eb17a2f45a7ea9b85fd3ca8cb70bd8c0578f7963ac76c3d39a44f2b87b1fdc24f15d32f2b38831d55722aea8642a7ccddf2011f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_private_key = 3c401449fa6ba9280ea8570c68ca244bf821bb5367251b1572008b2d86367a8a1148f6391440cfe1f9bd1bd02d87c984286561691145ff82954341bb34406abb2343cb88a74692bf39cb000884ca13cb8186f1a788e313cb739d48e8365659c324bb6b032a85ef37a25d538ccbb2ad678616f52c86093ba9352822b7f9b0a2307a3ff5a17d8033603220424b7485171fe2a14d1f758cae896cad6842a90ca5a7b69789d356ff574607ea1286c1af8b127449abb495b485c7c6078ceb9e70421667968176025913535879e5cdaa4859b6f02d20f67a0886ba71851a21f55d7b7b503785ca9722c76ab06531b83cf1bab17cc0a5b3c263f8593293068d7790270f1723d7713fecf34b93a096e89c31fc52a2dbcb8129133379866f938b71a2f3265f939d741abea2886ba849c991ac0505fb5c4bb4a78630039b0a0cec5064f7ec2a56126665e02afb71c0732625b76b0015b7cdc3bc16e6e6ad06914e28364fbdbca2c1a653b9a8899f236bebf770e477abd1dcb937b7510d7ca3a00aa093cc9b62bb6407e00cb36199d077856c4682ad78b241cb9c2537cd9591bc4b49798389b3ee21964815a4b6c0ab98e7b318600a0c663e54522cdab923cb809937f2b902fc0fc90bbbe5d48a2f489a857377509b8b74ccb6ac875e07c3429c728943087ae9f5af33155ab0eacecc1445836404b98284acc63a385a2a55a82c758287cd313fbc91bab8baa4c7d3b3ea5412a496ae64a59c58132dadb408552c29fd34bf4e73927b16c81d47188954c0ef9039add7697a9b6ecc7915131b6c6cfa335c3b016d53b3547669d758943d316ad65979473692bde8725247b333eb412b09389e55c97f655d20f9850b1198b1c358a3a87cb93cc47a91ad29b7c9ac7110c886a79a39bcaa68310ff5c9dea81b0c1c37004021ef7cb24029987cb2617f842f2f51417eb51f39ca7aa50c4fbbbaa51a1c97c4f00e582060e95ac1ebab6e267c8367b7365cf43986fb0103a192a0028ca2205a07160e2d0b4d2d82602b288d89f0588e6935054ccbb773aa6955964c637efeb889495145c629794692a20a13b9b9732083fc2701341ac042ba3987b25411406b32a000a12e00f726799b88f2219ab42bc6d08b3396bb77e51a38808b5a00823d45fa46dc142077ac63dd25b5209b0b35c0a3bcc30537248f568018f1324141404c3a603f8bfb30f675710b33b1f986b78475a2d4b1a6c44b6277b881c8f69c7198657db21fb0a9887afc4c3af212d1751a1d58aac3c8a95494a82d737c124347a06b93721c50b3d5a62773b756a79ea7796588754a6da906e98630ba611eba0b5d622670b33152c3d91311cab5fc052c0050097d0c9bf0a4729a58b216b92537f21948c865e471276918b712037569a079600b1eb611c8d0424f8903404b9338d4ca368c0a42df6a9b6be6692ba24232c68a82b22076b72c5a71b5cd603f52493beda57f12c660f241a6b772bcf007819acc094e4cc63147359b43a81b6a5425487275da3146bbba33d7a08b242eff33c5263685afe47dfda38a8250cc54160e4c22bbcf9765fcdc1b34a94faa088d4927a6d8121ce556576ae682e5fb2761035981b442245c1d114285ca20b3af733c2d3a8121998bbf87734479505644b568301244e31bbdbac05b8c5d93121668ec64080287ea074f02323a91425c7362428c9637e61bae86d03238c96336081a86198e0f31c17a945e50e15634e23100c6499bf1b58a48813bfbc7ceb3322274329366267132a972553c6da19e13898b89277a33836371084a5297bae0298288fa68a27605a60b274620111d376227d157d066181714ccfd42a3d33882335565f9a0babd7154c5f12e67215567676193ea837ea188def143e98c7721dc539914c678e1876d334fb99627b848616190a9f5371251593381bc933bc47c1e5ba50429b1bf71ae7c11ab43273cde9538fe8b21b310c8da5a68d7828c60761f2178405ab96cc3d179e75837f7c69c0990c75dbc2718003862448eb3b03e6abb535ad733f5701699d543ff893003b3674ce997e0c6ab8b7b2bb834c4a437068c9271f55c2fa3abb4608cc88128b13eb17a2f45a7ea9b85fd3ca8cb70bd8c0578f7963ac76c3d39a44f2b87b1fdc24f15d32f2b38831d55722aea8642a7ccddf2011f83a740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f29ca90d64e28a5bbc54c36053ed333c530f72549c2afd77b10c2944fc833408faf48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +expected_public_key = 8b49619f318f10025f45eb7f63d1875e49a296eb1ef5586a9ddac4a59bc96cb01e0af7655b052f9a08b861f0573b8a64295315b76c3b0a13cadfa47e02c61825226d3fcc25202a862e509d0ed99521b1c46c7064de830cf70497c934c7811733e9c70ec2916075ea425d3a0d03ea272bcb0f294aa32f1541df2bbcab251e9173701d8cc678009f0323677c2b0708a246408b4f37e95c170311bb15787e9b035ffb823db6cd02e4421f3690644cbd4a413bc7e696d7491a6ed4018091a9be8b149ad93c49f6424c218803b72c146cab9721ab22c347787090d9016199e65940e19d6902324d138561592a0901700dc54058a6ab298b3d62453865ac29bc815e65582f9b8bb6b5e44c12316de7169f4988c86f953a61a313e4a2734fcc24afc60f6d22491e97bc688c528ae661c9923d587bb11d512c835a9fbb314c39109c3ca2166127084d282979304265d8a78ef343bee9baa7038b9dc9517200c4a049613c936f80982efa61a3c0f18edfcca724a43c79ec2f03b99b656941d5cc040ba07c8d2668085a1e1d7a8e9448767e32c86315410f590b03b993f5c21665a7339db6386e923f7b50809d528772c27660615acd53a9753085e7b9c025b76b952518b5b11a778a880350aad71b2df3260633a570250805b4b0c8887268f1a572c86469e4a75194d50a6e89bd4b2a6d4d09698b880dff136def5b03e66726dcf26fd4911bf3502ea40b0ce71c2588a62dd378447c5477de819baf0795134001bd1250aec31f39a25c98c59938d97390a309ace0bde67b3d13cb46e89b3d7f8369fd539b639164f9825900b36895bcc60fb98bc0a28110f3a7af4070c6c72d63096946423ef49269176a529b5792e4e10deca940564906a29ca1b6e95352210992718248e664a65263a235b17293b6f4b45836166cc461ab04f91fd9e7ca24a891e44c2df9684b85a5845efa2003709b07a596f36aaf9224ceb70c98bacb06d0a1be3b0a926d9c537223097f420a0c1a1dcf360d87d0825a417382c40f297a989a7bb827ba5eca46395e4351aec09420405e9a919f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_private_key = bdb32bbc8a7399e7a4e9ba59ac9030bc29a6f85c8fe2418c2aeaaeec3509e789a854b7126cb5402c185074a72c4f2a97fa34712ec219a8db1653d214a9c623bd093dc15635a8675beaca02b1b8b065000229464fbb123cac72384cfc5f0205b76abbc3fc4b2b94353d3be038ca780fb5687332279a6fc379ce9c28314c4c4347268970ca5b3c084eda04d8438961f4bdc40ac8bdccca6f14b4db7376f8379b0b5a329c4c5ccc975ed3d85e5ea782ff7a1e23c6491be04f84384e0bb56755b985f8ac2812db5e6a08342772a66fd2a2130b621a84578d444712ac76f3107e1ba6366291a325cb4d0d836427a4a27f919ec234bcde6932f42446d87140e2798837124f3f59045a45993fd82388a2702b014f956c59f7c85c3eab0fe8b948b98714c7a460bd844f7f0a5f0d2aa1b6e0b92c934c28f5a42bb4a08407290807ba03605f676732bf6259ee8bafea9445725b20dcb23b52f969d67c3bf7f6c1b354a315dc2dbc38bfe501a5ed1266b23624c1920bbf493fbd44895607474a455544da28682711da721257709e616b504a5195939621e8255001c281757c4bcc85897951c6026550085460e3c19b8bb26374c24f4b245710c450ebda82cc8abc28ea0b21680bdc26948fbc6e13cb5dbc89b4fbeb5dfa4c338bdb3290d834eb06083b5c4655c571cbf03503404de4860dc80934b2252555b4446cdaa14ea30e2a470ce2715bafb5cca084a7bc5595015892830b4bbd362d487c7cc74095e4e7bd1ad7c95e227c25a96621637edd1b7586b026b32b1f2034075b68406dfb7c81c9ac18e56d12f96cf4e4ca77e280350a35c20cc3fe48398ba14050fa515e116dffd8106d815deb282dafaa71f9dbbf5047125512268eb41e7cb16ec4904d80a6c15d1a130c123bf3f4c99b95a569653e5485a5ce9a6396ba91c3130ead31ab5afa2249d0ce9abc0e27f451283343430b8909552da1db0662330f64bb7ed34c7343e7b61560c1e2e601841a90f21cb177fa55a0bca3089462b8b61c8746726b203ad1581ff830b0caf3067130099ce24fbd550e1a6b325d4a71ea542999f87955a986050b0f8b49619f318f10025f45eb7f63d1875e49a296eb1ef5586a9ddac4a59bc96cb01e0af7655b052f9a08b861f0573b8a64295315b76c3b0a13cadfa47e02c61825226d3fcc25202a862e509d0ed99521b1c46c7064de830cf70497c934c7811733e9c70ec2916075ea425d3a0d03ea272bcb0f294aa32f1541df2bbcab251e9173701d8cc678009f0323677c2b0708a246408b4f37e95c170311bb15787e9b035ffb823db6cd02e4421f3690644cbd4a413bc7e696d7491a6ed4018091a9be8b149ad93c49f6424c218803b72c146cab9721ab22c347787090d9016199e65940e19d6902324d138561592a0901700dc54058a6ab298b3d62453865ac29bc815e65582f9b8bb6b5e44c12316de7169f4988c86f953a61a313e4a2734fcc24afc60f6d22491e97bc688c528ae661c9923d587bb11d512c835a9fbb314c39109c3ca2166127084d282979304265d8a78ef343bee9baa7038b9dc9517200c4a049613c936f80982efa61a3c0f18edfcca724a43c79ec2f03b99b656941d5cc040ba07c8d2668085a1e1d7a8e9448767e32c86315410f590b03b993f5c21665a7339db6386e923f7b50809d528772c27660615acd53a9753085e7b9c025b76b952518b5b11a778a880350aad71b2df3260633a570250805b4b0c8887268f1a572c86469e4a75194d50a6e89bd4b2a6d4d09698b880dff136def5b03e66726dcf26fd4911bf3502ea40b0ce71c2588a62dd378447c5477de819baf0795134001bd1250aec31f39a25c98c59938d97390a309ace0bde67b3d13cb46e89b3d7f8369fd539b639164f9825900b36895bcc60fb98bc0a28110f3a7af4070c6c72d63096946423ef49269176a529b5792e4e10deca940564906a29ca1b6e95352210992718248e664a65263a235b17293b6f4b45836166cc461ab04f91fd9e7ca24a891e44c2df9684b85a5845efa2003709b07a596f36aaf9224ceb70c98bacb06d0a1be3b0a926d9c537223097f420a0c1a1dcf360d87d0825a417382c40f297a989a7bb827ba5eca46395e4351aec09420405e9a919f62da58d9443646f48f5b863002d7c24dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccda073c98794493ec169c78eb75a39c1594ccfa635b8707325e0ab6cb8576e30ce6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +expected_public_key = 5684bc32ba5b14f6999a9c794f0c6af04803fa57cd54278313e99327d579b217682b1b86dc02431c6aa125062367798f2c7b1ee7f907dfe42736cac924d169351853f15b944578c5543aa27b626ffe7b3114a11805d8a3fd464ec46b912ab89a3df2a561855fbcb3820f4c11fa7b5e3727612e685830f3aea6c9881bbb06eba102e3f53e6ec502a4ec98f9c1af0d564df79c8d7c403c4843cd6d05732000c6eeeb17cae7032fdcbc275949a8d0501ae182cad756808cace516b72696c618b319f56615bfd0472c76a5b3b4b6b2471e1955025139c5805c095867be34657c5af333c9111b01da84198a8d33655a37f6aa3f35b7e6f34b1e2b158987ccae22198ae605a9a86fb3985f189292785a14fe2a4de8e245a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578b21260625b7ba7339057a94435966df3033c647beaac74bc7014b01dc539445c77509bd481c525a226dd44966feb66684644f598c9493346c9071b16576978f477ea07862863191e02805fe4c54f4153749b222a001af7396a2314054548203bfe66080cc0ec95c2b86223ed936268fe418486a58afdb9fe8dacc49427597e4198ac4c8dd747aa56cc22e38c7f140988ee37dfbb251762868915b6ac205a006846d74e8734a930211941c4e5721ff281551605866db0f6bfbbc9fcb649b45249b9610e647c827cb983d61a6c9e717206135e40780f99495aa3c9c6b619e47b40521db992e5329c4d3c894342e2ab2808c630d9761ab13416c55fa1f1ee2b7c918bf78832b23bc4561f6cade041f4223067db18033eca02d243811132c5d98acb172bd825660e07007125b7428f7403bd2c19f522588d20413162253a95f3e54738ae8694b7a5bd13c7b0a41ada087a8cab72b6927b3ab614cd6a00a00e2545fc7ce547a2f3b320b9711167b694c75ea6494047a8b6c07df344dfa099482d322fed5792d1507b801424bf50fdd2088c0f18a9bf31aefa239faa50c01c8866d0389eca7a521cb9028f94aab585841c021dfe04a008a8d11d23d534105aafb413450a2ebe6918eab0e641bac2d000d7fab0ad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_private_key = c6420c2d0681c74c90b9ba6bd94054efc357c500bebd15a0ff4a1216271617e220cf7a6f46fa77636c255e9885418991220278023cbabe86770b1c9761171187937c00fdbc10783f47c7388d367b03756eb2804cb53c8cc4989ff3cba449014835b493a452180da54877a3a6daa63357d2408e5aa0a274175e427721989f954942ae7909dbc2a987904946766eb8971a8f1277f4a155e792aaba1cbb9cd09647d589e9863b5bcc2918150444006b509884c2a96a817c9ea900144f834b0cd74ad0121bc1b93f7388925523711327588a74a58dfb7780003e5f2830f15507fd2b5057e5c74e306f8f26844994049b9c5c338909d867c547d64ea6a691613067d3670d8382450f191e206187912425795bbb31d7af1c22a99cb72e05a5a768c855af3a0ca56480b8db26ac36ce8b582b838b8a488c4f744ba785b8bbf4eb4578985f7ba29f3ec60541fbb4a47a84a5504562b1c36f24c0569a7f24998d90c9b1e6d5393dc96cb1748eb4c5c963e46431d45f70b536a2db0132a44a9a98af50087e88a33002a3acd1875fdf91322de0347929354a6c5bd52585fd97c8d111a5494ac1cc269c075ac6361b71294494075043ae6b1039f28a51e51368c419268c5001d44d680c0bacb1304b7719fc6813f9b152764b80ba56588250a035822c4760082a265a7f60ba94acb1d0f00a6b10068f832f4496834e505bbd4a3bf2262b53998001a6c87b0b6abf07184b302df8c04b794079895157cc1211fc6c4e87035dfc08105ffcb811882b3a08c6060b526cc92916131122a449057160dc03c8cb985d921881269b070c35cfba1a95412b8c3f13b63d82641b453bfb76ad4181573a27b1a31c411ebc57594b742e53424c549932624b0675795d568cdbea4803e2180b084a52bc7653385ee4801d09014c0f63c8bd8c7e2d2324eee42176d9a1520185a4cc255b0471159cbb29708183b72d6a22aa3a55b672e28d6f7066e2d47270141c809a86e60389d838c0cee42324b97cf9dccaf435caad008015e83c78217d84ca93dfd165f41c68a7f66c98f21caff200c523c7291c57f8786cbea3734899705684bc32ba5b14f6999a9c794f0c6af04803fa57cd54278313e99327d579b217682b1b86dc02431c6aa125062367798f2c7b1ee7f907dfe42736cac924d169351853f15b944578c5543aa27b626ffe7b3114a11805d8a3fd464ec46b912ab89a3df2a561855fbcb3820f4c11fa7b5e3727612e685830f3aea6c9881bbb06eba102e3f53e6ec502a4ec98f9c1af0d564df79c8d7c403c4843cd6d05732000c6eeeb17cae7032fdcbc275949a8d0501ae182cad756808cace516b72696c618b319f56615bfd0472c76a5b3b4b6b2471e1955025139c5805c095867be34657c5af333c9111b01da84198a8d33655a37f6aa3f35b7e6f34b1e2b158987ccae22198ae605a9a86fb3985f189292785a14fe2a4de8e245a1dc45513ba55487a6d45940e62b6e6c95cc83264c913c578b21260625b7ba7339057a94435966df3033c647beaac74bc7014b01dc539445c77509bd481c525a226dd44966feb66684644f598c9493346c9071b16576978f477ea07862863191e02805fe4c54f4153749b222a001af7396a2314054548203bfe66080cc0ec95c2b86223ed936268fe418486a58afdb9fe8dacc49427597e4198ac4c8dd747aa56cc22e38c7f140988ee37dfbb251762868915b6ac205a006846d74e8734a930211941c4e5721ff281551605866db0f6bfbbc9fcb649b45249b9610e647c827cb983d61a6c9e717206135e40780f99495aa3c9c6b619e47b40521db992e5329c4d3c894342e2ab2808c630d9761ab13416c55fa1f1ee2b7c918bf78832b23bc4561f6cade041f4223067db18033eca02d243811132c5d98acb172bd825660e07007125b7428f7403bd2c19f522588d20413162253a95f3e54738ae8694b7a5bd13c7b0a41ada087a8cab72b6927b3ab614cd6a00a00e2545fc7ce547a2f3b320b9711167b694c75ea6494047a8b6c07df344dfa099482d322fed5792d1507b801424bf50fdd2088c0f18a9bf31aefa239faa50c01c8866d0389eca7a521cb9028f94aab585841c021dfe04a008a8d11d23d534105aafb413450a2ebe6918eab0e641bac2d000d7fab0ad265468e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0c2aa254714dac09b9e712572b24154be391063afd3cd8cf4cc4ed8ef21f0cfe55a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = 6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +expected_public_key = 9a3aa452bbcdc82111a6eaa59b04ba8a78bb9474659cc944e7a883780815b899cc64219dfc583f0ce4103eb04ea7e60e2c627a91b28a32843cb395021ec544005326f12b53144ccea0096d8b186fba2ccbb9e4197a43406fec09f53abac00245ce1a239790ca622401df204a90b4a438d33391dbb10ce1aed56456f4238af548881d188f0976887eeb672cc91078474cc2c289de2459513ba16458aa5ff06ea2746d4293b7ec95078d9346d0197dc9a93b2c153abad1c62758cc2f57544f37cc9597691047acfce10be1246fa51b056ab87f24c38a0fe36813316191612e9cd7a26b745f4c51a1a164422b4502b073185a93725bdb606ad6850ca5a27f7c2e8002aa709517783232514309b3c280444c0706422652b170011122e0ca821b5117e530ce07282873ecaa7d751689657aefd5575a7ccb65515e1dbb647c31b1f8578120252aceca821df0416c6780b9f9988ab68c72c73538ca21687cb4654667d3e9bf8a0bc6263053766c8180b8079aa8c975d867b36b45bb709436265ffb0524a0b143095351c90541f8437e756a028be92910341db30b8a94290cf1f9042b6bbc99411b72176e7c5a830be2569b695e40e63122e574e061278a35c607ac8d491b60bd96917d81154e9a244dd014ee85ce9b0691c21c08cf2b7143b21ebbf71412b873828a66286cb2b4f11c73954aa64b1717769573aab29de4cece271cfc549f7f26aeb28360d22926cd16cb67f0798a1c1a03f706cb3b37ea250b75b1b881c36c86461597292561503e6f3405b19a3fc3a8c229d51b6a5391964a4c05db926ef13401250e4a8235f8ab4fc3039f61446f37c1c3fb01b626e725c8c5031db11093017a0bb5905fca5a2721c35ad2100a41567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a3751bbfa83e7237329a8c118b7b7af9816e0922661869a2e68c7deec83545915cb11570a4737542ec9ab52246e7b58c0df812e2672f86ab92c788257f69a0f62b8f7757489a182de8f626a4a91aad8a06f9013a9ba28d3eb6617a21c9070cc65e3551dffbb66ea449221c17efebc429c489fe107bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_private_key = bc6b78c468375dfa71b708464bb934109c1720cc0b3f0b3165d968390c9dc90584d5f093ccab5f42a44e54d61bab919f73dc93c7823fc9a36ff8c67e5e840aaa5282d035ba6cd41f12655b0d9631cf3722c669bccd01ae3129ba7c1ba1d95544a3cb3c2eb94e4d305948840680e8adc651aa42712358a6419ac5626c52c0b4bab13c03502d882a33b710fcd64a16838e38c682e3a3968f5044dd968232599b5e134850e874aff2a8243ba3869497502827e87282fbdc13040a1569c5023675036364932c445073ba7749d470f98751f6471b4c198c3cb69cd110bf945b1a43489644d0bdb231ae1761a5eb912df7ba8c3f815eca6c2cf71907c6bba149607734a412e2a4587ba64900453600ac72f6740b644265a563ad17f3c4ba328caba49393d4c201c8a03079b482a49188d249869326cc5b7c510258a533416d508b62cb1bae79b361b6b78629aac2f0c47e056e2508cecacba42e0cca57a8c182e203371c7533d3454db6585c855328b31dbdd4bd8c232ac8263cb960bfa9e53e4ba733ad822e6919afa507753fb19e279637d9999e2fc948304a4bedcca20f820aceb36813a36695ecae0ec790ef810d4a2c8bd940b6fe3163dcc5b53e20b608ca76d6f70c6419c1c0886683e506f130315a600d8034b972959d42008d5912c799134eda79c0a4c6324f636260778832358211e3a4277268b7074f04e983890130c85c8545dc374e61cd9c5483430760cd3b218c887c22e0c2dc4c2b8e275c8851105fc08fa8609bf6165a029a153fb38282240ed44126379143a454245028c222c65cfbf2824cd61bd3474e59900e162703adf13b1b394caf948f8cd070e22c78c6a17336c6863d360d2bc08848f964fba4a0aa4a181aca56643667d130267f274446b7020c0b4d9dbbb025ea3f90d5219e753391f2b3d489011a1c34cdac46e30b4de544ae19b530d46571d8c6beddf9c62126089982a02612181bfb9f3913caf9e0732519c5208b2a52a53fcd394583762ed3973165187505f2274efa03b6a79e6a39297732a880638e2ce18178420621e1435e919d00e092cc2571d8f09d5cc7b19a3aa452bbcdc82111a6eaa59b04ba8a78bb9474659cc944e7a883780815b899cc64219dfc583f0ce4103eb04ea7e60e2c627a91b28a32843cb395021ec544005326f12b53144ccea0096d8b186fba2ccbb9e4197a43406fec09f53abac00245ce1a239790ca622401df204a90b4a438d33391dbb10ce1aed56456f4238af548881d188f0976887eeb672cc91078474cc2c289de2459513ba16458aa5ff06ea2746d4293b7ec95078d9346d0197dc9a93b2c153abad1c62758cc2f57544f37cc9597691047acfce10be1246fa51b056ab87f24c38a0fe36813316191612e9cd7a26b745f4c51a1a164422b4502b073185a93725bdb606ad6850ca5a27f7c2e8002aa709517783232514309b3c280444c0706422652b170011122e0ca821b5117e530ce07282873ecaa7d751689657aefd5575a7ccb65515e1dbb647c31b1f8578120252aceca821df0416c6780b9f9988ab68c72c73538ca21687cb4654667d3e9bf8a0bc6263053766c8180b8079aa8c975d867b36b45bb709436265ffb0524a0b143095351c90541f8437e756a028be92910341db30b8a94290cf1f9042b6bbc99411b72176e7c5a830be2569b695e40e63122e574e061278a35c607ac8d491b60bd96917d81154e9a244dd014ee85ce9b0691c21c08cf2b7143b21ebbf71412b873828a66286cb2b4f11c73954aa64b1717769573aab29de4cece271cfc549f7f26aeb28360d22926cd16cb67f0798a1c1a03f706cb3b37ea250b75b1b881c36c86461597292561503e6f3405b19a3fc3a8c229d51b6a5391964a4c05db926ef13401250e4a8235f8ab4fc3039f61446f37c1c3fb01b626e725c8c5031db11093017a0bb5905fca5a2721c35ad2100a41567eac8a1f5cabcbf79c87d370311c65fdb69f8f94b3a3751bbfa83e7237329a8c118b7b7af9816e0922661869a2e68c7deec83545915cb11570a4737542ec9ab52246e7b58c0df812e2672f86ab92c788257f69a0f62b8f7757489a182de8f626a4a91aad8a06f9013a9ba28d3eb6617a21c9070cc65e3551dffbb66ea449221c17efebc429c489fe107bc50a755e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a18aaca951e0573f28d50831960a28dd11126f0eb080afc55f394e8eaf6379f6ebb9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = 2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +expected_public_key = cb0842b8b213052794e18787efe902d94c88c0986acffc72dac4505e4c36cc7b4990353e249112a8251e887aafa1ccc9c627948179a747b5cde3b0409d5158230b56ddc86cef9b241c044fb3d523fb909ce0065e260879690bcdf70c33c24303f81143624446fba37748f820cdd97e50d7a3bec058c404c458294eb812908dd87e4d652d51824518b3185425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444412b20a802c399bb56f461aa7631603b85c18a9bb7c83f6c825b9a421e59718b43d745c3667781f819b2014051bd51758524bac2dc9176cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3555b1950de9907289bdd8591f5994be7f920d25940baea14226cb6907aa5ec878ca37ea698c84819b62c2e13115de0ac334169f3107742f42a9b02912b74c39ccf5181ec5c0686c785e246c424143f5363900c7c22df505d1308f8483108f31003a126401950e2afca878443722b30246344ec2290fffa542d6598f14e803f9d91e5d050541fa2c52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b5491149e25746e262193965815570b9d353eb1ac9ea9875323a33fa4878b06054e3867ad9a302b6a43ff902453a92517c7055b2261c7ea04f3f6051c16aa727c169c421a0bcd036b2eac82adc3efde4bc28381589f36806189b780c327bf4b4b9b11dbe036557cc38898557a8a48693fa70984aad327078c1f851ef3409ce0348c16202385c22a70a0c0d54a7e727c0fd386845890df7687a6f65232a327d8b778eaf5a29f43787646c8eadba0a1a9b5c2a6473252aa6f12954bab410e4aa4108b48f618ba595159ea8737c7870ce4b0791706ac871111b39f71b0a394d0482c5d61c4d4d5b3ad0f5936002477763774cc2a06e7681d616b12cbb18c9e0681eb66a724123eafa52f63b2774829a373ac8211ca3a9369f128b2c810496c8a9b32d0813bfc2ced0904cf0bc24222b96ac4897a7f4686b5b2118780b656406cf42294579036dc995c42089648b63504b756b823d22c54d2fd7428bdcaf74113d6345c1eb505b843291a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_private_key = 5722777c9100b2289d443400f2b5aec17c0f4f87a49568870a50ae1e30cb3f051d541a1a5203858fabb4575b472f9b4888cb5ab3900f1e316fef1a89d041c2868b26c7fca4b2ba6fc0e87382eb43e8bc99afe986b26164b5709cf6f5ab83996bdef929f67763d7f51083a414f786508be47c908064d47b7cf0b0ad934c03bc6a6ad89247708c47b49ac1b0cba389eb5281b8275cf8334e89907ac298b86866d2ac854bdcc0d53241d2db6ba1a84051fc809c224ed1c93c0ec67ce9e13cf2e05dc2eb30f19615207c47c69689b780b695f8c70d7970378455be3728c2935bea297b45e9c063025d8309c9037a38364a7cb9fbcbefcb959f64723961adaf07a62d38a961d408cf3276a994b4ad2b3914b63cb196c71be49c9ca4141b02312a5ab1a2b6ac38d13046a05752e431529b84d7b57c75e27404630cab837bf3d32bd41cced982c3f1b7cd1d534feb414f83870df581bb741a3a88515523143dfc353e4c6649dae801e4b531af1164ac2c8ea6a44691998bef1b09a38a057344badb07cc8a2756b9351c2a2c70aee67555e391c3251a997a5071793eb2d508698ba8fc18cd9690ad5af22923c402a951a724931bb395127d63a1acab2a24060e72923cecc40892b04b5cd94a15585f045a9aeab96e1b3ac25eb0a3de579964aa4c6ba5107b41b02e36335f42ad3fcb15849425d0937205120427494953d43ceb514d718406b7f40cfabc5c57911a27b2338c14ca0b505fe26296e259b6b61c73b57cbb9700cdf318359a4742b55a7ebee072280cce8512842d523dc7b969516345812a6585d828fccc8a85c6403decb0b63c9b6384c3d0fb224c2b53f9534881a01c0a642c8064b17d2410d4b73819bb81257b58ca7b0021f6514d7c277c3a751e323ab546b86812a8d660cff93cc3b1e85f9fa0c5da791816c864533410e2345a3b36033e97aac1bac96a280ddd70908b68221353526312cb836915d7352e453c069ea78d8d135afdb8208a16a6ba8b39fbbcafb3fa54e9f808c2b28d63079b5d3b990cd4a94331a9020ac8c37742c9860e487931ef9b9088e5c9f55265adf006025a6bcb0842b8b213052794e18787efe902d94c88c0986acffc72dac4505e4c36cc7b4990353e249112a8251e887aafa1ccc9c627948179a747b5cde3b0409d5158230b56ddc86cef9b241c044fb3d523fb909ce0065e260879690bcdf70c33c24303f81143624446fba37748f820cdd97e50d7a3bec058c404c458294eb812908dd87e4d652d51824518b3185425afa4eb9596c38c08068f21e79a1f8c91903834d2db720a285f65444412b20a802c399bb56f461aa7631603b85c18a9bb7c83f6c825b9a421e59718b43d745c3667781f819b2014051bd51758524bac2dc9176cf3a54d379f9efb915255ca5d14ceda1bb17f25b3d95645a1ab3555b1950de9907289bdd8591f5994be7f920d25940baea14226cb6907aa5ec878ca37ea698c84819b62c2e13115de0ac334169f3107742f42a9b02912b74c39ccf5181ec5c0686c785e246c424143f5363900c7c22df505d1308f8483108f31003a126401950e2afca878443722b30246344ec2290fffa542d6598f14e803f9d91e5d050541fa2c52fc3a5f2ccec895422f0bc3af2bc98c5738db99a5b5491149e25746e262193965815570b9d353eb1ac9ea9875323a33fa4878b06054e3867ad9a302b6a43ff902453a92517c7055b2261c7ea04f3f6051c16aa727c169c421a0bcd036b2eac82adc3efde4bc28381589f36806189b780c327bf4b4b9b11dbe036557cc38898557a8a48693fa70984aad327078c1f851ef3409ce0348c16202385c22a70a0c0d54a7e727c0fd386845890df7687a6f65232a327d8b778eaf5a29f43787646c8eadba0a1a9b5c2a6473252aa6f12954bab410e4aa4108b48f618ba595159ea8737c7870ce4b0791706ac871111b39f71b0a394d0482c5d61c4d4d5b3ad0f5936002477763774cc2a06e7681d616b12cbb18c9e0681eb66a724123eafa52f63b2774829a373ac8211ca3a9369f128b2c810496c8a9b32d0813bfc2ced0904cf0bc24222b96ac4897a7f4686b5b2118780b656406cf42294579036dc995c42089648b63504b756b823d22c54d2fd7428bdcaf74113d6345c1eb505b843291a663a4a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273f15a8fc937b12ff78c54fc273fcd7dd5611e5835472ed377652ae64495f9cf5224c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +expected_public_key = 595aab2d5917eee9401f1b23be84c1e1843126763b2d98c83094610e55545e5478f7251d83282d889cbbc4fc2ae7e11e13874a1cac92000949f82b43ec516de9500f51469975f5b6d5a35de6002e1aa68f84879ad6024b8d913096e381e57776b8ebb2ef501e6a3464f3730e668a22fc8224764a3810aac4c4213e9584516041437bea1920321d4e53aeb3336dd677579f84362265a69090464d053447684ad3961adf10605d28ac5d0193c2f59c5304b14da328ec44cf51e83992fc6f69380e694679556b14add4801342cce20a8658b98846827fb2f440ee21061253c3207c9cc8961ca37c4b3d9c0ce74b36c176643e8ac5fc053a7622158e8aa1ae36824a5c6a70b07dcae4846f28321fd2bd6822293ff4c446654f5837856fb98be568405a822f36fb610301ad2f6027ce1391a8bc0c4fd964b7b807b3fc5b684aad79495f78f980524a808419c13bb1437596621d89cad5475fde6887b973ae08f4a9276c2600489d0d773bd18b0bab3016111c3ae1725742f424d31115be336a5e5b9c3020bd7a4b5cb587c593ebcf61981e3cc6b4b19baa868092ee71812a6791a6e02077c48ee4386120700a054290e0c6b792857659ac01d715b663a3cbf1530976cab2ad5b54e6463168085ad60c3713a41722887e83b406cd67a7ab77596f820013fc7dee7c5c87e776c3976706b3013dd45395653fc4a42f0ce85dd9d49c9f299e38480dc1742348306a51d79d6f8a4285c580ad7b66ce5348e44461eff13ddb4aab80f84948f94c856c03188746bef5c8479c9c9cd1092607822eb82c2679966b17c093643e45d28bcfb424239abc55a52a9209bdc3d70042204e69c1926132588a6759ec3776e8794483a6b2f84319c132508c804112865a3a7c804b496294314de47a8c03a71fbbebbcd9e28e5441c654c04cbda9b7345a73db10a462280eb727c2ec31931d592d333378a6d261aad3a90ebb4d1b23b92d7779a0ab56e8d0ba87aa5413a34c8a18cb1406a8696837d7f547acf97132a015f5a76087f292b80835e32a46d250aeae45999ef2669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_private_key = 2bf07e4a962b0b87b2b35403a151c7a474a78d33b4a0132b524babe056ccd3ca0992059842a132f34a3178caa549c338355b81f900345863b4150036ce45bcc56660ba511f511a52044649e0a4a73612a767c461d08cb1dc6698e9a8675d408fc3875a1cb402129b71595a2577637bad415540487a65ccc30a5a4d6a520ed069834583c732722ce4b22269c67de135c17f92360b0cb555d5892838c5754a1109cccd93e8aba06863c134a5707b2352d07f6fb0b5df0b6df8c10fd3f807923b1f0135a52770188ae84785f33341488b7e64a40777425f693143a90776ec67fd88c79272b4482a46cb3667406a646602b3c2f6a2c2a4294b14b844bc8f9d4063474a52e1627b3d351c5e20520487bb51d7c4ecc54eaf2a6848a5931194be7fc8b39c508b2cc510533cba6fd671cc77463dcc83902cc18af5bacadc8507b14059c77d3b362d8c91956ed9c1d5366781f5774a28b360b45abde0c56599b2edc28fba61c7893589b8266d3bc66e9d9c73a3e1a35fc47e754b91e7e5328c79b28f48952aa0b982aa7027f0105d020cdc6273ebea851d948c5187b9ed038bc79a64ce5c7ec90b85b3921e1e255990fa98687c8a9a921784f52270c77058f090779279ab7c315f824bed678fdf845e79453afeb48d4df17f38011c1dc66412a22317b15f28070232706d97da10f5942cf485879b8366df4b115d0949ed4670c4c2556e8b5140818a13025c044996a31725be3b70194182487048d9b08d926a2e6a9abfca0997365286960800aa7550806a3fe8761fff81b7d89cbe2d49a445225e401037441b337ea2a6dc3a8d09f076e2d9228d69172135c65d40994a62b3f8e86214eb0e597306e2d30d81392117fbb48ce0c27ce106228067eac0b7437a3d06675e832a153e327471464658eaa6f7866d0cc9b49fe66496b26f2ba26050f670fff80f97494221e633c345417ae33abbd60bc6795fad37a7b4f822e502338cbb29d35a71a2217c1b8c49f0932267ca37eaf0c27c8979f2334873864cdbb03dc860b9815018e7165909768ca9311fa2d0550193c60ce5ad408b8f9d733ee5e0385f8b6b595aab2d5917eee9401f1b23be84c1e1843126763b2d98c83094610e55545e5478f7251d83282d889cbbc4fc2ae7e11e13874a1cac92000949f82b43ec516de9500f51469975f5b6d5a35de6002e1aa68f84879ad6024b8d913096e381e57776b8ebb2ef501e6a3464f3730e668a22fc8224764a3810aac4c4213e9584516041437bea1920321d4e53aeb3336dd677579f84362265a69090464d053447684ad3961adf10605d28ac5d0193c2f59c5304b14da328ec44cf51e83992fc6f69380e694679556b14add4801342cce20a8658b98846827fb2f440ee21061253c3207c9cc8961ca37c4b3d9c0ce74b36c176643e8ac5fc053a7622158e8aa1ae36824a5c6a70b07dcae4846f28321fd2bd6822293ff4c446654f5837856fb98be568405a822f36fb610301ad2f6027ce1391a8bc0c4fd964b7b807b3fc5b684aad79495f78f980524a808419c13bb1437596621d89cad5475fde6887b973ae08f4a9276c2600489d0d773bd18b0bab3016111c3ae1725742f424d31115be336a5e5b9c3020bd7a4b5cb587c593ebcf61981e3cc6b4b19baa868092ee71812a6791a6e02077c48ee4386120700a054290e0c6b792857659ac01d715b663a3cbf1530976cab2ad5b54e6463168085ad60c3713a41722887e83b406cd67a7ab77596f820013fc7dee7c5c87e776c3976706b3013dd45395653fc4a42f0ce85dd9d49c9f299e38480dc1742348306a51d79d6f8a4285c580ad7b66ce5348e44461eff13ddb4aab80f84948f94c856c03188746bef5c8479c9c9cd1092607822eb82c2679966b17c093643e45d28bcfb424239abc55a52a9209bdc3d70042204e69c1926132588a6759ec3776e8794483a6b2f84319c132508c804112865a3a7c804b496294314de47a8c03a71fbbebbcd9e28e5441c654c04cbda9b7345a73db10a462280eb727c2ec31931d592d333378a6d261aad3a90ebb4d1b23b92d7779a0ab56e8d0ba87aa5413a34c8a18cb1406a8696837d7f547acf97132a015f5a76087f292b80835e32a46d250aeae45999ef2669a9c98bb9456e54699c4bc4172dc52d5c87a92d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14ef7ef8d7d81aa907fece4c1920c7ca9dda3bb9d57f09193487bb89d6422f10cb3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +expected_public_key = 14938a88ea6a5678c232e9542a42bdd4664fcaeb10c9b8b9c98c7a03a82e25da09a2349361570f46038b3902031128311f04c50824ae86421abb346bdeec824a085f46a51d86f5843c319da7470190d572668384c46149b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85bf822110b942e309d03674d78e49e19a8cffe729986e06c14f87bab772035908096d7382488a7e450b516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd34146e41b811350f8fd9a86b113dce4735bb149eb4e8c04735bdedc8119ef7a5f6abcd94f55acb7276bb3b6000b9a82831209820b89d25946b59a888285e1fc1904d4c1fd0f39625ec2d01360768f57158a5ae7a2193243b009297702d121e52237b4cf8cfe794560f270fa985c949e2c4ed748f2006159d4879492b4f8a14b8d90c9e540b1f993a5236704cc5740a1490461fb23f3540766d249394a144fc434a226b04a38c755de32dc6dbacb70177189c10d8e43e49649840083a93817342d4294f1ca04f9a9ac52846f388bcd784477d5405a6f36c9774bc80909bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b8764f3163a597910c9aa74fac696b0cafd657882004805d36a726ecba03171c7ae41e68d08e67cb7780d7ca135652137613b3dc58b4176eb8ecc9d0b71c5098679d0b2a9d7058c71cc0d64c7a22f37c63a29c4f007d8d62bd8e245069bac1f2d980c0651591e5a4477bc03b47488d08825d44892558009392c0edfac55a2c8fc83a01577192d1dc27efc76b27104e61f34cabd900784c1fefe7125db21d15a6a4fde7780a9a22a0b52bd6a8b7f2120266f9472fc12a02d17c5ec6938ad416201bc2fed6094bc17e86082659863f5ab07c07d20ab6c9b15312a444f0482f5a24f3a96230875ac1121cde130d6e221341d78a30902ff031122f40c6032661f56b605135464185236a91a8e161aa0bfa7a59bac682ba31b5030bfb178cc33cb877796ce20a6e873c921b2c26e63349dfc668f2d3550fe0a914178c9845b23af95b52f86576c71a23223f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_private_key = 4aab84f31c2c167cb7a84377554902e161c51149c4b9da584cf7688eb35d668cc7283c5dc6e7a98ec61388c7b5cff73abe0a703d29396a80a00fe124e6486be3980e53f9c03efc93b7b64964f3bd733aa09a1b4c9ea0bf8460768f82c1068c13b9cb9338497cb6447c97ba84bd63309ce6b5ae5c798d323076f952b8fa9e8bd552b46236d458a42dd53542f4152e12278a282ba3669a20650284f76ce17531def56091da71bbe64477b84197e131b964c0ae909976d62df53697e6422a34d1c268866bbd9048670a8040485a341514b0eb83f028c1ff7583f677334f41b0616063b98c6a6343813bb335e33247977b3bad15bf47824c207348db304bb16332159ac81ee0656d2c6cc5496417d734d7956506e73271962021b1a3c8072b96a7937355709bb613bd336814778684f85107aa079302c820d701b3b4c301dc870794bdadba10e8dc001e41478b540383689f0574673237c730481083a6ae4439afac2605ac8661b0c24417aacd88595030aa1395abab8081c6d98685ccbb1aab1b8d4ec42d67b491d2bca6c0f02f994753ef7babcd51009295c5e1b816a326436ee64511ea8e83d637954388b6c15397f00a5dd85b66a92a82829a28027eb53c38849c315d67a8ed3cc23c3229b98bb4c8c89ce8653cb3f8800f5895eb6c6703642e86562d97f5bcaec2c0c7e3cc3301b6b119a772668447829c5fe43aaaa1c6a1fcbfd8c82277f2859380b77de92bb24b279d021a3188c9e90576cd901f1b64b201a7190793171f8cc16fe69b639318a386bcb2b8cf82998512a691a9f92a92d5b2324343a6137abd2260f8aa7870b78bf864122bb261c2c11d05c24832f413650171d92b8c5a1c65ee04b942f90ceaebaee2cc73538b7cf11a63d8025f1366456f841436a36b98f1bb0c5aa8917cb8674471d57809ecbb2076182261296f1295371a91a736a064e3e5650fabc21564718873b653ea75189b1fa328b9e5169df387a4be50cb392179f1138921aa28843c559b9b53330cad72f17fb20189bb578ebb16bcb5455ae207280658c66b012ad50abe122cac1f5844fc567921fb7714215214938a88ea6a5678c232e9542a42bdd4664fcaeb10c9b8b9c98c7a03a82e25da09a2349361570f46038b3902031128311f04c50824ae86421abb346bdeec824a085f46a51d86f5843c319da7470190d572668384c46149b76a881eb3c3ec036e0d5362ca145ffaa93a41f9b85bf822110b942e309d03674d78e49e19a8cffe729986e06c14f87bab772035908096d7382488a7e450b516c4b1a19ac11586c7b1a3ba9b49bbe8ebc5b6d8542fdbb5ea25374a644f64d852ed978abd34146e41b811350f8fd9a86b113dce4735bb149eb4e8c04735bdedc8119ef7a5f6abcd94f55acb7276bb3b6000b9a82831209820b89d25946b59a888285e1fc1904d4c1fd0f39625ec2d01360768f57158a5ae7a2193243b009297702d121e52237b4cf8cfe794560f270fa985c949e2c4ed748f2006159d4879492b4f8a14b8d90c9e540b1f993a5236704cc5740a1490461fb23f3540766d249394a144fc434a226b04a38c755de32dc6dbacb70177189c10d8e43e49649840083a93817342d4294f1ca04f9a9ac52846f388bcd784477d5405a6f36c9774bc80909bfb8752146b5a021485d11bbaa60a8efb5889f288ac10b8764f3163a597910c9aa74fac696b0cafd657882004805d36a726ecba03171c7ae41e68d08e67cb7780d7ca135652137613b3dc58b4176eb8ecc9d0b71c5098679d0b2a9d7058c71cc0d64c7a22f37c63a29c4f007d8d62bd8e245069bac1f2d980c0651591e5a4477bc03b47488d08825d44892558009392c0edfac55a2c8fc83a01577192d1dc27efc76b27104e61f34cabd900784c1fefe7125db21d15a6a4fde7780a9a22a0b52bd6a8b7f2120266f9472fc12a02d17c5ec6938ad416201bc2fed6094bc17e86082659863f5ab07c07d20ab6c9b15312a444f0482f5a24f3a96230875ac1121cde130d6e221341d78a30902ff031122f40c6032661f56b605135464185236a91a8e161aa0bfa7a59bac682ba31b5030bfb178cc33cb877796ce20a6e873c921b2c26e63349dfc668f2d3550fe0a914178c9845b23af95b52f86576c71a23223f2488b2d3e8695e89a7fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e9399b151aa6b4654589afc36b8343fcbdc09a3e5255b378d6ee5629cd8b3cfd555230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +expected_public_key = 811637e2faaacf51518bd1668fcb964116b7732c71d6515f51b0a454d0359384a2ef7c5fd7ea6b47350c68fca28d6c35219a359e273fb5489e8f4200f830036c8c6046fb7269290686241fc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b2021bbb207832f7b17d187a749eca9cd8aad1fa0c2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956e821c0bb623f033c0b926303d77cf8c2284648059c9b73afc326b0ce96bc8190d41d849a9a7afd7091527804812a914adb475b1149f090642f1c8c98d6453cd531cad4b886df17975f91b3aeacc23358b13b54e40d8856058bad19088371c7d8d896b2ac4c8f3443b95099000a237d791ba0853a6c0e821b051472bbb1a95c7a480529683a7978373081f30af1a7a6c713557c38b0bc9b281a622c68d7912bee99ad6d1bd541182efc3bef160358c067a3363b6e03a5db440bf6ce2cd8cd09c03985a5dc44ad7219c41b860eb2a8b6b025da63978d0041d9231a4ffb28fe6a6cf918bc6fd59aa6f8260c373b645789b9e0ba4798b4b7d8b468e52b2aa20496ba9cba4e2ae6cf069c86b652fa7204d717a623829218c4b288035b551c6f614805257516276531a6cc9b6260b50576e149acd9fd4b324ba5a89ab60cbdb682a85aea36230eee9215e442aa22679def37947d4846fc7ad5ea3626c9c20d94378834a4f086a05bc8c252d22adcfd47ab0d63c886947ade8282f380730fa7b827374e617582a7a2fd4bbbe56ab7031a51871988ac823181966b6bae54e93fc63d2463cc3b103b745b367b70bd212b79363b2669ba062c75da3f2037c17a290281abc4952de641feb740c1cf2829f1b3ae798c3a128b76f4711121597dbb5755a2964bf886f1208cddd70b759797349e4a8bfa0779da984f43195b6bc24338ca7a4714458068b0193c6556c471ec7586268879582b64d26383a9489a6f525c923a9e553627c365bdcf32a4158452410357952479d84306c3abab55792bc1466beb85bd8917722289534c74559887b0d8250309562910a0a692b0da73439d5e87007a4b0c2ebcf3c124394975657fc07b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_private_key = 3923aec9e98d11c99196b0c711e136e5036c4b9174a0d54ccba085ba5a2f7d38c4fdb81d162415fe1730ca3a645e10be5ea053a9f0acc909c038b73d95a3c94ad476a627036d4205a58b287d38af91913932786b7c235a2e62116ea48c53337a946b96de3635a1873794b90943cbb7a1cbc7bdf9a6d6296973d572eb9c35a24905c405cf7d997dc77233c040a9e8169682ebb57e41306bc6cd6caa7facc098d4571788b406146c9f7b6420617b63b17b29aa07cae97654c9e71808aa3700e04ecb141ac2fb3126da710a2459aa210013336657bb2496926a58b730076a7fcd9912372a541dc12873d31c0619af0f5663d66719de703547eb09d0173cc8ab2a65ecbea08b4cd763c8b7caa8ea1c8ac35c9c3e0baff48097395381d511c37f1b1a4ac1c9489724ae05b3c3e3894d07018c463117eb422dab556ea49f9eb65b7d29b4ecfb791848715246cc85f4374faaa26457982931be3d84256724522252b079f54e356aad6557b65a4182d85b29d847bfc4e3b2c5e81e974c00a00cc3fe81ade2c6211bb2c2d1e503e7f5c5e9f443403745ec50aac78859aff7a38ca28a3de66342d0a409248f8472280b135a8fa77911f554ef078650a163bc27a506cb521de8223e9a729a43010c2806086c059d51a6d01254f2eac6bcac118d7735abc7785c1656e68c4d29b03c5e9c2f5ffc16da202c2dd4c48d91c517c2be222b18cf602a699029aa8778a915693a22371e475a323844ac38a7a806c55f229a0f92c83d7828e28b64f74aabab1c4bb3b50e94e64df6c79a0ada21829a30d3356ab85b4533469ea707c216548de287750ee96229a022bed692d1f2021d2723b2365b8b6a3b2a381a9cf75083b38d57fcb127589f13f522051685bc563cca799b7b4047a0a3915ed34881d26fafcc73fd2c00880241296a27e9c68dfec08b4a465787312a49114be583289f8587763844b630602c7b84718641ba4467279b940bfb863437335ed8a917e3450c18a9c6e83a6836b786660fd8234b1c845b95485238232e6719cc32164aec22c130ab468dc14d44e99c360c97b6571700d5b483fc4ff8678f811637e2faaacf51518bd1668fcb964116b7732c71d6515f51b0a454d0359384a2ef7c5fd7ea6b47350c68fca28d6c35219a359e273fb5489e8f4200f830036c8c6046fb7269290686241fc9d4ae42e4b59aa373e9d65b6d5462ea26ad220b5b2021bbb207832f7b17d187a749eca9cd8aad1fa0c2f205bd8358771b156c0e4bbaea29ad45296b788348653ba896d3956e821c0bb623f033c0b926303d77cf8c2284648059c9b73afc326b0ce96bc8190d41d849a9a7afd7091527804812a914adb475b1149f090642f1c8c98d6453cd531cad4b886df17975f91b3aeacc23358b13b54e40d8856058bad19088371c7d8d896b2ac4c8f3443b95099000a237d791ba0853a6c0e821b051472bbb1a95c7a480529683a7978373081f30af1a7a6c713557c38b0bc9b281a622c68d7912bee99ad6d1bd541182efc3bef160358c067a3363b6e03a5db440bf6ce2cd8cd09c03985a5dc44ad7219c41b860eb2a8b6b025da63978d0041d9231a4ffb28fe6a6cf918bc6fd59aa6f8260c373b645789b9e0ba4798b4b7d8b468e52b2aa20496ba9cba4e2ae6cf069c86b652fa7204d717a623829218c4b288035b551c6f614805257516276531a6cc9b6260b50576e149acd9fd4b324ba5a89ab60cbdb682a85aea36230eee9215e442aa22679def37947d4846fc7ad5ea3626c9c20d94378834a4f086a05bc8c252d22adcfd47ab0d63c886947ade8282f380730fa7b827374e617582a7a2fd4bbbe56ab7031a51871988ac823181966b6bae54e93fc63d2463cc3b103b745b367b70bd212b79363b2669ba062c75da3f2037c17a290281abc4952de641feb740c1cf2829f1b3ae798c3a128b76f4711121597dbb5755a2964bf886f1208cddd70b759797349e4a8bfa0779da984f43195b6bc24338ca7a4714458068b0193c6556c471ec7586268879582b64d26383a9489a6f525c923a9e553627c365bdcf32a4158452410357952479d84306c3abab55792bc1466beb85bd8917722289534c74559887b0d8250309562910a0a692b0da73439d5e87007a4b0c2ebcf3c124394975657fc07b7ba88cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454339ba63f705606d8c7fbbd6e66dadbf23f532d5423802c836f2105a636e9e6da1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +expected_public_key = 1ee3723f94a99b7abe01cb641c501f856398369804ab87a2e97191f6c918367c653ed9a2a2559a73db3f04a4ab05e1924d3a9af7392289a894057782ae7139b1e82bb32a228bc7bca367af59519e5ff9319aa987356c97ab724b9169302e0b2924307a46839a4872a57b00ad4f8b30265b5d6a3c95b31c248da1514ffa25d908915635732c1a7e2c938c4e528184ea2facc556eaec7171831aff013da5acca8c500038c55eb8521b14e0263cea2252986c9023c405b56aa85791bda25c73db65126967ac8669c197153c14275a574abf090d5e52821f51a479238360305cd7720fa3e239878635d92315b41b2374732216ac4eeb5650a4896b3747c752827407ca7046a315baa63d9717824cf51513639607cc752ed60e743b5f8ac54168497aae4aa3e4c8aa65b97bb03314501b8644608ff49aa197bc0fb427a13600bd8395c94d534b1fa96341f8cec2b218c1a5745275799e93767c44b128bbb0fcf59f1899593e9176f070cc541949b490bd20790584d3b54b369ac5f2a7eb24043155272534889be150f320019aa29b8585ccedf65ca73211ffd8a60f558b4482a1b0194202c16cab1699cbb9544b221c2cf84726608311416267d065d5a819bc05c54fb0c2406bbd4efac451090ce9dc93437312278ac7f7b88f0b69b80b7982f7989c47a18185d2437c1689d1378d01c14dea68b701378e62173fbad1ac05ac1fa904ad1a22895c52b89c8cb548a4cfe168846f996db569cd252281d62c675c298a62d1a38c019c5c08caa986672df818640a90002c12042c3cfa437887a4cb221b65b94a82d7102d07a16333177890ec100c2a8df22987d0019f65e64d5dbc544fdc3a3945a3a77a75099238d0774e9681ca16ca0e9c0554e0e401b401243bc75390b3b4bad59151128f8cc28c2d40bbfc89b890c64ecb65826f202912707f976a2f76463ccb803a945c946d282cddd40f5916c77e268dee390c7a823e5f3313ded9bdc39c2690f15834e44b2cb1335a01068955a3be7c635b7036a975ba7fb986295c3249916b3997c7f0e2845d24b9b264ca4d49a697d1abf3ca9ea6313f46c0cf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_private_key = 9a605c2cca636eb3b589f3853b52b59aaa3b7e7a6aaff24b74c6cc2f2022d662b69a018683a5205c0a37f9c88db6737eab28bfa1e12d9613188cfa7a5aa7807efc6ae9ab78ce34ac85b4ca61e8beacb89f23d37fad0c91225b8dd7f10358d8096ad37f2287a175e158cd90a2a4128d2e266ef72708958351eab74f63e45672a16cc4d3aa77260630c663fdf27878e0501079c55b56449f2bb932b42617097126a85a2e5b24e9130e4d02b2cf70b26c2395d2f8996248124416cdf21679c006440fb0aaf570aee279042adbc3fff40ccb122ab7199468273ea38abd8098af3940c65c8951782a650b50211927cde10c3909168d4e4699a154a2714785ffd86c6cdaa85586a40aeb6cc081022edcc27ebb900786c4aba36a45d65d100508a4e41231b58695a53f0d340fbfa128e5e2202a986d471849fcb4947e1c1a2505494a320f288179b5cc5d04847c68449ac100093ccc879bf7a1b892be385844365835a4006011904a235003df8a19e0ea37037202f3b6809dd0bddb43ca5d46506c165bdad665f97ac882512583175818ba0e63942a612b3889645e86dc293d352380b68379fcca92c4c1c7aa5d1a842950365ff465118fac96ddba65dec7a78b1523e0d5681cc7bdbe656d0c440aebb4801ef465a05ca9b51253ef24abba291821f5a1460c0f8ad09f4ae08d83401ac0033f84c9866ffbcfaeca8d4b216eea2b05d92964a1a57250c6b09d7c13e1aa665791471212cbda902c9ff58a0a05120c8364b502187dec8f4dc35843d13e85dccef6448afb8b80fb28763f044684403ea3f110297822c7889b8bec5af016b4fb22c557eacd82a574ee307eb19673b26683f6822c192270ca38044140426b9b4f36cab6ca673f6bd60e67a18d73390eebf88542f976d53ab808116c65020e6d4825f10bc00d664fe0cc23837a9938d70db9304994bbaa56b378d8c5214d6762c1c25d8386328c092d73a9174f6858bab76ca807aa8c376af004a1b4679dd6f500fe139080981b6836a83f05c7471349d1405984fa95bdc3428805c78a4bccefa91f84d8985dba27585a834079b041486a7ad9981ee3723f94a99b7abe01cb641c501f856398369804ab87a2e97191f6c918367c653ed9a2a2559a73db3f04a4ab05e1924d3a9af7392289a894057782ae7139b1e82bb32a228bc7bca367af59519e5ff9319aa987356c97ab724b9169302e0b2924307a46839a4872a57b00ad4f8b30265b5d6a3c95b31c248da1514ffa25d908915635732c1a7e2c938c4e528184ea2facc556eaec7171831aff013da5acca8c500038c55eb8521b14e0263cea2252986c9023c405b56aa85791bda25c73db65126967ac8669c197153c14275a574abf090d5e52821f51a479238360305cd7720fa3e239878635d92315b41b2374732216ac4eeb5650a4896b3747c752827407ca7046a315baa63d9717824cf51513639607cc752ed60e743b5f8ac54168497aae4aa3e4c8aa65b97bb03314501b8644608ff49aa197bc0fb427a13600bd8395c94d534b1fa96341f8cec2b218c1a5745275799e93767c44b128bbb0fcf59f1899593e9176f070cc541949b490bd20790584d3b54b369ac5f2a7eb24043155272534889be150f320019aa29b8585ccedf65ca73211ffd8a60f558b4482a1b0194202c16cab1699cbb9544b221c2cf84726608311416267d065d5a819bc05c54fb0c2406bbd4efac451090ce9dc93437312278ac7f7b88f0b69b80b7982f7989c47a18185d2437c1689d1378d01c14dea68b701378e62173fbad1ac05ac1fa904ad1a22895c52b89c8cb548a4cfe168846f996db569cd252281d62c675c298a62d1a38c019c5c08caa986672df818640a90002c12042c3cfa437887a4cb221b65b94a82d7102d07a16333177890ec100c2a8df22987d0019f65e64d5dbc544fdc3a3945a3a77a75099238d0774e9681ca16ca0e9c0554e0e401b401243bc75390b3b4bad59151128f8cc28c2d40bbfc89b890c64ecb65826f202912707f976a2f76463ccb803a945c946d282cddd40f5916c77e268dee390c7a823e5f3313ded9bdc39c2690f15834e44b2cb1335a01068955a3be7c635b7036a975ba7fb986295c3249916b3997c7f0e2845d24b9b264ca4d49a697d1abf3ca9ea6313f46c0cf073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb1f9e26333b637ef9beb8881c63f9412b07c47a276af0e242062a54026bcee2bd7a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +expected_public_key = 501a0171c94c8651b920fcae8eb447d9913047183cdb16374d9b7c6fabc86fdbbe5905805f50bee8c12612115ca16bac13160198873b4f999e4ba1c052767d7d5ccfb364c12a5a6c81232991b5100f21cf47c50c8566c32afc13f7b03fd9a2b09a807b198a4b2ce48d163b0398731c142ca7f13b3f95000fc1345ad1a50952d09c6fa42ba6b5119ca1061a64a5ec4b1323a5be3ecc97bb21383f6c559550ca985c53c4e78d0d660c6baa11527242e61780c52770cc3739edd2ae47c676753bca078266d565377d2aa5cf677945551eac12c61a0a95f6930a95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a48b016de4c331ea591bdd43a51a2109f02601569764b8999bf4cc987f25b3fca822f5771d941ab90a0083d6676a3d743e458381cc3971bacbe8c3a4871d51baa80a1c34462cd46ba338ba319dcaad92ba7e471658097335921728f96b1f06a7b84e8a74cdb635b904dc7a583c4a6208d894caa22265378aa24808ef605193fe186bd0565d2c32ff234b45e2726d0d7c939754592baa93297c28c6462bc0945ec2035e776b2e4526129443c1135cf16620ce8b12825321aefd92010283f6a034fe86474a6e18a62693600d012ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a85a1f69f7aa39fc98938b5bf0f8768c2020b97b1c06d1c3b8773f8d110280a76834fb9643b42fd3dc002e3602ec84b79cea4d9b9c173c58c5417531547539e1d61e7c6ccb5fe2152eca572c7738e2a872a711225e0922e1b219beac2b2f3ac82d68759d83a2998014142491404a6e51b88dd7a21a664a14d6f3043f67cb0a2a697d537f3357bb19a6865172653f183e396a78b7217dd0f18f1cabb936169f6d75498d9027e1c59c7ff8558ef138ed0236d20a23af399067d4ad57d36927bb88b4a0836ea06cfb941617db0efa049b6de6cce0f5cc122239d85391c56487c48b919764536fc11a6b3b3860d6baea255e48d007272a24cc32637665640ffc8c17e013a3e974d6a5aac78ace4a2c9a173240a9cc1c8e18ccf841b4b77793c6028ec75c5e4697a32b591652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_private_key = 03433175f23a3116525719b8fb7c7a4cf3c8b360a79bb6c54922bbdc396a7577a7abba86eff8b329075950f42c0c8173eab72f614bc6def934277883b121b0ded70adada3049f5cf30db20dcb313fe3b4c7b60c396b17a80350f0ea38e6f800c7384be35571fb8170aef046cf28c152682cab9ca8fca2117e6baad471a78b24b75518840aedb34ebd3140072abcb9a18427714059b2cb5272baa713ac7a1c98df30042dcb7fd7b2ae996c4cf34168497352d298ffeb5bd64232610c6b7a728b5b383573220053766b1e31720daf91775c608cff42468142a37f3acc06bc113a8cd493abbc10ccc1b660e7f821ba8901ba1374fd51948ad897bdd0b7f4887b41600330a4cc6e77a6910888bb87cbc26bc1ad69450a92bb2c8e0b56f131d0384c90b30312bac22f7b521ec6bbde3112053b246c9880f64c6610bab71d0923190f3ae46a1070658b646351dbc0ca88ca88a987b9e23614ecb72795d2b5cdd31b0b912200a229b657c4bd80c38987332a7296c2c065e1dc42a1aa2525b968e5289bc16ecba39111fa39a4597a1674c1009dc649a6b611a0a513b93e9636eca68c3e461f76840ab73bab8329915020cc9e280c719972afb7d3100224a327fe9e622735097e4e1507e1c0d19a60fc0676bda061bdc06b12b38a0dce0107c39b32847649cd33ece1a65f4199eb348319d0a0a0886ba0db3b7be893ee353b0122a62e95571d3f91316b6ac40270de06a7cbdc76bbaac7896bbaff178a2eaaa1d9adc2102e3b256f43adc249544eb0ead915b9df30fb6ba4c4fdb4cc10a59218446c87512683165ef97735ee11d76a82a8f26c50f45491621a7a3f32df657a900e919204a5df1cc89f0f5b3273632badb3738c501a4a77a76e40bafd478c3f504e54a30884bacbc107f7349ce03930335d171c6c4acdb18951163387b07b233712f3560bbd59182d754148ce13e80142f6f9a02dc2032e8b7516c3749c7fc2891a5c410339cab703feb2b894deb0ca25a785f09a25d1803e50118a1c09eeea85f62c52292e1c560749ae1f3c23b43cd8e430e70931d282927822610bd871f48c337c5da3d501a0171c94c8651b920fcae8eb447d9913047183cdb16374d9b7c6fabc86fdbbe5905805f50bee8c12612115ca16bac13160198873b4f999e4ba1c052767d7d5ccfb364c12a5a6c81232991b5100f21cf47c50c8566c32afc13f7b03fd9a2b09a807b198a4b2ce48d163b0398731c142ca7f13b3f95000fc1345ad1a50952d09c6fa42ba6b5119ca1061a64a5ec4b1323a5be3ecc97bb21383f6c559550ca985c53c4e78d0d660c6baa11527242e61780c52770cc3739edd2ae47c676753bca078266d565377d2aa5cf677945551eac12c61a0a95f6930a95b9a76206733029aecdc6cc17378305b769b9e6b6fc95a80a986a48b016de4c331ea591bdd43a51a2109f02601569764b8999bf4cc987f25b3fca822f5771d941ab90a0083d6676a3d743e458381cc3971bacbe8c3a4871d51baa80a1c34462cd46ba338ba319dcaad92ba7e471658097335921728f96b1f06a7b84e8a74cdb635b904dc7a583c4a6208d894caa22265378aa24808ef605193fe186bd0565d2c32ff234b45e2726d0d7c939754592baa93297c28c6462bc0945ec2035e776b2e4526129443c1135cf16620ce8b12825321aefd92010283f6a034fe86474a6e18a62693600d012ec58c26fb9904cb8cfb71c582606493bc4748fd669d65748a85a1f69f7aa39fc98938b5bf0f8768c2020b97b1c06d1c3b8773f8d110280a76834fb9643b42fd3dc002e3602ec84b79cea4d9b9c173c58c5417531547539e1d61e7c6ccb5fe2152eca572c7738e2a872a711225e0922e1b219beac2b2f3ac82d68759d83a2998014142491404a6e51b88dd7a21a664a14d6f3043f67cb0a2a697d537f3357bb19a6865172653f183e396a78b7217dd0f18f1cabb936169f6d75498d9027e1c59c7ff8558ef138ed0236d20a23af399067d4ad57d36927bb88b4a0836ea06cfb941617db0efa049b6de6cce0f5cc122239d85391c56487c48b919764536fc11a6b3b3860d6baea255e48d007272a24cc32637665640ffc8c17e013a3e974d6a5aac78ace4a2c9a173240a9cc1c8e18ccf841b4b77793c6028ec75c5e4697a32b591652367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d64b9f8198bab9b3b2f2a1704cd4ddf6b3cbc216ddc0f062a72ef40115917fd218f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +expected_public_key = f17c93d23556b9361ab12a87de122ba9264dd889232ca7c301859aeb32611dcb01faaba8f794aa3c0b858ad75e82b51ef707b4266320a6a9ba4b3616896c14db18bcae601828fcaf9e895c571205070562208c45877780fd2a02b3c697634116efd504104709f75426476bac050ababd708f38fa075dd2661d9241f0c31d7b674285ba03cc34c05fb378ef68a3e6a03a1366b8b432186001c56b01169227ad4bb614dbc290e5a085b7b90478b5702edabc9c12544f9a2102501836ecba58763b10751e9db7a29590711ffb3ffc240500995e30318fdd141f6177c2673330fc558c1cab769f202b5aecae19d1479ad32b4e2c59834ab79464770ca619e88535f84c26e219790f24b1bbb17c2b1017464c1f1d102720f111bd2b95d9ab79f866c26c730103aa602fe5ae1710c4a1782caad0674129cdf8791d780095e5d8a659333149b0797472ac623a1a2ff2beec7306a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578e801c35a429e341af97b505df8a46a7055633718d57814bb6e2abb272c9efe0192c2b55ecc5cb8e389b8bc5992b037d1e72074bd361740aa8a86c63004c99ffe50224378d1c28431f599f4a701f3165c8f6030a1ba7590ed49d4300578985add03887d867a3e82b577574c398c56f21c34f6349b6bd072bcf8318e4a8244bec6f93fb84b6716846670945a33ffe53bcf4c82f8c52ae84faafb4b46bed2a9807d2569c90791c087f3af05b88b45345bc099e9ba4f3028c469a3b4f2a1ead50147b208f24b21c9c4582cdb8633a9a58d7820fdd0c761e70855259216e2a3eae25129b2b6808ec1611800d0fbb3ad6179480bc4391860547199ba04b3a97f72c8c4caa93379f559626f6a4a8da750e6ce0651794138c6b68d474bb70f41975b246de5953c5226606102f98a36b66994e2ec785fdc2377ed9c664a05edbfb694a2c5f87dac238841245733852da5427a0b105ea2612a06ee9019b6dd0c3fa034f61da229b5608751bc29bb13ccaba83832c8d37108be5943cfd2173eb8512d16aa1c7b3b7d5ea6491c379c1c66853732d7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_private_key = 6ae07bc60180e5b519e45acd6a33b1e15b0fa2353bff580e32abac68f48610bc9419c0382cf4b4e9cb730a1c44e9281a8d1cbbca26ce94d51aa2871d4065a706505061a991da7960911b76694a94144c24904c82b1266278546a636b6554f12572a9cef82593b35ccf00995553a6cdd0a4357aa7913bc7627d40594530cff8e68c345ac211d3619c2a9c033293b2e41d28db2e6f17136f73952e4a6f2d9364996394cd461894b8b38e85af3e4b1df33b0e44c867210c4680a76a56c16f6f396274362684466a0ef73a3beaaf0c09221e577ef3b96fdf3a196d58415995ab5844b65e8a841202ca7bb24993c53d4658a541a4895659cdb0a342a7808aad10a6bf8253655a58df23af6e40adff94b4f9c3606cdbaba00a8a04b99b275ca465f59e7247308741c738ec40772a12554b62d5030da743439c59a560b31a8f72370fc12238f95aaf8737bfb7015a4a3b3b8a772b225f83fab6ceb0c9629a1de010b2db5b90b427030a186ba159c3a853c5de732fbde798e0643dedf63d8d549bdd746bd8f81cd331476581408b7b8f29334f224239f7d4bae95831d260a46f4c79f7d9b9d0208dfb238ea918222177291087ab7dba59e3720b6bf14ba0c93c7cbb5d79860f1087917db391abf882be366036f1aaf436580a01ab775205810a5049432ef5fb383566c904693d3d645536408875390a9c8319d0a7573c84a9aec892f862a4da685d7b14742d63044012ab74a10b88c60a44319f8b97b404d0784de33153927f19c7aec9f069bd8c88b5f59ff5aa2be104c658e2211448ad236a3520e54251494f64c84355039e60aca4c696b440b8707f3b0ed0196a1d3881d4cb6520c237224a5dd733a67efb33029c67f5da6a2c42ac9a902ed8ca1ec59b1190e0c29245a5a57210ff8526a4163ada06588e73688d410d44fa92c7a7af49f2a0b6a42ac2660ac76594f472648f762924267a90657aa3595c4d672b7301acdc750a53963a49704fb65a7f5877214d7bc233cc4f0495c5944a43e39a6724509e24f56e6fe4b44e453b6b151931a04e6d1b31c049c5ca009554c89cc0d4803b21a14bb316f17c93d23556b9361ab12a87de122ba9264dd889232ca7c301859aeb32611dcb01faaba8f794aa3c0b858ad75e82b51ef707b4266320a6a9ba4b3616896c14db18bcae601828fcaf9e895c571205070562208c45877780fd2a02b3c697634116efd504104709f75426476bac050ababd708f38fa075dd2661d9241f0c31d7b674285ba03cc34c05fb378ef68a3e6a03a1366b8b432186001c56b01169227ad4bb614dbc290e5a085b7b90478b5702edabc9c12544f9a2102501836ecba58763b10751e9db7a29590711ffb3ffc240500995e30318fdd141f6177c2673330fc558c1cab769f202b5aecae19d1479ad32b4e2c59834ab79464770ca619e88535f84c26e219790f24b1bbb17c2b1017464c1f1d102720f111bd2b95d9ab79f866c26c730103aa602fe5ae1710c4a1782caad0674129cdf8791d780095e5d8a659333149b0797472ac623a1a2ff2beec7306a88a6f8a6448f85a62de253e1af77717cc86604c386dbabcb3a9578e801c35a429e341af97b505df8a46a7055633718d57814bb6e2abb272c9efe0192c2b55ecc5cb8e389b8bc5992b037d1e72074bd361740aa8a86c63004c99ffe50224378d1c28431f599f4a701f3165c8f6030a1ba7590ed49d4300578985add03887d867a3e82b577574c398c56f21c34f6349b6bd072bcf8318e4a8244bec6f93fb84b6716846670945a33ffe53bcf4c82f8c52ae84faafb4b46bed2a9807d2569c90791c087f3af05b88b45345bc099e9ba4f3028c469a3b4f2a1ead50147b208f24b21c9c4582cdb8633a9a58d7820fdd0c761e70855259216e2a3eae25129b2b6808ec1611800d0fbb3ad6179480bc4391860547199ba04b3a97f72c8c4caa93379f559626f6a4a8da750e6ce0651794138c6b68d474bb70f41975b246de5953c5226606102f98a36b66994e2ec785fdc2377ed9c664a05edbfb694a2c5f87dac238841245733852da5427a0b105ea2612a06ee9019b6dd0c3fa034f61da229b5608751bc29bb13ccaba83832c8d37108be5943cfd2173eb8512d16aa1c7b3b7d5ea6491c379c1c66853732d7a15551cc360ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112cde4ce515b882c849717a1ab34f2ac0238c868f415630c1155bcfb302d346dc91e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +expected_public_key = 623668ba98183ca92c9075804d082ad2d17769032e77c50484281428c00320848073a17bacd2c47ab391fb9472d395a6376b3f44aa625c36c95457cbec00641a1cc4e248ba7a7012904a73179a61c1524578f739f7a5998355276eacbcfe462f2a82776ccc04ddc089cd2407f4b757748089d10baad85a3819d52a6560970353abdaf08dde151555f92b6953c0b6c51a7cb882ec5c574c31619d8c824c605102bb8d836c68f29578432c8515c913189b650ada84a2b5795093b5edb2a6e0b13b38fa3db500c7bdfc8dc796c7f57a9b95cbafb8610780eb6787d36067f89831d98590b91d96144d7a4c0fb1c34455902d49e39fceac427d723b027709338628defc8a771a055cd8bb143108c9724cbad1729b99c8fc675d007b7c38ca20b14c04549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499170a109ae98e53b807ad277dadda57a4d13f2397c167ca0955e3148dfa1b502726c908bb283bb1b41b89e15780dcba45485ab771f19f1f0350b64a4ff983a5e68982523c1e936b9be3c38ad892b0a20b4d4ea2918498065d2431e7f950bb33c68b23167bb4693bb258610404788a37009a24823b81b95753bf09aea4a7b219cc8a9af4632d9c5e4790158071318e9119def243a30a7925f17233098d3c594f1571abaa0744f0e44714d0c8765559cc327e35fabe67066af141127ee7145546c89fd55a852712eb8c9c77bc649e847d229958e0d7a3947cc4284729209a704aa4640f0c73dd63c6e48651f62c33f2351f5d90bde888c3dc116827b16d8071a01fe02d1b4b485e9779217641f0a0af2434574ef92e180c116f44899afa647cea8403a831ecdcc04faab8faf3215d622dca40a95decb5a833206866068a6b49ee588151454eda821a35a5937a63c23ba0a0d8c5657d18777aa10492b1652ec2cdd22a7f800708beb1943ec347fab41219171fa46b7b58006f91ccba3b69cd7603645c9bb584282dbfb9ad584c4ec0c692a25795111a18709072be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca241ca7e50ad46000ad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_private_key = 58e44706119642d7c64c6293dc8a78da6809cbf38b043c74614caf23eb8f63db45721457c5e22fec94bfd12cb2ba10587e16c31deb45cb66948677c889b4b638286da6d08b062aa5fb825476fa76a5f0b4d7a5301b4b90ba66292f139891a8aa523609e4f975b67830c2a058bb2bca48796f5fba0e111ac682e10e5368cf8f94095f5701384147abcc2f24f6bac2a57e1ed2bbee684bb3321117323d943a4d890340b28035770c8c5bbb39a5b9794432b021d1b7373870e15a60fd8c4f00b650c529095d8a310868c78bc427a583b00f897d0ac81b6afa2dca4bbe4b665efb79661668bdace01f9a30820c91095d586a9b232a1037bedab70c9dd87377447b4a0043546334d3c2c38feb870b1644eca7b957cc097961bdc3e6165c0907edf4b6328894f7a4413b583bc937109777bd84065aee8352471082f162bba087b025ab16c2a04fbf3c494f43471b012060b499eed776ab383c7ae0200b1aa9aff0090f4741c2a1a444187b702172df84600487820c5374986623c1652b9a966bcb02662e5409bfa5bbf166c9f894548221451216adf6e3bd861a268d25a032c838259825b8b4be0d3622aabc24b5e997756b758953c0a2b38a4336b6dbab69a9e89620a1ac44a748171106efd125f953878815486ae621ac10237c60ac3a56b57c92331cba08f2367e80750a872c1ddbe9a24f5b3cf59c8476d4284a094f1b0095784ab3ab0635a24c96bd1b48dfc1817d27300f2654d4063d0d379c7294607a432187451061e50ef5096ca3e01f020610fea83494b197ddaa8e8e15b054f770bef4b564a539c6b786358892b62439fef59cade7843cda8c6bf48a459bcade476e89a73edc002d06f794ce60043ee660e50c71c515148bfaa2beb876512c6af4e48416d086e8ab844d0cb8e3e15063c26373816bcba06124a1a0ca5102bbaa487d87b16d39b181d34f17474849fba7fe12047883bdb6b816c8767808418f948764b7b1beae0bc09e937e0edc9db69a0c2a265275b77ee4071990aa91f5f62b01f5c76a7556cb1662bcb0aa9d2b560a8b813ca04f28021753c446f5a46665f87ad89447623668ba98183ca92c9075804d082ad2d17769032e77c50484281428c00320848073a17bacd2c47ab391fb9472d395a6376b3f44aa625c36c95457cbec00641a1cc4e248ba7a7012904a73179a61c1524578f739f7a5998355276eacbcfe462f2a82776ccc04ddc089cd2407f4b757748089d10baad85a3819d52a6560970353abdaf08dde151555f92b6953c0b6c51a7cb882ec5c574c31619d8c824c605102bb8d836c68f29578432c8515c913189b650ada84a2b5795093b5edb2a6e0b13b38fa3db500c7bdfc8dc796c7f57a9b95cbafb8610780eb6787d36067f89831d98590b91d96144d7a4c0fb1c34455902d49e39fceac427d723b027709338628defc8a771a055cd8bb143108c9724cbad1729b99c8fc675d007b7c38ca20b14c04549c3dea4b5fa3a94933bb72d2e433ea638c1b157b0eeb3e84d499170a109ae98e53b807ad277dadda57a4d13f2397c167ca0955e3148dfa1b502726c908bb283bb1b41b89e15780dcba45485ab771f19f1f0350b64a4ff983a5e68982523c1e936b9be3c38ad892b0a20b4d4ea2918498065d2431e7f950bb33c68b23167bb4693bb258610404788a37009a24823b81b95753bf09aea4a7b219cc8a9af4632d9c5e4790158071318e9119def243a30a7925f17233098d3c594f1571abaa0744f0e44714d0c8765559cc327e35fabe67066af141127ee7145546c89fd55a852712eb8c9c77bc649e847d229958e0d7a3947cc4284729209a704aa4640f0c73dd63c6e48651f62c33f2351f5d90bde888c3dc116827b16d8071a01fe02d1b4b485e9779217641f0a0af2434574ef92e180c116f44899afa647cea8403a831ecdcc04faab8faf3215d622dca40a95decb5a833206866068a6b49ee588151454eda821a35a5937a63c23ba0a0d8c5657d18777aa10492b1652ec2cdd22a7f800708beb1943ec347fab41219171fa46b7b58006f91ccba3b69cd7603645c9bb584282dbfb9ad584c4ec0c692a25795111a18709072be46981cc6c5d495652bc697caa6c5f13a30f3756d42d93b2d0471c0fcc59ca540376abca241ca7e50ad46000ad9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f793b60f0d00c09af885b5a0cbe942fde6afc4841428104710823bdcc12319eb35393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = 7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +expected_public_key = 8843b50fbcc8bbe4aae3f4c1942926ddb8580ef06adc73a7f869842a3211bbf36172ac6972811c887b350b5189a376ad6e032234c0840dfa0a7dab2cce171e47e3945f2798380583e4e2b1d5188b18bbbab2564a0a06c174c577c91000e1dc3c79c1a7d54c38ffc21dc0e52e62a3c093a30c0986aad289b0c45841253c39a1a00b90712f4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a630a00a4585f6a5ba1c0ab2c16450e0a30ab06670465628d763b5b0326fff11d5306abd4886cb304a515389e3d9cc4664039bcb80509661ff19bb372a8c8e121c94f5103994b91448982bf1627b38741a8560adcb5101b68937673a2ed345a6fa76e10b2a014115eae9b4a7ab8ade144871fb2cef1b10309a6ab67b218671500c0fa5ece8952d2635061524be47a33e4fc06eb1409cc4c7bead4a0ba8007df2b0d475a4312f042cc6b75b3484b08099c208971a07a054b701c193cafb509120d89579e282b07fc6ce1bc55c10012ecf1399c910b827a4ddde8995848861a8caffed9a284b829de0bca22585024d4a2b5946c5385267e9052141a5e27ec2b75188195d7c693f8c64b4351f2bb3076d95db950905087bb14d87831618e9beb5583064fad4952eaac72f3a3079da32668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab6712c40b933d663ca9fcb3441c62477e3209795150c4da33c9fc13b0e421d23a9393a76728f55261b41c8dac98e48c24d91701fe6c719d8964318655a0f9bda8e1c876c04a1b729951f5111735b3558162c1e27e6a9c0ce0ba0953620d6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c098e07607648179121d2ab55b81ac018143724015aadd1b730c274a6ec281ef446a8468515519b1477492e5cb87e0962bd9216f9863bfafd025b0e00c58a709d200be9187b654fbc6f76b76092c1230526d051836ba580f90e368a4b201dccc9a3637c19799465e3685eaf51bba70610d88b6f08bc6179ca607241b62e54e94f97257838acee5a9375b347d9723466b6609330a071a3ff9d1acbeb4c41b0650616689005408bf8c292b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_private_key = 0b107bf998c10ab147262c4e15ac4933a033d6d6a0804468f06b17abda2222f73d17c94c1f30950719cac69a81af4985e8134e67b8cc84064130a11f1db09bfad73550bb5a00696141f35b237ab114aa4688f3b98a563f1e2b7b8f85c5d61aa9d759c2d6d45958b18251e62e8d2c1ac389389cc2278e778b42e67c962a0484e78eb57b0632c04776f41ed69b78eadb9339376844222b7396699238793f617c96292b30b66a0992caed38042f64a34e353132829abca68e7dd119b9954282a8c87c4a5dc4bbcb36eb2ca18876f8c5694be86df3099be1f6cbd17c2fd820693ca0a0aaf8a495b24777fc4a05129e4731517472cd67998de55417d30190da206255c1cb56c2495ebc2f444a0572681ca45a8b63e262c9e4a025cb60abb81008f0a30bb345eda853a940c87fe9b9ff512043770959206912b65a79b5cfc977506fa407180c8e9e7b178253851ff925acf9026849089ea1a80d45a5e39430ad1ba48698a49cc1319473a91ba46da0ac0d51856c93a2c515283903e619a1b852845235be702405524d86b6ca91814d5fecb8a24669de5a2123d320b6589a7a4508f935594a0070737518c76885c82816e6681f172c72d2825e43c82b5e6abd58a3b7863a5e8111893f53b2fc89011b31840aa010aa7c92db4895b3740d2be47b9b5b34bd034f5d7842c2943eb7ea708079cf54b11a4a2074823a17c40cbfc0b5166cf38831e4c874a086bc15cc3db21710e4c0c8848ffcc67520c291dc9aa33456508a52af89865dcdf4a3c8e71900f6b69f6bbec635bbc088bc79d7b69c7a3e3c6413f8a1892275b8ed8a38fd384cabd4cf5c37bb7eb5a818118a8b239f3b873161cc1b81605106540ecad69faaf143e487aefa06056b188aa05a933e1380921048072baa6c01162bf56531ca42d39aa5bad485852743f5626f36a881106cb32142acdc69bf6e234cfcd1696391bd5be59c284869d1d7c34e86628a198ee16021d6e8aeae9279d62725c7107ca250c9ac3a0d1b045a9a1c8c8af89cc88b295998043c307901d9920be770ce97b348180764fc7ca83c889e12bf4d2298e5691865f9928843b50fbcc8bbe4aae3f4c1942926ddb8580ef06adc73a7f869842a3211bbf36172ac6972811c887b350b5189a376ad6e032234c0840dfa0a7dab2cce171e47e3945f2798380583e4e2b1d5188b18bbbab2564a0a06c174c577c91000e1dc3c79c1a7d54c38ffc21dc0e52e62a3c093a30c0986aad289b0c45841253c39a1a00b90712f4e4a9fd22ccca9c44b85c5bf240989dc077829fcb6c874733a630a00a4585f6a5ba1c0ab2c16450e0a30ab06670465628d763b5b0326fff11d5306abd4886cb304a515389e3d9cc4664039bcb80509661ff19bb372a8c8e121c94f5103994b91448982bf1627b38741a8560adcb5101b68937673a2ed345a6fa76e10b2a014115eae9b4a7ab8ade144871fb2cef1b10309a6ab67b218671500c0fa5ece8952d2635061524be47a33e4fc06eb1409cc4c7bead4a0ba8007df2b0d475a4312f042cc6b75b3484b08099c208971a07a054b701c193cafb509120d89579e282b07fc6ce1bc55c10012ecf1399c910b827a4ddde8995848861a8caffed9a284b829de0bca22585024d4a2b5946c5385267e9052141a5e27ec2b75188195d7c693f8c64b4351f2bb3076d95db950905087bb14d87831618e9beb5583064fad4952eaac72f3a3079da32668ac35b0e76e21ec63f46cc2abaa3c986970bee5ab6712c40b933d663ca9fcb3441c62477e3209795150c4da33c9fc13b0e421d23a9393a76728f55261b41c8dac98e48c24d91701fe6c719d8964318655a0f9bda8e1c876c04a1b729951f5111735b3558162c1e27e6a9c0ce0ba0953620d6343980ce7b3f5db31249b557dc76c8273b9c5075a60b8c098e07607648179121d2ab55b81ac018143724015aadd1b730c274a6ec281ef446a8468515519b1477492e5cb87e0962bd9216f9863bfafd025b0e00c58a709d200be9187b654fbc6f76b76092c1230526d051836ba580f90e368a4b201dccc9a3637c19799465e3685eaf51bba70610d88b6f08bc6179ca607241b62e54e94f97257838acee5a9375b347d9723466b6609330a071a3ff9d1acbeb4c41b0650616689005408bf8c292b9341b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8167a2fec4d72cac2ffd844246eebabdac0c074e4f984433744e31d299faa389ceac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +expected_public_key = a9f0c2475a69f1e96c610badd664c99895021f497c13111930880c02d9c8ad7a1309085826b4116f9a9cd841981f766944137de5587323dccfbba28366f86ae7a7481c054b2dbab86823b77eecbe7d9088a9ca882eb7aba5aa23c27209df4760e70b4876b709bfd225b0ea9644fbac9de01df90648a25b5fa9a48228872ec2cbaa09880100bc24f1414102d92a5a206399295333485f00c111ad49c0fbeb5f4149477e46075377967c310fb5231b9d6204bc877c31c524bd76b5edf23fb9b091ffa3bc2ec64423b02f673505d5c69dfe472d8df62f9775852b901000d84e4237aab4f32226272766234dda706fba5962e816a98586bc2a5bcdc1db80bd9b18bbc3c82d01cb1b67369f32741d50ca57a45c45667d5e5428824463c8a651afd95e995a4b860043cae74e265aaed3320414989a346a63f0f0842e59972a91bba62559422705ac6422d66098747a85737abeb01c00b4b90311081a17c6403726ca39e27c8d426845fb624a956c39bbbb404a8ef5073e37078ef535b9eb581783eba401243b02d750f5034d4a366c197994189846dbd82712663a0fa0beef5847622a904b04983b519955b717025c01d9e5b928d4b860cb0fbff76fbbc22b4761a5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b090aed1c9478a68ce883cc9b8960e8755485099912dd509e9804e33e86a12a75b53d42f0c784c6a73732a471e44900d41ec9c4c0b006910202b1b2dbebb65b5d7471f189faf194e642887c5631271649662f4b235829644198bf8e965d9728778a65405c4417eeb7ee25502618ccb0a0a226945adb0d73ffbd2ca47a5580d0803a56b3c3bc66e877ccf05741e29501bad787d8b588f97c20c8255687ed3aa1631122c387456088d1209c4a5475f61d12c2b60b1776244512a08807c09e7c7aaa3935125f235f8e872bc4356a21379bdb84a25b132f4449561e96bbf8776fab1c681d42575a1bfc0dac357653996d41aac4a9341196da05c49ba84a4cea37c818ba0f0408c8c9335616410b1d479ca035656119236ea9d6979366163791648088fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_private_key = d1d08267ab33fa3a0cca990d20543e59075f87e1b20953ca4b775515a07af10c6ecd7a5e299b69fe05c0939cb6fc789d94c762940925a1dbc9d7a33d42a2970b36a76f5869efd38b2a81b632ac1fe38a114c083496b5bb8b211a174695c29862633c283bcba5be7c2ece82b9d517c0a8099ee1bb1624838bba8b5b73a463e196098986130a84be1cb8080e643f3f4b08f1b84d02b10b932a3cd7a921a1f97ab8f38b099bac9df962ddeccaa1976be86a63b39c59511a07a29046ba6451a2d77f4c29070d9a6cc305ca9d9585010089ec435710452390c80704375458636921ac93e5294dab58040cf309a53ac808e82fc571aa09137ca8504fe2e71455d085f42ab98a9720a85138fea10cf996137e361d1861b7d346cab82bbfd9fc0100949e945279a4757804b29cab22090a8cc6c39495c44273bb0210e1495d139650ccc60097e77573884da44ace0c6755a8454dedabcdc92359ee73246b045f61da9ffa172a95a20315b688461050f052301f0b1700f6070b95218b583f026ba17be6111e0106dde5bae1314dbee2629d5cb291d396bb04cc48b92ecab20c476bc32f155b05964b49649d9e5a8f3f9bcb5a192cc8d9b3858a81e9ba89a9d7a88ec90838f862472c2f60a38d1b444edfd411f8b4c0e4f090c5f353f897cf704801422861879471482a956f591e16046ddedbbd68b5768b14001a335a676b75bff63ae7614b1bc03a04460768a12dd3c99ceaa6964db1ba11173711c7601fbb3fba511c0f63251567b51de163b83373cf02c0053516c152425e0c7adb018571160c0f4a47c026404c0802428c0a373c991ee5c4320ba566705af9490d6af3a53aca021ee11f53b361072688f46526184a23914991f3ac7ea28c20878990563cb96688707099465ff3b65e46280a15a11bf05672ecc7e31934da8226997ab2a9773a53059d3748295aa10b08d394b885944406401470056b645315198d2f42c18df155e053a63d147b436aa8502ca97833c0450bcc48851d82e21866a51dd7418f3c6ab231c7067a874028688469c326b5a49de1fa3c78b31410dbcd5b2572c8485393148da9f0c2475a69f1e96c610badd664c99895021f497c13111930880c02d9c8ad7a1309085826b4116f9a9cd841981f766944137de5587323dccfbba28366f86ae7a7481c054b2dbab86823b77eecbe7d9088a9ca882eb7aba5aa23c27209df4760e70b4876b709bfd225b0ea9644fbac9de01df90648a25b5fa9a48228872ec2cbaa09880100bc24f1414102d92a5a206399295333485f00c111ad49c0fbeb5f4149477e46075377967c310fb5231b9d6204bc877c31c524bd76b5edf23fb9b091ffa3bc2ec64423b02f673505d5c69dfe472d8df62f9775852b901000d84e4237aab4f32226272766234dda706fba5962e816a98586bc2a5bcdc1db80bd9b18bbc3c82d01cb1b67369f32741d50ca57a45c45667d5e5428824463c8a651afd95e995a4b860043cae74e265aaed3320414989a346a63f0f0842e59972a91bba62559422705ac6422d66098747a85737abeb01c00b4b90311081a17c6403726ca39e27c8d426845fb624a956c39bbbb404a8ef5073e37078ef535b9eb581783eba401243b02d750f5034d4a366c197994189846dbd82712663a0fa0beef5847622a904b04983b519955b717025c01d9e5b928d4b860cb0fbff76fbbc22b4761a5a584770b25806bbccb94fa7312233027f5b6c97c97a4fc5dda7936b090aed1c9478a68ce883cc9b8960e8755485099912dd509e9804e33e86a12a75b53d42f0c784c6a73732a471e44900d41ec9c4c0b006910202b1b2dbebb65b5d7471f189faf194e642887c5631271649662f4b235829644198bf8e965d9728778a65405c4417eeb7ee25502618ccb0a0a226945adb0d73ffbd2ca47a5580d0803a56b3c3bc66e877ccf05741e29501bad787d8b588f97c20c8255687ed3aa1631122c387456088d1209c4a5475f61d12c2b60b1776244512a08807c09e7c7aaa3935125f235f8e872bc4356a21379bdb84a25b132f4449561e96bbf8776fab1c681d42575a1bfc0dac357653996d41aac4a9341196da05c49ba84a4cea37c818ba0f0408c8c9335616410b1d479ca035656119236ea9d6979366163791648088fecabdc7c80a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab955468734662471c953fa516b35b3a53053ff396b7e2798fe07a2ecd549d6c063fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +expected_public_key = 28376c399946f6089f4eaa70736726a20c6e2acc75ddc880fb015477d3ab44c36e047c4bedcba5e2d775628154eca695261b5825ba495f84c925f73c5e86b59fca1a535906c29b0546134469aa2fa9a273e987c50f2b5c1f0b52d79984246c653bcccab49c172a990a72d93ce02c2a9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f4715b977580345b13cb945ee374a980a3152e1690469c47f8310d02ca01dec8f1a149e6c1a1a4ff0496c18c8ebc67b79127195341b132947ba62a89871adc0c9b32d951acfe88334189aebf89991c9b73eb0b68e6c2aeaa1455aab124160179ebbcc40667ec7159d8991897cda76e31a8330793fdb035feffcc74e251993913c6aac99e5ecccf5f9289343989bab7640c9c2a9e2c622d0214cf9c696e803d9e119af0a90fba50199032dbf491fa5e260cce4b92b8c9892c8519ab23031d9c3c53c671a4008e8ba31b3d1bd4c9602f045b92e42040ffa00f441579b105562d507d6117a9f5b9fb6e50146ca47faa64165c84a3c9a77a70963e3a6a8a28b658998078cd91cd4599cbc21ca68d13395b907e395b581b490b3007af66cbbdb222d78973b7b69b37c77547669695c347deac03374c209fd163984f03f59a6ae8de53a169041c35c99a4c95f25a759ab6b2f0fda12e1744a85194ffa736be1d67d7977b32eb7ae6bc04220c8846f157aa7d05c12c02eb8d3053059ce8ecc34791953f00077a4e13c001a48c28500c025c4bcd11e5ff83ae9e31e0a6788ad70a71c1c0d5da418c6e6934fc959d70259b606c986c70348cb7cd11a46be201c474b819d8b54b538c78a06a9bcf905da7469d9c045686a3b38e345e64994cc0785fc12073ce961763074f4d2aaab6c059fb67c947889dde52c8ffa432c9171cd16133d337f10546d864b3cf3243b2f3097f3314976c183128aa1a11916e6365749910600e64d96b663b236c43339cf979c717c6b03056081d9ac4301722330e13cdb0a75de4a4099f7a615419c82e10c6eab027447a78303697d8089647263c0b39834986f8da41566dc254891bcf93014b4b33e2be203b4e2c67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_private_key = 17061bd1a9b682d6741e754ed82792d3dcc88d3c8e5cd88bed131bf12176af10c5b6d690be325c67ab7b05c67eaba3c3f58838897c5a11861dbf757f9937cbfb01a668c84f2a0ca7627497a4e4417331506cc28c68f550c9ac96eb2030585b306ba62f020281b8b59470f0b59a3c8036132556b381c7cb8d8c365912d2ad91d01442b534fb09bc9a692e5941b90342552207a8d099b0f628cd8acb5f3bea9d5985a050a28f69743f5c22392aa8b185272fa8d19969f5c0f45354eb18b961066305f183dc29891f4784dda37f8c9c058b500e1fa393c2d92f37175c8176cf4fdb746e377f0c97aec1d43da947c889269eba88951d925392225c5eecbe1146b255011236c34517c3b1cff1b91d17823ff4b2273ab1b276c0c89b87b086b3e0588b9ed14ff5e303d465744528388bfb90d42414b1529dda707d2ed515baebb05667580a52ad78a211a8cbc0c8f1274d23504f046e1b84813147255ecb6f18314ab1c3187b876dc97926cee74c00c956ad1341af66a4b89281d1fc2caa2620a806b7a03042c8d401527077ecb91c4fd12f62f0045498b1c43042cf103a9e73430a0c5298f55f4e5517f5e393197a5c9400705758c9a66307d263a5ddf72771857c29a97216a4aad7824e2dda2c3ae7c38bc851bd2c65ed584f789a342f4056f3da3315855c675557cb7b2177c3847b21a777b3b24e74572e1554285347b116a7210248f6307bca828369b8cec51bcca4b707e508c3baf21560b5450e4ac9968ac543485e21722a7f535f26216bd7378fdf28676feb7ede34aafd981a805729c11b4cf9ca7be46a3df96acc14cb4b6908be9a79ae6bd13980e6bd997a1dd8553a98b4569681ce78578330181ec7c1b466d1c226ba0c15a6bfeab52e80a118b0a3c5e9657910063cbc2675b5a724d1f867bf82abe2088e83d3ac0f55827f864b61ccc439906db818319e360fb0707cc0c6bbfca62c7c00b5a1a6341915941d6563acd410afb960c1d626dd7875047129a2b13750e3a6c491616de3b44b1888d2bb5b98e118c4aa6e2e386dc933b441067ec7e6b2bd730fce342c17720ab3d5b7154c8228376c399946f6089f4eaa70736726a20c6e2acc75ddc880fb015477d3ab44c36e047c4bedcba5e2d775628154eca695261b5825ba495f84c925f73c5e86b59fca1a535906c29b0546134469aa2fa9a273e987c50f2b5c1f0b52d79984246c653bcccab49c172a990a72d93ce02c2a9c56a9cc2c8d808b8d6853361f9977db4bca0ad75aa65c76b9c47f3f4715b977580345b13cb945ee374a980a3152e1690469c47f8310d02ca01dec8f1a149e6c1a1a4ff0496c18c8ebc67b79127195341b132947ba62a89871adc0c9b32d951acfe88334189aebf89991c9b73eb0b68e6c2aeaa1455aab124160179ebbcc40667ec7159d8991897cda76e31a8330793fdb035feffcc74e251993913c6aac99e5ecccf5f9289343989bab7640c9c2a9e2c622d0214cf9c696e803d9e119af0a90fba50199032dbf491fa5e260cce4b92b8c9892c8519ab23031d9c3c53c671a4008e8ba31b3d1bd4c9602f045b92e42040ffa00f441579b105562d507d6117a9f5b9fb6e50146ca47faa64165c84a3c9a77a70963e3a6a8a28b658998078cd91cd4599cbc21ca68d13395b907e395b581b490b3007af66cbbdb222d78973b7b69b37c77547669695c347deac03374c209fd163984f03f59a6ae8de53a169041c35c99a4c95f25a759ab6b2f0fda12e1744a85194ffa736be1d67d7977b32eb7ae6bc04220c8846f157aa7d05c12c02eb8d3053059ce8ecc34791953f00077a4e13c001a48c28500c025c4bcd11e5ff83ae9e31e0a6788ad70a71c1c0d5da418c6e6934fc959d70259b606c986c70348cb7cd11a46be201c474b819d8b54b538c78a06a9bcf905da7469d9c045686a3b38e345e64994cc0785fc12073ce961763074f4d2aaab6c059fb67c947889dde52c8ffa432c9171cd16133d337f10546d864b3cf3243b2f3097f3314976c183128aa1a11916e6365749910600e64d96b663b236c43339cf979c717c6b03056081d9ac4301722330e13cdb0a75de4a4099f7a615419c82e10c6eab027447a78303697d8089647263c0b39834986f8da41566dc254891bcf93014b4b33e2be203b4e2c67b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791f7310c0531060051469ffcd2f88e3200bec6c721bca1fa4c9e7bf1773d7ccb19d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +expected_public_key = 2972584323c917fc24681b6168eca204b8210bb3029e05cfb2e08d479b413d987152a0203f0ccafc45625647b57e3796ac904643c73e9cd26653600209a62bc6498de68223c990672470c2a2b77289f41f5e07ac7320500a7c30a9e99544f7837dab6e7b7b7652751457d96e23080432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b576a242131aca3cc9c08833304dba85c07c212951af1303e91206f4a54c45e9ccaa1e96fb07bc27707311aa2a1438a9ce7355dc5861592a4cdfaa13e66245ebe67610de4875b57181e118930e671b34104a38859d203ac064b417a30aa8d23af7c5c732f4c57e8359f0b698de6320e0940a4754904bae082ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ad9109146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ed52e2438b6132400f3bc06f00c71b6669f02735229b9b1a5b580cf271003b498a6c6826d553cc736a19a6cafe69058ae8717b91842d92bbdeda0670118116b719264465e61d86b975a843a5c62a056b9af8a7cd402a747a6b758da977b12214608cea52540dd390135e28e6160468c97b713826dbaf27aec20b34e07aad340351a64223068318113c5148861aaec535d15368a6b096b559f57b2842713c44d46bf001477ca0c92bb47c5c502b4e5f22e7aa087c26bbb36d9acb0712af2fc7c09e55f1fb71238e33d05d41d186790ad725afef46173134620656449917d3e52320c8542e5d725ece72390f637af286a8457165f5622608c0813da9c78e83334005732246091aa5877e7ae460c18ba856d030a856a749d2740689ef036fa936ff3e25dedc97a72f539b3a32f286a02b79472f28089a6b4b9b42134b6ab252f377e819c233a16be6361a59b4a9d52aa18c18263fec2602ea9b8e9164bca2946a31a892093af891a3369a01e169594d0e50fd5b3b144405ba1139a8d167564943530a26522f3216517144937cb5a14b98300a03d6bb2b8c13eb23355590cb5989a4e26f242ed7b977a36c65e768f21e9417f3180c304009394cef9bb74fe1306337b7100938260c68dfa7910df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_private_key = 96d7a99c7bc70e97783a8b4e9e6c33b02564b94918979154f6117e8edca085a680ed1a205a91a64d62032e0bac503717b040cb5aa25da6c96981069a516336ea5438d97315c4971c3808357ef20c7a9540ba27509ab9410c2a0003c81b0a072f1187239c772829baa0892c22fdd8baf62960fba2118ed5c000d7486dd05e9b252726804078a08a672c12fea5798418cc02c2c8d475833b4ca99906a9b9d91e0c2aa362fbb5962a2ad75a64edabb6f12c1fdd0b7639732c0a2190af04b35409125a3851b4b53ee7591a559986d7f8bab94baacccac6c06c82fdd166f31404da49ad4213c4c7f64941c1a12460abcdb72eb4f6005792cbe2b11707ac56ba54737f082e940004a2a0a57a650e56a45498674df03165500558bfb2a63a9526b0088736c710b2938d7b7a2347277358d8b842ac9127a8bae5cb02a25206f2522bfc0887bec9b13fa170a5f436abc0b3027796fd4aabd3f6054368903de3119b72655bbb30bc4958ef471ce57580cb96b9d875a3cff34b1c8492c412a272db89590cc717006931589e5d546145413a78b7607f38066ab83f8701b874689b5894989460c2fbb108739333ad3928110419c922ade0a21ee5106d7171087d5994951303a4760a99f6ccd75892840ca8947651637cb39266abd80584fd1a197b22b6fea5c50ac1640026bd0e2810a2591440901ece073f29b7c0b2c40f42d71d26997c6db26e77ea3393faa75249030bd0638ec89892fb456e95c1aad8887f00ca3dd704eef8c26560b4caa39874e4271c185ef06ccdf1944fc838a163fb8545f32b107517bca29026878902830524bb51c77ca5b2274aec9106621701664a4eac03268fe109427b2d57f976fbb75a4b39a8d8f663264328ddec9dad23ab87809ef87a16c1b25addf3c308714f57c9489f25a4a7a414c279b7aae576be7c95b2761e242b45b174065d529b480b019cb19c80185a94d6046be2aa95a7c03bf4933fe65765a8cf60577c49c5132865b0f5b265e86543d24a20508157196c5d0bb91b5b247bc200a2cb32215571395e216739b69f69d26905015bbf732aafd63675b12c65156e2972584323c917fc24681b6168eca204b8210bb3029e05cfb2e08d479b413d987152a0203f0ccafc45625647b57e3796ac904643c73e9cd26653600209a62bc6498de68223c990672470c2a2b77289f41f5e07ac7320500a7c30a9e99544f7837dab6e7b7b7652751457d96e23080432a495f6c7cd2824b791f8c4fab45f0f94a97ed67b576a242131aca3cc9c08833304dba85c07c212951af1303e91206f4a54c45e9ccaa1e96fb07bc27707311aa2a1438a9ce7355dc5861592a4cdfaa13e66245ebe67610de4875b57181e118930e671b34104a38859d203ac064b417a30aa8d23af7c5c732f4c57e8359f0b698de6320e0940a4754904bae082ae6c4d22db5e6dd5ad03665906ca500f6c8d35563ad9109146c89986c3a0b19c8dfd04c52ffaa81153c2e8b6c9f34c366ed52e2438b6132400f3bc06f00c71b6669f02735229b9b1a5b580cf271003b498a6c6826d553cc736a19a6cafe69058ae8717b91842d92bbdeda0670118116b719264465e61d86b975a843a5c62a056b9af8a7cd402a747a6b758da977b12214608cea52540dd390135e28e6160468c97b713826dbaf27aec20b34e07aad340351a64223068318113c5148861aaec535d15368a6b096b559f57b2842713c44d46bf001477ca0c92bb47c5c502b4e5f22e7aa087c26bbb36d9acb0712af2fc7c09e55f1fb71238e33d05d41d186790ad725afef46173134620656449917d3e52320c8542e5d725ece72390f637af286a8457165f5622608c0813da9c78e83334005732246091aa5877e7ae460c18ba856d030a856a749d2740689ef036fa936ff3e25dedc97a72f539b3a32f286a02b79472f28089a6b4b9b42134b6ab252f377e819c233a16be6361a59b4a9d52aa18c18263fec2602ea9b8e9164bca2946a31a892093af891a3369a01e169594d0e50fd5b3b144405ba1139a8d167564943530a26522f3216517144937cb5a14b98300a03d6bb2b8c13eb23355590cb5989a4e26f242ed7b977a36c65e768f21e9417f3180c304009394cef9bb74fe1306337b7100938260c68dfa7910df6c7ecce93fe398af45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723152c13a9a4dfbade0f98e8a5136358f69c93f0722addc008952cf72e1bf350b1b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = 334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +expected_public_key = 3a090559a1773744077304007ce9af65672c5f221ca99685b84abb134800f5616b734c184107c8c5892c437b8aa3d0882929b8dbe394c1680e33dc2c706c8db227c292fb0a89a8a29261bde4fc1dc12663e8ac502e473e58d6206a90602ed87675287ae301d0ae94ca923ac8672a031b5840de90121b72c58310cd924c12787428adb9b09ea0b8a2226b84e9b5cbc2930122b5027c70a694238f78c8381078393178c936b8de4c204b4a31f9f72bdde751cdd0b31b2c840752181d838ad37c637cfc7584f37686fb3a31020a81db35c5f7af49071470b9c468dccd7c258780cbaece579819d8c766e873b6468718f60da09539fb7a34de11a70c45ad71918925467d8807cf8788318fd010a6a57ac83473d332bb9f2411cffbc7eac87cb7c9b1fd456dcf74896422513ae691cac20d03172728b11d5ecb9b9c8b520bc628eb5724e1b415fb8b99b519c1700537c2a22a2fe52e45a748ad5b7f4366b33b5a2cd8192f9ea406e181b4ba47459aa08033498b6c1cab1fa0327df5afc5a87f0806c6b26159886b40b3c8b068a7208dd12a7c150a679cbadf3b27457883231a8c351c04640099efb363bc962262d9570ff8b425d206227175de94c5cc010d9a3277e2c0055d84475501877d608156868708d5c725357b9df9b47e4c9d7819c310900df9926c0ef230999aa2b420860a6b7fdd020fe0345e8d539c5c839c3c11a270f360e2f93fb61507fd86442379029737823bdc445f05a9ad3c7e29804068fa96035a95459509b53c426e9188a0f016e8857182119ae936656d60072549557891c4fe0278791b58e1d0bcc4b322ab249865650be6946f319c7f0bf58c72b819b79c1b78982b2e24a8b15a1c166cbd3feb06eda478fab90ce7b16935bc4880f78f7d2a80b5b41095a53f19f46ccdb84bfbba460d1c33eb923eb56024dd437cc256a610920a650bbcd3f54b8ed8b1b0814e6f4acf94617e2b68735210bd263597195a6b59864c21e371c1d947f6357a4e064fae992dae617500794af82a5911c15dac3416ffb21ba5815b79a79c30ba72b66bb5d8d2800e581579219b2f0688d87a1346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_private_key = f3d4a8bba18dcb278d29b99dffecb79ac90496826fa0351f37495ef081b1e0a64b680b95f136caeb851aa2d58905f06d67220eb4834260140be1ca248adc2d78a05e4d41815405be653b1585a78e64cb52e4a656eee07f2d4a39ca50894fc02916f0a86c6939b3514e446cbfa0e05cefd2cd26965260cb967a09485e2cc8dd6c0d7c452f281005e10a62b047217864055c78bf2de7208b92b0e0a01e15315bafac07ed3c1a748a1c8bc6c81ae21afb04ba76017a1bc920fe546c949235ca61b37a3612506350c7eb5202f267afe01350f979ea679f21420c7eaa4818e5180b258edb390a21588f0362647632a00d150fdc540bfa785ea2680e5e90a8d58962cfca3da824138ca3c8e7d448d5080895f85625372028a5176932991779030ae8c04e328e01f1574d1c4ad70acd2b197f9da55d01a7c8920914896584c9fa8a6c9183b05319e2395464893c491a34453451295681b9e15908d16986a80016c0bf2153bc4b18cf59300d45a00ade932ab816c5cf10cd72a4b1a3f831ace60f0116594b0cb96b8b1615099e92887ffa7744a3e769e6bb6072b70385fc0bd30000273291b101cb1bd77ea7abb5bd7a53f70a806419022d873360f96a636b1d0d59257280c94620335603a3b8a73d85a1a0ed709680e04c5aa233fdd67c8ac5b20ed115fd2c892a6579c308bc9a693d3376338c64b855169246a98428e49af4a24b8d53cb4ee5be29112001e103e7589937618556221910401d0471c12b6743a6b2b3c701a72a6a859d933eb7833a423b5622c02d078b6ac1a2582c30cf208895e76b4b226cc547cb1dd6e376b34199534aa103b417cad5a67862531265c28506051ef180b9e67b3ea1a40f598e78908a9e047961b5908501417f12667b0a7a873a856c1ba921b5cd4d61265936542ba1ba0dd619754119fb9c91c5951b9fdc1945f32f02c2b0c7c8c20ad3805b13cb861ac28634828c31595ab163c343aabf1351738514189232369b0c92582555111a35d074ebfa6aa81333890a39b370bff7bb7dc6384000274575083c32bc004c2a88c5a82a38fb682ca00593f72487f3403702c33a090559a1773744077304007ce9af65672c5f221ca99685b84abb134800f5616b734c184107c8c5892c437b8aa3d0882929b8dbe394c1680e33dc2c706c8db227c292fb0a89a8a29261bde4fc1dc12663e8ac502e473e58d6206a90602ed87675287ae301d0ae94ca923ac8672a031b5840de90121b72c58310cd924c12787428adb9b09ea0b8a2226b84e9b5cbc2930122b5027c70a694238f78c8381078393178c936b8de4c204b4a31f9f72bdde751cdd0b31b2c840752181d838ad37c637cfc7584f37686fb3a31020a81db35c5f7af49071470b9c468dccd7c258780cbaece579819d8c766e873b6468718f60da09539fb7a34de11a70c45ad71918925467d8807cf8788318fd010a6a57ac83473d332bb9f2411cffbc7eac87cb7c9b1fd456dcf74896422513ae691cac20d03172728b11d5ecb9b9c8b520bc628eb5724e1b415fb8b99b519c1700537c2a22a2fe52e45a748ad5b7f4366b33b5a2cd8192f9ea406e181b4ba47459aa08033498b6c1cab1fa0327df5afc5a87f0806c6b26159886b40b3c8b068a7208dd12a7c150a679cbadf3b27457883231a8c351c04640099efb363bc962262d9570ff8b425d206227175de94c5cc010d9a3277e2c0055d84475501877d608156868708d5c725357b9df9b47e4c9d7819c310900df9926c0ef230999aa2b420860a6b7fdd020fe0345e8d539c5c839c3c11a270f360e2f93fb61507fd86442379029737823bdc445f05a9ad3c7e29804068fa96035a95459509b53c426e9188a0f016e8857182119ae936656d60072549557891c4fe0278791b58e1d0bcc4b322ab249865650be6946f319c7f0bf58c72b819b79c1b78982b2e24a8b15a1c166cbd3feb06eda478fab90ce7b16935bc4880f78f7d2a80b5b41095a53f19f46ccdb84bfbba460d1c33eb923eb56024dd437cc256a610920a650bbcd3f54b8ed8b1b0814e6f4acf94617e2b68735210bd263597195a6b59864c21e371c1d947f6357a4e064fae992dae617500794af82a5911c15dac3416ffb21ba5815b79a79c30ba72b66bb5d8d2800e581579219b2f0688d87a1346f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f97e5b18cff525ef46fd8a6aa6e5e4b8d953fe1e67b5771d1b99ff18e754553beaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +expected_public_key = 1cc61043d28bba4a2b4ed1c19f1369c6d7578ada06533b0dd8ab5afbb3bdc5b601ff108031d017b3d89aa253c90c7a4a7e368d528773b62c6aa38046de9b6651cb1f5c353a1f2c99a3e7bbf1679357219417c10b5c1c60348c5c22424807903ea4e9c685aa5b53da5ff92034c7c15a51777d7a637529a274e767539bd68f2b0281a8e13c08210f17ea7168b210830b0d07bb61e22b2f87323c8debc3c97a399de71590a23806f1903ce109ab804c5657290407463ae5bbe24c7fa62230c83288eab45edbc28248d89890491b32ec4d214263557b053f0642f327c78d3565df61796376a6e04a1d068198125ca6826a4c34e65e30a7946deabddd3062178253847c37f92a9cd1a749f1d12fab1cbc0017b468426d8bcc26422cc85e97199420a9367000e7f52e17b4bd5dbb6400bc42182cced4c564ac160d2932ad801650cdf29ca854a0b2d8918a3a2320c5915c1b37e6b3b0f08280fde7c6f2543d2c27728dfc8eef776ba012860ed55906a3a28ca88d5550b540538272c01ea0f83b78465ab8f062df740da6d31ed95a53b5ab8301b79d8ec6a5fc503bb0a6b57ec99085da37b3262843017f9e572b15c7b8aec40ef66755a1ac91856a8d0c8a0b1572a676b8ac671908c210c82c5900abf4696e2c73ebf3ccc4b76df3f74b930977fd616d31f48248c578a8d63b14bb48fe5c259f9734760944ae78164ceb699b1623ee648330019d79b49b650a33b841622b0061a4b79331a03da78b1b70a3901f42159bb4bf7e1512fe8483eff80e3e241bd94aa8740862a3800313b0c160a1302122951b620255d6c8beb52c7aa2ca1fe1858bb60b6e6077a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6d0058bf5477d358b630b42daf131ecae24e7f33960841415585101de67d96e2349962685fab259c312d175326268c807e036836f75d43e61cc65274e42b37d874b2c989044dec8aef59a2663047d8f6a0eef1649d7150b20230cc279baaac5e2a30c84bb1bb6475bd2d4a201863ad207674f4dc25a3c07cf9fb25b1d83b9cd3942b50c423d0b31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_private_key = d21b758292aa9a363fd0cc835cd370b7c23acc51348efa05e2ec1e6cc6aa13e81f40da39dea5bd71836aaf33196909cc13005c5ad26b75b6b0f4f233268b710277acfe0a3325e384d58abb7ccc0677258dc269a1f312b33f889826061abc5a7cab01cf7d6733a86089dab2c01c8214e21b0237eb4f0b446e083bae64ec26eeca1bbf8b77042226ce478fb44c5aca031935fc9478c401a92abd659c8d3cc142ae72943c669f265ab9d9d6283d8badfda1ad3d533895630dc31559578cb89aa6153563be7366909f949be80b5f4eb12aa49c6400a298a60c00a2fa36b886437223bb55b81598912213e188a210c9b6b49b329310a990c44f96ad8ed42fbdb31200521c5756c1d500a4f9b7c3310827e5c9952b9972e7328c38c668d1d1bb0f199d8b917acf7047278245a6d06d2d8bb800643210f7a1373667c9450447f86e0f067f57c16469409cbbe77abdb65f652b2c33456b1e87428d0abdae211436b46a035b630169ae1f044adf26564841240a3a956fa7ba0b931baed47c93364b6ca8273a195e75fca7bd52451e5c92c78b16c9f19bbe431ab8f26ac3dc797d96793e289882585edb1a7a39c51a60242e330401f0d3b1d0dc29000287d2569139e05d0816421bf03e509278e79ba645c66602592429799d962a6e02a61682b410b38963d0f8363ce43f08759cc987b5986ab366a87e05c430c78281c72864948282d3ca682e42bf42c57c91fb09c2b596b33083289b5a0b39c997d6b585653fbd9122f6123308177bf6d6ca614255989ca6451783e607b06bbb0533ac5634722a267733d67747c8447366587f6be662daa3bf86d078f946070971a1e823c4f0a919f329cf584317b3d9a468c13b5d398c33592272175fbe27bd7a30ce0f0284e5f380ae4947d5170c67b3ac0ed955c81a9ebd5845aa38659f186756cb94d41698b3e1387bccc8eb03186e34bcdd0532e775749ea928c8eb886ee0bcbf204e62b050b199807d216428d48ebaa108e3ea9783a340c6803ba1b206e5fa107982534c33cf9b757af7459ee86a1fed072530d31c411741718b8bb977b60242ba45437f8209871cc61043d28bba4a2b4ed1c19f1369c6d7578ada06533b0dd8ab5afbb3bdc5b601ff108031d017b3d89aa253c90c7a4a7e368d528773b62c6aa38046de9b6651cb1f5c353a1f2c99a3e7bbf1679357219417c10b5c1c60348c5c22424807903ea4e9c685aa5b53da5ff92034c7c15a51777d7a637529a274e767539bd68f2b0281a8e13c08210f17ea7168b210830b0d07bb61e22b2f87323c8debc3c97a399de71590a23806f1903ce109ab804c5657290407463ae5bbe24c7fa62230c83288eab45edbc28248d89890491b32ec4d214263557b053f0642f327c78d3565df61796376a6e04a1d068198125ca6826a4c34e65e30a7946deabddd3062178253847c37f92a9cd1a749f1d12fab1cbc0017b468426d8bcc26422cc85e97199420a9367000e7f52e17b4bd5dbb6400bc42182cced4c564ac160d2932ad801650cdf29ca854a0b2d8918a3a2320c5915c1b37e6b3b0f08280fde7c6f2543d2c27728dfc8eef776ba012860ed55906a3a28ca88d5550b540538272c01ea0f83b78465ab8f062df740da6d31ed95a53b5ab8301b79d8ec6a5fc503bb0a6b57ec99085da37b3262843017f9e572b15c7b8aec40ef66755a1ac91856a8d0c8a0b1572a676b8ac671908c210c82c5900abf4696e2c73ebf3ccc4b76df3f74b930977fd616d31f48248c578a8d63b14bb48fe5c259f9734760944ae78164ceb699b1623ee648330019d79b49b650a33b841622b0061a4b79331a03da78b1b70a3901f42159bb4bf7e1512fe8483eff80e3e241bd94aa8740862a3800313b0c160a1302122951b620255d6c8beb52c7aa2ca1fe1858bb60b6e6077a8cb8816f64ce348c4f38791a5185121b67225f7a166d38003dbb27213bc6d0058bf5477d358b630b42daf131ecae24e7f33960841415585101de67d96e2349962685fab259c312d175326268c807e036836f75d43e61cc65274e42b37d874b2c989044dec8aef59a2663047d8f6a0eef1649d7150b20230cc279baaac5e2a30c84bb1bb6475bd2d4a201863ad207674f4dc25a3c07cf9fb25b1d83b9cd3942b50c423d0b31a46c562a8378d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b247b5c67fa6e0ff374f691540fff0b4d14d4ed8a8a8c48b14b2a35facb413a5ee60f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = 995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +expected_public_key = 8ed95fa3d30d9fbc979dd7cd223a3694b874c8272103685e3bbbb8888117d53abc7667b4eb158a34953147354f6a5714aab10aac07299c3038fedc9b0d3553734401be62862ca82277f57f1e6225c5206a86e175ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae5b1b521c6af59c721ea23ee2ab0ea2e451a8831a82d098e924604d6b02e151bc43e761c2324368a643ea23bce9fcc7e2502285119343603a4cd5bd444798fdab21d5369f4c73477e3891aab51e1b11cc55b3ab67cbbfd5f141715a9ae4681cb0f0391abcbb48ac63c8a707677650aab59c09b43dfae8653d887a6c2c0664096e551929fc0a00167429ece069f0aa266c542d28db4a42250fbff86aeca6a709c9a25f384effc74c0c7b32b4a616ef2a140a8c96c8b56e61f32963505775658b6c81cb40c2b99e43bd8fb8a8459a73d8d083ac178225461e83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91a7250499891698553bcb9d0848abd391afd195cf39a6213a078161d7ad1aa5b28b1c442f6ab732fc14dfc085f2a6475d4bc8f897a7c1d3b3e0c1203aecc5d5a8287e34c6e3f2a920ec8065644a373453cfd796a58c03b7e241bff2986b3c6c6ce4064db18137862d716c54c154a7e294b218bb1df2d76f8f36847288c76ae21e1967719ac92aea8b8e50706ed8cb06492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4626f29fe843623a55c02b1a0250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad196098b1a1383ae99f2ba6384a1c39c69350fe22437c1c00a651aa0932a771e09e4efc1abb893639f1340ca76a8cbc4c605257e14969d83cac02d131dd4273ac467b6db186e9086548224a4a1526f769a90c93101e26a2c1112744844b0584343fc9b35320b841961fa55016c9cb271570bdfc501d68f9557a920db4920d15e2bea64a6aad743eeac97560bb024c70c099608e55d351fd1784673635aa1b26b9248528d069d031658eb2c559876a7fe6adca630e2f2589de2aba5fc24528a982e2e5ce88a73b80121789522f63602ff0340f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_private_key = 7d926fb223c21d99084c7a171b6575cc04a2d43349519033fe9a24fa8213c5308774e9b41ba51e4347943d2bb1f32517ab6c5444d97e0840821d2ccec62bb44bdabc9fc22c8aebb96c49ca966ab9949b44eaa196682148adacc20737b85c120bd662546ec98d3221589f3a98dff6a531789a56a4337e2b5f6237caca4b3bbcd756749524ba16a0e4aa9d5bc5090117c342b03335bc01e9dc1ee8e560b90b43cca0bcec177b86810dab7b179a67a56aea2e99b69783a629e08cc4ed4950552b53cb29a82ac68a1bd896262740954256315898c5c58cbba58c7c7173f83bcacbc73067e44a5e72c054d05ef40a9b5304cb4c210798556bad251c11f2a726d3a1eccb8863405e2ec3274285bae1e196a4a26bb7d80888a53ce87641e583600bf148124806417c08e9c76c620536f37940322299edf0caa3b46ec3e05304bc354239625da3293905cd59d666edbb3ffc40428b0347979244ad55237d4c7334e477141cabe315cbbebcc2cb2ba10a48834d83163d937a234c4215ccaaaf1ca13180a1a8f1aa17362635da8967b47c81a172ff3171871453877b89e3ab70b2b43eba3683da73b0549290ca551b74d52343950f97345685b602c9d7566aa394f6707c335954051c0753c1b482514af5bcc61b65cb36896f38b46c5dda7fc2d536035c70f905077d299e7686b75ea5b5beba5739ac4fd0d84d6f7a08dca071b3f43611f48047c7612d638a6af602ff069dedd2379f519b819c369a0ab216543146e83cf654c22241810b437ddcb67629d20eb61086a17c42706460962c15fc0aaec5c5651dd7b9f53b3f7e85c70fd09f14bbb6a6b3213ca6c6d2bc46b13024b6593bfed9ba6c9740b655ac70c33f17b639fa1897d40cad4e98316e457b5027343b4b8d3e20ac082b0001532558baafb43ba273c03ccc36bd17d039d12c316668c33f15cf5e3269da7519d950c19ed35ac1894255019233057bb0417ddf8a7547a93d06f6127e717e0abab754783560c81a782a1805fb55b27c10a2c014230bbfbb808f6f973be9195d2fb5459a19265d0a93d423c8340a4ac1a4cb65b2caaac903647bc98ed95fa3d30d9fbc979dd7cd223a3694b874c8272103685e3bbbb8888117d53abc7667b4eb158a34953147354f6a5714aab10aac07299c3038fedc9b0d3553734401be62862ca82277f57f1e6225c5206a86e175ee638bcda6665e3b58b01bb74ea7701d97b3a909ca7bb9b4c4d89460cc4aae5b1b521c6af59c721ea23ee2ab0ea2e451a8831a82d098e924604d6b02e151bc43e761c2324368a643ea23bce9fcc7e2502285119343603a4cd5bd444798fdab21d5369f4c73477e3891aab51e1b11cc55b3ab67cbbfd5f141715a9ae4681cb0f0391abcbb48ac63c8a707677650aab59c09b43dfae8653d887a6c2c0664096e551929fc0a00167429ece069f0aa266c542d28db4a42250fbff86aeca6a709c9a25f384effc74c0c7b32b4a616ef2a140a8c96c8b56e61f32963505775658b6c81cb40c2b99e43bd8fb8a8459a73d8d083ac178225461e83a4ce9d6c6133da8d1f5b4139457762ba5beabcbb453b9c91a7250499891698553bcb9d0848abd391afd195cf39a6213a078161d7ad1aa5b28b1c442f6ab732fc14dfc085f2a6475d4bc8f897a7c1d3b3e0c1203aecc5d5a8287e34c6e3f2a920ec8065644a373453cfd796a58c03b7e241bff2986b3c6c6ce4064db18137862d716c54c154a7e294b218bb1df2d76f8f36847288c76ae21e1967719ac92aea8b8e50706ed8cb06492a58ceb932f2284c023c6e3bccb303d6bc56e842b144cf68fa4626f29fe843623a55c02b1a0250d7c272855e0118b3a553bcfd46b7563bc5b2f5ad196098b1a1383ae99f2ba6384a1c39c69350fe22437c1c00a651aa0932a771e09e4efc1abb893639f1340ca76a8cbc4c605257e14969d83cac02d131dd4273ac467b6db186e9086548224a4a1526f769a90c93101e26a2c1112744844b0584343fc9b35320b841961fa55016c9cb271570bdfc501d68f9557a920db4920d15e2bea64a6aad743eeac97560bb024c70c099608e55d351fd1784673635aa1b26b9248528d069d031658eb2c559876a7fe6adca630e2f2589de2aba5fc24528a982e2e5ce88a73b80121789522f63602ff0340f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd9928e49b73bae3b0285bbe1676eb6fad2641e7354e4c0a4feb0b74bb16708b01351b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = 3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +expected_public_key = fb32553b02b45153901b5951ae055f75a270a6f1b4d37cbb975b979278aff301470513b66f58817e6a5b2ed17891f24a84950be275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb89267f12daea09828f143cd6c7c133a38ce82788a6bb88126956f30943169b2e4a18357e43262d6350b07651a6b2b2b227436405ecb5655e5892ab1a0ce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8fde25fd8aa691a95ccc7da9df35393213322f50a61ad4113c094cdaa568b1f43517692c4918c2590a221fbc0a313d2b4321b9e1a973492bb519c010ced1c590f0a61799832c15012e04550edc12414f4cb7c32ac3a1bace2f9250caca0d027bfe238344e278d6509796155386c1ca904c34727f0772c12b66c2016cd933053106fb4a308afc2619f8a3ec5843bc2c64af8d71f86b6836ac3941022a965bca96de03a5982a8bd7730141b4232610cacb6684db89eb1b55456aace6df449ad5b7964cb4a888148d472ae45196e8096a87b014fb5954719e82d8ec33c285323c7fb4dc2eb768259696b41c489ccb08d8665fef6a7a14ab69dc3a72690b5480c1ccb2cb70d3ac37e4b2e00ba7111905fc6d53f0519c44877c9cb1b54abf3106d90424c6a39dfcb6e6c3b80d96a1dbef922aa762d5433485822b1f28c8776305018023cb3328b9200728d082260ccb07b3241b7c86f90f91f18a582aaba4003f9b8c3a468818619a57a2ee0d636db09762e634400305e4495b49f927091773016c72196e29b2e20034c854608f54d1c7506a6b89f8d1201bf659a53f7c16dc671bc65089de9774ce4b52543a1882c12773bc7cf00b746c5b6ed5026f7e30bcb3cb60a091091c2ac85f816d377167801c47e951b18e239c005bb9612bb03262a6c21306749a60deca6b47b22fd7c7ed472aa3e8b9dca5150c4d3209ae02eb72783594b0c713509410a01de44245258790058ba90ca08cda4c45fa6867b038c7eb99d0b026320070b1a18ace2ca6fed80284d094b72881232144f6422a896d67505e40106958c81946a86e19f153712ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_private_key = b563c9c846ca91b6cbb3e138f43c9d8d647d22146889138a615670caf738419b5b67e6c837cc9a15545f33c4723e551428877a4e933bdde9673c5c660b2a64340a927126a56a48660b9396d457b8bb1516ddf8c275753e234590c607be27c81e14d5411c17488c1aa1bf42c74dc4a06b538ea5e9991819a93e6a6ef8f28ceae91fdbe27e6407178f563f7fe272d62746c9228f4ff510d46c1c559644fb3c31c767a8a5ec43f6610488f793328ab819a905d1096645ac1d3c8c49703065bca4a4bf7a16edb2a7605c53b8d0bbe26a0ae4d50eeb4c71df764344184d88c8916952151f18b48d68383e2070e5e57e75c602a48b34c5c4664d7c7ffcc3a6172837b36caf679b40a409761b089ef3ac2f3895969ba9322a074da98b00d29061d08a77cbac871b059179172b9a0a12ebd424d8a2619f94639e28a19cc38b020b30ae00110eab53c5e38516c320e507a3ddb338f3d4bb264157fa452a8a77a79b35a4b25444d7ba020d2aac98c797bd64495c401f1d658da12a9acba8179d6136421197b3c1a4378920b4ec8052568e2c2c580dc08a9fca7d7fd02cebaa91e8d892ea3b23ee3c5c95d037255ca685b62399ccbfe6c88e6c426df43c4e948968ddb3c9aa8a548d7a55c887c211bc50a0870d2c1b00a9383e233b9b1809ca1911b4abd78e2fa23310063d80cb6dd4896adf68829f40c97828c401204d501a6c0f571a48a15d62479e545abec163152b28340f5a077a9c5eca95bb71d256852a6a0b38ae20c3be667cab7a17001014abbdd8c205512f4b546364f6072971a88eba00a2789b34e7a1578909d7921a421cad8f590180ac64637224604166e52233ddc520d5b801349912a5ccc0ac3ba0f5b25b6b6242ed71731afc69597b635f7ac835210947da60b4c6685245bb17f34dab876e553c12fc6619e34237790704881c95f792a5a0070d69e747512218bf99866e417b5bec3c7b664163c7aec73867cddbcc3f3821ed6a92e50119591a667be609a09ba7a7daa4cc0017a270bf568a3a7c373e1a8883057aabf71753d599ca10a13a94659faa71c2694118920690ad71147f77b2fb32553b02b45153901b5951ae055f75a270a6f1b4d37cbb975b979278aff301470513b66f58817e6a5b2ed17891f24a84950be275a805d374111a5aedcb761b6c446f986f37b646187461868797fb28731cb89267f12daea09828f143cd6c7c133a38ce82788a6bb88126956f30943169b2e4a18357e43262d6350b07651a6b2b2b227436405ecb5655e5892ab1a0ce6848bb34236a07c3aeb159822c85ba741944ca68654ba38ec2e4412d5c73d2f87eaa46a8fde25fd8aa691a95ccc7da9df35393213322f50a61ad4113c094cdaa568b1f43517692c4918c2590a221fbc0a313d2b4321b9e1a973492bb519c010ced1c590f0a61799832c15012e04550edc12414f4cb7c32ac3a1bace2f9250caca0d027bfe238344e278d6509796155386c1ca904c34727f0772c12b66c2016cd933053106fb4a308afc2619f8a3ec5843bc2c64af8d71f86b6836ac3941022a965bca96de03a5982a8bd7730141b4232610cacb6684db89eb1b55456aace6df449ad5b7964cb4a888148d472ae45196e8096a87b014fb5954719e82d8ec33c285323c7fb4dc2eb768259696b41c489ccb08d8665fef6a7a14ab69dc3a72690b5480c1ccb2cb70d3ac37e4b2e00ba7111905fc6d53f0519c44877c9cb1b54abf3106d90424c6a39dfcb6e6c3b80d96a1dbef922aa762d5433485822b1f28c8776305018023cb3328b9200728d082260ccb07b3241b7c86f90f91f18a582aaba4003f9b8c3a468818619a57a2ee0d636db09762e634400305e4495b49f927091773016c72196e29b2e20034c854608f54d1c7506a6b89f8d1201bf659a53f7c16dc671bc65089de9774ce4b52543a1882c12773bc7cf00b746c5b6ed5026f7e30bcb3cb60a091091c2ac85f816d377167801c47e951b18e239c005bb9612bb03262a6c21306749a60deca6b47b22fd7c7ed472aa3e8b9dca5150c4d3209ae02eb72783594b0c713509410a01de44245258790058ba90ca08cda4c45fa6867b038c7eb99d0b026320070b1a18ace2ca6fed80284d094b72881232144f6422a896d67505e40106958c81946a86e19f153712ef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0f5de62d662f480d4ed8ba235b4aaa4bfff19edebbbfbd96e5a9b7c4e89365c3ed8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +expected_public_key = d9f06a7e367399206aec69c5569ba3fe2816a0862539951ec9f32fc1a2b9ea199b877873f6b13546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1da2512163eeb5c5c3eb60c91890b5992aed81b9992ac238c7c2a7ec41fb4481508a525f10c4e10b448ee4a7ba149649c11a20190cc95c60eb727cf84ec66c24c008a0308f28171f9c74cc7023873b1848b3450e28377d8115bd17462eee419f1c69414611c659449376b88e23061886338126b8ae317123786ade2d6c839f227ec302132fb59f5d3a5e11010adc5bcda4b01a28bc02377a6f3f4a0033249073b18f553ab65b57fc3176e514794db93a941d620f3f19d1103a6f0a02b7cfa8c213347c6037b85817b27b22f47b8a513d606444736af884fde78a879cc77a4d7644ae360004bb8b072b74a1cc99fb32a68770a110432e4c06f08148ff54aa6a5d2ac1b3b8e461b9813c3a16dc0b200ca81d4e336a54341c8d157d1742a0c327b7c0c9390416b59843353443530a5b70b71bf3768873771155617637272b1cd057f1f01b59565228daa20a060970adb811c106491fb32fda5c6fb70415125b1ab6148062100ab78107b37aa064942acf56919216c6fc58732598f0dd82838d8881999b431586a315375444c6a27d14ff8aa3da9d1340d137b885c95f69862b63c2618e28a11211e3b64bd1a678f631494aba55d42d8116b6388e9ea04b51c9773083a207000e83332c727b4512806a2dbceb6b40c644a5294362770f1108c467f6c64b907b0bc142625ac621352d64b73948d88f281ed3a65a1d4bbf920c962e91496718531756026e71a5986990b5bb1f9eac8ba3571052c32d414a5ab07832ff3172fec8ffd1197028a9ee410203ba02e6aa6b9517ba8746317c69304b381bd6d23b3db6605bfb2762b556bcb502cd10a22c8b78b4d0a173cd56ec835aa874c485f733b5e4c0db08558f1cbb11f866544f10a8a5b5cd52053d8708c3bacab400c78a65436febc36e5894d05b163ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff3703bf5150d1a7004c1c84ce25229ce751f8d00340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_private_key = 30ba4f28910160e87263f66f6034ba1de4662ebc3600863de8844620e0a08a46aa83f565c3c33076eaa5a3c689c681beb935349eb517252c738b925be8720683317f79cca1fbe150a32a0573c21a7ca34908a21dd58266b88712519935f88363a1d9c6d253ad38032d09113cb132c709c4bd56ec73b3121674fcb032e8696dd395c9021d47a39a74c2167e084fd4f85df9002c246c86f1b1b498f05b7d41aff082bafb610fe4576c55064459b665fdb03b98b98839e221710466ee8839d846620037cb6516021841063aa1cf8cb59019f52769fb0bd72152f4e74d7c833f66b272be12839b91c8ccfb0466f835ba068e82b29b1cc79e596546567244c3d5520f6371660193e5000feac74b0dbb40c1d46dc82749486c4f40f96f55867fe3f6121b60095ae9bbf6bab7be258a4faca7af20a2dec2b736bb690c425fe91b37e4200234cab1eec7b8834909acc2c8972b127b1113e17ca26dc7168b345f1af411b4917463d8c7ebc1bf55ba555809b1282a38bab43a2528ccbc0a3dcb2445597744d3a5530a69059da7a34d9429952c626e255dfc8b6fe3b6b9a508120284a1d75b01e695a90eba34e3b1a8e5e99be069180cf073b7695119dc3981c0768ad9c31e095ae83675754971b03184ef7025ba19b1d9812f39133719925426ebc421b204900ccb0c813cd0bc9859b0b7752abff9bb1bea8b24f3da4dcf80a03933a85d784a3400708de7820e750518195c9b08a232e09abca31e033495ae72c84b66499355167886be0ec6b5a337cc1e38060e2a0fa0d4ae1ce4ad34ea9e2dd4c66cbb3489507d95520747e472c4ab1a640c672a978f2b1a8e7e732a1b56796300c961b404e796117f1a8a5977a81f04bf4097336ec0148d19164b831e54b9b98d72b18216af8e58af19731d9d92079df04d584ab964a49ed7f31e99022aa86828ea11ab2fa847210ab0428238103abdeb248a663a954c363d516b48cf9bcab1f0a2bcf0b186b46290189c9db9405b873d83f11e5936ce94e42fa56574497c424a91792145352ed167ad076346aaa7cbe074d1f2a6e6e1cb93634f8aa61fed9c4d873b71d9f06a7e367399206aec69c5569ba3fe2816a0862539951ec9f32fc1a2b9ea199b877873f6b13546d685dfb63429a9bdfbf62fff1b651bb89c9ec8b047c788e82983552482e1da2512163eeb5c5c3eb60c91890b5992aed81b9992ac238c7c2a7ec41fb4481508a525f10c4e10b448ee4a7ba149649c11a20190cc95c60eb727cf84ec66c24c008a0308f28171f9c74cc7023873b1848b3450e28377d8115bd17462eee419f1c69414611c659449376b88e23061886338126b8ae317123786ade2d6c839f227ec302132fb59f5d3a5e11010adc5bcda4b01a28bc02377a6f3f4a0033249073b18f553ab65b57fc3176e514794db93a941d620f3f19d1103a6f0a02b7cfa8c213347c6037b85817b27b22f47b8a513d606444736af884fde78a879cc77a4d7644ae360004bb8b072b74a1cc99fb32a68770a110432e4c06f08148ff54aa6a5d2ac1b3b8e461b9813c3a16dc0b200ca81d4e336a54341c8d157d1742a0c327b7c0c9390416b59843353443530a5b70b71bf3768873771155617637272b1cd057f1f01b59565228daa20a060970adb811c106491fb32fda5c6fb70415125b1ab6148062100ab78107b37aa064942acf56919216c6fc58732598f0dd82838d8881999b431586a315375444c6a27d14ff8aa3da9d1340d137b885c95f69862b63c2618e28a11211e3b64bd1a678f631494aba55d42d8116b6388e9ea04b51c9773083a207000e83332c727b4512806a2dbceb6b40c644a5294362770f1108c467f6c64b907b0bc142625ac621352d64b73948d88f281ed3a65a1d4bbf920c962e91496718531756026e71a5986990b5bb1f9eac8ba3571052c32d414a5ab07832ff3172fec8ffd1197028a9ee410203ba02e6aa6b9517ba8746317c69304b381bd6d23b3db6605bfb2762b556bcb502cd10a22c8b78b4d0a173cd56ec835aa874c485f733b5e4c0db08558f1cbb11f866544f10a8a5b5cd52053d8708c3bacab400c78a65436febc36e5894d05b163ca7892eda9ba6c0792b2c9c345c399a0c841a70b56db1c5aff3703bf5150d1a7004c1c84ce25229ce751f8d00340f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39ec2fc5834e128c5e1460d8cb0c35ab340d706a6c8b52070a7e41a6405fada53fb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = 1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +expected_public_key = ce04a546261fb88a14769a7ebe1ac627d4709ad47e84c44ac01ca4c40c0977a9c8c6871bd929b6e70a8c76a02342ecbfd8a90f1f31470a8708506160f961564db86466d049894437ab1a89dd41363eb597d3265d1f7b9a10c715d40a182e945c9666371431a5a54c6a80222362fa245d9aa10fc115642b3f28ab28bf05c254110a5f5ca553db719a16269d749bcc85388825201c8152c172806c9986f53509a2a3aef9a28e22e58cd1043e19e757b8179e40689c9762bf2138bc02453802869b8f53abb6bb088828726cfa51eea526ccabc971007a0d011315c996ddccc0fcf365f475c578517592c2c48117a63a2b6b854bc7a7a785a5dc4fe4c1b012d78cb3341f9cd826d1d2a13e13083e046de47711e4ba0a784aac886b25dedc2033895e48386e57234ef28590c9f542331a9ce6a0a2dff143b6f542bd752ac6a67a6b319ef15c7203119608a21b1374c5287348e54284dfb3b421b674f0fb3186080553b81f92e403a5eab01d564c9486622bb5233ae0bdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff437197215da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d600260c2e077c1558c8f2abee536999d951bb934cc974b55365495795a6418ac4a9f4491b4e60f992142487457e7359cb5b01e7e1ccc909ca00e6005b213c339c524b26a0b747c18a116026db16239492eb056b12ff700fc56ae35e97ec6d0b787c8aa02e4b828b41996f01d69fc9be7005d4dd89963298838e27c59b79c8de62e4a636bc3ab197326c8eff92c90e4958980a3382365fc65594219ce9d7070a6c3586466ccc031310825ba43ea933d416fb7a73d83f05ec222064f03b635091c25ec0a7aa99b9080844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da88a02883406f1b379e95792c68197d591cb9303b3d5bb2791550da44567d2115da0bb4d380849e1145140d9c6983819f7447332cb697aa2783be169db60249d3cb77d35845a380be3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_private_key = afeb5fbf8bc9fa409670dc0f6c94934f53bf3d4b40163278a3ab076086c5bff79d153c890da535b3d291a2a68acde58df67911f17939b8b474306a862be548b6d092aa188fe4419a3ec659b9b8854b489ba2200270e3601ee6973b6287df400b0775ae483c55547a9b7aa66b396753df934c13085f27b978bd03a5a661a9e94b809a19130c92c1de21b26458c675e955ffb20c939028ccd358652b0b9f3c1d3c300bab422603354a6cc0a270e7aca3706487b67b16accba7ca9296661e2a9b2fc7cbcc60f10819a0bdb400662e203a77c84c75824269d662c826ab11f1b35f8754a2870fee05a04353c23146b62d91161a9a10ea028f8b96b082034d4e63359ae565a00ac0e1c8201a86294673beac8394d01935c8c201c76a0143a9c36e737d5bca9a07994d91dab5e10acf3b96aec1dc1fb33c8f260b1ff6e8b39ccc6a20c554e7c48beb3ca45d9341a0d978846382065b4ff6e13f39a9576f3b559a58194d75ce5e48b89e857c45f104cf7781ed5bac03965bd74942759231e8146d4051b86e33964b25a9e4db0655949d04bc73f8916280cc73d175834aa349ec8614b3f072eae445520b64c57bc284781061e72a7c264c05ea9d9bb20f33cb86ad2b080c98a7e7b6a4a31b119bd139f270a8430a7aaa122e5bdbc9760b0c0f562719e6630d3bbf0bbb3311333f0918385c86c851ebb8a306cfadeb4634aabd720387c787833c9b7fddecc117188af713798126039a1b940694cbba5171d2b977876a9d74fc067cacad5865104a627c7ab0715dba6c0945916985bad2d041eb43a584a1c152ab6df0cb8dc6bac599a60b96ac6e5833982d2167f8ca2c9b984ac1450865731aabc3796e8b4a30a6c78ef76fc2f5c829a2b23a33af1325b54b869374493d2d82275fe49ed6760cc90992973c618489c37f53a3e5b605be77ce48e4c05d398cd648bf63c7298ae11faf889d684a522709c7e301956919c419875696bc782c5b160ebb9acb542138f12195ec3d8ed03c64045f37e53970b7856b3b0719d330b603033dc54c81a66cf7a93d8565b3dcd91458158e72962b2bd78a3ca11e6730bcce04a546261fb88a14769a7ebe1ac627d4709ad47e84c44ac01ca4c40c0977a9c8c6871bd929b6e70a8c76a02342ecbfd8a90f1f31470a8708506160f961564db86466d049894437ab1a89dd41363eb597d3265d1f7b9a10c715d40a182e945c9666371431a5a54c6a80222362fa245d9aa10fc115642b3f28ab28bf05c254110a5f5ca553db719a16269d749bcc85388825201c8152c172806c9986f53509a2a3aef9a28e22e58cd1043e19e757b8179e40689c9762bf2138bc02453802869b8f53abb6bb088828726cfa51eea526ccabc971007a0d011315c996ddccc0fcf365f475c578517592c2c48117a63a2b6b854bc7a7a785a5dc4fe4c1b012d78cb3341f9cd826d1d2a13e13083e046de47711e4ba0a784aac886b25dedc2033895e48386e57234ef28590c9f542331a9ce6a0a2dff143b6f542bd752ac6a67a6b319ef15c7203119608a21b1374c5287348e54284dfb3b421b674f0fb3186080553b81f92e403a5eab01d564c9486622bb5233ae0bdfafa3867785e123a645c5a37124a5344264ac6767d548650f23a643ef347f43c5e1c49378fdc92f7e36cfff437197215da7970aaf5653fe9cce0cba1ec2677c0e9bbeb26526d866d600260c2e077c1558c8f2abee536999d951bb934cc974b55365495795a6418ac4a9f4491b4e60f992142487457e7359cb5b01e7e1ccc909ca00e6005b213c339c524b26a0b747c18a116026db16239492eb056b12ff700fc56ae35e97ec6d0b787c8aa02e4b828b41996f01d69fc9be7005d4dd89963298838e27c59b79c8de62e4a636bc3ab197326c8eff92c90e4958980a3382365fc65594219ce9d7070a6c3586466ccc031310825ba43ea933d416fb7a73d83f05ec222064f03b635091c25ec0a7aa99b9080844e7c44f6cbbefee8b3aaf9aa5aab3e4c49c24d73aebd8c37d9c4433193bbd1e6bace139da88a02883406f1b379e95792c68197d591cb9303b3d5bb2791550da44567d2115da0bb4d380849e1145140d9c6983819f7447332cb697aa2783be169db60249d3cb77d35845a380be3cb789f66395c4c3d894c95e9a3714099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f305e7f49b87bb2319dba8d3485fe814aedb0b43173bc48f3a793554c3e8bf90c17273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +expected_public_key = 4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df08181e5a7343291002915603d891099172597c173a88b41cd45c24e40601c6a5bd379113d876e06614087204cf43c3564980d9630e84b621d6415d0ce224d50bad07b52d58c6ae9ff108948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd6013eb33046060cbcaec21b13549e3df843e9e7b6cd731664808ad4a773237194e9d5a39217457478a6198203f9e6a90e9a8492f96fe28a72c9e2743a41caf07752f52b2ed4fc17efa95493a24c66c93bc6aa846572ab7fa0a808a16279382f87700d8f195e1781803880b07c925256100f7bf223087a85c4f3c88f861e60f92532d60f5cb2033b883cade25f8beb7312520fb3210b2230528644b1ee298161f453b5f32126310899c88ba50690ed925ab0537ebd594567e837471a84c6ea72787176f80c94894c870e69337d939691568edcab008850a6f3a53eb585c01af253d1c9434810555afabc430b7fe69324a3e775e6f2be3638b119a6429ff98d8eb1b5808720e467302798a8ccd8350d36bda8fab17a53bc0c851d91b7cf10c617a1c03bbcc63d93a38ea4653b80731442889ff8200c96b5c37263081dd400d5670959941764a61cde119662325339da81f926affe427e31c6883ce10f5e5705eff1cb209acff5644717e6c6928a41b6e7183590aa524744881aa427c17fe955b306c33447054ac729112568a4cb16806ccc008ffca87e4cc37c3bbcf8e50d3bf07e01132efbe0605a14ac32f6ae2802ca893139f62a64cef28b1720acb282173f2cb4b0f392f8077a325a6259a32455e57964e338a6a731c5aa29beebb0843730ffa93d6b234d51bb87a054968cd07f9c3a2ca79607a97079eba2481e590955e124fa7805e1f03499b7216b6a3a14b9c0c6bab99917a435b88c4314a290e70c7eec8a145037b6531b35b89655e90df5eb2fe53ab33b6c68583780a3b52bb92cc90c45a28cfa8add511ee03bb8bf528d4e94bdfc0cc510e732df4913116a7786e437ef523607126f047a17168824a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_private_key = cf59c55278aa76dc467176c58cdc4499667510219cb1a28e973404472c38c4e7bf7e00d00ad5c6e0ca536bb13081e9708857723029c619f1bae117b283c6c96bb61818942a4b63163e957f1a76a1a3c8af61b851c618927ab771098a43261ab16a8a252d25211d1682d2265908e091d10365347380e314bbcc224cf8889bb37759345754c4fa6589c8b055a75313cacc3b0c21959b621a68ae1a5a7b6398693c0194e57ab2e722072c508027b98980e864fb82b7f1e42cbdb9b608b428e9e391922189b54b18f5e66656b236cbe50563f75d84f785dcca6fedc1123ed31892d4289952cd9968478915b5e2e4a2d92bc6281b702a84a02ee740a4250f67f893809bba3c790b963b70facb645969457f91adc732406cf4010b76b478e37bd0771b3e801c37dc1fcf7683adba4eb0c49fa3aaa9cc829c2ec77b39e15d3a8c6873b139cc7c1dc9f8581e829694685c0a06cf9e33370cd8cc514abdc6aca6fa8203e13baa97ab2d55eb8c9c122c1fb55d1de97d95fb9323392a499100d9a5cba9d8cb2423688dec85a5442091398419417749617c66c06321f3a061235ccb799e8f23ce537351e49b59029a59abcc4cc9f27727653a230051d907bc1fa67895c60242c4a945908cbd480904977b6e016c1a27c120e37bd19410a8864e5b24ca2aca3cfd2ba3d9e9bd63f42f3977aa0c815e5d13c4ecb1b7120997f77638dba3cd5ea57883f5ac82222ecb245885904c9b6058b023253917b7af71c2f94b74f3637c45045d75f840191455b6154115555808d1c122d379ae176947984ada6c4ee90870e51185ee5ab0fbf042e3a299b0797e36d2c5fe5004106800868629d0dc48f46c14c2082e66a5a4d6579676624b5aac1fd07c60a0091b1cdab40cc2341f1961a8d882496c21573a21a7a4907d0164960cac9aeb10e62377ca7c2dda72594977225c9b0218b2787bb8b79b54c819418ead17109f950d6ba4bbe1da35fa698ceffa2a52484eeb868d72a784535814b030130852540eb372e7b7218cf499d2ea3915682a30176b08074f2e4336c391b69f1130c4765032649d00f0b397e8bb44c18f4707348f9ac63776782d877317d4548ddc9edba94a8454c1422bbaba88a9454585ec9668df08181e5a7343291002915603d891099172597c173a88b41cd45c24e40601c6a5bd379113d876e06614087204cf43c3564980d9630e84b621d6415d0ce224d50bad07b52d58c6ae9ff108948b4e49d9c941c3c0eb53a3f118445eda39b1cb8fd6013eb33046060cbcaec21b13549e3df843e9e7b6cd731664808ad4a773237194e9d5a39217457478a6198203f9e6a90e9a8492f96fe28a72c9e2743a41caf07752f52b2ed4fc17efa95493a24c66c93bc6aa846572ab7fa0a808a16279382f87700d8f195e1781803880b07c925256100f7bf223087a85c4f3c88f861e60f92532d60f5cb2033b883cade25f8beb7312520fb3210b2230528644b1ee298161f453b5f32126310899c88ba50690ed925ab0537ebd594567e837471a84c6ea72787176f80c94894c870e69337d939691568edcab008850a6f3a53eb585c01af253d1c9434810555afabc430b7fe69324a3e775e6f2be3638b119a6429ff98d8eb1b5808720e467302798a8ccd8350d36bda8fab17a53bc0c851d91b7cf10c617a1c03bbcc63d93a38ea4653b80731442889ff8200c96b5c37263081dd400d5670959941764a61cde119662325339da81f926affe427e31c6883ce10f5e5705eff1cb209acff5644717e6c6928a41b6e7183590aa524744881aa427c17fe955b306c33447054ac729112568a4cb16806ccc008ffca87e4cc37c3bbcf8e50d3bf07e01132efbe0605a14ac32f6ae2802ca893139f62a64cef28b1720acb282173f2cb4b0f392f8077a325a6259a32455e57964e338a6a731c5aa29beebb0843730ffa93d6b234d51bb87a054968cd07f9c3a2ca79607a97079eba2481e590955e124fa7805e1f03499b7216b6a3a14b9c0c6bab99917a435b88c4314a290e70c7eec8a145037b6531b35b89655e90df5eb2fe53ab33b6c68583780a3b52bb92cc90c45a28cfa8add511ee03bb8bf528d4e94bdfc0cc510e732df4913116a7786e437ef523607126f047a17168824a00699ca54b71eec5b690cadfd69b8db5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0e3f73c56254fac37209f5a59818fbaabf5abff3320b0b3ee00e20679b5728c12a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +expected_public_key = b6712164215d038aa3f9050a35732e408ac91a2635b4c6b502c698104c7e90a26bcd903a4b78c20218ae92d39bf634828a14b529983e92900ecb3778a1583deef38497a336063a31ef9460e8b240fba40ffd4b7b070a4650ec3cd698046c097189237a11a510f6941e6b73a79dd99ee4a8517d25650ff2c0e9b0ac238302ecfac7fd642df9830ffe8714ea8071fa097b39e57919462948a177858c89fbc8bbb2717eee7169b4256606c8abd1e9399df44f12fb8e4ba0b846ec7fe1d65582bbbdd0d494a8a25cc81667ae1964a525016d9ba5ef698c84472ae62cbf10293cb047082a58bdd321c616fcb7a79223e95c8834362da8e60d0feb36a5d1a1a6b6736200213ac3620a113a6d5436ef2064fc360805d2ae84d79d07376123fa1682f80a5e85c87992329d52125a9965d8b039784a3bb472a7f310057dac08e5f41fc1ac9e55f7532f2359c3063726a25599980597da9715117a5af15de88b516f8a41e4ab824ffa8e6ef16cdbcc1fe4f965eac97474a7b235dc0c73140ee7153a835c29289311e1c2a0616a2742c70e27d656ef9954c7643947bc32eb713d9ac392b982400ed275899a04f1b7356b02a54c37beb03215d9e1505380049f9b61b35a61c105980652037142a44c42252663799de7bafa6a042d439c893a37a87b1a792c1689924cc642ae09a299d456c6d36895571572f19c144bcc6eb0cb9aaea09289c8cb193cb9ac33823c11980c950d1106625755b280077f9f383f828824818956ed46755f7933f029a9363054ded02a42f5c56986c541e9ada77084b08b7eeaf4abb700839a59c18fc556a6d528e5326c0b4baec27285b0353e3a152f06fbac742a9606542ffbc14d0ec214757cb1a23aa810945aa8526d3cbbccd11b86ff12b553268abce55d7d723e496071a8bc3a8072ac653cca7c261feb53c95b569a44d52f3d61ae991c38828557caea637e6b130142291dd51ddef7163cf84be7a266e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4a622bd8540b044bb14384aab596147e813f9b1c94f75bac39a1aeb14a035d858892b7e900a2163828f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_private_key = 4f9166b63489953773ea5abb3d0c6a3ae64910943321a13fce603d2e7190d288612ca63fb1ec86a9d50bcb228f74208d9f6352c5f57e1896972230c36f752b8fba83f9d006ea92350a01474ae53799b117e38860fb5cb37630549b5b3b9e5928b6fa4559f040332ac243b90c01353ffbbb77b29735d5e8463e930444b987456072d6579b1fe52ebaa689e85950f393c25fc0aa29d76306558a6b1c2d461bcd4769c2d29358c891a72ca63e61c12c43bc3252107acae4194780ce0bea39d2daced340416382bf99cb8c12bca7ac94ab1d50809a0b1f18d1c4a4a3aa537519d9772fe0a88e668698e59b77b94abef2f969c9f46fd9a850b9e341ccf588485315648a960db0ca33da481987310455452f3933c8db0e1692611d40233ac617e72034b6e8b1d614bc6f0b29735aaac3c050ba38682cf3a6f0c5638b6097f46a85c32a7cc8b06f34f8542c44064b46663af7acffc0a45a99aaa225a30f2c6fed688cbf789c3b6a7464aa17388b69dca70f3e9a588b6531e9032b883946490c9d9f3a53ee0139ffd6c9db19491bb428ea92c2d830c04cc98fb193b735c599d527c375652a964c58e198caa37c3f97e4251ce369b501cf96656f2cc1b29ec1b88ba8341727496916a4d01c8158d4a5654723de0c418755271834608e72a2b48bb0b5a62abba9a99d07139858c7b767ba2d590fb0715329392927137f58724cb72137ffc08fe2059671828d57e6885b5c09007dc5da4089807cc097fc1bc376bb5197a6c5c932df08066c2b6805490604f6c9cd4a1406661141257e8b1074ff2ccc6f262c11cc0e9c9b30eeccbb824170251ba65aa1bad79a91771cad19226c3962543478be9c48ce4a869d98e16e08e753aee5321fc060efa807cbf54d10c8611064a4e68c7da6120f67b3bb9bc016e5ab61d6a37b9a83a490910c59e91911c33d2ea20f3e414ea08195ab979a7c204fb4582fd52547d4e0758721c32d6ccca0dc34493a52fb606be8785014f9761e704514022db0a322c10a377680c4d274b17aa9472fecceb4cbc3213153aa55af49b808f4c5abf98192bdda571c366e658177f8e055b6712164215d038aa3f9050a35732e408ac91a2635b4c6b502c698104c7e90a26bcd903a4b78c20218ae92d39bf634828a14b529983e92900ecb3778a1583deef38497a336063a31ef9460e8b240fba40ffd4b7b070a4650ec3cd698046c097189237a11a510f6941e6b73a79dd99ee4a8517d25650ff2c0e9b0ac238302ecfac7fd642df9830ffe8714ea8071fa097b39e57919462948a177858c89fbc8bbb2717eee7169b4256606c8abd1e9399df44f12fb8e4ba0b846ec7fe1d65582bbbdd0d494a8a25cc81667ae1964a525016d9ba5ef698c84472ae62cbf10293cb047082a58bdd321c616fcb7a79223e95c8834362da8e60d0feb36a5d1a1a6b6736200213ac3620a113a6d5436ef2064fc360805d2ae84d79d07376123fa1682f80a5e85c87992329d52125a9965d8b039784a3bb472a7f310057dac08e5f41fc1ac9e55f7532f2359c3063726a25599980597da9715117a5af15de88b516f8a41e4ab824ffa8e6ef16cdbcc1fe4f965eac97474a7b235dc0c73140ee7153a835c29289311e1c2a0616a2742c70e27d656ef9954c7643947bc32eb713d9ac392b982400ed275899a04f1b7356b02a54c37beb03215d9e1505380049f9b61b35a61c105980652037142a44c42252663799de7bafa6a042d439c893a37a87b1a792c1689924cc642ae09a299d456c6d36895571572f19c144bcc6eb0cb9aaea09289c8cb193cb9ac33823c11980c950d1106625755b280077f9f383f828824818956ed46755f7933f029a9363054ded02a42f5c56986c541e9ada77084b08b7eeaf4abb700839a59c18fc556a6d528e5326c0b4baec27285b0353e3a152f06fbac742a9606542ffbc14d0ec214757cb1a23aa810945aa8526d3cbbccd11b86ff12b553268abce55d7d723e496071a8bc3a8072ac653cca7c261feb53c95b569a44d52f3d61ae991c38828557caea637e6b130142291dd51ddef7163cf84be7a266e504a4e4943d164c912e77cd9c1ba5a9549e5be685945b66a4a622bd8540b044bb14384aab596147e813f9b1c94f75bac39a1aeb14a035d858892b7e900a2163828f03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86bbc0a40ba03d27bbbfb91654fdcfab2dfb3e94d9607b99c1d7da1f2663bfa2598e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +expected_public_key = b7665f3a5a380255617309ccf80a53dc03259fd252de0bb4865372fe22148ed6c5f6c111ac00b31460c5c8da7728dcc4c45093f6c38d78432542ec71be51526d588d46bb07ca388088a1c873219d74334070895c396a87ae390cbdf309e41a2fdde955cec2a29bf205e492747dcb39599a49902151aeac0852d6c042b4c0db99c3f3f94eb7db193bfaa7005709933899c04235941969baccb59418a41e603ec62679b2808f25c8565e6954335227e40040d8407147ba15b7a84405c6a6e72251236bb951e18a1f81b84d0126804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1eca19835b0bfdf637a5839c007cb5c5972111aa64bb0f84884d70375e352241bb0dc4acc5f170a7f7b7ed3308b95d975d5c933e5058df99c4e08878523bb98274488aa712529870ddf5211da039bf2e43eb6506f30b41a90c8922880bff2b1630c0048c22c4972690bc965c009e834bbf936581c9da72a70e2a4c2de0220cb4b88296c9716215007ecc9cbf9c1ac081d84d56adb884d2522584cbc5e61d3327bb2002b275683664487a3ca8f767e54e27e541a403754a45b9512368b0c0298bfdd2143ef9c16b49a282e14010591bef728001d0892b939c3fce379c2e96c2b41a9e5cab8c09cafce0c2a14d79137e3b86b25546c86228d008c792496ddcc9ebb01a664e62040d09fa798accce9033bf828d6058c27e79e434904b756afb332c9800312ed69c4cbbcc379b30b83fa4f71c15e86680b6e40b1f79601ae530e7cb8b7b7d536336468ae291d63360814b83ed574c98ff9afb2db8fe0e4561b98001ac783eea99b82d13de2fc5fd59a1e7cdc63e814b3275a0adf318fb2419c76545ccc70066b0abbca763a99901ae6412b43e26090418c09554bde64c1d3767b074901b5e61449e32532f98365b0bcb65cb3b63c03f1d023e495a0f96a258ffac4d3299896055838263ddc85bb3a071ac5c87cc8a4ce8467881f54047759b420d5809489cb2785aff1935835b845977bcf2b275fabe31222e8576e3578a7a56a26a31bd5510d12bc9aaa3a46fc87cf9d0706d20a126bbb446c24230fc82a780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_private_key = 53b12801738266b450385a9729b894208ac7b3e5719acb43d716461ed1513925192b891180b2bcba6a22a0465ce788832be49b0e3b7fb1d44217618fec80b973ac90f4413cd8f54b10848bdc304cb2025a880c7aa3ab1c2743364523361d84c5db3439ab5cb32c38406e3c5b1b7c7d0403aa4e70786f579cec2c96f516bcec6c69c3d969287ab855e55d22ca8379c1286c52085022c1272baa2bb5c6027075a830370f981c8c836a08f08132394113c93ffe345766766687daa59a591d58398262764aed1cbdf8e87f6cc5b881c18aca05187f76a61bb429e9e024ebd58f1090a6961a0aa8706058d90a8091bf7385aab0b27f16485e08a67b5ebba9ea365b7ada2c055a0daf82b5845c992c945960159a50f7aa1a588084c48cb65403101747fd588cfdf43549facac6d78799759f2ef38d06c42422d73b5ec70b512313738027b9b18eeda06332dbb5856ba413e357c07c1480401bac34309aba9ba13825ba5682345511a45c17353789dd302bf6b1af1573245848986890acfe2708523c02dc53165f204fd6a85b44a650f2d2a325477587bca84994025d221967f61c746a12fc09bfdd3b89ec72a23405ad2a8512d89129585080cf0a6a416365130398bcbb93e37c18fa745b6e131908b0400a67470fc4b40e447e2e378222466336f0966fab951cfa3cf72316c7d843880c297e4444633b52a0c317d4a1a9aa6892eee5a538cc0e07c17a135a2f0e6194bad18494e388866b0cf480aa3bb436b91b33d574372fc054c72b82a4a823b1120b9052c41b957f58131d2dfa8529f02e24f50d88017db823457602a22ad78080661ddabbbbb9f6280d0aa59ef37b62594a013c74a03b8c108ab225a218a2f81358fc0182ab7a607ab103591078077d4f1b2b2de6957ad404ad8b30c146be11d99a0fda6b0f254c13ec2daaf4374afba07ea6ae69fb6633990c0e79cb61c9a81fe4bef140cd1ea569a036cf716009bb3b33708327c478826a08b03839afc31663d4f77f74a972e92910d06995390a3e193ca83706aacb884ae6b589c9aa169beb63d4558d2d43b43d0c4f5ef23bdd26092cac54b7665f3a5a380255617309ccf80a53dc03259fd252de0bb4865372fe22148ed6c5f6c111ac00b31460c5c8da7728dcc4c45093f6c38d78432542ec71be51526d588d46bb07ca388088a1c873219d74334070895c396a87ae390cbdf309e41a2fdde955cec2a29bf205e492747dcb39599a49902151aeac0852d6c042b4c0db99c3f3f94eb7db193bfaa7005709933899c04235941969baccb59418a41e603ec62679b2808f25c8565e6954335227e40040d8407147ba15b7a84405c6a6e72251236bb951e18a1f81b84d0126804a9b0ad3bbe3e65055a4ce714bb726ab9a94d6c1eca19835b0bfdf637a5839c007cb5c5972111aa64bb0f84884d70375e352241bb0dc4acc5f170a7f7b7ed3308b95d975d5c933e5058df99c4e08878523bb98274488aa712529870ddf5211da039bf2e43eb6506f30b41a90c8922880bff2b1630c0048c22c4972690bc965c009e834bbf936581c9da72a70e2a4c2de0220cb4b88296c9716215007ecc9cbf9c1ac081d84d56adb884d2522584cbc5e61d3327bb2002b275683664487a3ca8f767e54e27e541a403754a45b9512368b0c0298bfdd2143ef9c16b49a282e14010591bef728001d0892b939c3fce379c2e96c2b41a9e5cab8c09cafce0c2a14d79137e3b86b25546c86228d008c792496ddcc9ebb01a664e62040d09fa798accce9033bf828d6058c27e79e434904b756afb332c9800312ed69c4cbbcc379b30b83fa4f71c15e86680b6e40b1f79601ae530e7cb8b7b7d536336468ae291d63360814b83ed574c98ff9afb2db8fe0e4561b98001ac783eea99b82d13de2fc5fd59a1e7cdc63e814b3275a0adf318fb2419c76545ccc70066b0abbca763a99901ae6412b43e26090418c09554bde64c1d3767b074901b5e61449e32532f98365b0bcb65cb3b63c03f1d023e495a0f96a258ffac4d3299896055838263ddc85bb3a071ac5c87cc8a4ce8467881f54047759b420d5809489cb2785aff1935835b845977bcf2b275fabe31222e8576e3578a7a56a26a31bd5510d12bc9aaa3a46fc87cf9d0706d20a126bbb446c24230fc82a780cbaa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfae16da7f99bb7bceb75a6468a921ab9fe53aab2972ca616ee10697c204df1e3509f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +expected_public_key = b6a67cd98268afa159ba69953a085099ba56f4e4c74fdb6759791d1ad738cf320c3cf8c52d607a32059f1e8333b4021d855816496963baa6cb41842fa7ab7297a144758b84a27aa6dd507c097a6c7a19063f2b2baab0604aea5ca1c82dda790fa390c142b3709cb69675b8ba0f4990dc923aa525a316a0c7931aa5e5dab4a4e19f08f898ebe80258ba72127a92e3005611a72022d285bd279332817ed4f13a06a71f8f68a0be49a13eac34c773937da6218401c3fd55577572466a271a4bb10a7938919688629fd1c77b802b6358189e13a52330c4f836bbf41595df29499b42a5a6605ebcd6aaa89ca33580b5ee619d282702b4380b717532e0dcb6dbe3bb0c6431ad480821f0c184e7817616c110f2155a0536a4c65b21306fcb5c343fc38191b8b46dd7a3e27240fb85c365a33e18bc231127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddc52157daa998c392a255b37bea55f1c33a23ff4cdb70a3fd0e019ef82131bd92e5db8ce9230421a670c246695afb5bc33e8569ba69d2843957ee52204e435f85c6a713c3fd677cf7a54cac8d48975f1609cd68659643a1a10558f7397234b583e5665e3d30d1fa26d0788b21bba2ba23507123b89ca5a1f54cc5957737159e93070987613dbc7dbb2ad163909fd167d9e099d8c394a7161417141cec54a24f34310bbec13abbb05a3681c81d7034b8687c1d62abc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa8309812bf6459c26c5fda4abf0ba46544a9146e5247adf99f09622c74b8b90397503e211b9a23bbbeb3bfcec659c936987c87104814a312091fb443acfb87a0863564b9eb9191708ad370ba73d42f35b5ae9b97004793992d13b5bbf00b277a2de699ae41222f28d593f6d3385583bdc938334e724341883a8026cd2ae5205da3b44b9075b86c75fd203b0cb738b4f533efe6117b97105a275edb7b0a15aa1ffaf029f3e13145eb3c500440c0e30c426c093c420496d85ab46883b4b695f30952bba32134189589882f5c297da14236a073ac04579e4e7a70685916e53845c8430e2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_private_key = 326a5f31691381162b5c776bd677b60c25b49d60661c432859069e849144008d8b8e9636af2013fff55ba4120929662057c2463050040de482875c5f7cc940b4b9bd27c90812fb2405ac42767254ef83b74882c4db071d926604383ace54751415d564ddb16edffc4bd762aa5a6714df4978f3ab1928bb539f921713170df8109d4005135c74c7e6730691739b0dea12d0c1be131228e1b094b0b894cafc4fa0835c2a815bdc288f56f33c7d2c25ddba868da6503b00017b1373df2c2375644de677cfb56838bf3581bc173a588a9f0b952a3b9abaebd27e71d38431e4a8edd398bbc4a58db608aa255fb210cce7247b17e3bf922ab17b811bcff5627ed2480a5c3c26b273ba478a0dfa80e5344b88e9cb7a00a254b8705755b762216b4abc4f74d7cb17b69771729b77e39608835292822ae073bce322701ff37bf06b917d41396dd948632b6dcf572ebd6c2a37271670eb178ed31de5b50d17072d33914b0044a977d0862ef1ab630ab57eb207f445177cd0b3c34b2d7c75ac832b6127c08b71f1579a63b653945222560c3565a0bb77ce8b5761f71a3ff63097f4813871f57dcfb4b3beb1ac7f5938375aafb8197c552801fa07cbfd8575864ba807e0cb37aa6aaf60a48c7202b6a89a75a38b019c6a8f00cc642901e7a98f81b6c76db06fbd0a7852e4291dd05a6be618e1c97b6b70446a7810b3d470bcd01a593314e75b4215c96b049a66ecac66a3021141f9ba12778e729213cb4656eaa80c7d900a079c70f890285356c0a13a6c9a4207315b95bf45c8780138521bc72a3c524c689baae033c80a461c3cc4ffa48c0490517be741b7f6c98f85a86d8814a96b3df6c469a197c0ec5367e37150e9c19a726826be6453381b833377890b0ac6f9176a1214a352a3a49101532b3840f4084574cb76aaeb64881c78d5a8bfada105f7440e3d04a4291bbaacac5a981b6f8777a7d109966cb2a347515ae01801916174826a4124a495d0a07861892fd5f8c90e085bf4e1680275848e24c6627701dafaa17c9b6c3a59a0aa5c87b19a4a23fa4ebe49218f588690f749739a39b523a08152adb6a67cd98268afa159ba69953a085099ba56f4e4c74fdb6759791d1ad738cf320c3cf8c52d607a32059f1e8333b4021d855816496963baa6cb41842fa7ab7297a144758b84a27aa6dd507c097a6c7a19063f2b2baab0604aea5ca1c82dda790fa390c142b3709cb69675b8ba0f4990dc923aa525a316a0c7931aa5e5dab4a4e19f08f898ebe80258ba72127a92e3005611a72022d285bd279332817ed4f13a06a71f8f68a0be49a13eac34c773937da6218401c3fd55577572466a271a4bb10a7938919688629fd1c77b802b6358189e13a52330c4f836bbf41595df29499b42a5a6605ebcd6aaa89ca33580b5ee619d282702b4380b717532e0dcb6dbe3bb0c6431ad480821f0c184e7817616c110f2155a0536a4c65b21306fcb5c343fc38191b8b46dd7a3e27240fb85c365a33e18bc231127785c3c68892b5ca7955a148a8c52176d5e2596bff83ddc52157daa998c392a255b37bea55f1c33a23ff4cdb70a3fd0e019ef82131bd92e5db8ce9230421a670c246695afb5bc33e8569ba69d2843957ee52204e435f85c6a713c3fd677cf7a54cac8d48975f1609cd68659643a1a10558f7397234b583e5665e3d30d1fa26d0788b21bba2ba23507123b89ca5a1f54cc5957737159e93070987613dbc7dbb2ad163909fd167d9e099d8c394a7161417141cec54a24f34310bbec13abbb05a3681c81d7034b8687c1d62abc98b3a0c9a3c35352f667a49a6378380748934ac770d78517c5affd68a7f6eaa8309812bf6459c26c5fda4abf0ba46544a9146e5247adf99f09622c74b8b90397503e211b9a23bbbeb3bfcec659c936987c87104814a312091fb443acfb87a0863564b9eb9191708ad370ba73d42f35b5ae9b97004793992d13b5bbf00b277a2de699ae41222f28d593f6d3385583bdc938334e724341883a8026cd2ae5205da3b44b9075b86c75fd203b0cb738b4f533efe6117b97105a275edb7b0a15aa1ffaf029f3e13145eb3c500440c0e30c426c093c420496d85ab46883b4b695f30952bba32134189589882f5c297da14236a073ac04579e4e7a70685916e53845c8430e2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1fb80edf4f67823ff4e53a8963a9c9937fa9f8e014b750e11b4c4bb1a361d6484f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +expected_public_key = feb55ffc9306f08b6202ea25968669d4597145180620da32b9b41576a297fb5010948a0516ec3428f1ce8012c664dc5c390663cceac966656cae6110d1a45d4360c420a69014709a70b71c0cf8cffb81958a687656859a8979a24c8c131d1b03e791bb81376db31562367880dc097f04c150a171445283cb4444701bf513887c917a310c87fa30dc3a49a23727e3824f5e2b821875ba8b5288a28b40abc8ba0d130953352f60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c569c2b7fdea81bde50c7b495f901c14b32779baf70c57d84d92aca4163637de873f0581b170e77f4ff840d0e56e13d367c74a23c453c847e208c85cc687066c09c6cb6c397df1232313d93a9ae45352e746c1645528a30d19f6ae36a56cd1116af5d11f6fab71d45544c121895f355657d982fa23554b6525a68a050b1454cd3acb4c32af315b19c9e6ae4a9a3791e6be07f64c1de5782ebc2e54f23782c64d74276f5f060e89c826c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b352b34b71958b0147517061a45c22b0316deb27ebc26b33efac3a1b29c4a301e48e00da82930d4959a13e763cb63035844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544aa3290dc0697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f7625cb0a1d3bf043e304144b559e969264053a53e542bab4e57dfeb53aff658db07c6213586315f57289e2bc66e49c35e28f9a5219c9f653a9f1314406a6cf9115adec8568309388e18fcc5bbe221c323829c91bec116ec1128cb39460c25876e32c08d1c409c581a9360d570ccfe323244f0ba84c19cdfeb6cc761a2e408a9d073511b90a2fb7178fb9cc096ce14a1ff14b6b6600ef99c47de431cbc7482da47d87540b3e72801f8a9b1c6c583ee73bb157a78c585b95c09a868a957709a5305c7424a28a8d731ace8759f5212566388a7fe50705b6045a945b69a52bfb4a61e4dc53f6230773f844ed90c571823c3094912c3a9ba25879d7f4135780596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_private_key = a3f608e503bfd0261066cc5aba7a1720aa8a9d9b86da5858cd5b595c688b5b29ae3b8b6d9510c484d33e6905b86d9c236171cf825bad4d265630878d8b8b89257a510b907eec6146326ab4aee3cda24c9c36526578c470b3c44934823a6fa71c08f8ad662bb2d290aa0da8ac3aa59a7b7210cf1caad0321c63f07074e2527d2ac4676b68b96a8b74711849d03b2443696e43bb5a34a2a9ac29a43c7c316a1de1cb33b78a5b3bc04df6490c05596671d9a5ee355e4c568ce5aa73855a735bc038fdb254f2f60e8b75bb60a1bbd429a8713282eb149a35c75ba5f4853f735ce9186f7eba0b05e292805987df34c826c34dc8b63e701a3a90037a9b03b835e7874381208987c517b978a1fb0570360af357874b0a0860e6cbd4bac028a9bd2d187255602cbf599468d46844bc5caeb3a3b7bbc6d7503f7ae013d6266b4f054b95616e02690ae54c2d4cf89082790e41b60d4f865bb92584516c2014bbbfaf255d7b47212810777b6710a0db1859482ddc858a5eb6c79ac8795de152361358d895c57587ce0d110e1178aae7c881d0d21f4773096fe57fec3bb96afa475603abad868fbcc61a83aa1d71176670d051d52c4ba56b9eb87bacdef570443353c7d120fa4a1511d247a22102af98c2d6a0b1ff52673f585d09f6034c97c8c08022f75b82a7987de3506362a6785c23934242599c3175b7d8c218855c5110a22ce558d77337cbc36b9d7b69a2314264e0a22252b4cdc54857c40d5edb8dd958cf9156284b95818e009541705885f6663d2549a1508f11f862319b92c03013a1035e26b3658ee21790fcc7296b3841ea5991c5b607caa51d78a5bbd3ccb5316d5e9083b2f9b9ab1937bd120c3b94aa3bf356079592a1144bfef2650b3c5e95e6a98506ac74b8aa4996ce5dd92eb7620b7fd860af0267d8532dd1b85ad95547967627fad85cb2e798998b27f340bd2116abf155ae7baa09d8e6411db306d4b9bd3ad45dc878cff3824c4cf16f08d72ebdabbebf8939cb0b0103e6a47dc64fa325883f73a2bd8c7353938f1f81b7857a03441228d4366354a959a37637f2726e953cc3d90056feb55ffc9306f08b6202ea25968669d4597145180620da32b9b41576a297fb5010948a0516ec3428f1ce8012c664dc5c390663cceac966656cae6110d1a45d4360c420a69014709a70b71c0cf8cffb81958a687656859a8979a24c8c131d1b03e791bb81376db31562367880dc097f04c150a171445283cb4444701bf513887c917a310c87fa30dc3a49a23727e3824f5e2b821875ba8b5288a28b40abc8ba0d130953352f60bacb5c6ca6a13aa9757bc70508a4185a85a04669c63a44a213c569c2b7fdea81bde50c7b495f901c14b32779baf70c57d84d92aca4163637de873f0581b170e77f4ff840d0e56e13d367c74a23c453c847e208c85cc687066c09c6cb6c397df1232313d93a9ae45352e746c1645528a30d19f6ae36a56cd1116af5d11f6fab71d45544c121895f355657d982fa23554b6525a68a050b1454cd3acb4c32af315b19c9e6ae4a9a3791e6be07f64c1de5782ebc2e54f23782c64d74276f5f060e89c826c425466ce8c81da46cf4737b4b57447f5974cddc5957e7744b352b34b71958b0147517061a45c22b0316deb27ebc26b33efac3a1b29c4a301e48e00da82930d4959a13e763cb63035844b6daa746804bbae406bf858b772d958a6a3586dcf8464006544aa3290dc0697fe84d0033c702b78df9e7ad2c75b8a04854433b5c3727870ac546ff3b5cead7a527637ea779b467d696952b430f7625cb0a1d3bf043e304144b559e969264053a53e542bab4e57dfeb53aff658db07c6213586315f57289e2bc66e49c35e28f9a5219c9f653a9f1314406a6cf9115adec8568309388e18fcc5bbe221c323829c91bec116ec1128cb39460c25876e32c08d1c409c581a9360d570ccfe323244f0ba84c19cdfeb6cc761a2e408a9d073511b90a2fb7178fb9cc096ce14a1ff14b6b6600ef99c47de431cbc7482da47d87540b3e72801f8a9b1c6c583ee73bb157a78c585b95c09a868a957709a5305c7424a28a8d731ace8759f5212566388a7fe50705b6045a945b69a52bfb4a61e4dc53f6230773f844ed90c571823c3094912c3a9ba25879d7f4135780596d8b8490195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9d9f630c3838eb161374710d9f01bc70d4ef928fcb1c38bed93e30f3633a05e01a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +expected_public_key = 9a620f09135fe651929f4b299df28fd9943ae75a983b544e62305fb6711e780519b0794d9af7b4acb2bff7c704418bc89c38a9e2b00ffd6854c6f41d38b204bfe220034213c066cb62f721e59521bb6bc039c19781fbb71a546aeef31b90783695c47ae2812523f84f0f462b60f3bf77f2020e793813109d25332e966231a462ccc596a48ccc22677a904e35035ea10ec572b15af3ae770abd79c72a1dfb3a988952c925b461f092dab51726e999bab44806199716f425e21441cd82919787c629c90b6b1975e7b0844ae52df6a5cc7d393ada542f78952be2b001979ca34563b390f712111a24fe33ab65265b70eca7eeca275a993ea2793b0b08adc56ba66d93ab1a65524bdb034a33a9e9f59b79f16aaf12c470a22105ea1e2ca042dde1ac61a982ed40102968437d216cc6387989d652bd59a4d88b625056b40550092a506cb4b0532380b35ddc4d34318e33a797c696c12fa540df4329268ba47c95368473c9a70b0a5b0a3360b73767f16d94e59c79b1c839b0af93f3cc57323b9b815b94f6889cba154fb0c6bfa11ab5fba4f10c83405629b9c177cad4307a7b0e72ca4f8c7ba5f292afad92c566abb319124205554fb538c6a5c630a32655ad56be818aaaadd546b1d04df1121ac167bc09274379f0719f3056febaa36aac0c926512d21530d5b9a8ba838f7a44656e868c915046ea818e19b06afcec6a14594e6a5574eef2a937731f24994ef7dab03e223c0fb0bef2a2661703baca090c50a20da05a64bd764f1f1b5ec5a6ccb7ac59e465146304c272453dcf897ac415a8895511f5d04c24080ce0a1c024815af6fa0f21c7cd0c702bfaf7991d915df9b7a57f513cbf0cbbe6e40854e42a603a6ea6524fb3f49c81d71c4ca27848f51a354bb35020008360201baa7fa2d64d269a598e3919b1076b89b0c894d8cd63924eba5b25a92b351a516c50686b2597828bdc894a08349cb0996b73b2fa0b98d0d39fd2c6952e1a60b69b1b8d41b5f6c002409c3bdd716c56586b7d440eaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80cd502aa28063835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_private_key = 20baad201378db4baaf53b7fc750cadb1558f238a3c0d6b70027adf29398b33a6860e084741669991a2c365bc2c1d53f48741d610a4bc93434707739336b1810f43d57743d5918b002ca40e8bc63d2d047994a7614c9793302193995c18ad19af2a36721dcc32c64a0438778f3351bdb12a778dc6d9386234d82bc20469856a8bcdba5b70ab22caaf6758f29a4660261a45222ae069e5d5b7d5c835358190166c3ccbb7c46ba63a71f1628a41a69410505b68a8808d44e5b7840354739708b956a38501621242a7650521aaa7349b086a72135c6797ea4459380265da9583b8742a040a87599c9d1083b76415fccd9b83b25602eda248864bbbc9b47c8b02176f7a3a2f6bec1faa53492846ffb340b825ed7298e807a8e721092498b37e881bfb44563d606274df771a9e3c78d575865764972cb7c5871136cc990b508adba8acdf672be68927ca1d34ff7e45f70dab80807981f82ca50f7177cf1cb70a27d68c60431dc7f4f026375db70d5930206d3982ea32616b8b3393b524f4899a973272060b78d81962a6a21322acef9441f8d0754ed39370f9c03afb39800042f3405958dd5b7b60209bd9ca6a5414c568c6ad4118abef52f12d192e57713ddbb49e3d34c2f3b5941f5b07f6a3ef799553d67adf7e569ffd8949aa0a120398624b5387c3b8cf7a277baa6410377bd88cb74d814388da2cb8f96cec82a486ca962721a532f455369f269e3098a2c15508e102b0bd79e8781489291451c8a2606a34edf048c6cea76aba3b737c6b20427080788c2884b2782bc4229d2c14f0868f1dc7cccd93277b012f2e731d0f0c03c330a944725ddf53e8eb76b64b7bdb833699082772f9062e1f28401a908aa8187bf160c87185f0c35975ee1cf93e8a3e0ab027c48750b59a4e2887ace373cb34490277cc24a151122d2b326433f0691b09b3b004c21cac1914052aa1bfdc7cd09b95fa71624ca399b7f430d5ae6ada1ec55c28b9fbd19be20a47aed181c816cbfa526599fb054b6a15c529791f8101c579b9ef554aa63e86805556933c15f19ebaa09ea2200ec053f00bba05091eb4ba19d95539a620f09135fe651929f4b299df28fd9943ae75a983b544e62305fb6711e780519b0794d9af7b4acb2bff7c704418bc89c38a9e2b00ffd6854c6f41d38b204bfe220034213c066cb62f721e59521bb6bc039c19781fbb71a546aeef31b90783695c47ae2812523f84f0f462b60f3bf77f2020e793813109d25332e966231a462ccc596a48ccc22677a904e35035ea10ec572b15af3ae770abd79c72a1dfb3a988952c925b461f092dab51726e999bab44806199716f425e21441cd82919787c629c90b6b1975e7b0844ae52df6a5cc7d393ada542f78952be2b001979ca34563b390f712111a24fe33ab65265b70eca7eeca275a993ea2793b0b08adc56ba66d93ab1a65524bdb034a33a9e9f59b79f16aaf12c470a22105ea1e2ca042dde1ac61a982ed40102968437d216cc6387989d652bd59a4d88b625056b40550092a506cb4b0532380b35ddc4d34318e33a797c696c12fa540df4329268ba47c95368473c9a70b0a5b0a3360b73767f16d94e59c79b1c839b0af93f3cc57323b9b815b94f6889cba154fb0c6bfa11ab5fba4f10c83405629b9c177cad4307a7b0e72ca4f8c7ba5f292afad92c566abb319124205554fb538c6a5c630a32655ad56be818aaaadd546b1d04df1121ac167bc09274379f0719f3056febaa36aac0c926512d21530d5b9a8ba838f7a44656e868c915046ea818e19b06afcec6a14594e6a5574eef2a937731f24994ef7dab03e223c0fb0bef2a2661703baca090c50a20da05a64bd764f1f1b5ec5a6ccb7ac59e465146304c272453dcf897ac415a8895511f5d04c24080ce0a1c024815af6fa0f21c7cd0c702bfaf7991d915df9b7a57f513cbf0cbbe6e40854e42a603a6ea6524fb3f49c81d71c4ca27848f51a354bb35020008360201baa7fa2d64d269a598e3919b1076b89b0c894d8cd63924eba5b25a92b351a516c50686b2597828bdc894a08349cb0996b73b2fa0b98d0d39fd2c6952e1a60b69b1b8d41b5f6c002409c3bdd716c56586b7d440eaaf7821835a70e669f2b0558a4674fe52539a757b59f843b2c636eb44aa80cd502aa28063835cf90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c105c27fa929adc826f98fbf0a7fdce33c8f215b34e70450da0767240741894ffa4e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +expected_public_key = bda121a1925eae9139af19594444a8953b824f4ba5ca44c07df745fe911f5071975a5b4952c48df7d431a821998fc84f064bbee538569565bd0db70087654203dbc0cc21bf4cba678d1a093ea8b295789d52fb25f4d78d6986a0157145d054afe73a90f25886780044d4b9a4e112259d4a83dce439739a171f5a0fab0736d6731988ca74a56580d3c11dc3b187cd688cf066710a1458a7431c7bd69fbfe67b3532386dda99b9a08368d887414423d6c90cb69736a6a021c70a4c7e33bf3169aebd7227f5fa7f11927b315a52ec3341af239cb88b8137b509c7699b0a8578a4425a0dd535eada924f872fcc719aa785a0e0045b03b24d0f5c1dc9b720a4717e0705cedb88bca8e29a76043a73a87c867223f487c6cd7598bfa4194fb584f4028150513f8692cf17aa5d1009756db4b794f3c7c3d40253991923f098cd7680887935729c4a40a23dc20227cf18c86137482b574c5ab880ebc10c312c5eaaf15870aa4b51e59f70c35d356b11fc6abe072a501bb61647694d6c02a731f13c32a27fa5314a5e641836e23bd6a28c2ae62ddd79039b9365b007110dc95760367ce6a8bc2a358d9ea04cfc302663caab8c710c9f199c2363c4627c14b6cb5c3d3a0d9a3281f07aa5d67029653b2c9afa1375e343c197cad3caadffc0076ce91df0e21436cb368d9c2ff2cba5691acf472b4df839785737842b378cf29567db475622319328dc5388aca633531272b2c164a4a98359b0e9813109640847a8605815a9dcf84531e09b6dda2d1163cc19824baf076f5ef39e67761622cb0bcefc7430c07ef8b8bc84ca8f57131974e5a39244407d376fce88c340030f33ca7c21e27f2cc06b443a12937b978e68a2465b70fe8917da84700365a68ae526316c61fea6b0e5a88813e5251f83ba394b0296475dc1c77878db73ee4671e62bb66d50604efc4a7a91b87de178a617931f9406ec952cecaa8274d095c91062c0e0004093b3e6b36c9db094cb16a34a33a5890a56e973a12af859a7a2557235c50335c6418751952c1e3b3bb8b6490faa78c81d84c724e979cc2b368963552f21518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_private_key = ad411082dc4cdadc6267b69f5d8b404583b112d27de6970e12485a7b68bca0e3132ed64ace676c1e7c48d5ec98a60062757057bba2358bf8128b9b918c456a3942906a0275b8b08435b7ad16090d388c428d4b41d61c4e5a3859e2a39a80e61dc4874f51073d02cbbaa08413fdc64639da42d0529b7eb8b424951b9c879fe6656e3462cc13b7909c6471b77b878bb6006691b1c673c0dbb1435b166417555ae0347ee1ca245c049eb40b6c23cb34cec026f3da5c528001fab341bb300c2bd159d6e302e9f7919a11ce539780b5da3d3db112144a385d1a5eb7725693d0ad5c7c9a2b899cd8eb1a04031aaee25bbd624d251b865efc7c303acd18a4aa5c0538dcab5522905caae913995bb0231195ace17c47d05102c44d42287c4e60bf4e42568344b6e287be650921ac55984c572550b9174edc9ea39b228fd4b04371a233747f17a1cbe15145c34449239ba0b3b65355a23f22f26f132ccb281a484048486429258ec487352aa9c87031dad59a806bc71d5ca7ce6311194669289795b9a3cc7a2c6bc756712cb4cb8092ba75430e9ab96acd624f480bbdf515b423134044b6a543f708167a7f6a307a32629b0d8903b97c1394059cd511c2df6bbefb9c81c3ac7d15b05379e214aad30f7c4bcaad99c21e3b00b44022093110c001d04716c5aacca8812b73213c5ad4b473fd5a555756b18bdc02094ab27359037d6a67509271cbc82d3619633f900e5959756bb63ffeba3ab51c1161ab6cc8f47bb30a7849c674c6fa58730bb70a2c6333698761503889a652e5381c6a160407682738d0ba8da898885bb02093bc44e04bc5eb71861790138340ff909549596303e3772d287c77002fb441a72d543da9376206b3802f51aa72009233e69fa3c256fed0b182717299b67dcdf2ae46b8b95a08526429bc5ad5cfaff9898a978855882ae5147af390762ae335936c17de1c58262ac11329a007aa3c0f9a7b95db13c5e24874147ae010092fba13729877d18832c56c71ab9a5d6a2a9b6da5c2b59a20499708382a160aa87bc6f3b4c53ab0558a26da0b81a239472f1941cb5495ddb003070504bda121a1925eae9139af19594444a8953b824f4ba5ca44c07df745fe911f5071975a5b4952c48df7d431a821998fc84f064bbee538569565bd0db70087654203dbc0cc21bf4cba678d1a093ea8b295789d52fb25f4d78d6986a0157145d054afe73a90f25886780044d4b9a4e112259d4a83dce439739a171f5a0fab0736d6731988ca74a56580d3c11dc3b187cd688cf066710a1458a7431c7bd69fbfe67b3532386dda99b9a08368d887414423d6c90cb69736a6a021c70a4c7e33bf3169aebd7227f5fa7f11927b315a52ec3341af239cb88b8137b509c7699b0a8578a4425a0dd535eada924f872fcc719aa785a0e0045b03b24d0f5c1dc9b720a4717e0705cedb88bca8e29a76043a73a87c867223f487c6cd7598bfa4194fb584f4028150513f8692cf17aa5d1009756db4b794f3c7c3d40253991923f098cd7680887935729c4a40a23dc20227cf18c86137482b574c5ab880ebc10c312c5eaaf15870aa4b51e59f70c35d356b11fc6abe072a501bb61647694d6c02a731f13c32a27fa5314a5e641836e23bd6a28c2ae62ddd79039b9365b007110dc95760367ce6a8bc2a358d9ea04cfc302663caab8c710c9f199c2363c4627c14b6cb5c3d3a0d9a3281f07aa5d67029653b2c9afa1375e343c197cad3caadffc0076ce91df0e21436cb368d9c2ff2cba5691acf472b4df839785737842b378cf29567db475622319328dc5388aca633531272b2c164a4a98359b0e9813109640847a8605815a9dcf84531e09b6dda2d1163cc19824baf076f5ef39e67761622cb0bcefc7430c07ef8b8bc84ca8f57131974e5a39244407d376fce88c340030f33ca7c21e27f2cc06b443a12937b978e68a2465b70fe8917da84700365a68ae526316c61fea6b0e5a88813e5251f83ba394b0296475dc1c77878db73ee4671e62bb66d50604efc4a7a91b87de178a617931f9406ec952cecaa8274d095c91062c0e0004093b3e6b36c9db094cb16a34a33a5890a56e973a12af859a7a2557235c50335c6418751952c1e3b3bb8b6490faa78c81d84c724e979cc2b368963552f21518313849088b248ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7dd8aa653122eb5e3a4c3c877e95e8ecfcfef1ac9e0e6af92cce8ee89d09188fa9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +expected_public_key = 5581cfbb9262be71c820b270d635c0002bbc92e596f5cc0b5cfc114bb2267640308b495c33314b8d208015888159c02831a062d7967691c64b0764966762c2c28666cc1119b4bc8541f016945c200de76f6f5a83605ace8dca54585a5f115434d70094fd540aae769450aaa7af961cd96239d624082ae6a494a000950747188236a3b9b170a597cae821b6d74d7d00c42ad89a31b0383665b4daf70a95885530e315fd75888e76c1113c0b43f80b951a626c5c59706138567aa786ccb7966840c7acc5e70c029fb38f9bd3b9ecd9b11291c808b44803c06f2241afc703834a125474ac3a926a1e24a0856fc27ecab603f0a82c53f94dcd8797ee25ce4f1635e2b18706032191c7834651c1bdb21ea8630884aac48ef3287093a95f7291e9d3bafd94574a41823f2c7f5600c6bfe237e09158e848b59f1702e1b924d47cc64f7b24beb41c3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bda063a3545f0cc8284e40bfa4b99d2094727f8cf006957fcc432c058685072a5653434a92b9ab4211343f063fd44572a23829aa8b19e16a7121b1f2352813d492fd91c834eb5a8e5498cf7fc76874a3ef8b926c0d29f3062588163a24c5976bf48797b694fd9b964b1cbbdf62a23a941c99fc986710a0cf2530f11f84914a916c6f704d879ab4cd3aa51f7c078006eca60a1b53075ec71c11ce0b6d8f9769f9549c2d7a690dc07f79396bb2cbe2e0ca72436879b0c8878d0a9eb9387c5759b1591c5339662009d449184690d717a8a768f0ce3056e477a9dc822b5fa466c0a85b3a0256a61b3d0e433ccbb6a9254222fb779cce1273cccaf7c51760e260e2f566b487b8dded9049e037290d102e03019c8c0b2983687d37c880a17484337a66467abee2b5c8340534ec6017a660344083c7ec21a729c754f3cabd2218dc2f200f48a3b67a07b7d86b072e4553be45cb50a2b424c07719878d4a84ad2d33453b783ad117577f41d6ee58ce4326c4c893711d66c94d6aca65c980a545b5521026a42318cd72e7f7129c60b652ea49b2dc075833c3ac3e7cc094618f003b26421bd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_private_key = 58c8c996e892ffe562f9aa44f4ca31ef7c174cb24d20c683518c1361e68ca476345f19612c872fdc3307fb876096c96f5e714a5fe794b9dca87534c2e91b167b555aa9b95005c85b9584aa33f09b87b6a8620441f1228b551a29ea8788c26c33deb97fc98aa078d5cee62c5ff45b0417b8358aa55408140f89e611fc641f8010ab30c08a6e789b492cce5006c3ce45434912bdac595e4eb91b4ac820e930c4d4db33a736049f53758bdaab51302fcf0c371ddba37b808cc2830e7fa5605f77250e9a9a2f8819505c035c26b8b6498d28dcb77f0742cd8695591a176d059775c4af51f43ea9935672f42a1419a5ebfb8f1681cb9087613db276695562cc62c3f2439a9aa980a56371bc64b22e16b3e01790a202bd0e48afddb50e8c7783527c162fa838a2f32a8e153b4647bdc490a81a494967849a4c814db1582429d296e96bb18c8b294cf05eeeb4aaedd84aaa0b97e3e1b5276c4b7ab8746a717e2bb0b8f433b85f8580cf884689e4afacc61f32587d5a1356d402483ae96f6ff332faf02d61a7a76d3a1171e9721ba801a98127f82314cee599ab1c52ea948013300ae6b576c80979ec4040380394ac95b420a5c562077758714acd91bc1df8bbbca1768fba4b2b349c64504b70089e7eb820615119068b7665c2c5e5da56032cb75ed159eefa3d99a764deb9453a44201910438d0b1a2dfb4d8e7acad1f9abb9b2720d58b72fe18417200ac289369e019f9c9c1e60262407bc8c3a8478db446df952b10083a6a2b4228d482003228a44fa6a71e1255108954311c6fe281cda968551829ab7794893fb715ad90a022b51907c60ccf5156c485f50005b87e9b219c18ef83883631536323a1e7f9b4db6720c4e311ace289e20ba404037663650aeefc8a07119a9c11a67d91cc0447c4e38f68d828c430a75859db93b57f5c49566931f62b3e5e88e211c0ff0ba03b6b8b7645360243aa3b51c2514c923e4151516d019010aafe51a91ac78695a4a4fec6b754bd30bc27b664816c1d7eb35c2bc5cadfa7b764a1ffb5b48b84402ba5141fa8154e5160648177f210059fe8763fad15fbc43195581cfbb9262be71c820b270d635c0002bbc92e596f5cc0b5cfc114bb2267640308b495c33314b8d208015888159c02831a062d7967691c64b0764966762c2c28666cc1119b4bc8541f016945c200de76f6f5a83605ace8dca54585a5f115434d70094fd540aae769450aaa7af961cd96239d624082ae6a494a000950747188236a3b9b170a597cae821b6d74d7d00c42ad89a31b0383665b4daf70a95885530e315fd75888e76c1113c0b43f80b951a626c5c59706138567aa786ccb7966840c7acc5e70c029fb38f9bd3b9ecd9b11291c808b44803c06f2241afc703834a125474ac3a926a1e24a0856fc27ecab603f0a82c53f94dcd8797ee25ce4f1635e2b18706032191c7834651c1bdb21ea8630884aac48ef3287093a95f7291e9d3bafd94574a41823f2c7f5600c6bfe237e09158e848b59f1702e1b924d47cc64f7b24beb41c3184980e5cb9b2db75bbfab454557c479b5b2566577bf63ea959856bda063a3545f0cc8284e40bfa4b99d2094727f8cf006957fcc432c058685072a5653434a92b9ab4211343f063fd44572a23829aa8b19e16a7121b1f2352813d492fd91c834eb5a8e5498cf7fc76874a3ef8b926c0d29f3062588163a24c5976bf48797b694fd9b964b1cbbdf62a23a941c99fc986710a0cf2530f11f84914a916c6f704d879ab4cd3aa51f7c078006eca60a1b53075ec71c11ce0b6d8f9769f9549c2d7a690dc07f79396bb2cbe2e0ca72436879b0c8878d0a9eb9387c5759b1591c5339662009d449184690d717a8a768f0ce3056e477a9dc822b5fa466c0a85b3a0256a61b3d0e433ccbb6a9254222fb779cce1273cccaf7c51760e260e2f566b487b8dded9049e037290d102e03019c8c0b2983687d37c880a17484337a66467abee2b5c8340534ec6017a660344083c7ec21a729c754f3cabd2218dc2f200f48a3b67a07b7d86b072e4553be45cb50a2b424c07719878d4a84ad2d33453b783ad117577f41d6ee58ce4326c4c893711d66c94d6aca65c980a545b5521026a42318cd72e7f7129c60b652ea49b2dc075833c3ac3e7cc094618f003b26421bd82ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaab7c80e434104e9838cb08529592a5f81b0e8ead186663db8facc569b09e75c9a5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +expected_public_key = 6845671057a2e8e3b4c8a70e757c8b424552b1b79f18eb72a64334ffc70b2b07203ed0870f6630733c26daf928dec6bef96a92064a738b1bc57c10c965d1740b313e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fb72f0caba15c00595af1b0eff68479daa985e79a0c5734987a34847215be37729ba51bbb1311f6f0800a37670d3a2f55023e88a019fb068382902a5d94a8fca972dd291178e039f8d2ca22936896c68976ca2309838416108888f13916089556a277e6958352484f231703d120922d103d6b2badb528a2eac86e174186b3278d7f480ec2195006f36583cc91c1288894759807692f15c22b9fa61ab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0aa1f182357104230349a0c21930f5fc760b821a07aa38b021123b9160d49b2438eca5ec5aca812f96cd7574a0761cb17eb9b71236b19a88d6bcc7e4a0751af543a151417d55093f6530543c678e19c330c63c371f84ee2d07d5a76ac273703b8166e889286da5c5055961084265f2e5817879713d74186fdf56793ec6c8dbbb4dd75196aac4318aa4f773bcf462586566c3c6e980731e7b8273a21c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768ea5026b61aa1698279191b69c39b53183c2745a7c251f48d26812eb4764d9196a18af28d91c54035fc149112ba7eec9df4421121aa6132e7069072a59a8739535c9c76959f8138112d7348c9030b60038a66bac005e38be1449e3b961850c1853450b33d680cbc2a586ef37e323891deccb16bc52eab1b7a6fa13205d38963acc148435cfb72803d6054a18c0de3a217037a257e157a59f8a968d250aa1baf88935dc54272bb5950303ac68495956689238bd2b595d7cd42749ae1b38097ea7ff90600056b5ff674a4c02b26aca5cab4379f0864a24fb14f24e274ed640ae6d692adcb3fe2541b9851ba35893967d39531b0c163d5b7f131cda1976e405029614399b7ea6cad628ac5245ab7552fa4d2acb10aa7fe2a91081707c327cf88192d904287c47014a4c51766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_private_key = 8dc7329af7a016354818974b6814c962e91e268c24ffc843ced150d4593c4c586efbd608c8517e6f7c520b59133a81c6214baed3a8304220999e30b00241244e9abbc2a4b70d2b042c36843402255e1307be53b7ddf52621ccaac4c266d02ababa0b6567a76e2482887d6b729558a70c6931805a8d8c3739dd95c06a33b42e67c45e19aaf4d859151b75b78b5419f867c4b74dd6ba9f54f533dd51585ed89eb6a22be8757d2915752a14420d99b20d033d4840ad2e83be1207a4fd3020a38aa9e0125d9ed36ba6058551976e5bb27a170aa071b46bd98b7c4c438fcd904d366406a45589af938532135adc2c790e759a1b0713fce38888d626599a7061b6cdd0856c5404b042d73aeda2a613d51852d5526496217ffc4030d8b1d521cc5c3b47a8f513e2688d794a15ef90b7b2c5a213e76a5f652a0d4659444a1170bb3762f55ae46207cb5a015298610023b16d01624845205956ce413c217fea95dc939829434afac49172f5bd6ca5bd1dcbc2c3e94d4a8ac0c7f051f71b53501b8abf676a4c372491c39e5b83492734356bdbbf6ee8ac98fb765ae4a5b26b33c2d09d0accb0c8a3412418a30198b014d62d16ecabeb863fb037575d06b43e33cd0d857152424d9e2c3e4968cba3cb978a9b180d539b7d061fec9095e77817e93b2b3b189ebb7cbc04e4a0862547b1a9270bb4a089a957bf3c439777114552993ce67520567259b7a48dd8534c83bb6f442d652543ac9143f6450908f3cab1c47e92c83077815f5d85891f10a04f0c0cbb0cbad8261a0ed014f09ac33a9a87c5729c7067678c7887787ab7ec7a2a775074c4ea58219c10eeb253a1695d20612ba7a8a68c5719f532cf78b1977e177a0bf4ae76328d7230ac51341f7f4b866e926fd3f44996f3a14af4ccef25296a67a8b71356c2dc6688b9781efc092fda400050910505c7193003de4609842ba365842eb4e19d01fa514322a9915c98be0b48f42b107afaa383351ddfa57f6042bd1c9bc3e47a253ac21b3002004f72a3afb176c7eb9b106c561be17c4375c40b231524b95375b27982970f123b4cbae78fad99c6e6f12a6845671057a2e8e3b4c8a70e757c8b424552b1b79f18eb72a64334ffc70b2b07203ed0870f6630733c26daf928dec6bef96a92064a738b1bc57c10c965d1740b313e5adc7c283674319c89ed38b7224b97804a5566593e15c9404ca582a58b869a485c0fb72f0caba15c00595af1b0eff68479daa985e79a0c5734987a34847215be37729ba51bbb1311f6f0800a37670d3a2f55023e88a019fb068382902a5d94a8fca972dd291178e039f8d2ca22936896c68976ca2309838416108888f13916089556a277e6958352484f231703d120922d103d6b2badb528a2eac86e174186b3278d7f480ec2195006f36583cc91c1288894759807692f15c22b9fa61ab1e587f6f958a5358bd8cb3edd49ae6906aaa7b74f2c2883a0aa1f182357104230349a0c21930f5fc760b821a07aa38b021123b9160d49b2438eca5ec5aca812f96cd7574a0761cb17eb9b71236b19a88d6bcc7e4a0751af543a151417d55093f6530543c678e19c330c63c371f84ee2d07d5a76ac273703b8166e889286da5c5055961084265f2e5817879713d74186fdf56793ec6c8dbbb4dd75196aac4318aa4f773bcf462586566c3c6e980731e7b8273a21c1e4adadf99d4f0c71f8db3f6b28739466c570ea5a548a4d6ed768ea5026b61aa1698279191b69c39b53183c2745a7c251f48d26812eb4764d9196a18af28d91c54035fc149112ba7eec9df4421121aa6132e7069072a59a8739535c9c76959f8138112d7348c9030b60038a66bac005e38be1449e3b961850c1853450b33d680cbc2a586ef37e323891deccb16bc52eab1b7a6fa13205d38963acc148435cfb72803d6054a18c0de3a217037a257e157a59f8a968d250aa1baf88935dc54272bb5950303ac68495956689238bd2b595d7cd42749ae1b38097ea7ff90600056b5ff674a4c02b26aca5cab4379f0864a24fb14f24e274ed640ae6d692adcb3fe2541b9851ba35893967d39531b0c163d5b7f131cda1976e405029614399b7ea6cad628ac5245ab7552fa4d2acb10aa7fe2a91081707c327cf88192d904287c47014a4c51766837a8a39885f09cad717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5e619285c692532735f1582d227b9a9e77b1eae4aab9eaa79f6ce7ac2fcac831811eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +expected_public_key = 781451ec9a7efaf8639ea457c023088684a91cf779fa465940e25955d47a2df9782838648350be44899b198a706c6b5763c2a170c8c5f87b2f9a7b6af7cb48efe386c28c7b0b19a808f24e3e2b6b212a3b8b9a19f6c47d484893ed89cfd3f678207630c3844e969c967eba8926461a58826eff42beae5339c620607a704f91f1b056fa06910746c7e002bc617ecc64add1090ff1d1afaac53a40487b83e9453e6728cf352415a930079abb7e5115bc0745290c706420853d080377e921b5723047c22cfa289d2df186b1908a7bf471e5877fe23b30028a34f3fb27e726b99ba827d347c62997314e39a0f4b2b1e9163f53654e056aaab4718609983bb674a47642a81b000ca7422d3e361af12461b8620064547dfb578959b18bd1b61014d20315a659a5ca65f9cb4ee214b0d123113e34310c56bbd99737f0305f6f3b49f688610a777edd4a3a482163e6cb2c64668fc3aa024d789219078b49471be7dc4395346e7f87c5b150c1e7e30b9d2a435e7c3a32f7c4d33622d7b73cdda989aed858fe4c7e9cb163f35679b84b01096a1e2c3897c290caa996ccb3943e22f789d3c5098aa1a6f117347e0725c358670d678c51a0a9d5f66aaa6923a895cc5fe5c9530b069397a0e4482438e713290c62a94771f7168212a7cda8e2139d573a9ab0137443180c213b78a1b5b291a0f1566316857a72a521c2b79c660792acfc0f5a788962a6ae74e87c48a8010dd6436672817a00b49862721702668ff29f1077a87a96cc27038e0a2752a0d196cb17babc25b2996054d61c68c691c93a6520a97392830a8f157940fa903e75f909bc9691b86391ebe3611e04c9e0678c189b7875d373f0b25b9fe0a9b063cdd4446ab9aa6b23e6ba6c324cac29736447529c76c3398218152607aa5488a5e7b243a0920984b06dfbcc410679ac035ff824768168c758689d0b326831f5c10220c10911540c5b7f9a3510d73cc1153a2fc2a84b8a08cfd7f863e6c93e05f05a39da58cfb57dce98cbf1b7ab960bb14a9b86dc611045d1730f3b82e5eba970018bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab922085c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_private_key = 259193f271825609668f04a250f64b599315c8264bf3104c1b23a4adea1689c16618f20deeacb02dc4cb3dbc816e8712f1192f94c7c0bc2c0f468c2243dab1f351269744701904adf53c3e50fb87e65c4abe161d15759bef01ca78586a6fe64287dc392b94b6fe5b110895402aa843abe89de0689a1674b2b8e29e6bd232dd728ca4447546d2bf29003ee47331d5e1362cc380b6aa0d777a2ef6f38aa295100fca1913e1bdf2bb630c4aa3ff809a9144cba1717f1730afd1d1439998a8bc82c2319c0d46fab3bfa147b9d691d94cc75de0a212009d7fab51a5f216e7aa67336243b2b311cd3638a8c0bd9ff8a6ef699c08374a705ab4718256d476af2ec008e10267767c3548d42e25688db2c8a3dd0874bc34b55637239fd55e2b855cbd431f3a575812c54d57ca19d6e075c5837c8345323657c9cd8b53aeb8a9566a92b12c45aae7958b2920f1574c1e34724e8009d8219b7eba2a0999360e372044e6bc5bb6c658998d307a9ae5d18928e26473e66fe2fa74a6d48cff0834de15b21b11929e4aaecd922803085b78f5551f86c58c560fe639a2c35bcc31271e11fa14d739185c8b062cac95f1a34d6a2b9461a9bf766c140f80baad13be13038844604af313be2006cf79d12f6456c760444a0399562d8220e2496c84d9953779275c808856718f5d3a3908652440700224b0039d6b9abca5a7a1403fc823179e6c0e8784cf86055627b973685cb2ab74b40e85a436c7b66a7453dacb36af915fb934054cfbc36762c17de28b48f5b27a92ad4dd4b8baa16b37a56863bcca1c0505001c45fdec718624a7f6207ec03635edc7c0c793c42e1a7f167a6aecb2a912418c0ff09b771c82e7736b08a09bf54933fae3bf34a593f2d19d90473e499971e214c963b11b427a7aed96b9413ba1fb487045b7359c9510baf04062a907f0a0b8b088bbd0aac738423c5f077ee8da99c0b8166792c63574cb2a5c05f2460b84540a1280a41aa5432ce7445e4aa1d55893a9f1459e6b7811111a1fd98640b35c984503410443f7dc8739d757f4f00d69b3a7dd90845f225932307bc2c92d52ea846bd826781451ec9a7efaf8639ea457c023088684a91cf779fa465940e25955d47a2df9782838648350be44899b198a706c6b5763c2a170c8c5f87b2f9a7b6af7cb48efe386c28c7b0b19a808f24e3e2b6b212a3b8b9a19f6c47d484893ed89cfd3f678207630c3844e969c967eba8926461a58826eff42beae5339c620607a704f91f1b056fa06910746c7e002bc617ecc64add1090ff1d1afaac53a40487b83e9453e6728cf352415a930079abb7e5115bc0745290c706420853d080377e921b5723047c22cfa289d2df186b1908a7bf471e5877fe23b30028a34f3fb27e726b99ba827d347c62997314e39a0f4b2b1e9163f53654e056aaab4718609983bb674a47642a81b000ca7422d3e361af12461b8620064547dfb578959b18bd1b61014d20315a659a5ca65f9cb4ee214b0d123113e34310c56bbd99737f0305f6f3b49f688610a777edd4a3a482163e6cb2c64668fc3aa024d789219078b49471be7dc4395346e7f87c5b150c1e7e30b9d2a435e7c3a32f7c4d33622d7b73cdda989aed858fe4c7e9cb163f35679b84b01096a1e2c3897c290caa996ccb3943e22f789d3c5098aa1a6f117347e0725c358670d678c51a0a9d5f66aaa6923a895cc5fe5c9530b069397a0e4482438e713290c62a94771f7168212a7cda8e2139d573a9ab0137443180c213b78a1b5b291a0f1566316857a72a521c2b79c660792acfc0f5a788962a6ae74e87c48a8010dd6436672817a00b49862721702668ff29f1077a87a96cc27038e0a2752a0d196cb17babc25b2996054d61c68c691c93a6520a97392830a8f157940fa903e75f909bc9691b86391ebe3611e04c9e0678c189b7875d373f0b25b9fe0a9b063cdd4446ab9aa6b23e6ba6c324cac29736447529c76c3398218152607aa5488a5e7b243a0920984b06dfbcc410679ac035ff824768168c758689d0b326831f5c10220c10911540c5b7f9a3510d73cc1153a2fc2a84b8a08cfd7f863e6c93e05f05a39da58cfb57dce98cbf1b7ab960bb14a9b86dc611045d1730f3b82e5eba970018bd2cc4a6fecc9a7f3ca3753b12ee64a7349ab922085c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1dd3761c0e96678a959f30997e96d6a59858528c5e10234398e2da2e50ffcc51711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = 9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +expected_public_key = 1534105e4b3bf53b1e728b61cca6adea603ce85425d8f251b4173f288b2ba4e61a1ff409215046a381211a26b897479a5b1b3623362ae7d22410d9a11f72cad7c107e5659731a6c2e0e95c956386cd2527b29095820b6268dbaf16c0754b583e8288787c186de1f516b204705aa1ac8b80ce70b9100c92093c3a7b69ea8976f5c5dce45b391aa28f0640940166741876baf7b5b7c6878a87438db18ff45c7371016a27e572360c4b2fe4552af9a1a47cb82dc249f2c8bae4197de351a48cbc549e236eb895c487f27ec3e765101a2e68860c61e93022292ec7435df62a1012d78824960216c4ce18e060f1c4af2aba5e9ca9134732149d3a57f72521ec9a97d059515ad9c3add828c75c90f6300e5135cbc646af16866aca30b6bcf60fbd9c0d1a2ac95b999e0749a3f5b9a992e18a8257af35fc9f7e4bce74c87c7496cf2a7a16d966cad9d02260f630d2f1b011aca52f78b6f040759068c0f3f553a4fc0dc7c9a4c8c05ef6c9b026b3be38f0c02049b8c89c88ad01a861f2b1b142a961c62f246a4c19d2cf1849484f884119a823d793a5790420a8f74f97a220ab8b91d475717785c12abb83291b3fb32c7bfe836b7b61c03ec76f36d1c8ca01426c28471676302129116d2a5ea5d415bb13188cd720cb96939f21c7d1fa17a59589817011a48cc65ad90a7353232e8a3db9ac87d425771c7b5bd1968498819dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7d61ba11bc93007147ed613c72f756bc367280278f0076addf854e837b62c9458c34f138e576a99f8a4baf5b596d327149616dc1827d2ef5c828d4764193b4f39a4fcc027d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c5449225132b1c764e91cc686afded843dddb97213c28ed00a6e4e4b66c17074181cd26b15ec1f3c53a18bdd85a6dad68562e3b78180066b4c4c3401aa1f752685ebc8316d6bdb5291e0c39cfe778b8ce55564aa50acae94c4962cd942271ef257bf1993ab04904832a9538e0749c97790f26a09c2c81d95543b5d97667c25da1c7ada9e9780aec099fb096446c03fd1a0b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_private_key = 26f5bd7db659ea8288f5e6bc550817956a1beb27bb0c38ab6222718d6718a0022bb637b6d96304bfc7b71515398c52bdea95cb78fb43676900eb5c8644572ccc73c2f52164a9ea434d8444c94806e1495ce193a873927b78e77479b0ae91854e21f9234715a413d2452e20c273c1a17487bab18870a17cbd5351830d30bccf3124b1173bd19baec1d53fe0ba781a2453d0ca148da2349474343857a806f39d0b7088a4b4b5af1abeb51433b01a11df04806a921fedb3376485b356c6c8e059b854710bd003bd49e56e411a56a9682c221ac55cec46bc0298c8017163b29c74880441b5a6f49b6ca47b4ca7b26802a06943bb11ea5a1aafcba476334422b9a62e2469e24a64d6bcbba8a5001edc50e1b85b339c18fcf55a4c392ffd854a588967dca1b87d3639937b37bea9599b6418476713fbf45b833364a9acbf974c70203c27306065e0f69b748297d74287d2c7a14b265d902c82f7dc608f6089bc4707842ab599f798d1bb21de317efb9483c91423ef0025a2432526636d6f773ab381cc2a56948488666f724fba6b57862925b00418abd72c2ae0602ce8a8f33638ccc626c763636c00b416b7cf12bca01af7a112605f8d4c0c5d5a5c5dab5dd9b22e6fa6b5e30a0cfd90605da8874372c001b26591a847522521e8dbaaabf57ac6595c03377e64f8238e4a7648409e98752860684c00db97eccacdb16ca5a217231eec7b9a7177147c76fb7421a3d7129d05cf27d361e3b8c29abc3f46e9a578233a30233dd1e5a54ee94857a8796256100d76490e9953416781fe168680906d46b950d3a18b382c18bec8c62223a08c3cce9c406b25b5b93c43a420bbc7c5216994e88c148621294c6a3181ad5499c07f615287fb8cd9d847d0d485aa3585455231cd170e90a78784f3c05c280cbcb48d87da39c6c9ab0b9b5a0394b482b17dedec0870134102c8156d6a838e509942b029c9659e3c930aa4f6764d7670781936c303938dcc128a7010bf6962c72b86d06a497bb852fa690f1b43b9ca216efa170216c664eb82a0619944d79bc2bb698f7f77b54abc4c6f56b7d6ca2a1b036551561f1534105e4b3bf53b1e728b61cca6adea603ce85425d8f251b4173f288b2ba4e61a1ff409215046a381211a26b897479a5b1b3623362ae7d22410d9a11f72cad7c107e5659731a6c2e0e95c956386cd2527b29095820b6268dbaf16c0754b583e8288787c186de1f516b204705aa1ac8b80ce70b9100c92093c3a7b69ea8976f5c5dce45b391aa28f0640940166741876baf7b5b7c6878a87438db18ff45c7371016a27e572360c4b2fe4552af9a1a47cb82dc249f2c8bae4197de351a48cbc549e236eb895c487f27ec3e765101a2e68860c61e93022292ec7435df62a1012d78824960216c4ce18e060f1c4af2aba5e9ca9134732149d3a57f72521ec9a97d059515ad9c3add828c75c90f6300e5135cbc646af16866aca30b6bcf60fbd9c0d1a2ac95b999e0749a3f5b9a992e18a8257af35fc9f7e4bce74c87c7496cf2a7a16d966cad9d02260f630d2f1b011aca52f78b6f040759068c0f3f553a4fc0dc7c9a4c8c05ef6c9b026b3be38f0c02049b8c89c88ad01a861f2b1b142a961c62f246a4c19d2cf1849484f884119a823d793a5790420a8f74f97a220ab8b91d475717785c12abb83291b3fb32c7bfe836b7b61c03ec76f36d1c8ca01426c28471676302129116d2a5ea5d415bb13188cd720cb96939f21c7d1fa17a59589817011a48cc65ad90a7353232e8a3db9ac87d425771c7b5bd1968498819dd3d9c471a69254dcb46e36a9ba4a944f543eb9abac7d61ba11bc93007147ed613c72f756bc367280278f0076addf854e837b62c9458c34f138e576a99f8a4baf5b596d327149616dc1827d2ef5c828d4764193b4f39a4fcc027d4c2539c2257fccd8690e64c56fd8897355671d5b829e2656756c5449225132b1c764e91cc686afded843dddb97213c28ed00a6e4e4b66c17074181cd26b15ec1f3c53a18bdd85a6dad68562e3b78180066b4c4c3401aa1f752685ebc8316d6bdb5291e0c39cfe778b8ce55564aa50acae94c4962cd942271ef257bf1993ab04904832a9538e0749c97790f26a09c2c81d95543b5d97667c25da1c7ada9e9780aec099fb096446c03fd1a0b46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef96d9e513a7cd137583507ad7256844bcb9775ca82ef5f411331a7c37ce451181f6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +expected_public_key = 4098cfb36505dcb77ea88c2ab18a760aa67c49228b7e5bb524b5c4be081fb3d8b92cbc4b92ccb4a61a1b1c14521ba4a898d46ba44168dc5a47af9484aeb453c4fc56eab73b0cd0407f5124ccf6b21575805e311af65084e2b0100202a1a39a866ed038328b75bcc206b55a90d714a7175c446dc2091b057ca54c111a820e8a75ba0206715a3042dd0ba36d2cbbd72326532b58b02636cae1949175bc51dc2f46ec5736ea91023657cc65aaa7c22158d22d76a304f796cda7d377c0e79a4aa683f341b7d0321b623782cb189ee6eac197860e05a224fcf12f7cfa8208054a56039485b11c1d888f51c479507b8a85a57b51f5b824f3a9e41274cd188d2099765a004bcc64a86844993fa69c0f63190c347e5f015c6bc290b39cabedcc3be8515905a37fd746616faa036666a08d537aba7a645a501f1cf0c0c8d76d07a67f47514c4c49c854d0b8d3fb02fa34abffd46620e886e00700c7c34a2a9199c78c23f58278fd71c0369b3d0288b711ec5775c70334e984c686cd8e3a141f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31eb51329c8125e8079557a63a53a8a31f245db209cb7375272d9689cd94edd20be8a380f27ac993a9287111cab084c196f4a921b6270e43366ff94af4d4930097cc847769cf3b8016e024733233e9ae67f8f1aac07b450d2299eb1c7ca84c28990377ef1150ff12b14f99b9a1bb705d719321e384399d675b382beef53304074c518382d341578e96b8e123312112c2f4dba5dc5b7278ab251bb3c530bf104783819ea985363fa8b44201d4f1c5c46497ec64380fffc553239cab6f543453485b6044b7b5049f85323d0e8614a8b5c28b52633e72c64db6d0438aceae55b8c239c6b06bf660a146c1a0b132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613ee0520dab93b8c15e0a301f9aeccedd16aa71a9570f31c3cffa013b27a1ec259e738bbd69164f5cc002cba96c68a22b35597f41fba0cdcb81729ac1c4ec49507683fa304d00dd398515ad3e92c33ed440e3013daf434712704921123fbf628531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_private_key = 0950ad4fc96449f3512042277b505267b339a7c58910799cc125ad58785d88f60f73755c0e26582ff9becf91c8a37307c815a5a5d42ea1d10680b4322b095b1789a7631288ac37b6a8d8168d7852f7a7c4a6c178eb43840f44c9a84a8cad91bcbb25207d2546eb341963654411974fbfe2249501115d861d39b046e903bafd4c6791d75249b32b24705892e67a3182268b7c197a025fe5f0689e96a2e11b822565365718721ce6b39061cb9318069fdbb7a1eb2f7fdc188168c124e1a86ee9530482885443a47179bcbad04dca922714a96314811c910439dba531c4787f089a3ca8c7b97db1482171b9e7c72f0535476104998334a99f0bbf168683b0bc49f2d0aca698b92e285592acc7f785cc1dd71a699c4f5da0b986d48dc30c33c443638c344c76387c07bb545a24504fb119ae70276112cd47a3a15cf3ab78b760807c92e2ea23907948e1e0bc11e6597bdb5fe60236fdf4744be21bbbc18dc057088dcccc60ec17081232cf700b04957fe4f052c6dbc053da79b2d9478d2711b1fb79345788089c8c511c50890a24f4767048cc3aeb03911cd19579e26eb64380f95472c9408a85551f0ceb05efc70c105081c1901cf2e9c689f742bf2b8edd0b8403a825d1ba316a9a7b8438c739d64a55e93821b41895c07314c392016476ab38c806926879a69e2271a7b912a5e785120d035cdc507025ac7e4811c5ba6b517cc194a8dc11311832c38934409233b4917844c821dcf61a8f96538ea6964b88a0b5dbb117db4bbdac9db2b6b15723cffe26a63b663295ac3cdd44cb78488a0f5655bb0bccb7c57889f76fb23442eda09248430fd212542df8aa28979179c58fe68521b9149592b9a81b897918682addc32db685acfee337ba52c0552a6445d076d45102ad828fbe7849195cc44824168572263926cfa76031667bc2851314536114d2eb5e68901f3f20ca5de889e24c5440e969e99071d3f135582c7ece997b2ff84e0a934036f03610c62931c7773648583dc9c83e4432c6b66f1346475df3b2a9814327e1504bc69506244d5057004fd839ed07b88d94137598ad222436cc72494098cfb36505dcb77ea88c2ab18a760aa67c49228b7e5bb524b5c4be081fb3d8b92cbc4b92ccb4a61a1b1c14521ba4a898d46ba44168dc5a47af9484aeb453c4fc56eab73b0cd0407f5124ccf6b21575805e311af65084e2b0100202a1a39a866ed038328b75bcc206b55a90d714a7175c446dc2091b057ca54c111a820e8a75ba0206715a3042dd0ba36d2cbbd72326532b58b02636cae1949175bc51dc2f46ec5736ea91023657cc65aaa7c22158d22d76a304f796cda7d377c0e79a4aa683f341b7d0321b623782cb189ee6eac197860e05a224fcf12f7cfa8208054a56039485b11c1d888f51c479507b8a85a57b51f5b824f3a9e41274cd188d2099765a004bcc64a86844993fa69c0f63190c347e5f015c6bc290b39cabedcc3be8515905a37fd746616faa036666a08d537aba7a645a501f1cf0c0c8d76d07a67f47514c4c49c854d0b8d3fb02fa34abffd46620e886e00700c7c34a2a9199c78c23f58278fd71c0369b3d0288b711ec5775c70334e984c686cd8e3a141f175693785d563b5459f59ee3bb98b5cb74f7436dd38cb31eb51329c8125e8079557a63a53a8a31f245db209cb7375272d9689cd94edd20be8a380f27ac993a9287111cab084c196f4a921b6270e43366ff94af4d4930097cc847769cf3b8016e024733233e9ae67f8f1aac07b450d2299eb1c7ca84c28990377ef1150ff12b14f99b9a1bb705d719321e384399d675b382beef53304074c518382d341578e96b8e123312112c2f4dba5dc5b7278ab251bb3c530bf104783819ea985363fa8b44201d4f1c5c46497ec64380fffc553239cab6f543453485b6044b7b5049f85323d0e8614a8b5c28b52633e72c64db6d0438aceae55b8c239c6b06bf660a146c1a0b132c416d66b1ca4c9e37ba41ce2a84427c4fc4e8439ee6613ee0520dab93b8c15e0a301f9aeccedd16aa71a9570f31c3cffa013b27a1ec259e738bbd69164f5cc002cba96c68a22b35597f41fba0cdcb81729ac1c4ec49507683fa304d00dd398515ad3e92c33ed440e3013daf434712704921123fbf628531d9ba23c4a369c58aab1557eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516b252e5abf757e116a92518eb72df9f9ce66b07edf4d31be225585a6a827a35b8faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +expected_public_key = 68517fb17496bc71146b716e9c289410ca7ac5fc5f663abb1b7672f8115917c610dada39ae344dfe805568a0141b6103a9d07bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326043258a62211ebb3568d10b46b08864b637e94a38b132199001a5f34c5e8dfba0f853980f071d8125c12ca665e72673102c05d50b28f71696f90c274e74cf57cbc86be00177930fa0a1164a245d57b4b2fe6c4e0f740d87b8695da43a98e79b3b102efdb35253812336c1058e727e14c08444f24b1415312185b2afb6ccd9b5920781ac0b5a7a483125a1a2300974c429e7957de3a796a48996f1579982adeb538dbfb8867a855059622fa7394fcaccc507013c910c79558b1bd4b5bc696052005c8c413253e6617ee827bc31bc973bb0bca2d6ae0b17239c1210b4866f5802086460589c64963a83a3ef18b5277272030079b3c2015cc1544985c687a438e94145838a14648c5ef5bb46a0988f42e124397bcfa42a2dff898efb586b2c6aa86b75b0eba10b2aba678687822ed5ac8dbccd49966e2f1991e09260f547a4b0d02a6d9b31ed02bee1764f7a5085ebf51fd5862550e0a19d05a78a80276ca0414ffc07b109afbaa9ba78674b92c5b6df20a153051a3c2378b7d05882ea15ac2183a62b8efdc15a9063b041bc1ba601bd9c16c6156c6e4ad82c6be595152174d1527a6555b42086be9d05945a289ee90c91e525b8a69324aff21306f5375d0934b49677b1f288d1dac1d1918adfe3abf0e738c81b0087e22c1b23aed4d742c283ca5530a0960122cb2a79c0a2966c5780034297fb4c1569d2b73127bee4e53016b04188599bfc468df3b091cc0a62a0832137127eaadc7bb0176baa45788e994cb8983c7b08547d340092594cd0f05d3baaae475092c3499e73d16584daa3e3f31df226c30aa49e59313e5dc98a6eb16f40875fddeb735ea6cafc657db8692d28c35c69022ad1e53418c461dcf46d5a40046193ca8277b28ef606a9e152946b04591ccbb1b7271940105436644e275d6f4503b5a32fc9907bf5c98d7f90623b822feb0c033a1b90d87422453a0460087b81098c163c295079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_private_key = a2753e3fa25fd7824843d5a621205f777c992c7bc7e49a740ca64571804a0910768ea40a6b3780ae95a6c3a0236f3a3f729c232a9b275351a3bca02f09e6828601a6e8b2900017b32da12267a856a8f3147c954574c954daac9c7f1bb90e66c5df96a6213b98f6f470f3095d6b37a3482ba7ce984f4a4789901b63c35a573980216d7098424500359b6fbf953b6e0a662ae160d056cd31c26a699a05b28106fb272119583bfee78e86d7bcc430b28f071236903e39e3316341046073b8d27b1370601df2d901347682527c7cdf4875fdd6c0d3330f51334fcc8946f2363bf9c0b55798a81e4c9e95db7550a7535b1c909a5a8c353b67efbc3892821262671abca02797a5948e53cc32ba32f2c5a8823c84b903c9e7d50669ca6e499c888b64be5b59a758711d49022f4604a11e590fa713135bd521b594331d2783a4d958a8f7b42893a16ea12f2173553e496a3c4089137947a0e55bc20c795ba12d81032118db3bb1363eaa92c24860c72f424836043aa6085c81eccfef70a85e981e017045a1d194f1b76128d1953e92bc1b09a708a51227484928505a4e467c3cd508b9d52591c8659f27bbef053f8ee8a0fca26abfc4a515470545069c1bb8230c58b33f5c591f27ce6dd174ef1621dba035e4c07eaa97a08b92c6a3b52d3b07a6cd3a58518989e9a77ca7125dcbfc7936f506e7d65a9df7c761cbbd67c35dbb89a04053b97eb0b8ac37b22cab34bfac91d7c83850b834beb5c034fc1145b93c2339275dc47bbd828df71b41c32666350ac4c4e3087fd64bcca47f3d0638bd26cc2309578f7c621b56ad0ad912d84054826a02540597e73bc6f015434a55c9ff8c446c23a35820ae4cd220dd3aa454f9c9c153ab640accca49c4e8fc7d946b900ed68bfb33908374382de59d02e4abb581a688f0137e51118253185ea19784a683bfd6845578a348d7bfa2e5a35cdba7bac582926b57e8831c90b3c6b8e6cc3af84556d34e5779bb97b0b2dfc316a54bc57c112f49e9ad3ab98b53e31256996780323656cbcb60522f9edb4593676d9d67c2cd729626147e5c37aa38903333c82c17f97b68517fb17496bc71146b716e9c289410ca7ac5fc5f663abb1b7672f8115917c610dada39ae344dfe805568a0141b6103a9d07bd5f7a600a4a11ba8bdaf98803dc8bb6dab82249c326043258a62211ebb3568d10b46b08864b637e94a38b132199001a5f34c5e8dfba0f853980f071d8125c12ca665e72673102c05d50b28f71696f90c274e74cf57cbc86be00177930fa0a1164a245d57b4b2fe6c4e0f740d87b8695da43a98e79b3b102efdb35253812336c1058e727e14c08444f24b1415312185b2afb6ccd9b5920781ac0b5a7a483125a1a2300974c429e7957de3a796a48996f1579982adeb538dbfb8867a855059622fa7394fcaccc507013c910c79558b1bd4b5bc696052005c8c413253e6617ee827bc31bc973bb0bca2d6ae0b17239c1210b4866f5802086460589c64963a83a3ef18b5277272030079b3c2015cc1544985c687a438e94145838a14648c5ef5bb46a0988f42e124397bcfa42a2dff898efb586b2c6aa86b75b0eba10b2aba678687822ed5ac8dbccd49966e2f1991e09260f547a4b0d02a6d9b31ed02bee1764f7a5085ebf51fd5862550e0a19d05a78a80276ca0414ffc07b109afbaa9ba78674b92c5b6df20a153051a3c2378b7d05882ea15ac2183a62b8efdc15a9063b041bc1ba601bd9c16c6156c6e4ad82c6be595152174d1527a6555b42086be9d05945a289ee90c91e525b8a69324aff21306f5375d0934b49677b1f288d1dac1d1918adfe3abf0e738c81b0087e22c1b23aed4d742c283ca5530a0960122cb2a79c0a2966c5780034297fb4c1569d2b73127bee4e53016b04188599bfc468df3b091cc0a62a0832137127eaadc7bb0176baa45788e994cb8983c7b08547d340092594cd0f05d3baaae475092c3499e73d16584daa3e3f31df226c30aa49e59313e5dc98a6eb16f40875fddeb735ea6cafc657db8692d28c35c69022ad1e53418c461dcf46d5a40046193ca8277b28ef606a9e152946b04591ccbb1b7271940105436644e275d6f4503b5a32fc9907bf5c98d7f90623b822feb0c033a1b90d87422453a0460087b81098c163c295079896401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d018c081231277f424c5f3f1f6b4db91958611fa28bcf09ccb2573da64547e1958a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = 6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +expected_public_key = b130cd26fc457b8ccdc1a7ad81ac5db25945132a6c152b12a29c8149419543a6bab0b8af5dd272c5a7b19b82199e943c5a12280a22453ff36c7b698f40d092e651cbee12cfd3843c07da95fb5168a4f9ae4553b149ec3f0960199f6375499372247cc59f4719916b168f02574e1cbef360cc18c3ba41a3258df742d9f6b32c076f695a7da1479790d9a1809001747002d8f488cd54be71022e134a4e8a9aca21570351248a4daa454fb201b5e57d15b30994b374277b3861898734436c736a2fcf0a9214661551ba8530b6ca4f36a74f8933b3c2bd0fc89b78146871c8849b31acd0fa55726836f8a6a2a36a32d43b78f94810141c6b18b4bb6763290a289ad6363f08816c3bb3a2e519a1dfe276f6814b7f693958f4746ccb68cd320ae60c589ea94023c7adc3c680a5c17075d772b28bcd8d109397407b60c2a7ee00758d7c52630ab0f686b510969404cc1a9110338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed0a283f71912b69b40d6a1f84a56576a02b129409e2429d44a9b45858243279a5fdf07f00e6392c662de780a5b8f82ec6dc248347c9a02062ebb67eb33457e5d36f10fb99db0171ef0949d117be5034ccbdf951a46c7497166294727b59c4b63034435e41c75d70641f800f0d458b23736ecb76bec2702b152389ce91736890af06840cb8d9b8f375a33b03438e9236fa3a221f83186f77aa388c840e2b6b9328710a2092faa59eb8aa2d59769be77046cc334f9704c8b855a787373dbd77215f268946e5c8792aad13e645f292bc73487432897c50e817a1f15002f472e404298a785b26f441ced2b5c7235c7f3b4428d78a7d47cf4b83561ac38da9cc124eb40b44b48231c9078702510326095b2b3492b82ddce7a433e97c65878f8fea220459bf77a81b8f010ac66ca102fc14fe804680fa9678c41746211444d85aba5c57051422c69630acfc7b86a843a74127effc452035b41477ac3ea934008076f09796323cc9d1970864300e5c309f3d7a3419d25fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_private_key = 0eb3ce9a9448f8252e9e4178b1e103fc9c546d5902f2449f375a877e7461d602ab4f68c2ad47b3f9e90ce9271833d40792845fb4c38eb8b231132a7374898032333b8d427272a4afb2c54f5e37bc0446385541201be25df5ab21b0045bd304b62a15c14fcb465e29b845e457430757e5902fe3293837b31b43655978e17411154de442748b1a69d0b728f273769de1544950a69bd4558e032ded3abffa163c30705ecb290896a9b08c34a41a521ca94ac999501c84e89dcb30413cc27e105bb81d88a3ee3678e6a40af492afcdc276a9d67bc7e87aa5d78f9d046ba453c1cd4c26909b916ec8cd7c3877c5eb3e5b4028ddba148500381992b76b3b40fb374a4e45b3e87ac4d4b1434272c68c948f3e777777c78db6f506b79768bdc6657ff298a4252db310025319b0f612a1b8a3509f32418984193d540753da22f151724b264692620af8f661a180109fb0718ee588aa7443f6824fcdc3c28b523b2e822871e32deae143d0f024c7da5572415fdcd9af004848f3fc1fb5b38c0b3c71f88b4266bacb56d38b20538cca1a5eda892e334315213ca163c36beec696372c4d7cb28c2e8a82e96930fdb628eba59e24e208e9857cd63351b6f0911d8618482a41ece8352ada231dc77c3c7ab51e6ac73fc7700fc97a3d3c14297705dd4bcb529247defa600c6504eb38cb7c00a6d2956a3a14b21cca2e6013b954b967050bc5369477c59a365a44057a00ae8b746e57e5540b7199fe200c3917adcf914cb1ea8bafc3cdc2a53c3f70c0ef29394f55cd799c44d309d0a4735bcc4a8dec7160a35211141573eef285bb0c11f7d828d2497f9a63446150c179e6854429a0a2d09a78d4b9d8c73123c2411f2ac72344c7f221c7bf9c3012d6151b496912551db06224bb5743df435c281c3d2cf77efbe606cfd5b79b2ca45f02bfdb123aca61a4c1e512f8017501e2bb68c45585e06858e05621bb4098d870ba679e541a28a380bddc568bd187882a051e34bb8f36bcc8d8f05c4777761d8267241308b0961a267a7caaeca84247421fa8cebcc2b88ad9958ff61aa0c2cdb7f4b0041051254112cf7bc9b130cd26fc457b8ccdc1a7ad81ac5db25945132a6c152b12a29c8149419543a6bab0b8af5dd272c5a7b19b82199e943c5a12280a22453ff36c7b698f40d092e651cbee12cfd3843c07da95fb5168a4f9ae4553b149ec3f0960199f6375499372247cc59f4719916b168f02574e1cbef360cc18c3ba41a3258df742d9f6b32c076f695a7da1479790d9a1809001747002d8f488cd54be71022e134a4e8a9aca21570351248a4daa454fb201b5e57d15b30994b374277b3861898734436c736a2fcf0a9214661551ba8530b6ca4f36a74f8933b3c2bd0fc89b78146871c8849b31acd0fa55726836f8a6a2a36a32d43b78f94810141c6b18b4bb6763290a289ad6363f08816c3bb3a2e519a1dfe276f6814b7f693958f4746ccb68cd320ae60c589ea94023c7adc3c680a5c17075d772b28bcd8d109397407b60c2a7ee00758d7c52630ab0f686b510969404cc1a9110338be54435084410756e7ea3937ae64523e9b2d5689d77863b5338b482daa294455aed0a283f71912b69b40d6a1f84a56576a02b129409e2429d44a9b45858243279a5fdf07f00e6392c662de780a5b8f82ec6dc248347c9a02062ebb67eb33457e5d36f10fb99db0171ef0949d117be5034ccbdf951a46c7497166294727b59c4b63034435e41c75d70641f800f0d458b23736ecb76bec2702b152389ce91736890af06840cb8d9b8f375a33b03438e9236fa3a221f83186f77aa388c840e2b6b9328710a2092faa59eb8aa2d59769be77046cc334f9704c8b855a787373dbd77215f268946e5c8792aad13e645f292bc73487432897c50e817a1f15002f472e404298a785b26f441ced2b5c7235c7f3b4428d78a7d47cf4b83561ac38da9cc124eb40b44b48231c9078702510326095b2b3492b82ddce7a433e97c65878f8fea220459bf77a81b8f010ac66ca102fc14fe804680fa9678c41746211444d85aba5c57051422c69630acfc7b86a843a74127effc452035b41477ac3ea934008076f09796323cc9d1970864300e5c309f3d7a3419d25fba23343f459df543524f999230cc8052cb582d2557fe5b8b6f196346ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e40ac7db13184d6ae6e21a14a63a2ab3d6d5d1ee7f4a6011413a0295b752fd2c28ce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +expected_public_key = 320558ec426b57e36419124bb8516c6b4232728a1ec4f1a51dd01b932738d9b00c6a50cbefb657969b4dd318295b6278f73963da647156944423045978c50d3c078e6d0729e0219352028970272f34147900370d490c12fce9b22357bf72fb470e748d82b79859133d8db603ac7cb2672ca9c7226b6e99a7488a219966b7b897ab398002090b4900acb068a866c50c3867380ff5eb2e0c9c4eaf497adbeb79632b0c023474837709a3d7cdec9c2f782c9a3ec0c6ddfb37cb3321db6315f0b0ae23e7c6a4e291baa61e4fd26c98f36f69d75369f5af277124295158b2506a39eb43d1a16308b71f3bb5cc26897df2378837d9cfa1ac4745718fc3739f5535c35e07b461a8cd65da18a3809d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcb41d00bac933c3783f05c47ca28058558cc05690bae3c507fa8d5780227a61095f0171a6d826f714146c934b80e07672e6bd66432ad1479136c06dd1a29f00d18b26ab9f8fdb7e6021ce7c657948273268e6b65245101952c73d949c4d82c8144a3dbfa7a82784844d57b354b1598076258fe83a23987de29261b0a8761ae3167d035e96b78fecb9bb51055d86e46466708d79a8b732b686a23b7e36f9ce07ba6956cc46bba61ce934af8ba7738bec5de094010aec2885a8153bf71f002c9eda917f337bbc18da2324b45bc79127d21b1c12774c6fca6a5166c4f03440af4520cd09233d493461420e5ff81ba290cfd23001052a9dd3665121392224746064f00f5b1a4dc19528a7b95c524304aa21164a45c964a7320d2611c68498faf56cfc195373267b01591e6c0a8d1bc0007ed456a4e205c49495ff99b1b1754a9e429346536d16e015dbf7967e851974b19721e845008b76b2c47e7c3b04457c924693bfb6007c918c64cc28126665b01cd18b7a253bd0706d3c466eac224fa12bcfd60417afc1b865029b672663afb3ba51b6a2b20502de6c6bbdb33a0ac4765f967f8d685ef1200ae1d17cd5b47aca963f2ba5cc38059b6937916566a219ac32157728dfec1b9950687ff543169a96f648ad2501948316b55ed4c1e861661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_private_key = 5a3861a9a0670a9ccd72238832c63a956965df07b614cc8073b95c6a3375f9b73e32333d33e96ea3140aeab832b523bc7d55361aac727dd3c22d8059062c37733c241f388199ba39a4f6a08b2403d14b760e525c85a87f8c732d1be726cf11295010bce0384c37e1ac73787d17b2b5aa4b094cbc17b1d2ae5a14ab12d51d7f319f3928ba35ea00cec1706be397ab323c13b852653bb6725121e2793e2f19cf1d54c95d8b7d7520cd63350012e2b815d1ca9e518f7089258a3a217aa1a9d3392bc9aaabec9668a70403ff6c193d2a185f8294da15c9a1d1120184b5fc7a3dac62c1909913f68741227556aaf6c3fa58426c99a5ab8ace5b1614c23cb079084d310a3fd6f738ddb86edca4c1f975508c394637b94a57e60eab053dc74556d950353de0a0f8207f2efb4e1b34642f8b7fd836876f41ce5d152026a3881c375e2a613ec610a21363cf0ecb42f9a7acb0000035e113ad8bbcd279756f60837f9520e4f907c3f79e34b5c852ec3f33b432027076e6968eaf11203f7461548969b472487660beff441cfbdb0e4701804a175e121b10466a51403c095e45517c481199d62ffba850e8d5452f43857484066f7513f6a24289a619cfe14889585271f7aace5b2b43937255d469177c17c2e636d2909f4bf165f49b102e20c1beda46026a14a993127dda10ea989a05cb04f546a663f068abc4cabb32a7a4568023796c39329c9cac6183d9b88e1625c603378aa1c041d0c1436105ee284e30f24d54c79fe332c63fd92e2928892e8401c64c6982b7607127882d633dc87335262920a458938877496976bb122bc09cc40ff6511fa29320fb581563799dcd56a4d36125b7dc5731a3888b3331dcdcccb2dc21eec146625854cbf863b2e0091334af76a741b7db1d69116e2e868d21d942eb99c5b24a9139c63c3c882a879a2c5e341177c149a7f32c0540ae2a9c3d61a4692807afa3469e363a6abfa18103923e908b7d7028497cd3cafa81a8873c7064a7a1c3b310c523b3df396eb71b0bddc12a32cab323017fda4378f919cf8ce660d8a8616f43539f2aa8acf74f6549743985865f2673320558ec426b57e36419124bb8516c6b4232728a1ec4f1a51dd01b932738d9b00c6a50cbefb657969b4dd318295b6278f73963da647156944423045978c50d3c078e6d0729e0219352028970272f34147900370d490c12fce9b22357bf72fb470e748d82b79859133d8db603ac7cb2672ca9c7226b6e99a7488a219966b7b897ab398002090b4900acb068a866c50c3867380ff5eb2e0c9c4eaf497adbeb79632b0c023474837709a3d7cdec9c2f782c9a3ec0c6ddfb37cb3321db6315f0b0ae23e7c6a4e291baa61e4fd26c98f36f69d75369f5af277124295158b2506a39eb43d1a16308b71f3bb5cc26897df2378837d9cfa1ac4745718fc3739f5535c35e07b461a8cd65da18a3809d7b6384f474a3ff95c5b379a78ff9410ad3a8f0085b83573dbcb41d00bac933c3783f05c47ca28058558cc05690bae3c507fa8d5780227a61095f0171a6d826f714146c934b80e07672e6bd66432ad1479136c06dd1a29f00d18b26ab9f8fdb7e6021ce7c657948273268e6b65245101952c73d949c4d82c8144a3dbfa7a82784844d57b354b1598076258fe83a23987de29261b0a8761ae3167d035e96b78fecb9bb51055d86e46466708d79a8b732b686a23b7e36f9ce07ba6956cc46bba61ce934af8ba7738bec5de094010aec2885a8153bf71f002c9eda917f337bbc18da2324b45bc79127d21b1c12774c6fca6a5166c4f03440af4520cd09233d493461420e5ff81ba290cfd23001052a9dd3665121392224746064f00f5b1a4dc19528a7b95c524304aa21164a45c964a7320d2611c68498faf56cfc195373267b01591e6c0a8d1bc0007ed456a4e205c49495ff99b1b1754a9e429346536d16e015dbf7967e851974b19721e845008b76b2c47e7c3b04457c924693bfb6007c918c64cc28126665b01cd18b7a253bd0706d3c466eac224fa12bcfd60417afc1b865029b672663afb3ba51b6a2b20502de6c6bbdb33a0ac4765f967f8d685ef1200ae1d17cd5b47aca963f2ba5cc38059b6937916566a219ac32157728dfec1b9950687ff543169a96f648ad2501948316b55ed4c1e861661c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f527ea5a76294070ab10a6edc502d82be3d240672e5fa61377e73e5e19d11f64a37f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +expected_public_key = 16d85b965a81b1f55647985ec3f58023574f49003f67d1847c44a40d48a2d3d86a0e66505037b1a9898be7010d98c686d496c646babf8f998833620e287b7464f8005bf4acb8839d93a311e99ca4f889b123b81f6e740b604cb86464837be291d1f4a919b07dbcb9589a228286ea1ff56554a818439a3c8f1753b459dc557ed135149553d7d82b1d8c0fcdacc3043729d6ec9511c6a3f279783a2a8457817df77ac945450732d148f8964b83c16e7319ac67acb7fc903501d466fcfa22ee13a7010615bb7a2edad26fdec633397516ce0c36d2288ef1fcbe2e1b459348cc6ea669d8810740b2b7581a9e1f62825d80c903e57d40732abbdb7736e8a1a1ea9a20d217d55b5355aab672e61ae0d183e660c182b846161147aa1426e34269636406cf142cfdf43982a076be1ac956e114c316a7d6921674f6cab0fa0c49c91e01ca7ff76b61d06c13701892e208390edc717447a2b01c8a2d855c7487c37a0043644b26fb3a446774baeef30d1a09a3ea9680f52449df85262437b14afc2b4ea62504f443af0752b97620ba8145b396ced5366dbc9447c010740614360401be32903f2680817542b356a7a6ff830e944b2af872779f34911d9b99b0a98f3198198d73922f5567aba3b8a55b2341fbac3a2a3dcfb46256885331417f4eb8c209c235921a440e8695032247600c885a82acbe34af41653a33200ff59794fd98840f94745a607931c1a8a4450e67cb23a99b46a4368b6060b4dbbb5a394820a16bb139baa15af551b40a6b01232cb99801cdd4387f23ad6dec96edea64b64a76fbfc35587508733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddc0216d226bed9b723cf846aee457b0ec23c59107caaa49a3c879b761350ed319a828507bc687561a87841e56f37f4b4f6f77e253988f38488ff2a1e9b07257268a209f9b31705bef791236ce9c193f2980ad38c5b9939189a618598ce90f435221214259c6555c7041e2a9a12bcad5b86cc04842d992834425a10a3411f5609af68a525290320cc1cb607974c6d19b662122245991efa06cc6f075e84f2b025018f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_private_key = 64dbcfc86711f74046a26641dd9065f197ad5f2c8f62056b9a2b027452b0fa07241085ae275570f7b248878bcd2664764b76a810c401b16a2de82177c0b93c7f204823643fb92978ef23a81199b9a5c04966d94d59a13270b32afd858f61074bd14b6605a999f940194a127e21507416158bd22155c7c46ae229c57ad4c1d4517bf1977c47a73c1e05998352a9cb76be6d17329ae9b1e42a08499918029ccc4ba00ad507aa10a18d96c5b4c40a78a9f23162f20344d61811323feed16ddc8635f14c9ddb879fc3c5678321af658cacbd3236f9949ed2f1b56a94b05fc0cec8d737b434c341c444c4271faa241487c130cacac5afbbb0b7558372356d5555839d89b9d3a47ae3b9cb596920cc0c19c97c389ed76b2b04c6a764a363d4229989c0d82986889840f4fc716a9a0f08530339b89a3ce468c59607bc45215e771a7e7a86a3880ea776a128b08539655a1d83810aac7ff0c589dfe85cadcc91aef6268115c5e7275d4df19264e98a40275b66f00010f54ff231cdd62abf2dc8cc29d6c3616ba123156049f667755c8a58e93dfcc640eb1a59c6f49b3b4845bc00181fb46279a02219937395318f3d943772ea71c965b15c272d5c92cc71e025147c3a4263bfcb7490045951dfe91f027305caecc152c09150b1aa4893845dd4330172b3db2688a4fc6d9fa9776c988a664c3af8c5a081c9915160a5b7f61b1956ca67b28a63560762ca8ce9260b50827be105bf45ea56fd8a2c2831abeac08f1bc808fe2c3654030d41507277638dcd06bafd909683e6ba5408a3cd358ce90c69a0959fd39169e96bab584b4cda80c6c0140574d4053b109bda0c6e05060628240c41ca0864bc0c516c6d1c45c308125377464114e82d67958c886c5bf0d17b2776a7832a330356b7bd936dcb23ba530b8c63f8583a8051923cb408c01fec645726608130a138e6306d2ee0842e917617ab464712035f088f8f759904550e2e0681f95453bab9c61d16b1c2d64ab37c9f787b1976c6755d27c9be181c44a5bea47b9a6df9abe394b894106a03569e130c6fefaba53a583f7e35781fd5638f5186132c0116d85b965a81b1f55647985ec3f58023574f49003f67d1847c44a40d48a2d3d86a0e66505037b1a9898be7010d98c686d496c646babf8f998833620e287b7464f8005bf4acb8839d93a311e99ca4f889b123b81f6e740b604cb86464837be291d1f4a919b07dbcb9589a228286ea1ff56554a818439a3c8f1753b459dc557ed135149553d7d82b1d8c0fcdacc3043729d6ec9511c6a3f279783a2a8457817df77ac945450732d148f8964b83c16e7319ac67acb7fc903501d466fcfa22ee13a7010615bb7a2edad26fdec633397516ce0c36d2288ef1fcbe2e1b459348cc6ea669d8810740b2b7581a9e1f62825d80c903e57d40732abbdb7736e8a1a1ea9a20d217d55b5355aab672e61ae0d183e660c182b846161147aa1426e34269636406cf142cfdf43982a076be1ac956e114c316a7d6921674f6cab0fa0c49c91e01ca7ff76b61d06c13701892e208390edc717447a2b01c8a2d855c7487c37a0043644b26fb3a446774baeef30d1a09a3ea9680f52449df85262437b14afc2b4ea62504f443af0752b97620ba8145b396ced5366dbc9447c010740614360401be32903f2680817542b356a7a6ff830e944b2af872779f34911d9b99b0a98f3198198d73922f5567aba3b8a55b2341fbac3a2a3dcfb46256885331417f4eb8c209c235921a440e8695032247600c885a82acbe34af41653a33200ff59794fd98840f94745a607931c1a8a4450e67cb23a99b46a4368b6060b4dbbb5a394820a16bb139baa15af551b40a6b01232cb99801cdd4387f23ad6dec96edea64b64a76fbfc35587508733c5e08ba4dce5376de978f4ed980872b3d4dca59eb1bad19236ddc0216d226bed9b723cf846aee457b0ec23c59107caaa49a3c879b761350ed319a828507bc687561a87841e56f37f4b4f6f77e253988f38488ff2a1e9b07257268a209f9b31705bef791236ce9c193f2980ad38c5b9939189a618598ce90f435221214259c6555c7041e2a9a12bcad5b86cc04842d992834425a10a3411f5609af68a525290320cc1cb607974c6d19b662122245991efa06cc6f075e84f2b025018f9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa09859898462f05bea461adb40faacdfdde363c06f58bc756f0a8417df63a66d3a544d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +expected_public_key = dd08cb516c78a4619895f576bc8b3367f99d50aa502f365a5ab881d18044150539084a918d43a002665f4dd155c6bb9363127412dc05df9c9c2df480937507210c8a1a419c9cbc840e54a0734c8a281bc5fa709a2312798c998b9cec0ea947c0e9fc128a51700a21be8841395a2552ffa4645dc67212117131db3b54989bbbd5569ac4cc7e43b4b6a012ed87757f46a8382ccf1c561868ca741e51a554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759ac091519aafa6a4367e19b376011adfd48d34521e47b10bf497714f6464388121f46a444ca791ab9b84741518ad082153b2944d61a9ab8689410a7424b653443a9089ab110dd83d91f07adad9ccb6bc05f4a34133248524f5347f2473ab0c18b2fb3da280a8364464cbcb1c62dc7505b6c2cd057de444ba218ba49eca1142281e971bbdf531cabe6b7cc6892ab7b304c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627bb09f7dc6609b18a3c92badfba6560574bfe70b4b3578f1778785754146aac9e2a890d368b7144e7b95e4516adbc2eccc82e81627935bc455d9397ff14828a8c0a84f5a876990d909c481cf0668f9787b9f87b7604b392443d4d16a0f201057d578cb7411532528c190523a06120dee1a291e55d0fe860821b9647d289158163b19748a1477fa31b3e7c048cb93287a3d7760caa0a0bc5c880d6723ae61f4fba744808aae2e3742016c81d371638b883447a1e3db611f241255bfaa48811397989382369ce7a59a3a17c559fa29ca4b7a6751526c1db169dcb7fe00a146f6033cb44207836c405a4aa1c1274c9206537c1b767c9948c533e836a2bc7373c10c7b149ec2cad5bb515186ed9865968801dfab0123e3ac729681754265e8c9a3e9745cb9a770b2aecb473631184832b086a7a2217ab2d553d54aa431567a52f25078c10ac6f206e1e198df76cc6f8828b337685fe84abc3151bc6817a98c5beb0db1b2a4a28a7580747b6330da24561c7ce37d8750952945ce7731983b62a1025f322b515e47442b05a01955b4ad8aa63856345151c8142718e7412ba20aad10624ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_private_key = 4a057f90101eabd7270e3b51eaa016e7c88b931bab7839776aacc82fc99530e8544a67cf487c002cf289c57c0e2a4811ba9b168a20b5f78208e4b615dd9354ea67c919673b6e5560421776013749c3016974c6044d3b92f585856437b2f7b6627db363260a0f6138445ad21f527592d0facd7c40bcec70c75c72cad891b66ff533ab40c1989816b4c64177b397bee52a4a8ca07cd64997115d339cbaeebb53a2fcc42f851a6c88766c54b0c6744e41e3c1e0c6b3547ba890129641fc10af94ac12c623f44490967242f9845c4f360bea0c3aeba99ff0984c8c2872ce400f8e924c77741d8a861bd2bab8acc4bce2a34324346aed98353e14b52e27890b984102943a7378b641b6c6425441a57c9f1d594cea351f3ca22b74ec09f47714f7b8b41c186ed6548c5b141335a503701459b30017f364180bb4635a83cf0cc2b48293c0e215239241c656664082e97402478d1fe39a9194b8b585c3fe024abae8a60ef70db89336e06214621ac2b69114d8f0a03e2993715241e2e7b45b852d0aa12c84e941137b17a6379b30e31b64d64dabb6935b758aad601e0fa980331319792072cea89fc4819b54f9501602a0c46bb31f9a5165e5bcbc4453b71a04af9573142c3ed98c3f88e83b0dd4c2f4370915a71e3cc5c29e51c9cc1cb38388b9812127ac59aacd5a2159f34f0f40acc0712e106c87cef441deb6089c3196dce4b6b81a559c0bbf7e4097215795549b52857868c907a08497ad0042bd128460d1c88d78b29fc76ba35ccb7748c6cc85eac37ac05a63e76ce24a81d9888d42c83796a9890c09a604ca6e5ba596a3575276474a63224e0224048911bd501c60bb34871581ca0923bec2790740c26d3babb74063b9f668ae037c0a656467eed87b6f6a18158c4e9c753cc6a570043a278233121776198006be0f28c5744b98f3e33483387b56b6ae138122dfb46d0f1014acf383fab60023d619a9ea7a3355536bebcc3670c742c52cc9312be8e182de09aae8b4bad265c8cbfc6715664dd8c67062db10088b6d3905a5fafc415a0337d878cf4feb29fa307761d981db422b3e5b80ee9accdd08cb516c78a4619895f576bc8b3367f99d50aa502f365a5ab881d18044150539084a918d43a002665f4dd155c6bb9363127412dc05df9c9c2df480937507210c8a1a419c9cbc840e54a0734c8a281bc5fa709a2312798c998b9cec0ea947c0e9fc128a51700a21be8841395a2552ffa4645dc67212117131db3b54989bbbd5569ac4cc7e43b4b6a012ed87757f46a8382ccf1c561868ca741e51a554393de04980d3538fd59c6f1c043e6378773675bd3f185f1cec759ac091519aafa6a4367e19b376011adfd48d34521e47b10bf497714f6464388121f46a444ca791ab9b84741518ad082153b2944d61a9ab8689410a7424b653443a9089ab110dd83d91f07adad9ccb6bc05f4a34133248524f5347f2473ab0c18b2fb3da280a8364464cbcb1c62dc7505b6c2cd057de444ba218ba49eca1142281e971bbdf531cabe6b7cc6892ab7b304c6d8c1137abf1bab7867aa308c7690aa29cbd9dcc37c7cb627bb09f7dc6609b18a3c92badfba6560574bfe70b4b3578f1778785754146aac9e2a890d368b7144e7b95e4516adbc2eccc82e81627935bc455d9397ff14828a8c0a84f5a876990d909c481cf0668f9787b9f87b7604b392443d4d16a0f201057d578cb7411532528c190523a06120dee1a291e55d0fe860821b9647d289158163b19748a1477fa31b3e7c048cb93287a3d7760caa0a0bc5c880d6723ae61f4fba744808aae2e3742016c81d371638b883447a1e3db611f241255bfaa48811397989382369ce7a59a3a17c559fa29ca4b7a6751526c1db169dcb7fe00a146f6033cb44207836c405a4aa1c1274c9206537c1b767c9948c533e836a2bc7373c10c7b149ec2cad5bb515186ed9865968801dfab0123e3ac729681754265e8c9a3e9745cb9a770b2aecb473631184832b086a7a2217ab2d553d54aa431567a52f25078c10ac6f206e1e198df76cc6f8828b337685fe84abc3151bc6817a98c5beb0db1b2a4a28a7580747b6330da24561c7ce37d8750952945ce7731983b62a1025f322b515e47442b05a01955b4ad8aa63856345151c8142718e7412ba20aad10624ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24a24e6203d9b1aa5cd06c44f048da7225e33952617f12b4289494b3969857c2ff8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +expected_public_key = 57178f4476049b9483f4357ac027b219226fd5a9c2b9da1f45c9036d55411bb3c8f941b75a844baa7388ddb811abb4cb13d003aee4aeab466a592b77041bae4733b5f1cb6ce2765778b02455c5536a02a2dfa640248c6442398f48a5b8ac7b6e2630b2c1e872a3e752da777eb4607875e0c771f81ccd633961a5c9d5987dde31439dc131f536b083709f7f072dd75533f9c984f08c7fc952878f2b9720da006c3b60f5298ed3921205604fc6cb969aaa69c3f3a230b3865a84a555925c895c58fd19c3b98b7b2d2acb941a44b7e519c7d22aefcab1def18429713772285de2ca225b5489466322538bce1ed99e9dab3443e47a5ce5a9b284008865a4177666345237cb7b796b9582da027d7af4ad28f558e4d7426caa80c3a19400e286799caff5b4bfea5cc04631bf72684983ec67943bc955582575f399fa5c4bf125b65bfb3f2603458c2a1b23925193f6b322a30bf8a566c43032e722961a09386aa2459c249415cc675e27722fe83d53785e2d817391485c7a14c402879a84741b03a87818295dfce827926b34cf045385f26ea08923b7462c5fcb7348bc4a2c207c5d28ce8d71b77d998fda190c41db9ea45351e35c5a4ab51d42702856e8cb07839b89a22c851654ae0cabb3ca66fd0007942789b43061382079bf9b32d3c07d1d903089a78c542113cf086e7d1319fd37b282974db3c41b08e1899fca1ab7f6358ad204a0b937a9d91266da6ed5552baa2535c2ec0efaa9a606dbcc8ce013c1123aceb73809761b0b7523f8981416f819d0803453b58c2bd294ab55b3abd7873371831845a8f4449b798ca3d18a5a4f183b4b16c870f21d36f00d6552907c11c76c547b10c27913d9a39e6340b8d4775a919868689c19e6cc7659c5263529e3f840c0182db1698fb43663e4545b9695889924b5d27a41d014cf8150bb46a59ed6c3890e087b2cb043de68cc98288a1f2bbeebd4ad7bd0880f86cb7093407f393c6af5579adac1f5a35bf08c07a12810b8d28298383ae6a298398b022ad50be3408ca5d11adc6510d1e561eae2b62fe5968e2c826c99a7d9bcad1092a559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_private_key = 7abb8c9d2275c12685be83c95670454d46c2da45a5ca2c80d033665dd6844ec49465993f8f48513cca870a2b8b80e83c8aa712ac22cd62f0912456c69950a50568ca9c1b257b761a0a452681c484af60b78f7502db391ab51a0099262ae2d65a161ba0111991b5ea15e355cdf0eb5c84c49319169badf29afe15215712299935c2f52707a7dbcf5656568c573e3dc927593bca24c1c7343c268238243018320929c469ba99a7335500032c33ea33a337abeddc3998c19b27f92f6239148a7c0eef419b44d5b2920064ebe56f629319944a11a16868b11887cea11f1d55cf8981738d281baff1877be289b4527eb8a71608b0b292301e4a170dbbc73913203f00573711746f2e021e70499d25559b8a009aef92a661794381a4abdae16ba2eb8db69b67b5a2cc058142b3b9b14272bffb6c22c33008a0d3b4d5981254e28491d81363b24d3aba3b081b9bb7d5522ceb6b77c9403acc6d10db063a68a9d49200c1d6752c36249339ba67f74f79434e75f4858b756387a9b074f32179c958490bc2e6cb10b3615059e50c143bb5d8e3c374e44051c646083c9daee1c8625cca2022511c1b490a593ab8436f76c31dfb8270720b21f360cd8c405a1185927f2a2be09cb81a2a41b4389291a56d7cc90c30699b3bf131da3636e9fc0bd4e582b6a14653d838cb2370e58402a86b65c58c9c70a3ba0bebba2da179856c92c730b4e2ecbee0169408f781b7388b15a6480a3514c0ba5cc1c2545f6547d06588305561b71a514031a5132654f980bfe9e85d5f415422e2815de7c078229740e122b876380c4a80ae6312484c2df2c0612ef55f44c9723faa06259c94947067e54cc3c4651d85bb316ff59c462a67817517004437add183381bcdc554aa820118742901da442679284e0590c4df360d45e428a0a47d397c38b45791fe63b008d2b7830b1eae24005172311736745f935a43f53ecac4411110cb7c335d98b2cd756158bb35c14514c295139c5d46aec9dc377cb0ce7f2040b0852a75fb242da10b6b2a2a152b71dc7cac18c26b2e308202b44d42f17e6261cba326252fe06c0735b647bb2857178f4476049b9483f4357ac027b219226fd5a9c2b9da1f45c9036d55411bb3c8f941b75a844baa7388ddb811abb4cb13d003aee4aeab466a592b77041bae4733b5f1cb6ce2765778b02455c5536a02a2dfa640248c6442398f48a5b8ac7b6e2630b2c1e872a3e752da777eb4607875e0c771f81ccd633961a5c9d5987dde31439dc131f536b083709f7f072dd75533f9c984f08c7fc952878f2b9720da006c3b60f5298ed3921205604fc6cb969aaa69c3f3a230b3865a84a555925c895c58fd19c3b98b7b2d2acb941a44b7e519c7d22aefcab1def18429713772285de2ca225b5489466322538bce1ed99e9dab3443e47a5ce5a9b284008865a4177666345237cb7b796b9582da027d7af4ad28f558e4d7426caa80c3a19400e286799caff5b4bfea5cc04631bf72684983ec67943bc955582575f399fa5c4bf125b65bfb3f2603458c2a1b23925193f6b322a30bf8a566c43032e722961a09386aa2459c249415cc675e27722fe83d53785e2d817391485c7a14c402879a84741b03a87818295dfce827926b34cf045385f26ea08923b7462c5fcb7348bc4a2c207c5d28ce8d71b77d998fda190c41db9ea45351e35c5a4ab51d42702856e8cb07839b89a22c851654ae0cabb3ca66fd0007942789b43061382079bf9b32d3c07d1d903089a78c542113cf086e7d1319fd37b282974db3c41b08e1899fca1ab7f6358ad204a0b937a9d91266da6ed5552baa2535c2ec0efaa9a606dbcc8ce013c1123aceb73809761b0b7523f8981416f819d0803453b58c2bd294ab55b3abd7873371831845a8f4449b798ca3d18a5a4f183b4b16c870f21d36f00d6552907c11c76c547b10c27913d9a39e6340b8d4775a919868689c19e6cc7659c5263529e3f840c0182db1698fb43663e4545b9695889924b5d27a41d014cf8150bb46a59ed6c3890e087b2cb043de68cc98288a1f2bbeebd4ad7bd0880f86cb7093407f393c6af5579adac1f5a35bf08c07a12810b8d28298383ae6a298398b022ad50be3408ca5d11adc6510d1e561eae2b62fe5968e2c826c99a7d9bcad1092a559ca57020b6c163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcacb2e9159ab5225a75d02268af2dac89a0afb33fe83a45f552e2bf542868c0683c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +expected_public_key = 88b88ddb2517569570e3b33d93928c62ab5680c31939a085255311d039144ffa338bc7633516c32144ab0a85869d0809b7ac8d4e4b6e6df00cdf36600e4308f395c1a9821a47126623827c489ab73a68104caa3f75558e596811417c966fb38ea85b703fd13004db91e1eace232664c06a8e85a35346b56a83e89aeea01cf009a02223312397185d9c801aa5672d61a56ff22b34016b7b2b1c20b7b739ca5319206b1ac42fd991c2fd959f63471431035830e122dce7cbe1c416e5a69d5a766d7959b5817177e6b29b450a7ce080969a3603b738b23916265852c837104499c8658e8cab078bbbea91b4a9e2a5394aacd8f2bf0f94107509c69bcc9b7094512f6a4fe9411b3cd77200f63087e4b205f40d9d08a6d093208bc2311a299e7c722c55f50bf01a75bff5bcf95780a4496e00431e6978a6396c1232ac08f6db5a2ee3b5cba66c67b0c431b165fe83a62e0801a3e65f8ae30b0f2477892133bf9a1d03d4a68b96b726392908da8c554b32a5c59a839661e77c6fcbe9bfad441be0bb9767a2368d216d1e136ad5b334f775c296c1bd69930dec23a72dc30ea45636bcd242d5f38b91aa23fed98d7aea5d2d173d33c034311807c480981c141821a962c92951fdd77906817f63000b966311f584b31bbc4ac3469cca648beae1b4582697acf62a832a455f169e07860eaa4856240a1e48814cc7393a2c7552b29911915250ea677a7fe3561229421bdc31c56ab2cdf41fb16040b7f83e198a581fea0753ab8d388b677e693fea102fc5e99fefa215c178ac1a178e64c4227743a98f428b80f91bd1acccf8e4c80df483c5997438748155538edfe6445c7026f7cc1fbb8016260a0d86e19338d7255d84817929a026ac9c96bb215f125997e311f0807224d12322156bb4e320404bb6ed190bb4a1871ec9b274088b0d584a9d405f0ac08114391622f893d6cb8f9a11a9e19c803c4365656129514a49de618aca46b47317785be7493218a5d6f879f121bd1a852110c5145ef7585a0179fa1c1aca7c4b42109efef4886454807bf40a06064b88b740d0fcab975b5d3df74ac7bc20f4f8265f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_private_key = c5e71ba70a7fbd9046d9657d4a704a9bfc795c663cfd48c95f398aacf1bff4b47bd2f05da81a44f4d900d8b80ba98a1049a83a477012668207ee088e2e46c384c3623a201b651c1aa9a97fe2628b0cb21a94e4ae83514f97e43b23370aeb0444f1a806ed49487096896f629a115cc1bc34a1943347fa4b4237978c50d23e57e9bac04a996480404234c398d8c9d2059278706e72244df23c20111b5f0a94aff729663046025b52ccc67813807b74db53521d64cc88ac6bf08b659a4c23fad33485c7511d6b2ae6497b7766a1ec455b217c9818ea85bbc117a385bbab3797664557ab9675c2858b8ffc46ace6a6a35c70006ca066226be1d5521fc553196271bcd80231378016e49cc2c90a90c531ac02b39e4b1754136be05bb653f3a7b17cb9d0a950b2c04f75f46c4a35ac2c2031d813ae2466149a657a5ae189bf8b898db71c51571993106daf6aa096400e78e129fde3a39c3a4a28d37650078b80a505f656aee9b2c04c942fee7542176acb9f532feec5a047c8ce2b18832f252394d73845305fe0ea9498da4517d93ecc63836f976b0979181e0c4a821a9bba5a62fb27c801da1dbafcc7d3cb5db4e8523500be1318184df976f5c842d5950a9f26015cb60b6d9368554a9c6737b47b44b736681fef583aefb2083fd98691ec4343704bf5bb4aed8c1f99e41558cc72d549c493463037b99fbf8b431233136be5166bf522a7064bac3225ad790998f79bb510c42f0726e95103656b4503fc8af37acfd471bd2314247966cd20d95383b8214e1a2b5aac7e8201312a53c663fa163167afade668f61779f9d82742e9aaa2d25a6c4c1dda295f45f33beac46502f503b99c6473a0904bc7a3fb410f1122a16d073f2535b991729bd29159865b592194bb3855ab2899c7cd2a477c0ac24ce6642004b34dc26173d11b4eda8ea0a60fce857a9f7875b1f0574535a605b5344160c813ea068fdccbd2839441d80a16acb5733c2625739db723a71ef0a8138761b81a7cbbeb679d2406f50557945a12e099466ce4619067a61afc113978aed60025b2bb855159a774984f02e92875846bc60b5b88b88ddb2517569570e3b33d93928c62ab5680c31939a085255311d039144ffa338bc7633516c32144ab0a85869d0809b7ac8d4e4b6e6df00cdf36600e4308f395c1a9821a47126623827c489ab73a68104caa3f75558e596811417c966fb38ea85b703fd13004db91e1eace232664c06a8e85a35346b56a83e89aeea01cf009a02223312397185d9c801aa5672d61a56ff22b34016b7b2b1c20b7b739ca5319206b1ac42fd991c2fd959f63471431035830e122dce7cbe1c416e5a69d5a766d7959b5817177e6b29b450a7ce080969a3603b738b23916265852c837104499c8658e8cab078bbbea91b4a9e2a5394aacd8f2bf0f94107509c69bcc9b7094512f6a4fe9411b3cd77200f63087e4b205f40d9d08a6d093208bc2311a299e7c722c55f50bf01a75bff5bcf95780a4496e00431e6978a6396c1232ac08f6db5a2ee3b5cba66c67b0c431b165fe83a62e0801a3e65f8ae30b0f2477892133bf9a1d03d4a68b96b726392908da8c554b32a5c59a839661e77c6fcbe9bfad441be0bb9767a2368d216d1e136ad5b334f775c296c1bd69930dec23a72dc30ea45636bcd242d5f38b91aa23fed98d7aea5d2d173d33c034311807c480981c141821a962c92951fdd77906817f63000b966311f584b31bbc4ac3469cca648beae1b4582697acf62a832a455f169e07860eaa4856240a1e48814cc7393a2c7552b29911915250ea677a7fe3561229421bdc31c56ab2cdf41fb16040b7f83e198a581fea0753ab8d388b677e693fea102fc5e99fefa215c178ac1a178e64c4227743a98f428b80f91bd1acccf8e4c80df483c5997438748155538edfe6445c7026f7cc1fbb8016260a0d86e19338d7255d84817929a026ac9c96bb215f125997e311f0807224d12322156bb4e320404bb6ed190bb4a1871ec9b274088b0d584a9d405f0ac08114391622f893d6cb8f9a11a9e19c803c4365656129514a49de618aca46b47317785be7493218a5d6f879f121bd1a852110c5145ef7585a0179fa1c1aca7c4b42109efef4886454807bf40a06064b88b740d0fcab975b5d3df74ac7bc20f4f8265f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c597f8d36076b3a8aa13b633650726f7e907806a0573402ef3af129f611def1a813e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = 690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +expected_public_key = 5900914fc65434ab614df28f12e7206f50784d52417763b09de06a433b1665ca88c8e303129901536b1c99d284f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb0108323f8224d5b6936a2a0ecfc0874d6139a9c300d2505a2d10d926b05cbe404e5e764a1b353bd5c34d86a1ee2230387857f97d0ca13382f2ffc8ffb23933803c52af449c29042c4ccc7d06a2c3272786be7cd4642588d90ba7599024428c055c2ad6232c02a83a27fa7150c1c503dc421410ac376056933d3305f76bdd399851e8952c110693b99ba35dc3a337b9bf6cbc370c6a69f593add08149d88606931b363a470b2e16b3f688ab1f1478b2b9255942b86718082a2663f7939e893a5dce006da504f38e98c4ccc36432a491ce18217932dee5070ea27779697274457bb6930b4cb34297eb39c01923cae32835aa7803722908e9b3c6b488a7f46676b1c4b4218720423a809116a41e59577c8c89afa582a8a8b2bda1009bc8b48e58d08a1b418f954460b8ebde004870bd0b7e082d3c7af5ddb4980c2acb9510a12352312991368295adc166bdf522ad76a59ffc974e4cb04ff8034896bc40a8ca508300e411732d8e729b78006d69482e1704ee70c4e8576c003964f6ce60bf7d5a2029c03a8b778b65556a70c617790c2541a9a8f37b23096401b984c99e7459dc38436d210e7186bc7f070ce1574a8c17298a82557612c19940cc1056b92b2b13a8a2f93e83d635190ac1c5e093891aa3cc6d9a98c5b30793fab0aec423b09ba6dbff15d5e8522f86aa877000ddf9752f17b082768929ad7ae1122c2da818db93c52a1d921c7ba26fb857d3ef1c11d925635f050b4a89a59262438a7a7eaf30fd5bacaf319ce957b42ba7a1de408346e393d231ccd545081ed338250661a65eb45d5c05c5ee73c99538a7bd4c65442a14759188037670746906b35484fd01b89526dbc94123975087402b558d3c611040c65a9a2cc4c38f4a871b1a764a170b85b5c12cca551e6e466c8889798fa0359149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a72241af2b01254922a708038e5c5658e2ba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_private_key = 4dda3333b34f27f44bf9813dc1db6cf44514b2eba571b3208f1209bf2740d3177d9bc40cfd381bc045a6e371707342271cf861e5f8948e2543ce5c72c377b80c96616a677b2ec143f035a51f0188a5a44f0d5798b3d9ae1e4b381e038dbd854eebb768b6cb1303d88297576575a5814cdb58f91ac9b9ec539fc212ad3ac108108eef061afe15b4b751057faccccfc3291d002ff4ea758e9c4781436967881d3969ccabe13789d65928ea3ca697a3e0e4499c0168f9599ae8447ee892094cb376d008979441634dd9475bbc3aad9a54ef37a576e551455196e627107aaba907eb57ed2a38a5db61881b99c5e3bd0ec9205ae363a40473f2e83face2bf613b3e87da3186a2c60571bc36dc4d1be99e8c42ba13745f180833880042bea83915733038ab250fcc32dec0c7b531bd6720a94e3c9dd784984f49cd19c14e74849f3c157b1f708160e4365a816936fc665682796406ab1e213dda2130be82cdb83569d6739fc7405090193a63cb0f31c3a76500a9f1c31663643dd55050ef1b7163768dbc35cc4de9adf01094bbc44556f681cd83bd1b44c02a90323832b8f6d3cb6f706b16373ee00762089b85bcca993f703b1f4833a45497de593794b700c24cada428c9a82627b5f5663f08a440a473d5312ece374914376749c1c71e1b8a17315432707d6db0c4560921989c95d414c9ac2a28e3f226bcb608fd69ccdc5a587291b132e4597184871b8885b22700c1f1780ccc5c27469ee9d811ce1a0880573b7fd392b19374e74ab457d8b1ddf5680852067e02838450209ce87e8fe14b4c068c51e526f7e31cfdd7b10a642c37536926ea6464d0548876610ad3ab54e6a6cdb60d8f4727b3947f03bc8a06897ae8901f686b7b7f96a1318c2ae42bb73c393053343e18f7ccda60bf2f5275c7259b8a6a77b9c9989fac317d9230cce67f14c5121e91a61e9306de506989e96d3be6aa5a7c6198912ba89457b97023872358a7b21bf2198cca4653fe125188218236454dc0174dbba7a462657c56507cc0f02309a6477e0ba6592bcd48c26c414c776cc126a346529ca972c3f272755612c12b185900914fc65434ab614df28f12e7206f50784d52417763b09de06a433b1665ca88c8e303129901536b1c99d284f26954dffc9a27cc773c365f42a3440f244012cb76761c7fb0108323f8224d5b6936a2a0ecfc0874d6139a9c300d2505a2d10d926b05cbe404e5e764a1b353bd5c34d86a1ee2230387857f97d0ca13382f2ffc8ffb23933803c52af449c29042c4ccc7d06a2c3272786be7cd4642588d90ba7599024428c055c2ad6232c02a83a27fa7150c1c503dc421410ac376056933d3305f76bdd399851e8952c110693b99ba35dc3a337b9bf6cbc370c6a69f593add08149d88606931b363a470b2e16b3f688ab1f1478b2b9255942b86718082a2663f7939e893a5dce006da504f38e98c4ccc36432a491ce18217932dee5070ea27779697274457bb6930b4cb34297eb39c01923cae32835aa7803722908e9b3c6b488a7f46676b1c4b4218720423a809116a41e59577c8c89afa582a8a8b2bda1009bc8b48e58d08a1b418f954460b8ebde004870bd0b7e082d3c7af5ddb4980c2acb9510a12352312991368295adc166bdf522ad76a59ffc974e4cb04ff8034896bc40a8ca508300e411732d8e729b78006d69482e1704ee70c4e8576c003964f6ce60bf7d5a2029c03a8b778b65556a70c617790c2541a9a8f37b23096401b984c99e7459dc38436d210e7186bc7f070ce1574a8c17298a82557612c19940cc1056b92b2b13a8a2f93e83d635190ac1c5e093891aa3cc6d9a98c5b30793fab0aec423b09ba6dbff15d5e8522f86aa877000ddf9752f17b082768929ad7ae1122c2da818db93c52a1d921c7ba26fb857d3ef1c11d925635f050b4a89a59262438a7a7eaf30fd5bacaf319ce957b42ba7a1de408346e393d231ccd545081ed338250661a65eb45d5c05c5ee73c99538a7bd4c65442a14759188037670746906b35484fd01b89526dbc94123975087402b558d3c611040c65a9a2cc4c38f4a871b1a764a170b85b5c12cca551e6e466c8889798fa0359149de8d885d11a3c94ca410cb9c91567750df354c055c0e76934a72241af2b01254922a708038e5c5658e2ba10d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0ff2044ee6a3bfd4f7033dc4bbd6283b534cd3fbbf1c4af072fea1ba37d3262d581c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +expected_public_key = 3629b44f771560c15223c88cf70005d91365e13c0040a79377468104752a66c4aa268aaeca53817a449353d27c75387d2a14242331bb16ecb8e7810d76801bdd3122ef9c6407439e5de3cba26a91e6c314a9fc543ac7cb37fac5f4d24ada0067cf3c97bb195834b635c9b099992c3657d55573160e26874fcab1a8febba997e22843ab7a7adc3106897e2e9215351014b2dba6f68074770b5afcf4b5bc9abd72c97c03e703ef473ef58bc8ca8a6ff0fca028590e2a44a85013415b5c03f3a301ac06bf3d95691664c9d0c76d60015b0398aa44f778473c09746b50d770331c011aa51b1379530daf2ca17fc5bcaf06c59e792f0b117fa2755e1f371edbd17b584ab5b5a7c0c7ac0dd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b063160ec596b9fab9953124eeea8484ab8441a0b2a85b481858a2817e04c9e821a703bc9e55c28643a04e4b431acd7c9e54368e7e361b1f23041439f0d24760827971cd52328793e029b634e792c96fc437d396eb61a08422279e853bc2501bd6cdbccf16958bf4bc133438280e8b28f494a83f61f365646b22cb238eaa2554250aa27202743bfe6f4a26fb2234aa80bd7142caf7646a5874bbfb0900f7016ca225a7f016bc015c9401a87ff339def0bcc7e95197ff4be1728ce9fc4986b58bf933b2d2ac703ac0823ae701e3b5717f74583c5aa5156b744abe535a9dc1cd42873a44c3acc9080aee873fa975fe78547bad901c929c008bb6e9ba24af9d285e7c139a54c72ad525e92384d7d650fcc40686404a8c931410e3c92daf8ab090b5fe48c2435ec7a8f21295c2473eae893c6c46b5e35868a91c962d15b4565461f067ae0036cad3bcfb3b23182fca257e7516fa25e00056144768311144fbf526e43b0a9ef797eb07346d78165e71a8c426abf868a5c251caad2c4a038529211c6a3937098a48b7dfa9322d30723c460cf2eecb0c4b752cf310323caa7ef39779c7754574c6a06a2b9a0a45e35d3732d490541fa7ed66ac5d5b007fc1390b1591a0f19a4dd9c8fb0d91275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_private_key = 51d2207e7c29bd90868c00ccf1cc9179e99895d90674571cced7860962cb546069faf329fbd778e7f95baaf5a92dd8ab57321dff0bab97542ec5c408aca59c31882b16f3139e60bbad6c5c67c75b3ee62c22002093a16bfe30a0694046a319a08867225b3766a81231ca95bb1adb6086e57b3ce5a47979b8cbf690dd79296f1c4b77c98268c68dcfaab8ba3509c7d1c419b56187c447b65866e0a7106e33cc3f3a36c8381baaf343c1c9085f7c893531a56d47403fa447a34b4eac391b2d2a15c7f051720aae6d4a66221159cb4b0f32508ff5b8a1af3c08622a7a799622c35164f0a8c0a6b37e869a60eb454cc6db072377064c0ba2ba48315cc76d884aa9d7b6165d0b945f82bcc09c65d6b85315935d98954915e127d726aafc7c7c9db82cb16a7580a6aca450b619d2a983052407ab554c3acc0451c5d008098d53a7e07677fdb65a3eb1b51d74a4f863507bf513e55823ddf927d55218f4390c3a672a37a1385cd43654d28bead7bd93a764c99198cb940079e40031a36029ec42a6863c66836bbf15a29ec5b7b1c1032e90bb5114b2b91a4e50a7a193e80d05cba17d5b04a6d82b0b2186f4402ed49c322356c43af162896b04d846a64a6718f2ab8dfcdb516d354bebc75ef403b049c1829bf7643dc62ac426ce1346220df94f5795684e81bbb8854ccb19b6044253b9ba7ddddb1123c83ff575b2f66902baa287b54b9daa8a4917b248ec139653ca970bd936b5aa51e70163825ccbee184d2fc22078253070591c75e67651b1286d755233e715e4b85f0f4067b4b43360e37cd76ac14ec203b2a853eea82f9baa3e12c52463a78e4f59293279bd1b1c5e35f1275d53bba00b0e8acccc373b2465c9ca2b039586f4b43e47acaa991b6cd26b998aad77f54a6952b67c7a318fa9b6b3499ca8517a635a7e88a75a111b0d78720e98654dd9302ede58621aa97b941a52b395b91537a8ba246b342680b5890b1f911f9e3b360d1241666203dca693d6eaad08b782da628377420d0091af7f4027bb4b920e345e9fc5c26732580fe63a745ba6461ab376013a4855a088404c998038dc3a093629b44f771560c15223c88cf70005d91365e13c0040a79377468104752a66c4aa268aaeca53817a449353d27c75387d2a14242331bb16ecb8e7810d76801bdd3122ef9c6407439e5de3cba26a91e6c314a9fc543ac7cb37fac5f4d24ada0067cf3c97bb195834b635c9b099992c3657d55573160e26874fcab1a8febba997e22843ab7a7adc3106897e2e9215351014b2dba6f68074770b5afcf4b5bc9abd72c97c03e703ef473ef58bc8ca8a6ff0fca028590e2a44a85013415b5c03f3a301ac06bf3d95691664c9d0c76d60015b0398aa44f778473c09746b50d770331c011aa51b1379530daf2ca17fc5bcaf06c59e792f0b117fa2755e1f371edbd17b584ab5b5a7c0c7ac0dd337562279c960a48a8cc63e53a992f516886bea8e107588df24c96098535298695c46c5e0a8c5ca4476ea43abac794b063160ec596b9fab9953124eeea8484ab8441a0b2a85b481858a2817e04c9e821a703bc9e55c28643a04e4b431acd7c9e54368e7e361b1f23041439f0d24760827971cd52328793e029b634e792c96fc437d396eb61a08422279e853bc2501bd6cdbccf16958bf4bc133438280e8b28f494a83f61f365646b22cb238eaa2554250aa27202743bfe6f4a26fb2234aa80bd7142caf7646a5874bbfb0900f7016ca225a7f016bc015c9401a87ff339def0bcc7e95197ff4be1728ce9fc4986b58bf933b2d2ac703ac0823ae701e3b5717f74583c5aa5156b744abe535a9dc1cd42873a44c3acc9080aee873fa975fe78547bad901c929c008bb6e9ba24af9d285e7c139a54c72ad525e92384d7d650fcc40686404a8c931410e3c92daf8ab090b5fe48c2435ec7a8f21295c2473eae893c6c46b5e35868a91c962d15b4565461f067ae0036cad3bcfb3b23182fca257e7516fa25e00056144768311144fbf526e43b0a9ef797eb07346d78165e71a8c426abf868a5c251caad2c4a038529211c6a3937098a48b7dfa9322d30723c460cf2eecb0c4b752cf310323caa7ef39779c7754574c6a06a2b9a0a45e35d3732d490541fa7ed66ac5d5b007fc1390b1591a0f19a4dd9c8fb0d91275f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568c7ca6ebbe17f30f8ce49e15c40c1ea5456f43624148eaecc9f3018f7beb96bdfc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +expected_public_key = be37c2c02582a708d02feb86759511c62580d99a5121ca60d7002246176ee5534c1261b86e831297a95ed8aa7732b58f0975c4445bb00db116ef36cee951006ac2709551872a84ac9b6a2b97b7a4e15011335777687749e7ca1319683840c017a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59da62cad366cf25351525536dc58cb622ab259cb3a6707d0abb088ac242338424baed40c182b15a9144dcce03456281ed2b9006915297fdb96e9c34efb551369ca9cb0012ce2c9af9cf90f2f616468abbb89b7acb5d18ee17a022a98b1fe2c2e8b4b1a2d4b3054d19162a243d4f0837e697f548164caf878366b26772351d28a025b227bd1c135922a43fefb55e3c37231fb188a37a6053a8a0ca88502d82a56f716313a5861f001c28678b23c7f66828dbc492fce22cf1d300bb3c576a1c01f13b962dd1b1c2364900f4a0db48a14cd103a7a5b535da93df79371c832b3e188bd0845ca95044002fa0c4bc92932e95180772ddb860b80063799b614fae43901d7cff686c8a5d05cc5589df1c7841d0312ad4261c8d81ed48b4ac513a88df3071d047d3380465f4a3a4fa894f6757be0f99e124150852cb56a483cee8c4f3f052c7489956f167e529a9c3dfc8256f764c78a4b58596e6cd0ba1c2c0e5aba3dcf5c46a533647195a682092dbdf61fc497a25e8b9c8770bcbca6c154629596f41c19879626392be7715a36570985ba46db7670d257566844a228db612fe32386590322b4a864a6c537452a9de020d2727dd1a0b066b0cb9d7144033765db050c0c363e926107f06b94fa70813c3c8dca862b98a4197be6b9f230a4931b659608ba32936da1904713c043718a8ae08419d0e34b26c6675b45451b392ac717a0e8f5245f035f65cb842ea68c7b2425b2550f12732402d852f5b7305975b588427d3de1b48c9783b19c7b1e486a47414a76449c26f3ab37f275f80413ab159765797d5cc653f2b4542f4027c199752530b6f7b49477ac60791706a4f7610138c8b3614950c06072ac49b6a25b464374a4d2c31483b34f83792db87d868a167aa08f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_private_key = 57eb9e1e877cbac8750e89257973465fc92528081bced98496d43331eab13c71848f76542f873121412e5b372c6b8613c303a9389ac2e3eaa125bcb1e1c6b84742a7c5245faf8c01a2a826803a43b1f82a568574aab051fc1067191a36ea724b991b1eab28b08bbaa79ad243dca24c8270655794b6354381ea57745c858468161b312abd8e28018ab6007e9bba3c458ff0e2b94b48bc04bc8dede533c8098b6a95204f28944fb55adad3084b78096df75a5ec44736520a92fc2444e3a5c4a69727e84ffdc8b33b6385fa42368df31edcf57a5601565ff82f0f6a342fa310c9c022a6d3a6e3d870f5e5b6977579fda405c495ba300279ab26897022680d8b16d196cea4ab53c221947a527126e8222feba42f0221cb690d5ed74057911acb25696aea2339213993010cb54ba78c4c4ac3a38240c19169c78bfb349623d067613b94c283856f942b36772c211a19457b890d90cef1586581853c98040e50fac9f89934a7917deed286fd7408011381795532515742a8d2902d2663b9e821b5f20f44a385994588f7f0c3ea6c4728fa1b63a5045d91bfa8e9786d86acb6b32c31c83ca0086978a3756f23bd5d411b9dea6a19a760c1ca24594c1890837b71609933534dfc986b56d05a04e1bdc101a125ec48732136941766b0b13e4d48638dd52bb9098cb711c3d257c560b829532581d153811e4bbfb59cc89ab062b3ca6c1d27bb47a933c1f3ad5aa398bfbb02bf8b3e83094da5c4332229a06a961d28e298e6095a27c078081265f3d2955eacc0459330bf5012fb157d6eac4d50f17946d38611d8bbf7ac3dcfaa6ad1086f5a30728ee53a07602d1248576e2c6f8c14c562f8be9b84a3867793f80a36d6dc37c1d670f747c1b120b5e53505ba52c3d765b4f8a9a7346a417c466c9c8102e43b2d7bd410ecf76f15fc4581f7008aaca8f855ad98213d50d06141394fedd78fbc0a44cf7403eee35cae02125ba15ffd656238d365fac18c1cf81bb91609c6941a1fb196942b13362ac71d782fb194bbf9715538abca8415a4e1dcc621f92494780ceff619315571fe054a4ff2578ad167ea3187be37c2c02582a708d02feb86759511c62580d99a5121ca60d7002246176ee5534c1261b86e831297a95ed8aa7732b58f0975c4445bb00db116ef36cee951006ac2709551872a84ac9b6a2b97b7a4e15011335777687749e7ca1319683840c017a3277cfa13c73ccc3a62b7afee998d872c58d22482008aa0faf7ba9b6cc59da62cad366cf25351525536dc58cb622ab259cb3a6707d0abb088ac242338424baed40c182b15a9144dcce03456281ed2b9006915297fdb96e9c34efb551369ca9cb0012ce2c9af9cf90f2f616468abbb89b7acb5d18ee17a022a98b1fe2c2e8b4b1a2d4b3054d19162a243d4f0837e697f548164caf878366b26772351d28a025b227bd1c135922a43fefb55e3c37231fb188a37a6053a8a0ca88502d82a56f716313a5861f001c28678b23c7f66828dbc492fce22cf1d300bb3c576a1c01f13b962dd1b1c2364900f4a0db48a14cd103a7a5b535da93df79371c832b3e188bd0845ca95044002fa0c4bc92932e95180772ddb860b80063799b614fae43901d7cff686c8a5d05cc5589df1c7841d0312ad4261c8d81ed48b4ac513a88df3071d047d3380465f4a3a4fa894f6757be0f99e124150852cb56a483cee8c4f3f052c7489956f167e529a9c3dfc8256f764c78a4b58596e6cd0ba1c2c0e5aba3dcf5c46a533647195a682092dbdf61fc497a25e8b9c8770bcbca6c154629596f41c19879626392be7715a36570985ba46db7670d257566844a228db612fe32386590322b4a864a6c537452a9de020d2727dd1a0b066b0cb9d7144033765db050c0c363e926107f06b94fa70813c3c8dca862b98a4197be6b9f230a4931b659608ba32936da1904713c043718a8ae08419d0e34b26c6675b45451b392ac717a0e8f5245f035f65cb842ea68c7b2425b2550f12732402d852f5b7305975b588427d3de1b48c9783b19c7b1e486a47414a76449c26f3ab37f275f80413ab159765797d5cc653f2b4542f4027c199752530b6f7b49477ac60791706a4f7610138c8b3614950c06072ac49b6a25b464374a4d2c31483b34f83792db87d868a167aa08f8b2394ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e161fb6cfc0f388e34fb28ed783c2733453005eea03d3fee4b01bb6364abc01c304f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = 527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +expected_public_key = 4611b241fabba8f6435b0b4889a9403e60524f820cd8d875926a2d68b33c3134c90e9230b43cc743921623eb484f7c65a741a8c30cbde4fc74a55305ef8588db967ce70b29049a8e5c821b484390a01761f4850bbc916af732afe9a211419944e6c7457207ccd12aac09c421bc0a4225f84727424b306549738b91eda3a818e994cbc763c176795c1286019183ca6b2e2d3c8ee925937c5a9ad62306694724e0b62b68369a204b0d0d1b74ad9ab5158356035045416a8eb48483f11ba52ecb1e77babb800bcd67245932a237f237410730114ba4241a295ace13ae201b776c29613fa04a82050bc4514e8c532a0848a75fac67177844bda15368f1756bd4804b28bb55bb2e6c610f5e0ab9df749857405dad47c8b16b8063533b1e1c57d4db06f8e6643216cc342b053e3861cb1c71f2f9b52518457056676064abcd0041f1011b1ad3cb297a96200a96d6a30d2960161008cc7d26c1c011a00f857739e223ebd536c61748a1a9c792dcc7351210c8dc6c3e122ad7d9407975a75c3286f0ac032e5a655637c5b6a043aa840905d9623a077489e8cafa1285ea271c25f12cceb3664e3975f0eb6b25a04f18e4537ebb3f27405398d34718304e2a7265268367312aba5c069b765361d907775b3041b391668da99968c198e116530143c781160b80fb5d4b473cb7f60bbad1b83a3c8a80d93ee4e61dd546c5e06a67dbb6c94fe82d7e1b963e744984b849864a22d535cba8408bdab3854be3694515af4a58a4c6c0204f110ade12c0811036f9171635c00af6a29652914ff0cc23e0e67e84072bb1b3a027591ba96959ef3373a3912e1d43ad63449ec2f47de225767b94417a0b918bd83abf4439ead3090ee872f6c0c5967564da6c4a3ad061db656f3b8caf970a690422b914c599fd606eb1a17a3a220a1d86b8ba7343e1048c1d4328aeb57214e077246b7421091821c6299a4b75fb1b9fa124c7f5b3b1f8938ce9dc7551d25898387f5a86bc9a1c49fc8a7c5902b8e2912405a592a8221816570362c43589aa9eef609b0207c9e1f3b564aa6be9a60aad4193001ac4f6756570d983c8982cb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_private_key = 2a541ba3859e76c09675f97ec24138b384583a33c30fcaa3d7b1847788c04ef7113cf63d602740b90c19ded0975e4c470d660fddf9bcb210298bf18bde0569eb24abdf3796d107288e2748c1986d2684a4e4396da599992f63b895134eb331ad1b010569d02c113bab4e1ac1ca15362f2c7586546b4af6b2a3281bd691316ec4c31f06557fc387fd3446df00a73af0264fdbc51ee6616d54c4b29b1b80e44eb90b7727e7136a6cbb4e34ca49e49dbaa3ba3a71342f52ca0fe1332f87b2f1486c6aeca774647c31b00f387224319768fbe96c94f1887c3946d73cbbba863adec9b6f798bd7007a061692e79b734a1a69aa6ea4cd133a78da739b4e376d9750501e538477a6968f944c5d354a26b789ab90c63250530978be6cbc85830715a9b4837690bbf67b89150b8bab2459c3bb82ec97175a459a7eb645bac79a0f4087240551c493849322aa0a3a25c3087c5d667ffea5dd19197c6f3cb5ff4a9dcd61833783f2da504a8fcb58e35b8dc1b26770b7c3d211cf3a9b979d8b1d3746250a74aaf23aa62b6c9acbba545a0ccbe0a1316d5a86ce931fc9a31be4a764c0807928959f2ecc7427b6f344812ffa994748797284b25a26936cda35af397104e235b36b71b5fd9a5072b415d818a250800df540ddf164257882a4126aea50739f4957c823a3caa026182b415ae54c40c8998417131b3924af587022659accb85409c6a8cb9c4a32f372ce061437671b9d56a7e04b1a5dbcb1c0d53960c564096d4777f9a56e47197d1d9c7e144929cb38290066e39a3c25ef866014cabd01852a09168df1a59fce8bed6382d91ecbe6c38979b5b1617e58bf6a05f3318a64df6a5a7a97cab71ccf7069f1dc7ada344006c604633ab3b542b6acd9bbe19fa027c81725f2c4837109bc4887d2d669fcdda0ea6722cca228561477d9a456975e1ae62a25967419eebc55e60203d9cc7b17c51a668a544805aa5470b1e84651215e3bb58447583b5942498c0483a3ca405cd71958c1208a3bd306ca71695d8290cf378a91ae601dbd8cbe6938042a5c886ca27f1eb9b9e3c246383a9a3509ad04bc66089a04611b241fabba8f6435b0b4889a9403e60524f820cd8d875926a2d68b33c3134c90e9230b43cc743921623eb484f7c65a741a8c30cbde4fc74a55305ef8588db967ce70b29049a8e5c821b484390a01761f4850bbc916af732afe9a211419944e6c7457207ccd12aac09c421bc0a4225f84727424b306549738b91eda3a818e994cbc763c176795c1286019183ca6b2e2d3c8ee925937c5a9ad62306694724e0b62b68369a204b0d0d1b74ad9ab5158356035045416a8eb48483f11ba52ecb1e77babb800bcd67245932a237f237410730114ba4241a295ace13ae201b776c29613fa04a82050bc4514e8c532a0848a75fac67177844bda15368f1756bd4804b28bb55bb2e6c610f5e0ab9df749857405dad47c8b16b8063533b1e1c57d4db06f8e6643216cc342b053e3861cb1c71f2f9b52518457056676064abcd0041f1011b1ad3cb297a96200a96d6a30d2960161008cc7d26c1c011a00f857739e223ebd536c61748a1a9c792dcc7351210c8dc6c3e122ad7d9407975a75c3286f0ac032e5a655637c5b6a043aa840905d9623a077489e8cafa1285ea271c25f12cceb3664e3975f0eb6b25a04f18e4537ebb3f27405398d34718304e2a7265268367312aba5c069b765361d907775b3041b391668da99968c198e116530143c781160b80fb5d4b473cb7f60bbad1b83a3c8a80d93ee4e61dd546c5e06a67dbb6c94fe82d7e1b963e744984b849864a22d535cba8408bdab3854be3694515af4a58a4c6c0204f110ade12c0811036f9171635c00af6a29652914ff0cc23e0e67e84072bb1b3a027591ba96959ef3373a3912e1d43ad63449ec2f47de225767b94417a0b918bd83abf4439ead3090ee872f6c0c5967564da6c4a3ad061db656f3b8caf970a690422b914c599fd606eb1a17a3a220a1d86b8ba7343e1048c1d4328aeb57214e077246b7421091821c6299a4b75fb1b9fa124c7f5b3b1f8938ce9dc7551d25898387f5a86bc9a1c49fc8a7c5902b8e2912405a592a8221816570362c43589aa9eef609b0207c9e1f3b564aa6be9a60aad4193001ac4f6756570d983c8982cb3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b29333445958cf50f9cfba453f058f562158bc253e535e4e2f07715531a1c6289ee32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +expected_public_key = 69a047a0a46968f3828fa4314fac3f911a71a10c866e7c035fe4cf00a92ba9471a735b808117722378a879702d59728d66f35d53c34bf5797c2ff9a2f55a0b2cc873d8063a8ce7914eec935f55174cbb542702b1e7736f50215f7a1277968c2d35c711653a8e4af95115c9ae33d0349d4a09504a10cd48c77b411cf079a497a5785e39830cc8a189b9bb56891249d976991b23a4a7a1aff34f3788b148166c40f381bc5704058339bde0c192d307515a6a8fc5747a1058e394cdb79c4142fa5ccf3780f254a10c671543b63bd7d192913480c77517512c0e49ec3fb8d03ffc793e7cc01125226fc4929c8c1c2aadf12b452746306c2a9c36392b23045888c2f4170b5eea07aed4515a819d7c5749b35380cefc976c87270a1237d6f4ac214548268a6da75928e0734eea7887aac0a2bf623e17852501556b03c662e4e9c42b914923b88d502714fe53373904b91598c8d7c6b022e5367a90173fa511005039d9ca5c3cb2bd5ed1404f7373654848ec436115339db37cb3549ba77237c243f25da96a4bb4a8b88e441693f6a80840b0ef7538f8fa9b71ca736d08bd3678c4ff8c480b115452c9c8fcd52529b1481e82236e5a311a204bb571a89b0a60738101b4617b033ba2df6c7967cb7b7f218aff886edaf2464b2a12bf244bab812731f46200ec6e94d24548650e1e1572e4a78157e2ca569c3b1472cd8fe98458c1a5ab8340f3a90e5a854ece60469698cf85d88739cc96adf7048cc584637a408acb79980a8dc119049135795245748683ac8f53b815e29ddcf5452a9504e0fa1de9840e4d489810c35a100687bac18e185bb53d499d266a8758c68782778b533bb9e5b16ea833309a0c8b3e640a2c417ad23b01e27220a7e9cf9bb91bd6eba10c08acff499295e0ac4f61b9e85ca75185af845c4f4330652ef024869ca7d3d33cc188a65cf17aa645b8d9b010f379198e31b7ae448082069b33ab6ff3a235ccac081814b6e063686707721f6006eabc91a4999915661427c85979b93ddfc14e24176e9c0359839a1c16f91afef473652480d4a2261abbb7fcb031de8993a57600220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_private_key = 79888a9bfccca036909f99bea673c23173c15865c07460cd894c115fa1b673a8c2f60b5a99e3746be64b2ab5a7d7d980ef78131a5c9839714692649458667cb70361faf61a5fcb967f235b80858cfee9b9b2aac5d32202e6c881a150c38fe9c8fc51ad32f57ee2f140f34abd1cd586c754af25e23c60289302b95bb9ab1a90f59ef045ae45698fd57acd202bcbb8b960fdaaa6f9994e4f201e6d024874a68e3618245e993d035c50834062fa16b734ea4e6351cff4b77c4d2724af1b6ac8391736b23bd5caa94e61400877266b266d206b39c8c7563e86633fc90fbad12141715226c071042b1efd61cdc7e32f89e750dd24314f7c594652b9e45c4bc07b6fff66b5344b0548eaa81f189a6fb656ebfa3d46c4c5453b7f183a335a765a58f647f8735900e2159733b01a84789d162966a15134831d9223cd10a7039286703c85c3aae57175314a6a9c83e869aa0f3a77c400c1b705768d31826030391e0c82b7b4694be10f6c902b74d8a1730006534b44f3128cb42322ddf32f5d6b6f1e4524e867383dc52e554122dc0c3042459f14f88bcdcb7f133b8782728635339c5bc2b8cc2366d4ab11049cc96af69b686884694a968cb84573d56f2fe6b71df18d999436171a2c45c88fc4a0983333432e33bfcd1600673078ed512f12804d691c50ca935b5281b809d934ed3a41b41282c4b483d4d1c9487509f120246fe98cb408afe5c2714d57a41b95791164b406e85e9dac5494016b2f4bcf197419740a3b3aa5025436b0c46b7d5a4360cf972c7e9b8f32560747168d0b7818f72b22629074dbb79af74b91f4970844862c30dacad02455e5a512fb82cbf67ca4400ad038d8a867005724e2c8c2727dd0da6b696828f741804d27956f3c3c67508e4be740be8c63b8858af9f74fa19c7333fcb49d4667c9dca264aa5d78cc9f7df99bd6c063493759df3a6fdbe2b5e241a5f98c4ecf78b83be48d55c81e8de43b210378d4f2503de05c2d76b01c3821e0006c2a5542a5027898284709149a58c3b5b3d4b761e73ddd892262d9c80584967c047fe89a409ef879427164ed5708a0150e30d0ae69a047a0a46968f3828fa4314fac3f911a71a10c866e7c035fe4cf00a92ba9471a735b808117722378a879702d59728d66f35d53c34bf5797c2ff9a2f55a0b2cc873d8063a8ce7914eec935f55174cbb542702b1e7736f50215f7a1277968c2d35c711653a8e4af95115c9ae33d0349d4a09504a10cd48c77b411cf079a497a5785e39830cc8a189b9bb56891249d976991b23a4a7a1aff34f3788b148166c40f381bc5704058339bde0c192d307515a6a8fc5747a1058e394cdb79c4142fa5ccf3780f254a10c671543b63bd7d192913480c77517512c0e49ec3fb8d03ffc793e7cc01125226fc4929c8c1c2aadf12b452746306c2a9c36392b23045888c2f4170b5eea07aed4515a819d7c5749b35380cefc976c87270a1237d6f4ac214548268a6da75928e0734eea7887aac0a2bf623e17852501556b03c662e4e9c42b914923b88d502714fe53373904b91598c8d7c6b022e5367a90173fa511005039d9ca5c3cb2bd5ed1404f7373654848ec436115339db37cb3549ba77237c243f25da96a4bb4a8b88e441693f6a80840b0ef7538f8fa9b71ca736d08bd3678c4ff8c480b115452c9c8fcd52529b1481e82236e5a311a204bb571a89b0a60738101b4617b033ba2df6c7967cb7b7f218aff886edaf2464b2a12bf244bab812731f46200ec6e94d24548650e1e1572e4a78157e2ca569c3b1472cd8fe98458c1a5ab8340f3a90e5a854ece60469698cf85d88739cc96adf7048cc584637a408acb79980a8dc119049135795245748683ac8f53b815e29ddcf5452a9504e0fa1de9840e4d489810c35a100687bac18e185bb53d499d266a8758c68782778b533bb9e5b16ea833309a0c8b3e640a2c417ad23b01e27220a7e9cf9bb91bd6eba10c08acff499295e0ac4f61b9e85ca75185af845c4f4330652ef024869ca7d3d33cc188a65cf17aa645b8d9b010f379198e31b7ae448082069b33ab6ff3a235ccac081814b6e063686707721f6006eabc91a4999915661427c85979b93ddfc14e24176e9c0359839a1c16f91afef473652480d4a2261abbb7fcb031de8993a57600220a6c9fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852ee6cb12a54341aeedc99f1040b01603c35f07c5487ffac7b4fc1925f490269165aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +expected_public_key = 8c9845bf1121a0172c991415a6456b7d708cf45a376e689e8c74b1dd589e2ba95d19192e47937b647c21bd9a518644113f44877aab626c40843b078e9a93be166c73772b290164c7ca1454f2b310c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae30b2267aa97bed49c5eac3a9b769c3a9aba51e882d0f5984cd7c39a2d1136fd627b3a204ca30a32efa02d51977eb2145e6c91717e0760f8949caf6b928a59f4d6b24221a291d008679b4b761178909c83d4c035de424c202117132010da0502b75e51705d07da603526fe46f50807af33593b0d59d4b28b31ac48ba7ba35793b194224a4f7577d4a7664e4311841b3908ba57292728a428a516d96c90511ac6b34673dc0127db223b7b27121a2aaee2822744b7f23969cf95b3960826c0ab4a100501bb601b6f2597339a408eea5360b9c6b752a03d648817654a35db7c5fde89357cb1e44a1b800d99e87872f95a17709f72a2a502d8f908cca15a22c14691e219b95b9c3fdcc3fe3c849efeb9cc0dc051f451fbad93ba360b2dc2370b400ce74058dff270757f20603176ef888cf2caabe2f8b337377368ba7aca7131bd6c8615e0017e2b21bd5b9b029085ac668803f66798ab060104ba4e930322b1452befb11c45112da8592fc0a74ccb8a75491120c1b0c1f0cb0a1abc7386948be2bac6bc92c60944ac8482e5a519b3ff36df7ea5e6f939b0c1b662342a08b6059658448b65b65c432b28fb66b92594d0d8938e5d3a0d6a99c7b3173a0796e02195e84b28da2b06fcd5672412420c916c77613b9c69039cf1c6594d90aad857dd319cc9bc9702fd452ad455d5329b14ab033a5910c08124338933f60993c3683433352cce6c484efb072f59b85a6b402d4652d910173caec2adeca708bdcad9d996b60a08f8c3131c571b5faf01a4b65565b18298ff8c6b3f68e77e768a1c0cc009315a4459b0b191c3584bbcd562861c20fc8e2c70944b7eec84c7e427f935b5731fb6e42d8b40b013951852413e94d5e01a04405319a7167b8e4cf638279331a6c3eda1dff9cac99e148bda370c2d00715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_private_key = 68442641472c1216cff86478bbd31e60e47a22391987da1541aa882a649a482bc06b28a7181913790294e3a4a3429c7ccec1ba4012132b8c26458a7afc514e3c859584bb2768641abff48ef730920f15775fd408ecb1ce3dcc3a10095c96a3b23d6a39e6caa335bab5e143118ddc72ef347426f83907153f0aaaa356200279cb10a6a1922bd148898731b5a82f0977395f00189f244036d8a409937ad9a4550972b165f52b15d851f30b127ff5b3f6b29818501aa2c9b00a7981773c32d2d55d8caace972c8fc097821382aadbe553ed8b8e1e7ac0418002f1901ae384980146aa6cc01b8a939075fb36d4d48b55f489b870afd61768468204acf72eef892141e05d1a1518e01218519249ef45910a06baa4d442ac9a95c8a39d9d474667b48cb669558e301159e1cf8c6748651039c7f90945708ea56979ec42a8e9e86bee5b5554d8a46da0bb4d8b100809203110518534260f321d0adc1fa6993fed33283af10bf0130ca4110b6193a7bf746513a8cd4b84658054623e75272c198fb443af89927faf644824e8cfd7ac3eb2d12efbacbc7f837834c57e31a521977b655d682a34079c89f3c38418ca432242fd7420f990312a722f67269437481abff29b1f4c6795975549d38d6224ba7006046a015d0f770434e597f039767551381474868eac4d653a7bf0b989eef6582b80744a5b91b1473a9e920055e4b5bcd523b7a618722a107470234430158dd887982b79383b7272a4685a854c306b43d36ab89b57736ff667c27a10265a7e15bb5cd9112d6f9387baf21f1b32957e17c05ddc50c176a5bbc2ad5cdcad536185be78c13ca6c2a3220d493213bad32f33f582449070c4b54725e329b1e99a0fa58010d7a22a6a4dcb822e5bb28803e4027dd935cff4c556204531d27c5a462c92a085c7363a214a2e0c8c1d1cf42b069ac623a245a14974d2cacd58f18a8973a02c66ce4f771124e9878e402103f96bd3f00ce61a78a5fc5123d1aae661c8908c09dd457285f435401310a6f4a513822c8261aedd896adaa8ac1d52c1352a1a3e2c7b1ffb13afa0cd6b39875e9c7db636b82bf2278c9845bf1121a0172c991415a6456b7d708cf45a376e689e8c74b1dd589e2ba95d19192e47937b647c21bd9a518644113f44877aab626c40843b078e9a93be166c73772b290164c7ca1454f2b310c7133a12aaa960e3b4ae6aa2fa5666de35733547c069e9911b15c17a8a732c9aae30b2267aa97bed49c5eac3a9b769c3a9aba51e882d0f5984cd7c39a2d1136fd627b3a204ca30a32efa02d51977eb2145e6c91717e0760f8949caf6b928a59f4d6b24221a291d008679b4b761178909c83d4c035de424c202117132010da0502b75e51705d07da603526fe46f50807af33593b0d59d4b28b31ac48ba7ba35793b194224a4f7577d4a7664e4311841b3908ba57292728a428a516d96c90511ac6b34673dc0127db223b7b27121a2aaee2822744b7f23969cf95b3960826c0ab4a100501bb601b6f2597339a408eea5360b9c6b752a03d648817654a35db7c5fde89357cb1e44a1b800d99e87872f95a17709f72a2a502d8f908cca15a22c14691e219b95b9c3fdcc3fe3c849efeb9cc0dc051f451fbad93ba360b2dc2370b400ce74058dff270757f20603176ef888cf2caabe2f8b337377368ba7aca7131bd6c8615e0017e2b21bd5b9b029085ac668803f66798ab060104ba4e930322b1452befb11c45112da8592fc0a74ccb8a75491120c1b0c1f0cb0a1abc7386948be2bac6bc92c60944ac8482e5a519b3ff36df7ea5e6f939b0c1b662342a08b6059658448b65b65c432b28fb66b92594d0d8938e5d3a0d6a99c7b3173a0796e02195e84b28da2b06fcd5672412420c916c77613b9c69039cf1c6594d90aad857dd319cc9bc9702fd452ad455d5329b14ab033a5910c08124338933f60993c3683433352cce6c484efb072f59b85a6b402d4652d910173caec2adeca708bdcad9d996b60a08f8c3131c571b5faf01a4b65565b18298ff8c6b3f68e77e768a1c0cc009315a4459b0b191c3584bbcd562861c20fc8e2c70944b7eec84c7e427f935b5731fb6e42d8b40b013951852413e94d5e01a04405319a7167b8e4cf638279331a6c3eda1dff9cac99e148bda370c2d00715c4ae7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c8242ad42d6d3b13c72b16287909bc4c0da04900536a1e48a1a28db4f5ee2d2e771e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +expected_public_key = 5b5b3208a4c987ac02199a6c057376e2e11015c237bff18c63b730297052d7b9a6c7e15a3f02a9046c23e7d977111524afdb42fcf24526ca4f17ea597a26874e333f40e840fa3c9910c12ed9d86425421e7b585fec42326fd1618db61c9c7ca727e03fa772cc9cb241166cb40d3148b4889ffed89c8b0b772e807a157a6ad3b067c9f43c675c69890a71b996a323376777723cc6a4bd240c40deeb93b9a61bbc306177909e181636353a2f4b3b02f820a9f841a690b50a74f09eab73ac4b13689e267983241b3c9774c42701dabc8c3060381f60c591608431ea91f5743362eb86add70c93078349f4bf4b137d43e06c6258484c92c8457521d54915c96754673a4f981ca7c1a3c228a22ab44a4c1d207988d8a49925724c218efb34c1afd4b56dcc8815622d0e1c206991abb6e50a3e8299d9ea10a8b5c5611455378a5ac2b179c74501896102890171f95bb18d32ca7aa01eab0b272df4b77c6377e9397f8fdaaad0294b59c68607a073a2e021ab8b1ab1205cac74c4bbe21ba80b98225a33b0f18b45a8227c9b6e18f9c25f6b901137a7912ab148849228d2aa374a261073307127c6b09777fa9768c183067bc821f3d77e343874864288518ca21ebb2061828c0a60340e30ce80f60ef5523129f18bed579625e9419185019c8cce24162384cc6eeb7b5f9ef1725ab6034db7c7ef0580c9f0cd0a81c2236c46ec9a3225593e3b11939b9758556cadd3f9967de57f21db4c4af8541b4b813d67159afcc69dbb36d3dc470a829a5d771dd8468a21356d40c80f1c156008b3bff356962f84a48a041f4e4b29b7276111660851f7ced28ba0cbc24cc631942b92691e386bd81a28f66b8d4306bf89f36d0e015542479f3041cebeab2d8e95304795a31e6cae206b40189b4823359382393bae1057a62471c5a3a93cc874f96c294a6a4e00e6bbf8cc4cea280942d0c43729b2576076e73b3edef1be7317cadbb58db1a046b617800d5ca0e352b6d40a16303c596652a4a2209c5c72428de4b0d6b6821eaab1f6824cb35a04e067b5264359a9a6ce8b3a26259b613710a672d13d2690caaf62c5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_private_key = e9c556bea1b6cf3b62f9db44bd74434d6067b1700c98647a5890c35224c1f871c13b80738417c5c78171d61b6b500c907f936a1bfa6125cbb5d41c88e291cbab81a44aa84f4ff4224ccb8a5e05ba5b66927d696c2de24142ea480881c63da0ca5f8820d36a360f345ce4804758d02a3959c2cc876ffe84c6fce10ed111b6e7f594dae12a30a015b30b403dfb1ce3f71fc295b962e22baeb913aabc4397ab4011980dc1d335f2460ae95127071a6fd810248de27004e283e208cd00d91ddc56b60445714679b4aef87f2a844fde365b162cbae33a078ea0a516f6661d66b3c03abef8daaebdb0af32b28a7be042e78b85ff14b421f82c1acbb0bde1c8306821a851605ae83fd8a3135b896d3c990f67da3a37617915f625e7cc7dc8db4fcb6a10723025294c4223aa809ab29c0c4ccfe0330309e4a3d6d5884f3b46a9a0367efb62caa19d9a1ab299b83e0bc0390d011f3c5b5a9b8593ac866591bb284727c52c435105453c0842c9558174ad98283c248ff8392619833cb39a14a22906d2b8738ce2cb4695b8cc60a8682cb7d8356f3af1bba91396b9c06414dc7ecd139eb87158596b3221955baa56265897c78bf65efe116ac27332c7bb529ec52fd1baaf7cea94f9da2444a01f1cd61777840bce32900eb69471cc6d18749824ea94e8183a6c0007a4d6c1289aced952b595582f548713a379b39d47ad348c68d2613491116fe01c6f70a5ac6578a05211a44586c68c982f72d6645e67409fc85c584c253710c800b1a0d1293223f874044ca3fc1436d2daa5751a1b596c58fa4270fdf102aae4179451ccdd913bf0bc36ba7cbdf6ba276f988a3586420ae2afab95940f9116fe5439a71927f9ca087a9891113ac8f9c2bf0d2b091d7accec51afc15708e8972370d547cc9269fa487810c2b2f1c474a6c8858de8414f1895487c10de2cb46cc68cd601b9f0d8059599c7ea620e5e0c0f1b4008aa1a4d1f4c25a1448a51447463a3a88b9a72b69cc5385750fcacb78ae35982cb3ad5285874a5b34c53c00c17913e8b746421aec51b93698c4bc48b74dd65384fda4297f170bd65436453335b5b3208a4c987ac02199a6c057376e2e11015c237bff18c63b730297052d7b9a6c7e15a3f02a9046c23e7d977111524afdb42fcf24526ca4f17ea597a26874e333f40e840fa3c9910c12ed9d86425421e7b585fec42326fd1618db61c9c7ca727e03fa772cc9cb241166cb40d3148b4889ffed89c8b0b772e807a157a6ad3b067c9f43c675c69890a71b996a323376777723cc6a4bd240c40deeb93b9a61bbc306177909e181636353a2f4b3b02f820a9f841a690b50a74f09eab73ac4b13689e267983241b3c9774c42701dabc8c3060381f60c591608431ea91f5743362eb86add70c93078349f4bf4b137d43e06c6258484c92c8457521d54915c96754673a4f981ca7c1a3c228a22ab44a4c1d207988d8a49925724c218efb34c1afd4b56dcc8815622d0e1c206991abb6e50a3e8299d9ea10a8b5c5611455378a5ac2b179c74501896102890171f95bb18d32ca7aa01eab0b272df4b77c6377e9397f8fdaaad0294b59c68607a073a2e021ab8b1ab1205cac74c4bbe21ba80b98225a33b0f18b45a8227c9b6e18f9c25f6b901137a7912ab148849228d2aa374a261073307127c6b09777fa9768c183067bc821f3d77e343874864288518ca21ebb2061828c0a60340e30ce80f60ef5523129f18bed579625e9419185019c8cce24162384cc6eeb7b5f9ef1725ab6034db7c7ef0580c9f0cd0a81c2236c46ec9a3225593e3b11939b9758556cadd3f9967de57f21db4c4af8541b4b813d67159afcc69dbb36d3dc470a829a5d771dd8468a21356d40c80f1c156008b3bff356962f84a48a041f4e4b29b7276111660851f7ced28ba0cbc24cc631942b92691e386bd81a28f66b8d4306bf89f36d0e015542479f3041cebeab2d8e95304795a31e6cae206b40189b4823359382393bae1057a62471c5a3a93cc874f96c294a6a4e00e6bbf8cc4cea280942d0c43729b2576076e73b3edef1be7317cadbb58db1a046b617800d5ca0e352b6d40a16303c596652a4a2209c5c72428de4b0d6b6821eaab1f6824cb35a04e067b5264359a9a6ce8b3a26259b613710a672d13d2690caaf62c5f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc755b70c5bb1b7af3b643588aa7c20567d4259dbe6abd7617a61b48185de8f21e1cfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = 195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +expected_public_key = 45c83435071624067d69587335b97bf564929709c8825a004b028ae09c40980a07e8d4bd604527ee221e8bac67d34cbe762c26df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367d3153e460f497a209c495fca318862d6a57800865479a006012d82f7212b40284d310e01bcb11e122c1fd303e441807849a7ea47976a99abb7ccc4b674ad66f68eca195789b277d23c3d67bc418ca7c908b21e53984983ba0205e4689000ace97238b3699016fa95e7a3a59cec0be813638527562fa9bf10d715e7505f6e1c1433521a918a7df52760a0d8a9549569f10827c423cddff82aae01a90111395487b9c82b7b5a7978d789679e66b75087bfbff0569fc94e94f93531b721315926388431f2a36ae0f701bac254befb437c58641d4560c8738a98f30918945db0a6900ad2c2abfc3e0f4786a4555639d84dcdd031d8f0508d8c774d68298bcac4f42c6a7ff585af491fa7d7c3bbb41727699ebb315c437b210d42626ebc66c916af1f3515374314e4f40309ca7289c7bc51c301d8180edc792d4dd44c41b77bd47a972d8434a9f03bb3954236ec422be0c8e991a79af286b6a7c459a95ed44868ed8052f2db0f3741710228979507cff961564882b5ea19515ee00d657c7141e9b05f9a24136a2f915620b664404b5397cc7842748973d0716cc273b528d51383a63fc8a3c4a3b1a8bc965775d750add6996c929e29f41e42362a759baa76f5a3dc0552f1d83195960e45837901494a87f2a6dc3b5d8b73a9695c1229a0c9bddb0b2d99aa350c6cac657745c1308af354e10595f3682a34dc26d9d28e2e2c4634aca75e94384700c9c06b1bca348330ac1791fab1419099cf1288283bab03dca09ab3593cf3b12739cb44c0c04c6b93d1ea831df6bcb8807aa6aa8cbec64d749a9e47f851c47c6537e196f1fcc4d63b67d29a58e86b9a72a199cbb793c5084e5bab20bd02289b4aaa64e4c119488531e8a651a31750148e1742c5390bb9995c123f3056ad44c476468ded4b88a49130e35b4b00803dd24718674ca708e436d5c15ee1d95367c623512653c83b27b41cb308f8c2929b193b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_private_key = 109cbf34136da8c797072085f046541a205922b9b9291acc027173c0d824ab1534102b07a399853c9b5d4fea1f7ce38302c587fa9643af3218afdbb48f52c516b0074cd336242591691402750384db8323f812a8926875014089df7698554391f1d687a1a2380e9c2b81261656632ee78996d404ab4f224c0dd3acd6b428b8d2af81250e7d9825640c3f94d297b2506427505eb3045a8852708b6854f0a99437f6738f22c1dce44c160163515074c3c72e2a4041c8a407dee38ac53335841029bc005705894ab658224134421ad4af7543009c0093b9b38597424a32dc9a5135beea4598d8f2589d72855ad37cd99880c1fa91116c1a933c70a176086d437443b63523145314003884ec19a0b745855002e4b63f4978520661c589d9132ca27f84e9ab5536b60420c89c9a9717082ad58a05e8c808c7155600c199e8fc3ad01b229308071a2b9587e203fd211442f3ab9e9236aaeb8c6555c1d47a75fff45a5d7a5ebe85a8dcb7ceb077393712cf9f7c465d066f80c359c7a3c713cc21a4653078fcc51b7232e48900ed750986156cab756d9af0c685263b19772b35a8ac3e214e8b7b9f3785395b500f76477858b123e24c0e63419cc6db517a148e560a358ef50b8ab238d000181555b46db95d9e8c1bda5273cd58818e322831a71301d092904289cb4c017fd1c86d758c064136f6b937ed222bbff244de7c213ce24c967cc5787b87747a305c73223bc2a6cfca8450d4954cb21e3d160e5b860e89dcb38f8bcfd016a927997f6e9c7c1e2a2ff97c93879cc1a5e30c20d80423f83c84373b85384bb7d88e9feccacf73ab59969750410ae69537c3225d3423acba55174415a259f60e58117712c21acee6a97d281cc6642997833371358f60c35da6e6a833e5bb20d94eeea16e7093501ad54ab65caae67754b9560b5f68b78b44ab26b439d453412206325186bc4ec2479fc103e73b057a972aef6949d7403beda51d82f0c654fa1136071b876704c7c9333db252b4a37a06755a1cd428b8041d8c80a94aa76cd8d65d1e16a8d240ac71db05dfb69d1439b57d9a3e262cca3feca48d9c1145c83435071624067d69587335b97bf564929709c8825a004b028ae09c40980a07e8d4bd604527ee221e8bac67d34cbe762c26df8453aae8b8c82b59c51a85526aba8ddc4b5f63cf69a5b367d3153e460f497a209c495fca318862d6a57800865479a006012d82f7212b40284d310e01bcb11e122c1fd303e441807849a7ea47976a99abb7ccc4b674ad66f68eca195789b277d23c3d67bc418ca7c908b21e53984983ba0205e4689000ace97238b3699016fa95e7a3a59cec0be813638527562fa9bf10d715e7505f6e1c1433521a918a7df52760a0d8a9549569f10827c423cddff82aae01a90111395487b9c82b7b5a7978d789679e66b75087bfbff0569fc94e94f93531b721315926388431f2a36ae0f701bac254befb437c58641d4560c8738a98f30918945db0a6900ad2c2abfc3e0f4786a4555639d84dcdd031d8f0508d8c774d68298bcac4f42c6a7ff585af491fa7d7c3bbb41727699ebb315c437b210d42626ebc66c916af1f3515374314e4f40309ca7289c7bc51c301d8180edc792d4dd44c41b77bd47a972d8434a9f03bb3954236ec422be0c8e991a79af286b6a7c459a95ed44868ed8052f2db0f3741710228979507cff961564882b5ea19515ee00d657c7141e9b05f9a24136a2f915620b664404b5397cc7842748973d0716cc273b528d51383a63fc8a3c4a3b1a8bc965775d750add6996c929e29f41e42362a759baa76f5a3dc0552f1d83195960e45837901494a87f2a6dc3b5d8b73a9695c1229a0c9bddb0b2d99aa350c6cac657745c1308af354e10595f3682a34dc26d9d28e2e2c4634aca75e94384700c9c06b1bca348330ac1791fab1419099cf1288283bab03dca09ab3593cf3b12739cb44c0c04c6b93d1ea831df6bcb8807aa6aa8cbec64d749a9e47f851c47c6537e196f1fcc4d63b67d29a58e86b9a72a199cbb793c5084e5bab20bd02289b4aaa64e4c119488531e8a651a31750148e1742c5390bb9995c123f3056ad44c476468ded4b88a49130e35b4b00803dd24718674ca708e436d5c15ee1d95367c623512653c83b27b41cb308f8c2929b193b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b801782fce09e644e310c9286f1e381be9ea8c54a1804e61f2958c1f975aec185aae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 + diff --git a/libcrux-kem/tests/kats/wycheproof_early/keygen768draft b/libcrux-kem/tests/kats/wycheproof_early/keygen768draft new file mode 100644 index 000000000..e6699996f --- /dev/null +++ b/libcrux-kem/tests/kats/wycheproof_early/keygen768draft @@ -0,0 +1,500 @@ +comment = Official test vector 0, seed: "061550234d158c5ec95595fe04ef7a25767f2e24cc2bc479d09d86dc9abcfde7056a8c266f9ef97ed08541dbd2e1ffa1" +entropy = 7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f +expected_public_key = a72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922 +expected_private_key = 07638fb69868f3d320e5862bd96933feb311b362093c9b5d50170bced43f1b536d9a204bb1f22695950ba1f2a9e8eb828b284488760b3fc84faba04275d5628e39c5b2471374283c503299c0ab49b66b8bbb56a4186624f919a2ba59bb08d8551880c2befc4f87f25f59ab587a79c327d792d54c974a69262ff8a78938289e9a87b688b083e0595fe218b6bb1505941ce2e81a5a64c5aac60417256985349ee47a52420a5f97477b7236ac76bc70e8288729287ee3e34a3dbc3683c0b7b10029fc203418537e7466ba6385a8ff301ee12708f82aaa1e380fc7a88f8f205ab7e88d7e95952a55ba20d09b79a47141d62bf6eb7dd307b08eca13a5bc5f6b68581c6865b27bbcddab142f4b2cbff488c8a22705faa98a2b9eea3530c76662335cc7ea3a00777725ebcccd2a4636b2d9122ff3ab77123ce0883c1911115e50c9e8a94194e48dd0d09cffb3adcd2c1e92430903d07adbf00532031575aa7f9e7b5a1f3362dec936d4043c05f2476c07578bc9cbaf2ab4e382727ad41686a96b2548820bb03b32f11b2811ad62f489e951632aba0d1df89680cc8a8b53b481d92a68d70b4ea1c3a6a561c0692882b5ca8cc942a8d495afcb06de89498fb935b775908fe7a03e324d54cc19d4e1aabd3593b38b19ee1388fe492b43127e5a504253786a0d69ad32601c28e2c88504a5ba599706023a61363e17c6b9bb59bdc697452cd059451983d738ca3fd034e3f5988854ca05031db09611498988197c6b30d258dfe26265541c89a4b31d6864e9389b03cb74f7ec4323fb9421a4b9790a26d17b0398a26767350909f84d57b6694df830664ca8b3c3c03ed2ae67b89006868a68527ccd666459ab7f056671000c6164d3a7f266a14d97cbd7004d6c92caca770b844a4fa9b182e7b18ca885082ac5646fcb4a14e1685feb0c9ce3372ab95365c04fd83084f80a23ff10a05bf15f7fa5acc6c0cb462c33ca524fa6b8bb359043ba68609eaa2536e81d08463b19653b5435ba946c9addeb202b04b031cc960dcc12e4518d428b32b257a4fc7313d3a7980d80082e934f9d95c32b0a0191a23604384dd9e079bbbaa266d14c3f756b9f2133107433a4e83fa7187282a809203a4faf841851833d121ac383843a5e55bc2381425e16c7db4cc9ab5c1b0d91a47e2b8de0e582c86b6b0d907bb360b97f40ab5d038f6b75c814b27d9b968d419832bc8c2bee605ef6e5059d33100d90485d378450014221736c07407cac260408aa64926619788b8601c2a752d1a6cbf820d7c7a04716203225b3895b9342d147a8185cfc1bb65ba06b4142339903c0ac4651385b45d98a8b19d28cd6bab088787f7ee1b12461766b43cbccb96434427d93c065550688f6948ed1b5475a425f1b85209d061c08b56c1cc069f6c0a7c6f29358cab911087732a649d27c9b98f9a48879387d9b00c25959a71654d6f6a946164513e47a75d005986c2363c09f6b537eca78b9303a5fa457608a586a653a347db04dfcc19175b3a301172536062a658a95277570c8852ca8973f4ae123a334047dd711c8927a634a03388a527b034bf7a8170fa702c1f7c23ec32d18a2374890be9c787a9409c82d192c4bb705a2f996ce405da72c2d9c843ee9f8313ecc7f86d6294d59159d9a879a542e260922adf999051cc45200c9ffdb60449c49465979272367c083a7d6267a3ed7a7fd47957c219327f7ca73a4007e1627f00b11cc80573c15aee6640fb8562dfa6b240ca0ad351ac4ac155b96c14c8ab13dd262cdfd51c4bb5572fd616553d17bdd430acbea3e95f0b698d66990ab51e5d03783a8b3d278a5720454cf9695cfdca08485ba099c51cd92a7ea7587c1d15c28e609a81852601b0604010679aa482d51261ec36e36b8719676217fd74c54786488f4b4969c05a8ba27ca3a77cce73b965923ca554e422b9b61f4754641608ac16c9b8587a32c1c5dd788f88b36b717a46965635deb67f45b129b99070909c93eb80b42c2b3f3f70343a7cf37e8520e7bcfc416aca4f18c7981262ba2bfc756ae03278f0ec66dc2057696824ba6769865a601d7148ef6f54e5af5686aa2906f994ce38a5e0b938f239007003022c03392df3401b1e4a3a7ebc6161449f73374c8b0140369343d9295fdf511845c4a46ebaab6ca5492f6800b98c0cc803653a4b1d6e6aaed1932bacc5fefaa818ba502859ba5494c5f5402c8536a9c4c1888150617f80098f6b2a99c39bc5dc7cf3b5900a21329ab59053abaa64ed163e859a8b3b3ca3359b750ccc3e710c7ac43c8191cb5d68870c06391c0cb8aec72b897ac6be7fbaacc676ed66314c83630e89448c88a1df04aceb23abf2e409ef333c622289c18a2134e650c45257e47475fa33aa537a5a8f7680214716c50d470e3284963ca64f54677aec54b5272162bf52bc8142e1d4183fc017454a6b5a496831759064024745978cbd51a6cedc8955de4cc6d363670a47466e82be5c23603a17bf22acdb7cc984af08c87e14e27753cf587a8ec3447e62c649e887a67c36c9ce98721b697213275646b194f36758673a8ed11284455afc7a8529f69c97a3c2d7b8c636c0ba55614b768e624e712930f776169b01715725351bc74b47395ed52b25a1313c95164814c34c979cbdfab85954662cab485e75087a98cc74bb82ca2d1b5bf2803238480638c40e90b43c7460e7aa917f010151fab1169987b372abb59271f7006c24e60236b84b9ddd600623704254617fb498d89e58b0368bcb2103e79353eb587860c1422e476162e425bc2381db82c6592737e1dd602864b0167a71ec1f223305c02fe25052af2b3b5a55a0d7a2022d9a798dc0c5874a98702aaf4054c5d80338a5248b5b7bd09c53b5e2a084b047d277a861b1a73bb51488de04ef573c85230a0470b73175c9fa50594f66a5f50b4150054c93b68186f8b5cbc49316c8548a642b2b36a1d454c7489ac33b2d2ce6668096782a2c1e0866d21a65e16b585e7af8618bdf3184c1986878508917277b93e10706b1614972b2a94c7310fe9c708c231a1a8ac8d9314a529a97f469bf64962d820648443099a076d55d4cea824a58304844f99497c10a25148618a315d72ca857d1b04d575b94f85c01d19bef211bf0aa3362e7041fd16596d808e867b44c4c00d1cda3418967717f147d0eb21b42aaee74ac35d0b92414b958531aadf463ec6305ae5ecaf79174002f26ddecc813bf32672e8529d95a4e730a7ab4a3e8f8a8af979a665eafd465fc64a0c5f8f3f9003489415899d59a543d8208c54a3166529b53922d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee868626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f + +comment = Official test vector 1, seed: "d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac81adde6aeeb4a5a875c3bfcadfa958f" +entropy = d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 +expected_public_key = 6dd406b49b9ca035467fd26c6c0b824bea310f435fbe8bbbd3430b5c39889e6b117e994e2f08823a33789ff858b72715323c6204a241d9835ec0da85c5884a8a96210219099c8c383c182632280356c1b4f298405258a170e81624e861fc1082d31867a9037e3b90b0aeeaa064d27020da7ba79398fa92a963a8a294e7720bd4cd9ea213f08063079c4d55b094bebc4e979444f462b967972e61206fcc80337911b02c7396bc64405ffc0b77cccd2ebc121a734037cb90b77846b2359c30a451beb20a6d72c238284e5df2ad1cc1a33fd5a104965c86251a596360d541240a4828231a827a0168b6d8ac7e27328173886453a9c91498765c2bd9ea9f666bb4a1d60f992538a1a746df845574f99adad23b9744afa81c7fb79a32b175706454438f46b8985132b8e1cca10c2b0fa011eab2428b88cfef9378a5228e55d7463dfa5022c998abd6354118b5116b3bc1004f0008134b85a1cf2a9f409a10e14b6d06c26d8e355864c35bc71b60d5cac33a513efdf6b9bb83bc880983682c8fb8a81b6927ca52e93835956795488181a8cd82b1a50dd18a25f35e2643cdd76c282e7018bb99624f031418fbc8052c4179b43a5998be9a20cd2d8a883b313ec282598202add6471971c88cd9607d3a8052519930bc5bc71ca4652352b4d02620b8d983b9849ce8b8935f1a4decc3250de7b0cfcb49eb7b74e0b5792ae97633b092081c3c6bf58f1b242ca07610c3387098ac3f0f9043901c614590c4ebbc64ce1971e824694a999cbcc430ae923a1432b6a4911162213c429481394a27006b9d48c0ab5801823d756bfd8c6919502d613594aec81f5669bd4e8495292606959292467ccac7f688333b3f48a39fce5c42c9c2653886a5adf4747cc943b2416348f46df5b58e4916ba64e9664a4baaa3e0a9652408c8e5076c226c3a7932c42a846949a2a26b4e2c452f86cacfe5c201ae1321ab5c2cabda557648a849241f077a799edba3582202cb27763047219f5546cf18819322b9c63974b322b949baa491d97c70f20545886c87086721d3ca2aeab441264b516975ed0c6044a425853528424532e4d721e85cb0bf65c26082c790765b062916fac4a0dcecbc2e900c6f600270838e2df20ee0a907e3613dcee049c445640362c980a292f123c6c9b5918f21443c996016c44d2a124c5925a8e0c48e89bb167a129fcbf67adb89903e1249f6028bc176bacc722366139858e583eb582ada714e79b5ad1bc1a6f18754e100624620968d0702e080befec425bc16b650a307802004c57590897c87e65347f32c324569051d798bebdb421eb28b2d1a0c662444c7db32bf97845d7225c7539f457894eb87606fa85b5e804053fb6ecdea773566c006e540ee65101d99bf314181d666680985c78b103dd00a040dc69cff389fea7c18e48a363b943ff042b476dc86be953a5925076cf749a62a77a9406165d31dacdc3a677b9114d8bf84b43f59f647fa4023535140fde04285921184809c5f193a7df45f62187854061a4d6754da528f3b71a134aa487d9b5f7cfc6838108b8b95b51f5540c9ea5f29990f7be07efd502461033f103723093a16dd96c098977f81330249183cf35a636841bd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d2 +expected_private_key = 94b49ea42526935245c45a7d580b6aeff8bbe0f5342bb8bd2550212ad5935f45cba7caa6df914007fba79e9946c9433a86a2c4202bbdcea008af78975e6619d3582787530dbb7318a530b7b5a27d24258c7ccaaaf505ca92cb853a5818d4269be812becf169a05e71eb957557787c2f3b72315281dba87476b157a06095a30d52b388ac22840755b43440a931df8a709dc435b415a7babbb04ccd93cda00ca1fb090646b1d6514813368a794d38c907163b5917496b018c519b160c5144d6424495626e3a5ab9ffb8d8d3168d77599a88a1d12c07d86498d88dc1af7fa7de15073fd4b62801c1a902b215e7cc3eac350bb63adeaf9c7594844795a9a6274aa3eca0cd10891f05795a77b30add76b6b1a35338b8156690ca2ea1c9c3b602b23324925314f726535b36dfb355225d37e7c85be15a5976a8a6ad4e2c35d4c45acc954368ba6df88a47dbb8c782336f7ea507a6c2d26d952dc03b4bfb89872644084783ab493cd72d3befc2c803b692729638af69b03e6db9b82e678a42969fbe770fef65723f77da6437c20b203601c884a9b9e08c0b1ddbbc1a66517dcfc76b3f125f7795e5ddabef0cb00119778575513e05ac38a7901a0e8c8794685c0f274050097bc50168818a74aba5d71980f5c76279ec0214cd51efa8a21391567fa052e6dc0cf9bf216cff9287c80693645a53d71b3d7509f6a432d51b2b0aad129b594278da74ffacbb713357d735a744b7c65e482b7e172c67a5b4edabaae11222b8bb6b4564ab4fb20c28b4981614b69bb188db6056607e089f64803d89210c7e604266b00548a2ae27996196a6d6f762c27b22731f7942543ccef3856edf9ad1b1b1652a33c3e038dd9b2cd9a4612ce174315e67b26dac767e50e68508d104bbae1a2b89b78266d27b109f90bce1581a8b8888c90c1c4ea5fc1f009d5073780cb4545087c88026b9b9abddab923db52620713c8b5ac3301e8715ac39d13084926e841fae41a7bbb7912e10680a78c0c363a251720b2d69467b6cac5d894f862595072a7c9b14bfefaa2fdcc75cc42892cec6184b52962b9b73d663b7d76c1ea499d538bb45a4caecee0c8eb93bba5ec1a8c936156382b10102e3211b2dc15663412805f60590ec33dbab80d2a3bc05fa8af5145644f712e004c20f799650159c40dc952c9a54c27e816c3a6a95efbab24a31f6c402300f9baf88a46644b4df8a24979e80dc30425b9e75a753a36510b87c5fa95cbf36e19a12245876003b54d4e008ef7ab9d83c5a2406014b5cc33b6167f4c452af45084b7412ec19556d82b0a6a90c1aea60a72312d8a7a8e5060189717094ff950af2b503988964f0aa227c523487471d3bc905b6672be20bc714729b7a71478b07a19f777dec546c624723af7b5f6c142274ac5652a7c2d7abbf1171f2bdb12f1ecc876681a600806d6fc229e6a8f6424419187bd22e49b8f27486db25371c169b3f61e81131b57659b1030a959790ba5d6424580b1f588326db9cd01a260b21b8c42062b883854fb173ea7613764d41dd6b89468c7ba6c4236d1a0436b945b8b340983023139293fc48c07659b955453bba07b0eb4e2a91f594232a47c65c66e1c5c8279f179925c55ee3a0b6dd406b49b9ca035467fd26c6c0b824bea310f435fbe8bbbd3430b5c39889e6b117e994e2f08823a33789ff858b72715323c6204a241d9835ec0da85c5884a8a96210219099c8c383c182632280356c1b4f298405258a170e81624e861fc1082d31867a9037e3b90b0aeeaa064d27020da7ba79398fa92a963a8a294e7720bd4cd9ea213f08063079c4d55b094bebc4e979444f462b967972e61206fcc80337911b02c7396bc64405ffc0b77cccd2ebc121a734037cb90b77846b2359c30a451beb20a6d72c238284e5df2ad1cc1a33fd5a104965c86251a596360d541240a4828231a827a0168b6d8ac7e27328173886453a9c91498765c2bd9ea9f666bb4a1d60f992538a1a746df845574f99adad23b9744afa81c7fb79a32b175706454438f46b8985132b8e1cca10c2b0fa011eab2428b88cfef9378a5228e55d7463dfa5022c998abd6354118b5116b3bc1004f0008134b85a1cf2a9f409a10e14b6d06c26d8e355864c35bc71b60d5cac33a513efdf6b9bb83bc880983682c8fb8a81b6927ca52e93835956795488181a8cd82b1a50dd18a25f35e2643cdd76c282e7018bb99624f031418fbc8052c4179b43a5998be9a20cd2d8a883b313ec282598202add6471971c88cd9607d3a8052519930bc5bc71ca4652352b4d02620b8d983b9849ce8b8935f1a4decc3250de7b0cfcb49eb7b74e0b5792ae97633b092081c3c6bf58f1b242ca07610c3387098ac3f0f9043901c614590c4ebbc64ce1971e824694a999cbcc430ae923a1432b6a4911162213c429481394a27006b9d48c0ab5801823d756bfd8c6919502d613594aec81f5669bd4e8495292606959292467ccac7f688333b3f48a39fce5c42c9c2653886a5adf4747cc943b2416348f46df5b58e4916ba64e9664a4baaa3e0a9652408c8e5076c226c3a7932c42a846949a2a26b4e2c452f86cacfe5c201ae1321ab5c2cabda557648a849241f077a799edba3582202cb27763047219f5546cf18819322b9c63974b322b949baa491d97c70f20545886c87086721d3ca2aeab441264b516975ed0c6044a425853528424532e4d721e85cb0bf65c26082c790765b062916fac4a0dcecbc2e900c6f600270838e2df20ee0a907e3613dcee049c445640362c980a292f123c6c9b5918f21443c996016c44d2a124c5925a8e0c48e89bb167a129fcbf67adb89903e1249f6028bc176bacc722366139858e583eb582ada714e79b5ad1bc1a6f18754e100624620968d0702e080befec425bc16b650a307802004c57590897c87e65347f32c324569051d798bebdb421eb28b2d1a0c662444c7db32bf97845d7225c7539f457894eb87606fa85b5e804053fb6ecdea773566c006e540ee65101d99bf314181d666680985c78b103dd00a040dc69cff389fea7c18e48a363b943ff042b476dc86be953a5925076cf749a62a77a9406165d31dacdc3a677b9114d8bf84b43f59f647fa4023535140fde04285921184809c5f193a7df45f62187854061a4d6754da528f3b71a134aa487d9b5f7cfc6838108b8b95b51f5540c9ea5f29990f7be07efd502461033f103723093a16dd96c098977f81330249183cf35a636841bd1a9b9796f13f56be785d942d7eab011805cf3504fce325b6a5ef1aaadbbb11c662b9d22cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672 + +comment = Official test vector 2, seed: "64335bf29e5de62842c941766ba129b0643b5e7121ca26cfc190ec7dc3543830557fdd5c03cf123a456d48efea43c868" +entropy = 4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade +expected_public_key = f5a35b4ec7538b62289dd1204db91ac492b610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78a4149cf10b6d93283050167e737596b711a9f32a0f6909975055ce6632f4b42cf9a2361cf69047b5bde1868dd745a82cf473ebb30d86a71793364f70b1255b1c2003f166683c936a7977df156a84051e69b95e02616dd3090dd38086ef3bc12353bad25377618965c2810fca929dfbf46f20360fc847818cf90dbc044eed16b3b9052c5c70a5a430441e53a5527a689f49b35ce82b84d6057c5269fb60c710c5731f431a970b86431125910277fa7c310a2285117b47b95054e4174a1eb11da3e3c26ac25619d36712b11b2ef7405bcb943dba10d50c0436b50de5b04d96488a38f53df37895ac20c10d959d81a29fe1f319ff871831d93c54654172a02e65599f9d820ab037438e62714be6c7d868b66ac03c31c8753a062318ca36b6e59d340b9696d47c38f115104765865353a05c8fbc4b0a62a96577e94c17094de259006f169e75b8919bb4c37df6787b59bec8fac999a90b73123a5cc8772ad67585c879ebe05b5c06afdb440adfbc4ad400d0e634822a843e9b165f2f0bb748e231c0e0ceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fac291a0bbe96e9ad36a4a1d9c96939603bcd76a81c040fba27a5a39a1c387cac9d1b086e512468d378e96039aae2622fe5483673850d411ab64b892f2c29853822eae76feaf5716a660b55c2020dd3323a150ceef9ab79925d2bc09cc6faa31727a5912a7f5e9051f8b94d8866c4da173d3f2a388e6c44218338cb85702cba2f602c24e1788158b0129e7c15dcf2cc6ed55c54b456cacc07d179b432a5aa63e8ac59f0b6979a833d99c13aa0c56cb65928032e2f30583fa6c038748ceb77a91c631dd09b575f13126f1447cab00bc9c85fc7601da44ac5fea5adcbb599a409bb1a67b24ef438d750bf87a8814df22449c9256da1286dc623e81546c283b80cc88c48f003678ab35380a6da551ac7041cd5112d59d15a80032c28b61a1bb3b8a7267adf4662b5963468b3bc5918418f980cd7db3946c5a67f864dc1f3adea12142fb71fda590e070007662b5c3b8b31af169a092a2e466aa01ae879641bc4d1d62523ccaa3ed436cc089b2621456114215d1a9eefd1016dc81d5320956fd942bdda40f3a033e5170ca6a2c57ce17eafc97aa0959cf37b92e789636f159faa827ddb895553540d52a61edc1b3dceb22a7231c48037cc78594718902333d0bc4fe6b29352991e2ba5d31217457007057b9d3c07c39b7c7eeecc222d4415d6d9272ec50b81520bc607592947c86d2612e434c22513235536cd08f10022b97675b89f1de58130eb6797380f6b68773dfbba0664bb7caac84f7b06711587c6ecaa383505f62751c8346bdd502a58e9326e4a0d2d29226f794ad0064b2cf0a56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b8372158c1a7bfdcb65d426458edbcf8797383e272d3b18bee68c4d74e25751ab1ce4567d66b714cd62a8e9b886baa812a9f50739e30f296791414727d55003bcb52ab6bb74cab215b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd +expected_private_key = 72408d44c2be6e83c803da2846d852dec1848ee41504b5c91f774f6e512b51f71dd1520203c486f63240bab4c1dbb212299753b8627f9bf2117cd6a83be4075a385782ab804a420972eb25bc553eb981aae7d7a715111338529f6116c10b10bbc20b31c3161d4bc1a5f050220b5584abd6a546ab51a9a10120ecc131220502697e9d61bdbad346fc43824135692204b49b5b377b870b7b28c86946077a215acaa11abd851eca479988bc69ccc9975eb42a33523c525434bc594217912123957dcdc18e410a6d6a811bed8a0b4135b56f4562f343aaec34396bb0556d7962679a76934b016b4b4bacc14650c55c3aec9bc2e85b548b5d3eb891b6596f0c44009bd0982d98bf81ac77c8da98264a719cd8568e48279df9c8e9552b94aa773b43a70742c75f041915752551347f00447d72d934bec553bf1014f4276015e0b4db77cdf8c546af05861804a5b7d92838744511ac6c8be55e883acb7775b98c4b4c9c8789aee317f8f02b4127a6ae879d02c13772a003928041c53351d8d70ce59b14cab5ca31d717f69129c8fabe46582ca5298ed156209c25bc57870eea34255ce1b4c426211f957d74876dec169c4c516c8716b3ddec6c3e610c31f0c52e13650f0b1c70124dee27111a76abef82c8fd3172d554121e6a87e9d3b58e11379cb812b7f4b95d46104934ce75c715771204d7c46aa9439836453bda709cef3bc1c9341994f25c48b5c80fcc8a67e316c431bd302b20904456b3283e9ba1bdde494ce9f8a3f0b432dca69d0ba9c43c703e1616272cd6b904d5b6279c55a539b7e46a601b28493e38a2cd9ba66d997c8c5c3b7631822c529fa48835f8a08f322615e96b9087c71c9f262b68851f00486489d25c92221c2759c89440ce733614b8c7a06f26b374cb4f8a6a7d67da521eba7232c0a4c066886b8450755896cff77a369bc8fd4b3b5b0731452a908acc68366b8edba66d09f212c9330c83990ab2db7095d708b6c3589bf929fea31534646537d2ab023887fc286f00f46f8a360476998e4fe7315f03c234929247bba2a05297a5e01aa9cc6158458e2302513274a2e3359d66126f5fd44d348ba2b634642ea26c6cb616f64a2d2c819abaa48bc565ca0ab67e6cfab1129a0144c10a003b44bd3879b4e62e0ad3a58bd86a7030be34309f3309642b017b0aa03ffab4012b36adc49a95ddba67cd81306ef6bb20b546bcc55eac2b815fb38bae991d6ae7aa87d42ecbc740cc816a3ef42e9d204ca0177cdb30cdcb870386c320ff51b137578b029125ba518a5b887d7b9050dff113468608f6335ea81a59b87cb753724ed0e159fa4709ac018a31194247a6a9c65443a35ac36e11bfa6a8559cf20e50116ee5fb3780fa03dcaa77846b18c04894e50486acfc3b8feabb8cf860d79c2734a700ab731739244580653699b51b7fc440b8cb1d6bb1360291bda5b11aeda3c77a25b40f96763a372512561e0d52848fd6a3a8241dea49c4c24692cb43aa22067072fac2dff7898f298cbae17f9ca68a132321932295161a1f31c178932004d17854d7d9c69f6640ee216747102280191a5695433763b6cf3b86756aae22a37f9f6920c361c2ac68a7e11c8f5505af2100651595bff5a35b4ec7538b62289dd1204db91ac492b610538c93eb5f2637ad97dc88f0035ff3cb735cebac9be7ca78a4149cf10b6d93283050167e737596b711a9f32a0f6909975055ce6632f4b42cf9a2361cf69047b5bde1868dd745a82cf473ebb30d86a71793364f70b1255b1c2003f166683c936a7977df156a84051e69b95e02616dd3090dd38086ef3bc12353bad25377618965c2810fca929dfbf46f20360fc847818cf90dbc044eed16b3b9052c5c70a5a430441e53a5527a689f49b35ce82b84d6057c5269fb60c710c5731f431a970b86431125910277fa7c310a2285117b47b95054e4174a1eb11da3e3c26ac25619d36712b11b2ef7405bcb943dba10d50c0436b50de5b04d96488a38f53df37895ac20c10d959d81a29fe1f319ff871831d93c54654172a02e65599f9d820ab037438e62714be6c7d868b66ac03c31c8753a062318ca36b6e59d340b9696d47c38f115104765865353a05c8fbc4b0a62a96577e94c17094de259006f169e75b8919bb4c37df6787b59bec8fac999a90b73123a5cc8772ad67585c879ebe05b5c06afdb440adfbc4ad400d0e634822a843e9b165f2f0bb748e231c0e0ceeca8806046b5dea7cac614a5e2cca3767556448785dbc739caa9c58fac291a0bbe96e9ad36a4a1d9c96939603bcd76a81c040fba27a5a39a1c387cac9d1b086e512468d378e96039aae2622fe5483673850d411ab64b892f2c29853822eae76feaf5716a660b55c2020dd3323a150ceef9ab79925d2bc09cc6faa31727a5912a7f5e9051f8b94d8866c4da173d3f2a388e6c44218338cb85702cba2f602c24e1788158b0129e7c15dcf2cc6ed55c54b456cacc07d179b432a5aa63e8ac59f0b6979a833d99c13aa0c56cb65928032e2f30583fa6c038748ceb77a91c631dd09b575f13126f1447cab00bc9c85fc7601da44ac5fea5adcbb599a409bb1a67b24ef438d750bf87a8814df22449c9256da1286dc623e81546c283b80cc88c48f003678ab35380a6da551ac7041cd5112d59d15a80032c28b61a1bb3b8a7267adf4662b5963468b3bc5918418f980cd7db3946c5a67f864dc1f3adea12142fb71fda590e070007662b5c3b8b31af169a092a2e466aa01ae879641bc4d1d62523ccaa3ed436cc089b2621456114215d1a9eefd1016dc81d5320956fd942bdda40f3a033e5170ca6a2c57ce17eafc97aa0959cf37b92e789636f159faa827ddb895553540d52a61edc1b3dceb22a7231c48037cc78594718902333d0bc4fe6b29352991e2ba5d31217457007057b9d3c07c39b7c7eeecc222d4415d6d9272ec50b81520bc607592947c86d2612e434c22513235536cd08f10022b97675b89f1de58130eb6797380f6b68773dfbba0664bb7caac84f7b06711587c6ecaa383505f62751c8346bdd502a58e9326e4a0d2d29226f794ad0064b2cf0a56e6a67c18b331f5537d2fc6c3aeb52a5c3313118cb7d159b8372158c1a7bfdcb65d426458edbcf8797383e272d3b18bee68c4d74e25751ab1ce4567d66b714cd62a8e9b886baa812a9f50739e30f296791414727d55003bcb52ab6bb74cab215b348ad06f974192cbd61576baffc815999ab8556583024cdbd1c4398f4a4ac60e8cb68627382a145f91be9d78fd51ba5e3fcbc3155b62bc07751dd3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade + +comment = Official test vector 3, seed: "225d5ce2ceac61930a07503fb59f7c2f936a3e075481da3ca299a80f8c5df9223a073e7b90e02ebf98ca2227eba38c1a" +entropy = 050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 +expected_public_key = 25949faea67e908040a25908a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f12118e0685b09d30947ac76f4f72e89bbb7579bba13d3cd4e262fcd385eeca8b780d7b6d3343ca7ec1958569c49808b97586c263903989928ab9b63efac00b27037637897556b8aab33198c144d226ab9284541400138e03a31f10cbf1cc4bf633c3ad70c65218c1b18770c91d139971574dd90317a421b8bdc56c02c2564b2496793a27a12009ecca141aa337e911f0b448d913394ec1abbb46a568ba749f0fb0a2c4562637a220225a0afac0e9a53ca4f506391d7483932814dea886c89879237a95c03684cc0c2d2701b40e5b3a340316159cbc56bae84130f2fa830501257f8a8948f482ad194ccd4f6ba6c01bacc4c1b9c3188c3d002f8f18f62393b373396f6c510308b6754b8ca81f53d5a1512ffc3428a6c2a543a61fe1193a86b97b260339fb43a9f0375b1c2c62ddb4c1f6629db701b2d2a50577cc7d5d55a30766400842938d83a6818a128310d16648614a6b6df6b5d8d9a8d0ea4a127f4233b9a50ba539f5f01b62513a5c7bb8ead8463c0a346252c94f753a34751b078a06dd785ac6532c2730caef7249515514f8e18713c2a72d8949de781c698e708deb35448ca1df99b8e09ac4faf694ca71b7bd41bb7024c0435424831424f680a77f13506a56c97b6966afac4b90fe60bf5e7507e6a7093c47b5f8ca47d86c767455d645c502d82cf5b1ccd8880758bea855dc71b1c98494862030202c06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacc7117980774e12355af27e506a2ac63c4abfe585b2123e2404b9ea9753fa101604663d07e153c07b743b23c56b86a91ca34111803a1f5865e47807c012a81885104495499884b495ea3f457a2ae1363221b2a94be84e27cc9e8bca44f8fbb92746821782b3b92b1bfe87127f34076bd4acabf60e4f9b97a8f63008b584d0221af927c67d616bb9933be9486e38d7befda11a27175f670600041a6dbf0c9a4364b3ffd28eceeb0c8077c3aba19c6123a20ca72c0776aa8e21a582168591c7c1eb146ba820c9ea1aa3374625c8744612bcab37250ffb34a89d305c35169660dc9b09f7c960a4c4450b1a2e56088e8605fd75a35eb620c3c90b93fb001e03c006a15b67136ec1c354d405a61014821fa9590dd212cc6095dd011bd8801a10f08f15da21c14cacfde606ca02b7e2e1483e3514cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d58c033ba2280ec0521bc53dcc3772d48258593a5a1f9974228652b8cb4a08296eeae869c733a316d926d400cbb09a2daf532da06522da9694cec2a29cd4c87f6a6c837c6ef6182a30548afdb807bf447953a3827db3122bcc7e33576a33a943492a61f3625dcf412793996c664a4664b3666c154f90b40c3ec514c4b1a2d265a23b897177342b76c69637d52e356620f468480472923313a658683566dc8f8fc1079f248f9d8ac67d4ca703339ae28a86edb4bc21db231dfa970249aeb1e2138bd4791352151520a73b0792a0e77d4967bc8b46740cf5599d4056f382c9006b79938825dfe2806cb6afe7523d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e22581 +expected_private_key = 548a01803a231ca63843872abf16b2c4b9ab7407a093b354f8882c6775bacf2931de0a501c5a7ea7ea5c3baa067290b9fca059d69cc6de9b772cc058470544b64b11abb77f490746384b83283740f0702e17d046759b61e75030f187c2283045b22b4f9e222ca44980dcd0a42e5704504bb3e097cdf93a99f057ab21e3ac305666710c3b4c1b750aa3ac0f00a6f592770d8082f6157addb170a956456c7616c856657835970578b35fa87d8f79c2ae54ad36823c6a13a4207453ff324f17d13d43a400a2102b6f6224e6f2132bb14a32fa3f10a446d7944428b66e0e0a04b204c5993c03c294927c60540f836572793c8825376332b64d109bb7273147a878ff0b0bd2808b62104515d0824c90a4e249b4ec8c0f6b572bb621b7a74089de4b49eac5a3cfb61a5d6b420779a29e1c5ae98ab30e01a0b45538c9a14ce61c4dffa27a4e462757a3bdf00c0206c5bf5233132c47b7111771daac633e22132ae82cbd616ec92b4e9d1c88e7285b84d9a12e14897a020c06832e9cab42102ab999838a93a77141d12ff068ac13dc4c685328c7036ccfc2087bd92ca5a675cfe40ae4c32b28eb770da04234a456eb889ef92a93a0d3ada8061599d99cd8a96880a2b5e440766a9c81e7a24f14c295283c333a0576b49c569c99450f8714160c4cc49828090bc2ca390094e14bd6a3011a5c038f0927fb4bad38440ea9f96fee99141c564a91f9c86dc72498f89d05b047461699fbba62ec28698e273e2b8436a6eb8c9c094d3404853a45137881c691352f6240abd2298488299331cc03b1a3106f242d2871525587888e448d0f45a61480bd7e377dd5b63e143093fcc8bdaa563264baa458649ce7fa5826e4b9b49159e7541d432143c5093a2a5bc5b835535fe7395ec556bd467a10975ce26304bb892d056a6ea4c5ce08d033e9334cf7f6750cb62209ba21f6b147ac875c3f1195d9d991e333c7c25465176b8a566a71451b8305f35d831a36c57c64b664c707f3bf08b54ff3847f1ef0ac4b32ba7d563af40228b2957b8a95063a65bafaf86609b4bfe1127c029c2eb224465e1c178c74cb5db4c0c2aa46456761ec4a528ab2bb8f92c120a1b78a9517a29c8ee408ae7fab4fdfb1941cbbae4c3630f407a2c23c4d10a58a8e64546727153d61766d0242c5132236f637b7323905f4a7811c1b8019a808946c11a54f8ca6c16e06ad9a685edb094616a80383a79e482c611760c249988547194266000722743346d13c80f72117c25cbb48490e05789c6a5e85ecbfbc73669f249c10a12eca037dfd15994cbc450eb40868abc2fea05b5058429b6b04dce2c4e2630a13dba2bec9be9c30b9f90b45a97040a1f227200ccb4a4413c8b0c5b169830d451bc7993eb3d5b4d914a02c3183b7423d61101b0e3ac0a2a18673126f69511f27ec55e28b975e22a8ce800c37473cac71788a42cd39c26c176c9c255c4355a62c0b84cda33819a1ab6c07bbc4f2847aa23a600829cd516485dff565de9c392791b84bdb4580326f5128556d160100622affa2756e1cbd0a0a1f217a0c198a6dc043b1c50813bcfb3c2488a5c02c79393b65f39990b610274fa77b814ba93784562e0794c179549ea0927d9b4a25949faea67e908040a25908a7e33199d586f22a3cf5a7ac49ea41bf83452528c7f12118e0685b09d30947ac76f4f72e89bbb7579bba13d3cd4e262fcd385eeca8b780d7b6d3343ca7ec1958569c49808b97586c263903989928ab9b63efac00b27037637897556b8aab33198c144d226ab9284541400138e03a31f10cbf1cc4bf633c3ad70c65218c1b18770c91d139971574dd90317a421b8bdc56c02c2564b2496793a27a12009ecca141aa337e911f0b448d913394ec1abbb46a568ba749f0fb0a2c4562637a220225a0afac0e9a53ca4f506391d7483932814dea886c89879237a95c03684cc0c2d2701b40e5b3a340316159cbc56bae84130f2fa830501257f8a8948f482ad194ccd4f6ba6c01bacc4c1b9c3188c3d002f8f18f62393b373396f6c510308b6754b8ca81f53d5a1512ffc3428a6c2a543a61fe1193a86b97b260339fb43a9f0375b1c2c62ddb4c1f6629db701b2d2a50577cc7d5d55a30766400842938d83a6818a128310d16648614a6b6df6b5d8d9a8d0ea4a127f4233b9a50ba539f5f01b62513a5c7bb8ead8463c0a346252c94f753a34751b078a06dd785ac6532c2730caef7249515514f8e18713c2a72d8949de781c698e708deb35448ca1df99b8e09ac4faf694ca71b7bd41bb7024c0435424831424f680a77f13506a56c97b6966afac4b90fe60bf5e7507e6a7093c47b5f8ca47d86c767455d645c502d82cf5b1ccd8880758bea855dc71b1c98494862030202c06b935125654ee498a7e7f37254084aa1795484fa77926c8b438592f4d7baab58978329cf12f461b1f93aacc7117980774e12355af27e506a2ac63c4abfe585b2123e2404b9ea9753fa101604663d07e153c07b743b23c56b86a91ca34111803a1f5865e47807c012a81885104495499884b495ea3f457a2ae1363221b2a94be84e27cc9e8bca44f8fbb92746821782b3b92b1bfe87127f34076bd4acabf60e4f9b97a8f63008b584d0221af927c67d616bb9933be9486e38d7befda11a27175f670600041a6dbf0c9a4364b3ffd28eceeb0c8077c3aba19c6123a20ca72c0776aa8e21a582168591c7c1eb146ba820c9ea1aa3374625c8744612bcab37250ffb34a89d305c35169660dc9b09f7c960a4c4450b1a2e56088e8605fd75a35eb620c3c90b93fb001e03c006a15b67136ec1c354d405a61014821fa9590dd212cc6095dd011bd8801a10f08f15da21c14cacfde606ca02b7e2e1483e3514cc6bc88c2987587458d77851e476aea14a94c176a4eaf865d58c033ba2280ec0521bc53dcc3772d48258593a5a1f9974228652b8cb4a08296eeae869c733a316d926d400cbb09a2daf532da06522da9694cec2a29cd4c87f6a6c837c6ef6182a30548afdb807bf447953a3827db3122bcc7e33576a33a943492a61f3625dcf412793996c664a4664b3666c154f90b40c3ec514c4b1a2d265a23b897177342b76c69637d52e356620f468480472923313a658683566dc8f8fc1079f248f9d8ac67d4ca703339ae28a86edb4bc21db231dfa970249aeb1e2138bd4791352151520a73b0792a0e77d4967bc8b46740cf5599d4056f382c9006b79938825dfe2806cb6afe7523d940792782d978970256c691434f939b02c14f42b1874087ea68917c2f3e31315e2258194391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60 + +comment = Official test vector 4, seed: "edc76e7c1523e3862552133fea4d2ab05c69fb54a9354f0846456a2a407e071df4650ec0e0a5666a52cd09462dbc51f9" +entropy = 66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 +expected_public_key = eb14cbcb226951857be4b3bc2a1b578b148e824a2414412a3d57c8213793c418bf2e0803de4a16eb9c8b5d53718d38ae40299b89793f14741792bb10d9c21d5f06633aa3cf1cc78d0dc99983076f8756b2f96b2095e0b812160fbb9494038a88057671dc692f14a956d5e6565ff752d28237c70b8f8528cb1a04cfe5e6495bd3b46a3264fd7364e0d54f2ad27dd27b022efb3d3a632a7f99551bc3317250207f2658f363164a9631a34b468e9b3c9b34b27a3a02fcbacc516469f69b3a51554b93e05fd6dcb098e8af8a3681ce89548ca311e2f5421ca1496a532366435cfd56a26a245ba68655db99cd113c1ad1170bab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b302c037bab4954627a2363020c4ab5ceef5aaf2e352ded62fd6a52acb70c84723a527ba34f179204b26ac10692822ac66cc56bfeceba65c33295fb805c596a48a0c59477405c21ac3edd2c27e56c19bc84d710584ade48647c681746038ac74ab73591fde872ccdfbc3cb1218fe12acbfec9248c00e19424b1fbca70fc5193151aae1415416ba2d7faa6a2c745cdedb94295438bb182dadb77182b2be5bd1ce0cc028b7eb71ba8cac8585cba3ca01620b63fc91bf3c210f67c65c92f893fc616158c104a5799720ab0fd907798f0678746475c8502029865dd653209a39c0c362258a266b1b244a4f42b4adc1c6bf602fe61125c3b989c018c0a0e0c73e35abc97c9ee695cd265909af82548b865eb4238376a6ab53a6baef185799489f64e200fb542ec3d1b42e8b3960e02730936d620360ff4570b4079b369a83629b599e7b27ff48c37f727a4f93bbb2d4b7e1c73fc0d6668e53c1efe0a0b547b1f38c51f4001654f45bf0e5766ca1c662f2cb99a6bd42a17f89c80a4db03c990a81ae9487e1a52c13720266083e152061aa08c03a7a703de58251f129546a42282515a3e27195ca97ceb39b00566cf4acadaf320d5c88c75ff310f10bb5ad738d38aa47c945235e1730b6cc227a194dcb04ce046a22c37319d910060b594bf8a64f2c4b8f26000031948046721e6546893a341ed2c32804149954e3788ea5054c51a43da89f9c789eda6727bdd4be32b15d47b9c327ec68422813b00950bd73c96c7175274a5ea8bc128a7c0993031b4e8a5d3c074d2d1abde8239d5af58c06509b24109c84297e3feb447fb3926dc19f39211119c4597711a222b341cdecb0698580e422a951db2305d4a7a871967db945a60439de206955c371ea52452f865da438130d2b8eab3669a97911258b08931a2e36c6c390b6845e8076a0d621d7692971ba71bda0b8aaf7ba0ad3c4f05ac23621a146c68bbc501854062b924c3a64916a1b9b19ce5b466f8672ede621ea987f83495106dac22ffab6f4a5cca797587126ce50589f68a2084875bbb505c7ff46922eb496da260e3719cdb2f23950455dc8d36e3932518bc11bfcc067ac533360b86550b6ad09e93dbb092be410721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae1907adea5772276b2929b9507db5c06041e5f9846506055417c6fa091652a4a424bf6396d46365bb40601e3a55801b93a1ccf39126ba7f025a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495a +expected_private_key = 944ab695c2345bb67894d451ea2a5c92561a5467c769352379950879899c9cac9d05e89cb2729b2bb47724923fca357623c69643569d66912b2f9b3249908090d4c5f68388a6141163c931df430d70290950b07de410af913c0e5a215c3059785ef05b824545aba0b95e7279d1c5726b59890b82131d5c62e8b3be33b8016ba0c321c248a5293c71eca570c9536f958b84663b1dd5bb6f272c3e201f014aa3ae05640ed92200274d45d9bf4410ce8ea72d680ace1eeb04cd8b002de72795db60681bc9ecd387fcea796ff7726fb29877f895e6832eb7eb179a5956499ca3bcf3283fc8489d494a88668e6614b1f49824f12a448b31a42861190ce3a9f73c6ffa25622d7a504e0694bb7c75ee71cc8e718ce9d57ac86a11721721e6181f157c333ae098f8a6823f765b60f0300f4733cf65240c779569620213b8a331731a7b31937104becc0995ef57255261ad9b246009f855ca82af2001b256760c1543074d70b3c578279b35137e16ac2089a4c60038b8671d308964b68a2211187154746c27f59c8105981c8c7d0ad58717978c01a66b5ee1697188bfaac9b927822c940c5380409f38459f5b302cf7dc9d6bd823a0308b0da45c35d541d2346bae4173fb0c677eec26a94c4158b28d4d7b4b0f62a4ab06bae0b42208b099a174bb4c482c7c321aaca49c4a517114a5cf408750e8588545134f83a67769cc6e0b413bb800c04093184625a7ee24134a721d5fb1571cd82dd1d7c5f9103e0c2c4416cb775aa28df48643084b391dd2caf39278e9a31d2254871b170ae1b60a4e39b1f5a8473f580c7153caa1369d8e9ca381660a57ca8d2523202816767ca8cac0914c16f1cec8ea4ea5da930e0403e7a876c390ba31fa250d946a2eeaa479888011db7942f7676a120338357bca38c4c95088a4a0884b8b4c14e9c09e831f8aa658ed77cc164124cb281f61856bd6c965b6b6cd60b1b1034888f3970555443f0f5cc29c800f578806beeb4730ab9af4b9beb89502ab48761e188cb9aa95ba06b28cf4b89c200b2145a4339a53406b6790a518f54902eba0230a8c2a45447125b7330f12645d935e00651cb4996e395543b7e643137abf3df59e042abd6fa11927062d73d0a107ba6fea0908ff6759a972c11e864ee7393254051bda558d4b272e6cb2c337747a7ef46f5ac872d5d5238521c09e21495ef98b59c22961e5a4967370efc4865f06a72a41464d37ce4dd1803bc117888b681d35195c857a47b764c6799a86e27327eb0403931e29f90fee8628aa43b333615bc0f251707024ad41a24e3c4f15b99e72f536dd989c0325225dc682e3611640d99c1552506e687e18a883f90882056c14385bc08be82616d811a4fb2dc93670945b7efa17593c4b7bffb76f9a805f5230c50b065dc77b409ca8cc0b7190aa61614c528af2d1ac130c19e4362e85a40693a87c00935a887b9b58699777453d8278c445bbc8d225412bda6fdf026207e3b207613d2ed74c085707edd555fe4c00b40b2a83aa219cd643f1d83ec0fc21bcf94fba6a8262d959c9fb345f2221082c40a1501c46c55082db2709230b04090558cb6d6815173525725d8cc0bc93c881c99a16041757d6a05ac71a15e887eb14cbcb226951857be4b3bc2a1b578b148e824a2414412a3d57c8213793c418bf2e0803de4a16eb9c8b5d53718d38ae40299b89793f14741792bb10d9c21d5f06633aa3cf1cc78d0dc99983076f8756b2f96b2095e0b812160fbb9494038a88057671dc692f14a956d5e6565ff752d28237c70b8f8528cb1a04cfe5e6495bd3b46a3264fd7364e0d54f2ad27dd27b022efb3d3a632a7f99551bc3317250207f2658f363164a9631a34b468e9b3c9b34b27a3a02fcbacc516469f69b3a51554b93e05fd6dcb098e8af8a3681ce89548ca311e2f5421ca1496a532366435cfd56a26a245ba68655db99cd113c1ad1170bab16a22bb3399e45c6a9ba45b5dc5da04a426c635c844744c557af7e49ca12437cf455b302c037bab4954627a2363020c4ab5ceef5aaf2e352ded62fd6a52acb70c84723a527ba34f179204b26ac10692822ac66cc56bfeceba65c33295fb805c596a48a0c59477405c21ac3edd2c27e56c19bc84d710584ade48647c681746038ac74ab73591fde872ccdfbc3cb1218fe12acbfec9248c00e19424b1fbca70fc5193151aae1415416ba2d7faa6a2c745cdedb94295438bb182dadb77182b2be5bd1ce0cc028b7eb71ba8cac8585cba3ca01620b63fc91bf3c210f67c65c92f893fc616158c104a5799720ab0fd907798f0678746475c8502029865dd653209a39c0c362258a266b1b244a4f42b4adc1c6bf602fe61125c3b989c018c0a0e0c73e35abc97c9ee695cd265909af82548b865eb4238376a6ab53a6baef185799489f64e200fb542ec3d1b42e8b3960e02730936d620360ff4570b4079b369a83629b599e7b27ff48c37f727a4f93bbb2d4b7e1c73fc0d6668e53c1efe0a0b547b1f38c51f4001654f45bf0e5766ca1c662f2cb99a6bd42a17f89c80a4db03c990a81ae9487e1a52c13720266083e152061aa08c03a7a703de58251f129546a42282515a3e27195ca97ceb39b00566cf4acadaf320d5c88c75ff310f10bb5ad738d38aa47c945235e1730b6cc227a194dcb04ce046a22c37319d910060b594bf8a64f2c4b8f26000031948046721e6546893a341ed2c32804149954e3788ea5054c51a43da89f9c789eda6727bdd4be32b15d47b9c327ec68422813b00950bd73c96c7175274a5ea8bc128a7c0993031b4e8a5d3c074d2d1abde8239d5af58c06509b24109c84297e3feb447fb3926dc19f39211119c4597711a222b341cdecb0698580e422a951db2305d4a7a871967db945a60439de206955c371ea52452f865da438130d2b8eab3669a97911258b08931a2e36c6c390b6845e8076a0d621d7692971ba71bda0b8aaf7ba0ad3c4f05ac23621a146c68bbc501854062b924c3a64916a1b9b19ce5b466f8672ede621ea987f83495106dac22ffab6f4a5cca797587126ce50589f68a2084875bbb505c7ff46922eb496da260e3719cdb2f23950455dc8d36e3932518bc11bfcc067ac533360b86550b6ad09e93dbb092be410721d48bf56b3594b93cbecfc785a5852b598425e4c4cdcc7cae1907adea5772276b2929b9507db5c06041e5f9846506055417c6fa091652a4a424bf6396d46365bb40601e3a55801b93a1ccf39126ba7f025a2467f6d44de229c527f6e4e7071cb826cfe76fea483d9163eaa84f6afac495ac5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854 + +comment = Official test vector 5, seed: "aa93649193c2c5985acf8f9e6ac50c36ae16a2526d7c684f7a3bb4abcd7b6ff790e82badce89bc7380d66251f97aaaaa" +entropy = 7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 +expected_public_key = 86b5c9a75157e73ccc2e138518ea98a246145dfb6bac9b2ffc333c0ba5806047ca9ba8ab797937000270e773c9863709e59786f8ec948ed27660aa3758e33f59140e527787fa74a2ce22a4a8f3037a26903665cbfe8a0677ec273f590d64c97f69f396db78448535746b43296bfa2bf0a251bf986a524074c1f96077f5219cfa9124d1458520993f627aa8b7b6a0f191683233e0ba6bde24561a666fd10151b0c52c9982c301e0970c3363de27825a5bab078848aa5cb75a90c1cbd24cf67a68f3417780cca947131e4573934f9959787b6320a4b47bb311048289e2c915e35344e3a144e2708893138a15a03fce3816945464c229c587093b5cbbb519767fc65c078d6c684b8b81c1f9cc2b3ba749fb3074623e3c9124a8e1a513510357656b37087bfd02773fb59157eb885e1501740483f3ec070bd492dfc217d7db99cd7c9d57b937297634c3494deb585b8c93cd4eab1865f8a9c8bb15dfe583c7dc0427274f8df3c693fc351289964a89a3c745967231261d949552e0809ba9b7c5d258af579a4515981e991d93154bcaa170491b06752415b1d52bc2a98b7f39c5b91a87eb759a9a4537218156746930a347a5026911adc0412f10a7a7c200a1514d500805c10a276c327e4899aa3f9b95d1ba2347e0140184b1235a719e6c4a3011576235215d77084034771129c33199b70774b2130898a0c69d8f39c3a50b273c665dcd8031b4454d144a4356b9c2b16641311856cb65466991b06d1a8a74a5aad6b5b935b65dba8374ee690cd1c701a5a28b41732b5f88a9ad919a7fa563bafb529885488f544e1240b3cd673f94ebbc91b4757444a302578aa953161993cc918216bc56ba53ea17664bc5b543a38c3516d4063c35695791d8821240bb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58e507f8a105e2f71f6095621e354b3dec1f9c979ed7b3aab56b4741110fda601fac78c2edc386669118a425c634157875f61adf10c43d2184d3252edeb11a61eb67a349405ec74b9fd307558a887efbbb46c904f9469db491605a3582be433bed57363426055cc4852acc0317f24d89903a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5a0029c1513d5a1a98eae78713785bd4322261d90109a0806e565ebd9308849cc6708b536c83a2fa35995c819d99b850251c1d50ea902a053c7ca31faac37bcb1b40d6123cc4d52002909d0ac566f7d75dc89998036aabb267c5aa70184ab4cffeab018f195f62879be0a51b42b843caf7c494c181c2f06866cb2287a00349ebb136747da52a3c4a3c581798c413929ce3e698fa594f019579ae329a22d4af66f27b46453f22e61aa6ec5d7d854ff6d3c3d4117be2145b5c2ba7a57ac968a5ca43b461f808167fb5a76a942c95145098b95cd46439669c00366960e2162ab613c5ecb151359b093c27c04ab230fa7c0074684996f44939c81fc31373c8231bd0b6679991a32a031002b257b2f31101317b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659c970f94d0942124c17ce3ad50d5a7019146bf51b012d1cfa0f59b220a795dc6b3d7896aac680adad383ec46762b669d35909a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc9 +expected_private_key = ac65af9fc8b905d09638374e58c551da08ac4ef86a8ff04489ba462841a85d907ed0c70e1a790297ab2df7d6cdfc5c6af513144da105dda2c75f00736dd91564a79668e335fbdca1c9d31592e73d60066b959a2fcbf55474f9c21bf058f021457586766fda4fad521f64940d4932b07ad8ca7e1a06662730ea6c15aa1c2f9662552313176af04fa4a98962101492566adb8bbc3ec04f9cab9ebfe5860f886d57a2c73fa050a3607a8c0998754b417c9c5ae2fc3f829cc3a2ebb1e927ae87b68c6db355f4c661cd000d10d6bc31ca1c249a9b3931a4d1c57904dc6df923839d9a90aa2b93a87c44b5f82e6a925d22e679428064ffcb9621067b75477fb7d51a1d3b9d9de4051cf874ccec12976562752cbfcfc59f56c2c60b8b4610a9bb36e9019b974502407d57289726ab8a38d7a6c880074a5686619abfffa5757dc79e1449408851502beb8196f493f4a724b9d681645a07b193586c5c05d8d10e2c968bd251b88691c368dc18cf8270dad3c22bf5093db4cf05668f8c6315c0ea3f55495e784ccd6055ac451363fd77a91686ad77c5af53141eb5e7534fac4de481741e48b414302e4743789e250c39c45c0a15cf42e7b3631b6a8c0971c8a34b8200bbfe11004ab06bfc5949c3615b02947c73e7a0717c6b60f2679daa21afe4c55768a08e70105868aa6ab4aaa848c79bf125883907b9daabe367afce273e2c168aab02acd27855e2944b67b938170a9258f67397770136e466758c260ccb7da226b5a95692514727fd48953c62959c88c8784a8a52131c4ba5a6d757b4311048b602b554e8ad509b0c12b0a64553cd4270ca92f36cec227e16a217c769a2bc1aa6c356a5a39c69f4963ba6273db9232f1d8a28ce65b5b9058f1b8a164ab0380c42a8eddb6c2b8b19f26b557c387e4db9aeb92c4d7d0a2ca1e35f97e05cf590bc511ac5efb2357e70525bd027b36c6781c4b86b0069e7b89c8ca643fb9990ecab2cc5a8a5a5b2b0441076ce934d96bca9ffc10eb6e7bb093675e97b68894bb030581d89123642c1118364115a76ad1c181eed4b691bbc15df182dcde00c71f8685b71883a184396d3475cbbcb674360dc14c42dd6461514479c85557194a97a654c4be7620fa84c59db5057a0886d760460cc4a3a713f4fd4bdebaa93b943c48e6348053703ed818fdd9cbd62e246c0b69a265aa381822d6a474c5aa530aa5306a0c8572c413718a278194367405789e1f749ab4a02af87b362067f3da12ec01a83acec26a390cb5419b351bc95e08c7338fb933b81476ea950881275a186c9e9f99dab63634e6b7314188bfd686d74ec203b71542b62b1c0c7712745940f7b9237551467470e5b1ba2f8e34cf585adbaf980317c9db1147382946c12223c3a45973b879a523855bef121151bce620216dedc6c3457ca03951ff45b662f79a1a7a5cefe9a846dd5774c7c2a22f842e4e465a94314e036bb55a2787a1a0f0f111143872dae74af706a369ca54259b80578bacd497700871842b98cae2ac3b572f98f145cbaaf54569779b616242060b30b2a482daf335c9a502cd318296958c696f7080c7a3926c7b62f36a5dbfb87ea0518358155e8e94390b6c0f808b91c166577037d86b5c9a75157e73ccc2e138518ea98a246145dfb6bac9b2ffc333c0ba5806047ca9ba8ab797937000270e773c9863709e59786f8ec948ed27660aa3758e33f59140e527787fa74a2ce22a4a8f3037a26903665cbfe8a0677ec273f590d64c97f69f396db78448535746b43296bfa2bf0a251bf986a524074c1f96077f5219cfa9124d1458520993f627aa8b7b6a0f191683233e0ba6bde24561a666fd10151b0c52c9982c301e0970c3363de27825a5bab078848aa5cb75a90c1cbd24cf67a68f3417780cca947131e4573934f9959787b6320a4b47bb311048289e2c915e35344e3a144e2708893138a15a03fce3816945464c229c587093b5cbbb519767fc65c078d6c684b8b81c1f9cc2b3ba749fb3074623e3c9124a8e1a513510357656b37087bfd02773fb59157eb885e1501740483f3ec070bd492dfc217d7db99cd7c9d57b937297634c3494deb585b8c93cd4eab1865f8a9c8bb15dfe583c7dc0427274f8df3c693fc351289964a89a3c745967231261d949552e0809ba9b7c5d258af579a4515981e991d93154bcaa170491b06752415b1d52bc2a98b7f39c5b91a87eb759a9a4537218156746930a347a5026911adc0412f10a7a7c200a1514d500805c10a276c327e4899aa3f9b95d1ba2347e0140184b1235a719e6c4a3011576235215d77084034771129c33199b70774b2130898a0c69d8f39c3a50b273c665dcd8031b4454d144a4356b9c2b16641311856cb65466991b06d1a8a74a5aad6b5b935b65dba8374ee690cd1c701a5a28b41732b5f88a9ad919a7fa563bafb529885488f544e1240b3cd673f94ebbc91b4757444a302578aa953161993cc918216bc56ba53ea17664bc5b543a38c3516d4063c35695791d8821240bb749caf98896c4718a9db33c1a7e9b91b9b6d06fbaa58e507f8a105e2f71f6095621e354b3dec1f9c979ed7b3aab56b4741110fda601fac78c2edc386669118a425c634157875f61adf10c43d2184d3252edeb11a61eb67a349405ec74b9fd307558a887efbbb46c904f9469db491605a3582be433bed57363426055cc4852acc0317f24d89903a918875c949556a6a458fa3cfb5797d6a3a68ee9991d97a38e16b9a727c5b2e7b5e5a0029c1513d5a1a98eae78713785bd4322261d90109a0806e565ebd9308849cc6708b536c83a2fa35995c819d99b850251c1d50ea902a053c7ca31faac37bcb1b40d6123cc4d52002909d0ac566f7d75dc89998036aabb267c5aa70184ab4cffeab018f195f62879be0a51b42b843caf7c494c181c2f06866cb2287a00349ebb136747da52a3c4a3c581798c413929ce3e698fa594f019579ae329a22d4af66f27b46453f22e61aa6ec5d7d854ff6d3c3d4117be2145b5c2ba7a57ac968a5ca43b461f808167fb5a76a942c95145098b95cd46439669c00366960e2162ab613c5ecb151359b093c27c04ab230fa7c0074684996f44939c81fc31373c8231bd0b6679991a32a031002b257b2f31101317b3e2b6b28b8911e3991479444c6086110b7a70125ca71c6659c970f94d0942124c17ce3ad50d5a7019146bf51b012d1cfa0f59b220a795dc6b3d7896aac680adad383ec46762b669d35909a47c12dc8ee619e1a0c8915822d574a243f67e14104d4f021cf95bf33271c9bc962e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082 + +comment = Official test vector 6, seed: "2e014dc7c2696b9f6d4af555cba4b931b34863ff60e2341d4fdfe472fef2fe2c33e0813fc5cafde4e30277fe522a9049" +entropy = c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 +expected_public_key = 05eb362461c4a2e81885084505c3862c3b647d181805205ef3e4ca5c30c46a0c21eb97700b70c2bee78d862b3e19dc1e0cec0ae6998a7b3c4fdac39a950027fb2a3bee027a8e54b4a5b981bba01badc0b5ba6a36a2913f1c1a046036960790ce2cf2583e6c62a778290f242b49606ecf24b3a0dc023b22ad8945a0b8dbccc9356475b36b2a990d7435b12e1536a21079fb7802b998488e690f763646c3b66adfbc8161855b20ea18afd87229d05e60372694e4c4c6215344da04173559d7954b029555e6ca4356f6cbe325a39431a64df06e75c63ed0e40bb0cba6ed68bc7211b02f1165c370ada1e0acf4ab61c87cc32f7017b4a26ff8cc0784f76047316af6398ddecc0c62e9a37fc4ca685017b33aacf597767312192cd330b2f3a84e0bb858480a63a607295a39f61510dc2c6998614013f45d319858da8228fe5bb6eaf3b03aa60f4b721a3f046d3088671930672c61c92d6005254372d8081be322ccead06cdd472cc5a481ee385096a5b8ce64b57781cbfc4457e917162da007bd7bad8e3803e05b08876842d9e6a0a545407a5067ede3510ccc4478c040310aaf46051454d855d1a5521e2514af676846650e0043bebf453e7488b6db8aaefcc16e26a75c52bc0ef3c80da3bb39f73b9852b54d9c606363438c45dac4ff1a1913d81b9a80544177ba7db6503a04a5405299f80a83fb7135fde04f8cecc0962461c0e80298d219531c9cbf00a3bb5b84908b5a807739a63485128512c0478084c8964f9064cd4514ce92c30454ac25b48919b719c5a853010a2eb712b80975660456562c4c448c39162ca63aed14af7f28875149857f9b8965bc1d04cb8ee2e67c14a493a3822fcd0a2dba2677e719b8f2c8bd09431b82ba56007584beeacaa1f081d244b0d771bdb0c8033b18ca9597443ff8cdf754569dcc2dc4d4c212e2bbee88925ce73034e19167cc7ac46059cd3b9ebbf6bc3a476f08438c61971af139a248821002480f42c2b9c0979ad3bc6868565ca3fcbc124a7548d53f56b51c9f8aa387b59b07638c7aa45704420b3c24642035a7884cb42f877260c29697809aa7482e3fc356d8ca061c1c443cf24c4535bdeccb02c3e3b8b1d90e5b47bd11615caf849da5811aa743b9bd7810c470187e81af9bdb4d1307303f615ace2a58e7ecb3be260e9f7c1e10eb3a84f207d2e75a30c7c741ea45fb04a9473c1425f80a9186a7f2625ea6abb4aaea3bb50602df23acf8e452cc01a909ec9034acb47b969d904213f0a79edb7766d0290005c954a1da0155f7318be854fdb038d019c1904b714f0514ac331c3813bd703b45076365be4b47ec510a9f585907bc0f461a6befe13a2667593e12134a86ac139777a50ccdad16b6891a0871621b387684b5226368400164b29109328f672cadadf7648377cd11c9232094165bb1cf12f694f940c3cd784c84925ba74c8a49dc27cda4c553c85334a860a8a55d8a75969977ad1f505b9b20ceeceb24a262c707843310f39434390ea5315a67491f0592bf722a1c2658c8a720991b26561e14b178c3a1028003cab8b69f60828f47b876d43d3f193c3820804068a5cae76dc3f27f5f1323e6a2797b9a13c86713a83ba9c161899cf295cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f +expected_private_key = 67a93bb27acd00c9b95aa03552809c38a08480dbaa67a9584a460345e20e5f381c9a82710ef1709ca51393f916345719bd3144b3121a8608c0a48017963387f7a31c5febc6b6749e6bd9be3c58a9a77b53d7762f5854a3467a85941ca2c03873c0458b940275e5ab85b83a5c2027894b92246dd8632d68a310fbc6d214381128528b375fbb8c3c7923ac6a8c7f9e37c2ea4c6b72e3451922761ac274b5cc8569ccb93917a748e93c190320e3f1381e08cccca70903975ae25689c12709c8e9096b16a26e4439c2552a088194368b36efe3871a6a1cd54ca0c70974ac936e45dca01de296a14c7d20652999e61841dcba6c0171fcb406e14a95b0c02517447bb9370996176bfdc5beb4316c0ed34a13431e34ab27d9dccd3ddaa49d314659bb8d89325099d0b06931796ce65c0628c817393bb1870f19a10cfe3546d8bbc2509058327626f490a1bbca6fbb653ee1c3555203353509ab14b64cf8a29c32b17096805b8d751848dc4494279266f2cc474228b2b703cff81f0f29152f4570151517995262d705afffc08dd413c12f37b605bc32ecc1292b9ac99e4a34f911c8db990ecc9a3dfb37517446908b91b1172a3d4f547b3aa642709ba40c3939734545ddb6b45c66a1a3e58c6d1929e5721bfc6a6021a635d86c8378d4a0ba68ce385b6b7fb983ec4a95c8b20b3ec750b082bf2cec89a6f8c2881650e5b71a0135c865bb3fb12a4c2c3c917d655a2997984c8557ecf1943436a9fecc5c84808e38701cc26a251f458334f59bd40bb0d8f82e74071a5ae3c9439541aee59c6e46a5852834ce5712b3665018154c5339467d606af189ccf20c68c583c96d969815109cd3ecad4f5ab0a8bb8a7b68359b0319078a7405821c2709a615864422ba0a3970c8ea138ffc1522b1a53ed1c71d396a0ed6b782c6552c70216679bb4761a600634276d553cd703897c6943a859112caf9a7ac99517c23ce6457aa069b6fd2775efb262dbc27b02fe6923d14b047a25cdc6b86d20a55d85108ff276f121a352e098e5d4cc3ef92b3a1c4a38244621b055d5f812189f6941b492330fb1ab0a442a656655455b38b522ded5640cc4136df6cbf4c4b0651531cd8c95280e2af13fc57c977bbd1a8bdd253096ea98c3ab33a516448a8301a4b141ae213bad2f640b2d5846c99a25884360f604333197816ba9dd1d0c427c5b8d3a6b434207b8539ce5092ccda67a755d6a6d7e8bb6bb02af1ca7283e797f24a1042d29b64262f29b0482b840bd70a3d6d54205df412dd6490e3dc38c1236758f65e461b11ca480b476875c692508e7bb90c430797e1917041642d88506c07255aa92ea32508462c2f4a1661c05114c9361f651b7c5ff70b42659ffee71f58cb79e445536b8948142cb4ec16cfe5b21da659c2dce452346323f1632c37f128a6525f40e03d6c073e05476252b2b0483c4b87c1c1fd8c972cf651eb9684fafba3f862c8619c089f01277c14be7cf7790712ca1e8877a48909efa31d814c1c21f4a151b886076840546419a1c8b6ca4466389a3f6dbb69e8494d7b25a4e9b234a8d928a26b946ff305b8a33b0bf8b3eb992d68c312b4074788e69d1a5a211c3b55f8c654ae778fbada1d75fb2305eb362461c4a2e81885084505c3862c3b647d181805205ef3e4ca5c30c46a0c21eb97700b70c2bee78d862b3e19dc1e0cec0ae6998a7b3c4fdac39a950027fb2a3bee027a8e54b4a5b981bba01badc0b5ba6a36a2913f1c1a046036960790ce2cf2583e6c62a778290f242b49606ecf24b3a0dc023b22ad8945a0b8dbccc9356475b36b2a990d7435b12e1536a21079fb7802b998488e690f763646c3b66adfbc8161855b20ea18afd87229d05e60372694e4c4c6215344da04173559d7954b029555e6ca4356f6cbe325a39431a64df06e75c63ed0e40bb0cba6ed68bc7211b02f1165c370ada1e0acf4ab61c87cc32f7017b4a26ff8cc0784f76047316af6398ddecc0c62e9a37fc4ca685017b33aacf597767312192cd330b2f3a84e0bb858480a63a607295a39f61510dc2c6998614013f45d319858da8228fe5bb6eaf3b03aa60f4b721a3f046d3088671930672c61c92d6005254372d8081be322ccead06cdd472cc5a481ee385096a5b8ce64b57781cbfc4457e917162da007bd7bad8e3803e05b08876842d9e6a0a545407a5067ede3510ccc4478c040310aaf46051454d855d1a5521e2514af676846650e0043bebf453e7488b6db8aaefcc16e26a75c52bc0ef3c80da3bb39f73b9852b54d9c606363438c45dac4ff1a1913d81b9a80544177ba7db6503a04a5405299f80a83fb7135fde04f8cecc0962461c0e80298d219531c9cbf00a3bb5b84908b5a807739a63485128512c0478084c8964f9064cd4514ce92c30454ac25b48919b719c5a853010a2eb712b80975660456562c4c448c39162ca63aed14af7f28875149857f9b8965bc1d04cb8ee2e67c14a493a3822fcd0a2dba2677e719b8f2c8bd09431b82ba56007584beeacaa1f081d244b0d771bdb0c8033b18ca9597443ff8cdf754569dcc2dc4d4c212e2bbee88925ce73034e19167cc7ac46059cd3b9ebbf6bc3a476f08438c61971af139a248821002480f42c2b9c0979ad3bc6868565ca3fcbc124a7548d53f56b51c9f8aa387b59b07638c7aa45704420b3c24642035a7884cb42f877260c29697809aa7482e3fc356d8ca061c1c443cf24c4535bdeccb02c3e3b8b1d90e5b47bd11615caf849da5811aa743b9bd7810c470187e81af9bdb4d1307303f615ace2a58e7ecb3be260e9f7c1e10eb3a84f207d2e75a30c7c741ea45fb04a9473c1425f80a9186a7f2625ea6abb4aaea3bb50602df23acf8e452cc01a909ec9034acb47b969d904213f0a79edb7766d0290005c954a1da0155f7318be854fdb038d019c1904b714f0514ac331c3813bd703b45076365be4b47ec510a9f585907bc0f461a6befe13a2667593e12134a86ac139777a50ccdad16b6891a0871621b387684b5226368400164b29109328f672cadadf7648377cd11c9232094165bb1cf12f694f940c3cd784c84925ba74c8a49dc27cda4c553c85334a860a8a55d8a75969977ad1f505b9b20ceeceb24a262c707843310f39434390ea5315a67491f0592bf722a1c2658c8a720991b26561e14b178c3a1028003cab8b69f60828f47b876d43d3f193c3820804068a5cae76dc3f27f5f1323e6a2797b9a13c86713a83ba9c161899cf295cfb4a4aa443f32d16b72616a0db4d3849fc41a7a6ba87f4af757a0ab1956518f0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c284ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96 + +comment = Official test vector 7, seed: "aefb28fdd34e0ab403a703b535296e3a545ca479c1d8148e2d501b3c8dd8b1034bd986f13f1a7b4671be769359fd2aab" +entropy = d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 +expected_public_key = 89c28969078e11664ca1554eca81b9542bae2ea8cc12b44e81b3354818141af0b494543d4674160a086f7e8755a87258e7e6a6aeb96955286924b42636e04583f74184133d8acb9067925f4969642f274085f70fc12361ff96c3130b143e23797f2a3a6cc757c97454cc8aa5d9c062f9254f4cc7335b44cb66dc712b4677c290ccbba08cfc3948c535be29f44736a23b4c8ccb3978404e419a08a67aa555becb48bcc161cbc5492b55e3498e74bb515c28a7a44a3afa0148ec3411d82a1ae103513074a13938a5fc17dfabad006d90455b4b5e45079d7bbe956c7a18a8bec9a64c1db72544cb00c6997d545ac7e3bc5c6565885536af486417e728cc99c78cfa12a1f7697f1ad26efeb7262800ac4e0121e766aa9bf0a74ae635074c62fb6ca79975761419b12a985ed7a2c8788c9020462fb5764c087681be1595a5ea4ee7234aa2d22f4119b559a536e0da0e8d0b2e493c2b5bd576459994acd684a81a0955684818e1b88e348446a22c9143a4eefc7d8ec678624763d4548fe2451f078582c93c986b0417e1aababdd76dc0532e252b59e47370e81951ef75ad48c223316a40237152e3508ec164c7375594f73b5f0483c560f52f250aaef28431e9d1b2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a7fc02eff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968aba093e8f42dd3c7cd68c8028a90cb0c93cb44d42ef9d15e6ca978ed5b88914c4e20768028f2c927a33433d33c5e6a45a6c5ae8c252a83e68ec121347b025865f26912b89a9da7472b75b9aba75581852b97d27ea7c9c5c7e8bebc0094c01947f43a2c6501c97e43231310167eccbc4c3a2022839584a12ad5b51b4cd308c94302e58c70eff7b24faa051cf548b5a73ab4254179eaa038ec95d4d4182d2971084cb33a6ca1106076dfa76ec0c4b3bb5c7266a481001cad07d12051a77e31603bf47c62dbf959c89774587111db1b038ae834e0a08c27f2b772a967179a9bada1ac12bcb8fd3b06ca44b3f11a6762ab51a9a0b67fb83def8c9a712a1469b719f2557e5a03c6bac808d0e0aa304955a3e961618920d0bc2347c74ad6725a9a855d1d8456d2c26addd849e59b7ce7c85765064ed6d63039e368e9f18d4fa11e16f8cc88bb3ffb40b4c6269996da8a6b5586365292b5b1c78bf4161c171e2fc7a6a8293a96d61d683275eafcadfed74473e30a1026809076a1025398b745be723a78e008c85b558d2b76392f5015d1024c171c0fc6c7c0c0e631bef57166e660269231c3216fb08b6cff0a420aa413ec1285b7b5ae9fbb15f9fa6b8af29ec061996a7612de524c7e0724766bb51e1264ab50c3a095815645b1d1021060b90c96555e8a001044d16cffd7719858065efca6c2654ea25506f0541fae242dbb154e420c0dd4e13a79053b431b7c00768bf0f781810a0832a2b814c5517aa1a0949523e12aa35893912256a7370bcd9faa30788b631b87731cc5c831a26e8f48ad7cf9c935301aa8cb006ac59fd2ea5bdc1736b2a5523ff3c4d8f429dc037292e863a087bb29cc2732ba30bf11490dbb1f3adb3448d6110a774b25d242602c250999ce69d1b32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b +expected_private_key = 0fcbac2fd83a9eeace0215c784e20260f0991b225897e94ecf93368b79565b478731537eac74550cd599d5268e03a25cf327606686ab8864677907a3c3555018b478fbe125498652d5259a31c2b4649c14c89bbc5758a9b53c64e95bc9ce30c306372d431cbc642c0d60e25136c3919f3bb48b280b9d5ca0b21bb4e1510ac49aabdf02c9fd66420b475d0731918a4a5d3c7a963a468fb7a86c128988ec36c34f475f2b87791f5604863ba6dca297ee29238ba79eeec5096e9b336cf0b24dbcc9feb8bfd77ac888554472d7732e7492c231302a073680c684870b86a05592355baf2620b51ddc7b17c9328d7a74da6367d9ec2b87e9221c297b5398cfb55c10e8a68323aabbed806c2272c192fb180e7a5b958a02dca5c55654a43c74216b192522bc2a2dc05bf865062cf56839831ebb837a3ed8c7368c15933730667b7463ab7026848bc9ba14616b2e88e17aca4109b5db56510b408465523307619fca752919b947eb40e5e8c19a7b4a9099734d648daac8c81c1c628c895400e245df8a324899273efb441b564305ec48ab305c69d37e846ac9b77a2917915e82286ddb397936769be7e37fa7f27a003090c7f2b9b395a41370b5a38c07c2d8314627267fa06bfc416d8ac1155df645c6150bee70c4cad8c6a5c564ba2571c9bc9bfaf0c2d12578c8198d49e1414cba5749d712556a537a4131f3f085f9047735482e23342b218101ad30122113060cca4196f778c77cad2ee58b6f23071a85b79c1215f0a7c8745abcdb768c3c26042d09a9a0355a5c45745d1acf52c205b949acf581ab75cac74f2364406a43a74269645166fe167642900d169a1e84929da4cb361e80c42dc702a79364f1d664528b6cec667bf230078af06a0b48466dc90b34ea7101512e37d8ba3a351d7023aee652351ae514b8d217faf09a07654b0cba1850041d7206cecb05c8f6703f762c97dbf82255daafcc3608e8891e3ad8b3d4e18dbcf6a1c2e74cdeb87d15236d70943daa722481692890a548d7c69a14fcc1155202ca4941c3900b57a452f281091a94781c64a9583c8d302c21484cc6159b88a931aedc4291e097982eeb0528c152a43b97dea2a0b36922fc60c226b61068c792f377b9f655940d73702d41bc515086e8f9266c53a4c15a35907cb2fc2a2f19bc5f974034677a33b648322cc9bfcc6b947b5346df2044249623e53430895295327c9b35f59ecd4a9521f4b93a4c031a624c12f40ba17b9f36908e462b928ad452ec74b84f9b5c1c69660038c85d6743f8a5a65b3787b5640d683b7a45009a1efcb5e50a35244c9431f21f1b6826311673832ccbc1794fea917268f5323726698f67bdb41bcc012218929649c972149393845dcbac7fb58582964405d4adeb814037a39e512c3fcf72a22ab70e21fba3822b493df9983866412f0439e1a613914042c982739031949b2780d8133e13e632fc4281de567a333c5d8ad458b848ccd65bc87a8b6b29134556a6780eb7b02e4437ae69c09e304210d5cce3ca3dfef261a809bc5dc44787a20afff49f3e0156e7b428ae1cbd3292c9d818844d4767342708e4016eb9bb0f7099876c26729f443e7cb3b9666441dba01c8397953f586e3da45789c28969078e11664ca1554eca81b9542bae2ea8cc12b44e81b3354818141af0b494543d4674160a086f7e8755a87258e7e6a6aeb96955286924b42636e04583f74184133d8acb9067925f4969642f274085f70fc12361ff96c3130b143e23797f2a3a6cc757c97454cc8aa5d9c062f9254f4cc7335b44cb66dc712b4677c290ccbba08cfc3948c535be29f44736a23b4c8ccb3978404e419a08a67aa555becb48bcc161cbc5492b55e3498e74bb515c28a7a44a3afa0148ec3411d82a1ae103513074a13938a5fc17dfabad006d90455b4b5e45079d7bbe956c7a18a8bec9a64c1db72544cb00c6997d545ac7e3bc5c6565885536af486417e728cc99c78cfa12a1f7697f1ad26efeb7262800ac4e0121e766aa9bf0a74ae635074c62fb6ca79975761419b12a985ed7a2c8788c9020462fb5764c087681be1595a5ea4ee7234aa2d22f4119b559a536e0da0e8d0b2e493c2b5bd576459994acd684a81a0955684818e1b88e348446a22c9143a4eefc7d8ec678624763d4548fe2451f078582c93c986b0417e1aababdd76dc0532e252b59e47370e81951ef75ad48c223316a40237152e3508ec164c7375594f73b5f0483c560f52f250aaef28431e9d1b2b9dc650d2371bbb7c8360c72369755bd8696fc5c83fca76a7fc02eff54ca60579caef6341385aeee34c7182445bfdb549bc59f70b76368da88d47386f75968aba093e8f42dd3c7cd68c8028a90cb0c93cb44d42ef9d15e6ca978ed5b88914c4e20768028f2c927a33433d33c5e6a45a6c5ae8c252a83e68ec121347b025865f26912b89a9da7472b75b9aba75581852b97d27ea7c9c5c7e8bebc0094c01947f43a2c6501c97e43231310167eccbc4c3a2022839584a12ad5b51b4cd308c94302e58c70eff7b24faa051cf548b5a73ab4254179eaa038ec95d4d4182d2971084cb33a6ca1106076dfa76ec0c4b3bb5c7266a481001cad07d12051a77e31603bf47c62dbf959c89774587111db1b038ae834e0a08c27f2b772a967179a9bada1ac12bcb8fd3b06ca44b3f11a6762ab51a9a0b67fb83def8c9a712a1469b719f2557e5a03c6bac808d0e0aa304955a3e961618920d0bc2347c74ad6725a9a855d1d8456d2c26addd849e59b7ce7c85765064ed6d63039e368e9f18d4fa11e16f8cc88bb3ffb40b4c6269996da8a6b5586365292b5b1c78bf4161c171e2fc7a6a8293a96d61d683275eafcadfed74473e30a1026809076a1025398b745be723a78e008c85b558d2b76392f5015d1024c171c0fc6c7c0c0e631bef57166e660269231c3216fb08b6cff0a420aa413ec1285b7b5ae9fbb15f9fa6b8af29ec061996a7612de524c7e0724766bb51e1264ab50c3a095815645b1d1021060b90c96555e8a001044d16cffd7719858065efca6c2654ea25506f0541fae242dbb154e420c0dd4e13a79053b431b7c00768bf0f781810a0832a2b814c5517aa1a0949523e12aa35893912256a7370bcd9faa30788b631b87731cc5c831a26e8f48ad7cf9c935301aa8cb006ac59fd2ea5bdc1736b2a5523ff3c4d8f429dc037292e863a087bb29cc2732ba30bf11490dbb1f3adb3448d6110a774b25d242602c250999ce69d1b32ad3702602e6d28fdacdbd2a03546764c4fc1c62c0efb3462c7c88ab8d94e20b2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209 + +comment = Official test vector 8, seed: "cbe5161e8de02dda7de204aeb0fbb4ca81344ba8c30fe357a4664e5d2988a03b64184d7dc69f8d367550e5fea0876d41" +entropy = 0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 +expected_public_key = 764b51d1dabf923518de898c5e7cb5e0066fd69522f5889dc05c41a472c983583333132052a1c93a464120b325764b8665ca42555b98d8d6a93c88a0a383ab51280f52873f2be26e12c131677027c616711d478342cb424b0463c88161ed84bf6e869abe9cb915d13534d2756dd72343359e9911624dc7c6e828b19d6cb178c43a5ceb9360d2939df2744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ec91e52c4030f5453e6bc9103b9c19cd83e69048272855b11b8af3edc09b04ab31179bee59abc76726fbe9612d271b7010844f62535f2f30d8417c35f17c1619b055fab6a0f5458568c753310299fcb335a7697e7cbc9b9eb1b14ac2d0ddb765b266b6d68bdb5b0236895328540b20f91bbd2910625e674b33a4f8b6c1b4f66c4130c2e973ab72d809282ca63edab71268c02a9d020bfc805410aae2dd4b699448a56049d1e9a58c5fc2abe159dec69c5027099a3b57d3a2560ce24a6f5017d32e00f3078b792309384421878cca555b7065d57537c804e10bac052788769b7c1121a78911a153fb56a365a2f97b070d7b61724d0c4d14c295d78be57a8aadb873d3af6b74d020b8654cf48543de8ca22371a48ded585b7073ecee0c44eec27c85b5a68f6b454b0cb10692039cc68ec2c2bf892804520c71be5b7badb807b4059a3d87d32548ba3e4b698ca150d784a8c2c35a67a8c92c68ac0037888b65a4c9800ba7a1ec050627af648fb61c87cc55b8243545aa514cbc550a8804c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6326e0bbd4402dbe26cec08a7c1a19457bc2677f15b984a74fbc52cdce48618d50c47400011b392908ac2cf08a579783a80fb2990cea90eee90b7dd81e6cc9c961372d8c720d7eb223d5a6a16d4571c1a93213b32289934f7b30a63527c6399920086940b7696503e623e63a050f4b69810b6e6f6729e5782b572221f596a09a1879bbb46a62a955043a30a2aa3e62e02ce1ab6f3d03693a8cb653e361d8783ffa37274ae06a3f2292f1a6557182006e493ff2653437a64dbea950bf6a8ca8836407fb489d42a6f6257770310f28715bc6411c81486cef3cb9ab500558f070f4a15817f8c177d63cafb176caf3b2b1cb7b7254c18fe15111fcab9e9a9682f41c9fd247ec532ccef514860a3fed330255323dafe46eed198041d732538c9424d43fe2f5481650470f08906791b2bfe65a445bb26ac87d9bd04aa648a54dc13a137b60e5c2779fe4b5a866620dc2829d42384aea9ab1552fca920f8929b7baa059dea53e6a5b3e492a6e45b5ae11f6ad24d035d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124a81ed4420c87b0601de23e3ccba915faad0c2b47ef6238dba9449274c64ccccd85e91712470e8f9a2866720059a8501c7762c0883cf9827bfd62bdc0882ee03b457be2b2794b8becf74ec0da4684282200a294c13c8a9ff376c1187911121bdd886f27514846f740b72aad5544cbd97a7e208635480acddf404fc067c82a45b5c97829f06abca5201429e9a516f66e65d07075cbc0c60c2a9734baadd68f421617fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f6165 +expected_private_key = a5c7981510819ea27d27a945a0f6619d730dd196b6f3a158a4c48acfb82d1c348540160b0cc665c43c4c0e4567b46867ced06d2cf228d0b64706227593db7392395b7ea95360105c1bb05472787430654aa03b6e894c2add2a0467ea51b9486f3df18274c0a2079459df3b9aeab15d203b466ea426911572251b0c8fb51a31aa142bdc4142e393d3c527c841a03f796e0cf7cc71dacb47456fdd386527bccf6e43013eeb755924a22e3a55f74a8974b38e06908349fb3da5887d1a041c8acc6f07a75198462353942267d7600d5243095bb012d2a70be0a3fb2bb599832f8aa68652846ba501bab3aa574ad08bc991c8b86717b87a45041657d0264f35f0c2b70324eac43d591202cfdb9a7d357489f70f86d6308d3382cf9139106cb28d947ae3bc389ef18b728c1568436b3ef80644009a80f01ef550c794011e44f2812ef507bd55820a872b90e797626b8ef2d94012b4cf639bc5c8a7b87306753f93cb12e46a66c4b2053c037b87c51436cc83b884f7634a6950c419684af3b78d41006467105f753194144539df45ac7fa46e71815f53d2304b474a434b02517b083b058aed078dcf86746313bd8108148ea34658613560ca722a126dda147af8c5733705bc8343331bacc5b5b80e424ccf6114955056329a68a2a6403d65197c21da02a390c41ef713a814a798a434145b9e3a5c31a9614cdac8a8bcab6b5274490f5c45b2a307f492c28ff40ee39c2068a5826e8466542559e9409ff11b463e9a4eba0a2172ec8ea6332d3a5bb66531b670c52cc2f8b651b513e60a9e64795369e0c2cf56a9921669299b6b5399537e112ac358112810abc6945bde69aada92552a10219a630e26e4ac7d9b5c7469a960ac64a6d127971296c53a15df4c847d061e69cc030b9cabc6e58903c5adc88882cac147f2888263ecb6ae97a9b2aa245f131e2e2939f5c8bb8ffc012cb578b9babf90db062502b1923ca88b35c424fc6524128fd1d7b5ca719f5a9a538a51a97ababce07b006eb701ad8490b74462f93648fc39a2004db6e951b4c8219ce49395891594353b92b6b496d09376fb28711d87221851a5fdab80cc52a6352c062f06c80f891da2a07573b42bf0f6cd5d6b63fd4b1c5bf2572fc8460385a642e6290fb79a9b1cb18cbcb34bd87f7eb595f0598c67709d72011fbdd07a0eb6616a88b8e33571bfa7597be4cbd6976b93e32c2c088de3ab59dcf2234e553a5b2ab143c46df13211e816aed6d02bf6c13fa7f8b282237f249aaedbd3a6fe8771014c1b811c05fe86102c0b0e7e9b961c1000c82408d8a8aa381552920803418c49e1662c7ed8c3d35763c510585a78664ea0012a8a02f34b2bd7e96ee5c298dc296537c985577cac3e310568353ec2ca8eeab4bb1ee2393d5b3cdd25305b148fd8ab11f60b5871e9c9359a46a5da003e98b61d82c51cd9262764301c86268db87fa6273f9fa3c35b1c1fd822aaf2f74edf73ab5af9175070bdd7d5cc7600a516726c3e49348d138d19836391a54954ac4a0c029b1441c37965422019c2ca49cfca81317a211e22ea2297b865da163a0ae2a9dc25701e71847a05754cb733620a824f090d591c51c345420e226b8f3b846fd356e78b87764b51d1dabf923518de898c5e7cb5e0066fd69522f5889dc05c41a472c983583333132052a1c93a464120b325764b8665ca42555b98d8d6a93c88a0a383ab51280f52873f2be26e12c131677027c616711d478342cb424b0463c88161ed84bf6e869abe9cb915d13534d2756dd72343359e9911624dc7c6e828b19d6cb178c43a5ceb9360d2939df2744accb4dfe8aa5eca35bf87c6ba265fb4ab7c4888516ec91e52c4030f5453e6bc9103b9c19cd83e69048272855b11b8af3edc09b04ab31179bee59abc76726fbe9612d271b7010844f62535f2f30d8417c35f17c1619b055fab6a0f5458568c753310299fcb335a7697e7cbc9b9eb1b14ac2d0ddb765b266b6d68bdb5b0236895328540b20f91bbd2910625e674b33a4f8b6c1b4f66c4130c2e973ab72d809282ca63edab71268c02a9d020bfc805410aae2dd4b699448a56049d1e9a58c5fc2abe159dec69c5027099a3b57d3a2560ce24a6f5017d32e00f3078b792309384421878cca555b7065d57537c804e10bac052788769b7c1121a78911a153fb56a365a2f97b070d7b61724d0c4d14c295d78be57a8aadb873d3af6b74d020b8654cf48543de8ca22371a48ded585b7073ecee0c44eec27c85b5a68f6b454b0cb10692039cc68ec2c2bf892804520c71be5b7badb807b4059a3d87d32548ba3e4b698ca150d784a8c2c35a67a8c92c68ac0037888b65a4c9800ba7a1ec050627af648fb61c87cc55b8243545aa514cbc550a8804c8598cd35786eb8c6b06077a1e2d4344e4a6baa789c305b6326e0bbd4402dbe26cec08a7c1a19457bc2677f15b984a74fbc52cdce48618d50c47400011b392908ac2cf08a579783a80fb2990cea90eee90b7dd81e6cc9c961372d8c720d7eb223d5a6a16d4571c1a93213b32289934f7b30a63527c6399920086940b7696503e623e63a050f4b69810b6e6f6729e5782b572221f596a09a1879bbb46a62a955043a30a2aa3e62e02ce1ab6f3d03693a8cb653e361d8783ffa37274ae06a3f2292f1a6557182006e493ff2653437a64dbea950bf6a8ca8836407fb489d42a6f6257770310f28715bc6411c81486cef3cb9ab500558f070f4a15817f8c177d63cafb176caf3b2b1cb7b7254c18fe15111fcab9e9a9682f41c9fd247ec532ccef514860a3fed330255323dafe46eed198041d732538c9424d43fe2f5481650470f08906791b2bfe65a445bb26ac87d9bd04aa648a54dc13a137b60e5c2779fe4b5a866620dc2829d42384aea9ab1552fca920f8929b7baa059dea53e6a5b3e492a6e45b5ae11f6ad24d035d4246a0cd53436687a0204a1de29aad2c8b53ad4b938a57c2e29555219544ff64115cba2668b54c6ea8779146980b58a2e669124a81ed4420c87b0601de23e3ccba915faad0c2b47ef6238dba9449274c64ccccd85e91712470e8f9a2866720059a8501c7762c0883cf9827bfd62bdc0882ee03b457be2b2794b8becf74ec0da4684282200a294c13c8a9ff376c1187911121bdd886f27514846f740b72aad5544cbd97a7e208635480acddf404fc067c82a45b5c97829f06abca5201429e9a516f66e65d07075cbc0c60c2a9734baadd68f421617fbf9515b569fd08bf3aef948095de1afe74bbc3bdbb45fd8f92eddbf0c682c81a98f930f616553b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004 + +comment = Official test vector 9, seed: "b4663a7a9883386a2ae4cbd93787e247bf26087e3826d1b8dbeb679e49c0bb286e114f0e9f42f61f63dec42b4f974846" +entropy = d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 +expected_public_key = 5a1278bf11b37fbab1db212359473012f3b545301ddc833c69a75afe16744557b5e28bc0ee895da16c2c5dd34fe6783949d555e580c1be7994bb008daf27a47f554932b87222e82ec670490ca5139ff49d5ed896218825056a8639b31d3ac8550356a408a01404c6aa9c2b7284e7c7c27036256b7902445dde00630d81930f4ccc518b9efd8ab24fc16a365b8068c90f7e09bbd23c2a6ab12792d245551a9894f704042501c8fc49eeaa0132701e29a3c97834530a7c61f1b8440822cd1bb6b11dca2a5951b4deb0b1268c2f5aa8cf76a6bd0be3013a37ca1a903ac634405ecb3714bc54610baa63bacf0a263d8cb018b03b0a286083998a7e8b2a573e570179712130a19f9ebc2337d43926f9c96460996cc03199d81a0e19259da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f1f211c6d85499c46746bb00ba687a17877e6650c678d13861337faaa7045a16b8eb7173e7c08b6394b5f2b99ea3083ba175c55d350fd61b73aa790ca6f479fd4b01282b6baefa00a1946f6dfb855ce7bd50389d42856823301e01a228ac754cb65a0e323a0943b75741cb498cc499c8649b6bf87e991507194983aad1b57994b7d79bbcf2eb3b5f8734ccf3cea2662e95d486989144aea22c94c363571ac7dcd81f577645cf19b313f849b422afed963cdb701395020c2d18601a40a42429896aa9b0b1c10c4876928aeac59862414e143722a0b94746abd157343d15bb9fe500763b18c61b184407449b1b5ba8fb1554e4bb58ab99faaac9cdc3b698e64179b089b786204bf95eda86474ee799440478348989c91c3462446724340cd2376c682907edb58c85a4ce3ef46cc5d0ca345590ab14844b224735dc05e0e66ede94258f395fe867ab9d8c1b0fa80743002a15da197614295dc358f40758c9cc05e45bbc659b93ed611aa58845d94acc7aa75deba56d4d83c640c252975bc3165254c92957b78c9583b370ad785f2c16cd5cb9913839939c7293e6b956e23cc5d14cb3ab2a2e94f179bb076355157920085236f60b84449d43ac89c2b46dafa6b784438f3510bfc48357a5681043ba7428583bb5e912b08786562579df58a41bdb82114344b3ea3574b997f8564248210d4e50ab2277100b9a5423178b1f138e9d427762253cffc3cd095cb53a776f4fe015b5168b1a9759ac4acc77f90c69b307192b7b866753872a69813b1bcaab5cbb8126d8998e78d99f5a527992b89495a28e3fa83e75337ca2b896172ac244ab7e30761c8e3a00890046e5f599eeab65bf1a4cdeb5791cc10ade7197fb5bc754233f3b10c9ba2240adfc61c05231c36a6cf71aa752ab3c95c3756ef9373b677105d11f86e68036348bdd181f27407e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc4872617bdc17a7baa97af9a9322ff015956678e8d622cfb1a11ed929f29bb1f094c17f49417c09c1c443369123caf8701199c43bff97034efc6999424144c9395d9063bb153c0ed82b1c5659bfb23d4cd2c758a26b6c448525060f686bb14873cbf5046b3a3033c5c8081027bf5e3c51f6fb6a1d54a77c46b0ea4299a9da4ab03b95f9d3601f553d46800f661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a75 +expected_private_key = b04c33b257b199352a85b55624f1a1a42b2ab72c4810b839b2bb2f51a502cd498aa258373eb3bd43e03973d129e4fcb61df58986809ec4ea4333659f03dc0fab236cd4e815d3f9524e90a28a3a0af869735b362fed9837855429700cb815c43a6e650e54d6267a832dc0385696274e1e73a12b5960a8409a4b4564de909b797771b4839782526fd69abf516a73f9eb8130f41cd6103a6e67c6724186d1c709d3d90141b1bc1c028e28324de4846bcc6837fc243c54dba144c40fcc6223fd19b8f54c11bc0982ffd366530abad387946e1495a3c05d9cfbb62b28778905ab7d576610a74b3daac9767a051b153af7c6bf0177a4074397be410411cb33ddcb895091990dfb85aee15e9f288d01ec5628034a4adb01da09283493baffd36d224b1efe096289a2afd427b82f8b04ea44319f4a16bb07bd21026f2ef550b919ad01cb3744b37103eb54e62400e03367001510776698e28b4fc367a77f1b4690cc2916e8ccf1fa55aa3495014724f1e66ef7ca8283d917b501c931274d9808a8103004176bb69783c094bbbbecd5b90ea14e7cdb9768498b22332283f6a079991988ac6a85bb591ef299bc57027b0ca9932a41c14c193467374f133bb8539c2d5164ef11b70b4a2cfcdacdf6841cd835c4f4e174be3c26b55770acf4137666a431d669fd5775a71749922c0b223abe36284fc880c3aa2a41f45a4a299c647d6738585287f7a47b88ea1c6c088c6207646d99cef5f56a2e02cd3ea85202c7725dfc99d04b2d52600f0f89366a3a83f8dc74e4a27fc58a622061a6332403ae8cbd0179149b841f5e0ba193ec237ac57a4cd5528c10545cb75e35a20c3ce63950c09a7b0810b84124f3a00c9ebb67bda9b2ab42113e631123b4a85897160637a32eb856d55c2905f7c655d40c84e92e773056d2392d43e33c4f9256dbfc7aa0683802d04d218139f829ae362c1f48096fe47b09756c36873cadc5300cea8094e6f8925c1b81ade69fee5420b7e94555286cdb596e08caa81f758022b3a949059ae91aa9b78a825703cd53d1235800681dbc7657a777bc267637ca2954c09344110a05e2bb90a83f95990986fb559bb1282778933631701393b705a5c122ec3645c1b364367c83444d30fa438eb3a478a0bae14270cd49556399085c566d9e6c467dca66a3f36370693ad5f86a9932773ae5064e9bc73ff7979a5510c88198beea7ee2aa494eb046e4d70a3f9ca0f88b234f6918f7eb41db97a327654836510276e0154e7a4dfa088b8acc5f02f598d1494bfbd07c3132c5ef6c3b466606b3d93da2e69c96744095435fcacc2d24c3016002b5c4b988877ccdb9233c490a8b121ba7821b529de85e638168b0565d50f735d1cb54cba91cfc1b9eff882a643121e877c43b6147a2a8266196346859ce53340208253ca419276b884dbb3b7a30ac3de983c75ad73995a0b62de7563ec9a4a715bcdf376dfb6433de691c54e660f4aaa4b184015026b6189415e66c90dd32c0b015aee63b5d8b3cb9ea206e45ab4938bc86fc54c7598c6553c29ac34b2213b90afd144c8b4629a560382778b28d666667caaad49633a8f985730318eb033374b5cbebacc7f453ccd8e77c5a9abc12da1bc1733e5a1278bf11b37fbab1db212359473012f3b545301ddc833c69a75afe16744557b5e28bc0ee895da16c2c5dd34fe6783949d555e580c1be7994bb008daf27a47f554932b87222e82ec670490ca5139ff49d5ed896218825056a8639b31d3ac8550356a408a01404c6aa9c2b7284e7c7c27036256b7902445dde00630d81930f4ccc518b9efd8ab24fc16a365b8068c90f7e09bbd23c2a6ab12792d245551a9894f704042501c8fc49eeaa0132701e29a3c97834530a7c61f1b8440822cd1bb6b11dca2a5951b4deb0b1268c2f5aa8cf76a6bd0be3013a37ca1a903ac634405ecb3714bc54610baa63bacf0a263d8cb018b03b0a286083998a7e8b2a573e570179712130a19f9ebc2337d43926f9c96460996cc03199d81a0e19259da696fecca7906931a787a5c264826099a3e03339295b587e7a4efec6a11aaaab057aa8689473f1f211c6d85499c46746bb00ba687a17877e6650c678d13861337faaa7045a16b8eb7173e7c08b6394b5f2b99ea3083ba175c55d350fd61b73aa790ca6f479fd4b01282b6baefa00a1946f6dfb855ce7bd50389d42856823301e01a228ac754cb65a0e323a0943b75741cb498cc499c8649b6bf87e991507194983aad1b57994b7d79bbcf2eb3b5f8734ccf3cea2662e95d486989144aea22c94c363571ac7dcd81f577645cf19b313f849b422afed963cdb701395020c2d18601a40a42429896aa9b0b1c10c4876928aeac59862414e143722a0b94746abd157343d15bb9fe500763b18c61b184407449b1b5ba8fb1554e4bb58ab99faaac9cdc3b698e64179b089b786204bf95eda86474ee799440478348989c91c3462446724340cd2376c682907edb58c85a4ce3ef46cc5d0ca345590ab14844b224735dc05e0e66ede94258f395fe867ab9d8c1b0fa80743002a15da197614295dc358f40758c9cc05e45bbc659b93ed611aa58845d94acc7aa75deba56d4d83c640c252975bc3165254c92957b78c9583b370ad785f2c16cd5cb9913839939c7293e6b956e23cc5d14cb3ab2a2e94f179bb076355157920085236f60b84449d43ac89c2b46dafa6b784438f3510bfc48357a5681043ba7428583bb5e912b08786562579df58a41bdb82114344b3ea3574b997f8564248210d4e50ab2277100b9a5423178b1f138e9d427762253cffc3cd095cb53a776f4fe015b5168b1a9759ac4acc77f90c69b307192b7b866753872a69813b1bcaab5cbb8126d8998e78d99f5a527992b89495a28e3fa83e75337ca2b896172ac244ab7e30761c8e3a00890046e5f599eeab65bf1a4cdeb5791cc10ade7197fb5bc754233f3b10c9ba2240adfc61c05231c36a6cf71aa752ab3c95c3756ef9373b677105d11f86e68036348bdd181f27407e344bcd297cb02bc44f077976ed588d6a846c2f839bc9bc4872617bdc17a7baa97af9a9322ff015956678e8d622cfb1a11ed929f29bb1f094c17f49417c09c1c443369123caf8701199c43bff97034efc6999424144c9395d9063bb153c0ed82b1c5659bfb23d4cd2c758a26b6c448525060f686bb14873cbf5046b3a3033c5c8081027bf5e3c51f6fb6a1d54a77c46b0ea4299a9da4ab03b95f9d3601f553d46800f661e2c9a7e548ca42e385cc6a0678f9e9d268ffce02c4b465a46773432109a759cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb6356047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9 + +comment = Official test vector 10, seed: "980d0ba7c8f8b23d0e948a6029ff2659810ea1360064663a8994d0333c8543ee5ff5d6d5c9acf446e61dc464f792b9d3" +entropy = 2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 +expected_public_key = c4a90087866b29244c3641310e94b8311a1303465975649288713e79ca67a9085c8f7449c0bb9a6ab196245b0da028cc1765a8ba0501d5e360cb3064e11554f3fc2914f1260509073b67b4a0570d7f708ca7c435ea987762f2a5a23cae53907fc9db26942136d72202d0a0bb10b65d422091abaa1c21d152dad59c25d20c016237634741def8ca26b9cce3097ffd896f1bf08300282fcb7000c7e1956673223902ae5b43bc63b6806c469a4ebb8bd34b057b375e725b07ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdcc12892d588d06655f6103e033547cf5933ec237b21b2956e5921cf10a0c55a70e4a24a57b93f6fcaab2a44bb079987eba57223b4b9deb60ec6464faa4058283b8cba6956c792ae8ff9184e93c2e2152823c15412c102518462c2691db1c64412eb1ec6d75d47c82fc5a9214670b3297067e30c6d9ce0cf3eb314cc1a4cf35342ae419513ec2bd47182c4ea52626a56f7831dbdc5719f532a5a421a7bd5a115c2195d0532e7c1c0ffe40166404137a5b45d7b2cd31752e1646588021508293fb881123f61034318700eeac429500905179b283162ed0b69590541eba0848decc94bd18c888170a4c030a89305fe97a2b0292390a3b1fd6aa22909cf0134a2754728b6fb5180276b7d65c2fd530b4ff48cc7c7093dfc2b418b97762c42bb0980c7f41d9651c69387173a6718038010f50b79b233187bc3a0f7c770e50abc62e8acbe297c58c58055387bc7711473d81ca97b6a6e6504870c0de1d806e3603ed0b04d01dc62529434014c5068c3ab3d4a909a079947127a8a2746cc8126f0212e21a0318ef273d5e0be16253848413c5cea22853c6e63b675cfac1d6590004a2bb3bb4974e79aca0dd927607a71d4b4c9980a86e5a2b5a84bcd2e694190491060411b332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d45f72d82ec24fb268537c07b81aa79b5b28ef5a657e0f8b6b2f3a4279abcf06ca2a79401312943d1d1086d91b1ad3030d0c0bb21806cb87b56ed391e6bc6aad974034664b4902336d6e45a7449cb656207d59367f2b142746636e44726f111603b28670f47113d28ce6bb11f464b181cb3205febc13cc70d3fb35924a641a1117df5cb65fd9a69c71bb800fc22a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ea920e4f2275f4f7bb361866647c04c573bf47e6b54cd31810c7814ab5cd27da1905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abaa2229c4c294e7a70f97bb6d119be54553eebab1c80c8da7459258e44a234357a1c9cc46412794116123d21db27455063672245460ebc8b6b1116b34f2401169ace16a514534154e798ae3155809b651ca963f854ba501407920765a14f826dcfa4bc4f21766b05bceac55e6854f1ad080d9b2538848a8dc7857f10c4c843c46b172adece3707e01c03059313bb96bb144996b127a16006db4063ca1251f550836e167adea545b3a0c55c0ac5de3fcab6e8242c2c5c09313646117a95ef46536dc74d869301335a2f9040484fb0c9cb85a3d034d55b03c66725d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a +expected_private_key = a5019e7b82405cac3c8f45bec4e70e20590bd7e543d465ba702cb1447c0f114cc44f404a31b091c638347cf5a464106a2f92a0b4e600a3d86ab9f57efff088d1887865c695c3aa29ba08356da1b4042146e8817f2bd56bc014071b896d5b2cba9fa124cba45e294a0f30fa01e4eb18262059cc987c64f9185aaa12d7ea1f2780308a91a3b2f171d9c41d166872bc7b070d44af8556a356b631a6eb2e804cc09c531eeca476adc8143eeba767298bf29c19fb2496e0c573938babcd749ee2d02e9817a3ee5a687f9324e7e1082892142c04ae9715c4a6980d73c6a54c16beea97a659da476e49c1dd1b8292e04321783e0a66a36267673e92c2c7463668b1742987405c1621f94b87ce88aebaeb7bfd787116b30a5b64a7e8956321463b351a9753a0389937b7aed431a5028d309cbed2d8ae67f859ce371cd1b3cb11a8a70d3b9b92e15530a260d1874118ec505fd451897712ae4104e67b1d2bb2676589aa4e8833e03b017aeb2666464c87ba809f2ba29106b49647666fc58c712b5b8127882df3723e74a9b9e4b0e5a96bb325144111c75e96a13b5566e8258e36d34a76096f9b013236b3036bda5e3d431aad3ca33e9a0916d8cedcd3466c75c1b5603a3e724c60a796e0844cc0d79686f086c510ca0cb11c2e936ecaba446560aaf0931c6a82298bdc7fa82aa6a0b32d361b3335cb83dda38417720e9e745bb9ca008908cf6931ab2b4a7b78036704153359dc4fdb5742ab3c39a346005374cf3107b95cb771ff1c9592d59c810a93e3593169ab26de85077dd79a3b3aa03c332a9d177d7ef88624c285a90099d1d0209a0bb0c425ce6ae9221613b2cd596aa77ba2bb98a385d2898d504d68117ed06233e69c43b541438b3274b579c1a5c27b0d85159836aa48907f768c97b6b2b19f475655022691182b2d9c80aec12eca0890c9e47bf764684ff1a94d1083d85905212431afe09342004b44a090cd71357d2431c923b3ce08bc836b3edb82ab2fa3c508867eae87bf2768ad61d4894b123b6f861db52b9b3eb77a8c99839e9108704c907e258f8d8001567078037aa1ab87b03a46ad3a0a30c753b8bd790923b7454f84c67ab6bbbcc105edc36ab6ab67c28c1d3a54bd06f9c09c12cac8483e015301db6650ca3228abb8353d2b3d95fa5d99e96bcab65b37dc8a1e958f7395391bcbb4a944aa955bc2176aa6600a0d40489d0534423776184c85057ae00e9636bfbfa76c2d329625747968f53d1eb26cf4f95d6cca45c60b2da0f1899a7a1fc651c12bc2c3a2ca16d8aba4e05c0cbcbb2b72c48ef55403462ab49cf6576d8c358a865de1f795cc0629f4b13837b6b1704250b8e97f7a116fb63a0dbc12c955b49a67094cfeeb0e8c7b23abe4bdabb787d3e45ead108a96d3206a4977aa128866e596dfca9d68996d82021a4380c0991561ae40a96bf490dd5538f0718098479a5763787939453a7a87a359643885bc5d6149ea048b5ef1adc65c78e4a9c917160bdc625352596034b3558f98637b33061f769cbe341f9c764238318882caa978996d1c321a92838d109c187011bf84d17fefa0271eac7d5ec90743130234e79089f5b9a6f0267813939b5a3b22321376fb1792d8bcc4a90087866b29244c3641310e94b8311a1303465975649288713e79ca67a9085c8f7449c0bb9a6ab196245b0da028cc1765a8ba0501d5e360cb3064e11554f3fc2914f1260509073b67b4a0570d7f708ca7c435ea987762f2a5a23cae53907fc9db26942136d72202d0a0bb10b65d422091abaa1c21d152dad59c25d20c016237634741def8ca26b9cce3097ffd896f1bf08300282fcb7000c7e1956673223902ae5b43bc63b6806c469a4ebb8bd34b057b375e725b07ee856fcc0453379b96f89888d21a7bd5ec91f837b90a2c334a97ad70d87bdcc12892d588d06655f6103e033547cf5933ec237b21b2956e5921cf10a0c55a70e4a24a57b93f6fcaab2a44bb079987eba57223b4b9deb60ec6464faa4058283b8cba6956c792ae8ff9184e93c2e2152823c15412c102518462c2691db1c64412eb1ec6d75d47c82fc5a9214670b3297067e30c6d9ce0cf3eb314cc1a4cf35342ae419513ec2bd47182c4ea52626a56f7831dbdc5719f532a5a421a7bd5a115c2195d0532e7c1c0ffe40166404137a5b45d7b2cd31752e1646588021508293fb881123f61034318700eeac429500905179b283162ed0b69590541eba0848decc94bd18c888170a4c030a89305fe97a2b0292390a3b1fd6aa22909cf0134a2754728b6fb5180276b7d65c2fd530b4ff48cc7c7093dfc2b418b97762c42bb0980c7f41d9651c69387173a6718038010f50b79b233187bc3a0f7c770e50abc62e8acbe297c58c58055387bc7711473d81ca97b6a6e6504870c0de1d806e3603ed0b04d01dc62529434014c5068c3ab3d4a909a079947127a8a2746cc8126f0212e21a0318ef273d5e0be16253848413c5cea22853c6e63b675cfac1d6590004a2bb3bb4974e79aca0dd927607a71d4b4c9980a86e5a2b5a84bcd2e694190491060411b332aa7e7766a4c693b00eb9d68f34e5b0564de24377d3a6d45f72d82ec24fb268537c07b81aa79b5b28ef5a657e0f8b6b2f3a4279abcf06ca2a79401312943d1d1086d91b1ad3030d0c0bb21806cb87b56ed391e6bc6aad974034664b4902336d6e45a7449cb656207d59367f2b142746636e44726f111603b28670f47113d28ce6bb11f464b181cb3205febc13cc70d3fb35924a641a1117df5cb65fd9a69c71bb800fc22a6bc47e52756c23533a3a494733b74d9689d64a849d048a2ffaa62b24ba53cc76ce8489d7515834ad3a2ea920e4f2275f4f7bb361866647c04c573bf47e6b54cd31810c7814ab5cd27da1905fc5976286b781787d2db606c036a2616af7946935713ce2c7ac3fc4972abaa2229c4c294e7a70f97bb6d119be54553eebab1c80c8da7459258e44a234357a1c9cc46412794116123d21db27455063672245460ebc8b6b1116b34f2401169ace16a514534154e798ae3155809b651ca963f854ba501407920765a14f826dcfa4bc4f21766b05bceac55e6854f1ad080d9b2538848a8dc7857f10c4c843c46b172adece3707e01c03059313bb96bb144996b127a16006db4063ca1251f550836e167adea545b3a0c55c0ac5de3fcab6e8242c2c5c09313646117a95ef46536dc74d869301335a2f9040484fb0c9cb85a3d034d55b03c66725d000c47537e0d5ae249eb884b67dadb110119f1d0a5ea38cdf9f2e0e27c75a43a9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363 + +comment = Official test vector 11, seed: "6c029462ca42ed520f10a579f52687101105e0b90c6e7bfa582a4c112b579d5ad0a0abd38f72abcfdcaaf5893a112bdc" +entropy = 31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 +expected_public_key = e9718a491b3262d206be72a9ceb000e81b6be6668d14a124bb49be524abb09b91942a60ed38b1974e36376a7724ddc7e5a993ea9c25f40b80c766cc57e807bd5932603403458b84703ca58f8e57c451227128654df4537fce6a57bd1bd6fd8c5be1135b2c82cbfa4b96d577575406f92538034d22d6198a9cd000fc8dc8988f95608c1974c4359ada14f7dd4870c63bf79886ab2d4cad1c89a8fe232fc1c8c515b7d2aa9cc35759ef583244ea767916478f8415fdf7b1cf85a80f4d6960298b977a7abf380709ef904c1706ee3f51abf415028321e4fc79fb2e15454c47b3572bc09c62c0dc466efaa759f116e8ba4717f91220f125656ba7c52338ab1facb0fa6a75ce61f3135911d5714fcda7a5a271205547018cc0607c5aa7104a4a77266c0525579f054ecc6c62522068e79352ae7a1c3265413459939764a4421caa937c8f9b2b276a2c77ce7814fe9034783b8aec29881e2563a63780cbabbcbe72501d68f1b72c6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c9621bed149be06aa2e72f72d1b24b086836b525915b93a49d90cb3c45877c54204a605cc27f1828de6ca1e95056938a6c9651eb3b4a9b09c5aa9fc4401215d9ea9015a996f9a7b898cea466ca14f0065a5b1f374d422b4a277a011f3b3e8143b053507bee829e582528dcb3c9e950f39d17ad0a849c701779d070e34cc606c84a596650b7776a468659344446bc19186b43cbf042516a7b133065393c83b85313c53b71a5bc4421a91694beeb39760806d3b910aa8ea546f53763b656c99ea50a179986dc3786a554b819317fb58564dd69428bb1d7bc45a642a8ab9cc013f932a67222d1fd42b455930b8147d6175c66330217246c400c4b619b922182101b2d8165f93bee58757c14cbfc958552137b904009fcf845321841f8648b8f9e58d1572119b11cbcd59480246a46e255adcc1649817a052736ed9c18a262c36f7c37918db789ab177ed39add0850a509319888073b54bc3ed81000c780fc87ac5c302235a959b1164b491001b92811d4aa76876065e841b276a27b868822fd1da7c3fd1831d88c9f5d891ff610caf264fbc9280b8d4085251774ee20c23576ace6215b3eb8c1610ca2405115e89421418a7610c05bb526ffa39918e9558c6cb2618a612b6d38bf8a2569b4c3ae902a4ac744ed4bca8ed783c4eba450470aef5ec5370b87daa419145298170d64caafc2eda7c989645b9285a3fbd16c16e0c1e3fe085a6bc05248426ef106e7f6012e80882682660cd05ce49520785ea66325078f9a91e5ffc3ba0833de333326fecbcd8878f286064cd1b672f210133e30d106c61af9a75a7fc64fb5b1e1a1649fab356c0f26b9062c5dceaa7cee502c750a93187a21c11b1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee70253d77065c02926bfd9b031260b5af95846573ad09c42573c8338609fd3e5c0b50092b17a83128a4a9f1a6a232252884504846b3b7df82981dbb036f6a57c5c19136789af9690a978145ea6adb74132ec55840965083f388877a93fc01b006fe4cde4012a1814b327a12cca8991cd18027f4485b4025b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28 +expected_private_key = 7ec737ebf52eb7905da8b3c58508928dd74462e8968a1265bb3b9780649210c8202e2950ac11863bd78af3123ae9899ceff1992608cf5bd1b4eb0ac1c13ccaab4ca89a869424bc1af777cfc7d90a071273f5aa5df310493fab17ce5b6477c773d8cc81d995509ff3a40ce80e734a9e8968b7fbe79a9900ab85f7b442077a890688dcba0bd5e64ae491ce5d39b554e6b82b7602a149a686c19fcee21b8e3b1792e7529f2307505c77ed84a63a68258e832bf0f118bc05c91a6b216ebcc051b90143b9748b365ec841b6098c4eece8aa8231bc24b03e732a0ec55aa5b0e3231efb7c7f0ab21e2544072c22b6b4075049b63fba05c68a936989baa2e55ad1846fd1e335568b01d4acc869e710357708bdc25db545447e41727224545ca8c16bca5458eb24d746a12e170ef191cc8dd840e26910cd9484b4e40d0c7446959a521618b9bc472c8001ad0d1c8428c43c0fb3230fa9b17694284375a0e1563fdaeab6cad367c9949c4723802d6931f0c212b03004675652b958518d31c8d4b06dfd99820702319e668dffb5c88622170b0c0eaba56ee7b77ef5d7600b9c0bbbea5b99e05a9443bb81a68c22c7904a1755d4c80a47ac148ed13c3981c6bf4122a7880fdd597429a32d6046981146743ae85cc8c0ccb715937f29c933d63ab475c2c5483ce07acc5b8bb4c7456398a9236d02bed9b951f6d43a67ea06f7fb803acc33e9552e7150c34003a2e2e11bfc0badfc537eb2b69122352ffb62b285b6cb0935adfa0385dda074f7a63adb76bcf4a80aa83a1c32f87be3a786537acaa32178b136c8bf817ac1cb1e25b44654266f4b2b14f33358b9b75a2d916d78e89d3cec68b782734fe052449598d847b2a02c3056a64e72c5a3b34685e9fb2c0037736e0a21df39a356310777a36fce908c243a4a50216b6199cd63c7bdb18b95fbe4615e9799757176fa4a88c93459bc3030e09889ede148890cc221362472586e3c026b0dc10ba5a823f07acc1c693e9bf31518b90359b7aaec54473552835b3590174109337b6171eac38de29bdef8095da13a8f7014b3f531fc152ca5eb19859673d52067e28c7513141245376baf368b07627fb1b844fc033361994ffb3b39822a2a2de17597d16601329866f42c3697a6f5132dcea2140b871480e50523c3c5227537a5089fb6742cbfca55ba9c307a321abe440241e34151b2c2aab6ad55817b115330c0b15891fa35bf344be7d93ad44bb27962101982902427242f5b06f85204e738aec7a333a15001252004b21b5e6fa95a41a4456f74c9522657a9a40f8c4a162f4951cd5bb8a4f334f45a3a73266e1c386caed53ab52b9a4dfa173b96869fba6c72987f4b328a0e56a08c96a00d78854d6762ea2394c2a102162143cd40192749cfbc5031739711f1ea8c37db5b635bcfe9b6396e2902d56bb135eb8975e1b0a171258d39a7ae84aabd46baf4dc2a6ff18fb6002ce232b7a45a532dd54d3da8c580d6cea4209098930477d207622a7cdedc2e72c24eaf5787d4b2b461889d23ab93a4ba327c371eff58cff7f65738886abd046895834aa06a6cb57973f1011353fcc1452b015a324c406515e9290aff4356fb393b57f4066077b2152819b6a69de9718a491b3262d206be72a9ceb000e81b6be6668d14a124bb49be524abb09b91942a60ed38b1974e36376a7724ddc7e5a993ea9c25f40b80c766cc57e807bd5932603403458b84703ca58f8e57c451227128654df4537fce6a57bd1bd6fd8c5be1135b2c82cbfa4b96d577575406f92538034d22d6198a9cd000fc8dc8988f95608c1974c4359ada14f7dd4870c63bf79886ab2d4cad1c89a8fe232fc1c8c515b7d2aa9cc35759ef583244ea767916478f8415fdf7b1cf85a80f4d6960298b977a7abf380709ef904c1706ee3f51abf415028321e4fc79fb2e15454c47b3572bc09c62c0dc466efaa759f116e8ba4717f91220f125656ba7c52338ab1facb0fa6a75ce61f3135911d5714fcda7a5a271205547018cc0607c5aa7104a4a77266c0525579f054ecc6c62522068e79352ae7a1c3265413459939764a4421caa937c8f9b2b276a2c77ce7814fe9034783b8aec29881e2563a63780cbabbcbe72501d68f1b72c6ef3c5d84a4bd7cf4a84686682fe36a151bcb3bb76ce5fa67ae545c9621bed149be06aa2e72f72d1b24b086836b525915b93a49d90cb3c45877c54204a605cc27f1828de6ca1e95056938a6c9651eb3b4a9b09c5aa9fc4401215d9ea9015a996f9a7b898cea466ca14f0065a5b1f374d422b4a277a011f3b3e8143b053507bee829e582528dcb3c9e950f39d17ad0a849c701779d070e34cc606c84a596650b7776a468659344446bc19186b43cbf042516a7b133065393c83b85313c53b71a5bc4421a91694beeb39760806d3b910aa8ea546f53763b656c99ea50a179986dc3786a554b819317fb58564dd69428bb1d7bc45a642a8ab9cc013f932a67222d1fd42b455930b8147d6175c66330217246c400c4b619b922182101b2d8165f93bee58757c14cbfc958552137b904009fcf845321841f8648b8f9e58d1572119b11cbcd59480246a46e255adcc1649817a052736ed9c18a262c36f7c37918db789ab177ed39add0850a509319888073b54bc3ed81000c780fc87ac5c302235a959b1164b491001b92811d4aa76876065e841b276a27b868822fd1da7c3fd1831d88c9f5d891ff610caf264fbc9280b8d4085251774ee20c23576ace6215b3eb8c1610ca2405115e89421418a7610c05bb526ffa39918e9558c6cb2618a612b6d38bf8a2569b4c3ae902a4ac744ed4bca8ed783c4eba450470aef5ec5370b87daa419145298170d64caafc2eda7c989645b9285a3fbd16c16e0c1e3fe085a6bc05248426ef106e7f6012e80882682660cd05ce49520785ea66325078f9a91e5ffc3ba0833de333326fecbcd8878f286064cd1b672f210133e30d106c61af9a75a7fc64fb5b1e1a1649fab356c0f26b9062c5dceaa7cee502c750a93187a21c11b1b7fcaa45f8b857d38e18287b1e878c7ee59e07966f3619bee70253d77065c02926bfd9b031260b5af95846573ad09c42573c8338609fd3e5c0b50092b17a83128a4a9f1a6a232252884504846b3b7df82981dbb036f6a57c5c19136789af9690a978145ea6adb74132ec55840965083f388877a93fc01b006fe4cde4012a1814b327a12cca8991cd18027f4485b4025b5583747fbb37916585261abfea163b617347acaf453ae235166cdd8afbffdaaab9919f0cffdc75d8796fcc28241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5 + +comment = Official test vector 12, seed: "db00120937570d62331f4c3f19a10465231eff46465cdee336a0d46aa1e7493df80f18617f9ffd0476cf7784a403ef4f" +entropy = cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c +expected_public_key = 14345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea81212eb91339aaa4bfa87a197a04d46a7b666837f55db6f16c095db449e9baa879ae14016ea4f8ba975da26cfcf59401237accb908efd17146e9439b1473bafa07703f2932d5c598276b59b419402d681d87111f70c20d2710e10a407634ab216907d7363af0bc4647dba208f9c6744d71a8a1c1a99082a3bd8a843e4ce581412f04877edb1709d1a9623c3c428eb111a1189073c9a3d34ad16aa1f1551a07e6880147360e60888ddd5b0956036951021af4699c96382cc0c16b3f0b960135391c6692b0c556a5b9ad2f8a5ed0cb0baea2406868ac6f7a5a44b722721535e098fe832c9af148ae027604c47ce4d3214a1bc974675289ac7bfb9a644db30235a664417c57a8a46a86e18a10f81b87f4b4727f7234017088f447f28680b0600ad1dd672f0ea19e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d0a2042c744555049c48b2bc2577738a698bc58910f55b0ede555b171838f6086ca365aed981aa5354561411990707bd3305cf4d10161fd3124156691daa5cf3795653e2aee1c4ba021b0edd0809b14905e46c2cd0bb1e165c8aa428b180ea394e6c92bd6873e12328e5e1916c94c81393172df3815127b937b9646a783524671fbd8b5f01395178c6a9ff42c47d8b25fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f27640fe59b1ef407110a317cd72023828192b131cb9af96899a69b0f51125b2828f29493a997a33023661bb7811c4593e4e579f8b17d0cbb6037d9273932af4eb235f7d01dd398b70752a925968adbf56cf132b85680abffb937c35425c244345e805bdb608cb0666984775ac1852690908cf2a60214f6a888004aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f52f10d4a852d38f5354981cdfb7a851a675c5a01c2fbe886192582d1f08ab37753bbd81ba6d848949731c99ba92278a2833cc11ac3bf603512bd6557f9684eb980c7588424db0c1e2bb2bd09196a7da29d79208da50c4a0c839284a44d8861706e991edd099e0b1467b88948c89778787c26dd4436fbc4bfd12b0acc00ab4d85b613bba4f928bbfcb04e2eaa51b81845c3a710bbc8458027a4f055061d0b39ad28482646aebc5458d0e70d396c99a0b456837376110488f49a83f48372327467ab87870d11b3c1e6c112ab3d6d486a99bc2b9b368a0695c6c6251d6bea5b56fcb96fc23475719b8cc82806875cad772e4716332ffb02189438e27097e565159e4b1790558273ca887fca2a6e7226c53879adbbc07ac1072e6aafdd2a1dd89677842041f33c447204a3fb91c1e4935111ac739cdc9fd6f2ba8c0c66dff5552f3b2bdfdb19d4f65cb3b23777292cf97cc54bfbc41ed041e53318386173d229b9288c5d68e87d0ce2032d481c46b646ef71940d97af370732533260c6ac943272866bb2bc90ec64424c67b1c877f5d2b35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866a52385c85c241677f75487d4156c85db639ad741e0412438bdbceb6092fa14501fe1c5e95d90833332debc0441554a8cb5a8f7826b047882b415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f13260 +expected_private_key = d62c6ce5e7594be682a8167743106a44482e3a79ce257635773513f0b0bf77a161c8274a705b93d2eaa899d8c0126ac8adb7b3bbb5891711380da1a9de0541e4160dccabc13a165b5c54178da95b919457c684b9cef81e97637c73f22a3ce9295de79bedd83c3ff871087b9412301863e291b04779457807abe4687368c84b3408e26aa30bf58bbe4bbded32adb03607598714464222524b3c2cd4c15f98a2e6695463257bb8fa9a84131a64d45a57b9a539094b5e957496b79008878396d3b9b2ec41cca75b66fa6d069a51af611d4bc03e20cb12a216072d7834d996ae99e1cc6522a42b48c54282cd0ae8cfdd1b874fbb4ec17434ad584af5b4561bc1597aab63390b60fe7c052e57846e1a8c4f6c6758798b70503507554946382fa6e2004a616a40dbc2b0c596c2cb2873c38e6ff82ff159ba93563d23671dfc433949d3705f398b3752680169657623937a8c357864c39d82c16da5c1ee407fc7fab357c0b114965e89815409964ccdc54cd8d5b17039aa9283a59e746a45a2800e4806064683c292b425c18f73aa2f720a6521a050c5196bdabc9b094895b9527759c1a7210958e11a3411b05e67097fce2c11ed024a85a22684b51edd652ded89c23e1440ca5616bb754361c549776222b8b297f8f4bb7f818d3b29b16c369cc8ba9d91e6012bf006999c7057aa2a44c30237314079b2a55c63990c3ab657cb80d41022651097ed680d200195be82a9b9d08b24f039bffc42c66459b0c8889dda6714b63762494a5e6106f34223990772b1cc12dc660f5be62eb0a15c16d4a0303773d768c7dda7b749711f7c12720c150d30ec6b625624e3f94861483be03271d8b05780ab62e0294a8cb193238530b49455718c872428bea1d84955f54a3bb619dadc6106ea3ef27094a085634624377312648ac46559d7a7dd902497aa9f22879d131a08b9223a05e5b76a00807225b304480f6105cbec8a11cea18e8910a9bba691047c95676c9e2dc7ab76537691dbbee397738c613e1fb00a79f06698c10ec26c97dc00b82a54af572a02801aac20983311f42bca18699a2684e4b5aed83c7ad89a1705f1605a87cabefac499a56058d8b02bd597743524a90c3686d9405e33c3d70880b6449d41a76f83e23759664f1f301d3935998d690a7167afa11a59cf8b87624283a738c0d221b1b55453504ab64fb89824351a49ebbcc291465af92f50d7b53874c1190a766dac5e70706f88097be4500942534df5e5887c48b234c11992f32bf3f2867cc055d7d6c3a4d25d2a141be7d706bc1203814667552888e3bb13221a10dc3a4157d811a7ca23088ba5aa1a3fd60c0c6af29b3b52aa6da319d8e359d842c6dc65c29eccc0523115d15b19a7b90d1090c5949cc66a004f0a0513132640a284a87384c7ed06782607584bf5cdd8f099acb0229cc9588b024b0f3b5ba80b962218b3bce4c0f542bac9e8c235362e33ea30d789094fe82fbf64569907755ed7bfd00c3f6f446deb00a27b37bb92e454aaaacb69dc854532c718c85508ac8742c7180ea805a78999111915bd414275e92d75c1953c10968c802e4aa6429eca0a5ef49fb4046ed2c93914400b0d882b67c275c483037e859c8c015114345d52853184aaab60195152259d9b643d864c4ec5fc4978c657c3365ea81212eb91339aaa4bfa87a197a04d46a7b666837f55db6f16c095db449e9baa879ae14016ea4f8ba975da26cfcf59401237accb908efd17146e9439b1473bafa07703f2932d5c598276b59b419402d681d87111f70c20d2710e10a407634ab216907d7363af0bc4647dba208f9c6744d71a8a1c1a99082a3bd8a843e4ce581412f04877edb1709d1a9623c3c428eb111a1189073c9a3d34ad16aa1f1551a07e6880147360e60888ddd5b0956036951021af4699c96382cc0c16b3f0b960135391c6692b0c556a5b9ad2f8a5ed0cb0baea2406868ac6f7a5a44b722721535e098fe832c9af148ae027604c47ce4d3214a1bc974675289ac7bfb9a644db30235a664417c57a8a46a86e18a10f81b87f4b4727f7234017088f447f28680b0600ad1dd672f0ea19e38a39fcf964cccc64528c97fa474ef3aa6777676b3db443d0a2042c744555049c48b2bc2577738a698bc58910f55b0ede555b171838f6086ca365aed981aa5354561411990707bd3305cf4d10161fd3124156691daa5cf3795653e2aee1c4ba021b0edd0809b14905e46c2cd0bb1e165c8aa428b180ea394e6c92bd6873e12328e5e1916c94c81393172df3815127b937b9646a783524671fbd8b5f01395178c6a9ff42c47d8b25fb37a2d1da975f69c7a8286504faaa6ad5b05307c2d20b4f27640fe59b1ef407110a317cd72023828192b131cb9af96899a69b0f51125b2828f29493a997a33023661bb7811c4593e4e579f8b17d0cbb6037d9273932af4eb235f7d01dd398b70752a925968adbf56cf132b85680abffb937c35425c244345e805bdb608cb0666984775ac1852690908cf2a60214f6a888004aa41a44831537e55a5dfae7b2a4448fe6c562ea66764dfb5fa508b6738c4f52f10d4a852d38f5354981cdfb7a851a675c5a01c2fbe886192582d1f08ab37753bbd81ba6d848949731c99ba92278a2833cc11ac3bf603512bd6557f9684eb980c7588424db0c1e2bb2bd09196a7da29d79208da50c4a0c839284a44d8861706e991edd099e0b1467b88948c89778787c26dd4436fbc4bfd12b0acc00ab4d85b613bba4f928bbfcb04e2eaa51b81845c3a710bbc8458027a4f055061d0b39ad28482646aebc5458d0e70d396c99a0b456837376110488f49a83f48372327467ab87870d11b3c1e6c112ab3d6d486a99bc2b9b368a0695c6c6251d6bea5b56fcb96fc23475719b8cc82806875cad772e4716332ffb02189438e27097e565159e4b1790558273ca887fca2a6e7226c53879adbbc07ac1072e6aafdd2a1dd89677842041f33c447204a3fb91c1e4935111ac739cdc9fd6f2ba8c0c66dff5552f3b2bdfdb19d4f65cb3b23777292cf97cc54bfbc41ed041e53318386173d229b9288c5d68e87d0ce2032d481c46b646ef71940d97af370732533260c6ac943272866bb2bc90ec64424c67b1c877f5d2b35c39656957bbe40c53ed88c4124764b726a5e24aba7b0c866a52385c85c241677f75487d4156c85db639ad741e0412438bdbceb6092fa14501fe1c5e95d90833332debc0441554a8cb5a8f7826b047882b415b78a0c2e966ac7c67b03ef5106f0a751017b67cc52a3d0e1586c74513d2b5f132606ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e46858e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c + +comment = Official test vector 13, seed: "bd26c0b9a33e3b9b4c5d7ea32d5bd1fc371015be163c86f584e49bfd5362c8d8341161cd1308115b2a03b7e5eaddd418" +entropy = 4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b +expected_public_key = 8bd98be4597242c95c9641b194a093a928b8d3b30f33c10ba326943a8b704c09a6dfa55f700c488c38a3334716cceb6585008a853162e40a544c0a16878328f47c4e67b5aad276a2dec4c320047e2eab345cc14982b96d1d13566da409e93072377a1729546117a04ce291a2090b60030a35d5b360f9f871cad52f37e63954da0e0a8675abcc3717972f89469978730607293267cac89e3c96a98576c2351d8756429722a1278a173a75114baa4f0eec6a12b09cafdc99fee2c1af7acdae3c747b94b06517464f654adae25888a15cb4c5017076c9d3fac3b1560dd9112d88b2bcf31b15ac420fe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a972308c7b040d2fa32bfd1096503a3a0e84b9941188a6720e06e6641b896d365190369766995826b72122d780477581bd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0a423409c285d0e21bbca97be6707557bb0027e755f9a81912d04b9ebb374bd79411b2c283068670431f2de58d346bb525d192f128c9316742115275e9214def7a61da509b5848013b304216f783d77c3f57b76fb8dc984f05ab557709dae4691b519c44d41813e4b61e6664af5c970ae7a810714217745af087bb00575b18081921a854b7d953e29cb1de704e6578283292168ea73a03e2082b8b641c819649270011861a7b301dcef74e9b116a86f717e30ba6c5398e34390072e20c82f570fcfaa2bd8847a7187052e6b9d0d9bc9fec0217373bcc7b8d38245e40a1597077bb00a408e9eb2bb451c31a746d2aa07fd6432cf176382b6665d45343cf32731817023ee046577abc342bbe25416daee417f2971a8ed4c839126e996a8db40a55bd424c0e534cab677fa1c6b692d2b7e322a331305f75289a1ed102ed604722737e76501c7e7acc69842d6ffb2d31d1003c3b3bd8f4458d93b0270cba21db21a7d16e22e18584e68ea5b890ee839de75b68d60b25d5452bbb91658f3220aaab200ee7a8f070a5b5aa7fa30a768275970012324fe01910e8647945ae6f8b3a17d08e5c36af468a7f6308751c4141439b567eab03d72538ddf71debd2aec5db13537a2b0130b4c2f6662182bd08eb750eb681fce77981a3012102c45642bb8a44ad5cb27cda8369ec28190f64987eb600101aceae7a807158cc8100555a82644b3b513d7cb283a363c70a4ea090241c8a96ac562e7fb3c38f3515c3a68fecb271713729fb77a1a68695fcf995855749c1f0ae09f90741ec332e7602cadb69e55438b9d8ccc213119627410488145777907d280ddb7391d2ec9f27371277c266bb1b14f6eb8d46b2c8bccb0c68f3beb2d87b07044904d5b08e84305b0686f923985a49acdcb1a662d1a08948c9b8d95883518d0ad3933976c464a41c18351216d84066d71164a32d41886a153703c584b747555eefe8309f0810d49c0df8c5512b245f637c9448c47e1456995e922460b8210c7ac1063047c3764077288a1345c23ee0c8fa6865fdd52acb49614207285d241c14114db55cc0c92049f3537abff81b8a30a02e5ab013741b36d92191691b3197cce8d2328bbb6ff61932434899ae01412b231b0efa18d8381555866091c77981e753f8a2b95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c +expected_private_key = 212393fa68c40d1153ec29801f4472db30b8e6516647cccc6a160bdac4299d515717d46bb4248673d11558d8af5a6373720a9c96a4c51bf12ac506cbe51b560ab742ec684ddf86cb08121bdd412e2476842d051e3182c415c49b7184c9322242f70b63a960576296a8af5451f5d474019c47e1822e2b1503d30cb8ea20b3cec334a2114fc2381d910a98e633716ef9ca2f7939c7033bab756371d6c2e906061df822113c57dd5992c8826adecbc9ae381931473558ac94fe8a19c9c4bea3dc40defbcbde234a211623f8d80bdefc74f657a797098ebbe2b6b57438c2253f89d13bcbd5c0c4204def79bb37859e36e920768ca7d0651a7ec9bb63336698acbfb6c9a384084defc1bf5d9c050087b691d40344e107bef0241bd99463532a05b795f820213392cb16d668605ca86df134c03c4a7df581f8ca7daf732f5aa75146457163c3abfa9c655f966a607a69aa1234fd1ca2a97213f280a10e84c4aad26c0ea2cba6773d63b39ef7350f6d284830ec3275e5bb9a318b03f87cd3f3bba41632c0f9a1e65989b74b91b23a82bcc22d617aaf8b14c10d0037ab970b8cebbec0cb866be5057964b7cae6c9b3084a696602a25961dc53558c065d6d8b25248aba262b1b635322bb82165a8cbede60bbf6b72459d47b64a964b3c32ca563ba5aeaba8ed912d81b2e733b4b4587a99ae5037dd21dfc9aca5d869596e36547c0336ae774b8ba637622a597c05dcd43b092d938429886c708448b24a45a701ce9fb9db54c67bb531bcfb82ebc15c127409b02a3350d6168f1296784b86f7310b9160681f0133a66356843401b9c0414d7f687aae41a36857ccd3b26bf8c11def30769e30630169365aa3c3b53cc89d9cf47c2cc6c166f197c9e5c5b2408b03c41b0613703cc4872be78dcc4b28089d7118ca1186baeac1355d5b9d4e45515897ae233a26810356a373dcbf6cd5f02cdde8c468be006dbc67e60a69908d1171d4a5ec1643b87059cac80c259788eaf195f4fbccfc4c0284be822f94c2978fa119371291657b927f8b332124d61d17e21a36485d2c3f2893865f305589a8d048b06fba7bb9f087f96d5785678a7f2d16c892cbb2273677ed0cb70f5729af0a0403b0bf0608acec1ce32f2924535c16e8423be0c8854e439ea395dd792399dc98aeeb7493b64965858be35977dc053b3c0b3788fb4244cd3b49e40934f90b454c983da38b2b5c88521347788f832e9c64a6cd012511234275c9f6c251442a87b496743333a161d8c04e3d78be3097942aaccede09b9cb673e1fa261be71dbeb5c4e1049b2b2a00311acad4470f8afc85172476b949aefbc0110a261461291b5ff7a74697c88ad40c82770fccf68b9ad5382125879e637b7cebc1aae95b03219cf2488b2e3b2e51480c8cd8022c2092470236fe6042dcebca24cb9ee9379386d80e54c232dec93b99b694e99ab5e41cc8cfb8928d5c08edc7a707044b49b8a131986a3f37bcdbcab5255b64b4905a93a719d01a32384a87543b6ba1a22db75c9baad257bc8b9d8b78641b394c7ae064087454cfb17b307bc35a97cccb842602990747d60f30d220ed3171ffd7a2b77049dc210e2377607b817f24c011dd736d7918874aea4b8bd98be4597242c95c9641b194a093a928b8d3b30f33c10ba326943a8b704c09a6dfa55f700c488c38a3334716cceb6585008a853162e40a544c0a16878328f47c4e67b5aad276a2dec4c320047e2eab345cc14982b96d1d13566da409e93072377a1729546117a04ce291a2090b60030a35d5b360f9f871cad52f37e63954da0e0a8675abcc3717972f89469978730607293267cac89e3c96a98576c2351d8756429722a1278a173a75114baa4f0eec6a12b09cafdc99fee2c1af7acdae3c747b94b06517464f654adae25888a15cb4c5017076c9d3fac3b1560dd9112d88b2bcf31b15ac420fe5a698d52ab41ef33fa6ca8d8cb9b94d58648f39a138974e8016a972308c7b040d2fa32bfd1096503a3a0e84b9941188a6720e06e6641b896d365190369766995826b72122d780477581bd69b348bb6c5c8f65b4d84ac3f0768ef6645e422b3ed7e38d0a423409c285d0e21bbca97be6707557bb0027e755f9a81912d04b9ebb374bd79411b2c283068670431f2de58d346bb525d192f128c9316742115275e9214def7a61da509b5848013b304216f783d77c3f57b76fb8dc984f05ab557709dae4691b519c44d41813e4b61e6664af5c970ae7a810714217745af087bb00575b18081921a854b7d953e29cb1de704e6578283292168ea73a03e2082b8b641c819649270011861a7b301dcef74e9b116a86f717e30ba6c5398e34390072e20c82f570fcfaa2bd8847a7187052e6b9d0d9bc9fec0217373bcc7b8d38245e40a1597077bb00a408e9eb2bb451c31a746d2aa07fd6432cf176382b6665d45343cf32731817023ee046577abc342bbe25416daee417f2971a8ed4c839126e996a8db40a55bd424c0e534cab677fa1c6b692d2b7e322a331305f75289a1ed102ed604722737e76501c7e7acc69842d6ffb2d31d1003c3b3bd8f4458d93b0270cba21db21a7d16e22e18584e68ea5b890ee839de75b68d60b25d5452bbb91658f3220aaab200ee7a8f070a5b5aa7fa30a768275970012324fe01910e8647945ae6f8b3a17d08e5c36af468a7f6308751c4141439b567eab03d72538ddf71debd2aec5db13537a2b0130b4c2f6662182bd08eb750eb681fce77981a3012102c45642bb8a44ad5cb27cda8369ec28190f64987eb600101aceae7a807158cc8100555a82644b3b513d7cb283a363c70a4ea090241c8a96ac562e7fb3c38f3515c3a68fecb271713729fb77a1a68695fcf995855749c1f0ae09f90741ec332e7602cadb69e55438b9d8ccc213119627410488145777907d280ddb7391d2ec9f27371277c266bb1b14f6eb8d46b2c8bccb0c68f3beb2d87b07044904d5b08e84305b0686f923985a49acdcb1a662d1a08948c9b8d95883518d0ad3933976c464a41c18351216d84066d71164a32d41886a153703c584b747555eefe8309f0810d49c0df8c5512b245f637c9448c47e1456995e922460b8210c7ac1063047c3764077288a1345c23ee0c8fa6865fdd52acb49614207285d241c14114db55cc0c92049f3537abff81b8a30a02e5ab013741b36d92191691b3197cce8d2328bbb6ff61932434899ae01412b231b0efa18d8381555866091c77981e753f8a2b95e8095765ef7a13bd38f9fed3bf36477916cb802690a213c83f6624a067a5e2c9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a588aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b + +comment = Official test vector 14, seed: "e2819ef86853bca1b9dee7ee1c1619988964f9a913e635aacf0d96ca6e0300d084329dabd8f149e24176d22757404260" +entropy = 38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a +expected_public_key = a6bb3b93c181b651918a25235e22779cf052e1d30e6852557ca32aaf841834b423a9e61cc24b5231d7590f863e814aa19f123c0cba97cb3773740871ac23868731748355a85f03b275b3273486142153be4920bc9ee77ab5c05d2b96228906586ec831ebe8cf6f9bac3631b7cc904dfc768b1a717274b33f70d08b6a79c4aec3597e1c9664c9472b6c100c1601f27bc0aed37152e20b327b5d32646f2980bd780c8f476715ac04bf1e03c2d4a31da23b14dc0233c1a2c2d983627bbc845f023e349ca59626a99eeba5dcc12e8b82076ef2295238667308451c2052c6f9b127778a3c656213a23dc7e25660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b881b0365fe513fc661a03689581e045d2f921444c6a76e6344ed8a335b6681ccbc7b42b50b9b03558c64da65088f60b136882012135a8a659355503918ba25da1c167b9fb9f771b5727493c921338c1acccefa80201039d28c968aa3a40c2a28835f63bde23b9722a245ee3c859997f45e10a11f1906c1485b0b51093f51819963393a692ecdb1dda2c88a6133f69f401b124cad796217c818152a528f7d073bfcb9eaccc6cc8825ac4612533126c1ccc736db53f648201ff29a6c3f77b41e01de2087986f237200014e5fa540735513400004b5925cf64b0ffe9575e27ac19ac5644f355231bcdd70348c4507c80780f1d51abf6ac4c5e2957a94325a3f64e83a0a192516f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a723fe1a44fc97543f269f670c593935bdf87a52a1a31cd2b9ad92807407b5851b49eb1a2318611cacaa7710b6764a7e57f8962bc3fc483a8393640e602ca55526eb1be56f2c61ce802b9592f24c14aaa75aa4b002ac9b81fc1327b2a93aa889c9eb178bebdc91579ca7bd30796cc324447892558d2c052308946a451ca49816c06aad39603dd3841ef03ccc1075df164739feb342adcce87aa12f550200ce94765eb4f291a5152941b4eeaba91c3a59257c03017c0b7e0003b07657ba60b4256a8a4b205d7646813246385b348ec157dc6eb3be4546d7eb85c29512840018968743d2ce147f071c8f96c7436596337d69f5074485bf4a288833f2855787f8a18d874c5a2a41422157f65b62b5e581c2181a7023698fdc1ac60a8340a34b29f81b03dc35da2b453fa61293070b1c6db57f3040c3af7766c69b84d624dba1163feb0c71fab6582473f93c8753d67b0259a2eee1c847b1b8a73455a74fa10c3a4c21a35ad20fc36d563be9bc55350f565e4076670f0c77b3c4aa2a06f7bf2ad1bfc4fc8721618454d640189a6f8b3d6c71086dba68b213f4c51100a6037e717147893cdae20a97759204b2c684d8206fdcb10df575799aaa3de388cead4446dcba8e14368f7202520c71e453b41cce426be6c1e29ac475c45742ddacf7c520da15780a9056183900559129e5e3cbb3feaa288b25b6fc69bb8b164c1db8e24391172a8c23859545e98a13725130e45c3d1cbb5d6f5c0dc275608163916013e6e466c29502902c97d3bc33dd006abaaf2aacc40c046e55951d744e31887155a3fa880058a8767b35684445982767c697540ce339a0f4c29c2ae42b5dac5047c12c22bcc155a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815d +expected_private_key = 69e774db244d05192a2e064257f3a7b9b08941a2018aca28c610b8bfab59176bad88b9a7781222cb03aabe6a4c2937be24645a28c3a7931240503769edd1865f72b44c4842114980ba64a59a647438c5476a700d0dc4a63277c4dc73a3dc9b59bfeb0ddf0817612ab73ab14378e93fa4982d15131c5016b36a639e4f689e9b6b2d2bb2501e130eedf72afe4861ae7cbe7e717b4c4001b78bac719c6afd40969392cfb1d918794b4988a7c03a23c8c5a751ed2c39d3e18474b43cf8b7814a5932224141fd543871ac102bb0a349153eb4a13ad57ac06602bfc6c1b4425284ead058572a1c7c0cafdc6756555b2033d2ce67f9155b16726625928ea26d13e2c0c0a66988eab99643b4cf23ac68724ce635188dd8b3f2f421e8e8a9f838b707a16fbf27445a7555cfc052982cb002130ca3500cc428aef14281564997d5f37d0a1c411cf73d3d2082e4c26c3bb7beb9fba2d9ec631f8953b3d03075318b4b720b4fb5b177d43c11e8979c640639136fa20b718c0846404b2f0604c55ca82f519241d811a697000dbce1c743410e92922e83446410a93150178a4a2b52123174db128b2eb97df4e8a617d5876ab9977daa8b7845537db0a2b6e0599c0cc165438329d1251d6aa09d5b30f27040082a135c2b831b7722c416072c655c4d511e1fdc0284932849126d49b5a03b3593894bca250b0d198601a02900c9406d8f5b69beda735a3512bd355dad587bca7330364031573b44eb9c2bd103bafb7283c1b923ac3a41f0607d4b7b7e1e681aac9b4090538b6b7975b9c5c64c6196577b7861cc88ed6c3365aabcc9b97a6a318a39a2ba8b17376509a563b58dfbf4584e6b00d56bbbec309164982d1b906635a146c04bad613c02c8e2c2d0597fc285779c628f3e290a84d8710745c444410f129a140358991d601fdc787faf4506c6003e2130c2e03b3ffed39ca3b9bbaaa34abae794d4266e59a80efb44528b2b234d70025767a5dea09032767722c61e53423417458de9e809a42257a27001e9c8ad43b775bc853d8475abdac86811d568e9e38747618aff0b0901283a3913b6595cb2a85b6d42101dcbc90146ab85ea5449850bc9d8b1356f820ef365731f176ec0a0a5b7f35d9848c426f32d6a37046574a93cfcc043614e8708026621a06ac00582da7b64421d4f50aaac1bb10d6bbaea31808712b891344b7b865243614cd706c2dc098b0a069fcedb89ecd67de8319c92f3aa0a9b92a1fa256302587a5859408b5cab563ef1814cea386becd756db669fdf87a003ea1e7654cab281220b21cb234ac1c4b459ee48517bc838082191de35b265d5264119c05cb500a05307c806ae8246128a8194f61024f5b2b7c410689150c0a8f68e1b3a51dfaa834b7c8ed989b351e683af7ba73dd91e9733282fa2559ac53aa2819811190b5827000d98433241a3da2b77f4e588b0088e3d3318cfd049c4777f7b08678144618e2406b9b6b72698888c4529b7e3b272e92620bb36792266c3da4c9c403d1d49650b5530be017c3b99c068890f2705702440aa0bfca823059822c18981a03b16670e127386265487665aca4c171e023621a853965a629757148e37833d31e453dc9b20191c94230833a6bb3b93c181b651918a25235e22779cf052e1d30e6852557ca32aaf841834b423a9e61cc24b5231d7590f863e814aa19f123c0cba97cb3773740871ac23868731748355a85f03b275b3273486142153be4920bc9ee77ab5c05d2b96228906586ec831ebe8cf6f9bac3631b7cc904dfc768b1a717274b33f70d08b6a79c4aec3597e1c9664c9472b6c100c1601f27bc0aed37152e20b327b5d32646f2980bd780c8f476715ac04bf1e03c2d4a31da23b14dc0233c1a2c2d983627bbc845f023e349ca59626a99eeba5dcc12e8b82076ef2295238667308451c2052c6f9b127778a3c656213a23dc7e25660443183298753475bcaf667a9483192c6bf553b7e50b44a84a4b881b0365fe513fc661a03689581e045d2f921444c6a76e6344ed8a335b6681ccbc7b42b50b9b03558c64da65088f60b136882012135a8a659355503918ba25da1c167b9fb9f771b5727493c921338c1acccefa80201039d28c968aa3a40c2a28835f63bde23b9722a245ee3c859997f45e10a11f1906c1485b0b51093f51819963393a692ecdb1dda2c88a6133f69f401b124cad796217c818152a528f7d073bfcb9eaccc6cc8825ac4612533126c1ccc736db53f648201ff29a6c3f77b41e01de2087986f237200014e5fa540735513400004b5925cf64b0ffe9575e27ac19ac5644f355231bcdd70348c4507c80780f1d51abf6ac4c5e2957a94325a3f64e83a0a192516f6cbb40b8abba5f8b85bf2aa60e44b46585bf009a723fe1a44fc97543f269f670c593935bdf87a52a1a31cd2b9ad92807407b5851b49eb1a2318611cacaa7710b6764a7e57f8962bc3fc483a8393640e602ca55526eb1be56f2c61ce802b9592f24c14aaa75aa4b002ac9b81fc1327b2a93aa889c9eb178bebdc91579ca7bd30796cc324447892558d2c052308946a451ca49816c06aad39603dd3841ef03ccc1075df164739feb342adcce87aa12f550200ce94765eb4f291a5152941b4eeaba91c3a59257c03017c0b7e0003b07657ba60b4256a8a4b205d7646813246385b348ec157dc6eb3be4546d7eb85c29512840018968743d2ce147f071c8f96c7436596337d69f5074485bf4a288833f2855787f8a18d874c5a2a41422157f65b62b5e581c2181a7023698fdc1ac60a8340a34b29f81b03dc35da2b453fa61293070b1c6db57f3040c3af7766c69b84d624dba1163feb0c71fab6582473f93c8753d67b0259a2eee1c847b1b8a73455a74fa10c3a4c21a35ad20fc36d563be9bc55350f565e4076670f0c77b3c4aa2a06f7bf2ad1bfc4fc8721618454d640189a6f8b3d6c71086dba68b213f4c51100a6037e717147893cdae20a97759204b2c684d8206fdcb10df575799aaa3de388cead4446dcba8e14368f7202520c71e453b41cce426be6c1e29ac475c45742ddacf7c520da15780a9056183900559129e5e3cbb3feaa288b25b6fc69bb8b164c1db8e24391172a8c23859545e98a13725130e45c3d1cbb5d6f5c0dc275608163916013e6e466c29502902c97d3bc33dd006abaaf2aacc40c046e55951d744e31887155a3fa880058a8767b35684445982767c697540ce339a0f4c29c2ae42b5dac5047c12c22bcc155a63a8610db945708cb5425ce0c3c651532a43d32473f236519d54fdfe0a815dcfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a + +comment = Official test vector 15, seed: "669c4ef8a051ce201da65fc4bc34d398ec1f806276fc5d987ad71d93bc12dc8f107b58be6e8422a0795c88cb9a0e7488" +entropy = 97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 +expected_public_key = 8452a77401c4e343bdcbdc985b70189ea976e3d65c47649593c9cfc112a4292238302253118cab8ec52060305392e6a131f0445a0bb4e11a1a8d7465e704b3134c3807d9be9f8b2abd57a00758685392592fa0b01e116410706a669a0ec5acb524d1561a265e307c24068b12897568490458121c572c2cc43b2464f2703212641202a40b27a41fafc4b24bea9f26711f28b1050645a38757708ad607ff6763f14c15a2caadfc2bc4d23c576e5cae6a20b10cc9cf610a5931ab4c59ecbe67ea079bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da3515288f933da602f1a2747a6856657b2102774bc1946163b534d02a1ce2e641cd9fc7f7d48b6f643ab53045bc690a249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4b414c223a52a6c88475405232c78ab3aae8861a45a817ebb16c3a3070b8e842527e965013244fe50907bac3883122393340b1e06728fa0400791b1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a58604599eb6d1d248a37ebcb17335713c4c9a0500fbf893df475cf7c19792fd56fe0a7505de0158f34603e0071b2aa0bdc8a12376a1313f571d33686d505660c4bace8ea40820918e05bc15b381b90d9b31bf52e1b18c422c3935d04140170542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472b409b1ec31ec887fd6e76ceec6812d40ba4469b3eeb028a0a6875a19b7aca51465cc3fe78566a3eb1b98c621eb3bbda4e7beb5f2344b64013ec233fb5714bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f7a228d28a5936968915d026cf683c762714830c1742ab4dff789f1f43782622a070a4ab52633efc52693b695dab939bc24944733905ae86801c4577324c625159b141c5a1014a6e458b71a959001839c461e17a3ac46da47ab687d2342ff63b83d3331510c98ac484f44b7fb6a31f6926cf047982c400008bb3b0d1ebba3cb2345613680531b0708a64b937c88b2985c01a10eea22fe5022912f9ad2bc667cea16b0a091f3fa9bbb9b8c30160717b21cef9d74458241beedc215d44900cf40709f6671f221d39c804eb6756c812364df0503355b8b01102574ac3f07234bbb1b658ea822d52a452545da3544c041c3a3f89ba30005a992b432178bfba078686a07971601f8b12c22b23b69c05a89adc2469287f052a6d4f58798e10a464db4aa71ab30a94854d1b8c16893b432a8dc2859c66a168c8c5ad4d04559056c4588b0a8755013e378545b47efbe90ca97552c9b8711d3281cc7b9057f78a68a59d5aa642d1e9233de093df5705d8639d702097f0dbc98451a46905ae72d876e1243546590599fc5923b37b4cf0a3f7cb47dfe8af00f6a999127a256681a5705bf5100d7096713c49149c7c561c0783e048cc3444776bf8997671970535c2cac5360c9b53e0d952af348a28e4826db9810f07110a48771c2c9b21da3ca719c7a5407b92020aaa0180b4d6b3ae42a1c09ca38fa59d1ed02a3a0079f2e922d0b36d9795c1fa42354ca51ddc11a315515a45bc7e1e21bcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dc +expected_private_key = 48c78cb714b9cf88a8b317a6fbb681b8f47d56524122156503823b600236d3726edd9087504705cb4698a1515dc0d80b3f87c63d575170f45d121a848d897c3c0063dfe9b2d616a96552384fb72d6226a193f90e15b364ae667c34ba27fdd0ac0debcf450578c6d182da365d40786522c37b54e0126ed7b3c6bccf28f40770f23736b394210b67ebfa72f6b27799fb1f6e48cb7407261a86884621c529974635b35f5b4c530e68bee8cc213387b66a4127d01223180067a2ec24b2ebb579f74bfd5417fe995bbf816737722912b5b4dbb4c938d0686d1c2a44880fa7231944c195fbd67c67e60861d169ddc41f8150b52a68c14425190be2abbcf5babb734aa03538899678d4290738cc63eee611e4344ea73b9c41f36c712a4c6c72422000cb93e144f3c588a2299d5704cb347b90b2905cbf69cf1dc5c670909c478094e88c01bb3b3e4fe246f8dc3c62da37bb13b6e2046911d85d5790869fa4a54ff16794620480919c0dd74b9887bb5c125c34d76b3527a42a46b689fc4c57571af13c44b7d30a041028e97c0a1e50621567374de7a4207acd4cb18417c7984645cf4f2b5a5434be8f119798c0760229301e14431b0b652c643c0ea0ccaa13cbc6fa6dc8d348b908b78343978fd5a0eee90ca5104184f33f107837b3ec667eb207000570dd33856939bc8ba671b3731edb2a94596a8f2f37bbbf5048087091fd2ab164f5c6a8f92f65239f08844ed4f605e3bc1bf780877eeb3f4c85bf696c691f85a947461331aa33b15973ab4923f429c7913731bc025539232217f801ec7078e2f0af3ec7494684bfc40b4ff31798467746f60bc9bccb5b1e397dfc6165773a965e55034dd1094966694d7806f2f505cebc3b3dc307405431fca21614089c633b522510a5fca73462b32fd69200dc614c5e88454f181d845b19b8866259a2372bb3361b9abd5aa278b1773057e26108bb020a9610bc19af13454df46b4fb5a68c3e7aba6e7197ad63439c7252cf9507e32072e437296883c93902250165a1aee8be0ce6acc2029e10e97536eb958b691ae3e3aa9996986805c6d1f6356d26c1e63c550381b292fb1b95e183ca933d5be1baf6294c4b248b4264724712b2a2816ed3d09042287eb8a17ad6c86255ac492f53a21ebcc19b3c8bb1e78f58ba98bc8aa77f6a5cb90c0456e1cd663137e11185536b02d8708644539701b193ba52258064b289d053404bc78a397ab86895baf1934e8b2f6cc3ae48869be7422e581a6ff748519bc30bc96c716b0a24a02679acd5151cb2a0fa127c81ea513c3ccc3b84a34025522486ce424bc04c860edc5758aa990fed372db324614fe91589d78acc88c43c2643d540a509f090ebfa6214832c76ca982faa1ca4465f9c14ab4e6459f072558946ceba113b5fc7024a364970c72933331a6a4b0d4196b9e6219595e229f3e28fb2d5c6c4c041db226ab611b04c3a80fb5a7f15e08df3347def02663aa39409ac4e8c8bb0934b46b6a8816cc70c8c0b11a7ec1cce57bf5baa30e69207d7e59c9e386d5cf7863c133ba1b510f5e06c4876ba7849611bacc369b039efe173df6b8a22469e1f200f2aa53ff84390b88302d9f9915c4b8257754b3423097e7c6b8452a77401c4e343bdcbdc985b70189ea976e3d65c47649593c9cfc112a4292238302253118cab8ec52060305392e6a131f0445a0bb4e11a1a8d7465e704b3134c3807d9be9f8b2abd57a00758685392592fa0b01e116410706a669a0ec5acb524d1561a265e307c24068b12897568490458121c572c2cc43b2464f2703212641202a40b27a41fafc4b24bea9f26711f28b1050645a38757708ad607ff6763f14c15a2caadfc2bc4d23c576e5cae6a20b10cc9cf610a5931ab4c59ecbe67ea079bc3911a96b24b86a0d6b99cf85aa44094b0f6c55924776c4e1bc9cfc88a127b8195145da3515288f933da602f1a2747a6856657b2102774bc1946163b534d02a1ce2e641cd9fc7f7d48b6f643ab53045bc690a249433553845b34a5953c873c1c686c83ba46acec4e91046f9e7590196c9c24a747c6d986b4b414c223a52a6c88475405232c78ab3aae8861a45a817ebb16c3a3070b8e842527e965013244fe50907bac3883122393340b1e06728fa0400791b1dc3ba103c8aadb6cb0328b5efbc85694164d0934c207b63614cca28eca71e5f63a58604599eb6d1d248a37ebcb17335713c4c9a0500fbf893df475cf7c19792fd56fe0a7505de0158f34603e0071b2aa0bdc8a12376a1313f571d33686d505660c4bace8ea40820918e05bc15b381b90d9b31bf52e1b18c422c3935d04140170542829cdcfc883bc344606e75a2ee7af469c5a81daa1071771fff275f2358472b409b1ec31ec887fd6e76ceec6812d40ba4469b3eeb028a0a6875a19b7aca51465cc3fe78566a3eb1b98c621eb3bbda4e7beb5f2344b64013ec233fb5714bc68b767da8b60a6b0ffc8565369c19877c16d7c70f17b85f7a228d28a5936968915d026cf683c762714830c1742ab4dff789f1f43782622a070a4ab52633efc52693b695dab939bc24944733905ae86801c4577324c625159b141c5a1014a6e458b71a959001839c461e17a3ac46da47ab687d2342ff63b83d3331510c98ac484f44b7fb6a31f6926cf047982c400008bb3b0d1ebba3cb2345613680531b0708a64b937c88b2985c01a10eea22fe5022912f9ad2bc667cea16b0a091f3fa9bbb9b8c30160717b21cef9d74458241beedc215d44900cf40709f6671f221d39c804eb6756c812364df0503355b8b01102574ac3f07234bbb1b658ea822d52a452545da3544c041c3a3f89ba30005a992b432178bfba078686a07971601f8b12c22b23b69c05a89adc2469287f052a6d4f58798e10a464db4aa71ab30a94854d1b8c16893b432a8dc2859c66a168c8c5ad4d04559056c4588b0a8755013e378545b47efbe90ca97552c9b8711d3281cc7b9057f78a68a59d5aa642d1e9233de093df5705d8639d702097f0dbc98451a46905ae72d876e1243546590599fc5923b37b4cf0a3f7cb47dfe8af00f6a999127a256681a5705bf5100d7096713c49149c7c561c0783e048cc3444776bf8997671970535c2cac5360c9b53e0d952af348a28e4826db9810f07110a48771c2c9b21da3ca719c7a5407b92020aaa0180b4d6b3ae42a1c09ca38fa59d1ed02a3a0079f2e922d0b36d9795c1fa42354ca51ddc11a315515a45bc7e1e21bcd3287e18bb0ac3f8119a88d1fbce1d3419bef67b6694d9fa1bb309cc61c819176964dca19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2aedf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5 + +comment = Official test vector 16, seed: "9debccfe818f6b5204db4ea09c03ec9a19dcf1629c1527685b8a29776bb1daaec45f8abf8f0adc9a8c8bd6e2df6d8048" +entropy = ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e +expected_public_key = a16730c3d8a8484295a1d995716a3bf93c7270671afb7886f397af65f5bac1b1a1a49084d1a672a1f98bca762287e90410ab01098c74869b42479c2cae5906ab354970c05cd256514f5c2e763230b6770884e7b700544977993df1f57969e0265fac4f474b76648b36f5711163638069820232b8a64f16bde83557b0540405d7987cc39069923dfa984ca4045999a77483e04fe6eb0be954a74c13cfcea79ed0d8124b01b740a26ed961b2bc496cbdc539a10b8151e0078f66751fe78d2f3a5100761c8beb514923a7b4f3ae208766fd852222dc31fc1a59a883c401459dc73468eb35af61d28ec1da147c882cc7f5ad5204bd8da270e4c91dc37baae1811cff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6896a288a9722183e199f608cd7a412ca949113e87a956e4ad12737d53c3be4752533bc755f7a1c4b07661e988210ac72131b4496941893a9c6f1180ba622436eeb02f3a3a090c00b1ffd310e811a7a8b87984d275d76b0f99abbfa45cc5096a1562a375f0599d9698b18012a84a0628601c731ce1ce6824907f1b16878a75418c2fb0751202fcc988779be2326e2e5228c9493a0e628441b13d58b3c79df34b7b53c7be816cc7368f2f31c380296250b33269158c4f9706d75b3b5536adfe5b0bcf514899287b4b637bb4249db25a0413533d628597ddd745a7f5270d136763e48a517ca62e116913350e7361580cf77bcdb5b607b38d49e1581654a61ad9602f4415f484bccbd833255a29d2e76262b401f7fa5a1e68bb136771c41b29333b653602b79a2aba21004e8a257df7362163b6512eda4e1376aba1facf04d1aa56c814000d718b5b504f1b9d2e627b8a678d0294c5e3b186a67c082b90abb1c839232912c39c3e02717a65e24a185a5d96e99851eb538a4ab872148c2d7bc52ec4270f708690d0678d43c783ca194b4aaeb6f2156297355d7823e0f80890608768c65073e04e7e5b45acbb1cb6446483e7c315a0a0c2066f080a53818a4ec0e4973f630f6822a437f6684fc9431f20a306a055f9906435172699b3cd0d46457be26560f692864a97f80b493093270b5225980287f1f5711b355f9ccc018d670ed8ba64f10ba98b0068e7714074e14736087819ec2cbc960fe6939a4e9a4de2045b53e81fbb845b0e546de6b34ee9e91ecf0c9f74c569dec949d3ea11785639126bbd45137021e9670735488e46a325342a2b4a959297816d1ac731cb501d628bc09083ab5c4dafc09a36c7c70f2885a6622bb7162aa2c999927a1fb749bae280237db21418e2cec419990288b813e80765b47e4c314171b849e570c7533cc5bb77cb9f10272926c382fc0796f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4da2d5264b282b32933d8c74242aa73c15875934e99d6c570572e03c54e47726e3b0416d3737a29624169778970e99de64bc2b16039ae97c7472a41c9a6c6fd45bd7738cb662505bb26a307a2cfb9680f5cac086f9bbf7799263c0b5367032196f1bd842534601094668a33bd339db59746d63ba6007887ab750f5887453e02b22c3148bf6c48c806a94cb7bf23568789a1260c87af0548c71881401c565268317756a211b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2 +expected_private_key = 953b6e6f452ffab6b9e27b707f600992e228f5fac92680aaf31300154b218ae51a012a4cf53840cfd714cb63cb4c7aa0e8ea6e50803ca370bb38c7205d9365448b38308868c83348acc365be62b4fa763ecc5112a48558e57230d92b5869d77d99a5c0bef49819500b333300910117e05b082d15368ae529923c6bc9d3594ab33c91b81549829a2ee55ad152493e80aa80399f770899ec05417a698e6493aa647691fedc92854c23702caafc8ab3a3194ce8437b8e2a7f69454adf3170c282972abb93cf152dd85587f6272b0b71590c81b3a9f680d19445fff0c395310a17f55272cc3e1364a9aea7a67af4561cf10043b7b7eb4ab0791a8d62814f4b6536cfa69ca0493fec1a53d58709fbab9c87578d83c9441d62c267e7aa4ef0afc7106c9f834a5a13206c4b58d7378af90b85f7e05237559d6d7819f455aa01d68bc297a8dd760a0df971542919979218b4861a49e45aab12be67080d197c25ca53483d781ba27893d23baecd393dd1643dc2a53275c84a19900b364ccc94a8ba3b5768f8dbbe08a7b08fd2746bec62c98c5e5198695b12048ba5c98753aaba88bfbbc6c8de490afaa8343d334aaeb72532c63d60667079b41b6a287b04c797458acd9104c94e96bf18137b0868737dc00a8e2164e0980b9b2135dc7c0e80e1b930c22874fc2cdbe0b5542732e8fa80e407a1a6e5af0aa3168a963587379aa3e6a2b082a8a35604bad827bd6aa1fea76a608100ddc40b17283eddab2335b8796dc1bb57887787a4273c4185867368be581f6e5767bbf0580f07b003556ecffc3ae336260fa0a80a2c9e4c9914144551c89a9d68373ed9c7afa83c75c6b8affb54187d3b46abdc61d9e070b5584be7564f932985ea4c739cc906732a7cf79a65f0f7b0682caa5d2070b3e0699b1bb3ac0b38caf22ca4db9472d06b02954e36c0a3d8890473588c77e43990da1c7103985761ca711109bec0b805607d732a36baf897e93c6d9a988b94c67a4592b7583126fd452ff0b45a033824983715c60478685b9c2d013d41b47eb342a05fb76232554df30990d6f1b37ea9172020c66fac8f415615ebe07833a2588ef622034074b214ccd9395648071821d1109daa87c0e00cd9573254538ec3b8459ce56578c09ca66a508e88c4dbf6183a268b86fa4b7733a8cc89ac81619af8f56d8adb1f665a7ac413005be730aa41cef2b06a7fba535552c8cef73e90a8584a8b799c323f61faad4b8c25d06cb883493147069eb1c9c8fb262b699693d0601262e9ce5b383a0d27c1572c49547bc908c003490827343a690859a15b20119975c35aa991183052f117b53d06c5f4683d19ca5ba6f5595b8b269d96c1b3524cc8fc6eec750ca33b5518603f59b50741d246642bb88ef61a8bd4c54f48af3f573d4cdc5143ecbddab5a281400721544e16e35ea7a05f161003a6c3adaf690189bcb074f546bc2033b1e8b00d56cf32e0733dc81d05eb358d148a91faca963b814a9c5fdfdb4de79b729dfc26c3d9b48a4730337b0bac8c2a3628268159979f6b10aa9ab90adab98b9c0928fc4e3570ab01f02d5a64c5f605596e3498ea532472760f61cb2eb734c174e48237c656636645886b65c566bf95d927a16730c3d8a8484295a1d995716a3bf93c7270671afb7886f397af65f5bac1b1a1a49084d1a672a1f98bca762287e90410ab01098c74869b42479c2cae5906ab354970c05cd256514f5c2e763230b6770884e7b700544977993df1f57969e0265fac4f474b76648b36f5711163638069820232b8a64f16bde83557b0540405d7987cc39069923dfa984ca4045999a77483e04fe6eb0be954a74c13cfcea79ed0d8124b01b740a26ed961b2bc496cbdc539a10b8151e0078f66751fe78d2f3a5100761c8beb514923a7b4f3ae208766fd852222dc31fc1a59a883c401459dc73468eb35af61d28ec1da147c882cc7f5ad5204bd8da270e4c91dc37baae1811cff4cbf8605bb48ac8585094327a8c17527bf5b3968aa268e152b6896a288a9722183e199f608cd7a412ca949113e87a956e4ad12737d53c3be4752533bc755f7a1c4b07661e988210ac72131b4496941893a9c6f1180ba622436eeb02f3a3a090c00b1ffd310e811a7a8b87984d275d76b0f99abbfa45cc5096a1562a375f0599d9698b18012a84a0628601c731ce1ce6824907f1b16878a75418c2fb0751202fcc988779be2326e2e5228c9493a0e628441b13d58b3c79df34b7b53c7be816cc7368f2f31c380296250b33269158c4f9706d75b3b5536adfe5b0bcf514899287b4b637bb4249db25a0413533d628597ddd745a7f5270d136763e48a517ca62e116913350e7361580cf77bcdb5b607b38d49e1581654a61ad9602f4415f484bccbd833255a29d2e76262b401f7fa5a1e68bb136771c41b29333b653602b79a2aba21004e8a257df7362163b6512eda4e1376aba1facf04d1aa56c814000d718b5b504f1b9d2e627b8a678d0294c5e3b186a67c082b90abb1c839232912c39c3e02717a65e24a185a5d96e99851eb538a4ab872148c2d7bc52ec4270f708690d0678d43c783ca194b4aaeb6f2156297355d7823e0f80890608768c65073e04e7e5b45acbb1cb6446483e7c315a0a0c2066f080a53818a4ec0e4973f630f6822a437f6684fc9431f20a306a055f9906435172699b3cd0d46457be26560f692864a97f80b493093270b5225980287f1f5711b355f9ccc018d670ed8ba64f10ba98b0068e7714074e14736087819ec2cbc960fe6939a4e9a4de2045b53e81fbb845b0e546de6b34ee9e91ecf0c9f74c569dec949d3ea11785639126bbd45137021e9670735488e46a325342a2b4a959297816d1ac731cb501d628bc09083ab5c4dafc09a36c7c70f2885a6622bb7162aa2c999927a1fb749bae280237db21418e2cec419990288b813e80765b47e4c314171b849e570c7533cc5bb77cb9f10272926c382fc0796f39924b6971fe6b54638c4cf25318e146aa02769e64c47e4da2d5264b282b32933d8c74242aa73c15875934e99d6c570572e03c54e47726e3b0416d3737a29624169778970e99de64bc2b16039ae97c7472a41c9a6c6fd45bd7738cb662505bb26a307a2cfb9680f5cac086f9bbf7799263c0b5367032196f1bd842534601094668a33bd339db59746d63ba6007887ab750f5887453e02b22c3148bf6c48c806a94cb7bf23568789a1260c87af0548c71881401c565268317756a211b6955ed03c49e0beb46c4ea9ff7be444932e61d464966bffc96bec0647ab34f2e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e + +comment = Official test vector 17, seed: "8098ae7a92c10f707d405f7dea02c2efbef44efa132ba8aefe81bd45e543ecec74f10920ae48a40b0653d63532517f2a" +entropy = b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 +expected_public_key = ad735e9e838da63ac7a3e1cd3e574db17c2601d3927cc2a9d228a05f5c1e51a63634383ff5e03151f43c66a07be9e992aa65ca4ca17b1e021e06b261ccaa89b12a4916a5a4e39826a94c86bcba9fc7d65ff04549db70b300b1cb280b3a41e82b6c8b0a4a3c5e40eba59fd18f004ca3e4c15bedf22e099c99a3d114eb0c5988ba02873b9581107a23e54a8e51ae62375a887929f7333d4d763e23b20a246785e07700bb16c531692531433eb6a6594d1464bca7348022c1d4219cd8aa6614862c42376c3a0c4674181983f2a2ce8b7f32659ae87accab6023938592e188a3c1015e98720eacc9aa837a49c4617a850c89e1212478f3c6bba51c30a64a8a1c225274c92ea953872342a96ca3235ca7a9467be55250796126b30694f71b2f75b56d84ac89c4b635118145c7b8967de515ecc719e35804194b7ea9304636283cbf72339474ce1da00106110a596725574747dc07b3f0c7c527aca703cb23baa080bb7a4cfc1009b3e5aa89659121e365fd6cb6fd15afed70779a978b3ff50f915b6c16a350141721efd61085189c3265530c1a17491b317031b4e4667eb8314ad34cb7daa50566a9812377cf24076fc3dc748fd58865b1b02dbb831b25b7b7383579376fdaa6c8a5323230025a4bc66977f6a458374faeb14e47f70e654c42c94a5fc5e386a57abde3f29349623e4de92f900527c165870fcc26a2f95fa1850f2c940fb7b87686e253dd54b6706a84a0c70e3ab04ca8446efb77609e9815a261af5a135836064d44a485b5e850f10153653838e5874b76568516e847a2a9b186e8a50c34c2d2b0839ee58024211018b0a13fc781623cc313b30c26a258106941a66b3cd9481aca7c7e3ce3202f098746c42c58f4c7dbe52fb5f606fbf31b9b5022e691cbef1464f6942aa503147eba081817ae28581ecdd867a96195db320bd2d91c36db01ade9affb6b00f86c13e2e252c988300b05afcd007470cc3022e96af0768dbebbcf62b53345b213c1544491f1bc75ba96bd73be57a2cd6874511b44bf2dd27f4fc87c167815fec59f7a043f699ba4d23400886a7214160c23dc96056bbcc7007a0049435c534b66971e6e5c90effa6645c45031c0c905b9887700181565b53165bab605a51bcaca0dd0c308a46432794c38f21e04172005f4348211c63a40cffd7c32bcd57fde852fec793cb7013e74504721f6bfb7637f73319f75b08e3c25777c969c6ea000c9b79d6f16a00cc4b00ad7ca4f8704b2e54d9d27524f6b80a6d51f85447b22c29af0036c6ba486862c8b4fb03f26042a0e195a3e91bc303770ac844e77805e41ec6aca920ff3a1a3abe81b598c193723b20c8685590131da89c0ace08a592489791911c92c7e6ed55f642caf918173f190b2fb8cc0cb2139fb6caa259b5a4634cfd0a532b719903e32831489a2d390b4c5a5066b4ab5a3316441b162407096a0bc0342599804752fd4f21c45923705a7a04012ae4a900c01d584f9f41676c36681994c2f4037bdfb84a69a81fa561e5be05777b571922988eac714ff249926fc9cc4e93666e198308a434df74dff3c5a440948437a7c500582124574ae225f52d322d0909b5e946a5e22ac8f774f69c48b7874417bb1c0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a +expected_private_key = 87c0b4d44cc9eb48c126c5877ff87929b08485fb81e479139c3299c70c43c3fc8c238a81d4e61e62a33db2499c866b7107d116b7fcb1b0530a7e758a8d487d11575079265b3158302a23732bd07330071bd7cb7199476c39b583a2446109e99fd5c95be21a292cf37490906e84a82605b8455825c82eca4b7e218644460ce581214c78ac4473688bd6a9a826217490ad791b7835a85935782847981ca97b6dfe88b63701cfbe3929a2dbab1628155506c353639d153656b90c5aff36baedf1b87da5bce2a108fb6c3b29e77dae803a0dcba48ac6882f6c1194e88387f30a47c27d02c37d988346a2a29584a55cb5d3c44c05a18619a4fd412babc31a046221b3994c8f22ce272c9e6e948c3d043295f413349796c38911f8dcadeae47351c15e9a1743eb65bdc7471f37fcc93cec867cd4808ecb281fc17efd004dd64ab432d664864b43f8a9b1e763529ae2c413abbcf30a4a478a30a0104d802037c4a8af01b534dd600e31a1630ff13b2f730924cb790166af3b7322baf4409cbba500c1bb32894e65445f04e4b4b4933de51267635037faa44e2775caa4212f4e0600e51069aba662c86145e2117347bb1748d63e412550c004237cf02b02aabb18d8533d19b1a879a079b31d529aacbf5258483c80738b380c83119c12b23cdcbc7d027506f3705ce1316dd24594a4bd32d10382f8ab47478f23763898398d7430264203a76b0c4455237f3e765ea5516388595ce9e2bce2dc2258b5b96c782865fb5354427a2d7806123b0cca782b1c329411c6c133934ba4a959da88a072bc6e2d63a007572e36b82c5643564bec47bc8953d4aaabd146ab5eb36e33f825fb9ca01e223253c320f76c98f810ca52a2c604622f7a60378809a59b19680aa69eed2003e272b8a1f3c8a55bca129640c5a00d187bcaf465204c73cee66a2feea414f02859c9988356d26665196674d25e64cc5689965cfdb2c0e47a531ce32b3daa9c649954342a3f62253fdf826aafca7dc85a7a8e15161435212d7a4a3bd4b57a2ccca3506999d407d9b6abcc97209fa97454b0974dc2c7cf3c3fa40306cd6239dc450536974a8ab773374504b9889cb42bce4ef4606bdaa559346f18d087bf8b7f0d9b21b0c9b75b5903194b0744a1c47483488eb4c1ca2c83d8198cc6a523d9329f6582863cac2951268c01770a8081c1c26587d7610088e6068e020e10472c825c395ac6783f074efa8597feac3734399bfa247e4e1531eac70fe49355e44b3ba5439ea1e65eda94485fb710124bb968490f1c8b68e87a4c4682156fc06a33275b6b202aa0d508b3789aaca627f0f0c19026cec38a95f7547d936b255be7a7525c97ab4282714c32a23c4723a82298f2ce90fcb4761b9eee869e4d3484ba2b222dc28bc612b1f41607cf57781990009f29617549c0b2179705a34916db154aa3747867c3ef6a0693bba5c1d42e14b3247b41059f92607a60afcdecc1c6f3839db943f5ebc4d340aabe21269095b3f7d9bde9ebc21de788794b63e1098cc2903a83ca2027e8bcb78b855fd56fcf16b45e47994aac71fc815c521ac1a1b697a18569ac2816f52640cf9059c4eb95e6fa1b32b77bd7cbcb6ab384de74b6a2708400e980ad735e9e838da63ac7a3e1cd3e574db17c2601d3927cc2a9d228a05f5c1e51a63634383ff5e03151f43c66a07be9e992aa65ca4ca17b1e021e06b261ccaa89b12a4916a5a4e39826a94c86bcba9fc7d65ff04549db70b300b1cb280b3a41e82b6c8b0a4a3c5e40eba59fd18f004ca3e4c15bedf22e099c99a3d114eb0c5988ba02873b9581107a23e54a8e51ae62375a887929f7333d4d763e23b20a246785e07700bb16c531692531433eb6a6594d1464bca7348022c1d4219cd8aa6614862c42376c3a0c4674181983f2a2ce8b7f32659ae87accab6023938592e188a3c1015e98720eacc9aa837a49c4617a850c89e1212478f3c6bba51c30a64a8a1c225274c92ea953872342a96ca3235ca7a9467be55250796126b30694f71b2f75b56d84ac89c4b635118145c7b8967de515ecc719e35804194b7ea9304636283cbf72339474ce1da00106110a596725574747dc07b3f0c7c527aca703cb23baa080bb7a4cfc1009b3e5aa89659121e365fd6cb6fd15afed70779a978b3ff50f915b6c16a350141721efd61085189c3265530c1a17491b317031b4e4667eb8314ad34cb7daa50566a9812377cf24076fc3dc748fd58865b1b02dbb831b25b7b7383579376fdaa6c8a5323230025a4bc66977f6a458374faeb14e47f70e654c42c94a5fc5e386a57abde3f29349623e4de92f900527c165870fcc26a2f95fa1850f2c940fb7b87686e253dd54b6706a84a0c70e3ab04ca8446efb77609e9815a261af5a135836064d44a485b5e850f10153653838e5874b76568516e847a2a9b186e8a50c34c2d2b0839ee58024211018b0a13fc781623cc313b30c26a258106941a66b3cd9481aca7c7e3ce3202f098746c42c58f4c7dbe52fb5f606fbf31b9b5022e691cbef1464f6942aa503147eba081817ae28581ecdd867a96195db320bd2d91c36db01ade9affb6b00f86c13e2e252c988300b05afcd007470cc3022e96af0768dbebbcf62b53345b213c1544491f1bc75ba96bd73be57a2cd6874511b44bf2dd27f4fc87c167815fec59f7a043f699ba4d23400886a7214160c23dc96056bbcc7007a0049435c534b66971e6e5c90effa6645c45031c0c905b9887700181565b53165bab605a51bcaca0dd0c308a46432794c38f21e04172005f4348211c63a40cffd7c32bcd57fde852fec793cb7013e74504721f6bfb7637f73319f75b08e3c25777c969c6ea000c9b79d6f16a00cc4b00ad7ca4f8704b2e54d9d27524f6b80a6d51f85447b22c29af0036c6ba486862c8b4fb03f26042a0e195a3e91bc303770ac844e77805e41ec6aca920ff3a1a3abe81b598c193723b20c8685590131da89c0ace08a592489791911c92c7e6ed55f642caf918173f190b2fb8cc0cb2139fb6caa259b5a4634cfd0a532b719903e32831489a2d390b4c5a5066b4ab5a3316441b162407096a0bc0342599804752fd4f21c45923705a7a04012ae4a900c01d584f9f41676c36681994c2f4037bdfb84a69a81fa561e5be05777b571922988eac714ff249926fc9cc4e93666e198308a434df74dff3c5a440948437a7c500582124574ae225f52d322d0909b5e946a5e22ac8f774f69c48b7874417bb1c0b93cc0a90d2a9640377808ccc2673495c4839fda0d1038b27befe3d22e2b727a2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f40f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252 + +comment = Official test vector 18, seed: "d5f23808871544e9c1d6eace2028362b48e225312f77663e9f78cafeb512b908cd9e25875d61a16ec615f4b8ff826856" +entropy = 9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f +expected_public_key = e0b9190b548bc164bb826874c1800980dab529866b951c01c20cb4ad363c681336b13105fc338b1788afbff321bd981974c33d98a35666eaabe3612e61839d6ad65490d71ae992111719aacf12a060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b0731621cc04e6e2061e93cc4b51209ec92abb303bc638c52ab2ae40d746cfcc43b7576a240540bf410c14744f80a442d0555d474192bcd9b187a56691b63965973c7793668682852f91cfbce70d6d4832a1855cc4b83a847734c24019c508b2d29539fd1a114f787285e197b51bc092f80b559446f1076f02e984a1b27cae7aa1d0b50967939aac74cf2335ad421021e3225d94fa3b09148e60c20e8454c68a8022043206b7bb1e799c9b69286509a188db29a9ebb078420a0844c858cf4b11f9b4959934002be0229e714350451b9c2775a5cc8c45b07e121290eee32a73d46f8d7c55311a8c29027356139f153cb405fa14064c5c31060d7a964b33d76bcd4809d21b34a2f7806486bd2835b7f871164ae496d4264f89fb4eb15b7e5a7232b6c68b11351a41b09bb0c92c8437534d2b4c0ca2538023b29df93d93c98136780ff6f82846cc2868664322ab28dcd7279f68994ba5a5ed406d4d717d16c14dfdda58db1524f7c53f3cb170d45a411b07cd64f001daa0ad1bf63a11550c0c154d20f5096db44d1ab0a1c9d66581891a9314c18f778330a0936e7a2f3e19c18f7bc87cf078627770dfc5a2fe71b27eb8276863c3295c11e08703ef4a4ff6b3a1871c7b42c43a6eeb6bd1526aa95b7dcd6b38edc207c630bed1768ce9505544e9053e5c8cbf6a181a1a0f48c8a98b59c3adebcc3a5c99e61588834024cfc71c9dfab1df558711b311404a739f79b45b1a8a7633081a27a08c3c16478c9d24c1229723addcea225d39bde7851345b18b1b08254181b01623347a9a57f5d902290b10476083949556663309059815626c3ccb5302b978b2ce82af231934ffc7732352b990b21b69210f2acc048387b95c346974c2181148078154416e08564d664db3045dba82c9a7934de51ab5c1d7346a391baca48209c8c7235309943c1cb9cab4771c7eaf59321b510d430c88473ab16f54ae461a5dc613c6fec61a5e899552e835eff57fc34b7992755d178a0365c52b3f020ab40020ce21b45717654634606dfb2917fcc266193e2e5b2c4559cc5652aad1121cca0711e26c23eb33c1f7d389f2d742f384725d3268f8159f8c463585998289e58369fbb883caae21b87139e52d7ebb92b011cbe6426390458247c45f06f2519ab35b35675bf93325351617ad3ac470f73d3d3985e10277a647c96a6c56cc2346563cc496db232fd742aea3adcfbc506ca8cbada7b040a04f6e329fcea77bec0683e1a87c396113639159d9ca52a5a5484d2839869a2e80557a6bf7ce2ee295a464aaf835c542457d021c65c2b2a457c771fcc47f8b1056c8b7aa61d1843a40c4c9b083269b2e89fa3ba5959f89972805fa4b46e35abef0c57d875c54804de77071f1219195bc8b4f7c18a19a7953573e7f4157ca03be2852461a784e736110157ba3f83a6947aaa09e9bcae730b9b212bb837627293a485ed6b42ca1cf26792676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd +expected_private_key = 4dba785b32456e16a8e9a20fa7536f1b4555a9b403a09738657a148361788d3c358a7baba8b4c58ac979c4f786e588ae245cb0c12c284f848b89585f76892fd65cb906d39b385a04d2f5b2154abd1e77ad9501abac73237780b33c601fac50ba3fc07e8525819593b7d7e69fdea46f14f1128a475e4784af38985501dca6d20bc8dc1c5c7740b33804358f71b6e97b2a0e7350f7608321736083dc54e0253c6e5c5665d0b7e68355d4e98daa753c1abc1429b397da773b043459e5aabd093a5b0210502bc2cab250041997861286924aa0a190307431719588cc2e6fb68711c964fc20393c73b7c967c603120a3cc11b2efca3dd6616d0e2c835fa92946a40c4cc2f4655301ecb09424286b3c7a07ad3c6ea37bf6132aae2d9a335e34b6c816d93cc7ede020ab723b272b70f494834ccd93bd7800bc39919dea4be4c585f827a4351e233026760dc83377329ccbff180a562ac50833c0f861e795c00ee74b584f693222b28eefcb445f19b06154abd0110c6a017ed525b5fa30c64e60663573b8691ba68e2bc580157f1c66ebe388aa2747c50919af644acd903a801a5c04a6a2eac686c89835cf59a791ad5642274a0f78244491670c66c9bce24ba5cf6b86967aefe6728dce8973fd29045db844dc80022297cf530c8eca4808f603a90a840ad70a803e6a0bfb44b38616816073c5d7ba26a64048f81a3bad3a0c9cb0672c7466e38824529298a7c0d82940540c312f429411b403f64e419cf720e1f73026184cee538b27cfb91f16186dcd3904ba6a34254155b3cb3157937d5618568f46f283c7c0e88696324a4fd77c3e6fa5b5dc0a13116274e5792fed69eaba973730a79878103bf63934d179143dc23ed39585d40c06a99aee0f4462f123b8a6b539dea9e05117b08338dd6754398e7496f612b4d892ca54a13ec9b2dc7022cf779668809ad6db97a6e8b15ff0a862e664d292c4af549195a23c19e2b9fcdb9b4a5b9ae517873ccc644993196de5c2716d58d50e7cf11558f44a16580c980654c8ca581671121cb2f8cc6f90529c9754cf0700b30943eea1a7b05f0bc8fdc1cf776b0cf2c2eab927dc83197a4071dabfc07f983bf4d2c613e087976eccaac031b88420ceceb6df0350f04ba61ab39cad4c6b2b32503d773a34514b7d5bbb9d5e7bb6dd9ab5bdb8f34a9880c49ab5c40970c435508e26cba50705c6538686249d344bdb7c820a5c8869b371b8fe13922a5af390bbb7b809c392266541671c75cc2b7a7248d0234fca16da64265e5c70257d770d2e9982d5a1c6d19bf0ba48b53ab900fc8280c754c14774939b83c63592a12f35d198194679942ec227b46cc8f353a0547e929175c3585107239aaafca151df3c835e770921e5c9b134ca7e27a18c7656bfd6a4fd2431ce1743576e575dbba8905f4cc38108e3cdcbf0155b5300a100958aa99940bcb473ef64b05baf55e91952c46851d313b0990ebcf2148cf28130cf49c8d080841fb81384e73367c792a11099f5b898416946826714e252457b23a3a1e33a36ee2612372cb2c04030840a87f96a31913a428cccdd2817b38372da4637f46044f2218c28d525a57d9c0cd2864fd43aa5c9a003a09a35ba786a7520ce0b9190b548bc164bb826874c1800980dab529866b951c01c20cb4ad363c681336b13105fc338b1788afbff321bd981974c33d98a35666eaabe3612e61839d6ad65490d71ae992111719aacf12a060648667e34d09343d93db88abc69e0e098a63749bdad39f8c6b93d75990b0731621cc04e6e2061e93cc4b51209ec92abb303bc638c52ab2ae40d746cfcc43b7576a240540bf410c14744f80a442d0555d474192bcd9b187a56691b63965973c7793668682852f91cfbce70d6d4832a1855cc4b83a847734c24019c508b2d29539fd1a114f787285e197b51bc092f80b559446f1076f02e984a1b27cae7aa1d0b50967939aac74cf2335ad421021e3225d94fa3b09148e60c20e8454c68a8022043206b7bb1e799c9b69286509a188db29a9ebb078420a0844c858cf4b11f9b4959934002be0229e714350451b9c2775a5cc8c45b07e121290eee32a73d46f8d7c55311a8c29027356139f153cb405fa14064c5c31060d7a964b33d76bcd4809d21b34a2f7806486bd2835b7f871164ae496d4264f89fb4eb15b7e5a7232b6c68b11351a41b09bb0c92c8437534d2b4c0ca2538023b29df93d93c98136780ff6f82846cc2868664322ab28dcd7279f68994ba5a5ed406d4d717d16c14dfdda58db1524f7c53f3cb170d45a411b07cd64f001daa0ad1bf63a11550c0c154d20f5096db44d1ab0a1c9d66581891a9314c18f778330a0936e7a2f3e19c18f7bc87cf078627770dfc5a2fe71b27eb8276863c3295c11e08703ef4a4ff6b3a1871c7b42c43a6eeb6bd1526aa95b7dcd6b38edc207c630bed1768ce9505544e9053e5c8cbf6a181a1a0f48c8a98b59c3adebcc3a5c99e61588834024cfc71c9dfab1df558711b311404a739f79b45b1a8a7633081a27a08c3c16478c9d24c1229723addcea225d39bde7851345b18b1b08254181b01623347a9a57f5d902290b10476083949556663309059815626c3ccb5302b978b2ce82af231934ffc7732352b990b21b69210f2acc048387b95c346974c2181148078154416e08564d664db3045dba82c9a7934de51ab5c1d7346a391baca48209c8c7235309943c1cb9cab4771c7eaf59321b510d430c88473ab16f54ae461a5dc613c6fec61a5e899552e835eff57fc34b7992755d178a0365c52b3f020ab40020ce21b45717654634606dfb2917fcc266193e2e5b2c4559cc5652aad1121cca0711e26c23eb33c1f7d389f2d742f384725d3268f8159f8c463585998289e58369fbb883caae21b87139e52d7ebb92b011cbe6426390458247c45f06f2519ab35b35675bf93325351617ad3ac470f73d3d3985e10277a647c96a6c56cc2346563cc496db232fd742aea3adcfbc506ca8cbada7b040a04f6e329fcea77bec0683e1a87c396113639159d9ca52a5a5484d2839869a2e80557a6bf7ce2ee295a464aaf835c542457d021c65c2b2a457c771fcc47f8b1056c8b7aa61d1843a40c4c9b083269b2e89fa3ba5959f89972805fa4b46e35abef0c57d875c54804de77071f1219195bc8b4f7c18a19a7953573e7f4157ca03be2852461a784e736110157ba3f83a6947aaa09e9bcae730b9b212bb837627293a485ed6b42ca1cf26792676c1f4bef1609e71524b877f53fd3133bf71ab13912bf37c2cd7a359eab035cd631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f4f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f + +comment = Official test vector 19, seed: "822cb47be2266e182f34546924d753a5e3369011047e6950b00bc392f8fec19ea87c26d8021d377df86dc76c24c5f827" +entropy = 851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf +expected_public_key = f1390e49f3b488ac39d0e43292b70042c52355eb48b841887ea256055a688fcac5a71c896414ce75f57bba12967215c50d4b5be692b6dcd1ad2190a3d785c19e283f87f784a03c8f52a23e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d062ee1ab3922a2c9b5b02d14557164149c62e8029b139e6950b3f8acc9e8c30274b69926c1658f7836f479c8cc70138b829848c7698b179643b7550e9193d6fa87350503c2b69136b08cc298b5c335b1ab95054d13c9260625e34c6c2fb8186e1916c137ad9907c8b2ac9d88faaaa0375236751a47918f96477b7ec01819f8ae1d72951e21608c87532a9428bdf4cb5658440cb025ce3b271652961bd935624b9eb70047e63184b9503adcd057b6744fe42908cfa325e401b9d0db5ada201f5d64350d392c4fb842823895e15720dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa3917130308f2a2aca964790baf960aa12de3334d146e64db81ef09563c9667381424c809441ee989eec93597e7c5b558a89dfaa976f6934cd18b8eacb6f2f54e8f748e4bdb69b0764fd59352575066dc242dc0f1356fab4467c8064fd23f8823148b77a4acc642eb2c181fd5ca251b323561191cb15f2ff0784900a15f67014b518453c4c3663528ffb53271e195c27533fec8c3b159ac1bf39c6fdc69dd5a5fe5872ffb6b2271a09966a5c738c48e63e141d65315051610f0f5588ac97f14100027b144aa23774f199d0d9a122953aca8782a4136820ffbcc1f2692bb919b674aa1f4d679e8418e8597c74d60c5c287cde6d44492411222636b03cb661ad66fb442193690a5f1d6b80a947442a46bdd239fe3989e6da86949474e395056a5e6cb42b25343a7c73b650d843527444243852518a9034b9efa7a6bb8505bf605ec238ffbc08cbee35a94845d7319144b381819d0928c27023b727656ea843140649c03098fe74c717aabe91948ea7698db0a86d34296b5e50dc0a9949c8ba07f64ce60da2b6e62458da229d52c08b9b696a124a8cbb791c0d255d3e4a69ed2c242000dc6476b4555552deab63ec19fe8783151daaf78e561e1844886d4418e7510bd025299b1c83c7ba22f63335b9823043336da897a44fc6a28b44c68a49b436b0dfa406be642a5bd303bb0d633685364d80440cd7189b6b34f6535101979ba9d251474fc91bf2497670bad0da78ab3c13eeaac864572a2f919546a57c719bcabc9dc8215b492d53118c2d379e879234a700638370a530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d8891b4904b8f5db93d0531caff25be53e28c45c94758e309b83abc2ba66d98d3bdbc53b7d06592f2712663c777db60aff496a217e82d8272c3a218ad8c8b04ae7c66be35c08e3a955fbc18edd07e8e68a806fc3fe218b87f87bc332b86c2625d8ff01c9ff6214b75a20cc465f847511030b47ea664a75b3d4ed9038a9c747c6872de0a57f3b76c60585ade64570a21cf8548a5be4996bc22b3d16a7bbbd20149034764b820892b9394581697e39f9b35077eaaadb06702968a5e5418983110a97d4749d3160ddb2b9c587767fb56b9ed9bb3d91cbeae141769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c +expected_private_key = ed55584416844e1cb3c75acfb3771013d1aaf1fb3ca8a5b718a8ce02a15ae26bacc7534f8b084a665b0608780e532a161686b07faa83884c6a0efb490a8a3fcabb50add21f58ac43ef4355246b1a661c5937562fa6067e7aa66978e4b36ea1431ed41e4e4282d4003d5bbc06cdf7af225b6560c44f43a278677abba8c6b79741b3ce7c0d0769ab407c9b39c032f0e42d1866addf2115e2f3336384c61ce9319cc92ac1350b264cbc4059b94372631c8241ca376aa6f76111537018c01d1346019d628f1f00cdf828b48c47cbf958989b846ed893bb0b6444bc2a35c6443f77d757a0cc957716373460a7a94151cc548f0c78aa5a323581c192d00b4d96219806a04b1a0ac829002b7fcbc8cbf8a8e3abafd3dc2164d03a24c19d50133e967c7668aa8b81977b400067fad2ca802a76716b95e3d28be5603e4977c33d3ba5df2446f6265827464641204ed972286b58567ba129bec0cd6f1644c4032edd6239309aaa259a3d997b1ecc535f17d773ab1c5350e3c82c600175269700a56b0d4211dd02c13d4bc7c54238f40163441702613a1de34ba9b0b42ef0a29300098667e8003588577e64b031139dd2180db113623fc4b74e946eef86a1a6bb52764c6c12911765e37a685400888aa9140a3adfc48712688435258d56337fb8d8a9e1f34bd2e818ae3b7480f500fb6bb03bd50019c33bd37b060bc2c45e8a2267d18927c0af66076619889ff6b1769fe59e5f131f5fe40db2815bb6886b7bca9da659935db493ded9a808157e4151b04c153e673333424b7aa939559e4ca973f7644a813b8d9c1db8c87cac6365c0e008e329403c69490976cd3f006f3138114a6b3e6b3c4f054451e5bbcb7d232f285a2ef5202b81740053512f8e4b33fda87ea61042d1f9736ed58e9047c8744735a728b636dba7abc33b2de0b1572a28b23c25a8668cef9291990a499bc8935f955e1cf0301a65be870b7f01f06099192431f3436aa5aa6564c4689c1d2e11540355138c91ba6e0182b6daba0e7a177ff320c6b04977d47da0d51672eb96ca054ad2d4a0f72930061775592aa40e9c9418ca611893044460495d8a46b242201886cb52e38d91d25d7fa8262290628d91323dd2a51f8c7a33487232f4934133117699028381751d8594fd94910ee4115389c57262ba579220567a7b5b42441a641fd6630d7bc06802878c76bb9ea576965ee45acb90ba549a01b6e873a1d8c741662067a116e64c8897e83204170c9bf2676ef60c20f3450804c7a1b80725da17f9db18f715b7894ccbb53321cf01755d168d19a96356ec07efc62d9a8c3a8ffb15500433f915137ac42a474b8e43f283bdb2b46cd62d509a5aee8cbe23b74cd48079d82293bfc9cd931289a0aa27d8a930beb2000acc2019e3cce107a18e9c4408c516fbe19e45459ed77231851b88b6b73156ec820a4c097072c2fd61c83d23413ad510662894daeb238992138f98185042b53a637aefa83378b026fa7bc314516b25d343f0e0aa7772cd2da27f8b39a8becb44923792a7d586631b2ab963ae537768e45961f5f96cb42320e75738a964168b9403d5b3591ac5679a61857c818b2a486bb299019c7b03beb50d2d40a17e84712aac01f1390e49f3b488ac39d0e43292b70042c52355eb48b841887ea256055a688fcac5a71c896414ce75f57bba12967215c50d4b5be692b6dcd1ad2190a3d785c19e283f87f784a03c8f52a23e150734fdd7bea2ab6d122c928606bfb60570bd696d9676397ac3aa1d062ee1ab3922a2c9b5b02d14557164149c62e8029b139e6950b3f8acc9e8c30274b69926c1658f7836f479c8cc70138b829848c7698b179643b7550e9193d6fa87350503c2b69136b08cc298b5c335b1ab95054d13c9260625e34c6c2fb8186e1916c137ad9907c8b2ac9d88faaaa0375236751a47918f96477b7ec01819f8ae1d72951e21608c87532a9428bdf4cb5658440cb025ce3b271652961bd935624b9eb70047e63184b9503adcd057b6744fe42908cfa325e401b9d0db5ada201f5d64350d392c4fb842823895e15720dd7785c7f5986f15cc2565a71f6ca11b854a293c9ce6c9a1f4aa3917130308f2a2aca964790baf960aa12de3334d146e64db81ef09563c9667381424c809441ee989eec93597e7c5b558a89dfaa976f6934cd18b8eacb6f2f54e8f748e4bdb69b0764fd59352575066dc242dc0f1356fab4467c8064fd23f8823148b77a4acc642eb2c181fd5ca251b323561191cb15f2ff0784900a15f67014b518453c4c3663528ffb53271e195c27533fec8c3b159ac1bf39c6fdc69dd5a5fe5872ffb6b2271a09966a5c738c48e63e141d65315051610f0f5588ac97f14100027b144aa23774f199d0d9a122953aca8782a4136820ffbcc1f2692bb919b674aa1f4d679e8418e8597c74d60c5c287cde6d44492411222636b03cb661ad66fb442193690a5f1d6b80a947442a46bdd239fe3989e6da86949474e395056a5e6cb42b25343a7c73b650d843527444243852518a9034b9efa7a6bb8505bf605ec238ffbc08cbee35a94845d7319144b381819d0928c27023b727656ea843140649c03098fe74c717aabe91948ea7698db0a86d34296b5e50dc0a9949c8ba07f64ce60da2b6e62458da229d52c08b9b696a124a8cbb791c0d255d3e4a69ed2c242000dc6476b4555552deab63ec19fe8783151daaf78e561e1844886d4418e7510bd025299b1c83c7ba22f63335b9823043336da897a44fc6a28b44c68a49b436b0dfa406be642a5bd303bb0d633685364d80440cd7189b6b34f6535101979ba9d251474fc91bf2497670bad0da78ab3c13eeaac864572a2f919546a57c719bcabc9dc8215b492d53118c2d379e879234a700638370a530577700982c4334673aa5d71db98627384e8ca876e24b5a31575ea3c334d3c7d3abb6d8891b4904b8f5db93d0531caff25be53e28c45c94758e309b83abc2ba66d98d3bdbc53b7d06592f2712663c777db60aff496a217e82d8272c3a218ad8c8b04ae7c66be35c08e3a955fbc18edd07e8e68a806fc3fe218b87f87bc332b86c2625d8ff01c9ff6214b75a20cc465f847511030b47ea664a75b3d4ed9038a9c747c6872de0a57f3b76c60585ade64570a21cf8548a5be4996bc22b3d16a7bbbd20149034764b820892b9394581697e39f9b35077eaaadb06702968a5e5418983110a97d4749d3160ddb2b9c587767fb56b9ed9bb3d91cbeae141769c2128e0acadbafd72fca96aed457caafaf51dc8c30ceac70cb4621cd4d7b4c87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf + +comment = Official test vector 20, seed: "81401db81138d6874e91b7c11d59596e4ace543f5a3471b6fb00999221765fec3ca057abe20f03b2d59003375fd71fe8" +entropy = d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 +expected_public_key = 2d7b0180596be297a4631abe0d48a046dcc99c8912b8255fc45592a2a61230652bc7c450a674ccc3abb27395738d177e7579afdcc30e74e7c7b5ac5dc235176343cfc4920ed8d9472e13c9b36a6d38bb44756bc31fbab62893656da065901303700a14b2f785d98896ae97953ba358fd53091012b97498cd7516b0e1898e2f6803c5a13d70f5bec346917249940ba35e3ea954f6ca13c343a09cfc02d8e66852c1ae0ff8b22e7424f53b1897ea11268a6b866c09efe8694031754ed1a2a147c0086283284133aa6c324e0b0570469f09e0901f25213ff9b113147990b54cb241268e0b6c7a3a90c638b7c483c71ac1344bd65c988736c4756e0b71111bf5b810fb3cc4187363a94efa020de1c3cb9a005cf472bec5685322faad5bd1cb0f240458b56fcc5a6167f22577565dac1ba9b984c33c348babb70506b87926540547389b805ba01e4443b5d60b9a407f8b060fcd96c4b717baaeb72400eaaa9853b962e8a0c8d966458cc4cff31e960c447c6b205629419478360cdc945d6b9a55504d853c1e51364e7a9aad82b64fc37a02e4139b9e6c392dc83c04005f6d1299d990a89ed68acc31b5d1d224f2c8b3cd5280a12c6e088cc2f9d3c59afcb9fee458af5135c9b4b477d878f34723e3912189d2764f9366ab8752c9248a5684296ed46f404a1739ba72d5d652c614860d41898e45b72bf66d587089fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed880048885355f193ddb1690b9092aa2a86af03a41797120be84334ef25c2e70bfe8e0a658f03435b65787f38bc9452ddc584162955f8b8560991c407fa0c12d770e80fa4a2cf7b853708bef2a44f959b9d05b6faef83f6f41a2454257b0157c55047ae7d0cc17079e118c8a4ee3358d877251970eaf86684ec70858a94bbaa4bd2fd1895c2223320ccadce636c2156471b76c48d53e6a6c12a1317c39c48bf3a0aa0dbc8afc034b43398b9f1c56d407a4b7c2bac134024df6ae9800b230e2592f529f79f0ab048867a349684b242bc4d2284a6106dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b22027d6657f12379abbd248c6967834239e2d3a0211b73a77d681b61892877b7e102a53cb4602e3dc1704ec92a9e260d9817c6393062bf520f7a845fff19123a1662fd241090ac81ee1748eea878d53969fea20fb95688fcb3d235910f154bd09a75556d890409cce0a20c6cd2a59664bc4ecca3d4725910d210db0c848ce7242cca945f1568561bb90d9a4c3dfba83074a16fb3ac934c865dcebaf6fd90d5b458c22542ded5111e77c12d8656908557649e9155a8472d5213b46f739f095b5fd4a2418074ef7db9385f19d6630aa29b28881aa3474b7ac352c5dfbfb20fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b9190064f3a862d10cb5707215f456caa10a2c240619925a140b6cba878a0d40283efb9e1562c227d716d2935e8d96649c06ae9465aebf552d68da1e7991bf987a4dff4371049a0dc9e56f110779d562959f278b069b3c7712af29027aad6109bb0c3201565c0b0892a62aa74ca7bd6b48039066a95dbca4e76a3a323612269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff +expected_private_key = ffd8874d8b37c946409d69cb03529b7d1a43ddb24792d4773cc723643567671b8e0fc2b903d302679a530118ac453b0541a2389c46b38f317b43130972271d8146a66593b8fe659db570c941f1abb4f295493085a85277062c3d4db168e466015ea506b5b8a805a435ef6812a6b68afa9372776717c1042e24e7a10a842182e7c40c4cc547b98fe007a1d98804ac5bc3c31b6511425a558c73e5b1935c7a664ee224955b6d67ca54d47b04e1622716a27b21f12a2eb27c16d26a541cb0c1ba5a1a8629b7f2222b84cdfed9cb6f666b41c92fd0b074f42b5d2ee72e8c5443f34c5dc2920da165558af074e3ccae84c1cbf1f70624e1a3a30a7db045a2c4a79bb1a4b0f01187bbd8b29a8c60b07068a72264d9b305b5e391521bb945d53ce1d65436441932ec5867549408b47f28d3bf37d7af0df432ccfc3667f4ace969542cd626637b570fd84210b3ab5456b23b8b339f4885e9a96bb17ccf1ca4a962c5667d0c3dfb356146c04bb8391197d54d0f4202f160824d900b27b36bf8abc7876ca331c2c3a8a161d98523adfc1ef9d538c9203a6729cfcf6089f7d72f57093ea3a34113749f23ec21c051ab2c836679b0210a549f2678c7187691de949994a25769d4647fd992be411e24e302c07569cf26c11f3942ca505391a794d42c77da0a324b05908aeb9c70b88b38a95f371b1902e06d071457bbcb382ae4c36f14ab3a747a30cb7e9d35791879873a0333b3fab967770465a056de9c4420662c046aa8ca32093ae23abd80406fe60bdcd1725daab0e50931c575a0c9137fa61442b1101b05686d398a6fdc0bbbbb25a073e99c3702b9268ca91420a1198b5c54501a03c878b6827e6d586ab42c2fa47258d1255711654968fc80e1364886f18e98fc10eb85645b399788dc225b1a233fe564604a86397a4483c102203188df667961bac9ef19b99432475c0a2c9978c81cf5314a2b2ab37479549b14c8d70ed8f0c6625938ca4a92bee5a7aadb286e507ee8890772c3353e35c2de8696041bcc8b81997f8c7800417c91c32e9b8b34b62a25e5c2af2854cf902269c3c5b50a5209dc1c63f8835b3a73137d855c69f9335fc66efb985933f4a66b084aa58909e658998a15ae8b087120f59a00426cf9a327dd48467f8c12cfbaacea7bca7407060c42950cf9543cac1edf9c296d978a2c36aad92b665d6c9513b59278ac1cc781204e555e27f81e976a74d3055a48035203472960e596c7c4c2d0158a006d884f40681c6610f1124574eb9ff5323e10480d0e306f1e398ad1e6cf8057024d072def4719e3a6be9aeaa07b56077be495a635c67066a2945376c9836ebf4c413a05a9b1348c31329884bc7d820a6bad7a63bd62518878a97fb525332433573973df74a00ec02d50198a2b1306005335e6a51191505fb244999cc333bcfa4e7845b766b050cf66607982014d28548a4454f86a06e9321c82781478cb938c709ec5cc81ea1a9269543dc8ebc6d253be1698990c81c587d7263e7445baf53316c23eb8863d151a4e5659928ad704c1c7b2bd2a1987907a05ccbd2f0c78232a10653452e3dabb7598ca83d37166791ef11a2524f371180984bf72a6e2291301606b7351a284a1a62d7b0180596be297a4631abe0d48a046dcc99c8912b8255fc45592a2a61230652bc7c450a674ccc3abb27395738d177e7579afdcc30e74e7c7b5ac5dc235176343cfc4920ed8d9472e13c9b36a6d38bb44756bc31fbab62893656da065901303700a14b2f785d98896ae97953ba358fd53091012b97498cd7516b0e1898e2f6803c5a13d70f5bec346917249940ba35e3ea954f6ca13c343a09cfc02d8e66852c1ae0ff8b22e7424f53b1897ea11268a6b866c09efe8694031754ed1a2a147c0086283284133aa6c324e0b0570469f09e0901f25213ff9b113147990b54cb241268e0b6c7a3a90c638b7c483c71ac1344bd65c988736c4756e0b71111bf5b810fb3cc4187363a94efa020de1c3cb9a005cf472bec5685322faad5bd1cb0f240458b56fcc5a6167f22577565dac1ba9b984c33c348babb70506b87926540547389b805ba01e4443b5d60b9a407f8b060fcd96c4b717baaeb72400eaaa9853b962e8a0c8d966458cc4cff31e960c447c6b205629419478360cdc945d6b9a55504d853c1e51364e7a9aad82b64fc37a02e4139b9e6c392dc83c04005f6d1299d990a89ed68acc31b5d1d224f2c8b3cd5280a12c6e088cc2f9d3c59afcb9fee458af5135c9b4b477d878f34723e3912189d2764f9366ab8752c9248a5684296ed46f404a1739ba72d5d652c614860d41898e45b72bf66d587089fcf49e3b94cd26999d7539c32bdbac0139b20988cc7b578ed880048885355f193ddb1690b9092aa2a86af03a41797120be84334ef25c2e70bfe8e0a658f03435b65787f38bc9452ddc584162955f8b8560991c407fa0c12d770e80fa4a2cf7b853708bef2a44f959b9d05b6faef83f6f41a2454257b0157c55047ae7d0cc17079e118c8a4ee3358d877251970eaf86684ec70858a94bbaa4bd2fd1895c2223320ccadce636c2156471b76c48d53e6a6c12a1317c39c48bf3a0aa0dbc8afc034b43398b9f1c56d407a4b7c2bac134024df6ae9800b230e2592f529f79f0ab048867a349684b242bc4d2284a6106dba36de7b3a114b6353b479d014a69e33acf5c465ced6669b22027d6657f12379abbd248c6967834239e2d3a0211b73a77d681b61892877b7e102a53cb4602e3dc1704ec92a9e260d9817c6393062bf520f7a845fff19123a1662fd241090ac81ee1748eea878d53969fea20fb95688fcb3d235910f154bd09a75556d890409cce0a20c6cd2a59664bc4ecca3d4725910d210db0c848ce7242cca945f1568561bb90d9a4c3dfba83074a16fb3ac934c865dcebaf6fd90d5b458c22542ded5111e77c12d8656908557649e9155a8472d5213b46f739f095b5fd4a2418074ef7db9385f19d6630aa29b28881aa3474b7ac352c5dfbfb20fd7b8a0b87cf3933547cd498256a9e17733ad6967d7b9c7adc64a951ec5c8ecb75b9190064f3a862d10cb5707215f456caa10a2c240619925a140b6cba878a0d40283efb9e1562c227d716d2935e8d96649c06ae9465aebf552d68da1e7991bf987a4dff4371049a0dc9e56f110779d562959f278b069b3c7712af29027aad6109bb0c3201565c0b0892a62aa74ca7bd6b48039066a95dbca4e76a3a323612269546b18ba1bda19c123c24504ecdf72189dfa1cd24ebf011a3bb66d35f78633e1ee7b249ff699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f6196590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73 + +comment = Official test vector 21, seed: "30b5de5b73681ec08aaa03f6f2d2169525d25f4042a5e3695a20a52ca54927b85f8bb948fc21df7defc3910b28674994" +entropy = 89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 +expected_public_key = f3576ff861541032094855b18cf574d868b0eb783ce9011f28fc14c486b122cc80093897bfc8ac1082421f99767bc42b0ff41b22dc7b50d5556041338e6c4368ab190e92608f6cc69d8b33f1ab04de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f150658715403d1e1c957e5a914b9a3bc4c45489053306329c7984e76f169c8639de4080db1671ed01a24724a101df89e45b5b385ca2ef663586ae58d9b33ade9738f84482e6e28909e7641aa673ad772b125161a316166e1717fdbdc8d02b2b2b6dc21805619d4facc40e9a21bcca9d4da71220a4631e95b25e960192a22a39b904bbb02f1184b79a97b3cc16b5e4b5eaf278913b7a195f3107342a77a68cac90c1b5a3ca9b354a6095c29c09c5ac2b44c6cb28a250834d5f2a307ea3434977d0087017ca2692b79008640b770b41ee2c2c77bcc2605f1857368c8e12983afa8633c870115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68c2198b2fb558f463a7477b9fa7680f1e65706a888b8740a87cc7e7949156f896c182b53e464721e46a258820201887ce9b83d43250b63e2ab29900a115084a6e66584f767853b2e684c547d97266b36b6838aaba73298dab79c58c88f1b51113ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd78106ec0c5e9967a6d81139cd516027c25afbb6c47e3802d56079e6265c4f21f1315a96ab994597214b814cc53e8566330cd51fb4045f605df1c7c9c255166651de6041b7fd85c7e376e28076ad352051c65494a1054c30930621c53ee8947dce3c55bd686f186cd5aa21afc17664d36a2d7f5008ae83950b93ae510847552a5c2f761207b0f478c73c4d6313c8acc25b13ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940b70b68f40bf570c461f11795952e69f21ec4562dec99448263188ef44e71a1681d626cac69c6b56ab51ae656be1ca028672d97d044e43577f26329d50851b0f8a4a1b6c2b673ac6418ccd58005ad400c27d274dd4732e56b5d7c0b6ee731a99e15229f7295c153aa3a873c20c23a35b6137c824f6fb021a0e28f98bb3be8dc07a5b038dc89944952913af7a39a9b00f1a038a628686a735dbd4c45e0b8bcdc1c1a902cc4d0571cbd589f507a0c0dcb81bd39811e723358d6320a3049bcc90d776562eb34877978c9929548286a85efb85f7c6c76ff255f13a0cf5e70304f1cc838fa398fb34e26ca662759c8f3657125dc2aacdc4615653ef074a784500ec60980be4aac94b0c7a9012dbe73cdbf1687a684ac63526778926654a4ae4cc779a600a836e3273acb95a802051f18af32683f52363572583fdfe30287b2632874cb04832f55e0944712c86d37420137c56f6251a1352ae37a0c3fdb885cb561e63a493a15beb5e3b123aca6b6b7294d8002e7ec758ad2c22d336aae3c067703821842cba2dc0b1b7a45cc0a48202a002f927122c040f84a884c1334c1e17347108b91c055d331c0b170c6f06048b40ca0bed838ad963fb8747ca714cf1d3267b701132046699798421acc06a3bc1ade172fc62123235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffb +expected_private_key = d32cbc1116ac88219f9af2c33beb59bb94b372f97815278f0fab2c690c94b8f209dd1575bd7c0bc7f48aa133bfa068cf1af1612c3325b8d08963bbc66d938f46843fee424357e535c2259ed958a75ca6203286190be53a9b46373f8b41cb38c1cae2bcb91898669a872f1a8d9cd21227e42ed655569202cc6b494cc6a6bdb08731cde417f48b86554ccaf953b8fb70aec727085510cdbaa7cd2a0ba853928886332fb1e3a419c49b34ec90fd31b716252acce7a79d05cc04074d69ab3cc9809102261a2191a086231dc70aa583e86912e5beb2c1a22e841f39db531d5c26cc333834a20480d6b1ccf19a654149045791d33b414696375dc3c7b0644626e8822c5325d52ba764f2361d853d244416cb9a5bc0540e1238ccb53438c90a196a45571f743894f060f6031fd623abebb4afea05190dd9452c981352a78e09579f05e24db2033aacfb10d9335986e8542d9480bf5603fa932d2d0878c3753e6524a809324ad6f169d7fb6d9c0264423a632996abf297707d8412a6b86160b69980e18add1c372faa406f540c00ed0a75c3544811759c3b5026e6c19102b7160883ed002de5807b5933934fa01559c4a790230ee93c215bd75aff117d0f170b4feb7aef5b007aca616e688161fc00cb037c8232cf2dca569f01a2e1dc2af7ecb6111181f2ebcb1df27c6ea84251d8a2b6b6582ef915e2b8c7f8fb6be8844478fc570b8054a067b34120b47fc6ac68125cca8514db4540b7796c9fd05523e7014db34b8ec94d5eb66c9f5cae2f838191d2234f43c72262a18deba17ab495b7f0529d89b8e1e407bd5a185eaa2444d20c6c9566526b8707b13bb0cc8d9589773db90952a5cd78e43bdc68cfa4401d7912618f456eb4f97ac1b49ab948592976233f962b1916531fd1672bb69be320a2985b38b80279572488c5f86bf3d55fb9fb90449b66fc874b94292000466786fb7e393765c7057051999711d234b4d277419320e0046ec0925b41d6b89c62133bd2734e296dcfe90bf6344219a6a22d2cb50c75bc02b07fd0da11fe0a0a0b9aad76001d5d7c8fede065dde87d5d47821e756a926638395883879a91b94c6164a40895476269917caeb12944dc956174b6cc5154944571a6f6553f604d3212728fb08af6e8c0ea00265ac0c5464595b31a9131871d79298867aab426d009480c0befc08ace14991399079cb62de9e6bc80c88c3339640fc667ec837b691c3da4556a952b3e63c162ec911101c5a49b35475ae68634a7b0cefccfbee608cd4c43c8eba7a8f957db595645c64ecf08b50c7438bfbb415c27a45ae940ad077e5a533825d998a9095a735b5d23887b0048af49ca85f18395c7d3cd06bb687c92cda9ac9c03a9333a866a9639803c76b5b189294a269f389abb5010789d410b88215c554008cb10274f781ed6b0be3903576cd16934c4b6b65296c477aa174043f06792f3944efd0206e34042d827caffd2989b936b91694825c4bd8b10c0777b11971cc1efb93ec1b3674afb4fd07568ffe89c707b5785c140d51b433b7942d88a6ef9bc9d091472833004005aa803a050ce03b2bb551f62fb1fac6649d3e14f0141b2eaca73b700489b73a8d840834a7802a96864610b10f3576ff861541032094855b18cf574d868b0eb783ce9011f28fc14c486b122cc80093897bfc8ac1082421f99767bc42b0ff41b22dc7b50d5556041338e6c4368ab190e92608f6cc69d8b33f1ab04de68cf96d9c5882c97cf28c30b86924aa57849954369c5427c876a9b1ca341e8522e1357e60a4450b69f150658715403d1e1c957e5a914b9a3bc4c45489053306329c7984e76f169c8639de4080db1671ed01a24724a101df89e45b5b385ca2ef663586ae58d9b33ade9738f84482e6e28909e7641aa673ad772b125161a316166e1717fdbdc8d02b2b2b6dc21805619d4facc40e9a21bcca9d4da71220a4631e95b25e960192a22a39b904bbb02f1184b79a97b3cc16b5e4b5eaf278913b7a195f3107342a77a68cac90c1b5a3ca9b354a6095c29c09c5ac2b44c6cb28a250834d5f2a307ea3434977d0087017ca2692b79008640b770b41ee2c2c77bcc2605f1857368c8e12983afa8633c870115a3818d6bcbcee864a8db694f4b77bcf63a8aec407a45716af6358065c30b77b68c2198b2fb558f463a7477b9fa7680f1e65706a888b8740a87cc7e7949156f896c182b53e464721e46a258820201887ce9b83d43250b63e2ab29900a115084a6e66584f767853b2e684c547d97266b36b6838aaba73298dab79c58c88f1b51113ee752736b7566eb5759cc4dbc37551135bb3c87b1a6c83ac5a38dbd78106ec0c5e9967a6d81139cd516027c25afbb6c47e3802d56079e6265c4f21f1315a96ab994597214b814cc53e8566330cd51fb4045f605df1c7c9c255166651de6041b7fd85c7e376e28076ad352051c65494a1054c30930621c53ee8947dce3c55bd686f186cd5aa21afc17664d36a2d7f5008ae83950b93ae510847552a5c2f761207b0f478c73c4d6313c8acc25b13ea64a72ee3334013cbc0a855b55e88ea17466534786b6176b9053ca9d0494c6b4a940b70b68f40bf570c461f11795952e69f21ec4562dec99448263188ef44e71a1681d626cac69c6b56ab51ae656be1ca028672d97d044e43577f26329d50851b0f8a4a1b6c2b673ac6418ccd58005ad400c27d274dd4732e56b5d7c0b6ee731a99e15229f7295c153aa3a873c20c23a35b6137c824f6fb021a0e28f98bb3be8dc07a5b038dc89944952913af7a39a9b00f1a038a628686a735dbd4c45e0b8bcdc1c1a902cc4d0571cbd589f507a0c0dcb81bd39811e723358d6320a3049bcc90d776562eb34877978c9929548286a85efb85f7c6c76ff255f13a0cf5e70304f1cc838fa398fb34e26ca662759c8f3657125dc2aacdc4615653ef074a784500ec60980be4aac94b0c7a9012dbe73cdbf1687a684ac63526778926654a4ae4cc779a600a836e3273acb95a802051f18af32683f52363572583fdfe30287b2632874cb04832f55e0944712c86d37420137c56f6251a1352ae37a0c3fdb885cb561e63a493a15beb5e3b123aca6b6b7294d8002e7ec758ad2c22d336aae3c067703821842cba2dc0b1b7a45cc0a48202a002f927122c040f84a884c1334c1e17347108b91c055d331c0b170c6f06048b40ca0bed838ad963fb8747ca714cf1d3267b701132046699798421acc06a3bc1ade172fc62123235c2d8dbfe40dd56ce5de6756cc4b6afdf64050da2eecd9953e893c53bf7ffbd3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465 + +comment = Official test vector 22, seed: "e335df8fc0d890588c3e305ac92c7160ff199e07c85760a828933750e3fed8c83b0dbe802234481ecf890a32d7a2884f" +entropy = d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb +expected_public_key = 4c376ba98c3a0415a3bfb0ab42d0a3d68cb171109c5f83147c33adda2cb07c62a9025b44523b0ae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da2a02d35610787f22966298ffbb45fd78a8d36eab454675d6951a70472caf06640bc1b97d6760e74b41c577855bc0756abe528eb4894e8776f1e739da45a9f84c9bf3c72b43262525b547f75176ab2e12d8ea808d3b0355766bd69d964eb3b450a96c835d7b238220febd62443b03985731333c54382d20200e30e4cbb2b607ac998f20def865bdf47ce78ac3dbc1abe33245d6fa7583b31b6fe7b6ede7a8ec776b20f7bbe7e376578f0933b761bb0952161123d61282cd6c80cdc8a85f9632aba1a8ef5925e410bb80beabc67735d07e4abdd587827745a3220a24a7b3902416befab3073c2cb1fa76ff04315b653b3e7c18343391f92015939829dabd0289b5aabc4cb5335d963ab842865bb7c38106eb1274eccd0140b415901279e8719c0415517b5101394f78a48f565317909371a3154d291698b0bede17052f30786dc2d46e71edc438c288cbd44445f993926bff0a8ca1a033b656c2362a659eabbcf37b2cb5916940aa9b3e850e51039c08c8588347e1099a0d8380ccc4b8cd0c87218bc24f09126a82a3d530a75500254510ac765cc1de612a4ceb14db78a7141109f947b4329158f87e4c8b41a92afccc9eb749d66a71159db90e7a36642636af22cc0d541ce52db7ab44baf30560691a637c93193a11a00efec075289953fdc9df3ec3390342aee44c08d661632fb0303681e1f89ce1300b0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66205c28766ba5eef7062363c19091c61c543d5c1b8a547372515722ee515e8ef52bf8e089d93377e2c8458e626d3391953d658cdb05c7a40077f4e19dc0b132be719014c12b0cc242466112e94809630b63fad12c99d271dbd38e5afa54c894542b940415354203a0c8a785ab94200ee0cb976991c642257d9af6998b61ba27b236fdfab86f834fb2d47cc0904b9d6acd2f8311f0d4b8ad81a24f712d92272587220e8023a8bc13bd17572d38851778f319607752466cb0de7c5c12103fae4c57d953b96be93262ba9cb05405a5d2a9e012b21a22a2ef33a385c898c80aa9663565b63241a1b206f3379abe8262cfa49ba05c3b43e9485e60cd38d66eaed114ef81afd66b2594baa361d3c3b02069b1a164bc387632e24c82a91be2ca390eb585e900173699a8b26b8916e52bd643645d3225df38ba50a50ea013b4b2a86ee1f76278e27f5a4142f034004b567f309c52acca3c7530162ed744a67481ca338861ccc3e8331e1c67886023743719493cc3caea51438e28ac4ea06b906789a65220e3c7407c874c6322be1f9b627386081753ad618a8dcc013395f20f5017ae2b57ba908617490460d5a67fae2660a56c4c4d97babda0bae0f494260877f7077af2536b2ca46e297c61dd8422bbe515519210dabc02e7047b13f16607ac15e4950574c43bf8c39a2528addfa2782506635e5626967a1f30c02fa3442fa93250571a8173999a88dc27b43c476468a6a4739972dc1b68493413a2743b9b563283cc886916eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648 +expected_private_key = 818b55fa5ac30a81891f3a3643924b2b046feb6765a61cc81c9059d1f82f6a0067a102825c88a530d15f0dd95f0b4742d29abe7044c62d45a05bdac46130305e3c3417d67f60b92edeb6b2a398119ad160ee3cb0fb52144435a5bb5412c0512dc6121bf6e72d0f87a3834ab5338196fdc950a3cb1b7354c4e50369bd4364cee9066a221dfcd580f1b914c0c335f547748bb19264b7879f206a9c610573b8676bd0bdfd777a2a0ca5ec891a1317c5289784de114e84c53b983778bf8933805256c9a9bd05a11af8f5ac271ac3f1e635eb9a8263c855bb230f58ea3b7e8287d76258aa57646b97560e593944c4cb3567a2c382a795c991f69bc2df2cba8837c9a3b58a9dac5e4d84b50722a144737ea38b14be51c41cc55c53340ed158ab4a0b0f0a2612962b89cc2aa8b29198f2e04b0f0cb586f271c6414f31a71a45eccda8c597c38415d262571bf0a7bfa17115e0c7731c70c2d01c492c85de16c511102c5a96973c724f3b58b504eb65f56116aa7779b76b2554736d9d6176dfc6ba007a590a311d4b86a7a6251fffe6086ab3319db48c4dcb91fe680f45a9480241242e4ac9861b62860837cc813fadf00751c8021f7a1c4d7a1e5f13bc3e8462f372cd7498197d172eff98b1f8bbc37974b025295a80e3525d282fba8467f8079d78fa6068e23bdbb3349a31506e474ea228c3927a554d7747bd3621a0343cb155bc786075c3015c3692c0fc65b194a12152a14153a03d5147b0cdb423a3b50ed6461813f9ae1fd63ab7a53031dac2d0f87cacd1cb81461c8c08bf367c4ccae7626343469d417acc705546293498035195240387fb1f2e7c005de000e530b9e21cc7dbe463e7d24adeac1127026843b87cf6fc1bb94674399b0636506b1acab72f623adef866f883762b5b4509cbb2be142c5c550046e10d29fa431f9b7d977253928a8d2d4c33add899ad736b40cb4fc656be02d90bf8d393d632a1ab509c432511f1ca16b01139cb0627f6503bba75440414af97a04bc5239567c060ef94c9ba7221d4612eaa640bdbb8b72e32a4668401aa79421ba68115261a8d94878c90a0468510b247968b7463ff49a0578044c5e9147f0739f6a17b18828bdcf56966b1caa125cde7ba6dce939e56d350e896ca6219a6b8947e3909361754593fb8a85e742cacb74e1d45704fa4cfc91c142453ba5c08558de1321ad6a6a2804769a0bf69770a1264ba5148b40a3a9be3c513a382cfa3c244c9a138ea9cb8da7627b350cff87ab064a079876893d893250ef59f369c41f9ea40daa5a5984c19ce06cf9bec2947932133a4157bb8cc3c72a1fd25715962a9c88026c018b7202885224019466540c9eb5482a87e665157be7722bc64133c827c20b97d9e692342f23fdb1b75ab2ccb6fa5973820b92ef1bb45c2b5ed1330c1417ccfb39fc6301b8a749d3613b3803a6abba20990151305cb32ba6a5b558265c2e27d8d49aef3e91819920db20360355919d5f641922233a1c24c0045172cb10f9564a029f07578a48a4d215248f3ac7a912ef8e56e366b03c567ab978c750d85454c68a5806ac38b7b3395f19fe78a001c5867d3e90e9b54bd63954761ab7f4a57b1fa32b65f285742c1207aa0684c376ba98c3a0415a3bfb0ab42d0a3d68cb171109c5f83147c33adda2cb07c62a9025b44523b0ae4cb8a8bea5e550b717ca6c8271997cfd6c5ed76aa44e43da2a02d35610787f22966298ffbb45fd78a8d36eab454675d6951a70472caf06640bc1b97d6760e74b41c577855bc0756abe528eb4894e8776f1e739da45a9f84c9bf3c72b43262525b547f75176ab2e12d8ea808d3b0355766bd69d964eb3b450a96c835d7b238220febd62443b03985731333c54382d20200e30e4cbb2b607ac998f20def865bdf47ce78ac3dbc1abe33245d6fa7583b31b6fe7b6ede7a8ec776b20f7bbe7e376578f0933b761bb0952161123d61282cd6c80cdc8a85f9632aba1a8ef5925e410bb80beabc67735d07e4abdd587827745a3220a24a7b3902416befab3073c2cb1fa76ff04315b653b3e7c18343391f92015939829dabd0289b5aabc4cb5335d963ab842865bb7c38106eb1274eccd0140b415901279e8719c0415517b5101394f78a48f565317909371a3154d291698b0bede17052f30786dc2d46e71edc438c288cbd44445f993926bff0a8ca1a033b656c2362a659eabbcf37b2cb5916940aa9b3e850e51039c08c8588347e1099a0d8380ccc4b8cd0c87218bc24f09126a82a3d530a75500254510ac765cc1de612a4ceb14db78a7141109f947b4329158f87e4c8b41a92afccc9eb749d66a71159db90e7a36642636af22cc0d541ce52db7ab44baf30560691a637c93193a11a00efec075289953fdc9df3ec3390342aee44c08d661632fb0303681e1f89ce1300b0c1a36e63e5a45886a4c76534fa78b87a75cf96ac66205c28766ba5eef7062363c19091c61c543d5c1b8a547372515722ee515e8ef52bf8e089d93377e2c8458e626d3391953d658cdb05c7a40077f4e19dc0b132be719014c12b0cc242466112e94809630b63fad12c99d271dbd38e5afa54c894542b940415354203a0c8a785ab94200ee0cb976991c642257d9af6998b61ba27b236fdfab86f834fb2d47cc0904b9d6acd2f8311f0d4b8ad81a24f712d92272587220e8023a8bc13bd17572d38851778f319607752466cb0de7c5c12103fae4c57d953b96be93262ba9cb05405a5d2a9e012b21a22a2ef33a385c898c80aa9663565b63241a1b206f3379abe8262cfa49ba05c3b43e9485e60cd38d66eaed114ef81afd66b2594baa361d3c3b02069b1a164bc387632e24c82a91be2ca390eb585e900173699a8b26b8916e52bd643645d3225df38ba50a50ea013b4b2a86ee1f76278e27f5a4142f034004b567f309c52acca3c7530162ed744a67481ca338861ccc3e8331e1c67886023743719493cc3caea51438e28ac4ea06b906789a65220e3c7407c874c6322be1f9b627386081753ad618a8dcc013395f20f5017ae2b57ba908617490460d5a67fae2660a56c4c4d97babda0bae0f494260877f7077af2536b2ca46e297c61dd8422bbe515519210dabc02e7047b13f16607ac15e4950574c43bf8c39a2528addfa2782506635e5626967a1f30c02fa3442fa93250571a8173999a88dc27b43c476468a6a4739972dc1b68493413a2743b9b563283cc886916eca5887796a4f833aaed6639b9d531efe5cadf9225573a23664c9cea086428dcd19ff40a06186a41fec0723953781475f648e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb + +comment = Official test vector 23, seed: "fbea1bc2c379f4f8fdcb0de260d31cdb064c9ea9b1d6dfbe91b3692add1d34dec9c9ffae7bf5e72ed2743ba3f9f2e43d" +entropy = 5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 +expected_public_key = c8735813347c3c7c05f81a176264a5ff791d9801af88047574008c870635457126b4069071242c24dc0977a8c13d43b889d27f08984d9ea657d241922bb12aa28a1408825b02663b970778bf669d585a975abba6bcf8513c11bc73a0c33897991c3428a5cb4dfed155b9a2909e6597dd8cac1ad62f9cfbcb27088860512859761885c5b6c5d89fd6b18f9e324ee8f80b4c507626762a22f4cb7f4527527896aaa97a69b8aa4fb09b16cbafd73a667e9cb085f7ca36067d4f740694e6c83c671071762fbba26a640c86422197894caf01b0af66960651998073ba7fccd3189148187ba22dd2661262766399a6b8bb943aedc590fa048816d1b9d827ca80935d30e1830c8115b18b754f20acd7a376272c119cc8210c9aa112d604b2022326f51ad674aa1579c081f12df04a9a2b4571fc1c21a8a4ae2c701eb2ebb0ce65cd2fc22fee530fb3daa6d82b3d46e33e9c918f6d33abaec34f45391245453ef4d128c4c068227a6511800d69f6a31a1421e2d322f897145961abea377c9393acbfa72ab3c3aaf7f04ddad50077e7c36ac46e083075265c58db4b7b47da253b8a9361c08a1248b53098c6b797622e228939f110ece18c02ac613e00b624c61eff4524f92c1ea632553d9b90cd886fd2c364b25c877459ba6de0ac8cc2a8b0f2c6d71a051f8727c2892d1934857eb995a8d728b9739872ea472e6602f2c39484d290109ba924933d6ae52c30eb4d80935f0d2c87d4dabf07582cae3c2f21692f0825c079ea6700065a6086b197582b76cac90a58451d7479965475ac8a6af662c7d23055c404246264c97bd23d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1e4050f97ca3e9ab31e561ab18cb3af721570380023a9349ed6bbc5df66bb243928dd3a4b5e113a0f99725c9c8bf673818b89030db28edc536c9620a1625c8a647bd3d7055039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651a0234d2325ed82369bcd415089692547b325ef28189482714c80dcdc5bff72a6152b70ac2f16707c63a42830dd6cb88ee646d882338d3dcb202408fc5210c71d1a8ba02b8c2ab7e06e43ccd85ce39a215e67914369c749c3978778592d9e34b7671283dc787446b5b70a32c4c1ca4613b01a5d0bfe55016b897130d1bcfb49bb5f08c5df9f15b6d531b06c53a389500675aafca9700fbc310fff968300360ab631ad95649f0bb47e55b90b2593d9a60bb0477ba848c0db9f8bf6c774cf8348c65695b31b921e4439e976b4306a47069c25e4a7515866c0bd77b44c7881121025cd2f28430383600e4ba0bd28074b7bbf2a2a3bd62a73ba240d644ab1f89ace0c8a83ae62f642237de265765458d6744273e4372add9cf5215bd39fa516575bad72034288ca3e0d3be57dbc7ada731f5f13fc0252bc5a9213f502c342a451b933d3060a2ad8a9c13013e3d93455327c187547809fa57faa299a843a251f8368a715508c32aa57a42f9551520433f9675add0359c5997c341464264986fcf67261d16b7a6989ee33730754a2ca0f66b6c98cb421c8e4b36002561b1a5550b93b144d5552afee236357c8093932829f864963159a8e7ca992b8fae006190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46a +expected_private_key = 91c087e623025864c3c5d9049e865c6226cdd2b39f8a1578eb69a864ccb2fa155db32702def5b50e973495997e18c6c21756568802a4bbb86c5018016fcb0655b09e6a4b39a8ba2d70e32bbb255bdd296c998a21f5716d49968dd02a9c4f4cb9dc72c874c232011225f8e8840f7589c2d285c1e72c8588c0a33a502a385d0527186cc6809185408e9c7fe6262725528a439332f93a5ba2943e6dd7b30d79a25939a4c0802bf57c755a5a0ebbdc8390f8aee407a541c46cb1530fe1642215556d20ab942ddbcd1627826648acc3fa1367db0b45075470196b46697d9ec6974f477eda553f80b701e853398c69a6e4970a746534928631e6b811e533a4d1e89cdd6969bfe0c861d2cec3e16d0035bb50573ed61b5dbd45c8c5b223cef4266c5a6daf104949eabd27d3319bf12a7aaa4e5f636732b28e902a1098972977d98c00a267225b84af1c8c404a52472b8d1a793e370b17a9935ee590331256620e302e390474dd6a17d17a50291b6bb940bc43f89fdd22109a72c8ecf9acb1e67ef6a423396225e6acbff2880c35673135c5183ba37df968330ce992dae04e9455267a195a41893194bc51c67393251a11ed3c0829d99a3d23ceaa387208e00974e73178459bda539bcbe89f5eeb05ee21be3b1159018a3262120c21d4972aba1a1350231d3a646ba70fa5b641ebea1b130470a5ec7c40627035b03d15696be1313b458cc9ac8460cf281a6976a9d2ccaeb9fb157300b4289a55eca386d3d8a7d16c21102aacf361578010042c3a6397e2cb2ea5224141a1d451b38fac14d7b64bd7b72db17408b0a8906cec108bb926df54299261b6b5c6a636b395acb651ce6b6018ea9c92c1525de1624b5570f7000466cc09a909cf36f34687265b61db6bf2882514705fb37346385cbf4df33b98686e0189bddea7268f598db1b6cc7b32792d5546e242a807e760ece7080392823004453048c6f743b87c1670c6d10e3001008a24590294bc9ac899bd588197530fef9c2b85ac66520a195c77a7aff61672c8cb74c07d43a2bab7a764e750663091a005c9af8cc4b55d502169d4293e79b365f60085b1cc2f4900541588819b5edcaa3b80253178639f63a3091701c7e7b04e95435bdd2114bbd3abefb23355591b0ff102bc94b56b338083b82328712733f2762c5b1d0845073cb3b46aa28ce2cb282a4347f2118a6e062d7e8524147545488a01378a853d489c03eb0c6527307fb0ca5f7aab6c328438d33cedc10733ab8a68c7ab88e0b06fc51c92c557fd59488b6245796b7dc291728121bc7643aa5d56c483186cb55086d7e8654691cd5eb97580f0a553a2613c486c0b9566a6f05f9d2b82b57345aeec1368cc126ac53b9e794be471c16a498b743c1848a14d53478fc341a0ada42bc2e0717fb6965737876468515195050d64079d624da1596f88819fdf95653b8217f9885d151821a9529420ac95dd928fc429674025882c9758226194615304f1f5caaa456182c1bb11f0a02b6c758eec4ab6441879a42450a024559697c4494d8aac2f7045342234cd8081c0077c9232e66838460ea26274329988af3a82b898c4efb033ff4101f302a898e84bcedcc45e369cd1bb7f3517280d6655c8735813347c3c7c05f81a176264a5ff791d9801af88047574008c870635457126b4069071242c24dc0977a8c13d43b889d27f08984d9ea657d241922bb12aa28a1408825b02663b970778bf669d585a975abba6bcf8513c11bc73a0c33897991c3428a5cb4dfed155b9a2909e6597dd8cac1ad62f9cfbcb27088860512859761885c5b6c5d89fd6b18f9e324ee8f80b4c507626762a22f4cb7f4527527896aaa97a69b8aa4fb09b16cbafd73a667e9cb085f7ca36067d4f740694e6c83c671071762fbba26a640c86422197894caf01b0af66960651998073ba7fccd3189148187ba22dd2661262766399a6b8bb943aedc590fa048816d1b9d827ca80935d30e1830c8115b18b754f20acd7a376272c119cc8210c9aa112d604b2022326f51ad674aa1579c081f12df04a9a2b4571fc1c21a8a4ae2c701eb2ebb0ce65cd2fc22fee530fb3daa6d82b3d46e33e9c918f6d33abaec34f45391245453ef4d128c4c068227a6511800d69f6a31a1421e2d322f897145961abea377c9393acbfa72ab3c3aaf7f04ddad50077e7c36ac46e083075265c58db4b7b47da253b8a9361c08a1248b53098c6b797622e228939f110ece18c02ac613e00b624c61eff4524f92c1ea632553d9b90cd886fd2c364b25c877459ba6de0ac8cc2a8b0f2c6d71a051f8727c2892d1934857eb995a8d728b9739872ea472e6602f2c39484d290109ba924933d6ae52c30eb4d80935f0d2c87d4dabf07582cae3c2f21692f0825c079ea6700065a6086b197582b76cac90a58451d7479965475ac8a6af662c7d23055c404246264c97bd23d280b43cdeb59be0cb31e04474cacc4a1453fa10a9e1e4050f97ca3e9ab31e561ab18cb3af721570380023a9349ed6bbc5df66bb243928dd3a4b5e113a0f99725c9c8bf673818b89030db28edc536c9620a1625c8a647bd3d7055039753e11c4b1be3ae79eb565e6367690b5338c554cfda9369e9b1ba75651a0234d2325ed82369bcd415089692547b325ef28189482714c80dcdc5bff72a6152b70ac2f16707c63a42830dd6cb88ee646d882338d3dcb202408fc5210c71d1a8ba02b8c2ab7e06e43ccd85ce39a215e67914369c749c3978778592d9e34b7671283dc787446b5b70a32c4c1ca4613b01a5d0bfe55016b897130d1bcfb49bb5f08c5df9f15b6d531b06c53a389500675aafca9700fbc310fff968300360ab631ad95649f0bb47e55b90b2593d9a60bb0477ba848c0db9f8bf6c774cf8348c65695b31b921e4439e976b4306a47069c25e4a7515866c0bd77b44c7881121025cd2f28430383600e4ba0bd28074b7bbf2a2a3bd62a73ba240d644ab1f89ace0c8a83ae62f642237de265765458d6744273e4372add9cf5215bd39fa516575bad72034288ca3e0d3be57dbc7ada731f5f13fc0252bc5a9213f502c342a451b933d3060a2ad8a9c13013e3d93455327c187547809fa57faa299a843a251f8368a715508c32aa57a42f9551520433f9675add0359c5997c341464264986fcf67261d16b7a6989ee33730754a2ca0f66b6c98cb421c8e4b36002561b1a5550b93b144d5552afee236357c8093932829f864963159a8e7ca992b8fae006190b55c6a4fc08ad10190d2a178865abfa35607e1a88b47ec8ea71b102d7f1567bed46ac74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fafc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552 + +comment = Official test vector 24, seed: "7e87fb886bc3c7c9fc12569f465d2ecd12532e76cc27c65644c8d3dd603b0cb2d036c5974e675058f271d5c82ad7a813" +entropy = 293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 +expected_public_key = 04a592c364aacb2c89689106aba29029c58ddf7050a2c78787358571aa506570288e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a181d4107cb723bb6d0729ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b370d37a66ce048a9dd27ad17b38c66880491985b2af8916c547e9c6cb16b506170f29304c4393e8274ee254a3f13c6b0e31105442bf92799f21774be9a0f64970e6ab581626115a1aa3ee4da7936504d036b75be6046e5778f58caba93f8640bdb24982c17ba3445f2ab983b685644b596ef66acf739039ad0a3cd61bb80b000f7e8bf53f60ebe235c0bf22c7873aecc6b3ae2f3b2cc3bb47d1b88423a188393c43c4999c32a886807cc4262bcd5a588c5e1bf8ed6a6ea9910c19a6042679926f314e7c7c85bf550482735e7fa088c857ac1578560a1a2f7e831223cbde33a46632b7e24d400a82a8c7307c23d6ca25075b58e727673d7cb5554042cfb9b7f95b11a55a9fd63b1b9f0b60f6931a0ba1ad28b485753446b0005e8710d7189bf438407b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b6c1729e7ae22e28f2082a5e653b5babb0d147a8748f2606ddcc7847c24f0d32771b910ccba85befcbd2b89c5035b2062e6b9bb40828902b82e12b752d48d52b7a6599ac014731e8da091cb30186c849b61954dff867899e5bf27428229376ac7d97fa03996160964abe56d3d0278f9f91fec6bc821fc822949ad5ec8a9d728b95b19052ad9442fa0527b3935f4697cfa3c7413ca2e81b32a57f69479e89760a46d710032efbb662f9467f0d03c806b619b9228135076fa235d502230e56669e2354c1b412ecfd01a429b5c76b17ae2ab99c73b4110957aa38c22c8fa39c00261c78aa571b953d868690761655ff700803a477917ac8a6105cbfc220a30a0cc1466d7598b2058b3899c567a71a66d5c9da75085686aa4ad4015100360c6102c84c336c13b229ff599dee4cb2c90a1516682330722da110f42f7c0a4f23a2089add65438dc66246671be41e7766641b4c9139777e08cb4d5b953e602931a7db3e1ce70d765516242ae8987454b898f19c5103bad39207bb16771b5d4191abbbdca9b5bea711081ca6521149b60975e02cc2250a355897960a8e203ba148f8be76452420d2134b607976f7809ce97597d8ca57337fbbd6748c03227607fa082195b49753c43047b95a020c7d195b01dd3cddc4c091916c37e447acb606f2d232c37c9871831c1fb9a8d00717762f18e62e7995a7393e0a82617da4674078d8f10065a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e887107d6c14488e604dfa15e55004fda8b65ae19006ea7c8a7471b354a4e746703d5c79857a02ec222b78b966ecf161d97ba7cf39b37fe173485a0156c3712a6ecb14e629899da9163709b672a243d1b87e15c0ad611419d85522252bb5a02ab725cb5eaea5bda73976d534a881b8c32c5328d117306fc5217aab89cf51c6174489ad241d1cb261d449f24a235fcd46fc19a8d14a4281906236738a060061a494947bd91604431b1a2871080616ee2e915863b2bf2d9cd86743b0cc12a5d21c6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db8552516 +expected_private_key = 817471e55466b5babf92a2ad879c9c951ba60d230add630984b2528f9aa07ff755d7d79a2f9ab53d8986fd90895d5401dd97ad3f7a922516279b5858f2087e6491b7bc42b8a52a5952f23622d5603a0a3152990cfd6ab9cd863345d8be5e295c06b79332b0ac89282e61e5534fe0aac95aca140398b64175235b94417b8799a4b6d6933a8b815bfbdccf886664e7b8c5cb0b999bdcb2bdb288d569666c421e2a950d198158c0d36ced3a74d9032ab7a2b9f276be025296a773266e516826480e520b844eb69710120373a94705f9030ca200a7f85a94db1f55d46081570925a476099c3ebdb32c532a6d8f16be4de6416d0c30d450808cd3c08131a92551985b92255282be6087703f182156a13cd144aca3924fd15492dfd253ee5c9e78853590930521e843a0e37a26994197b3161ee1a60861c344720286b6566796787b05cb8fd76a419c364f1830fe2bcd3a2970e2dac1dbbb3803f8053591b29bf64c2dc660ea9938200738e2c0c318b77ff86749c43c72f9667d80d462d549bdfea30cb0d9641b29308a461df72914b4b40213b62e68b161f83224c1a45472b5464f97c6d6371c69ca0d520426db8c1e938a934d50ae0b03be706b74cb8c674ea955a4d8ae1f6c0b56263041fca1871a5799921c45d9bbf13c01f0a9c5d973086b33acf923a2721c8b2fa7b058bb2e64f43bd80260b6bb19f26a4f55d53e7ccb1bfe3aa424976132c3b4b3a00908e722557a3657d285c8580ef45b76a207cb31a71402ba1ef280048378b80dc3312f78a74065b2dc873b22d37990e465e425b992722a25009a93a7a005d91b9460ab7c2336bd303883a151e829234c964265e42fbf8252cb89858d590cf0830e59c54021b83da94884a173be6bc454ad5a719252beb52a4f7544a7fbc03ce9091e9acc0568306e5bec2ed942b39a8455fa341b84571ac3fca43c14563f91395d117ab021c8f141a4ec7364ba4abdd8896bc6b281c751a66c767ac960ab52058335e14e7fd8a4e1d44de2670f9bbc67f682a0657530eba11c31381897d989bd392fae02d0afbaa5afa1748a80847af4b326f970c6161e15b212a1c66003a4317348374e66b29fe87f36d01af5f1c75be11bfea21dd8626765c46f0c153d0555b419227d50da5232810d8517b1a5e4147a52ad07012d8da23829f39a40c70d565937c58a11b1a25b27c8207246c4e1b40230e39e4f089d43d562ef954f332b7ea6b36ea28a9d26eb251ab562c0e44bd238874e93a4d3b900a4b2b08a0b68c2b82c0cb56325548da3316279672913d2021d742c3619823c4391e64112b5b77e8d707f9c1a37d3464cd5f96543f720a0cc6c9631458cd9cedea7b6fcaa76d1e60c44f74b986a772cf593ae712214e21179519c39fa533a724fe8177ea59b1123e831e1dc561543a7e559697572157b60499c4c615d02099d34b0738581061a85b2dcaaf13556208b3e5af388392490fc338dbc55bbf7d25f49f61bd7363cbe3841aafab88524b0ca3381f5b22dc84c6a112979c3c39e45157c0749c04b022f83f53733a21e1f1842e0e72f78c6ae1e337b53215ae8563b16d99ebd6225766185a0d92f9a28bbf4e2b444b7c8225148f601d014bbb8839b4b04a592c364aacb2c89689106aba29029c58ddf7050a2c78787358571aa506570288e747a4204c43e8c6020aa3e2d77b36c3440a618c55f3cae6d43b979786e6a181d4107cb723bb6d0729ce3eb98e7a979caea9508563d5a0b7a7ba55b8985b71f3c489b370d37a66ce048a9dd27ad17b38c66880491985b2af8916c547e9c6cb16b506170f29304c4393e8274ee254a3f13c6b0e31105442bf92799f21774be9a0f64970e6ab581626115a1aa3ee4da7936504d036b75be6046e5778f58caba93f8640bdb24982c17ba3445f2ab983b685644b596ef66acf739039ad0a3cd61bb80b000f7e8bf53f60ebe235c0bf22c7873aecc6b3ae2f3b2cc3bb47d1b88423a188393c43c4999c32a886807cc4262bcd5a588c5e1bf8ed6a6ea9910c19a6042679926f314e7c7c85bf550482735e7fa088c857ac1578560a1a2f7e831223cbde33a46632b7e24d400a82a8c7307c23d6ca25075b58e727673d7cb5554042cfb9b7f95b11a55a9fd63b1b9f0b60f6931a0ba1ad28b485753446b0005e8710d7189bf438407b8ba36a1687a48e550fa37cf4c6b591afcb0af6b8d2ea5a97b6c1729e7ae22e28f2082a5e653b5babb0d147a8748f2606ddcc7847c24f0d32771b910ccba85befcbd2b89c5035b2062e6b9bb40828902b82e12b752d48d52b7a6599ac014731e8da091cb30186c849b61954dff867899e5bf27428229376ac7d97fa03996160964abe56d3d0278f9f91fec6bc821fc822949ad5ec8a9d728b95b19052ad9442fa0527b3935f4697cfa3c7413ca2e81b32a57f69479e89760a46d710032efbb662f9467f0d03c806b619b9228135076fa235d502230e56669e2354c1b412ecfd01a429b5c76b17ae2ab99c73b4110957aa38c22c8fa39c00261c78aa571b953d868690761655ff700803a477917ac8a6105cbfc220a30a0cc1466d7598b2058b3899c567a71a66d5c9da75085686aa4ad4015100360c6102c84c336c13b229ff599dee4cb2c90a1516682330722da110f42f7c0a4f23a2089add65438dc66246671be41e7766641b4c9139777e08cb4d5b953e602931a7db3e1ce70d765516242ae8987454b898f19c5103bad39207bb16771b5d4191abbbdca9b5bea711081ca6521149b60975e02cc2250a355897960a8e203ba148f8be76452420d2134b607976f7809ce97597d8ca57337fbbd6748c03227607fa082195b49753c43047b95a020c7d195b01dd3cddc4c091916c37e447acb606f2d232c37c9871831c1fb9a8d00717762f18e62e7995a7393e0a82617da4674078d8f10065a28649e53377a88bb0f996d84fc83e9496564344d65b73ab96c4e887107d6c14488e604dfa15e55004fda8b65ae19006ea7c8a7471b354a4e746703d5c79857a02ec222b78b966ecf161d97ba7cf39b37fe173485a0156c3712a6ecb14e629899da9163709b672a243d1b87e15c0ad611419d85522252bb5a02ab725cb5eaea5bda73976d534a881b8c32c5328d117306fc5217aab89cf51c6174489ad241d1cb261d449f24a235fcd46fc19a8d14a4281906236738a060061a494947bd91604431b1a2871080616ee2e915863b2bf2d9cd86743b0cc12a5d21c6c745b34247c17f9447579fcb9bd38af3b64cc94782e299e1d98e68f8bcefa20d1e8db85525167378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558 + +comment = Official test vector 25, seed: "ad1424e804f306c7ff513da4c1e8d445afca7bc942fac5c0b335733aaf70693712ecbde26ea726ee0f9fd9d52a83b1a4" +entropy = 74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 +expected_public_key = bfd11fc259a2115806f9f68ab15859a763a49d169d615b4999714d550707e8a0c0a93c8db2fb5e4de7c93111206f052a7d7a5e0b5632d94c7a87596d24e950b361a185f065fa96435f312745164693fab8d3a741c56c6f10d8be52c06a5d83cb1bd327e5b28db12291d907a2888136b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861626167c5a17cc2a4cc9f668df0707d26795de7f771bc614b994b574fa309a1e1c8b4a0a4ad6240286bb78ba701ecc430269a37843149e1f1aab731523359c735694f09298e2a1a08c6ec273b4a1d57118b20524fda18190c2029da4095ead53212f609a76a343d5c68ff17ce6b92b340dbb8cc6c03ae4b29df243b93233af6b95eb5a7a8b8643b0cf5a8114152b8ea54f0e3668511ceff536d888baef85a62299c641769023b7b92088546f338448c1977804b71781a554bca5f13c0480b42c5a6626904516139abaa54b429e7a0502b17a5a2727a7f230d63c5764dd497f164b24e5ba3a626785ad1b917a6b77b175e64323783c9791832a7c442b895eb338e6a29ef671d4d7c0230668c14bc794cf11340229ac905891cf1c51ef62b6a4a0553331f7f581054da45c370bf606126b39492e4a3b8592bbe0359bc017557379471ef922367d82635d8494c88bd38a7720669a1f9145367a92090fc5df15c034b82cdd9b7cb9ca76e74b2069c36987556012bf0746424677f60ade29c9cb52c6d9cc2052394691d7306952c65ef498da41279eeabccc66b3a41747a8b447d7ee81116eabc04f4b776923c93a28ffe888652fc34415baaeb6854d4732745a4bd5ba61c35678780063ed874c81823ceae41b9684a05410266f7ecaffbfcb5285472e5b02fb8c15d126410f0ba3ba8536cfdb65d23797414a55f2620be653a98f33c95690714fbd3418c6893f8693908d41d6d69a744e63b2b0c190e3b1696a5c8b1cbbaa4719a0bd184f896c9d8f926dc933ba81b2785c05a51b22a95191f43dc23b42c050dc9133de2b003a5b6f1a5730f490454c58af291cd8d46acde69842df79353670a54e2c88cc693745516ee64c2afebb95df25ec0608ae4aa9c89215d471bbf68dc6530fc0fee495fdfa09e98ba8d37f9636b270bd1102579eb7f1bf0b911cb79f03537168867eaf60d77d48be27bc935b02662929dbf2263270670e0601e5e43008bcc07f06451e54755fcab421d584bb603008c9909caa61cf99a4b43a93ea8a3440991ba402c9a8fc51f90584c55eaa450b7a600342e98420d728a8b6344659f2a0263140e69ab86bdc6b20b3aa0920b90c70c0108358c8a92b27635154af9a0a76080ee593ce3d37e40fa33d0c654aa77171f822e0082c95cb60b54a6a26099443f671e863889f35a0b9597b3442a71fa704f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75448d21926da0938f92b9133a92e426dfd2634a677878ea9820f5c26a2382fdb1c4b8ed59db74b4490b87b0dfc35f5b22112e5110d494e53c50d3fd6c64cb485bf5ab37f7a1b709122c7086d3fa56fddc966db2c53e09b976f986a334290dd8c3c7e6582c4eaab182766ff70503b03b4e68261cd0303f7a83732795cbf84a04d78a541a0929691c94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae +expected_private_key = 60e93beb5544294bbd612141956430cff041e0f969e954a48298c7b5f321b9e1b70b7c796a753cc5bb93722b20380abd6b8aac4f0b102ddab380b88ab9dc040fcaa8b775882a673864fb757a3453273627df0690c90000b54112dca50235ba14fea59a764736a018a091b822a636ae7934a33bc5c15a7b77e1e53289c9757ec75cbbb792645325d6755d79b972ae993c9e3413ac040b3bcc85c4f98a2e185bf4ea1d19a4737dc78547847b7ef385d2a07bfe272764cc873be8cb1286a0e7c83539d2b9bad5a17f0893ccf41e2b5cab8f66706955c5e168a99e9820a8402cb25a434f1a149f0148761014d32a51bc73a8cdbcb104c29be554b2724107ef314c25d082c7252e0ce68833a47a619a611b08394960a64d8c22c25aa1121a8033605c9bf35221730b15e6269cc25febcb8e3336870b3c1c9d3a89de4a9042758f517b55f85133b403c501590a0f53542239118f93874b319be0d063ad82144eca6156051424235d785c92ac00c412f8ac0ff5b88f056142f8a0934734b09ba14c00089bba136279a5fe462082ab4b0709a6db3279f8e9544f3909ff78b264399c2ed129c803b341d816eae96bc531952d55059ef0233b0c18e1f7aee5498ff6f11dbe801dfe193bb61b870008ae57483daeb8ca7ccb460193c68a509e8dc738ff227fda89b21eba0053992a4d3a1f8767c0d3f3419838c8c7a2c0b3d68e737ba77221c68a8570948a322a143e5a03888c08a1bb7c42e9db9111819ed94523848bc32781a881a468d26aa7fa4acb926ab8695b24a094b8ccb0423192cea88c1fac818a6b0ca19e423b7afcb51b121d48ea44037963ec1a325dc0bf7555977f468feb49b8346338db983e512b2fdeb35a300495f437cba88c36d01536f7a56bc9dabd1000b77751031102caba7182e2c440919435a14bc1ae1b354499324862885c9c301b7258faf778cd0a4721f26ee32c5dcc7a7283dc10e3cb04713255d0044bf1d9234f5180f32483f7079b2c0558b95c622db01be885b2580931fc8617b6940ddfd54cb327712da02f90a6a8ddb6ba17a31fb1d7231d94cac2fab88a43b0f56968fe2b724fc8a97e1a371c96a9a17a94fda08897ba1edf959f37029a84e707ef676b89fcb5e94b8997d95542e26cbd28a7d01b1fef76b1c91ac327874c04f01b2d6280fdc60cead3587bc0aa6ec76f064b3263b2419bf3120aa7791053bfa6e089f6cb8bb020b5c5e2517d4b2f34ec3c4237af98dab3f4d44ae161773ed53f391a689d7b38f01155fcd080869656e15baf9a2a6419b38c2ec39112b4216fbc5d94771fcc4369eb90aaccf3a752020e24f97c30c4c67632180e9b928a0941c23c03ce588f7d841aab91b74b7959bfd8b5b042294ebb094b523dfc425e9ef70bd2e2bcb2937eedba0ad018737ba91a3691030c1a6e54c0bd4336a4bbb7c5dc79057ef5c574c04dfcf9c8407cac999a54975b1a45519075ca167b8285b2d554eb81702e30626897413051aa546bc63a42723bb95f0dcc525944c967d7a5793c34c7638ee59608c8680f2418b648b7450b09c31bebaabb956e1203bfb3d377373b5483c93378f15dcf2959d0e02a15e2277b7ab78cb2ba78703f13dab307ba1b663c86bfd11fc259a2115806f9f68ab15859a763a49d169d615b4999714d550707e8a0c0a93c8db2fb5e4de7c93111206f052a7d7a5e0b5632d94c7a87596d24e950b361a185f065fa96435f312745164693fab8d3a741c56c6f10d8be52c06a5d83cb1bd327e5b28db12291d907a2888136b6fa3a20a48990c6b6c81499de2bb12d19b591234d55c4549a3861626167c5a17cc2a4cc9f668df0707d26795de7f771bc614b994b574fa309a1e1c8b4a0a4ad6240286bb78ba701ecc430269a37843149e1f1aab731523359c735694f09298e2a1a08c6ec273b4a1d57118b20524fda18190c2029da4095ead53212f609a76a343d5c68ff17ce6b92b340dbb8cc6c03ae4b29df243b93233af6b95eb5a7a8b8643b0cf5a8114152b8ea54f0e3668511ceff536d888baef85a62299c641769023b7b92088546f338448c1977804b71781a554bca5f13c0480b42c5a6626904516139abaa54b429e7a0502b17a5a2727a7f230d63c5764dd497f164b24e5ba3a626785ad1b917a6b77b175e64323783c9791832a7c442b895eb338e6a29ef671d4d7c0230668c14bc794cf11340229ac905891cf1c51ef62b6a4a0553331f7f581054da45c370bf606126b39492e4a3b8592bbe0359bc017557379471ef922367d82635d8494c88bd38a7720669a1f9145367a92090fc5df15c034b82cdd9b7cb9ca76e74b2069c36987556012bf0746424677f60ade29c9cb52c6d9cc2052394691d7306952c65ef498da41279eeabccc66b3a41747a8b447d7ee81116eabc04f4b776923c93a28ffe888652fc34415baaeb6854d4732745a4bd5ba61c35678780063ed874c81823ceae41b9684a05410266f7ecaffbfcb5285472e5b02fb8c15d126410f0ba3ba8536cfdb65d23797414a55f2620be653a98f33c95690714fbd3418c6893f8693908d41d6d69a744e63b2b0c190e3b1696a5c8b1cbbaa4719a0bd184f896c9d8f926dc933ba81b2785c05a51b22a95191f43dc23b42c050dc9133de2b003a5b6f1a5730f490454c58af291cd8d46acde69842df79353670a54e2c88cc693745516ee64c2afebb95df25ec0608ae4aa9c89215d471bbf68dc6530fc0fee495fdfa09e98ba8d37f9636b270bd1102579eb7f1bf0b911cb79f03537168867eaf60d77d48be27bc935b02662929dbf2263270670e0601e5e43008bcc07f06451e54755fcab421d584bb603008c9909caa61cf99a4b43a93ea8a3440991ba402c9a8fc51f90584c55eaa450b7a600342e98420d728a8b6344659f2a0263140e69ab86bdc6b20b3aa0920b90c70c0108358c8a92b27635154af9a0a76080ee593ce3d37e40fa33d0c654aa77171f822e0082c95cb60b54a6a26099443f671e863889f35a0b9597b3442a71fa704f164834fc9c8e2c63847c9992cd73c1bfe7abd3d75448d21926da0938f92b9133a92e426dfd2634a677878ea9820f5c26a2382fdb1c4b8ed59db74b4490b87b0dfc35f5b22112e5110d494e53c50d3fd6c64cb485bf5ab37f7a1b709122c7086d3fa56fddc966db2c53e09b976f986a334290dd8c3c7e6582c4eaab182766ff70503b03b4e68261cd0303f7a83732795cbf84a04d78a541a0929691c94a094b7b8f92c5d5a3bc95122a6a7968dbb1334a712823d470766b3b9e7b55672d02ae16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9 + +comment = Official test vector 26, seed: "7c33ca0e987226c8524dd56c811fa4d1ccf9995b1e4e4dd5b1481974e88cfabfbf6787775c2611cefb27ed4403ea9b46" +entropy = 013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 +expected_public_key = 12422cea108045d2888e2c29ce0bcd454b95c09730d6c4698e779987523de0e972332544c34350d29c7bc030bb6273b9f1c98c3a63170abb2641c54dad64790e83387c51aac922814f834c4745409273ab00051b2a819eefc9a048f222626409fa7b3f8d27a0dd754f9372aa37eb92f6454fdbe3116d406b571203dc05201c31a52ba8b2b95b191a7b7b55e743c4ccb80a710863ab741b727f176224012c539af2bd062ba6be7a42eac08c5b6b420becbb41b55454ec1f41347ccd984f11767bfc82665286a56dd31598834b37ca6ee93658999798ead094298160b7e6c76978370db3180273401532315168a161e087d4c6086846a3b60b80103c1ad814843bca7ab329c7914982ed32bf16507b3024a16f231281a732d3d155fa60260064919c484c1741874ba96cfd91aebe5c314e407a66d7cc4c846176d759618654ac2a52fe69c69a375ecf625e2889abebf395fa20561ba6300a72a2091356fcf197c866ab5468a3af7bb3de755836d9784f7c0949445d83b3358721c7db3c09b5120f7f757bfe3366ae4365b677255ea680f27c310f768e56f1aab8792259340bd6b984406148a254bb605a291c0946c83b1e9c5bb3f879a787b9106f98809e94bdc23c062d592318f9854df04bcc343d64387baf398599bb352f82b1f0a5b530e824cfd69d7a4a15cb5624f70cbefe1c61302b8fca337d70d1900dc817837619fa893208da873c350f02892097708cc637093eb25bfb4b3c793331f0fc73c5446cb11276824cbe419378a224a683fa0d17c671fb8c4bdaf18c20c53a21a4bb8fba9ab7a1b7eccc81946bb5fcb15e1d08ada7761a55d503dba912b73765ff93a6ab642b5fb72ed4f16657ac448a1957413cae547ccd76d9936c860c70c5635c28754421af13448959d67cdea3997ee923aa326129b5397c15ab90f95832f263e080a42460cf9f081152aa59cf17263d008acbf146f34a7808257689a3148e58a0a0117fbb47bca97810a42a7e0f734c0a17745afc6ade752080b39f3267399c20b1fdfa195437b83ef5125405aba8d2ca42040371c541a5fc339772948a21b7efc30c909c7938779bd012642441083150118ce431baa72e989425210945a7c47479f4873e3c3ca6698ecb2a050415066d0bbe5e240222a2884b3cc17bacc14164be0d21330456a279547579f8a4e9443d913a154210a3fd1a1a263186445a8e1b884bbe8b54d0196affdc47544c8d10a69378fa139bc8a422c44c5568555f9080f170bc6e97284f448e6c23885d603a732c469b376a762b5068e29e80b74f994588d9822f3e81ba6ffc273a9c905d0910062bbe94aa1e0c8c3424303845779f8c9b515dfa0864578a66da8ad7b56da2810c11e1a2888b88bb55b8c096a145b62ad9d2c98e003658c9729d7b82550527411a9c0b981f3479251c1774014749d211687dda83626c6bfcd5b08f8075954bc10f48623838a736e38c1143b9472b4df5d30d37f0bd7c727a2f16a3cbe0015dab5a12e27a63f7aedb841d6d9bb1a79a5c3e903c9e374da62a298c549b9842b77c33aab6b4939aeb55704cb610d084950c41b746afd7157613618f6f1574ba51b36f7828af0aa4f79c0840ea3d679013df619046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6 +expected_private_key = 3a756d6dd157aba65d60721c41eb4edbec38834c22e9ac88f03119b472bda0961d1f5c3268ec6492f92d5d066dcba69ce9c20311e1c15fa81fa5014c6c956f88055fc2d35e6b295d05d6167e4375bff23257ba72c0f97f452b609f22b57f7c27f71a4f259938b5aa18097399a0d32c3602203bb6769015495b4bb7317c9e99c966215c58d3455efcd36003826c2c7b1bb437a66a968dcba35dad7098fce9133110a109c2b91764719ca25866c98550082e88f29e78b38b40a53c4d626fe63390a290b54389624c597909d79fd6a658e2166704c386eb1c8e951b4c7619b7b79349c3f59505809b1095405949cc55c109a1108649552d5f83a970083bffeb6550893b5c5106417b0cf1e44b6b05a9f9093e386c9d43f14d4cfbabd3b17efb49aa2c571ae99197d2e4b7d58775962570d528b8ebb8032e8065bdcaa391837d483a27239a4a8c0b8f13013f4aaa6bac0ca86e532523d9620bf9c2c3e2aed2365e90a1699a4cbf454c4d2e2c4273e93456142f737c8b3697b9821039142c3e25b346d020c829850d6ce2649087ab762c25baa2639c8c7a852bc76d456ee69747fe561e267844a7e51ae05c5820f0c2b880b05cc935a3bbade2c6a4881cac21938a304c4cd2c1cc1bfabd932b777cc459bae4be75389862464367c6318a0521dd62c5f070a139a95522d10d2e4134c06522cf52834562a208b22a95431014934f51ec49f5ec087d1435db935bb5223c3ec87bb7f7427a458232474ad9cc222b422149977c7f366f48b0b14ab260bd0a8c04623f9b12091ae049725064d0bb4a249075816aa249718f1a7768c3469aac7182d2f01d6373038d7c4ca24802693a354c19c66dba1c05eb180ad04c1fb095b42947d16b66139384c71206bd0ba9ad9bbb5dd7593d08616c214fd9013e792a5b4930122d1c571f1315d235562c167d7546c8ef7536a929982f6a55ce7209b0d5735f69ac6c52a824e508d2481a5be01075c54d8743bcd76767b69b5e350989e629c97ac1982a75806126245fa692def22b15a29499c82ef7f993eb3472f850527d900da2f513a9366a4fa978038b9e46752dbb8084fb12cbc591008d692544078343e9ad67909dbd77c18bf18f02607210f4a0f5dc749f8b0bf371309027968968678b0135af65138c5544abd57ed8a646409224d32052bb14bab4d51dac981ccd838b4a513a36a351b81a0785ca281d7106872583b8babbd62a5787bab8ec9019c7009130ec6be4e25d9992aa1dd13da9c1a7f1ca27fd78968741436003789b8c781c599c98d2465c7513cfe85154d7a655216e5b3b800deaa6b9dc7c0d998b9ce2b99da6afc27a5ef6c152eb16184d91cd038cba69835ab3500ac2e87368f37888ba90f219ce9da24109f0b3e1894db5f640a17b0e705195a350a61ec62b2c7a216231c530f557d4c5605346a6500b7c1484012fc87dd4526823c447b71a726d65753716b30c212565dac474ca3acee664218285a5c4a726f681e98619e2a289d08895bea26bd6a3bff3a5c5c1ea894cb6440d075004f879b41a14ebb82b74ab0131d0b3348742db7244e750ae2b7bb57f8a95379502827880f8a50ecb1394db2553c07627c113a300078db1bac7b5007812422cea108045d2888e2c29ce0bcd454b95c09730d6c4698e779987523de0e972332544c34350d29c7bc030bb6273b9f1c98c3a63170abb2641c54dad64790e83387c51aac922814f834c4745409273ab00051b2a819eefc9a048f222626409fa7b3f8d27a0dd754f9372aa37eb92f6454fdbe3116d406b571203dc05201c31a52ba8b2b95b191a7b7b55e743c4ccb80a710863ab741b727f176224012c539af2bd062ba6be7a42eac08c5b6b420becbb41b55454ec1f41347ccd984f11767bfc82665286a56dd31598834b37ca6ee93658999798ead094298160b7e6c76978370db3180273401532315168a161e087d4c6086846a3b60b80103c1ad814843bca7ab329c7914982ed32bf16507b3024a16f231281a732d3d155fa60260064919c484c1741874ba96cfd91aebe5c314e407a66d7cc4c846176d759618654ac2a52fe69c69a375ecf625e2889abebf395fa20561ba6300a72a2091356fcf197c866ab5468a3af7bb3de755836d9784f7c0949445d83b3358721c7db3c09b5120f7f757bfe3366ae4365b677255ea680f27c310f768e56f1aab8792259340bd6b984406148a254bb605a291c0946c83b1e9c5bb3f879a787b9106f98809e94bdc23c062d592318f9854df04bcc343d64387baf398599bb352f82b1f0a5b530e824cfd69d7a4a15cb5624f70cbefe1c61302b8fca337d70d1900dc817837619fa893208da873c350f02892097708cc637093eb25bfb4b3c793331f0fc73c5446cb11276824cbe419378a224a683fa0d17c671fb8c4bdaf18c20c53a21a4bb8fba9ab7a1b7eccc81946bb5fcb15e1d08ada7761a55d503dba912b73765ff93a6ab642b5fb72ed4f16657ac448a1957413cae547ccd76d9936c860c70c5635c28754421af13448959d67cdea3997ee923aa326129b5397c15ab90f95832f263e080a42460cf9f081152aa59cf17263d008acbf146f34a7808257689a3148e58a0a0117fbb47bca97810a42a7e0f734c0a17745afc6ade752080b39f3267399c20b1fdfa195437b83ef5125405aba8d2ca42040371c541a5fc339772948a21b7efc30c909c7938779bd012642441083150118ce431baa72e989425210945a7c47479f4873e3c3ca6698ecb2a050415066d0bbe5e240222a2884b3cc17bacc14164be0d21330456a279547579f8a4e9443d913a154210a3fd1a1a263186445a8e1b884bbe8b54d0196affdc47544c8d10a69378fa139bc8a422c44c5568555f9080f170bc6e97284f448e6c23885d603a732c469b376a762b5068e29e80b74f994588d9822f3e81ba6ffc273a9c905d0910062bbe94aa1e0c8c3424303845779f8c9b515dfa0864578a66da8ad7b56da2810c11e1a2888b88bb55b8c096a145b62ad9d2c98e003658c9729d7b82550527411a9c0b981f3479251c1774014749d211687dda83626c6bfcd5b08f8075954bc10f48623838a736e38c1143b9472b4df5d30d37f0bd7c727a2f16a3cbe0015dab5a12e27a63f7aedb841d6d9bb1a79a5c3e903c9e374da62a298c549b9842b77c33aab6b4939aeb55704cb610d084950c41b746afd7157613618f6f1574ba51b36f7828af0aa4f79c0840ea3d679013df619046e935e0bd96ec59643250a0b38f9779b0142a9e546eb525e72ad204d1eb31a6633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f49da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72 + +comment = Official test vector 27, seed: "54770ea1252ea2857d6635151194f5f520adea8a41e409ff498d40c271359858fe2b084d5b96bee087b8e8f4dd4e00c5" +entropy = ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f +expected_public_key = ace2af54375d684a6cb1fb38bd9c803a158483f91175263779e75b6d42734dc72fa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106e91e32341aaa4808df6528c3ba98886184e0195e3ca09d9cc525980cb5a2e9027c6a88e9042bf77653b9dc02ad3cbb04f594bae08da4683dfc960708d85e39a28ad6e6a7dc81a2f0f8167633901298628b695cc1868756a97d80b1afebb71eba5969a1086de4d611f737af56a83c7378c6e5e04e79a8967514cc668bc8fb7c7a1a671e29d55068e34d883a8320438ae7a44f01db1d4dd07304081d684796a9257154381ec44562a8d005f3dc4c94d5ce9e36705132acc8876142194da54934095c2d5725a10e376432b17bf7d1b085d342cb3c633a085e950248ccc9c7ff350efc341d07d0ca06e6bec943353c479506691f2347a29ccb34ad09c929692ed98640e6b8560529cb17030ebfa4c769fc7707c75d86c234edd78e7b3010fe86bf71748cc1c5b00023944774200b2163b403b8207093dfc959b6aa09fe6b98f6e83f972a50abf113e9da2fb9fa10d0d05789ccaf05c448854249ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf428087d8333b16b1a9e59794d49a40b513b50867979230243b27f3d784932e1caadf8b58fe11bbea62da4875d004a73fbcc90b566ab998a45099194d449cc60b0562570648ad588b213cb99a01283706878287930a71b68b43f87023d2f49829abcbde6a37a941182b78b8cc1b93982c7a24457a9e1683d2bcc97b4259518e0102760100e1c26cdd85022a04a91168486ba3413613ddd6c42ccb563379a08096b287b41a011fc9594d132e33957f2a5bc1db4c57b4c8d9d3135476095ded35b2fdc09d8f996e332baf7939efb1032e529606677bb1144374c41c08807c9c0868b0c32772f18b755d7bc5c5b12f8eb9ca9dab589185553b74408301062c90b2d68504f0718d42a1989f050f9097889aacdc175cd7e6768d626a8c9aa1b0cd6cbe91b10af1a3e507575b47b6ac8c2b7c801a81985a81ad4ac04b32d0dd880d43b3d36857738369b7898b231b24ce6e9944526b9ef370354e21e38f6aaefacbda63497a85327a2112a5db95179c5285d805698209f2a1b67a7730405b02b3507b4e4b65298734f5eb1b66bcb68f9369abc01c7e4545568d432a685a6e038122253987edc55efaa3d926413dbdc43f9908df1925031f45d28712734fbcec3724653b019f7d5698da7b0c3c90eece1a1be3567a253a143723b9550c8f7333ddae88208667353a6184853a85a99c0c463189eb5763fe59d678349f536c56d014cd92b56ed2aa6b0518f1221a49fd6588650057ff00aa29b93f182b3437386f1f846d2a3c60cd900559425b2b7a5ff88cfabe24bedcc825552577b5c12e4856ddcd91b0713526098b5fa555f105a0f1219110347af9016254951c3cb5c7ebe602564242276399b0048ad8d370b544b1cb9789694c7753ef2cd4ab51513cb33f38bbb10c83c9a1a5fd1489d97476d9bb314849581d688c3dba01662b539c50b0db8e889a4654e6af708a64910fc503cfa0abc21b8abc233ab978965059c41d1123a4bb90306aa09263b25be885f4db186d0e720e97524464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc +expected_private_key = 0baa531a985251b6b10153c8fce6938a280e93f9ace7a56dc7f44fa8bb2f88c09290888da8134a0fc43ccbb75b50b6a724d6812183acf876036dc252fc893419280314c7611750875821b2f3ac4f1c20b06365709bc07ad4161c94c41930568996f8cca58c4a0536cd5668488715593e66621f96c87a2178a36438dd4c390ca0532d30b88db712cd3c50d30baa91c98cf0bacf32c60c81468307ca35b47abfe59174e53467cf7b1d376758f1a5926fe225f0078ff288ae24d23241709e471624285c4fbd35a333088dd643cf6cb0ab6b27c8b679792ecb8ba4c28cd8b09677f0a7ebb692eca6777922c4ed6c20402533cbb9a3f1e0c10250209ef128a626b763b30b5e49c4c4691e3a13c2c2601b6666aba1d099987990bd1bb00ab5806390ce8088cae30a5b20567295aca7f0191cbdb4795e78bf150c7954f9a49880c218c23e59014620e18f18c536da0b7807b0c9e11b1e341c2e7e5ba799653fc669c1032aa014cb79769361b01091b5e000cbe100933c6d05714481f491b2355e72638831d0c4f4daa18c6b4ae6e825e688cb812490fa13b43d306e5bc857fbc18a61923f6b685e5fbb5be9c1871a9822ff07caeff40318482144143cecc5b0c579c84fc949ef359f0b24b20fc0a9f3300a3217a8058469c78b7998744024e275cd1c70a96a75fd86019ca031fec081dbdb796a56186d9a1df8c098940527d34a1df2db50b5136b6737829f0cb1da3b131ab238207a011f02bcd346a0a7138ebe3ca2d78646d7f98d5a886a24b83f8fe84ae81627011a2633f1c159c3870f7c69126b3c31f50d356888f9077fc207168cb075e0940fb7a0becc556de78089ed512a39a6adcda9c3c5126d874b50c163ba7b091656e52f9813cb318c87abab12a3f8996a4cb446d0793055ca177a1bf455cb956443e56c160f4788cdc6b008c086403bc910332d3e3274f9825e9964484d7a52c91c275e153a496801c0e6c8084b25b53c8eba77a9412291df78bd39895dfed82fd3c92947a1beab598d33da8344c88a9e073e28549fc939cf5c6978b6f74ccb23675616899fb69c5eca0c6b68090a338eab57a222fbb5a482837c097bd40141659a2a71d81e3bd38d60d0a903592b768b0ce60a7044350a75fb02f19482138603a9d8cb89ba6a32d37a15549548aace4636047d66ca4de6cf7643c2a5939478a39873820578150172f965d4dc6cc6d7adfc360568a53c97d268900b7b20122e50cc5e460304927333beb7bf73446064d76c3af1274b503203804774b00f02534772ccb83caa8475651460b156a7238da2a9847d445f55687a84baa06dd69d4a637efcc1c09f81bb97b541fd77a96883869731ac776913ed6c02ef03183b27b4655639509b1e8bba74837375628152814448f270b6dd865c888180aa071a2ab42740e93f05b32a9c85a069420be2ecc5335738f9d46c90c5af1625779f3a329dd693706618afb300b5c7099c220126c8398fbb8f32a2a35888bcaa187950365f022585c2e08243f53122b6c5ee9a95b84151afd10b2110135c2a940bb8370565bcd8739609c44f4aaa7c5c266c6ef7cab87b351236702e327b3e53555e24abb670ca6e505df0e0aecf7513f7e36374988dace2af54375d684a6cb1fb38bd9c803a158483f91175263779e75b6d42734dc72fa02bc3b09630a0f79e2f95cb067c7dabf42f409a9635d55106e91e32341aaa4808df6528c3ba98886184e0195e3ca09d9cc525980cb5a2e9027c6a88e9042bf77653b9dc02ad3cbb04f594bae08da4683dfc960708d85e39a28ad6e6a7dc81a2f0f8167633901298628b695cc1868756a97d80b1afebb71eba5969a1086de4d611f737af56a83c7378c6e5e04e79a8967514cc668bc8fb7c7a1a671e29d55068e34d883a8320438ae7a44f01db1d4dd07304081d684796a9257154381ec44562a8d005f3dc4c94d5ce9e36705132acc8876142194da54934095c2d5725a10e376432b17bf7d1b085d342cb3c633a085e950248ccc9c7ff350efc341d07d0ca06e6bec943353c479506691f2347a29ccb34ad09c929692ed98640e6b8560529cb17030ebfa4c769fc7707c75d86c234edd78e7b3010fe86bf71748cc1c5b00023944774200b2163b403b8207093dfc959b6aa09fe6b98f6e83f972a50abf113e9da2fb9fa10d0d05789ccaf05c448854249ba8973a19c537dd69d3f39744da89debb58705ec90ea56cdf428087d8333b16b1a9e59794d49a40b513b50867979230243b27f3d784932e1caadf8b58fe11bbea62da4875d004a73fbcc90b566ab998a45099194d449cc60b0562570648ad588b213cb99a01283706878287930a71b68b43f87023d2f49829abcbde6a37a941182b78b8cc1b93982c7a24457a9e1683d2bcc97b4259518e0102760100e1c26cdd85022a04a91168486ba3413613ddd6c42ccb563379a08096b287b41a011fc9594d132e33957f2a5bc1db4c57b4c8d9d3135476095ded35b2fdc09d8f996e332baf7939efb1032e529606677bb1144374c41c08807c9c0868b0c32772f18b755d7bc5c5b12f8eb9ca9dab589185553b74408301062c90b2d68504f0718d42a1989f050f9097889aacdc175cd7e6768d626a8c9aa1b0cd6cbe91b10af1a3e507575b47b6ac8c2b7c801a81985a81ad4ac04b32d0dd880d43b3d36857738369b7898b231b24ce6e9944526b9ef370354e21e38f6aaefacbda63497a85327a2112a5db95179c5285d805698209f2a1b67a7730405b02b3507b4e4b65298734f5eb1b66bcb68f9369abc01c7e4545568d432a685a6e038122253987edc55efaa3d926413dbdc43f9908df1925031f45d28712734fbcec3724653b019f7d5698da7b0c3c90eece1a1be3567a253a143723b9550c8f7333ddae88208667353a6184853a85a99c0c463189eb5763fe59d678349f536c56d014cd92b56ed2aa6b0518f1221a49fd6588650057ff00aa29b93f182b3437386f1f846d2a3c60cd900559425b2b7a5ff88cfabe24bedcc825552577b5c12e4856ddcd91b0713526098b5fa555f105a0f1219110347af9016254951c3cb5c7ebe602564242276399b0048ad8d370b544b1cb9789694c7753ef2cd4ab51513cb33f38bbb10c83c9a1a5fd1489d97476d9bb314849581d688c3dba01662b539c50b0db8e889a4654e6af708a64910fc503cfa0abc21b8abc233ab978965059c41d1123a4bb90306aa09263b25be885f4db186d0e720e97524464c7f1b57e338a864d6c447ed4e29d88c30bac7d2d0cdbac43e9f4176f0078c715acc3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d830371600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f + +comment = Official test vector 28, seed: "cd6cfe94e9c0a1cc4ffdcd2d7876504be5f50f1d1ca5cf93482943465b268276056f2781f4de805c138976ca72621387" +entropy = 2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f +expected_public_key = a9c823efc5c946dab44b5b2068d61f00e7b0d87ca67706343927bfe4c12d20d69c4a5ba892f97eeeab7b5a45742cc4ac4d37219ad72ac312051d31b8385ca2293415a13bb8983b8457b8af9dcca9e6322094ca68399ab77dbb9f6aa7ced5f224641c3fa07507da9a08e0d180d52585dfb3b2fc95cdc733a573a888d403cbbb71c120baae2a195278370bf33299b9b2684accc5288a3cba1277fd3999839a6ed29bb91d71a528bb2e4f953778ba23341cba4b9b3c17f9a8366212af3b722397419e24874b163470b3b2b7f24ae62258983b6161c6773b5ac90969c03d01cf4669b9d1f46e05705d4f676d464264d7549e1e2c3290c9b2bf5a71132057531714bedbc7a91bc0ad56254d298908d33d588951333b3cb7924abf14b0d70652c45aa62cc3062d851e45c866c6200df4e74a9e559b9e6ab738f2b0da9693ccec3d968a866f0220ca95b7c6e8b04ec41d39c17eafab77444aad4ca3a9d6b5b5d4611a6c074fdfb01f7df68ad2440efc5588f3b4a5c4106efa3b9b6bb35c327465c7b656d1c1c6409993fd91cc20172e53190dad63ce02691ac326904cbb6424c906bd091312c1bfe6969ba6aabef954b5c8d439da5064a248c92988961fd2254479946dec829c76cba61690e3c541648228b59805d7fb2adb6aaba70718985279452a2fb1414e4704ac3dc84d3eb767101c8f4feb24bc8148316609bf963afa826a9b87638424052067ce8fb393d9ac579ab1080d1c549fd5103312a1ff9988dfe7805ed906fe9228e25942d49484a4510e0ff9a4a54a22cba6be945126ebe461c5940a74e1517c60603b2651e8371973da7051eb7197713f5583ba51b92a9eb3179b45a8a8a5099b40c29f59146f25a563291364f236038c79b784bf09524fc6810f91b777bae252e5b723e8059c06157653e335549784a15553ff9a7a29407d87725aa6b7a2a2669cc776bb810672967cb5b8b9a9ba751a9e69a8ddf796b1f324348712ff0c23f49a1debf210c027995b8a7cc5b288c4c74218e5086112237128cc57f4bfeddc21ed23bad00c58d835b5a3f0c8fdf1001e0ab26c2cad47d5caf2252cafd3520e36ae21119e56fb456f277132059ca18623bfd994878c794545ba4a04436d804231f430b12808fb01647fa15d94b975bb6798ab7c3f6355b9bd50bc1ca00ee76342c8609be0bc893deb398b65a453ba08bef83b805b61945229d98422f59c27e86022da5620d737867828540c20b097076bc6c03e5435aee1b9af19958a7dfb921da414280429da389eefe23fc9578b714b4f2e5b19b792903ff45aca045bec0b3d83c204747a2e24971b440c10119941d9316f45a87c4ab2ac0f7c4bde9bc8ef73a7f42513be3420c56720ddb984cb173587462aed9996d2a848d11344eac02351e6c5a18cc7ae813bfdc50d5b143f4d07ac72a213a0577f9802043a585d95031d017b319358a24b06b7c2ea19f22b6634146cc0a123a8051c51e6ad6a956b1a935ffe00bc65c44a60534d1375570bc036edfbce66255f523bb377b2256c29b870da2c870868299828f6fbbd8e0a109386b8d743a6e7a38384d5933e64565a037b9f520ecf8466f2073eeaf03d1b606f947ca2d2ca49e4b41de9011ffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fd +expected_private_key = e0c2121f06048fbc565fdaa305202d439ab3a81b31fa257aa6f4273547c1465610ae51c2c1c8603aa36d1575754a86c9194b1cc6a9b8c9f77ce6484c5198a193ea4369293798943f7918142f849c8d7479eb0588e6e6b4abc4ce81a406642414eb4137c2da905ce4ad2b750e7d966d34a3b1bfa8ca5c8070456b1f6d5b71e582c9e1e2bf9dc37ab60a09e797a43f66b27b04c13c034fa6f594264c9d7da884c762b159d775f7750a1862216e8bc992c9b2e0d18513f409df8b0811ea89d2a69b66d34e59bc93f5c7bde25140a976a3195541ee22a7edfb7f9d647616b31399b6c924022f036225af7c34e6d221213ab5f7a20b908325835266da1b456f5649b895bb032142fc5c700cfac4c2a44cf1f96d57b8ba1ef2c9332a612e8bb9043559b5567090873d3f9450f37670b473a96f812ce1d71892e43c9fe61fa594601a27a98ec817dd822c625b98e0fa8f2d5a311a87a6c23b4dfdf44d7511373e64a4a18a833d654a946b0da9694329023086013a919971cc4c8a45916901b45c25c28eb6051600644660796935e65a4700496bc32204201d5c8708fdeccbfe949d1339947c6baabcc67ec901659d220fa4d1a3da1a4adc2b1b323bc4cabb6065d9032ccca3dd3c8689c9a35810bcb30b99b3f55cf2ac8258c5b85c696a372c7aab5b0dd62aba06804466fa4c22b2ca0e09b7d47c4644898aacf6899c79b5321110f010cd40253e40c5920db980a57c01b55c506a6662be1253ff171412820272613940704f63e70340414322b69b60b50bbb4459c1d6a0f25065da032455598edf678505f54b51713209565fc4812ad5f8a05a926340fc3853719146d049017475a09a1fd2d47b35371d715c455debb3a40a8a0e83247b6b8ffc05b2e857b5d8b201e56c109dc155b720b2528301c49237f7a629234231fba25c75d600bd360796a68991bc68cafb5b0b7c748ab7039d8c4fd1b3b4de76c193123e50109ba70956b9556f245ccd4330b888d43a84714e8cf17e5713b5ae5a9fc3a331718c227ef4bdce131f31028d68529f06a218ac32317e9b7634c572513974da2bc3ddc4c07f2c6b8d3aaf5734b5d9e691d790b0fa67cbcf36c0372c056c268e0c243132db5de7365310f5732151b80bc98a2bb76f9e8c616fb1c90a5b83ca5738bfa9cf1fb96242998a44d667a57b517a834834ac0f2ac00e91b32e4e7aab452249d31575bc96c8652ca8e4c3c0d3277a60f5ca7beb80b563391a3b8e1a1a97c85823928877954c28d052a2c116bdc325b687d26d1ccb3386cac9bd4c10c3ac381e056f9060c89e25a910c78e677964d153b74554c8f38939f881543f820b6f11989589302eac53111a45f7664616999d7a64aa26e4cd74539dd496a1f0fc530415b16faa4ac86341c5400cb1bbcffd2707be12c31acc9b5c94b806b71dafab1eaaa087efc1419cd2978ec1b973336d27b69af2fa85f6c33b73770c0f6b85d855938ed8758e6aa5724b8c0d457b29a9394a3528de99cbd7a875bb5b299c8a6dfe416104a59aa9e958e3828d3c651b5a9a7e81d7738374692033c4c68254d5170204f83a9b8520016466fd9189efbacaa23ab8f962af7d66aec2e27e468b9c326711673839541262a9c823efc5c946dab44b5b2068d61f00e7b0d87ca67706343927bfe4c12d20d69c4a5ba892f97eeeab7b5a45742cc4ac4d37219ad72ac312051d31b8385ca2293415a13bb8983b8457b8af9dcca9e6322094ca68399ab77dbb9f6aa7ced5f224641c3fa07507da9a08e0d180d52585dfb3b2fc95cdc733a573a888d403cbbb71c120baae2a195278370bf33299b9b2684accc5288a3cba1277fd3999839a6ed29bb91d71a528bb2e4f953778ba23341cba4b9b3c17f9a8366212af3b722397419e24874b163470b3b2b7f24ae62258983b6161c6773b5ac90969c03d01cf4669b9d1f46e05705d4f676d464264d7549e1e2c3290c9b2bf5a71132057531714bedbc7a91bc0ad56254d298908d33d588951333b3cb7924abf14b0d70652c45aa62cc3062d851e45c866c6200df4e74a9e559b9e6ab738f2b0da9693ccec3d968a866f0220ca95b7c6e8b04ec41d39c17eafab77444aad4ca3a9d6b5b5d4611a6c074fdfb01f7df68ad2440efc5588f3b4a5c4106efa3b9b6bb35c327465c7b656d1c1c6409993fd91cc20172e53190dad63ce02691ac326904cbb6424c906bd091312c1bfe6969ba6aabef954b5c8d439da5064a248c92988961fd2254479946dec829c76cba61690e3c541648228b59805d7fb2adb6aaba70718985279452a2fb1414e4704ac3dc84d3eb767101c8f4feb24bc8148316609bf963afa826a9b87638424052067ce8fb393d9ac579ab1080d1c549fd5103312a1ff9988dfe7805ed906fe9228e25942d49484a4510e0ff9a4a54a22cba6be945126ebe461c5940a74e1517c60603b2651e8371973da7051eb7197713f5583ba51b92a9eb3179b45a8a8a5099b40c29f59146f25a563291364f236038c79b784bf09524fc6810f91b777bae252e5b723e8059c06157653e335549784a15553ff9a7a29407d87725aa6b7a2a2669cc776bb810672967cb5b8b9a9ba751a9e69a8ddf796b1f324348712ff0c23f49a1debf210c027995b8a7cc5b288c4c74218e5086112237128cc57f4bfeddc21ed23bad00c58d835b5a3f0c8fdf1001e0ab26c2cad47d5caf2252cafd3520e36ae21119e56fb456f277132059ca18623bfd994878c794545ba4a04436d804231f430b12808fb01647fa15d94b975bb6798ab7c3f6355b9bd50bc1ca00ee76342c8609be0bc893deb398b65a453ba08bef83b805b61945229d98422f59c27e86022da5620d737867828540c20b097076bc6c03e5435aee1b9af19958a7dfb921da414280429da389eefe23fc9578b714b4f2e5b19b792903ff45aca045bec0b3d83c204747a2e24971b440c10119941d9316f45a87c4ab2ac0f7c4bde9bc8ef73a7f42513be3420c56720ddb984cb173587462aed9996d2a848d11344eac02351e6c5a18cc7ae813bfdc50d5b143f4d07ac72a213a0577f9802043a585d95031d017b319358a24b06b7c2ea19f22b6634146cc0a123a8051c51e6ad6a956b1a935ffe00bc65c44a60534d1375570bc036edfbce66255f523bb377b2256c29b870da2c870868299828f6fbbd8e0a109386b8d743a6e7a38384d5933e64565a037b9f520ecf8466f2073eeaf03d1b606f947ca2d2ca49e4b41de9011ffbd23920c0d2d0cb20e3a9c63bff3e047504a8965639e8fd0db690ffa1e791fdd1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f + +comment = Official test vector 29, seed: "265eb2de7099e4bd5614e5de7f0c2a05c78ef3e8e2dd4ae4cb70f3e5e59c8d1d88248303f07de0c5508652da66b47222" +entropy = 174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed +expected_public_key = e71b4ff986bee57636f904c856ac93e0c18775864b7b932af200251b0328f5b3caa38116c5a187305622b4a152ca337ed7a3690c31161862447b847f5639c5851133f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c9582407a0e59a866991564ca55b21a48ee530676a435d26b749c1264f9e58c3fc619d1a23ef5f6300e96665eab70e7350852115f5859bbf1a8308977648ae5cf5a55c9fb42801aca4f0592254461a632a94a9c3a7ccd05c8b7c3b09666be54f072cdc58d8cba687d609d1f021115085c340153ce63a37750acbda01a6944a46cd16cad098464a109bbb611a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534eb80a620c308dd779b074c11f31679ae98ae569bbe79cb04bb127208e24ba008bea28c5db5ec18f31c50712171e27042651701c3004e057a6865d54763843d27873220c174c57154c9a9705da162e8685a035b34e15c411fd1b7220c57265c2ba7579f4bd9ab1461650e8027c0ba79f2ba3f14093cab6015d8cc092905a6b8f09dbfd5743818489ada2bedf88ce592396074a79824457f7caefe334fc84869ff43641821ad60e80407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac382222c193bddb31275b84374cb4679a5ffd803eff07987ed085fbd43e45752dd9a32f5ec03e7b74567ed9674e1070b026801e99ca27ebc0ed24742530507e19b97a09877a1b511da3b9835268ac35ae44187ea14b996dd96c35686eb98a81f1b2ad90a80d0c989b12813e7df2b34573b876289e7c79481c7247e637a60f9b2d3fc129c379a759756408636048565cbeb24c2186a875606a43d20bddd8b9d70781b1848be54a075fe978a3e112a567223d21beb3395921d1a100c578e7ea0455949b7b420b6494688aeac00697ae1914084eab375d86243b50a948874dc973b7670c8f9173228b64647e58761442a2cc90165b188b58025f8eba65cc654575a1bb3823a1a29633aaea1763f24486aacafd611c28774c98d89b3ce8a696e29f62775b5d5c50847c3ad4bb968c441086aa070097508da888b5b202e5a3b5db579943f0861a5b6e2d58415019182262c444fabb77679e019cced4e0a3854507fcd0935bf81b0e8500dc6c0b3c154ecba94d166407c5dcc67bfa6aea8b4ef0c53859ba4416d5c1975c1feb6bcad8076e6b020a62b077f0141deb5ab5986b386d51cb7e8c779654af5e5485a969467012c572f62daf788d1f58bf9ddb4bc6e04b00218cb671ce8b2515b072b76cf253a4006ac5437c107a077f162a3984586978ceb3752b1fa1a2b525961f96c63d7207ecc4c0268a354afb00231b1cb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a53730405c92130f756050771999e469cf07cc8c308ece9b827d7558bf882630556150a602d9400e3d4abb229a9d8b8132a7f0c0c5475bb852000b63228c490472b42488aac0ed647b1e834f248534fe2195adf6952b83b6705593a1e53f0315613d2596aad44e27a26d632b9c71e9c9e5a6ab733c7e81e54db3437d894a19b4710a3cd5075602b176ec369f5116638775574c74425789154b0bde48bad6e52c91c451c87b48ec406674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d219 +expected_private_key = 25933617206ae881c4de291b4f269f2e51897ff29d3c6803e1a4c58e53051e879f1af333393c75b366cfe2e84cf9cc930d1928298897480571d7050751601bc119b1071412efe8873ad325bc00420d13a752d33087bb6f884628def98f4fd21d01113219203f93419875c91cd33c7976b7a45f510f70e6002957ac49b862cd35640ce84e6b989201a74eb76422f88b31c94acfa811605a32634199be1639a50b709e89683c5cb0c975d627b76223ea48a2352c8bcc254abc60812a6a5ab7747ca82073d1d31fef708866a9801ad067a6da0d848c409861c350db559a0ab1d91c9be0c149d6c241a13849d9eb2da4b9b9b30b348217491449a43ea4544467824ff954c4869c8dc0b2ba2744c8d38ba584cb78ea6f6188bcd090267ba46882f16964aa003e2c60105415f937cf13b9cd00456d3545bc5e48b6ddf61a14eccbac23bb1d071bb14361b4c9acb7b48805b7890c3676b550238391b388260cb0e2567f725b0382c7174440d82ba8a6d226d325cdd1c26abd510abb195b73d203f9db7db44abba87581a3c57f079b44a9455e3fa16ec87a0cc14368569b35517272220ba7760a8a0508bf0033031d42763fe89b611366b8b93d2d523d5c872bb99bbb099515a5911f1182404b7b4ccea91462c6a5abc16c64f55ab38a763a03ba48e0268819b6df8ba88704ab4c7bcd8f8a150ca434ab0632adc522a49c0e45997375d69901416792f845fcbc1a18789b22870401d6872374b15c851aba4c3cf5a8930d34c74fd444a2c87f90d9353cd77361e26c99c8027b50504bc5b3f2bc27f3978822113e13d71e19e3915a9a4f0646aef6d513e155b41237b2ab08bdf38322bf4c00706c0f22854d080bb8ecf58cc9b75d19a0185412a74b3c7d61a04dd8cb07bb37156c46221a7183beb9321c58a924048ab86032f54815da1bb33ad4312391c1a6778d9070b1a4542aae231aac97bb5e1a1cf42792c9921313c07aba3a8c15db5d1be417c3888a2e0921a7aa1926044ab865935a2738b4378484b44471da250e41925e976beeca9f93d191b0c85b487badfcec4be7c7683c508412e096ae888bafb97cebd3266ef7397004cc56741f53683034fc3160522e6bdabad190c51f31926aa94b2f2a4506d69705623e3047176b46169ab8a715b84848bb4fb9830be744cad7591dd8d128c1a40f8a5b2829a92177d73cb1f319c0f45557a69ad790c87a6b8314e618444081c221c07c4ba5c1c450b8080db278770a0c110dc386fb8411d4b983503964f7b6afa10ac5154ccea9e6222b4a70e5175f125b0a83010474311f8ef84fdf3aab6d508b313a93c29675abe12cde50bd4b5b7e13c7228d9ac9df569cc1bbc995eaacbc2290b0293a2bba70ae8757c5a7ce84386093e02b3201573c56bcc368a7dd404371453c38823ba4752edb663e5fb99c5e91ca9ba94caebc9d60a6318cf62168a86c0c419cad1bc4fe514a745bb2c81701b89ba371cc1f10b50d95086d99778383108dfed849a1f74696464aa1d67f7f40bbc69c1fd907696d6227cf20750d68a3d36c600448c91a523a16e5c84b40819bbb2bfabb2cb03b658fd0656f410752f52bfc9bba4a3a8d09d5835b1540f5dc673df71540f560e71b4ff986bee57636f904c856ac93e0c18775864b7b932af200251b0328f5b3caa38116c5a187305622b4a152ca337ed7a3690c31161862447b847f5639c5851133f627b5980572023b4acc37c32f6b70b3555e0ec4c5809c9582407a0e59a866991564ca55b21a48ee530676a435d26b749c1264f9e58c3fc619d1a23ef5f6300e96665eab70e7350852115f5859bbf1a8308977648ae5cf5a55c9fb42801aca4f0592254461a632a94a9c3a7ccd05c8b7c3b09666be54f072cdc58d8cba687d609d1f021115085c340153ce63a37750acbda01a6944a46cd16cad098464a109bbb611a83346ce6b59a5f4ca3cbb4394daca06e5708459cc777534eb80a620c308dd779b074c11f31679ae98ae569bbe79cb04bb127208e24ba008bea28c5db5ec18f31c50712171e27042651701c3004e057a6865d54763843d27873220c174c57154c9a9705da162e8685a035b34e15c411fd1b7220c57265c2ba7579f4bd9ab1461650e8027c0ba79f2ba3f14093cab6015d8cc092905a6b8f09dbfd5743818489ada2bedf88ce592396074a79824457f7caefe334fc84869ff43641821ad60e80407649edaa8bdc2fa877eccaccaab8a1f35a1573546ac382222c193bddb31275b84374cb4679a5ffd803eff07987ed085fbd43e45752dd9a32f5ec03e7b74567ed9674e1070b026801e99ca27ebc0ed24742530507e19b97a09877a1b511da3b9835268ac35ae44187ea14b996dd96c35686eb98a81f1b2ad90a80d0c989b12813e7df2b34573b876289e7c79481c7247e637a60f9b2d3fc129c379a759756408636048565cbeb24c2186a875606a43d20bddd8b9d70781b1848be54a075fe978a3e112a567223d21beb3395921d1a100c578e7ea0455949b7b420b6494688aeac00697ae1914084eab375d86243b50a948874dc973b7670c8f9173228b64647e58761442a2cc90165b188b58025f8eba65cc654575a1bb3823a1a29633aaea1763f24486aacafd611c28774c98d89b3ce8a696e29f62775b5d5c50847c3ad4bb968c441086aa070097508da888b5b202e5a3b5db579943f0861a5b6e2d58415019182262c444fabb77679e019cced4e0a3854507fcd0935bf81b0e8500dc6c0b3c154ecba94d166407c5dcc67bfa6aea8b4ef0c53859ba4416d5c1975c1feb6bcad8076e6b020a62b077f0141deb5ab5986b386d51cb7e8c779654af5e5485a969467012c572f62daf788d1f58bf9ddb4bc6e04b00218cb671ce8b2515b072b76cf253a4006ac5437c107a077f162a3984586978ceb3752b1fa1a2b525961f96c63d7207ecc4c0268a354afb00231b1cb6eb4e4a694524448e7a043c22a5bc1094b23d3c5d0a9641f909a778eb64bab84feec3a53730405c92130f756050771999e469cf07cc8c308ece9b827d7558bf882630556150a602d9400e3d4abb229a9d8b8132a7f0c0c5475bb852000b63228c490472b42488aac0ed647b1e834f248534fe2195adf6952b83b6705593a1e53f0315613d2596aad44e27a26d632b9c71e9c9e5a6ab733c7e81e54db3437d894a19b4710a3cd5075602b176ec369f5116638775574c74425789154b0bde48bad6e52c91c451c87b48ec406674a75b0cd39d1173c3f411ad1efdd8bf4be2afea69c2327bd070cd1432c8d2191b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c50950a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed + +comment = Official test vector 30, seed: "806bbd111f27c2668318387bd0830f65ec21a51af01985ef48d03d64e1958ff7ee5133a4ebf6dbf36329bcaaf65f40ea" +entropy = 351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda +expected_public_key = 8518c8d8dbab01f270c3131ac1586bb783b35db82f3c24ae2b767e2c4a7d15c2a86eb19fdfc41113a7501367cd70d73d0f63705487ac4e0bb1c84001fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b52f1cac91b6c36f37a59780e454c50c5dc354b56a43040804de2394bea14c2d385e082c5f181228d62307f5a6a1aaa1eabb84f90f34310844df95a4e6d423d8c993fa7f390e6984e482024c2968254b54b7d3418d6f859e295665262246e1bc8cd6c9b726581cee69140f85c02024c5b59aa0711813d66433aa384b2a4a3447939378a1e6a98936bf04ad075981d93c53e9635b5e285f96755f8689b5ce5429142af6fa02edeb1a719b272f6b0a6211a5b9807ce6ff368739b51d4d9480bd884c8b456569027b08a3cb928645d450c6264c5fce2a2de2b241f965034a08716649a3c71020a6986fbc8bfb5b4a2cb162749264cc1e44bd66223f3db1b9bd2c68744b52ed7bba0b9773df128883110d2cc4757dacaf7f4c90fe02884e1a581d89af687ac79444c9d801d156325590a3a24441b7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d222a5d36b86ea2aa2006c54940a5f843ab708d19d5937643309c12d522dd479c3b2d57dd5696d25615abbb573fdb62eee5c6a6546cb1fb188f356800ff4177c69b636cbbf9ee9a7c7d512ca156490c96b347a5bc2cb257a061452dab5fd15bdf5026677f14967b6c825d03eb782cd0422bd1078b7781624dc318a33b0c437d6c35997a22e30496e876762ba5dcf5146c5188dde6c684c265a8f05031904572f7554123832c78767ff4b5ff525680c773ab3ba1a93776897d57b0d507b9391712344326f090b3d964df8c293b6638fa36815c7cb9b7962956f903f62c4ce3d7646ebc1a8ec04a815191cb4bb085ec8693f2188f490731c087c23a8bc7cfb32fc019d106934b2d17706526cc6f787be424bce5b26329591c47402d57548110ccb42955c422323addb4987fb0f3441558964bf14021a54277ba14c5773a10b81c1427f51173f5c6cbe1b7575a4b6766ac355bc443e479a2953a51f7010f7b04b23e0ca93d08836432e3ae5a1a6bb62f5476c07914f88532cecd00ceb340588ab675f93c286e7288da1c6ca3621ad6a4ae1fc64aa15b27a7c3eabc120e7460737585b5773ab18e23ee185c900ecc3b765983cb807e2f7047e6c999c6716e26801ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d172db81947643a84fd2173fcb0477ab87b57b55899a308d51311c9ba6916f15947d707d88b9228d0488ddaccb25455cf782b7a18264e55c9b6798f39a53f53240c82fbaf461364cd5202c5c94cdff23e0f731624e69310e5b47964b2bfd3a59a5b0d55a026e260731de346f74938abc607b4f579b8b200ecebb633614a46983e60e442a4914c93fa62219025e4a99d71032f0b00906126365c467e0a235570a544a7640f23800cd5f2a825479a632343f20801f1774f0e8b7db96a860fd40a43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444bfe219452c464eeb2914ec19031152cacaa00dd541fde81ecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb +expected_private_key = 719950ed1960ff6c2d7d59bbecb83aabe1ccb569b76cd9b053389c552cb6bf847cf4fc1f18a03e66f02cdb284c15d656151644f78caeeafa8b12cb7c616256c032ce6112735a74285d66a90f3a745ed8733c195f6b1b9b272897520a02fafcb958a9669990b73420bcce373acf5a1c86a555c3c48f78166c0fbb023c49608592261060884b408c9fdb1f4b023506d3516956b02637af26fc7b1d9345f8b54b5af96997d39fa32c01ab64a6ab7491d50303b4e8a134086110d220462395b9d89d9651205aea9e1b88bc80c4c8bac44af4f1886ea788a0b259dda78116051059853d2cd073ed8cadad9ab04f7175d57c3224e953509588e788713d5a6714d0aa48e972f4fa55f16579d9bc6988f562ccf1286e87aa785929bf8266d7e340022c0221736c3cb372b85723042382092545a45032eb727bdc750449c786145acf42b85d4618b0d6f009d0224a816620f1db67f59713090b0849559a51b9589532ce2dc25df8f09aebda932073a2ac2115b12c5f94c64750220d645b34c14ac1b2208565377d61426d7f2a25cbd969a2705ea330b676ea6eefcbbc6cd40da9c0716d147b398b7d469a919d83baacca80f0e41414382804b0a321362e14e766db2450f599963cc2899e1048d839754858910d12c23f99158a9a3149362690a9c5540133e5f217a7b66b0d627321c810f7d1639cca948d708616047f85ba41cee9211df72731ac0986d1c3149854b71683faf68179799b12c031a2a84574b9a67c96a708355f7a86bfabe63ddb94b6c048359481ca7a45cbaecbcf34407d8e378733f812926599df5c156a94945fc7911db26bef17074470a7bd6b60f771cc3f396e847195ce26444b641f91b468fa1670d0184942472667aa76e42976fac48e78da72ef0c207fc7400f92699b46345e4c9972a35daea31adbe87980438de4f211b005c8dcec1a6eecb56d891677f9006c49385e8ab20a19b74325a9a95083bc711537480db30719815352616b2c5721979bd4267fb134188a75b9cb303215a76a246d8f69acbd173d069b2b99b727829aa5469a0212c006a88aa4a6b614674674fa75500aa294711c178b741b0275280bda27813647a5dcac3a258991db4bf436c23f37c697115143a2755fdc199ff32b19209d7ff904feaabff7383884c1bae3c0cc20d019066653b99c1cafe366567c9238785b0f0b4d1432a9e02ca2d9a3b37d84646b157684d7ac720727af4533749a9ff99bad8f3877dbe5cff9c75b38c4002178ce30773ee36a14f1497ab386cb36420f04d85c8312ce25b357d3108226925f6b85c7a3729064f81aa66336163c00506bbfc82030f4f33a5be7330926bb3f849d1dcb09f5cb814ba8a722506d0a037e6eb26216aa3c4d4c05d5cbcf0358501936ad2beb3563c341e2315de6d68404acab0149bafa84491ab67a2dd82972220b0df528da7c4d441c8cdaf508cfa2c0224932e7e5215572aa433c9212022899e43a93cc7c8f4aac6ed5acbd0162e4da4b897b7bdcd72a0b2a2354f61a6c211089c11e476715f3369859c3021584b6593b5784344d53b40da0725a90804c45d02f6eb7670071660478c53281b5e290bfc77ac46602b530b1300628a7a4f20ce227688518c8d8dbab01f270c3131ac1586bb783b35db82f3c24ae2b767e2c4a7d15c2a86eb19fdfc41113a7501367cd70d73d0f63705487ac4e0bb1c84001fe6657610c7d64fa3df4538bb6069128c4597ec9b291938ea5d7cd46897ac2179b52f1cac91b6c36f37a59780e454c50c5dc354b56a43040804de2394bea14c2d385e082c5f181228d62307f5a6a1aaa1eabb84f90f34310844df95a4e6d423d8c993fa7f390e6984e482024c2968254b54b7d3418d6f859e295665262246e1bc8cd6c9b726581cee69140f85c02024c5b59aa0711813d66433aa384b2a4a3447939378a1e6a98936bf04ad075981d93c53e9635b5e285f96755f8689b5ce5429142af6fa02edeb1a719b272f6b0a6211a5b9807ce6ff368739b51d4d9480bd884c8b456569027b08a3cb928645d450c6264c5fce2a2de2b241f965034a08716649a3c71020a6986fbc8bfb5b4a2cb162749264cc1e44bd66223f3db1b9bd2c68744b52ed7bba0b9773df128883110d2cc4757dacaf7f4c90fe02884e1a581d89af687ac79444c9d801d156325590a3a24441b7c2c893b777386198c16374329e640b6a439fe5bc71ab3ae195575a71cbab773ae6f0b5ab2d750d222a5d36b86ea2aa2006c54940a5f843ab708d19d5937643309c12d522dd479c3b2d57dd5696d25615abbb573fdb62eee5c6a6546cb1fb188f356800ff4177c69b636cbbf9ee9a7c7d512ca156490c96b347a5bc2cb257a061452dab5fd15bdf5026677f14967b6c825d03eb782cd0422bd1078b7781624dc318a33b0c437d6c35997a22e30496e876762ba5dcf5146c5188dde6c684c265a8f05031904572f7554123832c78767ff4b5ff525680c773ab3ba1a93776897d57b0d507b9391712344326f090b3d964df8c293b6638fa36815c7cb9b7962956f903f62c4ce3d7646ebc1a8ec04a815191cb4bb085ec8693f2188f490731c087c23a8bc7cfb32fc019d106934b2d17706526cc6f787be424bce5b26329591c47402d57548110ccb42955c422323addb4987fb0f3441558964bf14021a54277ba14c5773a10b81c1427f51173f5c6cbe1b7575a4b6766ac355bc443e479a2953a51f7010f7b04b23e0ca93d08836432e3ae5a1a6bb62f5476c07914f88532cecd00ceb340588ab675f93c286e7288da1c6ca3621ad6a4ae1fc64aa15b27a7c3eabc120e7460737585b5773ab18e23ee185c900ecc3b765983cb807e2f7047e6c999c6716e26801ea938302abc312aa797535358196b63309846675bcf1b33343bc3d4d172db81947643a84fd2173fcb0477ab87b57b55899a308d51311c9ba6916f15947d707d88b9228d0488ddaccb25455cf782b7a18264e55c9b6798f39a53f53240c82fbaf461364cd5202c5c94cdff23e0f731624e69310e5b47964b2bfd3a59a5b0d55a026e260731de346f74938abc607b4f579b8b200ecebb633614a46983e60e442a4914c93fa62219025e4a99d71032f0b00906126365c467e0a235570a544a7640f23800cd5f2a825479a632343f20801f1774f0e8b7db96a860fd40a43cb7abae76039c6bc80b94ec315ad49e9904908a20cb444bfe219452c464eeb2914ec19031152cacaa00dd541fde81ecaf1f339e468be45459e708bfb464d0c480a1becdbc021a06af7aac4772545eb2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda + +comment = Official test vector 31, seed: "ad540a9ce816d6fb1661e5483c44f6fdd00c9e7bd1a8ceda4b4c4d3697d4f78ed0a56954996ccb7da96ecb8f5cb15809" +entropy = 9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad +expected_public_key = 5e55633267468551b3ee117792c80c1a802230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab5f11602e977ed051115508668c244a44e09569a13507d4009ab72b16cc3bc615c12ada7c56d50ba6307d00801bedf8526f0a9366869a4830314d162f63ab8f51996663c1138641275e164ddf60c7708a75376bc235e16d5c22033de1a149153d1868679e1825f638967becab5b9644a6e201906771a703b7844cb5cab61748d202d38b5b8f03cc45626027895e23d0c1c1b526c6d519620436ed593b58732164a39639c813f6032eb902b05db15c5d8825c8b11815768d29522536698a751bc1f9964dc579358adc57eb83a0d2201b9b9354b1b39c6e7008d5f3189902964973af9a9c694eec1298d68d3372783d34700b0280d692998b49a9bb76293d7a95363b317670352a71822f415b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b3905df7f58c6566621eeb25dda29d97b598970684c5780f665243feb854f9f566177200f9331ce353cd1a23cce8aa4529bb667d1b9e59b1a312a7c6ff08871cd95c6934419f475c1c08395ce1a3aff83dd14784303b4ba7751054aa59f5710e4ac6039f3168c1b601a5278562b525abb11e66193dc9d34446bbcc8163578cb8065f89b9f43407f79246cad2b6b8b40f16b839a060a95b76855237bab2fa315db48e40842f8306125fb04145356bc50b00e3389dcca26ff048af5a730ac573b5b80331d2597c4188227682075bc0000186b8fd26a383e1bce5c19f13b18cb21602f2160dab202bb07b63d925b71708095daa662cf25dcbecc99395400a79842f5c40e79b46b5384ce730439f537bbc8a8608f61520e120ea9843456118a0a4cf36384832b12076044c65f06c8f8cc31752469c8a1e33dc529ac05485548a6e075f46a089aa8446c0d465bd43cdf0343acc9668fba2a7f7191a9d29be7e9300cef33d13a11edb2b409de297f30b8a7b077fd4ca4d1ac74b31092aded0503ccb5818d1834a734e15b74d3fe550ee49773a800d86f129b4e0250ea1c43da3a3b802b0757c6401ea090f98a28291621341a9d98c67bb001e46e89973f40c1c4950b0e34f07772ba6379fb6a93ecb57369b48b3aca26ef815c615b4a97ac2190fd2b15e83aa10545fb859635d084a57b0268ff085d9ea4b7ee1763b914e67b33dc46037f39815a1f8c58663c88662b91bab0db6758288c682372a269c64cf3ab5c46de2c8f0f1b7780a068948b9480c6af10251453c1fe213855d74675cacc7b162917730ae74ec7a8e7673a7d0887edc175791309ab28e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a2a1c2456a108a5cb4de1b15356ca737369668b0b5c7bc10e22377d6b5fef7515b4f348015872e3518c2676079b8a06de8b53bd189ec9766c04c084e74c6e747c783ff3a99b930547a72fc3a179cbd62b52d46207e79e37d65c9f3c4839d1afc167ae4041671e2c1bf3324d875b78615067dfe11653e6bd4dd5414579ad8c942081db4f1a10b0e1054fa3d79af6a285f2107d4232700676b8a007057d15c923a7889f115762b4c242392ce7c4438c68c6c3fbcccae4a071e404c24274f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bdd +expected_private_key = 4da026f053c3ec1712c7f294dc891e26196894a1b620f97429574edee9568e113feb564d89a1883d5a0329929ca57ac001925c8d616791842dcd291627d61c7c2c3f842b547f074f46f082a06bb4282323a291c3cc07904079125cd5a854168d83ba8ab6b160b5e1881d25403b297c73048e3298287f51529a8ba2deda6b4d7665a373171b03b1c0baab6482c50ca3a028d485ca8491b1b73767ec9ef8874a54d4ca414895d2e49fb2ac0cc80c9d248b97ddc51d00a10ca3324fa8a6373a99c5dc1bb7a389cd9a3c6931fc7bee05abcba579251b742f46383afb48faa514319b8f9a0491f9212da443acf9b9ce5b29a6e723a4eafba5c1a7b3e017870fb35dba8a69f1f7995ef2aff817907de5c66899824889a760ca4a38a57b3afa880a3524e138b37487b2ee7332d2689f99a5a3748020fbca43ed6045a5aba65f6c67783cb74c217ba987ad381938b4a651b6908fa4f18e6d073a6992160438ba3c9547e4557e1e724192414c912648d25907bd8b069c845465616969161c483927f5d610c815638e242323465839d36a8149bad494b71f1336a3f0a954369d4265b6cab935f06694c482b500cb77bb32c4d805a295a692648a31611b206d06c2e86c61675577053a747bd3a748f452b480028edcbeca8a10eb843ea8a71e21e9b822d80860764d8c5a77ef0222f8004c902c832f1a344758776eeb99c3ec8b24ccbc03f5bcbe59027fb424e6c580cc3b41c041984ea552bdd6396d52867887430a2534a44ba544a0b285c061d7d6618c76945a5c3b29bbbb09a724b1ac53e5954f66708c8c0b2d7da57c62fc8b80e73d737741f9141f7164b4eac08822a4c340b5b74cb5c2d407b9d63365c55c14c5e6ab43a8bc68908c34074a9bf4816e000ddb464656c379fdd829b6961c22e5345674243ca64705212d52e616664587f90947feeb4366a7aba98b76d9f79a1ecc4bf50571a07cc57e0cb1af828bb26263a8a898bf3b7b0ed07988e82dbe3c0405d46b1cdc37600570fc37ad9b2237e3032bab1a0ae420b6f011a653987305aacc8876ac4d014b7e619227b8b35ba2616c9575506870fad2585549a2f902b185d7a61139c027912ee2a00ee460328b16cceeb259149a0881f8152d563bc0243302d29fb98cc57a45369517640bf0bf63a555a900269878c4ba567f8d376176d6941d34957e1373b7520483394c3606089d14aee0917059227bd848bb22e088def4194bfcb36eaa81d4da713e37be79e52f51ba2c32f05d06405947838625e49f5f6bcda5e683d014a12fcc0c81601b52f80c39b6659606a8fea82c62e061a939cb4451869922083268561e16381b026152170104e11f30b2399f4097b94078adc66f23f85ba6651e861237700bcb1ae92e2bc652cbf19bc0fca0d7f7577c9c96dbc9b8b07b917f258c15661da17621db1287ebaa7714a54052fa660f034f227198ea14c2467b46cf9877f4e0c29962992b560a7db93c8ec13343f734d86bc548246a57473d1285463d0942f288245d933ddab7a09766a9f8c178ef539f9ce9a0e97364cac0366b5b08b4c1b081e01d198c2aa5288617a50019eb3a40a300af538119d733f2544d18b9094f387a3f4c17baf01523f1455e55633267468551b3ee117792c80c1a802230ac805f769807976c06399b97b3c93fb83bdc136cb3cba70bb4ab5f11602e977ed051115508668c244a44e09569a13507d4009ab72b16cc3bc615c12ada7c56d50ba6307d00801bedf8526f0a9366869a4830314d162f63ab8f51996663c1138641275e164ddf60c7708a75376bc235e16d5c22033de1a149153d1868679e1825f638967becab5b9644a6e201906771a703b7844cb5cab61748d202d38b5b8f03cc45626027895e23d0c1c1b526c6d519620436ed593b58732164a39639c813f6032eb902b05db15c5d8825c8b11815768d29522536698a751bc1f9964dc579358adc57eb83a0d2201b9b9354b1b39c6e7008d5f3189902964973af9a9c694eec1298d68d3372783d34700b0280d692998b49a9bb76293d7a95363b317670352a71822f415b1c97742934713c5995fe5ca9642c3ac18b73c43357d4d497b3905df7f58c6566621eeb25dda29d97b598970684c5780f665243feb854f9f566177200f9331ce353cd1a23cce8aa4529bb667d1b9e59b1a312a7c6ff08871cd95c6934419f475c1c08395ce1a3aff83dd14784303b4ba7751054aa59f5710e4ac6039f3168c1b601a5278562b525abb11e66193dc9d34446bbcc8163578cb8065f89b9f43407f79246cad2b6b8b40f16b839a060a95b76855237bab2fa315db48e40842f8306125fb04145356bc50b00e3389dcca26ff048af5a730ac573b5b80331d2597c4188227682075bc0000186b8fd26a383e1bce5c19f13b18cb21602f2160dab202bb07b63d925b71708095daa662cf25dcbecc99395400a79842f5c40e79b46b5384ce730439f537bbc8a8608f61520e120ea9843456118a0a4cf36384832b12076044c65f06c8f8cc31752469c8a1e33dc529ac05485548a6e075f46a089aa8446c0d465bd43cdf0343acc9668fba2a7f7191a9d29be7e9300cef33d13a11edb2b409de297f30b8a7b077fd4ca4d1ac74b31092aded0503ccb5818d1834a734e15b74d3fe550ee49773a800d86f129b4e0250ea1c43da3a3b802b0757c6401ea090f98a28291621341a9d98c67bb001e46e89973f40c1c4950b0e34f07772ba6379fb6a93ecb57369b48b3aca26ef815c615b4a97ac2190fd2b15e83aa10545fb859635d084a57b0268ff085d9ea4b7ee1763b914e67b33dc46037f39815a1f8c58663c88662b91bab0db6758288c682372a269c64cf3ab5c46de2c8f0f1b7780a068948b9480c6af10251453c1fe213855d74675cacc7b162917730ae74ec7a8e7673a7d0887edc175791309ab28e6ccc629bf79c6d69b19269a19488b7b88a45a199841916ba4a2a1c2456a108a5cb4de1b15356ca737369668b0b5c7bc10e22377d6b5fef7515b4f348015872e3518c2676079b8a06de8b53bd189ec9766c04c084e74c6e747c783ff3a99b930547a72fc3a179cbd62b52d46207e79e37d65c9f3c4839d1afc167ae4041671e2c1bf3324d875b78615067dfe11653e6bd4dd5414579ad8c942081db4f1a10b0e1054fa3d79af6a285f2107d4232700676b8a007057d15c923a7889f115762b4c242392ce7c4438c68c6c3fbcccae4a071e404c24274f5066deaf5359eb3382eda6d6338f166acd09e376826299b77b781250c2224486ef23d424bddbdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a75a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad + +comment = Official test vector 32, seed: "288a5f2684d862a86d2790afddddbac6fda934ee7d2e6da1508bb550838609e8107312b28e00a6c01706374ccd3aefa7" +entropy = d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a +expected_public_key = 420a3005a17c7b4a08178b83f8540601145b102970b3fc29f30a4ca1a8a5bc4164051931ed68a59efb2b50d549bdc1a65e9909f5aa690b0235d32b1c6b2886ce2959fa189e2ce24224e99255863e6d964d4f422c02646a461bb5abf86f4b4c0975765a5b0ca01081677334af26c3467da771cdf40ec4293608801cad9c61d5f80839774eaff772b139051beaa65632120f00171ad020276a1fbf23517582149ad2c73450b11315ca4b244e7218800350aeb5808da774030635bc247508144740634ac4a078a5af2816e9206a645287de06263277242dba12af2a82ce13ba6787c5ac3020e5d30cbb92452985ae41027056f492bb1a5e23332698240b5038302e552c5acc0443a8795804126e15369ae96cebd7c9765233982458ad6520550baad77bc74296badcd4cc37240d0163caf8c806a0ccc3f4125a0874cdc1c67e4626c9c753453fa37b208caf5f523388d6308248b7688c80f6c925895670a1397880933af0152da1e54f7a7b512aa87499f7a718e62a7cc5bf5687add09060426b0d3cd292ab9b8372083ee462182872815cd740fd69acdd24615110bb618ca1ef662715f028864ba0872b8c199abe40f35f91906a821b8ce0742f931c661c65aa2445371a300e68f23b767382f3701ce685cea5f59c50e82e45234169c3bbac814ab9d68f83842c513a8faf475590b3bac2e3a4685b8f71208357d221ae41310e8454d315670c3a3409a2a95258b9057b42def7a7c6f588f6da61183acfb18a7cedf138c7984b50a940f17c687e5a2f83451d94398f4c82c93a375be195b4b219232e9a766e77040d3b9125e70fa4097d807a6d25323342508f2490a59702575d64af146088f59802aa2cab3537a8b4e92a10ec447bd89f9fe738d92a5f83c2861628601e42bb427b87c2153d4bc44b19413b79baa5ef55325ba8a42e1a88548155d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526df1adbea64930b6995f60181544356c0982e957c5e5186f321b9467d05dd5970a96e226c89673e50a056e7c0a8027aca8a5cd93723353ca1991730dfea1aee943cb0d62537cb5ad88c14f52a78cb6228ef4750eb7db0aa831a4202b178ef47446a06a17e7caf5274f384b36832a07ae0a66069bc59fe439f7b6005f064d865b550505210768bd636c61f0e7a1bdcb3c3065908d51302ee234a3fa113a1a1a2a618750075a6ec277cbdac535fc1524a62e3c0601aad1c46026ab6b8495c1b7093f776f9e6b3b533267ab99801e83bd18570166387f14ecb4d279b86cfbbaf90649e5c514e432561f850497d47c2bda1bc2c398b306751991392c399df6f408ff836f989c41cf76234b9445d9f81f4aaa987c1721c0c726efe44c311a589abb5e0afbc4add9bff6f87597a52e16a53d6c3551b7e6be0a1958a89a739e0717f0a86be0385c5ca433b68ab9506ba3a6e00debeb1ad0519e228b5b2d9aa3c9b4a2bfc8b35bf0a04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996109113446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f1f30d0cd1c40d14b09429215e0c5325bb2b069b85c9e0bd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad +expected_private_key = 1f83902bbb77a97b032277079cd0ca70d09d57385ce5c1b3c08b80ed95b2bbe70c101cc1912b71b29b87dd08254b593d616a31ff4957c7c0c325f82024f6a7b125b0ff799fff47afa6a9a7055382bca08cbfba71ea1b530bda5a4548922c90c6de8927494370efa6c96780086bf585ae6534dc05344dc1941ef793eae214312a371ecccea680c1a166ba97e128064748269922c9a19cee4b8a669abd146491abe31a57b724f3a173740269a33309f651c934e09a564627896150addb8ba181cf2503256512b0dd5588f4372781f35cfc0328c0dac842a1b3f418b6e8c567f410568f2c6be8eac9bab558deb08389ba08bbaa50e1ec5dce044efe5830743402402a167a9369e1d281d37713eb656662600840409c4fb971c0fa7771ba53b6c13ebffcbb85aab3316a3a99a9ced8bc4596932b3d052fbb13a5cbfb762ad7a08ca4aaf33862b6325baddb0e56d395e8f92ebc7347e847956b471695c978dc2431ef7286c0e0a880f7871bb05160209900c0c403da599b988a8ef0a716a9535b71002b3bcdade60053f5a8bc66419fc907f1ea718b7bad6bb76fd3f710e6778587c36ba5e4c2d7796185bb72c5fbb839b6c91119ae6c954e9b66c3edb500d884428be2c7cb6a6c86b807a6059739e23f70433d8a7a4aa768975aa6b0c3924cc8827cfc731a464121090a685820068019197f489315a2274a7133422b2968830271fc94b1c775c5a21e3b07bce543b32f00b7250cabd0d04a2529347848830c975261a54717324533ebc0ec627f2064ba693a9bf9a16fce87a8d7270759a06c00eaab71a5cc25034120445334a39d63baa2ab3254d77a921209750f6869e6971d05da1e1bb29cec9cb7b4962370e5c139ba472a75114b28bbb8e7069c5a8201b730db571c1ee0b10e1c42b4a97fb7f7ae54670d12859d68199443157ddea85760445895e7175ef8bb919c7213f427301c4f6561afffb0b03cf1ad05613c52dc5ca71a74545abe77d239576303bc9678272873d9b28f4a4aacfdb46940f59b0a82a75642a0cd794d63d03d43f65e753a6aa2b58e0cc664a48ca3d8a3b18c7b05cf8293d3e23fdfda93506c831455b648e2017fd866c87683ab307c6fd9cf24212509d777f34b0618776864ebae9fa5318e739692c5aa86648d49778b67f81347b434ccfa990ee9a79de94c94054e6e4a8a152b5f4757b89f075a27ac464cd1801d02ab64bbba4f932c0003458ff73011282bf444961c54c5275408c4f79c3c553424aa4aa13a53d59b1b785c0ffb686fda185d5438af5c494d98b80381c821c493bc0e7797cd1995db681ec9e18859a9229c497cc251af12d9cfebc6a19c599c9d364e587c7d32245145a60ceeb54cc7ec5b541b71dae959c800a747eaab53f8cd24365c91f53b7b0b9d3630361d41ade4c82c85e04d8ba243763b3f9dd65d60921f962337a3421051d36889253a423939abeb0ad962ce1e1a9931c960d9f4948723ca17a731adfb4834615693f622470225cfa7b036b931a2240564cc35e59a7acae48707491576cc1410a304e0885534f577692c5a237344a5f674ec7c45bda3242d70b004d5ab620ca2b1ac0a56c0cd5b942529b054e0f840e3c1837e0053539b4a420a3005a17c7b4a08178b83f8540601145b102970b3fc29f30a4ca1a8a5bc4164051931ed68a59efb2b50d549bdc1a65e9909f5aa690b0235d32b1c6b2886ce2959fa189e2ce24224e99255863e6d964d4f422c02646a461bb5abf86f4b4c0975765a5b0ca01081677334af26c3467da771cdf40ec4293608801cad9c61d5f80839774eaff772b139051beaa65632120f00171ad020276a1fbf23517582149ad2c73450b11315ca4b244e7218800350aeb5808da774030635bc247508144740634ac4a078a5af2816e9206a645287de06263277242dba12af2a82ce13ba6787c5ac3020e5d30cbb92452985ae41027056f492bb1a5e23332698240b5038302e552c5acc0443a8795804126e15369ae96cebd7c9765233982458ad6520550baad77bc74296badcd4cc37240d0163caf8c806a0ccc3f4125a0874cdc1c67e4626c9c753453fa37b208caf5f523388d6308248b7688c80f6c925895670a1397880933af0152da1e54f7a7b512aa87499f7a718e62a7cc5bf5687add09060426b0d3cd292ab9b8372083ee462182872815cd740fd69acdd24615110bb618ca1ef662715f028864ba0872b8c199abe40f35f91906a821b8ce0742f931c661c65aa2445371a300e68f23b767382f3701ce685cea5f59c50e82e45234169c3bbac814ab9d68f83842c513a8faf475590b3bac2e3a4685b8f71208357d221ae41310e8454d315670c3a3409a2a95258b9057b42def7a7c6f588f6da61183acfb18a7cedf138c7984b50a940f17c687e5a2f83451d94398f4c82c93a375be195b4b219232e9a766e77040d3b9125e70fa4097d807a6d25323342508f2490a59702575d64af146088f59802aa2cab3537a8b4e92a10ec447bd89f9fe738d92a5f83c2861628601e42bb427b87c2153d4bc44b19413b79baa5ef55325ba8a42e1a88548155d03ab116e47ee0455f0e5a71bae3a03ef476f77a9a9cc6526df1adbea64930b6995f60181544356c0982e957c5e5186f321b9467d05dd5970a96e226c89673e50a056e7c0a8027aca8a5cd93723353ca1991730dfea1aee943cb0d62537cb5ad88c14f52a78cb6228ef4750eb7db0aa831a4202b178ef47446a06a17e7caf5274f384b36832a07ae0a66069bc59fe439f7b6005f064d865b550505210768bd636c61f0e7a1bdcb3c3065908d51302ee234a3fa113a1a1a2a618750075a6ec277cbdac535fc1524a62e3c0601aad1c46026ab6b8495c1b7093f776f9e6b3b533267ab99801e83bd18570166387f14ecb4d279b86cfbbaf90649e5c514e432561f850497d47c2bda1bc2c398b306751991392c399df6f408ff836f989c41cf76234b9445d9f81f4aaa987c1721c0c726efe44c311a589abb5e0afbc4add9bff6f87597a52e16a53d6c3551b7e6be0a1958a89a739e0717f0a86be0385c5ca433b68ab9506ba3a6e00debeb1ad0519e228b5b2d9aa3c9b4a2bfc8b35bf0a04b5a9d0154aef1a9478df4c8a0354f8878331f76c8cb6851940c996109113446367497cc73d395b34a9c7dd9621c9bb277bbaca6d976c3e65fc3fb4588643ab523bb35f551f1f30d0cd1c40d14b09429215e0c5325bb2b069b85c9e0bd9fa841771aa7c9709046b442990cf89513930f122152632a3c3d7c15c8018e1c23aa33cb89ad61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a + +comment = Official test vector 33, seed: "4635dc5bb92ef98cdb6220df0dd717c7f8158375eaa2b78fc3f0b58e9c9653e92684cad3461d9158a481da3d14694c44" +entropy = 684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 +expected_public_key = 63992e0d6a8f811b3f0d30807456c84c8bbb008d3b126a31424954cbc6cdbce91e25b19928f4a41b1371447ba3d173915580bbd7899e9adca37b4b5a21e715101717710bc7eec56ec2e58002127d1898bc55f8a3be385d607b3ba6561991ac6f0913617303830da25f0cf0ac14e67abb8097d17b0ad1ea8c6c267adf51a15a9a363d7aa5c8ea535a89115c984ac5d6bfa922c6fc44a3b35cb667f939fa6b2676ba212c17bcd25c82e8172f6a7506e8b77d82cb21d7066da93a7eb3cab8e881a24c7592bc6b656e459af33a06fc2846d71221f1da641004b68bd65dc28a59036ca678508614b15a93e74f89b8af58200d50e718dab1c41c4556cd47b43f14092ca47397243983406e12e423233c90cfeb661a32ce65ab464db58c922bb693f56553961868b064e17a11162a7f0e3ab0b0aa76b8494ba394c902c598c23721dc16c51d46b8258c635763776b922fcac747985b94c006696f18ba49d0c5eb0525cad1349745691320969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960d61a6f94b317d488d2d04a8b42c7fb7d89d52d89b2de30336333c50895348870bbc311611f27845c7775128a9cc831966fccc06292d86b582a18c6ab2fb3cce03701ba91047227a9fcbc6f16130710756c5dc288ba92402b5b7dc90c39193737c206f3f8230261852f1694258d47c469c7452156e70634384825bc52b03e90720066b609a4102862433e2621987e23af51121bed807810501200b776f847ff615c0f594420dc29ca6573276559c1c84b0723569dc2a76728909d9d1279a8c240a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb434132ed5f1340e2c669430b13a709f7d1612af876454f06ccb7841f84c60f3806d5e423cb34b23bba90ab630403a46783329707388a1f4232785d4723c993cc62284d0e35242e52cfd6981268b86f598b11472900f83333c48627d402abba59c6740b4a40abc3200b5d9e13010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6e3017c94ba93c7518f017695f5bf5b99214c8555bda863fdd11d40053c0d652696286d2ba14d569915e4532132527ce1b88122640ad668a20964476db20afca5ca663c6c17156ab3cc8e4b723b3a5209d2d10767da52b2443764f91a7f3aabb35137ee18a1f744562e22385716892ca77d518c4bec578e0f1145b3241c1831bf782c760f9081a1191812790531648954163b10e6a1f02b2b9e17cdd439c6707aab0df09236ba33d9b271196a398ff0b2c9521e57b6c8833489c5328f4866c14d2cc1ce037400dc610b28cd99150404a175662102f9617205c1cbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d3e12f5b56406cc51796c66a6e871deb601cc767c0b8e45744346de60bb160808210506c5779bc275940e000314f30555677689f23009a583cd6f9779c83530e5b2a5a0a771bf1376f0091c627afecac104fb2ba251c074e359e5fc44dec244ccb78423532a7eb27c8313a341dc1431035162838835c85c677a420b67c847dc6605821587c8064e0bc2f4fe6a6b22113e73519125b92b3a66f15564666023ea99273d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968 +expected_private_key = 8b78635ac351c94bb6b1d2b861e4914dcba415f66ccc465b370578e136330a2c5cb0ca2857e1cb733a75e5cc4fcdf7a12580017f1c0ff484401cb23318a98000637b3d065608678103940d8ba75ccbe58206c130ed62bbc0132317b6556a9c2ae8f71a43712002d795ca52007782652d291dfe535f75034b0d624277527a6ef623168aacfbf721a9e8753195b82eb9855467322aab0ab1701546c470ad139944b6736e1c97c9768370846b45693aaed9c80a7b53b863830df61fe9600ad5717bfa2c8e59e30c8a20179b27b59341c855677880330afd1a227b6c6313e17c46e87d109a4aec4c1795908db6046598483159907a667378f80bcb84472d5a748043b1bac10ba5bcf61b07a2b13b12c347f3253e26c25ef0af6a003a67b0bee98a7c5a489c9ec9ac1f042c6f2bc7585cb01bb4b55496a93de903ec974398e277ca7cc25e3265a879420ea0bd8451716ac21f1bb806c12b3488d408ebf18b89b79b1f8c09eaca235f1c165f9504ff987139590f9977513ee037249b4e25e51a296526ba76cd3295895a571cac279bc65642cba501c8f131eb52b5c7cb73b17757440b1ee4e9295d404177e542bd744aa587738bfac0ef3c1fa0f19b0a5c5e28b53c2340c7fa061ad354c85ad26993087b61ac2002795d5ada7a3e6747ab8110367c824988ca705b818d7a921dba33371405ad235b18e463a8ac88180c88f071579fa5ab6d904a2f53b03f7c7ec39c473632369f984f8cc66dbd1924206a6376706ca36601be7b16edd17e93cb9a0437b3615374329b0712794f5058790d88182be4863293133a83aa00e07c8e79c6f12c33fa9437ed984a1392903da89bd43184db6c8dace3789af5cbba092010b889ca98af99e5b0b3d4399bf61266e833a55a85e11784708b98efab223a27aea1a16e76a73c2027759fd97a7db870f9fc79afc89435d092db556e0a738c133b259f86c98d78a43a49744f306da8cc6c9098a5a9cb091c9bad94970f03b543d669a9aa4944e0c08ddfcc1d7d485fa414b0765a88f175ab6c94b12a2177dcd4998e6aa263ec3fd5baa2466ca04568869466887f7bcf636c7a1f084277532841f51c3edc5c1873bce0f07a8871740c4aa82bb5ab164916082b795eb0660be32da9972840c927b7bb4061343d56757258ba4c91624f21da11cb265b00b9aafbb1665679c86eabbda12b74f1c5917101d0ea2bb293c71ad5b556369378a8d5b7297c9731705dd4493dbb173ad01458686a93287b6da0a6923b913989b69612a915a03a0962379bbc466a03f5517aaa0c0b030c6ca420636b2ee8821916e9c7f2ba228bb2aeabbc292f6c07ad85c6f43ca90d42629759536046394936c3ac5ab979d5cec1a1cc19b5c17edb47b0f47f34d616027b29a12725bf14b62fbac4f2cc6eece89ca0467d4868c11c17299373687b657d132c55785080f5b87f0e3c1504673825b98e8a0aa35f2c8d84f41b060ab43a930e7be1c9d04746169bb4ab403ed8c74aacb868b4a93f1dc55144738e2736749ac64170ca7d0f0348a9550ee494466a49617b541068f2c57ad4108ab813db58526c7647d55c1cb657ccd1143343aaa8421c23bd0c822f763b6a82b7d0041648a143bcc43163992e0d6a8f811b3f0d30807456c84c8bbb008d3b126a31424954cbc6cdbce91e25b19928f4a41b1371447ba3d173915580bbd7899e9adca37b4b5a21e715101717710bc7eec56ec2e58002127d1898bc55f8a3be385d607b3ba6561991ac6f0913617303830da25f0cf0ac14e67abb8097d17b0ad1ea8c6c267adf51a15a9a363d7aa5c8ea535a89115c984ac5d6bfa922c6fc44a3b35cb667f939fa6b2676ba212c17bcd25c82e8172f6a7506e8b77d82cb21d7066da93a7eb3cab8e881a24c7592bc6b656e459af33a06fc2846d71221f1da641004b68bd65dc28a59036ca678508614b15a93e74f89b8af58200d50e718dab1c41c4556cd47b43f14092ca47397243983406e12e423233c90cfeb661a32ce65ab464db58c922bb693f56553961868b064e17a11162a7f0e3ab0b0aa76b8494ba394c902c598c23721dc16c51d46b8258c635763776b922fcac747985b94c006696f18ba49d0c5eb0525cad1349745691320969b6bcff69c30851b41e66aac3353c6894ab0097b4ec49783cfe4960d61a6f94b317d488d2d04a8b42c7fb7d89d52d89b2de30336333c50895348870bbc311611f27845c7775128a9cc831966fccc06292d86b582a18c6ab2fb3cce03701ba91047227a9fcbc6f16130710756c5dc288ba92402b5b7dc90c39193737c206f3f8230261852f1694258d47c469c7452156e70634384825bc52b03e90720066b609a4102862433e2621987e23af51121bed807810501200b776f847ff615c0f594420dc29ca6573276559c1c84b0723569dc2a76728909d9d1279a8c240a3979b0b44003687a412389581b8ebf0ccb06c797f7f5815ccbb434132ed5f1340e2c669430b13a709f7d1612af876454f06ccb7841f84c60f3806d5e423cb34b23bba90ab630403a46783329707388a1f4232785d4723c993cc62284d0e35242e52cfd6981268b86f598b11472900f83333c48627d402abba59c6740b4a40abc3200b5d9e13010fb4dd6bb503548c777256e0729905a89bb386459e0b885b6e3017c94ba93c7518f017695f5bf5b99214c8555bda863fdd11d40053c0d652696286d2ba14d569915e4532132527ce1b88122640ad668a20964476db20afca5ca663c6c17156ab3cc8e4b723b3a5209d2d10767da52b2443764f91a7f3aabb35137ee18a1f744562e22385716892ca77d518c4bec578e0f1145b3241c1831bf782c760f9081a1191812790531648954163b10e6a1f02b2b9e17cdd439c6707aab0df09236ba33d9b271196a398ff0b2c9521e57b6c8833489c5328f4866c14d2cc1ce037400dc610b28cd99150404a175662102f9617205c1cbc24b5716c7b9b0e8635bf960be5b632a976156c64078cbb23eb86b7be9a2d3e12f5b56406cc51796c66a6e871deb601cc767c0b8e45744346de60bb160808210506c5779bc275940e000314f30555677689f23009a583cd6f9779c83530e5b2a5a0a771bf1376f0091c627afecac104fb2ba251c074e359e5fc44dec244ccb78423532a7eb27c8313a341dc1431035162838835c85c677a420b67c847dc6605821587c8064e0bc2f4fe6a6b22113e73519125b92b3a66f15564666023ea99273d0d5657cfe1b1b3bbf85039a8189076a3752784e23d8a802023fd0743eb03d989a6968672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec33075d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6 + +comment = Official test vector 34, seed: "5da2c51b4acf488c8bded5e985cc4702e4a7bcb248b5ac18aaba529f7f9cbf30efa776e99f76d5c1686e94f50fb57dae" +entropy = d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f +expected_public_key = 192042d43a4271e44d1546306137a4427130c86a2025bcc297eb36d3c44e7cd4b0b1c22005fa702ac12569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb3a268165596fd0470400ccf5e3b56714792f7a87b9e03019751425695ad70e4ce0b2769571901c6c2003b58152fa9757922bd28a094771b0cb1dcc73741b14b402e8ab86dc0f647525c131e9aa1a9729075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4c015ce5f65fd1042a137453462b8710704bea463204c463273bb71056378850ad28f37ede664e38514dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd0a0417c2655a5476f51a68cbdb4aebc53f00c11e78e5ba6692a516c076330c20d0a09f167bbfe1c956a619825a8305d1aa9ac5736e6d24145924b2409a8688b41f33a181a9e4858325140a797f2ba81d50f21af88650cd0ba8e662077708551a947c97c0a3355852a77576ca5b054d3b0b9fd973dada618bd02fff1cb59eb56b12c71b24bb1f02e27282d21281493ac7d07a20b124aac30b7bcb8c2ff24b2c927d3d62ade0357bbf7c1281fc94da2b21d10a5e5ee07a3fd9cf93e34615b871c8da7db5441020d0522c12711e1963be54739bd43949999083115988a09c6020ca88124b35c34ebfb0743b494b2666ccf5b5235968275fabcf9a054ef92833d8ec816d68c07fc53634a02ca192a411c87dd1f17ffea094b6868638716cf593b33483591e4049e4e7c65c8618b242b17d6021bf0a70c7c59bc81c34f5441b063b9a1d95481e6529602b95f874bf1c649d95a072e70a52e9252e1dd1bccdf64332345355f7cc48eb7dd1aa2f2c31ad1fd58b8b3a711d113c270a90aa2c5c79958f3907ae3ba071aa6144b88ba6c5575bdcf5331729a65d8acf3db97aca4191b72a2bc1433fb3483efff09698c291dd868275dc5a86d06d97305ba596515e434a8d956b2b73b3c00821ba055aa7541e4f35896113acfd9320fa91585f3212cfd5b023a77d7c5c0ceb746723c2c7d7417bfb740e4bfb2299b29f987698edfc1b8d7b33de2c80d0cbcb44f05b1ddbc667005b6e4335751ac281022cbcfac0a55226fa69cff845007b9a16d2b6bab3135b325b12c263a81fd423120a6fa639910159b693406411a289863736557a028bbaa23e0c984f04543e61916d9bceb4f64fd48823a4b13e4f83b43d443f62ecc72fd304f71772cce318c1da9a57a67502a1119313b93c4a66d03c2316c2cc5c2285b1e80c413b2f29c447dc975923d9100bec9db958acd7850ab0777d82814929121bb87a6f4f07880510331ee6171797bdf23850d5fc1802e432b2f51b3cbc37631c9729892b6a09baf6717e6ec39ec2b3489b33baf257c35b9cbeffdc1a1334380fc35df386116baa9bad3a0a8381c4fdfc4b1b98836f23ab923175eaf72c59d9c500e10944fb0fd701ba5142b3cc358bfaf2732d643d0b135c8f991b0c73789c465a7e1b3ea6804b5ab9ab2e42ca1e91158019306855a5767893bcd17e92a41470d721f6432448fbc370c64c3e330d83987f3a9479f000c75320a296393e253a68e0e1c05969784f5612adbaa2662459b09638202b74d8d5cbd2b01a915ab2ad06b08670546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26e +expected_private_key = bddb6a1bb704f8b530860b719752402098c84ae4809b01c8ec7583a66a3f4bc290bf2173abb41868225606d54991f5b547c2254c74391717045997a57ba534a97b3605e1ad9f7c6446ac08bbfb1999179bb8f67731a63ce1c717f30b57fd17bc00605e8e14127eb0c26e324aabd45138484a51a15dd2464440178ca7e966d4d58383f6bf9bb2a971729074781a8d978965f9a51eb2729ba8c308474d56089f2cc869b523c41c409507a671f0f3621e057662454d49c49a398343d64cca74b7822d773373d5185426b7b3951256154a7b78cb1f5049df0371b840ab21b83944fb383cc84ad9e24ff42b2731276c1d26b6120534438b029c4ac7c0739453c2860d32acd75229c63a23a7201c303032bc0a410319035d38a3c9802d41a56a8c6c2496db10441a2bcd13a81f90cda2564cc9e4020a47595a30994888b383e996115aa282eac3e3594447110c2d07774f9312d796c6b74a7634b6c0da2291458a35d3022bee048483461cfeb152e1d2ca9195afd1f9aa82131804d35e739299c539b913c54a0c58683259b3137aa464b9c6e03b0eb751999b6c5354d6171c78cbbef1b456ec4c88199764a5761d18c0849c1b0a263ea401b86cba549c712e4a251830f7b6ee16b2bfabca3ce018c3833bb881385c272dee151ac35a2c9561b3c1266855219b0c6b485e669fcbc49b24c50c6c3237aa6b116085085405115e0422d956beaff9360b58bf915654b9b887ad9733f425a5c6990b3f0223d8099bc0e95c6a5702cf5667209ace08fb4697d02dc45caca8074185f54ec4641b35bacd2f0b770fc215fdc171c98baa7ab6c0450ba6e47a838575a528f7be221c3c91f02734269a9425a2edb76cb6d077ed76040a716d39c9c87a58ad8867954c752367a905aa158e0a9019dda50a6213c260f7bd8a0a6e8cf581fb74cb17283f3a1a8aa9a0418c79a948199365a6a1045238104280ac704b33791e156a2377bc83e9b9c86d0a3d2aa3287272be6431bb4e598232312d10d03bcb13b4d838a9a624566c6a25fa44a0934ab6cc333e6d52af3ec26a6fb97615cc3c77102d1a315486bc69c555a3e8271660222a406022e8d97251308a90a15f748153c1168cb133593c1641e164c8a06cc008059c55449413c2b28667b99122ac42b8bffbc15fe395003249c676db7589d2896e7405bef8ac510782ff204454c8a0390c332ceb7a5a3123eb1a1ad0470096058358ba779df70106e24990da77aaf09705110993f16a2320a941d8865b387236cb8528babbf2d9196c15898bf71040d3ba500cb7b1ac85df11003a058d838c2652d4577306023c756ae9715136e91b20699fef425e48953fece15baf27489d929876803eb0b5764e6338bf5970c2f35d1e815bb5b0b1bab630138859b729923343c3d24922a8522e38e19868b8a4585acf14b795ff3a609d93b1a5ccab08f877c5b71ea78c2819113fb3632d5d995b02926663f2ab8e3a73dd6ab93503192e0243f2593618e3a809684bb6a31674e77802828fefea3a50fcaeb1088f7edc036cb84329c988d965071e97c1311643bb1ca2b43cc57c84cd5ea9109ae36de2801cbdca3bb6f977959578954ac17d303841d5726631663f12816edab5192042d43a4271e44d1546306137a4427130c86a2025bcc297eb36d3c44e7cd4b0b1c22005fa702ac12569bccccaf6ac9256a1693c8b677c5ca243b9c8556cb3a268165596fd0470400ccf5e3b56714792f7a87b9e03019751425695ad70e4ce0b2769571901c6c2003b58152fa9757922bd28a094771b0cb1dcc73741b14b402e8ab86dc0f647525c131e9aa1a9729075ebb3cdea4d31f6c3b23a5bcbf74a3c653d4c015ce5f65fd1042a137453462b8710704bea463204c463273bb71056378850ad28f37ede664e38514dd735bf9ab9b95d367c54d84ff085650ad33ebbc982a329c6fe3a516ef387bd0a0417c2655a5476f51a68cbdb4aebc53f00c11e78e5ba6692a516c076330c20d0a09f167bbfe1c956a619825a8305d1aa9ac5736e6d24145924b2409a8688b41f33a181a9e4858325140a797f2ba81d50f21af88650cd0ba8e662077708551a947c97c0a3355852a77576ca5b054d3b0b9fd973dada618bd02fff1cb59eb56b12c71b24bb1f02e27282d21281493ac7d07a20b124aac30b7bcb8c2ff24b2c927d3d62ade0357bbf7c1281fc94da2b21d10a5e5ee07a3fd9cf93e34615b871c8da7db5441020d0522c12711e1963be54739bd43949999083115988a09c6020ca88124b35c34ebfb0743b494b2666ccf5b5235968275fabcf9a054ef92833d8ec816d68c07fc53634a02ca192a411c87dd1f17ffea094b6868638716cf593b33483591e4049e4e7c65c8618b242b17d6021bf0a70c7c59bc81c34f5441b063b9a1d95481e6529602b95f874bf1c649d95a072e70a52e9252e1dd1bccdf64332345355f7cc48eb7dd1aa2f2c31ad1fd58b8b3a711d113c270a90aa2c5c79958f3907ae3ba071aa6144b88ba6c5575bdcf5331729a65d8acf3db97aca4191b72a2bc1433fb3483efff09698c291dd868275dc5a86d06d97305ba596515e434a8d956b2b73b3c00821ba055aa7541e4f35896113acfd9320fa91585f3212cfd5b023a77d7c5c0ceb746723c2c7d7417bfb740e4bfb2299b29f987698edfc1b8d7b33de2c80d0cbcb44f05b1ddbc667005b6e4335751ac281022cbcfac0a55226fa69cff845007b9a16d2b6bab3135b325b12c263a81fd423120a6fa639910159b693406411a289863736557a028bbaa23e0c984f04543e61916d9bceb4f64fd48823a4b13e4f83b43d443f62ecc72fd304f71772cce318c1da9a57a67502a1119313b93c4a66d03c2316c2cc5c2285b1e80c413b2f29c447dc975923d9100bec9db958acd7850ab0777d82814929121bb87a6f4f07880510331ee6171797bdf23850d5fc1802e432b2f51b3cbc37631c9729892b6a09baf6717e6ec39ec2b3489b33baf257c35b9cbeffdc1a1334380fc35df386116baa9bad3a0a8381c4fdfc4b1b98836f23ab923175eaf72c59d9c500e10944fb0fd701ba5142b3cc358bfaf2732d643d0b135c8f991b0c73789c465a7e1b3ea6804b5ab9ab2e42ca1e91158019306855a5767893bcd17e92a41470d721f6432448fbc370c64c3e330d83987f3a9479f000c75320a296393e253a68e0e1c05969784f5612adbaa2662459b09638202b74d8d5cbd2b01a915ab2ad06b08670546d8b76877b8b2eaa1abb3132e55d8bd5b08678bfa4243430bb4d059b58a4b0cf0fd26eb86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f + +comment = Official test vector 35, seed: "4d2239e84b052109a78dbab6d80c51a86d38248105970476b74a0b78b9cfab6283e30d5a406fae1c7f54f8bae1110ee4" +entropy = b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 +expected_public_key = 38e84df3c6a2dc2389897c3745183e08c1681b5b9f57c16aa2c12778528510868964122c1747662cf97d8b0353bf23693a70b3b2a7c8cd5c5508a227261cb7c3022058e318d3dc39e320770724351ad78010eb423ffbae6714999226895ac23735a9119622bbc0811516d617353c7f769628925bbd49629fe0aa333d1909a16c5c27604b7db0b4e602ab27987df23c3718630ba4c2846444b83fe914d840cc8ed79a85b645a32809ca069ffbb8b3201131cb129db9282b73174f8d4a14a37393552b109d2271edda8d968ac3ff67aa3374a2355c2ec895441873325db71c91020e91f19347d965f1410f606862f69643216b869673b5a70583fd1218639b5036cc11d051a13d219f3969c817326d2b60ba5c13cd8cbc9313aab478833d73716a2a48438fc529084c241bcb4fd67179d1f5494b4bac2b05a5767b9647ec8829a500d1365bca7b8ce7b75bfea0c68f8a28edb7bc4a3817c0d32c4e10169832b9abe271cb0b473aac2c3dd39ce895551a297a61f47162d97c41f051d48b62e5a8882da62fcee16eacfb89b98a12ab626e69d77ceb3b6b02878ce346ae5cf754c3f6097e0b5eb7ac80b9b8ccd9418f63e545d01c7d17a71e45ea3a6d927484d4976ca936fe392cf2052535c201de9464008c932617cad94085c5816aa41973a8d21610430ac4b3080dd480169258e65b53e340759bfb70d68b15b868c4098847901a6b255938ecd15d5ea94232b2971e3bcd56205fc6f0425f50ab880821f56c7b25f51f2412cd7fa023852cad04f2704d4103d4362e965473add3563d9b36e5097c982506865454ba30af132bc17c807309723847257c697c525e27cc570a88a1688134f4193db67eff018f54751e578483a77a119210106fd03066c403b3303ce54b39493323c4334d4a7a20aae04d8ef529a15cb7d0900fbc4236c717310246c9cba14d6874beac61b566593b5ec5887272b914ea655d254d595824288a666f10c7da583f933052f43b0b0fa59248b0584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea50b00a5503cb542c254a26f456aa3286b0126350272638ef0b4a3abc56fc8d0aea2f7396d97b64c56817d58c32103996db88345d377fb7b2644fc99a24258c50730045b897ac908f7fccb81bc2b51c286899c8c499c1757c6b0a6ac0a8482159d564cdb746037a1224ca72177f79ed19a398040426664abfbbb7b7ba99906e7982b665a551881e0f02a97409a3e2acd37fa96a4f9293f786a11b21e1f0bb22cf400da06081bf68111a9bb64469487d4cbc10578106b381b8b054ee29339e1830dd613e19a9baf9a81c2b9ad1d121a47d40234bc9d4b79c2f5f165bab5a2db68c59c0737e0e4786990a92476aea44105f3c77feefc342b458e4310b9b110a8b2c01593b512f069944828a3f6a219354bbdbb1c344f24aa0784160ca704bfd89c4933b6123c4434cb9a6ce16d3f042f1fc571db728119f6a33e4a9f6981193d60be6ab916818b8e1ff9a1d1a59de8824f808043a1949a5520b675d8834ef65c1d47afde2710c6b63998d43ab47a681f0a856d166c24494081e076d5fc05b541145d3155e232a5af0ab96ecc0b09c2c41e285d350500a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c2 +expected_private_key = c6389f081ca0932ab66f658046c1278b38bc42b5c4e1a7c7a51b09d8a159773b67aae1c2aa8666000c6e6a014b5c0369dff147688ac6fd48c73d783e3025c92d782a479acbde8a7548384b763a868c46178345a773a9852016b9fe765db0bbaba5751e8056b7564c53fee8040d3c0125115d323c62a3f0a2b518330b6cc4abca84f62c792d07c1e1a0bbbd7c5b9a698cb683981f8828ee69912600311a0281dbf9c6c9e69daa26a446d136e8b0310f236d7a5a49b2bc616fd346c3462ab09544998c8d5ef641e7b48c35ba7a68f25414f703fb02b501c69c58a9b798c8c76923272ed9bf432208bab30f2db45e1cdc56f6ec11792a33ec1a62b3fc992441527e63328a46003db49b7dc07f73f705ca0220de94bea4967213d612b5a03b2c16a9bd4c66e0ac893263169a87aeae67843944628e6374b5518bf40919840b8e6c64172be3a35ee5a29777c035463380203072ea50e7daa4f906d01c502560621137b91649c97417cc2d3e1677006226d4621073cb1aa213525199bbbfa78f1899a53cb2b8d00819869867a41b2f48c615efe2c8da15a4e6965bef0c4207a499a2156ebfb611478182d85a71c9f8776d28051d1a6e4a104e54615992e0595ca9b0cb2a0ab0159575863f3145b3401498949502b2ea4392c77728215f8700c93f5846a1a8126eb6b72248bd1047bbe62aa58737268428509e53575f945735e75b42db2ba2f21b24c990a847241d2c3533b10d50847c85d98143fbb2eb5138accb055a8b8bcec8afd7b5697306165af982190821a14301ef0a90c3d829ed9035430725a99c67745ca415600d10d7c29b228998d7402efc1f0d0476c4d74c34754af9a1aa1213c9a0198065378de2d023eb73b3a4bc5801d98213ab7040cb63318b8395dbad6c7c604760ca679b301ab08ef1a948a5a83debb39651310b368c736a56977f78af0916364f278a4e3973374213f7a28ba70296d1916fc65cad3b33c4e1597f818cbc489ba970680999c373dbc246740c07d97c5e1ea5aa1d627757f4467e84ab9c5bafd9ba484f1212706788cf5ac1829c7ff0a66f26c30aae327bb7e167bde95fb5829340b187162a5fde3a7cc6a0a05fdb6f26902bdb0c6c4f75692e67ab1c8b1b46a40e53fc901dd892a3e612afd1cb2cd52bc5b0c3191137e602b0a5872d3a961ef7168990b634f438b744375d75995943caaa47e3cc5dc634432b6cf2db29b637a5e22559a59971be46004fe2a40f7c330610377a5b0eacf79d85f3c86223a4c90c31c2495314748601431fa1f49abff2575410af33f7367c5540084b75d6736ecaa010290839ee2456ee16bbcb57c601f26aa104916254a689c24cae98296e4bcef8770ed7485511f55a46c75592c88d6f76005356c397eb1e61caa04bf55a05c8409e644055759a7e60c1c8210221fb97780b92c2c8aafb6b94c259a9ce6291e18a801a82456b93c221a625129a1720328f11574a5c35c3650a7b57619c61f47ed6319329f118f4c31358a26a7e9191cab61012a71b27b47fa13cb0b2c959d913a2f4bbb3d106ab695a4c13d41256a0b442f0428de78f90609a11b8cbb475083712539e1ab034903c30f6b73bb8229ed50f901b142a597e7fe48b38e84df3c6a2dc2389897c3745183e08c1681b5b9f57c16aa2c12778528510868964122c1747662cf97d8b0353bf23693a70b3b2a7c8cd5c5508a227261cb7c3022058e318d3dc39e320770724351ad78010eb423ffbae6714999226895ac23735a9119622bbc0811516d617353c7f769628925bbd49629fe0aa333d1909a16c5c27604b7db0b4e602ab27987df23c3718630ba4c2846444b83fe914d840cc8ed79a85b645a32809ca069ffbb8b3201131cb129db9282b73174f8d4a14a37393552b109d2271edda8d968ac3ff67aa3374a2355c2ec895441873325db71c91020e91f19347d965f1410f606862f69643216b869673b5a70583fd1218639b5036cc11d051a13d219f3969c817326d2b60ba5c13cd8cbc9313aab478833d73716a2a48438fc529084c241bcb4fd67179d1f5494b4bac2b05a5767b9647ec8829a500d1365bca7b8ce7b75bfea0c68f8a28edb7bc4a3817c0d32c4e10169832b9abe271cb0b473aac2c3dd39ce895551a297a61f47162d97c41f051d48b62e5a8882da62fcee16eacfb89b98a12ab626e69d77ceb3b6b02878ce346ae5cf754c3f6097e0b5eb7ac80b9b8ccd9418f63e545d01c7d17a71e45ea3a6d927484d4976ca936fe392cf2052535c201de9464008c932617cad94085c5816aa41973a8d21610430ac4b3080dd480169258e65b53e340759bfb70d68b15b868c4098847901a6b255938ecd15d5ea94232b2971e3bcd56205fc6f0425f50ab880821f56c7b25f51f2412cd7fa023852cad04f2704d4103d4362e965473add3563d9b36e5097c982506865454ba30af132bc17c807309723847257c697c525e27cc570a88a1688134f4193db67eff018f54751e578483a77a119210106fd03066c403b3303ce54b39493323c4334d4a7a20aae04d8ef529a15cb7d0900fbc4236c717310246c9cba14d6874beac61b566593b5ec5887272b914ea655d254d595824288a666f10c7da583f933052f43b0b0fa59248b0584f193ad548a12a845fdf14a73a0a37adfb4d1845afe6b56ea50b00a5503cb542c254a26f456aa3286b0126350272638ef0b4a3abc56fc8d0aea2f7396d97b64c56817d58c32103996db88345d377fb7b2644fc99a24258c50730045b897ac908f7fccb81bc2b51c286899c8c499c1757c6b0a6ac0a8482159d564cdb746037a1224ca72177f79ed19a398040426664abfbbb7b7ba99906e7982b665a551881e0f02a97409a3e2acd37fa96a4f9293f786a11b21e1f0bb22cf400da06081bf68111a9bb64469487d4cbc10578106b381b8b054ee29339e1830dd613e19a9baf9a81c2b9ad1d121a47d40234bc9d4b79c2f5f165bab5a2db68c59c0737e0e4786990a92476aea44105f3c77feefc342b458e4310b9b110a8b2c01593b512f069944828a3f6a219354bbdbb1c344f24aa0784160ca704bfd89c4933b6123c4434cb9a6ce16d3f042f1fc571db728119f6a33e4a9f6981193d60be6ab916818b8e1ff9a1d1a59de8824f808043a1949a5520b675d8834ef65c1d47afde2710c6b63998d43ab47a681f0a856d166c24494081e076d5fc05b541145d3155e232a5af0ab96ecc0b09c2c41e285d350500a4f8bb32e99b4b05d558ea7918a7881bcf516457ad2c3ab72ef2e04e3a4acb85a987c285441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be6241646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71 + +comment = Official test vector 36, seed: "ee762f5c9021c36446706a88ef16312f4a12c725cd7afff1484337c91eda8e89f7007f3705747d29907b3fb7500e5074" +entropy = 056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 +expected_public_key = be390596bab505e51b3fc147af616e0f94506635a758964b3e7cc067b80827db21dc87450fe1415ee41fca8a2b56b355fff13616622fd1a19a7cd98f5084610d1ac9f1b8a6e78cad9281a0afa5a7c2a9a87916710ec9c5b3544b76b4808d01399f219b745962536026c79841f11961b63c10c99074edbcb4ed786f7e8c3826609533e5bb4cb80f3e515299eb757c217da2806d26664f154c0cc2b4a644b224933502adf5a66f5b54cd45a71589219aac65be0623cf5b4c0df17e72cab64b91bfbd903d75e164e2a0c9e2c997f36a0b432177de617f5e6746bd82984bb9375b4a0a12e96d06045a3a984667d03d8c08cd980b59cb2b0983b13f9c53790fd43653e78255882f9b0c980ef6b062789332a6b67b2b78e9e370b78181531846b9980a8af905fef403f47b891a6b440ee71cc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36613a15f147938d32673402164b001975d9c4a8ba5ce84d20b47f26eba5909183c6fe1343d062389b9b99cedd21e30d5841fb68f3450a47f4c4be5e8c413c37ea4d5ad629141d7430938158cd04492bba8aedf7477ed13a0b97c8217a300dfcb22de05449547626d21409f491098162d7ab477e3ebaf0e15124f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb6705a467a3d4d9102ff2b6ed976ca9d856e9f257d5d586c7d8a4c2617dca73aaa65719a21538d9e6997c5637df8c5a2ab98a169a5ba8f708bba55f2c0a9463c9b4ef0c9822fa64ecc72c8bda4030157bde5073fae6a6e6f036121125dfc5a9dca1504a1225e6da9db4d0665f6413386153ae25be78b3410369bbdbd84a86c6c7bc924dd70005bec0c54e07b4adfa2daeb8265dd98bcb8968a2f683a3b07633aaa0290550665c01fdeb22398aba31140fa7494fd6a0087194673f51ac7d759d649a2fa4d7520fc67138f445287b681f5c3d1678b497129bc6624163e3515c8381e85c173d6a4cc0038dfc2064a213c557931e2e7138fa1a6bc3eaba08965bd803bd5759332cb1bbc4c41337bccca153905990970c261cf63a53204b6f8cb228d4234f08837425a82f1da9be43775df88a20a0381f70044c76b3524b437cf365cb131baa14ea6f24502336762c8e126afd009e1997b8b3bc20c246070df7b33bc9a7bdfa8ccd576925968915f186ca4a5a4934528dc75282e246b0824ef7118d39dc1f07449a218836d47cbb7365b677ec7d6222abaf33068b5730d9e674cc008125226cbc5382a76a9823db1b42976c5c90c23bc02eb7b874dff93699e6035a838b22a7126aa42d62682505f9bbc77143dca061f5c38e99652fc2e28e30ca8d62127af02186bd9c95602992e20baa636ab050ab870b11c52da19b3a68b7a07a8cfbe7bb016a2537e50464265ff6f065d7a8c30f659998a35d79032f887b4629d07bb2dc895f09ac0387cca9c5cd1aebc08a687798721f24ca43c2c5ad42d1b6641838efc2a72ef210bad10218846f25da336a4c00c4a29eac8a608f2261b8c76b18f10b7aba755771376dc7b876152f9fba5370262919511d4ad50d76aa5cd6566c29225dabb3b668608d9de5bac08320cfc3570a0ac8deb4bbf3d941f9325aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd +expected_private_key = f75196a57024be817edc544dbd552f6b42ba121c2b8ea95e55017856a10c5905a8bb2590e63b449364802c6b438fc19eefc875017acf652a8f0d6ab0f7f5aca1f1833ed3551d37419d906d2b55123ec14d5f109abcd9382e990628bb30d882cca8665957346c3a08553c870d32f77e66348ca9dc321960b7d50b09de64178411439c021899f2b8c583762043a4508c3160544ed2264735c600a6ab43c8515532130583298a11450ae3b7c99ff559a1d33115dc2d2489934518bd52fba1cb9a019d918464b59cc90941599253957364dcca9f95a08035f8be5bd36db6b19f1f191a6e4b7fcd493b7a41c90bc76fe882aa0f3b39b6f454785c5dd1d106c80960bbe5846d90bcde837cd277a039dc22427b86a6658f97a60101665f3f69125445647f3bb2d3125c80d89aae6096a01c24902321933909a8a2925faa1e7407b3c90c8a53d958c1c83465e557ab620e53509ee8c960b3c547fea08d4ffa215742113ed9661b57ae1b30ba5768645c632de76b96161a9b6c34b8da48b75d176c2c849aad55c6680bd0863273c345c4c7379cf3f873fa5953f53b9a026a4dc120c96e279085566c7d090eba276a0928693e639b5564a59c08aeafd25915f5478dd86e938a11529bb9a2b0b83487c696e79f1fd034ef000fa502328184be42b8959d9c0683f3bc20e71902423ab14a4744e162f6a2b474dbc4a6f21fc0432ca7422cfb253d0f952be9c13125458df8753f5d551caa38bcca1625b533051c5226c8768335854e7477064320cb765ab9eb311a1859b4b5a006d918bd8508a971205e6902897cf95e0b652e09030794b46fcf7a784560c0a18b8e6334a57ec177ba56a8bb9a857013c6b9998975379bb04b540015a14a76c658f856becca363cb37997bb85b185aa0104063696f1020bd1b443419989798826e141a24a3533494391fa233cf848451cbd609d014508fe137534c42d6f22ed2cb82363c847865aa243ca993b14992572cbf5535845cc708bb09a1e8a7834c200d8036768755afab53aba85813eb859ee83efea7563ee4bc158599f0cb04033393c829aedbda289ed852e1eb1feda9484777051f967e048041ba3c313a1414d463cf3ec36801aaa1aa540deab122ab530ecaca30101a1089087311972b338b045a1637189020c3030e63f707feea9af844c7e1b20b4a5348c1a432f341bb9f598b8c0c2f6f55c4d2c2c22b187430748f82842daba92283dbc4bd20636b6754b20a7127f01fcfd4013a1155e4746dbf3ca1f34991fe7c39ed99bdf5760d39db8e6c428f2de8157be0139415aea96bcf6fab633f2257b582312d3c7acaf6a5f8e55ad699672160ca01246545059e58502e28199cd0f5505adcb91900a283f0b059f33d1a8b352010a3c815717fb3a9482c946df0c74a526353d5c9ecd2590c5050996393a02286841580ab599bfbc8838a53301bb11d5fd492af40ba26224505969d88f6b193ea42b0348954180e17124ec2c64b962a92aa9c3fe2d72f94301531c4aaf847243702bc8f9c37d64b54f20ac003b844c52417e1436d2e75ac09c313c83b8575e791a7c95d0412cc61521a6826997561485dec26ad7baa8e065e9a279add7301c5c74c5b95c1b6915ebe390596bab505e51b3fc147af616e0f94506635a758964b3e7cc067b80827db21dc87450fe1415ee41fca8a2b56b355fff13616622fd1a19a7cd98f5084610d1ac9f1b8a6e78cad9281a0afa5a7c2a9a87916710ec9c5b3544b76b4808d01399f219b745962536026c79841f11961b63c10c99074edbcb4ed786f7e8c3826609533e5bb4cb80f3e515299eb757c217da2806d26664f154c0cc2b4a644b224933502adf5a66f5b54cd45a71589219aac65be0623cf5b4c0df17e72cab64b91bfbd903d75e164e2a0c9e2c997f36a0b432177de617f5e6746bd82984bb9375b4a0a12e96d06045a3a984667d03d8c08cd980b59cb2b0983b13f9c53790fd43653e78255882f9b0c980ef6b062789332a6b67b2b78e9e370b78181531846b9980a8af905fef403f47b891a6b440ee71cc5d6bf3ba5c7b087a31123ab61ec9f2d0c89e1eaa7dac36613a15f147938d32673402164b001975d9c4a8ba5ce84d20b47f26eba5909183c6fe1343d062389b9b99cedd21e30d5841fb68f3450a47f4c4be5e8c413c37ea4d5ad629141d7430938158cd04492bba8aedf7477ed13a0b97c8217a300dfcb22de05449547626d21409f491098162d7ab477e3ebaf0e15124f449f08e47d8ec6847a0ac839bc5d237b3d509a8b5c44c8fb6705a467a3d4d9102ff2b6ed976ca9d856e9f257d5d586c7d8a4c2617dca73aaa65719a21538d9e6997c5637df8c5a2ab98a169a5ba8f708bba55f2c0a9463c9b4ef0c9822fa64ecc72c8bda4030157bde5073fae6a6e6f036121125dfc5a9dca1504a1225e6da9db4d0665f6413386153ae25be78b3410369bbdbd84a86c6c7bc924dd70005bec0c54e07b4adfa2daeb8265dd98bcb8968a2f683a3b07633aaa0290550665c01fdeb22398aba31140fa7494fd6a0087194673f51ac7d759d649a2fa4d7520fc67138f445287b681f5c3d1678b497129bc6624163e3515c8381e85c173d6a4cc0038dfc2064a213c557931e2e7138fa1a6bc3eaba08965bd803bd5759332cb1bbc4c41337bccca153905990970c261cf63a53204b6f8cb228d4234f08837425a82f1da9be43775df88a20a0381f70044c76b3524b437cf365cb131baa14ea6f24502336762c8e126afd009e1997b8b3bc20c246070df7b33bc9a7bdfa8ccd576925968915f186ca4a5a4934528dc75282e246b0824ef7118d39dc1f07449a218836d47cbb7365b677ec7d6222abaf33068b5730d9e674cc008125226cbc5382a76a9823db1b42976c5c90c23bc02eb7b874dff93699e6035a838b22a7126aa42d62682505f9bbc77143dca061f5c38e99652fc2e28e30ca8d62127af02186bd9c95602992e20baa636ab050ab870b11c52da19b3a68b7a07a8cfbe7bb016a2537e50464265ff6f065d7a8c30f659998a35d79032f887b4629d07bb2dc895f09ac0387cca9c5cd1aebc08a687798721f24ca43c2c5ad42d1b6641838efc2a72ef210bad10218846f25da336a4c00c4a29eac8a608f2261b8c76b18f10b7aba755771376dc7b876152f9fba5370262919511d4ad50d76aa5cd6566c29225dabb3b668608d9de5bac08320cfc3570a0ac8deb4bbf3d941f9325aaf546fc368af005caab7ac6a7dd70d90506ddbb5f53a83079aba0927bd52a68e278d3f01ac19eba6bd065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e279238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411 + +comment = Official test vector 37, seed: "d882ba69ac8bbc88715f1c6387531f53273a5dab87e66faa8221a7f628d2bdeee1cbc59c0e08d0add84520a3a70c1389" +entropy = a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c +expected_public_key = 99315a88d083bf5196f65cca4541bd4ce3526e514dccaa8ed176ba58014bd0ac486056240ce06c6c182040606dd98978d6cba367eb0ec18401ed348743780ddbd277f2ba22e1b34208f215f8f91a048ca497ec37a7663587ac85f221810e64acf87478a101062535287250907d0854b93a9d4bb39cd5788be361c00faa87bbe078b26353a51b7bdba58d17e5496efb263df826a59296a13535abd799cb931fa5886e35476dfff97e82870653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b27243c42634045506762ab1817534f419591b04622c650b828b3d4a66d9b163d09847bd172ba8ff452759184c07b11183665c0185e0a089c957135dce64bda52338b6492a27a1238aa567f017dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02901b73885557cba188f72ab5a35b489e98ab377691033934029118a34af7d176a436139aab3ac127a8f510c8719936e8676caac2211c8292a42f274c7fa85c542b21422c5790079f34a26f0678c005818bf4981a2b4c7db780c0bd43ad55c0acdf1ae0e0761d7527813076f3174a1d49c74659a453e09c2b4468de6f185d5f3c04f2b7e59e05317586e743285e6817283ca11faab44271a4667912df262c0c03843730acc24e80e2ee0251cca86a83853e6251e3036714576b1c171a112e7a15ca215f63039aaa7632ec77880b89ef8a45cb0b3746202ace1d7221fc98afb73a28a6ac2ae443f16e6072d6b3da1a3be5fac533a9175a5f176fe131f021795f8880d320c6096ab63f53525d01b32a2ca90e1a9138e4ca72502785976bee4e566dc0cc1f3827733b0a7d00cb58b6b89c5e26d2da00429a2450e269da77c46b5c954cee6bdc0339ba357a9b9951802a255b74a4f4ca1297d124056147a0f8123eb903071546d2c22723367308601a22f199f9588734fe1241450a45fd7395df965f46574a030581cc714a50c08da03a51b367b524a2ee4e56752db9b66d9c6b07702ec23bcef798d68300859383c5baca9d8f08b71409ae5552209b5237e697ba55328a1693af7fa0ba27020de2c35f643514db292c061c8e2085d06c101644c94d17c07560811c093afe61c6b4ffb970382ce9fd25f76c6728108842b3841dbbac62504185edc32dfb817c45878189a7ac02859eca77ab445797e030e910243b121a859a05d8caa3c32fa54d033714d20a771c7cca73999f6d91d4db4683a9543d3c978f1d56816d75590642cd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b8290078e2c0ac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4127a214e5532884274646b91f49a1e36a3b42cfb90b27425d2645c5acc2482289d0b4b84a6359007f23b9f528718e6c499590d6bb2a5bb674e89561ab1a48e3988927ac41d05ba143799214701b2f6d708d365be84baa60df8bf7d969a425c93452a0277f218790c80c60b4b59fc6131e7865d1135ac84a6655507c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4152c005ecc44fec299094a285ff50b09388b6ac3972911cfb8ecc9f0ea58761741ed23ce16fc02af5a341f65043f0802c0353d987c718fb72d3d922cdc861bb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984 +expected_private_key = f8fb5ba9d24c8681558cd13593f0cebb335b6f65bd5dda6de6d19e09f15165051f981ac6472b263cec43883a79149707093066fc129ae148b04f860c2df119f8a51056eaa5dfd89bfc564226e56dc391ade1cc2a1df58edd4572c5a147bbe21283b97f1b213bc276a471b63a7df1cdc86c7a69a34ed17a425b37aef969c1cd079529ba29a2e2c3412c5615e23523f3124c00c778752bb9b3677b90885cc21b0e257bb7f335fd53928b737d19da3b3208219e6c898e96b45f801135a09a1425a0986c597e2b4042c1a4e6d7a4d0e30e729c73f2bbbe85b579c3c13a34344a7403b95d425936486c3b602804c08ef6f5ab22c400b9523ea3345abfe666023bce6a1b63a872c33e3aaf0ccac2c40a4d5a48107d0c7ab09001ea67ca6f4c1fa7137d259c860d032c396bcbcb4177f82439852463b640855ce604f91c8f2e4a0899b2102c6059dc077d5ee6054355c546c2148077b8defbc313c71f1a420dace126b16c21e40064e2522f9e224cc8e3526b1a99a2f4a81efc2dd3609043246d461c7c1af025b56a9c7e72adea57584cf044c2f0bb60352c32400d1631c034572ee46b71edbc0334031aed7bc26af543028c3918109da52a6abf3217a2219c0607ba9edab5b4daad5ec7948393c4a670c340688541aa713b596843e5ccb9616b54e92610539bfd39159fab36d4928ee9cc8b1291ac0134257e242faeb595100ac113ac416ff517866021b550b6d063512dc37477117d025964c95c13535c2f09a96740037fe1846efec4446ec03f93fa6b6fd8b539f0196444a61823b08cb74b7520618c08324f0667f142beb3a34c2c5286b3d159fce3b046079f07e558ba28a8893a8c94f9711c227fac6900114c8bb6aa5369b059dbbca008482a1843b62a1b06c68c6b2f40bac6f02b6cac1633055a178a396ef35f59f1a76543953d3b07e2b8be217c5d5b1a82f9c080f4119d22275958026280bb8c96626c1d0baea6658a29546e09418aaf85a121f8647cb4789484bee0189b9ab10852c397a2e25b9b15b71ef17440dc3554db740289ba05111979614aedcca79699021f4bc3a4c68b39d0256d88cdd7a24e3ac31dac35388720671a12a765d705f8429d0891c3e0d8062ad45a0b882bc53016dfb007d1c550998963d7e12fa51c7361d86156ea3a8ad7018c627a9ea18f9d3787ab3b88a27b3f9443aa87ab75eb1364a4c66c50e8170892a08fd15cf2913749d0c61305c4de45a1ba2550009726a0873c70049705009dc8327be3610f61f9bc60a26d14dc0c3e67cdae4b5ac0d5a0638804d6c6b4ceb351f0c19f0974324cfa28fab704b4677aa3f2bf65686c22100b74cb9ab5f7215452cbe8d6909754304573a9314b3c8362cfc34c6302b3cbd5dc482e76576fc5900b367016c03a860a88744928cae55413231ca8a5008d210cd2e317d1bb6bc8624ecb83002e66092d8aa77fa0c6766532178a8cfb532c70f1114e5156e91486c3c7658e2a22cf0a77873c944a5a4bd70ba1686146e18b328d30813c9850c3003698c5afa2082b3425c785200596592fbfd7b2ad5568f9d278fa24c523251bfc966a69ca882e707426563d2e099295305fe2e2a96f968a92e9423dc4a1f6662f68299899315a88d083bf5196f65cca4541bd4ce3526e514dccaa8ed176ba58014bd0ac486056240ce06c6c182040606dd98978d6cba367eb0ec18401ed348743780ddbd277f2ba22e1b34208f215f8f91a048ca497ec37a7663587ac85f221810e64acf87478a101062535287250907d0854b93a9d4bb39cd5788be361c00faa87bbe078b26353a51b7bdba58d17e5496efb263df826a59296a13535abd799cb931fa5886e35476dfff97e82870653d5c4ba09c2658a9a22838ba0c6aaa4ab7b19699b8b27243c42634045506762ab1817534f419591b04622c650b828b3d4a66d9b163d09847bd172ba8ff452759184c07b11183665c0185e0a089c957135dce64bda52338b6492a27a1238aa567f017dffa796de84532fd5bec8fa800ff4c5e34791cc5aa02901b73885557cba188f72ab5a35b489e98ab377691033934029118a34af7d176a436139aab3ac127a8f510c8719936e8676caac2211c8292a42f274c7fa85c542b21422c5790079f34a26f0678c005818bf4981a2b4c7db780c0bd43ad55c0acdf1ae0e0761d7527813076f3174a1d49c74659a453e09c2b4468de6f185d5f3c04f2b7e59e05317586e743285e6817283ca11faab44271a4667912df262c0c03843730acc24e80e2ee0251cca86a83853e6251e3036714576b1c171a112e7a15ca215f63039aaa7632ec77880b89ef8a45cb0b3746202ace1d7221fc98afb73a28a6ac2ae443f16e6072d6b3da1a3be5fac533a9175a5f176fe131f021795f8880d320c6096ab63f53525d01b32a2ca90e1a9138e4ca72502785976bee4e566dc0cc1f3827733b0a7d00cb58b6b89c5e26d2da00429a2450e269da77c46b5c954cee6bdc0339ba357a9b9951802a255b74a4f4ca1297d124056147a0f8123eb903071546d2c22723367308601a22f199f9588734fe1241450a45fd7395df965f46574a030581cc714a50c08da03a51b367b524a2ee4e56752db9b66d9c6b07702ec23bcef798d68300859383c5baca9d8f08b71409ae5552209b5237e697ba55328a1693af7fa0ba27020de2c35f643514db292c061c8e2085d06c101644c94d17c07560811c093afe61c6b4ffb970382ce9fd25f76c6728108842b3841dbbac62504185edc32dfb817c45878189a7ac02859eca77ab445797e030e910243b121a859a05d8caa3c32fa54d033714d20a771c7cca73999f6d91d4db4683a9543d3c978f1d56816d75590642cd4aa7d9e9c709c6cb5aea8832d7c84c576afbc837b6615b8290078e2c0ac9a8ccfa8338b36649b9f7c41d0064dca53b8fa1793cbdc8f7b75306f19c4127a214e5532884274646b91f49a1e36a3b42cfb90b27425d2645c5acc2482289d0b4b84a6359007f23b9f528718e6c499590d6bb2a5bb674e89561ab1a48e3988927ac41d05ba143799214701b2f6d708d365be84baa60df8bf7d969a425c93452a0277f218790c80c60b4b59fc6131e7865d1135ac84a6655507c1d98f6665c932093d61fa578e7acbfdf49f2e15c138bab4152c005ecc44fec299094a285ff50b09388b6ac3972911cfb8ecc9f0ea58761741ed23ce16fc02af5a341f65043f0802c0353d987c718fb72d3d922cdc861bb6a8ae003197c8f9c878a367c021db7e9273fe2e03a2716683dab6caed5c770f6e7984ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd1291f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c + +comment = Official test vector 38, seed: "6c3aff39f5d097096d882f24717718c8a702382dc4aaffd7629763fda73c163cf084807bbb0c9f600cd31a7135f48aec" +entropy = 952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed +expected_public_key = 2e7240107059c16c3eacf4a1a8342b73911db6a51d3cf12bb168229a1b29f7c334d0d1ad99932f21babfd8153bae937fdd2393d9748518f12689ca7627a1041d868094aa7440c6724b4430ebd20776b602940c9d1fcb5a109978573434da891962b645002508e46992c0c148f5a039609826baf5834ba7271c443b69dc5110c4b7089068d16202cbab2e1e4525738a19c8315fae806fd139be91f4c1e192a2c04983291340dad4018a8a83c27a57c622408f933a51b7618148b16375a80e0a901f10aaf6e7803cb2a693abcd4ca8bafb942086f42f6b743937098e3d2a607f212f766603c9d89accf7ac584491f230bb1108b1465b865f824215d79fed2525d7e95c7976946e22a9e6510afa2a9e8af29ddb65c47be8820561661050b70ef3b7bb249b7fd0cedd688c37d7a3de667626c2b389b38be066089405703bd51fa32199e9c83d5265bd62a2aa2ce521b69973a18777e32151d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64c9d00e55d814536171496037036a078d026164d7b07e3277b7ecaa770b06dd291b9ad29241c3bb43553bccf66a1dd81fe2e2bf79f1a21e1539d0bc517a9ba8ede2c39deac4cdb7c65ff96048461ba2e350017095a35c1bfa25c242b000affc8af29495a2d349133c343d680eea815cdcd89c4fc283cd5136b89abd473b4aefe2228f4cba5e0c10ec7a1083833735f081034aa7bbf20c11319ca263b52262096e505c45805e73619e2ceb242e559883d20dddd4120f0c9e49f4995376284147cc2d2a96a046bdb3f56b6dc1889976ae1ed732eba43af5941831b2202d6091c16b680001a82d98ccccec212b79b5a884756c75cb2545316fc072d903c670864d5a13534e545d836276ee594d3a7841e5f91d6b738d97e73a7274671d6470cd2719b0515fdd67c6e4969ad213254502c5ac9ba23c264a375237369b46d0c45745041a20511459d3321ee9b395978f2c575ebe1c6caed03afc7027bc457e03f527b0ccbaec71850e0955f0a2b54d9bce69b6c8fbf90850168adac411ad5c973b578424c55ce01b3ec2825b0085232469968b8a96fe7b9f26846f789323a15aae6397242a712cd26b0465bc038a4aa30dac42c0036c062c21c3a4178a0c92b8992cbd54a6044b789d943f1eabb0bb24c3d0d4c067251779374579b27c84fb435e6c745334485fba84676750a27c520f79366d008e4be93fe8a958e8d06b8ec323bfd5bd01e86b1f13302eb17aa3aa8fdb3445ae5775111b2124e2a35021c04945661b2c510a29264ad855836c7d8eabc069011f8814934bb4b32176c0b59b04c5fb6cdbc8bc41b0bcfef4423635c0c7ac43e4d5286c74920ef37c951266b92074d239b2bd0a0d6c096141fb6a718a213a3387d75b927ce176169738abe0cfa6b68d3b064157c3cb03c5793a7400c1960351b059e43a7f1b28ae5073780cc606f7e40aeb458dbe95a31c23af7e760001b0bd601647ad1805c4329e46f490575ca928fa908b5a30fd31520c61c9f1cc5ef18578b350a929164de33b008338180ce41c45327152090a91b8c9b3928c2629a48d78abd1992720e841a52ca91a15a1c7953d18b4ba1f990af34ca408ba2d449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a1 +expected_private_key = 5b47b61ce23572623c431a498e378c6b71a5cdccb58e225310217f6f2b1b7140b97349b965d9c95332a66d7a9879f24c479851a0ea485254755db347bff9a06d00502ae3a910c06771aacc0a51add07a291496ac10e2899b6562dcda7b6b9b7eb516335d222c43498859d87a44cb8ad589a06e609fc5798ca06744051533d5c6154608c790a8abd776cbd2984b57e1cf4e0638c77915dd89249d3c0775b45cc159b44bd32f49a51a1e398763e35dbf5c6ccb100929c9b91047a1ab98a140e00f77f5076310c33179a8c80449591c4156c244eb8c8b3009328139c18f8c59e1961a2b91c840d552c2e4b3897265b16c28de6abb72d218ef713a1d179cea38561663c9bf21b68166aaa45748316877a9a5bed6f5230d3015193aa5a9e1b34dc6576b57692b543fff321b14879a24728de3d6a297c06ac6cb28ec3482da708abab28fa815272624af6e26a879f65c6432812470c52de01edce20681db43a967069dc9bb34f9c540a21b8d7322a3675fee059f5f655cfc480ba31255e899c48a7c25588303d67055434702ecca24d31a9d69796df408328912ada084ab122c6ac53c3c349c105270c9aeac73923614ea9129ce4c9fd8d78bd33045d8557ad3d0a698b34a7c073b93783670662f8558375647747905402a6aabd1698d1d3b430ce8b5ee8665771a34ca73b2dee04497c997c9e74044230690354b7af23bd94aa02cf599554391095c0d53f5c1db19ac33189b2b9aa3c48bc4e09bcdc5029bd3b45a370c59045abcbfb257ddf30085da053056c17dd0b5ddc6494524875ac189e6c7a7cd483288f03abc155bc2022eb427b7d5093f4616c124b7c29a0043181c7bded83de7592511e3617a75652d4568d7c7b3ab2b7464c514ce6ccf54fa8d73e61834e534966620dc59196ab44b736151a27c02e065a000611542fc296a69a24989331ef980f708142d7274ea863669a52039b59d48b90bcc75ce4b434f5751cef621cf3a29873c003a57276128e70bb4aa5de581834946741a8134890491d37b6051959739fa8eb81c6947141704683124136c1c382760e13f00c59ab5bcbcef98b973831b91ba87fec02216619f012859faa6b01b1649786b626348182398226cf794095681d1c25800b18bf33cc71123898ad2aee46905a8118916ba8651328a051697f8041667789c874394e96a0efcda8998d420684217952496ae9117c6c618513c147148979f5c8bfef8c7ca1836430c3cfb66b17cbca63ed1a2157961cee600617157aad986b5021f4f69c3bee6ae181a076c3cabf076903bd59814352f4ee2c04a138ae0eb018a2193ced58981caa3bb032317499e6ec4bc5cfab8b389467ef295dbe7305bd1cd099364d7596b1801008ed734d7775c5606af0f1a2978733dd7f55556dbc5fbaaca5a95bbc287b6d3a43aa9b78ad10a025f46af233512b126230cf928fac14d753160bad961bdcc4d5e1b4edd241609a0adc6b3c6cc9660e5371d6c1655b4465f16d535adcc54f8376371b758cacb81d84a7b3e6b8754b430c0753982a89d5ca8b2f4244aabe0bf05f75ed0b092f332aa83808f897ba21906af25e68a88b61a357a10ece1977199203e465ef9bc020e145f6421abd11b182e7240107059c16c3eacf4a1a8342b73911db6a51d3cf12bb168229a1b29f7c334d0d1ad99932f21babfd8153bae937fdd2393d9748518f12689ca7627a1041d868094aa7440c6724b4430ebd20776b602940c9d1fcb5a109978573434da891962b645002508e46992c0c148f5a039609826baf5834ba7271c443b69dc5110c4b7089068d16202cbab2e1e4525738a19c8315fae806fd139be91f4c1e192a2c04983291340dad4018a8a83c27a57c622408f933a51b7618148b16375a80e0a901f10aaf6e7803cb2a693abcd4ca8bafb942086f42f6b743937098e3d2a607f212f766603c9d89accf7ac584491f230bb1108b1465b865f824215d79fed2525d7e95c7976946e22a9e6510afa2a9e8af29ddb65c47be8820561661050b70ef3b7bb249b7fd0cedd688c37d7a3de667626c2b389b38be066089405703bd51fa32199e9c83d5265bd62a2aa2ce521b69973a18777e32151d3d5ba1983c8659a79ac978ffa15ceab733b49ea8f7a853d4b06cafdfc64c9d00e55d814536171496037036a078d026164d7b07e3277b7ecaa770b06dd291b9ad29241c3bb43553bccf66a1dd81fe2e2bf79f1a21e1539d0bc517a9ba8ede2c39deac4cdb7c65ff96048461ba2e350017095a35c1bfa25c242b000affc8af29495a2d349133c343d680eea815cdcd89c4fc283cd5136b89abd473b4aefe2228f4cba5e0c10ec7a1083833735f081034aa7bbf20c11319ca263b52262096e505c45805e73619e2ceb242e559883d20dddd4120f0c9e49f4995376284147cc2d2a96a046bdb3f56b6dc1889976ae1ed732eba43af5941831b2202d6091c16b680001a82d98ccccec212b79b5a884756c75cb2545316fc072d903c670864d5a13534e545d836276ee594d3a7841e5f91d6b738d97e73a7274671d6470cd2719b0515fdd67c6e4969ad213254502c5ac9ba23c264a375237369b46d0c45745041a20511459d3321ee9b395978f2c575ebe1c6caed03afc7027bc457e03f527b0ccbaec71850e0955f0a2b54d9bce69b6c8fbf90850168adac411ad5c973b578424c55ce01b3ec2825b0085232469968b8a96fe7b9f26846f789323a15aae6397242a712cd26b0465bc038a4aa30dac42c0036c062c21c3a4178a0c92b8992cbd54a6044b789d943f1eabb0bb24c3d0d4c067251779374579b27c84fb435e6c745334485fba84676750a27c520f79366d008e4be93fe8a958e8d06b8ec323bfd5bd01e86b1f13302eb17aa3aa8fdb3445ae5775111b2124e2a35021c04945661b2c510a29264ad855836c7d8eabc069011f8814934bb4b32176c0b59b04c5fb6cdbc8bc41b0bcfef4423635c0c7ac43e4d5286c74920ef37c951266b92074d239b2bd0a0d6c096141fb6a718a213a3387d75b927ce176169738abe0cfa6b68d3b064157c3cb03c5793a7400c1960351b059e43a7f1b28ae5073780cc606f7e40aeb458dbe95a31c23af7e760001b0bd601647ad1805c4329e46f490575ca928fa908b5a30fd31520c61c9f1cc5ef18578b350a929164de33b008338180ce41c45327152090a91b8c9b3928c2629a48d78abd1992720e841a52ca91a15a1c7953d18b4ba1f990af34ca408ba2d449f94385651c3b4c0503726cafa118167110e848fbed995526b458d362061a12fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c7262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed + +comment = Official test vector 39, seed: "cf520b92a2e3677afd003ec1ec6ef136a709d78f828c9c0dd4946efbd451c5faabfc83ca66f9d3d17ee4220553b7a69f" +entropy = 3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 +expected_public_key = 45fc2d1bb1872a743763f12d29d937f3f2a41d257531c1172af59c90806c7e5a15972a8cb9dca049bc92700a72b4fa5a739033437c946ee062aa86c12103b557822a08084be63c4c74d1b92608c3b02c6520b2991f8499470114fb659f89a937a25897faba6c0dd142d8d4868ee3c6483128241b287cba0ae49430dd6a28d1339605a4b750e6029f73baa1fa8ce6219c36a40e5542ab45cc781a613fdf416502743df8cbb3c4b864d0b448a20c0b0942a829601f2b131fb038587a99b80ef44033061b2e4b8f9a12c3c03193506b62aa1c7ab08569c7d0a88c8a098f87061ee41000fd202e2c3af4e625b34787bce55f74aa58eeb9124de7089e51a581893354b36fe035ce5fecab74018ee6209b75fc2702429c932abf71d89b8c82c047d77725cb6ed98608f2ba0b3462c1d428352c6376f6269d9869aff4bc821870b63f2284d296677b6145683ba6282c12c72512ef015eb19ba86b3571be7438f17311655c118a530266bbc6d9d10636b6347c630607864949dabfa558522c100f6c7941a076109253b5ffd76328c99590f48b3fc7ae7a5847cc958fa5523f540ab54ea0a302174e6c401341759c121b355c9280d2ab6a84f9028634bf7e3ca90679aca188667d5086df35b88d95b262e8478561a414b627f43b0fb8731d3bda73c6396594694a9f7024cfd55d3ab88342516cb34a922e6835eb8c067bd35ce0b3711d7bad2d7529464c493adc40d8ec8679c903e8984850034ef4a828d3fabcae9474f7278cbe79c8e5c1c948b94798d4c68da8255237ad8b0b38cd4a8dfde5abf6b2cfad98a677a8c40e208206774661490c3c212d23327a46a23dd6855275b78d29830b23900b13c638e31b4745a917d4fba95a04956c371212e475271ccf94f6295346118806316ec01d08454b0cd922d6f1a3e4a651a7a931f380042a09244bb39973ec5872c28c8d41c4bcc72ca4409a363c49995c45c7909522128c03814612214a5eb01527b67bce4463202cc14e31225b36a7d7d10e26966beb389877ac0062f9172c0517ca8676f5a44a10106fe75a31a4aa86688c075918a4d8a7461dcc1ea1193913c259e3b44c2d976ec67613468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cb514bf7178e14112c8b31727a38bdd20a5ad087746768957f837179d50d25f6697f4a88d056451a593e385b74de8a01cf0244e70ac9ae36b2d76cb91e5419165c6507d141148869d6676f28645653bc78c96b9e7f382cb0c6768e2968c513c7ab076928781a6530cd3ae3286b0c681743a58d9c524be5120c880605bc139f672e30174095932a000800d58a926cf40873c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaac9f0344c9b6bbb25cb0aa084f616332197295163989e1448784082c327075dacbb7d912025e4786710b0c7452f827aceda11a73ada09c3e54b404419dbf3a8f8b6096a73528dc50fcd230155a97a614663174683d1095d97b7c0e994764df2095ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1ba061302ba9cc20cd46f769e1021c03c43ab07bab1bb0c7f3426d252a15ed5a27854ca7b177a6f79502789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e134 +expected_private_key = 2c021f19322a908456f1677d31dc8a4a2a734a2571d19c421c47aecc507c3c53a931113290b693afd1b7ffeca87cc90b0419c48bc4359d64146d9932beec78766408f59216c692228fe59b768c92f4d5a3ccfa6a35599da2695766d754c1f682ab13c8966997f37a74985551c36828224c177d3a3ade3c2c20a907c830bc32906df70b021b47c38c606ef951acf7c1512ac15fc0d761c9057a7db1ac6c56198f9a8ed2f67a0f159a5ee6612109254d57745736cc3cdb634f5658fb684d805888fea8582135bd4890343a545e4e0a6f0c130b8539125ab06358f8bcc0a4b44a7a4903d018c960ca45779bb564a30cf1b340b4c317cb77da50bf899c10b4676f3c295b90e93c2540a9e17c3bde560f351c81c58b545306449585718e9199a6302e3b0ca1e737c07a4b7e21ec154604590d415f4b82778778905360cc2e49be4b08c94a744995f18959d4492f0b7a3f53a98f9a8d914863b9583d866712fe583fd2677e8a3b8ba5341902178824f4c41ba21cbf7a4b666acb413c31cfa744b9a5405efc5b53a2c64481270484134753c1b0407e23b95850a8c026843643e42b329bcbb7422df5cbb968b04f39210a4ec959e1b5c9cb32a180588b9baa690f7459b1282d9e9200bd1a0e910a3efd948c3bd0af04d866edc61c866b48d7aa22e6fb5025c6892c66116e271b998b888e0481abda592c8b36f7464704fc22c51b5ba995928fe03594a8073ad790798aa304579822255e61d11557092bc9b5bd4c94068c60b2940c180831c5167487b7538c9ab47dc268215c8c7f324563d3973fa73bbaf07c771b15070d880478d2693535425fccae0f8272cd7224f3795a70241d480425e4a74922309906e1c11c5107e9f34fac3536354100f911234d55769b763cf2408b9812aa6b7c2601161953cabf0733cd3af819f5158a136621fb159db3dc6c3f3220adb8acaa8cccb7cb2ee583b9909c903ff43612d178c568aa7e9217e345cf4daa9aaf17cca1b5a4a5a73ce9b0581e73bcc019bce2b68c8c273dfe588ba0861c5a73a6edd9bbdd66935af04e5ea81a55d62c9a8c51b3e6a402587ff4f837c16380aef5640f333db08a6cddb425cb4189ed773d8adb91e2708f12b78a0105bffee30873c1b6d5d5469f6464705741ec4310a8185a1553372f6091c769109f19527e95a6802c2a49127077b21126e7531a5941298bae199309cbe00d97513bde1ac82292ca1a76957d20a306932f83994a00f21d89519e16138f0477667f338a67450e1248a682142a79d9ab6b58b88754362a32af3402d062a554ca8a40da0481ba721a9b023da71987b744c6b9ab5e80830f8b7200241007f0eb72ae3694ee92814df4b1db269f4404cd0c77a844d2b751f5a0bd1cb93d61a628098d0eebc941827f77139831575b98e47b7dc3676d887b56d0ad96bcaa1f280049776339cb3fef6489dbd26205530cb08c53fb0839b49909864ab06b2c3fe15957dda96ccda90c51904df02c6a1e5846f892a1683838b9760ab900664a1a039b6a1c75f9c4b05340ede9881f48869dc881da0191e24bb5aec448ea052e57e69edf254575fca87a1b50e6d39520630688b04328a70ca1a871ffbcb0a8823dfd4747dc859b45fc2d1bb1872a743763f12d29d937f3f2a41d257531c1172af59c90806c7e5a15972a8cb9dca049bc92700a72b4fa5a739033437c946ee062aa86c12103b557822a08084be63c4c74d1b92608c3b02c6520b2991f8499470114fb659f89a937a25897faba6c0dd142d8d4868ee3c6483128241b287cba0ae49430dd6a28d1339605a4b750e6029f73baa1fa8ce6219c36a40e5542ab45cc781a613fdf416502743df8cbb3c4b864d0b448a20c0b0942a829601f2b131fb038587a99b80ef44033061b2e4b8f9a12c3c03193506b62aa1c7ab08569c7d0a88c8a098f87061ee41000fd202e2c3af4e625b34787bce55f74aa58eeb9124de7089e51a581893354b36fe035ce5fecab74018ee6209b75fc2702429c932abf71d89b8c82c047d77725cb6ed98608f2ba0b3462c1d428352c6376f6269d9869aff4bc821870b63f2284d296677b6145683ba6282c12c72512ef015eb19ba86b3571be7438f17311655c118a530266bbc6d9d10636b6347c630607864949dabfa558522c100f6c7941a076109253b5ffd76328c99590f48b3fc7ae7a5847cc958fa5523f540ab54ea0a302174e6c401341759c121b355c9280d2ab6a84f9028634bf7e3ca90679aca188667d5086df35b88d95b262e8478561a414b627f43b0fb8731d3bda73c6396594694a9f7024cfd55d3ab88342516cb34a922e6835eb8c067bd35ce0b3711d7bad2d7529464c493adc40d8ec8679c903e8984850034ef4a828d3fabcae9474f7278cbe79c8e5c1c948b94798d4c68da8255237ad8b0b38cd4a8dfde5abf6b2cfad98a677a8c40e208206774661490c3c212d23327a46a23dd6855275b78d29830b23900b13c638e31b4745a917d4fba95a04956c371212e475271ccf94f6295346118806316ec01d08454b0cd922d6f1a3e4a651a7a931f380042a09244bb39973ec5872c28c8d41c4bcc72ca4409a363c49995c45c7909522128c03814612214a5eb01527b67bce4463202cc14e31225b36a7d7d10e26966beb389877ac0062f9172c0517ca8676f5a44a10106fe75a31a4aa86688c075918a4d8a7461dcc1ea1193913c259e3b44c2d976ec67613468358886a9108acc7d0c6a25f5a991d7c53b8638c24a585f07aa074b5a2cb514bf7178e14112c8b31727a38bdd20a5ad087746768957f837179d50d25f6697f4a88d056451a593e385b74de8a01cf0244e70ac9ae36b2d76cb91e5419165c6507d141148869d6676f28645653bc78c96b9e7f382cb0c6768e2968c513c7ab076928781a6530cd3ae3286b0c681743a58d9c524be5120c880605bc139f672e30174095932a000800d58a926cf40873c44ae6096940a3bdb6e7966595bb3d23c9915bc7e29aaac9f0344c9b6bbb25cb0aa084f616332197295163989e1448784082c327075dacbb7d912025e4786710b0c7452f827aceda11a73ada09c3e54b404419dbf3a8f8b6096a73528dc50fcd230155a97a614663174683d1095d97b7c0e994764df2095ab7bc029b7dda3799e5a88ed825cf1674aee01bb0c17a5c84b8ac1ba061302ba9cc20cd46f769e1021c03c43ab07bab1bb0c7f3426d252a15ed5a27854ca7b177a6f79502789842e229637fd32a677f68dabfa371062d8b8ce9dfe0d90bf06044ac3a840ceb626b16e13486bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9 + +comment = Official test vector 40, seed: "197e5d562de7e01bed4fc597db28dc6efdf0179f3a5bda5f94caa39d67bae730540534d59a7a06c8448f628da8b7859f" +entropy = 588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 +expected_public_key = f6446774b30fef5b426f563962cc29ff78ade42b497dc3b970f1b848b1141d7a5f45a37c25b125aed61863f22732a06128bca08efc8cb176ab6343239b572e1c8c138d829810227afaabb81cca0a73131155377730a120558231e8f8a598a2b730578edc7800b0d6c5627530ee92930eb2b40a9888cf648263b688f0a12e08f004f4bb449a25282029cfb73c32f8d31229d0a58e6aa08698517fbc5f619837ae3331cf763631d305e88c8f85413e9d5420cc282bad24a783011184011a79a3b305db5b3032b75c55907ca5c7f839320028305c439c39484895212b1e87925999681819416dcbc7ead45ac2b1262154bce16866c04561eba2c9ec6022b07a57a67c7b901b5da3bb8025c7585c86bda0810c442c39374040236a82884199159729834663d3b1967df9955de3a387d93d50f5001924c4fe433d016bc2b6614f2d3ba72fda226864ad6ba5b8c31681dc104348ec2b29c39fc9f567cae17bdf1c6e215c92effc60e2d6a3a3106bced0bf301b542f7987b582b0780b6d398631eb8559459b1db01a0443100dcc731291c737499c2f86452394c0b6662401fb57a4db232e40d1b0f2511ee1eb15dbf7b603e2a67808c064fc5103fa7c9c954fcd12bc619582f82590b323698a328cc14acb87c217e39c309421c7e6ea15ba6c3bd8587126c5aa02c26308c9912d7262dbb91ac2c2cdbb9cb009a3ae10761771740b2e6558fae775deba7a66086859270ec07b584334900c278002d8a47d01547dba3036336616a8c12415b86a1423a6c9aab5f085c7fabb6355b3db4023e47c7917c10c284333110bc978b2c08e16512ba95a07237cc35c97bfa51bb1b25e30750e65664377ba49200aa6e935b4c7451e547859edf03bcfc6904df05220c02f5e576604a873ee82b7693b962853b5522a5b0986348da63df86a64671737c17201ed556e92acb56f065eebd31bef43ca85db1feac395e19110a2f0c5b90459838cbf779c27247709765569e5a649bf160301003169e4ac2baaa4c4697f25869ab99179f9f792d9b19df0c148df7c6b9aa20e63426697d83a6e33b35f4c7e798175bfd73ce60a050146a3d893c4dc9b2fabf5960bd80fa0679433bb33bb91915e93c1eb2aa16cb13e0b9870fef99835a674b1bb76946bc4064cafde3063498ca30aeb3983f5cdb3a6b9c4970459d969f4d8b6ba27755b6ca8fbca178dec28dfeb2ac03318be7002a9a4cd7b1749a7fc7f09a6b560740da89baab8130872510c99630f3b588069d50a9550c97f8198b7a46148fa7ac1580632db1ef49528f9125784a5bb2757235fe44e74529a7ce88e91543b2ff81d9ed78e2647aa07033cf3422d34942e7830191b104c7ed56b8951a9c8706e4cb33cb0b918387b869084386420c13b09be75d2a5e9276246b674e96bac7782541e1ca441e53ff3b9c702cb95ceab628d1617704a448ef743e8b811fe52c659cbaae22377f28646c45642a9886628c9b73c510bbfb645d4077c1d8b954bdc8b707b7f6bc4701bb1af0f28b88dd282b78b7ee96732521aa6180b6021aabb415839dc3a1f6f545c1320c58b965b62993abf6a10c18a22ce6a45539685f297b1f04a130465845d189d17552e2f4917e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c +expected_private_key = 47a7741316be87861aec518a9b38146b43aa54a98f47e242866b8d79f731d98c754b572a2a9170a7eb4b0d73b38d6665d1e43af0b61ab95cb54879707805bd787913ee369d231c600b76949bf86366579ab62724caa1beabbb02fc945bf007cf57a225afa67393cc58804a15016a12dfb90d5a52be41f907b1f2c4fe93712f555b0ae896e85931020089642a23e4c38581d4c40a46aa8ddb3c26db0e29fa5f7a12b6ca32cd2ab6b50327ad0dd8139ad83dce676ab2dc0c2774c86a2c72a5fa2d4dcab588a66d6551c040e91ae045698ac0a1dfb95048c545d08654c1b560384561ab07bd8c61182f99c79a2267c961ae66434321e8501d474ad84aa71286a948c5ad187232cf72576f167d63992f62d3423ce75577c2052ef84019404b0e1706ba704fe3d116a518293112b8b80708c094bde829ac38e362a404beb67026ea6782362035cae099302c5660931ce31b93b665059633699ec44c28c2bd230b1942421f12388900081618bb29e315beeaa090a06ac7feda567fd1a12d1a41eba931c279acdb875d9ddb7cd9a6adbfb32239e843012a8cb91776775408316b056fbc42758772c1e53ec0344479c2791b837a6a34aa77710d35593a55e57572fa99711bbe5a83454bca7990e834ba285a09aa11666cb2b2f39704904354687d0524888cf6461ef302139b042540138e322453619b3dd715b617230e08c4585478f9996798e9b47c712f82ba45857551ea4c79b4a0577938666403174e84585e684783d33f3b701420f66d48473fc6bb627b399e90697e760783a3e09d6531cc524568def8507f0437314488af7376bf2a6bacf783b632197d8565f9456d04a8476da8cd6c988d26a56d29479a2dbb85afc18dc81a8611bc4adaaaaa440471b530053adb874db67102b6a64ffca8bf8487e18b2f7582b71fd78d85f819c24b892741a83e67585b6b1ae5ab6ad1f5cc02ab78d0ecbe01087f46ac9bfca464a4b9ca817c3a1af5cb0a6a3f1dd3a2ec06774e805e001b44c8194660a280d0d59bfeb35ebe9c943e626b98e488f8984275401bdc4959993345c38bc801b95d56bbb47a2b23f5f1223d5a0e2a827d4578948cfc5432627c9586275679202e3c970fcc980af56757912080072a4af234dd030ec481a6ed8030921691d6126839635c6b270497ca4a87d4bef47cac60752383712636752a4aa18af13bb36ef445fe653628704e4dc2cadd62839f9842f9b2c264ab4ff648c59d15708f55ae4a396d5f4bc75d20603c03cdec4252facc579a0cbd1f64a734e8350f03aceaa2734de2b486f6b93c36ac11803e564070aba97d2309078fb43768f98ef5d03b09fa10ffbb0beb3b5fe01310065508100206a640b93de87bd94a634907730e30800803b233b95d1cc7cce49c08ab143734347f3459a5be0230f9481d50b4b835a91736d6a7b351c8082a4d080967b43b0553835bf52943a380051f48c27823c5aa0b20b7b733dcb004b2a7819beba4b3fcb1f991789c2c57ca01b50523214af309fdf421187492c411c14128744bf4a83599a30b86194473c2bc9222fb4ba34108689aa8065aa24ff3559a76f759768c81a8cc5aa2a6792f3033b2437b05068bed096475d9280bf349f6446774b30fef5b426f563962cc29ff78ade42b497dc3b970f1b848b1141d7a5f45a37c25b125aed61863f22732a06128bca08efc8cb176ab6343239b572e1c8c138d829810227afaabb81cca0a73131155377730a120558231e8f8a598a2b730578edc7800b0d6c5627530ee92930eb2b40a9888cf648263b688f0a12e08f004f4bb449a25282029cfb73c32f8d31229d0a58e6aa08698517fbc5f619837ae3331cf763631d305e88c8f85413e9d5420cc282bad24a783011184011a79a3b305db5b3032b75c55907ca5c7f839320028305c439c39484895212b1e87925999681819416dcbc7ead45ac2b1262154bce16866c04561eba2c9ec6022b07a57a67c7b901b5da3bb8025c7585c86bda0810c442c39374040236a82884199159729834663d3b1967df9955de3a387d93d50f5001924c4fe433d016bc2b6614f2d3ba72fda226864ad6ba5b8c31681dc104348ec2b29c39fc9f567cae17bdf1c6e215c92effc60e2d6a3a3106bced0bf301b542f7987b582b0780b6d398631eb8559459b1db01a0443100dcc731291c737499c2f86452394c0b6662401fb57a4db232e40d1b0f2511ee1eb15dbf7b603e2a67808c064fc5103fa7c9c954fcd12bc619582f82590b323698a328cc14acb87c217e39c309421c7e6ea15ba6c3bd8587126c5aa02c26308c9912d7262dbb91ac2c2cdbb9cb009a3ae10761771740b2e6558fae775deba7a66086859270ec07b584334900c278002d8a47d01547dba3036336616a8c12415b86a1423a6c9aab5f085c7fabb6355b3db4023e47c7917c10c284333110bc978b2c08e16512ba95a07237cc35c97bfa51bb1b25e30750e65664377ba49200aa6e935b4c7451e547859edf03bcfc6904df05220c02f5e576604a873ee82b7693b962853b5522a5b0986348da63df86a64671737c17201ed556e92acb56f065eebd31bef43ca85db1feac395e19110a2f0c5b90459838cbf779c27247709765569e5a649bf160301003169e4ac2baaa4c4697f25869ab99179f9f792d9b19df0c148df7c6b9aa20e63426697d83a6e33b35f4c7e798175bfd73ce60a050146a3d893c4dc9b2fabf5960bd80fa0679433bb33bb91915e93c1eb2aa16cb13e0b9870fef99835a674b1bb76946bc4064cafde3063498ca30aeb3983f5cdb3a6b9c4970459d969f4d8b6ba27755b6ca8fbca178dec28dfeb2ac03318be7002a9a4cd7b1749a7fc7f09a6b560740da89baab8130872510c99630f3b588069d50a9550c97f8198b7a46148fa7ac1580632db1ef49528f9125784a5bb2757235fe44e74529a7ce88e91543b2ff81d9ed78e2647aa07033cf3422d34942e7830191b104c7ed56b8951a9c8706e4cb33cb0b918387b869084386420c13b09be75d2a5e9276246b674e96bac7782541e1ca441e53ff3b9c702cb95ceab628d1617704a448ef743e8b811fe52c659cbaae22377f28646c45642a9886628c9b73c510bbfb645d4077c1d8b954bdc8b707b7f6bc4701bb1af0f28b88dd282b78b7ee96732521aa6180b6021aabb415839dc3a1f6f545c1320c58b965b62993abf6a10c18a22ce6a45539685f297b1f04a130465845d189d17552e2f4917e924cc0d2dbc2ddc739f6b876472eb12ce233ccd402ddef61523fd6fee69a88f34a34c29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4 + +comment = Official test vector 41, seed: "f170583cb451d8a45d105457c02c01a33a40350616ed8515bd49067142f61efb00f07857e4fff3fe11e7164c648c76ed" +entropy = 47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 +expected_public_key = 5fd557f7434fcb61b199e793c5e763764c48df412acb7c756e1370cd117f8c10cafb39cbf0c8c3f5dc8da1855203d02b39647856b55c38e944617b8348d16a8221962a42398fb61978f40328c83a0b49bc843060d1711e289434db4b5b0838cd87949df5ac0727d8a528b8b5bf30ccb9e37a6664050cc5880d34c13ca42c1779b8d098c5e0876627c17a79b6bad44a9a38c56883d97cf2d2b114a1c4f1a502ab4a9b7b5398d9e73e543b860f87062e27a9fd1a2035185f0d98857b0759bf1c39a41984c8c1a1a9027944417f84cca0dd4206e9133f6eb6a989075d004accd9f57cdc928cd455443f0222dcab9a8890004c2596efeb06903b5d0af33a88f14fec760fc074a3dcdc744e9864e7ebc608a56002e483e60b8202b31377dc7f5a486d5a060733fca9836aaeeae05909c6b6b0db4531271fe4f3548bd5bff1e92160321218f963081c518874c0cbb792fda4513f7902be6547745a0879ba6ccd7c0f73b123dc605bc7995bdd14b018d8278c8c3966aa87a24b4a4bd3abafe0c8173c028df14daad39c288943eac139210392bed70c38d7af7439697be96977d23a27cb6e7de7b785673c9d1b33a081a9cd417129430c6c6300c496b04e1796c9c781e4211915162de147501b7bc55f8913c66c5cbd209ba6d115f753ba739417c8eb182200113ce17c935a0622dcbc674553b9dabcda17bdbfb4865d58143c149512cc2e74a2b508f67be8058461252d95042f8b7641e1d85161521b81a616a02110d7ea3bca4723d003a4db1673d64273b34c9432ac981a0c01dc8b8c0ed5a05d20c5331831ce56014ab0732b301ca2f8569fc061ddaa95d63667b9acc7a1ea656f821d55a31b41f32dfb3b66ddd5cd2155438db6923069430b61c85ab309bf56b0ecd990427c1b7d93991e783a647b1dd66696659b5c926485e1642854f0839033138a3a54c349c138977275e71e0fe985493cb85e0923095804037462ae248780006d0778334f664262e88498fcbb22d46d4f4291bb90afbbd40fbf2b302415cf195542dcf3375e78602fe1067638ab995b70e6dbaf7b75bc11701207e489f361512b590a860401a3facc1ef1375d8b64e0e5c7f863786d3984710c2f55ecac578c41170194d832929075671b814fabf45c6e2bcdf8c0cbe2954c5a414e3f8878ab68ca13189d97f316517abb4c5187dbb03413da654e650ec1cca0bc9472bd4bcc60ca6fcdcb26e77a025eb70ec0e60e20b19d30fc261ad11d3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a0531315dec20d9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceeda5036c31a897b65612d2b176e9648352899bb2869f48b1e70c1ff04864487258526226a7dc64306b6838f4286b9a81a3193f5c9c711dfc5b9fe79bc6cc14c934591f93860b66511aab061295af186b8ceff5772fe50dffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b159a1c84c85d717824a0573cbf219fd9b2a32ab66bf8a498a04aa4e22509a5057997b74ab5a1b27b96656bc194af08114551709a41142b715c6e167e5ba5945729bfa702c236073fdddb4ceada972810253d642ec094333c028b0af40ce2e29993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a +expected_private_key = 35e4451348cfb9a06f1836296178b6af41a1c0196f26525831c081ea779e6b8c4b3f150afe2963aa756968358bfcd47d76415ed4294f02a843f89b87d6803bad504a9165b9bedb0c946058965b64bbf953e719160b53552c100d251cc9c111837e0a7c4c043ba0777e53b39f658b41b5f8900d4721268a8ab868b15a12c3b8f41316dcbe117ab3a027b8fc2cbf3566569a130d6db132ddccc5eed69a392bae8e4a7bd6c9708a48badebaa79fa1ac1e729eee0399803a374d3733ae501f1a846cd2f5166dc31b4d53750bcccf937b1ca43c3a6cd5601eeac251f9aab8b2489e22ceff436f1142ccd1bb17dfc75db6125a1a433325a5599fd23b49bbc3d1b9195b984303735f9f2646efd050097ab23a8aa5569ab744a934c2991ba046cb012467d39c3936eba9cfec4268e1a0eea559980133b4121f9d5a603e092c199818c057b7c841a7dd00af2c0ab3637878a9ea90bf377874fa38bf290fea6131345340857a1a53d4bdd9201b99fb628d975a91001f907a2e9ad37c9b99b8af915070339fdf76125d9556b1716cb74a9f18092afd887880526fd82cb002ca49e879c50e33af2e747104674eb1f30859e3c22f3aaebfd30fd672b6ab855928c4085130488540c8cbdb832ae25249f46b7178af9769a4b359664ba48da4a746c215c58ac2752e43835b5c2a9ef0a3fca159d29038cd60cd60f5bf508521d3d59c4f083653264776501b4fc62337fc37562973a1f9bd9532b4bdb25c21597a11e17096b155cd43c76874c44f25c1aa1bbcea897367536ecf4124feb6cdf2360cd5a082ac03b5e94232dfb44e1f124fdf65a4bd03b16ed729884065d77135f1f730a7a91fc2eb43271c0b2bfb8e615c07df54041917a95b0544e8513e8c6060d14c0fb802c0f2680051341960654f3594c9972c08664b7bd30b2f031827307b95fc525a2632c2456041b1286d6f175bc0b41942e8b8be69bb364a11ab4cc199f20aeb516ced1acc1f4b2b91b860331677290c643bb9a00b4b65644592c5ca5bb19b25d2a7080cc32b08910c137946a3fab6c8e31a1e97a4735a5c0a239b073c6e056053cd6498117497870718d35235019b3ee6050dcaac31a27167fe35ce57586c364c13bcc7587ca066c6e05673e2ba0186281d94843df10bb3a93c05025c0c691a0c41b229a55b7b506724026c4f1b48313788a212b0c951783ec9447e64314e878734ab59401923ada0586225c7a5c00a5f97bb76632dec47c15c06c7c20090c790404b3044136c79f46181cb1123a7d3cf969b72f6cabe063a35774a60863267b1ba34b93a5d3db25fece84a02429a9d142ed897320bfcc114391bcc097a078b04bd9356113b3cb993c19384886df182e37ba659d5b8bee24445411e318cbd092b8f8e53c63bfa3896a2cdbdc66e27f25c83fa85c260a34fd6cfe6872172f1361aa125e6c5c6c902cdec68708c14c175e910cf002ad647a317f78f52f76bae006a3aa51780d37a00aa20c6a532281719c5ac88641a9d15549088b5a4dda23f443335abfc5c2f7c5be2a142740cbfd612a83af271af0aacb43833b56295b51a885d798825c3a2c04b399c528530ca24117b6e762c7b6527b0509b5963b68560015db4d4895fd557f7434fcb61b199e793c5e763764c48df412acb7c756e1370cd117f8c10cafb39cbf0c8c3f5dc8da1855203d02b39647856b55c38e944617b8348d16a8221962a42398fb61978f40328c83a0b49bc843060d1711e289434db4b5b0838cd87949df5ac0727d8a528b8b5bf30ccb9e37a6664050cc5880d34c13ca42c1779b8d098c5e0876627c17a79b6bad44a9a38c56883d97cf2d2b114a1c4f1a502ab4a9b7b5398d9e73e543b860f87062e27a9fd1a2035185f0d98857b0759bf1c39a41984c8c1a1a9027944417f84cca0dd4206e9133f6eb6a989075d004accd9f57cdc928cd455443f0222dcab9a8890004c2596efeb06903b5d0af33a88f14fec760fc074a3dcdc744e9864e7ebc608a56002e483e60b8202b31377dc7f5a486d5a060733fca9836aaeeae05909c6b6b0db4531271fe4f3548bd5bff1e92160321218f963081c518874c0cbb792fda4513f7902be6547745a0879ba6ccd7c0f73b123dc605bc7995bdd14b018d8278c8c3966aa87a24b4a4bd3abafe0c8173c028df14daad39c288943eac139210392bed70c38d7af7439697be96977d23a27cb6e7de7b785673c9d1b33a081a9cd417129430c6c6300c496b04e1796c9c781e4211915162de147501b7bc55f8913c66c5cbd209ba6d115f753ba739417c8eb182200113ce17c935a0622dcbc674553b9dabcda17bdbfb4865d58143c149512cc2e74a2b508f67be8058461252d95042f8b7641e1d85161521b81a616a02110d7ea3bca4723d003a4db1673d64273b34c9432ac981a0c01dc8b8c0ed5a05d20c5331831ce56014ab0732b301ca2f8569fc061ddaa95d63667b9acc7a1ea656f821d55a31b41f32dfb3b66ddd5cd2155438db6923069430b61c85ab309bf56b0ecd990427c1b7d93991e783a647b1dd66696659b5c926485e1642854f0839033138a3a54c349c138977275e71e0fe985493cb85e0923095804037462ae248780006d0778334f664262e88498fcbb22d46d4f4291bb90afbbd40fbf2b302415cf195542dcf3375e78602fe1067638ab995b70e6dbaf7b75bc11701207e489f361512b590a860401a3facc1ef1375d8b64e0e5c7f863786d3984710c2f55ecac578c41170194d832929075671b814fabf45c6e2bcdf8c0cbe2954c5a414e3f8878ab68ca13189d97f316517abb4c5187dbb03413da654e650ec1cca0bc9472bd4bcc60ca6fcdcb26e77a025eb70ec0e60e20b19d30fc261ad11d3c0c56ace53de82c6a38ca5d59e9c24568b7cd15a0531315dec20d9cc957fcf8958e3747471a8d944a6678f6ac8a8763a1759b3dc83edd18ceeda5036c31a897b65612d2b176e9648352899bb2869f48b1e70c1ff04864487258526226a7dc64306b6838f4286b9a81a3193f5c9c711dfc5b9fe79bc6cc14c934591f93860b66511aab061295af186b8ceff5772fe50dffba4f5256522b5c7c55a6ba9b13b615fb3b3bdc4b159a1c84c85d717824a0573cbf219fd9b2a32ab66bf8a498a04aa4e22509a5057997b74ab5a1b27b96656bc194af08114551709a41142b715c6e167e5ba5945729bfa702c236073fdddb4ceada972810253d642ec094333c028b0af40ce2e29993369eb7ddd07164969a62466b80918873a4ea56cd80a8e559fb30f6cce44f1f8fe60a286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611df89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92 + +comment = Official test vector 42, seed: "44a6774b2cac02dff210ff861a090561a453db311f47b6fedb81811872d5d9489f5fc4103010139ae53fcaed209dc9be" +entropy = 610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd +expected_public_key = d5f135d06aa99635c9b53244e1f898d8494b681312bfd243c8ea5b7e71ccb7a5386e477d01fca3ef4122a63934843450a446caff55184d052923a393fd887df6b045659cc282d1424b19b17cc2a2384132eff067a0347f88c6b392aa56a3519a440438d3f90f6941112124c91fc31187ab0ce6752d9b336a1e230f97837a657599e253b7798c912a66a48314447c352b84590941355c6bd1c0951374105858a46502ef39cbb58b8e63a64e2b99c4825912155695893a62af6745e76058d551a946161f25f1b8fc045602344a7f342facc50e9565c1d59a459d34233c1921ceac6e0bd936b496c8fd6a619d8b0649eb458f8943eac97293635092666688db559d255ce9f280227755c3605d6ed007ca718527227fa1f40dbcd88792801d8db6b2374a23178a72276c790f902d7e969f2686c9508186788905e77132dd909397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca64918370809d3b1b70cb09641878e7c0a141573030aa2b687761bf43ac89a81e73376793ecb32db53368ec9e079172e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca582017892a188fb2440ca7240c3c22577230b59ab8ec038bb95cc49c2a2f59a4a22c0c482713544fbca9d7404b3a6ad86e8764a601b7084289858bf62a2828d3091ff015089726ca23b1ca0f87195ba1abf80b01f101f8584c15289196744500000b431a60267174f2cc56860bc5ab4ec20d19ba8ed47535eb42fe1d33f2980ba211805a3618f2ff64d1cc634caa6b40fd23615538366dbaf41971d8b5857298c1e406a293c1b8b7f4a499a97be8cc51b5382020ea9c7cf809fa7323134290fa461218f4a6f495caba2d1511ea48b7e0905b0465f7a6711f2716b17dcbb4b9a1b31933d7d3622315c79f3f11a93c8058fbc01c4839a808a5d2d45b99f7918faf52db1d81d669c7988ba7eb8847187ac7b76404b1a139dc4e4917c9b4e29833fd9fbc36e4bba96e25bde691ce0c369ace7183c762bd04785efcc6b614165c014a0fc4b64b24b3b46418ac5b6b7bf69cbc75090b69aae46b4a12feabd4e134bcaf14922367b50f17976c6705e175ff34612cf7b086ed733deaab0ca815a53c99b2985963db89bdc284d251340b0e3ae20990ee93344dea18063db6ef4374a331244ede00b46676475937a9472c82e124b1751a9e4203becc77ace092b055abf0892637b39c3a9a011219c88139277b8bb73b9508142421939380acfc2b81523c72e923609a0505e2979e086ab85f9663e549f3350a694458ce7b02bd8716c0f8b8946a21d99d97632952bee898989c1adeb710e15bb25b0a22be598a65465bf2b899719d00f9d16367e9436803ba8c17b6b3bf62a10a017c177125396bf6745163fe24c455319cea69393ccbae42508156167b28a1d1050bdefa5a789bc389031bd86e72af5f5bc80a215260737839654998295d5aba8c11a5417b55d67201243393b7593400d46cca1d321c027bfb09cb08a1738c88b7d47e876ef7517f8d96cc1c93b9e93b7062227a55996fa958a684aaeda89587b015a6b336dfb610721298ac6ab713f3a2e37b2aa7b1ccd2a876f03c72546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447 +expected_private_key = 03a941a829c025261f44172acf806bea5b216b58bab845328c36cb925a5169d6b1ff141ba44010ff2c1a446113c443c6d98ca879e673cccb84d5519067619edf59c23798b9b6bbcdc0d49df5f4b21563ae54e287dcccbe4c53c62918a6a213c460eb8c92377cb57a1b6d6467d40297fb90c6907b6be5b03db314c3ad5b2f46999743ec7ff0b055af2b2753695395c6157c60115e183dda398d136806b7017bb4fb4f36b7653bd17cabd1bffeecbaf2eab65b853c710820818b05afb86388f327fea6c3562a027c610afd9c0bbb23a571489120c2baa0d7aeffd196b2dc8b40d4016fda16062512a64462fe806d5959c49dfc0c9b2955e6480b7af0011edb2d44c6a43d08b5f469656cb9396c9c640bb077cc24ac0f293bab4cbadd998ecdba31534408b74420cb432826cb5dc8224c48159626053096063841153f723761f83315629c945778a24f826a28a90a5854ba7e80c48e44929eeca17e28304babcd0af4198962a045292f09ab5b7197a685a67d07ec9769b69e64ea1457fb8e1a70b23ac4a797132b021244944143e936c6e5d840494b674fdc9aee84a091175f8e3121150b1375e028d0ab6b709a443f14c56ab67e3a8721a4b698eac9615fa12c0e5277e4a412508446ed4999687ac5ac626ccf5468f3e944b8d099fdc319337c85e5024a0798556cfabfd47a40146691d32c0f179b5bb3c3088f2cb29e2b961b630610d1528fab952dc75d23339c26a38f68421c12c2360f369abce128cd64551ca29455e02aec7c359cf9182f5642f1bab42814aea8f2844af15670421e0e113063b4b8c614487f6b6236dcb21e48613c0635e5f6a6a6e070fb665756f98156c65a6f407e1014bd6540a92e8a09ef6c944db876250b951d16332251c5bb6b79f88928adf6bef819a241068b08337136b8bdc33476fddb0292b68ede75490db193e267bbf2f8459fabb17d10bef7018ae895995200453065ad45457e3e86a12c554db3617a99613767598031c86bd5815585444dfa41cbe068034fc0a1cc2636d010230870776d2645db640b409a292acc909aaa11d0d05a1b1469ea2673020bb7ebc7381190c271e2cf73d37f61f12c8389843b0540117c7ab924c140d1409f701ab0c0596103a1aef3c93a2a79be19c7870abe83232a7de265a1a1280d30490ff50c414a006d8a403c50948da4b1054b18be35a8f9252079c5acb2104bd42ccb51617839e07380fb3a62b3a5080295bcca410215ab5c30a89b727363185363027bb1a6b09fe83233d79e4527371ecc8b879c81a25b3e6e088d2e786976396ef8d6c383495b52eb69bb718dd7facf5f120303ea259fb2bc32a5269ab45e6bd8ab9f9456a68b869a4c13a0b6c98dd1bf276572efc9a31591acb33b9945919fd20495db284bd4ba7c66620754e58396c0a191f20304b545aa2279cbe62d08eb4c82e60569598147f9910ef70abf792d375420bb999e4a9cc28db0193a124d0cc78807a54d13933b25b350a16c842e4b31337bc7734104fe564c20f27ed6ab800717baac4a9c954c6ec5238bcdf309c6fc497a6a9b9e4973d7d44ea53b90db26912ac7796c327d24d3705db5bd0266b17b145fd8ca77624c8eccac1c209073b2a639d5f135d06aa99635c9b53244e1f898d8494b681312bfd243c8ea5b7e71ccb7a5386e477d01fca3ef4122a63934843450a446caff55184d052923a393fd887df6b045659cc282d1424b19b17cc2a2384132eff067a0347f88c6b392aa56a3519a440438d3f90f6941112124c91fc31187ab0ce6752d9b336a1e230f97837a657599e253b7798c912a66a48314447c352b84590941355c6bd1c0951374105858a46502ef39cbb58b8e63a64e2b99c4825912155695893a62af6745e76058d551a946161f25f1b8fc045602344a7f342facc50e9565c1d59a459d34233c1921ceac6e0bd936b496c8fd6a619d8b0649eb458f8943eac97293635092666688db559d255ce9f280227755c3605d6ed007ca718527227fa1f40dbcd88792801d8db6b2374a23178a72276c790f902d7e969f2686c9508186788905e77132dd909397f6b6bad3ce77e8cd4c4a3b9686cac35abc86d57e911cb58b0c997c1935ca64918370809d3b1b70cb09641878e7c0a141573030aa2b687761bf43ac89a81e73376793ecb32db53368ec9e079172e9aa482fd8652583b9155683da3467e4546f26ac98371487527c37b6646ca582017892a188fb2440ca7240c3c22577230b59ab8ec038bb95cc49c2a2f59a4a22c0c482713544fbca9d7404b3a6ad86e8764a601b7084289858bf62a2828d3091ff015089726ca23b1ca0f87195ba1abf80b01f101f8584c15289196744500000b431a60267174f2cc56860bc5ab4ec20d19ba8ed47535eb42fe1d33f2980ba211805a3618f2ff64d1cc634caa6b40fd23615538366dbaf41971d8b5857298c1e406a293c1b8b7f4a499a97be8cc51b5382020ea9c7cf809fa7323134290fa461218f4a6f495caba2d1511ea48b7e0905b0465f7a6711f2716b17dcbb4b9a1b31933d7d3622315c79f3f11a93c8058fbc01c4839a808a5d2d45b99f7918faf52db1d81d669c7988ba7eb8847187ac7b76404b1a139dc4e4917c9b4e29833fd9fbc36e4bba96e25bde691ce0c369ace7183c762bd04785efcc6b614165c014a0fc4b64b24b3b46418ac5b6b7bf69cbc75090b69aae46b4a12feabd4e134bcaf14922367b50f17976c6705e175ff34612cf7b086ed733deaab0ca815a53c99b2985963db89bdc284d251340b0e3ae20990ee93344dea18063db6ef4374a331244ede00b46676475937a9472c82e124b1751a9e4203becc77ace092b055abf0892637b39c3a9a011219c88139277b8bb73b9508142421939380acfc2b81523c72e923609a0505e2979e086ab85f9663e549f3350a694458ce7b02bd8716c0f8b8946a21d99d97632952bee898989c1adeb710e15bb25b0a22be598a65465bf2b899719d00f9d16367e9436803ba8c17b6b3bf62a10a017c177125396bf6745163fe24c455319cea69393ccbae42508156167b28a1d1050bdefa5a789bc389031bd86e72af5f5bc80a215260737839654998295d5aba8c11a5417b55d67201243393b7593400d46cca1d321c027bfb09cb08a1738c88b7d47e876ef7517f8d96cc1c93b9e93b7062227a55996fa958a684aaeda89587b015a6b336dfb610721298ac6ab713f3a2e37b2aa7b1ccd2a876f03c72546b861e351a73036f4b363137340efa7764c439f68d3c8e0723683aa8254a66284f447029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585ecd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd + +comment = Official test vector 43, seed: "49e1855588b6235df2a400c4a70aedf8ab17b6e5e2891aa745f132fa2e7ab0c8117c1df37c39f5d57624eb77c2b4a091" +entropy = e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c +expected_public_key = 26ab73a3355199a1833a1268a37a087ddb57ab621046db1f407c804c488e4196048ceb762b9024c2157e7dccaa1a762881280715a1467e766dccb159f4780a39bc4f4a59715700070318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa913052119904745ec68cf3502f4663bda74522ddd61a318539e10a853bc90a5b06aa12018c6bac4a8123719c567719cb723b420540ebcd84c2787f37a76c6c40fc983436c26f7fdb14df17062be752af2c1f1cd1026856500f3831cca75eff7a08d4d9c819d295674550c1c951ff9a0155856c3cc143824556c09025d55b0db7192d969926c18912bf5ca8629401b8c53e23832cefdb369020583b360595541f48573ba1557fd0c1058a8cc5ea7ca7f092b7dc7b4b04490fa4e72a37aac0e33b1746aca327258d9d29acf140c5f70b8f94a23195d60d30a498259c6f9d06bd69f82398953b4fd39adeca972851431b59c9614b7867cb1228e2519ac130f003903d801f70bccd776a9b916684cd89cd71723ca732a21fecbb90d547646b987155cf5425abbb2406cdc1821afa8da120a540d1c3af175032444e1fd85f43f47903665be922636755b5e75a90931c66e89345f57ca4a032959bdb4521cb62bb1377dc5c99fbe36c71347b81a80b6b7251fac3732475009a719f4374bd5ff01cce4601e761a754e05756968f33fcac4d6a540d93951d0bb4d0d838a3112872020c2dc67718888dbf408941b877eb6543432675c879aa85f102e608aedf267e32d333ca9c3860f907f17b553580aec75902ec304e6c7996ee34061b40a9f4f8ba2ccc55775490dc9c2a6d5c0134e809bd305d7445c9ebf7b89f9604146b2e55a1090597033bab2a25a3886dc524f4908adbe98dc2d74386806ad641712d9c23a19562e4ac7f57a86fc98663e455bd963c4e63d8471b504c14eb718d8bcd6475cc45687f55099f8fe2035f3812f081b6df2a174999765cd69433e5312be67698346fa1030a40943f8927b2cd8a1e2cf2514333bce85a89a6a99d03c4a5c0b847550972f9d1448d1819b3582b99a50ff97c124398cff30967013c4dc4d374379b4e8b037eb0e570aec147a1c99cadbb651bfb576ad61bc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a192211b4d6918260c1251eaa1014c6f41427465609310d8b665c6763639c71ad48019905cc0874be438023936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953778124c2c92d29cbfedc21678e54861eca5cd350fa09b1365fb74435316f37386b9b510e2bc585da30a71ecc7b9913921ec8d8fba2dbc97807b693b1e306832507cac90410e0576611ba79c1ca9c0b106d0147680790ec5051798592d3035aef57a0174cbc70b435710c51695852841907d41a8180123a4d911787b674acb513c84047bbd5851c3e83a8a046062c06bd84397858241c95b8d8d2a2c53038856247506065a70a5a29b701bae1b488a68c2bf02472d86bcbfe263e7820902102c612747cd60344957a871c7774a0980b70b56f7bc45f8e2bd2085af080cb923b55640bab2aa2c30f206ccbad17bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923 +expected_private_key = c842401604c8c4c78d8417c804c2723b14733044aa2755897f65987951218361a07aa84d6af8a956454036b79e145c93b9d4b862146bd4db824cabcb61fb91bc306f851c9e93ac266e3c9e9c939be422b07e512d28503a6efa9d3ea8861e39b1ad481b8ad1805a8c0d48179aa1203c2ed7bb59d5c8ef651281c77f83ac7b49eb997965b161db025b47ce6e2c09edd41f5eab1c8b7b4d20783d60c90dbfe6ac387b629be10351868186f6a0bf68905f8c1cf34303fb577c25212919533c7044697d9425bfb76bd9d367f43b2d3613351d95395f4c2bae63b2a4608c69364f41e85d542a08f35b940fbc3b48f63360b50aa88259c7cb4634e5a34300c5957a3644f6ae381389b53210110329fc61519113c17e64782239941cfbb11a647b814372e313205844592cc3c17319b41ff21a0bda3f5acac3f18bad085c8f27b7758b7519316653ba9c253dc94ccad37f98d00b9fe67e2a13662c77921e4a9a86c8089682811e53a60b1089a1038483e615e6eb109a3b7636e02a44c2c3a81b96d84336cf594d24172be1bbb9c7b3685ea45e45b81d731b9b75ccadbfdb768119b20a0c346156cbcd5bb107a00a0e3c6e949b9db0b4ae21026c915908c5f38413c648edb20623f35b382b0cd5f4a8d7062bebbbcc9e809bdbb5c84042bce2e81bb0d795c6786af95a7e7b0629f7978a03558f98709a86319570273bea71986aa92560260d022569d4c98a85bb98aa198deff63dc6bccd1e6032ebab8caee5cf4717b17d89125c67a8a472c371153a4fc9045fd3304a74b983936060f42c80454a005342c1318a284bc5b9a71a39e748a94739536b517dac1619c00db64c81001acbc2793f9f29b42214442fba962f331d48c300da2186d21a4de61c4b5948c7edd1b9fa5865caf2280a81b9f7171137d6a678c92745b1aeb9db686ba84d65f6beabe332ff036bd113161fa068e74032ca5736d3ea3a01f1acfe067dfe5a5b398575bb9b148ee6155be2b4b67b348420ce758c5855102fd06a1fe8d347ef1b073f064f1f7926be5b2343029e5b7468e93b8abec6be231b6bee714031e04ed23c6da37032ecc00374706eff7453dd931d80029382f17e82a85ad7a8b25ea97d1d2aa21238b25517008b0400281168328b02869889f7f142cbf1ae8ddba5ef2713de649aa9ac56229494db211b90b96ae3b2829ae528c634110a3bcd355a243f3654295b0b79b9b7d43272321959b3632313aac107c8b7aeb83172778b7b199e736307fdf5ac6aeb40cfe750b7227f46a00b9000880d405877b63ff6c616bf4a51ca11c863a79b0e099308b42cbb7997420008268a3b762b9a5e181da14a4a92a5b55e7950268a9a83402889a98835cb9562a5a627750a5348b3398b39783009a081a058bbabcc7740af00b8cdbb4e0842c7f14b47ff4cb424b6252ccccee30398023a9b50b4bb4a2c1ff0a007a0a54eaf421fc2113f0353c7a1da6cbf3c7f5b448b86534fce3b3b82c3b82c3420bca7c865aa22461b3d95522e9792b37b78c5555a62a3439f3ba7646076111336079bb8352a286e542094bb58b07cb832e2b288021034ed4934469b1723e57e57e358942730196140f47658258a761edcbdc046c08bb89726ab73a3355199a1833a1268a37a087ddb57ab621046db1f407c804c488e4196048ceb762b9024c2157e7dccaa1a762881280715a1467e766dccb159f4780a39bc4f4a59715700070318c2ae03706b639f79a8a81af34fbf6c9ace4843151ab5c3cc81af08ce392335e4fa913052119904745ec68cf3502f4663bda74522ddd61a318539e10a853bc90a5b06aa12018c6bac4a8123719c567719cb723b420540ebcd84c2787f37a76c6c40fc983436c26f7fdb14df17062be752af2c1f1cd1026856500f3831cca75eff7a08d4d9c819d295674550c1c951ff9a0155856c3cc143824556c09025d55b0db7192d969926c18912bf5ca8629401b8c53e23832cefdb369020583b360595541f48573ba1557fd0c1058a8cc5ea7ca7f092b7dc7b4b04490fa4e72a37aac0e33b1746aca327258d9d29acf140c5f70b8f94a23195d60d30a498259c6f9d06bd69f82398953b4fd39adeca972851431b59c9614b7867cb1228e2519ac130f003903d801f70bccd776a9b916684cd89cd71723ca732a21fecbb90d547646b987155cf5425abbb2406cdc1821afa8da120a540d1c3af175032444e1fd85f43f47903665be922636755b5e75a90931c66e89345f57ca4a032959bdb4521cb62bb1377dc5c99fbe36c71347b81a80b6b7251fac3732475009a719f4374bd5ff01cce4601e761a754e05756968f33fcac4d6a540d93951d0bb4d0d838a3112872020c2dc67718888dbf408941b877eb6543432675c879aa85f102e608aedf267e32d333ca9c3860f907f17b553580aec75902ec304e6c7996ee34061b40a9f4f8ba2ccc55775490dc9c2a6d5c0134e809bd305d7445c9ebf7b89f9604146b2e55a1090597033bab2a25a3886dc524f4908adbe98dc2d74386806ad641712d9c23a19562e4ac7f57a86fc98663e455bd963c4e63d8471b504c14eb718d8bcd6475cc45687f55099f8fe2035f3812f081b6df2a174999765cd69433e5312be67698346fa1030a40943f8927b2cd8a1e2cf2514333bce85a89a6a99d03c4a5c0b847550972f9d1448d1819b3582b99a50ff97c124398cff30967013c4dc4d374379b4e8b037eb0e570aec147a1c99cadbb651bfb576ad61bc5449c5737bc4ba4a01f24aad80375acbcbaafeb564665a192211b4d6918260c1251eaa1014c6f41427465609310d8b665c6763639c71ad48019905cc0874be438023936856017b5562a9ee79686bcb55e04a38eb9b3bbfc07acd4865860a77af3b5acf7db344f139f79d5953778124c2c92d29cbfedc21678e54861eca5cd350fa09b1365fb74435316f37386b9b510e2bc585da30a71ecc7b9913921ec8d8fba2dbc97807b693b1e306832507cac90410e0576611ba79c1ca9c0b106d0147680790ec5051798592d3035aef57a0174cbc70b435710c51695852841907d41a8180123a4d911787b674acb513c84047bbd5851c3e83a8a046062c06bd84397858241c95b8d8d2a2c53038856247506065a70a5a29b701bae1b488a68c2bf02472d86bcbfe263e7820902102c612747cd60344957a871c7774a0980b70b56f7bc45f8e2bd2085af080cb923b55640bab2aa2c30f206ccbad17bc9f58c1cda80399962268f2ae99c43bbc1fa7d8949cd772a745bd9ab018fd3f6ed02f32cd2bf845923e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c + +comment = Official test vector 44, seed: "df0e41d2f6f86c1f79d31fd5878e7ab434fc0af3a0d5f47d2ab3fef31a42bd949b0e3629df9f575befbb62e829e51dae" +entropy = c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd +expected_public_key = bac16e6e3c5e5d9c8ca207a5c77c7883b917fe0463d3101962b802549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a6204903b9bc9311c66b907c5825621b7ebfb52f6c7cf75c169c17129595631a2fa95920317aad4cb338329adc69c6795158558638c474710c78763e012240cbdc2e586adf93c028522321a94cb766f9e983fb5110a10476ecba92fc0c120cc83632409940db249ec569ed5740471c86623b06962910307781349f342c759886f7c376ce708091019fc407eeae76409387d151c97cf7270319143471a84994bb596f9b5e1a78d33428740fcbab415c575e478db4b4e30771802e409b8c1ad4ecc9cec1b7396e664645cce83a40d512684e0b2750d8445d2180be5b4cfc09bc9fffc8d6e49b49d68c4d849b584512cbb55283722ced5566149811545609a4c5459f523c1c76667859760e690385f65768331b7654c30b8c0b26f2b8089a3c5b4f21eed42179c54ae61d22736512fa3aac6eb018946a47cd79acd545719c829b304477541ea92b10a1ccae8b36ba83d5ad83083fcb51df653ce899227c52581699b7150456cfa1910212f7678056a33755ddc7d0648164aa297f196057060009dea8d87e86b6abc0106a5536d7c83933ab12e294b4f50870fa0bea16ab49b88a60ba7790549ccc0e6571e81875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a5e295e3c3231f4132e1117b835529456a53d3d748c16280f4d597573685b04780f611094c665c66164a1323c290ba8c8b1031b142a3b53062ad5c59d8d112f9926e5aa591aba711ee2ba1509aa09b86c60a969020d74e238b849374bcae7788fae61296d5ac7ad0927ee30912c4287e3981b7851d5823295076365196bfbee4a3cc189020254f31b06fd8d70c43a94cf380c01936465a334fa59b3d39296305dc8b775269ee204639bb3a30ac437936cbd734a5c6477b2a451eaa0159e571bb12473b77698621d5247eb5012f608c6f070a67551f6f63abe87ba12a56b2b2dba44bf72e01c9a2c490579d2c103ce91a841c4f4b3aafddaa0cc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d1421aa91216bbf56bcecb89f11588b4085a62ba0a47ef9a184c2c9346525ce006ca4819857fac8b1498c9ca1222175ca5b01b6bd502f69f8977a0b3b04987a1897a8f2f20dcddb098ad070d15c15c099a5672c17087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c85971fa10d465970d61446f106cca6200f85eb2de2947bb4ec57e58c1f7be6b6fbc025a4a41eb05c516578ae9ba4c197b692d20976116ba35660cc5b612b616269a837012230b65f2913e5d0362d0b510f1272716a4dd2832d3bacc914929ff33354c01217d8a0745c9263b5d80a4f497d99d98a4d895b59a59a1dc173ca6945fa54c398f351c8c3ab8d66cb8971a68157ce3ce82104094fc83c7306d242f1f0497180842beb8e126988c5a830d2a39c2711b033490fe1d53e432c7a453b4ceb05a5644253797135231228f246bc6a1445efc16b2f2bc674327a62ec32dbc209f2c4a5c600920d2856dc34549bc4656f7953e697cea6f2891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e +expected_private_key = 0c9c633ff39d1c6c29f8356aa02981dcf189d6535e2ac00750c30b111a88b21024e4823e7d543614f30112f7c78f1679dab68b71aa992538658fd0c8e2984abdc09647453b3fd99dd860238cf40c9112a7dcb57e06540148ea4ad6f97020474afb65c5c67ab4fdb1515c6592941b1e38d4097155bd194b5324f464dbe678ece9b5f8f57822f87ed7f3a6b470ca3fea3314b4bb404cb66e3bbf8f2953f2682cdb65cfb47906b3962443775796564d75cbb4b9bb24a8a98d7723269e8204ba89782f974ae591808e97cb2468252c8539c2454041c9232f33b43ed8359dd6856c98ba4fc09e92f9a4ad497f8f1159e159b5af795ab09c20aa753931f47764b6cbab6968c7a779802b469abb1e7f677a0a485ff5cab2f028112ee8c35152703bb14127b33fb00a0ce21cc607e49a73544029baca215a67091a9ad89a408794c4d2da78557b1d31686c6b4c3749958efc60891f12c9e0b7c19613823eeab1d8f672089339e46c16daf0c3b7d53727605c26a723518a2651d8762ac373817bbddbec1ebca2cf91fa2a66896c55a4c946a791e5502ff19aa21cb132322bbfd127c10d87563028bc49b222e5401acdc81991828e4c111a54566e5724b40a452c0f4632b7b85f0445c881938134d516113560b0065beb409fceb25f796c0ba0ab190fac0214007916ca93c2abb11bd88553aa34c3c518bfec423728c86e529c300a1f70225f2f683911040ff9405614e1baac070e0e90337e134e3c93081514a937f9798ea7b57b3a3a0b829a2697b0778c802116c067a5c368576395c43d33882f97c770519c16426284e19bac180a2a6cb85d65b1a115316b08541dc231c123c184e82c691f20749a4b92f2d1040d09519df7678ac282fff9cf5124acbe04388ccab61bf71b87ab3b830a3ef6700a68b06770012424031e89a895ae81c8aca9169d6495cf01cd8ba0c27ae132c16aab0ebc4b13abb37d67ced10a0246e87be1233ff09a6802f6371858972d21b48d410d8cf3a8a1e664f62028cf851a134037142c20e8eaad7de32581b39b5d93221cf72124a73daa2b61f3d7c8f25a973a815b351206800bbcba60ac8c2a86a7758b38339751c23ea5523d84ec982a260256c69af739349d206ce9c9a70dbb0a950a0b63815994a6878711578bc22942914df8489ec5a09258eba796e8a6ff5483a71887e55783a94201e5b88898870e67d32eaab132519624f4b28f22e80903e591331ca792c0cef824bc62168be6eb8f7ba299bc519b0c370509e38377f171761521f8fc882d1b8d0db3c2109a43d1754f75529f7b071b7492b753688feef12fda217ccba484ab79192b7933781811986430bcc010b50a5621ec15dc7bb545cabc77c336892a0df4436e732b905d70769865cdee0a9906438e9d921f521862a3227bab93202da0cd19f6221bb68fda8155ae38132cf2a30a4a5c3dc0b17df0016fac3bdd56cd9d06cc8f2c6b4ac41207fc1aead0cd87506caf5c043941513f0a4abf725818c7686f0745ece93c23f2951ee263f51a3fb3630076dca4ea80a156dc6b4248246f638024b8782c9757e076ceaf18cc27284c321ba91766454640ad32d97e65650b39c9b23fa80405f8cec82abf70ea4fbac16e6e3c5e5d9c8ca207a5c77c7883b917fe0463d3101962b802549a87bf39b9bc7a30a5b654c9c96b14bc61506371e4768429db8f7c0a6204903b9bc9311c66b907c5825621b7ebfb52f6c7cf75c169c17129595631a2fa95920317aad4cb338329adc69c6795158558638c474710c78763e012240cbdc2e586adf93c028522321a94cb766f9e983fb5110a10476ecba92fc0c120cc83632409940db249ec569ed5740471c86623b06962910307781349f342c759886f7c376ce708091019fc407eeae76409387d151c97cf7270319143471a84994bb596f9b5e1a78d33428740fcbab415c575e478db4b4e30771802e409b8c1ad4ecc9cec1b7396e664645cce83a40d512684e0b2750d8445d2180be5b4cfc09bc9fffc8d6e49b49d68c4d849b584512cbb55283722ced5566149811545609a4c5459f523c1c76667859760e690385f65768331b7654c30b8c0b26f2b8089a3c5b4f21eed42179c54ae61d22736512fa3aac6eb018946a47cd79acd545719c829b304477541ea92b10a1ccae8b36ba83d5ad83083fcb51df653ce899227c52581699b7150456cfa1910212f7678056a33755ddc7d0648164aa297f196057060009dea8d87e86b6abc0106a5536d7c83933ab12e294b4f50870fa0bea16ab49b88a60ba7790549ccc0e6571e81875d5632dd8a5627e48e0395bb4c243ed9d53cce7b591949408d2c87a5e295e3c3231f4132e1117b835529456a53d3d748c16280f4d597573685b04780f611094c665c66164a1323c290ba8c8b1031b142a3b53062ad5c59d8d112f9926e5aa591aba711ee2ba1509aa09b86c60a969020d74e238b849374bcae7788fae61296d5ac7ad0927ee30912c4287e3981b7851d5823295076365196bfbee4a3cc189020254f31b06fd8d70c43a94cf380c01936465a334fa59b3d39296305dc8b775269ee204639bb3a30ac437936cbd734a5c6477b2a451eaa0159e571bb12473b77698621d5247eb5012f608c6f070a67551f6f63abe87ba12a56b2b2dba44bf72e01c9a2c490579d2c103ce91a841c4f4b3aafddaa0cc3d33d31ec3ffb4a3f9ab87f93494720d386bb13cc482a4adac46395479d1421aa91216bbf56bcecb89f11588b4085a62ba0a47ef9a184c2c9346525ce006ca4819857fac8b1498c9ca1222175ca5b01b6bd502f69f8977a0b3b04987a1897a8f2f20dcddb098ad070d15c15c099a5672c17087c6b58245bc25c382ed3bfd5ba9b8e48932a27546a089113f37e8c85971fa10d465970d61446f106cca6200f85eb2de2947bb4ec57e58c1f7be6b6fbc025a4a41eb05c516578ae9ba4c197b692d20976116ba35660cc5b612b616269a837012230b65f2913e5d0362d0b510f1272716a4dd2832d3bacc914929ff33354c01217d8a0745c9263b5d80a4f497d99d98a4d895b59a59a1dc173ca6945fa54c398f351c8c3ab8d66cb8971a68157ce3ce82104094fc83c7306d242f1f0497180842beb8e126988c5a830d2a39c2711b033490fe1d53e432c7a453b4ceb05a5644253797135231228f246bc6a1445efc16b2f2bc674327a62ec32dbc209f2c4a5c600920d2856dc34549bc4656f7953e697cea6f2891fd65321f89bf2d90cf3dfc681c2fd81792135e1938ca482ef3c253d8976201852444e79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd + +comment = Official test vector 45, seed: "d3c9ebba6eb03ccb5c9b9d2c8d7f0cfbbf50841e24396cddf0e56525b38918c2fbe6c34cc1b93f7bcd4f4d5777e1a488" +entropy = e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 +expected_public_key = b873b2397a7c7ada2f4b0b589ebc97c50174e4317ed5d9cf2878c924937bd258bacbfc83283a218d443d8ee43f8cf3c64459b189e6b3ad100a6c6a3ede9916f89b8bb67cac332c0519f502a4c427f5c9af1a16a59a2122521a0c624a20149765e986339ed63567cc29cff15d7e8ac026c96f08d6ac4e057db4e66361b18ccdc3bcffc300a996ab7346232db7310662c75b39ad7aa080b23763ece54960397b8de836071b8914d56f95a681accb8fcb9529e5e4cfc2ec0601f7b0b291524e180aa0a69fa74ac2f17aa88162c481f51543a5a527da5c42b59f9a72b14dc91574b51e5806ace3f022d1f19e3eb621560478bb70beb8407719a01e16313d2f0c785e3b9886f679acfa465ba974676c0689a149ac04996f4132dc4974f2fc322b56115a64b0b5dbb8dc71869cc655dd61390b032f062b024bb71505640a41cc6174b68870da11eaeac28ad061f3abccf4e12231655eaf9285b205251ea69371d90527793495835715ac005868a78b1cae80025426848c4ae869b52034bb266e1b97480aaa7a31e384780442d9933fdb750efaeac0bfa802e5314d28a17d374caa05b46121e16362e8341dd923a66872df3c942177b58951c40ad1641f53a53d8708ebcc22aac67ef262b6155007dc6880a1f45cad3a5312b282055b1e0b181d9b396591fa78dfccb9d6a92d5cf8189c14c68cf4238654716f0a1e4f2542cd35a7e4e2185814c1f5b16d8c423213c69d5958c46960b8df589c185087ec5474df3c5112b5bb6bbcc6ab7160abdc2ab28801d775caafa049479a837cfc8847763559ea86239889385baa43a2848b489087fb43aa20acd7ac05606767798500f9271271e52032f21fc2a82d8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851116c2cd2fa4671b95cf7e60bdcb4976a2393647b714031870b1a6b2d486a5cf2a8093b7b948c9418f3a27f6296ea12336b8a6dd5a5715ce9a70dc6978038369a10332e3ab6c2971961d5c66441abc3290113b21c46e96c509aaf09e658d9b77928935b9a122e42bba23f920b58ea48f3f19a7924128669c09e135f772c275e55904400495153a691794a8d182ee1314446371501e87c41a944f850c9cd288cc2ea90a4e27864c79e554cc5924c4ca9a217dca424ee8b76e49993ae4b085e9809eae27401eb9c6c794a67a31705876243478f86d5b9f9cb3295422816526439950a412b4d1d28a70c6b9794c959be155aadb39e00b418efd0664b08843d20b71c547f1468c5fdd92b9d818336282f34f19b515946a7961b5a9319d9444cdc1aba840cbb57272e4da4ab20facd5fe4958a57c3c812978fd772c2862dea8b60b30a601b692dadaaba0f361cff27c5c734a42265341641b861b7899cb311e7e0acce396bce2809f24289c5361b91cba88493991987c0aca3b070411481e154104c15780abafe725dd3e1adf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de252a4f24795e9aa631d5198f07511160300a2e02a402b4cf8aa556ce67bd341307ce5a1eb6609efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d0433 +expected_private_key = 2ecb7caa911a2f615a13cb82e5a8be85e1c2bcf06c71b9696682532639b57a91537e470e8514390949cfadc80b0e5c3ee3eca869e22250560d8896b5f6eb0fc6ec0a6d01760c9108b7a26cd79039bcb3cf9ea0432fe0581626cfedabc12f758b407c8e9dfa373f45c377fa6d41a7205a7322b737cdabc8114df437e864c4abbb3dd084964f971b36e24406a7a7544a260d917c0ef95ccf33b1833bb6d4232bfce37b96004ed7779258faaedd9abaeb5051d8f605eb85be0f9599ff28b40587488fa376729685a8336c0dd213f55447e2c4895111b98e73bd783b2d08960abce22f6f894ae5456577a81156c66f6f1bbebd9c04d1ac43b77936f13060d3305a3893a825781e47928fc492adc16b31b2669882fca10581603b400f297b7fe7525d20e82958099b2d118ed3a14a8a915731525c470b7852a9b0ef04b4a3b0b65b4c5d7d486366175540a91e752993ba979d8a446f94088c7c3a02fd5c051f900a141957e63cbd71aa012db60a02b3872f3a623218a6b1f628fe8580e8725d9fb647f128c2519a8a0cd0649671616b462b83904ce621c95ff44697ca71ce930eaf0b28a6448a1c6b38c14800427683b71c954e49b6a3b978417b78ddb1a1b9729b89160b4c7ba49f312e23632460913d82d655d6e00b5b17a635827d8a0781e12a68c536ab40909f46a7173fa9cc9990371dcbc0b8a433436133ac123a73664a14e1409b4476ab001c17f26ebe968ed8c6a9d491b92f234499435e2df615c849be5f6422c8bc9de8f148a7c0713d93642dc852b33652287010f02b1d7b77972c797add3a38651b4c11ea968ce53f10d38df4160101fb0ee557bcf5b3328e12150a7c0d769812abf2ad2c1c7661844e6b34b25e7a30ec64b6e7d4282f48344bfc6f33ab3c428c76705cb9b1e9637721c9ee60874017013374082892b4af174749041c606b3f6690146bf1b0c8d2844f80594f265a8fb639e209c9b7fc418a230aaf340bba34c1c66b7d570918ed6caf8f62768620058cc7cb4fe1c762aa96a5015b82216e204c5821022caa84af9b12b9c9bc683747a2724c88e650539779742edca6a6a6c5f5d68faaf73d4cc7aab9b105f3a1b46cc96c915912e807aa6c841f6be63812062ed1d07bc9164eccec7e6662056313cc32f63c6181cf3343adc9073888d5756f508d65025bf6490a5f6b164a942466e60c4410c72aa69d2ca10459b890a4cb22a7613d44e70ac96aca21169f932a6134d27a6c05582e830c0ba137df060c6249b360831cc6b993e3d455c2e61694b11b520c64078bb552a65a3bab407d46c0ee173bbb52a95c7cbd8612380fc0cf1655c8e691bb0493103ec80a5fc92b4951a0d78768504284ad52580f16247b3c44af0a397f28ce3d0c0e4d34cc48b26b3998b060f2a9a013889685446b6281b3341c08e8300a013390a881a3a4937b412bf4745b069acbf5315b9955aa4999ba827bccbbf776829291a9067272059104522d69d1834886bde76c078a6061305833fefa710ebbc0dd0729493a285acbcf2708cf93ecc76b85691e20bfa4379c8521420c231f68429bb5c76e69378f6ef3475fca5760a5be829c2b4fa955e0e0931423b0a615194c26225bc538e2db29b873b2397a7c7ada2f4b0b589ebc97c50174e4317ed5d9cf2878c924937bd258bacbfc83283a218d443d8ee43f8cf3c64459b189e6b3ad100a6c6a3ede9916f89b8bb67cac332c0519f502a4c427f5c9af1a16a59a2122521a0c624a20149765e986339ed63567cc29cff15d7e8ac026c96f08d6ac4e057db4e66361b18ccdc3bcffc300a996ab7346232db7310662c75b39ad7aa080b23763ece54960397b8de836071b8914d56f95a681accb8fcb9529e5e4cfc2ec0601f7b0b291524e180aa0a69fa74ac2f17aa88162c481f51543a5a527da5c42b59f9a72b14dc91574b51e5806ace3f022d1f19e3eb621560478bb70beb8407719a01e16313d2f0c785e3b9886f679acfa465ba974676c0689a149ac04996f4132dc4974f2fc322b56115a64b0b5dbb8dc71869cc655dd61390b032f062b024bb71505640a41cc6174b68870da11eaeac28ad061f3abccf4e12231655eaf9285b205251ea69371d90527793495835715ac005868a78b1cae80025426848c4ae869b52034bb266e1b97480aaa7a31e384780442d9933fdb750efaeac0bfa802e5314d28a17d374caa05b46121e16362e8341dd923a66872df3c942177b58951c40ad1641f53a53d8708ebcc22aac67ef262b6155007dc6880a1f45cad3a5312b282055b1e0b181d9b396591fa78dfccb9d6a92d5cf8189c14c68cf4238654716f0a1e4f2542cd35a7e4e2185814c1f5b16d8c423213c69d5958c46960b8df589c185087ec5474df3c5112b5bb6bbcc6ab7160abdc2ab28801d775caafa049479a837cfc8847763559ea86239889385baa43a2848b489087fb43aa20acd7ac05606767798500f9271271e52032f21fc2a82d8d15bf774771b69c570ec488053743dc5398c4363aeb3932a5c54d16f45a033386dbe3b2d0a851116c2cd2fa4671b95cf7e60bdcb4976a2393647b714031870b1a6b2d486a5cf2a8093b7b948c9418f3a27f6296ea12336b8a6dd5a5715ce9a70dc6978038369a10332e3ab6c2971961d5c66441abc3290113b21c46e96c509aaf09e658d9b77928935b9a122e42bba23f920b58ea48f3f19a7924128669c09e135f772c275e55904400495153a691794a8d182ee1314446371501e87c41a944f850c9cd288cc2ea90a4e27864c79e554cc5924c4ca9a217dca424ee8b76e49993ae4b085e9809eae27401eb9c6c794a67a31705876243478f86d5b9f9cb3295422816526439950a412b4d1d28a70c6b9794c959be155aadb39e00b418efd0664b08843d20b71c547f1468c5fdd92b9d818336282f34f19b515946a7961b5a9319d9444cdc1aba840cbb57272e4da4ab20facd5fe4958a57c3c812978fd772c2862dea8b60b30a601b692dadaaba0f361cff27c5c734a42265341641b861b7899cb311e7e0acce396bce2809f24289c5361b91cba88493991987c0aca3b070411481e154104c15780abafe725dd3e1adf00bb0eff4a29298ac10c63fc0669df6379294aabb4588aad2087c9c16c9afb654f0c9c213d79cee1a843a84742d574de252a4f24795e9aa631d5198f07511160300a2e02a402b4cf8aa556ce67bd341307ce5a1eb6609efea3f066379865489701783b2c95ee6967f0893d44d76104bf396577fd719d69eb306117f3abd65385a87af12d1bb6d04330c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8 + +comment = Official test vector 46, seed: "6b3996e8bc6f52879f2b7be012c44ad555707cb7e5fd8abb3457a298336d6fdc9eb7853008ff13201d5969a315c7e493" +entropy = c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 +expected_public_key = 0846c63e2c3018bc8733f05f8ce3b614088a787669205ac9889bce2d3b523f366f4bf811f004666b2b654431b135d97a70a00fb9a3928c1a4a2c7285f6f7b19bb766bbe6b966b4013ec06833ec6f1118a772c2465d81b77ba740b7ea33129218542a41e2f1b10f42bb42396e9a6c5011351e783641aa692a982272d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1d901855bbb2b68b988953ab63607d988999ed96e5a4b963497a061ac69bd90c4eab7c0dc17820b6963b0293d4ca30d82f5997a877a9aa71c5c7893c1d153ac6779d0a88190b13df828bf3afac9d7ea392fea899ef844535187af673972399a5fa31034c02d70b57b97434ecbf3b1985c86ec75b23ac0afaa67225f12a257b78341966bfd2569670680e012899c112ad3873aaaf26d2f4a5c8cc133c92b9a446530c169b6b87b118d03329374a71ada1778a2035986ceae200c763a12b6e2b2fdb672b4d58d8be640e61576f2cac617a5ada5d1b874bbac9d272ee4c881bbdcca1c9a84626012b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac252bda1a83ccfaad69e38ceda6b149c1b3ba295fd5025c63225ce88ccdfbfa6b3950cbcdf96e14dc0962745a5fa32d10525f71d895a2085620c89024d922359741be366ce9038aa3b260320a456858a7b8d01bca12316e9c6d1782bedcb590a1d2ad9ada0c26d3818652ce6f3b6403c94dbcd1424d090e9deac559472c9ac19cbb26c16e8b27db9140a1161ea96a171728689cd6b6ba0c8002ba6c46719a1a0c175638770cd088ae29a7fa958209788ade14354a1b0880f05ef7c15a6786be063b357fc7521973abe4fcac0a8c26f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7d316f75accdd1911df10a7e838a7c2023ea1eb0a956abb53fba02c48396807229f492966796805e04ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf171899a911fa910dfa6687b2c28c1d419a4817abcf656ff669b587b72374f3cc20b92858361d21bb85a3b9aba157100875c993b54ccbc84db2d72374bcae29c5479cc95197e625da047447ea5797551595853651912daec4891e68901bb67faa98bc5050bb50e913645874fb7a0e51c816acc88a7f8a4ad383170a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb892aca3941cdfa7a487c13af9787a309779b759cdc037c13e839314803bb10a3ab19b7fae477c8c322bf05bd3ad9cfb0b241371c85ffcb607748cb518a6c896830b191737ba289b15288ab59869e22637c57019818801ef9a6b7160ac1b5b4d7519b41905e6687b3fa7230eb88a3c9530813561308b68bd2b740e7aa08ca72cd6468c008ccab34ab99b6773c533b3914b19b2b80bf7e783e7bd9366c8962e7f3410f34651ee606eb737e6c9c5f6d306af7348ce955228cf02d15b8abaed16994b56260221beb1a29be5596e204b9ce111127989bd2ab49cf27c976f74aa7b084fa6b8400a25f3c36213f7c2d160045d865c75aa14542f5a4e4d1459b5676491c6a3fa0a2f0319ca1a63a401c9c3a14c94f0016a9a69e64c522aee93e8b96b4f6691322242b20353e0d8b995a6a9129e961ae7349f92c92a90b833e82b9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e +expected_private_key = f3ac3178bc3e6b8002eb20046ee3288f9cc63c1abd0b14a118d52e2c9a998d4c67e2014415084f520945f55b985adac8c503079789aecc491eb7ba540f32be8823a4a837786be140d260cff5d46186588f4fe2419e0c4ba1b619567b9d8206b53ab1289640520f2259f5d6854871498b23696a321813d7a544e77fb3100b34c89af2c63856fb43bb0a74a6073958d1199b4098386984847962b353b4d81aaf4cf65349c8197db8c1b29a91fde5af1f9749a96b3b82c567207a81a163347919aea565304b4820369799d352ce72415cf1c692537a48ab603b9dc741a08a66d874bf46daad570b6f1f4133067a1d900ca87cc25e91c4ce1c84b46d3c5baad46fed227268f1a9dba968eff27249b3c6e4c7c19e8a13046a2b45bc24f4304a80c09d37ac289f924f33e97181b8393eaa82a6fa54f2e76dd88791b5c3773707046c362d94ea547c3050ab251953464f4e540764b08103a88e448446f6b82375c15e3ca9a98798639b83638ada857bdc1e3c6705471975c51b8087a26348babefd234d27d6c055d3aab7560b28dcc13d343a79530ac868b5f6ac83af04b8d7a20b64dabe9de32a5c1b2c2acaccc4588c1ba26f5462aaa5c1bdbc36467f346a1ab5c5840a07bd33ceb44093659bb0451c4c87ca4852172dc0bc3674b4275078cd2b9a3afd61bfe454107d092e5840c4968c547adc723c1970cfe705c5d33e3a4533f0028655c6ba44ab22c2a4c85a82b4b6dcc09765124e43c985459cb2ab1519db1ec6f348d017a785484802d90e0222ca2313b4fbc465dec0cd4f3a5675e33cf0db79145867d5f0b8f340526c8a744929728ceccd146b6e66d03f660aa4e2e15d200b5960f3a03b571bb2e59160048e498c15379027e07987ddd841bdaca79764bcaa1c9843fccc65b53695335d9d4cc789e062571665da99b4e10368467aa551775c39c7c9dfe7624e8940f294c8655503f2f970071b40f6ba3544c64c41887184828be6057a9e972631604901a7870733580c6ab8d4aa18b49cb4d567577aa8b0ca2490edc68b168583b8b38415d32f5558996cc911a9470951430c36f71712f1c579a12327c41c441c980c286b71a31748ea54df2a557fd1701c3173944b7b40117ef9cb08a7d03d45531b8de4c753f697ec4b4303448c260b0783c81ed599425d9b16806828bf795c8cf65a95f366bb90110cc75d3e6064bee17cf1497f36c48e68b46ec07417b2a876cb556c705c7ddc387d74f2b0aeec9070d227af09a324495f551680a474328d379aac253a6f4c42c865a183d7c2f4f8ca94a92388b1afbb5408cb1c0fcd3c945e2923acdb7e16a45c03ec3298b3c44e9c1e75d049b2ebbcf2f29a2d3b7fc68644530010e052a0d357809009cd786604a39898b385b70ad7b3be011ea83b93d4426f4f20a3d0836fc6fb532fa14536285013050c16d01c5752884e49a82a4a0bdbc8bc2c7598d548278703ab4c607a16b1bab64052f40a06d3915cd03825f12c069d956f2a5662e05804183932b5216ca66274214acf5c01a7f4c77ebf522db776068f94151f7ac33831259b53bc48e99c50b260faec0b7bd3cd4fa9b5a5c2588cf098fce5aaeeb15fe651355537953d9b8580313b56336f0846c63e2c3018bc8733f05f8ce3b614088a787669205ac9889bce2d3b523f366f4bf811f004666b2b654431b135d97a70a00fb9a3928c1a4a2c7285f6f7b19bb766bbe6b966b4013ec06833ec6f1118a772c2465d81b77ba740b7ea33129218542a41e2f1b10f42bb42396e9a6c5011351e783641aa692a982272d9544ac93580fa6a51b8c7b6a4b5b1ce3b58f1d901855bbb2b68b988953ab63607d988999ed96e5a4b963497a061ac69bd90c4eab7c0dc17820b6963b0293d4ca30d82f5997a877a9aa71c5c7893c1d153ac6779d0a88190b13df828bf3afac9d7ea392fea899ef844535187af673972399a5fa31034c02d70b57b97434ecbf3b1985c86ec75b23ac0afaa67225f12a257b78341966bfd2569670680e012899c112ad3873aaaf26d2f4a5c8cc133c92b9a446530c169b6b87b118d03329374a71ada1778a2035986ceae200c763a12b6e2b2fdb672b4d58d8be640e61576f2cac617a5ada5d1b874bbac9d272ee4c881bbdcca1c9a84626012b988395eb5a4a48bab1e7551b6cb57ea7b627138c3ac252bda1a83ccfaad69e38ceda6b149c1b3ba295fd5025c63225ce88ccdfbfa6b3950cbcdf96e14dc0962745a5fa32d10525f71d895a2085620c89024d922359741be366ce9038aa3b260320a456858a7b8d01bca12316e9c6d1782bedcb590a1d2ad9ada0c26d3818652ce6f3b6403c94dbcd1424d090e9deac559472c9ac19cbb26c16e8b27db9140a1161ea96a171728689cd6b6ba0c8002ba6c46719a1a0c175638770cd088ae29a7fa958209788ade14354a1b0880f05ef7c15a6786be063b357fc7521973abe4fcac0a8c26f3eaa052959e2f973709c9c6bbf4c889c8b76c0ac81353b4a4dc81b7d316f75accdd1911df10a7e838a7c2023ea1eb0a956abb53fba02c48396807229f492966796805e04ad62b8107493aab264a5beb32f5459c06aa6e7f79acbf171899a911fa910dfa6687b2c28c1d419a4817abcf656ff669b587b72374f3cc20b92858361d21bb85a3b9aba157100875c993b54ccbc84db2d72374bcae29c5479cc95197e625da047447ea5797551595853651912daec4891e68901bb67faa98bc5050bb50e913645874fb7a0e51c816acc88a7f8a4ad383170a583a2e17b0d5766e12dcc827386ba8d868ee16b2fb892aca3941cdfa7a487c13af9787a309779b759cdc037c13e839314803bb10a3ab19b7fae477c8c322bf05bd3ad9cfb0b241371c85ffcb607748cb518a6c896830b191737ba289b15288ab59869e22637c57019818801ef9a6b7160ac1b5b4d7519b41905e6687b3fa7230eb88a3c9530813561308b68bd2b740e7aa08ca72cd6468c008ccab34ab99b6773c533b3914b19b2b80bf7e783e7bd9366c8962e7f3410f34651ee606eb737e6c9c5f6d306af7348ce955228cf02d15b8abaed16994b56260221beb1a29be5596e204b9ce111127989bd2ab49cf27c976f74aa7b084fa6b8400a25f3c36213f7c2d160045d865c75aa14542f5a4e4d1459b5676491c6a3fa0a2f0319ca1a63a401c9c3a14c94f0016a9a69e64c522aee93e8b96b4f6691322242b20353e0d8b995a6a9129e961ae7349f92c92a90b833e82b9fae1ad459ad417635c409c28f9ef936ae28d221563e30f83162cef01b482889e5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2 + +comment = Official test vector 47, seed: "730b65ece22de27d573ce3aea7cb021c415df210d228808d91d4f380070ffcb0778b683c71d4853deb569c822765f2a3" +entropy = ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d +expected_public_key = 964435fc16be2cd2276b7bc78ee8b5c963af2af4673a93940b429131663cc124be5a706bff5c157dc17dc5cbc2a11418dc4b8a28c841c5a831b1a2ba989a20fdd17dd06706ceabc0d20714d5595d54216e9fb6824e3272de0a1e262aa246494152b1cfd95c970f38aa35fc0337b26e76c77a0a76bc2c57b80757550b11807a423b85e32ddb537ab6d4694cb8b9ed58b11c9a6acc746749c21011a66dbd7896329c3a31d0a7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1bc1a133a41565305cd4a09fbb10934e7a3d132bb0eb83559c484ebc92f7cf93e445020b7187e2705a2d1a8386c008ec7f22fe172088360cd3fd160e7020b6d0c747ccbbeddb1b84fa7549f625dbc064621fc2e13f720188c200c1ac1f10394fe4117018b9640632fbed570c942575ff61a7149a51f9993b90827ea2a08c32a330747ca27ecae452154ce1a6a67a8b63676998af929e8a7a9d2ab709e2162a2e0bc0721bfc7e49c5b2c9ba975b3bd881aa3782391f5cee4cc1835c83732c84f54b373eb18869b2c90e9f986a0ea345cbb020333893b463671c95e6aa07193d06f7e62bf4361cd0009b1e528c85d147d0e650cea7b0c67f1b4fb754bf2f1a7b9cc621d4c34682a6195776bbb9b2cc866cfa94c368a2b4b346c75a2a6bfe946cef09416aef21b15d3c72b7cb408141608c058e506271380841656963174c70e09c1f593acdfb9bf4a3a9387b693f882495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b610f00bf4f4a282f752a070582f2f3c141e168f6fa037f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a6f82ecf8863c1692dc2073cf517cbed3c362a853beef1a8cf2247000cc4cd8176ce980d683b8ad89b3eaba3b962624f5ab3695fa10a88055ddd664a2ba0749e439a39c6999496999be3ba7bba2ffe06388b1a6c83068ae70a1c6f8a36e788b8aa148933c896eda61efc86cbb7d5c9cc96c9f137c6a9210347289010979bc1e16700a610c7c990d685550f537ab0c45b2bc57e5ef4c08b2220961c6e17e95e2e4482a4a94da2e17b6854ce57c263d69429e1566bab646fdb216e0444cd8fcb7df4168ae66223a0ccad971583b5917c4805271a17b4a1e17462815cb39332699ac447332a3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd2131b98aaca67343cdbafa3db35661c38c0ba1e18043a4c945067adee46e428a16011abfeb58c1bc8b2330288b57cc319389921857c9d015a0471128c34cbc13417db24b91a3567ac299cfa6d4c2f1123661a3ce0996111d340d9613b966955c6a758fa7f3556f6716e5ac7ad3a93174b2032a983cc0c73c0de302f9f83a0de89a1fb576cd3b41505b5ba712c387730c45399b8cf0b0e548cbed984e7bb5095cf7263b05cba437ac6fc369ebca85e0211715133bcc314723d79c9b93abac57ad3d3a5e77f2986a3539eb795a5b4967ac7753115b916236a97900870b658b9d4b3e35827e1aa9adc3500fd9ba18fc6b03465903858c61c1259cf485338cb700eb731f31643b469bb259210cec78c158e3290573c5228518e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b +expected_private_key = 37f7089480382622ac6687b4b15bbdbc1a9ad7467e8ff4cf44f0614de74b9591b9c5410d2d7084bb57ac27963aafac148de80dda6232f4a0c634d677a80c226fe67063191c05a54afc026080877538f63df93cc6fdecbbc0a9a0a4215488da1a2f7b1ea8f8b917f32f397b94c80170bcd423c1f1ba4c736449f84bafd6711b0070dae72de1ea3923435fe15a4fb35ac98d6379f0a44c200a37704b5b269ba3a555961aca5e2cc1518fa4bad3c23438e06952c9317d198b0c112d79a89560dc3361f5732f820ce4d16ed448ac2ed221c8ea3601602c27f640dcc394a7ecb5079978cf52b80de15c3015839a44b9ee36837866c5c8e9579849b331e53dbc049e46dbb524c2090a54ba793c845420a7c2c29e78a9b8c83c310d780f74127c02a59ab68c1b29952dff1196d0940edc338df3e1c1c8e34fd0dac4d5596f97a2afa98b1e8be46bc0a96df412639ae5b52229086229b5bc79ac020b61a56c04091c10cf9940f798a9c50ba1f5fb30bfa947f20b62a60215c5a88d23b70c0e299c53f49a1ed511ac5812558133d9f195e1fb5d77314559ea79e63a88e781c4224155abb5ca91f089c0c609cecca32e549b0cba167d9307a3a64681a815a69c5d7e787751162483e7701437034f0864d8d53201fab9763c7921eca6f11247e7ea364298c1c3ab893549572bec45c1a8c3b88659cfd526810b23f2095aa6c1424c7178187109f83063b52547b9c731f9933622a33c7a8b927a50191593488f9a0d12331017919159c7a027c3956fe109393a167a6475cebb49224736847319d161490ec52396d7babfb638bdea29f50c9ce37314fc858455f63fcc70cfcb751df12274feeb45a124ab1b997c917a550c3469a0c185eb0238ffcb4dcbf751e12ca17a71b807b1446ea7180ee302e6998ef8d12a857c84ffc377f5e42fd41238a54345229916a715977025b3b4a6060f778de7d426a2f95927335cb202bf4080b8510cc0da12c4eaec4bbfa42997e21504b8c5d32604f1d66e8d55b50c393f973acd37a236db595e3ef08239c42fb5e9243d967181b9b94f4521c104a8aa726dec057abd419bc8c6cf350c91acb78b0832144f409f78992652e30eed7ba2375b3245d877c8e8b873f0427071c956633495381a2c642b15282b9945c758910fe469cd091b4458218105da96a479be0ac6b3ba155d359b2815916e93e9bad3d431945b852e519df0129174b24a32cc9fb8a62de96733d153a799cb8fba3c86b9101cf3d4a97bd3b699467991a57129607c27274d3224cd1848c17f1550be47b71a119873045e215bb817cb92c12a7bdc6347df8b64dd686873d800b4672aade8af56d2995546cc37c06f9212a54745c5597184ea85cedca7b980386fb91b8ae677a035a4547b5848879c2567c8cd6ac285f6f2460dbc0b73f5ae0993c988418c234895380c556042acd15a6c015a13ebe16cdea4be38528a9d244230a0ab053c568e31c64d06a3d7bca0e5207b7669811a3512f8ac6887137b0b7627d2401ccd604ae786753fb6568cb522b28712211208c1849d1f75cc4fb951d2aa081ada952998b0b0e938b77359233a76c135897e91059cc5639e978c12c6bbfb735fef4bcb1d60180df21d964435fc16be2cd2276b7bc78ee8b5c963af2af4673a93940b429131663cc124be5a706bff5c157dc17dc5cbc2a11418dc4b8a28c841c5a831b1a2ba989a20fdd17dd06706ceabc0d20714d5595d54216e9fb6824e3272de0a1e262aa246494152b1cfd95c970f38aa35fc0337b26e76c77a0a76bc2c57b80757550b11807a423b85e32ddb537ab6d4694cb8b9ed58b11c9a6acc746749c21011a66dbd7896329c3a31d0a7e1e78efc93574cb7b051d79188ea4981dc6299eb9bd1bc1a133a41565305cd4a09fbb10934e7a3d132bb0eb83559c484ebc92f7cf93e445020b7187e2705a2d1a8386c008ec7f22fe172088360cd3fd160e7020b6d0c747ccbbeddb1b84fa7549f625dbc064621fc2e13f720188c200c1ac1f10394fe4117018b9640632fbed570c942575ff61a7149a51f9993b90827ea2a08c32a330747ca27ecae452154ce1a6a67a8b63676998af929e8a7a9d2ab709e2162a2e0bc0721bfc7e49c5b2c9ba975b3bd881aa3782391f5cee4cc1835c83732c84f54b373eb18869b2c90e9f986a0ea345cbb020333893b463671c95e6aa07193d06f7e62bf4361cd0009b1e528c85d147d0e650cea7b0c67f1b4fb754bf2f1a7b9cc621d4c34682a6195776bbb9b2cc866cfa94c368a2b4b346c75a2a6bfe946cef09416aef21b15d3c72b7cb408141608c058e506271380841656963174c70e09c1f593acdfb9bf4a3a9387b693f882495149c62a77595574c0bc745b51ba8338c6361a293402e74df74a7a70b49faa1ac4d66b89fb6c31dae59f318b610f00bf4f4a282f752a070582f2f3c141e168f6fa037f23945893766215b9ee9a3a1de662060a5b1fd34bc8dac56c0875a6f82ecf8863c1692dc2073cf517cbed3c362a853beef1a8cf2247000cc4cd8176ce980d683b8ad89b3eaba3b962624f5ab3695fa10a88055ddd664a2ba0749e439a39c6999496999be3ba7bba2ffe06388b1a6c83068ae70a1c6f8a36e788b8aa148933c896eda61efc86cbb7d5c9cc96c9f137c6a9210347289010979bc1e16700a610c7c990d685550f537ab0c45b2bc57e5ef4c08b2220961c6e17e95e2e4482a4a94da2e17b6854ce57c263d69429e1566bab646fdb216e0444cd8fcb7df4168ae66223a0ccad971583b5917c4805271a17b4a1e17462815cb39332699ac447332a3f7acedc03541e93a822a96089d6a1f47a7df35cc9b659cf419bcd2131b98aaca67343cdbafa3db35661c38c0ba1e18043a4c945067adee46e428a16011abfeb58c1bc8b2330288b57cc319389921857c9d015a0471128c34cbc13417db24b91a3567ac299cfa6d4c2f1123661a3ce0996111d340d9613b966955c6a758fa7f3556f6716e5ac7ad3a93174b2032a983cc0c73c0de302f9f83a0de89a1fb576cd3b41505b5ba712c387730c45399b8cf0b0e548cbed984e7bb5095cf7263b05cba437ac6fc369ebca85e0211715133bcc314723d79c9b93abac57ad3d3a5e77f2986a3539eb795a5b4967ac7753115b916236a97900870b658b9d4b3e35827e1aa9adc3500fd9ba18fc6b03465903858c61c1259cf485338cb700eb731f31643b469bb259210cec78c158e3290573c5228518e4697f19171d8f1a3a633448fe9c83bd28097bb29a168db5af1d1b354b6881a2ce509b172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147fbdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d + +comment = Official test vector 48, seed: "5522a5a891a9a9b5514f4556afd8df40b9cec63a01492f0cb8a1db073a285a963e4a9ff2376c88662f7d8d241f8acf17" +entropy = bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 +expected_public_key = 58718343322db0162d26965d5e946b700ab88d702fd5a1376920b5be702297aacde28588da91c719d40c1fab0af109742ac26c456961338c44c93c83ab58581635499545cca66160e15a35ba4931e2b91fee68a8734acbf72755e8d452d17215457161284435eb6a7a2933c8d146a12679143b80740f68ae052087eeb988771a8fb43b34d6ec79868a0670551bdd19cb5313892bcac9e4fb500d3375ae471a3ed551b2d9c76142b22607615454a910f8578e44b448aa9200d805cf4c15eb635013bb80a65593ff578c794066f05abddb850ff976c74ed6acb4c41064fb5eeab479a13ba57dcacf7f02421603194a3cb549f08c0d700790809ee0e585dce4088f96a740320c57d5a632c8bf5dc173f0f841173aa47ca42004b808ebc2a6a1770ad9dc06027557f80420db47b0158a1d1ff32007fc058875c4f5d21fabb67bfe8909e10b51bb35c76d0605d0e6a97e56cb93dcc58f722d95f33008b0a237b711420a20269a7097396a4a98be20b8226e103cb1136ea3fa39d438b305b63fa049c420cc378392b9f911bd7800bbaaf2bdd7586780c7078dea622df51c7190841585bb16bab9a0d83625d55826e3949ae018e7c4703ca082466b9a078393c30a4f6b7b1fc775c9dff7cfb5909cafbc66ea946e6f098f881b3039c251fd3ac142029e8728082f838a202cc3586672cb6285b021c41e3c16f5787ce6e319d849483fe40d989c246f7c36c11a991234ae7fea68770c79d8290aae3bb72ba014aa1279fd13977a49b0cdd494ca00c610cc2306059b695686399c1590f274f735142639425dd88026f8be0f260cd66672a12b5c7b5c7323408a2711677f062625eb8f3541098d079c13208415dccf3ff72d1999721db3c271f7521dfb0f129b3cb6885310a0689166a3b97b09610347ceea5579650720db621db20eeec24eec2144fb523ed2d30f64b9c6655928b3d06e1fd9b088ac8b7c964213e5674757c7bd48a3d066355f0249a50548f430c55a6ca0471953eb7c67e140aaf6322b7741225931622db114ed46b9ea997974c9ae2f54b87125ce79e8621d712688b50c7a49877d52091643a4a43148550135f27bb30ea131521583f5b79255309465f4b9f2233027855cc0e7c93bb33705136c88392cca717254640c540573d3a20032c9b297eb5b02c954c744c4c6143a56eb48f1d15439f885803ba5acb524f3d54bed37145cd9173ed92a00f724273787cf1b89c788184de0905bea74fb331ddba00cda70c1547c634c706a8447145489752b0633628ba4f5286851e1b5ffb8a7fa2bbad3f92c542ace74e67aa07b467e70b6a7d3056592b36a7a37c6c7114c610721e9c6ea933742e43609c41f6f3803e99a8d5a27b069bb73c892bf07524a8b2989633c96ccf33791ba29f3d575f249c640093046d1684fbc701ac633381bb349bb7d351230a8bb1a22223de3850258ac7043b887770a307c3746002cada2826e47f7694ef51f94fb9e3645aece6273298592bf00c0fdf14c07d8c9fca401ff351d2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b8b11d0e47c323d6b3c0ba12dc235d5c310ce2c7bc1f0a8467d627568a185855750e12717760355a0b8a756468e95406d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f +expected_private_key = 5e43bfe8ea443466ab6b087deadc672e7aadc85521d549b978b054a9b8949e519e3fc3a653607d794491341039713037d31c9824eace39e7127a974403441e25b714fafba4b98041e85b2fd8d8acc2a69aea9c80930306b46baf5245a505d48e293a77aa4174d1c095b0b4a45754a4a94bcb01d4543bf7c7def2ae2009408725c58bc76bde03abef3c4ee0831d3c6b2632609707b3b861f093e857902d52a2a48619b1ec20dde7a923412f79c22389601473076965959b2aa3c79dd31b98ca9847731c89b0929ef5174cc6b92972ce2c07c8139a62c901216245cfc92b2da158079e1c93c8e08ff438a02ddca4ca948f47a106d40ab6a5b0afaf52052f237e44f0765b3436271421308611845785e257cae691c39fb8c80bbc1c5fd687a547b7e8e3aa1d7c15a918984b6b359cd24711cbbbb95716ea54a8d3511c5dc983fa1b019e0b0d7de90c3c0a9e7652c18e72cad6f9c510e64f0cda8cbd86502a5880ee1536edd16ab36bcfd859ce879b3f5d6a0d90630668b7385c8599ecb1849a4942d87a91497129e196309156c9ab245f4c637080c963f9648fb2ba6f32d2566f88bce680203dfb827438295f8670c9bcc34a98497851bdb0e631ea06accc26373809986da62fa714012d2579d5d61443330e3b882c800b6c9d02c98e9859a4022db4a09510fc91a3b95bcbf73b3a09311cd13e52b61733e02dbb400e8a54a30668311ac02fae2b55fe05c95ac43875d92f3c2acb3d4a6b53d363d5d75a697061055a3a788bcdfa051edf97c3515ca920ebac9e7a998bb598b8436bdb63550e416d2aea5057562a901b609b129d92b27536e02c26ec6a3b2c5f6b733d0529330e9a89600b089dd30a0bb52530a3062be741b09818a78b4fb9f274b7262ca23b3f2a40542caa64fe38a6ed06beb5498733a38a7fd0b5aec2673aca2b07e00909e68d40aa207fb179cf7a60a9e13719635a15cb221d1cc88b921e950c94cee17d60f80ca5b4a656f501d7136d1245207479a1da42c26c48664297562a0bae0e7906e9d853fc7c490e4078b5b3b226b37101a31b5d05a26f1ca1f231a853f23f59d86a3fd269a0256eebd02cc0c6b77f1b1c613114e1084d8d1cbabd0c7702f43d2ee01db985382c562f1b7885a7015edf59bd8988b5bcea1cb04639bbf5b119e6293f908245455070da3013d2b6e2116776694b44e3a7e433407099a51940870b336f547677665c7066e181ce266ff0e508268731bd13afa2ecb4546276a5dc50772a6fa38541af968ae5c59e2d04c3b6002c7120a6a970ada2671590411552e48e7119c7b7f7ac97429e9b7cc0b5242df277cc10e7c48976266643a9b2308cf1799324780743f95e65851c03599fea7129d5552b86ac35aed10b5f00058a8742c02a3e4f6cbf5df61c66143ebe933060c98a4bb55318566184601bb395625fc86e4bd47377b54459b45e50c145596b9178d57d01bbbaa9a63bf444889fc810f1e40e07d289e0b04a58f84348463b9fca3176aaae6c1c119cf679bacc6eb685b9f443c2a9e304bba0adf3888b42698ac1f68f1626439e796e1967c7bef581dbabb6c22c9c16029e18d8493a524fc2a41738a25e735c665e79ac423aca37b5222d970358718343322db0162d26965d5e946b700ab88d702fd5a1376920b5be702297aacde28588da91c719d40c1fab0af109742ac26c456961338c44c93c83ab58581635499545cca66160e15a35ba4931e2b91fee68a8734acbf72755e8d452d17215457161284435eb6a7a2933c8d146a12679143b80740f68ae052087eeb988771a8fb43b34d6ec79868a0670551bdd19cb5313892bcac9e4fb500d3375ae471a3ed551b2d9c76142b22607615454a910f8578e44b448aa9200d805cf4c15eb635013bb80a65593ff578c794066f05abddb850ff976c74ed6acb4c41064fb5eeab479a13ba57dcacf7f02421603194a3cb549f08c0d700790809ee0e585dce4088f96a740320c57d5a632c8bf5dc173f0f841173aa47ca42004b808ebc2a6a1770ad9dc06027557f80420db47b0158a1d1ff32007fc058875c4f5d21fabb67bfe8909e10b51bb35c76d0605d0e6a97e56cb93dcc58f722d95f33008b0a237b711420a20269a7097396a4a98be20b8226e103cb1136ea3fa39d438b305b63fa049c420cc378392b9f911bd7800bbaaf2bdd7586780c7078dea622df51c7190841585bb16bab9a0d83625d55826e3949ae018e7c4703ca082466b9a078393c30a4f6b7b1fc775c9dff7cfb5909cafbc66ea946e6f098f881b3039c251fd3ac142029e8728082f838a202cc3586672cb6285b021c41e3c16f5787ce6e319d849483fe40d989c246f7c36c11a991234ae7fea68770c79d8290aae3bb72ba014aa1279fd13977a49b0cdd494ca00c610cc2306059b695686399c1590f274f735142639425dd88026f8be0f260cd66672a12b5c7b5c7323408a2711677f062625eb8f3541098d079c13208415dccf3ff72d1999721db3c271f7521dfb0f129b3cb6885310a0689166a3b97b09610347ceea5579650720db621db20eeec24eec2144fb523ed2d30f64b9c6655928b3d06e1fd9b088ac8b7c964213e5674757c7bd48a3d066355f0249a50548f430c55a6ca0471953eb7c67e140aaf6322b7741225931622db114ed46b9ea997974c9ae2f54b87125ce79e8621d712688b50c7a49877d52091643a4a43148550135f27bb30ea131521583f5b79255309465f4b9f2233027855cc0e7c93bb33705136c88392cca717254640c540573d3a20032c9b297eb5b02c954c744c4c6143a56eb48f1d15439f885803ba5acb524f3d54bed37145cd9173ed92a00f724273787cf1b89c788184de0905bea74fb331ddba00cda70c1547c634c706a8447145489752b0633628ba4f5286851e1b5ffb8a7fa2bbad3f92c542ace74e67aa07b467e70b6a7d3056592b36a7a37c6c7114c610721e9c6ea933742e43609c41f6f3803e99a8d5a27b069bb73c892bf07524a8b2989633c96ccf33791ba29f3d575f249c640093046d1684fbc701ac633381bb349bb7d351230a8bb1a22223de3850258ac7043b887770a307c3746002cada2826e47f7694ef51f94fb9e3645aece6273298592bf00c0fdf14c07d8c9fca401ff351d2e35491aeb55aed9b1b0ebc2424cc729ac7eb07630b8b11d0e47c323d6b3c0ba12dc235d5c310ce2c7bc1f0a8467d627568a185855750e12717760355a0b8a756468e95406d375f6a1289b8cdbfed9f6518d7031c57fd3455d4544735cf52680424c90f14f268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2ffd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246 + +comment = Official test vector 49, seed: "1853e72329353b3f89ae6a1b1ef700da8ed3c10d19f9e61ee9252e28ebb0e15802ee43083a12a0b7527088832605e3ab" +entropy = 447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 +expected_public_key = d8279f9a0681cb98bc38cb551320031f46262799c182b0355eec82cdb58d750596a4e6bf1213490810415a4b347e13c9e8514890a0995843936be342e81c7f4971bf9b75925d61ac8c961492a85d83fa8e33c12fa37ba08d7c681c521ed4060481f58be673007a081321e01e21419e232283a01cb1a4481550dbade263382eb93b7e42470b265027a933c480cda340a9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a3671c18479db082a706768a63109d2c4224d71c7c95755ca24b056c355e9c22cf5006662b3218edd4b317b19962cb514af123245b152eac41391cb432c6caf9295c66da4e5737ae3d60023f46aa7a604c64a6c403306ca4b96fc2929aed5b4ce7e6c631b473d7d61cbcd19826ab82c0c58880d77ce8f9bcdbf59d645424baaccce334809b43acb99248bbd966c88793a273ae857946902649f97b5516fa2ea2a84fcfbc054653852d8421b6b78c289b49080c8efaf85df195ab5562a03e7099c43c439a25ab41390b86db4f57188f002129f3ea1ffdbb9e9c688ebbb26e0d7ac6eea395b698a134f70f98480e87313b79444963557cee82534e9c1cf10b74718caede3bcbd98a68d9956facd8a45e2184c16b14048b9d28e8bfbf5ab43d1b650ee8cf13148caf451cfb144656052cbaf82e2f765c8c9c66c23b0cbae0257d6000f247200ab87f93b5167478a27b42ad7681b6919529bb1430dfcc809e171a334b33a0527a1d9519c18130971c55f6ec172b86248059830fc57c7356c9bd8263f7d571d0f7bd87d2a1686a7c41db9306558cbdf39f0176959a188b4d457b40c152b7ea09f6860d4d945e78c45eb68b579d48774eb26ad43bc1be3c0ac327c80b4c1115c2cb58bbc24a18146470abc223ad51fa10eefc311f1ac02af4c7432210233a4abc408b1db484e7885d239c0c2b9c4952e577a8ebc3d6a7684e711e12db96e1f988df423a395301d2c15fe2f1abf708bc64147a30e2717f7868ff602d50fa9a3d0b3a0097259ac52057dcc14319c438e113da967f6dfba4279245b72cc86cf724c81769dae271e18c0b6cfa84b916ac89b12a1f8b05d88527ad40346775cc832713146806a2b2884e35628169bc12f67811b507bee3bbebca81ab93b5d700aa92898b3f5cb6e9d345483ca3743457fad8cc5bec2a8e7a22a41ba8b67641ab181d42abaf94d0055206b648c81361f8486408b610bb3552299316b5c0b7d301d9f1c3d55621859ab2ee922c59b11ea9f2a1efe277c534128f2cae6b598c0fa059efc2c24e8a0c2337bc2c57a0bc64a7fce190c656b529d21244eb66a900288b5c484bb033020b9b9ba3019b72387f2746b3b893a1427882bc3135f0a17f8271f9c8480eb60732672d44336b32f851a283224144c480aa302c05836edc1ac4569a6020130b341466322d17811229441c4513a2e8041c85e035113992f16799dfe8c1eef3aff8ca2f341628808a81e8b66ee5ba47ad0863c735a904565f036a85fb1203058137aad2206c303f22d3027e732542a342caf3376d6b065a745e31e865fc2243da31ce08eabbf8183b4294700bf8928da8ca78bc08490810c39747fd3851211b22f26451f6772e0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c +expected_private_key = 469963001d4d93da7cbaac0acdfc833c47601ae334dcc0022a9220138c16b9eca73ad1863431a34f593addca4f0ea393fc4595d22a7cadd0a8d89827086a955400abad84226541114cfcb3e3a240fb600dd6c0960a7976175c56b0b48c66721e13882e3aa5784e12869f0c8518037955f876997975d27a7c92d4cf005ab859590504c768b02576a94263c87c4bbfe1afb09b8c0a5c067776a0d96a5d12925b44ab3d3e57c6971b0a86617f65a16c7e9b42c283577219409e1ca4de08a92dc5b4e8e87051680c1b24068dda801fe871e0b28ab0611bbb97cd49bcbf159b7785830bc9d302c0a61ad138277afc2374aa64e983506bd11288f4a20376b50ae1c1233a1acf30af1da67301a5a420aa826db58322dc1c7ad8bfd25c3b21025b565c357b4a0802e615a35a384f1794a0612e030228a865a0390197e7c27f45a4258fe26082c850170cae86721bb5c68cb32153b9934de4cb11528c570af363925ab0fedac79748b3489b7180e81ff6db702d5a100336955ec02fd2b9c86c2cc001833b0ba1b7dbc9699c6556b448324d29b0f6a4028bf48a49b1cf60b4a9f91321aa64ca849848cee2be0a29219f783008417da307710f87cafa2603fd206e5698177e81470af4c608a6128908541183a5b4769e74166349e55b4d2a2a84600ef712c2d1f13f4fb3c91bca8cad209cb5ba0ff578bd6e29a0cf07a972d262a2ea3c4dd44a5d55446c174b345b96871076fcf785cca68545eb6be64bc9be17a7d5914d8a50b286d3a2a8e1a53faa53815acf0237b8bf204c34766e97883071e56539361bbdf29187c180414c83d9c09e30983995aa4850a6b2358aa6240642cb9b0fdb739fa5a93ec60c11061aa8b5e71316a517be2baea2f74baee32eeaa0a75d2030f5e8bbe1b517f56511fd8aa499621a9ef6c88b96a9f33b2b3cf04381b5c97b743063a6286751ad9ee14903c4674b308dd5e28bc700134c43c788b04460db78a0e795e24698553722b4c3a095784828960672cbcafc11af32c918ace0580d5bceaa574409854051a2419f148809147133866f9b651a38622f21e0614f10139ba53724831ff312157146169ea29293d2a3f1250ab9cc877d448ecb53139e6c5487dc2931d45b4a74c34bba11cbb965e1e664ecfca54db7bfe7e61db2382e50076a70a9aa028670a354013c894b729945830b1125aa53f4d352bff33fdbe7c64bf70a4c3acff3680976fb26368693d928122ed5707b453a1dd714fa9c5a8e6534d45b53a2ba464e217dc0461be31c5763715bb66b6f3a4c0e7a3a4cc107602cc3b67487a7d162422468b5cf33c8e5a63f801c2016b15c40398f914cbcdac9664b7601680346fdd3a499d89b5cdb7e77cc8a1215661aa34737149bd0734f7be6a0c20bb94e6a89dfb9b0a9d6c4bfb86408922fdc9650df7577e5a89215c8636d5c376f4596c329158964084200c91af4a7699018c6d139f521204bc521110aa222203774db88ac0ac94cb97720a71411eabee0b2863c35607a617e761298825acd91c73685198be96b84a98ac7295142f6c19bab0082c53a8a50a3a39eec2a34e859cfa2c88c9cbc77b1bdb5377981f61c1fc394d70820336baf21820d44c0956e09a5d8279f9a0681cb98bc38cb551320031f46262799c182b0355eec82cdb58d750596a4e6bf1213490810415a4b347e13c9e8514890a0995843936be342e81c7f4971bf9b75925d61ac8c961492a85d83fa8e33c12fa37ba08d7c681c521ed4060481f58be673007a081321e01e21419e232283a01cb1a4481550dbade263382eb93b7e42470b265027a933c480cda340a9a4065b4bc47990833786456aaab5a81c0a46e0076b91ba5bb4d4abe21c6ab193b3a3671c18479db082a706768a63109d2c4224d71c7c95755ca24b056c355e9c22cf5006662b3218edd4b317b19962cb514af123245b152eac41391cb432c6caf9295c66da4e5737ae3d60023f46aa7a604c64a6c403306ca4b96fc2929aed5b4ce7e6c631b473d7d61cbcd19826ab82c0c58880d77ce8f9bcdbf59d645424baaccce334809b43acb99248bbd966c88793a273ae857946902649f97b5516fa2ea2a84fcfbc054653852d8421b6b78c289b49080c8efaf85df195ab5562a03e7099c43c439a25ab41390b86db4f57188f002129f3ea1ffdbb9e9c688ebbb26e0d7ac6eea395b698a134f70f98480e87313b79444963557cee82534e9c1cf10b74718caede3bcbd98a68d9956facd8a45e2184c16b14048b9d28e8bfbf5ab43d1b650ee8cf13148caf451cfb144656052cbaf82e2f765c8c9c66c23b0cbae0257d6000f247200ab87f93b5167478a27b42ad7681b6919529bb1430dfcc809e171a334b33a0527a1d9519c18130971c55f6ec172b86248059830fc57c7356c9bd8263f7d571d0f7bd87d2a1686a7c41db9306558cbdf39f0176959a188b4d457b40c152b7ea09f6860d4d945e78c45eb68b579d48774eb26ad43bc1be3c0ac327c80b4c1115c2cb58bbc24a18146470abc223ad51fa10eefc311f1ac02af4c7432210233a4abc408b1db484e7885d239c0c2b9c4952e577a8ebc3d6a7684e711e12db96e1f988df423a395301d2c15fe2f1abf708bc64147a30e2717f7868ff602d50fa9a3d0b3a0097259ac52057dcc14319c438e113da967f6dfba4279245b72cc86cf724c81769dae271e18c0b6cfa84b916ac89b12a1f8b05d88527ad40346775cc832713146806a2b2884e35628169bc12f67811b507bee3bbebca81ab93b5d700aa92898b3f5cb6e9d345483ca3743457fad8cc5bec2a8e7a22a41ba8b67641ab181d42abaf94d0055206b648c81361f8486408b610bb3552299316b5c0b7d301d9f1c3d55621859ab2ee922c59b11ea9f2a1efe277c534128f2cae6b598c0fa059efc2c24e8a0c2337bc2c57a0bc64a7fce190c656b529d21244eb66a900288b5c484bb033020b9b9ba3019b72387f2746b3b893a1427882bc3135f0a17f8271f9c8480eb60732672d44336b32f851a283224144c480aa302c05836edc1ac4569a6020130b341466322d17811229441c4513a2e8041c85e035113992f16799dfe8c1eef3aff8ca2f341628808a81e8b66ee5ba47ad0863c735a904565f036a85fb1203058137aad2206c303f22d3027e732542a342caf3376d6b065a745e31e865fc2243da31ce08eabbf8183b4294700bf8928da8ca78bc08490810c39747fd3851211b22f26451f6772e0c75659133e8d8c063cd3044da1719855fbbd9796314b11df8459ebd2d92b7fdc94c4c4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01 + +comment = Official test vector 50, seed: "027c3d5847ed4470931141104f25b19ae76117cbb64b224ee424ffb782e9a0e988839e0bded0df666fe8e5fcbb5dbc09" +entropy = 2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 +expected_public_key = 41aa7b69158362a41767486ec3da09ab4335fe2a25dd6c07366478cda91c691c5ed9264f771124c1f3693050802f480f5df89d5be189da765337a69c5c838488a0a4ba7880e91871fe346cf3abb0aaebadb211b5acd3b773c9146cf97920e509dc202f79b14734c9777a567cd44a43500b5eb8005bf4c5a387701286639e6d9ac2574b33f2432b3a787039e34b2ae511a27825cba7a8e09b401cfc6123d3b4c42318e7b032331230da960a09f61a6a196dc185bb8bf1c1a6b691a06cb57f12be1e45269c56490e256a83c13352a878c724242ff0681881160ed03166612d69894951d65b95e690db46129d149afba2c835d3b138036931423d2f84ca51179466a1028d1601d5c397cc81b1b5e468869185b25095a0e5b5dd6a421b5c7eceb58c4cf97b7feb114fbc435c78857c65098d3017ff8a58f5927e5ee7712fa0c2962939b9d8c84bb6428b3902881188df17479ec01e4709b7840235ccd77acb0bb3a05995693781fb711d61f2883827a96ddace29a9cd43ec6abd4691be1a758b72a629f6aae1c795981c0d8bf8160bfb3b8f5047e1a410cdd49c6a42adf0bcafed1b21eeb95d504b1a48b1ace228bb5e1508bf05128f0cb63f5597851b9df4caa5b6ac10f7f6188dc41b02761f840caa42871c55205cd09771ac9125d6265ddc56a466249fbd774ee53756035349ca12a48237221bd53d7ff1ac18242442935ba818a3b50007a3fc14a2fa3abe437ff14705df0cb5af97561a608a3fea42a809a7a7d5491453c849dab7acd99636931c007a70d01655c7302f9a26012c494de47839c1ea2951a87ff73968dae83a86f392f021873be4c75d2b0700a3b540f50cf6fb664a4627dda9c75394032f434655755d12d4c781e2324ae00dd61744cef6c5ec9680f379a26284bf9590a33350905e080e9b70547ac1cf3ad888f30232fdea7bd2c184f9e1a9b6835401e737204c5ebf2b28f2b58edd399f873c7849cba8064b8a20c9c391841875b4963bba2097b958d752739383bf26787e64ec215974b45848185f44b8780c0714b9651a7685e673cd1b6230c5d6639ea5629c20659802bc6f2b95df274836241165a524ea99a941312fefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2d31916522701d80252e9c7fbd7a17d306a4e1e02cda405f3f07b38eb65824d5c9d8b91f7013784fba0df0348f21b00ef5a325c745a829714a5b9aba16acbdf029771d5415e867590cc5a57360a8969407f0749ab8a08a65e37e70146fc1b7bc40d789eae83761e77749a07859bbc046b5a87e3a92a5368251127f12d27789318f8b9c3c1f79211922c852a0b0e10bbb631599190b49a66937920b3f113185d89c6e37da5f7ce9c12d37c12cc24741cb9a79446606eabe8c9ab06d8963c959955f198e03a0bd127242dbf2a2180281a7b65f54c28ec9c6cafe64881d6456c07607cdfb89e2ca2fb3ba8f8357720051c30952734932b08b508402a6a2f4f9c76b053c12a267618928032b5d9e41990a18c2c04ba7c2868ad9f4538ff1b494707eb9da6b81374d7f9731f9a26089d7033a8c24600944d65871d313387b4101c0aaa27ae19d978653638577bcf4caf48083eeeb57f401544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d1455 +expected_private_key = 3c14bdd913cda0f267abaa8b0a30a5eaa527638c01926623b0bc2ba55b0b596a92bad72e92845828e8050f4c2f40873918e4524cea8505208d345783f71202496721e361a582c5445fa31fb662a64941abf9fc203ab4a741c9214c1b80b4ca617c4976c819794f53cacdb3509978a6df5900016278388234cc1a09b804679f36718255b2db60a7eee5bc3bc78bceea8060354b54031c4c76b30a1a8b1ebb697ff8606ce408fba72dbf0856e5b53b1e4a4ecc746cdfc77545b46060974c8a788a1d59529a9aaa571b895be01ed5c23a0d22707d89467a5b9c662767a0d77d5c49adca983ce7401f34526dab1cb9fe744bde8c54c230705548b9ed00b9f4ea055466cde77019324c0a7c9ba404b641a6530ae64a964ea47e6e80aaa4652c9a8b66061103f385479e50a780249a909c92b7913329a478880162d8857d58fa39d3283f5a2a7f8ff6abffe2463db40728d06166627e9c92283fa57a2e46190ab869b6c21fbeac86911284153b259bd2a442070d1cc581fdd333e5990f84ac67f47491df01128f0959ada0891c236e0aca87755289c0e6c8fb136974c97dbb1b8871a4c70aa001fc950f0cbb3ace4ac44f800252f5bd76fc1dc09a3d2f8860385a4bf8d765b49c5379140e0a2801dac947c23803ab6b467f2bb1b019b9d53771418312f51b28db18be216794a0467d79ac8abaf2c90f4b1b3474c168bcbcc1e6ae59c5781296467f2b8d63d5842d67935dd429bf8319bc0b8199cca9d3f78c483b8e0771622ea764fa610ee13c1a188c56d0b5c17094c1b7a45321bb69d99a666a7963268a1d0a0491b8b5cb700a7d86ab9039330edd8bb17cf1ac79355a82166458d2323e070ac109c98d201358f22bf9a3b513b8bba43905d1a790a7b1a11f682583ab4fe0a82f3e316b7c70afdd823c8fb7acfd330b22f378e8597ca5357454a71197cb4039e9a81d7995d14587b479657584407b281886d6a7fe9b6170a056d2003bf898027c275b7c1c3d1d0c157145ba52d264699b969d60aa3873a9606041c20b17c90055b8016ea703539638cff8aa0a219542bf51b68cf153a86149881c087d898ef9c3a089cc70a8656117131aa3f233c73cbf439022d224422920501c07243432aeb925c4023185d3f897a79a983d857c6d1422f9b22234005e00882f77c7704cc74adea4c8f3971e7964ba1a530c1f722ef696828c46946f0b329d909a47b83353330630359eb8e9b7e78abc50fca8c3aa9af967c89f464430c815d1959a21a226a966a6434301fa600a4d129886826803ec49a54a34acd62b50e33fd782937571816421341cd76a3570c17ac9c338e4ac4c51077650b98ae445d236904da694f755c1a5b288275b517b4c9b896c49bbc18933e52d34969b6ad8add604b526488c6397842a54b6657b93386b0ed7d36fd2f448efe43b0a144c33f729df530c8b6340cd61897b3c50b0d8ba81228604f7a4bcd120cd2a7bbba3b4818177c435a2b0c3ad838c6d9bd3903d64b32b8a8da5d93589021251d14c920328c4063c2af3c8c41228355527adf41037e1ac6aa69a427a55354ca9d54025306c16f93154776b4a7af9c9ef2298dba9b669c40bd0601abd410357b8940511beb6c96541aa7b69158362a41767486ec3da09ab4335fe2a25dd6c07366478cda91c691c5ed9264f771124c1f3693050802f480f5df89d5be189da765337a69c5c838488a0a4ba7880e91871fe346cf3abb0aaebadb211b5acd3b773c9146cf97920e509dc202f79b14734c9777a567cd44a43500b5eb8005bf4c5a387701286639e6d9ac2574b33f2432b3a787039e34b2ae511a27825cba7a8e09b401cfc6123d3b4c42318e7b032331230da960a09f61a6a196dc185bb8bf1c1a6b691a06cb57f12be1e45269c56490e256a83c13352a878c724242ff0681881160ed03166612d69894951d65b95e690db46129d149afba2c835d3b138036931423d2f84ca51179466a1028d1601d5c397cc81b1b5e468869185b25095a0e5b5dd6a421b5c7eceb58c4cf97b7feb114fbc435c78857c65098d3017ff8a58f5927e5ee7712fa0c2962939b9d8c84bb6428b3902881188df17479ec01e4709b7840235ccd77acb0bb3a05995693781fb711d61f2883827a96ddace29a9cd43ec6abd4691be1a758b72a629f6aae1c795981c0d8bf8160bfb3b8f5047e1a410cdd49c6a42adf0bcafed1b21eeb95d504b1a48b1ace228bb5e1508bf05128f0cb63f5597851b9df4caa5b6ac10f7f6188dc41b02761f840caa42871c55205cd09771ac9125d6265ddc56a466249fbd774ee53756035349ca12a48237221bd53d7ff1ac18242442935ba818a3b50007a3fc14a2fa3abe437ff14705df0cb5af97561a608a3fea42a809a7a7d5491453c849dab7acd99636931c007a70d01655c7302f9a26012c494de47839c1ea2951a87ff73968dae83a86f392f021873be4c75d2b0700a3b540f50cf6fb664a4627dda9c75394032f434655755d12d4c781e2324ae00dd61744cef6c5ec9680f379a26284bf9590a33350905e080e9b70547ac1cf3ad888f30232fdea7bd2c184f9e1a9b6835401e737204c5ebf2b28f2b58edd399f873c7849cba8064b8a20c9c391841875b4963bba2097b958d752739383bf26787e64ec215974b45848185f44b8780c0714b9651a7685e673cd1b6230c5d6639ea5629c20659802bc6f2b95df274836241165a524ea99a941312fefc7cdd2fa8016d69b652c3e94e73c70c97f65b3adf14bba2d31916522701d80252e9c7fbd7a17d306a4e1e02cda405f3f07b38eb65824d5c9d8b91f7013784fba0df0348f21b00ef5a325c745a829714a5b9aba16acbdf029771d5415e867590cc5a57360a8969407f0749ab8a08a65e37e70146fc1b7bc40d789eae83761e77749a07859bbc046b5a87e3a92a5368251127f12d27789318f8b9c3c1f79211922c852a0b0e10bbb631599190b49a66937920b3f113185d89c6e37da5f7ce9c12d37c12cc24741cb9a79446606eabe8c9ab06d8963c959955f198e03a0bd127242dbf2a2180281a7b65f54c28ec9c6cafe64881d6456c07607cdfb89e2ca2fb3ba8f8357720051c30952734932b08b508402a6a2f4f9c76b053c12a267618928032b5d9e41990a18c2c04ba7c2868ad9f4538ff1b494707eb9da6b81374d7f9731f9a26089d7033a8c24600944d65871d313387b4101c0aaa27ae19d978653638577bcf4caf48083eeeb57f401544d4da3b73dc1c5c4a047b0a5ea85edac7bec66f4d87fd2fe422e7dbcd02d145572be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9 + +comment = Official test vector 51, seed: "450751d4401737459c6d93e6c5f2fbcc4a3af7cd7250ccf404bbb817a67bab7b4c9d0ef4570bfe25cf919da331c31d88" +entropy = 25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 +expected_public_key = 32b6c92f059443501427ac964fa569cbb074c71053f179bf1963ac704489ebb9936e23950e51ab7e26a98d6031c652701fa4ac59aa7c15d88c0337a067257b8d916db0456fad9622f44a928df6cce84a3e6634c9caca246208920c487b9a666342abc389c14c499785bcb91a95dc868fa20d25b08ac0e48c72e9b486151f21b11731d1bf049174adf279f9020aa98c38372877299c4f54a4493a3b20f8bc71cbc490b363c4162055cf3a5c13650db1154687462fc01b5e5b78c9f603255a24189b808358e17e01b9cf736a77d78a32520b6ddc9c1dd65a00e84b562b607b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf040dcaa766bcc18d6b8a2f91e51ed6d49aa37aa44531bd9dfa25c116a842e50f53a68bf1617245e8b7da778eb3343d3f2575ea84627c640a6509133f4c5d78151a6695245659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e647223c0154388912ed028ae364a9fa9a018d8558c3e9b179b66f2488c2be8792b1849fac0401a9756f209889fa637cf7ecc4f2c0249eb5c6f7e0219faa2a9433759ac70dabc7baab623c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d467273268a0797b8d6fe57ddfdb03fff7ad3d5b9c80dc1939720ee8810933a04f51b78262910d7e28c0eab06b91980b65056472a293f2361183125670ac2426e514790b945d6b09c9ec354fe7c895a30231d95794f89ee60761ac9b2aaa9a75ef168c0950afb498915b2518e010c3800764bc5a65c0c54b2af686b7d954e77bc4cf8137ab398fe93429dd0ab80fc846d4cc8db2b9b2b4bb36d4c4121639c1e74622e59250701302301b4df96b2fa62736b29caf0866096f842898b2c6012b93b5ac23d1f39e192002ff0b9005fbb8cfeb8930562a4e0aae7a40c5032b8b33d0760d96c7c203920e2439d3ea02372c7f5d80b92259349076ba20c3ad4fd21752a3963cc5126342a963a363c1157f33189732f7243e465b14969f1ca199af45b50851266742151a235a8ba9a595534bd6aa31ccf52b8c5885d571a93d2577c57057e2caae68c9c84f565c72681fb15056a345236b02a1e5b13289388f035a2f8e03402f8b0a44259179a904c94725319acacd28ac1e449b87e8916091940e33861a4a35a8600267f04ffc6a3e06c60858d578bec60ee7716fd4b0225e5cceb5fc5437387522200f66fc880e0c874119c71f462cb4eaa24e67be77ca67278344199b27e2a55b50f372b65345122225d7324ca9504ce4d12bc101639e93b331e3b60e1b520e03c9703a69f54c2b1a52254ac44b86f310a711263a5a9b87a7116ec5654f7297ea76b63f939c1f49ce99d52bc58876160401558193ad98c7c8f4b6822712429679214bb2b6e8b324b58e1f57695dc8968bca7ec3717df12c1279408183b49679b349e2e45686e722c3a57bd9547a65656cbc79aec1d3b129837d84a6975d018c7ab04c88775e9c68839955775fd66ab02aad69b76307f51db2ab33915aca61969aeff14674a557c322af6997b1a8d9c51445884779227ee742986446ea1719808996049038e0d9aecee828ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f2 +expected_private_key = 2d149d32c41889573ccb5166c597c3fe207cb806bd13a8a7bdf86267a93da7110a31f22221a17a5381c367eb1b9cd00810189c1f12358b59adbff2060ed6ac6712c660b51b553402d406bcc1d2444a863b6ff261e17aafffd01baa2b05cd83050ab460ced09bc7c0c2963784b7f9798d837bbc0483001539f0ea65a0574b46785645019b25130095725fb71556add2832ea245e250973f504dc58a4ba3c45cc8259e7906588d688f4f4cc79a1a955ee31e0fe931d16cc9da767c3a48bad09874f7730fa74c349d2163638aadfb59a462e904c5530a0b485541e391b6037041ec6a0560563f186be2ab97a42520a7daceabf1216e16870437cf012a6b6d082bbb23349628af4dd8ca9ea986498a80edfcc2418c3f5a627ba8baadf3739b3c578b2f193f57b72dc2827a2dc379aa31b6127c65352338c012cfcce0af1b33150d488cf47134e06b5ebaf0432c172090fa6671670bf7b66002e135e7c43d938343d5729e22e5597a06209e0793e65417de945b5e1aaeb2740fb1b350c902c1390a97586564fa94120cf7538b21aacc0ac0831b477e37c9e984b73ec91ed88705ef4cafd2f15a50227c0e4c0627d2a6d7875e9605afec339799690bb6f0a5b01141a6976fd51aa7a079827d37ca89726686ba95d6f275a59341fa229b4c163c260c4dbc4587c50ab8f0ac777849b5f700209f17c15251854c35aa23c20d486122ec8145565966f4a067251b96461950ac2171f1996e94517610338b88c091c356804cc691922449db0645a404ae4a641d1482b58e6230c7965c23605d66e96c8f0418ad786801d7530cfa2b5b757e06abc10518b274e3992e538922b717866c7eef827d2bb4c05ffa3322981cd8069dfe028d878a8b7a002472d302253a83ab84adf5530cc5f4671bf5219fe600ba97abd2555c52857abb76ccf4760adb30346c55aa5340b189e1968f72999e64c0b76297d232412b3c9384783457b83309ba7ef74abd50d16ea1c32a2362aaebd02da7790fb8827ff368261cec14f3a2095323502446703783ca9b6aa595d690031297c59b25414455c155924a47896716ac45330ce7069d131b75a57769fd4b4ca1990170a3570160cdbef1c930063d56e3546f09b1cd913c82057c0bb89111e6b1bba88eb8cbcd72078fcbf5059fe25c84bb5607d7b20bd0733fd96dbae2abd9531ddbe3cdd89a926361bb56ea0e5f9181b2c8c1532312f3f9005135c07dc211b824b1e63ac96e64845c35c41e0313511a5d429663796abf2443908d353766d40f47a910fd04a710ba5d6a5b301832a5b6016338d8858b220e8219512b643b8b60ca2a9347ec39638b787fdb44ce72408dcd2504de24af91130abc09b2e7c9bb26b3393ee06fd77019ed3466e019ac92a416c9683da22cafb1a9ad3475af17a15ee9f97446096647578f77fa02e79904fcc008fe509425446ca2a4c1dff32cdfa4ce120230bb5cc9cb49a2e2841bf69a1c49a762ec171698ca0445201c485a15fef2562eacabad3259119c9ba4185677e03aa0470ca848709c4ba0c8e5814416c5678033c819773db36e7a90c65fa82ffdf6921c38285122163bc0744de5c5363c9a973428a6daad20e5a62d37017b464da7637d32b6c92f059443501427ac964fa569cbb074c71053f179bf1963ac704489ebb9936e23950e51ab7e26a98d6031c652701fa4ac59aa7c15d88c0337a067257b8d916db0456fad9622f44a928df6cce84a3e6634c9caca246208920c487b9a666342abc389c14c499785bcb91a95dc868fa20d25b08ac0e48c72e9b486151f21b11731d1bf049174adf279f9020aa98c38372877299c4f54a4493a3b20f8bc71cbc490b363c4162055cf3a5c13650db1154687462fc01b5e5b78c9f603255a24189b808358e17e01b9cf736a77d78a32520b6ddc9c1dd65a00e84b562b607b6ab472d5173ab53a97db08b322e95cb3378d5d088cd3ca6fa4739c6633a27d686abf040dcaa766bcc18d6b8a2f91e51ed6d49aa37aa44531bd9dfa25c116a842e50f53a68bf1617245e8b7da778eb3343d3f2575ea84627c640a6509133f4c5d78151a6695245659955cd3824f264a7df58ec87c8aa3066ecd1b68d848cb758487e647223c0154388912ed028ae364a9fa9a018d8558c3e9b179b66f2488c2be8792b1849fac0401a9756f209889fa637cf7ecc4f2c0249eb5c6f7e0219faa2a9433759ac70dabc7baab623c2023cf7ec869b75bce953ca3316b7a6fa685bdc7c8d467273268a0797b8d6fe57ddfdb03fff7ad3d5b9c80dc1939720ee8810933a04f51b78262910d7e28c0eab06b91980b65056472a293f2361183125670ac2426e514790b945d6b09c9ec354fe7c895a30231d95794f89ee60761ac9b2aaa9a75ef168c0950afb498915b2518e010c3800764bc5a65c0c54b2af686b7d954e77bc4cf8137ab398fe93429dd0ab80fc846d4cc8db2b9b2b4bb36d4c4121639c1e74622e59250701302301b4df96b2fa62736b29caf0866096f842898b2c6012b93b5ac23d1f39e192002ff0b9005fbb8cfeb8930562a4e0aae7a40c5032b8b33d0760d96c7c203920e2439d3ea02372c7f5d80b92259349076ba20c3ad4fd21752a3963cc5126342a963a363c1157f33189732f7243e465b14969f1ca199af45b50851266742151a235a8ba9a595534bd6aa31ccf52b8c5885d571a93d2577c57057e2caae68c9c84f565c72681fb15056a345236b02a1e5b13289388f035a2f8e03402f8b0a44259179a904c94725319acacd28ac1e449b87e8916091940e33861a4a35a8600267f04ffc6a3e06c60858d578bec60ee7716fd4b0225e5cceb5fc5437387522200f66fc880e0c874119c71f462cb4eaa24e67be77ca67278344199b27e2a55b50f372b65345122225d7324ca9504ce4d12bc101639e93b331e3b60e1b520e03c9703a69f54c2b1a52254ac44b86f310a711263a5a9b87a7116ec5654f7297ea76b63f939c1f49ce99d52bc58876160401558193ad98c7c8f4b6822712429679214bb2b6e8b324b58e1f57695dc8968bca7ec3717df12c1279408183b49679b349e2e45686e722c3a57bd9547a65656cbc79aec1d3b129837d84a6975d018c7ab04c88775e9c68839955775fd66ab02aad69b76307f51db2ab33915aca61969aeff14674a557c322af6997b1a8d9c51445884779227ee742986446ea1719808996049038e0d9aecee828ba054417cc3a683a7295066aaee9cb429c4740531990744a987152dca2388ba27e3769c8bf287e54e41cbc0ecca95ce621f20831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67ef48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451 + +comment = Official test vector 52, seed: "5de720f2d152bf4e1f96a61e7ae5f1bed6b8548e32638c2ccec9f43b87d1bb43dfcf334f0582984d27e440d519ab662f" +entropy = e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b +expected_public_key = 7c6b065ef3308afba0cf3607b2c98d83f76f7c058262b55f7c0746b3c22437f00de9d7cb69f40afd60ae74b0506afb96e30669f51c464a27b4f177666f92459b293dc208a0dac5654a8058a8fabc2d1853009743a598bab2c248068750f01227be5a4f7c4c6948f9167e88894d43b5aa44687ff177de837e2f0537f708a8f73a11fe6632dc285c9026bb23424ac2d1cbce39ac6a0a7686f088d617b096436c9f773e7cc50cea1c08db20c2949a7878d18e7372cae746b04558a8fbe97df0b9a69090449a507e6e1c07a35680412033127037607b2f0502690b47bd300a84c041650dc748ac2c060260c933a0b81847243fb3267f3cc8dbea4cea40790f37cd0373a71ec00634bb3b3b087a82ccb1e1dab77300156d8094a1d61d1f1bb3f977b749c938ab8092d71c93394856ed133075e2bbdd3cc0f27c2a2d34bc0f633f5e55c0a6c989b1e277ee9132f8779923eb2e22f78a1502ba5e55b6d53a05137867c10536e672c7336a3ea1f237263a6046f260ed3871f1d479be589744361a0d819439779075cc47a5a33e18326615134d9f09b68b6873c6ccb682f6b75662cecdf5432c37189ae09faf36735ea01c12f9ce64f4116d509c70e0072a242ff126710d178daae86539226c92d090d9b60dc63539f51b46dbf24cc8d54eda255e0ac19b03d34f5a270b6fda6d6408bcf1d2a46824b5290b8a26a8131402c9aea052d0101759345f86a66a4d238a20c6531d792170c52deed889ac3050ff87c659524337830c205622a989736b788092101933c0073c0b686106a9b88c17958a8711d272392ac448b01507634df4a23846aa9d594c80bca99f17505ac1793f2877bab4f1b211d2985842795c4c1b9fc018dd15b510556ef89b687e6b01701cbce0b56159a90f7b2c6fc1039aa38449a596c087a62b2ee5a7c3799f5a601bfaf8b9c598834fa115ae010f71167fd41b5cccc45146009752f380cdc56453e554cc779604f976fdc34e9f135261eabffbf00afc514f2699aa6a5aba0638542891c6858c7f6c6c4a12e4ce2d89b50b04c33ef262ee8b0d9a7777d3c56c85b1bafac7052fdbaed24303c843110c1892381887eb351134798b9745bc229208b277c2c999570075903deb530bf22f7906b75db35c3b24b04751bf6ed41724058c70988952d86b48519264d25ec2b817894ac370bc081362c841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d21470586510acf76fcc683035b18c05eca7d0702e0453ae00a8144779117d7c19cffb568a3c0959193d689a6adbac13df43907fd45fbf3313d49425d32ab9d81c6bd9b3486c3636e6e0015152c1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fcf020cc611e3e2c8e52f5ae886b8d9480551d012885318e5e6c1ecee0a3d75b342667c691d19f34fc7946e7a7047097f7938516cbb6c7f3abdb85b15e302a5547198ac0b89e7c2bfbf74050970e8dc746cf16bee6147076bb89c5124a89e070a785427cea590301cea7ab28ada228ee7bc7fcc17074063358a706989c8d6c82677287905722cca0a24ff91958c44a3044787eab3599eaf241eadb932b06b151a1a02ba8b244e9262b96144302124dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038cc +expected_private_key = 85b01a4a587bae308d39792b47f71997fc55fdc2746f881ddf7bc215145c56d399c6447ada39230866384bb718ada160a7349747867cf695cccdb8a4f1fbb3e573ade85ccf38924f36482bacb9798d481521a0cae103cc9fc9675184490f281d3516cbee910287758a4c374c0a4313f1c29251b1655522936dc329f540a1fd887f0c775823436df736c367aa3013341e66854fb39a9eb90b23caec3e84690ad531141f39914a77a767a47b60f2868cf11311aac9da94c72e9624d21814cdc99c89a4b35e1c4c63cbb3edea06888162e180503cfc6616b24d270601d0d275c03109dd9486220b66d523a8111b4de5b99d236586a09a4f77a240cacb4a737c770bc4915f55b609075ee68499654baf90622647052a8369872a93114c80c60fca1345e20114552119669a0d3a7188d3326017ce92112f0b715c26b40851683478e5c719c11088f00aac577f5a8763d4a76e3cd00cd9061f021672847ba0d4785ea7b1b28fa364e64c4fb7f718d2352b1fc26858b6552419a4d8e1b22f8c7992e3b5373183d040948777c356d514fdfb2d0c5a636bc5416a799270e5c975c0a62f3a76fb134646b333b75582f7f2c51cf4bd37835c3fdb2ce1ea86306362f8216d27e40ca43a45edc9554f08c604624659aa10ebd29e59a60f7bd66eee447f4398addc73387579148bc4a26b6749c961926fd34296db3044cb0d2d1312ca6a6755ec48c46865a36a6330a9aa5d39167c6062ef1a7c82ca5c0ac1b163b85e43c278312c4304aa127d66576e7218c2d0c850108076109919ac6931264dc2e919ff441875e607a97772feb45f14881fbcb37b4d00b45f416cf56c9501c6598ff9425249740eacca49d92e31d679a4f16c3ccb4384db45e47621719c6c585ccc03355216d43625c08760254ae3cc4aeb1287cd5c3f0911641b05c7036c9bb360c72902325830bd25eacb5a88abdc926e0f205ee857aa66c8c47e434d8bb4a6cfabbd8b681c427846f0e18a2762152b170063b489a3e6b8ba06b00f14a3f2e6ac00725e5724cb629b7a312b3a1221c9460917c07637b71050bb644a38a8192270c857d43ea9304495206bf62b1c4c11b04a817aaa996b2a266ceb8a80aa46674f16207b61bfb484af461b6dad9a9e6c22c56f81bb355a6705310e921239497809012159e78a8a249796c155a9dc7cbfe7384dd092239c29773f6610e536a77b879eef054c5e539a381043c1b53d69566a96d1931b166c6f066cf0ec81e7492a200876d42007724ac916460a1266ab77a327ef1282479685bc43a2718c93a806c3de3a0cb918c7a734cb04759341c5b1496679987aa5db93b70f903a5f4024c3da6fe8bb2ebc27182e1179611c61f8f6214069ab83c7165a46caa74bbce0897fabea9b6b58cd34e7535b0297b4359960d23e4a498cf7610601d92af2fb6163c4b2761615121b62a7900b08d61065c83a69d51253d48399fc665962ad36275ed3774f114a079f13b8bce420b44638cfa6ce6018b58bea422a8287a6680eb21c75456592e8b24cb6c26ec3d3c1dc4a19ca16888e9b7fea1a863b7a0143307530b533269a8b692cb4522ac1aa27b01d38603fd009e1c02017bbb36da2049a2c5045a63081266d7c6b065ef3308afba0cf3607b2c98d83f76f7c058262b55f7c0746b3c22437f00de9d7cb69f40afd60ae74b0506afb96e30669f51c464a27b4f177666f92459b293dc208a0dac5654a8058a8fabc2d1853009743a598bab2c248068750f01227be5a4f7c4c6948f9167e88894d43b5aa44687ff177de837e2f0537f708a8f73a11fe6632dc285c9026bb23424ac2d1cbce39ac6a0a7686f088d617b096436c9f773e7cc50cea1c08db20c2949a7878d18e7372cae746b04558a8fbe97df0b9a69090449a507e6e1c07a35680412033127037607b2f0502690b47bd300a84c041650dc748ac2c060260c933a0b81847243fb3267f3cc8dbea4cea40790f37cd0373a71ec00634bb3b3b087a82ccb1e1dab77300156d8094a1d61d1f1bb3f977b749c938ab8092d71c93394856ed133075e2bbdd3cc0f27c2a2d34bc0f633f5e55c0a6c989b1e277ee9132f8779923eb2e22f78a1502ba5e55b6d53a05137867c10536e672c7336a3ea1f237263a6046f260ed3871f1d479be589744361a0d819439779075cc47a5a33e18326615134d9f09b68b6873c6ccb682f6b75662cecdf5432c37189ae09faf36735ea01c12f9ce64f4116d509c70e0072a242ff126710d178daae86539226c92d090d9b60dc63539f51b46dbf24cc8d54eda255e0ac19b03d34f5a270b6fda6d6408bcf1d2a46824b5290b8a26a8131402c9aea052d0101759345f86a66a4d238a20c6531d792170c52deed889ac3050ff87c659524337830c205622a989736b788092101933c0073c0b686106a9b88c17958a8711d272392ac448b01507634df4a23846aa9d594c80bca99f17505ac1793f2877bab4f1b211d2985842795c4c1b9fc018dd15b510556ef89b687e6b01701cbce0b56159a90f7b2c6fc1039aa38449a596c087a62b2ee5a7c3799f5a601bfaf8b9c598834fa115ae010f71167fd41b5cccc45146009752f380cdc56453e554cc779604f976fdc34e9f135261eabffbf00afc514f2699aa6a5aba0638542891c6858c7f6c6c4a12e4ce2d89b50b04c33ef262ee8b0d9a7777d3c56c85b1bafac7052fdbaed24303c843110c1892381887eb351134798b9745bc229208b277c2c999570075903deb530bf22f7906b75db35c3b24b04751bf6ed41724058c70988952d86b48519264d25ec2b817894ac370bc081362c841ebaefcd7625a67a48e3ca492d63bb9036a5b9a35d21470586510acf76fcc683035b18c05eca7d0702e0453ae00a8144779117d7c19cffb568a3c0959193d689a6adbac13df43907fd45fbf3313d49425d32ab9d81c6bd9b3486c3636e6e0015152c1cc78c809f3a3ffbc6f0628609b996980b3c43294c0e293940cd65a34bac8fcf020cc611e3e2c8e52f5ae886b8d9480551d012885318e5e6c1ecee0a3d75b342667c691d19f34fc7946e7a7047097f7938516cbb6c7f3abdb85b15e302a5547198ac0b89e7c2bfbf74050970e8dc746cf16bee6147076bb89c5124a89e070a785427cea590301cea7ab28ada228ee7bc7fcc17074063358a706989c8d6c82677287905722cca0a24ff91958c44a3044787eab3599eaf241eadb932b06b151a1a02ba8b244e9262b96144302124dddb5584adf5fef6bde5872a551b6840e3a082a8aa6dfb7232a6813367038ccb30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68e6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b + +comment = Official test vector 53, seed: "d71729dcbb27d7cb39e9e905025d3e55c8602efbcc483c9b866ebf82326157833169243c14550ad728bd1470f39c642e" +entropy = cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 +expected_public_key = 9e686b49d538cf32a05ab82372f7525df40085b3413f078226b97c234b815ec615b2683f1d9ab32dc0314c6cce6e9620c8e73b1dc85bed5205cde5a44f40427865a62356ce44751c7278a3b236bc2d208c7b383129661810a6a2962496d058ca4875ad234c2df951612e665984bbae791c279ee835b105202d4751f1a330dc6b0bdcc38fdd6458b0ca7a9bda026bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847487142561863b5f38c5aa4c0158ac28e95012c10a8b8e99ef7db12c05009311a74791c6c8b355e4a861dd3cb6fa085884d7a7e8cd270f656ce29f9bf3b91b798032c16b00f8cd722a1cabfbb25c3002324c56b66df87182504581a76297ee1181cf05a6d89698cc94021b16574264435f2cb137a7a667a4548c96f835cbbcf27805ae37448674aa998818cf26d15a63689777a9b98219ac3b9ecf84203826eae294800f5a07ffa886cc86e7d095f42c471c121a69a1972a7906abbd31003f6c8c0d07ef481b55fe185811084d9a472ccbcc586b6a9a6f24d269ab36126a3f0381b29532d027c2d5e21cc5b9c6ec8303e4b388a6b7216b3e581c0566558107c8b94c599f09c2ecc4b7a824fa3db9a29722317d5bc5d43827f4bc6d3a91f65dca56bc26de9d40bf2f69263cb010a9a24a749c931631ec2d13ea4d5136aa8a97ee019ae1291ea34b0807886ffa323ad3b0f83f82e5d9a2d748945a3ca34b9535d0460a6f734bbeeb66a4e3c257bb079f5d80f6deb0dbec130fe4a182fdb16291403f37a191c381723965c3fd90d9f2b67c36ca3ac141030ab516a01453532aa06b73a91b5ba7d1a308e286fced38f2858801022a453320a857b564179c55f0436b25cb191865de69877b47041d9d0c2c9bc42ca513f207a72ea9a5cc48b573fb402ba8b5ae6d73f2e0b044b8ca67c1031577099b9975fad7103c7f6bf80099bb51138d8a7af7bb509b761a9c6407dd9826b7ff87879098248d779d6f26aa0215084f286ac77c50849ad19f29a32b07ef517000ff71799d6be1d177508bb969d9479c6c037a5a18bf4302720e240dfa603b7f8745144906bb88522505b19336bee5572188853a47b4f8ed8a040b251307299be642e086317e1504784990f2149cb2d89b1a8542e4a19cfafd57ade9a234545142afcb3e544b49df75b0cc78f5aab935752746ee7a7f7936777330a66c1063c50becc4286a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5db8251de0267ea3c0eec342b51505469aa7fe936a5829463892645438a3a182859da136e033b926695421a1891610816e136dbbe36adc08cf00e4b44649410b2a11ef254144c27787e54cc5a533e8e54f11ea94f7e9c2009d25a6248321f04a53c31787c12aca9cc78fcc06b161701852215bc6c29d1779f5c183152cacb583a90399746f75c5bb337f1b580b9029b112579884f792ea5a52187a109f547cda89b7fbba90c66065a33423da4515d13bb5ffa074aadb0c55119065a51239511bb33288f994b121da8913992b979a59bbd64036968621e76ae336096fd6125cdac4f767a883e6448b078dc04b1f2b7aa49a1180c0f3bc65d2a93458291982652063419a9cb7f1042c38f483c4a90e17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0 +expected_private_key = ce732e28b21f42f2bbd1b049e6b80264b218b581cbab8c9186e325f7617895e6320fe5c697fc3b82546681b3ca5f4a52f1f7501b652f86d35ccb9756e869795c166362fac89c7b5ad41c7c74c596e2a7458e419cd10c10c890c94fd3564aa25f1ec3a3282607d8b1864022cdccebb1b1e48961207e29264a9ca86c94b71d5382c9c6b8004c818f51a52006706285bb3281618a157c80c2c00905c33316516c17f04460124fd79a1c330417984220334c84d96a66fc8a5556814c58f7826ee86f17319da3f504f0124c3f06ca50792c1e1800feea8a8e8805a54bcb90c52eca144677327f5058cca151617f443dabba304b353f4a5caabf0c179a772582711c033b3f3c1225f191b887d8294fd18914850de6b194b91c250374963bdc7215b07cdaa8001372a21f0c3845979386c27949e0bbedc0b004258866a01ec5cb82fc751ba2f4510e514a3fa09b6aea7e5e45762076b81d781c2ba91dd6f40cf13c91e947a7d7abc2a2aa91a1404d87462b42aa71eb15209a9b0d4990c2265b051163cd2ba8319576758237482f500f7e94b3ff099616225737a766c10b6aeb213b5b073eff93c3ac91bbf2b93ff47c84d7ca2e794990e2db4a7e9ab19cb50cd522427e6a935ce3976490b21792cce5e4b971668c4793ca4954b477703730411df1f5ad2557caef78c914d0c223d836c407936ec58825f3b2a1925a5164b097a94a13d8ad3a27bf1ffb0c08c72b92215cb1b67c7d2c4a7bc7a6a8a054d2a34de69c78195bb149e4b4cebab78f41612db19540385f2f74757c662c2da3c7b03a34a9524e2ab90f5cc21fc0d2ad84bb996e6c73426770ffc1c9942cc22aa2934d97a66037a18760c51b0236ca1b1880a2286ee5241ffc220a4c6ec0e296090874b3ca751dd701086a15f419c67eb4514744047d7848980c036107586d36818e74ad98989c8c02afab4134ee0b545ed707876a613ffa10be7c3f10b758b215827ada9fa1c83b129c6bdc5b621d3a5da7f396d6e29b184a38d8091b6a2c288ee2cae833a68a3cb6b30bac5ad7567c788d8c803a7b622fbd8a253b274b93593115b5b7a5282eaf93706c88c178bab897b7198c23b844219852a60410e8afa85c902edcb9a5e87a31ca84ac6b89a75830566062bc159cb129277af0645d5817c8822e384040f1621d66d41643897df21c1013cb1b426a703f120f21c780c67bb011fb3e8cb746c0b14c9f847dc1235f72e6bdfda1c55bd26e377395c4b17b764a41e0f7312782bf71820dd379befe58901a011fadac1efae549e5933aa9f9c64ce2273c486b56251674d56212c0ad7637854c7b8447a135fb960ffc435ac7553dfe935caa98bf32186817b5adb42375e96c30d0a96df39658ede95912946813cb75cc32b395aa73a916514533857b4c3405fc32c2946cf4f4251b2091b6cbb00ce296459c45e558b5048b79cc4cb8aa01bd7e82320637a62e2038d5b3c0593b42d32a38be8312ab022ebb496a5fc4a991a1baeb660a23988fba329a79dc7144d20b5246466f25af4ad971014970ebe2b36316b86b3585f6b0753711a0bf3952c688b4cf6c8a24c0964cdc1f5c1c34b3c28359ba232840063ac30bdda83f0611042fd8b7c2bb439e686b49d538cf32a05ab82372f7525df40085b3413f078226b97c234b815ec615b2683f1d9ab32dc0314c6cce6e9620c8e73b1dc85bed5205cde5a44f40427865a62356ce44751c7278a3b236bc2d208c7b383129661810a6a2962496d058ca4875ad234c2df951612e665984bbae791c279ee835b105202d4751f1a330dc6b0bdcc38fdd6458b0ca7a9bda026bd64e80868b87b58ccf2a37ca94cb06279ee77a6731e847487142561863b5f38c5aa4c0158ac28e95012c10a8b8e99ef7db12c05009311a74791c6c8b355e4a861dd3cb6fa085884d7a7e8cd270f656ce29f9bf3b91b798032c16b00f8cd722a1cabfbb25c3002324c56b66df87182504581a76297ee1181cf05a6d89698cc94021b16574264435f2cb137a7a667a4548c96f835cbbcf27805ae37448674aa998818cf26d15a63689777a9b98219ac3b9ecf84203826eae294800f5a07ffa886cc86e7d095f42c471c121a69a1972a7906abbd31003f6c8c0d07ef481b55fe185811084d9a472ccbcc586b6a9a6f24d269ab36126a3f0381b29532d027c2d5e21cc5b9c6ec8303e4b388a6b7216b3e581c0566558107c8b94c599f09c2ecc4b7a824fa3db9a29722317d5bc5d43827f4bc6d3a91f65dca56bc26de9d40bf2f69263cb010a9a24a749c931631ec2d13ea4d5136aa8a97ee019ae1291ea34b0807886ffa323ad3b0f83f82e5d9a2d748945a3ca34b9535d0460a6f734bbeeb66a4e3c257bb079f5d80f6deb0dbec130fe4a182fdb16291403f37a191c381723965c3fd90d9f2b67c36ca3ac141030ab516a01453532aa06b73a91b5ba7d1a308e286fced38f2858801022a453320a857b564179c55f0436b25cb191865de69877b47041d9d0c2c9bc42ca513f207a72ea9a5cc48b573fb402ba8b5ae6d73f2e0b044b8ca67c1031577099b9975fad7103c7f6bf80099bb51138d8a7af7bb509b761a9c6407dd9826b7ff87879098248d779d6f26aa0215084f286ac77c50849ad19f29a32b07ef517000ff71799d6be1d177508bb969d9479c6c037a5a18bf4302720e240dfa603b7f8745144906bb88522505b19336bee5572188853a47b4f8ed8a040b251307299be642e086317e1504784990f2149cb2d89b1a8542e4a19cfafd57ade9a234545142afcb3e544b49df75b0cc78f5aab935752746ee7a7f7936777330a66c1063c50becc4286a3db4aa66cb602553849b5baaf83965ac6bdb19a9e5db8251de0267ea3c0eec342b51505469aa7fe936a5829463892645438a3a182859da136e033b926695421a1891610816e136dbbe36adc08cf00e4b44649410b2a11ef254144c27787e54cc5a533e8e54f11ea94f7e9c2009d25a6248321f04a53c31787c12aca9cc78fcc06b161701852215bc6c29d1779f5c183152cacb583a90399746f75c5bb337f1b580b9029b112579884f792ea5a52187a109f547cda89b7fbba90c66065a33423da4515d13bb5ffa074aadb0c55119065a51239511bb33288f994b121da8913992b979a59bbd64036968621e76ae336096fd6125cdac4f767a883e6448b078dc04b1f2b7aa49a1180c0f3bc65d2a93458291982652063419a9cb7f1042c38f483c4a90e17aca78e9fe10b44687f9aa606cae8888e4c21ab0f7b85eb3d3a2a3d2fe8ed883d1de0ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b496485a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922 + +comment = Official test vector 54, seed: "a7c2c8edb3601396beb2df0657ec82fd5780a2723581a9e03dee1cdb018440439bb1142cab0487c5d136e9af46338ab7" +entropy = 6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 +expected_public_key = ecd4c65cec93a9b26efe3b667405482e3aa37d48aeea67c1698008da4b68683697dfd34fd72a6f39ec0aa0806ea5c59b4554182f6034b9c5b7cb438e21a14774d58afab0099e478a4ba8568e192c71db7c208b7115d29bf649bfb3d23c2d70599682c549ea28dc16597a43aa6e65c77c432f554b067a64ad62ab71492a1aad6045677c74e3e8773fb8665259abd821bf07d2157c09199435bf41992628534daae814ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0d828174805da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5da2467db42479b478f0570d48071f028110f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b2c12d34027aede4a22fd80abe26a9c93c938c6b1348708d1bda7fe6c55bf66981695487ab81362f50b7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c3a2181b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee4a13b75379d2776a7510abb21941c2b36357e8248686a5d973b946b82e40802290651a073636b367671c9c001ac91ad03b9d6e83721ae1247cc188fc05b0249571656a276eea09b6d3376c208335618b1fc2748655ceef805c39165d0ce9bfed062add0c0a50e43167c80e5301a076c9cdc1f13852a5987aa3cef5e5864a706b3de947d2ac8e8cea0c3f83745bf3185bac9fd0162510f70bd20129d7c5215026114c4b5ef044a8a29a3f01fa02a0a3ce928a65ce8cb566848110994e7ce20ea5c30304d6ccbc7477bb78b3ec527758b7828b836dbb2742af6095a0bb882c2c9d8e162618029c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca85218dc27678719ca0d4a8cd8e9bcaeb944b7c0670ab171927c56c35034ad92bb3e6714d0f7c137c2b9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b68240ad193e95c0311aa501b3c1c44b20ab6ca2d2de1c56b65618ca53f0e91550851bfbc289206d1406b27047fe610ec01a86e8ba94516aa926b99879836dbb27a7056c4d54bbd19a44096d1b3f3e9956cac29e7ab95f175b9d9a0078da633f10a6fee899f400533f0f77102da19fb02610003674828758e23b5ec724c6829b95b8a6750f1988f431e7537ca9d05701ac8ae2034688082c5c20a122c6349db27ab958504fdb4c527b223b2420db7246a4a69b58085a3c1e6997db19fe17a2bc23bcd60b924cc393ebfca864da054ba38bb733b00fdf57ab147b922278fb132c5f5774bfe368dc2b66583790d30d282a248b7e9d43a562ba1892a985b75a7aff961762a05fb35b9420905bb8c4de00a3846e38ca7d71411e89f9e2c9489c597834c7a5315080130648f5347639184f315bff2d580ffd0227c9185adf9203ed50baa43a9174a7ae9b5655f2245a15c30f877bb7dcb2ec184138792738113895a980dca31baf6b5261e10a1d98ab660c066bcb05ac25429775c3bd1550d4a823fc96442cb2770751c812ce67613e48bfbe66a0fdba909317513220ebc3c55fa1364f318812199009af24f9f70c36f81b22b20be53208f0dc44dd3b6abb7236e1fd37c53fb1ee8c86810863a86b0029a58955dc73ec8a436112b5c3a75ceec356bbd91355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1 +expected_private_key = f76c7d8002b7ca65bfe6a59aa3645a8e51afe5fb80145241134cc072a60ad4b72d80c2bcbe1630eeda661cb62e01b0798203a1a287c4b8f725dd422beee6627c864149ebabd84280739193067a2348f2861dbb7f1a0914ba2bb3ac6c80d5ca1f483c8b86c1cf5a2c3bf8f6728555799381a1b1f3cd02e445cbe798ac0361e15335380051294667b9149f38d85a1839ae43d331bf14091c4accbb24c8e8105a9d1185ba880b7e13cd3563aa235b899e7509525280a37162c043b089d5a0bd48b225ebb2d0538f49c8ac3c3b0677d8093cf70b3404016b4686d653ce4715a85953171bb937f5a1916271ad53318e8155269dba4d0a520d057963e70cc01e680fe8408d03d3275c95a2c528190924749bc32dc31b21b58c6f5e4b59c157cab7653c0d146dec9a3f94e241993b09bd62446f35ad7772279e116464fb316db8449a3ab7525b3e89b12b54f14fb19057c39510b072894831a5747782d404487926ad756b1bf81cb416d94265dcacea475fcdaa727d0b5f01b376250b123f717fbb0b1976b7704fe5ae5ac10cd17b87fa8bbd3d824d3b91b567b5c20243677d741ae2cb1c1d049a842b7f9da9cece8931851bb35776caed97c27d395108e42661aa60cc181abb2774c67773fb29b445f3554d386c87d489d895a43ef268af0c81f6065e57e744f719120323b013d35801e26bac2700968566512106f5161ee8528372d45a42b41022239fb0b3cd23c4251927b355719a1f2a0689a4abc508660dbc282706b765ca4bc1887fd064cf8285b1155863e15b112bcbb1962255b362ce8fa4c51c97cfcea7004daa9f746766f2f5487c93b99ee9825cb78ab0a98bf6863a083758e9279245e495ad0a5b86724c1adc3e67d756c1c8647fb4ba32b75a6da3a05a870fc1e12cd279666ca046e064a74625530e742efc72c1d5f959c9d256389c4c63609fa11a8fb5e70e1e2256c8164d80c69fb8f4008a647af7f3ad960265f55cb786e8726b65689a6a751fe045b7d45aecf50605d135a44793ad2c6bba5a59d293528bd94d65f54bae4798eba5b26de8b225728eb8836ad1f373f66a2134b8b429a8457b600c5a3274b0157f66f091ec88436d5667802a15749b4c9c499a36c58fc5a7ccc10a604ed00de74bbf433502c02ab0ed949f5da8b9efb83c4a2395e49413a7030f4f95901e8aa2716a3ebb09aaf61c9384586021301de0f8c085421460a10fdd176c68b4c115c91dac04121924213855ac22e8c98e3643c3d7c3b6c6c4ca964308510525c5aa00c32ad9ba258bc44a9f521a2873bedaf7c56bfc26a320c0fe95cfbe12c0038c1a65b62c18c37e61a2b9194c9ec1db8b9fd036c7c3a620b5c661d8ab0b46a6cd3391e53218e40cbdb082c2207630c2715541b10e3c395bf2a5a15ae8b506880dde937432ecb150f9b3c136881058a750024d9b247232b7289bd07462c051b7ba599c985c6eb08c7ac22135c99e85930113554c59ac06ae298d5935658f513644b01132b4c1ab84677e342a1f4a8a9d5c6a44659805cc8898e563823c8286d54a1cb4b8db866a8f5c74f782784e4b6fbad380c5131fcae11d4ec89df82490b4f1babd4673d7417b9cf04513718f2cd0cfc29707145034ecd4c65cec93a9b26efe3b667405482e3aa37d48aeea67c1698008da4b68683697dfd34fd72a6f39ec0aa0806ea5c59b4554182f6034b9c5b7cb438e21a14774d58afab0099e478a4ba8568e192c71db7c208b7115d29bf649bfb3d23c2d70599682c549ea28dc16597a43aa6e65c77c432f554b067a64ad62ab71492a1aad6045677c74e3e8773fb8665259abd821bf07d2157c09199435bf41992628534daae814ee4ac64ad89ffa1547442b8cf6f54664c550da5cad0d828174805da5d66f01e584789992bf0a4036d770b6c5b3e21b78f5da2467db42479b478f0570d48071f028110f555857e4acb555b9c7d5b5d913b75d5b393bd4b9b2c12d34027aede4a22fd80abe26a9c93c938c6b1348708d1bda7fe6c55bf66981695487ab81362f50b7376c6a52cc39769b921f575e5d7a9666abc2dd9459a5595e3ad631a0c638c3a2181b649704748141394053849b4f996f9b8a68567b73227b8c9e4588ee4a13b75379d2776a7510abb21941c2b36357e8248686a5d973b946b82e40802290651a073636b367671c9c001ac91ad03b9d6e83721ae1247cc188fc05b0249571656a276eea09b6d3376c208335618b1fc2748655ceef805c39165d0ce9bfed062add0c0a50e43167c80e5301a076c9cdc1f13852a5987aa3cef5e5864a706b3de947d2ac8e8cea0c3f83745bf3185bac9fd0162510f70bd20129d7c5215026114c4b5ef044a8a29a3f01fa02a0a3ce928a65ce8cb566848110994e7ce20ea5c30304d6ccbc7477bb78b3ec527758b7828b836dbb2742af6095a0bb882c2c9d8e162618029c1fb5aaf4b963fcc4a35ab78b0d9942fbdb53d4684ca85218dc27678719ca0d4a8cd8e9bcaeb944b7c0670ab171927c56c35034ad92bb3e6714d0f7c137c2b9a1fc5b72367c35c55d5feb93d1274b88bc558158c5d478c34b68240ad193e95c0311aa501b3c1c44b20ab6ca2d2de1c56b65618ca53f0e91550851bfbc289206d1406b27047fe610ec01a86e8ba94516aa926b99879836dbb27a7056c4d54bbd19a44096d1b3f3e9956cac29e7ab95f175b9d9a0078da633f10a6fee899f400533f0f77102da19fb02610003674828758e23b5ec724c6829b95b8a6750f1988f431e7537ca9d05701ac8ae2034688082c5c20a122c6349db27ab958504fdb4c527b223b2420db7246a4a69b58085a3c1e6997db19fe17a2bc23bcd60b924cc393ebfca864da054ba38bb733b00fdf57ab147b922278fb132c5f5774bfe368dc2b66583790d30d282a248b7e9d43a562ba1892a985b75a7aff961762a05fb35b9420905bb8c4de00a3846e38ca7d71411e89f9e2c9489c597834c7a5315080130648f5347639184f315bff2d580ffd0227c9185adf9203ed50baa43a9174a7ae9b5655f2245a15c30f877bb7dcb2ec184138792738113895a980dca31baf6b5261e10a1d98ab660c066bcb05ac25429775c3bd1550d4a823fc96442cb2770751c812ce67613e48bfbe66a0fdba909317513220ebc3c55fa1364f318812199009af24f9f70c36f81b22b20be53208f0dc44dd3b6abb7236e1fd37c53fb1ee8c86810863a86b0029a58955dc73ec8a436112b5c3a75ceec356bbd91355e4c3941a07e45ad3ecb9ae67e7527f70f6e07a757bd112947074d5120a1f2a1e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88 + +comment = Official test vector 55, seed: "467f6158cb86b724039ff18c47950ae5c49170163c910fc9a9b30141f86e9c06ebcec91497bcd156d95758c9f0c6ef91" +entropy = 2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 +expected_public_key = 8c5785417b65b2e4235cc67947d7b214627d326ac1adebccc3a64017e004499a8887c4a649e443e74720f0b1bedd52b1a8eb78b3ac2d5516b7a3233be9448575209675f4a813120422684191d6771ef2b44d92b2ca3bcdd5f5ac20a63efc237ff9d99bb4f5094afc187ebbad39b8b9ce75902190741640babf653886162645a84262a24b1885c626403f23136707816acf28950bf181742c98347022cd5941b7b69e21b5cfc2b4c6c5f301bd32a2e7882a1e1a9cd94743fc86af0cd26b51b3512003cbe8628d299663da40baef443677033da8b8c21e0a0f12fb93f4d63809375fc877866394a1a5409e2f13b3e5011a2a5877732415281b7b19991e6ee0a470561b6bcb46d87b4086f18ca29c5fdcd622f4315dcfb11db2c6cf136b7b0a870ae89669ad1011477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f499435118d9143723da05ba8f13e5cca1813f91ce01092917ba1d798ba3481121026713be1889b58375e5c4f9bb0bcc5fa808e2c00a36ca575c68b1d232778f71bf0927c5f2092d0629588826d02005db9bc0dce456e2b928ec9fb9c7a138e7b1065a2b660c287c3d062144cca71e5c1294442073ad48afc555767f1bebaf550d520659496af9237a22c27670a080f8a461778aa42c6ca9a954c28a658c73847a586fc3ef266562240acb6978e026152b1149b8d426aefe37bbd263a00da05df48375e53bacf9c4c11d4bbb055666ad008736b9c323a9974661215495e032aaec611af0e6a9244c2bfb6f3195d5121edc3c0719c3fc1365c2bfc70d5c6140e6a383714a0931ccdff946adcf73993aa113c90aef03374e251ace73770a350428ec32a9ddb4aed8832526968412863966228644b9af9842c2e967957f10d350a3499876f25d157bb2812501c8dc95365f83bc64b6340fa6cb4c2816b31824d028726de0112aa9ccc9e0b6869099d310aa6e5b79609487e7a20a56ba75c45986f92f5a4d1672f3d99927a1193ba15bf5df2586e823292593c49321bac9044e4844a7a6bcb08309e2520b6acf20e73ba5b05931e29ba43b2000a48c72a5df05ef715cd8865cf16a835a83c271402071d1068a426839ca424cb666545664ea5e7461af147b9d84583285ea1a05a02732031bb0ba40b14c828bb0e82807fc57882b31d9cf509be7b712f56994721b55da921eee8ad45c8b4e99931c9b71b473a89a2d4821213a1acfc453a41784d35b522e93c2d994d083674c71583782128476b04fec71f17ccc65b9c83f52c207b08adb10824a505b6da8a78d4c599a5b09979d9491e1383ea155576730614fcbdec1a8c801b94083a0fb55790b136bc5f37b752f3a6c636481debc5da8892ac1b04ac7447953015e7251838acbb6e24b508578b62d7450c46c76272806ac407112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b5b07b861be5a750bedb4a909605e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983be821e79682ffb18553b72cf0797b2d2117add5ac0abc71cf0e4ca83c26d218295aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6124d18b9a4606305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273 +expected_private_key = ab150a2298917b1707af1ac0941acc5b6b259d1aae8f878bb0a37089b845991b203ee4c8f1a58cf9d2cc0059ade2db131bdc5fe3049e17f350a805c6f30479be91b12a36190a5332eca4737df5a32fd60cce222b592060add75a62f88d5bf6426fb18a944195f1ecb1babac1dcf20c39339ed45ac8c3ab582382480851107683102fa1914e753731964fdff686f0a354703858c15c99f30a19d9c281ae93004c718d1ca5452fe58183d806dd666792da7a76b0927dc77793396e4508200ef5097e45095a33af5683a4dd1a5f6878c1e6fa85771a990ea16f7a28034a897855769db8e4a9a425860fec7031d09e96b665f57662b2bb86e362c3f9a706e354c12423ac6cdc74973a0767d73e75f5739747433c3451f8e5b85e5311b6e009f79c00cc07ba26b74d512520496b1998a4445c19249729225044cffd51679b495511223417b2bac86cc242241f2b70966e9a7a03c3cc0ab526abf857dc1a140ad85825757d2b5a59b97b7f8c5015da02159d013c1f15491ff4cf64c564e50c389f6c85b7c060f98011a4518cd3b48c2df68c67f3497f439c11f8504e577cf49acfae704a2b093238520292602cc2138762d87536f6285c001d6975a242654ddecb5663ac44228bbe5bd58d9b90426c66802b466b21dc8d7a23893a953033874d0a93626c00b6a4fa3fe9eb0dfeba2f3e789aad8103ca153fbd7218b95547de700ca526aed4f159639c59a7699296486188c3ca111479ddaa747f99ac825c7593911d6261683ce92ee8aabb77f82ab14838db54149194b12791c4991181c66bcf05c67e19f05dcb658d8dfab09c180967311f4e2aa03d9b8218889f87c5a5680299a7459afdd69db27302d9761daa20be37900b971694d3b6aea8c6b5d53a686beaa478f2abc17c1c461807597148719925590c1e482aa05bb73077c017c1010ea576bfb5a63031875a23b0a019d608d64a30d0dcb39d750099d1c7583c34ab1cb1dd99a115547e3e4ccdf2a872e821b2330a5f6b30918226b7fcfc9fb4f37d8103437db12ee073a49d29a7359316f8d922f783797e49b8c2b6146f76c7f8a66838c86364a788d3c4ae67d02ca09391e8547edfe86ca1d131c5b96caf479d9562688d1238c6196526b17844b475149ac3a76865c94993e518941a63a2e4559e81a46c8a99afd2a73b36c633ddc6b32b14723f04a83af89a420a3d04810311a28880247236a3761236b068a9a4edf55317e8841218441eb1137342977215992ba99c1eea7dbea33aa83382b909bf1eaa9030b4386f8baaea643e41531204bc0df8243f81367f4d979bf0125b84eb5d5df53318463102938a85214ad7355960300db40719a2acab9297381a6708391c78a8d4029487c324291a7e4a0945a806e0f24368c7a2af91b8bb155d04c557759228673b548b6a4feb8944b7334bccbab144c84344457b8b794a3d3b4dfc2357be9227f9c4ce8b98003452c1d8d19c7a8332403a41308086346129d3f929b847bab1aa5d88935d816a708c6a5e41023bcd4252569cbc724a53df1b88909267a932186c751339863c8dd49cbe200797186924c26edb976de613cc2c46beb06b39f5c264716a76e67831e4198822d77386592c777a088c5785417b65b2e4235cc67947d7b214627d326ac1adebccc3a64017e004499a8887c4a649e443e74720f0b1bedd52b1a8eb78b3ac2d5516b7a3233be9448575209675f4a813120422684191d6771ef2b44d92b2ca3bcdd5f5ac20a63efc237ff9d99bb4f5094afc187ebbad39b8b9ce75902190741640babf653886162645a84262a24b1885c626403f23136707816acf28950bf181742c98347022cd5941b7b69e21b5cfc2b4c6c5f301bd32a2e7882a1e1a9cd94743fc86af0cd26b51b3512003cbe8628d299663da40baef443677033da8b8c21e0a0f12fb93f4d63809375fc877866394a1a5409e2f13b3e5011a2a5877732415281b7b19991e6ee0a470561b6bcb46d87b4086f18ca29c5fdcd622f4315dcfb11db2c6cf136b7b0a870ae89669ad1011477899b8f679e5c9a8413959ca0cbfb3b54ad58c98b94760058c6f1f499435118d9143723da05ba8f13e5cca1813f91ce01092917ba1d798ba3481121026713be1889b58375e5c4f9bb0bcc5fa808e2c00a36ca575c68b1d232778f71bf0927c5f2092d0629588826d02005db9bc0dce456e2b928ec9fb9c7a138e7b1065a2b660c287c3d062144cca71e5c1294442073ad48afc555767f1bebaf550d520659496af9237a22c27670a080f8a461778aa42c6ca9a954c28a658c73847a586fc3ef266562240acb6978e026152b1149b8d426aefe37bbd263a00da05df48375e53bacf9c4c11d4bbb055666ad008736b9c323a9974661215495e032aaec611af0e6a9244c2bfb6f3195d5121edc3c0719c3fc1365c2bfc70d5c6140e6a383714a0931ccdff946adcf73993aa113c90aef03374e251ace73770a350428ec32a9ddb4aed8832526968412863966228644b9af9842c2e967957f10d350a3499876f25d157bb2812501c8dc95365f83bc64b6340fa6cb4c2816b31824d028726de0112aa9ccc9e0b6869099d310aa6e5b79609487e7a20a56ba75c45986f92f5a4d1672f3d99927a1193ba15bf5df2586e823292593c49321bac9044e4844a7a6bcb08309e2520b6acf20e73ba5b05931e29ba43b2000a48c72a5df05ef715cd8865cf16a835a83c271402071d1068a426839ca424cb666545664ea5e7461af147b9d84583285ea1a05a02732031bb0ba40b14c828bb0e82807fc57882b31d9cf509be7b712f56994721b55da921eee8ad45c8b4e99931c9b71b473a89a2d4821213a1acfc453a41784d35b522e93c2d994d083674c71583782128476b04fec71f17ccc65b9c83f52c207b08adb10824a505b6da8a78d4c599a5b09979d9491e1383ea155576730614fcbdec1a8c801b94083a0fb55790b136bc5f37b752f3a6c636481debc5da8892ac1b04ac7447953015e7251838acbb6e24b508578b62d7450c46c76272806ac407112b73f7946d9654a45e943b406776e057c22e669b34a39d92f87928f8689cb8363b5b07b861be5a750bedb4a909605e6e26a489a5a4d9fa7be3976479f8abab955200c479e75983be821e79682ffb18553b72cf0797b2d2117add5ac0abc71cf0e4ca83c26d218295aec75872ba3a8b3ca22a2ab83404a046355fd394bf35d66df46a6124d18b9a4606305a5968c4ccdf6b77a5ef23c5d54c68389e610b30de122c2b2cdcea30b3c780612fb9992721e26273a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb24c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4 + +comment = Official test vector 56, seed: "687c02de1041abac7b2c1e6ec2a7c3375552ed5edb10e3a8139c24cc76bda44d719d8121a81d47a0b762b4e9eeb85235" +entropy = 63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 +expected_public_key = 605471feaa9e92b94016a9a05f585f3c52a993a91a6db73c9ae6364dd2a07b6c2afb449122e76a3b273d424b94343b3bd7e7b1e1366204820819c8ba8970218a22262ca649d8e3223167be77d9a466c860ad7c320b227e873a0d68faaa441c0907805996d64f7759bdeed65cce25b367f02094714be404ca9fe56f6ad99e7d38b5396281314898036493002cb516878db66ab19e09478872c0f76abbe0f754b443b13dd5afe610c1adfc52fb3c82488984dbcc4d9850a0ee4bbc07d0051208c87914a3fa5159c775ad91a552c2fa2ac573787ffa68f456012af600af60183f97cb3e2936ef683fd8e2b5742c6de946b96f825cd0f4807640a532561c70600d4995bf8d2ca543db1eacd68d28b207617c23cd9a57bbf75abcb620d941913e6506aa0123f89c261ce9c39c605646904d22586643f4ad250870afe94dc950913602cc1cdbb77bb9b4df518d1a18ab0c5a25948302c0535908e70f84587eff169114161c3e646740893faaf6b37b42168fdbc494549776d528bfa2c2baf6a00a7498f403347a646c9a58328c59274ae8cff8b82787a29d67336dadd3404fb5509640c29c9456fcf82d4abbcd9899ab108a1fef872617c5ca780970182861c046a594d62757d33247b79e12873493634c16fa70983c9b593814e69bb160120b4129370519327ac2332063992af4370d9871e7a27d13420a6fb16ed9b579d1ca1d36a2094eac96b537109ad83f4df1a1d2e184c309ab65d75a3e409c57578214ea4035657757ab92aa930a76d251a1b87bc6b58f9d900e38156d73a1961c43be2e044314c89ea9601937c0a87d9c4b14cb9e79d83e722cc40b048bec5ccd038304ac0a65bf93b9a787105eb31b5be8845c5c57b9a9caf6243f54438ed84159f5b1b8b246073b1715b0f635e8078991118dfee2ce08887f9680bd4e672d3aa78df8954554d398d1675d785b85dd28a1675944d7597968f22855999f148cceabfabc2358c315076c6b4333a82520a8332543aa100034bb0a6776cd959bcb263074fc28956726d0d99b9d81a7dec14f13ac5ceb5b9eaaecb28e282bb517cac09809073c3d085718d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0eef3233cf91c0bf5a6a9279f6ad136808a9a3515b02e303f4da26f93264c5ab9010a9c8550b9076d6471c196675edb08223672c1a229ad31c05ebc4fab557f46b4bb37dc2b605a87b888a1f475516db87b92451127436eda7922bb45b8b8462122542de969c31622cdd62676a8faac5663a8bc2191711383ef4c1cd7a183bb55cc3c83b566e5514f233d79a2963710c5e5225f7b09b0b6176f451a7f77570b1c17b7ba335511bc3c3feb884e459add3a594dd35662419272499b4e9258dc9aca946ca80911999d455d06407cf9c69e814478a9f5151780bd754a440bc69925155fff0a675e0c322c69174c27cd804279ebd3260feb62c0e24eb63c7a042996c25bc9342c589c340e99999f9c5054ff35c760a43974096c5fd23bb9e51e2483722a132b0277bb24010297c4ba2c58bb286c49ed20b7aae98c5d9b0601f06ee53c1808e07fda53114efc6d36b28b906611be3a29e68a8da76457be5419d70059f7c329aad28692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14 +expected_private_key = f80c63dd6cbda93b6cee719fbad6bdbe1a03f18b3379306ace5625fb38c5edac9c8c94525c85961e14a76082bbd760ccf9b5ac777088b0cc80e0304fbcfc697cfb13dcf1cf777325eb473d11a43da4575b697a860445b02cf75e8b945ff9433a337c754e19453d4bbfd2f07c76e8b7a68b92abc870b56202f7634b9b37902d39bca04653fad9a0e4f0be548abb97c7a1fa18c34cebbae3987f4b3c52a5006629159ac6875276053908b389d931bc7e2871751169b6d81c8d8b5f52854a3e644c5c504675d688ba030e9e78a79e7788522516ffda2ec9946aa9791a634b6ab6d04456003acf348bdcd859567a74a7b73556820f8dfc12e467ae2fd11025e430114a5a60d3b42bb43845721637a69596eb953ab7b3e3b28b3bd9923dbc5189a37e9fe7bd9b763fa905314c0a35387a8e8552bf7135698e15b8d99b0777a0a5af1b7dafc172aa6a4d69202f10351603771876c580a7d24479db0d804b6513a09281f291f2706ab128905663aecb0bb31a41046771449d12c335051a2eb50ca81ace90940a8a6a355b21a9c7505491ea3b48b5323cc567ead909fbdb380fd504c851452bd34f0f65a39ac62d922a3c50a8566edab03358745d701332e4011022bfd4839ae7b6745c66aca80abab8213369e299253b40a7922df02ab70f9723baccb1ad563ad20c5eb8a01ae564be24f40ce91a0f06ec68c0604c74250909d317f8968947a12ea297a279821f1b5377b02653d66897aa526cf51553c268481f7174bd9495da4b0305650358a637a5fc31c99ba7ba304c6811b555e4b1c2f80eb4223c54032d16238861fb650bcba24b127026fba51f5985476103fe1375b94007a06bc2ab048bcb4a78e6d3c748b141be410992733630b8c917f89960273740a595071824a9d02908d52d334373e8a575d5d52e96e5ad0cc95bf2c761ae577b9ef6bead33103e5033e0765d748c409f8a44227b8f55838b38695c5e132f2cb9bfdd7cb8522906e9bc03dda468a04012277417869277e2169c63112e6a8942a1c13aee97300ff4caabf862058b6e7cc16f34c79ba200853701a98d630936a8a595098c8b19820ac91f47451e011069aa688bfbf5ac4ee018c53639a1b0573c8a420c4619166b011e79bd0b843d97766810a48e55d5ce389b5de4a739f77ccc5fb70d52b3ca5d01729935bf7e4bb984576f2acb7466c8248f975bad539b2260568dfa34cf2974d83699761c95405943a7a88374112f8ae79b4d244bf2d683f7cc7a533229bbd8b5e822c8b3449548634ff34bcaeff25a41aa84a1fa1f52f486f89630a7730e4f81ad23c14d6906816a849810951727042ed0782ef26c31281c0aade6c9334a88acb917b781c4f16327196422c24541065b5e80f4374da0853d478625a68f728a20c1c82ca4fcc4d62744fa658059141221a917d6121187d3b621179aa8f7b7cd0904e6e0787f9a5f65eaa78011b6b63290a55542c80a4bfad64677467dd1b12785e6bfbc31c1f3d46db55c0a035604ef658279db3232c675bc0bc97717ca3eb71d4f44caaf1b07bddc90ae982886594f98c41ae7481562cb63d0b2539eec589146735490a4a87b6ec5cc77bfc0810627aa3452cb061a1648ec7cbb4937605471feaa9e92b94016a9a05f585f3c52a993a91a6db73c9ae6364dd2a07b6c2afb449122e76a3b273d424b94343b3bd7e7b1e1366204820819c8ba8970218a22262ca649d8e3223167be77d9a466c860ad7c320b227e873a0d68faaa441c0907805996d64f7759bdeed65cce25b367f02094714be404ca9fe56f6ad99e7d38b5396281314898036493002cb516878db66ab19e09478872c0f76abbe0f754b443b13dd5afe610c1adfc52fb3c82488984dbcc4d9850a0ee4bbc07d0051208c87914a3fa5159c775ad91a552c2fa2ac573787ffa68f456012af600af60183f97cb3e2936ef683fd8e2b5742c6de946b96f825cd0f4807640a532561c70600d4995bf8d2ca543db1eacd68d28b207617c23cd9a57bbf75abcb620d941913e6506aa0123f89c261ce9c39c605646904d22586643f4ad250870afe94dc950913602cc1cdbb77bb9b4df518d1a18ab0c5a25948302c0535908e70f84587eff169114161c3e646740893faaf6b37b42168fdbc494549776d528bfa2c2baf6a00a7498f403347a646c9a58328c59274ae8cff8b82787a29d67336dadd3404fb5509640c29c9456fcf82d4abbcd9899ab108a1fef872617c5ca780970182861c046a594d62757d33247b79e12873493634c16fa70983c9b593814e69bb160120b4129370519327ac2332063992af4370d9871e7a27d13420a6fb16ed9b579d1ca1d36a2094eac96b537109ad83f4df1a1d2e184c309ab65d75a3e409c57578214ea4035657757ab92aa930a76d251a1b87bc6b58f9d900e38156d73a1961c43be2e044314c89ea9601937c0a87d9c4b14cb9e79d83e722cc40b048bec5ccd038304ac0a65bf93b9a787105eb31b5be8845c5c57b9a9caf6243f54438ed84159f5b1b8b246073b1715b0f635e8078991118dfee2ce08887f9680bd4e672d3aa78df8954554d398d1675d785b85dd28a1675944d7597968f22855999f148cceabfabc2358c315076c6b4333a82520a8332543aa100034bb0a6776cd959bcb263074fc28956726d0d99b9d81a7dec14f13ac5ceb5b9eaaecb28e282bb517cac09809073c3d085718d1dbbd75ec83707cc768bc79a3b637d0acb34f37c9c2b4c0eef3233cf91c0bf5a6a9279f6ad136808a9a3515b02e303f4da26f93264c5ab9010a9c8550b9076d6471c196675edb08223672c1a229ad31c05ebc4fab557f46b4bb37dc2b605a87b888a1f475516db87b92451127436eda7922bb45b8b8462122542de969c31622cdd62676a8faac5663a8bc2191711383ef4c1cd7a183bb55cc3c83b566e5514f233d79a2963710c5e5225f7b09b0b6176f451a7f77570b1c17b7ba335511bc3c3feb884e459add3a594dd35662419272499b4e9258dc9aca946ca80911999d455d06407cf9c69e814478a9f5151780bd754a440bc69925155fff0a675e0c322c69174c27cd804279ebd3260feb62c0e24eb63c7a042996c25bc9342c589c340e99999f9c5054ff35c760a43974096c5fd23bb9e51e2483722a132b0277bb24010297c4ba2c58bb286c49ed20b7aae98c5d9b0601f06ee53c1808e07fda53114efc6d36b28b906611be3a29e68a8da76457be5419d70059f7c329aad28692d45892f335d02d36153217d5db379b621e416a54ce8071dfda35f639a04b14aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93 + +comment = Official test vector 57, seed: "4142237070c216bcbe245a39bd9220533c97651d84832b26727855ad994a0760c52b9319ad404693e4248b8c5ff324b3" +entropy = 6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 +expected_public_key = 5b668ae6721c79e07ee5d26233936d195b62b192058cfbcb0a5a73ea0154d78224ebe84b7b611ced7256d0726492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9a725c5278c21d896ca5d706e5f03d71526cb175ade2606e3c3a24d510b4d9816aa6846a77663a80f5ac0d364747307068da942b15cd2e02a3eed2818f9056d697897b509bd5048b178240c841580bbb77a79423996072f39497869007b19442f401009ba1a039c18f191cca42f9551713cd791c9fb847690cf6247bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32da070fe29411f17a420521fc69c0d09a6425a20affc98681568b8ccea88e54b8dd9f12aef4b3c10f256eb1519671091984a1dbe972a901bb4b24246d7db01b86665374bb6cb841b3cdb2593ba5c96e32c20936ecbc4abfd24af76158b36a2c752a9bba8946b34c414eedb355a3ccb87431221aa2e936b0bd7540e697142da0817b1b51314fc71cf4017f50544474c572c70bd142c676b69afba4292f5f19e88163f2ffba3b1685073c3bbcac825b095b5d259228a459fa7e866e09735e4cab8fa733d4db6a98172846397883394059c635d23c09fbee3cab350b9976c6a8a900c8e1693c3704e779049cd1221ce767651bc23755a3a49c6be0c314a8c501579f7a447070effe0314fa3687ab92090738434e55280a42f22a66eab77a2932b07e6857a32e31a527a2a909865e053a32148b59cbac224c12468e444916ca375dc204c600899f90ba7c854b3646f2af3981797afc4e261c7a93aabc40a93990dabc82564336d01b2447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad66161890325533818f845301d9311bc8035714a722ed9206967123e65410562a745fe28f90d50d772a9cded6354132688ddb1ae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbae00a91040456f4023174c73dd8a4d50f9714ad1cff718321677a6962587ba6ca82c341f02a7382be9715b41994db91e6d0b487207b9b660793e62470b806a7444b6faab38f48747484062ff443ae1da9e7ef41f797398f0527406787e00e197ac3248ee4a0e5037cf6c754ab9a24d08936e9d3313b99ac18886cfa9972030f1a40e58b25939a21698c434391785a3a98f0445567a9dbc0b4284d49652bb1862bb76fcfc6abe60831cac9aef6469464319411a30f7601b5358568b014e67a76ea42acacd7c3fc2f983bce1bc0667897b92590dc724b5284fecf7c36b3842c61c27af1a2f2ec95899591e707272bea384cb9c8c9409bb26d743faf196d3b8b33119a379d5cbf6823d4176ca83ba4e2a426745f346a42861a7b5343ad3ac26ea8895f24a379c449156123ed91a4ca701bd789da84ba0ed5c707d373634ab7a65680667191f806b6f62cacb4b40afdd649cc9d1650c3a5e40c8346c91b27ec1b1a957c778ec9c968c670fc84645fc07881c54946b5ab0b6033f45afcc6a61fbb99746f3991f5b827c22972939c5ff620bdc4b131eb393d108c56556719abbb978452ff0a12a1d138c9065c304c8514658193232c832b05b0b21a10483c6faab378c6b1415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93 +expected_private_key = d809438c90aea78b897a528534fb009d716de8d513d32168a1537489e52255d00f49c424bf5b5db0e15a3a9b9845eccf287776f9700ff5bb7ab9f40ffeab7f148a9633546846b672cda9ab8a37c8f9711b76474e7975ab7e16675a8626f8648b605066a4fb4a5c255a0a39387b03bb7f618c9ed1b37e488d4b7175b593860f6c97d637a2d8761d3b933291b2ccfa6bacc4dcc4ddbca804c7c55edb9fc5abb503036059da4d2929447cab1bb1cb746ab01293a2b2f2638beb06030d476bcd2c335dd5226b7450f8b5b2b130332dc9210640c10daa5faac16c1381c2a0c4aae3174be4faa53ca9cbf29769084715d6f8c163a0185030b0c7c9621336a9875946fbb73bda9774c07615711451f5594a44313878204c291ab7550aaf981409d4d7cbee727ba689400dab7382605f03873f38566421a354b59a3b48bc8f62a09519d932af5800a9a0c6efd5783bd93483a0aaac7853c890c3ba18835d1a2e8f14bd0768cc7d0b951909825c988648f797f5711fbc654380e661bbc41cf89b088e1410f19669aef65fd817564a4a4f40281b5e16a69be2b503495a4b6b680a08a54fe0b80ae668041aa120c7a363e38aaf2156cee293bfd4396dcc503646acb74b9460142e4476807c058d72c9610e3cbb50a29ed7244419c2c258659b3a8a23e7e69a3047298378424b7a12df3cce34f1364732b292b105eee6a487126815bc0013d66fb7099efd4931e4301d570bcf2facba0b433b9a03147242c298052650416651db690ce81c268381032b17c429a8e418b7e2bb63d30b570da588cbc36dc3798c65f81ef05530b9043310e182e88bb3e58356de408898738c9b3c457faca42b9b81ed7c4118869d5153338ef4260006c6be294b528c779bd6c8ffcb16e2aab439d3032b8ac45216282346200cf1c812033a4f9667af842481d807f92245bb322e04343971a656087cca8ce9bd3117013ae816ba745888a4ad51a167a17482ee5b88b0bba455a565b1d97bd3b9beeaeac0b4f2879a727028d4a1c61900d0770f15451a01964366d8a6ad1b5bc520392d43bca270ccf9a72df3d68b955c4bed0352b3f78151c4716512097bc92f2cf0a2560923d01358ab1b5f8b7bc687f5c110b04c6512372f119fb23bb852398a6f599f4d145a8afabaf8ac8726abaee569c4579b494a01c67e232b93080d5df1542dd59f21760a24747e98e26466280c04d1784d9b581b4cabcac1c3dde1ca8e00588e0732f76b99ec844032d99ef65c8a9ef4a661e78a47b0542b3129e850647862132c208cb9b3986eb5b510ea1854300ee966b0d3bc09922260ffc96b894a181a95a41f1bb3acb2572475b3fe8933fe3902c965678b95512289cfbac30a2b159b8f2b3535e40881d81c204cba9080b9a7b23190965eb660754368955c0c7929e9447b92ac78e7867c1b4770596047fa820c03a11caa3c2ba48120e29ad46c289920222c511c9e18343ab20067f926435c6d6b040955f9394601b805e38a751bc8a1853fc05857eae658a8a7cad729373e73253e7728fdca89e347bbfc48a7bafa48cb167111367f40c93bf71ccf208a891c383ba3b593f2663148d779ed82b23f4b6796209d51425e9168cb22224f39f0695b668ae6721c79e07ee5d26233936d195b62b192058cfbcb0a5a73ea0154d78224ebe84b7b611ced7256d0726492a4b41d4a8d6b2ca73a3668f93a77294439b0d8ca9a725c5278c21d896ca5d706e5f03d71526cb175ade2606e3c3a24d510b4d9816aa6846a77663a80f5ac0d364747307068da942b15cd2e02a3eed2818f9056d697897b509bd5048b178240c841580bbb77a79423996072f39497869007b19442f401009ba1a039c18f191cca42f9551713cd791c9fb847690cf6247bb752a17a9873e97bcc36b793b6ad827acf418543054698d77693f9c38c84354cc81c7a3b6a43acccc32da070fe29411f17a420521fc69c0d09a6425a20affc98681568b8ccea88e54b8dd9f12aef4b3c10f256eb1519671091984a1dbe972a901bb4b24246d7db01b86665374bb6cb841b3cdb2593ba5c96e32c20936ecbc4abfd24af76158b36a2c752a9bba8946b34c414eedb355a3ccb87431221aa2e936b0bd7540e697142da0817b1b51314fc71cf4017f50544474c572c70bd142c676b69afba4292f5f19e88163f2ffba3b1685073c3bbcac825b095b5d259228a459fa7e866e09735e4cab8fa733d4db6a98172846397883394059c635d23c09fbee3cab350b9976c6a8a900c8e1693c3704e779049cd1221ce767651bc23755a3a49c6be0c314a8c501579f7a447070effe0314fa3687ab92090738434e55280a42f22a66eab77a2932b07e6857a32e31a527a2a909865e053a32148b59cbac224c12468e444916ca375dc204c600899f90ba7c854b3646f2af3981797afc4e261c7a93aabc40a93990dabc82564336d01b2447fd35e8e86a0cbf676cfe6c3d229b256e585d8373d26c3ad66161890325533818f845301d9311bc8035714a722ed9206967123e65410562a745fe28f90d50d772a9cded6354132688ddb1ae6956eadd896cfaa71c44aa925fb3b2c6b7d5e47cbae00a91040456f4023174c73dd8a4d50f9714ad1cff718321677a6962587ba6ca82c341f02a7382be9715b41994db91e6d0b487207b9b660793e62470b806a7444b6faab38f48747484062ff443ae1da9e7ef41f797398f0527406787e00e197ac3248ee4a0e5037cf6c754ab9a24d08936e9d3313b99ac18886cfa9972030f1a40e58b25939a21698c434391785a3a98f0445567a9dbc0b4284d49652bb1862bb76fcfc6abe60831cac9aef6469464319411a30f7601b5358568b014e67a76ea42acacd7c3fc2f983bce1bc0667897b92590dc724b5284fecf7c36b3842c61c27af1a2f2ec95899591e707272bea384cb9c8c9409bb26d743faf196d3b8b33119a379d5cbf6823d4176ca83ba4e2a426745f346a42861a7b5343ad3ac26ea8895f24a379c449156123ed91a4ca701bd789da84ba0ed5c707d373634ab7a65680667191f806b6f62cacb4b40afdd649cc9d1650c3a5e40c8346c91b27ec1b1a957c778ec9c968c670fc84645fc07881c54946b5ab0b6033f45afcc6a61fbb99746f3991f5b827c22972939c5ff620bdc4b131eb393d108c56556719abbb978452ff0a12a1d138c9065c304c8514658193232c832b05b0b21a10483c6faab378c6b1415b75b43796f314542b9d7c87c1ca5fc13a12e8459454d36096c3ba38e979a3d4c852032429bfe1e663e0c256c2e93cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7 + +comment = Official test vector 58, seed: "bd334d7b7eb14e00e68863f2e5551a095f8af10681c28353fd19b9a7e70b8bfe266840860609008a567abc66316c77ce" +entropy = 6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 +expected_public_key = 98cca518437873f144e7e261e8465b3720582cf7706d684f84e618e8834f35857d4a8bbc303134b5e235dd1b2387a81c663876c5530293f99571b97ae5a299df0c012e9662947089c9f81687722fbdc30ce50689690b30932a8a3ce7bcf6a353bf988dd310a2c347bfe6b30999e69c455b9f472b9bca0216c84265e5d9486f6a7f1f3125c16467ae41b9f85180497b255adb06a406a13a221388e14c0de8cf73b6a952c2b2501644831c3700b7c273b7a3180a7641621f33b41c0f9255efec1025fc46f658c64fc89352c54c264b97e5a91c2386cd3790605127740da2076eab4876e128f3746843205b8328cfcdc65feb92c2d973bbbfc68fd7a46db51641b7830e73589f41d413fb571c37685dff142863078acf00043395bfab3589b0cb435981b84e54318ab46e398389b8e146cab2a9666330ec4c90a652a0f036951519880a45bf5d000d4e40c6b6554cd222880d0b91b67153c43909eb2c0926354d436c2318c593f9fc214b548e17245c0c9b83174a6783508b97ac6a8d8a88ecd278e2e52c3c9138b1685dabba2bb1425075b298cb9120e790afdcb9792c88698cc156ca5a789474992f470b1d554514823e87bcae52ccc872c951b0c24b4a2b0460f488ee7768d56b07dc79b3b4cc321e5878ac0a5c3146aaeb6ca123206b0c7b5aa6e0bec5d0a903ac9415da345af199cab86ba99234c9526e6e8812f6da8001f31337b8498a8374ae527b6032a0cf3142d1d34181a5afd6aa432a588ae1f644f5a100fa593f0ed2753f441ae5677484738ff694abcec58781b06d0213579f827fb4f97b3fc343a445ba3035aee989685e7b20be6103fd39afabc334417379bd666181925ed369680b851a54c41b6546b9c04ca69742b2a814763674abc9cbcb03e96f9466cbeaec698cb5c9acf814e90887f8d15bee556b28f50b739185eb7a5a06e896ed0048bbd905e016436477a68ebbab1e172928ac8fa9a8b0a0d999b135a753a29a47d0136865b0f382572b0697d0fccadc8a77c1b591bd73b639e13f9c21b6f0969b0aba3ea807303377afe0f49421b68d0712823fc448fa9a468fa000d5964bcf9a9e7fc92dece03bf6732a36935b25023b47fc94c15795dd983bb4531e935a19778305d0e8a75c2cc770eb46b6d5759df503bac33f0669c775729c59eb94d48223d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb0b1ae805b1498471ac1149d578b454041aaa2f5cf13390f10a72df3385c6a8a1f990bb946f4c888e585069b5849882788a1be27da0725276ff9db130519050b74cff69a68534222499cc61f5845a8fc0ac5629e0cda20d3ea2f0046b78a2267fa0187f15721ec53083018772097892be85c1be99480247e6e30aac8fa2c593c630b981e57515e0f7414cfa8b606d931280a950e567c93b319fd23ca1b682fc0b960dd309f80455cabbbc71979c59a025008462c0681465d748ff2a6ae24e86c79922e2845568ceb5063fcb81b78295b93a80b221ae7e14a9a9bb7182c1acf347f2fa73784835f3375a29ed05e4bd120a119cd0fda29f76a1eb873aa88d0cb3c661ff0d5652f2b4604e2bdb1497486687f17b8ce7a096a59e0922260ae99bb7412e306cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d369454 +expected_private_key = ba45541ce7b3de134e6b17030710bcce09bcdba837f23566dbf1928c99cffcb674cab9c41b3151faa3078177b9126c7973e25687452da075965baa804276859b092d9d4095b5e3a27943776da65262511f62a3aa875b258c7929b502ad6cba00e3b38011c943310bb5cb24791a71bc5a2796d6197192d9594936089d88bfe976058ca16c152193838a3d7306b312f8160df15288f9063514a403acb76be298f5c92d65a90a0bcb28a4f438ea447a9c881808a18a2f5c3c1b876b3ae94ed28478fddc1e98a64fd797a0931cc4a18777e5d481d9e92c0cf2b5f5a58635b368cbc8c25dc733550774c0861795939b74e83a23757c212927805663de14a0fa00cf10f51850dbb4cdd7caabd5c09b2818cc0a09a58169e3827969518e8fc7bc8325b45656861a848347a358ef1155e5d43f7910a738a132c8892977075c9a19c1eb6399f2e7bf1dbab593a907bda509ef5b0de35a222fc951a0829a838591a0441294c35ca0b86be6fc02e1ea1b7d4004e5bcbcaa2a280ef37067d72790bb5d59587e050272ddf8b117286fe80c1bbf078e6d259a9b53bd6ff1b43a86b24adb27bbfa3546c179b8f295726ab768bc7fc8dc2a62715030d93581165f1e4a03d42374a31039d55741c9c49a1c807468cc826f0380b90c9c3f319cf1f73811d674b05c147bb2613ba56365ea04872b9244b236b0d480dd0b47b7797a23286269f97450e13791b205c8aa3310b72f3423b263d93ca320ae1ff04fe6e3bb703a6c4fc17dcfb6341aeb485576b53d1cab71d9049dcc68cf86008bdb6152994e70152f96c8ae4a0819102ba5077b26086b2dc6b04b324a31aeccb372cc18976bb9da42c8eba89640149acc544511546c5dd293c3173ef28ca92b85b86188bc6fc09e2725307a2c3802c6086f922cddc62b5989c5a6846496d2bcbf7775a4b3737ee6c6b69cc3373c96e79675cbc781146c7a78824aae4322e1a69dbf64336efc3348e414ecab04010b9f7399310253679b48af3c23961bf345b35172c1d472f9a31274c730373a29154a581631a0916a21259a46efa387b36cc9272b5284085709e46f07babfcc835959d841b3647f51147a013987dd9556111435124101e5d42ff0848bfe2169a49485c094226ec6994cb50ba9f6476fb2a39522a08145b987593f2fe67a2b2ccb036c4e6540145758c6745a389955ce9744cb8030bd85a838a5904198b318a4d265eea61c70e5a34156ba00a53f05c9be7f1ac214f6a75dc8154eeccec7ca6218b34b8e063231c450ea3a8b48f7c97d9c58fed709c350a28a34873ce76f0fc7a4237aaea0804e2d3874d726aec41c3ac8e02706da459c01736b7a5e0936b3abccbebf146350ea2a246c225ba897473817f28c8d6bbb55fe98a48de682a91770edb1bdb190a0efd677a7fc29fc62690668924cb5887f4078179aade85c0dc8e3529862b2760b187b7778a56c6b026769e339aca5f8c948801fddc4acc3bcc7ff548dd9fc12cd7a394c24a7cbe18d3d22ae3b48beb295905b217af384393705107f33b02547822b0a2cb1b57b6fc637e071c0fdba2f87f010d0c81c42db454f5c7be69ac0069c33330bc40532248fd0b90a28908f7471fbcc543fa94403818698cca518437873f144e7e261e8465b3720582cf7706d684f84e618e8834f35857d4a8bbc303134b5e235dd1b2387a81c663876c5530293f99571b97ae5a299df0c012e9662947089c9f81687722fbdc30ce50689690b30932a8a3ce7bcf6a353bf988dd310a2c347bfe6b30999e69c455b9f472b9bca0216c84265e5d9486f6a7f1f3125c16467ae41b9f85180497b255adb06a406a13a221388e14c0de8cf73b6a952c2b2501644831c3700b7c273b7a3180a7641621f33b41c0f9255efec1025fc46f658c64fc89352c54c264b97e5a91c2386cd3790605127740da2076eab4876e128f3746843205b8328cfcdc65feb92c2d973bbbfc68fd7a46db51641b7830e73589f41d413fb571c37685dff142863078acf00043395bfab3589b0cb435981b84e54318ab46e398389b8e146cab2a9666330ec4c90a652a0f036951519880a45bf5d000d4e40c6b6554cd222880d0b91b67153c43909eb2c0926354d436c2318c593f9fc214b548e17245c0c9b83174a6783508b97ac6a8d8a88ecd278e2e52c3c9138b1685dabba2bb1425075b298cb9120e790afdcb9792c88698cc156ca5a789474992f470b1d554514823e87bcae52ccc872c951b0c24b4a2b0460f488ee7768d56b07dc79b3b4cc321e5878ac0a5c3146aaeb6ca123206b0c7b5aa6e0bec5d0a903ac9415da345af199cab86ba99234c9526e6e8812f6da8001f31337b8498a8374ae527b6032a0cf3142d1d34181a5afd6aa432a588ae1f644f5a100fa593f0ed2753f441ae5677484738ff694abcec58781b06d0213579f827fb4f97b3fc343a445ba3035aee989685e7b20be6103fd39afabc334417379bd666181925ed369680b851a54c41b6546b9c04ca69742b2a814763674abc9cbcb03e96f9466cbeaec698cb5c9acf814e90887f8d15bee556b28f50b739185eb7a5a06e896ed0048bbd905e016436477a68ebbab1e172928ac8fa9a8b0a0d999b135a753a29a47d0136865b0f382572b0697d0fccadc8a77c1b591bd73b639e13f9c21b6f0969b0aba3ea807303377afe0f49421b68d0712823fc448fa9a468fa000d5964bcf9a9e7fc92dece03bf6732a36935b25023b47fc94c15795dd983bb4531e935a19778305d0e8a75c2cc770eb46b6d5759df503bac33f0669c775729c59eb94d48223d763880e8b58473683cee48e309380f7b442e6c83f0eb9bbb0b1ae805b1498471ac1149d578b454041aaa2f5cf13390f10a72df3385c6a8a1f990bb946f4c888e585069b5849882788a1be27da0725276ff9db130519050b74cff69a68534222499cc61f5845a8fc0ac5629e0cda20d3ea2f0046b78a2267fa0187f15721ec53083018772097892be85c1be99480247e6e30aac8fa2c593c630b981e57515e0f7414cfa8b606d931280a950e567c93b319fd23ca1b682fc0b960dd309f80455cabbbc71979c59a025008462c0681465d748ff2a6ae24e86c79922e2845568ceb5063fcb81b78295b93a80b221ae7e14a9a9bb7182c1acf347f2fa73784835f3375a29ed05e4bd120a119cd0fda29f76a1eb873aa88d0cb3c661ff0d5652f2b4604e2bdb1497486687f17b8ce7a096a59e0922260ae99bb7412e306cc0b25940ffddf25214ee4dd4e1aeb851878e2493c05e2bd5a30b5b99d3694543a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a15231100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9 + +comment = Official test vector 59, seed: "a0264c58ab1f2cbcb212077fd378d340307accb31f1312137cf84e3d3135044d4eae8bd38bc3e540a0c14d46458f6179" +entropy = a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba +expected_public_key = 5e451e4c8c85a192c91df27c17c0684baa6375b17586f8bf1ef12b91615bd08a340c58629cd45f7a392f10a04916c249af956b180bc418b8a95f66b2d0847e79d247b430812d682b1fb91879faab68f25602579bf0d895073780007b7d61940239913eb217cb16a63ea08b29656712a21a32c754953335c29e769df17125d84c32b3250ec96067b975bf524091ee4013a8b67a19a331daf38a396a765f7820a5e3606a734f5ba854d1e6b6e70cb9ee5b00d4d18d928921ebb8048e284a3a05a3df9469ec53195180ac9f869a8e8866d69019e9730fd6e672db024b6ecb4dc55729024033703b6fdb7bbeeecb2345782815843b7b7664627cad52038f98db605fd23d24080f809a276419c876aac69977998b1400395829656c97be262e053197ead738d9bc995145cb2713b5e181223e04497c8114ec5a05384aa31cb84406f93365d7059dd88db8f94a8f068fcd10be96e32a0e926dca518b3fe9286a755f29d83cf667407758141b2011fbb1764d3334f3a763a17cce33c2816ac79ec4cc4c2d842b004c352aba419be87281779300708bb20143a43413a2a55c41e36444046a3c021a4d7818dd146d1dc335c66152866597aa69a44f39a2814a4830e002672731d93b7fe5f77587b782aa279cc9807d6126392f812e83662d49db231dd3060f882d71d2a0a4c94adb3784ba1785187423d7e8a82f379eecba7e6f6a67b568698ac3a2c0b096b015100bf9acfee522a0192e49880439cc1fa9b30fb7a10544e1867b0c34da981ce6e660cebb8853545994454815178c60b04dca7073531aa2a5095f7b8578cd9889f3428a7d1c72b8fb320f304fe5d23a4291666bf7aa1afb5086532fc5aa347dc29279a4484261614f2774c81374aa453024b68d384b01565a36d98b751297477a61780e98135375af8ef68359332826da01ba6a73d5263abc659454f57d83172d0e515d3754270ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cc407bf027df7e2a505db531d47344552321107b651fa4e47d4b389c5825e02ca1f42839ada4d7eea2ccb24a74e34672bf1bc4f33c88c3603a3fa6ce87aa5cfe30125f99e81550c19b58a807ba8a586415c2924a6e467ca8bc85a5400f910457e8b9d74a11e2668c0f1a2a1d0389361d09900ec6671206139380ebf9390b2401555ba0a57fca36d2742f569a573096a2b442c5992c3fb65271479291f097cb94589fa15bf73cb9319d93860eacf1cd1bf7d380e03587ce3faaeb6360d79574803b5c49841b74918768efb518ca46b26929f68639eb8fa9f73e61a8b69b004cb5d9d92cf0dac9abc03171444a03409714dc1514931182701c19e242ae73b465af335c8d3588ff468346abf76604b6ef887a7eb8e8b44005bb55af328155af7928c732e7805010cf0a50ec68e29acccebc4a39e2aca10084e2543746be6c81d482f6f3c1fe0d31c6a69329d783a1bfa0b43e289a2f843c71196809ca4b82c75c59c7aa5d311350aa55e89735d9c34e6982d17c033937253d9778ca31a14a9894c5d801415056552c410484970cf2ac86b374644a37976ec4a123c0603ccc01c6c6e994514f13885bceb2f8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdb +expected_private_key = 2d80a415a1b29961459e396204e5b5e65540a2a9ae9cd52d867a9e20952fc7565b66151653448353697b09723b17e3b1ef375a3e260a5869b579883fd1eb3a06da5c11e493f4cc9d18381856fb2c36223e7214ad78a178b2153dcde882451776478a4e06b392ce9b9d0310a5a134b42c37312a8932151571d85cb69d9333ff8685569568a0fc4568682ec2f5506f59742601c46db34efb9665b5815574518ff677be1c0991b644b5931b112220c6eee10c37c19316156bcbf354fb661635e42f6b26b07f9552d7b1a65d51c7eb6a132034bd755674dfc14345aa72acbb85d4724b2ba14925421e570543ae904f9bc4016bc0389fb9922cb12a393a24df219290dc506e501003c0ae8cbbc685a25a91147265207f93f190b12baebe7cc7edec476553762ea45e48694ddd172b6787b7d9719e89d77563c9c2ccb77caeb23d7aa9181b82b6cba09aef1851235c7986194c8322280b4192b94262fc79ceace4b894c86814d4929bd773e6a73fb0c7c36c67391a314555674cf415292055bb39319dcaa7b07230204c068028b3ae7a7223df112032d60edd1b6b52ea1ed13b86231a1efb2969a691cef0d219835a44e907bb0cd2ce6da1442af1460f2ab882959e0862bccfcc6e3fc2bdb5eb673b218d6e9c5dc6461d8796945b614c81a68f9cf381d256bc1e63285141814077af5f54c2c6b487dd29cdb1d2ce08f09122d09632ab823cb00d86a57f8933743f347c203894d0043f5692a6e12283abfa1b98b39c6d638132ea4b94644e89a0adc35816be01a408f752b3215029d7661b554bd39abaa906af32f877cd4b28bcc217825ac897d06a4c233462fba602a81321db93279a19bf44131b86035db3c4ca911f1fa30146f9be0333650c3c24a5c85bf5e252413853defb040f8a16f4abb9e18cb3d496a69b356d8206c106864c7464a7a7ec5e998b3fd5b18df1d947e171272ec5aa1137ccbe50ae73ecc106250c0392a41a73a4861acea19257be33cef406b7eac1796f605a709a4bc06bbe40867966e830e8aac19af626a4642a8447276f09cfba6486564079e1aa38d7e179d9634e3398b743a1812f02818e979b4434a4516c2c77672600d5b7d3bb6d7e3253189c3694120dbe2519c62c80558ac1d522855682962df611febc9f33fa27a0787501a42802863b5cdcc6aa81b964cc2c9b8081b63750a6358db5566a0d3229d2989e98199855a2448f54688ed2487b816f5cd651206350fbbb5cdd995a9db37b089caa57ab0deddc9392ea1c0f99031a42c350cab7b6f54c1e4acdd0e28d7975a188502fef055feb5889bf87929b6006562626335b05edfc544f10cbd927ab3c4c9e806700349b9a0099801d5948cff3bf0977a9691a25ac880d593a36d1e5436eab078bd9a6bf25bc3d6b5bdfa02aab06ab5842c440e40d430aad9311015a8767417b233fa8cfc64914533031ab39b845a3c50ce00ba0f1a586053768ea48293044f3a831b456320600404761c7e826a0b111ae37db49b31bb3e9389bd3e354f08879906996df2036ac49b9c773af5fec5375519ae7b8c61ce475ac544d13a5b421b8a686251b6d1c64f8a353406248b0430c8a3a308b600d0c9506d6509aac9a460935645e451e4c8c85a192c91df27c17c0684baa6375b17586f8bf1ef12b91615bd08a340c58629cd45f7a392f10a04916c249af956b180bc418b8a95f66b2d0847e79d247b430812d682b1fb91879faab68f25602579bf0d895073780007b7d61940239913eb217cb16a63ea08b29656712a21a32c754953335c29e769df17125d84c32b3250ec96067b975bf524091ee4013a8b67a19a331daf38a396a765f7820a5e3606a734f5ba854d1e6b6e70cb9ee5b00d4d18d928921ebb8048e284a3a05a3df9469ec53195180ac9f869a8e8866d69019e9730fd6e672db024b6ecb4dc55729024033703b6fdb7bbeeecb2345782815843b7b7664627cad52038f98db605fd23d24080f809a276419c876aac69977998b1400395829656c97be262e053197ead738d9bc995145cb2713b5e181223e04497c8114ec5a05384aa31cb84406f93365d7059dd88db8f94a8f068fcd10be96e32a0e926dca518b3fe9286a755f29d83cf667407758141b2011fbb1764d3334f3a763a17cce33c2816ac79ec4cc4c2d842b004c352aba419be87281779300708bb20143a43413a2a55c41e36444046a3c021a4d7818dd146d1dc335c66152866597aa69a44f39a2814a4830e002672731d93b7fe5f77587b782aa279cc9807d6126392f812e83662d49db231dd3060f882d71d2a0a4c94adb3784ba1785187423d7e8a82f379eecba7e6f6a67b568698ac3a2c0b096b015100bf9acfee522a0192e49880439cc1fa9b30fb7a10544e1867b0c34da981ce6e660cebb8853545994454815178c60b04dca7073531aa2a5095f7b8578cd9889f3428a7d1c72b8fb320f304fe5d23a4291666bf7aa1afb5086532fc5aa347dc29279a4484261614f2774c81374aa453024b68d384b01565a36d98b751297477a61780e98135375af8ef68359332826da01ba6a73d5263abc659454f57d83172d0e515d3754270ad84543d995c0534788a6786927b952698abe693bfbb358e9e393151aac991c97fec8c55cc407bf027df7e2a505db531d47344552321107b651fa4e47d4b389c5825e02ca1f42839ada4d7eea2ccb24a74e34672bf1bc4f33c88c3603a3fa6ce87aa5cfe30125f99e81550c19b58a807ba8a586415c2924a6e467ca8bc85a5400f910457e8b9d74a11e2668c0f1a2a1d0389361d09900ec6671206139380ebf9390b2401555ba0a57fca36d2742f569a573096a2b442c5992c3fb65271479291f097cb94589fa15bf73cb9319d93860eacf1cd1bf7d380e03587ce3faaeb6360d79574803b5c49841b74918768efb518ca46b26929f68639eb8fa9f73e61a8b69b004cb5d9d92cf0dac9abc03171444a03409714dc1514931182701c19e242ae73b465af335c8d3588ff468346abf76604b6ef887a7eb8e8b44005bb55af328155af7928c732e7805010cf0a50ec68e29acccebc4a39e2aca10084e2543746be6c81d482f6f3c1fe0d31c6a69329d783a1bfa0b43e289a2f843c71196809ca4b82c75c59c7aa5d311350aa55e89735d9c34e6982d17c033937253d9778ca31a14a9894c5d801415056552c410484970cf2ac86b374644a37976ec4a123c0603ccc01c6c6e994514f13885bceb2f8b0a57073e0f3130daca54c038dc1085402160513337af2b6dd900b04dc3bdfcc90bdbda43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc6467a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba + +comment = Official test vector 60, seed: "99a9cdbfc674ab3ff2c64cded7d697a6e27a767434a47aff7c3fbf3c6a22d6043d27868955286a13efe3de36d22ec48e" +entropy = 47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 +expected_public_key = a20c8da5745f754b89a990746ef771cf07a6d8109998936b282757f344a1b00b851eaac27a9a7fbf480d44262868542128461598b5597b10cd3a2a26e3f941a9a4719ab2033fa1181ed08e3247bdd396a834e43f5700522cb307ff4b150bba9d8b6aab47361a7947b7a04b8d923202ab1a3d6644be06bc6c1e0735d5d92821c5b8e9b9a83c343d0c456b181b6fa566b0e83602428b6cd33405a95abb623a73299c5b4550a7d6c31d6ef81473489bbe457e744b5d1e39ab74d8a051951abd01a6cff3942a102a33080327437635c1c17966834340c26654a3f38616e5eacb0e489141b14e9d1b15b7fb30927715273547999b93ea2a1ca2189f5645cc4889943f3ccd95496b71f392f78a82aa1a21d66382c37154323c0616804f50125d6b0698e5dca3e2d5658ce153bbf57e4b1908c92587b8c863ff4872e9e1963ae6c971c6ac3932bc974b9f15e5743ec069ed203c3624a022f9a7420ba951425a432b46c5e8bb666091d6f223e357ce96c55bf067b3c3f51abe70abd85a73a42233800853031313ae9971d280b3aed18489e75cdc16cbb3ebc95a8c97a768aaa6c0bb0da7943037bf2b4a523e33abf669c262941f326b11ec6bc8ef51b0666268d6d433b5190bb6996f65925a7eb0761eab6906178be9a923d1c61c0b7683cea681648c44608217d6dc86441a8f423a9d1c288b32ebcd049c15ec151e256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7bd4145e837b756003bab223ff1a74feacc2e449b5dd9b5777d62ff0e20e4b395821474ab428aa2ea219bfa169b95039616598dae0b9282c69ce329b534bc7aea58e17467b1348b1ab2a031324bf835c985371b0f53877dca53570199b23bc4d70a9425a32b54749082e794e10012e9b458205e106da807c03ac3202a4350050815487626bd018706c69a6ab02fcb92621114a16cacfbea02aec424f82fb874800c61cc23bc6618ed75674a70a6c43c4068e2a7c9723a054967e4dab09f337695bbb01053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd7661dfb0b8eecdc2a4134103380988758379d0a73b0f348b00b4b13b115e74674aaac2ba8c2a7ff440340b622b5c0bce05cb601259913c488fee540d7c058a28a0c28b856ea800d26a6a26f8bcde7d78298314cea6056b00a845321a245949a8c7c98d9f8821f1264c658a8061a3014249b7e522d586a54ad7a12ad805544247d74058bc9ac0f603a44ac5199bffb69c1570c4076b345064ec00c5ae0d6a2308947593a84ddb6133ba40577b7b245c20b5d04c5d08281ca0aa10da2a358386d2a4c048c89a2402c9150a7419c0a1aa17562fe786f00486dc82a9809dab08f7b16d9432981087b6741269424598eaa99082525d5db0deaf1b96f55b41ee209f57aceb895babc38828b712724204744834303c496b7171fc458534f46892627ae54800fe6f11d06b6af2b6b9259144f769b1f16c0586c9caf01f8491251907fd213aa6c0bce5b08f060124fb99822d964c502ac49c16ce9fb17eb0c91af559947c056af77ca687c4f675c89be35aae91584cf82202734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d +expected_private_key = ca481db6775f3d276a56ca0e60ca79be147e63b6898f4b814c69a06f55111c9824cbc1c109a01a7baa259da651a1a51d60bb358432550bc1aa1cf3656e0667d726c69a39ae564bb99162c824634b8b8a706d82175bd9657ec09a308b51a3b429822667a5135fe4350a8b3ca10e8b03b6da0bbd616ceec0a08476909c6182ef0314b284cc3f43c337307facf7b617348779d7493ae0a25d415124bc5d9134182169238cea1a46a3001a8165713a3e5c16ae03a477207b99c2cc674fcbb14ca439fcc3032e4c2f1e92841d73859c76cfbe245193816d87c12bb3f12763174997760d6887a429a37f78c32cc1ac8facc587aa235821c254a2341b7c6bcf8b52c908836b67d39d63458afa9530fc2748de4a698af346f8b5405dc7b43b05953554021af73c585b6ef248c07ed23116baa18c845571823d25cbae0af57d4f6ab2473b5919cbabdd7b4cccc1be89150cfc585953389172590edd61c3885446b500495247aed57a9fb1140ceb6b29f7f9a9f524106d8cada3432c12468f9bfb9a50b920cde85654c25249350f6760293ddaa28c771963497c4c5230c05862a4391330f54cadc3b0c92b9798f5bdf8b21016725ac8f565466464c2033872684608111248fccf94c61337eb6b1a9017e342c29eb2b148936119797fdb2757bef51a9a2601a00c6f0547b1831b1ca1118cd2e1cdd601a0b491c588cb5ed88ac36ae183848b9f87264cc5b020b2e965e5b89ff74c58cd2b338177bf1350afda9a74516a5845381e5fe132b4089506e8cde6346fcc760759592345927c5c6a97045b0ad3973e806778759b35988953c80b3e7574b7caa225c744372ee3042e07cce978a3f964395d40176aab7905a4bba98250f594c5a96bac41851e09f897df0376a89516040c1f8fccb93d44ab474c56913826c9e2171ef67510b53eb31153fc028b3625aa7a353bbe79cc76d393e209115dd00b5d6c98f80101705544604351cdb87715618343bc3fa227c1e9fa1ea3989390b02c59ec9174e5165239427592a2d973774ca62dbd9410164bcfd95834c11621f7da54dc55c44c594785fb0016448f2cc39a05e01d8581658a2410caa630347c3f0f6c86f344816bd13b3a04313a730f2de9bb50659b642353f6463d2e2a1a78b722287616cdc266b01098b3544632152db3b23938d67c63e51949496e13182326d5b7d70b81d90cc6c5d84d4e5907833a7a76d3850ac4993a696c4b210dcf352a32b4c83dc9114305308129bb4ff73a91d733303bca92fc0083d95d32ca54557a6ff3c42c2bab46ff913e1d39ba3f6092e30ab47f9985c7c439448c92b245259d388e291c04de427f378011ca983b21b2ba8bea9d6eb36001ac4fa5061ee1670066f9252524848973782774cfa795a2285a2669515d4fda7093bc54439753fb6b4e6b781eeff574155b2438e074b332417d751eab1ba1475436e8fc1b670c3928a3553d2bcfd1a59c46ea2542884f91f98a38d42ecc026ebcf91258acc99a50ae1edc88b90c98b74c3961b70759f39b3c20175fa80386376cde2b66dff213151b800921ab6932b45b720932a540c79cca0eaca0a9d5bc841c3acf3c08096c0446326114f05cb09745ebb986ddb76913faa6a20c8da5745f754b89a990746ef771cf07a6d8109998936b282757f344a1b00b851eaac27a9a7fbf480d44262868542128461598b5597b10cd3a2a26e3f941a9a4719ab2033fa1181ed08e3247bdd396a834e43f5700522cb307ff4b150bba9d8b6aab47361a7947b7a04b8d923202ab1a3d6644be06bc6c1e0735d5d92821c5b8e9b9a83c343d0c456b181b6fa566b0e83602428b6cd33405a95abb623a73299c5b4550a7d6c31d6ef81473489bbe457e744b5d1e39ab74d8a051951abd01a6cff3942a102a33080327437635c1c17966834340c26654a3f38616e5eacb0e489141b14e9d1b15b7fb30927715273547999b93ea2a1ca2189f5645cc4889943f3ccd95496b71f392f78a82aa1a21d66382c37154323c0616804f50125d6b0698e5dca3e2d5658ce153bbf57e4b1908c92587b8c863ff4872e9e1963ae6c971c6ac3932bc974b9f15e5743ec069ed203c3624a022f9a7420ba951425a432b46c5e8bb666091d6f223e357ce96c55bf067b3c3f51abe70abd85a73a42233800853031313ae9971d280b3aed18489e75cdc16cbb3ebc95a8c97a768aaa6c0bb0da7943037bf2b4a523e33abf669c262941f326b11ec6bc8ef51b0666268d6d433b5190bb6996f65925a7eb0761eab6906178be9a923d1c61c0b7683cea681648c44608217d6dc86441a8f423a9d1c288b32ebcd049c15ec151e256a322ee79e2c689a23a53b8d473f4c643aedc646401761a7b75f7bd4145e837b756003bab223ff1a74feacc2e449b5dd9b5777d62ff0e20e4b395821474ab428aa2ea219bfa169b95039616598dae0b9282c69ce329b534bc7aea58e17467b1348b1ab2a031324bf835c985371b0f53877dca53570199b23bc4d70a9425a32b54749082e794e10012e9b458205e106da807c03ac3202a4350050815487626bd018706c69a6ab02fcb92621114a16cacfbea02aec424f82fb874800c61cc23bc6618ed75674a70a6c43c4068e2a7c9723a054967e4dab09f337695bbb01053a7c5dbc764a0856d2b75dd4a94a9898af8b95a62b487ec7fa9f00ab75325c9ab8248f1db65fd7661dfb0b8eecdc2a4134103380988758379d0a73b0f348b00b4b13b115e74674aaac2ba8c2a7ff440340b622b5c0bce05cb601259913c488fee540d7c058a28a0c28b856ea800d26a6a26f8bcde7d78298314cea6056b00a845321a245949a8c7c98d9f8821f1264c658a8061a3014249b7e522d586a54ad7a12ad805544247d74058bc9ac0f603a44ac5199bffb69c1570c4076b345064ec00c5ae0d6a2308947593a84ddb6133ba40577b7b245c20b5d04c5d08281ca0aa10da2a358386d2a4c048c89a2402c9150a7419c0a1aa17562fe786f00486dc82a9809dab08f7b16d9432981087b6741269424598eaa99082525d5db0deaf1b96f55b41ee209f57aceb895babc38828b712724204744834303c496b7171fc458534f46892627ae54800fe6f11d06b6af2b6b9259144f769b1f16c0586c9caf01f8491251907fd213aa6c0bce5b08f060124fb99822d964c502ac49c16ce9fb17eb0c91af559947c056af77ca687c4f675c89be35aae91584cf82202734379b56784fc5ce56e3852d89b052367d9a5d375d06ec7863e051cb44929f17a4656a2cb2c58d8d457897a1aa0d6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff93588f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787 + +comment = Official test vector 61, seed: "c799d57b41f28c5c446dfc58a5ac6499c4bcf3c162afd2b09a16549826ec2a6f689e44bafc4acc82f5d6aec23f4a3993" +entropy = aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 +expected_public_key = db55c6cec7b63c0721aad84d2b6551fa941167c78a0c105ed9e5300a24bb2c8b2265251a38ec2b9d05a0635b2849a81a2a7c6f2660504d5602fd2763046820ca168d70b76e35b9641ce46a44f2a394f496dc32353c1a84302381e8d74ce4294a4a260a5b0704797567ae831d7c4410593cb7b9ab74d2042c84805c3aea6ebd193a927c8189082333b3a5e96857e3970be7daca4c884d7bb0b3b9c250cb4135d0b8c90ae320dcb3c423e8a6de79ad594240ae7aa036e320ad8807ccb7a1bc80c704c9532960864a9528347636b4123337db7e2de37823c6ae084418fdd05ff7e904211924fe5a370537762dfa012a2153af96a46987776d245fdcb9434d66aa10524a3ca74e494c9de919c8e23c3ff77c58cbd1cbaf5b8a69803a32e23959b2a7d9f808689906a0985aeff5a8464a2af64ba053a3c18d89b2cae3814cd712484288abf7655063c403f635d7a2afb9d804e2e89677131bbbf7009c981548036726d25f05f004d605a24b7c2bccc4294f065c013c8ecb242d25611b5c82bcabeb9e578758f2f3ad3f087bb6813db1f3990c867a2e679f47f074fd012e87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c870364192c555b81af58962ae771df477ff421a9b46c6e64bacd1a8a6d00da4d9507212c910ed2c62d199c7e330a11982c514f27aac092a5216b13ad54beebaa4049065a68d8ce9b1c969ea01599a71d633197bc33c2f6f958f72ccf14c7c09d973770f170f1f7bb9e458a00936d8677717f4a17655bc7a7ec56119779f7aa391d2356ae3a97d7ca04971cc2515154e148568c176a659a8decbb2c5c449ccd914d3cb7431cb3a0a400a8c7b59b1cc770c5bb5b64e0932c61783c9979d6cbac042216a0cc5800ea160c8c8556e0721d610fce13992396c382e93bad1514d780cee046525c443fae063c5882a01e5a73658a30864b1d6344a6cc46729bab7810c46f5b480d309a263e30461769a55a2965ba6ba0b44054f211b98c6c2355150acab81881e5ac1e561a4bc4b39f9902d1027e56155f5d71b7ca67415185319ba769f88345611ca2c20b233dcaca9ddba42edb204576bd028a79bfca57c9dbb0a54b933c970de35032b9b51d00c9922abb5106897cb896065fca846aa486d9c27f5b616e99ea0ada711729b75d86669645b9a223959b3c1c2f3ab6536d74295473c4c055aef8c2cd2d321e9e73cbb872698b3a60667bc768014332083139d08c321157cff1481f259ed56a7a3ff1717bb64fc951297c709a4ae3c05fe3910d6507ac947f944b970070570fdc9843a8a5ba564141f80f1654766f93048be6297a1cb76c105a7ba3ada06a42ed1ab3c17542201712f11824766c07bf14685ab0a9f69a15ad6574e59709d2411b37b509de3b7fe5e8b0ac65922df23e680c33141418f9551660467accc0c794a67cc530a5b130b4cf1c28747601d26983764acbddd30e42eb96125956a5870142574419977209a12e09ab3c5e8a22c1c5252527c90987a816b8830a757ec44b12e2e2bcbf19097d02b19ae47cc7bc99189370a1aacef36415ded82fa7a63be809b515f79f06612dabca5768201c59e2c92eba6d13b72c31648ee1d504ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112c +expected_private_key = 90d7129b79c095b3063f53058a4baa74c262a99c822894254a050409215fe67773c26c7a6dcc739d8406a6055b388204604c7b065c0cdccc16fa880858a36d6200c6cec473bf81b245e09c6e5a55a8d8314334c23dc14fd6a9c011a2ca93753afa8609320b1d01fb9a2a4263ddeab8d5a00c40346b8f84afc7b945f521321103a5219b533f52bee42256edd1b9a526013a00ce07d44ebfd66c0bb67775d1acde4aadb7c98731931e54f5c458264894971df5d0ccd93817bb77a2e7d29ce47aba205c0971f34096280cc725a3c22a4ee24a9938cc2fcd9a670272a463c852efc04388ca8ce86a8e9f63273aa208610c2274709c55922ad371c197741af0526218e84c3bcb61355ab94d5c94dcbb4bc08986ac075e01134b4029c8c1d78f829796c1cab0ea2075bc25b797d82a8e0385ef1094d0a2b1731624308487991a7164d8a507f2390f354b4fa3a225d5a46463145ebb57b98724f1d3cabf11ad4fdc00bfa267d8f3107ceb7da37c060aa23e247c28ad0069d30681e37807117ab841f23548caa02212afbc1bc54297202fa549def55ddeb5ba4d10ace2650511366ebe9c1d61fa9d5574c86c0714aa523cdf946e1fd259148a7e2ab5c21884314e3b8082bc210b5209ccb6b95eaa2ef62203a0b707bf9c5db1a155169b07d41c0edb9709744caaa36622f189773ad7a59dc142317454d9c81d55d1c637876f104b6836a6842b87174290125505461eea77d63a8dad03c7941b69d7f66e434922e13a8182fcc35e51c9ce81978e35818504cb32e4a6dfc777227a5484409a38b2a1e2243110e84d024b1fe0e0bb36d4aac0622152599fefa177b294bece391d47553983e420de5462c72ab588b2934680a399ac40ef35a5e8819458e0a7bed1afbb29a446ecbcd4e45a50176ee201526e314cde085afda30226039ceb41a14d87256bf566db30ac77acb80b29b1f9d602e919707c96863304372a353771e1ce994241a12369fbf42bcb4315592724cd5085a589b1b4ca46dc49cd65a1247178151e455741c8b5d7c9cafcb75bf27a5b4ed05b22e932b1e3bfb0c93248400e5485486e0c39fd5ccec680c78e6137be96823deca37c6306d31c9142fc03ec540ac0120ebbe9bd5237583e1972d0c4676708ad35b559fb89bd872428a3e0504350451dd65f58bcb292c0ba437394dae55e6df13a8f41827939016a081935d1788c4807a53a011b89528fb60f386632e725b163e83e105324c3914f26f389dac199a926a25a02624d9a530bf0afafa4c5ffe6a5ef9422e422019ff337d1bc2fe16a07d9a046d183137d477dda378e17a95fc7e02ecddc0d551724a4f36ee7648c9aa771bd15ae29b7259abb63d0983917156ede6557be445735ec539b2199f9816c562842627cc83bcaa659075f5179abdd1a7056d27f7dd96a6813a940a9321cfb1946e95c16836ef028106bc26a3ee450d8e569eeb23b70722bcbf828821648b1668e6e47869afb16c0e4b827c4cec3c4c9948a6c7f874968dc80160a811cd06d58a885d033210341a6f7907f53a82c98468f6bdb7cc7a60107973db0e70f9a387673234d6665019676215ee4597c65a13a2636cee74266f373a4e48bb1db019bf44ebfb0a5db55c6cec7b63c0721aad84d2b6551fa941167c78a0c105ed9e5300a24bb2c8b2265251a38ec2b9d05a0635b2849a81a2a7c6f2660504d5602fd2763046820ca168d70b76e35b9641ce46a44f2a394f496dc32353c1a84302381e8d74ce4294a4a260a5b0704797567ae831d7c4410593cb7b9ab74d2042c84805c3aea6ebd193a927c8189082333b3a5e96857e3970be7daca4c884d7bb0b3b9c250cb4135d0b8c90ae320dcb3c423e8a6de79ad594240ae7aa036e320ad8807ccb7a1bc80c704c9532960864a9528347636b4123337db7e2de37823c6ae084418fdd05ff7e904211924fe5a370537762dfa012a2153af96a46987776d245fdcb9434d66aa10524a3ca74e494c9de919c8e23c3ff77c58cbd1cbaf5b8a69803a32e23959b2a7d9f808689906a0985aeff5a8464a2af64ba053a3c18d89b2cae3814cd712484288abf7655063c403f635d7a2afb9d804e2e89677131bbbf7009c981548036726d25f05f004d605a24b7c2bccc4294f065c013c8ecb242d25611b5c82bcabeb9e578758f2f3ad3f087bb6813db1f3990c867a2e679f47f074fd012e87b3b6f51cb1707b9287d99fdbf43c8e58940109c376789e16c4a30b6bc34c870364192c555b81af58962ae771df477ff421a9b46c6e64bacd1a8a6d00da4d9507212c910ed2c62d199c7e330a11982c514f27aac092a5216b13ad54beebaa4049065a68d8ce9b1c969ea01599a71d633197bc33c2f6f958f72ccf14c7c09d973770f170f1f7bb9e458a00936d8677717f4a17655bc7a7ec56119779f7aa391d2356ae3a97d7ca04971cc2515154e148568c176a659a8decbb2c5c449ccd914d3cb7431cb3a0a400a8c7b59b1cc770c5bb5b64e0932c61783c9979d6cbac042216a0cc5800ea160c8c8556e0721d610fce13992396c382e93bad1514d780cee046525c443fae063c5882a01e5a73658a30864b1d6344a6cc46729bab7810c46f5b480d309a263e30461769a55a2965ba6ba0b44054f211b98c6c2355150acab81881e5ac1e561a4bc4b39f9902d1027e56155f5d71b7ca67415185319ba769f88345611ca2c20b233dcaca9ddba42edb204576bd028a79bfca57c9dbb0a54b933c970de35032b9b51d00c9922abb5106897cb896065fca846aa486d9c27f5b616e99ea0ada711729b75d86669645b9a223959b3c1c2f3ab6536d74295473c4c055aef8c2cd2d321e9e73cbb872698b3a60667bc768014332083139d08c321157cff1481f259ed56a7a3ff1717bb64fc951297c709a4ae3c05fe3910d6507ac947f944b970070570fdc9843a8a5ba564141f80f1654766f93048be6297a1cb76c105a7ba3ada06a42ed1ab3c17542201712f11824766c07bf14685ab0a9f69a15ad6574e59709d2411b37b509de3b7fe5e8b0ac65922df23e680c33141418f9551660467accc0c794a67cc530a5b130b4cf1c28747601d26983764acbddd30e42eb96125956a5870142574419977209a12e09ab3c5e8a22c1c5252527c90987a816b8830a757ec44b12e2e2bcbf19097d02b19ae47cc7bc99189370a1aacef36415ded82fa7a63be809b515f79f06612dabca5768201c59e2c92eba6d13b72c31648ee1d504ec3e89c8d796e77fa9a772499aec973b63e864ce36a29de99ecec9695d12112ce2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78 + +comment = Official test vector 62, seed: "f7ae036a0176a9de9a036a542dd2840033277c44ae936d10b768566216de9d4395cd42b116873b69d9804ba6ccbc05d5" +entropy = 6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 +expected_public_key = 7a2912329482f244226ae33507ba8fc8366736352380b346ca39a936190f09576c5188c5e82315e3532f34d41f1b50bccc42c1138802ccd5b50a7846ffa7bcadd91fe757ab7fe30e873ba233e13b21d25461030593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236218f199c3925142b53500291a3164516fabb941f98f0daaa1e2d619c9622d649a0408ac02d5ccb9b787c1f9b196da37020e362ecdbab03cccb63b659c6347104074b1f8254499c8452364726b1294669a3a24ac8b487752175b30cba68860184d5f78b845b107beba80f8750475d059dad57caf827878b926facbc00b54388f24b7b431347e334ffa046c45e234124c958cf66023dca620e1400cd5c08b89554a474d7d04086e5cbd0d051c03c4580d3442a575255c833026bc19dd301a70367fed300ef27779d2a49819a370519c7fc404acb3fa441a931c67a3033799519c883bea134242f35f92393dc134bce15713ddb33e252b991af10c7134a8acd09408c8cb2ada36bbc25224e8867a4138ed9b4daf403a477321614b3ee5c7bc2281441936b0b05513c1525421871d007346bcf52d6e09b756b4529bb5480aa3165e617cef41720167707f35a4415975a62114c7918ad83bbd8905a283d14d22b2400cb29fb1e102562cbee5a9c10929229f8c60a4b153c430a361812e75b244e4c3954a945459f735d45572e83b505030c13867c720567fd681c539d7094f5558dc5a86da79b38049b0a45a1259713af2c1640ee0279bb7191f0c0ec59c2f91184ca70a2e8b7576ce493e32f2c549c4bad6c925039c4c57114075281ac7631ff4d94ee0723c3400cb2d73c184489aa5b440ad470cde548f2f70903d08b9b4cb6db68a5d4fbb049a5a9727f50f9e6c59295c62bed7182ca96d6093578dd014f7eb0b121ac6faf917fa9b47f6650c6c7336d8848dedb92a0f70971e456e9ae625cfe266b1000c4ea6252de1ce20c014bc161fef405ff327cddda37be4919c2a0c097d6995b0eb743ff66a548307cee1080a13841ed12333e62eff081514a5915022c550c6021a27889bb0421df3a709ab2f9f3b0c0f6019fa8810ce3a9c37f53cd651acb4e5bc1d8b231f373b7a4ca6723a9710681016943f29697b09f6abfc1c60e8fc4c201a9ab05c260d2452c83b88423b904df74f425a9b4d116de0d059d96779d61017c2e984c2bccd6159c82dfa5ae7bc63e59304b1105ca054a71d753e7e583742e715bfecc80e51245ff53c16854ae0ab41c581402221cc8834a5f4556a84c19f6172c7c80c759299a42c71bd67040a29185a45c14b91b56a4af9178e0bbb0c4c197549b5c9765a8874686c63445dea7a85d43ac4d0b979b4ca13a80bf8db634a163fe3f4327210a7a128716b9805bc1920dd322b15c74fc722a126069abb8c95bd090f84497d832a1ab72358d4193b6542bfd627a139374404dc1998416f46054d1b4b538e778d6d0507fbf5571bd01ce56362164793e58355366495aec80eea35463c4044b202451b3604d6ab96acc3617acc1015379564d6a5ff1a6ae4d802712a94422a99d90988206776055545172b0282b5162b479d748a2e9d22356af11daf2629036665eed0642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7 +expected_private_key = 0246c2025246911b525e6c3421584bfdbc83d73ab936e76a26236a85215c78db7ddd010c2e038e3dda69b5aa2e9f4997d8589bdbf918be1c046cd518e6958ae6925146009d185b53456b5e16d59257f20cd0f6677535510d02602d5ba5b61c440fa07fabb1b5fbb38437e90522665776892ef205a41a1a2083902648844dc9d65e633266af871481f036a2888d3fb9901355397f37875a4494777c781ec40478d09a820204a4115701d25a74b4bd91676ea6391fa160617c80cd05b0a80e040cdf22b29978ca55282f2c40316a35433dcc8ff7cccf4280c0b11c548b5cc08fa45bd0760ce03a02f25689d0f057fae44cb1574c42e760cb331c2ce4be16823dbb2870592ba844f30dc407298590a088425e023b856e106437c6074547260a856e648cba07e51a23e70d7cc65656b4692ec24277f04905c4aeeaaacd36341c705b504cfaba73201c2745ab06b056f1768447981e0d676ec904698edb230f369190d8c1dadaa5ca59001ee8a68c302f04298dc5700c56b2b577d89cd9a585b239089847cd3e96ca80d928867b27f3657987724ff9031649c246cbcb4673f6cb8544150c9975a13938c89a68cd0b6de5237fc8d2b7a6bb94e0c0856f00b821636801e9ac84f35276065ee4108bc1d755c1c428566a1ca3762d050458dbc7093567a4465453ab8656272a3c03b4a3c55929271437724471d5d4926109c9792ba49d117813948106d27c33069eb3c40aa8370b79e23f35934ac28666fe72b43f722151f3c26c96cc3b6a40d9e1876e55970f252811070fefc00d70a009e4871f136a08515ab239c33e2de638c4260d0c89cfe30b8f8e5927f2c59fea3947ffd0bd636b10876c3c387c00e15469b42b80bfeb8681dc7715c2b248ca6fed92a9399b72d1023f9507229593bd9bd936a0f6abba09bc3367782370b60d9cbd0e8b3d5744101c8ca97eab822fa4cc399b5be3195cb1e3c9260030af60bbe3295c4de898c502543589142cf48dbc7505ec9a9d93cb6dd4c9678c1cc0a082c5631a255142603dcc01fc07c27d628d89f09b473816b5d5171c18a3f9737bd6d3420d4bccbd3a5624a2686e54062ce4696e061c83bc2586f1a618639e51e63bc6c64825eb50d4f88334b29145bacc49e28dd564b7a578217fac230ad00a44f3acbf8753aa572d66e1ab9198cecdf9bc722455bd267faf98424eba4031c3bbec8298a9388cabc6b3beec7a7fbb1c814811117a9d550407c9e6099cea65ece641f69454b6a0ca9bf86a3dd472f7c0a7703c6a5b25464c0b091b29258de673220857878434ea14cf50054fb2e63547e9be15107beb7a78cd5c00cbb1462a0347e72b51a15ccb5c333894aba511295b37c97c7f4c2eb6d97219559b40a67310f457108015ac1b8e3ae15acf85689c4058ec8a0bb18b75615011f2701bde8ba70986b39d3368e1f978675a49fbe8509f1239a1c88f1df4adf0ac8b68a87e2a403373fb808a7b1192371c7e68b80854b0e4335739090b953a2b67999f9878a32415b78c22289eeaaefe3298fd38abeb6abcf5a55bca388004e46375a729cc45926a7c3e3bc8b4e2a2b196aabe5651b642c1cb50f666a1bb6da4d1cce8c6344356a68de044214453d03b5c7a2912329482f244226ae33507ba8fc8366736352380b346ca39a936190f09576c5188c5e82315e3532f34d41f1b50bccc42c1138802ccd5b50a7846ffa7bcadd91fe757ab7fe30e873ba233e13b21d25461030593433f4f66482d94b916aa8d1b4b8d6786926e9364cb579f52236218f199c3925142b53500291a3164516fabb941f98f0daaa1e2d619c9622d649a0408ac02d5ccb9b787c1f9b196da37020e362ecdbab03cccb63b659c6347104074b1f8254499c8452364726b1294669a3a24ac8b487752175b30cba68860184d5f78b845b107beba80f8750475d059dad57caf827878b926facbc00b54388f24b7b431347e334ffa046c45e234124c958cf66023dca620e1400cd5c08b89554a474d7d04086e5cbd0d051c03c4580d3442a575255c833026bc19dd301a70367fed300ef27779d2a49819a370519c7fc404acb3fa441a931c67a3033799519c883bea134242f35f92393dc134bce15713ddb33e252b991af10c7134a8acd09408c8cb2ada36bbc25224e8867a4138ed9b4daf403a477321614b3ee5c7bc2281441936b0b05513c1525421871d007346bcf52d6e09b756b4529bb5480aa3165e617cef41720167707f35a4415975a62114c7918ad83bbd8905a283d14d22b2400cb29fb1e102562cbee5a9c10929229f8c60a4b153c430a361812e75b244e4c3954a945459f735d45572e83b505030c13867c720567fd681c539d7094f5558dc5a86da79b38049b0a45a1259713af2c1640ee0279bb7191f0c0ec59c2f91184ca70a2e8b7576ce493e32f2c549c4bad6c925039c4c57114075281ac7631ff4d94ee0723c3400cb2d73c184489aa5b440ad470cde548f2f70903d08b9b4cb6db68a5d4fbb049a5a9727f50f9e6c59295c62bed7182ca96d6093578dd014f7eb0b121ac6faf917fa9b47f6650c6c7336d8848dedb92a0f70971e456e9ae625cfe266b1000c4ea6252de1ce20c014bc161fef405ff327cddda37be4919c2a0c097d6995b0eb743ff66a548307cee1080a13841ed12333e62eff081514a5915022c550c6021a27889bb0421df3a709ab2f9f3b0c0f6019fa8810ce3a9c37f53cd651acb4e5bc1d8b231f373b7a4ca6723a9710681016943f29697b09f6abfc1c60e8fc4c201a9ab05c260d2452c83b88423b904df74f425a9b4d116de0d059d96779d61017c2e984c2bccd6159c82dfa5ae7bc63e59304b1105ca054a71d753e7e583742e715bfecc80e51245ff53c16854ae0ab41c581402221cc8834a5f4556a84c19f6172c7c80c759299a42c71bd67040a29185a45c14b91b56a4af9178e0bbb0c4c197549b5c9765a8874686c63445dea7a85d43ac4d0b979b4ca13a80bf8db634a163fe3f4327210a7a128716b9805bc1920dd322b15c74fc722a126069abb8c95bd090f84497d832a1ab72358d4193b6542bfd627a139374404dc1998416f46054d1b4b538e778d6d0507fbf5571bd01ce56362164793e58355366495aec80eea35463c4044b202451b3604d6ab96acc3617acc1015379564d6a5ff1a6ae4d802712a94422a99d90988206776055545172b0282b5162b479d748a2e9d22356af11daf2629036665eed0642044b76775cfd9417ddacfdcb371aaef7abb3c2cfdca88891dbf808a90028d4f12c57e4985f7d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445 + +comment = Official test vector 63, seed: "d995d38f934b6e1a7ca77c9522e3d037676cc939b0c8bd4b84394b3dc91a791f09d2d97199258c9943da955e7f7b26fc" +entropy = 7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 +expected_public_key = 8e892a62437ce84445f2e82b495c9730fab393dc6f3b36bb2a63759a79ae27b162250076a608522440ac1e04630ba766b4c256341c6ac967b36e6934dc58cda15621827b9558076361192e89708ed88a71826a20e8ec948b9c7915566c70a7c15a72c36ecc7a3cc644eae696022657c53500a0f13a8ae50fdfa432d8d2530999275e5b9c1d341fb34b8a5a7421b7d290cbc3218486b555c92572bac8f1085f058a87fd48796824844553261ca11f06978a03f3a8d68657c22064af83166280af52270e004731d20b18982283e51ca3db7a2679da6fb0aaba1e75a2d283add699a797e1be93502c6823007ba5b9760a338768615b671baedc6a6a6937b9e1c35575776a4a791fec7751079c6683ba29ea28bad199175b9629c44bbf219cd88a19f1089aa551946e58032a9c9dfd29bc4ca3b654f494990cc02bbb8e1280b54ba3920ef98903f171c27a5c0fb679c8e84774f22136e89915a534d973733410a96280a3207407235ca0d81a636a35b9dd628dee9a64a12918d0dc6d4c600989168a163730fab8c78e61a57970c16c813b791a0ee9f625c438ccd1a9429a93062c4ab38da5890188829ad116a6f1564a43a2e4f3bba3712207b65e701995c99b29d691c86bd9844af2471eb5cecd934f764629dc25839c809432e395fd8582cda980359246eef0637b9771fa5853099007f173c8598164da69c8e67a910a50b9940b213547815e0589326b02ff21b89bc4200219652dea6ccd59883e29127e2abe3787738b124d839a67e02195d64989520737e3aa99c6822f2c32249256c45455cbd931a5a1fb27cd56a21e22b51c03217aa387e151631cfa445b2b77ec90ae01828601961ada8a8e6192104f02ba5064c4efc27cf2dc3353fc98f34bb947b21ec5235fba6caffb6bc6b1c09a783ab8ef14c4921a28a3896bac07ae8ba98c117b3624e01ed0496a8c649a38a33fb679bb535a7d1960028ca6c8ba825178e74f0e50b5d74c2a9119b595b863d0375a3da173c63a03d8c60a8d613cc08064588890e3894a9bf4580704038841526ab84e27cabc8fa4cad6dbbde9b53017f100778478b86138fbd6be713a7e695358538bc4cb5a4fff531bff178bb16ace5a295ca0340985f34267a3a931998b29a36935d3b13af0631cd37777689ca0b43b9208afbab88ef886a8672b331224c66c6086b8b15a8eb86107fc0ae260bf08f970cdec98ece9a197751b6996258ffb6dce05306380770dc63498e9b5d65acac5a179d8946b27630525b39c3755c070a120c9f468ab3aa8b1a48848081b888baaa1156bd600733be887abf962c46107c432c34edca8e549977d9a6f7eb77eb9974bb353896e8261502820f599257cd9c2852328b0fbc5c2b98658d67e4a636575a46e074a1efda2cfa50a0594b0a421661d81d95a9ae0ca1c037532ba7eead089961c29765c443d428bf20767d1f08615e85d0c08b0fa5076e297143249283c13486f61a4d9d39780624055d6043120a510d4a686f9b490c74f2da782ab42157a00991be019e093a509c0c00b7c1e6ab611dfc4373c640a2f488e7632be1289666206cba2b096a479b2140c6aa301bc448b13b6839447c4675aa1be46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad8 +expected_private_key = 34c91f6ec981b1830501d8969f8847b2c6bd5d5c43dfa044c43b551e610d5675bb7e7c9e393b411e69575301bf4ef4c7fd0b4b59e213905a254eb5540aca856c370dd28899541b725091c23907c04390ad32a56385075f42a7545672544fe177b74c7ed99507e4d95def7c4a9f84c9687b9bc318a23eb452fb7635d5201165a47391d21a7ca732fe9b3455c44ee4e54fc3a6518d51402cd5a2d49429b9c8815cd4b1a22c59ed368ed6c7a9df83b958cc83c4654c5cd040245543431c0d2c9091376611cfdc2eb9181b21c8417e3931aa2b1141c1051cb82aca4bbbe6dabda3356bbf4962c3f883d0578580477ac56353ac7524f3855de2b00967b7bee0668112d51ccbc139fa73374df2685a3cc06838b150f92a64c17772053de2b05cc4d51832b8a2b8428436d99e1f2484b127ce0d861dc8a11ab0b0019e0b3439733b36a7a600f4638d820ba5624b445349a86465e1b25de787207dda0b629cb472d415a42a8ba191b76b5829d4d987a2b0c235521c187a0baddb603d755eb37396cdd57ff76276ccca997b00cd481587cb8728830021dcbb8478a267b744a5bfd08b4acb2c1e726121996e55b60d40f6975637831c392845d6823d4b9092151149992794f4ab29d4164a44239f07c365a87ed9786af7a57ac0bc0d491018007b6bf7705a21b082d1e040a4f4c25e329ef9a8518956044e7683af94728487a4f95305d4e15aad45c040f1cf9c442c519b2aa47a4dfc29063243c21f8b838171701b4b73516944efc4b61fb5bca63c3ed12a123f55b832e6c312e8bc48f145d62953f5901f7530068f2c9c9f51ca8fcb342852936d414fddc2c04f551c827071f99c7c24c991f9c97e10e051694c86789a9442d79092b6547d67af70d8c8b074cdbf854718a882daaca3b8eaad0bb1c2d3e859d3eb03c0a23b290518ef88ce1bb02fe71399ef71b380ec1aec4c7c6bf3830c1b15f7718d0e471d10234393d94fbd3305abd09cdf070a0abc09d7497d2f9b939794b923eb3f28b40904a53a05216a526132d9f3cc64606b40f26434142645d79481a8316e8cb0a9321a4c530a0ad139ed5953168a4ac864c726874e1366ab09a249f251ce5b1a7f5ca60ad66375bfdbcfa3d7ad23a13649c03327d409fda64581cb00a696557945c58e96c1c889be648c4885958adea79ab212a0bb15506bf5635e437ecee47b60032b4273b8c96806639c87031b6e23b71996b4576626124281ae4ca0a8fc081e1c91667967b25f76c4f72624cb29bd0a865fd67a4dbf14acc7a09871bc7adeaab37b298f12b60b6372b741681627e4c8346c0d34392716ec173b1b711b1c0a1d010dca486bd5167223658a5c55bcd0739dcfe30dfcf9bd8aa45b3ca0b5a90243547767a1843e4c87922031819ef9249800c6db8b0270f9cb8f2624adf4199741870b0630e1bb1b325768c79984d5e33283a991bb3c98b6bb8be0ebaac47c4310c51eb565baba36be54f6a3151a104911c38ef78e61f1654ef35b2c836c2321a52fac710d6b03811444de5b8403569c8ce0444ef615dad54ae5649e68ab437c00a2c9ea9b18f59346d8b2a5c6582d763730bbc7f24a7ee7c23607c0683a2826fbb4bad4a58ff6e3bb3122bc8e892a62437ce84445f2e82b495c9730fab393dc6f3b36bb2a63759a79ae27b162250076a608522440ac1e04630ba766b4c256341c6ac967b36e6934dc58cda15621827b9558076361192e89708ed88a71826a20e8ec948b9c7915566c70a7c15a72c36ecc7a3cc644eae696022657c53500a0f13a8ae50fdfa432d8d2530999275e5b9c1d341fb34b8a5a7421b7d290cbc3218486b555c92572bac8f1085f058a87fd48796824844553261ca11f06978a03f3a8d68657c22064af83166280af52270e004731d20b18982283e51ca3db7a2679da6fb0aaba1e75a2d283add699a797e1be93502c6823007ba5b9760a338768615b671baedc6a6a6937b9e1c35575776a4a791fec7751079c6683ba29ea28bad199175b9629c44bbf219cd88a19f1089aa551946e58032a9c9dfd29bc4ca3b654f494990cc02bbb8e1280b54ba3920ef98903f171c27a5c0fb679c8e84774f22136e89915a534d973733410a96280a3207407235ca0d81a636a35b9dd628dee9a64a12918d0dc6d4c600989168a163730fab8c78e61a57970c16c813b791a0ee9f625c438ccd1a9429a93062c4ab38da5890188829ad116a6f1564a43a2e4f3bba3712207b65e701995c99b29d691c86bd9844af2471eb5cecd934f764629dc25839c809432e395fd8582cda980359246eef0637b9771fa5853099007f173c8598164da69c8e67a910a50b9940b213547815e0589326b02ff21b89bc4200219652dea6ccd59883e29127e2abe3787738b124d839a67e02195d64989520737e3aa99c6822f2c32249256c45455cbd931a5a1fb27cd56a21e22b51c03217aa387e151631cfa445b2b77ec90ae01828601961ada8a8e6192104f02ba5064c4efc27cf2dc3353fc98f34bb947b21ec5235fba6caffb6bc6b1c09a783ab8ef14c4921a28a3896bac07ae8ba98c117b3624e01ed0496a8c649a38a33fb679bb535a7d1960028ca6c8ba825178e74f0e50b5d74c2a9119b595b863d0375a3da173c63a03d8c60a8d613cc08064588890e3894a9bf4580704038841526ab84e27cabc8fa4cad6dbbde9b53017f100778478b86138fbd6be713a7e695358538bc4cb5a4fff531bff178bb16ace5a295ca0340985f34267a3a931998b29a36935d3b13af0631cd37777689ca0b43b9208afbab88ef886a8672b331224c66c6086b8b15a8eb86107fc0ae260bf08f970cdec98ece9a197751b6996258ffb6dce05306380770dc63498e9b5d65acac5a179d8946b27630525b39c3755c070a120c9f468ab3aa8b1a48848081b888baaa1156bd600733be887abf962c46107c432c34edca8e549977d9a6f7eb77eb9974bb353896e8261502820f599257cd9c2852328b0fbc5c2b98658d67e4a636575a46e074a1efda2cfa50a0594b0a421661d81d95a9ae0ca1c037532ba7eead089961c29765c443d428bf20767d1f08615e85d0c08b0fa5076e297143249283c13486f61a4d9d39780624055d6043120a510d4a686f9b490c74f2da782ab42157a00991be019e093a509c0c00b7c1e6ab611dfc4373c640a2f488e7632be1289666206cba2b096a479b2140c6aa301bc448b13b6839447c4675aa1be46eb6ecfcb4ddf2569b2d79abe93fceaff0f0ff88688c870d19759a41d3d361a0cec73cc908f52bad865f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951 + +comment = Official test vector 64, seed: "5929f02a271725cb40200de32d9d03d8bea53b53ac83186c42c7f565ccb1ca508305d470850cf86e9b2c61a5b8ca1c93" +entropy = f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d +expected_public_key = 61101724795296a2499158c8e1b50e4c900d65c8ae65503932dca40e058e8192cec2a997cf12c8a1227567b12a1b21bb31d3198c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397a9133d99654e6c56e7465d9b98bdbd624c12e36c62b60b6a32c9086a8eeb9b8919706f4573a33c393f74bb51d5609231f1707e152f23f36f6c6830ef28253c8cb81ec5c27adb02fbda5302212826f0b88aa4b4d72a509e29cb1bfc8177c019c60598e693bce999aabc4621123415235208e7869f62aa7b50a51724c13da2db59d5ba5302c772f2c1820fb0882ef32f73321c17f40d019cad39c3b12c57c3519ca0b38366ac4353b133c39262be6ee47ecf660286f6ca8eb7090418aba0d9833e22b46b761fa2872fb80972b551809c02775be07c796636a2c619fc748b90d28e1e702ffb0653e250c8c3759178c39e42411327a81c7e7887b21915a5cc032c37a11382c4d9186221b1c66afcae8184559910201c8baaacec62bab984e080433b9465e64a2d987028e9d9090cb2c41753742cd77f0998c672441e83d45f2d06c22899c2136362271b731f6ba3965b32e2517463e627aeca0ae5644bb8602f7fc599abc120aa111e2e549a276a18d2a92c39502f6f9519ce76c0bcb514e8084c7122a321479338f59ece08a0acd30f0ad68f2091855d5980219083398a6c0a63c70d3743678a1c0202a69dc526ddb77e30b779c36ac2575704ead94ddf1661a38b2624e733f2e2ae18467ce2c3083b75017411390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae1c29bdd6656cd75d9ba453aa115a32745f2dc1829881a9f4d5cc2cc053ab79b89d107e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b102378d93990cb8280b21a5d5ba8415c48ec17288044623a9631577c16639922978258cee0b6c51bbcfe3f70be07cbafb7c58111cc7f2f922aa023d5ad01d2d31a57e0469ac428b6fb88a97d957ae22beb768c3cb7c9f02f583fa2513db7c580d2986984314e8b346a06501d8972e31ab8ef5b983e9a15e8ffc624d0041fd523570960e09e57d616a06297bb3f9d938f5655628b06c4f6c4fa5f8136f8cc05dfab7389237ea75aef46117bf1b67aa978ba622491260128e743f28f95f533b708f3c59230b23faba96ffb5c239b32b30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a0812f59d9b5812916246228f2523175242cd1f432f9fb054a8b52d824349dc0756091b2f7c21e2a899362157bf9f631287b90d6c80fb55b1469273f79892435d031b62982c49a1464e2274f815f56f3b6f8c949be11388df1151e7077f603ae592623e4259853a2b90159344b041aa29c8afc5074bee81959102e0c57a761f1b1aa65b1dcb66a18bbbbe12b2b2942a37d13c77c77b2bde758eb1901f74c7d57d373a47737d6e23998e35dcee70983359b4162c7135126e90a807604034d52add3530456b66f0da64453150afbb67d67d9b359137c2420250c279a1c537ab06952e4823f09372198c253d5b71a7e70a1c48b1dcac3a85feaac35a11e670b2840a57f2a7c77b6a00cc80a282f0a1c8160080c702d619a6b6d68c757306c93a5b21ba8185b1a46c79b03c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dab +expected_private_key = ab4545850434076342eae8409fe0590c34955e860267305fca05c347bb3e53bc714e3134a6e9b338674a9aabb02f021d1a09a190757f03d573c27687f7e35f2d77294d10cded732218395b344523f1b704b27689dcc286b5c98217f239c159ae5d655436f00517a50c6dc6b7f4f111e7f37a0f319bf6acc7b0e3345c9367b2a2b8d9d644936220c0a817fbb38ceb3469cd55c661e1c58d06807504443448c4e53204dc59c60a5153494478eb4056c9a85967a42ebbc287afda51fdd6b84b285523d41d80a56f7a68a168a4527d902311b18d5e381cfdd578bb7924fe687d3aea5607906815181171a727e4dbce1b678762a8b03c2a2bff1635ca85332ae90f14b880c5ec4e5389b7816ab885c44a8d83c5ef0c4c754c7b6e673d984938d3ca4eb0f5b83b90bec27172ac85154ef27b91623841e188d76b040f958c38c8a112c05b54103e55a159de0954f2477e798a573339508b7c2ac3872a623429777ba3179060135c083e2198d1e0aa01967c39c27372a1a36a92bac3bb13ee3c94b1f0391e2702c50253dd497f16f39bdcb9c68ccaab6312084884b113e70f38555422767f4e613b2e87affc01395fca37df0a1aef74263c1001392732d9d1047cc7c6fb910ae6136c33094526876a113514f2918909532a759617dbe2c97e72176490995dc82b663655df65324b1996a42150be41b2a1c90f03b2a6f04174da1b1cc7fbb024c3c972b9714300c683c28a90f48b01c28607922c3ed25601a609673481b365544b7c36a9550ef20c37005b0e395a268e90ce1a5271e1421b46303b80cbcc81e2894d7569e82c2f5d8c6996c766bc505976628cadd84a3f468c67c209117c8254bbaa1ba584dc2661728a69e959949ed6c9f1b42f01ec8e55614aeb7168cfbb5e16504eb9f585c7789c48e59c17b5975c444bd6e32a6654bce298a605043bd367400c14b1d8e1a592a034543c04a44c85711aa66c807fb07378fb525600c19d9a4a9a8c920ba7db0b1d912a45f2b6d518b469e9121d25cf40499196376d3d92827e1b96ae255aff288037793c7db07e1d15533c07162aacae3255c0cc368e2fba3fef09540952910eac0fb2f3ae376aa666fc97a3e122570ccf797c79ec575835e0be6e808b3cb1b72d8241c3679bf15020b6a63be65b95a2c9147eb98c6553c71c550e37603e6b73c877c94e7b603a22eca456c1409d5aa049673d0ea17c123b1835692253fcb589186baa498f39481c3d0640a4d34931033b30f26ebed6ca9c49ba6fb219d6dc8461937284235a6417cc9c0ca0ad385b04b01c81d5a7b97a34977250e3679ac55c3d76d83b1f7b99dba039dc179147223b5d6c11fc9109dc062a1e4b7c88c710c449320949bb4405b28ea2c04d48c58aabb46edaa58e442f3ab6c9810b6d702855f7ca91af71b0e574bac1040dbe864ddaa76827874839414cf3418d1702c6f368a10714cb25e208c8a5779f639837a07e348841a11714f41399da175c49678307d3634d6b9921880fd43ccb8d7842e5f34ce44a4923e7ce6b671c7a989aa748604d147ce7ac25a1533e80ab321b7aacb8d523a3a6298beb0cfda435d77714993173d080827fb07b7855769eba987696afdf58231f361d61101724795296a2499158c8e1b50e4c900d65c8ae65503932dca40e058e8192cec2a997cf12c8a1227567b12a1b21bb31d3198c85c4878c6ea1967668e3952d04b4123cbb9cd8c77f3a7397a9133d99654e6c56e7465d9b98bdbd624c12e36c62b60b6a32c9086a8eeb9b8919706f4573a33c393f74bb51d5609231f1707e152f23f36f6c6830ef28253c8cb81ec5c27adb02fbda5302212826f0b88aa4b4d72a509e29cb1bfc8177c019c60598e693bce999aabc4621123415235208e7869f62aa7b50a51724c13da2db59d5ba5302c772f2c1820fb0882ef32f73321c17f40d019cad39c3b12c57c3519ca0b38366ac4353b133c39262be6ee47ecf660286f6ca8eb7090418aba0d9833e22b46b761fa2872fb80972b551809c02775be07c796636a2c619fc748b90d28e1e702ffb0653e250c8c3759178c39e42411327a81c7e7887b21915a5cc032c37a11382c4d9186221b1c66afcae8184559910201c8baaacec62bab984e080433b9465e64a2d987028e9d9090cb2c41753742cd77f0998c672441e83d45f2d06c22899c2136362271b731f6ba3965b32e2517463e627aeca0ae5644bb8602f7fc599abc120aa111e2e549a276a18d2a92c39502f6f9519ce76c0bcb514e8084c7122a321479338f59ece08a0acd30f0ad68f2091855d5980219083398a6c0a63c70d3743678a1c0202a69dc526ddb77e30b779c36ac2575704ead94ddf1661a38b2624e733f2e2ae18467ce2c3083b75017411390314ab06abb4d0fb58bff99dc3949e92994703e85fb6b863ae1c29bdd6656cd75d9ba453aa115a32745f2dc1829881a9f4d5cc2cc053ab79b89d107e6054c69dc93f5aa9c8ca6cc1a7583f2e2739b102378d93990cb8280b21a5d5ba8415c48ec17288044623a9631577c16639922978258cee0b6c51bbcfe3f70be07cbafb7c58111cc7f2f922aa023d5ad01d2d31a57e0469ac428b6fb88a97d957ae22beb768c3cb7c9f02f583fa2513db7c580d2986984314e8b346a06501d8972e31ab8ef5b983e9a15e8ffc624d0041fd523570960e09e57d616a06297bb3f9d938f5655628b06c4f6c4fa5f8136f8cc05dfab7389237ea75aef46117bf1b67aa978ba622491260128e743f28f95f533b708f3c59230b23faba96ffb5c239b32b30a65b36fc5a0a76b76f04a60c9c7d5eb78ebe44b736eb56a0812f59d9b5812916246228f2523175242cd1f432f9fb054a8b52d824349dc0756091b2f7c21e2a899362157bf9f631287b90d6c80fb55b1469273f79892435d031b62982c49a1464e2274f815f56f3b6f8c949be11388df1151e7077f603ae592623e4259853a2b90159344b041aa29c8afc5074bee81959102e0c57a761f1b1aa65b1dcb66a18bbbbe12b2b2942a37d13c77c77b2bde758eb1901f74c7d57d373a47737d6e23998e35dcee70983359b4162c7135126e90a807604034d52add3530456b66f0da64453150afbb67d67d9b359137c2420250c279a1c537ab06952e4823f09372198c253d5b71a7e70a1c48b1dcac3a85feaac35a11e670b2840a57f2a7c77b6a00cc80a282f0a1c8160080c702d619a6b6d68c757306c93a5b21ba8185b1a46c79b03c35880a7b265a3e05b2db868482fcdba0367177bbbcad04f3a50adeb85ded90bd59dabb8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef457933fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d + +comment = Official test vector 65, seed: "905074033d7b75deb2d06a2f29144eb377b452534c5710632989f02d45312d156557e96d4486020826db200153bc4a8b" +entropy = b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d +expected_public_key = 657b941f466659fcc971c1174aa4459551848e7a116b751e5e4022c8f2a4b3152a1b26a3096539c9b0bd6a435ea1e33413ac4d5f401f5de8570cc11cd4bb9fac473328d55501702743e2c8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b9571200b05300cb30bcec4a58b06f70830c2b32d28992b70427781854456129cbab53a7c72ff557193d3a221d06177d002095bc04e993b8606245416c3b998b01716af3b43a535f7a6bea71270b34ec808ca00e9453ae660b732963ba634f14378b1691a90e3708125cde31bae3d10451a5643f526cb790a8d6e091a725681fb539e9b05bda7b04c48a31b39da6e39e6be624663b6284de9f958c50149ce4090e6a486b68511ae90a0f093297bf090db3c81d34400a40cbe11d74271e23bbb7a49ea875ea7f7cc25516a899198362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b4314c4c44f44c96f48b29a8e7b85339037acf131f2692b7e7a49282237c8f37267c835c24883d1a189d4dccb7c6bb1fe622fc31301a6d3612a448084e0a210449b7e15a4fd84a9a538b2d5844dc170c911fc1282bc513e8c18c469a01a548d1ce4853128a03a8b1d369b353c3003b0a29d210ab6af23acd010ae3671493c774efad8b3746180746401d0e5862a3265e7969f247c954955b4afc13fc420143c10263eb1c6dabbbf5a8857a7f3bee7658c8399503c21a9a38ba554132344e214cd2036c2b30d0770cc5dd87ed9b246e7f955ea926965748cb9e58351a938f7e4ac249ca5c970cfde48c0ade051ba873d36a581e0fc50d9583109a79549fc5b32ba432444046ac0a66f3c64ae1498f43b1b36d8082442b5aaa7bbcff2c4cda8c0c4d2c62cf9135a75709ceb5b82ba4ef5716c4986a36bd7b4ad5c3a505869fd34aec2d7caba492f4bc30d232382b2651d5923242bb50df87092ace5566bc5a18fb2925cab467b641df7b5b91142318d120456245f2f0887ff13516d23216637393c469ce1f776cf2426c6577844cb3d4e0a92aba85ffb59979a7c33eaf51ea2bac9862160bf8a85553a3d4edc05da102106f632c91b8d1df2a9b2734185283941ebcdfd788107b307738786d6c0a0e7d4957dfb17488c5d6cc11b83e3504ef2923034a06270563e18a18bb29f48c36a64c132aa626dcfc5a615e4416df76746673e500186a117a27c5007a4b04867213c33739e27058adb23c0de35ce6158c99e59b88b147e2ac05f09f7c0a414c3240abaf65c24cfdb6857eca66bfc58e52472861bab1e03ce70d2115480b443a9bf799379af9ac978d0072f75bc7923816a189da5974ed948b8a709a8191cc9be60ac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac47260785c1b86a98a5dd733d3dc2b947d148f698c5a117821847604151068412268169c86d50be92d77683386025704575177aac0b9d3d3196a610985e860e2f799f480b1331ba346db0c379cb1833223836d88fd4e11dbf2985825c78330658b9a189233bc76b172127bc7a98e6c644d28da7b0857f67157ae2c27659297c32a7eb653697a295097a32ac235a11887388265ecb3b46a75c865c239395300d0f8152cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e97791 +expected_private_key = d7e3338b3ca1d6118b7485bf85ab9e8f6c36e158b67d2c3530b0a544b8afaa0a8604710987429d0d1b1eaaba8f06422e992c475dc4cf909061efe673a3547575e8b00ba47d5a158c22e6b2c280b3152165a5a01a43d801e96791b6d99c92c0b0602c94c0b13f2672146a7044e4372c5fa8843fa7974692b0f292af9fc3b5793092c705421e6aa39b7b3eec76694f5555985a94879abf737949bc33cfd1f8563565b2f345b6b3389fe061509be046b3a048a73599ac20466f0707e9b46045352f94507659ba428cc6994ee3375b07d09ad3be1872c15692c7394626cfc01bf5435d7922bf9199533a22cc4ff021a97c571db311485b36e2a3344eb880c67819aea18b09919fbc57cbc11cb228f8c24f38a445c512245c3a5cbc65d20269ee849bc268899981b9f334704499b60a891139d9470a1a147f38470752c4eaec5b14d51817fcca22e7bc1c585cd2189131960a9e9284ac7940b2949707ec7a67f22db280775d8163394a3a9557bd48f50c26f177ffe83030a3455de1196a763f8af156df73ce3bd07ac70447573a79dd04a59e8b40e39c6fea736e14f1b1b67b5cf556c3adb29facfca4e6d8b759d37737863da2a7ac4a645a8f202ad61c17068385c21415f7e14146d896020b89cc73aad60135d5a3b94879184e086f1066a9f56041b6029d1f538fb5b18a7a741e04e2c158b69927a1a7708bcc411988c0c315d0d1bc3a31b0cd473fcd3abacb1bb3eb23224379b5350081efcb8c45584d3b845e2500420453718ad83194130983a355b1388bf246b9fe7400443c52629812fc1125c3800c3f824c0ff95bc24a2e8b306d5e3278fffc585843bbfcd06d2ec3482295717a5111aa7b6475040083106a01491cf981197eeb77d9b01c2be476f07c59cbeb5c4d19a2000d61546a9cc149a149ba8e57cb0ecb3105d94715c7b1ba7800785edba95a7352583354b93cbef98c78bfa946a7431813ec36ac45488b170859c098b7c6813cab2ffb519814c3a9de3c254ed7a144fb6d15b183cb48a9021972233382fc8c388511add6a86837801f4bea0df0103b3a152648bbcda68499352691be0c3e5218a7c22c8ce49790af1bcd4f6717eaa18cb489b446d24f5ce239c79a6e34215e87bcb8461b5b509c895ec22f94c17c3bcc5904d968c469b200d3322b423761e3749556476d925a915971a62a5a330acbd106ad77da7897815cfa31cd44310d44915d762164b6170b2916b5427c694ff3340fb16b73500e92833ecc35bb25db6e652701d85ab215b366a173604c2797c2a9c420e069e7e4b3d1120dbd1c196d105211134478d23cc4428f8f56182ff3a51c7b84f01a08ba157e86b9374fb7c2e7eca3d4b65f4a73472e38c6f7c06883c99c4ce934f9b04436d250ef262c42d4862b90c11f4924087469210a25cf4cb29d139d85d9c904004cb246348c60736d707b2b9b111c91acd3937d9e8934032746aa5025bcec8bf637936448a0dd67a27db2a74b60bba82bcc87d73d4a9033c427a85883613eda43829c7ca3c7a8f24364633610d8199a5ec8038d0b6686abbd47692ada94282c40799ed4bf8ecb65ee7c8b2047c41eb255318c139b89ce909831fe3024bac10b4110ca34f1bd657b941f466659fcc971c1174aa4459551848e7a116b751e5e4022c8f2a4b3152a1b26a3096539c9b0bd6a435ea1e33413ac4d5f401f5de8570cc11cd4bb9fac473328d55501702743e2c8d1b97cedc8ad3d55b67d284158ea8bf1a4a8a17a9de6d5669e8b9571200b05300cb30bcec4a58b06f70830c2b32d28992b70427781854456129cbab53a7c72ff557193d3a221d06177d002095bc04e993b8606245416c3b998b01716af3b43a535f7a6bea71270b34ec808ca00e9453ae660b732963ba634f14378b1691a90e3708125cde31bae3d10451a5643f526cb790a8d6e091a725681fb539e9b05bda7b04c48a31b39da6e39e6be624663b6284de9f958c50149ce4090e6a486b68511ae90a0f093297bf090db3c81d34400a40cbe11d74271e23bbb7a49ea875ea7f7cc25516a899198362acc52c8a8ca14bee12bbcea9a6e3509b6887a3d1d4c3b2b4314c4c44f44c96f48b29a8e7b85339037acf131f2692b7e7a49282237c8f37267c835c24883d1a189d4dccb7c6bb1fe622fc31301a6d3612a448084e0a210449b7e15a4fd84a9a538b2d5844dc170c911fc1282bc513e8c18c469a01a548d1ce4853128a03a8b1d369b353c3003b0a29d210ab6af23acd010ae3671493c774efad8b3746180746401d0e5862a3265e7969f247c954955b4afc13fc420143c10263eb1c6dabbbf5a8857a7f3bee7658c8399503c21a9a38ba554132344e214cd2036c2b30d0770cc5dd87ed9b246e7f955ea926965748cb9e58351a938f7e4ac249ca5c970cfde48c0ade051ba873d36a581e0fc50d9583109a79549fc5b32ba432444046ac0a66f3c64ae1498f43b1b36d8082442b5aaa7bbcff2c4cda8c0c4d2c62cf9135a75709ceb5b82ba4ef5716c4986a36bd7b4ad5c3a505869fd34aec2d7caba492f4bc30d232382b2651d5923242bb50df87092ace5566bc5a18fb2925cab467b641df7b5b91142318d120456245f2f0887ff13516d23216637393c469ce1f776cf2426c6577844cb3d4e0a92aba85ffb59979a7c33eaf51ea2bac9862160bf8a85553a3d4edc05da102106f632c91b8d1df2a9b2734185283941ebcdfd788107b307738786d6c0a0e7d4957dfb17488c5d6cc11b83e3504ef2923034a06270563e18a18bb29f48c36a64c132aa626dcfc5a615e4416df76746673e500186a117a27c5007a4b04867213c33739e27058adb23c0de35ce6158c99e59b88b147e2ac05f09f7c0a414c3240abaf65c24cfdb6857eca66bfc58e52472861bab1e03ce70d2115480b443a9bf799379af9ac978d0072f75bc7923816a189da5974ed948b8a709a8191cc9be60ac2a383a7e27cc62543a2a0ca9ea6897d284ae79b595d0893514f75db35c9254b7ac47260785c1b86a98a5dd733d3dc2b947d148f698c5a117821847604151068412268169c86d50be92d77683386025704575177aac0b9d3d3196a610985e860e2f799f480b1331ba346db0c379cb1833223836d88fd4e11dbf2985825c78330658b9a189233bc76b172127bc7a98e6c644d28da7b0857f67157ae2c27659297c32a7eb653697a295097a32ac235a11887388265ecb3b46a75c865c239395300d0f8152cbcba77b4d655c9f1ea4b448fbe32c4996fc298d26cae25d276bcf6e66ba65e3e9779146fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d + +comment = Official test vector 66, seed: "a3e2e511afa7bb560446bdadf67d2ee2e16ffc7baeae7efb8c5455068bbd4e91bf9be9d98b280072faba7712c75b26d4" +entropy = c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 +expected_public_key = eb9b77f8c16dce72611902a8ccb81e8cd4c5a2fb1d8fc30ce226bb45779f41073ff3ec0362ba152102cf45d3a95874a551c14c8a621436e248ffbbc4ca3b4033d50efa392dbad9c339745803f845736c30bf309546229ef52788ab223758c03491f62913fb4ca4307dc6b4c7fd9503a701ad21671387cb2cbc728ecff4641e312779c7034ce720554a948a021751d4628890ca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934e4144922ccfa2035892c4cc2a8457300946aba4ffe77868d34c7a90507be43748a366c49d0a927e66610a08cd0152a2c1bada92a05694b6e3d2610acd4579d5634fd2675f2101290e2ba1855252b57a438b50fcb854ea7b6a89b109ea9857c23aa38333428b94ca5a524977d72077b56978328c18980382ebc967dd37e6136360a958d5f00c3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347d9b018d437b3b065c120d26e9033078b5838dfc7ce68f244b32c5b4ac04def068f58fa733e99a418176575ec2ba0f78d4c402d67176db5717023b57f8d26c636a11f49b926d20b277d2613941c3e786b1a9a3c1135993bce22a1de16434a5902c0f101993b65777399828ba52330a2f356203521a3c59b6007c3aa41d198a8232d27c05f8e0280c9076d54d5aebdfbc95c7c06bce24507892641f90d2b774a2d98764c42bcf009799432b706da59bd84cde4892427c0586929c99850c7d769ad9a221c85a4062a62b2a1847454554224c4cc47898574fa66d147c4aedc59ff612f49285db54170508c89e6787a8ce6515cec673d4545970ca8ec486802933e319800fbe46d5cc14c8363656dac0600d895fe383fcbc3614fe334cac0a94c185b73db30cb5a56a8d04cb271b13859862f164f980625d78ac35ed120605cbd69e6410eb05168819440816eebf8cc9ad153cda5bc2efbb00a7563a55856711231cd12873a9a56996c174ae43b5c172a1445bb40cb3deef9051035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54b6021d180881d59d2458564acba148b0ac36cb501cc8242919064ee24343f26a87a0696000533a20943445c72b9260b4c8a46a1c921c582600d978c5370b400b2412f73541a13ba0349e66fa4025735cab6402aac51e08a019b48115c49c665f415244fa91c208c6b1f2bb02bc18c47a5aee366edbe3bae1e41a8b405ddeaa22a2fb254a6b70dc5a16c0217e4dfb933a127039b788e6c035df8993ff86923500ba466a81d34a0ada271da4262f33123a1b81a13621211845a167449d93370bd95a89725a56a8452b510a7fd2642af41a4a7856abd9688dd7c85433a868103679a8eb2bdfaa0cb52cc141267e91e2c1e57162c6b4897c9004a3d375c1c8bb87c5ae2cc80c2a107e0f904e5bf8065ac96c9152aeb07322fa181a83a9cba0224c9faa0f06cb67e2787eba832d3f53ac60b7b014d28945361759689c3ec65f8b885eda081443a2afd2a735b1c57c201aa4d273b1302267e5a63abefbcae8e1b2d3883439e2be2436382eb9bd62146de0e446b6e2baf8300575091db145a646c733bf352989938fdd8003218a607739c60da6758bf448bf18a22630b08ac40635382e3bf86d16625c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723 +expected_private_key = d338b8576c1fd9168551a681f9c590095b6b8d8474f571226a4b68ee81a83738bb964356edb663d925960388c92896029a201ec7f046cde497e3384f613a444634aa3c41656c6031d5233720241603612bec1032afa7b3d41242ce374c8b118cf6219fb5e645002530781cb4660403f88287d115baaa07ce95496a7232862282a653367fbbca1e337155a3c8905e368c1974418e735f93b6965fec11ce7b43d81710d727a4c4b434003b9110d013568b7bbfb341212543031c862fac505944b86394554772047b2a864a6675ed984583269362759cbb464e7e248a48c3554b8054ed9342aedc8e221439f812697b691bd5c89b7fb11ec716bff96c97dd73c45b00980bc6b1f69117c2329386518058e97b26626d98196025724baf0c5729109399e035ace9a630cb6d7ca9cbc16ab560da5c01e37601bc0dca7a3af891b80418c0056145c7ac8c176605411a39bfe843cafb4fa61463b20a504e984308f2b82ca7081a97951d0961b2664e2d7b41df902571d02c1fe24ec0ea998609248cf51cf2f81d96a983dbd29bb37b9a7d559c72fc0baae894583a842fcac92d910c7d682dde70a4a7b26e3259b290a182392cbe36b68d2e321708e9c00d8c06dca5043c1a461e76438b7801e8faca17045b272b16999471f8fb42f53a43294124c3b2b7f7a13eee8b195a01871909a70e41a0cedb37f3f733ee259f40c1cd12c79daf90788d78ceaaab9e1d20b7ff8800a17ac28953a4e90b257d099da195b6701a695195bc730389a84a499ab784762631935a5a974398c6988a59822bc6382b9cdc6072f0a6cf65c9dff2309d1a433ac52e6cbab472e788f76558d57986bac5c79b921f06e509db18c70ee88af044b527e221e5a5105a19610f059fbf6009b985190ac81640607cc4fb69d4892b5d9ac12bac26765aad5c874fe3080beff77961cb9e747a8e4b4acaf3f3b81d51a4a755ae8ef2994e8a722dcb5b8014c1ccdc6a79046664c3b75c02b91e0b4c5c250b8eda5d67e9a0984a6052053d22266b2413b98d841e8aa686f4e0aeb8d5b2ed2c8bbddb0374d0ad8cd47a0e6945f0ac352307ac0db224eba29bc09397f05b1308828cd42b85c556bf0a938959fa7cde083d3d0163c21b016133145ae0c47ef73604999e76f9ad19432f82e762ba8174f89a23d09333f7e677f33bc15bf996ae6999ada8747bb0c454412c2b651d2a90382937427ea555b3856d0250ab1e3663b8d78f3d96cf9eb90b5a501129715df5db38086076c4b351305a9718903abf12609fb1bc8a59162e2152f8e0c62241ca5deb5260d71ae162b7ea827a342584576b00dc674a5be149c7744d7ff43a5b04a3ebd38c110630ff656f2ff042eb603403d14f18eb17cf675c995c2790e936cf8b60e758484bc04314e50105b28346829077aaaca72acb46d331e9127b17dcae5e639d2b33b9f3cca468f731bf0b332ba41d196ab77b3c436702078730369cf59144540ea08b5025a4c880c1530f40a852e35f96519c91eaa680d90d25a4256feb1878b48e39143ce43378eb3335d3e03f2a358782e0b54ab56860148dc0fa5cfd149cf26a7260639a347aa72b977b6f38bf29e1472c26b4d7f80e4bb3192de06ec05a6aeb9b77f8c16dce72611902a8ccb81e8cd4c5a2fb1d8fc30ce226bb45779f41073ff3ec0362ba152102cf45d3a95874a551c14c8a621436e248ffbbc4ca3b4033d50efa392dbad9c339745803f845736c30bf309546229ef52788ab223758c03491f62913fb4ca4307dc6b4c7fd9503a701ad21671387cb2cbc728ecff4641e312779c7034ce720554a948a021751d4628890ca7367611d4b9f269c5ccb2381f1f6a01b0634d9c5c954fbb934e4144922ccfa2035892c4cc2a8457300946aba4ffe77868d34c7a90507be43748a366c49d0a927e66610a08cd0152a2c1bada92a05694b6e3d2610acd4579d5634fd2675f2101290e2ba1855252b57a438b50fcb854ea7b6a89b109ea9857c23aa38333428b94ca5a524977d72077b56978328c18980382ebc967dd37e6136360a958d5f00c3b9996de3b97b6468b9f98c3c50f37a9e73ac8e8364288347d9b018d437b3b065c120d26e9033078b5838dfc7ce68f244b32c5b4ac04def068f58fa733e99a418176575ec2ba0f78d4c402d67176db5717023b57f8d26c636a11f49b926d20b277d2613941c3e786b1a9a3c1135993bce22a1de16434a5902c0f101993b65777399828ba52330a2f356203521a3c59b6007c3aa41d198a8232d27c05f8e0280c9076d54d5aebdfbc95c7c06bce24507892641f90d2b774a2d98764c42bcf009799432b706da59bd84cde4892427c0586929c99850c7d769ad9a221c85a4062a62b2a1847454554224c4cc47898574fa66d147c4aedc59ff612f49285db54170508c89e6787a8ce6515cec673d4545970ca8ec486802933e319800fbe46d5cc14c8363656dac0600d895fe383fcbc3614fe334cac0a94c185b73db30cb5a56a8d04cb271b13859862f164f980625d78ac35ed120605cbd69e6410eb05168819440816eebf8cc9ad153cda5bc2efbb00a7563a55856711231cd12873a9a56996c174ae43b5c172a1445bb40cb3deef9051035b33214a61e26852ef3bcb3fb319e1b4d6bd832d6b9bb54b6021d180881d59d2458564acba148b0ac36cb501cc8242919064ee24343f26a87a0696000533a20943445c72b9260b4c8a46a1c921c582600d978c5370b400b2412f73541a13ba0349e66fa4025735cab6402aac51e08a019b48115c49c665f415244fa91c208c6b1f2bb02bc18c47a5aee366edbe3bae1e41a8b405ddeaa22a2fb254a6b70dc5a16c0217e4dfb933a127039b788e6c035df8993ff86923500ba466a81d34a0ada271da4262f33123a1b81a13621211845a167449d93370bd95a89725a56a8452b510a7fd2642af41a4a7856abd9688dd7c85433a868103679a8eb2bdfaa0cb52cc141267e91e2c1e57162c6b4897c9004a3d375c1c8bb87c5ae2cc80c2a107e0f904e5bf8065ac96c9152aeb07322fa181a83a9cba0224c9faa0f06cb67e2787eba832d3f53ac60b7b014d28945361759689c3ec65f8b885eda081443a2afd2a735b1c57c201aa4d273b1302267e5a63abefbcae8e1b2d3883439e2be2436382eb9bd62146de0e446b6e2baf8300575091db145a646c733bf352989938fdd8003218a607739c60da6758bf448bf18a22630b08ac40635382e3bf86d16625c45e12ebeef4308b229c948d425016d674119c0aadefeb21338ba6cedbf7df723a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ceb2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643 + +comment = Official test vector 67, seed: "074ab1a37ba5a0403d8f68d26fb787bc2c90f5ef88f2a6d286c3e6b168abd85d393d8225618608b8eeb301d26af53bc0" +entropy = 334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 +expected_public_key = 9bd11c902a159f41cb5395be189b1b7e98cc23658dccc7bf9a843a77b2a6bfa27bc941b04f391950d998c607a59b49330811200b38b243060b55e381c078100da84975091f3a0acb06f22ae3fb1b7d756d36f54200a367c109b13cf40f3671231d5b0ce9e5908776768767209f4726c54277d0f8b0e05bb4cd50bb5547a01051c89abc4a352745316c8d85a3187d68382ef05dc96294446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c308f22b8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf2325cb060638c723364b27c8e3123fe26cf9862f247cc31c844ae77754206b03b497bb3283cc7e38664b23771f709e1d308cfaf5086f25acbd04cbd9f1612acc2712d129c9c195bc024cb057b0766aae7b533e60f04d947947f920470bc37e5eb4ac4fa1c48066877b4456d4ea2a5ee089de38a7fc7573fae5480bea823727132651a85d873378cb97d6f7be1250a94621abf5eabf0114952665cd2a5005af338b36d19f6e4c8f77e2cfb6f24d3cb7a909315a026b5aad50a9cd4baf3308059a91323b1c226ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91546a2354b59328d411a724cbd8b3689efa335d879996fb0d1d2244edb361be4b2489e84086f4a995f20ffa9404082c4e66061d3ef668fc155bce04916c92b8fa46b77a4a9fa82c8c0ca5a5a5245883d25fded230e74b22394169464bc33fd51fb7f2aa9214b1ed546dcfd00ad554aec80882ec170c6ec44794204170d738ef9341d6034920a7aec3b68fac00527b2812d88969c6207f9aa122464a4d76320ead6271d2836e574155310a756cd4249fa7474b301ca978a0653935b7740a16c50df1eb678c1bc3eb451cf6fa35beb903cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4252b093d2ab40884c39a4abcbd19b108b81172e18a84a288aac2982d113454335423148168bb6b9d97494179bba1ec8760be59d06251b94b4baaf82a6481c4a8f33b0fc3164635452e6497f992308688352cbf44537c618000536f9c41a64361ee162236f9227219b8b84a3984c649ea82211207c974f6c7575027aeef57e496a58ce2719096a58e2e31e82844f4d674a4cd9cfcada79afb0c63e634d2514ba4d8604ccc42b2eeb64691aaf23727c93c4abe1423c27b3b7abf0b649334760056e591c32fe812a753723f7c93ef5524c8e0267db177e6e55620715688cd0ac70b2a90e133caec86945bc74d7ea1cb88479a37b45eae4993bb7048e5316bf66b9715591148c9a20a35412c2404bb62c512b3800b9ae104453d95acffe000d3ae85b96d8092532796a03039ba2154f84afa4a402acb673b8799441bc505e836c3b558e1fe2057fa79153e1630d72afd96aa4fe9c0ed4822ab33a559719b81d274ef0a2773e405761a036521278df5ab3617cbd89d7543cfc7c6ad373b2d0b781dc78dd3b2afa34b6565979231681fffb8c62843dcd11686ea59406e23cdf96aed95554e47027c5b6976f5515bc40b0e3a31c556219f89b73c0871e1ff552ca04c33daa4a363794cc7c0e05249b53d20460eaa8ad217787c8c9423a7eb71058b5a8081b82454dc91f77f8608d60caff30a7c42424542a1746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f +expected_private_key = 9bfc3a71fa83a4070db5064ada8410a770845e818c49b91e09a251e1925edb226ee8ab153f94b2417560d88959113a6bbc854b0065748e6a7db90977ada0216f3c41cff70e5202b306cc22ff8a138c360d75b9cb1bba849c5bcc8c9b55e80647e513c9e3e15f66a144f013822da24266765e3f1125f435bda4c46ef57430eae331e1d54c91960eeb363ca25387d0d441abb930e4a7c329191c5ff7a87996a4b1aa74162611e67b303e284c7098a65069356b55304b11b8bba66c5829647493c09bf62166017977a988333092efe98d9c13a2bce53f8ea2c81a0099b7d5c2b11704971366a5565cc14610df796c604700680226cb165e9acaa6ab507a923b4d472a4b6c9424e7f5a622f87f4f8a1083b4755067a93c285cc0748d241c7051971128cc5af4db5c1f7c144f98b6bf9703f5338628ca22df4b84d10312edda9df71442464a24491a62687928c22455dcc23eca964e9248543520790d813924cb58a0c156aafbcf63906ec5fa891936c7e16b5fafd98026d64ea2012bd75b6c5f376eeb74ae9b29cff7041c650b91a2b852c021562ba33b66ebacf787be40810f22aa43f4174571c77710f775d1719968a5523780b613262f94bc36b611b63f460dc6e02cc588af99f164302276b0386e697469c55928c0e62438c25af90577de0883cf45819262905ed30d9a1a7918b82f9b4a28ca5b8dd1d9ad4326adc7ba69c087765cc6511668cc0be83d510245f8834e890662e06774f389c0c623be3212aae5accedb101c43463b68889ea9a2c21aa0acb5329ff80a336f8914fbc602e2b9ae452647777651ccc4bef70ac06423b66ec5982c861ad9723dfbc834ca6a6433174c1d6c1ab9569265a96ab5d48495d72122763b3a7275b297713f1a729bdc48329b64fff9c45955c6091375d4d77fbac540dacb140666610ec7a15ff18bc741aa69425508d5cf682bafb6d3c9dfe02d80349597f56fbebb7ec8031fe71b6d6c065c4e6b5e5d17abf3b412ded81efcc8b6b1935fb37b467a5cc61f318aed20678800726509baa73bba244030500050d4b23e4ad71349cb0877566ad100ba77f8b409bc8f0ef8cfbcfa3cd1baa1935c9abca798ff6965ec7b53141b6709597bc4f9983766403ed80df4095d59ab482fab7fca432ef5e76affc77f74f4cda522a0085a4917d04167a00b09863850d6caa0621c2d473de0763b7d3168b6147bdb009eb260901fa82013c8c0a3f6c39de3cc49a773d08b357ef932077b5bab86391239b3c366c43010ad15ea2eb1e05267029e5ad8139728a907b98761b65dd6dab895363159b48875fb6aa80882256a04460b2977280688745c5914c089b37bfc949a8f9864afec2e4dc13f6092070eb561d09b530eba2ccd66b87b0986adea1933448066521e28ac2ed9c57ede492799b401cdba8377d593dafc1a0d233004e25877242c30070779d8bc5bb488dd3988004b5a8554861b560ebaa5bfff7c89ded193ea077f421c216996c1445b165b912901b217315636a168c0216ac026fbbd4239858837b02dab5a39d1be6b072468a264661c5e34f42380c66526377c990092434bcb551a744227445c5108fcfc3cb4526d0b711dbd4539cea05a08a78fba723f9bd11c902a159f41cb5395be189b1b7e98cc23658dccc7bf9a843a77b2a6bfa27bc941b04f391950d998c607a59b49330811200b38b243060b55e381c078100da84975091f3a0acb06f22ae3fb1b7d756d36f54200a367c109b13cf40f3671231d5b0ce9e5908776768767209f4726c54277d0f8b0e05bb4cd50bb5547a01051c89abc4a352745316c8d85a3187d68382ef05dc96294446972f4c76c7b9b91a4babe06fc634e76ae4b778f939c308f22b8c816bc3fd6b48e168f5dfbc19fd8cb7e4686bf2325cb060638c723364b27c8e3123fe26cf9862f247cc31c844ae77754206b03b497bb3283cc7e38664b23771f709e1d308cfaf5086f25acbd04cbd9f1612acc2712d129c9c195bc024cb057b0766aae7b533e60f04d947947f920470bc37e5eb4ac4fa1c48066877b4456d4ea2a5ee089de38a7fc7573fae5480bea823727132651a85d873378cb97d6f7be1250a94621abf5eabf0114952665cd2a5005af338b36d19f6e4c8f77e2cfb6f24d3cb7a909315a026b5aad50a9cd4baf3308059a91323b1c226ffc76b3565cd9386592476b76057e3477c8b7cbb201ca91546a2354b59328d411a724cbd8b3689efa335d879996fb0d1d2244edb361be4b2489e84086f4a995f20ffa9404082c4e66061d3ef668fc155bce04916c92b8fa46b77a4a9fa82c8c0ca5a5a5245883d25fded230e74b22394169464bc33fd51fb7f2aa9214b1ed546dcfd00ad554aec80882ec170c6ec44794204170d738ef9341d6034920a7aec3b68fac00527b2812d88969c6207f9aa122464a4d76320ead6271d2836e574155310a756cd4249fa7474b301ca978a0653935b7740a16c50df1eb678c1bc3eb451cf6fa35beb903cd89cde0aa58a43bce9cf591286792fb3b5e658b5a32196ea24a4252b093d2ab40884c39a4abcbd19b108b81172e18a84a288aac2982d113454335423148168bb6b9d97494179bba1ec8760be59d06251b94b4baaf82a6481c4a8f33b0fc3164635452e6497f992308688352cbf44537c618000536f9c41a64361ee162236f9227219b8b84a3984c649ea82211207c974f6c7575027aeef57e496a58ce2719096a58e2e31e82844f4d674a4cd9cfcada79afb0c63e634d2514ba4d8604ccc42b2eeb64691aaf23727c93c4abe1423c27b3b7abf0b649334760056e591c32fe812a753723f7c93ef5524c8e0267db177e6e55620715688cd0ac70b2a90e133caec86945bc74d7ea1cb88479a37b45eae4993bb7048e5316bf66b9715591148c9a20a35412c2404bb62c512b3800b9ae104453d95acffe000d3ae85b96d8092532796a03039ba2154f84afa4a402acb673b8799441bc505e836c3b558e1fe2057fa79153e1630d72afd96aa4fe9c0ed4822ab33a559719b81d274ef0a2773e405761a036521278df5ab3617cbd89d7543cfc7c6ad373b2d0b781dc78dd3b2afa34b6565979231681fffb8c62843dcd11686ea59406e23cdf96aed95554e47027c5b6976f5515bc40b0e3a31c556219f89b73c0871e1ff552ca04c33daa4a363794cc7c0e05249b53d20460eaa8ad217787c8c9423a7eb71058b5a8081b82454dc91f77f8608d60caff30a7c42424542a1746f0f10feb3f0fa52eaad4f2d4c36e59ca0a5389566fad53898992a17bbe0a0f26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9edaba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523 + +comment = Official test vector 68, seed: "cc0c86cc0abf86fa21899be1953913c00e7c46e6b5f730c4e88b3c034012763981d7f14459d3081638080378348856ea" +entropy = 6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 +expected_public_key = 8683354b3c3f035586b50b88c4140f346a05ada7ce4beaaa5f096614cc767af89ffccb95124b00e8379efaf76ca381ae4886abed9240bda4710dac62a71017059b07921c770da1ca2d209338536c3a9b5238313bce565fb861bf8ad3a78f030b3f646b34347f1d215e8ec1789d602d92a971fa3c2e892a09cfa68968f96f206a7535766ed7533497fb051c8036b0aa81c2c802fb7333cc6744ec830e4be56ef1e4874371409486c477cc4ee90092d2919f585ba21f32bc973acaef42b4969746ab2618631b6536ec298b2828abf41e24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d1712e9ffa937ec5194a3541e3fc9c685102f9a47faa077fecd688d607996e5b60c1715e617994b842b46574b87086a061488bb2445b357a38934b612c16168e662112756bfd764a4fcc5f7b1634f6f28094464d600046ee03b4540c1049bb3d18f783fba2ac5bd36ecde662d9e08e2a89cb754b090db7175277941e5973d010ae08a4b4c922aa99f47f657a49c3b81fcdb54c905a3010405ed544bdda9942bc857b6d979f796c859e0627a5212543477ed791c2adc95fdfac9d21d19750b8b5ddb95f02d721a9304099ba6b2cd0a40c1a2f9dc1649b2318acc93a5fbc52e3f4900bb44d20a7250142ae5f3b77c0720c77104b74c78eb821bd32e260051c499b5ccdd9d716521163557b5e4526acaf09a2beda04994188a5065b4a975b215171eb288024581cffa37d6289813773b29f1c0ef5587f9c98049f548d2a0c3a5c71c1693b5ec8c64ce0267fdf625485dcc4b5553c5736a0d0623cfe20596f984c014aac0380ba9b58257a993b1be3bd2cb9ac25912b36b2c085443074f093510a46cde5441ee3cc88dc2cd636a5ef77310f91cb21abb149db2541407726582b54b50306cab4b5356492c220c138c64b4ab293680e01c2aeb369bd611064fd8955b790222bd5997dd76bfbe50a2bd039c1f14f0469b623c53195a3b2ff068182d951dab05ffce9a6c8fab42886987b7999043c12870965bd463980aa6b35e13b5bf9c25b64920d7788a291a98ebc30d3785783c27e53ca9ae809004f23706e3cc0b9ac0bd571084100299c932db2933cd91566aaa367371b16069a706be664e86107b33b1cf05360248c808ea250fcacaf9096715478463932a1c632cc9a185eeb08583a9309259c567743995af013216b1086815b851655d0f14fcc43682720acdfc36f35806894177ea2144f6e28837cc887e560874ddcaaf60a3580fcc7a5f1733180b1f1202a08182345370cc5c46cd28a507ad846d1d9415af679d4b22ee560c6c1b2499d5b74aa2758da090e62713343b3a8b14c68e415a3f196c2573c5e828a16cea51443104f9cd899ad03c3b727774b48ae61db98feda4c1e029b57f89d1735381166b70450215af92120ca61a8a38e575abf2cfaa54c613031a9ba60275d23178ba553a3ed7179aac44fb3607e93c1c57c7bad6854533844bf3d6a9b95a966f891612239cf6cc41df1a859afea9c0cec6d2679cd7c71c2cf251dc9759666c871853a1012294022fabdeb2269b430397f337b3f416e528748903ccb8b24c8fa28197244c0ac3a0345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b24 +expected_private_key = 5e484946337e3f4135d738b0862b69f7b247a5bb0812d56201300c53bb87b798b2b551ccea75a87f002d7de7878ed08e976a2cb62b4aa559bc36816e9690973f608b262612f89b5bc784365e33193fe9013c05818e0a7151297ea53c95089388be203071d0335535436c799f6d3aa3260a9c8c9c9e36f79f13135c3dab92914137c33773660aa15557c32b7a086a5a1cfd125dea60183ecba94da22f0f3a18dd2131bc792c4013b7bf84a7840c976c53117653c4f947839d8cb35538bb97899418688a9e062f9fc17d77450d85261aab01bd9ee77e917966bd26bd3d3990aabc8561cbaddc5a22f8c80d99453fa7350b2a022e4ca48dea6c9c07309543611abfc7cda76aa03e51acfdf0cc73921ef2d02f45990aee50ca77b93f14e4bef44576134391f7b67658e1cc7876713742267a556ea8f562bd858b24e04314b025ccb5be0650642a23460c3c65e0d6cb68232cff709204b7b7cab0741807100a712686b982f632095d7730dd9385a7a26c23741474e12cd8fc259ef346b5f287eb01b046104ef8415372b47da145ab0c5c1774626b5dea7d72db4c62fab14c03ca51384420690a799194e8aa05bb914db21956bedc948299baed7289c884ab9833c8669422adf51d4e1a0466056eeca478f11ab55ce2ce34430addc889044a5601357ea6a5b097b54252b046fa83c0211c236953954c36840e390d2707848c0b879aba2354ea200fca56cbb86c0c2269a81c790b966893f782aae9a4bd1b02fa85995a757ff2083fd26347c97711e07560af77cb59c7cd64f7cdbc880ad26a7bd7fcb9b210710e581c49453a3200ac08554a641068e6879ba6665ae9f281fc14c8fbfcb0cac0081c1a06db017d80048b324248f699825a489d0726893e109127a0ae802cca29ac56f6118d209a54cb842c9a8c539e43b9681cb868018c95d872c532a10a77bf52a796d33187fb8aa3fd780bd2c4b30fb7394dc64b0fe05b81128763a1325bd00eba411247b1c22a1146feba1b255c51f74999dd29a9453151bd9869e3d548347b93c1b798fe92a053b88c80d7afa5c561d31435d61251253b9a4c2b0f42830c81e990006dcebddb7002240ee8e276d4e31c2d249b84414f3997b9c4f5c0698cb2a24c48e3605f6d704e5db734ead12d62634dedc68ed6a1248273bad5ecac0651978b098ffcc148667671d4b59ea6095b0b363c31299e5b90282f914bebc66f6291338bb7600c8310b83963336952ec33854ed7c979b71f30188180b11bb66314c93242ecb890123c9f2aaa786acbc7dbf560cfc1625d06c3828998ed51b79d28c583bb38719706d1d67b9ba5a556cb9ee1dc4ff2c53c33969f2f97bb93056729f65fd90aa2d7113edf611c521761be671fe37baada7a2b4a114dd458a19966a2a42914d61b47aef5abccf8240c88af752b51bcd0a3788c2aa38aad8dc00d835476c8386dd3a8628b261f1d6b2b9f771842c97da7bbc3d03696f60524be6476430044f6a8aa48c22901f750dc55c1ea7813ec3518b26b3fd0657ea6fcb6be94c026244a0401593664673faa680f866e174143b0cc086fdacc1f7126c3e941f090332d8487d5e66061d5311c9b5c8edc39bdfc34948400a9a3aff3a85a8683354b3c3f035586b50b88c4140f346a05ada7ce4beaaa5f096614cc767af89ffccb95124b00e8379efaf76ca381ae4886abed9240bda4710dac62a71017059b07921c770da1ca2d209338536c3a9b5238313bce565fb861bf8ad3a78f030b3f646b34347f1d215e8ec1789d602d92a971fa3c2e892a09cfa68968f96f206a7535766ed7533497fb051c8036b0aa81c2c802fb7333cc6744ec830e4be56ef1e4874371409486c477cc4ee90092d2919f585ba21f32bc973acaef42b4969746ab2618631b6536ec298b2828abf41e24776bf288ca6a4a8094d63c7ceac44854ba9e4837e44b3a7b269d6ccbb6d1712e9ffa937ec5194a3541e3fc9c685102f9a47faa077fecd688d607996e5b60c1715e617994b842b46574b87086a061488bb2445b357a38934b612c16168e662112756bfd764a4fcc5f7b1634f6f28094464d600046ee03b4540c1049bb3d18f783fba2ac5bd36ecde662d9e08e2a89cb754b090db7175277941e5973d010ae08a4b4c922aa99f47f657a49c3b81fcdb54c905a3010405ed544bdda9942bc857b6d979f796c859e0627a5212543477ed791c2adc95fdfac9d21d19750b8b5ddb95f02d721a9304099ba6b2cd0a40c1a2f9dc1649b2318acc93a5fbc52e3f4900bb44d20a7250142ae5f3b77c0720c77104b74c78eb821bd32e260051c499b5ccdd9d716521163557b5e4526acaf09a2beda04994188a5065b4a975b215171eb288024581cffa37d6289813773b29f1c0ef5587f9c98049f548d2a0c3a5c71c1693b5ec8c64ce0267fdf625485dcc4b5553c5736a0d0623cfe20596f984c014aac0380ba9b58257a993b1be3bd2cb9ac25912b36b2c085443074f093510a46cde5441ee3cc88dc2cd636a5ef77310f91cb21abb149db2541407726582b54b50306cab4b5356492c220c138c64b4ab293680e01c2aeb369bd611064fd8955b790222bd5997dd76bfbe50a2bd039c1f14f0469b623c53195a3b2ff068182d951dab05ffce9a6c8fab42886987b7999043c12870965bd463980aa6b35e13b5bf9c25b64920d7788a291a98ebc30d3785783c27e53ca9ae809004f23706e3cc0b9ac0bd571084100299c932db2933cd91566aaa367371b16069a706be664e86107b33b1cf05360248c808ea250fcacaf9096715478463932a1c632cc9a185eeb08583a9309259c567743995af013216b1086815b851655d0f14fcc43682720acdfc36f35806894177ea2144f6e28837cc887e560874ddcaaf60a3580fcc7a5f1733180b1f1202a08182345370cc5c46cd28a507ad846d1d9415af679d4b22ee560c6c1b2499d5b74aa2758da090e62713343b3a8b14c68e415a3f196c2573c5e828a16cea51443104f9cd899ad03c3b727774b48ae61db98feda4c1e029b57f89d1735381166b70450215af92120ca61a8a38e575abf2cfaa54c613031a9ba60275d23178ba553a3ed7179aac44fb3607e93c1c57c7bad6854533844bf3d6a9b95a966f891612239cf6cc41df1a859afea9c0cec6d2679cd7c71c2cf251dc9759666c871853a1012294022fabdeb2269b430397f337b3f416e528748903ccb8b24c8fa28197244c0ac3a0345e699b247c863e9a58d8caee564224faa36c70ecd281b67eb98908468420b38f3c24da9290ea98b242ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf3745163360f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6 + +comment = Official test vector 69, seed: "6d5a7cc326ecf3983c4e7683f45263a37f692f3bcd2d920e1fd9584350119e74f9a3f905f70d3e20318c1413de2a0dea" +entropy = 995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc +expected_public_key = b147b4694b12c461130f3126f8f71673e4643b2147ded2a7270ab360f6303dc05b03a314bb776c488318686069c3a4c91cc62435e829a6a8621ef5cf838311a4278d7f453ea5484d32f94c2e9628f5532ff93771dae106c8ac9cc80ad07d306b1da78463a08226657680e5acaba6819543cd96194aa5973d4f7b8682b13a07e7a5194c91ec95a2d671a2627710a4c78aa107b3707942d0c78f3eb2b3a58b7833fcb0fd7785e349a2f0027aff079b62a68e3f425122f7bc0a0b4c053a6696f90a67088f139b2a39f542d6439091e4c1a0824734d8b6e5e6483f48ca738c39a5bc2016c0746cfa9c1889297f5377d614acff2833ced20abed0aa6c7024221b73d53610575c6d91a262a5e834abb63cf74207437b31b1e989ecd7416b2c4e7bf807b5f8973006877e204a42774c93a1b394e885cf727b7fd286def2b4c8d5684460219c31b1b225aa08ac2ee1da3922e935e981b3b5e2c3d044a784bc965a580d3052ac48000ef6183b94b0a870e65207ba8029c0bd34a10443e5706792207fe2224da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1a518fea187bdd08072e47588527c3b9a5eb244ae9e910f93c92b69faa7250bcf38e68e9c3a2b2b733b18032f37673907097a4cd65a9b396db4859312d59113e07b39746c52126ea697a69929b1b625b5ae1b809ce9a811d13cca70971ae8bd6ad223206691af6897f136cb451699e0a19739d52d60cc89dfd654a320a79b2c7cd55116843239d6847b8bdc1efa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93dc2a395117426a17af4d404151814cec80e856b777eb35085f1ad14285078803c2d76ac1d25c3f8609aeeec4adbcb64136516a2077cff4c13748c5d1fe6386782688d944e0027a2f8c9af77b79352ea5523767cbde4577877af1f8017e4db244e833e99dabd0fc70824bc3c50a38275040446a5c74406873ba0b5bfc2570a406570b424727379e5c1c39ec194a29a8aa249844bea2a078c1c0f25a400d6bada80731a00b87bb5a19325b4e79b78af0bbb2c52c3db38ae552ca972c3927291145438115a952bf2a85e78f6141e1cae8516b056e614b7015017e71d54268ab9919b7eba09d196768d99651d60a334fc443c8ccd9064a420263a68531f0e86cdc48776a3d44b4726916273a0d3002de095526257bc5e6246dcc10814d1907885207a53241a184ab7e40d87148a336a33262a4bb0826b417abcdf957f68737adee682194115348ac58814661765bb321254a874c4a3c6745cf984528c2b9726ac35441015233219e169d0ea761425c06513720881b330185b48bc271b275dc024419d8761eb23801eb704f6326f162656713acc2915a1a6f877a583c8372cc391ebcf2cb22873c5bd22c58c80640cce759b2c09b368ab4ab504c613493479b7725a18811837213f9237734577af09c4be0b3fe07ab78b712b0683060be76920cc5fc56993e56c7b46a543ad675b2d13357c008911320e0d292268768b8370c66ce757af191bb703cb5732113acb8f02618eac98693224abccea04e7b3157c03b27a3cc4f0b880dc4877ac35077c1c2d5584b971261d2c4bb767c75907827ad7370f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992 +expected_private_key = de4627135b3976b8ac07c0059bb28d09e98e3428228c1786c2e8a1d6029d93cb9eed217d09b03e9a7561af7441e4271c7b6c8c862c5a93e955a05a87b01a63d9e8a334b26e1fc0346051bf31d078860a9afe939f4a90c2a395b2b6c205475164e36a0c2930cd26e26420470b0d068e36971a978b17be984a418a3cc5c6b62ab00d6dca5657f71e08b215edfb88a5b6751eaa525dea4b0bd41430388e0cfb445da3347eaa375b86858f19c81b73a4bf88c2f807638d808f78535b9fc6c6bc0c1402e16f0b784f9a22a30e5c6c1932c2063bc558a7b2636c76d5c0cb77e6c5518b3b31d920a23b2bfff3ab93fb03b3386f670b07655989c5185d5d393631e9acee701dad333379a63efbcc636bf2b4fa05b84a375559079c5909651e481da96b01a771befc7bc407db7d9f94b819a468d443a7aa8c9b4741266875268602336c1b1160a4ce5d41c57fb915335c87a72a7345316373d921a6d0ca09606154199c4f06c244a7c568bc5d82449149f92ad3350b51d3c474e77a3a1053160570c876132434aedd92c8961b95588910102c62ae1a75479175cdd666ab85478ebb6133920e9154441f1383b0f147137614dadc823f1848fa478b1f301d3f745c647c216c741dfd3b3195483f24f1a5313cb458273ffeb559689004cd534ec1369b0c68a873651f7413037118c6f98c538dab9c1ec649ff2301a03a650cc0c138e79d15f9079a639737e840a7dc720b173bb329a34cf65418495e4df2805a491a4c96b47d452725850ca8eb3944399f9d14157fa46b76f0891525461113766dc025ee1c2e735198c3db253a2b8a566cacb81b65a1c9473c6c6da9743d780685cf83cebb441cdfdc9fba20a9ce2943759c4d08c57a0e74bb0e1888e94723169437aec19aec1a2a46c81ae4645de32bb18f3527f4dcb8221a0f7be74f3f5a8cab0609be216465819fb858232b008a855c9e6b54439a67aaffd9701967bc46a274d1d6ac1d45cee7c54cf49669e89a44ffd7b73b2a12327a85bf5938e6975b949c03ef3a1d824ccde033cb175a3356c8a998e4c69d94630a896606fc1979dcb5c172a54eea2e99d5ae331bc64d708fae45c514a2544843ca59c3c122947bc3660da7357ac0e33f55485e79eb3117d14c42ec5c56653e0dd1a4e8205fe571823098ad8d9844a25b92238063a92040c500cc0bc2b25b493e4cf69de95c87b03b773a796d13f42014847727345888eb06d9251aede24d03e292cb452a3a38a0a461c8b4f9cd9f87b09bc0ca98e62e5027595c24792f818865777a346004fe3b5b587452648263aaf688154526d591acadb74520f3627d7395ec7b71dc3c6e8414985d591a05c88b6455870c48b12c576d7b328b88795295c051ca6293b0fb4dc61ab8ad34cfb114a4c7e44ab4667d4b1948c83c28baa424b19370afe997d8b08e447a2eff376024f5ca54dc8ec0972b96f057acf5a6b0d32869fab3e1797ee2571b1620a076082c4ba6799c27b07fb073092a7a2f7aa110635cb94900e487a6664b318f54956039c57ce509ede489faabac96cb11f58c87708a8ed3408a526701bfb8507d67415fe64e7d41081ac12c21f3092af02810c604f02c4064e348b4f98f6be65d87650eb147b4694b12c461130f3126f8f71673e4643b2147ded2a7270ab360f6303dc05b03a314bb776c488318686069c3a4c91cc62435e829a6a8621ef5cf838311a4278d7f453ea5484d32f94c2e9628f5532ff93771dae106c8ac9cc80ad07d306b1da78463a08226657680e5acaba6819543cd96194aa5973d4f7b8682b13a07e7a5194c91ec95a2d671a2627710a4c78aa107b3707942d0c78f3eb2b3a58b7833fcb0fd7785e349a2f0027aff079b62a68e3f425122f7bc0a0b4c053a6696f90a67088f139b2a39f542d6439091e4c1a0824734d8b6e5e6483f48ca738c39a5bc2016c0746cfa9c1889297f5377d614acff2833ced20abed0aa6c7024221b73d53610575c6d91a262a5e834abb63cf74207437b31b1e989ecd7416b2c4e7bf807b5f8973006877e204a42774c93a1b394e885cf727b7fd286def2b4c8d5684460219c31b1b225aa08ac2ee1da3922e935e981b3b5e2c3d044a784bc965a580d3052ac48000ef6183b94b0a870e65207ba8029c0bd34a10443e5706792207fe2224da533d307c3e3077e6e1cbad064b0399abc6f445b651864f18b42e1a518fea187bdd08072e47588527c3b9a5eb244ae9e910f93c92b69faa7250bcf38e68e9c3a2b2b733b18032f37673907097a4cd65a9b396db4859312d59113e07b39746c52126ea697a69929b1b625b5ae1b809ce9a811d13cca70971ae8bd6ad223206691af6897f136cb451699e0a19739d52d60cc89dfd654a320a79b2c7cd55116843239d6847b8bdc1efa29cdc0a979f0e3a8f225a16fcb7996fc8ca3e79fab55b93dc2a395117426a17af4d404151814cec80e856b777eb35085f1ad14285078803c2d76ac1d25c3f8609aeeec4adbcb64136516a2077cff4c13748c5d1fe6386782688d944e0027a2f8c9af77b79352ea5523767cbde4577877af1f8017e4db244e833e99dabd0fc70824bc3c50a38275040446a5c74406873ba0b5bfc2570a406570b424727379e5c1c39ec194a29a8aa249844bea2a078c1c0f25a400d6bada80731a00b87bb5a19325b4e79b78af0bbb2c52c3db38ae552ca972c3927291145438115a952bf2a85e78f6141e1cae8516b056e614b7015017e71d54268ab9919b7eba09d196768d99651d60a334fc443c8ccd9064a420263a68531f0e86cdc48776a3d44b4726916273a0d3002de095526257bc5e6246dcc10814d1907885207a53241a184ab7e40d87148a336a33262a4bb0826b417abcdf957f68737adee682194115348ac58814661765bb321254a874c4a3c6745cf984528c2b9726ac35441015233219e169d0ea761425c06513720881b330185b48bc271b275dc024419d8761eb23801eb704f6326f162656713acc2915a1a6f877a583c8372cc391ebcf2cb22873c5bd22c58c80640cce759b2c09b368ab4ab504c613493479b7725a18811837213f9237734577af09c4be0b3fe07ab78b712b0683060be76920cc5fc56993e56c7b46a543ad675b2d13357c008911320e0d292268768b8370c66ce757af191bb703cb5732113acb8f02618eac98693224abccea04e7b3157c03b27a3cc4f0b880dc4877ac35077c1c2d5584b971261d2c4bb767c75907827ad7370f4074721445e155a3a1624cb4aca373de6947f148ca7e2b3c93605e706eddd992de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7eb28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc + +comment = Official test vector 70, seed: "f68fc0314dea88f66afaa76e6c9b6804b13d4876924410d1f526fac59a62e26c560b125b1d0f8b461f1fc2e351effb4f" +entropy = 3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 +expected_public_key = c0c8122855031d7bb0ca735042bb43b8ec6ee13061046acab9b873b13519c22678ace2b59f92aa4e8269844b1de5e3426d66c0451a8d78cc07e719033a536c2bf4c7397c64c6478be5f42a06413b8b44111ad9742b8b020711446d63cdd64490c0917557b884eb429b05dbc0df7acec032adbba55d3e104f7bf391cba28b903a07712a8da3a1a92f5682cd650a628573844032a307704fe77af738696e974181a85c5ca1c14f7546f8713701115883480be2cc686625a37b62292367b5e1546f4189592639cda4cc20974c6a87c0377d15b8ec5c84b70233b64800b79c62e536553b43263532c6bc2b726970cc58bb20f0c0bd35b317d9b66b327bbeb5175d9611985ad799ebb19ad0587aeb856c288464d983256649827de9af0fc79afa1aa5817c06d3447a25ab3eb8248167ba60a4462ed47c007107b1eecb630ac4707b837f24d26da46bcda77c4b6ed5b4118b79294744788b9a9c21b168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb8615262408ae25c2985189ba8ab99643624b70557a984011474586c357f1c7551f0bb069336fe85bb903040f48c4a111113507055f2716d37ea6a6ffa48f40584914c4738397430d65756f298aad345671077da8a4173728364a493bdca944b1879b114166cc3b8293937221257c2e78f8f1c7794eccbf0368ce34921a2ebb01e32a92255a676e77c39564b575aa5d1f9c7d1388226d636f4f12c5636b2e2f712c59ca583a811bdfa56448c013cc820f21a36c3351aec3c2c6f01243ff47bf17181ecac752108c43a97729c6b9472270fcef5a7c08665f7aa9faa55b152163e8446c1bee5082192b5eceab269ec13e7879da3768bbedc0a104c5e9496c63e9507881a4c8e758211076653f369e58b59bd7cae5b9a64772c2a84329e43f492fecabbb56514cbe70970f361e6d3c6595065f6cc668c64bae7d587fa8bbad129136d5c9b6f757a51e653d2754aa0e35307845a55b80086d5a0e86302d306b9ee1550419b495d424f701a098220897fc47333d5a1e994c8584a00d79804e4989a1cf02dcf9a0ac2ac52be1090bb149778235ff6091075a5360ce095cb705c81e3be126984f51aa471f90ff98c21d3989fd936502a8a2b38c4a2320a618df751c7099d1063495a6a5936c744a094cc1ff1b04ba8b56b0464e852bbe06176034cbf5239cd2c687facc2cd37329adbec3a77b4842aec40be902e8af72fa5805345668408cc7b6073097391921e765e4d76025fd5c78e246da268a4db21446f2cc3273861d2081daacc2cc775631927b709dc1fa8993b1e92619590c08940342219682af351495b2e0aac74786c897fab196abb609e216997c2c7b283bfefca4b1f2b1b6e98991bb32424321ab7d61e4d13c44dc93295a75f6145bf2d4b8f1a03109bd7038ef4b16fc15f44ca6ea3411b68400eb20c46c11cbb98201d705a6cf4f4b792aaae80d97a6ab830576aa651142793fa7da0b8bedd877217d54897375ec285849a79268babace85176842c601ef8c740a21c2c5321436a21cb968ecb5410e811912cb0962f713322021516535907914b86e9411d27cf164b580528768ad37b57300dc201557bb0a142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d0 +expected_private_key = 84d7070ee80107976bfd1b0db6cc33f3c98178817d8460b63dc012311638aa43b253a705bc994931bab38a62c5d1dba793b8437bd600a8725d36aa898e353d6b955b80f8578f855bcee194ce2c6e4c6179ade8176e34578fb24b6d60c395b674a7a8a4c72550f83a09d24582f94125690428a4e76972b77a53e852ff3718a440b67d6521ca699e5a8c434dc47a38032129bb76bcb4c810028938fc94f1741a1fb26ec95252e259b8f9176bbad8763cb63da6f295b460cde1479be8d6b9e3c49ab77845c21c8f3f88741759461e339f76376ab81b4f07e7bf0db861a4ac5b24e09d4144ac900b43cec07f1dd2cc4f7c976eb0baa4d8637bcaa70946391109981e978ca023313b200092d26ccc823ebbaa85b8ba1680636d0be656f01769555b058af7825fa00d10a38b0a2b127a773cab406c1d4310a0882889759f20b44aecf68dd24416d9491cb523a1afb1a1ed87b28e5589f4059132603e228b185d426f49031af8fa21b11cb0f37c4557f94b2f158340921f95091128c5616f54105d47253f150ff335081d231f5b308a526b9506b03e0b5c6a88394f0c9c6e7c2b475c7508a3a8b1e0d571d1c364784cc8a7ca7ae6c2b24366a0d2865658d42a8495b24a16c9a9d8b1ea77332a1058dc292ec02c4723fa7204e93eefc24f10c4877425975cbb6142026a2aa649fc6c77e8c72dd3e5b0d9e9495a02c251b12b7ab51f6a9853bfd151a4873cab4102db62676496a8b38c8038e4c6d988880a6b2774875a5fe69693d9726af64a51d77a03e523bad8b2a6dbcea137a051d19e81059d07437e38db7891956c5b2c8abe282b5a02a5530c56a7b4b46daab256588b04344365313a3ad94a2d7aca4ba7072cb9259e2676a5c86215b24faa159bc18bce05451c69d2699a056ed3f6a7f2bc7676f11bb06cb72dc53d7ea6bafee89797b57445f3ae11262543a2882b863cdb455d5ea03eba56946dc61d798a76bdbc4ca7f2a102c518224a2091211ec4d251ccfb08aa2598065a79b8b61a56e925031a579ac5bdeef1a6e0b1381fe180db008f19e775e030052a624b91d1550fe5365260150ccaaf228acb8fe471d2c8b4b27bb57d62ae9ad9ce15a0b72ed98b8a619cfdd3a17ada37cc455d77640ea327088e9c33d4281b65dc9a27c68d27088b1f2a5fc586bb0993753e62a67bc3886048274ac267a95b42aaac3e60c2699321a79301acd350b92899a2c0ccc4703b243660a39c5901e3b6bb146c588dd3431c4a5bead8aa29e04f8fdc0d04783751707cc25ac359952abe7384f839b42d9c9982dc66a21c7fb5cb7316748423e25005d389bcd56fc498080f88cd75ec974ca9ce9f2ba995b50eca85cf09612fcbdc492ccc6d0662a59f8cc0ff3355f17424abb6c774a377b81c12b9982f60777926ba0b860123434cae8f926e902a5e633019e3c62087a1bdddf2186768baf91656d903c4f1ca88163b8dca041823bb6ee525583816cdfafccbcfe63dcae0b93c46a14fb72114194cd084c208921925e7c55ec807ee6c0a8ddb71c4ab3bd5836b7fa160009dabd1e5498d005718548324b0339ec71ac4a75c81f522dfd92b64e3676b337758490e068c3cc747bc004da30cecab9c542ffce826c0c8122855031d7bb0ca735042bb43b8ec6ee13061046acab9b873b13519c22678ace2b59f92aa4e8269844b1de5e3426d66c0451a8d78cc07e719033a536c2bf4c7397c64c6478be5f42a06413b8b44111ad9742b8b020711446d63cdd64490c0917557b884eb429b05dbc0df7acec032adbba55d3e104f7bf391cba28b903a07712a8da3a1a92f5682cd650a628573844032a307704fe77af738696e974181a85c5ca1c14f7546f8713701115883480be2cc686625a37b62292367b5e1546f4189592639cda4cc20974c6a87c0377d15b8ec5c84b70233b64800b79c62e536553b43263532c6bc2b726970cc58bb20f0c0bd35b317d9b66b327bbeb5175d9611985ad799ebb19ad0587aeb856c288464d983256649827de9af0fc79afa1aa5817c06d3447a25ab3eb8248167ba60a4462ed47c007107b1eecb630ac4707b837f24d26da46bcda77c4b6ed5b4118b79294744788b9a9c21b168565d9398b41edb91517493f5fb48ae5cc04fb95bb13a8fcdb8615262408ae25c2985189ba8ab99643624b70557a984011474586c357f1c7551f0bb069336fe85bb903040f48c4a111113507055f2716d37ea6a6ffa48f40584914c4738397430d65756f298aad345671077da8a4173728364a493bdca944b1879b114166cc3b8293937221257c2e78f8f1c7794eccbf0368ce34921a2ebb01e32a92255a676e77c39564b575aa5d1f9c7d1388226d636f4f12c5636b2e2f712c59ca583a811bdfa56448c013cc820f21a36c3351aec3c2c6f01243ff47bf17181ecac752108c43a97729c6b9472270fcef5a7c08665f7aa9faa55b152163e8446c1bee5082192b5eceab269ec13e7879da3768bbedc0a104c5e9496c63e9507881a4c8e758211076653f369e58b59bd7cae5b9a64772c2a84329e43f492fecabbb56514cbe70970f361e6d3c6595065f6cc668c64bae7d587fa8bbad129136d5c9b6f757a51e653d2754aa0e35307845a55b80086d5a0e86302d306b9ee1550419b495d424f701a098220897fc47333d5a1e994c8584a00d79804e4989a1cf02dcf9a0ac2ac52be1090bb149778235ff6091075a5360ce095cb705c81e3be126984f51aa471f90ff98c21d3989fd936502a8a2b38c4a2320a618df751c7099d1063495a6a5936c744a094cc1ff1b04ba8b56b0464e852bbe06176034cbf5239cd2c687facc2cd37329adbec3a77b4842aec40be902e8af72fa5805345668408cc7b6073097391921e765e4d76025fd5c78e246da268a4db21446f2cc3273861d2081daacc2cc775631927b709dc1fa8993b1e92619590c08940342219682af351495b2e0aac74786c897fab196abb609e216997c2c7b283bfefca4b1f2b1b6e98991bb32424321ab7d61e4d13c44dc93295a75f6145bf2d4b8f1a03109bd7038ef4b16fc15f44ca6ea3411b68400eb20c46c11cbb98201d705a6cf4f4b792aaae80d97a6ab830576aa651142793fa7da0b8bedd877217d54897375ec285849a79268babace85176842c601ef8c740a21c2c5321436a21cb968ecb5410e811912cb0962f713322021516535907914b86e9411d27cf164b580528768ad37b57300dc201557bb0a142d9416ed7afef52d284175dec18f24979ef5ba8eddf7caa3880aec7b42a147e75f0dd62b3d066f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473 + +comment = Official test vector 71, seed: "a229218b0d51f58d915df549901548fb0722f352c7470900e7e4d8399205764a319bbddbd06c00e8c5932722ee5a404d" +entropy = dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f +expected_public_key = 80b3b92647a1dbec6bb883a4b2160e4dcc84c89c6adbd955cc055933d3238e325fa826acef899a555873a5b9c189117844202c65e40eaba07d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885660b1d3df32d1bd50cc50757c5227928b32e0c567872e66bcb58128b15c8696710a7b33bfda469128996f6979f896b93d22910383c90d0d877a56b4b7c77c53c99128719c2995497dd36877276a25fa8b74a4947e223215a314a075585da457daaf17c41711363950ef9013a8ad95f9e07635546485a3568aa502d608321061a6999057e705c46b6691183874fa9ea38bc392f718c99ddbba59a1865a135207a00058a408b6c61772ce777456c92b28a51ce823f7524a26639ac64aa49d6903cc2b2b5b60b59643bc950230362caba6abb5ba4f6964331b1f62099cf385be3f5b43c2b8402006bb3386f5a16354e45118f0b759c3363ab4069ec2c4c15cac4e07a24fab0c682548337d157e6ba213c7801dc5a0a7045a442b4939d611469746e9da665e2e910b51c56b77a035900b25490216c0bb53e04173b3bc454a7a17d77283ee278e7d30496301480c8c1af6b3e1dca213b174f968c8a45a3ba2044bddb1492bef2af610b4ed2481ae0823df53282ba7750fbc7a764db58e3789ccaea778083c27ed101e3c75be5486249f9818a08047f97447773c7dec3ba7c59aecb5778a09cb7f1182b2e0a01c182a1bd13ab7d72af97f96f564607a9a970b35a6adff275c35c22c2444ad6e997d821c065ea49080900e766c0079b7acae7bc7cb3b31301656fd39591e0bfec2c33f05a0dd633bba463781f1c519d902342bc12bd16c1ac8305ea9769e489073297784ee45f99b248670749c728385f601fc84c1ffb298bcc447537785226bb5de712b7bdd04a0ce39226919105f06ecf6bcddb0cb5ec3b5505b5a169b05480b2587ce4934d2b232a44a6683920a81a6038c59497c9b47faa62f4f2120b15c360616e6573bcc5a23a88887b50d1a7dbaa429bb00a9f87b63829b1b641922425016c979db571ba0f1a139267bb362c68f47689715cad6636402049c2b5c616c321cba6e43c1c1a48a0e141cf3a71c0099bd183a5c0e59bca9a2fb637c1b534cb6687493eac495acc7c5fcc4898a52e44094fb1b7014a15c88e11a9e7244ee53c2d5b16708c233ed37859268501630a296d63c094f563f0e559c59453abf05a93722aed5ac0c3cc6a0be7890f8c3191677c21f70c8153ced3e2bd96a4bfdce27f86b809d8ab04dfaa837fe030f420b845d23c78cc82a2d7c440897c91c3b726b4622445899de72bfa263b93c3cceaa8500b4b0c240046387b25bd98b5901aa670180a2a8b27de424f4d804a68dca2e044430d701b67e9b4af33c60fc54bb3a94a8b8604fa5882a401a5647b8dfbb20878e4b4094136bd4b5bc14288463c2e87f0cdf6d9497fdb5f42f26d2f9ca2e048a757a59b440c2c5642232e714d11fba959ab9ac52126bf689864ac98cbd1a633baa3ecf75c09c4c6878994cdcb3e882798ea02aeaf39915dcbcebfe2ba14e620f53b3d83ab58bbf99509033db99b0acbac29fb4674c95cb94982ac398c2771a8ab6da1ce9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab39 +expected_private_key = 47318b2cc6a9d8bc6ebe7c12489017c03214325b61a2a8541fb783c448c3a31c1d82ba7906b09e3512af8d00d0706a3d391281f0315044c9c4f92b0ad72c60e18637577b942a442589cbb466ac344438750b86cc86b97d16339a9db0365e6696b183041543b031c9220e82bfb89c21a5b0a0d301109568b1c00b2b878c9284375949c88394f141abc188ef7607cb8151bae654a7b7bfd785b44bbbb5c5a68ca5f96bfe5abf179cb83a58aee518202c9119c80081beb38caff81f5ea51811f13be9491f431b127783227bf9b691031145d6a144213fb4f1c89c38c00c81abf075c4415586bdf28b946380c948b94d7a0c3a793100842230663f4eda9174dc7214884e0f552a50d16dfd0a5ddfa7920b0aa50437bfc735a546f5b0f4bb22e174b061bc80e91428547576b6205490ca3934c9b15fcb69611a1639974478800b2cba3d5243a0e2762be2f87035295fff40b56be37ddc71915434c4af6472c1e5c519506e691703c49c715b50b360a5c2fcdb79f59c7ade27380f9905eb7aa6f5042c6a32bae657c699eb85a53395c0303e87e89800131f96969bf45b3f574a40ed813268603a24f1c3180607814914775350b88a1fa7e1034c9cb155879668950ad5950803abc0cc58bdfc408fc1f2bf7d3a2972aa66b58844c048150c0b8c89aca3bd3269474875bf10a94d2b9ea3687ab9547ea59731b73a8849ac7b7c4b946d70b8b87c56b81b77024503ba87485ba3655f669770410e89fc84925b87c008c3cc13c7b9447d82fc2932a1c641230725a422b6219d9bdb5ceef17e121132e6615075e0b26cf71e91a1593210a09507214716a3405b2503ca5f29d4479914cd10b3457aa62a6bb71bd08736e1519e69f709b8c8439b4441bbab5d0911bc6737ca742747ca592e5ed734a8aa1b77450a9d4188e05422bd9240e285865d530e718c6f1a816153cc27414446bba8129a1716171aa60ae086ad09951c2b9aa2744e0153cbd4ec9d1736908cd78e7cd75d0333434715c517633ee6603f7993083724a596069f3270c071b6bab955844a081a896096f76059b9738d819ca3b6588d5f578058d28d2d0710b2bb2e307a5f9e18533713c41e172a99614a97c00ac0a83a25526c399cc9fa9b74cc4774830c8e754231b04274c90c526dea7fe3d203688114e7a90d3ac02ae69a139649b754581bb56825a215c3ba282a26c036e5d5785c07c62956b612fc37fb73a7c6ebb506b998d54979ff29781cd09ccb64993299745b34b6d7f897c0e05e1a6966e6757dbee29af2eacbbb7701dbc39294db584c7c3a7841112258951d88145cf73404a17adb8cc4d11788225557a83b652f95053e8507093b2a8b00ce77e7bbbe83233dc18880f2274472c05e646b90952fe92440d164092a058d69c96869d8a83377a2da92c2d668607dec3cbefc6242b49a9da97c19c2067722c8d309cb898593b08b5d8138bf2fd1c59081614f764acb392d7feb205a85270dfc1129929cf7b53d41031c92944972b8bc9a9c494ab384996647e177a87a101c45c747660aa4a38088a5f7919ca46dad338576463a1c1425a6c4409e2ba8217827ae83bed4e6c80ab528a6bbc1ad58c868b995d9f72c77e84173c9ca80b3b92647a1dbec6bb883a4b2160e4dcc84c89c6adbd955cc055933d3238e325fa826acef899a555873a5b9c189117844202c65e40eaba07d9fa94d421bafe8f3a5e3346b6b93cef8b75628e4418e2885660b1d3df32d1bd50cc50757c5227928b32e0c567872e66bcb58128b15c8696710a7b33bfda469128996f6979f896b93d22910383c90d0d877a56b4b7c77c53c99128719c2995497dd36877276a25fa8b74a4947e223215a314a075585da457daaf17c41711363950ef9013a8ad95f9e07635546485a3568aa502d608321061a6999057e705c46b6691183874fa9ea38bc392f718c99ddbba59a1865a135207a00058a408b6c61772ce777456c92b28a51ce823f7524a26639ac64aa49d6903cc2b2b5b60b59643bc950230362caba6abb5ba4f6964331b1f62099cf385be3f5b43c2b8402006bb3386f5a16354e45118f0b759c3363ab4069ec2c4c15cac4e07a24fab0c682548337d157e6ba213c7801dc5a0a7045a442b4939d611469746e9da665e2e910b51c56b77a035900b25490216c0bb53e04173b3bc454a7a17d77283ee278e7d30496301480c8c1af6b3e1dca213b174f968c8a45a3ba2044bddb1492bef2af610b4ed2481ae0823df53282ba7750fbc7a764db58e3789ccaea778083c27ed101e3c75be5486249f9818a08047f97447773c7dec3ba7c59aecb5778a09cb7f1182b2e0a01c182a1bd13ab7d72af97f96f564607a9a970b35a6adff275c35c22c2444ad6e997d821c065ea49080900e766c0079b7acae7bc7cb3b31301656fd39591e0bfec2c33f05a0dd633bba463781f1c519d902342bc12bd16c1ac8305ea9769e489073297784ee45f99b248670749c728385f601fc84c1ffb298bcc447537785226bb5de712b7bdd04a0ce39226919105f06ecf6bcddb0cb5ec3b5505b5a169b05480b2587ce4934d2b232a44a6683920a81a6038c59497c9b47faa62f4f2120b15c360616e6573bcc5a23a88887b50d1a7dbaa429bb00a9f87b63829b1b641922425016c979db571ba0f1a139267bb362c68f47689715cad6636402049c2b5c616c321cba6e43c1c1a48a0e141cf3a71c0099bd183a5c0e59bca9a2fb637c1b534cb6687493eac495acc7c5fcc4898a52e44094fb1b7014a15c88e11a9e7244ee53c2d5b16708c233ed37859268501630a296d63c094f563f0e559c59453abf05a93722aed5ac0c3cc6a0be7890f8c3191677c21f70c8153ced3e2bd96a4bfdce27f86b809d8ab04dfaa837fe030f420b845d23c78cc82a2d7c440897c91c3b726b4622445899de72bfa263b93c3cceaa8500b4b0c240046387b25bd98b5901aa670180a2a8b27de424f4d804a68dca2e044430d701b67e9b4af33c60fc54bb3a94a8b8604fa5882a401a5647b8dfbb20878e4b4094136bd4b5bc14288463c2e87f0cdf6d9497fdb5f42f26d2f9ca2e048a757a59b440c2c5642232e714d11fba959ab9ac52126bf689864ac98cbd1a633baa3ecf75c09c4c6878994cdcb3e882798ea02aeaf39915dcbcebfe2ba14e620f53b3d83ab58bbf99509033db99b0acbac29fb4674c95cb94982ac398c2771a8ab6da1ce9b0771e3d5c2e7655b4bb99ebbb57adbc7a540f228114639b811c5c1d3b614daf84266bc4c312fa43c4109dafde79000ab397537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f + +comment = Official test vector 72, seed: "6960f21c7350dcf41b4770c551dc8692d8ba2c0b6e162c589166ff22e7a1ac0f94c2f48504a5f7eb0da094df427bc98a" +entropy = 1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 +expected_public_key = 03a20a0337040adab8bd449e0beaa93b07512485ba33f291af1a44540bd04af4a3dd2a09f6454d7304d0944674a580551061ba5f88217aa57c10640dc1a97396f138c1a32cf40b0bd9286f88c4087f9084a9012d248c63efec072d77ab0e736719a23a913b7b8b62aaa5bb40be97cbbc1c29edb283c776aeb9b032e2c2691aec9ce89617b84b09712b40e2b713e566c714e0baa75957d6ba5062ba76471357252b72ac66ba97e10921ca2313a232a6ba908dea13645b5617938381fbcd748a11f61cbcb615c458d056f0d55a449c4f544c6673322ef106010cf139d1c586aed5a5dc210fff7a60f3138c34a4244398b692c567ade5beb55c1edcfcbd93183e1ed0c2aff5bdab67b51e39a58bdb8388d67cc1ec0d7313b7ec8a56cf3c9b73214c4ada14592794749b6834e9b81a2ba47de929e9ac7856b56549f40f38f0784ba0cdfc195952d3155222bceaba0e3c233ff7e19a65822437217a42721f9c060ac2cbb9c4e6bfa9fc3014d8add7b4bdf78291423511f9874a07e06a82b6369fe349e08333c7f56b7b7b808a0b4e888a95799a2df4873944cc43eb958b1508c66e571268e79a69178793e7a4d430507e1259d01c86f999c16772cfb7b4b330114ff55a51ee5407bce95a6d27875a91773420c24f8734b3023e9db777819ca2163c431de46f22f38398d46ee352b815b6b07e1a242b01a4230b59ea8c7b0c3c3dbe2b7c77b4c860660daa04c452e391c710722c67bc0632c072fc1e5296a2e70932d4d38efbb96bd636bb41260a7bf27cf5e71ce3708e6884cf0b8584adc3cd3b5c5ee1003a13731704472a203c8f9b49534309bf2b60cc3e2448e02b5a46d889ffd78fbe722a709a2d5b5c8a7d805bcff44052c553cb990ad016079bd87db7573eb1d431d1e549edc8ab56a0bf52999f32555e8ef2b03182bd8d812cca638055a73b548c8b432a2a7d4a6a074aa212d50362d1382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1edd04f8f8cb7af4c947af224dfe0af6a42c7b65120b9c18abe9161d88cc5c4780fd74403cd177f7160281884a11cf686f0f523f39cb7ad39b780f13a8ee83c0d646f9d85babeb306d53a7df53ab00b5a1aa8c215914a48222940fee10d1939ba5c93617690cae113a59de071c969436b3771fc50b2f4aa641a4c852922380a420fcdfccb81816f4b474a2ab293a4d97b2b280cef031148ea7e4c9c0db7e7cd0e50b203a6b7519c3cbc8062c9b60b8b81cd956463b8180c67f34be4868e3ba94b9f0226d9f010d9ec5ef0bb62c865c807184b96526d94170af9474bbc100530f7c77e46b98c2aa41f92a48d8027c855c7f84684389bcc8e7c67164a204bc5c0c90828faa439fba235b6f20785cc8ef4c090a708bfbbe26e1933886cc96ad9b4562a119d4c66589c85bf0e55606886206734142d432c1b032e0aa93ee3731f069a8cc069a03b95a8ab873b447a04ead3a32be3054af834882bcc581712be18539b805577e50ff5d982c98c0b0dfccc96a4c6429281068c8429997dc17a6600f0736b8453e3d77636faa8d0ca89f9193bb34819ca1117ea368ea23198ee11345c613993ec052992954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f30 +expected_private_key = cd28aa8c74142a0508c2534d5adc64284806bb2c653bb9783adc640e9945c253af86f57c19b42c6697ac85d1bfa46b5231559c11f5a0da9b2bf43c40001d4e6c00b81237343e15a41da190cf8940b641a4b42b72d9cc8bac681369dc07d80aa62f135b0f956355a4a68e575f34393c42bccea68a7a63c269a5821557299ff63b9f0161368f6084132c8b56984f4d1626d7436dae2596e1b24a86562374b066d2483a1b354fff9766845480ff396f6ad089b724b0f15a34c2288deb05a8418909803cbfe2f3c63c30056f358fab798f4e385eb0e35ed0c38ade7382787a2502d117ad0bc6cc0a4746aaad23345f10074b21970c18eacc898472766b2313472dd3348c82f69b7d961cd35a8c61984e7ca20ae6382f04a977a72b532a1395707cbb7cd595e0da0202498058e59f22e0c340c438851674e3ab1e0d872fda3baa7f87b67f449e6bb461bdf1cd771475d5b59facc30181599ddac8ce68dc2de5741b21422fdd512b39d9633adb202af3941e323c9326297cb58086c3282f722c4d50b94b32153ff30b91f07a811a9d9e07b7667846806b6f7071ae29323156b668f831a9f79ab7949cb363dcc8d151349db4b5ec1266e7f5af98105c95c0a4d47648aeeb01fbe1113948b407fcbe199bc2cdba40257745d765c6a0766012f19df41a770e96cc95d3cbc70549f7e61914a73dc71062f2a3a377ec26ded59e0cc85b11a74f43c3237c7561cb7046c0e660b5bb0ba0634ff2b211438a9b9b906f241b04b2439f29a3cf0ad9128d683f0c2c26ca050978cc179872b1664a751458c072106fdfa07d97105188278268b0481018782f361d08555fe5799a0654398285b378f7a9f143ce20673184c75e8b662085899812912fb8a60485921b2f7b3feab95cb7aa327d8b9dbcf7c7256a131270b731e33f8f555cf4f8b7a1e6aabb4c83d2938b7b21beb1c3b3cb3bc08bf52fc1f5715fa89ef8e205d85862f6a2cf420592aa24568fa0b8dcbb90d0b654c7c82c7411b6c3e219f46c352aa034c4fa0aa4fc47daac204b351497727b96714359a66466f6c4cc2b83bf6b87785367c7116489d6c5feb975e41c4bbb2a3d8fda920021c523227a438374d96032f62c41b17422584ab5880475cdda8b7f4844e5420c25d97235b0acf71012adab59298bc80052aaf1807e8015695d92184741bad318ba9ae27c306a2e42c80512534963b70b9d0b7f5ae70326c33e7d43249e8c9ce386947c167c8f33c88947244989c45b4858203249fa5a136734153cd94f1ad467b5043f7ed77f58d34490d1b5f9e323f3e2146011921b8a9f94e419bb85ad965443e7f4a73534457be43ee5f677a63a7738762b799600fa0b9cd328ae4cf507c1d9845eda77c30bb7c39c618afb402cd9b016f0092cb61e8be13a18925ca122a142409b8dc637a364093cd76925a194aeda21c61709255ba2de330693b888a6c2c6f0c39fa5b4c7fcfbcc198b3253c0abc5ab5edfb438ed3a82b72b5f54a39d21c37879480c4a648f182a94ea566c598ba4cf697140a20fdf4cabbc540b80e8664216a6e880553899964a7b239d00c68e720706512cd2a58b9c49bc0acb90283b506ca196f7855ed69ab21f059a11fa3fc4670d03a20a0337040adab8bd449e0beaa93b07512485ba33f291af1a44540bd04af4a3dd2a09f6454d7304d0944674a580551061ba5f88217aa57c10640dc1a97396f138c1a32cf40b0bd9286f88c4087f9084a9012d248c63efec072d77ab0e736719a23a913b7b8b62aaa5bb40be97cbbc1c29edb283c776aeb9b032e2c2691aec9ce89617b84b09712b40e2b713e566c714e0baa75957d6ba5062ba76471357252b72ac66ba97e10921ca2313a232a6ba908dea13645b5617938381fbcd748a11f61cbcb615c458d056f0d55a449c4f544c6673322ef106010cf139d1c586aed5a5dc210fff7a60f3138c34a4244398b692c567ade5beb55c1edcfcbd93183e1ed0c2aff5bdab67b51e39a58bdb8388d67cc1ec0d7313b7ec8a56cf3c9b73214c4ada14592794749b6834e9b81a2ba47de929e9ac7856b56549f40f38f0784ba0cdfc195952d3155222bceaba0e3c233ff7e19a65822437217a42721f9c060ac2cbb9c4e6bfa9fc3014d8add7b4bdf78291423511f9874a07e06a82b6369fe349e08333c7f56b7b7b808a0b4e888a95799a2df4873944cc43eb958b1508c66e571268e79a69178793e7a4d430507e1259d01c86f999c16772cfb7b4b330114ff55a51ee5407bce95a6d27875a91773420c24f8734b3023e9db777819ca2163c431de46f22f38398d46ee352b815b6b07e1a242b01a4230b59ea8c7b0c3c3dbe2b7c77b4c860660daa04c452e391c710722c67bc0632c072fc1e5296a2e70932d4d38efbb96bd636bb41260a7bf27cf5e71ce3708e6884cf0b8584adc3cd3b5c5ee1003a13731704472a203c8f9b49534309bf2b60cc3e2448e02b5a46d889ffd78fbe722a709a2d5b5c8a7d805bcff44052c553cb990ad016079bd87db7573eb1d431d1e549edc8ab56a0bf52999f32555e8ef2b03182bd8d812cca638055a73b548c8b432a2a7d4a6a074aa212d50362d1382747ca8dbb95e03945d95b995d6346d7db47b24b86e4f774f3767db7996335b789733cb251f9b1edd04f8f8cb7af4c947af224dfe0af6a42c7b65120b9c18abe9161d88cc5c4780fd74403cd177f7160281884a11cf686f0f523f39cb7ad39b780f13a8ee83c0d646f9d85babeb306d53a7df53ab00b5a1aa8c215914a48222940fee10d1939ba5c93617690cae113a59de071c969436b3771fc50b2f4aa641a4c852922380a420fcdfccb81816f4b474a2ab293a4d97b2b280cef031148ea7e4c9c0db7e7cd0e50b203a6b7519c3cbc8062c9b60b8b81cd956463b8180c67f34be4868e3ba94b9f0226d9f010d9ec5ef0bb62c865c807184b96526d94170af9474bbc100530f7c77e46b98c2aa41f92a48d8027c855c7f84684389bcc8e7c67164a204bc5c0c90828faa439fba235b6f20785cc8ef4c090a708bfbbe26e1933886cc96ad9b4562a119d4c66589c85bf0e55606886206734142d432c1b032e0aa93ee3731f069a8cc069a03b95a8ab873b447a04ead3a32be3054af834882bcc581712be18539b805577e50ff5d982c98c0b0dfccc96a4c6429281068c8429997dc17a6600f0736b8453e3d77636faa8d0ca89f9193bb34819ca1117ea368ea23198ee11345c613993ec052992954099bb9a086057df0c5465326e1932aa50da74aa8435d9294fd6b7c05a153f3082f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6 + +comment = Official test vector 73, seed: "53df46012cad4a745b7a3c06e18ca95e0b839fd8161e3025749a0887549eb0ed6a44eeea08bd6060d6509dbf7e9dc864" +entropy = 3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 +expected_public_key = 611ba36d3a65c0d17cb22b7f3a682b593595b1c682d521a16dd621a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf101bec273bca5d606a5e76fdc183175a233c93373e956580a522badd22d97d71199c1a7b4149e652686eda541e69187a2abb68f89ae9492443547cfde7b5d609b4835911d154c33e49248c4cbb244acbf03e93e52e71ed87a75cbc43c3f505422c1ac31c014e82009d4b13bf2cb7dab16896a320fe6c0476f37767ccccd80850dc94b410b983fbbcb484dd09b44a817fd95686106c710d983cd2bbc11dc4ae59091a401a6941bc704142c792c407f7524ede1a71a726e2f921b0626768307c31dab514a783febd67b50e93479d2c7d1787142f591607b7a5626a718d502b37a6f5b8766e8175c6ef276934a12ac1107aa3362840513d3f5c02042ae681181dcab30f6810389db07c3fa1790345e786031e3196bcc01c22bd064b2f9c439d7b7a7b7633232aaa4d88e0288cdb791049b8a8c64883637098def7c88fbcb974554af0f3c51c70a758176215871227869766452871602093d6949e1d078691537d9d7030b36926147aff8151cfba202c0364795122d1d748a18289cdb33982900b38ef9aaa5d10d146985c757ce5cf82ae0a2489e0c00c83550d455a03fc885dc7a5ebcd71529ecb0ca13ce1259186f9b0ceb4b90789aca0762c8bee063780801ce365540f440b0aa0128103ae0f5b4a5d9b98ff3aec5793e8fd046a7e15b517c5c4164105e87c593db19b85792b6c705e615c4d95c38bc4bab4f30737a20241a3189eb38865c6b60f6341dfb931626e729ce39313e122687862bced934ccf88411730fd066be831542abc5b15a1cb2d3f0aeace904cb419754d9a5cfa35d72e570c8d3b0bde5a5b18201f14cca3e3564c16769757a2daa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436bd21282d6a3242417b36211c84b75f388151f087186cfc01e59383e8218039db15da50120aa1c5489743bc42335a774f8494a4244acb6677b22a46224df7bdd8a9292ae58e07f3068cd975abb51e44631172535e52c910b48748a190c50d877903a4c7b9f4b18993669d254ef566058528a157428111d43d360ab54343adebc2a3636720f1e0c8ccfcb0fc3b71b55353c2682946408cad171fb711cf0b3ab561ba6722647acee4b8daf0aee2c43352609dc617549841adac54adfd3319efc715dd917ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a551230a335510f55733ca4f3a6329aa0830894e06a05ee578c45b3117fd07d62718a9842ced5f49710f7b15741ba5b06298c550b96bc6fdb0561926240faf09012e2cb49c66868e27ea318aaac50bf882c5bb8e674381a96645b7a7dfa936201933c31955e24912e436528027b39f74a909aa5ef4653cc23c5e448be6f81088fd322fbb1779be52ad60005c2f57241932ea3b435c47a39e6e0477b989c00bd5ea71ba671d8a37dc64d36216ccebb14e6dc7420c362926b555598b92f6a78061423a4cc8961d57733982fb8c78573c35584185fed801ea674a7fda06008517b42d1a45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0 +expected_private_key = 8dc4a33d0a013d102a7ed6a5303693669033816bce0c8a83594695531999647a48f6708c65220be4d9a60f013201a36ee053796356b26e3617126c3d0a354d2fbb82312a372ffa37b939a7bac8ad0e127f18eabc771462fc57b542a73bb7067fde6bcffe4982e6db3394264d34dab222318856ba8b6919c5a0a667866c0d2166b69ae04432c044f289bfd7255542cc7946b82c2db388c8b656f234a3b607c2f6611acc3a5a12c8111e42138abca9b8dba79921a177682c2ad1138b133636951f5aa77a52b7554943af52f7b53d0b84ecf44fd77018f7062e564c5e58753994724242d6b3a8f8a66df518f7e13a0a5c1c4b253dce12ae197342f5d72c296498bc9888ec347f528958aa689c8ddb81870184c9e2254f918b7465354826870300790044165216c8bc279ae93854381c28cb438bce444b2258afc3a84cd4f91de8373f877b30137c4ce4664e4d330bf763b344489604e97f4c9c24ffc226d07c5824ccabe38cae22487ea2ea0e89920f304bb911b401f45735089512dca2298ea1a57f643cd7524a3d6c9f055b25eaa62fbda318a7b8c8dc9c5cea953ad5170c0452a7bc04469987712d0522256a1ec52961561175c32abe93dc5ed37289b9d4cbd3966911fab85fe47b3c68692cf5a845286baef91493e15c6d23437bf7517ec5cf609c8628d82ff7cacb54d4a5ead25c85f59ab51151f9350247782459b598a2089a85f2c9bf66797e863a4ca0732268a4e40c57009d0c7d1ab1ff46b78e350dbfc19fcae823bcc040183a27182abde00a966a6075e68c011aa62eef913024ccc85b460098facc9c4c81d17c577bc009b8f9416d225d156c4e75b84691a90948d31883b1b2ab3635dc357ae867b2496983cf9595423c541e3c17947042b3d141ef825c99862302ba911c67619434b3f9cc489e8c8abae92af1ec3045c895edb41f745aa1f3d1a625e47eabb49432129a5608571431c4890c8fa5769563b8b1f9ba3c1b77b034f568038865c90304a4f79f65f74c17fab9e6b52236cb636ef5b686271f955a9e889b7a1ea1a010828aea1a838de1723f0149cf172f48890161c34039e99b36185f068b5707fa476d650bf149479b8c928f93089a4b941047b5b528135685797e0b9e65f595d9016a614393cfd630c6a217d0a03091853f606b238ee13c92c2b5d9e19b2c57638ce82a3d767639e115838b8eeaa5a47b7b686ea05cc088abd47a10ae593ae39a07f55cb4c1347acaf7cf59422182749e6aec39d62ccb876094ba3cc0b871c57a03a00ad67c5c1c6ef911c6dc36b13cab713be1a6610caa46db4ebb86b76572a0bd60adf163b325c89b506c33cc343c37a2bca7cacabd90494f044b550778677c2ebee76e03622705556b509c204087b5c5e5936c0153857691c3149521b800b76c43195897067529a4a87d68e974ed57178b7980eee227e4150af1234025757eaa3b645064202d632eaea3943b40cb10922bf569ab2c44867c411bc8240d110134d78143d3d44b450056be166b57921fe64a44f80968a1941d91a971e10c347aba369702b1ed542984f28b6254bf61d94b69f015b0e32b05e8897502238fd21d87978eaad45bf5997654b40a903319ca64095c9297611ba36d3a65c0d17cb22b7f3a682b593595b1c682d521a16dd621a05a7d22c9b2d29c9bb75cc5a8567ed3a545bad39e2c85cec0f83f37c6aaf101bec273bca5d606a5e76fdc183175a233c93373e956580a522badd22d97d71199c1a7b4149e652686eda541e69187a2abb68f89ae9492443547cfde7b5d609b4835911d154c33e49248c4cbb244acbf03e93e52e71ed87a75cbc43c3f505422c1ac31c014e82009d4b13bf2cb7dab16896a320fe6c0476f37767ccccd80850dc94b410b983fbbcb484dd09b44a817fd95686106c710d983cd2bbc11dc4ae59091a401a6941bc704142c792c407f7524ede1a71a726e2f921b0626768307c31dab514a783febd67b50e93479d2c7d1787142f591607b7a5626a718d502b37a6f5b8766e8175c6ef276934a12ac1107aa3362840513d3f5c02042ae681181dcab30f6810389db07c3fa1790345e786031e3196bcc01c22bd064b2f9c439d7b7a7b7633232aaa4d88e0288cdb791049b8a8c64883637098def7c88fbcb974554af0f3c51c70a758176215871227869766452871602093d6949e1d078691537d9d7030b36926147aff8151cfba202c0364795122d1d748a18289cdb33982900b38ef9aaa5d10d146985c757ce5cf82ae0a2489e0c00c83550d455a03fc885dc7a5ebcd71529ecb0ca13ce1259186f9b0ceb4b90789aca0762c8bee063780801ce365540f440b0aa0128103ae0f5b4a5d9b98ff3aec5793e8fd046a7e15b517c5c4164105e87c593db19b85792b6c705e615c4d95c38bc4bab4f30737a20241a3189eb38865c6b60f6341dfb931626e729ce39313e122687862bced934ccf88411730fd066be831542abc5b15a1cb2d3f0aeace904cb419754d9a5cfa35d72e570c8d3b0bde5a5b18201f14cca3e3564c16769757a2daa89b03dd993ec8b7c9fcc63098478af1890346a8824a4b142f88759f382292ac404f436bd21282d6a3242417b36211c84b75f388151f087186cfc01e59383e8218039db15da50120aa1c5489743bc42335a774f8494a4244acb6677b22a46224df7bdd8a9292ae58e07f3068cd975abb51e44631172535e52c910b48748a190c50d877903a4c7b9f4b18993669d254ef566058528a157428111d43d360ab54343adebc2a3636720f1e0c8ccfcb0fc3b71b55353c2682946408cad171fb711cf0b3ab561ba6722647acee4b8daf0aee2c43352609dc617549841adac54adfd3319efc715dd917ab2b887dfeb49cbb6323acb566e43638a5c9b6f865da4157cc3f866066a551230a335510f55733ca4f3a6329aa0830894e06a05ee578c45b3117fd07d62718a9842ced5f49710f7b15741ba5b06298c550b96bc6fdb0561926240faf09012e2cb49c66868e27ea318aaac50bf882c5bb8e674381a96645b7a7dfa936201933c31955e24912e436528027b39f74a909aa5ef4653cc23c5e448be6f81088fd322fbb1779be52ad60005c2f57241932ea3b435c47a39e6e0477b989c00bd5ea71ba671d8a37dc64d36216ccebb14e6dc7420c362926b555598b92f6a78061423a4cc8961d57733982fb8c78573c35584185fed801ea674a7fda06008517b42d1a45fcc50416883d0963d3b744edb5e8548c3b3dc474f7843c49a8dbfc939c41af7f8ec6c8354aeb0c67e05eae0104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99 + +comment = Official test vector 74, seed: "deb963f8b1d8fbdf499d564ba8d2d47915bb402da02f17031b37b4039a842afb9b7e48f37200605992bd2429427a7a4e" +entropy = ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c +expected_public_key = db0a138c9442fd3a7580e68eec01077d31525465babef901806363a2d664ef8c1908a30491e336e27b0f8690ac71c30adb145805a15fc654ab8982565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a20e224e4361977b71c694a88e5252f608cac97e97dd7c80a5ad10d62681b57162269f7b8d812af039226ce2a7930e43007c0b3ec6a4cdb3897ee85796d051cb053881e1b9706a572ccc75d0ef32f92610c40db4553824f1a352fefd979a310124b9456a9106367ec6a50db6fe0b057fdbb00a46028c0d6a638bb7f2139ca6df68f014c4e1e0b79670869353912b5d67edd4b77c70c067aa76d174cced6c7a901c65737082276188cffe28bcfaa2604447e68d490c0f11cd22b8c351c2d63e7a01ee460bc408e174bc4a6cb023492c6eed42f5d85244ec883b1b49b8e3584f27835f21b6b2e6060e0671f289771d124168e196edacc1aba26cec9e09fe7367f46893c2ea3677caa3005e34e722608a3b64a3b987289952dd695a82de89b9034390355c5e33546eb833f602cb9324c095bb4cf66c05fa0ab98d69bbdcff155c3169f3df2a575901724b678fb080b67f32240ab8f0198cb43176f6ffc93fa602748d591f0b2acb9aa67a8d8b15c27140c320b0ee040e737077a8c9fd6a20dcb865ff51c41808757b0ca750c502a356b1c7d821f1bf804ae2b337819c5ea89542e079045c887ba6550e4f05693f5c7012424d37a17e2294669c0538ce69a1f1c1f121784e3c3537424bbc4d73cf1a685f03a24c4ba8fd603b328d2a07fa2b714dc1eed17693727732ec7be2b02c0614caf3d42b222061ddcd758a0674133e6cfc5362f855b717695acdb971aaf16320690606c1c42238856d757b5d610bd64427f04c97abe1bc6b0185116cbbb2dca28b5d7a9aee205dbd37e92bb36311c8936d958aa1744ca67332a600d8c719377273c7fb0029f27c75817746e1058dd196de71b0e4302682da21b4ec1beca3cbdf690509573959d816cf5fa034ce01d6a4ac477e3bfea75732678aea6c0a5401c623dc225c7a9a7ae6a572f738387181913cc71b9379a5a2bbdc45773c6a1167fe756e13731f47226bc678331312b99428b07b2122b2b9dc86b01c5f090ff632fa83b598863c0b42623549ca831f66bdbbbb1d4747d56a97dcef9c81766a3d90043c1a99ce5e81105e9113043342a539de446a7c5f9c4b46a8cadec388fbb8bca527d90a56c649200cb2a7f968611934014f9a7b6faf3015bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e35771947172118eaa02cd95f7137c93e2159d9389607c3011a76363560a97df950b0329258b0126c7bc10e4081ce46b7c7b0af0752b038386e9afa2d0a7543d85ab909376b618c0a2d33875d264b76941430e81c48832f43270160176ed5938492a06cc08392237caa8487abd3c83019000bb6671784109c7bc4c2a0362a5b5122e620aba511c49ca42d75091b3b1abaad9b8162bc27f182ae310872e789cf05f6c949598c41c3b73a1a9cc0808e68f95c8ad8392f021f77c79618685db2fb1d04a9a8acb8441ccc764aa3b191736f5a24ae31c23428390c1c22c6a6052664db63b94960a433584036c05e031a07823a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b +expected_private_key = 38bbb649e7520a59ac57783e32a5022489365713cce30171ab46ab219b7e81369af44bab6f5badcf613e963938a0829ace625bd8594ed3c0981c5963f68874aa87685599041c4c296b4cc181e57667d499b2f961f44773ca958193e97988d816d702078c0147e41390f503921f139384d75efc91cd08544536b4c9c09bcc2914a807e090d98b5c07c1a4a0c16ff0eab557e5ccc1871ba1a36ff66b1acd113facd6bd16053f22cc85634a3d56e564e30862aa1409d48aaf92643b62009f8e206c2c8bb7f357b9432a8474349c3e1679f1d154cfd4a373665a86c481b9c3163308cf3a1a265a6313d0068ba2181ae5e5a1114995005c8fb574c4a7da80562953348a80bc23cd90c37a2d166ee4e895f2a429aff3c9eeeb869ec9982d367c5809396987a2efe93dfda2cf45e774cc3541bfe655a7280af9b7601fa5183ab62682465fdb273ab435355b84563047bc4c6204aec310d4b91e8b849182c16a57605a6f5690d3804d8857379e11b324977f30b461954a17cb16c4dd93761224a47f4c680373c51de251cb69a2c737cbb1f76d7278033ae86480c7776cc7ca02393f333b6cc00c200ae58922756d3664a30d7b262302672c27a7496746f8f56797726340c734473522fa880819d76a004a480f48b74f7c6ee1998741d39fec12759670b4e8057aedc67950b929e200526ba5a27e0bbb67570bae100b77d525af70b7b6143a7419a35273c14b492e1e42c5b5918a62f3c829a50c1fd8715b030cec454c90c72e6509ab1936ae7490c6b62a6720a840aa714f7b6b0134335c75c44a421598b790631e2ca497e256be08910b69c01997bcd20591d1967ef5ec5c035b0c1f19a01bc0103de6cafda45db70950cf551da2442741eb7233b36396c124c6365a83b66d9cc896ff448f54194fa05267b8154895173075039143dcc58062cbbb1946a917abb184788052920d1428c856bafb3461a463627ec7430671ce75bc2adc95622eb2925a582a15e487787389bcf14dfd84801a37bc39136cc1a49cab7cb924772606d48d3941bccd3221eb418b12a6342ab6c357f273795339bbc720439aa9cd5a478122b8b01769edb013686c8e872a4e2c049a755a8f954614665c61d5d9aec7d67cddb779512a308ba3cffd5c4bc642c091226667c40957c17b3c92bea102143dec663b6155464ac7a9559c533a647c5a106c38972a26beab45c2f04c974c9bb860bca64615b6f0782305c81862abc973d280088bac791876d3172d4e340f26452f60009a49989bec107b680b62cdc12751f9079ed07c28143a405a600a974230b20719b0953da3c2da574ce2c31786c77600646e25b3c305f6507d91084a836366c273d62c526e0630f9b483caf335d6bbb5bcf4adeb4143443a07055349cfb690948487f7795b67dc2e45430e7a5c9564cc84cac0ad0832480aa844417446b9b086a493b7aa163b76a50f35b7384bd054147a8621674843c3040ce06eaec68b6ce8a2c5b42390c76350e10dddb35c9f4c4a1cc148ba08601f92b2fb12c9088922c3463139239a62e878e4db61a3529a8fa7905a7a1aaf90216dab5026469b27d4122af5561bb91d111a721a78587eea259a4c7f6b743574398e30a119db0a138c9442fd3a7580e68eec01077d31525465babef901806363a2d664ef8c1908a30491e336e27b0f8690ac71c30adb145805a15fc654ab8982565eaa96fecb93a2ec7ebb697652965fc5ab837f6b7a20e224e4361977b71c694a88e5252f608cac97e97dd7c80a5ad10d62681b57162269f7b8d812af039226ce2a7930e43007c0b3ec6a4cdb3897ee85796d051cb053881e1b9706a572ccc75d0ef32f92610c40db4553824f1a352fefd979a310124b9456a9106367ec6a50db6fe0b057fdbb00a46028c0d6a638bb7f2139ca6df68f014c4e1e0b79670869353912b5d67edd4b77c70c067aa76d174cced6c7a901c65737082276188cffe28bcfaa2604447e68d490c0f11cd22b8c351c2d63e7a01ee460bc408e174bc4a6cb023492c6eed42f5d85244ec883b1b49b8e3584f27835f21b6b2e6060e0671f289771d124168e196edacc1aba26cec9e09fe7367f46893c2ea3677caa3005e34e722608a3b64a3b987289952dd695a82de89b9034390355c5e33546eb833f602cb9324c095bb4cf66c05fa0ab98d69bbdcff155c3169f3df2a575901724b678fb080b67f32240ab8f0198cb43176f6ffc93fa602748d591f0b2acb9aa67a8d8b15c27140c320b0ee040e737077a8c9fd6a20dcb865ff51c41808757b0ca750c502a356b1c7d821f1bf804ae2b337819c5ea89542e079045c887ba6550e4f05693f5c7012424d37a17e2294669c0538ce69a1f1c1f121784e3c3537424bbc4d73cf1a685f03a24c4ba8fd603b328d2a07fa2b714dc1eed17693727732ec7be2b02c0614caf3d42b222061ddcd758a0674133e6cfc5362f855b717695acdb971aaf16320690606c1c42238856d757b5d610bd64427f04c97abe1bc6b0185116cbbb2dca28b5d7a9aee205dbd37e92bb36311c8936d958aa1744ca67332a600d8c719377273c7fb0029f27c75817746e1058dd196de71b0e4302682da21b4ec1beca3cbdf690509573959d816cf5fa034ce01d6a4ac477e3bfea75732678aea6c0a5401c623dc225c7a9a7ae6a572f738387181913cc71b9379a5a2bbdc45773c6a1167fe756e13731f47226bc678331312b99428b07b2122b2b9dc86b01c5f090ff632fa83b598863c0b42623549ca831f66bdbbbb1d4747d56a97dcef9c81766a3d90043c1a99ce5e81105e9113043342a539de446a7c5f9c4b46a8cadec388fbb8bca527d90a56c649200cb2a7f968611934014f9a7b6faf3015bf6494ef72fba0c7ba40c499357acc96562c65b9ca7c53231045e35771947172118eaa02cd95f7137c93e2159d9389607c3011a76363560a97df950b0329258b0126c7bc10e4081ce46b7c7b0af0752b038386e9afa2d0a7543d85ab909376b618c0a2d33875d264b76941430e81c48832f43270160176ed5938492a06cc08392237caa8487abd3c83019000bb6671784109c7bc4c2a0362a5b5122e620aba511c49ca42d75091b3b1abaad9b8162bc27f182ae310872e789cf05f6c949598c41c3b73a1a9cc0808e68f95c8ad8392f021f77c79618685db2fb1d04a9a8acb8441ccc764aa3b191736f5a24ae31c23428390c1c22c6a6052664db63b94960a433584036c05e031a07823a03ca153015fb2665c77d8fcc529f21afde0d4f32cbfa399f2973d812f516c86b0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c + +comment = Official test vector 75, seed: "8e2995f1b3e43853b18916bb1212aceb05898e2b177a87abeb928ad7184e59695c56b2cccf5db80853c28a525e327d13" +entropy = 6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 +expected_public_key = 35a0c8ea287462d8cf8841cdc9016796500e61e89eff672e87c667f453c8ccd148b94c9a9a3765649ccc6e1c05e5350218d091783b6c7e4958a0807e73e9839992c8c36a87891b7ce5d7122e38b5cdd745feb1058fc2827b882df77cb564323746855392247b054527ee862abc91a557c431e55b81d23b1c1a94992ef540e07338fa944d24b17ed4e693eeb8224a0c5307202457c8033aa4651b2b30f85a9bd8070d1b11675fe240a1009dacfab21d50036426a6dc9c3dfc05cd1612ba91da51bd5a0f7ef9b235f1b3b2641747ab8a380b42c060357bf259548cb80788cb41da4c7d3c4b9401925588920df255167240f6b092c1329799f0039b74cbd549b2c053a71d4641071a3a95a460b2b3a8ada727193267de555e6ce87986ac06e647c4b7967cdbe5083c4b99a1b44b5df58959c48beaba0818608fd4046ea0c09a28416c6a97a1066c0650ca619d14a056252d38539f1c2676b69cc53502487389648fe596783baad0d7627cc6ab2da5b6788410b67285841a323e04d037f25e103b38b07672248186c969b04661ac6b2753c5429eeda389599b78e84608dea89556a9510627b29e13b1713a1442158561db8f435bbd6234a420618985dc4f71f0a5f15762fa16084f178e0e76bfc9ec5c35fb52e52301e6809cbb287d42b7591828afe605cfcc93c337bab78b55237b075a8bf08c48c15087e82600655234fa99f6987da7904ef50a1599867d56760ae1d70006925ade67157508289f137def9b9714f4cb72a017ee6a6325f9418f3a0ea3a8762c55987ab406dd9a6d248a33eaf264774aaff6f00607f37bc20041d3a170e07407792a43c5407fb3622ccb065b74bc1a54f86af9f7246d288fee725a6fd85e82477483f778d5388728c4565467a9ba3216d92089bc1c742a20b03bb526b73573cdc91aa8e085f1eccd1866280e791bd1e43d4843a440e050e2967daae26686cc2d32f512332cac82095ab0005133023e75c9c92b0388bc8b2822a82f93fc3520972e2e0a062a388931092bfa8758f251895c641186d1b40f6a332df3088bb24381da133ce40d3461a7d87a93e702472e49ad91cc013c936b02a96c4ce14c2b23ac79869c6d139c8d85b58da27c6eb4c4250bc3ddaa56dbbbbffaf452c09074e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779db92453f7aaa4e58401cbc6f3718a3352013e1383b4222572118878c99289b91b02d929dba06c6deb6f4c2b0459f86d04fc8d287b6a676b17e45997027568bf7bcca05c3d394c1557873711174242ca50cfa30bb3d715d1400807cc5ff1049ce720be3c360febccb61dd7244f4352b655a517485ab13b413983cc089749ac7144312966b2c67ad50096bc176142858881f09e3a075f8fa6bf638a13af572ba026a172b23317a01a999c8c1ef478422cbfa9802f98f2856bd6a11f8584c532807771c19c411a2900c5a57c9b8e44b4c07b3be3477baa738ab2c407653a309d7a82cfc6b86a1b59ad1251e008598e453e04e3306c1877dc703869da25a9b91fec80aaf4f30b4d0a83e2daaac73990f05a9002d6ada0409450454291e37112a9ad97147cc89999dc89a30c809757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa +expected_private_key = af361347809757c2ae0c4a60393c90222c394cf136e95517552721ff136dcc234d64715a1ab43d15708187f89a6830791e0062cd43253ee486ac54179d320fa6a8bac4d0c07b7158a1eccfe52c4847403849982d73288877d04eaad37d392aa487597f80f19af7444e5a82cfbe51609ae515c1b320b6c75aefc121d5e2904a0185654a418e5c7a379b41838ace149b45c5a4040dd239ada846102a6bbc811ebed4710b2393ecc4bb8c6254dc815d2667831f962887a74eb883a5a8642e0b427450d01321246a8797b7be1211eaf64b0c706eedfa17cba2b010626112ab6b2b2b928df38ccbd9b639b9c6ad090e92da98b5c9914549beb6a9b5505579a56943d210722bf590d63c1ed56534a96552005226c34cc1ac32572d2ac0823bce348086096525188088df229536bac34a1c95083309a0971f31d975de0598e4e009d24661b2a79dfae85343b94fb1bc171493ad77d767e0814837348616205652eb4f98838ce536691de8c3af0a4970eb0c3600b4605841bcb0884e08bca3198b04b2afa6f575229c56462b9516026d32d2ce33a4b1add3b411371ea6516765f457613ccb50f94ab9395f6fbc94395a6c9c104ce3b79171a83a49b22add3a915086b804c3b42301bc1f14630ee3217f059aef485c019a4248b4a78a516d75919eb2b15bb1e5a34cb6b470ca7a797ba1b5193cb4565497f98bfe30a7578044867897c332687d925c8bab05d0c35693f557f541b571d6ab7e4a752b80267b0329d7558fe4bbc54c8612aa95c03f81641a129b1793160dba78c4e0269e9361087328a73c67c0044217a25c2e05b64a1b8ebec972606bc220b1a456d8ba86a76ac4a3c06429cfb6035ea50549db887a5f6170ea282bcc295a2ef000f571038fa97b6bd98fe0399ece3755d4b55e16261f7fab678c394c83676cb9f080bcc915c8b1c67dc998d7097074249585e31c5b30bd0250abc570531db43f546c2e05983a7b5219127809987343cf722fc38525b2ecaad2ca703679cbb7500420f83960d7505bb7b7b59a8b6f0c876c7a53d893a10468a516fa7a6a08c04d3259ad003db768559e173df06a08793b10e5a1a46145b6f0fbb230ca504424b4e9617cb3f509993567b4cb94cb2cb39811bc1eab31b5f5691ff4108e5a6eaa9b15dc2aa45fc4ad26b9ca007a7c2a680acefa88f12790abec7e3da1c13a355c1c669117070a7e1976f6859921e273f53632b4144b58e0a74207100d2cade0c8a0410814d40a4234843a44978d0d4a173be52434760423235f5d7c8e1f56c8181487bba930cc9272acd524eb6c9d71d753fe62b0e9ba33a478b7e82b36d9690607550aca261085a08725281b02e531432b35398b7ed1355b8172776926bfe41880df90af6951a58981c708724deba6b6c2bb8af1c0009c71a0b82ac0d14cb0910a8ec3988251dc9e93f17e067608115c85bb6c47d33a2a9359a35beb47c3a04ab65537f59bc1ebacbed4b97855f753a954929b6449a4db7d2098cdfc04008873004bc535bd5c74dd49247419601513c4e8125731307bc858845896a67d33902afa4b58b50be969b947851bbd791d66887cc6e92e19a2b92ba6bcc2825c4239ab2894b2467547ff3a63bef65e35a0c8ea287462d8cf8841cdc9016796500e61e89eff672e87c667f453c8ccd148b94c9a9a3765649ccc6e1c05e5350218d091783b6c7e4958a0807e73e9839992c8c36a87891b7ce5d7122e38b5cdd745feb1058fc2827b882df77cb564323746855392247b054527ee862abc91a557c431e55b81d23b1c1a94992ef540e07338fa944d24b17ed4e693eeb8224a0c5307202457c8033aa4651b2b30f85a9bd8070d1b11675fe240a1009dacfab21d50036426a6dc9c3dfc05cd1612ba91da51bd5a0f7ef9b235f1b3b2641747ab8a380b42c060357bf259548cb80788cb41da4c7d3c4b9401925588920df255167240f6b092c1329799f0039b74cbd549b2c053a71d4641071a3a95a460b2b3a8ada727193267de555e6ce87986ac06e647c4b7967cdbe5083c4b99a1b44b5df58959c48beaba0818608fd4046ea0c09a28416c6a97a1066c0650ca619d14a056252d38539f1c2676b69cc53502487389648fe596783baad0d7627cc6ab2da5b6788410b67285841a323e04d037f25e103b38b07672248186c969b04661ac6b2753c5429eeda389599b78e84608dea89556a9510627b29e13b1713a1442158561db8f435bbd6234a420618985dc4f71f0a5f15762fa16084f178e0e76bfc9ec5c35fb52e52301e6809cbb287d42b7591828afe605cfcc93c337bab78b55237b075a8bf08c48c15087e82600655234fa99f6987da7904ef50a1599867d56760ae1d70006925ade67157508289f137def9b9714f4cb72a017ee6a6325f9418f3a0ea3a8762c55987ab406dd9a6d248a33eaf264774aaff6f00607f37bc20041d3a170e07407792a43c5407fb3622ccb065b74bc1a54f86af9f7246d288fee725a6fd85e82477483f778d5388728c4565467a9ba3216d92089bc1c742a20b03bb526b73573cdc91aa8e085f1eccd1866280e791bd1e43d4843a440e050e2967daae26686cc2d32f512332cac82095ab0005133023e75c9c92b0388bc8b2822a82f93fc3520972e2e0a062a388931092bfa8758f251895c641186d1b40f6a332df3088bb24381da133ce40d3461a7d87a93e702472e49ad91cc013c936b02a96c4ce14c2b23ac79869c6d139c8d85b58da27c6eb4c4250bc3ddaa56dbbbbffaf452c09074e013a3c7599cd5b8a876076523c6b0aefc6a503bcee0fa76407b779db92453f7aaa4e58401cbc6f3718a3352013e1383b4222572118878c99289b91b02d929dba06c6deb6f4c2b0459f86d04fc8d287b6a676b17e45997027568bf7bcca05c3d394c1557873711174242ca50cfa30bb3d715d1400807cc5ff1049ce720be3c360febccb61dd7244f4352b655a517485ab13b413983cc089749ac7144312966b2c67ad50096bc176142858881f09e3a075f8fa6bf638a13af572ba026a172b23317a01a999c8c1ef478422cbfa9802f98f2856bd6a11f8584c532807771c19c411a2900c5a57c9b8e44b4c07b3be3477baa738ab2c407653a309d7a82cfc6b86a1b59ad1251e008598e453e04e3306c1877dc703869da25a9b91fec80aaf4f30b4d0a83e2daaac73990f05a9002d6ada0409450454291e37112a9ad97147cc89999dc89a30c809757933c5d0356f329bfa3823d34197b7d9e60e307bbabd9b3e8272a0ef1b3333269a7af6a5bb8740bfa12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee63859f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110 + +comment = Official test vector 76, seed: "9218943c51fd2de47e509aac67eff176795102f37d7a2017e3afd768fcda7877af38739b00fcdf227c2fd62eb635942c" +entropy = acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 +expected_public_key = e4749bcd8577d50a102352b869402efde59f5fb54bbee919e7d4a8bb8cc40fb8c7240401113152ba727cecfc8e4b817c5d537df050902bd03df866317006a2aef59cac269813a47fd337a0c5b694f4b080f100089255614634a2b0bb1ecbcc3f1d84cdfb3054fa749736e531c2e673716079cf45c89b444b7d821d892c7ec39a74d39b815c2b9981ca47f5e56840341ff9d23fc877285f9b90fc78bea1b9c5c647ac52d066ad7b8ca2aa01e0729fa22c39d9c3c6cd833c6aac061aab1c1ee6819d2a245997b8580a9e1630112cc6b62c4952215a3281111675f25a10ca0c32bc68c7bc920bfbc7bcd82edfe130b0434afa29b2b9d90ac3f1143b5664e5e51984b52d976439794507d92cb256a1520078972b843ff3dbc6736602f68b289e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a45a1a62e0b749ee14a38e11a094bae60a38c84079d81aa655782138671a0fa186a727457d351a8a45b6fe05369f7b158de844e31117ddc47af9fe52075c6acd5f93a31c38ec7f608ff9096c8562e0271a35fa7265a56b24bf31c6a727376d1ab3f600573342e60884f41d355b2336e464b94554b7c108614c3394fbd561a2e74ba7045c0d74032877901e4f8a95c41ce9fc72013c51fa93b5c0b3c3b0a8c90ce0960f510a9f6a453b8b0012f7c2430350b8a4b6143ab5adc7aaa6f3533e230c3062b7caa33b1e9a3bfda7bbffef8341ad0a33ab272bada717a4790f4c99cf430bf114b62854810eab7af582a2ea327a599c490e25795cc5c42219771391b33df4c7fc01524c4c520eb4559c2ea8c38ab5cfe27035c756248662c1e969ef478a2d2419ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2941b89b803ed1c7d8de65f64a29d8e7bc2020b723d391987f83db0bc35e96aae7b2772b37159a3257ead277532119cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352cba074bc4714deb09f9cd81624d2782de91efbc30882c45631e96e35c9b53f77cc0d268722ba5eb858a1de719a88ec240da229cd7766b9a237641c1277c006a6672bf61ab5dab4c223b7381fd3c16704cf7920b2f11210c969b6b46a152b72598de4aac1665d72a45bf51370de61559f83081dcb6aa49339e489968c80498550afc467c8aaf0c6c1b9085699b801c75eacc3142be38de6f6a64ad6708c426eacc13b09d8bea819bdc200258d31a8d1f308d0a7470dd35161379191576a03b81d70ec58565ca7c4a6bb333338d8113d70f5bef45b6835917e17c2945a06cbb7f2225675252f351593b06a6db504b6e67c6e88763fb06879187c5053029724b3477281cc5c5294b36b64f12a08084eea098489d5cad338a0cfa61231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b130a103c6244a17870b75023e0014e6d8433ae5cd2b145bfe253a8bba300b6465fce277e2fabe36d6c8112887cb0a6daea4a54e258cf89071e407594de1bf1f4aa2beb50263dc5d5fc729b632957375b5ce6373d9b93211a66a29736a6ed616ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a1f4022e6c3bb3d2294c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f1 +expected_private_key = 31cb44a14c3ff840758055bf2afabad14a723c048d4d20c5908bb781844d574a96a0807c59d5192548a0089396a78b953aa52677b9a111cb012954b674571c5d0c7c5e6488d498290f7665f4f32dba7228ade2a724413798ec32619901215663b2c26360612558070bd06261bbab86b4f96056a498bf37b1b84238c5099ec8f1af4251c0862b861f334eee85af8d364a54f6bad0e44a23a0577933ca8482889a955086ea3a2c94b057c1c20d540cd6d2976126854ac123cd386a855caa385927318825494861079ac84606ac0f1810eb78a8398740be69cfa1777c61a5cc1d758ae28c072d6087c379a567648558ac8a1883734c64361db33cdd156fd371a2abe534b162c6e336143b944dc2309aac106525d6586793a2b3420358185fc787c2cee3875e3425be5627c1d49313413ee498b17e8c295908b718b3c4a6e03024d77f1ec37eaeb7462e09c683cb9b272431ef0abbd0422ae2569fc37902ab90bd2c236f4da66d78301a61765a77e43ace81102c7355749c1463b55f10e26727086d73a1800924c6b0eab6ec905d5b01adc538c9eec7a25989b85f24b1f68b9a22637613e9acf609a67cb20b38bab1a8d81cbd22a5ea8c7587a13bf8eb8a37e5949084c26b4433741a31c502a4c412535fc6a1c5000057c65103027f78f81ddfc4a8843c59f8563bebda15da543be2146a3eb7b521700958bb2a5064923236193d981bd1e2920d00b1cfc504e32495dbb116c5bb7aa21b6cec5c9fc0b1ab73330544e7af5bb1ceb7c159e3509938d0332cf51add245606617dcec688f117bfedc27dc5b8b4884446861b592b720b53fb23cf08513f66c3b51833e51b9a63e297054a8c03f8baa257c64c2c8a265a8a92052c41146bdb3a32ce0b7196aa33564806dac33ac05a20178c2a0cb04000d484f0325c9d16956da0af88f68bb72b7bc6b122a486cc1eb01bd3027aa316c6d7c1ae7d8b9a747443c5d7237989a93ed939d905832e76afae4172d5f70589e54f7b5cbabb536e5f316b3d38911513b400ad83f7b2a3c72a6c09ea3b4f68129ed285fb99442fe61237d61756a2ad78b7790ee69748b79e42ebbbd6b9b0d803a3eb77477609ab2cea5920128356c369878855126c22f1ab66a3a4c202892c8863b609f7926175cf1e3967ea93b7ade7a8e6779672023dd5d81bd4d9345af36a38db17e96b8d85b7c0beb586aefc9fd9ebc585f071c1b9c34fa2283a60884a0cc5ea210887aa677d24192db582f05117fa189c868a3cffe8b2fb584686eb3d009733e1d86c07d6a9893c7e9410b4ca99a4a880b48053878a45340d0056031068a63113be4b51a630016875541e099935ea92b2668ae84c5a183cbbfed619691038973cc07b72adb803cbe26986c827ac75428cf183cd5fe7c9c719378438058f470b62fa977dd658f219983f97b517bb1aed01a478a18dbb89ac1b916419a3b25f388c276c190b866356ec84c33b29022286c08a34d26948c59341a789cfa168adc0c7a73db36a72ec6c2c688c06aa3eb1fbb25b7b828cc3719c7b2473719f4e2b5c4ab8a4fc172a132439e0e3af22a1beae17ba4cf39a155925c62a4c9ca76436496646906630b9349a335a4852c01b018f77da15e4749bcd8577d50a102352b869402efde59f5fb54bbee919e7d4a8bb8cc40fb8c7240401113152ba727cecfc8e4b817c5d537df050902bd03df866317006a2aef59cac269813a47fd337a0c5b694f4b080f100089255614634a2b0bb1ecbcc3f1d84cdfb3054fa749736e531c2e673716079cf45c89b444b7d821d892c7ec39a74d39b815c2b9981ca47f5e56840341ff9d23fc877285f9b90fc78bea1b9c5c647ac52d066ad7b8ca2aa01e0729fa22c39d9c3c6cd833c6aac061aab1c1ee6819d2a245997b8580a9e1630112cc6b62c4952215a3281111675f25a10ca0c32bc68c7bc920bfbc7bcd82edfe130b0434afa29b2b9d90ac3f1143b5664e5e51984b52d976439794507d92cb256a1520078972b843ff3dbc6736602f68b289e0850ee845e49586c889ccdc104cbf13470f6f6c0e6766007e5c3a1348166933a45a1a62e0b749ee14a38e11a094bae60a38c84079d81aa655782138671a0fa186a727457d351a8a45b6fe05369f7b158de844e31117ddc47af9fe52075c6acd5f93a31c38ec7f608ff9096c8562e0271a35fa7265a56b24bf31c6a727376d1ab3f600573342e60884f41d355b2336e464b94554b7c108614c3394fbd561a2e74ba7045c0d74032877901e4f8a95c41ce9fc72013c51fa93b5c0b3c3b0a8c90ce0960f510a9f6a453b8b0012f7c2430350b8a4b6143ab5adc7aaa6f3533e230c3062b7caa33b1e9a3bfda7bbffef8341ad0a33ab272bada717a4790f4c99cf430bf114b62854810eab7af582a2ea327a599c490e25795cc5c42219771391b33df4c7fc01524c4c520eb4559c2ea8c38ab5cfe27035c756248662c1e969ef478a2d2419ed9da7125ec32b0557edb5b77e0dab221544e5f7a57a2941b89b803ed1c7d8de65f64a29d8e7bc2020b723d391987f83db0bc35e96aae7b2772b37159a3257ead277532119cf55959fbec482169c5391a9409877c79255cbd1c8d2b8352cba074bc4714deb09f9cd81624d2782de91efbc30882c45631e96e35c9b53f77cc0d268722ba5eb858a1de719a88ec240da229cd7766b9a237641c1277c006a6672bf61ab5dab4c223b7381fd3c16704cf7920b2f11210c969b6b46a152b72598de4aac1665d72a45bf51370de61559f83081dcb6aa49339e489968c80498550afc467c8aaf0c6c1b9085699b801c75eacc3142be38de6f6a64ad6708c426eacc13b09d8bea819bdc200258d31a8d1f308d0a7470dd35161379191576a03b81d70ec58565ca7c4a6bb333338d8113d70f5bef45b6835917e17c2945a06cbb7f2225675252f351593b06a6db504b6e67c6e88763fb06879187c5053029724b3477281cc5c5294b36b64f12a08084eea098489d5cad338a0cfa61231268bb866c2c524c71bd6a467c845ac7a4eac579049734970859a2ea753c6b93ef01532b130a103c6244a17870b75023e0014e6d8433ae5cd2b145bfe253a8bba300b6465fce277e2fabe36d6c8112887cb0a6daea4a54e258cf89071e407594de1bf1f4aa2beb50263dc5d5fc729b632957375b5ce6373d9b93211a66a29736a6ed616ef8538e95c45bf595b2eb743d79436d6385bab74c80d88c1a1f4022e6c3bb3d2294c474c2c554f3be4d7fae86455763b97ec8fdbe9640219b35fc36033966a3525d485f12fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7 + +comment = Official test vector 77, seed: "542e20078add5296050af150360f057f6b9ab3ba835589dd56987de805f900b906505b5390a0d86cba28038992dfc59a" +entropy = 241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d +expected_public_key = e26411e0cb6648d36c6236468793848aa4b7f4510377e0a24bdccb712bc98cb21ceabc08101328d3d032cfe9c82d21372924c69ab5a402e9b3d88c87e9bc5c90335e5ac231a1b87ea3c2527b82445d7c8596b10a609616e4da431c9593b91a1aa21a2e436a359a7a5901902a6b516d562363bf95890501af4c5946626ace3f276af8966709cbb9b666b9842102f3077978e4872307ac65ea11002cbe4dd0bb83677419b89c9e0c9847fa6441c86b8b601663e40357831d1b3c21b4a8985ed50e546c2917f332d4acb59bd64d9be88efb981362458b8d868da7ec516ea9c807a29c5d51385781302072c1f3295da2559003d4265cb330f43ac5b774562c182be83636fa034bdbc3cb25ab6c8c21c69b873329321533a788287a40c1659f457c5e6e15456da54a7fdb18c8ba246447606f2aa340a48b4fc667d7e67efec47910e05c3da4463b75359668821711530835357b6a8ec62a3e7817c508c79754063f7110362be73416a46533341cde577c17a75b3316ac59575eb1a1575ec0104ee77f70941e91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797ef827f0bb0821ea69bd9c43abf2181d0775fb64b8694c74f0323600fd3e5f1bc5cbdacdb2329928247e4759747c02cdd924cf1c93bae5c37be8c3b9c7e09b4660c3b9901ee33b62350a695d799b52743d5158c015cc609e891c87f9ba02616ed2d3a1c14aabef101b4b42ad5c47916481bef01b11b9496819ab76a428c0f5b8a69ebb24fb5b3407e1c22e2020341575c7098e63379406c9b60b6a1733c171682b1776719db5acbd2ac6ac4b97aa0a3c8c168a5ab389010a01b4dd01829ee4a402e54e633a229a94cf96e01f72ec4054c13335b89bd6e91e965bc324924c028b433074c9705ac4ca2682fb1b385f058d574515319397754cac9f68cb70022882a24242d1c3f1242cabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a5849211d831abc2c86834be35bc3500cc44522bf9aca86988aaf580bf45a5ff7f8192e110e163356b8a52486f772204bbbbc19befc631433f081e8556579d288b3b27c1a8209ecfbaa30a82b34eb722fe2be60534e2f625c0ae477826a9e75b7c5aed2398525358bf0ad127c15915133a32a9add47a72270a98f942807fc59f2420e14365a758c534f289160a65cfb34619c7c9b2992083cc699f554bd64586dcf379605581711d607235c944820cc28416ac761498d8b54193a8cac8b815d7b19a21b02a6d5a737c4984f3a888c0b9e3f51b95ed9430327642a082787132e94d6c26b298b77554e7f2237ac286f419266580697fc9316ec1176c4d763b194c52d79b25604974c1bc899560b72094701709797c5183391a268853b9ff3aa277c707906be0b078fd6619050e14b48bc73f877bee69a3ebdabbb8b2198cf51b14b2cc9abe673caa803b419be1c34b6341c2e83d2013152b557a87ac4fb55c5c86ccbba995492cf960479b044b3d6233317677c78a453d4e247ecdab3fb200c3d2a0564c4100a995c4f70597e498cf0897b507ab35e4587e2b875030303dc2ca8ceb41ae2a9725085c12040c8d0cb20ace46f1936725bcabd60d0b880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb9 +expected_private_key = de9a3f4dc6a54e98c850e3af0f7abc5cb5b363bc668f2c10c6e197927c89e57088c4960c46b767e27129fe78c7cae38717e6a2a7fc16dbc1582ac697e8915c90281a0a784c4b75345a13161bc6a586166d4385b507748d3b9516b10550f05782125c10f3761aea2c631afa83870c003950b891d96ae721317b192f21a50f2b2caf49f81177790c29c02216759b005692ccab4281927a46739ff7a9583e9a5eb9a62314e4967f5bb375fb627e5a45b918c801b4b1dac24d55c13aa7fc5cfc104647295650b5cadcac2c74aaac28b82233f64c1c01ab50f16213154d0312c5add25af449cfddf494045000a01c449d1084c876163c83c13321b1f6f87757dc186d4c30ce916240e538f196936ab9bb419093fd593409f3a308827ad9002e5a621fb1387ac06b442970cda9c720ac9049cff1c307806e9ff9209fd0cc52b9517c685c36c45801875dbce490163c91c707755cc8701af04deb9aa0ce460f24c72e5d811c4ecc297abcc4c9ba304c75812196409c19be10c494a8b138a6f05fb5558e7f2cbf6f1694e7d417f73781205b941eaa3ecdf91c71e998f9a8b6b72400a048a77ce4ad17eb265313303cc86150d477e42a39cb4b8c5a3723d03550f4b76d5fb7b524ec2658d374a8c955b0fb3fe878072ebc0201b2328b737f9f19bca8411f35980890d71e7bd9707c917545aa6a659c3c70877134bbb0a1e970e7035021168c4a493ce1c9950456a76cdc05fef147fdd625d2b4bc51b39f3b9bc73a35a06a7485306457544b88c168b22e81cbe9bb0174a2b526b6ba0641456a3cc941569124557d3bc652dc8259ac66552db0ae06cbaedd091c268c2c6f4bc7e948329778cf48c3b37f9a3ed714c5c8e0099036514d9a052631b256fb7e7f7c91ea0311b8db8721d5001ae90991111c5873499bba20a9d08a135abeaa544706dabf7338497c578084e1bdce9155f87417b29313dd39505cc90c45c12c324b5d5af01eb2656d58607724725485465e33a6a64da220421c038f0a625254ad127ac941eb23362649d2049f8ae8c057321aeeaa31e0e98fe3da74d53938f4f900b6a33f1305a383cc12b35894ad498293957950010cf7912174373967c294bb89a90331c828048e3fa862fadc95283025e2f66dca10104be8b9f286c198b8c9f0f24c79a454e8dc0742283cbba84b95b388d8f6912f4b74198aa52ab561ce59508ca6cc09251fa2780ec0da59d8b12b17179320d23b822a3395466dac34384a364d06882592734f72ab0d2dd7131196afd4da54fc5801d85928cf61bb257274c98479ee0c2f65fb985f6c669d948fac153158530849311f0bc51ae72bb8c23ab5fed55e793a4e8489b423044a1b017273a4be35a305e19934b99b45dd2734ad4cb4c5b368c7a32650f306b7148c199a44bcc3a297429cca6015e906204c827cff8c9dcd48bf1b638091f732dfdc570ce6618dfc839b4a4648a52bb8302e32098c26e9a51a6571c9c290005265b6359f07598b10c7674f5356b0365ceacbb55b1a1822811c92c44f0e4bbda4a13364749c5384ca7670acce69bc48b6a0b0b2bae8ac5cc40aca6ce24957167cc0f24dd0caa3a0228c13934fbbb0c205f53d713aa441f5b0feb01fe26411e0cb6648d36c6236468793848aa4b7f4510377e0a24bdccb712bc98cb21ceabc08101328d3d032cfe9c82d21372924c69ab5a402e9b3d88c87e9bc5c90335e5ac231a1b87ea3c2527b82445d7c8596b10a609616e4da431c9593b91a1aa21a2e436a359a7a5901902a6b516d562363bf95890501af4c5946626ace3f276af8966709cbb9b666b9842102f3077978e4872307ac65ea11002cbe4dd0bb83677419b89c9e0c9847fa6441c86b8b601663e40357831d1b3c21b4a8985ed50e546c2917f332d4acb59bd64d9be88efb981362458b8d868da7ec516ea9c807a29c5d51385781302072c1f3295da2559003d4265cb330f43ac5b774562c182be83636fa034bdbc3cb25ab6c8c21c69b873329321533a788287a40c1659f457c5e6e15456da54a7fdb18c8ba246447606f2aa340a48b4fc667d7e67efec47910e05c3da4463b75359668821711530835357b6a8ec62a3e7817c508c79754063f7110362be73416a46533341cde577c17a75b3316ac59575eb1a1575ec0104ee77f70941e91786ad457832e1493466a3faaa55911e9bacef8ce49f579f1753b5138797ef827f0bb0821ea69bd9c43abf2181d0775fb64b8694c74f0323600fd3e5f1bc5cbdacdb2329928247e4759747c02cdd924cf1c93bae5c37be8c3b9c7e09b4660c3b9901ee33b62350a695d799b52743d5158c015cc609e891c87f9ba02616ed2d3a1c14aabef101b4b42ad5c47916481bef01b11b9496819ab76a428c0f5b8a69ebb24fb5b3407e1c22e2020341575c7098e63379406c9b60b6a1733c171682b1776719db5acbd2ac6ac4b97aa0a3c8c168a5ab389010a01b4dd01829ee4a402e54e633a229a94cf96e01f72ec4054c13335b89bd6e91e965bc324924c028b433074c9705ac4ca2682fb1b385f058d574515319397754cac9f68cb70022882a24242d1c3f1242cabdaa4d68a91ddc8a22c939bdf1539645a912a33c1d11a5849211d831abc2c86834be35bc3500cc44522bf9aca86988aaf580bf45a5ff7f8192e110e163356b8a52486f772204bbbbc19befc631433f081e8556579d288b3b27c1a8209ecfbaa30a82b34eb722fe2be60534e2f625c0ae477826a9e75b7c5aed2398525358bf0ad127c15915133a32a9add47a72270a98f942807fc59f2420e14365a758c534f289160a65cfb34619c7c9b2992083cc699f554bd64586dcf379605581711d607235c944820cc28416ac761498d8b54193a8cac8b815d7b19a21b02a6d5a737c4984f3a888c0b9e3f51b95ed9430327642a082787132e94d6c26b298b77554e7f2237ac286f419266580697fc9316ec1176c4d763b194c52d79b25604974c1bc899560b72094701709797c5183391a268853b9ff3aa277c707906be0b078fd6619050e14b48bc73f877bee69a3ebdabbb8b2198cf51b14b2cc9abe673caa803b419be1c34b6341c2e83d2013152b557a87ac4fb55c5c86ccbba995492cf960479b044b3d6233317677c78a453d4e247ecdab3fb200c3d2a0564c4100a995c4f70597e498cf0897b507ab35e4587e2b875030303dc2ca8ceb41ae2a9725085c12040c8d0cb20ace46f1936725bcabd60d0b880f7aabc887090195d95fb6ec060b5257ac37481faa2eccaef99c0da37285d53baeb0e25bdb93eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d + +comment = Official test vector 78, seed: "6a85a61dd08c0733fcbc158abb49fe0b0d96a50dcca140a2e9f5a254f1901985844613b1c656c0cb0112620591b88ad0" +entropy = b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 +expected_public_key = fb262aa9a031e49084a6127b8410a5a46cbcabe6b18f607c97d4af6c6a598a089bb40c1998d16cd307895035b15df2c34bfc05f634813eec780c96b83fab557075cde3b64eae6ba98b65106e729b81d11c926404e99164bac5b546997d2a842f6aa9ce1f6bb7ab7551a06a3649e1caf7872ac675cb8981a124ca05a318bff9a234853821a3036a86404b0f056491a5b20ae09dedb123df8b4e9eb612a00207c6ccbc580373b0921fe2831f50610340865232c60660655184d8a0867a47811b88bcdc4e6dec5874839919188f63740588ba97405bb1ff2925c1553188c0137336948f7809dbb96d2f910a9c0aa95d49267e543057976e3dc7346cdc7560e68911b8829d37bd0eb20dd5e2b0eb1538a98a76a68798b5469f9dca82a08648a2da13bdc1a9b52a7b6f345626bb691aeccd14ec20f1c252b4fb2595474b2dea0edda47b87cb51f020072d489a2e79cfcf9a12b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a029e1ca5cea27d729065d7137bb518c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee590d1ad93852885db721b85d4061dca1327179acdbfc329416b23234572901b3f63a2cda36aa65b17035f449af2b404691957c30028f053989c501d8c2cf8a8cc0c04aa59f3b19a98777f814a18a0753a7180264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657256015f68a8c887c23205a6655f30c51084925167bb75c98b8a25b7579bdf40a912365164814794bdb0b78824fe9066cc63473496ab9cea06248d883d1846fc8084d59f05277aa3eec0c3186d68bdceb6c240cd0128a6bc1361467b861ab025309c82183233c37b35e8af1b464331cbe7cc3974a48a8e015a491677567472f263e31188966eb556151819cf52772053936abb0d0a48e99357e558301dc8157a8a7853212828269786919a8f9032e17f9b692ba8efaebb602e83bd4b75160541500779d1907b1159170dea870e6f57f5229222e85b178dab32f897bf45510ead084887566942656357b7896570756ab1614994f982841a525c8ec63ccc8e4575df03be2f5cf96505ade252fa4e80fcff664f6fa8c337980251904a9135abcc509db15a49fe4c6d57b41bb6383b3483ca5f5ce11641f9eaa423c0c3254a508d4319dfe72168070cc8c771ed3e06ce74c93240947a8dab87d889f9ad894f37243b25259153324e103b73c708371400ebf007bb5459ee084be938a18d055af7cc7aa98fbb88a156849765936e7273bc385a1bca94a74368168cf26d8806c7901eee2359c8694b5439f1e82c0a6892e4a68c4858a9a00b1496e177d1efb57eb9c0ae382b56626595673230903cc19c79714364cc4b10891823535e21cbcd45c90d471e684af1fe243e925c848565a1989637f7614c900af1bea9049b78e07f00950ac800ef72860e209c192a4aa0b901090987bf15a2db6165516ad0238a40b0bb233a365bbf2bab2f60eeb8a54771a8d8e5279e2740298563aa2868e2df1be582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc3659c03d37240bff084d77f09dee76b60952221ed2c1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10 +expected_private_key = c65b5692b9737bd5bcef94376a685fe08cb59c2b94884b47bb6a4b292c4ef8dbcfd1d9392ba3c464442cbe0879fac60cb733496ffa7116011cada07377eac759172db45c9035532a5a48c18f3343e7fb3a0a7a1da9c75f647648a822bb8fcc59a2e0476fe958cdf968433b46ea296056a8460edc0b7d4430252b227cc38c8dfa639a72759de9325d3bbbdb1a5305e546580127b11332bb666236924ff1f13105176b81a777ebc946bd4b962e8050c0f80be026a513f7c9c74308f8336a9bc73bcabc8353aa10afb69aa502b3b6e9a53ac67f8cd8784be4519ab3c6e8e47212bb59ec3958be442bf2162dda987c602030770555c0bc62b1422367b95a91399642155cd0b17dbb848b642c765fda2400358040d4cd154a68db36265bb525fc90988fd0c04bf0b66ce052bb216d6183b444cc385bb8ae17388d5e8024aa41563653b5f72899cc16b37d642f6ff7385f557c941571a1c73bd9425fef3c343ed9b88bd02a9be5652736ae69949e43b5c9719c4b8e42c9071c10e3d454b3c90d315c93579cb106a3b16bab7163983f5c514b818516bba802b7fb1166679ee03c4c41ebcffc6322db61a7988927dd83b48c24bfe82a4fb1901f70e2c39c411fa65c43d56c02c79849e7745bee15b70e405939b055c2a76fe1021e094b4671a290f5d708ebf0b1155b94fee9b34cd9858d3a8dd4bc27f5fc0627f2a80d6681c11324ecb74639540b72a23083c3758cb29ad40c979b42679e1436fc56b3a7d1115137015e2a2af9a8bef038b6905c8847c16558ba2bc6ea92ad90b026228695d664720c15e6708b0934064760a745ea4a5587ba211312c7203005f838a2d5b7bb09b8dc7aa39d4956d494472f71a268991ca907aacf8048fc98c095798d0ea043c42c437f6762ed3678b6d701560016f405cad66117c786b56b3a88fb5968c26869f73a2227b129553b220f67cae75b5433b29259553ab4375a0aa6766b2aa0ad480b6969201ed21ccda0a39f8b8f565112565065d8d26dbc1a57425a29fe0a606ba826ffe45a69493b08b11712e88a2b4b0371db5c0ec0125e2659ed08275d18277b9c0ca51797d46cafe91951737868483a418427733ee2637b4aa9496c30fecab67b0b7278a76da2da201874711e6928b7a40e7859378c867b9ba81529656200584ea9a5881b657b68980ef8cb201338ac1b856c4ec5b0c48a80bcd6676c0ca624f05296e59155d5587c2c20bfa1bef1005bbe9840db205d9658935a67614595bb3fe48e52877fc5ba639d023f54d534c58cb90a0a98bd1c2e9e940fdc61193d4753d17463d7eb8c9c6575e0f6845b5c0a5bc69c5f90128d3078960671394b75c5c72eaffc1e8ef4afdb395ffd40a2f6bc75fb9b79e1d8756705b710b0bac1dbb4ac312fff30745590739c08bb25cc9ec62caf1226176c161ece62aedec392a3591ec2ac80e92571c1417be7d82b2f9a1990d50dab78c1dee631304ab5ac57274846a8fdc6547b224c72e0781b233ff8a6c876eca3a3e060a00b560f661042e85340c4a8257660c0592a429c7b81b5137d410b5492864e156dad292dabf59035fb0e02247e6c6847cfd86b6958c74209a8f389041e5389ebf5b9b633b7fcc08cfe14bafb262aa9a031e49084a6127b8410a5a46cbcabe6b18f607c97d4af6c6a598a089bb40c1998d16cd307895035b15df2c34bfc05f634813eec780c96b83fab557075cde3b64eae6ba98b65106e729b81d11c926404e99164bac5b546997d2a842f6aa9ce1f6bb7ab7551a06a3649e1caf7872ac675cb8981a124ca05a318bff9a234853821a3036a86404b0f056491a5b20ae09dedb123df8b4e9eb612a00207c6ccbc580373b0921fe2831f50610340865232c60660655184d8a0867a47811b88bcdc4e6dec5874839919188f63740588ba97405bb1ff2925c1553188c0137336948f7809dbb96d2f910a9c0aa95d49267e543057976e3dc7346cdc7560e68911b8829d37bd0eb20dd5e2b0eb1538a98a76a68798b5469f9dca82a08648a2da13bdc1a9b52a7b6f345626bb691aeccd14ec20f1c252b4fb2595474b2dea0edda47b87cb51f020072d489a2e79cfcf9a12b52bb4f626c35ba4c0888c7939f38e6126484a7932f5d6a029e1ca5cea27d729065d7137bb518c1885a299b58e1f6446fdd8449e58a21453cde7ab683bec6d84876cee590d1ad93852885db721b85d4061dca1327179acdbfc329416b23234572901b3f63a2cda36aa65b17035f449af2b404691957c30028f053989c501d8c2cf8a8cc0c04aa59f3b19a98777f814a18a0753a7180264e59f2be7c9f0266b8dc481cab4833be8b3b599818aa930571748d41657256015f68a8c887c23205a6655f30c51084925167bb75c98b8a25b7579bdf40a912365164814794bdb0b78824fe9066cc63473496ab9cea06248d883d1846fc8084d59f05277aa3eec0c3186d68bdceb6c240cd0128a6bc1361467b861ab025309c82183233c37b35e8af1b464331cbe7cc3974a48a8e015a491677567472f263e31188966eb556151819cf52772053936abb0d0a48e99357e558301dc8157a8a7853212828269786919a8f9032e17f9b692ba8efaebb602e83bd4b75160541500779d1907b1159170dea870e6f57f5229222e85b178dab32f897bf45510ead084887566942656357b7896570756ab1614994f982841a525c8ec63ccc8e4575df03be2f5cf96505ade252fa4e80fcff664f6fa8c337980251904a9135abcc509db15a49fe4c6d57b41bb6383b3483ca5f5ce11641f9eaa423c0c3254a508d4319dfe72168070cc8c771ed3e06ce74c93240947a8dab87d889f9ad894f37243b25259153324e103b73c708371400ebf007bb5459ee084be938a18d055af7cc7aa98fbb88a156849765936e7273bc385a1bca94a74368168cf26d8806c7901eee2359c8694b5439f1e82c0a6892e4a68c4858a9a00b1496e177d1efb57eb9c0ae382b56626595673230903cc19c79714364cc4b10891823535e21cbcd45c90d471e684af1fe243e925c848565a1989637f7614c900af1bea9049b78e07f00950ac800ef72860e209c192a4aa0b901090987bf15a2db6165516ad0238a40b0bb233a365bbf2bab2f60eeb8a54771a8d8e5279e2740298563aa2868e2df1be582897c7a9a0547acc2d8933aba9cbd5d937073455489a30e8cc3659c03d37240bff084d77f09dee76b60952221ed2c1aa73b772cbcea4d7a1fd64561e88bb90327b7c13c809696c0e4711ce152577517be0a2fb3d597fa5804e0c106a4c10306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47be99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969 + +comment = Official test vector 79, seed: "7f4a56eda151e7b097cfb8ef980440fff707affba91867c89522ced6c5ff3bd7f5f00bb49ddd615d9361a7e4efa42851" +entropy = 28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 +expected_public_key = 5226aa8edabd5a4a5a7cf6633a394b756ab38bc652ebc1bdb728c74ec316d039ac982b118f1aaefec04e48448d45f72b319289691a93a20283c3cb1fec992364ca83226332107704d3390f71e1883b46bc2f31b4242744e0847e72d5645586ad0b8c0fe48ac04a003045ac2d2101b52c7c1d494673bea69766a5adcb38ce3a978209471b5d7095a720a4c1971d94970884f11fa90c5c8b7009e2e1769b382004c93a2d9187b23929d941468444cdde233db3791656c860705b714e3aaf076921458b8dddd61e09ac461e96a1b1e9af19ac6984129b6c8ca9d4e39d70277b5d9a6a4b605f5e0454ac05729c2691e87a8d79353289678490a822c41c52a2f56b91a35f89918aee8935ef2bbc48485bd747cc5c59066b7577739b669ad21a5561018f021663f5cf48e08f39881d221552c846ad789810030326c8530dbb369681c69cc00c2390fa857a37ad81623eed4262db69929353118a0886e6c1ca3d36c65898968eb7c187b7b866f18a8bb369aec780e0033ebf1b0df846cd60633a461c569683598c7744fbecc54282725e337cec503d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a222418bbc57d7e1325fc2a075608988bdc44e276af10ca2d7e52b045514080597a0ff73732789d0f955f93ba77e8034900251416b43e291984cad36c53c947cc954a8320c11424be43283a6dc586a9fb39b2927867b79772dc1caa16234233adb5ac819f1a172da5194edb997f924a827a85fc7c7a8281c98f7a9cee443f68a2aea6001de7c7475b46b55ee8991dccc6527b5fa1393c9107c4d35a073ce29a7ea205a9279b62f5ce21f3aab0838b42e6679000cc4c182504a2a4e81757b7f6a183428786f09c76c69e2d7598f1e5049cb57738daab6972abf6d8bfd2ac7137493bd2b8b5f997519b2026ef38623294b91999a5419356bfe03e338194e471926fe5842e79740f416adae2a24f441ba4a0c08acc175f347ee3b614664496a5e51c01a55b1d2a3e8486cec4c3ba461970868502a0f9553d776514857bb8a872c7f736ccb432b1392e99568b51b9c9a56c441ac0ccbe785693722f90d63a0f78c8ee777236ea43de2583d0e093ec8bcab7c8c6ddd8254258b7a5732939d953e491a6bf310449083986b2a0f236c5b9a300db22299146b9a0943115845f3fe98045ca844bcb1132e0bc98cb54746937b1479dadac5a4f9320dc572ba81cb250f13869d132fa259604a76a5dd56a7543b96c3096d3046389a917dce53cbdd9ab04a65b31c6c5cfa23a2ad53faea3bff3985fdff9ca3e3965989c072f4659ee8914ddda0acf30a64a1a823b78561d5a9304950ea3056f50b82915c71ae0b6883ef319d061464d8050f37c24c62c7693f204dd4b4d74b66dd7526fdbd707a3490769764adbea61c09a2d7f464d7e932705212d6a9151b46c2ed93a7b99c1148f679d622419a4574310ac20941b3e51591ca5d53cff51a6ed2c081ee7b4bc23c8ba8b1aa2924406618715731b1cc404929a38911020fac6647c24306e349f1ecb4e2f530e8f200eb9c0a315606a3e130498f96ad5865ebb4cbb55265e69316a3bc96e51745b02f4a593b796b5951f48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f7 +expected_private_key = 52d431d74363ba07b7ec47c2a5b98157f616b8c7b7d3e68ce3f2a31365bf4e21747203c5edd758000a8c09d38a83457fb7b015bdb187e842b46cb9bfab29a917435431184219339df7cb81018a81b283814ff8b15e3a526ac35185bb45c7a865c45ab0ca1c7c5cac9e35f753d378556a62c8aac92f0ff59651c1abb789970a32c69d153b14a687fc2a56b9e0c382ba4f907a0bef79bddff781776abd042044a1c84c4c80ab9ce9a76bfa6374e9cee06081e3661a09cc3272331936cc85d6b2319cc7873227303191c36842b61013c0a41082b82034a2e1bfc8c47916859eda53033d5427741510e842265ae36d530a19e5d7365127bcab5b506321abe2b69de823b660b4699f8859de76899098159c211cffe51c7198cf1025bf9ee69236c913b16aad84aa4c381a577b6c7a3403627b323f11ebc1f304747f47407db9a8c9e4b866082597f28b6ec272ad2140a43a52188b061650bffae19761ba99ca724b71191b6dc5b16450cac50b247415370d5b207701aaec3a13cb477983f180388050175658ccb4714acb603b6b3aec340dc6c164fcb81331ec194c382fed024e0d962b056627a5b05a00b5511d78badaa489f8bb3f3c5b484f9c1450708b89828ef24b815eb43a6b8b127bfa49acacafc46434987bcaf5f91a926140bd56504fb4525ee1921b63733db2986dc133078caa44518871ba12894a553bd024fb731a0ac44ab80199394a2385bc440515877cb69b73b0c847e40adf238847608908c20bf7e1b86fa84781371d4cb52fcf2cc30306c8d98c679d4cb41eaa0ea8b395c08cac6df2348474a9504592ecd34a93b3262c9751e42193719b617355c59a25679d909a5e756c8db03e3b174e1a063edc733b9350b4f738618648baeaec5b76376d05329be6e706e632bd61292755f361096cc4565573562053b4402c42c85b5299b1cca0b9cfec4605d63665f24561d8c1dcfa896d1c6d8918a3e6f2a8d4224ff97503d1ebcc8d5395f0a64d1454623890bb7ac6b87b29333096535118cd243c52e49cbc0945385e38781b9bcb6b220a66d96d426b9a1f4c4c4d0349ce2bc790732247ec5d98e43bcd37cd94b652bfca7b988b063bb102ea0772df0aaec74c228261b4fa7a49f3b329f2c7c6d04c859c9816d5ba2aabb85e52dcae066b9af4d9951766041cc783dc672dde42558f50473bb43bc1f93bc6ea7d33f46ac4999cd33698eea603c7da265ad713e48691c8b048b21134c9998da19060cfb6ae31cb5a3b7387f2257fe94bb3ea4c963d01849fb021741395f1862085f031b6b05a7834551a6c8f0ef91397a29e12db6d776b05c7f12c8b260cf128c02e48a9f403a487ac3a6c0888c5299414aab1d7283252f62f465867a851be9a82c9a79a25cfa727c632727c765d4c496d466942147a8a7b65aec4ba84e4e2745671bcb207654b087a26f93ac77c82cf34a7c2f86fe8f48ff9a0b663d79bba6b2b8908b32fc145e4f65c6a8a379a99c9e68a10c278130a1969e0cb708d0ca6ff1669d8756d1d530ade051aba3a07903b5d801456315057187758351588bed222785c9fe83a0fb4c59245cc2a72b309767348eedb7c2097b457bbac8aa96a67d785803744e149b3f131a85226aa8edabd5a4a5a7cf6633a394b756ab38bc652ebc1bdb728c74ec316d039ac982b118f1aaefec04e48448d45f72b319289691a93a20283c3cb1fec992364ca83226332107704d3390f71e1883b46bc2f31b4242744e0847e72d5645586ad0b8c0fe48ac04a003045ac2d2101b52c7c1d494673bea69766a5adcb38ce3a978209471b5d7095a720a4c1971d94970884f11fa90c5c8b7009e2e1769b382004c93a2d9187b23929d941468444cdde233db3791656c860705b714e3aaf076921458b8dddd61e09ac461e96a1b1e9af19ac6984129b6c8ca9d4e39d70277b5d9a6a4b605f5e0454ac05729c2691e87a8d79353289678490a822c41c52a2f56b91a35f89918aee8935ef2bbc48485bd747cc5c59066b7577739b669ad21a5561018f021663f5cf48e08f39881d221552c846ad789810030326c8530dbb369681c69cc00c2390fa857a37ad81623eed4262db69929353118a0886e6c1ca3d36c65898968eb7c187b7b866f18a8bb369aec780e0033ebf1b0df846cd60633a461c569683598c7744fbecc54282725e337cec503d12a87f9cf5ba6587baf31b852bd45a871abb81e88c8b8a56d324c87a777beaf543ba153a222418bbc57d7e1325fc2a075608988bdc44e276af10ca2d7e52b045514080597a0ff73732789d0f955f93ba77e8034900251416b43e291984cad36c53c947cc954a8320c11424be43283a6dc586a9fb39b2927867b79772dc1caa16234233adb5ac819f1a172da5194edb997f924a827a85fc7c7a8281c98f7a9cee443f68a2aea6001de7c7475b46b55ee8991dccc6527b5fa1393c9107c4d35a073ce29a7ea205a9279b62f5ce21f3aab0838b42e6679000cc4c182504a2a4e81757b7f6a183428786f09c76c69e2d7598f1e5049cb57738daab6972abf6d8bfd2ac7137493bd2b8b5f997519b2026ef38623294b91999a5419356bfe03e338194e471926fe5842e79740f416adae2a24f441ba4a0c08acc175f347ee3b614664496a5e51c01a55b1d2a3e8486cec4c3ba461970868502a0f9553d776514857bb8a872c7f736ccb432b1392e99568b51b9c9a56c441ac0ccbe785693722f90d63a0f78c8ee777236ea43de2583d0e093ec8bcab7c8c6ddd8254258b7a5732939d953e491a6bf310449083986b2a0f236c5b9a300db22299146b9a0943115845f3fe98045ca844bcb1132e0bc98cb54746937b1479dadac5a4f9320dc572ba81cb250f13869d132fa259604a76a5dd56a7543b96c3096d3046389a917dce53cbdd9ab04a65b31c6c5cfa23a2ad53faea3bff3985fdff9ca3e3965989c072f4659ee8914ddda0acf30a64a1a823b78561d5a9304950ea3056f50b82915c71ae0b6883ef319d061464d8050f37c24c62c7693f204dd4b4d74b66dd7526fdbd707a3490769764adbea61c09a2d7f464d7e932705212d6a9151b46c2ed93a7b99c1148f679d622419a4574310ac20941b3e51591ca5d53cff51a6ed2c081ee7b4bc23c8ba8b1aa2924406618715731b1cc404929a38911020fac6647c24306e349f1ecb4e2f530e8f200eb9c0a315606a3e130498f96ad5865ebb4cbb55265e69316a3bc96e51745b02f4a593b796b5951f48ddd5d61bcb3f79106fb3f881087b21e528bdc627a8a1fdbb3b1ff5d83954f79bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b19c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5 + +comment = Official test vector 80, seed: "09fc004519bcf85b20d25d314a0dfc79e00cb6262a7dddf9c52473641afb8cfa0f5dd5f53558184caae9ec34b459e98e" +entropy = c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df +expected_public_key = 724abfcd15255f0a5efb7783d909031ed02c52a203de570873c7a7c556202d53a6c086899802bdc877bc6a813ab59b781bb95f4fca9ee76028aecb9142a992dd7180bc1c15dbebb66765c5abbcc5ebf764d5234d89a378d5925fbaf63a00e35d568804b973450a045e55c7c5f4907fee390fe6877963e386bc20cbe929c3d247611e346eae401acb972843dc204eeabb043644eea29ba2c1a160b98f0d28caf0677ab2aba362b7bfadaca4e1197f54f03ac8033814a71e1cf407972b3f1d9a986637a972b46d3ac46509c053efbcb9a475bc4055265961c79e1374c2159bd2409a84f22755a1b32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f02270bbb19508e903888aca4bab72e332285837b9ebb466e5cba74d5ab6bb3b2a0fa26209a97f959c905bb4b058ba8abf30a5a6c190a018a9803ac29d84ba710b30da9a0844cc1a1478c289c32737144812355e0d7589b9ab765ca3b23353a350876f05081f3e4b14d8f66c998b81f458a394cc68c3b7bfd37366ec93113db928e5f9bf0e9aaaeafc619e332a7ef3898a66020dfc64f671879691c023409b53686770f8148a2b6f7b62b6aa42981ea0cea7753599585034b9ad99c9ac8b12872b1a47a088bd8afca2d42093928a4fb770198c4cc50b0214c4c94fc7b62b5e636423c6adb553b138591f6372ca6d53343ff7c70782a2ddc4801b262f220a539181c13f3c3e8e0a0d7191a43a54ab008d326df803fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdad2199bfa332b8c22c136350adb9553e3643d0c45413782f3bc9e941965dc051df98738cf50113ab422e4a22759ca016bea6fcba390ed64540112842f5b1373a2847107a43403b4aa5ccae154b9c54831e3911239b79f1fe997bae30a542560fe6647a2e7c4916097fd484c3d040456ea2bf8b63dbcdcc8577b7aed99c05fa28d468272876b614045095e918600f7c94bb0944f62235c169b58789ae8bc3e6f677ca8d238602399e307553e235d11836be120b3bac41b0a668e0841ab11f49e27aabdfc27afcaabbf542911b6a220cdd626d819c44c72556a3946df86c43d1b8693944d399a3b5b1309b9780e34330ca387cde8e4c9b2d0775a962f447828d6295873cc1629777fd93c062098b6149a3e7c383e2c33cc3fe7730537416fc1adb6c09f4caa736e4c796d2a97fa3807c9eab72993b4b876136b856c7bc75ad054288ef491effa872247a99aa39a9c2b7602027d65a169317cafcbb77c37d89ed32489e3c2557998a06689b06ab96615bb5752d439da446354cb0640686aa794444a806c31d721b8c6b820810a5afc00932a885107b5f968b5c8ec98207293d8851892a01dfae4a99832326e3863bcda75190c4a487b46e3914b702017b1b520ccc30a5c475fb2da94ea217f76556bfee825076533973bad3ac7305b5c764cd040d723617090af4a7811e9ab206c6a331a647d9385a5e7d8bad6c89b390b617018c4a0691d262429bba173598b37d7c245452853506437e756a399670ad8e292b0d820e3567047c82870e82236389d99d678cd9b49526aac30d1b830b12f4e62407a59c8f88b7b5d088a2d08b9f114c3f158650f32c682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa +expected_private_key = 28ba2f24db8e2a5b21092964f1871e97e10f2727c8b27916a5068edd27670d26b91a93332157ac686205e23616eb0271b081b51923c5996743cc114f3ad310cd6791aeb05f77960991513ec655533921a8d14cb2589399ebf18f7ba89bb7d6cd2d7336ece1b7b63b98f26a49d356578ce7275ee67677d1482e1bb3d85b88325bae0a00cfd1288c34078d73965442b7b140705f0fb76ee3d0921112c400c7a4d1337d6a3a8cdff9af05c64c079c64dd143f1fd56c28096313e82d51836a2dc1b0f37a2e00545f802b417a9406e55420b4d71fbc2210d05a771cdc164ad50932ea40a876051828236153b4e1715edb1453045721e89a60acd0066227704b8ab991e8a06812226bc59943c0814c847a1865c19df4b7fa13ba3ef95543e724ef854ccb28bc1db49b75c1aca3649f848bc6f32c139aa79197543c628238adb755f4da6bd67130772b4790b28c9f1544a4e9860e875e68c1cdd9cc0cf17451434c7c53f3a9be39849720b1b80a836ba4c531d49bad16077e90203c9120c23239cea972454b08a5f10812443ca75b913df98dbe29c3312157e156311f67354d414aa041833f8454aca5b3898b3572e819fb2c4cada43c9c5191d6f7aed8f310cf77ccaf0c478686952e71a8a8173d0c223b04462b96c04ea7b218a13519b90cbe3be8c32b276f90d349acbb6362706dcd54aad0497a058ab0138a8e57d514d5d431043184bd1a07b77c3299ba6c7205938eca8403f31a1c605a942b73775a1ac11c40d81988e69c15079719aa769b5f618052d5290d84714ca57418366c15b74da4e98df96abdd19884ec1703f7978c4dd72b48528789d7148f16c23ef8bcd1f353cc4a76e7c238aeb1035424300f529acd46926874190556133021a6a9283ddfe02edadb7de23a4d141b0787539b68110b4882a51f95403865becea06e2d7a1c1f534fa3366bc1ab387eb867477b92f00c0d09615bfcc1138137cede4098ad57894ff74982d71ba2eca6a0f502cdc9c89bc6a44bd84fd8b62bb5d84332faa830e2a732259945028d2830a8aa866f92c24e46d164c4f4658791c11f0703d906a82546c75f81285c24597bba4b1be3972f069d6b383d61cc32b9b66604b7cdc4bb39058c74ce770f04f758e6124543e13d2365a915802f75e90997b10b15e650aee33a291c87030517b6c29cf10670d2dc5c8889aab7518b4dc86d86e25c52acc4db175a5957118f983c3a4443b33803a3161ab24004b7a789778c8414a8aa8c819468ebc28b68afe5333f7e666d44b5a961533280b0021bd3b24e2aa51ba58f2f45767a5722e918b1204656a2b44ce628a3a84125f918999a6311cb3569431c7b0d6b58adab6a30f9473b3747e33c7a2a9baf87b709353a77743949277147928273f112b5e618167a5715157b49ced69a2492203a08730ed07b7aa14bad136cfa969dfa68c28af40b9763872ed1b05d4161489bce1f473d4cc067a86258f6b664d2436d4856166cc60467887f9b97439f607d336114e46b2a2964c228a18eb532cc4c6813dfb841e60c3baa59978234a06fc95aaaeabec0123230ac33bdc48a4452403842bd6158c668f28f20bb5501984c5d3992594a9238e03798d178702b86973350724abfcd15255f0a5efb7783d909031ed02c52a203de570873c7a7c556202d53a6c086899802bdc877bc6a813ab59b781bb95f4fca9ee76028aecb9142a992dd7180bc1c15dbebb66765c5abbcc5ebf764d5234d89a378d5925fbaf63a00e35d568804b973450a045e55c7c5f4907fee390fe6877963e386bc20cbe929c3d247611e346eae401acb972843dc204eeabb043644eea29ba2c1a160b98f0d28caf0677ab2aba362b7bfadaca4e1197f54f03ac8033814a71e1cf407972b3f1d9a986637a972b46d3ac46509c053efbcb9a475bc4055265961c79e1374c2159bd2409a84f22755a1b32e4b604783bcb2ac49a27a5b0b07ae346ac38f54a2943559f02270bbb19508e903888aca4bab72e332285837b9ebb466e5cba74d5ab6bb3b2a0fa26209a97f959c905bb4b058ba8abf30a5a6c190a018a9803ac29d84ba710b30da9a0844cc1a1478c289c32737144812355e0d7589b9ab765ca3b23353a350876f05081f3e4b14d8f66c998b81f458a394cc68c3b7bfd37366ec93113db928e5f9bf0e9aaaeafc619e332a7ef3898a66020dfc64f671879691c023409b53686770f8148a2b6f7b62b6aa42981ea0cea7753599585034b9ad99c9ac8b12872b1a47a088bd8afca2d42093928a4fb770198c4cc50b0214c4c94fc7b62b5e636423c6adb553b138591f6372ca6d53343ff7c70782a2ddc4801b262f220a539181c13f3c3e8e0a0d7191a43a54ab008d326df803fd8757f88ac9bdc8bc75cb83517ac71ff8613b3ba713377fdad2199bfa332b8c22c136350adb9553e3643d0c45413782f3bc9e941965dc051df98738cf50113ab422e4a22759ca016bea6fcba390ed64540112842f5b1373a2847107a43403b4aa5ccae154b9c54831e3911239b79f1fe997bae30a542560fe6647a2e7c4916097fd484c3d040456ea2bf8b63dbcdcc8577b7aed99c05fa28d468272876b614045095e918600f7c94bb0944f62235c169b58789ae8bc3e6f677ca8d238602399e307553e235d11836be120b3bac41b0a668e0841ab11f49e27aabdfc27afcaabbf542911b6a220cdd626d819c44c72556a3946df86c43d1b8693944d399a3b5b1309b9780e34330ca387cde8e4c9b2d0775a962f447828d6295873cc1629777fd93c062098b6149a3e7c383e2c33cc3fe7730537416fc1adb6c09f4caa736e4c796d2a97fa3807c9eab72993b4b876136b856c7bc75ad054288ef491effa872247a99aa39a9c2b7602027d65a169317cafcbb77c37d89ed32489e3c2557998a06689b06ab96615bb5752d439da446354cb0640686aa794444a806c31d721b8c6b820810a5afc00932a885107b5f968b5c8ec98207293d8851892a01dfae4a99832326e3863bcda75190c4a487b46e3914b702017b1b520ccc30a5c475fb2da94ea217f76556bfee825076533973bad3ac7305b5c764cd040d723617090af4a7811e9ab206c6a331a647d9385a5e7d8bad6c89b390b617018c4a0691d262429bba173598b37d7c245452853506437e756a399670ad8e292b0d820e3567047c82870e82236389d99d678cd9b49526aac30d1b830b12f4e62407a59c8f88b7b5d088a2d08b9f114c3f158650f32c682ea6a76cb62d3ad7357cc617d597a3dbbdf515f6852d71220768859d599bbaa6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b32735fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df + +comment = Official test vector 81, seed: "e3c41cca6f04cfe7732fd54de30cc5caac93e2f80e76aed7d24a962a3969c1b6a311459a3ec3e510e3e9b1e4291d4d7d" +entropy = 0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c +expected_public_key = 30e92dbf312758b73beb83625df3b8d5c47a7a334d4e140915ca1401d461d7052e9ff05f73a1598dc9622c324c1c8b5de9b0386ea3cd95b86d80085588ac69ae310be6b5b5379202f4f14878fbb5508907b99490e4191b1e13a6890a9209f0a12910a3e096747eba94a337af9e609da4e8a9f8003633ec099983b8e778ca3d72bca1c19b4fb4a0faa4459ea06782367580b7aa49ab74b60c4cef7ab3bb9ba081227a7e1ac2f5400f8f7395f96567403b2401a2abb0b70e92e6ca2102c597f496cc8881d7b688861c7988363112155b5b88271072a7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be3907d15852fced4675547796d3046535390d44580c24bcc3d67a50cfa2ad8936d46121a7f60179be7aad0746e8a2c8cae124d27181a374493da6a68d47387a44460b39a45b2619f1d29b08ba4495230470b87bb926279eb760b9041632317c4d7a19e7753458dac07eb73331d808ce318555e1a2828da2f1d101cdc9b8363990b85064f63226c36c71061444e17a28c3b56332bab4bec2602f5c31394c870dd21030997564de52602c2628c41cb7ac2388ef35371f870a21675ac522660268a1802a2e4ca4c7152a9776410910175fd08c5e0307f4c2a61c877abbd2185ce58738fda15335aba2c77a804f94077a777fb49854c7a78462263e435a1d7b4a5205ab879438a91eb60397704cd937e66c7310625a6276182d86894ef9750f1817d85709bc578092d3b65f5c84514361264909dc2147ae6f3a577097e64bbb2c679c845d827b1ac393497575e385bb39563e125c3a3925a21160201897072f03f45d6ba85db7eb1d5b8ec7111dd785ebde07056653507e967385945389493b95c0a95827583f01dcd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa1323a34432b72c7b68f658868a2ae87306109b1053ed2bcedcb7037ab72d8c2bf48d29a0822575cc91ca1e5698286c9b19a7471a5b652f6a900659df9183c76417f0fc89d743aa635791d588cae6f650f3d314d65a6ae81a935f38b964f290be7a1a75f256776f17383f9bb9f9203415622b60b2a152a7ce3420cb49c3592ab8aaec009a237a12c2c04abaa08a382622dc84a053c94881664a97381ab88ca41846e82c02e00c6033b4721db29b71fd29069297a2cc387f2aa5336816c66e75b594bcd144171c3f7ac6df8a9a10a71f35b39a3da7d53571cb33860315288c2f7843e855d27db6f27b38940f973b2b063eba12b3a8b73d46c6781ac87f44c91e982cb27e534161212b367ab74a318b0f41e7a060823f17814f9a6e4f5a9093a6379fb0291d99916b15abc596550f152bc79703f1b0393b720cb85a510d4c9557acf3e620cf994c0bf8c06c2606041e7c3ce6044879a7612c3a2fa587b1b7676b956291a7ba5a78527a163ae08696c7c881076189bc1623c8d360c8d85c287a9c0c6965d0fa315e2037eed604084416fe31b2f01c7678311ada765acd7f70de59a9a85a8249205c78cac786aac9a0a0a7352b18f9cf936165a9c39d99aac7c175a5025f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aa9c205c1507a8f40512a45cebfb2b39f3330a962ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a5 +expected_private_key = 2f766ad78a0112b8cd4bf28dd0f589873553bf114f19c2719f61a32cbc85c71975b911237bc6aa6acb32b613cac9dc80c85493faf63c3e337c274542ab4729d02abc5dc07309032c7112540522575d663c89714aa7a456410144d7c2bc1041c03d5a56e08cc7e5663c01f52e5077288bb8cbfba21b4a8a19c055691e05c22f94c62c3cc2b6a9c155e2a4eb2bb9d95b8c9d5a6394d05af87b038c210d9faa266cf07088b3cc7ab56ff3366fbd595b3c790b5497b34b94a72d8153fa13b40be96b51315ca4d22be3828c3556843545c47b0254266a802a44bee6e5a19a446472322c6aaa4cf47218ee3c99247564c552c93ed589ea8bb2c637bcf7277d5b5058dd80342815b2e8864b4c330920a82ec76b4a7bb893e0d18278f47f84743223a67f2983ac8c4a1845a61259670b02d6053ca181ba4c1bcca05b7af2a27c59c1e4e38da723b787aa2f36c71e3be05039183bffea6ab3bc779de2273326b327d42517b6c6ed8c7f96c6330d4c39e3d2a7b81a538693329abbbb5947b068c3cf7b45c173c1ba9964c86ed91d0bf64e209c1910c218434311a50a2128d52754148159891e00475654ab30b9693ad507b2e19acb7fe6b14f27c09c6b2570b861926683a285014631c2d7cb8c0c10a25d073d3c067ab819b9dc27971825ae21cc2e50d377e3396f0266a5ba598bbe9a868b0b6cad2ca3a8cb503778967bb930d90795719b237238c1f831007c690186949c600c6f587ac0d81c8334c57fe0c59db3e2815d63c26c620fdd75836261644d99327a334ea5a40571f0cda39ca716d2bb894a50bc4cc84d6621b60509dac77ecaa39b9779a3696749ce83933eb70c1e85bb2dc3421ae9a0ef40ac2d83a1fac16c6dccb0aa16aff9a94bb6d125665c3001b845e7f20e7c90a3db636950b0836ba008da33500fe47fd4a81df0e268c62974bad02a6d3b2267f917e2046df3c1883187683f030a28a129902083ce26730438b0dc0042998c9472f5a7fdba371d74481dbcb9bc4cb281e7cc1dc4455823ae1ab8b233e83324544913dc261b6274464b656bcb645f87b0cf4512af443959e67c47d679020c2905d45e21da586ee8291085a8a432ac6afaac594081ec298dc13175779b8635fc8eae58982258759999a57b704a5b040245d282a9b6c9cbca838399523f26695f60389ad42f6512783ae65a0c25b7258674398839af28866671329109a58e579c026549f0b7041dbb6623665fbc9a2ede41c0436635325912366ab1364b5a3162c4b8c2a14480aa6bf165588b8d26ea968291cabf66a4e26722f87977dab7807a2c65a26a9cbd339bac0b24e6b46e0a8082be95bb7a41b1b8b670ed3105eaf994a06a6414e9abe2a1b608c29c94b846012a0fcbd6959ed411d8d0c70a32559c68c74d94b2a9707b9d9755e3c69ac40782e97a1f904a32da824c7459b59b174a9fbb6b41947f47b3361d5558d831b2b444818ffa4c17f4bfcf8b9c7ce451f4ca99884c13f85c24d3cc4740d2567a54ab0583a175759fd7e197f3000a39717bfd9c768248518d50791cd84dba795e85388dca21507bc669ff0b906bf515f38c04dc838d0d1357377b1601887ae1b0a0c4490d38a871910c695c50008e5a5a30e92dbf312758b73beb83625df3b8d5c47a7a334d4e140915ca1401d461d7052e9ff05f73a1598dc9622c324c1c8b5de9b0386ea3cd95b86d80085588ac69ae310be6b5b5379202f4f14878fbb5508907b99490e4191b1e13a6890a9209f0a12910a3e096747eba94a337af9e609da4e8a9f8003633ec099983b8e778ca3d72bca1c19b4fb4a0faa4459ea06782367580b7aa49ab74b60c4cef7ab3bb9ba081227a7e1ac2f5400f8f7395f96567403b2401a2abb0b70e92e6ca2102c597f496cc8881d7b688861c7988363112155b5b88271072a7a7d68b76036059ca5e402532ce8763c52ca237a334832832f2a49be3907d15852fced4675547796d3046535390d44580c24bcc3d67a50cfa2ad8936d46121a7f60179be7aad0746e8a2c8cae124d27181a374493da6a68d47387a44460b39a45b2619f1d29b08ba4495230470b87bb926279eb760b9041632317c4d7a19e7753458dac07eb73331d808ce318555e1a2828da2f1d101cdc9b8363990b85064f63226c36c71061444e17a28c3b56332bab4bec2602f5c31394c870dd21030997564de52602c2628c41cb7ac2388ef35371f870a21675ac522660268a1802a2e4ca4c7152a9776410910175fd08c5e0307f4c2a61c877abbd2185ce58738fda15335aba2c77a804f94077a777fb49854c7a78462263e435a1d7b4a5205ab879438a91eb60397704cd937e66c7310625a6276182d86894ef9750f1817d85709bc578092d3b65f5c84514361264909dc2147ae6f3a577097e64bbb2c679c845d827b1ac393497575e385bb39563e125c3a3925a21160201897072f03f45d6ba85db7eb1d5b8ec7111dd785ebde07056653507e967385945389493b95c0a95827583f01dcd473fd3138887d3472e18b24c1b7e2c837668fc6917175471f3caa1323a34432b72c7b68f658868a2ae87306109b1053ed2bcedcb7037ab72d8c2bf48d29a0822575cc91ca1e5698286c9b19a7471a5b652f6a900659df9183c76417f0fc89d743aa635791d588cae6f650f3d314d65a6ae81a935f38b964f290be7a1a75f256776f17383f9bb9f9203415622b60b2a152a7ce3420cb49c3592ab8aaec009a237a12c2c04abaa08a382622dc84a053c94881664a97381ab88ca41846e82c02e00c6033b4721db29b71fd29069297a2cc387f2aa5336816c66e75b594bcd144171c3f7ac6df8a9a10a71f35b39a3da7d53571cb33860315288c2f7843e855d27db6f27b38940f973b2b063eba12b3a8b73d46c6781ac87f44c91e982cb27e534161212b367ab74a318b0f41e7a060823f17814f9a6e4f5a9093a6379fb0291d99916b15abc596550f152bc79703f1b0393b720cb85a510d4c9557acf3e620cf994c0bf8c06c2606041e7c3ce6044879a7612c3a2fa587b1b7676b956291a7ba5a78527a163ae08696c7c881076189bc1623c8d360c8d85c287a9c0c6965d0fa315e2037eed604084416fe31b2f01c7678311ada765acd7f70de59a9a85a8249205c78cac786aac9a0a0a7352b18f9cf936165a9c39d99aac7c175a5025f1c66d04354480175fc3249930e66c9d06aa50e7adfefab6aa9c205c1507a8f40512a45cebfb2b39f3330a962ed717408e0934fde42a5e1cbf04c80f37d7dfc7eb53a785194c4a1232e61c37a564c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c + +comment = Official test vector 82, seed: "373fdde922cfc416ed96b444e445bdd0962e8989f6c50adf9912a89937c57217d3600b06c95440448e3f601ae69ca5be" +entropy = 2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 +expected_public_key = be0aaff4d255d72c6e8424c2d5d23f0aa4c28094691ac4bf0f56a51ea4799810cfb024c151c35cc3c6cc90a41ab964370c2bc953a84a73c87a02813de34b933f233da28643a93388f944c033236372fa6e6aca085b598123f27122a40074a4af57684d46398e5d58b13a863b0b984e224a7ad52c1c4eb26909451dcf2a15dcb11ac4ca38d93ca350078138e0ae87f1390fc9045eea420260c913c6b54dd93495f31aac32350cd03500da308fd8ba0777c999cb4982c91e569a1c52396edc506ac7cc43264a05cc880191501860f1a32f7760ad3b17ff693508339fcfc05fae095c6a96c1e6864baf147186bc22dd882620e5a5f4516df92b8b715394c5677d0db913efb25459d6c636442a8ce22899f8943957bb2b281a8ed14bb5d0ce6de3086ea8b6165798619b2ecbfb22727cafc6409e23088c6c940c23e86a603788c07ba89d6badcef07d79174acf70c55b7b30c067bd8202a1a70998459c54384196f814515ec9c7f360061270090ef37ad32115242c2aadc0121e1a08623038b311982c669de3dbb1c7789530191b07a947c9637bfa241ed35aa1d03c81f0d70f8b95112a3b1b08b25c34dc7e1d577fd30a808ac574decbb51538c2a017287e62128f32afb0f7a73ec8831e6b975007592b5c652fa636c7315baa474f873a5da2e82fd146268dc951689ba83e046c0f4820447c3b3e6c78cd240bc4d21e0a4660eb1c69402b617b83057874122e203bd6313d7874a987f2987599cd4d7946e50665f7d9a80651cc8dbbbc4df605f48274fba0640f8609b6554a7760856259c32df00d3056aef65436a285583cfc9d9a644f66e382d4907c6d78aa461a2b6ba8887c238f81d31e796a675ee8b7a598afd5d79a0587965420a2e9f2782b71331737680a499aa759824d11acf1a001f9a5865b6568ed8a1f4f4cc38f74c24e231965e9830232924526baa377b2ee933a1fc4677ee74fd98a0881628315aa95085c7415a1a51a98406fa345a69802ba71cfc885816ea30fadea0232b13eafbc24b84347124bb41f8c663506665ce4c3801b09933c19675c1f9ce54c418207b69215c91b10451730de65a4aab6c97804ad33c50233f83599133510bb334d9c1f4b7970087700ef45500ccb31b7933fe74a346aea4c9bd409bc5a186f00bdca67cfa8d041dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e6e1a11fec0938a3a886e9b328a8a539557f6c700285693266742f779bbe2e7a0603060673c7be9591be19a57a0cac91cd1c61860a86356b90715886acac2306190cff686883a61e56140f64ba76123c1b07614ff5c8a4b402cdba738ab68b749c1151da62c30dfaa3bf826d4848c4910c9ea20669735cca4df583e0c5412b610bce816fd17ab9c203a7ea42081901c8cd78940f090efb49718ac90ad6a101093580c13b5ffa0ac0d7b094d913a9ddfab03f835f79173e966746c69a0228d06a2c363e94522ec68312cd312eccdc688c4a88f6a5b7c3464cb7ec842fc1377359a162032c8c504105461936714f451481d8a4942d1715b6a65583999b96b0c47a914f2f721f5ec6315c91b009e714f6518bfdc75e828256f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1 +expected_private_key = 6c33b8ab2b4febac9ff7dc3e4a689f468a4f08d5c87ef8a142b4766e24073df336efa5a0d6fc17b6bb2c615658eb04aa9035560ff7979e27c65a85ca6b1b9bfaaab23d89c6a825cdf7e312f81066d516be72680e5a665830f74e371bc411ba86f00704dcd3c40c8c1295d6b52aca51ad41732032535af95bef907127eab1eeb54899a36961793ec47b91d9725643664082c4375f4843b0031b815c8dffcb7f25d4414191746d5aad14093bf2c005df655f69917baa956721b4cb8b8b51531a4a6c0ca50f8ab21dfc7cd9f81d730157a59b971e4b4a0fba8ef49754a7c2be0325c8bc623fd2a94a6cc4226677260ffcb64d75167d63334e395df5ba4505495cbc8c3a3e40ab68796d6c646775339c29683a21f921a7c6a79d39a95c876f782a27a6365908381d793b537d1a681cab5599817e050cccf7803bf9a90ccc4084743c96069183b08702979c9dca2b9d9bc26e1de849976aa1465b29eb260ffc64478c39945a9b402520172cd7861c5a0cc089a028c8200208b3e4d7b3a91cc8c209c5e1d201278b01cab34126c701bfc2913df501f6d73d9424cf1176b8616c04c10940ef9832957585ec350e9761505162aecb28884f659ea23125c382cf24f383f9b09feee8aacb981df21a6bcec26e2a67493b919fea06170c18b79e5a01e6e89516707bcc7ca353727825514aa0d52504606013e53ba916bd133814c36b98fff15f847b7383854f692450aad28231f2bb4fd839d2b532066114da65be8cc5073f9992e03836ca3a623c301999a56fb00332d1ba8a26d599d0f5a97975814be81fc9dbc536d1c165a131ca3c55d04a05d7a53fff1299d3860cafd8bc6e3b97e72a595d294303a12994510f74887fd1d7bb18da70bfc5bdd58c1f6c1cb56f5994b7f2225ce0ab29e8cf3dc851f1aa5bf2ba255f7215cc71c5da95115d6a98a2317224bc6de1b2c79353bc5c3c046a7a0933a73419f7b117b88f3a53777143546cd29014e15e37c33770a8a9a11bc2f38777e400132a812a984908b3d2b87fc465b564045e79453c0666e3682a894c269551afe25286fcdb681cb50b260b4327b46c2d0699beca103965b0a218902eb4680c1b8c3ecb2011a396b0dca97d56aad231168fd9a7cf177b85b7729de4a4bf035482aa7758aca9e1f36bc9033ea34c6dff91091e8b36fd2a2c6b1094a8338ad540c8f53cab80d73e7dec3977452915b616d0f0bf9e842663cc477cdb5dc94579d6222d1b647ef4d358c5435d3d0799242b66818a683e8c5651b0b26ce4909f8656ff35cd7ffa1c5988074ffa32df093bcda32aee2003825593b545b44190787c4c8656d85cac293f615811ccb35eb0413f44b1722e0a182f09481712ac68e3c9d31085ea77946a54baa91c8ab8e814c5b94206070c0a6037bc02a292082018933a5ac32141180a6dc760c2c9aceb3b1a1505464150a732664aa51b02a721b63759379a638bbfd07ff9a7a84e071fda70200c61894a8891dacc375c120a35e0a4f296a02845477bc0484fb5bc539c3b8bea3ed2511d480b1dbe76c640622b67a1a8e000b954057322cc005f88284d6290a5d720e32b5f6cb6b992bc182d66a73b5019572867640343f267133b060545d4b2be0aaff4d255d72c6e8424c2d5d23f0aa4c28094691ac4bf0f56a51ea4799810cfb024c151c35cc3c6cc90a41ab964370c2bc953a84a73c87a02813de34b933f233da28643a93388f944c033236372fa6e6aca085b598123f27122a40074a4af57684d46398e5d58b13a863b0b984e224a7ad52c1c4eb26909451dcf2a15dcb11ac4ca38d93ca350078138e0ae87f1390fc9045eea420260c913c6b54dd93495f31aac32350cd03500da308fd8ba0777c999cb4982c91e569a1c52396edc506ac7cc43264a05cc880191501860f1a32f7760ad3b17ff693508339fcfc05fae095c6a96c1e6864baf147186bc22dd882620e5a5f4516df92b8b715394c5677d0db913efb25459d6c636442a8ce22899f8943957bb2b281a8ed14bb5d0ce6de3086ea8b6165798619b2ecbfb22727cafc6409e23088c6c940c23e86a603788c07ba89d6badcef07d79174acf70c55b7b30c067bd8202a1a70998459c54384196f814515ec9c7f360061270090ef37ad32115242c2aadc0121e1a08623038b311982c669de3dbb1c7789530191b07a947c9637bfa241ed35aa1d03c81f0d70f8b95112a3b1b08b25c34dc7e1d577fd30a808ac574decbb51538c2a017287e62128f32afb0f7a73ec8831e6b975007592b5c652fa636c7315baa474f873a5da2e82fd146268dc951689ba83e046c0f4820447c3b3e6c78cd240bc4d21e0a4660eb1c69402b617b83057874122e203bd6313d7874a987f2987599cd4d7946e50665f7d9a80651cc8dbbbc4df605f48274fba0640f8609b6554a7760856259c32df00d3056aef65436a285583cfc9d9a644f66e382d4907c6d78aa461a2b6ba8887c238f81d31e796a675ee8b7a598afd5d79a0587965420a2e9f2782b71331737680a499aa759824d11acf1a001f9a5865b6568ed8a1f4f4cc38f74c24e231965e9830232924526baa377b2ee933a1fc4677ee74fd98a0881628315aa95085c7415a1a51a98406fa345a69802ba71cfc885816ea30fadea0232b13eafbc24b84347124bb41f8c663506665ce4c3801b09933c19675c1f9ce54c418207b69215c91b10451730de65a4aab6c97804ad33c50233f83599133510bb334d9c1f4b7970087700ef45500ccb31b7933fe74a346aea4c9bd409bc5a186f00bdca67cfa8d041dfeaa56547a71c35cef1b664629ac9d4f431cfccaf62a781a4bbb2adca7a7914627da380873977e6e1a11fec0938a3a886e9b328a8a539557f6c700285693266742f779bbe2e7a0603060673c7be9591be19a57a0cac91cd1c61860a86356b90715886acac2306190cff686883a61e56140f64ba76123c1b07614ff5c8a4b402cdba738ab68b749c1151da62c30dfaa3bf826d4848c4910c9ea20669735cca4df583e0c5412b610bce816fd17ab9c203a7ea42081901c8cd78940f090efb49718ac90ad6a101093580c13b5ffa0ac0d7b094d913a9ddfab03f835f79173e966746c69a0228d06a2c363e94522ec68312cd312eccdc688c4a88f6a5b7c3464cb7ec842fc1377359a162032c8c504105461936714f451481d8a4942d1715b6a65583999b96b0c47a914f2f721f5ec6315c91b009e714f6518bfdc75e828256f25740c91e7efd93a5d7db1850127df85b8f086dfc57f1f62a86d6ee7e45aff3f27bc1db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf711136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28 + +comment = Official test vector 83, seed: "16bef67f7ac3a755c59c816478b75fcc16ce5844db537791accd1ebd49d2824b105fd2e970f728c8f0cf16e439a9ae2f" +entropy = 9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 +expected_public_key = 690b34b6586039100e84215eddb39ad2d40ba9f80165623122a2c5faf3437ab0376894ce67397d32a67c3bfb9761850c1c68ad988348725c83a378143d504400f995157903b9d04ee43404ab2cc7c35b8e0e09cce4559945f5640450703f81c35ed332746162f7b8328f78bfc3359e7c1b4fcf06155fc745c70245ffec09eca957c8475c62b05bfff288a5e5a5c78206e48c3ef373658859c3d9636786980578c07b764641d6a87222224557d10436fc72b563883ecb0934e50b6ec89429d7792ec0bfcda416fc2ac323a58df3fbcdb6e023140478868055251b1c09fa023e240e109869c1d2967f598a529042d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f228083de6a04bdf58655c59bf57b107987b88cbc001e010b9c2458bdf138288190f955b62c7013dd5784c809a7b1a29f8c3c33f0311a555306327392ddd44ec8f72fd5893f56f58baf207f9ee98b7e31092f761c390763a8b57409c7c5c665a913e20c9b62a5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5e816ff841456261bf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36674194df1ac3f595a294c28d24c26e1b1b5af5b542e025a182868e1555442e0b0d064865ed5cc1665074e55aaad601779e591e1ed2ab07cc551437603d24ca743218fa846822b2857f871fa26834e0422746a6c7dad256bc0b4bfff21bd7309482d7669f8857543a0436140ec684c959d26f2f827a84b37534b7aa3bc0a08163689f01141b511e7d11a316d2aa7d73909e889dd000c20e38667da048278b5ee87188607b4210642f5c38866fac1549637c600c8be8c60c11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dc8070b5687f7c6a73225b9233685c6b703d33677998c24e40a72894193cca1c5acbe4a133d85a6912587ad4ad522214974cbb1f877e16164683021ea9c335d41b000cf52a3ed45b2d95b7e2d061b5213db4c6bc36d76df5db9ee6984d31bcb1f6757de7e51871f1ae7f388c5134956d3286a49bba39967889c9a424772bf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15df419f6ec22d15a95553831be379ed0489749c495e3b6b8e190049a8065dba8933fb21ba3a751cff289a2e2772b06a4687338ca88c0eef1488b848afa1041f4f9607eb18bc0650055803041b728f2f1922cd984d228096ff29e71f097921423cb82254c40a615240a2482a3f5f095f5b399a8f9addeb6b726f43e3af64d09038cafea26686caa2ce2194cba660edbb083f92dc2a51142bbc922958c86c62ce7a4b3a4c95240d72244a912c3c193485208cddc4514495b35863cfc6cb41fa721a78080fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c832000c1c337fc019f0aac04b2149a469420c15b2daf5281dba5dc3618e0135c043f139cc74b14e7451fc11328f06b73f124766403541131d94506628c30b7ba68564179faed9c9d2a20f3b61793a33a65e92b699a47fde974eecbace22690273a757da903a886778002d283a819cb1ea2d34b8462dcab57c85653e363629d9270738434ab1bb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9 +expected_private_key = 2220bfa6a447db5013ed5811b45742b6e95c723a35851518e04b1b619c5607944c341a1aca4c0eb297bfe3990d514aba3de30867d646cd76a1ec1176f1e84ee60704b0e04366e27ed0f321bbf42322f5289f5167435b880851b48de717e40a1b56387d4705815701bc2b80c55f33b3c20244e0e27ffcf43c457a3674000a4404b4157cbefa05c54f50021684059939a3aa088dbba13be56047df450afe33c8742abb0cf48e0b1c24e8719eece41ec4a3254836b4e45b4eebbb43d398a813bccc0c42cc4e437050740c892b657765b252943896325e3f4c45887452847aa315ba8c811b39254a5c3ee64f65823fcf2a92e3198d2981289e021530aa4cbd210fabf51094392e25e755d778a02ca145fff47165711ab9397a0f9b3def26bd0e5143c23a815c8582976521d63bc74d8b42b95280cdc77de3528628862f44d475f49ac204c87d2647414a4a136a094b7fb923bfd3496b187592e81b8168bdffd9522f60bc37052fc579cb3f7a398dd677ba14a3fca1248057a59a58531b7a1f1773735a27612520b03121390cf624d46927cec7c7d00ab13dc2ba6445236bc68642ec9659d7bba40aa692c40794bc4bf5f13fbb617e711a54bd825329ac6a9af2a88a54a600c0cd6754b4a3accadb397cabf2af41463c00512d6d206d011baf6d833e4abb8dfbf736df8036278a8125389c3b99940881760ac150967464483242dd52358a075271fb82d949af57f345e5dc46845a94a37893613a76b6e7b4d0db0edda213302677fb73c493a349704333278b201b6baa8315731a348ded27283dbaa05e057c26c35d68a5252f1715337a1543895dfa4c395f9909b7b1283b450b71730292c32dcffca05221b14849aa5f94888e2a3fd33cab3b380f8093742247ac27012e8d7a6b8702983dfba43601677679568a8051925133fbf6550dc318e387c3e3176ec9c3cad6a739c6ba5b72fa587f000ca8f06eea003cd05970652b0f3f92b8bd4aa1570b02cab21d2bd0a9937a499943ce285b32706589c11cb662461444629f5c755b4a09805dd5659127bdcf5466270a5cb6328fdd0583e701aa98d34095506284b63a6f7b39d0b31fedc43e20e4bcb39b99d82515e041627fc5402290be758a062822c26b750463141d9de8793b385f556a3a3f74bd8ab61f69304ac4082e08f2cd05e5beade17d2c87b9535a084a6b0547389d08f548030b1dda0137d170039e082c5583bc83695aff0898f7e19e54204582989556b924df35a00c518ab95cbb466b5ba0d8aef007a8294294870902e74152832365fdb79508b69e45484139b4342df8c391864b80e807b9dc8ddcd4463fd1a986986b81a62d79aa9565308ac1471f09d09a23f24e4ee5522b00265770674c61348fdb3bfdd539994b20ff22b210162961b56dba538252610fa607372db1317497b85307b61d890a62b90e4dd37246763dc6093af5f4cd0dc20081ba4ce2d6bbdc969580607022c590a1687004b0730af71c60590d1a6b2a5e51c742d2cbbaa826600055f4811287a062da1696a22808507aac327a9194c5c6d49c823557100c158e60b845af953539a855d217c5a77599b1783f7488aa85f222df73b837e4b8d1006a8fd6b5b06083690b34b6586039100e84215eddb39ad2d40ba9f80165623122a2c5faf3437ab0376894ce67397d32a67c3bfb9761850c1c68ad988348725c83a378143d504400f995157903b9d04ee43404ab2cc7c35b8e0e09cce4559945f5640450703f81c35ed332746162f7b8328f78bfc3359e7c1b4fcf06155fc745c70245ffec09eca957c8475c62b05bfff288a5e5a5c78206e48c3ef373658859c3d9636786980578c07b764641d6a87222224557d10436fc72b563883ecb0934e50b6ec89429d7792ec0bfcda416fc2ac323a58df3fbcdb6e023140478868055251b1c09fa023e240e109869c1d2967f598a529042d9859f97cca2e85a635418707b3aa1835b77df93ae4dc53f228083de6a04bdf58655c59bf57b107987b88cbc001e010b9c2458bdf138288190f955b62c7013dd5784c809a7b1a29f8c3c33f0311a555306327392ddd44ec8f72fd5893f56f58baf207f9ee98b7e31092f761c390763a8b57409c7c5c665a913e20c9b62a5e80646364aa8e3b95030fb2fb289991b8637ea57c7b324a25e0389ce979b5e816ff841456261bf042c85dad84f80d788076b7c69cabb8e389a72657d7d63949657b934a468516c36674194df1ac3f595a294c28d24c26e1b1b5af5b542e025a182868e1555442e0b0d064865ed5cc1665074e55aaad601779e591e1ed2ab07cc551437603d24ca743218fa846822b2857f871fa26834e0422746a6c7dad256bc0b4bfff21bd7309482d7669f8857543a0436140ec684c959d26f2f827a84b37534b7aa3bc0a08163689f01141b511e7d11a316d2aa7d73909e889dd000c20e38667da048278b5ee87188607b4210642f5c38866fac1549637c600c8be8c60c11aa394e8344b6c6536e687ef6dabac397abf1ca7486f6ae87d8a3dc8070b5687f7c6a73225b9233685c6b703d33677998c24e40a72894193cca1c5acbe4a133d85a6912587ad4ad522214974cbb1f877e16164683021ea9c335d41b000cf52a3ed45b2d95b7e2d061b5213db4c6bc36d76df5db9ee6984d31bcb1f6757de7e51871f1ae7f388c5134956d3286a49bba39967889c9a424772bf5dab014c94893a4c8b74ab099687919243c7633caf297b2b73ab15df419f6ec22d15a95553831be379ed0489749c495e3b6b8e190049a8065dba8933fb21ba3a751cff289a2e2772b06a4687338ca88c0eef1488b848afa1041f4f9607eb18bc0650055803041b728f2f1922cd984d228096ff29e71f097921423cb82254c40a615240a2482a3f5f095f5b399a8f9addeb6b726f43e3af64d09038cafea26686caa2ce2194cba660edbb083f92dc2a51142bbc922958c86c62ce7a4b3a4c95240d72244a912c3c193485208cddc4514495b35863cfc6cb41fa721a78080fd7ba72669ac6b29accd3b832d35ad70f7584e197d695b78c832000c1c337fc019f0aac04b2149a469420c15b2daf5281dba5dc3618e0135c043f139cc74b14e7451fc11328f06b73f124766403541131d94506628c30b7ba68564179faed9c9d2a20f3b61793a33a65e92b699a47fde974eecbace22690273a757da903a886778002d283a819cb1ea2d34b8462dcab57c85653e363629d9270738434ab1bb46bb71890031ffecaf8fc027d2dfa2a4ad271dd702f055836f40ca137e5d0ef9c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32 + +comment = Official test vector 84, seed: "d0611f9ae5be4da5d7eadc9109944348e716cb3daee545721eea8c892e7831cf2e54603146454cbfd92387739e9a78d8" +entropy = 9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 +expected_public_key = 44bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d7c227ba5c64afd5c87e01c1ad12a294758f45804719dc7369950e9e6398bfcb60a7819585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586056201ffc3cbd92c3a42d6851ec064a89227b4d1551ca7af6b5b3e892b4e44571669412e4240a08c42551dcc50086389f9e0c0290956b5ac58844a84be308d0a5562b57b5cbc594ceae87910a13167f27ce63b822f201af5e9c33bca746ba7c5e8541fff17324228321c7a0ec976646a6b5615f80fb56351d319b31960aa8823426682a610652652994d4a78c25659b533f5b40e6236a6e704cd891502e9c2d1858ca64c94d3734ac0bbcab2db2f9e03450e721a38c82a4c26a487f006e1966fbf8063ab115e74f441837506559ba5b7266f62b17e4d959209b657193689a0354149880d08434fbc282713118d9daa89c52186ea918ce2c170d8380e45a32e9f710cd6f89daf91c9210b767d743f61655a9702051d7c8a46f17a681b136c0863cb62430d084d282099d1636c04d6b1ec212a74046d2d8108470123dd751db685a1a1fb3a3b2c216f51302fa13ad73b919a439d424a4ad9e12994d1963b3c0e0316739ce50a1a7c23d65acea61423a5792321a84ad2e1b3f5b595f11637eaca77fc753260e04cec9ccf55d70d4d567bb78749efd005c9525f6e921f0630c25cb9a129781b9b864b7556272d5b4164e340d9464bf192979a073384f6a5e52aa0b6b74d43faa5412c5914524974161afcd91660705659dca87ba482d67c8c1400b069e66a19905b331243701ac8261952c5b736b25290235669fbdcc254631294fa2e97c440d97a0211c35c2ff4b6009aa66e27cc09bc09307c7b3794a5d189892ea60b2b323e95057ff355114ab48613e2760e00baeb82b0a763067e216aab899e7ca06e195a5e92486ce8911bfd5c7d956318ac3b029436a9d88c56aae2a3dc7b382f2c5e7265a037a827761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abe42cfc463c2f1542ae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0ae91cec8235705805af096cbefd0cad6dc0bb5130907d64e76e4be957a117d121d66071598112ea7d02b9648cf53e57af9e7cc3c9803aab327d87c53e41cb9bbc42368d332e0a963c3385c18936ad7483a5f4292b625c844c2282f25af0c86984ddc09371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dbe147efc2a34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf0b12d7f5453e669be2d805dd6961454ba8b40c6efa961e53da19eea2243c998b504c8ab9eaa2db11b2f9b591990040954a1567074e69154ad6e618d0830d3b554fe4c99f48b51cf6609952cc9693acab000c335b98126b4b45a9f317f80a6049558fe9d855a026aefdc649d295387c530e075ccb32aaa202171c6f6907a4a2202a9c5fcf252d98328f12f927e31c596047140af9b177e0352b120954d00529a07d6b2bce5026a6d7cba01231a85ba39b1692694788c9215b69fcd111fdc8934a1ba24cc7890eb479aef01ff29161b0a7ad921bb72a8b495ffa74c62c880bf03f0bc175eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516 +expected_private_key = 7934a9fabc835bf9a77bb807332251daa00876e5500d2c59f07485ed01bc934911a336acde5527dd166476ca1d1aa558cd88cd7bd17ce1791958e851991867c0525c9472a953c8b04a730e2e132c6c26811cb86f3234229f4caa2aeacd2e3c840e97b8f1805b94d7317b08354bcab64887a4e6a98ffd90a7544562ceabbcce6489c6e8534119c9589c405d7a96de3230094a459549b6f37078f2c01fc9080f049464b0a969eb742419147c8b39b8065a769d400a17bb25de51a699b69d54ba460d33ac6a6965916829b7a578d0b24bff786cef9963bf961adcc20f9a0cb1c159865a344a0e36879c67852df50aca08a46e72a4a70c027ce283de5bcb219808f2635bd7540915c5485ab70358cb017882b12acb4426b22b02605873f2bd0da59a658075136cbe15418cca0a11386aad43a52e3c5ac97f36bc7f648808c260643c325cf456e6166eeec74ee8476ad62c73d7d334ac279d84b66b6c8aac217a813dbb3dc6007317a165e6a1657d0277c1e683beccc956d973c7624e959724ff9275c1aa2bb5aca75159721b8c6d7b299c7acb4704c654335982e83ab3724ccab3709d20601c2a943d5bfbb3d384a7e83a7793905301b1704cf49992077b19f0204f3394717c9ab9a173113004fd325edb797a30155d0d2a1e4984644f245f5b495b56a98fdc487b29b4a5c6dc4e3047a8da2c9325f1705613705628458bd525fb333087cb4b967a61a994cbefc504d18c1b8a62898af32bc454a57e264722897d5dc71e32c2495ca857e1a234ae61c77083ba9b780342d7cfdff8b7ec1257b79cad017113a3238510c5683c3a8c396986ed392b0122c16e34a7249691ea7a931c44087fa1731746c1f3855bc72414fe3484d85b5e2586b6231b4bcf27831ea7b57070a815795f43e90b2112b235f5959ea253db76192bcb11d4e16399d40c5dc0a15d98c3b3b0289f07839f7738aba3281d45aa0a9ca1d349a64e79246c2c7770227f1e1cc74db8ab7ea7b0e60a9dc0e45443b30ca656cd6a8897ab105bda51b02179936f04374554a52992710f2a70972479462a2859736c2fe4359a474939ac3531b2905f90bc38860b5615abfb1a1327814c01048bb93c9725c7c3b0547921975766a97e29d529e4d8a090c36820db0fec33277cc679cd4a51f7ca05f204bff20acf63ec403ac7ccab951a8ec166c545abfce8734833274f724e77e68137967da75515e3c270ce79838839721bf3a14c952085071d6b3a555ce62d96e7736a583f44f726aeb921caa340d4bb788d63645deb2621629dff8a2c51d23bfee95caa7756f1884a0cd263039c37f7415e83d4908507c1b17a7308cb329d829c86953422b8b2f1786a4b86b980751255339258572a02ab22ad845632f859eac223e1245ac3533d359246316a3cc1ac58b4e6386592859547171ce05dd7a76bf8e93901eb7f40114175ac45e0b35109ac57be844c52d31a7ba60a24f30ef0e45581242c02e020ec86af106836b3dba8071bb8e8574fdf208100982e55f4b0dca72521440a2aea68c57b2039d14b21a56274972eccac7eed41c4b26cbe2c973507f1cdf4e618077406ccd3c8c5118545178351522485730b1a1ca7971b01766b914e835244bb530c48419abc7578b33d6db56c76179e9da3808ba4c8d7c227ba5c64afd5c87e01c1ad12a294758f45804719dc7369950e9e6398bfcb60a7819585a689462346aa5968dfa83bbb3b8a51bb59311c9d100a4a0c7586056201ffc3cbd92c3a42d6851ec064a89227b4d1551ca7af6b5b3e892b4e44571669412e4240a08c42551dcc50086389f9e0c0290956b5ac58844a84be308d0a5562b57b5cbc594ceae87910a13167f27ce63b822f201af5e9c33bca746ba7c5e8541fff17324228321c7a0ec976646a6b5615f80fb56351d319b31960aa8823426682a610652652994d4a78c25659b533f5b40e6236a6e704cd891502e9c2d1858ca64c94d3734ac0bbcab2db2f9e03450e721a38c82a4c26a487f006e1966fbf8063ab115e74f441837506559ba5b7266f62b17e4d959209b657193689a0354149880d08434fbc282713118d9daa89c52186ea918ce2c170d8380e45a32e9f710cd6f89daf91c9210b767d743f61655a9702051d7c8a46f17a681b136c0863cb62430d084d282099d1636c04d6b1ec212a74046d2d8108470123dd751db685a1a1fb3a3b2c216f51302fa13ad73b919a439d424a4ad9e12994d1963b3c0e0316739ce50a1a7c23d65acea61423a5792321a84ad2e1b3f5b595f11637eaca77fc753260e04cec9ccf55d70d4d567bb78749efd005c9525f6e921f0630c25cb9a129781b9b864b7556272d5b4164e340d9464bf192979a073384f6a5e52aa0b6b74d43faa5412c5914524974161afcd91660705659dca87ba482d67c8c1400b069e66a19905b331243701ac8261952c5b736b25290235669fbdcc254631294fa2e97c440d97a0211c35c2ff4b6009aa66e27cc09bc09307c7b3794a5d189892ea60b2b323e95057ff355114ab48613e2760e00baeb82b0a763067e216aab899e7ca06e195a5e92486ce8911bfd5c7d956318ac3b029436a9d88c56aae2a3dc7b382f2c5e7265a037a827761447fc59a40a3c8693bc996ca786fa7ac1bbcc6aa404a1bfdb3d227c6abe42cfc463c2f1542ae418cf4b38cc2c1595f9343d41b4a1967c7c94a7a0ae91cec8235705805af096cbefd0cad6dc0bb5130907d64e76e4be957a117d121d66071598112ea7d02b9648cf53e57af9e7cc3c9803aab327d87c53e41cb9bbc42368d332e0a963c3385c18936ad7483a5f4292b625c844c2282f25af0c86984ddc09371ab555d57de146664faab59dfa514f8bb8d397a987bbc8dbe147efc2a34daaa712baa1e36c9c5113a7f47ba8c4a83db2dc79ae93688af7c480dc8adf0b12d7f5453e669be2d805dd6961454ba8b40c6efa961e53da19eea2243c998b504c8ab9eaa2db11b2f9b591990040954a1567074e69154ad6e618d0830d3b554fe4c99f48b51cf6609952cc9693acab000c335b98126b4b45a9f317f80a6049558fe9d855a026aefdc649d295387c530e075ccb32aaa202171c6f6907a4a2202a9c5fcf252d98328f12f927e31c596047140af9b177e0352b120954d00529a07d6b2bce5026a6d7cba01231a85ba39b1692694788c9215b69fcd111fdc8934a1ba24cc7890eb479aef01ff29161b0a7ad921bb72a8b495ffa74c62c880bf03f0bc175eb865a17ecb56e0aea501bef8e12d3025185ba4cf8edd1b0f297471d58c26516f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dcfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714 + +comment = Official test vector 85, seed: "fbc38d7614d7718e931edb850d2c6f0c5eea9ee889b3e25bd69ac255d5b91e885d93e808e66bf9c88c655dc594da5792" +entropy = 6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b +expected_public_key = 9eb92fff176a27197eb4ab0171211dc7fa954c652698c50105b5c2e9f7a2a887bfb40880f8624e1fc67b1b43a51139ac6025b9eeb60925d424bb82c58b4b617618c43c99b07fb14e5b86538d29700e1ccb4f53a52bda2ef566b20d8cce1d7616dc81398d14abd03964940c794e6100da994d5bc0bcf28b04a8971214e7ab9285515ef09a7b486ecae5c84655c9ee15255b715c3b784d9c243993171c604a3e29450728396e7572228610bb9ac04b06577b3636c137a24e2139b48db005553152c6b040cf0b2408248675eb90afb66d6105537a316c7c989746f43c3b284342e2cdb5f2183a16ce71ab39c67797112b0b907c00f6a47f17db08d924826d526cf88234a25676d82449f93b2859076978860e499a0de134a936e35f06a7802456008c23970818318aa2b55a1762a9394dda7a49ebb4b38469410f5945dba2801ac25ba39a2df819b0db194b53c4247fa5065ff99f73e71d51c22f51fc262dd2809ebcc6879b0d90004da5ba7cc9462f6c822ac8fac8ab95b769a465cd743ba2babb26958ab9c3494d329a0c736c28a9cf84f5c90c5a0594485a9b339212d01bf6910105d44109b09bd063b4f2f3b903c94dc650812ae5cc87527754d476ffa82f34f39b5462006029875712cfb1da648dabace5aa1590b5ccea82c20e74795c71bb70826ef4d0bba580a447693a42d8af3256c64ce327b370ce576b6343f2bf8fecc76e1434d5e448aa8a3b326584ddc56496704be54108f8572170c2bc39680598017641422bb81645959b8092e82a54c68aff60b78be78107e7bcacb241b09913461579b52aac5c6c8627cc033be2273580a523d4cb7979cb65d7056643856be187ddac112799559a87168aa96a18089a6c547e87da949c62b8ea876aa0192af409bfbc354f05dc08fed46904a2688fba59fb71b83031a19bc8a6350bba93552be0c01b73c89964563fe588a5b76971dacba69868b588bb2f9076532d6a8fb4316dda4c85c2945a2a29b6ead3900e50abef2b44375ac36bcb0e028a20cce58353c827f1d53a9a0510e3827cbd1383a6d18c0d22c374e2b6061c2197a6cb094ca9dcb42f0418c24a9cb893c45423447cd5eabb0b9b410c9144013543e5c3bad525377ce8073d4a5f4a22bb24874b7e21523cca731265572b487e3b42ae581a617437348c290f00ad09460aa0c7b6a1a53128e4e01b3c406a296cb35ca0bd0d1917dff42a4848ab3bc28a2a28044c719ccaac45c513ca007653bc854dbdb79181157aa17220153ca3563b21be77aceae06bcd02531ff5b7f5453db0119364dc4e97ac7a495287815b5eb512129643aac4f42b3af35afc1207db0a3194302fef097bae37bf382c154e78154b3407bbd90bb2143bc285af1ea0b1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83baf26ef19367724b1c989c39bcb4337deabf7d531fe2b3327f4ab0f6457c5f3869590c49664923993cb2b0103b8e8a41cc5793acd192a047972978a2ea1b9e354cb135f2ad8928574b2c14fbc1a4c02715292c9052b69ab2a8329c02938bfa0994c209f816a24eb13f4365af2d20240ef66f9bf6b39d54ab5d350c7cb3cd6f645379815aa3028232bc89bb89bfa2c62e351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d0 +expected_private_key = 46f47850e2b9aa4a6d209125be58806002c278a6295da7a4ffe85551529f17d83b358b243f2a622f353eb6138cc6380f8ad3340d7575e865a6cfd34bf473a3da8b9fc961cd921452d09b3209d041d6612576c573b08422715160b891a3370268468078f5464d7e5b84b3a3793f0c7cb2a0a13df37b9763cfbf054c768b1e65a00e8366b406251f812c5d428853d0e00f7bd58a8e348275461c1336c2ac6a39783a35d849aa9a847f37f50be0b95f617bc7adb28c0506c16ea3ce89aaa28a9252f0e228d0fca732289d05d9395133a82d8cb76db2023924273b39cb52b5a846f338b96c5b6f3acb41c7265a0c5b13094231f05943d58875ba7c2a6889f16107d325ad1b810a0b3c9e8928169d440194bbb90f771796856f9878158a432eff742fbfd5acaf59521e361f448c0bebd805a1b4435d0761d0448d83e1201a506a0b0a4980172d05e88d7d87b42054680cda74a386027aa4c3c5193fb1a893bec2722d55ab9b840d99cc81408153b383345192649eb99825bb4b1957326c4791a2722951c0ab67472f4841c20c23926c3c331f24c360e81977c2791ff3171c2c489b68c923b65d8ee6bd2d510e6ae97fb771bab401bc1a42935f38a0fd43ae2f8a24d8fc3f6e15c2c6bc800b73ccd8e91c592452484b44e6b2a624881064526182950349c78c7d58180b1676b5191eb6065c50596232b9566e4b8f0635a7d71927f8eb8572e62d57996ddf66cfed2147dc3451e95c034d6b9145bc0d30c915d66b1cce367406212f8bb40755091c9cb0306a490ef5336e21f82c1b7b6ccc8980da28a348815112f00c57362eb163a36e016d60f020bd12b6796c9a88a8af4e833fc4585652e76f2ff77deed799757c7f64e07ee6e6a300dd1cbbc840af561746d279beaa71dea5318aa3cb3c4c63c4a91e0fb60d6dd6abf1fb24d1b078de9413f1b0bfd8916577c4cc9e0b0c332625a5fb705e94babbe0659e022234586529a194012a6e9e7650c504c380436e1df83e5c5c9e22f79f394bc0f22a0acf114b90829b43112fdd617089c8b9d872b70d7027d74402b65058347b56074ba33fb91998e5a559d46622f5423808c8236317767a32e4772ae66ca472ec7828d682d045835ebc5e0089b0ff955dcfb9605214a3e5087f7ee57d5369abcff1be00c7bbc5b5b25a0c1d853424123c98fb330318432d324bbc7330342224baff909849d65e1d08a77e07d07cf16ce6f64fc71374eefb66bf9c742e518f2e30c480f82652b81c4ce7bf42593b990980d94062f96a7178258f31e2b90e86241c04b7b44057bf4700a040b6c0b08e4e8a6bf1cb1eef738f51ca9beb9c19b94b1cc623704a6c2455009f48b4cdd0f4a5d7f06320457670db92c7a4371743593600022da4600c56296d336a52e98888818ca10282d4767010a7abdf81bb6752048b5b163da385d7c5cb134108ecb03398500c1612a1bd563b21a0bc7b94c9719a75bf3b3e02143bf04a7e3d9b0070c4b449cb9594a1a8bbf871e595178bbcb611b466a8677905443abfa1601a9664c5f54f36dcc1ddf35381f586b4aa4566c02be610186df8493a30479f4c72aaf049a6666e806b13fd77c3b738721f81218b48984ef374babc0156f94e9eb92fff176a27197eb4ab0171211dc7fa954c652698c50105b5c2e9f7a2a887bfb40880f8624e1fc67b1b43a51139ac6025b9eeb60925d424bb82c58b4b617618c43c99b07fb14e5b86538d29700e1ccb4f53a52bda2ef566b20d8cce1d7616dc81398d14abd03964940c794e6100da994d5bc0bcf28b04a8971214e7ab9285515ef09a7b486ecae5c84655c9ee15255b715c3b784d9c243993171c604a3e29450728396e7572228610bb9ac04b06577b3636c137a24e2139b48db005553152c6b040cf0b2408248675eb90afb66d6105537a316c7c989746f43c3b284342e2cdb5f2183a16ce71ab39c67797112b0b907c00f6a47f17db08d924826d526cf88234a25676d82449f93b2859076978860e499a0de134a936e35f06a7802456008c23970818318aa2b55a1762a9394dda7a49ebb4b38469410f5945dba2801ac25ba39a2df819b0db194b53c4247fa5065ff99f73e71d51c22f51fc262dd2809ebcc6879b0d90004da5ba7cc9462f6c822ac8fac8ab95b769a465cd743ba2babb26958ab9c3494d329a0c736c28a9cf84f5c90c5a0594485a9b339212d01bf6910105d44109b09bd063b4f2f3b903c94dc650812ae5cc87527754d476ffa82f34f39b5462006029875712cfb1da648dabace5aa1590b5ccea82c20e74795c71bb70826ef4d0bba580a447693a42d8af3256c64ce327b370ce576b6343f2bf8fecc76e1434d5e448aa8a3b326584ddc56496704be54108f8572170c2bc39680598017641422bb81645959b8092e82a54c68aff60b78be78107e7bcacb241b09913461579b52aac5c6c8627cc033be2273580a523d4cb7979cb65d7056643856be187ddac112799559a87168aa96a18089a6c547e87da949c62b8ea876aa0192af409bfbc354f05dc08fed46904a2688fba59fb71b83031a19bc8a6350bba93552be0c01b73c89964563fe588a5b76971dacba69868b588bb2f9076532d6a8fb4316dda4c85c2945a2a29b6ead3900e50abef2b44375ac36bcb0e028a20cce58353c827f1d53a9a0510e3827cbd1383a6d18c0d22c374e2b6061c2197a6cb094ca9dcb42f0418c24a9cb893c45423447cd5eabb0b9b410c9144013543e5c3bad525377ce8073d4a5f4a22bb24874b7e21523cca731265572b487e3b42ae581a617437348c290f00ad09460aa0c7b6a1a53128e4e01b3c406a296cb35ca0bd0d1917dff42a4848ab3bc28a2a28044c719ccaac45c513ca007653bc854dbdb79181157aa17220153ca3563b21be77aceae06bcd02531ff5b7f5453db0119364dc4e97ac7a495287815b5eb512129643aac4f42b3af35afc1207db0a3194302fef097bae37bf382c154e78154b3407bbd90bb2143bc285af1ea0b1b4fbcd3ea373a077c6107ac2800c89f20544cb7a83baf26ef19367724b1c989c39bcb4337deabf7d531fe2b3327f4ab0f6457c5f3869590c49664923993cb2b0103b8e8a41cc5793acd192a047972978a2ea1b9e354cb135f2ad8928574b2c14fbc1a4c02715292c9052b69ab2a8329c02938bfa0994c209f816a24eb13f4365af2d20240ef66f9bf6b39d54ab5d350c7cb3cd6f645379815aa3028232bc89bb89bfa2c62e351a3c6401b7b384ec61a83f9056f3665e523a0c28d48e778b0314c1ec2a83ee9805d010e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b + +comment = Official test vector 86, seed: "1722219cb5db47374eb0af0232c856a57f026f1cb09e5a5799f4c333dd422ff6a0a67c4da502faae727fb2d45dafcf35" +entropy = 6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 +expected_public_key = 5c405485d51fb10cb0f150b9db466c53e070f5849049d225047bc47aa15f630a6d62c5b179906ee6c067fa3384a4c22748f984eb31ab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b261beb0eb4eebcb8548139bbd6a0a844ca1e4e59f3d7c4372ea8632b278a7e68b59032012c5518a8021bd5367557077c9c1b4a50944ea1a834bb61004b2cba7f6401a57839a3cb85b326449a25457851b4a2bba2e2187f040745fb608079c8b59d2b191813d51c5c3f329b1f5e40771e1b33f63ca400555ce5351cffca2ddd268d7855151618587c8b037e7ca290467e4a7c2c38290b84ab8dc4a839f57102dd559114092165b13b130b41bea2f857c84ae45c1734375a3ea91021014d29ac58f12bd5a44b91ce986e094a66089479dcac23a6275b864195df24f2d4a97f1b26b508c3a5bb89b9f0a913867c1294c252d5022d9fc60ffeb3ff3c29b2dd1aa97f22271c5c8e749cacea39f2c637ff4a235882747ceca1d95e093966462ad401510ec112026bf0fbc106270988b2c35cc7269da693a7d67052f9156d30c916ad6552eacaa3ac2396bc56668686ea8a1578e46658a71b4b7365ae56a263c783973c1b63100b1aff4c3feb64856a781334c6e83519e541511b4d581914c697ff31239dac56662a145316ac4d14e522480782c4ec52b1a2b8a85f657217ed11426a2a606c01c17171fd10824c07042b189225d40919aac5cbe05b031689b1ea61041f6091d961a8910a205e62ff21909c6b4095b270d87c9727a2b611118c84aac033ea9cab5f40efad6117f2160a56505fd775d3f415aae9271a9b2b1fd1964edfb772a9c4875f06826a49c26e93f0b1846e006468de71b98ac6fc0f81ab146236739c9a7b6c13952089d621936e8b265b50dd4016547a2abd52339daa0b459d265558a1d9b61c73e49346396b6155195c9c3a437614e68e23143f09fd28857aaea50aa808600f5c5ca33c5963cc00c4b1c1ce2609486ac4f1b2ddb7b06acb62398a32320f315dabcaf5d4a833e2a01a6e7c971ca15e40c459ef18db8452aabe1584412b4c4dc52e6004ca56b5f48555041cc828a7a6da77c435f05574e5c25efc3c6057443eb77993c987cac2363c3030d88e288f4d08966e624794078a39c53ecf273df178cb022a5fb025a2687409a785cd6c019f5761b0a3087ae91844a69c2a89c1a00b1caec7c1f7a67425b87be02d80b67ca6c7dc3b45bf425dfd33dc5a13e7531907ed6329593c333466d9628668b98422c985182f8c0952cbf5052225363398e516d23678b5320a9cca38e21c6be86822c4fcbb9094277bce80992858c5498c6bcc57db982c196b1a78c317975544ffdf33e57a30dd29a5ca4a22a918746fd9a84ee1008db920432e39b6ff182c930243cf350c6f486832a807a36c8a9242a5c39140eaa7a45bace0086a86fe36be28acec756b5e9a47225638659b250c52b564751ce8c42c39bd1046d2b6cda70b7951707b63073f0eb5ea3fc5229f816ebf4007ce97307c6607b4ca17ca30330570d4f39bf76998147060cc04b33d4b91294f85f4a717ef9c288e3741f70fa5823ab8329f56d9d0b05c996701a050a387362db09427d5587e7751131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e4 +expected_private_key = 8747252c693a0d6c06ab66071b13517e1c45abb370d26aba3fb31641a170b365c5f6235d1fd688d81c72716a3921420d228a7bd5a1c48ff445c47489b8116b7ca14d3ea78b20a7b5e579c5681187a2aa8fc900557501003fb9bead185ba9e7939f247bf1757ea66a4392095ea90239a3c67a8ca70186047d9a6b06b8887fae01ba8e556319a003934c88ddeb05f9f3b4964a6545e8443f57383a2bcdafd96c794b399296615bcb9c59f8703595709724b6a4bcad06e116f4542c4322072e3c6713015b1339512419b4daa8c87f5a8bff481964a8ab8a101943230f9527a10a604df6275e1ef18fe54a57d7544402134ab77802333897d4769ac23093f9b951d735b5623452c90270a0896ed3a81bf1191e451a4a67a4542556af78f1690982360ff1bfcff66386827df93bcd894ac8c996be6e0a29de70ccd459b9de46acc9e8043bb82d01c40e5785845ff4b0ddb8184afc5e52a72e899093669a9eb110a100a1159241bdd40612a9b1955b1752810764e7b68d89704a61442adf68108aa229e406cd10b6527a39a6b46068685b5e802cc25614492dbb6e06ba2160e930733956e7b29ab9981d4b477cd4eab880e56eb711b278f540ac204a996b32fd06b8bfcb7729660cf5125fe1626199f6285da628faf491dce2ca3bf285902350d52c0649339f31ea3ab764b90701bd647194fb27383681c13470b8d5ccb61dd74c5f666ffea7b0714c469c4803107235599c998349b5be7ab9e9dc6f01e928593939270411ee2490f16c54ba672ee03b710978760b962319bab3c2fc67cd9c2e9d4c153a8717826bc4c3d6c7444c051a61a06a2c87a1207a20754e9d7725b91077766871509ccc93f5a1fc1c20680263082801f6b81e8f319b92110f2da22f0d8c251ee4531b127c44b378da6a0d26f55de3285190ba1357012e42521cd1855252147d1abcb1582422f55091b5eaade93194cfa0be536343a282c4a948c355984cd20a7ca454ba034ac7355b02730107a71b3986fa01faa38d17e07494fb510e5526f690bfb27294fbb963a0606e140a182a9a247029abdff6bd8e876ec92207312432cc2700ec4c6a4a7037c5b612eeb2099d54872a5884e28981d794c7855590f1f1464017c8724bc92e0b644de92b5b80a573f641e4e65bd6f0396184086d6a5a50662f9cc6241fb7241d194b6d23ae6fa3c59fe60c81309ff7e39f93f72bcb0696edc771a80cc5ffc74138ac9d01b95defe7258bc555e3e28cab6a73372337efa0b4aa0c7d13b312a7313f8b63426c6677407903822aa1acf4acf4a130c4c68dd4dc47dd061ed0a4969e5ab630baa11fa0aa51133c6509c83e603425a385730aa0e07a2bac0754358c812f483f5ca6bef3105cce4cc33532116c6493f19880f693581e08999be24db44b84970c8fa4f6784d50614cdc9e626a31966acf81309ea6a730eb42011663cf10a90a9ec12f3fe133a7d02cfb95cecc6b52cc08571bd03e8315532b7c76c2040b60e9021a24734854b6a3d77cbfd087015410b7322ad5d9b04f651f895ab5bfc25f8cc9703bc67dc5eb5aede41682a17feb1b4339335efaa44a64e8b4eb0bbe17fb00875a06318c1e68c42e6ce0946a59c61700a72779765c405485d51fb10cb0f150b9db466c53e070f5849049d225047bc47aa15f630a6d62c5b179906ee6c067fa3384a4c22748f984eb31ab4cd69083da31a5b45f586560371bc99113c44d05828fa7687aa649b261beb0eb4eebcb8548139bbd6a0a844ca1e4e59f3d7c4372ea8632b278a7e68b59032012c5518a8021bd5367557077c9c1b4a50944ea1a834bb61004b2cba7f6401a57839a3cb85b326449a25457851b4a2bba2e2187f040745fb608079c8b59d2b191813d51c5c3f329b1f5e40771e1b33f63ca400555ce5351cffca2ddd268d7855151618587c8b037e7ca290467e4a7c2c38290b84ab8dc4a839f57102dd559114092165b13b130b41bea2f857c84ae45c1734375a3ea91021014d29ac58f12bd5a44b91ce986e094a66089479dcac23a6275b864195df24f2d4a97f1b26b508c3a5bb89b9f0a913867c1294c252d5022d9fc60ffeb3ff3c29b2dd1aa97f22271c5c8e749cacea39f2c637ff4a235882747ceca1d95e093966462ad401510ec112026bf0fbc106270988b2c35cc7269da693a7d67052f9156d30c916ad6552eacaa3ac2396bc56668686ea8a1578e46658a71b4b7365ae56a263c783973c1b63100b1aff4c3feb64856a781334c6e83519e541511b4d581914c697ff31239dac56662a145316ac4d14e522480782c4ec52b1a2b8a85f657217ed11426a2a606c01c17171fd10824c07042b189225d40919aac5cbe05b031689b1ea61041f6091d961a8910a205e62ff21909c6b4095b270d87c9727a2b611118c84aac033ea9cab5f40efad6117f2160a56505fd775d3f415aae9271a9b2b1fd1964edfb772a9c4875f06826a49c26e93f0b1846e006468de71b98ac6fc0f81ab146236739c9a7b6c13952089d621936e8b265b50dd4016547a2abd52339daa0b459d265558a1d9b61c73e49346396b6155195c9c3a437614e68e23143f09fd28857aaea50aa808600f5c5ca33c5963cc00c4b1c1ce2609486ac4f1b2ddb7b06acb62398a32320f315dabcaf5d4a833e2a01a6e7c971ca15e40c459ef18db8452aabe1584412b4c4dc52e6004ca56b5f48555041cc828a7a6da77c435f05574e5c25efc3c6057443eb77993c987cac2363c3030d88e288f4d08966e624794078a39c53ecf273df178cb022a5fb025a2687409a785cd6c019f5761b0a3087ae91844a69c2a89c1a00b1caec7c1f7a67425b87be02d80b67ca6c7dc3b45bf425dfd33dc5a13e7531907ed6329593c333466d9628668b98422c985182f8c0952cbf5052225363398e516d23678b5320a9cca38e21c6be86822c4fcbb9094277bce80992858c5498c6bcc57db982c196b1a78c317975544ffdf33e57a30dd29a5ca4a22a918746fd9a84ee1008db920432e39b6ff182c930243cf350c6f486832a807a36c8a9242a5c39140eaa7a45bace0086a86fe36be28acec756b5e9a47225638659b250c52b564751ce8c42c39bd1046d2b6cda70b7951707b63073f0eb5ea3fc5229f816ebf4007ce97307c6607b4ca17ca30330570d4f39bf76998147060cc04b33d4b91294f85f4a717ef9c288e3741f70fa5823ab8329f56d9d0b05c996701a050a387362db09427d5587e7751131953146ea3591818f0dde74e33983c010419218b08822da9c3c62eae1f2284801b3e47c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102 + +comment = Official test vector 87, seed: "ac139b78fd16ca0f26d6d7f9e15345c888d857b1910cf38d883339b37ead2dcac30f7cf10176f23ff34b4488eb79437c" +entropy = e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 +expected_public_key = 7e395f02d56d41b5c5889bb6b2f149425a2ac8aa06ff23a82841887de199b56c91846392a026b50e87453f44588ee6ad4a443f54d25ecae39aaf286efb47a760da01b6c13fa178811c47a0dfb14110fc6482543e8a3a52abec3a8d7176aa2868b2d46cf68538c27514222a34371c25fe832184206e5abb699d61426027a942581d0bab075a367793c81b7fdc11e2f6772c8040d271be5d07d00b330a6c874b46d26f51db8f43f22dfcd72613f8c22d15c28a2b384051142c148b07f7362eea4771959b635a215b1351f650342d2a071acb16dd8ab50539096f295e44173bcac20f3cb271a8041e3008a742057ef2fb2d78f8a3a3c252f6d38d8e85bd57a75d45ab4dc21b8033992caa623866e8989f98560de33004d3409f233020899340b2591e1a4a0223a79e20b4b85c632ce7609c0c45a0246251468c1b6c20716315a54520c5718f4c5c7066331fc7e953ed91aa5f3b92e69617b29c256657124242ae8305780cc0caf00c92896929a1648be9b47f86f144a3b12d9dd51f347875e6da935f0bd043abbfdc7b85066a7836d442872c56fdd41d9a3a01d9ac6a12531079f74b273ca129f36a7ae463f6464436e50fa70cbc2756bd25234893b50a2898345e588b819c0955e9c50072517d58b0a3e4bfc9832b727c7f2fa924ac672d4d104a8f3ab81200a624c61eb6aa7b4553aeb2084360f1c03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed6b12e8be5a6ccc74efea7cefc7a0f5ee18857250d08f03cd94cb4c455141d7aa2fbfcbe3eb896c2404bfa3580bc63b73265581d87618b206caa9468c65bb1863b18f560413d1b1d392259f37c00f7d89124c56913483513006feff89092f218fdcbb8b118b206b64f2de52be0b553665c32831bb4cba3762991716be65e6a222b30a0a5cb246207352732bc3c8ad7a2c3243c62424af222a922787f7fe44df05299da1105f9ebb0c5aa18b6c6c73f43390af9c2454442110aab4aa629c8f300dd38318c43a25d269885f970ddd8ac1e5918e59a3d53dc8a44873eea97c31f34108b893b634284d69153779230c28b2a1636b6b839a4d91b7e23f0414b111f2e7c1b3ed58613120fec37c78308587494233313950d82ce946778e044c3d245a19c29b09a80c3b55416a811af33032a0068c7a4767f05e9aac3e8b99b967f88d5281a38b072b8c4e194794c40bcd5366714525e846048e55c008cb48b5ea0c61655b8819b08fbb88337e20d63003f2453462598ca66181ace033c707c1ae9760ced165596b2b163e54934540c4f7097bdf14d29ea850b95be6fd42973436144270549a81b5f73192c2c6ac2474686a9a3ee556b6f26a9039866176026e25a60b5864e963850cdc8219d21859b5c5c3714434ea53bb16786dde8036f317c430b3bdb025e6b62c097340f1e961b90e0c5182183de05b293a05b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b835c0e2973261bdaa43e414153118b66c641f834c949e77fcdbcb59dc27089138a2e07a5b40c7666794fd8e6b97685bc4a3c2a65912c35f50a278bbad765c8c775bacf28181d61530e54ae7fdcaa2681a01bf51c0d7a033d6b005893b98da86005381f1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f5 +expected_private_key = a32b081d2579d7737a984126b05465963ac3d0fc3d471b94e30b242699ae3ee7a305d187d9371af3568d7bbabdc30ca69be166aaa07c67799dce7345b2024ee41c5a6f35733cd12efa19256ddb74440829c6b52aaa25b258bac8d950ccdea410535bb3a44a46ebc44f5772cdad96596980c32a14916cf5c4a2fa8538491f7eea270543abc467344ff098edb4762f658b6b26431b9863cfa7546c1489a25bc9061b8ca0165528241b4bc173bf17b4e7873a5081016a1c55e4bb1e7f71b849274d03e05e866656c126485979ce9660afdf3622e3051f76d02243e660a5a78c663880a7f9765df45410926a86acc7962878b4037cf2960b06f072367b476eb24b8c57924a9c699815bbeb0bb10b2a88b0c63f0171c759d59cea91c5c043a41a8155e462325893685f18c5458a0ac3e5bf2c696c8f07727c090e1d3502d075a706551c54a00a710027c52cbd83fb9dbd7567aca2b6eb809c00838e56b209e0c5aad2e6235e2c157d3659d906452f4a8c60b26f838a51f6789e42c00580e4595a5c0a12b796cb44240a4724c298abff1332bb0970a3ec475a434ec4dc2a4aa92c42e22035a4499c66827c882b542a8fb22b6b6054984fdcbd6a637583145010d89a4654bf0bc0a0c3b86788459b659a539833629c1b585a13134d766c9e8003282683aac1486a934edd3a7511319a7952b5eb7c5947b69ab5c904b2481a7709c95bca352df45e8bb87775a9cb566581c3777e7b975c629c89063c8f0e982a24d344ee8a22221a02c6538154217c453ac0ecd4bb1f820baab94d920765c4ac15972aa79ba974f3b5055efa7fe5bcb454f7ae70e1c017322a20c73ebf278054060687c6301e13b52952459c56bc8d8795044302fc9123921143ec2c73278939826682126b65c7d9bac044ae6cc7ca40f92c8ff28470e41d51895adb53ae30216b1aba552fcc14ab277a872029f3dc8d56794d842ba06770808f1c097787973b0a14280c5fbcc45c102c23821a07eea6c3abb4b52ae116f4b38e4a50cfb849177766495463197bca3197b53ab72b172c163003c9ab89721eff925f56b59373f5abd1430b0731419a12ba80641628d78d712bbb74579c0a18a4cb2aa6edd76fd7605fbf8214a00aa44e486810f3ac6e36345431c23f247f251112cb8a6c76444b1a5277b7c68afd2c49d4a81fc5069b9a004cdf0587a4a193d243bc5f16357e1b1f280706b4c16f9d8b3b6a5815a1597c49076589d5303a5c89ad320cf6042f2f819cdff04b850870e807b4f2b6bf99aa8f3fd16e95b3bedf247cdbdab048586116db7a4530c360bb240fb2964fd41a5128cee9fa6ad434b536345a49bc758d849260b78cd9f3b3e8461cbe906e93b209742c0abec1c1bba9baa05a8fd05637d26548f48512f5477b93d0bd54f6674158b2f6ea0488191eb023a641b175cc689a2f326214793228138d6da03bfe4466dc962fd2a7c57102cf3f96cf3a6619d2f613ca063a35f4515c0473140b8ec3c53b1d9974021616bca2459bc31502daafc861990c1b97ea1ab5ae018ead781a67a075cc4924f9ea364bec33ed167637f0a643c3a810914a49366af69b3cc25938e77422832b7078c6be562513ee3648758515e3c04f7e395f02d56d41b5c5889bb6b2f149425a2ac8aa06ff23a82841887de199b56c91846392a026b50e87453f44588ee6ad4a443f54d25ecae39aaf286efb47a760da01b6c13fa178811c47a0dfb14110fc6482543e8a3a52abec3a8d7176aa2868b2d46cf68538c27514222a34371c25fe832184206e5abb699d61426027a942581d0bab075a367793c81b7fdc11e2f6772c8040d271be5d07d00b330a6c874b46d26f51db8f43f22dfcd72613f8c22d15c28a2b384051142c148b07f7362eea4771959b635a215b1351f650342d2a071acb16dd8ab50539096f295e44173bcac20f3cb271a8041e3008a742057ef2fb2d78f8a3a3c252f6d38d8e85bd57a75d45ab4dc21b8033992caa623866e8989f98560de33004d3409f233020899340b2591e1a4a0223a79e20b4b85c632ce7609c0c45a0246251468c1b6c20716315a54520c5718f4c5c7066331fc7e953ed91aa5f3b92e69617b29c256657124242ae8305780cc0caf00c92896929a1648be9b47f86f144a3b12d9dd51f347875e6da935f0bd043abbfdc7b85066a7836d442872c56fdd41d9a3a01d9ac6a12531079f74b273ca129f36a7ae463f6464436e50fa70cbc2756bd25234893b50a2898345e588b819c0955e9c50072517d58b0a3e4bfc9832b727c7f2fa924ac672d4d104a8f3ab81200a624c61eb6aa7b4553aeb2084360f1c03e443ab99acb63ac699443a638ba9b8013c7aca95acebc9ed6b12e8be5a6ccc74efea7cefc7a0f5ee18857250d08f03cd94cb4c455141d7aa2fbfcbe3eb896c2404bfa3580bc63b73265581d87618b206caa9468c65bb1863b18f560413d1b1d392259f37c00f7d89124c56913483513006feff89092f218fdcbb8b118b206b64f2de52be0b553665c32831bb4cba3762991716be65e6a222b30a0a5cb246207352732bc3c8ad7a2c3243c62424af222a922787f7fe44df05299da1105f9ebb0c5aa18b6c6c73f43390af9c2454442110aab4aa629c8f300dd38318c43a25d269885f970ddd8ac1e5918e59a3d53dc8a44873eea97c31f34108b893b634284d69153779230c28b2a1636b6b839a4d91b7e23f0414b111f2e7c1b3ed58613120fec37c78308587494233313950d82ce946778e044c3d245a19c29b09a80c3b55416a811af33032a0068c7a4767f05e9aac3e8b99b967f88d5281a38b072b8c4e194794c40bcd5366714525e846048e55c008cb48b5ea0c61655b8819b08fbb88337e20d63003f2453462598ca66181ace033c707c1ae9760ced165596b2b163e54934540c4f7097bdf14d29ea850b95be6fd42973436144270549a81b5f73192c2c6ac2474686a9a3ee556b6f26a9039866176026e25a60b5864e963850cdc8219d21859b5c5c3714434ea53bb16786dde8036f317c430b3bdb025e6b62c097340f1e961b90e0c5182183de05b293a05b58dcc251d8a2911c6e71a635f5179d06d93d33d8cb332c8b835c0e2973261bdaa43e414153118b66c641f834c949e77fcdbcb59dc27089138a2e07a5b40c7666794fd8e6b97685bc4a3c2a65912c35f50a278bbad765c8c775bacf28181d61530e54ae7fdcaa2681a01bf51c0d7a033d6b005893b98da86005381f1c6e600b1787bbbc13a01210c0764a4a2578d4bf90a24704178f06a4e4b110f58aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722 + +comment = Official test vector 88, seed: "cc7152849c98d5fed2813275d32069e44824ecb14eaef425ce017448cd9a401c91c06d0f7eed6d22b7bbe8ba6c429ec3" +entropy = e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 +expected_public_key = b5d6022ef207e7629736d614527619e33cb92600a1e39a20b25a5b16eb0ec1070e5d566b28449bfb38936f44721ed428ced5768ee647a771b7d76a30c7e5563b515f5aa89ffe994cffd9277b0695049c355267b3a07c61f3c5a2c0d4ab8df76129c19f44f762b51bc0374a43e6f6c1155901b2430b2b77afc9ba4e14d3658607387dbc2d12b99ec0c0b0c2721af298a6ebc92a7e6b97bc460674931e21f68377c8303b24cae8d5ab720c79c4399414a514254603b565397857a7078b36e24a262cf9070a92c034c76614d5ab455b60b3b3388500946677195cd587942342a6fc91bef144ea412ece186a422b85a213c43fd0c361aa00698458f5c5370c6c553a9c238201754e2b2e2785bb03053e0b414e472087a0276bf2d805cf477378ca34d8f01c21b433f33b49a8b9bcf762451460558fb9c3cd071e654c250df04b6541baa278c1669bb49ca3ab4c78cc92d0137a2864bae0c904e23aa28395edcb435d9c1cf742562d603bc61c521145ca16f69192b137ee372f04402527bc557b754e187355a388410751267561a6b1f59e04190ebc604ff64a2b08b244b57abe84f18938c5a9ecdc972191bba33915c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f421281b5763865c584cfda6aad7482d00a0520d947fddb173947865fe178f9800570d4b2b9529a42a514a8691c8531a271c18e5f84380c20cd9a992051d29b5be76b2235b511514904e3b284e8854556334515162db1b09894b18a3127982269509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bca04e2cd90db634a3d52b734e224c4c60ba3c8240d7b2755ae5892a09a0e7ea1b2424402c45a0ad59563ab97ed906a1a15b8c4412219203ce6826b91dd00ad602089ebc5163b416c0d02009a7a5440350a00a7b49309ce39ba26df79ece038f23f4b4300c01287a51f5fc619eba04ab1b78e6396bb23c1cb86a0f3bb11f7d31a161a480b8f33734cc63ea7219d76bab759b1ab3405ca61b535b893b1bf2b678849751a6a4f18923ef44470e543924d0c462d8a078782b80241334f547d2aa474d95b8709747162b228993ba15a0c4fbd8bd662a1a2f01cfa859ca723a011949823fbb55947b9c27c2bad547b0e6d29665071b30f3c8c536651e6437c0d4a314ab38a8f707928c0c2b864a3a67397a936dbfb98fab2c0935441b83157d05072891a43573882be97686534c8bc7015ac267b75f0a79c6991cb6c96c735a4bea90acc9bb6ba1b12388f0821a074018909f76944d9295b5eff73e70ac1b0e1644e3a40685305f8a0626b2f05969fbb4cae07c61f6213159b3471654a88ab58ec3a648f2944625820f6592c67126bc085dce216fa708089d4947ab911ac14c00e53782a01580fd967594e0b2b2a3272d590aa70c7a3f419accd33c1b1294d21242c739a3e8e577316c23ebd4b4c4d0577b2bbb12cca71841b54c0b76729320bce26dbfe5bbc017c92491762a6c938d4bb0099aaea190813a3a78e5685d83975050d719d6b6a80ac313d3018d25b9054b5013f832c1353401e6cba3fe527b8d2906871b79836cb35284725e733d8fb60e6a8410e5f61428a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985 +expected_private_key = d1f46e67cc5aea63ca9ec413938661c2f8156cc79e10a64174774545b597e91a8cadb58deb15b27f343073b071873870bf858b5fa3ac3689698deb68c570406972210c2b9909571a12753448e00e6a0c165a101469828e8f60a16b55478c8899d9a38c1751bf220a60a999b0d2a429b375137db8bc9b85ad5fcc073355ae630100f8fc68ebb8534135590ce22d0a0672ab54936c8665aaf476b50293a32135283777c375767b04547501a53b72a14d3c4de4e001d16b2b2b598a22d784a3711c39db183ac82cf895b242954b41c713bf464464917d6b608d21b67b3519a6df161ad237359e262b95c6be3a8522b9248346785fd0db03cd083a21092f4d91af156b12f4c9c77c11cc0b68adbdb813beb21289743758f8136661704d0c5ca9302a064040334017d47815b7c35363f5c730298670536c69c122cc91cdfd18783efc4c39c8c29cb1023f1488a7469f1cfc1d7ebb3d1ceaadba3b07310000bd89c043290abed896e655cb1f43a1c7335aee30044d9652e6d3b8e394218f63072c7050a2984032c45735a3aaa4108aed8b9a19c13b9bac28ccb123d9987c45b91e89b7a949b5b4ad56abe4237f21dbbc53ab651bd4b703069f82133c54acc1aa415df9961a4785337535869fb758cd04b798907e36197ea428c66aa516f602404e87341e154a0e09c881725cbf00761fd9645b658d97d21f33059e4a898deb0c826d9057ac302663897d71567117fc4416c860775b026e51a52663711868777d542f1224b277ec005f2bbcfc0c84146591cb36caba82692b010de229797cac57aeb64af446a896527bed9b3e55539c0f6a0e9eca5953890b95b0b282c3a4c46a44a8705a54a8806ccc0d3c736a20d34aab118813651d85f12906958933d69679d0457a4817dc83b525ccc63e94c1bcb1c869cb3a0bc46d47084481c2563754aa8f44682b870ed04996cb8886f43b91ac8767ae12856ce5b85f55c8802830ba1babf5797d0da723eec24616a195ac809371d93f89b19c874c840ee9c39e7370ca561b6e91552cea47f1d09c9cf633e7cabc9ef85f89d01a29d9cfca8143bb05c3015b3c6035afdc45ac7b08b5406566bf864657bb3a82322793906462c03c20969f76c2c8c8ea2622a373c3e40164a77055ebae05787965b60a861c09658c32d4194dccd7ab1df87826590890b1785f0385b965b5ab3b870a0088696a783b5c7a69962b86f789bd43588705315258c117c4313198af42e2b7fe39894a86189ffc4e8c6bac5e7a0f03d86d18089a6999972f309a6debb365781f64197165d259bda98c7a920a9e790bddc587e7c08040d649b8b08fbbf36d1904970354410bd77b87889668566cdf4a94e1c65b04d33c269c5152b049850857308ba1310283a976a31db34722e97c97da85d14372e14a8a95bb45c63670bd7712686200d451cafe599ab0d3a183d2b0df7b8fbf0995042ba0ce682eba8b71dc6c0744262c75b7638b51b9c4931d4f7c842328486a799d06027cd5cc75e4b1b6816c2ad66b86ed047ef978184bd344c00aa1200432c5d142246b883b5b85ad5cc8f8fa994f4a790f3b6c201353f77aa9b7e9bb195375060282b7da42ecd36295fa55f8b5ce94b812bc421bb5d6022ef207e7629736d614527619e33cb92600a1e39a20b25a5b16eb0ec1070e5d566b28449bfb38936f44721ed428ced5768ee647a771b7d76a30c7e5563b515f5aa89ffe994cffd9277b0695049c355267b3a07c61f3c5a2c0d4ab8df76129c19f44f762b51bc0374a43e6f6c1155901b2430b2b77afc9ba4e14d3658607387dbc2d12b99ec0c0b0c2721af298a6ebc92a7e6b97bc460674931e21f68377c8303b24cae8d5ab720c79c4399414a514254603b565397857a7078b36e24a262cf9070a92c034c76614d5ab455b60b3b3388500946677195cd587942342a6fc91bef144ea412ece186a422b85a213c43fd0c361aa00698458f5c5370c6c553a9c238201754e2b2e2785bb03053e0b414e472087a0276bf2d805cf477378ca34d8f01c21b433f33b49a8b9bcf762451460558fb9c3cd071e654c250df04b6541baa278c1669bb49ca3ab4c78cc92d0137a2864bae0c904e23aa28395edcb435d9c1cf742562d603bc61c521145ca16f69192b137ee372f04402527bc557b754e187355a388410751267561a6b1f59e04190ebc604ff64a2b08b244b57abe84f18938c5a9ecdc972191bba33915c653a84b1a970aac7343ac98bdb7bb877a3170e8b1e8693fa5089f421281b5763865c584cfda6aad7482d00a0520d947fddb173947865fe178f9800570d4b2b9529a42a514a8691c8531a271c18e5f84380c20cd9a992051d29b5be76b2235b511514904e3b284e8854556334515162db1b09894b18a3127982269509bbc5e8758015a5b810569e544bef9398f7d195a50a958dd78bda187cea0b7b2bca04e2cd90db634a3d52b734e224c4c60ba3c8240d7b2755ae5892a09a0e7ea1b2424402c45a0ad59563ab97ed906a1a15b8c4412219203ce6826b91dd00ad602089ebc5163b416c0d02009a7a5440350a00a7b49309ce39ba26df79ece038f23f4b4300c01287a51f5fc619eba04ab1b78e6396bb23c1cb86a0f3bb11f7d31a161a480b8f33734cc63ea7219d76bab759b1ab3405ca61b535b893b1bf2b678849751a6a4f18923ef44470e543924d0c462d8a078782b80241334f547d2aa474d95b8709747162b228993ba15a0c4fbd8bd662a1a2f01cfa859ca723a011949823fbb55947b9c27c2bad547b0e6d29665071b30f3c8c536651e6437c0d4a314ab38a8f707928c0c2b864a3a67397a936dbfb98fab2c0935441b83157d05072891a43573882be97686534c8bc7015ac267b75f0a79c6991cb6c96c735a4bea90acc9bb6ba1b12388f0821a074018909f76944d9295b5eff73e70ac1b0e1644e3a40685305f8a0626b2f05969fbb4cae07c61f6213159b3471654a88ab58ec3a648f2944625820f6592c67126bc085dce216fa708089d4947ab911ac14c00e53782a01580fd967594e0b2b2a3272d590aa70c7a3f419accd33c1b1294d21242c739a3e8e577316c23ebd4b4c4d0577b2bbb12cca71841b54c0b76729320bce26dbfe5bbc017c92491762a6c938d4bb0099aaea190813a3a78e5685d83975050d719d6b6a80ac313d3018d25b9054b5013f832c1353401e6cba3fe527b8d2906871b79836cb35284725e733d8fb60e6a8410e5f61428a3cf9c25fd45802d5699f33205a71d6404704483bd2c82e92ba9457926a45bfa0985149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0 + +comment = Official test vector 89, seed: "96d9a06f88ff2c2036fa8e914b89c765e4a510b468dee40f914f78858c811857efe9fd0e17c0048e7389e8d996b7e2b0" +entropy = 470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a +expected_public_key = c55170fe0945513748c0ecc9098a02e9d51e44acc267272633645ad562816d479466b54d2150afb682b4f32265f1f4bced21caf7c7980105b08056cc4192bfe0da9aa5e00864b0a34712204cf6ae82dbad360a7c840b4804826c39a59ae029056c1b2542b6a589eb47c14a70acd1731bb0a4d657656915b91d696b2f92afd82245945c7b77958a5b6a3b6cbb179ab83a0f32591b757e8b68368d6a5ee63490604aae70ea7fb4619c91a455429a6b195214bd28bc717385d3cb8235991c05088c7939bf852125dafc3bc368479165438092b530bb2b869246988b8f85425a2a523ed108c6d2f54358580944d64d801078a4b621f58012f9d8a17a92ab8ad43821e24e2f87bfa844abd0c6b08650ab76d5397f2cb0060b31af689fc8612249d46374848f496b360e733fc991809da804dcbab14030a4bd18cfe37b41cad91a66a263437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524c616babd17a8dc7924f37345dcc32de04273c5a0ac038a133ba01ce2481ffb57ba153826a7cc4123570293c82082b6a75fa05031cc7fdbb9031e10ca94aa283aa26eb3546f894b646b9a85afc5df3b513db522efb340287c64492aaaac5fc25547129b56b9541eb0912222c2e60a11b9304692a749bb174cb47679cc294253b0f768a7872f698c23493fd908c9ff95f9275551b947bfe84780f86c1e0bc105f6cb7c9430369b58bbb07b3b0c87d8541618c76a43d52c98a08166e052b4487177ad222e6a002f7fa3f3601cf1ef0b4c02ab550d76447eaa695561118a46301b544b493c368b5b77ab17c5af4543fa6a8c682a46af39ca48046b1529684a53d0e492e1b8596f55334ade15591dbc4b411537c88a5113458f187a6d77278675b0c85bb017416b6e9543fa1b924b631ac1ddc5556127548fa8ce0c90125139bdf13428e2c7805607a44251a5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343dcb062ea3a039e949a7f151c8900484368f1cfa385bd13cf55685bfa4b959f8634ed7c437fc9c044b401683cc7482722c98583de24ead414c1833858be987672c557db87aefe4ce2db8a676d14083462db35862dc0cae95f88ec1f59426fa2e24e9cfc54813be07c98f78a87b9703276b455e15474d7a283d5738d4b639369077e7790dead3336e1467c871a571080004a91162fcc31d2912646a9406902248fbbf28dac4343b081c327743335b9efa4b7fd13d5177064a5b6e8065b64d8c6580b47e6472c8f5139268145ba7a23a02f59acf680692b20ec2dcc087a99be036bf7e9c8c0df15f168c508ae28e33d951740a9b0f0321e35cc01328b7ba860592b566cb369b21f51b7ae583d26652da729f07f5b8d59caec65aae42c7c9cbe73c68504f26670bedc542fbdc67a95c9f2da1a08e559797170ee63147a4688c8e101e5aab48a4d1862506cfcd297c7ea61a9ed4a54fd3a28380292fc1570fa2ae43920b0e940675b60534425c69f35bba714c88b3a6c323090b4c56b7f89963059f8ccb0994373fc1344412f694175c2eabea110e035bee6abf546396d79472eeda164bf49350f54c2e75754f502de4a42721b37974a8266c49b57c6837b38a28ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd24 +expected_private_key = 09d0009aa9878c697e2eac9cec9675a9570660346547d7aa8d4548e3aa917e238cbbc10c389445d15714b237566cb44132d6983c9610e779570b74482d5ba2742a1bb51c68142c1680b800f1938795367b6d8a56c32a0d77922c78116643530aac01cfb2692f4bd6bbde615a3335b397487db8a1175a043719ea58d0dba627d7c8511468b34442879cc227e6b39e084dbb68be71cb988766114a80b1979118eca08217540f032966688c99feaba06d0a0a1e701deaacbcff9c2f2948a209ac8ee505c85fe0444b5c70d067100b63cbd6d98f9aab73cb06c97ff31d7aa0ce188707ddc5c07d495b27957b369055650abd5d9b9f75761770920dd0b574a5841c3bbc9f6f1ab0179c118c7a83b2934e950b3dc732c84264c66fcb0df78975fcab5feaba4e6af97131696a0cda1cc9e2c40a266fbe6667c1abb361f063103311a792b95cc525ff872bf3f394ffb48b30b334ca02bb32a901e3478f811505da066de6a5caba425df83c27565ca48b16bb2855a797a72dfd57615d5117b24374c2d306473a349521a8107790d268ac6b5813c593cb9e8621f8c68fd2e8082c491c95c5ac74c86dd37b0a4ea0cb66aa576af50fbdb0a31235bdc9e8107f1859acd2674fc72c6669a3465556f90269cc30b0a8f53563378ee016a7abcb5460d5371b01754bd7373c2314e2a42d98636112f3cbe0638e513b38d4850afd6a1d3d485308181febd88b75f532e4541965e0bc592885fd1c1b3108c33f74725850617b526ad4f2c8cecc19b0a0ade15057c90ab086c26cb014bff92988903bafefa3c4c96ccbcef178f988a40d339db324257de69a119125c52a4147360b1274808299446ee768680170457acef18814559996fa96b418275e031199e0d578e86c946381c369ab839b1a75e9d6845c98aeca24253b3b0f00ec7e92cc6f6a40a4d8b04900ca3e78cc7a5c51886e0901a908bf0a08947e3b524f1c606b055451ab6eda2bbcf832510b3075e2cb0ecd493b71102f4ec69565f96651a3a2c3b738c2d55805798253e055dc8508b98822e6803785130d22e494b50025b0ccbc69667013c4ce4a140c2e9ba928d41d7fb5237da8c5ac0310ef5007b2b0c6737bc17a747c5a2c1f3c1166bc2b0ad7aaab1d870e54694c1ca293665286c4eaa35d34bd6ea7aacea04871c257cf63641264aaa0db4f65337274356f71d02310a57e44d23ec6b4185bc5cb45a65d3b592af3138216332060264a6e53702d766d0f4a0f14f70b75b780688591cc414283a59ad2f84d665354d71c2aaa1c278ab6c8ba902283b286f82761906c9b2796595bf5ac01455ed2b43607207a30c949afb1ba5c50659143c98237279003ca820b4b5963b0882a088ce09c99f4a6368971a7d6885237bce28580e2ec483fa305fffc0aca173a89cc41727a55d4e29a8c410b3fe851b3d58b58c31920759ada529da162cce47618b2f715f3658d71f5455365c67b04748b371a5a96b75f342cc4c031c713c04d2b6cdec0cc92b7596bf4a2a0c91537a0c8174b3456489d2db70d3af2995c4830245120e9411e92ecb2293700973386983a0c6591cd5eaa34d5cc00fd672d20a604e78696d5542646c120e02c8dc5162630e71465accbc55170fe0945513748c0ecc9098a02e9d51e44acc267272633645ad562816d479466b54d2150afb682b4f32265f1f4bced21caf7c7980105b08056cc4192bfe0da9aa5e00864b0a34712204cf6ae82dbad360a7c840b4804826c39a59ae029056c1b2542b6a589eb47c14a70acd1731bb0a4d657656915b91d696b2f92afd82245945c7b77958a5b6a3b6cbb179ab83a0f32591b757e8b68368d6a5ee63490604aae70ea7fb4619c91a455429a6b195214bd28bc717385d3cb8235991c05088c7939bf852125dafc3bc368479165438092b530bb2b869246988b8f85425a2a523ed108c6d2f54358580944d64d801078a4b621f58012f9d8a17a92ab8ad43821e24e2f87bfa844abd0c6b08650ab76d5397f2cb0060b31af689fc8612249d46374848f496b360e733fc991809da804dcbab14030a4bd18cfe37b41cad91a66a263437b7ddc2484ed55acb16ab95a1a8c9345a898e89c37248f9768524c616babd17a8dc7924f37345dcc32de04273c5a0ac038a133ba01ce2481ffb57ba153826a7cc4123570293c82082b6a75fa05031cc7fdbb9031e10ca94aa283aa26eb3546f894b646b9a85afc5df3b513db522efb340287c64492aaaac5fc25547129b56b9541eb0912222c2e60a11b9304692a749bb174cb47679cc294253b0f768a7872f698c23493fd908c9ff95f9275551b947bfe84780f86c1e0bc105f6cb7c9430369b58bbb07b3b0c87d8541618c76a43d52c98a08166e052b4487177ad222e6a002f7fa3f3601cf1ef0b4c02ab550d76447eaa695561118a46301b544b493c368b5b77ab17c5af4543fa6a8c682a46af39ca48046b1529684a53d0e492e1b8596f55334ade15591dbc4b411537c88a5113458f187a6d77278675b0c85bb017416b6e9543fa1b924b631ac1ddc5556127548fa8ce0c90125139bdf13428e2c7805607a44251a5f289be4e3a2c3c95c5b5cbf7c87b4a7d87a39a44b672bbe9af8343dcb062ea3a039e949a7f151c8900484368f1cfa385bd13cf55685bfa4b959f8634ed7c437fc9c044b401683cc7482722c98583de24ead414c1833858be987672c557db87aefe4ce2db8a676d14083462db35862dc0cae95f88ec1f59426fa2e24e9cfc54813be07c98f78a87b9703276b455e15474d7a283d5738d4b639369077e7790dead3336e1467c871a571080004a91162fcc31d2912646a9406902248fbbf28dac4343b081c327743335b9efa4b7fd13d5177064a5b6e8065b64d8c6580b47e6472c8f5139268145ba7a23a02f59acf680692b20ec2dcc087a99be036bf7e9c8c0df15f168c508ae28e33d951740a9b0f0321e35cc01328b7ba860592b566cb369b21f51b7ae583d26652da729f07f5b8d59caec65aae42c7c9cbe73c68504f26670bedc542fbdc67a95c9f2da1a08e559797170ee63147a4688c8e101e5aab48a4d1862506cfcd297c7ea61a9ed4a54fd3a28380292fc1570fa2ae43920b0e940675b60534425c69f35bba714c88b3a6c323090b4c56b7f89963059f8ccb0994373fc1344412f694175c2eabea110e035bee6abf546396d79472eeda164bf49350f54c2e75754f502de4a42721b37974a8266c49b57c6837b38a28ca489f02fa05307d7163b35ba6a4c5024b70ba27db0de8d64bb8b55c83bfdd2429b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a + +comment = Official test vector 90, seed: "d26ce360d399bf7b89dc364aa7ac06bb513eab8f527383e93e30727edc3f22c262aa0ec70257b39edff0630dcdc1b79a" +entropy = 6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 +expected_public_key = d3b1cdafcac7f6d08082da095a7658b3a45f7bf717d4b80a3a050a04cb23e01103ffb1731b2c35a9dc23c4341976b188f5226459a02d348bc9d2064d574040147b41612914cfc2954e4190905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca662024335a083911aa53828d6d79c948425422c32ec471c2fa843b54f6731fc401475612a135aae4b146fa829871c0654c075dce41190483c3ef60b7336200a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0d402147a08a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb3f184d7d6ac6ef64cdfb89d1ce66a059a4659d8137dfb3c95cbc9e8d86e064cbfdfa50c68130a8d82258407bb7b926f7a802b53209f3ab78784102e88fb91e6311d496251f7b574aee5797e881ba1db16af40281586267d826c0f33a0518c26e6533e19ea0ebf29474a131d882a189ac03b835c16c34c9ae7a1c4d9f5159f85b8542284e0409dfb0876fa6488e6519867b5c53896867772210e95399a1733d2e78532b7651ca9704ac063df086cae4aaf65150093f27054f34e2849449c7680ef1ca1a0ac399a01a9b74484a967592ce85086230582518414c247bb7680abfc2a04a35a20a851b73548a8e4cfc2b84cb5ec24108396c28498a6614790d56bf8d1b9f9e40bf574c497218eebc06217c9bd361baa5d0715e666c2d3d299346a79be0bbe4b7ccd49f948a60438514129c126aa1f3875718922c5124728f09fe5437ae83194ddeb81f0d744fd2b9b59fc223e2792501b4932924facc16c1e5444dbd6a823016b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c59910628c8ca22b1138d884842c387b594b544e5d99784b06acc3b5d80ba81cd34739a20af11f7735d645d9ff25c07f8af9b5902524a1953ca2a58d6b796e3695a006ad6c703dd161c12c01b9bc995773c5d2ce59470c765c3f5401cc07885c77bfb3c15d7f766f0ec7cb3f601dbfc210d599093a21c87d82002212b06898a5a878d4ee913eb451dce14a1bc424838d4797ed14d9eea2473b304d6624f1725c820751a9d313cbdc79ac9a26548587fb41371c5f48a4da04d37ab7189685aaa054853f0491a0388ae4b7af4259969e29eaaa2b2eb9503518c7c53ba0e6bd20ea8355a63f1c481eb5e662a0b792014ae4c0981274d902759af794338072a839b05d9d42c1ebb1a3da33b54066d1a63024a3b1d1437b37a83bbe816075cf416275a6f58336905937105e63a1a017f87911cf0b41daa41a5dae3856a606e2a9333176628198b49d2517f54a9182e4ba877760517dc94a079538822251204b4c4a2382cc7889bf84923c09072f86bd1c5879ecc3a37678e6d031568c24012578dde5ca01005b2df71a4a0b0455a03afbe7c366bf1b086973038fb5debd793a303b4c867b611772733f66574cb0d7c303563c389b2f1b46e98945a94b142b2b0d647521f4b58f12326fd86286a448909191bc600bc7578b0169a45c071c77f280c583788f9c2aa1200a73431ad56d23b20471bb67a627a594ba9922b1ffb75d2d030432a954c71235a9278857c3010a8a8906c070b77060fb831842140770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdca +expected_private_key = 96d9c668915384c2847b7991e5f557949c99a3d46a2fc9ae7448a229a89ef7f405c2911777fb1e2f44721be8cc326a80e524486a16a083527e22d51e4ef624b02625fd6a857bea2c0590a3a4e39f0e041b7284bcc501201842345ed5ceb097a5a5f730ee53176f8acbf9e03c6dc4a069718dd64c47e1d17323d29acc630db2da9922804802cc768070245380cec6672f6a5a9d14e4012bb13caf8c320a320ed63b0591087a0c5a76ea29b57d5c997fdb372e9a57e3f4827a2441cc485718a421d3c45bd0426a87589362e52953822cf785802b2c6aa441adaef93dc6451ac68a9867c9b9703abedcaa540146ba6dd8acf7dc317a82a4c1396267032fccb53be9306e20e4713b82842e03b7fa984e5827c441e293352b2e2a51566eaca8d9c4206000655f761729020f7ff9b230d6c4b986bc94551175a8acc7e2a2c174c500666d3cf021a9b40f1a465447291f920865ad16240309b5c838a2ddc5beb8aa11bf987aa9d7c082e8c55c63ab01d0664e545e505b4aae50606136b6b01499a5ba10174852224ac6bd242d5d21758c4342f9a02a3d46a9a845112adccbb73488cfe3055cac398b0245c467b94eb342e1845969d70511bc7100f886308cbf21c13840bc17626ac93dfcc4eb22ba18f62b15b521539901166598f25555c32587637a341017885af1a6d1841aa1c747d918253e1c873c2ccf292bad45805d8946b00dd23cbda03878f66357d175d67a1b743c1e5428ce90661067011874b062e9ac8a0f726b55b76627c53338549c3f2605840a11d5606acd104bfadcb51253af718835826628235878d6160f15033844d76ae946ae6c240053c2ad6c3a3d72e721d9565a6c79b56840cc5a878c6a4033bb9c88dc43b130348082e41c269cc0d3b05ffe356b5695bb01c95f8aa9c30e50cf31f11419e13acffc7192b75948e06a68458db80a8f71573b6edc1513aa5b060cb77b12c62761bc188159a49c95180249b3e35c3100635012637cb9cf17ca9936787aac954bcfc655aec8b4215861a7709f2846a1c14889d0384591753e3f19cad2236dfcb7b225abc430a7b61e6018ab30146d60a6563b2f980acf66186fee70a458750cc62c433e651f447ccef8a773bb2731a866832ae535f0d82e605371f6b35fd6fc1188a52080c609bdd8748c321ca37190321b286c849d35224bb5107d83e2827ef0c63859133852630b237247aa8c100678e43618289239ef19c99aa6b9156704643285bec89f0b0c21f3a091e2063e5d3029f52c33af97529e701298d3961f492e6b731d4e2064d034533f4611fefb64f1899ef563ad71a52e20b199f0d80c557cc8cedba3cd1746d3a6ac2e697637f08a43d681ece3769c8980c76a26adcc585eb1194d28ab163aba5563a5c7985720248662bbc21470022ef4110b33b6b8b744a80ab36d0a9b0a7988a0c98c6a597f8cdc76791c467b0cb53a020928f7a55981b520017bc06b36d10a21433797c15124e0892a81230bd6bb4774d46f73b874602588d3f8966469194041bdee87ac54059458b19724949e7998ae8018755d491bffda76a70a64eff902a4281734a7484037c739b7bf71b658b779cf6370420d2073fb820bea1b1df29c3b12c54ed3b1cdafcac7f6d08082da095a7658b3a45f7bf717d4b80a3a050a04cb23e01103ffb1731b2c35a9dc23c4341976b188f5226459a02d348bc9d2064d574040147b41612914cfc2954e4190905446e5ab8632ec96145b917dfb4a9dac62b18cb0120679e739901d9bca662024335a083911aa53828d6d79c948425422c32ec471c2fa843b54f6731fc401475612a135aae4b146fa829871c0654c075dce41190483c3ef60b7336200a4a39cfb6787ac09ac85f4cb3dbb494727a20acc8a1cc9cc765862b0d402147a08a5e4aa6e679d482786910399bac7a36efa477236b1a01baf452badb3f184d7d6ac6ef64cdfb89d1ce66a059a4659d8137dfb3c95cbc9e8d86e064cbfdfa50c68130a8d82258407bb7b926f7a802b53209f3ab78784102e88fb91e6311d496251f7b574aee5797e881ba1db16af40281586267d826c0f33a0518c26e6533e19ea0ebf29474a131d882a189ac03b835c16c34c9ae7a1c4d9f5159f85b8542284e0409dfb0876fa6488e6519867b5c53896867772210e95399a1733d2e78532b7651ca9704ac063df086cae4aaf65150093f27054f34e2849449c7680ef1ca1a0ac399a01a9b74484a967592ce85086230582518414c247bb7680abfc2a04a35a20a851b73548a8e4cfc2b84cb5ec24108396c28498a6614790d56bf8d1b9f9e40bf574c497218eebc06217c9bd361baa5d0715e666c2d3d299346a79be0bbe4b7ccd49f948a60438514129c126aa1f3875718922c5124728f09fe5437ae83194ddeb81f0d744fd2b9b59fc223e2792501b4932924facc16c1e5444dbd6a823016b3afcb46ef59ceeb49728ac541bbb6bb64b7e196c59910628c8ca22b1138d884842c387b594b544e5d99784b06acc3b5d80ba81cd34739a20af11f7735d645d9ff25c07f8af9b5902524a1953ca2a58d6b796e3695a006ad6c703dd161c12c01b9bc995773c5d2ce59470c765c3f5401cc07885c77bfb3c15d7f766f0ec7cb3f601dbfc210d599093a21c87d82002212b06898a5a878d4ee913eb451dce14a1bc424838d4797ed14d9eea2473b304d6624f1725c820751a9d313cbdc79ac9a26548587fb41371c5f48a4da04d37ab7189685aaa054853f0491a0388ae4b7af4259969e29eaaa2b2eb9503518c7c53ba0e6bd20ea8355a63f1c481eb5e662a0b792014ae4c0981274d902759af794338072a839b05d9d42c1ebb1a3da33b54066d1a63024a3b1d1437b37a83bbe816075cf416275a6f58336905937105e63a1a017f87911cf0b41daa41a5dae3856a606e2a9333176628198b49d2517f54a9182e4ba877760517dc94a079538822251204b4c4a2382cc7889bf84923c09072f86bd1c5879ecc3a37678e6d031568c24012578dde5ca01005b2df71a4a0b0455a03afbe7c366bf1b086973038fb5debd793a303b4c867b611772733f66574cb0d7c303563c389b2f1b46e98945a94b142b2b0d647521f4b58f12326fd86286a448909191bc600bc7578b0169a45c071c77f280c583788f9c2aa1200a73431ad56d23b20471bb67a627a594ba9922b1ffb75d2d030432a954c71235a9278857c3010a8a8906c070b77060fb831842140770acb92e856c8a95e163d5181caad6a478ac9ae82ee27f7256f4d4cacddd43f45cfa4de4dd067cdcab990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5 + +comment = Official test vector 91, seed: "c5856298c3cb6ac9787a0f30938537ab2635b96f6d19cc9522063360e7a5c88e644929d2879180e3e5bcad2422b7cfc3" +entropy = dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde +expected_public_key = 112b1dd09313b9a25b7094700639775f89b8d0314eef0186adf7ceabac36cc9292c270717f27caea51b1afe1cfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad4841b229fb7a17bc213b969935c672d0993a94ec170bdc8b7c800e66bc6514f84fbc81c7d1c9417b79a82e5b3980acc792a19c46d13a2e75a3af791beb401f7555793d94c0ee1b9e98a5b6c52777e537bfb287268ca9524a4438ad87a0e85279e474c5be7740b7867d8b04781a2436a8d343f62274e236c736dc3c59d5b326563b9c86798ab14a6c9a0e67b36db89a82af690da7016418ba2d6c435e39095bb81a0e49c01a73a31ec9159844d1a3eb233d16b932919421e6a342473a71de629477183e8f34b2b7c8abb7a3b6e516107cb5229d780b93417f9bc94c38bcaa58f34dd88835308c742875cccf4928122199cd932148f48a94c5c2252295890bb4645761d3c2c0f33ab3e1021aa56b573e9c6fdac37c83f678b97148ce573a244b0487f3cf771bc7b6a13fe53a6ba58854b87a67a6a17d6a301c85f7c061071b4ddb27b3f404dc402ebacb8254a0568d48b2d299bd831188886a65aea5cd8d987f6017a2f4392f455c2b4f9b63e6cc1a27ea38f2588b0f8086d7a5c5e4b05b76d2b8918820cb8851704ca6d730861b512fefb0a76b61401e23b01ea710c5e3b73fa716dfa6408a635423c61372592dbf174d6d811eef7c4d885bca5fe669233a141e43810ad10235cb59f824728bd7acf17765bcd354a493aa60438f07d266d728b640cb07d50275bc2605fa6c964614b2c8143b37b184f3c30668662149bc18c6038706c12f0d31b896b69a7d588d0004497e4808d8c12253987f000168ea758a5b32c195f03f23a07c5a546a6607084cf79e073bc6cc1cb372e385ca827c490a42d900035bf735c6242031b8332bc57765ecce4792706f1cba0c7cc390e7bd3595ab876c4e397c58fc325c9607b0ee39692c31730eb4744e967e7ff8139fd1a545622ec870516b2925628ba782cac845b2429c3cc0ebf7747f414e8d35cd4a91c959d2276404a5df4790f4363104e6a0d1d60a48b65bbd92b417b51a5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3c31637e14c5c0279cdd6386e20ca89a53671fb2f04249565491ac2f900ad380d1a68b67693b185f26a232aa1b43503398002085713ca4b2f94cbcf6e837b020404b7f519a2b520f93b901943c918393f26061346a0193ce9ba8a48b5c4b01b0efa231eba0528c5b38cd32cd5d22586494734fa746b411759303a51a12ec58b03fc99a1edfb1cb01375032054878a6ec9dc4425945aae387e7fc6cd399c90049854cf51b3db690eb78a0a2db04d05102dacaa9834620aba427b5733bf1d1693643c88bd265af0280ecc66344b81129c491b3998c6c70ccf03257c2d06115b72aec35b4c8774cc7936c578b29fb3b0a5c66709363b73f41b08db919cbe57ad817cbb5df62b7836af6ff4ab8cbb07c9fcb7e3d601b2117e6a7242abb24ea96ca867b597e9e9b45c01aba9b54d2d323df8b38d3d37b72c2790e1041037355f274cceac2714a92955b31c55d4903a85bca55b2bc22c536aab22557d912fe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59 +expected_private_key = b1c127d24808fb2b9922332832131c4fd67fe8a1a070ac8d17100bf9f6291efa0bc8114d98f65c8f4abac3ab17b4241deccc37688b881bcb68503b54379838bbc100b5bab306327e7965b694644c470a5148666c7fa89872d39aff60bc533c83f280abfbc26f073331ef40b694ab25feea5b2f55196798b70681caa21537dfb5746c66129775852e5850f57c2db2e8a0e90530a57b387b1c429101d04096c3e0bb6e9af19f83b1b0b74c47bac678b0f2269798573fbca5d8e687965b13e495827adba63da8a17564a3e68037b3a4991993401c1c6b149895ffbc03760c13595035a713140eb7a42ff6adfe6bb371c9af5a686ef858a8fb7a63fa137492b53305685205b08d44a3ac8f8948f2b7bed9cace27ab6265722d8f2950e0c9ade053a4c4ca8e3f80a907a39e33db78e6065fe9dc050a5a730595ae5ea32e38c512edb79dcf345f1d9c238a1732c552ab8db2ccccd11822972896b323cc43aa03633617f82e89d63d4a1003cf9c5ce3379b1d53a63eac57adbc91510316acdc30fd74a1a2e6c23584ad1cb28444f9231661079b0913e20b3278d8a2e8b18556f336cb750694066b6c82c5d267a903b624cd440d8e187d9e438d178c8394706f016b835e1522ab6904f80cc24358b7dd3bb271039acc174164021e8a522fac473054d5b4cb3bc64bb107c6b637cd6360e312a85a3b1e3d2b64436a87e81016acb763a23ca9b7463023148b0c4888bfb18d9441841f723b9436b77b09c79fc714385a3ae97b5bde0a2a0c541dcd2b668c696281389ec270bc6d088fc42506cec85bcb4b611342af0a61b1b9d75e0df43be293cee6eb0413363716ebbc48ec6c361a48b9d871bd5742fef2ab286094a92b508cb794f2f69a8ee15c2d748d8fca8cd2284719815e75b3b0df76298e48280bf530e09a34d166cd5379777d472f0994ba8e5629ea7691fb973f45869635b61b277c375606b911aa1228271c85b047942a52187bb231412b50f5be423476720240e62b9d3cfc5b7af5ce9fb38e03349063741ade945e994a2d6492a92b1250880318b9b9ce845ba29bd3733228ae960663050888bb98a0fdc21d6fb34cfb5c1af6d9b98ed6ae454c09b89b6067401fb30a17dd331a845c713715b5bd4a087bbc14cbbc9d2ea83d0f9b0d56d939d01b7d590b3082d2405a20724e2c44b5123bc1407b11da3de5889ac52b7b7821c4af1303d3959eef3888b8847f3e0695b5b844e8e3c221718a25057e707a50e0159af4462bb1d103b9057ff7fbc1740bae1afa44138aa2b7e3270cf80a6ac745cf701040c97253133ea195648e929e6c6394940b6eceb18844f1c862da6597a46f64e0cb5d2803eaba4a08110a011a32452185a6425d9d44b43463893369514957592f519c22d2b06bdc762c519d5cb84e9a68456ac60aeae85ac6453de2bcc103e32dd509309fdc08e3b3698a193d83d62df74719703bb5f8cc5db7b88b80110d74d6949d00469b840ff7fabdd4c0cec1a097a6117c28046b06b82c8ee8204296428ab703840acf7f3333d742726b114d3292b3154b2c4095b6d465657ec0780c488a0c60443717109363c45777271955135e60b46104bc18bac09a18690b37c8078a22645532112b1dd09313b9a25b7094700639775f89b8d0314eef0186adf7ceabac36cc9292c270717f27caea51b1afe1cfe6b6a1cb1a7da53c6715c9c9b2694bd5a581b733ad4841b229fb7a17bc213b969935c672d0993a94ec170bdc8b7c800e66bc6514f84fbc81c7d1c9417b79a82e5b3980acc792a19c46d13a2e75a3af791beb401f7555793d94c0ee1b9e98a5b6c52777e537bfb287268ca9524a4438ad87a0e85279e474c5be7740b7867d8b04781a2436a8d343f62274e236c736dc3c59d5b326563b9c86798ab14a6c9a0e67b36db89a82af690da7016418ba2d6c435e39095bb81a0e49c01a73a31ec9159844d1a3eb233d16b932919421e6a342473a71de629477183e8f34b2b7c8abb7a3b6e516107cb5229d780b93417f9bc94c38bcaa58f34dd88835308c742875cccf4928122199cd932148f48a94c5c2252295890bb4645761d3c2c0f33ab3e1021aa56b573e9c6fdac37c83f678b97148ce573a244b0487f3cf771bc7b6a13fe53a6ba58854b87a67a6a17d6a301c85f7c061071b4ddb27b3f404dc402ebacb8254a0568d48b2d299bd831188886a65aea5cd8d987f6017a2f4392f455c2b4f9b63e6cc1a27ea38f2588b0f8086d7a5c5e4b05b76d2b8918820cb8851704ca6d730861b512fefb0a76b61401e23b01ea710c5e3b73fa716dfa6408a635423c61372592dbf174d6d811eef7c4d885bca5fe669233a141e43810ad10235cb59f824728bd7acf17765bcd354a493aa60438f07d266d728b640cb07d50275bc2605fa6c964614b2c8143b37b184f3c30668662149bc18c6038706c12f0d31b896b69a7d588d0004497e4808d8c12253987f000168ea758a5b32c195f03f23a07c5a546a6607084cf79e073bc6cc1cb372e385ca827c490a42d900035bf735c6242031b8332bc57765ecce4792706f1cba0c7cc390e7bd3595ab876c4e397c58fc325c9607b0ee39692c31730eb4744e967e7ff8139fd1a545622ec870516b2925628ba782cac845b2429c3cc0ebf7747f414e8d35cd4a91c959d2276404a5df4790f4363104e6a0d1d60a48b65bbd92b417b51a5338cebe36c0f218bf27968c05d99947e9b44b4b5b2934c538f85cd7c8b9e3c31637e14c5c0279cdd6386e20ca89a53671fb2f04249565491ac2f900ad380d1a68b67693b185f26a232aa1b43503398002085713ca4b2f94cbcf6e837b020404b7f519a2b520f93b901943c918393f26061346a0193ce9ba8a48b5c4b01b0efa231eba0528c5b38cd32cd5d22586494734fa746b411759303a51a12ec58b03fc99a1edfb1cb01375032054878a6ec9dc4425945aae387e7fc6cd399c90049854cf51b3db690eb78a0a2db04d05102dacaa9834620aba427b5733bf1d1693643c88bd265af0280ecc66344b81129c491b3998c6c70ccf03257c2d06115b72aec35b4c8774cc7936c578b29fb3b0a5c66709363b73f41b08db919cbe57ad817cbb5df62b7836af6ff4ab8cbb07c9fcb7e3d601b2117e6a7242abb24ea96ca867b597e9e9b45c01aba9b54d2d323df8b38d3d37b72c2790e1041037355f274cceac2714a92955b31c55d4903a85bca55b2bc22c536aab22557d912fe2234423e7bc0894bb5f846a2dbc4a0dbb11c51840059ec11bf6cefa3ab473e1cb0f0bd17ee0bc3c59175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde + +comment = Official test vector 92, seed: "a28ead0a08e7228aeff602b16a1e752278b8ed1e91dac67994f5adc372e1d82f95cc390cd97ab9212275e0566c833fd8" +entropy = 690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f +expected_public_key = dbf001bfa28b07e21adc142c75111b9785aa2109a795ab792de4cb7b6298a504200f8850d32cc44e54182761a1c9c9ba591a9fa6873a61025515b068099bb1e63751c5b887d283077f86b733e4344d13310ce12d22322f254a0e92779a87067d19c53c70dbb927e14e1f2892b5273949428eb4c70c49da8aa7fb87048961db4892a6f89f18f0bb69347b9575025a964047ac7bd2c7472838383a6072f8338b23aa07d6b7b221e18d4e3c62641916106694315a2fc5bb88c6d664667680df556c3c046398a88328421f32ecb758bc64cf246815a25922021dcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532dcd138a4c03e2ff5024c52bb486ba7665b27610b822975c412331ed6c98e66721daa1897936371113a4f17d96ea735a5cdc019809c3907c03fa950c00eba9dffc69a902151a39163f2931e1c0271d491562e0a87fdf7b7846c31151017ef08727dfb68f22a8585295659ea358cc1b85c9ab4d107413225b8259804b31850eb347e1fd37f5435617a7a07b15321cc204b1a6b7c30d67e91c088a458bef5cb704e6b662189a9c0079e224a94e21502c0f1a4dff6028ef6645cba38c0c86eaf673e9b2613620bc216914a9781645fc48e33cb9ea06182637439f1d1a19fa50cfd3b5e2cb8310229b74ecbaead4b079d535521b8587a2995fa9b8c6694be6e432343c97c16ca23bf53883e23cc38f10c38e54f5639b9fc0943a4f41cd0acc8db40cb12e644cb74b9d4b858f7d6767830b92381a42368476cf2602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859902d19822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a459c0764cd943e0b6a5b61b8358530459685e2842ae9ab867fa712172207e692a7affa872323779087547c3d8b89f368ce078acecd55aafd5305371a5bef24fb255211b2169f4543927c845a3049f7a88513a682303960c2d12bc277656f15738c4368deb70cff2a32a1d179f4fdca57812cedb21b356e0aa63270788b510e58b4bf613473fe931dc80a9cb8bafe63aaac3913936c8a939c413cca10a1277409250b5da321ee5c24ad3d093c1c7095fba34b81380e5da561bc039e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d1a08127db4cea30340b5589b2327988c97b78f003d1315dacb301520a11f9f0b4fb33ce7c0203ff11c6a66136c0aab83928c145f4b968783b131281f2153925dc13ad133fcc5247b595cef0f03ff0da0a429c0de9a54f66c03f1a616c7210b7ed3624fdd27e99f38472867a9283c6b294b0d7014cf9eb62f0d7b051b190f093450453c056081370b45f5ebc4c03808fbb5c6d8b659bd22612c2872de9034b11c6aa6d356b2baccea0f909da0c775969c12fd5bb0c8a9bed5172a9358e01c29d308636b5d668f5b2c9def1380ba23b5c84259d887d3dc4882702b41d99c72c800dd5b19935d7722610741a105c1d227c38c5665cd5a6daaa991a9868499830c1697fa430bf4f95b03004126fac283a167281e4b847eba8487b0032914edb0b67b1e320c25bab50499378115cb07a9000e0156c9c93c1d90693b9c22623a3eb15618fa1c470481c4cf292b7462410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa0 +expected_private_key = eeeb8866b17cda12a45fcc6f9d05afd103835147647a7301ee071366398473c8103ab3b064e340f4f9866190acede02473fb49635bc38debcff0f34c5175ae0ec025aaf19cccd46d658c2a6ba62b50d1452b09c21b430ee9a3ce05d36a8e1aab2bf0185f35664b4999cc8c0df049c01056af6aacb025708c184534f1172b28fcc94aac2fb7012e20443f11f43478e7b1dd8a5c7d9b5a8818c0d2259c7f710f51003777b060f8db5fe06c3520d35e97f6b5792b0ac3304349387b637686cac1a6e45149173041fd7c3cfff5a398ba832dba04dd7179d0768122a701f4e0bfa48149ff140e2978a723fb985b939458b081e1068ee5102e5f540365e6accbb8c28db84125b21e8d04622412c2f075cb57019eb828616caa245a8b099a01bd86268cf491823e440e984335af59924fac1d43263af725895c717e827532d35c7da9ac1420b46aef13c9f33a427bb5a1bc646f7b54a21760527d303bacb2a21aa39c5577bcd5f416f126741fba9c2cf9401ec20a14e9a7bb927cc8135bbb0c3180696093289f4b19539c58655b8698a5d1339c9490be7c04ad3311fd422045a5027b203407cb5755462c21ac51f523389e803f30e12fa9c0aa7b4a1fdd85c66989af558cba916c9a037ac7de1a3f7f1b5bd3208fb6f28661696ad0db88d10a3b224a5bb5c99ccc96820e153e478ac579c65bec5a3d4b85aff1c4af5bb222e7aaaf9e9149afd11ea5e86990913d2b543913942d148639d9815d4a8908362a84bfb6ad20b8acf9596df4187009e7b773070450010744712f9e7a9b8e9624e3e2b1d6140a9e4789775abcbd2657aa487740314ea1e446db5c09746accaee29783b23ebfb255ba5c9706f1254703c676ea09801762e9fa45d858732ae7218b37107b3708eaba05d2c035fd447ceba46ee446aa324bc184e7b929f7513c16bfde5c5e55c05e6b5041552c17dd223af273cbbf65a44b4b6dabd51b341464a9993effd671481592c5a655d116b963975006b13503baae38332248f58656620098f42f97a813dfc7b4df880e5e783af5d833b89079474040ac05a6a7ec5e9ec1bdb282443c736514514f1cb7455958608a62503428464d89c66b209c417445416a54aa66234b1a5bf1c0c3f7064b6d0a7243e170b6acb01c033c5b1670a3ba6801024c03b24cc1786025fbc56bf04f3b241e4be701c9764938695bea4316adb6abacfb44f2041d2c29bb867379374b211e990f194b872a7b684a212dc179a4add943aabb1e6beb93f5cb100fe342d0781aa80989406571d1b79d08e31ae15b81740a22df02270f920ebfaa3c9d74392cd64e71f363df221134e9be32b6b855fb76e15b5c91cc6c3f750aeed71071a0803987ca7f35882ac31413a6001a6023c0a183961722b6ebba16f5577d95bea2c5ab446ac8e57acc96281a07599a8d335c2c12388bb0cb9f8633cd2251c8a7563b396072d0cf6e7b8e3af2192e5731341214c30708e128914c124973e759d4221f1735386b874905220c41fc731a22b9c665cef0cc5353b799399905f0acb549f13c6fa56fae2907d0353ff2054accec40310a2c4b62aac3f392b014ba88fc90eb868693eac83516336baa601f600518fc820bc8b0e76c66dbf001bfa28b07e21adc142c75111b9785aa2109a795ab792de4cb7b6298a504200f8850d32cc44e54182761a1c9c9ba591a9fa6873a61025515b068099bb1e63751c5b887d283077f86b733e4344d13310ce12d22322f254a0e92779a87067d19c53c70dbb927e14e1f2892b5273949428eb4c70c49da8aa7fb87048961db4892a6f89f18f0bb69347b9575025a964047ac7bd2c7472838383a6072f8338b23aa07d6b7b221e18d4e3c62641916106694315a2fc5bb88c6d664667680df556c3c046398a88328421f32ecb758bc64cf246815a25922021dcb67c995fc72cc6b46bf5ca9ef3998535ac5cfab70aa54318f9532dcd138a4c03e2ff5024c52bb486ba7665b27610b822975c412331ed6c98e66721daa1897936371113a4f17d96ea735a5cdc019809c3907c03fa950c00eba9dffc69a902151a39163f2931e1c0271d491562e0a87fdf7b7846c31151017ef08727dfb68f22a8585295659ea358cc1b85c9ab4d107413225b8259804b31850eb347e1fd37f5435617a7a07b15321cc204b1a6b7c30d67e91c088a458bef5cb704e6b662189a9c0079e224a94e21502c0f1a4dff6028ef6645cba38c0c86eaf673e9b2613620bc216914a9781645fc48e33cb9ea06182637439f1d1a19fa50cfd3b5e2cb8310229b74ecbaead4b079d535521b8587a2995fa9b8c6694be6e432343c97c16ca23bf53883e23cc38f10c38e54f5639b9fc0943a4f41cd0acc8db40cb12e644cb74b9d4b858f7d6767830b92381a42368476cf2602adb9ed08b35ff5c4d1ea93c94aa75e218779825401d859902d19822e9820d86c7e57562795b89cda97eba773070bbc502884a6f437d7ea7a459c0764cd943e0b6a5b61b8358530459685e2842ae9ab867fa712172207e692a7affa872323779087547c3d8b89f368ce078acecd55aafd5305371a5bef24fb255211b2169f4543927c845a3049f7a88513a682303960c2d12bc277656f15738c4368deb70cff2a32a1d179f4fdca57812cedb21b356e0aa63270788b510e58b4bf613473fe931dc80a9cb8bafe63aaac3913936c8a939c413cca10a1277409250b5da321ee5c24ad3d093c1c7095fba34b81380e5da561bc039e3a8c15ff3982a7938bc16446a3ab2679a50c2e5c1d1a08127db4cea30340b5589b2327988c97b78f003d1315dacb301520a11f9f0b4fb33ce7c0203ff11c6a66136c0aab83928c145f4b968783b131281f2153925dc13ad133fcc5247b595cef0f03ff0da0a429c0de9a54f66c03f1a616c7210b7ed3624fdd27e99f38472867a9283c6b294b0d7014cf9eb62f0d7b051b190f093450453c056081370b45f5ebc4c03808fbb5c6d8b659bd22612c2872de9034b11c6aa6d356b2baccea0f909da0c775969c12fd5bb0c8a9bed5172a9358e01c29d308636b5d668f5b2c9def1380ba23b5c84259d887d3dc4882702b41d99c72c800dd5b19935d7722610741a105c1d227c38c5665cd5a6daaa991a9868499830c1697fa430bf4f95b03004126fac283a167281e4b847eba8487b0032914edb0b67b1e320c25bab50499378115cb07a9000e0156c9c93c1d90693b9c22623a3eb15618fa1c470481c4cf292b7462410d057c2e5851e08e31fd88af2f84b0cf79a88de834c1f17c7a5fa17d329caa09bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd381c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f + +comment = Official test vector 93, seed: "92877d706daf88ef3412eb143db8cd91bc047a9a43b7acdaa42523560dee4c172697be4332042fcab91135839bf74ab2" +entropy = 32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 +expected_public_key = 2df84a0272c13da5a495942ba848ac92d302a98a3e55937b8b1b49fe588be32a540ec90b5cebbd90d1b80dd24d32eb85fc041a7ca307e522b8c5fa9c85bc258c8abb9f2678d29569f313a1e660a2454730261a6766945ce42c140e5181c68461eaf12d1f185c358233b9bb4902fc5089f851bac83ce3f07bd7b185ef08626d7029129703334084375bc5ba27ba023ca6722319a916baad529715661e3a413c8137cbbb206e313906df1ca77cba73e5499f54fc53047741af2341d5623278f76131ab47af10bb4dea8f493b6c0e4829ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d02d1131e493da5a0a1117b41d4ab3db35a7a2e95c6055ba70ef159e7aa0dd5452598f91477087bef1396acd48e747b962205af92eb99faa809b4bc47eb93bfd3860102d4adcbfc39be80024550656c42785a6788c7a851b107823a02a3daa4caf25097f1f9afb29416dbb360c4a824e3ca2a30e19f94b805de181d0a028e685c378dcc225112899a6b79869109ca4b094909b21042c179c6cdeb22564cfb6f89135022fca3028caf7abab19a4045dd5a60721c6bb47ac53e40cd932511f2e5473d3b4ceeb44be1a00e090a886d345b13a58620c49ca0893f23058412054ae5069c1014361cfb0379c2215f330abc647114a3c597765fd014c64c8c1b1b45b3bd02be9d5a55b0cacfce297581fb48fe0256f4c0cfc84aae1c542f36730e5f10795c72157c653210686801210418b549a7398ca8b7c70ed007cb153d2a55178ae23a5b095ee2d116b9f3a1a9f19faec40d75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c6701368b8ddc219a9f2295e6e01d22c4a50bd08179a08044b702ffd786faa088f867b63b951a92751cb0f839cd554a83745444c3bb88d3609a9a4bc2e0bc73108a71cc7534217872539bd6e942cd36a09aa0374a3894d279a1f7c38a56e7c0298948c330b8c3a5b6aec3bbdbb87384677ada78017564a7fe40c2983a9ed3acbce5e29e3a78502952a9540a44975572a1512b1d4284d9bb528e538f43a15216f4b4f2a5208e06c43896a19c416c99c3b677564975948468792edb6532f9b0567f407fc6d6c302766c6d1373bf78a18896188cf20ccec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f314827e0b24539e2aa91123b3fe42308f041dfb6c876d079d60a3ef5735ab8a36abae34f4a12729be4a00f753c7e4699572375e6c7b037948684206c08a27ec12b26f7349cdacc3559ac29d5cbc35c310870597e391ac4e4c02991096f37492083bc1c43304bc3d5925843622494c735942dac8904cf195387eccdcfcc8a999b6d1b744a542359e6b167f91022be1660bbd218a6a6861aa17c57152552172f38b43d5281956caa77daf9b94cf60cbf08cd9d9b4c1edb6c4a17bae3b36800891910c280c3e7cbf4aa11f33a7c70e3b419c2b2b9a64709c31878f913fb934d77b4c36e329ba98b44f394631e0a289042061f527d67446d6ab55ce7b43ee1080fbae67085a2a03b36cc9ad9b5b546156c3c5a79b092a67912a19575f6b5546397c15ae334b451c3d919422f28b70727c75fb631a2ab012bd5971b5b2b75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a568 +expected_private_key = b27ca8d40a1cf8aac1a62553ff541ef56b4b4e352e38c0ae8c2cb2240c2d2525adc52b1953a1c239e3add71b5f7693196875babf8b31edc528f3b320e6569997639f1c9b5279c38d5ddb3b691b0228ac4480d45077db55bac24285c5820c49be25632c4aaaa23ed84e10a1256d9cca9b584d423a9fd37276cbfc5953c9284a4097bf71706069ac413ab857c64ebd179eb75496170778afd74180d877c9d69e1956450b1289948323f64227960a0b24b442e78c551c5b35e89b34b018b80bd094f7594365195f44c05bacbb2e0a976a86559bd6b23d220b5c900375c6b188fb353c3b064ced669bee6751d5d22659eb89900a92b7ba84eab58b7e95cb8495191ca0491ef75a3abb9469a7939796c2f8c15ca22283235852b0a96daec403c5c057b5ac91d09cb16e01bb0d078170e0ce9596b913e953c5aa67bd8a2ff20c0261ca814f334244886daa0694368293fd858e14e23d13e66ac89a58867574804786c4c48d2fc003336c002a7776217acfe7084588455a0a85b8aa51c33e99b1cdb75541855577911db00475df42168e7a21efe57402303dfe37ab5bf10200395550a1639da2aa8e358748ec38946bbd3dfc27deb08f4f017abe33a2df3b9b96cac0e8c261e487cfff31a1484ca5e04036797cb4fc87ae6cc72f9ec0835ae2b160b425acfa8b75236d92870e4d43bfa7ea5c98827f95db6dd4200068650e3d8812de827c3f660cf8049933daa52793ac10f57ad8f2a7445927ca6022d5a485f9424662a175b2a6349b248aaf4853be709d42228c3ce3b13990794b9698869842b81649cbd9482c2435886441ed9a7927384371d02005a514717abec398bd183b321134a4de85a1fc9b72f7268ccafbae289c15dcec18bc26b81ec43c6b8a3919625165617d60c33f1e6b04cd5492414a15bbca5ce84284557c9cb481a951fa5df2e444e2c20969f38284e60ff15b0ee707115880bc6d3834230c7d22c7cd69229d1eea957f58b2d47b11ca97c926070cf1c1934ef83f5a26241c7c73959c8a0501c2c1c70671987243635fea56ce6ee292b1d6aa26c4cddfaa1751520fc3218e7e20c13c6a1df4835c7d6c0ba45923ceb2ab40fa7fe3732e47ab652309cdf28091d8d86308b73f90d86995220acdd9c544c95fcd24a77e7c90f2f15e52aab595e11b1ac0799a3ca95e0644771420aedc777a9048fa89ce94780c8f2b903548bd46a2c22e453b68736f5cca6c35ebb027c0c7035678f7f69a9ca02fbb4b23746759660251f6757be3aa1767d7280aa75b60a7a0cc892f70f67cda886cfcabb451a36023c688d7ab5e0a3b5bc88514ced3597a594d0e28c7aa25859e57be9fb12691c047a8a7373fe1695ae742027a8f5630cb2776721815742c66a4ba0c7e7e8b8281144b80288cc7296bfc8625a2cb995b548d48294b2fbca97d375b91203392cc27fe835f62db97b14739f6c8b1880a53ddd388e2636f866416817a110258a098d9af4458a64c68654e97099746b9b9e23adab5653970c00719b54e4a2d2092cd7bd62ad9317357e35224184a4e24b4a58014f666b33e1530365070b73aa6da432d04f2588f34ac1cb3b3f7fb4ab200b459966fafc689cc40adad0c26108859a2943e2df84a0272c13da5a495942ba848ac92d302a98a3e55937b8b1b49fe588be32a540ec90b5cebbd90d1b80dd24d32eb85fc041a7ca307e522b8c5fa9c85bc258c8abb9f2678d29569f313a1e660a2454730261a6766945ce42c140e5181c68461eaf12d1f185c358233b9bb4902fc5089f851bac83ce3f07bd7b185ef08626d7029129703334084375bc5ba27ba023ca6722319a916baad529715661e3a413c8137cbbb206e313906df1ca77cba73e5499f54fc53047741af2341d5623278f76131ab47af10bb4dea8f493b6c0e4829ecf4c425a46d21755e93e5a80d0a927739848695be93444a98a45d02d1131e493da5a0a1117b41d4ab3db35a7a2e95c6055ba70ef159e7aa0dd5452598f91477087bef1396acd48e747b962205af92eb99faa809b4bc47eb93bfd3860102d4adcbfc39be80024550656c42785a6788c7a851b107823a02a3daa4caf25097f1f9afb29416dbb360c4a824e3ca2a30e19f94b805de181d0a028e685c378dcc225112899a6b79869109ca4b094909b21042c179c6cdeb22564cfb6f89135022fca3028caf7abab19a4045dd5a60721c6bb47ac53e40cd932511f2e5473d3b4ceeb44be1a00e090a886d345b13a58620c49ca0893f23058412054ae5069c1014361cfb0379c2215f330abc647114a3c597765fd014c64c8c1b1b45b3bd02be9d5a55b0cacfce297581fb48fe0256f4c0cfc84aae1c542f36730e5f10795c72157c653210686801210418b549a7398ca8b7c70ed007cb153d2a55178ae23a5b095ee2d116b9f3a1a9f19faec40d75256cdf76ab8e393210d3afae375a7bc384799a6efc5b76f287499c6701368b8ddc219a9f2295e6e01d22c4a50bd08179a08044b702ffd786faa088f867b63b951a92751cb0f839cd554a83745444c3bb88d3609a9a4bc2e0bc73108a71cc7534217872539bd6e942cd36a09aa0374a3894d279a1f7c38a56e7c0298948c330b8c3a5b6aec3bbdbb87384677ada78017564a7fe40c2983a9ed3acbce5e29e3a78502952a9540a44975572a1512b1d4284d9bb528e538f43a15216f4b4f2a5208e06c43896a19c416c99c3b677564975948468792edb6532f9b0567f407fc6d6c302766c6d1373bf78a18896188cf20ccec39632269f6a193de5ec5dca85cad6bc79023c691d5682643b6f314827e0b24539e2aa91123b3fe42308f041dfb6c876d079d60a3ef5735ab8a36abae34f4a12729be4a00f753c7e4699572375e6c7b037948684206c08a27ec12b26f7349cdacc3559ac29d5cbc35c310870597e391ac4e4c02991096f37492083bc1c43304bc3d5925843622494c735942dac8904cf195387eccdcfcc8a999b6d1b744a542359e6b167f91022be1660bbd218a6a6861aa17c57152552172f38b43d5281956caa77daf9b94cf60cbf08cd9d9b4c1edb6c4a17bae3b36800891910c280c3e7cbf4aa11f33a7c70e3b419c2b2b9a64709c31878f913fb934d77b4c36e329ba98b44f394631e0a289042061f527d67446d6ab55ce7b43ee1080fbae67085a2a03b36cc9ad9b5b546156c3c5a79b092a67912a19575f6b5546397c15ae334b451c3d919422f28b70727c75fb631a2ab012bd5971b5b2b75f80e14bec0494baeae3c7ae947bd69827e1fb86388052c3bf3f8b4cd25a5687ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26dc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884 + +comment = Official test vector 94, seed: "bb4c0082ca4044b1ff60b036c9b0e0495d58667156786c530bc69d949a13bfaff53798e456423d7a0e162a60039367d7" +entropy = 6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 +expected_public_key = fed53d194419c06b92e51498ac2601869a1024eb0370ca3a420c48a765a5b99bab88a759251cb83259a628603c54a831ac0147f3a97b8329474258b7bd6067476605a2b2b8311252fe54565c865e2dd96ea9e43b23121c27ab02c348310acc38d9d583b0d8105dc87896c238069c689027910f9bcb5d29aeebf57c2b9c78f76866768c0699c6bf743c0b43108c128a5277f39b32c351926369fb8754cd0197eb9ab602f391c4ba564be2c3423005266229a10b21d31a7cc3d40c2e7192cb6628afa692d3e75aace66e7bb1169893c8ee45bda5560e7f79c711d32d52c0c783eb40bf8977c3063cb114b6368a8d1486a86cb108d146a648e080751440f4d8087116701987c328d8547d0573f8c03d321ac07138a60954297cd832dfb989fd99aba8b213e7501cb3d25b384c023f66776efa3ad4981037a54400729634a782adfc24404bbb4f2405a27a8500cd79e8521daee48848e485f53a28de91089d849ebfb54d97d0cfb3cba46a27438f426eea1a0122f2180630864ae46cc5f3a828725cae89331d540b5b3633eebc0228000d75908f21277104d7816f56854c3289ad1a5c72c1655830089cfb9c90b1306724cb2828be679b989a3565758b058ae983c1ea9b71f10553795537d454eed50f50a40274592ae165c846d85527e479e3fa8d8865047bf68d200287c0a5b8a6a78c4769bb3a795979b774713a522dbb723f3628f2f4126b639e3b4c5c4b076d321a208a123d82852aa0db6ff8457e745b6b710b396c8106e635a379e22c59f17df7b7070eaab38d5448e4ab67e6b21078d5b9f9979c6d7365cd1423cef6b4c2b186ac6b792ef9351b6040f423ca22e7a1455a0473273e3b53b92a132d7c44556477907fb41f981a06cac9beeb9655fe90c4fe93cc33337d78294f7c128ffee82b0d4211e550342c599c9932a201f3cb8bb253a0559fd667a3d2cb46a4936f5cf9c4d0d105880a446066ae06841e12f259e4e6220d932633f77f9a6b463e180778d53c37e0bf423717f4d476ecab6bfbda7e461ac3cc9806ff4b38fb80c0ac9b0dcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f53816d79c6a1fb40f1ce200334a7e74760999f8a0294c3029bb23ee0cb81700b95ba20140cc5de537aca62c9808240e74d508a93263eb14b7d202a31ddc2147747192ba1f38932538241ad1db35caa40097393038957b64e716d4cb3675aa9ea46257bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cb62c702165c74864c3a7ce67d8af92eb78496c4e8eb78b55db7963b016a252a85e655c95936d6006bc07ba6250e458a387bd7bb43a3f5a16cd8733b66565377c1a74d5488c1a0dbfd7a6dfb474eaf29fa80aadc83267d0b98eb7a8ad3aeaba977a0a5e55b8937ab68e385f94db13fbc6c26bc23b0b8ba331a578b99b493d875f206c278a3b4f63e156fd386fc13104d6dc96ae9bb3055481b846183de71eca09273e58c466ea225b1824246c799ab8b045fb844572882299bd6f1b2787e1094bca102fb20e0a274257062385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac0151687859b155ad62a8539cc6b872aeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e1 +expected_private_key = 2735bc066a2488726c89432e56452acb24a2a5407522988c0732ce072128c8d5147c42988f94a8516c77873858394a2bef65b87741c5b9691b6db84e3b1b2b2f851b1305832e4210e5d05710a5bb7195b8bee0cba9b5ba21ba57b962a280565aabe1c9015635cf1a7121a8581fa0a78ab26fc82838b6a405c6fa5d46469136cccc34930664240915ba5c86e67ed9e73f4b123233c92d73bc05408005dcd6cfd62635c3026c990753c55ca8dd385a29b1c79fdb97c0b4cc8f26b28ba573b5194d6bcc065f5b97df702009c43a65eccf452447af91200ef68f18cac25e5c71e62a39fd7a26c6b64b47e29d1e4084801599aba838a3808ed83454b506965507cc6d0b34bb139300d1014168a79d5707c74bbc7b980461249fc31734dc384c9dac4ea6eb4701402084719593b62aae53c8d55719945975cfd25bff31c886640fec37cab3942676c840a453c6751caf16a4743495bcde6528a942a47e7c2d6499b2a872a76e928ef4b0aabbb21604f33231235a7cb47c96d9c976a2aad533a06a24024ad0925007984d99aba3aa8168a8ac92f662348686f756bdc1a23f8537545d13ae9f657caa801788c9368864a05f40af22e33e10705741f06ef577cade6ccbf1d01065565a5b13284690bf611093e45684d6c69fc0f548af852248db6a6e86a2a907c95ce0053fd942a92b024dd18803474b03f73fc022912257454c008d137c5e8404379db2719581af17108a03f58dea58892912c5fab701d28ca845068761f6bab69bbb75584f7d289dd921ab30379248c91106a784738b17cf0044418bb9ce34bcd913bb26d04ca04896109a255a39beba1a2b58490862409e473ca623933ac14c90f64cc74af396c3186917061b5c8c28f3e8b694535fc2c73af9843031c19166d2c8a3a76a2aba45eca36321ba367bd5b176b5c7b8d7b7192c95cf2803e2c3ca5d585c4ea63009c7b850f08759c278f1027c59499526a8b2e494203197a9304022fa0c4e47a3a6fbd8bc59a7c1312a6d19d3063e8078b1a1bff964af48151e4cd3cd87f49bbbe01afa3a5bf46a7f9bc97de729285af35a6a9168683658ee37ba6d9499cbaa8cb44c93beb287ef7cc7b1eb6491154c14fc2027ab49316b70b8237a546090c9687cc70cbfb82208a7f61f63aac1a42961568407343a050b1048967c5334f3542860249ff9c2fac8639ef8c125d0b9fd537fca93c1006a77499658c0286267b910c10b12a6136152bcbc03e782c41b1fe94a000cd974a3a9ade3a3b8b4bb8ed8b403683ab4ea3b84b84c4825f61f99d72eacd894337523c6b6af765bcc99393213938d66b18b2b168d6c73c2eacc42ad22255cd3ac6d75200111c0a6076f02f906b1c96213e80310b8752b1b619e72366f9a0ba4283520333ebf8693f93a7fd6c3560058a8d16cb50b585b3d519e4263b050259a9a0a8823e3cadcd0b81c1ca53820323a9539133c68b0a6cac1fc834b808d9375431f961fe3233c49fc9e88ea1ed0a068a271b502c0a0376a1309f86013b4947bb671c1b048c0905c8ce16d8035c7c05b9cb8755c7d7b6db2907dacc5a91b61b666837f209075e8ac5b86444b49ac878f9b2e18d42e0f791ab7cb7c973ca8e0437f158889fed53d194419c06b92e51498ac2601869a1024eb0370ca3a420c48a765a5b99bab88a759251cb83259a628603c54a831ac0147f3a97b8329474258b7bd6067476605a2b2b8311252fe54565c865e2dd96ea9e43b23121c27ab02c348310acc38d9d583b0d8105dc87896c238069c689027910f9bcb5d29aeebf57c2b9c78f76866768c0699c6bf743c0b43108c128a5277f39b32c351926369fb8754cd0197eb9ab602f391c4ba564be2c3423005266229a10b21d31a7cc3d40c2e7192cb6628afa692d3e75aace66e7bb1169893c8ee45bda5560e7f79c711d32d52c0c783eb40bf8977c3063cb114b6368a8d1486a86cb108d146a648e080751440f4d8087116701987c328d8547d0573f8c03d321ac07138a60954297cd832dfb989fd99aba8b213e7501cb3d25b384c023f66776efa3ad4981037a54400729634a782adfc24404bbb4f2405a27a8500cd79e8521daee48848e485f53a28de91089d849ebfb54d97d0cfb3cba46a27438f426eea1a0122f2180630864ae46cc5f3a828725cae89331d540b5b3633eebc0228000d75908f21277104d7816f56854c3289ad1a5c72c1655830089cfb9c90b1306724cb2828be679b989a3565758b058ae983c1ea9b71f10553795537d454eed50f50a40274592ae165c846d85527e479e3fa8d8865047bf68d200287c0a5b8a6a78c4769bb3a795979b774713a522dbb723f3628f2f4126b639e3b4c5c4b076d321a208a123d82852aa0db6ff8457e745b6b710b396c8106e635a379e22c59f17df7b7070eaab38d5448e4ab67e6b21078d5b9f9979c6d7365cd1423cef6b4c2b186ac6b792ef9351b6040f423ca22e7a1455a0473273e3b53b92a132d7c44556477907fb41f981a06cac9beeb9655fe90c4fe93cc33337d78294f7c128ffee82b0d4211e550342c599c9932a201f3cb8bb253a0559fd667a3d2cb46a4936f5cf9c4d0d105880a446066ae06841e12f259e4e6220d932633f77f9a6b463e180778d53c37e0bf423717f4d476ecab6bfbda7e461ac3cc9806ff4b38fb80c0ac9b0dcef56e9b27881d1aa0892657b12a913a8ab84037a6c78399f53816d79c6a1fb40f1ce200334a7e74760999f8a0294c3029bb23ee0cb81700b95ba20140cc5de537aca62c9808240e74d508a93263eb14b7d202a31ddc2147747192ba1f38932538241ad1db35caa40097393038957b64e716d4cb3675aa9ea46257bf55a6d1fbc2c356b020073e16ebcbddb3692515be92dba54cb62c702165c74864c3a7ce67d8af92eb78496c4e8eb78b55db7963b016a252a85e655c95936d6006bc07ba6250e458a387bd7bb43a3f5a16cd8733b66565377c1a74d5488c1a0dbfd7a6dfb474eaf29fa80aadc83267d0b98eb7a8ad3aeaba977a0a5e55b8937ab68e385f94db13fbc6c26bc23b0b8ba331a578b99b493d875f206c278a3b4f63e156fd386fc13104d6dc96ae9bb3055481b846183de71eca09273e58c466ea225b1824246c799ab8b045fb844572882299bd6f1b2787e1094bca102fb20e0a274257062385dac60f37a15b0496ed23c465a3ba46bcc0ba9b5b78c93b45cac0151687859b155ad62a8539cc6b872aeed63847ca64797460ff5f477504df1b1894fee3e6bbf8218590936e0102dce8adf459d590355576e12c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b204114f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34 + +comment = Official test vector 95, seed: "121d90e70af6204445d0deb28ac0c108262719e9fd3476aca74bbfde89faf04d8d5f89a624e8a75db80431f0d10ad28f" +entropy = 527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c +expected_public_key = a0e473a9d639b1299251b46d07c79c0df1ceb995a968b5b707b760d8bcb120f6226ef5b742f34548902a7c73338a8cbf8d6b02a83470874b1ec5845dcfd3a4067c420f8485fae1286a23adb7373b9217c6dc173748870bfd164a16d62a3a6608f5e2b7fe78b92364a4b821967db45ae29aa1b11c0cd67cb4299b32d263aad7a26eeb3a69ba56790fd806abe3935d82487aec3205a856b4981e7f53b8f82a30d13c1b725b1418607b6619b0e8a8870bba6070e33545730182fb5f6f9938ab2ca68c50719fdb472a88384ef210b0c22785367dedfc840979ab758479506064b7971426d70af9a95e7d585dc8b67d4ffc2082bc45a4fa9b4fb9541493c3dfb88fca757eccb50f1a9cced9c046f37062e3879e13958bcf063041e858810b057680276d2ca12a307f511217fd626561587617674319382a4a00ce5e3bcfc5ecb5b3816133910650a469ac663f7a4a742ddb87c4e5be636213880c246370b1cbb8adaab6bb7e1185e1f95c945bb001a0210cf56f326b35051b8dbe85245f9bc6d973b39afb3a3b961501862b4caabd0d55693c201390f48fb7511990571985764be7373a7fc4bbd5e82b31f52494b15b6c2c8b5b593182028bd7ac7a40fb446ea756463c396de29d0fdba2569b9001e169f7c824c8a42d313a15b682bd52004867837344324e2f91a06a4c9f7ca447d6291635257cb0934e015c1937f732c1bba2c13591ccf4add16960b2303476000d984a8fc8036772c3b7c5721261387ae535129a7921a1711c98103161a95ebe16c0e0a28555dc3598cac2d701a98ca249801a4bb10379a5c29a1932acb6f6c3d040639fa98fa7297c6d453e35587488576db9bb2f9d1c37f8260cba3ba90e4b779867ad97db03ff005ecfe3470d2c25d54105ca287a9e0c039c2a2b71a1cbc6260d59a268d60c05d61202ec336cb8285b41a043bf58949df50def5937bee1af32d174e8fb463d03449ba747e92a79a1eac8ded247aa0a50821a16ad4c9f533a0fa24684d452a71df461aee15cddc2185551112682b4867c6cc27c43bf835432cca184840b85886a5d970e9f515f7f97151410c401e9baadf41ce2b8642313c295d28587a327c41c24da18967a6426663642dcf389c50892d6847718365cbbbb80723c1397b90447b197842c96a141bf6cd317bf12bb64c664fd237e886a9f793313aab15f668c91c71149c4b90b35b147f7c34b8ab6948799897855b22283050b113d64a60aac739948844a9f99c448d21c414425d77560670c298f493d891128ab1665d8141d2b1c8e67950a68255b7f9376332b1cd7c6630ac05ae7c127fa7acc35e640e94285e78661b15b21685a36c889a8cc890ce53c36ef23c2f17cbd8c31351beba827949f8707a05324abf05aa71857bcbe690405ab0030e648fcd3bfc0f2ae2c627e04f490bc3ba237059ab93085de218029f056b0f57abd342170f5b16db069073a3c16bb1c0bda5136952919b22ac477ac2489237bb0869656614e4ac248b003799c761b2ba5f2711b24a01419c88937dc4ce745acc16c796e0123a4228ec623a2a4e059b80b72beb1329c9204b6555b0a62c14df0b19b4a157bca985090b428dba8587b53ca2714b2ec2a04d306b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2 +expected_private_key = a680635121c694ac4672c809bb3b913e8ca2f659c756db1d7bb2369f41ab4ac9b3f5141216f3c997b00dcde37352d46463f371fec14b26aab239498d44975f787504815552e727329dd78428f5568b912c76b572ad9b3d335a9f5bc0283c76aef8d81369a0ceb4523bdc4bb0607c29d9998962f76b217774d74a3453a61ff1f40f89a51365212f39a07e913824bf36b6dbf6c8934014dd8716e998a982b124aed8b082c3a2998708bc1c4733773b73e0be315203e8e264a032797280ca0ab023a9d81fbf0565f491837cf031e219084b640ee8710589e05e1701870bdb7bf0b0bb539a0b3ab0028447110288c1d7d83f89578413a46b0b04406657b4e7e5a6d04bbb91055becc8ab907ca9647c4b8b144045b6cabcb974a47a35308a23e9c9281c61c556ec148c9a663ad9518cea36aaec71b6995110fc01cb66b75e128478280fcd31a3416a12e28c15ba617574730437da8bdfb86b58d88c789c4f9e23adcee53b170c6a0b80033ad52cfe1a155ea1a568f5b2ef77ab74878e0ce42a1f7c3c845713d17105ab2c91b83836e11b9858a66997b22e8a67682588ca78e6b6d736298ee34b100bce61e0ad921a9f020a7032351daed655d35b3659a96b32db9e68d882fc986da904408a98c469a84cd29cc999b2b071f84c921c585b9b3233c5bedf82637bb1253a4b29b36b42b54751dc629a215656aa1890c0c56e0cb62a3c02252b771d72375a60374bf8d84552080e0d456579930b3f2a2a3b7913c031112fabacaef75bb2da5202d7671359282cb4707b52740d9ca06ab7034b48a292404d26b6cfd08c8b0da61550044069f4cf27488c028001f2c29292840b60b321de5cbdef1ca216838091c3172ed26d141c957dd93bb6a59d9e883640d87a2a85605a9730dd5333843805374b58747c7262d5a65ef442d6843deb731c943269b4a9bf00f39b4a3847840c1bf4b9907fd7b9a66c5da724cec467102f080d4d0bc519d0b2504a05f7207edce7398d009348f64267e01b0ec207780791942565aeb061bf03719d706f87953c4757a75a126ead15c6c9447c02938c3b75a58ab25ce65a5caa21898fa8050319880223899f5546e0d253df7950691b86f8e3115438c3b80cc2e7a6178a96a0f38a0cc47394be36c9b0721580d646a89b9327210d40728f4bc4adbd8b130eecccf528a5a09595f32c0f64e602f6898b8a4c82d79a8ed31c4172a7812c295c93841929b782b334490eeaa38c17cb4e77664306bc7b01726ec656e24311c51b0524c72f0745665d43073604c59ec88df6fc9ee2f2a0476079bcfb735e562f57e2b0e1987a0220c98f0b4cdebc70f93ca709c5c2fac7098a7b866662accdf09c85974d7c88ce9afb01f48276ee320d70c7c0e15950fc0775e13173b60555a470302d0a0047260e5cf85ea2f3c326968d3c308c15eb400b13bcaaa65ebf941ef59a069ba0bd3d00841b6124574303ba8c2bc9f90f107865882c18eba462f6b09eaee05796e43a8647c59c64b7a8db9c0941299280af728b872c303755b682a3ec10c5876f040543bba028e870c02a4312aee9cf2bd1302df80bd0facbd0765a778a7fa2d3a4c9675965d6799fc7bd4e28a4e2a53948790234f62ba0e473a9d639b1299251b46d07c79c0df1ceb995a968b5b707b760d8bcb120f6226ef5b742f34548902a7c73338a8cbf8d6b02a83470874b1ec5845dcfd3a4067c420f8485fae1286a23adb7373b9217c6dc173748870bfd164a16d62a3a6608f5e2b7fe78b92364a4b821967db45ae29aa1b11c0cd67cb4299b32d263aad7a26eeb3a69ba56790fd806abe3935d82487aec3205a856b4981e7f53b8f82a30d13c1b725b1418607b6619b0e8a8870bba6070e33545730182fb5f6f9938ab2ca68c50719fdb472a88384ef210b0c22785367dedfc840979ab758479506064b7971426d70af9a95e7d585dc8b67d4ffc2082bc45a4fa9b4fb9541493c3dfb88fca757eccb50f1a9cced9c046f37062e3879e13958bcf063041e858810b057680276d2ca12a307f511217fd626561587617674319382a4a00ce5e3bcfc5ecb5b3816133910650a469ac663f7a4a742ddb87c4e5be636213880c246370b1cbb8adaab6bb7e1185e1f95c945bb001a0210cf56f326b35051b8dbe85245f9bc6d973b39afb3a3b961501862b4caabd0d55693c201390f48fb7511990571985764be7373a7fc4bbd5e82b31f52494b15b6c2c8b5b593182028bd7ac7a40fb446ea756463c396de29d0fdba2569b9001e169f7c824c8a42d313a15b682bd52004867837344324e2f91a06a4c9f7ca447d6291635257cb0934e015c1937f732c1bba2c13591ccf4add16960b2303476000d984a8fc8036772c3b7c5721261387ae535129a7921a1711c98103161a95ebe16c0e0a28555dc3598cac2d701a98ca249801a4bb10379a5c29a1932acb6f6c3d040639fa98fa7297c6d453e35587488576db9bb2f9d1c37f8260cba3ba90e4b779867ad97db03ff005ecfe3470d2c25d54105ca287a9e0c039c2a2b71a1cbc6260d59a268d60c05d61202ec336cb8285b41a043bf58949df50def5937bee1af32d174e8fb463d03449ba747e92a79a1eac8ded247aa0a50821a16ad4c9f533a0fa24684d452a71df461aee15cddc2185551112682b4867c6cc27c43bf835432cca184840b85886a5d970e9f515f7f97151410c401e9baadf41ce2b8642313c295d28587a327c41c24da18967a6426663642dcf389c50892d6847718365cbbbb80723c1397b90447b197842c96a141bf6cd317bf12bb64c664fd237e886a9f793313aab15f668c91c71149c4b90b35b147f7c34b8ab6948799897855b22283050b113d64a60aac739948844a9f99c448d21c414425d77560670c298f493d891128ab1665d8141d2b1c8e67950a68255b7f9376332b1cd7c6630ac05ae7c127fa7acc35e640e94285e78661b15b21685a36c889a8cc890ce53c36ef23c2f17cbd8c31351beba827949f8707a05324abf05aa71857bcbe690405ab0030e648fcd3bfc0f2ae2c627e04f490bc3ba237059ab93085de218029f056b0f57abd342170f5b16db069073a3c16bb1c0bda5136952919b22ac477ac2489237bb0869656614e4ac248b003799c761b2ba5f2711b24a01419c88937dc4ce745acc16c796e0123a4228ec623a2a4e059b80b72beb1329c9204b6555b0a62c14df0b19b4a157bca985090b428dba8587b53ca2714b2ec2a04d306b3cd5d09045252960a068412f1bd67b83a217049d0685ec3d63d691559a327b2aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c + +comment = Official test vector 96, seed: "b3ac6503206accc2a92cbc210d020a2654726911d11ce676aa04feaa08af1d20c654e4105883ae470ec3ab299075d420" +entropy = ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec +expected_public_key = 4d960c98359f5719b20dca6d1e2916f2829e73f79b55b468170b64f2f8b0c788796801c8ec244e1973c7e033b768414c55d43079b2711bda630e678b184a70dd161c4dabbcb91c07fb634620d1450664a444e82d22a0a4f54ac6c7c02d74120b2ce205fe49a139b9c8194341f4295ef126b37f3b22e35792a8853b60eb3f7ed01314491c4451470870a5ea5b1d23442019bc1def547fb8935ecbeba0833228b8d7bf2a4aca52436a3f993f6164666ebb3c38317bf5b48cc7182c00d58d4a095d0fd4c60e4229e77803c4f38f22464c7a4259e45ac71e8ccde6e5738dcc798777317f9847f8357dce21b24ae462d0465f1d58203f3b8590d88deb9c6df4722a1420a9ea0813ec3777a6cb11ca0271292b6c662a870c292291164004299c82442a8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c053203f265bab420eee2c95a5960f8a87c3333785e1b89ff841a6aa5aa964f3a853e512acabb60e29c3a4810df33830134c0e49bc5e1ba41b07b671e1ba6bfda82576406e6da854920a46914c8ea986b1d6a0328d4a450fc0ce698b9d16954aaa0c52b6f2b5ff7b5347e84c3af403e9b31ec180238cd5af96f5c6f0d3644ab51717f7255ad6551f44378294778937cc56b610680704bfb37e3ccc07c5276777e37f36623dec8225388c3a5a2c7026eb902c63260ce27ffe657bce34a47db43667b9293e04ab9677b6fdb0b0a429a4435a9f5624628a2c07bbfa8afed562be4233019524e67cae6f955226437433bc59835561c462071ac38058c145787c242d4b6dc055170675190882792ea49726dc8b2cb638763784d3c23e1791c93a55383a8c4b59643626f8948d228b670312893ab3ce5b123401b1b24432545889d4d124d2b846070c1663b87a3475c01adc4f4df286fc91c76b018c05b5a26a696df86c4b1fbb2ed3050cc9b54ca2786839f854b9461655972fe21c3c98007a693a4d0b8aafa3ab73f1c411dd283cce59528477b6e089847ce6518f29b523602f80ac573618070bca649efb84fc3947d43b229e05682914c153809521ec9b7978a6bd667f59b18f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734df18a218c5bacb364c9136b8e055053567a1856c21b96a1a2723913c98cc364bbd1fc4edef37e1853c523727a6c677ca4c82ac4d49238e1b60c1531d1dc9835c4a96124a0011c09350353aac4568a84293e8666f6016e56c38371489eddbb3df3e53e6767bd01e231eb122f13f59a83a35101844ab389954e8068f6d7128c738ac1774edc6465eae8ccbabcbb41271467c407d36928d9e3174c99665e3a9af0fc1b2733925b254a3aba050ec3925dabc511427c0b2930bca63ba7629366c1ba620cc0d7090752157b5d70c098745e37db7316056c7bb37c024226425107da8ba0e9c30e2606752f31a017e50a0e10c05332677ec851eae14f594a55d07392c23a962248ccee1221feb2c8f801860892b33ef2247b801e5ff55ba97675a71037fd133133840050b8b7914125e9d30165847319eb1e483005ca0bb8338b75eed618c47408d0260ddfb1527640a148f29e64f65fcafc59a8715a8126830024767009bad41a3385c0173be51a35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e2870961858852 +expected_private_key = cf8293b02a9a6f579f51066bd6e51abd270104634cfd482823102f2b63b18a8bb4f45a5af4d8202523cc1779b44fd283860bd004307c399ca5d8eacade156af824a988f5ac6bb50eafa6177a95b9752c922bd6a7c4265a6a88b11d0403e47127b1e80787742669e763929483393cad6ef91f18143e9d2b7cd3e028c6f56b91768113259bcab926a082a2a6185a1bf18656448a628258e21a3c6cca23449b4f9483ae9d01bdd4bc674e06566300ad2a215809e547e2626f8d9437baa727f3f05c31e85e4d34643148981bb6a82c3c75099a33a0e7528d45303d98223e1a4ef6536170f53a0c61004beb75fa34b8aed5156e4a538269775808283cb0ba5282607d50661d2a626fac2737c98cf33050353bb83e1c1136f1c26fe48d81973eb974ab1ba4b97c95c0dee065523430cc06620debba3db92888497658bc5c64b98be65ab2a0738f0750022b95a66c583354a63865b5237fe7098d279c53f731f3fcae8689754194a7b888199b89761fd09ff75677b2c500d7359905e76357163834712659f26d0d8c9b47192404975cfb89969a77615d1a3fb404baaa54511ff1b3b08c1577eb274f5b3b0b825434e87f60d18fa73141f912701a99a7c11305000789229a144a0899685596aa646f13573eba0b54dd3205de2c60c3ca1614066474b89f2377994bd14ee0a77e1d4c0af77748c1e623cb8947a98636694c4efaf0ce2bf779c66a317989a335a0071505831471c8d845a5fa4b3e42d195074244f70578124c4c7894ab84584daec8c13a6598524c023ca99f4c0499a68aca3e6827798b10ef9a4639605e2fe8656606438274ac8ed8c87ae0a16ba3b8e5857a7f25831d8b85bc7105828575320c6baba75489455154b31e50074a313ba9ad10b747f39405544f44949dde165070c8271f1ba80e57bb5bd1320c8a1f8fb47354079532bba51282ae3197026e18c46ae6b2ab9940eaba9f1ee421592770c9a9604263a4917c825c084c3534381f22c057592dd97940adb1a439d5128cf795cdd25640fa9229220a1ce4a6624cc9956105465246334c77ffcb9907159461cb1416637d8df34ab4b401413c27b6d5a1d23331f88273222653adf9685a614bec9840355b1a23a0c4ce60b0b678affed200bcb383bec2580c89127b2870745c15570ba1cec89f5dccc47be517bb020c57959e433c11df10810d5b37aa8ab3392b3358793246f11ece238646724beb859c861463c42b5030d9a1fdba3e1d391f9ca5a99df58a7948c66fa2b50864b73a40b52dc7cff031b3a3b21009268cd5cb00a89b44c156333b802ad03b2f07f70f7c11057ce78705ab6ee43681aff0874030807412a7743399cae832f6f3b65df56ab1b30d6967379e10b4ef53b9efb5632a23b942f832a7fa22cde494b0c7393d51ac807a38af119d526a5a3b91068e107812269ec85410aa739c288c20446b68880343f2e12157094dd424a349d1523e76c0acb9c29c22b6346386b522b0466bc8a85b97430a1df80850510c4825ec4f2aab987c4a07f11693e7bbb4662a4890a3c54ebc0cbbd75ca468428e38276e81c43d81a8d0e3bdbebac9aeb89fc9d7870bb88c5c16a137c41fee75640774c4b536bb1d7bbce797844d960c98359f5719b20dca6d1e2916f2829e73f79b55b468170b64f2f8b0c788796801c8ec244e1973c7e033b768414c55d43079b2711bda630e678b184a70dd161c4dabbcb91c07fb634620d1450664a444e82d22a0a4f54ac6c7c02d74120b2ce205fe49a139b9c8194341f4295ef126b37f3b22e35792a8853b60eb3f7ed01314491c4451470870a5ea5b1d23442019bc1def547fb8935ecbeba0833228b8d7bf2a4aca52436a3f993f6164666ebb3c38317bf5b48cc7182c00d58d4a095d0fd4c60e4229e77803c4f38f22464c7a4259e45ac71e8ccde6e5738dcc798777317f9847f8357dce21b24ae462d0465f1d58203f3b8590d88deb9c6df4722a1420a9ea0813ec3777a6cb11ca0271292b6c662a870c292291164004299c82442a8dd5404e74cfbcb45175237ae5649f7136cb47b9c6c053203f265bab420eee2c95a5960f8a87c3333785e1b89ff841a6aa5aa964f3a853e512acabb60e29c3a4810df33830134c0e49bc5e1ba41b07b671e1ba6bfda82576406e6da854920a46914c8ea986b1d6a0328d4a450fc0ce698b9d16954aaa0c52b6f2b5ff7b5347e84c3af403e9b31ec180238cd5af96f5c6f0d3644ab51717f7255ad6551f44378294778937cc56b610680704bfb37e3ccc07c5276777e37f36623dec8225388c3a5a2c7026eb902c63260ce27ffe657bce34a47db43667b9293e04ab9677b6fdb0b0a429a4435a9f5624628a2c07bbfa8afed562be4233019524e67cae6f955226437433bc59835561c462071ac38058c145787c242d4b6dc055170675190882792ea49726dc8b2cb638763784d3c23e1791c93a55383a8c4b59643626f8948d228b670312893ab3ce5b123401b1b24432545889d4d124d2b846070c1663b87a3475c01adc4f4df286fc91c76b018c05b5a26a696df86c4b1fbb2ed3050cc9b54ca2786839f854b9461655972fe21c3c98007a693a4d0b8aafa3ab73f1c411dd283cce59528477b6e089847ce6518f29b523602f80ac573618070bca649efb84fc3947d43b229e05682914c153809521ec9b7978a6bd667f59b18f1d986222dc9ab345ad2c7c7cc5799c15297c22c3734df18a218c5bacb364c9136b8e055053567a1856c21b96a1a2723913c98cc364bbd1fc4edef37e1853c523727a6c677ca4c82ac4d49238e1b60c1531d1dc9835c4a96124a0011c09350353aac4568a84293e8666f6016e56c38371489eddbb3df3e53e6767bd01e231eb122f13f59a83a35101844ab389954e8068f6d7128c738ac1774edc6465eae8ccbabcbb41271467c407d36928d9e3174c99665e3a9af0fc1b2733925b254a3aba050ec3925dabc511427c0b2930bca63ba7629366c1ba620cc0d7090752157b5d70c098745e37db7316056c7bb37c024226425107da8ba0e9c30e2606752f31a017e50a0e10c05332677ec851eae14f594a55d07392c23a962248ccee1221feb2c8f801860892b33ef2247b801e5ff55ba97675a71037fd133133840050b8b7914125e9d30165847319eb1e483005ca0bb8338b75eed618c47408d0260ddfb1527640a148f29e64f65fcafc59a8715a8126830024767009bad41a3385c0173be51a35f3825843b59fe06b5fc03dc21f6d925b9f6d92fff175c9dd625bfaf502b4e287096185885264e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d35aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec + +comment = Official test vector 97, seed: "59eff60b1ef6185db34ee1e3b1dd2f159106ceceaa79beb74923b4f5623d5bc52dbf5d2594a1f7c6c64d12cf144e9ed4" +entropy = ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab +expected_public_key = b49b9264faafe731c0dee965ac981965a28ff907ceabac477e2c9b6dc95aaeb0531cbcb65d8b3f6251be17ecaa89a5b57c1198ea66af1f4461b91c360e4531c4d49269896107f10ed1f1070e68cddb2a4e06c387f3126087a71a366a250b450be1567dc957bbd034b66ab65fd4eab2d89b8481ec2427a4af3c1b861c799263f492779053a0128508c86ebd6201c876bbe8ab8053b790314047a1901c9f327207b2130be5bce8504bb03817a380975cd81fe0c0416986a7b74a16a21146636abe4d2b2c5c1223d39265a6845804d49e5f160abfe3ca21a345b5d044afa5636c37b976f2894869bf4500c62ae9941b9b3c3e6064fec351268243fd75bf287cae8aaa9aaefc1cfba1032ad2623a6239a7f834a4826f86132b59ab24efc9c57cba929a64ba90271b987bc08a913298911650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348c6063aeb0bcee9066028b3340aa147b09c42752cfd6d491ffa497e17ab6c0726aefe59c2577764a1a996fd879e58c23f1c0ac9e9372b3f0be42c829b7b09acb722e3189a2b3e72124895ccab565dae583c6c76c34c2c0075568379639869325f6e92e0b91a2d4100b2f4aa6486b756cd521e1b781a964a21b8b0c72637a2e4299fe15c1ac275fb077cf42f36453e7603c91a648e09cbf128ed188639b7247584b333003a2175bc587925111654f24680c540b32643b035ff38bb4598785524504ebcb26163d513867d74744c8b562bd48989b3a328374a125ca05fa962ac08b0d22277e578206a165a9e3d31a084b4492c664448aa62986b55fe8c8420816a5a9c035644f592969fd0951b6e9aa57303d1f9927ff6b3de99263e2e11cd8317cfc899a45706746e9850922b9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc56285e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38c807f7274708aa0587f94a107089a99694fc627291c30fd6b0430eca692db54a96019eaf89635cf54f579a63048070b7f32dd2c32a18e2b7e8400344412e9dc5943bf3af11b4aa6c328499da7c220670958a22bffc89b8f0091c8665b6605571d8a1b5c934ce4686c7c047ae416bc6e39b7ccc92cb076de94001374217e9b8820354351cb377b4f06b7fbb69f64c7b48f781ded2cfee998718d875eb94866e7c5135358ea4ec92849978438c77cec1ba1803bf9933c8856657c953125eb76014bacca8ec9be6290936130d166b187e1463e55cae3ad85e96e81bc574220ab0cd374aa1f657abea849259b4431f1a00ee59b35486beb09302bf71b4c2e840963333b4a3be37f8048d42a0f67c886de9b47611555495248ad4c587577d45775f52135518793ea14582bf153c74210c36b9251609a4b28559ade5a93203725a475971b92beb88a69357bf83f384577cc1dfb62c70fc65401073c67a66af878fd961bacf46c633e7cac0e5092458cbba0c3b69494c4c0c0da6025cd6516c1ab89b3216bb9ba123040051563610251974a0b11be7190504522a128ca3107938f5b18e4441b52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb12f40ac971cb475610a0e6c546998dafe5c2ed852d7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c82 +expected_private_key = a428a1343429ce9c3dadbb6213410e264426d1cb5c69c68e7f377bcbc454aaf867771258faa622b6367fc5cc46e960682a3984a13230b3d7c25a69ce4ab9af0234a109878e0cc42a9b858dc559ad3fe82c4060539c08828c51b337b7c0ea768ba646a2f04900a235a4042b88e8934d3b62821a13b67a912f162aa80953cb71c396d91b91521b6665062551e0a6ce453c233460789138cb16ac6e598f670c70d6325804cc494466710d984e3ea551f5ec60c5031e94421919f62c301181831b7fb4fc61da443fe12784cf84b5ecf240daecc87d711aad10808b96233d345ba80b0469797dc03583214355e8e9a356e367a593a6898355ad129a8546a0d03b2279021889c118db3583da691a9ad544086540bb2178b2125f00c94ae753038486b6cdf1cf7e5a2202290b4e5ac807eb04bea95678b52ff76c4757c68d2eb9283b8766f1a39e06c999015b1f1d5c3164338aeb432d54b338c361b9a7258981555fc2563e585a6ff60886c32343e0045746e50fe78a0a9bcbb6281abe3474ba50e1267b3276a1327a8f128e2b5ab077618c59902c35488553f745d2a0c942b81c0aab7afd0c869b9b9c66c1847257cb22b018b81b25c468a9bc35a180b090f4bb90c4ec035c0078b799046833cd90f7bc2678cab9b75b95a6b457dca8fcb84937c01479a0b7b6da9643da507a2b8b1ae25373825189729bda8b35fcea315b3b359705cd5b486582379093e64f431309f0389ff899beb4c3ca9689b412a210eb654f183362ab8398b1e3696df7432be662cbe62666471f2c056504a5c1c91017a6326acc7306524058fd0937ddeab972b00734f60d065a1ba8655dba3093d161b99e698fc778b2fe782fa8ec7c62d422e17b24fd107b87a8338ae7af6994c70d959cbfc3720b3174b9658f5d43713cd47325eb926320073f384f04e6831435524b686f2cd377c18363f8e554dbe6af09f93c2ff2a1f4a87159472e7d7a4db9243a1c6a636ad50735b870f1297b6d6b5303e2552a54aa5991340aa40301ca2d6bd9a765b72fbde1c3c44a7649ea350e00cde59628e06acad29888c9b73cf0aa65d44b60f086c21c6abcbd544295317b55ea9ab1117989ab7b7304304e5612119396727943678c31cf2b1779c946b82420a557a8d6426263d33c7f71591c7857e90a7fa05158e315ae19d1046249b3011b22291cae30501d1423674824b852c34c97258ab972af6c5195ffa20b6cf05ba0498a529756f173349bec8c180869293c5967454d01cb3c8edc7a3a776dba54c37513727a69caacfbaad8ec4a529a1872ca25cb4a99c38b225e379ace27485d8b91fef9ceb97c04322b59f533745d23720ae457fa11b3a0b831de777d07f88ed1771fa1d89db9acbc7bac471bd423acac482bfb29de13881aeaaae2f340c1e747a73b9071cc551ea59b03646b65bc2e6e04875754a77025985a026adcd321574ab45cda47134b560219338fc93b0a398d7f85169b4b32c2ec3a06529f8e3a57fd353327b03f87d5cb60c67074146fb460476c92619d9c23ba7a371fd9425cfc6486992959109cfa1c1a75ab9eba4235af63c6f8648ae7855a4eab5c9d3923386996181980b16b02a53060e5a64a8cf3ced087bbb49b9264faafe731c0dee965ac981965a28ff907ceabac477e2c9b6dc95aaeb0531cbcb65d8b3f6251be17ecaa89a5b57c1198ea66af1f4461b91c360e4531c4d49269896107f10ed1f1070e68cddb2a4e06c387f3126087a71a366a250b450be1567dc957bbd034b66ab65fd4eab2d89b8481ec2427a4af3c1b861c799263f492779053a0128508c86ebd6201c876bbe8ab8053b790314047a1901c9f327207b2130be5bce8504bb03817a380975cd81fe0c0416986a7b74a16a21146636abe4d2b2c5c1223d39265a6845804d49e5f160abfe3ca21a345b5d044afa5636c37b976f2894869bf4500c62ae9941b9b3c3e6064fec351268243fd75bf287cae8aaa9aaefc1cfba1032ad2623a6239a7f834a4826f86132b59ab24efc9c57cba929a64ba90271b987bc08a913298911650399429e9bfc40742df735f7cb935eda73a41f96caacbb34324b29e64348c6063aeb0bcee9066028b3340aa147b09c42752cfd6d491ffa497e17ab6c0726aefe59c2577764a1a996fd879e58c23f1c0ac9e9372b3f0be42c829b7b09acb722e3189a2b3e72124895ccab565dae583c6c76c34c2c0075568379639869325f6e92e0b91a2d4100b2f4aa6486b756cd521e1b781a964a21b8b0c72637a2e4299fe15c1ac275fb077cf42f36453e7603c91a648e09cbf128ed188639b7247584b333003a2175bc587925111654f24680c540b32643b035ff38bb4598785524504ebcb26163d513867d74744c8b562bd48989b3a328374a125ca05fa962ac08b0d22277e578206a165a9e3d31a084b4492c664448aa62986b55fe8c8420816a5a9c035644f592969fd0951b6e9aa57303d1f9927ff6b3de99263e2e11cd8317cfc899a45706746e9850922b9a4f9cde515623f3c48b86379c969969934ccbec4bea3e9796889cbcc56285e9a85f0b3471bf9692f3c72ffd945089b9a262ac1a8844c38c807f7274708aa0587f94a107089a99694fc627291c30fd6b0430eca692db54a96019eaf89635cf54f579a63048070b7f32dd2c32a18e2b7e8400344412e9dc5943bf3af11b4aa6c328499da7c220670958a22bffc89b8f0091c8665b6605571d8a1b5c934ce4686c7c047ae416bc6e39b7ccc92cb076de94001374217e9b8820354351cb377b4f06b7fbb69f64c7b48f781ded2cfee998718d875eb94866e7c5135358ea4ec92849978438c77cec1ba1803bf9933c8856657c953125eb76014bacca8ec9be6290936130d166b187e1463e55cae3ad85e96e81bc574220ab0cd374aa1f657abea849259b4431f1a00ee59b35486beb09302bf71b4c2e840963333b4a3be37f8048d42a0f67c886de9b47611555495248ad4c587577d45775f52135518793ea14582bf153c74210c36b9251609a4b28559ade5a93203725a475971b92beb88a69357bf83f384577cc1dfb62c70fc65401073c67a66af878fd961bacf46c633e7cac0e5092458cbba0c3b69494c4c0c0da6025cd6516c1ab89b3216bb9ba123040051563610251974a0b11be7190504522a128ca3107938f5b18e4441b52f7944b0e54cd3946c57e7ae3475bec06791a9f5a83eacbb12f40ac971cb475610a0e6c546998dafe5c2ed852d7715b3dba61b94849dea30e28720bbcb90c7af7feb0af619a0cf57d173405c828dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964ce63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab + +comment = Official test vector 98, seed: "dddca9dc31bea737d3f474e7560b37facb2f53c803e768ffaade7669ff94b1d4fbd17068cffd5dfdd24aadada4ef6b12" +entropy = aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 +expected_public_key = bc962535672a8d77c9eaf9726cc1a8b8d87d61b1461f33b7f7f5a003a8657297cd100324fea561ba879ffa75287d9a838275734593abc2b842d9353906334d3f9324c7d00eed794c78310421db45cab6900817348d67490bf1485e85a3dfa255694915d286ab5243b62d3a91f8493f0b19626fb89c0b9109c6e1084bd8c848c06b3472a65a2646dd89be2d922a0d2c5e816652c826854ab36f44809ee56c9f7e26a1dc30823535997a05255756704aa1029b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e512b1c767347ae28ae046076c20179d0977d2d54a3f78add2ec6bc06071d9447f0461846fb1a5e91a760112424082c2994a98d07aab29e818fd15134de437c7fbc59469ce8ba80545a4a5bf337fe142b72e602d8a1b3009cc95975759ad38274e234aef0552b8aa65cdfcac975495a84c124f8426a9c87d8db03ce48b0382642cb9e31ce210b774724912b09b16d88ae007ac4542c092f9bbed9c262d823d9d5719b357821d4c245f384fc923cd334b9dff579e324a0bcfbcba61fb7ae9f69b3ab88693e005ee32bd1a6a3ca950a22421125391a060276b07242a795085d0098906969c421cbc469128fb5393b72590fd391dcdfa3cf87b9f7a4c6cc3a1791ae1717478a5280a3b7580bbedf88f0dd7c1c09aa67d6b284334049398ba983bcbacb8c56237bc3efb3fbfdcb358a006457832df7a01efd937e68b3299580cbe1c9f69e165d22683b3721e4189adaaa91846b7717d41baf8d9a1dc76c387f0b55c2552533326597466ecf06aca624fbf73226e471d835b0ee4a24a8f1c5fbe359c61d974a4d57c2f7c49822286ca27116839b784d6782c13b606b87804ba0969c7c47c7a29ce16cecff5514028c3d84944ec8cab4b4acb5b681723511087e25b8ae84f3741a2de6cc21e7a370b35c255c34555f29645d4b420494c4d993ba3f092ee240f1d3691753420891acfc9421c361ca2186b563ed63456096227eaa738a33ab56029976c1125dca790114aeb83aebcf271ed59bbc2e8377301b53d697cfabb4c6b40bae19b6cecd421a1109f9cac7b71c749e60a2005a30179c393d5033cb4f8795de4c98d91538fb9a8cb1654b1e6a82918471470461f54cc71fba50deb3e1221c55aa616ad5262e352adb7a89ca04557a2090fb05704b9521809b8cabfa325892ab46765cee83850586918422212c812373a1c6217ba890b4c5310f7b0d5d8275b884aa9e4914c85023ab53bea88ad4281a7f501a87534ac1d806b0f8691e9f1bc7171001043015b391cfac09b5fa88f840c63194632bd5a012b34b50441ba08c879c44654f136cccbb7114f7b4099016e0193cbbae63522927df4b740b3ca5b32b741ea15a47370b98926a1f90618f5235357e8087443c93444803dd22bbdd5340c876d41f3ac1db59e9ef17db71369a315600fc6801a54483fb015ad3766284a97cbc241ad73461f4b2a0f6645ef428805762a6e57474d29288404ad98fab63ae95e25436626bc66ee10c01e55103597288ac521b463886f863833948455319d3455110b68bf7bc495d1a922191a1a230a5f036c3c4ac05ee2609d09891ce368c01f037d818805a566193a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75 +expected_private_key = fa198bb15b4278509dc232002c75a8bbf1853c474c8248b5062821e4d77fd5880979922016d17377f76a89ab9477a1024c9780fb728f6df3295666828143c52fe817b9688c70eba292d2716ab4970840abc4603f597b5fcdeb0144813602242625a067ea48b426738dad0ab986369aa5326dd199c72212c59ab20c8f63429683721a2c682c5aa853b86542698732ab86fe39c340db2d452286fdd599336b9923599b66c144c0c7848c20a6979133fb7b5efa3726a4f44389cb93d6a9c1b7e300cb852698c236ac00b2855861c88bad062a25423362c7774c1626834ee59880762508fb518f926a3f475d01aa8e5c8c4140537091d494af66b0e9426359032a2264af67e63541c2408b1853f87c68c28c8c13417f94d77f6ac3315f23405c233e14f7762c152609ac34842553de175a6fe1c08b44baa9d15cf09a6049b05b69f71df322171701ae91d050778a6754e374878169181a2e1336677889318cb54218ac055491b918bc2553023167151c98b30e1340403e0c59b3252f4d0c85ebac1877798c41aa43c5c7b738b7ce116428c049370ba6665be646b3125aeb947b1f3b2ec5357c7566c13eab148c453d6b2274a9295a06c822df9222cb2026f19603b5602d08d46d4c71384e776af2a441894826e4559f5975c586e47bc0236b4897622ae4396160334cc97aca101805814ae44786d1e445147a4728275c32554b9bd148ae9605e10c5a6b556704f1c17297a32eb311f1e92ee5f160e8522e06554b93b5c796e44086e75d236ca88ecc533c3b348091891e35639bd6cbdb3a408720b6e3a328c4268454169267a5c5348703c412c58846c192e0a162014600dbb351424fa8d0599775bd2d851db4b07438f655aad6402628563db3a435f75d440636cd64041de162d178c923490839f190f106be0020ab63e7b3eb718a4fb59e01057c416c330cc26e485a6d9c72b707da0b297c0a25247d26d40f044844c2db883a5bbfc2b06f1bfbccc6d10b65c9bdbfb806d7a04cd71774dd60bc423c1dfa897a0512365cd54a90ba6ac509298bf6455363583843925281aa405c291f11695cda995a9ac5f742351560b38f8720d66327b4dcc47626744241679247cbe42695b8d81c37c718cad53d1b318f9f900757267c43b982f26639901028f8f636c35091f1ca90a1e329d5cb069a918f45a078f33ab4dfd248390627926aaddff47ecef1718b2b048304cd40e72fb0872b6207856a61bd764034e82bb426747405e1ae5b93c63cb12c7bf09e47e27117d26acbc102b043616e60b714316dfc17306a77800ee87e03e4b74759794ee6943dc274aec1a08197a841e68f258202b1124803064f6e3295dd51ad18949a5a383a81363bb00118a8569a38d138bf8835362c723e999402d3cf728b0e11f647ce2b9390615b9e50487e23cee6f9cefc4a1ce5e83d28d642e3c16934b43931158ccef3832a457a5e833f317918858807ab084f687a394c257abcd8435cd717d1e6b79e78a37bb71a236729839b89a9905b5d935afdc2c1e6c71c597898c6a69765ba05e9784b7849c685ab5b6de3358c6299d8a4b075045d6ee15b639601aa95603a67378157b54889c3021453e373208cd06c0deb77bc962535672a8d77c9eaf9726cc1a8b8d87d61b1461f33b7f7f5a003a8657297cd100324fea561ba879ffa75287d9a838275734593abc2b842d9353906334d3f9324c7d00eed794c78310421db45cab6900817348d67490bf1485e85a3dfa255694915d286ab5243b62d3a91f8493f0b19626fb89c0b9109c6e1084bd8c848c06b3472a65a2646dd89be2d922a0d2c5e816652c826854ab36f44809ee56c9f7e26a1dc30823535997a05255756704aa1029b86601e2853c2d34a192a9b2b76b31c69c1a048a76a6a58e48bc8e512b1c767347ae28ae046076c20179d0977d2d54a3f78add2ec6bc06071d9447f0461846fb1a5e91a760112424082c2994a98d07aab29e818fd15134de437c7fbc59469ce8ba80545a4a5bf337fe142b72e602d8a1b3009cc95975759ad38274e234aef0552b8aa65cdfcac975495a84c124f8426a9c87d8db03ce48b0382642cb9e31ce210b774724912b09b16d88ae007ac4542c092f9bbed9c262d823d9d5719b357821d4c245f384fc923cd334b9dff579e324a0bcfbcba61fb7ae9f69b3ab88693e005ee32bd1a6a3ca950a22421125391a060276b07242a795085d0098906969c421cbc469128fb5393b72590fd391dcdfa3cf87b9f7a4c6cc3a1791ae1717478a5280a3b7580bbedf88f0dd7c1c09aa67d6b284334049398ba983bcbacb8c56237bc3efb3fbfdcb358a006457832df7a01efd937e68b3299580cbe1c9f69e165d22683b3721e4189adaaa91846b7717d41baf8d9a1dc76c387f0b55c2552533326597466ecf06aca624fbf73226e471d835b0ee4a24a8f1c5fbe359c61d974a4d57c2f7c49822286ca27116839b784d6782c13b606b87804ba0969c7c47c7a29ce16cecff5514028c3d84944ec8cab4b4acb5b681723511087e25b8ae84f3741a2de6cc21e7a370b35c255c34555f29645d4b420494c4d993ba3f092ee240f1d3691753420891acfc9421c361ca2186b563ed63456096227eaa738a33ab56029976c1125dca790114aeb83aebcf271ed59bbc2e8377301b53d697cfabb4c6b40bae19b6cecd421a1109f9cac7b71c749e60a2005a30179c393d5033cb4f8795de4c98d91538fb9a8cb1654b1e6a82918471470461f54cc71fba50deb3e1221c55aa616ad5262e352adb7a89ca04557a2090fb05704b9521809b8cabfa325892ab46765cee83850586918422212c812373a1c6217ba890b4c5310f7b0d5d8275b884aa9e4914c85023ab53bea88ad4281a7f501a87534ac1d806b0f8691e9f1bc7171001043015b391cfac09b5fa88f840c63194632bd5a012b34b50441ba08c879c44654f136cccbb7114f7b4099016e0193cbbae63522927df4b740b3ca5b32b741ea15a47370b98926a1f90618f5235357e8087443c93444803dd22bbdd5340c876d41f3ac1db59e9ef17db71369a315600fc6801a54483fb015ad3766284a97cbc241ad73461f4b2a0f6645ef428805762a6e57474d29288404ad98fab63ae95e25436626bc66ee10c01e55103597288ac521b463886f863833948455319d3455110b68bf7bc495d1a922191a1a230a5f036c3c4ac05ee2609d09891ce368c01f037d818805a566193a433e924b30f4e86dc76ae2b345932a0e7025f8ce6101884469e31aeacaf4d77e3f1201bc75919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463fda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9 + +comment = Official test vector 99, seed: "2a6f7386b815366f572aeb6c79e272cc21b7095fe09575f18072c9d677da23bc9c8a4bc393b7524604d299bedd260c8b" +entropy = 195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 +expected_public_key = 28441cc07c18856568c4fc0eddc04175f564bda148788608b71756367551a5709127668efbd60b389877001b948f2c50ce62c7ed63122daa7c1889400a4175ab959d09ab124bea2c9d3659b8b4861e482eded950dbf57a47c87f79fbc143d20420f4162f711963c47dcf7b8ea7faa329d6a70f601d3a1b15a7890804917c84477d95f916a3761e3d94a0b0d69d9b7c39692b7f4acb9091f87583810ccf67bdf86c4be8f08762f2c3428646a3d33df4b67eb87a2662353a208403bf59334bd9758a9439f8d8bdd45195f2255282a73456d168a2b249e8d180d5b310ba828685b3a1daba2fb88783bb5062c13b79c2b0c3a10085664377eadbb477329567d1158882085850b95697248c6271f44988218777d33823ad70791bd40e29825ed124b963e05d06547c740a5ab7a1488e38c464b53b6f016ba1b7648a14aaa111907846c5df162f61cc62747386915724a3b054e868bc04c934d64b7f2ff461aae980fa806cca7a9c4d7255564b420887946f7a72e4d1384d8222c70330b09c08d9a70aa176529f0685d087b8f9eb464a776f93606b05d0729fd2afa7969eec2662ebb7c7fc821d6b5393707acf25c0c2c81702cb195f8cf730e8a46442e91e18fc7577f4aafd6933450491ee24763bf6786d794d889c3005a323cef2a8863c7ae00998d2e3ccc1f5a6c8a933d5d615ce82af312990969c6288b6893c42142ad87ab483362461b87c641f646410ef5b393283230220a34730397188920b6873f16478331cb22a5a2c73273d865985533a1f8e109dbde719c10c8ed87a831ab65562751ebbb15d3d5b6e01f78db26a54e47943d6b31f916a552ed01a39f96dff820765d6ae52265010545162d509f6ac3f9b7c0fd0ecad4008732d6a9df9449b2017b389522f11870704127bc6d018e0a420dd441ebf636c31b3b63da9c00dc15be0b3188371bbc855254217b99294815d78194fdabcd1970e31e38d37b4b1cc69bf428514f50ac9bcca9125e6473028571be535fca274651752dac691ff8a28c555036378b260acb060faba9573b0b65cbc76b892425294d65658f4a1b3309b424c6865bf1ab307b88022087f97f6882d4360ecd91f3d2513059a784bb256e47670afd5c1ad5c177142a2955b082fd0b546577ca5286e0f1c85af8b0bd5650038609e8ec8344e6ccb6df93a056644cb89294fa19266948e9a561bfa66517a900b67f6be5efb853c703ccb4a296a493c24607a6ac4a749361d8f738080a80ca62aaf658b6a972894e6ca402af3c09d2a6e9c181005e0c4d193361859011173bc8b97755fd1085b52808373b29733a7d0488c5f890364abb9716920c074645ae023679bc9c2b3ad29b9051a94a124a43688a1027c35b90f9303664aa37aa92284f97dbcc7ad0f12b5b6ba38ce0a07130110518c74ea36ca6d6a44399a3983101458f926e0bb3357bac5a294446463814806ad1623185f295d27f2c913c9608314174b2bb8bc03a92db6cc6f044d964a7e3e289ea8f064d9b5c0d0eb43357495d09c0fbc4069903bcdc683763bc4c6acc2517b7c94e3e0265029bff55773421bc6143a38f57410bfb50bf21bafec948548a87667d95439bb78cca2c9da670beb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8 +expected_private_key = 55873ec8c5bac259501e025faed327b9b659b0810e7d43b8bf7a25a8c1a51062cfbc9bbeab182747196797913398db1c1ca41c1cc3a883400a29797ab4cbb553076c204167aad2208355279f504dd9a476985362898b4e423821cc2642c335c3c953c866451cece03098d5a2ae366ddae1a06e05547e1c0c0667cc98494bfa778eebc5cbaccc3038f93b82e57f814799cb7a921fb14042aac83a1b4897bc6a15c87fc94144828966c49b6cb8f842a3157b60d6b3271c3661529d8a93c7daf7b4de1396308c0cbbfc9f984617cbb5b1825c88bdbc4c74c58ef3d54d089613a6a431e3a59acf4201fbb6828db0061f1bc514dcbfe72023cf8102e9834d5d6bba8a354fe04c6008b37f9b07857cda1238f5a562f288f3217ffd1a1bf8b2a0fcf3af0310c84bd6cd805c246c4a227c9bcf963093a9755cba968e7c06cc4f987b516171461b69e013076cb652c2a0b10f1b0fc9d6b583a929fa3905ba4b6b41f19d862c82b5f170277530a278773fa740eca749c00a61735aa1a27719cfb75eb0768956718239f43239e25a316339db665eb9784ab581137d020b992782956522b824b3ea4cb540a4b12ad7c512046711b0463f779e1279bcd2b7238580c72df6120850376db48978dc717cd1424d0b5e7331b76d0ac0b024c6283c8418e5b1a7a297aa483e5d2a65f2181ede32c69cc4b9a8c4c0b90bb17ec06336d2100766aed931876ce45435b5662dd8a5b9f545292c870a16925546ae0cecacfb737647504ea1a29d13e0bc2d060bf7480345051e9379cfb0f901b9a426641802e5522ff8b199439026b123cf9b5827ffa147567912c46c88cef0b41d9526d227a72262c0e3b3157dc4898e07caebc8038142b5172a799b8a6db0f7703730c98e1957fef13d5d7b2a52945eff5c4337b6cc5004bacbb419ba73568aa357f61c70383447c6015a5896b9c0c0a2f2c7a76d940278d736d6b685f4fb3cc392caac1830b439468b6bc73585b4205751e55103099986308702a477588611a990580d88657024fa6d371550141405a8240109824788675d2546afad54628e93281abccae4eac11d200aa5c40a9e440d9f2a40deb31c2688a3266c9e16b60461087da271a1973374c99693c8111f9d458f92ac3208268078b177c818038305ab421b6d8297063061bb36f1318bb2108163a723a4bfc3c2a25f958f28b2b806a15e4310b8852103843c8ac26c7773084f1f82151c52083e69772a049123027916f039fd08713b98039f3b84cc83a8f88b2c19f48a958a443339a5a2158dfd7a08d11983601a1892a8c1152c602edb1592c3ae555b2ee54c5dc6020c0b95626fc06d85d78120ac135fd369de6b6aa902bb015a7bc3ba13a7391960c533d2f1a6278494e78b6a3c5b91a2b1aa2a0752e5c0a30e33cc86dcba2e3232c98b9aaf1bbdf9e825b15a6dc3a741d43a53eb10ad18e93541e224ec5a952d673984990af0d81577d1bc83b09856794d11707faac63a1e49a799224b51464916bc07f0a69f06f26696f5806e92ca4ada050cda48a9c90635a9c68acc753a711115c35488758a68256a32f4964c431d50c0a8c5053d1a41126a952270a309f69931c32194fd201bc3809db548a000558528441cc07c18856568c4fc0eddc04175f564bda148788608b71756367551a5709127668efbd60b389877001b948f2c50ce62c7ed63122daa7c1889400a4175ab959d09ab124bea2c9d3659b8b4861e482eded950dbf57a47c87f79fbc143d20420f4162f711963c47dcf7b8ea7faa329d6a70f601d3a1b15a7890804917c84477d95f916a3761e3d94a0b0d69d9b7c39692b7f4acb9091f87583810ccf67bdf86c4be8f08762f2c3428646a3d33df4b67eb87a2662353a208403bf59334bd9758a9439f8d8bdd45195f2255282a73456d168a2b249e8d180d5b310ba828685b3a1daba2fb88783bb5062c13b79c2b0c3a10085664377eadbb477329567d1158882085850b95697248c6271f44988218777d33823ad70791bd40e29825ed124b963e05d06547c740a5ab7a1488e38c464b53b6f016ba1b7648a14aaa111907846c5df162f61cc62747386915724a3b054e868bc04c934d64b7f2ff461aae980fa806cca7a9c4d7255564b420887946f7a72e4d1384d8222c70330b09c08d9a70aa176529f0685d087b8f9eb464a776f93606b05d0729fd2afa7969eec2662ebb7c7fc821d6b5393707acf25c0c2c81702cb195f8cf730e8a46442e91e18fc7577f4aafd6933450491ee24763bf6786d794d889c3005a323cef2a8863c7ae00998d2e3ccc1f5a6c8a933d5d615ce82af312990969c6288b6893c42142ad87ab483362461b87c641f646410ef5b393283230220a34730397188920b6873f16478331cb22a5a2c73273d865985533a1f8e109dbde719c10c8ed87a831ab65562751ebbb15d3d5b6e01f78db26a54e47943d6b31f916a552ed01a39f96dff820765d6ae52265010545162d509f6ac3f9b7c0fd0ecad4008732d6a9df9449b2017b389522f11870704127bc6d018e0a420dd441ebf636c31b3b63da9c00dc15be0b3188371bbc855254217b99294815d78194fdabcd1970e31e38d37b4b1cc69bf428514f50ac9bcca9125e6473028571be535fca274651752dac691ff8a28c555036378b260acb060faba9573b0b65cbc76b892425294d65658f4a1b3309b424c6865bf1ab307b88022087f97f6882d4360ecd91f3d2513059a784bb256e47670afd5c1ad5c177142a2955b082fd0b546577ca5286e0f1c85af8b0bd5650038609e8ec8344e6ccb6df93a056644cb89294fa19266948e9a561bfa66517a900b67f6be5efb853c703ccb4a296a493c24607a6ac4a749361d8f738080a80ca62aaf658b6a972894e6ca402af3c09d2a6e9c181005e0c4d193361859011173bc8b97755fd1085b52808373b29733a7d0488c5f890364abb9716920c074645ae023679bc9c2b3ad29b9051a94a124a43688a1027c35b90f9303664aa37aa92284f97dbcc7ad0f12b5b6ba38ce0a07130110518c74ea36ca6d6a44399a3983101458f926e0bb3357bac5a294446463814806ad1623185f295d27f2c913c9608314174b2bb8bc03a92db6cc6f044d964a7e3e289ea8f064d9b5c0d0eb43357495d09c0fbc4069903bcdc683763bc4c6acc2517b7c94e3e0265029bff55773421bc6143a38f57410bfb50bf21bafec948548a87667d95439bb78cca2c9da670beb4c816478683b5487a4ce6401ec27a1605f879e2d9c53bf27e165246401cad7840a077934b8cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21 + diff --git a/tests/ml_kem_wycheproof_early.rs b/libcrux-kem/tests/ml_kem_wycheproof_early.rs similarity index 90% rename from tests/ml_kem_wycheproof_early.rs rename to libcrux-kem/tests/ml_kem_wycheproof_early.rs index 21bd4aa39..506816c4c 100644 --- a/tests/ml_kem_wycheproof_early.rs +++ b/libcrux-kem/tests/ml_kem_wycheproof_early.rs @@ -1,4 +1,4 @@ -use libcrux::kem::{ +use libcrux_kem::{ self, MlKem1024PrivateKey, MlKem1024PublicKey, MlKem512PrivateKey, MlKem512PublicKey, MlKem768PrivateKey, MlKem768PublicKey, MlKemCiphertext, }; @@ -35,7 +35,7 @@ macro_rules! impl_known_answer_test { fn $name() { // Encaps let katfile_path = Path::new("tests") - .join("kyber_kats") + .join("kats") .join("wycheproof_early") .join(format!("encaps{}draft", $parameter_set)); let katfile = File::open(katfile_path).expect("Could not open KAT file."); @@ -98,7 +98,7 @@ macro_rules! impl_known_answer_test { // Decaps let katfile_path = Path::new("tests") - .join("kyber_kats") + .join("kats") .join("wycheproof_early") .join(format!("decaps{}draft", $parameter_set)); let katfile = File::open(katfile_path).expect("Could not open KAT file."); @@ -169,10 +169,10 @@ macro_rules! impl_known_answer_test { impl_known_answer_test!( ml_kem512_wycheproof_early_kat, 512, - kem::deterministic::kyber512_generate_keypair_derand, - kem::deterministic::kyber512_encapsulate_derand, - kem::deterministic::kyber512_decapsulate_derand, - kem::ml_kem512_validate_public_key, + libcrux_kem::deterministic::mlkem512_generate_keypair_derand, + libcrux_kem::deterministic::mlkem512_encapsulate_derand, + libcrux_kem::deterministic::mlkem512_decapsulate_derand, + libcrux_kem::ml_kem512_validate_public_key, MlKem512PublicKey, MlKem512PrivateKey, 768, @@ -182,10 +182,10 @@ impl_known_answer_test!( impl_known_answer_test!( ml_kem768_wycheproof_early_kat, 768, - kem::deterministic::kyber768_generate_keypair_derand, - kem::deterministic::kyber768_encapsulate_derand, - kem::deterministic::kyber768_decapsulate_derand, - kem::ml_kem768_validate_public_key, + libcrux_kem::deterministic::mlkem768_generate_keypair_derand, + libcrux_kem::deterministic::mlkem768_encapsulate_derand, + libcrux_kem::deterministic::mlkem768_decapsulate_derand, + libcrux_kem::ml_kem768_validate_public_key, MlKem768PublicKey, MlKem768PrivateKey, 1088, @@ -195,10 +195,10 @@ impl_known_answer_test!( impl_known_answer_test!( ml_kem1024_wycheproof_early_kat, 1024, - kem::deterministic::kyber1024_generate_keypair_derand, - kem::deterministic::kyber1024_encapsulate_derand, - kem::deterministic::kyber1024_decapsulate_derand, - kem::ml_kem1024_validate_public_key, + libcrux_kem::deterministic::mlkem1024_generate_keypair_derand, + libcrux_kem::deterministic::mlkem1024_encapsulate_derand, + libcrux_kem::deterministic::mlkem1024_decapsulate_derand, + libcrux_kem::ml_kem1024_validate_public_key, MlKem1024PublicKey, MlKem1024PrivateKey, 1568, diff --git a/src/hpke/hpke.rs b/src/hpke/hpke.rs index 1348a3e4b..4d6343ed2 100644 --- a/src/hpke/hpke.rs +++ b/src/hpke/hpke.rs @@ -1,13 +1,11 @@ #![allow(non_camel_case_types, non_snake_case, unused_imports)] -use libcrux_ecdh::{secret_to_public, x25519_derive, X25519PublicKey}; +use libcrux_ecdh::{self, secret_to_public, x25519_derive, X25519PublicKey}; +use libcrux_ml_kem::mlkem768; -use crate::{ - ecdh, - kem::{ - self, kyber::kyber768, Ct, PublicKey, Ss, X25519MlKem768Draft00PrivateKey, - X25519MlKem768Draft00PublicKey, XWingKemDraft02PrivateKey, XWingKemDraft02PublicKey, - }, +use crate::kem::{ + self, Ct, PublicKey, Ss, X25519MlKem768Draft00PrivateKey, X25519MlKem768Draft00PublicKey, + XWingKemDraft02PrivateKey, XWingKemDraft02PublicKey, }; use super::aead::*; @@ -439,7 +437,7 @@ pub fn SetupBaseS( let XWingKemDraft02PublicKey { pk_m, pk_x } = XWingKemDraft02PublicKey::decode(pkR).map_err(|_| HpkeError::EncapError)?; - let (ct_m, ss_m) = kyber768::encapsulate( + let (ct_m, ss_m) = mlkem768::encapsulate( &pk_m, randomness[0..32] .try_into() diff --git a/src/hpke/kem.rs b/src/hpke/kem.rs index c4c93a98a..96e96bcd6 100644 --- a/src/hpke/kem.rs +++ b/src/hpke/kem.rs @@ -4,13 +4,13 @@ use libcrux_ecdh::{X25519PrivateKey, X25519PublicKey}; -use crate::kem::{ - kyber::{kyber768, MlKemKeyPair}, - *, -}; - use super::errors::*; use super::kdf::*; +use libcrux_kem::{ + Algorithm, X25519MlKem768Draft00PrivateKey, X25519MlKem768Draft00PublicKey, + XWingKemDraft02PrivateKey, XWingKemDraft02PublicKey, +}; +use libcrux_ml_kem::mlkem768; /// ## Key Encapsulation Mechanisms (KEMs) /// @@ -511,11 +511,12 @@ pub fn DeriveKeyPair(alg: KEM, ikm: &InputKeyMaterial) -> Result Result EncapResult /// /// FIXME: vec conversions and unwraps pub fn Kyber768Draft00_Encap(pkR: &PublicKeyIn, randomness: Randomness) -> EncapResult { - let (ct, ss) = kyber768::encapsulate(&pkR.try_into().unwrap(), randomness.try_into().unwrap()); + let (ct, ss) = mlkem768::encapsulate(&pkR.try_into().unwrap(), randomness.try_into().unwrap()); EncapResult::Ok((ss.as_ref().to_vec(), ct.as_ref().to_vec())) } @@ -626,7 +627,7 @@ pub fn Kyber768Draft00_Encap(pkR: &PublicKeyIn, randomness: Randomness) -> Encap /// /// FIXME: vec conversions and unwraps pub fn Kyber768Draft00_Decap(skR: &PrivateKeyIn, enc: &[u8]) -> Result { - Ok(kyber768::decapsulate(&skR.try_into().unwrap(), &enc.try_into().unwrap()).to_vec()) + Ok(mlkem768::decapsulate(&skR.try_into().unwrap(), &enc.try_into().unwrap()).to_vec()) } /// ```text diff --git a/src/kem.rs b/src/kem.rs index 62168208a..ed5a93123 100644 --- a/src/kem.rs +++ b/src/kem.rs @@ -31,712 +31,32 @@ //! //! [FIPS 203]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.ipd.pdf -use rand::{CryptoRng, Rng}; - -use crate::{ - ecdh::{self, p256_derive}, - hacl::sha3, -}; - -use libcrux_ecdh::{ - x25519_derive, P256PrivateKey, P256PublicKey, X25519PrivateKey, X25519PublicKey, -}; -// hacspec code: don't let clippy touch it. -#[allow(clippy::all)] -pub mod kyber; - -// TODO: These functions are currently exposed simply in order to make NIST KAT -// testing possible without an implementation of the NIST AES-CTR DRBG. Remove them -// (and change the visibility of the exported functions to pub(crate)) the -// moment we have an implementation of one. This is tracked by: -// https://github.com/cryspen/libcrux/issues/36 -#[cfg(feature = "tests")] -pub mod deterministic { - pub use super::kyber::kyber1024::decapsulate as kyber1024_decapsulate_derand; - pub use super::kyber::kyber1024::encapsulate as kyber1024_encapsulate_derand; - pub use super::kyber::kyber1024::generate_key_pair as kyber1024_generate_keypair_derand; - pub use super::kyber::kyber512::decapsulate as kyber512_decapsulate_derand; - pub use super::kyber::kyber512::encapsulate as kyber512_encapsulate_derand; - pub use super::kyber::kyber512::generate_key_pair as kyber512_generate_keypair_derand; - pub use super::kyber::kyber768::decapsulate as kyber768_decapsulate_derand; - pub use super::kyber::kyber768::encapsulate as kyber768_encapsulate_derand; - pub use super::kyber::kyber768::generate_key_pair as kyber768_generate_keypair_derand; -} - -use self::kyber::MlKemSharedSecret; -use self::kyber::{kyber1024, kyber512, kyber768}; -pub use kyber::{ - kyber1024::{MlKem1024Ciphertext, MlKem1024PrivateKey, MlKem1024PublicKey}, - kyber512::{MlKem512Ciphertext, MlKem512PrivateKey, MlKem512PublicKey}, - kyber768::{MlKem768Ciphertext, MlKem768PrivateKey, MlKem768PublicKey}, +pub use libcrux_ml_kem::{ + mlkem1024::{MlKem1024Ciphertext, MlKem1024PrivateKey, MlKem1024PublicKey}, + mlkem512::{MlKem512Ciphertext, MlKem512PrivateKey, MlKem512PublicKey}, + mlkem768::{MlKem768Ciphertext, MlKem768PrivateKey, MlKem768PublicKey}, MlKemCiphertext, MlKemKeyPair, }; -#[cfg(feature = "tests")] -pub use kyber::{ - kyber1024::validate_public_key as ml_kem1024_validate_public_key, - kyber512::validate_public_key as ml_kem512_validate_public_key, - kyber768::validate_public_key as ml_kem768_validate_public_key, -}; - -/// KEM Algorithms -/// -/// This includes named elliptic curves or dedicated KEM algorithms like Kyber. -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum Algorithm { - X25519, - X448, - Secp256r1, - Secp384r1, - Secp521r1, - MlKem512, - MlKem768, - X25519MlKem768Draft00, - XWingKemDraft02, - MlKem1024, -} - -#[derive(Debug, PartialEq, Eq)] -pub enum Error { - EcDhError(ecdh::Error), - KeyGen, - Encapsulate, - Decapsulate, - UnsupportedAlgorithm, - InvalidPrivateKey, - InvalidPublicKey, - InvalidCiphertext, -} - -impl TryFrom for ecdh::Algorithm { - type Error = &'static str; - - fn try_from(value: Algorithm) -> Result { - match value { - Algorithm::X25519 => Ok(ecdh::Algorithm::X25519), - Algorithm::X448 => Ok(ecdh::Algorithm::X448), - Algorithm::Secp256r1 => Ok(ecdh::Algorithm::P256), - Algorithm::Secp384r1 => Ok(ecdh::Algorithm::P384), - Algorithm::Secp521r1 => Ok(ecdh::Algorithm::P521), - Algorithm::X25519MlKem768Draft00 => Ok(ecdh::Algorithm::X25519), - Algorithm::XWingKemDraft02 => Ok(ecdh::Algorithm::X25519), - _ => Err("provided algorithm is not an ECDH algorithm"), - } - } -} - -impl From for Error { - fn from(value: ecdh::Error) -> Self { - Error::EcDhError(value) - } -} - -/// An ML-KEM768-x25519 private key. -pub struct X25519MlKem768Draft00PrivateKey { - pub mlkem: MlKem768PrivateKey, - pub x25519: X25519PrivateKey, -} - -impl X25519MlKem768Draft00PrivateKey { - pub fn decode(bytes: &[u8]) -> Result { - Ok(Self { - mlkem: bytes[32..] - .try_into() - .map_err(|_| Error::InvalidPrivateKey)?, - x25519: bytes[..32] - .try_into() - .map_err(|_| Error::InvalidPrivateKey)?, - }) - } - - pub fn encode(&self) -> Vec { - let mut out = self.x25519.0.to_vec(); - out.extend_from_slice(self.mlkem.as_ref()); - out - } -} - -/// An X-Wing private key. -pub struct XWingKemDraft02PrivateKey { - pub sk_m: MlKem768PrivateKey, - pub sk_x: X25519PrivateKey, - pub pk_x: X25519PublicKey, -} - -impl XWingKemDraft02PrivateKey { - pub fn decode(bytes: &[u8]) -> Result { - Ok(Self { - sk_m: bytes[..2400] - .try_into() - .map_err(|_| Error::InvalidPrivateKey)?, - sk_x: bytes[2400..2432] - .try_into() - .map_err(|_| Error::InvalidPrivateKey)?, - pk_x: bytes[2432..2464] - .try_into() - .map_err(|_| Error::InvalidPrivateKey)?, - }) - } - - pub fn encode(&self) -> Vec { - let mut out = self.sk_m.as_ref().to_vec(); - out.extend_from_slice(self.sk_x.0.to_vec().as_ref()); - out.extend_from_slice(self.pk_x.0.to_vec().as_ref()); - out - } -} - -/// A KEM private key. -pub enum PrivateKey { - X25519(X25519PrivateKey), - P256(P256PrivateKey), - MlKem512(MlKem512PrivateKey), - MlKem768(MlKem768PrivateKey), - X25519MlKem768Draft00(X25519MlKem768Draft00PrivateKey), - XWingKemDraft02(XWingKemDraft02PrivateKey), - MlKem1024(MlKem1024PrivateKey), -} - -/// An ML-KEM768-x25519 public key. -pub struct X25519MlKem768Draft00PublicKey { - pub mlkem: MlKem768PublicKey, - pub x25519: X25519PublicKey, -} - -impl X25519MlKem768Draft00PublicKey { - pub fn decode(bytes: &[u8]) -> Result { - Ok(Self { - mlkem: MlKem768PublicKey::try_from(&bytes[32..]) - .ok() - .and_then(kyber768::validate_public_key) - .ok_or(Error::InvalidPublicKey)?, - x25519: bytes[0..32] - .try_into() - .map_err(|_| Error::InvalidPublicKey)?, - }) - } - - pub fn encode(&self) -> Vec { - let mut out = self.x25519.0.to_vec(); - out.extend_from_slice(self.mlkem.as_ref()); - out - } -} - -/// An X-Wing public key. -pub struct XWingKemDraft02PublicKey { - pub pk_m: MlKem768PublicKey, - pub pk_x: X25519PublicKey, -} - -impl XWingKemDraft02PublicKey { - pub fn decode(bytes: &[u8]) -> Result { - Ok(Self { - pk_m: MlKem768PublicKey::try_from(&bytes[0..1184]) - .ok() - .and_then(kyber768::validate_public_key) - .ok_or(Error::InvalidPublicKey)?, - pk_x: bytes[1184..] - .try_into() - .map_err(|_| Error::InvalidPublicKey)?, - }) - } - - pub fn encode(&self) -> Vec { - let mut out = self.pk_m.as_ref().to_vec(); - out.extend_from_slice(self.pk_x.0.to_vec().as_ref()); - out - } -} - -/// A KEM public key. -pub enum PublicKey { - X25519(X25519PublicKey), - P256(P256PublicKey), - MlKem512(MlKem512PublicKey), - MlKem768(MlKem768PublicKey), - X25519MlKem768Draft00(X25519MlKem768Draft00PublicKey), - XWingKemDraft02(XWingKemDraft02PublicKey), - MlKem1024(MlKem1024PublicKey), -} - -/// A KEM ciphertext -pub enum Ct { - X25519(X25519PublicKey), - P256(P256PublicKey), - MlKem512(MlKem512Ciphertext), - MlKem768(MlKem768Ciphertext), - X25519MlKem768Draft00(MlKem768Ciphertext, X25519PublicKey), - XWingKemDraft02(MlKem768Ciphertext, X25519PublicKey), - MlKem1024(MlKem1024Ciphertext), -} - -impl Ct { - /// Decapsulate the shared secret in `ct` using the private key `sk`. - pub fn decapsulate(&self, sk: &PrivateKey) -> Result { - match self { - Ct::X25519(ct) => { - let sk = if let PrivateKey::X25519(k) = sk { - k - } else { - return Err(Error::InvalidPrivateKey); - }; - x25519_derive(ct, sk).map_err(|e| e.into()).map(Ss::X25519) - } - Ct::P256(ct) => { - let sk = if let PrivateKey::P256(k) = sk { - k - } else { - return Err(Error::InvalidPrivateKey); - }; - p256_derive(ct, sk).map_err(|e| e.into()).map(Ss::P256) - } - Ct::MlKem512(ct) => { - let sk = if let PrivateKey::MlKem512(k) = sk { - k - } else { - return Err(Error::InvalidPrivateKey); - }; - let ss = kyber::kyber512::decapsulate(sk, ct); - - Ok(Ss::MlKem768(ss)) - } - Ct::MlKem768(ct) => { - let sk = if let PrivateKey::MlKem768(k) = sk { - k - } else { - return Err(Error::InvalidPrivateKey); - }; - let ss = kyber768::decapsulate(sk, ct); - - Ok(Ss::MlKem768(ss)) - } - Ct::X25519MlKem768Draft00(kct, xct) => { - let (ksk, xsk) = - if let PrivateKey::X25519MlKem768Draft00(X25519MlKem768Draft00PrivateKey { - mlkem: kk, - x25519: xk, - }) = sk - { - (kk, xk) - } else { - return Err(Error::InvalidPrivateKey); - }; - let kss = kyber768::decapsulate(ksk, kct); - let xss = x25519_derive(xct, xsk)?; - - Ok(Ss::X25519MlKem768Draft00(kss, xss)) - } - Ct::XWingKemDraft02(ct_m, ct_x) => { - let (sk_m, sk_x, pk_x) = - if let PrivateKey::XWingKemDraft02(XWingKemDraft02PrivateKey { - sk_m, - sk_x, - pk_x, - }) = sk - { - (sk_m, sk_x, pk_x) - } else { - return Err(Error::InvalidPrivateKey); - }; - let ss_m = kyber768::decapsulate(sk_m, ct_m); - let ss_x = x25519_derive(ct_x, sk_x)?; - - Ok(Ss::XWingKemDraft02( - ss_m, - ss_x, - X25519PublicKey(ct_x.0.clone()), - X25519PublicKey(pk_x.0.clone()), - )) - } - Ct::MlKem1024(ct) => { - let sk = if let PrivateKey::MlKem1024(k) = sk { - k - } else { - return Err(Error::InvalidPrivateKey); - }; - let ss = kyber::kyber1024::decapsulate(sk, ct); - - Ok(Ss::MlKem1024(ss)) - } - } - } -} - -/// A KEM shared secret -pub enum Ss { - X25519(X25519PublicKey), - P256(P256PublicKey), - MlKem512(MlKemSharedSecret), - MlKem768(MlKemSharedSecret), - X25519MlKem768Draft00(MlKemSharedSecret, X25519PublicKey), - XWingKemDraft02( - MlKemSharedSecret, // ss_M - X25519PublicKey, // ss_X - X25519PublicKey, // ct_X - X25519PublicKey, // pk_X - ), - MlKem1024(MlKemSharedSecret), -} - -impl PrivateKey { - /// Encode a private key. - pub fn encode(&self) -> Vec { - match self { - PrivateKey::X25519(k) => k.0.to_vec(), - PrivateKey::P256(k) => k.0.to_vec(), - PrivateKey::MlKem512(k) => k.as_slice().to_vec(), - PrivateKey::MlKem768(k) => k.as_slice().to_vec(), - PrivateKey::X25519MlKem768Draft00(k) => k.encode(), - PrivateKey::XWingKemDraft02(k) => k.encode(), - PrivateKey::MlKem1024(k) => k.as_slice().to_vec(), - } - } - - /// Decode a private key. - pub fn decode(alg: Algorithm, bytes: &[u8]) -> Result { - match alg { - Algorithm::X25519 => bytes - .try_into() - .map_err(|_| Error::InvalidPrivateKey) - .map(Self::X25519), - Algorithm::Secp256r1 => bytes - .try_into() - .map_err(|_| Error::InvalidPrivateKey) - .map(Self::P256), - Algorithm::MlKem512 => bytes - .try_into() - .map_err(|_| Error::InvalidPrivateKey) - .map(Self::MlKem512), - Algorithm::MlKem768 => bytes - .try_into() - .map_err(|_| Error::InvalidPrivateKey) - .map(Self::MlKem768), - Algorithm::X25519MlKem768Draft00 => { - let key: [u8; kyber768::SECRET_KEY_SIZE_768 + 32] = - bytes.try_into().map_err(|_| Error::InvalidPrivateKey)?; - let (ksk, xsk) = key.split_at(kyber768::SECRET_KEY_SIZE_768); - Ok(Self::X25519MlKem768Draft00( - X25519MlKem768Draft00PrivateKey { - mlkem: ksk.try_into().map_err(|_| Error::InvalidPrivateKey)?, - x25519: xsk.try_into().map_err(|_| Error::InvalidPrivateKey)?, - }, - )) - } - Algorithm::XWingKemDraft02 => { - let pk = XWingKemDraft02PrivateKey::decode(bytes) - .map_err(|_| Error::InvalidPrivateKey)?; - Ok(Self::XWingKemDraft02(pk)) - } - Algorithm::MlKem1024 => bytes - .try_into() - .map_err(|_| Error::InvalidPrivateKey) - .map(Self::MlKem1024), - _ => Err(Error::UnsupportedAlgorithm), - } - } -} - -impl PublicKey { - /// Encapsulate a shared secret to the provided `pk` and return the `(Key, Enc)` tuple. - pub fn encapsulate(&self, rng: &mut (impl CryptoRng + Rng)) -> Result<(Ss, Ct), Error> { - match self { - PublicKey::X25519(pk) => { - let (new_sk, new_pk) = ecdh::x25519_key_gen(rng)?; - let gxy = x25519_derive(pk, &new_sk)?; - Ok((Ss::X25519(gxy), Ct::X25519(new_pk))) - } - PublicKey::P256(pk) => { - let (new_sk, new_pk) = ecdh::p256_key_gen(rng)?; - let gxy = p256_derive(pk, &new_sk)?; - Ok((Ss::P256(gxy), Ct::P256(new_pk))) - } - - PublicKey::MlKem512(pk) => { - let seed = kyber_rand(rng)?; - let (ct, ss) = kyber::kyber512::encapsulate(pk, seed); - Ok((Ss::MlKem512(ss), Ct::MlKem512(ct))) - } - - PublicKey::MlKem768(pk) => { - let seed = kyber_rand(rng)?; - let (ct, ss) = kyber768::encapsulate(pk, seed); - Ok((Ss::MlKem768(ss), Ct::MlKem768(ct))) - } - - PublicKey::MlKem1024(pk) => { - let seed = kyber_rand(rng)?; - let (ct, ss) = kyber1024::encapsulate(pk, seed); - Ok((Ss::MlKem1024(ss), Ct::MlKem1024(ct))) - } - - PublicKey::X25519MlKem768Draft00(X25519MlKem768Draft00PublicKey { - mlkem: kpk, - x25519: xpk, - }) => { - let seed = kyber_rand(rng)?; - let (kyber_ct, kyber_ss) = kyber768::encapsulate(kpk, seed); - let (x_sk, x_pk) = ecdh::x25519_key_gen(rng)?; - let x_ss = x25519_derive(xpk, &x_sk)?; - - Ok(( - Ss::X25519MlKem768Draft00(kyber_ss, x_ss), - Ct::X25519MlKem768Draft00(kyber_ct, x_pk), - )) - } - - PublicKey::XWingKemDraft02(XWingKemDraft02PublicKey { pk_m, pk_x }) => { - let seed = kyber_rand(rng)?; - let (ct_m, ss_m) = kyber768::encapsulate(pk_m, seed); - let (ek_x, ct_x) = ecdh::x25519_key_gen(rng)?; - let ss_x = x25519_derive(pk_x, &ek_x)?; - - Ok(( - Ss::XWingKemDraft02( - ss_m, - ss_x, - X25519PublicKey(ct_x.0.clone()), - X25519PublicKey(pk_x.0.clone()), - ), - Ct::XWingKemDraft02(ct_m, X25519PublicKey(ct_x.0.clone())), - )) - } - } - } +pub use libcrux_kem::Algorithm; +pub use libcrux_kem::Error; - /// Encode public key. - pub fn encode(&self) -> Vec { - match self { - PublicKey::X25519(k) => k.0.to_vec(), - PublicKey::P256(k) => k.0.to_vec(), - PublicKey::MlKem512(k) => k.as_ref().to_vec(), - PublicKey::MlKem768(k) => k.as_ref().to_vec(), - PublicKey::X25519MlKem768Draft00(k) => k.encode(), - PublicKey::XWingKemDraft02(k) => k.encode(), - PublicKey::MlKem1024(k) => k.as_ref().to_vec(), - } - } +pub use libcrux_kem::X25519MlKem768Draft00PrivateKey; - /// Decode a public key. - pub fn decode(alg: Algorithm, bytes: &[u8]) -> Result { - match alg { - Algorithm::X25519 => bytes - .try_into() - .map(Self::X25519) - .map_err(|_| Error::InvalidPublicKey), - Algorithm::Secp256r1 => bytes - .try_into() - .map(Self::P256) - .map_err(|_| Error::InvalidPublicKey), - Algorithm::MlKem512 => MlKem512PublicKey::try_from(bytes) - .ok() - .and_then(kyber512::validate_public_key) - .map(Self::MlKem512) - .ok_or(Error::InvalidPublicKey), - Algorithm::MlKem768 => MlKem768PublicKey::try_from(bytes) - .ok() - .and_then(kyber768::validate_public_key) - .map(Self::MlKem768) - .ok_or(Error::InvalidPublicKey), - Algorithm::X25519MlKem768Draft00 => { - X25519MlKem768Draft00PublicKey::decode(bytes).map(Self::X25519MlKem768Draft00) - } - Algorithm::XWingKemDraft02 => { - XWingKemDraft02PublicKey::decode(bytes).map(Self::XWingKemDraft02) - } - Algorithm::MlKem1024 => MlKem1024PublicKey::try_from(bytes) - .ok() - .and_then(kyber1024::validate_public_key) - .map(Self::MlKem1024) - .ok_or(Error::InvalidPublicKey), - _ => Err(Error::UnsupportedAlgorithm), - } - } -} +pub use libcrux_kem::XWingKemDraft02PrivateKey; -impl Ss { - /// Encode a shared secret. - pub fn encode(&self) -> Vec { - match self { - Ss::X25519(k) => k.0.to_vec(), - Ss::P256(k) => k.0.to_vec(), - Ss::MlKem512(k) => k.as_ref().to_vec(), - Ss::MlKem768(k) => k.as_ref().to_vec(), - Ss::X25519MlKem768Draft00(kk, xk) => { - let mut out = xk.0.to_vec(); - out.extend_from_slice(kk.as_ref()); - out - } - Ss::XWingKemDraft02(ss_m, ss_x, ct_x, pk_x) => { - // \./ - // /^\ - // 5c2e2f2f5e5c - let mut input = vec![0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c]; - input.extend_from_slice(ss_m.as_ref()); - input.extend_from_slice(ss_x.as_ref()); - input.extend_from_slice(ct_x.0.as_ref()); - input.extend_from_slice(pk_x.0.as_ref()); - sha3::sha256(&input).to_vec() - } - Ss::MlKem1024(k) => k.as_ref().to_vec(), - } - } -} +pub use libcrux_kem::PrivateKey; -impl Ct { - /// Encode a ciphertext. - pub fn encode(&self) -> Vec { - match self { - Ct::X25519(k) => k.0.to_vec(), - Ct::P256(k) => k.0.to_vec(), - Ct::MlKem512(k) => k.as_ref().to_vec(), - Ct::MlKem768(k) => k.as_ref().to_vec(), - Ct::X25519MlKem768Draft00(kk, xk) => { - let mut out = xk.0.to_vec(); - out.extend_from_slice(kk.as_ref()); - out - } - Ct::XWingKemDraft02(ct_m, ct_x) => { - let mut out = ct_m.as_ref().to_vec(); - out.extend_from_slice(ct_x.as_ref()); - out - } - Ct::MlKem1024(k) => k.as_ref().to_vec(), - } - } +pub use libcrux_kem::X25519MlKem768Draft00PublicKey; - /// Decode a ciphertext. - pub fn decode(alg: Algorithm, bytes: &[u8]) -> Result { - match alg { - Algorithm::X25519 => bytes - .try_into() - .map_err(|_| Error::InvalidCiphertext) - .map(Self::X25519), - Algorithm::Secp256r1 => bytes - .try_into() - .map_err(|_| Error::InvalidCiphertext) - .map(Self::P256), - Algorithm::MlKem512 => bytes - .try_into() - .map_err(|_| Error::InvalidCiphertext) - .map(Self::MlKem512), - Algorithm::MlKem768 => bytes - .try_into() - .map_err(|_| Error::InvalidCiphertext) - .map(Self::MlKem768), - Algorithm::X25519MlKem768Draft00 => { - let key: [u8; kyber768::CPA_PKE_CIPHERTEXT_SIZE_768 + 32] = - bytes.try_into().map_err(|_| Error::InvalidCiphertext)?; - let (kct, xct) = key.split_at(kyber768::CPA_PKE_CIPHERTEXT_SIZE_768); - Ok(Self::X25519MlKem768Draft00( - kct.try_into().map_err(|_| Error::InvalidCiphertext)?, - xct.try_into().map_err(|_| Error::InvalidCiphertext)?, - )) - } - Algorithm::XWingKemDraft02 => { - let key: [u8; kyber768::CPA_PKE_CIPHERTEXT_SIZE_768 + 32] = - bytes.try_into().map_err(|_| Error::InvalidCiphertext)?; - let (ct_m, ct_x) = key.split_at(kyber768::CPA_PKE_CIPHERTEXT_SIZE_768); - Ok(Self::XWingKemDraft02( - ct_m.try_into().map_err(|_| Error::InvalidCiphertext)?, - ct_x.try_into().map_err(|_| Error::InvalidCiphertext)?, - )) - } - Algorithm::MlKem1024 => bytes - .try_into() - .map_err(|_| Error::InvalidCiphertext) - .map(Self::MlKem1024), - _ => Err(Error::UnsupportedAlgorithm), - } - } -} +pub use libcrux_kem::XWingKemDraft02PublicKey; -/// Compute the public key for a private key of the given [`Algorithm`]. -/// Applicable only to X25519 and secp256r1. -pub fn secret_to_public(alg: Algorithm, sk: impl AsRef<[u8]>) -> Result, Error> { - match alg { - Algorithm::X25519 | Algorithm::Secp256r1 => { - ecdh::secret_to_public(alg.try_into().unwrap(), sk.as_ref()).map_err(|e| e.into()) - } - _ => Err(Error::UnsupportedAlgorithm), - } -} +pub use libcrux_kem::PublicKey; -fn gen_kyber768( - rng: &mut (impl CryptoRng + Rng), -) -> Result<(MlKem768PrivateKey, MlKem768PublicKey), Error> { - let MlKemKeyPair { sk, pk } = kyber768::generate_key_pair(random_array(rng)?); - Ok((sk, pk)) -} +pub use libcrux_kem::Ct; -fn random_array(rng: &mut (impl CryptoRng + Rng)) -> Result<[u8; L], Error> { - let mut seed = [0; L]; - rng.try_fill_bytes(&mut seed).map_err(|_| Error::KeyGen)?; - Ok(seed) -} +pub use libcrux_kem::Ss; -/// Generate a key pair for the [`Algorithm`] using the provided rng. -/// -/// The function returns a fresh key or a [`Error::KeyGen`] error if -/// * not enough entropy was available -/// * it was not possible to generate a valid key within a reasonable amount of iterations. -pub fn key_gen( - alg: Algorithm, - rng: &mut (impl CryptoRng + Rng), -) -> Result<(PrivateKey, PublicKey), Error> { - match alg { - Algorithm::X25519 => ecdh::x25519_key_gen(rng) - .map_err(|e| e.into()) - .map(|(private, public)| (PrivateKey::X25519(private), PublicKey::X25519(public))), - Algorithm::Secp256r1 => ecdh::p256_key_gen(rng) - .map_err(|e| e.into()) - .map(|(private, public)| (PrivateKey::P256(private), PublicKey::P256(public))), - Algorithm::MlKem512 => { - let MlKemKeyPair { sk, pk } = kyber512::generate_key_pair(random_array(rng)?); - Ok((PrivateKey::MlKem512(sk), PublicKey::MlKem512(pk))) - } - Algorithm::MlKem768 => { - let MlKemKeyPair { sk, pk } = kyber768::generate_key_pair(random_array(rng)?); - Ok((PrivateKey::MlKem768(sk), PublicKey::MlKem768(pk))) - } - Algorithm::MlKem1024 => { - let MlKemKeyPair { sk, pk } = kyber1024::generate_key_pair(random_array(rng)?); - Ok((PrivateKey::MlKem1024(sk), PublicKey::MlKem1024(pk))) - } - Algorithm::X25519MlKem768Draft00 => { - let (kyber_private, kyber_public) = gen_kyber768(rng)?; - let (x25519_private, x25519_public) = ecdh::x25519_key_gen(rng)?; - Ok(( - PrivateKey::X25519MlKem768Draft00(X25519MlKem768Draft00PrivateKey { - mlkem: kyber_private, - x25519: x25519_private, - }), - PublicKey::X25519MlKem768Draft00(X25519MlKem768Draft00PublicKey { - mlkem: kyber_public, - x25519: x25519_public, - }), - )) - } - Algorithm::XWingKemDraft02 => { - let (sk_m, pk_m) = gen_kyber768(rng)?; - let (sk_x, pk_x) = ecdh::x25519_key_gen(rng)?; - Ok(( - PrivateKey::XWingKemDraft02(XWingKemDraft02PrivateKey { - sk_m, - sk_x, - pk_x: X25519PublicKey(pk_x.0.clone()), - }), - PublicKey::XWingKemDraft02(XWingKemDraft02PublicKey { pk_m, pk_x }), - )) - } - _ => Err(Error::UnsupportedAlgorithm), - } -} +pub use libcrux_kem::secret_to_public; -fn kyber_rand( - rng: &mut (impl CryptoRng + Rng), -) -> Result<[u8; kyber::constants::SHARED_SECRET_SIZE], Error> { - let mut seed = [0; kyber::constants::SHARED_SECRET_SIZE]; - rng.try_fill_bytes(&mut seed).map_err(|_| Error::KeyGen)?; - Ok(seed) -} +pub use libcrux_kem::key_gen; diff --git a/tests/kyber.rs b/tests/kyber.rs deleted file mode 100644 index 1e6bcfe06..000000000 --- a/tests/kyber.rs +++ /dev/null @@ -1,248 +0,0 @@ -use libcrux::{ - digest::shake256, - kem::{self, Algorithm, Ct, PrivateKey}, -}; - -use rand::{CryptoRng, Rng}; - -#[cfg(not(target_arch = "wasm32"))] -use libcrux::drbg; -#[cfg(target_arch = "wasm32")] -use rand_core::OsRng; - -const SHARED_SECRET_SIZE: usize = 32; - -macro_rules! impl_consistency { - ($name:ident, $alg:expr) => { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[test] - fn $name() { - #[cfg(not(target_arch = "wasm32"))] - let mut rng = drbg::Drbg::new(libcrux::digest::Algorithm::Sha256).unwrap(); - #[cfg(target_arch = "wasm32")] - let mut rng = OsRng; - - if let Ok((secret_key, public_key)) = kem::key_gen($alg, &mut rng) { - if let Ok((shared_secret, ciphertext)) = public_key.encapsulate(&mut rng) { - let shared_secret_decapsulated = ciphertext.decapsulate(&secret_key).unwrap(); - assert_eq!(shared_secret.encode(), shared_secret_decapsulated.encode()); - } - } - - // If the randomness was not enough for the rejection sampling step - // in key-generation and encapsulation, simply return without - // failing. - } - }; -} - -macro_rules! impl_consistency_unpacked { - ($name:ident, $alg:expr) => { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[test] - fn $name() { - use rand::RngCore; - use rand_core::OsRng; - let mut rng = OsRng; - - let mut seed = [0; 64]; - rng.fill_bytes(&mut seed); - let (sk_state, pubkey) = - libcrux::kem::kyber::kyber768::generate_key_pair_unpacked(seed.clone()); - - let kp = libcrux::kem::kyber::kyber768::generate_key_pair(seed); - assert_eq!(pubkey.as_slice(), kp.public_key().as_slice()); - - let mut rand = [0; 32]; - rng.fill_bytes(&mut rand); - let (ciphertext, shared_secret) = - libcrux::kem::kyber::kyber768::encapsulate(&pubkey, rand); - let shared_secret_decapsulated = - libcrux::kem::kyber::kyber768::decapsulate_unpacked(&sk_state, &ciphertext); - - let shared_secret_decapsulated2 = - libcrux::kem::kyber::kyber768::decapsulate(&kp.private_key(), &ciphertext); - assert_eq!(shared_secret, shared_secret_decapsulated2); - - assert_eq!(shared_secret, shared_secret_decapsulated); - } - }; -} - -fn modify_ciphertext(alg: Algorithm, rng: &mut (impl CryptoRng + Rng), ciphertext: Ct) -> Ct { - let mut raw_ciphertext = ciphertext.encode(); - - let mut random_u32: usize = rng.next_u32().try_into().unwrap(); - - let mut random_byte: u8 = (random_u32 & 0xFF) as u8; - if random_byte == 0 { - random_byte += 1; - } - random_u32 >>= 8; - - let position = random_u32 % raw_ciphertext.len(); - raw_ciphertext[position] ^= random_byte; - - Ct::decode(alg, &raw_ciphertext).unwrap() -} - -macro_rules! impl_modified_ciphertext { - ($name:ident, $alg:expr) => { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[test] - fn $name() { - #[cfg(not(target_arch = "wasm32"))] - let mut rng = drbg::Drbg::new(libcrux::digest::Algorithm::Sha256).unwrap(); - #[cfg(target_arch = "wasm32")] - let mut rng = OsRng; - - if let Ok((secret_key, public_key)) = kem::key_gen($alg, &mut rng) { - if let Ok((shared_secret, ciphertext)) = public_key.encapsulate(&mut rng) { - let ciphertext = modify_ciphertext($alg, &mut rng, ciphertext); - let shared_secret_decapsulated = ciphertext.decapsulate(&secret_key).unwrap(); - - assert_ne!(shared_secret.encode(), shared_secret_decapsulated.encode()); - } - } - // if the randomness was not enough for the rejection sampling step - // in key-generation and encapsulation, simply return without - // failing. - } - }; -} - -fn modify_secret_key( - alg: Algorithm, - rng: &mut (impl CryptoRng + Rng), - secret_key: PrivateKey, - modify_implicit_rejection_value: bool, -) -> PrivateKey { - let mut raw_secret_key = secret_key.encode(); - - let mut random_u32: usize = rng.next_u32().try_into().unwrap(); - - let mut random_byte: u8 = (random_u32 & 0xFF) as u8; - if random_byte == 0 { - random_byte += 1; - } - random_u32 >>= 8; - - let position = if modify_implicit_rejection_value { - (raw_secret_key.len() - SHARED_SECRET_SIZE) + (random_u32 % SHARED_SECRET_SIZE) - } else { - random_u32 % (raw_secret_key.len() - SHARED_SECRET_SIZE) - }; - - raw_secret_key[position] ^= random_byte; - - PrivateKey::decode(alg, &raw_secret_key).unwrap() -} - -fn compute_implicit_rejection_shared_secret( - ciphertext: Ct, - secret_key: PrivateKey, -) -> [u8; SHARED_SECRET_SIZE] { - let raw_secret_key = secret_key.encode(); - - let mut to_hash = raw_secret_key[raw_secret_key.len() - SHARED_SECRET_SIZE..].to_vec(); - to_hash.extend_from_slice(&ciphertext.encode()); - - shake256(&to_hash) -} - -macro_rules! impl_modified_secret_key { - ($name:ident, $alg:expr) => { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[test] - fn $name() { - #[cfg(not(target_arch = "wasm32"))] - let mut rng = drbg::Drbg::new(libcrux::digest::Algorithm::Sha256).unwrap(); - #[cfg(target_arch = "wasm32")] - let mut rng = OsRng; - - if let Ok((secret_key, public_key)) = kem::key_gen($alg, &mut rng) { - if let Ok((shared_secret, ciphertext)) = public_key.encapsulate(&mut rng) { - let secret_key = modify_secret_key($alg, &mut rng, secret_key, false); - let shared_secret_decapsulated = ciphertext.decapsulate(&secret_key).unwrap(); - assert_ne!(shared_secret.encode(), shared_secret_decapsulated.encode()); - - let secret_key = modify_secret_key($alg, &mut rng, secret_key, true); - let shared_secret_decapsulated = ciphertext.decapsulate(&secret_key).unwrap(); - - assert_eq!( - shared_secret_decapsulated.encode(), - compute_implicit_rejection_shared_secret(ciphertext, secret_key) - ); - } - } - - // if the randomness was not enough for the rejection sampling step - // in key-generation and encapsulation, simply return without - // failing. - } - }; -} - -macro_rules! impl_modified_ciphertext_and_implicit_rejection_value { - ($name:ident, $alg:expr) => { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[test] - fn $name() { - #[cfg(not(target_arch = "wasm32"))] - let mut rng = drbg::Drbg::new(libcrux::digest::Algorithm::Sha256).unwrap(); - #[cfg(target_arch = "wasm32")] - let mut rng = OsRng; - - if let Ok((secret_key, public_key)) = kem::key_gen($alg, &mut rng) { - if let Ok((_, ciphertext)) = public_key.encapsulate(&mut rng) { - let ciphertext = modify_ciphertext($alg, &mut rng, ciphertext); - let shared_secret_decapsulated = ciphertext.decapsulate(&secret_key).unwrap(); - - let secret_key = modify_secret_key($alg, &mut rng, secret_key, true); - let shared_secret_decapsulated_1 = ciphertext.decapsulate(&secret_key).unwrap(); - - assert_ne!( - shared_secret_decapsulated.encode(), - shared_secret_decapsulated_1.encode() - ); - - assert_eq!( - shared_secret_decapsulated_1.encode(), - compute_implicit_rejection_shared_secret(ciphertext, secret_key) - ); - } - } - - // if the randomness was not enough for the rejection sampling step - // in key-generation and encapsulation, simply return without - // failing. - } - }; -} - -impl_consistency!(consistency_512, Algorithm::MlKem512); -impl_consistency!(consistency_768, Algorithm::MlKem768); -impl_consistency!(consistency_1024, Algorithm::MlKem1024); - -impl_consistency_unpacked!(consistency_768_unpacked, Algorithm::MlKem768); - -impl_modified_ciphertext!(modified_ciphertext_512, Algorithm::MlKem512); -impl_modified_ciphertext!(modified_ciphertext_768, Algorithm::MlKem768); -impl_modified_ciphertext!(modified_ciphertext_1024, Algorithm::MlKem1024); - -impl_modified_secret_key!(modified_secret_key_512, Algorithm::MlKem512); -impl_modified_secret_key!(modified_secret_key_768, Algorithm::MlKem768); -impl_modified_secret_key!(modified_secret_key_1024, Algorithm::MlKem1024); - -impl_modified_ciphertext_and_implicit_rejection_value!( - modified_ciphertext_and_implicit_rejection_value_512, - Algorithm::MlKem512 -); -impl_modified_ciphertext_and_implicit_rejection_value!( - modified_ciphertext_and_implicit_rejection_value_768, - Algorithm::MlKem768 -); -impl_modified_ciphertext_and_implicit_rejection_value!( - modified_ciphertext_and_implicit_rejection_value_1024, - Algorithm::MlKem1024 -); diff --git a/tests/kyber_nistkats.rs b/tests/kyber_nistkats.rs deleted file mode 100644 index 307ec2d28..000000000 --- a/tests/kyber_nistkats.rs +++ /dev/null @@ -1,89 +0,0 @@ -use libcrux::kem; -use serde::Deserialize; -use serde_json; - -use std::path::Path; - -use libcrux::digest; - -use std::{fs::File, io::BufReader}; - -#[derive(Deserialize)] -struct KyberNISTKAT { - #[serde(with = "hex::serde")] - key_generation_seed: [u8; 64], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_public_key: [u8; 32], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_secret_key: [u8; 32], - - #[serde(with = "hex::serde")] - encapsulation_seed: [u8; 32], - - #[serde(with = "hex::serde")] - sha3_256_hash_of_ciphertext: [u8; 32], - - #[serde(with = "hex::serde")] - shared_secret: [u8; 32], -} - -macro_rules! impl_nist_known_answer_tests { - ($name:ident, $parameter_set: literal, $key_gen_derand:expr, $encapsulate_derand:expr, $decapsulate_derand: expr) => { - #[test] - fn $name() { - let katfile_path = Path::new("tests") - .join("kyber_kats") - .join(format!("nistkats_{}.json", $parameter_set)); - let katfile = File::open(katfile_path).expect("Could not open KAT file."); - let reader = BufReader::new(katfile); - - let nist_kats: Vec = - serde_json::from_reader(reader).expect("Could not deserialize KAT file."); - - for kat in nist_kats { - let key_pair = $key_gen_derand(kat.key_generation_seed); - - let public_key_hash = digest::sha3_256(key_pair.pk()); - let secret_key_hash = digest::sha3_256(key_pair.sk()); - - assert_eq!(public_key_hash, kat.sha3_256_hash_of_public_key, "public keys don't match"); - assert_eq!(secret_key_hash, kat.sha3_256_hash_of_secret_key, "secret keys don't match"); - - let (ciphertext, shared_secret) = - $encapsulate_derand(key_pair.public_key(), kat.encapsulation_seed); - let ciphertext_hash = digest::sha3_256(ciphertext.as_ref()); - - assert_eq!(ciphertext_hash, kat.sha3_256_hash_of_ciphertext, "ciphertexts don't match"); - assert_eq!(shared_secret.as_ref(), kat.shared_secret, "shared secret produced by encapsulate does not match"); - - let shared_secret_from_decapsulate = - $decapsulate_derand(key_pair.private_key(), &ciphertext); - assert_eq!(shared_secret_from_decapsulate, shared_secret.as_ref(), "shared secret produced by decapsulate doesn't match the one produced by encapsulate"); - } - } - }; -} - -impl_nist_known_answer_tests!( - kyber512_nist_known_answer_tests, - 512, - kem::deterministic::kyber512_generate_keypair_derand, - kem::deterministic::kyber512_encapsulate_derand, - kem::deterministic::kyber512_decapsulate_derand -); -impl_nist_known_answer_tests!( - kyber768_nist_known_answer_tests, - 768, - kem::deterministic::kyber768_generate_keypair_derand, - kem::deterministic::kyber768_encapsulate_derand, - kem::deterministic::kyber768_decapsulate_derand -); -impl_nist_known_answer_tests!( - kyber1024_nist_known_answer_tests, - 1024, - kem::deterministic::kyber1024_generate_keypair_derand, - kem::deterministic::kyber1024_encapsulate_derand, - kem::deterministic::kyber1024_decapsulate_derand -); From 4e49371827cda96bea02b1df412bde482ac0aa0b Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Thu, 13 Jun 2024 10:08:59 +0200 Subject: [PATCH 82/84] Make spec libcrux interop tests use standalone crate --- specs/kyber/Cargo.toml | 5 ++++- specs/kyber/tests/interop_with_libcrux.rs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/specs/kyber/Cargo.toml b/specs/kyber/Cargo.toml index 0d1a92fa2..7a798cdea 100644 --- a/specs/kyber/Cargo.toml +++ b/specs/kyber/Cargo.toml @@ -4,10 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] -libcrux = { version = "=0.0.2-pre.2", path = "../../", features = ["tests"] } +libcrux = { version = "=0.0.2-pre.2", path = "../../" } hacspec-lib = { version = "0.0.1", path = "../hacspec-lib" } [dev-dependencies] +libcrux-kem = { version = "=0.0.2-pre.2", path = "../../libcrux-kem", features = [ + "tests", +] } hex = { version = "0.4.3", features = ["serde"] } pqcrypto-kyber = { version = "0.7.6", default-features = false } proptest = "1.2.0" diff --git a/specs/kyber/tests/interop_with_libcrux.rs b/specs/kyber/tests/interop_with_libcrux.rs index d10850518..22a30a5f4 100644 --- a/specs/kyber/tests/interop_with_libcrux.rs +++ b/specs/kyber/tests/interop_with_libcrux.rs @@ -3,7 +3,7 @@ use hacspec_kyber::{ KYBER768_CIPHERTEXT_SIZE, KYBER768_KEY_GENERATION_SEED_SIZE, KYBER768_SHARED_SECRET_SIZE, }; -use libcrux::kem::MlKemCiphertext; +use libcrux_kem::MlKemCiphertext; use rand::{rngs::OsRng, RngCore}; #[test] @@ -13,7 +13,7 @@ fn same_inputs_result_in_same_output() { let spec_key_pair = hacspec_kyber::generate_keypair(keygen_seed).unwrap(); let libcrux_key_pair = - libcrux::kem::deterministic::kyber768_generate_keypair_derand(keygen_seed); + libcrux_kem::deterministic::mlkem768_generate_keypair_derand(keygen_seed); assert_eq!(libcrux_key_pair.pk(), spec_key_pair.pk()); assert_eq!(libcrux_key_pair.sk(), spec_key_pair.sk()); @@ -22,7 +22,7 @@ fn same_inputs_result_in_same_output() { OsRng.fill_bytes(&mut message); let (spec_ct, spec_ss) = hacspec_kyber::encapsulate(*spec_key_pair.pk(), message).unwrap(); - let (libcrux_ct, libcrux_ss) = libcrux::kem::deterministic::kyber768_encapsulate_derand( + let (libcrux_ct, libcrux_ss) = libcrux_kem::deterministic::mlkem768_encapsulate_derand( &libcrux_key_pair.pk().into(), message, ); @@ -31,7 +31,7 @@ fn same_inputs_result_in_same_output() { assert_eq!(libcrux_ss.as_ref(), spec_ss); let (spec_ct, spec_ss) = hacspec_kyber::encapsulate(*spec_key_pair.pk(), message).unwrap(); - let (libcrux_ct, libcrux_ss) = libcrux::kem::deterministic::kyber768_encapsulate_derand( + let (libcrux_ct, libcrux_ss) = libcrux_kem::deterministic::mlkem768_encapsulate_derand( &libcrux_key_pair.pk().into(), message, ); @@ -40,7 +40,7 @@ fn same_inputs_result_in_same_output() { assert_eq!(libcrux_ss.as_ref(), spec_ss); let spec_ss = hacspec_kyber::decapsulate(spec_ct, *spec_key_pair.sk()); - let libcrux_ss = libcrux::kem::deterministic::kyber768_decapsulate_derand( + let libcrux_ss = libcrux_kem::deterministic::mlkem768_decapsulate_derand( libcrux_key_pair.private_key(), &libcrux_ct, ); @@ -81,13 +81,13 @@ fn implicit_rejection_happens_the_same_way() { let spec_key_pair = hacspec_kyber::generate_keypair(keygen_seed).unwrap(); let libcrux_key_pair = - libcrux::kem::deterministic::kyber768_generate_keypair_derand(keygen_seed); + libcrux_kem::deterministic::mlkem768_generate_keypair_derand(keygen_seed); let mut message = [0u8; KYBER768_SHARED_SECRET_SIZE]; OsRng.fill_bytes(&mut message); let (spec_ct, spec_ss) = hacspec_kyber::encapsulate(*spec_key_pair.pk(), message).unwrap(); - let (libcrux_ct, libcrux_ss) = libcrux::kem::deterministic::kyber768_encapsulate_derand( + let (libcrux_ct, libcrux_ss) = libcrux_kem::deterministic::mlkem768_encapsulate_derand( &libcrux_key_pair.pk().into(), message, ); @@ -96,7 +96,7 @@ fn implicit_rejection_happens_the_same_way() { assert_eq!(libcrux_ss.as_ref(), spec_ss); let (spec_ct, _) = hacspec_kyber::encapsulate(*spec_key_pair.pk(), message).unwrap(); - let (libcrux_ct, _) = libcrux::kem::deterministic::kyber768_encapsulate_derand( + let (libcrux_ct, _) = libcrux_kem::deterministic::mlkem768_encapsulate_derand( &libcrux_key_pair.pk().into(), message, ); @@ -104,7 +104,7 @@ fn implicit_rejection_happens_the_same_way() { let (modified_libcrux_ct, modified_spec_ct) = modify_ciphertext_pair(libcrux_ct, spec_ct); let spec_ss = hacspec_kyber::decapsulate(modified_spec_ct, *spec_key_pair.sk()); - let libcrux_ss = libcrux::kem::deterministic::kyber768_decapsulate_derand( + let libcrux_ss = libcrux_kem::deterministic::mlkem768_decapsulate_derand( libcrux_key_pair.private_key(), &modified_libcrux_ct, ); From b47fd6e7500ed7bf50f189754397594340a0b1fd Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Thu, 13 Jun 2024 11:00:44 +0200 Subject: [PATCH 83/84] Update benchmarks to use `libcrux-ml-kem` (resp. `libcrux-kem`) --- Cargo.lock | 2 + benchmarks/Cargo.toml | 2 + benchmarks/benches/kyber768.rs | 71 +++++++++++++++++----------------- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82ba8d5dc..3494423ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,8 @@ dependencies = [ "curve25519-dalek", "lib25519", "libcrux", + "libcrux-kem", + "libcrux-ml-kem", "libjade-sys", "openssl", "p256", diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index cf65f4872..b89591bd5 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -13,6 +13,8 @@ publish = false [dev-dependencies] libcrux = { path = "../", features = ["rand", "tests"] } +libcrux-kem = { path = "../libcrux-kem", features = ["tests"] } +libcrux-ml-kem = { path = "../libcrux-ml-kem", features = ["tests"] } rand = { version = "0.8" } rand_core = { version = "0.6" } # Benchmarking "RustCrypto" diff --git a/benchmarks/benches/kyber768.rs b/benchmarks/benches/kyber768.rs index 8e8896dce..2fec056a9 100644 --- a/benchmarks/benches/kyber768.rs +++ b/benchmarks/benches/kyber768.rs @@ -18,17 +18,18 @@ pub fn comparisons_key_generation(c: &mut Criterion) { let mut seed = [0; 64]; rng.fill_bytes(&mut seed); b.iter(|| { - let _kp = libcrux::kem::deterministic::kyber768_generate_keypair_derand(seed); + let _kp = libcrux_kem::deterministic::mlkem768_generate_keypair_derand(seed); }) }); - group.bench_function("libcrux portable unpacked (external random)", |b| { - b.iter(|| { - let mut seed = [0; 64]; - rng.fill_bytes(&mut seed); - let _tuple = libcrux::kem::kyber::kyber768::generate_key_pair_unpacked(seed); - }) - }); + // FIXME: This has not yet landed in `libcrux-ml-kem` + // group.bench_function("libcrux portable unpacked (external random)", |b| { + // b.iter(|| { + // let mut seed = [0; 64]; + // rng.fill_bytes(&mut seed); + // let _tuple = libcrux_ml_kem::mlkem768::generate_key_pair_unpacked(seed); + // }) + // }); group.bench_function("libcrux portable (HACL-DRBG)", |b| { b.iter(|| { @@ -77,9 +78,9 @@ pub fn comparisons_pk_validation(c: &mut Criterion) { let mut seed = [0; 64]; rng.fill_bytes(&mut seed); b.iter_batched( - || libcrux::kem::deterministic::kyber768_generate_keypair_derand(seed), + || libcrux_kem::deterministic::mlkem768_generate_keypair_derand(seed), |key_pair| { - let _valid = libcrux::kem::ml_kem768_validate_public_key(key_pair.into_parts().1); + let _valid = libcrux_kem::ml_kem768_validate_public_key(key_pair.into_parts().1); }, BatchSize::SmallInput, ) @@ -96,10 +97,10 @@ pub fn comparisons_encapsulation(c: &mut Criterion) { let mut seed2 = [0; 32]; OsRng.fill_bytes(&mut seed2); b.iter_batched( - || libcrux::kem::deterministic::kyber768_generate_keypair_derand(seed1), + || libcrux_kem::deterministic::mlkem768_generate_keypair_derand(seed1), |keypair| { let (_shared_secret, _ciphertext) = - libcrux::kem::deterministic::kyber768_encapsulate_derand( + libcrux_kem::deterministic::mlkem768_encapsulate_derand( &keypair.public_key(), seed2, ); @@ -113,7 +114,7 @@ pub fn comparisons_encapsulation(c: &mut Criterion) { || { let mut drbg = Drbg::new(digest::Algorithm::Sha256).unwrap(); let (_secret_key, public_key) = - libcrux::kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); + libcrux_kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); (drbg, public_key) }, @@ -129,7 +130,7 @@ pub fn comparisons_encapsulation(c: &mut Criterion) { || { let mut drbg = OsRng; let (_secret_key, public_key) = - libcrux::kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); + libcrux_kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); (drbg, public_key) }, @@ -204,7 +205,7 @@ pub fn comparisons_decapsulation(c: &mut Criterion) { || { let mut drbg = Drbg::new(digest::Algorithm::Sha256).unwrap(); let (secret_key, public_key) = - libcrux::kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); + libcrux_kem::key_gen(Algorithm::MlKem768, &mut drbg).unwrap(); let (_shared_secret, ciphertext) = public_key.encapsulate(&mut drbg).unwrap(); (secret_key, ciphertext) }, @@ -215,26 +216,26 @@ pub fn comparisons_decapsulation(c: &mut Criterion) { ) }); - group.bench_function("libcrux portable unpacked", |b| { - b.iter_batched( - || { - let mut seed = [0; 64]; - OsRng.fill_bytes(&mut seed); - let (sk_state, pubkey) = - libcrux::kem::kyber::kyber768::generate_key_pair_unpacked(seed); - - let mut rand = [0; 32]; - OsRng.fill_bytes(&mut rand); - let (ciphertext, _) = libcrux::kem::kyber::kyber768::encapsulate(&pubkey, rand); - (sk_state, ciphertext) - }, - |(sk_state, ciphertext)| { - let _shared_secret = - libcrux::kem::kyber::kyber768::decapsulate_unpacked(&sk_state, &ciphertext); - }, - BatchSize::SmallInput, - ) - }); + // FIXME: This has not yet landed in `libcrux-ml-kem`. + // group.bench_function("libcrux portable unpacked", |b| { + // b.iter_batched( + // || { + // let mut seed = [0; 64]; + // OsRng.fill_bytes(&mut seed); + // let (sk_state, pubkey) = libcrux_ml_kem::mlkem768::generate_key_pair_unpacked(seed); + + // let mut rand = [0; 32]; + // OsRng.fill_bytes(&mut rand); + // let (ciphertext, _) = libcrux_ml_kem::mlkem768::encapsulate(&pubkey, rand); + // (sk_state, ciphertext) + // }, + // |(sk_state, ciphertext)| { + // let _shared_secret = + // libcrux_ml_kem::mlkem768::decapsulate_unpacked(&sk_state, &ciphertext); + // }, + // BatchSize::SmallInput, + // ) + // }); group.bench_function("pqclean reference implementation", |b| { b.iter_batched( From 8cde88cf60559cda7a2b9a161a66993d3cad1baa Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Thu, 13 Jun 2024 11:01:05 +0200 Subject: [PATCH 84/84] Remove dead code --- src/kem/kyber.rs | 355 -------------- src/kem/kyber/PERFORMANCE.md | 8 - src/kem/kyber/arithmetic.rs | 201 -------- src/kem/kyber/compress.rs | 135 ------ src/kem/kyber/constant_time_ops.rs | 64 --- src/kem/kyber/constants.rs | 35 -- src/kem/kyber/hash_functions.rs | 65 --- src/kem/kyber/helper.rs | 57 --- src/kem/kyber/implementation_notes.pdf | Bin 348700 -> 0 bytes src/kem/kyber/ind_cpa.rs | 510 -------------------- src/kem/kyber/kyber1024.rs | 160 ------- src/kem/kyber/kyber512.rs | 158 ------- src/kem/kyber/kyber768.rs | 178 ------- src/kem/kyber/matrix.rs | 158 ------- src/kem/kyber/ntt.rs | 339 ------------- src/kem/kyber/sampling.rs | 240 ---------- src/kem/kyber/serialize.rs | 626 ------------------------- src/kem/kyber/types.rs | 156 ------ 18 files changed, 3445 deletions(-) delete mode 100644 src/kem/kyber.rs delete mode 100644 src/kem/kyber/PERFORMANCE.md delete mode 100644 src/kem/kyber/arithmetic.rs delete mode 100644 src/kem/kyber/compress.rs delete mode 100644 src/kem/kyber/constant_time_ops.rs delete mode 100644 src/kem/kyber/constants.rs delete mode 100644 src/kem/kyber/hash_functions.rs delete mode 100644 src/kem/kyber/helper.rs delete mode 100644 src/kem/kyber/implementation_notes.pdf delete mode 100644 src/kem/kyber/ind_cpa.rs delete mode 100644 src/kem/kyber/kyber1024.rs delete mode 100644 src/kem/kyber/kyber512.rs delete mode 100644 src/kem/kyber/kyber768.rs delete mode 100644 src/kem/kyber/matrix.rs delete mode 100644 src/kem/kyber/ntt.rs delete mode 100644 src/kem/kyber/sampling.rs delete mode 100644 src/kem/kyber/serialize.rs delete mode 100644 src/kem/kyber/types.rs diff --git a/src/kem/kyber.rs b/src/kem/kyber.rs deleted file mode 100644 index 89c310820..000000000 --- a/src/kem/kyber.rs +++ /dev/null @@ -1,355 +0,0 @@ -// This module is declared here since otherwise, hax reports the following error: -// -// The THIR body of item -// DefId(0:986 ~ libcrux[92b3]::kem::kyber768::parameters::COEFFICIENTS_IN_RING_ELEMENT) -// was stolen. -// -// This is being tracked in https://github.com/hacspec/hacspec-v2/issues/27 -pub(crate) mod constants; - -/// Helpers for verification and extraction -mod helper; - -mod arithmetic; -mod compress; -mod constant_time_ops; -mod hash_functions; -mod ind_cpa; -mod matrix; -mod ntt; -mod sampling; -mod serialize; -mod types; - -// Variants -pub mod kyber1024; -pub mod kyber512; -pub mod kyber768; - -pub use types::{MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey}; - -// TODO: We should make this an actual type as opposed to alias so we can enforce -// some checks at the type level. This is being tracked in: -// https://github.com/cryspen/libcrux/issues/123 -pub type MlKemSharedSecret = [u8; constants::SHARED_SECRET_SIZE]; - -use self::{ - arithmetic::PolynomialRingElement, - constant_time_ops::{ - compare_ciphertexts_in_constant_time, select_shared_secret_in_constant_time, - }, - constants::{CPA_PKE_KEY_GENERATION_SEED_SIZE, H_DIGEST_SIZE, SHARED_SECRET_SIZE}, - hash_functions::{G, H, PRF}, - ind_cpa::{into_padded_array, serialize_public_key}, - serialize::deserialize_ring_elements_reduced, -}; - -/// Seed size for key generation -pub(in crate::kem) const KEY_GENERATION_SEED_SIZE: usize = - CPA_PKE_KEY_GENERATION_SEED_SIZE + SHARED_SECRET_SIZE; - -/// Serialize the secret key. -#[inline(always)] -fn serialize_kem_secret_key( - private_key: &[u8], - public_key: &[u8], - implicit_rejection_value: &[u8], -) -> [u8; SERIALIZED_KEY_LEN] { - let mut out = [0u8; SERIALIZED_KEY_LEN]; - let mut pointer = 0; - out[pointer..pointer + private_key.len()].copy_from_slice(private_key); - pointer += private_key.len(); - out[pointer..pointer + public_key.len()].copy_from_slice(public_key); - pointer += public_key.len(); - out[pointer..pointer + H_DIGEST_SIZE].copy_from_slice(&H(public_key)); - pointer += H_DIGEST_SIZE; - out[pointer..pointer + implicit_rejection_value.len()] - .copy_from_slice(implicit_rejection_value); - out -} - -pub(super) fn validate_public_key< - const K: usize, - const RANKED_BYTES_PER_RING_ELEMENT: usize, - const PUBLIC_KEY_SIZE: usize, ->( - public_key: &[u8; PUBLIC_KEY_SIZE], -) -> bool { - let deserialized_pk = deserialize_ring_elements_reduced::( - &public_key[..RANKED_BYTES_PER_RING_ELEMENT], - ); - - let public_key_serialized = - serialize_public_key::( - deserialized_pk, - &public_key[RANKED_BYTES_PER_RING_ELEMENT..], - ); - - *public_key == public_key_serialized -} - -pub struct MlKemState { - secret_as_ntt: [PolynomialRingElement; K], - t_as_ntt: [PolynomialRingElement; K], - a_transpose: [[PolynomialRingElement; K]; K], - rej: [u8; 32], - ind_cpa_public_key_hash: [u8; 32], -} - -pub(super) fn generate_keypair_unpacked< - const K: usize, - const CPA_PRIVATE_KEY_SIZE: usize, - const PRIVATE_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, ->( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> (MlKemState, MlKemPublicKey) { - let ind_cpa_keypair_randomness = &randomness[0..CPA_PKE_KEY_GENERATION_SEED_SIZE]; - let implicit_rejection_value = &randomness[CPA_PKE_KEY_GENERATION_SEED_SIZE..]; - - let ((secret_as_ntt, t_as_ntt, a_transpose), ind_cpa_public_key) = - ind_cpa::generate_keypair_unpacked::< - K, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(ind_cpa_keypair_randomness); - - let ind_cpa_public_key_hash = H(&ind_cpa_public_key); - - let rej: [u8; 32] = implicit_rejection_value.try_into().unwrap(); - let pubkey: MlKemPublicKey = MlKemPublicKey::from(ind_cpa_public_key); - ( - MlKemState { - secret_as_ntt, - t_as_ntt, - a_transpose, - rej, - ind_cpa_public_key_hash, - }, - pubkey, - ) -} - -pub(super) fn generate_keypair< - const K: usize, - const CPA_PRIVATE_KEY_SIZE: usize, - const PRIVATE_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, ->( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> MlKemKeyPair { - let ind_cpa_keypair_randomness = &randomness[0..CPA_PKE_KEY_GENERATION_SEED_SIZE]; - let implicit_rejection_value = &randomness[CPA_PKE_KEY_GENERATION_SEED_SIZE..]; - - let (ind_cpa_private_key, public_key) = ind_cpa::generate_keypair::< - K, - CPA_PRIVATE_KEY_SIZE, - PUBLIC_KEY_SIZE, - BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(ind_cpa_keypair_randomness); - - let secret_key_serialized = - serialize_kem_secret_key(&ind_cpa_private_key, &public_key, implicit_rejection_value); - let private_key: MlKemPrivateKey = - MlKemPrivateKey::from(secret_key_serialized); - - MlKemKeyPair::from(private_key, public_key.into()) -} - -pub(super) fn encapsulate< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const VECTOR_U_BLOCK_LEN: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, ->( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], -) -> (MlKemCiphertext, MlKemSharedSecret) { - let mut to_hash: [u8; 2 * H_DIGEST_SIZE] = into_padded_array(&randomness); - to_hash[H_DIGEST_SIZE..].copy_from_slice(&H(public_key.as_slice())); - - let hashed = G(&to_hash); - let (shared_secret, pseudorandomness) = hashed.split_at(SHARED_SECRET_SIZE); - - let ciphertext = ind_cpa::encrypt::< - K, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - VECTOR_U_BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key.as_slice(), randomness, pseudorandomness); - - let mut shared_secret_array = [0u8; constants::SHARED_SECRET_SIZE]; - shared_secret_array.copy_from_slice(shared_secret); - (ciphertext.into(), shared_secret_array) -} - -pub(super) fn decapsulate_unpacked< - const K: usize, - const SECRET_KEY_SIZE: usize, - const CPA_SECRET_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const C1_BLOCK_SIZE: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, - const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, ->( - state: &MlKemState, - ciphertext: &MlKemCiphertext, -) -> MlKemSharedSecret { - let secret_as_ntt: &[PolynomialRingElement; K] = &state.secret_as_ntt; - let t_as_ntt: &[PolynomialRingElement; K] = &state.t_as_ntt; - let a_transpose: &[[PolynomialRingElement; K]; K] = &state.a_transpose; - let implicit_rejection_value: &[u8] = &state.rej; - let ind_cpa_public_key_hash: &[u8] = &state.ind_cpa_public_key_hash; - - let decrypted = ind_cpa::decrypt_unpacked::< - K, - CIPHERTEXT_SIZE, - C1_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - >(secret_as_ntt, &ciphertext.value); - - let mut to_hash: [u8; SHARED_SECRET_SIZE + H_DIGEST_SIZE] = into_padded_array(&decrypted); - to_hash[SHARED_SECRET_SIZE..].copy_from_slice(ind_cpa_public_key_hash); - - let hashed = G(&to_hash); - let (shared_secret, pseudorandomness) = hashed.split_at(SHARED_SECRET_SIZE); - - let mut to_hash: [u8; IMPLICIT_REJECTION_HASH_INPUT_SIZE] = - into_padded_array(&implicit_rejection_value); - to_hash[SHARED_SECRET_SIZE..].copy_from_slice(ciphertext.as_ref()); - let implicit_rejection_shared_secret: [u8; SHARED_SECRET_SIZE] = PRF(&to_hash); - - let expected_ciphertext = ind_cpa::encrypt_unpacked::< - K, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(t_as_ntt, a_transpose, decrypted, pseudorandomness); - - let selector = compare_ciphertexts_in_constant_time::( - ciphertext.as_ref(), - &expected_ciphertext, - ); - - select_shared_secret_in_constant_time( - shared_secret, - &implicit_rejection_shared_secret, - selector, - ) -} - -pub(super) fn decapsulate< - const K: usize, - const SECRET_KEY_SIZE: usize, - const CPA_SECRET_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_SIZE: usize, - const C2_SIZE: usize, - const VECTOR_U_COMPRESSION_FACTOR: usize, - const VECTOR_V_COMPRESSION_FACTOR: usize, - const C1_BLOCK_SIZE: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, - const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize, ->( - secret_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, -) -> MlKemSharedSecret { - let (ind_cpa_secret_key, secret_key) = secret_key.split_at(CPA_SECRET_KEY_SIZE); - let (ind_cpa_public_key, secret_key) = secret_key.split_at(PUBLIC_KEY_SIZE); - let (ind_cpa_public_key_hash, implicit_rejection_value) = secret_key.split_at(H_DIGEST_SIZE); - - let decrypted = ind_cpa::decrypt::< - K, - CIPHERTEXT_SIZE, - C1_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - >(ind_cpa_secret_key, &ciphertext.value); - - let mut to_hash: [u8; SHARED_SECRET_SIZE + H_DIGEST_SIZE] = into_padded_array(&decrypted); - to_hash[SHARED_SECRET_SIZE..].copy_from_slice(ind_cpa_public_key_hash); - - let hashed = G(&to_hash); - let (shared_secret, pseudorandomness) = hashed.split_at(SHARED_SECRET_SIZE); - - let mut to_hash: [u8; IMPLICIT_REJECTION_HASH_INPUT_SIZE] = - into_padded_array(&implicit_rejection_value); - to_hash[SHARED_SECRET_SIZE..].copy_from_slice(ciphertext.as_ref()); - let implicit_rejection_shared_secret: [u8; SHARED_SECRET_SIZE] = PRF(&to_hash); - - let expected_ciphertext = ind_cpa::encrypt::< - K, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_SIZE, - C2_SIZE, - VECTOR_U_COMPRESSION_FACTOR, - VECTOR_V_COMPRESSION_FACTOR, - C1_BLOCK_SIZE, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(ind_cpa_public_key, decrypted, pseudorandomness); - - let selector = compare_ciphertexts_in_constant_time::( - ciphertext.as_ref(), - &expected_ciphertext, - ); - - select_shared_secret_in_constant_time( - shared_secret, - &implicit_rejection_shared_secret, - selector, - ) -} diff --git a/src/kem/kyber/PERFORMANCE.md b/src/kem/kyber/PERFORMANCE.md deleted file mode 100644 index 93bf98dd9..000000000 --- a/src/kem/kyber/PERFORMANCE.md +++ /dev/null @@ -1,8 +0,0 @@ -N.B.: All measurements were taken on an M1 MacBook Air with 16 GB of memory. - -| | Key Generation (µs) | Encapsulation (µs) | Decapsulation (µs) | -|:----------|----------------------:|---------------------:|---------------------:| -| libcrux | 30.671 | 36.31 | 36.3 | -| BoringSSL | 33.8152 | 28.7323 | 35.2664 | -| CIRCL | 39.785 | 44.517 | 49.626 | -| PQClean | 30.671 | 38.511 | 43.458 | \ No newline at end of file diff --git a/src/kem/kyber/arithmetic.rs b/src/kem/kyber/arithmetic.rs deleted file mode 100644 index 4543b6fbe..000000000 --- a/src/kem/kyber/arithmetic.rs +++ /dev/null @@ -1,201 +0,0 @@ -use crate::hax_utils::hax_debug_assert; - -use super::constants::{COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}; - -/// Values having this type hold a representative 'x' of the Kyber field. -/// We use 'fe' as a shorthand for this type. -pub(crate) type FieldElement = i32; - -const MONTGOMERY_SHIFT: u8 = 16; -const MONTGOMERY_R: i32 = 1 << MONTGOMERY_SHIFT; - -/// If 'x' denotes a value of type `fe`, values having this type hold a -/// representative y ≡ x·MONTGOMERY_R^(-1) (mod FIELD_MODULUS). -/// We use 'mfe' as a shorthand for this type -pub(crate) type MontgomeryFieldElement = i32; - -/// If 'x' denotes a value of type `fe`, values having this type hold a -/// representative y ≡ x·MONTGOMERY_R (mod FIELD_MODULUS). -/// We use 'fer' as a shorthand for this type. -pub(crate) type FieldElementTimesMontgomeryR = i32; - -#[cfg_attr(hax, hax_lib_macros::requires(n == 4 || n == 5 || n == 10 || n == 11 || n == MONTGOMERY_SHIFT))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| result < 2u32.pow(n.into())))] -#[inline(always)] -pub(crate) fn get_n_least_significant_bits(n: u8, value: u32) -> u32 { - hax_debug_assert!(n == 4 || n == 5 || n == 10 || n == 11 || n == MONTGOMERY_SHIFT); - - value & ((1 << n) - 1) -} - -const BARRETT_SHIFT: i64 = 26; -const BARRETT_R: i64 = 1 << BARRETT_SHIFT; - -/// This is calculated as ⌊(BARRETT_R / FIELD_MODULUS) + 1/2⌋ -const BARRETT_MULTIPLIER: i64 = 20159; - -/// Signed Barrett Reduction -/// -/// Given an input `value`, `barrett_reduce` outputs a representative `result` -/// such that: -/// -/// - result ≡ value (mod FIELD_MODULUS) -/// - the absolute value of `result` is bound as follows: -/// -/// `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1) -/// -/// In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`. - -#[cfg_attr(hax, hax_lib_macros::requires((i64::from(value) > -BARRETT_R && i64::from(value) < BARRETT_R)))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| result > -FIELD_MODULUS && result < FIELD_MODULUS))] -pub(crate) fn barrett_reduce(value: FieldElement) -> FieldElement { - hax_debug_assert!( - i64::from(value) > -BARRETT_R && i64::from(value) < BARRETT_R, - "value is {value}" - ); - - let t = (i64::from(value) * BARRETT_MULTIPLIER) + (BARRETT_R >> 1); - let quotient = (t >> BARRETT_SHIFT) as i32; - - let result = value - (quotient * FIELD_MODULUS); - - hax_debug_assert!( - result > -FIELD_MODULUS && result < FIELD_MODULUS, - "value is {value}" - ); - - result -} - -const INVERSE_OF_MODULUS_MOD_MONTGOMERY_R: u32 = 62209; // FIELD_MODULUS^{-1} mod MONTGOMERY_R - -/// Signed Montgomery Reduction -/// -/// Given an input `value`, `montgomery_reduce` outputs a representative `o` -/// such that: -/// -/// - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS) -/// - the absolute value of `o` is bound as follows: -/// -/// `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2) -/// -/// In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 · FIELD_MODULUS) / 2`. -#[cfg_attr(hax, hax_lib_macros::requires(value >= -FIELD_MODULUS * MONTGOMERY_R && value <= FIELD_MODULUS * MONTGOMERY_R))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| result >= -(3 * FIELD_MODULUS) / 2 && result <= (3 * FIELD_MODULUS) / 2))] -pub(crate) fn montgomery_reduce(value: FieldElement) -> MontgomeryFieldElement { - // This forces hax to extract code for MONTGOMERY_R before it extracts code - // for this function. The removal of this line is being tracked in: - // https://github.com/cryspen/libcrux/issues/134 - let _ = MONTGOMERY_R; - - hax_debug_assert!( - value >= -FIELD_MODULUS * MONTGOMERY_R && value <= FIELD_MODULUS * MONTGOMERY_R, - "value is {value}" - ); - - let t = get_n_least_significant_bits(MONTGOMERY_SHIFT, value as u32) - * INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; - let k = get_n_least_significant_bits(MONTGOMERY_SHIFT, t) as i16; - - let k_times_modulus = (k as i32) * FIELD_MODULUS; - - let c = k_times_modulus >> MONTGOMERY_SHIFT; - let value_high = value >> MONTGOMERY_SHIFT; - - value_high - c -} - -/// If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to -/// `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to -/// `x · y`, as follows: -/// -/// `fe · fer ≡ x · y · MONTGOMERY_R (mod FIELD_MODULUS)` -/// -/// `montgomery_reduce` takes the value `x · y · MONTGOMERY_R` and outputs a representative -/// `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod FIELD_MODULUS)`. -#[inline(always)] -pub(crate) fn montgomery_multiply_fe_by_fer( - fe: FieldElement, - fer: FieldElementTimesMontgomeryR, -) -> FieldElement { - montgomery_reduce(fe * fer) -} - -/// This is calculated as (MONTGOMERY_R)^2 mod FIELD_MODULUS -const MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS: i32 = 1353; - -/// If x is some field element of the Kyber field and `mfe` is congruent to -/// x · MONTGOMERY_R^{-1}, this procedure outputs a value that is congruent to -/// `x`, as follows: -/// -/// mfe · MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS ≡ x · MONTGOMERY_R^{-1} * (MONTGOMERY_R)^2 (mod FIELD_MODULUS) -/// => mfe · MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS ≡ x · MONTGOMERY_R (mod FIELD_MODULUS) -/// -/// `montgomery_reduce` takes the value `x · MONTGOMERY_R` and outputs a representative -/// `x · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x (mod FIELD_MODULUS)` -#[inline(always)] -pub(crate) fn to_standard_domain(mfe: MontgomeryFieldElement) -> FieldElement { - montgomery_reduce(mfe * MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS) -} - -/// Given a field element `fe` such that -FIELD_MODULUS ≤ fe < FIELD_MODULUS, -/// output `o` such that: -/// - `o` is congruent to `fe` -/// - 0 ≤ `o` FIELD_MODULUS -#[cfg_attr(hax, hax_lib_macros::requires(fe >= -FIELD_MODULUS && fe < FIELD_MODULUS))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| result >= 0 && result < (FIELD_MODULUS as u16)))] -#[inline(always)] -pub(crate) fn to_unsigned_representative(fe: FieldElement) -> u16 { - hax_debug_assert!(fe >= -FIELD_MODULUS && fe < FIELD_MODULUS); - (fe + (FIELD_MODULUS & (fe >> 31))) as u16 -} - -#[derive(Clone, Copy)] -pub struct PolynomialRingElement { - pub(crate) coefficients: [FieldElement; COEFFICIENTS_IN_RING_ELEMENT], -} - -impl PolynomialRingElement { - pub const ZERO: Self = Self { - coefficients: [0i32; 256], // FIXME: hax issue, this is COEFFICIENTS_IN_RING_ELEMENT - }; -} - -/// Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise -/// sum of their constituent coefficients. -#[cfg_attr(hax, hax_lib_macros::requires( - hax_lib::forall(|i:usize| - hax_lib::implies(i < COEFFICIENTS_IN_RING_ELEMENT, || - (lhs.coefficients[i].abs() <= ((K as i32) - 1) * FIELD_MODULUS) && - (rhs.coefficients[i].abs() <= FIELD_MODULUS) - -))))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || - result.coefficients[i].abs() <= (K as i32) * FIELD_MODULUS -))))] -pub(crate) fn add_to_ring_element( - mut lhs: PolynomialRingElement, - rhs: &PolynomialRingElement, -) -> PolynomialRingElement { - hax_debug_assert!(lhs - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() <= ((K as i32) - 1) * FIELD_MODULUS)); - hax_debug_assert!(rhs - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() < FIELD_MODULUS)); - - for i in 0..lhs.coefficients.len() { - lhs.coefficients[i] += rhs.coefficients[i]; - } - - hax_debug_assert!(lhs - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() <= (K as i32) * FIELD_MODULUS)); - - lhs -} diff --git a/src/kem/kyber/compress.rs b/src/kem/kyber/compress.rs deleted file mode 100644 index c2ea6f7d9..000000000 --- a/src/kem/kyber/compress.rs +++ /dev/null @@ -1,135 +0,0 @@ -use crate::hax_utils::hax_debug_assert; - -use super::{ - arithmetic::{get_n_least_significant_bits, FieldElement}, - constants::FIELD_MODULUS, -}; - -/// The `compress_*` functions implement the `Compress` function specified in the NIST FIPS -/// 203 standard (Page 18, Expression 4.5), which is defined as: -/// -/// ```plaintext -/// Compress_d: ℤq -> ℤ_{2ᵈ} -/// Compress_d(x) = ⌈(2ᵈ/q)·x⌋ -/// ``` -/// -/// Since `⌈x⌋ = ⌊x + 1/2⌋` we have: -/// -/// ```plaintext -/// Compress_d(x) = ⌊(2ᵈ/q)·x + 1/2⌋ -/// = ⌊(2^{d+1}·x + q) / 2q⌋ -/// ``` -/// -/// For further information about the function implementations, consult the -/// `implementation_notes.pdf` document in this directory. -/// -/// The NIST FIPS 203 standard can be found at -/// . - -#[cfg_attr(hax, hax_lib_macros::requires(fe < (FIELD_MODULUS as u16)))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::implies(833 <= fe && fe <= 2596, || result == 1) && - hax_lib::implies(!(833 <= fe && fe <= 2596), || result == 0) -))] -pub(super) fn compress_message_coefficient(fe: u16) -> u8 { - // The approach used here is inspired by: - // https://github.com/cloudflare/circl/blob/main/pke/kyber/internal/common/poly.go#L150 - - // If 833 <= fe <= 2496, - // then -832 <= shifted <= 831 - let shifted: i16 = 1664 - (fe as i16); - - // If shifted < 0, then - // (shifted >> 15) ^ shifted = flip_bits(shifted) = -shifted - 1, and so - // if -832 <= shifted < 0 then 0 < shifted_positive <= 831 - // - // If shifted >= 0 then - // (shifted >> 15) ^ shifted = shifted, and so - // if 0 <= shifted <= 831 then 0 <= shifted_positive <= 831 - let mask = shifted >> 15; - let shifted_to_positive = mask ^ shifted; - - let shifted_positive_in_range = shifted_to_positive - 832; - - // If x <= 831, then x - 832 <= -1, and so x - 832 < 0, which means - // the most significant bit of shifted_positive_in_range will be 1. - ((shifted_positive_in_range >> 15) & 1) as u8 -} - -#[cfg_attr(hax, - hax_lib_macros::requires( - (coefficient_bits == 4 || - coefficient_bits == 5 || - coefficient_bits == 10 || - coefficient_bits == 11) && - fe < (FIELD_MODULUS as u16)))] -#[cfg_attr(hax, - hax_lib_macros::ensures( - |result| result >= 0 && result < 2i32.pow(coefficient_bits as u32)))] -pub(super) fn compress_ciphertext_coefficient(coefficient_bits: u8, fe: u16) -> FieldElement { - hax_debug_assert!( - coefficient_bits == 4 - || coefficient_bits == 5 - || coefficient_bits == 10 - || coefficient_bits == 11 - ); - hax_debug_assert!(fe <= (FIELD_MODULUS as u16)); - - // This has to be constant time due to: - // https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/ldX0ThYJuBo/m/ovODsdY7AwAJ - let mut compressed = (fe as u64) << coefficient_bits; - compressed += 1664 as u64; - - compressed *= 10_321_340; - compressed >>= 35; - - get_n_least_significant_bits(coefficient_bits, compressed as u32) as FieldElement -} - -/// The `decompress_*` functions implement the `Decompress` function specified in the NIST FIPS -/// 203 standard (Page 18, Expression 4.6), which is defined as: -/// -/// ```plaintext -/// Decompress_d: ℤ_{2ᵈ} -> ℤq -/// Decompress_d(y) = ⌈(q/2ᵈ)·y⌋ -/// ``` -/// -/// Since `⌈x⌋ = ⌊x + 1/2⌋` we have: -/// -/// ```plaintext -/// Decompress_d(y) = ⌊(q/2ᵈ)·y + 1/2⌋ -/// = ⌊(2·y·q + 2ᵈ) / 2^{d+1})⌋ -/// ``` -/// -/// For further information about the function implementations, consult the -/// `implementation_notes.pdf` document in this directory. -/// -/// The NIST FIPS 203 standard can be found at -/// . - -#[cfg_attr(hax, hax_lib_macros::requires((fe == 0) || (fe == 1)))] -#[inline(always)] -pub(super) fn decompress_message_coefficient(fe: FieldElement) -> FieldElement { - -fe & ((FIELD_MODULUS + 1) / 2) -} - -#[cfg_attr(hax, hax_lib_macros::requires((coefficient_bits == 4 || coefficient_bits == 5 || coefficient_bits == 10 || coefficient_bits == 11) && (fe >= 0) && (fe < 2i32.pow(coefficient_bits as u32))))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| result < FIELD_MODULUS))] -pub(super) fn decompress_ciphertext_coefficient( - coefficient_bits: u8, - fe: FieldElement, -) -> FieldElement { - hax_debug_assert!( - coefficient_bits == 4 - || coefficient_bits == 5 - || coefficient_bits == 10 - || coefficient_bits == 11 - ); - hax_debug_assert!(fe >= 0 && fe <= 2i32.pow(coefficient_bits as u32)); - - let mut decompressed = (fe as u32) * (FIELD_MODULUS as u32); - decompressed = (decompressed << 1) + (1 << coefficient_bits); - decompressed >>= coefficient_bits + 1; - - decompressed as FieldElement -} diff --git a/src/kem/kyber/constant_time_ops.rs b/src/kem/kyber/constant_time_ops.rs deleted file mode 100644 index 2066a1d74..000000000 --- a/src/kem/kyber/constant_time_ops.rs +++ /dev/null @@ -1,64 +0,0 @@ -use super::constants::SHARED_SECRET_SIZE; -use crate::hax_utils::hax_debug_assert; - -// Examine the output that LLVM produces for this code from time to time to ensure -// operations are not being optimized away/constant-timedness is not being broken. - -/// Return 1 if `value` is not zero and 0 otherwise. -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::implies(value == 0, || result == 0) && - hax_lib::implies(value != 0, || result == 1) -))] -#[inline(never)] // Don't inline this to avoid that the compiler optimizes this out. -fn is_non_zero(value: u8) -> u8 { - let value = value as u16; - - let result = ((value | (!value).wrapping_add(1)) >> 8) & 1; - - result as u8 -} - -/// Return 1 if the bytes of `lhs` and `rhs` do not exactly -/// match and 0 otherwise. -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::implies(lhs == rhs, || result == 0) && - hax_lib::implies(lhs != rhs, || result == 1) -))] -pub(crate) fn compare_ciphertexts_in_constant_time( - lhs: &[u8], - rhs: &[u8], -) -> u8 { - hax_debug_assert!(lhs.len() == rhs.len()); - hax_debug_assert!(lhs.len() == CIPHERTEXT_SIZE); - - let mut r: u8 = 0; - for i in 0..CIPHERTEXT_SIZE { - r |= lhs[i] ^ rhs[i]; - } - - is_non_zero(r) -} - -/// If `selector` is not zero, return the bytes in `rhs`; return the bytes in -/// `lhs` otherwise. -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::implies(selector == 0, || result == lhs) && - hax_lib::implies(selector != 0, || result == rhs) -))] -pub(crate) fn select_shared_secret_in_constant_time( - lhs: &[u8], - rhs: &[u8], - selector: u8, -) -> [u8; SHARED_SECRET_SIZE] { - hax_debug_assert!(lhs.len() == rhs.len()); - hax_debug_assert!(lhs.len() == SHARED_SECRET_SIZE); - - let mask = is_non_zero(selector).wrapping_sub(1); - let mut out = [0u8; SHARED_SECRET_SIZE]; - - for i in 0..SHARED_SECRET_SIZE { - out[i] = (lhs[i] & mask) | (rhs[i] & !mask); - } - - out -} diff --git a/src/kem/kyber/constants.rs b/src/kem/kyber/constants.rs deleted file mode 100644 index a48705a2f..000000000 --- a/src/kem/kyber/constants.rs +++ /dev/null @@ -1,35 +0,0 @@ -/// Field modulus: 3329 -pub(crate) const FIELD_MODULUS: i32 = 3329; - -/// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent -pub(crate) const BITS_PER_COEFFICIENT: usize = 12; - -/// Coefficients per ring element -pub(crate) const COEFFICIENTS_IN_RING_ELEMENT: usize = 256; - -/// Bits required per (uncompressed) ring element -pub(crate) const BITS_PER_RING_ELEMENT: usize = COEFFICIENTS_IN_RING_ELEMENT * 12; - -/// Bytes required per (uncompressed) ring element -pub(crate) const BYTES_PER_RING_ELEMENT: usize = BITS_PER_RING_ELEMENT / 8; - -/// PKE message size -pub(crate) const SHARED_SECRET_SIZE: usize = 32; - -pub(crate) const CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = 32; - -// [hax]: hacspec/hacspec-v2#27 stealing error -// Using these functions causes stealing errors in hax. -// /// Compute serialized length for output size of ByteEncode -// pub(in crate::kem::kyber) const fn serialized_len() -> usize { -// OUT_LEN * K -// } - -// /// Compute block length for output block size of ByteEncode u (c1) -// pub(in crate::kem::kyber) const fn block_len() -> usize { -// (COEFFICIENTS_IN_RING_ELEMENT * FACTOR) / 8 -// } - -// XXX: Eurydice can't handle this. -// digest_size(Algorithm::Sha3_256); -pub(crate) const H_DIGEST_SIZE: usize = 32; diff --git a/src/kem/kyber/hash_functions.rs b/src/kem/kyber/hash_functions.rs deleted file mode 100644 index 1e605b4b4..000000000 --- a/src/kem/kyber/hash_functions.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![allow(non_snake_case)] - -use super::constants::H_DIGEST_SIZE; -use crate::digest::{self, digest_size, incremental_x4::Shake128StateX4, Algorithm}; - -pub(crate) fn G(input: &[u8]) -> [u8; digest_size(Algorithm::Sha3_512)] { - digest::sha3_512(input) -} - -pub(crate) fn H(input: &[u8]) -> [u8; H_DIGEST_SIZE] { - digest::sha3_256(input) -} - -pub(crate) fn PRF(input: &[u8]) -> [u8; LEN] { - digest::shake256::(input) -} - -#[inline(always)] -pub(crate) fn absorb(input: [[u8; 34]; K]) -> Shake128StateX4 { - debug_assert!(K == 2 || K == 3 || K == 4); - - let mut state = Shake128StateX4::new(); - // XXX: We need to do this dance to get it through hax and eurydice for now. - let mut data: [&[u8]; K] = [&[0u8]; K]; - for i in 0..K { - data[i] = &input[i] as &[u8]; - } - state.absorb_final(data); - state -} - -const BLOCK_SIZE: usize = 168; -const THREE_BLOCKS: usize = BLOCK_SIZE * 3; - -#[inline(always)] -pub(crate) fn squeeze_three_blocks( - xof_state: &mut Shake128StateX4, -) -> [[u8; THREE_BLOCKS]; K] { - let output: [[u8; THREE_BLOCKS]; K] = xof_state.squeeze_blocks(); - let mut out = [[0u8; THREE_BLOCKS]; K]; - for i in 0..K { - out[i] = output[i]; - } - out -} - -#[inline(always)] -pub(crate) fn squeeze_block( - xof_state: &mut Shake128StateX4, -) -> [[u8; BLOCK_SIZE]; K] { - let output: [[u8; BLOCK_SIZE]; K] = xof_state.squeeze_blocks(); - let mut out = [[0u8; BLOCK_SIZE]; K]; - for i in 0..K { - out[i] = output[i]; - } - out -} - -/// Free the memory of the state. -/// -/// **NOTE:** That this needs to be done manually for now. -#[inline(always)] -pub(crate) fn free_state(xof_state: Shake128StateX4) { - xof_state.free_memory(); -} diff --git a/src/kem/kyber/helper.rs b/src/kem/kyber/helper.rs deleted file mode 100644 index c0bae70fd..000000000 --- a/src/kem/kyber/helper.rs +++ /dev/null @@ -1,57 +0,0 @@ -/// The following macros are defined so that the extraction from Rust to C code -/// can go through. - -#[cfg(not(hax))] -#[macro_export] -macro_rules! cloop { - (for ($i:ident, $chunk:ident) in $val:ident.$values:ident.chunks_exact($($chunk_size:expr),*).enumerate() $body:block) => { - for $i in 0..$val.$values.len() / ($($chunk_size)*) { - let $chunk = &$val.$values[$i*($($chunk_size)*) .. $i*($($chunk_size)*)+($($chunk_size)*)]; - $body - } - }; - (for ($i:ident, $chunk:ident) in $val:ident.chunks_exact($($chunk_size:expr),*).enumerate() $body:block) => { - for $i in 0..$val.len() / ($($chunk_size)*) { - let $chunk = &$val[$i*($($chunk_size)*) .. $i*($($chunk_size)*)+($($chunk_size)*)]; - $body - } - }; - (for ($i:ident, $item:ident) in $val:ident.iter().enumerate() $body:block) => { - for $i in 0..$val.len() { - let $item = &$val[$i]; - $body - } - }; - (for ($i:ident, $item:ident) in $val:ident.into_iter().enumerate() $body:block) => { - for $i in 0..$val.len() { - let $item = $val[$i]; - $body - } - }; - (for $i:ident in ($start:literal..$end:expr).step_by($step:literal) $body:block) => { - for $i in $start..$end / $step { - let $i = $i * $step; - $body - } - }; -} - -#[cfg(hax)] -#[macro_export] -macro_rules! cloop { - (for ($i:ident, $chunk:ident) in $val:ident.$values:ident.chunks_exact($($chunk_size:expr),*).enumerate() $body:block) => { - for ($i, $chunk) in $val.$values.chunks_exact($($chunk_size),*).enumerate() $body - }; - (for ($i:ident, $chunk:ident) in $val:ident.chunks_exact($($chunk_size:expr),*).enumerate() $body:block) => { - for ($i, $chunk) in $val.chunks_exact($($chunk_size),*).enumerate() $body - }; - (for ($i:ident, $item:ident) in $val:ident.iter().enumerate() $body:block) => { - for ($i, $item) in $val.iter().enumerate() $body - }; - (for ($i:ident, $item:ident) in $val:ident.into_iter().enumerate() $body:block) => { - for ($i, $item) in $val.into_iter().enumerate() $body - }; - (for $i:ident in ($start:literal..$end:expr).step_by($step:literal) $body:block) => { - for $i in ($start..$end).step_by($step) $body - }; -} diff --git a/src/kem/kyber/implementation_notes.pdf b/src/kem/kyber/implementation_notes.pdf deleted file mode 100644 index adc84302604712f39f42c7375dde699ecc99a884..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348700 zcma%?Q;;Ugwyn#yZQDkdZQHhuF59+kv&*(^Tm6@D*S_bzofUESjL1ktzGcjeFUK57 zt|%%_&&;r1cf&tw`ixH(2P1R8BH$?T|}YHDv6Mgkh;+{ui^MGd~Ssle_?f25d8%TU1lsrL79&TY4F*-Mfo(q<|X8 zFPYMgmr61oI9HU=9=R zg~T(`b>kWq817bAlUmal>_A5c%y!Ieki$!hkiSyticzEN1D)h&G2yi_OPtQdpoFTt zPYuX2ak?7-cq3hO&~mIJ>(%~-x1gm-S8!~aXiPOzP?Pi@k-=(aAnapX%1!z zz6o{8+)F-|670_T@}LRKjV+Cd$1Mc4a$KLxt=@_0$vRn@0c>X#ryie%bH?rAu{l_AmKd8x#N$mf{H2n>xJ%Iv@HRr!*XelXDYT7bvGZo-uk zm73rEQk^Kg_jsw<+6#w_Vlj+jt=|~=Q|j#*`9{hgy#%Cw5mb(sYtlN6moH6nFS&(_ zPI4cEtvAY|K*}CUJM@0UBZqcOM*3w5N-u%@ZT!Su8Z%ixxSy5^$E$7g%%jpLM*`Of zJImN&q^A)5#b=-$7wLl&C!sdFh+|P5`qerhCSBb3eY`DruiDUG+;mgLw5(;p5AZYi z)E8NBuNPwYjjYI9XZ+yixRUQ>xy;447nJ?-y!+0#)q$t)WGBa3d1c zk3albVUNb?Dwm4FP;bfo3rgFWZM|)0*=9X`0Zy3B?E2x*@iC{4x?TW`nZ4=%%awmd z|H(5hw*Q@QEG#Un|82spXzREfNhABu)iW^?VP0{&^x3XMA~c{aS2`MsD2;HJ!%(K7 zu5B)oOqjmxJ;jPElbIb)@hIM-P_I^Wmw#m6)^C+Hhhyh{eMfPuIXKk+@v1+Lks>KM zZQcUJFpJQ&vx<-#3D4PUG!vq57%+{hJ^Cfub9T$M(Q#OD|6DxB@AY6Bk5V};Gyibp z(sP+o6YPF$ZAX#iGJ-8lG||0uzweT*9OaPD__ftMk2vFEn7P;|f6e~%W;5P%(&O+; z0{~2=kxdBi*8H5zIvGT|9x{{GTB@<+YV)!azQmz&e}c*BDslMh7>AgQORUU}mDt0$ z%D2d?*`})9$F$}_9n|8xTQ;{pUJi&)BFb#r0z;*{?u{G0JpXRhVVoS9>-7%Y#s){A z+qX#j6ELipTspWqw`ck!cS_}PnBfq7zn``rQ2Z>v+H2W8PTwWD5W;4%Ioxe&;CRtU z3GO+hcYFK28n)93te!3w=Kj2HFcK+DmP|JC66br+i6Wgj+;Z@5eL`{ubis4-Z#@RF z2|$8iJ4ruah@@4B6Oz)u?mF~}ryU0l3uB?@968)B&A2D?%aSAsXWy~ZA*`A zlH=Z4nt>)b0Wzj8o0DeI6$loK{Qg8;G$&cELVxfT#zTJy8+4%QL$fuO$RoazZQb2| z{#ZSfDOrlcWG2_PbZ5vVX=CusMoUG|S1oy;rz}6Z2ySo8tu6L*+LT z_rxE8OY|CtD-Gw6z@(VLh#mf*i=j@W6eDfkM%>gThP7HX56)9DF-gxgUfwZR!!2|b zv(u~J5J3P{Gh+}Z3~z)zeo1!5Z8$^-OBrZptk!IcZJ^a-=4ATU`+N8R=4cJ9&tr^! z(x7h57Y8hm0{Xh&4=8zb4v5d;5)E4w0E;^@yn`isC+^P&mviuh1n)b^?Ds}i57%@bG#vk=&#h&4rrpXPITQbvTRqizYVx+tM3#K0wD6 zgPwRhExHlWilgDy#Fu1cOy(IT3u3kDwF@colREO4epmWha zW90zSP2u`fSr|ZAP;pI48Dlvfo;45OUXg^npKm2itwVU^8OwLoL##zkNTWot?YKhc zK(77K=qaJJTB*2cZgO`_?7dQQiY>diQV6#3Exk_)(Vdy4!t1U(qbI^#LLz0Mc+@jQ zJewHH+iF$c*VqbjSEJ zzt?xlUt|sbiMmR-D{a8+wAbB;X%$%m;3i^PVH7S=5?o>-3K=DTqU?z$b$QyK&WYvgNZK4K+G+B@dqLKfGx#+iwlZe!^OjW_+lmKzl=U7hOV8W?#RR4w~1wXZw=anBL zB~N@P-8UelF0n?oSWrhT7ouN~z~&-RP4-=rm0FwnsDdMNzo7i4cwk-9v|jRy@)P0~ z_WWCb)636dd2bNG#LsP+z&NVM!D1Pqe4qF>m`o^@f>#8Yc%?#SMl!zuDl~Zs+Ha&@ za7{$ZBZOBm1-wtR9=HMgJ%gvu1OWx=u@r6ydMI}T_CtU`FfUFD=J&mWusSHJpLtwZ zQQi-*?2w)^-(JOS4n=IU(h9?@8fz26dBqbYwB-15Cs*!BIFCd+MGI#?$aGGh?;@BH z-DW5F^Lmj_B>uE6yAlw7oQ=pXdh*h$^Y}jJ{VMK&P&W1i6u|Rg?B7gRd{f@9-%3!b z!k;T|fJes<^VA{d#f;H>IpP5dxK*#VtW%1Je-1V~rrI2SdS;#}dTJ43^YJJY9&jwfDm5qsMVL-@W0P@iiZi3q|| z27A$SX&V*CtBdkyNXcP}`Zx(4`@18^kK&z^7Pu-29mBZg56WImrG08&J`!Sm#8RG- zB0d%4pJTtqfYaXBM{mHI38>{E(OwMLAuh_YRcSY%8lN1^zFHj#-dG>DBMGopX?(_! zMI-(!yGXbbS}03OOnZ1}(q5Yx;DH3Mr>O#%Ipo_rn`WD4Lu{{Ho%`g{N1kO~8>q|c z4CKeMkb!-;PWr1LZXyd~aRr%lTuPp!u5* z#v{W>LxWTE4ZNF#fQ(5F^&GAC8KSLyTM)CCR|PcAgYS@C`5gr420?cB_@$l9WW8hZ zs9kcaw;&A?EG_(vSGtC7V4#1!_aHxM+Dy4({Kmv+1T~HHFN4*h8tH>ck8gIdd3(-0m2TF(*! z@xSqhnTh3J_=lN|u$2`U-&C#ic016giu64R$`-U|Tj5R< zq2?#?%98}m2aSo!)LGx|E`Tkyme?BAQY{mH4K2-SD}$Z7djEGVb&uDx7xW->;IBQh zt~de@@uP>v_lL_pH=5&WE1QtCswPt~+VpIW=7>jONEIu3K9aV^a9Vs~sGwuvMxy#` zMVd-gP1JARgsp5Y4KLe6V^#A^%^2eNh82sCz#_0m`yj+X!ikGs1|qq^MKa9(hDinI zfgm-}tWcu?ik!>f?GE*Xn+^aRs!bu;Q2p^oE!>vZP^wx(jGBnLJ>H(fi8v-xzGwfq zdVgE8EZo+nr3s8M?W~sk@ef>tIyY| zQ|pf3=c89AwZjH<%7jp$1TuR|J$frx6-^w;mi3`6cnGv_U^G6LizG1-oel;;1M|LV zVBpp3IssidKFM-5j3jZ)wBNQEDz>lK;D#Pv0PYms5Ki@(ntl7n+S%*Hd*$2MsTE~I zrp>wozzU$tMg+>JrgIf=!(3o}wc-Bu*r2y8AeM`UQR@BMc%|&_>kctnVWjIeWEXNy zOsT$GbyeuI(jL)2l;6~H7o9ZJSGZ&6W!MP`D_Yu2ByqzM_Gt$_})$U{G|fBUzQJuK2AMa$<8uUL{!fFBJ!;p2a{w(Hb zHFmW9ROZ_*$gAnVTP}~Hhdcq+p|+HYr1f!z6ObU*uNR6|7`nwckxNR2IV<#ei>wN0 zI~}aS8=i7tZaiThAcofU_2j5pQJ=+(t92FGpLe5feSujeVN%6E%Y^*4_XXzF+*ew% zUcTof-W)%>m9KyK&d5s5r_!~jSBbLo^4#;ue(&iY(MauArnJE3=nX_gYksd2klz(* zAld!;V^pFRK`0(ni~-HM-4f#k?yokhMwiHh=4?HzSKlF0GGoG?#%L6?gPf5&-Is)% zznK4F@92>L4maCA@D=}oVo987mGXQ~P+iQ(&Mc`R>gibd_ttE#iiNRp2zWYOl5xd= zHCEv(4!Tjk!^N5+xYVjDMxqz-cKCC$_99sZ0rk3@1b?!t=y!*_k=;k^0r2ShCV0$m zb?M;E^cd#FUr=OCi~PV)pA>DBqD0#8qWe2~z805IviX8N%k}x`TO3?hkn`7WU#jLe z=RvK1gY9y~8m*4raH)>UR>&IgO`Q3vyn1&Z-v72}{pk^qu#|B)-JH>1V@~#$D!;Hw zPxz^DAjLIVvj5UkolERnyAqX2;ApQ){v{L`##z^M^Qg35Xh7noTx3#C9p zk7s4MILJY(Po%MO(aE#psFzpA6&@kyZL47$5)$FJ{UNLQ*$ao+piqNmnSDXSP4B`_b zCe1A{rc_Ha&vX&qK@?|+nD`mJN&_yUiCLE8SOYF{5O>b%-)~&YV(!lW!nW1ChpTB^j0OGc}U#e2sW<^D==MVA))i0v+L)A8R9hBRxw zXCt!wF2$YM7v+|rG|fT}4kqT3zTy}TpmWD%`T`la{F?uiJb(qt>eaMGk*UN%AhsK% zvj%i%*K;s#kwS!%AGHpv!nC*l@}LP9kUA-@u@d11{9sR(E){YUW=&Oka$ZwTpG?2% z#xb&{U$Lpd*0R%O+)a%;hGwh7IN> z?sHDdcA?1BogZTb5z{Ns2 zzoey)ZCK2GvjOE86p4f>fR=;&9Q$k?NC&SawHR>y_O(bSdWZx?JW6Z^yQeh1gdpo0@|F*XA7?4=S!cx4$ zpId^5jdJY#ubU{3x`3`u@2A-eY^T%C@{O6Dm=KHEx6G5MM7HMa_~!hx0R8KG!?kyZu3ibJx?eDgpFqE)U=1kQ;FgZw)uPc$k-u zCsQ@9ePyCsyWg;KNzPr{m6?2ja*WKS{)iY@}9(x6VOcJ$1caxLON z9PHcexkWmg;2 z2eH4#n0wMEOV7n{#H3{Z2VK5H=L8O?2rZx#LhfaJUExvRu%fCr6f}NlOa%4*G$dIe zYDu#)>RC^jqQ|{q4^Cq1F%F!89zkdg-De?Yv_+?3qWcKwS9ESwa9$rqB%!QK{Y-*SA7wR2&jikC3B{FcCxbSJz>yx9xTlNFOLw%{fQ`OO9tcR&sS(lC6GUejjL@(;R-SO2VIn5y7z8VA zyXEg98pjC;c6F-Y8f2vtd~(^*Dy%FWmJ@s*!9AIU+4`(e^t>_)HH6Uh{;NMNq3OV; zs0fxhRtzuvARB8B^5D1N|6piNy9IOH1YLqFfs1oOpK#@d`|j4hoY~ zl>Yt~lj76*m+=~EZWJ%wu#^s?h?xOhYA66HlUn!C5w#bdfwz>z){b58;*=48dSw9hgSX>ea z*4Z)eRBDE#`0TTa1!qzkHhKAa$D?I_XeivhI4Yej_KP2c{7f0P)g_iDswQ*go5umk znd&O2n$~=it@JUq@n1)XZmI5Wn}on34zDVp`Ao9w>jJJs0pg7mn_iposEuCikU47Z z*SHdltiTe#)&zAo`W9XKwF*2Xh#QY`ITRz{7cvC{N%MNLN<%b5{7DVOT|)S`+sz5?%bgsR z0{#_@fLY3LJB~VNwcCJ4viS@i>Te`#9exA)myI?cvG=^H6zO1TH{tsBM&<7ebaJJ? zuMY^p0>qBZ94ymajeKHZ9rpDn5%XHS;JZ$gG@j*Y>iC{7M5Tj7Xh9EOk@vg)dZdw9 zoxj0DLfFW=x>Xi(^@{6MpZe}V5hm8HVAi%)oFB04M|=bN#v$N1@OOxA*PyVJ1e^4I zcg?`HPIGV;CfNM)zc~0n1ga7en5>Zt8#YNW6*U(=t)A|$me^;~PsYw{YR{rqR6fVg z5H|?2Ny{!%e|T}Fr8}KyA}?piWFO;874$*)G;p@{F~LF$4yu+N0|l1BkJt6HJ>e+|w+OoqR?bZG~ST*~+wrGVJ_|b_RKWIn4JwBPdt~j@EUt@lRpV{8E zAmO#b3bQfaJu_qjf~c9Vg_e=rR+|?CB$4)YNxr{0*3ZGaym!OB_7%kQaR;Ga>PWBz z-9#F^wF&Y1HCpm=mV@{aiRd5o;z>(5+2RsNNJ_B9BsrrJ)L9@0qJ}WWwtlFgv}6ut zWter7l^hlH_WaT-jeB4 zXfg223~uanEPw{84&2M&W)xgJ{omd$MGj!>tR}3ylPHSa6AahoK_E70^l3;tT~v(p z!bk!F>A1EXGs(brjlHY8*j9A#wRJ|I0%sRY*-2CtvOJKV7H~s$pH6E4+wzn0KnXw- zGHSeL1_`S{_;SGJ%@Cy@R#K_~{p6llG2PQb^u3*V=FgP+9beJ7VQVn|_{V@Xq?a;n zpHCM&&tAIpvy-MNVLJT^jMSS{NMMjIJ8z}pM(HFQD-3vXK)wokB4bl5)RLX(c-%o3 zKu`k!LC6EUO2MC0j1rI74l=l}NdC*YMO?GUO5LKFuoLLnnD&oG=)ujil^VR31|qRR z3CtTxK;sTwb$0h-wBN+ey@`(hgCYl6T0HvKuG`tw&Vqn)=ptVR$40qE&NbpN>H+ty z_)+E1J&`gTzFuROzW!kTj$k(Qp0`tc`@((zgE(TJUI?#%}=WD1^05AXc8~ zEsM@t64|ymHI_$~%4A6!MyGRN(CPB3pay~^zK-6}d%PNGYeCvOKNV#yPAvol_8y6H zjW7JsS`y3XoqL{}@|3T^b3!vS#JBWK3`0v~?HN|*`ko+|?pJN()!rlw5xni%&YVb} zm3H4W`B6g5M=BUT;L!PnGiY>Muor8Y^j1Tg8Ctb#`zy92=EKK&AW;c{?{3lDpe;6V zCyVvcRl)l{3U(tQc+gv~uxPOn6{G&6eC*P`H>S1{zT>g(SlG`{3I!~GTT^aW_e|VMo^rIDN!N4{5^|?^)82&A@KAotGbU>1R_< zpFs#%KwRm^*3}>oWfLo-!ongZ?F)D3xd zwTLXIpbssdFH5dHOs`(_8Gv>cp^_6!gbF%B8ZY4y=Hw6G_V>~PCkeRZA)asXfOy=H@KY;SEVqV%WiD(Y|Wgk z1`xs7Bgp-4(=93Y%gBA(k$p25vM*&<1s%U5%c52Tgn0T*{&vcJ7#{Atv!$6Q&XiP3A#yYggrQSoDdZ1*&5 zH@KcE_ICfn7=ZqMb|RAokmFv9zM~%NvHxaqZHN!dkbjjycupifHF|{or(cahv|)B{ zxH}Fd`=MRW70?hH>>}y{y=*!n+yb&MLI9kI3VIUAr-u9CrwEi#j0{xa*Lby5{7_U z1(zU2@Dlw>N%MyKYxoB^EsfgkU-+Db`+xH}D-%2Cf6M1Lx?A?R6UcsR8q+Gm19|Ry zjKGggzwk_rY*Fe1fi|u|&6L_uR8%Fk^uPS%Uvz!eT?)BU@cI$c!c-OH+|&S-Dm(0D z8)Gr%0RqLjdxE+-yo?jo*e3(77-*g&B%e^|u%?9+o zHex)S)*{_}fZI3Y1;B8ApKK!fKdE1wV;?l(G}DD=JR`}(EUiQYD9t80V=2`TxM{&f zt~iNCipLaP&3Mh;9MX`-9Tl#s7Y9g3yGXYkH$Le?HFo^8bjeAf8Ac3=#VHT2%q};1%#p zLTh(lQ0>&@M}6)rwLPZ~&`KZmDSb8EZ;ad$Ee_lFGWSGdKPh&uCaV{3;*1pZ2w zDypan3cOq%f-h7z^Rh8zDZrwfts4E|=HvjgUW|;wGRtE`L0ga?S-4%nZHPAvVHH>r zctm?{oU_Ttf=5}XNA4`c7QILb#}KiFgor`@E(CeiJ}8n`P^L~lNmHD}J(sD|A0!W$ z2z;zOR=~9Q;eSFBW=(^hihvlkzJW^S_-GLLIMK+`JBSxFPmwGssW&?3NzQ37{F&RB zvj|{J(t-@Y$N2M`$*j@-=2wmrrms~*OA)&UVL;6LU3E7qjm&R4lUKA<^hD_qoH6g^ zrcInDRX(CRv?(r1^=ckGS!;XlCoZZlYZXzcm!wV#ecWl3(d|miu{^dgBHQ}7DN!sO zp$zv-jQe0S5dlEXFL-ey@+nlfp|E-R{x?6Rim+luE*ZKahoI47CCw>o8@wW<=2B?* zaJ}aYXY2-Tcl=eqh2d4ZIuW>ef+`go-K0+;!A}?HY z(!qSs^K1bxXG2IE2A7G(lCXHw-t1t74*P`%PC_`olRsGdfrx%WvSoxZ-|7DL!Tg9!t&D1)G2m&sKgOy-!8^MOPhC%2ejLgBtACF=c1B*gH<% zMF2-~kmgwuz#UUwi}c>B0S3$<5~?cg12&%)YWTQxX?~snT&Y!NEbnihnuR*3^`YH4aD zT=y!dk-xQBCHMc7EB`s*{3g7H$c9W*dtF0$m)E8=H*E`?SIH=^9IXlOEY=5wlDCSq z5FY^;gdx_v@`x`}$_+M3|JWw3Pc9m+4RU0i`ZdGefs}U= zyx^cee(bJV^3`E+{+2Kj_9MieE-*k5EG4NbBCZct>i4m{4nnSjjSx$^wpkyYtrUgn z!mPQRxvA6{wN-_me}Hc~CkWC@do^)2V!f1*gB+|rn;P3W7c?T{zz%G=r2Kk$9mXKk*xI>5tFjhvnJ+G%F<-Q5_Fh;rPvY{OPbkKZ zp%+1O{iNu>rRh_OU(`O-ACowbTE4wi*9MFSq&vjOR?KZY2HQ*#EBcbsbz za>k~!X~jRe*Qi7@4=*BfIF=P>QnWvsZ&ANm)Z*<*hM;}856#noeeh8-aqU!SWqh-hY86LG20lH#Ai8HesF~qE4&y zuhy;aX!CFD*1|y1emnN=)I?W%052g`oX|IIzbn^A>$ok0Ec`(=>e{GV9cdsQMnWhp zN8$3a*EKm zVce>>yJu_fF_IpN>FA^dzg2hJR*ml)-S~1c&!uc!P-H}?ss>vULPdQ&h#-z;Ie9%i%%S)7z@8_Xu=hm`X*8J#mb~#!79yyfdygdrg&A*a>_0QO z11vSS8NEx{p+PwowGs~{!v3Ju;IZXPV<@902tQTj_N{WDx2!mc0Vd+dbGE}%A;Ltc z@J&6&{6It**~TQ91%{A<@CZh>MZkZT;O3!$ATs#afV|^$(2ghpdfVIEZKtfo<2moH z3iByZUx-R@zAD-8(wG{R_X{@|9iY?oyr(akgwGd)R9Um?9HR34RTF^u2Ezcwca#)J zS(gvZB>b@m(GjH5q!kB`sV)3P9VOOsXcB3m&HGMM8WmB_5h$$g6z7Nd><If zB8PxltMuK1GJUj9mPOd5e98gVeaSOq8Q#Koj)m^gLUF0Ky3P@5i(rTcR+3vQg}j7A zx^9`rtY7Y_45~?ZZrxCs#NXGWN5O0$PIHD=n++p*KOW(z=9oI9weZ693vZ!`SF?QR z+>t#HRMaKQQ7{EQv3!1o3QA9sS@V(2@gwn(iw#-iRaJ`SH%B6K?P7hvHO>f@C!XH{ zWPSQqvhNYa0R4+t6)xXoJBcmO^--;aaOK;p4aClAumzb1Ut{xayGKdx7*A5?J&3(2 ze&#m9{SAGUT}`k_9^#m9ex}>xG;`!t9>3#YX{IqTU;d*Is8AXv`ZehoExEd#5?~o+ zmJkP-c)1WyRC^D2%;JEkwdRdWk|Bd$KbZgiEAvj(=x&8Ly*wnN* z@ibCsfj&Ebw4E;`mHu5Mxo{?096cR*;eNyF z^UA1{Cu-8$Mtv8{<+fI&eUrxKx;vYc*S(K<>(do`TCQJ~6LbENM9B`%%ahOd_uk~^ zi_`Dr<$uXiB&XN~JSJr;^_HJ3pdvo>w-1&f2o78{P)9WiAa(9B?n^9E_o-bY68cSy zQ$A8J-6c4w!~5V*Xn=W zh@{a$9(Bg6em115q)OY_;q{Jq6_9Nji;>|cw%PoAJ>zjfVCj-jO=$IHFmYS{byWyh z`jQjj^2tBA4u{=-{ror?nOaje2O|xJpJ3QC3&AOAoj^N{V9M0nHSJ^gZse&+@6-E! zePlNQ48V~hw3`SPP`l^C6%Ki60O}S?8XBQI~#J z&_=ZJWe>4f2s1iPB6J={u%w=(kjRJh z9X+n@3>_PH>)#BXJh;2HXcQrlshWbs(Ae~jq=XAKMnj>nVn@X>rC4LpA0$;#YTC6-McBq5zhRN))y1K@->mJcls0z6SIjj;}j@1x2{XG3s+PbnQobdUHiq ze>b5)s1sRcy3At!Z2N9*+q&O<#nh##GJap3WoG4;Nm6BI=&`~%D zi!#mCwPW^uhc)BAK8(Sk03khZ!0(u&kxJM0-8LC8_&;BW*&0`2745@7i?klJI!;A| zm=4m+v0n{=U$$gS@hlCnw8h19bHux0aU@6#j~;-ID(wKXq9=l5iylkAN=4L=;fkB$ zLa+-`rco>*DK_*=VD*iQblVw>Th~wLSVFHFJ%bc*gS}R#fRZIOwUI`()RJq~U@b?Y z`r7BryMX$DQgQ+D!lh#6Nu5M;5p!kyvKWL4iH_+CMfHWE9JXD}3@L)nDaay*qje;> z`jy)+G&0WP+s`wHMx}}dQOmbnr5EdcaJIe;qC8I|!iBiygM|}R^K5LJ-k_Y^^}y>Q zM^dC1w1}+U(}pF&z8Lbp_uba5HOT1dw7#W~9%-2!xqkI>Wg-o!h!Gw3kWDngWmSK6 zstU!3`8S(Mm~$JhA4;gD7EGuJg58xdZ3svMdl_Fn zK%ZI~r-E3NEmS=y(kKm%gA9lM+_E(c0KxA6`-}P&HSiJ$nDlSEDX_!2!9Sa;>ICIF zfzlY7FQJQN5F=crgxJU`*bRCwi!dTQLF|7Eu-X$>#s|&>fVCru$*04w*lt+8QMo6< zTU6V904~}Jtv3|~EPad{X#cXpO8vx0n=F;lOKfbWRE+e!jLooHUN~iW&(4|j{9eX% zAFcQ$$diYpK3w#w`}5%RWJP^!?AE@k)i3yd7yohZWkYTQy(gk~*%tC;fcOUR|2VMk zjkV{t-Mw4o6zcgg^7}dP_tVAa{K)4xW>H?co4@w2JZ_ppkuKu(&^lY(LjQ z>I{fUTpR(B%3UEixiD?(uMjF8i}8`C%E*fB7gs2{zxV+SRVY(_l}<+!(1n08sAO9K zV+O8XJj~9^zp_`46bAnzjhGfy!*W5YE(~e`;XVDQZZ5#Q-_3Ls6TcJL%#{Fl*2R=5 zAO4Js<-DQrvh85FDOn?X2n;fohSx+$pw7Cu>y=vkt%DSlKhAB{jDQ%(QaX+|;iDk! z*nbZ-v?u6AzWE)EG;(gt2Nf<9nU5*_42#|;gE+3l2s>S|Qqo14UVjqB@LO0fYnCEP zJ12I3Aumi(e(?szXl4w{25x7T*w%7TJCBOw=-mB*EgV^@D_1D4?5q(X*aiXMW}168 z(w zL3I-z5G_bhob_wN;!f?`@e+ATIoyjV>Rc;@QM9$FqG%&CNI|W5LoccMWkOY`dFzhH()|*d z@hrj3cy*}F1~UQF)~Cn2>%!eAon)y6Ofpm65T1`^4a#Iwssq(T%7{vhJ|Dzr#l%rY zj1B4~>^+puJb}6`lM{a{rnD`)kmpi1T-Z(?fE60PG)`1i=a6Is$q0)T+k#d)qh@V9 zikj{Al9OvJ*t=pWe1K$x7mj%>j(9b;r^`F~%Pe@t(lca6PyF_yUd7;fH`J3pC|@RQ$3G5#`^{F@M#-aAlvN+DPZ;M=xQ*(<=)OF zrNLrLv16fMqRSsvr-oLAVD@re-KdXt)=@+!w4zPfKNRW1q^ee!KIp!vb}+KO zRqgmUM`~SF%od;USZFEQB0lCe$N0o<7%bEunv6c^8F)Q-Oq443-7QDp^vQWhI}w)_ zZN7Ap^+nvW6>6YM)MX0dj%A=;isE68C3Yz&b5|*0!zuGXNIqy}875_m6d2Q(b5!D? zsB<)6$Cyg51SoKFSfk`Kfk#sKLd*JLCJeuWm^^OhUSE7hW!O4OLb-bQY&nlwj1!GtjaQ}86V8M4pISL2 z=I2r|Dk)~4;X!*zQtlaz935n=KALRXi zS}dc$W-w-OsOD`6OucNYtEa?qypjX{EU&pa~l7W0^Lh|8vlAQU7 zM|z+B*XzxTG^b4li(C%VhANhE2OK+J3b|f$33-^1pzm+FDjM?$mMWS@4z$RRD=4)h znukZ{$=KYU!l<;B%nBZ{m?pIY&Xh&f*fdEW%VZ(FnDh}{^9a_Ks%Yx8f23^~vHB_H zE+uKC8N}X?vRe(+RMO}9N-SFowFo<|%vnBEJKHzAlTl!UQ zRiVg&!zDZ#L9+^K$=5OQ=xdaF8w3R&zET`0paO$1eBMpu5MHg+i%WXJzpIG7HsV}x z24ohZ9&_U&MJiE_SYIiqmR_b~c^fh2NO5V3bxmDUeB2C`s;C5K7s^$<5DnG&es0Up z0gIxn#xao=Jk~ZeDP%aZoZt~!10)6s$M%kjr@B}39mHT0&5oQTRC!GdoRrY%pKOen z>r)CUqj*k0%pxJRyMt?(0o`4%Hz03u=5$BGNVH~UGPtFtH0=ZJRE-@x@ZKT!aojzZ-u^=czvg!T8qQ(q`{Z? zKdTt<1e(A85&@@m)OBG72T8O20#e-sCZD;Glcw{-=;EKV<|f>`ME0fad%U^uol1qM zCZaGr-t<4&l6bPC$5CM&Ehg-hW%L+!^kFxIzKY}O*>PHGG1nN|%D6tSCf&@Ga0OTf zHR1^2iAJ%jYF}5=rJ!V*r!i@I@?X;ugQ=CJ`@=hyPO*&$oUdzkHGkxSsv^Ui=AaV0 zEd~3P9@V@0+VgPaSY}L6dkjON6SuGviK8uv&=RZ`*eOcnV??H3l&5}1NChA8tnmdW z8Pcst;1CU$Mu&f|?p7+O7C zG`7478d|~AnIP!~L8(>!-gt*Vy);(dUfXcZo-K1Zw|#5=DeJO6h%D@c^N77|vrHKB znPRzs`}<*)cvZ+?C{lHE!G{&kCR)d&OKqkwxF?)#>A(c()>z*x@kbt54YhXi{W~Qn zK3=YD##rHRv~`TZ=RMl?1!kv#0VxpkC?n0G;j=igaNZ$ypLxs&fAMEvl9s=G-b0CL ze8g5@5EL}YCc;#FWuafqcP z%bCi^m%5b^tPA(jLfstrHO1}O{SExL!j}JYcD&&~BSujsl z@*~OMYa7e;1ZcXa8{n89<3UptSvI2^6D^>_bJBR__yR>N#luAzI23EllhY`(()Ota zK}<{Y5dz6hXauQ9jc$J=jl}7N%DHS?jP%6u3uEFRSFKCvaAh;)LPMRTA)4S)%(Na? zAm*O_1UPY{Ps>L6@NG=JnzDcRH4buqsJ$K@C|6F{dQDLH7?2&)sC0j#6k);oEz)sx zl-!q!tiR1TL&)I4F;vDiGT@Yg9Z;ZmW{YFaqnZ6A*EaX~=@L+HH7;Rc4Zx#Y@a zI7&c|Yagc#C7zbdnG=a}+Z*D}klK!xf%FV)5*X2NPpTS+RK8mZ0fmIPS}>>X6W^e0 zNavYWlO_dvJ}QwB6Z<;SCrQeMfbF;Cq)W+x74MJ{!-ep?nEi#CLN8z z@22w^)z@HeSq6%@PtdgL;vX=s_{c(mr{IxzK~#e;?5qA@ek~UUhHwlX1WJ1=#v`w{ zVzDBTs!#!?Fh;p_B0-(~J!kZFUZ(nzQBfBaoV-LjZ|6NQLwxTL_(2|+`HWu$BEWta z63iF-kE>an%Q&=?8XF%sN>nE_JsIJ!96=nrsKf3>+oN^)+|^XM2E4LgeUsFwCyM)o zn9sQC;kfR^&p)|nkIlcX*2SVlWl|iNsn~A$B$Fi4 zFYZK5gWcF`qVR+~aw+kSC|$+s=J=AJXGB#}8MY)0m1A zJ^LSf#Pq_`c6hzUn{BVmoqw<~`m~u!aJmEy@6_;danOLBv!NrWv`Xb!YJLarZ2t@_ zZN&VgR8|ypl*Wm$yV}cuhH%Rf#EC^jjG}**lJr+jne@0qj;Z{Kmu#ugJ=5m6`XiYR z{}sjNgQz5<;0@{tB_#A+?_~pg_%WqAxl#sh&7&(|BTflh^(r|f++|s{RF50ff~9p> z{Y8F?_2jP@7nuteee;&;n&Q)Aw6XeewQp>Wa)?Lv)}^VOmU(8qdh`9Qd$VrXy@x~( zbv10`o`1cLhZglbr@0Yv)qxtxL4C7c9u82Aa^)7}bjxiD#$M~DeSSq*{*BQ7Xr*_* zanH?BhYgu~Z=a%j()M?z_9Y{c`0CF~(XVzPEAH0&hFvr-z)B62LbMwo)&V5%l*ulF z%$lP4@x&H3we}IDC-J98Z+k}rD=5DEW5iBPPfP0iAKvQf!LeVD>Fd`eTmvC4H0@+C zCkNv6h<>xx8g$9+vjqOTgJB5Iu0CEXF!%Inj``;?ILIKKz0Ulq)uX8c45NC)xs4uk zv`m+Itx){hvZGH<`5+z~0gPgJJ4Im90onp_S%}&8H_30FLzm zWL1Isj`Rd-p}-2Dlh4P$JrPtFyTPV)ybExQjmSI&`^QD_c+6s|C$2_zcqABDtRI)m z{ixSVI<{&aZwL>%^PjT6dNlj9!78Zxu{SGGeCl8Bc0;8$Q`4{ZI2ksFnk8&zY{Vw~ zbZm?1z|Rd)Ed?_nLL-)&IFg425Ki-}F&wB@9)qZcCP{vzx_BYP5a=ERYLxdD^so#C z9N-7)g$pU5Tv$6hq4U*G#=e~UU{CZDo$a`{bJ2{PQfH3|y%OpW8f4O!ht$ z4a5H8%ofSoAa`!}S%T!j+)(ncAU$?gx^#E=h>X(nvNJvDzo?z-I8Va0@&m%V`*f?% zCgmVOG3EFyGwjP1E@bvO#0ON_Bi;Y$xL6{=gv*qIlZmR#F<0@zU9`B36Qzul2j*-TvcBocTj!BRzw^vS0I2 z7@)bw&gGczX`g>k900`zLa1V=b=phkI-GzU#bki6N?0MsK`yDZ)8RgdVe@@)_L5n% z|22617PGtpg+x72>{c6)GhjR3sNSWO8ta{84VJxl@7#h?KL_5o{GgxnF$t4SXlsgs zyRe$f@`TkykJ`8N=MTs*-YCfQNo8gFpcV5xLhJwu?9p6!<&J!=^w2PwKdyc=C#0ct zzPJ-AG8cJ2A#xGnjff+=?apkiEDNFjFql1zAS#$`S9!{^L!c92## zgqinTxcOI?;C#a+NJn1T1)U(bTyVM6Pz3lZWCoNvPCg}Bx3LNyc(rsjGc2{Ug zpXYI!ES{HnSWu%ZK<_Y47BlvK$OA=IspLRLs-&DPDty%T0p_VPWe{qkegU$EgTB2F zl7_@(TSA+MMwQ(@9HwxQ(cx#~pQby@tX^OXbufh{!~3~D;p$#$N~x1^+0pk(_7G|f zLQxkTnEMs0aJ2~c@WKlqWlIU_<~28QpyK$lFxs7Dd|Za_$>b0T2A-jaovmP40#^QP z`O+CGScEd(sF@5XID8dfEJ=mW>@5zK8Gdp0zW z$3@s1cLTI!poItH@Vwei9b%J1HGOktYjv2R+4}V0Tz38v8YrOMb-rBP$z<&gD_ovOL z!xjRGINH&K!&zvnSV7N-9?Bsu&q zBzf45*z>7&N3JFcu@fipPG7-o+18jfRHY1e$zyIDTN6z(ePLks>%)t%2h1!!Z)Epk zn8>(x_A__((;=X_h0^?X2^zD?M@#Gbi$(w?8c`IB5+w)vClS2{>VFy{(4saEM%NE| zxRcYI2!^b?d8%)3=>BHl!0)GpIeK8-$S%`4x^8v%ep%dK59gu%1H<%F!qBSprs2n} zb1O(Okg8cxcz%V$G(Yb)0uc_S?vKM0LnIgF?sv{#7W%2LwY@D5kMAJU&;rP`5sDk|*M`Io3K zVUMZFz;$=lE#lIZS2qP7YLf=hOb(9!&AH~$H!w@W>!jrkUkenIi8=N{C^bTYvJ$ot z4KLB~TqIgXD3>*Pt+*yb^_J@#YQYt`XifL={p|By>sC?N2S2H8lH!>n*r7ze#UsS( zURq08{4sa=B0w%sPK-40ktL58*^r^~SI4z$mkRATWT_pC@)om#Kof(3zYi zCHc{ajX<@LFPBbuk#4?mD6JoS7wIyBe6tw zLM6a56cEZSOFfXZ^O?4m5^jC85RVA+-0-MO55uel@9ko|U#Kt&^Y8xqA)2m?G7>w& z$pfP9U}@mX5VILwDn%`*Th1lyKQr{nbXj}wgMuRIsOOrudGcj0FCMR_jV}6TO;4qg z8|Wqqg&9R>pTV9)v-LSjuVJi@{OlAj+cdsn@i#690GZt7z64(A7n3Tf!(*j=d~VM> z(TV_TRotxPHFn{CD#auz_*+N|iKlLI6NtBaVck> z>nXKM<{Oe|HSzfTk#<3P4tDZX)jEG~b8NaVmBbhST#k|55u3O$p0w-A)t+4$weQ~L z*}@&LA>VF?D$zo387B1?D}Z7@3IZt%zJ9yfn)$JZjCr=!(2>#EFX4ogEw}x0FURf+ zwXf8hz0k#hcigz@-h4j%XyrcoQXpRv)}hUb;cL|Lqkdcxf?AHmfHA6$fmol=K(g`3 z+jy;cykHKZWINaaZOeEH|20s&C5^R5hSh;ass#r+ymA8ej4mJS=R5Ia%C89TP$Y;_ zWSR)t^KoXL4fGCFML{|)tKwpK-vd{W^)JcHq}4IO5F!8JE}}n02QAl5Q=n!lrDTV5 zQj+GGB)3$+kSb%0JiRH8S39X_aP}AZSmFdlrE3V1oB^b!bRpUSNzq)Yl9zamsSEN5 zl*A+y(g{So#$8COq`Pi(sDGBt3Oifm43FE-&z=HD>jE7RR}u<-tv- zhWg{dO3yG9js{ZdhVk3yXaFFXwAgE#yr21p2oWQm28Ps2CV5}~enk*ftVL{kEzv)7 z&?AvNNc-%fI$XQA$GFL6xd6{H4g>U4r*2N}R6u2(l-7|0+#-(#$Yaj2l_G7^ebaPw zh%jvGGPh0$s$e${3}4RwZj0AOI7ciVamJli_R{!b2&d< ze%z=a)CiT5$N)ORGFa)eGG0YWP=qP7L2&4S|4tST9HmRoZL@%ds#dbYJ{cj6?>glL z%8ZpGpUoo{-V>^gU+!<4e;LX%c3yw@%?D!lEzne(8rO&}EUWMHSGOLb0 zlPwuSXO;iEr@oeglK*j%|8&X3Utx`g@)>-&uvd}E_{qUgAVA|IA3?(M;Hy=+m9@VAX}#CY#r8RZ(vQ8CWO)`@2)Jx?XJ2%~po z#WqA+@>y0z9CxJ-mkM&j~(vV`(c2< zqjdUsa%08Aq+fJIGh4x+{KeC$YwuI8p%A)@3hZN>xeayR4j|=VBiZ1N(n;SOf+$Sd zGMooCBGvVVT*_zsd~53i_C$2Ph{H`W8`Ao#2d7T6y6H0^0z`GV$a z1(PaPDq0nffXm8C$JcWA_iD?#n%HkB4oO(ebG6hlKTbfJS|O}eJ-0HSc1UjbHr-*s zPV1;`0@vo6``LHxB@XuP%ny}5J5S3@s%&GXN2Mz+FXfxG`7G(D(kV5T9Htx!vdP8X z>@lOGPuSK?xtyPxL6=;BVBrN;;ZwUuS8;g54pF28rEL^W@*hpRaS zOO}89qU{qCuAly-pNh3NPKAo1*vEGFzYP8iTRincIJ;NtP)zPp^o7Rmtlw58WDNPn zdE68z9y_~|y2YkV5~FefgX* znWNs1@g0!UgR+9?Z@NKR@sJmv%QJbVaf{{ljht)C_C0Seg&-GFtp7p>?#2r*5hTxH zHr!Fw@W2236j3taexm4m_2jePqwx44l!|hjd|1DD@&yl>{~I{|pWPbD9`+{qbaIB4 zO3pS=bh7vi^z{Ej|wqZr4Ab zKS}=<&J8q>nE$q89ljHbg~4_eu4_kVLvPp2SR<8sGF7h?HV_y|;Q%fSJ`V%dj68{P zg33%;-Z*d~GTpwc+AT7>k)lA%VL(Ya_byr4xtO{F-Q2ilg78G;q?kIHJ*Z#)F#peQ zxR5ejQFp@xLuhBUwlLP5ppI#s@dWmFIL%XL^_&T$BX+V2`Va=q5sxxBFm^fve}q{x z2L=3l_&E0w(};((1!0`G;tWvFs50CDU_3h)iuhmsBuV#Jf(iih^?a8|*u&fO#6%Uq zIqVgjK*JZ;;F5Yd0RspzYF4E5fJSq`d3O|oJU~==4kO(96G-wLAR`ii@aVW>N1Op_u=%i!S2wTBzbL#d>CO6B|yZqU-K$7h22W(db%am1!-qAx^>|u4$Kvjes`qFDtK77NyaUH{a-e|7~w0HC+LZ<()~=Yo8{wqW6mK zBJWBOJg%Njncpy2ZZ5rs`fC&~4XZb8V0ERx<#@f$cUvp!Q5$G}6)oGXO%>;{`>#G+ zr-K4?#{oZho!VU%bfxA(nXOIDwM;sMeykTUn0nHvYK33#kMnQab$QS%zCPa#=rMXT zrBQ|*?);i`fkpRO2L>Gl*K}FU){;4j9w{;$q8GIfpeamo zBX)RpsK<}Jq>I0?BXp*Z@WWlfvTBFDalZ_{9u$k2R2rApf;xq%^X2Tt9}5zeQc2AT zjfpv?k@24b*RprBz`%=1$R5ee1*T2eF5!wqra6Kea79_)d1z4vIMvCMs%EIx0$dZH z4Qr1^`_h;sl}1%G68Cm4Fu?ikOoA2MAwmE&svLisvCZwJ^Fv%cCzR+9a#$VL5QVOilAEs#Adms4|DstLz#8a z(}&H41xU+k?my8TmQ0Xi0E9+{_Qj{P$~KFz5+kh;JFOS4zA7g!%!Y zqavn4D$oqb5qA&_bmWi^yl)R82EpV*rt^5@L*WO#yomeU%x$jyMDF;D2=7*>XhGi9!wfC-L8ojBiWHE zj^ieX*FcKfvNzbQZx7if!OmE5q~Q==GHK$HM#3sSgbOr|vBVp}B$`OfKhU?s{gsYp z7GE(8a?AewsyY{w*|qpUX54O0gmjedz6cwByx^_0R(+K?-Y^TApvp^0I#Yq88(pIM z9t(ez@Rb~~<*f9^VINjHRvOY*+eXlRw_G9!F&M~=ku}Y)CnnGK6dK8#flXqaT4pp_ zbe3sin_i>WSuD0d3Ij!!t=GWI(MfU$w zfTlhP8$Ne({dYmf!OzcU=IW@b&mV+_NUfToxLn8npYmV_102bnD3?wJgVCCBYyU|f zTn8I8L~sB+V4&5$(S&3$D>)b((JkBmt$|qkm!qa=y8&_LL^inTz8OMHMY!qzIjxpD z%Z|$*m9S@y>D5uXUPtDG!9M&ai=76{tU*1nMRrN%wqQbv2QDHmSE2hI6b(*gDoi)=*PAx$ z2{j2tIJ_oeJH3N9Yb{tquPLR}e6EsY46{onKlyTELk3Bntl;vysI}#@s1DpOxd_ki zPC=QZDW6h*S+`*|@A3KYs&@Uu!Ecc7u~e@(%Apw7@{DP2IaeN>qgyaDP}Ew8{^w+* zvYAb1V_z^5o2+o)DCBCoZUi|@BH^~>5$f&wWKWYt$(e2A^kCv2XM}#$GK$$8fj7Df zWzU*yjd!|QGg2Y+0(%JO2>x&A!obS@pExfz#{U|eXq`K4j-dS3_5yt`B+At9e99Zm zHvge;v0SeyZeDaygq0CMqQRwv=g5`*dF|nW&@Ui?R1`~*?g7{{yuX{-<-*^;VjNs& z^J35bb?kUOkROZIH?AjGKNk_@5CVCWrVJupUO)GE>2ccp-ha|stGM7|xiaD(xqibn z!e$jY`Z{)8bzw6req{7Y3otllg_SYQDnuU$UFw2TXc#(=?D}DCA}|5VDYt`MlnvDsK}DnOO!4w%5voCdoh!7h3)193*MHs zC=Ix~R+UI7>pmht)iq9%)DpA8?Y(pLovf&|I6+*BqDij$^5F#2{MO_BtOn7S} zL7$9_PrHfC?QLdtgOh#p?H1RElZ^V4x)K1P{w$EspQ@Ty+#QD4q;*%T(&^6M5;dygg$<+)gdv|Pk3>CRE9}fZi9L%4I%C=~T+I}?+-WC97)Ww7a z7&pB1qo1=gMW-u$qCV!fwe; zStM2>tisFN0;Dj^k53lU+jDoy=T>nALr1pQ|7CfU7S1=#pS%8=erK2}y@1r0o^z_tL!~2qs4W2$Dc}2cpF7Ny7BZ9ha^jqewzHh*;OSGTPZc(bonk z3<*j~p_f(*Ll``IPH7lI5dspA;BSx}L9WHZ0J6XkWDj9*Cn89{78?WbQh~_AZb@&~ zCq@v~x`*qo1bcF657ltBATY%J>^)pt>R%V`1u{Qqe)_!DIWMCYFKfq%_oOrST&nkB zU#PhqQ`RrCuuP8>+V;}C*<3ch9E)nT!KGPzo~?gugGQANp=Az0Xz0&HvO$F72#ZfRB5w6p^jQB7RIS<~hyDt?26(@0gND-)uE56F4LhAwJNuStLqaBg zc!8?r@iK_T)GA;E5I})V*M`4R6uS5Y1snn}V=U>?v!Ecz{SR-;8>2&5l&NC00V*Y2 z;kn|KNsU3%qsr{bb$r(!uswv%DeiK_KNbLvt<*Ri8ik`OkE6{d71ddOMsU^3i>4|( zJ~lqI>)Q&G&Exsgf|<2W$n_ZWo-!T9`na1*4&qrbK%Op6;34Q>Cac^fxPNXaH8ADx za2>_iU;~g{?mIN_A#H0`#+!vj{ZNii8-~!x3i1ez(lfbfSx{OK;FoLPl8bfd) zM26;ETo6pd9kxg6*IG=om=OVap@#p0vF2Y-MFbQ|y?c=bIrNIZxb)?ed$=`{4yq8m zH`+jZbr_zhktVlqMvE!q8t;)yV`MTuo09*{mmRa>N-`l~K2Q<*CFxoXp8=0@$fJQT zd@Mze@%&MIUu+aNATI#;>Vk!16O74) z55ho%QzMG`molXJ67oi}kmD`dl4v~iCdx8`99fsbXw+2NS&!;eF5e`0y!%8B8(I44 z-zybb@`lB4Llc2d>IAhh24ShFEpQ0z%HQJI5eE7P6qK(3NOAPIy*?)bIj3m69UAuf z%aM_?H1B((nO*Pc6uAA+7f$dRUbD74NU_|a3LayyKkUc(-so;L9E+U3f%@J;9p+HanqX^9W`SR?|OwV?~qr zEowV@^Bg$hEhw<_h)%i}8$Qqzcdth!yIX}4Zsj5}D9;thiy`CVbn9rkmh*(BLvHXk zsK~Mq$2|hyhk+`9Que97Y{AOWAKJLMP^EMhgA8Y+yup+BpMMMCRVEhT%JcPv# zp|m0w7K-0LNRyL{F=rO`DA996Y+IZE@(Rp5b-h?1dG!Hb8;{P^sZ9EJXe#d-pDCF% z%GUumk`gS3=?}Tf-UGYg4_jKm8LW-$k5$)uRWWr1uUeD!Nk_# zYyJIvjqGyAehyk{#Rlm%8Hz$Pl?OOASVrEX2BrC8O^)~$0C5k-f52)#6cUyd8CG0P zz8R~eIBhZ(ni1@|g0%W2!w`N8Bb=XiVr%({(W)AIQ&rW#&adYySz%w&k1=<;Xa?;8 zp54d8p13IG@Pf(fg%=ILUF>!z*Z1+}Z0~K?jLgr+#~o92@#WG%A3W1tj9in077|2e z)qT%(_F)e<&hLlxlKZ%6h#KP0 zT9?oBvXI!C=_^qSglfE!=GEj?edY)~)Q-yV_aOJKWa#g8<3A zsT3_mn{o?Zd-r@~8*_z5=7t9~jm-Cf$SS16+sEGYs+7?8X<7Ey)v8#MNh#Zs$@bXo zh590TbzreeSxB;!@v_XvI#`uW14sAPUFS)%>NY_sA%H7R#y7U+sVuj(@)k8OGfiu? z#9hA^#9onEkFwq1lJD=RbK|4@!*#Qq@+2>7TfJ`2 z#0>C72sTUSz&v8*ttdQNMeS>MSC;lJ&lQ5lGm@L%e!IZUc;qXjj+XjM>|=}SY(5C< zHprGc@W6ZPA$-kmnvL12-WUYRcvj;qJEHmD*Wo;q@&-TZawefIw=&NK7^F%&8SmB`DXnfpc zAedORYDiupeQtbQFsY=7(7U#F!jPfEk~jKt_3-?eIPav%$99pj zYGjz2UwWj8n?HNMici(8XHKoMoP2b7nc3SIWKKL2_eLuN)nsj|$pcq)*rfaM^Z5s$9{JHhAArryD)7sb zJ0n;nL+^wow~~LOhhwRlN*QoKS=N7wCxLC57e7DOPtyN%3C?-l)O9)#Q|RNeMZ4d6oKk$1=IIa{W7-(=n&$>65(8t@!aL5)I` zL}rQD*PkA-2td}<-wB1rMkec;C?qKH@BzR2hx+au1Dk+Q(p2^ulRde?2-0~d43>Zh zi5r(4fo?90@v?ve%5Nluttj7!VAfx5Ydf=c;h$}zice`2oy=h;h4-|w{D;BOq9i;% zUw5vr)AKuy2psP8H81P|&oKW2z%ZEK+@z*nURBuJ*q?h>_pg_y!~OHHIKHokpEM)y zT)18zfaOgcWB`UC#^IkZ@B7K$@4Mb*c(?j9d-Jh6cw?DPFa|Zi*0#l5MpMs}zjkcJ z#(;WkU%V6^LWpGzH*+o)&fK{VJk~{w1;4QI;6m*P~a@b?-0E0!9aj_%92u|0ju^mn>$GGS0p;OFLR_zW@cKorB zCnZh1{v@;#ZfOD#bxe^Gv4=P%3vA<5k^UgxsHKFaZ4CJCMUW%lQav_;(X=?aHV4@9)*=ztH*;%8zaY<^w zDtFCnS(PWTApb3?lg0Ao!GE*&A_v#I0&Sj6zF2Drm8bGTv_WqJFR5%%#qph*|Sx?SqfTV`C>$Yh8+&JMsYgciQ zC_YaV`6RF+@z5~TG^sOLtZu}plR%L_Pxs9*B0R?y59QOa^87i_TFmUz!HjpNezSbM zzgRZWkoJlDJOIZDyWQ#eEy!@-W^38?`&D=3qItiUyM>d>^}u~JX1xWED^ok1Uyfq^ zG0ThV0fFYfcC6lWKds$ccVTkRtjCbSQxxDYJc$s+L}Dxmd{}`#g?$ker1l~pP;x_P zO=V-LXPbSjKfjGPv`DYA#pR7dqY`ac1{)Dg2xq{Q4}i-G3R4iJ-yt6=&rAhi zSGZ>cf{qagGxG~;lUP$kqPmuS&Sr2aSy}tVsj{Cto+t)>XP-tV^k1tr{nuW?(%9mrHX z>MI$#2%6F}KEYU5d1sKWM?LfHV}4`~qvJ1qZ{kE%GBkPkk60Fw5%@Fn);dm9UI}O+ zW}&bDXsF5c*5Z~&PkHaF2L|Dn1}*0+4<6WJL(e2&4FvQDHQh?gTmR06snNySzd`bb zne~hxw)~-Evg*_QCt3O@n5^=ECupGM|l-{ge>rxK8 z%U^(r5G0=Lo%CN!r=~PwS;I93+ItbQCj;~!?n6)ul3@dBr!AuseB&=B9C$GC!(gF3 zOS4Bd?hkwWa4#ikRU@3x*@MjfVoTl~k6JRz|XXDrFBr<6@^{=|I&{0T~f& zPhBc);-;F7@8ugfb!ZP57xVD&Ka`FV3D(PS_QrTd3bEaBAHQS)RBC$_MSHIWj7WP8E6ESIdnBUs9dogfu*lqEnm7z0K0@5TZPAs*)o|$4#kIJ8=F63I4L8*f z+T;8-5B<}$n&1xrW)&>mKEg0R;tx>SmT40Wfz)HrpO^fynvX?kCJVC3K)9zuvHBf; zx1mLTDGa9iJ0qy+GLBel;Y3Q_^o_XkP znnL#A$e%BQIyIfJk>1T@e%#*UD{@n^jZ;5tD4#e%`ia(*Vf*c^mwgm@IHkWzTid)V z-Q=7(OZveB#dYGVW5`Q)P4B0#^}T@F7p1Yn&(!SEFi@@aM~m%KvV>h~pf>vN)2f4u z3bkc&S`-o-_2sP&a@~iJ(LakhCZcVM#-DZcYk>gGA6PxS0iXYXt2q8o#qs}LAI8YS z!v0^AcK?iO|AO=Xs&V(kS3;9K_!6J{D>Us$S}wQOI)*v$k%{N`g#ZcGe_lUf!SLz# z5Qu3uv_9Lz0hrCDU!DEFU1sO5Xp7eM>dYTMM^OgprqxH%2~szw=p~w&*1cVxC+nCy z`}zDP$Qj(93UE6nf*XaYLM}~SUM^0n@M`ONd_uhb$Ju7G+Lpsi8G*R|Eb}sXbo^ke zL|gf}>`Ypnes^BC%IEVb8UEw-Kc=&G-~HYl2yg&t02DR#md%jXSgvn^R$ z%xTr>>%#{JENLLZ|c=RL0bFVkqsFGS%OS=t|d?!RmmCI&F6OxN*f>Gchr zpw1ZtGjsIvhm3!QDo#FoNz^jXO&T@q)~-uoR@Q7)MJAvWkto%Ss z`3Q}cP^yVh(-K&J-K%3OiEz%Xol{w}l37#PX*Ur!NB{n_oDH;h%vK#~Y7La2i^r^P z42ZVk+{ZemCIZ)8i^wjlv@3U!iO;iQD*^o_8QB=~dqJC}SWg-SYh78<61LK)LoACF zw>c0oJlvmPpZ7jJrBhl7IOu{7aZ_F}O^y*I_(AAORWH~~P$mt;WSG`wO-d)c3>X4% zXUU(xlP1EhX9nI%c@vK63?=__8VeZQ9GG8jlu%;?T92ve=zx(ta?c2|EZ4 zfN7V1fbI30+sH;J8UdZDCH^Pl6Y{=rP!T?+7QmBm5nBSwfYs1tYKYu->4tN03W-!X z8P-q+yO2M}!fk&ybejXQRY5P?==B|NNR8USEvNpI);xhoM|~uy2?gnH;IKS-H)gLK0;4WlXdXNeM%@%NBQSe$*~aI zf%X~T=`cf(atf#s=kK-Q_FZMAJA_7B2>7FSjy@{1oLlDA7JVGOg7y*5&y8K1fi|u! z-h?6RZuOmK{*@!+ZgrbV5f%n4E|mTpz^CcV>g#YRbta<#tlsi`)dtdpx*2*cS+@n{ ztm0+fFzeS$S)>fB3CA!J@{cEPx)!UI@XQ{L_89(Kp2@fF_i1YMqCmt~n@}L0)+e1R z{G?nz{qQLGZ9L3Mj}$lw$xQZ4C9m`*XmU~~;aq3IR0gv@N->Hp|N2$=8SYmXdxqL| zP}~>HorDV1)h>Mosf@COYsu$`AKd#tTccExT#Fbl5q8=}6KR@6i9$;|19n+`55Fi3 zIc}7FpKt}Jy>4uTe;|t`4sw9T*}VofvH{RDhgL#@Gx7aomhJE^8_NoGPgTH#q1Jo& zun_8_7lv zmlG^wjsyi+9qMr_CK(MA;Es89c*Bj|uw@GPUC5s}N9H-X^N~eG?WivCXBc)=BxuR@ zMFrASZo}cktZ#f=dNY%0`kc!hfVZCY;dXddflYm({t9|H=RP?|>gfrXVW2;qbQecx z9EAESSZ|(uC+sZb<}#!h+OF9pRO$hZh^aFnxAFJVieV^9=cVzu%pqMN4INDO>=tiK zOdHSLuRaye#9x`?PzC!=S$?TuVkQY`COth=sxeVvqrAjl<($M{!!r9CNI;`(j~fIO zcfe)FnK*We>pvH+@|b^-;86tXzL#ojzch{{l{vpfRWhv!VahROlvucof+T-s7`xw0 zsrcA*N}y!H>`u|DZc{3>at98e(O;v1dQ*&v6C&{_?iNE%crEU6IWNyWfi&9N->35( z5pdS{%a9y(MEtQj-41g>Ym z27Cnr5|6;1)12Xgy?NwLv|v$LWSbCfnydD;n6ElM6sv?#$n>M3IN*$cXc>@oL450f zNZ08^VkEA9M6L@e!H?Et{AWyXpn=I29%(aH~ zx;aU!TS+X3hf#V_|ET}QDJo+wTKzsMNHpX}CFx}+<<~b`CRqh9TyQ}BE0=`fmMu24`~7i#)%bJYvVb8Z zaJqH+95U-DaM))yOrkTF9mW3ZmhnrS)(~kw(;Gf1eB@_0IozR8jX^F>CsaF3ay}H1 zOY+Oc6J;gj?n8-?FMMrF=FXWUE!V1|8=~7-;Wh5A{F2AN=Xdld9~*G)BUPBn3II!L-DcGHN3Zw?hCWax{iE+=3>Wldqy~Mx zB>o4x>uDEcVsZW_zQPR$q;yUCTJBs&7M%N~Gy9@`oEShOx0v5BsbtqMc>y60;6`drycOrvI5k~AJ(y%|oTc8aTZd#Z@2J|5`w zNBL#n&D`qE%IbD8cOYbY+=w{1sz4ZI5UHuxrpK4EcT(%d{j{K4F=VRo)vmo=uiIfE z(&=h!4l9Eg@*7z_usPojIu_l;4Nrklc=H-075>E|7 zD~MkMqAH+UrPI=ylGW`#93bg^tJ;_PZ_Y0FX%G-Qk#f6eb#cDC#k{$zT0q3RgfN6A z)SdFk+yn!31wsHldlD%Y!_X6)XAJ+6LfzzN&ez%A&`vD%j5D;gSX<3LxC?k|+9)G5C!X!-$pi2WYdgv!SPl4!DxVJWInBR}QYRyHKl91`E zgK7jOIA-Jk(9{Dlmv?Vo4VA(aWb|bxt>pR*sZ!(l;3n0SuM8C&gB=R~Yzl zM(z~X28}U1pQM+l+wqaTK)2%4K!Fm@L1K&XwyukUkKlk>nl0wq9C(1PCK!Fj7)haT zYgttWzyX;6!XY(YuH{5X5T&<*<&s*T;A_A(U>G*lkXO!{LTSy(65FhdBQO&Uxs6v_ zsOQFzX;#j!yMU_3Cm=^dD@g}RFV88ykB*A`)!v!9y>LFT>=7qL%uU!1uF3uCPtuH2 z*ZDVnHD(eYcNH!@81ho3jT4&~BBJ@+LG}~#NM;toO~ZT?)^oceqlWkR>lOImAoo(j zL7T5w`fnpLY2HE(t=-0pOQTAVxN=9h#l8jM8N#y7VZRX>=VnfpS<_2O03RTdd%>ha z^aQ7S%mKxvB$O9GMr_E4cl0$);a4q`=1gkt(^Fa$ulO^TsV?c4&zDfT55Ja{O!J89v052DB&&W!JAWMiBcmAELO8hyK3aH5d0Sf5n3 zTM>SXp)*P+@DT6ik_ys@n|5XbsE>aV)l?GFz{WH$DO!Wq&kQc#*68+y?bgF4RN%wgP9l)1FC=*Z%Dc!(G@6ld(;lczx4tTj3MGC1f#} z8xmd6_yAaZH?M@$NZX{2Wa>K$H4hw&zWkzORdlQg2K96VuyvF1b^6Y><`XPNI_LClh%} z%_RH|y(7Sdu#bEl@#DSWpKMdIpV{ML$tdEYbHy1Nri85aa8N4 z6Wk>MwOa!GDGd(3-#VI3S**Pd%xRQ9W4bb+Pc*-Eo)fn5FngD=a_YUm+xpYeVH-MK>bEr|7`O6W{WDtDz*=;E z?W4iR*(;gBhtL|21<)&p0npNpEEmFacr1qCmlq1kmUX>Ny~v}nAyY5 zBQqeTt2%ILXOBL*?D_O&l?IrJRu>#ij@hy+;kNBNu`w?MvM;5Ib~GAwaZOHcFDcuO zi*=$Ly2Ap;t1j+no#m_Q4D|2VnDlq-VGe4{F{(E!YbsIiD@WxjtPzhhX7b9|hpo?U z*Z`>*)dWLKjX0QZZ8gs6W1}}gUOJ&I5khEg)P8jB66R3c>LqLAo+*hP6rgjR{>h zBSxfU<34R;+1{>#Smhwb) z__;j#sq+0?2vbML@;>V9@@S!>wAX3kla7pA;e<%TX$JB(`sB^gYa@;-8Ig*XgI9k2 zE}$(0T)*XguV7B5S4(&C+G-wdOVYj>pbyU_j6SDJd7!owwCT{k4e}hw8Z!YRV&p&n z3#h~m8TcQ7Ec1UV6#f6P<@8$fQfX5Z;de%_V5V8Avm(}u&pa!`7|Ld&82-Rpk_!VE zh}p=Ra#DgT=jV3YOME3_5S<=I=G~t}wrab3d-vu#2i1%WW2R?wVE@Crxuu)TT@->* zaL(EprVYxXk|~6PP};Pp=<3>^fN=`4!0@hvI|Eg0Fq?tXowv5Ku=bkISRO?zYOo_) z=DW#}^ULRH@FkZS(TNDL0Dr?FCmB3!`9Mw%-KrmBAdxLNZx(p5=~2Q#RXPm64wr3U zOyAYo!3|)fss#6?2K|Z>HmS=Qq z#|1^nxB`7yYB*VGN+&H=tpAoRaQ*OkZP z=165wh}$0ng1|aYB1zCBs^I|yYVSaXLQsfaK^4*fdjd98h)Tj1q|t&YN+qP}HYL@HNzAyJg>=h^04;T@BJoW6YWq!GH0>t$3 zX!h~ZSvcSM>)Kqyz6Kd45DKJIai^Of^Z9V4^pFR%waCE#XUWpw^_+=qxtd%BpOoR8Gk>skAH zB@ksqB*T1JO_FFgss4&Bj27$al~~osQY$y{ZtmuFhQgIMZJeOXd8vgp`Jsus>R$7H zyY5uy_x(6I&RnfAx(5wAl7Pe{FCqU%1&|Y7yXfi$PdN)fLc?89v(@+9a$F(wFP?7# z$$d(DMzBpU*FX;i$-5cQvqpP4jSTEz&J_AXd&1^e;h;;B7KiO;gzLX^xtN5z7dm9e zMm)(5|Jkyiy~$YgG;%wdC|bYB+Rx>cSiD{>ik#v>STzpg1_FSQ`D{%Q&;@w}6d}~#+h>k{qp{dbHXL@F1uHEpemiL&RtygBZ zc|x9TzxepTH8g|I+w&*bLLz2-f?mYf4N~Q2oaS!SNG;U{&!=xZ&nNFr$_DMGW9p8a zlszis*~&+3bwfhD9w9{pcR9>(?vtFji0UMAd@u&SwP(9HAFLz9tv!-QG0;C?i!tM>yXe4ePc6rl5g0@ay!!SOG36BjOT2aD==TAxbJD z3NyHEPw!$@d2RPd<+1?Ol#^G^`M|n)V(jJhtdr3~% zE%>X#-UCI$+0601vDgiIAeG?98`H;VnK6^=eP3^`mJUcZitT1{uba^vSvgZx&DYXZqRnscgOKXAJSQ}CR1vRFJBk02A zJ^-kc1(%TZY`}I>d?c#8xHPan*Ybr+}Fk&olg`lFn#O6$;|z(B-TZ z;6N(@#Fo}x;1}7;SPhL8KvQnpd#G!Ui;};NmaoYp$N^Ndl3FSyFt+6ciht8t( z%FWwM{U-_`v6tCNep!CSh7_eJlGa$5vaagDpiEiqiGZ5wGk1-*oGGP)q!pyEq9p<4gmP`fDZgygL4BR_a78^5z^gLY zQx1UXCOv||Kuy7bv<$}dN&(3_06;iU4pOlKiV^pVbkPQqV@s$73hzQ9`J{?dKma!i zZ#vFsLzN)-p^_wo6xts&ag$GV<<*EuOyw%FESL-aK}e`Ry!GM=#8m z03Ubv$$w}D=B|nJSGDL(?_ZC{!|HayV;H0{Tq(MGW-<~+O%pK5L6F(HbdC6ry{Vf< zZ0ItlG@m-xY^`pi2MizQ51q9;RNKV{nDG-p-aqGzFyZ9$Ll)|>?ukSL7>Y8h!h8c& zTt8f*5tMBx&wc322&tF{Fx8TnbWD7UOTSX$~<-!j*S{r#*|PzUoblWK&SKs20zNoHKRi~BXi4CrWj zu*Zt_HklAxf06S=M@Vq!BL^=X|s~ZPp2#?i zm7K#w&R$A3Vw|@z&0Sw6i|IH7jS7Wvg6B{1&P>_^+SKC%m*g^HMMm)td$Y5kmic#D z0ifI;aZ2-rg6+#+fSV#teM|bK>cr)~vAq{~F9G*50o~&osQwJAdxI4Jidi(DZV%d7 zQp)-{M+szW1^TEbV?44Lp$MX3=phFCkVdLSA33%7{Ss3ChdWmNP&+XEe0oYA86tRt zM$?{c9vNL&-WBxNFEo+3y$7#vCdR5nKv}S$pf49CnbADwl>;Qh!we?~It310Np^;! zlbMMX;)5pR0ThG(RCtZvStJ==(IpPZrCd%d31mLVer zEv7;1LlR46NCVaqB`$j$QAGT3A$-p8?+%m>(An#U8T+gMeE3*EJU{}BU=#+Z&GzEbM1EM@8bd<2o zfFKQ4>cxnX$PiN;8aOS++olBvLAJ&8)wo0{nFBdT^2M5@4W`YJVW}q))CG-8Opav| z4h#=#c}5a za=Je1$6-O$j?S$a&92P=HhK=OdZcj$k@3WUr`V)!8%xQ!)6L{FSKQW3%)SwO;K3#F zH|2`~6x5BZ5B|z|2LzM>3#B=TbyP1BZ z+Ae;C5%vh4+y1zzL)XB$`tl*_Sp|_>8*Hv#@|nW#G21K8ZfhzL0Qz7#HC0-?yL;BJ ze+^#9Xw$#&dnRKfDP5YG+If9YwTtEVBkLIq^|w$XeY%z7QU+C_raN44s)~k{+j_Jt zX-dKFv2*-?-)hH^tTe{BHK_trRgktf{*8B{WfNaAacR6eb(q?{MtcvTs zU4Ewd2Ow(UkSl>X(a};m;R4~~0lo?!5ct3uQ7F;AIKrL`cz(MXn>9i=JFoM*);$UB z)oOv?ZfZeS3^8Dr-);5bN8?+WyB;ECB>>1NTgOFm9mnD_9}b0y+JF*-wPJ>|t5fdj zbla3D6uAoZT&s&U-HzR-f@sR9vxVE+MdgtU@FPtch*Zx&VDU)b`iz!XK?$``79Oe4 z!JyV?p+NAfBM0++!e^q?n=){#-7#zIB8)`>{8?`Wm->H63iP}ZujNhIuu*i=$n~DUblu2^jK&8nS&i&n!kV&c`rwOx=2f< zyES2V_ipW4U_3m%U;VFt+kJuP1ZX+|8bW zIR%n|)({b=LD#YxMn1Bat9DCPzu3Cf;I)Z;$FSt7(jm?k_W|xNs>}&;@nDVC{jnd| zTDElsPiW@6GK9*_UKBLtu^_l-1w6UYvtVtl_~dlI%3|~IZUL9ZMHb|MlH^H|ET#Gs zDF#5KIfqJY;+VN=%5c~*acM(^l;z3rV<95p9dFNJlR5legu3FgG*%}idOwX`-y$)g z(G`>tg1MWw-5&$NH?n`6a6>cUvcF$Iu0^YRY2e1U$*%A&M(!6WYT zZ>9}SAbTitC)vRTB%qg71p~Kv2LY~Zy&s&IbG9_ExZUi4Q;ODdnDIJp(w+(CLfzS$ zCZ_=_HsXFj*j+@F;!&*Zgl^obbAXLMkl#&VN9k5xOnudtGxPl!zBuaj(1{N@$7eNw~`=&qP4j!35D>gl%Lghp!++^TUyk z^xsqF7WXdyq@$N)@|6~b$B|_%?#I{dwP=%256U@pg!#fshQ}!I?hqMlAQ_^#Q!IHZ zIL2Nf0yG(zS-F3NVMZYU38*xq>Nq-K&35?(=QwSZR=9C9L5r8<`AA=6hi*^I=DGWn z9C)WZ*b;O|EM7w6dQ-z-zh@fN%c{v{AkMoo<%TiGH}-g(tg$+{pB0J4U<2svwG_Au z^c4JUzP0Enn3+}gK|i0cD7UyiWjq|0mCZQdNq7^f3E1yjFV_JD@XMiAW>!KF!o`Z3 zmsttSHkLk><J^BMCAQ5AGXe`Enlt&8chl)hOs4=Z^ z2}xJHc+YtzIMtZKFZKL&qHJv?46($>vbCf%Ev6%Z5KI=+Zk~zz(eSsw; z1sOgoP^vIydkOGYMMyQ%FW@463Va~^&9|zq?w$_+ZWl>@tN^bxfv`mNR^VRYHd6F7 zvA0cB)~2H6x{py5O6*lQ;)|bf>xCdjZPX`h0+mGPEoM{4x?;l`>wS1oc z@IGMsPfS8i_W!ygXN$q^YxN{xFH^&r{n#H$-PS67L9|O)p6&#f2%=F_EE4id z$=1)k!9?iu14c@q7)D0~31Q~_dVRmd3p34S%J}++(bfW-TyC2jblMM2nO<5$zmAI^Q$@QDI#` z*qm;#OrB36n3eg`g&*={G8VWw)-zD$j35+xtYAO4CY?ng4sRTr6L&-$BTih2p;UTU zV$DD_x-!6iR-$+VbVIC$>P&HzL-)BJx`|4NK zOeQ%qj43>`Y{EGAi|BJGfMY9$HXle{gt1?QHPGlO&UZd@UUBEf+AO!I{lw)gmgfkf zc4DjpHOen)c4ZL;h)I3e{^6{661dTLlkpRd%pvdTy1=jY_~4jMd`vH(a@;bXOc1&bSJ?Oba1aTMl^DprsP=w2JYM&m!T3xuy-T9a&ML&d<>->h*6o&?{x$-@n3e*O-(C$R51I5uV8j zoO?`HVDjYvZ}dd|!%WEHFxBt)i%1-3+XNE#vJHi`?(3h7P4kl!#b`}mNzjA!I>U8juYNMv?G)SlH@7G}-H{o&)^2c;LB(#QEemj1P zI&M9s(N}quPT5T!u4o@Jmo-&q0GbP2yh@baEaifNYJi9Og_@s)=7}*3VDfWN2Y#As z1$Tdd$$onZ#rAb7c&8^;04vnAJ01FZpt zXE1|L!R8g(_#$KY2!(m6`cPef8WaIWJ-KPEw4(=Q;j$8O*T|y`KZ|Nst2e5__+7NZ zj{b>P#jU!fi4zwtv#QeCrn9{u5pCI#>;RBG_XxOHt^VrR&+JL~9=6rV*=E6`g18EN00Bev9j^K7n8 zSJ})+EwcfC#awQQ6}l#uu7;DsrTjz*ro~8?e&HZ6A^yV)wlM!7g~Yl3GoAD>(WT?z z!Z<-7mjvE^ZbulMmZk8wtwt4L`N~}PFV!%=?iFu?Y5CdUG2|3E_;Nik9itwuv1}ii z%IIi>F)0K)74VHDhR79jg)yjD9FejXvdvTegbV`I3|Br=BuAO2Yc!0O>x+9lOaSEy zbwcri2FYL3&{gpZ!{V@mg-hMoi)>|kCb$hH0}_DG(#vdRz}H~|vN{6x(5D$*XtD0b zLR1HN&{+dDG#cJwt_BvWFkOl;T71ed+NvG0@!kRWwCT&u5gt{C)7q%o*wsl7)Sm4s zb_*@=^6-w-JXVCEl z$1TX7(WcJ-LYpet^?PY|2M>00l}wEX;SCrU2DFM5wUxn!crt3=Ec(ErxbbTu6tWMVMN0Pg`J2dL*u0}pnor^AcqHW2j)FLNs z0wsb4L^(pbm`4sg+Hv)WlGwpHBiJ}}R-pazqP=`g2w~#S$Y%95CA#n^+?03hCMtB6 zA?C+p(t^WfBVjh7ik_%~KUXd|mTA#Yc*O2G`f1SBS2M3u|7;2H)@oCK{?%S~?=pED z-u`OnqE=7iSCC>T=;C zLo+qAbGQP;JT*kn@nKSu^5K%~8!tDl0hNBvgG zZj@7mxh;6h7B@CS4J$i-ep^7x$R|ezm&$6b)W)V1w@#_us=dzwb1Lp>wRhzWQmjBM zyrh7mgd0=KfUk62N$t~0rr(cyR+QWLoxKdKf68B=+tPMxT#>RZIA5$>2#Yc%jZ6hz zk-%E_AhfAt_}6jDyvNfMx%eqD7>2=Xz&cEUeE5j9g+b+Jy}-N;z1MSc8<$X1sD~Hrv0cAhZmYg1 z1QIov9a0Z;Fye*p;yW|EL(U-OF+v@nQ1A-ZwjoZr9m*qw>(YV^5zZhNPLdUvhQu>m znzHtXTwA3cu<@O1liU1Si{pX}@x?5?J#yhF-Qttv6{ps=mTV?F;%mFG82HEv>y>t` zrD+Io61FYvT@r7Uu&k}Wp&WWx_xMs)owKd@Xsja%4Q)nkcl3Bz5?*JjvW^y(09_g> zuX$w`3^3!@K#5Pyz1p(5Pq~>8HdB6vgS1lU+h+0+OWcyyKO#Ic$yK$p1tbuiY zcD#ho+)Tm@*b9xk58aXPb5okNXkH0CoGBt=WTwEH_y`_2la^~Y5g`oHNJK9{DcDn4 zLQr6XM5jqJAzU)p}u;*++c@V5uLO+yH!G0N|uWxsghIU`T&&EuhH3Y@QKu1GDH$jr{a4fu3Q`^(qAkd9vlOV!6c6NyaX8 zrpU2D6&A(-UkSjPPec3Y4fBlSod1eyb#!iBe#9!+ttv7;IcB*v*9-=W3khZlyZBno z^K3*1M^v>34D~{(OF~PD!JsC-riC>*`X_d51=7#>G;5${*6w$FI_g(Z>H8n9UKUVp za%%WL`rl-bNfOw=XNu~kR-Q}`PPm;igBC_d=sydCmz?#D>vGx~@U*Knaax;M4y^&z zn0EW`26MgbJtRp|5c%er#!aL7yge) zKw^JS3jOqrM180qXqZWS6IEuYqv__#Ie&4?>yPQ@RG}lElR_RNEXU1Is;Y$km}-# zAg!|vaVmQ9*H0>52Y_Z&RS%l-hXxkz)l*K@rL{wA8J>594ZCui&cwttdx|H0yJXl# zF!D!t{^7BARb9Vlxym4k<3hvXtH)ppVbUf)niwm0m3>$~QT}96zoz%=p&DUaNwP>4 z0cE8teWtBGF}J*crbex#Jp;NRxJK1_C$x~5YOqSTWpD2tFz zpZJ|!wHd8w{Nr3Y>Qa}bS|eTl6Q0qaEW5J6T&UAQn`FF*xmeP(a8K1LycE;}MZT8B z5~zCeTF9lMbZ$#}iur}Yh=tty>`fcm_MtBs=l}!oUIcX{vzX}6l97MRwv(+{l_Sj0m=E=86GDI7TfNwi zT^-qj*@ynLzvMbLeB8Cs-B#hnEOCuQ?nevZ^zi2Ow@E%uq|HJlHHuzl1ziZZ)ij8{YM_};H~(9=MnMXk zw2_saa#!E&j%)bBwWkuVJl4*%28h@CV*l-7IsI=x5H^*&A5nRW3B$o3Wx#FqgatDbKU<}+(Y+SpGK0*-;4+dOg#^P zc{ZwQS;Fnt1QA>pPCcG^jxIy8n#%G8I;y=`v(W;|P2F!7X6T}0zvysO7S9}Kq*$Ng zN(*OlCToiw6do8pP47ksm^ziFoFA8ylh-2_&B^O75UR4|;h9{O%FB~jB99o-FLdYc z5ksuvNg8}D(t*GyLw{7Mw1S~uehSF-3hO=??1wi2hEDJRMyaZ3RM~LvY8hXPA74xQ z2*Z0+7Pzt=A>`@{lq_jtG8U^$|d}4$s@SO^moLZJjqJ6KqXG>gV{78 zKh&UfIG+vNr86H^*}x)YwLPELz(I#RiB6bp-*`Wq#*LN-)3*uiI~*8|kk_E%aEuIe z9HOiS1?4#WACNAxv?}zO#eH;vK|r-o<&yM5lwKE>vl<6_v?zfgmm7~PaKBHoEv{Ur zx6+tWk8JZ_v|9}yB?E}Ml-`ayQ zV~VjFTM9w?vD`P8WFjlGl2bU+*bR#MsgAY~)!;%-^w3DRI?yAgh0V?pGD~(f&o{ATl^)5sn9$ECu0cCY*Nalva?OL~ zGNZP)8?ppy&>o-JN>EI3m>jLnBpxd!y0pVvJU2Q~r%>2(8Z z5%9l*Eb~rWDoJ2amaF%+Z!#$IoyEo%XWQ!vW z2{&5r4+$SnkvM8x$VvjpCX+Td&$RrLl2|;z;L1VE^?uUu`>Nz4{TzgE6qhzX!e_6HnAi&ObXzc2|g*y3MhcwyS9 z2=1?nvx6xwM?BA78k z$mv6%Dp5&hhxy`Un7BC+KS0u?XXekJz;y{L^2=eB`tfV8)=#JX+qQAX?#O>=v0*tj zU7Ws8t!Ve$_wR&0*67FYnXlqMEh#_0IMoB+Sb5RU<pA5S#6i{^4`8cUNn(r(3&c_xNtc=6x1>`_^Tp z;d`dH`2hbDudDBoY*Lx%@EZA)c*-gP zj{{jR{vMrg-5ev1Vz|s&l;UuwO+VY-c~Zf2UgtU1$D`xXckVIz9{{l-XR808rT$|~ zo{i(b25(PmY1?g$V0y3C61+D>x|2KQ<|7sgEOba9G`SEHz&qek(3&9bL{1$`wfK6^ z>PXPFH|mTl`S*mS;?7LD@t%H&v3$hMU*V&(==pYay?$3GU?z%4OgBzuMllN0w5I1L zFyuE*n!Jq4%%Vp*u>S4bm_ZMiZgFXT^W!cw^{u?A)NS6r8aTXFb?V$^|FV;2f0&)r z@A0Mn?dTl0nAzfD(YCLuaM##hZGbFH;=>ts6taow_nGTl5{W{THsL<9?AdcwJFuHE z?Y!RDyfZDCXnXqlxc8mp;@;a0 zImnStUzFFld#W~dP~elNJsRTjTD3lci&A;{RbehguF!&zw5Ib1nk+2A1EHwhr4fVq zqbXKdCA!lq+>$AjYc8se=hg*bDakD4C?o_?Az^}Kza1)&&30~hm!6(am%&SdIfbzj zf|X`*BLQc}zPso3P(Fk9{*WG%6lv#fFSLd+d*!B4^<{Iob5AVr_`RGXUJPc6eT%CL zmJEI9>#xKBc?7rtzs2KBvzZ+1esM%_aj;KWW+@5kXSmT=Q&c3|RDy zAnen7Fhou9(?hA){Y2p#Ghe2dDgKF1l>8?yvIgTl(y4VxR8VHIwe! zHu|&Z5vTn?`_o+S42vY_rfs_zES(kQH>ZR&!3d4A^H-NfsQ5Y)?N7@aOmhzx(t zV`3?tjzlVFO5nEx99^~BLhFK89bCD?@CVvom=p{L|J_oqmPcz8IEGn37JvRBaX9{z zCZt1TQ<4=;AkCOGB!NZ0Iw?r9Ck)O16Z)W?8Lx#Z ztbh~6U5wT$?xRM_d7u$FS_Vp-gn4d4A;O-%3XLuDK!8q3gt#71hi1iBf)qdsrVsf0 zRc|N>c|Z(S{9H7 z%a*QGkpr^W&lQ2ZBD&#-Fz!ul>&G(F7SV89CY<+IEx2DMlr1E{AKZ{1XP^_%=4*u1 z?yV`e$^$OC*62;BzHsz^PQ_-!miUA~7gyJbzlIJ(SAd zaB~Xw9-LEai%WvJC2%_KL26in;j=lyxE6GG;ilfBb#NWq=XD@B8F8V3+?Ru;>%%*% zE8$ynDCt~Vmt~Pf+oBJ4mbGJR;r8`Gr$$JEw7H%AKPq6fw7~9YTmj1>?b|EZM8A$n zTzex5;J!}e0X=HVD$Y3(6WW|{fXxSu+1_oi)x7Rdc5K|i(ONPZ*O{8T7>_7v z2F}?Sq0NGr`D}<|2oD>MY8ir)8e3JnBQw1@jzmr7+67XAjK1U*J5<~C&;{Xj@7c(z z>WG4X$NFpVT8#~Z=@}u@h^u%q1mMZ$E*Mnkc!O13U6p6!rJ!b^d99RV<~r0}ki`g| z@k(LEaEl(8S-~p^e>xrCg+O?T9h{XFN!a+tu!T7h!@3D88ZaO>8_J3K^~Oh(D`by{-EuB z`CEq20q-hdT`7u^M~2U8!%03U>Qi1(3~^H*X8^5_-%h(-SWkW|nxDd(v$c(XENJY?N7*Cx8ITa#m4Tv3Snp`?`7Q@#+#iFyeZV zBw=RGuohMjD!%&4nIr*%5Nba|y-+@YH}ogjMvQt=WlN`bri;tgnd*?wdYwXDv~Gd^ z``F0?r@I7=)9%ZK4;cdlU#^SQ$MDBPjPIgk0ZwU21v>I0jw`H#og8&^_BHI>V$7|) ziU!ga&RK!n*}#kYPSkl$&P5Ge{7((DGiFr;Q~~9x4TQ%c_?AOYv}%+L%Nz(RAoq5) zn0<{}zH9?@@AlHBOWUU2^~5`06Kgr&U4A?)%>q7hqL={UR3|{ifmDyKu=nmTq=FBG zPWZht4lt(RQ~J5cj-qKC`L>X5&Qm4Ze#gz6bru>;LMqm?O@cLcnWRY$04rk!-Qx~0 zCg%%Xc|SCZl+8JdN01d!Yqp!Bx``ELw-twIjSU&9V+N|SvUzO&(-X>CFpz}TBub56 z05y+hoZ&xj5m}*sx*bGe5rDyo3sVR^izslJ*WS0}OWVo7LBU1s#CJCh>$Yf_3xdy~ z1?4xBcP&EiTWul{mWuc5p~$)%pu0EN_4EhyI~l%!MdG3UWi&b>XmJQmCo&c zTN2S2*#I!=&a^Dchr;INfxQ0tuv=K=e-f>K7&YRw(LwfHyi29$Sa9=VzHyv8ddSSH z4F#-66*w+7QpTPt%=rXITiM+L5O~2}ZM3}kvUqfDgBjoU`zI*= z*8vRGt8<#grw`SL4NNT@pmbFo}0Qvp3fZ-Ea-ysA&9ew`mTG)B+E*(F_4*K)yk zX-tf^=@$|fx*d)rj)}TF&Sx{m3cbB%LOUqW`U_+tyc5?&uukSI_zF-mSmV$uP&%Wn z2z>1ObWK%p%igP0ctI?iEVWBLoO0yaF&X#_e}~Bo%?U}!r+A8`a1_4EzngXzo_=a=IC^E>M|W4@JP)*y(M`ez@Vi zAZO#vc*Q#)nPVbbX1T#_N`bxuJow{5vww?6&Jr@wop7Yn)JCn(eNTCIBQA+ssIuMX zs=3X0=t96i`PaG;7M+s|SNs9XxRDu=>8J?+byi-nZi40VJFQ3LK1gOIV*q@EnohGD zvZ)EL3LDqkNJ^=i?wbMV5f<_0{wlr3k{WL`hTQzfz+F_`J&qS*QbCrjuCpvQE?9cE zR!r!oy^3tgG8=*GwkAnpEJ@U3UYiH{sEw9qLxJYCDBpx?s}sY>17;CqlL=q0$9S@B z1*~kV+2}99YNQUE{_|X-M8EM}-HX1FXet(%f&mkR`~fwL1t|{KcBEg(_V0(p9|kNWe+yM zL$Xk;Gc=E2?d-e#+fG>D#rF8zJE=#yBLkt}yENf&=5mqaFJ8x5?{iUt5fw`GDrXnBrMT!`m+> z%XUrf(YHPn6!AjnrFD+l_M#-u{C_EY+TS=UTla#nw9T)>;(2b~oa7v4Akg97rKt}Z z>>4(lj4%e73~R%Ls^giuNuv}jGD&-tq)I_en(IY0*Q?fUQb}7QS2;BScEWpZ3T=FR%rPQxmOzylfLP(oy3FW^mnkF2QkdYLlH)Ps5Qgs^e-deHb53nuy`T5JEH~h^ z$7@t;eaZ4sMT3&)D(e%laOyMkc2VrR!fF=h1zB(-v+P(?oq?EpA+ZEQGz;l~as-PU zX5T6HL8gGmcxb$zP`!JtUG30F6Am4WT6XHbiMQ{)R*WQ4f}(n%7*VT>@9)OklUIfg z@_idMdV8&@{1WTh^l%$Fq==ec7Z*HAM$DI?7Td4QAFtWh#@9f-F=;uf+1;eAyJJ>t zDwl8WOn@cI;EDw}%DDO(6ayC{o%AMuxF%*drsAKozJgS+MZm^Q34$?X(;OAFkVz93 z=LV&atDoB~%dBApBdnw+tuq^Y1jj0zD7<3c`C)Sg(+%Gr1KeT(nkv9e_^wWVwO-my2*ODzj2tHqImM$C4Kmmee@OfFvZgO>3ec%ne7HF;EOq&VHE*!b0CN zb!bSIWkLmGN~+}5xi8-$xhcgc&JONAUNH3y{3`d;g#^OC37Xwk-BUYJdAd+-xiN|3U=+D*h_@J-3pqYRu-a#o79 z;nIRtMqw%fI7PAMf`Ug%N4XlJv|_8=Ag(TSWxg#A0k}xoDhlIb*`xO~^60j| z%~Gu%<13Be0K7|sK8&vyM8)98=H95Ln5|rss2MH{Hq9R7&Dz(Zd;2>h@&}vMBp;;r zf$|gzt)+mki2+waYnl0uE;Mk&e^pu8WP-~iCH>P`E7yUmy0Vl85w&X5G1sIxW0G0- z7sp9S)2>C0H?c8i7uOvcHfP$-9_gIdK$@3a6VnJeI z`U~f7+q?ra7X+brEae4gVauM+i`caWQGx+sx6_3-0HrtdoyvA0@zeuE9gGS)Hdu{$ zi|Mk=jhJH{#Gg=V9PAT1>WpfJb6{EdPpPj_s8QR1qD!cOdCN)IYDlWJ$`gQbReeLBDhCDlxSYKlnAy7pb#$jDoY``Y6m~Ap`%7x%ioK%0g6`?pZS0$tOVM*h-%ec76qA?q zTe)$}nlnhSQ7IvW2RY|Vj6u>y0yZ&4vtGh zVUoM4 za{ga>>;Kj2$HDUdxB4-#{MQW5Z7tbYY<8sXOZB_9zxiYD2JwD~1mk_3fJl8|-fOyp zp_<|nQO)9=#+VY{Up12Ozn6ozf~K+rVP()%l$vl$#0pTn z{;I%mt;#gd;#0M8B{ZknE7sN;r z25BUr1#mJHC{CgWR?@@XG}h(WG@%PPlvSflrsU=QYc9mJY4*AT$_yy#L^R_x!qs)4 zl`%jW4JVI%XO?96^>A5pG5R^nF8Tf1D#?o92+z!t6U;=A!4zyX+h7dKN&6*&Om10!!xjdRh%_7zxe{ zI3Z5vA~JEEcVHeFZCk;-k^PR67^s(R?TQ-Q?~Urc9!GuE4d1S(r#%}rdcGfSW!=6G zLo;|;=(Lg6bD{bjtP`@7>p3fIurp{~kGwsk`PYG%UHepzc?wmBf4|9JWaIvZR z)){mMpV;;Je7x9ct+VYJBYGH3AqOuC4GU+GLgqz6rlW%NYwXyzN4tZjjZ1FIQ*Aw3 zE`_hFZ;fs8GJUr4E_>jOZMi+lpzm70VlF3c05t$^ZTrev=z(L7D>t7%R;ej|Po&!o zGs#}L%f1hHpw?RZi;$sB*#*A2Fnz>4TH(FH`t164{P1~hFC4HvD_y3?uj$qP!Q;xd zT9kObqT*ZuGwJE*8Aj>1C_%ohI$_qkVY!OS3TdT%zD9fD6&cmSX4Syf5MvhCz>C6G z0}rMwg*f3gw_U~e)!p@3`+T81$sgv$CO|_a^XJ8=Y;&4V%UYrpcTWaq%hSby*!3R9 z69h8ezgAP7nJ=0`4pEP~<3ir_Z1WD)c5T}(ZMlsD``)VmXD$$M?b;?znc{|iC*#%y zXq&uUg*Sk4O}BSoGYa)vu)^{Veb;#>iKDoPC$7PpOk8vtbPeQg-E8BwT5NY+l_f~Z zhGAU(3qBJq04G}O)7(V1U7GasM=+Px@ta533O9f1Qvn2V*aX&Y=3_>HsOSfrHa-qJ ztB*9;iVJ3CY6cf*iUi*OY%z|~oZ>{g8E23rDWYc%$RZSk)pQ(^7v{oQIEs@B^`ADh z!b(l!AumLUe4O`<}|MBs@0}-@=&zbhT6N*Tl;#gd7R9MI>CVMz2Swdb_rVRil z46hI!2(jOPe$F*KT%8qK0EaDn`KL$6j<3p&NZcnzf{Q-q)(?VW9lDp2g@mSG1 z<5od@KnVh1XqLsOo=IM#TBLU4_Xi_Jn1hSC{HIV&MT)DKgBy*+Pdo;;j-PBw>?PwX zWZ#|@_pJwNU~ECHun|`cFJW}cu!Ov#C;WtlG6+Xw;8Y zCab%TUkr;&dah|Z__ZGcR~oh0ATT!OHi*#qRg%+?6VQX?qMxns^0OD4=t0AgyWTy# zV~1ux) zMEIcm^Y~FeBR6z185@OPn-z&LktRQN;W#d8&b<6l6w7n@`A2<4rqoz{v-}_w)0UN&yvG4NSUqk237nb=I z@b2rXQg3bkupi{9iUhy_sTj-ls0@JP0M0dzI9gfodq0y%N$>wDIG7m!yWsc_)SHpz z|C_?NtSRF}+=}>5P)re)6Isb%#MrfUg^~QL@fgEvtxUfJP$_giMILDuTs`-`0@E{L z!7$(_s>eDJK^kJ6-K=ic2JA0?MymaG>^-0UYtZ$4iB3eaKW-_xcql1c!1`>>RAy0!qPp*X@}WtfkS&bJ5ReweBvn3#W1Ra7B(Z29Kk6W_xnhOf7p zUFmM6*5QIye1-L>WAmajs&#m210pH-``iJTDvvnNe624>0z-g-0w1;t426_@1T_Wc zApXYm50t~gruO_+VRc~ZSpa}^MH1PrxcV;ay41YmdiYq7B(B#%SL}NyR zyG0h~QZ%=;hk^`rPjNvi%Vh^eKAJCzYivf+kF|*ijmc;(D&z@JLvqq1fOrxF_h_t^ z200fmO{A&-79-R{x*g+$+vfN3Nz}2VWV?GSitWADTMgRp_Lb`;v-CrhVGPho`6TgJ zYO0IBmy}!W%BN{L>dHnD{-u$olUo}f8i9$zq{p8c-AL))=$+#(|3@O1xtf@&L_K+- zejG{~0lRp!5g;;v08hZAdklkgw0Kf(CCRuqPz!PW%Y2%$<`EQj4T$4q)WUCli;kHKh(iE2VeN>4fApJ|}XUhSG2f4Jefy!I5+g0SD9aY#6xmu-=*e zxl*tIzN(IlRDoQR=28&3U47m_Id>);Zln+ln^hPujuZFV)5$YYDySFBL>VW`F)s2y zYY0d&0MK`bX5hMpXstE)92{DPSe+N~#fnFHt^d~u7a_XvPJoyw4HmIV>fqAGLm|FY zx9C$PbXq4ybI$Sd#y%&1=HB&!6NR#GFo?O-#=~C`Upr$EC%Vvnm!B@8ZoHyj`l$xS z9*AAkD$Q>#2Y9Yi2>{Om1}mvZfW8k~2BanpiG>`{BAC7cR!THLyYxm2CX!d#ICdka zN|M5kD!=bSumDKFnus4^NYxkIv1_c-Nw0>goa(D<@C=4 zk@hzK)BNe&+TOd1_hO;1<@a;i>UN&rnRx5YIr;FskS0Zrt}YB&|CYSb-w>c7h_z^yOle7naN&hsdxHjh-nqbro zNnIc5f{hJ|5K~@xQ5t5nU53YJtyuaoshBzZ@nWD9%t+X#&4Bc1yJVFvav<+8C;n*@ z(@VSL9!D>oPew+W+TvI>0Bnjyp9F-E;Ms+X$Y`Y*7Os5|;-c}RJ@YR5>AQcUNvWx* za&B&Nr;a7VRm!0%{_I+1OD>^99G+MxWwK>E}?-EfnZgD1S(wi@>cu*P(Fh0Cp76WMKX%c{B9)TUfB?QYb6mSWo zHudaP%uWP_vwAHSRtQ2T0E#CjG45LuQE;q2X9xx&f0RvjKWXsU6-!W1m^E2kR%sb| zniF@C+-N_LJGQ(bt^eAPq@0iIO_qq&c>yq(d5gGdD)>r0QAn*a=wHR2P&ZT|jtme3 zHY`aoT3P#RH+k!3|BfOV)|(O_q_05KwIqLVs2`!E3?Y&mXa6tapF+bBD*pX+B^G`g zK=&2^ZY==a`)*|ZnXp!@c-*slmdLQr>mMH?sO#n!&9M_|BoCzdpo==FFs<|?t9omC6!l?^-dyDMo$DSt-w_WTi3wiu{HZK-P^EK4{+W7u%d#M#_TdX#m;vIZ%`yA1^-}okWfRQa_mTd zy$A)nlI3lDf(gKit4QDQ4hc4JH!M-~(~u3LF9bv>Wboh76B30a&YvRu#_6-HFXfRi zEi6gnj0WwCJc#onBFhN@0*%8e_tmx1NebtbsNg`O=}~_!*DayQq*84sjjTE)-8Kzf zjyFReyS9#`wDu|b1@=7oT{65P9JOO2RZz5x>OhRjAxGFn#Lx!| z`Qjj)hae>|=EDQr6dB^B$R-Qj@a-8x>}rvs*`+_5le7a_DQs#*9$wB~`Ey^)W5^&6 zKkj|wFl*w$`Y;s}Jz2ol_g137L99DT8oVg+D1 zK#&O93@gGUxa9q@LX$r4~dH#GQ4SUO?ty2I%1GC!9yA= z9>PRO<01I(j|6hhkW^3Q0Mb4)GK^thaA^*cVr?CNfSDrsx>-YpW67vTU3W8&aU8@q7Vpsx+(LNfajLo<3&2IC2dE?qVXJLR zuiYa#0w19h0hk;Nr!sUggH(V4HTAhen1easfWn45aS^iQ^>^)x$_y%7`a)PD2%O9) zub){Cn!aPZs1O?paDs3yht16Y-NW#raG_>rpTQ*6Bi5mhP1qHpuk-J($O*7g1Uu7H z4T^S3K-2n6wP1NAO*qM2$@K1|nNayQK{2lM2sa4y@>^}$5qo&v1edw+Ri&4mC| zRm_F}rn;+6NyFTpi-3$N+GJ>XUm~OLugh2vHV^1Kuaj{RTH(@PD-K{>%OtC5YM1n+ zvC9ck46(@?09&F6(deIUs&+e!9f)`K*#w*r@a@zBHf>D-ks>T5{|r-Fu<&^N(%m7s zWfTzM)Ec(;2S0zQ(t6>!zL`Y2aa61_Fj6?qt(cTZpEVsW8dFn&iCHzr0G8dd`7VAp#SU2!|OEGCD?9~>m+ zpyswqDDt&y?n5uJ#S7%wtkm*>81YzpD}>_>Sz0N@j^)E}@F6DrdcJrIWXC?^2U&G; z+extiktyr{Zsd#XQuNtb;MKwuK5=6FmHX?%c?|Oqg!Iar0|hr~H`Lbsn!~d3Hz9nf zS8R!Z7{v5chIf+f-7?Yc^Yd~B6L+g1Pa!z!$?Zr8z9d>ddJ(;Fxgz+HWAS|U-I!nH zW0U}A#RmIof6r!N9_W3*YvAp2E9d_DbaimQ+|G}6Zi{Rqx=3aFJkqt+ntQH=sK02IZnw+x^vdud7LH@=AJMU?lj7(|X^!Tlc8v&F(?YSc=l8 zofB3Kx4>zc5XG>ny~o>wHII?U57;MJA`G~AVVWOdt{Ye8DrRKGuikd^_5H+DCq?yO zVzT;lcxcyRDI-I&PK#nxHq&nscV|cRpq72w(PiG@*@IcgO>`azwhVcRugrB z>7QT^CpB-ZPK^l+qj1B8Y>Dt*X~=NZ&m%?ib4l_W4Ve@EyYJVym2TB;06A26RQrK$ zraXL7iZ^5yWvW;5f*EXvG}MER{9)V1@Jj*DT$lnlEtYAOxvq+pos`AYAP2Und1K^? zpU7yWHM=K&DmFFpVap6Z!OQm#WA~qfgX?i~CDbGl--r6KS~(aNB2x}hkco<*K3-z} zBY^?^q3?$NDp{N-A-Y*-A&Mb$`S(oduzH`=JqQwdH~6vWKPh$6vkza1L_u>sm4e94EogzfP76VW$$8?Gz=$#;t$cHZ|(AJIRi6>cZI!sd4Eh zD&?OOre9l`U5sldZ9oShu0H-cGhk`8=EEs754`Uvm%suLSY#S!Xn|C{=7U1)aT2^{ zsZIU?yzX@ue8PiO-%|HvO>cu8E3bY?X8bHUubiJSecm>AQc{|Dy^)71h$RCmzY$k z0en66OB_bJO7G^-?CQMt9u`s-)y{AyL}m)}MW5{E3^3NV4)|9Ca0-WeDvMiM8UT%q z?B*APv*Qk6D0;hk8sGs208mdW9B^uDE6e%U5gcMO zvr|12iwoc=CP4M%1s_u;<{F?Pwq)gmzxEeWVAu>4g!7)B(bL_X9%HkUk-bA5N`4WL zyDC5x0M$v&3Ej+%yvxmb+imG%#TV31HYg;rv6v|-R_sR zj80Xye+^8{imRW4@fX#USmrS9lrZk~^)#-3O`YE|x#_i`?Z>n4gNM#-z z>AzCrUukbaLAh~Bg~)veL80xr%^~lj@Kte@_5aRvc3^sQ`Y1R2OQddU>Yv_BfuL__ zYjF+mN&XSGwsm0ld4v_wgDi5B$TH8hAK*lmT4!1Ji+r%$0OLivIX}>hPO3`P)nJOEvL(nfJRJNwRfy z^;2B>vAOpvW@l|@bNXx-6*ukz>}ws+bvR1P{-viR^VqAVHZ(tT^?OkiFoNGnaHVhY zy34BBDXH$2kx8KeEK~i1m)3iH;YX8^-5k`OSXlY2rv~kxlOA#Yd&b)`x%6`QVgLPi z+^>9!FZI+SEs?ztc0rx;C1tSf%?Z`@HWvOe=CxG@-g#&7-a-t+7JFT>lPg@d?$u>`c0o8P-P zsq3?o2ly~}FQfa!C%G>^+ThXrROpX>%vV7GbA$KzaQHY|KY)B^oxcIp_<&viwimBIO21*% zt?iS${Xb?F(%ahFyt=r*9V@)77kqDew-ioJa!yKX#U5fxI|!K@@h@Sw1MYZFUWZ>y zM_w5gOHaH~w0zq+2>FU-Rz0A0ZCj9~FfPQkH{nX#P&CNhA6ZRHLLtp$6sdmRwG1Ts742w7l&mBodp5;1tgTguaPBnDJ>F|WjK{B|AyG% z-n~gm=4F(DT8e%)M%}HRr+bpe*csxm!aGg%xAE-b@@=?^rSgqV5|bE(+$R@pm7+k$ zyDXT1icFm|EOYZYq!6zD{Sd_8?s?@7J@E3xw$G&BHO%YY;gqAxB1cbMcx#MM{5Dv4 zzg;buajzuY4!u2V#mFU3faPi%bR!F(wyTne$x0)1UZ7Sd3h$+AXah4@VEubCcdc{3 z+|Nv&k~`HT8*yLy0fK0z+sNsg23_+fH$SK0n^i3$F*0B=H^Nxl4T?SsXAu1ht!dIF zb^6eKXt5~vQuR-2QK40?Z6CY&7JXv}KK*Pe)V99cAnRZDuy*j|!^cvBg(-;Yr+B85 z7GagZ8^@LnMYt)9+2JpfLtP#bT+f=@k3o%)BbNqKg5)RCov$l&0i}td}-L7d0Fwozm2L71z+nG5>#->oEIaa3U&AL7|8@Kgh?}FSDPusb3 zNA!uAdT*?Vg@MQXw$Zq)k!$(T%Vd;MBtx04#3C#kkvPGdmIR?bQ!oc_z1v9HZ0}3y z9qSPMyT}INXl*%m67)HxF%!js$t>K*Kp+y-bx;lUzQtN0ye?)XuYK1m`)qq8BnYC6 zPPwW4ir^tTAN>$&X4q2q_(mg9_jzq@&HHKrHP;K&Hu-77g?F~V4m?!-w#~v4dK6A@ zQBrm#6As+V-F=!%wLLFIF7wctMkh5LmmabOMVm zTu7Qx3s8Yp(ly_#*+Uwr>BEopTjeYYc4khMV;$ktgO;yTNvH|MFiISrLQS9JviMo< zu<%VQnr$3cb~tIWExoJfO*-0hS&THPsHdiJc6%3#prv7AiOY_`e$2Gdz3D9?Zt3u43lo*ngUITu`@93s7iDOp8y=|zR0B?xkgZ| zLYNcodDSkdP1@d)wOQ)ufE{hHn>^b+Rc2mL%Dlh1Wzw$TjRG+JBl)5kL(n=@Fz~)A zRr9X_1w3?Jrz@&^bDWjkUgs#7Ah^?yUQZDcQCh78y7y`2_z^(>9Zya%Xsgt>dK7eC z10@iEHV}!yOn2|!-X*Rk->1ki!8;WNiZZ5qd`E_o90UzLu|S``i01*-7jl-za2pyk zf$+agGE1u^Ibrr19p6JD9y^qE_2U#NNt>o18`#jxc>L>|;xPw6n;qNixLRq%9L##a zs>$#*hq)A<@le>sGXMbuc%&OG!x@j`c0Y$MU(Kz?S~xWMiEj+zPa>;M&QpyW`C3cq zO##Z&9VvkCBOd}z0rv}@aVL#=Rr3$>uDWy&3sgIuy9uPX?q-5CiYAHj`?KZ&9_1N* z6E#VvqmK=!Uf?$hCr{)bb)Vf^X3>l~N5b@T6T3bTJa^#y*s|>AE4=S4wKlg0@je|i z0@+by`QPNI&ZLM|0hin3Nd=FKsIT_05ga@QRGav*7BS1YtO>mi0tf>C3-TD!&SXtp-N2?251${>dtV%emhz*8IYciv}4m&&PMZPD>p%b{XW zG!zRpb)oCkx@6S(7_R$bwib*kExcbXY6CpzlR4w!7$Fv~>BSn6G1qoP#bZd_4Wd-r zU_h^aJfTLd5fRRg*k&mVRAe)XX7h|6GB)0HLbH*jJgI=IA@u`y)S*WYm%QLaKy~ZX zY7gp0NFI@gU!q$Nsapi~Q;1wrX1WWOgT=#xF>mFm<4 zsuP~0hA$17iiULMBeVwXUI_(Syq2Lu&b9vg+=9Q19{^7;0`KW*uDg9ZsQDEZ$kzPT zy4Q|k`mWl6-u>k>ydSx*_vAIA#T4s4RF-x6g5Y1dG`i29M&1r6mwIFDWvmqnS07~WMsx0rWM;2JMNTHweyw!Y|^5&h6Y^I4)O+4HnT_wrkjW}8kZH7c_~*nEE$ zZFXb#LwF~D0WP?#A`K(rsATTpSv)co@W?In`zqN?uU#y-4y|y4E>I&kmM`XLQlkj) z+-IvOGd~e&1ngF8jCcr<6pxUoh2gvBWPct}DbSs8hvRdza(I+h1(sDZFh%Vp*V_h= z3XBl#yRzE-E$l&g6WfB$`}>j$T}rxA&i67Jy0=)IuJG`A%(<31c+oB|_;NydI&DeN ze7|U6qVKm>w1-#vU6tAhC$?W66O>A*O<6Zq*s}BiZTV-vTk=VqjHGGx@C)oib(@N92tX|*z_A6vLJbP!d zqidL4t4#eZu?U-E_7$3tG@%?mAy@000V~CzUd<5N$)s@c8q_^Iu^#QC4)bV|sM#5Y z&8Pwb6QT@9Z*j1W^Oe~@aWTA6mGB6MMz1kvh}EN=1s>tOdVI<&)Y*KUeo7(UCv=9*)4dc5xxE4d1*-*et=ROBLSw^O6)5wv2mU2= zikXil6s8{YWe7K6NfiVhjm@{>OT=^N!ss7(i@~>uaY{MA_nXY*sh4v_Lcq3nB#wv5 z?cmUxoDYI$bWEa2ObmWH7a3xIq*@ZWR|Z#EB%lyP$wOwhkHjfJq`FkD`-*%(=9KZ~ z%&kiYjoyr&Ms4}v-(g@-L=o`+7DP<+0g-_vH7wy`8)j##6ZVu1_yq5Dvf0&obZT6@ zswHanO$=9C<82Jhoa$L!yu>b^o6Sj4hY*zLm-{XSXmEk=NMv%ed;j6PnYB|BB*BZ& zcf{?a``{%`Gr7f+oFMdot)y|%y^pBPvg`eJjGcQzub%a5S{-RW;iKO*peObV+%-dT zr#so^zl^rBB--p|#sHs0&0G8#;U~E7%Fu?$NDzX{pk5DJj?d;4O z_j(g7-_UyKC7^HMmkU>J??dFOtFisg+|b_W9tD7;UK***A$_NncU6Fpew+B$RK;^? z3brs&5Vxq`7>Wuu>FU~cPT}^_(hs?L7skDLDxr&XoEh^Id9~Oe%p|0YD#{#~Jlk3o zZb7?+;K_aS4dkEYTatZ~^9%Wal8M5+)yQgiHI0afo zMnD07lWGJ3ykDBJ88*Q1zJUQOZxy4zZ~l^HgrLJgI~BA1-Z<0N@bRatxB_ z8QqcrtiRqP-s9$_3JaPwg)8;pagCxnHB|w`99~h7L*~|M~a}D@@4MrnOI7v~A2BJ#w?>;a=z6qm4>-L^x z7JLLn5pl2sWz%%Yg%&D^rKMJ$^7@i+4BbHkm?_oKbFX;Kj&dP}@#n<9F)fblLGBY0 zJqI+V+=g*h7NQcA2TruztE*CuERCn4UJ&aN(bk&4XqOzc#9(O5M#a~GlYszAd%Owz z6-0q4TL!1p>*>iAuf_03LpyG`IDJx+0@!j0#dsq_4;O=wG%Jge2`g%!S7aJ& zFA^;5@rEmI>c+f0>?N%%zTTaqMWZVoSncxFiP18oBXQ>}_RIA|W^XO{DWCM#UU8zf z&w1AheKBd4#^mQ`?PCvB>lz-dTwa(bU$yg%z>J5b?+_Ztf&wXRQDS}Vw9dtzaCGXg zB~rY3&}jCNFXyY|)}2NDkE_Rufzzh>r@{#kY}x4pqlKxCbKx<}vZIjwj{E>sL|BOm zf0;`i>TR8KBpCzV{FA|K>7QF1w?Gziu~dRT^TrUCgNY{OWgY_3P&JNMtx^PsVvvr) ztF{SG^?5jtsi8M=`gM+`i858^`RJyy+JRwp4QvTS_X40AAT#_5YW-R9JoNwZ#3X&h8> zDu8$1D`y?7LE|OewHY@JBJ}J*R4O@|n%_nG3$giG3ikEAH>wIJEqjtC(ybn$<|>d} ze60eCfQs$<-;s?}*+ubet;-i;m@5=t88M_jvr+A%Ft z0-f}%D$WKbnu0FXo`_dflW21WLvCCJjg^vw@e?Nm2Iq=>bjpUeyMJH$PY=914vr_8 ztq27}&&s#gZqRiLxC@3)kscltRe2n+MLFbh<{o?}Tlh2$pS9Z}>QYH#%N<>!GNhTK zDzpyV`q94gN!@K$e>hB(iTM|&tZYJbz$kibFXmjIgU^jG0A-t-rzKrvT1?nNJ1`HG z2n_ZHlsIgKC4+Pt$5SsscV5}>=aBI%ay^Nm{3{kWx2U~o%zZTln_oIiAlm@k*1wN1 z06dmWrUKuXjR)!1NCl9AahJ z#-4A{NUj726zJbS)5vDdM)N-2+;B4goLr)vsh}S|={@Qe7h5Wbo|%gdkln77_O(&+13TWzSehSOf3tWNrKn!yw3mYogK4a!aPC>H9~vZ* z%(H)^nBPg!bW@9@Utx(0j_K7V|mea>)Ul7r$MC#%;&s|+;!6YTDcil1M3Ur34KqlFZrLzAKFN>6yjVR*5kmNEd z;@jRx6F7*{KbK0`cmDVl&KsLnaiTB*RmDxVX&O}Gr%Q-4fYx1q^8ptwKojre;kA*Z z2WtNnP{sm;2np3@CJJe~wPo2NKK=0h=awAt^qfn&N$}9c$a9WC$cl_DZi(v1th|j35n@qhh$}^| zNdA=|Apm9@4F|lf^wERo;;itp>X`j&1Qe_q@MmnTfa{}nwX--tn0is21a2;`pqMLk zp9_gmTd9_(wor(gmo0m^qh##QRBj;ym_9Xsb10D}zoPtOt2bvQTydI^0_g*|L8w$Z zNn_79)Gnto^;ck|E84qG8Lu zJ`2;^g0Q4UE0j+|^j%`x3WGfjax6%2_eXLeZEJYiyqK|}Q{dYY_(y~*DH>_m( zVAfs(@>r-IZ#l+CvG`?1FYJ9h*dQ?x!@c zvrQ0gM`r{*etx2F0ZMS2<*y^|Xmtr5Fb+0^t3p2Hh0j8G`So2cUER%6sK5)~Cb=3C zY0ABzn}GCFa^@oveG^z8HBp17R1WNVHTSkx^90aPeBN_Egf4Ka+bEaX* zOzc-zL6ZVV1w5X_+o($EGwYHkIfb~d@1ppv@{JLVK!TC9aZ$y+JPG%nwVNI1$_2%$h2`O8bTNu_yrg;> z#^Xo-<1Yo#%iE+-pN6eWAPY+7D{Ax#=Ml%%%=RB-&BE31cSsLP(%Td%Zz#Jzos=5$ zYzk0M<5iQfTy;Z5xuCWlOS3kk;ViKoh_mg_8;)7u2KdO1vJ?A=&RtN*MVjKwu5IjG zqIaqN%Nz5%zU~i^LE6i(-OTFmt)Xg?c}8wh4f`Dti!bgRtQ?IfzQc8co}1AFMk8I~ z$ZA%Vq)V_5h?rH!hn}zOL~{xI2p(^Oz!(t{DkS#5g#{pMl=4`Su;0eKF?1{g_nzSE z(qqO-J#vg8(*Ym2-9r;G)CvCLIh|J1yp*e94yisSd~+U(LFoK_`TRD~MgIsp(?lrA z89X>s)Pm#Rm2{G(*HWb$tmZf=M05Gy5`!wfD#Gc7K=pj=>aUx(s|k_pUt&^AD00`X zDQW`+m&FyXQgMdmtEtYkVn&s^MHH2D1>uu!!zSs{4KAc9*jwrji>!;`2x??+`|jeI zjynl|1_Y>lFfIW(noL7}s#O9P)NcDmvH@<#m0#zZ6pYdz16oD$& z;VN?dB)xTQa@Akg>>4^)?Hk#bDsWZCGR|@6Q&ks>&`=%XhCV$8NOAh1W6aqRaiHOQ zFB{WH8AgU@i#;N0<@rYsmG0nvH^2pu&M~qjh(u4&ou9ZqRyHYI`5=sFbtL51aw9yj zks%K|ND{Wrqvk>VdKZfBuyeO&fX2?2@L0GSJYr*)awd18eF zSXC&aDOb)H#bpRcZm{72!Q!ooXb1k@U!3F;!k*CCgT{mTvMHYS5F+AExzj~CB_}%^#J)vH$crgM=<5fEM@DVwg*RSxaYN{Rs`8Z7RIYbKRDTf0Ua>|T-UBEfeN63h2|2Iq=7LkYzJg$(6$J$UPA13%C}+`73zkF1+cfPEe5k^i7- z;RMMTfW<{DgLTEa@mf;#Eb(rtZ12KrC0`_&7<8zBP|=2FIqAA@~&-6s>v6h4=n zZbg4%MJ8GQO|{1g^EOf^6||69r?I_K=aRa#jX+&b!^3rWWhY~Hm%SWym7b7=bYAo= z5&Z3GT6DS%^HRE8r^Lsdz>nL+_Tp-MHtct?H2@SVI%wP=zQs!+S} zSJyN8z&W1k8_i7!Ex!-Q(V9~m(=24>rB?kfYA#s~oWK>?#h;ax78?QAZbo$ZL~x^# z$LD~&u_y>b-Sc_ZDgw>WU%BM8lOFWfiR+s_lq?4LoA0c8baYy=oa~N-uV_XX8vwRX z={&hAoSW!IJc)~$lUNYbp9pY0_@1{u`D@-kF7Z3;Mq~{r?4|B_b*`0G=MVbe5fn7O z%M?RGZ>9o$!e^Gh7VhLhT}8SVD#!hj;X|TZ_jZlK--M!1w(Huc`Y%h_fH3?O3|rRN zK0woG1QUMI!PGWCWY*o!+05Rl}cxVL_ zU;YTmS9rB+Nkhg8oLhF0+Pa$ZOl#TfO}YI_yzb?TF}&+=chBi>`)lW1Z_L=Q_Do}M z$`VZ4{x#C^D^nPF1BI|gPoG~Cc`Y<(!0Sy+EN#EEKn`jx%+hrm%no%jj$U}LFZ+sx zBQ1|6dQg22p&tC>m{_N*-IcDGq68A7b?oq0SyLCpjMG6-p{IVMO>=qyO3(Vm?)_hm zLqwoBkEZ$<>dXRM>|=1-2F(Ye;Ek-cTH)tpy5!_2aDRP9nT7c)ta4KAnywKg^c+7^?c76a5*KNFrF1B^yS;zHk<- zJyBo}?@u4ocx-uge}fcvRREbJQk^u`kms#3DMz3emlTynm?oc`X3K<;Y@XjHo%okO zjlK5r%+;!`o(Pq|0gJgCcIeBR9+L=)uKMhuw@}uTLN@^=+?i&^L|p_vuv!BrP%>9n zfcQ7j-+BMI)s}deTdfp~`+mUUD2t5FhHX+liTn*g6JIM4@J71z2~%G`gkdUQAArNM z0Rf_c9p<3}D4?Gh9?sUY9<+eaM5^%vZ+q}4bqUw0*!alcyaEc78|bgN3oc#ZYwl{1 zI|(UQ;h?)$S)$3JyU;*+*C``DN;?<%9I++ zXCJ)oGS6e5J~^zcj|N37>7q(eC4{!KLbT41dr`Hs9ZhC?PeOKcrM1}iDTZpJFL(Bq zX4U+u#Q9D?5+&ZF@J&md)IC^((irDc)nJUhC&}qDWjRlJ>9s&I(lL~{$eEXjK&0-s zFQJnikTLN}nsvw(lTLDma@joCdlSfrWDNT-KJfFaF~n(kGqKzC6zPvJc=IY*w zapC(%&Pp`-^K3rH!#tgSxH-gKe5=KcA99KD_~xa{z@0y3FIIJ_;{zJf5)nY9LBkly zN$j4DMrHr(Mu2&_8v{R{j+Qth{b>>Zj#&_`guK`Iot6kSmMwHFkPRr@-CDUgJ+{D# zULDd|H5^rxC1gjQ>@I~HMRezKMKF%6oUs;-l=QXB=DM|_)I+@Nn~tf`Q?v6ZTmp~$ zeC>zAi~nMiOmrVmxR#c^)5x(llYCuq0g}F=_0kjl#&eRc23yW3%_`^CQ|{0$@NSkO!Gu3s$hnawlqBD%Sc|5nXhfvdCaDSW9+ZXZpCiUGgE-;DuwgW2gVD zcPDK->EIoCC5i0M!JJ^WAp2GjxqxXJEF7B~PjG#fE>qKMk3lJ1<}rPw za7TufEPJL<-$;e}&Z(gtfCLJ*y3%M;xLg0E#Tcq3Ne;?<%N0fx$k!(>f%~*GRhuAd z2!w=SbEQS%5>)dp{b-=LpM`!Gu=BMDj{e_Y|DWf9e zYEpA`B{1X{Xkpc9CkVK2p9gmP68efby$M`7tM0Qw+@Cp}h_Hzk)XuvgAd6$hFaIjeL!jSpFsCe`| zno`H3s86z2jimKA#A3EQEEVK&!nq5*{6bSs_D?6E4WbqjICKTkhxg``($0tLqvYS`;cfN_*h|(5Vei}tD+Vp9nxtq|6$gI$#g=g#eY~+4t zk*h92FVt*uIZVDPNA1)=F*bUHh8Wv^U~E9WOg_JsvMtm8%h*VfN^Eo-YFvm1k~<_7 zh!uzE#@KKcVfe`J7ux_??>uxePnOS4@Dh)iOIkIi-qCt=6E$S=j%me{DufDN&99*h z=Exv6(22+Q$Jq^4qF&-jxLA(^7vD_$JZ*-S;~cy!y8OnMJh>O{r`xh!2+2O}WHcgm zwGu6v$xqi(ZfHa?PK(*jm$n^Gbam*51P7Xxur143ei=dmJp2&NeF$((4l0YJr5ZV8SuzLy;C5R3% zytZxIwr$(CZQHtQd+*w|ZQHh;n}?(-l~iTk`*EtPXZn1VR<%DI>?C$uZi`b9jszcJQ3a{K8Nyj&x6~Br%r#E=mEl;FkK< z_OSp)n@oOKC^*)!ucrNaAF6c%UDZKl{LiOv)^+V#4gjpPg)7LnC!ZcGFu$C)PU#3n zc|xB}#IdGDQH;r)ZmRr%zbW(%-zc}wAI6ATTs4(0v>Ucnc&B!;~oOYjeC;@4;tH*I~HBOM}6)2iVG)q1z+y^~G}lc^0Rl_aS?b z?8C}1QVgI=E1~LyrJ>BBC}T%AZOHqMhj3A_)Bxx8Gsy5LzC)y-280NjJ;_9mS|$ zTud?z!OA~;FCDig2Iyde(Bq*C^sI(<>>HlGa7ZQ0L5sd9L|;S~HT4w?lMUxYAVr%i zk7})6Rn!jd_gBulWr6mG_d{`x4lMeawPX~n-Wg*{WJBHg3Qs)U^{pj6LFe zF-r7`NBEmssZ(EX&+|e+T2Y@m9(sPAc05k4@Y;@p#cpMDTG};SI2+O1QuF%=p3QjR zu?3mp@x`{R2q)l=7b%gftieoV9A+mrUZ{AE`*KeU(`v!j3DkvZlFUJl*e~GQ6VqUM z-a?-@Z(alKr47Y7$cORRz~AacR6h7n;kKj(VPF-7r`0(bqzh?5gkP;^{kg^EHip}M ziWAMToVV|*4pB>p0irN5m*XX4Rt?%z++lZeTgT>TN2*3Pme5f6U@RX@@&`rAAy2CH z6e%q1X`xTE&V{K7m{L>z%oISeEn^39Yb2_-QkqrsFyUe>{Su`>qIU{XdKdkmT8cnm z<%Enk@`1#bv5dw#B=q_#`}VyO$4=B%9$HZLBPrkx7TOGla~5-)jOL46E5C^H^*mzO zLPIz=*gMCW+J?Cfy;)&odK%)1cnag@OHB1f6VZDuuir_s0k-U*q+si<;jOgL0f1nS zT$b|U7gn?9QUf&7#Hsd3_V3N*i<<^_OzU|DGu~%oly<|N zoPI6IMupKKL!@dKm}};=N>s|3XvHA~W%jb_WOMMS++ChjJNz|^c}GXMyxqNPX&Ftv zMh^7gEa;b=TelCT7Pepd$cH{^#xbRSwpkoGb567w04IR!s7Xv_^jZLU=yVHdx3iN% zy%&PpUW;wH2d(=aSRj%1(;}#4%#K+6Q+&zR6esAyr!`vM5Mn-GKhapMx+Kji9fJf5 zL%nH+#;I*6-oq&8=keatcog**fh`zpN;w+gi?_?CvR}lp4DF`{oX#cQAz)rV_h)-7 z1JpZ=rwkcgKdPamkXE4VxUFhaUKTI~D#!W^D8wnJrcil1qoV!FotB@K$)G$_k~TAv ziV~tK3B6vHplJCdHo5Cxj(g3kpErPAbO9Ch7*gd@;vUWj<4x7{{(4K{H6%V9b7dLSe>uA2+`Y;DAoE5PvwH|Yk#!Z=}5jEk;S`gaF!FTkSiTr$x zito)6@rUBTy&cJ8d0R@U<13Y~gcp_K)1DZH9;pX6UQ_1Sx*`uGB;W5(d=ic#P!YYhECG-pqlFlbm+$Dkoo`alfJ z1%UxvV#Oj$bp2}Tz34nf%MvOg5S`a%Bo(POgoC=>;Fo&u09|y1OU-I6?LJ&_WoJ(PXy<7g$pwcz1vPV6UL;C-44lG#o`R z_uS19cP_qKxet{;CTD5~hrOsmCM&B0VZK6G0m7-05ofnFoknj{ymCLFAgrBwT?yNp z5v z)3;5X>RG@yrad2vww2;Msl)87T^Ew{Vt?YKn6^WAWh!|#a6_>%E9P0aD6v?D`v&P{ z)sbytK{Mm@5TDH}=}VZ}c^CeD_@Z!2Gan4P@>-r%4va~$weQaj9w1&I5Tu+y6t1&@ z5VFsugld_8ASBI=0=gdNokb#y_w$z6#H0u#j;$1;x@$i$o%v~?w~@a-9}7x`yV59h z)p;6MY`O|_hjh;IOnJI7QptAaieRsdb@F5Zz34J|4F?_>?arKUsR)r@Rrxxai7*<& z9@l!C-+jauYn;2v)w0X{f+*QqiFRd+F^ldc+r?-sj`Ty-BW`2+o1D^sjpAv?sZJ!7 zKD%r9EHTlEj`RhDHTg^fiXx@zf2xfQyZmqW#AFf#oUfY;5Ey8~BoG~(XS&Nxmd1Ev zx>ggI#@VN2ZgbsG+7#*RR^J3bQ}A(U@t5?6bpOHrw1YRq*GVuWnHISQ_XH*qB9 zGU=0b9&zLq`zj+fM`llDztMp?=p^CnQY(8L^^D`n)A@5m!wdh6dLg2eb5qWodFXJK z5b)Q+pdQ+@h2b0dwsNmfZyB1RuH4M z=z+qjJmK_2J@0qXFN4LNLFhRqxlK-s?^S2X$Ys_C)CR~#ptu6G$&o}b0`RGW`o$No zpp(P?>kaD>8r_Yjt$NwJcW)tH0nkaQ$NS+21%IliKx4;%X403--FobHad-Q!yA2^6 zaQ4Fvi(6znN>W+H5sB|LdSZXKctl=&K^_g3mQwmgL$;Ab5|w2&VU7s-;F3^@Yb?)k zNjYBk!99d`9gqsDzdOEhAH&swfQJZ0}d7G=(LHo+u^)Gc~W)nf}7nTII z2vjrTXza}#skV{4*q5j|LIeEilZ&ftD%W2)KJjBlx4M#dkAq6$$v`ah!SXbk0D{*e zj_oYyPSn--Vz=*WS&q^Y)o$|Dx2ge|9*=u+#%m|tEw+I8(c{X_R&GVlU z)aEyG%uQ92A8O}Msjf*?@j*<@LPM}jlp#*g6r<9pkoJ=PG2oClu?OfCnMnJ0SnEGa zns2;wgxoo(`@&z?a$l$0{Isy-$X(B6yvm>HA8Ei=;GXE_>HDN;bLe|1C|(TYV=xpN z`G{w`*w?)}p~XgrR&FC0GO2!f);IRSRwfUAJ>0>>ZWgve<#z$nY(elzBchUt zXj3raWF7Wgh)7Y}IKf~JITDHw0{&mM*di_u4>`*3`ym2luof4Y$oXg80v&_3^Kx{a z$3>G0a$eg3#bt$>#m{~5rk_8s4RsuTc0sX}B-$yGZREUIr6msQ;tE(YI6&q>H4n|E zZCqm@Y9iPU!l~9$gY1(l&ys&H4%~HkLgiF*x$Ux;BY~ibVW`}fXg1d}lVca?>w_*6 z&AsoSeFTq?RDjiJ$QWT40;Cm}WY)6Vx+7JO+q(W5XXC? zq-eG{UZ@4u%+(--$m?QxlrpB9y~OeM6Z)nN{@64ctW)w|b7SOZ9!onEjo#yU9X>x9 z)Ue)Bq?Hta<`dIRO#;lA`U&yX+<;6{#KE3ppsDK)($;=v1MO{mg#95p{*;5ygw2`@ zd(5t~__TBZIz^TR8PTmaC^VkM zPaTpF*aq@7C)ohdTHRonvM7xaIc3ZkInfc(d`8M2t~F)%#i7ziZ*#0dR5MV=9H90g zMBN{ouSOV)!6T_FxyR>qnp2KV`NFZ{O%_54RJEdZBU%)k+Pygfkl^_X*7WzB24bK| zPEu9U#%i_QMpv|zh7s*TdC_HGjv52l>)U0EM_jmIGUi*rD?8V*ku_t9*< zew|lPFOEm~OwyiL_Q7Uz*BiE}R0F{P$K!ORCo;&V8hY0cpBPbvzQPn<(HV;wFZ+&8 zcXyCY8E~-g%kKyh-Pwrh6H>qr9+5#$a8d1)LZ4!yF~HKl;m0gMpxw z!U~$r1gSWC!a7YU8}Q{WvTR7c0%;9uKW(S3+9j&9M}yL zA}&4R7a&)k+54%i32oIrdVX{pin4?j5xoNk9lAsCZz--R78-u7eG0lO*49#$gH3M< z_(wb|mnF2^RTgW=@>7gl@#Q6VebfU2REpDkU350}#cs4D$rXbk`@b1bqh3ok+2!)) z?p^f>u%|II?DbQ>$du7ay~wy|ty_{AM(JHgd|$8jfX&fVu#z)pW8au700Xr6uL31{&t>9h-D!2AjUF9UXS~umR{=8C4O3ZN6hM1GHe3 zI*(Wq#VVO|ycFn!Y3JTT62mg<9u9~KH74v>c`5nX;yGw=pGz%^I3*~aJ@|UVRDFNs z;cPl=r6@V~`(L+YN94S0))AaTFrJy12w5vi)vdDEbUIWt!Bg>%|NgKy zI&0^@bX}^A&01~OhBT3dsE_6%1;o~QvI`n*NZ%j)v<79y0T*#qe0fMrRCbs1)LEAb zTlHUJw=?NO+><8(b~<*exu7q&D!}5V&uw9??sB#(1EWeu`1!tCBhWa+*V1+qpAgKhOkrXOQ;2N(1Pe6G(e8^>Xv(7rsvFZLOnQeMe8EyHh?iId`Onh+?W*(F64)&=T(HRAiywPQ6 zD0YZwI@3a#FbE9X`ZD&&bp$53fo++xTrZ+p^H?K2%1qqFEgZ;EcB|!|25b6B45%C^ z(+nS@(++~VO6P6h*~uPD`AEDTkDg0a11t1fg=k3zHh-j+s)AJe@m6J*)*Yn!LrFj;%zXk?jAH7$rd9_&Wyzeu>8+ZbUHAJ7HlXR-)zwq_CnJ zSob4PI~T~7#Oyd#2UzuYWH6rQ2>UEmB9D2r*RT&$dA#IvhDiQc)KN?J5+<5i@^oj1lEP_3m0kaYc9w9b1k0lp zrB)QB08*!DiMbDtvl?|t_^HNlPL4fLZxaHghNGu(ZOND6kt9gVih5HG>LVJ$BV1!? zusM9@UbT9@kMu09fX*G6jto1thNyv|?5e}gK@woW1DbcLpwBZViE65J)~|Q>DB*nH z`#UCLk;45s>LACrnMah1?K*XV6SAybN{>yJW5ec}!*E#(A`c-t_~vKTcIYs7gC2#Z zbCtJbq*c`Ux_xaSDDIL`sl=I~x@LSQmq$2~+%8xq0#+9PqPs&d(QkcZ)Q@n}e9ro> zQB2TwkuT#V@6?p$|AC6IGyX4v>>nz^z{vhzbjUwcgqfB3zb*Lxfr_xO|6Bf_&;O5# z#6E*6=x#26LJ0>6JHWO${xd|}gEqz3Z*Fe-Y1_0Nf;vIm-QoMU@lSQe+joD}yVX0b zu30<8U$1hVpL9$_qNrSi$Xdh%9JR5@xyZc4>;fXP>&TFq0}>NMa}yIW<6>l%2OvSd z;&J0-aL@KE46O&h;lm<;=jP70$*j(vU(0LbX*;5K>(0fklsz@d$W zu>-OTk~!x-d_|3g5d?-;)_~5Ae)uUVJg0NAui7v%baZvkVXJY^ZE>gGDl7nN(Bw`4 zO!JB7`avy#-YQK4x(ZnDcB|(H69HAGX>op!73x`ComgD}fOcRBppElm54|HAV?T2|b`*ly6+%m9?3 z5fJhT=%jCtPDG#?ni$`sEg+nleB;?&7@GhvvAU6e=(Z6E=!!uYd~WY{zd5nEHP$#e z7r38n;e}&J}dbYp~3U-KYKcvzdjwRZESRHd47XsXl-O< zeys+F*5d@HM+SBz`VSF7Vmo@;vyjpj0~?p7=SW0*ZRK4 zf9$|Af1rEwdV@o;1+wmS{bT?}di{QV7k$;!BdcM@zTv-biOmvJ&=dclmAt!8{<=az zZ*~CkoUdsBxJ=o|0FaTP(E)&C6Zd`kKT=?6eRaZ(@YgG`m9_xX`2YFrk^iM!Ki$>iA3Iv$o7g{wmF=p}eXZZF{{oEz|{Z;uHaRe{{if;sn5utT&k3Nh35aToNB7pC0pKDNAO7BV%cs>Ze?ITO)r|M*_Py@E z?~)GN#MsLIWHOntxdjvi2N!VT9CoIpude~*%G@4W0J(f>4+DUCVQZJYBJ_DX?*J%k zgSYj{rR3oD5qzbc>qh|h5j=o90%3^!Msr{Q!W{S`UMn_)cUvD3$3~p^cYu0*0-^uT~ zFZ`c|p7aV2^KyTM1k(JU`d;MReR^GfK)UFk$+thxm^d=H0e&<@LPbhm=J47d^10#cu3b}s2)p@x54f@ohf6=@6QN#BSaF61gZTYO8e6xPIyiez2YBumEQ1EMs3 z((0C`jAmt{`+x4jnO-1lX6+SeQkO6a$bB0Jo+8_IusHDJH>u&y-ZL3^*7nTV~`|_ zKVvGg!80F5uE!DvR;8dv^FH`6RZQMDp&qAtJ>lj_z~}PMubT}HMP1cs=PyCTouPBT zp6e{9#eA_0HV105-8k*GEifa|BZ}ZaRnn_2_kA0`^csY!L6Z<1Paj)(YEj3~Tpa-? zPyB(ibNRaKeGU=dtH-y>xeLZuqGWU3xOy#RMZ@@_fh6xL184Ey2S|d*@-s|jHO^=; zAwPAF@3SM-G8SI4PoZTRKKs8^aa(ux2Vg%0;5Jg(Q11bPG4|sSn}H;lU$R=M+pQ;_ zgRm?WR<$+D_UPOWv(Lqjo!!ZsT-sO;?#?&A*sNj69+)1G|8i9D;Qd{^ZVFlWd zh^MV1XUJs?G22=b43D~X$`gFbrQrDwR`+6c^remCRa2#_fwOZSJVg>sr%XZ0uJ2qv z6%rA9dgWsHY%{>4C_gHhlY}LFr@ug)y=g`FFT}!{ugbz?>iET}YG6IhX^g413Kp{2 zzYYN@ajp?O8WHibS_ie=$RV3JIAXZj=*pTQFyIlxo)N`t{-HhW`02;Z^~vcm6LchZ z@jQEiDg2bFuaMu$9kSLy{JhL4Sk}cLQKfJ_dnpb<;6FYpc==0$RFGDf;*-H=+L<>p z{$$PE;?e|}BqRFW2Y;iL!0sF^biLBdYDUf%aJ&J6>z50f7ySnO!W!)IFY|ZS&NobG zg~)ZKRM3|TE9Gu#q_UPZQYBlg%f&dRt?j0s6G&Ml0SJ`HMnD4Xf{K<7X~nl`KBL4k0j$fR}E683#8ayqPX$BTWbu?92*;q zr_3LhIlx^7X8>AEm~mpqQl#_r@70^xV>|@UZAtl$4*dQJ%f?hscreyN*nDN+cfnXN zu`Dl;N5FBYP;fx>{ME(sfAroF+OYha;h`=%;88)))fzkyce-3HYL)W?m&Ec0O+sWgE zun*wR!cX@uFh%mxv%<^9RmR3#AG#;=Q%-BQZbrI(X{0<03$55o7R+V;QhATCeR!R4 zl#yIIqpvlv%(k<{#<6a35azPXAalRW;!)!?rF&ZY(-~2Cf&>JfxwN`{a_-G#Z!arD zjHjpBcTWs+8>2`f$`m^Qn`LqhOe$Is9=BFZ0ZhA+A}9Krx;O?!O$!VD#=%QA)$&2P zM$rAVg5gFx6UBg^Ge%G4y%1NdEC6J11z38^rE@n=0CN<++O~y;aCKH1B6F;uRk+$l zK+`vbry|wlUTpyuebJkKK4}-CTE!WfYlgNs@)7Sc<}I3kvs$j9Cjw9c>a|1*NqDG& zz>gk$AlsX32Ai~t_BOy7#o06AGT-6L-@<9py9=*yY@-4s=BA}Ng6eV7fvJG-J{1yr zc+j*=%g6c^jj+xgPxT%G zkALNDi@F|ND5|uPpwIp(+&pQ(k*Ot(dd_uSTN6r_a7)!;XbSF?SyDE{F_^gei*oTV zCb9M5)SyOT(*(%Z= zhDJlUX*#5L`GxszwLvXxTWP^Ont+QSDgQuyoxMn-HcA_bTf*o?F2h1ZQ%H0=5f+|! zsL-Yw;qaXMmi-r*iiu`j6jK@0thkx#_gWU9SUl*qRE8IKf zFDgWGZ>UkD+Jgz0VU9Ib0A1om!Q*&4Sj}Vx7_N%FQ{&`@!_t+a70o3^W`Jic6>P~g ztmZz`&pW3Fzmx#6&JUjwTyV$nqPwR=bfdE7BDM0pW|$G+n@`=mi1yLFqVFJMVfM28 z=0I<@i#-pJ%SJsD0rd*s>joX&iB$!*+~xy#GZ|eqEM`in>S5dM`Cz9Mvwqs};c=QqX_U+TbUAI_nDp>U zE0(X7V~Z-&%pgA)n9K#FTBf?UqgT~Oo^3McBSr@o^@rHC1zd{cchM{R4U$7iX!Zlh zjjQ0^dT2(x=XCc1>S$-*S+yMTyO^RWVtHQjZHTzXW4v~@+b^G2H)QHpvvpSh-K5yM zh|eqUuenX9^r4poX=Q+vfIz6%6UJ7SIXO>*CP$3(9rrBiA{-hjbCcND$()vH z1u5g>=e>{cbYqOCjOn=QcYzuG;`khrA%S#Bz9mj-ACE8SMc2jrt)sQ_E5tXdrG)@5 z5K(oVda#;X>M_{080BEb#IBf9;P;N-O(=5VyRS^9(xN(GyMd&Ywg*sMPjSLmhMUD$xp5Dyu{{&V^@8`d_edEx8^RC#xtq=ZLf5&8QM@F zrE_ZPyur>dZX^w-z5Ng?PVh%TRCu4bu& z*&}n1**j+sbGo?3LXsYp2}l@Tgj=@jL^Lc~oXXklW(2(|Wo@6qk-t)~TCJDW=41lD ziF2p4qTPD&q%=(Zw{!_L`TQ_&>m!*#A5+~qD#j#k2}L#7LrWahem@2x*b+EY#?&(w zMkwZQ?Z@mhn-(t}l$9Yn7NN`PQnSH3j5n$r=}lp)uDV?LE{lcpr^SfIznp+EnOCQZ zkNe!>SWEXjyAh*+-(aIL_P|ul8k*s6O<{7RH)wmT=*mTKwftij^uwACxzh>IjnJ#a zrt2g$`jh#W9Cz0JIEUt zN4y<022+ZRW#rYxzT2dvobN+F49D+YV2?U}b-K&t#5YbwFWSKPJ&W)zP~sp z(LP8v<2T9?R6zXE^-^EYmAR-A#V=F16{de+ZvP}$B~6to8q4u02Li(A!f{S_FSuj) zzVw|+P4;{jyJXA>QPHpEHBo4rh_D84(AHJyzgAokWL#v<5nHC7w_-X#*<9BN>N@FKrrVgILw@5L!!7ZBuacmcF|7PMe!aU^##|kqNe;Y0l3|QPw zan5iYKWLEq?e}}(I62v`?W&#@@ow}`e6#1`eu@G%;Zl%HA z>ftG+BD{Tj1;JWMX(se9K50lE4RmfDnWIn54OGt_#0hUBDn5&^tfXC4v}LVOC=dH= zmLm7cwPRxOLT#uFDZBZGp~A{P4%hED8iw6fJn0vug1b`fEY^}Q6yV({#}Ohr$95uW zKc;HbkzTs;;bAu9z6fy{Oe~%ht0ZpWJy0z)Sl@W0dhLE7f%hJ;2aLk*Au7mL%6-U8 zSooq0c&M0!#J~n5sSQ099KG&ukloVixS#K=coT;~hFs-a!7rO|_Z>6;Qt;y%P{em> zXiK3@gS7MB0u47=oe(+fjZWx|?$di>$9u{=c`Xz8e=pc(v{v^;=`Y0fEEzVvw5Z<^ zV{K8Ye=U4F_1fK@1bt0CPN+&|iBSuESm*jO<4niX3cfYsT4Qg(N^@c}DpP`3zag1I zep#_bOnlHsENAnczdrP9kiOe%GL0c_wRQM{4v3h3Ydiq?Enpy;gQGwTJ+-Ro=5|F1 z^HKtN7sH5oa+{1yJpT}Cv)PIuECq6>oww_pon<42R6a<|eEikyUC6*fgcz5vAPfY3 z@H!fvQPN|F7i6)2j46Q~y4$+jb0pKCnmhe-%zLG3Rl^Q7WCShW^Ok&?HtKUw-`xcq z!YQG=G1PAtb7nxnO@C*}u9ce$IN!Z`8S*5!20@-p9E=jHRrkDY{1IkiMwaKJ<$D<8 z24~7*HW|O{#3Mx4Z~sW-KVcqvw7nn&NETRzRtJtR@D)1?{zrR+`<+lXfdz(OKbsQ& zDITxi-Q|<>4)-A;0}I0fYor>kKG{ONe_ulpsE7BWiOg@0tC&X=RnFsIo89EhDSNxH z*EfsYv=O)0BP@C)xo%(=Jjx3z^+Mx;C2<3VDC=vg6azaMQCOn1PI^t4A)ByGcNtx< zAILnDT~Ng5=iP>aEUaxpYD;sd^4q#?06S?gKG>$7^tx|0Dp2$9JXLmK!`gEZ;%&JD z(na+u!ED;K$J<{yg|xO)BTU*6+Y>)RbQ~;DT7QBw40`>^9lg6wKr;@u4vC{zWi1i6 zY|~n4*6cwo+mn8!+0T>tZr@q!Z?3KgcgNs{jiyctdnNT@Dz~6RrtwSDh%?NbxN<6} z!vxt``xCQTj--4e0cEyxryB3fu8cdq!91>8=d9UP-TDkkEq^EPSecgk+EcnZDLx}IF7yF@4;yKp4@H;_X?O=w!-UqId^L4yIm}yA0(Q!l#cTN^62Fy(R+z8rU6?8 ziXlRz%Oc65-n@+h8KQdX;+@lCY{Cw^hl-+H2)EpM`>c&!Phh9v!wn1cOK*V-_pL*x zaC&8O(dGxl-A3&3no@@;gFd=&zDmoatoYFSQCcb&935V}8LJrP)iYY--O)f|FA0@A z9$=ay=hD$h{eRcoHlI~@BGTUS&Zc4P_@Nu6ar(Od&0CNo^1x?UTULNo@PL=Xn`}*i^rjifps0S@L1 zG1J6LyYj7&t2s=(yM*@0a>G?8v5v-#Pwr37Y7Kj%nm!?P)NXfZcy@`zVw|WH1?bhn zDBDWLFwI#(Oh*06U&kuM0}lCt0jS(-?xm$2te9*FCs!!sRLZ$+o-HL`tPj@=;^z%} zarBd%G$oeJBgkGxZ-ahwurxa(BoOx(#LFnKQmkp0gi7U-*cD^W>`D5H+!;q)w01l5 zUB3yAjW6{>vsyatp6t1}_(#RJK8xX3BdJg5p2n#}4#-$2v8V@*;Oy$Vz27I*q}nTj z&uGSV`>4&9Q@-mjVST;qjxJy4od2%@qf z%Al#|R>}>8$B#I4Z8N0pI}#TEX~4UIt$940&0q(wVR}4?Eb#rh_Q`s&Wb(ko-&sa% zU9vTI7xqkoCN-v+k<0>LFtPnE49J~GRbNeTV7<2EOb$*qE{SVebzS^$I2#93ziDPo zLKJb@7H&t&g}ESmdCNMrcnc-ZN@bQL*fO0wqVd8fBw3{>61m=v@v$#`UkM| zJI#k0N2X+Pm(3gZYG=1G|E}x`s?;7(H&a$_=!Br&ja}ghn8O8w>9T3d>VqSeTB{r% z^ey%bqxtDJZXY0Ghi^I+*JZ8W4Pv$1KBSXw<|c^&=3(|6aZyp&?q^fZrv+8 zk!Vwaa3KAuLLB4Qm6OK~nZIIxVQpJ=KyL&NLZIrM%`)^CMTYiTdj@P86rjP;JBEdn z&sZxzIB3dqS+6alGtqUkXcJd+E!F-Gj+0a8^MLUEsbaiI220D)tgUIbfqR!0{f5-o zPuZmp_UX2PV~wIobm&xo^v~-Ach*NM)hE_wK0TVyix|T9?AU$jE`|8l+l2hQnh(xz zruuio{yVyi*8xX_@gQ!zCT*u_iT|ud3=QlEDaq<2fpk(dGwh6^*x0|ixJEhd9(Kf; z&GvpYWq>XI4)(*z3GK4_Bep!CB2mgrF!5)Rp%oa~l(uCvst5uufTiAWOT;aDJ)VzE1KK40;pukM6$G8HZUXEs(7d z%@noGBOsQIg?v z{(3+7Ij%(sHKn-i+_P+YryAi$E16T`2h~(@GU#;M5JYIogc@3LE*mR`bQ%40I7az} z@5+0t5w=K9G~^ve>W#E_X*AopXo~9u-Bs28`hMb%r2Bg>*MiNnPD8L<8A~gU!2pR8 zvG|DV1q!W-?onkZ|7RTFIm~}^_Ja?{_D9fGL)U81qFObK`@YDf z>|;-7?R^z~E@Sp8a_Uc3P+F%mTQ|dPxKj~h4&vvf89NiP%2VNAD_uOw?H3SIn$TlE zawj18kI15CWM=x4KRR;{=)@xX;fDM@q^PDsTkpPtkvv{f*>*3yh+vQi)n+l_IZo98!GI2QQ70tyH?ZB5s-gu z7wLfK>IidA^wGNIFw8BpHG!6tk=i@Z4e}V*OE%XIJ~Z^MFrhz0vdWT*y%eGHe2^xo zCERnvZ6}t$xcnOZaZY5-l+b%!I0pC7#a|NVZ{?#qUBr#&5L3xa`$kGCIe;GNx9g%; zw^B@aCYHHNvg2I?ng~%>Z$J|#aV)I;bZlM|O^&{Fa3&RNfMvN zLZL7d!2Hwa#H2EVaNtwLU|FR=&2ox-XTr7P?VeHTtA3kE0D~0lxv!LxoSjMKb=&xx zn6@%T7VW^%a6p|zb#N&Ufc*xDQ=a!Hm)X6(@gOF*JK4{whmF^K{s6p@{$UQi*)}PUv;s*YR_SDocla8AceH_u&$a z1rJ9j-;83{xV65Cv@oSkXnT1%T=NMZ>NZd@fG$;kL;*w%v!fre_#Qy6&os@Dt54C( zo2>GNrV{z~d-7g~i=6Tu;Rk(Sy+z%;gac@CCEvrOx6UKg0x>e;jn}_lRSPc5PKMSB zAd(hu&Eq_kPXj1_7?E&nsrLKRm#td_sVq0`tXL_G{#t-X&?U0Qv;=sZ&TwB-j|B>h z75tmdeb;CTIdw#F&ly!FLICNgm;}$P?O$7mz7bl(tayRMicKnq8)8WXk-ZN|VCiv) z)AT!|?%*d?&$r9sbZkl)8Nx=<5^@$9F~czAp%(Ic1@S?^5vrh(d`x?#R^v(zTpdxU z&WGiS76=TMCAP3ctAy#oyLF{b`Ncx|mBeajt6u0#<)Z1bx;|Gm>E&Y4FP7f4KCnxv zUIKwgrJ#&MdApXL_P{H(k;A4hfI4O=R>OG5xC%72T%Y#c^D6;UOe?Fy_Nvxk8cge+3;eE<)*IfyNV&T|MIEGfKO}T_tjNZrwasjEO3UyWS6M zjQi76xgk|95OO0vV8R9(*0(QWi?i>S*-Dn zqo0G$lb&?k!k%l92mKQtf!s4g?Oz{#oY%YxsL5>(57{qlave2t649okF?mNvgACj8 z0a<4?7rR{dvutQXVioFp6jXXdO(~1YYJc7h7`QM@s!*?)t9|;z8MIlqq+~3%3EsgE zf8*jyrA%&F4y3J1wA5$S&C0C@yDVXKc)syBMZF-)){8KQbI+Xn4>zZNexehBI9o-6 z8X9tRYvMOiL&hFe+EfZLLy=k9wc<1lIx-rPp35d4mC+QAe%)3u}7kKWaGN1Tu9D{g1`dH=BU;#w}hDvF9$ycwJLWoUp)W;BUR_P`asy z2CYQ?)*qdhf`A2#)w||Tl|BLC&7*3wpADmJTKitRg1_rho@8!fU@6Fiu_nNY1^`FN zTl27YhB)(Xzc}a1)0F%zoH*aZu}pEw>#4?m+uhg^{xpSzSqe+hf0{}k=c5h43>#C| z?%S4=54AraqnbsZk~N9kj!!HmsfJdBz4zF{;5*I01f9FoEt+@I!v!XNo&T693Diaa zaXg+2>Ne)2Mys#BlECnal}`x6aRD^AmY6C<>9QDIrA2QFB7$Ia-lLC~Re-p8AbVBp zW5gc4&p1Ey&|i@fWv<|Ye{Bx{mKUTl3cfgQT8EbF1r<^3y#GY({fv4$PxDZj_D5<^ zeA&XptBQ9S+Kp6qkwrIEH>)=@tIP6F;rE6FcpNz7HP&#j`nVGa4=v(`30FV`t*eBe z%0^MS3ckOq@1}u|O^4KD3B+f?wdCca{T1G5c#ts6UTjIVb1wC@!!luIvStruYH~ZG0<&>vWY~I#{!V&iJ=vw6!8&Zg|L8EV-J!2^|b|-D~j3!3ZGy(edP0LhCX9K zTr!j<+SN#cHfop9mth>@uj;=ria={2Vc;^#d+&Pm4k5q9Hpt%A$e?psQBGVEVVy6)l@&?W9H9$WltK^5i zo2fI9vdpzqIxxw?d@J&H77#BfEU1BFz~EEJ5j03?7D$rgQ+J`EUd2@|^5Y zQ~6yeWszEH&nQ!8{1ZZloV-mx)}X5zQ^#&pnQ2D|pF!v0suKXNyQZ0#`LPGImX)yG znd{F%_cN6S?sD$sN&49UbF#wI?AxKNr~W?w@2wrgJdVL!jWOTNC-3>5!_8YnXx=f$ zqh9-I%jCTPIaya3|4!DGOVQdU&n(H+QLBa*N>`s9{+pNz7u9a1&m=08U(1Q0g_U4( z9Wz=KwZd`YpB{M`QSeORwQjR`d#rEBl-!7aVUKo#;#)SV9_WsVCtZz zql}T5*aLLNJjFB490@+i;EfSdL~$&l6?eVg1K>B~bwmlr#2;d<9I16bsKm^ifZ$0#4|w99QDC&Jy6za#8w)W*Lg`_56cmwDa8i&q2uggc_F&#M48HZs`<$XB zeU`H=EKQRYwYg}283WouvKN(zgku61F_=j_o|oBOnV*OK#qzG{LAbV5G{4m1~mS(bvm!2j^jLGofqc7`%CLW*zTQB}aHd9eg@ znZ&;z19c%?ZGBse$7af|1Ag`D)Y){&>pwegBaBCq#-evg0uSyeT%^35IR?vOYqdOn zA>Bhwb(4qb3m5I{gtJcwHm)L6obZ2BzJU&$o;!6sc7n+BC}Um0%Ful*pF6r{_@V?c z5ZZKKgyh*gxmRL1=Ewuy&<)y%MEf}65uQ7+Le0WvAr2@>b5*k#c&_g`LN`C(F39&= z$>Rw>CPs>``;c84%5`W3n@cuoP$^6e2e-6UL*%Ad)locE)Yz$faEVUUECa!-dpj+t zUsPHpbfmUg4Z0i#U4`@quI7SVoC~$(DF2YU;MO}7uZZ5?@-=b-FH_xo6O3%adjhSPf-i|=}LypJ|XRZ*WSsT-pn4QaF3lv9x-CYX_56#gDbT5-Nh_ed~RdI8y%Ch_sYq0 zso=>N->aWs;PIzrfx%K!9pq;}e!kpExUFy_hHc!y^1G{YQ&YYZ`GO4Vc~>;fFAK(NXx>q80ZosiQ1d z6GgdQ9ru$_Up_Dfm26b!-$*E$1#WWSD8tH(@5(Z@8n?vWo5EQ}`c$r7Efkyo-mq7G zs51C121t0$37A+XJQ)k9sM+6A<~=z`BUYWcf}};fKyFc=iJ&q9Yd(n-%AGQBip~z0 zZNIn%y=7xliD%tJyWz-75(pi9yf^UZ#K*&Eg`Bqb5T6bF@tb~?*MzY`0M1yPzr{bo zZ_;H%>~Pwuyl(0=#~pbUy%chC(ASX}pWAQhWlY5}U53Sk!_!oJruo2C4Ef_#csSxS zYC57%wu;h@;rTa^rt`Yq%!s*b)pM{Jb4@GT?;!+a-Ti?Fe2x6vXlT82;V)NJy;4rp zt8b`yR=+a=tA2(19z|5kd~%ehh*-clhlafL6iv=S!(mcAN{eCCf+Nh$r*D4XfP#cE zAHBHBV6lg+kfa-EmTsdMS)X-^_|V7M>=kYU{fG+OI=**#5);y^wL768ZjWET|0|$f zS;I2FCok|g7Aa%G#?>3=rmos(#w1~j3+VFW62?d2F#+tw#X3k2`-BQZI5h}JYmyEb zN2YF1#UY`)kW+kZd0043&~yIcmfV1ab`C+JMBBD4+qP|;vTfV8ZS$0M z%C>FWwr$&0uYUZv5x4Ogua{_KCv!)}USrIu2II=;>+`>&5Md$X?G09TN z!tYJ%%jomE2@{M)Fm`GL=`^{vWDn{Z?H9d!$FM$6Z#*UR;$0f+irB%kV5fU`$Pmrl zi;HG9m|I2((R-46c*nI!@C15uZ6Dxg8)l6t8FAwf*UdGW&Cd>1hDF_-NJ&%Y?N06c zuXbwT@1}&BUzPkLrbSF&sagDo|EB^FB0`4W@|5tGp#)7Qb^U=ravp2XntML6z1+Gx zC59HuX1C>=h3YHZM{il8HOSj&fQ&{@Mc#=c7V)%71^9yY`FWL^(!a96Vaivvg9|pJ zh(^e5@#m<*>g*b6BEGsFfF5|ZfJ^1EzP@?>mg7QEcP*4VJxWw!N}CI(1&;RBq6jfStR@ zYPP=TmzNXIf`}dtx!!g01D z*Bb5R-2jv)qEM(pmO$TG_}7LCtfIs5$OrIaBGR)n?Dc)^3UZ-?F>o+OJ#}THk!ti# z1|KO~IWs$=NRuM2uH7EO>f?gvMvr%#Q>;&W+`u$;Yhx?Tso_m2?;9Qh z4hpkzIdy8)!W(Ay#NU;O2t@iQF1ozf1*bcUPu5|o$mOrL7v7V3JW{B6pG#-3He0=6 z>D>e-IWr;mf=k0ANW?c&UsI#!JrCeXmt;GBM&Ja#+uLN4pqf}F#jdZ3{I(qRf75P) zBSG$cX>p&boo&42Q`{Kw`f|Avt_ZM5g87e$gPCw3rG^uTD_{GdciR5NQX?;ln)w7v5xXo5teqX_$}pm_;@AXli%A!Z=8EU9D=2TIX; zUWf=}%MQ-c105z+HhQFQm&=MdwG2(!dKsn1@OZM2DV>OFip%AnaN@_UU9mIYQC}u5 zCic%MAvJd`&u|Dcl*q^e(4x~$$x6zm;c}l^C5&soXmu{mzTP- zy`bk#+u*P-v)Xc{gHShk|7C)byR!icIa70eu)yopQx2D+Y-|i9^awG_yQO)ro5KU7 zH)R*5eN@@zen)&7W<-?GRH-+MCY89Dx*I+7&12YYwq~gjErDWX-vSxH)~*UtCDzhr z8&^PAmFqYN)h#S7#dKP&1jKp>0`3eA&S|t$Pf{G4vQRmtybz!1KXtJC9O^40N1TRj zX%zuid|#5vYjAUcNa}tuGYtZBV15+i@lAdrBrJX^kU$(FXew@Ib17Vy9QcLt)0%Yil)RY`SlFzXv7X_WRa{VkzMxRoL) z&RY=L_alB^cD~hD-Drd(^zU1%vRAE6ovM~$)Y2JH<$-Q7^u0iLQaWY_BI;kzIoz27 ziqKoJ12r9Mgz!dHvJ(?+f`;yMEm6j{SKqD4tKCmXhQWpp1E(wI*8ESyZhtdFDVBT8 zg6l$<6T1UBQfTbc9mCg=jG`$PdsutB8ByROn_zp*mgah-y0tZnS#z2Jv(XXkA!BNW(R)ABWIgfm^MyC1SS7Sq-3nnE|`4<}U&RGw+2) zV3)Q>Szf*W5bD-xRa7Y3*{6NuW6pMsLFU%h0!(?j=&9eZn(;~aqa59cbWjHmAD@Pp zQMN=MI-M28o}gxAZK@h(gKRqOo$7Iz7RLF?P8pllaPZ&WwvxFlv4(`1Vf|C%`DaC8 zG8oZOrDHgMUaiG20`2|?MJZ#n@)B(Tfzlvj*%6S~zHFLHq6YOhkA|seckJ*1*`rFP zrjpS|U;=4YK_9k$A$2?CxGJV?BVaagW=85;833HvLM@4D3MpwAFH42mM>HhwX@Cm~ zlRLh|-7L8+L{3Z2{@LS{uKf;u{qnh*39+7}al^^JamF?nGc2w?a#fq6*EkjLc}1?R zWcLJ@L+BWU=kp!TLZRRW6ZX&n2EUYq-8DauS;IC|H+d4Q*h(@UwQnHQ>1z7eNt%d?>qhmGRE+L9YF|8m`STtP6S;iAU&m5})wIZraHM$DFJ% zNShiD`r83!@aIotp)fX2mVL0VjFOj2XTA@bP=S8IA5OeQc@@IaL=e{y`11?Aj##4# z7-ZLdGXO5POis#~H-W{Y^!zkuC98aDsHHV9kS&ds;=hXk9KNk-Nl=8?eUPT1Ql8~J z<|b2)=(cAYH5t4@WQ*eX7`X&3+C@D;!b^rs!lyd(c!Nc7sK04235NfY9+gjtg*6F6 z+~@(wnw@>))nHd7W~DX)Pn~*e&QWZP*$s*fy*th-{0)J()5H1c1wdA;xLGteopwHP zg+^u!Q73!O%Yt&tB#wMXR)6HZWW{71Q@jr<5CYsN9`j2fUS6kwu)+1L6 z(3ELk#ZFC;#D}kTNeRvTs_lIwY%WP0W#@?^-<}tzz|aQ`-pMxHG=Ts@*nju z^EJGzOL^J8NBb$stNRV_(2#GaLly8!Qr)iVC-lLiLDj!Sr`_P(*UWBBS4 z>EAD|woX>tIQ%f7la+TzQc-xGZsF34t%+Fv5(kvCEYNxhawq|!GCAAjcl}}^L383) zt8ov_f+N2%>l}LmA-A_1LgGYY{VMVe-oc771`?=Sa_ed78{x1NGK)c5JwWaURyQIq z@f!1_YMyk}i1TYsw=dJz-7lOlHY$qaEW?D9_KMVROLI%%>c2iVXJraYaxCqQ<+(m_ zrWnnR4iG|9?S#IXjH3FOBl2>=$zM%>%(!$BjjihBxlqfwA%)_T@U4|SF6V}aqv5P) zvscD8;bVN}jmvl$J3r!pjnUYT86d9)2rtnlE+s-2FN=?z4 zT{?4qx6HKS#NJ~S)){6q0G4D~ml%IQvBDo1uR0q=yR%d2e?sKQXY!9H;feQQ#uvu0 zF1jPo^58jbEEgmHEdtSB!X8I^>G#x&NE11b_@~TX%x(UW&U)^7L`2=E(s3~`egRDk zS+~%+lCXicNa|md6$_2|65L#94cmOO6k(vW-lIkAWYN|jPdDqdQib9%z*X4iEMFBX zW6)*l0ZDvSb?hVE9fS2s5>lK09Q}3yifvkj=d&j3CjLQqFNi6G`@|}+fsOj3o#T~w z8CM$HOns{>s_TpyCtG2Wy5lF0_0>eIDhif^T-bgBtJ!HvX}DodI{Ct+fK1P=8nVmp z9ZJ6#e&y#cjIq@erQ4s$dd%J9`A%VBp=U1Gx9N=xK}dsF>UpQ-H3G&OGGinUMke(x z@1K?JU;86-p7!^1fVPLmmSi%<)64cVd!gmSi$df_ttH+19kO|W0WwKPH4M4Krp(?_ z$@Hfo$O}_#8KwKr$UgSZt~Dl7@J`OFPMdidA>Y!9r6c0nz*VIT#@qos?3F{6T4AA8 zAG$2mbpRPbrEPwn*eucpWi zo|5k@&-7Kk1f)&(!_wk4)ZZ{@(oy7+%{;W1q5cp9;RHEdFL*wc^0# z;n9N`zUNEIm*RChw)Y|LWW`r~eLE-=Pf<5t=gVoo`R5~o0RxNOlL#^QXBtgv zY6q;PU*YIuNzUjf4?{L#0~4*ahj8Uieg4RS zKuftDnXlK+Ey+oZ<-~=qf+N%toLV%GvwsBfprRA?ynEpF?@NDgge7-k&diK>)UU71 zd%_MC%R;kC{Gd->zm+48kTf|$ypL6|7@>lnl7Y#~MBTQtqw`xYJI-s58&s&nI7PRk ztVc}Xq6e%vDj3(`a(g*Hf4fg^ouO~YLg5ZPtdpv859hfe!0vUmmubG=qEM9MCq|ZT z#$IvsiFbfp4kI?5A&X$%V5Wh(ZgB;Royx<4tm5cEwVTKfE>jV9C0%+R8a5rrA1_sT z+AcuwcAJPjp8V_|9o|3Y*?&t8NpuI`S;x)CXsNAF(-JPDQ5LrfE)Xzkm|$>errA`+Dm#y>3o<%+VgGqe8Z-hZp2?CgJ7{+}rN ze^NzTK$VmHkXfb0gIL0$Xeg)Vx3cC531}{Xq%MhQa3!VOBqZEQ0_V4W4?!CU4Tc;H8~4+cTN;TSsaL84auX2=;`jvv z8{-g8%Tpu3$7`Gi3{$!(w_ilFDt?csi|r`f(3o0105>EqQA~kr zLpk{YW>A;f5bz-20Di;dWI#Atd*km2*bo*0jUz}t6}TXBDGFc#2(>;d1kkC?N|F0R zCP2?`J0z}mEaIG0{R576V`306`axgZeD3AV!ciS>vp4;AYItC-;U2!hHH8fHe{+HT zb+THY3})4;5m4WH#Kn=X{j6CLK==VDXa?aALHTt73Gh^#H+y1dADja}_YU7|L|ykT zu0Y&?)QPbJUInWNN9ncg(BrT{{Ow&sUOj&{?sgzj!oUGSH3C_vBrN-cjCf4 z2^z5WQ|z*sA21j79)9Mh;qV9I?MLbThUUku?#E8zZ#5j8AAA~#`O&;A}d3XqQ=)bk~UrNk= z>rZ|+8NeuDbAcWFem#Z&ncV!lKd*68rY5o8(X9j_Zza%&ft&1u_${y4LUCMAJERo7 zmAkt;6C>0F5C9xpLEH}UY_Y;X;)Db(C@^=gLhAswbQm}Rzc0?l6R7$?mV@6;eJ+B( z)^*DnJV~H%u3wx#gZ~E9wLi_1-Nen`w!WW0ZUEcSo?HNb>|aJR%Iy_im=2ijQ!fs` z_v-Wag3BAau(yD!;py$1JXv!09KNC)QftvMM(KY=h_sH^0(1E>1ePQ5KpT&zOo;E?6<6tU z_GV<%swj%Ewo9Lzx;mM8vUkdZ`hGg#cYXDGc1pX4a}Ad+BdNX7;tRDXQ*Muz`#JOu z2U`{4svlq?V#4*#xMd1)ZtHj$tNS_Ot0x5w`3ioHaEBtEk#IWk9e&m zNkPsF;Qc`Q%<7D%J!pTf{u#omigS(f1ymNoE%Su~%Q)r*yT_;S)Gpe_=$RTxk}2@3 zeQ~tfU{}8GPdzuEaK)I;FI+Mqh0r8eAFV1gL?LRZj*lM058gQ)ldC2YNa>m7u~+Puf#S50c}7Zx@NHJ zrs#dXMrQ4wG?9tCFheoVdAWc(e+a-CG0K)BsfpC~FVw z?heF5hqjfX6I|ZkA$_bjj8;xJx#njOP}i4#p$8O(l^-qa$I~G`0qczP44&!v2X*Gm z*yrHF8ia6xwTgtJ2AC)+*+igD8rkAXd>V~+t;(0Drd2*{gYw4gC%B0cH^h>xyRf^J zR>umU%AATRu=FouDcEVSSR=2R?0b})2l1}YorvL&Xx_(b1j}M(7#W`Uq-)3@9|SlI zDc5LTF@>xsf@Xk;ao`LDA1g|DZ==iX2Q};Y&O^#?B9%B~i8s7x-0>*L_;9X#6gZ{W zx)_<5yrnpvLntJ8ts*`aSA0FdJ1KrL#z6DPYe)$LgxE;H?5r%YWvF~wyFGz~DdB5W zzEwLxb33?H$v#67VL{bJGqPU&m|nT1J(>^PIxB66rs$5zp4GNQ z9i6D<=kR%FZ*XpvZ$Q9(Xwv$G^vLK;kUv?eviQN@$lOx=-biMMFd&UMsc zdHlG%iOZhNRBJEV%-wuoGZK1z%E6kQT|I`l;C@KE3e^r}qT-J6rm*FD^uRu z`PQ=13bkS~f7PRRxwYcXv%$;%iHK%!ja7KM&R#&Ja0A1l)0siMG)F?? z<#gDHuh~y_`V4B`X#YzQ>RY>)KZrn2M$>7P5wO^n0=$UI6hCr!g^2L}DH)adA%w&u zY>XI^1uw{qHo9bqQ4DOxLnZujCxMQvYq~e+hK{yjT!gg?WfVF7L$`Zck{4@A?DhiO zf@i(+fhM``^7FEci(PMe_%3M;U`eKAk$%NaIpxb;ZR_}0#9@5Ojeo&1Qcp3`l{^WOyv|93wlB^vDxM)!zsVIssO}acZn(Ro)6E3f19zANjZ8I zw%sxkfysS;Hqir;;@g;*C6R3dSdrE!p^kir&duyftI3+leo%{`Jkn1(y@2GSs%i5A zpi+>vc-bsD9=d4ti+E!8P4W6ua(lQm0BL41?#@z%v7twR#dM zdipftzp_;c>qw;`E>JRW@YUF3xxNk&RdG~V1nqhy+7R*H?Qw$4$~+r`eo7q?mKp0j z2`4cx?3QoOU2SbcQf~2s6g{-92*nO}B;V9IaSWR$OQE#@!=&bo!)6D9fD7*p`wnmAbI^ksd;Cm+gIWT*M z4f(sV=J!rSvM?F75rM#!+-unR{a%3_F%(C|)pcVr?*Y7FJ+5?~PkUtUOV(-S4Ls4b zL^DkKGO>IpSb4X`k2{XJsnqs9Y-}d!v%%zZmndeHMV15`GF#bggPQxuH0L#9&$@Tt z+f3+mfqh*-!3$eI1*y%d`83W%-M4rxm)u>OrYWj(Ug$3#!v2+GW;yVB9BE%4f$%;S zEp`FV=`dx6mm9~;-&T@`9V>y)mcTJ2U3X3`1IaNpstxr}g5V)S&5fjwpTO^&Z|{mq z$u)i_?=mtjfX!FpEx}jHGIm}NsV$%pB1j!dfkmw>ig_are$k+WQQ+~c#4#-s)nA$Z5SMqAf)zx!-t4`Xl%uvYUWC1lnpx5OqWnI5!CemWWmY1HF@PV^V&b3t1 zdVL&(JmBLEXGPjxX=F(&57+cLK+iL+*_$_;VklQ#yQC7KT*A z%54CtmPFSnx$>^O)IPpi^+%t$3SjX5A20h(f8#?fWua^caVEXFtlPJ{EFW1=R@@%hOS(^=m`YN|R3&!y`34iOmFe)rb6@(m5sOom7`2{5I)m;l#DU zt9!rGdHxx-QOvFoyXk5dUu4~QMyAA?wvS<}i0^jm@IRy81y9AKlz21eO6W59 zlZpusY835V$UMm>@I&J16b_?6>V&A{Q{t!2(K*RP^i&lzAZrO^`)+IU53bctAAn54 z#^8%>S4+7X>J`ai3hIg|faumd=YvSJLBfFGoT;Y3QszaE=Ya#ci12JFQ2~rKjSkOA zE!c)GadIS07+ZGHuJB%BU{#;SviEdvPI^Zp7oNhmo#=c^=Emm^cRxX*ufQWk}O`w4A+&#N;bm2*f$Bx|+<6JC9sZhzP-$P9pNCjh)21Xj>>qTz_f}sZ_ zeE*bHHwtp#x=s<|v+fu<)qb#nft#&h(VoAT=|rGh5|z$Nt;{Qm zD|ysRI&O6av>>Md-xBUN6%aF=+5h>@Ylq0x5|@tPZwo|eyalJj+{nT`vwIqKjE92E z&+_oA+4^yvA*`20nN#hrziXESzY3R*<7rcmQn;<>K~lx}iu9C~zPYTkJoOf{06G!B zS(bg@b2p}7ziVBlvwU8c2CI(x;$(v3DSad`KWZ}9z~rO07_E6SQg_*CE=b-#_me@1M0 z-9Oyd^9rP<8I0n^KBuaJMQ(mvK_e-9R@z({1Q@E%IJ_)s`G6?i*zwnTPA55mc8)#z!aaTQymO8C8D7d1Yq~WFQ%+YFc0T za8hTX8=_Mmt?`d&sS!v_V)_KOxQQcSa|M4%O02PZq0Wll#4Zhs++{-a@y43j$Iwl$ zUb;F^#i>nXu18)bmF|>5uwDX5 zP^u@Q`{VQYy)lqJj&r%^t}cV#V)&00$V-|M|3xa#nQ*t0$?Ht5+~7XqO-E4JN6YEe z(nN=L=!#6WV40b@@;$^DR*!g?vWMVvzwPtw2kzE+lA0#{9;g{(d|J4qOEWQkn z4ns7C$hh>$tfWTRh=VK;h;*7s2x!1@VipL-z&fNEcTxzM*yRb)(JJ7SZHTmMTJS4i zFnqNu4j*X;^yMoK!O_!Hji%( zjHHI=1dH*j7w}+JL9D2BPm-Ftq?XTj9$aC+a5ndCki|}8a>oAfgS9}^bvsJ>HBd$z z$JfS1q-6}6yRn+^qbJ=9VD|=VNObV6BT5e$)X^yX94&zuY}=5j_~p1`L(iGe!#5qi zA%`WuXcQ~#RpoM_y?a9MAror>JzhmBfV1hfHN6ww+_x@62QJUi(9S+ZX5A{P;@^$d z9l~AHC3jfb_1%qtGf^%)d&RgW8aX+xbLKk_^Eo&^0D33$x^aIl!ipkaRcMi(py4uq z0vc!~t}wfg;GwNNmMRH(V%+>wOj}}KY`P;851K|j)eej35_FVcSPKvwzG-Nt^jvh7 zoW@Gu=JI4b4eE%76Bk%S+a!ar+kbvy*QMC#7RQ>I4`=nbHo&=}weqRkc%&c}n2!Fm z%EDV+-2)-FE4E6Y-`CLN{m6@s#-Vf`9PG1cKD5=4zC1^d6)H=Kd~IVii+Fn3FxL%f zZ7com1Y;?1cAwmuBmEn%%+=XNRH$+$@I!fAXM9Z$$kM|f@Brmm6D+m-aHcjCuW6EM zfIE{BwdjU3XiqX5Xi#=dmAISK;2(9d|8zgwNosvoJvg1BN8UJde#!EXybYg9_P#2g zik8OsX*qx0juiuy3MhEhVdq2e6X%&WZV?V;>{8o28(V zGYR>mWKUkxb?%^Mtl^IYwaA+)2Yv*X`{YBnD=hZF@f-qP#Y!l)i-$hp;cVI*3{y1^TKI;te3?YEnR`S_xrMT;`Y#qpbs z;>0*$HAj|A3{>*{bcyxpsOK47hkGq&S}G#Jtpa6`fu+}m>PouL;?#MtMg}I z!x=?_3G(oyp>>dcLOUTxXrHKc%=*{Z@Po;pHPZ3>OHFi{M@!&_$JZpAG)$;Kr^TJX zPrRa@4u#=Do@74=QFfj?jy#RWYAd6yK2PL*vl?@5`0 zrPqsKyxtzT#HvhrlcsNVhCj46jd$%c%&??GbuZ()k7Kx~&QgCll-Qm@-Woo}T+fbN z{rqh?o;W!?5MjXy6yFl5&I&GZq0;ze*UN@}w>{i??DOgGrE z9}g?e&`FdB=z%E$`*p?=j_AAJ8Jd?G*l4F5HwMp+8|Zr>GS#8XOs?5#g)g(sRY7y6 z8|cd&p1VtlVtGk58tvMcJ!P9;7_*i5WQIp&?; zWQX5+9r%u;>WH5t>yuIlzo}^Lc&>n`r|lzKX%xIknZ+}#Y`=MYK&0ukhXH9bA16ti zTT{G{Vt;rSz=9`-V5l53lY+B{HgW6^AVR)u^RV&i3MON~fRhV5aTAr}z|Xw-1QUHG z3$=LgqcCm!0YZm=ETHFN_C;NJeW`e&Rj7_cQm9EUy2}>y{@ZJ3oh9Y4BOQf@igKQ( z_53Y4?y4t1PdiG-iJCmLCWzc%;gg$K?%q`*T(lSb?@~RKM8-l-AkVS93U8Z zAayoM2qVGTyY`H7|M~x@&whLc^{p(b6c!hd>IC_~)h#Z6R{G)yp})z6k7>ugD6+J9 zdVi>|30q1m7O%~9Q9?xWTZ>>(M2xkbsTO_G{-{jl&TA0Oc%{lcch!nf0 zxw1$x!-Zra8M_utsl{L~ zRT3jMoV(K^C?Fk-2?pBL!lGFnVEo|MtP<4SIm@@ujLVxZMYk@qsvwuN)JV?;VxS4T z`$8O<)NP{lh6d8z82K|n)UNs3N(GUYw{>>=-u1_tyA_RLQ{q6M#-*mhbIn*`nu-_o z^WXF_VX;c)uhhb3D+%Pxb8H@#g*7qj60TTH@(L~!SJwOCi45C32B;M2NQz#Zm&+vW zZZp1QV%vj$J|@`jS<5`8xONYZ+JArA=!H?vhcI_3Q)I$01WB-pDXbWL`LVlgWpL`d znmfu@=?T$^3Qs%wEh=meojlv8E-X0}rB+i^#OJ8y-YqH$w&wL!{oHGg!V<@ZYQb@6 zUpb9i-L9S$uZDsxziZX9=`c4Jp7cleoI8U9!dLV!)Dc{?&5xgmG#y>ioF>`W9?Q$^T7U* zqa}JH-Yzvgx#t$xc)UD!qtw1PvDkAa?0y(UK(qD~(BQ=m+z&BTBiHc`H@0Y&c+v^`<~4n5q=_@qY9$ zkPl$_M2z(~t4-jryG;yq=PVaVGd4L$p$-qpFRaiJ{P3r|l2Nb2P@A+@Na15YT<4JN zF|9c|-jBct=no(?y~f-^M}bzwBX5UT*1GyNiYpP=gXIaZP94a2LwW(_ai5Nj5-!pa z{1}=&&%?QGw?eqQFZ!WS1uxqK+?I|l;@3Y*$!kBH7oZ^4{lv8716%1~;@=@;)*U*x z=Si}*E_%@?kPox}nUFMPeyAKwhEyxfg;3F@Rkk{;k}^tg6^QcE6scEH0nFibd?pf} z%@xI!MyrI&jK#2Q_CxORJ5LEa`ES&$e`yLMH*mFjs zk6Iw_^L+pjaOoe@=?}oV61U0!M#KF1UuYO61~%sZ@GndR>}+i8|2g|_8is>|`Tysp z|6hXBlYeO#EA-N{YcNo-xamBhvuoQpKrjr;@VpLekTX&KB5V)~5RgKWLLtF+l(_EG zyUc=<9;>Ym)2cL&mxhNeFF$;q=ytS@VA4e#8fcf`I$)00U_eDGrgwfi0CaSCaCCGw zFrF?}5L5VXtr&qCXjg|2e%uhhg*ZpRApI963xrEu1<-Q{dFKXj01p6uUxQqK26S}) zj7X_dJCV{z27atVxH^zhdjOQY7=1MuPs-B76zIWqFjxGOn;rl%Xj1@radH2v5)S@; zz)PSy01hB!eg^E?0Uu%LI39jzOF+PZ&Tsp^$5k*eC#2)U$J^Uo0FG8iew|8@v^4-c zgj865LoM8fJ=+YqM(K+aSbJ*Iz z)gVC2`f(fvISg!oL-RKwMB^K%t`_jNAcALt2d|KvvLJwZBrJg0-@)#=QBYv@prlj4sB5`9Gt#bD)n&eXCWb-e&mPO%l_w*HkVjwSi#H=IdynJ(NZiE z%~mG6%P$jTs}Fjn$N54Oe=FdZG&F%*>`|Jqx6Woix|AF=C zotY~OQ1QXk>x)4Bo0uLNOFfDU=Wk z0JPc`^4bQ#ugk0J?+?J%dm|@yPB2;{?8~fb-xvrK{5}5io&P<(_O*h*@U@O$+MCm@ zocB@y4aV@rbvCT+t&R4g*ZXth@ndoChy8%B`<;{cy%S};b$R9ISlom19TtQ`@T}Xz zaxJz3>)HcGHTz*=|5;Ox_gb^10;napiSsRms-OGe5@+Ao{BuG?SY3}GS6jphVruZP zGWbcl@>XZ{j38Faxrlmya0a9g?&$Cpwnd*Bvh{^L_~c9DM|Au3{fVhKJO^a?W;ECO z_6kUVjvj|T?2~aL=M8|r`z5Lw$m0jcLlBw9Pl_qxyr8?Ki3i=f}MN zf&66(dWZyKujxyOXu8_b-_T z<@|m}+5H>%o3yhhfDg#w2hul|=ob1*ZlC*yw5RFN?Ou!^`zLN^bL(W+`N!4%GpDl6 z7r2KD80s6+_hINE^3%?;cV`TLJNR43SLmhe*M~KD$=H2w=;0f~=Q7wkcC>@~c-w4O z`}p{LkO2Yn3Z!K)Ey+V8%4=@QtJ_z&M;}wNI$|Hf^=&xrRi~Y?(Uka! z*hYv+x=+~`<^YC2R;4U5FUMOGnF2*_v0s&WeK;63-58|rYP%NYO=78j4zN2`izrrf z=x;opO_D_If$Y$C^Y*)LTE2`c;0}hJw4Tand!XacCo0ogQh$5#0qLk71 zsL;n;*=MU_>5nj?L42M-HT;XM(lh$qydE+KD3(!>;QYx%ca%pzO;o=a^LW+%Qhx64 z9Pc%O+x`m5(&7}4u}PUc1U(`XoF%Mwu~^UZ)b@COF+Z8%%1T|8F&U({;m@T79;QSV zF`eeI38(%rLYrpM#KHTfM3;60Dv9Rfz@Y(4K<4jSC84os>Eau$xFy31>*wWMFk%3KgMno0F5NCR#f zOK!tJAe)AJap5gUWe&kk;qMfycAnGHoweI@8}ds(>ams0m7oRMcnj3HuSfJWd<9=m zHrvZ5iKnmVS?Iyab7g{omb>vwMAsO~lI}3Oa%))`uVIP!v4=FM@%K`b^>P+xS=A;Kt9nj>*SS^x?}FKkTaoJG}8Id z^hn=+VTRZqhjj2_?8z?iK|S7UeJJyXOxX*p2!aE1(xSRz5hs_rHvK{sBZ zXm$W<^(t}Gc^rk4S)E`R?n;mM?Gt5lZcO97W9-3EdFT1|9|yHa1TNhuMiPu@Eaf64 z_EO_uHZ;v!jMj5Vr5a&p$yd+FO~d8|u(DMlL(LOBMG>;Fmu4zo2SrrsInGpbl7ATX zjP55XXbgn8oHLsfa9k#IOtgs#`b;|Fij4g_VBXeV4HY&|>!m&|2Yqob`^|FSK*iA6 zi!5#?VSQ?mGm2dzU!y}^N6M%W=&IOkh3MBpF{ta{%j*ft4aKUod6vQ=o=2$$?pNHB zk;{7L1h!&Y%rkxY@Y8h483Wlql5eu|-wE%VZ-4AXBaO`8L9GO-S3XMpM=DNgq_Ox~ zPgG^OatCa`)g;^~|>nH&tBrN^nXg7-A<{s6DX+ zS=E@jLz{Jcq!Pr|H3S(u+b32j@g(3biFJ=GZu>YC6*RrkULP;d&n~$*X7gRcK=L_0 z^&fu|->f8Zp7MdLC(fc-QEZ1A7RO!YsQvwqK{OY`72EhPsTAK!g3Zhim|Hg^Mx1s)TR#Gg-oB^yu=p*PFbLCO5e200 z+KyoMdgmNNai2lR&JgITiwjo7R9zL5N`*xQJd(?xvk&VcqvW^;Iv#-zvqSr#41Td6b|$CEiwjQxqVX(h0hwOL+6FZmiYzB?mvnW@-DcEen0YyGbd+e@P97c!Ciy#g& zn|DOiq_|=^podAT@M)ldA*)^vGiLc);zm{yC~Bpn1h0JMv6#OxwSHxEk6wu zkkw)U3h`yNIyzmIbs1V4seLYerZb?PXY%n*t`6bJ4AdtJRQqN?@taw7)7qiYZTOcy zrbSZSfjnp05JNa`tywcfthjy=8yP?^lvD#v=C7!55Pz1V`ekKv78U3V{D7ul@1}Wrm-=#?D z5`(7a&B+9IM40FtL2$#!s~1sEg{(IKc*!EeTrsT zsr}{@ms?rg6pK~vr~qkPjvOZ*O*hSA|IUQ+g+)p-pM@=CZnA_2VPFUV8LhLC+ilM9 zj-GeO%Om_t09T;^{%`StyETLxRP>2|+KZHClRS0>dZhA_>5O(Y zmj%6df8dGXp~@nRkGGiE!zUTspY`%uO!o(JlP?DohaD$5w-%2zMyLKhf}PcM03^gQ zrm{T}R^j=g&A!RIPkO$w3$WR`yi>IoknwQuL-_CM@0<~ZgD9xUjxCRt+|lKB`@>#= z*E7^!lfU4}E&BAmvF1*w=>#kSn=XWwYkP6lKSRYai0?`bR<(_q*utorgk1cLVOS5| zTl9JevZd?RMQp_btNg^q{BA90Cf1Z%D5J2bO|}UTSB9*N#TQCxh4NtSI(%To?(*Wa zLgGLJFkn?#OXLfGf7&%K!!PujYhT_ zhfcbp!HhBQz0vX~7h|p~!rB%j55B3)?|v5i*yxE=HtF^?UPJdu?$WH9D2We>HYH;j zWLcW34z?cj4~)^u{A zolp7c`PxHuT9r`B?h0Hg_1)@q;7e_Sv6ABkQ5=RR(Da+>cK2d~;D^R}QK0PhOLj?p z5lMw%`d9^j5oLX}z4l6cQ;znY;5R_-`r+YGQ6CD1^Pe41mx}+Ml@z|Ca@zwEp#vhj zT7Hru)(i zF#oh`%uT;MPn}OmZGHejGudv{TJH=Pu&mg^%6Y-Ed44&OYlH|Ma(T;`V*l)3#_L%# zqQ_%v*GXATu(e5voF4HPfJ2j38gjJ~H$l{j8WrLFmkRp{^R~$KAL@|o^$DeNLNl0L zBZegLqc3i5A9|C(&S(kN2*dM%b5DRx>lTl7+3l}e#V&?uEv5RmK+UJJvEK^r+TFt9 zeEf;P-W!NCE7|8Y5Jt)mV8< zbc8D_-sYHL5^`Tntn!p_+-x`0wk--bnoF~ecEL03KJsS#*%Ga8qXY+En~SUiK25;s zZK1M~srd3Cjb}BBiNI)gv2}mXheGp0%qGhP^g>P|@JN1|p_}=$+)@6zX*MO6A z`WT%F{ACW?U+8~aFWnDvOZErS>VL;3M}tBMb3uI(IQ8M6Y7lLz)DJG%KLuS!_mHmK zjQxBo1({eIe_H)lN8*%C)+gZQ#(BhyEdpsS@DS#B=QC`N+xTMn965(&2XDA2sE2?} zEgg|0w*G)q77!R(*m42@%=LgbHj?Vi6}E7H*WCH>hVl6rt(kfyE&Fc|6*)?Q4z|7J zCJzEfWNpkj8)||D+CIx%#fGLe&C!xatUoPmh|4SNSf&vFab;$Q7aL?OxUAgx#uUDs z2eMlg-ST76WO*G|sCx7iOvc?&H+n^IJZ5o{0_eKotjePY4AnUt5BIG3dtsqkwED!$ z3Le?0Khem8)wJiI5s)t zf2r5VO&^dW_$rYI_{Tep*V)|k-lw#%O>ek}JX6zhjX3VKtz#)==7c$nE zTC}=b-(_P+f)~LBEw?-bj=G!G4o9cd$}sAvagsxGGRg`pJ(06g4cSdV-n}gBw@JJE z*2MsRTrKp?+o^ikJy|b8M%icaGO?)#3*KRNt+~#Ms%_@59a^p3=^F;as8&`EV2C8|kWySan1?80xBH z6aD}6q!^;1S@V}TBJ*i1&Qs`#A)sF*NHM=~L)CC~+P3`h#N;s#O)6x#P?APLU&XY2 zDq{-Oo7~}kR>1hD*a&?wVs}->o_{^bkuZ4zUMhHNwn~*eZ;PLjUhzzD>N-<;I46+= zabWEd#vqZg3T4Qz^JEI|Y`k7OCyOvX!y}5ISGmM|JI=w8v8hFY3bp&aX7j?Lrkl4Qky~b)GgSN9!8AEh#JeoLAhViL~0qpl=3sT|T)#KC0^tR^MwMk#hSb-+esf_~xj zh?<2{dl+3y7n)GcW1>D9sO}n46xF&N=^B_llKU7x!njPWQmwK8YRZDN%-?tB|Z+GXAfj;sjQd zPyX=aT*H&m+4+S@%Q0R9GI)S)moQqM9(16Q{C#p3Z=vTQCbv*62nP$~<{04gA7FcT<^lgoB7##x+|6 zE6!gDjx`#VnJbNR(*^XcY2nrQ(Y9m$peQ2#KuTHI^zS^*{!{&kS7XO-TMjdv zG?hXXrT(Bdcvqip+@VB@zoJc=G)lnKlfA^ich^ltsaT$X9q=83oqWR(b~G0vv0c_m z(6?xoOLAgKlwras6SlK(|A$nxv;Q{&79IPR-6I3V!9rP%O&lwTRSkQPYJ$Ta=SiSlQ7U)h&eldN&2V#aPTr_o5$m&&b-mm&+Nbd zRNZrr@MD+y_}+En<{&e!>QT7Vptfp|P%Rhh+qWwvN=QY-{8AVN5XvwzJB78&W>bTw2L#xi2 ziS4<*T}D5gTUg^2uqlZr3ia*D(xbOcdSB!5lXSjt4P(ffdJVl#px`)lt(vMg*L2VS zPt{k2tM@ZVo)6~r61Tu{b?d&QXU`gfEDO?IGucKHVNH7^grS^HWZePLE9A}hodD-w z>xeSJx6_0NP^6W*Ake||u5Y@TR6~~h%fP*fP#;t|a8`_ty7N-_n%EIHl($dk3}r|N zkd4dz56jwX3RGv`uF|0~f%a^F7bs9tZ?;u=Yt}*8gtnPgc%L^QZFuiE8kOej@KF6W zy~r7-KH=xT4K&|#Io;QEo#Umy{6(YP!xSpByh!y3_vlnTe6I`C`|+2Xh&+$rBGcD7 zJ#Mv*|Yu&{-9Wa>36`N*b~*VV42#i1+U*U zVR>_hqK#%)p%_>=NS8y>?i zA}(-R3#on9c$<%X_;*}5rDyC6zJEEhP7ejf6sj5`cD>9y^8biX`Fw9&>O$>K-9Q(q zbWe2Fjk}j>SSEwjPWF2C$g(4zQtHDm9|aNWjnTqCv&`5PjH*{F)liwK%4=i{DypAB zn@HYI+9zg zBiSsmxc7z%NYZhKw8O}bpIW@zZBh~Rsy)TKSUHj_Qs7HwX3*T=`}Y4*rB+pZJemSvw+UlkA94OpQ$>>`WpqlD$ zdZhzrZV+7T+3w>;m0;1*(aw^7yRm5V0#>EyrVMFni;y3@L8js>Ua3jMF;r1Iw~LC6 z5hKQ1bQ8ivO!+xpD#CC!1wFKh+c1+Fn1}Jry*mWkj^aEj>a6+G=Bx8ZHH%88@xAt4 z7s?HIMFC1tZvC9H^TnvY2LHq&w-h5!_cL+wHiD&qWx5DHUtq;J<{)|BclxtN4t<7s zo-$T1is!<%{TS6%7XFRCOOg`m*^8Bugs_G+ug*jeE<%y-_9@TOYu+hn1=Ufl@txeX z;FkC8vbYE*h9XqKTz19@IaEFMi9KrE;lTS^p`5 zw%vwbEhyBQiV^JDU_%A0rN|3?sZnuz^A<~vhfiJK7r!Z~ywwUrTz~?DjfmSO zZ!ObKuuifLovn35F(qiFB6U;0E+5a(Eze~PMcDO>N`AFU#z@rVBfRJjLzW)F*!fw} zpKjWu-Tyw-`gd|Zhi&Ms>yv2m1)?N7-k#|3o*CbCp0ZG6I@-xn`usHUa(L)| zlnHWiisd~$UWGDf@$WdUi%A}ucRAPd1fLY=Kqb6xsdnNXc5_e;B`aJ7?j~P`lzrti zZ8!cu@ovxaPFE&%Pf`wN(D=>Z*2$pWX)f^<>ZXY5|8PPeUs&1{!zZ?BKhhAAYN+EZ zC!Y9)JRR{2A3|)pWonwdlc(yswvjg`h%{#d; zVuYiSFJN$RRF!k9o%lY@U%^z&t9CLl`;^nS?O{(uKB+$*=hdSS6b=GHJ}1 zZFf;=Fsr-WAvy3X2No@v>Uibo-V>A`)fmPGHHgOps1!4d8V5Wq+Ka(GyPH?xUOO+1 z2sM&*?$&8h&Qy9muZtA3JF_xwp1);b}Qf)YN`@HAa&0?spa-yUNI=?UFz? zTCvClp60r4Gbm;>vM4)d+j_7Lh90e1#F}DJe%Fh-=J}bS1bd29WfD>~nm)=+k7lu! z;Lg-=(r~RYJ_uor9Z^vecru5uNrXWoSWJEU{N=pZ0ZXs-`&oz_zlFp~u|(sTjaafX zOY2sGLz=Xmo|5h;gpV|pubyqA6sStM#Y40W-Cr>vRHYh^7eN-lufG@{@vMC(BCb`A zQ!Zdc#5Zw3e-NN)BtsKK+`PB+AJ)tnIC6Bl4zQYeqCTXj6+YH_BMPQvz$D;m381;R zx~bh)Z~2UWM}B=6OyipnV8QBobT z_`9TY?!cD!>``mKrVh8|%5Tfs8M0Li1;wI{9P|kvY(;s=T<_69jRQDm41BmV18Xin z)Tp-3$Ao+N?ohI;%F+kXl~QAm4!FdZjh(7lYwFf3kk#F zRdtE$u=%3)t{_y($CeuNj($xCLbEh%pne1!>kX%M1=&R2HZ2!YcqMQ@yIrm>Xx0m+ zqy^jn7QcV7`UK8EO`U6}SlkF)T7{F|eImD%2rNm;dld0^c%0Tuc`f;(hpN~n)w%8N z0T<)D-hGRLxw01y^vnxrwJg9H`qaGD$Y5{b)oH*6ZPiY(X8KN+@xNpkaVI_@{Dr^| z;6ZgclX$759$P)qH$+?=qJE_jT*JoGwuV6cHl7m~n(|DY+sUbHh!)cemPO{Yrz)=J zisZ}f(ymdJEZ~cB7Yb=|HLYII1r@_&tN;?6i8gd!9+twF>ZaizQytoKHu~jynt@2X4*Y1o6LafJ z+V??sdd)^0b$sI|PGSicSY+}94Ks2^YR{Z)*FA$nPV=-zbtgaZRK?2fq$R&vxhB#z z@jwGj$mC7P94bUvLXGZ73(%FX5^5X%gt5xQF#r&8sT`7GS%$q%uo>!U@j_&wxV5J* zM)p2y3r;?^#1v5? z(Pi}trd%>ynUv5;u@#-gFosIi6yZ$^>TXZ$ml24lSNg*l0$E^x6H1uE)qF$5A=MN6 zlerCP(gpfV8dabY58EET^p>!RK;aaWB~^v}l1c)L%wEiOeK5{T79_VYBfl0Q(Y_#0KkgabY)B|9i&N&uzny!M=c=`nJRU7D|6!`dO$NMSX zX;oE?5{kst75~l_oEsSTJy1}DzBY5aIrjI_M0_<-(fw)F1@l>bEeUYDway^7 zz6Aqc#}xiog^u%oROpzw+5az~6bBn8_y4NUadL2S{J%V@|34MFR&ce&Yg|r+=>H(b z*Hpkk_HNKpoW)5NvB0FQ4f9g4G7+Icp+v;nc_dO1Y(+#Q$sjT^-K+%O`MbY>+0XpE zCVxRq!`1JOo7?s^H+Zn4Yo%5vbhHJ1Atb1D5GtE0TpXBSV552_BsdI`!vhwv_OAY4 zn(_A7eJnbVu+)!?C=v(+_pyo8!W%AGdo+~7{e2K5Gzh3@Y3OL#paCFaCaniTQ8Wpd zLa=ACHQ?qTAb2#Cc=AIPu|NJyP>_bk-IGyH&02~ARz+-1EF$SjL1Q*@rMV{Zls%dAb&25`1{aJ z-~bNzxuDL$-*b4WQE(0wZFh$&F}6A-97JrEeY zC~;z6?jI(sNpyJe528c_Am30}JRs$HkWSyON6P&+Qr4ZJJZx18}=NcgV`%n#aO=iRGl@f?t^9;p)`lppU^^dut8 zXAt-X3$eX#w-5bS+$=a4h!<=c-w4)Ih-hNA_;A?ia~Dez7;X^P2w{|22?^-u{r%G{ ziZlx!=KR3b;pZ|{SmHy*vl;IF=ls1+Lm2oN{%*(|9SH>kA~H%EWSDFO=;s%{7*_m? z`p_`{LdqBIKP^B@JM*_{!zm%k-Iq49K|jFsywGVY4Ag73!T}fqe8|Z#`1fDv@A1R$ z*kgh6&#l_;Zn7Gmo?Za<-B-igFP4x#GJ^m>>mcX^cLY1EvjO{Fj|Q=-0r|z8!yX z=o!#*aig>)GER!`RDywo1{^FNFompz9?H3;fVq$0`ZbcYYf@Z*dm1b>=&r0a{7)9* z6b#}w0in%;$#P3PctrUz115g6=(kK=Vo=FLa8+JP4Gw6;s8GPn2(LI)Ox#&AVN;g3 z{gsggR7i+y68{vWzvT?EUeb6xAip}33W)4i^$9l$SP14+3Is@nM=}{G@xhP`0U}Us zHi-zR#3w!!nCRIxG^WBmei)eO+BI~l&^6u(n+T8;iUd>wh<9R!pG|@SGV_Xe;>XG( z)k9nClS0Wr^oe&0P@;ni3M6J?LR{^05hm92(uG5V@C@4Q`jw^oko?M-0UWo7fUJMR z9>}!(!iqaLTp_o^?h^(+5ZXkPBe`pCE7&2Y?9W1mksaEd&9NG~AdPwS- z&`u1)_OkE7OanAO{)3S4F}2HV0rZKuW`9BeJt%ulj$E;JJ|N&Jy{BrQ59#q}BP-(h`}TLVqoGzGOR?zU1q>~9c459{dX3SbY!LfYokHoL zO~;H5iLi3jVe2C$iHxY-$(jiw9K<#Zz&JwYEt#(;*u*0P~5ISM;cscBjZF_C^eUZ~g20x>}MV0`a7$)Yx zkPx@Dto^Vd&;s`BHQRs48wDB1C)CynNGQ4%@~?_-;bW*-pdaOZS-Mb|e)AFw5zXI; z9g#^53>+`LVO|)dW`AM%XzG1Sah*M*i?HO8uY?0!a0&M>1ciSX0(Z~g)~GVF#^@&8 zg37EFSn5BmNzvuubelq@%G#mDH$j7(eg-CoGhR8v7&vwqnaR~UQqn$`Ahk~DdCvlG z>~;aO$M4G?Yz1dQz@tTVReQk8O&9q&yNw;|+_s%kWXPk4Fm2JHCnbX332hdHr^svl z9iP2`OEZS%SNPuKX-U)(s_z5Wxw3Vr+sED}Ny__zU5kRWW%DS$3S2GrxZ?y2F(;4A zVL@vq2TKjVSRKk12F`YCQVHSp@|)qTIs$gchrZQmiitQdS7=-;&6#t7$JcJI`F)T7 z49eBffdBNf_H2a8syIg$OU<^2p%;HR*4O4OIOYE zSF*w@rJgDS>xd2120m|a1VMfq{JYRYCmCwN2BqW)mc-@_feQzJrTJw!SvQv5R*`mu z_d~$6F?LLt(HZ$Bt#QwDtG5yaad@0)XHG{+9gui#w|eS{KODfZcC5I*-&}-#A3PEA#{SHm&~@^Xk&9Bh3I)BKnI8Ys{Li&zyz|dS141>u2R};2 z)s0FKj+jOwDp znubq}njpn3hZ9(ptd#h5gFI7slM(4*2N72y<@F&jyYK0;%c9%SQo}e`#JVzdUC~q@ zMO`<|)*^>wb;^rFM{+k4O1^Bd>oBd6!5zwCRbA`Ot)K-gPz_>QJk@dwN8; zmb}1HSspu7ejcS-bIblXsMR74FkTe}fJ({=CZBZFl&Ci%>{=+SC!80g~{T z?kPU7u1MciaMffmkc&oKu=I$43*z+ojM9k?kbf7v?wcVTvX;b&m?pymk%mJgR8^pb$ zXum^TNkR>)KQPIVey5LDd7&bYAl4MqX;3z>7x&IDtF%pZhOor9ZWwJ!jK^(YG2_(Y z$1w_LwEi26XG#Kzh8mRvA4}nV&BeNa4ivCSi5&%O4-DV&-yO=+jZ`SD%9sZ)l0OBR z1O$1q$&7mB0e>&vg_$m8X>SJO9C{T=VehU8>&CZ&P3GLKuff@u)OcfuZaP>{NMvZF zf&Elzj$VfIJdf(|6ZArpDVw3Tv9fnpr;l@yH{5Jr;wRJKB%#8P7O_Ir+&t!ThqclP zMp94Yo4PkQ0^FxCA$Wb-Eyk%Puzao9*Mv5tBosZ&f0DJ$l-lZ{uhFAX`V?LA$V=x{ z0;nNw{r%}E#G^?Z#Ors4(wPfUSeKh`swqX@hR_7H>xC<$B98?5It#rL!UU+Ie%C!_ zrZY2zkyQ1Nz-<_64YHhM80v$`>6*Y8P|eSwUn7_6(ck8uxY%ys9HpG>z_h(}%(;cX zgU50D$_I}+O&e&V0Du4TOxns{>8$Gs6rkuad)bCkQ}ge%FI`_Znf{=kZu(6d-@>0u zQiAAGo_2Fhvss11J$D`dbrp#wVUBNutEvvEa0EBljg^{QNjpO3mN6KQWR_R&<^Kw= zw5weK=caVMJWqJ)osH?&%IQ+9DsOmxmo!|Xwo?>}`BX*+)dNGLgi@!SHIBab%4D(> z={;tcN;*?&cq^rZF1!511y2GYac+8K*eT1tQkeC<{+cYHCAF*DZRe(7kbrCIab6q< z#0%Xvn?E5aknj33FLNBt_|f^1Q+dCN#MZ^$u`l%?Pn>A^Fxp*P8OjI&OXw2<(eh_~ z9h`Z%xrTh=e2~|#$|w9KA}k}W%Vk&a&sNlt#@+vcCpE+nCCQ z?aVVK6tX|uB0L&h_ZW$JOEc%_{s_EiNQ(x8UPABzcubzea=@y^OpvLjMXYjrYbKa zA~fV#r_iBobA*b2^|vKG8t^@CcWdWnQk~?pcf9^&?r0d-O$oyqFbua-oG#5 z%0ExA{K$la%|G6aD#`~Pom3iT#3|mOF-#ffl`j+w<`jrQ^0Tx0wJ5K17rK{**XITJ zupSH^idVg?5hM)!c=Uh_)Ud?kc~d&44{9^4TDP<1SB8cMf@Q~jQ0Lj^KY_QsG(Q$6t;x0upLdp2(Hm`$S$ zC?GFqcVaQ%xr%l1tJ=?@{)LsnhwWw%LdiKtBj5FKrZaRFPQef7W1Yx=uc7o)eE=U( zaHobOsYHG-i^BqeR0{$#sWV{r@{JN*Jnw?EM5P>Bdt`J?7i95S{J{G&${(#qT>6fU zNe527rrNq;Ar_m`?ItL&z0)z&GRqhJOD!+5u1zb^FZnZW<2CXdz2O^BNh(Ngv3$$R z`xi7=+`P*u!FS#I9~xX{?Io#!ecBIkzentWhx9&0)^qCI z<7dz-NapK!BR}7bi-nhC9JC>aXs+T@b9*fa|!Q^U~*Y%YlscuZYWJa4&X}YE${!YPij% z9&fHL6iHyrLW>56ZRjW2FNeCmd+zf5d0^w4ZNjag0cCvSAy?A<4SLcXDogHFb5}wgnRQ{nU zmbT-~XYPffb>Svjd;#Pd)`Y)W?Ab_e^Lc_(p-2T6vXFIZ?jMml3srN3oakS-uD@3N z{dm)QNR7 ztW5kGI?(!iXpE?I<3IHmW=03Q5Xh455h80}MEwe_=e7(+uWIj^a^W(Z@3>$aL(SiG zwW~9M*Sj*-&Dr{Yz58+f3@b_+O)Rnx*A|lKzqQ4f!I}kpbB9T)uZ+dfT(luZ+;6jL z)P_3sVhA~Sx7+VW=+EvSA&qg8duh-I$<}ZUFMOvt2YWD!_5aIs=n<~x`!826bnwv; zzi$b10Q=ELhR7=B_T-A%A?3HTA))7RQDhbB-zoX$6FRSJ(lJHal<8+Wkm7$`6pEg# z+I(ELGr+pyV87}zmk68@xZ-&X>!?)^a{SSnwD|@;-d=cLrV1~Ho`>#E85pk38ROld zw7r<(OFL^wT-E=4V_cQGZ|IAUtlBD&mDS{fD~wU2GqmM2M>0Mz-L}Zp*2?CfHgRvp z5jMN9VDZBIo25HiA?$uSZd)3dnl5D36v#oyn?C?#w$I*7FJ^D+T+&E5<=GeW%A6VM>ZN8xqJAR3s9{z@tjVY^T|+8-PvN2+oju!kMBOFD z_b(bfvkt=)abYPc`%kpWf`)%&D4|A=&vBiWw=gTU#-?8xvmxl9JN!sc^ljpe+w{`FLn9Ei(>lI znB+LI-cFVnzo6MJO7984r_Iyme0AlFI&)t(oPlcGcJFxw} zcOVjO_fxbW71{57x3fgz^!A>CZgJQuKa->%Ae_(*P2>WlCP8R$!v*-! zGaVciZ_WAO{8nG`xbDad74=vBQ5;<+-Z^T*M+}eR$!1WyKyYcLzj`r20I9t8#X0?h z4ta}%gAqSkDeXY#Brh`L&mAeKDcMs!i4oBpt5RVgFg&>*WEBb&z!x(LX*$o1J(7f$ zq5EK-Pq4gvA;3_ysFi;zM+okRbMRwv<-^oY3Kmhe-Gq2?^nuVy3011IqFs&ET{?ep zVXx-ND4l2#Ljr?8vEjMRTp(~n02P?9l#$~QA0T@t^bz7&OHG}SICVY+%%0!*y*O3e zJ1DO@o1`OenU4JW*$>=f8C8a1gXz#}j)e8PqHYK4--%7a@Y~ZLvt*Vb z#HL`Tz&S`YHKw-Gj4GY(V!3dk=HTFw-XYd^rE{4BltN`Me%ZzBj9(|o?y7)R z`*9@W5m0uRQX5buB*I8z?*q4&_l;#O);+X6`!Fj|Rt3#s^Wo29Ho(MdJ>(JVR{HL; zd~C+U8mt{Ys>Xa-$>SkpEDwV{wH~30U3JI-t3tz&Q_(e zTaj5nIQJS29o;VT3RHmkh^dn0RKeB2jl&oHF=9A&Pk`xTDq-lR=s zT7!E`-5NERX#_l=3 zUgZ{0PT!rK`)YDNf69;rG&O4JMGwKa6zTW zbcVa`>RrO*P|g$~!Qt2Xm~^lvc0qPpM6``NRqX>+L^j)^{=)lSv|%gweUndrFI*|C zMt?SGXIRT4@STB{gI9AaEwZ2PgEs+lsWHZz^7o;ElG{uF9%d6q6pWP){vGnxp2{Cl zoDy_b09O8s$=TPQUrXz_e=Rwc`f|3@vOx9+zAd<2J^`FT0qSU`Xeq5@@)YOB-k=~M zis!o6VqA2va+PG~Gv;j9rsx*~MG2-`h^E)0BqNi;Gw6vakR>#QLl}D{KxK#JlkKs3 zA>c^+X_)sM)i6M#3yz=lVtVSts0!m2adE@D;n6g!b&=RKoq9QWh_NPDvvrcMD}y`} z^jMGAo|yDq<#TMqQMHMU6=4wVW(q?6!`HK_hR$Gy1xnv`mb-ncZWe!Jy~?9tUy8~d z50%h+d7e`AH8yKZOiA8Z%-GYGSU}-e7p-IG4$Tb0sj!-0Na0awW6mt@>}6wQeZrc}q!`qK$$@#9)x0Kf#*DR7zb~y_@2h6jjVW_O4n;{(8YW^A zb@Q^%U!2`m#N5Q#i=4>0epXCiqHQleVA`w3r16Mv&E3;x!(QaB@>e;pI0&y%89MHRnkg=VW0Nxi09KD)+k5z?8o7^%GOg?TgPj;=|mx#Mj7RnHMW z$?G8d^j9N??GQCud*5HJtcEl)bxa;IL#qk&WbDrYrm|Tp1;0Ap{4LM6_{*#2!vMWn z>sMOHo

|yNsz%cq9n4cMifUHW@A(QnClLuIx$Dd(|h+E4_E&SvA!pzivd1sKOg2 z^n4WyeZ5nEvC;jj5y|n<9bXi@2DU-oA1SuTcy9;1faM|*J3R|At=#PwT zm5pzc)@9JCwxsf;q@e+ZpM{y2GyA4G5?A9Qd~8${xFj4+g^eauF({0GYfB(G7x8JJ z_X4}0OnJ7~q0*aP2X=a87P!t7`opBV#YASDtlDZBAx+xO!DA91; zFHCRKVr16Sy27QmVEm1Ph#4K~Zq=`MA_3WbAZ%vRP;<5Z1xbHhp5YI#V2Yz{y0M;y z6-7L3H%l3nVcB+~`o}RBh;3aCdox7fX<%7PJQ$xpNO+5VY zg~#HPjD%x=3738PX!0G6^*CHm!oH|Rbw=vu#(6rU*lh189VN##QHt2Q*O1G<$Bc2~ zf&o)FFt=)CiV3^V2l1Zvm(7p1u~q{+H%#0+G_OrBXsoI|iA}dsI64m!8ypovQV{WJ-j5_^?}Iiz zA>xhS%Zg^1$?`pXH5rJ1J{DEZvw~H6=0S&(!*PaGwn-h*+cGvIpV+$0H=+-@=vM7! zIUcOLz&kj2DKJ@$v=)n^8uVb$fBR`^cQ$Al+f3mrsFaTa=g(%=?1Pk7>!Ul%fBQBaH?jkgZC#bhg?mt&%gfYp_%JD1K1j5 zYAw3TM_id@@5o_0i`MAwyDlVlhWKvw;}I`0(d}9AWLRU|A$nznYGa`DSyDKrY387^ z(cGs3HWjJ8jy&;k>*;?*?~{V00_kWYHfO^7$**IaV(+!e`~$j8s#~|l=tX@?aBu#7 zXfi`=z!Q+$f0rv5PUY3%&iI%j6$b^RiHxG!N@v%ZQOZcb!pey0uH)cOyS;rltPC|5 z7^RD4gB+jf8Yomrln;D(%*^qPDaC7Qemn9F$i|bNqMmPm9c_DK$@@LsXU}V%gYSx% zDDeme#8eWGB~WVGNTb+!bs?n&wEi9Nr6vnnS3y1Su;cVctzUpg%kd%}(<|Kn*UfJ1 z`zL}<@6AzK`)KZ&O*^Dnb=|OuJHr*Y&TE%Oyo4=k3IjIP0}0bdAk_u)lLYn7dW}BY zm?0M6y)4Jl-8bBH6L&Y7(~fnxs1MI-!8Fv9*UIyl7S$&TBOn0d>gHl@Y!BnL5%&tNl)JeA4u=YLgA&Y2 z*51|CWg867)Nd5R3q~pB1b+kO>6x*Iu?3B?^-X%3>+5>+`K!LGsmlIXeY4!t^=i;_ zi4DVI&JKZ$8i_20Vsbd%KR7-Oi=?WQXlx9@#M<=VGn+`1mC8f#YlMCqNR_REukibk zaCZRA!&kyWW0*NybN6B8Kn=j-JleooYe00l-E?~0)6+m278d!xNW?GQK+c7%YhZ=_ zP>Eq{fq02j!$hqPFGj4cV;Sy0k5GjiWx(}!cTV%a=mtwcF} z6Au8?GvHr4gut+*xd9ELz~mCX;^Hb&ejqE; zha9M8m%#2}(7Yfc+QNC*{knx9AZcWDpu5r`z=tbSE952*4--#dO~C8;6YtCvhwNHr zq;PeOFh@LsRNo~kDO?6P%y?{r>;e&B=^IY~ z@BjLI+@`L2C6FaA+&dK4rn{IL|V0{YF7Lw+F9M+*E%Sa8qc z&Wtnc)%p><{H{y<1+e_)9sjDI|F)4xQ_@!TeJue{e*j-Xw)JV7g0YzAJlwspK_Exw zSav^*>ab6*S2Tfg{R%6;tF(tue%O%6xJ{VSto8M*EKR@mki1gC`oa{GMv|tFeddpC z`iHOm+Clb0lSq(vx3nkZ(OK`mZw6)4YY)db&R+8;y9|XxQ{&t}?umWOXXfQUZ3xh~ zrjZl3=cdPdU_jT`K@L)k5x>D)Km>G*rZylh-?H046cV_Rhq6$6rIw6=)WZblufnb_ zK$&6zIX@D5KokwXB(<0&caYAYnP|T;?b<+cGyo*pKvCoFY=Jnrvv(@9&k&LGC}y3jAi!e;xA;U^)up4J^f^OSIW{P zxZTS&6R>;8i1H@tJpuZI=~prL@ZXJCl_0bMP5pl?QB>GB8j zix3){cYU+Z>Z)!XFuw}8Gi>9AI)Y)5$Sw%OdIZ-}18?3^i$v;VvP*avBB0#1YGR2! zxgh0wk&(lx9xE>`Wf(`7o_(#Cy3lQ=jo#QUshiI8wNp=7X>TxOPL#RHPQnqN5isn@ zj(={a@ZpTv0ZJ=PBa#`^HQI$OmBS04527+NS*el;x{+32{w7@sL;0(eEXz?Z-cVCq z#H3D;5h?k&8eVByJRkVMF$PYcJ{s;`@@vuVAXRj*>gn=j-zLS(aExX9Eea}|$v>QD z+}k)Cut|9&9G{8e2P$@Ob$6UCyKaSu4L%EL*uWQCQXhsW=M$r8jp9&=_HVjv7U5~U z{E(-88vamjNIRfo7sYggVLy^$-SXrrG@GsrGG%b-6?W8s*UE!3q_j&zhBK1hJOuQ3 z3!|)ya)luG2*q3={ux|pk#-o0FU{`zp|aHK`@jwdY+Fn{DX@cFI3h=;>DK(BU|Z55 zt<_B&pQ~o%BZ+sSTU?(B5Jg!yA&Hw32fvJ+t5y~?s`lALD4=*cIh6NJ{n=e3pXxGD z%Qt-jtI__c^PGITx>em}icvOzb9glA#O#TA`AqxIW!0VkJ-}8fU$eqDhJ9>*1J6Q? zD-=^G`^UbIpKTA8z*Kd-Yhh$2|6c|f`J6I^Qdo4>h$m)mJE?yn1{DX{smShK7wGF4 z=vf_*IN2tS=Nic|r(br;wMFjtde8V=@Z;0JzrpfRG6IcPDJaoEOes%fE%5mfYH zAiYqre7gZ<1bX#Z$SApgVG5H1>{yBXIefygy19|b7pC=lE+28j>v$J^Bz+iNCDZ?lH7q$I??gCbTDl+DxxAk3b{Z=KO{c7^o_F$#jyR$JiwpodJ3}C0V{ypYV z6bW*Rvq{mLEC<=su`IBp7zl1rom@tJI+21Pd2=Oh3!yo<65?Xmp7;KTAUe);FadVG zK>uK@*`Qe=)|IM!^S5z^lFO;uOFYkYd)}5*;dhU!Qi!Rm1pTuk=k_|TtK0q=SSO7& zrLm=Zvmwjes*Z_GZM|TYy(-&F;cn(G;74(_&VAv1_K4U0l;b(ebsKj~Vx3{}ezrBX z({CG*VcJow1F~~cDOc0^1OsyY5zE!4-8;U;9zSWU1OXE?YFS$hE^wQ}v2tIaHO?<4 zm!!*~rC+0jrKgp0X-xKL$MW=M>Co2#Hi-xz(dv{}Ayl=v$9f&1=x>;Si^`PF(7R(& zas1vffx&Ec&eXm@CK2=&dhaL(wU*+Ivvj2bT;F_@d#EdoWBM9bN$@|80Ub##A73u< zFsd*~!<64+MV-Sjmsn?HmZKuBUjNhs&(IRFt~px@^KSN?<7fQ)Z>Ow3`#et*a%ENw zPhK49)s}sk`r50lP3x-yfxQ~zUgm@T@<$#E4WB9r$67wfmLPc1Fq1`gvM)+oRHH3R zl3J#_(GGJr`|F8m%p4PL1SV|N6ZxMYGDL-5X5n-H73cs359){Q;B|`#R4bJchd>dH z;rxySvdP>xzx3}2In4BMmkRe`4?ZYa3G6_`0HphPs1O4^vd7TgU7l|3zb{{1JFfo% zCS?+%Ud1#;od1Whb7-(^ZI^AL(zb0|m9}l$wpD4{wr$%sR@%0CcI&pj#{C7e`_6bq zj0l6igkaa}ZvKx3^TVrvLP*UrHOI&nXh-?-^*J& zv#NhAVumBDl4S#g>Q{0)Sr-Ckj*_&c5G0D~Zr=xp6po&itSCw2V_cS%<4_f9)4E%P z&vwqbsx`#0vaE8Z+L1)(Zi5{)|Wfpm3dHQC=44>f%S2^e$`zVdEB)%FU;~v)!e}uTxrQ!8Y4ne?GNMzE)=6H=hK61#J1;#Yn{9tA&#(jS~RB`>2_8y06Sc z{+Ffws2-*pJCjpQH;AFGF4XA`!+#lB?@MZJeg2oA<(7*^h@J7!k+Fn^1aHhbJVBrH z0`PcP^I35xxc}(BZjI5ymQGM50ztvZYQ(Xo#yh9p{#>NoXFkLw;o50A<=*fmon}Q) zeX}W`vbIDj)nfV^ zT{3dskW*Z%CaX1cmd#{~K^zH!k=$1~{%u^=dZxu;$MM~U3YoO{m&nzhL&%;l`5Eu? zpL29DUO?GdWM+x+V=5t8GmH+V4)Z8d;dU;5iWYznv_=@xomYg@0+ED^PYuNYa!TiEHiCwhUU3+53!vTdU z#J07HPCddN`);K8VZp};ZH$GQ*h`J~9mwfUJR1}5zf^naJ2X_=7QI_$eBQo*PeuHL zhu`u@d49(c`QnGO4rN<2PB;97U~^Xuo}w+Jf%5tM4B&k323rh@Q5!JjWExevbV*PO zT!Zb|GeiO3^;gysJy35$qEk0^(dhGTOt_77LPp}?5)g1gB!a+LZjM5RRT|7+m0fS^ zf3?sQwLr4aPP~2*%0+z2;tG5-NWm0L+F68D2wwP(04Lvi1T?7(YXIy8*CC=9UHpV$ zO_{mUM$=(aPZnEM3D`rWaWaEemu?hqFwrB(?a2c#f}PPz-FZM6-I+0_YGUHM!1~(QW&)(581Np9_~mQ<+#+8#>{q|wh}ol&vF*uWI$y;85-1}l zwd=BI{i(J+(n;Spa2n&Sia0#aW!5vXb5v6^U)ONn_@J_c)v&Mc{Jw1$WMaY&!TU0K82IdMc9#oqjXK*rhm`^jbh1D-Dkuk4y3(f100CIdlkA{Rb zS{{IU0!1SI?+kis3}gl6Sp_e_zo4rvO&Mw4P0#ucj7dTU(FS7lzhi6+dn$mdb@CEG zprv`Z`6tSMqGPkc^|S^Kn-d)|t@KJX##_!}M$yM?_MN_-1c^>(2X)M2y0XtqKW8jU zP?nZX17uTI;ip%JcShasyU3rOrhiI{#x-ugS;M>(IcK zSCHydS3f=w(Fy$(3s;laj}eLSSsdpcVq}b-S8IpG*1LM}T6S1aNsOfdlvw=3fZhMt zQCiU;bUn5e7XN95Ci_8dWOswdEdi(M9T(9l9&MzUgJ~?xjusLkk!;!1K7vH9=k!GQ zJ=s<5(dXtalT+BgPpDt!ij=!^)Lrw;?bTowFZVVoP|qf+=XGk=>wNtIk$eo|=;l#Z zuEAbM$qXq*vMngM`>d@Hgy$&juIwAa4?DGl-L zmEkSB45P>#K_Tw^PRRCe;(ZstjG^u*gLhme#@F9>%f43B!g6+ zaY?YOQ9Yb!D)&n*B-3WM0SSsjBB%OBl(a}bAL8k0RcrYfR%M@dPTEGVscS#cY^`<= zMgTjY;Xy_yOlEQ}eb%u(7-Mgm5ftz?NBUwme z<_!<&m|j{oTEf?%4rkJ3HJvuj@<3>;m|8>*zYQH-vtcRk9-sx%$+8;UUEiO9G;(zn zIOGgnmH2jYvaw%cT`c70i#yNCrCrub2C@pEp}=L=?~{We`B=NPgTN*G-yY@2)}PD$ z^ZQohZd-a`%X5@=$$4%DC+A$g?Z$(Dl+HhQyXqc0b zTcph4lKWSdlMIOb80#Kx97oef1@`}TK71cNuJsOI;L^J$=+<~7AMP)C%%dUrJlwr= z(bnpS<&2H=%UL$s_)n5j38J1buiKtZm$&RSQxr5h^cnrZytu!j(bUnEP12TXwD|x? zi5~uyRxF-)zjprH58qCsqS5tQCpl%b%rlQ6%{SIUoVW}h?ULqjM2>#gdHcb}JzL3R zTSadtN$H6(DZCZ;e$%rW8s#5#7e`&p(CU|Vh6?%}jvE=M;k+~#fL(J)Oef^00ihu= z?n0wDCvEtIfF}3-w-~!aWfp9GB3rXP-%^r&6aiUJx|X-|ByJAyw9FnlQw227@Z;mv z@H=uLTR$aCg@IFN^+E0IS7BAcxzA#lq6fG{6BAVNcY~VaN&^3H|JR@2nqHeU*C6+4~Z#3vTVw@v-Gk91Y8j z$D6Ir$~i~36q@d$=y9&RYGO=XX zgt~1Y;ZjA)NY133ZQ(V|S3&Rl>v?vlp|Fro%ls7H%4A$=D7!Ef?L?Z@V6kPVwPU^) zB61HV<&3Fg9(WFlML*aqhvVDcKqx4GpEDGGVhO{o|JJEQ-UyF5gj#qUTUmVe3V?#p z9lPth)*9K}$`2^sCXugwY}OofwM*_UC#XHQvZqh&tev`>A)6{|`*^Z%mX4s^xxi8s zbL2*wj$W9yR`S=DV>#}v**FDKpPOeycg+%)ki{eqzw%3)P+sX(_l|rW!SCM@jB8WZ zvQq^P#J{0>^NVc69KM3q))Bs*B>9jOAv(`64^5x^%PhczP9{jhllZo#w*&4|#BZ#r zF;@MaGzlr{OieUITsVT_E=r{7u#UczpI!>bxd#85PBdh(^tiXQVJwj6Pk2*CU)w`^DBjdB4$Z`r1CB9GWmxv7{i%b?UVmH+uJ^ zT^K3lzm5M4`o-o=3!&%J;urWU6+jR>XvKBJ!UPhAT2n9|URf+ebfMKYw>0hEG!yO% zfL{txwZKWIC})r5Lw89^+!{R-?#KnLj(d=>gL4aKE5vg>+8$JS%M0Ut9dCwTjTbAr zA>CPio?yjy-kIN>DtAwW@b|=amCiumi}WSSF@Uk#@?2$QmtPxdD%8=LNxafKvAr5p znA|4u=SPebAfMHSL<@yNlMn=jivt}7$S69*_~M@Vn-k`FP>3v>{uA{c!{M3onXVi= zmin%W*hcS=$><764Zm+;fpF{`sz>@Y6=})smO^}Fx|Yq^GW^2T?WrdWPcQ^lVnyrt zBn{OMjr;jaR5dqd1$o$RFSLfEpK=4&;mkoQ$iv_{Kx=`vKQZ&_#_x;~-g9P|gd|Ne zo*1tx_&^7-v$wjm#U+znbg_+NI`*n!F8H6RlqkBcxRERtaoJ?7IrOj(1BtRQviql= z$&kRKt3i?-lFO$5JLQvpNdHsOsWEH+B%1t@t)mxy)2oDn6FL8*M*fIxtO=+zapNaE z9WEY_(;Dmw`!t-<^{0;GT0GIp+fJsWlm_&!x-c)RG0Vr8CX2~^AunPMd{fz?p_~=GE$F}t?VY1^u9fjS{rCgK?Epk4 zB0{3oR8#4u@PRO<9a!s3U07$K2C7w*_^#>bDp>Juzc$@YLznaU5U_Q9>}<1|VWL~i zaaS6K2CJN9!&l5!fwkEC=;R8}d^uUZJyaHB%6#)A1~E+b&y?_GlU18w&O>oNP?*|2 zI?D9MP!eVS&`7Q*r^p|sm-oj#ib<6U%V0R|4~rkZJ(Jsl{ZBg8gONTN5_>RIC&67~ z{1m8sxo9g~rP80^)saue6$|B7IQt7@JH~NhX-{kaP5j8BB& z@@{L(=%CFmfG2B}1i0yAan2?7$ek{kQSsw|)hw>>KLln^T%_{6!gcYI@UFPsiDnZb z@ypWylSSYdgZ_~t0z!h5C6M>r&6oDpYDnN=-R$wQXy8)h`d^VfwZ@hq%yQ|YXku=u zDeyZ725{%cbOTo4)Glhg^U~pNYaP#Oo28=xP2lv){5T&TA7q%PtH0-$@gr0>{N8Q30z5?jq80~4(pGEhNcclNOu7wWRMv`3BZ0;TUmj>1R z@>#@vJp?N9S&mP$WwRTUL|Aan7I@;8?IKD)VX%Kd`!WYv565wdl(oG3+llhLsS&2j zTW~tX2am{HWJO?>AdBTqwb09T5FNT#TbOS{DY&?u!aay^Ft^<1Bu9KA*RcldL2g|o z#&nSKKHW?%D5O7)HqnUe7u#uInH45+2}S6uhM81s5)ukf4`*DH@~ zR#-gAUQRgufL^SyObhFM4&j06qo>qs~HTPOcxFXu=}Gz-c9xlTU%I7wZ%N+>Wh~H z8l49gtaQgY1bf-xNe2z65_?|PIgC{B1vKP#L?UMP|Jv&?(wZ`H!SMFb!BW?8w=m7- zkcu=Az;TUNsnWf-r0aEj+%ffRLrb&Ds}w^dcwfvwuAZB9xjgHziaD8I_t4jcnm8_ec1|MkP3Z{&fG2aekK;D|yC90jn3zY^tJooOyb}sEp z2iQo!9?Jn2_H1*N*1lM{SNyjXI8KndgM~CzXk`bWulAG3x{$au(qLa(IxM5EAdLZe`IM@)-<_Y^)y@ka z0<72YT-ijf+|;9qwqV?zx~iA@899Amq3v^}$KT1u#QCjhBlweJYH*!?3*-(Rk?o;c z_$%^0)?B6%ALq=&qMXJPNg}bU)q}fWF5eiL=Hs8X%#u(tY5Qf`{#%W|?TVZ!Xl;AC z*7l;@sdl_vV(*ypPd z(LyjFk_j#U2@h(ToJQa(l`mZOJD-QL4M>Iry$4UsZH8p9uG@rVJdd0-Tl8^j}{lX9UXgB9o z%F`#%zZx;G&Mz#)wSQ}Yxx87=*bfRoVd&KH5_oY2j4_#~b*1vC4~t4xA-&7L&wIQJ zu6H!3U!bRFDdpI68FrBRkx9k4?^7}6ecJII7cL$J-ba=pjyfkB)VOr7gYv@YFHkr) zLSRi46LQcwPE_yW2+OV;E08LjFiaVNYtA1PwWDlV++~4Gu3yH3I zbbMid>AoBoJC?*r6}|U*^vG+&XM=dt%IeCvXEfJ^?r>p?SIC?(*%;0*u0B{h=+ob; zz8&3}#3XEU^XPhu0~aZ@L&LkGMSe`$OZUAy`^bfwv+w->$NdBi8170dpNpk(hjB~^s+t97^BNe7Pe*E|i5(+4+fkN~0yMXER zOdRVwBF!+qhe~E|0SM&X(&vhug7+%!j=tjuC1nl@Z<76+kyEF0_GIm>Jcxg%G&jgL z)3hY;^|?@xP5eSQ{e~cly3%ebkvN92y%a6;s$}%duo7gmOl7T)c5`hu%0)xeLd2Tw z)HC2rcjah_cZ}Bo?5M%qH6Z>qJlKsDX09td4IJH?DSL+uX#@`(8Lt}^7GlGE(Bt|Y zV_s?CmkP((8b094;M*IoOSz~@hxBGoHFijddRYAUw@zZY6%{=NtWCIk!@Mq#$pEW{ zS1YCBm~nHfbAc?%(&{rVq9ec7Yj4O=)nmg@l?o;Qu~8#LVp-i^9^HL&>&=hxOsg3e z^jEG`mTO+;C;{rA{Tp;s`L%h0(j5~?Or3h+SNO64UPqnCMl5N_e|D`x{)_M@@jWqQ z-PDt3b3_0$qhewsSl#6BSikF|h|LTH+>VQ_7vzon)sRr?NE}U4d5oDyCV;~b&csPB zdX<H2Rc!XN<|ZI>L(PWTXjbMfYz5`GX&5)$pqh+Nn|`A<$jl*-d1E zAn}Xrp;NGoeau|vzcM*n+U^0{hTrLg49PCGakayjeGxm4Yx!ZW94>`4A>3w z`_uUbulLR^6?sUkdH4D+H=RO2r`bqWv9eHqb=>DgNuC5uTKyWPIRCD3w*6{8+x6E7 z2z#3hF^q2eCN#_|V7m@m!`M+{c%0)yaai?h@X!7GF&t+(XDcaoe@z=fA^$^|lH)>& zp1&7NzT=ky&f!*fVWxfYT$>mG&IY0s@Vmx=z@0uuogL%Kb(+umE!5NUFWOu(U3=p3 zP!|RvT^cljR}mslgs!^Df;Vr*o*9)NTZ-m0S8m&No8zr(QiXPHv(Y$8=RGYyc-Rnb z*d9XpEzQ&$R0a*z5tBWdVORQXg;s_}X82u4ZHG?>1XvvQN>Y4bsXCKllvTxC*D_)1 z+Bqghi`*h;4@;D@evOry_?}D(ONmwV6aM~A zk)hpDt{ep%s#Qk`qkQzzR!jS=LjJIz#?JJyq6S3p4W8s!6BsocDyp-6_W3z+)LFEM z{_zp#rKUS>_2s8!Ba4L8#hJ#wFM6p;G2`|Mb4~8DXN<}S{hy__syM&I6)EV=+#eo+ zrB0g_hoLAVVYvNA?W%kd}*6rHn@J5 z-wxy!_UOz`-589^g}tiP?*jAt9=QiiL-=Hnxu3049#^Ph5c5FWxs-D|`cz%lUf={{ zZ&Z?qyqb^eS-tlI>Sv&CsFM#B>_kwa`u6^aX%b8n{DW!Zne~v+T|TR=RpA=6ml{G1 zem@)~@axlFX86$;Q*f3w`l52bPo3USRf-~vX==bqs-elhH)&NV^1imiYE@1N0z)=S zTxC%b|6FuD#X1b+1&T6fUVJ8jQQ4_P*+5xt+LF?D-5Y8rNDk9(dr`#VSUb&KkbRzH zO?nq40@wZ&or8M;h*4`-zeX|!IH+$guSGreS7;t(V7z$MjpxX&6fjk4^1&@r!b){Q zyl@;u;$o&g4g6cvV=kMct!mxNMI=7U{o2-4lJ6GW<lyI>BlR<4cZmyT(vvO{zlkHj1d*^o^j^h)#c{?xese?C+{h|?9C znu<+ELG*VT(~50I%%rT$WXeVzxTG8z+IRcbt7de@doEx%cm)X6} zuhDlj*R=_*-cL53*F?)%!!>g&OjY<*N#i6>G6S&F06`!>; z);Zbw%}}{s4D(w;F{?pb8BhGEB0UUY8SRZer7j_q*d%|9I~`~)g9mrOSCxOKa3`^xpal(1mlAvye|WJD+n*pdR0YE z0n{s1kQ7}-UD(Q#Sz)8xSUV88o1);R%+WU7lj#rt$pPRmSZ)n@PH$p#jyR>%? z+~xv3gU+XvFwd{+vPNLSY<) zk{v>Y>9f&bm*VG9gwyFzmxjAjqipVvIw`NxB?<0j-VD+_EPwve!XwiVWTI6?N z<$oeVOy3c{@WgZd@kV3L2+uy?g676QPnPzFS)$VM%pg536^!FIG)TwWX7p8E1j~|V z;z0$+5n>AvWG9k-El>f}T=^ur|HIZzVN^Q%O^CfKQkkbE zVOMlIGuW{nFToL2_f_c=*?b{qb|P^dc%|~V@&tWw64-s&V^HXllMQx)j$)f+`GR9Mm zGXPbywDa?s%L+^W4pOv>Uf9S-uHyEabK$GlAU##HeqPA=gN)wXa#HBmp7|;LlnHOw znZ&mU>m2`(28^vM;3yyZ6d|Frj48){aQ(slyNUBei}fk9Dc{9-Tl;*e-X_WIo!*Bj zj`93RhB=pDT-VQU`JW~ZPu*J&qP=$gvCChkQm=2l6al_FOgqxQ?HsEvOeo;vqw}l+ z4EM+7tKjTQIktbVD+)J76}QvEK)MAh`X1TvRgYiZ>KKz@#^cj?8AGc5%+T)+kiC#6 zUF^xccIdt%yI$yn@@JQIjXh;*W;r&p@{wY&5%u#01?N)f?QVgN#~X#9cwd5HWI^U6 zmTBqEH&@1|eetverE7<+GKCAL`+$Go{Lo+f4DKu zGkJU;iNH%ys`iO~#)qs>{ZsKgigHHna@?Z55e94Vr`DdE&KR;vuxrSRmy@#ga7RA~ zUoFvs_Wj2}9BmpvL%VUE*es}wKM&o){&K!C_uN}wJ9h066H!By4RVXpi&Z(vuuYYQ znwU!WxAR%|snSCmK%3blpk-ZBb@+xpNu?8Qt;4z144naMQaNHd8WZy>F7Ax-5gF;6 zr%&~xC3!T~vY_?mDk^xe_!xf|nA*c~ro)e~-en5-L=MlUNv&xfrg$EEq~z6O|DGlf9FY`3@Rg z|Jt0C>3vk{q-2yviJWi4yaz4CTYx-`MhZMD`wu0SB6{FDgpq_-rk2Yl_7w?CH=W%+ zkG*}QWxi$57@AoDj^n$u+M}Kr#e1?qp7U2L1YvnS^k>jwaI{Wh3b_&kWE;r_* zzQ-nM+|1}+Ih>Tn`G&Bd%95^G0{vNuJF8D@c5;8nFNC4~3)|@Jq{@M$7TblIM2@?$ zHI{K0>Bj{yNV~(tr~O^S*rlhlGfJ8tjLKo)IuKgU(h`VsZEZsvi5?)uwV-(zYCs_~Sle@$`i{ zTL_^VP48f1ML9|Vt9ga{{oqu!Sjo|&U2ZOk1}mBa{S}l6TpqX-VafrRik#)qIUDH) z*$)Fa9Q)n!C_UWbuZNQxTa0J5kG#nj6_UUwzHEol%rMTM_kIPy>#QVNQZ0E*Q!1^< zMWH4<_p_?~crx3*rJBMpj|Du8OXRz(;t3G;Wsy1K%D!~amKG~i#nC#|e!#&U0L?{@ zj>^|m9tG0MkIccu9D)>Y$oMhpV87JCgr%^51g9c0*RqIh(3*x+Js+m6C|X}V3tyGK z9_K04&z{+*r@hu$JSha325UB|YIWwX?%{aSQIBlj64iA(l8f-CeCo_Q<0;+bU6hu4 zYogbP#$~W)>9NoKvtoa8bDNl#$CWSufhZe$ca4KS94MkiGRgVl)V>DHbYUdQODpDJ zfx&+7y%{Eo1p;dL4OKY2h9u8gZbp@P=X7cEkp+j&SR$Y6a1RB*gw$thR(CI9;^liW zxjHoZA|$GZ&e>^gPY~2)0Dp(Ea}Ari7$R?v#QsktY0vFd0*-0t8d@ah4}7$M(u~$d zIa?fbe+-Lr!EQ+v3-a-!DBFo^C7nF0FAh&VFzYeD}0(YqLnjYN{zdR09ucEEbJ=AZ22t{iJc zUkgiQqv|>Io!amU#CQ5?dmC4$@c8x!VxsRb28qL2(h@J#xFuQ@%RS31S|1L6j9WO5 zo#3AfD+5IlBi#QOMSVV-vC^{Xejid`L+L=vzLX8_~}!hMy}*sSq!z20fPu z6wIx6s{HZMD@J(8)ljhU?hl13Xje$?dgyIi5b>MaZLCumza|tpLcdUCENun4s@cT3 zNY_Xla(9oOrk!Dw>Hs;}@i#2esfFE-pK$XuySlH-aTW3Wy-qF?BJFmd3^`M}Ya0$! z{2Vjcl%WF$S7O%K{uDM>h{0z;Y1Unv2)$;D{D>s`4#5*SrVjuYjd&TS8m_Q2)gc@M z6S5I!gQcR$f#({ik@=R?ej_o_=uzd|v@!QYdIEM6y8(2Z@rA*z#d`F~6#vo}<6#iB6 zVH=(>clNEINPrh(g!FK3fyKvrKC59f>YDOLW^FVJ#kw7BoKmm@v`qK7tYBIFvB5>m zEcO9}?mxzypaqH{s4P<#B^PnDNW|Fr`4@M@1(kF{A*kB z5uBV)857`B)ce}=+VlIXwcBP^vzy)X+Vr|H$2G@yHU0O4=K(PoP6Z5D{Qm9{gbXNB zOUsHFh)^LO0}_?c#GE6bAUof`18O5CUxEV@g#Mo3Kg=FASm-lZfRa@X1{k8eiyQb2 z4ET!}`Ku6FfKUJk67?4YF)$g3GLXjrF#w%G01r5<6RDAgSf@LIk=q;9E6bk_7}r1! zsIR@9^7Ymwpqm913N&aBhz@ZQ{~~$^3DybZjHI8Da`KaajI;PkkrD%nk567+UN620 zhXKTrVrT;HF1X+d*h_(fauF2zzfZ%?gL4W0G9HqdKwz#9ZT-AGBehb>BO*f!aAzAB zP;SBH?8Ao%Bmg~~0R4BT>Nm!q{6f%pL%!sa0akpK6Oo@V|rm|%ZS_b=S9Z=cUY+>@-UOvex74|i#Pz#Yh2 z;p-6+A~?t!SnwNg;aSKpf7Mxlfxj#8mwP4l7CP`A#Lqdpugveo`XK|b!xtNFc7Q+n zl32bf44A{0_R)!eAtC1X{x84uxBKL;{C;2Mmp$?CZK%ptPPShdm*3cL9^*LH$0T}f6{m_<*fu2G* zJSMDaLY>k55!_i1pV zaZCK43ZX$r@%qjbgtQ<)L%OVO`4+u6g{axQIf$M1?Cq|1nN9z06+BkKa9P1BdRM z5xU0h&Dh)Qmv>Dj4n0W;d9;X4fwk2=Nb$ZfPx#oXOrYJKTlW~O7Lnts(R%E-3E29L zM4BJO<5}j(w2RAbs>XNd+QfNex)D)sVGyULzQ!JB=q59WSc!_>TDk*1%}H2P%wgKA zNb<77^<-TgOqxD6)Kl=l!J{WH#kq^u0%ScsVjc^ej~Kwm@xA^9ikRD0epxE%bp(lq zoo^c=hrS?8+dojJZ&E%Pz`{mB;v58Pvc&rK7p#dA>tVPlj8+?9PnJK*iWq=!49XpaBG`P7U zP;jT-rEMhlDf`puQPD^FZZZS&Tq4z`l2ngtNrhFR1ljVLJZq}W?op7qw6WYT;t1nM zr{7o6Xs|ZYk}~cZ}ln>#YeRzRWaJ?P?6P9fEQDg?NJ4kDhMjF z=D0SA$BedUKYY&>GqY&|3U9M+>ypg)EO-Ov>29Slq=p~7kQ+iYoq7)lWgjE@{)VmbU&-sj0f-4f4x8n|Zt`r;Y zWkk!zeh3Q(()FpV_CcJ&z}|?G4D{p^&Hefu$c|ENQB0QMVoaICl=Af&Bu7nP+=9*2 ztxF!oMQdZYWb&{^j`x#-i4=GYQ(t>jPSnR=I)nC~#KsVLzqI)u@sLn|u;`1qII6OK_}qd+eVBhtt}?PFAqYke8hqk~Y!&Rhj~@(l5vIu&w8s2KoE^k*Gnx2+_fII%~TjN5fL z;MJAP+6M~c#A$}NKIM9TDPrb+2k|3OJ$idBu@0t%RS&|;c4Ig9ak`y_{87Q}k`49( zlMba!GpgE$qwTu$WHLAF8`gAsBw^$4^WyrQ;a1x2T=;O+2`*|o>&yL}5-njHSZz1F)ZlGBHV!LP&OL+I)nb|@H59rJ(j^<7 zvJLr`5bOaS$8{-$KE)jJ6Q8yO=}S@>o_I;B<~Ev#!ogX!)6mMM=OZN!X(~zO!dHQu zyX>Zc0Po7>6^q}>b+@|(_+^Jj=`E*_3kfSQYo%fhLy`bSlSvx!q+#6l3 z6F?ml@_CmKPNnprV%WRZxjmK@yzVy}rby?1ad~b_SDql(fmw($@B;IuDt}{A_RE+& zW>1dY{w!y@a*QhPU+tx8URlmR<~Kbz{e0=N{hR$jlX65xe#K#pr(036@fDOKIfj$- zu$`sfi(;qv>yYT{P83-jUmfC)gNla^=f-tr(B)1s)^aa1!!`Dq)TyV?c+_I`mr>u5b0aR=QDjSd7hc1=&w{}x zuq?%E=$BkuK1#P~`p$J2XMEG%witK4wS7ztIejOTyW#o7ff^6gO67+d`uh7*|cmq=8#=}EKVwWoV2C> zjQb?9P%BWO7)+U$eaca+>r8mk1vQvON@EI~*IBkm0DM%C8P-q5eRBhl#z-;yb4oSH)+6Cx-(Ad zIWw?v!PR~x*PgwSn#mn{=odIL_w6}+gkW7u>E}B4e>>E3RSS$ls|Vw&Tty@Xe9pi? z;ZqF(kAAtD&ahK69k*Ut%*MjQX3iO-MG=5D_{ZhCx4KajES>V`f34}=1Fkf}9dD5o zihLM=XO*btX8T=VDmz23Ns25OuKf;VtJr(Txf%j9z$&gX@7`#N6z5(fD=m$86#rZ< zef90v(`R^}$}Y>~n8)HZNvHC1>*X}cv#0G7QE^wgE`pHciZP$4 z??M)sNChiKJyFp0zN{Krn7q8y zH5VwfEhAxbk~JVq`(D}-^`aRfrf|H`r#o16KIm5~)#1g4g#k7wXFjQqh_Tr!twh+} z^`q80E)2odgOOOTnz!i(y)*n7voT)r1+k`1NHb8`%+zhG-wstEC5Oz2t}S0WvlD*9 zzP$tr;ZVh}Dr3(>20GMpF>uFrt&O$I<=!1c+Ag+YF%Wik3nf79n*7LwzG zJwb)9fc1PmBMZStg1x~y+Q3vQBNLzB=jCwPK6$^(9A6mE!8+X`eXWSU4Nm;V z=!#V|YgPf<8*oXb9lJ(#MFDP_|9zFq?5bkSAK=$P+>#)WY!YBu$_DUr^pX8_v6Cy{x_8HLXgv> zWFyQex;!#?vg`jQcm5yqj9tmETn|wPl%$D!$??i8ZBhAkbeGfa{^B|yciJTVBSL?a z1$%l~RX^PJ7P?{A0H==GfvaDd6#Z_fIMcnPhlbITo_9MO%8Cv$td96vX{C#ovqLIs zB?6;6ha9s8UUoWJ<}*bu_3sB2iVM?E7AnOJq4q`bG<>w--0vi0DLS58Z`Fht;_2JQ zrh|=x+%`_P9T(sw_Ywg!F?>~edjIsOiOooYlwyU z_OqA!Ry+DO(j0%m>$W8O)Y>%KP$D8{r#>idBUOUFD2k(8wyblBv_6(0)3+28&v}oY z*jKFiW5S&sf{bDS(+_`yIq*JNiHoYUdKbZSEdF|bL{2V1FO;B$zXfWn(f&SIpV!<% zS;3xBKXLVcBhXu1P|lv!8(ykTHypk7wT%l_kj2T-a{qc zGefa%->-{nXZqL-MdVv~s>jPsL?LO zA#7L8mx-wxnss~KrbPO1K`bO@8uvX2h*DOZ}Zg%F0AsAG`L zRoB>b_%6$QRriS%H<`DC8sL4Hn5!X5=5@H7T`uud5*$H+`uWMTQ$ zKNgRom2ogf8;{jg1>NFMaE+Z;qO%7Ft`rn6D+WVGb{5%AzR z3)lBkC_7&#=l*zioJl{h7a~&b zM3=^lM;gxH*N9)3qnp_jQ<&FT#1rDMp|cuoOrueSU{{(WAa3E$6p!YG#PK;c$DI&I zt*3IXs198>676BKpjOfY4ucgExhp)dDvs8O&F9YTbKSH=V!%;1*do;Kw6-P}*h%bN zk>1>GpDz~Fs-O)Fil@ZCwb^+QH<An`K0HMxVSsYS?-inq*P1q=G+ej18OGKgLefM>brr18RAmK`*E-!hg4#w~c$ONn`sV(P4_PcFXTp`5t~t1Swc;j>Yeo zKwVuB2wg23Ec6=UXbia;d4z<8O>OAAw8dBvAm%5}av^O?%c<_$j16<_)0s`s68NhZO<9I8QjeOb3zl(va#6A|Zx8ud z5c7_(6BHZ$y|9rG9gk$O`3WK#?PH*Em5B*=fTOjlfvn|j zkCXpHk^OU!kxMLO5uBbm=WM1J+k@hB*Vx6B^;E?*GJ5xBusscy>hdUqliJ(#`6Ga` zCAc%B<{TNxF5=9*1LV(oQ*(!iINv3;Ki@%z^j?ft*24wlhzD}G3q8UTe;Sc`?AIIT z;^afguOIQjG!TjL2Dc{YuJM_Z6`sd%^!0Kvo4*kyGeg`m2YM2F<`TFJ5`LKQXD)b; z_*FN#($9ubv_j4Id;-*K8gZo)x0+dgxJQeJc6L8Ry>D)cP*GgM+ESj-9edqAoib0Bp7P;M}{+(^COj4;ij!azqN`@K0WqHRnt%QyksQy(rK}o zs+RepR*ESu$&Wa8JpIV1myryP(|9BPRa+Pb66b*o5j;*K|bDC?5U3hZZ0OBA=pDj#v(U#w*Gv? z!Sx4!S!&-W2pP_{D^d`>9aE;Y`F-*J#XlQ^k`d#(3ffmZ2~ow2oZt>yV2^T?JNEh} zzadzuVXiB5^^<2&vacFEAMewWsF?^HPGw65UnkyaCq?sWIc*o!0LR_zJ9*DgR?}eF zem3Ccy~GP^f?FxnKslN!mnAPfMgsu_Wk8NwHdMcGiiLABRbGYHAC`&-4RObw;Znt7COUk)oG$T z6dQxNG-beq;0i^)gg)dIpZ4M1q3X=~HH8cQ(u4P6DnbnrK$0fCqG=!+l?OBgjdDt) zbJ%FPjmm3C6}Hym5>6A~r~I0*;QOWN2l~d6e{*nMzU4}l#@-tFmiUGV|^C>c@Hl-FKzDMhE{aRuZ$43x4KA-1x9<(fLD{ zGtDVa)s6fRj^AoRbc3K2Wrx1r7!|N(^?0$~gmAU}4T$`;L2_^7KK%r-N{N!rXw~!Z1<{St`9-fJpBv86q>@K4Lp>MEsnvNSJZXGhq~j-^ikNO3b+kPw(tl77 zCnT}j3Nx7P55F}py{>~|Ath6qdYe%U_CXXRJl%aRN14h!tu%cI!m(SiPV|ji^j3(| z+bNWlVB{|U_RSK#q?^h04-TGVi|pQHJ11B;!SGjAt4yd<%*xnt`m0+qRNru&#Au0g z8JGmVN-ZRAy!|mDmCCC~y)2g3+F}*K2rs@QT$BA{5{HT4>z6Z>)CN_);KQ+9o?1AuI_ld2d@^wyDDzO&dAaT19<=BvRG->&V5M zDJCCYpARe8BC!UZ9E;{DlGoRYb@a10MqQ0dN@5ec+e#i@wxzSy4IOWbd_VBQ(AXLVFkT>XM6)-^x0p z2?^S5U&-Way&EqXNTeqt9tQ-AF1MHcbJHG9S<72oMT2zAG6$SZCcXD7=-is^#2Z zC9oA1qQNRDrCvyoR;e2&BBDcqb@C8hCW881J7>_1cLd26q$UV1 zDAj(>qIHe3Ps)J(T!D?Hy$>H$s?$mNEAw*k`wF^o zjTt&oIcJ1L{YEiINx#lVr2n29^?D!q<5T5j>2`Zqz%CFp-({2hzwrbA)T%@d#@0Xh z`2NEPFcUFzaQ$EP>OT`J6EioH!lX3IK;W1|lI}P=O?{IW=-XQ#FDe z7ykSSA1eW7eS2eRXLa)QlnLwsJDb4*x%&F*nf4C>AHEWbTQ#Tn8ITm2j6QyI9&Jux z7yz|AjdOeqFrYpQt;xx`f?QwM)zj0GyE3d%{3T-qWgbx7nv5=l4*|~I6)+9jj|)YW zy&ed-ib0Qsx?7#Zc`4Tew>~(wK7;||!yZ^QCxW@69>O+8bcW#b#Va5#hf!>V76y>f z0;CL~zT7xK+|^(Dm%h=zc@x=>;|)<+Su1jTVTX5cjA0uZpn^eY7Nct9?d7LIP$S+Q zieRyze4{v>m>Z$8GX#(U726O*^kq;?UeKW{B9?`b_OMJOaXv4Z- z))vq~T!Zs|Ym`>kFf86Y?jCJ|ls0gIT_SuyFpSloF422(8N6G~Rw6a{Il|6K{z`eW zmcVs7VR;aHB0@$=LQ0Th5RlGHt;TP8;OY*+Q+V=s`+Ft0gMxPj|G;4-Y(jf0mW z466Ad7#J5fPjC-E@cPXmWONphshz_GEF*}nme>+#>dz8P2N+iPM~GKL5O z0DOO&-;pu8P(fS)kiO&Jo1|pU$1D5IKAMmEeGd;6IRhx+pfLkNgK=RDEi9nHJoEK? zfV{C)k zDfkoNCRe10^5nKESTPqIKK%2!1%4xqO(!{IjrHe+h|Zs)n;;zOFw5uE5O>SXoC9DN5ij1;eA^%#jeBK+ z$czDUhYrJ^At?Z19}td{eq=)40J&?zVNgRAAnv{3Naj~?-k~f|qTkz`6^Qu{27kjm zhG@_NzzL{Xd^5hKtiKrCQM0}gzLn^6jQ8)WgwFd5Gk|0t3C0R=8yTWztn|b1fpC=j z50)P@0EObpdH4YVK({aR*|<1`$9EH(Jo87wuQ75Mu+G5g`BRGm^B`dkcHtR~6=SkG zx@=Mr$+1d}O*}f%&@d`_eq~e%n}5NXOt>E>i;p{3i(wpglZS{J8&l1H^Ke_y+-`I+ z>ChH=)6mMCSmQD0%24;{#3$?B8tQJIMp}T^6t4;*T{&*u>jQ*J9|zQv=P5r#YS%39 z>(scaeZjw@J9bR*69EqlpxKnm#PS`=LEj}wy5nlv(eIib+~f?O=bm|GEN>|FY$*@= z)u=_!GRKsD+!V|G#UiV16Y%ZQLR*x>_7e(w3{62FrMfQ89#9XZ$FfRc+7g~waP(5u zpRInG2>2O99XY?W@z+6$+vC|6ER?;pe5v>!pRv)FB3h(s*_OkwJ0~cvKl{;7y7`J{$uNrZ+(9=l_mK5 zlKBrRfd2VSnr$b4x^LCRAbk(6FvbXNA2EsCl0_7X;w>&ba|W7e{yx9L_IEr8ypRS% zJr7}a6E-|_0sno8#Og7ZGjZ?$1<><}XrSjZ_|DGAUYb~2JM)$dVUI_7t3c0m60kR9 zzdh1Qt^Cdw$Re34t6B)FHASbxAEB@q72odze9`c$>m7^Vb{#o_Kc_PYK95~KHRt6= z$?cBr$-O-139cKK8F&{DS;$OHyRX6fEc_Z7{l4?@VlGx}_l+x$9w!eIuu7KIi5gtF zu`g>N14$jX!qRKbxH!mg$RJASbUwgXPU##Djpb_e!)`QY>w?M6nN{KnW`1%~a`URJbm=dSALssSN5i%BnWNg}8m#Np@E zZ_d?BF|0t5hB?l6;95GWMbS+?6ckEfXLoI9vfzpS@jXod%;C_Je~id13=-9H+pjv& z22WA&9$);$tX+|2txsAh*u({QF`_;qzEg^$=;CbY;E2Hi&Z2~raRP%U@1lg@RK=?G z&gbGkI`Lik;FlXMN?cJR&~P(k@8WQt3r#E4cXDczZOJTl$X7q1l#T^J`^ixBXJlWw zzPlw)^e>;ggT)WNbqXxISL1(0Mq-y}wzNTWl3J`VB6x;M3TnC23hMT40tN9V|Lzrv zsG{N1$~Dv9B?EO|44-|WF~_5htFU_tO(9pf&#$b5tv6KWr=R=r-p_|T*4sIibG=(D zo;pSs0cFCB3@phvjEU{XYDNxk=2Pp*&Tetw7a*<{LHpS9G%Vhsj)(9ePR1@&ex7sz z!PCv6ts1803opO-1wL5gf?V1u5Wa?{l=mp?m5P;|l2u1dN~jfP-cHwJg!t0>M#()h zzY>1DAc`kB+RwOK?cZFBCEVpD@qmstYh5wBL%D=s$)K7SZh-uFJ}!xrzemB}^D6Gi zI^GUrRMEH!de=7F+wJW!Vw-0`?Hobt6e|o-nYV+7gAZ&*Ry!(&gP`Z+uC?Lxec7`@ z)Ak8v_xN@boN$L5dpyLA5yupuoSPjaUT@SvoU^x@1f7kH-6NwEdlx@;kzw6A(ok6} z#7H$w(%)a?AK}WqM0CoQnTqEeT)`&a9aW#+jbcq+&LHKB}Sc^q|fIPYi%i_Q-<1G*( zhy!6MqXA7Eb(ya6liwUeNJFi}xMt<(J^chrkAshgQVLyKrGl&KE%P=w&X1O5I_DZB zb}+0A(w0vZFxoQiW00qqxFm+n$7jfr>A$6o=PIdQvY4|E=@4XH_=~v%sVTc~s_pM;Y=5q1m z5a&b~m|8uc3cq(P9h{Xv`QB(7a9E)+V z)JMGbl!TqRaz&(TvpSiS$8#OF|5|QR?2kXcSA8TLAL)gjmY*t%=(YB({SRv+&Yt?A zjFDWHdZHELry@An4#b+DU7wY~*^kmcew8Xp#)RTDQpDYCDXT)qMFFZ8FV&s6VTWTu z_N*D#sQOy9XJRH^wjV{@78HtV4!L(rBgB>X-U9)kc;Ju@!K%{U1d?D8IP%O0ZHKKX zpTiuMCuLz=%NuhJf9H!a)5K)95}`+2BB(5o$PQz{SYYW~(sRhcK6giKbS7TJd=yRj zb<4eMPR~StT&^WcrmGN=*hW;~7Gy8vu@W9smdJ4Mp~i*y``_#Pw(e-ztj1o@sjTlX zJY32`U0*yJ*c;^k#rs7;GGdkl6myzGXzZIj|B&4(@lGxaE%W=*yBejY;#bpe$##6t@6n);8u!28vW z_gogGMh`7DaHpxigr}+pL&=JcsVvJ5&7ouCkb3GC_kE#-K$@w#8S0#1iYq<3@ezOW z{dV3+!h9z2E`M*mxLj3oWaFJz>H1?8FYjH?^y$0Q2IkYAf-*$6H@sQ4RG&G>^ugPK z$1eXvXGhs}dAZ>vrkAfSD~H*J6rfRj+;RhH)BxJBzAW^E(qx^dry`ranW`sU=W~=q z$A13n?O5o6E_gB~LDP{Ex$Z@w)~c3DEO7s4L!cZbrsfXDE!5V`9x+3=qW>!a^fVi8 zg~*~0DM@a{5~9O{{hQ<}1CtG7y#!$nfAA!&t@@}ZEo>4E$*V|fNA;{P#Zk~maD6-) z8c*0t;Y7Q_#$qnJg#8#`YRwed)8QE(jdsG+{wVdL;ztD^~Dh zDxTP|T|wDQ^?O$$;EN ztuC+W$DD5s86PNct9McIrsILB8{vavi$3F>XdW#L8g%IF54oI_dfrZd#_UTIPmS{v zn!!A$D&d-IR9kZwyY%>1Te(2hrHhb+#N6lt%v+fQguiD|zvB4tr-YvcVfJrTZ~xNg$VY>|Y`-@6=Zs_Y!6BbcR?-Cw<4kaxmuEW~yAsl@?#~=HdWKB7E%-&P*MAAO5?6!t)9oj-43rCLag$mpEyu>!olT8*vuj8^^9OeADs>Jaf+_zMpom#}uEhe-&@CD{=-NJ!*A~ zMty(t{GGz%%GAWmhCaUzoJjKTkiBHBW>)r zrJNxGnysYagK+D}fK&a$y6QQ>Ai?|11MFMy&Y`wPmiX^!NjJ4Zs;}%KFd?=8?dHeM zY0UREnGI=}>+}U3tWZsIh-&iwob$f8_0&Cqt(K6rN>Z~OH-LJ9*p)~buG+uvF0)v* zPdC?3G8OL=L}jZ$c4>O z%~5tI+}Zei(o62AFS|tZC;Y{VB$6sa!Y!0h?yunxm-P6@dPYR|nQ09IgY@$uKjO%6 zS!?Kn&c?R}t{DczcZvcBD?!RZ%D9?TJiEz2r=mE1Q(nld^geROuW6Haw%Q4GoBFXY zM6RN4%q{;W>93T6E?PMVSjS>Y>Hg5>O`uXo`pp%ix&Pb36{4W#r``_M7$?@)Z0g@h zgq>{1<%AEmm_Z1Qi7#xV48Cb#A(z&}POvM2nPkQAQA5S^VcM?hk1DF6LZp0ulKar? zWEov|ZX1ZcP;+{AimpPP_VOJD-C8F}*4^WLZA|#^um)+WsqN`madu6(3Bd*YCF9T`qdyc+Bmapc*@w z{J1EYa~m|yy~I7pBh#YW+4Hs0O{r}Pxgw}-MI&rX+`c9z%-jYk3X617O`msycT#e( zf;HEoU!x9h0iLzuBI3 z=jWeYxEeVL>d9!h?&CpZ)axkZOF%m{m-R3!1Es)TJzczW87T=WB>3fdNHSo}(8AG` z6m=7CDIONl;Vn|ej0vXX6q2#jw~RfOl?$c7x7h{#EkDffp=`fBhq2*J@X(W~PcBS7 zVw$5je24k)W_?WfUicN|&+x*PE{||Og!{f|Y07BJN$nk>{l40z~vsubIsmRrTXx^Ti9 zg75Xysr`}8=4X%nE|YO`^;urko{^W{BBYKT_tqrAj&+8%(zt;@OonLT8p_&*XAIs( z>iTwQJ4s0N^gzh_XounLrxn9OmYBbPEdL$*rGt7~nRBLu6ztVFms0!7Z6k;Eo!LZ* zh=5ENp#TX%F*d*7n8kNwY;$3_@W|E7$)ZrHw|2I*zpmTJZlx3($l{sd84mNwU<+Nk zIf*y-E?MT>p6je29C{#*Fnp|i9Yb+}Do{Y+L71qHo;HQ44lRU40*~B3vc(<~mLN*1 zLmGM&pZI;U7wK1t7gT&MrKLUD78=~==!e_X$c26VE9i-K{5Nv3NK|bC2bC#L>LnI!SiNfg3cxh^=Z86-G!FjWJmEzGj<= zmsL3va>PS%-9(YeXrh<-AG|mp`VU*n#0QmmK%?jsx(dyeJOsY7X4Kjt>WV)-c6@df zmYQ4G1u`Qu(pv_$S2qD6>WMxLG5eb%O@ERg=czigQYr&d_q3;;bDPUAL5VcBRGOYX zLs-@hyaQ5JjOhVyf#>^FjP2~vQcc>eto@ph_4e@x4a`kx&lo8m(XdB?PxFEn%bu)z zL+UW+XR?^KHEO;H{<`OKuffZ5G%{?JoQV#4S69B228UYr?m$!LQHKC?wloua&Oi)G zh+FP6`VAx}f`qnZOIUs71A&sQ@Jg|jeA14yh|@_Fe)-IQC(LpYlNY-A$_NzJG>!?z z75tc;n;m%(FvHB1Am&yhXM(GpoeuKe{P_6puH%UTs`Y0&;HlUp0!L!m@!gNDS6s42 zh3B{WP>Y$EwB^8z+oE_H(E6u_bd4x~odhyAHceW~7a?ww3&rCqa|PImF%_AmVHcrj z5=P*&2nD}zPD0N+vJ11YObo-Vwm2L{SugNoo*IiY-5hZnwcF$87R+f>iavWFXU zRWh#lPnK?E^A_>5mC>lPr?i^3;e(C8oFv=Kxv8Q1Uk6FtAeGl%ae&t z%wfrDeyi_GzJ2S~<&Wk%0=3bQ>)?l!mGo3Mdg}(Ct@@h%CYy~+DY_*8ip3`s$efJR zR7h6Yj_}Y}Xb`4HAS-Os9f3b#G3GteqbN*92QeR70IT->=L8k43L~KQDF&Rv-S{hmU z!z$-eLwq;o8Z_FTdeK9)-`_`g=A4*PnuvpmX(Rk(fL-fS)$D`Z=<17_bt< zIrfYG&UI)sF4uPR*z}w$zx50W*>K)D#4xi!{+Xm>f5|ZhLG-w!!^Vi)%+a0Pft zkZ*KO&*v8--RFu@7no>{NY1aUYcn$nCAp6g&@9y;++uksf`=0)>gR29i#cVdPwgjD zKc^d`m-j>muW@E?l2;Q!qq4rcsly4lYU?Wc7pL<=%Wqqg#`v~zUmOyS*rv+~7cf~I ztRw_5DA^`)2k#D8eOC$X9-sPpblL(z!}oj424F{%Eq($Or_#}J?5Y}c>Q&Q-KrsIg zRykj9@m+dukGXcwKfQ;!5c<(P@biWk{IhEo*B$e-dioc8sO$LX!*DY7gc1fXWg^d# z$ZVKi&CQn;^l`a~d({^?akC4((zbr03o2>do%$Pk3BVUt>2iU^EG@Meuk-QCq#-nG z-Cti&YH89)VPN@*^PIPdg!4a>H2Mh^vd@~G;Ce;`SoHsD&aH)NwYYEVi#b{-x7yl; zo{UiTQLGCYPqP4H7;qWfj%VghRP1Hg$&b{oan^7I-PX;R38Z4U{;dkpwX4vl^1?YJ z+6GJR%-{YnE@9>H>8{NL+L7NMV$O;%g$I3OEvmbZ3QjIDvx zpIFSg$%;5)BK-4Fu%UVwwC`kd?zL6j-N_qjl)6BAnR*fUQ@vWxCco~}^EnLx-gxVi zkJVD=@H){4w$z<9tK`?bWzZiF`$5?=FHe{g#~*rE3x=flj10)b(*OJpOJmHgUPsEn4w4I8#~lmpjpGS+a^A5+m%d@ z#?4GmvqbQ^Zj=QniJBAu+ZDP8?5LNcNwsztBye5V_NFBBKmAmtKaH1v$%RWsa@5J{ zTL~6DAd{FQ4-;h-9o;X5-$l0t2XD%R{te(vY6P{#@8< zJJc;JsT|^Ax4Nrs-QSftG#721GH4caE4sp!w<{8!4KL_o=~_C1uTU&MOmlT_dv%^J z07uN0TQJ)BtAiJYcs6?vNI%j8Q47xU6N8qJZja$#jPK@xM}I@koKiyINYq^R&Jo=% z)dlk5Z67E=;=w5GZ)l`fFB7<)o(@oFjd0Fm*CT(tWyx3}nx=g#&}0@aF7csuwDE4` zTQ0Os$4cE}!b-3N-(xFNWMWF#&XVewV^4c_FO{pvOEO2CMsKNT9qaaOm-U0!M$+*A zP@V5v9ItbHj14~sHKL?{&#}?-=98SM2Dc}&t0~uu!JE2SCGo@Mm$4R-HV5>szt#O;rgZex+S0UKdo!L8wVo@aWI@m~j^OR?IHks3ymMbZI6h@gEi=8Wv zkgyo>m7zNsfu8d8VG}6MxeY|}V}1IuiCG4#Dbk4@0{7%}c}@uTO2Sd@==QRi7Mz`I zh0VP0&I9RY2_Bmjj;qIPW7~z40#^5ZY=N2N98KM0fu#gy7Vn6_CniF_F-~~cH{c<^ zz%i<{A}^Wl>=4}&sUn7}IJ&-mf? zrle?({oV%=WR^#k>wuTXO7Mci*eA61$+ z$8{$#x-3Qv*HiSY*YdrNIOVd0{iGZbG1zv|=EAsK{}&a;EU&JE1zGgV`#0XO7CuwK zbULY?22?B;N#vm%2j=L6SBR<*Sdm#wBdGXEFtVnF)OFt=XAHp2(K7t8%=k>#=r`r% z*XpB@9wUD>@p=stCs&9=O60AKlKJNdxfWr%ChK5wfyNaH)MwUMFzu zT0i%c=C76ekxt!4bCl$*xKpuMo(MFvn$P{CW9B`KC$Ety?rYd>(V0^I;pgGUEU9hE zX`c7C8Y+nmkZ<#9Bgx{@t6yJ=^fQ@F6DxdDF1(4oN{9d^?-cAr>0;!#4&+svQC&tXQjh=xPpDc7BluDVy|DOP>e!^&6RF{qRi)#8 z(02iP6d-TSuWpgDmgejSXpK=$mGhenJFV5}oe~#m&W$qm2PHt&r`lOGf!hGsddL~iadgM@j-ENPzF``?xeM!r^hw@~D4g11fbX9G{kFy5(& zK`lztb$utYmJZk1rTbMZ*y+_`joTr_`rW+V00`yK5n z=K$Jyt3z{#-NK{CweYuaOARrIW6aTzBh+4f&|SD=2$cw)0f?HpRYpN@B7G&7#SzCp z!^ekwtU*3n4v<3wVJ8cNgufAsJZjWm7B@*a$>d6Bq#%a@Uh{${utCvo*lt!Yo93F6Z{jIi8?7pFm5OfgYeMMK}WEDXJ2A#JpFqO zAn$8$M^Ot-!jtFx2W3b=V_eVqf%duQns#NB)A9WYX$U^ZmHDNmql?KG+YC%}I|QYa znxd&Q1Xcjr>iXCKFpT1;D~a=0kjX3)_6}qI^LCcIOW`aF`DP_Un@n@29b?sZ&%VQq z@jZiz&;D2T5A77}^zQ_W*zQPjgA(z8{SjzM?XP}t2WeQB_?e?+iF~(G z*&dv&hwSpQ<~B4_G49>u>y+-xK(e9gVe?FDjn6%#scwBpvy8v4uj$03RBqc$9gLlr zpFh_|_I)!LSFL}|ueB(AjJX*N<3UE-t$scqPoo`ZOzOpJA=4EbCXtoa})1|CRg~d@Ch0zBpqkLn3r4oqORSN*2xexQR)iNCMKx3dY?Jwt9UDyLZPxXk*eC~#_bLh<#)i%6&D1d zqc@e92GFn9x@D3{=(b%%{7b|P0WRT$4+s++RtZhB71yH3Kn@#Lu*Aa>d<5_`+$BA= z4$Bs#j@)7TJ&>!7K-h=xu2Ze?b&6Ddw+{S@{^HYbI`WKqe!S%I3ulwFfxWWajKN18tY z8Z}pN-!?r3v_#U1XsJ)92Ddi6lL;&JCC*8@6XVyr7Z5$Zyz?E3!^9VzScYaVJAI~ zdUmCTCeE9j{Ngx|sykTj5pfl{>*vyqtqsh}yWL4HO@dDB5zt{AYVbmn} z%PS|D)Fb!Q3X% z){{5>v(ElN6v_};_0P)RMdt>XNX(u5^{%Wp`OnI>9_k^F(hFu_!GjI-RuAnF-JFM| z6|1wa=u@70N@$;Mk6vzx;ct&*SBMg$9n@NAY~(N23HO*FFt{C%hNXI0DUO_2vZv~M zyq&^VmnA&r%9EASmA+JK`9BI0V*9n@|?%w|v^ zGBA;)-@N;u*};$r*Riv<80^8RSS$U|N&1p}`tX}nKo`7y?>0ye{y}RiLqDn4?)sz5 z)Iufv6WXIV><{Zdl_DA%B|k!#@R{@s%%WNnM32oYnwcyQ>eG0cwgKNXA5 zv)}j;v!L&%VR#XI7K3cfxn#fn6ujA*RYz%b0xm&pS zTkNIk&@$z}z2uc@#Pq10sv3dT-op`$O%py3!(1X~wINxCA?))!5Z}_ZeY4H9UV2g_*P%)L!8BQTj zRtt~Pu_R_G8=a4c#8dAG^O?GTs0M3xg*>QqJB>%Ae^HTBRc0q;cXh{b?>=kt8oCRR zu!C{~!0$hsoynzgtTa$cpMrz-9mEvv5tjfC_qL;|7k!KsOzAk`r9N)f=0e&u5K0AfA&isKksD>k4ViJ2 zIdlX0U^@#^FIYPqHjc-#gYtD4e_MAA2r9u`US?w!-lc>XF# zYs8XBeZSxCbh5jvDs=stvrOW9eC;H^y} z)2%hCnv**So6AIk)^I{GwVcSqj6(M_w&7{|T$$lSH<;|-F@R)DOe2n%+F$`BQu;Ky z=5Z7_t4;#wuX+76Cs+|2hQQ@_Y21z2%(!8*uadEQ!P9s;QvdqGP*(vuGW-M>YbxmH z=lRqca~du|RQetTqY_N+yPtlL``8|cveK*Q7NO(JMxUg9SAd~@73Q-}&^*6|(?>Py zARjOPerr$bom@ZvlbkLqRTgT+pzWgyBj~c=Xi^I%7KI90pU3E!iG&`_8m%Adyka%0 z>6Q+QE%zLri^}a{Ff2QiO&ac+sr<76tTzLe23(nHh%Q!8@pYgQyPoOYf5vG8tEH~|vcM{}cW8bb z68SgQ92DPgV^R;xiYAf%@S78QUrvKRDi$PVHs_c(I~M-_9m`#{w3-PFL*ZXK6c`Pt zD|G2Mp+;ZE9$uItfw)+fUw*4sdUXE5oB)3O_~hFuLHb|;gcf;$3H@&wU077S}c+y+qs$8<3XpyL;sT!lJ=QD88(`Fmq%Z+!|;^qwCN zB27vIf{KX=eQj_9LTpnI+?g1NAhbF#0dI+5%*N6HMzw{L37)$RL=8$>o1U16%MKh| zSxMa;*i77A9ZboO!q~UIF@;hD;{n6h4HykDfCN8=uL<4+Qj}AJ_YT241z2ONY4t%1G`UUHXalM1 zZ-#6=_h)f`w*aLAawF0V_?t{@1hrwn6nym_Z^qchNE8^z0_Um$=~KYHFksY!zs>_N zHzA`rb;ZDXvi}K4*c#Z{nffURRZ!~Y4u&64Lw^Qu3uv$8xw|b+g~Z9`)d4!xmL!9o z{S2{{tp(T>cNS-K;?8RhZcmI~-P*nD)O}n|)=b+4{Ai0i?axC8!M9`s%0Tnblgi95 z9l&T$^s5TZpM0f11ji=U-q)j=n43UjadBaF{0R<&7qJCVpqQt}0p9^=8-sxN#@3>a zLxRxE;TjrWf&gubu53Y|3Jr?-k$D4z-#8CJm?FL;ataVWV>>|L2?64GF(6QldlA?J zMEAIjAXsGnr0O8S%MK96>3~?FE0%ub2)!3hu*Rux2_pA*e`LxCg>z1@dupHrkwEGm z%y9V!ZXnh&P+XVD^p4RO^d4JtD-h#*&E&ZrLDKpSmpL#YI53g?=hKYQ;ginnL;ct7 zHBbXodh5(!80v?)sSRY-7f@1D%U`Od*1!DTh8!yf7(gVwe+yF(1`7N$FbsbPMIRYh zym71a{m|$EmAl$M^3CGR+QiZTAZ4kDr06H6LPbS=6g&*Na~L0efb0624LMKW=LFqi zbkVU07aR(PmjwnCy!Er1LdK3v@65tmK88a|zCa6-TJog%3n|{#00Ig|0ZMRZ?)Xu6 zAe#1OXZJ5s0ZC(^H(!4O>->E^=l-6Y5rDkK4GafY`#U^6^tt`epC0p5FblZp^6v)q z%uDs4KxP68#dd#-aVTeJ2<>d32k(a828bR23k8=dg7nPh!UIbYv0qB4oGxO?a#%SDx`<;&0{< zCK&Z8s+B?4@NUESVqf^RH+=^_XgfxpZ9H~VVw|eD^cYVSuO;i(EH2x_eGQSB1H}N1 z^X&p)Ts}PLgZ%Xt-i+-2GUF6?h|~|Z-WKwvp}H-+Yx+*@4!)&R#l$Y%QQoOni!chM zd*>u-q%Ggk=Ho8#tmchU1-WN1hLuW;+q<*6d$Psmay=+gBZ~vx`C?6Io_^bgab5Y( zn%`AJSL>1g{%ayStc`3Bpn{9!unN7w{|0r@F6~tA zkP}sCojNn-U6Oyn6q@($@oUL_yGVj^<%dS`ikZadb!02I#*iTz6z-0^v%ZYgPLC8v z0idkCI@AYXlgTxk^p7&kjcI?b6dw3>Z6%bPb{B>nTr)U4lLQKY`lx77Tp*ci8_`Z} zTR})Emdcy_%)Jnjdh%$IVKCszFMtp7;s<94C3MVed%(sPbQXCIh(FA4H1pPz@Je6P z8*g=(E|}KoEV_W`gKC=U#c?Oo(>*@QX!My^Kq{P;`ka5}wxIv$B~d_Vu%~E9IWR89 zOV)20&XuIFkG4B-4yXxGQ|__w=rg90ubQ68jaYOG5ziylzqSV+_mQs3ng^X_UT@3HZ@4;}x5QF>eSoHOQNu+6GpaTgKMqW?K6lzs-oUGMgF`Fa+wJfXp`e(X_Y&*QmfM&-rR!O zH;R@FY>6r*%G-O9`R<(kg^m1TjI!EMc0r@s9b%Bnv4o^6h>hnZ`F8`Nc<**wll7AP@&fx<~M_@J6gU|2`k^mK=ZTeHw0(r>o9=) zvOC)|u4qOGTi+UMHqMLuT~~zS{tK-Ko)t^IRo$Fsa>YH65#1?7szCyzW&u>1i*B9c z_R9NdFzakshMWyD4T*bL*mZk_>Q;$EpCUA&bXR>*l>TKkLNYd3iaRw(>B-YsXskiw zPx42#+>5L`!Q8CW^x+5)-hv8S0wbH#jU3rTCc?c}6_Nb0%ICRV?HGTLP(ef}WAU}} z?+lTtG2MNToY#pRcZ)#1U5A0B0WM3o<`kkfqu^6;ZFO~(G%D86{{THe!oSfM_{ouY zjESH(nhmA(rTr(Tn*uK@(=5SHKBtL039zNNNIdK*O^x0T(#}kWERU(GB4AMFshG7A zPUSUI)804k*o1R0K1PJ(+Uxe`e%j5=d#v)TF2q`Cdbg6zxmD-iDxWa=_l&}E8P^HQ ze#lDQ%VudZejSZ=@nm1ePMFia>j6MGWZ4g;lCa?L-9jd0sC?IyreBf9J{qFxqQw#) zmi9CV75OMEp4kRZNZ`Iqi5w>VKBR|Po^e_&se)ZnfsD-R@$lhmBV9b!hE^x`@eFWm zDEw{!7Zyi)be@8l+%&{sSqY>zePxRmTqGwjr<=*EX4TY)gCA0Tp`B0+MDUZ=DZvgssoSps~2?n2=!?5{+R?2Hn|j z13H)100d%4#X;CIHf+j2Tq#QEj;E_CGsQjbin)%k`3B#|?NE+Bw@N;l$vxE0dG5%g z0+5rLAZ1*PX00)x%gC&Cnae68(*v6rB^{QY|?&zssKo|ioXK*WTG6=@DrO^QL0gMh zJt4uSS$x`j8-gTa8xPWAcPcrCkIAv^YW`7Hlvbt{T^UP;-^(Lci5m|}XA@^f zv^Ssc4OkVKu&PFV0A*ZT_G$%vg51(T7dg@Pa9ME||Dl!b*0i#nkWs2E#0h{r(1&(d3I zN))fV-Ml#Tqa+kUv}!<`I%Cpb;dG||=}dFBy-4!#lb`2;*4JaGc8VO{wxx1C+YNG% zG1)NyWo{4$Rh>!9ZQ^X^AZZ<7`eGd$S?8waeqFbOGL=E1L+as!om6D!@}mnWgCHa} zoXaKO{1nrxd_ukuT!b9An9!}C)lK=+^3mv=_>H-X`Z~!qnUUsf3XKj zXoQ6bxu0Q$;5-|f1;#I5yB|-%pMiTj; zAFOtmYqrrg)Ju+`7(XsnV5`v9yETOp=u1`_(?&AI!qR%Hz%|cx@-fnp>l65U{q1r> zq!WiF^?Po)go2Yn$LZ^Vga#r(Xp=z1bX@}V)nE!{R#(&#D-VP{vKeOebF>=Q)!_aU zc`n1(yj>Fc!Ys7mG4&p5F;tyZhC+S!(g?+BxX_^lZN)F$cw*G0E9NSgmyrj$a)29S zy*yd{!2A$pa+Pm#&C(pvm9R8QDRU=U4h3mXgPPZUXs4R?K=0P-1$@MU@Y@B=PYMrL z@Z)0OsvmMse!fIpOiKrL&c2n1cwbY;5B^b6aQv<0;)WA>-p*@cdZ$(~6-O^c`%|{r zxJ?FPHO`^t`*NSL zrN!#jmoIcJ(+t7S>vymlF5A0 z9IS<2&m6y?clZDNVe@evk~*b@ujF>v@%q9x4c$=CGuC|$0hU-qgecq-%LtZU-S=bt z$vNR3BbE)qhM`@ssiQ)&F&W*I_D$vZOd5p@uU*F*)W)|~Xoy}-K54a_2M_c^y@~ZS zCgTGh?!_*FM4Ngw!X6dFpRz)(m<3#BT4A9fj()aY&wuLC05`}Z=ERxJw}ww#{)BDn zx=0KI4|~V4D+Z@2=&r2ea~Yfkky3tdWh*>)_%$AmC^5r@nDPFgAxtbG0C9Ew;jHAt zx`9?`fXSVL8>^p0a5je55sdm%Ezhzz;T-xqO*9e~;VZVqpHF*tn-bb2(`8!FcT9=n zDW^tka(7&%cKpm7QZ2&IKkFPBAkV_;O)0NR+%Obrk)8OpDz-Ss;>8{N8vVJ6l*qVr z*wHCMAFSOgsLbnd!d!+9ExK>ii^FAlm4tN(l!OheI*#4G>1EGrW^mWA$re?HQb zMn4aOL5pfBe_My=Tl~miksrL#x0plhy{4aVb}UMvj_)^Ex-+M!(L@FSurmkM_ zvMG98olhoae>6{|K4I15X|c5Mr?m@qU~hfb3Q=WjBRqe?fmMg1U2F($S+4IiRcA!9z6E}uWE3Cf8E?i|RBmK8O02FR7){L#;jD6Za2V3+2O_AfDIt4pebH5JIO=H z^(GQu=S|5JmL?cxc(5RwU)<{Y6eTYFU3x4(LPk$u!;q+i#i!hN+m09x7y)i8iST>$ z-TX_FbCs1j6P8I8OIE!+6p59jy!%V3RX>0+R3=k9VjgMw4Fe4Vx!aOPV1mjL6p6gA zP_1!iZ-6c~V4P_F8DatW+S_W?r7V3v4a$Xx-Q8Qaxi6<_&@+vQ^V}|=5(5k;WMAe! zZ!(y8v#ckk9gh?aY?FwWB%+k>zc-O}oPwDl(ok1@_I|plYiQK$t&7w}@SB+@w-_5B zmS{f@mzQ{j9U6-w(z~w@=Q;RPGycOjc1xfp7qls}@O9l#ojNSF2JCv7x6 zEtd6JysRKx2rBfO-%DC$Kl^S}6YthOoA#?bVxcc*pGrWnnk$n#hTbH{J@$;(AY{moLUFQk1Ds4G< zyHhsRo;kO~kL-5&;NE4*3O%5_{~>{xTKkLrBs3=fSLcI`UOI8^(9O$UkHE~}G>MPe z%ei#n;l69`*WdU789X>bxjm==dXU0#Yw(H&J>-Ki3A?C4~sCC`H==~u~6f~Nm1gvLHeUj;?Bt)5^AYsWe()dB~8LgSo{O1bBkpp0*dd8LI+Za zG-Z3C9ZfB;s7t7P*NJjDyJYMxHOjaunkb)1m$55kl3rQIi_Z21(!eI(-<;g`-1~}Q z8LNrQ%+b>9V>)7d6@SU!&}C>Wv9IlUGjs!P7SZ?i>;3&l!ml1dq9sm(h%C22)YP=B z1K9;ZehVsIbu;}P+1610*ZJI`SD#Jb#;Ka9)T~!hbF;=<@2MgYhp<7cew9I?!2<*n z>}QDNyto7fZyu;HlId3In`zSVSe5JsWU<=^?S0(mTiuy>NCI3)1fCSQPOl>+fT(tF z0Fs3B4Ew8M-}7Yh`wT^vK|>xl(#9wvmY+n*quiwyhA5}Y8)8)2^0N?2`N; zF*9~GNz^Hz!hI^ZAa;(mFZYT7qpZ=j%2>_&m8!*TLwyd~zm3(TNldiCEP9!K;hPEs zm98?>6dhr(jjQ)FEkfu=xyBC|lOo_(mA43*2$4!qz&elanVSoi*6-Tz^$Sj?FE5&# zZ2HkyVm^9lZe5XqkgAzp;qNu#>IOaqi3`3}oqNYFiJ(oC612Z^!~euRq^9=>F~mPx z$VDy5=#4pDr%mFyfB}2XqPpbKe>vp5BbIIgIl7o1e66rvJWTZ=CY1ASz>{i0`hzP~ z#f2$a*a(LG4EKhy1!+N3 zUBJg59*$nY0p5ANGPAYHXki81ekP@})~!X|LM-Rea~H}8%)NX#v2$AAj2jl>pQO^Y zSH58qmgE1xG&)(r_ItX2>jgdH)Na8v)t@G`@9+|aQPDY7@q#ld<d*_oFs= z;)~i^OiVg_@>7~(P_5R=8n0@X1~>kjfTd*tBbpoXjcT}4xt0}SWj3ymyTGn*;E|=7 zBt3Jz>EBEbR1RBLcXSO))catemnmzg$p8_q&|mKks4&7J;>k=9RzKd3K8K}Cv*J>Z`AgH`%&)2!DDNtSk5vej zioXx+#q3>q!1^}%ee}aQ^TMQr0!J5CCE=;&j`|Q?jo1+C2ie$pozy|$&s$k!s9-vm z%;da^O?z8Ddyr|hR=omNKYf?F7%_LONF)w__i8qsn9NXLkl;}XK8hSQAjL_Xs82p@Q&N(l#3 z-pD0=7i-1nyxK9gy}LK-6J2lz7io}SQMB3Gg&+0Xp&dmw)4~*?K!U69%K|gc@_Kps z2|TQIS`Yk8%1RebS`oTQSQ)xiIwu^dca|>I67Mf^K#&+ghA&}po_ldtH#<6Y^LBcv z2RaciTxDC(qA{ON-%2q;fm6MM09t6kC88l2;^Q~!(YCg_Lgu8ZGqj5SeGyF{*PE#$ zyo`@6FIQxX>U9*ZD3k#W{(=#)t;=A@QVrMc?Sj&|Hf*#V8QByo9y0*x(dI0q+nf8y zlChmtVPU%q$4LI;CS5L4#Lq}yR3^ zr;6SorN-(|M<01Gvz8d$-VDgFl3g+{i&aCH9lP=_=x-Hoa8MzCEz|2+L}biHmz?~0 zzVI=y#mb~9xpI}Q{d`0F;MD2NM~x3@xRqiBFFNl9eXE8=E$tO!P7@-0+vUR^m(d}I z+xjEuKil(t_qccKh_(FQnY|6bwurXg@_mZA6`PBPI$#@1yAvV>?#wCKLEAGM#OO^o zF1S$e&FRk(91i1=v?j5sLfhM)ZeVnjS`9C!+xho_aCS-7fVXS!Z$w(kMsU%BW+~)s z`$=i@TP0S63;EMH?3}b*Wk01ef| zV~%9n%#2qr*VpGkO1FbT?TZS$!q4R7C8BbIj(O`q{VDxs+|5PZpY+YxoZHT2Ml!~s z>H4~CpJt4<-gDy1gI)(!(wnT(qUd^rk%hd6c=Gy}(h1|;WCn=Y5?c(`^+a@!^}_#Zc4In{E4eRjOb zq;g~4)#$lgak!9*E)7eqA+HCeKiKOqcdtplmz58>c(e>$!xZ5$k(zw`)^&rwabOc!#)_hPY5_=JY>;vs8mlT0wD&>I3WKCY!R2bz)i>L;9UQ6iE zTua!`^$Ysz-Yd5Jw1ew169I?9g+GP;P+?rD4OGnDSsn_D|4^KIS9NRa>o^CDjRm6Rq*4pYEjaqvgQtamO50HKqLs(FaLdm{&t5Hg^fm-^E42G@Dh( z=pqy>JG>?C~+%MMzN zGdMf`(i3|@`(tl>ZUqT8jEjp1IkUjr%Gktn`m84SYm@IvBy|iN|tQRgt7y&X5@;juz0EO-Sc)otgsa# zq{k~Jvaq+DB=Ux2q1w*li8AmMUrZ<{~VYkie8r7yq;D7n)^$B{&qG+!;CDyZqASk!^r>k9Hrq%rTX7EqKn3 zc9{X;!|7-&TVHgvVno%aueNsW<}@L8geKYWafZCT@N1;27om@ppz4K zU1G!kwu|46vb)V`WQM?>Yo3LVG_@vU{fx$^&Tg}}5wo+44N5eaGsF!%QD*&hq)>1_ z_lJ4rzSJk}Mii_!@b(O)$7Ym^9$lgHM@)6}ft1CCn#pELZJDN+8dJd$R~68^qJjv* zhnnT~jb@v6^>tA>579B`M=WoOn*x-@j4R+9GcH2PHIEyYT*i$T!O+75)VJc(Q^Pkh z3ir`g3WM@0ATc=b9wKl>_P8SrD{^iehOoX|WRE5gKHz-?k zof}5}jCl3F|JlTE^-9Dy^`+VGU?xlkRx`0}iXb!E7ayB78fQLh5O~+>I*< zM~C0s>Toe^sd6i`i%?M5PSlJ7<>x%|-0tzs3tHZ|4lal*>A~*hXk@!!J}h|k{ra&J z-Z-T`6%vVFLj(iUN2l+FP&R3wLoJD3XA?R1NKBN}TsuPb9D%PfxknDWR%5{*689?r zp$}DEX`WUVJooX+Jv|9kOGRl1n^ag?jg;3n76+BiJ4{_IbXg}Zw+AvJ*6Q+oKfX6> zU!fg}X$C-=dUq>^&%h{H5j35V9#Bmp<5ZN3g6?0o3ySvVn+}p2@zF|?;r|a~3 zdsrgWmBDB~r%zzH7;o}9rKjR8Ap>3#4LV;*wDvt;wFK0%i6j2TQlj=$blJ%bIsXfx z&B|eCp}NPXGOwBI&_x8N*hf? zLcD?-ZHWNt3vilcfkb=44x`wf`2K#V=2S0{1YgV0_`nzk*Y`68DSS5D$kiqH8eupZ z$p*iY4tUdi85-N6JVmiJTlrXv^Y%k>bly{gY5NoKo2z#Vx=@Z{rYZtBR3|L7(1uU_ zfnOD-ss#=P;sGDr?%kR8h!nkw$6I!5>70fiZPN!Q<2wV+-}EiKo$Rr;l^1&X@Dye7 z7#ZU>jPH-DR6pXiKFHhn)iuhcV3d9CpGIC71>4PO@irdX`9dKnY}+RG*j~NR84tT_ zmB@jrPA+hcD1voYWILo#V8bx+DF;8qsz5LnF_R9=;x;;RGK$8|f_^g@o(& zxPg3n_7xFX$?Nosqw-nT55g#xv}_VeCEN9_>D_Q`Ioh&isNop5z(btNLD{}(KlM?0 zca&S+>Izwf-0ZcZ8ug%cN^qRy^n!-M05)!ex^Jz4Bze7Ic~cW~zC|8eS*p7%Y2U?K zIz-nYfpeN72~F?c$qb;Lkj zoZ*^LEhml*DYHCL-NB6JvIdeGS&L+}%6>O2+hh_xP}09{Kb`L80Eo}7MiyuhhLlK1 zEoEfZ+At)B$P+{cewv>YudnRFm4qF{a=O>)By59Add$a@TA+NsA^iSEb_SoC+)Y&uHtO8!$39F*O|Tor`gcoH zV*9eHRxfr8Hmef(CZ}=o+Y0MXB1!#K#fCw%)odkzYt>Sa;bcfHfisF28 z^bif>@kl&pW#4yXs4bGNJ^0kd%IRQ99pR(>8F{*nJAz#;-NST|^r;(K@icFVbVA{! zsBSpk7%53jZ)a)?lggd+L~IItd&@7Y+x6odb=tMJ80)gRm1G>`ZUE*d_TfE%@M$$Ch4xc`d-UP?BeG2>bX7PsI+)eGk;a` z{_G=WfAbB}GUCq7S9fDquqZ{@+v11nnjcSZ##lk@8;(nv$4AGEN=)gsE?3;fSsyYl z?~L{$Gy=zDj*M~ePRTMF*3IyK@%kV$8--afDe$S!qCG~%o}J?TV{|nY zz8iKn-1f(`1RlkuZ-gMvmPS?tj{|#Jqm3S#Mn>x3Bvvyzbp~Z|IE`Qp&NFa~@pra@ zT?D3BD6DX>{IJJ&1&v?PJ9%0Aosub_$OEC0Pg(_((IQ0zFVJJ{FjmKKl(SR{bu_3P zkY|Hc0?mV(YPeNQQQgH7^oV047z)_nKW?b~nIT!{99D2mccs>6O(N99|B*hhvuyIx-B~mzA1VNur1th;@0N_ZWam+GU z)j689aywSAgIvDX$HDfY!kgdPlUr{!lncU z#!ac+(3XKMx!b8e#$e&P1L*sgr(5fb>Cxv^ys0QG_ zo!>#HffQ~hZXcwn2R+@8CHZ9f;}EPX^w&@w;<|pDllpf@`2B-Y%FUi31~mRmB@-qX z39*XU9ch{$TZ3J?Qu1Lux6jHrq~M8%nmZMzYrA#2E3_bm&x&{i!OUc9XOuKlcC}OW z@0g)}6lEVl??S(Svh91^T(`tH&Xiwb*7$q~Ze48wqhvkG8F|5}fe|y|LVX;OA#dqh zGDYO$p~#WYI*ktGx@<?Oj|7q^dI=KMlnkH2?~v+rfsVyj(}eA+ zHT`a1W4MZzd3e=touWn#Dr~s$9`MiOc(~xRWp)ZiSTH_38oqV``c5hzK8JHk3(}hR zHX;s}c^{g?FqW9^+h;EJhVU}ywo>tsD%m31LRoUuyesD&L*I;2=lwE#^BA3+5gT%+eXUT?cXzNlkNq}E00&O^?y&494kZy- zD|MnXy#;_ETf-}`5@4SD7`8J|n#o5U*cEfRKlLt%V&& zVU;%JJkjATp4M!emSNqlmtDJ$m3s@9;0GPPZG=^UYQ+zsWZlqV#o>xFki~mKIegH6 z&ux%{E#MjDFmT2e)R+BZJ1T|eO}b(>?Z_Kl$)fw2r%r0SB)b**Va6^?qp$gUeO4E? zZN3^`oDbD9Nek;ur@m4IT)%^5VLDc&iU{yEGf7wE(8fs6V6VE9!CwsIX}dNRzpP5Ymo7Pz=z=W z(k7Z8IUMTu3Ktsp#c)Y89oQfK0AkfxdZ`z!mNRBt5UmKmD+FWsMRzsXvmh$dA?A-tn8(EY) zuUP7R`%3WJWBwvZ$?GHIjqs4i8?B*Y?l(W-3NYJVi%)q1wbqFAJD3!6HBq0^sYCIi zo`rMVX?JtA)iH7L)pa~}c*0)muJ=muFu8)TK9*}~O`;0R*ew@EDRvg~-4m z?YV=oaph1Q`j+nDKv3SqVixqwyDOrH(_YzjH4r%QPSg2zq^$P2#5wXxuBYwy_c(?A<3IRYu7SGcq3#fG+wg^ zak;Czs3I>jXebp2T2Bc-B*rZggNd&wD12G(BNNQKxU0Shm}K_}rDAAPtb6j~a8bYh zt{UWKYV3v(O#l@TOZNcTA6HaB-M&lXsowMblMOFS(3Z!8VS--&x*CJeSF?)wPg?ao zBf3sy-q@FV)F=8wCsU-`2!z76SaP{Lh*Gebb>N6rGRTil8VD_-CVD~$ou zzK%=|B6f>FEj=pTf(xy{jQ0_1?)qp6Ds-m<67MiEJ_% zkqS2^F}UU{2B^4(Iv!k9(iIn47`H3p*0`E3oQVdngSVT`n75sJ1Y)|5Ctg^8M1>U! zcX?-Rpq%oYsh(41BDIa%LgNXtRUk3KoQntdo~VyJSOj4XiZ(w9b{xbs*ss3&64&2g z+UM@hP4+Xuzaxuv{%+J`xk}ga1=w1Xq~|2NalAldPq5y74e+k>f0rzONPwq#=6&@e znOXwPy$*~fBL48GxEM0{rFtRCbN+T*m>p0AWg85Q30hTwmYf=sdJz$tMit93(2p-B+l`Bx+ ziN1Gv@QNoC`~8!540wWu!QKMQB#WDCeS2;a*3WJfGJG`f*m5LYS^vgsX?Sh{=aejF zCf@Z`eGPJ6SMji1h;6XKnFh@AC#0YWuIon)%Af1cQX;C_sn`%PD`(jD9t?A9T4hJ+ z$d;IVdrAVCCP=i%XJrr5=V^J>W~HI%eignf=GAOiDtGEaR;p)s9_Ox7vku&5=PL-P z)nBfc^`op#l73=al9{H(2pcq)J{s|9dUQS{MKucV3D#9-L?hXbi&4zgguG4FN_a9H zq;_sqU^0`bT-shEqHtDMLxA8qY);-7ak@UfLYZrwna6XAHbb9=6`3lY4mgNXP&8~8 zaDoLIsDCq2BLYml%kuP+e>=AXerR)F$6Px+z0gzr>?xEQuvs-jZckRiw(8=p&KCh+ zr6fRCs)RH^6*F3W(Y`|#kld~v9LE}Y`Bl9$4h6uM^|LCFyb!+W%e7w26Lsm!!-{yU zS2?UJDRVnhm^tRG`|wCF9G&r3=}>sD;1-ui?h_kb21DLF1@j+QhOt5u&bFv8G_j^F zg0s4q%j>P>a_w9f&dmgALuT6@S_!JS1ckjOnX zXXp@)ijIVtEw7XTzI~cYd?agyZ}>4uGhh<#s49X{DEZzgK|K+yP$s5-n?W*daGf5N zUnKcsev&%D~F5U;$N_32k8d}MI51T>wGa}4WuGD~S zhFzxOaZG6B{JAIh1f@2#ZL7r;!-Ln>EWGe$_ZZ(6NeOZrB`i*id8hHA_>L5ptEphgNVKR%D?}K@iAwF|a<@6qUXRSJC-@3+joNY1RTzyrZUMchnGCS7eg2kL{ zKTj1mT=nZcyRSGf^!RDz%YsCa?keUig|Ny$^<0~zYfz%3k$0(I8TGKZe6(JIR4k*- zj1gN#pR%%1o1HZ5`bnwP`^Z5f2E!6+lF!>l`ss79jG^d{s7dSI?aSls$#L1TAKUVu zofaP`fcppfZ|4WrRM?LJBZLLFkh~;~&Nyi}>kx>C_h+%X!cWghSjN^m93T6(aq$}VQ?rDmA{cX1OWrQhAnCKC8I=c!v}h31#3v2S(&AC6>~{H;-w7-> zVC@WF0R$@7Yw%>V%lubaf-2x%wcR0dFF4D4x+n63gaP!{B6IWBE~eqLWbcG{$xAQD zhohFGtx+Cx(uR0S0(YwQQLJJZ-klMqv?gSL-O@0Rm|28dhodr)Yxb$7{Xmz^SvDA} zBz8|CC|Dsjo1DPan3KF&DOP}#*|ka{^oW^yPi#lqCR}qIK<(0=0Je{?#{kS_^bksm z0O&7%2P}>OA{NE~vWPHKw>gMOrckDIaE2b|=pPKUt(*&uXDs>(tJM~$;N zsY6^+h=n`kQ(cR!F9EbslHAxQz?NpBIOWx#S$MR~`tEuka3WNrydUmfp=)x_N_`_8 zZw(%ze(7bn_G2J@J`mq?z8da+rQ3Ms!}=JRx;ETsOQzgi>>F`pr$W0;Be;`jz>pyA z?2D47vUh8U`ZlybU>9sSmjD1^B<-D~0I+#8awQ=A77{_n)ZF{7^@LB2JJj|rKCK3j zx^HNybS%_<8}_{9lT^8BartJ@`Rc8X%!Z{y@_R+07WTwy+ON8j^^9<0PWsKII{9IeZBrwg#>v>ChdUVk z?00A!MYm87%>%77&z2{oNA9S`^iVqU*Ss0=(E|!I_HFm>n5DG&A-yn*n0Te|Ht!ck|(2OC-7KWuN zbc^nJlUQ9}e89@6VGUpuUNd~CVy|MKT#KM?WEgdIL72_s_G@L)kDL(^C{tvoVeh*A zW?-rQm7UP{MWqT-m_5^+g*>?E+sZ_q;sC$2@8>x*dlBS;bR`}XCg)ZdvRnarGb;!q zZg@X}=3Vm+Oi53P6sI$YFy#RC1y}L0>6tJpHkev?S}u=J#H)mAP8+j=0k0j;fuF~> zP%VM|dqOS80i2Oo6VsJ~qutS?-ZIP4fQd!gNhoWNn zttM2?KWeRACbvS4zUwh#ig9omq(DnMf8$T@$PFb@pVmV=^e8|5bSIQiiwLy2ce@#= z!6Q)MeeEBROX|?*D^x3KQ^ZR}kq%NtLk7_JZp%W)8#f|;*My_v94yL!&f;QHXv_7y zCK4!-rj^fEfvYA*aaark1zr`8ehsuWtv7alG}m4paHv{ zYNb4Bkvf!?Wh=$PsDv8(ggkT6jrI2GtdvV|(lXQdh*E2ow7u?K-w@v;L16{F%eozM zOWD_C?Uvp0(gVC8eM=$d+cn`a9tB$en4fTt>|Nle?k#hqDE`tU-Viv3VCaHK$s7QU z7?b-TOtB-IMhFXoNnwuXzW2(mO_;ac{_ocd_dmZ^$1e5AAlX`v1TTYm%!6s%tflf^ z&Y16WY>+skR~j#~mKF0m=n2Gmn*A1VT}6|_)hd)gM%^%Cv#D}@^RVWHJsX#~o?bJL zu`)HcTb3YycSmwkKuW`c|MLd+vP}lY4FyJ^AvGXYxi1$rDGW1w#SKNBk_G+a?J8V% zZe#F=4_1*DSqw_GUJ$!PUlGYslw7}yLhQkMR@VfCh?)=ft#c}j>$h`#L-T$D;~_kK zEvh6m6xlEl5UidS>!s{ip;OioohIhcx2VO_LWBu)$lnIDN%O*AUuiF#U}{cqBQh1VYWP~fI;+qSP7f9``ApK5n2tlqqlj&;%Wzyz6o$!;PWl;{ z#QlrN%LIcd7Zhf!^8==hCBUyZ9@4}ak}4b~VkSqE_3&_z`SU~cILTe&3)NwH!!wwLgBbPiG##E&sGY<$4_5jm_ z_4&SRqZphJ%LnE*t*(7uz$R*ivjZdgu6_~7o6LeFCsy;E!X)+6IYJHtLh}ew>P69) zGQL4|HU@!HEf7q*xIviW_L1Ppg}ChF6!MxA0W)*90c{=%W`aXxCY#ROlKr$uCyuY+xn+~QB!2)$K|Fjo97qlBzqmPx9beYnuahGz^p@-zMZBK>Qo+Im0R3`6wi zuH=aVFTl{*fUbyq$o~mj8KmZcqx;g5y~!T26+h~>wDj)W2b4mq`I^3^M6l|L08u~K zxIoHd7XTiOsI>Plf?x1Kk_+E*U2}FUUuA7x{4G~htw84lbo-g(hs=Os;BD0R4O21b z>+q$){GSOdBccEm3u-}*FyvIHB~5Xwzsxx#jYCLAetA0d+ofc%$nUtvmlkxg8tus) zDr4dGn!A$j5#>6E@;&Ip$jh^B;X$zWlYM9WZ8s_jUCZzEmp zBF)MA%gH^F4%E1H;kAQub948G6)fVd@;88Fsl9e=ft)^X-pgbte$6O@V|-Qwl147= z+6R$yaGr^wgGklF6*5tzNvZW3+f>*R0I5RbLZ&EaQQ|vRBhhO1$b7Jy=SPwO+V2et?!Nf5qB)`ty4NY;IgFWfZ;Nkv-ZxN7i* zsz8X>BY7=Lgv&rf+BlLg_u_ViA(jKhcXbQCQS0PmKu$9}@LXm7pvG_f(&~19J;SS| zimM?C2&pWgKS#ntp#YRhYcc9;Lg%*HpNd*!oo`0LlUE_U_+bdl15IqMQ5+erU@}Swsr??Y-STcdUsuO` z8!YSOxlUWbK_%fJ%rXwzj<}ia(LErgQhU{pNH7gE2XmA-uS)^fa6-I9ijxju+d^sV)vFNGlfO+ojU#(>Br_`4Ue95z1fi$JA8m#+tB! zCW#PW?J7l8u*)`@su5lyjHuhPD~!2W=XI~)v`IN>wRm&9tp&=5CCMx_C3`l8^ar(K zUEb__Gv84c3bvWN+)x5(+31uxN`HKJfu7&(<~W-43zRqQa>r2|AOdP*P7k@w36I?< ziIYlFVYHZXxeBlY_>E{2pG)-zCTloE9wVvk{-T3Xk!6))#MRoImV47hgP*v84O0f7 zaXj9IDaD$<$>+CV(RY#j)?k-?>PDkKWTb#fJ}?ny1Ga}ID-avAmVpgKMgJloWE09h z@)6wrN}f!(m6Mrv0=rOvTRECpnsHFIv2h5%B_V8+z8_K^uV>{g^v)1>f&Paf zy%Qa5f-p%U%UR=W_e}P^FmgeqV99!oJ^!9FBcC{mQ&>a%8)On`V4-48dTP$_@eH`A zmjXKMMKR~QCCDP=Btj)dsdbGYjSEoxb+f4CM$l}Q4i(yy^qH4(pvzfz^)y`}@n_6Z zt8f*p#zcf`E;nJIk2MngXyq*L$#Ed3T3Ez$*irIDab6M9F-g+gha*ILZXu=c4XvKz=#Eq~!{5}*xl9Qx*p$0gq^-^Q+b zwYlZwKC+RR=4_T@1wtJPL_}k~&@T(&|4StWkb7qVWLywO0QQ_6rNVYX=I zd3`e;9YE~Zv&Jk@p+_5gqC8L<(>_3QPpQM)<35EM7DoFsffr=8)Y~EPD|MxH2W_tq z$#lzbSMtRt3+y~*TrHqTYEb;UQy~L1qr32f4+42l24($fqEC9FzZ-DpwaLMb{4W71 z-vl_UVGsVtel+o$MN-!R=auXofh-B6jiRsL`5JXY@T9GRJMVp{$$XkIBzp^sk7?VT z5s+ua;>J5qUio8ax4wm()3beU%&=Uc+{`L#;M7Aj*9u<;UeeUPw*Df^HO}LnbfvL_OZacrXXeIwp+(wiQVo)+SxfHMlKO=E9yx7Sjw{?YUlye) zsJ3>TFUJ9ccJF;bZ*UZG)ocE^XBg1}c(PyJJ8?=<6rHdKE{Eb75 zc3#plI9QSMeP0vrM>5NjieC(9BMMIn7yF8J?@g|+HU_Uh?+TSP$j$8-xFljahBV2gAX-SAMf?4jp2G7IvO46HMjnm# zayXC9bSr~Y_0wOkflSiA2|#yo7ImBDaDgRgvy_&waJEmCaG7j5un3gxM_W=f^11vWSGgA}lhDqOGxI5nk}4}yYDdp&e)vq$i55|s zXZNtRbsfGJ{B6XXE#ltCf+voOdL<6U=4P3Cha)w5s?K5ggqJxB$4W+h}opmi42YxUdY52NKa+QBud3-8IhwIAeGD7(JO; zY^-K%PLHSwB#HNEMcz(Q=JdSHob^{earYU74>kLReSlx|V>l1YLIB#41_ob(7xOB&Xy z6U=%!kCA(FAPIvD&q^5H)*FJ|;_HIzi)3Etj9VGxgK=wHGCz3t(gKcqH3yuvuHV%&HZs4xh$bIAi{CKlI~;Ur3B4>#VGl#N`3A1f@x zWD1cBOk-j>Hc7dF!IDkm9U4}`-e#(=gbD`Hgs+57!4n)rPc5pnt+>OAxyYEm) zz(xiq2IhVQ5t%u=`v(a@!LW$QjE!pco7{@1!M6aVBa^`R;_Dq|OxkkM*}c`q>2-2p z(AB$a8X|rRmEU9f>rB0k6w}f(pw*4j;;0kwAq}34g}HI7^Nw@tDEZ18_h^i-VtbiK zAjC(d3F%%@kRQ9-PFAx8Qa7lCa_ERVh6y+YG(K*Su)q77r03Jg+r~^5e|n~lJ+o!9 z_dxNtu%rvOqZT-~IlNDru#DEURUg#`L>-S;jjF;_FRry|@S*e!R*HG@P<_uvTLW*~ zJ)EC=R0j_{2GC{F5he0K;(GX4&%-Zjl@?4$tIi_?7oHc{+wsV;BxS5Wt^o@2@74xK z#~>jOOUcP2X{-GJ?;)M9*ECR8IQ*M0gS9aPw7Edgq-6nPHX^XMM0eRtv|vyP)eb`! zo?qr2tcgF++8%liZF7z#boxdISN1e-xj@n4bKgT0Qx_dhefZ7P>--B_x=0DZ7V0)L zTsQ>@U10j}!cm(GRx%a?8XIw%LJC&& z_LUhhb%DK0%|jR6x^8T(#axA~ssO`+N9WE-%eG5ie9=tuj7(`qV z&8jJ{vm}Pe7`v^U2l5gDQM z%pmvOxYE~*UT3Df%0|$&)OMS?y-$}x2Y^s{!W-C;__AjEa6G;0Ykb!kMfK4K?(JPs zY{NVDUrjYVR7AHwUh-Re#uX!0Dk>GNnn%h-5fm6_arnXm)U%q z?p;dRP2naFco3H+JqWZu@iSh~%6fQC{i!nA&D3Mc zRq)UV(y`gG=m$@+uPg?!j!vWl(WI|4P9FdSHjT^c8?$}W)Z7-ke2BT0y@@kKLZ9g! zINcj@4M(KEQi5vbm>XjWVcgOtIEF6HeG#&R!j$(E40g(^UFn&?&seM(^bKNi7eS1) z5&l48M&ih(KnX0$gxu0L==KIin;P(5ZCzSVM8?FFr}T6z1Hboe@NEwg6|U91xJb5* z_eh#@ytK&$)AT&rK{flOCn+|Glopl)mXUm<)IgJyw zrj#mkX%~LvQAV|}ZtwauTM-(`SR?k+0#UFujweB?Lm2|whNZTl+W}LkJFpg4QLWvw z75*RR`3(#z@+?t*I>d{F!1%+-w$@fj`NWo3zyn#`DSOf2=u9a(Vk|l z6ZwNbFs`UT?x%4R-}a7Bw>+7^$XR~zdsHl{<1&6=DImVg&~MWGQSacI-F??HF-4^c z+o$rODcbcZpFyL4)>8qmW>#9cI1_$%m*$y0p)wcarsm<_Ci9)FsoqHcxYmo<##EX4AnoXGW>4|_qY7@uGX2eXIY+?hlZ;8pOo^H)N7 ziPjJHXBdq$uiG1t>k zztXSFl+&?l9GFTx*l30U%Qx&uIgyrRKn zjNmhVL5Zqx)Vt_RWeg{UhWCiHQGgiZ*Hp)qCHm-xHAmz+&-jSM+_cT zjn$5wA&|%7io_o~Y{8-#ifBq>KC()bn2K}<%(gRlq*H;#>XJaNiy(L*5rx(PEF zO0Xewh%eC$*g{uFS#Q(t@NbIU$&$8vZe8rvOw$hS6ntMtENzjy@()0yb~B65R3jgN zQEYZR&feNl4X!^^ac0gE zc_WN<(69LyzI5SCOYp02&XBBi{&@e(tr$!hw5w$vaJCRT>Km78t+zK0T-mk)fUl@c zZ@T`ew%-s7);Vl~E$=b)BVX*ucVIJy{ppI%oG)oFp*BU0zDaM~2Q)b-&-NH+dXj+; zK}u6MY!D_$`@C zQqI2#CooI{h*%`}o@xKY_d3>vFD8XSHoFjN_TS6NcTz5#fGK*}vDF?;?6?nva)y&$ zrlSi4S8P)Ddeek1dK0FyQ_9_EJ;;$=g2KEL`J4Z?YKwnzdbal1MK0<~p$tIL8o6LV zjs@vQEnCu^zdTCP;{*tIoAy_+eTYwT^#~LkN`qei%Ive$*FFY_K@fnckN=Yz<0lkv zX$pDLAPyZtwSXI$<28I`vXqt;i%QXDK&kyTAaLl|iSgN_&}+hNFvt=qZmV=?$@vu{ z=Q?Z`E(mo8VCxs3?A4hs^+P^w^!!`bGMPR%mn0h|>h9KMsRJ{}L60Da7NFc+{5qA! z*XR;qYkaNDy0xAsmt0WC*ONHYXeV7Ld>nqW+|{BIK^2;Az5eK}Z2nEU{Y~?&`6Fz9 zV_TxzQt$#gt^5Oy8Q$bdMxxu%jLf2=y7X&it=CgTbjUcwi3kz5xS-P~Lrn#Yy2#FV zwY??HoFHv}Xt3>|_}$AAaVgm$kjI7G6uZkHub#6UH(Qc7d$)8`*X7ahorEJ_5HHt! ziX3IG0(@MG3oW;OwXoIUpeW7Ww~UaX2)SARv3@|jI)xFI^P3%7g6A>~XE%_-oB7+? z=n&pFBuc`4OJWI*WQn_W2vPXVwH6k9hb%T3gFfAJAilb8DzR!)+NNUw0oOeBC<4uJ zY9{L(ECW{i9DX(wv40ShZIuq9+Nft{K;nMqQ<+LQ8n2C!x_MeV%>h68ON-FSRg7x= z^Ol7yaZ|;V16{a4#BN9{KzL(=9`!LxLF|N7J>Tv{A>G8=Us}iwm55OjhGH}D=LAVI} zAgTG%0$k#dFr@U~4BhPi#n8>j#_<1@+)M-<>`aXRP0-EB&d%}w{M-ak^kRRk|C%}y z(2H3c{xuabHMTP`h2rCba{B9NYG?!Hwh`S5s*rV#L>JZRNzjL|wY|N~ieTagNCpE8 z6W9p?EoTpbw?)_{949b`pc4>^5Fi~V?ecnc!}+W4Y$v-s_4=28Ti>-;zE^cnqO@?9 z((2M0R>?7BfYZI*Z3y5Y!=uX!01wZH4iAryMobKt0SD+~GHTcYB%s|tJKyM+XlzhG z;H^*=5W@H950@~YftkIRY3E4;Fy|Hp0?1;{dKDbO0cpKHQx8GJr*=U!HFQ>ko-Nz)uFO zUuxv*?O$KfUpbJFA4Hg@dIuLrK%wq_1y4U*3?Lv2>Oc1V-Fr9y1WPaMh!74=K2hKv z0R0Gg&&2z&6aE0Cnz{gY_5HmYPL2Nlx_h=dwgzLjXzjkG?pX~)OKLmopU^rnV++X&OuzBLf*eXE(T@Q+qY!a+q!MA`3CB)aTNplN#e*W{A`{GI0R#Z zgTypc008Yk0(xw4TfK|eZk>KV_76X7{4RU9mj_osb)MEhNANAcygvr-9e}(7031`e zN4KALqrSv6dU}4eYhZA7VC#YT8owsKEP+=)L$RUoz@C6pZg|b3(0lLS@1Nseih3Ellq<{0vIr7(Zi1vBz%H`e)PA8R2u`16!_Q1blK(Rfe z&;O3$9y&d2H+%C5@clMt)^T6xdnx=j&+*4TB|?9o`Opr&=-<+Q_3OKY0Bqm*+wq0> zbAHYES5AKDDS-A~-oPJtOJ06TAH+-HAzsX%e5V&iaKSvgWPcPs5A%Klf7?0)2ZXRhTFn4>mF&a1L|pzGvbv3Z_QRx+;QSl5EBCnWIuA4-TO z+oy=Gvu_2hh&@EK8*D%6d$lJ;y34O!s@^3V;E_ea8(;&M(&RZ|OIayTak#BU)SgbngsC)(<1=ZNj~GN&nVDZ57Wgd?GhWs(0K zfVdRa4lCmpAH4Y@+**HBNgraZCZ;Ztp(S!(g;K7~9oVyBzUm2fTZ=IlP2&k$IfGaE zE+g)7W!E4m;ghp&!s&aqgX!An>|x}eHn6sYLe#FlnUYZHH!b&^QAHTK@h#Mp43*53 z!bi%@T$|i03GO+z(B<<9kjYwUR_i^7d`abaw@D`1ZulN(EvuR%!Dfh90_EYg<;<)! zG}6YM{%{nMHbA8~6ryFa#VhUBU+$o~d+xS+9`8;_9t)!0-ra-47lU>LTYs*74H8|L z{>33k1wB9Fli*p8^vuSl(u*&pL1+ly^R4JN9G3UMDH_vEZs*(XLJ%+Q+;dbf@yI1n zy^7mq&UU`b53}Wqx(w(Oz)bWrwE0)$6lW)(LDNr!>{)@m_o_j95WC7wCGrfPpX8;+ zycx&Ma`KSjZkU}xVF2=)Irns5!}da!wzFZ_(7$?98hzw5N zT$A+exs<|Qf89l$p!}J5D&A_Yt)ZLm)~v{*nR0)8D)SW0%QC-sPw|cKgjSF(^+BMJ zuW4}d=}cVlUq4)Cg}w&odv!d+ys2tm8i{zCk)P-0uNh9j8L6Agf4&->y8e-c90)tU1vn zk^mM1ZknlVC%sW=l;Z-f0T~+VMw&XR7&SnIH8Zsdu`F*P>pmq9p3Qid*)N-6rx9Ii zt`t)=HE)uMKG2hoFUe<(&xBEB`xX@Kk4_Sea-0=@)&L&XVsXfYY9R57c3UHl!_$_& zo$G*)g*Ho`nInD=JYyH(b3Qe@d5oXrZ-QB4p>F4c^qUvsuu`5|$<}ASHdr%mD8fY= z>Rux_mrfKO%~DU?h5ojRC-x#i=H$nVvWIBUIsloLC#fV^v!P1w5pKn+B2DlfXZd7i zF0Ds?sizjN2~;wHcTg$n zfk(F(L}bVtmIRzhvaKjx%BaSqG;0GH zV$0h_+H=d5j%?Qg7`k-jDeNZYjZoFYVveimCA5#GWaBqWe26GK+u^bmsHYooaol=e zv`PM-P#HoMW|^Mg=92L(5G<`lXZXR!soFR=Tz)aN!hAHI(p(#TD#x<$Fp_jGKaI|0 z6LU+4Z`*Ujl%-(fXGzSm9S48tB%dA+LeP34;AlJX#iNCTVEqa`r2_CoaS+(j$701D zRshKYTWJgjyam%B&^l8*1c_eAIuhRNy#$djK#bC65AN%}D<#hE@tfoWM%x2?J^F8t zC+s(T0C+N@xSCZEaSM}yuQ6_fBYK&saduP$IS)Szg z>+-;xVeUGc$a$?4!or!f!=!32SB~)z?9$U4ULpO(<5N9mB{)8I4)Yc6NX!B+&gi&H zo>A#)O}OXPwperVw{)5k@7*C@GiOTV4(>#5%_UC{+$aZu}6&%+l4B3k)ILQzX9k4JhyFH@P%ToMQA#R%t=P8W%Rl0T-@ z;%vZKuQbc1Cw8Cr!645koYNkfD3v{v74!F<;rRh;CeS^!=rQ|w89S-))E%srvcnv# z8!{>QP7buX()%J$qBB`0(&sMX|Hj&i;oMd2@S~bP1Qzc*hzD_xrLC@YqB+r(ZiIq$ z3bW?d7j)O!>8|vJWF8Gz;Or~jmubmTes|ol;Y<6f}?sGGnj(|3NDB=IQkni7*`{>#Sw+selTq%f|35O<$ zLdKVg-^c{8W2164Rv>qomS|0>MgCCG7TraUz%0Wl%u?6p-Yi$s>XzcM9b{JZjZKlY z9P%{n-O$cw^EiHA2!d)GjlTO#kXVImU>6?d-#J3NRrvJ=5>Pm(ic%x70wgepQHXWfrOVMPa|)PW{ne^aS{#wB3cVy)RqLiFc+yG6qp zKUmQV6koUAEaBC5X|8i;2KGPAw}gKMY@W7I(->MC+0|wl+f)-lLz%GJ{jC}_8sN+q z4M+TBwND~(`Y1UlgGcZziN{p zeeish$Owl1UNr>|z65e*OhcRDke17h=In#nEw|t@j*lC#Ii}t0J@Yw{h{~>juR=?t z@vf6%8t2YWnV?RKoQWFR5b`!1bwr_}HBU-s3w$P}f$&{$@`25KDK6~~dO_#=eEQCM zCEMbpgvM4WRvXNRa8Hrp!4^8b>+si64v1vS>ht|nxhVPfJo>|KWa<}vuN9ruHVYcvf zyRJj~o8yEMeDQQ|*qdr&13d}90x6}H4BCzL$dZ~Y>}Z)DEN}IIs^?v!LovdcV(_u(U-jsH8Gol_NXnCwOvz+>k#I}TizEYr zei~%i7P@Mtk%}2i8#K_a#0g}TWAU3FJY!Wjq2Fgir!%4;XXQh}#x~ILj1LmqDSa^d zuWY*43x9mXiLGRi6y!?k$iG1vgY%|pa_R7qq%JrAhS`-oGEn2uF4?eapxV6f{)?sV zjfX4~tp-!Ip-()>BUlt14x6U) zF`I2xlCo%%nqG22LXQyYG%4Pd7Z#)s&lIkQnn4^2w(&rVl(?S3yT0DZxFLnd56kDl z0c?^!X5Hz4p3tXeq3QUBveQFEPLW2H#6@S`uMxtT^37f04yrf$gYMaPz|UPk1Tr}R zu>ur3L^eaW%;qJs7Dsj?7LWYV10y3S~afe zw$36xyT31rkwK_=xDxqOZQoCk6*ZLB08MEyoO1gnyaj@4^y2&*`oW5yHs%-()jU;r z`h3e#dV}vK)Tn4Y(vXZ%>}Z~`QdfGap>a_WjodD;6ur>1C*{`eWK!qF9sTl`5CG?O z3({3&CFD7;jhY#!+S(MPo@f)la24mmKG}(Ozu2>t%#*U5<0IGrX6<$1?%)Qd2V?}{&VT+?cYJJznIy#Su=e+VvB7{ts)L+})p zkA_Bp?&U*yU-QC1Q$c6cAvnXh)4b|o7Vlp?)(n1|Jk-)m%A}f-SNrgw-{BYUuRP3n zS<)i!O{|svyY)g=1EJxpp1*63*q=FvWDDT7SL;xjuxPLuc}x0ev7z`eL;kIFP&y(L z1H1gH;@|N`y>yRLu#1!Bo@)nq9U&Ab)oA)&j7opd_5|U0e21{A&>Fa?U_%D;-6Suy zt_@p`iDjsq0F9^!xvVl5)H$LnSXrMW6!Q#wv!08_;2`)%YJUDb_f4r|T}wYnw*M?Y z*(&uP$o^-aE}>_iIpu8-lc$mDP>BW~dpnxjJi_~{0cHe?Jz9m8-Rf#>1!^$pLt=i^ z+NBbmmSmyf8Dx}~gST?Mh4udQkhoS}*b%xTqCMXzA!m@0fR-GjGK+Gzjix zTPfcT#lFwXJvdF=lpkZxpLAiE6aDpgvvS4(DV-Ya_f`|7Rgv2SY~2EEE#uF+A(yH% zp_({dWBj`sA7jt!l;(Q89*3fM(N(&n2L3pyk3?TDNw}pc-BV1ppo(hQquQ3^2Wjk< zz+1Di{;0wjJy4|EGGB6P{jg8@HQge^qy=7>vvFfRe`-3sy<^iOMKZc3CN2>i^yn}u zt36|Kcq;)6?x&v)QVKYl%b%J(&s?N}O2v5s9sQ$)z)cx5>c+_m^PSHG4SZ9NlD`~nIJR4bh7KxE&m@| z^_@e`^iUei!!1NW5 zES5ryas{@>k&bz0{k$=kSGkyMh|V$f6I9D21k}p$=7%hOgdFp8P#ttGUWo9}5miHv zGcQw8wVL+rt(AO(q1skv^QhGjaPW~^!$o(+qFXJ2~cKb-SA zz3+ZnE|xL_P1+L?Qoi5k(h4?aQ(N>eUXCI0AU(Ksref(jF|pti@yp6i@85(@*e~6A zd*x{@bz&+lbMu!a7dEm~IV&-DlV9}oBcZqRS^RT!*(2Fp&6tMC4k*}Z&RGShbW?zX zF=^n24w1Uh)43%7QeH3nDYA<=Q-Zf2e>KqM$)$G&*32N-L8A2Ay$r_&eJszUr!gOU z{!)q1MO>i7VI#|(cci5%`hhkr;5|BRM>WWbPwQ{L4fV>0^DOR;)ZIsaF4<`*-3~a|30sr$bHiNBbGu7N2~SQ_foNgP*w&o;iaq_TY4|BAAeNC`!};s&wzQH?!SiXE>fo+;6n4!mRG4 z*368H@`5TB(#eO(cA4s!>A(*g2ACdkyc&k{>M2O3%~GC7ceOrh@p0&BSHI2gaBOD| zSc;0ys+De%`kN70rojGr{gir`tZnHZxb!JgsUF_mx5kvMmExBg#kIUoJ4mebrXf2q z5{DAKNBO5HDl4qIBzN_ePC*T6GR>n9cWV|gjq8sI;vgo3k&ux&rrm*vjo#TFkFuG2 zO9b;<^Vi2s7p2!B_l1N!z2pQ7V8ASOQYmBmpR3t~)_^iC2{dh?$>^R65p$AkdcHpq z$Etc$-75DHKOZ=~#=ChwUL8gt^R)hryQ2JH)dlK3`FyjgFw`KLDofBNfo3)AhnK|q zp*Zto*VWr4{G-i-J+=aN&Q{OXcnDGN{fvy8@$ziamYL^&%0#~>c93~2JiW2on!K+y3)#Tucs~m$APuPS$TM*t49xzr7*`ad76^!TueVBH3J78;pNUI9 zDSN9+*?+L65=4HCz@A5;aC^8>bP9C7nx`u*s4iu-Nw&}OPvtDO{O#f#ttvWc>L87h z4EIQM z5~#RuU29P+m0Kx6yDKpdLip>@Uz(Um@1NT^10~cR@XS2F7CLU4cE??atPdlT{(7W= zU33c`AKI|%Rpq_WltPufK&k;>`=J~)-f4HG+IdHvx+W|t65UdRm z?n$CQ>KK(-7B?>9^#>{Y2=+8{IMaFmRV9R2R*p5KJ+gI9b7H4k?uK9ztK zRCel@z;$P%M-igH&|p@IYMLZo)Jo;zCT)<4xArz7|5ItSAtwCs`?=(HuNy+VUIe?b z-mYC?latTcWI%Uv&oD)Kj1QVv(+R=l{B=eE>n1`&INX(X_KZBdI_Raa8*n-b$V#~m z3U)Ku@Yy5^#gb0)C>nF=klw+L(=JgixU(1k@*X*C(o#IqUaXf1_t5+V){^A zW8^6EBk&T%xRkO5581q`toQZu2KxL})yVWS_modk!dE(1wg}&J&W|im_prQQ=n8RbT{pM%`albGUxB%IpG4@&sL@H8*0oXkvTpSoA=w-+ zZ#mU*dZSNinPL{IBRFe&Z75HSO)k2*%nb8`$}R=HWzxM8U2!nihD&|_irC@S=&1{X zx+?qZ(If4nJ<$?<}_ z=^Q^lxv8A&GJoxziqwo%8uVDIHl06bB*l2lfE~`;@AZ82ij@Zdu z4TI~tZFdZN=tE)_tbRkwIS{Lb%&0N-r(Tdp=Zk%4H>E@r)uwGoUtm4j-Gj_i#Ke#Sfe!fH zA|Lqc$`Uky3Txy|P9Vl7*%v^b z(vgO0` zN+%vx$wrQB5fVRXDDfGU;LI!W)X@&Rbx6Cw1XJteAkdG$7Wbz0mDJ|7) zccE4lUM19~AoC65dT(R-*Hi@U8O;VdjPp_D4GyG`6}W{G&KZ(3UHZ%`8oGTj%pm3> zg5VE4jh3>xZ`}chKL<-zYAvXcXysXArG&`R710JC(7>RAh&7Iu3Xn6w#%V zdzi|NmQ8T=i%c*3K43SJr6hf%gzlE@F}$+uJ47;qGTy*nF+TW>3A_CC)iN)fm7Ak9 zC773ZJ9;DgD38rojLIMIJ_Wf(;-`42{L`VposW;P-mNDYl^;21G9MimRUjo--p_P7 zcLlw%yN_bHPU-GAp>U^%#QG@pH*JNL?hKuTYWAnc`WgV4n_o>pHtj<99v^TG zsR(`+%Xy_-)4}u|uw@tyE1cM|(p{H1Cp!njIK7)Y*qZ7tJ7DHM6a54n)ToJNR&m z(4+hMum`J{s|p(WU?!?ARNfa#T89?2*2MU4)LI$n`(g&xPwq*y2( zSSKGh+5t&KQwI7p`^-p$kEt8^{59z=dup!zD=d_j9rBNL}=exBEQBkt3 z&ol|ZuTCOM8wkx5Rb1zk)?}|{thR=A{8f_NomWf8x=ka<_P*JVP1r}VTNg8r@k~*5 z-GMTf2cTsPbOZNmt_R0-r>}u*CBI5$j_tr`czTcsbGh+UArfu1BIp*}9FY zqjFbbXa9Xw%?VIQ{CUNJRhptXGyRnT`DdbBGTjeWAd&fNoBBU|+*Xel?{pQLr3cfw zvtgbGhmLmY;?>8Aq>Asgi|l>=`c_BM`~5qBJ|lip;53^j3i8Q^jU-OMoP+Rb0o_w^ zLXIV(t-vVeld{$Ki5<%AGCI9qFlf-NYD)7-An@05!TXU)G6+g$JWq4ys+7!d#(kGn ztn=lG)M&?^=!kH1tGaKn*Oix}HCCS}x!dbUt>7BnkO3aah{CtNFT|q3{%ePyx;n*Y zg(j0@rZa$3ht@SEU0RIl=?H4*OI-Tw4Hq$3aqh#4Z{lL{xkRq5fD8?MP+;WPok(3p za8W>K$gOeANBi(M{y?CFN=+GEsYueqU`dQ`b~+WuP1B^JuwwaU3+rG2KG;B?=mvO* zT{rmML}WP+#0pk5>q+W+uLl%>5qc>gc6ye0)-7ay@8QT@5)YPox1 z#2#AjL`^cHz4C|qGBtQ{xNv*lBMUY6{y3FM+P*fJ@Z-jMB!t*$EV4s7`6cvWy`dLL zb~f)M`&=rWPpx`j zu~#D?-SS_GdWIT?*FO-;XtR?jR*CauvpSz3S&b7XK*Y=ht#W4*ZQ1CgA{NSqi>KDm z8Ql|R4}=7&or-Dy?Ogq7UF%{*DGgHS#{+yLw^e!i<2eMT}!?e_8SGT3}?F!CBVxUzCh`gVakX@Q8ydw@!S^*t5&|C z7f(k)Rcl=oUE-csZMYS-zov8=1F(7~;!Q3Da_zVVwz1_>IMMNzIV$?U09i7c^~(dC zmfNzr+HRp2O)zBRhoD$D_GkpYzZ&8C`E7szIU3Dc-*uwh892KCf{T~0w){6zjq|^eYOEa0|6$Yqk!l>Q zEdN?PNwCxP>mnmMyG|yDtA&)|M11ts2GG1!?-38Y-xx!Kt|j z`Xxn>f#dsSXGbPyXCp_)$YCE?!v9Q0iIqaTxcK+w1^g08a0dF<$g};)yF``;1p}q% zSO?~41HkDD!0`&Wx&n~<_uemp;YPzrz@8-BPsY9N5ufLaU)AXgX9`ji+!HafbvpzCWq zJUklyaCB7+=2nVgW`5v9%V2qsE`Z#ffwX|V&|qaixP88ABN1ZYb1nXDUw>8uG}}D@ zvitqW19?F}LOOUv+XQL*XZ%Ws0kxne09eHtp5z-IazV`c^t%D=>m0wbZ)(qW!wKg2 z1N;dPruq>fo&yA`0o4#Z83bh2(wCPPlQ98;w0_8du5}IM?*&{5hVU%zMc#~01^lXl zzyRJ<_Vkb2{jvySYUrxy5I%QF8@}ZpmrOCsiczNe0b%}`a6Y^F|AaAPJT1Ai~>P z@UOaun8R{;@=@fAy0(ZS@S9oz{^Mk(+LwaB9{T%C)drM%A^>D*^XrODNY{WMUsudE zglh6ws`1lw`Gv>i34u}t=j8v@qY6NSb9ME5=$Szix4k&M|4=l>ud`R$|9(qqnn#d! zd<%Jav=0i9o$aq@aV0NwaI_ET=EM_SK)Ut_4-34ek^uCi1_#-c=<7e=%+8qC_tn7b^D}I&l zrMcfd{u&B~HDnke?X19mgLBqaLL0UfBoe$DE+Zl(=Ppl57@A$^*_+!wMug-{YGxqS zocfX^KIi?KI|+tuDEb9ncYM}0!fVl zJ(rJrM}^oH;JaT{%JFog9iY zm>oKiQ<_AUBl7Tm4CXf?!~2s;cMr;Vs{)-J+Nz>dOEYc86-hP%h)@I1v#g4@q|cqO8FAMZ>(<2ND?UH#oj?A?hO{Z4g+Tfxei62$)=f|-Csu* z<)~|WG=isY`G2a*2w5r-u%fW=jWwRsM`tM z86;C9`fDkpV&aLNcDoA4*LvnW1d_{awK}7uJ&!yPSq&9JeAR4&SFEz`T$?wo@G<;abmy@pQ}>cL!sWS8ogwx9jI6isR*}d~ zN```ZPu=X=*NXv9z?UNGcMq48-HjK;Ig<9EXN>3rRCy0{=hTyj|DNo~0zs}~yeyn( z9Bclr^Mwmh#kMKy5fpxGohO*bY~B=$+~3lb<4$R0;ev&Si)uEQ!b!~o6%^k*Yj|^# zMX~T$bRY#7lg-p`)RU72^Vb=s|K(eT1s|!OZt*xZwZU!*g~u@jtqN%9)@2p=i~8m~ zDAD+t%5+n90HtDt{zKBv-GRJtREMW*1o)lkQZU@Y(ZRtmetd0bl)HK_r2)0a85?-DR8WKvUC8O($lAYJr?WRdHK@W3UQG=?? z^{q693s-u?IV^6pDm*{uZ@!SN#Fj5zPYz2@y98x9yJuvZIqfRqpPrO#*3UIC^dG1H zUd+qZZ>Up&&q`SbUYLU(Apb|E}zLC5nYS0Ms}0ok~){B zIpfUL{ouqYx$A6h_QMEsfcEhj(D~-v52w5= zbZpy&P15_Zi5I#XMHN{mc`aeQ)EN{K?K#fCk@;x)b8=dsFLa(gkK zsCpvfc<)4<<)0(#FOmIDs^4W6L6W@%4HJ*;JKJx~-$S@_ZY3aHf6)@la=h=Y>rT!Q ztfXDOZo!{l6l~-sEmR;}fuJ9J)O`tO$U0uA`iA7^0an=IsKtLjMepxng3TwkpBR>h zGSOb%Kmu(Ix#M{K?>m?XUS1P5=>^-P_bqVM=@Aw2NC_tJ4z27i?NUfn)9EC1EmBb| zvVr(Ry98Ao9hMf&>gU9a2XaNPC9fYm)bD~FV;xCz47WW$oumI*$c_lue}y&GRU-~% zf*-N~=KJFbjIxws#xCUL^4U)OlNi{WaRI8Wy;q{21pVCm>Ilkz#$g983fFZmw&hw! zj`|$5cP!g2t#nMp*z4V=6#mMgQ^X-FH(SS@Gd=8iZyRCP%I4@5KZKVGv0~Xwqfj%Z zxYZq6h2PpKI^Jc0t-Vcg{6A@^0|aY>&IRIc$iNQ}e4o)_<1-VR*0H+ZlWLlF({Dxu z+4WeAC*tF-)hYSTmS&QWvz8Cr0y`|4PqZfdbE`Mhu*7s?a{}%<-`mcynmqW`;xmLf zU{SlCC|^&d+=d!O?!3Zsd`bKK+BFeVOo>d)U|yle6gv_mNvheo9T!%tMsEmGtQHmn*o?7~zKI3$*h} z;9ImR62wVhdtE#S5XoZ$9>X^Y*mm&2`sbKxQZ_(^2wABO0*Dpwu-^YmRs_qWP9%;nrpg+N|K|$^#8VIq@4NOam#X^n^F8iD$T@l_BE1{QsBsMzIiROHXXy5ons_*Ba&9ABp zzDuO@Sj!9=<9?S|;_CK;;|}M}dWBKTvdrD2JE;Ci?YabQQCw6$o0O&X*Tcv*%%txz zIV3ph!o>SVwdl!mh|l%L>qKkk5hATJt3fEY*<690D&OC3T_&Q^ zxsm$T;57mX5ti1aGG!Tnk^X3?J?n;VtlIlxne)UqHG53<6;HpYZzMlYJ6Ve}n+qGq z$vtA}PdGU0E5%9<9c&OXI(6EN@Pd6vJ=xN=B$Ltyl;;eGs>m~hKIO;Kr_A(HQ*#_$ zT3*DUsfF5*&WEGo9Dzz}Ttr&D zblr~ex*b2p1-W>rue7SeT7>+F@dR_tp7D*5O*A@VtJ)j|g}epNn-Ndt7@>%*!C(Xe z^JV>QadyNXmMrcEZvAmMqACAt%V8{&-(<#qt~BC*gF-M%a?RpB=o#?Yd&SuIm(Q|9 zTQW)qy(~=GwDN3wsG$DFfElsK05K@N)g|0tSkQvalwpIM_yt7GF7p|lI+NvaX!Wrl zKZveCbsgzw%GOG8Bplm(F2rMhncjmz`#pel$hTPMBvSsZ=`dh|$Tgk+g7i=^a_I=j z9sVnj>ga>eTzX_Oy+5J1Bb`e>IOd~KBJBQYAQhImMG&xj3>5Z>cELp2cfrOWdF)-p zStm3#9#}8jf~9^f8n5+AbN@^p-VP3G5Lp>}U zm3d$dt2RyfJF7?Sv*{KEh!+olplTqJD3(0e#B7xCYi%Evhb<}=4c}iw~4jhD=f6T9;-RZ3f=YSFtt1&6&r>;DScM8M^|mUqInsHf{}f3ZQNM7 z*BT}=DYzaHd|E@sw6imNeKo&v*1Sm~c%K_tmyT6w9hHLYBJ@AjRnh}bm>Md5gp2_y zxy_=wD26;jXQ4ZFy4Oq~cer`QesYJt7Z&d{-TramIKggAo}Vcm1(P;T!B-lA=l9JA z50B66W5<~7Fxm^^Z3-3H+lapqV-c*%IDw>)571-36)ez7ASR@>HlcJu<#IU=jS5JG z%y}e$-lvDf> zeT?iEGeqWO!L`+xifY%8{-Iko;u^oeO1K+iu9X@zdI>-Nv!c^~d~ue$YFzw5YQUf`{v7P|&t_F?t5iM@<)mh;zFn{|* zt*4D$&$j+Un^@&p3&{bH-c#-Zv@L$w{O!d)*eEKXIF2%i5L68@e9jaPW7mNhdj`EP z8W=NRca`YCpA#&6^w!G1)voQDA)!xfi5_@e-`?lfiroqYBb@+s1u5M2M{2vJMs`J3*ZbiQ#$&e`?6Tqym3u*Zkq5?c>-j6|PM@FpD zs*d@W21=aSSD6PN%WGSM}Lusd?tAHu!&2sjZ{K8uj1lCJwfjm--Ms#kx^0 z}ttQR6Q+F-E# zHF5FtMwQ%jVAm>6{-||dd*AXzZotgOp~OwuNI*=hBV35lj{oky!Z3hek+ z=LFh}%pma&)=KB6;-s*?41-%5*m*_Kw9Jz1kyco#%$90wUXez&{(5IhZp?;F@*-uG zWqYqU;VO$jpVS9bO`R~o6pe;Eag&(R8QZFiLcv7Y(^m1vDt_$ax5CXe2ZerP@mfOh ziEh@#Su`E7%M&X^=<#AW_4);xz6wJqo9KhUwiZpz(m$Bdew0OAXSAYF1c$8OqzsDE zus&d}YlI)7&XUB7siU?UU@Vq!RimgW(`@(%w6}^}H?8pMi!FPUeY_2kBrVy%S$iy~ z>4qcs5XNZiH6Tx})Xqh@*%saP<^zAE><7 z8M%Pg$*>WscAo1fyslJr;5^D9ZQ<~j)8!HfHI@K zBdQNEpE=$42d?3#&PS}M)yL6wc57-j`5B9@+pg>RZJQ=MV|e%AdJO@ZhhM3_?+pJ8 zD90Q*Nalz{U+zO!x4!48!0{I7!)=zn^sCg0y-;AnB7HZWl9{U<7M|)T+~iGD={~ld zv_%GrUevPix7>3?&cxz>Onv<3JhON8UN9=g!JIxW@!x^A*qZ9Vs5t=sQ&c%_8eA0? z9(JRsOt_d7sd}7YCoRadVx0d(gIPBsu>P46U?ksxbJ8TV;jZ~^$tO-JJpGvG_1JKn zT;b_*4}2-2^){D=+~N=hPtVP5kkn0wS`jT`+fU=NMeT@61jbctspm(V%v%$#2vr&+ zz0qs~PDz1`H2cEJ9Wkrjd#!RMPvw+R$Yo z@J)w9!x2tC2>Y)}a+BKN5$#kRAEnP);81Gq$CUUot;prqj-9u(eDVS6vHt6!u_`;` zP%H(^=s#gC-6EGrS*_QR6^}DBm4m%W1ou4MMVxd`U?5g|Mi6C0V`0EC!L~dHr9yF+ z;#h820lMQbFFwMV!5=V^Dbu~>)W@7z(Vg>rcb!!u^+yO%#dd&rHZq_4b$J_meQ>1E zuIc#Uv@`Z3?A7ujb?`NXfXEVDOB?h>O-$Ay!a!CdL3liZ!3Bo8_z2i{1U@w5}mcT4YKi!1aKjux=u?l3CWf0VbIh;S|&NLr)RbNf&m z4wjY?9P`sml~ci@m)FgG4_?;p+MZpYM^*0@gQq$I1Dvi9R~D=$C4WOOu)k;)Q7Ilj zfH}RI{1-AWoWGP3W&c*Cw={VrY@k+&9bwC#V zcxRb?1D;b{)rvF^-dLQVAF#x}=^^VW{Ae_s`P!$A}7)zBDaPRF2L@GwY8Gp9Kw%$4RC0@PzZDIKto z%4;<;!FyDXOFsR2;xCYZIdt%0%r^(>4|ez7Ixtue>jT zLR1i9Y8R8ivK$!VIf6~FIcHd>ejmOZzsDL*UgOzGZ;55XfLNCsV@A3AzZ^YoY(`-h zJn||FWn*CyI=`DD&K*wbW!Gi#wZJ~z_b2r(?VFm}=#7$Ll98d^1!;-WI(_p}{ZT_Z z({sIA&_O~T5Cpv0cIaco)fy!mYfvN?Fi-nfv#wm75w2YdDnOrMr!s%|KE6LSas@&q z1Pzco?Z7&ym<7|UcO%>W;7@O*(}y~E<07=;`IY49N@Ys6Lv=&Ek}l<3dL7J=f+(_V zssjD$S94>E(nCn%!1#&u+5jm&yXx75x5}r;OCc-Hw&P}0>5JbY2>8i_p!m{5m@O-= zocXwop6`ZgB5N47dZTG z0(rfJG*Jy9Y;O}6ohff+(DAGawEkOX4$27qB*;3eZ1SF@=s}z%L!j}+@DLoZh{t8O zUSno}#wH)n-wKKp#;4i!n~k}Dk@q{;^xS_-*>ijPrqrpkIpAE@h9eGdJxfBE_MJF7 zh>SIAXIQS4Fe#+CdQl_Fs2v?G#BY}Dw`I*pJVx48+7gVOzM6cTXSn=C4Y8F;5i>k8 z64mJpJEF3{Wo$7{BLZ0!!QkE-$TaAzmSom5ZMN!r7zZS)AmTPket@HtVVo;34 z+*G%$ zW-6JL$5fOzGmDVO2Zk-^fZoG&>}9yN`O2ZzRT>mc)-NgWxv`B3kMRJvFT%@X%qoqn z`j(6A*iX1J+XJoCbH1xAHF6HhY0SvxWhtrG=OZo}l-t&yd=zMr5ci_e(y|8$x~BRo zAX8jqhTH}sUEhTeZBT{?D53eY>5Edg)0Up$H3sC=guJQJBSiYcMAGp0TdZJ8WqS5H!q80i@!;h08`re?4=$BIAYo0NR*vFg<9fg!`2zeT(`!lDjxk`D&2 zclj;Lh5Eo2$r?)}C@72|gE_VJwGxVz$&)n+L1!2v8m8c`7UC$2Au|d?T)ylI!b^1o zy8Jczdwx=BhiN7t{^|EA-Eqz~`f+{y*s0_zz~S0toSOFGOH1gkWh_mi9c+>N#-7zZ z27PizqM}P$jq=uKzwbyDs%>_mN{aA29B3jGXEwofCPaExV?)J3)ZfIlHCgz(I0%u?5d>Poip+$lHbiuVhf%U%rBI6e!tr z&UCCuQi6i9#%f*NiLj9s!f#EVSQ8Bywo)8v8ttXZu9=>i1UNRhx@3_7>d1iwuO%hK zWTp%RVGA^>w2MkL2WLg%P)|3@s{D1DTP1pvBntIQ%!Za5;It@dzaun8D=Qtg?+YZL z?*-DpC-~2KSxFIg4TtL5j%hk4kfFu|UfEV|`mmfuY_Y>TmQ@k{nAn%+0O}Za-99s#8tV(O*+jJTxwFVz0cjf0OM zmzRyPeB!WF8vJPSrB;P;FyOliRMAGoW|h6)>%xa@2vm(O~aD1ltTJD!mrEKl1VbuL2U)Uc8gW&I5#L%JnH6gq;qyh16V@E z-G8+ zWm!gHie4|dU;WIhUk#@aQs33(HimFNbcn2h+9^6WS9vRNl6-Ruz+is;(Vf2mlQ;FU@_CuBRXFc&*MFiuO&$AuaQcwE+fb376;QLw>nW!cKR`C zmj-tV6XV!-p}Hc9fhTcibvL01j@{pY2PdkRUgOtfv;Le%}0u@ zv{oL(2@afnYcjF*3|dTgIBxc?(8d7ZYzy1g-JQ_0ADLX zw14{)7!Rd6$Sj*3uXBhy=h!fK`PH`J>kxY6G@isu;M08*MV2gb%3F*{6+ol_%P~*W_n~Y9yP`lfci58-Cnxh@$#ZNM?If zRhjcPryHx7`V2_-LxCbFgZRsXOVbsL(x9|$^W&{x_skJ=)&u+;*%uzo7k;m_DJJ{)ck-|GIlWDfdi#8gjEBq4n zbws#Lau#|s6k(LbFqd@>i74!g-~(!pZ70(nD#+l+XVCvpT*k}oKvc?&JLbmK~F|{vXZ$)#oe;doYFS5&o`T%sT9%3u1MA_FcQUne;i|~|8Q|0vHcq&^!wt|Mj zU=(#oBU4`L?09i?eA-%=`clyMXF-iTHl+H^z$H(DhfX~l;4P`Bxx-LDNNL$E-buS| z>Bi0-u{MJytJ=NvTzS5qn>X;m9NC*0P&%K65RdtuQ(hh4rtyBpw;SEG>=ST(chePW z_hLIa2Dn>+p?qWgK-zS3T>k8njWtFY+k`6y$5;S9(QS;g6YLw>)}a|%ZgsEOOxa`AOK&sFiqoY@^#-WHTl>zN;M$sj)* z_7EQRoTg)|W7;AZ5Rv|O5$zCVuC}+CGG+b?z^$9I2J^If!c0EoXyQt`G zrRQnV?MTu|21Lad=w;zn4SDF3BT`XkS&_j}ys9^>THmE~GwZChI;E2)#q8Rn zTq6}B5m0*Y-jN7cJc|>EfmMyPljWQ?S=#gwv4Sh)VL%xWzT8 zyM|-wRv_4;9m@8TE;yo8#q2KIjYHUv-b!3a@br4`qS2hfVceESdOnZ}D{dJ_sy!J* zPJDudjb>L3=3hghMLC~;EpA4?@M{|2OMjy%rNocADQSfLLV6%8h;}B=@<=!pOor0I z8Gkfi;IlsfeF4k+|H8&`GXAe@9OM7-wlNW~v#@ji4-of%vvC|OoUH%PY+M_t3d$uK zn@m}d1Ox@cu*A?j?BWh7DGWnD0y6{54kfK_5Q{`vO0z_iOBorkr~APA@F@floLcG&_IB0f`oB@m;(sK z0GxGPD_Dgypz?l01a+W)G}{}{fGsV;g?1lvi2X(*Q2U68h==bta0zZf1pm|wFa&U8 znu9qC?3#hNfm{yM6d)F_^a(YFZxSTT747Wc;o<4(lc~{h45=q30q+BdZUDFt)FB3O zjbPtZ=>&kUK|XXb&;b$tnS;Cj0ACH-Cg2%>fCK>H6sRF&P)`oPn!ySJD7XW=q^vuS;oAWJb`lkRwaC^V<;z^ z8mcxukds5eSWMkl_j6JJ8HQSMrN7-Xb`2QdHQ@7~WmCv#nW;mn-pT2BF;qZjk7(T1 zN27??$Dc+E0)Yq+ARshE1Q-SdcxY}s`bE{5o5Fn5o_K;5JGnbMf^i31|0fmjE@(?o zjt_*dUe65@Akr@Q?enYsU>_L}4sHP3A_PQ3*s6drz`vl#Fnk&xlf?sc3CRFh5HSV} z@bmfY%OvbLg$3vQ{5kgh=Fowvg8JgxvhI)m-6kalb_;oba108_;R!16pV1GIF96|k z|Lu-K%ivsJGvN0@HEg3FkjOtt^gkvJvg?o4H?0pX81?>61Iq!$m=GY%AHog_2|%-; z*W)+e@^|axFMg-5@LM0^x9@|Zos;W#weef&&%fD#yu4^l-wQ>5CxPO&YDf_q;7eaw zcs$=#HC#h@C+AnaDh8y;O#sX6>fIf=pcYC&KB5H;#nSXGoXX$fM<4nWB2=(>zjj_9 z9x5Oi9OM%p*Q%--M$k1^$ff|kQl;m2Ki+8r;G&U8~gy+VM{=fTVq#yQ=9@CY*jd~dO#q2xwz6b#&`!CHCU|WJ4tpp6~m z0sLKkLd^~W#OlCb8EGZ{Z@f<*9by>SNR)vexD5%qr4HJbyDri1e4yi3(Fm#CE@O7` zf;ry8y^CZ}*05$4N>4OLsto3JTlm#OE5BF$6q4)c${zA` zl;Tqix~=4DZ)uAocHZq^|{(#zxAEa$4u9| zNJ}C0zS1U$S&e^`rQ8H6!#tB$b|N77xOl+0%YR>z$JL3;li&O~O^!4$x8I&Tt!{kG zBbNQvXw$nxD1NOaIx2E9BMI#3_&5AvjE^b1f(qWuR}a00h_6^yxjEj)N$S*b+vGuS zZJtxy=kMW~(Lp68G%5)@S%#C#tVNY_p(2D2F`WO)K+<$Y`6FB*x`aC1jObZyNwFNR z%BV5JZz$<{0dJ(~W+nC^EIvp3F-gRSRDw}-8{@&1aZGr@{ryZdtCRBWk^iF6QmO~p zatc>B_pdq4O~;x4j3>77&Y zk86M|d}?#`zugl|4bncc9GHHg$dL^>nez(P(WSs;g&&O<<~xRqSo9;+$Svw)YZI9V z4_M2C>8D08^NY}(Y5^?tn9ss zriU$UC{Fkd59<+SreD&a7F%P?tGZ>QD?-l|I25@llXn#DG?yDNn9R0#_$qSmW;C`e zPk#3rRFSev1f3Fr&jmsO+AJnw^ zUgI^qE}7O3R!Ni-a6i zoScAwOPm9Al>hB<;&`1Vd*qpVhX?1i;RI8m22PHT+?Qicx*UWxVvSG|NV!&KlF1U= zd_Mytfjc&7bhi zSnf*N(bi9j!=gp3uwn{Is%V0Q(F%G~b;-GFz@;I4B#YKHT9!k7iWOb~?*rAu!{KL8`d+ z$tSkKP)q16ept zw#s6Y0Fa}Tl2x8Jp@_qD03Yc|&OX`M&iw#HK44ER!t)Ay1vme}rU!Q(<4_d7&05>s_ab=PEs(snNvOp#^9}2rRFpiK#zFE><~LCMm50 zVZqQ-db}X#Tu#zTy?5So_f^jIFL%YG-^xGIrj( zRI4yMe3vcAgbunpdu&Z$u4|X0Qzf;4<)W(ZGzY4!W--~?h&$`dr9Bc@Css`MQOAiwhGaeDx z>7TcoRc7Z>wKnQ*&?Pof{*r_}Mus*EE4#A&r^3(J+kvUPVJExiwK_3h*DKq@SVF;w z<<7`5_qSjk7vyR1J55}sY1g7VzYxx+-n9MH=D0a1qz+YvXsoDr$>6mQzHj}gcR)1r z=*;59-}|X{x|(ca%sBRj_FO*(Vo-D{?Kir>q`Wx}5oh~3Nl}(ZC3kX{Rmz35#%=s~ z3Ww1+3Hjk*oH3pw1RIGlL;chXD?Z`%^6-p9$p$F9ikHf6gpaoVb<7?y{623JdfA!V zF)h8s)ko(FrNBWbwJ*F{GUNCY`zVtw8ls3WqIm_<7yn)j;fpFyGeI`zTV|3 z=EtMFQsT9^6Ee+Scnt%Y=E@6|3;Raq8*Ia05+Qk*$YCp0LvNi>6;)MIR=_4yt z%lT{;2o@M+8H40*eWJS zQj2nGyA<%j&nFx@(>k}eQ0t(439GLKtuV^tOat3Qyi_lIM(#7dRa`)Avk+iKPte{N-d#hq^ez*6mf-DL&}SHRa#!#))8wti(y(KALevQN3cvxtKJ zjaKF*hw}unRrUgz$x?#w3ISFfT#hb%>sp(+DmjyWHI>BeaM?=;S1YyWRE*&u9We`P zBeBYQ8(N=mA%KJdB$Xt!lkhm(JwEzM;V%~ANyanAyUH6l4nP&|u{J~>&xX6qs^F1n zdkV#{kv2oE$X%cgSqkQqoAV^{A%#sE#|^qTPX3n4wNDQm`{AY5L70BKucNowNvG8< z0KOb^8&7n!lcDMSyolcBwmIky61)P@4-O{<=Cg@}%qN?HH7s6(SjeT`=~Ea8!7P$N zhmxFx0#nh`+eIeV-jd?~GXZ!sFU(*^eILNRos78!(GRS;&S(? z%Y*D8s*j^&4IY}I^Htum%xvAV?N`ou0kXS#XhlE^+E4kahmQF5{j(3znlF+lMWoug zss2c+f8}c!RB+D|_3;$q4vnT@B( z1`$0BHkn1yb5@`lg$#VdbHU!nn4uy4-4^5P+zQ5Yti;>5Bb|^o9DmQM1A4Z_E|^t; z9PR6=k~uj3b-EraIaLE6vW5d%L{LoA`FHJhHR)Hu)qFAW8*w4oDoH!bIIt*bL&9Wg z6su#ztfv2iU`Avt$Jd{26^AMP404)ASHdXPnAG%P%D4Jll zsQgJ6d&X>Idz61I!1Rs2m1x5UFIH5VjR1g4>VwQiT-U5N&(++A1kyU(>sL;y!gbEN zgm`f+ccoC+c5kRAACCL32Vr{$6<=!?$=B!>xOmzv7>Hp|)!rDERtR z&SH2|rsd^U7s>v%W^hWicaYWlF+`}94h;*{r6&C@GouQcx}@(imz|9lhwjP5!pGkx zbM|h|{x!v-)0Md4D27b8SV}~`+n37xyyOziOmJNw4k9$NQNDAv#00`M0w6Iid&M}d zhbd}Fa$YIZn@w`Z&@OI0aL&EgTArq_?Np!^j%Erc!tfSPQj?EfWX)L|j#ne2_1`z4 z54rJE^4#H8?VW74rk@8#E*=A%a80mIBh_6xMg^m$5%V<{;y6QaVp+I8i5P?|`F51H zsglFq9o|LLc;}m;mjva^;TEy|&%&`26eVwBS9&sGO}gTvRwNm4-mt|<@^*u3foHeu zK(*@8wKc3P<}jzok#I|Jo+1AGQTD7<VMIaN9O6dr!xcBG;DZpSzK!Va?(vr zLmPcfC*;(MPfi<5lilj^gRT=KNTx=5zcQ4-BO~?eml%O7%G;)OFG!9{F?>Gz-;1S% zcxj96-$Xg?M>`p0im%w0NayAP+A^(fQ^mNa4S6d1B~g1EH0@j@!EV-ZzrV3ssFihg z_9*x$QjurRbZIueP=)2T@l_r4CA<-NYDB-=FzzwJ40^PB6qh#ejl0V>csP2-T=rLg z8`2UYn+D|UF??mQxu-GM&kQXL8Y$>>Zv1)sy5bc2J_U={py)s}J0MHAVl^~!wA|)V zk_yZ)%&-40s`YKs$OUBie3N26cr}0fyzhOnh_7&j;`_rioVnwKXstTJb))+6$>f9R zVu*lptdT{{?&R~bLAfBn?SpSn(_^!)n{cz1F0$1OEjiyK2rc>5_#F<($@N5MpmEC1 z8fmx}x90)enI8F@%Wx*dgm^C<_@Vz{59kqZ9*1q|IAm5bMN;l0?@rxE@xwzcM5qF> zvF48XUjg6Cd2(_!Y0oBI1sJCNBYqRt5ixDY$EJzv?nz0L*_)(p(bRJ*d>na8o<*n` z!a+Et(`y}oi^wuJ@LCV`T0GF2=10U4^V{;4oMUtfmHvSj-*pG8!Kf_Fp;4wwO$UlL z_Ny-I*uwHureElni?`5lkQyTQ^DJs|+JO(@um%6IgQL!%7#@dexuh)WnGLOa^R>%0 zZ-6e>lJ#pvC{Oq8j0|F{`@D3QJdQGEh>3Q!D0S?JvKV-o@q$I{sJcT&m;q?^4VMq3EV zv|o4L;|hl~>8;Hj12nj(S%Vou9r%H};{Xq6hAJKWPp3=tn{Y5=Zg~1}&m^XO+v(-{ z3r^=gyh!CDx@e?2IIJu^(e_ctt)T~~6m$Z){qxKEuRs%HawED)&&`vM=4p#W-GdMT z|7M!8QVKga7qgK(VQVbN`;4vDu2G#8x~-Dg5_A6%OuT7_7X#0eBk)4gbW!5|wLzmr z>>+aS!p!D~dT7xiFq1p(e{HpA9!wKFTzPo+8%RidSax*lk(qJ}qG%^hLq_@@yIHgy z+oLRW(;ev2f2^2eWod(r-GaSmiyRcA4>wthS?-rlR~LtI4pn-_C`o4X^!{U;7?tK+ z*4G_1F6e-7!B2F2GnjX{V9xsO_^tn0b2!h-aI#%wryG@>ZPM3fx{FGRk1Qt1qJ2r}Vw_NX$=i&T~06iO3!wXo3T9l92$5iGV$TWZt4h^8kVuH z)RcIG+PY3M!+iVk6x$+4pOaH`*pArCSg?&^+}xxqh4wH!M=DLzv7dtdS08s@5_DSuGM=RL`D2#s$v4> zL-rNAV|lxZW*@{QzZXHP@uAPHxdlr?@ZAA|CNgsDgl6)>uPnD2Ic%_#!1i_+2aC3G z==tw#;-S%2GLA~~QnMwg4m_iNVuqnVWO9ZsaHw{jHU0MQ6@>*vVL9o$ScSanT!V=6 zW3;Qe3EBM!4+iC5-}2|l0ejoxYlQaPZ^s_LRq*;fiZ9lp=?1uxFgV&Fnu!dtsejXfOzC|XIZgH+Jsl$1+_d0WOiD&v$#%@%C;Qna^vJ+EM zelZT%qK3~MW!pw`#ds3wMSz8U*b8VP;TjkAN^rER1XfYQwRd_%^qI}nFhoZ+%vNVS zEa5uXK=U~~HGh_}(d$CPW%`ThdsT~tsG(<$CtQg=MBSd42My5pM;0n>F!m}W!vUbj z-?M%u^*oN0H^&)XghVPPv}Y0h&~?M=<<_tQ)j5>*M&idY?rijVIx=}WVG50 zGziT4WOYL1CZbD_vk z{aWHqwz%#Wh|p>=eLuRvr|>%T6(`HmC>h(3K=xad z3%p~5$8D)L65r&jC(uhT3Oq(_y)SGz0$HuV?D$?6&1_mjH zlq>^nLKo!Y=c7n8gkwU8$S=j&@#j=kP7^0YLL%GXa_xj-_i(#Fp8Kj%CfHoVSO_`L zOpx$-ylSE-AN4??X{rl*Ezq7zNO-YWwSXit=pK^K<#V6Y>UMMpnY;r%98k|2iCOM$ zw7*Pi8qJe~=jP#=BGAHOK_n#;5r1YF0^Fle~iNe`y-= z1zm?YQ%mfm+OajcOyxP^U&B$+yJ*Tqu^%AgpQxuVP?NZWvDXl?Y|2sz8dj-i1r~po zMu%c#uN*Ml_nyM*GoeyJ=y#6_O!eyVB*@^H`Ndo7f`u8dr0aQZaOmPI zCEra_thVkmI&dWg#La56c=C`#eSvI$o>o)Xx8c&XP%SCfM;pdp%LE&Dq6Kry>UNtmp4QfQLmZ-=SpY{aD{QhH2e-|*F3 za5QFceYLO(F*pq;F1bNUlPBN!1yHKD&O9_MOit_ zRdlQu*8&caD#LLCzX(6k(@-NiM!eb9-KE}IyV2-kJvNzSIiL(5PbNl6`9FekoAhu| z*tw`NuU>N1W>8XF>liA3<~4uJ==V)u)jNxN3iKX$A-Ut)0mV&Ipbl*Z|1g$>493O_KmO>O6YVOx1_m|7qO+-ZF>&drlAXcc6B#nJ-= z9FY$lL~LOROq6`NzU8?hM(+WcP;G~9gJKUB^29Cx+dt99e4$_EB9gt_QjgIk#vhuJrg)dTBoK^kVck-2-gsdR6zE>K0&R^0!MLGw)N>?0npZpE=Uz!~ z!cu$wQYgM^H(YN#(K`#i7Z2@7IHMBP34$-e(WB?ao2?=MMoLNR3PkO1VG~b*F+(K|)3#+a+2LbCDo&8>psjgFH zZxh1n3$7euSTxY}>Vf)noB8x#IW%HUI+E=R*dI)dJm@%ZOjVWqJeWa#KFJ`(&P*%V+DtXYw}t z!ML*NUg6s)hDR-$ZL#2{QZ(!$pH8GD??HX_F#9q**a7jZuEbX(nL?|AJSNq}gW}kN zLZW8IU`{$L48k{?lc(|<>$tCtN(0{#7xm(`(@jfl4GyZtSDRzToA9j_ST)JHg%!pH z|2&4sHxehBxjKfY96c{Q+V@-u>GIVn8P#Yg?U!|^%5y-~Ls+}We2&f}kjvbY53cpz z4C(iYwgPVLxHvwXf(6oOO+RitG^+9S9DEs@X8CanvXh+k22auQ0fds+xjGS_qdI@4 zal=0=;2GoClf>z4_I(k}5mL>*3zeVjOao%%&r!6Fc!BVyv4tT!nN{Ou?!+SX#=Hs^ z?1aai!A5OT{&h4pZ`*d{y^7y*de2?FiYeygF$XX^e|8W+uYX*P#f=_sF6KDC4i;p- zNJXhY2CKLVT>$c)3NUac2g_iY{aU(B$42BHw_geA>rQYFfe>YBb#Leczh8z4tA zl=bqEq2xVGvIZ-ikMfp6i-^;QDJs16jIP(B2ww>3@=fA5U3q*2Nr)Btq)mlMQVj50 zP906P$=@5i{Nt#fB2DpT>IF}xUrdm^I^Dj4r~T-EaVT7e6(?VJVVWuQ=Dpbnit=~0 z2d`pCM*8%{uI>JIQeX|V*s|Fsp4K`+I`e(C&Ms@aQhcZxMDTuMK6O?T^6wHWGKtxW z?2fT(ol%B%uIqtXB7uQwkb0xA*ea?I(0|<uK8ZP%BRJ;T&gvDJ7JS&Up!D z)Nvoz@z-f6N12;<7HB4lcy_|r%K@v4VjgeIj&I z5@?t`+O|wjn7Z?vSnkL{@pWi9X7<~Nuv=Z)EdOP;$tnX*IpqUk^cAWYUGm%f3}}-x zrHDV+?o$qS{s8%%LJa>mOyfWBg23L$3W|s4e^3lY0!B7=j{m8c2sjy;|4;RQV;YPM zOw9kk!|4BE*N3JWI*t$`VVCI-qZ;PEjUm_&sI1Wm&G7nnL4`;Sfk&@ zDgb;0;^+*h0pObo?QUZU{!z#vCnM&c!n$@Yua0aA>Bi~;0*D6)v4#WU;^}N3s_Bmd z7~2k*@lRl+;)U=eZ*;WA4g_J=HS(pZ2paY8EPLA3?QKL zKUQtu*51{ha_OKopK=KD<;?EF5Gph+gBR;da0`Wix*U$dr|P!$B5Mk_|HYnMj-27h zEkwI_kVm%xW=ROj)C@duAe+JOF%gVAa0=gUJNq)WWkblIMq!qJHbuWIF!mt-UjG=Q z&+ZTSdbkG&xYg_Dmm7s=HVFh4()MfgBkt6`v}D5S;=J}l@n*MNsm8$WPd*Cm3jhv} z&kis~+Xsu_&g1^;hQg|Jr$^KFd#~cJIRGH!m*CS?{EOiFUinGmM?2!w=QrvJ>y@RB z;D4M8$bNKk$maJ2@S8jO1)uucd;Wua{L8fWJ1M?`3G^;J`JnavJD;%;KzQSKj(@t0 z`NQ!^RW}Oj|5JO8J(qh~0n`A%z4=|M3TXS$2ArTkJ+_+);hF&289=ktXYX{$FMceq z{rMUw*ryPOH3j+gDF|o}(BA$l{@SK;(h?gRx_HR*lmD-?H|=YlE2@CdcMRzGh5S}Klg7=>#}xQm&lzj; z8T&O#3<1<0FvW;&YH&gnz{VOto2rtKRD-iwXs8smY4<1B$(@d)g-h?SfRwj(%DeT% zoiLqc?r-mxO6ak+Vf@L=qm~h_ri4m!ec4<+8N?oZuRO&lqroS>D9`xY^4=L_AJ)VAKPAJ5OL8*; zHS%K7&T6_^#UL=cZr&T1es3u6op=M_* z^;FKEe6I_^d`(&7D8Z{ zdtxln5RKWmbwpByNh20+r7YzcE*sTH8Nu+GlGw9YvWEjHW$p#h|H^UZcB-)h8RrTI zcjxjd_pB`pM+x`mt2(rcP#Gq9`7E%lJ|_7zx>X45JCA?QO!d4534g! z5hM&s2;OABt5z2Gtu*QN-^u5+BSy3h^Vrb>+8%Q>VDQGz96Lo%|SYtrWDv6>Q$ z2bLyV;NmZ5H0bR{Q8&Ujq*)%OGo`mL7jKw82S{frG+!x%jXcbR zttPEI2#|V6Y<^Am2f&Gy_ae=hb~zXcyVdPEOEjK2B|p66jqTMIoXKCU#1%$}gt{dj zmL1$rbgR(%i+yAi4t366EdkMpyH}QE<|vhVRtB4tp~75g+()en_^T=oW;UD_exA4O zsySUd{BcI$^ZJc?s-j2v$3EsC08>|7BzNJY?+X(x!ICf86+Reobg6?r4Ev!AXun#J z2yZUVin$A^bfvMlD*M023v)|!7!AmMjYrOR3?2xWJ`GYo%(ZllOcN2|elfB|gG%YO zbAMX9otG*<7}440y!Zy6Ocaf^_xjh+dS%;CCkCTzlNeyYHhfamR;#lh4zdFh9xTqr z!)FeOYLY02hd##WcI#3nS}pR%#)BQ=_Swhft#MeQLTAusXLLv}P=K}U(h(U|eZa)* zr{n6BiY#x8934222LU6e@a)5`3-g2c>IBb!w&Pk5U%51Iu!^?kWUd`$!mq6`azL}^ z{R>XegMu{?Mxtb zQiftHlXK!rtjm_VNu3#6z#GbOwwR!e`rrcH(CC!GYkz~{iR|Ui-e0$st$rkc)V;IJ z(J3)qVin<^?=fY@ke1Kvly4Vq@0$`ruB*|_O%lAF0v)9v$A{DSUqA%kJw9m^Cp^#whS~4s1)Sv>O;i$LemH9QDp!l{_T2&wnbmfWpG!)U}D*Xmn^Y@K^0&{(yObALox{)n+YSq+k;;LNmT zQ3z*WsbWfUsQs0L3QS(;a#OOkjD*O1a=>#pMVb3@H8gZU2ai`b&vMEWF}!$ebe;(3 zqgx|2v}*wZE*89L!0Yt3=P>ZqiXAwR&Upg8I^A`&&5WSV@g1+dyuS~(k39PQvuBlx zAQDmHMOcZP<4#Cgcu|7k9c@8urG{Ysou%!Thk6dYJmoGCtnVX$?=p1Y+i@{IJe{ zqXSXRwCAJ@cke2&%H>es7@x6C$EtKrhSD;z!*Ov2)!uiuqWCQagSWjdt4`DJr7CyJ zx^Md$8RQlmir1%Ag!x%v2J~b-hhVN;JwtD98 z(|uJcD`yLwi^B5wCyu#;nI6&w?<^|T8l*+fcmk&5EU%=vp5W9H6Q5eg{%9jY{0HML zhYxkOozQUq-P?2!?>qTf$(e1Zp&P@@28L!OW1*WIdtlWS@|~z)DN63P!h)0GksTbw zg;{LvD&3vldO@OP?2=wNTFZa=UGs%baY1l|vVLfL+ngo-T$;no7N$HmW{rl>Ow0D( z;RxRqgo|pJZ9E|3i=I**N3uqRLYN1j>(XjV44#A1gSf*&@DFIE@Fa@}I4%ayQ4dA8 ztX($VTUPO8RBifjZ;ip$x<8Ht{p%c8%`CKHU8Saacuqm9t}H1{*(8S+Q-{k<{n~s! zF;UNeA)}M?oD+eY7z-9{a%szj)|nW=r#XFGVw@J8_P3{?PQnmS{V|2RsTlov*sq(5 z78-rR{Y-1GH|t~DN0={U2HBbRGc(g5n$B61M}fs89JEb&_50GWksN;#&n~2VgW;dA zK6@D@37I{1-l3kIR^vhokpUJ6o+K9xeA8=weI2YhS+nREz*GStUrWs%ITERR=eg2> zGGnoXGp$yEo?xLeY@XY*q>kcQM?`$j1x8bkeQ8ZkMtAv;1$^gjk7~h-wYZp8Af&$_ zAIcls!#3LQ2`92uhawQe3AmwMOGLG$JeLXZ|@b6^0W@=ov03Ct3a}5l# za>ZBbYi3Y%V#u!C3k#a|FN8laCm$uq2!x`?q({!iCgg0lnto0vyp$LFT5X1^lz)Zw zG{G|tG+x3)v`&B2ZdjkJNmYgg-i1vT?M#Cv=KY7R>zbbM0Z%u()$OLtE245L#Sy30 z)rIB_L$9j8?_2keEr<$3>nG#U0|&sba`IVO4c#On+?fD*!0f1sGI@%C$Z^cOzPdF-kdP-L?>u1C0hIwpDa>1TC~!vu(C@&fY3gi+CB#pi?Q+Jt)C^ ztD}iPD!ld?rqNiRTjhOh7YLaB3?^BY8}iZ;gQl(6Bb+Q5c5UP4?58d@V_9= z@Hs8-ZFae%;Q%_P)@<+zUAsmk<`+P*$yFFLu& zJgt;SerAG`;ZSr>-yayi+N;&-KwiF>Be*hRI*M(=(J zt)wg=mf0)40>;nbPg1~XIo=am-k}(78dtsSugD6M=8PT4mQpjstGlz3*7Ne2n~wAY z%hpD!H?ROkwt$?Tb3YChI34W=0CJf4%AWf(g+bDxe9ac!SJDri8hS4J^yKAFAtCw{ zIY(4aT*S;jJ+F+T=tuVUck?~FVG5&fL21-)tJD1mZvKW`eecD$VhhL!{Fb@_80eX9 z`?kb;IQFw|Xkh0iP&n9;8G18s$CkswIq9c|qszyKZyj9Sh#A$`KE0bk8P9+?S{1jf z2PYqtzz-l*u-B-18`H+=X(a>9AB$zWV$jDOAc~!QMI!Oz(nVL>KGT2#Y_nVC*4P%N zAcetwcD6_fD#W--O;j|7;rch=UZije96jfpgp&{s7Ttm)Wz%AIvdE*gYIq8jUqllx zmK&GFk6PVgU{`3=(W3GWg!W?b4^EUB$yHPf`Z+#eiUTW*G9w{dW335opvQStiHCDz zSMA>IU&-ZC>01s^jTJx(Ynew}R<4FMQfAkyR<{NhQOlsf*fCE?1P%FHu;YmoIyyOG z+xmE|Y0D3sSzbU>nfPT7DnwX{u4^0?Q030(?a|K7o`3sKL)NA<4R1(P$GyL*y&Q4l z$7fSFXCx`Za=M8X(#QeCwb3zU*Xqcc>?y9(0(e4H=e~9>uKlTs?z|Ek8rvkue2?3k zQdkf&RgDXMW&_tnIc2swAd083Qcm_(zx7V{FoD@w6OG+ug`S3N%cj{vtqeH2c(xCE zG+p4C8D_3Nbb3;+CmJI2HS(9!y!aLm#abFe2Ci_QT&tchTpv8Lf&?zr&;r@j>uQOZ zCP&gn&8Q$XQs5O8=IZo~xHf{9-wXTKLMR)Of2By@tdgL}k7$(|g}&Dvqp@k9V^gCn zSO*i}zXe!C&TO@*b~FL0%u4p0KW;SzBae>Y4h)erCI_l=mT7|UEiBY92~Jg%f#K&l zu8Dy*9Firde!K0I$^jRNVDM-MsoYCo&DUvhGr`t1KD4wfm^|928kDns<+v5ocJJC^=#@$w=?(!U$f8i`a3kZcDuQGspqMl5QOvKS`I zp+&2djGQe6TO|FV$d^E?PHG@t9`%roxr)U!ZLv{}7%$8vL9rt%%crSD_ESI7Ua-2A zIJlt?j8#$9z0H+$B>@O?uFt?3~jNkXn?^^%$+qmCeBAm>P;Fw&nvecFfZ zm>%u!eN6o55K#7zN9Y!$3=K-B-vp;`%B{cQ7W8|mYTIH&-0siVoE)0@vlSU+U7JLz zUs`Z-yc)BHyQ_-@zDa&FWx!=feY4o@ADS$yf5SWylcEN=rrb4a0x z?-^8Lmi;uG$+YlYhnrdPlWYhc8XXX%_Ak1#p7ebb1y*kmm#2<~OGeuuDzjz#m)z8GQ z=~^LbRV$+G?`-7q@GhtB8DuFgVula(M6CGv=iO7-;hT6hX^l99v?B1 z3Ej8(6T)${OswdTkz0CL(&Yggo`*O!rMKKi5JK;_BTA7GKJ27A25mg7@G|zKYJ~>9 zFZX|k*E-^t4Xn7kgP-+GF8FDyOwg$L#u@lD+o{PkUqvK${_Ei?m`wlZChat=N8jgM zuV*mf+sP$-PXD08f;>@toFysAmWG}Yv^X>|XCjTP?EFNpXSR3KiHBXkMyP1~=own= zsO-DE+3myq5bcV6lKTDINwjN-lFB*{~ zG`=j*w>iE@MqukzG2>81jvfCrS6Af>nngUT?o3^#p<^Q3RcjZkE}5VjoP2Y&1XbydjCVwKqztN&0{=-2j2XqJFc z?gfhu89vqCiz19wJ;3!>gD1@A@~vQ0wP2|;X&)b%ZgUwJ{^9K8<0{|a^3==Zs6Pkx z9LaNjTsh1HCt61e=XuX}ae7I?H2j^gXeNYqR`k`s>^!p()!d0GM~p!WK6iHt9O zlgRW+E7n}2GwG70@S!fzgu9wULSWbS`>stnWydTz*o`jTe%Up`YyjVS)Mzt=Mb%mXIhDu~*en?Iz6so2=RF1`6qXf4(V&JU2OL7Ru!9@dQEy zSZrOjr^EE5$f^5z)@;$o2dj#?qHDLNn4o60H&OD&dQyJzvdvay$v6WeP!P%up>tqY z1+lUVz1MZ;__-d9p*h}*!c{a&7Vd{5i9J!(#f*&Omb7m7xYO+}h2n1=w&H`?E;(Ll zDw252W6Qh@%-r?)Jc5+@`v7_(_Ca_(8Z_zoYKkByOR`qa*H*W0*VDAj7vyPkmyi|e zpwjCp@nx`{%Q2O5Gd>Ho3s7)GWBOvcG4Z*4(GtsOjH%@%5Ky7aA0Q4fbi?mqi z{cJ-of%~6K8$Ls%vj1Cq;=*b@19K*xZ}SBccGl| zC-EFN;PC!8buE&Qoq9NLVQeOhKCxfn+LYK9K2oV|>eeA01ZHiRtLqDQy_|@m= zJj*UjKNye-I(qLVtfE;r#u%+&AlTu?{Jq=b0M&_#LGOzIywNWmYnK`SjJ&b(;V)6} zuF@iv`90^Z^T2!t;-N}-VnfFJpf{P14?7mQqp>&4-N)aTcBNr#mg{1`y2%r{Vf$p$ z-4tiB>JYVgL;n(mQ8}-WGpY#I2yzt6Fal7bml(uaTXS8I9*bA%Ei~;INscaCUc1z! zw1=9elkd*~HJM{1s#Ed(jWEPq1P4AinGp>?)ZMp-Zx7@59kOy zrreL9ZE}O2KO~wVcphZFc4eU%~)H=1dzqiV$52*N{#9}~M8)CpSQAGG|C9s@HC z$`Okq-AWJBtQca+o|)s&i)nMs_suUKYqKrNdu^TcpqLiPDr|a}~>G4Iuuevg2n%NxiZXM?Z0Cz8{ULNMFE-^-GwNVdh5by~m+i zN71@AwEO8IgY)fXY{WEAb9}v0@=KwOOMR*Llz@9eWzso52+|E=tvvS|vpV5w&guYB zmzp~KY;3s-ESqY8k8$Y9K)40>llAfdCddM!pBiajcbwjMpWfoG9LcgSuv;4;r`CXr zn06_>r%C!WObLqFubjT=TtRiXRA$z~aO{uXgZgAsQuV@=4AgGdrn0yCPBg^Kd%D{S zK1KQ#eRTrdeB-TKfzC+AQGb*hXv?<#f4wU1kgBUM3fb*#;UOq#J*twb-0mG6E<;`& zV$RKtihut28y&r8K4j%x`)@#LW6{5fkEA$*_@V ztCp~dF#Sph4CExptfM{oIFwBeQ;6_n_y@F30kY>lqbMh8uuy2PDYQ-&-8`^O3-q_D zt7Vd0iZmd*r7B&*`R-MUQG&f;uu52uO`{dEIv|EwW@80sJuT3uTdJtEv=i|V-GgkC!|jfYZL{guc{0hb!$bbxD|69W}_l^-m~Y)zvI<9 zDbPdD{A{w_H1a!$N0PhGO>iJEJ|Q-V_QjN}kP)pF#qxZF zDK{G1{}d@D28tE-OG_?4g*L$*ZP~_=;ABYclkbtcqb?x55z{`){Uk5Rm0bVx921em zmwa^JkuI1GyC{sgb6hS0DxI8QOB>+!np|p7 zag$q>&hl~utXs`|(i}xu$A}Lo$Xe$f*$-Iyl#@k94m`l~&HSYr;Kvp{_HG72o)7|W zAPF|8Y)GYYp@~Gv9fZ;g`)981+{z6-{h(+4;8PO)P3x=(bmwj<(8>1`pk1TaEEIo% zRUTve_*(r3gLx`@#?ps{F0i#VdT>-gO0~4nlwSl16{?PgT@Fxm_uIi zx^8lpUUD9VEO|~=G8Qv#{^~=fULGMp;6N|@W&KpyS7#YD>>qpXTu;q7I$3xL?nL5= zzat>crRJgPp{eCfOpiEZJX|t(cX;`m>p6DfRalrVpf`_oJsUY{`=TQ*J0u?rd5Ju! zilRdn^1f(&C>0?MZ93{0(s*KjQ0mz#A-ZwboFESajxsHE+tq*ju+%uQ?xgVlh&O8Y;WkBC~}*9M$8p z0mqv7_%5h_)h^-J5t7R2IV~9lSuPW;QutS_g4Q zt%BktwG#J-9*Q|A6)rG}lc3qMl>FD>WDeq(p-aCkEp3{Jr~-vKWxRj#F2)PdnOuD6 zTw8TnsNC+pkM+%6_zMUUC0J&_|3-RcwYhvqt&74Zp)jeWbeTL!%eoh8E6MUsZBKHeh z{U_BTOO|uRq%?zFOojkoj=gphIs-~XzTD!HWWoSm6R zls(RW#T=GBP#^Kc$L(RE*WSlDF@m_|w_k<96{tbCgJp4kci80}%F4|;J@Wz!9H2jd zw5RJ(+fbML^KrP)VWg{@_NroXe@}ccDYq$`8b2Fv=<=G=BwR#qv9tGjHr~lw<*iR* z=k{+VldI4|&M|tTM)hD~7i$8syJo}JW0oe=jDSDD2nTRvaG^o6w(Oa{d)}Jtk zz%rVG+3`w8w@I$vt`(`Y zOO-<^GmA0>;ex=xw^c~!VNU({s^UEMKp9h_J6~AUbtdBiqqb;xixss%+JVp5+s`$9TlX&1uaeU<=@Z!lERTaH z6kLZDK#}p&v5)REA$Y1YWLk9q$bIe}*nmunl>_HcVo^1^hsH(G;pemxHQnG7Aue=@ z=7;IU*M^&c8?E48q|8TQ>YXAjyPWwYP{?Tm?MeerH8U#n^n>}MXp91aBuF%2$DA%H`^>>p*}{S{*RcsCyLyXRQ;wB zAE4zUB-Wd2m?v1#eWtbFt@z9*ZJ*EDA%~B9{^CXI11=F!G0iWv6zC7eqnsCK|8V{q z>0iYX=xQ+zElvB_C=*Kv^`9;!tAoDh7317d)H>Z4Ujjtr-NPg_^n7cbdHP+Fd)Z&^ z^FrJ_x6+^O#zF_DgA^gzgUj-z9sDpDu!?qW-ScY-!vUGFknL8Na@qlhI;cUO)IOAF zh?I&9M6Cy^XE{n*q#CqiHyw$B@xh;(PI>54=O=M~L_(JnVtoQpj$0I^rBwN4OAY!z z=QVomskXfBx{joYK5mnW#``#nY?bonEUccVIWRb5xmo6svMl=IPQU#^cFIEg{niER zd#y6EZU7q}1^IU)BP2RQI_fK6ChEWEh-Q0`?QQo(idXF==8^Mfyg@*At*D^^r(J%# zIeOPAH-m~^nnOM9jwx!qK!&hFf;p8ChQT~NXNhaziC9jJ(Z~3iff_YUIQHeyP}r69 zQt}bLAoGsqdFvLsbkgYYTw`q*$FkaK0X=khx>`g$rpe=N>owIn(pCGM~C0p_rC;O9i_M`XCLbd(vK=?ieY97~e#fi>W7;r{;#Wd&y9Kq$U%W zIoA|7D|btD2#^TJi_1LPZ9LxZvz=HA(C3L3{|($F@Nb9PHO9KA$*BXf(GE}=Fk~I{ z3$BHP%DDZyoT^-mzb!|SO$&;cGx?>m3na7$f*HDsaV(d))_j zcIl&&@)?P}e{$`|uXXxta7hx}-CUIbYB3J9a8 zT-nP7RJT^q3(Z#ji!m70DeRfW8gfYOJ+@p-HBgzOPU5?tAAm_Vt}Z8}U!8>e#^CuC z>o5K}3DIOWIonbUA-U=z)ou~Er{5=iwH|70l1Rxbe#Iu^aA$nH@xhovvNtl*@9IZR zt?6gaU%oDY&|vi3i3-Z|I*doshJeFape|X88H?X0&X+r=J5EnT2ZoQ5%IUY5tv!Id za#gSDySmKuY?0xTZ2T5)anreqAX5CuH?THfhv-(#t$AcOKKR}IF!25_-jMbG;tg3? z{v(;l&cXD*xBuh~IXD>q|H(wxe_E)m6}AOJS{-37XE!%Dc3>EWAs8577}{c%g#{u? z9i%{(KxZk5aEVeNpuoHQTd&>E?ayDU@867O(;1JP?$`CtE3;hIswmIUt%n!}uR180 zh`p23{X_r?OYCsqw>J=vf5%=!Bborh?M{z^t`ZXC1~x#D^as5b0z3%eH4O>E!L9^0 z2#Cdd3-Butz!wqHR}qqr&mRCk_pKMkz#h^cX$<`UV(tXcyf07RPFqzpt&|_<;3}|< z|5#5NU@ic+kDiWh;&~L8;1)1c7)LlY3r z;Ku=slcSG^M^M2JVhM8(!~q=GS*6JxK>`FF0L10X2Ey?*bo(>NTM)r5?z_7`cSsNb z)x!titf!~9^3l~_m&dG0lLP1H}0!<|MM#dnAac&p!5@|uOET@?i=1Vk9`asMxf89uRq{7^KBNFj-S5| z@xUKoEhw8%VardvH>_XI@A{S-K8ye`#rt*O5d7}@=c}=yXElWw=Hlkp?va1`xOq;2 zZE5cCOX-e3DG&$-657DQ;t}xe9YhqM;5BmZH>vcZ> zccB;Q<-7BbLD{cj=pZ;#YX@H#;^W zw(}Do?Je_%Up)?dX#3ahN4J(Q-0RwE@P-`VW4EMauXjWR`wHUz{>@Gm7qBB2(4(yJ zlRp*WUNwNAKgJUwIA~Ju&pR~x53l|W0);yK3GDlK9zfgs``b@sXD$_Z>!oF*B zmcISg?l%e=@Eup*)@^KW*sl->V3%B+7ve84#1=3E{u{r49Ebnw59MboAiqEQJ`ngX zeef;bebD#%uXqO>pZ(i+-B0|Y5AE;9uLowIKFJ!O+dc7=Ak#uKVZ&jAT+T?Wmy@<< zsLSFLD7V`l(O34Y{J*)&%f{9n>l^(06MVPGB=$s~Q#)y>Ucje~torOu$wjLk`1TqZ zwv0{7A)QP@Z!X17svS<=VE!>%!Y0(mF{&}rN$AQ;o^;T2acV3^zz+3-bg!?9@u9$Q z>3k_Z`*W+MD9gPqRY^N?)M53&gsBGf_2UUeIs@XC^BN8bxx~QwBR(?;D6$(2)_7K1 zKR9F{X#iR-C{pbSkZMH~NLOdMdKnGH`P_`8Sm_!Nsw)!<#R>4FbjmJ0!Df*Z2Gm_U zQ)>HPcUKTcOF}S*xs)Ey-T7g;pIZ7w!1!2;okU;RYQOD=F|?T?Y1K_zZ1IRPbZ6kj zYiBOXD(5eTa|g%iA|0e$+b-a#zf2`7ho_@&(bZ{^&ip7eG!!d$+<4S{GQRmWk~bZ` z*CHmK!uQhIAO54$Y7WLrORl1AeEC!FiRHr{CFk(lnQi5FF(pBH375yEwpSjsE>isPVEjBN%2_e8k*qWB;!=_2 zN9>L+4Ve?4UGzRwY{eB4DAVNA3VSzGtv)6^S9=B$PbvHdqv0jQi+3f+{}xb0l4xdi zANTaf=g->XM>Ex+dbe7aW*qfmD6qA}G|Ph7yIL0cAI(~|vJ2FEoLxbb%FE1B`l8!+ zt%A4ahX`l0;X`sPGjLT7$w6OeLRDFHi%d%o#cluIG;Fci_b#jmJ+(^DSTBR`pki#WR;I;9zkUT<)x zDEXW?+egC0P960)37CGg+s0qyI&wODq%(EgYuY1zCD7dL3m3Xoy#fDAQN*t1Ooc#Y z)drrX<}~T)CGh&{?J8L6n?E)LdyCl}$)cU5PrTdWqSY~z)CM%1g99=PYQ0{LjU|h# zk->w0{sYFx;Og0MB@@&It1@|H165{lL-q3!G!8CF-w( zJNg>3f@!RiIzl;nR$bWKAG^kl%6NVg~pB(=Bt}|QT>JV z$^#zz7~n+XVK9S#UJ^Ka0)16TH+*G^L3>Zzpmy@8;k65ljt9d>;$6ZIfV^Z=EVxEi z#h@TvCw_tQwcAUk)v5Byc%Dw`t9ImPt|FneEhuNIXo9}*1vzt<%%o49FmCh7P0X-q zt-D9N$~u4uTINE=laFcS2EJ4}pR<4Ty%SUqjGZdtrS8P%rOr*85i0fj5pvnudf?G1 zXOhoA3L&xf*6V|SvByc}F=c4DrF_QOb=}IU$_>-}!xKK?J1<$Y3}BFZ+_jmxHlaMi z?KX&ab!3Uj1N3A>PQdl&=R~zs(!JIx{xeg$Lf){&2BYG*rUqF;6t%G8he)Xe&R1`P zr)5eR8LC|$w4PSzgSW_+IIc-03xhy|`mFr@-MX7LUT^I)y@kY|J)O!g(o4;_Zk_}a?>D)ie zZ{fNh3f{8S94cddt^1w7h_Y5ytPZrqd0M@g0aRqSTwVmc$qRFa}*d5{x(A1IWlVXU)$cNn=fV0}vkx2^c7|oROku z*sMTj1cuh3^i)#X;$6F+71%YPp}XRZi=X62{Z$mc*8dbocRDKOQrkd1WiHICa9e%M z*wlki9ITmJm6CrxUYXChHLjKLetxT38c^lVJ0c7b_dW$BgcXWyEm7-G(dx{$SCpa% z@f94RuAI`=Prhv^Cl7uy#R4*=eIrMoj$s>-2T=5u$KrcihJ86F8B>LN$cvfUcr8efZq$hiP`DR?cX*4=O7i(%dr`M2%OnZ%w z&Ieyux_s8Zb0v^s?YEp0B>{i9aI4lH@C6h#_ zHfhEEO*XY$>@NN}JPteUly6JL2-z*>?~o^{Q}Y-oVJROYo#t9$ZZm+47vhlHnr!3@HkCOD-qXwN>!-x_JV zAqz#)ozlr*$~txwo(M7oQX?70sI^R5++Ll=Al{^5q~40ZlunRas*?7|Y6K(82es{M zwJ%|S&y*^O8gC6JmsOyZ>8}dy&a6_yfkG>>X$P_7F&igfpU&9&GkrgFWdtfzxb zt}^-hyq*krgxFKvK?(FGZwC(SzR*@>?NhT3iLSV7f@^z1+DGZ1pQu3AtKJrpM-E>$ ze$N^+_O%52WZWl2g%^|s`9A%UgBes%;XZsc2yIhv0gvS2_of^t8SpUakCWWen0nKt z(H&PivplLUj(>@`Ud}1Y7qXzy(Vgg?gQ8ZRE8ri& zO&4-|lqQC`i$<82M4}Iip~gMOy`znI)=;KBs>~Vg{{^bb$-7bSP--my)W-0AjfmRQ z6jY_e@o%#k#y8v{y{>Do${el7`9`&N+i}wcl6h9t7UqhM{7QJ{eoD`|S||TOA8g1F zI=`luraH~oOC4FxTB?Sr|)w6E`DKYgGCeR9nxE|+wk?AZfX-M~`0c3zX zOT8KKgEr?NO*Jr{71BIGtFD1)v~k{D&|sWI^q_fw;6aXEiTfIp<4L7(Dz9I|Mx}<^eY{x^wA63& z7F4yMvVNKBc)1XNA)7Hp_jt)3$g8072*OZ8Rx;-_)YN`oh)eJZH}(|Rr~U&3rnwvG zxY1t|tzwDWNuIFW!enh=cwe`5ZfcSox7!l{BuFUwakSv91hqcp}hCkAs5RA3wk2kwc zy9#<-fX5nGliDI8{}wfwqBthMG{W6SUUt$fO10pPhhXE1!~!6u?8S11c*N}^@Vz!M za6Fr*3kd9a>Arapo}D$JDzQR>HT6GAceE z1d_*J8uN^hbM9_Dyy14tc`~Zhir@DG(^Q4pWrv1clSqj}%InTM5&+}GI3Xi*$r+py z!N)2bc!B2ja1DmzrB)QeTmF3`AcGu^?PAnUWW!381apTa6R){yqT*S*%l9dpy!-B? zfyP(sT-4Nr=4%N%>UQEcHg>DTvMkbTI%J-my#VoCaGNm-`v+1BwMyc>ogcdc& zR&7=rQp;JF?d18jr*|+JCUv@Bo^;N;D*4Y33N@wy^_*Sm1f^)b6YgkU=uS2||rDQRm zL`dyCP6Guhk0Q!&wmw;Gfe&@Yi+2MSwFX||YbzjDawppN@;E(R#7%t4H#q)#4ij=H zfmvLAZ3osF>Vf7v_$hfUKaguN&!q>*TEl2-xj~j0p3mijUP`v+K5w9VxO0gJyXUu{ zasC4ViuI_wZBJdsoHh-AZn3cZIQ5=N@=`-Z0{B{mK+xAKwh<1YfLU4c*6}7_lM_yo z^`iaj9rgZnmkG!tO{wMza=89fo%0hxwcFFN-?(vB2s8;hfLWgiv^$agtnWrXq zIY%5VLcYdGf#ILb32htChBXZeP_Ct_J=qd29jJ~jv_7&Qp7cU?9&)6S#!Q3f#XIwF z@aGdE&xH1l*#Q3Hbhl<2O1y6hKRz9|)pO$nk$NhzXrt?v)u0DvTr}8IsHj{8+S}Ry zDBY96l^W%9yDZyj)Reu?zx849r@MsNNyMcCusNakY0111(XjO0B=&>zL&Nd<;4)T0 z>3smho=s+UCf_c*SiVQ=2Vd4h)^3IU^C&Zlx`ojAnW=q;r?zJbpoom+Y3pwKkX;ya zD*H)5)^q2i9(-6VhV0^ifdjHPEDq<2QWu-Fe@dXlk!y|%3e~t=NFT6z1}<%oT1lFu zhr6lqcEnI+JjO*GDT=>X{0yW~xQIgvZ0QT%V68op*2vg3OsBEr)VQ94Lp79GVhHVA zZ%=390<0WsGX1?{rpT~uf@KFM;F1OVlA4emrfk7JiyJGyq%Mq(n7u%G#mhIMkuuLk zYB0qHdW3e{Wn)2kU`LKT;mR{SbqB$g@^zIht`+a~nYkwA!2&P&k3l(Hh;Uxhd)^Al z!uKe0OV#ln5zu00)z8j?spscxo@|-h6cUEfK^fz+%xxzjpd{I=%cp}6m)$P~#Ew!VWUafBEirE$>z=Gxo2s7O7kU6`*l$-m((9KCpFPRx zh1!p7nif6IDNHyj`bNjLUg0;mrp9`VWaYilqFjGih=uu*4J~uWDbe_nA5{<4&@~;fm%7X2Y z!dj1Jg-SA1bK961I5qzig7LQnrFe{{4;fkvrLH!UFL_|7@aqLK&6RpvmSmX^UR#Fl zfvzJQ1d@FQ6%*k3I7%urV|wfO+OP=LSd*wH{GBSJBu}ELK4}7JeTY+yHC`ukl_ppw z`oM!XLRi`{V0eu=gopn6OK$TselgR9%ccI=+ZeVVLwu^P2aW)02AL6iV%p$uyiwHN zVYDDN7aCX{?u0eirQzf<=w30T?@A*!mI>#4zpJlbfO!mVNs^QgT)+%mB?cVIwbn!O z*6OkioRcw+mSQ69so`C!#rJmsb1b*qkgKGfSCDZFSKm9Ba6OL=*5m?NN_sHh{)8JdkX8 zsF$}Dq&&Qk(S1q9Bw*C7_&)usjqGPrE!6Oqn>?s|7Hb3wuMyMjIL!>_kyNAg^I}zG ztG^+Hv79*g{Lo9)tDmY``^#g$I3pB9TXRP_B4@ahZSuVOq0lk<;gZsYfZobxbuV7T z{M`}WtEo~Se5lw6C~)&=7^#Z$WtG43&4iA5IX7jFNc~F7Zu=ia4F_ao&f)==j!mu&t;vACW|Geb+j8GU+*1F_{yjVg6yC8@`_~( zqTlJud+nkJWJRes;*oWuMz=+w!mHc{2_NP&FRtV{aoZ%VKUDJ3;Zb`}U6gG%O{XWo z#-j>BVR?FahoHFnu8lBq))~qheI$%(wV6x|^T_Gz?E`S=&*6`pd>H@O0Ay0GMfT2X z<iq|v+N^PM~-n; z_Q69Z>{Ge=GMIwdA<2^wuc9z@7m{$nrK0axr4QwtwFA8>X38p|bKHzo(B#xO9a2_r zzJE$Cn|g*n25tM8P@&^KqaHP}Y>Nx{sqQ|1|9A%=ALgcx0u|vW07e>n z)UhWc3bPq!vL_MddQ1J$MoVU$iom!v@hExNdls=G(s<@)+K6SsLZ@&^z0mfuR$ZAz zqj-{ct3I|aWrOo*B9|r+c_AF?(SKl&`__=#ZO!^%&8;l+ndpdjW_|`Jb!huj-da~+ zHyu(o@}aGYHA@WH@(M9peeR&~g>VwUU31+Ugj*W$^UMb`yk13;iXUsD0!n-!H-O|` zCf+1+^q15;^W93SEIm6&mfLe|Y+*vRYN$o@z$Q7Z^)(lZ@Y&6&AdU>PBCso4l~nl4Urjh{~$6nMA=|*R*j5n{m^I$ySZZF4@OX@}SX_s<3<} zp{tMs+csN;>Ud$7aI1{&$2~}JWh>?=`{xhy1dH~=^$aoy=f#K_q!pL5`5jRvqn#~)bEUsvm=0&A<>oJOPYgfUHmfXwd zW3MJ>W!HMW=^-W98GCNl3$sWmcBy!=#FQfzsO3RSJzlLrT`lwF6*AyWEf?hno8G7&Yq_)cm<@oz!pLXEGI*((f zU174zy{A9E=i3Nj+JjwkpFUoL;$c`OsX=HN!AWyMP}W(ap;ZaXYE=XH!xgQC*GYDP zgyc8{S@Z>(+qvOGef(y9Yq484c5Q4QtbkvnQZU`n?R|1n9&FQ{&YJteDRI@T(uIbo zF!S1DRIJ=#ZjIH$LxzGjgL=Gq6AT@imv^0nhyNgg+#I9@gJgyG$`~BVOc1>Ly}-5S zhanw8)4`v~RYr3z@JLYEYE3fIi}}osXST~J5|A3Zx~+%eSq-W8hndhgJ!m79g4K6_G@6ifa>EVW#tAL(=#;?ydo;TNO}eO+;Yav>G7&H zR{mI6Q{OP%_T3OdhAG^bd$uOYR;$)Y8obH-yx~9RyS%^z2tSL z(5C!ZK|ByznVw?MA(&~v+Ny#wv6c`@*2rXV^+Jjg(H5CLzA}(KYM~t5-D2_fkgp{n z)fA!Izi407!7`M=qzQ}db$WyV;j0?`KzSS$q6y)3hk!4a2gvZ&uOCWvzvgX5krPFh z%HV+hy-6mmOj)m}H$j1zTl)D6?5%d4+`tV_e?HFzVboD-*_DlwtG%a5(7|!OUtQ@| zKdFS$2s5HxJhGX%wlC-23kZh$op%m~m)gQd$DFlNd2dC`u-X3H`fV2JKp$KPt{ zA%U+(^jRCIGO{&3JB)a^vm|^GR}oh+HVMfH1_K6m)ciK#HYvnHo_|tP zld}Y6AOyre=H*`2?)KF8=Ja#MW4F<%MW=VS_fWHr=^XQcYOUXA1SZM z#+-}-009Bv1Q`Kgz{rF(kRX4r*MVCVnPC7IC{*GnH5ds9M!0~%gaC=O3^o*yg*y*G zz`#GRtSB$7$RB`ToS*-|PJlxYDG%l;cnz@W9RSN7V+}V}1@h)1$e)9QNWu5V7kUrC z0SJVYWXRpO5*S6h58~ekYz`bBqmP~>hJXOY5FA9HUo_h*Z7&=hu z#>+7vkdg?#2P*If2&V5wKbU+C?vC2TA8roxi=360Th%|Fc<7sc0Kqo)35ci<00kh# zzmLH!DFS>7E(##83m9g(8K9#^e@$;d(+~0v;0FbqV2u0?-^s7Z4>PdOml{}rpe>Rb z;RHB<6X1$ao`GLYB@+HT`Unufz_k}7K;Df*68{V`m_ML}B49Tk7_b8B1Au^Pkng=c z2mwK@h%1*1KM4Zj=%K=>U1_}e%8{Vj4%9zh=*kRXtCKO6$a4&RCb z!`e?RbHy)27<-=}0IP2xK!9HCZ&#zROd2i@*z>#Cms{jJ>eMm}N>bZz(HFj=0^$wq z-63iMz@20m6aWY)s0g5;A(6ko-{w59;Lp&#UdIK47YF}At-XTF2bb|IA9LTmnE(gi zZ%Z+-m<%08-~DVJA0h%GKz%{MF(r?3qAMVp{wD>YG)c3U07wO&aegGXp z*(^Tf(vc^Df>s`^*fr3Vp9p@?ucnSo9q!QJv7d$u2|_b06a)B@@FNuO5wiOmI-G-A zh>9 zAHRL4-Xs|b5flIs0zW>ta;*Y6qJJ)dCG~aRPH!k?-z<0#u>uu9}53I1jyFp3>p;ZCh;#J$S>iK<^66{-5maj-owCv-<%&b zG*lSSn@vF2FOd923j_hg7rl!B;6C5o??oXHNC06O73WuM;GSQYUuB-;SS-`e<;|Oz zCQL}X2S0a!JOd1CyWb(w0f4U;1y0Ocstsf~-&rp#bUyc=ua2MoFh6t!h-1Wvi=AEt zlrx|JkG5apzd+o1;$hSkrN59bg#P$ou5aJ#hj5@BTtCQ6{=29uFm1RO7vIP8H|&qK z`2ZdS2ow*mF9l>Lw~x1%7%(qjL3e1Udj#e7rK|hb=*>_~x?R{tYt)t5j1s2b^F-n; z@29>onjD<5CEF-ASGqg+<4am)VObfErNf`KtcHO6Ph?+()!H9}ZjB z0H$?8iyYEnCL>kxI3$;g$m{C*nsueTIh_#*mxw#w&&_Wgi$06mhTwZZ6geSOM@aO#t&X8v1e7QPSL)1$XkAiNQYxend1dxnnt0nY*{Yy#4xmH z!$rmb`m1ifUCTKEsmZyS76#tt5rdF0$Sog#Jbnkrc*!;7$Cz}$sCeJrLki09lKNeS ze(po5&z%7yUx!MVLl=|2cnN}|f^606y7H$uG%;Pz=gpHLPFB}#BP zxqLRqr!R=iZY8AKl!fD6{{1+mvzi(D8cHV!3iOulZkZ8NJb6HZPMiuS8xRf=C3zIp z%rw{d<2Fq~j1p)T205PfN`0p1Q-+4?Lx=n!N~XiDPH=a4MA*^rV@u?)y}|RHgRibC z(Gn))OQ=mf9VqK0mdS+c3VSq2BEBfQu$)q`?mU*iw&fUb5bY4hs^PJh2=w`u3t5^; z9t{p!0`)w9GMCm=bDqa~iC*}GdjbsUtYJs)=Eb$P$lkq-ML){`KW-h0F9F9Cn#y09 zfh3}t%nK_&grNlk(7YkHvq$79dYvijy9ceACB>r+@6fzqxx{Jzt#Mvb217tyGSz!Bu|kVtDo3q4WhDfLbw9tkqor*MZFWZ855x{!(txTPQuR17V} zZ!tcK2e)PaNA6R@9i#Po=$rdGn`h+1->D1-H_VDN!{fJDB~IX3ZBjCI%;n%UuEBm< zay$PVgzVYNq1H_IcdN_KlHbuNI?ID5d7Jfv$7)U}=TLw&!Kx|B`XuN6k(=-L-@D`+ zAn)$4CFhf@=V^T#yD2NJ>^%#U$aTG-$Lu7%;hc)}x!! zk>|xCM)AVKg|TRgvBv=T%0$JVTn4pobIIBK45qcg2NrorJ&OLRMK#xGYtdf6*Di|lepxKa`^K1KTiHLA%k6hWQ;>_Ay-&%*q7z2 zo1YdjYEkWr!h5%|>B~*%H}|)muH>@nC@o*w`tF6p65^34Riin1_l8GC zab^!Rvj9@S|FHY?mMw|zm@Uf+>Q(KwH1d7!9vbh!H8~y`1|O3B^Yl#1YEo=zbELd79s^#ZO%m9 zx<{$m-y)1Y#$I%L57&K$J)LnpoeTA|52>1${c6m$N3;Sk2jwmdSd8p13>UR$8S`rJ z*)Aq!FSZp&r%`~E$5Qe+a-R0drIX5f*^E18PKXiv9ozM9eZk#czU$mQb*zsdJ7|`y zvkOybtq$JC5=3w^a@uzPx)#vzw5gdZ-T5F9s9*dJ{x438cwwF&&CL@3vN@yp+0$E}0j0Gg9u6|#&bXCI=? z|!N$ zpTBI~kgh$T1)sXQwJM5sxQ!~U^tYV?1O_m7LrDS}6ljM>RU$+^%za_w{w>szr?FFd zm?PL~d{eHjyv8TsFk6-Jy(xvGFRJQ{q?vz-hX?GSO|G7xjc>-hW(na!Qo*CONM5Z~ zda-wyduV0c?Ly|?FTMb)_mYDM)4I-&(9$UEcSZ>>rRmK-p;{nD$aV2(M1e=+u*>$1 zqcc_*IW;dy?zCFcW#h0PJDFx5v>iLm`hlds7rn+dC!-t{9L8%{#g6D~-c76?Ld0e0 z>n%3q9?2}pM>(dnN_DOrG!cKLO?lZ$xio8|l-WAYrsIT9YsBx7-qJ1WSP?`M|I{E$5o z&jWld=mh#?1$s}4_6vem6ty~7Z2e?5<6P2`HSVez;wP&K4GXefTi_>t(h);dy&C)S z8on6SdUGIIRKQXkpLOhJ>Y{t_Ur+Wb?>3!rRWDoN-RvS2M$ItX#igE&R`^fkSSis& zx9=Zk8in*PmsxI|eYjOFLEE9MENXUe#m&uhI5b}hLbDVi*u6Sj6MaB*W7PaT)wdTh zEcdY>&q#d?E&GH)w+zfOY&#A|IC&f236e(x{0Pa6`&*%l%qfmeX%TgMU-HJ^>!%i8 zwOySUt03zwZdVvSxwkr{V%gfD0A6fxaddbT6w+GFd4|-ZZi6j4FF7gjmgxmBXQWFs|%yDL9v@hFE zqf%(C2@*tQtnPd*Q^zn1 z`3(Ry-ld<>Gi+{q?R|$ye^XjXnHWa-4e{LSdmy~iiGXyk$VHIh2g5Nq)vb_{wvLr@ zd&Pv@WlAGAJVFPv>mdWN;eXv zbsq{jrL8Al1Y1B^XI3IUiXx7u6>EEokTk0o18)XP{U==pek|3T-(DB=CSPWo8lTlt zj_5*W_LG8@cZj^v=|6K~GE>plM!}Q(g3ibK0(L%L$?ehPh(hX5yE!I&onKg5@a>u$ z=BRDwc?d|Bp3LXu*2r;Q&+Jp!*~jIxp#guj)G2FrDNUf%<6xR|Hk$h4B%b1o;^zfch$s^Dq*Mhto z;sq!lcDx;2n7$*@m?K5L;*wC)IGiBUKS>WZBW0KH`Ex&b}S>ceGG1diz@zCksf0l4` zBZ8d?!rrzwmeEvzrxKwawNRODQs&=9Xbq(jH@fq^+rfuJdC7s%)~Q7@NlPvC*`Zx7 zrD-xFiBIjLb9V%QMf(=139gTKNpLuZxIeI@KJ)VVt3!5Ks7thk9OX^)VSyPikv%&Z zCNu+B7J`TM^^M48>l5u&NN3=Q>$Ut3=E8b6diAXE?^3lC`CZgBbBBUr27YNe7eQvsF&%h2L~cf0GVv>7E;p zs2#VjtXa~^$qW zaj*OA?8t|WX_hqzT-V^FlI& zq_hs0N}aqyc)b9bpAl}8;ol{OsBX_R2j>A369J%(7ePTaWIA0x&?!Hn_Y#(AWNne>^nm<-SfgF=&4udV{(qp2SaxEiWFE;KocO3Tv#B?iDu(p=K)Cil$^H zl{#9~Qb|pq)@P!M0lV9_axLBJb~3eY|DmE0F`Zy}IobIaj~U!t(-*E|Q(O@%Axp5L z9a24)HOoU40B^`u1yoRjFtO`6qnGLZBkJeq*dxy%T#6c4kE~jjIzjeV7|9^ZgZm+Q z!P)(7-<>K)pkh5J@m;HX={Ui_Q#96WbZmdQTv5MUJ5^L2+b@Euv5Zl#+W(4-Z3OZ) zq2x!p4S@CWPI@_MN_Ncc)o#+uV8vYOo$e%gaojd8EBopCEQ!blmRl*I8FV*hR!qcc|BIEj>ziaBPw zm#w~@8jYRdd$Dlh8T9^Z$|i6C%i3l(8WoP5%2;D<1ImBzQyB5;Q@7^0&7_xi*RXWu7kB+kqZQ7jK8P?yM+dD)3UAi{~xEYY?wveUbdP`iejd>Lp92S8ylA>ch#k+PfH5vB7*V{sSQCR`7(NNQ0o~vhGA4(HE zM3LAghxJR3?AQZMd#=*ho5$dRA%%vwb$D}&9y4jeb(zI$3X(RJp$j;dm3oK9>w}^1 z58BuRZOxo}F@;_1H`%ORwp@M%L$O1N?L(^|J>fpXkpo$g)K!)lbMS)QTZ~&JL72$Tjef{>|G47P<=f z1Y13{bt}VQyK7yeMpK3!orcI*ebfT^v%6{y`8x1$GpSlLUQ`WcPFlHKh$JhD5b=8JdN6C4y=_X)0VAJkIaffDKI! z{m5K2jxUfh(7o3i%D3??;Z(zQ{$tl1t&Jal=ZqjVKBN32OabnXMD!NJ8JH@{FIt-C z%9$FPR&(2{_AkeM7jSg@_u@c@qg1Pm07U~aDMffrfwYCE(hZNvo&l{8Vl*d^S#m6I z9e$BtvD|LEk(#|NRAdsGpUXh2>Ul;R{=H8N5?_huwB1umabP|0GZV>>b}(1lW_Pr` zcxjY+dX9=4@2l`2s*|D&+UHO;=C$BoFPd|r6cEEq7PQe~(s2x0Hqt)!_gsky<;`lD z`UsCFXq=d>;WJJrU3`yv*eh8YkQ>mv)Lutlaj_Q+wwP9vXnNVHk1q<8B{4HrCEeb- zEpyxB4wY$Pv3txsihmOgBqc73&N$v-i``OIw`a49pAakTQk?47Ab`>bS5*{EMv1;N zi>w*KKkj+_8gvb!O*BMJyd+LsNu2!O(wEb7y{Y=rH|7aq!`c(f*yj6|oMG9@>n&eLI6Wp3u=vgN4 zEEv_}qO>8Cmwg;!2cgCX)|owT_tST@=Pa^1%Ltz3yt((JVvE|P(2Ief@x^cQa!iV} zjy*r8i>I6PgFvhLIp?5`H!;hvHSeFr#=S}<^gnpeY`S1{(|M(9H=Yy!HvhH^yFVkn zzUo1BTPg+-^hOC;;EQP0Ls1}Sx*1*)rg)1ieFiye>vjrG#p2>!ZpzJhjxh8vnSo|E zdR@VPDlv@vqWnLn{tQ^YsBHMmtXu2$nr;uJXl}Pl5gGMa_SF zw~^~cz$K3BZPdcnZaz4rpHkJ@Dwa zw9bYsHs*B?GKvpA*7{UE5qf25ebs;kp-)EIQK#QRvwH5Cl=~|Q)3tq~S#3{F#jaV{ zk6&s|$TsrYZHQj>mT+=bu?8ogaXjY&CX`utJ8+lJhouJff;2qDTYT`&6VgY)?sjQ% zl`5}~>}vpLLdYbJnJe{=bBuckvG50x@!fM^`tv`ocdSY)h!U;S;2bPL_&h9asnct%}b zbN=COubf}IQUQ|65DnKZpq5hRIHq>o}^yYq&kNSyzQ=mSN~INnOfnxpxGW!H72@VWRbE>KW!! znk=a94zmgWMZr$@_7=KLotJwj+!L*y9L9l^`^;+UqGi)wZcot8%jH|!YBz_D*O_2m zrKK}+$HU9CT(vCyvk3~cU(cXsvi-8w?Q0wh**bOz*@bnynSVxUBvP(in=Sq3L+JP8|ruI;YN(! zV)ulERIuRzj&H{Hr!~3S@}`7p#!eK(z*u2YqSjfKASfz{E-(ZjH-Qzz2oJ)}cx6*n zp>qqC!MzvJjZy5`{WI4EDJ+uaVPp+Y%U_Lv^_vPyr=9i@$D3SU z{SNLHy#c_4m_I(w{!d7+0%Gj@eY#OQHyp_n@P4s!M)duDw&arxXi>=@ENhyxOnpv` zxZejfJu1*KTH8z$fy}#r_F7p?XNl zce>??!#so5mGn*r5hj4dfXXJB%4yI{CQA+ii!j27<7F=NJ+6zn) z_MPNUzIuZUa-^P(HSR(nYgIL4>(~8syC}7KgDnzOSD0fcp6Wt({SeOQsC;HVP~?H) z^@_K%9PDLBIX?LTj%2?$b;Ansc5ll2@<6#sh4NsZtveU)v^?h9(zfXj+vlI9K+q5@$fZJ3xJZlhP$lX07SK|Q}yVw>*vBK z1j9r6*}yX^*vyZo_Y6m#$T4b8d)|4v(xWIYSR9IX3CbZ|S)SQi?^1hn_`{GR2UL0b z51)T+u{h>tt#3tqGotwNfXHsEvnERt3-a@jlcqxY2)rgkVtO;1Kn0mo5}Zkg(C`C7 z(k3m@6!t3n3%nIzG$B098^)KW(WC%6NpLw&QkgTeFQizDtUpS@FKo=Aw;uq7epk|E z*;I|j0f{-yv9hOLv<}{l0}iFWq?5WOxh%HHZ6w40Jbr4tRs4=JA48^JB52jsuOK^e znUZ$o!%JhPZsbybyhVSwLhFTC0n<9v zF%{P(#5!S&u8{B{UQ~mW!uxkeKOabax+6u&iH>xeoTZQ;gqa_;%3OQlGjnB)d*tNT z1pkaXd@T55)sl#;Ch~MYAcp+XjL&6 zT@BVEC%j_3x;45lD~CYzxB~TdOOUVtl#)oMUUFU- z9CjDqU(BM6C_^jS-OP?N&V5pNTLn>Lmfkhv%3Wc=<$XCI{o37kybi}K)+seq}hNtnqPlMrM`D$#c1v9A{I3iz{mE(4<9iC8rS~{mD z&SzR}@>qNeO=xmt<^J(FA3%~LG4dp?Uc`-7hsAQNW0St)gVu9S{D7Ln^vx^dt_#$S zlQL{>Rg`=?WU2#^IM&O!`?oN0cOAj&RvhBLXyQi`(L*M_whGaFh}vhHcV<|!!*2uu z;Wyq`P1DdjZ?l&7Pql^CE&=F6V)wbkg8E(X>MKRk>oCf^Z!%@hS#re%6yc2HBVyF7 zqPk1&XbmDLs3I+qmVsryvw&45J^jYwVza)fCaV?*;}V+G1l0EIsi%v7+6;D1sA_&n zTJyS{ATs@y-Mb0y*yAOg3O1(&j>oYl$pjT2O^*p+ zrpz|I!V8=+mGkWPc!aHiLrBXMd~P>aWqGfMWME%TjKutuWoya|{aUPH)%aIpA<@U# z>V$Kxy|zNyxyGIRO|YiK9;LKKn^injZzA(Ag91*1LcC>))f5~pW=>4{F<39s79xG= zM_z{S*lV|gSs~sgUn+~LYHb+@$pD>=oIqJGDlQ&AXY}gkruLQIm4m?N{IxlXfEDiZ z9bHTengko-M(Vw+17NfGpxAf8zc%T{r*0PjlLNAK@vff$woT{r`VMsqJ&^^CYvIk5!#(@o(^SD|rgjXu z;YJ9aMVb6iN0YU49~EXjH{6~OJ@1GlEOnTD@phB+KW#c=;_a6fBv!SoHcEg^R>9wI zXYB2Cm9zePY`4qZ<|RdI=Dyd16v!b_`Ny{Kac2;6fo@8qrjWNE8sHTx-D`5QOv8rb zHbrWRmh@c)dPcaG^;Cw&8F`wrBA<|BzB80%eR3NHbg@=)$8hEC=b?uyP&tG1JK{Vh zF!6sDNIPM8fJ09uDtvd$IP^Ko3ka+^g6?^9{~1eH)*y+IJh#P|yNI&t!47KsYwd#D zhmOvuk_+!;7W)|)5i(JU*CCvwrePag@J;wpAr*)X7P<5jF#oU@XXIpPC z4$g}IzLQ#%gBsaCS$+!$jGJB9v{d+PT3oY1XiE8z5HB7m*sW9$PgL+vFs`X8L zkhfchxcXsi(S#Aih?AW91kr~o7W8YFo!X&8Jo9jA_IhKdlHqZ4YX%JBcD%~Zja6SY!B_&t-! zfRHMd;^rzNo_4q(0ze>&_>ulVNY*Y0SO5`GseqiToQuT8EGYk>5Q$g{|M>Zx{xn<3 z(9ocMzv2DN@|x-P@}u_F{!3OcA>TwSjT=1>9vDF2;UAF`p3DLOk^m6Me}LlcU1E;| z^nxzkZw5E0zi*!Ogmo{GARX-Ve^;5@PhbM`mu81rGuYyax!f1^IX2fVoRv9s|sO7e~LK7@FbE zKmRArNM4N%i2n}whZS!H68N>xAV8htU^UFJcVbUY0~S<8 zfH?D}am9L(U{W3=IGY{xTlVeap{!~whzngn#O5R?MJ}u=!4~1L! zp8W)95U_~fabY2W2_TIe;NZP))JQw`R4dDxVL=FLEFW?1$<1o}8v_IS64L<^a zW(XUs&!9_R0PvURZWa|31IB+K+a5qH4H`$}-pz#@#_6YVM2{Ej2D%P#zZo3N-`D5o z+c-289VJ@u?OW#8r`Pa<>H@69bHI=6$L(qcw~3yBUm1yjikvbswXzL|UsM$f;c1rY zFT$Iij{lGBvLI(6prc>LaPC4c*2~Z359rUsUxK~d=BIi0`2heRKdUV?5>UqhzkuIe z$=~dUUdS)C^jE!r7XE4A z1JIxBZ?SY)T?`mqn0}Fs7V8BHMVWwK{^SF*2p;m1rAZ&4TOif(N-|9IE)fd)7#}FEX>Q z$8RpC;?`*AJhTXP(E9r(&T6NVH*>e9Cz6t?bs|akdWl`~9*Ah;Gn*kW`}xFztFV9@ z8z0HKj6ewihp%kEC+^Cm#xbVJC0E(ECz3Nz62an-XZ_wvtE*v82~IEzcW1bvT3!E8 zKS0(QG1R>aw1McWT6CHSrEm@yf|{w;?yYk^&_lnh$&rs?ofmbk0r$Yd#TIZb*!|G^lA`ql>{!(fe+hr`?k{=pM{Ic+ee1dUnS&`l|6d zkXG7$PAdso(Po0%&W!iTw}soeEgGS7Gj z){Ny;Bw!_EDwT*}me@8?06|^V0QIe$# z9|^&R^l@lu1vwOz?IxS3=jJruVI`@5cAx>y?sp9o+#bZ&`5Gf?(w}M z3>pC)1NPIOaGZQ1IIlx1v?|5Q@ukJuhTDKH@TnoQRj8X;j`w;7a=Y6mD3H$$Z?t>9 zv!c}bM4=cM5I08Y@NWy)MmHUL>HLrS)a}edX&iu;n)zG#b|sTitQ4bfI?s5FMd?VSAUA(BicClClLEo< zC^ks&5e(Z)4Gd7K`o|7duBaCXgT0MXx&?D(jb=Qp4h*!pVaNJfhNw$S5Dvyaa^MKx z1+r6w)k#u3wYzOfzPE7cnipxsw*TtcQ)(e$?)fv~6auI;oKUOEuX`f@@VrC<*Zm;O z`-PeQ042N&GpTnwTc|uP0drn~y)caRW9zL1sv;v1eMH5NcR)x)HyyQbOM4=h9^Erf zkFy)EpENl;-r7q{Nu1dbl!Mwq8h^20OvL`4Y2|pDIcR$B9!CUMtnfVaL?fCj>r(Wy z$1@K+ws*zbPmn#kQc5e}EdR59x04fvX;NgJz;wAmvApdsqV(KUC>392iE>;T#TG?4 zV=1p+X3cOwlzWDKDD~MVp+cJC!@Z+dRcrUrAr*wgI9t;K4F|x@g2t>$DZw|zP2ivl1B~~fpp5Uka zYwTgKM?eR&ZWJQLWJQwA5cVM8PoZ@#FC|tCzH?m?`V^_kn$Mh$U1-?~jM&m|EW)%Y zX38at1W5?h@0*vG9f`xWe}mJMTN}-m30J85fu_mjxTW!AKO<& zb6l^N1mk!F>1`&G=aXP3!LXvdP8ySqGm8z>ZxCJZ^h9>dbTA(woLDh6k6Bhk_?>~-aXFNe(-XD_8X7& z1!Ayxpj-h~U)4pa*}2JVO-(l?aWv4hb-2~0w6Y#+l7!of&OZ>cv|GGxFfb)>?M3m{ zw<0Tbo%m^`);tXi3TKTg!Qb8fC2h4;m+{qNM&868GDMlRs- z;M>_J?CaKAFRMiTLoEacOqPtp@V*(D0Sk}At-yH4S>2IJWoGLgPn`VO8G3O!kRTVx zD#-`kn;Oe6=Gx}U;$Eq(GrDYMtzoBk9U$NyJY5`FHH|sxMvUt$GSe1W4bnwy1NVw1 zjqQ4#0imCD@+l0$B};YfmX8UFz_ITP{VEOL;wEIgCH#m~KgmM*HgUP+Wlx6sVbYar9j}y!bUI$# zQg|+Ym&;*CaOD3KZp|kN-LgzC4I>DK?e7CUV;de|ns`5NLikjh-M+sBOy30oZalN`-wCcT*MOMJ(yS?|N%ZU))PD?mC+OmtT9 zH$NSGa2qJ41jBk)dtB*Xz|&CUsr8}@%15TZ2y9aY;yO}oX^2$uuJ8N9rrzBp1Z6CHxqZUH2aL3J)urI&6gqfCAQpQf#ieB zC2;Y>_Y!iPR<2SY7~r&5uJv>HQAsa>2&g0tFV{_3KtJrJ)Hcupu7k!yIMMv zoB2oHJmHZK7REU6_;%y*uxwPOQ4jB!-r|H2(^vLH_z}jlejCqjj11e`sSFY1tn#ss zJ28QGT6~pj#Ck-lw{9k}sBZR7iv!A$$VmlAfJ8Ec**Fnxg&U7!K>4ShW{)$hK(d(8 zbc9znuoQ7*EjDL#p_=iy4LzQ5qmZR$bx_P}IYourplrE;IP4Ubxfn_?c^>E~Vz@B* zEeduid(=rq{b+NWX&NB-vdA{t87#f3IW7mrjk_7jcN@^l)ugmXhdF18slM}!lW(gg zZ#Sy6`ZG#(%y4Q1$zuT#8au zoR%RA)y&IL>_*t5u8(rbY@alC%jCUd0*Qn1K}p zfy&{~J)liJAcWDV2!`c4x|YtL<=7{~R*Js3ps~*Qu+T%wPQ#tL7ayF1I+XO2_pkyRnY zBW>D1XJ>SdnPFw5X?zhO{_Lh9CWCL{bA{%zaQAZ0cDwbyO0v@lO>5x?5u^${0C!pO zt)yKaZF5D9>;$bAf|tT09B~91o<-|8a1sn3Ls1NN=|jw_Czd+o4z|kv!yI)eZY!6% zW*;6T!~|CUy>4E;T^(lAV-HUZkcTaR^-mqI=c;=Ik1#JU10>pyZZdCkTY^>$ATZE{Sd%&2e@h5WOl3-DSvl#2 z%H-U^5AnO^k*ONS2IyK(Q+mjKE4;v?3B@_&iAc@ufATXw+zCfkbepEDtu6AKy~Ovz zWlFOLqGRMIsL%VFPkH!WE7W%BhV;(Dpg4F0{vJl;SV%Wh2+hp&K#o{eu7WaRn3c50nuxIj z>zE;AguG&tg1A6r@?yZQ0C9JFC*RZQHhO+qP}nwq0r4wrzdc)zR^HbjQ69_dMf_Iyp9*Y^s0oU z!5251PXE0^^xZ>Lb9Ah+682aJ=(12aS_nJAt>a#?vYi^ey6@J)OvTKIa<}mkGIxDY z7wtZ;WvwvAy}dEXKi2-b(i&oZuU{$o^2%;T8-sd15R)u+V(-;bgDT0Do7>JQP_4)j z4mYp~@gS2)_i-}YBoz-yS32{bjLOSKT3DoTC& zlA)+72>$j; zd-t8Wl19GJOK=q@@fk|{N-C8=IO7eCKUQtD#Iu>_CXYGqRuP&O!<5B6^vl`;^cR0t zHSwCC_7~hCWo%i$52>AdqIKXSwODslJ+BOm{kpC5C20-|`sCtRNm4|K|CD|oAa7dF z8(A%qib4jBPR+fsG$bmXI><2T`m6|9*~ED`9(;L&DN)+ysu8N5-Ff-h46PQ$6*n zIfW#TYMsWnB%+tv?iyKnnz~QruS3#qOTkp^B5mgg->w#2pbo2=hh~84oBpPZ4{q;?6~})y2=Cfe%mYdI;HkMvk6Cz)YM{ z61-mNHhrhjL@7hviO|d=+l&i~gRAcUwKtduvr+UYxGJ`5BIRfErv=Oj*Bh$qw((;r zIYHjHQ6Pm{s33ndmG-thW*>*CX7bbAS;u#OX^MP^^8k4Mq#l#?sg-%gBaM`-UjV=a zd?S?PF2NOdw!=hDq9y-#v3#tx-PULNPbmR^&gMYZU2IF|gsGySMw-}8#@Qo{fNW(a zGK*Zn%V%AuGGFu`iTD|YyW^!td7Ev}&W~5Rz8+rtB=m$7nIIcE2rWJP+kiJd%u6t( zoLD&!7j(s!#*@|}V_S8ZbF&k&d05a-27h(ll9NBs^JyT8g2Ai9iDra(^XfBych9Y4 zx$A}WUMfpc6f?E4y2K!=oHoJp0`#!<(FmBqD66e6VTn6#{I}1 z^ivEyl8A(RpwrSj6=%*Jv!|L(wl3R`zo>NLHAVNI$a(4dl$1h-C`LCCz<})5GAao-k1p-0J?cnsBFL%;C zpHSGb(K?M9t=8d2H+)Un`uGH18iDao=!|Zng^g#<$di;3h0^qxGa85fQ{4JB4`aJLtZ%B}S&bMB$X8|Ow`V-us&{Sq zehNLq&dNUaSekm)7k*||c15emOl3VL*0HV%`E*s@9Hi~udqJJ{d~&){^T$ewQv$9{ zsBv+Bgn3FEe&dxNZlJfp8a&TZNPaOcgsszS%=r)oMj@C2-b_}jl0U4YkTE=b_oO5u z+OuznU1RbeKyt1*olEYFvIy%M)IUoxJf`g*PgAN@Bq4sL>Dst^Hgfy?L~)-oTl`*H z#3;O~JoWUJjb^mUT$H17t2F{88K#;Z@~+Tiy!pX@)eZmE;)dgDj2WHnnrYO6KXkMt z<{H#Jggy*{HhP?*L#^cSGmCVjM(I~nSBO~!4kwW@M40S7BrVGrsdxCJG zl?4-@xRBaY@{F2IxITrgRPXrIH_d&aklF7>*FYvRaFRy|q&k4g@>TSU(J8iZ2$7xL zyIU&oY~y%tjucQFF)4qbBM?-d^csP{ZPSbK+tisMLPrm3AbpGQ^x~ioH)!QXr|qz5 zMhAA?#&&n$`nHUQ$(l!1J4rmwj zfq?!Ol?)Saa(hW?B@D!ltZ9-Brw!LQ_52v)^|zeQwDTjYo%FbFujqGGgkEB)fg;)7 zc~m{Eo_fP->$42QEloI@2wew`S-8@+gY$mg&Yuab6p~+L+na7+*w-INlO305N^MHg zmgbU}aHl<=_bQ^UPrqsX>wE~1bM;y?1M{H`ZYmE)avf4>E6qlsFch2@#znpe+QPxQ zur#A#?PR+rzcj^+)p+kIL{T$txHQKA&$7!|S@|iaQ7KqC9Ns#&vD7H_*tj~OVJL99 zWZgqkftDq?jlj*WdCqCTdufmRW-kAfYFeB;Q2hUXZl4YSd3iG38k0Ojb819DtK5tl z-*{eqXWuWTR3z43XYPtgM$ya4^XfZGI{|m78`L+J6KiWpRt`<8<-(CSURR1+ybHLt zmRMuEoE;0zin+#EFM2K_n-~9;GBVRM{I`^mo%KIlkrAJjiHYq$)Bi^qnVA3Ql+ooM zW!zk$(TOJ1DTXW%CkxgUsdPSP@ed{DCx;>~c-@H-hfs+07e_(lU_M`n68|lLTuk2M z_M<+-^V4w~bH6i&KK@$6vAW@P!?HR<VOvW7b?QPzmXqBhX}?3ADtTf zSC9yBn=J;B!%R4zK|hTWD0q}`k?{|j09cU!!5xDNIsELRNRhwh%?$rhNT0 zbXa7tAQJ#-Awwg-N;$+I_$4slmN{}zRC_6~>x&qH4X(Yr$**t7qmX-G5o6r_{Gh>if;#d4wNe1v0>|LQukAVzHRH@6MG64j1Dg@U2K?iUTMG7| z;Ng1M=EW5tOHLyBzDX{=NT30JGvMUE{=Ca|@U8Q~5GeE|7SN+_45LIoh!$Q2xQd&B z%HP()L!O2pfeI?zbqhY^Y`*!cANAY|7 z5$Sil2>I`3XZ>=k?_UCo6lQjQ=KP-3)`o<)x0Lnv+75p7Cnn74^6TQ!(aDL42!N4) zC!_*NN{j=2|LBO~MSeBG-SKr~l5;W3pS;@Mk3PM|@&M5NUuW&_fPZu@aWQW-LE~TX zlC%Oy`su&Y#(vtC{Yt)eu>nmJKa)p4Jq2AiGc$eqJ9=+Fz(P9lGdq5e?u(s=cOdyu zBXPhNeHEtRyFyh_{zTh40IcO9f%~BR;KtD`4RK*?P}CnBF~eKJ9z=T|V)&E0O~$@M zQa-V1j0nNAqK2_NHyB6FNn`(C} z+D^I^s>8U}&bITyP*s9r!V(W|t1lYAWs{?3*q3i1kGfy=07;BpW##x}EpDgKwkFkW zD^O_Q3QUTh77geA1CfK`KlEZ%xKjN!)DHO%+$<46_Zd>4uhe_7$1Q&0*+jA%;g+g#qBpoBUNjnfg;B;ebVne4TU+&072xj^f*U@^8@sJveG`y2J z;d#0%U&qO-%!v$d(KCsni6|c{Ix?_!g~%2sOSN#SAkfEaJtnWU0&lK8mV5GLnPQd_ z++3Ut*26qTYMk+5#k)Crh265BB7O1jFV<#>|9Hx4 zucU7EEKGerUFy3vEMK>S$7zgSnL#~o+Lw(3VgOVYZCxRJeTVhc$CGj??c#ki9|aL> zeL(}J_Pi?OcQb5x39%Ja263+RyeYeE+mN>~FoUK?6quxOpeMP*3h+Cx{<`FvLos8p4DJOC*xZrN9!aS6ina~zQbDm^M_k?P zHS}RE!i5se(*nDn{w=h1oB`B#^)Th!R6eTso_EZuIJ8Y_Bi=N-fiIZOQSdPYQTkv` zr$!XWr19wH$o^FLlzG5A>mz8>!kgDx6{H^ZfL0y^nCRNe*!;8ici7%%v+q;(2>H)q`XYl zH4PHKZQX49*Hi~9u#gqysDLTt5zlQJSFsUgyK*l;#Ywqf~<+e=_l|*g=itOMdE>fQPDh&jdDZxKkycOU7)?N zj;Rmen@-E#FsY059x$A)Hzg;1Dd4DhNMoo0cjR80h!UGoIxVdp^u8|SIh^Hj5nC#U z@M&)5)4c({@@42*-x%0QSgonWvy@aBC7(o9&xz7+UMaFlt^6r+sR2;>@gOImMWvuL z8yXyE5*u2cihB6R0%Jw8Y4_D4ecqvs<8Q7F@puQLj;mIFjdFQw7y`T zL+VFuFb2|#dE0P0w#+JeXQahYJ z&|1ZKm9!PL(%;@YMonV!sec263tNe&Rv*VY=yT&|hghc*kp@k_g=#98FOgMIX*W?r z-EuwHOdF~|NcP$u5-V1l&0cKCe35Tgdx8)BLvAU9K3R#$C2d5?}9LpwIlx<@Xu3Tca`Q=8a&8tdBDv z;)|h4HSPVH!$Z`8Z>`7nD2<1yq=qZ86Wv$@)_v3YeLrrL$aD|_1{k8#t0UBzbXlVJ zmmTCHh_a=?Z9hqEB&%rjv^T~ zHvwEc<0UT6t%Rb?6DKh&`Z@8eGEy?OF`E{Z(L=3(NpJEb6rn+EM8T9c((+FvTis@Jcp<4eY9oTiANj&-sy{**4gwnxP zxr)MF1~(h%6-Z4~;CH;>lX9bNzBrmXHTHlr?7*#(gq?ikeZ8)0xQlF`JbBDV)tfg+s z<6jqo!|d0TU~&9iuHpV2G|P}&PtdsIT+;D^NNYHIz{SQ|Sy)Ha00iAGo0~==pLW@j zv`j%eh&+Xo5UC-Tbzd@19agtx3IsjXO= zW4tpT>prJKEHFH+-Ujcob~-^occK_A!rzcE!fPFeew^p6O$|kv&>*;zeCDw zeUQ|V%uV3i=@}Wy{w(E!$>#L->?o?9GEI-iwUS#}kV$F6;RjQ$f)Yc4U9EW0pen(@ zR07PvHRfeK;z@J4zz*0Su-^zis zwAb?_vHY@Zl5Q^8yN|Wj?nnv$fH394)25hCrw5xJYw09GCa%_Du~X`rOgo`k(MG;` z%B62v0s2BXSL~l@c-q3j1_loiV^5u?qG=$ zVRyN6rg>Q$QWL@HQ!Utqr`)^7krzGr6Azpr&X$gW47lQ01Kdsj#4uQ|qZOInx}?eD zv`~sK+l@MU-&IyT1Cg}$&^oyhWM#0}LGQ*g9}CW@v06dnybyHMrZUUp+kmbJZ3Dvh z`q7D;(v6|gtM#Li<7=szf}DNSy2x_oh;lijqHH~%$CEhJp0Atba@9LAVbJdLuHuO? zY&*x0DlnM-*E#zEqMo*W-E#w&)opHI{&a8Nh?4Ht8EHY|UaX zH>=w!OM5tjC|D!iM9`KPWccI5xA19yYG)&+Q_u4`2)N;#VQgCOBihs;V~{0v$^@5C zp^ellhLiZB*|txQ!p3+2jol>-$vC80D-=~10^4N3q$z|hqIEZier+67l~8h z#{Tc%gyGJJG{MRy#rIL8AmQc34er&oJ{j&cC`+CdnYd=nTDo}Ay3k=Js5Twu^@>|A zY1(FC5|vX-&|?z$IpV}QJ?|$9W%f%y7Ua_T%xo2RAc2s09!p}@s&j%23OdOCO8*f? zlqzZ2%u1IWbBG-n?v{W4LytZ6CSyDPd_nos$j0o5<`3lqC6gdh%zq;D6gG?Zzx0~C zl(Uis=1F#eKZ9JiVmGNu=2dvBB~S0AVh+`UqDwDLO4iunpsTaYzrh@~n6JpeYxf>? zl)$WJYf`0Hv5#T4aNa9<-x-u!Ul8<@i8P&*O8E|-V#Vz;~%B~hCOOT$oruDXo zNw0_IsnclKS`PQonNMXqvtlqWaSk+(hYnN{^W)ddbwY9|9miE95-%%O}*US zpUx4gKh+|woAlI}i+II+OxoY64XpFx-xrP5)XsNYj7(PDtbpeAnO8RDB?A>wJe~El zt%sXKJlr;&fS*h71Alp0 zLM%TOXt}URxh4tTUx%;5o z-xKAm92egI8QhjSm%{|dqGU;*C53OYI>@^-Uw7}L_wNkl6ZDv-g-oErbNNTr7@k}0r* zS6K2I6AAVZd};V_FtMsbEW0#)?bj6PRHeX)H`R#A={`}`zX)p=83{AMC2*k1;tFnZ zwQ#6H4vRg?Mo_}c;qg(*yF^&bEV%S`d=QMlBWiy|=>mfxXWu}WDXLSPhc#LOmcHww z&qTi-sf(uA-ZcDMCWIh`zXdaGxR4KPXxnnrTv-Y<8HHbjFJEtSrz!N@Nyx9^xFyB; z=87|_q3igdJm;Sm-Q0ezhr`85cTfbAv_-!DcRNn*^7S?fQ#bpWkDqmB4ER)TAoBV} ztXm&2lR#ctxV-XZM#f-p3Zbgbg!6ps_rgL4>5qF8lFV>Svfr1Dbb$8408@bn} z?MZqW9*rHJ^5kGcVReSf;mix3^ca~PoR*}`%528qaOg}h;TCS?=`Jb@{Ihawq z5f`ES+`D*y4T$Wf{juk4RI8`74brV#4=9#Q>*g{df#yaokmXGUFVT-;=MqFh@xwmR0OwuIbj@Qo z_C0MBjK#t7-v=TNzWR70Q%+pyrYc`>&$i@jcl+HeZ7&^p*}2X}32BICpF6>T?eqB? zQV<493ZkS=6!VK+g#3+vtp=B8Og-L}QI$dxUb6|x9sI(&a-2(@i+aSrQa?ePs$w1{ z)1z%CmnWCpfm`h&e3Efp(&mU#Uk&+*?Fh28`pzb&>c(VSs%iJLz}mf1bgYbEWMp{%c&=Y&y1#$a{3oGzB6N2Z4R>=5QnL5 zGFv0E#yYLF5BKgZn}xql-6@Q4*_#>d$vKqwQ*&vhS$|a^73~Cai9$@vGM(M4iIU`hmloi@2?+qCH} zCcvAg;7BH)gb#PWMPD}4VE^_70A0(lARQ|(IZrH}zl*Y;K=3;TB5_#)6 zEsW+gVt8REeq4EPC!P3(+M8fNoOgxI*h=$v-G*HzXU@%qRpa&ePQJGT7;yg(n9Zu! z&lU2oyv`WXoSIFvBL=Ko3bmjoGd4B4bxM}&6_ljk#<~iyEOsaSpQ@|9-cB1drp0!w zd@XcF7i+vyU>RzgM&soL)sVrGeGTmA?#O(eC1;_`I1)bjsb8&jpW`vM4csdphfeSj zE%fNiOQ{QNnq5|=E;(uSA3N{k!#1r=OGIF|$=C1X8i_4o`~;1elSM1w4k(V?1$qre z*kIWzD6(3*bVqtTHCY);T|fIgKh>jD?$;lRyCeE?`<8cUxiRLVzO=vVk^j|av_Onb zfJSO3BAG(m>W1}vG&aX{P?^1}tjNc7W-o)#J`nEeJ+}CQcBJiYdVd;aPforpht}c> zCB>22UF^8~JC8+CBAkyt5>uz(ZPycR>=u~c#AFNlRTb?WEaisisggRzNRd}oc%erZ z*<|#fhW50lUb-?v74a)-8)i?AsktU}(K19NR+cgHS>72%$_ly7&>C~*Tn$8SsZ^Z7 zWkcEhtLM!Oy#ZZ@gLv>>@^fZ+W52p751n!OSp=pcA(ebZ(~>xPa8%vb5?nXq^}c%` z&ugH3aCE`srK>~eKsc1f#|eDeX&4|fK$+r>KUow>s|AE+P##$J$(?*yCiJ!rn}g6b z%(0F0G@(LJvc)~5xz*lmr82v|bM9Gw((0%Y5zkU}PuPi7Z8Z=8wkO~XtZauFDTbko zAKI@fKW|`CfwCF|UrZ*3))^(F5VT%>n5Pogcxqn>hTSI&x#&MGa5^THol z&ovO#Q4pMEa1{F75S~zIvC8%@b{gd`;n>-2H9l7;7#1gn^!^pn0aA7^bhjAP@Z>5y z5lJwW`+j#~8E3OBtqItrIZ^3dzG33UcT(>z+&V$!dr99?(B2b^pkyd7LaEeRU?H<$ zt$h2Aknk{BC81P|G!ojBWD!s9QP#3ej8cAqd8=o_{6b^lo3?}!S;Y_!K-t}}J2wZTkU z&YaCm;bE7zuLSgn=h1!j9PFkCU2xo0SgSsb4!i_3pR9YmdZ`BkRWh-Y_r`=9ttO6Y zAML+|K>Et~ePXCkAQJ2I_a6*ue5ccrv7dNom?lz`hOn>erjo&S)DlK2w)Nj&({g~P zg4D*n-aJpdOQnNeM%sA@ZA|ZYxM{9Na&1;k~GS$J7(kB^6wxHt!B-*51#gi_Pc0N=C!0-2Dl3npG$#ch)Ml z50zI6t=u&q7iPdAD?0nED}`S`2Go;gdg}pm}+rotzy_3~Zp?H=>`xY;#$Q(BJJ*MY39v#G7EvBj5`G+S-q`+vp~%3b_x^|i?2`}wGebplLn z?HDPT+Sr6l$PoDlwt@R+p!83F>z|_N8-du@H{Ab>&W)=8;hUTo{IeaI0+X```0Eo} zN|2e^scBhZwY72oc!14m%z>=Ezk6f=j^PpAKsz@y(*uAeOl?{DN86%NP2quL$Y8Yc zvtECK^N|`IoSabgO`e~gj2WCjo7g)vqvn`^xox(sfiU^$=axatq28hx`G==|zu8$* zi!TAuU}@d$Ld%d*vB@#1;qS@p>01GV2JC8Y38eC?^=rBMmv;Z*U&es^*i=8a10n72 z%L36iGx)J<_w)Ke8AE-dGh>2*ArmuWif^MC!_+sq1OhFeAa7{*=wJYz;!pL%$mH

S1gAKtHaSTEv$WClwJP z9)XK~RPj=1spSuA?e=K=__V*^lgY*3`o*Wvj4fQyVW!^9RBzyGp}FOEFZJ2%2#fm} zukf=0v0-6h;X&X5o&5sx)L5$rr0`E}V!Y9jeCi#r!2^0{WM_b?*f9D1w5awr@e=9Q zra&O=om?P3J^@PieUK43IQkY=`{48tnwx>~0AW8QkQ%^<-RZ66C7Ao{3#;!HP-~y> zj}Mb)7QGZ%e9$Z2qaO}KRd8l$ZZz^?AH|Ov1;PFi*qzDA5jee*eG~B7I!8NDw;dhe z2TN>v>SfpEYfuf>_!xBWUzoLx_q)tE&TkfIyALfG_pYx&IeUi`4Kn|e=`7TG%No@V z;pJ!c5I~pqd`bZT%zm+G>pYV%G-wX2bkb@~iiH?&l;0T!UQ$&|;0f#SO%y zrp9Df+}7kPv<0O1(pJ+9>iKPz4qQ!*Pu9kU){iCT=bw^9wV($vIS8kZ@+0-cb^ul{ z2@voGQmx<%$Lpv3)*G4x*H3v5Vh5^r^g|@`R{CnMz)FXtVZ^c?~EpB*zfmi*394W{hFSi1bc^X5(nq6!ymO>4VoX| zb>QlLzy7wyYCwNq{54;*or&fTNUuoSd(vf17wgUpEB_oH^^Wn+lV6eH55k*j-5}o{ z7RD&woz1_i7JT6A1lA)n&i7=O!u354IJtV_yJ*|U`6=HGns8(bTQ98b6%TjXR2qi*AE{{kjclYMy zl|?R}bG@H>k&M8+&sc}|pu7uN8*(6wm;(4{{*Xhw)&-O>l8SFmGZzMdD4PveO@SmV z{ZoYsiY!v}!#=ylF#`_GI`^tt=MbDv_84RoBnPP9uPb0WqOQ?B;4Vo!2H?&B$mZiQ zv&d#x;RhVLC(V7)U>KYwlA63Uq*f^J_Ku6G&&g?%hA@-(gs(LC6ViAgD~(6`lphq! zuySPRRsl&(rVEkjqD=KzOU!gWevNWk__3lP?IRnE63t20V3xuB#-sh4-_GUtgtM`m$41e$qnw{lzvZ01t&rJHLLgd zOXgW$j=3@}OcO$^dA7JEqzoOS(1QZueQWTV_q&jeVsyS;&$j)dzD<$K(sVjt8OQTv zz?4g>MKQNx_^u-_y3@vr1ZByp?$lqB3ajtkQJCwbck(ST)mj@+$qG>r95K zH@UH6K#~V7!w9Ohfg#Fx?{AkPZXV#W%fdWlW-hDAj|=YFio}ar>r3+T87q~dgonj( zM`zUKLlFc5)mKDzeA)>rc8`fI7y>C#GU@LI%WV*7%T0XW1m8`{x4(Yd?_F)7j@laS zpgWPn*q4T;<=#>B^(ZQ-&fq2Y^-t!XLOawUgc`uVR~Ce1H8A_7d8g$|VhfCJrFq=m z(}6L?>g7_S5aB@}qWq`*V=WE+WM_lo1=ujLoyx%<8zC!&o9DgeQHiMy&)J9$m$AME z;Eu6?>atIosM!3sDq13Py=`7uG?>qHc8SJKIkOoSvJLq#a^7=5;0%xz@CPV~W`D?EHTl?HAvDHJ;-yv# z$RCTYucZ0l1#*bmf%idU@QNzdkp+^voD15wZy(>USol_JppFrtYM!gMb);aGY+((! zV%s~$>j-7&U8R{0UgQfb%UOYgR_Lawt`yzO6KC+=Zd#uOm<&@~w3fTgA3}^Mk(b)Y zYKG`u8o9W8G*H@*J0(#>EbO(AlJOmP6!eoz2qtQpO}Cnxb32{TeNt(?WxZ&7N6>i# z;z_kMO~x#l;2c>pUn>vGf~OjN%uez6mgQXXnzqBDIoCXlG&oC|ER@&fHS_fd9Y^G` zbNX2lfLSb!DD`EEZF6+nt-xAr&L{vn}hZX^<|{+S&|o^MmzJ3gs~e zSF;YBQajsEQ7+$~)HbyROW%`IpMHgdUQfj#xpC(F;$hk4P0A#sYpL zbVuH8oIMYQ^xmN17!V=bG`o2N8zF6GF|hj|M{(80A=e9Rbp;Zqx#vs=y25Bd|LX;G zgPE4qI8x{`8GhPU*x4t^C(M>LQ|#b3zQ}l98@BBzfIX8-Vw2n5^;ND znx{=2`4Ht2sfdN}y$b%hlqz;?p~qZoqpAsBfF}{56@)KvG(!dkXsyYaho^OH4uK-f z%V)=}o$qxfT%wJrlI0{0bxa1Sgr-2k+mqjE`x8?d)HRmJ87umP1s%w9lf^Jv+g)K2&JIR_y6Q0%HhP7V40KYDTqDx} zs-l=!M3st&RF{T@eZinlrm2(=gub(i`&W$HGEB~aNbcCol*6DZhLeykpdGv0j~Mz| zzG%F5U#e0CIl%Z!FOiX^_B#2drL3J;^T1>{^F-@At<5QHG0lVh2Z3LRXYqN4ZKsqJ zb1puyO*Rg6|VLyrUPy<;(p%dAPm@K~2&H4v+4B8*J;`?h9Dh`Ml@lT4JkB;1FP8Fdw=U2TC zj=FeTy>E;WHKZ)!N7)kC!5yW5D6x-{oIr>mmel)4&W+11>3i}6^_@PPheCgeeGeem z5uv_#1=B!k>iaU&Y~IiY8;k>|I(B6NIcz~();lfXwZ)B(l;1c#-eNZuqN<_U8l{w?oPdnWv<+)FiYwPY5gu= zM}}gPh0ti-FpQge|7d<#B=+HBsMznsdn6i^SHgFJHLf>`d8KLA*TsOKvNW2Y`(#c# zqPErAwp$5wyT|9WkXkgh<}tBg7oCcNEDnA;n5!#0BDLiz;4w7|q>C4MQf&WAcNg(t zX2D9a70u1r%t05b^N{Jq3v$f{`)5jm;|63l6X*DfaQ#~+S8GyciT&jA&0&50G)=;2 z206O1`1q#6&#pflI~f$O@4s|H`m}}(^&mp7Tv7v^x&ew9OYsU$x%wKmHLqB0gC1B^ z1v`)I2($aVHZ3D#-|f4AkS>{NbZB)0)LQd&6_%Tjo!t%DU>1e5w{qJp*k@)D9`83W z;hf1TbU9O&!InrjM>=8UI!U?vcA6V?J;T>opyax3)5%GqLeRETJzgrm%mZPb(=-~E zkc7=+@!p*eFj(51I0d#1OSKK>v#{L9GW`U-ZEa;S%g4gA5(f4gRc%c|DsZu}BIj+O zVT1xeHwG01f6j+KD6&_WOwlk3{-z6{aq*2;w-%E#5iV5hf88&VLTNhw=^TWD0RDEv z#D4*?g*^QGTE7W@nHCrgd33ru7X<&Hd3jqd(5%{1Nb8bYlVHoogz^Y?g1c>7XQ5wK z;Fu9iPLO-}i&$?1 z?G;*zd?f%0%2R6ZoI9Zw>HfQH$N!JU6nZ^Gg^vD)c%e@RW+Tfz>LrG64*eGQ$MLio z5|It$!dB>waUMvcFmjC&DP_)rg|BqieUeGg^G8*?8f@Y!zx9nC&SlK7ZGltK1+7ua zXp{w?@ih&pEvuY2OcUaFB#Y)vL2e2@L;ULw9QwYyc;x1l0$l#0!>Pw()E!Rb<2?sX zepB2IN});`oQUX&MQk~ILAY0Vq-Y88ac$d-fDOy&6d^3)RNt<(Off)&x zj9K|j>3i^2lIO+}&jYDZw zO*YVNwe8dMgtBcYH$z+SM_+SyZva_}-ryX=u7zpUR~jZo6FQ=5{D}wN-w-#x#t)t) zDb#ZZWAN$NivyPgugEg&-|Gl)ikcDJsTub72VG{_ws>u5 zQqKL=F{XqE9f+A!pEv0c0 zo@VjYVH{MCX3CFAe^(PC#r%?~mnZ+rN^si2$Mhg2_uYRmcM*hVg}IUN<%?Ri@x|M1 z3*Y5<0{?sf5&Yb9Csx4J5W@*iQVV=2dluVah?wjEy9*9)roO7-aZ#65C%6-%8G}f;SRkOLY-$n6ZRn3G zzE=b_z^=c)`{lRr0;#N~cEH0utZUs955!I2oZlT#MG4{s@wk>fkxr&NCdx|vkGqDRu>0*=!NxLRuN)8 z9Zy7>atO+)k;CP7-vGG7oaCLVKm6B$+&Z;SsKE^%;I9ZyGDoo>(1cEiXSE>#QNIylqE?NUI{CZ|9ZPD8GnJpF+D=|?8g)$1=kSU;C7IW zmRvfl`a8Sq=5L+3!Wp-ZDDC#+h-U9%uLhO$QD>P!sSpFNA=V_lHq(W&3HNt*y>N$o zM=tDyKvzk1<2IRh^xUv=7d5gV%&Lz5QTbQeD_WKo`tkh*c;fcVm`e>LH-s!E&aleJ zMqn~)U2A4R9^A=OSxTzPY#-{5CzWzJ*#eSVg@B+FzdY1ATY()Re3RVx zo|XNGpq)XPFc|0I(fePrFxN>n4FX*FXbXeLYvGQ>SWvl(oJL(I-z0{0XBfYo=Jzz; zBSDwxX~~jXs`M(MNzB?p*j(tk7-}h+m=xy{e(eW&7r#u?VHe`vw=C$(rsFR4UEC5* zu<_l5tw@O94pKVLwYOrV6CK1TS6RYC&VaX%-D$xp?D){M)r%9DXUJXFD`QeKn_;~% zZbV?D^qMZ({V&GusaKG2OTh59)!Vj>-nMPqwr$(CZQHhO+t&2Cm}DlIi>aiNsvl4n zm9@U-y?d-uAp#N2cSFD*pr_Idp+;&It2?G57l(F=Yn^ih(PK2G^*S2Ql`VWvrn^pa zfF$$_*PoBu_P{}d2VY4E7Jzv{yKyW!Pk1AsfGSz)OO*kplo!tH=JE94Kd;32I*K*<=@<^*h@YLP$3_DzDPc`*sd)FoMt;Fvo*%O$TVg0C(K6sV>N{HfIF15KWZwZ zL6ScCR3mKwr(l{Ez)#XPrq^O`$2QDSZV}!8)Ooh}VER@?*nB6OFqV*Cy^fapB;mNA zAc@XR#VZ5J%uI%#1+lF(P4s6HW^uncNF5EY7B{d@aPfQfTiZyU71rjsAVK$Xsmf>v zWw$7nu%<2z$2UKbSXV7HiSf2a1RrUgtNN$?JE*A3HvlM_J^MB3(ruVk>m zR$LfL^})&-cOu0KFN@8)1!W^HN*4=|S>4!gm~197smLtPO7Lk|{zGL&oz9cx)r4yG z-+4^C&Fmwb%1lUUG6zlT;(Zl637ZtL6H9O(k%LI(bh7yN_^{mbOCSu>iMu(3!fP+E0*f}0xz{-J6?H?e&ZqVlQ~gN(D8lTf2ujr zlg_>fl2k!{jdnlo?$QxO*{jo>)FEIHKue{+91g=!|5`|-n6hTDU_h-63DV)~g?#9+ z(^|0Ir(d|@s!r)C29MsQz|DVXbHVQlh;6XT<*aLqNR7j%mQ~PL6Dk+Yd9{;W)`LXT zk#M~>`RM)(>Ick2d(xshQJ(OpHrgoR79IJbez$?JhFov(ldy*?i=WIa+zo(?O{&`bJz! zn?dz0IP0T1`6#Tyxaq|R_c$dQ|9z?!4GD5;cB6q)CeNsP%kED4yC@-@avx)p7(M`? z7KlWev?^Yuj5Uh0t8GnBL7g~7j;Fe}+DZ4NIJZ)O{m>$?|M1*)!N7WOTwLAOPAqVr zUGm0c4J^$`H|+phhd<^OU~-dBVYXWAsKNz{p9G=}%JWv;^lI7B3ZIS9B_A@~FLoOL z@CTAw{GG<|@FwEGzYTE$BlP0Zs)bPDK``Jvp3XkZ#`G8WQcGnT;t=&;^QMOCRD|Ui zlUmrSRZZENvooERjJ+^I;RoK#x?0aWa1?F4YQp>9_V{eBWa;co3ZWBI!OwCzsh9w@ zde?nC*V$-R<@qd_RU+^C-Yn6RdVByNJ;FA5OzjwWXhP$k4*kYO)1S&NfoC3j#J@Aa ztM%3DcCNW?+Y#rB1p!N0NlvI!p5re6GE5kU-ZZ}6>EFU~dAHT(`Ftrs>ctKoy1laH z!~J1-u(UjBGK%jx{?GcuZX1G*-z`B_V&rSI=6icPX8*cSMIM}n z)+ruc(>a>o^5SVK+oeq{6siTYDR`l^_B@`PT0Nl~5gtbv-D~L|6i!Ihxa{-eVVu%{+1n zz6(|h7%5H4SUdBbOHwe=ozrsOd>R8B6^LQ`TP-bxg# zyaLM3__EfwV)P%JbIwMc!`lcv06i+PB(cZHgPp}U}%ujM@&{<>`7t`QMr;`-z zL#_D^dV}-0r%JY>9r-^ozh{j2Ze*8I!-5ulEk~dWv-Ukv3ywCOxJ!Yfr%d+b4=6JP z@#!WQ(m1MzvSY$r9w_gB4c$r`7p#VQ^qeVfVh{1^3v?xI=89$p%}iK)l=0@F*-=%0 z!%`mhEomI zED7J=i9~FXGw>xKEy$jVegyQx`JY1+g zyAIg98JsB}Pa^pJmg??mDIrVVpnkg2MA_maBgBVU5SW6?mqyZCgx!pdx_v%xlFopE z(NnRuicE&`|bGvlelSjRu zM>T{+pN2PvIf*%h3eE3xr&a1H)8SecWW#kMaiTYY2hgT@Qwf(W#Ik>*xDKfjb1^S3 z$9%f&8r{hDGofpxuwKIUEVlrKGw}<+RsfIqc)~t##~?-vL9ohN6^g;A42? zd7v95a(lo?c0u${+)|%4#LZ2KtVs*MV3?QyvD%pM)=V0yiC%*i*4H2vvli?BO@=6k zKx|p%v)&CZ28W;!)ukP6izbyU*R!79tnH0_+xecx=U;tecL#=p*ZJSwCm7X257A_0 zZdzdI|8-sBdE6xHAC+7cO`y7>2MdPs2wjv_$#=)fAu$=7|93{@LWBw zCaxaCl)c>tf{ctF1zJ6Y?MLn|i0-4NwWt}lK^&hv@G@D;+_GhJ^K||Rz0;vBa-ih` zsSIfSlG**#sH&14UHgoeuAeuLP#MI)l;-5srG)E z+P+|A_Aj*?u9L#ePQUtDu(Nd_bbd_+aP4B3-|KD_m0@nd`O8axFR>%#1Dtu=X#G!w zmCG!+Z*z#82cNxhOOYp4%=n^#!iEM_nf`B=(UTn7!BBX)+UO!-tZ@Ps@80$CDS3?=gwzVX_#8vfl2^+GC{WYYZoXgS* z13aUz<*j`2L7}f(LgF7>4~9b4u5XWne4q2L9t5^Qta;Q~x-Qo#CO(e)F+E!K&xx_x z8H~X4sB>ZKRZoBEE)N9wLpzIBtGl8l8=@pFtMY_l2hVMp#l(z&S&u-K&*1QbMCj8I zz=48rm+F$h#^$Ikx$R)syidq640}Zalt^Qg1OkoIGT62X!z6_j$m2;tzRuZH5a=YKpt%HVKJZQV~joj?1r3c%CBqpXV&cy7la!x}=NSPDfJ9TbPcvpk?!wksfcw{lctpDR;a@{L9e#4gL+$#Bm( z8{^ad(%IQhgmAOmL?vq-+jsXHSG*gj7aubF=q>v9lCQ(fWh$d5+c_0O93_LIaas~Q zWrE~$pI&Pi$IoYR{$C0cPPX;cIl#C^ZV#|z30j1F=Oe}X?ErOAhgBn0gkKTl2DOu% za58o`hucKUFhe(#yw$7ERPN6^@E>F65`x8fJ4d$;-E+SQr(bSeAz50 z)+!kWsoe$p+O^${0Bl4W-V4{NbOm8>fr4f&8Pah0=2gr&q5>Mx4eRlgAtt4F$Cyek zV_h(&h8BRDGCV=2q5AkyuLwA9YRFL4%zeBEZSZR!@m5+cgXXGt_1w!WF( zX9xw&3h4pNZmy-;d^uMqA$^-E9MpZ6C&gzL*vD?O|( zGK$>&Q>00(QbszD`qy|;Ad5wFd-;vX^pk-~F9GTitmJzFtQ=^>QZD=p9cfd#X73;0 z3&g)W6wfGJw(@QR{%qPTh!^(l&(*~HduqW-vx*|6N`hzUL=qlLkzB`;NDXscp`ZB3 zcGa4H&gCU-#N=#{0((ewKTJ*f>OUK)T9Y(Ck6z+{q4029i8PDR5_K{w56l^XkZhzS zAp#nd#~L=j)t*2SU(!R5#~D>NE2KA+G!@qJ;EVrd9oj;_*{#3ZORU`L{7FxOU~~}c z{;UbnSzP3LB3do!Cd~Ifd=NkEBu60UIg|6`L;ub(Zh~nx0{acY`xZ^ zY1RL_Ba1H_6t}cQDht5!*lI?cGGZ>0tF01(9ql2E=>H%a( zr7(JZ<3;E|F=x(VM#qRiNUfOWfX+YHjFygbC|`co0aFFf)n@}7JU53bg`q%-cW zJ!md6BPZ)kAKk;ZN5=427^i1`-i&~Ige5Q@T#uw#mc6LkLM8jC5lWFP|YOMol#ZGzGQ}IoelA8-~IRPUPtKb}Ke*A#Et9psa4aoZ1X`$&nET z9*TwgH%1%xjzKq*BrQ|WA*r_?JSk@{ilmK?1{eE#iF$i8KLnGg()h5u!p%Zx%#6+F z0tbQdNHOurxR<)q!P$rPlGiRVYgRgvt@`^|6Egs~&9Zj>pKHuj zOFL!3S?vx61~Pk#$I^*WlRZ*fH0580h{sZ8-mku>98HO?0e!d3$J&kBMM1>$Jbci^9n>9I{HU5M8gp z!(sCsvP0et>g1_Z*h9)e)V+XWsV-zyrP)+!NJoxJfO3}eX zCB^S$k|Dj0`_~09X_T{m7dtGDp~YfQhijXg!UQkq$jLiy%{FLxjd~F?N16DchU!xD zMBgjKp}Q+!a4P#jvf7njdWzXAXfiEfXagg?9NCj0_XS>8|{iuh6-*0+916Mxko^TS2?&f zR$>$GtU7nu;vePxMB|643Pw{r?lVAbY=e)3nx?M4v9#f%A9`EJ*PgIFjmJ#xQ0Kc4(I4-b;$)t(mnV?8IPmcQ?#>qz5&`SVnfV${-K6J}~l z0c?BJX*2f20J{TSPm`2;B`^k{3|0ru+>zZXc$Y9y@jXxpZHzc+KKb0W4~H2JJ8uV& z!6Hw!%io9DEK&Xt>){lHrrUA{h~`>@G7Sd3$C^?qd2Op?dINRzI%-9`v`MDSLtffy zu4gtd%fC9StgH+xHkHr`D`%V)vXoQ+2EHg2+9Bak#vQW5KLbl=#sIg@pka0{l+{8C zk7Oy2$H<<04y?kT4o!X_t-99q#Znp^u5tt)##LIo@Q0*lR+MeZ&2|--CDyTE19BD0 zHZ36!bl1@-Nk}UyyD9cH;$mkdY)NG(Tsx|NNh$tOS|P#tXHo2T5ta7be}s>iWkdGC zMelU0NMtIM@I+XH%5(vnOe^9($=)c(OF3y;oIHAU*>-j z<+H5qwk~83Tpi#S=um%FNZ@mTg^o?L#lW#q1*Go~j09@UH$t;*00d{_)AF?s z71Izr88CbalHtCNnubf`_R0Y=r(Q*wiAS6=H;6h8`m#IH-IZVx`30j<(_xTNzf;8K z6VwP1^*=dti}%sRzbz6g39&u;vw{2<{`?jf@v5eYR2_42-x*Dl%DrkmBYI8)a|&3C z`6&j*uwbxs!m4S7511jIQRI1aIIA$2q#3i4v3Jhwv?-@-azTZR6x>UP$7i%AGWe}d zwDKY6Ic~=CBz{Wg8C(tgyGHSD6RkT`C;OWvl48l3Bz0mP#Qrf%oA|hwfA^Fwu-tZ7 z+C^^UEuqYXCteFH*V$vx7j_1dB6LtQU(<@CT|}fT?nFiLqBexJGg~G#F_>~4)J{v6 zhyAmEioX+&Nnpl`vb+Bi#wJau_zitp0b#H$iT1n}c7Uza#&2nRq=vwUB%)p>Cj zr05VWTZau^)^U!~?-;r*WP6i+V8_bp3lP?8ZMqCq_;bB8BF=sz^94QeSp1EDkQ1ShgMidK9ccURvX>BKJ}(V{vg(&R ziL~p&yU!acZatdx;!~6#Ns4^}|5UhgU$uT?HnrQAATJNdGXDtx!-Kb&S6%S z?&bmWB0(MID5rNJ?s>zBaFt1m&GaWp*FkpgZbU7}&Y_m4t&ysM-2SwbPgc|I#z(}{ z2S>+Jo(sd2gC+#^6sjaO-$wsjUmbfOmU$t~864nBWaX@LoQ4HkeAW z<^~20UeR*=Fb)rZ|B0e|9_i)6aCn8>qkmtf_BgSlaI7Tua^psQp93j!O~tON8rXhAa!i>9 zJ5daBYI5xeH6P1uyxgxh_t@vFooGkq`USyd;Y2ivls?N-?3t;dH&)Nwm2e`0*fFd( z8cV5ZJLrR~lNKrRPG#d&kLoW=|(ID zH_7_o!P6IwW&Xoi^^azPMb?!=@s%lv%>a;V($L`(Lcgfg;kK$Skf|`p)j%o5YbONe zDOtj6oQcdND=H~>iI#Hy-ns)CCRw<`CKnYe&-{yMRSQJY+MYl)X48 z@tZEago7MGI}Ya6x7@sRg(P8N5=*}G(x|y#VGw7l1}Ex9x~{%m@}=ydD{r@NMR*V* zwtRU0N|pYhD0qffcw4{WK*4+>)XFHli1Y**@?>Lb=pMQTz8v&N75cXBgC@*rm_}X9 zVM*CKY9f6)4^kZS2%TBgg+2+XhVL{s>h0V8<+ykyRsF#IDcQQE5S&^;yz`fUC$cC{ZXWu1m$jBtxbej5*ct^T$ltn?MS47}1daH2 z@6iiRX-k7daeJk{AdX*qr}SST<&fed5l{#7+*h`sH{#|--?emj%rj9zq++g%k1Ji; z`b3)rzLOx9;2u`$>EY|@SebJ>Ny&gI&#%praCNb!#rU<=n(Tz{P=!s^5e&g6oFIaI zCjAxn#GFBfSEdD%rJrl{|lp}6jTyEb71pWGtVc&&My66=*o zNRtEA;nBziFlF>6I2DKj7lz+%}nDD%eo;y(UML-QAtD74q zOfZ-wP^7c3Eh)(#&85^aQ%_<7#4)ePrkt8B-JRvxv=8PRjG+67)(z?C8A~GNiMf*@ zuqcSwJU{42rP>`861L$7l$E7W%z4mrhB?~E*VY=p=-bO;>;{MOcz`6;XIUe|55pt^ z;^@{p#rv*Ak20q1NDbtpPs5W`kpIAdSSgbLUGystVKHC1QhluneDp9O{% zYVLLhUywF4QZ z$o{`)6_P8+ESLUu;{l!7mX~C{p};etqVN5Vj!Q@+?cN@ZW5egMk}Xk!i!}72uD*`c zq#b`wDim)T@Yb&S>@UK5?7cP&3YSq&0iPc12VB56G(rV$-Hka zbWWY;%O4ZJFDb!@4T5rZ4*BK*&}80bm;1pcA)FAsNVng@q4>);R7d&1bGn|ugRvN=`XGIECmtFo zj2Qzemf4~L4I&DcL2TzENc<|>YB?Kd&a~Otf7HFF!29SKuo%BCCus`DgC-KNQXyTwH4;rel)Nix4 z>3t30<9isB`VT|3Lg2Dj3Duhw5wjWRRsEuiGRO30;fpgz_)J;Lz0JIe4;Tm$Q+djh zifWko;P_$udhUzZPQJ-^|64C~sRfU0?<-xe{4=&7!&yHTq@ZPviL2=}<#?Rq7nSnM zbu1+<3_-dtk8v`bn335pmKlf~?#}huEMzexbgROQfM&##LGrm%pq@YLAy)i1A1T0u zv4j=7Y1!k?gj_}K(i#1!r4&D53l>o% z>mam@Hr9#}J^2J*1wt*(7_pQr50EP`OW3BBK78HCC@~6SPtIZ2lWN>Qe+g!S$ept? zec?(I@<;F)DOIwi;ot%!PFbi=Z}iIQkUmL;xkrd776g?{k-6PU(u-tHCaq|+MeuEz zWQ{qHT^2(7o9-ZVH5Tg*CL^N}4ey^6)}gbWWp@7DJJPT>bp2`sZ0^Fp({RYIBJOCS zxnSkqsgGj~+~Yj=A;Da&0+7^Q&&)Ows_X%$nDS8?tbeY|`lPW`N4{}$`;g`lUL!3q zcBTa;?WMFtpHQ*;`y_$YZ*hDHF;gb?HTBlrp6(lQXF7k*D955{gWO*gw+WcdDu;oNb5sW$ixi9mb1bqRCzTx0 z6$I3J_|$Z{Ho;7jLnje!3>cnym?HO_XLAsMpA5c(m_BhoNTU88t9I;=Tk#eOC>dKO?R6=n>6ZhQ!26^Vunw6!a}(63R`AY99Utz{O}yn} zKG^Pl2-vH)_htSVT`Qxwl3CqE_&7+%#iPb~3P3EdWVE~s;C8QkUus7??iv_zaDF9Z zt!pI;UyNqPtq(tBG6vRtsVpnJQ73d|U@J!;o%?IQVlovYNEL&=rdpzJB(evO#en8f z>N{VXhKwt~UFFI;fpM{}*ac}?)~xS@)l(oyj-(MRRHV&_1w-7?C?oyUgWigrB&mys z=k`;FUAP=wB!y`7hg_f8MF?+oaM17XJJ>f`w#6$XV-K4xKQeCZ=eO6*3!&vk^A^Uu znKgT!zO}KoKB!;~ACyk36&&c z93^hrP_i-SoKZP{vrQEj$cy|N-S#r0*HY}U3bfB2=}1#xlo5NzPT#dBf{QYmvD_fo zK~kvTy6i;JS7Q<>JypFTzJNpKq8j1V zGcf5!RK80t9s8Cysw^-X9wuidibra=di@1%^{L<8*+0Hc78uD}PFa*XtbFe=bu?P6 z956TW{nT^RyRN$`x4OI!t3y7VS$3Xya*X}Vlpbhi{TQ3jVoe61UWTU?rEFBvJkahe z2g`0AY0$o>%J)Man{{K>79T81E*Mf!vCvZ#9Xm;wmb9QEK^}2YJ5i;Hn`zdJdaf${ zA#?=tw2#8Z4PQNsmHZt}WP=y$p^L%g_yN5*e@FB*JhKVUPvG(FxdIJN;>vINk`zVK1;rdcM z_DQiE4L%iPVXK;NB8d81>qLtB=@uO^RNne&ScMcv4%3%HZl2i@0^8e(;$q&mNM*J{ zCx+V5>{6hV8b-NYdj|)6y4pgqx+9y{>RjHDw@^n9XBm4(QIb&KT@J+A4NPneq@{|GN;6W_*Y8qXCco$2&}v2*Z`>X(3vt7gUo#qBzofFw3K!3;7ZbiA61_aD z@fCA^s~%O)-pM4t4~(ifWBS}~W(aE7f3zyMMuCl&tYvZzG*r^Tm#R z1h|&PsGY(dbPFc_kCb9}C>%6!T6`n|$b(lT6smV91V)_?*-HBn#x=l2SQsIQn6_x2 zcNn_)H}$Lj&qkBzPb2E_Gp23_4qgfblF-657>}uCen)rC_~3csoGA-rP5(d?!@IEv zrd-<`ak(h3`FxD^0GckeNpZHE%bME_Tt3|j5o6-fyhU-1*FPDkQ(k(qmYk>p(+!fP zH&WJNb)BQNUX@wN21gkx`x?zSx0j@;&qPK>zfXOB949dD0|1fBo^YumKFaY*nQly= zB81bcMuc-*K(~0idz!;3!JNz1S12|9gG_hr8=~*hzdM!?iuCN1y{ea$hBdP^PD@sQ zzbO_d`A1FL*#P|>L4mBqG_I}^P0u_Pn=&9&7h@@(*>FVlbzjOmuoiikTBs`J2hgU(S*M|J{ z_%lrUN%EDyy^;ss;NVtAL=xh*ExVV8C}Y#g%}QLWr#I@dwVW{G^8eLHru&;6qBFv9#y#AOduGFF|Q^h^S(IoM$*xu)Bx6@8%b27=+^! z-b$#bB<9I{>GH064iS&)l1lEfk1Zyt*N}X#dw;b8LumE=TaB`GRw6hEOk1!c^Nm!$ zn*BMc97@Vrf}Jq5lTB_rHQ#fG8}=#7D=u4A0w_(mXhZRP!7A`ePCurrBfIDR@gB*TI49qIqboOU1)`No0(-%tCYo7d+Y`_H`tSKfhW2zAk)u|ydY(78 zXC4`iq+{ECJnM-n65N>?PAzSCM%6pL5r_caR{Db4+e_$F3wbLx;G!VC2`B`HAh8^D zoo_1^OK&uRxT|d-!5Axi7t1vb;j@7y$OeZ`Gj;o^W~}RB)4!0q6Ozw&A(J1=W-cq$ zi1CnXYuragW%KOL`5f}g3&`maVc%JQVzFwq&e`3g6fLzTfVme5z~M#-6)(x0EM$wk zZmV4F>%9BL+o*+m^H^w3dTCbx-Z@HyD_Ibfrj;ZuHmbpOb13-Tu-}RW_N9tZ@hDO; zH5F!6(ZcOPrdZ(`O%k=x9#S}vc^Xw1;RzB;(MPq#WY7LX4b&;Pz^YyjiNM;RH8NqG z)&W7f{NaYtzyG~_@IX}um84|ioKi-blqR;@2jKZ>)`vWbd<@uVca-7kjL}}|RuRBPVKeOIRK@h)qloufTVYNL*qm$DUEZSp z@D%a26+vN7jl&pJ-x?pj)&pcn{<$3M(mQl&GQqsuqPvdFuTHx#g-C_@$wDn9*hBF@ zueE}b3vT}Itk?rFXMd4Aq_92x2`u2k(g4f(5{rT!$$&N1C-0&K%imi#Wk~+Y!?_Vf zf?(iUw|uG@^?_5j6CtyJ6O>2U z4M{9?=JD+6qti9cd@4x7DR6snDYl@jUaggpBGQnOA=3>35T-*I#BRyF!1wqPGZ+Ra zKZ#IA;0lq$dl!(itEqCYife4ryLB?n0IF50viZrK3c-G%@)TOt`&l_?-5=hpAN;v) z`U4tav(*c9T&CU%HY@awCg~?r>@mFv-B9B#>pTw384B%X4dC6$EN==l5z{IL*I+ZvgnMwK>d1Q&bhgu*>pS7XDD7*wM8 zrdjRi+8Gq0t+PwMG!kB%BPuQ;LcCbl;djq1eb7W;|99z($d|8q*RU6;<~FtM zK(GJk8Ckx<;WhvCn*V{s@(7R=2S>(ct{zcPl6;u~fAsgAf$ zT(`fm_uhuF^)DSIweGX-bPfh2${zZPo`!ir-PzFGOu$I+d`ddf(dm$VLqik)ZXi*a z8k2Ja;ICNhm@lTe@%4qBm{UB|0vSG{RQU9?_{q@xu5KK@k!7&HDJZ>@J^hm-eFLC6 zdItM{Zp}_OIKIh|i8)l9DZtp;CSdmdnD8|YS2p!DjTXh>z$;nC4=Ozxm z6|_^sUxo(YF|2kq0Bc^x4D@vXrE6(wf7+a1q=1Oof#G5Q(D?c7?d<-smGu6daV@_L zxILS513)=I4&dx9zY@P*a$w{rEC1h;5dcv*xyCxDpHzY6ovGpNF-V9vgf+Dcfa@$? zEv;)Qe;L2nD*$D4cE1APxf|UPhhN4#;IB@0028p2-;mGNS6zSV>mL^uMuz%UXZnW6 zrY0uvH1!Ptzz9SK7+PFfCjcVO#a@_btE_9@ujs8PYU`*dUYH-+Z3ujVDj50?y*FE* z8B&=PINBMQnG_aZd!sL^DbdW~YboJtYioZO+8I0FWipdSQbL70G#&o@%<`&Yd9cveQm|{oA&EH6!kzkFt7pD z^jq?!TO1bF4c?cT1Isr%Faf1!dJJM`=Lq2S%Nmgof81O77FybrozCs|sXOfBbj}Of z`Rxf*_S22K^fEB~WA`t_?qyl-Ln z*qU>p3--(FL8K{(HS4SCHC0_XISMzn>1!3R{mZ-z@MCFz>|c^n)AFlIb#3re4?W;= z!t!ffRNNR;3_hnczA!v=aJ&ANs`g#W-B{lQOu5df`QzLOaF(8)_7i(!*e+GYYXg58 z8~>#V`n8t*J56q5YGC`ZnowWo2oRN(6~(om#zPt&oQ<#Y3QgbW8t{23#=Zs^HQ*cm6U+t>Mfe|{M*a!@0E|B37tNj#5S`=)9~Gc*32z8W zFX<UY(@5l>pLM*J| zmsx9c{55ZZ7d^u#((&NH)WS8M{;$GjC&%~T{@~CT-d$kzurI+TxF)nLIP@Ox%P@5??tQw&QBR{0K1o$;FXo1 ziSNh2$d_&T;%`&rb)i2To}}$>EUK@U00z!4AaC1GA<`7yP}c9#N50cf8|p9CZJ~=P z7LjSBFPm4TIa7nHQo;HuOHq& zc~I$b{{qzML-p!cT>(k8G*+kW%RAP`>dyCWH&+;c4%iH+wZ+PI0Ly9_{p-122YojC z$1cRz|4WW2J7dRlx_t8)5|SghgO<~5^IV6`*lTZbq=#)edyZqi^3`3G$w|#L!C|#= zHj+PJ;!7WG>jL{^%<8_~Zjm04nx{KsE`GMMaQ2kX@(ylJ2jjs@RF#&vSfEMtl|VeU zWPjpTF@G|2Lev?%;f^kO_snpq&>46VbsRd%F{MsCPwNa)&rGhCI}Yvk22JkKWH;Oh z(QMy~&OlAFtJzh}z?aV5TBWj{?R7tH-^>unZ#Q3NTG1^st7t;6+ATFz#P+fFh*6%& z&q@{+>0RmtQTO3&OuW#5VV$koUQ#Ch-G!L}%mR+E&jhamlVk2LM;1}F-eN|3r=%Dv zWlJjDIbL*dKTi2i|oJ|CV|7?s$$a%glwF^jX?<|G>4rRa3ZCM0W`L zN5Q1v{w}Wl^Efr}ZuFIj=y|_L9njIoJY0jHd_{V!kxn zG+|1hdOb=7Oh-@f|wI+gUVb z_L+ayZL+#QMH)o_L{I@tITQ@g#lhsD_#wt4_8`B65R-fr`EfM&3weB*73^`XLqMN9 zp`@#d*N*QO3(Pn8)OmcJRaicsYHNR*+^UCptJprrXK8|W7U^H-M&!!u`A!GPmeKi7 zum|mzSx<;%uy7AJ(-O6ZOaptGtx=%}X3)U&7!F}jnI+CDAxaibi;ljq$(@H_LRMx; zePX~0^;ukf*-Xx<^bDz|XDv;yQ7SeTt52UkY>u2+W}|#1aOOwq679dK=q0v@#3CCU zs~+~FxU~j`a(8DcLXB%ZAuZNHzKM6TF$hkM?Jt6u``BbP=%_gxb{o6n$y_b~=B?WE z3=XL&&+o2Ep4zvjz5=>d^Y_wcA40_9<02M132n;l5y!hPq@Tr5(uBuJUVNC?V_R2; z7&#YRk0jsl<&p3klx%tt7Srv*OW^N|d9OoV%yE&w-ZwanCA_4`5z7i*yM#Q3^5$() zM%4Bm52@)sOon7)HqcFex7ptJkn-cerx~JgrK8q-8K90q)A) ze38&&VACvs6W}%7J^1i!f?z18bjns!ELCtyrDCisZQU48II{BLpyy4d`7*hX?MMoy z{qw7k+45g#Fp5N~;J4V!vP1{t)n<1ciu$^##_zt1+JJyKG9K*u>_!FfECBeWX=FMk zWGI2m9OpE`7PzzDm|pbhcM+T)ecXBJx%YgGk@(bQ&JcQ{g@)nfi-))Dope#+Yj-$x zwP)P&-$2U2L~X?E{cmxkf@wIX2Jt=g*=Z)V*DeW|rD9K7$bK5ePW1a^(0$NTdsp5O z)7gbwGc`>*Ob2Dmxy-xH#ZoDqX947-DtPxXcY>AW>OALg6TToJug^H7*H|{{sB>Xf z95-!$ygJM#AmBy-tbNZ#nU=C6IyTn>x#ppTT-~y){0)ER&n#oH@u3~~lRb`UqBu{f zdu8>=A^7;mtka){-;V-6n6OYlnzep6JusFZIUH*>bGXV*CM)Wcx$aHFbakuN-)BY0 z8=9bKsUcUle1l~^^pXuvgF3=jged^KUr6vVTMT4iNqVlv`KSy8! zmAaR)+6sFqEx%KnGeGB=vA*SC52Z=!51m~)GArvOTS3CA(hZ~JAEtUtK_jtr)ka!tTLpE2xwgmlEWrqjaQ&8v=Xy~%R1)-Rm~IPK zsQ~@_Ym2TmD#SHK96hXyzQyd8E68|t{-IYdA#_w#ZLHaq-#)E3HLZKbXD#DhLEdu! z>NO~mfX7rop+Vdki+|=!v~7mcwx`rf&;Fc?YZY7rly3zr2;XR_%9k^lrXMrIMZ3I) zS?&=?tLypOQ$)_D3F6DR*?j_4U-R*n8g&Cdvo2=vJtTceWh=tA^`QDvxH zqr6?L5f)@a1E%$(awuIY8y~VFCU6Jfi{mJ0FiQBz!uLl?*Wg{cj00V@?@A#-wf|lv zR;x@;u@6ZNaRnMa-wN6GdRx(dg!4Vg#NiGHWZeQCKINXRbly3}(L}3JQfh z6s{X{ngq+KIY=PzUs{vE-!bYm2u ze6gvR*Auo*ZI&?Y9<>uh5HQfb$Xq~1qybc*{LoqAdg|vAu|btg$z6(Ns;u>c*P#4f zhE$%;_SB{kwh_8@&#XVD*XEQ;Xo_bR_GqmUw-qek+{X!NpMCHaLH4GUe@5j)xHtIh ziR=%SZUE~2$+$y>_j35SIcZ4IPKVkFjfLBy=~NkAQ7>sxeu;Z0P|{PKT<55!4F|n4 zpXaWEj*J3FasPRO_y|a&Ljut4Yqao#iRp-rN}Cr;kL1jWjkV7CgNp<~-+J_wKzdz} z?W#M1`3ztFDH9U(!XNyv0UE@f%9AVseZL@DL_fBTt4_`Ey}*dBUSWtn4R?mL2n%d>PoVrHho zn{~lyQuC<3?k4KSg1stzi}E#La#0Jx2S+E6nEX+;;}-PN;fHj{&H4^0q7B_?5c=M< z?aHc#v_a`=`K9CMgu;bNR#g@KQShlO(cI|71}!RpS+VnD&D0hOcuTHyQ++ zVK|}M-|7KT(CDpICYP6jE1X02Ean9So0=&Ey}^=TPf#jj*X@&30;SJ)r9@(s7{CeT zn&!8Nh84vd%m?P>h0<#@4d+T#VXxMCO&{=sW2+UQgs| zkHrpq%huIcv&?*Ezcxw78I%Xf+{J=2D!fHS-{)IC)rl=L@1FFj1B;$B!yDgVMv~-s z!x3bmL|a@WAtHO_KU)c`KF7)RrP#7lI!}ZP_g#CzqL#LC zb2v1cWA+}u5cKk1%H)3921rKw*J{<4c$IJieEpSw{vVtn{~vRj4M>E~FrWr|2=B(Aei%b9C>C2np3T!lz0`tzML0j9fk}ER=uY__C9ef^pHg zpt28HRB>pyvLM`6BA{5MJ|dOd6@yc!k7GpPZp9>oiRRfsMKkU^yPC{LYYA$hGx>(_ zj2l}bW$Lq0KEDOx7CaD(^Xukx7UPnjjeksQn#$5Jpw)dCQx`$&_(ZrULLdl+mk?Bu$KXFW&{VIu> z_GwmE>Hn7dxlQtY7!a(J2YVD_`g-sX0c$L?Xk}BeBH0T`$9Vy>m(NG-GeQd+3LMWC zD8)YqQPK96=UR4v?N(Jqq@_Z%@#|Sg!Rix@R2e3WzZ+Y zFH}TGqU4+fJpX-?z3bxCZ0-bf^u2D^Xi5ZHDGX2~s9IKUOD!QK%-JvFO||@;9Jh15 zxsWw5&)vKch#_QTM%`jV_9K;Ua6hlQ&w|tevCoWlZfjEn%-r`JwZ1x;3wvoQ^|4Y( z2D`!@+5#wXH||~NHC>NS2AMStAAj}LC7wuS8<%j8_2_4Q12l#|0YB@EpU}I zqcbQ((-V8zqx0|CV*hMX%FkC&y(<+d=Fvnd`xkP>#WDRzi##WIgEW5rVogge{2 zwPMf#i;JCaiJjFlTCnDxfS>bdx~=zd-afH%>sE(w7p8=*22k8+CFh7cvrzR+7KCL- z^v>&CkjUQFB8cJQl4m$q=~!1C6eMI#rz8N=ak=&$1HDG>!Yor za+drJEIcFY=YlU)ruYTe?5!2WsriFjOJ0l6I7yN;{$|4DBG}9(H`MYvW2>JMCo($; z{GI$@yq0b=#jDkdPym0PtDiSc+%6)2#Iz!UL;$*rYIjA&yXk~K1_TnPJqQXKPQVz# zT`|47bTZ-jB|tWSJ14ST-inW#B;z7up0~i{1nTh%`UiUwc*6NuZXSZ3t~%Z!D1D?3 zZMzrjrHZO=MWk!SPV@H5XLjY4BftKFv~j|c?yzSkkPJV zrnppa@{Z(EX|MbQme-ebUaGl~45U&PiJhR`uhgv1`EF_m**Q|iWqd0jj@gDFU~?aF z&Zv#1Gpu`XvJJEvN{-p`Sry6Wm$E+JnjWsL+b1<D-(1qETS%0;t# zGvRYZgHMNnlS{{an9@67hI{i~nwK)1-L%7V7snjdzY{F1ez##1Gc8^YkU9o`i5s+< zPk9Z~Q^y#A2xj3%&Uh#eEx_$lbP_)*Y7b3pg>0YEm)LP?#Ca}D5w(^V=otUwj5F|| zrun0%VqRQEe@aGeo-VzIG(Lz(mi{5EGlk|CID~U1g#}wR>>FG(%mv2-!V=iPZG*?H zdo`p?8U!?@tq06lSZH{TMP<)jO>~-dSOc<$wqlI-c|&AjKxZ#YciV5m5BV3MpQrwE zn!Wi)!GXW#R(cXJa5Q~2?fKH7t4IEG_44~{?byrUNXNo9=-|?`I!x>kDkcn0!E|Dr z*}I&EChg!&E(a~#ueF7D`c3FdWbl3yiW57!*?oh*H7`ltlc6MK8w zOcH-{wiy9P9fbO}U64ToPxPw=0Tu_lsOpjdUz62e zov26D0eQE=r|w(c`cvEDFUTgkcqAYBu^$48L%B`q4hh7xz=)({BDrj?>+Ne%G@n5pn@(;@d?3KpOqS*vH%5nwV244CVAz~snekO^Z;I1l^ej*`)Ht1Z10%^&Wd+GkttE4NZTwH5G|tP z;!Q-T&hsk3zy|Y~S#rQ>F-Hwt!DeaST!nC|!Ppz-N_ZE(oWwx}XyOd(7vIem4O^w6 z*2g`W<6J_a#LMli;n{En){Z$S$Q2}p2adN(ikxqe3;koLPTF_P_SnS{y;M9bNQg>Z z)35|YL3m4rY+8vWIYAa3te#Wz7}=est|))U$_uoiQiJMXf1fP-UaL#w5;P}H5x_*1 zLY4Bxy_rKc=rhc9l*3@D513VZCYyZ?JVC4a0@&*J4c z@uK;R{3gJY`|0AQ*4eIcaR`w*LYq>G&~sUXgMT69;lm{#h!3WUz(@S#ICp!@{=%Hg zJ?8QJvV7VL-Z_#Sw!L`%Fi_Tc&L;Y%^SQ<yc*kb<^)PCEoqQ&5O(;?1y`83X^xy-fc&oE3K2JJE z9%K(@67zW}5u`T7i!Z7zf`O+~S0HgsEQ)A8(jR{6y2@Up!IGajh$;2@hhb7MwIab! z@ikXd{#ji;K5|y0D;(cFJ1Rk@;`=2syqS%qjX?@~o8CPa+d2^#kubLGrV38yslUJu z$t*_c);v^$Q=mg&yhW!=5GXFlW2Jid9U;{6@lciN>fi?<#LUiT!ghlKY$IUB6oX!eb_JytP7zv-zAUO8_}-Kq%I^c(W0;5Tc77K?hR^ zl(yjqg_di#N|s5q`u4deO&gxoUM`&dWNFwMVQJPs%7uaJ=mGddfhQhbF%cPpLeFSe z`NA78oegxw7Lm=>+mZNyuscdEcK^2+sUs>GDb3$M`l3fzM1DPCLRwq1=$r>(Wdg$z zF=}5b1+UIZd!du&L+Ad?Or`rx4zp$wUKg)dYPZLc{Z9d{W8{~~z<`3sfiCvhKsOI- zp%uo3Pgf!Mo2eIe8~;#e`B1IL#TfS8OSLw56Ll{BIDl~Tw8l-&AqP9~GNy7(s@=`! zRt@I|d|$bJm>7+Xv!SA!C+WOaL9)D}*eo~1KP+J8CNy?gJEF+lWRV)#6sA@Fg)^QK zlMhlsqIH5==y>duMj-)kD1LWzCWe(ng6At*K~%&qy?uRUK?iJ+j$0Jz-=Uv%zZGi} z8{+4CCS0ZI-k05-`C(A>Z}jpue1y=$NPQR*2(CUzONf0#|H#^O#K!HEiEjvu!SJu? zk=v_2bP|_B6UBhM6d6gBIzk!>0&|ix^Ns{YX>X~7Ll9&(3ytWx3G;fr;i+EFU4_({ z)=LmC-z%bCHy|}l|7i^M6a%N4tQQ8fVt7b!=-~6~bxzHt7P=@Y9W&En2F2%u{>ofl zLVY(w^%{qdZDV@G@NMe|Dr@vXjbrd}MOCsNT_6B2z$R_Sy=Q~H(d~xM>y)e2AW;p) zZ#LhuUNbhC1D>{tHm5n9kIgDwg?Sb<>IjF;|^q%0wI+%7)IEVDEZyGb!Oqvs{&L2xtzm@rQD@_KJ zEF3?tP@O96x!n~_Mx#}#1s-OD_)paaOK!(r9+myFSVLWlZbA$MTGGIT$mgDM?)k<_*Uc?65T&n^`EhZ~VA@oIp*U(9fTUB}umT zd`o?2Gv#Ke2f-GfOM~h^{zHiOgzSY18?Q0kX`26j;@3%q1r)Uz{~~?!1K|DD8N2qQ zkL2zJO8-N2%2len$}p^1GuidF$wzyg1vtEv;Oai(CWR#Z8Iq)^l1^icl)nxpHF^`= zpurSFo*31Fc%Bcu+srd|=+~FN+1l>X zZvZnx`~Fp{g0`LiL>C!ufeRvpA04J)b0Rc6JD^HKXh8){?TYOlJxz8Viqk&bDgBjQp{)NSISl|Yh9^286I48;9!WMgHp^(DjeW@>R{|*3jp|tjNzk&2kdRQTvyW4$5ng0hr;%-A7b@1AVW)4d$F0N*8w{)N5XJTIhH$EPM_W{uE;FrT|5Z z!RHhA@uNLPZbGW!UoZ`PYq)pXSL`~ijo?@4LZJ&IlquiySQ)Up7o&ZgT^Q)8h0=g< zvO`A9v4zH|mHZeTT;j23(A^fgV^99U1;!12X&%!keH}AF%JlR=rLm$C;27a^Ey4qC_Jw8Z(S;9BmSLy zYX6$dL(SxzjYL16RcoAx(^O%%zKxVyc^4#G8fL1cu@f$I_o9QBHmUsKg*)lKf5Y!t zj&e_eq~6MHLLu#uo2{4n)N%+MJU3*BcG2&3VDVa$|D4?SGFtIuKejWs3tw%z)o2|& z-orM_A!9i~hmw&>%`pDk3NBN(9fK<&_dTh z@~Rj2KPh6gQk+{qb37_KG^jsr@?-Q6_U6DF+#*|El3iw|R*>fDP&baAx}W`VGyFhB zStD7Mou5fWTAAA)sXk7UyExN$7Kk=n&U-egvP>4x7`j}+h+%yw0Ya2LTg7LtPCS29gb(mr65P~S{NZ5ymCd~QG_A^c62 zqfyfQ=cuO|a{cQe6(Rtq)JiVG`JsRmxh zMQ9Rl`JqtBmTAU3y%Ml2{G0t)UI%Gj5;{NXi`!Iv=^dV83|>wseV{pu0!`*OhZ^Y> zfqDhVNcch>0`*0x)72g+Z;!&1v`3zb?{B)?Ap;R#`LIE4P}hFkMhhMbWEy1Z`Vx#` zK;iGj7_M>d#MGReD>tU%Y%XF!1YG{>sq$NRipP6nIfvG*^13<`>oz z4FV&^n6+ks3u4#;mv(ihn!AWJipgu$tXyhkDI;nt>pu3aB1NrWv~U!z5+~Jc#|Iy- zQc-2g<+O#4%3)nxZZBg~jBKZuk#wTqm&F(_@U%RoQ)EHA@JNU4E%`9(CG(kI@2i1j zIRS8)&AaG#&&8(O=5?V2tHZ6R6j_nWGBvRp>l@Edwen=D-#%GRBkk72F=;a2%tgW% z?oL(tZ-7)CbQ~@|ucgA&thNXk9GC}Tu!!?W{L=OZqJya-b}kX4%%=gRPg4r*IE;Yt z?4blf)J3r8-17Ql&C{!Q4RU;DvKiFxqzjlthUCp6NAP$u@&IDf%o^ZQ0&Ey=bjks8rT zOq{|{TnT)6iTfpi{?y$E+9jWH?yxzW9x6c*phMkZasAre2j0}6n}v><){YE~8w64Y znm~5aQM?N1;b`!uYDRxi@)Q*IJI%>LJn%ZD0PXNk@&ta#SH?kj6Ib9(lWl+tG8G z&EJ$$!>DsxP&yGeif8%=v9w{{R;>6vo^tmpuznK=P8)eJQ=a0!(8hBt z)s3fCs5({i3k!@bQi%CI`wMNZ#eY`wfw-_F$Z2pbj5ZOq4RcF%^vY(At z>oM0cq5<)bO;}!DqpxqJEEARcvZ}$_?8=sEmkMq{{@nS@nuz?OzBj=uUA)e}?Q%8y ziuXzO>lQ=oDlcqvhPuQ+kQ{8&u^mz$NUe0=iRlPeWBU`?Kw;YKXdHZzGUr@NNIc$5 zZxjzjIXVFGM{;BAap$6&4pw}M0hVu*@uWZ9qG;O$gxN!%VfsnVkwOkf)o=^mbyJ;B zgRYdNECeKVoqm05pg1f|nSCWrXkLZqEPS!qJQ(NU&(^wJyWdSknR`B(o5cBqvV1qn zTrnzC3dt$or$THp5sG_*xa0*hGVO9>z=))ek-8NjhYvmhTQ)E6mG}0{vfKliB#8Bn z+C-mfcC4Ldn!Os>Yx&uIx-PrJcbUP;T4-$g{T?=?ucgSlU*7CHkn)qJh0~+fypthL zFOc=eTcvIXwTmteV;LIiOD>f&^nVMJ-jwcA_`V5mLFtsH^y_b_*FJa7PsHZRut>h| zvpvO~fJt*62e+VgEEQJd<*$h>&Q_>LrpETqZ{?Rn%Dlrq5Nci{r8`4^jOzB3 z7}pq`o5>}+C3Ud8Qj7AVi@vcYdIL9@zNv}Kqv9vcJaErLJo2q=V5Jxv(X}LzH9tg+ z^Xz5LBAHYU*Q?;$ql69A_5KDZrxh#u(9SkmKd=o8A!jV*;E#SUL%B{VQ?iN%uUgH# zHs}K+C1W)UCdd-IKVtt(TqKJfI?1uF&%nfTM{})_%gjUg%J`K2oUw-0&+EB*Llh4s zsJf~!SMK-Up>5U&k`JY`w?D}79~%Z88YzlsAJ8fuW=acb1|XJV3X}#}o22ao7?b^> z8(kU$pJ4(!^THg@j0^kI-o*IKIEXiCK>o8?E+h9u5w%C<)g}VOfc$Y z!YZ*z9Xlc0res19@zSb_u19Vi-@u_Q38nDs({LaUrC4H@5P3wG#)>>>>BjF# zVhj8AGL43Z`>)4Qk3O6`V=B7?H3PEM-pwRsjUsE|K{PuI6$BuAbuHGrMw7wl0T|R! zxIxURW%=!DmiD_ zGTo}v*SAzuF#3&P0Ja7+z6I35U5oRTtSfxn-|U_B{vpH>mOd9!W!Cl)WW@%)+fw5u z=2zr=8Uria?V1!JyfNkKq)DBHY6kuZ-uM}(c4<-vq@qeg;Zfd4E`Qk51CH*tXCj{V z6wDqqE?GcwkqxXzndC-mLo*4>Vu<&6k_Ib%fq~~ns@$W}4p){H&DO#eZdu^F_ zrFR^fpqtbE3B-{EOZD2-^AS;kDmer=lDti==$+Kr%2`j=-j%fR`l$1Ad-5EnG5)uc zrnYhsyM=!h2$o}Z2~4<8k&xfLnaHPD9+Yw{yoADXC97zh<6dEF5I?Aq7d zdW4KlO<{cSnX<%gR5f!NRuPKz<+wUMlNmQn+%SFDSgKH`{3CqEgTZFH#N|g2r>#R; z#CHyPEH99pAnBE*V!jWnpni2d*nDdHf2aP@*BSSrfSD0(*v`170VWAZVzXqCR;%y+ z;XQ~}_IpN}bEAnvh4;FX%FpdyYP}C;f$hrtF)Qg@yK=Ujotm4{(``eHID5U)YhQ% z^j|~Z2H~Pf3+cLzsrrQdCv?4Bsescr!^+wOKssdRt`;=srjd*&7#|nFj}TS|r|!k0 z-Kc)33o%Uq0YgeUZF-rq?>3h_O=SGL4*B$eKQv+ECMmVw7r<9+!+;@&0vk&yG|n(dpn@$&MBzwmwI`~;f^&MKG9xPkb(Md z3k%bTr=y3f4i;9`z<@FY?ChcW1)3@s@MW3_B5>^DNs2So0J7R=WuSUK#pYul_)pHr zJE4%$kZ;H=G#j?1Dr2y`Sj=V|N)Mk;tMRHgea9A%LV%UWM6lQO5aK;v%j~~0*o52z zQNQ(T33CLiG%a{{9*w<)ND6b1Of%=a_7vm?y+g07K!o`;Q_NKZ{lAZwoIi(udH`K) z?L>EYgf?_bqN2g?B<4!9_u0F)9W?|LI>gzB7_@!4kqWK-v9c2td?j15m%^a7lSJ{; zxT`6H6{wI2%|8&M{iJtHbxUi4yTgkvB~xEkb4#5lL#HCP7#8$dhtdM_bCvrr#6kt0 zreX5{-9S>OhbLmye>JvhPNp4GY^-B)wQstXlHuZQOf3L5wCFkZKtZUZR?*8XCHI~J zBO=*yMphiTaw@gH@Xo&SseA&2>~CQP6VRr&0*L93-_Wf8^)5M`F@tnVur-fk+tLky z7AH$bJqc@(zhkSk!Dw*GUYKWR>RvLyj8z~EQafqEn@fJ0e% z7ap~jhXK_s+5TwDTS)-zzEV%Jd)flhnhip=cxrRK+{pKlO!?5f6sfCfQRB&JQ`a~4 zXcapSmMp0#ekhHdr}}O`Y^$Gz@Uziu;{9mmu{4qOa2Rrm4MvK`=YAk^e{WDTpl>B9 zxgO6<9d21Pda8PKAgkE-74<~s-RPX-Ewz@gV4p(!8l@G$^GOs}ZX-OJ0Yg{Xb0}1# zA&M6`G#b^&_$&i&yIC01{sC}%VcrECY`=?6Yv13S2?!{RGJmJvZ#?X?o>;nh&A@G? znM0;jRf!|Sbw0m^9e*010V>^{|MLUEni-x7<6r$oW zoDH{f@UolA<+{w@u02lYB7eoGEctl-03HqRuQ;?lHmkhq*c3HWCY_ZNjO{47R=<}y zcY3@jezJ5k@@{g6{VHPQ?$9i_hQ8>r9T%By-W;R^goB~X!u}G)Q$3m11bp2(AJiK#%s9q;IvP%9;A6j(2y7|pXMKmKG!WeBahKx@6TlkGqCrS^b ztrDF5z+fc1>7E8DA7VX1_3V-TC(gMEBoRT?ibS70wb#OC1f_c1Ir6X0<^$N_o9?b& zqCv&{^8uXPKSe$)6C5q>Ah=Q&6HMi7kjv0(hjL!_2%Ab9H%mtv@b%r6<6iMYTv>-i;iI#Z0dUwtr}W}tkNvzeNEsK^g(^!N z*T7uFI3(%`7JFtMZG|^glZvt`Q_h5dpejfgV27DmiVbr5pq(%#G=1$8eX}Msr*Chy`W$SyD}%p)b2HtJ}Q9?aIOa zqxl(;djRL0)v@w@4A@BgM|c!bWF_BtmqTa`&aW_fF|) z2b#iYs&*s3X9WFV+6Fkm@=@sSEvrk&FOqRWxrJ6-Hu`$5aj+UYj&s<03j<5oaP&=D zDmk2iLPq`_0XZi7Yz3JB)2tGxJ()X@C2`%q-V+~nsO>(|k)FkqR0vz8ou$OFuc~w% z+3AK0YR((Acd-!K(iY`RIVYdA5}USFr0n^oBUHRQLnABT?@SfaD z^9H)76$nrujrv@-6s=d20=fT1s`*YltUuKJD*m4}FU25$+Zas;=$5QH6bjK2s zDzeSw7+vGYv#C;(+f2N^d7*17CAW!myoHI;$(@)xdsai^JKsRI5+Hb(mhI@SUgq&<;E!Vd4Me$ zq!{T4%Ql)eFqo-iQ%j3>y&SaN72H2?d{=+roLR&pGENYmNcHfaP-xbVDi*l9H_M3` z%PdFLBK}R-@kq|NimqM66!qN3P^9eTuH?n?a>jJk0qoDxN?K_`!@6cRr`#7bYd3B( z?$`Jn6}cREl)tpf-_x>1{ODQuF@nXv*%XnqPg++@I6&*!2aXW9UttHwx~8D~Sj?)%ES$7RByIbC-K?NTw#a;|K}Q!~f_iT(#OG+aTOTPa2#Ta$i1 zv&#RS=6x!;Kvx}f%cjbJWq}m8XvWusf+4aKMi0^sMdu9qXXirb&5e^;C z#}WeX*8koO$VSF;OppBpCk=xkTi`!(@vkXmhH?9x#du0J8w3Nh?Fc9Cwn;um&bCb6 zn^0O(J+BQD`fbr=+>ag24=6-ix13#b*AYkedbvn>8C3Zs&1`_VVWRk~9YB*uS8J~) zBj@3|c>rGeZS}yOi>ZE|2>l!VHsPL4qo!5&gWfT4WM%My42C*oCf82BEs-OLeGfvS z>tSzGxc~lZM_7NilEw@NWjRS~JYrz1TuL%iHOZB$LQbagf%>Fp$PD38J_)%uvqt;b zmy^f1dg}(+QLJ=)UDyRE>dbP->M8*XEpdzNCBDWPmH*M*9+>hZwR$HDRAue-QjkAU zLSHudRWqbaw$0xwfYs`rAndN~p_WaaR}i%mJdj3Ll*EFHs)S5oQVya&mui3t*X3Y)x5Cx+-}22A^7)XhW=;vQ!akCbbhQ8^uR?rZLa z6taij@el-Rx-uGsr!7jA)rTA;5u&>0G2f3Lq;<{ZJ^KyI<8I$Wveo}rO>fgIF$ka8 zwCg>KPWp|^^88@bIkgIFGEPwg9ZsozXRbcn=f2p+senTfG7g|IhwJ{L5^n$ISz5dL z!pPaG6Gc1J0DS|TONU!TT;2x5-};>~5)gg34VA4YZgWzf2C6OT+@tmLQiJv{NF!?6 z5px2LO5C#zewIhspqmpr4It#Sjl;vPh<&80$SIKbkzced&>_~;NzWRP`i4QEmsKc< zW&M1{sx@j~vd|8J9!aWo$P*&DjrZwvOMpRF!Lg*yy?T;Yg23k8ScSf{Z*9S{P&jQQ z-$a|d+qYSu_NybO3UOq#I2fmW-j~U>{_sBnJWszClo_CIqlYo7F7Yz*Dr}TRRHs3s z(q%)Pz84YF5q)escl=DrmvF81^?7*!SV!cy%9Y3HX7wJ9XyQ(+e~O;U6l*Ow$Qfih z92Htt`0_#4PTB#x!M+=wJZwlbD`V(XysI$|9a8}o$>E`~y}c~33|;ymk9t-cnBg`; zws!7mU7y=meh2J})~-1e{>y%2`g_1Jzo_el&@^g!Jr9e)Ul=Ji*C^NB8^=iS; z7JGe$S%4YaBdwLqU;oHVOv*D|A5SM_nM++qd_mCQN68Z~=)83t$i%UEv5p~@9b#xC z$Dee161Dx}Y~9*g-Euu?U+W8W4Lg>t8+ws%Eu=R0XST~y@jW9m2k6aezK_f7)}^N^ zu%f^hP!)p2RPjLkcXQ*8(c+EHJ81mWS=dJhPzIU7RN(1ft{Kta@pau_-vNsw24qIU z9|mO}`y!Dr9~}QO%-O0h>RaUlJy+cdRUj{_ka)b_=5qjL`eb|sxtug^&2&rDoJRJW z#cq>CX)N=8PY3v3!#Kndp|Kn$JHcS&@DaHU{_A>v!_j>%06c`r1*i8!h2bnqtDx)o zB=Y6l4!%6NZu(h57$SKyHZ3hVPb?0*dj)k>cYEC%B&hT_Iw3g8<1;Be@hy)*1@=~3 zZ*WEk!wY zJdYI`a$~P28CWEMO1b;9)m|uXW|X! zJb9kzP==s|Y9N#2cFO9ZM$$hIXK#7KXI!9Woi7xTX=hZi+Bk7sql(Z%eAV5!H)t*K z4O~BfUM}Eaq-+pQJw=;)$`J>dF;N_vWGxDBH;m4LRy3NFt0c=yQ)i=yzsD{=U6a*e zw~I8TyWa86_JR*CWv-wu*+*e|#f$7w$0;`Z?^z(qOh|)_Tr;rlpv_$ zV^?W*c9WX|n8y7r43zqX+i|+JLOxu-W%w_0I)KGr7Stp(ARI`>vQDzkjpM~D@!&)U zl0Q-EyW{uj7cE#qC~%qCu={0rfBj5Vu`Hm}nWH2Qe+wt&OLxr|mOe6aBA@y<0Y36O z3=1Y5vbW-XSbeOm1faGR|LxHU+?1#We==()@*cTWIBe!wxw+6p_yCwMs1a7+s3b<* za_awKMR4JMW6()kwS98|79U=DMZpO6REiFP4J+KUfMz7FPEEC+Jj?Rx&t^;f`lA zMiHWtTH`4SC1fR|X=zCgiK%=`Qc_gf_(X~%3t#Z1um9?=|J6V5n&X^*-kE>qoB!T> zukP8}RGrQldkUMN2`LvHID!S79Gs060P*NyLyIRjN=e-{z(f8z8>g@j8y7?^ja!o~0&&cTox1ON^d5BOP3twbqvFjX{!K>v}BWHknZ z7jGLe3<&~6GnyZ5>gdB(VGRU0V+?>E0qqDxh?RkZ$)WU9n7P=1VR|qY(76n#j+RSa z;6M<-mBD~2)L{XIUnqzZPzR@DdlQI^EmSu6whSQ4(99VSKiI0C+4NCuKK@us1NAdjqoutkzEbkeloBSiperqrW2pmL2Oz_t%UaS_7&>{yAD zF?(#($>8iHwqt_nl3j~{6?u9OPsl@O*2FKJ0j#*_3qLlCQ-?o+68d@g9Oxkc9zT9h&d#*LBm#1 zY%E~NfGfnGfj~!!0K@}_4+Z_n`A{87hyVav_7uQ=0!*BNzpBVClHa!Yd_Ev(z>Qam z4|qVHfA7z&5VoiR!TbU4a~0vpHs{8+=5}o+_6M(}!2mQ6ffi_i$f_QkYvfg6T>w1f zS8FsAXx=68Z=z-Jg64ohm!?a4A1e;WFhDD&XGO5SHD{B;o{+#T_$==umj~4s(a*j~ zzSO5ZPJYc3zvUlqaTC5|PE_@5upjZ9BY5Uua|8_}%xhXfI4FwYe+ly)-R?DAJJki-eh(a`dHGy>59R@DP1t^-&A4)1qBgMomnzRTcKQP|9fz+T<|FssO}Ez@Kd~X$g%jdMn~N_ z;LmnTj2Yjz&WF2ir1yE@`g1{j$v)z&AN{*y`sk-eFT8vVYnrb|nJxZ)w*q6E!iMQR z+=ey#DB&JMygW(YK%T-_ra`Z z6x!GKHnf?@KFe%(rme$d@1L=Nw$W(q{ZkbVVhq;!z47D{oVdtc=P(?(tdcvzUf0=Isx%dBT!r) z`$l(;%!QW~wWIs>O2p#ZPVQ=q&fnCYnWw)!K&YSPKdDhO>ye$NDszkvmG}FVXuHg^ z)oD&xg&sD@Jt%Tf*q8Mr&vIBEwC>5f*zV{XA!s;JafSu5%NHp`gi zeKwk=enMm|Pa360{tDL%$4ya$v%R^tWQw|7vXkUq(RFuzdBmB{nd;i;y95y=arT=< zmdcuqCT-OKoe!D+WtVNfg{0@qLC)%%()t(^H&lE#dQD7Ue~~H^!54+GdqB8-n@rld zDH6Yb+cL1Bxe&dvW$igNB^sW)xr&L1e#xO`#ffcN+1Hn?)$>R&Y^e3j`W9l&sE0Y{ zJ-oH+ zH%+i@;txY==T#C_B#zO;w@Aby>Oe95t@)G?#WhiaAP9E#8Jff3_Nxx$T5SGmp2jYr zwCspG(&Zl0CYI%pT2L`Tz}8CqF&lYlP9p%ZgLVJo2`<`ex>D=0=_hgH93{u%)|;%j zWW>Cv_U>70r8l^;De`^l`5r-aPfLq>=QE|*>%eR@%M&9dSN&DWQx){PCHikFX;~J& zMW!xC+m5!;?-=!JHIp?x3>!~g1E0w&y+KR25#;n5Vz$%3ZzONKtn-swdZpUG2s-Vr z5w%K)@1ldwQ>>jd%)3=>tUA+oDWe6ZuL(}uj!TP%VYwF-m->%JX=K>Eb@&kumpI94 zJbP^I9rSi;if{VpIA;==hgy3R9We`0R9y}kDbtJh2_TK=G2Z^Qx!y-BIbS2?<*LWX z_cdF-9sJc_V{hhNPQA|Ub8%D*+)d4+?Q|@)_0`*rWQ83cF>tvA^$CqO&Woa*4rgY% z!3&Oz>1As#x>~7?Q|!{WVa-ZHMJ-+{8ek;8sX@ls%#5MkK9f#UnWn&(#~s_m`tI(| zC%|*`*yY%BxupVAdESq11*!NuYUUNF`$`Ri*It?u-bLzt)81+l!yJ}8(o#bd(w5Jjp#r$|o@tk*iyZ4^%X-dCAkJ$V!UoD-I z@==-)o|q=3IiN`y)r%LoQ9omE8_6K!U*=&dzjY2LG^*pFF_AkfgGi2cl1 zx!TR^@=>0pgnT!@!XX>04y)x>$F{brQ)n7kFyawt|IiG_*R(y#P7EIG@LYRhvC~uN zuV_*P_S#&+E#Y^IO>Hr~#ozj+ws@^x*1KLa0C%d(-As0Br>?&w6m%2y7dN1GLI~kN zV83%D|q4R&Fy2@w=6=pAAk_y$Q#?9nQVJ9ZRoWrIJ6|);_+It~~3aljBdf z&AY7r7M&{KrcxG0DR!-D=vVy_zcGsIu*3%J))*2gzG++)?yur1?&u4)NK~$;E=_#G=l+D0>sl!)07bkCe1ZkElpY<4Y!A-25@B?ON9JF?RAM9^1LNfvdJ! zMqhoBii%WAHQSlz*6*dHzb;k+PHoqrdtFKJ@m*Y8uKBz1n5~!Jub{5ee{fQWeJa+R zOKiMWb?nR9YJK!ZZfJR=T-9ox+Kt}chJ&@{SCy;e!ET2eIYME8!RdJ`)g_C=eZHpZ ztX4R*LA>J-2QU>4_zn&~LtmSi!@fk+6#M5#BV)_)(D_LuXC?p64JSS+9J-AxVarUJ zon`qWhJ4L>Ul08r7VgqPlD_Ntb*MZTbKTgA?v0N3wv@~8Jh+$FLuC=r`#k49@ z98R*}*xq+ymanpZSlRBJdgPr z-&SJ9XQgu|%!zniLX`5W0{;5dim;7&r;LMR>}0l^Fy?GHS>L=BtY;;n3L>2*c4V%7 zbI0HBK|^Y6bG)~&ZD&^)n;2#O6h&nJNXAz>c64~=YK^HW;TZZ6FnH282&SQFfp)m{(nRd z4PB2AQEPI*(vEMQZuvZOroZpK`>+1@+-=aKgfxXP z=>&TmVoe=35&%3Rg@tkeK{y)-BgLCrVMQfKn2gId>x3a-ql|<20C*rk$tknQWRy7& z;{o|k61S^16VYY=GI5FXoAqrrmRH6*9sDz>?5r7m% z1taVMAe4wV7&r_t20)12fjeyO!d-|L$3!U1pu$R(bV|b*d80-FIIBbi65Ii@We73> z#!SQrYE}+Zcxr+bNofiJ%H|9YXmy|stOgPvS(JcOld;;sRI$WQFqReCZ$c+|98#eM zC1C%VBIHs8N>^L2Ift`jMjkwA98L+v88UV_LS?GXLkui((H~xM0u;!$D`>$90q}we z$-p29904Q}s5r)73cXm2oSkCKtb$HOSn9x>tRP7-Q;1jbX%&I45Co94NjV?l;~U7a z)1XW$Qb3SM!A32MHz}Bj@cEUe$QD2mK@@k6fF?h_9@_$o(qYC@zZ5$y`f?HZ{w4cb z--nU>A8Peu$O1&s@ESbecn9?7!Kia{1fDiXj4^R6fU#myaE4iQ_qC_;n7asmc??fSBR;l{lypkG9feF!weI8;d#*0)n$;Sr{)#wSovvPPMpKoqab;4nrgb zNLb3gJ5)+fl^vx#(?^G}J=VNs_na=%^>6I)Q~orjx89|}quSE8J$=IQy0d7R&Y z?vrMr-~A89&Z$WhU`w-Q+qP}nwr!iIZ2J^W*|u%lwr#t*?!?SQKlDTYgpA0@{C4Kv zYq5K|&pcdvCM!D!jr`iFc1fIh*8dtWZ1Kuo?c}UnJ=>ndQ6InBR|31+;QySmdQl|S zHT`&xtHVSTt7V!#ThT4>*jigjTDSK7d`^PqMG^STP=_#cL0!Dq&F~u4hCjh>e9Rm; z#rpgqIJw{=x|j?)3L2p%AL6x!$hq>p%d9+9vGttI%VMP+@&2nefE3c5$e&$Up}#GL{_oWVy2ibI@Z8`Ff~03AIY;mFUKw%quG91xfwPU=TkqQ4{b}nvxA3e zn`3w|e<5**?YY6>Go9aGSF_m(j%T5E1X|P*WrD+dAIV)$%UYQ)9S(&mg zA3B}ctRvT7be-#|pilIQEUW1&LgJ2iV&$l+n%Fau1}OvGrmhiX(Tv+*P&t@i zayE|i|L7xJuV9C*a0dfydp%)j8t-Q~L4T zt2#Gy7I9d&^6Aqzp_gOPX}U9VLkJ$3;s_h~xifCA#wOcAb@O(tQ}ZgjQB=Z~U3r$N znQ?6_PLhB4c}ji_H=}&>^mpj3f~ol13((8h-pDE&`_b88GseGXY1#ry|7-C1aT%tb z)*E|GPj~ck%)0a5JF;)ONY$yS#K^$FQs8aju(#7|s6qdAu|OIR6*_;qecd{rS$$9z z=Qb_zi>un=T=#*wSubO20k-aCdfM;#etppE!2Uah2_vNXr3VMS$yu8i;X)5D1%dhe z#_sz}N_+aq>^fyR8Pzh`+5Pika5kZYOSSx9?)Up@KOLC6V@u0O-`+$0dZ~Dnr}sKi z-+N*59_?0B`LCCt`^ljHpp!bpS0aB*P@L%MXvcsOekgPWQ*86(tLM(3oZ{ADz$oid zfH~gF(oIe0wM4Ow!Q?}s`JK9E1Q75)O=Q@FW5oq8eb!IcrTbuD{h`cKpHm_TuJt)9 z4*n%_5A}&T`7OLSFKU_z#7+uS{?b&wx*i{Oc+2FjHE%blyqQ&`Otr4|gZ>TWqUAnc zyDw-WHhp>>4YulIJCz9-b`^A?7AUUl3g6dozDM2<9NrX;q@*gRGHvjqQEGN?tTc_B zWAyq%r4BbwuMpRT1lFKR{jcx(u`a9q==rN_-9*f*P-?YvkDWGf-8VA7 zWrdp!W$?G|4rnf7a@;0?uLUp-&5yT;gSQv>l45X-W4iN2y^Y4Jo5~sc7GKM+`x$#Q zcoQ1tmd48Jhguu0!E^Z3L%cI5qCZ{bvD6rze>fkeV8iBzVo0<3HiU?8X1wl%J+Ef? zH90SPd?YOxi+a94c-bEfdnQ}XZOrCexs_AUUhO~J;?z&(3wHnoV{r2ShgibM_&>xF zCKk5;A4Hf47+Klbnf_l&`R`AnjOWMlx)$jGjL7#m%80mCucQ?Y?fFaeaB*#yKvoD8+O-NBue znaLH>f8HQ-nexFHoSmKLzs}$g8o{_yu`$;HOklGn{g-p2#X{8pOtp!fa}z)OgcR=5 zI62qu7?|4I+nF%5xS3YDQhf`Hfm_qL(*TqFV+Fv`a~XHzLIIsZmwS7-j0Fh5OHyXtfT*2`b7P1{2iAr$P5}T&!6~H20S>SH+59jkK1~I{U%lA=gX#6_ z|GN4TCveW-&w`DKwyC;;vE7`ql>sC>Ruk~=Ooa(b%s|HNogIFK7Z#=#*N*SWi^^+D z-ZPKy%Spxt8U#TF49x}mv74D2?c1ClOX!>1JdZ=e{DA;YuP=?MtF3BcogE%S+>3h` znZ)%M%dP8R{&uZTVQa2t%k~3CcE&bNdw8JGtNJh3)jheWpf2UmP_WpeM}}Wiyl}~kOz&hd$|x_VeJ4DM}iAM4D{*bN-5-6(3)P-J6&V{C^p}#(=+!Uck;DY>~d%&l{ptUoWZk z)K#F?pK?@|!k@C0qnm@0cQ4jbz@HdWbLf2<1c9fFeJ+_x8L?dc$)6dKpM|5JxE(){ zw;sh$KXj5~8`Gzf^mF;IA8}g?Tf3w07QpcOX*q)TiS@vg-ebRva^N2=P0if8wuYyl zWhpMqz-58i;l=YD#&qt;v<|=+)XA*q$#0TjeWN9QwaM{Kuu_8yi|>&vpj>k^qj!C- zU)HK-;5Do`0{)K*prG}`PINw-So5&oB|0=Wc<*dq-z;tbqzEyZo0~s5vjt*IfSn)H zfB3w{7a&f6{_PK7sjFNBpN_dWmjGgY{33pYZ~z6f_P^9)l((2x!N+&-|KNFte2L8f z3SR98feeyfV>AGx|MnnK3-u6f{s_;Vh7w)eu?FJ zkM|&A`zs!?1DUFS#R#k|`4TIDP5B|Pm!b{$AyAj130rd`T>P}Qe2YV^6N?FpBdAW| z()w`+%JBaLrD_T+dAl*N0BHfrW`2{J{b+x#xP2bLl=q$D55hs2nplJ85A$QLeaCBP z|5RVXPcvZsKnKbJy>bJU3h(+cIeg~*Zndg4dvpbCvL0Ol(2UfMPwHWOD{b>IKTdxc z89#B5GufX%n}9#IKvavD?rXVrQ=30ArIspn?z0pXeY>-yI@w3UO+FHhuQI z77EKfgv_J6?lx`;G}yDxpVIK>>(B0-1m+t*rGm7pUur>tYXRBeY(Kv|^5dSOA6`bb z*?PDhFmG%70`AI%&bWq{~s=K1#P)slCu*)%-9?IlK|$o_a!&h8rP>6TW+Gm z8@i*Q;&*ZqXwvYP`w4+IeC~ig=eM&gCMUPQ*vaFGGl)yr7yS1_7660`Fcu*V{VLWS znC2pA6aO;Ae#iWc&q)sHjft~%oCi)X`&(nCwI4dBgRqM0W5 zVin&WseZ`zE!IJKDhyWh2Czi?XPg`o^bWFy3a9n8bJ zUSIp75u4wm*Qwyp2EJIbSSOS$qe)LLbdGq2Kt&m|(_vPl!4V$f4!^R5l*}5|qde!E zOFAx+{TQ(!vjVUFm6iW4im%(|HAaMl?s_GvnsL25v1FL`^xq^7QQeg{W)KhWShRK0 zelC_)YdiiIK}iv!MSSh7+AcDcxDHVKGRx$u`vTrn(0CunJM2vhrCI!JJ_1N`%(Z5g zVHeUV)L0XPMT=t1x!B$8YKZ|spPUu?R~>9ubSMxV#yFL?ulXI=Kh59ipps?lXh8{Z z1Vw`TZ}-v=%64@L-TF$Ev%g}5O(=a6mH%)%MTa>VT}}+zN(v2rphgp+!XkxYQt`bi zz7h`M_4OA;C8MxthE*TU%i+P7)LfX#mJc1$A&RNJ*g#T^ZHUH^c;UdyAhV55zLobV z{=(rO=DY5xezTgZEq4p&xIOZClms-bbMfiW_y9`T8Q%iLtJW0^*VaQJdH=+BkQIrW0(iu#Bd zojEuYFr%#w2W)*z>xOLHYx|k?pcQ;C*Ds_$!Pj;KFC?y`-b$}0`}f$fUt|M78TZCY zbtxm;ym01l?g^K88}8Tkn~?||uAtiNlt~k}C-XU7;mW!3V$Jie|9m#g_1bh}e<#i) zQ6`YWp(NV3>jkLQU%&hXi=wM-&SH z|N7j&R;z}vYo`mTIz?mvMVZk(ZQdl4r9O_la)a#x#$LFtU5<2yJ9f}O(;prrPz3ZcfdQrBw8Xgj78JPrUaZYB)E|6(_qLkcD+} z)eB`*+%XTgDsS(C9#C=sWQ&K8H9#Ce10QWR@XKxtsrh0eD%^q?_a!QlAFAuaB@1*g z2LNt42;&Q^Hu|Efc6DjUhku>|_~hA!1v3`hfI9Q@NaE7`V5L{^wJ91UU*-G5 z*O0A~`|2&!a0Od+TH#l9nlPkhtW&gay_}=W<)?8A#IvQl%))->Gz{9*PI<*aH>EmQ zGam~v=!6R8Ci*0Utj<|xu($C+y9#kG zYIUYew4*yRR7^d>?Xb96R0Afx)gqjk)itguoyPBD6FIg++6@~g|ERfX-{#N=ycZ=R z0ql8O74bLRw8_#6N0{IBwksym1aC$faoz(SVD*YG%!3vzuhpL8Ttnip9fp;Z`XpGt z{>hlPuw&^*(u+e}T|4JC_Hb`i+8ZJX#&O^yT_n(>>SH4)Z4)w-y&e+^N_zGqgF9>7 zp6u}nM|X(P^u@WLxK;%ZG{wL=gzoaem2|uI%T#9@!SPhx{^3LKp%(3$u!Q|GA)TAe z7W2t+>P4m2H&sftuQC)ySCmiUYEBERjE9>uwEK3p6j2WXB0ZBi9hyS^J;5AG`-24< znQaQnl|gnaFM5pwHq0h@3)8M?L}D_lKj1KXqfA{p&Yu2leb_?b z5DEp$aVzbF=QqJW>?{4UscwxlUqsT^n&-A1bOXzVb{O@|T6+3p6>|o=(<0&cjW8%N zOHu=y@HTmlX3wJXOi@-n4Y_Wt)Ia~Y^OsOa+COGb)^T}2OPvwD7opG^+63;69v!xe z{-dY<(sP8+PK{?!X1p(=)^TA9YG6x+j{p(_IT4GK5c2Ms}M&7^u!cd=2N$$)xfLPA0r4 zOmFB_IHJJyx~8gePf_g3g8>3O(JzL<9DZhMY42pqb{Fe2nH>59AbQVRvI5c>%=$I^ z#@;n+L_Ur=g-T^I+40==D+1scZ^cF~PQ_&`yC#Hp_BLV~9lh@i{xaq@LZEPWfyg+> zbgwK5k|yZXcmqLow4;YVC=f1j3u*MPeKHdhsH5T z<=BLZcI!p$e>m>-fiuWIf1c|Z2vWqwb0HA9%|BVz4dNhcJ6GQT+{{4tu_XR=0DBp` z!4IXfGBjV6K!i7mht3sRYG2KFlr9nlWhj8&9OOaDO9eE zV!jw64{S4pkNij%B`T~?&xmI=8TRx045tQMARmt7ncqUZ!6f-=#`^F`svKv)Jli-{ z!gMFkY(^)``Qgq|!`F7*+FGpBvG?WH1BLXE1JMw1X&Ux7tc8nt28Luh%9qE7o7`DW zwx22o*G8nqAxObWnrHAeD2GmDq!d$J_r0Ds4 zc&RBZYrao%hU$&Kb64p~dR_;H1f1%GSmDcTiag{7{~42>%EE^mJfgU-Z@NUbfa@8T z6pA5qmLYF0`P@A13_8VAtDC-G7$UI|;SNuqXAKvT$T3rNaSrO+sT`$3v&{sIrNIo&s=tsvyRKjUgrveqGzR>2<$x z>>KPBnw}qS=xM!XBYg-Os=~;4QSK9lZNNz7K{FX$#x5}fD~WLZ&**u?U@|SGOzkHk zv)s~zQ%PL|gAWv37Q%1k#P%`S8dOJYwW83imnFVaw;?k%gOKXF{Z4rpR*vfrHbbXf z($QM`}L`5PLy%XrPydDUv!(-!G7!)+(4tf(LEvYi%$?!3C-%0^`9 z1R6%=qzsYPl7h{ms*2$~pf~jJ{5`2^JiU%IlN3o^jjnue6NRHfWYOV28D&6HZU*4k z!(hsAtM;FTPsG&^>Q)I0-N&8|_qqW+z^64G(}QSPgz&PDZ^cP)TR2_Jh_0E zIAX<7ATf${dNzPcye21C!Eyv_VLXa?sB~&;puz9u&sl%cglfTDfDVPdIYwHwpkC;- zPq#1D>aTF>(2>h`!Xhf3o$V~PuQ)8E9O*G@caYA-L+5ozx^_BZWhF5+yIEOcD{C?G z-{D$}+@{C*_laX1`DD61=PFH_p5NK1Vcq!_qeY^TkHkJ$1{3~hn@QY*xmNP;%kXZa zM5eQ-d^2>6@buqRw%)4jM6GVW0T4LYxxJ(s?2CuwfZe<6sz^>h3iVQnre>hwLRqDh zn_N63@pDPn=Mg&pLKG>!%mot(vI?asWq7CjVMfIkqDR6GQh?p`Eb3X+d2#^RahTDj zH1_n3SldMcpE!1VMI|MR#wr#fG>hsYezM5x9p3u!kX~MURa2Qx4%L#2B#wT1e|yhT z*;>KNX_FFu=Omiroc~n?xHh2=3pq~1Q3zwX@jUtp5-z(*RpuYMQLsZ|_pC;jBKu!g za|UzCzeF{I10ZJ+-wMn=cI%I>7+4bp(xrdM_(bBjUa*uIJSRZisVm0s655(FH)W7n z`dQ?EO4(kStQd$XPp;M<*ne0Gc3rwD!;pGZsX2p@7jrHQum1V?yw_bVRG??>HNy9y zXn_L~%Js3cd@{A99`Xh`zgaZTt)jPmOro$TSv2w}J0oR0BCLeRnlMi=PntQ*l^gQjF6+@2O*3$@;TcyCgt(nvCj_3cA zrn?V%&&D$+YECsCHlmP_Fu!y3!cZKQ?KJNz)W>d-S#WfzN|+fWhYM*uIdey85HW)e zd@U-gtXk7~OnY1$ymFl`TfmNh zui?Hb^Y#oaZSH%Xm{W=4{I!FdX@A>@E15?VBPCqY@a;*xiN^rWZ~h>j3FM^NIl%9) zuMI+Ei8h(jJk%QH40x6GgWU1lEK`Myi2Gr;y{BFz{h9|WQ=*}mE=sF165HLPwZm;9 zX@UHJo|!-3b+mSDKlL#B(H63|4dP^!SVI)g&k0!!RZFWromOxNjuHG>uq6RV%jMq-Blx3P`zbz&P za^{G|aLR9_#&F2-u>urX_Cn)lASn*XAyL^<7i^{wvCE_Q*%uo$Q#-ZY%Tm(8hIKQS zmV?T_y<6}zo#tL4cmBBEZF}c2tw5tVf=FsYZJm;!87Z_)6ymT6X0e%Y_ZkGNKrB1( zcmMMVXnhfesjjo8zD(e1D^~qe0*}T9Z!Fw9LRE#Nx0|UESF#zVGn2-AGbf*U9ajvI zT4vTdF5CAep$#UdHB>0U(y9>_*^e?G%P_50;H)Hjre}c@g>Z~*0%w>HZG=@^yu-~- zsUsFf`batvRdx}!Y?|cIY-wb5mywI=B`eNS-j}(sbXvSGIWhXwlZ51(@P?-%F@9XX zthCsnbH2Z_Qq1Zi4ir<%&hPtOUq*RLfsFV)z2LrS+Q1sSjL&x8ffGZf){jxu)pkw1 z$ytyM^8}|TA`D{4)7|tz#*FtPt5N#sNNfhy6_yD|Y3F9@J zSP*`zokH;Lb-Q|^?QYKf*Rw!kovI%?x`(JCSLE9J_rJrB&e4=4>#&Jkv4<>1axSQ1 z-H=F_y$QCxlue~)%$c*<>`&Gxy4IB$3)1NG;TaRz6SB8mzhj#BqUtSLXjfsLf0GOL zQP)(%bxJX}H8=f! zvTvscj=^UvXI`747tc57hCVY2|ADK*wupPc8~oZge55khKlc&KsQ^9#e&6kGbv!16uENxaVVoJ&{q*)RXHYI)z+glZp$(+ ze&R&6g3bbMLOY9JIz}l8UXcH690UWb@?KoqXKsaW5@{v!nV%W)G@Zd5d z=fVJdndOkYii-0Bz)*E3KJauYAosM z_-^k`wcU`u4p1T*=6OCaA30p)181zRR6Tjfc*F+`Ig)5KFws;wI0>3<2uGpzp45Jy zncHN;fe87oWpF*x7F;LR+ldILte9uXNs@HCPNxnTcN%gVG}OVNBYg^sT#R4x{%=Bf zO;&48`>c8<_oyW5yH*xr|7C7lu$yC{6+?l_jnVUX)dI98bB!&?!ZBs+sSRt&DnJWs zV^kn0Uq<4R`$tFGsYNrz*{S+(zLPc{;^q@^XjmmovggIheF%nW!%$_8PWB7ujK7n ze+*W~zD%E5)veS&bhjj4d1*P)vYmOL8lX%!6t8+1U19}m%qQhrKJsNN zSTe$g`*T14!i$LVWy=nVy3-030tU5^4EUEa>j_%NdX5ZQLinaN}&%`NieqY1X|j_Oy)U->jK0P#Cy72!34();pX_fl>D) z)3zXKZlKiHg@Ut%?5?_$JR`^5v0t)0F_kgMTQYx5=1>qlCz2z2aeNji&@$tr8@G!m zSWQ8k*sj6XaT`K(c;aqLED0~h*hE^Q_a#q->+#-(5LQ#`8&k%-6WhU5`nBC41{Uuv zjXn5d!@ZFTF_6!k)lSRLf(+iPxv)t!u{8BbqOw(+mCaJ931q1qi>3bAInu=-ofUa1 zDoyTE1MP?UnYnC*BJC1>azA;TzOXo7UHE6%3gdpuJ&1WuWYsm%WPN+UcNp?Gu;GP?am&{ zb=ZpT;1?&=)unsJyU00Dl$Z4QiO$i(fLqNKl*2&H7T9Ez1%DN!OM|;~ME=2p5FKh% ziWO1QB)-`YEN(in8hn2n=^yL*i$Y3K72xu1|0xiA5)oDlZ|VmM zP(#8e2iuak1JXVj&!lJ66r^CaBTo2a>Y74d5-MmrS1JT-9gaH=+l8}}U%jp`6RZl! z#cwjm$1e9CNxyhgJSZ>%e3B&2CUnUjv3kMev>^$rOIJ%(-j4VTLd7e)+`52v{jgW* z861XXqWm^b)r%g;vLoToZkJ_RoMLtgw{U$w%S$ za`%N=#bjnkUXNrqB{fMiU67^jxC-|rA{y(=4M1XBPepEiHwTJ%fPms@kt5)7JJ0N@ zw3y>?hbFh;ObfY?`<7fwcd}Qr35R~0Y!q+fRqw$QsVaGWve{3K0w{ZrODi{)@^R)d zcLQg|`Ne5c7gW|^fX7f~L{U;@CGM>V2aM^Bu0Z-_Pn|)E+f6m0((#Meka}?S3aQ}4 zeQOBo)T>>O)H9O-sv9YI2cC?EvqG&M`_#JpyS>L1W`nTIm~C=bCP5=)It4E>`xYzK zYYBIB$|`c@7k-biv41H%H=kH0`|_wLs*0?TM+B9fSNR7gT^_am?Ru_gk4c4S3pP+j zl?&0Z_Zb%P0AKDbShbP`6mC4I(q8*LAZ{)7D1@B)w#ST)m2|`JIC-h=bdsSkI@Y3d zZ6N0I$+=XnI!wSu(>iW4E?bdViv*U-_0~NF&ce>AmBsKKRa#O8iwT3_8k!C%!u&q7 zs7IPbK|y9hQ8vZ=EBt%n{peMh#U1U1N)t)~9p$1J6nVv~R4jYh!_&(i1w-ps&!>x` zQk9a`0$KjJ){}LQmS0SH+9Wb>t53ko`1pC1`^}S3(or9Wx+I+Akub~wtsEu#c@xvZ zz|yp-U&KUld5r|R(_YC#6AL1DzoY0U2s7S)y-8UtM_;s^G+;{Gk(RdX`j$Mx=F)S7 zg?DGADu7(KKlDWe^-jB4e4lJB_b$fs*@)IHb|d_JzK|O1f(34r;d#e6BcC1jPC%aA zS{Qr)B7@Fn-4~u{k=#$2AK`tO^NOD9tVkx#^0j!&0UZE+i$h{B+hIZ}Lem92N4*oT zZUaloqQcq#XeQW;3ZUoqtBax!Ltzj)8k)=tzeDgEMdJPG3{(2m^A=PdOk(>fy*l2? z{cYpU$tQGg0qc;?QCQS5NSVRR`t>8u3o>#5={g#%;Qg~m{{a1BKNWU3J(1tC;7@Ax zAj1J&61AwkJwaVxj=3iWMN{198~+G;4eLT2A(Yy?Je?~zavNJo&ip50tq`7k)@A^& z7pyvJwLF8GBUShkUmZ{RPvdS~&a&#hnbf^q>DY2QRgG%T7spuRPTjZ&I_->Ac7;1m zCITUQ(B~#&K_oKwSrif$sykE2~_>wdf0 z3(DAAN#aT8REokV`e2P{ zrwU1R34`U?bIr%J&f#Q-(gX-ZPw4ea6D2z#-B<%wN;~R0CaY1Ohnwsy)cB*^5|9%7 zz+PoT$+4)8FQvUY&4&*z+iV*9fvVB!&2h{Vj%eZ|lo;jyqs$I@d*Orkb-~Lm{k$jp zrBTXtZhbbd@%Jp(w%`EOjTJR#qG-HFNb~BWod* z>T%)myGPy{>5+UA(~-N9<9+l*W#nUIp4`fzn;%2&G~u`veLMWM`ZN?UT$qt3BTh#3 zuS&pZe2yV+1MpK-0&3IntU~zUHh-im`9f`t#Y{3_!vAqG2~7FT>`u*p9zUMC-m!r( zAO{7-!J!&L7(&XE8mLRZ{oPJO&Y0#%%lvsjQUxe_^nFSH$R46m!Ky@7-#p|-*6wg% zRuWz+xgA<2CJTMbHVXhRA%2`{v37XrPk$>Qnhqet7u~LXghh`DPKlK^c|`A(CUJ0o zMuvm+-yNv{9jZ;bHHm`XeO;fD6-pk6!21#MbP@9%fFNJ+Vv5jMSaDU2Ip2-sQ_!Pl zMLk`&48W>MR>>9GKvN-!ZAth$V=ISpk#wAq+jZ!sB!Ie>+3GL-$arDViHeRmNjCJB zZbkycDnn9t0Q>^ILYt~P$A^ulCQS#M=Yc_%4?pyG5P}oH0t?=jV=`6rxoa+3?6+-s z+;wAz$i{e6&36(CeoYoq2dI9wSKYGCTkt7ZEaebwjiCs;6uZc06?}?W`2>GDG5U>o zY(f{XIICH9gw0ozW;LcJb_lcj3TMctC6{10%A!EqM3bT~Rmw!f1`8B*o|y1p{dvv4 z%5mfF{M4J1BKJfmr{F#~o6w#E{?zFw*)83p2UjK*K=?uw-N<788G`)Z8nt~M$a(OF9=xe4*kkNx-bXCxdi*eioQqq@k%?N z*V_(;=RSG-NLH^Kj!xQZa=2I1uJymXOzB@Lz>X1h>u{tiV7nD0mIW6@RhV3j29#O; zdHAZ*SFtE{=MzMvl_-3E2V8$%J`l#pUL`?bKFeDKR^dK?a;iBqZkK)4sF}Iqk{Kd7}ugh z)$v11kH*9r80=SwO`2UM#3u69#AriCdGPh)9?3v9k)jcoDlhgzWVZ-x!@CX!X1acx z9hNOv4~bfe7fHmH84zbPeKju;fT{hbc6ey;^@bcK#9?QZi*wuYvQPeMjEqKj5e08}Bu8J@j%iU*I zI}KWo;T7ZmDKA@rQmwsDxN1)Nj-Djs3^Ilpj7T{{ZWsigXF+itR>q*eK}WhQN2ueT z%ETp*j$Wy!BPB%MHrNhAPz5OF1^6KO2Wut~&4Vu}gY7%bPv^b%Ze%ygEXMv5N0X3BsZcUAWf>GnqA!~- zIxE%s$wO6Lzphj0HLJ^Xz&cTuPjo75^myTvccaPoKv;Ef3V!k?&S>ux#q{o!wD|S> z-skgrH|&XCE*tE^-+UpSf<(PJ4IwsK5I7UPf+%;c+Z0<8io~6!O(bOP_d*%L8sZC< zx!Y>OY~&ci6vz&ye+kQvM^*7PTr)q|N=;QQyyx=c~0 zz~UVxTE4uF=N|b?dOML-na8vvs2GouyT*^4n8RYCG2Y)O&RI>CWSjewR#=Krpc0I1 zmWj=)+j5$tyiio+IvWH?LGsS^AeT(Pcc55Gpu$J(7Ft&0J6t_@;!(~_$IONU_vGZz z;{FE?-T*eF*$$KAx>oUGYFo5_&BkY?knSY!j}ZKOb}NOt)(D>07>!ttnm7}49Ez%0 zolAF?axn`@itWrdz&czLnmwvr{<)gN;K_g@Dh#GiYa;o6fDVt1fwQ-Vyd1iAl8XyT zF;4^$g(c^eV&}R3u1NroyFmtih{-bwBr4U4m-1hy9CB0bYS%6+tO;DST9OTis>!dV zC4$VG0-4=zzvxWGNtyea!U-JX)UR_eoUwtH_P8;U*m$6;ILi3=Sq&iF-cydC#M5)Z zbD%AKZ6=*s*>+;L$vgDzW-kR9=N zCJA<-dG<6a2$7{FnAy}r%@t=t@YInAGjw!#UVt|4gz$zqrW4B2d*7irLai>IPIDK@ zEzc|JsjScX7s#3~S9^dROse|&z>)v~?CeVq-t`y4fgl23vL%g!)Hm%u#hgS8=uaJK zr94v6`C=KEJrAKl>CJlEif41d00DaCJOs$hg7j-%H3pk@d8&;+7I5JLD8es}-YW~e z9fBwgGpF;O-E<7yA#(GjB_fofs{eQ5o)LZ&R2}!fR5|on^>8TxP7cj^y-Vgum4VAcis0rK6kNT?)KwEFjAc zl=YkL#8h?~vn}UVQb@}3arZaNj}eIa0+$v{z<@#K($NoIy5+NYc&UYErPC6$DB~&y zX@Qq&X1iJh)%;PkZ2MBcNrup_CM@QY`qC*=%a@89_po|tt@x@S;t01@rtDm28uKd# z<<0HY#l&$Adl7g+*4n80L*Ll$Xkymykd2d++~ywFCm@kjER`Ndd1-jrA0@dWF>P>g zHA0JeR~PxZ!XX51x;Kgm1%x?}EuXjEsK}C7D+%QMc(*|skekOXxtRN=H4HU4&R>UG z`Z`?j1PYH07{~FDI3HrgDKR}*tK+TeHx}MXUl%`qUFx#Gd5A{FK& zL<&lE0}*DOf1T8jA!02}r+oVFzz?{>9leRe6luG`@W0JN^|iY%W^_G(?#mEi6~Shc z4L45W>`vJ2gz~AS%ZpGQ;I7PN(J`vTFJy7Yim-h}*5C#;c50|vAFT>k?xEh!Y|;N1 z(eS5Q#Fg^a@`zB|O5(=J1HPF7ndN7#QmI35id7$w-UZV*1sKqbqZ0e+M>uUgdH9{& zWe1xXkMv}#Ny&?4y6-eV?&K&O6buY|G?YsfHwJSXlDF}fxAkxwo2KE*wokxJ{ZgCW zrwO}C^c-)uP)HSwIC<`2&4FHwbh~G9r>iipzcn8Gi`UnUE%@-Nyr(&$cO$ZHK4eGL z32#n|IE*J01%@h9FVH;(trtRE^PPzH^`qX7<)8LMQjw|^j>hveS_}H|?Sg2*Ecgb0clpUHD&n z3TsGykQIRzDg_C}S6LY-cM7L}bG>c>h%uU@fK|PkSKVYjCOSnUzXDytks@Cu?uB`5PDJsYTayY07=QN2Auvk8W)9F@u6ik>dVA1Y~sK-TIuAC8Pgh>!ufz<gVd$2`Y?+$`vuu?M#JY>2BuwYBPbIXN4}soy z_swt(S(wuyz{QQRiK$!SM#=5ptHr}-$($f4GmZDR#T%ylysmb~Z5OD`FCLjszMi+qeADnes|epGov(X2x!b) z`&5u-xt=X{GU0q;UEj!T!By^dn3Wa)=F~;qfL4;bwvVqPA}=LC4W+H8Ovoj+6dvS@ zkz2ztjnpM>{rJH>?Rtj>t#teOeXr%n6ti%Z{KZk?ChgcE$*Xfjn=g~%G5T>-_*N#~ zJTB|8?XSnywRBU-qN!d!}r#S*-9t&OC0Jwu!)= zZTUoiVdDv9WHe;FibqKqhOF;`s%Z|&Pn$0(CwoZ#&5G-9Hl=z|VZ*$n)yD=F^OXtQ zEGUlcIjI&3u9x$LbUX+L?!0B!$Og%i`2FHGO?6*;)DeRCb2Rb-j?iiP-*x>JH26}# zW<=@0rE|>=h*Zs;yTQ2yvaW*^dzW9>e(OYkgP4By?#CIH_YtVM>M~u+w6Fw21aEZf z&pIRH;PCXFLXuWz1Ye@B>vK}73>IbX3oyY08EGFLBGW(OhgjP9f;3)kHk1jTaj|7v zoQlAMvpAdk=mBzxnOCNsgedz2jFAAY19J-3Tf6RCB8#4i$ zj5?=b6KGj_&JL^dL@j7waJItyp*?;pNOg=Wh|&Eu&^!ZP#fS=N(aWRtaV5dPL!|a! zq)JCxN)P5mo(<_U#tm9s9ZY6@xlRZIzlN=gooeH(rJ4put4vl=nDlWkuCEX+jP1Ka z+=}L|Pa*dHYo3t^d{JCGKK<1tU`P!Or8>@Z=EBO&!FxgEd8Kf`ta0E+eJ~f_i6^mo z=-1#%6s4IJ6r7%fD0GJLeAa->CtgZJC^gY$ z&@8!X-mLQlr|5=&Ot_~K)H1_z0krRsKNj!x8^=;GixsLo@CgSO2cic!_u%B~lG6Di z>V>VRM}*1cI&dMS4IHnTm(urkMkgdpJ(QzzPo(9~-9%s?N8?nyP-(qSV zJ>2R3Ki?vMjaW6@fM>nYtJKRGeAHV*4Bu_4vLS3I$FudyD1KRpKPd>}m=U|266d8ZKI1S=|;#iIgbWGtYdO^^01sWL^yp6*(>79F%Q7t+r(n zE$6W?P&l_=TS zQYl7U)r6JjxH^tFu-KAXV#aT^?_}!1pu9~g6DNs`m5#mXkOQmji>hjyjd?y8GBx6r zg1RU^P}V7>kHOggwH(v_!*JPUCmOS>u=7y8ed(hjv)V_WE%w_jw1e*4rq5JOOr*cQf>HLV!Suc#B(1PvzFc(o^e>}Eh?D9XKpX4Vx;dIG;M6P zI37>p=<&|vVrLUBpc+h4R>kE@7g5+0n1<@cnJE7XtxgW3_{((f$reqHJESod&PdR0 z{TDd25yf*biwi5wVN*)|gWH z(2+x&j<4Na_vwm+)@3{-Sy$>E${Fej>qHksb~Xc4vaOBNXX;jOX`YbiAMu#gt$|$})Ye4JwNe8F zGF@5_e|<>=<*!T)y`H*hNQkx0Q7pydepiTPE~SN`+O) zDUmZ8)SPJw8%6pqh`k-Mf&djb3yp)>$7L6YbM2K&m+P1% z_^LB_Wa1-}yWx)-Tf>QBufwzqtK%fxWR@iCbksFs+`WftA3XLA;k7QC!n)0~p$Q-( zyx%&Inb9=SkPE;5t)dp?K(hpE4UL$!D&BO+RzXHrsS+poE+zI3^MWvm>XdAXp{~Ag z09=*K6am-m``|r|IdM7D500e#PP_HuQ2Dx)nuE-EQb#+JP6*l9cz2DOa^Ob&R}^U> z6hvFia==^vwwV@k)iju&kMgWb^xB6iU^Ty#LAyN`!m8%$vCp?gvj7{iMkAC!#Btzt z-la~#Ad^SHpc&UVE8Zz_T7W3Xg-o)Gjnf46cGeYMGaR40-aUmo;5J!47Orb76O_C> zlcxsHDF-d3N1J4{=(`*q1;dW&65K=U8mmIfVqhG>yHa#+8-$Fs9)VY=Y~;!it*c#p zjDfb2=t~mv0(8|i5s76%F+?6NUIFvQIb;@KJc3OWhenAm)?V*r!)N!u2}xmCYT?Y! zU};a}5oxnXq%Z0xununNr?2AHGPiady27=N?$d!s!jM@hp=vhkDEUTSJlN*C))>f| z{eIoAaoI88X^_x_U9Q>EC11rmly@SmJ%f{u?*MkDXWRGpv4~}X9K=-leFKUE1Cr;* zouo7djz=1J-l`Asq_?|m5qxsC@@BX+WVBCk~&5tmJ$gb`$6GIve)_K1SzBK z+GTAK?*Y0!4G*IeVuHZmLa;P)#CLCG;D(aO%3q`C8}VMu(;JWoXd82_=-(cmuJX)V+lU&lp%PTLz$ar1h6GMG(+p>*dL1EOyVZTed6GLE*(r_*~=(%l3%il1cT ziNQlcQ6pVUzJ56P+liG^#_eteZa(`Y1=fFIkyaR(oPYFb#U4Ya9sVJ2=M0+NxmJAz zt|02fV*9gSj)5d#%P={vt0(R2pVP(qT9kSbZ31ZHLUUVjkkSr+Jx&_Y3t9cYEFho;B;@yx{EG1$*<*j`DQ&R7G*|H ziNnOfCr!GKRrLLyJJbnsH+_u0MVwO)*@5UkiRlzD-Fe>EI9bX>;t%4gDb}3G$-!Kh zWWG&o<9KdR5?F_)4Wv1b$lo4Q4Oe!mBNN{yat9@L`1r_z{qNoK;&i~3Cc#BY+c`>? z#CTcJV88qaP|eb?f|#Mp5Fu5KRvtS#CH?u!kSgV6CgD(}X5VYCaA%Hz2zU zz$^KY$GWMttql?g)#D5y`vqOmM;}(N-*o#bZFfe5HqG;vsjd@%)gLEA zev%q3{`_9MA=74#LNb;6q;lqo|M~IZZDV-naJ!cD43;*>C0|L8+YdHO zeRzl(s3r7>FTNT~3$Q;d5CV1umG=m-M7S5jLhd0;NXe9*L2Cd2`G4O zoRSr}MZ*pDa9K)CoT;E1eI3-syylo3AoD+c?5@NLYS4IpQ(`)dryG<0)Ro`ni48^6 zv(LIFyO9fEhfy!6-FM=Wc!PEk1y8`;J>aJoQb9DYKgx@ZDsOvNw;jO!C9ruV-d!kb z?3-3>6B;X2Ga+NXO`1yO9IN-$C3RwAB5!y3Z_UKmJj?*Di>81NaG7+C)^ zG2*k*v;9AX$NzSAuyU}m{hwW8&LGOlR$Ht)Fo=Ql6?vcBXFcXVf31A>Hm$CE@;-ZSdT+wAmf(r2{|Iaf zt|Wj**QbNa& zG4cgU0QYa@!p0{BgilIEOG*F(0zBl;-`3+Nmc-46eDN0m@FWDVAqI*hJyI3u^eobc zjYaq9-|GY5s0wx0R)Q=`wKA|kcL5Bq(xYn1Ce(lq~+i@7y z*FF&u;o;#C>8CYEAf6Nm&;#Fx7-9#CE-)vb1cn6sqQ=OFa}D^Rl?jf<(mwVWR073ulDZsGs@Q>^3)<+o; z`r*Hh=ULeELr78gA$V8-FLZ23digb!0e6F70R2D5Wbn{pM0HmKxccbW)?OfQDV*r} zwZ?w{^im^z*VJRVq=(`4 zRSK|o`@IkLwUx&E5ZNvdu*b*U1|$i1U8`&OYu5V9`2L&lRhIUfa`u~((8-1UBQ^I* zw*R{jq@!?jUBND`^|cRPHUr=S%_T#!Pvb;!8y%Zm%FVMG;hYv0F#! zh^w=$|9;1di!>ebim!PD8|}0yTR^iqgHXJ3ai+9ko1-HySM9o2hMTS zZs22 z`VIyWuv1QVSxIax$(h3_4SN$J(D=uT;h*gbmFlpeY>8Lug!J&QEh;T4)G5}RnDY=4 zckkp@#in#qFG+~q=V^E5g6uW&Ba46FyK`LR_5M=;Gu&3WxOrrV-W8z96XmYzkUKqX z36P~QFq%&5?}u=n7jj{Gi*xEqj-RL*kBlH~jn2H1E(_2B^d`Q@HEUwss$qo? zJp&>^PRxAmFZBlaZWId{oQ{tC!bt+o(f^dTJ1Q zy|assKbzDpR1WjZJ~n9>f9UM#w@peQr4x4D6EK1hDZFkas~B&wN1h2UWakUx9XaS@ zO;EJ{_IJI02=x^ZNY73*mb1gN#dV4-n~#e#Thr>&kAulM5iNe9(hL;yuf~DEucjwz z%Jn9N=EcL@j7tfPnD88J!S{|N;UKphjnUUG%t-0}BxhteV+d=<2?Zy=QLlaUWVgr5sBZ0URA;f1T-DyE+V-#Cq)PPwFRzz!Asd9;JH1m(7ScTg9_Q-qg=a>7<4 ziZgyQcC}O3(x81ZQi7DT+Vr5sfi0_61Pf%p6u)J~9B$0hVE0L$5lwk#Zmm;P4l$5~ z3|tw}d_u`fzh+wUlj4hvd7<3aZDXyNc0smPNb26hU@7uNn~w>Ng<-1AJ|#ZPN7*(Eqfae}NLhAnKiy3PrA>Dy`X=O1v@v58v%u zzc^(ARFEV7Tz5Dw$qT&b2*rWLih^o&p`}4$d{%Xbwzbn=`{Mz8(=z96(48FlPiu%m zhAa}3c<~1Ao7;NOj*9x_viRIdWHB@pC>Hxj#K#M%+@RFsTNkH`J#;O#P-!$qxx44Q z=NJ8b#Hr^OuP8f5%lVNq*IhDbn>~NZHh&s3maHE&)J*~mY*C|u+_i+*p#@{nFldf+ zQ{rRDqVkgfEtI^Nd5Q&mby|lp~LJXwyb(>N=&z*s?xxYdfv;68c%m5 zO2htmx2dSyt_SdIKaVsKox!=@qH6sK1yj*%A2Y#KfdGfCSjzJq{$3U4cSqWO;OnhHW3q404bImG@y4LXNrDY5N7@F!u+CaWR-pC8_al>xI zqa^~*2k~_x5Hcs4=w5DFNmr8zc_bCNkeVCYCfo{(RBj2MvBIc?nMx_}peYqJ|3S|n zwAM8yOptqH04sfC({^#PdiU;}pM04xEc_6xYfJxAF_GfmZSgEH8a6323_%terYmnS zsqP(Yx8jl9Ia#`MRdi{Z4_|SJr{^#j?Wx#D7Hhr}udz@bHJOQfK=(8{BB!h?XSIlr zy7n5~L=1JDm_5B1l5?!y@JA=!@u@zq7FqasICb{3Xs-F=k5ii95F@Tn8Jvu4yD%DW zUwHm1EZE#&$T1}Mmbl4D6(h!l6Ri(S#cdNM8y}U$-%N>4(qKu>qmBS9d)kNjRZ@|H zvxJfBI#GjBjXeq}I>Yq4?94v+wMLz?n$&B|80NISvP2farGi;2+3{X+I`3R6to25E z&v$2)CjIgEaeD2GdfL}k|I6A@?bC_R)^<9N@TaFrZU_PbnB0+|I=kA6qvYX+XIknM z_!~Emq)qhnB`Hjm)yC{rgYLbD>JzAc7ie`*9L-p&nm79n(@fl96r0qn%NB5`Lnb|K zd{P36VK)Bf@r&@r9h;q3Icw&ut#)9Ob*A5aB^%Z(ofW)Zd6;Gdl9;ZsiTr72v}5sP zzsF}ywop#mdijcwIj3WspT`QJG;G2uGuSjasdKzi*pFhDGOX^Ia_AnV0s@?!K+3WA z>I@D6OMTO$W6G)mp~K%1b5copQ9WLPCv3q(lz+k)dFqb0Re{y+@ zkwx#{9E70Iq}O{F2TeW?1=EHDdpc#ylfR_)aT{xfs?gTgo5|gBcfu(qzb6xqCtV6_ z=6R&9>Ak%m8O@5&r$37jte=i#Y^Mcry$i0}IcVUJdZ!3hgzKrapP+bFV6L}CY8LWp zXpro!KSAK~saDbXpw8AhXvFFxzQvs_w&`EeJ*BPQ>nN zfw-J1;Q2HyM9?Hcp)j&|9#k$&qkAg$@D>$cA3A_YD%AL2+^g%&O$N%1UP?;{Uf<2L z99c+V&91}v$^Ahw0!rq#CSSotaCQADEqwH$limMP^SjAG5$%h<5qZMz^%76+p9vNE|v-)4_)OxR@a=Qd^) zTc5ceG8GFTM~*FFt2}EI`K*X}tXsUoN>0r*deE$$LfxE3e;tV{tt`y(^zV7jzV*F^ zeEc1r*&$k}m0IJ97JtmTh%GCrCnGOJeyLL#rw7=Bh^%Bd*Lfcy1-%M&_#@SOsXcv(ua)1ALb+^-1 ziAE*Y2C>6?Tzf&-iv11NJu5}p&>DNp@i)?HGkN=8>GXz8g;y?evVJ46v{v_Ly;$ zRpKCnOR3jG<)y-AJP1RhQnz$qE2@&%bAE2FG*;v~Znzg&h^$=|haKa0u1Va%bCLVb z8+@$&l~n1N?$i2=Y^Oj6D!Z+KH|tBzN7~9J)m#d13a#vGboN?FX7-xVf8X>(XD0E` zvJA{7p)0!=D__U!CHFyUMAn!P?a8jh3?$Y1K6zYI1(4u_rhA=g)t=XT4}4l~f@s4* zDgsGe@l57WeP5;NV(OiAa347{r-h;&7zf9}L7C0*a!z45hzPLn0l^h< zB*WnfkJu&4Caqs0a{^_&JmlK@Kv^Q>suY`9I;yHPtFM0=)T$k|;hc^7{rY3kudsE} z{0g0#yD?Sr3iZ0h%%DefSv^?6r|D#6dMtYNboF(xn}9NHbwri-&RE8gz-ljc;@UV= z>|{*`t2D|1IBMIC)gW*;%h4(u%NDk&9#@j@pZ9R4lWtk1l=|T>Y=?iGDS%B?nh}HGRf;2%ASd zbmMsh>eYx0H6s;H`U*+#hgEiv9Bvc`cJO6I2F~?RdnwTpDFtMs47}9C%HTE5h>*2_ zxtz^=PX!cfXK4dx#CEWadM9)m&WkZ-uQh~R2pDk^&q+yI}e5{08>4@zG0u#YeVo-6O5 zJKG)3vLn2+Az1}Pu|$SrRU*|qT7naAScx!vXOY(o;$<0JeFSx?< z*LH?KCS;A2%9?y7~7WAm&u^Y;`*&l3BP#|ApZB(JT@W!l|;aS(KO z$V7%#czwq&gYjbLX8j8=^$WCdnTBH0MDl@G>vkvJ42Tn?#caD0vI$YSO*Vo@j?J}* z=+@c_B=Mvd+`pDbXVwU3n$^VTOXHT5R$3zxdqtaQJsyEDEQ zv3zfzP0lW6(L%hN*Oo5~DJ!RczX{Y}*l9lP)GlbsafJ8N4a$zOuUS+$nijo}2 zHE<@_s;dfbsP{&o#%JI?k?g$$iQ*-+#EzPT_HJHvmf|GA2a?PEYYoULwC5^hAh5?g7k6nye&1?dj*rwBOwoedem;5Kq}8 zqOIC3oC5BqFz8k}zps2h6&|G)Aj*({)MZ>O+ZD~_Z%}jAUOEDq^Pa)QOIdTI zIZKAi1I`-r<8z`!ZyT$a;$L1EtaGAegW~9&YioE`}C>#`w~5E zyid>;t1ujL+FVTpZwazR-yPd8G!9kRT2ILkIa}$^hC8B|NC)uG^|cc+s=H*$Q7TYT zN^yOvpd1at;Mv3N+rDm+u)CH2(u~|B=dyVZ`A){^mDL~5I*P;B2@H$rHG{a@_to?3ZNvtK*rmtvU{~~Jp8^{)n%kv%!xXat1t#)Tr_LPv>eq zCe#1%`7H3$O%s;1iTKJd00Kam9^Yx3o&IpyV-}MsdOdgbbjj{A+Ts<|184-U6;`Ff z`f_k{9;0+G+mbAA%)NzekeTaTPxT1DDn+zls^5ev>}UOVU*RLnp|J&JM9vnR=rB>k zM#U1!>-bP7#|N6@uxM}C1W&R!hNu?MfRV7oD+KfEW9t|Z=IL}0aI--yJJ^x!TxmjMv=*tKC z2Fi^`^z#7%ZMei|>Dy(D#Idndn&a&T3$gLT86Wa8Um}ho$(|$m1dlW(#M6vhUhumS#lK* z*Gw@h^~%ly`INkV>!FRR90)z^rVf`XE}}y5RkE(#WAn7EV*xZeh(;b0^ZP-G4~B6W zv!gT5L=MIBm$fsDF}ni0oP(tA?g~63CKAXP%0sYU@bGE7c3-Hwx(~j1 z{RrsTlrJw*fdYYc(HgFkSz+CrtOL#MM-~R`!#$!ro1FL!&5~ z{n=jlNkFD2Ws<5tnf5C4{1QW7Y6r`t(?NG&gBb?# z3(<~a77Az}pPQld4ogu{o{6rDZlg8j#ko8$RCZ04p&gFp7WVpb`LLmS+Bo@lq>GNO zAVNH5ageryp6|%64r9c!u*yzoD#F~8-c1b*l_kog!_w*xfE={KE-FHZlHPkmxUeY-S zJhT}lEm79Wee$9##0Jax_UL^Gvasx`t)Yi^E9Z?2Lm-3(N;lIq^VXDMu8VR{UHpbJ*2hZllT# zfZ(QriFqwhMpt$mPqB_nv@3yUP_pQT{VXIBFoF*r!4+b~t=3oxo&6Iv4zPRR^I#Gr z6);@kXnQnJyPk`QF1BV|Y#x1sI#mHEIwFcl7vj-;>9tZa#nOZ;p~niEy^uC}*sunz zCU~rIzP=}I536UyxJ3Dj(;CuM15;yD3t3+I71uP}>bIk;dfITCybNa!1X zyY=2Rr=R6etK>w><@O2oSOO!qNO=#~uz4r_o>r<`Svd?wy^$*9&|dm^7ZS@7DdoBn z%W%JH`K~a_>_CsI!mRB{VlPQJ4@gK!g_E2PX2Y(f>|O`Dr%X>79WBf5rV#frPFhjy zLWJTf_du(N7*p0LTiDaM)qez73`s3@HmL*{2c7Y($(^IjLLeUy_1_=rQ)20}foKV5 zwnG}d^4#+lC7%T@0m&!%m6L_Kj(TTJB&!XC?~oJ)NV%vO-U)$Vdmi6sDrZLk&k5t2 zJ>pp&8h8$5W4$D0y=Ov?$ z+mNdb_0nPp-&Gsfw_AT4TL!~a%zd-`4QMo%&cU8%-efG~FBu2QxFxBRf5Fz*4YB_lxMTV6;Ev({gF6NWR+j%v{~O#f z($oLn`$v_al#$dhYxAjM=3Q3^1y{7FsMN=k@P&(m#oVo+wd*Pc~SL=aG_2_-MH2vNNAMMVHXngjb$P2jGG_krE!Hh4J99B*I!e*J#O zUb}p0WABkC!6}dt*iR-58bR=2sD7;TKjfh97#h=$+2YvN~suXDfG@6 zf_Ca~`6>e0bM(}&KnBD@=e?Nfg9A#3LI1Me-U$Y6(zaxRB`b9Y_R^K1yL|=~R# ziFhDy*0`g~ArN^eeaK3E4cu@R%lwt`hJI(5Qe~I|K*vsK^TFfzAEV-ncw=yKML3y? zTTIbibZppo19FgJdWazmyP_rfWVoI4_at>l^}*7UF+l67+Zl=g)%56omC-im%W#dy zVS)R9AUjOT*9aP#SdqVyEDw&mr@dL$LzjDB3QwBoC>+6>J5)Xv4jp0aJk17FCGuP9-Uq)AH`48qS) zY&k=ULpVaAn!tn4pdfp5{epbx`O2-<5Jm7VAVF@i=Mt|p*`Q*+bhJXbp*X23_TmNJ zIaXj%@N^@ob}t*hI3fe%dNXSKQ@g*c4JJ9-N7H1^iqo|e(tALB+M zJ8vCzoX!fKwpPX}D~H0kv{H`Vx&$5Oe<8}<@{S9xEjx6VQ7>N8A`|&wDRbj;JiaKF zc1u~wysDGp;O2Ho|NVW+8i?wY)pqPSyh5*p`7atj$O>Ciflg}eUtwoQ0D95G^=sl`9=RQp~TUjiTS}G*^&m>)xF9WQqr<3Wrk>W?H>9Ww#1B zUXvlwz1inNvePck_wN8`GcCKTtrdm2cefW`C9|n=)limFJeJy;o7(NQr=^flJ=zmF znjDJCjz+2|$6u|>ujcx#*WV8Mg;YY)ymPHix2#Hnfb!H)6XDO7tCw1zP9d*^q}HQV z{nBxX#)|drpyVI>!@|dxz$2ZnA7C34*RgbqsIuo;+jE_JqpOqrr^i#B9HsZTNnoY> z7d248CclMjn#8wF2eZ#5KO|WV>8pw_bI`sYU@pEs8L^K+UvkOa+{SlfTDdBG*GDRp zEKtO0u~wWVv(Cp{Ut-$EoX3mcx1{p}FWH|)?)&bU&b{df*iy7ajlveF!M+_Smo8%4 zPHlH^AL}_yoo&u_He7RJGcx76&MP;Ym8PXQSifs~wz1R}E1hyB*}A=)x0g5^V-EwY zE-Bnr-#v;+F2)2vlJN(ugWRtJ;riO;vKV9L8VD7+xs~hlfo@CY#OJHloKz0j8y%mL1d=NqEmLF)`5uZQx-g`cQ5vL_HC#m2 zvFbm?6I=`4Yqg(7_oob4OI4Mya9_T9Yb5axWT3|-O-G%Qa-3WoTYGvL8+;Y|V}d_n zZ1WF)VJKK$SA$8Z9WeZw)I9GB9?7QfN z`u}xp2H4EWzGIui%+_*_L1wi&PK&-VAKeA{PYWqoi)~0dv)bk5Egn>oKb*gHS%BVK z-A5#r*z8)oxDUaE?Qo@?xYt%L> z{G$51Ly8pqf;)*4@Bn;Vlu}}bf|dffun;J*0DuDm{RIC6DVXJp#-B zjoQ!uCA{-n@KZ_N<4eF#2nPoMauNjYmq$Yn6#q-N*NiYL?tjcjKRouhw}>aO>-PlM z{_8#t?9ZR`Tko@P4;&AM++P#=boV46qyXSU{3lWnAUXjTf4Gl29t`^C_xI!*P6!L; z<0uGn@FdP@@Ry(74kjHB87R2mSN$3~@VDWw-8Rt2T+d%20(!hSzmEdHuQ#V6cw(TN zUp}!PjH6rNkf)fK0MkzIUz+|s6PI8lL?EGd0O@(Z?mq?izkq&e0r=~DTaR_=er*u= z4}BfH;4y*kfY!kvznX9deZ77}UB4z3m4x3wAi~8ZfIxVruyFZqW*+@2;_vLnkL9PCfKHrqMZ<2h#aB3c^?(UntC@8t~(Loh_NEq z>#BthtpSH3DTR9LA)YqS*AH&~RK7?6W050BHa>f>$FgkNrXDn=_Y9I0TfT3W?^m*J z{=m;=?+#4>+>)Q7=QOm#!ye95ZsBNB zQUm`Dd@?lslyJ2yy+@c8$lz>2>dHZ2Bb2zR?VDdRK~Z}GC|+Xn*-56?2e9k)ol7o6 z-$0JEh)}daqAe=SK&NDMX>T(qouZjYyC--RP07lw(EzS1Jozf@wlF$~5iWd+Xx>k$ zxOvR}yeG44_w3;eptMdmxIO-Rbr)g@2J z>sMFI9k%{kGYmcjtLL@DW3j@tdWy*{?X%0*M zyal%l25P>-)G}HdHG2tjq1wvB3S?X_B4aoGlGMduYzt=|YqG~n7d#&0_-@*Bg;;(F zrSx|fRaU>!G$?jjXFLe#lOmO*0bU|(T6D9rVKYT!pxT1kwi;N+xrIPEt@o1G3Guet zUo~mYT_>nxrUvAx@;Q*(F_*~tda3WC1D>2AywoO+Jrm=~`Pt%p?Ra{)Q?zB}exMK1 zNQwmuQ;~N{$DiEa-rc1di(PkFTcqi+&~*0-AtKBGCMzn)CqKQJ9@C;Ru1ij?7upt4 zCdC>dVC{$#^cuS93z$QP1Qggp8tN{MDC&8v1jo2W?%sVliCOg`{m=!_`}|vq@@WLd zq^U&?)H&D|2bQ;XvX7zQcr$|4w5?F>tf}8&&0;h7w!IEbPH-dZDb_ZfzKZXB)>-rF zWOZ4^D44AqDfjPb0^%aESjL`lO^kXr;=KGhLU2(u^dOIT(UdtdVbkHgdyo=F6cLGC;R3F4a}u-)Yk)d zJZ*+GC{wGRx2hLXo}U+UZpwKoEr(^NDwKk5eeQ3F(8bF2KN|(OPfwfTPpR7cqgZdw z#7rt=lRU8jx6I9&ffh-VqQo9M+*q~3xu_$xG5_~-75&JUFt!JGfCqq%C*i=d~51M zZ#^I#E^p<}CAG?~NtmIWR#lRBr>KS&&iHo&XYjqm7KMpq137&_WNpZO zF3)9h>inE5@;!TGyH6odC;CYyU0>43wEh&Efc0Iq;U_XKZrcR=^yg$Nq{OypB^=o+ z%B1q|3YzFN(K{zAhg=a_?l8w8AKRrff?vZ|dbD|SFssOJk_p2^a=JQ?)=_`o+s?;$ z6*g2N(J>yG#HjLTtpq%e9JY8ax2Yf8o$6LeRc+TuI`I-K!@V<6Vq{(a+aeAo0+jW6 z);ki1!_6XzUZGOcv7qHERTd(dWH)IRqN|jLzucYO##7mzXUE;?H~+H3Wku|ikqMqL zqgmoYF3N4AH@e$fjU9OU{ll~@Hk|!MJ&le(dt?t zo|Tj-H$HaKOK<*8Vp|JmDN-Q@Ac3J;$dAv5{N~-T09+~zcIg}{?ynAjCbfpXW~Owy z7a1S%#QbNRY6!rcvpipjB|>Q#nuRc!o015GT;o!uuh4#7G0!uj?CB*0Dlh*TMpKO?HbD+hgPDP&ze5l9r=2 zPV20A3EaAD`CuR3G$#u)15cvCK{z7>V#513&o z<<;D9R;cilMH}6%>%tL;*&u|%C zXW~<2Ia*g%qD!4fvF96yYkG?MN3UeejXIamNRc{2)!e#sH=}zLtuI{a$b3ufQ(IaR z()0Sh{=S@MbV22UGnjQU+D|3&l2gUzV1Vag&EYVQx(*P3LY~-nT6}|UE}9^%>k~E; zXfyTM%~>IcxW0U6ap>F*hXnj)5HHFyAmoQOkuh%lv z8ri+S_38Aw(RKq*(JN8v6eCL|2v=ZYfb&&Xo2{%_#aVH~d_=4S`gn7w!?o-S0a5)J zhMb->T9xzIMRpO2nE5F)Wr~;Gu9zLZvX^CxGwe`0Wa}2C!FHA4d4#g|7po-L|;H1 zQ3}_VwM1$s=bmeQ?6Z0AtH_8w?;lWgY&X^rU|R=aKJSzfSSYxiQqcJ#7KoH2+i6Fu zpZkm^IKskudUy&>$&mrk3P6`SIL%Qvk(h}HNj$`I-Vh;tc@9^eb@Vx}^R;lopW!U) zi$Qe(;jT`7nPK2oOf%j~V)nn7XzVx(n6K0YS}>b@=VW#W2Yp1KmoLA=hbElhQnY9T zIEo@*hC<%P%Y>30JT^pc6RK=^Vz;Pd9K+vGSaiXsgo6&|U3z34O zvEwjtRW-Z{r%Vl=d|l%m=sYg$vVTdFDqY3MNK+bU=2RemT{xw0v5fI=obx3f^{)1Ag!dLLGd4BswZwkreMjtKhc3O~HrVl@VTpRb|R8TMub2 zt7IIM)5XKahKp||bk&ubfmuV&+^R80f%vJt*U~NN&Cvp+K|{*O*%@`a2&p3DV7Jqm zCTO{D-2T!L4@@dH7CjO@U0_Ro@HOcaka`f54wyxDezxVtig=-cdLgox!wYp>tnoGP>nm^gpA_l#ZfW{Nn)egD!iT-I!zztiGqMVK?dp3Mf z%T)MmZtk{^$p{$v!AI5V&lMBW7@vE{GP42VP+4SjLNJ~pLBto8 z-@G#eOmF5}2MR^zRHC<9!K0One&vY)?j1>F10j{j1x48Lf#{)%ZvtXSKlJlDf6}q@ zS-SQJ5qGOZDh{{dTa%@}e`y9M)k z_-kz<@76Mc`+|24JFI53XlmV6?^r<`RDz?0o*-r156YvUiKeeMJtQU;lyv$B*;-A2 zjxa#1c)cm_774Ddoyg*(S`mZjF|MdY2=Zb)V2*6rqUIZoD>`k{YI{m^iiv6s6Bn*S zN>RHRi|>`p*gj6ugM{>>hJHEtNU~8xjL0v_H^w*)E*|$v z!L}OxNw92Wdiwzd_R_B&xb&Gw7ty~z3eVvq#MIq;0# zCl84DQS-E0k<1qP{#eEY08*~TkY{#K?Bj7Hw=HYu=F%}2w_-Z7#)|EHvI!Tzf@fYr zY-%Te+vqysqqOeQhgt;A79^%sVu`8-Pbv_utmp6^R@aH=RO`hj-LbcGl5r-pAQ%!I zqiWkvESn5TT;W68nYu-pK9VWyV0=&K7V`RxkwNa96n?i@a+JBuVzVeXif9Hd6V7ua zIokS#;;FrBR$95r41wr}l2I>YPxjnVowqWsJsL^^R0n$_7(;3-wXaqkmSeI0 zRKvnf)IuF{TH?Pu6bp+~wr$30!yO^~Aa4{?Y)yJ`(RE+2CkUtT!{hN zw4KvBodVC^xe4A!MOM|6&&g__(af+P!;3P*R5{e0-(DPp-?F~B+AHFy8Go&)^ruUk zhi&)VO~+rL2FUNIhti>sDmaoX<)Se}0K}M29d9)1(^^Rmz8+{)8dJ^wE{!Vs+|3{2 zm}Y}d=cTIspxi{67O@ky&{M2_?yx;>`-TZ4$uguPP4@F}W}VJ6txCJB=^fw7=G#M* zViS}^e25R?Vt{w(PyV6iHkXMbb)X222f0}7zFLz+hkuL=m6$Kt7xp5mx>zid&(o+b z;W=t*%C_hB87Mc?ODRK}Qzd(s|4^=olHWSh6r7<=VOq`0ii@<(9z#FKnxYLvZRS~C zMy$4SOz?JDg8D$GS=X~Q2=pNQE7XsYwav0b6_Hm)HZD;8f)NgqYQXQ%`DmBE-g5aY zX+B;><-C@kWs?Mf!f{leWapK&3w)loJL}u|FyLHcgOP(rgzhA8-L1*`6W*XiWEE~){*zK&8Q~C{10rl2= z`b%&c5+v4)?eL^Z%JZ(>w6LvYq_VYdM36WJG+Ur&;@&T#3a-J_Qnd})+o^%BRm40{ zv~A84n6E~NCtqPx3N8_ILv`-GZQeL-OX?}S2%V=)gIHj;;zhA;eG00a@gHhQ^i#=S z&HrKVtzs)_lWjpWGcz+Yv&&RwW@hHHU1o+dW0@JtRAy#oW@cu_yZ=M#J6+Q4GjlYW z9<`K8?aX}H53#;j5wRk|_jMuyZz&w94_TD{aH;s@2xJ+WK=K(Fqk{d?ZNVD)q z^7hQxwIXM?!bQ!=W+!3Z_Vr};36A#^!hEp+*lHVK!vveb-a^mW+_59DRD%PEx>isU ztt_f}#>+nn8XUc7m^FKc7yH&b3RBHmO>XwZw#(R&5rb_8dkZ4LaBt_W2^PigwLF=_ zdTrlAB1X{PTfPMJ9|aC)9;sWQI&ZS7c5a%m`L&v{mpH9MeAEB>HUF}^%o4h)u`h;^ zkMqJb=Asm{*3ISinapbo!96|%M&QEEGvlt`Kj#27`XeBNbh(gdh^4Pz@a&L4OW)E1 z*f+0`uyr0y$8lK?19$|SN`aDNs?f8knYI@Bz_8@zC)hq$^QyCEMVl8&2Vq;;5D$~g zIz+sC(@m)mOv$iA@rbvLUMU-Ol*xicwm?VZ4Tiz_`51>V9}?@)mM;3xjlEhVAMxN< zA79UJy7xEm_@Fx`PD8*@;x*IXCFj=+mO#H5vkoUuSo1HzHY}M%^0q!Fw6DCdf<=)L z47G4KZGy3su$9%Z0IfTQ{wxpa?~0e7(kmw2F>3)9A8lV4dc8^FlCZ$R3Vv*7q=A;C zu4kYa|9uiQDk)VL)&}hOD~EKbM4;)QKf=3pWsID5HanZYec7X5n+XCK1D>I+fCR3* zjkO0?mR?FTt(AKHUT^bP@ng9}YH?IK;x9}L&(!ozuaM&S0@`_CM+_1vquSIGP)!*J zg!bs0J%^GMI3X?ie!Ul9o@Z$Cv$u{3wpbG)Y?;mQ9$VwZ1lx*k8t-wZUOtq3>1(%S zEgF4bPb_>)vqOGYaUD|%iP#RxUUf4u7-U{0D!VxAM=(F>ShPWYvWWGokHJ-puS`|m zsWHEGheSqBc5|OfbHjqEycpdE=3ts`?S(!5Ku;<@46Q zl{{Z!N)5~MKYW(oZqQ(0ONh}D?Ykq5$(KZx20&)2(-(FY=cF`MB0$-ZWd9CC^3nJF zehDi$#CeiLw7~-*Upg0ch$|5OiRz;zE8D;9|HLinGejGZTlwm7*n*urX-@;w6PV8g zVu#P0No~)N0x9CVa@J7ps&_~V&y{tqFxtRH*)fmKvvK7X0QNn49>2*1A9lg-NqPtKUB@VY^~kFY__BKdRrv12~kfe==K<{4MXdRabRjq|JIoKDebXpC9^19U?>~gBxwv(7o~wr;&TCR z_&k&~wW}YE3gfhFMYDLEY0cF5uvB!8D}ELas3jLbBC1%D+(B3|t%gbV-V0BevAW?e zFC_#zYI-LkcDv*z%@TBWEP?X-?s0f#Z&OgqTaI`^EvNJ+d(;z3o4RN9a`vOsmf0)S zJ=9gWsBJI#aB(a2OKp%M{5N=e@*Q@=J8RQyf=l^Ps)j3TrI)s&PCf_z0nWCw7NvLh zyX_BHMm2~}WIC+*cjub?co}Ok^gWWj=_N9J$i3TQ1|u4XY^>{vnc-h=_IROsz4?&WmOx;KGT*KNxq7v2ExNjVWq#g!n94EorETDeqIMa2 zKKrg-t)9837Qj&ULBpp5_znj>Bc^e7J(K25x5tx+J4Q#XYgu6HSl9b}+Qo1Pc76$r z5ie`^dCH!b%o-Xv7qj^~`^X&E)SM#-X#V_ET($LZY<=k2&S%9x-w^6)@L_Ah=oAy4%cz;P%${1g}k%9Ud)$DDu9d%z*Qb!sx(P zch%`eV~sj^$*nHX^A-a`O>}cf&D6OMCcCDF(zGo zLdb{G_qPF9;)kawh&;q7KK|9VKyckA{iuIa5hx zEzVjGa|q0mL-3VOghtv<`p^NDkQ)7D*Qy2jO7-ttJQ$t%A_Z3@JS^FI(w6;Ta zcf_O>(Ee|dAm}1Bx5SQ1wyI_Gdc@4@lCe2R1?QdmG5P^1wum{`w@)4e1Y_%sDdS&M z&nIMhBqsF6o7-IqQwug5i?=QqtVc(u+1?S2X_TXC4=EpJ>h}lk&IEMLPm3-H={(jG zL#0i{7Z%BEH%x7EICTYj^0=FUWbV8KFEqg6|7Keu@QTq1x^_c^{E z@p$FJrdZdAt*ogSd#x3^HD>L3YPt zlp}9_pGb?FD*P!kAdz?I!1$IDWcr=OVs` z>xMp#WV-__u5+M3b|i7g%XkwJRf%Q1i{!q}B_1w8@DX`~^G2CDzEEu&8(3ede;2Y9h^C{+yjbn7wGJek1Ym8EoXn+TI#tn$KF zSbLh;tl#lkxNF-Z{oVUvM0#-LBDWV+o%7&@Bzpx_tvSYXWbhLqGV8|{qtIBH z#vf3_!u0J~p?$G2UZNEwDDF`!X_Kv)Sr=brtJ2zrVL~ zJ>R@CKYM&dvhiBE(xS*`mhLsnv710?zjESUy59GaYO=0A%L0CZ9Fu)TDWK9 zYZ+}kJ3&@0n0|evDTo>r6VY1IRVP?Um{#eHe4_dF7*tH#d>wkj1nNMY-ALe=m(6xv zpFEr&3N8`DRXJ*r@~uj)gFLqFoj}}er7n~~QknVlDztaWH-Dtq;A3I2(td^U+P!!@ z+m`Y0cG@3-IPhL;?qW;&g`n+1PHxQCXB_wV_Vp}iz+7yktnyp0hkCQmqE9nXk`w(* zjSggG#pQ(2$Pyui)lR7sv~OY352r!f2#4~wB z5l-f~j}+%L1KCj{aJ!^O#1KwWxSdKS!H?9rz|j58k__9v2pmtwDkDjNQoOrYsoh2A z=v(8cB5)D6-Eg%;Gl2pssas#b+hONozRtkCX`m3EP;&SCXCn!Q@<3a5X<|v?Wh1?WTDMoIiua ztsy)McsC$@2#i`rLzYrG5}CT1H&n z;lO<3xwZ~+1wK7*h$xfZe5DWOMRG&5$t-ehWcRq3hz%B8tD2PyEpB9aLQJ|%7Wfk` zSpFUtY}{=BI0s9Rwa;fl3b}lPxg=Klp7S%tOBE`-Pk6*|wJcn%o#KH^3i*~<%i(* zbgheAnZ~kevFE3r4xJTjou>2r#n+{U(t)~mz$NOl|w3l#P#_I zf`e4}nrz{Nhz~!@QLWDEt5jz@Q0)p1*I?s1JthsqZi@>YD^m!;v!IJMCZn>%bq6PT z&E-e`{#Wf);riLb6=`J*uO*Y!)b!h@J#c$*f9m^SSzoQ%QtwSRbs^kHPt5_e3|k4_ z&(q%^7>3)1HTE_;l7FI`l5$y zAM3n>}^~Iih!HHm- zuE()WM3BSKW7*pY0jfV0t}x!9SN;|5jaLGPl2Jz*!=#k#kY ziGAccVPl3Jy#w)A_{VqK6Nq1Hlk^`?^1ZX#+wY)YGI*hXGM~Sn#74xy#rlt%Pon%^ z$7=uOGunn|;e*ic%vhn|*t54dE*tG6t9o@w8BP>3MHGbhhtpJI8CAf!n%ed|`(63q zV)4|@tn6XSY&###-p+#2``GOG(i?Ma-PG2DyVcC=Tcy+d-8XlXDsSzJHL8nQ+XmZ{ z>+bYMS&tSKJEwP>nu~n9C6L#!SGPwuwX9P|6{l}abH%^y%uv=Y@7-@Iv*CNx`y0!; z8UW|&NrMN!=Ik5%)1s5AxISPIh_64&7zR&KKT^zn$*0<0 z@x+b%J6Uc0$%8OBoaX*Zr$^rc zBi*1PX^|%=;BEyILm{lx55a*EhKA0YI3$^DPy~)10?*7O=(eRkA`e|9a%RhLKvW;dCdu|MYiI`uW-el8PGV+`F*eaRHbFKvfn{b+XF4P_>oJ_oten8AtjwfLn_8+m zHfLpKC2D3xYG#EwHa9RfM=>_XkXowCtZe-^Xl%}G3^1&84r7chX^c&EjBS35 z4L(&GXWe}puv;0^>w~G%F2Attu05NFYt|vT3#}B_4cAk5RT%TbK~IhqCrdA4OYn{| z(&JCI&-V96CkHpjKW_W~7fL}$<_|->4E?vJFQot#`tf>?i(0P6k0hJ5Io5U!>->1? z$~&#v*ob;Rw4BcGmeNs|aQ1kCw!Xfv>tSib%crfqY{kbf_iRFBPzlTU_>qc@u2g8&;z%mxpu!k%0ka`8BpR?UAc8Ok2E^qHAOH)704BpUXI9*9bb{v z)yPt8{hn)ve^nbc%1hEU^O{=fW75vrF8EIUV7R<1*?hL6ulf&UalbG(sS$oHdQPqSykJdAbX^K?H!WEPno<{ z;L+pmBGN-O2m%Ew3ts|-1}cEcHgW=j1xoXa1Qmjh^ArN6(xD56RDzT&7zNLz0QGaR zgv!Bzu|>zqpao(r7@P~9B%*`h6~{~^n~L*``z{U=B97S()oVFs`UPu(3h0(8L%4<6 zkgIqC*aK@KM|_~yAr&mguD4m6u*!{tunI6i^0aEgp*&D#q&{}T>4{^St;>2NSf`6}&=ck->L+q)_>fA`I03~!*rAX4dL z=|jiu92GSt!x^%CmF5&@%ptl+9p8qBhIh_(UcbMZzd%f+ri>x<6qkQ=Ko=suG5fHa zBmH4YY?M5`qq+BX$~V3z)Z%4Ey`gFq@!O|ZD(|wMTycId%s~EpgzCcYhKi0%sSD+Y(71FShV0#3mo_Iq z;WmmcC`c$3)ZdUOK$6G;{d+(dKy1L+kbXEMkA5HuO&TzW1qiW{DX=245J1N>NJ8vr zD>O`8>Of|aF{QBC!WwYjA{khua!7$m?<2wBq8Pp-hs^#Q4P(ks1UfL}3Uo2=FB&+Iz)bva$!*cBS4o_rBAqM(A*(dE9ZDIVZ9;7iT-T-11uv`@moVPOCxv8YF|dT7@?oT4 zSBc-D!QrXz<6%~2)|?&Gspq%3ub$`Sw$eQLo6PA0^tB*5>tKA2HLs)x0d4@S(*@^k zhUcm9b}J>Wo3R$k$8_fa(_8b7d^8U!}a?%Xy#vjw&0NW$7d zr^VfqI`4CCBjE8*IQaXQV-6~a2FRhl{|zpynMLI>EAQ>`2ob}*Mb><7}4n0k6#%K z|7uvtwq~vAptQW5uFDGWUV3kR<}XEP-%2=dUPhGt%O7y|Za8(Mn>7sBS&h*@o4zQ| z*2~NAIZfE+TAY^icJ)&K)N`pmF0omxbM-~;ZHUEy8a^q)VIY0f#XmDNxPG~1``KHz z?kb#CbDW;Z2mfBI{DdT<|FUu?``UeBpSYZQ|LneoTVlYc!JujTts(dRqm3Jj<9%W) z>E^?OO{V2Hk*cbC`mCdJs?V&?PojOVVL+w@qNw6CUD~4m8>bSg^uDuKFpU;ODI9$= zGt8Qic9%&>DN|!`bsbk;K))~!><`p^Kz83UV3F0RL2 zxZNGXk0EM%>n-R*;UF$pV8jP9R0AoUBh(4dMOK4DVYBF6z9Bp@EI3sHEawK#CS^bOKf(SrX|K>lk`c;6ezV-hptN&NR z|IuS67?9QX&SC*%^`WziWnTD9|0b)?``!D#%z1Maa+<&4udM!J-N6e1VJqohS^c5G zPWVW@kuApS+Y*I8VTSAPeaAl`W@7(^nSWvCzjFHjQ<$NREz$ZDX8u?|X8M2NXW;(M z&wP>My4$SECfuf9B@o&@yuOX(|Jh1dwVGPF(w-R{lhMAM%l}xISt#hH>)@7BzyEBK ze!aXhqBeVW)u;E`u(lGnUYu?-JGUE1YM*xFUU}B{l4Wuxv5o}(VEB0X@L0}wFEajc z_`}l=K4^S%ZI9_8TW?#G$@j0oV;r)zQ}Mv8 z;jofdOQGAnTCaA5Ku7fO-NUWM<|DJ4cK^M$R_5imkgBQna_%aCZ?O|{NOI}d7Emqt z+m?MEpj84g`ejZk9YIwJ5~oCQxxFkQAZ|S~xghbj5%3%$ zmmZtX&K3jYs0%K`DR!^~nB*+m0vyG6(FUFc-@=vG7W^pNAd!1Cp{};%lz@|mz`c7s zx6FW-JY!1_-4R(pD?qA*dx>F#UE$rst@#H%cT*3y@b|XF-0ev~K0&!yt-|@;G&s{xBSdOyCpyP zYxOJVt+^8Zi+c?}=WDJdCEi@4*^>4MXYE+>(jkg7tWWyKoXfulDcV#kJf{du4lqTS z$TmD9E9`(WSYkE33%E#4OKHgHkheOdCyGYf2N(Q7wUwK0Y|&qm3whDc?K^&ej%ewBWJSzMb0|X|HsMM`u|;W zhU&YQ*vNhrbW0?X5$p%)84q1e#&8FH=zoe`4NzMQIue*5R0LECZ^w#>0Qz@|>!Wwu zuGbuo5MbPqC(^^V^kb`Lu7{NmxWFCBn4TS8zX~_PzbnnKA9O(*J|UDAgHRS^5pxk| z#)V`Zp#Wz{eaV2zC?V>cLQ2|$+el=;ec+;b?EA|Q|b=rIyBsZ8OWRkM6Q zvBtRhK6A~njovQseZKkf-18_)>v3v3+*-@oJ1S-!`PbSY|L(3Jg!rWC6=G;e@t-oi ztbZyV|MOwy*~HWCL3CD*tHgf1x-rq-ES3KEB>4fx8^?R;@yfr;loaY*7w`?X&}0}% zmRu6+tyfw)sSLG`V1i6smElw3UMmqE$g17n9dX7C=Pz1_WS8&e<+4IPdXGJ!iYC2n zUy8iVAG3p(!~ZRy3H#50Cj0)~+L_7bC90Kn_k7plr;D+0T3IDW@oo{zdyzM%@W^v~ zp=mRmjP~bWGNp67|B@-eDPe2T8KX7zH~0-JC>z?r8d^Gj0sj%mhJisjf=-7p1C}5a zBCeAY3RpJYbYbKg1rz^VQu5Mz%(&vw)Ws70m!r{8!iRB})Bv4?!t6pm@A5b9shl)5 zZ^Ym!jIE?h4Kwy)ns{^fcf1(H9_Xk1S3vVO0S)bU@4LSOn#U>r`u_}QaQ-8p85s11 zi_99`BJ2h#4*Zj!`9op(e~CKX^~S4Z4w=PabZcvqiFo?-g&~CC3Zs zU_zt$1_W@tqZaR06L!Mfi+xS?yIKp@F2rHneUIw5hb|6T(iQhs;JJm;1YSQ$mTfpww#xSyfaPue~>BGK5TNnQrl4< zkgB7l1ldy^B-nQ;X>Gt_lS$_}u*FAfHP9RF=u|KltyO>BgFa9ok+_c2m{TkdutZ|y zf^4xK*7NJpa*X8Ba*k|I<4!cmNvjZfhK;7)be4IhzXa!OKXCW|Ir-H;J-1`Vpvo|7 zxSiUpaF{HlJ|37kwF$;#I>NY2R0~`5nJ*uVvzPVji23dJF}tS^NvxsjbM);oO@H6v zG^{<9j4H$6h|8)0I&}S3oDBNx6j1q7E(p$1Z~T*0Y5cjmwGVzH^NO!y zI}9BlkP=!RptmhQ)UINTE7-W2;xED4_LkILo^{806nqR~wj=SbeMLROsjWg>G z!VhjKe;!~nmLhB_B)wm{K6G*}e|C(0JgPo)HZFf|n0~(Uyb2DTedg4B22Ok+QoIT# zE`Ji6e1=lIb~1Y;7qyK`0t7MaAI-beE$z7L9%(ZPBA4jxXzrvT%o|yCy&rzMcM|s7 z_t*W4F|yZ!l^Q1me**O%WCH)Zpyu@yK(sG5%#hj>fG=)Lyq&I*{P_fmTDPCgg&+F< zq*}tLGy+yW*s*-c)cgCVzI)hn(()+N!)$P*J4C&R6LVcxfw%5mVhKOeg z&<&-m4MatY7qzjn)yHf1rEiWa(N(`SzBZ$bj+?3W{ra~iKuuC$qnS@>b4 zN|z+}n+0qRLkK#Dq$?SS4hXXA6&?tY=n4ZK=w4-1o6nEk4;~o7uLz=~e7*-L2O=35 z((eSBd7h*sOe;&lT%H6MHr%I5 z^g|6#8GmL3Yvd4{ya_u?QAr?u(fC{MqePETh;0>=`2@_H^g2=32C-MRo@ zJnO>l?j$eDE%L#RywOXm1^*jRPdM|vu$cP9S*J*6N9*Wg9y>0G>=({ScPZDWkg_x1 zs@l)?;g3htht8^+&-U?;M~2tU#pO?7vrovRcS4s3U#8{H+_4Wt;#Wbo<HfSHh4tj+{O9VZLb`(={Z8#i*bo55nv9F9rRAL}-l|@7hhn z5M$=fE2LZ6+7!dHVp!~JIIG~9Ji?aQ{U1K9x+tLOgqtzNO`cf#5B*Nm2c0uJ*KF;m zy_5ZKgL8wHSo;0%gkv)!yUz~pKMaUXertsbbQAXSsl|0&~7hgC^6+6sm;Y4@F4K zj~-Y92*K|W7l=S;iyjB)q%^tF9mpC87X%MT7G6Q~S1_;;JRK+k&^)P8nOKN0d@nnn zdm>Fg`giHn9V1QR{2jO`91IbSer=&KBQELoC@@4=mKtGWb3jn{0Puod05^xf8lzIv=5_pE7E8K676|NzJksv)TFTt6v)0j=VbA4gP1q;2@DDf#scY#*YH2b?8noC*3E{tlFe6!k1sSAL2?PnkW$26~kM`xb~HJ_rX?}Q=`z7{o~xC!Q#Bdd`vqsMBy*}MdKtF_aa z#nkOocUsfZ{+vcwyXV5ZXNXH;zIP~ko4Q`_OK6{<&f&+3e**O%^c$S)|2_Ksw><&? zK_AV(_oFq?%v)8({w7wnQ{$Sf&PueQaxm;8_2no5twtua&41Lc(v=q~Fjl>nY z-nqJ2d&9O6F!`Sag(pBk0padkz**{Bx{1c!=!57w$G;V>bxG{Y>iGR5iGS*sR6l>Y zP~cSc-R^zpVnF&!(Wj^OL@$3KkmLT!9r;jaiC`N`X7h2t5&HY{OEhBlTVa)rJ}2SX zM{?TgN>=NIg+Ih@_xEvtkO@EY<8Xbr=D884>gVI+1WUNJaN9^jjc6mSZKt(>O{_zQ znUrEV=&H)+dB4hUL7Ax~;b#2*d^TUyZ*r~=U_po~+(Yh*zv=R$jezfijc^VV z#CJfI4S{aZf+)MuB=MByd`8)|k{WTo(9R#-pa*1qEj(%(<$aMj= zn2a12H1lznb79UR#D~%hs~HliIW+%%K$9UJD#V58v?h)fdS+pc+Vnd17PekFup2rG z1(?jwS$?3#YNGZj)}0_oJ4bPkuEC(m9C?|y>nL{0EQd)gcR|bJ_kyIy1U+}b#F}n82v60s?i%VAHwn>>2Z!?xl)&$S&)Sg$m{SEWdD*@@kN6nU|4s1EF3?Qaj zgC4y>LqKVPliCq(7bs|2o%4aGw6!6S=50GH`$O5_UJ1+>_;{=e>`(CdgY1KYljR>T z$EkGN0a^*#Z_)pfg2xVU0LRlrnBc}bEj3sH+Bs1jS|r1Tg%I9f?;}OcT2FxQusTyc zb}0`o22bsZP96-*uSw1AzX7D+rsfBS9X|lFkA{|v3f%093S0h61o^Xi`(K&(%k9et z+KZ8hS#7TK$4aZ=_xw_;F$2ipFV(MZubyg|gNj$n+cOyh1LIt=o9WkkQkz+#J|#sR92hp1PBNBzR*{J(VI7yvn}Ek}8Sg#Ps8XPcll z$LF^J+{3@BaXXDrEoBW2qK#EHoo)d2lXHjRY0cV~h564+a^hWwjFQyi8}c@zB%8c? zG=fnykTqjMzup2k|3buqt|1t>f-Z$Fg$YDIW+mHG_MTEZkV=hb7uc2;{ozFI5h%egP zc6E&1XnxCG`zCEuor7*yo<&Ccd41(M5iFrj*epayRSL@sY?W-#;GYcs51NgCLW3Xr zm%;zb;Qx1n-~JUe{U?L}gW%$y&)^-od3DlemzuC4FFaYZ_zqi*4~);GBMnCYdJEap ztiKu_UWK-;X0r@Kh|~04tDg(bmYP~RBMc#9F`)m_^;PLVRZe`c5P3WT=uw;NAct1f z^4mBeg7IfK3}N20wEk*`BY+>{5;P< z9eySf13De z+a-0>1zZeloM~-7rmCPUSzd}&2@3rF&P`FbLtL?K7hOwSyp2KFVH7{9a1LFk?MYr;3PA zY2up__H!ZHbD_&rEGPmigpZs+S%8-c`Ev>Pa|!r!3E+n@;7}iu$c&BQAt!Vd7dQdD zQs2v0+sj|r%jek3pBR?Vjg4s`BZQ|Uj3Oe8A|sTQ>G;_{&iK}Q6%!zc*D!7C1{i<+ zXbrB8Q3%c zJO|+uD#HB~{+mezL+hxgrwya1TA;^Xkqg`y9flAj(i{2MgQ~#6P(qqZ5?a*)npJC6 z#9C1j)Evj%s4%2`>36ketH^h7>m+)Uuq8)un*rG}h4_Udk?tORTcEGM40r>M3#sb- z*%d)zaTcUXVPL&2`DK6#z=Hg-O&uU6RNMpoQOg~sfJ-Xa9GLiOpo0CEf&8qN4A91b z=2ocJ6tVIxAYIrdsE)p5Ob0uia+KgD%De)ubQO}d1S0@POA+qzCXlQo zyZYh@&JWsUWuJ3+ZHMUTALrK~L9iU=-iv?_tly>yQU>JXhd>Q;=%POzwV}T=Pyz~pOV_Rp5C;f&Qdk$#8U;BNIg6YW_?M_9Vd%JO zbTUkLU@#@WLa>?b7eDjwM_+)zhDy*T0_A`q9QezFvVgf&yI2ctVtEk>FA^zzb=Ab0 zc{3-HdH1j956PqSql@+3MkH#VE!jV*g#7o5Z!|p=F1!<&kg~sx-*# z4|}?eY}pjB9)Tg+A@cJTNLo0nE^jV@h!#SHbfwL_8An1m)sn@)B*^ov4nufpL=qa! z6`%*5D0^qF%KngeT?ihIxf5{Ro;DqE^XNqShmY1eCYO{y5kb_ z0etYX?PYRQq*FtxAo)Fn=%D+_HM&-1W;PjgiIqPjmSRf|PC-Y)8DfAtTW=k(-O(l3ozvDY{sAIB#?XpU1|IC9NRvEQEb~ zTR|M+?uo=qEQy4B2?>FkzA7>X6djt+4J?qArM3x~a+tC|yirRzxbM(`7ek@?Y^(FG zDUN)TVkdK5}Lg!v(!Z2n@(@pzI9R&qYY3mqe2`&;>~8{EvLTQ8s#pr| zkB3>lAJWUdkip$JLQkLB_RtvoVf_siAgIAVe;z@?`0!Fg)-#k+(KERCfNIodA1 z0Oki|hSoz-7`%iKjp_tshDXGFg?ITIgk@EHwVCd_{pJJnmO^_%k^Pb= z;UV5P^|&vbmW2*|#w!iy2e|l|KKFvdmv#b{HntPofktEJ?CDHbYWInlC9!MbbSDML zwYL633Zt}GM2Ha zRx^AC63SgyGMFI>45Bg{jFI5T@)mwlSv7iH>?vN7Jw~!YtU(cTj&4s#2`0CpT(w)qMB%7&~2-1 zQ9WRaZ&mht2qg&aNGQ!JkEAm~NRveZVGONEC@j4@USKQ6+-i6L7rv8~4A%h@rbXC> zKl4)2N#;wLr4uF;d74o&r&46t0KO4&5QYgHz7B$?oNoi{n-5NJ@%R5Br(H7Z@rarBaVFLwn`k~Z3ss~73yo^*s)}nzEb#4@(2^*lJ zn)`~vYWJ$bQhhp2Uq7FAK;MikFBhl{_oj5p{$1FvBCmMO%>1CDG4Glbym|g^R6@zp z>Q>iVQH3b!xFMcp;05!CtQE0Y521wK=L?4eV3{>Xg}iyy#Zb?>P+ej?MEKd4B{p*U z&lWo}3sJW66L+xel|_*(xjIuCwyM?x^|fm0Eo(D@O5WMnLLG<&ddb4#+b5L^ZLYla zRw-$>)jQ`~TTZUTwDH<|@6%M9>+c!2Ub{;Bwpz=imS|kn6N;m>P^uBXl+%Gzccvw; zIhxLd?9;FMa|@tS)xNqUaHOHlYx#hJZvaHZs=P`|L`)lqTNKlkd0MTK5#-!54^82q z=7G!s$|e}(FKbv&G)kHhj=-t4gjCw%HDn5z4MiOkD303d!Ay~%26~=1-qCz?{qxCA zYL{vh2)p_^#xqu@;4k7&Q9(W2ccXZ<$ZCm+Twk#>^4ce+mA{gpc__VoAq|!b@$yxd zRH1m`NGMEyDtXjDSrk74MJZ;*AWH`%_ z%9w(vVBob+LRQ3DNX;D|BOJ8f#D7MLi!>G#J*{9^agN+^BNxO#2b}M=Pg?7^keoV> z40|sJf8G+WRosclKQBIv%gSHDdYqaeb77W3i+3+hnzMPX2;ILPqBM#Yjhb)Mj~yq{ zU4x%GOy0XCdjSiXDheJ=G#+^<%WCBIWVSN!j>49Q)%v;83x3ieZ5y0?H?metR1_Oz zzdcLDPA?SPUgDnlawv&rP9$t;k@9y^&igTh7&n_E)p{3gX+MgT&Db3GZCWL_s#AtL zgon77b`(mxy7MzZhUo-zX#AduOYSXIsIeaT@$|jj;Ie;y9@q@%p1jiC{bu}G=P$Z+ zk2Ss!quyW3+qO)TSpr7ox+)jxj(EX&M?~mF3&~#Ruuo~OjQUBdvgu+-cXXha4IgBW zG#*GP0kC(}8SAWCWZ7rb@dUNt!LGxVX6`(1T(NX~nZ3?+oS75UpvZigonN8nPQGhP zs91klZI1+V(I6;v65J&i=Ws7uFc0F})T}r_Pjf;UXYj+0=QjnrDRCo5)#xU}Ooj1% zqMw5Iy}2Rsp&LaQiswB{HU|mj6^3x)39#yq4*+3+S45HN&kM6lftKebO;X0&4k=|o z57{EwaiMWg5_IsUBiF4C;F`pg9-gKZ6|TTMy(t=fu`MsJVCCjWEUn^8!Z%roqd5pi z0Ap6Ia;GQ?z&h6f{F@NGsNZuqoj%$^@~LWThYJggi2FE%tfTaZhhPwC|L-w>R3)BpTpsSu?DHpB3#(ey-3wo+iiskv3inMATnP``hhs^1B({H zv9Q6)TDe6}Nv4rlFfNLmEH!RnE{99wjDt)YB}27dPBw~qJSOxrY#sQG04E{(N~6~3 zWK`h}?ip0L^r^WF@kMbm9jH%IdGp+XD*o9kh-8un_MY*L z??HoDviGB^@?s;XYLk|b!|{u~B@Qm8Sh5C(bTQZmxrZB5+W-K`;LHyYgCo#5{79tdv1HH6?! z@Zjze0t9IY7Nmo_!}RaocW2(r{MNc}{+zX5uddanPVduIr>aivKDEDZf77!iy!w#R zS6PXupEY_&GuyFL3*|RjH(#+syf4}f6ZUo{cb#TTi@K;x`qFNr)sjDnJX)VF7W-=U zMU0<0X^@zl$A~HinHisp7wubdUefoaPdqQW8KyRRmlrj{oU^YT!u4gl?fL1% zyUqDYtGx6{vbpT6#9j2EOS)qsIo{bu2r^wDn2H6T(L7Ku8vsYIspleEQ@it&6 zJ}Z${m{MnFoJ8V_;{`2c{z$V>pvlG>RbhrHG-qm;C_A-P@$AkXO`>iVNcR5hvYl6m zjq|+tXpyiQw{8mAzFE{uQcGguAD~?VoL*-IHTp6pL#QH zrOM5q$_X75Gy6?qv$jq3Z_LEWX{6x$8!~KHLoZ%74;w$JuV4#)uLc zL{B*%b_+mDAMer`6s)zF%(y5)!G8nPtb5pT5CBx47LT7<5CTgZ>>Fu49y++;o8#I|JG8!r}E`30`vbmZsL=sW^OLVThdG zIWVPFNY3!LJat%eFOze9qx^F!g1N!VqO>R5W%uhgByUGbdj6WE&2Zd$;dTK0InY1v zqDv=a01Z(rC#D{uYjC4I!$9oG`StGDNV;pZ%CSw6f2f=0#F%rtoN{5VFX7{Cj>?Li z#`komRv2SAXX{rn;ZTpKdlYF>m z-iB=CWy0pBXDGy$l6T7DyY&?Kj(XK0&u#7Q2Hg~h;K=Z_7*!xo`Hm%0g-+mo5&B})&h`2CuVFv5ZC`g@gCtJo(2V&%PBB=} zDVL9rJm#|Bs?`tOvb*bFFZImzF$yBGXlvLnAFyLzwSFP{V!vs8F7lIgAEEY62~eSE zYaDd_B^-Qvlj3&NBxe>=JY4lQq-t{~c+9+4M$+I9VP2$9L~mZD*^sX6{oK}hXYiZy zf~#`l)*HErHLZr@I_%aZiT%kMMT2tFX#qT~<+n)Dp_lkm5EU^x;-`cx05v^g(xtfslWM1%oJH&9X6j-Ny)}`9t zJR9zxCsuy=WS5J^e>Y9jL*MAj930A(SR%tS4cmLFQqtP^eRS3|$nS-mcG0q1-I2FP zdLWDQd`7?+UkNkM&&m2jp)mOIdNcd%05#y9CVDYUvYW5)RHCAT%UPiSjQ> zv#uwS$w7dP@e(TabV#m=Qt*}_<8s09d}j%5Dbj~nulQ1Wfl1OR=VU25@D#fcMl#vt zx@R2T8ko`scuI5Au;%#Do*AEDWbxZ8Y0j%PQlKa{VSNUhlCsDDeDeGSmnI_iT-K8$ zOvZ37>*S8Qv+19I+5muoN}cLW?ITeh24^sD1!f(u!PhDOrK3ae$%;&tSbolT$|n=oXPb z_GMv@k(6t;?zM~OkhTeoF+62mh4E$pgBXl{Tac zLGcB>nCfyhbCOmtkOXUTf@xQ5_3E27B$juxJdD7wAmYyrBI30jZs?zvaUJRdVOKxj zw>2zHqq&fOs#D%Co7|j+=7|(?H8ItR{#8NR?ml0mrQQ(nHR$9P`)rN zFwWQoVzdnL>HmtU-u}z|_f@QMn2UL-(Qpfs@LjZXeYl+MgNqJvzESppE@cg7Qiq^_ zhpO_%fMgq+rgPX7_8W`3Q*weMBBl=GPJ5{ZT>Ev`@D3BGfoz)+nRAQ~4<-3l4qi^C zv-*P(2}D=q3u4L~Q#MLiQDXtsmC(|9(^t0{soI@&Civ6z_k>rv5uN z^}ola=$|59|L%hS8-f)#7tep-ZT@}i$yry$6)b?$eW+)L4f`X)F?Bmyn*>RI90`iI zv3oykLK&-oIn+oCj(&Q)m|otq`52K{J{QzQn)J!*c4>Arhx%sLT{oC;x8859uv~Oz zwU_@dwg~w4pKK9|ZMW{gC*7C)n`cYmjN41B9uuTya5)8gH_8aZEKw7G7_sIWjNR0=w>^I8=*D=s(!{ z5V4^h^Z8MGV9$sJ?NH;pnx#p)q`}t{KtJs)r``s~eVopN)&&2g1#S2)84{^94-4YE zkNwCbWM*o#8LCle*Q^RZNBY82;v}`(6p=8oRj8^|hlr4tS#Hj_`oMM*8pUxEgo8S8 zq=qEfm2lkgZh@7OQDjIK<%W^^kzjEJBb+9bwuSsgmP7F=+^>qQTr|;+%P@bi;62{8 zO2~`Lr}$g2yH&g3D{1v6>BWJ&9yjtJ9w2~fnLxiFnKrI4S~4F(i`B9mkf{@~wemQU z(h?nGVxpF9Gm88E`*@eJ<)(k~$jA-wG)0K~RBeYA@`MpXFA#k&uUlJF&9;0|s&*C41xU zN+e*6M#kzXTuD5taq2s>+68f~-+d8Qfh4LF!e7yiu=%|m0TU0Jhl&$CA8747I7d`dA8uo>WAS7B z-Ru|A$Pj|47>OKNDofA4dvkqm0i)FARp*8P(pP#ex&H@d!4*hxUd5Bm1h5 zQ=Ww{pKP9v)`IWvg_~4*ubb|w33{K3#4uY5cQ^PR4^HY14(DflM^At8_mJvgCvWe6 zUz&YkIk_y~u5?VsroF4I-cU=VE*8c1c&R-u!#ScqF?}jrIcZo22!cPY-dcjE8Qz<& z?gXMdco`$8uf2bt8uGaH{bs#b-Ly0vmZg*F)R$!kXL?q1D2U*8)o0r6Cw;3rF@Qa{ zRrHhXmFcOZSjy9ryTHS`*6pfXbw>6pT72}*nFJXW;*nf*E(Pw6g$gp5L++b5dIQIB zcns@hc1+4kAoxZu;sP>=?@fD_qGcH%trl*T}_U~T8{zB zWPs>CxBHKtxO*iZq~_5hyx2i`{p85j^jeCNNN#(rBVLclA7d(*{tfR*HTh&E&z+jH zYve_Z2_l>L{={yP5n4be`o%2mqhZ3e@;& zI#g-_7r(!xxxffg)dPOLOiCFSM$vX{U4?%xCr$PM-%s*eZJd6T5qr2xFnv1}qCF?( zOg=~ScO&v|h-3Uv^@o4H{=I__hNjj02cDL#D_Ze5e1tDDn>B8zJbkcLN2~TG_x-$# z0}QMnG`r0PhJtQ&74mmW=y=>)nVL@CFDP7C&%2HY1ehEx7eq}wtjq?VuCM(z_7+<8 z321I@z4rGG!kLxQJ3eA?X>#sy&V$T+Y;(SLuR6}T<^{BzssxsrQM*4ngg$EVQe-4# zg?L|$YPlkZl4Wpyyj)eLPI{zNY3DuP&Haqmd&I?O{7AFVo&Ezcu63q^K7hP?xJK>G zOdPg~5q6XOInwy2A75Om>|eh4dV4X^LP1xmH|@^Y1#Kqr!|_HG z+S0WcZvz)$@Xy!UT7jKoE-iTVh~@4QuVtgW@8(Tjob0@Cs3fsp#M`CC=~L9>207FP z^6LcD+r{Go06+?#aE$Qx@T3qSwwNzXU;fO7WVa}hnmbks&?8`d>w%3DuDqnkzFAyB z%YKws+)Ve3E#wwMoT~9rq_Xy>sgOj>qsh z3W+Gf+9{8%a{l{3jXuVmzO4i5SNd&fT#rO6?5%PQz1hT`Paja1L*FsxhsQ3P9&jB2 zHn<0u(4R?ev@KlI-gN^Z*Y8O$;)D5vLQuW(-g67{92vjwwh&!H@ZL_j{m_$r&2S+0 zNknow`x>Ew^pX;qbQS`DyTU6UDmU3)@y$0-Cd)(|UXgoozDvN*cOM86di45*PWB^x zmhh#lDdg-j#>4YWX=K;o#qof%KQuAND~Dpyo@7nEs9#13Zl}op*t+%FIQdP09m^*< zV9zJTQ%;SmguA~PAbkHBou%&KYUOPSl?!5Vv$D~))@SGD0C92f@B+{{CA_`tTs>F- zoZ9wYPS(&*EpH14YfCR^NeU_@ZlO^YZYpwgGS|S^N9CdRTd~ zK!4*OhW4&5(oiWP8Ww3G9xfgb7dLd_;^qhPvvUENxwx32b}Ft`|IS3)!`#iy+6t;` zWbWi?jmD|2Eu+sN>+R%ZVeaDcR|mAAkP;f``=1?oL!)c$;R)R|4UmHy#LX+n!^aC` z=i%V{R}Y~Lp!=?D?_*5^-76q~#?j5(%g)o7qdwTmtExNw7b1^%nIo&tRhS1=z=$Zh?mW#bp# zae4qAOI)c!ypKvQjRH4;lm<&(CW_M0l$n1)8{1dHIg%nI@(93_hOYyc)oeH;9miCRP`+V@ki zOaQ-+9ljZUlJpMe0OvTp`a3s%6gkt}j9s{xvi9mU!m7d1=bV;fM0bh+4<2<))pEqly`2xES&sGh0mh3&9#ljOfgoCydDd@_oq$mGW`f1gFTz3k2 zH=2|Z!1vny{BzxjWYfwIJh@nI-Kih!7*iT;(*1xciQL;QCe-8SvdkH zUcJq}_TLsFEW*T(Wweq)?|Iz?;7V5jnVK=!>&Q2BIhr|!()$W2q>x~<6Ch*iM$1to zJR@N#8+9ZXUrBIUV7OinBW@#{7JzTWdi9W~wS-lvJHS2)EX>qVXtoa$Gn^&s0~)^n*x3n8-zdoiy8ee4kry?ps?%gfnJKjm>I!RvyQ zc~5RMrUx@KUj+CxggiRT#Z9^6GkWJg(Q0?3(oyez3-AClBWiveq2;n7LR4j32WvHH zd;yHn_8;$?$6`UhX{whQs}*C$y?VbaU1aKSWroed@zbB>u?m;>GQI8NK?>VBHTY4)s0V zCbi&`y^{~iqt2Si8sF69^20dJc%^J+n1XpWD`Af;*C7qVQ_0}YR`L%g(>)0g|95k4 z_|GlIm+xO6It-o`YkGSgH8|^gLn^W+sgG^kBgSmuo|1p##lp5bZMp}y7#6NF5-mOY+pzQ|!e!>TRY@Eedph3UD#7$`)qK5hp$Y1al$Qpw^)+ z<2a$W)3ukl;OYh`i|nU^PZj$22GvpsjYNv5H*_AH`vLkdP*o4nA*tMcT=;v2BxSHCw%@sU}iny#3`K*hU3QjRX z`XZ7Ti?CRgQgV(3%qRh0g^oQN8&Kgu_Lca`GAKZmi4$zu`TPnN9yo3M6h)b|8ckmN zByUy%6?b9!6X#q+!W+(z+-n8^Mouna*EaA1CTG4OdLL)nDMPA4u9x~6Cn|DId`gQD zm=mdrL2VuL<3OJ}FS^>iVKx|!=|O7`RNT>Lz5E@0&GqVeuB}A%(9+8IVndYwH#=3u zZAYF>i^~AHb^MvNScCowStnZYx(^Wpux4&v{gWW>Us1+sId@1STrr!i$-{O{SYiga# zOPOj*k{2V_mfsemN(7#s*bB<3K(tiseE0aakWbI-WT}1PCU4Bw7u%{24cd`i>XV)` zI0Qu>s?==+a7_7`{h|v)S3%&%4M=d4@Y(M0m0RgO_La+Xg|IFt4r-#tjw6;Ox zRB*Af_M|qcP&90n%_oD>YqRy`YtUk)$>MYGLCFUHi*h z|FtGfVxIzDA z*TneKz=_bCVD$VoCr8O>RrA2)VCDyrU3k%Bh%51DFZ}-2^wRX~Y`g7vvYm(n{8%+6 zCWrUuB=6N8BrW9kWMUAc-HVY3TOx;s>=djab{uNrKhgq%MCB)e*8{PkE z;-JBBgh~NZ)$!Ux{;G z_0yEl!b@>s(7VAP4P^}ZglQ}zKW@<^3?e8G5GY3&_tR#FbGx@F`J~HjaV>wC9js~J zvj7Vr%YFMmuk9l@I^-?7HZe#=ix; zqv#3a++u4-RC3GXk4QCM--_P&{z%jl@%BvQ$?nqU!69eMIGMn(p48Bc_$W#Q2i{dyVrBK+YcxPBXtDp{C4ZOHei`v>`GFSu2z{f;ZQ9q-B6{7v4vP5gV z4o{8}?^f~KF(1;9ZftF;K4YX1`^mLxo}^R8a@F(aNcH4_g!aosKI_avum#`#(&v~D zEKztYA9z@z(JGp)=?Vf?v8xYs{&9AjSGo|hiEn=aefZE1Q3b~R*&X4CtUrY<6K$ur zE7^m|B;p9s7<4Y{t{Z7b3yTZzy~UZmB>p;m7&Scp?7ttjXu3gGW++jyVNL#r=I}KU zZ`}F+9H$FYD-h|>5=fvr!M%#F{b}+K!rMk;iApp(Jy)!F?@$qLSP`KB<IOCl3W0tjgG&7%kFX42bD^$K{9mQ5)0g zaTqSLH(vBrQK2dZ)<9*4J=d#5QGbODRE40{5gPK+^gk0-BQZ|(I_nq?+~8L8;LY$F z@G@-W@Yj%Ko~`xjCdy|o81S-g{V}e-QAqdyS@n#k@?yRS8*4LT$jdbM&7>Mj(aV0g z$~~6Dwk9{lPS6W){qW-Hs(F9E37Xy~FywLU@=;~B&@}Mnq5sl1e7`?szjwc&%>c0k0Y)wS2p(`~qHWwAuDbM$LD1{L%;Vb8x75On)Nj|*Bk12_fP7ErkWaq@6$U;Y-v4cdV{zfst b)63k$%MUu&Km&sKc?9{;7#U^MWYPWyKdWyH diff --git a/src/kem/kyber/ind_cpa.rs b/src/kem/kyber/ind_cpa.rs deleted file mode 100644 index 6552e2c0b..000000000 --- a/src/kem/kyber/ind_cpa.rs +++ /dev/null @@ -1,510 +0,0 @@ -use std::usize; - -use super::{ - arithmetic::{to_unsigned_representative, PolynomialRingElement}, - constants::{BYTES_PER_RING_ELEMENT, COEFFICIENTS_IN_RING_ELEMENT, SHARED_SECRET_SIZE}, - hash_functions::{G, PRF}, - matrix::*, - ntt::*, - sampling::sample_from_binomial_distribution, - serialize::{ - compress_then_serialize_message, compress_then_serialize_ring_element_u, - compress_then_serialize_ring_element_v, deserialize_ring_elements_reduced, - deserialize_then_decompress_message, deserialize_then_decompress_ring_element_u, - deserialize_then_decompress_ring_element_v, deserialize_to_uncompressed_ring_element, - serialize_uncompressed_ring_element, - }, -}; -use crate::cloop; - -/// Pad the `slice` with `0`s at the end. -#[inline(always)] -pub(super) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { - debug_assert!(slice.len() <= LEN); - let mut out = [0u8; LEN]; - out[0..slice.len()].copy_from_slice(slice); - out -} - -/// Concatenate `t` and `ρ` into the public key. -#[inline(always)] -pub(super) fn serialize_public_key< - const K: usize, - const RANKED_BYTES_PER_RING_ELEMENT: usize, - const PUBLIC_KEY_SIZE: usize, ->( - t_as_ntt: [PolynomialRingElement; K], - seed_for_a: &[u8], -) -> [u8; PUBLIC_KEY_SIZE] { - let mut public_key_serialized = [0u8; PUBLIC_KEY_SIZE]; - public_key_serialized[0..RANKED_BYTES_PER_RING_ELEMENT].copy_from_slice( - &serialize_secret_key::(t_as_ntt), - ); - public_key_serialized[RANKED_BYTES_PER_RING_ELEMENT..].copy_from_slice(seed_for_a); - public_key_serialized -} - -/// Call [`serialize_uncompressed_ring_element`] for each ring element. -#[inline(always)] -fn serialize_secret_key( - key: [PolynomialRingElement; K], -) -> [u8; OUT_LEN] { - let mut out = [0u8; OUT_LEN]; - - cloop! { - for (i, re) in key.into_iter().enumerate() { - out[i * BYTES_PER_RING_ELEMENT..(i + 1) * BYTES_PER_RING_ELEMENT] - .copy_from_slice(&serialize_uncompressed_ring_element(re)); - } - } - - out -} - -/// Sample a vector of ring elements from a centered binomial distribution. -#[inline(always)] -fn sample_ring_element_cbd( - prf_input: &mut [u8; 33], - domain_separator: &mut u8, -) -> [PolynomialRingElement; K] { - let mut error_1 = [PolynomialRingElement::ZERO; K]; - for i in 0..K { - prf_input[32] = *domain_separator; - *domain_separator += 1; - - let prf_output: [u8; ETA2_RANDOMNESS_SIZE] = PRF(prf_input); - error_1[i] = sample_from_binomial_distribution::(&prf_output); - } - error_1 -} - -/// Sample a vector of ring elements from a centered binomial distribution and -/// convert them into their NTT representations. -#[inline(always)] -fn sample_vector_cbd_then_ntt< - const K: usize, - const ETA: usize, - const ETA_RANDOMNESS_SIZE: usize, ->( - mut prf_input: [u8; 33], - mut domain_separator: u8, -) -> ([PolynomialRingElement; K], u8) { - let mut re_as_ntt = [PolynomialRingElement::ZERO; K]; - for i in 0..K { - prf_input[32] = domain_separator; - domain_separator += 1; - - let prf_output: [u8; ETA_RANDOMNESS_SIZE] = PRF(&prf_input); - - let r = sample_from_binomial_distribution::(&prf_output); - re_as_ntt[i] = ntt_binomially_sampled_ring_element(r); - } - (re_as_ntt, domain_separator) -} - -/// This function implements most of Algorithm 12 of the -/// NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation algorithm. -/// -/// We say "most of" since Algorithm 12 samples the required randomness within -/// the function itself, whereas this implementation expects it to be provided -/// through the `key_generation_seed` parameter. -/// -/// Algorithm 12 is reproduced below: -/// -/// ```plaintext -/// Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. -/// Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. -/// -/// d ←$ B -/// (ρ,σ) ← G(d) -/// N ← 0 -/// for (i ← 0; i < k; i++) -/// for(j ← 0; j < k; j++) -/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) -/// end for -/// end for -/// for(i ← 0; i < k; i++) -/// s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) -/// N ← N + 1 -/// end for -/// for(i ← 0; i < k; i++) -/// e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) -/// N ← N + 1 -/// end for -/// ŝ ← NTT(s) -/// ê ← NTT(e) -/// t̂ ← Â◦ŝ + ê -/// ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ -/// dkₚₖₑ ← ByteEncode₁₂(ŝ) -/// ``` -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[allow(non_snake_case)] -pub(super) fn generate_keypair_unpacked< - const K: usize, - const PUBLIC_KEY_SIZE: usize, - const RANKED_BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, ->( - key_generation_seed: &[u8], -) -> ( - ( - [PolynomialRingElement; K], - [PolynomialRingElement; K], - [[PolynomialRingElement; K]; K], - ), - [u8; PUBLIC_KEY_SIZE], -) { - // (ρ,σ) := G(d) - let hashed = G(key_generation_seed); - let (seed_for_A, seed_for_secret_and_error) = hashed.split_at(32); - - let a_transpose = sample_matrix_A(into_padded_array(seed_for_A), true); - - let prf_input: [u8; 33] = into_padded_array(seed_for_secret_and_error); - let (mut secret_as_ntt, domain_separator) = - sample_vector_cbd_then_ntt::(prf_input, 0); - let (error_as_ntt, _) = - sample_vector_cbd_then_ntt::(prf_input, domain_separator); - - // tˆ := Aˆ ◦ sˆ + eˆ - let mut t_as_ntt = compute_As_plus_e(&a_transpose, &secret_as_ntt, &error_as_ntt); - - // pk := (Encode_12(tˆ mod^{+}q) || ρ) - let public_key_serialized = serialize_public_key::< - K, - RANKED_BYTES_PER_RING_ELEMENT, - PUBLIC_KEY_SIZE, - >(t_as_ntt, &seed_for_A); - - // Need to do the following otherwise it violates invariants in NTT (the values are expected to be >=0 and <4096). - // Maybe we can remove these reductions later if we make those constraints looser - for i in 0..K { - for j in 0..COEFFICIENTS_IN_RING_ELEMENT { - secret_as_ntt[i].coefficients[j] = - to_unsigned_representative(secret_as_ntt[i].coefficients[j]) as i32; - t_as_ntt[i].coefficients[j] = - to_unsigned_representative(t_as_ntt[i].coefficients[j]) as i32; - } - } - - // We also need to transpose the A array. - let mut a_matrix = a_transpose; - for i in 0..K { - for j in 0..K { - a_matrix[i][j] = a_transpose[j][i]; - } - } - - ((secret_as_ntt, t_as_ntt, a_matrix), public_key_serialized) -} - -#[allow(non_snake_case)] -pub(super) fn generate_keypair< - const K: usize, - const PRIVATE_KEY_SIZE: usize, - const PUBLIC_KEY_SIZE: usize, - const RANKED_BYTES_PER_RING_ELEMENT: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, ->( - key_generation_seed: &[u8], -) -> ([u8; PRIVATE_KEY_SIZE], [u8; PUBLIC_KEY_SIZE]) { - let ((secret_as_ntt, _t_as_ntt, _a_transpose), public_key_serialized) = - generate_keypair_unpacked::< - K, - PUBLIC_KEY_SIZE, - RANKED_BYTES_PER_RING_ELEMENT, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(key_generation_seed); - - // sk := Encode_12(sˆ mod^{+}q) - let secret_key_serialized = serialize_secret_key(secret_as_ntt); - - (secret_key_serialized, public_key_serialized) -} - -/// Call [`compress_then_serialize_ring_element_u`] on each ring element. -fn compress_then_serialize_u< - const K: usize, - const OUT_LEN: usize, - const COMPRESSION_FACTOR: usize, - const BLOCK_LEN: usize, ->( - input: [PolynomialRingElement; K], -) -> [u8; OUT_LEN] { - let mut out = [0u8; OUT_LEN]; - cloop! { - for (i, re) in input.into_iter().enumerate() { - out[i * (OUT_LEN / K)..(i + 1) * (OUT_LEN / K)].copy_from_slice( - &compress_then_serialize_ring_element_u::(re), - ); - } - } - - out -} - -/// This function implements Algorithm 13 of the -/// NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. -/// -/// Algorithm 13 is reproduced below: -/// -/// ```plaintext -/// Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. -/// Input: message m ∈ 𝔹^{32}. -/// Input: encryption randomness r ∈ 𝔹^{32}. -/// Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. -/// -/// N ← 0 -/// t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) -/// ρ ← ekₚₖₑ[384k: 384k + 32] -/// for (i ← 0; i < k; i++) -/// for(j ← 0; j < k; j++) -/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) -/// end for -/// end for -/// for(i ← 0; i < k; i++) -/// r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) -/// N ← N + 1 -/// end for -/// for(i ← 0; i < k; i++) -/// e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) -/// N ← N + 1 -/// end for -/// e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) -/// r̂ ← NTT(r) -/// u ← NTT-¹(Âᵀ ◦ r̂) + e₁ -/// μ ← Decompress₁(ByteDecode₁(m))) -/// v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ -/// c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) -/// c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) -/// return c ← (c₁ ‖ c₂) -/// ``` -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[allow(non_snake_case)] -pub(crate) fn encrypt_unpacked< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_LEN: usize, - const C2_LEN: usize, - const U_COMPRESSION_FACTOR: usize, - const V_COMPRESSION_FACTOR: usize, - const BLOCK_LEN: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, ->( - t_as_ntt: &[PolynomialRingElement; K], - a_transpose: &[[PolynomialRingElement; K]; K], - message: [u8; SHARED_SECRET_SIZE], - randomness: &[u8], -) -> [u8; CIPHERTEXT_SIZE] { - // for i from 0 to k−1 do - // r[i] := CBD{η1}(PRF(r, N)) - // N := N + 1 - // end for - // rˆ := NTT(r) - let mut prf_input: [u8; 33] = into_padded_array(randomness); - let (r_as_ntt, mut domain_separator) = - sample_vector_cbd_then_ntt::(prf_input, 0); - - // for i from 0 to k−1 do - // e1[i] := CBD_{η2}(PRF(r,N)) - // N := N + 1 - // end for - let error_1 = sample_ring_element_cbd::( - &mut prf_input, - &mut domain_separator, - ); - - // e_2 := CBD{η2}(PRF(r, N)) - prf_input[32] = domain_separator; - let prf_output: [u8; ETA2_RANDOMNESS_SIZE] = PRF(&prf_input); - let error_2 = sample_from_binomial_distribution::(&prf_output); - - // u := NTT^{-1}(AˆT ◦ rˆ) + e_1 - let u = compute_vector_u(&a_transpose, &r_as_ntt, &error_1); - - // v := NTT^{−1}(tˆT ◦ rˆ) + e_2 + Decompress_q(Decode_1(m),1) - let message_as_ring_element = deserialize_then_decompress_message(message); - let v = compute_ring_element_v(&t_as_ntt, &r_as_ntt, &error_2, &message_as_ring_element); - - // c_1 := Encode_{du}(Compress_q(u,d_u)) - let c1 = compress_then_serialize_u::(u); - - // c_2 := Encode_{dv}(Compress_q(v,d_v)) - let c2 = compress_then_serialize_ring_element_v::(v); - - let mut ciphertext: [u8; CIPHERTEXT_SIZE] = into_padded_array(&c1); - ciphertext[C1_LEN..].copy_from_slice(c2.as_slice()); - - ciphertext -} - -#[allow(non_snake_case)] -pub(crate) fn encrypt< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const T_AS_NTT_ENCODED_SIZE: usize, - const C1_LEN: usize, - const C2_LEN: usize, - const U_COMPRESSION_FACTOR: usize, - const V_COMPRESSION_FACTOR: usize, - const BLOCK_LEN: usize, - const ETA1: usize, - const ETA1_RANDOMNESS_SIZE: usize, - const ETA2: usize, - const ETA2_RANDOMNESS_SIZE: usize, ->( - public_key: &[u8], - message: [u8; SHARED_SECRET_SIZE], - randomness: &[u8], -) -> [u8; CIPHERTEXT_SIZE] { - // tˆ := Decode_12(pk) - let t_as_ntt = deserialize_ring_elements_reduced::( - &public_key[..T_AS_NTT_ENCODED_SIZE], - ); - - // ρ := pk + 12·k·n / 8 - // for i from 0 to k−1 do - // for j from 0 to k − 1 do - // AˆT[i][j] := Parse(XOF(ρ, i, j)) - // end for - // end for - let seed = &public_key[T_AS_NTT_ENCODED_SIZE..]; - // ρ := pk + 12·k·n / 8 - // for i from 0 to k−1 do - // for j from 0 to k − 1 do - // AˆT[i][j] := Parse(XOF(ρ, i, j)) - // end for - // end for - let a_transpose = sample_matrix_A(into_padded_array(seed), false); - - encrypt_unpacked::< - K, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_LEN, - C2_LEN, - U_COMPRESSION_FACTOR, - V_COMPRESSION_FACTOR, - BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(&t_as_ntt, &a_transpose, message, randomness) -} - -/// Call [`deserialize_then_decompress_ring_element_u`] on each ring element -/// in the `ciphertext`. -#[inline(always)] -fn deserialize_then_decompress_u< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const U_COMPRESSION_FACTOR: usize, ->( - ciphertext: &[u8; CIPHERTEXT_SIZE], -) -> [PolynomialRingElement; K] { - let mut u_as_ntt = [PolynomialRingElement::ZERO; K]; - cloop! { - for (i, u_bytes) in ciphertext - .chunks_exact((COEFFICIENTS_IN_RING_ELEMENT * U_COMPRESSION_FACTOR) / 8) - .enumerate() - { - let u = deserialize_then_decompress_ring_element_u::(u_bytes); - u_as_ntt[i] = ntt_vector_u::(u); - } - } - u_as_ntt -} - -/// Call [`deserialize_to_uncompressed_ring_element`] for each ring element. -#[inline(always)] -fn deserialize_secret_key(secret_key: &[u8]) -> [PolynomialRingElement; K] { - let mut secret_as_ntt = [PolynomialRingElement::ZERO; K]; - cloop! { - for (i, secret_bytes) in secret_key.chunks_exact(BYTES_PER_RING_ELEMENT).enumerate() { - secret_as_ntt[i] = deserialize_to_uncompressed_ring_element(secret_bytes); - } - } - secret_as_ntt -} - -/// This function implements Algorithm 14 of the -/// NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. -/// -/// Algorithm 14 is reproduced below: -/// -/// ```plaintext -/// Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. -/// Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. -/// Output: message m ∈ 𝔹^{32}. -/// -/// c₁ ← c[0 : 32dᵤk] -/// c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] -/// u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) -/// v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) -/// ŝ ← ByteDecode₁₂(dkₚₖₑ) -/// w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) -/// m ← ByteEncode₁(Compress₁(w)) -/// return m -/// ``` -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[allow(non_snake_case)] -pub(super) fn decrypt_unpacked< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const VECTOR_U_ENCODED_SIZE: usize, - const U_COMPRESSION_FACTOR: usize, - const V_COMPRESSION_FACTOR: usize, ->( - secret_as_ntt: &[PolynomialRingElement; K], - ciphertext: &[u8; CIPHERTEXT_SIZE], -) -> [u8; SHARED_SECRET_SIZE] { - // u := Decompress_q(Decode_{d_u}(c), d_u) - let u_as_ntt = - deserialize_then_decompress_u::(ciphertext); - - // v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) - let v = deserialize_then_decompress_ring_element_v::( - &ciphertext[VECTOR_U_ENCODED_SIZE..], - ); - - // m := Encode_1(Compress_q(v − NTT^{−1}(sˆT ◦ NTT(u)) , 1)) - let message = compute_message(&v, &secret_as_ntt, &u_as_ntt); - compress_then_serialize_message(message) -} - -#[allow(non_snake_case)] -pub(super) fn decrypt< - const K: usize, - const CIPHERTEXT_SIZE: usize, - const VECTOR_U_ENCODED_SIZE: usize, - const U_COMPRESSION_FACTOR: usize, - const V_COMPRESSION_FACTOR: usize, ->( - secret_key: &[u8], - ciphertext: &[u8; CIPHERTEXT_SIZE], -) -> [u8; SHARED_SECRET_SIZE] { - // sˆ := Decode_12(sk) - let secret_as_ntt = deserialize_secret_key::(secret_key); - - decrypt_unpacked::< - K, - CIPHERTEXT_SIZE, - VECTOR_U_ENCODED_SIZE, - U_COMPRESSION_FACTOR, - V_COMPRESSION_FACTOR, - >(&secret_as_ntt, ciphertext) -} diff --git a/src/kem/kyber/kyber1024.rs b/src/kem/kyber/kyber1024.rs deleted file mode 100644 index b15c6ec12..000000000 --- a/src/kem/kyber/kyber1024.rs +++ /dev/null @@ -1,160 +0,0 @@ -use super::{constants::*, *}; - -// Kyber 1024 parameters -const RANK_1024: usize = 4; -const RANKED_BYTES_PER_RING_ELEMENT_1024: usize = RANK_1024 * BITS_PER_RING_ELEMENT / 8; -const T_AS_NTT_ENCODED_SIZE_1024: usize = - (RANK_1024 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const VECTOR_U_COMPRESSION_FACTOR_1024: usize = 11; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::(); -const C1_BLOCK_SIZE_1024: usize = - (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_U_COMPRESSION_FACTOR_1024) / 8; -// [hax]: hacspec/hacspec-v2#27 stealing error -// serialized_len::(); -const C1_SIZE_1024: usize = C1_BLOCK_SIZE_1024 * RANK_1024; -const VECTOR_V_COMPRESSION_FACTOR_1024: usize = 5; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::() -const C2_SIZE_1024: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_1024) / 8; -const CPA_PKE_SECRET_KEY_SIZE_1024: usize = - (RANK_1024 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_1024: usize = T_AS_NTT_ENCODED_SIZE_1024 + 32; -const CPA_PKE_CIPHERTEXT_SIZE_1024: usize = C1_SIZE_1024 + C2_SIZE_1024; -const SECRET_KEY_SIZE_1024: usize = CPA_PKE_SECRET_KEY_SIZE_1024 - + CPA_PKE_PUBLIC_KEY_SIZE_1024 - + H_DIGEST_SIZE - + SHARED_SECRET_SIZE; - -const ETA1: usize = 2; -const ETA1_RANDOMNESS_SIZE: usize = ETA1 * 64; -const ETA2: usize = 2; -const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; - -const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_1024; - -// Kyber 1024 types -pub type MlKem1024Ciphertext = MlKemCiphertext; -pub type MlKem1024PrivateKey = MlKemPrivateKey; -pub type MlKem1024PublicKey = MlKemPublicKey; - -/// Validate a public key. -/// -/// Returns `Some(public_key)` if valid, and `None` otherwise. -pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option { - if super::validate_public_key::< - RANK_1024, - RANKED_BYTES_PER_RING_ELEMENT_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - >(&public_key.value) - { - Some(public_key) - } else { - None - } -} - -/// Generate ML-KEM 1024 Key Pair -pub fn generate_key_pair( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> MlKemKeyPair { - super::generate_keypair::< - RANK_1024, - CPA_PKE_SECRET_KEY_SIZE_1024, - SECRET_KEY_SIZE_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - RANKED_BYTES_PER_RING_ELEMENT_1024, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -pub type MlKem1024State = MlKemState; - -pub fn generate_key_pair_unpacked( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> (MlKem1024State, MlKem1024PublicKey) { - generate_keypair_unpacked::< - RANK_1024, - CPA_PKE_SECRET_KEY_SIZE_1024, - SECRET_KEY_SIZE_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - RANKED_BYTES_PER_RING_ELEMENT_1024, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -/// Encapsulate ML-KEM 1024 -pub fn encapsulate( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], -) -> ( - MlKemCiphertext, - MlKemSharedSecret, -) { - super::encapsulate::< - RANK_1024, - CPA_PKE_CIPHERTEXT_SIZE_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - T_AS_NTT_ENCODED_SIZE_1024, - C1_SIZE_1024, - C2_SIZE_1024, - VECTOR_U_COMPRESSION_FACTOR_1024, - VECTOR_V_COMPRESSION_FACTOR_1024, - C1_BLOCK_SIZE_1024, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) -} - -/// Decapsulate ML-KEM 1024 -pub fn decapsulate( - secret_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate::< - RANK_1024, - SECRET_KEY_SIZE_1024, - CPA_PKE_SECRET_KEY_SIZE_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - CPA_PKE_CIPHERTEXT_SIZE_1024, - T_AS_NTT_ENCODED_SIZE_1024, - C1_SIZE_1024, - C2_SIZE_1024, - VECTOR_U_COMPRESSION_FACTOR_1024, - VECTOR_V_COMPRESSION_FACTOR_1024, - C1_BLOCK_SIZE_1024, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(secret_key, ciphertext) -} - -pub fn decapsulate_unpacked( - state: &MlKem1024State, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate_unpacked::< - RANK_1024, - SECRET_KEY_SIZE_1024, - CPA_PKE_SECRET_KEY_SIZE_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - CPA_PKE_CIPHERTEXT_SIZE_1024, - T_AS_NTT_ENCODED_SIZE_1024, - C1_SIZE_1024, - C2_SIZE_1024, - VECTOR_U_COMPRESSION_FACTOR_1024, - VECTOR_V_COMPRESSION_FACTOR_1024, - C1_BLOCK_SIZE_1024, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(state, ciphertext) -} diff --git a/src/kem/kyber/kyber512.rs b/src/kem/kyber/kyber512.rs deleted file mode 100644 index 8edce7f47..000000000 --- a/src/kem/kyber/kyber512.rs +++ /dev/null @@ -1,158 +0,0 @@ -use super::{constants::*, *}; - -// Kyber 512 parameters -const RANK_512: usize = 2; -const RANKED_BYTES_PER_RING_ELEMENT_512: usize = RANK_512 * BITS_PER_RING_ELEMENT / 8; -const T_AS_NTT_ENCODED_SIZE_512: usize = - (RANK_512 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const VECTOR_U_COMPRESSION_FACTOR_512: usize = 10; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::() -const C1_BLOCK_SIZE_512: usize = - (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_U_COMPRESSION_FACTOR_512) / 8; -// [hax]: hacspec/hacspec-v2#27 stealing error -// serialized_len::() -const C1_SIZE_512: usize = C1_BLOCK_SIZE_512 * RANK_512; -const VECTOR_V_COMPRESSION_FACTOR_512: usize = 4; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::() -const C2_SIZE_512: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_512) / 8; -const CPA_PKE_SECRET_KEY_SIZE_512: usize = - (RANK_512 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_512: usize = T_AS_NTT_ENCODED_SIZE_512 + 32; -const CPA_PKE_CIPHERTEXT_SIZE_512: usize = C1_SIZE_512 + C2_SIZE_512; -const SECRET_KEY_SIZE_512: usize = - CPA_PKE_SECRET_KEY_SIZE_512 + CPA_PKE_PUBLIC_KEY_SIZE_512 + H_DIGEST_SIZE + SHARED_SECRET_SIZE; - -const ETA1: usize = 3; -const ETA1_RANDOMNESS_SIZE: usize = ETA1 * 64; -const ETA2: usize = 2; -const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; - -const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_512; - -// Kyber 512 types -pub type MlKem512Ciphertext = MlKemCiphertext; -pub type MlKem512PrivateKey = MlKemPrivateKey; -pub type MlKem512PublicKey = MlKemPublicKey; - -/// Validate a public key. -/// -/// Returns `Some(public_key)` if valid, and `None` otherwise. -pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option { - if super::validate_public_key::< - RANK_512, - RANKED_BYTES_PER_RING_ELEMENT_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - >(&public_key.value) - { - Some(public_key) - } else { - None - } -} - -/// Generate ML-KEM 512 Key Pair -pub fn generate_key_pair( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> MlKemKeyPair { - generate_keypair::< - RANK_512, - CPA_PKE_SECRET_KEY_SIZE_512, - SECRET_KEY_SIZE_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - RANKED_BYTES_PER_RING_ELEMENT_512, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -pub type MlKem512State = MlKemState; - -pub fn generate_key_pair_unpacked( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> (MlKem512State, MlKem512PublicKey) { - generate_keypair_unpacked::< - RANK_512, - CPA_PKE_SECRET_KEY_SIZE_512, - SECRET_KEY_SIZE_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - RANKED_BYTES_PER_RING_ELEMENT_512, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -/// Encapsulate ML-KEM 512 -pub fn encapsulate( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], -) -> ( - MlKemCiphertext, - MlKemSharedSecret, -) { - super::encapsulate::< - RANK_512, - CPA_PKE_CIPHERTEXT_SIZE_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - T_AS_NTT_ENCODED_SIZE_512, - C1_SIZE_512, - C2_SIZE_512, - VECTOR_U_COMPRESSION_FACTOR_512, - VECTOR_V_COMPRESSION_FACTOR_512, - C1_BLOCK_SIZE_512, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) -} - -/// Decapsulate ML-KEM 512 -pub fn decapsulate( - secret_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate::< - RANK_512, - SECRET_KEY_SIZE_512, - CPA_PKE_SECRET_KEY_SIZE_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - CPA_PKE_CIPHERTEXT_SIZE_512, - T_AS_NTT_ENCODED_SIZE_512, - C1_SIZE_512, - C2_SIZE_512, - VECTOR_U_COMPRESSION_FACTOR_512, - VECTOR_V_COMPRESSION_FACTOR_512, - C1_BLOCK_SIZE_512, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(secret_key, ciphertext) -} - -pub fn decapsulate_unpacked( - state: &MlKem512State, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate_unpacked::< - RANK_512, - SECRET_KEY_SIZE_512, - CPA_PKE_SECRET_KEY_SIZE_512, - CPA_PKE_PUBLIC_KEY_SIZE_512, - CPA_PKE_CIPHERTEXT_SIZE_512, - T_AS_NTT_ENCODED_SIZE_512, - C1_SIZE_512, - C2_SIZE_512, - VECTOR_U_COMPRESSION_FACTOR_512, - VECTOR_V_COMPRESSION_FACTOR_512, - C1_BLOCK_SIZE_512, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(state, ciphertext) -} diff --git a/src/kem/kyber/kyber768.rs b/src/kem/kyber/kyber768.rs deleted file mode 100644 index 2e5ab7eaf..000000000 --- a/src/kem/kyber/kyber768.rs +++ /dev/null @@ -1,178 +0,0 @@ -use super::{constants::*, *}; - -// Kyber 768 parameters -const RANK_768: usize = 3; -const RANKED_BYTES_PER_RING_ELEMENT_768: usize = RANK_768 * BITS_PER_RING_ELEMENT / 8; -const T_AS_NTT_ENCODED_SIZE_768: usize = - (RANK_768 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const VECTOR_U_COMPRESSION_FACTOR_768: usize = 10; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::() -const C1_BLOCK_SIZE_768: usize = - (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_U_COMPRESSION_FACTOR_768) / 8; -// [hax]: hacspec/hacspec-v2#27 stealing error -// serialized_len::(); -const C1_SIZE_768: usize = C1_BLOCK_SIZE_768 * RANK_768; -const VECTOR_V_COMPRESSION_FACTOR_768: usize = 4; -// [hax]: hacspec/hacspec-v2#27 stealing error -// block_len::() -const C2_SIZE_768: usize = (COEFFICIENTS_IN_RING_ELEMENT * VECTOR_V_COMPRESSION_FACTOR_768) / 8; -const CPA_PKE_SECRET_KEY_SIZE_768: usize = - (RANK_768 * COEFFICIENTS_IN_RING_ELEMENT * BITS_PER_COEFFICIENT) / 8; -const CPA_PKE_PUBLIC_KEY_SIZE_768: usize = T_AS_NTT_ENCODED_SIZE_768 + 32; -// These two are used in the hybrid kem. This could probably be improved. -pub(in crate::kem) const CPA_PKE_CIPHERTEXT_SIZE_768: usize = C1_SIZE_768 + C2_SIZE_768; -pub(in crate::kem) const SECRET_KEY_SIZE_768: usize = - CPA_PKE_SECRET_KEY_SIZE_768 + CPA_PKE_PUBLIC_KEY_SIZE_768 + H_DIGEST_SIZE + SHARED_SECRET_SIZE; - -const ETA1: usize = 2; -const ETA1_RANDOMNESS_SIZE: usize = ETA1 * 64; -const ETA2: usize = 2; -const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; - -const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_768; - -// Kyber 768 types -pub type MlKem768Ciphertext = MlKemCiphertext; -pub type MlKem768PrivateKey = MlKemPrivateKey; -pub type MlKem768PublicKey = MlKemPublicKey; - -/// Validate a public key. -/// -/// Returns `Some(public_key)` if valid, and `None` otherwise. -pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option { - if super::validate_public_key::< - RANK_768, - RANKED_BYTES_PER_RING_ELEMENT_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - >(&public_key.value) - { - Some(public_key) - } else { - None - } -} - -/// Generate ML-KEM 768 Key Pair -pub fn generate_key_pair( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> MlKemKeyPair { - generate_keypair::< - RANK_768, - CPA_PKE_SECRET_KEY_SIZE_768, - SECRET_KEY_SIZE_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - RANKED_BYTES_PER_RING_ELEMENT_768, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -pub type MlKem768State = MlKemState; - -pub fn generate_key_pair_unpacked( - randomness: [u8; KEY_GENERATION_SEED_SIZE], -) -> (MlKem768State, MlKem768PublicKey) { - generate_keypair_unpacked::< - RANK_768, - CPA_PKE_SECRET_KEY_SIZE_768, - SECRET_KEY_SIZE_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - RANKED_BYTES_PER_RING_ELEMENT_768, - ETA1, - ETA1_RANDOMNESS_SIZE, - >(randomness) -} - -/// Encapsulate ML-KEM 768 -pub fn encapsulate( - public_key: &MlKemPublicKey, - randomness: [u8; SHARED_SECRET_SIZE], -) -> ( - MlKemCiphertext, - MlKemSharedSecret, -) { - super::encapsulate::< - RANK_768, - CPA_PKE_CIPHERTEXT_SIZE_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - T_AS_NTT_ENCODED_SIZE_768, - C1_SIZE_768, - C2_SIZE_768, - VECTOR_U_COMPRESSION_FACTOR_768, - VECTOR_V_COMPRESSION_FACTOR_768, - C1_BLOCK_SIZE_768, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - >(public_key, randomness) -} - -/// Decapsulate ML-KEM 768 -pub fn decapsulate( - secret_key: &MlKemPrivateKey, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate::< - RANK_768, - SECRET_KEY_SIZE_768, - CPA_PKE_SECRET_KEY_SIZE_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - CPA_PKE_CIPHERTEXT_SIZE_768, - T_AS_NTT_ENCODED_SIZE_768, - C1_SIZE_768, - C2_SIZE_768, - VECTOR_U_COMPRESSION_FACTOR_768, - VECTOR_V_COMPRESSION_FACTOR_768, - C1_BLOCK_SIZE_768, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(secret_key, ciphertext) -} - -pub fn decapsulate_unpacked( - state: &MlKem768State, - ciphertext: &MlKemCiphertext, -) -> [u8; SHARED_SECRET_SIZE] { - super::decapsulate_unpacked::< - RANK_768, - SECRET_KEY_SIZE_768, - CPA_PKE_SECRET_KEY_SIZE_768, - CPA_PKE_PUBLIC_KEY_SIZE_768, - CPA_PKE_CIPHERTEXT_SIZE_768, - T_AS_NTT_ENCODED_SIZE_768, - C1_SIZE_768, - C2_SIZE_768, - VECTOR_U_COMPRESSION_FACTOR_768, - VECTOR_V_COMPRESSION_FACTOR_768, - C1_BLOCK_SIZE_768, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - IMPLICIT_REJECTION_HASH_INPUT_SIZE, - >(state, ciphertext) -} - -#[cfg(test)] -mod tests { - use rand_core::{OsRng, RngCore}; - - use super::{ - kyber768::{generate_key_pair, validate_public_key}, - KEY_GENERATION_SEED_SIZE, - }; - - #[test] - fn pk_validation() { - let mut randomness = [0u8; KEY_GENERATION_SEED_SIZE]; - OsRng.fill_bytes(&mut randomness); - - let key_pair = generate_key_pair(randomness); - assert!(validate_public_key(key_pair.pk).is_some()); - } -} diff --git a/src/kem/kyber/matrix.rs b/src/kem/kyber/matrix.rs deleted file mode 100644 index a4908eaaa..000000000 --- a/src/kem/kyber/matrix.rs +++ /dev/null @@ -1,158 +0,0 @@ -use super::{ - arithmetic::{ - add_to_ring_element, barrett_reduce, montgomery_reduce, to_standard_domain, - PolynomialRingElement, - }, - constants::COEFFICIENTS_IN_RING_ELEMENT, - ntt::{invert_ntt_montgomery, ntt_multiply}, - sampling::sample_from_xof, -}; -use crate::cloop; - -#[inline(always)] -#[allow(non_snake_case)] -pub(in crate::kem::kyber) fn sample_matrix_A( - seed: [u8; 34], - transpose: bool, -) -> [[PolynomialRingElement; K]; K] { - let mut A_transpose = [[PolynomialRingElement::ZERO; K]; K]; - - for i in 0..K { - let mut seeds = [seed; K]; - for j in 0..K { - seeds[j][32] = i as u8; - seeds[j][33] = j as u8; - } - let sampled = sample_from_xof(seeds); - for j in 0..K { - // A[i][j] = A_transpose[j][i] - if transpose { - A_transpose[j][i] = sampled[j]; - } else { - A_transpose[i][j] = sampled[j]; - } - } - } - - A_transpose -} - -/// The following functions compute various expressions involving -/// vectors and matrices. The computation of these expressions has been -/// abstracted away into these functions in order to save on loop iterations. - -/// Compute v − InverseNTT(sᵀ ◦ NTT(u)) -#[inline(always)] -pub(in crate::kem::kyber) fn compute_message( - v: &PolynomialRingElement, - secret_as_ntt: &[PolynomialRingElement; K], - u_as_ntt: &[PolynomialRingElement; K], -) -> PolynomialRingElement { - let mut result = PolynomialRingElement::ZERO; - - for i in 0..K { - let product = ntt_multiply(&secret_as_ntt[i], &u_as_ntt[i]); - result = add_to_ring_element::(result, &product); - } - - result = invert_ntt_montgomery::(result); - - for i in 0..COEFFICIENTS_IN_RING_ELEMENT { - let coefficient_normal_form = montgomery_reduce(result.coefficients[i] * 1441); - result.coefficients[i] = barrett_reduce(v.coefficients[i] - coefficient_normal_form); - } - - result -} - -/// Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message -#[inline(always)] -pub(in crate::kem::kyber) fn compute_ring_element_v( - t_as_ntt: &[PolynomialRingElement; K], - r_as_ntt: &[PolynomialRingElement; K], - error_2: &PolynomialRingElement, - message: &PolynomialRingElement, -) -> PolynomialRingElement { - let mut result = PolynomialRingElement::ZERO; - - for i in 0..K { - let product = ntt_multiply(&t_as_ntt[i], &r_as_ntt[i]); - result = add_to_ring_element::(result, &product); - } - - result = invert_ntt_montgomery::(result); - - for i in 0..COEFFICIENTS_IN_RING_ELEMENT { - let coefficient_normal_form = montgomery_reduce(result.coefficients[i] * 1441); - result.coefficients[i] = barrett_reduce( - coefficient_normal_form + error_2.coefficients[i] + message.coefficients[i], - ); - } - - result -} - -/// Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ -#[inline(always)] -pub(in crate::kem::kyber) fn compute_vector_u( - a_as_ntt: &[[PolynomialRingElement; K]; K], - r_as_ntt: &[PolynomialRingElement; K], - error_1: &[PolynomialRingElement; K], -) -> [PolynomialRingElement; K] { - let mut result = [PolynomialRingElement::ZERO; K]; - - cloop! { - for (i, row) in a_as_ntt.iter().enumerate() { - cloop! { - for (j, a_element) in row.iter().enumerate() { - let product = ntt_multiply(a_element, &r_as_ntt[j]); - result[i] = add_to_ring_element::(result[i], &product); - } - } - - result[i] = invert_ntt_montgomery::(result[i]); - - for j in 0..COEFFICIENTS_IN_RING_ELEMENT { - let coefficient_normal_form = montgomery_reduce(result[i].coefficients[j] * 1441); - - result[i].coefficients[j] = - barrett_reduce(coefficient_normal_form + error_1[i].coefficients[j]); - } - } - } - - result -} - -/// Compute  ◦ ŝ + ê -#[inline(always)] -#[allow(non_snake_case)] -pub(in crate::kem::kyber) fn compute_As_plus_e( - matrix_A: &[[PolynomialRingElement; K]; K], - s_as_ntt: &[PolynomialRingElement; K], - error_as_ntt: &[PolynomialRingElement; K], -) -> [PolynomialRingElement; K] { - let mut result = [PolynomialRingElement::ZERO; K]; - - cloop! { - for (i, row) in matrix_A.iter().enumerate() { - cloop! { - for (j, matrix_element) in row.iter().enumerate() { - let product = ntt_multiply(matrix_element, &s_as_ntt[j]); - result[i] = add_to_ring_element::(result[i], &product); - } - } - - for j in 0..COEFFICIENTS_IN_RING_ELEMENT { - // The coefficients are of the form aR^{-1} mod q, which means - // calling to_montgomery_domain() on them should return a mod q. - let coefficient_normal_form = to_standard_domain(result[i].coefficients[j]); - - result[i].coefficients[j] = - barrett_reduce(coefficient_normal_form + error_as_ntt[i].coefficients[j]) - } - } - } - - result -} diff --git a/src/kem/kyber/ntt.rs b/src/kem/kyber/ntt.rs deleted file mode 100644 index 85d819e4f..000000000 --- a/src/kem/kyber/ntt.rs +++ /dev/null @@ -1,339 +0,0 @@ -use crate::hax_utils::hax_debug_assert; - -use super::{ - arithmetic::{ - barrett_reduce, montgomery_multiply_fe_by_fer, montgomery_reduce, FieldElement, - FieldElementTimesMontgomeryR, MontgomeryFieldElement, PolynomialRingElement, - }, - constants::{COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}, -}; - -const ZETAS_TIMES_MONTGOMERY_R: [FieldElementTimesMontgomeryR; 128] = [ - -1044, -758, -359, -1517, 1493, 1422, 287, 202, -171, 622, 1577, 182, 962, -1202, -1474, 1468, - 573, -1325, 264, 383, -829, 1458, -1602, -130, -681, 1017, 732, 608, -1542, 411, -205, -1571, - 1223, 652, -552, 1015, -1293, 1491, -282, -1544, 516, -8, -320, -666, -1618, -1162, 126, 1469, - -853, -90, -271, 830, 107, -1421, -247, -951, -398, 961, -1508, -725, 448, -1065, 677, -1275, - -1103, 430, 555, 843, -1251, 871, 1550, 105, 422, 587, 177, -235, -291, -460, 1574, 1653, -246, - 778, 1159, -147, -777, 1483, -602, 1119, -1590, 644, -872, 349, 418, 329, -156, -75, 817, 1097, - 603, 610, 1322, -1285, -1465, 384, -1215, -136, 1218, -1335, -874, 220, -1187, -1659, -1185, - -1530, -1278, 794, -1510, -854, -870, 478, -108, -308, 996, 991, 958, -1460, 1522, 1628, -]; - -/// Represents an intermediate polynomial splitting step in the NTT. All -/// resulting coefficients are in the normal domain since the zetas have been -/// multiplied by MONTGOMERY_R. -#[inline(always)] -fn ntt_at_layer( - zeta_i: &mut usize, - mut re: PolynomialRingElement, - layer: usize, - _initial_coefficient_bound: usize, -) -> PolynomialRingElement { - let step = 1 << layer; - - for round in 0..(128 >> layer) { - *zeta_i += 1; - - let offset = round * step * 2; - - for j in offset..offset + step { - let t = montgomery_multiply_fe_by_fer( - re.coefficients[j + step], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ); - re.coefficients[j + step] = re.coefficients[j] - t; - re.coefficients[j] = re.coefficients[j] + t; - } - } - - hax_debug_assert!(re.coefficients.into_iter().all(|coefficient| { - coefficient.abs() - < _initial_coefficient_bound as i32 + ((8 - layer as i32) * ((3 * FIELD_MODULUS) / 2)) - })); - - re -} - -/// See [`ntt_at_layer`]. -#[inline(always)] -fn ntt_at_layer_3( - zeta_i: &mut usize, - re: PolynomialRingElement, - layer: usize, -) -> PolynomialRingElement { - ntt_at_layer(zeta_i, re, layer, 3) -} - -/// See [`ntt_at_layer`]. -#[inline(always)] -fn ntt_at_layer_3328( - zeta_i: &mut usize, - re: PolynomialRingElement, - layer: usize, -) -> PolynomialRingElement { - ntt_at_layer(zeta_i, re, layer, 3328) -} - -/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation -/// of a `KyberPolynomialRingElement`. -/// -/// This function operates only on those which were produced by binomial -/// sampling, and thus those which have small coefficients. The small -/// coefficients let us skip the first round of Montgomery reductions. -#[cfg_attr(hax, hax_lib_macros::requires( - hax_lib::forall(|i:usize| - hax_lib::implies(i < re.coefficients.len(), || re.coefficients[i].abs() <= 3 -))))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || - result.coefficients[i].abs() < FIELD_MODULUS -))))] -#[inline(always)] -pub(in crate::kem::kyber) fn ntt_binomially_sampled_ring_element( - mut re: PolynomialRingElement, -) -> PolynomialRingElement { - hax_debug_assert!(re - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() <= 3)); - - // Due to the small coefficient bound, we can skip the first round of - // Montgomery reductions. - let mut zeta_i = 1; - - for j in 0..128 { - // Multiply by the appropriate zeta in the normal domain. - let t = re.coefficients[j + 128] * -1600; - - re.coefficients[j + 128] = re.coefficients[j] - t; - re.coefficients[j] = re.coefficients[j] + t; - } - - hax_debug_assert!(re - .coefficients - .into_iter() - .all(|coefficient| { coefficient.abs() < 3 + ((3 * FIELD_MODULUS) / 2) })); - - re = ntt_at_layer_3(&mut zeta_i, re, 6); - re = ntt_at_layer_3(&mut zeta_i, re, 5); - re = ntt_at_layer_3(&mut zeta_i, re, 4); - re = ntt_at_layer_3(&mut zeta_i, re, 3); - re = ntt_at_layer_3(&mut zeta_i, re, 2); - re = ntt_at_layer_3(&mut zeta_i, re, 1); - - for i in 0..COEFFICIENTS_IN_RING_ELEMENT { - re.coefficients[i] = barrett_reduce(re.coefficients[i]); - } - - re -} - -/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation -/// of a `KyberPolynomialRingElement`. -/// -/// This function operates on the ring element that partly constitutes -/// the ciphertext. -#[cfg_attr(hax, hax_lib_macros::requires( - hax_lib::forall(|i:usize| - hax_lib::implies(i < re.coefficients.len(), || re.coefficients[i].abs() <= 3328 -))))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || - result.coefficients[i].abs() < FIELD_MODULUS -))))] -#[inline(always)] -pub(in crate::kem::kyber) fn ntt_vector_u( - mut re: PolynomialRingElement, -) -> PolynomialRingElement { - hax_debug_assert!(re - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() <= 3328)); - - let mut zeta_i = 0; - - re = ntt_at_layer_3328(&mut zeta_i, re, 7); - re = ntt_at_layer_3328(&mut zeta_i, re, 6); - re = ntt_at_layer_3328(&mut zeta_i, re, 5); - re = ntt_at_layer_3328(&mut zeta_i, re, 4); - re = ntt_at_layer_3328(&mut zeta_i, re, 3); - re = ntt_at_layer_3328(&mut zeta_i, re, 2); - re = ntt_at_layer_3328(&mut zeta_i, re, 1); - - for i in 0..COEFFICIENTS_IN_RING_ELEMENT { - re.coefficients[i] = barrett_reduce(re.coefficients[i]); - } - - re -} - -#[inline(always)] -fn invert_ntt_at_layer( - zeta_i: &mut usize, - mut re: PolynomialRingElement, - layer: usize, -) -> PolynomialRingElement { - let step = 1 << layer; - - for round in 0..(128 >> layer) { - *zeta_i -= 1; - - let offset = round * step * 2; - - for j in offset..offset + step { - let a_minus_b = re.coefficients[j + step] - re.coefficients[j]; - - // Instead of dividing by 2 here, we just divide by - // 2^7 in one go in the end. - re.coefficients[j] = re.coefficients[j] + re.coefficients[j + step]; - re.coefficients[j + step] = - montgomery_reduce(a_minus_b * ZETAS_TIMES_MONTGOMERY_R[*zeta_i]); - } - } - - re -} - -/// Use the Gentleman-Sande butterfly to invert, in-place, the NTT representation -/// of a `KyberPolynomialRingElement`. The coefficients of the output -/// ring element are in the Montgomery domain. -#[inline(always)] -pub(crate) fn invert_ntt_montgomery( - mut re: PolynomialRingElement, -) -> PolynomialRingElement { - // We only ever call this function after matrix/vector multiplication - hax_debug_assert!(re - .coefficients - .into_iter() - .all(|coefficient| coefficient.abs() < (K as i32) * FIELD_MODULUS)); - - let mut zeta_i = COEFFICIENTS_IN_RING_ELEMENT / 2; - - re = invert_ntt_at_layer(&mut zeta_i, re, 1); - re = invert_ntt_at_layer(&mut zeta_i, re, 2); - re = invert_ntt_at_layer(&mut zeta_i, re, 3); - re = invert_ntt_at_layer(&mut zeta_i, re, 4); - re = invert_ntt_at_layer(&mut zeta_i, re, 5); - re = invert_ntt_at_layer(&mut zeta_i, re, 6); - re = invert_ntt_at_layer(&mut zeta_i, re, 7); - - hax_debug_assert!( - re.coefficients[0].abs() < 128 * (K as i32) * FIELD_MODULUS - && re.coefficients[1].abs() < 128 * (K as i32) * FIELD_MODULUS - ); - hax_debug_assert!(re - .coefficients - .into_iter() - .enumerate() - .skip(2) - .all(|(i, coefficient)| coefficient.abs() < (128 / (1 << i.ilog2())) * FIELD_MODULUS)); - - for i in 0..2 { - re.coefficients[i] = barrett_reduce(re.coefficients[i]); - } - re -} - -/// Compute the product of two Kyber binomials with respect to the -/// modulus `X² - zeta`. -/// -/// This function almost implements Algorithm 11 of the -/// NIST FIPS 203 standard, which is reproduced below: -/// -/// ```plaintext -/// Input: a₀, a₁, b₀, b₁ ∈ ℤq. -/// Input: γ ∈ ℤq. -/// Output: c₀, c₁ ∈ ℤq. -/// -/// c₀ ← a₀·b₀ + a₁·b₁·γ -/// c₁ ← a₀·b₁ + a₁·b₀ -/// return c₀, c₁ -/// ``` -/// We say "almost" because the coefficients output by this function are in -/// the Montgomery domain (unlike in the specification). -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[inline(always)] -fn ntt_multiply_binomials( - (a0, a1): (FieldElement, FieldElement), - (b0, b1): (FieldElement, FieldElement), - zeta: FieldElementTimesMontgomeryR, -) -> (MontgomeryFieldElement, MontgomeryFieldElement) { - ( - montgomery_reduce(a0 * b0 + montgomery_reduce(a1 * b1) * zeta), - montgomery_reduce(a0 * b1 + a1 * b0), - ) -} - -/// Given two `KyberPolynomialRingElement`s in their NTT representations, -/// compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`, -/// the `iᵗʰ` coefficient of the product `k̂` is determined by the calculation: -/// -/// ```plaintext -/// ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X² - ζ^(2·BitRev₇(i) + 1)) -/// ``` -/// -/// This function almost implements Algorithm 10 of the -/// NIST FIPS 203 standard, which is reproduced below: -/// -/// ```plaintext -/// Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆. -/// Output: An array ĥ ∈ ℤq. -/// -/// for(i ← 0; i < 128; i++) -/// (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1], ζ^(2·BitRev₇(i) + 1)) -/// end for -/// return ĥ -/// ``` -/// We say "almost" because the coefficients of the ring element output by -/// this function are in the Montgomery domain. -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[cfg_attr(hax, hax_lib_macros::requires( - hax_lib::forall(|i:usize| - hax_lib::implies(i < COEFFICIENTS_IN_RING_ELEMENT, || - (lhs.coefficients[i] >= 0 && lhs.coefficients[i] < 4096) && - (rhs.coefficients[i].abs() <= FIELD_MODULUS) - -))))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || - result.coefficients[i].abs() <= FIELD_MODULUS -))))] -#[inline(always)] -pub(crate) fn ntt_multiply( - lhs: &PolynomialRingElement, - rhs: &PolynomialRingElement, -) -> PolynomialRingElement { - hax_debug_assert!(lhs - .coefficients - .into_iter() - .all(|coefficient| coefficient >= 0 && coefficient < 4096)); - - let mut out = PolynomialRingElement::ZERO; - - for i in 0..(COEFFICIENTS_IN_RING_ELEMENT / 4) { - let product = ntt_multiply_binomials( - (lhs.coefficients[4 * i], lhs.coefficients[4 * i + 1]), - (rhs.coefficients[4 * i], rhs.coefficients[4 * i + 1]), - ZETAS_TIMES_MONTGOMERY_R[64 + i], - ); - out.coefficients[4 * i] = product.0; - out.coefficients[4 * i + 1] = product.1; - - let product = ntt_multiply_binomials( - (lhs.coefficients[4 * i + 2], lhs.coefficients[4 * i + 3]), - (rhs.coefficients[4 * i + 2], rhs.coefficients[4 * i + 3]), - -ZETAS_TIMES_MONTGOMERY_R[64 + i], - ); - out.coefficients[4 * i + 2] = product.0; - out.coefficients[4 * i + 3] = product.1; - } - - out -} diff --git a/src/kem/kyber/sampling.rs b/src/kem/kyber/sampling.rs deleted file mode 100644 index f4d1fbfc2..000000000 --- a/src/kem/kyber/sampling.rs +++ /dev/null @@ -1,240 +0,0 @@ -use super::{ - arithmetic::{FieldElement, PolynomialRingElement}, - constants::{COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}, - hash_functions::*, -}; -use crate::cloop; -use crate::hax_utils::hax_debug_assert; - -/// If `bytes` contains a set of uniformly random bytes, this function -/// uniformly samples a ring element `â` that is treated as being the NTT representation -/// of the corresponding polynomial `a`. -/// -/// Since rejection sampling is used, it is possible the supplied bytes are -/// not enough to sample the element, in which case an `Err` is returned and the -/// caller must try again with a fresh set of bytes. -/// -/// This function partially implements Algorithm 6 of the NIST FIPS 203 standard, -/// We say "partially" because this implementation only accepts a finite set of -/// bytes as input and returns an error if the set is not enough; Algorithm 6 of -/// the FIPS 203 standard on the other hand samples from an infinite stream of bytes -/// until the ring element is filled. Algorithm 6 is reproduced below: -/// -/// ```plaintext -/// Input: byte stream B ∈ 𝔹*. -/// Output: array â ∈ ℤ₂₅₆. -/// -/// i ← 0 -/// j ← 0 -/// while j < 256 do -/// d₁ ← B[i] + 256·(B[i+1] mod 16) -/// d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] -/// if d₁ < q then -/// â[j] ← d₁ -/// j ← j + 1 -/// end if -/// if d₂ < q and j < 256 then -/// â[j] ← d₂ -/// j ← j + 1 -/// end if -/// i ← i + 3 -/// end while -/// return â -/// ``` -/// -/// The NIST FIPS 203 standard can be found at -/// . -fn sample_from_uniform_distribution_next( - randomness: [[u8; N]; K], - sampled_coefficients: &mut [usize; K], - out: &mut [PolynomialRingElement; K], -) -> bool { - let mut done = true; - for i in 0..K { - for bytes in randomness[i].chunks(3) { - let b1 = bytes[0] as i32; - let b2 = bytes[1] as i32; - let b3 = bytes[2] as i32; - - let d1 = ((b2 & 0xF) << 8) | b1; - let d2 = (b3 << 4) | (b2 >> 4); - - if d1 < FIELD_MODULUS && sampled_coefficients[i] < COEFFICIENTS_IN_RING_ELEMENT { - out[i].coefficients[sampled_coefficients[i]] = d1; - sampled_coefficients[i] += 1 - } - if d2 < FIELD_MODULUS && sampled_coefficients[i] < COEFFICIENTS_IN_RING_ELEMENT { - out[i].coefficients[sampled_coefficients[i]] = d2; - sampled_coefficients[i] += 1; - } - } - if sampled_coefficients[i] < COEFFICIENTS_IN_RING_ELEMENT { - done = false - } - } - done -} - -pub(super) fn sample_from_xof(seeds: [[u8; 34]; K]) -> [PolynomialRingElement; K] { - let mut sampled_coefficients: [usize; K] = [0; K]; - let mut out: [PolynomialRingElement; K] = [PolynomialRingElement::ZERO; K]; - - let mut xof_state = absorb(seeds); - let randomness = squeeze_three_blocks(&mut xof_state); - - let mut done = - sample_from_uniform_distribution_next(randomness, &mut sampled_coefficients, &mut out); - - // Requiring more than 5 blocks to sample a ring element should be very - // unlikely according to: - // https://eprint.iacr.org/2023/708.pdf - // To avoid failing here, we squeeze more blocks out of the state until - // we have enough. - while !done { - let randomness = squeeze_block(&mut xof_state); - done = - sample_from_uniform_distribution_next(randomness, &mut sampled_coefficients, &mut out); - } - // XXX: We have to manually free the state here due to a Eurydice issue. - free_state(xof_state); - - out -} - -/// Given a series of uniformly random bytes in `randomness`, for some number `eta`, -/// the `sample_from_binomial_distribution_{eta}` functions sample -/// a ring element from a binomial distribution centered at 0 that uses two sets -/// of `eta` coin flips. If, for example, -/// `eta = ETA`, each ring coefficient is a value `v` such -/// such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and: -/// -/// ```plaintext -/// - If v < 0, Pr[v] = Pr[-v] -/// - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA) -/// ``` -/// -/// The values `v < 0` are mapped to the appropriate `KyberFieldElement`. -/// -/// The expected value is: -/// -/// ```plaintext -/// E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1] + (ETA)Pr[ETA] -/// = 0 since Pr[-v] = Pr[v] when v < 0. -/// ``` -/// -/// And the variance is: -/// -/// ```plaintext -/// Var(X) = E[(X - E[X])^2] -/// = E[X^2] -/// = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2^(2 * ETA)) -/// = ETA / 2 -/// ``` -/// -/// This function implements Algorithm 7 of the NIST FIPS 203 standard, which is -/// reproduced below: -/// -/// ```plaintext -/// Input: byte array B ∈ 𝔹^{64η}. -/// Output: array f ∈ ℤ₂₅₆. -/// -/// b ← BytesToBits(B) -/// for (i ← 0; i < 256; i++) -/// x ← ∑(j=0 to η - 1) b[2iη + j] -/// y ← ∑(j=0 to η - 1) b[2iη + η + j] -/// f[i] ← x−y mod q -/// end for -/// return f -/// ``` -/// -/// The NIST FIPS 203 standard can be found at -/// . -#[cfg_attr(hax, hax_lib_macros::requires(randomness.len() == 2 * 64))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || result.coefficients[i].abs() <= 2 -))))] -fn sample_from_binomial_distribution_2(randomness: &[u8]) -> PolynomialRingElement { - let mut sampled: PolynomialRingElement = PolynomialRingElement::ZERO; - - cloop! { - for (chunk_number, byte_chunk) in randomness.chunks_exact(4).enumerate() { - let random_bits_as_u32: u32 = (byte_chunk[0] as u32) - | (byte_chunk[1] as u32) << 8 - | (byte_chunk[2] as u32) << 16 - | (byte_chunk[3] as u32) << 24; - - let even_bits = random_bits_as_u32 & 0x55555555; - let odd_bits = (random_bits_as_u32 >> 1) & 0x55555555; - - let coin_toss_outcomes = even_bits + odd_bits; - - cloop! { - for outcome_set in (0..u32::BITS).step_by(4) { - let outcome_1 = ((coin_toss_outcomes >> outcome_set) & 0x3) as FieldElement; - let outcome_2 = ((coin_toss_outcomes >> (outcome_set + 2)) & 0x3) as FieldElement; - - let offset = (outcome_set >> 2) as usize; - sampled.coefficients[8 * chunk_number + offset] = outcome_1 - outcome_2; - } - } - } - } - - hax_debug_assert!(sampled - .coefficients - .into_iter() - .all(|coefficient| coefficient >= -2 && coefficient <= 2)); - sampled -} - -#[cfg_attr(hax, hax_lib_macros::requires(randomness.len() == 3 * 64))] -#[cfg_attr(hax, hax_lib_macros::ensures(|result| - hax_lib::forall(|i:usize| - hax_lib::implies(i < result.coefficients.len(), || result.coefficients[i].abs() <= 3 -))))] -fn sample_from_binomial_distribution_3(randomness: &[u8]) -> PolynomialRingElement { - let mut sampled: PolynomialRingElement = PolynomialRingElement::ZERO; - - cloop! { - for (chunk_number, byte_chunk) in randomness.chunks_exact(3).enumerate() { - let random_bits_as_u24: u32 = - (byte_chunk[0] as u32) | (byte_chunk[1] as u32) << 8 | (byte_chunk[2] as u32) << 16; - - let first_bits = random_bits_as_u24 & 0x00249249; - let second_bits = (random_bits_as_u24 >> 1) & 0x00249249; - let third_bits = (random_bits_as_u24 >> 2) & 0x00249249; - - let coin_toss_outcomes = first_bits + second_bits + third_bits; - - cloop! { - for outcome_set in (0..24).step_by(6) { - let outcome_1 = ((coin_toss_outcomes >> outcome_set) & 0x7) as FieldElement; - let outcome_2 = ((coin_toss_outcomes >> (outcome_set + 3)) & 0x7) as FieldElement; - - let offset = (outcome_set / 6) as usize; - sampled.coefficients[4 * chunk_number + offset] = outcome_1 - outcome_2; - } - } - } - } - - hax_debug_assert!(sampled - .coefficients - .into_iter() - .all(|coefficient| coefficient >= -3 && coefficient <= 3)); - sampled -} - -#[inline(always)] -pub(super) fn sample_from_binomial_distribution( - randomness: &[u8], -) -> PolynomialRingElement { - hax_debug_assert!(randomness.len() == ETA * 64); - - match ETA as u32 { - 2 => sample_from_binomial_distribution_2(randomness), - 3 => sample_from_binomial_distribution_3(randomness), - _ => unreachable!(), - } -} diff --git a/src/kem/kyber/serialize.rs b/src/kem/kyber/serialize.rs deleted file mode 100644 index c31d893d2..000000000 --- a/src/kem/kyber/serialize.rs +++ /dev/null @@ -1,626 +0,0 @@ -use super::{ - arithmetic::{to_unsigned_representative, FieldElement, PolynomialRingElement}, - compress::{ - compress_ciphertext_coefficient, compress_message_coefficient, - decompress_ciphertext_coefficient, decompress_message_coefficient, - }, - constants::{BYTES_PER_RING_ELEMENT, SHARED_SECRET_SIZE}, -}; -use crate::cloop; -use crate::hax_utils::hax_debug_assert; - -#[cfg(not(hax))] -use super::constants::COEFFICIENTS_IN_RING_ELEMENT; - -#[inline(always)] -pub(super) fn compress_then_serialize_message( - re: PolynomialRingElement, -) -> [u8; SHARED_SECRET_SIZE] { - let mut serialized = [0u8; SHARED_SECRET_SIZE]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(8).enumerate() { - cloop! { - for (j, coefficient) in coefficients.iter().enumerate() { - let coefficient = to_unsigned_representative(*coefficient); - - let coefficient_compressed = compress_message_coefficient(coefficient); - - serialized[i] |= coefficient_compressed << j - } - } - } - } - - serialized -} -#[inline(always)] -pub(super) fn deserialize_then_decompress_message( - serialized: [u8; SHARED_SECRET_SIZE], -) -> PolynomialRingElement { - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, byte) in serialized.into_iter().enumerate() { - for j in 0..8 { - let coefficient_compressed = ((byte >> j) & 0x1) as FieldElement; - re.coefficients[8 * i + j] = decompress_message_coefficient(coefficient_compressed); - } - } - } - - re -} - -#[inline(always)] -pub(super) fn serialize_uncompressed_ring_element( - re: PolynomialRingElement, -) -> [u8; BYTES_PER_RING_ELEMENT] { - let mut serialized = [0u8; BYTES_PER_RING_ELEMENT]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(2).enumerate() { - let coefficient1 = to_unsigned_representative(coefficients[0]); - let coefficient2 = to_unsigned_representative(coefficients[1]); - - let (coef1, coef2, coef3) = compress_coefficients_3(coefficient1, coefficient2); - serialized[3 * i] = coef1; - serialized[3 * i + 1] = coef2; - serialized[3 * i + 2] = coef3; - } - } - - serialized -} - -#[inline(always)] -fn compress_coefficients_3(coefficient1: u16, coefficient2: u16) -> (u8, u8, u8) { - let coef1 = (coefficient1 & 0xFF) as u8; - let coef2 = ((coefficient1 >> 8) | ((coefficient2 & 0x0F) << 4)) as u8; - let coef3 = ((coefficient2 >> 4) & 0xFF) as u8; - (coef1, coef2, coef3) -} - -#[inline(always)] -pub(super) fn deserialize_to_uncompressed_ring_element(serialized: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == BYTES_PER_RING_ELEMENT); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, bytes) in serialized.chunks_exact(3).enumerate() { - let byte1 = bytes[0] as FieldElement; - let byte2 = bytes[1] as FieldElement; - let byte3 = bytes[2] as FieldElement; - - re.coefficients[2 * i] = (byte2 & 0x0F) << 8 | (byte1 & 0xFF); - re.coefficients[2 * i + 1] = (byte3 << 4) | ((byte2 >> 4) & 0x0F); - } - } - - re -} - -/// Only use with public values. -/// -/// This MUST NOT be used with secret inputs, like its caller `deserialize_ring_elements_reduced`. -#[inline(always)] -fn deserialize_to_reduced_ring_element(ring_element: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(ring_element.len() == BYTES_PER_RING_ELEMENT); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, bytes) in ring_element.chunks_exact(3).enumerate() { - let byte1 = bytes[0] as FieldElement; - let byte2 = bytes[1] as FieldElement; - let byte3 = bytes[2] as FieldElement; - - // The modulus here is ok because the input must be public. - // XXX: The awkward code here is necessary to work around Charon shortcomings. - re.coefficients[2 * i] = (byte2 & 0x0F) << 8 | (byte1 & 0xFF); - let tmp = re.coefficients[2 * i] % 3329; // FIELD_MODULUS - re.coefficients[2 * i] = tmp; - - re.coefficients[2 * i + 1] = (byte3 << 4) | ((byte2 >> 4) & 0x0F); - let tmp = re.coefficients[2 * i + 1] % 3329; // FIELD_MODULUS - re.coefficients[2 * i + 1] = tmp; - } - } - - re -} - -/// This function deserializes ring elements and reduces the result by the field -/// modulus. -/// -/// This function MUST NOT be used on secret inputs. -#[inline(always)] -pub(super) fn deserialize_ring_elements_reduced( - public_key: &[u8], -) -> [PolynomialRingElement; K] { - let mut deserialized_pk = [PolynomialRingElement::ZERO; K]; - cloop! { - for (i, ring_element) in public_key - .chunks_exact(BYTES_PER_RING_ELEMENT) - .enumerate() - { - deserialized_pk[i] =deserialize_to_reduced_ring_element(ring_element); - } - } - deserialized_pk -} - -#[inline(always)] -fn compress_then_serialize_10(re: PolynomialRingElement) -> [u8; OUT_LEN] { - let mut serialized = [0u8; OUT_LEN]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(4).enumerate() { - let coefficient1 = - compress_ciphertext_coefficient(10, to_unsigned_representative(coefficients[0])); - let coefficient2 = - compress_ciphertext_coefficient(10, to_unsigned_representative(coefficients[1])); - let coefficient3 = - compress_ciphertext_coefficient(10, to_unsigned_representative(coefficients[2])); - let coefficient4 = - compress_ciphertext_coefficient(10, to_unsigned_representative(coefficients[3])); - - let (coef1, coef2, coef3, coef4, coef5) = - compress_coefficients_10(coefficient1, coefficient2, coefficient3, coefficient4); - serialized[5 * i] = coef1; - serialized[5 * i + 1] = coef2; - serialized[5 * i + 2] = coef3; - serialized[5 * i + 3] = coef4; - serialized[5 * i + 4] = coef5; - } - } - - serialized -} - -#[inline(always)] -fn compress_coefficients_10( - coefficient1: i32, - coefficient2: i32, - coefficient3: i32, - coefficient4: i32, -) -> (u8, u8, u8, u8, u8) { - let coef1 = (coefficient1 & 0xFF) as u8; - let coef2 = ((coefficient2 & 0x3F) as u8) << 2 | ((coefficient1 >> 8) & 0x03) as u8; - let coef3 = ((coefficient3 & 0x0F) as u8) << 4 | ((coefficient2 >> 6) & 0x0F) as u8; - let coef4 = ((coefficient4 & 0x03) as u8) << 6 | ((coefficient3 >> 4) & 0x3F) as u8; - let coef5 = ((coefficient4 >> 2) & 0xFF) as u8; - (coef1, coef2, coef3, coef4, coef5) -} - -#[inline(always)] -fn compress_then_serialize_11(re: PolynomialRingElement) -> [u8; OUT_LEN] { - let mut serialized = [0u8; OUT_LEN]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(8).enumerate() { - let coefficient1 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[0])); - let coefficient2 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[1])); - let coefficient3 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[2])); - let coefficient4 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[3])); - let coefficient5 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[4])); - let coefficient6 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[5])); - let coefficient7 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[6])); - let coefficient8 = - compress_ciphertext_coefficient(11, to_unsigned_representative(coefficients[7])); - - let (coef1, coef2, coef3, coef4, coef5, coef6, coef7, coef8, coef9, coef10, coef11) = - compress_coefficients_11( - coefficient1, - coefficient2, - coefficient3, - coefficient4, - coefficient5, - coefficient6, - coefficient7, - coefficient8, - ); - serialized[11 * i] = coef1; - serialized[11 * i + 1] = coef2; - serialized[11 * i + 2] = coef3; - serialized[11 * i + 3] = coef4; - serialized[11 * i + 4] = coef5; - serialized[11 * i + 5] = coef6; - serialized[11 * i + 6] = coef7; - serialized[11 * i + 7] = coef8; - serialized[11 * i + 8] = coef9; - serialized[11 * i + 9] = coef10; - serialized[11 * i + 10] = coef11; - } - } - - serialized -} - -#[inline(always)] -fn compress_coefficients_11( - coefficient1: i32, - coefficient2: i32, - coefficient3: i32, - coefficient4: i32, - coefficient5: i32, - coefficient6: i32, - coefficient7: i32, - coefficient8: i32, -) -> (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8) { - let coef1 = coefficient1 as u8; - let coef2 = ((coefficient2 & 0x1F) as u8) << 3 | ((coefficient1 >> 8) as u8); - let coef3 = ((coefficient3 & 0x3) as u8) << 6 | ((coefficient2 >> 5) as u8); - let coef4 = ((coefficient3 >> 2) & 0xFF) as u8; - let coef5 = ((coefficient4 & 0x7F) as u8) << 1 | (coefficient3 >> 10) as u8; - let coef6 = ((coefficient5 & 0xF) as u8) << 4 | (coefficient4 >> 7) as u8; - let coef7 = ((coefficient6 & 0x1) as u8) << 7 | (coefficient5 >> 4) as u8; - let coef8 = ((coefficient6 >> 1) & 0xFF) as u8; - let coef9 = ((coefficient7 & 0x3F) as u8) << 2 | (coefficient6 >> 9) as u8; - let coef10 = ((coefficient8 & 0x7) as u8) << 5 | (coefficient7 >> 6) as u8; - let coef11 = (coefficient8 >> 3) as u8; - ( - coef1, coef2, coef3, coef4, coef5, coef6, coef7, coef8, coef9, coef10, coef11, - ) -} -#[inline(always)] -pub(super) fn compress_then_serialize_ring_element_u< - const COMPRESSION_FACTOR: usize, - const OUT_LEN: usize, ->( - re: PolynomialRingElement, -) -> [u8; OUT_LEN] { - hax_debug_assert!((COEFFICIENTS_IN_RING_ELEMENT * COMPRESSION_FACTOR) / 8 == OUT_LEN); - - match COMPRESSION_FACTOR as u32 { - 10 => compress_then_serialize_10(re), - 11 => compress_then_serialize_11(re), - _ => unreachable!(), - } -} - -#[inline(always)] -fn compress_then_serialize_4(re: PolynomialRingElement) -> [u8; OUT_LEN] { - let mut serialized = [0u8; OUT_LEN]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(2).enumerate() { - let coefficient1 = - compress_ciphertext_coefficient(4, to_unsigned_representative(coefficients[0])) as u8; - let coefficient2 = - compress_ciphertext_coefficient(4, to_unsigned_representative(coefficients[1])) as u8; - - serialized[i] = (coefficient2 << 4) | coefficient1; - } - } - - serialized -} - -#[inline(always)] -fn compress_then_serialize_5(re: PolynomialRingElement) -> [u8; OUT_LEN] { - let mut serialized = [0u8; OUT_LEN]; - - cloop! { - for (i, coefficients) in re.coefficients.chunks_exact(8).enumerate() { - let coefficient1 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[0])) as u8; - let coefficient2 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[1])) as u8; - let coefficient3 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[2])) as u8; - let coefficient4 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[3])) as u8; - let coefficient5 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[4])) as u8; - let coefficient6 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[5])) as u8; - let coefficient7 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[6])) as u8; - let coefficient8 = - compress_ciphertext_coefficient(5, to_unsigned_representative(coefficients[7])) as u8; - - let (coef1, coef2, coef3, coef4, coef5) = compress_coefficients_5( - coefficient2, - coefficient1, - coefficient4, - coefficient3, - coefficient5, - coefficient7, - coefficient6, - coefficient8, - ); - serialized[5 * i] = coef1; - serialized[5 * i + 1] = coef2; - serialized[5 * i + 2] = coef3; - serialized[5 * i + 3] = coef4; - serialized[5 * i + 4] = coef5; - } - } - - serialized -} - -#[inline(always)] -fn compress_coefficients_5( - coefficient2: u8, - coefficient1: u8, - coefficient4: u8, - coefficient3: u8, - coefficient5: u8, - coefficient7: u8, - coefficient6: u8, - coefficient8: u8, -) -> (u8, u8, u8, u8, u8) { - let coef1 = (coefficient2 & 0x7) << 5 | coefficient1; - let coef2 = ((coefficient4 & 1) << 7) | (coefficient3 << 2) | (coefficient2 >> 3); - let coef3 = ((coefficient5 & 0xF) << 4) | (coefficient4 >> 1); - let coef4 = ((coefficient7 & 0x3) << 6) | (coefficient6 << 1) | (coefficient5 >> 4); - let coef5 = (coefficient8 << 3) | (coefficient7 >> 2); - (coef1, coef2, coef3, coef4, coef5) -} - -#[inline(always)] -pub(super) fn compress_then_serialize_ring_element_v< - const COMPRESSION_FACTOR: usize, - const OUT_LEN: usize, ->( - re: PolynomialRingElement, -) -> [u8; OUT_LEN] { - hax_debug_assert!((COEFFICIENTS_IN_RING_ELEMENT * COMPRESSION_FACTOR) / 8 == OUT_LEN); - - match COMPRESSION_FACTOR as u32 { - 4 => compress_then_serialize_4(re), - 5 => compress_then_serialize_5(re), - _ => unreachable!(), - } -} - -#[inline(always)] -fn deserialize_then_decompress_10(serialized: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * 10) / 8); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, bytes) in serialized.chunks_exact(5).enumerate() { - let byte1 = bytes[0] as FieldElement; - let byte2 = bytes[1] as FieldElement; - let byte3 = bytes[2] as FieldElement; - let byte4 = bytes[3] as FieldElement; - let byte5 = bytes[4] as FieldElement; - - let (coefficient1, coefficient2, coefficient3, coefficient4) = - decompress_coefficients_10(byte2, byte1, byte3, byte4, byte5); - - re.coefficients[4 * i] = decompress_ciphertext_coefficient(10, coefficient1); - re.coefficients[4 * i + 1] = decompress_ciphertext_coefficient(10, coefficient2); - re.coefficients[4 * i + 2] = decompress_ciphertext_coefficient(10, coefficient3); - re.coefficients[4 * i + 3] = decompress_ciphertext_coefficient(10, coefficient4); - } - } - - re -} - -#[inline(always)] -fn decompress_coefficients_10( - byte2: i32, - byte1: i32, - byte3: i32, - byte4: i32, - byte5: i32, -) -> (i32, i32, i32, i32) { - let coefficient1 = (byte2 & 0x03) << 8 | (byte1 & 0xFF); - let coefficient2 = (byte3 & 0x0F) << 6 | (byte2 >> 2); - let coefficient3 = (byte4 & 0x3F) << 4 | (byte3 >> 4); - let coefficient4 = (byte5 << 2) | (byte4 >> 6); - (coefficient1, coefficient2, coefficient3, coefficient4) -} - -#[inline(always)] -fn deserialize_then_decompress_11(serialized: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * 11) / 8); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, bytes) in serialized.chunks_exact(11).enumerate() { - let byte1 = bytes[0] as FieldElement; - let byte2 = bytes[1] as FieldElement; - let byte3 = bytes[2] as FieldElement; - let byte4 = bytes[3] as FieldElement; - let byte5 = bytes[4] as FieldElement; - let byte6 = bytes[5] as FieldElement; - let byte7 = bytes[6] as FieldElement; - let byte8 = bytes[7] as FieldElement; - let byte9 = bytes[8] as FieldElement; - let byte10 = bytes[9] as FieldElement; - let byte11 = bytes[10] as FieldElement; - - let ( - coefficient1, - coefficient2, - coefficient3, - coefficient4, - coefficient5, - coefficient6, - coefficient7, - coefficient8, - ) = decompress_coefficients_11( - byte2, byte1, byte3, byte5, byte4, byte6, byte7, byte9, byte8, byte10, byte11, - ); - - re.coefficients[8 * i] = decompress_ciphertext_coefficient(11, coefficient1); - re.coefficients[8 * i + 1] = decompress_ciphertext_coefficient(11, coefficient2); - re.coefficients[8 * i + 2] = decompress_ciphertext_coefficient(11, coefficient3); - re.coefficients[8 * i + 3] = decompress_ciphertext_coefficient(11, coefficient4); - re.coefficients[8 * i + 4] = decompress_ciphertext_coefficient(11, coefficient5); - re.coefficients[8 * i + 5] = decompress_ciphertext_coefficient(11, coefficient6); - re.coefficients[8 * i + 6] = decompress_ciphertext_coefficient(11, coefficient7); - re.coefficients[8 * i + 7] = decompress_ciphertext_coefficient(11, coefficient8); - } - } - - re -} - -#[inline(always)] -fn decompress_coefficients_11( - byte2: i32, - byte1: i32, - byte3: i32, - byte5: i32, - byte4: i32, - byte6: i32, - byte7: i32, - byte9: i32, - byte8: i32, - byte10: i32, - byte11: i32, -) -> (i32, i32, i32, i32, i32, i32, i32, i32) { - let coefficient1 = (byte2 & 0x7) << 8 | byte1; - let coefficient2 = (byte3 & 0x3F) << 5 | (byte2 >> 3); - let coefficient3 = (byte5 & 0x1) << 10 | (byte4 << 2) | (byte3 >> 6); - let coefficient4 = (byte6 & 0xF) << 7 | (byte5 >> 1); - let coefficient5 = (byte7 & 0x7F) << 4 | (byte6 >> 4); - let coefficient6 = (byte9 & 0x3) << 9 | (byte8 << 1) | (byte7 >> 7); - let coefficient7 = (byte10 & 0x1F) << 6 | (byte9 >> 2); - let coefficient8 = (byte11 << 3) | (byte10 >> 5); - ( - coefficient1, - coefficient2, - coefficient3, - coefficient4, - coefficient5, - coefficient6, - coefficient7, - coefficient8, - ) -} - -#[inline(always)] -pub(super) fn deserialize_then_decompress_ring_element_u( - serialized: &[u8], -) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * COMPRESSION_FACTOR) / 8); - - match COMPRESSION_FACTOR as u32 { - 10 => deserialize_then_decompress_10(serialized), - 11 => deserialize_then_decompress_11(serialized), - _ => unreachable!(), - } -} - -#[inline(always)] -fn deserialize_then_decompress_4(serialized: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * 4) / 8); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, byte) in serialized.iter().enumerate() { - let (coefficient1, coefficient2) = decompress_coefficients_4(byte); - - re.coefficients[2 * i] = decompress_ciphertext_coefficient(4, coefficient1); - re.coefficients[2 * i + 1] = decompress_ciphertext_coefficient(4, coefficient2); - } - } - - re -} - -#[inline(always)] -fn decompress_coefficients_4(byte: &u8) -> (i32, i32) { - let coefficient1 = (byte & 0x0F) as FieldElement; - let coefficient2 = ((byte >> 4) & 0x0F) as FieldElement; - (coefficient1, coefficient2) -} - -#[inline(always)] -fn deserialize_then_decompress_5(serialized: &[u8]) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * 5) / 8); - - let mut re = PolynomialRingElement::ZERO; - - cloop! { - for (i, bytes) in serialized.chunks_exact(5).enumerate() { - let byte1 = bytes[0] as FieldElement; - let byte2 = bytes[1] as FieldElement; - let byte3 = bytes[2] as FieldElement; - let byte4 = bytes[3] as FieldElement; - let byte5 = bytes[4] as FieldElement; - - let ( - coefficient1, - coefficient2, - coefficient3, - coefficient4, - coefficient5, - coefficient6, - coefficient7, - coefficient8, - ) = decompress_coefficients_5(byte1, byte2, byte3, byte4, byte5); - - re.coefficients[8 * i] = decompress_ciphertext_coefficient(5, coefficient1); - re.coefficients[8 * i + 1] = decompress_ciphertext_coefficient(5, coefficient2); - re.coefficients[8 * i + 2] = decompress_ciphertext_coefficient(5, coefficient3); - re.coefficients[8 * i + 3] = decompress_ciphertext_coefficient(5, coefficient4); - re.coefficients[8 * i + 4] = decompress_ciphertext_coefficient(5, coefficient5); - re.coefficients[8 * i + 5] = decompress_ciphertext_coefficient(5, coefficient6); - re.coefficients[8 * i + 6] = decompress_ciphertext_coefficient(5, coefficient7); - re.coefficients[8 * i + 7] = decompress_ciphertext_coefficient(5, coefficient8); - } - } - - re -} - -#[inline(always)] -fn decompress_coefficients_5( - byte1: i32, - byte2: i32, - byte3: i32, - byte4: i32, - byte5: i32, -) -> (i32, i32, i32, i32, i32, i32, i32, i32) { - let coefficient1 = byte1 & 0x1F; - let coefficient2 = (byte2 & 0x3) << 3 | (byte1 >> 5); - let coefficient3 = (byte2 >> 2) & 0x1F; - let coefficient4 = ((byte3 & 0xF) << 1) | (byte2 >> 7); - let coefficient5 = ((byte4 & 1) << 4) | (byte3 >> 4); - let coefficient6 = (byte4 >> 1) & 0x1F; - let coefficient7 = ((byte5 & 0x7) << 2) | (byte4 >> 6); - let coefficient8 = byte5 >> 3; - ( - coefficient1, - coefficient2, - coefficient3, - coefficient4, - coefficient5, - coefficient6, - coefficient7, - coefficient8, - ) -} - -#[inline(always)] -pub(super) fn deserialize_then_decompress_ring_element_v( - serialized: &[u8], -) -> PolynomialRingElement { - hax_debug_assert!(serialized.len() == (COEFFICIENTS_IN_RING_ELEMENT * COMPRESSION_FACTOR) / 8); - - match COMPRESSION_FACTOR as u32 { - 4 => deserialize_then_decompress_4(serialized), - 5 => deserialize_then_decompress_5(serialized), - _ => unreachable!(), - } -} diff --git a/src/kem/kyber/types.rs b/src/kem/kyber/types.rs deleted file mode 100644 index fda123bee..000000000 --- a/src/kem/kyber/types.rs +++ /dev/null @@ -1,156 +0,0 @@ -macro_rules! impl_generic_struct { - ($name:ident) => { - pub struct $name { - pub(super) value: [u8; SIZE], - } - - impl AsRef<[u8]> for $name { - fn as_ref(&self) -> &[u8] { - &self.value - } - } - - impl From<[u8; SIZE]> for $name { - fn from(value: [u8; SIZE]) -> Self { - Self { value } - } - } - - impl From<&[u8; SIZE]> for $name { - fn from(value: &[u8; SIZE]) -> Self { - Self { - value: value.clone(), - } - } - } - - impl From<$name> for [u8; SIZE] { - fn from(value: $name) -> Self { - value.value - } - } - - impl TryFrom<&[u8]> for $name { - type Error = core::array::TryFromSliceError; - - fn try_from(value: &[u8]) -> Result { - match value.try_into() { - Ok(value) => Ok(Self { value }), - Err(e) => Err(e), - } - } - } - - impl $name { - pub fn as_slice(&self) -> &[u8; SIZE] { - &self.value - } - - pub fn split_at(&self, mid: usize) -> (&[u8], &[u8]) { - self.value.split_at(mid) - } - - pub const fn len(&self) -> usize { - SIZE - } - } - }; -} -macro_rules! impl_index_impls_for_generic_struct { - ($name:ident) => { - impl core::ops::Index for $name { - type Output = u8; - - fn index(&self, index: usize) -> &Self::Output { - &self.value[index] - } - } - - impl core::ops::Index> for $name { - type Output = [u8]; - - fn index(&self, range: core::ops::Range) -> &Self::Output { - &self.value[range] - } - } - - impl core::ops::Index> for $name { - type Output = [u8]; - - fn index(&self, range: core::ops::RangeTo) -> &Self::Output { - &self.value[range] - } - } - - impl core::ops::Index> for $name { - type Output = [u8]; - - fn index(&self, range: core::ops::RangeFrom) -> &Self::Output { - &self.value[range] - } - } - }; -} - -impl_generic_struct!(MlKemCiphertext); -impl_generic_struct!(MlKemPrivateKey); -impl_generic_struct!(MlKemPublicKey); - -// These traits are used only in `ind_cpa` for kyber cipher text. -mod index_impls { - use super::*; - impl_index_impls_for_generic_struct!(MlKemCiphertext); - impl_index_impls_for_generic_struct!(MlKemPrivateKey); - impl_index_impls_for_generic_struct!(MlKemPublicKey); -} - -/// An ML-KEM key pair -pub struct MlKemKeyPair { - pub(crate) sk: MlKemPrivateKey, - pub(crate) pk: MlKemPublicKey, -} - -impl - MlKemKeyPair -{ - /// Creates a new [`MlKemKeyPair`]. - pub fn new(sk: [u8; PRIVATE_KEY_SIZE], pk: [u8; PUBLIC_KEY_SIZE]) -> Self { - Self { - sk: sk.into(), - pk: pk.into(), - } - } - - pub fn from( - sk: MlKemPrivateKey, - pk: MlKemPublicKey, - ) -> Self { - Self { sk, pk } - } - - pub fn public_key(&self) -> &MlKemPublicKey { - &self.pk - } - - pub fn private_key(&self) -> &MlKemPrivateKey { - &self.sk - } - - pub fn pk(&self) -> &[u8; PUBLIC_KEY_SIZE] { - self.pk.as_slice() - } - - pub fn sk(&self) -> &[u8; PRIVATE_KEY_SIZE] { - self.sk.as_slice() - } - - #[cfg(feature = "tests")] - pub fn into_parts( - self, - ) -> ( - MlKemPrivateKey, - MlKemPublicKey, - ) { - (self.sk, self.pk) - } -}